/ Hex Artifact Content
Login

Artifact d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72:


0000: 2f 2a 0a 2a 2a 20 32 30 31 37 20 41 70 72 69 6c  /*.** 2017 April
0010: 20 30 37 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75   07.**.** The au
0020: 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63  thor disclaims c
0030: 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68 69 73  opyright to this
0040: 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49   source code.  I
0050: 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20  n place of.** a 
0060: 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65  legal notice, he
0070: 72 65 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67  re is a blessing
0080: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79  :.**.**    May y
0090: 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e  ou do good and n
00a0: 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d  ot evil..**    M
00b0: 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67  ay you find forg
00c0: 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72  iveness for your
00d0: 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65  self and forgive
00e0: 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d   others..**    M
00f0: 61 79 20 79 6f 75 20 73 68 61 72 65 20 66 72 65  ay you share fre
0100: 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e  ely, never takin
0110: 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20  g more than you 
0120: 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a  give..**.*******
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 2a 0a 2a 2f 0a 0a 23 69 66 20 64 65 66 69 6e  **.*/..#if defin
0180: 65 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29 0a  ed(SQLITE_TEST).
0190: 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74  .#include "sqlit
01a0: 65 33 65 78 70 65 72 74 2e 68 22 0a 23 69 6e 63  e3expert.h".#inc
01b0: 6c 75 64 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a  lude <assert.h>.
01c0: 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67  #include <string
01d0: 2e 68 3e 0a 0a 23 69 66 20 64 65 66 69 6e 65 64  .h>..#if defined
01e0: 28 49 4e 43 4c 55 44 45 5f 53 51 4c 49 54 45 5f  (INCLUDE_SQLITE_
01f0: 54 43 4c 5f 48 29 0a 23 20 20 69 6e 63 6c 75 64  TCL_H).#  includ
0200: 65 20 22 73 71 6c 69 74 65 5f 74 63 6c 2e 68 22  e "sqlite_tcl.h"
0210: 0a 23 65 6c 73 65 0a 23 20 20 69 6e 63 6c 75 64  .#else.#  includ
0220: 65 20 22 74 63 6c 2e 68 22 0a 23 20 20 69 66 6e  e "tcl.h".#  ifn
0230: 64 65 66 20 53 51 4c 49 54 45 5f 54 43 4c 41 50  def SQLITE_TCLAP
0240: 49 0a 23 20 20 20 20 64 65 66 69 6e 65 20 53 51  I.#    define SQ
0250: 4c 49 54 45 5f 54 43 4c 41 50 49 0a 23 20 20 65  LITE_TCLAPI.#  e
0260: 6e 64 69 66 0a 23 65 6e 64 69 66 0a 0a 23 69 66  ndif.#endif..#if
0270: 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
0280: 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 0a 0a 2f  _VIRTUALTABLE../
0290: 2a 0a 2a 2a 20 45 78 74 72 61 63 74 20 61 6e 20  *.** Extract an 
02a0: 73 71 6c 69 74 65 33 2a 20 64 62 20 68 61 6e 64  sqlite3* db hand
02b0: 6c 65 20 66 72 6f 6d 20 74 68 65 20 6f 62 6a 65  le from the obje
02c0: 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68 65  ct passed as the
02d0: 20 73 65 63 6f 6e 64 0a 2a 2a 20 61 72 67 75 6d   second.** argum
02e0: 65 6e 74 2e 20 49 66 20 73 75 63 63 65 73 73 66  ent. If successf
02f0: 75 6c 2c 20 73 65 74 20 2a 70 44 62 20 74 6f 20  ul, set *pDb to 
0300: 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 64 62 20  point to the db 
0310: 68 61 6e 64 6c 65 20 61 6e 64 20 72 65 74 75 72  handle and retur
0320: 6e 0a 2a 2a 20 54 43 4c 5f 4f 4b 2e 20 4f 74 68  n.** TCL_OK. Oth
0330: 65 72 77 69 73 65 2c 20 72 65 74 75 72 6e 20 54  erwise, return T
0340: 43 4c 5f 45 52 52 4f 52 2e 0a 2a 2f 0a 73 74 61  CL_ERROR..*/.sta
0350: 74 69 63 20 69 6e 74 20 64 62 48 61 6e 64 6c 65  tic int dbHandle
0360: 46 72 6f 6d 4f 62 6a 28 54 63 6c 5f 49 6e 74 65  FromObj(Tcl_Inte
0370: 72 70 20 2a 69 6e 74 65 72 70 2c 20 54 63 6c 5f  rp *interp, Tcl_
0380: 4f 62 6a 20 2a 70 4f 62 6a 2c 20 73 71 6c 69 74  Obj *pObj, sqlit
0390: 65 33 20 2a 2a 70 44 62 29 7b 0a 20 20 54 63 6c  e3 **pDb){.  Tcl
03a0: 5f 43 6d 64 49 6e 66 6f 20 69 6e 66 6f 3b 0a 20  _CmdInfo info;. 
03b0: 20 69 66 28 20 30 3d 3d 54 63 6c 5f 47 65 74 43   if( 0==Tcl_GetC
03c0: 6f 6d 6d 61 6e 64 49 6e 66 6f 28 69 6e 74 65 72  ommandInfo(inter
03d0: 70 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  p, Tcl_GetString
03e0: 28 70 4f 62 6a 29 2c 20 26 69 6e 66 6f 29 20 29  (pObj), &info) )
03f0: 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64  {.    Tcl_Append
0400: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22  Result(interp, "
0410: 6e 6f 20 73 75 63 68 20 68 61 6e 64 6c 65 3a 20  no such handle: 
0420: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
0430: 28 70 4f 62 6a 29 2c 20 30 29 3b 0a 20 20 20 20  (pObj), 0);.    
0440: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
0450: 3b 0a 20 20 7d 0a 0a 20 20 2a 70 44 62 20 3d 20  ;.  }..  *pDb = 
0460: 2a 28 73 71 6c 69 74 65 33 20 2a 2a 29 69 6e 66  *(sqlite3 **)inf
0470: 6f 2e 6f 62 6a 43 6c 69 65 6e 74 44 61 74 61 3b  o.objClientData;
0480: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
0490: 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 54 63 6c 63  ;.}.../*.** Tclc
04a0: 6d 64 3a 20 20 24 65 78 70 65 72 74 20 73 71 6c  md:  $expert sql
04b0: 20 53 51 4c 0a 2a 2a 20 20 20 20 20 20 20 20 20   SQL.**         
04c0: 20 24 65 78 70 65 72 74 20 61 6e 61 6c 79 7a 65   $expert analyze
04d0: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 24 65 78  .**          $ex
04e0: 70 65 72 74 20 63 6f 75 6e 74 0a 2a 2a 20 20 20  pert count.**   
04f0: 20 20 20 20 20 20 20 24 65 78 70 65 72 74 20 72         $expert r
0500: 65 70 6f 72 74 20 53 54 4d 54 20 45 52 45 50 4f  eport STMT EREPO
0510: 52 54 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 24  RT.**          $
0520: 65 78 70 65 72 74 20 64 65 73 74 72 6f 79 0a 2a  expert destroy.*
0530: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 53 51 4c  /.static int SQL
0540: 49 54 45 5f 54 43 4c 41 50 49 20 74 65 73 74 45  ITE_TCLAPI testE
0550: 78 70 65 72 74 43 6d 64 28 0a 20 20 76 6f 69 64  xpertCmd(.  void
0560: 20 2a 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20   *clientData,.  
0570: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
0580: 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a  rp,.  int objc,.
0590: 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54    Tcl_Obj *CONST
05a0: 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 73 71 6c   objv[].){.  sql
05b0: 69 74 65 33 65 78 70 65 72 74 20 2a 70 45 78 70  ite3expert *pExp
05c0: 65 72 74 20 3d 20 28 73 71 6c 69 74 65 33 65 78  ert = (sqlite3ex
05d0: 70 65 72 74 2a 29 63 6c 69 65 6e 74 44 61 74 61  pert*)clientData
05e0: 3b 0a 20 20 73 74 72 75 63 74 20 53 75 62 63 6d  ;.  struct Subcm
05f0: 64 20 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68  d {.    const ch
0600: 61 72 20 2a 7a 53 75 62 3b 0a 20 20 20 20 69 6e  ar *zSub;.    in
0610: 74 20 6e 41 72 67 3b 0a 20 20 20 20 63 6f 6e 73  t nArg;.    cons
0620: 74 20 63 68 61 72 20 2a 7a 4d 73 67 3b 0a 20 20  t char *zMsg;.  
0630: 7d 20 61 53 75 62 5b 5d 20 3d 20 7b 0a 20 20 20  } aSub[] = {.   
0640: 20 7b 20 22 73 71 6c 22 2c 20 20 20 20 20 20 20   { "sql",       
0650: 31 2c 20 22 54 41 42 4c 45 22 2c 20 20 20 20 20  1, "TABLE",     
0660: 20 20 20 7d 2c 20 2f 2a 20 30 20 2a 2f 0a 20 20     }, /* 0 */.  
0670: 20 20 7b 20 22 61 6e 61 6c 79 7a 65 22 2c 20 20    { "analyze",  
0680: 20 30 2c 20 22 22 2c 20 20 20 20 20 20 20 20 20   0, "",         
0690: 20 20 20 20 7d 2c 20 2f 2a 20 31 20 2a 2f 0a 20      }, /* 1 */. 
06a0: 20 20 20 7b 20 22 63 6f 75 6e 74 22 2c 20 20 20     { "count",   
06b0: 20 20 30 2c 20 22 22 2c 20 20 20 20 20 20 20 20    0, "",        
06c0: 20 20 20 20 20 7d 2c 20 2f 2a 20 32 20 2a 2f 0a       }, /* 2 */.
06d0: 20 20 20 20 7b 20 22 72 65 70 6f 72 74 22 2c 20      { "report", 
06e0: 20 20 20 32 2c 20 22 53 54 4d 54 20 45 52 45 50     2, "STMT EREP
06f0: 4f 52 54 22 2c 20 7d 2c 20 2f 2a 20 33 20 2a 2f  ORT", }, /* 3 */
0700: 0a 20 20 20 20 7b 20 22 64 65 73 74 72 6f 79 22  .    { "destroy"
0710: 2c 20 20 20 30 2c 20 22 22 2c 20 20 20 20 20 20  ,   0, "",      
0720: 20 20 20 20 20 20 20 7d 2c 20 2f 2a 20 34 20 2a         }, /* 4 *
0730: 2f 0a 20 20 20 20 7b 20 30 20 7d 0a 20 20 7d 3b  /.    { 0 }.  };
0740: 0a 20 20 69 6e 74 20 69 53 75 62 3b 0a 20 20 69  .  int iSub;.  i
0750: 6e 74 20 72 63 20 3d 20 54 43 4c 5f 4f 4b 3b 0a  nt rc = TCL_OK;.
0760: 20 20 63 68 61 72 20 2a 7a 45 72 72 20 3d 20 30    char *zErr = 0
0770: 3b 0a 0a 20 20 69 66 28 20 6f 62 6a 63 3c 32 20  ;..  if( objc<2 
0780: 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67  ){.    Tcl_Wrong
0790: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
07a0: 31 2c 20 6f 62 6a 76 2c 20 22 53 55 42 43 4f 4d  1, objv, "SUBCOM
07b0: 4d 41 4e 44 20 2e 2e 2e 22 29 3b 0a 20 20 20 20  MAND ...");.    
07c0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
07d0: 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 54 63 6c  ;.  }.  rc = Tcl
07e0: 5f 47 65 74 49 6e 64 65 78 46 72 6f 6d 4f 62 6a  _GetIndexFromObj
07f0: 53 74 72 75 63 74 28 69 6e 74 65 72 70 2c 20 0a  Struct(interp, .
0800: 20 20 20 20 20 20 6f 62 6a 76 5b 31 5d 2c 20 61        objv[1], a
0810: 53 75 62 2c 20 73 69 7a 65 6f 66 28 61 53 75 62  Sub, sizeof(aSub
0820: 5b 30 5d 29 2c 20 22 73 75 62 2d 63 6f 6d 6d 61  [0]), "sub-comma
0830: 6e 64 22 2c 20 30 2c 20 26 69 53 75 62 0a 20 20  nd", 0, &iSub.  
0840: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 54 43 4c  );.  if( rc!=TCL
0850: 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
0860: 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 32 2b 61  .  if( objc!=2+a
0870: 53 75 62 5b 69 53 75 62 5d 2e 6e 41 72 67 20 29  Sub[iSub].nArg )
0880: 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e  {.    Tcl_WrongN
0890: 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 32  umArgs(interp, 2
08a0: 2c 20 6f 62 6a 76 2c 20 61 53 75 62 5b 69 53 75  , objv, aSub[iSu
08b0: 62 5d 2e 7a 4d 73 67 29 3b 0a 20 20 20 20 72 65  b].zMsg);.    re
08c0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
08d0: 20 20 7d 0a 0a 20 20 73 77 69 74 63 68 28 20 69    }..  switch( i
08e0: 53 75 62 20 29 7b 0a 20 20 20 20 63 61 73 65 20  Sub ){.    case 
08f0: 30 3a 20 7b 20 20 20 20 20 20 2f 2a 20 73 71 6c  0: {      /* sql
0900: 20 2a 2f 0a 20 20 20 20 20 20 63 68 61 72 20 2a   */.      char *
0910: 7a 41 72 67 20 3d 20 54 63 6c 5f 47 65 74 53 74  zArg = Tcl_GetSt
0920: 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 3b 0a 20  ring(objv[2]);. 
0930: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
0940: 33 5f 65 78 70 65 72 74 5f 73 71 6c 28 70 45 78  3_expert_sql(pEx
0950: 70 65 72 74 2c 20 7a 41 72 67 2c 20 26 7a 45 72  pert, zArg, &zEr
0960: 72 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  r);.      break;
0970: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65  .    }..    case
0980: 20 31 3a 20 7b 20 20 20 20 20 20 2f 2a 20 61 6e   1: {      /* an
0990: 61 6c 79 7a 65 20 2a 2f 0a 20 20 20 20 20 20 72  alyze */.      r
09a0: 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 70 65  c = sqlite3_expe
09b0: 72 74 5f 61 6e 61 6c 79 7a 65 28 70 45 78 70 65  rt_analyze(pExpe
09c0: 72 74 2c 20 26 7a 45 72 72 29 3b 0a 20 20 20 20  rt, &zErr);.    
09d0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a    break;.    }..
09e0: 20 20 20 20 63 61 73 65 20 32 3a 20 7b 20 20 20      case 2: {   
09f0: 20 20 20 2f 2a 20 63 6f 75 6e 74 20 2a 2f 0a 20     /* count */. 
0a00: 20 20 20 20 20 69 6e 74 20 6e 20 3d 20 73 71 6c       int n = sql
0a10: 69 74 65 33 5f 65 78 70 65 72 74 5f 63 6f 75 6e  ite3_expert_coun
0a20: 74 28 70 45 78 70 65 72 74 29 3b 0a 20 20 20 20  t(pExpert);.    
0a30: 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75    Tcl_SetObjResu
0a40: 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e  lt(interp, Tcl_N
0a50: 65 77 49 6e 74 4f 62 6a 28 6e 29 29 3b 0a 20 20  ewIntObj(n));.  
0a60: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d      break;.    }
0a70: 0a 0a 20 20 20 20 63 61 73 65 20 33 3a 20 7b 20  ..    case 3: { 
0a80: 20 20 20 20 20 2f 2a 20 72 65 70 6f 72 74 20 2a       /* report *
0a90: 2f 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68  /.      const ch
0aa0: 61 72 20 2a 61 45 6e 75 6d 5b 5d 20 3d 20 7b 0a  ar *aEnum[] = {.
0ab0: 20 20 20 20 20 20 20 20 22 73 71 6c 22 2c 20 22          "sql", "
0ac0: 69 6e 64 65 78 65 73 22 2c 20 22 70 6c 61 6e 22  indexes", "plan"
0ad0: 2c 20 22 63 61 6e 64 69 64 61 74 65 73 22 2c 20  , "candidates", 
0ae0: 30 0a 20 20 20 20 20 20 7d 3b 0a 20 20 20 20 20  0.      };.     
0af0: 20 69 6e 74 20 69 45 6e 75 6d 3b 0a 20 20 20 20   int iEnum;.    
0b00: 20 20 69 6e 74 20 69 53 74 6d 74 3b 0a 20 20 20    int iStmt;.   
0b10: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
0b20: 52 65 70 6f 72 74 3b 0a 0a 20 20 20 20 20 20 69  Report;..      i
0b30: 66 28 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f  f( Tcl_GetIntFro
0b40: 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a  mObj(interp, obj
0b50: 76 5b 32 5d 2c 20 26 69 53 74 6d 74 29 20 0a 20  v[2], &iStmt) . 
0b60: 20 20 20 20 20 20 7c 7c 20 54 63 6c 5f 47 65 74        || Tcl_Get
0b70: 49 6e 64 65 78 46 72 6f 6d 4f 62 6a 28 69 6e 74  IndexFromObj(int
0b80: 65 72 70 2c 20 6f 62 6a 76 5b 33 5d 2c 20 61 45  erp, objv[3], aE
0b90: 6e 75 6d 2c 20 22 72 65 70 6f 72 74 22 2c 20 30  num, "report", 0
0ba0: 2c 20 26 69 45 6e 75 6d 29 0a 20 20 20 20 20 20  , &iEnum).      
0bb0: 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ){.        retur
0bc0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20  n TCL_ERROR;.   
0bd0: 20 20 20 7d 0a 0a 20 20 20 20 20 20 61 73 73 65     }..      asse
0be0: 72 74 28 20 45 58 50 45 52 54 5f 52 45 50 4f 52  rt( EXPERT_REPOR
0bf0: 54 5f 53 51 4c 3d 3d 31 20 29 3b 0a 20 20 20 20  T_SQL==1 );.    
0c00: 20 20 61 73 73 65 72 74 28 20 45 58 50 45 52 54    assert( EXPERT
0c10: 5f 52 45 50 4f 52 54 5f 49 4e 44 45 58 45 53 3d  _REPORT_INDEXES=
0c20: 3d 32 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65  =2 );.      asse
0c30: 72 74 28 20 45 58 50 45 52 54 5f 52 45 50 4f 52  rt( EXPERT_REPOR
0c40: 54 5f 50 4c 41 4e 3d 3d 33 20 29 3b 0a 20 20 20  T_PLAN==3 );.   
0c50: 20 20 20 61 73 73 65 72 74 28 20 45 58 50 45 52     assert( EXPER
0c60: 54 5f 52 45 50 4f 52 54 5f 43 41 4e 44 49 44 41  T_REPORT_CANDIDA
0c70: 54 45 53 3d 3d 34 20 29 3b 0a 20 20 20 20 20 20  TES==4 );.      
0c80: 7a 52 65 70 6f 72 74 20 3d 20 73 71 6c 69 74 65  zReport = sqlite
0c90: 33 5f 65 78 70 65 72 74 5f 72 65 70 6f 72 74 28  3_expert_report(
0ca0: 70 45 78 70 65 72 74 2c 20 69 53 74 6d 74 2c 20  pExpert, iStmt, 
0cb0: 31 2b 69 45 6e 75 6d 29 3b 0a 20 20 20 20 20 20  1+iEnum);.      
0cc0: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
0cd0: 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77  (interp, Tcl_New
0ce0: 53 74 72 69 6e 67 4f 62 6a 28 7a 52 65 70 6f 72  StringObj(zRepor
0cf0: 74 2c 20 2d 31 29 29 3b 0a 20 20 20 20 20 20 62  t, -1));.      b
0d00: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  reak;.    }..   
0d10: 20 64 65 66 61 75 6c 74 3a 20 20 20 20 20 20 20   default:       
0d20: 2f 2a 20 64 65 73 74 72 6f 79 20 2a 2f 0a 20 20  /* destroy */.  
0d30: 20 20 20 20 61 73 73 65 72 74 28 20 69 53 75 62      assert( iSub
0d40: 3d 3d 34 20 29 3b 20 20 20 20 20 0a 20 20 20 20  ==4 );     .    
0d50: 20 20 54 63 6c 5f 44 65 6c 65 74 65 43 6f 6d 6d    Tcl_DeleteComm
0d60: 61 6e 64 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  and(interp, Tcl_
0d70: 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 30  GetString(objv[0
0d80: 5d 29 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b  ]));.      break
0d90: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 21  ;.  }..  if( rc!
0da0: 3d 54 43 4c 5f 4f 4b 20 29 7b 0a 20 20 20 20 69  =TCL_OK ){.    i
0db0: 66 28 20 7a 45 72 72 20 29 7b 0a 20 20 20 20 20  f( zErr ){.     
0dc0: 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c   Tcl_SetObjResul
0dd0: 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65  t(interp, Tcl_Ne
0de0: 77 53 74 72 69 6e 67 4f 62 6a 28 7a 45 72 72 2c  wStringObj(zErr,
0df0: 20 2d 31 29 29 3b 0a 20 20 20 20 7d 65 6c 73 65   -1));.    }else
0e00: 7b 0a 20 20 20 20 20 20 65 78 74 65 72 6e 20 63  {.      extern c
0e10: 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 69 74  onst char *sqlit
0e20: 65 33 45 72 72 4e 61 6d 65 28 69 6e 74 29 3b 0a  e3ErrName(int);.
0e30: 20 20 20 20 20 20 54 63 6c 5f 53 65 74 4f 62 6a        Tcl_SetObj
0e40: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54  Result(interp, T
0e50: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
0e60: 73 71 6c 69 74 65 33 45 72 72 4e 61 6d 65 28 72  sqlite3ErrName(r
0e70: 63 29 2c 20 2d 31 29 29 3b 0a 20 20 20 20 7d 0a  c), -1));.    }.
0e80: 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72    }.  sqlite3_fr
0e90: 65 65 28 7a 45 72 72 29 3b 0a 20 20 72 65 74 75  ee(zErr);.  retu
0ea0: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
0eb0: 20 76 6f 69 64 20 53 51 4c 49 54 45 5f 54 43 4c   void SQLITE_TCL
0ec0: 41 50 49 20 74 65 73 74 45 78 70 65 72 74 44 65  API testExpertDe
0ed0: 6c 28 76 6f 69 64 20 2a 63 6c 69 65 6e 74 44 61  l(void *clientDa
0ee0: 74 61 29 7b 0a 20 20 73 71 6c 69 74 65 33 65 78  ta){.  sqlite3ex
0ef0: 70 65 72 74 20 2a 70 45 78 70 65 72 74 20 3d 20  pert *pExpert = 
0f00: 28 73 71 6c 69 74 65 33 65 78 70 65 72 74 2a 29  (sqlite3expert*)
0f10: 63 6c 69 65 6e 74 44 61 74 61 3b 0a 20 20 73 71  clientData;.  sq
0f20: 6c 69 74 65 33 5f 65 78 70 65 72 74 5f 64 65 73  lite3_expert_des
0f30: 74 72 6f 79 28 70 45 78 70 65 72 74 29 3b 0a 7d  troy(pExpert);.}
0f40: 0a 0a 2f 2a 0a 2a 2a 20 73 71 6c 69 74 65 33 5f  ../*.** sqlite3_
0f50: 65 78 70 65 72 74 5f 6e 65 77 20 44 42 0a 2a 2f  expert_new DB.*/
0f60: 0a 73 74 61 74 69 63 20 69 6e 74 20 53 51 4c 49  .static int SQLI
0f70: 54 45 5f 54 43 4c 41 50 49 20 74 65 73 74 5f 73  TE_TCLAPI test_s
0f80: 71 6c 69 74 65 33 5f 65 78 70 65 72 74 5f 6e 65  qlite3_expert_ne
0f90: 77 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65  w(.  void * clie
0fa0: 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e  ntData,.  Tcl_In
0fb0: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20  terp *interp,.  
0fc0: 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f  int objc,.  Tcl_
0fd0: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
0fe0: 5d 0a 29 7b 0a 20 20 73 74 61 74 69 63 20 69 6e  ].){.  static in
0ff0: 74 20 69 43 6d 64 20 3d 20 30 3b 0a 20 20 73 71  t iCmd = 0;.  sq
1000: 6c 69 74 65 33 20 2a 64 62 3b 0a 20 20 63 68 61  lite3 *db;.  cha
1010: 72 20 2a 7a 43 6d 64 20 3d 20 30 3b 0a 20 20 63  r *zCmd = 0;.  c
1020: 68 61 72 20 2a 7a 45 72 72 20 3d 20 30 3b 0a 20  har *zErr = 0;. 
1030: 20 73 71 6c 69 74 65 33 65 78 70 65 72 74 20 2a   sqlite3expert *
1040: 70 45 78 70 65 72 74 3b 0a 20 20 69 6e 74 20 72  pExpert;.  int r
1050: 63 20 3d 20 54 43 4c 5f 4f 4b 3b 0a 0a 20 20 69  c = TCL_OK;..  i
1060: 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20  f( objc!=2 ){.  
1070: 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72    Tcl_WrongNumAr
1080: 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62  gs(interp, 1, ob
1090: 6a 76 2c 20 22 44 42 22 29 3b 0a 20 20 20 20 72  jv, "DB");.    r
10a0: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
10b0: 0a 20 20 7d 0a 20 20 69 66 28 20 64 62 48 61 6e  .  }.  if( dbHan
10c0: 64 6c 65 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72  dleFromObj(inter
10d0: 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26 64 62 29  p, objv[1], &db)
10e0: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 54   ){.    return T
10f0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20  CL_ERROR;.  }.. 
1100: 20 7a 43 6d 64 20 3d 20 73 71 6c 69 74 65 33 5f   zCmd = sqlite3_
1110: 6d 70 72 69 6e 74 66 28 22 73 71 6c 69 74 65 33  mprintf("sqlite3
1120: 65 78 70 65 72 74 25 64 22 2c 20 2b 2b 69 43 6d  expert%d", ++iCm
1130: 64 29 3b 0a 20 20 69 66 28 20 7a 43 6d 64 3d 3d  d);.  if( zCmd==
1140: 30 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70  0 ){.    Tcl_App
1150: 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70  endResult(interp
1160: 2c 20 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79  , "out of memory
1170: 22 2c 20 28 63 68 61 72 2a 29 30 29 3b 0a 20 20  ", (char*)0);.  
1180: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
1190: 4f 52 3b 0a 20 20 7d 0a 0a 20 20 70 45 78 70 65  OR;.  }..  pExpe
11a0: 72 74 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 70  rt = sqlite3_exp
11b0: 65 72 74 5f 6e 65 77 28 64 62 2c 20 26 7a 45 72  ert_new(db, &zEr
11c0: 72 29 3b 0a 20 20 69 66 28 20 70 45 78 70 65 72  r);.  if( pExper
11d0: 74 3d 3d 30 20 29 7b 0a 20 20 20 20 54 63 6c 5f  t==0 ){.    Tcl_
11e0: 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74  AppendResult(int
11f0: 65 72 70 2c 20 7a 45 72 72 2c 20 28 63 68 61 72  erp, zErr, (char
1200: 2a 29 30 29 3b 0a 20 20 20 20 72 63 20 3d 20 54  *)0);.    rc = T
1210: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 65 6c 73  CL_ERROR;.  }els
1220: 65 7b 0a 20 20 20 20 76 6f 69 64 20 2a 70 20 3d  e{.    void *p =
1230: 20 28 76 6f 69 64 2a 29 70 45 78 70 65 72 74 3b   (void*)pExpert;
1240: 0a 20 20 20 20 54 63 6c 5f 43 72 65 61 74 65 4f  .    Tcl_CreateO
1250: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
1260: 2c 20 7a 43 6d 64 2c 20 74 65 73 74 45 78 70 65  , zCmd, testExpe
1270: 72 74 43 6d 64 2c 20 70 2c 20 74 65 73 74 45 78  rtCmd, p, testEx
1280: 70 65 72 74 44 65 6c 29 3b 0a 20 20 20 20 54 63  pertDel);.    Tc
1290: 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69  l_SetObjResult(i
12a0: 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 53 74  nterp, Tcl_NewSt
12b0: 72 69 6e 67 4f 62 6a 28 7a 43 6d 64 2c 20 2d 31  ringObj(zCmd, -1
12c0: 29 29 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74  ));.  }..  sqlit
12d0: 65 33 5f 66 72 65 65 28 7a 43 6d 64 29 3b 0a 20  e3_free(zCmd);. 
12e0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 45   sqlite3_free(zE
12f0: 72 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  rr);.  return rc
1300: 3b 0a 7d 0a 0a 23 65 6e 64 69 66 20 20 2f 2a 20  ;.}..#endif  /* 
1310: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d  ifndef SQLITE_OM
1320: 49 54 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 20  IT_VIRTUALTABLE 
1330: 2a 2f 0a 0a 69 6e 74 20 54 65 73 74 45 78 70 65  */..int TestExpe
1340: 72 74 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65  rt_Init(Tcl_Inte
1350: 72 70 20 2a 69 6e 74 65 72 70 29 7b 0a 23 69 66  rp *interp){.#if
1360: 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
1370: 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 0a 20 20  _VIRTUALTABLE.  
1380: 73 74 72 75 63 74 20 43 6d 64 20 7b 0a 20 20 20  struct Cmd {.   
1390: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 6d   const char *zCm
13a0: 64 3b 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 43 6d  d;.    Tcl_ObjCm
13b0: 64 50 72 6f 63 20 2a 78 50 72 6f 63 3b 0a 20 20  dProc *xProc;.  
13c0: 7d 20 61 43 6d 64 5b 5d 20 3d 20 7b 0a 20 20 20  } aCmd[] = {.   
13d0: 20 7b 20 22 73 71 6c 69 74 65 33 5f 65 78 70 65   { "sqlite3_expe
13e0: 72 74 5f 6e 65 77 22 2c 20 74 65 73 74 5f 73 71  rt_new", test_sq
13f0: 6c 69 74 65 33 5f 65 78 70 65 72 74 5f 6e 65 77  lite3_expert_new
1400: 20 7d 2c 0a 20 20 7d 3b 0a 20 20 69 6e 74 20 69   },.  };.  int i
1410: 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  ;..  for(i=0; i<
1420: 73 69 7a 65 6f 66 28 61 43 6d 64 29 2f 73 69 7a  sizeof(aCmd)/siz
1430: 65 6f 66 28 73 74 72 75 63 74 20 43 6d 64 29 3b  eof(struct Cmd);
1440: 20 69 2b 2b 29 7b 0a 20 20 20 20 73 74 72 75 63   i++){.    struc
1450: 74 20 43 6d 64 20 2a 70 20 3d 20 26 61 43 6d 64  t Cmd *p = &aCmd
1460: 5b 69 5d 3b 0a 20 20 20 20 54 63 6c 5f 43 72 65  [i];.    Tcl_Cre
1470: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
1480: 74 65 72 70 2c 20 70 2d 3e 7a 43 6d 64 2c 20 70  terp, p->zCmd, p
1490: 2d 3e 78 50 72 6f 63 2c 20 30 2c 20 30 29 3b 0a  ->xProc, 0, 0);.
14a0: 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 72 65 74    }.#endif.  ret
14b0: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 23  urn TCL_OK;.}..#
14c0: 65 6e 64 69 66 0a                                endif.