/ Hex Artifact Content
Login

Artifact 3e0d66d6b82bd2dda88031788a9169e322b3bf5f:


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 36 20 32  test8.c,v 1.36 2
0230: 30 30 36 2f 30 36 2f 32 34 20 30 39 3a 33 34 3a  006/06/24 09:34:
0240: 32 33 20 64 61 6e 69 65 6c 6b 31 39 37 37 20 45  23 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 20  le_sync_fail.** 
03d0: 20 20 20 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75      $::echo_modu
03e0: 6c 65 5f 62 65 67 69 6e 5f 66 61 69 6c 0a 2a 2a  le_begin_fail.**
03f0: 0a 2a 2a 20 54 68 65 20 76 61 72 69 61 62 6c 65  .** The variable
0400: 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 69   ::echo_module i
0410: 73 20 61 20 6c 69 73 74 2e 20 45 61 63 68 20 74  s a list. Each t
0420: 69 6d 65 20 6f 6e 65 20 6f 66 20 74 68 65 20 66  ime one of the f
0430: 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 6d 65 74 68  ollowing.** meth
0440: 6f 64 73 20 69 73 20 63 61 6c 6c 65 64 2c 20 6f  ods is called, o
0450: 6e 65 20 6f 72 20 6d 6f 72 65 20 65 6c 65 6d 65  ne or more eleme
0460: 6e 74 73 20 61 72 65 20 61 70 70 65 6e 64 65 64  nts are appended
0470: 20 74 6f 20 74 68 65 20 6c 69 73 74 2e 0a 2a 2a   to the list..**
0480: 20 54 68 69 73 20 69 73 20 75 73 65 64 20 66 6f   This is used fo
0490: 72 20 61 75 74 6f 6d 61 74 65 64 20 74 65 73 74  r automated test
04a0: 69 6e 67 20 6f 66 20 76 69 72 74 75 61 6c 20 74  ing of virtual t
04b0: 61 62 6c 65 20 6d 6f 64 75 6c 65 73 2e 0a 2a 2a  able modules..**
04c0: 0a 2a 2a 20 54 68 65 20 3a 3a 65 63 68 6f 5f 6d  .** The ::echo_m
04d0: 6f 64 75 6c 65 5f 73 79 6e 63 5f 66 61 69 6c 20  odule_sync_fail 
04e0: 76 61 72 69 61 62 6c 65 20 69 73 20 73 65 74 20  variable is set 
04f0: 62 79 20 74 65 73 74 20 73 63 72 69 70 74 73 20  by test scripts 
0500: 61 6e 64 20 72 65 61 64 0a 2a 2a 20 62 79 20 63  and read.** by c
0510: 6f 64 65 20 69 6e 20 74 68 69 73 20 66 69 6c 65  ode in this file
0520: 2e 20 49 66 20 69 74 20 69 73 20 73 65 74 20 74  . If it is set t
0530: 6f 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 61 20  o the name of a 
0540: 72 65 61 6c 20 74 61 62 6c 65 20 69 6e 20 74 68  real table in th
0550: 65 0a 2a 2a 20 74 68 65 20 64 61 74 61 62 61 73  e.** the databas
0560: 65 2c 20 74 68 65 6e 20 61 6c 6c 20 78 53 79 6e  e, then all xSyn
0570: 63 20 6f 70 65 72 61 74 69 6f 6e 73 20 6f 6e 20  c operations on 
0580: 65 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62  echo virtual tab
0590: 6c 65 73 20 74 68 61 74 0a 2a 2a 20 75 73 65 20  les that.** use 
05a0: 74 68 65 20 6e 61 6d 65 64 20 74 61 62 6c 65 20  the named table 
05b0: 61 73 20 61 20 62 61 63 6b 69 6e 67 20 73 74 6f  as a backing sto
05c0: 72 65 20 77 69 6c 6c 20 66 61 69 6c 2e 0a 2a 2f  re will fail..*/
05d0: 0a 0a 2f 2a 20 0a 2a 2a 20 41 6e 20 65 63 68 6f  ../* .** An echo
05e0: 20 76 69 72 74 75 61 6c 2d 74 61 62 6c 65 20 6f   virtual-table o
05f0: 62 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 65 63 68  bject..**.** ech
0600: 6f 2e 76 74 61 62 2e 61 49 6e 64 65 78 20 69 73  o.vtab.aIndex is
0610: 20 61 6e 20 61 72 72 61 79 20 6f 66 20 62 6f 6f   an array of boo
0620: 6c 65 61 6e 73 2e 20 54 68 65 20 6e 74 68 20 65  leans. The nth e
0630: 6e 74 72 79 20 69 73 20 74 72 75 65 20 69 66 20  ntry is true if 
0640: 0a 2a 2a 20 74 68 65 20 6e 74 68 20 63 6f 6c 75  .** the nth colu
0650: 6d 6e 20 6f 66 20 74 68 65 20 72 65 61 6c 20 74  mn of the real t
0660: 61 62 6c 65 20 69 73 20 74 68 65 20 6c 65 66 74  able is the left
0670: 2d 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20 6f 66 20  -most column of 
0680: 61 6e 20 69 6e 64 65 78 0a 2a 2a 20 28 69 6d 70  an index.** (imp
0690: 6c 69 63 69 74 20 6f 72 20 6f 74 68 65 72 77 69  licit or otherwi
06a0: 73 65 29 2e 20 49 6e 20 6f 74 68 65 72 20 77 6f  se). In other wo
06b0: 72 64 73 2c 20 69 66 20 53 51 4c 69 74 65 20 63  rds, if SQLite c
06c0: 61 6e 20 6f 70 74 69 6d 69 7a 65 0a 2a 2a 20 61  an optimize.** a
06d0: 20 71 75 65 72 79 20 6c 69 6b 65 20 22 53 45 4c   query like "SEL
06e0: 45 43 54 20 2a 20 46 52 4f 4d 20 72 65 61 6c 5f  ECT * FROM real_
06f0: 74 61 62 6c 65 20 57 48 45 52 45 20 63 6f 6c 20  table WHERE col 
0700: 3d 20 3f 22 2e 0a 2a 2a 0a 2a 2a 20 4d 65 6d 62  = ?"..**.** Memb
0710: 65 72 20 76 61 72 69 61 62 6c 65 20 61 43 6f 6c  er variable aCol
0720: 5b 5d 20 63 6f 6e 74 61 69 6e 73 20 63 6f 70 69  [] contains copi
0730: 65 73 20 6f 66 20 74 68 65 20 63 6f 6c 75 6d 6e  es of the column
0740: 20 6e 61 6d 65 73 20 6f 66 20 74 68 65 20 72 65   names of the re
0750: 61 6c 0a 2a 2a 20 74 61 62 6c 65 2e 0a 2a 2f 0a  al.** table..*/.
0760: 73 74 72 75 63 74 20 65 63 68 6f 5f 76 74 61 62  struct echo_vtab
0770: 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61   {.  sqlite3_vta
0780: 62 20 62 61 73 65 3b 0a 20 20 54 63 6c 5f 49 6e  b base;.  Tcl_In
0790: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 20 20 20  terp *interp;   
07a0: 20 20 2f 2a 20 54 63 6c 20 69 6e 74 65 72 70 72    /* Tcl interpr
07b0: 65 74 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20  eter containing 
07c0: 64 65 62 75 67 20 76 61 72 69 61 62 6c 65 73 20  debug variables 
07d0: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  */.  sqlite3 *db
07e0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
07f0: 44 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74  Database connect
0800: 69 6f 6e 20 2a 2f 0a 0a 20 20 63 68 61 72 20 2a  ion */..  char *
0810: 7a 54 61 62 6c 65 4e 61 6d 65 3b 20 20 20 20 20  zTableName;     
0820: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65    /* Name of the
0830: 20 72 65 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20   real table */. 
0840: 20 63 68 61 72 20 2a 7a 4c 6f 67 4e 61 6d 65 3b   char *zLogName;
0850: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65           /* Name
0860: 20 6f 66 20 74 68 65 20 6c 6f 67 20 74 61 62 6c   of the log tabl
0870: 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 3b  e */.  int nCol;
0880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0890: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75  * Number of colu
08a0: 6d 6e 73 20 69 6e 20 74 68 65 20 72 65 61 6c 20  mns in the real 
08b0: 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 2a  table */.  int *
08c0: 61 49 6e 64 65 78 3b 20 20 20 20 20 20 20 20 20  aIndex;         
08d0: 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 73     /* Array of s
08e0: 69 7a 65 20 6e 43 6f 6c 2e 20 54 72 75 65 20 69  ize nCol. True i
08f0: 66 20 63 6f 6c 75 6d 6e 20 68 61 73 20 61 6e 20  f column has an 
0900: 69 6e 64 65 78 20 2a 2f 0a 20 20 63 68 61 72 20  index */.  char 
0910: 2a 2a 61 43 6f 6c 3b 20 20 20 20 20 20 20 20 20  **aCol;         
0920: 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 73     /* Array of s
0930: 69 7a 65 20 6e 43 6f 6c 2e 20 43 6f 6c 75 6d 6e  ize nCol. Column
0940: 20 6e 61 6d 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a   names */.};../*
0950: 20 41 6e 20 65 63 68 6f 20 63 75 72 73 6f 72 20   An echo cursor 
0960: 6f 62 6a 65 63 74 20 2a 2f 0a 73 74 72 75 63 74  object */.struct
0970: 20 65 63 68 6f 5f 63 75 72 73 6f 72 20 7b 0a 20   echo_cursor {. 
0980: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75   sqlite3_vtab_cu
0990: 72 73 6f 72 20 62 61 73 65 3b 0a 20 20 73 71 6c  rsor base;.  sql
09a0: 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74  ite3_stmt *pStmt
09b0: 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 72  ;.};../*.** Retr
09c0: 69 65 76 65 20 74 68 65 20 63 6f 6c 75 6d 6e 20  ieve the column 
09d0: 6e 61 6d 65 73 20 66 6f 72 20 74 68 65 20 74 61  names for the ta
09e0: 62 6c 65 20 6e 61 6d 65 64 20 7a 54 61 62 20 76  ble named zTab v
09f0: 69 61 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 63  ia database.** c
0a00: 6f 6e 6e 65 63 74 69 6f 6e 20 64 62 2e 20 53 51  onnection db. SQ
0a10: 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72  LITE_OK is retur
0a20: 6e 65 64 20 6f 6e 20 73 75 63 63 65 73 73 2c 20  ned on success, 
0a30: 6f 72 20 61 6e 20 73 71 6c 69 74 65 20 65 72 72  or an sqlite err
0a40: 6f 72 0a 2a 2a 20 63 6f 64 65 20 6f 74 68 65 72  or.** code other
0a50: 77 69 73 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73  wise..**.** If s
0a60: 75 63 63 65 73 73 66 75 6c 2c 20 74 68 65 20 6e  uccessful, the n
0a70: 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73  umber of columns
0a80: 20 69 73 20 77 72 69 74 74 65 6e 20 74 6f 20 2a   is written to *
0a90: 70 6e 43 6f 6c 2e 20 2a 70 61 43 6f 6c 20 69 73  pnCol. *paCol is
0aa0: 0a 2a 2a 20 73 65 74 20 74 6f 20 70 6f 69 6e 74  .** set to point
0ab0: 20 61 74 20 73 71 6c 69 74 65 4d 61 6c 6c 6f 63   at sqliteMalloc
0ac0: 28 29 27 64 20 73 70 61 63 65 20 63 6f 6e 74 61  ()'d space conta
0ad0: 69 6e 69 6e 67 20 74 68 65 20 61 72 72 61 79 20  ining the array 
0ae0: 6f 66 0a 2a 2a 20 6e 43 6f 6c 20 63 6f 6c 75 6d  of.** nCol colum
0af0: 6e 20 6e 61 6d 65 73 2e 20 54 68 65 20 63 61 6c  n names. The cal
0b00: 6c 65 72 20 69 73 20 72 65 73 70 6f 6e 73 69 62  ler is responsib
0b10: 6c 65 20 66 6f 72 20 63 61 6c 6c 69 6e 67 20 73  le for calling s
0b20: 71 6c 69 74 65 46 72 65 65 0a 2a 2a 20 6f 6e 20  qliteFree.** on 
0b30: 2a 70 61 43 6f 6c 2e 0a 2a 2f 0a 73 74 61 74 69  *paCol..*/.stati
0b40: 63 20 69 6e 74 20 67 65 74 43 6f 6c 75 6d 6e 4e  c int getColumnN
0b50: 61 6d 65 73 28 0a 20 20 73 71 6c 69 74 65 33 20  ames(.  sqlite3 
0b60: 2a 64 62 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68  *db, .  const ch
0b70: 61 72 20 2a 7a 54 61 62 2c 0a 20 20 63 68 61 72  ar *zTab,.  char
0b80: 20 2a 2a 2a 70 61 43 6f 6c 2c 20 0a 20 20 69 6e   ***paCol, .  in
0b90: 74 20 2a 70 6e 43 6f 6c 0a 29 7b 0a 20 20 63 68  t *pnCol.){.  ch
0ba0: 61 72 20 2a 2a 61 43 6f 6c 20 3d 20 30 3b 0a 20  ar **aCol = 0;. 
0bb0: 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 73   char *zSql;.  s
0bc0: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
0bd0: 6d 74 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63  mt = 0;.  int rc
0be0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
0bf0: 69 6e 74 20 6e 43 6f 6c 20 3d 20 30 3b 0a 0a 20  int nCol = 0;.. 
0c00: 20 2f 2a 20 50 72 65 70 61 72 65 20 74 68 65 20   /* Prepare the 
0c10: 73 74 61 74 65 6d 65 6e 74 20 22 53 45 4c 45 43  statement "SELEC
0c20: 54 20 2a 20 46 52 4f 4d 20 3c 74 62 6c 3e 22 2e  T * FROM <tbl>".
0c30: 20 54 68 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65   The column name
0c40: 73 0a 20 20 2a 2a 20 6f 66 20 74 68 65 20 72 65  s.  ** of the re
0c50: 73 75 6c 74 20 73 65 74 20 6f 66 20 74 68 65 20  sult set of the 
0c60: 63 6f 6d 70 69 6c 65 64 20 53 45 4c 45 43 54 20  compiled SELECT 
0c70: 77 69 6c 6c 20 62 65 20 74 68 65 20 73 61 6d 65  will be the same
0c80: 20 61 73 0a 20 20 2a 2a 20 74 68 65 20 63 6f 6c   as.  ** the col
0c90: 75 6d 6e 20 6e 61 6d 65 73 20 6f 66 20 74 61 62  umn names of tab
0ca0: 6c 65 20 3c 74 62 6c 3e 2e 0a 20 20 2a 2f 0a 20  le <tbl>..  */. 
0cb0: 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d   zSql = sqlite3M
0cc0: 50 72 69 6e 74 66 28 22 53 45 4c 45 43 54 20 2a  Printf("SELECT *
0cd0: 20 46 52 4f 4d 20 25 51 22 2c 20 7a 54 61 62 29   FROM %Q", zTab)
0ce0: 3b 0a 20 20 69 66 28 20 21 7a 53 71 6c 20 29 7b  ;.  if( !zSql ){
0cf0: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
0d00: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 67 6f 74 6f  _NOMEM;.    goto
0d10: 20 6f 75 74 3b 0a 20 20 7d 0a 20 20 72 63 20 3d   out;.  }.  rc =
0d20: 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65   sqlite3_prepare
0d30: 28 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26  (db, zSql, -1, &
0d40: 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 73 71 6c  pStmt, 0);.  sql
0d50: 69 74 65 46 72 65 65 28 7a 53 71 6c 29 3b 0a 0a  iteFree(zSql);..
0d60: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
0d70: 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  _OK ){.    int i
0d80: 69 3b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65  i;.    int nByte
0d90: 73 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 70  s;.    char *zSp
0da0: 61 63 65 3b 0a 20 20 20 20 6e 43 6f 6c 20 3d 20  ace;.    nCol = 
0db0: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 63  sqlite3_column_c
0dc0: 6f 75 6e 74 28 70 53 74 6d 74 29 3b 0a 0a 20 20  ount(pStmt);..  
0dd0: 20 20 2f 2a 20 46 69 67 75 72 65 20 6f 75 74 20    /* Figure out 
0de0: 68 6f 77 20 6d 75 63 68 20 73 70 61 63 65 20 74  how much space t
0df0: 6f 20 61 6c 6c 6f 63 61 74 65 20 66 6f 72 20 74  o allocate for t
0e00: 68 65 20 61 72 72 61 79 20 6f 66 20 63 6f 6c 75  he array of colu
0e10: 6d 6e 20 6e 61 6d 65 73 20 0a 20 20 20 20 2a 2a  mn names .    **
0e20: 20 28 69 6e 63 6c 75 64 69 6e 67 20 73 70 61 63   (including spac
0e30: 65 20 66 6f 72 20 74 68 65 20 73 74 72 69 6e 67  e for the string
0e40: 73 20 74 68 65 6d 73 65 6c 76 65 73 29 2e 20 54  s themselves). T
0e50: 68 65 6e 20 61 6c 6c 6f 63 61 74 65 20 69 74 2e  hen allocate it.
0e60: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6e 42 79 74  .    */.    nByt
0e70: 65 73 20 3d 20 73 69 7a 65 6f 66 28 63 68 61 72  es = sizeof(char
0e80: 20 2a 29 20 2a 20 6e 43 6f 6c 3b 0a 20 20 20 20   *) * nCol;.    
0e90: 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c 6e 43 6f  for(ii=0; ii<nCo
0ea0: 6c 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20  l; ii++){.      
0eb0: 6e 42 79 74 65 73 20 2b 3d 20 28 73 74 72 6c 65  nBytes += (strle
0ec0: 6e 28 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  n(sqlite3_column
0ed0: 5f 6e 61 6d 65 28 70 53 74 6d 74 2c 20 69 69 29  _name(pStmt, ii)
0ee0: 29 20 2b 20 31 29 3b 0a 20 20 20 20 7d 0a 20 20  ) + 1);.    }.  
0ef0: 20 20 61 43 6f 6c 20 3d 20 28 63 68 61 72 20 2a    aCol = (char *
0f00: 2a 29 73 71 6c 69 74 65 4d 61 6c 6c 6f 63 28 6e  *)sqliteMalloc(n
0f10: 42 79 74 65 73 29 3b 0a 20 20 20 20 69 66 28 20  Bytes);.    if( 
0f20: 21 61 43 6f 6c 20 29 7b 0a 20 20 20 20 20 20 72  !aCol ){.      r
0f30: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
0f40: 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 6f 75 74  ;.      goto out
0f50: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20  ;.    }..    /* 
0f60: 43 6f 70 79 20 74 68 65 20 63 6f 6c 75 6d 6e 20  Copy the column 
0f70: 6e 61 6d 65 73 20 69 6e 74 6f 20 74 68 65 20 61  names into the a
0f80: 6c 6c 6f 63 61 74 65 64 20 73 70 61 63 65 20 61  llocated space a
0f90: 6e 64 20 73 65 74 20 75 70 20 74 68 65 0a 20 20  nd set up the.  
0fa0: 20 20 2a 2a 20 70 6f 69 6e 74 65 72 73 20 69 6e    ** pointers in
0fb0: 20 74 68 65 20 61 43 6f 6c 5b 5d 20 61 72 72 61   the aCol[] arra
0fc0: 79 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 7a 53  y..    */.    zS
0fd0: 70 61 63 65 20 3d 20 28 63 68 61 72 20 2a 29 28  pace = (char *)(
0fe0: 26 61 43 6f 6c 5b 6e 43 6f 6c 5d 29 3b 0a 20 20  &aCol[nCol]);.  
0ff0: 20 20 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c 6e    for(ii=0; ii<n
1000: 43 6f 6c 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20  Col; ii++){.    
1010: 20 20 61 43 6f 6c 5b 69 69 5d 20 3d 20 7a 53 70    aCol[ii] = zSp
1020: 61 63 65 3b 0a 20 20 20 20 20 20 7a 53 70 61 63  ace;.      zSpac
1030: 65 20 2b 3d 20 73 70 72 69 6e 74 66 28 7a 53 70  e += sprintf(zSp
1040: 61 63 65 2c 20 22 25 73 22 2c 20 73 71 6c 69 74  ace, "%s", sqlit
1050: 65 33 5f 63 6f 6c 75 6d 6e 5f 6e 61 6d 65 28 70  e3_column_name(p
1060: 53 74 6d 74 2c 20 69 69 29 29 3b 0a 20 20 20 20  Stmt, ii));.    
1070: 20 20 7a 53 70 61 63 65 2b 2b 3b 0a 20 20 20 20    zSpace++;.    
1080: 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 28 7a  }.    assert( (z
1090: 53 70 61 63 65 2d 6e 42 79 74 65 73 29 3d 3d 28  Space-nBytes)==(
10a0: 63 68 61 72 20 2a 29 61 43 6f 6c 20 29 3b 0a 20  char *)aCol );. 
10b0: 20 7d 0a 0a 20 20 2a 70 61 43 6f 6c 20 3d 20 61   }..  *paCol = a
10c0: 43 6f 6c 3b 0a 20 20 2a 70 6e 43 6f 6c 20 3d 20  Col;.  *pnCol = 
10d0: 6e 43 6f 6c 3b 0a 0a 6f 75 74 3a 0a 20 20 73 71  nCol;..out:.  sq
10e0: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
10f0: 53 74 6d 74 29 3b 0a 20 20 72 65 74 75 72 6e 20  Stmt);.  return 
1100: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 72  rc;.}../*.** Par
1110: 61 6d 65 74 65 72 20 7a 54 61 62 20 69 73 20 74  ameter zTab is t
1120: 68 65 20 6e 61 6d 65 20 6f 66 20 61 20 74 61 62  he name of a tab
1130: 6c 65 20 69 6e 20 64 61 74 61 62 61 73 65 20 64  le in database d
1140: 62 20 77 69 74 68 20 6e 43 6f 6c 20 0a 2a 2a 20  b with nCol .** 
1150: 63 6f 6c 75 6d 6e 73 2e 20 54 68 69 73 20 66 75  columns. This fu
1160: 6e 63 74 69 6f 6e 20 61 6c 6c 6f 63 61 74 65 73  nction allocates
1170: 20 61 6e 20 61 72 72 61 79 20 6f 66 20 69 6e 74   an array of int
1180: 65 67 65 72 73 20 6e 43 6f 6c 20 69 6e 20 0a 2a  egers nCol in .*
1190: 2a 20 73 69 7a 65 20 61 6e 64 20 70 6f 70 75 6c  * size and popul
11a0: 61 74 65 73 20 69 74 20 61 63 63 6f 72 64 69 6e  ates it accordin
11b0: 67 20 74 6f 20 61 6e 79 20 69 6d 70 6c 69 63 69  g to any implici
11c0: 74 20 6f 72 20 65 78 70 6c 69 63 69 74 20 0a 2a  t or explicit .*
11d0: 2a 20 69 6e 64 69 63 65 73 20 6f 6e 20 74 61 62  * indices on tab
11e0: 6c 65 20 7a 54 61 62 2e 0a 2a 2a 0a 2a 2a 20 49  le zTab..**.** I
11f0: 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 53 51  f successful, SQ
1200: 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72  LITE_OK is retur
1210: 6e 65 64 20 61 6e 64 20 2a 70 61 49 6e 64 65 78  ned and *paIndex
1220: 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 0a 2a   set to point .*
1230: 2a 20 61 74 20 74 68 65 20 61 6c 6c 6f 63 61 74  * at the allocat
1240: 65 64 20 61 72 72 61 79 2e 20 4f 74 68 65 72 77  ed array. Otherw
1250: 69 73 65 2c 20 61 6e 20 65 72 72 6f 72 20 63 6f  ise, an error co
1260: 64 65 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a  de is returned..
1270: 2a 2a 0a 2a 2a 20 53 65 65 20 63 6f 6d 6d 65 6e  **.** See commen
1280: 74 73 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  ts associated wi
1290: 74 68 20 74 68 65 20 6d 65 6d 62 65 72 20 76 61  th the member va
12a0: 72 69 61 62 6c 65 20 61 49 6e 64 65 78 20 61 62  riable aIndex ab
12b0: 6f 76 65 20 0a 2a 2a 20 22 73 74 72 75 63 74 20  ove .** "struct 
12c0: 65 63 68 6f 5f 76 74 61 62 22 20 66 6f 72 20 64  echo_vtab" for d
12d0: 65 74 61 69 6c 73 20 6f 66 20 74 68 65 20 63 6f  etails of the co
12e0: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 61 72  ntents of the ar
12f0: 72 61 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ray..*/.static i
1300: 6e 74 20 67 65 74 49 6e 64 65 78 41 72 72 61 79  nt getIndexArray
1310: 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
1320: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1330: 44 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74  Database connect
1340: 69 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  ion */.  const c
1350: 68 61 72 20 2a 7a 54 61 62 2c 20 20 20 20 20 20  har *zTab,      
1360: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 61 62    /* Name of tab
1370: 6c 65 20 69 6e 20 64 61 74 61 62 61 73 65 20 64  le in database d
1380: 62 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c  b */.  int nCol,
1390: 0a 20 20 69 6e 74 20 2a 2a 70 61 49 6e 64 65 78  .  int **paIndex
13a0: 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74  .){.  sqlite3_st
13b0: 6d 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20  mt *pStmt = 0;. 
13c0: 20 69 6e 74 20 2a 61 49 6e 64 65 78 20 3d 20 30   int *aIndex = 0
13d0: 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 63 68  ;.  int rc;.  ch
13e0: 61 72 20 2a 7a 53 71 6c 3b 0a 0a 20 20 2f 2a 20  ar *zSql;..  /* 
13f0: 41 6c 6c 6f 63 61 74 65 20 73 70 61 63 65 20 66  Allocate space f
1400: 6f 72 20 74 68 65 20 69 6e 64 65 78 20 61 72 72  or the index arr
1410: 61 79 20 2a 2f 0a 20 20 61 49 6e 64 65 78 20 3d  ay */.  aIndex =
1420: 20 28 69 6e 74 20 2a 29 73 71 6c 69 74 65 4d 61   (int *)sqliteMa
1430: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 69 6e 74 29  lloc(sizeof(int)
1440: 20 2a 20 6e 43 6f 6c 29 3b 0a 20 20 69 66 28 20   * nCol);.  if( 
1450: 21 61 49 6e 64 65 78 20 29 7b 0a 20 20 20 20 72  !aIndex ){.    r
1460: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
1470: 3b 0a 20 20 20 20 67 6f 74 6f 20 67 65 74 5f 69  ;.    goto get_i
1480: 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75 74 3b 0a  ndex_array_out;.
1490: 20 20 7d 0a 0a 20 20 2f 2a 20 43 6f 6d 70 69 6c    }..  /* Compil
14a0: 65 20 61 6e 20 73 71 6c 69 74 65 20 70 72 61 67  e an sqlite prag
14b0: 6d 61 20 74 6f 20 6c 6f 6f 70 20 74 68 72 6f 75  ma to loop throu
14c0: 67 68 20 61 6c 6c 20 69 6e 64 69 63 65 73 20 6f  gh all indices o
14d0: 6e 20 74 61 62 6c 65 20 7a 54 61 62 20 2a 2f 0a  n table zTab */.
14e0: 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33    zSql = sqlite3
14f0: 4d 50 72 69 6e 74 66 28 22 50 52 41 47 4d 41 20  MPrintf("PRAGMA 
1500: 69 6e 64 65 78 5f 6c 69 73 74 28 25 73 29 22 2c  index_list(%s)",
1510: 20 7a 54 61 62 29 3b 0a 20 20 69 66 28 20 21 7a   zTab);.  if( !z
1520: 53 71 6c 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  Sql ){.    rc = 
1530: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
1540: 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78    goto get_index
1550: 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20 7d 0a  _array_out;.  }.
1560: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70    rc = sqlite3_p
1570: 72 65 70 61 72 65 28 64 62 2c 20 7a 53 71 6c 2c  repare(db, zSql,
1580: 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b   -1, &pStmt, 0);
1590: 0a 20 20 73 71 6c 69 74 65 46 72 65 65 28 7a 53  .  sqliteFree(zS
15a0: 71 6c 29 3b 0a 0a 20 20 2f 2a 20 46 6f 72 20 65  ql);..  /* For e
15b0: 61 63 68 20 69 6e 64 65 78 2c 20 66 69 67 75 72  ach index, figur
15c0: 65 20 6f 75 74 20 74 68 65 20 6c 65 66 74 2d 6d  e out the left-m
15d0: 6f 73 74 20 63 6f 6c 75 6d 6e 20 61 6e 64 20 73  ost column and s
15e0: 65 74 20 74 68 65 20 0a 20 20 2a 2a 20 63 6f 72  et the .  ** cor
15f0: 72 65 73 70 6f 6e 64 69 6e 67 20 65 6e 74 72 79  responding entry
1600: 20 69 6e 20 61 49 6e 64 65 78 5b 5d 20 74 6f 20   in aIndex[] to 
1610: 31 2e 0a 20 20 2a 2f 0a 20 20 77 68 69 6c 65 28  1..  */.  while(
1620: 20 70 53 74 6d 74 20 26 26 20 73 71 6c 69 74 65   pStmt && sqlite
1630: 33 5f 73 74 65 70 28 70 53 74 6d 74 29 3d 3d 53  3_step(pStmt)==S
1640: 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20  QLITE_ROW ){.   
1650: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 49 64   const char *zId
1660: 78 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  x = sqlite3_colu
1670: 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 20 31  mn_text(pStmt, 1
1680: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73  );.    sqlite3_s
1690: 74 6d 74 20 2a 70 53 74 6d 74 32 20 3d 20 30 3b  tmt *pStmt2 = 0;
16a0: 0a 20 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69  .    zSql = sqli
16b0: 74 65 33 4d 50 72 69 6e 74 66 28 22 50 52 41 47  te3MPrintf("PRAG
16c0: 4d 41 20 69 6e 64 65 78 5f 69 6e 66 6f 28 25 73  MA index_info(%s
16d0: 29 22 2c 20 7a 49 64 78 29 3b 0a 20 20 20 20 69  )", zIdx);.    i
16e0: 66 28 20 21 7a 53 71 6c 20 29 7b 0a 20 20 20 20  f( !zSql ){.    
16f0: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
1700: 4d 45 4d 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20  MEM;.      goto 
1710: 67 65 74 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f  get_index_array_
1720: 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72  out;.    }.    r
1730: 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70  c = sqlite3_prep
1740: 61 72 65 28 64 62 2c 20 7a 53 71 6c 2c 20 2d 31  are(db, zSql, -1
1750: 2c 20 26 70 53 74 6d 74 32 2c 20 30 29 3b 0a 20  , &pStmt2, 0);. 
1760: 20 20 20 73 71 6c 69 74 65 46 72 65 65 28 7a 53     sqliteFree(zS
1770: 71 6c 29 3b 0a 20 20 20 20 69 66 28 20 70 53 74  ql);.    if( pSt
1780: 6d 74 32 20 26 26 20 73 71 6c 69 74 65 33 5f 73  mt2 && sqlite3_s
1790: 74 65 70 28 70 53 74 6d 74 32 29 3d 3d 53 51 4c  tep(pStmt2)==SQL
17a0: 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20  ITE_ROW ){.     
17b0: 20 69 6e 74 20 63 69 64 20 3d 20 73 71 6c 69 74   int cid = sqlit
17c0: 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53  e3_column_int(pS
17d0: 74 6d 74 32 2c 20 31 29 3b 0a 20 20 20 20 20 20  tmt2, 1);.      
17e0: 61 73 73 65 72 74 28 20 63 69 64 3e 3d 30 20 26  assert( cid>=0 &
17f0: 26 20 63 69 64 3c 6e 43 6f 6c 20 29 3b 0a 20 20  & cid<nCol );.  
1800: 20 20 20 20 61 49 6e 64 65 78 5b 63 69 64 5d 20      aIndex[cid] 
1810: 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  = 1;.    }.    i
1820: 66 28 20 70 53 74 6d 74 32 20 29 7b 0a 20 20 20  f( pStmt2 ){.   
1830: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
1840: 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 32 29  finalize(pStmt2)
1850: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
1860: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
1870: 0a 20 20 20 20 20 20 67 6f 74 6f 20 67 65 74 5f  .      goto get_
1880: 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75 74 3b  index_array_out;
1890: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 0a 67 65 74  .    }.  }...get
18a0: 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75 74  _index_array_out
18b0: 3a 0a 20 20 69 66 28 20 70 53 74 6d 74 20 29 7b  :.  if( pStmt ){
18c0: 0a 20 20 20 20 69 6e 74 20 72 63 32 20 3d 20 73  .    int rc2 = s
18d0: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
18e0: 70 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20  pStmt);.    if( 
18f0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
1900: 0a 20 20 20 20 20 20 72 63 20 3d 20 72 63 32 3b  .      rc = rc2;
1910: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28  .    }.  }.  if(
1920: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
1930: 7b 0a 20 20 20 20 73 71 6c 69 74 65 46 72 65 65  {.    sqliteFree
1940: 28 61 49 6e 64 65 78 29 3b 0a 20 20 20 20 61 49  (aIndex);.    aI
1950: 6e 64 65 78 20 3d 20 30 3b 0a 20 20 7d 0a 20 20  ndex = 0;.  }.  
1960: 2a 70 61 49 6e 64 65 78 20 3d 20 61 49 6e 64 65  *paIndex = aInde
1970: 78 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  x;.  return rc;.
1980: 7d 0a 0a 2f 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20  }../*.** Global 
1990: 54 63 6c 20 76 61 72 69 61 62 6c 65 20 24 65 63  Tcl variable $ec
19a0: 68 6f 5f 6d 6f 64 75 6c 65 20 69 73 20 61 20 6c  ho_module is a l
19b0: 69 73 74 2e 20 54 68 69 73 20 72 6f 75 74 69 6e  ist. This routin
19c0: 65 20 61 70 70 65 6e 64 73 0a 2a 2a 20 74 68 65  e appends.** the
19d0: 20 73 74 72 69 6e 67 20 65 6c 65 6d 65 6e 74 20   string element 
19e0: 7a 41 72 67 20 74 6f 20 74 68 61 74 20 6c 69 73  zArg to that lis
19f0: 74 20 69 6e 20 69 6e 74 65 72 70 72 65 74 65 72  t in interpreter
1a00: 20 69 6e 74 65 72 70 2e 0a 2a 2f 0a 73 74 61 74   interp..*/.stat
1a10: 69 63 20 76 6f 69 64 20 61 70 70 65 6e 64 54 6f  ic void appendTo
1a20: 45 63 68 6f 4d 6f 64 75 6c 65 28 54 63 6c 5f 49  EchoModule(Tcl_I
1a30: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 63  nterp *interp, c
1a40: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 72 67 29  onst char *zArg)
1a50: 7b 0a 20 20 69 6e 74 20 66 6c 61 67 73 20 3d 20  {.  int flags = 
1a60: 28 54 43 4c 5f 41 50 50 45 4e 44 5f 56 41 4c 55  (TCL_APPEND_VALU
1a70: 45 20 7c 20 54 43 4c 5f 4c 49 53 54 5f 45 4c 45  E | TCL_LIST_ELE
1a80: 4d 45 4e 54 20 7c 20 54 43 4c 5f 47 4c 4f 42 41  MENT | TCL_GLOBA
1a90: 4c 5f 4f 4e 4c 59 29 3b 0a 20 20 54 63 6c 5f 53  L_ONLY);.  Tcl_S
1aa0: 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65  etVar(interp, "e
1ab0: 63 68 6f 5f 6d 6f 64 75 6c 65 22 2c 20 28 7a 41  cho_module", (zA
1ac0: 72 67 3f 7a 41 72 67 3a 22 22 29 2c 20 66 6c 61  rg?zArg:""), fla
1ad0: 67 73 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  gs);.}../*.** Th
1ae0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
1af0: 61 6c 6c 65 64 20 66 72 6f 6d 20 77 69 74 68 69  alled from withi
1b00: 6e 20 74 68 65 20 65 63 68 6f 2d 6d 6f 64 75 6c  n the echo-modul
1b10: 65 73 20 78 43 72 65 61 74 65 20 61 6e 64 0a 2a  es xCreate and.*
1b20: 2a 20 78 43 6f 6e 6e 65 63 74 20 6d 65 74 68 6f  * xConnect metho
1b30: 64 73 2e 20 54 68 65 20 61 72 67 63 20 61 6e 64  ds. The argc and
1b40: 20 61 72 67 76 20 61 72 67 75 6d 65 6e 74 73 20   argv arguments 
1b50: 61 72 65 20 63 6f 70 69 65 73 20 6f 66 20 74 68  are copies of th
1b60: 6f 73 65 20 0a 2a 2a 20 70 61 73 73 65 64 20 74  ose .** passed t
1b70: 6f 20 74 68 65 20 63 61 6c 6c 69 6e 67 20 6d 65  o the calling me
1b80: 74 68 6f 64 2e 20 54 68 69 73 20 66 75 6e 63 74  thod. This funct
1b90: 69 6f 6e 20 69 73 20 72 65 73 70 6f 6e 73 69 62  ion is responsib
1ba0: 6c 65 20 66 6f 72 0a 2a 2a 20 63 61 6c 6c 69 6e  le for.** callin
1bb0: 67 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72  g sqlite3_declar
1bc0: 65 5f 76 74 61 62 28 29 20 74 6f 20 64 65 63 6c  e_vtab() to decl
1bd0: 61 72 65 20 74 68 65 20 73 63 68 65 6d 61 20 6f  are the schema o
1be0: 66 20 74 68 65 20 76 69 72 74 75 61 6c 0a 2a 2a  f the virtual.**
1bf0: 20 74 61 62 6c 65 20 62 65 69 6e 67 20 63 72 65   table being cre
1c00: 61 74 65 64 20 6f 72 20 63 6f 6e 6e 65 63 74 65  ated or connecte
1c10: 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20  d..**.** If the 
1c20: 63 6f 6e 73 74 72 75 63 74 6f 72 20 77 61 73 20  constructor was 
1c30: 70 61 73 73 65 64 20 6a 75 73 74 20 6f 6e 65 20  passed just one 
1c40: 61 72 67 75 6d 65 6e 74 2c 20 69 2e 65 2e 3a 0a  argument, i.e.:.
1c50: 2a 2a 0a 2a 2a 20 20 20 43 52 45 41 54 45 20 54  **.**   CREATE T
1c60: 41 42 4c 45 20 74 31 20 41 53 20 65 63 68 6f 28  ABLE t1 AS echo(
1c70: 74 32 29 3b 0a 2a 2a 0a 2a 2a 20 54 68 65 6e 20  t2);.**.** Then 
1c80: 74 32 20 69 73 20 61 73 73 75 6d 65 64 20 74 6f  t2 is assumed to
1c90: 20 62 65 20 74 68 65 20 6e 61 6d 65 20 6f 66 20   be the name of 
1ca0: 61 20 2a 72 65 61 6c 2a 20 64 61 74 61 62 61 73  a *real* databas
1cb0: 65 20 74 61 62 6c 65 2e 20 54 68 65 0a 2a 2a 20  e table. The.** 
1cc0: 73 63 68 65 6d 61 20 6f 66 20 74 68 65 20 76 69  schema of the vi
1cd0: 72 74 75 61 6c 20 74 61 62 6c 65 20 69 73 20 64  rtual table is d
1ce0: 65 63 6c 61 72 65 64 20 62 79 20 70 61 73 73 69  eclared by passi
1cf0: 6e 67 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65  ng a copy of the
1d00: 20 0a 2a 2a 20 43 52 45 41 54 45 20 54 41 42 4c   .** CREATE TABL
1d10: 45 20 73 74 61 74 65 6d 65 6e 74 20 66 6f 72 20  E statement for 
1d20: 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20 74  the real table t
1d30: 6f 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72  o sqlite3_declar
1d40: 65 5f 76 74 61 62 28 29 2e 0a 2a 2a 20 48 65 6e  e_vtab()..** Hen
1d50: 63 65 2c 20 74 68 65 20 76 69 72 74 75 61 6c 20  ce, the virtual 
1d60: 74 61 62 6c 65 20 73 68 6f 75 6c 64 20 68 61 76  table should hav
1d70: 65 20 65 78 61 63 74 6c 79 20 74 68 65 20 73 61  e exactly the sa
1d80: 6d 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20  me column names 
1d90: 61 6e 64 20 0a 2a 2a 20 74 79 70 65 73 20 61 73  and .** types as
1da0: 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 2e   the real table.
1db0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65  .*/.static int e
1dc0: 63 68 6f 44 65 63 6c 61 72 65 56 74 61 62 28 0a  choDeclareVtab(.
1dd0: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
1de0: 61 62 2c 20 0a 20 20 73 71 6c 69 74 65 33 20 2a  ab, .  sqlite3 *
1df0: 64 62 2c 20 0a 20 20 69 6e 74 20 61 72 67 63 2c  db, .  int argc,
1e00: 20 0a 20 20 63 68 61 72 20 2a 2a 61 72 67 76 0a   .  char **argv.
1e10: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
1e20: 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20  LITE_OK;..  if( 
1e30: 61 72 67 63 3e 3d 34 20 29 7b 0a 20 20 20 20 73  argc>=4 ){.    s
1e40: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
1e50: 6d 74 20 3d 20 30 3b 0a 20 20 20 20 73 71 6c 69  mt = 0;.    sqli
1e60: 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c 20  te3_prepare(db, 
1e70: 0a 20 20 20 20 20 20 20 20 22 53 45 4c 45 43 54  .        "SELECT
1e80: 20 73 71 6c 20 46 52 4f 4d 20 73 71 6c 69 74 65   sql FROM sqlite
1e90: 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79  _master WHERE ty
1ea0: 70 65 20 3d 20 27 74 61 62 6c 65 27 20 41 4e 44  pe = 'table' AND
1eb0: 20 6e 61 6d 65 20 3d 20 3f 22 2c 0a 20 20 20 20   name = ?",.    
1ec0: 20 20 20 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20      -1, &pStmt, 
1ed0: 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  0);.    sqlite3_
1ee0: 62 69 6e 64 5f 74 65 78 74 28 70 53 74 6d 74 2c  bind_text(pStmt,
1ef0: 20 31 2c 20 61 72 67 76 5b 33 5d 2c 20 2d 31 2c   1, argv[3], -1,
1f00: 20 30 29 3b 0a 20 20 20 20 69 66 28 20 73 71 6c   0);.    if( sql
1f10: 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29  ite3_step(pStmt)
1f20: 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a  ==SQLITE_ROW ){.
1f30: 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
1f40: 20 2a 7a 43 72 65 61 74 65 54 61 62 6c 65 20 3d   *zCreateTable =
1f50: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
1f60: 74 65 78 74 28 70 53 74 6d 74 2c 20 30 29 3b 0a  text(pStmt, 0);.
1f70: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 64 65        sqlite3_de
1f80: 63 6c 61 72 65 5f 76 74 61 62 28 64 62 2c 20 7a  clare_vtab(db, z
1f90: 43 72 65 61 74 65 54 61 62 6c 65 29 3b 0a 20 20  CreateTable);.  
1fa0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
1fb0: 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29  _finalize(pStmt)
1fc0: 3b 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20  ;.    } else {. 
1fd0: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
1fe0: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74  3_finalize(pStmt
1ff0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  );.      if( rc=
2000: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 20 0a 20  =SQLITE_OK ){ . 
2010: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
2020: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  TE_ERROR;.      
2030: 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  }.    }..    if(
2040: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
2050: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 67 65 74  {.      rc = get
2060: 43 6f 6c 75 6d 6e 4e 61 6d 65 73 28 64 62 2c 20  ColumnNames(db, 
2070: 61 72 67 76 5b 33 5d 2c 20 26 70 56 74 61 62 2d  argv[3], &pVtab-
2080: 3e 61 43 6f 6c 2c 20 26 70 56 74 61 62 2d 3e 6e  >aCol, &pVtab->n
2090: 43 6f 6c 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  Col);.    }.    
20a0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
20b0: 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  K ){.      rc = 
20c0: 67 65 74 49 6e 64 65 78 41 72 72 61 79 28 64 62  getIndexArray(db
20d0: 2c 20 61 72 67 76 5b 33 5d 2c 20 70 56 74 61 62  , argv[3], pVtab
20e0: 2d 3e 6e 43 6f 6c 2c 20 26 70 56 74 61 62 2d 3e  ->nCol, &pVtab->
20f0: 61 49 6e 64 65 78 29 3b 0a 20 20 20 20 7d 0a 20  aIndex);.    }. 
2100: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
2110: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
2120: 75 6e 63 74 69 6f 6e 20 66 72 65 65 73 20 61 6c  unction frees al
2130: 6c 20 72 75 6e 74 69 6d 65 20 73 74 72 75 63 74  l runtime struct
2140: 75 72 65 73 20 61 73 73 6f 63 69 61 74 65 64 20  ures associated 
2150: 77 69 74 68 20 74 68 65 20 76 69 72 74 75 61 6c  with the virtual
2160: 0a 2a 2a 20 74 61 62 6c 65 20 70 56 74 61 62 2e  .** table pVtab.
2170: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65  .*/.static int e
2180: 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 73 71  choDestructor(sq
2190: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
21a0: 62 29 7b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20  b){.  echo_vtab 
21b0: 2a 70 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 2a  *p = (echo_vtab*
21c0: 29 70 56 74 61 62 3b 0a 20 20 73 71 6c 69 74 65  )pVtab;.  sqlite
21d0: 46 72 65 65 28 70 2d 3e 61 49 6e 64 65 78 29 3b  Free(p->aIndex);
21e0: 0a 20 20 73 71 6c 69 74 65 46 72 65 65 28 70 2d  .  sqliteFree(p-
21f0: 3e 61 43 6f 6c 29 3b 0a 20 20 73 71 6c 69 74 65  >aCol);.  sqlite
2200: 46 72 65 65 28 70 2d 3e 7a 54 61 62 6c 65 4e 61  Free(p->zTableNa
2210: 6d 65 29 3b 0a 20 20 73 71 6c 69 74 65 46 72 65  me);.  sqliteFre
2220: 65 28 70 2d 3e 7a 4c 6f 67 4e 61 6d 65 29 3b 0a  e(p->zLogName);.
2230: 20 20 73 71 6c 69 74 65 46 72 65 65 28 70 29 3b    sqliteFree(p);
2240: 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a  .  return 0;.}..
2250: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
2260: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f  ion is called to
2270: 20 64 6f 20 74 68 65 20 77 6f 72 6b 20 6f 66 20   do the work of 
2280: 74 68 65 20 78 43 6f 6e 6e 65 63 74 28 29 20 6d  the xConnect() m
2290: 65 74 68 6f 64 20 2d 0a 2a 2a 20 74 6f 20 61 6c  ethod -.** to al
22a0: 6c 6f 63 61 74 65 20 74 68 65 20 72 65 71 75 69  locate the requi
22b0: 72 65 64 20 69 6e 2d 6d 65 6d 6f 72 79 20 73 74  red in-memory st
22c0: 72 75 63 74 75 72 65 73 20 66 6f 72 20 61 20 6e  ructures for a n
22d0: 65 77 6c 79 20 63 6f 6e 6e 65 63 74 65 64 0a 2a  ewly connected.*
22e0: 2a 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e  * virtual table.
22f0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65  .*/.static int e
2300: 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28 0a  choConstructor(.
2310: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20    sqlite3 *db,. 
2320: 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69   void *pAux,.  i
2330: 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a  nt argc, char **
2340: 61 72 67 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f  argv,.  sqlite3_
2350: 76 74 61 62 20 2a 2a 70 70 56 74 61 62 0a 29 7b  vtab **ppVtab.){
2360: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 65 63 68 6f  .  int i;.  echo
2370: 5f 76 74 61 62 20 2a 70 56 74 61 62 3b 0a 0a 20  _vtab *pVtab;.. 
2380: 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74 68 65   /* Allocate the
2390: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 2f 65 63   sqlite3_vtab/ec
23a0: 68 6f 5f 76 74 61 62 20 73 74 72 75 63 74 75 72  ho_vtab structur
23b0: 65 20 69 74 73 65 6c 66 20 2a 2f 0a 20 20 70 56  e itself */.  pV
23c0: 74 61 62 20 3d 20 73 71 6c 69 74 65 4d 61 6c 6c  tab = sqliteMall
23d0: 6f 63 28 20 73 69 7a 65 6f 66 28 2a 70 56 74 61  oc( sizeof(*pVta
23e0: 62 29 20 29 3b 0a 20 20 69 66 28 20 21 70 56 74  b) );.  if( !pVt
23f0: 61 62 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  ab ){.    return
2400: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
2410: 20 7d 0a 20 20 70 56 74 61 62 2d 3e 69 6e 74 65   }.  pVtab->inte
2420: 72 70 20 3d 20 28 54 63 6c 5f 49 6e 74 65 72 70  rp = (Tcl_Interp
2430: 20 2a 29 70 41 75 78 3b 0a 20 20 70 56 74 61 62   *)pAux;.  pVtab
2440: 2d 3e 64 62 20 3d 20 64 62 3b 0a 0a 20 20 2f 2a  ->db = db;..  /*
2450: 20 41 6c 6c 6f 63 61 74 65 20 65 63 68 6f 5f 76   Allocate echo_v
2460: 74 61 62 2e 7a 54 61 62 6c 65 4e 61 6d 65 20 2a  tab.zTableName *
2470: 2f 0a 20 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c  /.  pVtab->zTabl
2480: 65 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 4d  eName = sqlite3M
2490: 50 72 69 6e 74 66 28 22 25 73 22 2c 20 61 72 67  Printf("%s", arg
24a0: 76 5b 33 5d 29 3b 0a 20 20 69 66 28 20 21 70 56  v[3]);.  if( !pV
24b0: 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20  tab->zTableName 
24c0: 29 7b 0a 20 20 20 20 65 63 68 6f 44 65 73 74 72  ){.    echoDestr
24d0: 75 63 74 6f 72 28 28 73 71 6c 69 74 65 33 5f 76  uctor((sqlite3_v
24e0: 74 61 62 20 2a 29 70 56 74 61 62 29 3b 0a 20 20  tab *)pVtab);.  
24f0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
2500: 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  NOMEM;.  }..  /*
2510: 20 4c 6f 67 20 74 68 65 20 61 72 67 75 6d 65 6e   Log the argumen
2520: 74 73 20 74 6f 20 74 68 69 73 20 66 75 6e 63 74  ts to this funct
2530: 69 6f 6e 20 74 6f 20 54 63 6c 20 76 61 72 20 3a  ion to Tcl var :
2540: 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 2a 2f 0a  :echo_module */.
2550: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 61 72 67    for(i=0; i<arg
2560: 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 61 70 70  c; i++){.    app
2570: 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28  endToEchoModule(
2580: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 61  pVtab->interp, a
2590: 72 67 76 5b 69 5d 29 3b 0a 20 20 7d 0a 0a 20 20  rgv[i]);.  }..  
25a0: 2f 2a 20 49 6e 76 6f 6b 65 20 73 71 6c 69 74 65  /* Invoke sqlite
25b0: 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 20 61  3_declare_vtab a
25c0: 6e 64 20 73 65 74 20 75 70 20 6f 74 68 65 72 20  nd set up other 
25d0: 6d 65 6d 62 65 72 73 20 6f 66 20 74 68 65 20 65  members of the e
25e0: 63 68 6f 5f 76 74 61 62 0a 20 20 2a 2a 20 73 74  cho_vtab.  ** st
25f0: 72 75 63 74 75 72 65 2e 20 49 66 20 61 6e 20 65  ructure. If an e
2600: 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 64 65 6c  rror occurs, del
2610: 65 74 65 20 74 68 65 20 73 71 6c 69 74 65 33 5f  ete the sqlite3_
2620: 76 74 61 62 20 73 74 72 75 63 74 75 72 65 20 61  vtab structure a
2630: 6e 64 0a 20 20 2a 2a 20 72 65 74 75 72 6e 20 61  nd.  ** return a
2640: 6e 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 20 20  n error code..  
2650: 2a 2f 0a 20 20 69 66 28 20 65 63 68 6f 44 65 63  */.  if( echoDec
2660: 6c 61 72 65 56 74 61 62 28 70 56 74 61 62 2c 20  lareVtab(pVtab, 
2670: 64 62 2c 20 61 72 67 63 2c 20 61 72 67 76 29 20  db, argc, argv) 
2680: 29 7b 0a 20 20 20 20 65 63 68 6f 44 65 73 74 72  ){.    echoDestr
2690: 75 63 74 6f 72 28 28 73 71 6c 69 74 65 33 5f 76  uctor((sqlite3_v
26a0: 74 61 62 20 2a 29 70 56 74 61 62 29 3b 0a 20 20  tab *)pVtab);.  
26b0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
26c0: 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  ERROR;.  }..  /*
26d0: 20 53 75 63 63 65 73 73 2e 20 53 65 74 20 2a 70   Success. Set *p
26e0: 70 56 74 61 62 20 61 6e 64 20 72 65 74 75 72 6e  pVtab and return
26f0: 20 2a 2f 0a 20 20 2a 70 70 56 74 61 62 20 3d 20   */.  *ppVtab = 
2700: 26 70 56 74 61 62 2d 3e 62 61 73 65 3b 0a 20 20  &pVtab->base;.  
2710: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
2720: 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f  ;.}../* .** Echo
2730: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d   virtual table m
2740: 6f 64 75 6c 65 20 78 43 72 65 61 74 65 20 6d 65  odule xCreate me
2750: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
2760: 69 6e 74 20 65 63 68 6f 43 72 65 61 74 65 28 0a  int echoCreate(.
2770: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20    sqlite3 *db,. 
2780: 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69   void *pAux,.  i
2790: 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a  nt argc, char **
27a0: 61 72 67 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f  argv,.  sqlite3_
27b0: 76 74 61 62 20 2a 2a 70 70 56 74 61 62 0a 29 7b  vtab **ppVtab.){
27c0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
27d0: 54 45 5f 4f 4b 3b 0a 20 20 61 70 70 65 6e 64 54  TE_OK;.  appendT
27e0: 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28 54 63 6c  oEchoModule((Tcl
27f0: 5f 49 6e 74 65 72 70 20 2a 29 28 70 41 75 78 29  _Interp *)(pAux)
2800: 2c 20 22 78 43 72 65 61 74 65 22 29 3b 0a 20 20  , "xCreate");.  
2810: 72 63 20 3d 20 65 63 68 6f 43 6f 6e 73 74 72 75  rc = echoConstru
2820: 63 74 6f 72 28 64 62 2c 20 70 41 75 78 2c 20 61  ctor(db, pAux, a
2830: 72 67 63 2c 20 61 72 67 76 2c 20 70 70 56 74 61  rgc, argv, ppVta
2840: 62 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65  b);..  /* If the
2850: 72 65 20 77 65 72 65 20 74 77 6f 20 61 72 67 75  re were two argu
2860: 6d 65 6e 74 73 20 70 61 73 73 65 64 20 74 6f 20  ments passed to 
2870: 74 68 65 20 6d 6f 64 75 6c 65 20 61 74 20 74 68  the module at th
2880: 65 20 53 51 4c 20 6c 65 76 65 6c 20 0a 20 20 2a  e SQL level .  *
2890: 2a 20 28 69 2e 65 2e 20 22 43 52 45 41 54 45 20  * (i.e. "CREATE 
28a0: 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20 74 62  VIRTUAL TABLE tb
28b0: 6c 20 55 53 49 4e 47 20 65 63 68 6f 28 61 72 67  l USING echo(arg
28c0: 31 2c 20 61 72 67 32 29 22 29 2c 20 74 68 65 6e  1, arg2)"), then
28d0: 20 0a 20 20 2a 2a 20 74 68 65 20 73 65 63 6f 6e   .  ** the secon
28e0: 64 20 61 72 67 75 6d 65 6e 74 20 69 73 20 75 73  d argument is us
28f0: 65 64 20 61 73 20 61 20 74 61 62 6c 65 20 6e 61  ed as a table na
2900: 6d 65 2e 20 41 74 74 65 6d 70 74 20 74 6f 20 63  me. Attempt to c
2910: 72 65 61 74 65 0a 20 20 2a 2a 20 73 75 63 68 20  reate.  ** such 
2920: 61 20 74 61 62 6c 65 20 77 69 74 68 20 61 20 73  a table with a s
2930: 69 6e 67 6c 65 20 63 6f 6c 75 6d 6e 2c 20 22 6c  ingle column, "l
2940: 6f 67 6d 73 67 22 2e 20 54 68 69 73 20 74 61 62  ogmsg". This tab
2950: 6c 65 20 77 69 6c 6c 0a 20 20 2a 2a 20 62 65 20  le will.  ** be 
2960: 75 73 65 64 20 74 6f 20 6c 6f 67 20 63 61 6c 6c  used to log call
2970: 73 20 74 6f 20 74 68 65 20 78 55 70 64 61 74 65  s to the xUpdate
2980: 20 6d 65 74 68 6f 64 2e 20 49 74 20 77 69 6c 6c   method. It will
2990: 20 62 65 20 64 65 6c 65 74 65 64 0a 20 20 2a 2a   be deleted.  **
29a0: 20 77 68 65 6e 20 74 68 65 20 76 69 72 74 75 61   when the virtua
29b0: 6c 20 74 61 62 6c 65 20 69 73 20 44 52 4f 50 65  l table is DROPe
29c0: 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 4e 6f 74  d..  **.  ** Not
29d0: 65 3a 20 54 68 65 20 6d 61 69 6e 20 70 6f 69 6e  e: The main poin
29e0: 74 20 6f 66 20 74 68 69 73 20 69 73 20 74 6f 20  t of this is to 
29f0: 74 65 73 74 20 74 68 61 74 20 77 65 20 63 61 6e  test that we can
2a00: 20 64 72 6f 70 20 74 61 62 6c 65 73 0a 20 20 2a   drop tables.  *
2a10: 2a 20 66 72 6f 6d 20 77 69 74 68 69 6e 20 61 6e  * from within an
2a20: 20 78 44 65 73 74 72 6f 79 20 6d 65 74 68 6f 64   xDestroy method
2a30: 20 63 61 6c 6c 2e 0a 20 20 2a 2f 0a 20 20 69 66   call..  */.  if
2a40: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
2a50: 26 26 20 61 72 67 63 3d 3d 35 20 29 7b 0a 20 20  && argc==5 ){.  
2a60: 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20    char *zSql;.  
2a70: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
2a80: 61 62 20 3d 20 2a 28 65 63 68 6f 5f 76 74 61 62  ab = *(echo_vtab
2a90: 20 2a 2a 29 70 70 56 74 61 62 3b 0a 20 20 20 20   **)ppVtab;.    
2aa0: 70 56 74 61 62 2d 3e 7a 4c 6f 67 4e 61 6d 65 20  pVtab->zLogName 
2ab0: 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66  = sqlite3MPrintf
2ac0: 28 22 25 73 22 2c 20 61 72 67 76 5b 34 5d 29 3b  ("%s", argv[4]);
2ad0: 0a 20 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69  .    zSql = sqli
2ae0: 74 65 33 4d 50 72 69 6e 74 66 28 22 43 52 45 41  te3MPrintf("CREA
2af0: 54 45 20 54 41 42 4c 45 20 25 51 28 6c 6f 67 6d  TE TABLE %Q(logm
2b00: 73 67 29 22 2c 20 70 56 74 61 62 2d 3e 7a 4c 6f  sg)", pVtab->zLo
2b10: 67 4e 61 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d  gName);.    rc =
2b20: 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 64 62   sqlite3_exec(db
2b30: 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29  , zSql, 0, 0, 0)
2b40: 3b 0a 20 20 20 20 73 71 6c 69 74 65 46 72 65 65  ;.    sqliteFree
2b50: 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20 20 72  (zSql);.  }..  r
2b60: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
2b70: 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c  .** Echo virtual
2b80: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43   table module xC
2b90: 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64 2e 0a 2a  onnect method..*
2ba0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  /.static int ech
2bb0: 6f 43 6f 6e 6e 65 63 74 28 0a 20 20 73 71 6c 69  oConnect(.  sqli
2bc0: 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20  te3 *db,.  void 
2bd0: 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 72 67  *pAux,.  int arg
2be0: 63 2c 20 63 68 61 72 20 2a 2a 61 72 67 76 2c 0a  c, char **argv,.
2bf0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
2c00: 2a 70 70 56 74 61 62 0a 29 7b 0a 20 20 61 70 70  *ppVtab.){.  app
2c10: 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28  endToEchoModule(
2c20: 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 29 28 70  (Tcl_Interp *)(p
2c30: 41 75 78 29 2c 20 22 78 43 6f 6e 6e 65 63 74 22  Aux), "xConnect"
2c40: 29 3b 0a 20 20 72 65 74 75 72 6e 20 65 63 68 6f  );.  return echo
2c50: 43 6f 6e 73 74 72 75 63 74 6f 72 28 64 62 2c 20  Constructor(db, 
2c60: 70 41 75 78 2c 20 61 72 67 63 2c 20 61 72 67 76  pAux, argc, argv
2c70: 2c 20 70 70 56 74 61 62 29 3b 0a 7d 0a 0a 2f 2a  , ppVtab);.}../*
2c80: 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61   .** Echo virtua
2c90: 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78  l table module x
2ca0: 44 69 73 63 6f 6e 6e 65 63 74 20 6d 65 74 68 6f  Disconnect metho
2cb0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
2cc0: 20 65 63 68 6f 44 69 73 63 6f 6e 6e 65 63 74 28   echoDisconnect(
2cd0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
2ce0: 74 61 62 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f  tab){.  appendTo
2cf0: 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68  EchoModule(((ech
2d00: 6f 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29 2d  o_vtab *)pVtab)-
2d10: 3e 69 6e 74 65 72 70 2c 20 22 78 44 69 73 63 6f  >interp, "xDisco
2d20: 6e 6e 65 63 74 22 29 3b 0a 20 20 72 65 74 75 72  nnect");.  retur
2d30: 6e 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72  n echoDestructor
2d40: 28 70 56 74 61 62 29 3b 0a 7d 0a 0a 2f 2a 20 0a  (pVtab);.}../* .
2d50: 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20  ** Echo virtual 
2d60: 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 44 65  table module xDe
2d70: 73 74 72 6f 79 20 6d 65 74 68 6f 64 2e 0a 2a 2f  stroy method..*/
2d80: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
2d90: 44 65 73 74 72 6f 79 28 73 71 6c 69 74 65 33 5f  Destroy(sqlite3_
2da0: 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20  vtab *pVtab){.  
2db0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
2dc0: 4f 4b 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20  OK;.  echo_vtab 
2dd0: 2a 70 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20  *p = (echo_vtab 
2de0: 2a 29 70 56 74 61 62 3b 0a 20 20 61 70 70 65 6e  *)pVtab;.  appen
2df0: 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28  dToEchoModule(((
2e00: 65 63 68 6f 5f 76 74 61 62 20 2a 29 70 56 74 61  echo_vtab *)pVta
2e10: 62 29 2d 3e 69 6e 74 65 72 70 2c 20 22 78 44 65  b)->interp, "xDe
2e20: 73 74 72 6f 79 22 29 3b 0a 0a 20 20 2f 2a 20 44  stroy");..  /* D
2e30: 72 6f 70 20 74 68 65 20 22 6c 6f 67 22 20 74 61  rop the "log" ta
2e40: 62 6c 65 2c 20 69 66 20 6f 6e 65 20 65 78 69 73  ble, if one exis
2e50: 74 73 20 28 73 65 65 20 65 63 68 6f 43 72 65 61  ts (see echoCrea
2e60: 74 65 28 29 20 66 6f 72 20 64 65 74 61 69 6c 73  te() for details
2e70: 29 20 2a 2f 0a 20 20 69 66 28 20 70 20 26 26 20  ) */.  if( p && 
2e80: 70 2d 3e 7a 4c 6f 67 4e 61 6d 65 20 29 7b 0a 20  p->zLogName ){. 
2e90: 20 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20     char *zSql;. 
2ea0: 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65     zSql = sqlite
2eb0: 33 4d 50 72 69 6e 74 66 28 22 44 52 4f 50 20 54  3MPrintf("DROP T
2ec0: 41 42 4c 45 20 25 51 22 2c 20 70 2d 3e 7a 4c 6f  ABLE %Q", p->zLo
2ed0: 67 4e 61 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d  gName);.    rc =
2ee0: 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 70 2d   sqlite3_exec(p-
2ef0: 3e 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c  >db, zSql, 0, 0,
2f00: 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 46   0);.    sqliteF
2f10: 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a  ree(zSql);.  }..
2f20: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2f30: 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
2f40: 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 70  echoDestructor(p
2f50: 56 74 61 62 29 3b 0a 20 20 7d 0a 20 20 72 65 74  Vtab);.  }.  ret
2f60: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  urn rc;.}../* .*
2f70: 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74  * Echo virtual t
2f80: 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 4f 70 65  able module xOpe
2f90: 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61  n method..*/.sta
2fa0: 74 69 63 20 69 6e 74 20 65 63 68 6f 4f 70 65 6e  tic int echoOpen
2fb0: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70  (sqlite3_vtab *p
2fc0: 56 54 61 62 2c 20 73 71 6c 69 74 65 33 5f 76 74  VTab, sqlite3_vt
2fd0: 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70 43 75  ab_cursor **ppCu
2fe0: 72 73 6f 72 29 7b 0a 20 20 65 63 68 6f 5f 63 75  rsor){.  echo_cu
2ff0: 72 73 6f 72 20 2a 70 43 75 72 3b 0a 20 20 70 43  rsor *pCur;.  pC
3000: 75 72 20 3d 20 73 71 6c 69 74 65 4d 61 6c 6c 6f  ur = sqliteMallo
3010: 63 28 73 69 7a 65 6f 66 28 65 63 68 6f 5f 63 75  c(sizeof(echo_cu
3020: 72 73 6f 72 29 29 3b 0a 20 20 2a 70 70 43 75 72  rsor));.  *ppCur
3030: 73 6f 72 20 3d 20 28 73 71 6c 69 74 65 33 5f 76  sor = (sqlite3_v
3040: 74 61 62 5f 63 75 72 73 6f 72 20 2a 29 70 43 75  tab_cursor *)pCu
3050: 72 3b 0a 20 20 72 65 74 75 72 6e 20 28 70 43 75  r;.  return (pCu
3060: 72 20 3f 20 53 51 4c 49 54 45 5f 4f 4b 20 3a 20  r ? SQLITE_OK : 
3070: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 3b 0a 7d  SQLITE_NOMEM);.}
3080: 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69  ../* .** Echo vi
3090: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75  rtual table modu
30a0: 6c 65 20 78 43 6c 6f 73 65 20 6d 65 74 68 6f 64  le xClose method
30b0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
30c0: 65 63 68 6f 43 6c 6f 73 65 28 73 71 6c 69 74 65  echoClose(sqlite
30d0: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63  3_vtab_cursor *c
30e0: 75 72 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  ur){.  int rc;. 
30f0: 20 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 70 43   echo_cursor *pC
3100: 75 72 20 3d 20 28 65 63 68 6f 5f 63 75 72 73 6f  ur = (echo_curso
3110: 72 20 2a 29 63 75 72 3b 0a 20 20 73 71 6c 69 74  r *)cur;.  sqlit
3120: 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d  e3_stmt *pStmt =
3130: 20 70 43 75 72 2d 3e 70 53 74 6d 74 3b 0a 20 20   pCur->pStmt;.  
3140: 70 43 75 72 2d 3e 70 53 74 6d 74 20 3d 20 30 3b  pCur->pStmt = 0;
3150: 0a 20 20 73 71 6c 69 74 65 46 72 65 65 28 70 43  .  sqliteFree(pC
3160: 75 72 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69  ur);.  rc = sqli
3170: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74  te3_finalize(pSt
3180: 6d 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  mt);.  return rc
3190: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
31a0: 6e 20 6e 6f 6e 2d 7a 65 72 6f 20 69 66 20 74 68  n non-zero if th
31b0: 65 20 63 75 72 73 6f 72 20 64 6f 65 73 20 6e 6f  e cursor does no
31c0: 74 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e  t currently poin
31d0: 74 20 74 6f 20 61 20 76 61 6c 69 64 20 72 65 63  t to a valid rec
31e0: 6f 72 64 0a 2a 2a 20 28 69 2e 65 20 69 66 20 74  ord.** (i.e if t
31f0: 68 65 20 73 63 61 6e 20 68 61 73 20 66 69 6e 69  he scan has fini
3200: 73 68 65 64 29 2c 20 6f 72 20 7a 65 72 6f 20 6f  shed), or zero o
3210: 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61  therwise..*/.sta
3220: 74 69 63 20 69 6e 74 20 65 63 68 6f 45 6f 66 28  tic int echoEof(
3230: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
3240: 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 72 65 74  sor *cur){.  ret
3250: 75 72 6e 20 28 28 28 65 63 68 6f 5f 63 75 72 73  urn (((echo_curs
3260: 6f 72 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74  or *)cur)->pStmt
3270: 20 3f 20 30 20 3a 20 31 29 3b 0a 7d 0a 0a 2f 2a   ? 0 : 1);.}../*
3280: 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61   .** Echo virtua
3290: 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78  l table module x
32a0: 4e 65 78 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a  Next method..*/.
32b0: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 4e  static int echoN
32c0: 65 78 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62  ext(sqlite3_vtab
32d0: 5f 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20  _cursor *cur){. 
32e0: 20 69 6e 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f   int rc;.  echo_
32f0: 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28  cursor *pCur = (
3300: 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75  echo_cursor *)cu
3310: 72 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  r;.  rc = sqlite
3320: 33 5f 73 74 65 70 28 70 43 75 72 2d 3e 70 53 74  3_step(pCur->pSt
3330: 6d 74 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d  mt);..  if( rc==
3340: 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20  SQLITE_ROW ){.  
3350: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b    rc = SQLITE_OK
3360: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72  ;.  }else{.    r
3370: 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  c = sqlite3_fina
3380: 6c 69 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d 74  lize(pCur->pStmt
3390: 29 3b 0a 20 20 20 20 70 43 75 72 2d 3e 70 53 74  );.    pCur->pSt
33a0: 6d 74 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 72  mt = 0;.  }..  r
33b0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
33c0: 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c  .** Echo virtual
33d0: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43   table module xC
33e0: 6f 6c 75 6d 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f  olumn method..*/
33f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
3400: 43 6f 6c 75 6d 6e 28 73 71 6c 69 74 65 33 5f 76  Column(sqlite3_v
3410: 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c  tab_cursor *cur,
3420: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
3430: 20 2a 63 74 78 2c 20 69 6e 74 20 69 29 7b 0a 20   *ctx, int i){. 
3440: 20 69 6e 74 20 69 43 6f 6c 20 3d 20 69 20 2b 20   int iCol = i + 
3450: 31 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  1;.  sqlite3_stm
3460: 74 20 2a 70 53 74 6d 74 20 3d 20 28 28 65 63 68  t *pStmt = ((ech
3470: 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d  o_cursor *)cur)-
3480: 3e 70 53 74 6d 74 3b 0a 20 20 69 66 28 20 21 70  >pStmt;.  if( !p
3490: 53 74 6d 74 20 29 7b 0a 20 20 20 20 73 71 6c 69  Stmt ){.    sqli
34a0: 74 65 33 5f 72 65 73 75 6c 74 5f 6e 75 6c 6c 28  te3_result_null(
34b0: 63 74 78 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  ctx);.  }else{. 
34c0: 20 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74     assert( sqlit
34d0: 65 33 5f 64 61 74 61 5f 63 6f 75 6e 74 28 70 53  e3_data_count(pS
34e0: 74 6d 74 29 3e 69 43 6f 6c 20 29 3b 0a 20 20 20  tmt)>iCol );.   
34f0: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
3500: 76 61 6c 75 65 28 63 74 78 2c 20 73 71 6c 69 74  value(ctx, sqlit
3510: 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28  e3_column_value(
3520: 70 53 74 6d 74 2c 20 69 43 6f 6c 29 29 3b 0a 20  pStmt, iCol));. 
3530: 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49   }.  return SQLI
3540: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  TE_OK;.}../* .**
3550: 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   Echo virtual ta
3560: 62 6c 65 20 6d 6f 64 75 6c 65 20 78 52 6f 77 69  ble module xRowi
3570: 64 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61  d method..*/.sta
3580: 74 69 63 20 69 6e 74 20 65 63 68 6f 52 6f 77 69  tic int echoRowi
3590: 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  d(sqlite3_vtab_c
35a0: 75 72 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69  ursor *cur, sqli
35b0: 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69 64  te_int64 *pRowid
35c0: 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  ){.  sqlite3_stm
35d0: 74 20 2a 70 53 74 6d 74 20 3d 20 28 28 65 63 68  t *pStmt = ((ech
35e0: 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d  o_cursor *)cur)-
35f0: 3e 70 53 74 6d 74 3b 0a 20 20 2a 70 52 6f 77 69  >pStmt;.  *pRowi
3600: 64 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  d = sqlite3_colu
3610: 6d 6e 5f 69 6e 74 36 34 28 70 53 74 6d 74 2c 20  mn_int64(pStmt, 
3620: 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  0);.  return SQL
3630: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
3640: 20 43 6f 6d 70 75 74 65 20 61 20 73 69 6d 70 6c   Compute a simpl
3650: 65 20 68 61 73 68 20 6f 66 20 74 68 65 20 6e 75  e hash of the nu
3660: 6c 6c 20 74 65 72 6d 69 6e 61 74 65 64 20 73 74  ll terminated st
3670: 72 69 6e 67 20 7a 53 74 72 69 6e 67 2e 0a 2a 2a  ring zString..**
3680: 0a 2a 2a 20 54 68 69 73 20 6d 6f 64 75 6c 65 20  .** This module 
3690: 75 73 65 73 20 6f 6e 6c 79 20 73 71 6c 69 74 65  uses only sqlite
36a0: 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64 78  3_index_info.idx
36b0: 53 74 72 2c 20 6e 6f 74 20 0a 2a 2a 20 73 71 6c  Str, not .** sql
36c0: 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e  ite3_index_info.
36d0: 69 64 78 4e 75 6d 2e 20 53 6f 20 74 6f 20 74 65  idxNum. So to te
36e0: 73 74 20 69 64 78 4e 75 6d 2c 20 77 68 65 6e 20  st idxNum, when 
36f0: 69 64 78 53 74 72 20 69 73 20 73 65 74 0a 2a 2a  idxStr is set.**
3700: 20 69 6e 20 65 63 68 6f 42 65 73 74 49 6e 64 65   in echoBestInde
3710: 78 28 29 2c 20 69 64 78 4e 75 6d 20 69 73 20 73  x(), idxNum is s
3720: 65 74 20 74 6f 20 74 68 65 20 63 6f 72 72 65 73  et to the corres
3730: 70 6f 6e 64 69 6e 67 20 68 61 73 68 20 76 61 6c  ponding hash val
3740: 75 65 2e 0a 2a 2a 20 49 6e 20 65 63 68 6f 46 69  ue..** In echoFi
3750: 6c 74 65 72 28 29 2c 20 63 6f 64 65 20 61 73 73  lter(), code ass
3760: 65 72 74 28 29 73 20 74 68 61 74 20 74 68 65 20  ert()s that the 
3770: 73 75 70 70 6c 69 65 64 20 69 64 78 4e 75 6d 20  supplied idxNum 
3780: 76 61 6c 75 65 20 69 73 0a 2a 2a 20 69 6e 64 65  value is.** inde
3790: 65 64 20 74 68 65 20 68 61 73 68 20 6f 66 20 74  ed the hash of t
37a0: 68 65 20 73 75 70 70 6c 69 65 64 20 69 64 78 53  he supplied idxS
37b0: 74 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  tr..*/.static in
37c0: 74 20 68 61 73 68 53 74 72 69 6e 67 28 63 6f 6e  t hashString(con
37d0: 73 74 20 63 68 61 72 20 2a 7a 53 74 72 69 6e 67  st char *zString
37e0: 29 7b 0a 20 20 69 6e 74 20 76 61 6c 20 3d 20 30  ){.  int val = 0
37f0: 3b 0a 20 20 69 6e 74 20 69 69 3b 0a 20 20 66 6f  ;.  int ii;.  fo
3800: 72 28 69 69 3d 30 3b 20 7a 53 74 72 69 6e 67 5b  r(ii=0; zString[
3810: 69 69 5d 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20  ii]; ii++){.    
3820: 76 61 6c 20 3d 20 28 76 61 6c 20 3c 3c 20 33 29  val = (val << 3)
3830: 20 2b 20 28 69 6e 74 29 7a 53 74 72 69 6e 67 5b   + (int)zString[
3840: 69 69 5d 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  ii];.  }.  retur
3850: 6e 20 76 61 6c 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  n val;.}../* .**
3860: 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   Echo virtual ta
3870: 62 6c 65 20 6d 6f 64 75 6c 65 20 78 46 69 6c 74  ble module xFilt
3880: 65 72 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74  er method..*/.st
3890: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 46 69 6c  atic int echoFil
38a0: 74 65 72 28 0a 20 20 73 71 6c 69 74 65 33 5f 76  ter(.  sqlite3_v
38b0: 74 61 62 5f 63 75 72 73 6f 72 20 2a 70 56 74 61  tab_cursor *pVta
38c0: 62 43 75 72 73 6f 72 2c 20 0a 20 20 69 6e 74 20  bCursor, .  int 
38d0: 69 64 78 4e 75 6d 2c 20 63 6f 6e 73 74 20 63 68  idxNum, const ch
38e0: 61 72 20 2a 69 64 78 53 74 72 2c 0a 20 20 69 6e  ar *idxStr,.  in
38f0: 74 20 61 72 67 63 2c 20 73 71 6c 69 74 65 33 5f  t argc, sqlite3_
3900: 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a  value **argv.){.
3910: 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20    int rc;.  int 
3920: 69 3b 0a 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f  i;..  echo_curso
3930: 72 20 2a 70 43 75 72 20 3d 20 28 65 63 68 6f 5f  r *pCur = (echo_
3940: 63 75 72 73 6f 72 20 2a 29 70 56 74 61 62 43 75  cursor *)pVtabCu
3950: 72 73 6f 72 3b 0a 20 20 65 63 68 6f 5f 76 74 61  rsor;.  echo_vta
3960: 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f  b *pVtab = (echo
3970: 5f 76 74 61 62 20 2a 29 70 56 74 61 62 43 75 72  _vtab *)pVtabCur
3980: 73 6f 72 2d 3e 70 56 74 61 62 3b 0a 20 20 73 71  sor->pVtab;.  sq
3990: 6c 69 74 65 33 20 2a 64 62 20 3d 20 70 56 74 61  lite3 *db = pVta
39a0: 62 2d 3e 64 62 3b 0a 0a 20 20 2f 2a 20 43 68 65  b->db;..  /* Che
39b0: 63 6b 20 74 68 61 74 20 69 64 78 4e 75 6d 20 6d  ck that idxNum m
39c0: 61 74 63 68 65 73 20 69 64 78 53 74 72 20 2a 2f  atches idxStr */
39d0: 0a 20 20 61 73 73 65 72 74 28 20 69 64 78 4e 75  .  assert( idxNu
39e0: 6d 3d 3d 68 61 73 68 53 74 72 69 6e 67 28 69 64  m==hashString(id
39f0: 78 53 74 72 29 20 29 3b 0a 0a 20 20 2f 2a 20 4c  xStr) );..  /* L
3a00: 6f 67 20 61 72 67 75 6d 65 6e 74 73 20 74 6f 20  og arguments to 
3a10: 74 68 65 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c  the ::echo_modul
3a20: 65 20 54 63 6c 20 76 61 72 69 61 62 6c 65 20 2a  e Tcl variable *
3a30: 2f 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f  /.  appendToEcho
3a40: 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e  Module(pVtab->in
3a50: 74 65 72 70 2c 20 22 78 46 69 6c 74 65 72 22 29  terp, "xFilter")
3a60: 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f  ;.  appendToEcho
3a70: 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e  Module(pVtab->in
3a80: 74 65 72 70 2c 20 69 64 78 53 74 72 29 3b 0a 20  terp, idxStr);. 
3a90: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 61 72 67 63   for(i=0; i<argc
3aa0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 61 70 70 65  ; i++){.    appe
3ab0: 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70  ndToEchoModule(p
3ac0: 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 73 71  Vtab->interp, sq
3ad0: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74  lite3_value_text
3ae0: 28 61 72 67 76 5b 69 5d 29 29 3b 0a 20 20 7d 0a  (argv[i]));.  }.
3af0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c  .  sqlite3_final
3b00: 69 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d 74 29  ize(pCur->pStmt)
3b10: 3b 0a 20 20 70 43 75 72 2d 3e 70 53 74 6d 74 20  ;.  pCur->pStmt 
3b20: 3d 20 30 3b 0a 0a 20 20 2f 2a 20 50 72 65 70 61  = 0;..  /* Prepa
3b30: 72 65 20 74 68 65 20 53 51 4c 20 73 74 61 74 65  re the SQL state
3b40: 6d 65 6e 74 20 63 72 65 61 74 65 64 20 62 79 20  ment created by 
3b50: 65 63 68 6f 42 65 73 74 49 6e 64 65 78 20 61 6e  echoBestIndex an
3b60: 64 20 62 69 6e 64 20 74 68 65 0a 20 20 2a 2a 20  d bind the.  ** 
3b70: 72 75 6e 74 69 6d 65 20 70 61 72 61 6d 65 74 65  runtime paramete
3b80: 72 73 20 70 61 73 73 65 64 20 74 6f 20 74 68 69  rs passed to thi
3b90: 73 20 66 75 6e 63 74 69 6f 6e 20 74 6f 20 69 74  s function to it
3ba0: 2e 0a 20 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71  ..  */.  rc = sq
3bb0: 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62  lite3_prepare(db
3bc0: 2c 20 69 64 78 53 74 72 2c 20 2d 31 2c 20 26 70  , idxStr, -1, &p
3bd0: 43 75 72 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a  Cur->pStmt, 0);.
3be0: 20 20 61 73 73 65 72 74 28 20 70 43 75 72 2d 3e    assert( pCur->
3bf0: 70 53 74 6d 74 20 7c 7c 20 72 63 21 3d 53 51 4c  pStmt || rc!=SQL
3c00: 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 66 6f 72 28  ITE_OK );.  for(
3c10: 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f  i=0; rc==SQLITE_
3c20: 4f 4b 20 26 26 20 69 3c 61 72 67 63 3b 20 69 2b  OK && i<argc; i+
3c30: 2b 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  +){.    sqlite3_
3c40: 62 69 6e 64 5f 76 61 6c 75 65 28 70 43 75 72 2d  bind_value(pCur-
3c50: 3e 70 53 74 6d 74 2c 20 69 2b 31 2c 20 61 72 67  >pStmt, i+1, arg
3c60: 76 5b 69 5d 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  v[i]);.  }..  /*
3c70: 20 49 66 20 65 76 65 72 79 74 68 69 6e 67 20 77   If everything w
3c80: 61 73 20 73 75 63 63 65 73 73 66 75 6c 2c 20 61  as successful, a
3c90: 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20 66 69  dvance to the fi
3ca0: 72 73 74 20 72 6f 77 20 6f 66 20 74 68 65 20 73  rst row of the s
3cb0: 63 61 6e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d  can */.  if( rc=
3cc0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
3cd0: 20 20 72 63 20 3d 20 65 63 68 6f 4e 65 78 74 28    rc = echoNext(
3ce0: 70 56 74 61 62 43 75 72 73 6f 72 29 3b 0a 20 20  pVtabCursor);.  
3cf0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
3d00: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 41 20 68 65 6c 70  }.../*.** A help
3d10: 65 72 20 66 75 6e 63 74 69 6f 6e 20 75 73 65 64  er function used
3d20: 20 62 79 20 65 63 68 6f 55 70 64 61 74 65 28 29   by echoUpdate()
3d30: 20 61 6e 64 20 65 63 68 6f 42 65 73 74 49 6e 64   and echoBestInd
3d40: 65 78 28 29 20 66 6f 72 0a 2a 2a 20 6d 61 6e 69  ex() for.** mani
3d50: 70 75 6c 61 74 69 6e 67 20 73 74 72 69 6e 67 73  pulating strings
3d60: 20 69 6e 20 63 6f 6e 63 65 72 74 20 77 69 74 68   in concert with
3d70: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 6d 70 72   the sqlite3_mpr
3d80: 69 6e 74 66 28 29 20 66 75 6e 63 74 69 6f 6e 2e  intf() function.
3d90: 0a 2a 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 65 72  .**.** Parameter
3da0: 20 70 7a 53 74 72 20 70 6f 69 6e 74 73 20 74 6f   pzStr points to
3db0: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20   a pointer to a 
3dc0: 73 74 72 69 6e 67 20 61 6c 6c 6f 63 61 74 65 64  string allocated
3dd0: 20 77 69 74 68 0a 2a 2a 20 73 71 6c 69 74 65 33   with.** sqlite3
3de0: 5f 6d 70 72 69 6e 74 66 2e 20 54 68 65 20 73 65  _mprintf. The se
3df0: 63 6f 6e 64 20 70 61 72 61 6d 65 74 65 72 2c 20  cond parameter, 
3e00: 7a 41 70 70 65 6e 64 2c 20 70 6f 69 6e 74 73 20  zAppend, points 
3e10: 74 6f 20 61 6e 6f 74 68 65 72 0a 2a 2a 20 73 74  to another.** st
3e20: 72 69 6e 67 2e 20 54 68 65 20 74 77 6f 20 73 74  ring. The two st
3e30: 72 69 6e 67 73 20 61 72 65 20 63 6f 6e 63 61 74  rings are concat
3e40: 65 6e 61 74 65 64 20 74 6f 67 65 74 68 65 72 20  enated together 
3e50: 61 6e 64 20 2a 70 7a 53 74 72 0a 2a 2a 20 73 65  and *pzStr.** se
3e60: 74 20 74 6f 20 70 6f 69 6e 74 20 61 74 20 74 68  t to point at th
3e70: 65 20 72 65 73 75 6c 74 2e 20 54 68 65 20 69 6e  e result. The in
3e80: 69 74 69 61 6c 20 62 75 66 66 65 72 20 70 6f 69  itial buffer poi
3e90: 6e 74 65 64 20 74 6f 20 62 79 20 2a 70 7a 53 74  nted to by *pzSt
3ea0: 72 0a 2a 2a 20 69 73 20 64 65 61 6c 6c 6f 63 61  r.** is dealloca
3eb0: 74 65 64 20 76 69 61 20 73 71 6c 69 74 65 33 5f  ted via sqlite3_
3ec0: 66 72 65 65 28 29 2e 0a 2a 2a 0a 2a 2a 20 49 66  free()..**.** If
3ed0: 20 74 68 65 20 74 68 69 72 64 20 61 72 67 75 6d   the third argum
3ee0: 65 6e 74 2c 20 64 6f 46 72 65 65 2c 20 69 73 20  ent, doFree, is 
3ef0: 74 72 75 65 2c 20 74 68 65 6e 20 73 71 6c 69 74  true, then sqlit
3f00: 65 33 5f 66 72 65 65 28 29 20 69 73 0a 2a 2a 20  e3_free() is.** 
3f10: 61 6c 73 6f 20 63 61 6c 6c 65 64 20 74 6f 20 66  also called to f
3f20: 72 65 65 20 74 68 65 20 62 75 66 66 65 72 20 70  ree the buffer p
3f30: 6f 69 6e 74 65 64 20 74 6f 20 62 79 20 7a 41 70  ointed to by zAp
3f40: 70 65 6e 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  pend..*/.static 
3f50: 76 6f 69 64 20 73 74 72 69 6e 67 5f 63 6f 6e 63  void string_conc
3f60: 61 74 28 63 68 61 72 20 2a 2a 70 7a 53 74 72 2c  at(char **pzStr,
3f70: 20 63 68 61 72 20 2a 7a 41 70 70 65 6e 64 2c 20   char *zAppend, 
3f80: 69 6e 74 20 64 6f 46 72 65 65 29 7b 0a 20 20 63  int doFree){.  c
3f90: 68 61 72 20 2a 7a 49 6e 20 3d 20 2a 70 7a 53 74  har *zIn = *pzSt
3fa0: 72 3b 0a 20 20 69 66 28 20 7a 49 6e 20 29 7b 0a  r;.  if( zIn ){.
3fb0: 20 20 20 20 63 68 61 72 20 2a 7a 54 65 6d 70 20      char *zTemp 
3fc0: 3d 20 7a 49 6e 3b 0a 20 20 20 20 7a 49 6e 20 3d  = zIn;.    zIn =
3fd0: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
3fe0: 28 22 25 73 25 73 22 2c 20 7a 49 6e 2c 20 7a 41  ("%s%s", zIn, zA
3ff0: 70 70 65 6e 64 29 3b 0a 20 20 20 20 73 71 6c 69  ppend);.    sqli
4000: 74 65 33 5f 66 72 65 65 28 7a 54 65 6d 70 29 3b  te3_free(zTemp);
4010: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 7a 49  .  }else{.    zI
4020: 6e 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  n = sqlite3_mpri
4030: 6e 74 66 28 22 25 73 22 2c 20 7a 41 70 70 65 6e  ntf("%s", zAppen
4040: 64 29 3b 0a 20 20 7d 0a 20 20 2a 70 7a 53 74 72  d);.  }.  *pzStr
4050: 20 3d 20 7a 49 6e 3b 0a 20 20 69 66 28 20 64 6f   = zIn;.  if( do
4060: 46 72 65 65 20 29 7b 0a 20 20 20 20 73 71 6c 69  Free ){.    sqli
4070: 74 65 33 5f 66 72 65 65 28 7a 41 70 70 65 6e 64  te3_free(zAppend
4080: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  );.  }.}../*.** 
4090: 54 68 65 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20  The echo module 
40a0: 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68 65 20 73  implements the s
40b0: 75 62 73 65 74 20 6f 66 20 71 75 65 72 79 20 63  ubset of query c
40c0: 6f 6e 73 74 72 61 69 6e 74 73 20 61 6e 64 20 73  onstraints and s
40d0: 6f 72 74 0a 2a 2a 20 6f 72 64 65 72 73 20 74 68  ort.** orders th
40e0: 61 74 20 6d 61 79 20 74 61 6b 65 20 61 64 76 61  at may take adva
40f0: 6e 74 61 67 65 20 6f 66 20 53 51 4c 69 74 65 20  ntage of SQLite 
4100: 69 6e 64 69 63 65 73 20 6f 6e 20 74 68 65 20 75  indices on the u
4110: 6e 64 65 72 6c 79 69 6e 67 0a 2a 2a 20 72 65 61  nderlying.** rea
4120: 6c 20 74 61 62 6c 65 2e 20 46 6f 72 20 65 78 61  l table. For exa
4130: 6d 70 6c 65 2c 20 69 66 20 74 68 65 20 72 65 61  mple, if the rea
4140: 6c 20 74 61 62 6c 65 20 69 73 20 64 65 63 6c 61  l table is decla
4150: 72 65 64 20 61 73 3a 0a 2a 2a 0a 2a 2a 20 20 20  red as:.**.**   
4160: 20 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 72    CREATE TABLE r
4170: 65 61 6c 28 61 2c 20 62 2c 20 63 29 3b 0a 2a 2a  eal(a, b, c);.**
4180: 20 20 20 20 20 43 52 45 41 54 45 20 49 4e 44 45       CREATE INDE
4190: 58 20 72 65 61 6c 5f 69 6e 64 65 78 20 4f 4e 20  X real_index ON 
41a0: 72 65 61 6c 28 62 29 3b 0a 2a 2a 0a 2a 2a 20 74  real(b);.**.** t
41b0: 68 65 6e 20 74 68 65 20 65 63 68 6f 20 6d 6f 64  hen the echo mod
41c0: 75 6c 65 20 68 61 6e 64 6c 65 73 20 57 48 45 52  ule handles WHER
41d0: 45 20 6f 72 20 4f 52 44 45 52 20 42 59 20 63 6c  E or ORDER BY cl
41e0: 61 75 73 65 73 20 74 68 61 74 20 72 65 66 65 72  auses that refer
41f0: 0a 2a 2a 20 74 6f 20 74 68 65 20 63 6f 6c 75 6d  .** to the colum
4200: 6e 20 22 62 22 2c 20 62 75 74 20 6e 6f 74 20 22  n "b", but not "
4210: 61 22 20 6f 72 20 22 63 22 2e 20 49 66 20 61 20  a" or "c". If a 
4220: 6d 75 6c 74 69 2d 63 6f 6c 75 6d 6e 20 69 6e 64  multi-column ind
4230: 65 78 20 69 73 0a 2a 2a 20 70 72 65 73 65 6e 74  ex is.** present
4240: 2c 20 6f 6e 6c 79 20 69 74 27 73 20 6c 65 66 74  , only it's left
4250: 20 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20 69 73 20   most column is 
4260: 63 6f 6e 73 69 64 65 72 65 64 2e 20 0a 2a 2a 0a  considered. .**.
4270: 2a 2a 20 54 68 69 73 20 78 42 65 73 74 49 6e 64  ** This xBestInd
4280: 65 78 20 6d 65 74 68 6f 64 20 65 6e 63 6f 64 65  ex method encode
4290: 73 20 74 68 65 20 70 72 6f 70 6f 73 65 64 20 73  s the proposed s
42a0: 65 61 72 63 68 20 73 74 72 61 74 65 67 79 20 61  earch strategy a
42b0: 73 0a 2a 2a 20 61 6e 20 53 51 4c 20 71 75 65 72  s.** an SQL quer
42c0: 79 20 6f 6e 20 74 68 65 20 72 65 61 6c 20 74 61  y on the real ta
42d0: 62 6c 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 74  ble underlying t
42e0: 68 65 20 76 69 72 74 75 61 6c 20 65 63 68 6f 20  he virtual echo 
42f0: 6d 6f 64 75 6c 65 20 0a 2a 2a 20 74 61 62 6c 65  module .** table
4300: 20 61 6e 64 20 73 74 6f 72 65 73 20 74 68 65 20   and stores the 
4310: 71 75 65 72 79 20 69 6e 20 73 71 6c 69 74 65 33  query in sqlite3
4320: 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64 78 53  _index_info.idxS
4330: 74 72 2e 20 54 68 65 20 53 51 4c 0a 2a 2a 20 73  tr. The SQL.** s
4340: 74 61 74 65 6d 65 6e 74 20 69 73 20 6f 66 20 74  tatement is of t
4350: 68 65 20 66 6f 72 6d 3a 0a 2a 2a 0a 2a 2a 20 20  he form:.**.**  
4360: 20 53 45 4c 45 43 54 20 72 6f 77 69 64 2c 20 2a   SELECT rowid, *
4370: 20 46 52 4f 4d 20 3c 72 65 61 6c 2d 74 61 62 6c   FROM <real-tabl
4380: 65 3e 20 3f 3c 77 68 65 72 65 2d 63 6c 61 75 73  e> ?<where-claus
4390: 65 3e 3f 20 3f 3c 6f 72 64 65 72 2d 62 79 2d 63  e>? ?<order-by-c
43a0: 6c 61 75 73 65 3e 3f 0a 2a 2a 0a 2a 2a 20 77 68  lause>?.**.** wh
43b0: 65 72 65 20 74 68 65 20 3c 77 68 65 72 65 2d 63  ere the <where-c
43c0: 6c 61 75 73 65 3e 20 61 6e 64 20 3c 6f 72 64 65  lause> and <orde
43d0: 72 2d 62 79 2d 63 6c 61 75 73 65 3e 20 61 72 65  r-by-clause> are
43e0: 20 64 65 74 65 72 6d 69 6e 65 64 0a 2a 2a 20 62   determined.** b
43f0: 79 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  y the contents o
4400: 66 20 74 68 65 20 73 74 72 75 63 74 75 72 65 20  f the structure 
4410: 70 6f 69 6e 74 65 64 20 74 6f 20 62 79 20 74 68  pointed to by th
4420: 65 20 70 49 64 78 49 6e 66 6f 20 61 72 67 75 6d  e pIdxInfo argum
4430: 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ent..*/.static i
4440: 6e 74 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78  nt echoBestIndex
4450: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74  (sqlite3_vtab *t
4460: 61 62 2c 20 73 71 6c 69 74 65 33 5f 69 6e 64 65  ab, sqlite3_inde
4470: 78 5f 69 6e 66 6f 20 2a 70 49 64 78 49 6e 66 6f  x_info *pIdxInfo
4480: 29 7b 0a 20 20 69 6e 74 20 69 69 3b 0a 20 20 63  ){.  int ii;.  c
4490: 68 61 72 20 2a 7a 51 75 65 72 79 20 3d 20 30 3b  har *zQuery = 0;
44a0: 0a 20 20 63 68 61 72 20 2a 7a 4e 65 77 3b 0a 20  .  char *zNew;. 
44b0: 20 69 6e 74 20 6e 41 72 67 20 3d 20 30 3b 0a 20   int nArg = 0;. 
44c0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 65   const char *zSe
44d0: 70 20 3d 20 22 57 48 45 52 45 22 3b 0a 20 20 65  p = "WHERE";.  e
44e0: 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20  cho_vtab *pVtab 
44f0: 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 74  = (echo_vtab *)t
4500: 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74  ab;.  sqlite3_st
4510: 6d 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 0a  mt *pStmt = 0;..
4520: 20 20 69 6e 74 20 6e 52 6f 77 3b 0a 20 20 69 6e    int nRow;.  in
4530: 74 20 75 73 65 49 64 78 20 3d 20 30 3b 0a 20 20  t useIdx = 0;.  
4540: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
4550: 4f 4b 3b 0a 0a 20 20 2f 2a 20 44 65 74 65 72 6d  OK;..  /* Determ
4560: 69 6e 65 20 74 68 65 20 6e 75 6d 62 65 72 20 6f  ine the number o
4570: 66 20 72 6f 77 73 20 69 6e 20 74 68 65 20 74 61  f rows in the ta
4580: 62 6c 65 20 61 6e 64 20 73 74 6f 72 65 20 74 68  ble and store th
4590: 69 73 20 76 61 6c 75 65 20 69 6e 20 6c 6f 63 61  is value in loca
45a0: 6c 0a 20 20 2a 2a 20 76 61 72 69 61 62 6c 65 20  l.  ** variable 
45b0: 6e 52 6f 77 2e 20 54 68 65 20 27 65 73 74 69 6d  nRow. The 'estim
45c0: 61 74 65 64 2d 63 6f 73 74 27 20 6f 66 20 74 68  ated-cost' of th
45d0: 65 20 73 63 61 6e 20 77 69 6c 6c 20 62 65 20 74  e scan will be t
45e0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a 20 20 2a  he number of.  *
45f0: 2a 20 72 6f 77 73 20 69 6e 20 74 68 65 20 74 61  * rows in the ta
4600: 62 6c 65 20 66 6f 72 20 61 20 6c 69 6e 65 61 72  ble for a linear
4610: 20 73 63 61 6e 2c 20 6f 72 20 74 68 65 20 6c 6f   scan, or the lo
4620: 67 20 28 62 61 73 65 20 32 29 20 6f 66 20 74 68  g (base 2) of th
4630: 65 20 0a 20 20 2a 2a 20 6e 75 6d 62 65 72 20 6f  e .  ** number o
4640: 66 20 72 6f 77 73 20 69 66 20 74 68 65 20 70 72  f rows if the pr
4650: 6f 70 6f 73 65 64 20 73 63 61 6e 20 75 73 65 73  oposed scan uses
4660: 20 61 6e 20 69 6e 64 65 78 2e 20 20 0a 20 20 2a   an index.  .  *
4670: 2f 0a 20 20 7a 51 75 65 72 79 20 3d 20 73 71 6c  /.  zQuery = sql
4680: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 53 45  ite3_mprintf("SE
4690: 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 20 46 52  LECT count(*) FR
46a0: 4f 4d 20 25 51 22 2c 20 70 56 74 61 62 2d 3e 7a  OM %Q", pVtab->z
46b0: 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 72 63  TableName);.  rc
46c0: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
46d0: 72 65 28 70 56 74 61 62 2d 3e 64 62 2c 20 7a 51  re(pVtab->db, zQ
46e0: 75 65 72 79 2c 20 2d 31 2c 20 26 70 53 74 6d 74  uery, -1, &pStmt
46f0: 2c 20 30 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  , 0);.  if( rc!=
4700: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
4710: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a   return rc;.  }.
4720: 20 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70    sqlite3_step(p
4730: 53 74 6d 74 29 3b 0a 20 20 6e 52 6f 77 20 3d 20  Stmt);.  nRow = 
4740: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69  sqlite3_column_i
4750: 6e 74 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20  nt(pStmt, 0);.  
4760: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e  rc = sqlite3_fin
4770: 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20  alize(pStmt);.  
4780: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
4790: 4b 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  K ){.    return 
47a0: 72 63 3b 0a 20 20 7d 0a 0a 20 20 7a 51 75 65 72  rc;.  }..  zQuer
47b0: 79 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  y = sqlite3_mpri
47c0: 6e 74 66 28 22 53 45 4c 45 43 54 20 72 6f 77 69  ntf("SELECT rowi
47d0: 64 2c 20 2a 20 46 52 4f 4d 20 25 51 22 2c 20 70  d, * FROM %Q", p
47e0: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
47f0: 29 3b 0a 20 20 66 6f 72 28 69 69 3d 30 3b 20 69  );.  for(ii=0; i
4800: 69 3c 70 49 64 78 49 6e 66 6f 2d 3e 6e 43 6f 6e  i<pIdxInfo->nCon
4810: 73 74 72 61 69 6e 74 3b 20 69 69 2b 2b 29 7b 0a  straint; ii++){.
4820: 20 20 20 20 63 6f 6e 73 74 20 73 74 72 75 63 74      const struct
4830: 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 63   sqlite3_index_c
4840: 6f 6e 73 74 72 61 69 6e 74 20 2a 70 43 6f 6e 73  onstraint *pCons
4850: 74 72 61 69 6e 74 3b 0a 20 20 20 20 73 74 72 75  traint;.    stru
4860: 63 74 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78  ct sqlite3_index
4870: 5f 63 6f 6e 73 74 72 61 69 6e 74 5f 75 73 61 67  _constraint_usag
4880: 65 20 2a 70 55 73 61 67 65 3b 0a 0a 20 20 20 20  e *pUsage;..    
4890: 70 43 6f 6e 73 74 72 61 69 6e 74 20 3d 20 26 70  pConstraint = &p
48a0: 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72  IdxInfo->aConstr
48b0: 61 69 6e 74 5b 69 69 5d 3b 0a 20 20 20 20 70 55  aint[ii];.    pU
48c0: 73 61 67 65 20 3d 20 26 70 49 64 78 49 6e 66 6f  sage = &pIdxInfo
48d0: 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61  ->aConstraintUsa
48e0: 67 65 5b 69 69 5d 3b 0a 0a 20 20 20 20 69 6e 74  ge[ii];..    int
48f0: 20 69 43 6f 6c 20 3d 20 70 43 6f 6e 73 74 72 61   iCol = pConstra
4900: 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20 20  int->iColumn;.  
4910: 20 20 69 66 28 20 70 56 74 61 62 2d 3e 61 49 6e    if( pVtab->aIn
4920: 64 65 78 5b 69 43 6f 6c 5d 20 29 7b 0a 20 20 20  dex[iCol] ){.   
4930: 20 20 20 63 68 61 72 20 2a 7a 43 6f 6c 20 3d 20     char *zCol = 
4940: 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 43 6f 6c  pVtab->aCol[iCol
4950: 5d 3b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a  ];.      char *z
4960: 4f 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 75 73  Op = 0;.      us
4970: 65 49 64 78 20 3d 20 31 3b 0a 20 20 20 20 20 20  eIdx = 1;.      
4980: 69 66 28 20 69 43 6f 6c 3c 30 20 29 7b 0a 20 20  if( iCol<0 ){.  
4990: 20 20 20 20 20 20 7a 43 6f 6c 20 3d 20 22 72 6f        zCol = "ro
49a0: 77 69 64 22 3b 0a 20 20 20 20 20 20 7d 0a 20 20  wid";.      }.  
49b0: 20 20 20 20 73 77 69 74 63 68 28 20 70 43 6f 6e      switch( pCon
49c0: 73 74 72 61 69 6e 74 2d 3e 6f 70 20 29 7b 0a 20  straint->op ){. 
49d0: 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49         case SQLI
49e0: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
49f0: 49 4e 54 5f 45 51 3a 0a 20 20 20 20 20 20 20 20  INT_EQ:.        
4a00: 20 20 7a 4f 70 20 3d 20 22 3d 22 3b 20 62 72 65    zOp = "="; bre
4a10: 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65  ak;.        case
4a20: 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f   SQLITE_INDEX_CO
4a30: 4e 53 54 52 41 49 4e 54 5f 4c 54 3a 0a 20 20 20  NSTRAINT_LT:.   
4a40: 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3c 22         zOp = "<"
4a50: 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20  ; break;.       
4a60: 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 44   case SQLITE_IND
4a70: 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 47 54  EX_CONSTRAINT_GT
4a80: 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20  :.          zOp 
4a90: 3d 20 22 3e 22 3b 20 62 72 65 61 6b 3b 0a 20 20  = ">"; break;.  
4aa0: 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54        case SQLIT
4ab0: 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49  E_INDEX_CONSTRAI
4ac0: 4e 54 5f 4c 45 3a 0a 20 20 20 20 20 20 20 20 20  NT_LE:.         
4ad0: 20 7a 4f 70 20 3d 20 22 3c 3d 22 3b 20 62 72 65   zOp = "<="; bre
4ae0: 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65  ak;.        case
4af0: 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f   SQLITE_INDEX_CO
4b00: 4e 53 54 52 41 49 4e 54 5f 47 45 3a 0a 20 20 20  NSTRAINT_GE:.   
4b10: 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3e 3d         zOp = ">=
4b20: 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20  "; break;.      
4b30: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e    case SQLITE_IN
4b40: 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4d  DEX_CONSTRAINT_M
4b50: 41 54 43 48 3a 0a 20 20 20 20 20 20 20 20 20 20  ATCH:.          
4b60: 7a 4f 70 20 3d 20 22 4c 49 4b 45 22 3b 20 62 72  zOp = "LIKE"; br
4b70: 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  eak;.      }.   
4b80: 20 20 20 69 66 28 20 7a 4f 70 5b 30 5d 3d 3d 27     if( zOp[0]=='
4b90: 4c 27 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 4e  L' ){.        zN
4ba0: 65 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  ew = sqlite3_mpr
4bb0: 69 6e 74 66 28 22 20 25 73 20 25 73 20 4c 49 4b  intf(" %s %s LIK
4bc0: 45 20 28 53 45 4c 45 43 54 20 27 25 25 27 7c 7c  E (SELECT '%%'||
4bd0: 3f 7c 7c 27 25 25 27 29 22 2c 20 0a 20 20 20 20  ?||'%%')", .    
4be0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4bf0: 20 20 20 20 20 20 20 20 20 20 20 7a 53 65 70 2c             zSep,
4c00: 20 7a 43 6f 6c 29 3b 0a 20 20 20 20 20 20 7d 20   zCol);.      } 
4c10: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 7a  else {.        z
4c20: 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  New = sqlite3_mp
4c30: 72 69 6e 74 66 28 22 20 25 73 20 25 73 20 25 73  rintf(" %s %s %s
4c40: 20 3f 22 2c 20 7a 53 65 70 2c 20 7a 43 6f 6c 2c   ?", zSep, zCol,
4c50: 20 7a 4f 70 29 3b 0a 20 20 20 20 20 20 7d 0a 20   zOp);.      }. 
4c60: 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63       string_conc
4c70: 61 74 28 26 7a 51 75 65 72 79 2c 20 7a 4e 65 77  at(&zQuery, zNew
4c80: 2c 20 31 29 3b 0a 0a 20 20 20 20 20 20 7a 53 65  , 1);..      zSe
4c90: 70 20 3d 20 22 41 4e 44 22 3b 0a 20 20 20 20 20  p = "AND";.     
4ca0: 20 70 55 73 61 67 65 2d 3e 61 72 67 76 49 6e 64   pUsage->argvInd
4cb0: 65 78 20 3d 20 2b 2b 6e 41 72 67 3b 0a 20 20 20  ex = ++nArg;.   
4cc0: 20 20 20 70 55 73 61 67 65 2d 3e 6f 6d 69 74 20     pUsage->omit 
4cd0: 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  = 1;.    }.  }..
4ce0: 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20 69 73    /* If there is
4cf0: 20 6f 6e 6c 79 20 6f 6e 65 20 74 65 72 6d 20 69   only one term i
4d00: 6e 20 74 68 65 20 4f 52 44 45 52 20 42 59 20 63  n the ORDER BY c
4d10: 6c 61 75 73 65 2c 20 61 6e 64 20 69 74 20 69 73  lause, and it is
4d20: 0a 20 20 2a 2a 20 6f 6e 20 61 20 63 6f 6c 75 6d  .  ** on a colum
4d30: 6e 20 74 68 61 74 20 74 68 69 73 20 76 69 72 74  n that this virt
4d40: 75 61 6c 20 74 61 62 6c 65 20 68 61 73 20 61 6e  ual table has an
4d50: 20 69 6e 64 65 78 20 66 6f 72 2c 20 74 68 65 6e   index for, then
4d60: 20 63 6f 6e 73 75 6d 65 20 0a 20 20 2a 2a 20 74   consume .  ** t
4d70: 68 65 20 4f 52 44 45 52 20 42 59 20 63 6c 61 75  he ORDER BY clau
4d80: 73 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 70  se..  */.  if( p
4d90: 49 64 78 49 6e 66 6f 2d 3e 6e 4f 72 64 65 72 42  IdxInfo->nOrderB
4da0: 79 3d 3d 31 20 26 26 20 70 56 74 61 62 2d 3e 61  y==1 && pVtab->a
4db0: 49 6e 64 65 78 5b 70 49 64 78 49 6e 66 6f 2d 3e  Index[pIdxInfo->
4dc0: 61 4f 72 64 65 72 42 79 2d 3e 69 43 6f 6c 75 6d  aOrderBy->iColum
4dd0: 6e 5d 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a  n] ){.    char *
4de0: 7a 43 6f 6c 20 3d 20 70 56 74 61 62 2d 3e 61 43  zCol = pVtab->aC
4df0: 6f 6c 5b 70 49 64 78 49 6e 66 6f 2d 3e 61 4f 72  ol[pIdxInfo->aOr
4e00: 64 65 72 42 79 2d 3e 69 43 6f 6c 75 6d 6e 5d 3b  derBy->iColumn];
4e10: 0a 20 20 20 20 63 68 61 72 20 2a 7a 44 69 72 20  .    char *zDir 
4e20: 3d 20 70 49 64 78 49 6e 66 6f 2d 3e 61 4f 72 64  = pIdxInfo->aOrd
4e30: 65 72 42 79 2d 3e 64 65 73 63 3f 22 44 45 53 43  erBy->desc?"DESC
4e40: 22 3a 22 41 53 43 22 3b 0a 20 20 20 20 7a 4e 65  ":"ASC";.    zNe
4e50: 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  w = sqlite3_mpri
4e60: 6e 74 66 28 22 20 4f 52 44 45 52 20 42 59 20 25  ntf(" ORDER BY %
4e70: 73 20 25 73 22 2c 20 7a 43 6f 6c 2c 20 7a 44 69  s %s", zCol, zDi
4e80: 72 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63  r);.    string_c
4e90: 6f 6e 63 61 74 28 26 7a 51 75 65 72 79 2c 20 7a  oncat(&zQuery, z
4ea0: 4e 65 77 2c 20 31 29 3b 0a 20 20 20 20 70 49 64  New, 1);.    pId
4eb0: 78 49 6e 66 6f 2d 3e 6f 72 64 65 72 42 79 43 6f  xInfo->orderByCo
4ec0: 6e 73 75 6d 65 64 20 3d 20 31 3b 0a 20 20 7d 0a  nsumed = 1;.  }.
4ed0: 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d  .  appendToEchoM
4ee0: 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74  odule(pVtab->int
4ef0: 65 72 70 2c 20 22 78 42 65 73 74 49 6e 64 65 78  erp, "xBestIndex
4f00: 22 29 3b 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45  ");;.  appendToE
4f10: 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d  choModule(pVtab-
4f20: 3e 69 6e 74 65 72 70 2c 20 7a 51 75 65 72 79 29  >interp, zQuery)
4f30: 3b 0a 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 69  ;..  pIdxInfo->i
4f40: 64 78 4e 75 6d 20 3d 20 68 61 73 68 53 74 72 69  dxNum = hashStri
4f50: 6e 67 28 7a 51 75 65 72 79 29 3b 0a 20 20 70 49  ng(zQuery);.  pI
4f60: 64 78 49 6e 66 6f 2d 3e 69 64 78 53 74 72 20 3d  dxInfo->idxStr =
4f70: 20 7a 51 75 65 72 79 3b 0a 20 20 70 49 64 78 49   zQuery;.  pIdxI
4f80: 6e 66 6f 2d 3e 6e 65 65 64 54 6f 46 72 65 65 49  nfo->needToFreeI
4f90: 64 78 53 74 72 20 3d 20 31 3b 0a 20 20 69 66 28  dxStr = 1;.  if(
4fa0: 20 75 73 65 49 64 78 20 29 7b 0a 20 20 20 20 2f   useIdx ){.    /
4fb0: 2a 20 41 70 70 72 6f 78 69 6d 61 74 69 6f 6e 20  * Approximation 
4fc0: 6f 66 20 6c 6f 67 32 28 6e 52 6f 77 29 2e 20 2a  of log2(nRow). *
4fd0: 2f 0a 20 20 20 20 66 6f 72 28 20 69 69 3d 30 3b  /.    for( ii=0;
4fe0: 20 69 69 3c 28 73 69 7a 65 6f 66 28 69 6e 74 29   ii<(sizeof(int)
4ff0: 2a 38 29 3b 20 69 69 2b 2b 20 29 7b 0a 20 20 20  *8); ii++ ){.   
5000: 20 20 20 69 66 28 20 6e 52 6f 77 20 26 20 28 31     if( nRow & (1
5010: 3c 3c 69 69 29 20 29 7b 0a 20 20 20 20 20 20 20  <<ii) ){.       
5020: 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d   pIdxInfo->estim
5030: 61 74 65 64 43 6f 73 74 20 3d 20 28 64 6f 75 62  atedCost = (doub
5040: 6c 65 29 69 69 3b 0a 20 20 20 20 20 20 7d 0a 20  le)ii;.      }. 
5050: 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a     }.  } else {.
5060: 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73      pIdxInfo->es
5070: 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 28 64  timatedCost = (d
5080: 6f 75 62 6c 65 29 6e 52 6f 77 3b 0a 20 20 7d 0a  ouble)nRow;.  }.
5090: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
50a0: 2f 2a 0a 2a 2a 20 54 68 65 20 78 55 70 64 61 74  /*.** The xUpdat
50b0: 65 20 6d 65 74 68 6f 64 20 66 6f 72 20 65 63 68  e method for ech
50c0: 6f 20 6d 6f 64 75 6c 65 20 76 69 72 74 75 61 6c  o module virtual
50d0: 20 74 61 62 6c 65 73 2e 0a 2a 2a 20 0a 2a 2a 20   tables..** .** 
50e0: 20 20 20 61 70 44 61 74 61 5b 30 5d 20 20 61 70     apData[0]  ap
50f0: 44 61 74 61 5b 31 5d 20 20 61 70 44 61 74 61 5b  Data[1]  apData[
5100: 32 2e 2e 5d 0a 2a 2a 0a 2a 2a 20 20 20 20 49 4e  2..].**.**    IN
5110: 54 45 47 45 52 20 20 20 20 20 20 20 20 20 20 20  TEGER           
5120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5130: 20 20 20 44 45 4c 45 54 45 20 20 20 20 20 20 20     DELETE       
5140: 20 20 20 20 20 0a 2a 2a 0a 2a 2a 20 20 20 20 49       .**.**    I
5150: 4e 54 45 47 45 52 20 20 20 20 4e 55 4c 4c 20 20  NTEGER    NULL  
5160: 20 20 20 20 20 28 6e 43 6f 6c 20 61 72 67 73 29       (nCol args)
5170: 20 20 20 20 55 50 44 41 54 45 20 28 64 6f 20 6e      UPDATE (do n
5180: 6f 74 20 73 65 74 20 72 6f 77 69 64 29 0a 2a 2a  ot set rowid).**
5190: 20 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 49      INTEGER    I
51a0: 4e 54 45 47 45 52 20 20 20 20 28 6e 43 6f 6c 20  NTEGER    (nCol 
51b0: 61 72 67 73 29 20 20 20 20 55 50 44 41 54 45 20  args)    UPDATE 
51c0: 28 77 69 74 68 20 53 45 54 20 72 6f 77 69 64 20  (with SET rowid 
51d0: 3d 20 3c 61 72 67 31 3e 29 0a 2a 2a 0a 2a 2a 20  = <arg1>).**.** 
51e0: 20 20 20 4e 55 4c 4c 20 20 20 20 20 20 20 4e 55     NULL       NU
51f0: 4c 4c 20 20 20 20 20 20 20 28 6e 43 6f 6c 20 61  LL       (nCol a
5200: 72 67 73 29 20 20 20 20 49 4e 53 45 52 54 20 49  rgs)    INSERT I
5210: 4e 54 4f 20 28 61 75 74 6f 6d 61 74 69 63 20 72  NTO (automatic r
5220: 6f 77 69 64 20 76 61 6c 75 65 29 0a 2a 2a 20 20  owid value).**  
5230: 20 20 4e 55 4c 4c 20 20 20 20 20 20 20 49 4e 54    NULL       INT
5240: 45 47 45 52 20 20 20 20 28 6e 43 6f 6c 20 61 72  EGER    (nCol ar
5250: 67 73 29 20 20 20 20 49 4e 53 45 52 54 20 28 69  gs)    INSERT (i
5260: 6e 63 6c 2e 20 72 6f 77 69 64 20 76 61 6c 75 65  ncl. rowid value
5270: 29 0a 2a 2a 0a 2a 2f 0a 69 6e 74 20 65 63 68 6f  ).**.*/.int echo
5280: 55 70 64 61 74 65 28 0a 20 20 73 71 6c 69 74 65  Update(.  sqlite
5290: 33 5f 76 74 61 62 20 2a 74 61 62 2c 20 0a 20 20  3_vtab *tab, .  
52a0: 69 6e 74 20 6e 44 61 74 61 2c 20 0a 20 20 73 71  int nData, .  sq
52b0: 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70  lite3_value **ap
52c0: 44 61 74 61 2c 20 0a 20 20 73 71 6c 69 74 65 5f  Data, .  sqlite_
52d0: 69 6e 74 36 34 20 2a 70 52 6f 77 69 64 0a 29 7b  int64 *pRowid.){
52e0: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56  .  echo_vtab *pV
52f0: 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62  tab = (echo_vtab
5300: 20 2a 29 74 61 62 3b 0a 20 20 73 71 6c 69 74 65   *)tab;.  sqlite
5310: 33 20 2a 64 62 20 3d 20 70 56 74 61 62 2d 3e 64  3 *db = pVtab->d
5320: 62 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  b;.  int rc = SQ
5330: 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 73 71 6c 69  LITE_OK;..  sqli
5340: 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b  te3_stmt *pStmt;
5350: 0a 20 20 63 68 61 72 20 2a 7a 20 3d 20 30 3b 20  .  char *z = 0; 
5360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5370: 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 20 74   SQL statement t
5380: 6f 20 65 78 65 63 75 74 65 20 2a 2f 0a 20 20 69  o execute */.  i
5390: 6e 74 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d  nt bindArgZero =
53a0: 20 30 3b 20 20 20 20 20 20 20 2f 2a 20 54 72 75   0;       /* Tru
53b0: 65 20 74 6f 20 62 69 6e 64 20 61 70 44 61 74 61  e to bind apData
53c0: 5b 30 5d 20 74 6f 20 73 71 6c 20 76 61 72 20 6e  [0] to sql var n
53d0: 6f 2e 20 6e 44 61 74 61 20 2a 2f 0a 20 20 69 6e  o. nData */.  in
53e0: 74 20 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20 30  t bindArgOne = 0
53f0: 3b 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65  ;        /* True
5400: 20 74 6f 20 62 69 6e 64 20 61 70 44 61 74 61 5b   to bind apData[
5410: 31 5d 20 74 6f 20 73 71 6c 20 76 61 72 20 6e 6f  1] to sql var no
5420: 2e 20 31 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20  . 1 */.  int i; 
5430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5440: 20 20 20 20 2f 2a 20 43 6f 75 6e 74 65 72 20 76      /* Counter v
5450: 61 72 69 61 62 6c 65 20 75 73 65 64 20 62 79 20  ariable used by 
5460: 66 6f 72 20 6c 6f 6f 70 73 20 2a 2f 0a 0a 20 20  for loops */..  
5470: 61 73 73 65 72 74 28 20 6e 44 61 74 61 3d 3d 70  assert( nData==p
5480: 56 74 61 62 2d 3e 6e 43 6f 6c 2b 32 20 7c 7c 20  Vtab->nCol+2 || 
5490: 6e 44 61 74 61 3d 3d 31 20 29 3b 0a 0a 20 20 2f  nData==1 );..  /
54a0: 2a 20 49 66 20 61 70 44 61 74 61 5b 30 5d 20 69  * If apData[0] i
54b0: 73 20 61 6e 20 69 6e 74 65 67 65 72 20 61 6e 64  s an integer and
54c0: 20 6e 44 61 74 61 3e 31 20 74 68 65 6e 20 64 6f   nData>1 then do
54d0: 20 61 6e 20 55 50 44 41 54 45 20 2a 2f 0a 20 20   an UPDATE */.  
54e0: 69 66 28 20 6e 44 61 74 61 3e 31 20 26 26 20 73  if( nData>1 && s
54f0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70  qlite3_value_typ
5500: 65 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51  e(apData[0])==SQ
5510: 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a  LITE_INTEGER ){.
5520: 20 20 20 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f      z = sqlite3_
5530: 6d 70 72 69 6e 74 66 28 22 55 50 44 41 54 45 20  mprintf("UPDATE 
5540: 25 51 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62  %Q", pVtab->zTab
5550: 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 63 68 61  leName);.    cha
5560: 72 20 2a 7a 53 65 70 20 3d 20 22 20 53 45 54 22  r *zSep = " SET"
5570: 3b 0a 0a 20 20 20 20 62 69 6e 64 41 72 67 4f 6e  ;..    bindArgOn
5580: 65 20 3d 20 28 61 70 44 61 74 61 5b 31 5d 20 26  e = (apData[1] &
5590: 26 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  & sqlite3_value_
55a0: 74 79 70 65 28 61 70 44 61 74 61 5b 31 5d 29 3d  type(apData[1])=
55b0: 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 29  =SQLITE_INTEGER)
55c0: 3b 0a 20 20 20 20 62 69 6e 64 41 72 67 5a 65 72  ;.    bindArgZer
55d0: 6f 20 3d 20 31 3b 0a 0a 20 20 20 20 69 66 28 20  o = 1;..    if( 
55e0: 62 69 6e 64 41 72 67 4f 6e 65 20 29 7b 0a 20 20  bindArgOne ){.  
55f0: 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63       string_conc
5600: 61 74 28 26 7a 2c 20 22 20 53 45 54 20 72 6f 77  at(&z, " SET row
5610: 69 64 3d 3f 31 20 22 2c 20 30 29 3b 0a 20 20 20  id=?1 ", 0);.   
5620: 20 20 20 20 7a 53 65 70 20 3d 20 22 2c 22 3b 0a      zSep = ",";.
5630: 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 69 3d      }.    for(i=
5640: 32 3b 20 69 3c 6e 44 61 74 61 3b 20 69 2b 2b 29  2; i<nData; i++)
5650: 7b 0a 20 20 20 20 20 20 69 66 28 20 61 70 44 61  {.      if( apDa
5660: 74 61 5b 69 5d 3d 3d 30 20 29 20 63 6f 6e 74 69  ta[i]==0 ) conti
5670: 6e 75 65 3b 0a 20 20 20 20 20 20 73 74 72 69 6e  nue;.      strin
5680: 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 73 71 6c  g_concat(&z, sql
5690: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20 20  ite3_mprintf(.  
56a0: 20 20 20 20 20 20 20 20 22 25 73 20 25 51 3d 3f          "%s %Q=?
56b0: 25 64 22 2c 20 7a 53 65 70 2c 20 70 56 74 61 62  %d", zSep, pVtab
56c0: 2d 3e 61 43 6f 6c 5b 69 2d 32 5d 2c 20 69 29 2c  ->aCol[i-2], i),
56d0: 20 31 29 3b 0a 20 20 20 20 20 20 7a 53 65 70 20   1);.      zSep 
56e0: 3d 20 22 2c 22 3b 0a 20 20 20 20 7d 0a 20 20 20  = ",";.    }.   
56f0: 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26   string_concat(&
5700: 7a 2c 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e  z, sqlite3_mprin
5710: 74 66 28 22 20 57 48 45 52 45 20 72 6f 77 69 64  tf(" WHERE rowid
5720: 3d 3f 25 64 22 2c 20 6e 44 61 74 61 29 2c 20 30  =?%d", nData), 0
5730: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20  );.  }..  /* If 
5740: 61 70 44 61 74 61 5b 30 5d 20 69 73 20 61 6e 20  apData[0] is an 
5750: 69 6e 74 65 67 65 72 20 61 6e 64 20 6e 44 61 74  integer and nDat
5760: 61 3d 3d 31 20 74 68 65 6e 20 64 6f 20 61 20 44  a==1 then do a D
5770: 45 4c 45 54 45 20 2a 2f 0a 20 20 65 6c 73 65 20  ELETE */.  else 
5780: 69 66 28 20 6e 44 61 74 61 3d 3d 31 20 26 26 20  if( nData==1 && 
5790: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79  sqlite3_value_ty
57a0: 70 65 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53  pe(apData[0])==S
57b0: 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b  QLITE_INTEGER ){
57c0: 0a 20 20 20 20 7a 20 3d 20 73 71 6c 69 74 65 33  .    z = sqlite3
57d0: 5f 6d 70 72 69 6e 74 66 28 22 44 45 4c 45 54 45  _mprintf("DELETE
57e0: 20 46 52 4f 4d 20 25 51 20 57 48 45 52 45 20 72   FROM %Q WHERE r
57f0: 6f 77 69 64 20 3d 20 3f 31 22 2c 20 70 56 74 61  owid = ?1", pVta
5800: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a  b->zTableName);.
5810: 20 20 20 20 62 69 6e 64 41 72 67 5a 65 72 6f 20      bindArgZero 
5820: 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49  = 1;.  }..  /* I
5830: 66 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75  f the first argu
5840: 6d 65 6e 74 20 69 73 20 4e 55 4c 4c 20 61 6e 64  ment is NULL and
5850: 20 74 68 65 72 65 20 61 72 65 20 6d 6f 72 65 20   there are more 
5860: 74 68 61 6e 20 74 77 6f 20 61 72 67 73 2c 20 49  than two args, I
5870: 4e 53 45 52 54 20 2a 2f 0a 20 20 65 6c 73 65 20  NSERT */.  else 
5880: 69 66 28 20 6e 44 61 74 61 3e 32 20 26 26 20 73  if( nData>2 && s
5890: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70  qlite3_value_typ
58a0: 65 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51  e(apData[0])==SQ
58b0: 4c 49 54 45 5f 4e 55 4c 4c 20 29 7b 0a 20 20 20  LITE_NULL ){.   
58c0: 20 69 6e 74 20 69 69 3b 0a 20 20 20 20 63 68 61   int ii;.    cha
58d0: 72 20 2a 7a 49 6e 73 65 72 74 20 3d 20 30 3b 0a  r *zInsert = 0;.
58e0: 20 20 20 20 63 68 61 72 20 2a 7a 56 61 6c 75 65      char *zValue
58f0: 73 20 3d 20 30 3b 0a 20 20 0a 20 20 20 20 7a 49  s = 0;.  .    zI
5900: 6e 73 65 72 74 20 3d 20 73 71 6c 69 74 65 33 5f  nsert = sqlite3_
5910: 6d 70 72 69 6e 74 66 28 22 49 4e 53 45 52 54 20  mprintf("INSERT 
5920: 49 4e 54 4f 20 25 51 20 28 22 2c 20 70 56 74 61  INTO %Q (", pVta
5930: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a  b->zTableName);.
5940: 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f      if( sqlite3_
5950: 76 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61 74  value_type(apDat
5960: 61 5b 31 5d 29 3d 3d 53 51 4c 49 54 45 5f 49 4e  a[1])==SQLITE_IN
5970: 54 45 47 45 52 20 29 7b 0a 20 20 20 20 20 20 62  TEGER ){.      b
5980: 69 6e 64 41 72 67 4f 6e 65 20 3d 20 31 3b 0a 20  indArgOne = 1;. 
5990: 20 20 20 20 20 7a 56 61 6c 75 65 73 20 3d 20 73       zValues = s
59a0: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
59b0: 3f 22 29 3b 0a 20 20 20 20 20 20 73 74 72 69 6e  ?");.      strin
59c0: 67 5f 63 6f 6e 63 61 74 28 26 7a 49 6e 73 65 72  g_concat(&zInser
59d0: 74 2c 20 22 72 6f 77 69 64 22 2c 20 30 29 3b 0a  t, "rowid", 0);.
59e0: 20 20 20 20 7d 0a 0a 20 20 20 20 61 73 73 65 72      }..    asser
59f0: 74 28 28 70 56 74 61 62 2d 3e 6e 43 6f 6c 2b 32  t((pVtab->nCol+2
5a00: 29 3d 3d 6e 44 61 74 61 29 3b 0a 20 20 20 20 66  )==nData);.    f
5a10: 6f 72 28 69 69 3d 32 3b 20 69 69 3c 6e 44 61 74  or(ii=2; ii<nDat
5a20: 61 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20  a; ii++){.      
5a30: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
5a40: 49 6e 73 65 72 74 2c 20 0a 20 20 20 20 20 20 20  Insert, .       
5a50: 20 20 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e     sqlite3_mprin
5a60: 74 66 28 22 25 73 25 51 22 2c 20 7a 56 61 6c 75  tf("%s%Q", zValu
5a70: 65 73 3f 22 2c 20 22 3a 22 22 2c 20 70 56 74 61  es?", ":"", pVta
5a80: 62 2d 3e 61 43 6f 6c 5b 69 69 2d 32 5d 29 2c 20  b->aCol[ii-2]), 
5a90: 31 29 3b 0a 20 20 20 20 20 20 73 74 72 69 6e 67  1);.      string
5aa0: 5f 63 6f 6e 63 61 74 28 26 7a 56 61 6c 75 65 73  _concat(&zValues
5ab0: 2c 20 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c  , .          sql
5ac0: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73  ite3_mprintf("%s
5ad0: 3f 25 64 22 2c 20 7a 56 61 6c 75 65 73 3f 22 2c  ?%d", zValues?",
5ae0: 20 22 3a 22 22 2c 20 69 69 29 2c 20 31 29 3b 0a   ":"", ii), 1);.
5af0: 20 20 20 20 7d 0a 0a 20 20 20 20 73 74 72 69 6e      }..    strin
5b00: 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 7a 49 6e  g_concat(&z, zIn
5b10: 73 65 72 74 2c 20 31 29 3b 0a 20 20 20 20 73 74  sert, 1);.    st
5b20: 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20  ring_concat(&z, 
5b30: 22 29 20 56 41 4c 55 45 53 28 22 2c 20 30 29 3b  ") VALUES(", 0);
5b40: 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63  .    string_conc
5b50: 61 74 28 26 7a 2c 20 7a 56 61 6c 75 65 73 2c 20  at(&z, zValues, 
5b60: 31 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63  1);.    string_c
5b70: 6f 6e 63 61 74 28 26 7a 2c 20 22 29 22 2c 20 30  oncat(&z, ")", 0
5b80: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 6e 79  );.  }..  /* Any
5b90: 74 68 69 6e 67 20 65 6c 73 65 20 69 73 20 61 6e  thing else is an
5ba0: 20 65 72 72 6f 72 20 2a 2f 0a 20 20 65 6c 73 65   error */.  else
5bb0: 7b 0a 20 20 20 20 61 73 73 65 72 74 28 30 29 3b  {.    assert(0);
5bc0: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
5bd0: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20  TE_ERROR;.  }.. 
5be0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72   rc = sqlite3_pr
5bf0: 65 70 61 72 65 28 64 62 2c 20 7a 2c 20 2d 31 2c  epare(db, z, -1,
5c00: 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 61   &pStmt, 0);.  a
5c10: 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54  ssert( rc!=SQLIT
5c20: 45 5f 4f 4b 20 7c 7c 20 70 53 74 6d 74 20 29 3b  E_OK || pStmt );
5c30: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
5c40: 7a 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  z);.  if( rc==SQ
5c50: 4c 49 54 45 5f 4f 4b 20 29 20 7b 0a 20 20 20 20  LITE_OK ) {.    
5c60: 69 66 28 20 62 69 6e 64 41 72 67 5a 65 72 6f 20  if( bindArgZero 
5c70: 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
5c80: 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d  _bind_value(pStm
5c90: 74 2c 20 6e 44 61 74 61 2c 20 61 70 44 61 74 61  t, nData, apData
5ca0: 5b 30 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  [0]);.    }.    
5cb0: 69 66 28 20 62 69 6e 64 41 72 67 4f 6e 65 20 29  if( bindArgOne )
5cc0: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
5cd0: 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d 74  bind_value(pStmt
5ce0: 2c 20 31 2c 20 61 70 44 61 74 61 5b 31 5d 29 3b  , 1, apData[1]);
5cf0: 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 69  .    }.    for(i
5d00: 3d 32 3b 20 69 3c 6e 44 61 74 61 3b 20 69 2b 2b  =2; i<nData; i++
5d10: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 61 70 44  ){.      if( apD
5d20: 61 74 61 5b 69 5d 20 29 20 73 71 6c 69 74 65 33  ata[i] ) sqlite3
5d30: 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d  _bind_value(pStm
5d40: 74 2c 20 69 2c 20 61 70 44 61 74 61 5b 69 5d 29  t, i, apData[i])
5d50: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69  ;.    }.    sqli
5d60: 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 3b  te3_step(pStmt);
5d70: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
5d80: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74  3_finalize(pStmt
5d90: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 52  );.  }..  if( pR
5da0: 6f 77 69 64 20 26 26 20 72 63 3d 3d 53 51 4c 49  owid && rc==SQLI
5db0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 52  TE_OK ){.    *pR
5dc0: 6f 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 6c  owid = sqlite3_l
5dd0: 61 73 74 5f 69 6e 73 65 72 74 5f 72 6f 77 69 64  ast_insert_rowid
5de0: 28 64 62 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  (db);.  }..  ret
5df0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
5e00: 20 78 42 65 67 69 6e 2c 20 78 53 79 6e 63 2c 20   xBegin, xSync, 
5e10: 78 43 6f 6d 6d 69 74 20 61 6e 64 20 78 52 6f 6c  xCommit and xRol
5e20: 6c 62 61 63 6b 20 63 61 6c 6c 62 61 63 6b 73 20  lback callbacks 
5e30: 66 6f 72 20 65 63 68 6f 20 6d 6f 64 75 6c 65 0a  for echo module.
5e40: 2a 2a 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ** virtual table
5e50: 73 2e 20 44 6f 20 6e 6f 74 68 69 6e 67 20 6f 74  s. Do nothing ot
5e60: 68 65 72 20 74 68 61 6e 20 61 64 64 20 74 68 65  her than add the
5e70: 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 63 61 6c   name of the cal
5e80: 6c 62 61 63 6b 0a 2a 2a 20 74 6f 20 74 68 65 20  lback.** to the 
5e90: 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 54  $::echo_module T
5ea0: 63 6c 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2f 0a  cl variable..*/.
5eb0: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 54  static int echoT
5ec0: 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 73  ransactionCall(s
5ed0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62  qlite3_vtab *tab
5ee0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43  , const char *zC
5ef0: 61 6c 6c 29 7b 0a 20 20 63 68 61 72 20 2a 7a 3b  all){.  char *z;
5f00: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56  .  echo_vtab *pV
5f10: 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62  tab = (echo_vtab
5f20: 20 2a 29 74 61 62 3b 0a 20 20 7a 20 3d 20 73 71   *)tab;.  z = sq
5f30: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 65  lite3_mprintf("e
5f40: 63 68 6f 28 25 73 29 22 2c 20 70 56 74 61 62 2d  cho(%s)", pVtab-
5f50: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20  >zTableName);.  
5f60: 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75  appendToEchoModu
5f70: 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70  le(pVtab->interp
5f80: 2c 20 7a 43 61 6c 6c 29 3b 0a 20 20 61 70 70 65  , zCall);.  appe
5f90: 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70  ndToEchoModule(p
5fa0: 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 7a 29  Vtab->interp, z)
5fb0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
5fc0: 28 7a 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51  (z);.  return SQ
5fd0: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 73 74 61 74 69  LITE_OK;.}.stati
5fe0: 63 20 69 6e 74 20 65 63 68 6f 42 65 67 69 6e 28  c int echoBegin(
5ff0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61  sqlite3_vtab *ta
6000: 62 29 7b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20  b){.  echo_vtab 
6010: 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76  *pVtab = (echo_v
6020: 74 61 62 20 2a 29 74 61 62 3b 0a 20 20 54 63 6c  tab *)tab;.  Tcl
6030: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 20  _Interp *interp 
6040: 3d 20 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 3b  = pVtab->interp;
6050: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
6060: 56 61 6c 3b 20 0a 0a 20 20 65 63 68 6f 54 72 61  Val; ..  echoTra
6070: 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74 61 62  nsactionCall(tab
6080: 2c 20 22 78 42 65 67 69 6e 22 29 3b 0a 0a 20 20  , "xBegin");..  
6090: 2f 2a 20 43 68 65 63 6b 20 69 66 20 74 68 65 20  /* Check if the 
60a0: 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 62  $::echo_module_b
60b0: 65 67 69 6e 5f 66 61 69 6c 20 76 61 72 69 61 62  egin_fail variab
60c0: 6c 65 20 69 73 20 64 65 66 69 6e 65 64 2e 20 49  le is defined. I
60d0: 66 20 69 74 20 69 73 2c 0a 20 20 2a 2a 20 61 6e  f it is,.  ** an
60e0: 64 20 69 74 20 69 73 20 73 65 74 20 74 6f 20 74  d it is set to t
60f0: 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 72  he name of the r
6100: 65 61 6c 20 74 61 62 6c 65 20 75 6e 64 65 72 6c  eal table underl
6110: 79 69 6e 67 20 74 68 69 73 20 76 69 72 74 75 61  ying this virtua
6120: 6c 0a 20 20 2a 2a 20 65 63 68 6f 20 6d 6f 64 75  l.  ** echo modu
6130: 6c 65 20 74 61 62 6c 65 2c 20 74 68 65 6e 20 63  le table, then c
6140: 61 75 73 65 20 74 68 69 73 20 78 53 79 6e 63 20  ause this xSync 
6150: 6f 70 65 72 61 74 69 6f 6e 20 74 6f 20 66 61 69  operation to fai
6160: 6c 2e 0a 20 20 2a 2f 0a 20 20 7a 56 61 6c 20 3d  l..  */.  zVal =
6170: 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65   Tcl_GetVar(inte
6180: 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65  rp, "echo_module
6190: 5f 62 65 67 69 6e 5f 66 61 69 6c 22 2c 20 54 43  _begin_fail", TC
61a0: 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a  L_GLOBAL_ONLY);.
61b0: 20 20 69 66 28 20 7a 56 61 6c 20 26 26 20 30 3d    if( zVal && 0=
61c0: 3d 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 70 56  =strcmp(zVal, pV
61d0: 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29  tab->zTableName)
61e0: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
61f0: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d  QLITE_ERROR;.  }
6200: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
6210: 5f 4f 4b 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e  _OK;.}.static in
6220: 74 20 65 63 68 6f 53 79 6e 63 28 73 71 6c 69 74  t echoSync(sqlit
6230: 65 33 5f 76 74 61 62 20 2a 74 61 62 29 7b 0a 20  e3_vtab *tab){. 
6240: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
6250: 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  b = (echo_vtab *
6260: 29 74 61 62 3b 0a 20 20 54 63 6c 5f 49 6e 74 65  )tab;.  Tcl_Inte
6270: 72 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 56 74  rp *interp = pVt
6280: 61 62 2d 3e 69 6e 74 65 72 70 3b 0a 20 20 63 6f  ab->interp;.  co
6290: 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 3b 20  nst char *zVal; 
62a0: 0a 0a 20 20 65 63 68 6f 54 72 61 6e 73 61 63 74  ..  echoTransact
62b0: 69 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 53  ionCall(tab, "xS
62c0: 79 6e 63 22 29 3b 0a 0a 20 20 2f 2a 20 43 68 65  ync");..  /* Che
62d0: 63 6b 20 69 66 20 74 68 65 20 24 3a 3a 65 63 68  ck if the $::ech
62e0: 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f 66 61  o_module_sync_fa
62f0: 69 6c 20 76 61 72 69 61 62 6c 65 20 69 73 20 64  il variable is d
6300: 65 66 69 6e 65 64 2e 20 49 66 20 69 74 20 69 73  efined. If it is
6310: 2c 0a 20 20 2a 2a 20 61 6e 64 20 69 74 20 69 73  ,.  ** and it is
6320: 20 73 65 74 20 74 6f 20 74 68 65 20 6e 61 6d 65   set to the name
6330: 20 6f 66 20 74 68 65 20 72 65 61 6c 20 74 61 62   of the real tab
6340: 6c 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 74 68  le underlying th
6350: 69 73 20 76 69 72 74 75 61 6c 0a 20 20 2a 2a 20  is virtual.  ** 
6360: 65 63 68 6f 20 6d 6f 64 75 6c 65 20 74 61 62 6c  echo module tabl
6370: 65 2c 20 74 68 65 6e 20 63 61 75 73 65 20 74 68  e, then cause th
6380: 69 73 20 78 53 79 6e 63 20 6f 70 65 72 61 74 69  is xSync operati
6390: 6f 6e 20 74 6f 20 66 61 69 6c 2e 0a 20 20 2a 2f  on to fail..  */
63a0: 0a 20 20 7a 56 61 6c 20 3d 20 54 63 6c 5f 47 65  .  zVal = Tcl_Ge
63b0: 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65 63  tVar(interp, "ec
63c0: 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f 66  ho_module_sync_f
63d0: 61 69 6c 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c  ail", TCL_GLOBAL
63e0: 5f 4f 4e 4c 59 29 3b 0a 20 20 69 66 28 20 7a 56  _ONLY);.  if( zV
63f0: 61 6c 20 26 26 20 30 3d 3d 73 74 72 63 6d 70 28  al && 0==strcmp(
6400: 7a 56 61 6c 2c 20 70 56 74 61 62 2d 3e 7a 54 61  zVal, pVtab->zTa
6410: 62 6c 65 4e 61 6d 65 29 20 29 7b 0a 20 20 20 20  bleName) ){.    
6420: 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20 7d 0a 20  return -1;.  }. 
6430: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
6440: 4b 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20  K;.}.static int 
6450: 65 63 68 6f 43 6f 6d 6d 69 74 28 73 71 6c 69 74  echoCommit(sqlit
6460: 65 33 5f 76 74 61 62 20 2a 74 61 62 29 7b 0a 20  e3_vtab *tab){. 
6470: 20 72 65 74 75 72 6e 20 65 63 68 6f 54 72 61 6e   return echoTran
6480: 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74 61 62 2c  sactionCall(tab,
6490: 20 22 78 43 6f 6d 6d 69 74 22 29 3b 0a 7d 0a 73   "xCommit");.}.s
64a0: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 52 6f  tatic int echoRo
64b0: 6c 6c 62 61 63 6b 28 73 71 6c 69 74 65 33 5f 76  llback(sqlite3_v
64c0: 74 61 62 20 2a 74 61 62 29 7b 0a 20 20 72 65 74  tab *tab){.  ret
64d0: 75 72 6e 20 65 63 68 6f 54 72 61 6e 73 61 63 74  urn echoTransact
64e0: 69 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 52  ionCall(tab, "xR
64f0: 6f 6c 6c 62 61 63 6b 22 29 3b 0a 7d 0a 0a 2f 2a  ollback");.}../*
6500: 0a 2a 2a 20 41 20 76 69 72 74 75 61 6c 20 74 61  .** A virtual ta
6510: 62 6c 65 20 6d 6f 64 75 6c 65 20 74 68 61 74 20  ble module that 
6520: 6d 65 72 65 6c 79 20 22 65 63 68 6f 73 22 20 74  merely "echos" t
6530: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61  he contents of a
6540: 6e 6f 74 68 65 72 0a 2a 2a 20 74 61 62 6c 65 20  nother.** table 
6550: 28 6c 69 6b 65 20 61 6e 20 53 51 4c 20 56 49 45  (like an SQL VIE
6560: 57 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71  W)..*/.static sq
6570: 6c 69 74 65 33 5f 6d 6f 64 75 6c 65 20 65 63 68  lite3_module ech
6580: 6f 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20 20 30 2c  oModule = {.  0,
6590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
65a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72           /* iVer
65b0: 73 69 6f 6e 20 2a 2f 0a 20 20 22 65 63 68 6f 22  sion */.  "echo"
65c0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
65d0: 20 20 20 20 20 2f 2a 20 7a 4e 61 6d 65 20 2a 2f       /* zName */
65e0: 0a 20 20 65 63 68 6f 43 72 65 61 74 65 2c 0a 20  .  echoCreate,. 
65f0: 20 65 63 68 6f 43 6f 6e 6e 65 63 74 2c 0a 20 20   echoConnect,.  
6600: 65 63 68 6f 42 65 73 74 49 6e 64 65 78 2c 0a 20  echoBestIndex,. 
6610: 20 65 63 68 6f 44 69 73 63 6f 6e 6e 65 63 74 2c   echoDisconnect,
6620: 20 0a 20 20 65 63 68 6f 44 65 73 74 72 6f 79 2c   .  echoDestroy,
6630: 0a 20 20 65 63 68 6f 4f 70 65 6e 2c 20 20 20 20  .  echoOpen,    
6640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6650: 20 78 4f 70 65 6e 20 2d 20 6f 70 65 6e 20 61 20   xOpen - open a 
6660: 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63 68 6f  cursor */.  echo
6670: 43 6c 6f 73 65 2c 20 20 20 20 20 20 20 20 20 20  Close,          
6680: 20 20 20 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65         /* xClose
6690: 20 2d 20 63 6c 6f 73 65 20 61 20 63 75 72 73 6f   - close a curso
66a0: 72 20 2a 2f 0a 20 20 65 63 68 6f 46 69 6c 74 65  r */.  echoFilte
66b0: 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r,              
66c0: 20 20 2f 2a 20 78 46 69 6c 74 65 72 20 2d 20 63    /* xFilter - c
66d0: 6f 6e 66 69 67 75 72 65 20 73 63 61 6e 20 63 6f  onfigure scan co
66e0: 6e 73 74 72 61 69 6e 74 73 20 2a 2f 0a 20 20 65  nstraints */.  e
66f0: 63 68 6f 4e 65 78 74 2c 20 20 20 20 20 20 20 20  choNext,        
6700: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4e 65            /* xNe
6710: 78 74 20 2d 20 61 64 76 61 6e 63 65 20 61 20 63  xt - advance a c
6720: 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63 68 6f 45  ursor */.  echoE
6730: 6f 66 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  of,             
6740: 20 20 20 20 20 20 2f 2a 20 78 45 6f 66 20 2a 2f        /* xEof */
6750: 0a 20 20 65 63 68 6f 43 6f 6c 75 6d 6e 2c 20 20  .  echoColumn,  
6760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6770: 20 78 43 6f 6c 75 6d 6e 20 2d 20 72 65 61 64 20   xColumn - read 
6780: 64 61 74 61 20 2a 2f 0a 20 20 65 63 68 6f 52 6f  data */.  echoRo
6790: 77 69 64 2c 20 20 20 20 20 20 20 20 20 20 20 20  wid,            
67a0: 20 20 20 20 20 2f 2a 20 78 52 6f 77 69 64 20 2d       /* xRowid -
67b0: 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20   read data */.  
67c0: 65 63 68 6f 55 70 64 61 74 65 2c 20 20 20 20 20  echoUpdate,     
67d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55             /* xU
67e0: 70 64 61 74 65 20 2d 20 77 72 69 74 65 20 64 61  pdate - write da
67f0: 74 61 20 2a 2f 0a 20 20 65 63 68 6f 42 65 67 69  ta */.  echoBegi
6800: 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n,              
6810: 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 2d 20 62     /* xBegin - b
6820: 65 67 69 6e 20 74 72 61 6e 73 61 63 74 69 6f 6e  egin transaction
6830: 20 2a 2f 0a 20 20 65 63 68 6f 53 79 6e 63 2c 20   */.  echoSync, 
6840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6850: 20 2f 2a 20 78 53 79 6e 63 20 2d 20 73 79 6e 63   /* xSync - sync
6860: 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a   transaction */.
6870: 20 20 65 63 68 6f 43 6f 6d 6d 69 74 2c 20 20 20    echoCommit,   
6880: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6890: 78 43 6f 6d 6d 69 74 20 2d 20 63 6f 6d 6d 69 74  xCommit - commit
68a0: 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a   transaction */.
68b0: 20 20 65 63 68 6f 52 6f 6c 6c 62 61 63 6b 20 20    echoRollback  
68c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
68d0: 78 52 6f 6c 6c 62 61 63 6b 20 2d 20 72 6f 6c 6c  xRollback - roll
68e0: 62 61 63 6b 20 74 72 61 6e 73 61 63 74 69 6f 6e  back transaction
68f0: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65   */.};../*.** De
6900: 63 6f 64 65 20 61 20 70 6f 69 6e 74 65 72 20 74  code a pointer t
6910: 6f 20 61 6e 20 73 71 6c 69 74 65 33 20 6f 62 6a  o an sqlite3 obj
6920: 65 63 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ect..*/.static i
6930: 6e 74 20 67 65 74 44 62 50 6f 69 6e 74 65 72 28  nt getDbPointer(
6940: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
6950: 72 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  rp, const char *
6960: 7a 41 2c 20 73 71 6c 69 74 65 33 20 2a 2a 70 70  zA, sqlite3 **pp
6970: 44 62 29 7b 0a 20 20 2a 70 70 44 62 20 3d 20 28  Db){.  *ppDb = (
6980: 73 71 6c 69 74 65 33 2a 29 73 71 6c 69 74 65 33  sqlite3*)sqlite3
6990: 54 65 78 74 54 6f 50 74 72 28 7a 41 29 3b 0a 20  TextToPtr(zA);. 
69a0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a   return TCL_OK;.
69b0: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65  }../*.** Registe
69c0: 72 20 74 68 65 20 65 63 68 6f 20 76 69 72 74 75  r the echo virtu
69d0: 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 2e  al table module.
69e0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 72  .*/.static int r
69f0: 65 67 69 73 74 65 72 5f 65 63 68 6f 5f 6d 6f 64  egister_echo_mod
6a00: 75 6c 65 28 0a 20 20 43 6c 69 65 6e 74 44 61 74  ule(.  ClientDat
6a10: 61 20 63 6c 69 65 6e 74 44 61 74 61 2c 20 2f 2a  a clientData, /*
6a20: 20 50 6f 69 6e 74 65 72 20 74 6f 20 73 71 6c 69   Pointer to sqli
6a30: 74 65 33 5f 65 6e 61 62 6c 65 5f 58 58 58 20 66  te3_enable_XXX f
6a40: 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 54 63 6c  unction */.  Tcl
6a50: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
6a60: 20 20 20 20 2f 2a 20 54 68 65 20 54 43 4c 20 69      /* The TCL i
6a70: 6e 74 65 72 70 72 65 74 65 72 20 74 68 61 74 20  nterpreter that 
6a80: 69 6e 76 6f 6b 65 64 20 74 68 69 73 20 63 6f 6d  invoked this com
6a90: 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e 74 20 6f 62  mand */.  int ob
6aa0: 6a 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  jc,             
6ab0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72   /* Number of ar
6ac0: 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 54 63 6c  guments */.  Tcl
6ad0: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
6ae0: 5b 5d 20 20 2f 2a 20 43 6f 6d 6d 61 6e 64 20 61  []  /* Command a
6af0: 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 29 7b 0a 20  rguments */.){. 
6b00: 20 73 71 6c 69 74 65 33 20 2a 64 62 3b 0a 20 20   sqlite3 *db;.  
6b10: 69 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20  if( objc!=2 ){. 
6b20: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
6b30: 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f  rgs(interp, 1, o
6b40: 62 6a 76 2c 20 22 44 42 22 29 3b 0a 20 20 20 20  bjv, "DB");.    
6b50: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
6b60: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 67 65 74 44  ;.  }.  if( getD
6b70: 62 50 6f 69 6e 74 65 72 28 69 6e 74 65 72 70 2c  bPointer(interp,
6b80: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f   Tcl_GetString(o
6b90: 62 6a 76 5b 31 5d 29 2c 20 26 64 62 29 20 29 20  bjv[1]), &db) ) 
6ba0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
6bb0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 63 72 65 61  ;.  sqlite3_crea
6bc0: 74 65 5f 6d 6f 64 75 6c 65 28 64 62 2c 20 22 65  te_module(db, "e
6bd0: 63 68 6f 22 2c 20 26 65 63 68 6f 4d 6f 64 75 6c  cho", &echoModul
6be0: 65 2c 20 28 76 6f 69 64 20 2a 29 69 6e 74 65 72  e, (void *)inter
6bf0: 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c  p);.  return TCL
6c00: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 63  _OK;.}../*.** Tc
6c10: 6c 20 69 6e 74 65 72 66 61 63 65 20 74 6f 20 73  l interface to s
6c20: 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76  qlite3_declare_v
6c30: 74 61 62 2c 20 69 6e 76 6f 6b 65 64 20 61 73 20  tab, invoked as 
6c40: 66 6f 6c 6c 6f 77 73 20 66 72 6f 6d 20 54 63 6c  follows from Tcl
6c50: 3a 0a 2a 2a 0a 2a 2a 20 73 71 6c 69 74 65 33 5f  :.**.** sqlite3_
6c60: 64 65 63 6c 61 72 65 5f 76 74 61 62 20 44 42 20  declare_vtab DB 
6c70: 53 51 4c 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  SQL.*/.static in
6c80: 74 20 64 65 63 6c 61 72 65 5f 76 74 61 62 28 0a  t declare_vtab(.
6c90: 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63 6c 69    ClientData cli
6ca0: 65 6e 74 44 61 74 61 2c 20 2f 2a 20 50 6f 69 6e  entData, /* Poin
6cb0: 74 65 72 20 74 6f 20 73 71 6c 69 74 65 33 5f 65  ter to sqlite3_e
6cc0: 6e 61 62 6c 65 5f 58 58 58 20 66 75 6e 63 74 69  nable_XXX functi
6cd0: 6f 6e 20 2a 2f 0a 20 20 54 63 6c 5f 49 6e 74 65  on */.  Tcl_Inte
6ce0: 72 70 20 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f  rp *interp,    /
6cf0: 2a 20 54 68 65 20 54 43 4c 20 69 6e 74 65 72 70  * The TCL interp
6d00: 72 65 74 65 72 20 74 68 61 74 20 69 6e 76 6f 6b  reter that invok
6d10: 65 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20  ed this command 
6d20: 2a 2f 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 20 20  */.  int objc,  
6d30: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
6d40: 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65 6e  umber of argumen
6d50: 74 73 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20  ts */.  Tcl_Obj 
6d60: 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 20 20 2f  *CONST objv[]  /
6d70: 2a 20 43 6f 6d 6d 61 6e 64 20 61 72 67 75 6d 65  * Command argume
6d80: 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69  nts */.){.  sqli
6d90: 74 65 33 20 2a 64 62 3b 0a 20 20 69 6e 74 20 72  te3 *db;.  int r
6da0: 63 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 33  c;.  if( objc!=3
6db0: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e   ){.    Tcl_Wron
6dc0: 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c  gNumArgs(interp,
6dd0: 20 31 2c 20 6f 62 6a 76 2c 20 22 44 42 20 53 51   1, objv, "DB SQ
6de0: 4c 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  L");.    return 
6df0: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20  TCL_ERROR;.  }. 
6e00: 20 69 66 28 20 67 65 74 44 62 50 6f 69 6e 74 65   if( getDbPointe
6e10: 72 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65  r(interp, Tcl_Ge
6e20: 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29  tString(objv[1])
6e30: 2c 20 26 64 62 29 20 29 20 72 65 74 75 72 6e 20  , &db) ) return 
6e40: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 72 63 20  TCL_ERROR;.  rc 
6e50: 3d 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72  = sqlite3_declar
6e60: 65 5f 76 74 61 62 28 64 62 2c 20 54 63 6c 5f 47  e_vtab(db, Tcl_G
6e70: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d  etString(objv[2]
6e80: 29 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  ));.  if( rc!=SQ
6e90: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 54  LITE_OK ){.    T
6ea0: 63 6c 5f 53 65 74 52 65 73 75 6c 74 28 69 6e 74  cl_SetResult(int
6eb0: 65 72 70 2c 20 73 71 6c 69 74 65 33 5f 65 72 72  erp, sqlite3_err
6ec0: 6d 73 67 28 64 62 29 2c 20 54 43 4c 5f 56 4f 4c  msg(db), TCL_VOL
6ed0: 41 54 49 4c 45 29 3b 0a 20 20 20 20 72 65 74 75  ATILE);.    retu
6ee0: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
6ef0: 7d 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f  }.  return TCL_O
6f00: 4b 3b 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20  K;.}..#endif /* 
6f10: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d  ifndef SQLITE_OM
6f20: 49 54 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 20  IT_VIRTUALTABLE 
6f30: 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74  */../*.** Regist
6f40: 65 72 20 63 6f 6d 6d 61 6e 64 73 20 77 69 74 68  er commands with
6f50: 20 74 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72   the TCL interpr
6f60: 65 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20 53 71 6c  eter..*/.int Sql
6f70: 69 74 65 74 65 73 74 38 5f 49 6e 69 74 28 54 63  itetest8_Init(Tc
6f80: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
6f90: 29 7b 0a 20 20 73 74 61 74 69 63 20 73 74 72 75  ){.  static stru
6fa0: 63 74 20 7b 0a 20 20 20 20 20 63 68 61 72 20 2a  ct {.     char *
6fb0: 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 54 63 6c 5f  zName;.     Tcl_
6fc0: 4f 62 6a 43 6d 64 50 72 6f 63 20 2a 78 50 72 6f  ObjCmdProc *xPro
6fd0: 63 3b 0a 20 20 20 20 20 76 6f 69 64 20 2a 63 6c  c;.     void *cl
6fe0: 69 65 6e 74 44 61 74 61 3b 0a 20 20 7d 20 61 4f  ientData;.  } aO
6ff0: 62 6a 43 6d 64 5b 5d 20 3d 20 7b 0a 23 69 66 6e  bjCmd[] = {.#ifn
7000: 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f  def SQLITE_OMIT_
7010: 56 49 52 54 55 41 4c 54 41 42 4c 45 0a 20 20 20  VIRTUALTABLE.   
7020: 20 20 7b 20 22 72 65 67 69 73 74 65 72 5f 65 63    { "register_ec
7030: 68 6f 5f 6d 6f 64 75 6c 65 22 2c 20 20 20 72 65  ho_module",   re
7040: 67 69 73 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75  gister_echo_modu
7050: 6c 65 2c 20 30 20 7d 2c 0a 20 20 20 20 20 7b 20  le, 0 },.     { 
7060: 22 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65  "sqlite3_declare
7070: 5f 76 74 61 62 22 2c 20 20 20 64 65 63 6c 61 72  _vtab",   declar
7080: 65 5f 76 74 61 62 2c 20 30 20 7d 2c 0a 23 65 6e  e_vtab, 0 },.#en
7090: 64 69 66 0a 20 20 7d 3b 0a 20 20 69 6e 74 20 69  dif.  };.  int i
70a0: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 73  ;.  for(i=0; i<s
70b0: 69 7a 65 6f 66 28 61 4f 62 6a 43 6d 64 29 2f 73  izeof(aObjCmd)/s
70c0: 69 7a 65 6f 66 28 61 4f 62 6a 43 6d 64 5b 30 5d  izeof(aObjCmd[0]
70d0: 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 54 63 6c  ); i++){.    Tcl
70e0: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e  _CreateObjComman
70f0: 64 28 69 6e 74 65 72 70 2c 20 61 4f 62 6a 43 6d  d(interp, aObjCm
7100: 64 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 0a 20 20 20  d[i].zName, .   
7110: 20 20 20 20 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e       aObjCmd[i].
7120: 78 50 72 6f 63 2c 20 61 4f 62 6a 43 6d 64 5b 69  xProc, aObjCmd[i
7130: 5d 2e 63 6c 69 65 6e 74 44 61 74 61 2c 20 30 29  ].clientData, 0)
7140: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 54  ;.  }.  return T
7150: 43 4c 5f 4f 4b 3b 0a 7d 0a                       CL_OK;.}.