/ Hex Artifact Content
Login

Artifact a91e09e9e3dd10e67ffe4a01155161fb5e6b6d399002716593780493452c4b28:


0000: 23 20 52 75 6e 20 74 68 69 73 20 54 43 4c 20 73  # Run this TCL s
0010: 63 72 69 70 74 20 75 73 69 6e 67 20 22 74 65 73  cript using "tes
0020: 74 66 69 78 74 75 72 65 22 20 69 6e 20 6f 72 64  tfixture" in ord
0030: 65 72 20 67 65 74 20 61 20 72 65 70 6f 72 74 20  er get a report 
0040: 74 68 61 74 20 73 68 6f 77 73 0a 23 20 68 6f 77  that shows.# how
0050: 20 6d 75 63 68 20 64 69 73 6b 20 73 70 61 63 65   much disk space
0060: 20 69 73 20 75 73 65 64 20 62 79 20 61 20 70 61   is used by a pa
0070: 72 74 69 63 75 6c 61 72 20 64 61 74 61 20 74 6f  rticular data to
0080: 20 61 63 74 75 61 6c 6c 79 20 73 74 6f 72 65 20   actually store 
0090: 64 61 74 61 0a 23 20 76 65 72 73 75 73 20 68 6f  data.# versus ho
00a0: 77 20 6d 75 63 68 20 73 70 61 63 65 20 69 73 20  w much space is 
00b0: 75 6e 75 73 65 64 2e 0a 23 0a 0a 69 66 20 7b 5b  unused..#..if {[
00c0: 63 61 74 63 68 20 7b 0a 0a 23 20 41 72 67 75 6d  catch {..# Argum
00d0: 65 6e 74 20 24 74 6e 61 6d 65 20 69 73 20 74 68  ent $tname is th
00e0: 65 20 6e 61 6d 65 20 6f 66 20 61 20 74 61 62 6c  e name of a tabl
00f0: 65 20 77 69 74 68 69 6e 20 74 68 65 20 64 61 74  e within the dat
0100: 61 62 61 73 65 20 6f 70 65 6e 65 64 20 62 79 0a  abase opened by.
0110: 23 20 64 61 74 61 62 61 73 65 20 68 61 6e 64 6c  # database handl
0120: 65 20 5b 64 62 5d 2e 20 52 65 74 75 72 6e 20 74  e [db]. Return t
0130: 72 75 65 20 69 66 20 69 74 20 69 73 20 61 20 57  rue if it is a W
0140: 49 54 48 4f 55 54 20 52 4f 57 49 44 20 74 61 62  ITHOUT ROWID tab
0150: 6c 65 2c 20 6f 72 0a 23 20 66 61 6c 73 65 20 6f  le, or.# false o
0160: 74 68 65 72 77 69 73 65 2e 0a 23 0a 70 72 6f 63  therwise..#.proc
0170: 20 69 73 5f 77 69 74 68 6f 75 74 5f 72 6f 77 69   is_without_rowi
0180: 64 20 7b 74 6e 61 6d 65 7d 20 7b 0a 20 20 73 65  d {tname} {.  se
0190: 74 20 74 20 5b 73 74 72 69 6e 67 20 6d 61 70 20  t t [string map 
01a0: 7b 27 20 27 27 7d 20 24 74 6e 61 6d 65 5d 0a 20  {' ''} $tname]. 
01b0: 20 64 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41   db eval "PRAGMA
01c0: 20 69 6e 64 65 78 5f 6c 69 73 74 20 3d 20 27 24   index_list = '$
01d0: 74 27 22 20 6f 20 7b 0a 20 20 20 20 69 66 20 7b  t'" o {.    if {
01e0: 24 6f 28 6f 72 69 67 69 6e 29 20 3d 3d 20 22 70  $o(origin) == "p
01f0: 6b 22 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20  k"} {.      set 
0200: 6e 20 24 6f 28 6e 61 6d 65 29 0a 20 20 20 20 20  n $o(name).     
0210: 20 69 66 20 7b 30 3d 3d 5b 64 62 20 6f 6e 65 20   if {0==[db one 
0220: 7b 20 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a  { SELECT count(*
0230: 29 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61  ) FROM sqlite_ma
0240: 73 74 65 72 20 57 48 45 52 45 20 6e 61 6d 65 3d  ster WHERE name=
0250: 24 6e 20 7d 5d 7d 20 7b 0a 20 20 20 20 20 20 20  $n }]} {.       
0260: 20 72 65 74 75 72 6e 20 31 0a 20 20 20 20 20 20   return 1.      
0270: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65  }.    }.  }.  re
0280: 74 75 72 6e 20 30 0a 7d 0a 0a 23 20 52 65 61 64  turn 0.}..# Read
0290: 20 61 6e 64 20 72 75 6e 20 54 43 4c 20 63 6f 6d   and run TCL com
02a0: 6d 61 6e 64 73 20 66 72 6f 6d 20 73 74 61 6e 64  mands from stand
02b0: 61 72 64 20 69 6e 70 75 74 2e 20 20 55 73 65 64  ard input.  Used
02c0: 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 0a 23 20   to implement.# 
02d0: 74 68 65 20 2d 2d 74 63 6c 73 68 20 6f 70 74 69  the --tclsh opti
02e0: 6f 6e 2e 0a 23 0a 70 72 6f 63 20 74 63 6c 73 68  on..#.proc tclsh
02f0: 20 7b 7d 20 7b 0a 20 20 73 65 74 20 6c 69 6e 65   {} {.  set line
0300: 20 7b 7d 0a 20 20 77 68 69 6c 65 20 7b 21 5b 65   {}.  while {![e
0310: 6f 66 20 73 74 64 69 6e 5d 7d 20 7b 0a 20 20 20  of stdin]} {.   
0320: 20 69 66 20 7b 24 6c 69 6e 65 21 3d 22 22 7d 20   if {$line!=""} 
0330: 7b 0a 20 20 20 20 20 20 70 75 74 73 20 2d 6e 6f  {.      puts -no
0340: 6e 65 77 6c 69 6e 65 20 22 3e 20 22 0a 20 20 20  newline "> ".   
0350: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20   } else {.      
0360: 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20  puts -nonewline 
0370: 22 25 20 22 0a 20 20 20 20 7d 0a 20 20 20 20 66  "% ".    }.    f
0380: 6c 75 73 68 20 73 74 64 6f 75 74 0a 20 20 20 20  lush stdout.    
0390: 61 70 70 65 6e 64 20 6c 69 6e 65 20 5b 67 65 74  append line [get
03a0: 73 20 73 74 64 69 6e 5d 0a 20 20 20 20 69 66 20  s stdin].    if 
03b0: 7b 5b 69 6e 66 6f 20 63 6f 6d 70 6c 65 74 65 20  {[info complete 
03c0: 24 6c 69 6e 65 5d 7d 20 7b 0a 20 20 20 20 20 20  $line]} {.      
03d0: 69 66 20 7b 5b 63 61 74 63 68 20 7b 75 70 6c 65  if {[catch {uple
03e0: 76 65 6c 20 23 30 20 24 6c 69 6e 65 7d 20 72 65  vel #0 $line} re
03f0: 73 75 6c 74 5d 7d 20 7b 0a 20 20 20 20 20 20 20  sult]} {.       
0400: 20 70 75 74 73 20 73 74 64 65 72 72 20 22 45 72   puts stderr "Er
0410: 72 6f 72 3a 20 24 72 65 73 75 6c 74 22 0a 20 20  ror: $result".  
0420: 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 72      } elseif {$r
0430: 65 73 75 6c 74 21 3d 22 22 7d 20 7b 0a 20 20 20  esult!=""} {.   
0440: 20 20 20 20 20 70 75 74 73 20 24 72 65 73 75 6c       puts $resul
0450: 74 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  t.      }.      
0460: 73 65 74 20 6c 69 6e 65 20 7b 7d 0a 20 20 20 20  set line {}.    
0470: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 61  } else {.      a
0480: 70 70 65 6e 64 20 6c 69 6e 65 20 5c 6e 0a 20 20  ppend line \n.  
0490: 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 0a 23 20 47 65    }.  }.}...# Ge
04a0: 74 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68  t the name of th
04b0: 65 20 64 61 74 61 62 61 73 65 20 74 6f 20 61 6e  e database to an
04c0: 61 6c 79 7a 65 0a 23 0a 70 72 6f 63 20 75 73 61  alyze.#.proc usa
04d0: 67 65 20 7b 7d 20 7b 0a 20 20 73 65 74 20 61 72  ge {} {.  set ar
04e0: 67 76 30 20 5b 66 69 6c 65 20 72 6f 6f 74 6e 61  gv0 [file rootna
04f0: 6d 65 20 5b 66 69 6c 65 20 74 61 69 6c 20 5b 69  me [file tail [i
0500: 6e 66 6f 20 6e 61 6d 65 6f 66 65 78 65 63 75 74  nfo nameofexecut
0510: 61 62 6c 65 5d 5d 5d 0a 20 20 70 75 74 73 20 73  able]]].  puts s
0520: 74 64 65 72 72 20 22 55 73 61 67 65 3a 20 24 61  tderr "Usage: $a
0530: 72 67 76 30 20 3f 2d 2d 70 61 67 65 69 6e 66 6f  rgv0 ?--pageinfo
0540: 3f 20 3f 2d 2d 73 74 61 74 73 3f 20 64 61 74 61  ? ?--stats? data
0550: 62 61 73 65 2d 66 69 6c 65 6e 61 6d 65 22 0a 20  base-filename". 
0560: 20 70 75 74 73 20 73 74 64 65 72 72 20 7b 0a 41   puts stderr {.A
0570: 6e 61 6c 79 7a 65 20 74 68 65 20 53 51 4c 69 74  nalyze the SQLit
0580: 65 33 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  e3 database file
0590: 20 73 70 65 63 69 66 69 65 64 20 62 79 20 74 68   specified by th
05a0: 65 20 22 64 61 74 61 62 61 73 65 2d 66 69 6c 65  e "database-file
05b0: 6e 61 6d 65 22 0a 61 72 67 75 6d 65 6e 74 20 61  name".argument a
05c0: 6e 64 20 6f 75 74 70 75 74 20 61 20 72 65 70 6f  nd output a repo
05d0: 72 74 20 64 65 74 61 69 6c 69 6e 67 20 73 69 7a  rt detailing siz
05e0: 65 20 61 6e 64 20 73 74 6f 72 61 67 65 20 65 66  e and storage ef
05f0: 66 69 63 69 65 6e 63 79 0a 69 6e 66 6f 72 6d 61  ficiency.informa
0600: 74 69 6f 6e 20 66 6f 72 20 74 68 65 20 64 61 74  tion for the dat
0610: 61 62 61 73 65 20 61 6e 64 20 69 74 73 20 63 6f  abase and its co
0620: 6e 73 74 69 74 75 65 6e 74 20 74 61 62 6c 65 73  nstituent tables
0630: 20 61 6e 64 20 69 6e 64 65 78 65 73 2e 0a 0a 4f   and indexes...O
0640: 70 74 69 6f 6e 73 3a 0a 0a 20 20 20 2d 2d 70 61  ptions:..   --pa
0650: 67 65 69 6e 66 6f 20 20 20 53 68 6f 77 20 68 6f  geinfo   Show ho
0660: 77 20 65 61 63 68 20 70 61 67 65 20 6f 66 20 74  w each page of t
0670: 68 65 20 64 61 74 61 62 61 73 65 2d 66 69 6c 65  he database-file
0680: 20 69 73 20 75 73 65 64 0a 0a 20 20 20 2d 2d 73   is used..   --s
0690: 74 61 74 73 20 20 20 20 20 20 4f 75 74 70 75 74  tats      Output
06a0: 20 53 51 4c 20 74 65 78 74 20 74 68 61 74 20 63   SQL text that c
06b0: 72 65 61 74 65 73 20 61 20 6e 65 77 20 64 61 74  reates a new dat
06c0: 61 62 61 73 65 20 63 6f 6e 74 61 69 6e 69 6e 67  abase containing
06d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
06e0: 20 73 74 61 74 69 73 74 69 63 73 20 61 62 6f 75   statistics abou
06f0: 74 20 74 68 65 20 64 61 74 61 62 61 73 65 20 74  t the database t
0700: 68 61 74 20 77 61 73 20 61 6e 61 6c 79 7a 65 64  hat was analyzed
0710: 0a 0a 20 20 20 2d 2d 74 63 6c 73 68 20 20 20 20  ..   --tclsh    
0720: 20 20 52 75 6e 20 74 68 65 20 62 75 69 6c 74 2d    Run the built-
0730: 69 6e 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74  in TCL interpret
0740: 65 72 20 69 6e 74 65 72 61 63 74 69 76 65 6c 79  er interactively
0750: 20 28 66 6f 72 20 64 65 62 75 67 67 69 6e 67 29   (for debugging)
0760: 0a 0a 20 20 20 2d 2d 76 65 72 73 69 6f 6e 20 20  ..   --version  
0770: 20 20 53 68 6f 77 20 74 68 65 20 76 65 72 73 69    Show the versi
0780: 6f 6e 20 6e 75 6d 62 65 72 20 6f 66 20 53 51 4c  on number of SQL
0790: 69 74 65 0a 7d 0a 20 20 65 78 69 74 20 31 0a 7d  ite.}.  exit 1.}
07a0: 0a 73 65 74 20 66 69 6c 65 5f 74 6f 5f 61 6e 61  .set file_to_ana
07b0: 6c 79 7a 65 20 7b 7d 0a 73 65 74 20 66 6c 61 67  lyze {}.set flag
07c0: 73 28 2d 70 61 67 65 69 6e 66 6f 29 20 30 0a 73  s(-pageinfo) 0.s
07d0: 65 74 20 66 6c 61 67 73 28 2d 73 74 61 74 73 29  et flags(-stats)
07e0: 20 30 0a 73 65 74 20 66 6c 61 67 73 28 2d 64 65   0.set flags(-de
07f0: 62 75 67 29 20 30 0a 61 70 70 65 6e 64 20 61 72  bug) 0.append ar
0800: 67 76 20 7b 7d 0a 66 6f 72 65 61 63 68 20 61 72  gv {}.foreach ar
0810: 67 20 24 61 72 67 76 20 7b 0a 20 20 69 66 20 7b  g $argv {.  if {
0820: 5b 72 65 67 65 78 70 20 7b 5e 2d 2b 70 61 67 65  [regexp {^-+page
0830: 69 6e 66 6f 24 7d 20 24 61 72 67 5d 7d 20 7b 0a  info$} $arg]} {.
0840: 20 20 20 20 73 65 74 20 66 6c 61 67 73 28 2d 70      set flags(-p
0850: 61 67 65 69 6e 66 6f 29 20 31 0a 20 20 7d 20 65  ageinfo) 1.  } e
0860: 6c 73 65 69 66 20 7b 5b 72 65 67 65 78 70 20 7b  lseif {[regexp {
0870: 5e 2d 2b 73 74 61 74 73 24 7d 20 24 61 72 67 5d  ^-+stats$} $arg]
0880: 7d 20 7b 0a 20 20 20 20 73 65 74 20 66 6c 61 67  } {.    set flag
0890: 73 28 2d 73 74 61 74 73 29 20 31 0a 20 20 7d 20  s(-stats) 1.  } 
08a0: 65 6c 73 65 69 66 20 7b 5b 72 65 67 65 78 70 20  elseif {[regexp 
08b0: 7b 5e 2d 2b 64 65 62 75 67 24 7d 20 24 61 72 67  {^-+debug$} $arg
08c0: 5d 7d 20 7b 0a 20 20 20 20 73 65 74 20 66 6c 61  ]} {.    set fla
08d0: 67 73 28 2d 64 65 62 75 67 29 20 31 0a 20 20 7d  gs(-debug) 1.  }
08e0: 20 65 6c 73 65 69 66 20 7b 5b 72 65 67 65 78 70   elseif {[regexp
08f0: 20 7b 5e 2d 2b 74 63 6c 73 68 24 7d 20 24 61 72   {^-+tclsh$} $ar
0900: 67 5d 7d 20 7b 0a 20 20 20 20 74 63 6c 73 68 0a  g]} {.    tclsh.
0910: 20 20 20 20 65 78 69 74 20 30 0a 20 20 7d 20 65      exit 0.  } e
0920: 6c 73 65 69 66 20 7b 5b 72 65 67 65 78 70 20 7b  lseif {[regexp {
0930: 5e 2d 2b 76 65 72 73 69 6f 6e 24 7d 20 24 61 72  ^-+version$} $ar
0940: 67 5d 7d 20 7b 0a 20 20 20 20 73 71 6c 69 74 65  g]} {.    sqlite
0950: 33 20 6d 65 6d 20 3a 6d 65 6d 6f 72 79 3a 0a 20  3 mem :memory:. 
0960: 20 20 20 70 75 74 73 20 5b 6d 65 6d 20 6f 6e 65     puts [mem one
0970: 20 7b 53 45 4c 45 43 54 20 73 71 6c 69 74 65 5f   {SELECT sqlite_
0980: 76 65 72 73 69 6f 6e 28 29 7c 7c 27 20 27 7c 7c  version()||' '||
0990: 73 71 6c 69 74 65 5f 73 6f 75 72 63 65 5f 69 64  sqlite_source_id
09a0: 28 29 7d 5d 0a 20 20 20 20 6d 65 6d 20 63 6c 6f  ()}].    mem clo
09b0: 73 65 0a 20 20 20 20 65 78 69 74 20 30 0a 20 20  se.    exit 0.  
09c0: 7d 20 65 6c 73 65 69 66 20 7b 5b 72 65 67 65 78  } elseif {[regex
09d0: 70 20 7b 5e 2d 7d 20 24 61 72 67 5d 7d 20 7b 0a  p {^-} $arg]} {.
09e0: 20 20 20 20 70 75 74 73 20 73 74 64 65 72 72 20      puts stderr 
09f0: 22 55 6e 6b 6e 6f 77 6e 20 6f 70 74 69 6f 6e 3a  "Unknown option:
0a00: 20 24 61 72 67 22 0a 20 20 20 20 75 73 61 67 65   $arg".    usage
0a10: 0a 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 66 69  .  } elseif {$fi
0a20: 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 21 3d 22  le_to_analyze!="
0a30: 22 7d 20 7b 0a 20 20 20 20 75 73 61 67 65 0a 20  "} {.    usage. 
0a40: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65   } else {.    se
0a50: 74 20 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a  t file_to_analyz
0a60: 65 20 24 61 72 67 0a 20 20 7d 0a 7d 0a 69 66 20  e $arg.  }.}.if 
0a70: 7b 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a  {$file_to_analyz
0a80: 65 3d 3d 22 22 7d 20 75 73 61 67 65 0a 73 65 74  e==""} usage.set
0a90: 20 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d 65 20 24   root_filename $
0aa0: 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 0a  file_to_analyze.
0ab0: 72 65 67 65 78 70 20 7b 5e 66 69 6c 65 3a 28 2f  regexp {^file:(/
0ac0: 2f 29 3f 28 5b 5e 3f 5d 2a 29 7d 20 24 66 69 6c  /)?([^?]*)} $fil
0ad0: 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 20 61 6c 6c  e_to_analyze all
0ae0: 20 78 31 20 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d   x1 root_filenam
0af0: 65 0a 69 66 20 7b 21 5b 66 69 6c 65 20 65 78 69  e.if {![file exi
0b00: 73 74 73 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61  sts $root_filena
0b10: 6d 65 5d 7d 20 7b 0a 20 20 70 75 74 73 20 73 74  me]} {.  puts st
0b20: 64 65 72 72 20 22 4e 6f 20 73 75 63 68 20 66 69  derr "No such fi
0b30: 6c 65 3a 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61  le: $root_filena
0b40: 6d 65 22 0a 20 20 65 78 69 74 20 31 0a 7d 0a 69  me".  exit 1.}.i
0b50: 66 20 7b 21 5b 66 69 6c 65 20 72 65 61 64 61 62  f {![file readab
0b60: 6c 65 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d  le $root_filenam
0b70: 65 5d 7d 20 7b 0a 20 20 70 75 74 73 20 73 74 64  e]} {.  puts std
0b80: 65 72 72 20 22 46 69 6c 65 20 69 73 20 6e 6f 74  err "File is not
0b90: 20 72 65 61 64 61 62 6c 65 3a 20 24 72 6f 6f 74   readable: $root
0ba0: 5f 66 69 6c 65 6e 61 6d 65 22 0a 20 20 65 78 69  _filename".  exi
0bb0: 74 20 31 0a 7d 0a 73 65 74 20 74 72 75 65 5f 66  t 1.}.set true_f
0bc0: 69 6c 65 5f 73 69 7a 65 20 5b 66 69 6c 65 20 73  ile_size [file s
0bd0: 69 7a 65 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61  ize $root_filena
0be0: 6d 65 5d 0a 69 66 20 7b 24 74 72 75 65 5f 66 69  me].if {$true_fi
0bf0: 6c 65 5f 73 69 7a 65 3c 35 31 32 7d 20 7b 0a 20  le_size<512} {. 
0c00: 20 70 75 74 73 20 73 74 64 65 72 72 20 22 45 6d   puts stderr "Em
0c10: 70 74 79 20 6f 72 20 6d 61 6c 66 6f 72 6d 65 64  pty or malformed
0c20: 20 64 61 74 61 62 61 73 65 3a 20 24 72 6f 6f 74   database: $root
0c30: 5f 66 69 6c 65 6e 61 6d 65 22 0a 20 20 65 78 69  _filename".  exi
0c40: 74 20 31 0a 7d 0a 0a 23 20 43 6f 6d 70 75 74 65  t 1.}..# Compute
0c50: 20 74 68 65 20 74 6f 74 61 6c 20 66 69 6c 65 20   the total file 
0c60: 73 69 7a 65 20 61 73 73 75 6d 69 6e 67 20 74 65  size assuming te
0c70: 73 74 5f 6d 75 6c 74 69 70 6c 65 78 6f 72 20 69  st_multiplexor i
0c80: 73 20 62 65 69 6e 67 20 75 73 65 64 2e 0a 23 20  s being used..# 
0c90: 41 73 73 75 6d 65 20 74 68 61 74 20 53 51 4c 49  Assume that SQLI
0ca0: 54 45 5f 45 4e 41 42 4c 45 5f 38 5f 33 5f 4e 41  TE_ENABLE_8_3_NA
0cb0: 4d 45 53 20 6d 69 67 68 74 20 62 65 20 65 6e 61  MES might be ena
0cc0: 62 6c 65 64 0a 23 0a 73 65 74 20 65 78 74 65 6e  bled.#.set exten
0cd0: 73 69 6f 6e 20 5b 66 69 6c 65 20 65 78 74 65 6e  sion [file exten
0ce0: 73 69 6f 6e 20 24 72 6f 6f 74 5f 66 69 6c 65 6e  sion $root_filen
0cf0: 61 6d 65 5d 0a 73 65 74 20 70 61 74 74 65 72 6e  ame].set pattern
0d00: 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d 65 0a   $root_filename.
0d10: 61 70 70 65 6e 64 20 70 61 74 74 65 72 6e 20 7b  append pattern {
0d20: 5b 30 2d 33 5d 5b 30 2d 39 5d 5b 30 2d 39 5d 7d  [0-3][0-9][0-9]}
0d30: 0a 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62  .foreach f [glob
0d40: 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 24 70 61   -nocomplain $pa
0d50: 74 74 65 72 6e 5d 20 7b 0a 20 20 69 6e 63 72 20  ttern] {.  incr 
0d60: 74 72 75 65 5f 66 69 6c 65 5f 73 69 7a 65 20 5b  true_file_size [
0d70: 66 69 6c 65 20 73 69 7a 65 20 24 66 5d 0a 20 20  file size $f].  
0d80: 73 65 74 20 65 78 74 65 6e 73 69 6f 6e 20 7b 7d  set extension {}
0d90: 0a 7d 0a 69 66 20 7b 5b 73 74 72 69 6e 67 20 6c  .}.if {[string l
0da0: 65 6e 67 74 68 20 24 65 78 74 65 6e 73 69 6f 6e  ength $extension
0db0: 5d 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20  ]>=2 && [string 
0dc0: 6c 65 6e 67 74 68 20 24 65 78 74 65 6e 73 69 6f  length $extensio
0dd0: 6e 5d 3c 3d 34 7d 20 7b 0a 20 20 73 65 74 20 70  n]<=4} {.  set p
0de0: 61 74 74 65 72 6e 20 5b 66 69 6c 65 20 72 6f 6f  attern [file roo
0df0: 74 6e 61 6d 65 20 24 72 6f 6f 74 5f 66 69 6c 65  tname $root_file
0e00: 6e 61 6d 65 5d 0a 20 20 61 70 70 65 6e 64 20 70  name].  append p
0e10: 61 74 74 65 72 6e 20 7b 2e 5b 30 2d 33 5d 5b 30  attern {.[0-3][0
0e20: 2d 39 5d 5b 30 2d 39 5d 7d 0a 20 20 66 6f 72 65  -9][0-9]}.  fore
0e30: 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63  ach f [glob -noc
0e40: 6f 6d 70 6c 61 69 6e 20 24 70 61 74 74 65 72 6e  omplain $pattern
0e50: 5d 20 7b 0a 20 20 20 20 69 6e 63 72 20 74 72 75  ] {.    incr tru
0e60: 65 5f 66 69 6c 65 5f 73 69 7a 65 20 5b 66 69 6c  e_file_size [fil
0e70: 65 20 73 69 7a 65 20 24 66 5d 0a 20 20 7d 0a 7d  e size $f].  }.}
0e80: 0a 0a 23 20 4f 70 65 6e 20 74 68 65 20 64 61 74  ..# Open the dat
0e90: 61 62 61 73 65 0a 23 0a 69 66 20 7b 5b 63 61 74  abase.#.if {[cat
0ea0: 63 68 20 7b 73 71 6c 69 74 65 33 20 64 62 20 24  ch {sqlite3 db $
0eb0: 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 20  file_to_analyze 
0ec0: 2d 75 72 69 20 31 7d 20 6d 73 67 5d 7d 20 7b 0a  -uri 1} msg]} {.
0ed0: 20 20 70 75 74 73 20 73 74 64 65 72 72 20 22 65    puts stderr "e
0ee0: 72 72 6f 72 20 74 72 79 69 6e 67 20 74 6f 20 6f  rror trying to o
0ef0: 70 65 6e 20 24 66 69 6c 65 5f 74 6f 5f 61 6e 61  pen $file_to_ana
0f00: 6c 79 7a 65 3a 20 24 6d 73 67 22 0a 20 20 65 78  lyze: $msg".  ex
0f10: 69 74 20 31 0a 7d 0a 69 66 20 7b 24 66 6c 61 67  it 1.}.if {$flag
0f20: 73 28 2d 64 65 62 75 67 29 7d 20 7b 0a 20 20 70  s(-debug)} {.  p
0f30: 72 6f 63 20 64 62 74 72 61 63 65 20 7b 74 78 74  roc dbtrace {txt
0f40: 7d 20 7b 70 75 74 73 20 24 74 78 74 3b 20 66 6c  } {puts $txt; fl
0f50: 75 73 68 20 73 74 64 6f 75 74 3b 7d 0a 20 20 64  ush stdout;}.  d
0f60: 62 20 74 72 61 63 65 20 3a 3a 64 62 74 72 61 63  b trace ::dbtrac
0f70: 65 0a 7d 0a 0a 64 62 20 65 76 61 6c 20 7b 53 45  e.}..db eval {SE
0f80: 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 20 46 52  LECT count(*) FR
0f90: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
0fa0: 7d 0a 73 65 74 20 70 61 67 65 53 69 7a 65 20 5b  }.set pageSize [
0fb0: 65 78 70 72 20 7b 77 69 64 65 28 5b 64 62 20 6f  expr {wide([db o
0fc0: 6e 65 20 7b 50 52 41 47 4d 41 20 70 61 67 65 5f  ne {PRAGMA page_
0fd0: 73 69 7a 65 7d 5d 29 7d 5d 0a 0a 69 66 20 7b 24  size}])}]..if {$
0fe0: 66 6c 61 67 73 28 2d 70 61 67 65 69 6e 66 6f 29  flags(-pageinfo)
0ff0: 7d 20 7b 0a 20 20 64 62 20 65 76 61 6c 20 7b 43  } {.  db eval {C
1000: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41  REATE VIRTUAL TA
1010: 42 4c 45 20 74 65 6d 70 2e 73 74 61 74 20 55 53  BLE temp.stat US
1020: 49 4e 47 20 64 62 73 74 61 74 7d 0a 20 20 64 62  ING dbstat}.  db
1030: 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 6e 61   eval {SELECT na
1040: 6d 65 2c 20 70 61 74 68 2c 20 70 61 67 65 6e 6f  me, path, pageno
1050: 20 46 52 4f 4d 20 74 65 6d 70 2e 73 74 61 74 20   FROM temp.stat 
1060: 4f 52 44 45 52 20 42 59 20 70 61 67 65 6e 6f 7d  ORDER BY pageno}
1070: 20 7b 0a 20 20 20 20 70 75 74 73 20 22 24 70 61   {.    puts "$pa
1080: 67 65 6e 6f 20 24 6e 61 6d 65 20 24 70 61 74 68  geno $name $path
1090: 22 0a 20 20 7d 0a 20 20 65 78 69 74 20 30 0a 7d  ".  }.  exit 0.}
10a0: 0a 69 66 20 7b 24 66 6c 61 67 73 28 2d 73 74 61  .if {$flags(-sta
10b0: 74 73 29 7d 20 7b 0a 20 20 64 62 20 65 76 61 6c  ts)} {.  db eval
10c0: 20 7b 43 52 45 41 54 45 20 56 49 52 54 55 41 4c   {CREATE VIRTUAL
10d0: 20 54 41 42 4c 45 20 74 65 6d 70 2e 73 74 61 74   TABLE temp.stat
10e0: 20 55 53 49 4e 47 20 64 62 73 74 61 74 7d 0a 20   USING dbstat}. 
10f0: 20 70 75 74 73 20 22 42 45 47 49 4e 3b 22 0a 20   puts "BEGIN;". 
1100: 20 70 75 74 73 20 22 43 52 45 41 54 45 20 54 41   puts "CREATE TA
1110: 42 4c 45 20 73 74 61 74 73 28 22 0a 20 20 70 75  BLE stats(".  pu
1120: 74 73 20 22 20 20 6e 61 6d 65 20 20 20 20 20 20  ts "  name      
1130: 20 53 54 52 49 4e 47 2c 20 20 20 20 20 20 20 20   STRING,        
1140: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 61     /* Name of ta
1150: 62 6c 65 20 6f 72 20 69 6e 64 65 78 20 2a 2f 22  ble or index */"
1160: 0a 20 20 70 75 74 73 20 22 20 20 70 61 74 68 20  .  puts "  path 
1170: 20 20 20 20 20 20 49 4e 54 45 47 45 52 2c 20 20        INTEGER,  
1180: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 74 68 20          /* Path 
1190: 74 6f 20 70 61 67 65 20 66 72 6f 6d 20 72 6f 6f  to page from roo
11a0: 74 20 2a 2f 22 0a 20 20 70 75 74 73 20 22 20 20  t */".  puts "  
11b0: 70 61 67 65 6e 6f 20 20 20 20 20 49 4e 54 45 47  pageno     INTEG
11c0: 45 52 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ER,          /* 
11d0: 50 61 67 65 20 6e 75 6d 62 65 72 20 2a 2f 22 0a  Page number */".
11e0: 20 20 70 75 74 73 20 22 20 20 70 61 67 65 74 79    puts "  pagety
11f0: 70 65 20 20 20 53 54 52 49 4e 47 2c 20 20 20 20  pe   STRING,    
1200: 20 20 20 20 20 20 20 2f 2a 20 27 69 6e 74 65 72         /* 'inter
1210: 6e 61 6c 27 2c 20 27 6c 65 61 66 27 20 6f 72 20  nal', 'leaf' or 
1220: 27 6f 76 65 72 66 6c 6f 77 27 20 2a 2f 22 0a 20  'overflow' */". 
1230: 20 70 75 74 73 20 22 20 20 6e 63 65 6c 6c 20 20   puts "  ncell  
1240: 20 20 20 20 49 4e 54 45 47 45 52 2c 20 20 20 20      INTEGER,    
1250: 20 20 20 20 20 20 2f 2a 20 43 65 6c 6c 73 20 6f        /* Cells o
1260: 6e 20 70 61 67 65 20 28 30 20 66 6f 72 20 6f 76  n page (0 for ov
1270: 65 72 66 6c 6f 77 29 20 2a 2f 22 0a 20 20 70 75  erflow) */".  pu
1280: 74 73 20 22 20 20 70 61 79 6c 6f 61 64 20 20 20  ts "  payload   
1290: 20 49 4e 54 45 47 45 52 2c 20 20 20 20 20 20 20   INTEGER,       
12a0: 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 70     /* Bytes of p
12b0: 61 79 6c 6f 61 64 20 6f 6e 20 74 68 69 73 20 70  ayload on this p
12c0: 61 67 65 20 2a 2f 22 0a 20 20 70 75 74 73 20 22  age */".  puts "
12d0: 20 20 75 6e 75 73 65 64 20 20 20 20 20 49 4e 54    unused     INT
12e0: 45 47 45 52 2c 20 20 20 20 20 20 20 20 20 20 2f  EGER,          /
12f0: 2a 20 42 79 74 65 73 20 6f 66 20 75 6e 75 73 65  * Bytes of unuse
1300: 64 20 73 70 61 63 65 20 6f 6e 20 74 68 69 73 20  d space on this 
1310: 70 61 67 65 20 2a 2f 22 0a 20 20 70 75 74 73 20  page */".  puts 
1320: 22 20 20 6d 78 5f 70 61 79 6c 6f 61 64 20 49 4e  "  mx_payload IN
1330: 54 45 47 45 52 2c 20 20 20 20 20 20 20 20 20 20  TEGER,          
1340: 2f 2a 20 4c 61 72 67 65 73 74 20 70 61 79 6c 6f  /* Largest paylo
1350: 61 64 20 73 69 7a 65 20 6f 66 20 61 6c 6c 20 63  ad size of all c
1360: 65 6c 6c 73 20 2a 2f 22 0a 20 20 70 75 74 73 20  ells */".  puts 
1370: 22 20 20 70 67 6f 66 66 73 65 74 20 20 20 49 4e  "  pgoffset   IN
1380: 54 45 47 45 52 2c 20 20 20 20 20 20 20 20 20 20  TEGER,          
1390: 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20 70 61 67  /* Offset of pag
13a0: 65 20 69 6e 20 66 69 6c 65 20 2a 2f 22 0a 20 20  e in file */".  
13b0: 70 75 74 73 20 22 20 20 70 67 73 69 7a 65 20 20  puts "  pgsize  
13c0: 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 20 20     INTEGER      
13d0: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
13e0: 74 68 65 20 70 61 67 65 20 2a 2f 22 0a 20 20 70  the page */".  p
13f0: 75 74 73 20 22 29 3b 22 0a 20 20 64 62 20 65 76  uts ");".  db ev
1400: 61 6c 20 7b 53 45 4c 45 43 54 20 71 75 6f 74 65  al {SELECT quote
1410: 28 6e 61 6d 65 29 20 7c 7c 20 27 2c 27 20 7c 7c  (name) || ',' ||
1420: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1430: 20 20 20 71 75 6f 74 65 28 70 61 74 68 29 20 7c     quote(path) |
1440: 7c 20 27 2c 27 20 7c 7c 0a 20 20 20 20 20 20 20  | ',' ||.       
1450: 20 20 20 20 20 20 20 20 20 20 20 71 75 6f 74 65             quote
1460: 28 70 61 67 65 6e 6f 29 20 7c 7c 20 27 2c 27 20  (pageno) || ',' 
1470: 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ||.             
1480: 20 20 20 20 20 71 75 6f 74 65 28 70 61 67 65 74       quote(paget
1490: 79 70 65 29 20 7c 7c 20 27 2c 27 20 7c 7c 0a 20  ype) || ',' ||. 
14a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14b0: 20 71 75 6f 74 65 28 6e 63 65 6c 6c 29 20 7c 7c   quote(ncell) ||
14c0: 20 27 2c 27 20 7c 7c 0a 20 20 20 20 20 20 20 20   ',' ||.        
14d0: 20 20 20 20 20 20 20 20 20 20 71 75 6f 74 65 28            quote(
14e0: 70 61 79 6c 6f 61 64 29 20 7c 7c 20 27 2c 27 20  payload) || ',' 
14f0: 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ||.             
1500: 20 20 20 20 20 71 75 6f 74 65 28 75 6e 75 73 65       quote(unuse
1510: 64 29 20 7c 7c 20 27 2c 27 20 7c 7c 0a 20 20 20  d) || ',' ||.   
1520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 71                 q
1530: 75 6f 74 65 28 6d 78 5f 70 61 79 6c 6f 61 64 29  uote(mx_payload)
1540: 20 7c 7c 20 27 2c 27 20 7c 7c 0a 20 20 20 20 20   || ',' ||.     
1550: 20 20 20 20 20 20 20 20 20 20 20 20 20 71 75 6f               quo
1560: 74 65 28 70 67 6f 66 66 73 65 74 29 20 7c 7c 20  te(pgoffset) || 
1570: 27 2c 27 20 7c 7c 0a 20 20 20 20 20 20 20 20 20  ',' ||.         
1580: 20 20 20 20 20 20 20 20 20 71 75 6f 74 65 28 70           quote(p
1590: 67 73 69 7a 65 29 20 41 53 20 78 20 46 52 4f 4d  gsize) AS x FROM
15a0: 20 73 74 61 74 7d 20 7b 0a 20 20 20 20 70 75 74   stat} {.    put
15b0: 73 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 73  s "INSERT INTO s
15c0: 74 61 74 73 20 56 41 4c 55 45 53 28 24 78 29 3b  tats VALUES($x);
15d0: 22 0a 20 20 7d 0a 20 20 70 75 74 73 20 22 43 4f  ".  }.  puts "CO
15e0: 4d 4d 49 54 3b 22 0a 20 20 65 78 69 74 20 30 0a  MMIT;".  exit 0.
15f0: 7d 0a 0a 0a 23 20 49 6e 2d 6d 65 6d 6f 72 79 20  }...# In-memory 
1600: 64 61 74 61 62 61 73 65 20 66 6f 72 20 63 6f 6c  database for col
1610: 6c 65 63 74 69 6e 67 20 73 74 61 74 69 73 74 69  lecting statisti
1620: 63 73 2e 20 54 68 69 73 20 73 63 72 69 70 74 20  cs. This script 
1630: 6c 6f 6f 70 73 20 74 68 72 6f 75 67 68 0a 23 20  loops through.# 
1640: 74 68 65 20 74 61 62 6c 65 73 20 61 6e 64 20 69  the tables and i
1650: 6e 64 69 63 65 73 20 69 6e 20 74 68 65 20 64 61  ndices in the da
1660: 74 61 62 61 73 65 20 62 65 69 6e 67 20 61 6e 61  tabase being ana
1670: 6c 79 7a 65 64 2c 20 61 64 64 69 6e 67 20 61 20  lyzed, adding a 
1680: 72 6f 77 20 66 6f 72 20 65 61 63 68 0a 23 20 74  row for each.# t
1690: 6f 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20 64  o an in-memory d
16a0: 61 74 61 62 61 73 65 20 28 66 6f 72 20 77 68 69  atabase (for whi
16b0: 63 68 20 74 68 65 20 73 63 68 65 6d 61 20 69 73  ch the schema is
16c0: 20 73 68 6f 77 6e 20 62 65 6c 6f 77 29 2e 20 49   shown below). I
16d0: 74 20 74 68 65 6e 0a 23 20 71 75 65 72 69 65 73  t then.# queries
16e0: 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 64   the in-memory d
16f0: 62 20 74 6f 20 70 72 6f 64 75 63 65 20 74 68 65  b to produce the
1700: 20 73 70 61 63 65 2d 61 6e 61 6c 79 73 69 73 20   space-analysis 
1710: 72 65 70 6f 72 74 2e 0a 23 0a 73 71 6c 69 74 65  report..#.sqlite
1720: 33 20 6d 65 6d 20 3a 6d 65 6d 6f 72 79 3a 0a 69  3 mem :memory:.i
1730: 66 20 7b 24 66 6c 61 67 73 28 2d 64 65 62 75 67  f {$flags(-debug
1740: 29 7d 20 7b 0a 20 20 70 72 6f 63 20 64 62 74 72  )} {.  proc dbtr
1750: 61 63 65 20 7b 74 78 74 7d 20 7b 70 75 74 73 20  ace {txt} {puts 
1760: 24 74 78 74 3b 20 66 6c 75 73 68 20 73 74 64 6f  $txt; flush stdo
1770: 75 74 3b 7d 0a 20 20 6d 65 6d 20 74 72 61 63 65  ut;}.  mem trace
1780: 20 3a 3a 64 62 74 72 61 63 65 0a 7d 0a 73 65 74   ::dbtrace.}.set
1790: 20 74 61 62 6c 65 64 65 66 20 7b 43 52 45 41 54   tabledef {CREAT
17a0: 45 20 54 41 42 4c 45 20 73 70 61 63 65 5f 75 73  E TABLE space_us
17b0: 65 64 28 0a 20 20 20 6e 61 6d 65 20 63 6c 6f 62  ed(.   name clob
17c0: 2c 20 20 20 20 20 20 20 20 2d 2d 20 4e 61 6d 65  ,        -- Name
17d0: 20 6f 66 20 61 20 74 61 62 6c 65 20 6f 72 20 69   of a table or i
17e0: 6e 64 65 78 20 69 6e 20 74 68 65 20 64 61 74 61  ndex in the data
17f0: 62 61 73 65 20 66 69 6c 65 0a 20 20 20 74 62 6c  base file.   tbl
1800: 6e 61 6d 65 20 63 6c 6f 62 2c 20 20 20 20 20 2d  name clob,     -
1810: 2d 20 4e 61 6d 65 20 6f 66 20 61 73 73 6f 63 69  - Name of associ
1820: 61 74 65 64 20 74 61 62 6c 65 0a 20 20 20 69 73  ated table.   is
1830: 5f 69 6e 64 65 78 20 62 6f 6f 6c 65 61 6e 2c 20  _index boolean, 
1840: 2d 2d 20 54 52 55 45 20 69 66 20 69 74 20 69 73  -- TRUE if it is
1850: 20 61 6e 20 69 6e 64 65 78 2c 20 66 61 6c 73 65   an index, false
1860: 20 66 6f 72 20 61 20 74 61 62 6c 65 0a 20 20 20   for a table.   
1870: 69 73 5f 77 69 74 68 6f 75 74 5f 72 6f 77 69 64  is_without_rowid
1880: 20 62 6f 6f 6c 65 61 6e 2c 20 2d 2d 20 54 52 55   boolean, -- TRU
1890: 45 20 69 66 20 57 49 54 48 4f 55 54 20 52 4f 57  E if WITHOUT ROW
18a0: 49 44 20 74 61 62 6c 65 20 20 0a 20 20 20 6e 65  ID table  .   ne
18b0: 6e 74 72 79 20 69 6e 74 2c 20 20 20 20 20 20 20  ntry int,       
18c0: 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74  -- Number of ent
18d0: 72 69 65 73 20 69 6e 20 74 68 65 20 42 54 72 65  ries in the BTre
18e0: 65 0a 20 20 20 6c 65 61 66 5f 65 6e 74 72 69 65  e.   leaf_entrie
18f0: 73 20 69 6e 74 2c 20 2d 2d 20 4e 75 6d 62 65 72  s int, -- Number
1900: 20 6f 66 20 6c 65 61 66 20 65 6e 74 72 69 65 73   of leaf entries
1910: 0a 20 20 20 64 65 70 74 68 20 69 6e 74 2c 20 20  .   depth int,  
1920: 20 20 20 20 20 20 2d 2d 20 44 65 70 74 68 20 6f        -- Depth o
1930: 66 20 74 68 65 20 62 2d 74 72 65 65 0a 20 20 20  f the b-tree.   
1940: 70 61 79 6c 6f 61 64 20 69 6e 74 2c 20 20 20 20  payload int,    
1950: 20 20 2d 2d 20 54 6f 74 61 6c 20 61 6d 6f 75 6e    -- Total amoun
1960: 74 20 6f 66 20 64 61 74 61 20 73 74 6f 72 65 64  t of data stored
1970: 20 69 6e 20 74 68 69 73 20 74 61 62 6c 65 20 6f   in this table o
1980: 72 20 69 6e 64 65 78 0a 20 20 20 6f 76 66 6c 5f  r index.   ovfl_
1990: 70 61 79 6c 6f 61 64 20 69 6e 74 2c 20 2d 2d 20  payload int, -- 
19a0: 54 6f 74 61 6c 20 61 6d 6f 75 6e 74 20 6f 66 20  Total amount of 
19b0: 64 61 74 61 20 73 74 6f 72 65 64 20 6f 6e 20 6f  data stored on o
19c0: 76 65 72 66 6c 6f 77 20 70 61 67 65 73 0a 20 20  verflow pages.  
19d0: 20 6f 76 66 6c 5f 63 6e 74 20 69 6e 74 2c 20 20   ovfl_cnt int,  
19e0: 20 20 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20     -- Number of 
19f0: 65 6e 74 72 69 65 73 20 74 68 61 74 20 75 73 65  entries that use
1a00: 20 6f 76 65 72 66 6c 6f 77 0a 20 20 20 6d 78 5f   overflow.   mx_
1a10: 70 61 79 6c 6f 61 64 20 69 6e 74 2c 20 20 20 2d  payload int,   -
1a20: 2d 20 4d 61 78 69 6d 75 6d 20 70 61 79 6c 6f 61  - Maximum payloa
1a30: 64 20 73 69 7a 65 0a 20 20 20 69 6e 74 5f 70 61  d size.   int_pa
1a40: 67 65 73 20 69 6e 74 2c 20 20 20 20 2d 2d 20 4e  ges int,    -- N
1a50: 75 6d 62 65 72 20 6f 66 20 69 6e 74 65 72 69 6f  umber of interio
1a60: 72 20 70 61 67 65 73 20 75 73 65 64 0a 20 20 20  r pages used.   
1a70: 6c 65 61 66 5f 70 61 67 65 73 20 69 6e 74 2c 20  leaf_pages int, 
1a80: 20 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 6c    -- Number of l
1a90: 65 61 66 20 70 61 67 65 73 20 75 73 65 64 0a 20  eaf pages used. 
1aa0: 20 20 6f 76 66 6c 5f 70 61 67 65 73 20 69 6e 74    ovfl_pages int
1ab0: 2c 20 20 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66  ,   -- Number of
1ac0: 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 20   overflow pages 
1ad0: 75 73 65 64 0a 20 20 20 69 6e 74 5f 75 6e 75 73  used.   int_unus
1ae0: 65 64 20 69 6e 74 2c 20 20 20 2d 2d 20 4e 75 6d  ed int,   -- Num
1af0: 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79  ber of unused by
1b00: 74 65 73 20 6f 6e 20 69 6e 74 65 72 69 6f 72 20  tes on interior 
1b10: 70 61 67 65 73 0a 20 20 20 6c 65 61 66 5f 75 6e  pages.   leaf_un
1b20: 75 73 65 64 20 69 6e 74 2c 20 20 2d 2d 20 4e 75  used int,  -- Nu
1b30: 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62  mber of unused b
1b40: 79 74 65 73 20 6f 6e 20 70 72 69 6d 61 72 79 20  ytes on primary 
1b50: 70 61 67 65 73 0a 20 20 20 6f 76 66 6c 5f 75 6e  pages.   ovfl_un
1b60: 75 73 65 64 20 69 6e 74 2c 20 20 2d 2d 20 4e 75  used int,  -- Nu
1b70: 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62  mber of unused b
1b80: 79 74 65 73 20 6f 6e 20 6f 76 65 72 66 6c 6f 77  ytes on overflow
1b90: 20 70 61 67 65 73 0a 20 20 20 67 61 70 5f 63 6e   pages.   gap_cn
1ba0: 74 20 69 6e 74 2c 20 20 20 20 20 20 2d 2d 20 4e  t int,      -- N
1bb0: 75 6d 62 65 72 20 6f 66 20 67 61 70 73 20 69 6e  umber of gaps in
1bc0: 20 74 68 65 20 70 61 67 65 20 6c 61 79 6f 75 74   the page layout
1bd0: 0a 20 20 20 63 6f 6d 70 72 65 73 73 65 64 5f 73  .   compressed_s
1be0: 69 7a 65 20 69 6e 74 20 20 2d 2d 20 54 6f 74 61  ize int  -- Tota
1bf0: 6c 20 62 79 74 65 73 20 73 74 6f 72 65 64 20 6f  l bytes stored o
1c00: 6e 20 64 69 73 6b 0a 29 3b 7d 0a 6d 65 6d 20 65  n disk.);}.mem e
1c10: 76 61 6c 20 24 74 61 62 6c 65 64 65 66 0a 0a 23  val $tabledef..#
1c20: 20 43 72 65 61 74 65 20 61 20 74 65 6d 70 6f 72   Create a tempor
1c30: 61 72 79 20 22 64 62 73 74 61 74 22 20 76 69 72  ary "dbstat" vir
1c40: 74 75 61 6c 20 74 61 62 6c 65 2e 0a 23 0a 64 62  tual table..#.db
1c50: 20 65 76 61 6c 20 7b 43 52 45 41 54 45 20 56 49   eval {CREATE VI
1c60: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 65 6d 70  RTUAL TABLE temp
1c70: 2e 73 74 61 74 20 55 53 49 4e 47 20 64 62 73 74  .stat USING dbst
1c80: 61 74 7d 0a 64 62 20 65 76 61 6c 20 7b 43 52 45  at}.db eval {CRE
1c90: 41 54 45 20 54 45 4d 50 20 54 41 42 4c 45 20 64  ATE TEMP TABLE d
1ca0: 62 73 74 61 74 20 41 53 20 53 45 4c 45 43 54 20  bstat AS SELECT 
1cb0: 2a 20 46 52 4f 4d 20 74 65 6d 70 2e 73 74 61 74  * FROM temp.stat
1cc0: 0a 20 20 20 20 20 20 20 20 20 4f 52 44 45 52 20  .         ORDER 
1cd0: 42 59 20 6e 61 6d 65 2c 20 70 61 74 68 7d 0a 64  BY name, path}.d
1ce0: 62 20 65 76 61 6c 20 7b 44 52 4f 50 20 54 41 42  b eval {DROP TAB
1cf0: 4c 45 20 74 65 6d 70 2e 73 74 61 74 7d 0a 0a 73  LE temp.stat}..s
1d00: 65 74 20 69 73 43 6f 6d 70 72 65 73 73 65 64 20  et isCompressed 
1d10: 30 0a 73 65 74 20 63 6f 6d 70 72 65 73 73 4f 76  0.set compressOv
1d20: 65 72 68 65 61 64 20 30 0a 73 65 74 20 64 65 70  erhead 0.set dep
1d30: 74 68 20 30 0a 73 65 74 20 73 71 6c 20 7b 20 53  th 0.set sql { S
1d40: 45 4c 45 43 54 20 6e 61 6d 65 2c 20 74 62 6c 5f  ELECT name, tbl_
1d50: 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65  name FROM sqlite
1d60: 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 72 6f  _master WHERE ro
1d70: 6f 74 70 61 67 65 3e 30 20 7d 0a 66 6f 72 65 61  otpage>0 }.forea
1d80: 63 68 20 7b 6e 61 6d 65 20 74 62 6c 6e 61 6d 65  ch {name tblname
1d90: 7d 20 5b 63 6f 6e 63 61 74 20 73 71 6c 69 74 65  } [concat sqlite
1da0: 5f 6d 61 73 74 65 72 20 73 71 6c 69 74 65 5f 6d  _master sqlite_m
1db0: 61 73 74 65 72 20 5b 64 62 20 65 76 61 6c 20 24  aster [db eval $
1dc0: 73 71 6c 5d 5d 20 7b 0a 0a 20 20 73 65 74 20 69  sql]] {..  set i
1dd0: 73 5f 69 6e 64 65 78 20 5b 65 78 70 72 20 7b 24  s_index [expr {$
1de0: 6e 61 6d 65 21 3d 24 74 62 6c 6e 61 6d 65 7d 5d  name!=$tblname}]
1df0: 0a 20 20 73 65 74 20 69 73 5f 77 69 74 68 6f 75  .  set is_withou
1e00: 74 5f 72 6f 77 69 64 20 5b 69 73 5f 77 69 74 68  t_rowid [is_with
1e10: 6f 75 74 5f 72 6f 77 69 64 20 24 6e 61 6d 65 5d  out_rowid $name]
1e20: 0a 20 20 64 62 20 65 76 61 6c 20 7b 0a 20 20 20  .  db eval {.   
1e30: 20 53 45 4c 45 43 54 20 0a 20 20 20 20 20 20 73   SELECT .      s
1e40: 75 6d 28 6e 63 65 6c 6c 29 20 41 53 20 6e 65 6e  um(ncell) AS nen
1e50: 74 72 79 2c 0a 20 20 20 20 20 20 73 75 6d 28 28  try,.      sum((
1e60: 70 61 67 65 74 79 70 65 3d 3d 27 6c 65 61 66 27  pagetype=='leaf'
1e70: 29 2a 6e 63 65 6c 6c 29 20 41 53 20 6c 65 61 66  )*ncell) AS leaf
1e80: 5f 65 6e 74 72 69 65 73 2c 0a 20 20 20 20 20 20  _entries,.      
1e90: 73 75 6d 28 70 61 79 6c 6f 61 64 29 20 41 53 20  sum(payload) AS 
1ea0: 70 61 79 6c 6f 61 64 2c 0a 20 20 20 20 20 20 73  payload,.      s
1eb0: 75 6d 28 28 70 61 67 65 74 79 70 65 3d 3d 27 6f  um((pagetype=='o
1ec0: 76 65 72 66 6c 6f 77 27 29 20 2a 20 70 61 79 6c  verflow') * payl
1ed0: 6f 61 64 29 20 41 53 20 6f 76 66 6c 5f 70 61 79  oad) AS ovfl_pay
1ee0: 6c 6f 61 64 2c 0a 20 20 20 20 20 20 73 75 6d 28  load,.      sum(
1ef0: 70 61 74 68 20 4c 49 4b 45 20 27 25 2b 30 30 30  path LIKE '%+000
1f00: 30 30 30 27 29 20 41 53 20 6f 76 66 6c 5f 63 6e  000') AS ovfl_cn
1f10: 74 2c 0a 20 20 20 20 20 20 6d 61 78 28 6d 78 5f  t,.      max(mx_
1f20: 70 61 79 6c 6f 61 64 29 20 41 53 20 6d 78 5f 70  payload) AS mx_p
1f30: 61 79 6c 6f 61 64 2c 0a 20 20 20 20 20 20 73 75  ayload,.      su
1f40: 6d 28 70 61 67 65 74 79 70 65 3d 3d 27 69 6e 74  m(pagetype=='int
1f50: 65 72 6e 61 6c 27 29 20 41 53 20 69 6e 74 5f 70  ernal') AS int_p
1f60: 61 67 65 73 2c 0a 20 20 20 20 20 20 73 75 6d 28  ages,.      sum(
1f70: 70 61 67 65 74 79 70 65 3d 3d 27 6c 65 61 66 27  pagetype=='leaf'
1f80: 29 20 41 53 20 6c 65 61 66 5f 70 61 67 65 73 2c  ) AS leaf_pages,
1f90: 0a 20 20 20 20 20 20 73 75 6d 28 70 61 67 65 74  .      sum(paget
1fa0: 79 70 65 3d 3d 27 6f 76 65 72 66 6c 6f 77 27 29  ype=='overflow')
1fb0: 20 41 53 20 6f 76 66 6c 5f 70 61 67 65 73 2c 0a   AS ovfl_pages,.
1fc0: 20 20 20 20 20 20 73 75 6d 28 28 70 61 67 65 74        sum((paget
1fd0: 79 70 65 3d 3d 27 69 6e 74 65 72 6e 61 6c 27 29  ype=='internal')
1fe0: 20 2a 20 75 6e 75 73 65 64 29 20 41 53 20 69 6e   * unused) AS in
1ff0: 74 5f 75 6e 75 73 65 64 2c 0a 20 20 20 20 20 20  t_unused,.      
2000: 73 75 6d 28 28 70 61 67 65 74 79 70 65 3d 3d 27  sum((pagetype=='
2010: 6c 65 61 66 27 29 20 2a 20 75 6e 75 73 65 64 29  leaf') * unused)
2020: 20 41 53 20 6c 65 61 66 5f 75 6e 75 73 65 64 2c   AS leaf_unused,
2030: 0a 20 20 20 20 20 20 73 75 6d 28 28 70 61 67 65  .      sum((page
2040: 74 79 70 65 3d 3d 27 6f 76 65 72 66 6c 6f 77 27  type=='overflow'
2050: 29 20 2a 20 75 6e 75 73 65 64 29 20 41 53 20 6f  ) * unused) AS o
2060: 76 66 6c 5f 75 6e 75 73 65 64 2c 0a 20 20 20 20  vfl_unused,.    
2070: 20 20 73 75 6d 28 70 67 73 69 7a 65 29 20 41 53    sum(pgsize) AS
2080: 20 63 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a 65   compressed_size
2090: 2c 0a 20 20 20 20 20 20 6d 61 78 28 28 6c 65 6e  ,.      max((len
20a0: 67 74 68 28 43 41 53 45 20 57 48 45 4e 20 70 61  gth(CASE WHEN pa
20b0: 74 68 20 4c 49 4b 45 20 27 25 2b 25 27 20 54 48  th LIKE '%+%' TH
20c0: 45 4e 20 27 27 20 45 4c 53 45 20 70 61 74 68 20  EN '' ELSE path 
20d0: 45 4e 44 29 2b 33 29 2f 34 29 0a 20 20 20 20 20  END)+3)/4).     
20e0: 20 20 20 41 53 20 64 65 70 74 68 0a 20 20 20 20     AS depth.    
20f0: 46 52 4f 4d 20 74 65 6d 70 2e 64 62 73 74 61 74  FROM temp.dbstat
2100: 20 57 48 45 52 45 20 6e 61 6d 65 20 3d 20 24 6e   WHERE name = $n
2110: 61 6d 65 0a 20 20 7d 20 62 72 65 61 6b 0a 0a 20  ame.  } break.. 
2120: 20 73 65 74 20 74 6f 74 61 6c 5f 70 61 67 65 73   set total_pages
2130: 20 5b 65 78 70 72 20 7b 24 6c 65 61 66 5f 70 61   [expr {$leaf_pa
2140: 67 65 73 2b 24 69 6e 74 5f 70 61 67 65 73 2b 24  ges+$int_pages+$
2150: 6f 76 66 6c 5f 70 61 67 65 73 7d 5d 0a 20 20 73  ovfl_pages}].  s
2160: 65 74 20 73 74 6f 72 61 67 65 20 5b 65 78 70 72  et storage [expr
2170: 20 7b 24 74 6f 74 61 6c 5f 70 61 67 65 73 2a 24   {$total_pages*$
2180: 70 61 67 65 53 69 7a 65 7d 5d 0a 20 20 69 66 20  pageSize}].  if 
2190: 7b 21 24 69 73 43 6f 6d 70 72 65 73 73 65 64 20  {!$isCompressed 
21a0: 26 26 20 24 73 74 6f 72 61 67 65 3e 24 63 6f 6d  && $storage>$com
21b0: 70 72 65 73 73 65 64 5f 73 69 7a 65 7d 20 7b 0a  pressed_size} {.
21c0: 20 20 20 20 73 65 74 20 69 73 43 6f 6d 70 72 65      set isCompre
21d0: 73 73 65 64 20 31 0a 20 20 20 20 73 65 74 20 63  ssed 1.    set c
21e0: 6f 6d 70 72 65 73 73 4f 76 65 72 68 65 61 64 20  ompressOverhead 
21f0: 31 34 0a 20 20 7d 0a 0a 20 20 23 20 43 6f 6c 75  14.  }..  # Colu
2200: 6d 6e 20 27 67 61 70 5f 63 6e 74 27 20 69 73 20  mn 'gap_cnt' is 
2210: 73 65 74 20 74 6f 20 74 68 65 20 6e 75 6d 62 65  set to the numbe
2220: 72 20 6f 66 20 6e 6f 6e 2d 63 6f 6e 74 69 67 75  r of non-contigu
2230: 6f 75 73 20 65 6e 74 72 69 65 73 20 69 6e 20 74  ous entries in t
2240: 68 65 0a 20 20 23 20 6c 69 73 74 20 6f 66 20 70  he.  # list of p
2250: 61 67 65 73 20 76 69 73 69 74 65 64 20 69 66 20  ages visited if 
2260: 74 68 65 20 62 2d 74 72 65 65 20 73 74 72 75 63  the b-tree struc
2270: 74 75 72 65 20 69 73 20 74 72 61 76 65 72 73 65  ture is traverse
2280: 64 20 69 6e 20 61 20 74 6f 70 2d 64 6f 77 6e 0a  d in a top-down.
2290: 20 20 23 20 66 61 73 68 69 6f 6e 20 28 65 61 63    # fashion (eac
22a0: 68 20 6e 6f 64 65 20 76 69 73 69 74 65 64 20 62  h node visited b
22b0: 65 66 6f 72 65 20 69 74 73 20 63 68 69 6c 64 2d  efore its child-
22c0: 74 72 65 65 20 69 73 20 70 61 73 73 65 64 29 2e  tree is passed).
22d0: 20 41 6e 79 20 6f 76 65 72 66 6c 6f 77 0a 20 20   Any overflow.  
22e0: 23 20 63 68 61 69 6e 73 20 70 72 65 73 65 6e 74  # chains present
22f0: 20 61 72 65 20 74 72 61 76 65 72 73 65 64 20 66   are traversed f
2300: 72 6f 6d 20 73 74 61 72 74 20 74 6f 20 66 69 6e  rom start to fin
2310: 69 73 68 20 62 65 66 6f 72 65 20 61 6e 79 20 63  ish before any c
2320: 68 69 6c 64 2d 74 72 65 65 0a 20 20 23 20 69 73  hild-tree.  # is
2330: 2e 0a 20 20 23 0a 20 20 73 65 74 20 67 61 70 5f  ..  #.  set gap_
2340: 63 6e 74 20 30 0a 20 20 73 65 74 20 70 72 65 76  cnt 0.  set prev
2350: 20 30 0a 20 20 64 62 20 65 76 61 6c 20 7b 0a 20   0.  db eval {. 
2360: 20 20 20 53 45 4c 45 43 54 20 70 61 67 65 6e 6f     SELECT pageno
2370: 2c 20 70 61 67 65 74 79 70 65 20 46 52 4f 4d 20  , pagetype FROM 
2380: 74 65 6d 70 2e 64 62 73 74 61 74 0a 20 20 20 20  temp.dbstat.    
2390: 20 57 48 45 52 45 20 6e 61 6d 65 3d 24 6e 61 6d   WHERE name=$nam
23a0: 65 0a 20 20 20 20 20 4f 52 44 45 52 20 42 59 20  e.     ORDER BY 
23b0: 70 61 67 65 6e 6f 0a 20 20 7d 20 7b 0a 20 20 20  pageno.  } {.   
23c0: 20 69 66 20 7b 24 70 72 65 76 3e 30 20 26 26 20   if {$prev>0 && 
23d0: 24 70 61 67 65 74 79 70 65 3d 3d 22 6c 65 61 66  $pagetype=="leaf
23e0: 22 20 26 26 20 24 70 61 67 65 6e 6f 21 3d 24 70  " && $pageno!=$p
23f0: 72 65 76 2b 31 7d 20 7b 0a 20 20 20 20 20 20 69  rev+1} {.      i
2400: 6e 63 72 20 67 61 70 5f 63 6e 74 0a 20 20 20 20  ncr gap_cnt.    
2410: 7d 0a 20 20 20 20 73 65 74 20 70 72 65 76 20 24  }.    set prev $
2420: 70 61 67 65 6e 6f 0a 20 20 7d 0a 20 20 6d 65 6d  pageno.  }.  mem
2430: 20 65 76 61 6c 20 7b 0a 20 20 20 20 49 4e 53 45   eval {.    INSE
2440: 52 54 20 49 4e 54 4f 20 73 70 61 63 65 5f 75 73  RT INTO space_us
2450: 65 64 20 56 41 4c 55 45 53 28 0a 20 20 20 20 20  ed VALUES(.     
2460: 20 24 6e 61 6d 65 2c 0a 20 20 20 20 20 20 24 74   $name,.      $t
2470: 62 6c 6e 61 6d 65 2c 0a 20 20 20 20 20 20 24 69  blname,.      $i
2480: 73 5f 69 6e 64 65 78 2c 0a 20 20 20 20 20 20 24  s_index,.      $
2490: 69 73 5f 77 69 74 68 6f 75 74 5f 72 6f 77 69 64  is_without_rowid
24a0: 2c 0a 20 20 20 20 20 20 24 6e 65 6e 74 72 79 2c  ,.      $nentry,
24b0: 0a 20 20 20 20 20 20 24 6c 65 61 66 5f 65 6e 74  .      $leaf_ent
24c0: 72 69 65 73 2c 0a 20 20 20 20 20 20 24 64 65 70  ries,.      $dep
24d0: 74 68 2c 0a 20 20 20 20 20 20 24 70 61 79 6c 6f  th,.      $paylo
24e0: 61 64 2c 20 20 20 20 20 0a 20 20 20 20 20 20 24  ad,     .      $
24f0: 6f 76 66 6c 5f 70 61 79 6c 6f 61 64 2c 0a 20 20  ovfl_payload,.  
2500: 20 20 20 20 24 6f 76 66 6c 5f 63 6e 74 2c 20 20      $ovfl_cnt,  
2510: 20 0a 20 20 20 20 20 20 24 6d 78 5f 70 61 79 6c   .      $mx_payl
2520: 6f 61 64 2c 0a 20 20 20 20 20 20 24 69 6e 74 5f  oad,.      $int_
2530: 70 61 67 65 73 2c 0a 20 20 20 20 20 20 24 6c 65  pages,.      $le
2540: 61 66 5f 70 61 67 65 73 2c 20 20 0a 20 20 20 20  af_pages,  .    
2550: 20 20 24 6f 76 66 6c 5f 70 61 67 65 73 2c 20 0a    $ovfl_pages, .
2560: 20 20 20 20 20 20 24 69 6e 74 5f 75 6e 75 73 65        $int_unuse
2570: 64 2c 20 0a 20 20 20 20 20 20 24 6c 65 61 66 5f  d, .      $leaf_
2580: 75 6e 75 73 65 64 2c 0a 20 20 20 20 20 20 24 6f  unused,.      $o
2590: 76 66 6c 5f 75 6e 75 73 65 64 2c 0a 20 20 20 20  vfl_unused,.    
25a0: 20 20 24 67 61 70 5f 63 6e 74 2c 0a 20 20 20 20    $gap_cnt,.    
25b0: 20 20 24 63 6f 6d 70 72 65 73 73 65 64 5f 73 69    $compressed_si
25c0: 7a 65 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 7d 0a  ze.    );.  }.}.
25d0: 0a 70 72 6f 63 20 69 6e 74 65 67 65 72 69 66 79  .proc integerify
25e0: 20 7b 72 65 61 6c 7d 20 7b 0a 20 20 69 66 20 7b   {real} {.  if {
25f0: 5b 73 74 72 69 6e 67 20 69 73 20 64 6f 75 62 6c  [string is doubl
2600: 65 20 2d 73 74 72 69 63 74 20 24 72 65 61 6c 5d  e -strict $real]
2610: 7d 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 5b  } {.    return [
2620: 65 78 70 72 20 7b 77 69 64 65 28 24 72 65 61 6c  expr {wide($real
2630: 29 7d 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20  )}].  } else {. 
2640: 20 20 20 72 65 74 75 72 6e 20 30 0a 20 20 7d 0a     return 0.  }.
2650: 7d 0a 6d 65 6d 20 66 75 6e 63 74 69 6f 6e 20 69  }.mem function i
2660: 6e 74 20 69 6e 74 65 67 65 72 69 66 79 0a 0a 23  nt integerify..#
2670: 20 51 75 6f 74 65 20 61 20 73 74 72 69 6e 67 20   Quote a string 
2680: 66 6f 72 20 75 73 65 20 69 6e 20 61 6e 20 53 51  for use in an SQ
2690: 4c 20 71 75 65 72 79 2e 20 45 78 61 6d 70 6c 65  L query. Example
26a0: 73 3a 0a 23 0a 23 20 5b 71 75 6f 74 65 20 7b 68  s:.#.# [quote {h
26b0: 65 6c 6c 6f 20 77 6f 72 6c 64 7d 5d 20 20 20 3d  ello world}]   =
26c0: 3d 20 7b 27 68 65 6c 6c 6f 20 77 6f 72 6c 64 27  = {'hello world'
26d0: 7d 0a 23 20 5b 71 75 6f 74 65 20 7b 68 65 6c 6c  }.# [quote {hell
26e0: 6f 20 77 6f 72 6c 64 27 73 7d 5d 20 3d 3d 20 7b  o world's}] == {
26f0: 27 68 65 6c 6c 6f 20 77 6f 72 6c 64 27 27 73 27  'hello world''s'
2700: 7d 0a 23 0a 70 72 6f 63 20 71 75 6f 74 65 20 7b  }.#.proc quote {
2710: 74 78 74 7d 20 7b 0a 20 20 72 65 74 75 72 6e 20  txt} {.  return 
2720: 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 27 20 27  [string map {' '
2730: 27 7d 20 24 74 78 74 5d 0a 7d 0a 0a 23 20 4f 75  '} $txt].}..# Ou
2740: 74 70 75 74 20 61 20 74 69 74 6c 65 20 6c 69 6e  tput a title lin
2750: 65 0a 23 0a 70 72 6f 63 20 74 69 74 6c 65 6c 69  e.#.proc titleli
2760: 6e 65 20 7b 74 69 74 6c 65 7d 20 7b 0a 20 20 69  ne {title} {.  i
2770: 66 20 7b 24 74 69 74 6c 65 3d 3d 22 22 7d 20 7b  f {$title==""} {
2780: 0a 20 20 20 20 70 75 74 73 20 5b 73 74 72 69 6e  .    puts [strin
2790: 67 20 72 65 70 65 61 74 20 2a 20 37 39 5d 0a 20  g repeat * 79]. 
27a0: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65   } else {.    se
27b0: 74 20 6c 65 6e 20 5b 73 74 72 69 6e 67 20 6c 65  t len [string le
27c0: 6e 67 74 68 20 24 74 69 74 6c 65 5d 0a 20 20 20  ngth $title].   
27d0: 20 73 65 74 20 73 74 61 72 73 20 5b 73 74 72 69   set stars [stri
27e0: 6e 67 20 72 65 70 65 61 74 20 2a 20 5b 65 78 70  ng repeat * [exp
27f0: 72 20 37 39 2d 24 6c 65 6e 2d 35 5d 5d 0a 20 20  r 79-$len-5]].  
2800: 20 20 70 75 74 73 20 22 2a 2a 2a 20 24 74 69 74    puts "*** $tit
2810: 6c 65 20 24 73 74 61 72 73 22 0a 20 20 7d 0a 7d  le $stars".  }.}
2820: 0a 0a 23 20 47 65 6e 65 72 61 74 65 20 61 20 73  ..# Generate a s
2830: 69 6e 67 6c 65 20 6c 69 6e 65 20 6f 66 20 6f 75  ingle line of ou
2840: 74 70 75 74 20 69 6e 20 74 68 65 20 73 74 61 74  tput in the stat
2850: 69 73 74 69 63 73 20 73 65 63 74 69 6f 6e 20 6f  istics section o
2860: 66 20 74 68 65 0a 23 20 72 65 70 6f 72 74 2e 0a  f the.# report..
2870: 23 0a 70 72 6f 63 20 73 74 61 74 6c 69 6e 65 20  #.proc statline 
2880: 7b 74 69 74 6c 65 20 76 61 6c 75 65 20 7b 65 78  {title value {ex
2890: 74 72 61 20 7b 7d 7d 7d 20 7b 0a 20 20 73 65 74  tra {}}} {.  set
28a0: 20 6c 65 6e 20 5b 73 74 72 69 6e 67 20 6c 65 6e   len [string len
28b0: 67 74 68 20 24 74 69 74 6c 65 5d 0a 20 20 73 65  gth $title].  se
28c0: 74 20 64 6f 74 73 20 5b 73 74 72 69 6e 67 20 72  t dots [string r
28d0: 65 70 65 61 74 20 2e 20 5b 65 78 70 72 20 35 30  epeat . [expr 50
28e0: 2d 24 6c 65 6e 5d 5d 0a 20 20 73 65 74 20 6c 65  -$len]].  set le
28f0: 6e 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68  n [string length
2900: 20 24 76 61 6c 75 65 5d 0a 20 20 73 65 74 20 73   $value].  set s
2910: 70 32 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65  p2 [string range
2920: 20 7b 20 20 20 20 20 20 20 20 20 20 7d 20 24 6c   {          } $l
2930: 65 6e 20 65 6e 64 5d 0a 20 20 69 66 20 7b 24 65  en end].  if {$e
2940: 78 74 72 61 20 6e 65 20 22 22 7d 20 7b 0a 20 20  xtra ne ""} {.  
2950: 20 20 73 65 74 20 65 78 74 72 61 20 22 20 24 65    set extra " $e
2960: 78 74 72 61 22 0a 20 20 7d 0a 20 20 70 75 74 73  xtra".  }.  puts
2970: 20 22 24 74 69 74 6c 65 24 64 6f 74 73 20 24 76   "$title$dots $v
2980: 61 6c 75 65 24 73 70 32 24 65 78 74 72 61 22 0a  alue$sp2$extra".
2990: 7d 0a 0a 23 20 47 65 6e 65 72 61 74 65 20 61 20  }..# Generate a 
29a0: 66 6f 72 6d 61 74 74 65 64 20 70 65 72 63 65 6e  formatted percen
29b0: 74 61 67 65 20 76 61 6c 75 65 20 66 6f 72 20 24  tage value for $
29c0: 6e 75 6d 2f 24 64 65 6e 6f 6d 0a 23 0a 70 72 6f  num/$denom.#.pro
29d0: 63 20 70 65 72 63 65 6e 74 20 7b 6e 75 6d 20 64  c percent {num d
29e0: 65 6e 6f 6d 20 7b 6f 66 20 7b 7d 7d 7d 20 7b 0a  enom {of {}}} {.
29f0: 20 20 69 66 20 7b 24 64 65 6e 6f 6d 3d 3d 30 2e    if {$denom==0.
2a00: 30 7d 20 7b 72 65 74 75 72 6e 20 22 22 7d 0a 20  0} {return ""}. 
2a10: 20 73 65 74 20 76 20 5b 65 78 70 72 20 7b 24 6e   set v [expr {$n
2a20: 75 6d 2a 31 30 30 2e 30 2f 24 64 65 6e 6f 6d 7d  um*100.0/$denom}
2a30: 5d 0a 20 20 73 65 74 20 6f 66 20 7b 7d 0a 20 20  ].  set of {}.  
2a40: 69 66 20 7b 24 76 3d 3d 31 30 30 2e 30 20 7c 7c  if {$v==100.0 ||
2a50: 20 24 76 3c 30 2e 30 30 31 20 7c 7c 20 28 24 76   $v<0.001 || ($v
2a60: 3e 31 2e 30 20 26 26 20 24 76 3c 39 39 2e 30 29  >1.0 && $v<99.0)
2a70: 7d 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 5b  } {.    return [
2a80: 66 6f 72 6d 61 74 20 7b 25 35 2e 31 66 25 25 20  format {%5.1f%% 
2a90: 25 73 7d 20 24 76 20 24 6f 66 5d 0a 20 20 7d 20  %s} $v $of].  } 
2aa0: 65 6c 73 65 69 66 20 7b 24 76 3c 30 2e 31 20 7c  elseif {$v<0.1 |
2ab0: 7c 20 24 76 3e 39 39 2e 39 7d 20 7b 0a 20 20 20  | $v>99.9} {.   
2ac0: 20 72 65 74 75 72 6e 20 5b 66 6f 72 6d 61 74 20   return [format 
2ad0: 7b 25 37 2e 33 66 25 25 20 25 73 7d 20 24 76 20  {%7.3f%% %s} $v 
2ae0: 24 6f 66 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a  $of].  } else {.
2af0: 20 20 20 20 72 65 74 75 72 6e 20 5b 66 6f 72 6d      return [form
2b00: 61 74 20 7b 25 36 2e 32 66 25 25 20 25 73 7d 20  at {%6.2f%% %s} 
2b10: 24 76 20 24 6f 66 5d 0a 20 20 7d 0a 7d 0a 0a 70  $v $of].  }.}..p
2b20: 72 6f 63 20 64 69 76 69 64 65 20 7b 6e 75 6d 20  roc divide {num 
2b30: 64 65 6e 6f 6d 7d 20 7b 0a 20 20 69 66 20 7b 24  denom} {.  if {$
2b40: 64 65 6e 6f 6d 3d 3d 30 7d 20 7b 72 65 74 75 72  denom==0} {retur
2b50: 6e 20 30 2e 30 7d 0a 20 20 72 65 74 75 72 6e 20  n 0.0}.  return 
2b60: 5b 66 6f 72 6d 61 74 20 25 2e 32 66 20 5b 65 78  [format %.2f [ex
2b70: 70 72 20 64 6f 75 62 6c 65 28 24 6e 75 6d 29 2f  pr double($num)/
2b80: 64 6f 75 62 6c 65 28 24 64 65 6e 6f 6d 29 5d 5d  double($denom)]]
2b90: 0a 7d 0a 0a 23 20 47 65 6e 65 72 61 74 65 20 61  .}..# Generate a
2ba0: 20 73 75 62 72 65 70 6f 72 74 20 74 68 61 74 20   subreport that 
2bb0: 63 6f 76 65 72 73 20 73 6f 6d 65 20 73 75 62 73  covers some subs
2bc0: 65 74 20 6f 66 20 74 68 65 20 64 61 74 61 62 61  et of the databa
2bd0: 73 65 2e 0a 23 20 74 68 65 20 24 77 68 65 72 65  se..# the $where
2be0: 20 63 6c 61 75 73 65 20 64 65 74 65 72 6d 69 6e   clause determin
2bf0: 65 73 20 77 68 69 63 68 20 73 75 62 73 65 74 20  es which subset 
2c00: 74 6f 20 61 6e 61 6c 79 7a 65 2e 0a 23 0a 70 72  to analyze..#.pr
2c10: 6f 63 20 73 75 62 72 65 70 6f 72 74 20 7b 74 69  oc subreport {ti
2c20: 74 6c 65 20 77 68 65 72 65 20 73 68 6f 77 46 72  tle where showFr
2c30: 61 67 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 70  ag} {.  global p
2c40: 61 67 65 53 69 7a 65 20 66 69 6c 65 5f 70 67 63  ageSize file_pgc
2c50: 6e 74 20 63 6f 6d 70 72 65 73 73 4f 76 65 72 68  nt compressOverh
2c60: 65 61 64 0a 0a 20 20 23 20 51 75 65 72 79 20 74  ead..  # Query t
2c70: 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74  he in-memory dat
2c80: 61 62 61 73 65 20 66 6f 72 20 74 68 65 20 73 75  abase for the su
2c90: 6d 20 6f 66 20 76 61 72 69 6f 75 73 20 73 74 61  m of various sta
2ca0: 74 69 73 74 69 63 73 20 0a 20 20 23 20 66 6f 72  tistics .  # for
2cb0: 20 74 68 65 20 73 75 62 73 65 74 20 6f 66 20 74   the subset of t
2cc0: 61 62 6c 65 73 2f 69 6e 64 69 63 65 73 20 69 64  ables/indices id
2cd0: 65 6e 74 69 66 69 65 64 20 62 79 20 74 68 65 20  entified by the 
2ce0: 57 48 45 52 45 20 63 6c 61 75 73 65 20 69 6e 0a  WHERE clause in.
2cf0: 20 20 23 20 24 77 68 65 72 65 2e 20 4e 6f 74 65    # $where. Note
2d00: 20 74 68 61 74 20 65 76 65 6e 20 69 66 20 74 68   that even if th
2d10: 65 20 57 48 45 52 45 20 63 6c 61 75 73 65 20 6d  e WHERE clause m
2d20: 61 74 63 68 65 73 20 6e 6f 20 72 6f 77 73 2c 20  atches no rows, 
2d30: 74 68 65 0a 20 20 23 20 66 6f 6c 6c 6f 77 69 6e  the.  # followin
2d40: 67 20 71 75 65 72 79 20 72 65 74 75 72 6e 73 20  g query returns 
2d50: 65 78 61 63 74 6c 79 20 6f 6e 65 20 72 6f 77 20  exactly one row 
2d60: 28 62 65 63 61 75 73 65 20 69 74 20 69 73 20 61  (because it is a
2d70: 6e 20 61 67 67 72 65 67 61 74 65 29 2e 0a 20 20  n aggregate)..  
2d80: 23 0a 20 20 23 20 54 68 65 20 72 65 73 75 6c 74  #.  # The result
2d90: 73 20 6f 66 20 74 68 65 20 71 75 65 72 79 20 61  s of the query a
2da0: 72 65 20 73 74 6f 72 65 64 20 64 69 72 65 63 74  re stored direct
2db0: 6c 79 20 62 79 20 53 51 4c 69 74 65 20 69 6e 74  ly by SQLite int
2dc0: 6f 20 6c 6f 63 61 6c 20 0a 20 20 23 20 76 61 72  o local .  # var
2dd0: 69 61 62 6c 65 73 20 28 69 2e 65 2e 20 24 6e 65  iables (i.e. $ne
2de0: 6e 74 72 79 2c 20 24 70 61 79 6c 6f 61 64 20 65  ntry, $payload e
2df0: 74 63 2e 29 2e 0a 20 20 23 0a 20 20 6d 65 6d 20  tc.)..  #.  mem 
2e00: 65 76 61 6c 20 22 0a 20 20 20 20 53 45 4c 45 43  eval ".    SELEC
2e10: 54 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d 28  T.      int(sum(
2e20: 0a 20 20 20 20 20 20 20 20 43 41 53 45 20 57 48  .        CASE WH
2e30: 45 4e 20 28 69 73 5f 77 69 74 68 6f 75 74 5f 72  EN (is_without_r
2e40: 6f 77 69 64 20 4f 52 20 69 73 5f 69 6e 64 65 78  owid OR is_index
2e50: 29 20 54 48 45 4e 20 6e 65 6e 74 72 79 20 0a 20  ) THEN nentry . 
2e60: 20 20 20 20 20 20 20 20 20 20 20 20 45 4c 53 45              ELSE
2e70: 20 6c 65 61 66 5f 65 6e 74 72 69 65 73 20 0a 20   leaf_entries . 
2e80: 20 20 20 20 20 20 20 45 4e 44 0a 20 20 20 20 20         END.     
2e90: 20 29 29 20 41 53 20 6e 65 6e 74 72 79 2c 0a 20   )) AS nentry,. 
2ea0: 20 20 20 20 20 69 6e 74 28 73 75 6d 28 70 61 79       int(sum(pay
2eb0: 6c 6f 61 64 29 29 20 41 53 20 70 61 79 6c 6f 61  load)) AS payloa
2ec0: 64 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d  d,.      int(sum
2ed0: 28 6f 76 66 6c 5f 70 61 79 6c 6f 61 64 29 29 20  (ovfl_payload)) 
2ee0: 41 53 20 6f 76 66 6c 5f 70 61 79 6c 6f 61 64 2c  AS ovfl_payload,
2ef0: 0a 20 20 20 20 20 20 6d 61 78 28 6d 78 5f 70 61  .      max(mx_pa
2f00: 79 6c 6f 61 64 29 20 41 53 20 6d 78 5f 70 61 79  yload) AS mx_pay
2f10: 6c 6f 61 64 2c 0a 20 20 20 20 20 20 69 6e 74 28  load,.      int(
2f20: 73 75 6d 28 6f 76 66 6c 5f 63 6e 74 29 29 20 61  sum(ovfl_cnt)) a
2f30: 73 20 6f 76 66 6c 5f 63 6e 74 2c 0a 20 20 20 20  s ovfl_cnt,.    
2f40: 20 20 69 6e 74 28 73 75 6d 28 6c 65 61 66 5f 70    int(sum(leaf_p
2f50: 61 67 65 73 29 29 20 41 53 20 6c 65 61 66 5f 70  ages)) AS leaf_p
2f60: 61 67 65 73 2c 0a 20 20 20 20 20 20 69 6e 74 28  ages,.      int(
2f70: 73 75 6d 28 69 6e 74 5f 70 61 67 65 73 29 29 20  sum(int_pages)) 
2f80: 41 53 20 69 6e 74 5f 70 61 67 65 73 2c 0a 20 20  AS int_pages,.  
2f90: 20 20 20 20 69 6e 74 28 73 75 6d 28 6f 76 66 6c      int(sum(ovfl
2fa0: 5f 70 61 67 65 73 29 29 20 41 53 20 6f 76 66 6c  _pages)) AS ovfl
2fb0: 5f 70 61 67 65 73 2c 0a 20 20 20 20 20 20 69 6e  _pages,.      in
2fc0: 74 28 73 75 6d 28 6c 65 61 66 5f 75 6e 75 73 65  t(sum(leaf_unuse
2fd0: 64 29 29 20 41 53 20 6c 65 61 66 5f 75 6e 75 73  d)) AS leaf_unus
2fe0: 65 64 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75  ed,.      int(su
2ff0: 6d 28 69 6e 74 5f 75 6e 75 73 65 64 29 29 20 41  m(int_unused)) A
3000: 53 20 69 6e 74 5f 75 6e 75 73 65 64 2c 0a 20 20  S int_unused,.  
3010: 20 20 20 20 69 6e 74 28 73 75 6d 28 6f 76 66 6c      int(sum(ovfl
3020: 5f 75 6e 75 73 65 64 29 29 20 41 53 20 6f 76 66  _unused)) AS ovf
3030: 6c 5f 75 6e 75 73 65 64 2c 0a 20 20 20 20 20 20  l_unused,.      
3040: 69 6e 74 28 73 75 6d 28 67 61 70 5f 63 6e 74 29  int(sum(gap_cnt)
3050: 29 20 41 53 20 67 61 70 5f 63 6e 74 2c 0a 20 20  ) AS gap_cnt,.  
3060: 20 20 20 20 69 6e 74 28 73 75 6d 28 63 6f 6d 70      int(sum(comp
3070: 72 65 73 73 65 64 5f 73 69 7a 65 29 29 20 41 53  ressed_size)) AS
3080: 20 63 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a 65   compressed_size
3090: 2c 0a 20 20 20 20 20 20 69 6e 74 28 6d 61 78 28  ,.      int(max(
30a0: 64 65 70 74 68 29 29 20 41 53 20 64 65 70 74 68  depth)) AS depth
30b0: 2c 0a 20 20 20 20 20 20 63 6f 75 6e 74 28 2a 29  ,.      count(*)
30c0: 20 41 53 20 63 6e 74 0a 20 20 20 20 46 52 4f 4d   AS cnt.    FROM
30d0: 20 73 70 61 63 65 5f 75 73 65 64 20 57 48 45 52   space_used WHER
30e0: 45 20 24 77 68 65 72 65 22 20 7b 7d 20 7b 7d 0a  E $where" {} {}.
30f0: 0a 20 20 23 20 4f 75 74 70 75 74 20 74 68 65 20  .  # Output the 
3100: 73 75 62 2d 72 65 70 6f 72 74 20 74 69 74 6c 65  sub-report title
3110: 2c 20 6e 69 63 65 6c 79 20 64 65 63 6f 72 61 74  , nicely decorat
3120: 65 64 20 77 69 74 68 20 2a 20 63 68 61 72 61 63  ed with * charac
3130: 74 65 72 73 2e 0a 20 20 23 0a 20 20 70 75 74 73  ters..  #.  puts
3140: 20 22 22 0a 20 20 74 69 74 6c 65 6c 69 6e 65 20   "".  titleline 
3150: 24 74 69 74 6c 65 0a 20 20 70 75 74 73 20 22 22  $title.  puts ""
3160: 0a 0a 20 20 23 20 43 61 6c 63 75 6c 61 74 65 20  ..  # Calculate 
3170: 73 74 61 74 69 73 74 69 63 73 20 61 6e 64 20 73  statistics and s
3180: 74 6f 72 65 20 74 68 65 20 72 65 73 75 6c 74 73  tore the results
3190: 20 69 6e 20 54 43 4c 20 76 61 72 69 61 62 6c 65   in TCL variable
31a0: 73 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 20  s, as follows:. 
31b0: 20 23 0a 20 20 23 20 74 6f 74 61 6c 5f 70 61 67   #.  # total_pag
31c0: 65 73 3a 20 44 61 74 61 62 61 73 65 20 70 61 67  es: Database pag
31d0: 65 73 20 63 6f 6e 73 75 6d 65 64 2e 0a 20 20 23  es consumed..  #
31e0: 20 74 6f 74 61 6c 5f 70 61 67 65 73 5f 70 65 72   total_pages_per
31f0: 63 65 6e 74 3a 20 50 61 67 65 73 20 63 6f 6e 73  cent: Pages cons
3200: 75 6d 65 64 20 61 73 20 61 20 70 65 72 63 65 6e  umed as a percen
3210: 74 61 67 65 20 6f 66 20 74 68 65 20 66 69 6c 65  tage of the file
3220: 2e 0a 20 20 23 20 73 74 6f 72 61 67 65 3a 20 42  ..  # storage: B
3230: 79 74 65 73 20 63 6f 6e 73 75 6d 65 64 2e 0a 20  ytes consumed.. 
3240: 20 23 20 70 61 79 6c 6f 61 64 5f 70 65 72 63 65   # payload_perce
3250: 6e 74 3a 20 50 61 79 6c 6f 61 64 20 62 79 74 65  nt: Payload byte
3260: 73 20 75 73 65 64 20 61 73 20 61 20 70 65 72 63  s used as a perc
3270: 65 6e 74 61 67 65 20 6f 66 20 24 73 74 6f 72 61  entage of $stora
3280: 67 65 2e 0a 20 20 23 20 74 6f 74 61 6c 5f 75 6e  ge..  # total_un
3290: 75 73 65 64 3a 20 55 6e 75 73 65 64 20 62 79 74  used: Unused byt
32a0: 65 73 20 6f 6e 20 70 61 67 65 73 2e 0a 20 20 23  es on pages..  #
32b0: 20 61 76 67 5f 70 61 79 6c 6f 61 64 3a 20 41 76   avg_payload: Av
32c0: 65 72 61 67 65 20 70 61 79 6c 6f 61 64 20 70 65  erage payload pe
32d0: 72 20 62 74 72 65 65 20 65 6e 74 72 79 2e 0a 20  r btree entry.. 
32e0: 20 23 20 61 76 67 5f 66 61 6e 6f 75 74 3a 20 41   # avg_fanout: A
32f0: 76 65 72 61 67 65 20 66 61 6e 6f 75 74 20 66 6f  verage fanout fo
3300: 72 20 69 6e 74 65 72 6e 61 6c 20 70 61 67 65 73  r internal pages
3310: 2e 0a 20 20 23 20 61 76 67 5f 75 6e 75 73 65 64  ..  # avg_unused
3320: 3a 20 41 76 65 72 61 67 65 20 75 6e 75 73 65 64  : Average unused
3330: 20 62 79 74 65 73 20 70 65 72 20 62 74 72 65 65   bytes per btree
3340: 20 65 6e 74 72 79 2e 0a 20 20 23 20 61 76 67 5f   entry..  # avg_
3350: 6d 65 74 61 3a 20 41 76 65 72 61 67 65 20 6d 65  meta: Average me
3360: 74 61 64 61 74 61 20 6f 76 65 72 68 65 61 64 20  tadata overhead 
3370: 70 65 72 20 65 6e 74 72 79 2e 0a 20 20 23 20 6f  per entry..  # o
3380: 76 66 6c 5f 63 6e 74 5f 70 65 72 63 65 6e 74 3a  vfl_cnt_percent:
3390: 20 50 65 72 63 65 6e 74 61 67 65 20 6f 66 20 62   Percentage of b
33a0: 74 72 65 65 20 65 6e 74 72 69 65 73 20 74 68 61  tree entries tha
33b0: 74 20 75 73 65 20 6f 76 65 72 66 6c 6f 77 20 70  t use overflow p
33c0: 61 67 65 73 2e 0a 20 20 23 0a 20 20 73 65 74 20  ages..  #.  set 
33d0: 74 6f 74 61 6c 5f 70 61 67 65 73 20 5b 65 78 70  total_pages [exp
33e0: 72 20 7b 24 6c 65 61 66 5f 70 61 67 65 73 2b 24  r {$leaf_pages+$
33f0: 69 6e 74 5f 70 61 67 65 73 2b 24 6f 76 66 6c 5f  int_pages+$ovfl_
3400: 70 61 67 65 73 7d 5d 0a 20 20 73 65 74 20 74 6f  pages}].  set to
3410: 74 61 6c 5f 70 61 67 65 73 5f 70 65 72 63 65 6e  tal_pages_percen
3420: 74 20 5b 70 65 72 63 65 6e 74 20 24 74 6f 74 61  t [percent $tota
3430: 6c 5f 70 61 67 65 73 20 24 66 69 6c 65 5f 70 67  l_pages $file_pg
3440: 63 6e 74 5d 0a 20 20 73 65 74 20 73 74 6f 72 61  cnt].  set stora
3450: 67 65 20 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c  ge [expr {$total
3460: 5f 70 61 67 65 73 2a 24 70 61 67 65 53 69 7a 65  _pages*$pageSize
3470: 7d 5d 0a 20 20 73 65 74 20 70 61 79 6c 6f 61 64  }].  set payload
3480: 5f 70 65 72 63 65 6e 74 20 5b 70 65 72 63 65 6e  _percent [percen
3490: 74 20 24 70 61 79 6c 6f 61 64 20 24 73 74 6f 72  t $payload $stor
34a0: 61 67 65 20 7b 6f 66 20 73 74 6f 72 61 67 65 20  age {of storage 
34b0: 63 6f 6e 73 75 6d 65 64 7d 5d 0a 20 20 73 65 74  consumed}].  set
34c0: 20 74 6f 74 61 6c 5f 75 6e 75 73 65 64 20 5b 65   total_unused [e
34d0: 78 70 72 20 7b 24 6f 76 66 6c 5f 75 6e 75 73 65  xpr {$ovfl_unuse
34e0: 64 2b 24 69 6e 74 5f 75 6e 75 73 65 64 2b 24 6c  d+$int_unused+$l
34f0: 65 61 66 5f 75 6e 75 73 65 64 7d 5d 0a 20 20 73  eaf_unused}].  s
3500: 65 74 20 61 76 67 5f 70 61 79 6c 6f 61 64 20 5b  et avg_payload [
3510: 64 69 76 69 64 65 20 24 70 61 79 6c 6f 61 64 20  divide $payload 
3520: 24 6e 65 6e 74 72 79 5d 0a 20 20 73 65 74 20 61  $nentry].  set a
3530: 76 67 5f 75 6e 75 73 65 64 20 5b 64 69 76 69 64  vg_unused [divid
3540: 65 20 24 74 6f 74 61 6c 5f 75 6e 75 73 65 64 20  e $total_unused 
3550: 24 6e 65 6e 74 72 79 5d 0a 20 20 73 65 74 20 74  $nentry].  set t
3560: 6f 74 61 6c 5f 6d 65 74 61 20 5b 65 78 70 72 20  otal_meta [expr 
3570: 7b 24 73 74 6f 72 61 67 65 20 2d 20 24 70 61 79  {$storage - $pay
3580: 6c 6f 61 64 20 2d 20 24 74 6f 74 61 6c 5f 75 6e  load - $total_un
3590: 75 73 65 64 7d 5d 0a 20 20 73 65 74 20 74 6f 74  used}].  set tot
35a0: 61 6c 5f 6d 65 74 61 20 5b 65 78 70 72 20 7b 24  al_meta [expr {$
35b0: 74 6f 74 61 6c 5f 6d 65 74 61 20 2b 20 34 2a 28  total_meta + 4*(
35c0: 24 6f 76 66 6c 5f 70 61 67 65 73 20 2d 20 24 6f  $ovfl_pages - $o
35d0: 76 66 6c 5f 63 6e 74 29 7d 5d 0a 20 20 73 65 74  vfl_cnt)}].  set
35e0: 20 6d 65 74 61 5f 70 65 72 63 65 6e 74 20 5b 70   meta_percent [p
35f0: 65 72 63 65 6e 74 20 24 74 6f 74 61 6c 5f 6d 65  ercent $total_me
3600: 74 61 20 24 73 74 6f 72 61 67 65 20 7b 6f 66 20  ta $storage {of 
3610: 6d 65 74 61 64 61 74 61 7d 5d 0a 20 20 73 65 74  metadata}].  set
3620: 20 61 76 67 5f 6d 65 74 61 20 5b 64 69 76 69 64   avg_meta [divid
3630: 65 20 24 74 6f 74 61 6c 5f 6d 65 74 61 20 24 6e  e $total_meta $n
3640: 65 6e 74 72 79 5d 0a 20 20 69 66 20 7b 24 69 6e  entry].  if {$in
3650: 74 5f 70 61 67 65 73 3e 30 7d 20 7b 0a 20 20 20  t_pages>0} {.   
3660: 20 23 20 54 4f 44 4f 3a 20 49 73 20 74 68 69 73   # TODO: Is this
3670: 20 66 6f 72 6d 75 6c 61 20 63 6f 72 72 65 63 74   formula correct
3680: 3f 0a 20 20 20 20 73 65 74 20 6e 54 61 62 20 5b  ?.    set nTab [
3690: 6d 65 6d 20 65 76 61 6c 20 22 0a 20 20 20 20 20  mem eval ".     
36a0: 20 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29   SELECT count(*)
36b0: 20 46 52 4f 4d 20 28 0a 20 20 20 20 20 20 20 20   FROM (.        
36c0: 20 20 53 45 4c 45 43 54 20 44 49 53 54 49 4e 43    SELECT DISTINC
36d0: 54 20 74 62 6c 6e 61 6d 65 20 46 52 4f 4d 20 73  T tblname FROM s
36e0: 70 61 63 65 5f 75 73 65 64 20 57 48 45 52 45 20  pace_used WHERE 
36f0: 24 77 68 65 72 65 20 41 4e 44 20 69 73 5f 69 6e  $where AND is_in
3700: 64 65 78 3d 30 0a 20 20 20 20 20 20 29 0a 20 20  dex=0.      ).  
3710: 20 20 22 5d 0a 20 20 20 20 73 65 74 20 61 76 67    "].    set avg
3720: 5f 66 61 6e 6f 75 74 20 5b 6d 65 6d 20 65 76 61  _fanout [mem eva
3730: 6c 20 22 0a 20 20 20 20 20 20 53 45 4c 45 43 54  l ".      SELECT
3740: 20 28 73 75 6d 28 6c 65 61 66 5f 70 61 67 65 73   (sum(leaf_pages
3750: 2b 69 6e 74 5f 70 61 67 65 73 29 2d 24 6e 54 61  +int_pages)-$nTa
3760: 62 29 2f 73 75 6d 28 69 6e 74 5f 70 61 67 65 73  b)/sum(int_pages
3770: 29 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73 65  ) FROM space_use
3780: 64 0a 20 20 20 20 20 20 20 20 20 20 57 48 45 52  d.          WHER
3790: 45 20 24 77 68 65 72 65 0a 20 20 20 20 22 5d 0a  E $where.    "].
37a0: 20 20 20 20 73 65 74 20 61 76 67 5f 66 61 6e 6f      set avg_fano
37b0: 75 74 20 5b 66 6f 72 6d 61 74 20 25 2e 32 66 20  ut [format %.2f 
37c0: 24 61 76 67 5f 66 61 6e 6f 75 74 5d 0a 20 20 7d  $avg_fanout].  }
37d0: 0a 20 20 73 65 74 20 6f 76 66 6c 5f 63 6e 74 5f  .  set ovfl_cnt_
37e0: 70 65 72 63 65 6e 74 20 5b 70 65 72 63 65 6e 74  percent [percent
37f0: 20 24 6f 76 66 6c 5f 63 6e 74 20 24 6e 65 6e 74   $ovfl_cnt $nent
3800: 72 79 20 7b 6f 66 20 61 6c 6c 20 65 6e 74 72 69  ry {of all entri
3810: 65 73 7d 5d 0a 0a 20 20 23 20 50 72 69 6e 74 20  es}]..  # Print 
3820: 6f 75 74 20 74 68 65 20 73 75 62 2d 72 65 70 6f  out the sub-repo
3830: 72 74 20 73 74 61 74 69 73 74 69 63 73 2e 0a 20  rt statistics.. 
3840: 20 23 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 50   #.  statline {P
3850: 65 72 63 65 6e 74 61 67 65 20 6f 66 20 74 6f 74  ercentage of tot
3860: 61 6c 20 64 61 74 61 62 61 73 65 7d 20 24 74 6f  al database} $to
3870: 74 61 6c 5f 70 61 67 65 73 5f 70 65 72 63 65 6e  tal_pages_percen
3880: 74 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 4e 75  t.  statline {Nu
3890: 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 7d  mber of entries}
38a0: 20 24 6e 65 6e 74 72 79 0a 20 20 73 74 61 74 6c   $nentry.  statl
38b0: 69 6e 65 20 7b 42 79 74 65 73 20 6f 66 20 73 74  ine {Bytes of st
38c0: 6f 72 61 67 65 20 63 6f 6e 73 75 6d 65 64 7d 20  orage consumed} 
38d0: 24 73 74 6f 72 61 67 65 0a 20 20 69 66 20 7b 24  $storage.  if {$
38e0: 63 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a 65 21  compressed_size!
38f0: 3d 24 73 74 6f 72 61 67 65 7d 20 7b 0a 20 20 20  =$storage} {.   
3900: 20 73 65 74 20 63 6f 6d 70 72 65 73 73 65 64 5f   set compressed_
3910: 73 69 7a 65 20 5b 65 78 70 72 20 7b 24 63 6f 6d  size [expr {$com
3920: 70 72 65 73 73 65 64 5f 73 69 7a 65 2b 24 63 6f  pressed_size+$co
3930: 6d 70 72 65 73 73 4f 76 65 72 68 65 61 64 2a 24  mpressOverhead*$
3940: 74 6f 74 61 6c 5f 70 61 67 65 73 7d 5d 0a 20 20  total_pages}].  
3950: 20 20 73 65 74 20 70 63 74 20 5b 65 78 70 72 20    set pct [expr 
3960: 7b 24 63 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a  {$compressed_siz
3970: 65 2a 31 30 30 2e 30 2f 24 73 74 6f 72 61 67 65  e*100.0/$storage
3980: 7d 5d 0a 20 20 20 20 73 65 74 20 70 63 74 20 5b  }].    set pct [
3990: 66 6f 72 6d 61 74 20 7b 25 35 2e 31 66 25 25 7d  format {%5.1f%%}
39a0: 20 24 70 63 74 5d 0a 20 20 20 20 73 74 61 74 6c   $pct].    statl
39b0: 69 6e 65 20 7b 42 79 74 65 73 20 75 73 65 64 20  ine {Bytes used 
39c0: 61 66 74 65 72 20 63 6f 6d 70 72 65 73 73 69 6f  after compressio
39d0: 6e 7d 20 24 63 6f 6d 70 72 65 73 73 65 64 5f 73  n} $compressed_s
39e0: 69 7a 65 20 24 70 63 74 0a 20 20 7d 0a 20 20 73  ize $pct.  }.  s
39f0: 74 61 74 6c 69 6e 65 20 7b 42 79 74 65 73 20 6f  tatline {Bytes o
3a00: 66 20 70 61 79 6c 6f 61 64 7d 20 24 70 61 79 6c  f payload} $payl
3a10: 6f 61 64 20 24 70 61 79 6c 6f 61 64 5f 70 65 72  oad $payload_per
3a20: 63 65 6e 74 0a 20 20 73 74 61 74 6c 69 6e 65 20  cent.  statline 
3a30: 7b 42 79 74 65 73 20 6f 66 20 6d 65 74 61 64 61  {Bytes of metada
3a40: 74 61 7d 20 24 74 6f 74 61 6c 5f 6d 65 74 61 20  ta} $total_meta 
3a50: 24 6d 65 74 61 5f 70 65 72 63 65 6e 74 0a 20 20  $meta_percent.  
3a60: 69 66 20 7b 24 63 6e 74 3d 3d 31 7d 20 7b 73 74  if {$cnt==1} {st
3a70: 61 74 6c 69 6e 65 20 7b 42 2d 74 72 65 65 20 64  atline {B-tree d
3a80: 65 70 74 68 7d 20 24 64 65 70 74 68 7d 0a 20 20  epth} $depth}.  
3a90: 73 74 61 74 6c 69 6e 65 20 7b 41 76 65 72 61 67  statline {Averag
3aa0: 65 20 70 61 79 6c 6f 61 64 20 70 65 72 20 65 6e  e payload per en
3ab0: 74 72 79 7d 20 24 61 76 67 5f 70 61 79 6c 6f 61  try} $avg_payloa
3ac0: 64 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 41 76  d.  statline {Av
3ad0: 65 72 61 67 65 20 75 6e 75 73 65 64 20 62 79 74  erage unused byt
3ae0: 65 73 20 70 65 72 20 65 6e 74 72 79 7d 20 24 61  es per entry} $a
3af0: 76 67 5f 75 6e 75 73 65 64 0a 20 20 73 74 61 74  vg_unused.  stat
3b00: 6c 69 6e 65 20 7b 41 76 65 72 61 67 65 20 6d 65  line {Average me
3b10: 74 61 64 61 74 61 20 70 65 72 20 65 6e 74 72 79  tadata per entry
3b20: 7d 20 24 61 76 67 5f 6d 65 74 61 0a 20 20 69 66  } $avg_meta.  if
3b30: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 61   {[info exists a
3b40: 76 67 5f 66 61 6e 6f 75 74 5d 7d 20 7b 0a 20 20  vg_fanout]} {.  
3b50: 20 20 73 74 61 74 6c 69 6e 65 20 7b 41 76 65 72    statline {Aver
3b60: 61 67 65 20 66 61 6e 6f 75 74 7d 20 24 61 76 67  age fanout} $avg
3b70: 5f 66 61 6e 6f 75 74 0a 20 20 7d 0a 20 20 69 66  _fanout.  }.  if
3b80: 20 7b 24 73 68 6f 77 46 72 61 67 20 26 26 20 24   {$showFrag && $
3b90: 74 6f 74 61 6c 5f 70 61 67 65 73 3e 31 7d 20 7b  total_pages>1} {
3ba0: 0a 20 20 20 20 73 65 74 20 66 72 61 67 6d 65 6e  .    set fragmen
3bb0: 74 61 74 69 6f 6e 20 5b 70 65 72 63 65 6e 74 20  tation [percent 
3bc0: 24 67 61 70 5f 63 6e 74 20 5b 65 78 70 72 20 7b  $gap_cnt [expr {
3bd0: 24 74 6f 74 61 6c 5f 70 61 67 65 73 2d 31 7d 5d  $total_pages-1}]
3be0: 5d 0a 20 20 20 20 73 74 61 74 6c 69 6e 65 20 7b  ].    statline {
3bf0: 4e 6f 6e 2d 73 65 71 75 65 6e 74 69 61 6c 20 70  Non-sequential p
3c00: 61 67 65 73 7d 20 24 67 61 70 5f 63 6e 74 20 24  ages} $gap_cnt $
3c10: 66 72 61 67 6d 65 6e 74 61 74 69 6f 6e 0a 20 20  fragmentation.  
3c20: 7d 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 4d 61  }.  statline {Ma
3c30: 78 69 6d 75 6d 20 70 61 79 6c 6f 61 64 20 70 65  ximum payload pe
3c40: 72 20 65 6e 74 72 79 7d 20 24 6d 78 5f 70 61 79  r entry} $mx_pay
3c50: 6c 6f 61 64 0a 20 20 73 74 61 74 6c 69 6e 65 20  load.  statline 
3c60: 7b 45 6e 74 72 69 65 73 20 74 68 61 74 20 75 73  {Entries that us
3c70: 65 20 6f 76 65 72 66 6c 6f 77 7d 20 24 6f 76 66  e overflow} $ovf
3c80: 6c 5f 63 6e 74 20 24 6f 76 66 6c 5f 63 6e 74 5f  l_cnt $ovfl_cnt_
3c90: 70 65 72 63 65 6e 74 0a 20 20 69 66 20 7b 24 69  percent.  if {$i
3ca0: 6e 74 5f 70 61 67 65 73 3e 30 7d 20 7b 0a 20 20  nt_pages>0} {.  
3cb0: 20 20 73 74 61 74 6c 69 6e 65 20 7b 49 6e 64 65    statline {Inde
3cc0: 78 20 70 61 67 65 73 20 75 73 65 64 7d 20 24 69  x pages used} $i
3cd0: 6e 74 5f 70 61 67 65 73 0a 20 20 7d 0a 20 20 73  nt_pages.  }.  s
3ce0: 74 61 74 6c 69 6e 65 20 7b 50 72 69 6d 61 72 79  tatline {Primary
3cf0: 20 70 61 67 65 73 20 75 73 65 64 7d 20 24 6c 65   pages used} $le
3d00: 61 66 5f 70 61 67 65 73 0a 20 20 73 74 61 74 6c  af_pages.  statl
3d10: 69 6e 65 20 7b 4f 76 65 72 66 6c 6f 77 20 70 61  ine {Overflow pa
3d20: 67 65 73 20 75 73 65 64 7d 20 24 6f 76 66 6c 5f  ges used} $ovfl_
3d30: 70 61 67 65 73 0a 20 20 73 74 61 74 6c 69 6e 65  pages.  statline
3d40: 20 7b 54 6f 74 61 6c 20 70 61 67 65 73 20 75 73   {Total pages us
3d50: 65 64 7d 20 24 74 6f 74 61 6c 5f 70 61 67 65 73  ed} $total_pages
3d60: 0a 20 20 69 66 20 7b 24 69 6e 74 5f 75 6e 75 73  .  if {$int_unus
3d70: 65 64 3e 30 7d 20 7b 0a 20 20 20 20 73 65 74 20  ed>0} {.    set 
3d80: 69 6e 74 5f 75 6e 75 73 65 64 5f 70 65 72 63 65  int_unused_perce
3d90: 6e 74 20 5b 0a 20 20 20 20 20 20 20 20 20 70 65  nt [.         pe
3da0: 72 63 65 6e 74 20 24 69 6e 74 5f 75 6e 75 73 65  rcent $int_unuse
3db0: 64 20 5b 65 78 70 72 20 7b 24 69 6e 74 5f 70 61  d [expr {$int_pa
3dc0: 67 65 73 2a 24 70 61 67 65 53 69 7a 65 7d 5d 20  ges*$pageSize}] 
3dd0: 7b 6f 66 20 69 6e 64 65 78 20 73 70 61 63 65 7d  {of index space}
3de0: 5d 0a 20 20 20 20 73 74 61 74 6c 69 6e 65 20 22  ].    statline "
3df0: 55 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e 20  Unused bytes on 
3e00: 69 6e 64 65 78 20 70 61 67 65 73 22 20 24 69 6e  index pages" $in
3e10: 74 5f 75 6e 75 73 65 64 20 24 69 6e 74 5f 75 6e  t_unused $int_un
3e20: 75 73 65 64 5f 70 65 72 63 65 6e 74 0a 20 20 7d  used_percent.  }
3e30: 0a 20 20 73 74 61 74 6c 69 6e 65 20 22 55 6e 75  .  statline "Unu
3e40: 73 65 64 20 62 79 74 65 73 20 6f 6e 20 70 72 69  sed bytes on pri
3e50: 6d 61 72 79 20 70 61 67 65 73 22 20 24 6c 65 61  mary pages" $lea
3e60: 66 5f 75 6e 75 73 65 64 20 5b 0a 20 20 20 20 20  f_unused [.     
3e70: 70 65 72 63 65 6e 74 20 24 6c 65 61 66 5f 75 6e  percent $leaf_un
3e80: 75 73 65 64 20 5b 65 78 70 72 20 7b 24 6c 65 61  used [expr {$lea
3e90: 66 5f 70 61 67 65 73 2a 24 70 61 67 65 53 69 7a  f_pages*$pageSiz
3ea0: 65 7d 5d 20 7b 6f 66 20 70 72 69 6d 61 72 79 20  e}] {of primary 
3eb0: 73 70 61 63 65 7d 5d 0a 20 20 73 74 61 74 6c 69  space}].  statli
3ec0: 6e 65 20 22 55 6e 75 73 65 64 20 62 79 74 65 73  ne "Unused bytes
3ed0: 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20 70 61 67   on overflow pag
3ee0: 65 73 22 20 24 6f 76 66 6c 5f 75 6e 75 73 65 64  es" $ovfl_unused
3ef0: 20 5b 0a 20 20 20 20 20 70 65 72 63 65 6e 74 20   [.     percent 
3f00: 24 6f 76 66 6c 5f 75 6e 75 73 65 64 20 5b 65 78  $ovfl_unused [ex
3f10: 70 72 20 7b 24 6f 76 66 6c 5f 70 61 67 65 73 2a  pr {$ovfl_pages*
3f20: 24 70 61 67 65 53 69 7a 65 7d 5d 20 7b 6f 66 20  $pageSize}] {of 
3f30: 6f 76 65 72 66 6c 6f 77 20 73 70 61 63 65 7d 5d  overflow space}]
3f40: 0a 20 20 73 74 61 74 6c 69 6e 65 20 22 55 6e 75  .  statline "Unu
3f50: 73 65 64 20 62 79 74 65 73 20 6f 6e 20 61 6c 6c  sed bytes on all
3f60: 20 70 61 67 65 73 22 20 24 74 6f 74 61 6c 5f 75   pages" $total_u
3f70: 6e 75 73 65 64 20 5b 0a 20 20 20 20 20 20 20 20  nused [.        
3f80: 20 20 20 20 20 20 20 70 65 72 63 65 6e 74 20 24         percent $
3f90: 74 6f 74 61 6c 5f 75 6e 75 73 65 64 20 24 73 74  total_unused $st
3fa0: 6f 72 61 67 65 20 7b 6f 66 20 61 6c 6c 20 73 70  orage {of all sp
3fb0: 61 63 65 7d 5d 0a 20 20 72 65 74 75 72 6e 20 31  ace}].  return 1
3fc0: 0a 7d 0a 0a 23 20 43 61 6c 63 75 6c 61 74 65 20  .}..# Calculate 
3fd0: 74 68 65 20 6f 76 65 72 68 65 61 64 20 69 6e 20  the overhead in 
3fe0: 70 61 67 65 73 20 63 61 75 73 65 64 20 62 79 20  pages caused by 
3ff0: 61 75 74 6f 2d 76 61 63 75 75 6d 2e 20 0a 23 0a  auto-vacuum. .#.
4000: 23 20 54 68 69 73 20 70 72 6f 63 65 64 75 72 65  # This procedure
4010: 20 63 61 6c 63 75 6c 61 74 65 73 20 61 6e 64 20   calculates and 
4020: 72 65 74 75 72 6e 73 20 74 68 65 20 6e 75 6d 62  returns the numb
4030: 65 72 20 6f 66 20 70 61 67 65 73 20 75 73 65 64  er of pages used
4040: 20 62 79 20 74 68 65 20 0a 23 20 61 75 74 6f 2d   by the .# auto-
4050: 76 61 63 75 75 6d 20 27 70 6f 69 6e 74 65 72 2d  vacuum 'pointer-
4060: 6d 61 70 27 2e 20 49 66 20 74 68 65 20 64 61 74  map'. If the dat
4070: 61 62 61 73 65 20 64 6f 65 73 20 6e 6f 74 20 73  abase does not s
4080: 75 70 70 6f 72 74 20 61 75 74 6f 2d 76 61 63 75  upport auto-vacu
4090: 75 6d 2c 0a 23 20 74 68 65 6e 20 30 20 69 73 20  um,.# then 0 is 
40a0: 72 65 74 75 72 6e 65 64 2e 20 54 68 65 20 74 77  returned. The tw
40b0: 6f 20 61 72 67 75 6d 65 6e 74 73 20 61 72 65 20  o arguments are 
40c0: 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20  the size of the 
40d0: 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 69 6e  database file in
40e0: 0a 23 20 70 61 67 65 73 20 61 6e 64 20 74 68 65  .# pages and the
40f0: 20 70 61 67 65 20 73 69 7a 65 20 75 73 65 64 20   page size used 
4100: 62 79 20 74 68 65 20 64 61 74 61 62 61 73 65 20  by the database 
4110: 28 69 6e 20 62 79 74 65 73 29 2e 0a 70 72 6f 63  (in bytes)..proc
4120: 20 61 75 74 6f 76 61 63 75 75 6d 5f 6f 76 65 72   autovacuum_over
4130: 68 65 61 64 20 7b 66 69 6c 65 50 61 67 65 73 20  head {filePages 
4140: 70 61 67 65 53 69 7a 65 7d 20 7b 0a 0a 20 20 23  pageSize} {..  #
4150: 20 53 65 74 20 24 61 75 74 6f 76 61 63 75 75 6d   Set $autovacuum
4160: 20 74 6f 20 6e 6f 6e 2d 7a 65 72 6f 20 66 6f 72   to non-zero for
4170: 20 64 61 74 61 62 61 73 65 73 20 74 68 61 74 20   databases that 
4180: 73 75 70 70 6f 72 74 20 61 75 74 6f 2d 76 61 63  support auto-vac
4190: 75 75 6d 2e 0a 20 20 73 65 74 20 61 75 74 6f 76  uum..  set autov
41a0: 61 63 75 75 6d 20 5b 64 62 20 6f 6e 65 20 7b 50  acuum [db one {P
41b0: 52 41 47 4d 41 20 61 75 74 6f 5f 76 61 63 75 75  RAGMA auto_vacuu
41c0: 6d 7d 5d 0a 0a 20 20 23 20 49 66 20 74 68 65 20  m}]..  # If the 
41d0: 64 61 74 61 62 61 73 65 20 69 73 20 6e 6f 74 20  database is not 
41e0: 61 6e 20 61 75 74 6f 2d 76 61 63 75 75 6d 20 64  an auto-vacuum d
41f0: 61 74 61 62 61 73 65 20 6f 72 20 74 68 65 20 66  atabase or the f
4200: 69 6c 65 20 63 6f 6e 73 69 73 74 73 0a 20 20 23  ile consists.  #
4210: 20 6f 66 20 6f 6e 65 20 70 61 67 65 20 6f 6e 6c   of one page onl
4220: 79 20 74 68 65 6e 20 74 68 65 72 65 20 69 73 20  y then there is 
4230: 6e 6f 20 6f 76 65 72 68 65 61 64 20 66 6f 72 20  no overhead for 
4240: 61 75 74 6f 2d 76 61 63 75 75 6d 2e 20 52 65 74  auto-vacuum. Ret
4250: 75 72 6e 20 7a 65 72 6f 2e 0a 20 20 69 66 20 7b  urn zero..  if {
4260: 30 3d 3d 24 61 75 74 6f 76 61 63 75 75 6d 20 7c  0==$autovacuum |
4270: 7c 20 24 66 69 6c 65 50 61 67 65 73 3d 3d 31 7d  | $filePages==1}
4280: 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 0a   {.    return 0.
4290: 20 20 7d 0a 0a 20 20 23 20 54 68 65 20 6e 75 6d    }..  # The num
42a0: 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 6f  ber of entries o
42b0: 6e 20 65 61 63 68 20 70 6f 69 6e 74 65 72 20 6d  n each pointer m
42c0: 61 70 20 70 61 67 65 2e 20 54 68 65 20 6c 61 79  ap page. The lay
42d0: 6f 75 74 20 6f 66 20 74 68 65 0a 20 20 23 20 64  out of the.  # d
42e0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 69 73 20  atabase file is 
42f0: 6f 6e 65 20 70 6f 69 6e 74 65 72 2d 6d 61 70 20  one pointer-map 
4300: 70 61 67 65 2c 20 66 6f 6c 6c 6f 77 65 64 20 62  page, followed b
4310: 79 20 24 70 74 72 73 50 65 72 50 61 67 65 20 6f  y $ptrsPerPage o
4320: 74 68 65 72 0a 20 20 23 20 70 61 67 65 73 2c 20  ther.  # pages, 
4330: 66 6f 6c 6c 6f 77 65 64 20 62 79 20 61 20 70 6f  followed by a po
4340: 69 6e 74 65 72 2d 6d 61 70 20 70 61 67 65 20 65  inter-map page e
4350: 74 63 2e 20 54 68 65 20 66 69 72 73 74 20 70 6f  tc. The first po
4360: 69 6e 74 65 72 2d 6d 61 70 20 70 61 67 65 0a 20  inter-map page. 
4370: 20 23 20 69 73 20 74 68 65 20 73 65 63 6f 6e 64   # is the second
4380: 20 70 61 67 65 20 6f 66 20 74 68 65 20 66 69 6c   page of the fil
4390: 65 20 6f 76 65 72 61 6c 6c 2e 0a 20 20 73 65 74  e overall..  set
43a0: 20 70 74 72 73 50 65 72 50 61 67 65 20 5b 65 78   ptrsPerPage [ex
43b0: 70 72 20 64 6f 75 62 6c 65 28 24 70 61 67 65 53  pr double($pageS
43c0: 69 7a 65 2f 35 29 5d 0a 0a 20 20 23 20 52 65 74  ize/5)]..  # Ret
43d0: 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f  urn the number o
43e0: 66 20 70 6f 69 6e 74 65 72 20 6d 61 70 20 70 61  f pointer map pa
43f0: 67 65 73 20 69 6e 20 74 68 65 20 64 61 74 61 62  ges in the datab
4400: 61 73 65 2e 0a 20 20 72 65 74 75 72 6e 20 5b 65  ase..  return [e
4410: 78 70 72 20 77 69 64 65 28 63 65 69 6c 28 20 28  xpr wide(ceil( (
4420: 24 66 69 6c 65 50 61 67 65 73 2d 31 2e 30 29 2f  $filePages-1.0)/
4430: 28 24 70 74 72 73 50 65 72 50 61 67 65 2b 31 2e  ($ptrsPerPage+1.
4440: 30 29 20 29 29 5d 0a 7d 0a 0a 0a 23 20 43 61 6c  0) ))].}...# Cal
4450: 63 75 6c 61 74 65 20 74 68 65 20 73 75 6d 6d 61  culate the summa
4460: 72 79 20 73 74 61 74 69 73 74 69 63 73 20 66 6f  ry statistics fo
4470: 72 20 74 68 65 20 64 61 74 61 62 61 73 65 20 61  r the database a
4480: 6e 64 20 73 74 6f 72 65 20 74 68 65 20 72 65 73  nd store the res
4490: 75 6c 74 73 0a 23 20 69 6e 20 54 43 4c 20 76 61  ults.# in TCL va
44a0: 72 69 61 62 6c 65 73 2e 20 54 68 65 79 20 61 72  riables. They ar
44b0: 65 20 6f 75 74 70 75 74 20 62 65 6c 6f 77 2e 20  e output below. 
44c0: 56 61 72 69 61 62 6c 65 73 20 61 72 65 20 61 73  Variables are as
44d0: 20 66 6f 6c 6c 6f 77 73 3a 0a 23 0a 23 20 70 61   follows:.#.# pa
44e0: 67 65 53 69 7a 65 3a 20 20 20 20 20 20 53 69 7a  geSize:      Siz
44f0: 65 20 6f 66 20 65 61 63 68 20 70 61 67 65 20 69  e of each page i
4500: 6e 20 62 79 74 65 73 2e 0a 23 20 66 69 6c 65 5f  n bytes..# file_
4510: 62 79 74 65 73 3a 20 20 20 20 46 69 6c 65 20 73  bytes:    File s
4520: 69 7a 65 20 69 6e 20 62 79 74 65 73 2e 0a 23 20  ize in bytes..# 
4530: 66 69 6c 65 5f 70 67 63 6e 74 3a 20 20 20 20 4e  file_pgcnt:    N
4540: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 69  umber of pages i
4550: 6e 20 74 68 65 20 66 69 6c 65 2e 0a 23 20 66 69  n the file..# fi
4560: 6c 65 5f 70 67 63 6e 74 32 3a 20 20 20 4e 75 6d  le_pgcnt2:   Num
4570: 62 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20  ber of pages in 
4580: 74 68 65 20 66 69 6c 65 20 28 63 61 6c 63 75 6c  the file (calcul
4590: 61 74 65 64 29 2e 0a 23 20 61 76 5f 70 67 63 6e  ated)..# av_pgcn
45a0: 74 3a 20 20 20 20 20 20 50 61 67 65 73 20 63 6f  t:      Pages co
45b0: 6e 73 75 6d 65 64 20 62 79 20 74 68 65 20 61 75  nsumed by the au
45c0: 74 6f 2d 76 61 63 75 75 6d 20 70 6f 69 6e 74 65  to-vacuum pointe
45d0: 72 2d 6d 61 70 2e 0a 23 20 61 76 5f 70 65 72 63  r-map..# av_perc
45e0: 65 6e 74 3a 20 20 20 20 50 65 72 63 65 6e 74 61  ent:    Percenta
45f0: 67 65 20 6f 66 20 74 68 65 20 66 69 6c 65 20 63  ge of the file c
4600: 6f 6e 73 75 6d 65 64 20 62 79 20 61 75 74 6f 2d  onsumed by auto-
4610: 76 61 63 75 75 6d 20 70 6f 69 6e 74 65 72 2d 6d  vacuum pointer-m
4620: 61 70 2e 0a 23 20 69 6e 75 73 65 5f 70 67 63 6e  ap..# inuse_pgcn
4630: 74 3a 20 20 20 44 61 74 61 20 70 61 67 65 73 20  t:   Data pages 
4640: 69 6e 20 74 68 65 20 66 69 6c 65 2e 0a 23 20 69  in the file..# i
4650: 6e 75 73 65 5f 70 65 72 63 65 6e 74 3a 20 50 65  nuse_percent: Pe
4660: 72 63 65 6e 74 61 67 65 20 6f 66 20 70 61 67 65  rcentage of page
4670: 73 20 75 73 65 64 20 74 6f 20 73 74 6f 72 65 20  s used to store 
4680: 64 61 74 61 2e 0a 23 20 66 72 65 65 5f 70 67 63  data..# free_pgc
4690: 6e 74 3a 20 20 20 20 46 72 65 65 20 70 61 67 65  nt:    Free page
46a0: 73 20 63 61 6c 63 75 6c 61 74 65 64 20 61 73 20  s calculated as 
46b0: 28 3c 74 6f 74 61 6c 20 70 61 67 65 73 3e 20 2d  (<total pages> -
46c0: 20 3c 69 6e 2d 75 73 65 20 70 61 67 65 73 3e 29   <in-use pages>)
46d0: 0a 23 20 66 72 65 65 5f 70 67 63 6e 74 32 3a 20  .# free_pgcnt2: 
46e0: 20 20 46 72 65 65 20 70 61 67 65 73 20 69 6e 20    Free pages in 
46f0: 74 68 65 20 66 69 6c 65 20 61 63 63 6f 72 64 69  the file accordi
4700: 6e 67 20 74 6f 20 74 68 65 20 66 69 6c 65 20 68  ng to the file h
4710: 65 61 64 65 72 2e 0a 23 20 66 72 65 65 5f 70 65  eader..# free_pe
4720: 72 63 65 6e 74 3a 20 20 50 65 72 63 65 6e 74 61  rcent:  Percenta
4730: 67 65 20 6f 66 20 66 69 6c 65 20 63 6f 6e 73 75  ge of file consu
4740: 6d 65 64 20 62 79 20 66 72 65 65 20 70 61 67 65  med by free page
4750: 73 20 28 63 61 6c 63 75 6c 61 74 65 64 29 2e 0a  s (calculated)..
4760: 23 20 66 72 65 65 5f 70 65 72 63 65 6e 74 32 3a  # free_percent2:
4770: 20 50 65 72 63 65 6e 74 61 67 65 20 6f 66 20 66   Percentage of f
4780: 69 6c 65 20 63 6f 6e 73 75 6d 65 64 20 62 79 20  ile consumed by 
4790: 66 72 65 65 20 70 61 67 65 73 20 28 68 65 61 64  free pages (head
47a0: 65 72 29 2e 0a 23 20 6e 74 61 62 6c 65 3a 20 20  er)..# ntable:  
47b0: 20 20 20 20 20 20 4e 75 6d 62 65 72 20 6f 66 20        Number of 
47c0: 74 61 62 6c 65 73 20 69 6e 20 74 68 65 20 64 62  tables in the db
47d0: 2e 0a 23 20 6e 69 6e 64 65 78 3a 20 20 20 20 20  ..# nindex:     
47e0: 20 20 20 4e 75 6d 62 65 72 20 6f 66 20 69 6e 64     Number of ind
47f0: 69 63 65 73 20 69 6e 20 74 68 65 20 64 62 2e 0a  ices in the db..
4800: 23 20 6e 61 75 74 6f 69 6e 64 65 78 3a 20 20 20  # nautoindex:   
4810: 20 4e 75 6d 62 65 72 20 6f 66 20 69 6e 64 69 63   Number of indic
4820: 65 73 20 63 72 65 61 74 65 64 20 61 75 74 6f 6d  es created autom
4830: 61 74 69 63 61 6c 6c 79 2e 0a 23 20 6e 6d 61 6e  atically..# nman
4840: 69 6e 64 65 78 3a 20 20 20 20 20 4e 75 6d 62 65  index:     Numbe
4850: 72 20 6f 66 20 69 6e 64 69 63 65 73 20 63 72 65  r of indices cre
4860: 61 74 65 64 20 6d 61 6e 75 61 6c 6c 79 2e 0a 23  ated manually..#
4870: 20 75 73 65 72 5f 70 61 79 6c 6f 61 64 3a 20 20   user_payload:  
4880: 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  Number of bytes 
4890: 6f 66 20 70 61 79 6c 6f 61 64 20 69 6e 20 74 61  of payload in ta
48a0: 62 6c 65 20 62 74 72 65 65 73 20 0a 23 20 20 20  ble btrees .#   
48b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 28 6e 6f               (no
48c0: 74 20 69 6e 63 6c 75 64 69 6e 67 20 73 71 6c 69  t including sqli
48d0: 74 65 5f 6d 61 73 74 65 72 29 0a 23 20 75 73 65  te_master).# use
48e0: 72 5f 70 65 72 63 65 6e 74 3a 20 20 24 75 73 65  r_percent:  $use
48f0: 72 5f 70 61 79 6c 6f 61 64 20 61 73 20 61 20 70  r_payload as a p
4900: 65 72 63 65 6e 74 61 67 65 20 6f 66 20 74 6f 74  ercentage of tot
4910: 61 6c 20 66 69 6c 65 20 73 69 7a 65 2e 0a 0a 23  al file size...#
4920: 23 23 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  ## The following
4930: 2c 20 73 65 74 74 69 6e 67 20 24 66 69 6c 65 5f  , setting $file_
4940: 62 79 74 65 73 20 62 61 73 65 64 20 6f 6e 20 74  bytes based on t
4950: 68 65 20 61 63 74 75 61 6c 20 73 69 7a 65 20 6f  he actual size o
4960: 66 20 74 68 65 20 66 69 6c 65 0a 23 23 23 20 6f  f the file.### o
4970: 6e 20 64 69 73 6b 2c 20 63 61 75 73 65 73 20 74  n disk, causes t
4980: 68 69 73 20 74 6f 6f 6c 20 74 6f 20 63 68 6f 6b  his tool to chok
4990: 65 20 6f 6e 20 7a 69 70 76 66 73 20 64 61 74 61  e on zipvfs data
49a0: 62 61 73 65 73 2e 20 53 6f 20 73 65 74 20 69 74  bases. So set it
49b0: 20 62 61 73 65 64 0a 23 23 23 20 6f 6e 20 74 68   based.### on th
49c0: 65 20 72 65 74 75 72 6e 20 6f 66 20 5b 50 52 41  e return of [PRA
49d0: 47 4d 41 20 70 61 67 65 5f 63 6f 75 6e 74 5d 20  GMA page_count] 
49e0: 69 6e 73 74 65 61 64 2e 0a 69 66 20 30 20 7b 0a  instead..if 0 {.
49f0: 20 20 73 65 74 20 66 69 6c 65 5f 62 79 74 65 73    set file_bytes
4a00: 20 20 5b 66 69 6c 65 20 73 69 7a 65 20 24 66 69    [file size $fi
4a10: 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 5d 0a 20  le_to_analyze]. 
4a20: 20 73 65 74 20 66 69 6c 65 5f 70 67 63 6e 74 20   set file_pgcnt 
4a30: 20 5b 65 78 70 72 20 7b 24 66 69 6c 65 5f 62 79   [expr {$file_by
4a40: 74 65 73 2f 24 70 61 67 65 53 69 7a 65 7d 5d 0a  tes/$pageSize}].
4a50: 7d 0a 73 65 74 20 66 69 6c 65 5f 70 67 63 6e 74  }.set file_pgcnt
4a60: 20 20 5b 64 62 20 6f 6e 65 20 7b 50 52 41 47 4d    [db one {PRAGM
4a70: 41 20 70 61 67 65 5f 63 6f 75 6e 74 7d 5d 0a 73  A page_count}].s
4a80: 65 74 20 66 69 6c 65 5f 62 79 74 65 73 20 20 5b  et file_bytes  [
4a90: 65 78 70 72 20 7b 24 66 69 6c 65 5f 70 67 63 6e  expr {$file_pgcn
4aa0: 74 20 2a 20 24 70 61 67 65 53 69 7a 65 7d 5d 0a  t * $pageSize}].
4ab0: 0a 73 65 74 20 61 76 5f 70 67 63 6e 74 20 20 20  .set av_pgcnt   
4ac0: 20 5b 61 75 74 6f 76 61 63 75 75 6d 5f 6f 76 65   [autovacuum_ove
4ad0: 72 68 65 61 64 20 24 66 69 6c 65 5f 70 67 63 6e  rhead $file_pgcn
4ae0: 74 20 24 70 61 67 65 53 69 7a 65 5d 0a 73 65 74  t $pageSize].set
4af0: 20 61 76 5f 70 65 72 63 65 6e 74 20 20 5b 70 65   av_percent  [pe
4b00: 72 63 65 6e 74 20 24 61 76 5f 70 67 63 6e 74 20  rcent $av_pgcnt 
4b10: 24 66 69 6c 65 5f 70 67 63 6e 74 5d 0a 0a 73 65  $file_pgcnt]..se
4b20: 74 20 73 71 6c 20 7b 53 45 4c 45 43 54 20 73 75  t sql {SELECT su
4b30: 6d 28 6c 65 61 66 5f 70 61 67 65 73 2b 69 6e 74  m(leaf_pages+int
4b40: 5f 70 61 67 65 73 2b 6f 76 66 6c 5f 70 61 67 65  _pages+ovfl_page
4b50: 73 29 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73  s) FROM space_us
4b60: 65 64 7d 0a 73 65 74 20 69 6e 75 73 65 5f 70 67  ed}.set inuse_pg
4b70: 63 6e 74 20 20 20 5b 65 78 70 72 20 77 69 64 65  cnt   [expr wide
4b80: 28 5b 6d 65 6d 20 65 76 61 6c 20 24 73 71 6c 5d  ([mem eval $sql]
4b90: 29 5d 0a 73 65 74 20 69 6e 75 73 65 5f 70 65 72  )].set inuse_per
4ba0: 63 65 6e 74 20 5b 70 65 72 63 65 6e 74 20 24 69  cent [percent $i
4bb0: 6e 75 73 65 5f 70 67 63 6e 74 20 24 66 69 6c 65  nuse_pgcnt $file
4bc0: 5f 70 67 63 6e 74 5d 0a 0a 73 65 74 20 66 72 65  _pgcnt]..set fre
4bd0: 65 5f 70 67 63 6e 74 20 20 20 20 5b 65 78 70 72  e_pgcnt    [expr
4be0: 20 7b 24 66 69 6c 65 5f 70 67 63 6e 74 2d 24 69   {$file_pgcnt-$i
4bf0: 6e 75 73 65 5f 70 67 63 6e 74 2d 24 61 76 5f 70  nuse_pgcnt-$av_p
4c00: 67 63 6e 74 7d 5d 0a 73 65 74 20 66 72 65 65 5f  gcnt}].set free_
4c10: 70 65 72 63 65 6e 74 20 20 5b 70 65 72 63 65 6e  percent  [percen
4c20: 74 20 24 66 72 65 65 5f 70 67 63 6e 74 20 24 66  t $free_pgcnt $f
4c30: 69 6c 65 5f 70 67 63 6e 74 5d 0a 73 65 74 20 66  ile_pgcnt].set f
4c40: 72 65 65 5f 70 67 63 6e 74 32 20 20 20 5b 64 62  ree_pgcnt2   [db
4c50: 20 6f 6e 65 20 7b 50 52 41 47 4d 41 20 66 72 65   one {PRAGMA fre
4c60: 65 6c 69 73 74 5f 63 6f 75 6e 74 7d 5d 0a 73 65  elist_count}].se
4c70: 74 20 66 72 65 65 5f 70 65 72 63 65 6e 74 32 20  t free_percent2 
4c80: 5b 70 65 72 63 65 6e 74 20 24 66 72 65 65 5f 70  [percent $free_p
4c90: 67 63 6e 74 32 20 24 66 69 6c 65 5f 70 67 63 6e  gcnt2 $file_pgcn
4ca0: 74 5d 0a 0a 73 65 74 20 66 69 6c 65 5f 70 67 63  t]..set file_pgc
4cb0: 6e 74 32 20 5b 65 78 70 72 20 7b 24 69 6e 75 73  nt2 [expr {$inus
4cc0: 65 5f 70 67 63 6e 74 2b 24 66 72 65 65 5f 70 67  e_pgcnt+$free_pg
4cd0: 63 6e 74 32 2b 24 61 76 5f 70 67 63 6e 74 7d 5d  cnt2+$av_pgcnt}]
4ce0: 0a 0a 73 65 74 20 6e 74 61 62 6c 65 20 5b 64 62  ..set ntable [db
4cf0: 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 63 6f   eval {SELECT co
4d00: 75 6e 74 28 2a 29 2b 31 20 46 52 4f 4d 20 73 71  unt(*)+1 FROM sq
4d10: 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52  lite_master WHER
4d20: 45 20 74 79 70 65 3d 27 74 61 62 6c 65 27 7d 5d  E type='table'}]
4d30: 0a 73 65 74 20 6e 69 6e 64 65 78 20 5b 64 62 20  .set nindex [db 
4d40: 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 63 6f 75  eval {SELECT cou
4d50: 6e 74 28 2a 29 20 46 52 4f 4d 20 73 71 6c 69 74  nt(*) FROM sqlit
4d60: 65 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 74  e_master WHERE t
4d70: 79 70 65 3d 27 69 6e 64 65 78 27 7d 5d 0a 73 65  ype='index'}].se
4d80: 74 20 73 71 6c 20 7b 53 45 4c 45 43 54 20 63 6f  t sql {SELECT co
4d90: 75 6e 74 28 2a 29 20 46 52 4f 4d 20 73 71 6c 69  unt(*) FROM sqli
4da0: 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20  te_master WHERE 
4db0: 6e 61 6d 65 20 4c 49 4b 45 20 27 73 71 6c 69 74  name LIKE 'sqlit
4dc0: 65 5f 61 75 74 6f 69 6e 64 65 78 25 27 7d 0a 73  e_autoindex%'}.s
4dd0: 65 74 20 6e 61 75 74 6f 69 6e 64 65 78 20 5b 64  et nautoindex [d
4de0: 62 20 65 76 61 6c 20 24 73 71 6c 5d 0a 73 65 74  b eval $sql].set
4df0: 20 6e 6d 61 6e 69 6e 64 65 78 20 5b 65 78 70 72   nmanindex [expr
4e00: 20 7b 24 6e 69 6e 64 65 78 2d 24 6e 61 75 74 6f   {$nindex-$nauto
4e10: 69 6e 64 65 78 7d 5d 0a 0a 23 20 73 65 74 20 74  index}]..# set t
4e20: 6f 74 61 6c 5f 70 61 79 6c 6f 61 64 20 5b 6d 65  otal_payload [me
4e30: 6d 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20 73  m eval "SELECT s
4e40: 75 6d 28 70 61 79 6c 6f 61 64 29 20 46 52 4f 4d  um(payload) FROM
4e50: 20 73 70 61 63 65 5f 75 73 65 64 22 5d 0a 73 65   space_used"].se
4e60: 74 20 75 73 65 72 5f 70 61 79 6c 6f 61 64 20 5b  t user_payload [
4e70: 6d 65 6d 20 6f 6e 65 20 7b 53 45 4c 45 43 54 20  mem one {SELECT 
4e80: 69 6e 74 28 73 75 6d 28 70 61 79 6c 6f 61 64 29  int(sum(payload)
4e90: 29 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73 65  ) FROM space_use
4ea0: 64 0a 20 20 20 20 20 57 48 45 52 45 20 4e 4f 54  d.     WHERE NOT
4eb0: 20 69 73 5f 69 6e 64 65 78 20 41 4e 44 20 6e 61   is_index AND na
4ec0: 6d 65 20 4e 4f 54 20 4c 49 4b 45 20 27 73 71 6c  me NOT LIKE 'sql
4ed0: 69 74 65 5f 6d 61 73 74 65 72 27 7d 5d 0a 73 65  ite_master'}].se
4ee0: 74 20 75 73 65 72 5f 70 65 72 63 65 6e 74 20 5b  t user_percent [
4ef0: 70 65 72 63 65 6e 74 20 24 75 73 65 72 5f 70 61  percent $user_pa
4f00: 79 6c 6f 61 64 20 24 66 69 6c 65 5f 62 79 74 65  yload $file_byte
4f10: 73 5d 0a 0a 23 20 4f 75 74 70 75 74 20 74 68 65  s]..# Output the
4f20: 20 73 75 6d 6d 61 72 79 20 73 74 61 74 69 73 74   summary statist
4f30: 69 63 73 20 63 61 6c 63 75 6c 61 74 65 64 20 61  ics calculated a
4f40: 62 6f 76 65 2e 0a 23 0a 70 75 74 73 20 22 2f 2a  bove..#.puts "/*
4f50: 2a 20 44 69 73 6b 2d 53 70 61 63 65 20 55 74 69  * Disk-Space Uti
4f60: 6c 69 7a 61 74 69 6f 6e 20 52 65 70 6f 72 74 20  lization Report 
4f70: 46 6f 72 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61  For $root_filena
4f80: 6d 65 22 0a 70 75 74 73 20 22 22 0a 73 74 61 74  me".puts "".stat
4f90: 6c 69 6e 65 20 7b 50 61 67 65 20 73 69 7a 65 20  line {Page size 
4fa0: 69 6e 20 62 79 74 65 73 7d 20 24 70 61 67 65 53  in bytes} $pageS
4fb0: 69 7a 65 0a 73 74 61 74 6c 69 6e 65 20 7b 50 61  ize.statline {Pa
4fc0: 67 65 73 20 69 6e 20 74 68 65 20 77 68 6f 6c 65  ges in the whole
4fd0: 20 66 69 6c 65 20 28 6d 65 61 73 75 72 65 64 29   file (measured)
4fe0: 7d 20 24 66 69 6c 65 5f 70 67 63 6e 74 0a 73 74  } $file_pgcnt.st
4ff0: 61 74 6c 69 6e 65 20 7b 50 61 67 65 73 20 69 6e  atline {Pages in
5000: 20 74 68 65 20 77 68 6f 6c 65 20 66 69 6c 65 20   the whole file 
5010: 28 63 61 6c 63 75 6c 61 74 65 64 29 7d 20 24 66  (calculated)} $f
5020: 69 6c 65 5f 70 67 63 6e 74 32 0a 73 74 61 74 6c  ile_pgcnt2.statl
5030: 69 6e 65 20 7b 50 61 67 65 73 20 74 68 61 74 20  ine {Pages that 
5040: 73 74 6f 72 65 20 64 61 74 61 7d 20 24 69 6e 75  store data} $inu
5050: 73 65 5f 70 67 63 6e 74 20 24 69 6e 75 73 65 5f  se_pgcnt $inuse_
5060: 70 65 72 63 65 6e 74 0a 73 74 61 74 6c 69 6e 65  percent.statline
5070: 20 7b 50 61 67 65 73 20 6f 6e 20 74 68 65 20 66   {Pages on the f
5080: 72 65 65 6c 69 73 74 20 28 70 65 72 20 68 65 61  reelist (per hea
5090: 64 65 72 29 7d 20 24 66 72 65 65 5f 70 67 63 6e  der)} $free_pgcn
50a0: 74 32 20 24 66 72 65 65 5f 70 65 72 63 65 6e 74  t2 $free_percent
50b0: 32 0a 73 74 61 74 6c 69 6e 65 20 7b 50 61 67 65  2.statline {Page
50c0: 73 20 6f 6e 20 74 68 65 20 66 72 65 65 6c 69 73  s on the freelis
50d0: 74 20 28 63 61 6c 63 75 6c 61 74 65 64 29 7d 20  t (calculated)} 
50e0: 24 66 72 65 65 5f 70 67 63 6e 74 20 24 66 72 65  $free_pgcnt $fre
50f0: 65 5f 70 65 72 63 65 6e 74 0a 73 74 61 74 6c 69  e_percent.statli
5100: 6e 65 20 7b 50 61 67 65 73 20 6f 66 20 61 75 74  ne {Pages of aut
5110: 6f 2d 76 61 63 75 75 6d 20 6f 76 65 72 68 65 61  o-vacuum overhea
5120: 64 7d 20 24 61 76 5f 70 67 63 6e 74 20 24 61 76  d} $av_pgcnt $av
5130: 5f 70 65 72 63 65 6e 74 0a 73 74 61 74 6c 69 6e  _percent.statlin
5140: 65 20 7b 4e 75 6d 62 65 72 20 6f 66 20 74 61 62  e {Number of tab
5150: 6c 65 73 20 69 6e 20 74 68 65 20 64 61 74 61 62  les in the datab
5160: 61 73 65 7d 20 24 6e 74 61 62 6c 65 0a 73 74 61  ase} $ntable.sta
5170: 74 6c 69 6e 65 20 7b 4e 75 6d 62 65 72 20 6f 66  tline {Number of
5180: 20 69 6e 64 69 63 65 73 7d 20 24 6e 69 6e 64 65   indices} $ninde
5190: 78 0a 73 74 61 74 6c 69 6e 65 20 7b 4e 75 6d 62  x.statline {Numb
51a0: 65 72 20 6f 66 20 64 65 66 69 6e 65 64 20 69 6e  er of defined in
51b0: 64 69 63 65 73 7d 20 24 6e 6d 61 6e 69 6e 64 65  dices} $nmaninde
51c0: 78 0a 73 74 61 74 6c 69 6e 65 20 7b 4e 75 6d 62  x.statline {Numb
51d0: 65 72 20 6f 66 20 69 6d 70 6c 69 65 64 20 69 6e  er of implied in
51e0: 64 69 63 65 73 7d 20 24 6e 61 75 74 6f 69 6e 64  dices} $nautoind
51f0: 65 78 0a 69 66 20 7b 24 69 73 43 6f 6d 70 72 65  ex.if {$isCompre
5200: 73 73 65 64 7d 20 7b 0a 20 20 73 74 61 74 6c 69  ssed} {.  statli
5210: 6e 65 20 7b 53 69 7a 65 20 6f 66 20 75 6e 63 6f  ne {Size of unco
5220: 6d 70 72 65 73 73 65 64 20 63 6f 6e 74 65 6e 74  mpressed content
5230: 20 69 6e 20 62 79 74 65 73 7d 20 24 66 69 6c 65   in bytes} $file
5240: 5f 62 79 74 65 73 0a 20 20 73 65 74 20 65 66 66  _bytes.  set eff
5250: 69 63 69 65 6e 63 79 20 5b 70 65 72 63 65 6e 74  iciency [percent
5260: 20 24 74 72 75 65 5f 66 69 6c 65 5f 73 69 7a 65   $true_file_size
5270: 20 24 66 69 6c 65 5f 62 79 74 65 73 5d 0a 20 20   $file_bytes].  
5280: 73 74 61 74 6c 69 6e 65 20 7b 53 69 7a 65 20 6f  statline {Size o
5290: 66 20 63 6f 6d 70 72 65 73 73 65 64 20 66 69 6c  f compressed fil
52a0: 65 20 6f 6e 20 64 69 73 6b 7d 20 24 74 72 75 65  e on disk} $true
52b0: 5f 66 69 6c 65 5f 73 69 7a 65 20 24 65 66 66 69  _file_size $effi
52c0: 63 69 65 6e 63 79 0a 7d 20 65 6c 73 65 20 7b 0a  ciency.} else {.
52d0: 20 20 73 74 61 74 6c 69 6e 65 20 7b 53 69 7a 65    statline {Size
52e0: 20 6f 66 20 74 68 65 20 66 69 6c 65 20 69 6e 20   of the file in 
52f0: 62 79 74 65 73 7d 20 24 66 69 6c 65 5f 62 79 74  bytes} $file_byt
5300: 65 73 0a 7d 0a 73 74 61 74 6c 69 6e 65 20 7b 42  es.}.statline {B
5310: 79 74 65 73 20 6f 66 20 75 73 65 72 20 70 61 79  ytes of user pay
5320: 6c 6f 61 64 20 73 74 6f 72 65 64 7d 20 24 75 73  load stored} $us
5330: 65 72 5f 70 61 79 6c 6f 61 64 20 24 75 73 65 72  er_payload $user
5340: 5f 70 65 72 63 65 6e 74 0a 0a 23 20 4f 75 74 70  _percent..# Outp
5350: 75 74 20 74 61 62 6c 65 20 72 61 6e 6b 69 6e 67  ut table ranking
5360: 73 0a 23 0a 70 75 74 73 20 22 22 0a 74 69 74 6c  s.#.puts "".titl
5370: 65 6c 69 6e 65 20 22 50 61 67 65 20 63 6f 75 6e  eline "Page coun
5380: 74 73 20 66 6f 72 20 61 6c 6c 20 74 61 62 6c 65  ts for all table
5390: 73 20 77 69 74 68 20 74 68 65 69 72 20 69 6e 64  s with their ind
53a0: 69 63 65 73 22 0a 70 75 74 73 20 22 22 0a 6d 65  ices".puts "".me
53b0: 6d 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 74  m eval {SELECT t
53c0: 62 6c 6e 61 6d 65 2c 20 63 6f 75 6e 74 28 2a 29  blname, count(*)
53d0: 20 41 53 20 63 6e 74 2c 20 0a 20 20 20 20 20 20   AS cnt, .      
53e0: 20 20 20 20 20 20 20 20 69 6e 74 28 73 75 6d 28          int(sum(
53f0: 69 6e 74 5f 70 61 67 65 73 2b 6c 65 61 66 5f 70  int_pages+leaf_p
5400: 61 67 65 73 2b 6f 76 66 6c 5f 70 61 67 65 73 29  ages+ovfl_pages)
5410: 29 20 41 53 20 73 69 7a 65 0a 20 20 20 20 20 20  ) AS size.      
5420: 20 20 20 20 46 52 4f 4d 20 73 70 61 63 65 5f 75      FROM space_u
5430: 73 65 64 20 47 52 4f 55 50 20 42 59 20 74 62 6c  sed GROUP BY tbl
5440: 6e 61 6d 65 20 4f 52 44 45 52 20 42 59 20 73 69  name ORDER BY si
5450: 7a 65 2b 30 20 44 45 53 43 2c 20 74 62 6c 6e 61  ze+0 DESC, tblna
5460: 6d 65 7d 20 7b 7d 20 7b 0a 20 20 73 74 61 74 6c  me} {} {.  statl
5470: 69 6e 65 20 5b 73 74 72 69 6e 67 20 74 6f 75 70  ine [string toup
5480: 70 65 72 20 24 74 62 6c 6e 61 6d 65 5d 20 24 73  per $tblname] $s
5490: 69 7a 65 20 5b 70 65 72 63 65 6e 74 20 24 73 69  ize [percent $si
54a0: 7a 65 20 24 66 69 6c 65 5f 70 67 63 6e 74 5d 0a  ze $file_pgcnt].
54b0: 7d 0a 70 75 74 73 20 22 22 0a 74 69 74 6c 65 6c  }.puts "".titlel
54c0: 69 6e 65 20 22 50 61 67 65 20 63 6f 75 6e 74 73  ine "Page counts
54d0: 20 66 6f 72 20 61 6c 6c 20 74 61 62 6c 65 73 20   for all tables 
54e0: 61 6e 64 20 69 6e 64 69 63 65 73 20 73 65 70 61  and indices sepa
54f0: 72 61 74 65 6c 79 22 0a 70 75 74 73 20 22 22 0a  rately".puts "".
5500: 6d 65 6d 20 65 76 61 6c 20 7b 0a 20 20 53 45 4c  mem eval {.  SEL
5510: 45 43 54 0a 20 20 20 20 20 20 20 75 70 70 65 72  ECT.       upper
5520: 28 6e 61 6d 65 29 20 41 53 20 6e 6d 2c 0a 20 20  (name) AS nm,.  
5530: 20 20 20 20 20 69 6e 74 28 69 6e 74 5f 70 61 67       int(int_pag
5540: 65 73 2b 6c 65 61 66 5f 70 61 67 65 73 2b 6f 76  es+leaf_pages+ov
5550: 66 6c 5f 70 61 67 65 73 29 20 41 53 20 73 69 7a  fl_pages) AS siz
5560: 65 0a 20 20 20 20 46 52 4f 4d 20 73 70 61 63 65  e.    FROM space
5570: 5f 75 73 65 64 0a 20 20 20 4f 52 44 45 52 20 42  _used.   ORDER B
5580: 59 20 73 69 7a 65 2b 30 20 44 45 53 43 2c 20 6e  Y size+0 DESC, n
5590: 61 6d 65 7d 20 7b 7d 20 7b 0a 20 20 73 74 61 74  ame} {} {.  stat
55a0: 6c 69 6e 65 20 24 6e 6d 20 24 73 69 7a 65 20 5b  line $nm $size [
55b0: 70 65 72 63 65 6e 74 20 24 73 69 7a 65 20 24 66  percent $size $f
55c0: 69 6c 65 5f 70 67 63 6e 74 5d 0a 7d 0a 69 66 20  ile_pgcnt].}.if 
55d0: 7b 24 69 73 43 6f 6d 70 72 65 73 73 65 64 7d 20  {$isCompressed} 
55e0: 7b 0a 20 20 70 75 74 73 20 22 22 0a 20 20 74 69  {.  puts "".  ti
55f0: 74 6c 65 6c 69 6e 65 20 22 42 79 74 65 73 20 6f  tleline "Bytes o
5600: 66 20 64 69 73 6b 20 73 70 61 63 65 20 75 73 65  f disk space use
5610: 64 20 61 66 74 65 72 20 63 6f 6d 70 72 65 73 73  d after compress
5620: 69 6f 6e 22 0a 20 20 70 75 74 73 20 22 22 0a 20  ion".  puts "". 
5630: 20 73 65 74 20 63 73 75 6d 20 30 0a 20 20 6d 65   set csum 0.  me
5640: 6d 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 74  m eval {SELECT t
5650: 62 6c 6e 61 6d 65 2c 0a 20 20 20 20 20 20 20 20  blname,.        
5660: 20 20 20 20 20 20 20 20 20 20 69 6e 74 28 73 75            int(su
5670: 6d 28 63 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a  m(compressed_siz
5680: 65 29 29 20 2b 0a 20 20 20 20 20 20 20 20 20 20  e)) +.          
5690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 24                 $
56a0: 63 6f 6d 70 72 65 73 73 4f 76 65 72 68 65 61 64  compressOverhead
56b0: 2a 73 75 6d 28 69 6e 74 5f 70 61 67 65 73 2b 6c  *sum(int_pages+l
56c0: 65 61 66 5f 70 61 67 65 73 2b 6f 76 66 6c 5f 70  eaf_pages+ovfl_p
56d0: 61 67 65 73 29 0a 20 20 20 20 20 20 20 20 20 20  ages).          
56e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 41 53                AS
56f0: 20 63 73 69 7a 65 0a 20 20 20 20 20 20 20 20 20   csize.         
5700: 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73 65 64   FROM space_used
5710: 20 47 52 4f 55 50 20 42 59 20 74 62 6c 6e 61 6d   GROUP BY tblnam
5720: 65 20 4f 52 44 45 52 20 42 59 20 63 73 69 7a 65  e ORDER BY csize
5730: 2b 30 20 44 45 53 43 2c 20 74 62 6c 6e 61 6d 65  +0 DESC, tblname
5740: 7d 20 7b 7d 20 7b 0a 20 20 20 20 69 6e 63 72 20  } {} {.    incr 
5750: 63 73 75 6d 20 24 63 73 69 7a 65 0a 20 20 20 20  csum $csize.    
5760: 73 74 61 74 6c 69 6e 65 20 5b 73 74 72 69 6e 67  statline [string
5770: 20 74 6f 75 70 70 65 72 20 24 74 62 6c 6e 61 6d   toupper $tblnam
5780: 65 5d 20 24 63 73 69 7a 65 20 5b 70 65 72 63 65  e] $csize [perce
5790: 6e 74 20 24 63 73 69 7a 65 20 24 74 72 75 65 5f  nt $csize $true_
57a0: 66 69 6c 65 5f 73 69 7a 65 5d 0a 20 20 7d 0a 20  file_size].  }. 
57b0: 20 73 65 74 20 6f 76 65 72 68 65 61 64 20 5b 65   set overhead [e
57c0: 78 70 72 20 7b 24 74 72 75 65 5f 66 69 6c 65 5f  xpr {$true_file_
57d0: 73 69 7a 65 20 2d 20 24 63 73 75 6d 7d 5d 0a 20  size - $csum}]. 
57e0: 20 69 66 20 7b 24 6f 76 65 72 68 65 61 64 3e 30   if {$overhead>0
57f0: 7d 20 7b 0a 20 20 20 20 73 74 61 74 6c 69 6e 65  } {.    statline
5800: 20 7b 48 65 61 64 65 72 20 61 6e 64 20 66 72 65   {Header and fre
5810: 65 20 73 70 61 63 65 7d 20 24 6f 76 65 72 68 65  e space} $overhe
5820: 61 64 20 5b 70 65 72 63 65 6e 74 20 24 6f 76 65  ad [percent $ove
5830: 72 68 65 61 64 20 24 74 72 75 65 5f 66 69 6c 65  rhead $true_file
5840: 5f 73 69 7a 65 5d 0a 20 20 7d 0a 7d 0a 0a 23 20  _size].  }.}..# 
5850: 4f 75 74 70 75 74 20 73 75 62 72 65 70 6f 72 74  Output subreport
5860: 73 0a 23 0a 69 66 20 7b 24 6e 69 6e 64 65 78 3e  s.#.if {$nindex>
5870: 30 7d 20 7b 0a 20 20 73 75 62 72 65 70 6f 72 74  0} {.  subreport
5880: 20 7b 41 6c 6c 20 74 61 62 6c 65 73 20 61 6e 64   {All tables and
5890: 20 69 6e 64 69 63 65 73 7d 20 31 20 30 0a 7d 0a   indices} 1 0.}.
58a0: 73 75 62 72 65 70 6f 72 74 20 7b 41 6c 6c 20 74  subreport {All t
58b0: 61 62 6c 65 73 7d 20 7b 4e 4f 54 20 69 73 5f 69  ables} {NOT is_i
58c0: 6e 64 65 78 7d 20 30 0a 69 66 20 7b 24 6e 69 6e  ndex} 0.if {$nin
58d0: 64 65 78 3e 30 7d 20 7b 0a 20 20 73 75 62 72 65  dex>0} {.  subre
58e0: 70 6f 72 74 20 7b 41 6c 6c 20 69 6e 64 69 63 65  port {All indice
58f0: 73 7d 20 7b 69 73 5f 69 6e 64 65 78 7d 20 30 0a  s} {is_index} 0.
5900: 7d 0a 66 6f 72 65 61 63 68 20 74 62 6c 20 5b 6d  }.foreach tbl [m
5910: 65 6d 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20  em eval {SELECT 
5920: 44 49 53 54 49 4e 43 54 20 74 62 6c 6e 61 6d 65  DISTINCT tblname
5930: 20 6e 61 6d 65 20 46 52 4f 4d 20 73 70 61 63 65   name FROM space
5940: 5f 75 73 65 64 0a 20 20 20 20 20 20 20 20 20 20  _used.          
5950: 20 20 20 20 20 20 20 20 20 20 20 20 20 4f 52 44               ORD
5960: 45 52 20 42 59 20 6e 61 6d 65 7d 5d 20 7b 0a 20  ER BY name}] {. 
5970: 20 73 65 74 20 71 6e 20 5b 71 75 6f 74 65 20 24   set qn [quote $
5980: 74 62 6c 5d 0a 20 20 73 65 74 20 6e 61 6d 65 20  tbl].  set name 
5990: 5b 73 74 72 69 6e 67 20 74 6f 75 70 70 65 72 20  [string toupper 
59a0: 24 74 62 6c 5d 0a 20 20 73 65 74 20 6e 20 5b 6d  $tbl].  set n [m
59b0: 65 6d 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20  em eval {SELECT 
59c0: 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20 73 70  count(*) FROM sp
59d0: 61 63 65 5f 75 73 65 64 20 57 48 45 52 45 20 74  ace_used WHERE t
59e0: 62 6c 6e 61 6d 65 3d 24 74 62 6c 7d 5d 0a 20 20  blname=$tbl}].  
59f0: 69 66 20 7b 24 6e 3e 31 7d 20 7b 0a 20 20 20 20  if {$n>1} {.    
5a00: 73 65 74 20 69 64 78 6c 69 73 74 20 5b 6d 65 6d  set idxlist [mem
5a10: 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20 6e 61   eval "SELECT na
5a20: 6d 65 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73  me FROM space_us
5a30: 65 64 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ed.             
5a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 57                 W
5a50: 48 45 52 45 20 74 62 6c 6e 61 6d 65 3d 27 24 71  HERE tblname='$q
5a60: 6e 27 20 41 4e 44 20 69 73 5f 69 6e 64 65 78 0a  n' AND is_index.
5a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a80: 20 20 20 20 20 20 20 20 20 20 20 20 4f 52 44 45              ORDE
5a90: 52 20 42 59 20 31 22 5d 0a 20 20 20 20 73 75 62  R BY 1"].    sub
5aa0: 72 65 70 6f 72 74 20 22 54 61 62 6c 65 20 24 6e  report "Table $n
5ab0: 61 6d 65 20 61 6e 64 20 61 6c 6c 20 69 74 73 20  ame and all its 
5ac0: 69 6e 64 69 63 65 73 22 20 22 74 62 6c 6e 61 6d  indices" "tblnam
5ad0: 65 3d 27 24 71 6e 27 22 20 30 0a 20 20 20 20 73  e='$qn'" 0.    s
5ae0: 75 62 72 65 70 6f 72 74 20 22 54 61 62 6c 65 20  ubreport "Table 
5af0: 24 6e 61 6d 65 20 77 2f 6f 20 61 6e 79 20 69 6e  $name w/o any in
5b00: 64 69 63 65 73 22 20 22 6e 61 6d 65 3d 27 24 71  dices" "name='$q
5b10: 6e 27 22 20 31 0a 20 20 20 20 69 66 20 7b 5b 6c  n'" 1.    if {[l
5b20: 6c 65 6e 67 74 68 20 24 69 64 78 6c 69 73 74 5d  length $idxlist]
5b30: 3e 31 7d 20 7b 0a 20 20 20 20 20 20 73 75 62 72  >1} {.      subr
5b40: 65 70 6f 72 74 20 22 49 6e 64 69 63 65 73 20 6f  eport "Indices o
5b50: 66 20 74 61 62 6c 65 20 24 6e 61 6d 65 22 20 22  f table $name" "
5b60: 74 62 6c 6e 61 6d 65 3d 27 24 71 6e 27 20 41 4e  tblname='$qn' AN
5b70: 44 20 69 73 5f 69 6e 64 65 78 22 20 30 0a 20 20  D is_index" 0.  
5b80: 20 20 7d 0a 20 20 20 20 66 6f 72 65 61 63 68 20    }.    foreach 
5b90: 69 64 78 20 24 69 64 78 6c 69 73 74 20 7b 0a 20  idx $idxlist {. 
5ba0: 20 20 20 20 20 73 65 74 20 71 69 64 78 20 5b 71       set qidx [q
5bb0: 75 6f 74 65 20 24 69 64 78 5d 0a 20 20 20 20 20  uote $idx].     
5bc0: 20 73 75 62 72 65 70 6f 72 74 20 22 49 6e 64 65   subreport "Inde
5bd0: 78 20 5b 73 74 72 69 6e 67 20 74 6f 75 70 70 65  x [string touppe
5be0: 72 20 24 69 64 78 5d 20 6f 66 20 74 61 62 6c 65  r $idx] of table
5bf0: 20 24 6e 61 6d 65 22 20 22 6e 61 6d 65 3d 27 24   $name" "name='$
5c00: 71 69 64 78 27 22 20 31 0a 20 20 20 20 7d 0a 20  qidx'" 1.    }. 
5c10: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 75   } else {.    su
5c20: 62 72 65 70 6f 72 74 20 22 54 61 62 6c 65 20 24  breport "Table $
5c30: 6e 61 6d 65 22 20 22 6e 61 6d 65 3d 27 24 71 6e  name" "name='$qn
5c40: 27 22 20 31 0a 20 20 7d 0a 7d 0a 0a 23 20 4f 75  '" 1.  }.}..# Ou
5c50: 74 70 75 74 20 69 6e 73 74 72 75 63 74 69 6f 6e  tput instruction
5c60: 73 20 6f 6e 20 77 68 61 74 20 74 68 65 20 6e 75  s on what the nu
5c70: 6d 62 65 72 73 20 61 62 6f 76 65 20 6d 65 61 6e  mbers above mean
5c80: 2e 0a 23 0a 70 75 74 73 20 22 22 0a 74 69 74 6c  ..#.puts "".titl
5c90: 65 6c 69 6e 65 20 44 65 66 69 6e 69 74 69 6f 6e  eline Definition
5ca0: 73 0a 70 75 74 73 20 7b 0a 50 61 67 65 20 73 69  s.puts {.Page si
5cb0: 7a 65 20 69 6e 20 62 79 74 65 73 0a 0a 20 20 20  ze in bytes..   
5cc0: 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62   The number of b
5cd0: 79 74 65 73 20 69 6e 20 61 20 73 69 6e 67 6c 65  ytes in a single
5ce0: 20 70 61 67 65 20 6f 66 20 74 68 65 20 64 61 74   page of the dat
5cf0: 61 62 61 73 65 20 66 69 6c 65 2e 20 20 0a 20 20  abase file.  .  
5d00: 20 20 55 73 75 61 6c 6c 79 20 31 30 32 34 2e 0a    Usually 1024..
5d10: 0a 4e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73  .Number of pages
5d20: 20 69 6e 20 74 68 65 20 77 68 6f 6c 65 20 66 69   in the whole fi
5d30: 6c 65 0a 7d 0a 70 75 74 73 20 22 20 20 20 20 54  le.}.puts "    T
5d40: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 24 70 61  he number of $pa
5d50: 67 65 53 69 7a 65 2d 62 79 74 65 20 70 61 67 65  geSize-byte page
5d60: 73 20 74 68 61 74 20 67 6f 20 69 6e 74 6f 20 66  s that go into f
5d70: 6f 72 6d 69 6e 67 20 74 68 65 20 63 6f 6d 70 6c  orming the compl
5d80: 65 74 65 0a 20 20 20 20 64 61 74 61 62 61 73 65  ete.    database
5d90: 22 0a 70 75 74 73 20 7b 0a 50 61 67 65 73 20 74  ".puts {.Pages t
5da0: 68 61 74 20 73 74 6f 72 65 20 64 61 74 61 0a 0a  hat store data..
5db0: 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f      The number o
5dc0: 66 20 70 61 67 65 73 20 74 68 61 74 20 73 74 6f  f pages that sto
5dd0: 72 65 20 64 61 74 61 2c 20 65 69 74 68 65 72 20  re data, either 
5de0: 61 73 20 70 72 69 6d 61 72 79 20 42 2a 54 72 65  as primary B*Tre
5df0: 65 20 70 61 67 65 73 20 6f 72 0a 20 20 20 20 61  e pages or.    a
5e00: 73 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73  s overflow pages
5e10: 2e 20 20 54 68 65 20 6e 75 6d 62 65 72 20 61 74  .  The number at
5e20: 20 74 68 65 20 72 69 67 68 74 20 69 73 20 74 68   the right is th
5e30: 65 20 64 61 74 61 20 70 61 67 65 73 20 64 69 76  e data pages div
5e40: 69 64 65 64 20 62 79 0a 20 20 20 20 74 68 65 20  ided by.    the 
5e50: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  total number of 
5e60: 70 61 67 65 73 20 69 6e 20 74 68 65 20 66 69 6c  pages in the fil
5e70: 65 2e 0a 0a 50 61 67 65 73 20 6f 6e 20 74 68 65  e...Pages on the
5e80: 20 66 72 65 65 6c 69 73 74 0a 0a 20 20 20 20 54   freelist..    T
5e90: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  he number of pag
5ea0: 65 73 20 74 68 61 74 20 61 72 65 20 6e 6f 74 20  es that are not 
5eb0: 63 75 72 72 65 6e 74 6c 79 20 69 6e 20 75 73 65  currently in use
5ec0: 20 62 75 74 20 61 72 65 20 72 65 73 65 72 76 65   but are reserve
5ed0: 64 20 66 6f 72 0a 20 20 20 20 66 75 74 75 72 65  d for.    future
5ee0: 20 75 73 65 2e 20 20 54 68 65 20 70 65 72 63 65   use.  The perce
5ef0: 6e 74 61 67 65 20 61 74 20 74 68 65 20 72 69 67  ntage at the rig
5f00: 68 74 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72  ht is the number
5f10: 20 6f 66 20 66 72 65 65 6c 69 73 74 20 70 61 67   of freelist pag
5f20: 65 73 0a 20 20 20 20 64 69 76 69 64 65 64 20 62  es.    divided b
5f30: 79 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62  y the total numb
5f40: 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74  er of pages in t
5f50: 68 65 20 66 69 6c 65 2e 0a 0a 50 61 67 65 73 20  he file...Pages 
5f60: 6f 66 20 61 75 74 6f 2d 76 61 63 75 75 6d 20 6f  of auto-vacuum o
5f70: 76 65 72 68 65 61 64 0a 0a 20 20 20 20 54 68 65  verhead..    The
5f80: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
5f90: 20 74 68 61 74 20 73 74 6f 72 65 20 64 61 74 61   that store data
5fa0: 20 75 73 65 64 20 62 79 20 74 68 65 20 64 61 74   used by the dat
5fb0: 61 62 61 73 65 20 74 6f 20 66 61 63 69 6c 69 74  abase to facilit
5fc0: 61 74 65 0a 20 20 20 20 61 75 74 6f 2d 76 61 63  ate.    auto-vac
5fd0: 75 75 6d 2e 20 54 68 69 73 20 69 73 20 7a 65 72  uum. This is zer
5fe0: 6f 20 66 6f 72 20 64 61 74 61 62 61 73 65 73 20  o for databases 
5ff0: 74 68 61 74 20 64 6f 20 6e 6f 74 20 73 75 70 70  that do not supp
6000: 6f 72 74 20 61 75 74 6f 2d 76 61 63 75 75 6d 2e  ort auto-vacuum.
6010: 0a 0a 4e 75 6d 62 65 72 20 6f 66 20 74 61 62 6c  ..Number of tabl
6020: 65 73 20 69 6e 20 74 68 65 20 64 61 74 61 62 61  es in the databa
6030: 73 65 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d 62  se..    The numb
6040: 65 72 20 6f 66 20 74 61 62 6c 65 73 20 69 6e 20  er of tables in 
6050: 74 68 65 20 64 61 74 61 62 61 73 65 2c 20 69 6e  the database, in
6060: 63 6c 75 64 69 6e 67 20 74 68 65 20 53 51 4c 49  cluding the SQLI
6070: 54 45 5f 4d 41 53 54 45 52 20 74 61 62 6c 65 0a  TE_MASTER table.
6080: 20 20 20 20 75 73 65 64 20 74 6f 20 73 74 6f 72      used to stor
6090: 65 20 73 63 68 65 6d 61 20 69 6e 66 6f 72 6d 61  e schema informa
60a0: 74 69 6f 6e 2e 0a 0a 4e 75 6d 62 65 72 20 6f 66  tion...Number of
60b0: 20 69 6e 64 69 63 65 73 0a 0a 20 20 20 20 54 68   indices..    Th
60c0: 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f  e total number o
60d0: 66 20 69 6e 64 69 63 65 73 20 69 6e 20 74 68 65  f indices in the
60e0: 20 64 61 74 61 62 61 73 65 2e 0a 0a 4e 75 6d 62   database...Numb
60f0: 65 72 20 6f 66 20 64 65 66 69 6e 65 64 20 69 6e  er of defined in
6100: 64 69 63 65 73 0a 0a 20 20 20 20 54 68 65 20 6e  dices..    The n
6110: 75 6d 62 65 72 20 6f 66 20 69 6e 64 69 63 65 73  umber of indices
6120: 20 63 72 65 61 74 65 64 20 75 73 69 6e 67 20 61   created using a
6130: 6e 20 65 78 70 6c 69 63 69 74 20 43 52 45 41 54  n explicit CREAT
6140: 45 20 49 4e 44 45 58 20 73 74 61 74 65 6d 65 6e  E INDEX statemen
6150: 74 2e 0a 0a 4e 75 6d 62 65 72 20 6f 66 20 69 6d  t...Number of im
6160: 70 6c 69 65 64 20 69 6e 64 69 63 65 73 0a 0a 20  plied indices.. 
6170: 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66     The number of
6180: 20 69 6e 64 69 63 65 73 20 75 73 65 64 20 74 6f   indices used to
6190: 20 69 6d 70 6c 65 6d 65 6e 74 20 50 52 49 4d 41   implement PRIMA
61a0: 52 59 20 4b 45 59 20 6f 72 20 55 4e 49 51 55 45  RY KEY or UNIQUE
61b0: 20 63 6f 6e 73 74 72 61 69 6e 74 73 0a 20 20 20   constraints.   
61c0: 20 6f 6e 20 74 61 62 6c 65 73 2e 0a 0a 53 69 7a   on tables...Siz
61d0: 65 20 6f 66 20 74 68 65 20 66 69 6c 65 20 69 6e  e of the file in
61e0: 20 62 79 74 65 73 0a 0a 20 20 20 20 54 68 65 20   bytes..    The 
61f0: 74 6f 74 61 6c 20 61 6d 6f 75 6e 74 20 6f 66 20  total amount of 
6200: 64 69 73 6b 20 73 70 61 63 65 20 75 73 65 64 20  disk space used 
6210: 62 79 20 74 68 65 20 65 6e 74 69 72 65 20 64 61  by the entire da
6220: 74 61 62 61 73 65 20 66 69 6c 65 73 2e 0a 0a 42  tabase files...B
6230: 79 74 65 73 20 6f 66 20 75 73 65 72 20 70 61 79  ytes of user pay
6240: 6c 6f 61 64 20 73 74 6f 72 65 64 0a 0a 20 20 20  load stored..   
6250: 20 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65   The total numbe
6260: 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 75 73  r of bytes of us
6270: 65 72 20 70 61 79 6c 6f 61 64 20 73 74 6f 72 65  er payload store
6280: 64 20 69 6e 20 74 68 65 20 64 61 74 61 62 61 73  d in the databas
6290: 65 2e 20 54 68 65 0a 20 20 20 20 73 63 68 65 6d  e. The.    schem
62a0: 61 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 6e  a information in
62b0: 20 74 68 65 20 53 51 4c 49 54 45 5f 4d 41 53 54   the SQLITE_MAST
62c0: 45 52 20 74 61 62 6c 65 20 69 73 20 6e 6f 74 20  ER table is not 
62d0: 63 6f 75 6e 74 65 64 20 77 68 65 6e 0a 20 20 20  counted when.   
62e0: 20 63 6f 6d 70 75 74 69 6e 67 20 74 68 69 73 20   computing this 
62f0: 6e 75 6d 62 65 72 2e 20 20 54 68 65 20 70 65 72  number.  The per
6300: 63 65 6e 74 61 67 65 20 61 74 20 74 68 65 20 72  centage at the r
6310: 69 67 68 74 20 73 68 6f 77 73 20 74 68 65 20 70  ight shows the p
6320: 61 79 6c 6f 61 64 0a 20 20 20 20 64 69 76 69 64  ayload.    divid
6330: 65 64 20 62 79 20 74 68 65 20 74 6f 74 61 6c 20  ed by the total 
6340: 66 69 6c 65 20 73 69 7a 65 2e 0a 0a 50 65 72 63  file size...Perc
6350: 65 6e 74 61 67 65 20 6f 66 20 74 6f 74 61 6c 20  entage of total 
6360: 64 61 74 61 62 61 73 65 0a 0a 20 20 20 20 54 68  database..    Th
6370: 65 20 61 6d 6f 75 6e 74 20 6f 66 20 74 68 65 20  e amount of the 
6380: 63 6f 6d 70 6c 65 74 65 20 64 61 74 61 62 61 73  complete databas
6390: 65 20 66 69 6c 65 20 74 68 61 74 20 69 73 20 64  e file that is d
63a0: 65 76 6f 74 65 64 20 74 6f 20 73 74 6f 72 69 6e  evoted to storin
63b0: 67 0a 20 20 20 20 69 6e 66 6f 72 6d 61 74 69 6f  g.    informatio
63c0: 6e 20 64 65 73 63 72 69 62 65 64 20 62 79 20 74  n described by t
63d0: 68 69 73 20 63 61 74 65 67 6f 72 79 2e 0a 0a 4e  his category...N
63e0: 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73  umber of entries
63f0: 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61 6c 20  ..    The total 
6400: 6e 75 6d 62 65 72 20 6f 66 20 42 2d 54 72 65 65  number of B-Tree
6410: 20 6b 65 79 2f 76 61 6c 75 65 20 70 61 69 72 73   key/value pairs
6420: 20 73 74 6f 72 65 64 20 75 6e 64 65 72 20 74 68   stored under th
6430: 69 73 20 63 61 74 65 67 6f 72 79 2e 0a 0a 42 79  is category...By
6440: 74 65 73 20 6f 66 20 73 74 6f 72 61 67 65 20 63  tes of storage c
6450: 6f 6e 73 75 6d 65 64 0a 0a 20 20 20 20 54 68 65  onsumed..    The
6460: 20 74 6f 74 61 6c 20 61 6d 6f 75 6e 74 20 6f 66   total amount of
6470: 20 64 69 73 6b 20 73 70 61 63 65 20 72 65 71 75   disk space requ
6480: 69 72 65 64 20 74 6f 20 73 74 6f 72 65 20 61 6c  ired to store al
6490: 6c 20 42 2d 54 72 65 65 20 65 6e 74 72 69 65 73  l B-Tree entries
64a0: 0a 20 20 20 20 75 6e 64 65 72 20 74 68 69 73 20  .    under this 
64b0: 63 61 74 65 67 6f 72 79 2e 20 20 54 68 65 20 69  category.  The i
64c0: 73 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62  s the total numb
64d0: 65 72 20 6f 66 20 70 61 67 65 73 20 75 73 65 64  er of pages used
64e0: 20 74 69 6d 65 73 0a 20 20 20 20 74 68 65 20 70   times.    the p
64f0: 61 67 65 73 20 73 69 7a 65 2e 0a 0a 42 79 74 65  ages size...Byte
6500: 73 20 6f 66 20 70 61 79 6c 6f 61 64 0a 0a 20 20  s of payload..  
6510: 20 20 54 68 65 20 61 6d 6f 75 6e 74 20 6f 66 20    The amount of 
6520: 70 61 79 6c 6f 61 64 20 73 74 6f 72 65 64 20 75  payload stored u
6530: 6e 64 65 72 20 74 68 69 73 20 63 61 74 65 67 6f  nder this catego
6540: 72 79 2e 20 20 50 61 79 6c 6f 61 64 20 69 73 20  ry.  Payload is 
6550: 74 68 65 20 64 61 74 61 0a 20 20 20 20 70 61 72  the data.    par
6560: 74 20 6f 66 20 74 61 62 6c 65 20 65 6e 74 72 69  t of table entri
6570: 65 73 20 61 6e 64 20 74 68 65 20 6b 65 79 20 70  es and the key p
6580: 61 72 74 20 6f 66 20 69 6e 64 65 78 20 65 6e 74  art of index ent
6590: 72 69 65 73 2e 20 20 54 68 65 20 70 65 72 63 65  ries.  The perce
65a0: 6e 74 61 67 65 0a 20 20 20 20 61 74 20 74 68 65  ntage.    at the
65b0: 20 72 69 67 68 74 20 69 73 20 74 68 65 20 62 79   right is the by
65c0: 74 65 73 20 6f 66 20 70 61 79 6c 6f 61 64 20 64  tes of payload d
65d0: 69 76 69 64 65 64 20 62 79 20 74 68 65 20 62 79  ivided by the by
65e0: 74 65 73 20 6f 66 20 73 74 6f 72 61 67 65 20 0a  tes of storage .
65f0: 20 20 20 20 63 6f 6e 73 75 6d 65 64 2e 0a 0a 42      consumed...B
6600: 79 74 65 73 20 6f 66 20 6d 65 74 61 64 61 74 61  ytes of metadata
6610: 0a 0a 20 20 20 20 54 68 65 20 61 6d 6f 75 6e 74  ..    The amount
6620: 20 6f 66 20 66 6f 72 6d 61 74 74 69 6e 67 20 61   of formatting a
6630: 6e 64 20 73 74 72 75 63 74 75 72 61 6c 20 69 6e  nd structural in
6640: 66 6f 72 6d 61 74 69 6f 6e 20 73 74 6f 72 65 64  formation stored
6650: 20 6f 6e 20 66 6f 72 20 74 68 65 0a 20 20 20 20   on for the.    
6660: 74 61 62 6c 65 20 6f 72 20 69 6e 64 65 78 2e 20  table or index. 
6670: 20 4d 65 74 61 64 61 74 61 20 69 6e 63 6c 75 64   Metadata includ
6680: 65 73 20 74 68 65 20 62 74 72 65 65 20 70 61 67  es the btree pag
6690: 65 20 68 65 61 64 65 72 2c 20 74 68 65 20 63 65  e header, the ce
66a0: 6c 6c 20 70 6f 69 6e 74 65 72 0a 20 20 20 20 61  ll pointer.    a
66b0: 72 72 61 79 2c 20 74 68 65 20 73 69 7a 65 20 66  rray, the size f
66c0: 69 65 6c 64 20 66 6f 72 20 65 61 63 68 20 63 65  ield for each ce
66d0: 6c 6c 2c 20 74 68 65 20 6c 65 66 74 20 63 68 69  ll, the left chi
66e0: 6c 64 20 70 6f 69 6e 74 65 72 20 6f 72 20 6e 6f  ld pointer or no
66f0: 6e 2d 6c 65 61 66 0a 20 20 20 20 63 65 6c 6c 73  n-leaf.    cells
6700: 2c 20 74 68 65 20 6f 76 65 72 66 6c 6f 77 20 70  , the overflow p
6710: 6f 69 6e 74 65 72 73 20 66 6f 72 20 6f 76 65 72  ointers for over
6720: 66 6c 6f 77 20 63 65 6c 6c 73 2c 20 61 6e 64 20  flow cells, and 
6730: 74 68 65 20 72 6f 77 69 64 20 76 61 6c 75 65 20  the rowid value 
6740: 66 6f 72 0a 20 20 20 20 72 6f 77 69 64 20 74 61  for.    rowid ta
6750: 62 6c 65 20 63 65 6c 6c 73 2e 20 20 49 6e 20 6f  ble cells.  In o
6760: 74 68 65 72 20 77 6f 72 64 73 2c 20 6d 65 74 61  ther words, meta
6770: 64 61 74 61 20 69 73 20 65 76 65 72 79 74 68 69  data is everythi
6780: 6e 67 20 74 68 61 74 20 69 73 20 6e 6f 74 0a 20  ng that is not. 
6790: 20 20 20 75 6e 75 73 65 64 20 73 70 61 63 65 20     unused space 
67a0: 61 6e 64 20 74 68 61 74 20 69 73 20 6e 6f 74 20  and that is not 
67b0: 63 6f 6e 74 65 6e 74 2e 0a 0a 41 76 65 72 61 67  content...Averag
67c0: 65 20 70 61 79 6c 6f 61 64 20 70 65 72 20 65 6e  e payload per en
67d0: 74 72 79 0a 0a 20 20 20 20 54 68 65 20 61 76 65  try..    The ave
67e0: 72 61 67 65 20 61 6d 6f 75 6e 74 20 6f 66 20 70  rage amount of p
67f0: 61 79 6c 6f 61 64 20 6f 6e 20 65 61 63 68 20 65  ayload on each e
6800: 6e 74 72 79 2e 20 20 54 68 69 73 20 69 73 20 6a  ntry.  This is j
6810: 75 73 74 20 74 68 65 20 62 79 74 65 73 20 6f 66  ust the bytes of
6820: 0a 20 20 20 20 70 61 79 6c 6f 61 64 20 64 69 76  .    payload div
6830: 69 64 65 64 20 62 79 20 74 68 65 20 6e 75 6d 62  ided by the numb
6840: 65 72 20 6f 66 20 65 6e 74 72 69 65 73 2e 0a 0a  er of entries...
6850: 41 76 65 72 61 67 65 20 75 6e 75 73 65 64 20 62  Average unused b
6860: 79 74 65 73 20 70 65 72 20 65 6e 74 72 79 0a 0a  ytes per entry..
6870: 20 20 20 20 54 68 65 20 61 76 65 72 61 67 65 20      The average 
6880: 61 6d 6f 75 6e 74 20 6f 66 20 66 72 65 65 20 73  amount of free s
6890: 70 61 63 65 20 72 65 6d 61 69 6e 69 6e 67 20 6f  pace remaining o
68a0: 6e 20 61 6c 6c 20 70 61 67 65 73 20 75 6e 64 65  n all pages unde
68b0: 72 20 74 68 69 73 0a 20 20 20 20 63 61 74 65 67  r this.    categ
68c0: 6f 72 79 20 6f 6e 20 61 20 70 65 72 2d 65 6e 74  ory on a per-ent
68d0: 72 79 20 62 61 73 69 73 2e 20 20 54 68 69 73 20  ry basis.  This 
68e0: 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  is the number of
68f0: 20 75 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e   unused bytes on
6900: 0a 20 20 20 20 61 6c 6c 20 70 61 67 65 73 20 64  .    all pages d
6910: 69 76 69 64 65 64 20 62 79 20 74 68 65 20 6e 75  ivided by the nu
6920: 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 2e  mber of entries.
6930: 0a 0a 4e 6f 6e 2d 73 65 71 75 65 6e 74 69 61 6c  ..Non-sequential
6940: 20 70 61 67 65 73 0a 0a 20 20 20 20 54 68 65 20   pages..    The 
6950: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
6960: 69 6e 20 74 68 65 20 74 61 62 6c 65 20 6f 72 20  in the table or 
6970: 69 6e 64 65 78 20 74 68 61 74 20 61 72 65 20 6f  index that are o
6980: 75 74 20 6f 66 20 73 65 71 75 65 6e 63 65 2e 0a  ut of sequence..
6990: 20 20 20 20 4d 61 6e 79 20 66 69 6c 65 73 79 73      Many filesys
69a0: 74 65 6d 73 20 61 72 65 20 6f 70 74 69 6d 69 7a  tems are optimiz
69b0: 65 64 20 66 6f 72 20 73 65 71 75 65 6e 74 69 61  ed for sequentia
69c0: 6c 20 66 69 6c 65 20 61 63 63 65 73 73 20 73 6f  l file access so
69d0: 20 61 20 73 6d 61 6c 6c 0a 20 20 20 20 6e 75 6d   a small.    num
69e0: 62 65 72 20 6f 66 20 6e 6f 6e 2d 73 65 71 75 65  ber of non-seque
69f0: 6e 74 69 61 6c 20 70 61 67 65 73 20 6d 69 67 68  ntial pages migh
6a00: 74 20 72 65 73 75 6c 74 20 69 6e 20 66 61 73 74  t result in fast
6a10: 65 72 20 71 75 65 72 69 65 73 2c 0a 20 20 20 20  er queries,.    
6a20: 65 73 70 65 63 69 61 6c 6c 79 20 66 6f 72 20 6c  especially for l
6a30: 61 72 67 65 72 20 64 61 74 61 62 61 73 65 20 66  arger database f
6a40: 69 6c 65 73 20 74 68 61 74 20 64 6f 20 6e 6f 74  iles that do not
6a50: 20 66 69 74 20 69 6e 20 74 68 65 20 64 69 73 6b   fit in the disk
6a60: 20 63 61 63 68 65 2e 0a 20 20 20 20 4e 6f 74 65   cache..    Note
6a70: 20 74 68 61 74 20 61 66 74 65 72 20 72 75 6e 6e   that after runn
6a80: 69 6e 67 20 56 41 43 55 55 4d 2c 20 74 68 65 20  ing VACUUM, the 
6a90: 72 6f 6f 74 20 70 61 67 65 20 6f 66 20 65 61 63  root page of eac
6aa0: 68 20 74 61 62 6c 65 20 6f 72 20 69 6e 64 65 78  h table or index
6ab0: 20 69 73 0a 20 20 20 20 61 74 20 74 68 65 20 62   is.    at the b
6ac0: 65 67 69 6e 6e 69 6e 67 20 6f 66 20 74 68 65 20  eginning of the 
6ad0: 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 61 6e  database file an
6ae0: 64 20 61 6c 6c 20 6f 74 68 65 72 20 70 61 67 65  d all other page
6af0: 73 20 61 72 65 20 69 6e 20 61 0a 20 20 20 20 73  s are in a.    s
6b00: 65 70 61 72 61 74 65 20 70 61 72 74 20 6f 66 20  eparate part of 
6b10: 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
6b20: 65 2c 20 72 65 73 75 6c 74 69 6e 67 20 69 6e 20  e, resulting in 
6b30: 61 20 73 69 6e 67 6c 65 20 6e 6f 6e 2d 0a 20 20  a single non-.  
6b40: 20 20 73 65 71 75 65 6e 74 69 61 6c 20 70 61 67    sequential pag
6b50: 65 2e 0a 0a 4d 61 78 69 6d 75 6d 20 70 61 79 6c  e...Maximum payl
6b60: 6f 61 64 20 70 65 72 20 65 6e 74 72 79 0a 0a 20  oad per entry.. 
6b70: 20 20 20 54 68 65 20 6c 61 72 67 65 73 74 20 70     The largest p
6b80: 61 79 6c 6f 61 64 20 73 69 7a 65 20 6f 66 20 61  ayload size of a
6b90: 6e 79 20 65 6e 74 72 79 2e 0a 0a 45 6e 74 72 69  ny entry...Entri
6ba0: 65 73 20 74 68 61 74 20 75 73 65 20 6f 76 65 72  es that use over
6bb0: 66 6c 6f 77 0a 0a 20 20 20 20 54 68 65 20 6e 75  flow..    The nu
6bc0: 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20  mber of entries 
6bd0: 74 68 61 74 20 75 73 65 72 20 6f 6e 65 20 6f 72  that user one or
6be0: 20 6d 6f 72 65 20 6f 76 65 72 66 6c 6f 77 20 70   more overflow p
6bf0: 61 67 65 73 2e 0a 0a 54 6f 74 61 6c 20 70 61 67  ages...Total pag
6c00: 65 73 20 75 73 65 64 0a 0a 20 20 20 20 54 68 69  es used..    Thi
6c10: 73 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20  s is the number 
6c20: 6f 66 20 70 61 67 65 73 20 75 73 65 64 20 74 6f  of pages used to
6c30: 20 68 6f 6c 64 20 61 6c 6c 20 69 6e 66 6f 72 6d   hold all inform
6c40: 61 74 69 6f 6e 20 69 6e 20 74 68 65 20 63 75 72  ation in the cur
6c50: 72 65 6e 74 0a 20 20 20 20 63 61 74 65 67 6f 72  rent.    categor
6c60: 79 2e 20 20 54 68 69 73 20 69 73 20 74 68 65 20  y.  This is the 
6c70: 73 75 6d 20 6f 66 20 69 6e 64 65 78 2c 20 70 72  sum of index, pr
6c80: 69 6d 61 72 79 2c 20 61 6e 64 20 6f 76 65 72 66  imary, and overf
6c90: 6c 6f 77 20 70 61 67 65 73 2e 0a 0a 49 6e 64 65  low pages...Inde
6ca0: 78 20 70 61 67 65 73 20 75 73 65 64 0a 0a 20 20  x pages used..  
6cb0: 20 20 54 68 69 73 20 69 73 20 74 68 65 20 6e 75    This is the nu
6cc0: 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e  mber of pages in
6cd0: 20 61 20 74 61 62 6c 65 20 42 2d 74 72 65 65 20   a table B-tree 
6ce0: 74 68 61 74 20 68 6f 6c 64 20 6f 6e 6c 79 20 6b  that hold only k
6cf0: 65 79 20 28 72 6f 77 69 64 29 0a 20 20 20 20 69  ey (rowid).    i
6d00: 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 6e 64 20 6e  nformation and n
6d10: 6f 20 64 61 74 61 2e 0a 0a 50 72 69 6d 61 72 79  o data...Primary
6d20: 20 70 61 67 65 73 20 75 73 65 64 0a 0a 20 20 20   pages used..   
6d30: 20 54 68 69 73 20 69 73 20 74 68 65 20 6e 75 6d   This is the num
6d40: 62 65 72 20 6f 66 20 42 2d 74 72 65 65 20 70 61  ber of B-tree pa
6d50: 67 65 73 20 74 68 61 74 20 68 6f 6c 64 20 62 6f  ges that hold bo
6d60: 74 68 20 6b 65 79 20 61 6e 64 20 64 61 74 61 2e  th key and data.
6d70: 0a 0a 4f 76 65 72 66 6c 6f 77 20 70 61 67 65 73  ..Overflow pages
6d80: 20 75 73 65 64 0a 0a 20 20 20 20 54 68 65 20 74   used..    The t
6d90: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 6f  otal number of o
6da0: 76 65 72 66 6c 6f 77 20 70 61 67 65 73 20 75 73  verflow pages us
6db0: 65 64 20 66 6f 72 20 74 68 69 73 20 63 61 74 65  ed for this cate
6dc0: 67 6f 72 79 2e 0a 0a 55 6e 75 73 65 64 20 62 79  gory...Unused by
6dd0: 74 65 73 20 6f 6e 20 69 6e 64 65 78 20 70 61 67  tes on index pag
6de0: 65 73 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61  es..    The tota
6df0: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  l number of byte
6e00: 73 20 6f 66 20 75 6e 75 73 65 64 20 73 70 61 63  s of unused spac
6e10: 65 20 6f 6e 20 61 6c 6c 20 69 6e 64 65 78 20 70  e on all index p
6e20: 61 67 65 73 2e 20 20 54 68 65 0a 20 20 20 20 70  ages.  The.    p
6e30: 65 72 63 65 6e 74 61 67 65 20 61 74 20 74 68 65  ercentage at the
6e40: 20 72 69 67 68 74 20 69 73 20 74 68 65 20 6e 75   right is the nu
6e50: 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62  mber of unused b
6e60: 79 74 65 73 20 64 69 76 69 64 65 64 20 62 79 20  ytes divided by 
6e70: 74 68 65 0a 20 20 20 20 74 6f 74 61 6c 20 6e 75  the.    total nu
6e80: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 6e  mber of bytes on
6e90: 20 69 6e 64 65 78 20 70 61 67 65 73 2e 0a 0a 55   index pages...U
6ea0: 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e 20 70  nused bytes on p
6eb0: 72 69 6d 61 72 79 20 70 61 67 65 73 0a 0a 20 20  rimary pages..  
6ec0: 20 20 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62    The total numb
6ed0: 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 75  er of bytes of u
6ee0: 6e 75 73 65 64 20 73 70 61 63 65 20 6f 6e 20 61  nused space on a
6ef0: 6c 6c 20 70 72 69 6d 61 72 79 20 70 61 67 65 73  ll primary pages
6f00: 2e 20 20 54 68 65 0a 20 20 20 20 70 65 72 63 65  .  The.    perce
6f10: 6e 74 61 67 65 20 61 74 20 74 68 65 20 72 69 67  ntage at the rig
6f20: 68 74 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72  ht is the number
6f30: 20 6f 66 20 75 6e 75 73 65 64 20 62 79 74 65 73   of unused bytes
6f40: 20 64 69 76 69 64 65 64 20 62 79 20 74 68 65 0a   divided by the.
6f50: 20 20 20 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72      total number
6f60: 20 6f 66 20 62 79 74 65 73 20 6f 6e 20 70 72 69   of bytes on pri
6f70: 6d 61 72 79 20 70 61 67 65 73 2e 0a 0a 55 6e 75  mary pages...Unu
6f80: 73 65 64 20 62 79 74 65 73 20 6f 6e 20 6f 76 65  sed bytes on ove
6f90: 72 66 6c 6f 77 20 70 61 67 65 73 0a 0a 20 20 20  rflow pages..   
6fa0: 20 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65   The total numbe
6fb0: 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 75 6e  r of bytes of un
6fc0: 75 73 65 64 20 73 70 61 63 65 20 6f 6e 20 61 6c  used space on al
6fd0: 6c 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73  l overflow pages
6fe0: 2e 20 20 54 68 65 0a 20 20 20 20 70 65 72 63 65  .  The.    perce
6ff0: 6e 74 61 67 65 20 61 74 20 74 68 65 20 72 69 67  ntage at the rig
7000: 68 74 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72  ht is the number
7010: 20 6f 66 20 75 6e 75 73 65 64 20 62 79 74 65 73   of unused bytes
7020: 20 64 69 76 69 64 65 64 20 62 79 20 74 68 65 0a   divided by the.
7030: 20 20 20 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72      total number
7040: 20 6f 66 20 62 79 74 65 73 20 6f 6e 20 6f 76 65   of bytes on ove
7050: 72 66 6c 6f 77 20 70 61 67 65 73 2e 0a 0a 55 6e  rflow pages...Un
7060: 75 73 65 64 20 62 79 74 65 73 20 6f 6e 20 61 6c  used bytes on al
7070: 6c 20 70 61 67 65 73 0a 0a 20 20 20 20 54 68 65  l pages..    The
7080: 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66   total number of
7090: 20 62 79 74 65 73 20 6f 66 20 75 6e 75 73 65 64   bytes of unused
70a0: 20 73 70 61 63 65 20 6f 6e 20 61 6c 6c 20 70 72   space on all pr
70b0: 69 6d 61 72 79 20 61 6e 64 20 6f 76 65 72 66 6c  imary and overfl
70c0: 6f 77 20 0a 20 20 20 20 70 61 67 65 73 2e 20 20  ow .    pages.  
70d0: 54 68 65 20 70 65 72 63 65 6e 74 61 67 65 20 61  The percentage a
70e0: 74 20 74 68 65 20 72 69 67 68 74 20 69 73 20 74  t the right is t
70f0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e 75  he number of unu
7100: 73 65 64 20 62 79 74 65 73 20 0a 20 20 20 20 64  sed bytes .    d
7110: 69 76 69 64 65 64 20 62 79 20 74 68 65 20 74 6f  ivided by the to
7120: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79  tal number of by
7130: 74 65 73 2e 0a 7d 0a 0a 23 20 4f 75 74 70 75 74  tes..}..# Output
7140: 20 61 20 64 75 6d 70 20 6f 66 20 74 68 65 20 69   a dump of the i
7150: 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62 61 73  n-memory databas
7160: 65 2e 20 54 68 69 73 20 63 61 6e 20 62 65 20 75  e. This can be u
7170: 73 65 64 20 66 6f 72 20 6d 6f 72 65 0a 23 20 63  sed for more.# c
7180: 6f 6d 70 6c 65 78 20 6f 66 66 6c 69 6e 65 20 61  omplex offline a
7190: 6e 61 6c 79 73 69 73 2e 0a 23 0a 74 69 74 6c 65  nalysis..#.title
71a0: 6c 69 6e 65 20 7b 7d 0a 70 75 74 73 20 22 54 68  line {}.puts "Th
71b0: 65 20 65 6e 74 69 72 65 20 74 65 78 74 20 6f 66  e entire text of
71c0: 20 74 68 69 73 20 72 65 70 6f 72 74 20 63 61 6e   this report can
71d0: 20 62 65 20 73 6f 75 72 63 65 64 20 69 6e 74 6f   be sourced into
71e0: 20 61 6e 79 20 53 51 4c 20 64 61 74 61 62 61 73   any SQL databas
71f0: 65 22 0a 70 75 74 73 20 22 65 6e 67 69 6e 65 20  e".puts "engine 
7200: 66 6f 72 20 66 75 72 74 68 65 72 20 61 6e 61 6c  for further anal
7210: 79 73 69 73 2e 20 20 41 6c 6c 20 6f 66 20 74 68  ysis.  All of th
7220: 65 20 74 65 78 74 20 61 62 6f 76 65 20 69 73 20  e text above is 
7230: 61 6e 20 53 51 4c 20 63 6f 6d 6d 65 6e 74 2e 22  an SQL comment."
7240: 0a 70 75 74 73 20 22 54 68 65 20 64 61 74 61 20  .puts "The data 
7250: 75 73 65 64 20 74 6f 20 67 65 6e 65 72 61 74 65  used to generate
7260: 20 74 68 69 73 20 72 65 70 6f 72 74 20 66 6f 6c   this report fol
7270: 6c 6f 77 73 3a 22 0a 70 75 74 73 20 22 2a 2f 22  lows:".puts "*/"
7280: 0a 70 75 74 73 20 22 42 45 47 49 4e 3b 22 0a 70  .puts "BEGIN;".p
7290: 75 74 73 20 24 74 61 62 6c 65 64 65 66 0a 75 6e  uts $tabledef.un
72a0: 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20  set -nocomplain 
72b0: 78 0a 6d 65 6d 20 65 76 61 6c 20 7b 53 45 4c 45  x.mem eval {SELE
72c0: 43 54 20 2a 20 46 52 4f 4d 20 73 70 61 63 65 5f  CT * FROM space_
72d0: 75 73 65 64 7d 20 78 20 7b 0a 20 20 70 75 74 73  used} x {.  puts
72e0: 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 22 49 4e 53   -nonewline "INS
72f0: 45 52 54 20 49 4e 54 4f 20 73 70 61 63 65 5f 75  ERT INTO space_u
7300: 73 65 64 20 56 41 4c 55 45 53 22 0a 20 20 73 65  sed VALUES".  se
7310: 74 20 73 65 70 20 28 0a 20 20 66 6f 72 65 61 63  t sep (.  foreac
7320: 68 20 63 6f 6c 20 24 78 28 2a 29 20 7b 0a 20 20  h col $x(*) {.  
7330: 20 20 73 65 74 20 76 20 24 78 28 24 63 6f 6c 29    set v $x($col)
7340: 0a 20 20 20 20 69 66 20 7b 24 76 3d 3d 22 22 20  .    if {$v=="" 
7350: 7c 7c 20 21 5b 73 74 72 69 6e 67 20 69 73 20 64  || ![string is d
7360: 6f 75 62 6c 65 20 24 76 5d 7d 20 7b 73 65 74 20  ouble $v]} {set 
7370: 76 20 27 5b 71 75 6f 74 65 20 24 76 5d 27 7d 0a  v '[quote $v]'}.
7380: 20 20 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c      puts -nonewl
7390: 69 6e 65 20 24 73 65 70 24 76 0a 20 20 20 20 73  ine $sep$v.    s
73a0: 65 74 20 73 65 70 20 2c 0a 20 20 7d 0a 20 20 70  et sep ,.  }.  p
73b0: 75 74 73 20 22 29 3b 22 0a 7d 0a 70 75 74 73 20  uts ");".}.puts 
73c0: 22 43 4f 4d 4d 49 54 3b 22 0a 0a 7d 20 65 72 72  "COMMIT;"..} err
73d0: 5d 7d 20 7b 0a 20 20 70 75 74 73 20 22 45 52 52  ]} {.  puts "ERR
73e0: 4f 52 3a 20 24 65 72 72 22 0a 20 20 70 75 74 73  OR: $err".  puts
73f0: 20 24 65 72 72 6f 72 49 6e 66 6f 0a 20 20 65 78   $errorInfo.  ex
7400: 69 74 20 31 0a 7d 0a                             it 1.}.