/ Hex Artifact Content
Login

Artifact c73a0da702a2e9f5fd48046ab182683a73ee0318cefa3f45826536d015f39021:


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 0a 23 69 6e 63 6c 75 64 65  **.*/...#include
0180: 20 3c 73 71 6c 69 74 65 33 2e 68 3e 0a 23 69 6e   <sqlite3.h>.#in
0190: 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68 3e 0a  clude <stdio.h>.
01a0: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62  #include <stdlib
01b0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h>.#include <st
01c0: 72 69 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  ring.h>.#include
01d0: 20 22 73 71 6c 69 74 65 33 65 78 70 65 72 74 2e   "sqlite3expert.
01e0: 68 22 0a 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  h"...static void
01f0: 20 6f 70 74 69 6f 6e 5f 72 65 71 75 69 72 65 73   option_requires
0200: 5f 61 72 67 75 6d 65 6e 74 28 63 6f 6e 73 74 20  _argument(const 
0210: 63 68 61 72 20 2a 7a 4f 70 74 29 7b 0a 20 20 66  char *zOpt){.  f
0220: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
0230: 4f 70 74 69 6f 6e 20 72 65 71 75 69 72 65 73 20  Option requires 
0240: 61 6e 20 61 72 67 75 6d 65 6e 74 3a 20 25 73 5c  an argument: %s\
0250: 6e 22 2c 20 7a 4f 70 74 29 3b 0a 20 20 65 78 69  n", zOpt);.  exi
0260: 74 28 2d 33 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  t(-3);.}..static
0270: 20 76 6f 69 64 20 75 73 61 67 65 28 63 68 61 72   void usage(char
0280: 20 2a 2a 61 72 67 76 29 7b 0a 20 20 66 70 72 69   **argv){.  fpri
0290: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 5c 6e 22  ntf(stderr, "\n"
02a0: 29 3b 0a 20 20 66 70 72 69 6e 74 66 28 73 74 64  );.  fprintf(std
02b0: 65 72 72 2c 20 22 55 73 61 67 65 20 25 73 20 3f  err, "Usage %s ?
02c0: 4f 50 54 49 4f 4e 53 3f 20 44 41 54 41 42 41 53  OPTIONS? DATABAS
02d0: 45 5c 6e 22 2c 20 61 72 67 76 5b 30 5d 29 3b 0a  E\n", argv[0]);.
02e0: 20 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72    fprintf(stderr
02f0: 2c 20 22 5c 6e 22 29 3b 0a 20 20 66 70 72 69 6e  , "\n");.  fprin
0300: 74 66 28 73 74 64 65 72 72 2c 20 22 4f 70 74 69  tf(stderr, "Opti
0310: 6f 6e 73 20 61 72 65 3a 5c 6e 22 29 3b 0a 20 20  ons are:\n");.  
0320: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
0330: 22 20 20 2d 73 71 6c 20 53 51 4c 20 20 20 28 61  "  -sql SQL   (a
0340: 6e 61 6c 79 7a 65 20 53 51 4c 20 73 74 61 74 65  nalyze SQL state
0350: 6d 65 6e 74 73 20 70 61 73 73 65 64 20 61 73 20  ments passed as 
0360: 61 72 67 75 6d 65 6e 74 29 5c 6e 22 29 3b 0a 20  argument)\n");. 
0370: 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c   fprintf(stderr,
0380: 20 22 20 20 2d 66 69 6c 65 20 46 49 4c 45 20 28   "  -file FILE (
0390: 72 65 61 64 20 53 51 4c 20 73 74 61 74 65 6d 65  read SQL stateme
03a0: 6e 74 73 20 66 72 6f 6d 20 66 69 6c 65 20 46 49  nts from file FI
03b0: 4c 45 29 5c 6e 22 29 3b 0a 20 20 65 78 69 74 28  LE)\n");.  exit(
03c0: 2d 31 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  -1);.}..static i
03d0: 6e 74 20 72 65 61 64 53 71 6c 46 72 6f 6d 46 69  nt readSqlFromFi
03e0: 6c 65 28 73 71 6c 69 74 65 33 65 78 70 65 72 74  le(sqlite3expert
03f0: 20 2a 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20   *p, const char 
0400: 2a 7a 46 69 6c 65 2c 20 63 68 61 72 20 2a 2a 70  *zFile, char **p
0410: 7a 45 72 72 29 7b 0a 20 20 72 65 74 75 72 6e 20  zErr){.  return 
0420: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 69 6e  SQLITE_OK;.}..in
0430: 74 20 6d 61 69 6e 28 69 6e 74 20 61 72 67 63 2c  t main(int argc,
0440: 20 63 68 61 72 20 2a 2a 61 72 67 76 29 7b 0a 20   char **argv){. 
0450: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62   const char *zDb
0460: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 30 3b 0a  ;.  int rc = 0;.
0470: 20 20 63 68 61 72 20 2a 7a 45 72 72 20 3d 20 30    char *zErr = 0
0480: 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 73 71  ;.  int i;..  sq
0490: 6c 69 74 65 33 20 2a 64 62 20 3d 20 30 3b 0a 20  lite3 *db = 0;. 
04a0: 20 73 71 6c 69 74 65 33 65 78 70 65 72 74 20 2a   sqlite3expert *
04b0: 70 20 3d 20 30 3b 0a 0a 20 20 69 66 28 20 61 72  p = 0;..  if( ar
04c0: 67 63 3c 32 20 29 20 75 73 61 67 65 28 61 72 67  gc<2 ) usage(arg
04d0: 76 29 3b 0a 20 20 7a 44 62 20 3d 20 61 72 67 76  v);.  zDb = argv
04e0: 5b 61 72 67 63 2d 31 5d 3b 0a 20 20 72 63 20 3d  [argc-1];.  rc =
04f0: 20 73 71 6c 69 74 65 33 5f 6f 70 65 6e 28 7a 44   sqlite3_open(zD
0500: 62 2c 20 26 64 62 29 3b 0a 20 20 69 66 28 20 72  b, &db);.  if( r
0510: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
0520: 20 20 20 20 66 70 72 69 6e 74 66 28 73 74 64 65      fprintf(stde
0530: 72 72 2c 20 22 43 61 6e 6e 6f 74 20 6f 70 65 6e  rr, "Cannot open
0540: 20 64 62 20 66 69 6c 65 3a 20 25 73 20 2d 20 25   db file: %s - %
0550: 73 5c 6e 22 2c 20 7a 44 62 2c 20 73 71 6c 69 74  s\n", zDb, sqlit
0560: 65 33 5f 65 72 72 6d 73 67 28 64 62 29 29 3b 0a  e3_errmsg(db));.
0570: 20 20 20 20 65 78 69 74 28 2d 32 29 3b 0a 20 20      exit(-2);.  
0580: 7d 0a 0a 20 20 70 20 3d 20 73 71 6c 69 74 65 33  }..  p = sqlite3
0590: 5f 65 78 70 65 72 74 5f 6e 65 77 28 64 62 2c 20  _expert_new(db, 
05a0: 26 7a 45 72 72 29 3b 0a 20 20 69 66 28 20 70 3d  &zErr);.  if( p=
05b0: 3d 30 20 29 7b 0a 20 20 20 20 66 70 72 69 6e 74  =0 ){.    fprint
05c0: 66 28 73 74 64 65 72 72 2c 20 22 43 61 6e 6e 6f  f(stderr, "Canno
05d0: 74 20 72 75 6e 20 61 6e 61 6c 79 73 69 73 3a 20  t run analysis: 
05e0: 25 73 5c 6e 22 2c 20 7a 45 72 72 29 3b 0a 20 20  %s\n", zErr);.  
05f0: 20 20 72 63 20 3d 20 31 3b 0a 20 20 7d 65 6c 73    rc = 1;.  }els
0600: 65 7b 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b 20  e{.    for(i=1; 
0610: 69 3c 28 61 72 67 63 2d 31 29 3b 20 69 2b 2b 29  i<(argc-1); i++)
0620: 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 41  {.      char *zA
0630: 72 67 20 3d 20 61 72 67 76 5b 69 5d 3b 0a 20 20  rg = argv[i];.  
0640: 20 20 20 20 69 6e 74 20 6e 41 72 67 20 3d 20 73      int nArg = s
0650: 74 72 6c 65 6e 28 7a 41 72 67 29 3b 0a 20 20 20  trlen(zArg);.   
0660: 20 20 20 69 66 28 20 6e 41 72 67 3e 3d 32 20 26     if( nArg>=2 &
0670: 26 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72  & 0==sqlite3_str
0680: 6e 69 63 6d 70 28 7a 41 72 67 2c 20 22 2d 66 69  nicmp(zArg, "-fi
0690: 6c 65 22 2c 20 6e 41 72 67 29 20 29 7b 0a 20 20  le", nArg) ){.  
06a0: 20 20 20 20 20 20 69 66 28 20 2b 2b 69 3d 3d 28        if( ++i==(
06b0: 61 72 67 63 2d 31 29 20 29 20 6f 70 74 69 6f 6e  argc-1) ) option
06c0: 5f 72 65 71 75 69 72 65 73 5f 61 72 67 75 6d 65  _requires_argume
06d0: 6e 74 28 22 2d 66 69 6c 65 22 29 3b 0a 20 20 20  nt("-file");.   
06e0: 20 20 20 20 20 72 63 20 3d 20 72 65 61 64 53 71       rc = readSq
06f0: 6c 46 72 6f 6d 46 69 6c 65 28 70 2c 20 61 72 67  lFromFile(p, arg
0700: 76 5b 69 5d 2c 20 26 7a 45 72 72 29 3b 0a 20 20  v[i], &zErr);.  
0710: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 65 6c 73      }..      els
0720: 65 20 69 66 28 20 6e 41 72 67 3e 3d 32 20 26 26  e if( nArg>=2 &&
0730: 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 6e   0==sqlite3_strn
0740: 69 63 6d 70 28 7a 41 72 67 2c 20 22 2d 73 71 6c  icmp(zArg, "-sql
0750: 22 2c 20 6e 41 72 67 29 20 29 7b 0a 20 20 20 20  ", nArg) ){.    
0760: 20 20 20 20 69 66 28 20 2b 2b 69 3d 3d 28 61 72      if( ++i==(ar
0770: 67 63 2d 31 29 20 29 20 6f 70 74 69 6f 6e 5f 72  gc-1) ) option_r
0780: 65 71 75 69 72 65 73 5f 61 72 67 75 6d 65 6e 74  equires_argument
0790: 28 22 2d 73 71 6c 22 29 3b 0a 20 20 20 20 20 20  ("-sql");.      
07a0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65    rc = sqlite3_e
07b0: 78 70 65 72 74 5f 73 71 6c 28 70 2c 20 61 72 67  xpert_sql(p, arg
07c0: 76 5b 69 5d 2c 20 26 7a 45 72 72 29 3b 0a 20 20  v[i], &zErr);.  
07d0: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 65 6c 73      }..      els
07e0: 65 7b 0a 20 20 20 20 20 20 20 20 75 73 61 67 65  e{.        usage
07f0: 28 61 72 67 76 29 3b 0a 20 20 20 20 20 20 7d 0a  (argv);.      }.
0800: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28      }.  }..  if(
0810: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
0820: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
0830: 65 33 5f 65 78 70 65 72 74 5f 61 6e 61 6c 79 7a  e3_expert_analyz
0840: 65 28 70 2c 20 26 7a 45 72 72 29 3b 0a 20 20 7d  e(p, &zErr);.  }
0850: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
0860: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74  TE_OK ){.    int
0870: 20 6e 51 75 65 72 79 20 3d 20 73 71 6c 69 74 65   nQuery = sqlite
0880: 33 5f 65 78 70 65 72 74 5f 63 6f 75 6e 74 28 70  3_expert_count(p
0890: 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  );.    for(i=0; 
08a0: 69 3c 6e 51 75 65 72 79 3b 20 69 2b 2b 29 7b 0a  i<nQuery; i++){.
08b0: 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
08c0: 20 2a 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33   *zSql = sqlite3
08d0: 5f 65 78 70 65 72 74 5f 72 65 70 6f 72 74 28 70  _expert_report(p
08e0: 2c 20 69 2c 20 45 58 50 45 52 54 5f 52 45 50 4f  , i, EXPERT_REPO
08f0: 52 54 5f 53 51 4c 29 3b 0a 20 20 20 20 20 20 63  RT_SQL);.      c
0900: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 49 64 78 20  onst char *zIdx 
0910: 3d 20 73 71 6c 69 74 65 33 5f 65 78 70 65 72 74  = sqlite3_expert
0920: 5f 72 65 70 6f 72 74 28 70 2c 20 69 2c 20 45 58  _report(p, i, EX
0930: 50 45 52 54 5f 52 45 50 4f 52 54 5f 49 4e 44 45  PERT_REPORT_INDE
0940: 58 45 53 29 3b 0a 20 20 20 20 20 20 63 6f 6e 73  XES);.      cons
0950: 74 20 63 68 61 72 20 2a 7a 45 51 50 20 3d 20 73  t char *zEQP = s
0960: 71 6c 69 74 65 33 5f 65 78 70 65 72 74 5f 72 65  qlite3_expert_re
0970: 70 6f 72 74 28 70 2c 20 69 2c 20 45 58 50 45 52  port(p, i, EXPER
0980: 54 5f 52 45 50 4f 52 54 5f 50 4c 41 4e 29 3b 0a  T_REPORT_PLAN);.
0990: 20 20 20 20 20 20 66 70 72 69 6e 74 66 28 73 74        fprintf(st
09a0: 64 6f 75 74 2c 20 22 2d 2d 20 71 75 65 72 79 20  dout, "-- query 
09b0: 25 64 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  %d -------------
09c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
09d0: 2d 2d 2d 2d 2d 5c 6e 22 2c 20 69 2b 31 29 3b 0a  -----\n", i+1);.
09e0: 20 20 20 20 20 20 66 70 72 69 6e 74 66 28 73 74        fprintf(st
09f0: 64 6f 75 74 2c 20 22 25 73 5c 6e 5c 6e 25 73 5c  dout, "%s\n\n%s\
0a00: 6e 25 73 5c 6e 22 2c 20 7a 53 71 6c 2c 20 7a 49  n%s\n", zSql, zI
0a10: 64 78 2c 20 7a 45 51 50 29 3b 0a 20 20 20 20 7d  dx, zEQP);.    }
0a20: 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 7a 45 72  .  }else if( zEr
0a30: 72 20 29 7b 0a 20 20 20 20 66 70 72 69 6e 74 66  r ){.    fprintf
0a40: 28 73 74 64 65 72 72 2c 20 22 45 72 72 6f 72 3a  (stderr, "Error:
0a50: 20 25 73 5c 6e 22 2c 20 7a 45 72 72 29 3b 0a 20   %s\n", zErr);. 
0a60: 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f 65 78   }..  sqlite3_ex
0a70: 70 65 72 74 5f 64 65 73 74 72 6f 79 28 70 29 3b  pert_destroy(p);
0a80: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
0a90: 7a 45 72 72 29 3b 0a 20 20 72 65 74 75 72 6e 20  zErr);.  return 
0aa0: 72 63 3b 0a 7d 0a 0a 0a                          rc;.}...