/ Hex Artifact Content
Login

Artifact c7aa1d069087935f3d4eecd685c80a8d4426ece0:


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 33 35 20 32  test8.c,v 1.35 2
0230: 30 30 36 2f 30 36 2f 32 34 20 30 36 3a 33 36 3a  006/06/24 06:36:
0240: 31 31 20 64 61 6e 69 65 6c 6b 31 39 37 37 20 45  11 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 22 6f 73 2e 68 22 0a  #include "os.h".
0290: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62  #include <stdlib
02a0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h>.#include <st
02b0: 72 69 6e 67 2e 68 3e 0a 0a 23 69 66 6e 64 65 66  ring.h>..#ifndef
02c0: 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52   SQLITE_OMIT_VIR
02d0: 54 55 41 4c 54 41 42 4c 45 0a 0a 74 79 70 65 64  TUALTABLE..typed
02e0: 65 66 20 73 74 72 75 63 74 20 65 63 68 6f 5f 76  ef struct echo_v
02f0: 74 61 62 20 65 63 68 6f 5f 76 74 61 62 3b 0a 74  tab echo_vtab;.t
0300: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 65 63  ypedef struct ec
0310: 68 6f 5f 63 75 72 73 6f 72 20 65 63 68 6f 5f 63  ho_cursor echo_c
0320: 75 72 73 6f 72 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68  ursor;../*.** Th
0330: 65 20 74 65 73 74 20 6d 6f 64 75 6c 65 20 64 65  e test module de
0340: 66 69 6e 65 64 20 69 6e 20 74 68 69 73 20 66 69  fined in this fi
0350: 6c 65 20 75 73 65 73 20 74 77 6f 20 67 6c 6f 62  le uses two glob
0360: 61 6c 20 54 63 6c 20 76 61 72 69 61 62 6c 65 73  al Tcl variables
0370: 20 74 6f 0a 2a 2a 20 63 6f 6d 6d 69 63 61 74 65   to.** commicate
0380: 20 77 69 74 68 20 74 65 73 74 2d 73 63 72 69 70   with test-scrip
0390: 74 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 24 3a  ts:.**.**     $:
03a0: 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 0a 2a 2a 20  :echo_module.** 
03b0: 20 20 20 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75      $::echo_modu
03c0: 6c 65 5f 73 79 6e 63 5f 66 61 69 6c 0a 2a 2a 0a  le_sync_fail.**.
03d0: 2a 2a 20 54 68 65 20 76 61 72 69 61 62 6c 65 20  ** The variable 
03e0: 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 69 73  ::echo_module is
03f0: 20 61 20 6c 69 73 74 2e 20 45 61 63 68 20 74 69   a list. Each ti
0400: 6d 65 20 6f 6e 65 20 6f 66 20 74 68 65 20 66 6f  me one of the fo
0410: 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 6d 65 74 68 6f  llowing.** metho
0420: 64 73 20 69 73 20 63 61 6c 6c 65 64 2c 20 6f 6e  ds is called, on
0430: 65 20 6f 72 20 6d 6f 72 65 20 65 6c 65 6d 65 6e  e or more elemen
0440: 74 73 20 61 72 65 20 61 70 70 65 6e 64 65 64 20  ts are appended 
0450: 74 6f 20 74 68 65 20 6c 69 73 74 2e 0a 2a 2a 20  to the list..** 
0460: 54 68 69 73 20 69 73 20 75 73 65 64 20 66 6f 72  This is used for
0470: 20 61 75 74 6f 6d 61 74 65 64 20 74 65 73 74 69   automated testi
0480: 6e 67 20 6f 66 20 76 69 72 74 75 61 6c 20 74 61  ng of virtual ta
0490: 62 6c 65 20 6d 6f 64 75 6c 65 73 2e 0a 2a 2a 0a  ble modules..**.
04a0: 2a 2a 20 54 68 65 20 3a 3a 65 63 68 6f 5f 6d 6f  ** The ::echo_mo
04b0: 64 75 6c 65 5f 73 79 6e 63 5f 66 61 69 6c 20 76  dule_sync_fail v
04c0: 61 72 69 61 62 6c 65 20 69 73 20 73 65 74 20 62  ariable is set b
04d0: 79 20 74 65 73 74 20 73 63 72 69 70 74 73 20 61  y test scripts a
04e0: 6e 64 20 72 65 61 64 0a 2a 2a 20 62 79 20 63 6f  nd read.** by co
04f0: 64 65 20 69 6e 20 74 68 69 73 20 66 69 6c 65 2e  de in this file.
0500: 20 49 66 20 69 74 20 69 73 20 73 65 74 20 74 6f   If it is set to
0510: 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 61 20 72   the name of a r
0520: 65 61 6c 20 74 61 62 6c 65 20 69 6e 20 74 68 65  eal table in the
0530: 0a 2a 2a 20 74 68 65 20 64 61 74 61 62 61 73 65  .** the database
0540: 2c 20 74 68 65 6e 20 61 6c 6c 20 78 53 79 6e 63  , then all xSync
0550: 20 6f 70 65 72 61 74 69 6f 6e 73 20 6f 6e 20 65   operations on e
0560: 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c  cho virtual tabl
0570: 65 73 20 74 68 61 74 0a 2a 2a 20 75 73 65 20 74  es that.** use t
0580: 68 65 20 6e 61 6d 65 64 20 74 61 62 6c 65 20 61  he named table a
0590: 73 20 61 20 62 61 63 6b 69 6e 67 20 73 74 6f 72  s a backing stor
05a0: 65 20 77 69 6c 6c 20 66 61 69 6c 2e 0a 2a 2f 0a  e will fail..*/.
05b0: 0a 2f 2a 20 0a 2a 2a 20 41 6e 20 65 63 68 6f 20  ./* .** An echo 
05c0: 76 69 72 74 75 61 6c 2d 74 61 62 6c 65 20 6f 62  virtual-table ob
05d0: 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 65 63 68 6f  ject..**.** echo
05e0: 2e 76 74 61 62 2e 61 49 6e 64 65 78 20 69 73 20  .vtab.aIndex is 
05f0: 61 6e 20 61 72 72 61 79 20 6f 66 20 62 6f 6f 6c  an array of bool
0600: 65 61 6e 73 2e 20 54 68 65 20 6e 74 68 20 65 6e  eans. The nth en
0610: 74 72 79 20 69 73 20 74 72 75 65 20 69 66 20 0a  try is true if .
0620: 2a 2a 20 74 68 65 20 6e 74 68 20 63 6f 6c 75 6d  ** the nth colum
0630: 6e 20 6f 66 20 74 68 65 20 72 65 61 6c 20 74 61  n of the real ta
0640: 62 6c 65 20 69 73 20 74 68 65 20 6c 65 66 74 2d  ble is the left-
0650: 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20 6f 66 20 61  most column of a
0660: 6e 20 69 6e 64 65 78 0a 2a 2a 20 28 69 6d 70 6c  n index.** (impl
0670: 69 63 69 74 20 6f 72 20 6f 74 68 65 72 77 69 73  icit or otherwis
0680: 65 29 2e 20 49 6e 20 6f 74 68 65 72 20 77 6f 72  e). In other wor
0690: 64 73 2c 20 69 66 20 53 51 4c 69 74 65 20 63 61  ds, if SQLite ca
06a0: 6e 20 6f 70 74 69 6d 69 7a 65 0a 2a 2a 20 61 20  n optimize.** a 
06b0: 71 75 65 72 79 20 6c 69 6b 65 20 22 53 45 4c 45  query like "SELE
06c0: 43 54 20 2a 20 46 52 4f 4d 20 72 65 61 6c 5f 74  CT * FROM real_t
06d0: 61 62 6c 65 20 57 48 45 52 45 20 63 6f 6c 20 3d  able WHERE col =
06e0: 20 3f 22 2e 0a 2a 2a 0a 2a 2a 20 4d 65 6d 62 65   ?"..**.** Membe
06f0: 72 20 76 61 72 69 61 62 6c 65 20 61 43 6f 6c 5b  r variable aCol[
0700: 5d 20 63 6f 6e 74 61 69 6e 73 20 63 6f 70 69 65  ] contains copie
0710: 73 20 6f 66 20 74 68 65 20 63 6f 6c 75 6d 6e 20  s of the column 
0720: 6e 61 6d 65 73 20 6f 66 20 74 68 65 20 72 65 61  names of the rea
0730: 6c 0a 2a 2a 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73  l.** table..*/.s
0740: 74 72 75 63 74 20 65 63 68 6f 5f 76 74 61 62 20  truct echo_vtab 
0750: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  {.  sqlite3_vtab
0760: 20 62 61 73 65 3b 0a 20 20 54 63 6c 5f 49 6e 74   base;.  Tcl_Int
0770: 65 72 70 20 2a 69 6e 74 65 72 70 3b 20 20 20 20  erp *interp;    
0780: 20 2f 2a 20 54 63 6c 20 69 6e 74 65 72 70 72 65   /* Tcl interpre
0790: 74 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64  ter containing d
07a0: 65 62 75 67 20 76 61 72 69 61 62 6c 65 73 20 2a  ebug variables *
07b0: 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b  /.  sqlite3 *db;
07c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
07d0: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
07e0: 6f 6e 20 2a 2f 0a 0a 20 20 63 68 61 72 20 2a 7a  on */..  char *z
07f0: 54 61 62 6c 65 4e 61 6d 65 3b 20 20 20 20 20 20  TableName;      
0800: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20   /* Name of the 
0810: 72 65 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20 20  real table */.  
0820: 63 68 61 72 20 2a 7a 4c 6f 67 4e 61 6d 65 3b 20  char *zLogName; 
0830: 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20          /* Name 
0840: 6f 66 20 74 68 65 20 6c 6f 67 20 74 61 62 6c 65  of the log table
0850: 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 3b 20   */.  int nCol; 
0860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0870: 20 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d   Number of colum
0880: 6e 73 20 69 6e 20 74 68 65 20 72 65 61 6c 20 74  ns in the real t
0890: 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 61  able */.  int *a
08a0: 49 6e 64 65 78 3b 20 20 20 20 20 20 20 20 20 20  Index;          
08b0: 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 73 69    /* Array of si
08c0: 7a 65 20 6e 43 6f 6c 2e 20 54 72 75 65 20 69 66  ze nCol. True if
08d0: 20 63 6f 6c 75 6d 6e 20 68 61 73 20 61 6e 20 69   column has an i
08e0: 6e 64 65 78 20 2a 2f 0a 20 20 63 68 61 72 20 2a  ndex */.  char *
08f0: 2a 61 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20  *aCol;          
0900: 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 73 69    /* Array of si
0910: 7a 65 20 6e 43 6f 6c 2e 20 43 6f 6c 75 6d 6e 20  ze nCol. Column 
0920: 6e 61 6d 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20  names */.};../* 
0930: 41 6e 20 65 63 68 6f 20 63 75 72 73 6f 72 20 6f  An echo cursor o
0940: 62 6a 65 63 74 20 2a 2f 0a 73 74 72 75 63 74 20  bject */.struct 
0950: 65 63 68 6f 5f 63 75 72 73 6f 72 20 7b 0a 20 20  echo_cursor {.  
0960: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
0970: 73 6f 72 20 62 61 73 65 3b 0a 20 20 73 71 6c 69  sor base;.  sqli
0980: 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b  te3_stmt *pStmt;
0990: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 72 69  .};../*.** Retri
09a0: 65 76 65 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e  eve the column n
09b0: 61 6d 65 73 20 66 6f 72 20 74 68 65 20 74 61 62  ames for the tab
09c0: 6c 65 20 6e 61 6d 65 64 20 7a 54 61 62 20 76 69  le named zTab vi
09d0: 61 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 63 6f  a database.** co
09e0: 6e 6e 65 63 74 69 6f 6e 20 64 62 2e 20 53 51 4c  nnection db. SQL
09f0: 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e  ITE_OK is return
0a00: 65 64 20 6f 6e 20 73 75 63 63 65 73 73 2c 20 6f  ed on success, o
0a10: 72 20 61 6e 20 73 71 6c 69 74 65 20 65 72 72 6f  r an sqlite erro
0a20: 72 0a 2a 2a 20 63 6f 64 65 20 6f 74 68 65 72 77  r.** code otherw
0a30: 69 73 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75  ise..**.** If su
0a40: 63 63 65 73 73 66 75 6c 2c 20 74 68 65 20 6e 75  ccessful, the nu
0a50: 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20  mber of columns 
0a60: 69 73 20 77 72 69 74 74 65 6e 20 74 6f 20 2a 70  is written to *p
0a70: 6e 43 6f 6c 2e 20 2a 70 61 43 6f 6c 20 69 73 0a  nCol. *paCol is.
0a80: 2a 2a 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20  ** set to point 
0a90: 61 74 20 73 71 6c 69 74 65 4d 61 6c 6c 6f 63 28  at sqliteMalloc(
0aa0: 29 27 64 20 73 70 61 63 65 20 63 6f 6e 74 61 69  )'d space contai
0ab0: 6e 69 6e 67 20 74 68 65 20 61 72 72 61 79 20 6f  ning the array o
0ac0: 66 0a 2a 2a 20 6e 43 6f 6c 20 63 6f 6c 75 6d 6e  f.** nCol column
0ad0: 20 6e 61 6d 65 73 2e 20 54 68 65 20 63 61 6c 6c   names. The call
0ae0: 65 72 20 69 73 20 72 65 73 70 6f 6e 73 69 62 6c  er is responsibl
0af0: 65 20 66 6f 72 20 63 61 6c 6c 69 6e 67 20 73 71  e for calling sq
0b00: 6c 69 74 65 46 72 65 65 0a 2a 2a 20 6f 6e 20 2a  liteFree.** on *
0b10: 70 61 43 6f 6c 2e 0a 2a 2f 0a 73 74 61 74 69 63  paCol..*/.static
0b20: 20 69 6e 74 20 67 65 74 43 6f 6c 75 6d 6e 4e 61   int getColumnNa
0b30: 6d 65 73 28 0a 20 20 73 71 6c 69 74 65 33 20 2a  mes(.  sqlite3 *
0b40: 64 62 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61  db, .  const cha
0b50: 72 20 2a 7a 54 61 62 2c 0a 20 20 63 68 61 72 20  r *zTab,.  char 
0b60: 2a 2a 2a 70 61 43 6f 6c 2c 20 0a 20 20 69 6e 74  ***paCol, .  int
0b70: 20 2a 70 6e 43 6f 6c 0a 29 7b 0a 20 20 63 68 61   *pnCol.){.  cha
0b80: 72 20 2a 2a 61 43 6f 6c 20 3d 20 30 3b 0a 20 20  r **aCol = 0;.  
0b90: 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 73 71  char *zSql;.  sq
0ba0: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
0bb0: 74 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 20  t = 0;.  int rc 
0bc0: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
0bd0: 6e 74 20 6e 43 6f 6c 20 3d 20 30 3b 0a 0a 20 20  nt nCol = 0;..  
0be0: 2f 2a 20 50 72 65 70 61 72 65 20 74 68 65 20 73  /* Prepare the s
0bf0: 74 61 74 65 6d 65 6e 74 20 22 53 45 4c 45 43 54  tatement "SELECT
0c00: 20 2a 20 46 52 4f 4d 20 3c 74 62 6c 3e 22 2e 20   * FROM <tbl>". 
0c10: 54 68 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73  The column names
0c20: 0a 20 20 2a 2a 20 6f 66 20 74 68 65 20 72 65 73  .  ** of the res
0c30: 75 6c 74 20 73 65 74 20 6f 66 20 74 68 65 20 63  ult set of the c
0c40: 6f 6d 70 69 6c 65 64 20 53 45 4c 45 43 54 20 77  ompiled SELECT w
0c50: 69 6c 6c 20 62 65 20 74 68 65 20 73 61 6d 65 20  ill be the same 
0c60: 61 73 0a 20 20 2a 2a 20 74 68 65 20 63 6f 6c 75  as.  ** the colu
0c70: 6d 6e 20 6e 61 6d 65 73 20 6f 66 20 74 61 62 6c  mn names of tabl
0c80: 65 20 3c 74 62 6c 3e 2e 0a 20 20 2a 2f 0a 20 20  e <tbl>..  */.  
0c90: 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50  zSql = sqlite3MP
0ca0: 72 69 6e 74 66 28 22 53 45 4c 45 43 54 20 2a 20  rintf("SELECT * 
0cb0: 46 52 4f 4d 20 25 51 22 2c 20 7a 54 61 62 29 3b  FROM %Q", zTab);
0cc0: 0a 20 20 69 66 28 20 21 7a 53 71 6c 20 29 7b 0a  .  if( !zSql ){.
0cd0: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
0ce0: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 67 6f 74 6f 20  NOMEM;.    goto 
0cf0: 6f 75 74 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20  out;.  }.  rc = 
0d00: 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28  sqlite3_prepare(
0d10: 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70  db, zSql, -1, &p
0d20: 53 74 6d 74 2c 20 30 29 3b 0a 20 20 73 71 6c 69  Stmt, 0);.  sqli
0d30: 74 65 46 72 65 65 28 7a 53 71 6c 29 3b 0a 0a 20  teFree(zSql);.. 
0d40: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
0d50: 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 69  OK ){.    int ii
0d60: 3b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 73  ;.    int nBytes
0d70: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 70 61  ;.    char *zSpa
0d80: 63 65 3b 0a 20 20 20 20 6e 43 6f 6c 20 3d 20 73  ce;.    nCol = s
0d90: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 63 6f  qlite3_column_co
0da0: 75 6e 74 28 70 53 74 6d 74 29 3b 0a 0a 20 20 20  unt(pStmt);..   
0db0: 20 2f 2a 20 46 69 67 75 72 65 20 6f 75 74 20 68   /* Figure out h
0dc0: 6f 77 20 6d 75 63 68 20 73 70 61 63 65 20 74 6f  ow much space to
0dd0: 20 61 6c 6c 6f 63 61 74 65 20 66 6f 72 20 74 68   allocate for th
0de0: 65 20 61 72 72 61 79 20 6f 66 20 63 6f 6c 75 6d  e array of colum
0df0: 6e 20 6e 61 6d 65 73 20 0a 20 20 20 20 2a 2a 20  n names .    ** 
0e00: 28 69 6e 63 6c 75 64 69 6e 67 20 73 70 61 63 65  (including space
0e10: 20 66 6f 72 20 74 68 65 20 73 74 72 69 6e 67 73   for the strings
0e20: 20 74 68 65 6d 73 65 6c 76 65 73 29 2e 20 54 68   themselves). Th
0e30: 65 6e 20 61 6c 6c 6f 63 61 74 65 20 69 74 2e 0a  en allocate it..
0e40: 20 20 20 20 2a 2f 0a 20 20 20 20 6e 42 79 74 65      */.    nByte
0e50: 73 20 3d 20 73 69 7a 65 6f 66 28 63 68 61 72 20  s = sizeof(char 
0e60: 2a 29 20 2a 20 6e 43 6f 6c 3b 0a 20 20 20 20 66  *) * nCol;.    f
0e70: 6f 72 28 69 69 3d 30 3b 20 69 69 3c 6e 43 6f 6c  or(ii=0; ii<nCol
0e80: 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20 6e  ; ii++){.      n
0e90: 42 79 74 65 73 20 2b 3d 20 28 73 74 72 6c 65 6e  Bytes += (strlen
0ea0: 28 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f  (sqlite3_column_
0eb0: 6e 61 6d 65 28 70 53 74 6d 74 2c 20 69 69 29 29  name(pStmt, ii))
0ec0: 20 2b 20 31 29 3b 0a 20 20 20 20 7d 0a 20 20 20   + 1);.    }.   
0ed0: 20 61 43 6f 6c 20 3d 20 28 63 68 61 72 20 2a 2a   aCol = (char **
0ee0: 29 73 71 6c 69 74 65 4d 61 6c 6c 6f 63 28 6e 42  )sqliteMalloc(nB
0ef0: 79 74 65 73 29 3b 0a 20 20 20 20 69 66 28 20 21  ytes);.    if( !
0f00: 61 43 6f 6c 20 29 7b 0a 20 20 20 20 20 20 72 63  aCol ){.      rc
0f10: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
0f20: 0a 20 20 20 20 20 20 67 6f 74 6f 20 6f 75 74 3b  .      goto out;
0f30: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 43  .    }..    /* C
0f40: 6f 70 79 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e  opy the column n
0f50: 61 6d 65 73 20 69 6e 74 6f 20 74 68 65 20 61 6c  ames into the al
0f60: 6c 6f 63 61 74 65 64 20 73 70 61 63 65 20 61 6e  located space an
0f70: 64 20 73 65 74 20 75 70 20 74 68 65 0a 20 20 20  d set up the.   
0f80: 20 2a 2a 20 70 6f 69 6e 74 65 72 73 20 69 6e 20   ** pointers in 
0f90: 74 68 65 20 61 43 6f 6c 5b 5d 20 61 72 72 61 79  the aCol[] array
0fa0: 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 7a 53 70  ..    */.    zSp
0fb0: 61 63 65 20 3d 20 28 63 68 61 72 20 2a 29 28 26  ace = (char *)(&
0fc0: 61 43 6f 6c 5b 6e 43 6f 6c 5d 29 3b 0a 20 20 20  aCol[nCol]);.   
0fd0: 20 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c 6e 43   for(ii=0; ii<nC
0fe0: 6f 6c 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20  ol; ii++){.     
0ff0: 20 61 43 6f 6c 5b 69 69 5d 20 3d 20 7a 53 70 61   aCol[ii] = zSpa
1000: 63 65 3b 0a 20 20 20 20 20 20 7a 53 70 61 63 65  ce;.      zSpace
1010: 20 2b 3d 20 73 70 72 69 6e 74 66 28 7a 53 70 61   += sprintf(zSpa
1020: 63 65 2c 20 22 25 73 22 2c 20 73 71 6c 69 74 65  ce, "%s", sqlite
1030: 33 5f 63 6f 6c 75 6d 6e 5f 6e 61 6d 65 28 70 53  3_column_name(pS
1040: 74 6d 74 2c 20 69 69 29 29 3b 0a 20 20 20 20 20  tmt, ii));.     
1050: 20 7a 53 70 61 63 65 2b 2b 3b 0a 20 20 20 20 7d   zSpace++;.    }
1060: 0a 20 20 20 20 61 73 73 65 72 74 28 20 28 7a 53  .    assert( (zS
1070: 70 61 63 65 2d 6e 42 79 74 65 73 29 3d 3d 28 63  pace-nBytes)==(c
1080: 68 61 72 20 2a 29 61 43 6f 6c 20 29 3b 0a 20 20  har *)aCol );.  
1090: 7d 0a 0a 20 20 2a 70 61 43 6f 6c 20 3d 20 61 43  }..  *paCol = aC
10a0: 6f 6c 3b 0a 20 20 2a 70 6e 43 6f 6c 20 3d 20 6e  ol;.  *pnCol = n
10b0: 43 6f 6c 3b 0a 0a 6f 75 74 3a 0a 20 20 73 71 6c  Col;..out:.  sql
10c0: 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53  ite3_finalize(pS
10d0: 74 6d 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  tmt);.  return r
10e0: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 72 61  c;.}../*.** Para
10f0: 6d 65 74 65 72 20 7a 54 61 62 20 69 73 20 74 68  meter zTab is th
1100: 65 20 6e 61 6d 65 20 6f 66 20 61 20 74 61 62 6c  e name of a tabl
1110: 65 20 69 6e 20 64 61 74 61 62 61 73 65 20 64 62  e in database db
1120: 20 77 69 74 68 20 6e 43 6f 6c 20 0a 2a 2a 20 63   with nCol .** c
1130: 6f 6c 75 6d 6e 73 2e 20 54 68 69 73 20 66 75 6e  olumns. This fun
1140: 63 74 69 6f 6e 20 61 6c 6c 6f 63 61 74 65 73 20  ction allocates 
1150: 61 6e 20 61 72 72 61 79 20 6f 66 20 69 6e 74 65  an array of inte
1160: 67 65 72 73 20 6e 43 6f 6c 20 69 6e 20 0a 2a 2a  gers nCol in .**
1170: 20 73 69 7a 65 20 61 6e 64 20 70 6f 70 75 6c 61   size and popula
1180: 74 65 73 20 69 74 20 61 63 63 6f 72 64 69 6e 67  tes it according
1190: 20 74 6f 20 61 6e 79 20 69 6d 70 6c 69 63 69 74   to any implicit
11a0: 20 6f 72 20 65 78 70 6c 69 63 69 74 20 0a 2a 2a   or explicit .**
11b0: 20 69 6e 64 69 63 65 73 20 6f 6e 20 74 61 62 6c   indices on tabl
11c0: 65 20 7a 54 61 62 2e 0a 2a 2a 0a 2a 2a 20 49 66  e zTab..**.** If
11d0: 20 73 75 63 63 65 73 73 66 75 6c 2c 20 53 51 4c   successful, SQL
11e0: 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e  ITE_OK is return
11f0: 65 64 20 61 6e 64 20 2a 70 61 49 6e 64 65 78 20  ed and *paIndex 
1200: 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 0a 2a 2a  set to point .**
1210: 20 61 74 20 74 68 65 20 61 6c 6c 6f 63 61 74 65   at the allocate
1220: 64 20 61 72 72 61 79 2e 20 4f 74 68 65 72 77 69  d array. Otherwi
1230: 73 65 2c 20 61 6e 20 65 72 72 6f 72 20 63 6f 64  se, an error cod
1240: 65 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a  e is returned..*
1250: 2a 0a 2a 2a 20 53 65 65 20 63 6f 6d 6d 65 6e 74  *.** See comment
1260: 73 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74  s associated wit
1270: 68 20 74 68 65 20 6d 65 6d 62 65 72 20 76 61 72  h the member var
1280: 69 61 62 6c 65 20 61 49 6e 64 65 78 20 61 62 6f  iable aIndex abo
1290: 76 65 20 0a 2a 2a 20 22 73 74 72 75 63 74 20 65  ve .** "struct e
12a0: 63 68 6f 5f 76 74 61 62 22 20 66 6f 72 20 64 65  cho_vtab" for de
12b0: 74 61 69 6c 73 20 6f 66 20 74 68 65 20 63 6f 6e  tails of the con
12c0: 74 65 6e 74 73 20 6f 66 20 74 68 65 20 61 72 72  tents of the arr
12d0: 61 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ay..*/.static in
12e0: 74 20 67 65 74 49 6e 64 65 78 41 72 72 61 79 28  t getIndexArray(
12f0: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  .  sqlite3 *db, 
1300: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
1310: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
1320: 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  on */.  const ch
1330: 61 72 20 2a 7a 54 61 62 2c 20 20 20 20 20 20 20  ar *zTab,       
1340: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 61 62 6c   /* Name of tabl
1350: 65 20 69 6e 20 64 61 74 61 62 61 73 65 20 64 62  e in database db
1360: 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c 0a   */.  int nCol,.
1370: 20 20 69 6e 74 20 2a 2a 70 61 49 6e 64 65 78 0a    int **paIndex.
1380: 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  ){.  sqlite3_stm
1390: 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20  t *pStmt = 0;.  
13a0: 69 6e 74 20 2a 61 49 6e 64 65 78 20 3d 20 30 3b  int *aIndex = 0;
13b0: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 63 68 61  .  int rc;.  cha
13c0: 72 20 2a 7a 53 71 6c 3b 0a 0a 20 20 2f 2a 20 41  r *zSql;..  /* A
13d0: 6c 6c 6f 63 61 74 65 20 73 70 61 63 65 20 66 6f  llocate space fo
13e0: 72 20 74 68 65 20 69 6e 64 65 78 20 61 72 72 61  r the index arra
13f0: 79 20 2a 2f 0a 20 20 61 49 6e 64 65 78 20 3d 20  y */.  aIndex = 
1400: 28 69 6e 74 20 2a 29 73 71 6c 69 74 65 4d 61 6c  (int *)sqliteMal
1410: 6c 6f 63 28 73 69 7a 65 6f 66 28 69 6e 74 29 20  loc(sizeof(int) 
1420: 2a 20 6e 43 6f 6c 29 3b 0a 20 20 69 66 28 20 21  * nCol);.  if( !
1430: 61 49 6e 64 65 78 20 29 7b 0a 20 20 20 20 72 63  aIndex ){.    rc
1440: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
1450: 0a 20 20 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e  .    goto get_in
1460: 64 65 78 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20  dex_array_out;. 
1470: 20 7d 0a 0a 20 20 2f 2a 20 43 6f 6d 70 69 6c 65   }..  /* Compile
1480: 20 61 6e 20 73 71 6c 69 74 65 20 70 72 61 67 6d   an sqlite pragm
1490: 61 20 74 6f 20 6c 6f 6f 70 20 74 68 72 6f 75 67  a to loop throug
14a0: 68 20 61 6c 6c 20 69 6e 64 69 63 65 73 20 6f 6e  h all indices on
14b0: 20 74 61 62 6c 65 20 7a 54 61 62 20 2a 2f 0a 20   table zTab */. 
14c0: 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d   zSql = sqlite3M
14d0: 50 72 69 6e 74 66 28 22 50 52 41 47 4d 41 20 69  Printf("PRAGMA i
14e0: 6e 64 65 78 5f 6c 69 73 74 28 25 73 29 22 2c 20  ndex_list(%s)", 
14f0: 7a 54 61 62 29 3b 0a 20 20 69 66 28 20 21 7a 53  zTab);.  if( !zS
1500: 71 6c 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  ql ){.    rc = S
1510: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
1520: 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78 5f   goto get_index_
1530: 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20 7d 0a 20  array_out;.  }. 
1540: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72   rc = sqlite3_pr
1550: 65 70 61 72 65 28 64 62 2c 20 7a 53 71 6c 2c 20  epare(db, zSql, 
1560: 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a  -1, &pStmt, 0);.
1570: 20 20 73 71 6c 69 74 65 46 72 65 65 28 7a 53 71    sqliteFree(zSq
1580: 6c 29 3b 0a 0a 20 20 2f 2a 20 46 6f 72 20 65 61  l);..  /* For ea
1590: 63 68 20 69 6e 64 65 78 2c 20 66 69 67 75 72 65  ch index, figure
15a0: 20 6f 75 74 20 74 68 65 20 6c 65 66 74 2d 6d 6f   out the left-mo
15b0: 73 74 20 63 6f 6c 75 6d 6e 20 61 6e 64 20 73 65  st column and se
15c0: 74 20 74 68 65 20 0a 20 20 2a 2a 20 63 6f 72 72  t the .  ** corr
15d0: 65 73 70 6f 6e 64 69 6e 67 20 65 6e 74 72 79 20  esponding entry 
15e0: 69 6e 20 61 49 6e 64 65 78 5b 5d 20 74 6f 20 31  in aIndex[] to 1
15f0: 2e 0a 20 20 2a 2f 0a 20 20 77 68 69 6c 65 28 20  ..  */.  while( 
1600: 70 53 74 6d 74 20 26 26 20 73 71 6c 69 74 65 33  pStmt && sqlite3
1610: 5f 73 74 65 70 28 70 53 74 6d 74 29 3d 3d 53 51  _step(pStmt)==SQ
1620: 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20  LITE_ROW ){.    
1630: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 49 64 78  const char *zIdx
1640: 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d   = sqlite3_colum
1650: 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 20 31 29  n_text(pStmt, 1)
1660: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74  ;.    sqlite3_st
1670: 6d 74 20 2a 70 53 74 6d 74 32 20 3d 20 30 3b 0a  mt *pStmt2 = 0;.
1680: 20 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74      zSql = sqlit
1690: 65 33 4d 50 72 69 6e 74 66 28 22 50 52 41 47 4d  e3MPrintf("PRAGM
16a0: 41 20 69 6e 64 65 78 5f 69 6e 66 6f 28 25 73 29  A index_info(%s)
16b0: 22 2c 20 7a 49 64 78 29 3b 0a 20 20 20 20 69 66  ", zIdx);.    if
16c0: 28 20 21 7a 53 71 6c 20 29 7b 0a 20 20 20 20 20  ( !zSql ){.     
16d0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
16e0: 45 4d 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 67  EM;.      goto g
16f0: 65 74 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f  et_index_array_o
1700: 75 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 63  ut;.    }.    rc
1710: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
1720: 72 65 28 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c  re(db, zSql, -1,
1730: 20 26 70 53 74 6d 74 32 2c 20 30 29 3b 0a 20 20   &pStmt2, 0);.  
1740: 20 20 73 71 6c 69 74 65 46 72 65 65 28 7a 53 71    sqliteFree(zSq
1750: 6c 29 3b 0a 20 20 20 20 69 66 28 20 70 53 74 6d  l);.    if( pStm
1760: 74 32 20 26 26 20 73 71 6c 69 74 65 33 5f 73 74  t2 && sqlite3_st
1770: 65 70 28 70 53 74 6d 74 32 29 3d 3d 53 51 4c 49  ep(pStmt2)==SQLI
1780: 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20  TE_ROW ){.      
1790: 69 6e 74 20 63 69 64 20 3d 20 73 71 6c 69 74 65  int cid = sqlite
17a0: 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53 74  3_column_int(pSt
17b0: 6d 74 32 2c 20 31 29 3b 0a 20 20 20 20 20 20 61  mt2, 1);.      a
17c0: 73 73 65 72 74 28 20 63 69 64 3e 3d 30 20 26 26  ssert( cid>=0 &&
17d0: 20 63 69 64 3c 6e 43 6f 6c 20 29 3b 0a 20 20 20   cid<nCol );.   
17e0: 20 20 20 61 49 6e 64 65 78 5b 63 69 64 5d 20 3d     aIndex[cid] =
17f0: 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66   1;.    }.    if
1800: 28 20 70 53 74 6d 74 32 20 29 7b 0a 20 20 20 20  ( pStmt2 ){.    
1810: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66    rc = sqlite3_f
1820: 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 32 29 3b  inalize(pStmt2);
1830: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72  .    }.    if( r
1840: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
1850: 20 20 20 20 20 20 67 6f 74 6f 20 67 65 74 5f 69        goto get_i
1860: 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75 74 3b 0a  ndex_array_out;.
1870: 20 20 20 20 7d 0a 20 20 7d 0a 0a 0a 67 65 74 5f      }.  }...get_
1880: 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75 74 3a  index_array_out:
1890: 0a 20 20 69 66 28 20 70 53 74 6d 74 20 29 7b 0a  .  if( pStmt ){.
18a0: 20 20 20 20 69 6e 74 20 72 63 32 20 3d 20 73 71      int rc2 = sq
18b0: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
18c0: 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20 72  Stmt);.    if( r
18d0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
18e0: 20 20 20 20 20 20 72 63 20 3d 20 72 63 32 3b 0a        rc = rc2;.
18f0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20      }.  }.  if( 
1900: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
1910: 0a 20 20 20 20 73 71 6c 69 74 65 46 72 65 65 28  .    sqliteFree(
1920: 61 49 6e 64 65 78 29 3b 0a 20 20 20 20 61 49 6e  aIndex);.    aIn
1930: 64 65 78 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 2a  dex = 0;.  }.  *
1940: 70 61 49 6e 64 65 78 20 3d 20 61 49 6e 64 65 78  paIndex = aIndex
1950: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
1960: 0a 0a 2f 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20 54  ../*.** Global T
1970: 63 6c 20 76 61 72 69 61 62 6c 65 20 24 65 63 68  cl variable $ech
1980: 6f 5f 6d 6f 64 75 6c 65 20 69 73 20 61 20 6c 69  o_module is a li
1990: 73 74 2e 20 54 68 69 73 20 72 6f 75 74 69 6e 65  st. This routine
19a0: 20 61 70 70 65 6e 64 73 0a 2a 2a 20 74 68 65 20   appends.** the 
19b0: 73 74 72 69 6e 67 20 65 6c 65 6d 65 6e 74 20 7a  string element z
19c0: 41 72 67 20 74 6f 20 74 68 61 74 20 6c 69 73 74  Arg to that list
19d0: 20 69 6e 20 69 6e 74 65 72 70 72 65 74 65 72 20   in interpreter 
19e0: 69 6e 74 65 72 70 2e 0a 2a 2f 0a 73 74 61 74 69  interp..*/.stati
19f0: 63 20 76 6f 69 64 20 61 70 70 65 6e 64 54 6f 45  c void appendToE
1a00: 63 68 6f 4d 6f 64 75 6c 65 28 54 63 6c 5f 49 6e  choModule(Tcl_In
1a10: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 63 6f  terp *interp, co
1a20: 6e 73 74 20 63 68 61 72 20 2a 7a 41 72 67 29 7b  nst char *zArg){
1a30: 0a 20 20 69 6e 74 20 66 6c 61 67 73 20 3d 20 28  .  int flags = (
1a40: 54 43 4c 5f 41 50 50 45 4e 44 5f 56 41 4c 55 45  TCL_APPEND_VALUE
1a50: 20 7c 20 54 43 4c 5f 4c 49 53 54 5f 45 4c 45 4d   | TCL_LIST_ELEM
1a60: 45 4e 54 20 7c 20 54 43 4c 5f 47 4c 4f 42 41 4c  ENT | TCL_GLOBAL
1a70: 5f 4f 4e 4c 59 29 3b 0a 20 20 54 63 6c 5f 53 65  _ONLY);.  Tcl_Se
1a80: 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65 63  tVar(interp, "ec
1a90: 68 6f 5f 6d 6f 64 75 6c 65 22 2c 20 28 7a 41 72  ho_module", (zAr
1aa0: 67 3f 7a 41 72 67 3a 22 22 29 2c 20 66 6c 61 67  g?zArg:""), flag
1ab0: 73 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  s);.}../*.** Thi
1ac0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
1ad0: 6c 6c 65 64 20 66 72 6f 6d 20 77 69 74 68 69 6e  lled from within
1ae0: 20 74 68 65 20 65 63 68 6f 2d 6d 6f 64 75 6c 65   the echo-module
1af0: 73 20 78 43 72 65 61 74 65 20 61 6e 64 0a 2a 2a  s xCreate and.**
1b00: 20 78 43 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64   xConnect method
1b10: 73 2e 20 54 68 65 20 61 72 67 63 20 61 6e 64 20  s. The argc and 
1b20: 61 72 67 76 20 61 72 67 75 6d 65 6e 74 73 20 61  argv arguments a
1b30: 72 65 20 63 6f 70 69 65 73 20 6f 66 20 74 68 6f  re copies of tho
1b40: 73 65 20 0a 2a 2a 20 70 61 73 73 65 64 20 74 6f  se .** passed to
1b50: 20 74 68 65 20 63 61 6c 6c 69 6e 67 20 6d 65 74   the calling met
1b60: 68 6f 64 2e 20 54 68 69 73 20 66 75 6e 63 74 69  hod. This functi
1b70: 6f 6e 20 69 73 20 72 65 73 70 6f 6e 73 69 62 6c  on is responsibl
1b80: 65 20 66 6f 72 0a 2a 2a 20 63 61 6c 6c 69 6e 67  e for.** calling
1b90: 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65   sqlite3_declare
1ba0: 5f 76 74 61 62 28 29 20 74 6f 20 64 65 63 6c 61  _vtab() to decla
1bb0: 72 65 20 74 68 65 20 73 63 68 65 6d 61 20 6f 66  re the schema of
1bc0: 20 74 68 65 20 76 69 72 74 75 61 6c 0a 2a 2a 20   the virtual.** 
1bd0: 74 61 62 6c 65 20 62 65 69 6e 67 20 63 72 65 61  table being crea
1be0: 74 65 64 20 6f 72 20 63 6f 6e 6e 65 63 74 65 64  ted or connected
1bf0: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 63  ..**.** If the c
1c00: 6f 6e 73 74 72 75 63 74 6f 72 20 77 61 73 20 70  onstructor was p
1c10: 61 73 73 65 64 20 6a 75 73 74 20 6f 6e 65 20 61  assed just one a
1c20: 72 67 75 6d 65 6e 74 2c 20 69 2e 65 2e 3a 0a 2a  rgument, i.e.:.*
1c30: 2a 0a 2a 2a 20 20 20 43 52 45 41 54 45 20 54 41  *.**   CREATE TA
1c40: 42 4c 45 20 74 31 20 41 53 20 65 63 68 6f 28 74  BLE t1 AS echo(t
1c50: 32 29 3b 0a 2a 2a 0a 2a 2a 20 54 68 65 6e 20 74  2);.**.** Then t
1c60: 32 20 69 73 20 61 73 73 75 6d 65 64 20 74 6f 20  2 is assumed to 
1c70: 62 65 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 61  be the name of a
1c80: 20 2a 72 65 61 6c 2a 20 64 61 74 61 62 61 73 65   *real* database
1c90: 20 74 61 62 6c 65 2e 20 54 68 65 0a 2a 2a 20 73   table. The.** s
1ca0: 63 68 65 6d 61 20 6f 66 20 74 68 65 20 76 69 72  chema of the vir
1cb0: 74 75 61 6c 20 74 61 62 6c 65 20 69 73 20 64 65  tual table is de
1cc0: 63 6c 61 72 65 64 20 62 79 20 70 61 73 73 69 6e  clared by passin
1cd0: 67 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20  g a copy of the 
1ce0: 0a 2a 2a 20 43 52 45 41 54 45 20 54 41 42 4c 45  .** CREATE TABLE
1cf0: 20 73 74 61 74 65 6d 65 6e 74 20 66 6f 72 20 74   statement for t
1d00: 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20 74 6f  he real table to
1d10: 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65   sqlite3_declare
1d20: 5f 76 74 61 62 28 29 2e 0a 2a 2a 20 48 65 6e 63  _vtab()..** Henc
1d30: 65 2c 20 74 68 65 20 76 69 72 74 75 61 6c 20 74  e, the virtual t
1d40: 61 62 6c 65 20 73 68 6f 75 6c 64 20 68 61 76 65  able should have
1d50: 20 65 78 61 63 74 6c 79 20 74 68 65 20 73 61 6d   exactly the sam
1d60: 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 61  e column names a
1d70: 6e 64 20 0a 2a 2a 20 74 79 70 65 73 20 61 73 20  nd .** types as 
1d80: 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 2e 0a  the real table..
1d90: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
1da0: 68 6f 44 65 63 6c 61 72 65 56 74 61 62 28 0a 20  hoDeclareVtab(. 
1db0: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
1dc0: 62 2c 20 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  b, .  sqlite3 *d
1dd0: 62 2c 20 0a 20 20 69 6e 74 20 61 72 67 63 2c 20  b, .  int argc, 
1de0: 0a 20 20 63 68 61 72 20 2a 2a 61 72 67 76 0a 29  .  char **argv.)
1df0: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
1e00: 49 54 45 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 61  ITE_OK;..  if( a
1e10: 72 67 63 3e 3d 34 20 29 7b 0a 20 20 20 20 73 71  rgc>=4 ){.    sq
1e20: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
1e30: 74 20 3d 20 30 3b 0a 20 20 20 20 73 71 6c 69 74  t = 0;.    sqlit
1e40: 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c 20 0a  e3_prepare(db, .
1e50: 20 20 20 20 20 20 20 20 22 53 45 4c 45 43 54 20          "SELECT 
1e60: 73 71 6c 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f  sql FROM sqlite_
1e70: 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70  master WHERE typ
1e80: 65 20 3d 20 27 74 61 62 6c 65 27 20 41 4e 44 20  e = 'table' AND 
1e90: 6e 61 6d 65 20 3d 20 3f 22 2c 0a 20 20 20 20 20  name = ?",.     
1ea0: 20 20 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30     -1, &pStmt, 0
1eb0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 62  );.    sqlite3_b
1ec0: 69 6e 64 5f 74 65 78 74 28 70 53 74 6d 74 2c 20  ind_text(pStmt, 
1ed0: 31 2c 20 61 72 67 76 5b 33 5d 2c 20 2d 31 2c 20  1, argv[3], -1, 
1ee0: 30 29 3b 0a 20 20 20 20 69 66 28 20 73 71 6c 69  0);.    if( sqli
1ef0: 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 3d  te3_step(pStmt)=
1f00: 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20  =SQLITE_ROW ){. 
1f10: 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20       const char 
1f20: 2a 7a 43 72 65 61 74 65 54 61 62 6c 65 20 3d 20  *zCreateTable = 
1f30: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74  sqlite3_column_t
1f40: 65 78 74 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20  ext(pStmt, 0);. 
1f50: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 64 65 63       sqlite3_dec
1f60: 6c 61 72 65 5f 76 74 61 62 28 64 62 2c 20 7a 43  lare_vtab(db, zC
1f70: 72 65 61 74 65 54 61 62 6c 65 29 3b 0a 20 20 20  reateTable);.   
1f80: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
1f90: 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b  finalize(pStmt);
1fa0: 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  .    } else {.  
1fb0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
1fc0: 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29  _finalize(pStmt)
1fd0: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ;.      if( rc==
1fe0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 20 0a 20 20  SQLITE_OK ){ .  
1ff0: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
2000: 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d  E_ERROR;.      }
2010: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20  .    }..    if( 
2020: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
2030: 0a 20 20 20 20 20 20 72 63 20 3d 20 67 65 74 43  .      rc = getC
2040: 6f 6c 75 6d 6e 4e 61 6d 65 73 28 64 62 2c 20 61  olumnNames(db, a
2050: 72 67 76 5b 33 5d 2c 20 26 70 56 74 61 62 2d 3e  rgv[3], &pVtab->
2060: 61 43 6f 6c 2c 20 26 70 56 74 61 62 2d 3e 6e 43  aCol, &pVtab->nC
2070: 6f 6c 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  ol);.    }.    i
2080: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
2090: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 67   ){.      rc = g
20a0: 65 74 49 6e 64 65 78 41 72 72 61 79 28 64 62 2c  etIndexArray(db,
20b0: 20 61 72 67 76 5b 33 5d 2c 20 70 56 74 61 62 2d   argv[3], pVtab-
20c0: 3e 6e 43 6f 6c 2c 20 26 70 56 74 61 62 2d 3e 61  >nCol, &pVtab->a
20d0: 49 6e 64 65 78 29 3b 0a 20 20 20 20 7d 0a 20 20  Index);.    }.  
20e0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
20f0: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
2100: 6e 63 74 69 6f 6e 20 66 72 65 65 73 20 61 6c 6c  nction frees all
2110: 20 72 75 6e 74 69 6d 65 20 73 74 72 75 63 74 75   runtime structu
2120: 72 65 73 20 61 73 73 6f 63 69 61 74 65 64 20 77  res associated w
2130: 69 74 68 20 74 68 65 20 76 69 72 74 75 61 6c 0a  ith the virtual.
2140: 2a 2a 20 74 61 62 6c 65 20 70 56 74 61 62 2e 0a  ** table pVtab..
2150: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
2160: 68 6f 44 65 73 74 72 75 63 74 6f 72 28 73 71 6c  hoDestructor(sql
2170: 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62  ite3_vtab *pVtab
2180: 29 7b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  ){.  echo_vtab *
2190: 70 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 2a 29  p = (echo_vtab*)
21a0: 70 56 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 46  pVtab;.  sqliteF
21b0: 72 65 65 28 70 2d 3e 61 49 6e 64 65 78 29 3b 0a  ree(p->aIndex);.
21c0: 20 20 73 71 6c 69 74 65 46 72 65 65 28 70 2d 3e    sqliteFree(p->
21d0: 61 43 6f 6c 29 3b 0a 20 20 73 71 6c 69 74 65 46  aCol);.  sqliteF
21e0: 72 65 65 28 70 2d 3e 7a 54 61 62 6c 65 4e 61 6d  ree(p->zTableNam
21f0: 65 29 3b 0a 20 20 73 71 6c 69 74 65 46 72 65 65  e);.  sqliteFree
2200: 28 70 2d 3e 7a 4c 6f 67 4e 61 6d 65 29 3b 0a 20  (p->zLogName);. 
2210: 20 73 71 6c 69 74 65 46 72 65 65 28 70 29 3b 0a   sqliteFree(p);.
2220: 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f    return 0;.}../
2230: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
2240: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20  on is called to 
2250: 64 6f 20 74 68 65 20 77 6f 72 6b 20 6f 66 20 74  do the work of t
2260: 68 65 20 78 43 6f 6e 6e 65 63 74 28 29 20 6d 65  he xConnect() me
2270: 74 68 6f 64 20 2d 0a 2a 2a 20 74 6f 20 61 6c 6c  thod -.** to all
2280: 6f 63 61 74 65 20 74 68 65 20 72 65 71 75 69 72  ocate the requir
2290: 65 64 20 69 6e 2d 6d 65 6d 6f 72 79 20 73 74 72  ed in-memory str
22a0: 75 63 74 75 72 65 73 20 66 6f 72 20 61 20 6e 65  uctures for a ne
22b0: 77 6c 79 20 63 6f 6e 6e 65 63 74 65 64 0a 2a 2a  wly connected.**
22c0: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 0a   virtual table..
22d0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
22e0: 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28 0a 20  hoConstructor(. 
22f0: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20   sqlite3 *db,.  
2300: 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e  void *pAux,.  in
2310: 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a 61  t argc, char **a
2320: 72 67 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76  rgv,.  sqlite3_v
2330: 74 61 62 20 2a 2a 70 70 56 74 61 62 0a 29 7b 0a  tab **ppVtab.){.
2340: 20 20 69 6e 74 20 69 3b 0a 20 20 65 63 68 6f 5f    int i;.  echo_
2350: 76 74 61 62 20 2a 70 56 74 61 62 3b 0a 0a 20 20  vtab *pVtab;..  
2360: 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74 68 65 20  /* Allocate the 
2370: 73 71 6c 69 74 65 33 5f 76 74 61 62 2f 65 63 68  sqlite3_vtab/ech
2380: 6f 5f 76 74 61 62 20 73 74 72 75 63 74 75 72 65  o_vtab structure
2390: 20 69 74 73 65 6c 66 20 2a 2f 0a 20 20 70 56 74   itself */.  pVt
23a0: 61 62 20 3d 20 73 71 6c 69 74 65 4d 61 6c 6c 6f  ab = sqliteMallo
23b0: 63 28 20 73 69 7a 65 6f 66 28 2a 70 56 74 61 62  c( sizeof(*pVtab
23c0: 29 20 29 3b 0a 20 20 69 66 28 20 21 70 56 74 61  ) );.  if( !pVta
23d0: 62 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  b ){.    return 
23e0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
23f0: 7d 0a 20 20 70 56 74 61 62 2d 3e 69 6e 74 65 72  }.  pVtab->inter
2400: 70 20 3d 20 28 54 63 6c 5f 49 6e 74 65 72 70 20  p = (Tcl_Interp 
2410: 2a 29 70 41 75 78 3b 0a 20 20 70 56 74 61 62 2d  *)pAux;.  pVtab-
2420: 3e 64 62 20 3d 20 64 62 3b 0a 0a 20 20 2f 2a 20  >db = db;..  /* 
2430: 41 6c 6c 6f 63 61 74 65 20 65 63 68 6f 5f 76 74  Allocate echo_vt
2440: 61 62 2e 7a 54 61 62 6c 65 4e 61 6d 65 20 2a 2f  ab.zTableName */
2450: 0a 20 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65  .  pVtab->zTable
2460: 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 4d 50  Name = sqlite3MP
2470: 72 69 6e 74 66 28 22 25 73 22 2c 20 61 72 67 76  rintf("%s", argv
2480: 5b 33 5d 29 3b 0a 20 20 69 66 28 20 21 70 56 74  [3]);.  if( !pVt
2490: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 29  ab->zTableName )
24a0: 7b 0a 20 20 20 20 65 63 68 6f 44 65 73 74 72 75  {.    echoDestru
24b0: 63 74 6f 72 28 28 73 71 6c 69 74 65 33 5f 76 74  ctor((sqlite3_vt
24c0: 61 62 20 2a 29 70 56 74 61 62 29 3b 0a 20 20 20  ab *)pVtab);.   
24d0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
24e0: 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  OMEM;.  }..  /* 
24f0: 4c 6f 67 20 74 68 65 20 61 72 67 75 6d 65 6e 74  Log the argument
2500: 73 20 74 6f 20 74 68 69 73 20 66 75 6e 63 74 69  s to this functi
2510: 6f 6e 20 74 6f 20 54 63 6c 20 76 61 72 20 3a 3a  on to Tcl var ::
2520: 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 2a 2f 0a 20  echo_module */. 
2530: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 61 72 67 63   for(i=0; i<argc
2540: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 61 70 70 65  ; i++){.    appe
2550: 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70  ndToEchoModule(p
2560: 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 61 72  Vtab->interp, ar
2570: 67 76 5b 69 5d 29 3b 0a 20 20 7d 0a 0a 20 20 2f  gv[i]);.  }..  /
2580: 2a 20 49 6e 76 6f 6b 65 20 73 71 6c 69 74 65 33  * Invoke sqlite3
2590: 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 20 61 6e  _declare_vtab an
25a0: 64 20 73 65 74 20 75 70 20 6f 74 68 65 72 20 6d  d set up other m
25b0: 65 6d 62 65 72 73 20 6f 66 20 74 68 65 20 65 63  embers of the ec
25c0: 68 6f 5f 76 74 61 62 0a 20 20 2a 2a 20 73 74 72  ho_vtab.  ** str
25d0: 75 63 74 75 72 65 2e 20 49 66 20 61 6e 20 65 72  ucture. If an er
25e0: 72 6f 72 20 6f 63 63 75 72 73 2c 20 64 65 6c 65  ror occurs, dele
25f0: 74 65 20 74 68 65 20 73 71 6c 69 74 65 33 5f 76  te the sqlite3_v
2600: 74 61 62 20 73 74 72 75 63 74 75 72 65 20 61 6e  tab structure an
2610: 64 0a 20 20 2a 2a 20 72 65 74 75 72 6e 20 61 6e  d.  ** return an
2620: 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 20 20 2a   error code..  *
2630: 2f 0a 20 20 69 66 28 20 65 63 68 6f 44 65 63 6c  /.  if( echoDecl
2640: 61 72 65 56 74 61 62 28 70 56 74 61 62 2c 20 64  areVtab(pVtab, d
2650: 62 2c 20 61 72 67 63 2c 20 61 72 67 76 29 20 29  b, argc, argv) )
2660: 7b 0a 20 20 20 20 65 63 68 6f 44 65 73 74 72 75  {.    echoDestru
2670: 63 74 6f 72 28 28 73 71 6c 69 74 65 33 5f 76 74  ctor((sqlite3_vt
2680: 61 62 20 2a 29 70 56 74 61 62 29 3b 0a 20 20 20  ab *)pVtab);.   
2690: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45   return SQLITE_E
26a0: 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  RROR;.  }..  /* 
26b0: 53 75 63 63 65 73 73 2e 20 53 65 74 20 2a 70 70  Success. Set *pp
26c0: 56 74 61 62 20 61 6e 64 20 72 65 74 75 72 6e 20  Vtab and return 
26d0: 2a 2f 0a 20 20 2a 70 70 56 74 61 62 20 3d 20 26  */.  *ppVtab = &
26e0: 70 56 74 61 62 2d 3e 62 61 73 65 3b 0a 20 20 72  pVtab->base;.  r
26f0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
2700: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20  .}../* .** Echo 
2710: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f  virtual table mo
2720: 64 75 6c 65 20 78 43 72 65 61 74 65 20 6d 65 74  dule xCreate met
2730: 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  hod..*/.static i
2740: 6e 74 20 65 63 68 6f 43 72 65 61 74 65 28 0a 20  nt echoCreate(. 
2750: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20   sqlite3 *db,.  
2760: 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e  void *pAux,.  in
2770: 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a 61  t argc, char **a
2780: 72 67 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76  rgv,.  sqlite3_v
2790: 74 61 62 20 2a 2a 70 70 56 74 61 62 0a 29 7b 0a  tab **ppVtab.){.
27a0: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
27b0: 45 5f 4f 4b 3b 0a 20 20 61 70 70 65 6e 64 54 6f  E_OK;.  appendTo
27c0: 45 63 68 6f 4d 6f 64 75 6c 65 28 28 54 63 6c 5f  EchoModule((Tcl_
27d0: 49 6e 74 65 72 70 20 2a 29 28 70 41 75 78 29 2c  Interp *)(pAux),
27e0: 20 22 78 43 72 65 61 74 65 22 29 3b 0a 20 20 72   "xCreate");.  r
27f0: 63 20 3d 20 65 63 68 6f 43 6f 6e 73 74 72 75 63  c = echoConstruc
2800: 74 6f 72 28 64 62 2c 20 70 41 75 78 2c 20 61 72  tor(db, pAux, ar
2810: 67 63 2c 20 61 72 67 76 2c 20 70 70 56 74 61 62  gc, argv, ppVtab
2820: 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 72  );..  /* If ther
2830: 65 20 77 65 72 65 20 74 77 6f 20 61 72 67 75 6d  e were two argum
2840: 65 6e 74 73 20 70 61 73 73 65 64 20 74 6f 20 74  ents passed to t
2850: 68 65 20 6d 6f 64 75 6c 65 20 61 74 20 74 68 65  he module at the
2860: 20 53 51 4c 20 6c 65 76 65 6c 20 0a 20 20 2a 2a   SQL level .  **
2870: 20 28 69 2e 65 2e 20 22 43 52 45 41 54 45 20 56   (i.e. "CREATE V
2880: 49 52 54 55 41 4c 20 54 41 42 4c 45 20 74 62 6c  IRTUAL TABLE tbl
2890: 20 55 53 49 4e 47 20 65 63 68 6f 28 61 72 67 31   USING echo(arg1
28a0: 2c 20 61 72 67 32 29 22 29 2c 20 74 68 65 6e 20  , arg2)"), then 
28b0: 0a 20 20 2a 2a 20 74 68 65 20 73 65 63 6f 6e 64  .  ** the second
28c0: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 75 73 65   argument is use
28d0: 64 20 61 73 20 61 20 74 61 62 6c 65 20 6e 61 6d  d as a table nam
28e0: 65 2e 20 41 74 74 65 6d 70 74 20 74 6f 20 63 72  e. Attempt to cr
28f0: 65 61 74 65 0a 20 20 2a 2a 20 73 75 63 68 20 61  eate.  ** such a
2900: 20 74 61 62 6c 65 20 77 69 74 68 20 61 20 73 69   table with a si
2910: 6e 67 6c 65 20 63 6f 6c 75 6d 6e 2c 20 22 6c 6f  ngle column, "lo
2920: 67 6d 73 67 22 2e 20 54 68 69 73 20 74 61 62 6c  gmsg". This tabl
2930: 65 20 77 69 6c 6c 0a 20 20 2a 2a 20 62 65 20 75  e will.  ** be u
2940: 73 65 64 20 74 6f 20 6c 6f 67 20 63 61 6c 6c 73  sed to log calls
2950: 20 74 6f 20 74 68 65 20 78 55 70 64 61 74 65 20   to the xUpdate 
2960: 6d 65 74 68 6f 64 2e 20 49 74 20 77 69 6c 6c 20  method. It will 
2970: 62 65 20 64 65 6c 65 74 65 64 0a 20 20 2a 2a 20  be deleted.  ** 
2980: 77 68 65 6e 20 74 68 65 20 76 69 72 74 75 61 6c  when the virtual
2990: 20 74 61 62 6c 65 20 69 73 20 44 52 4f 50 65 64   table is DROPed
29a0: 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 4e 6f 74 65  ..  **.  ** Note
29b0: 3a 20 54 68 65 20 6d 61 69 6e 20 70 6f 69 6e 74  : The main point
29c0: 20 6f 66 20 74 68 69 73 20 69 73 20 74 6f 20 74   of this is to t
29d0: 65 73 74 20 74 68 61 74 20 77 65 20 63 61 6e 20  est that we can 
29e0: 64 72 6f 70 20 74 61 62 6c 65 73 0a 20 20 2a 2a  drop tables.  **
29f0: 20 66 72 6f 6d 20 77 69 74 68 69 6e 20 61 6e 20   from within an 
2a00: 78 44 65 73 74 72 6f 79 20 6d 65 74 68 6f 64 20  xDestroy method 
2a10: 63 61 6c 6c 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  call..  */.  if(
2a20: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
2a30: 26 20 61 72 67 63 3d 3d 35 20 29 7b 0a 20 20 20  & argc==5 ){.   
2a40: 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 20   char *zSql;.   
2a50: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
2a60: 62 20 3d 20 2a 28 65 63 68 6f 5f 76 74 61 62 20  b = *(echo_vtab 
2a70: 2a 2a 29 70 70 56 74 61 62 3b 0a 20 20 20 20 70  **)ppVtab;.    p
2a80: 56 74 61 62 2d 3e 7a 4c 6f 67 4e 61 6d 65 20 3d  Vtab->zLogName =
2a90: 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66 28   sqlite3MPrintf(
2aa0: 22 25 73 22 2c 20 61 72 67 76 5b 34 5d 29 3b 0a  "%s", argv[4]);.
2ab0: 20 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74      zSql = sqlit
2ac0: 65 33 4d 50 72 69 6e 74 66 28 22 43 52 45 41 54  e3MPrintf("CREAT
2ad0: 45 20 54 41 42 4c 45 20 25 51 28 6c 6f 67 6d 73  E TABLE %Q(logms
2ae0: 67 29 22 2c 20 70 56 74 61 62 2d 3e 7a 4c 6f 67  g)", pVtab->zLog
2af0: 4e 61 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d 20  Name);.    rc = 
2b00: 73 71 6c 69 74 65 33 5f 65 78 65 63 28 64 62 2c  sqlite3_exec(db,
2b10: 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29 3b   zSql, 0, 0, 0);
2b20: 0a 20 20 20 20 73 71 6c 69 74 65 46 72 65 65 28  .    sqliteFree(
2b30: 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20 20 72 65  zSql);.  }..  re
2b40: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a  turn rc;.}../* .
2b50: 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20  ** Echo virtual 
2b60: 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43 6f  table module xCo
2b70: 6e 6e 65 63 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f  nnect method..*/
2b80: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
2b90: 43 6f 6e 6e 65 63 74 28 0a 20 20 73 71 6c 69 74  Connect(.  sqlit
2ba0: 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a  e3 *db,.  void *
2bb0: 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 72 67 63  pAux,.  int argc
2bc0: 2c 20 63 68 61 72 20 2a 2a 61 72 67 76 2c 0a 20  , char **argv,. 
2bd0: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a   sqlite3_vtab **
2be0: 70 70 56 74 61 62 0a 29 7b 0a 20 20 61 70 70 65  ppVtab.){.  appe
2bf0: 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28  ndToEchoModule((
2c00: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 29 28 70 41  Tcl_Interp *)(pA
2c10: 75 78 29 2c 20 22 78 43 6f 6e 6e 65 63 74 22 29  ux), "xConnect")
2c20: 3b 0a 20 20 72 65 74 75 72 6e 20 65 63 68 6f 43  ;.  return echoC
2c30: 6f 6e 73 74 72 75 63 74 6f 72 28 64 62 2c 20 70  onstructor(db, p
2c40: 41 75 78 2c 20 61 72 67 63 2c 20 61 72 67 76 2c  Aux, argc, argv,
2c50: 20 70 70 56 74 61 62 29 3b 0a 7d 0a 0a 2f 2a 20   ppVtab);.}../* 
2c60: 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c  .** Echo virtual
2c70: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 44   table module xD
2c80: 69 73 63 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64  isconnect method
2c90: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2ca0: 65 63 68 6f 44 69 73 63 6f 6e 6e 65 63 74 28 73  echoDisconnect(s
2cb0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
2cc0: 61 62 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f 45  ab){.  appendToE
2cd0: 63 68 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68 6f  choModule(((echo
2ce0: 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29 2d 3e  _vtab *)pVtab)->
2cf0: 69 6e 74 65 72 70 2c 20 22 78 44 69 73 63 6f 6e  interp, "xDiscon
2d00: 6e 65 63 74 22 29 3b 0a 20 20 72 65 74 75 72 6e  nect");.  return
2d10: 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28   echoDestructor(
2d20: 70 56 74 61 62 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  pVtab);.}../* .*
2d30: 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74  * Echo virtual t
2d40: 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 44 65 73  able module xDes
2d50: 74 72 6f 79 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a  troy method..*/.
2d60: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 44  static int echoD
2d70: 65 73 74 72 6f 79 28 73 71 6c 69 74 65 33 5f 76  estroy(sqlite3_v
2d80: 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 69  tab *pVtab){.  i
2d90: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
2da0: 4b 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  K;.  echo_vtab *
2db0: 70 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  p = (echo_vtab *
2dc0: 29 70 56 74 61 62 3b 0a 20 20 61 70 70 65 6e 64  )pVtab;.  append
2dd0: 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28 65  ToEchoModule(((e
2de0: 63 68 6f 5f 76 74 61 62 20 2a 29 70 56 74 61 62  cho_vtab *)pVtab
2df0: 29 2d 3e 69 6e 74 65 72 70 2c 20 22 78 44 65 73  )->interp, "xDes
2e00: 74 72 6f 79 22 29 3b 0a 0a 20 20 2f 2a 20 44 72  troy");..  /* Dr
2e10: 6f 70 20 74 68 65 20 22 6c 6f 67 22 20 74 61 62  op the "log" tab
2e20: 6c 65 2c 20 69 66 20 6f 6e 65 20 65 78 69 73 74  le, if one exist
2e30: 73 20 28 73 65 65 20 65 63 68 6f 43 72 65 61 74  s (see echoCreat
2e40: 65 28 29 20 66 6f 72 20 64 65 74 61 69 6c 73 29  e() for details)
2e50: 20 2a 2f 0a 20 20 69 66 28 20 70 20 26 26 20 70   */.  if( p && p
2e60: 2d 3e 7a 4c 6f 67 4e 61 6d 65 20 29 7b 0a 20 20  ->zLogName ){.  
2e70: 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20    char *zSql;.  
2e80: 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33    zSql = sqlite3
2e90: 4d 50 72 69 6e 74 66 28 22 44 52 4f 50 20 54 41  MPrintf("DROP TA
2ea0: 42 4c 45 20 25 51 22 2c 20 70 2d 3e 7a 4c 6f 67  BLE %Q", p->zLog
2eb0: 4e 61 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d 20  Name);.    rc = 
2ec0: 73 71 6c 69 74 65 33 5f 65 78 65 63 28 70 2d 3e  sqlite3_exec(p->
2ed0: 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20  db, zSql, 0, 0, 
2ee0: 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 46 72  0);.    sqliteFr
2ef0: 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20  ee(zSql);.  }.. 
2f00: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
2f10: 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 65  OK ){.    rc = e
2f20: 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 70 56  choDestructor(pV
2f30: 74 61 62 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  tab);.  }.  retu
2f40: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  rn rc;.}../* .**
2f50: 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   Echo virtual ta
2f60: 62 6c 65 20 6d 6f 64 75 6c 65 20 78 4f 70 65 6e  ble module xOpen
2f70: 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74   method..*/.stat
2f80: 69 63 20 69 6e 74 20 65 63 68 6f 4f 70 65 6e 28  ic int echoOpen(
2f90: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
2fa0: 54 61 62 2c 20 73 71 6c 69 74 65 33 5f 76 74 61  Tab, sqlite3_vta
2fb0: 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70 43 75 72  b_cursor **ppCur
2fc0: 73 6f 72 29 7b 0a 20 20 65 63 68 6f 5f 63 75 72  sor){.  echo_cur
2fd0: 73 6f 72 20 2a 70 43 75 72 3b 0a 20 20 70 43 75  sor *pCur;.  pCu
2fe0: 72 20 3d 20 73 71 6c 69 74 65 4d 61 6c 6c 6f 63  r = sqliteMalloc
2ff0: 28 73 69 7a 65 6f 66 28 65 63 68 6f 5f 63 75 72  (sizeof(echo_cur
3000: 73 6f 72 29 29 3b 0a 20 20 2a 70 70 43 75 72 73  sor));.  *ppCurs
3010: 6f 72 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 74  or = (sqlite3_vt
3020: 61 62 5f 63 75 72 73 6f 72 20 2a 29 70 43 75 72  ab_cursor *)pCur
3030: 3b 0a 20 20 72 65 74 75 72 6e 20 28 70 43 75 72  ;.  return (pCur
3040: 20 3f 20 53 51 4c 49 54 45 5f 4f 4b 20 3a 20 53   ? SQLITE_OK : S
3050: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 3b 0a 7d 0a  QLITE_NOMEM);.}.
3060: 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72  ./* .** Echo vir
3070: 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c  tual table modul
3080: 65 20 78 43 6c 6f 73 65 20 6d 65 74 68 6f 64 2e  e xClose method.
3090: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65  .*/.static int e
30a0: 63 68 6f 43 6c 6f 73 65 28 73 71 6c 69 74 65 33  choClose(sqlite3
30b0: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75  _vtab_cursor *cu
30c0: 72 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  r){.  int rc;.  
30d0: 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75  echo_cursor *pCu
30e0: 72 20 3d 20 28 65 63 68 6f 5f 63 75 72 73 6f 72  r = (echo_cursor
30f0: 20 2a 29 63 75 72 3b 0a 20 20 73 71 6c 69 74 65   *)cur;.  sqlite
3100: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
3110: 70 43 75 72 2d 3e 70 53 74 6d 74 3b 0a 20 20 70  pCur->pStmt;.  p
3120: 43 75 72 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a  Cur->pStmt = 0;.
3130: 20 20 73 71 6c 69 74 65 46 72 65 65 28 70 43 75    sqliteFree(pCu
3140: 72 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  r);.  rc = sqlit
3150: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d  e3_finalize(pStm
3160: 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  t);.  return rc;
3170: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
3180: 20 6e 6f 6e 2d 7a 65 72 6f 20 69 66 20 74 68 65   non-zero if the
3190: 20 63 75 72 73 6f 72 20 64 6f 65 73 20 6e 6f 74   cursor does not
31a0: 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74   currently point
31b0: 20 74 6f 20 61 20 76 61 6c 69 64 20 72 65 63 6f   to a valid reco
31c0: 72 64 0a 2a 2a 20 28 69 2e 65 20 69 66 20 74 68  rd.** (i.e if th
31d0: 65 20 73 63 61 6e 20 68 61 73 20 66 69 6e 69 73  e scan has finis
31e0: 68 65 64 29 2c 20 6f 72 20 7a 65 72 6f 20 6f 74  hed), or zero ot
31f0: 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74  herwise..*/.stat
3200: 69 63 20 69 6e 74 20 65 63 68 6f 45 6f 66 28 73  ic int echoEof(s
3210: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
3220: 6f 72 20 2a 63 75 72 29 7b 0a 20 20 72 65 74 75  or *cur){.  retu
3230: 72 6e 20 28 28 28 65 63 68 6f 5f 63 75 72 73 6f  rn (((echo_curso
3240: 72 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74 20  r *)cur)->pStmt 
3250: 3f 20 30 20 3a 20 31 29 3b 0a 7d 0a 0a 2f 2a 20  ? 0 : 1);.}../* 
3260: 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c  .** Echo virtual
3270: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 4e   table module xN
3280: 65 78 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  ext method..*/.s
3290: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 4e 65  tatic int echoNe
32a0: 78 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  xt(sqlite3_vtab_
32b0: 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20  cursor *cur){.  
32c0: 69 6e 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f 63  int rc;.  echo_c
32d0: 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 65  ursor *pCur = (e
32e0: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72  cho_cursor *)cur
32f0: 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ;.  rc = sqlite3
3300: 5f 73 74 65 70 28 70 43 75 72 2d 3e 70 53 74 6d  _step(pCur->pStm
3310: 74 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53  t);..  if( rc==S
3320: 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20  QLITE_ROW ){.   
3330: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
3340: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63  .  }else{.    rc
3350: 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c   = sqlite3_final
3360: 69 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d 74 29  ize(pCur->pStmt)
3370: 3b 0a 20 20 20 20 70 43 75 72 2d 3e 70 53 74 6d  ;.    pCur->pStm
3380: 74 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 72 65  t = 0;.  }..  re
3390: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a  turn rc;.}../* .
33a0: 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20  ** Echo virtual 
33b0: 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43 6f  table module xCo
33c0: 6c 75 6d 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a  lumn method..*/.
33d0: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43  static int echoC
33e0: 6f 6c 75 6d 6e 28 73 71 6c 69 74 65 33 5f 76 74  olumn(sqlite3_vt
33f0: 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c 20  ab_cursor *cur, 
3400: 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20  sqlite3_context 
3410: 2a 63 74 78 2c 20 69 6e 74 20 69 29 7b 0a 20 20  *ctx, int i){.  
3420: 69 6e 74 20 69 43 6f 6c 20 3d 20 69 20 2b 20 31  int iCol = i + 1
3430: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74  ;.  sqlite3_stmt
3440: 20 2a 70 53 74 6d 74 20 3d 20 28 28 65 63 68 6f   *pStmt = ((echo
3450: 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d 3e  _cursor *)cur)->
3460: 70 53 74 6d 74 3b 0a 20 20 69 66 28 20 21 70 53  pStmt;.  if( !pS
3470: 74 6d 74 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  tmt ){.    sqlit
3480: 65 33 5f 72 65 73 75 6c 74 5f 6e 75 6c 6c 28 63  e3_result_null(c
3490: 74 78 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  tx);.  }else{.  
34a0: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
34b0: 33 5f 64 61 74 61 5f 63 6f 75 6e 74 28 70 53 74  3_data_count(pSt
34c0: 6d 74 29 3e 69 43 6f 6c 20 29 3b 0a 20 20 20 20  mt)>iCol );.    
34d0: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 76  sqlite3_result_v
34e0: 61 6c 75 65 28 63 74 78 2c 20 73 71 6c 69 74 65  alue(ctx, sqlite
34f0: 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28 70  3_column_value(p
3500: 53 74 6d 74 2c 20 69 43 6f 6c 29 29 3b 0a 20 20  Stmt, iCol));.  
3510: 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  }.  return SQLIT
3520: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  E_OK;.}../* .** 
3530: 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62  Echo virtual tab
3540: 6c 65 20 6d 6f 64 75 6c 65 20 78 52 6f 77 69 64  le module xRowid
3550: 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74   method..*/.stat
3560: 69 63 20 69 6e 74 20 65 63 68 6f 52 6f 77 69 64  ic int echoRowid
3570: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
3580: 72 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69 74  rsor *cur, sqlit
3590: 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69 64 29  e_int64 *pRowid)
35a0: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74  {.  sqlite3_stmt
35b0: 20 2a 70 53 74 6d 74 20 3d 20 28 28 65 63 68 6f   *pStmt = ((echo
35c0: 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d 3e  _cursor *)cur)->
35d0: 70 53 74 6d 74 3b 0a 20 20 2a 70 52 6f 77 69 64  pStmt;.  *pRowid
35e0: 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d   = sqlite3_colum
35f0: 6e 5f 69 6e 74 36 34 28 70 53 74 6d 74 2c 20 30  n_int64(pStmt, 0
3600: 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  );.  return SQLI
3610: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
3620: 43 6f 6d 70 75 74 65 20 61 20 73 69 6d 70 6c 65  Compute a simple
3630: 20 68 61 73 68 20 6f 66 20 74 68 65 20 6e 75 6c   hash of the nul
3640: 6c 20 74 65 72 6d 69 6e 61 74 65 64 20 73 74 72  l terminated str
3650: 69 6e 67 20 7a 53 74 72 69 6e 67 2e 0a 2a 2a 0a  ing zString..**.
3660: 2a 2a 20 54 68 69 73 20 6d 6f 64 75 6c 65 20 75  ** This module u
3670: 73 65 73 20 6f 6e 6c 79 20 73 71 6c 69 74 65 33  ses only sqlite3
3680: 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64 78 53  _index_info.idxS
3690: 74 72 2c 20 6e 6f 74 20 0a 2a 2a 20 73 71 6c 69  tr, not .** sqli
36a0: 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69  te3_index_info.i
36b0: 64 78 4e 75 6d 2e 20 53 6f 20 74 6f 20 74 65 73  dxNum. So to tes
36c0: 74 20 69 64 78 4e 75 6d 2c 20 77 68 65 6e 20 69  t idxNum, when i
36d0: 64 78 53 74 72 20 69 73 20 73 65 74 0a 2a 2a 20  dxStr is set.** 
36e0: 69 6e 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78  in echoBestIndex
36f0: 28 29 2c 20 69 64 78 4e 75 6d 20 69 73 20 73 65  (), idxNum is se
3700: 74 20 74 6f 20 74 68 65 20 63 6f 72 72 65 73 70  t to the corresp
3710: 6f 6e 64 69 6e 67 20 68 61 73 68 20 76 61 6c 75  onding hash valu
3720: 65 2e 0a 2a 2a 20 49 6e 20 65 63 68 6f 46 69 6c  e..** In echoFil
3730: 74 65 72 28 29 2c 20 63 6f 64 65 20 61 73 73 65  ter(), code asse
3740: 72 74 28 29 73 20 74 68 61 74 20 74 68 65 20 73  rt()s that the s
3750: 75 70 70 6c 69 65 64 20 69 64 78 4e 75 6d 20 76  upplied idxNum v
3760: 61 6c 75 65 20 69 73 0a 2a 2a 20 69 6e 64 65 65  alue is.** indee
3770: 64 20 74 68 65 20 68 61 73 68 20 6f 66 20 74 68  d the hash of th
3780: 65 20 73 75 70 70 6c 69 65 64 20 69 64 78 53 74  e supplied idxSt
3790: 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  r..*/.static int
37a0: 20 68 61 73 68 53 74 72 69 6e 67 28 63 6f 6e 73   hashString(cons
37b0: 74 20 63 68 61 72 20 2a 7a 53 74 72 69 6e 67 29  t char *zString)
37c0: 7b 0a 20 20 69 6e 74 20 76 61 6c 20 3d 20 30 3b  {.  int val = 0;
37d0: 0a 20 20 69 6e 74 20 69 69 3b 0a 20 20 66 6f 72  .  int ii;.  for
37e0: 28 69 69 3d 30 3b 20 7a 53 74 72 69 6e 67 5b 69  (ii=0; zString[i
37f0: 69 5d 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 76  i]; ii++){.    v
3800: 61 6c 20 3d 20 28 76 61 6c 20 3c 3c 20 33 29 20  al = (val << 3) 
3810: 2b 20 28 69 6e 74 29 7a 53 74 72 69 6e 67 5b 69  + (int)zString[i
3820: 69 5d 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  i];.  }.  return
3830: 20 76 61 6c 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20   val;.}../* .** 
3840: 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62  Echo virtual tab
3850: 6c 65 20 6d 6f 64 75 6c 65 20 78 46 69 6c 74 65  le module xFilte
3860: 72 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61  r method..*/.sta
3870: 74 69 63 20 69 6e 74 20 65 63 68 6f 46 69 6c 74  tic int echoFilt
3880: 65 72 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  er(.  sqlite3_vt
3890: 61 62 5f 63 75 72 73 6f 72 20 2a 70 56 74 61 62  ab_cursor *pVtab
38a0: 43 75 72 73 6f 72 2c 20 0a 20 20 69 6e 74 20 69  Cursor, .  int i
38b0: 64 78 4e 75 6d 2c 20 63 6f 6e 73 74 20 63 68 61  dxNum, const cha
38c0: 72 20 2a 69 64 78 53 74 72 2c 0a 20 20 69 6e 74  r *idxStr,.  int
38d0: 20 61 72 67 63 2c 20 73 71 6c 69 74 65 33 5f 76   argc, sqlite3_v
38e0: 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20  alue **argv.){. 
38f0: 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69   int rc;.  int i
3900: 3b 0a 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f 72  ;..  echo_cursor
3910: 20 2a 70 43 75 72 20 3d 20 28 65 63 68 6f 5f 63   *pCur = (echo_c
3920: 75 72 73 6f 72 20 2a 29 70 56 74 61 62 43 75 72  ursor *)pVtabCur
3930: 73 6f 72 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62  sor;.  echo_vtab
3940: 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f   *pVtab = (echo_
3950: 76 74 61 62 20 2a 29 70 56 74 61 62 43 75 72 73  vtab *)pVtabCurs
3960: 6f 72 2d 3e 70 56 74 61 62 3b 0a 20 20 73 71 6c  or->pVtab;.  sql
3970: 69 74 65 33 20 2a 64 62 20 3d 20 70 56 74 61 62  ite3 *db = pVtab
3980: 2d 3e 64 62 3b 0a 0a 20 20 2f 2a 20 43 68 65 63  ->db;..  /* Chec
3990: 6b 20 74 68 61 74 20 69 64 78 4e 75 6d 20 6d 61  k that idxNum ma
39a0: 74 63 68 65 73 20 69 64 78 53 74 72 20 2a 2f 0a  tches idxStr */.
39b0: 20 20 61 73 73 65 72 74 28 20 69 64 78 4e 75 6d    assert( idxNum
39c0: 3d 3d 68 61 73 68 53 74 72 69 6e 67 28 69 64 78  ==hashString(idx
39d0: 53 74 72 29 20 29 3b 0a 0a 20 20 2f 2a 20 4c 6f  Str) );..  /* Lo
39e0: 67 20 61 72 67 75 6d 65 6e 74 73 20 74 6f 20 74  g arguments to t
39f0: 68 65 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65  he ::echo_module
3a00: 20 54 63 6c 20 76 61 72 69 61 62 6c 65 20 2a 2f   Tcl variable */
3a10: 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d  .  appendToEchoM
3a20: 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74  odule(pVtab->int
3a30: 65 72 70 2c 20 22 78 46 69 6c 74 65 72 22 29 3b  erp, "xFilter");
3a40: 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d  .  appendToEchoM
3a50: 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74  odule(pVtab->int
3a60: 65 72 70 2c 20 69 64 78 53 74 72 29 3b 0a 20 20  erp, idxStr);.  
3a70: 66 6f 72 28 69 3d 30 3b 20 69 3c 61 72 67 63 3b  for(i=0; i<argc;
3a80: 20 69 2b 2b 29 7b 0a 20 20 20 20 61 70 70 65 6e   i++){.    appen
3a90: 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56  dToEchoModule(pV
3aa0: 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 73 71 6c  tab->interp, sql
3ab0: 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28  ite3_value_text(
3ac0: 61 72 67 76 5b 69 5d 29 29 3b 0a 20 20 7d 0a 0a  argv[i]));.  }..
3ad0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
3ae0: 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d 74 29 3b  ze(pCur->pStmt);
3af0: 0a 20 20 70 43 75 72 2d 3e 70 53 74 6d 74 20 3d  .  pCur->pStmt =
3b00: 20 30 3b 0a 0a 20 20 2f 2a 20 50 72 65 70 61 72   0;..  /* Prepar
3b10: 65 20 74 68 65 20 53 51 4c 20 73 74 61 74 65 6d  e the SQL statem
3b20: 65 6e 74 20 63 72 65 61 74 65 64 20 62 79 20 65  ent created by e
3b30: 63 68 6f 42 65 73 74 49 6e 64 65 78 20 61 6e 64  choBestIndex and
3b40: 20 62 69 6e 64 20 74 68 65 0a 20 20 2a 2a 20 72   bind the.  ** r
3b50: 75 6e 74 69 6d 65 20 70 61 72 61 6d 65 74 65 72  untime parameter
3b60: 73 20 70 61 73 73 65 64 20 74 6f 20 74 68 69 73  s passed to this
3b70: 20 66 75 6e 63 74 69 6f 6e 20 74 6f 20 69 74 2e   function to it.
3b80: 0a 20 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c  .  */.  rc = sql
3b90: 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c  ite3_prepare(db,
3ba0: 20 69 64 78 53 74 72 2c 20 2d 31 2c 20 26 70 43   idxStr, -1, &pC
3bb0: 75 72 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a 20  ur->pStmt, 0);. 
3bc0: 20 61 73 73 65 72 74 28 20 70 43 75 72 2d 3e 70   assert( pCur->p
3bd0: 53 74 6d 74 20 7c 7c 20 72 63 21 3d 53 51 4c 49  Stmt || rc!=SQLI
3be0: 54 45 5f 4f 4b 20 29 3b 0a 20 20 66 6f 72 28 69  TE_OK );.  for(i
3bf0: 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  =0; rc==SQLITE_O
3c00: 4b 20 26 26 20 69 3c 61 72 67 63 3b 20 69 2b 2b  K && i<argc; i++
3c10: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 62  ){.    sqlite3_b
3c20: 69 6e 64 5f 76 61 6c 75 65 28 70 43 75 72 2d 3e  ind_value(pCur->
3c30: 70 53 74 6d 74 2c 20 69 2b 31 2c 20 61 72 67 76  pStmt, i+1, argv
3c40: 5b 69 5d 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  [i]);.  }..  /* 
3c50: 49 66 20 65 76 65 72 79 74 68 69 6e 67 20 77 61  If everything wa
3c60: 73 20 73 75 63 63 65 73 73 66 75 6c 2c 20 61 64  s successful, ad
3c70: 76 61 6e 63 65 20 74 6f 20 74 68 65 20 66 69 72  vance to the fir
3c80: 73 74 20 72 6f 77 20 6f 66 20 74 68 65 20 73 63  st row of the sc
3c90: 61 6e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d  an */.  if( rc==
3ca0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
3cb0: 20 72 63 20 3d 20 65 63 68 6f 4e 65 78 74 28 70   rc = echoNext(p
3cc0: 56 74 61 62 43 75 72 73 6f 72 29 3b 0a 20 20 7d  VtabCursor);.  }
3cd0: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
3ce0: 0a 0a 0a 2f 2a 0a 2a 2a 20 41 20 68 65 6c 70 65  .../*.** A helpe
3cf0: 72 20 66 75 6e 63 74 69 6f 6e 20 75 73 65 64 20  r function used 
3d00: 62 79 20 65 63 68 6f 55 70 64 61 74 65 28 29 20  by echoUpdate() 
3d10: 61 6e 64 20 65 63 68 6f 42 65 73 74 49 6e 64 65  and echoBestInde
3d20: 78 28 29 20 66 6f 72 0a 2a 2a 20 6d 61 6e 69 70  x() for.** manip
3d30: 75 6c 61 74 69 6e 67 20 73 74 72 69 6e 67 73 20  ulating strings 
3d40: 69 6e 20 63 6f 6e 63 65 72 74 20 77 69 74 68 20  in concert with 
3d50: 74 68 65 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  the sqlite3_mpri
3d60: 6e 74 66 28 29 20 66 75 6e 63 74 69 6f 6e 2e 0a  ntf() function..
3d70: 2a 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 65 72 20  **.** Parameter 
3d80: 70 7a 53 74 72 20 70 6f 69 6e 74 73 20 74 6f 20  pzStr points to 
3d90: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 73  a pointer to a s
3da0: 74 72 69 6e 67 20 61 6c 6c 6f 63 61 74 65 64 20  tring allocated 
3db0: 77 69 74 68 0a 2a 2a 20 73 71 6c 69 74 65 33 5f  with.** sqlite3_
3dc0: 6d 70 72 69 6e 74 66 2e 20 54 68 65 20 73 65 63  mprintf. The sec
3dd0: 6f 6e 64 20 70 61 72 61 6d 65 74 65 72 2c 20 7a  ond parameter, z
3de0: 41 70 70 65 6e 64 2c 20 70 6f 69 6e 74 73 20 74  Append, points t
3df0: 6f 20 61 6e 6f 74 68 65 72 0a 2a 2a 20 73 74 72  o another.** str
3e00: 69 6e 67 2e 20 54 68 65 20 74 77 6f 20 73 74 72  ing. The two str
3e10: 69 6e 67 73 20 61 72 65 20 63 6f 6e 63 61 74 65  ings are concate
3e20: 6e 61 74 65 64 20 74 6f 67 65 74 68 65 72 20 61  nated together a
3e30: 6e 64 20 2a 70 7a 53 74 72 0a 2a 2a 20 73 65 74  nd *pzStr.** set
3e40: 20 74 6f 20 70 6f 69 6e 74 20 61 74 20 74 68 65   to point at the
3e50: 20 72 65 73 75 6c 74 2e 20 54 68 65 20 69 6e 69   result. The ini
3e60: 74 69 61 6c 20 62 75 66 66 65 72 20 70 6f 69 6e  tial buffer poin
3e70: 74 65 64 20 74 6f 20 62 79 20 2a 70 7a 53 74 72  ted to by *pzStr
3e80: 0a 2a 2a 20 69 73 20 64 65 61 6c 6c 6f 63 61 74  .** is deallocat
3e90: 65 64 20 76 69 61 20 73 71 6c 69 74 65 33 5f 66  ed via sqlite3_f
3ea0: 72 65 65 28 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  ree()..**.** If 
3eb0: 74 68 65 20 74 68 69 72 64 20 61 72 67 75 6d 65  the third argume
3ec0: 6e 74 2c 20 64 6f 46 72 65 65 2c 20 69 73 20 74  nt, doFree, is t
3ed0: 72 75 65 2c 20 74 68 65 6e 20 73 71 6c 69 74 65  rue, then sqlite
3ee0: 33 5f 66 72 65 65 28 29 20 69 73 0a 2a 2a 20 61  3_free() is.** a
3ef0: 6c 73 6f 20 63 61 6c 6c 65 64 20 74 6f 20 66 72  lso called to fr
3f00: 65 65 20 74 68 65 20 62 75 66 66 65 72 20 70 6f  ee the buffer po
3f10: 69 6e 74 65 64 20 74 6f 20 62 79 20 7a 41 70 70  inted to by zApp
3f20: 65 6e 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  end..*/.static v
3f30: 6f 69 64 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61  oid string_conca
3f40: 74 28 63 68 61 72 20 2a 2a 70 7a 53 74 72 2c 20  t(char **pzStr, 
3f50: 63 68 61 72 20 2a 7a 41 70 70 65 6e 64 2c 20 69  char *zAppend, i
3f60: 6e 74 20 64 6f 46 72 65 65 29 7b 0a 20 20 63 68  nt doFree){.  ch
3f70: 61 72 20 2a 7a 49 6e 20 3d 20 2a 70 7a 53 74 72  ar *zIn = *pzStr
3f80: 3b 0a 20 20 69 66 28 20 7a 49 6e 20 29 7b 0a 20  ;.  if( zIn ){. 
3f90: 20 20 20 63 68 61 72 20 2a 7a 54 65 6d 70 20 3d     char *zTemp =
3fa0: 20 7a 49 6e 3b 0a 20 20 20 20 7a 49 6e 20 3d 20   zIn;.    zIn = 
3fb0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
3fc0: 22 25 73 25 73 22 2c 20 7a 49 6e 2c 20 7a 41 70  "%s%s", zIn, zAp
3fd0: 70 65 6e 64 29 3b 0a 20 20 20 20 73 71 6c 69 74  pend);.    sqlit
3fe0: 65 33 5f 66 72 65 65 28 7a 54 65 6d 70 29 3b 0a  e3_free(zTemp);.
3ff0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 7a 49 6e    }else{.    zIn
4000: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
4010: 74 66 28 22 25 73 22 2c 20 7a 41 70 70 65 6e 64  tf("%s", zAppend
4020: 29 3b 0a 20 20 7d 0a 20 20 2a 70 7a 53 74 72 20  );.  }.  *pzStr 
4030: 3d 20 7a 49 6e 3b 0a 20 20 69 66 28 20 64 6f 46  = zIn;.  if( doF
4040: 72 65 65 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  ree ){.    sqlit
4050: 65 33 5f 66 72 65 65 28 7a 41 70 70 65 6e 64 29  e3_free(zAppend)
4060: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  ;.  }.}../*.** T
4070: 68 65 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20 69  he echo module i
4080: 6d 70 6c 65 6d 65 6e 74 73 20 74 68 65 20 73 75  mplements the su
4090: 62 73 65 74 20 6f 66 20 71 75 65 72 79 20 63 6f  bset of query co
40a0: 6e 73 74 72 61 69 6e 74 73 20 61 6e 64 20 73 6f  nstraints and so
40b0: 72 74 0a 2a 2a 20 6f 72 64 65 72 73 20 74 68 61  rt.** orders tha
40c0: 74 20 6d 61 79 20 74 61 6b 65 20 61 64 76 61 6e  t may take advan
40d0: 74 61 67 65 20 6f 66 20 53 51 4c 69 74 65 20 69  tage of SQLite i
40e0: 6e 64 69 63 65 73 20 6f 6e 20 74 68 65 20 75 6e  ndices on the un
40f0: 64 65 72 6c 79 69 6e 67 0a 2a 2a 20 72 65 61 6c  derlying.** real
4100: 20 74 61 62 6c 65 2e 20 46 6f 72 20 65 78 61 6d   table. For exam
4110: 70 6c 65 2c 20 69 66 20 74 68 65 20 72 65 61 6c  ple, if the real
4120: 20 74 61 62 6c 65 20 69 73 20 64 65 63 6c 61 72   table is declar
4130: 65 64 20 61 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20  ed as:.**.**    
4140: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 72 65   CREATE TABLE re
4150: 61 6c 28 61 2c 20 62 2c 20 63 29 3b 0a 2a 2a 20  al(a, b, c);.** 
4160: 20 20 20 20 43 52 45 41 54 45 20 49 4e 44 45 58      CREATE INDEX
4170: 20 72 65 61 6c 5f 69 6e 64 65 78 20 4f 4e 20 72   real_index ON r
4180: 65 61 6c 28 62 29 3b 0a 2a 2a 0a 2a 2a 20 74 68  eal(b);.**.** th
4190: 65 6e 20 74 68 65 20 65 63 68 6f 20 6d 6f 64 75  en the echo modu
41a0: 6c 65 20 68 61 6e 64 6c 65 73 20 57 48 45 52 45  le handles WHERE
41b0: 20 6f 72 20 4f 52 44 45 52 20 42 59 20 63 6c 61   or ORDER BY cla
41c0: 75 73 65 73 20 74 68 61 74 20 72 65 66 65 72 0a  uses that refer.
41d0: 2a 2a 20 74 6f 20 74 68 65 20 63 6f 6c 75 6d 6e  ** to the column
41e0: 20 22 62 22 2c 20 62 75 74 20 6e 6f 74 20 22 61   "b", but not "a
41f0: 22 20 6f 72 20 22 63 22 2e 20 49 66 20 61 20 6d  " or "c". If a m
4200: 75 6c 74 69 2d 63 6f 6c 75 6d 6e 20 69 6e 64 65  ulti-column inde
4210: 78 20 69 73 0a 2a 2a 20 70 72 65 73 65 6e 74 2c  x is.** present,
4220: 20 6f 6e 6c 79 20 69 74 27 73 20 6c 65 66 74 20   only it's left 
4230: 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20 69 73 20 63  most column is c
4240: 6f 6e 73 69 64 65 72 65 64 2e 20 0a 2a 2a 0a 2a  onsidered. .**.*
4250: 2a 20 54 68 69 73 20 78 42 65 73 74 49 6e 64 65  * This xBestInde
4260: 78 20 6d 65 74 68 6f 64 20 65 6e 63 6f 64 65 73  x method encodes
4270: 20 74 68 65 20 70 72 6f 70 6f 73 65 64 20 73 65   the proposed se
4280: 61 72 63 68 20 73 74 72 61 74 65 67 79 20 61 73  arch strategy as
4290: 0a 2a 2a 20 61 6e 20 53 51 4c 20 71 75 65 72 79  .** an SQL query
42a0: 20 6f 6e 20 74 68 65 20 72 65 61 6c 20 74 61 62   on the real tab
42b0: 6c 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 74 68  le underlying th
42c0: 65 20 76 69 72 74 75 61 6c 20 65 63 68 6f 20 6d  e virtual echo m
42d0: 6f 64 75 6c 65 20 0a 2a 2a 20 74 61 62 6c 65 20  odule .** table 
42e0: 61 6e 64 20 73 74 6f 72 65 73 20 74 68 65 20 71  and stores the q
42f0: 75 65 72 79 20 69 6e 20 73 71 6c 69 74 65 33 5f  uery in sqlite3_
4300: 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64 78 53 74  index_info.idxSt
4310: 72 2e 20 54 68 65 20 53 51 4c 0a 2a 2a 20 73 74  r. The SQL.** st
4320: 61 74 65 6d 65 6e 74 20 69 73 20 6f 66 20 74 68  atement is of th
4330: 65 20 66 6f 72 6d 3a 0a 2a 2a 0a 2a 2a 20 20 20  e form:.**.**   
4340: 53 45 4c 45 43 54 20 72 6f 77 69 64 2c 20 2a 20  SELECT rowid, * 
4350: 46 52 4f 4d 20 3c 72 65 61 6c 2d 74 61 62 6c 65  FROM <real-table
4360: 3e 20 3f 3c 77 68 65 72 65 2d 63 6c 61 75 73 65  > ?<where-clause
4370: 3e 3f 20 3f 3c 6f 72 64 65 72 2d 62 79 2d 63 6c  >? ?<order-by-cl
4380: 61 75 73 65 3e 3f 0a 2a 2a 0a 2a 2a 20 77 68 65  ause>?.**.** whe
4390: 72 65 20 74 68 65 20 3c 77 68 65 72 65 2d 63 6c  re the <where-cl
43a0: 61 75 73 65 3e 20 61 6e 64 20 3c 6f 72 64 65 72  ause> and <order
43b0: 2d 62 79 2d 63 6c 61 75 73 65 3e 20 61 72 65 20  -by-clause> are 
43c0: 64 65 74 65 72 6d 69 6e 65 64 0a 2a 2a 20 62 79  determined.** by
43d0: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
43e0: 20 74 68 65 20 73 74 72 75 63 74 75 72 65 20 70   the structure p
43f0: 6f 69 6e 74 65 64 20 74 6f 20 62 79 20 74 68 65  ointed to by the
4400: 20 70 49 64 78 49 6e 66 6f 20 61 72 67 75 6d 65   pIdxInfo argume
4410: 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  nt..*/.static in
4420: 74 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78 28  t echoBestIndex(
4430: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61  sqlite3_vtab *ta
4440: 62 2c 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78  b, sqlite3_index
4450: 5f 69 6e 66 6f 20 2a 70 49 64 78 49 6e 66 6f 29  _info *pIdxInfo)
4460: 7b 0a 20 20 69 6e 74 20 69 69 3b 0a 20 20 63 68  {.  int ii;.  ch
4470: 61 72 20 2a 7a 51 75 65 72 79 20 3d 20 30 3b 0a  ar *zQuery = 0;.
4480: 20 20 63 68 61 72 20 2a 7a 4e 65 77 3b 0a 20 20    char *zNew;.  
4490: 69 6e 74 20 6e 41 72 67 20 3d 20 30 3b 0a 20 20  int nArg = 0;.  
44a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 65 70  const char *zSep
44b0: 20 3d 20 22 57 48 45 52 45 22 3b 0a 20 20 65 63   = "WHERE";.  ec
44c0: 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d  ho_vtab *pVtab =
44d0: 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 74 61   (echo_vtab *)ta
44e0: 62 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  b;.  sqlite3_stm
44f0: 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 0a 20  t *pStmt = 0;.. 
4500: 20 69 6e 74 20 6e 52 6f 77 3b 0a 20 20 69 6e 74   int nRow;.  int
4510: 20 75 73 65 49 64 78 20 3d 20 30 3b 0a 20 20 69   useIdx = 0;.  i
4520: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
4530: 4b 3b 0a 0a 20 20 2f 2a 20 44 65 74 65 72 6d 69  K;..  /* Determi
4540: 6e 65 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  ne the number of
4550: 20 72 6f 77 73 20 69 6e 20 74 68 65 20 74 61 62   rows in the tab
4560: 6c 65 20 61 6e 64 20 73 74 6f 72 65 20 74 68 69  le and store thi
4570: 73 20 76 61 6c 75 65 20 69 6e 20 6c 6f 63 61 6c  s value in local
4580: 0a 20 20 2a 2a 20 76 61 72 69 61 62 6c 65 20 6e  .  ** variable n
4590: 52 6f 77 2e 20 54 68 65 20 27 65 73 74 69 6d 61  Row. The 'estima
45a0: 74 65 64 2d 63 6f 73 74 27 20 6f 66 20 74 68 65  ted-cost' of the
45b0: 20 73 63 61 6e 20 77 69 6c 6c 20 62 65 20 74 68   scan will be th
45c0: 65 20 6e 75 6d 62 65 72 20 6f 66 0a 20 20 2a 2a  e number of.  **
45d0: 20 72 6f 77 73 20 69 6e 20 74 68 65 20 74 61 62   rows in the tab
45e0: 6c 65 20 66 6f 72 20 61 20 6c 69 6e 65 61 72 20  le for a linear 
45f0: 73 63 61 6e 2c 20 6f 72 20 74 68 65 20 6c 6f 67  scan, or the log
4600: 20 28 62 61 73 65 20 32 29 20 6f 66 20 74 68 65   (base 2) of the
4610: 20 0a 20 20 2a 2a 20 6e 75 6d 62 65 72 20 6f 66   .  ** number of
4620: 20 72 6f 77 73 20 69 66 20 74 68 65 20 70 72 6f   rows if the pro
4630: 70 6f 73 65 64 20 73 63 61 6e 20 75 73 65 73 20  posed scan uses 
4640: 61 6e 20 69 6e 64 65 78 2e 20 20 0a 20 20 2a 2f  an index.  .  */
4650: 0a 20 20 7a 51 75 65 72 79 20 3d 20 73 71 6c 69  .  zQuery = sqli
4660: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 53 45 4c  te3_mprintf("SEL
4670: 45 43 54 20 63 6f 75 6e 74 28 2a 29 20 46 52 4f  ECT count(*) FRO
4680: 4d 20 25 51 22 2c 20 70 56 74 61 62 2d 3e 7a 54  M %Q", pVtab->zT
4690: 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 72 63 20  ableName);.  rc 
46a0: 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72  = sqlite3_prepar
46b0: 65 28 70 56 74 61 62 2d 3e 64 62 2c 20 7a 51 75  e(pVtab->db, zQu
46c0: 65 72 79 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c  ery, -1, &pStmt,
46d0: 20 30 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53   0);.  if( rc!=S
46e0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
46f0: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20  return rc;.  }. 
4700: 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53   sqlite3_step(pS
4710: 74 6d 74 29 3b 0a 20 20 6e 52 6f 77 20 3d 20 73  tmt);.  nRow = s
4720: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e  qlite3_column_in
4730: 74 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 72  t(pStmt, 0);.  r
4740: 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  c = sqlite3_fina
4750: 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 69  lize(pStmt);.  i
4760: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
4770: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72   ){.    return r
4780: 63 3b 0a 20 20 7d 0a 0a 20 20 7a 51 75 65 72 79  c;.  }..  zQuery
4790: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
47a0: 74 66 28 22 53 45 4c 45 43 54 20 72 6f 77 69 64  tf("SELECT rowid
47b0: 2c 20 2a 20 46 52 4f 4d 20 25 51 22 2c 20 70 56  , * FROM %Q", pV
47c0: 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29  tab->zTableName)
47d0: 3b 0a 20 20 66 6f 72 28 69 69 3d 30 3b 20 69 69  ;.  for(ii=0; ii
47e0: 3c 70 49 64 78 49 6e 66 6f 2d 3e 6e 43 6f 6e 73  <pIdxInfo->nCons
47f0: 74 72 61 69 6e 74 3b 20 69 69 2b 2b 29 7b 0a 20  traint; ii++){. 
4800: 20 20 20 63 6f 6e 73 74 20 73 74 72 75 63 74 20     const struct 
4810: 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 63 6f  sqlite3_index_co
4820: 6e 73 74 72 61 69 6e 74 20 2a 70 43 6f 6e 73 74  nstraint *pConst
4830: 72 61 69 6e 74 3b 0a 20 20 20 20 73 74 72 75 63  raint;.    struc
4840: 74 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f  t sqlite3_index_
4850: 63 6f 6e 73 74 72 61 69 6e 74 5f 75 73 61 67 65  constraint_usage
4860: 20 2a 70 55 73 61 67 65 3b 0a 0a 20 20 20 20 70   *pUsage;..    p
4870: 43 6f 6e 73 74 72 61 69 6e 74 20 3d 20 26 70 49  Constraint = &pI
4880: 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61  dxInfo->aConstra
4890: 69 6e 74 5b 69 69 5d 3b 0a 20 20 20 20 70 55 73  int[ii];.    pUs
48a0: 61 67 65 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d  age = &pIdxInfo-
48b0: 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67  >aConstraintUsag
48c0: 65 5b 69 69 5d 3b 0a 0a 20 20 20 20 69 6e 74 20  e[ii];..    int 
48d0: 69 43 6f 6c 20 3d 20 70 43 6f 6e 73 74 72 61 69  iCol = pConstrai
48e0: 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20  nt->iColumn;.   
48f0: 20 69 66 28 20 70 56 74 61 62 2d 3e 61 49 6e 64   if( pVtab->aInd
4900: 65 78 5b 69 43 6f 6c 5d 20 29 7b 0a 20 20 20 20  ex[iCol] ){.    
4910: 20 20 63 68 61 72 20 2a 7a 43 6f 6c 20 3d 20 70    char *zCol = p
4920: 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 43 6f 6c 5d  Vtab->aCol[iCol]
4930: 3b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 4f  ;.      char *zO
4940: 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 75 73 65  p = 0;.      use
4950: 49 64 78 20 3d 20 31 3b 0a 20 20 20 20 20 20 69  Idx = 1;.      i
4960: 66 28 20 69 43 6f 6c 3c 30 20 29 7b 0a 20 20 20  f( iCol<0 ){.   
4970: 20 20 20 20 20 7a 43 6f 6c 20 3d 20 22 72 6f 77       zCol = "row
4980: 69 64 22 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  id";.      }.   
4990: 20 20 20 73 77 69 74 63 68 28 20 70 43 6f 6e 73     switch( pCons
49a0: 74 72 61 69 6e 74 2d 3e 6f 70 20 29 7b 0a 20 20  traint->op ){.  
49b0: 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54        case SQLIT
49c0: 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49  E_INDEX_CONSTRAI
49d0: 4e 54 5f 45 51 3a 0a 20 20 20 20 20 20 20 20 20  NT_EQ:.         
49e0: 20 7a 4f 70 20 3d 20 22 3d 22 3b 20 62 72 65 61   zOp = "="; brea
49f0: 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65 20  k;.        case 
4a00: 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e  SQLITE_INDEX_CON
4a10: 53 54 52 41 49 4e 54 5f 4c 54 3a 0a 20 20 20 20  STRAINT_LT:.    
4a20: 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3c 22 3b        zOp = "<";
4a30: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
4a40: 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 44 45  case SQLITE_INDE
4a50: 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 47 54 3a  X_CONSTRAINT_GT:
4a60: 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d  .          zOp =
4a70: 20 22 3e 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20   ">"; break;.   
4a80: 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45       case SQLITE
4a90: 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e  _INDEX_CONSTRAIN
4aa0: 54 5f 4c 45 3a 0a 20 20 20 20 20 20 20 20 20 20  T_LE:.          
4ab0: 7a 4f 70 20 3d 20 22 3c 3d 22 3b 20 62 72 65 61  zOp = "<="; brea
4ac0: 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65 20  k;.        case 
4ad0: 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e  SQLITE_INDEX_CON
4ae0: 53 54 52 41 49 4e 54 5f 47 45 3a 0a 20 20 20 20  STRAINT_GE:.    
4af0: 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3e 3d 22        zOp = ">="
4b00: 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20  ; break;.       
4b10: 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 44   case SQLITE_IND
4b20: 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4d 41  EX_CONSTRAINT_MA
4b30: 54 43 48 3a 0a 20 20 20 20 20 20 20 20 20 20 7a  TCH:.          z
4b40: 4f 70 20 3d 20 22 4c 49 4b 45 22 3b 20 62 72 65  Op = "LIKE"; bre
4b50: 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
4b60: 20 20 69 66 28 20 7a 4f 70 5b 30 5d 3d 3d 27 4c    if( zOp[0]=='L
4b70: 27 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 4e 65  ' ){.        zNe
4b80: 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  w = sqlite3_mpri
4b90: 6e 74 66 28 22 20 25 73 20 25 73 20 4c 49 4b 45  ntf(" %s %s LIKE
4ba0: 20 28 53 45 4c 45 43 54 20 27 25 25 27 7c 7c 3f   (SELECT '%%'||?
4bb0: 7c 7c 27 25 25 27 29 22 2c 20 0a 20 20 20 20 20  ||'%%')", .     
4bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4bd0: 20 20 20 20 20 20 20 20 20 20 7a 53 65 70 2c 20            zSep, 
4be0: 7a 43 6f 6c 29 3b 0a 20 20 20 20 20 20 7d 20 65  zCol);.      } e
4bf0: 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 7a 4e  lse {.        zN
4c00: 65 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  ew = sqlite3_mpr
4c10: 69 6e 74 66 28 22 20 25 73 20 25 73 20 25 73 20  intf(" %s %s %s 
4c20: 3f 22 2c 20 7a 53 65 70 2c 20 7a 43 6f 6c 2c 20  ?", zSep, zCol, 
4c30: 7a 4f 70 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  zOp);.      }.  
4c40: 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61      string_conca
4c50: 74 28 26 7a 51 75 65 72 79 2c 20 7a 4e 65 77 2c  t(&zQuery, zNew,
4c60: 20 31 29 3b 0a 0a 20 20 20 20 20 20 7a 53 65 70   1);..      zSep
4c70: 20 3d 20 22 41 4e 44 22 3b 0a 20 20 20 20 20 20   = "AND";.      
4c80: 70 55 73 61 67 65 2d 3e 61 72 67 76 49 6e 64 65  pUsage->argvInde
4c90: 78 20 3d 20 2b 2b 6e 41 72 67 3b 0a 20 20 20 20  x = ++nArg;.    
4ca0: 20 20 70 55 73 61 67 65 2d 3e 6f 6d 69 74 20 3d    pUsage->omit =
4cb0: 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20   1;.    }.  }.. 
4cc0: 20 2f 2a 20 49 66 20 74 68 65 72 65 20 69 73 20   /* If there is 
4cd0: 6f 6e 6c 79 20 6f 6e 65 20 74 65 72 6d 20 69 6e  only one term in
4ce0: 20 74 68 65 20 4f 52 44 45 52 20 42 59 20 63 6c   the ORDER BY cl
4cf0: 61 75 73 65 2c 20 61 6e 64 20 69 74 20 69 73 0a  ause, and it is.
4d00: 20 20 2a 2a 20 6f 6e 20 61 20 63 6f 6c 75 6d 6e    ** on a column
4d10: 20 74 68 61 74 20 74 68 69 73 20 76 69 72 74 75   that this virtu
4d20: 61 6c 20 74 61 62 6c 65 20 68 61 73 20 61 6e 20  al table has an 
4d30: 69 6e 64 65 78 20 66 6f 72 2c 20 74 68 65 6e 20  index for, then 
4d40: 63 6f 6e 73 75 6d 65 20 0a 20 20 2a 2a 20 74 68  consume .  ** th
4d50: 65 20 4f 52 44 45 52 20 42 59 20 63 6c 61 75 73  e ORDER BY claus
4d60: 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 70 49  e..  */.  if( pI
4d70: 64 78 49 6e 66 6f 2d 3e 6e 4f 72 64 65 72 42 79  dxInfo->nOrderBy
4d80: 3d 3d 31 20 26 26 20 70 56 74 61 62 2d 3e 61 49  ==1 && pVtab->aI
4d90: 6e 64 65 78 5b 70 49 64 78 49 6e 66 6f 2d 3e 61  ndex[pIdxInfo->a
4da0: 4f 72 64 65 72 42 79 2d 3e 69 43 6f 6c 75 6d 6e  OrderBy->iColumn
4db0: 5d 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a  ] ){.    char *z
4dc0: 43 6f 6c 20 3d 20 70 56 74 61 62 2d 3e 61 43 6f  Col = pVtab->aCo
4dd0: 6c 5b 70 49 64 78 49 6e 66 6f 2d 3e 61 4f 72 64  l[pIdxInfo->aOrd
4de0: 65 72 42 79 2d 3e 69 43 6f 6c 75 6d 6e 5d 3b 0a  erBy->iColumn];.
4df0: 20 20 20 20 63 68 61 72 20 2a 7a 44 69 72 20 3d      char *zDir =
4e00: 20 70 49 64 78 49 6e 66 6f 2d 3e 61 4f 72 64 65   pIdxInfo->aOrde
4e10: 72 42 79 2d 3e 64 65 73 63 3f 22 44 45 53 43 22  rBy->desc?"DESC"
4e20: 3a 22 41 53 43 22 3b 0a 20 20 20 20 7a 4e 65 77  :"ASC";.    zNew
4e30: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
4e40: 74 66 28 22 20 4f 52 44 45 52 20 42 59 20 25 73  tf(" ORDER BY %s
4e50: 20 25 73 22 2c 20 7a 43 6f 6c 2c 20 7a 44 69 72   %s", zCol, zDir
4e60: 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f  );.    string_co
4e70: 6e 63 61 74 28 26 7a 51 75 65 72 79 2c 20 7a 4e  ncat(&zQuery, zN
4e80: 65 77 2c 20 31 29 3b 0a 20 20 20 20 70 49 64 78  ew, 1);.    pIdx
4e90: 49 6e 66 6f 2d 3e 6f 72 64 65 72 42 79 43 6f 6e  Info->orderByCon
4ea0: 73 75 6d 65 64 20 3d 20 31 3b 0a 20 20 7d 0a 0a  sumed = 1;.  }..
4eb0: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
4ec0: 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65  dule(pVtab->inte
4ed0: 72 70 2c 20 22 78 42 65 73 74 49 6e 64 65 78 22  rp, "xBestIndex"
4ee0: 29 3b 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63  );;.  appendToEc
4ef0: 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e  hoModule(pVtab->
4f00: 69 6e 74 65 72 70 2c 20 7a 51 75 65 72 79 29 3b  interp, zQuery);
4f10: 0a 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 69 64  ..  pIdxInfo->id
4f20: 78 4e 75 6d 20 3d 20 68 61 73 68 53 74 72 69 6e  xNum = hashStrin
4f30: 67 28 7a 51 75 65 72 79 29 3b 0a 20 20 70 49 64  g(zQuery);.  pId
4f40: 78 49 6e 66 6f 2d 3e 69 64 78 53 74 72 20 3d 20  xInfo->idxStr = 
4f50: 7a 51 75 65 72 79 3b 0a 20 20 70 49 64 78 49 6e  zQuery;.  pIdxIn
4f60: 66 6f 2d 3e 6e 65 65 64 54 6f 46 72 65 65 49 64  fo->needToFreeId
4f70: 78 53 74 72 20 3d 20 31 3b 0a 20 20 69 66 28 20  xStr = 1;.  if( 
4f80: 75 73 65 49 64 78 20 29 7b 0a 20 20 20 20 2f 2a  useIdx ){.    /*
4f90: 20 41 70 70 72 6f 78 69 6d 61 74 69 6f 6e 20 6f   Approximation o
4fa0: 66 20 6c 6f 67 32 28 6e 52 6f 77 29 2e 20 2a 2f  f log2(nRow). */
4fb0: 0a 20 20 20 20 66 6f 72 28 20 69 69 3d 30 3b 20  .    for( ii=0; 
4fc0: 69 69 3c 28 73 69 7a 65 6f 66 28 69 6e 74 29 2a  ii<(sizeof(int)*
4fd0: 38 29 3b 20 69 69 2b 2b 20 29 7b 0a 20 20 20 20  8); ii++ ){.    
4fe0: 20 20 69 66 28 20 6e 52 6f 77 20 26 20 28 31 3c    if( nRow & (1<
4ff0: 3c 69 69 29 20 29 7b 0a 20 20 20 20 20 20 20 20  <ii) ){.        
5000: 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61  pIdxInfo->estima
5010: 74 65 64 43 6f 73 74 20 3d 20 28 64 6f 75 62 6c  tedCost = (doubl
5020: 65 29 69 69 3b 0a 20 20 20 20 20 20 7d 0a 20 20  e)ii;.      }.  
5030: 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20    }.  } else {. 
5040: 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74     pIdxInfo->est
5050: 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 28 64 6f  imatedCost = (do
5060: 75 62 6c 65 29 6e 52 6f 77 3b 0a 20 20 7d 0a 20  uble)nRow;.  }. 
5070: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
5080: 2a 0a 2a 2a 20 54 68 65 20 78 55 70 64 61 74 65  *.** The xUpdate
5090: 20 6d 65 74 68 6f 64 20 66 6f 72 20 65 63 68 6f   method for echo
50a0: 20 6d 6f 64 75 6c 65 20 76 69 72 74 75 61 6c 20   module virtual 
50b0: 74 61 62 6c 65 73 2e 0a 2a 2a 20 0a 2a 2a 20 20  tables..** .**  
50c0: 20 20 61 70 44 61 74 61 5b 30 5d 20 20 61 70 44    apData[0]  apD
50d0: 61 74 61 5b 31 5d 20 20 61 70 44 61 74 61 5b 32  ata[1]  apData[2
50e0: 2e 2e 5d 0a 2a 2a 0a 2a 2a 20 20 20 20 49 4e 54  ..].**.**    INT
50f0: 45 47 45 52 20 20 20 20 20 20 20 20 20 20 20 20  EGER            
5100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5110: 20 20 44 45 4c 45 54 45 20 20 20 20 20 20 20 20    DELETE        
5120: 20 20 20 20 0a 2a 2a 0a 2a 2a 20 20 20 20 49 4e      .**.**    IN
5130: 54 45 47 45 52 20 20 20 20 4e 55 4c 4c 20 20 20  TEGER    NULL   
5140: 20 20 20 20 28 6e 43 6f 6c 20 61 72 67 73 29 20      (nCol args) 
5150: 20 20 20 55 50 44 41 54 45 20 28 64 6f 20 6e 6f     UPDATE (do no
5160: 74 20 73 65 74 20 72 6f 77 69 64 29 0a 2a 2a 20  t set rowid).** 
5170: 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 49 4e     INTEGER    IN
5180: 54 45 47 45 52 20 20 20 20 28 6e 43 6f 6c 20 61  TEGER    (nCol a
5190: 72 67 73 29 20 20 20 20 55 50 44 41 54 45 20 28  rgs)    UPDATE (
51a0: 77 69 74 68 20 53 45 54 20 72 6f 77 69 64 20 3d  with SET rowid =
51b0: 20 3c 61 72 67 31 3e 29 0a 2a 2a 0a 2a 2a 20 20   <arg1>).**.**  
51c0: 20 20 4e 55 4c 4c 20 20 20 20 20 20 20 4e 55 4c    NULL       NUL
51d0: 4c 20 20 20 20 20 20 20 28 6e 43 6f 6c 20 61 72  L       (nCol ar
51e0: 67 73 29 20 20 20 20 49 4e 53 45 52 54 20 49 4e  gs)    INSERT IN
51f0: 54 4f 20 28 61 75 74 6f 6d 61 74 69 63 20 72 6f  TO (automatic ro
5200: 77 69 64 20 76 61 6c 75 65 29 0a 2a 2a 20 20 20  wid value).**   
5210: 20 4e 55 4c 4c 20 20 20 20 20 20 20 49 4e 54 45   NULL       INTE
5220: 47 45 52 20 20 20 20 28 6e 43 6f 6c 20 61 72 67  GER    (nCol arg
5230: 73 29 20 20 20 20 49 4e 53 45 52 54 20 28 69 6e  s)    INSERT (in
5240: 63 6c 2e 20 72 6f 77 69 64 20 76 61 6c 75 65 29  cl. rowid value)
5250: 0a 2a 2a 0a 2a 2f 0a 69 6e 74 20 65 63 68 6f 55  .**.*/.int echoU
5260: 70 64 61 74 65 28 0a 20 20 73 71 6c 69 74 65 33  pdate(.  sqlite3
5270: 5f 76 74 61 62 20 2a 74 61 62 2c 20 0a 20 20 69  _vtab *tab, .  i
5280: 6e 74 20 6e 44 61 74 61 2c 20 0a 20 20 73 71 6c  nt nData, .  sql
5290: 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70 44  ite3_value **apD
52a0: 61 74 61 2c 20 0a 20 20 73 71 6c 69 74 65 5f 69  ata, .  sqlite_i
52b0: 6e 74 36 34 20 2a 70 52 6f 77 69 64 0a 29 7b 0a  nt64 *pRowid.){.
52c0: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
52d0: 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20  ab = (echo_vtab 
52e0: 2a 29 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 33  *)tab;.  sqlite3
52f0: 20 2a 64 62 20 3d 20 70 56 74 61 62 2d 3e 64 62   *db = pVtab->db
5300: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  ;.  int rc = SQL
5310: 49 54 45 5f 4f 4b 3b 0a 0a 20 20 73 71 6c 69 74  ITE_OK;..  sqlit
5320: 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a  e3_stmt *pStmt;.
5330: 20 20 63 68 61 72 20 2a 7a 20 3d 20 30 3b 20 20    char *z = 0;  
5340: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5350: 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 20 74 6f  SQL statement to
5360: 20 65 78 65 63 75 74 65 20 2a 2f 0a 20 20 69 6e   execute */.  in
5370: 74 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d 20  t bindArgZero = 
5380: 30 3b 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65  0;       /* True
5390: 20 74 6f 20 62 69 6e 64 20 61 70 44 61 74 61 5b   to bind apData[
53a0: 30 5d 20 74 6f 20 73 71 6c 20 76 61 72 20 6e 6f  0] to sql var no
53b0: 2e 20 6e 44 61 74 61 20 2a 2f 0a 20 20 69 6e 74  . nData */.  int
53c0: 20 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20 30 3b   bindArgOne = 0;
53d0: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
53e0: 74 6f 20 62 69 6e 64 20 61 70 44 61 74 61 5b 31  to bind apData[1
53f0: 5d 20 74 6f 20 73 71 6c 20 76 61 72 20 6e 6f 2e  ] to sql var no.
5400: 20 31 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20   1 */.  int i;  
5410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5420: 20 20 20 2f 2a 20 43 6f 75 6e 74 65 72 20 76 61     /* Counter va
5430: 72 69 61 62 6c 65 20 75 73 65 64 20 62 79 20 66  riable used by f
5440: 6f 72 20 6c 6f 6f 70 73 20 2a 2f 0a 0a 20 20 61  or loops */..  a
5450: 73 73 65 72 74 28 20 6e 44 61 74 61 3d 3d 70 56  ssert( nData==pV
5460: 74 61 62 2d 3e 6e 43 6f 6c 2b 32 20 7c 7c 20 6e  tab->nCol+2 || n
5470: 44 61 74 61 3d 3d 31 20 29 3b 0a 0a 20 20 2f 2a  Data==1 );..  /*
5480: 20 49 66 20 61 70 44 61 74 61 5b 30 5d 20 69 73   If apData[0] is
5490: 20 61 6e 20 69 6e 74 65 67 65 72 20 61 6e 64 20   an integer and 
54a0: 6e 44 61 74 61 3e 31 20 74 68 65 6e 20 64 6f 20  nData>1 then do 
54b0: 61 6e 20 55 50 44 41 54 45 20 2a 2f 0a 20 20 69  an UPDATE */.  i
54c0: 66 28 20 6e 44 61 74 61 3e 31 20 26 26 20 73 71  f( nData>1 && sq
54d0: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65  lite3_value_type
54e0: 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51 4c  (apData[0])==SQL
54f0: 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20  ITE_INTEGER ){. 
5500: 20 20 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d     z = sqlite3_m
5510: 70 72 69 6e 74 66 28 22 55 50 44 41 54 45 20 25  printf("UPDATE %
5520: 51 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c  Q", pVtab->zTabl
5530: 65 4e 61 6d 65 29 3b 0a 20 20 20 20 63 68 61 72  eName);.    char
5540: 20 2a 7a 53 65 70 20 3d 20 22 20 53 45 54 22 3b   *zSep = " SET";
5550: 0a 0a 20 20 20 20 62 69 6e 64 41 72 67 4f 6e 65  ..    bindArgOne
5560: 20 3d 20 28 61 70 44 61 74 61 5b 31 5d 20 26 26   = (apData[1] &&
5570: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
5580: 79 70 65 28 61 70 44 61 74 61 5b 31 5d 29 3d 3d  ype(apData[1])==
5590: 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 29 3b  SQLITE_INTEGER);
55a0: 0a 20 20 20 20 62 69 6e 64 41 72 67 5a 65 72 6f  .    bindArgZero
55b0: 20 3d 20 31 3b 0a 0a 20 20 20 20 69 66 28 20 62   = 1;..    if( b
55c0: 69 6e 64 41 72 67 4f 6e 65 20 29 7b 0a 20 20 20  indArgOne ){.   
55d0: 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61      string_conca
55e0: 74 28 26 7a 2c 20 22 20 53 45 54 20 72 6f 77 69  t(&z, " SET rowi
55f0: 64 3d 3f 31 20 22 2c 20 30 29 3b 0a 20 20 20 20  d=?1 ", 0);.    
5600: 20 20 20 7a 53 65 70 20 3d 20 22 2c 22 3b 0a 20     zSep = ",";. 
5610: 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 69 3d 32     }.    for(i=2
5620: 3b 20 69 3c 6e 44 61 74 61 3b 20 69 2b 2b 29 7b  ; i<nData; i++){
5630: 0a 20 20 20 20 20 20 69 66 28 20 61 70 44 61 74  .      if( apDat
5640: 61 5b 69 5d 3d 3d 30 20 29 20 63 6f 6e 74 69 6e  a[i]==0 ) contin
5650: 75 65 3b 0a 20 20 20 20 20 20 73 74 72 69 6e 67  ue;.      string
5660: 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 73 71 6c 69  _concat(&z, sqli
5670: 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20 20 20  te3_mprintf(.   
5680: 20 20 20 20 20 20 20 22 25 73 20 25 51 3d 3f 25         "%s %Q=?%
5690: 64 22 2c 20 7a 53 65 70 2c 20 70 56 74 61 62 2d  d", zSep, pVtab-
56a0: 3e 61 43 6f 6c 5b 69 2d 32 5d 2c 20 69 29 2c 20  >aCol[i-2], i), 
56b0: 31 29 3b 0a 20 20 20 20 20 20 7a 53 65 70 20 3d  1);.      zSep =
56c0: 20 22 2c 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20   ",";.    }.    
56d0: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
56e0: 2c 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  , sqlite3_mprint
56f0: 66 28 22 20 57 48 45 52 45 20 72 6f 77 69 64 3d  f(" WHERE rowid=
5700: 3f 25 64 22 2c 20 6e 44 61 74 61 29 2c 20 30 29  ?%d", nData), 0)
5710: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 61  ;.  }..  /* If a
5720: 70 44 61 74 61 5b 30 5d 20 69 73 20 61 6e 20 69  pData[0] is an i
5730: 6e 74 65 67 65 72 20 61 6e 64 20 6e 44 61 74 61  nteger and nData
5740: 3d 3d 31 20 74 68 65 6e 20 64 6f 20 61 20 44 45  ==1 then do a DE
5750: 4c 45 54 45 20 2a 2f 0a 20 20 65 6c 73 65 20 69  LETE */.  else i
5760: 66 28 20 6e 44 61 74 61 3d 3d 31 20 26 26 20 73  f( nData==1 && s
5770: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70  qlite3_value_typ
5780: 65 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51  e(apData[0])==SQ
5790: 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a  LITE_INTEGER ){.
57a0: 20 20 20 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f      z = sqlite3_
57b0: 6d 70 72 69 6e 74 66 28 22 44 45 4c 45 54 45 20  mprintf("DELETE 
57c0: 46 52 4f 4d 20 25 51 20 57 48 45 52 45 20 72 6f  FROM %Q WHERE ro
57d0: 77 69 64 20 3d 20 3f 31 22 2c 20 70 56 74 61 62  wid = ?1", pVtab
57e0: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20  ->zTableName);. 
57f0: 20 20 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d     bindArgZero =
5800: 20 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66   1;.  }..  /* If
5810: 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d   the first argum
5820: 65 6e 74 20 69 73 20 4e 55 4c 4c 20 61 6e 64 20  ent is NULL and 
5830: 74 68 65 72 65 20 61 72 65 20 6d 6f 72 65 20 74  there are more t
5840: 68 61 6e 20 74 77 6f 20 61 72 67 73 2c 20 49 4e  han two args, IN
5850: 53 45 52 54 20 2a 2f 0a 20 20 65 6c 73 65 20 69  SERT */.  else i
5860: 66 28 20 6e 44 61 74 61 3e 32 20 26 26 20 73 71  f( nData>2 && sq
5870: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65  lite3_value_type
5880: 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51 4c  (apData[0])==SQL
5890: 49 54 45 5f 4e 55 4c 4c 20 29 7b 0a 20 20 20 20  ITE_NULL ){.    
58a0: 69 6e 74 20 69 69 3b 0a 20 20 20 20 63 68 61 72  int ii;.    char
58b0: 20 2a 7a 49 6e 73 65 72 74 20 3d 20 30 3b 0a 20   *zInsert = 0;. 
58c0: 20 20 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 73     char *zValues
58d0: 20 3d 20 30 3b 0a 20 20 0a 20 20 20 20 7a 49 6e   = 0;.  .    zIn
58e0: 73 65 72 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d  sert = sqlite3_m
58f0: 70 72 69 6e 74 66 28 22 49 4e 53 45 52 54 20 49  printf("INSERT I
5900: 4e 54 4f 20 25 51 20 28 22 2c 20 70 56 74 61 62  NTO %Q (", pVtab
5910: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20  ->zTableName);. 
5920: 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 76     if( sqlite3_v
5930: 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61 74 61  alue_type(apData
5940: 5b 31 5d 29 3d 3d 53 51 4c 49 54 45 5f 49 4e 54  [1])==SQLITE_INT
5950: 45 47 45 52 20 29 7b 0a 20 20 20 20 20 20 62 69  EGER ){.      bi
5960: 6e 64 41 72 67 4f 6e 65 20 3d 20 31 3b 0a 20 20  ndArgOne = 1;.  
5970: 20 20 20 20 7a 56 61 6c 75 65 73 20 3d 20 73 71      zValues = sq
5980: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 3f  lite3_mprintf("?
5990: 22 29 3b 0a 20 20 20 20 20 20 73 74 72 69 6e 67  ");.      string
59a0: 5f 63 6f 6e 63 61 74 28 26 7a 49 6e 73 65 72 74  _concat(&zInsert
59b0: 2c 20 22 72 6f 77 69 64 22 2c 20 30 29 3b 0a 20  , "rowid", 0);. 
59c0: 20 20 20 7d 0a 0a 20 20 20 20 61 73 73 65 72 74     }..    assert
59d0: 28 28 70 56 74 61 62 2d 3e 6e 43 6f 6c 2b 32 29  ((pVtab->nCol+2)
59e0: 3d 3d 6e 44 61 74 61 29 3b 0a 20 20 20 20 66 6f  ==nData);.    fo
59f0: 72 28 69 69 3d 32 3b 20 69 69 3c 6e 44 61 74 61  r(ii=2; ii<nData
5a00: 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73  ; ii++){.      s
5a10: 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 49  tring_concat(&zI
5a20: 6e 73 65 72 74 2c 20 0a 20 20 20 20 20 20 20 20  nsert, .        
5a30: 20 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74    sqlite3_mprint
5a40: 66 28 22 25 73 25 51 22 2c 20 7a 56 61 6c 75 65  f("%s%Q", zValue
5a50: 73 3f 22 2c 20 22 3a 22 22 2c 20 70 56 74 61 62  s?", ":"", pVtab
5a60: 2d 3e 61 43 6f 6c 5b 69 69 2d 32 5d 29 2c 20 31  ->aCol[ii-2]), 1
5a70: 29 3b 0a 20 20 20 20 20 20 73 74 72 69 6e 67 5f  );.      string_
5a80: 63 6f 6e 63 61 74 28 26 7a 56 61 6c 75 65 73 2c  concat(&zValues,
5a90: 20 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c 69   .          sqli
5aa0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 3f  te3_mprintf("%s?
5ab0: 25 64 22 2c 20 7a 56 61 6c 75 65 73 3f 22 2c 20  %d", zValues?", 
5ac0: 22 3a 22 22 2c 20 69 69 29 2c 20 31 29 3b 0a 20  ":"", ii), 1);. 
5ad0: 20 20 20 7d 0a 0a 20 20 20 20 73 74 72 69 6e 67     }..    string
5ae0: 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 7a 49 6e 73  _concat(&z, zIns
5af0: 65 72 74 2c 20 31 29 3b 0a 20 20 20 20 73 74 72  ert, 1);.    str
5b00: 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 22  ing_concat(&z, "
5b10: 29 20 56 41 4c 55 45 53 28 22 2c 20 30 29 3b 0a  ) VALUES(", 0);.
5b20: 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61      string_conca
5b30: 74 28 26 7a 2c 20 7a 56 61 6c 75 65 73 2c 20 31  t(&z, zValues, 1
5b40: 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f  );.    string_co
5b50: 6e 63 61 74 28 26 7a 2c 20 22 29 22 2c 20 30 29  ncat(&z, ")", 0)
5b60: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 6e 79 74  ;.  }..  /* Anyt
5b70: 68 69 6e 67 20 65 6c 73 65 20 69 73 20 61 6e 20  hing else is an 
5b80: 65 72 72 6f 72 20 2a 2f 0a 20 20 65 6c 73 65 7b  error */.  else{
5b90: 0a 20 20 20 20 61 73 73 65 72 74 28 30 29 3b 0a  .    assert(0);.
5ba0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
5bb0: 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20  E_ERROR;.  }..  
5bc0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65  rc = sqlite3_pre
5bd0: 70 61 72 65 28 64 62 2c 20 7a 2c 20 2d 31 2c 20  pare(db, z, -1, 
5be0: 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 61 73  &pStmt, 0);.  as
5bf0: 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45  sert( rc!=SQLITE
5c00: 5f 4f 4b 20 7c 7c 20 70 53 74 6d 74 20 29 3b 0a  _OK || pStmt );.
5c10: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
5c20: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  );.  if( rc==SQL
5c30: 49 54 45 5f 4f 4b 20 29 20 7b 0a 20 20 20 20 69  ITE_OK ) {.    i
5c40: 66 28 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 29  f( bindArgZero )
5c50: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
5c60: 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d 74  bind_value(pStmt
5c70: 2c 20 6e 44 61 74 61 2c 20 61 70 44 61 74 61 5b  , nData, apData[
5c80: 30 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  0]);.    }.    i
5c90: 66 28 20 62 69 6e 64 41 72 67 4f 6e 65 20 29 7b  f( bindArgOne ){
5ca0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 62  .      sqlite3_b
5cb0: 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c  ind_value(pStmt,
5cc0: 20 31 2c 20 61 70 44 61 74 61 5b 31 5d 29 3b 0a   1, apData[1]);.
5cd0: 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 69 3d      }.    for(i=
5ce0: 32 3b 20 69 3c 6e 44 61 74 61 3b 20 69 2b 2b 29  2; i<nData; i++)
5cf0: 7b 0a 20 20 20 20 20 20 69 66 28 20 61 70 44 61  {.      if( apDa
5d00: 74 61 5b 69 5d 20 29 20 73 71 6c 69 74 65 33 5f  ta[i] ) sqlite3_
5d10: 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d 74  bind_value(pStmt
5d20: 2c 20 69 2c 20 61 70 44 61 74 61 5b 69 5d 29 3b  , i, apData[i]);
5d30: 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74  .    }.    sqlit
5d40: 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 3b 0a  e3_step(pStmt);.
5d50: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
5d60: 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29  _finalize(pStmt)
5d70: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 52 6f  ;.  }..  if( pRo
5d80: 77 69 64 20 26 26 20 72 63 3d 3d 53 51 4c 49 54  wid && rc==SQLIT
5d90: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 52 6f  E_OK ){.    *pRo
5da0: 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 6c 61  wid = sqlite3_la
5db0: 73 74 5f 69 6e 73 65 72 74 5f 72 6f 77 69 64 28  st_insert_rowid(
5dc0: 64 62 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  db);.  }..  retu
5dd0: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
5de0: 78 42 65 67 69 6e 2c 20 78 53 79 6e 63 2c 20 78  xBegin, xSync, x
5df0: 43 6f 6d 6d 69 74 20 61 6e 64 20 78 52 6f 6c 6c  Commit and xRoll
5e00: 62 61 63 6b 20 63 61 6c 6c 62 61 63 6b 73 20 66  back callbacks f
5e10: 6f 72 20 65 63 68 6f 20 6d 6f 64 75 6c 65 0a 2a  or echo module.*
5e20: 2a 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 73  * virtual tables
5e30: 2e 20 44 6f 20 6e 6f 74 68 69 6e 67 20 6f 74 68  . Do nothing oth
5e40: 65 72 20 74 68 61 6e 20 61 64 64 20 74 68 65 20  er than add the 
5e50: 6e 61 6d 65 20 6f 66 20 74 68 65 20 63 61 6c 6c  name of the call
5e60: 62 61 63 6b 0a 2a 2a 20 74 6f 20 74 68 65 20 24  back.** to the $
5e70: 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 54 63  ::echo_module Tc
5e80: 6c 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2f 0a 73  l variable..*/.s
5e90: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 54 72  tatic int echoTr
5ea0: 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 73 71  ansactionCall(sq
5eb0: 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62 2c  lite3_vtab *tab,
5ec0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 61   const char *zCa
5ed0: 6c 6c 29 7b 0a 20 20 63 68 61 72 20 2a 7a 3b 0a  ll){.  char *z;.
5ee0: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
5ef0: 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20  ab = (echo_vtab 
5f00: 2a 29 74 61 62 3b 0a 20 20 7a 20 3d 20 73 71 6c  *)tab;.  z = sql
5f10: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 65 63  ite3_mprintf("ec
5f20: 68 6f 28 25 73 29 22 2c 20 70 56 74 61 62 2d 3e  ho(%s)", pVtab->
5f30: 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 61  zTableName);.  a
5f40: 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c  ppendToEchoModul
5f50: 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c  e(pVtab->interp,
5f60: 20 7a 43 61 6c 6c 29 3b 0a 20 20 61 70 70 65 6e   zCall);.  appen
5f70: 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56  dToEchoModule(pV
5f80: 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 7a 29 3b  tab->interp, z);
5f90: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
5fa0: 7a 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  z);.  return SQL
5fb0: 49 54 45 5f 4f 4b 3b 0a 7d 0a 73 74 61 74 69 63  ITE_OK;.}.static
5fc0: 20 69 6e 74 20 65 63 68 6f 42 65 67 69 6e 28 73   int echoBegin(s
5fd0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62  qlite3_vtab *tab
5fe0: 29 7b 0a 20 20 72 65 74 75 72 6e 20 65 63 68 6f  ){.  return echo
5ff0: 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28  TransactionCall(
6000: 74 61 62 2c 20 22 78 42 65 67 69 6e 22 29 3b 0a  tab, "xBegin");.
6010: 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  }.static int ech
6020: 6f 53 79 6e 63 28 73 71 6c 69 74 65 33 5f 76 74  oSync(sqlite3_vt
6030: 61 62 20 2a 74 61 62 29 7b 0a 20 20 65 63 68 6f  ab *tab){.  echo
6040: 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28  _vtab *pVtab = (
6050: 65 63 68 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b  echo_vtab *)tab;
6060: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
6070: 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d 3e 69  nterp = pVtab->i
6080: 6e 74 65 72 70 3b 0a 20 20 63 6f 6e 73 74 20 63  nterp;.  const c
6090: 68 61 72 20 2a 7a 56 61 6c 3b 20 0a 0a 20 20 65  har *zVal; ..  e
60a0: 63 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61  choTransactionCa
60b0: 6c 6c 28 74 61 62 2c 20 22 78 53 79 6e 63 22 29  ll(tab, "xSync")
60c0: 3b 0a 0a 20 20 2f 2a 20 43 68 65 63 6b 20 69 66  ;..  /* Check if
60d0: 20 74 68 65 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64   the $::echo_mod
60e0: 75 6c 65 5f 73 79 6e 63 5f 66 61 69 6c 20 76 61  ule_sync_fail va
60f0: 72 69 61 62 6c 65 20 69 73 20 64 65 66 69 6e 65  riable is define
6100: 64 2e 20 49 66 20 69 74 20 69 73 2c 0a 20 20 2a  d. If it is,.  *
6110: 2a 20 61 6e 64 20 69 74 20 69 73 20 73 65 74 20  * and it is set 
6120: 74 6f 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74  to the name of t
6130: 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20 75 6e  he real table un
6140: 64 65 72 6c 79 69 6e 67 20 74 68 69 73 20 76 69  derlying this vi
6150: 72 74 75 61 6c 0a 20 20 2a 2a 20 65 63 68 6f 20  rtual.  ** echo 
6160: 6d 6f 64 75 6c 65 20 74 61 62 6c 65 2c 20 74 68  module table, th
6170: 65 6e 20 63 61 75 73 65 20 74 68 69 73 20 78 53  en cause this xS
6180: 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e 20 74 6f  ync operation to
6190: 20 66 61 69 6c 2e 0a 20 20 2a 2f 0a 20 20 7a 56   fail..  */.  zV
61a0: 61 6c 20 3d 20 54 63 6c 5f 47 65 74 56 61 72 28  al = Tcl_GetVar(
61b0: 69 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f  interp, "echo_mo
61c0: 64 75 6c 65 5f 73 79 6e 63 5f 66 61 69 6c 22 2c  dule_sync_fail",
61d0: 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59   TCL_GLOBAL_ONLY
61e0: 29 3b 0a 20 20 69 66 28 20 7a 56 61 6c 20 26 26  );.  if( zVal &&
61f0: 20 30 3d 3d 73 74 72 63 6d 70 28 7a 56 61 6c 2c   0==strcmp(zVal,
6200: 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61   pVtab->zTableNa
6210: 6d 65 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72  me) ){.    retur
6220: 6e 20 2d 31 3b 0a 20 20 7d 0a 20 20 72 65 74 75  n -1;.  }.  retu
6230: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
6240: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43  static int echoC
6250: 6f 6d 6d 69 74 28 73 71 6c 69 74 65 33 5f 76 74  ommit(sqlite3_vt
6260: 61 62 20 2a 74 61 62 29 7b 0a 20 20 72 65 74 75  ab *tab){.  retu
6270: 72 6e 20 65 63 68 6f 54 72 61 6e 73 61 63 74 69  rn echoTransacti
6280: 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 43 6f  onCall(tab, "xCo
6290: 6d 6d 69 74 22 29 3b 0a 7d 0a 73 74 61 74 69 63  mmit");.}.static
62a0: 20 69 6e 74 20 65 63 68 6f 52 6f 6c 6c 62 61 63   int echoRollbac
62b0: 6b 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  k(sqlite3_vtab *
62c0: 74 61 62 29 7b 0a 20 20 72 65 74 75 72 6e 20 65  tab){.  return e
62d0: 63 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61  choTransactionCa
62e0: 6c 6c 28 74 61 62 2c 20 22 78 52 6f 6c 6c 62 61  ll(tab, "xRollba
62f0: 63 6b 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  ck");.}../*.** A
6300: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d   virtual table m
6310: 6f 64 75 6c 65 20 74 68 61 74 20 6d 65 72 65 6c  odule that merel
6320: 79 20 22 65 63 68 6f 73 22 20 74 68 65 20 63 6f  y "echos" the co
6330: 6e 74 65 6e 74 73 20 6f 66 20 61 6e 6f 74 68 65  ntents of anothe
6340: 72 0a 2a 2a 20 74 61 62 6c 65 20 28 6c 69 6b 65  r.** table (like
6350: 20 61 6e 20 53 51 4c 20 56 49 45 57 29 2e 0a 2a   an SQL VIEW)..*
6360: 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33  /.static sqlite3
6370: 5f 6d 6f 64 75 6c 65 20 65 63 68 6f 4d 6f 64 75  _module echoModu
6380: 6c 65 20 3d 20 7b 0a 20 20 30 2c 20 20 20 20 20  le = {.  0,     
6390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
63a0: 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20      /* iVersion 
63b0: 2a 2f 0a 20 20 22 65 63 68 6f 22 2c 20 20 20 20  */.  "echo",    
63c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
63d0: 2f 2a 20 7a 4e 61 6d 65 20 2a 2f 0a 20 20 65 63  /* zName */.  ec
63e0: 68 6f 43 72 65 61 74 65 2c 0a 20 20 65 63 68 6f  hoCreate,.  echo
63f0: 43 6f 6e 6e 65 63 74 2c 0a 20 20 65 63 68 6f 42  Connect,.  echoB
6400: 65 73 74 49 6e 64 65 78 2c 0a 20 20 65 63 68 6f  estIndex,.  echo
6410: 44 69 73 63 6f 6e 6e 65 63 74 2c 20 0a 20 20 65  Disconnect, .  e
6420: 63 68 6f 44 65 73 74 72 6f 79 2c 0a 20 20 65 63  choDestroy,.  ec
6430: 68 6f 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20  hoOpen,         
6440: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4f 70 65           /* xOpe
6450: 6e 20 2d 20 6f 70 65 6e 20 61 20 63 75 72 73 6f  n - open a curso
6460: 72 20 2a 2f 0a 20 20 65 63 68 6f 43 6c 6f 73 65  r */.  echoClose
6470: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
6480: 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c    /* xClose - cl
6490: 6f 73 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a  ose a cursor */.
64a0: 20 20 65 63 68 6f 46 69 6c 74 65 72 2c 20 20 20    echoFilter,   
64b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
64c0: 78 46 69 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67  xFilter - config
64d0: 75 72 65 20 73 63 61 6e 20 63 6f 6e 73 74 72 61  ure scan constra
64e0: 69 6e 74 73 20 2a 2f 0a 20 20 65 63 68 6f 4e 65  ints */.  echoNe
64f0: 78 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  xt,             
6500: 20 20 20 20 20 2f 2a 20 78 4e 65 78 74 20 2d 20       /* xNext - 
6510: 61 64 76 61 6e 63 65 20 61 20 63 75 72 73 6f 72  advance a cursor
6520: 20 2a 2f 0a 20 20 65 63 68 6f 45 6f 66 2c 20 20   */.  echoEof,  
6530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6540: 20 2f 2a 20 78 45 6f 66 20 2a 2f 0a 20 20 65 63   /* xEof */.  ec
6550: 68 6f 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20  hoColumn,       
6560: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6c           /* xCol
6570: 75 6d 6e 20 2d 20 72 65 61 64 20 64 61 74 61 20  umn - read data 
6580: 2a 2f 0a 20 20 65 63 68 6f 52 6f 77 69 64 2c 20  */.  echoRowid, 
6590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
65a0: 2f 2a 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64  /* xRowid - read
65b0: 20 64 61 74 61 20 2a 2f 0a 20 20 65 63 68 6f 55   data */.  echoU
65c0: 70 64 61 74 65 2c 20 20 20 20 20 20 20 20 20 20  pdate,          
65d0: 20 20 20 20 20 20 2f 2a 20 78 55 70 64 61 74 65        /* xUpdate
65e0: 20 2d 20 77 72 69 74 65 20 64 61 74 61 20 2a 2f   - write data */
65f0: 0a 20 20 65 63 68 6f 42 65 67 69 6e 2c 20 20 20  .  echoBegin,   
6600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6610: 20 78 42 65 67 69 6e 20 2d 20 62 65 67 69 6e 20   xBegin - begin 
6620: 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20  transaction */. 
6630: 20 65 63 68 6f 53 79 6e 63 2c 20 20 20 20 20 20   echoSync,      
6640: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
6650: 53 79 6e 63 20 2d 20 73 79 6e 63 20 74 72 61 6e  Sync - sync tran
6660: 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68  saction */.  ech
6670: 6f 43 6f 6d 6d 69 74 2c 20 20 20 20 20 20 20 20  oCommit,        
6680: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6d 6d          /* xComm
6690: 69 74 20 2d 20 63 6f 6d 6d 69 74 20 74 72 61 6e  it - commit tran
66a0: 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68  saction */.  ech
66b0: 6f 52 6f 6c 6c 62 61 63 6b 20 20 20 20 20 20 20  oRollback       
66c0: 20 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c          /* xRoll
66d0: 62 61 63 6b 20 2d 20 72 6f 6c 6c 62 61 63 6b 20  back - rollback 
66e0: 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 7d  transaction */.}
66f0: 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65 63 6f 64 65 20  ;../*.** Decode 
6700: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 6e 20  a pointer to an 
6710: 73 71 6c 69 74 65 33 20 6f 62 6a 65 63 74 2e 0a  sqlite3 object..
6720: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 67 65  */.static int ge
6730: 74 44 62 50 6f 69 6e 74 65 72 28 54 63 6c 5f 49  tDbPointer(Tcl_I
6740: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 63  nterp *interp, c
6750: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 2c 20 73  onst char *zA, s
6760: 71 6c 69 74 65 33 20 2a 2a 70 70 44 62 29 7b 0a  qlite3 **ppDb){.
6770: 20 20 2a 70 70 44 62 20 3d 20 28 73 71 6c 69 74    *ppDb = (sqlit
6780: 65 33 2a 29 73 71 6c 69 74 65 33 54 65 78 74 54  e3*)sqlite3TextT
6790: 6f 50 74 72 28 7a 41 29 3b 0a 20 20 72 65 74 75  oPtr(zA);.  retu
67a0: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  rn TCL_OK;.}../*
67b0: 0a 2a 2a 20 52 65 67 69 73 74 65 72 20 74 68 65  .** Register the
67c0: 20 65 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   echo virtual ta
67d0: 62 6c 65 20 6d 6f 64 75 6c 65 2e 0a 2a 2f 0a 73  ble module..*/.s
67e0: 74 61 74 69 63 20 69 6e 74 20 72 65 67 69 73 74  tatic int regist
67f0: 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c 65 28 0a  er_echo_module(.
6800: 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63 6c 69    ClientData cli
6810: 65 6e 74 44 61 74 61 2c 20 2f 2a 20 50 6f 69 6e  entData, /* Poin
6820: 74 65 72 20 74 6f 20 73 71 6c 69 74 65 33 5f 65  ter to sqlite3_e
6830: 6e 61 62 6c 65 5f 58 58 58 20 66 75 6e 63 74 69  nable_XXX functi
6840: 6f 6e 20 2a 2f 0a 20 20 54 63 6c 5f 49 6e 74 65  on */.  Tcl_Inte
6850: 72 70 20 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f  rp *interp,    /
6860: 2a 20 54 68 65 20 54 43 4c 20 69 6e 74 65 72 70  * The TCL interp
6870: 72 65 74 65 72 20 74 68 61 74 20 69 6e 76 6f 6b  reter that invok
6880: 65 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20  ed this command 
6890: 2a 2f 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 20 20  */.  int objc,  
68a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
68b0: 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65 6e  umber of argumen
68c0: 74 73 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20  ts */.  Tcl_Obj 
68d0: 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 20 20 2f  *CONST objv[]  /
68e0: 2a 20 43 6f 6d 6d 61 6e 64 20 61 72 67 75 6d 65  * Command argume
68f0: 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69  nts */.){.  sqli
6900: 74 65 33 20 2a 64 62 3b 0a 20 20 69 66 28 20 6f  te3 *db;.  if( o
6910: 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63  bjc!=2 ){.    Tc
6920: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69  l_WrongNumArgs(i
6930: 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20  nterp, 1, objv, 
6940: 22 44 42 22 29 3b 0a 20 20 20 20 72 65 74 75 72  "DB");.    retur
6950: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
6960: 0a 20 20 69 66 28 20 67 65 74 44 62 50 6f 69 6e  .  if( getDbPoin
6970: 74 65 72 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  ter(interp, Tcl_
6980: 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31  GetString(objv[1
6990: 5d 29 2c 20 26 64 62 29 20 29 20 72 65 74 75 72  ]), &db) ) retur
69a0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 73  n TCL_ERROR;.  s
69b0: 71 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f  qlite3_create_mo
69c0: 64 75 6c 65 28 64 62 2c 20 22 65 63 68 6f 22 2c  dule(db, "echo",
69d0: 20 26 65 63 68 6f 4d 6f 64 75 6c 65 2c 20 28 76   &echoModule, (v
69e0: 6f 69 64 20 2a 29 69 6e 74 65 72 70 29 3b 0a 20  oid *)interp);. 
69f0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a   return TCL_OK;.
6a00: 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 69 66 6e  }..#endif /* ifn
6a10: 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f  def SQLITE_OMIT_
6a20: 56 49 52 54 55 41 4c 54 41 42 4c 45 20 2a 2f 0a  VIRTUALTABLE */.
6a30: 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72 20  ./*.** Register 
6a40: 63 6f 6d 6d 61 6e 64 73 20 77 69 74 68 20 74 68  commands with th
6a50: 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65  e TCL interprete
6a60: 72 2e 0a 2a 2f 0a 69 6e 74 20 53 71 6c 69 74 65  r..*/.int Sqlite
6a70: 74 65 73 74 38 5f 49 6e 69 74 28 54 63 6c 5f 49  test8_Init(Tcl_I
6a80: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29 7b 0a  nterp *interp){.
6a90: 20 20 73 74 61 74 69 63 20 73 74 72 75 63 74 20    static struct 
6aa0: 7b 0a 20 20 20 20 20 63 68 61 72 20 2a 7a 4e 61  {.     char *zNa
6ab0: 6d 65 3b 0a 20 20 20 20 20 54 63 6c 5f 4f 62 6a  me;.     Tcl_Obj
6ac0: 43 6d 64 50 72 6f 63 20 2a 78 50 72 6f 63 3b 0a  CmdProc *xProc;.
6ad0: 20 20 20 20 20 76 6f 69 64 20 2a 63 6c 69 65 6e       void *clien
6ae0: 74 44 61 74 61 3b 0a 20 20 7d 20 61 4f 62 6a 43  tData;.  } aObjC
6af0: 6d 64 5b 5d 20 3d 20 7b 0a 23 69 66 6e 64 65 66  md[] = {.#ifndef
6b00: 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52   SQLITE_OMIT_VIR
6b10: 54 55 41 4c 54 41 42 4c 45 0a 20 20 20 20 20 7b  TUALTABLE.     {
6b20: 20 22 72 65 67 69 73 74 65 72 5f 65 63 68 6f 5f   "register_echo_
6b30: 6d 6f 64 75 6c 65 22 2c 20 20 20 72 65 67 69 73  module",   regis
6b40: 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c 65 2c  ter_echo_module,
6b50: 20 30 20 7d 2c 0a 23 65 6e 64 69 66 0a 20 20 7d   0 },.#endif.  }
6b60: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72  ;.  int i;.  for
6b70: 28 69 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61  (i=0; i<sizeof(a
6b80: 4f 62 6a 43 6d 64 29 2f 73 69 7a 65 6f 66 28 61  ObjCmd)/sizeof(a
6b90: 4f 62 6a 43 6d 64 5b 30 5d 29 3b 20 69 2b 2b 29  ObjCmd[0]); i++)
6ba0: 7b 0a 20 20 20 20 54 63 6c 5f 43 72 65 61 74 65  {.    Tcl_Create
6bb0: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
6bc0: 70 2c 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 7a 4e  p, aObjCmd[i].zN
6bd0: 61 6d 65 2c 20 0a 20 20 20 20 20 20 20 20 61 4f  ame, .        aO
6be0: 62 6a 43 6d 64 5b 69 5d 2e 78 50 72 6f 63 2c 20  bjCmd[i].xProc, 
6bf0: 61 4f 62 6a 43 6d 64 5b 69 5d 2e 63 6c 69 65 6e  aObjCmd[i].clien
6c00: 74 44 61 74 61 2c 20 30 29 3b 0a 20 20 7d 0a 20  tData, 0);.  }. 
6c10: 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a   return TCL_OK;.
6c20: 7d 0a                                            }.