/ Hex Artifact Content
Login

Artifact cc69e7fbc163f94da4a6400609be001543442d9f8f57a797d1eeb7b897585730:


0000: 23 20 54 68 69 73 20 54 43 4c 20 73 63 72 69 70  # This TCL scrip
0010: 74 20 69 73 20 74 68 65 20 6d 61 69 6e 20 64 72  t is the main dr
0020: 69 76 65 72 20 73 63 72 69 70 74 20 66 6f 72 20  iver script for 
0030: 74 68 65 20 73 71 6c 69 74 65 33 5f 63 68 65 63  the sqlite3_chec
0040: 6b 65 72 20 75 74 69 6c 69 74 79 0a 23 20 70 72  ker utility.# pr
0050: 6f 67 72 61 6d 2e 0a 23 0a 0a 23 20 53 70 65 63  ogram..#..# Spec
0060: 69 61 6c 20 63 61 73 65 3a 0a 23 0a 23 20 20 20  ial case:.#.#   
0070: 20 20 20 73 71 6c 69 74 65 33 5f 63 68 65 63 6b     sqlite3_check
0080: 65 72 20 2d 2d 74 65 73 74 20 46 49 4c 45 4e 41  er --test FILENA
0090: 4d 45 20 41 52 47 53 0a 23 0a 23 20 75 73 65 73  ME ARGS.#.# uses
00a0: 20 46 49 4c 45 4e 41 4d 45 20 69 6e 20 70 6c 61   FILENAME in pla
00b0: 63 65 20 6f 66 20 74 68 69 73 20 73 63 72 69 70  ce of this scrip
00c0: 74 2e 0a 23 0a 69 66 20 7b 5b 6c 69 6e 64 65 78  t..#.if {[lindex
00d0: 20 24 61 72 67 76 20 30 5d 3d 3d 22 2d 2d 74 65   $argv 0]=="--te
00e0: 73 74 22 20 26 26 20 5b 6c 6c 65 6e 67 74 68 20  st" && [llength 
00f0: 24 61 72 67 76 5d 3e 31 7d 20 7b 0a 20 20 73 65  $argv]>1} {.  se
0100: 74 20 3a 3a 61 72 67 76 30 20 5b 6c 69 6e 64 65  t ::argv0 [linde
0110: 78 20 24 61 72 67 76 20 31 5d 0a 20 20 73 65 74  x $argv 1].  set
0120: 20 61 72 67 76 20 5b 6c 72 61 6e 67 65 20 24 61   argv [lrange $a
0130: 72 67 76 20 32 20 65 6e 64 5d 0a 20 20 73 6f 75  rgv 2 end].  sou
0140: 72 63 65 20 24 61 72 67 76 30 0a 20 20 65 78 69  rce $argv0.  exi
0150: 74 20 30 0a 7d 0a 0a 23 20 45 6d 75 6c 61 74 65  t 0.}..# Emulate
0160: 20 61 20 54 43 4c 20 73 68 65 6c 6c 0a 23 0a 70   a TCL shell.#.p
0170: 72 6f 63 20 74 63 6c 73 68 20 7b 7d 20 7b 0a 20  roc tclsh {} {. 
0180: 20 73 65 74 20 6c 69 6e 65 20 7b 7d 0a 20 20 77   set line {}.  w
0190: 68 69 6c 65 20 7b 21 5b 65 6f 66 20 73 74 64 69  hile {![eof stdi
01a0: 6e 5d 7d 20 7b 0a 20 20 20 20 69 66 20 7b 24 6c  n]} {.    if {$l
01b0: 69 6e 65 21 3d 22 22 7d 20 7b 0a 20 20 20 20 20  ine!=""} {.     
01c0: 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65   puts -nonewline
01d0: 20 22 3e 20 22 0a 20 20 20 20 7d 20 65 6c 73 65   "> ".    } else
01e0: 20 7b 0a 20 20 20 20 20 20 70 75 74 73 20 2d 6e   {.      puts -n
01f0: 6f 6e 65 77 6c 69 6e 65 20 22 25 20 22 0a 20 20  onewline "% ".  
0200: 20 20 7d 0a 20 20 20 20 66 6c 75 73 68 20 73 74    }.    flush st
0210: 64 6f 75 74 0a 20 20 20 20 61 70 70 65 6e 64 20  dout.    append 
0220: 6c 69 6e 65 20 5b 67 65 74 73 20 73 74 64 69 6e  line [gets stdin
0230: 5d 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20  ].    if {[info 
0240: 63 6f 6d 70 6c 65 74 65 20 24 6c 69 6e 65 5d 7d  complete $line]}
0250: 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 5b 63 61   {.      if {[ca
0260: 74 63 68 20 7b 75 70 6c 65 76 65 6c 20 23 30 20  tch {uplevel #0 
0270: 24 6c 69 6e 65 7d 20 72 65 73 75 6c 74 5d 7d 20  $line} result]} 
0280: 7b 0a 20 20 20 20 20 20 20 20 70 75 74 73 20 73  {.        puts s
0290: 74 64 65 72 72 20 22 45 72 72 6f 72 3a 20 24 72  tderr "Error: $r
02a0: 65 73 75 6c 74 22 0a 20 20 20 20 20 20 7d 20 65  esult".      } e
02b0: 6c 73 65 69 66 20 7b 24 72 65 73 75 6c 74 21 3d  lseif {$result!=
02c0: 22 22 7d 20 7b 0a 20 20 20 20 20 20 20 20 70 75  ""} {.        pu
02d0: 74 73 20 24 72 65 73 75 6c 74 0a 20 20 20 20 20  ts $result.     
02e0: 20 7d 0a 20 20 20 20 20 20 73 65 74 20 6c 69 6e   }.      set lin
02f0: 65 20 7b 7d 0a 20 20 20 20 7d 20 65 6c 73 65 20  e {}.    } else 
0300: 7b 0a 20 20 20 20 20 20 61 70 70 65 6e 64 20 6c  {.      append l
0310: 69 6e 65 20 5c 6e 0a 20 20 20 20 7d 0a 20 20 7d  ine \n.    }.  }
0320: 0a 7d 0a 0a 23 20 44 6f 20 61 6e 20 69 6e 63 72  .}..# Do an incr
0330: 65 6d 65 6e 74 61 6c 20 69 6e 74 65 67 72 69 74  emental integrit
0340: 79 20 63 68 65 63 6b 20 6f 66 20 61 20 73 69 6e  y check of a sin
0350: 67 6c 65 20 69 6e 64 65 78 0a 23 0a 70 72 6f 63  gle index.#.proc
0360: 20 63 68 65 63 6b 5f 69 6e 64 65 78 20 7b 69 64   check_index {id
0370: 78 6e 61 6d 65 20 62 61 74 63 68 73 69 7a 65 20  xname batchsize 
0380: 62 54 72 61 63 65 7d 20 7b 0a 20 20 73 65 74 20  bTrace} {.  set 
0390: 69 20 30 0a 20 20 73 65 74 20 6d 6f 72 65 20 31  i 0.  set more 1
03a0: 0a 20 20 73 65 74 20 6e 65 72 72 20 30 0a 20 20  .  set nerr 0.  
03b0: 73 65 74 20 70 63 74 20 30 30 2e 30 0a 20 20 73  set pct 00.0.  s
03c0: 65 74 20 6d 61 78 20 5b 64 62 20 6f 6e 65 20 7b  et max [db one {
03d0: 53 45 4c 45 43 54 20 6e 45 6e 74 72 79 20 46 52  SELECT nEntry FR
03e0: 4f 4d 20 73 71 6c 69 74 65 5f 62 74 72 65 65 69  OM sqlite_btreei
03f0: 6e 66 6f 28 27 6d 61 69 6e 27 29 0a 20 20 20 20  nfo('main').    
0400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0410: 57 48 45 52 45 20 6e 61 6d 65 3d 24 69 64 78 6e  WHERE name=$idxn
0420: 61 6d 65 7d 5d 0a 20 20 70 75 74 73 20 2d 6e 6f  ame}].  puts -no
0430: 6e 65 77 6c 69 6e 65 20 22 24 69 64 78 6e 61 6d  newline "$idxnam
0440: 65 3a 20 24 69 20 6f 66 20 24 6d 61 78 20 72 6f  e: $i of $max ro
0450: 77 73 20 28 24 70 63 74 25 29 5c 72 22 0a 20 20  ws ($pct%)\r".  
0460: 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 20 20 69  flush stdout.  i
0470: 66 20 7b 24 62 54 72 61 63 65 7d 20 7b 0a 20 20  f {$bTrace} {.  
0480: 20 20 73 65 74 20 73 71 6c 20 7b 53 45 4c 45 43    set sql {SELEC
0490: 54 20 65 72 72 6d 73 67 2c 20 63 75 72 72 65 6e  T errmsg, curren
04a0: 74 5f 6b 65 79 20 41 53 20 6b 65 79 2c 0a 20 20  t_key AS key,.  
04b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04c0: 20 20 43 41 53 45 20 57 48 45 4e 20 72 6f 77 69    CASE WHEN rowi
04d0: 64 3d 31 20 54 48 45 4e 20 73 63 61 6e 6e 65 72  d=1 THEN scanner
04e0: 5f 73 71 6c 20 45 4e 44 20 41 53 20 74 72 61 63  _sql END AS trac
04f0: 65 4f 75 74 0a 20 20 20 20 20 20 20 20 20 20 20  eOut.           
0500: 20 20 20 20 46 52 4f 4d 20 69 6e 63 72 65 6d 65      FROM increme
0510: 6e 74 61 6c 5f 69 6e 64 65 78 5f 63 68 65 63 6b  ntal_index_check
0520: 28 24 69 64 78 6e 61 6d 65 29 0a 20 20 20 20 20  ($idxname).     
0530: 20 20 20 20 20 20 20 20 20 57 48 45 52 45 20 61           WHERE a
0540: 66 74 65 72 5f 6b 65 79 3d 24 6b 65 79 0a 20 20  fter_key=$key.  
0550: 20 20 20 20 20 20 20 20 20 20 20 20 4c 49 4d 49              LIMI
0560: 54 20 24 62 61 74 63 68 73 69 7a 65 7d 0a 20 20  T $batchsize}.  
0570: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74  } else {.    set
0580: 20 73 71 6c 20 7b 53 45 4c 45 43 54 20 65 72 72   sql {SELECT err
0590: 6d 73 67 2c 20 63 75 72 72 65 6e 74 5f 6b 65 79  msg, current_key
05a0: 20 41 53 20 6b 65 79 2c 20 4e 55 4c 4c 20 41 53   AS key, NULL AS
05b0: 20 74 72 61 63 65 4f 75 74 0a 20 20 20 20 20 20   traceOut.      
05c0: 20 20 20 20 20 20 20 20 20 46 52 4f 4d 20 69 6e           FROM in
05d0: 63 72 65 6d 65 6e 74 61 6c 5f 69 6e 64 65 78 5f  cremental_index_
05e0: 63 68 65 63 6b 28 24 69 64 78 6e 61 6d 65 29 0a  check($idxname).
05f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 57 48                WH
0600: 45 52 45 20 61 66 74 65 72 5f 6b 65 79 3d 24 6b  ERE after_key=$k
0610: 65 79 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ey.             
0620: 20 4c 49 4d 49 54 20 24 62 61 74 63 68 73 69 7a   LIMIT $batchsiz
0630: 65 7d 0a 20 20 7d 0a 20 20 77 68 69 6c 65 20 7b  e}.  }.  while {
0640: 24 6d 6f 72 65 7d 20 7b 0a 20 20 20 20 73 65 74  $more} {.    set
0650: 20 6d 6f 72 65 20 30 0a 20 20 20 20 64 62 20 65   more 0.    db e
0660: 76 61 6c 20 24 73 71 6c 20 7b 0a 20 20 20 20 20  val $sql {.     
0670: 20 73 65 74 20 6d 6f 72 65 20 31 0a 20 20 20 20   set more 1.    
0680: 20 20 69 66 20 7b 24 65 72 72 6d 73 67 21 3d 22    if {$errmsg!="
0690: 22 7d 20 7b 0a 20 20 20 20 20 20 20 20 69 6e 63  "} {.        inc
06a0: 72 20 6e 65 72 72 0a 20 20 20 20 20 20 20 20 70  r nerr.        p
06b0: 75 74 73 20 22 24 69 64 78 6e 61 6d 65 3a 20 6b  uts "$idxname: k
06c0: 65 79 28 24 6b 65 79 29 3a 20 24 65 72 72 6d 73  ey($key): $errms
06d0: 67 22 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 69  g".      } elsei
06e0: 66 20 7b 24 74 72 61 63 65 4f 75 74 21 3d 22 22  f {$traceOut!=""
06f0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 70 75 74 73  } {.        puts
0700: 20 22 24 69 64 78 6e 61 6d 65 3a 20 24 74 72 61   "$idxname: $tra
0710: 63 65 4f 75 74 22 0a 20 20 20 20 20 20 7d 0a 20  ceOut".      }. 
0720: 20 20 20 20 20 69 6e 63 72 20 69 0a 20 20 20 20       incr i.    
0730: 20 20 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 74    .    }.    set
0740: 20 78 20 5b 66 6f 72 6d 61 74 20 7b 25 2e 31 66   x [format {%.1f
0750: 7d 20 5b 65 78 70 72 20 7b 28 24 69 2a 31 30 30  } [expr {($i*100
0760: 2e 30 29 2f 24 6d 61 78 7d 5d 5d 0a 20 20 20 20  .0)/$max}]].    
0770: 69 66 20 7b 24 78 21 3d 24 70 63 74 7d 20 7b 0a  if {$x!=$pct} {.
0780: 20 20 20 20 20 20 70 75 74 73 20 2d 6e 6f 6e 65        puts -none
0790: 77 6c 69 6e 65 20 22 24 69 64 78 6e 61 6d 65 3a  wline "$idxname:
07a0: 20 24 69 20 6f 66 20 24 6d 61 78 20 72 6f 77 73   $i of $max rows
07b0: 20 28 24 70 63 74 25 29 5c 72 22 0a 20 20 20 20   ($pct%)\r".    
07c0: 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 20    flush stdout. 
07d0: 20 20 20 20 20 73 65 74 20 70 63 74 20 24 78 0a       set pct $x.
07e0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70 75 74 73      }.  }.  puts
07f0: 20 22 24 69 64 78 6e 61 6d 65 3a 20 24 6e 65 72   "$idxname: $ner
0800: 72 20 65 72 72 6f 72 73 20 6f 75 74 20 6f 66 20  r errors out of 
0810: 24 69 20 65 6e 74 72 69 65 73 22 0a 7d 0a 0a 23  $i entries".}..#
0820: 20 50 72 69 6e 74 20 61 20 75 73 61 67 65 20 6d   Print a usage m
0830: 65 73 73 61 67 65 20 6f 6e 20 73 74 61 6e 64 61  essage on standa
0840: 72 64 20 65 72 72 6f 72 2c 20 74 68 65 6e 20 71  rd error, then q
0850: 75 69 74 2e 0a 23 0a 70 72 6f 63 20 75 73 61 67  uit..#.proc usag
0860: 65 20 7b 7d 20 7b 0a 20 20 73 65 74 20 61 72 67  e {} {.  set arg
0870: 76 30 20 5b 66 69 6c 65 20 72 6f 6f 74 6e 61 6d  v0 [file rootnam
0880: 65 20 5b 66 69 6c 65 20 74 61 69 6c 20 5b 69 6e  e [file tail [in
0890: 66 6f 20 6e 61 6d 65 6f 66 65 78 65 63 75 74 61  fo nameofexecuta
08a0: 62 6c 65 5d 5d 5d 0a 20 20 70 75 74 73 20 73 74  ble]]].  puts st
08b0: 64 65 72 72 20 22 55 73 61 67 65 3a 20 24 61 72  derr "Usage: $ar
08c0: 67 76 30 20 4f 50 54 49 4f 4e 53 20 64 61 74 61  gv0 OPTIONS data
08d0: 62 61 73 65 2d 66 69 6c 65 6e 61 6d 65 22 0a 20  base-filename". 
08e0: 20 70 75 74 73 20 73 74 64 65 72 72 20 7b 0a 44   puts stderr {.D
08f0: 6f 20 73 61 6e 69 74 79 20 63 68 65 63 6b 69 6e  o sanity checkin
0900: 67 20 6f 6e 20 61 20 6c 69 76 65 20 53 51 4c 69  g on a live SQLi
0910: 74 65 33 20 64 61 74 61 62 61 73 65 20 66 69 6c  te3 database fil
0920: 65 20 73 70 65 63 69 66 69 65 64 20 62 79 20 74  e specified by t
0930: 68 65 0a 22 64 61 74 61 62 61 73 65 2d 66 69 6c  he."database-fil
0940: 65 6e 61 6d 65 22 20 61 72 67 75 6d 65 6e 74 2e  ename" argument.
0950: 0a 0a 4f 70 74 69 6f 6e 73 3a 0a 0a 20 20 20 2d  ..Options:..   -
0960: 2d 62 61 74 63 68 73 69 7a 65 20 4e 20 20 20 20  -batchsize N    
0970: 20 4e 75 6d 62 65 72 20 6f 66 20 72 6f 77 73 20   Number of rows 
0980: 74 6f 20 63 68 65 63 6b 20 70 65 72 20 74 72 61  to check per tra
0990: 6e 73 61 63 74 69 6f 6e 0a 0a 20 20 20 2d 2d 66  nsaction..   --f
09a0: 72 65 65 6c 69 73 74 20 20 20 20 20 20 20 20 50  reelist        P
09b0: 65 72 66 6f 72 6d 20 61 20 66 72 65 65 6c 69 73  erform a freelis
09c0: 74 20 63 68 65 63 6b 0a 0a 20 20 20 2d 2d 69 6e  t check..   --in
09d0: 64 65 78 20 4e 41 4d 45 20 20 20 20 20 20 52 75  dex NAME      Ru
09e0: 6e 20 61 20 63 68 65 63 6b 20 6f 66 20 74 68 65  n a check of the
09f0: 20 69 6e 64 65 78 20 4e 41 4d 45 0a 0a 20 20 20   index NAME..   
0a00: 2d 2d 73 75 6d 6d 61 72 79 20 20 20 20 20 20 20  --summary       
0a10: 20 20 50 72 69 6e 74 20 73 75 6d 6d 61 72 79 20    Print summary 
0a20: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75  information abou
0a30: 74 20 74 68 65 20 64 61 74 61 62 61 73 65 0a 0a  t the database..
0a40: 20 20 20 2d 2d 74 61 62 6c 65 20 4e 41 4d 45 20     --table NAME 
0a50: 20 20 20 20 20 52 75 6e 20 61 20 63 68 65 63 6b       Run a check
0a60: 20 6f 66 20 61 6c 6c 20 69 6e 64 65 78 65 73 20   of all indexes 
0a70: 66 6f 72 20 74 61 62 6c 65 20 4e 41 4d 45 0a 0a  for table NAME..
0a80: 20 20 20 2d 2d 74 63 6c 73 68 20 20 20 20 20 20     --tclsh      
0a90: 20 20 20 20 20 52 75 6e 20 74 68 65 20 62 75 69       Run the bui
0aa0: 6c 74 2d 69 6e 20 54 43 4c 20 69 6e 74 65 72 70  lt-in TCL interp
0ab0: 72 65 74 65 72 20 28 66 6f 72 20 64 65 62 75 67  reter (for debug
0ac0: 67 69 6e 67 29 0a 0a 20 20 20 2d 2d 74 72 61 63  ging)..   --trac
0ad0: 65 20 20 20 20 20 20 20 20 20 20 20 28 44 65 62  e           (Deb
0ae0: 75 67 67 69 6e 67 20 6f 6e 6c 79 3a 29 20 4f 75  ugging only:) Ou
0af0: 74 70 75 74 20 74 72 61 63 65 20 69 6e 66 6f 72  tput trace infor
0b00: 6d 61 74 69 6f 6e 20 6f 6e 20 74 68 65 20 73 63  mation on the sc
0b10: 61 6e 0a 0a 20 20 20 2d 2d 76 65 72 73 69 6f 6e  an..   --version
0b20: 20 20 20 20 20 20 20 20 20 53 68 6f 77 20 74 68           Show th
0b30: 65 20 76 65 72 73 69 6f 6e 20 6e 75 6d 62 65 72  e version number
0b40: 20 6f 66 20 53 51 4c 69 74 65 0a 7d 0a 20 20 65   of SQLite.}.  e
0b50: 78 69 74 20 31 0a 7d 0a 0a 73 65 74 20 66 69 6c  xit 1.}..set fil
0b60: 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 20 7b 7d 0a  e_to_analyze {}.
0b70: 61 70 70 65 6e 64 20 61 72 67 76 20 7b 7d 0a 73  append argv {}.s
0b80: 65 74 20 62 46 72 65 65 6c 69 73 74 43 68 65 63  et bFreelistChec
0b90: 6b 20 30 0a 73 65 74 20 62 53 75 6d 6d 61 72 79  k 0.set bSummary
0ba0: 20 30 0a 73 65 74 20 7a 49 6e 64 65 78 20 7b 7d   0.set zIndex {}
0bb0: 0a 73 65 74 20 7a 54 61 62 6c 65 20 7b 7d 0a 73  .set zTable {}.s
0bc0: 65 74 20 62 61 74 63 68 73 69 7a 65 20 31 30 30  et batchsize 100
0bd0: 30 0a 73 65 74 20 62 41 6c 6c 20 31 0a 73 65 74  0.set bAll 1.set
0be0: 20 62 54 72 61 63 65 20 30 0a 73 65 74 20 61 72   bTrace 0.set ar
0bf0: 67 63 20 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67  gc [llength $arg
0c00: 76 5d 0a 66 6f 72 20 7b 73 65 74 20 69 20 30 7d  v].for {set i 0}
0c10: 20 7b 24 69 3c 24 61 72 67 63 7d 20 7b 69 6e 63   {$i<$argc} {inc
0c20: 72 20 69 7d 20 7b 0a 20 20 73 65 74 20 61 72 67  r i} {.  set arg
0c30: 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 76 20 24   [lindex $argv $
0c40: 69 5d 0a 20 20 69 66 20 7b 5b 72 65 67 65 78 70  i].  if {[regexp
0c50: 20 7b 5e 2d 2b 74 63 6c 73 68 24 7d 20 24 61 72   {^-+tclsh$} $ar
0c60: 67 5d 7d 20 7b 0a 20 20 20 20 74 63 6c 73 68 0a  g]} {.    tclsh.
0c70: 20 20 20 20 65 78 69 74 20 30 0a 20 20 7d 0a 20      exit 0.  }. 
0c80: 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e 2d   if {[regexp {^-
0c90: 2b 76 65 72 73 69 6f 6e 24 7d 20 24 61 72 67 5d  +version$} $arg]
0ca0: 7d 20 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 20  } {.    sqlite3 
0cb0: 6d 65 6d 20 3a 6d 65 6d 6f 72 79 3a 0a 20 20 20  mem :memory:.   
0cc0: 20 70 75 74 73 20 5b 6d 65 6d 20 6f 6e 65 20 7b   puts [mem one {
0cd0: 53 45 4c 45 43 54 20 73 71 6c 69 74 65 5f 76 65  SELECT sqlite_ve
0ce0: 72 73 69 6f 6e 28 29 7c 7c 27 20 27 7c 7c 73 71  rsion()||' '||sq
0cf0: 6c 69 74 65 5f 73 6f 75 72 63 65 5f 69 64 28 29  lite_source_id()
0d00: 7d 5d 0a 20 20 20 20 6d 65 6d 20 63 6c 6f 73 65  }].    mem close
0d10: 0a 20 20 20 20 65 78 69 74 20 30 0a 20 20 7d 0a  .    exit 0.  }.
0d20: 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e    if {[regexp {^
0d30: 2d 2b 66 72 65 65 6c 69 73 74 24 7d 20 24 61 72  -+freelist$} $ar
0d40: 67 5d 7d 20 7b 0a 20 20 20 20 73 65 74 20 62 46  g]} {.    set bF
0d50: 72 65 65 6c 69 73 74 43 68 65 63 6b 20 31 0a 20  reelistCheck 1. 
0d60: 20 20 20 73 65 74 20 62 41 6c 6c 20 30 0a 20 20     set bAll 0.  
0d70: 20 20 63 6f 6e 74 69 6e 75 65 0a 20 20 7d 0a 20    continue.  }. 
0d80: 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e 2d   if {[regexp {^-
0d90: 2b 73 75 6d 6d 61 72 79 24 7d 20 24 61 72 67 5d  +summary$} $arg]
0da0: 7d 20 7b 0a 20 20 20 20 73 65 74 20 62 53 75 6d  } {.    set bSum
0db0: 6d 61 72 79 20 31 0a 20 20 20 20 73 65 74 20 62  mary 1.    set b
0dc0: 41 6c 6c 20 30 0a 20 20 20 20 63 6f 6e 74 69 6e  All 0.    contin
0dd0: 75 65 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 72 65  ue.  }.  if {[re
0de0: 67 65 78 70 20 7b 5e 2d 2b 74 72 61 63 65 24 7d  gexp {^-+trace$}
0df0: 20 24 61 72 67 5d 7d 20 7b 0a 20 20 20 20 73 65   $arg]} {.    se
0e00: 74 20 62 54 72 61 63 65 20 31 0a 20 20 20 20 63  t bTrace 1.    c
0e10: 6f 6e 74 69 6e 75 65 0a 20 20 7d 0a 20 20 69 66  ontinue.  }.  if
0e20: 20 7b 5b 72 65 67 65 78 70 20 7b 5e 2d 2b 62 61   {[regexp {^-+ba
0e30: 74 63 68 73 69 7a 65 24 7d 20 24 61 72 67 5d 7d  tchsize$} $arg]}
0e40: 20 7b 0a 20 20 20 20 69 6e 63 72 20 69 0a 20 20   {.    incr i.  
0e50: 20 20 69 66 20 7b 24 69 3e 3d 24 61 72 67 63 7d    if {$i>=$argc}
0e60: 20 7b 0a 20 20 20 20 20 20 70 75 74 73 20 73 74   {.      puts st
0e70: 64 65 72 72 20 22 6d 69 73 73 69 6e 67 20 61 72  derr "missing ar
0e80: 67 75 6d 65 6e 74 20 6f 6e 20 24 61 72 67 22 0a  gument on $arg".
0e90: 20 20 20 20 20 20 65 78 69 74 20 31 0a 20 20 20        exit 1.   
0ea0: 20 7d 0a 20 20 20 20 73 65 74 20 62 61 74 63 68   }.    set batch
0eb0: 73 69 7a 65 20 5b 6c 69 6e 64 65 78 20 24 61 72  size [lindex $ar
0ec0: 67 76 20 24 69 5d 0a 20 20 20 20 63 6f 6e 74 69  gv $i].    conti
0ed0: 6e 75 65 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 72  nue.  }.  if {[r
0ee0: 65 67 65 78 70 20 7b 5e 2d 2b 69 6e 64 65 78 24  egexp {^-+index$
0ef0: 7d 20 24 61 72 67 5d 7d 20 7b 0a 20 20 20 20 69  } $arg]} {.    i
0f00: 6e 63 72 20 69 0a 20 20 20 20 69 66 20 7b 24 69  ncr i.    if {$i
0f10: 3e 3d 24 61 72 67 63 7d 20 7b 0a 20 20 20 20 20  >=$argc} {.     
0f20: 20 70 75 74 73 20 73 74 64 65 72 72 20 22 6d 69   puts stderr "mi
0f30: 73 73 69 6e 67 20 61 72 67 75 6d 65 6e 74 20 6f  ssing argument o
0f40: 6e 20 24 61 72 67 22 0a 20 20 20 20 20 20 65 78  n $arg".      ex
0f50: 69 74 20 31 0a 20 20 20 20 7d 0a 20 20 20 20 73  it 1.    }.    s
0f60: 65 74 20 7a 49 6e 64 65 78 20 5b 6c 69 6e 64 65  et zIndex [linde
0f70: 78 20 24 61 72 67 76 20 24 69 5d 0a 20 20 20 20  x $argv $i].    
0f80: 73 65 74 20 62 41 6c 6c 20 30 0a 20 20 20 20 63  set bAll 0.    c
0f90: 6f 6e 74 69 6e 75 65 0a 20 20 7d 0a 20 20 69 66  ontinue.  }.  if
0fa0: 20 7b 5b 72 65 67 65 78 70 20 7b 5e 2d 2b 74 61   {[regexp {^-+ta
0fb0: 62 6c 65 24 7d 20 24 61 72 67 5d 7d 20 7b 0a 20  ble$} $arg]} {. 
0fc0: 20 20 20 69 6e 63 72 20 69 0a 20 20 20 20 69 66     incr i.    if
0fd0: 20 7b 24 69 3e 3d 24 61 72 67 63 7d 20 7b 0a 20   {$i>=$argc} {. 
0fe0: 20 20 20 20 20 70 75 74 73 20 73 74 64 65 72 72       puts stderr
0ff0: 20 22 6d 69 73 73 69 6e 67 20 61 72 67 75 6d 65   "missing argume
1000: 6e 74 20 6f 6e 20 24 61 72 67 22 0a 20 20 20 20  nt on $arg".    
1010: 20 20 65 78 69 74 20 31 0a 20 20 20 20 7d 0a 20    exit 1.    }. 
1020: 20 20 20 73 65 74 20 7a 54 61 62 6c 65 20 5b 6c     set zTable [l
1030: 69 6e 64 65 78 20 24 61 72 67 76 20 24 69 5d 0a  index $argv $i].
1040: 20 20 20 20 73 65 74 20 62 41 6c 6c 20 30 0a 20      set bAll 0. 
1050: 20 20 20 63 6f 6e 74 69 6e 75 65 0a 20 20 7d 0a     continue.  }.
1060: 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e    if {[regexp {^
1070: 2d 7d 20 24 61 72 67 5d 7d 20 7b 0a 20 20 20 20  -} $arg]} {.    
1080: 70 75 74 73 20 73 74 64 65 72 72 20 22 55 6e 6b  puts stderr "Unk
1090: 6e 6f 77 6e 20 6f 70 74 69 6f 6e 3a 20 24 61 72  nown option: $ar
10a0: 67 22 0a 20 20 20 20 75 73 61 67 65 0a 20 20 7d  g".    usage.  }
10b0: 0a 20 20 69 66 20 7b 24 66 69 6c 65 5f 74 6f 5f  .  if {$file_to_
10c0: 61 6e 61 6c 79 7a 65 21 3d 22 22 7d 20 7b 0a 20  analyze!=""} {. 
10d0: 20 20 20 75 73 61 67 65 0a 20 20 7d 20 65 6c 73     usage.  } els
10e0: 65 20 7b 0a 20 20 20 20 73 65 74 20 66 69 6c 65  e {.    set file
10f0: 5f 74 6f 5f 61 6e 61 6c 79 7a 65 20 24 61 72 67  _to_analyze $arg
1100: 0a 20 20 7d 0a 7d 0a 69 66 20 7b 24 66 69 6c 65  .  }.}.if {$file
1110: 5f 74 6f 5f 61 6e 61 6c 79 7a 65 3d 3d 22 22 7d  _to_analyze==""}
1120: 20 75 73 61 67 65 0a 0a 23 20 49 66 20 61 20 54   usage..# If a T
1130: 43 4c 20 73 63 72 69 70 74 20 69 73 20 73 70 65  CL script is spe
1140: 63 69 66 69 65 64 20 6f 6e 20 74 68 65 20 63 6f  cified on the co
1150: 6d 6d 61 6e 64 2d 6c 69 6e 65 2c 20 74 68 65 6e  mmand-line, then
1160: 20 72 75 6e 20 74 68 61 74 0a 23 20 73 63 72 69   run that.# scri
1170: 70 74 2e 0a 23 0a 69 66 20 7b 5b 66 69 6c 65 20  pt..#.if {[file 
1180: 65 78 74 65 6e 73 69 6f 6e 20 24 66 69 6c 65 5f  extension $file_
1190: 74 6f 5f 61 6e 61 6c 79 7a 65 5d 3d 3d 22 2e 74  to_analyze]==".t
11a0: 63 6c 22 7d 20 7b 0a 20 20 73 6f 75 72 63 65 20  cl"} {.  source 
11b0: 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65  $file_to_analyze
11c0: 0a 20 20 65 78 69 74 20 30 0a 7d 0a 0a 73 65 74  .  exit 0.}..set
11d0: 20 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d 65 20 24   root_filename $
11e0: 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 0a  file_to_analyze.
11f0: 72 65 67 65 78 70 20 7b 5e 66 69 6c 65 3a 28 2f  regexp {^file:(/
1200: 2f 29 3f 28 5b 5e 3f 5d 2a 29 7d 20 24 66 69 6c  /)?([^?]*)} $fil
1210: 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 20 61 6c 6c  e_to_analyze all
1220: 20 78 31 20 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d   x1 root_filenam
1230: 65 0a 69 66 20 7b 21 5b 66 69 6c 65 20 65 78 69  e.if {![file exi
1240: 73 74 73 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61  sts $root_filena
1250: 6d 65 5d 7d 20 7b 0a 20 20 70 75 74 73 20 73 74  me]} {.  puts st
1260: 64 65 72 72 20 22 4e 6f 20 73 75 63 68 20 66 69  derr "No such fi
1270: 6c 65 3a 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61  le: $root_filena
1280: 6d 65 22 0a 20 20 65 78 69 74 20 31 0a 7d 0a 69  me".  exit 1.}.i
1290: 66 20 7b 21 5b 66 69 6c 65 20 72 65 61 64 61 62  f {![file readab
12a0: 6c 65 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d  le $root_filenam
12b0: 65 5d 7d 20 7b 0a 20 20 70 75 74 73 20 73 74 64  e]} {.  puts std
12c0: 65 72 72 20 22 46 69 6c 65 20 69 73 20 6e 6f 74  err "File is not
12d0: 20 72 65 61 64 61 62 6c 65 3a 20 24 72 6f 6f 74   readable: $root
12e0: 5f 66 69 6c 65 6e 61 6d 65 22 0a 20 20 65 78 69  _filename".  exi
12f0: 74 20 31 0a 7d 0a 0a 69 66 20 7b 5b 63 61 74 63  t 1.}..if {[catc
1300: 68 20 7b 73 71 6c 69 74 65 33 20 64 62 20 24 66  h {sqlite3 db $f
1310: 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 7d 20  ile_to_analyze} 
1320: 72 65 73 5d 7d 20 7b 0a 20 20 70 75 74 73 20 73  res]} {.  puts s
1330: 74 64 65 72 72 20 22 43 61 6e 6e 6f 74 20 6f 70  tderr "Cannot op
1340: 65 6e 20 64 61 74 61 62 61 62 61 73 65 20 24 72  en datababase $r
1350: 6f 6f 74 5f 66 69 6c 65 6e 61 6d 65 3a 20 24 72  oot_filename: $r
1360: 65 73 22 0a 20 20 65 78 69 74 20 31 0a 7d 0a 0a  es".  exit 1.}..
1370: 69 66 20 7b 24 62 46 72 65 65 6c 69 73 74 43 68  if {$bFreelistCh
1380: 65 63 6b 20 7c 7c 20 24 62 41 6c 6c 7d 20 7b 0a  eck || $bAll} {.
1390: 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e    puts -nonewlin
13a0: 65 20 22 66 72 65 65 6c 69 73 74 2d 63 68 65 63  e "freelist-chec
13b0: 6b 3a 20 22 0a 20 20 66 6c 75 73 68 20 73 74 64  k: ".  flush std
13c0: 6f 75 74 0a 20 20 70 75 74 73 20 5b 64 62 20 6f  out.  puts [db o
13d0: 6e 65 20 7b 53 45 4c 45 43 54 20 63 68 65 63 6b  ne {SELECT check
13e0: 66 72 65 65 6c 69 73 74 28 27 6d 61 69 6e 27 29  freelist('main')
13f0: 7d 5d 0a 7d 0a 69 66 20 7b 24 62 53 75 6d 6d 61  }].}.if {$bSumma
1400: 72 79 7d 20 7b 0a 20 20 73 65 74 20 73 63 61 6c  ry} {.  set scal
1410: 65 20 30 0a 20 20 73 65 74 20 70 67 73 7a 20 5b  e 0.  set pgsz [
1420: 64 62 20 6f 6e 65 20 7b 50 52 41 47 4d 41 20 70  db one {PRAGMA p
1430: 61 67 65 5f 73 69 7a 65 7d 5d 0a 20 20 64 62 20  age_size}].  db 
1440: 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 6e 50 61  eval {SELECT nPa
1450: 67 65 2a 24 70 67 73 7a 20 41 53 20 73 7a 2c 20  ge*$pgsz AS sz, 
1460: 6e 61 6d 65 2c 20 74 62 6c 5f 6e 61 6d 65 0a 20  name, tbl_name. 
1470: 20 20 20 20 20 20 20 20 20 20 20 20 46 52 4f 4d              FROM
1480: 20 73 71 6c 69 74 65 5f 62 74 72 65 65 69 6e 66   sqlite_btreeinf
1490: 6f 0a 20 20 20 20 20 20 20 20 20 20 20 20 57 48  o.            WH
14a0: 45 52 45 20 74 79 70 65 3d 27 69 6e 64 65 78 27  ERE type='index'
14b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 4f 52 44  .            ORD
14c0: 45 52 20 42 59 20 31 20 44 45 53 43 2c 20 6e 61  ER BY 1 DESC, na
14d0: 6d 65 7d 20 7b 0a 20 20 20 20 69 66 20 7b 24 73  me} {.    if {$s
14e0: 63 61 6c 65 3d 3d 30 7d 20 7b 0a 20 20 20 20 20  cale==0} {.     
14f0: 20 69 66 20 7b 24 73 7a 3e 31 30 30 30 30 30 30   if {$sz>1000000
1500: 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74  0} {.        set
1510: 20 73 63 61 6c 65 20 31 30 30 30 30 30 30 2e 30   scale 1000000.0
1520: 0a 20 20 20 20 20 20 20 20 73 65 74 20 75 6e 69  .        set uni
1530: 74 20 4d 42 0a 20 20 20 20 20 20 7d 20 65 6c 73  t MB.      } els
1540: 65 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20  e {.        set 
1550: 73 63 61 6c 65 20 31 30 30 30 2e 30 0a 20 20 20  scale 1000.0.   
1560: 20 20 20 20 20 73 65 74 20 75 6e 69 74 20 4b 42       set unit KB
1570: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
1580: 20 20 20 70 75 74 73 20 5b 66 6f 72 6d 61 74 20     puts [format 
1590: 7b 25 37 2e 31 66 20 25 73 20 69 6e 64 65 78 20  {%7.1f %s index 
15a0: 25 73 20 6f 66 20 74 61 62 6c 65 20 25 73 7d 20  %s of table %s} 
15b0: 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 5b 65  \.            [e
15c0: 78 70 72 20 7b 24 73 7a 2f 24 73 63 61 6c 65 7d  xpr {$sz/$scale}
15d0: 5d 20 24 75 6e 69 74 20 24 6e 61 6d 65 20 24 74  ] $unit $name $t
15e0: 62 6c 5f 6e 61 6d 65 5d 0a 20 20 7d 0a 7d 0a 69  bl_name].  }.}.i
15f0: 66 20 7b 24 7a 49 6e 64 65 78 21 3d 22 22 7d 20  f {$zIndex!=""} 
1600: 7b 0a 20 20 63 68 65 63 6b 5f 69 6e 64 65 78 20  {.  check_index 
1610: 24 7a 49 6e 64 65 78 20 24 62 61 74 63 68 73 69  $zIndex $batchsi
1620: 7a 65 20 24 62 54 72 61 63 65 0a 7d 0a 69 66 20  ze $bTrace.}.if 
1630: 7b 24 7a 54 61 62 6c 65 21 3d 22 22 7d 20 7b 0a  {$zTable!=""} {.
1640: 20 20 66 6f 72 65 61 63 68 20 69 64 78 20 5b 64    foreach idx [d
1650: 62 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 6e  b eval {SELECT n
1660: 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f  ame FROM sqlite_
1670: 6d 61 73 74 65 72 0a 20 20 20 20 20 20 20 20 20  master.         
1680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1690: 57 48 45 52 45 20 74 79 70 65 3d 27 69 6e 64 65  WHERE type='inde
16a0: 78 27 20 41 4e 44 20 72 6f 6f 74 70 61 67 65 3e  x' AND rootpage>
16b0: 30 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0.              
16c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 41 4e 44               AND
16d0: 20 74 62 6c 5f 6e 61 6d 65 3d 24 7a 54 61 62 6c   tbl_name=$zTabl
16e0: 65 7d 5d 20 7b 0a 20 20 20 20 63 68 65 63 6b 5f  e}] {.    check_
16f0: 69 6e 64 65 78 20 24 69 64 78 20 24 62 61 74 63  index $idx $batc
1700: 68 73 69 7a 65 20 24 62 54 72 61 63 65 0a 20 20  hsize $bTrace.  
1710: 7d 0a 7d 0a 69 66 20 7b 24 62 41 6c 6c 7d 20 7b  }.}.if {$bAll} {
1720: 0a 20 20 73 65 74 20 61 6c 6c 69 64 78 20 5b 64  .  set allidx [d
1730: 62 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 6e  b eval {SELECT n
1740: 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f  ame FROM sqlite_
1750: 62 74 72 65 65 69 6e 66 6f 28 27 6d 61 69 6e 27  btreeinfo('main'
1760: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
1770: 20 20 20 20 20 20 20 20 20 20 57 48 45 52 45 20            WHERE 
1780: 74 79 70 65 3d 27 69 6e 64 65 78 27 20 41 4e 44  type='index' AND
1790: 20 72 6f 6f 74 70 61 67 65 3e 30 0a 20 20 20 20   rootpage>0.    
17a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17b0: 20 20 20 20 4f 52 44 45 52 20 42 59 20 6e 45 6e      ORDER BY nEn
17c0: 74 72 79 7d 5d 0a 20 20 66 6f 72 65 61 63 68 20  try}].  foreach 
17d0: 69 64 78 20 24 61 6c 6c 69 64 78 20 7b 0a 20 20  idx $allidx {.  
17e0: 20 20 63 68 65 63 6b 5f 69 6e 64 65 78 20 24 69    check_index $i
17f0: 64 78 20 24 62 61 74 63 68 73 69 7a 65 20 24 62  dx $batchsize $b
1800: 54 72 61 63 65 0a 20 20 7d 0a 7d 0a              Trace.  }.}.