/ Hex Artifact Content
Login

Artifact 63a415385a66fdbf736bfd204a31c6d851ed8da6:


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 47 65 74 20  turn 0.}..# Get 
0290: 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20  the name of the 
02a0: 64 61 74 61 62 61 73 65 20 74 6f 20 61 6e 61 6c  database to anal
02b0: 79 7a 65 0a 23 0a 70 72 6f 63 20 75 73 61 67 65  yze.#.proc usage
02c0: 20 7b 7d 20 7b 0a 20 20 73 65 74 20 61 72 67 76   {} {.  set argv
02d0: 30 20 5b 66 69 6c 65 20 72 6f 6f 74 6e 61 6d 65  0 [file rootname
02e0: 20 5b 66 69 6c 65 20 74 61 69 6c 20 5b 69 6e 66   [file tail [inf
02f0: 6f 20 6e 61 6d 65 6f 66 65 78 65 63 75 74 61 62  o nameofexecutab
0300: 6c 65 5d 5d 5d 0a 20 20 70 75 74 73 20 73 74 64  le]]].  puts std
0310: 65 72 72 20 22 55 73 61 67 65 3a 20 24 61 72 67  err "Usage: $arg
0320: 76 30 20 5c 5b 2d 2d 70 61 67 65 69 6e 66 6f 5d  v0 \[--pageinfo]
0330: 20 5c 5b 2d 2d 73 74 61 74 73 5d 20 64 61 74 61   \[--stats] data
0340: 62 61 73 65 2d 6e 61 6d 65 22 0a 20 20 65 78 69  base-name".  exi
0350: 74 20 31 0a 7d 0a 73 65 74 20 66 69 6c 65 5f 74  t 1.}.set file_t
0360: 6f 5f 61 6e 61 6c 79 7a 65 20 7b 7d 0a 73 65 74  o_analyze {}.set
0370: 20 66 6c 61 67 73 28 2d 70 61 67 65 69 6e 66 6f   flags(-pageinfo
0380: 29 20 30 0a 73 65 74 20 66 6c 61 67 73 28 2d 73  ) 0.set flags(-s
0390: 74 61 74 73 29 20 30 0a 61 70 70 65 6e 64 20 61  tats) 0.append a
03a0: 72 67 76 20 7b 7d 0a 66 6f 72 65 61 63 68 20 61  rgv {}.foreach a
03b0: 72 67 20 24 61 72 67 76 20 7b 0a 20 20 69 66 20  rg $argv {.  if 
03c0: 7b 5b 72 65 67 65 78 70 20 7b 5e 2d 2b 70 61 67  {[regexp {^-+pag
03d0: 65 69 6e 66 6f 24 7d 20 24 61 72 67 5d 7d 20 7b  einfo$} $arg]} {
03e0: 0a 20 20 20 20 73 65 74 20 66 6c 61 67 73 28 2d  .    set flags(-
03f0: 70 61 67 65 69 6e 66 6f 29 20 31 0a 20 20 7d 20  pageinfo) 1.  } 
0400: 65 6c 73 65 69 66 20 7b 5b 72 65 67 65 78 70 20  elseif {[regexp 
0410: 7b 5e 2d 2b 73 74 61 74 73 24 7d 20 24 61 72 67  {^-+stats$} $arg
0420: 5d 7d 20 7b 0a 20 20 20 20 73 65 74 20 66 6c 61  ]} {.    set fla
0430: 67 73 28 2d 73 74 61 74 73 29 20 31 0a 20 20 7d  gs(-stats) 1.  }
0440: 20 65 6c 73 65 69 66 20 7b 5b 72 65 67 65 78 70   elseif {[regexp
0450: 20 7b 5e 2d 7d 20 24 61 72 67 5d 7d 20 7b 0a 20   {^-} $arg]} {. 
0460: 20 20 20 70 75 74 73 20 73 74 64 65 72 72 20 22     puts stderr "
0470: 55 6e 6b 6e 6f 77 6e 20 6f 70 74 69 6f 6e 3a 20  Unknown option: 
0480: 24 61 72 67 22 0a 20 20 20 20 75 73 61 67 65 0a  $arg".    usage.
0490: 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 66 69 6c    } elseif {$fil
04a0: 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 21 3d 22 22  e_to_analyze!=""
04b0: 7d 20 7b 0a 20 20 20 20 75 73 61 67 65 0a 20 20  } {.    usage.  
04c0: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74  } else {.    set
04d0: 20 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65   file_to_analyze
04e0: 20 24 61 72 67 0a 20 20 7d 0a 7d 0a 69 66 20 7b   $arg.  }.}.if {
04f0: 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65  $file_to_analyze
0500: 3d 3d 22 22 7d 20 75 73 61 67 65 0a 73 65 74 20  ==""} usage.set 
0510: 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d 65 20 24 66  root_filename $f
0520: 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 0a 72  ile_to_analyze.r
0530: 65 67 65 78 70 20 7b 5e 66 69 6c 65 3a 28 2f 2f  egexp {^file:(//
0540: 29 3f 28 5b 5e 3f 5d 2a 29 7d 20 24 66 69 6c 65  )?([^?]*)} $file
0550: 5f 74 6f 5f 61 6e 61 6c 79 7a 65 20 61 6c 6c 20  _to_analyze all 
0560: 78 31 20 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d 65  x1 root_filename
0570: 0a 69 66 20 7b 21 5b 66 69 6c 65 20 65 78 69 73  .if {![file exis
0580: 74 73 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d  ts $root_filenam
0590: 65 5d 7d 20 7b 0a 20 20 70 75 74 73 20 73 74 64  e]} {.  puts std
05a0: 65 72 72 20 22 4e 6f 20 73 75 63 68 20 66 69 6c  err "No such fil
05b0: 65 3a 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d  e: $root_filenam
05c0: 65 22 0a 20 20 65 78 69 74 20 31 0a 7d 0a 69 66  e".  exit 1.}.if
05d0: 20 7b 21 5b 66 69 6c 65 20 72 65 61 64 61 62 6c   {![file readabl
05e0: 65 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d 65  e $root_filename
05f0: 5d 7d 20 7b 0a 20 20 70 75 74 73 20 73 74 64 65  ]} {.  puts stde
0600: 72 72 20 22 46 69 6c 65 20 69 73 20 6e 6f 74 20  rr "File is not 
0610: 72 65 61 64 61 62 6c 65 3a 20 24 72 6f 6f 74 5f  readable: $root_
0620: 66 69 6c 65 6e 61 6d 65 22 0a 20 20 65 78 69 74  filename".  exit
0630: 20 31 0a 7d 0a 73 65 74 20 74 72 75 65 5f 66 69   1.}.set true_fi
0640: 6c 65 5f 73 69 7a 65 20 5b 66 69 6c 65 20 73 69  le_size [file si
0650: 7a 65 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d  ze $root_filenam
0660: 65 5d 0a 69 66 20 7b 24 74 72 75 65 5f 66 69 6c  e].if {$true_fil
0670: 65 5f 73 69 7a 65 3c 35 31 32 7d 20 7b 0a 20 20  e_size<512} {.  
0680: 70 75 74 73 20 73 74 64 65 72 72 20 22 45 6d 70  puts stderr "Emp
0690: 74 79 20 6f 72 20 6d 61 6c 66 6f 72 6d 65 64 20  ty or malformed 
06a0: 64 61 74 61 62 61 73 65 3a 20 24 72 6f 6f 74 5f  database: $root_
06b0: 66 69 6c 65 6e 61 6d 65 22 0a 20 20 65 78 69 74  filename".  exit
06c0: 20 31 0a 7d 0a 0a 23 20 43 6f 6d 70 75 74 65 20   1.}..# Compute 
06d0: 74 68 65 20 74 6f 74 61 6c 20 66 69 6c 65 20 73  the total file s
06e0: 69 7a 65 20 61 73 73 75 6d 69 6e 67 20 74 65 73  ize assuming tes
06f0: 74 5f 6d 75 6c 74 69 70 6c 65 78 6f 72 20 69 73  t_multiplexor is
0700: 20 62 65 69 6e 67 20 75 73 65 64 2e 0a 23 20 41   being used..# A
0710: 73 73 75 6d 65 20 74 68 61 74 20 53 51 4c 49 54  ssume that SQLIT
0720: 45 5f 45 4e 41 42 4c 45 5f 38 5f 33 5f 4e 41 4d  E_ENABLE_8_3_NAM
0730: 45 53 20 6d 69 67 68 74 20 62 65 20 65 6e 61 62  ES might be enab
0740: 6c 65 64 0a 23 0a 73 65 74 20 65 78 74 65 6e 73  led.#.set extens
0750: 69 6f 6e 20 5b 66 69 6c 65 20 65 78 74 65 6e 73  ion [file extens
0760: 69 6f 6e 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61  ion $root_filena
0770: 6d 65 5d 0a 73 65 74 20 70 61 74 74 65 72 6e 20  me].set pattern 
0780: 24 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d 65 0a 61  $root_filename.a
0790: 70 70 65 6e 64 20 70 61 74 74 65 72 6e 20 7b 5b  ppend pattern {[
07a0: 30 2d 33 5d 5b 30 2d 39 5d 5b 30 2d 39 5d 7d 0a  0-3][0-9][0-9]}.
07b0: 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20  foreach f [glob 
07c0: 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 24 70 61 74  -nocomplain $pat
07d0: 74 65 72 6e 5d 20 7b 0a 20 20 69 6e 63 72 20 74  tern] {.  incr t
07e0: 72 75 65 5f 66 69 6c 65 5f 73 69 7a 65 20 5b 66  rue_file_size [f
07f0: 69 6c 65 20 73 69 7a 65 20 24 66 5d 0a 20 20 73  ile size $f].  s
0800: 65 74 20 65 78 74 65 6e 73 69 6f 6e 20 7b 7d 0a  et extension {}.
0810: 7d 0a 69 66 20 7b 5b 73 74 72 69 6e 67 20 6c 65  }.if {[string le
0820: 6e 67 74 68 20 24 65 78 74 65 6e 73 69 6f 6e 5d  ngth $extension]
0830: 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20 6c  >=2 && [string l
0840: 65 6e 67 74 68 20 24 65 78 74 65 6e 73 69 6f 6e  ength $extension
0850: 5d 3c 3d 34 7d 20 7b 0a 20 20 73 65 74 20 70 61  ]<=4} {.  set pa
0860: 74 74 65 72 6e 20 5b 66 69 6c 65 20 72 6f 6f 74  ttern [file root
0870: 6e 61 6d 65 20 24 72 6f 6f 74 5f 66 69 6c 65 6e  name $root_filen
0880: 61 6d 65 5d 0a 20 20 61 70 70 65 6e 64 20 70 61  ame].  append pa
0890: 74 74 65 72 6e 20 7b 2e 5b 30 2d 33 5d 5b 30 2d  ttern {.[0-3][0-
08a0: 39 5d 5b 30 2d 39 5d 7d 0a 20 20 66 6f 72 65 61  9][0-9]}.  forea
08b0: 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f  ch f [glob -noco
08c0: 6d 70 6c 61 69 6e 20 24 70 61 74 74 65 72 6e 5d  mplain $pattern]
08d0: 20 7b 0a 20 20 20 20 69 6e 63 72 20 74 72 75 65   {.    incr true
08e0: 5f 66 69 6c 65 5f 73 69 7a 65 20 5b 66 69 6c 65  _file_size [file
08f0: 20 73 69 7a 65 20 24 66 5d 0a 20 20 7d 0a 7d 0a   size $f].  }.}.
0900: 0a 23 20 4f 70 65 6e 20 74 68 65 20 64 61 74 61  .# Open the data
0910: 62 61 73 65 0a 23 0a 69 66 20 7b 5b 63 61 74 63  base.#.if {[catc
0920: 68 20 7b 73 71 6c 69 74 65 33 20 64 62 20 24 66  h {sqlite3 db $f
0930: 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 20 2d  ile_to_analyze -
0940: 75 72 69 20 31 7d 20 6d 73 67 5d 7d 20 7b 0a 20  uri 1} msg]} {. 
0950: 20 70 75 74 73 20 73 74 64 65 72 72 20 22 65 72   puts stderr "er
0960: 72 6f 72 20 74 72 79 69 6e 67 20 74 6f 20 6f 70  ror trying to op
0970: 65 6e 20 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c  en $file_to_anal
0980: 79 7a 65 3a 20 24 6d 73 67 22 0a 20 20 65 78 69  yze: $msg".  exi
0990: 74 20 31 0a 7d 0a 0a 64 62 20 65 76 61 6c 20 7b  t 1.}..db eval {
09a0: 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 20  SELECT count(*) 
09b0: 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74  FROM sqlite_mast
09c0: 65 72 7d 0a 73 65 74 20 70 61 67 65 53 69 7a 65  er}.set pageSize
09d0: 20 5b 65 78 70 72 20 7b 77 69 64 65 28 5b 64 62   [expr {wide([db
09e0: 20 6f 6e 65 20 7b 50 52 41 47 4d 41 20 70 61 67   one {PRAGMA pag
09f0: 65 5f 73 69 7a 65 7d 5d 29 7d 5d 0a 0a 69 66 20  e_size}])}]..if 
0a00: 7b 24 66 6c 61 67 73 28 2d 70 61 67 65 69 6e 66  {$flags(-pageinf
0a10: 6f 29 7d 20 7b 0a 20 20 64 62 20 65 76 61 6c 20  o)} {.  db eval 
0a20: 7b 43 52 45 41 54 45 20 56 49 52 54 55 41 4c 20  {CREATE VIRTUAL 
0a30: 54 41 42 4c 45 20 74 65 6d 70 2e 73 74 61 74 20  TABLE temp.stat 
0a40: 55 53 49 4e 47 20 64 62 73 74 61 74 7d 0a 20 20  USING dbstat}.  
0a50: 64 62 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20  db eval {SELECT 
0a60: 6e 61 6d 65 2c 20 70 61 74 68 2c 20 70 61 67 65  name, path, page
0a70: 6e 6f 20 46 52 4f 4d 20 74 65 6d 70 2e 73 74 61  no FROM temp.sta
0a80: 74 20 4f 52 44 45 52 20 42 59 20 70 61 67 65 6e  t ORDER BY pagen
0a90: 6f 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 22 24  o} {.    puts "$
0aa0: 70 61 67 65 6e 6f 20 24 6e 61 6d 65 20 24 70 61  pageno $name $pa
0ab0: 74 68 22 0a 20 20 7d 0a 20 20 65 78 69 74 20 30  th".  }.  exit 0
0ac0: 0a 7d 0a 69 66 20 7b 24 66 6c 61 67 73 28 2d 73  .}.if {$flags(-s
0ad0: 74 61 74 73 29 7d 20 7b 0a 20 20 64 62 20 65 76  tats)} {.  db ev
0ae0: 61 6c 20 7b 43 52 45 41 54 45 20 56 49 52 54 55  al {CREATE VIRTU
0af0: 41 4c 20 54 41 42 4c 45 20 74 65 6d 70 2e 73 74  AL TABLE temp.st
0b00: 61 74 20 55 53 49 4e 47 20 64 62 73 74 61 74 7d  at USING dbstat}
0b10: 0a 20 20 70 75 74 73 20 22 42 45 47 49 4e 3b 22  .  puts "BEGIN;"
0b20: 0a 20 20 70 75 74 73 20 22 43 52 45 41 54 45 20  .  puts "CREATE 
0b30: 54 41 42 4c 45 20 73 74 61 74 73 28 22 0a 20 20  TABLE stats(".  
0b40: 70 75 74 73 20 22 20 20 6e 61 6d 65 20 20 20 20  puts "  name    
0b50: 20 20 20 53 54 52 49 4e 47 2c 20 20 20 20 20 20     STRING,      
0b60: 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20       /* Name of 
0b70: 74 61 62 6c 65 20 6f 72 20 69 6e 64 65 78 20 2a  table or index *
0b80: 2f 22 0a 20 20 70 75 74 73 20 22 20 20 70 61 74  /".  puts "  pat
0b90: 68 20 20 20 20 20 20 20 49 4e 54 45 47 45 52 2c  h       INTEGER,
0ba0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 74            /* Pat
0bb0: 68 20 74 6f 20 70 61 67 65 20 66 72 6f 6d 20 72  h to page from r
0bc0: 6f 6f 74 20 2a 2f 22 0a 20 20 70 75 74 73 20 22  oot */".  puts "
0bd0: 20 20 70 61 67 65 6e 6f 20 20 20 20 20 49 4e 54    pageno     INT
0be0: 45 47 45 52 2c 20 20 20 20 20 20 20 20 20 20 2f  EGER,          /
0bf0: 2a 20 50 61 67 65 20 6e 75 6d 62 65 72 20 2a 2f  * Page number */
0c00: 22 0a 20 20 70 75 74 73 20 22 20 20 70 61 67 65  ".  puts "  page
0c10: 74 79 70 65 20 20 20 53 54 52 49 4e 47 2c 20 20  type   STRING,  
0c20: 20 20 20 20 20 20 20 20 20 2f 2a 20 27 69 6e 74           /* 'int
0c30: 65 72 6e 61 6c 27 2c 20 27 6c 65 61 66 27 20 6f  ernal', 'leaf' o
0c40: 72 20 27 6f 76 65 72 66 6c 6f 77 27 20 2a 2f 22  r 'overflow' */"
0c50: 0a 20 20 70 75 74 73 20 22 20 20 6e 63 65 6c 6c  .  puts "  ncell
0c60: 20 20 20 20 20 20 49 4e 54 45 47 45 52 2c 20 20        INTEGER,  
0c70: 20 20 20 20 20 20 20 20 2f 2a 20 43 65 6c 6c 73          /* Cells
0c80: 20 6f 6e 20 70 61 67 65 20 28 30 20 66 6f 72 20   on page (0 for 
0c90: 6f 76 65 72 66 6c 6f 77 29 20 2a 2f 22 0a 20 20  overflow) */".  
0ca0: 70 75 74 73 20 22 20 20 70 61 79 6c 6f 61 64 20  puts "  payload 
0cb0: 20 20 20 49 4e 54 45 47 45 52 2c 20 20 20 20 20     INTEGER,     
0cc0: 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66       /* Bytes of
0cd0: 20 70 61 79 6c 6f 61 64 20 6f 6e 20 74 68 69 73   payload on this
0ce0: 20 70 61 67 65 20 2a 2f 22 0a 20 20 70 75 74 73   page */".  puts
0cf0: 20 22 20 20 75 6e 75 73 65 64 20 20 20 20 20 49   "  unused     I
0d00: 4e 54 45 47 45 52 2c 20 20 20 20 20 20 20 20 20  NTEGER,         
0d10: 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 75 6e 75   /* Bytes of unu
0d20: 73 65 64 20 73 70 61 63 65 20 6f 6e 20 74 68 69  sed space on thi
0d30: 73 20 70 61 67 65 20 2a 2f 22 0a 20 20 70 75 74  s page */".  put
0d40: 73 20 22 20 20 6d 78 5f 70 61 79 6c 6f 61 64 20  s "  mx_payload 
0d50: 49 4e 54 45 47 45 52 2c 20 20 20 20 20 20 20 20  INTEGER,        
0d60: 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 70 61 79    /* Largest pay
0d70: 6c 6f 61 64 20 73 69 7a 65 20 6f 66 20 61 6c 6c  load size of all
0d80: 20 63 65 6c 6c 73 20 2a 2f 22 0a 20 20 70 75 74   cells */".  put
0d90: 73 20 22 20 20 70 67 6f 66 66 73 65 74 20 20 20  s "  pgoffset   
0da0: 49 4e 54 45 47 45 52 2c 20 20 20 20 20 20 20 20  INTEGER,        
0db0: 20 20 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20 70    /* Offset of p
0dc0: 61 67 65 20 69 6e 20 66 69 6c 65 20 2a 2f 22 0a  age in file */".
0dd0: 20 20 70 75 74 73 20 22 20 20 70 67 73 69 7a 65    puts "  pgsize
0de0: 20 20 20 20 20 49 4e 54 45 47 45 52 20 20 20 20       INTEGER    
0df0: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
0e00: 66 20 74 68 65 20 70 61 67 65 20 2a 2f 22 0a 20  f the page */". 
0e10: 20 70 75 74 73 20 22 29 3b 22 0a 20 20 64 62 20   puts ");".  db 
0e20: 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 71 75 6f  eval {SELECT quo
0e30: 74 65 28 6e 61 6d 65 29 20 7c 7c 20 27 2c 27 20  te(name) || ',' 
0e40: 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ||.             
0e50: 20 20 20 20 20 71 75 6f 74 65 28 70 61 74 68 29       quote(path)
0e60: 20 7c 7c 20 27 2c 27 20 7c 7c 0a 20 20 20 20 20   || ',' ||.     
0e70: 20 20 20 20 20 20 20 20 20 20 20 20 20 71 75 6f               quo
0e80: 74 65 28 70 61 67 65 6e 6f 29 20 7c 7c 20 27 2c  te(pageno) || ',
0e90: 27 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20  ' ||.           
0ea0: 20 20 20 20 20 20 20 71 75 6f 74 65 28 70 61 67         quote(pag
0eb0: 65 74 79 70 65 29 20 7c 7c 20 27 2c 27 20 7c 7c  etype) || ',' ||
0ec0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0ed0: 20 20 20 71 75 6f 74 65 28 6e 63 65 6c 6c 29 20     quote(ncell) 
0ee0: 7c 7c 20 27 2c 27 20 7c 7c 0a 20 20 20 20 20 20  || ',' ||.      
0ef0: 20 20 20 20 20 20 20 20 20 20 20 20 71 75 6f 74              quot
0f00: 65 28 70 61 79 6c 6f 61 64 29 20 7c 7c 20 27 2c  e(payload) || ',
0f10: 27 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20  ' ||.           
0f20: 20 20 20 20 20 20 20 71 75 6f 74 65 28 75 6e 75         quote(unu
0f30: 73 65 64 29 20 7c 7c 20 27 2c 27 20 7c 7c 0a 20  sed) || ',' ||. 
0f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f50: 20 71 75 6f 74 65 28 6d 78 5f 70 61 79 6c 6f 61   quote(mx_payloa
0f60: 64 29 20 7c 7c 20 27 2c 27 20 7c 7c 0a 20 20 20  d) || ',' ||.   
0f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 71                 q
0f80: 75 6f 74 65 28 70 67 6f 66 66 73 65 74 29 20 7c  uote(pgoffset) |
0f90: 7c 20 27 2c 27 20 7c 7c 0a 20 20 20 20 20 20 20  | ',' ||.       
0fa0: 20 20 20 20 20 20 20 20 20 20 20 71 75 6f 74 65             quote
0fb0: 28 70 67 73 69 7a 65 29 20 41 53 20 78 20 46 52  (pgsize) AS x FR
0fc0: 4f 4d 20 73 74 61 74 7d 20 7b 0a 20 20 20 20 70  OM stat} {.    p
0fd0: 75 74 73 20 22 49 4e 53 45 52 54 20 49 4e 54 4f  uts "INSERT INTO
0fe0: 20 73 74 61 74 73 20 56 41 4c 55 45 53 28 24 78   stats VALUES($x
0ff0: 29 3b 22 0a 20 20 7d 0a 20 20 70 75 74 73 20 22  );".  }.  puts "
1000: 43 4f 4d 4d 49 54 3b 22 0a 20 20 65 78 69 74 20  COMMIT;".  exit 
1010: 30 0a 7d 0a 0a 23 20 49 6e 2d 6d 65 6d 6f 72 79  0.}..# In-memory
1020: 20 64 61 74 61 62 61 73 65 20 66 6f 72 20 63 6f   database for co
1030: 6c 6c 65 63 74 69 6e 67 20 73 74 61 74 69 73 74  llecting statist
1040: 69 63 73 2e 20 54 68 69 73 20 73 63 72 69 70 74  ics. This script
1050: 20 6c 6f 6f 70 73 20 74 68 72 6f 75 67 68 0a 23   loops through.#
1060: 20 74 68 65 20 74 61 62 6c 65 73 20 61 6e 64 20   the tables and 
1070: 69 6e 64 69 63 65 73 20 69 6e 20 74 68 65 20 64  indices in the d
1080: 61 74 61 62 61 73 65 20 62 65 69 6e 67 20 61 6e  atabase being an
1090: 61 6c 79 7a 65 64 2c 20 61 64 64 69 6e 67 20 61  alyzed, adding a
10a0: 20 72 6f 77 20 66 6f 72 20 65 61 63 68 0a 23 20   row for each.# 
10b0: 74 6f 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20  to an in-memory 
10c0: 64 61 74 61 62 61 73 65 20 28 66 6f 72 20 77 68  database (for wh
10d0: 69 63 68 20 74 68 65 20 73 63 68 65 6d 61 20 69  ich the schema i
10e0: 73 20 73 68 6f 77 6e 20 62 65 6c 6f 77 29 2e 20  s shown below). 
10f0: 49 74 20 74 68 65 6e 0a 23 20 71 75 65 72 69 65  It then.# querie
1100: 73 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20  s the in-memory 
1110: 64 62 20 74 6f 20 70 72 6f 64 75 63 65 20 74 68  db to produce th
1120: 65 20 73 70 61 63 65 2d 61 6e 61 6c 79 73 69 73  e space-analysis
1130: 20 72 65 70 6f 72 74 2e 0a 23 0a 73 71 6c 69 74   report..#.sqlit
1140: 65 33 20 6d 65 6d 20 3a 6d 65 6d 6f 72 79 3a 0a  e3 mem :memory:.
1150: 73 65 74 20 74 61 62 6c 65 64 65 66 20 7b 43 52  set tabledef {CR
1160: 45 41 54 45 20 54 41 42 4c 45 20 73 70 61 63 65  EATE TABLE space
1170: 5f 75 73 65 64 28 0a 20 20 20 6e 61 6d 65 20 63  _used(.   name c
1180: 6c 6f 62 2c 20 20 20 20 20 20 20 20 2d 2d 20 4e  lob,        -- N
1190: 61 6d 65 20 6f 66 20 61 20 74 61 62 6c 65 20 6f  ame of a table o
11a0: 72 20 69 6e 64 65 78 20 69 6e 20 74 68 65 20 64  r index in the d
11b0: 61 74 61 62 61 73 65 20 66 69 6c 65 0a 20 20 20  atabase file.   
11c0: 74 62 6c 6e 61 6d 65 20 63 6c 6f 62 2c 20 20 20  tblname clob,   
11d0: 20 20 2d 2d 20 4e 61 6d 65 20 6f 66 20 61 73 73    -- Name of ass
11e0: 6f 63 69 61 74 65 64 20 74 61 62 6c 65 0a 20 20  ociated table.  
11f0: 20 69 73 5f 69 6e 64 65 78 20 62 6f 6f 6c 65 61   is_index boolea
1200: 6e 2c 20 2d 2d 20 54 52 55 45 20 69 66 20 69 74  n, -- TRUE if it
1210: 20 69 73 20 61 6e 20 69 6e 64 65 78 2c 20 66 61   is an index, fa
1220: 6c 73 65 20 66 6f 72 20 61 20 74 61 62 6c 65 0a  lse for a table.
1230: 20 20 20 6e 65 6e 74 72 79 20 69 6e 74 2c 20 20     nentry int,  
1240: 20 20 20 20 20 2d 2d 20 4e 75 6d 62 65 72 20 6f       -- Number o
1250: 66 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65  f entries in the
1260: 20 42 54 72 65 65 0a 20 20 20 6c 65 61 66 5f 65   BTree.   leaf_e
1270: 6e 74 72 69 65 73 20 69 6e 74 2c 20 2d 2d 20 4e  ntries int, -- N
1280: 75 6d 62 65 72 20 6f 66 20 6c 65 61 66 20 65 6e  umber of leaf en
1290: 74 72 69 65 73 0a 20 20 20 64 65 70 74 68 20 69  tries.   depth i
12a0: 6e 74 2c 20 20 20 20 20 20 20 20 2d 2d 20 44 65  nt,        -- De
12b0: 70 74 68 20 6f 66 20 74 68 65 20 62 2d 74 72 65  pth of the b-tre
12c0: 65 0a 20 20 20 70 61 79 6c 6f 61 64 20 69 6e 74  e.   payload int
12d0: 2c 20 20 20 20 20 20 2d 2d 20 54 6f 74 61 6c 20  ,      -- Total 
12e0: 61 6d 6f 75 6e 74 20 6f 66 20 64 61 74 61 20 73  amount of data s
12f0: 74 6f 72 65 64 20 69 6e 20 74 68 69 73 20 74 61  tored in this ta
1300: 62 6c 65 20 6f 72 20 69 6e 64 65 78 0a 20 20 20  ble or index.   
1310: 6f 76 66 6c 5f 70 61 79 6c 6f 61 64 20 69 6e 74  ovfl_payload int
1320: 2c 20 2d 2d 20 54 6f 74 61 6c 20 61 6d 6f 75 6e  , -- Total amoun
1330: 74 20 6f 66 20 64 61 74 61 20 73 74 6f 72 65 64  t of data stored
1340: 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20 70 61 67   on overflow pag
1350: 65 73 0a 20 20 20 6f 76 66 6c 5f 63 6e 74 20 69  es.   ovfl_cnt i
1360: 6e 74 2c 20 20 20 20 20 2d 2d 20 4e 75 6d 62 65  nt,     -- Numbe
1370: 72 20 6f 66 20 65 6e 74 72 69 65 73 20 74 68 61  r of entries tha
1380: 74 20 75 73 65 20 6f 76 65 72 66 6c 6f 77 0a 20  t use overflow. 
1390: 20 20 6d 78 5f 70 61 79 6c 6f 61 64 20 69 6e 74    mx_payload int
13a0: 2c 20 20 20 2d 2d 20 4d 61 78 69 6d 75 6d 20 70  ,   -- Maximum p
13b0: 61 79 6c 6f 61 64 20 73 69 7a 65 0a 20 20 20 69  ayload size.   i
13c0: 6e 74 5f 70 61 67 65 73 20 69 6e 74 2c 20 20 20  nt_pages int,   
13d0: 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 69 6e   -- Number of in
13e0: 74 65 72 69 6f 72 20 70 61 67 65 73 20 75 73 65  terior pages use
13f0: 64 0a 20 20 20 6c 65 61 66 5f 70 61 67 65 73 20  d.   leaf_pages 
1400: 69 6e 74 2c 20 20 20 2d 2d 20 4e 75 6d 62 65 72  int,   -- Number
1410: 20 6f 66 20 6c 65 61 66 20 70 61 67 65 73 20 75   of leaf pages u
1420: 73 65 64 0a 20 20 20 6f 76 66 6c 5f 70 61 67 65  sed.   ovfl_page
1430: 73 20 69 6e 74 2c 20 20 20 2d 2d 20 4e 75 6d 62  s int,   -- Numb
1440: 65 72 20 6f 66 20 6f 76 65 72 66 6c 6f 77 20 70  er of overflow p
1450: 61 67 65 73 20 75 73 65 64 0a 20 20 20 69 6e 74  ages used.   int
1460: 5f 75 6e 75 73 65 64 20 69 6e 74 2c 20 20 20 2d  _unused int,   -
1470: 2d 20 4e 75 6d 62 65 72 20 6f 66 20 75 6e 75 73  - Number of unus
1480: 65 64 20 62 79 74 65 73 20 6f 6e 20 69 6e 74 65  ed bytes on inte
1490: 72 69 6f 72 20 70 61 67 65 73 0a 20 20 20 6c 65  rior pages.   le
14a0: 61 66 5f 75 6e 75 73 65 64 20 69 6e 74 2c 20 20  af_unused int,  
14b0: 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 75 6e 75  -- Number of unu
14c0: 73 65 64 20 62 79 74 65 73 20 6f 6e 20 70 72 69  sed bytes on pri
14d0: 6d 61 72 79 20 70 61 67 65 73 0a 20 20 20 6f 76  mary pages.   ov
14e0: 66 6c 5f 75 6e 75 73 65 64 20 69 6e 74 2c 20 20  fl_unused int,  
14f0: 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 75 6e 75  -- Number of unu
1500: 73 65 64 20 62 79 74 65 73 20 6f 6e 20 6f 76 65  sed bytes on ove
1510: 72 66 6c 6f 77 20 70 61 67 65 73 0a 20 20 20 67  rflow pages.   g
1520: 61 70 5f 63 6e 74 20 69 6e 74 2c 20 20 20 20 20  ap_cnt int,     
1530: 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 67 61   -- Number of ga
1540: 70 73 20 69 6e 20 74 68 65 20 70 61 67 65 20 6c  ps in the page l
1550: 61 79 6f 75 74 0a 20 20 20 63 6f 6d 70 72 65 73  ayout.   compres
1560: 73 65 64 5f 73 69 7a 65 20 69 6e 74 20 20 2d 2d  sed_size int  --
1570: 20 54 6f 74 61 6c 20 62 79 74 65 73 20 73 74 6f   Total bytes sto
1580: 72 65 64 20 6f 6e 20 64 69 73 6b 0a 29 3b 7d 0a  red on disk.);}.
1590: 6d 65 6d 20 65 76 61 6c 20 24 74 61 62 6c 65 64  mem eval $tabled
15a0: 65 66 0a 0a 23 20 43 72 65 61 74 65 20 61 20 74  ef..# Create a t
15b0: 65 6d 70 6f 72 61 72 79 20 22 64 62 73 74 61 74  emporary "dbstat
15c0: 22 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e  " virtual table.
15d0: 0a 23 0a 64 62 20 65 76 61 6c 20 7b 43 52 45 41  .#.db eval {CREA
15e0: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45  TE VIRTUAL TABLE
15f0: 20 74 65 6d 70 2e 73 74 61 74 20 55 53 49 4e 47   temp.stat USING
1600: 20 64 62 73 74 61 74 7d 0a 64 62 20 65 76 61 6c   dbstat}.db eval
1610: 20 7b 43 52 45 41 54 45 20 54 45 4d 50 20 54 41   {CREATE TEMP TA
1620: 42 4c 45 20 64 62 73 74 61 74 20 41 53 20 53 45  BLE dbstat AS SE
1630: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74 65 6d 70  LECT * FROM temp
1640: 2e 73 74 61 74 0a 20 20 20 20 20 20 20 20 20 4f  .stat.         O
1650: 52 44 45 52 20 42 59 20 6e 61 6d 65 2c 20 70 61  RDER BY name, pa
1660: 74 68 7d 0a 64 62 20 65 76 61 6c 20 7b 44 52 4f  th}.db eval {DRO
1670: 50 20 54 41 42 4c 45 20 74 65 6d 70 2e 73 74 61  P TABLE temp.sta
1680: 74 7d 0a 0a 73 65 74 20 69 73 43 6f 6d 70 72 65  t}..set isCompre
1690: 73 73 65 64 20 30 0a 73 65 74 20 63 6f 6d 70 72  ssed 0.set compr
16a0: 65 73 73 4f 76 65 72 68 65 61 64 20 30 0a 73 65  essOverhead 0.se
16b0: 74 20 64 65 70 74 68 20 30 0a 73 65 74 20 73 71  t depth 0.set sq
16c0: 6c 20 7b 20 53 45 4c 45 43 54 20 6e 61 6d 65 2c  l { SELECT name,
16d0: 20 74 62 6c 5f 6e 61 6d 65 20 46 52 4f 4d 20 73   tbl_name FROM s
16e0: 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45  qlite_master WHE
16f0: 52 45 20 72 6f 6f 74 70 61 67 65 3e 30 20 7d 0a  RE rootpage>0 }.
1700: 66 6f 72 65 61 63 68 20 7b 6e 61 6d 65 20 74 62  foreach {name tb
1710: 6c 6e 61 6d 65 7d 20 5b 63 6f 6e 63 61 74 20 73  lname} [concat s
1720: 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 73 71 6c  qlite_master sql
1730: 69 74 65 5f 6d 61 73 74 65 72 20 5b 64 62 20 65  ite_master [db e
1740: 76 61 6c 20 24 73 71 6c 5d 5d 20 7b 0a 0a 20 20  val $sql]] {..  
1750: 73 65 74 20 69 73 5f 69 6e 64 65 78 20 5b 65 78  set is_index [ex
1760: 70 72 20 7b 24 6e 61 6d 65 21 3d 24 74 62 6c 6e  pr {$name!=$tbln
1770: 61 6d 65 7d 5d 0a 20 20 73 65 74 20 69 64 78 5f  ame}].  set idx_
1780: 62 74 72 65 65 20 5b 65 78 70 72 20 7b 24 69 73  btree [expr {$is
1790: 5f 69 6e 64 65 78 20 7c 7c 20 5b 69 73 5f 77 69  _index || [is_wi
17a0: 74 68 6f 75 74 5f 72 6f 77 69 64 20 24 6e 61 6d  thout_rowid $nam
17b0: 65 5d 7d 5d 0a 20 20 64 62 20 65 76 61 6c 20 7b  e]}].  db eval {
17c0: 0a 20 20 20 20 53 45 4c 45 43 54 20 0a 20 20 20  .    SELECT .   
17d0: 20 20 20 73 75 6d 28 6e 63 65 6c 6c 29 20 41 53     sum(ncell) AS
17e0: 20 6e 65 6e 74 72 79 2c 0a 20 20 20 20 20 20 73   nentry,.      s
17f0: 75 6d 28 28 70 61 67 65 74 79 70 65 3d 3d 27 6c  um((pagetype=='l
1800: 65 61 66 27 29 2a 6e 63 65 6c 6c 29 20 41 53 20  eaf')*ncell) AS 
1810: 6c 65 61 66 5f 65 6e 74 72 69 65 73 2c 0a 20 20  leaf_entries,.  
1820: 20 20 20 20 73 75 6d 28 70 61 79 6c 6f 61 64 29      sum(payload)
1830: 20 41 53 20 70 61 79 6c 6f 61 64 2c 0a 20 20 20   AS payload,.   
1840: 20 20 20 73 75 6d 28 28 70 61 67 65 74 79 70 65     sum((pagetype
1850: 3d 3d 27 6f 76 65 72 66 6c 6f 77 27 29 20 2a 20  =='overflow') * 
1860: 70 61 79 6c 6f 61 64 29 20 41 53 20 6f 76 66 6c  payload) AS ovfl
1870: 5f 70 61 79 6c 6f 61 64 2c 0a 20 20 20 20 20 20  _payload,.      
1880: 73 75 6d 28 70 61 74 68 20 4c 49 4b 45 20 27 25  sum(path LIKE '%
1890: 2b 30 30 30 30 30 30 27 29 20 41 53 20 6f 76 66  +000000') AS ovf
18a0: 6c 5f 63 6e 74 2c 0a 20 20 20 20 20 20 6d 61 78  l_cnt,.      max
18b0: 28 6d 78 5f 70 61 79 6c 6f 61 64 29 20 41 53 20  (mx_payload) AS 
18c0: 6d 78 5f 70 61 79 6c 6f 61 64 2c 0a 20 20 20 20  mx_payload,.    
18d0: 20 20 73 75 6d 28 70 61 67 65 74 79 70 65 3d 3d    sum(pagetype==
18e0: 27 69 6e 74 65 72 6e 61 6c 27 29 20 41 53 20 69  'internal') AS i
18f0: 6e 74 5f 70 61 67 65 73 2c 0a 20 20 20 20 20 20  nt_pages,.      
1900: 73 75 6d 28 70 61 67 65 74 79 70 65 3d 3d 27 6c  sum(pagetype=='l
1910: 65 61 66 27 29 20 41 53 20 6c 65 61 66 5f 70 61  eaf') AS leaf_pa
1920: 67 65 73 2c 0a 20 20 20 20 20 20 73 75 6d 28 70  ges,.      sum(p
1930: 61 67 65 74 79 70 65 3d 3d 27 6f 76 65 72 66 6c  agetype=='overfl
1940: 6f 77 27 29 20 41 53 20 6f 76 66 6c 5f 70 61 67  ow') AS ovfl_pag
1950: 65 73 2c 0a 20 20 20 20 20 20 73 75 6d 28 28 70  es,.      sum((p
1960: 61 67 65 74 79 70 65 3d 3d 27 69 6e 74 65 72 6e  agetype=='intern
1970: 61 6c 27 29 20 2a 20 75 6e 75 73 65 64 29 20 41  al') * unused) A
1980: 53 20 69 6e 74 5f 75 6e 75 73 65 64 2c 0a 20 20  S int_unused,.  
1990: 20 20 20 20 73 75 6d 28 28 70 61 67 65 74 79 70      sum((pagetyp
19a0: 65 3d 3d 27 6c 65 61 66 27 29 20 2a 20 75 6e 75  e=='leaf') * unu
19b0: 73 65 64 29 20 41 53 20 6c 65 61 66 5f 75 6e 75  sed) AS leaf_unu
19c0: 73 65 64 2c 0a 20 20 20 20 20 20 73 75 6d 28 28  sed,.      sum((
19d0: 70 61 67 65 74 79 70 65 3d 3d 27 6f 76 65 72 66  pagetype=='overf
19e0: 6c 6f 77 27 29 20 2a 20 75 6e 75 73 65 64 29 20  low') * unused) 
19f0: 41 53 20 6f 76 66 6c 5f 75 6e 75 73 65 64 2c 0a  AS ovfl_unused,.
1a00: 20 20 20 20 20 20 73 75 6d 28 70 67 73 69 7a 65        sum(pgsize
1a10: 29 20 41 53 20 63 6f 6d 70 72 65 73 73 65 64 5f  ) AS compressed_
1a20: 73 69 7a 65 2c 0a 20 20 20 20 20 20 6d 61 78 28  size,.      max(
1a30: 28 6c 65 6e 67 74 68 28 43 41 53 45 20 57 48 45  (length(CASE WHE
1a40: 4e 20 70 61 74 68 20 4c 49 4b 45 20 27 25 2b 25  N path LIKE '%+%
1a50: 27 20 54 48 45 4e 20 27 27 20 45 4c 53 45 20 70  ' THEN '' ELSE p
1a60: 61 74 68 20 45 4e 44 29 2b 33 29 2f 34 29 0a 20  ath END)+3)/4). 
1a70: 20 20 20 20 20 20 20 41 53 20 64 65 70 74 68 0a         AS depth.
1a80: 20 20 20 20 46 52 4f 4d 20 74 65 6d 70 2e 64 62      FROM temp.db
1a90: 73 74 61 74 20 57 48 45 52 45 20 6e 61 6d 65 20  stat WHERE name 
1aa0: 3d 20 24 6e 61 6d 65 0a 20 20 7d 20 62 72 65 61  = $name.  } brea
1ab0: 6b 0a 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f 70  k..  set total_p
1ac0: 61 67 65 73 20 5b 65 78 70 72 20 7b 24 6c 65 61  ages [expr {$lea
1ad0: 66 5f 70 61 67 65 73 2b 24 69 6e 74 5f 70 61 67  f_pages+$int_pag
1ae0: 65 73 2b 24 6f 76 66 6c 5f 70 61 67 65 73 7d 5d  es+$ovfl_pages}]
1af0: 0a 20 20 73 65 74 20 73 74 6f 72 61 67 65 20 5b  .  set storage [
1b00: 65 78 70 72 20 7b 24 74 6f 74 61 6c 5f 70 61 67  expr {$total_pag
1b10: 65 73 2a 24 70 61 67 65 53 69 7a 65 7d 5d 0a 20  es*$pageSize}]. 
1b20: 20 69 66 20 7b 21 24 69 73 43 6f 6d 70 72 65 73   if {!$isCompres
1b30: 73 65 64 20 26 26 20 24 73 74 6f 72 61 67 65 3e  sed && $storage>
1b40: 24 63 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a 65  $compressed_size
1b50: 7d 20 7b 0a 20 20 20 20 73 65 74 20 69 73 43 6f  } {.    set isCo
1b60: 6d 70 72 65 73 73 65 64 20 31 0a 20 20 20 20 73  mpressed 1.    s
1b70: 65 74 20 63 6f 6d 70 72 65 73 73 4f 76 65 72 68  et compressOverh
1b80: 65 61 64 20 31 34 0a 20 20 7d 0a 0a 20 20 23 20  ead 14.  }..  # 
1b90: 43 6f 6c 75 6d 6e 20 27 67 61 70 5f 63 6e 74 27  Column 'gap_cnt'
1ba0: 20 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e   is set to the n
1bb0: 75 6d 62 65 72 20 6f 66 20 6e 6f 6e 2d 63 6f 6e  umber of non-con
1bc0: 74 69 67 75 6f 75 73 20 65 6e 74 72 69 65 73 20  tiguous entries 
1bd0: 69 6e 20 74 68 65 0a 20 20 23 20 6c 69 73 74 20  in the.  # list 
1be0: 6f 66 20 70 61 67 65 73 20 76 69 73 69 74 65 64  of pages visited
1bf0: 20 69 66 20 74 68 65 20 62 2d 74 72 65 65 20 73   if the b-tree s
1c00: 74 72 75 63 74 75 72 65 20 69 73 20 74 72 61 76  tructure is trav
1c10: 65 72 73 65 64 20 69 6e 20 61 20 74 6f 70 2d 64  ersed in a top-d
1c20: 6f 77 6e 0a 20 20 23 20 66 61 73 68 69 6f 6e 20  own.  # fashion 
1c30: 28 65 61 63 68 20 6e 6f 64 65 20 76 69 73 69 74  (each node visit
1c40: 65 64 20 62 65 66 6f 72 65 20 69 74 73 20 63 68  ed before its ch
1c50: 69 6c 64 2d 74 72 65 65 20 69 73 20 70 61 73 73  ild-tree is pass
1c60: 65 64 29 2e 20 41 6e 79 20 6f 76 65 72 66 6c 6f  ed). Any overflo
1c70: 77 0a 20 20 23 20 63 68 61 69 6e 73 20 70 72 65  w.  # chains pre
1c80: 73 65 6e 74 20 61 72 65 20 74 72 61 76 65 72 73  sent are travers
1c90: 65 64 20 66 72 6f 6d 20 73 74 61 72 74 20 74 6f  ed from start to
1ca0: 20 66 69 6e 69 73 68 20 62 65 66 6f 72 65 20 61   finish before a
1cb0: 6e 79 20 63 68 69 6c 64 2d 74 72 65 65 0a 20 20  ny child-tree.  
1cc0: 23 20 69 73 2e 0a 20 20 23 0a 20 20 73 65 74 20  # is..  #.  set 
1cd0: 67 61 70 5f 63 6e 74 20 30 0a 20 20 73 65 74 20  gap_cnt 0.  set 
1ce0: 70 72 65 76 20 30 0a 20 20 64 62 20 65 76 61 6c  prev 0.  db eval
1cf0: 20 7b 0a 20 20 20 20 53 45 4c 45 43 54 20 70 61   {.    SELECT pa
1d00: 67 65 6e 6f 2c 20 70 61 67 65 74 79 70 65 20 46  geno, pagetype F
1d10: 52 4f 4d 20 74 65 6d 70 2e 64 62 73 74 61 74 0a  ROM temp.dbstat.
1d20: 20 20 20 20 20 57 48 45 52 45 20 6e 61 6d 65 3d       WHERE name=
1d30: 24 6e 61 6d 65 0a 20 20 20 20 20 4f 52 44 45 52  $name.     ORDER
1d40: 20 42 59 20 70 61 67 65 6e 6f 0a 20 20 7d 20 7b   BY pageno.  } {
1d50: 0a 20 20 20 20 69 66 20 7b 24 70 72 65 76 3e 30  .    if {$prev>0
1d60: 20 26 26 20 24 70 61 67 65 74 79 70 65 3d 3d 22   && $pagetype=="
1d70: 6c 65 61 66 22 20 26 26 20 24 70 61 67 65 6e 6f  leaf" && $pageno
1d80: 21 3d 24 70 72 65 76 2b 31 7d 20 7b 0a 20 20 20  !=$prev+1} {.   
1d90: 20 20 20 69 6e 63 72 20 67 61 70 5f 63 6e 74 0a     incr gap_cnt.
1da0: 20 20 20 20 7d 0a 20 20 20 20 73 65 74 20 70 72      }.    set pr
1db0: 65 76 20 24 70 61 67 65 6e 6f 0a 20 20 7d 0a 20  ev $pageno.  }. 
1dc0: 20 6d 65 6d 20 65 76 61 6c 20 7b 0a 20 20 20 20   mem eval {.    
1dd0: 49 4e 53 45 52 54 20 49 4e 54 4f 20 73 70 61 63  INSERT INTO spac
1de0: 65 5f 75 73 65 64 20 56 41 4c 55 45 53 28 0a 20  e_used VALUES(. 
1df0: 20 20 20 20 20 24 6e 61 6d 65 2c 0a 20 20 20 20       $name,.    
1e00: 20 20 24 74 62 6c 6e 61 6d 65 2c 0a 20 20 20 20    $tblname,.    
1e10: 20 20 24 69 73 5f 69 6e 64 65 78 2c 0a 20 20 20    $is_index,.   
1e20: 20 20 20 24 6e 65 6e 74 72 79 2c 0a 20 20 20 20     $nentry,.    
1e30: 20 20 24 6c 65 61 66 5f 65 6e 74 72 69 65 73 2c    $leaf_entries,
1e40: 0a 20 20 20 20 20 20 24 64 65 70 74 68 2c 0a 20  .      $depth,. 
1e50: 20 20 20 20 20 24 70 61 79 6c 6f 61 64 2c 20 20       $payload,  
1e60: 20 20 20 0a 20 20 20 20 20 20 24 6f 76 66 6c 5f     .      $ovfl_
1e70: 70 61 79 6c 6f 61 64 2c 0a 20 20 20 20 20 20 24  payload,.      $
1e80: 6f 76 66 6c 5f 63 6e 74 2c 20 20 20 0a 20 20 20  ovfl_cnt,   .   
1e90: 20 20 20 24 6d 78 5f 70 61 79 6c 6f 61 64 2c 0a     $mx_payload,.
1ea0: 20 20 20 20 20 20 24 69 6e 74 5f 70 61 67 65 73        $int_pages
1eb0: 2c 0a 20 20 20 20 20 20 24 6c 65 61 66 5f 70 61  ,.      $leaf_pa
1ec0: 67 65 73 2c 20 20 0a 20 20 20 20 20 20 24 6f 76  ges,  .      $ov
1ed0: 66 6c 5f 70 61 67 65 73 2c 20 0a 20 20 20 20 20  fl_pages, .     
1ee0: 20 24 69 6e 74 5f 75 6e 75 73 65 64 2c 20 0a 20   $int_unused, . 
1ef0: 20 20 20 20 20 24 6c 65 61 66 5f 75 6e 75 73 65       $leaf_unuse
1f00: 64 2c 0a 20 20 20 20 20 20 24 6f 76 66 6c 5f 75  d,.      $ovfl_u
1f10: 6e 75 73 65 64 2c 0a 20 20 20 20 20 20 24 67 61  nused,.      $ga
1f20: 70 5f 63 6e 74 2c 0a 20 20 20 20 20 20 24 63 6f  p_cnt,.      $co
1f30: 6d 70 72 65 73 73 65 64 5f 73 69 7a 65 0a 20 20  mpressed_size.  
1f40: 20 20 29 3b 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63    );.  }.}..proc
1f50: 20 69 6e 74 65 67 65 72 69 66 79 20 7b 72 65 61   integerify {rea
1f60: 6c 7d 20 7b 0a 20 20 69 66 20 7b 5b 73 74 72 69  l} {.  if {[stri
1f70: 6e 67 20 69 73 20 64 6f 75 62 6c 65 20 2d 73 74  ng is double -st
1f80: 72 69 63 74 20 24 72 65 61 6c 5d 7d 20 7b 0a 20  rict $real]} {. 
1f90: 20 20 20 72 65 74 75 72 6e 20 5b 65 78 70 72 20     return [expr 
1fa0: 7b 77 69 64 65 28 24 72 65 61 6c 29 7d 5d 0a 20  {wide($real)}]. 
1fb0: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 72 65   } else {.    re
1fc0: 74 75 72 6e 20 30 0a 20 20 7d 0a 7d 0a 6d 65 6d  turn 0.  }.}.mem
1fd0: 20 66 75 6e 63 74 69 6f 6e 20 69 6e 74 20 69 6e   function int in
1fe0: 74 65 67 65 72 69 66 79 0a 0a 23 20 51 75 6f 74  tegerify..# Quot
1ff0: 65 20 61 20 73 74 72 69 6e 67 20 66 6f 72 20 75  e a string for u
2000: 73 65 20 69 6e 20 61 6e 20 53 51 4c 20 71 75 65  se in an SQL que
2010: 72 79 2e 20 45 78 61 6d 70 6c 65 73 3a 0a 23 0a  ry. Examples:.#.
2020: 23 20 5b 71 75 6f 74 65 20 7b 68 65 6c 6c 6f 20  # [quote {hello 
2030: 77 6f 72 6c 64 7d 5d 20 20 20 3d 3d 20 7b 27 68  world}]   == {'h
2040: 65 6c 6c 6f 20 77 6f 72 6c 64 27 7d 0a 23 20 5b  ello world'}.# [
2050: 71 75 6f 74 65 20 7b 68 65 6c 6c 6f 20 77 6f 72  quote {hello wor
2060: 6c 64 27 73 7d 5d 20 3d 3d 20 7b 27 68 65 6c 6c  ld's}] == {'hell
2070: 6f 20 77 6f 72 6c 64 27 27 73 27 7d 0a 23 0a 70  o world''s'}.#.p
2080: 72 6f 63 20 71 75 6f 74 65 20 7b 74 78 74 7d 20  roc quote {txt} 
2090: 7b 0a 20 20 72 65 74 75 72 6e 20 5b 73 74 72 69  {.  return [stri
20a0: 6e 67 20 6d 61 70 20 7b 27 20 27 27 7d 20 24 74  ng map {' ''} $t
20b0: 78 74 5d 0a 7d 0a 0a 23 20 4f 75 74 70 75 74 20  xt].}..# Output 
20c0: 61 20 74 69 74 6c 65 20 6c 69 6e 65 0a 23 0a 70  a title line.#.p
20d0: 72 6f 63 20 74 69 74 6c 65 6c 69 6e 65 20 7b 74  roc titleline {t
20e0: 69 74 6c 65 7d 20 7b 0a 20 20 69 66 20 7b 24 74  itle} {.  if {$t
20f0: 69 74 6c 65 3d 3d 22 22 7d 20 7b 0a 20 20 20 20  itle==""} {.    
2100: 70 75 74 73 20 5b 73 74 72 69 6e 67 20 72 65 70  puts [string rep
2110: 65 61 74 20 2a 20 37 39 5d 0a 20 20 7d 20 65 6c  eat * 79].  } el
2120: 73 65 20 7b 0a 20 20 20 20 73 65 74 20 6c 65 6e  se {.    set len
2130: 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20   [string length 
2140: 24 74 69 74 6c 65 5d 0a 20 20 20 20 73 65 74 20  $title].    set 
2150: 73 74 61 72 73 20 5b 73 74 72 69 6e 67 20 72 65  stars [string re
2160: 70 65 61 74 20 2a 20 5b 65 78 70 72 20 37 39 2d  peat * [expr 79-
2170: 24 6c 65 6e 2d 35 5d 5d 0a 20 20 20 20 70 75 74  $len-5]].    put
2180: 73 20 22 2a 2a 2a 20 24 74 69 74 6c 65 20 24 73  s "*** $title $s
2190: 74 61 72 73 22 0a 20 20 7d 0a 7d 0a 0a 23 20 47  tars".  }.}..# G
21a0: 65 6e 65 72 61 74 65 20 61 20 73 69 6e 67 6c 65  enerate a single
21b0: 20 6c 69 6e 65 20 6f 66 20 6f 75 74 70 75 74 20   line of output 
21c0: 69 6e 20 74 68 65 20 73 74 61 74 69 73 74 69 63  in the statistic
21d0: 73 20 73 65 63 74 69 6f 6e 20 6f 66 20 74 68 65  s section of the
21e0: 0a 23 20 72 65 70 6f 72 74 2e 0a 23 0a 70 72 6f  .# report..#.pro
21f0: 63 20 73 74 61 74 6c 69 6e 65 20 7b 74 69 74 6c  c statline {titl
2200: 65 20 76 61 6c 75 65 20 7b 65 78 74 72 61 20 7b  e value {extra {
2210: 7d 7d 7d 20 7b 0a 20 20 73 65 74 20 6c 65 6e 20  }}} {.  set len 
2220: 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24  [string length $
2230: 74 69 74 6c 65 5d 0a 20 20 73 65 74 20 64 6f 74  title].  set dot
2240: 73 20 5b 73 74 72 69 6e 67 20 72 65 70 65 61 74  s [string repeat
2250: 20 2e 20 5b 65 78 70 72 20 35 30 2d 24 6c 65 6e   . [expr 50-$len
2260: 5d 5d 0a 20 20 73 65 74 20 6c 65 6e 20 5b 73 74  ]].  set len [st
2270: 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 76 61 6c  ring length $val
2280: 75 65 5d 0a 20 20 73 65 74 20 73 70 32 20 5b 73  ue].  set sp2 [s
2290: 74 72 69 6e 67 20 72 61 6e 67 65 20 7b 20 20 20  tring range {   
22a0: 20 20 20 20 20 20 20 7d 20 24 6c 65 6e 20 65 6e         } $len en
22b0: 64 5d 0a 20 20 69 66 20 7b 24 65 78 74 72 61 20  d].  if {$extra 
22c0: 6e 65 20 22 22 7d 20 7b 0a 20 20 20 20 73 65 74  ne ""} {.    set
22d0: 20 65 78 74 72 61 20 22 20 24 65 78 74 72 61 22   extra " $extra"
22e0: 0a 20 20 7d 0a 20 20 70 75 74 73 20 22 24 74 69  .  }.  puts "$ti
22f0: 74 6c 65 24 64 6f 74 73 20 24 76 61 6c 75 65 24  tle$dots $value$
2300: 73 70 32 24 65 78 74 72 61 22 0a 7d 0a 0a 23 20  sp2$extra".}..# 
2310: 47 65 6e 65 72 61 74 65 20 61 20 66 6f 72 6d 61  Generate a forma
2320: 74 74 65 64 20 70 65 72 63 65 6e 74 61 67 65 20  tted percentage 
2330: 76 61 6c 75 65 20 66 6f 72 20 24 6e 75 6d 2f 24  value for $num/$
2340: 64 65 6e 6f 6d 0a 23 0a 70 72 6f 63 20 70 65 72  denom.#.proc per
2350: 63 65 6e 74 20 7b 6e 75 6d 20 64 65 6e 6f 6d 20  cent {num denom 
2360: 7b 6f 66 20 7b 7d 7d 7d 20 7b 0a 20 20 69 66 20  {of {}}} {.  if 
2370: 7b 24 64 65 6e 6f 6d 3d 3d 30 2e 30 7d 20 7b 72  {$denom==0.0} {r
2380: 65 74 75 72 6e 20 22 22 7d 0a 20 20 73 65 74 20  eturn ""}.  set 
2390: 76 20 5b 65 78 70 72 20 7b 24 6e 75 6d 2a 31 30  v [expr {$num*10
23a0: 30 2e 30 2f 24 64 65 6e 6f 6d 7d 5d 0a 20 20 73  0.0/$denom}].  s
23b0: 65 74 20 6f 66 20 7b 7d 0a 20 20 69 66 20 7b 24  et of {}.  if {$
23c0: 76 3d 3d 31 30 30 2e 30 20 7c 7c 20 24 76 3c 30  v==100.0 || $v<0
23d0: 2e 30 30 31 20 7c 7c 20 28 24 76 3e 31 2e 30 20  .001 || ($v>1.0 
23e0: 26 26 20 24 76 3c 39 39 2e 30 29 7d 20 7b 0a 20  && $v<99.0)} {. 
23f0: 20 20 20 72 65 74 75 72 6e 20 5b 66 6f 72 6d 61     return [forma
2400: 74 20 7b 25 35 2e 31 66 25 25 20 25 73 7d 20 24  t {%5.1f%% %s} $
2410: 76 20 24 6f 66 5d 0a 20 20 7d 20 65 6c 73 65 69  v $of].  } elsei
2420: 66 20 7b 24 76 3c 30 2e 31 20 7c 7c 20 24 76 3e  f {$v<0.1 || $v>
2430: 39 39 2e 39 7d 20 7b 0a 20 20 20 20 72 65 74 75  99.9} {.    retu
2440: 72 6e 20 5b 66 6f 72 6d 61 74 20 7b 25 37 2e 33  rn [format {%7.3
2450: 66 25 25 20 25 73 7d 20 24 76 20 24 6f 66 5d 0a  f%% %s} $v $of].
2460: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 72    } else {.    r
2470: 65 74 75 72 6e 20 5b 66 6f 72 6d 61 74 20 7b 25  eturn [format {%
2480: 36 2e 32 66 25 25 20 25 73 7d 20 24 76 20 24 6f  6.2f%% %s} $v $o
2490: 66 5d 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20 64  f].  }.}..proc d
24a0: 69 76 69 64 65 20 7b 6e 75 6d 20 64 65 6e 6f 6d  ivide {num denom
24b0: 7d 20 7b 0a 20 20 69 66 20 7b 24 64 65 6e 6f 6d  } {.  if {$denom
24c0: 3d 3d 30 7d 20 7b 72 65 74 75 72 6e 20 30 2e 30  ==0} {return 0.0
24d0: 7d 0a 20 20 72 65 74 75 72 6e 20 5b 66 6f 72 6d  }.  return [form
24e0: 61 74 20 25 2e 32 66 20 5b 65 78 70 72 20 64 6f  at %.2f [expr do
24f0: 75 62 6c 65 28 24 6e 75 6d 29 2f 64 6f 75 62 6c  uble($num)/doubl
2500: 65 28 24 64 65 6e 6f 6d 29 5d 5d 0a 7d 0a 0a 23  e($denom)]].}..#
2510: 20 47 65 6e 65 72 61 74 65 20 61 20 73 75 62 72   Generate a subr
2520: 65 70 6f 72 74 20 74 68 61 74 20 63 6f 76 65 72  eport that cover
2530: 73 20 73 6f 6d 65 20 73 75 62 73 65 74 20 6f 66  s some subset of
2540: 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a 23   the database..#
2550: 20 74 68 65 20 24 77 68 65 72 65 20 63 6c 61 75   the $where clau
2560: 73 65 20 64 65 74 65 72 6d 69 6e 65 73 20 77 68  se determines wh
2570: 69 63 68 20 73 75 62 73 65 74 20 74 6f 20 61 6e  ich subset to an
2580: 61 6c 79 7a 65 2e 0a 23 0a 70 72 6f 63 20 73 75  alyze..#.proc su
2590: 62 72 65 70 6f 72 74 20 7b 74 69 74 6c 65 20 77  breport {title w
25a0: 68 65 72 65 20 73 68 6f 77 46 72 61 67 7d 20 7b  here showFrag} {
25b0: 0a 20 20 67 6c 6f 62 61 6c 20 70 61 67 65 53 69  .  global pageSi
25c0: 7a 65 20 66 69 6c 65 5f 70 67 63 6e 74 20 63 6f  ze file_pgcnt co
25d0: 6d 70 72 65 73 73 4f 76 65 72 68 65 61 64 0a 0a  mpressOverhead..
25e0: 20 20 23 20 51 75 65 72 79 20 74 68 65 20 69 6e    # Query the in
25f0: 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62 61 73 65  -memory database
2600: 20 66 6f 72 20 74 68 65 20 73 75 6d 20 6f 66 20   for the sum of 
2610: 76 61 72 69 6f 75 73 20 73 74 61 74 69 73 74 69  various statisti
2620: 63 73 20 0a 20 20 23 20 66 6f 72 20 74 68 65 20  cs .  # for the 
2630: 73 75 62 73 65 74 20 6f 66 20 74 61 62 6c 65 73  subset of tables
2640: 2f 69 6e 64 69 63 65 73 20 69 64 65 6e 74 69 66  /indices identif
2650: 69 65 64 20 62 79 20 74 68 65 20 57 48 45 52 45  ied by the WHERE
2660: 20 63 6c 61 75 73 65 20 69 6e 0a 20 20 23 20 24   clause in.  # $
2670: 77 68 65 72 65 2e 20 4e 6f 74 65 20 74 68 61 74  where. Note that
2680: 20 65 76 65 6e 20 69 66 20 74 68 65 20 57 48 45   even if the WHE
2690: 52 45 20 63 6c 61 75 73 65 20 6d 61 74 63 68 65  RE clause matche
26a0: 73 20 6e 6f 20 72 6f 77 73 2c 20 74 68 65 0a 20  s no rows, the. 
26b0: 20 23 20 66 6f 6c 6c 6f 77 69 6e 67 20 71 75 65   # following que
26c0: 72 79 20 72 65 74 75 72 6e 73 20 65 78 61 63 74  ry returns exact
26d0: 6c 79 20 6f 6e 65 20 72 6f 77 20 28 62 65 63 61  ly one row (beca
26e0: 75 73 65 20 69 74 20 69 73 20 61 6e 20 61 67 67  use it is an agg
26f0: 72 65 67 61 74 65 29 2e 0a 20 20 23 0a 20 20 23  regate)..  #.  #
2700: 20 54 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20   The results of 
2710: 74 68 65 20 71 75 65 72 79 20 61 72 65 20 73 74  the query are st
2720: 6f 72 65 64 20 64 69 72 65 63 74 6c 79 20 62 79  ored directly by
2730: 20 53 51 4c 69 74 65 20 69 6e 74 6f 20 6c 6f 63   SQLite into loc
2740: 61 6c 20 0a 20 20 23 20 76 61 72 69 61 62 6c 65  al .  # variable
2750: 73 20 28 69 2e 65 2e 20 24 6e 65 6e 74 72 79 2c  s (i.e. $nentry,
2760: 20 24 6e 6c 65 61 66 20 65 74 63 2e 29 2e 0a 20   $nleaf etc.).. 
2770: 20 23 0a 20 20 6d 65 6d 20 65 76 61 6c 20 22 0a   #.  mem eval ".
2780: 20 20 20 20 53 45 4c 45 43 54 0a 20 20 20 20 20      SELECT.     
2790: 20 69 6e 74 28 73 75 6d 28 6e 65 6e 74 72 79 29   int(sum(nentry)
27a0: 29 20 41 53 20 6e 65 6e 74 72 79 2c 0a 20 20 20  ) AS nentry,.   
27b0: 20 20 20 69 6e 74 28 73 75 6d 28 6c 65 61 66 5f     int(sum(leaf_
27c0: 65 6e 74 72 69 65 73 29 29 20 41 53 20 6e 6c 65  entries)) AS nle
27d0: 61 66 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75  af,.      int(su
27e0: 6d 28 70 61 79 6c 6f 61 64 29 29 20 41 53 20 70  m(payload)) AS p
27f0: 61 79 6c 6f 61 64 2c 0a 20 20 20 20 20 20 69 6e  ayload,.      in
2800: 74 28 73 75 6d 28 6f 76 66 6c 5f 70 61 79 6c 6f  t(sum(ovfl_paylo
2810: 61 64 29 29 20 41 53 20 6f 76 66 6c 5f 70 61 79  ad)) AS ovfl_pay
2820: 6c 6f 61 64 2c 0a 20 20 20 20 20 20 6d 61 78 28  load,.      max(
2830: 6d 78 5f 70 61 79 6c 6f 61 64 29 20 41 53 20 6d  mx_payload) AS m
2840: 78 5f 70 61 79 6c 6f 61 64 2c 0a 20 20 20 20 20  x_payload,.     
2850: 20 69 6e 74 28 73 75 6d 28 6f 76 66 6c 5f 63 6e   int(sum(ovfl_cn
2860: 74 29 29 20 61 73 20 6f 76 66 6c 5f 63 6e 74 2c  t)) as ovfl_cnt,
2870: 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d 28 6c  .      int(sum(l
2880: 65 61 66 5f 70 61 67 65 73 29 29 20 41 53 20 6c  eaf_pages)) AS l
2890: 65 61 66 5f 70 61 67 65 73 2c 0a 20 20 20 20 20  eaf_pages,.     
28a0: 20 69 6e 74 28 73 75 6d 28 69 6e 74 5f 70 61 67   int(sum(int_pag
28b0: 65 73 29 29 20 41 53 20 69 6e 74 5f 70 61 67 65  es)) AS int_page
28c0: 73 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d  s,.      int(sum
28d0: 28 6f 76 66 6c 5f 70 61 67 65 73 29 29 20 41 53  (ovfl_pages)) AS
28e0: 20 6f 76 66 6c 5f 70 61 67 65 73 2c 0a 20 20 20   ovfl_pages,.   
28f0: 20 20 20 69 6e 74 28 73 75 6d 28 6c 65 61 66 5f     int(sum(leaf_
2900: 75 6e 75 73 65 64 29 29 20 41 53 20 6c 65 61 66  unused)) AS leaf
2910: 5f 75 6e 75 73 65 64 2c 0a 20 20 20 20 20 20 69  _unused,.      i
2920: 6e 74 28 73 75 6d 28 69 6e 74 5f 75 6e 75 73 65  nt(sum(int_unuse
2930: 64 29 29 20 41 53 20 69 6e 74 5f 75 6e 75 73 65  d)) AS int_unuse
2940: 64 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d  d,.      int(sum
2950: 28 6f 76 66 6c 5f 75 6e 75 73 65 64 29 29 20 41  (ovfl_unused)) A
2960: 53 20 6f 76 66 6c 5f 75 6e 75 73 65 64 2c 0a 20  S ovfl_unused,. 
2970: 20 20 20 20 20 69 6e 74 28 73 75 6d 28 67 61 70       int(sum(gap
2980: 5f 63 6e 74 29 29 20 41 53 20 67 61 70 5f 63 6e  _cnt)) AS gap_cn
2990: 74 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d  t,.      int(sum
29a0: 28 63 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a 65  (compressed_size
29b0: 29 29 20 41 53 20 63 6f 6d 70 72 65 73 73 65 64  )) AS compressed
29c0: 5f 73 69 7a 65 2c 0a 20 20 20 20 20 20 69 6e 74  _size,.      int
29d0: 28 6d 61 78 28 64 65 70 74 68 29 29 20 41 53 20  (max(depth)) AS 
29e0: 64 65 70 74 68 2c 0a 20 20 20 20 20 20 63 6f 75  depth,.      cou
29f0: 6e 74 28 2a 29 20 41 53 20 63 6e 74 0a 20 20 20  nt(*) AS cnt.   
2a00: 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73 65 64   FROM space_used
2a10: 20 57 48 45 52 45 20 24 77 68 65 72 65 22 20 7b   WHERE $where" {
2a20: 7d 20 7b 7d 0a 0a 20 20 23 20 4f 75 74 70 75 74  } {}..  # Output
2a30: 20 74 68 65 20 73 75 62 2d 72 65 70 6f 72 74 20   the sub-report 
2a40: 74 69 74 6c 65 2c 20 6e 69 63 65 6c 79 20 64 65  title, nicely de
2a50: 63 6f 72 61 74 65 64 20 77 69 74 68 20 2a 20 63  corated with * c
2a60: 68 61 72 61 63 74 65 72 73 2e 0a 20 20 23 0a 20  haracters..  #. 
2a70: 20 70 75 74 73 20 22 22 0a 20 20 74 69 74 6c 65   puts "".  title
2a80: 6c 69 6e 65 20 24 74 69 74 6c 65 0a 20 20 70 75  line $title.  pu
2a90: 74 73 20 22 22 0a 0a 20 20 23 20 43 61 6c 63 75  ts ""..  # Calcu
2aa0: 6c 61 74 65 20 73 74 61 74 69 73 74 69 63 73 20  late statistics 
2ab0: 61 6e 64 20 73 74 6f 72 65 20 74 68 65 20 72 65  and store the re
2ac0: 73 75 6c 74 73 20 69 6e 20 54 43 4c 20 76 61 72  sults in TCL var
2ad0: 69 61 62 6c 65 73 2c 20 61 73 20 66 6f 6c 6c 6f  iables, as follo
2ae0: 77 73 3a 0a 20 20 23 0a 20 20 23 20 74 6f 74 61  ws:.  #.  # tota
2af0: 6c 5f 70 61 67 65 73 3a 20 44 61 74 61 62 61 73  l_pages: Databas
2b00: 65 20 70 61 67 65 73 20 63 6f 6e 73 75 6d 65 64  e pages consumed
2b10: 2e 0a 20 20 23 20 74 6f 74 61 6c 5f 70 61 67 65  ..  # total_page
2b20: 73 5f 70 65 72 63 65 6e 74 3a 20 50 61 67 65 73  s_percent: Pages
2b30: 20 63 6f 6e 73 75 6d 65 64 20 61 73 20 61 20 70   consumed as a p
2b40: 65 72 63 65 6e 74 61 67 65 20 6f 66 20 74 68 65  ercentage of the
2b50: 20 66 69 6c 65 2e 0a 20 20 23 20 73 74 6f 72 61   file..  # stora
2b60: 67 65 3a 20 42 79 74 65 73 20 63 6f 6e 73 75 6d  ge: Bytes consum
2b70: 65 64 2e 0a 20 20 23 20 70 61 79 6c 6f 61 64 5f  ed..  # payload_
2b80: 70 65 72 63 65 6e 74 3a 20 50 61 79 6c 6f 61 64  percent: Payload
2b90: 20 62 79 74 65 73 20 75 73 65 64 20 61 73 20 61   bytes used as a
2ba0: 20 70 65 72 63 65 6e 74 61 67 65 20 6f 66 20 24   percentage of $
2bb0: 73 74 6f 72 61 67 65 2e 0a 20 20 23 20 74 6f 74  storage..  # tot
2bc0: 61 6c 5f 75 6e 75 73 65 64 3a 20 55 6e 75 73 65  al_unused: Unuse
2bd0: 64 20 62 79 74 65 73 20 6f 6e 20 70 61 67 65 73  d bytes on pages
2be0: 2e 0a 20 20 23 20 61 76 67 5f 70 61 79 6c 6f 61  ..  # avg_payloa
2bf0: 64 3a 20 41 76 65 72 61 67 65 20 70 61 79 6c 6f  d: Average paylo
2c00: 61 64 20 70 65 72 20 62 74 72 65 65 20 65 6e 74  ad per btree ent
2c10: 72 79 2e 0a 20 20 23 20 61 76 67 5f 66 61 6e 6f  ry..  # avg_fano
2c20: 75 74 3a 20 41 76 65 72 61 67 65 20 66 61 6e 6f  ut: Average fano
2c30: 75 74 20 66 6f 72 20 69 6e 74 65 72 6e 61 6c 20  ut for internal 
2c40: 70 61 67 65 73 2e 0a 20 20 23 20 61 76 67 5f 75  pages..  # avg_u
2c50: 6e 75 73 65 64 3a 20 41 76 65 72 61 67 65 20 75  nused: Average u
2c60: 6e 75 73 65 64 20 62 79 74 65 73 20 70 65 72 20  nused bytes per 
2c70: 62 74 72 65 65 20 65 6e 74 72 79 2e 0a 20 20 23  btree entry..  #
2c80: 20 6f 76 66 6c 5f 63 6e 74 5f 70 65 72 63 65 6e   ovfl_cnt_percen
2c90: 74 3a 20 50 65 72 63 65 6e 74 61 67 65 20 6f 66  t: Percentage of
2ca0: 20 62 74 72 65 65 20 65 6e 74 72 69 65 73 20 74   btree entries t
2cb0: 68 61 74 20 75 73 65 20 6f 76 65 72 66 6c 6f 77  hat use overflow
2cc0: 20 70 61 67 65 73 2e 0a 20 20 23 0a 20 20 73 65   pages..  #.  se
2cd0: 74 20 74 6f 74 61 6c 5f 70 61 67 65 73 20 5b 65  t total_pages [e
2ce0: 78 70 72 20 7b 24 6c 65 61 66 5f 70 61 67 65 73  xpr {$leaf_pages
2cf0: 2b 24 69 6e 74 5f 70 61 67 65 73 2b 24 6f 76 66  +$int_pages+$ovf
2d00: 6c 5f 70 61 67 65 73 7d 5d 0a 20 20 73 65 74 20  l_pages}].  set 
2d10: 74 6f 74 61 6c 5f 70 61 67 65 73 5f 70 65 72 63  total_pages_perc
2d20: 65 6e 74 20 5b 70 65 72 63 65 6e 74 20 24 74 6f  ent [percent $to
2d30: 74 61 6c 5f 70 61 67 65 73 20 24 66 69 6c 65 5f  tal_pages $file_
2d40: 70 67 63 6e 74 5d 0a 20 20 73 65 74 20 73 74 6f  pgcnt].  set sto
2d50: 72 61 67 65 20 5b 65 78 70 72 20 7b 24 74 6f 74  rage [expr {$tot
2d60: 61 6c 5f 70 61 67 65 73 2a 24 70 61 67 65 53 69  al_pages*$pageSi
2d70: 7a 65 7d 5d 0a 20 20 73 65 74 20 70 61 79 6c 6f  ze}].  set paylo
2d80: 61 64 5f 70 65 72 63 65 6e 74 20 5b 70 65 72 63  ad_percent [perc
2d90: 65 6e 74 20 24 70 61 79 6c 6f 61 64 20 24 73 74  ent $payload $st
2da0: 6f 72 61 67 65 20 7b 6f 66 20 73 74 6f 72 61 67  orage {of storag
2db0: 65 20 63 6f 6e 73 75 6d 65 64 7d 5d 0a 20 20 73  e consumed}].  s
2dc0: 65 74 20 74 6f 74 61 6c 5f 75 6e 75 73 65 64 20  et total_unused 
2dd0: 5b 65 78 70 72 20 7b 24 6f 76 66 6c 5f 75 6e 75  [expr {$ovfl_unu
2de0: 73 65 64 2b 24 69 6e 74 5f 75 6e 75 73 65 64 2b  sed+$int_unused+
2df0: 24 6c 65 61 66 5f 75 6e 75 73 65 64 7d 5d 0a 20  $leaf_unused}]. 
2e00: 20 73 65 74 20 61 76 67 5f 70 61 79 6c 6f 61 64   set avg_payload
2e10: 20 5b 64 69 76 69 64 65 20 24 70 61 79 6c 6f 61   [divide $payloa
2e20: 64 20 24 6e 6c 65 61 66 5d 0a 20 20 73 65 74 20  d $nleaf].  set 
2e30: 61 76 67 5f 75 6e 75 73 65 64 20 5b 64 69 76 69  avg_unused [divi
2e40: 64 65 20 24 74 6f 74 61 6c 5f 75 6e 75 73 65 64  de $total_unused
2e50: 20 24 6e 6c 65 61 66 5d 0a 20 20 69 66 20 7b 24   $nleaf].  if {$
2e60: 69 6e 74 5f 70 61 67 65 73 3e 30 7d 20 7b 0a 20  int_pages>0} {. 
2e70: 20 20 20 23 20 54 4f 44 4f 3a 20 49 73 20 74 68     # TODO: Is th
2e80: 69 73 20 66 6f 72 6d 75 6c 61 20 63 6f 72 72 65  is formula corre
2e90: 63 74 3f 0a 20 20 20 20 73 65 74 20 6e 54 61 62  ct?.    set nTab
2ea0: 20 5b 6d 65 6d 20 65 76 61 6c 20 22 0a 20 20 20   [mem eval ".   
2eb0: 20 20 20 53 45 4c 45 43 54 20 63 6f 75 6e 74 28     SELECT count(
2ec0: 2a 29 20 46 52 4f 4d 20 28 0a 20 20 20 20 20 20  *) FROM (.      
2ed0: 20 20 20 20 53 45 4c 45 43 54 20 44 49 53 54 49      SELECT DISTI
2ee0: 4e 43 54 20 74 62 6c 6e 61 6d 65 20 46 52 4f 4d  NCT tblname FROM
2ef0: 20 73 70 61 63 65 5f 75 73 65 64 20 57 48 45 52   space_used WHER
2f00: 45 20 24 77 68 65 72 65 20 41 4e 44 20 69 73 5f  E $where AND is_
2f10: 69 6e 64 65 78 3d 30 0a 20 20 20 20 20 20 29 0a  index=0.      ).
2f20: 20 20 20 20 22 5d 0a 20 20 20 20 73 65 74 20 61      "].    set a
2f30: 76 67 5f 66 61 6e 6f 75 74 20 5b 6d 65 6d 20 65  vg_fanout [mem e
2f40: 76 61 6c 20 22 0a 20 20 20 20 20 20 53 45 4c 45  val ".      SELE
2f50: 43 54 20 28 73 75 6d 28 6c 65 61 66 5f 70 61 67  CT (sum(leaf_pag
2f60: 65 73 2b 69 6e 74 5f 70 61 67 65 73 29 2d 24 6e  es+int_pages)-$n
2f70: 54 61 62 29 2f 73 75 6d 28 69 6e 74 5f 70 61 67  Tab)/sum(int_pag
2f80: 65 73 29 20 46 52 4f 4d 20 73 70 61 63 65 5f 75  es) FROM space_u
2f90: 73 65 64 0a 20 20 20 20 20 20 20 20 20 20 57 48  sed.          WH
2fa0: 45 52 45 20 24 77 68 65 72 65 0a 20 20 20 20 22  ERE $where.    "
2fb0: 5d 0a 20 20 20 20 73 65 74 20 61 76 67 5f 66 61  ].    set avg_fa
2fc0: 6e 6f 75 74 20 5b 66 6f 72 6d 61 74 20 25 2e 32  nout [format %.2
2fd0: 66 20 24 61 76 67 5f 66 61 6e 6f 75 74 5d 0a 20  f $avg_fanout]. 
2fe0: 20 7d 0a 20 20 73 65 74 20 6f 76 66 6c 5f 63 6e   }.  set ovfl_cn
2ff0: 74 5f 70 65 72 63 65 6e 74 20 5b 70 65 72 63 65  t_percent [perce
3000: 6e 74 20 24 6f 76 66 6c 5f 63 6e 74 20 24 6e 6c  nt $ovfl_cnt $nl
3010: 65 61 66 20 7b 6f 66 20 61 6c 6c 20 65 6e 74 72  eaf {of all entr
3020: 69 65 73 7d 5d 0a 0a 20 20 23 20 50 72 69 6e 74  ies}]..  # Print
3030: 20 6f 75 74 20 74 68 65 20 73 75 62 2d 72 65 70   out the sub-rep
3040: 6f 72 74 20 73 74 61 74 69 73 74 69 63 73 2e 0a  ort statistics..
3050: 20 20 23 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b    #.  statline {
3060: 50 65 72 63 65 6e 74 61 67 65 20 6f 66 20 74 6f  Percentage of to
3070: 74 61 6c 20 64 61 74 61 62 61 73 65 7d 20 24 74  tal database} $t
3080: 6f 74 61 6c 5f 70 61 67 65 73 5f 70 65 72 63 65  otal_pages_perce
3090: 6e 74 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 4e  nt.  statline {N
30a0: 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73  umber of entries
30b0: 7d 20 24 6e 6c 65 61 66 0a 20 20 73 74 61 74 6c  } $nleaf.  statl
30c0: 69 6e 65 20 7b 42 79 74 65 73 20 6f 66 20 73 74  ine {Bytes of st
30d0: 6f 72 61 67 65 20 63 6f 6e 73 75 6d 65 64 7d 20  orage consumed} 
30e0: 24 73 74 6f 72 61 67 65 0a 20 20 69 66 20 7b 24  $storage.  if {$
30f0: 63 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a 65 21  compressed_size!
3100: 3d 24 73 74 6f 72 61 67 65 7d 20 7b 0a 20 20 20  =$storage} {.   
3110: 20 73 65 74 20 63 6f 6d 70 72 65 73 73 65 64 5f   set compressed_
3120: 73 69 7a 65 20 5b 65 78 70 72 20 7b 24 63 6f 6d  size [expr {$com
3130: 70 72 65 73 73 65 64 5f 73 69 7a 65 2b 24 63 6f  pressed_size+$co
3140: 6d 70 72 65 73 73 4f 76 65 72 68 65 61 64 2a 24  mpressOverhead*$
3150: 74 6f 74 61 6c 5f 70 61 67 65 73 7d 5d 0a 20 20  total_pages}].  
3160: 20 20 73 65 74 20 70 63 74 20 5b 65 78 70 72 20    set pct [expr 
3170: 7b 24 63 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a  {$compressed_siz
3180: 65 2a 31 30 30 2e 30 2f 24 73 74 6f 72 61 67 65  e*100.0/$storage
3190: 7d 5d 0a 20 20 20 20 73 65 74 20 70 63 74 20 5b  }].    set pct [
31a0: 66 6f 72 6d 61 74 20 7b 25 35 2e 31 66 25 25 7d  format {%5.1f%%}
31b0: 20 24 70 63 74 5d 0a 20 20 20 20 73 74 61 74 6c   $pct].    statl
31c0: 69 6e 65 20 7b 42 79 74 65 73 20 75 73 65 64 20  ine {Bytes used 
31d0: 61 66 74 65 72 20 63 6f 6d 70 72 65 73 73 69 6f  after compressio
31e0: 6e 7d 20 24 63 6f 6d 70 72 65 73 73 65 64 5f 73  n} $compressed_s
31f0: 69 7a 65 20 24 70 63 74 0a 20 20 7d 0a 20 20 73  ize $pct.  }.  s
3200: 74 61 74 6c 69 6e 65 20 7b 42 79 74 65 73 20 6f  tatline {Bytes o
3210: 66 20 70 61 79 6c 6f 61 64 7d 20 24 70 61 79 6c  f payload} $payl
3220: 6f 61 64 20 24 70 61 79 6c 6f 61 64 5f 70 65 72  oad $payload_per
3230: 63 65 6e 74 0a 20 20 69 66 20 7b 24 63 6e 74 3d  cent.  if {$cnt=
3240: 3d 31 7d 20 7b 73 74 61 74 6c 69 6e 65 20 7b 42  =1} {statline {B
3250: 2d 74 72 65 65 20 64 65 70 74 68 7d 20 24 64 65  -tree depth} $de
3260: 70 74 68 7d 0a 20 20 73 74 61 74 6c 69 6e 65 20  pth}.  statline 
3270: 7b 41 76 65 72 61 67 65 20 70 61 79 6c 6f 61 64  {Average payload
3280: 20 70 65 72 20 65 6e 74 72 79 7d 20 24 61 76 67   per entry} $avg
3290: 5f 70 61 79 6c 6f 61 64 0a 20 20 73 74 61 74 6c  _payload.  statl
32a0: 69 6e 65 20 7b 41 76 65 72 61 67 65 20 75 6e 75  ine {Average unu
32b0: 73 65 64 20 62 79 74 65 73 20 70 65 72 20 65 6e  sed bytes per en
32c0: 74 72 79 7d 20 24 61 76 67 5f 75 6e 75 73 65 64  try} $avg_unused
32d0: 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69  .  if {[info exi
32e0: 73 74 73 20 61 76 67 5f 66 61 6e 6f 75 74 5d 7d  sts avg_fanout]}
32f0: 20 7b 0a 20 20 20 20 73 74 61 74 6c 69 6e 65 20   {.    statline 
3300: 7b 41 76 65 72 61 67 65 20 66 61 6e 6f 75 74 7d  {Average fanout}
3310: 20 24 61 76 67 5f 66 61 6e 6f 75 74 0a 20 20 7d   $avg_fanout.  }
3320: 0a 20 20 69 66 20 7b 24 73 68 6f 77 46 72 61 67  .  if {$showFrag
3330: 20 26 26 20 24 74 6f 74 61 6c 5f 70 61 67 65 73   && $total_pages
3340: 3e 31 7d 20 7b 0a 20 20 20 20 73 65 74 20 66 72  >1} {.    set fr
3350: 61 67 6d 65 6e 74 61 74 69 6f 6e 20 5b 70 65 72  agmentation [per
3360: 63 65 6e 74 20 24 67 61 70 5f 63 6e 74 20 5b 65  cent $gap_cnt [e
3370: 78 70 72 20 7b 24 74 6f 74 61 6c 5f 70 61 67 65  xpr {$total_page
3380: 73 2d 31 7d 5d 5d 0a 20 20 20 20 73 74 61 74 6c  s-1}]].    statl
3390: 69 6e 65 20 7b 4e 6f 6e 2d 73 65 71 75 65 6e 74  ine {Non-sequent
33a0: 69 61 6c 20 70 61 67 65 73 7d 20 24 67 61 70 5f  ial pages} $gap_
33b0: 63 6e 74 20 24 66 72 61 67 6d 65 6e 74 61 74 69  cnt $fragmentati
33c0: 6f 6e 0a 20 20 7d 0a 20 20 73 74 61 74 6c 69 6e  on.  }.  statlin
33d0: 65 20 7b 4d 61 78 69 6d 75 6d 20 70 61 79 6c 6f  e {Maximum paylo
33e0: 61 64 20 70 65 72 20 65 6e 74 72 79 7d 20 24 6d  ad per entry} $m
33f0: 78 5f 70 61 79 6c 6f 61 64 0a 20 20 73 74 61 74  x_payload.  stat
3400: 6c 69 6e 65 20 7b 45 6e 74 72 69 65 73 20 74 68  line {Entries th
3410: 61 74 20 75 73 65 20 6f 76 65 72 66 6c 6f 77 7d  at use overflow}
3420: 20 24 6f 76 66 6c 5f 63 6e 74 20 24 6f 76 66 6c   $ovfl_cnt $ovfl
3430: 5f 63 6e 74 5f 70 65 72 63 65 6e 74 0a 20 20 69  _cnt_percent.  i
3440: 66 20 7b 24 69 6e 74 5f 70 61 67 65 73 3e 30 7d  f {$int_pages>0}
3450: 20 7b 0a 20 20 20 20 73 74 61 74 6c 69 6e 65 20   {.    statline 
3460: 7b 49 6e 64 65 78 20 70 61 67 65 73 20 75 73 65  {Index pages use
3470: 64 7d 20 24 69 6e 74 5f 70 61 67 65 73 0a 20 20  d} $int_pages.  
3480: 7d 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 50 72  }.  statline {Pr
3490: 69 6d 61 72 79 20 70 61 67 65 73 20 75 73 65 64  imary pages used
34a0: 7d 20 24 6c 65 61 66 5f 70 61 67 65 73 0a 20 20  } $leaf_pages.  
34b0: 73 74 61 74 6c 69 6e 65 20 7b 4f 76 65 72 66 6c  statline {Overfl
34c0: 6f 77 20 70 61 67 65 73 20 75 73 65 64 7d 20 24  ow pages used} $
34d0: 6f 76 66 6c 5f 70 61 67 65 73 0a 20 20 73 74 61  ovfl_pages.  sta
34e0: 74 6c 69 6e 65 20 7b 54 6f 74 61 6c 20 70 61 67  tline {Total pag
34f0: 65 73 20 75 73 65 64 7d 20 24 74 6f 74 61 6c 5f  es used} $total_
3500: 70 61 67 65 73 0a 20 20 69 66 20 7b 24 69 6e 74  pages.  if {$int
3510: 5f 75 6e 75 73 65 64 3e 30 7d 20 7b 0a 20 20 20  _unused>0} {.   
3520: 20 73 65 74 20 69 6e 74 5f 75 6e 75 73 65 64 5f   set int_unused_
3530: 70 65 72 63 65 6e 74 20 5b 0a 20 20 20 20 20 20  percent [.      
3540: 20 20 20 70 65 72 63 65 6e 74 20 24 69 6e 74 5f     percent $int_
3550: 75 6e 75 73 65 64 20 5b 65 78 70 72 20 7b 24 69  unused [expr {$i
3560: 6e 74 5f 70 61 67 65 73 2a 24 70 61 67 65 53 69  nt_pages*$pageSi
3570: 7a 65 7d 5d 20 7b 6f 66 20 69 6e 64 65 78 20 73  ze}] {of index s
3580: 70 61 63 65 7d 5d 0a 20 20 20 20 73 74 61 74 6c  pace}].    statl
3590: 69 6e 65 20 22 55 6e 75 73 65 64 20 62 79 74 65  ine "Unused byte
35a0: 73 20 6f 6e 20 69 6e 64 65 78 20 70 61 67 65 73  s on index pages
35b0: 22 20 24 69 6e 74 5f 75 6e 75 73 65 64 20 24 69  " $int_unused $i
35c0: 6e 74 5f 75 6e 75 73 65 64 5f 70 65 72 63 65 6e  nt_unused_percen
35d0: 74 0a 20 20 7d 0a 20 20 73 74 61 74 6c 69 6e 65  t.  }.  statline
35e0: 20 22 55 6e 75 73 65 64 20 62 79 74 65 73 20 6f   "Unused bytes o
35f0: 6e 20 70 72 69 6d 61 72 79 20 70 61 67 65 73 22  n primary pages"
3600: 20 24 6c 65 61 66 5f 75 6e 75 73 65 64 20 5b 0a   $leaf_unused [.
3610: 20 20 20 20 20 70 65 72 63 65 6e 74 20 24 6c 65       percent $le
3620: 61 66 5f 75 6e 75 73 65 64 20 5b 65 78 70 72 20  af_unused [expr 
3630: 7b 24 6c 65 61 66 5f 70 61 67 65 73 2a 24 70 61  {$leaf_pages*$pa
3640: 67 65 53 69 7a 65 7d 5d 20 7b 6f 66 20 70 72 69  geSize}] {of pri
3650: 6d 61 72 79 20 73 70 61 63 65 7d 5d 0a 20 20 73  mary space}].  s
3660: 74 61 74 6c 69 6e 65 20 22 55 6e 75 73 65 64 20  tatline "Unused 
3670: 62 79 74 65 73 20 6f 6e 20 6f 76 65 72 66 6c 6f  bytes on overflo
3680: 77 20 70 61 67 65 73 22 20 24 6f 76 66 6c 5f 75  w pages" $ovfl_u
3690: 6e 75 73 65 64 20 5b 0a 20 20 20 20 20 70 65 72  nused [.     per
36a0: 63 65 6e 74 20 24 6f 76 66 6c 5f 75 6e 75 73 65  cent $ovfl_unuse
36b0: 64 20 5b 65 78 70 72 20 7b 24 6f 76 66 6c 5f 70  d [expr {$ovfl_p
36c0: 61 67 65 73 2a 24 70 61 67 65 53 69 7a 65 7d 5d  ages*$pageSize}]
36d0: 20 7b 6f 66 20 6f 76 65 72 66 6c 6f 77 20 73 70   {of overflow sp
36e0: 61 63 65 7d 5d 0a 20 20 73 74 61 74 6c 69 6e 65  ace}].  statline
36f0: 20 22 55 6e 75 73 65 64 20 62 79 74 65 73 20 6f   "Unused bytes o
3700: 6e 20 61 6c 6c 20 70 61 67 65 73 22 20 24 74 6f  n all pages" $to
3710: 74 61 6c 5f 75 6e 75 73 65 64 20 5b 0a 20 20 20  tal_unused [.   
3720: 20 20 20 20 20 20 20 20 20 20 20 20 70 65 72 63              perc
3730: 65 6e 74 20 24 74 6f 74 61 6c 5f 75 6e 75 73 65  ent $total_unuse
3740: 64 20 24 73 74 6f 72 61 67 65 20 7b 6f 66 20 61  d $storage {of a
3750: 6c 6c 20 73 70 61 63 65 7d 5d 0a 20 20 72 65 74  ll space}].  ret
3760: 75 72 6e 20 31 0a 7d 0a 0a 23 20 43 61 6c 63 75  urn 1.}..# Calcu
3770: 6c 61 74 65 20 74 68 65 20 6f 76 65 72 68 65 61  late the overhea
3780: 64 20 69 6e 20 70 61 67 65 73 20 63 61 75 73 65  d in pages cause
3790: 64 20 62 79 20 61 75 74 6f 2d 76 61 63 75 75 6d  d by auto-vacuum
37a0: 2e 20 0a 23 0a 23 20 54 68 69 73 20 70 72 6f 63  . .#.# This proc
37b0: 65 64 75 72 65 20 63 61 6c 63 75 6c 61 74 65 73  edure calculates
37c0: 20 61 6e 64 20 72 65 74 75 72 6e 73 20 74 68 65   and returns the
37d0: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
37e0: 20 75 73 65 64 20 62 79 20 74 68 65 20 0a 23 20   used by the .# 
37f0: 61 75 74 6f 2d 76 61 63 75 75 6d 20 27 70 6f 69  auto-vacuum 'poi
3800: 6e 74 65 72 2d 6d 61 70 27 2e 20 49 66 20 74 68  nter-map'. If th
3810: 65 20 64 61 74 61 62 61 73 65 20 64 6f 65 73 20  e database does 
3820: 6e 6f 74 20 73 75 70 70 6f 72 74 20 61 75 74 6f  not support auto
3830: 2d 76 61 63 75 75 6d 2c 0a 23 20 74 68 65 6e 20  -vacuum,.# then 
3840: 30 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 54  0 is returned. T
3850: 68 65 20 74 77 6f 20 61 72 67 75 6d 65 6e 74 73  he two arguments
3860: 20 61 72 65 20 74 68 65 20 73 69 7a 65 20 6f 66   are the size of
3870: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
3880: 6c 65 20 69 6e 0a 23 20 70 61 67 65 73 20 61 6e  le in.# pages an
3890: 64 20 74 68 65 20 70 61 67 65 20 73 69 7a 65 20  d the page size 
38a0: 75 73 65 64 20 62 79 20 74 68 65 20 64 61 74 61  used by the data
38b0: 62 61 73 65 20 28 69 6e 20 62 79 74 65 73 29 2e  base (in bytes).
38c0: 0a 70 72 6f 63 20 61 75 74 6f 76 61 63 75 75 6d  .proc autovacuum
38d0: 5f 6f 76 65 72 68 65 61 64 20 7b 66 69 6c 65 50  _overhead {fileP
38e0: 61 67 65 73 20 70 61 67 65 53 69 7a 65 7d 20 7b  ages pageSize} {
38f0: 0a 0a 20 20 23 20 53 65 74 20 24 61 75 74 6f 76  ..  # Set $autov
3900: 61 63 75 75 6d 20 74 6f 20 6e 6f 6e 2d 7a 65 72  acuum to non-zer
3910: 6f 20 66 6f 72 20 64 61 74 61 62 61 73 65 73 20  o for databases 
3920: 74 68 61 74 20 73 75 70 70 6f 72 74 20 61 75 74  that support aut
3930: 6f 2d 76 61 63 75 75 6d 2e 0a 20 20 73 65 74 20  o-vacuum..  set 
3940: 61 75 74 6f 76 61 63 75 75 6d 20 5b 64 62 20 6f  autovacuum [db o
3950: 6e 65 20 7b 50 52 41 47 4d 41 20 61 75 74 6f 5f  ne {PRAGMA auto_
3960: 76 61 63 75 75 6d 7d 5d 0a 0a 20 20 23 20 49 66  vacuum}]..  # If
3970: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 69 73   the database is
3980: 20 6e 6f 74 20 61 6e 20 61 75 74 6f 2d 76 61 63   not an auto-vac
3990: 75 75 6d 20 64 61 74 61 62 61 73 65 20 6f 72 20  uum database or 
39a0: 74 68 65 20 66 69 6c 65 20 63 6f 6e 73 69 73 74  the file consist
39b0: 73 0a 20 20 23 20 6f 66 20 6f 6e 65 20 70 61 67  s.  # of one pag
39c0: 65 20 6f 6e 6c 79 20 74 68 65 6e 20 74 68 65 72  e only then ther
39d0: 65 20 69 73 20 6e 6f 20 6f 76 65 72 68 65 61 64  e is no overhead
39e0: 20 66 6f 72 20 61 75 74 6f 2d 76 61 63 75 75 6d   for auto-vacuum
39f0: 2e 20 52 65 74 75 72 6e 20 7a 65 72 6f 2e 0a 20  . Return zero.. 
3a00: 20 69 66 20 7b 30 3d 3d 24 61 75 74 6f 76 61 63   if {0==$autovac
3a10: 75 75 6d 20 7c 7c 20 24 66 69 6c 65 50 61 67 65  uum || $filePage
3a20: 73 3d 3d 31 7d 20 7b 0a 20 20 20 20 72 65 74 75  s==1} {.    retu
3a30: 72 6e 20 30 0a 20 20 7d 0a 0a 20 20 23 20 54 68  rn 0.  }..  # Th
3a40: 65 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72  e number of entr
3a50: 69 65 73 20 6f 6e 20 65 61 63 68 20 70 6f 69 6e  ies on each poin
3a60: 74 65 72 20 6d 61 70 20 70 61 67 65 2e 20 54 68  ter map page. Th
3a70: 65 20 6c 61 79 6f 75 74 20 6f 66 20 74 68 65 0a  e layout of the.
3a80: 20 20 23 20 64 61 74 61 62 61 73 65 20 66 69 6c    # database fil
3a90: 65 20 69 73 20 6f 6e 65 20 70 6f 69 6e 74 65 72  e is one pointer
3aa0: 2d 6d 61 70 20 70 61 67 65 2c 20 66 6f 6c 6c 6f  -map page, follo
3ab0: 77 65 64 20 62 79 20 24 70 74 72 73 50 65 72 50  wed by $ptrsPerP
3ac0: 61 67 65 20 6f 74 68 65 72 0a 20 20 23 20 70 61  age other.  # pa
3ad0: 67 65 73 2c 20 66 6f 6c 6c 6f 77 65 64 20 62 79  ges, followed by
3ae0: 20 61 20 70 6f 69 6e 74 65 72 2d 6d 61 70 20 70   a pointer-map p
3af0: 61 67 65 20 65 74 63 2e 20 54 68 65 20 66 69 72  age etc. The fir
3b00: 73 74 20 70 6f 69 6e 74 65 72 2d 6d 61 70 20 70  st pointer-map p
3b10: 61 67 65 0a 20 20 23 20 69 73 20 74 68 65 20 73  age.  # is the s
3b20: 65 63 6f 6e 64 20 70 61 67 65 20 6f 66 20 74 68  econd page of th
3b30: 65 20 66 69 6c 65 20 6f 76 65 72 61 6c 6c 2e 0a  e file overall..
3b40: 20 20 73 65 74 20 70 74 72 73 50 65 72 50 61 67    set ptrsPerPag
3b50: 65 20 5b 65 78 70 72 20 64 6f 75 62 6c 65 28 24  e [expr double($
3b60: 70 61 67 65 53 69 7a 65 2f 35 29 5d 0a 0a 20 20  pageSize/5)]..  
3b70: 23 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d  # Return the num
3b80: 62 65 72 20 6f 66 20 70 6f 69 6e 74 65 72 20 6d  ber of pointer m
3b90: 61 70 20 70 61 67 65 73 20 69 6e 20 74 68 65 20  ap pages in the 
3ba0: 64 61 74 61 62 61 73 65 2e 0a 20 20 72 65 74 75  database..  retu
3bb0: 72 6e 20 5b 65 78 70 72 20 77 69 64 65 28 63 65  rn [expr wide(ce
3bc0: 69 6c 28 20 28 24 66 69 6c 65 50 61 67 65 73 2d  il( ($filePages-
3bd0: 31 2e 30 29 2f 28 24 70 74 72 73 50 65 72 50 61  1.0)/($ptrsPerPa
3be0: 67 65 2b 31 2e 30 29 20 29 29 5d 0a 7d 0a 0a 0a  ge+1.0) ))].}...
3bf0: 23 20 43 61 6c 63 75 6c 61 74 65 20 74 68 65 20  # Calculate the 
3c00: 73 75 6d 6d 61 72 79 20 73 74 61 74 69 73 74 69  summary statisti
3c10: 63 73 20 66 6f 72 20 74 68 65 20 64 61 74 61 62  cs for the datab
3c20: 61 73 65 20 61 6e 64 20 73 74 6f 72 65 20 74 68  ase and store th
3c30: 65 20 72 65 73 75 6c 74 73 0a 23 20 69 6e 20 54  e results.# in T
3c40: 43 4c 20 76 61 72 69 61 62 6c 65 73 2e 20 54 68  CL variables. Th
3c50: 65 79 20 61 72 65 20 6f 75 74 70 75 74 20 62 65  ey are output be
3c60: 6c 6f 77 2e 20 56 61 72 69 61 62 6c 65 73 20 61  low. Variables a
3c70: 72 65 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 23  re as follows:.#
3c80: 0a 23 20 70 61 67 65 53 69 7a 65 3a 20 20 20 20  .# pageSize:    
3c90: 20 20 53 69 7a 65 20 6f 66 20 65 61 63 68 20 70    Size of each p
3ca0: 61 67 65 20 69 6e 20 62 79 74 65 73 2e 0a 23 20  age in bytes..# 
3cb0: 66 69 6c 65 5f 62 79 74 65 73 3a 20 20 20 20 46  file_bytes:    F
3cc0: 69 6c 65 20 73 69 7a 65 20 69 6e 20 62 79 74 65  ile size in byte
3cd0: 73 2e 0a 23 20 66 69 6c 65 5f 70 67 63 6e 74 3a  s..# file_pgcnt:
3ce0: 20 20 20 20 4e 75 6d 62 65 72 20 6f 66 20 70 61      Number of pa
3cf0: 67 65 73 20 69 6e 20 74 68 65 20 66 69 6c 65 2e  ges in the file.
3d00: 0a 23 20 66 69 6c 65 5f 70 67 63 6e 74 32 3a 20  .# file_pgcnt2: 
3d10: 20 20 4e 75 6d 62 65 72 20 6f 66 20 70 61 67 65    Number of page
3d20: 73 20 69 6e 20 74 68 65 20 66 69 6c 65 20 28 63  s in the file (c
3d30: 61 6c 63 75 6c 61 74 65 64 29 2e 0a 23 20 61 76  alculated)..# av
3d40: 5f 70 67 63 6e 74 3a 20 20 20 20 20 20 50 61 67  _pgcnt:      Pag
3d50: 65 73 20 63 6f 6e 73 75 6d 65 64 20 62 79 20 74  es consumed by t
3d60: 68 65 20 61 75 74 6f 2d 76 61 63 75 75 6d 20 70  he auto-vacuum p
3d70: 6f 69 6e 74 65 72 2d 6d 61 70 2e 0a 23 20 61 76  ointer-map..# av
3d80: 5f 70 65 72 63 65 6e 74 3a 20 20 20 20 50 65 72  _percent:    Per
3d90: 63 65 6e 74 61 67 65 20 6f 66 20 74 68 65 20 66  centage of the f
3da0: 69 6c 65 20 63 6f 6e 73 75 6d 65 64 20 62 79 20  ile consumed by 
3db0: 61 75 74 6f 2d 76 61 63 75 75 6d 20 70 6f 69 6e  auto-vacuum poin
3dc0: 74 65 72 2d 6d 61 70 2e 0a 23 20 69 6e 75 73 65  ter-map..# inuse
3dd0: 5f 70 67 63 6e 74 3a 20 20 20 44 61 74 61 20 70  _pgcnt:   Data p
3de0: 61 67 65 73 20 69 6e 20 74 68 65 20 66 69 6c 65  ages in the file
3df0: 2e 0a 23 20 69 6e 75 73 65 5f 70 65 72 63 65 6e  ..# inuse_percen
3e00: 74 3a 20 50 65 72 63 65 6e 74 61 67 65 20 6f 66  t: Percentage of
3e10: 20 70 61 67 65 73 20 75 73 65 64 20 74 6f 20 73   pages used to s
3e20: 74 6f 72 65 20 64 61 74 61 2e 0a 23 20 66 72 65  tore data..# fre
3e30: 65 5f 70 67 63 6e 74 3a 20 20 20 20 46 72 65 65  e_pgcnt:    Free
3e40: 20 70 61 67 65 73 20 63 61 6c 63 75 6c 61 74 65   pages calculate
3e50: 64 20 61 73 20 28 3c 74 6f 74 61 6c 20 70 61 67  d as (<total pag
3e60: 65 73 3e 20 2d 20 3c 69 6e 2d 75 73 65 20 70 61  es> - <in-use pa
3e70: 67 65 73 3e 29 0a 23 20 66 72 65 65 5f 70 67 63  ges>).# free_pgc
3e80: 6e 74 32 3a 20 20 20 46 72 65 65 20 70 61 67 65  nt2:   Free page
3e90: 73 20 69 6e 20 74 68 65 20 66 69 6c 65 20 61 63  s in the file ac
3ea0: 63 6f 72 64 69 6e 67 20 74 6f 20 74 68 65 20 66  cording to the f
3eb0: 69 6c 65 20 68 65 61 64 65 72 2e 0a 23 20 66 72  ile header..# fr
3ec0: 65 65 5f 70 65 72 63 65 6e 74 3a 20 20 50 65 72  ee_percent:  Per
3ed0: 63 65 6e 74 61 67 65 20 6f 66 20 66 69 6c 65 20  centage of file 
3ee0: 63 6f 6e 73 75 6d 65 64 20 62 79 20 66 72 65 65  consumed by free
3ef0: 20 70 61 67 65 73 20 28 63 61 6c 63 75 6c 61 74   pages (calculat
3f00: 65 64 29 2e 0a 23 20 66 72 65 65 5f 70 65 72 63  ed)..# free_perc
3f10: 65 6e 74 32 3a 20 50 65 72 63 65 6e 74 61 67 65  ent2: Percentage
3f20: 20 6f 66 20 66 69 6c 65 20 63 6f 6e 73 75 6d 65   of file consume
3f30: 64 20 62 79 20 66 72 65 65 20 70 61 67 65 73 20  d by free pages 
3f40: 28 68 65 61 64 65 72 29 2e 0a 23 20 6e 74 61 62  (header)..# ntab
3f50: 6c 65 3a 20 20 20 20 20 20 20 20 4e 75 6d 62 65  le:        Numbe
3f60: 72 20 6f 66 20 74 61 62 6c 65 73 20 69 6e 20 74  r of tables in t
3f70: 68 65 20 64 62 2e 0a 23 20 6e 69 6e 64 65 78 3a  he db..# nindex:
3f80: 20 20 20 20 20 20 20 20 4e 75 6d 62 65 72 20 6f          Number o
3f90: 66 20 69 6e 64 69 63 65 73 20 69 6e 20 74 68 65  f indices in the
3fa0: 20 64 62 2e 0a 23 20 6e 61 75 74 6f 69 6e 64 65   db..# nautoinde
3fb0: 78 3a 20 20 20 20 4e 75 6d 62 65 72 20 6f 66 20  x:    Number of 
3fc0: 69 6e 64 69 63 65 73 20 63 72 65 61 74 65 64 20  indices created 
3fd0: 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 23  automatically..#
3fe0: 20 6e 6d 61 6e 69 6e 64 65 78 3a 20 20 20 20 20   nmanindex:     
3ff0: 4e 75 6d 62 65 72 20 6f 66 20 69 6e 64 69 63 65  Number of indice
4000: 73 20 63 72 65 61 74 65 64 20 6d 61 6e 75 61 6c  s created manual
4010: 6c 79 2e 0a 23 20 75 73 65 72 5f 70 61 79 6c 6f  ly..# user_paylo
4020: 61 64 3a 20 20 4e 75 6d 62 65 72 20 6f 66 20 62  ad:  Number of b
4030: 79 74 65 73 20 6f 66 20 70 61 79 6c 6f 61 64 20  ytes of payload 
4040: 69 6e 20 74 61 62 6c 65 20 62 74 72 65 65 73 20  in table btrees 
4050: 0a 23 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .#              
4060: 20 20 28 6e 6f 74 20 69 6e 63 6c 75 64 69 6e 67    (not including
4070: 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 29 0a   sqlite_master).
4080: 23 20 75 73 65 72 5f 70 65 72 63 65 6e 74 3a 20  # user_percent: 
4090: 20 24 75 73 65 72 5f 70 61 79 6c 6f 61 64 20 61   $user_payload a
40a0: 73 20 61 20 70 65 72 63 65 6e 74 61 67 65 20 6f  s a percentage o
40b0: 66 20 74 6f 74 61 6c 20 66 69 6c 65 20 73 69 7a  f total file siz
40c0: 65 2e 0a 0a 23 23 23 20 54 68 65 20 66 6f 6c 6c  e...### The foll
40d0: 6f 77 69 6e 67 2c 20 73 65 74 74 69 6e 67 20 24  owing, setting $
40e0: 66 69 6c 65 5f 62 79 74 65 73 20 62 61 73 65 64  file_bytes based
40f0: 20 6f 6e 20 74 68 65 20 61 63 74 75 61 6c 20 73   on the actual s
4100: 69 7a 65 20 6f 66 20 74 68 65 20 66 69 6c 65 0a  ize of the file.
4110: 23 23 23 20 6f 6e 20 64 69 73 6b 2c 20 63 61 75  ### on disk, cau
4120: 73 65 73 20 74 68 69 73 20 74 6f 6f 6c 20 74 6f  ses this tool to
4130: 20 63 68 6f 6b 65 20 6f 6e 20 7a 69 70 76 66 73   choke on zipvfs
4140: 20 64 61 74 61 62 61 73 65 73 2e 20 53 6f 20 73   databases. So s
4150: 65 74 20 69 74 20 62 61 73 65 64 0a 23 23 23 20  et it based.### 
4160: 6f 6e 20 74 68 65 20 72 65 74 75 72 6e 20 6f 66  on the return of
4170: 20 5b 50 52 41 47 4d 41 20 70 61 67 65 5f 63 6f   [PRAGMA page_co
4180: 75 6e 74 5d 20 69 6e 73 74 65 61 64 2e 0a 69 66  unt] instead..if
4190: 20 30 20 7b 0a 20 20 73 65 74 20 66 69 6c 65 5f   0 {.  set file_
41a0: 62 79 74 65 73 20 20 5b 66 69 6c 65 20 73 69 7a  bytes  [file siz
41b0: 65 20 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79  e $file_to_analy
41c0: 7a 65 5d 0a 20 20 73 65 74 20 66 69 6c 65 5f 70  ze].  set file_p
41d0: 67 63 6e 74 20 20 5b 65 78 70 72 20 7b 24 66 69  gcnt  [expr {$fi
41e0: 6c 65 5f 62 79 74 65 73 2f 24 70 61 67 65 53 69  le_bytes/$pageSi
41f0: 7a 65 7d 5d 0a 7d 0a 73 65 74 20 66 69 6c 65 5f  ze}].}.set file_
4200: 70 67 63 6e 74 20 20 5b 64 62 20 6f 6e 65 20 7b  pgcnt  [db one {
4210: 50 52 41 47 4d 41 20 70 61 67 65 5f 63 6f 75 6e  PRAGMA page_coun
4220: 74 7d 5d 0a 73 65 74 20 66 69 6c 65 5f 62 79 74  t}].set file_byt
4230: 65 73 20 20 5b 65 78 70 72 20 7b 24 66 69 6c 65  es  [expr {$file
4240: 5f 70 67 63 6e 74 20 2a 20 24 70 61 67 65 53 69  _pgcnt * $pageSi
4250: 7a 65 7d 5d 0a 0a 73 65 74 20 61 76 5f 70 67 63  ze}]..set av_pgc
4260: 6e 74 20 20 20 20 5b 61 75 74 6f 76 61 63 75 75  nt    [autovacuu
4270: 6d 5f 6f 76 65 72 68 65 61 64 20 24 66 69 6c 65  m_overhead $file
4280: 5f 70 67 63 6e 74 20 24 70 61 67 65 53 69 7a 65  _pgcnt $pageSize
4290: 5d 0a 73 65 74 20 61 76 5f 70 65 72 63 65 6e 74  ].set av_percent
42a0: 20 20 5b 70 65 72 63 65 6e 74 20 24 61 76 5f 70    [percent $av_p
42b0: 67 63 6e 74 20 24 66 69 6c 65 5f 70 67 63 6e 74  gcnt $file_pgcnt
42c0: 5d 0a 0a 73 65 74 20 73 71 6c 20 7b 53 45 4c 45  ]..set sql {SELE
42d0: 43 54 20 73 75 6d 28 6c 65 61 66 5f 70 61 67 65  CT sum(leaf_page
42e0: 73 2b 69 6e 74 5f 70 61 67 65 73 2b 6f 76 66 6c  s+int_pages+ovfl
42f0: 5f 70 61 67 65 73 29 20 46 52 4f 4d 20 73 70 61  _pages) FROM spa
4300: 63 65 5f 75 73 65 64 7d 0a 73 65 74 20 69 6e 75  ce_used}.set inu
4310: 73 65 5f 70 67 63 6e 74 20 20 20 5b 65 78 70 72  se_pgcnt   [expr
4320: 20 77 69 64 65 28 5b 6d 65 6d 20 65 76 61 6c 20   wide([mem eval 
4330: 24 73 71 6c 5d 29 5d 0a 73 65 74 20 69 6e 75 73  $sql])].set inus
4340: 65 5f 70 65 72 63 65 6e 74 20 5b 70 65 72 63 65  e_percent [perce
4350: 6e 74 20 24 69 6e 75 73 65 5f 70 67 63 6e 74 20  nt $inuse_pgcnt 
4360: 24 66 69 6c 65 5f 70 67 63 6e 74 5d 0a 0a 73 65  $file_pgcnt]..se
4370: 74 20 66 72 65 65 5f 70 67 63 6e 74 20 20 20 20  t free_pgcnt    
4380: 5b 65 78 70 72 20 7b 24 66 69 6c 65 5f 70 67 63  [expr {$file_pgc
4390: 6e 74 2d 24 69 6e 75 73 65 5f 70 67 63 6e 74 2d  nt-$inuse_pgcnt-
43a0: 24 61 76 5f 70 67 63 6e 74 7d 5d 0a 73 65 74 20  $av_pgcnt}].set 
43b0: 66 72 65 65 5f 70 65 72 63 65 6e 74 20 20 5b 70  free_percent  [p
43c0: 65 72 63 65 6e 74 20 24 66 72 65 65 5f 70 67 63  ercent $free_pgc
43d0: 6e 74 20 24 66 69 6c 65 5f 70 67 63 6e 74 5d 0a  nt $file_pgcnt].
43e0: 73 65 74 20 66 72 65 65 5f 70 67 63 6e 74 32 20  set free_pgcnt2 
43f0: 20 20 5b 64 62 20 6f 6e 65 20 7b 50 52 41 47 4d    [db one {PRAGM
4400: 41 20 66 72 65 65 6c 69 73 74 5f 63 6f 75 6e 74  A freelist_count
4410: 7d 5d 0a 73 65 74 20 66 72 65 65 5f 70 65 72 63  }].set free_perc
4420: 65 6e 74 32 20 5b 70 65 72 63 65 6e 74 20 24 66  ent2 [percent $f
4430: 72 65 65 5f 70 67 63 6e 74 32 20 24 66 69 6c 65  ree_pgcnt2 $file
4440: 5f 70 67 63 6e 74 5d 0a 0a 73 65 74 20 66 69 6c  _pgcnt]..set fil
4450: 65 5f 70 67 63 6e 74 32 20 5b 65 78 70 72 20 7b  e_pgcnt2 [expr {
4460: 24 69 6e 75 73 65 5f 70 67 63 6e 74 2b 24 66 72  $inuse_pgcnt+$fr
4470: 65 65 5f 70 67 63 6e 74 32 2b 24 61 76 5f 70 67  ee_pgcnt2+$av_pg
4480: 63 6e 74 7d 5d 0a 0a 73 65 74 20 6e 74 61 62 6c  cnt}]..set ntabl
4490: 65 20 5b 64 62 20 65 76 61 6c 20 7b 53 45 4c 45  e [db eval {SELE
44a0: 43 54 20 63 6f 75 6e 74 28 2a 29 2b 31 20 46 52  CT count(*)+1 FR
44b0: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
44c0: 20 57 48 45 52 45 20 74 79 70 65 3d 27 74 61 62   WHERE type='tab
44d0: 6c 65 27 7d 5d 0a 73 65 74 20 6e 69 6e 64 65 78  le'}].set nindex
44e0: 20 5b 64 62 20 65 76 61 6c 20 7b 53 45 4c 45 43   [db eval {SELEC
44f0: 54 20 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20  T count(*) FROM 
4500: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48  sqlite_master WH
4510: 45 52 45 20 74 79 70 65 3d 27 69 6e 64 65 78 27  ERE type='index'
4520: 7d 5d 0a 73 65 74 20 73 71 6c 20 7b 53 45 4c 45  }].set sql {SELE
4530: 43 54 20 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d  CT count(*) FROM
4540: 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57   sqlite_master W
4550: 48 45 52 45 20 6e 61 6d 65 20 4c 49 4b 45 20 27  HERE name LIKE '
4560: 73 71 6c 69 74 65 5f 61 75 74 6f 69 6e 64 65 78  sqlite_autoindex
4570: 25 27 7d 0a 73 65 74 20 6e 61 75 74 6f 69 6e 64  %'}.set nautoind
4580: 65 78 20 5b 64 62 20 65 76 61 6c 20 24 73 71 6c  ex [db eval $sql
4590: 5d 0a 73 65 74 20 6e 6d 61 6e 69 6e 64 65 78 20  ].set nmanindex 
45a0: 5b 65 78 70 72 20 7b 24 6e 69 6e 64 65 78 2d 24  [expr {$nindex-$
45b0: 6e 61 75 74 6f 69 6e 64 65 78 7d 5d 0a 0a 23 20  nautoindex}]..# 
45c0: 73 65 74 20 74 6f 74 61 6c 5f 70 61 79 6c 6f 61  set total_payloa
45d0: 64 20 5b 6d 65 6d 20 65 76 61 6c 20 22 53 45 4c  d [mem eval "SEL
45e0: 45 43 54 20 73 75 6d 28 70 61 79 6c 6f 61 64 29  ECT sum(payload)
45f0: 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73 65 64   FROM space_used
4600: 22 5d 0a 73 65 74 20 75 73 65 72 5f 70 61 79 6c  "].set user_payl
4610: 6f 61 64 20 5b 6d 65 6d 20 6f 6e 65 20 7b 53 45  oad [mem one {SE
4620: 4c 45 43 54 20 69 6e 74 28 73 75 6d 28 70 61 79  LECT int(sum(pay
4630: 6c 6f 61 64 29 29 20 46 52 4f 4d 20 73 70 61 63  load)) FROM spac
4640: 65 5f 75 73 65 64 0a 20 20 20 20 20 57 48 45 52  e_used.     WHER
4650: 45 20 4e 4f 54 20 69 73 5f 69 6e 64 65 78 20 41  E NOT is_index A
4660: 4e 44 20 6e 61 6d 65 20 4e 4f 54 20 4c 49 4b 45  ND name NOT LIKE
4670: 20 27 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 27   'sqlite_master'
4680: 7d 5d 0a 73 65 74 20 75 73 65 72 5f 70 65 72 63  }].set user_perc
4690: 65 6e 74 20 5b 70 65 72 63 65 6e 74 20 24 75 73  ent [percent $us
46a0: 65 72 5f 70 61 79 6c 6f 61 64 20 24 66 69 6c 65  er_payload $file
46b0: 5f 62 79 74 65 73 5d 0a 0a 23 20 4f 75 74 70 75  _bytes]..# Outpu
46c0: 74 20 74 68 65 20 73 75 6d 6d 61 72 79 20 73 74  t the summary st
46d0: 61 74 69 73 74 69 63 73 20 63 61 6c 63 75 6c 61  atistics calcula
46e0: 74 65 64 20 61 62 6f 76 65 2e 0a 23 0a 70 75 74  ted above..#.put
46f0: 73 20 22 2f 2a 2a 20 44 69 73 6b 2d 53 70 61 63  s "/** Disk-Spac
4700: 65 20 55 74 69 6c 69 7a 61 74 69 6f 6e 20 52 65  e Utilization Re
4710: 70 6f 72 74 20 46 6f 72 20 24 72 6f 6f 74 5f 66  port For $root_f
4720: 69 6c 65 6e 61 6d 65 22 0a 70 75 74 73 20 22 22  ilename".puts ""
4730: 0a 73 74 61 74 6c 69 6e 65 20 7b 50 61 67 65 20  .statline {Page 
4740: 73 69 7a 65 20 69 6e 20 62 79 74 65 73 7d 20 24  size in bytes} $
4750: 70 61 67 65 53 69 7a 65 0a 73 74 61 74 6c 69 6e  pageSize.statlin
4760: 65 20 7b 50 61 67 65 73 20 69 6e 20 74 68 65 20  e {Pages in the 
4770: 77 68 6f 6c 65 20 66 69 6c 65 20 28 6d 65 61 73  whole file (meas
4780: 75 72 65 64 29 7d 20 24 66 69 6c 65 5f 70 67 63  ured)} $file_pgc
4790: 6e 74 0a 73 74 61 74 6c 69 6e 65 20 7b 50 61 67  nt.statline {Pag
47a0: 65 73 20 69 6e 20 74 68 65 20 77 68 6f 6c 65 20  es in the whole 
47b0: 66 69 6c 65 20 28 63 61 6c 63 75 6c 61 74 65 64  file (calculated
47c0: 29 7d 20 24 66 69 6c 65 5f 70 67 63 6e 74 32 0a  )} $file_pgcnt2.
47d0: 73 74 61 74 6c 69 6e 65 20 7b 50 61 67 65 73 20  statline {Pages 
47e0: 74 68 61 74 20 73 74 6f 72 65 20 64 61 74 61 7d  that store data}
47f0: 20 24 69 6e 75 73 65 5f 70 67 63 6e 74 20 24 69   $inuse_pgcnt $i
4800: 6e 75 73 65 5f 70 65 72 63 65 6e 74 0a 73 74 61  nuse_percent.sta
4810: 74 6c 69 6e 65 20 7b 50 61 67 65 73 20 6f 6e 20  tline {Pages on 
4820: 74 68 65 20 66 72 65 65 6c 69 73 74 20 28 70 65  the freelist (pe
4830: 72 20 68 65 61 64 65 72 29 7d 20 24 66 72 65 65  r header)} $free
4840: 5f 70 67 63 6e 74 32 20 24 66 72 65 65 5f 70 65  _pgcnt2 $free_pe
4850: 72 63 65 6e 74 32 0a 73 74 61 74 6c 69 6e 65 20  rcent2.statline 
4860: 7b 50 61 67 65 73 20 6f 6e 20 74 68 65 20 66 72  {Pages on the fr
4870: 65 65 6c 69 73 74 20 28 63 61 6c 63 75 6c 61 74  eelist (calculat
4880: 65 64 29 7d 20 24 66 72 65 65 5f 70 67 63 6e 74  ed)} $free_pgcnt
4890: 20 24 66 72 65 65 5f 70 65 72 63 65 6e 74 0a 73   $free_percent.s
48a0: 74 61 74 6c 69 6e 65 20 7b 50 61 67 65 73 20 6f  tatline {Pages o
48b0: 66 20 61 75 74 6f 2d 76 61 63 75 75 6d 20 6f 76  f auto-vacuum ov
48c0: 65 72 68 65 61 64 7d 20 24 61 76 5f 70 67 63 6e  erhead} $av_pgcn
48d0: 74 20 24 61 76 5f 70 65 72 63 65 6e 74 0a 73 74  t $av_percent.st
48e0: 61 74 6c 69 6e 65 20 7b 4e 75 6d 62 65 72 20 6f  atline {Number o
48f0: 66 20 74 61 62 6c 65 73 20 69 6e 20 74 68 65 20  f tables in the 
4900: 64 61 74 61 62 61 73 65 7d 20 24 6e 74 61 62 6c  database} $ntabl
4910: 65 0a 73 74 61 74 6c 69 6e 65 20 7b 4e 75 6d 62  e.statline {Numb
4920: 65 72 20 6f 66 20 69 6e 64 69 63 65 73 7d 20 24  er of indices} $
4930: 6e 69 6e 64 65 78 0a 73 74 61 74 6c 69 6e 65 20  nindex.statline 
4940: 7b 4e 75 6d 62 65 72 20 6f 66 20 64 65 66 69 6e  {Number of defin
4950: 65 64 20 69 6e 64 69 63 65 73 7d 20 24 6e 6d 61  ed indices} $nma
4960: 6e 69 6e 64 65 78 0a 73 74 61 74 6c 69 6e 65 20  nindex.statline 
4970: 7b 4e 75 6d 62 65 72 20 6f 66 20 69 6d 70 6c 69  {Number of impli
4980: 65 64 20 69 6e 64 69 63 65 73 7d 20 24 6e 61 75  ed indices} $nau
4990: 74 6f 69 6e 64 65 78 0a 69 66 20 7b 24 69 73 43  toindex.if {$isC
49a0: 6f 6d 70 72 65 73 73 65 64 7d 20 7b 0a 20 20 73  ompressed} {.  s
49b0: 74 61 74 6c 69 6e 65 20 7b 53 69 7a 65 20 6f 66  tatline {Size of
49c0: 20 75 6e 63 6f 6d 70 72 65 73 73 65 64 20 63 6f   uncompressed co
49d0: 6e 74 65 6e 74 20 69 6e 20 62 79 74 65 73 7d 20  ntent in bytes} 
49e0: 24 66 69 6c 65 5f 62 79 74 65 73 0a 20 20 73 65  $file_bytes.  se
49f0: 74 20 65 66 66 69 63 69 65 6e 63 79 20 5b 70 65  t efficiency [pe
4a00: 72 63 65 6e 74 20 24 74 72 75 65 5f 66 69 6c 65  rcent $true_file
4a10: 5f 73 69 7a 65 20 24 66 69 6c 65 5f 62 79 74 65  _size $file_byte
4a20: 73 5d 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 53  s].  statline {S
4a30: 69 7a 65 20 6f 66 20 63 6f 6d 70 72 65 73 73 65  ize of compresse
4a40: 64 20 66 69 6c 65 20 6f 6e 20 64 69 73 6b 7d 20  d file on disk} 
4a50: 24 74 72 75 65 5f 66 69 6c 65 5f 73 69 7a 65 20  $true_file_size 
4a60: 24 65 66 66 69 63 69 65 6e 63 79 0a 7d 20 65 6c  $efficiency.} el
4a70: 73 65 20 7b 0a 20 20 73 74 61 74 6c 69 6e 65 20  se {.  statline 
4a80: 7b 53 69 7a 65 20 6f 66 20 74 68 65 20 66 69 6c  {Size of the fil
4a90: 65 20 69 6e 20 62 79 74 65 73 7d 20 24 66 69 6c  e in bytes} $fil
4aa0: 65 5f 62 79 74 65 73 0a 7d 0a 73 74 61 74 6c 69  e_bytes.}.statli
4ab0: 6e 65 20 7b 42 79 74 65 73 20 6f 66 20 75 73 65  ne {Bytes of use
4ac0: 72 20 70 61 79 6c 6f 61 64 20 73 74 6f 72 65 64  r payload stored
4ad0: 7d 20 24 75 73 65 72 5f 70 61 79 6c 6f 61 64 20  } $user_payload 
4ae0: 24 75 73 65 72 5f 70 65 72 63 65 6e 74 0a 0a 23  $user_percent..#
4af0: 20 4f 75 74 70 75 74 20 74 61 62 6c 65 20 72 61   Output table ra
4b00: 6e 6b 69 6e 67 73 0a 23 0a 70 75 74 73 20 22 22  nkings.#.puts ""
4b10: 0a 74 69 74 6c 65 6c 69 6e 65 20 22 50 61 67 65  .titleline "Page
4b20: 20 63 6f 75 6e 74 73 20 66 6f 72 20 61 6c 6c 20   counts for all 
4b30: 74 61 62 6c 65 73 20 77 69 74 68 20 74 68 65 69  tables with thei
4b40: 72 20 69 6e 64 69 63 65 73 22 0a 70 75 74 73 20  r indices".puts 
4b50: 22 22 0a 6d 65 6d 20 65 76 61 6c 20 7b 53 45 4c  "".mem eval {SEL
4b60: 45 43 54 20 74 62 6c 6e 61 6d 65 2c 20 63 6f 75  ECT tblname, cou
4b70: 6e 74 28 2a 29 20 41 53 20 63 6e 74 2c 20 0a 20  nt(*) AS cnt, . 
4b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74               int
4b90: 28 73 75 6d 28 69 6e 74 5f 70 61 67 65 73 2b 6c  (sum(int_pages+l
4ba0: 65 61 66 5f 70 61 67 65 73 2b 6f 76 66 6c 5f 70  eaf_pages+ovfl_p
4bb0: 61 67 65 73 29 29 20 41 53 20 73 69 7a 65 0a 20  ages)) AS size. 
4bc0: 20 20 20 20 20 20 20 20 20 46 52 4f 4d 20 73 70           FROM sp
4bd0: 61 63 65 5f 75 73 65 64 20 47 52 4f 55 50 20 42  ace_used GROUP B
4be0: 59 20 74 62 6c 6e 61 6d 65 20 4f 52 44 45 52 20  Y tblname ORDER 
4bf0: 42 59 20 73 69 7a 65 2b 30 20 44 45 53 43 2c 20  BY size+0 DESC, 
4c00: 74 62 6c 6e 61 6d 65 7d 20 7b 7d 20 7b 0a 20 20  tblname} {} {.  
4c10: 73 74 61 74 6c 69 6e 65 20 5b 73 74 72 69 6e 67  statline [string
4c20: 20 74 6f 75 70 70 65 72 20 24 74 62 6c 6e 61 6d   toupper $tblnam
4c30: 65 5d 20 24 73 69 7a 65 20 5b 70 65 72 63 65 6e  e] $size [percen
4c40: 74 20 24 73 69 7a 65 20 24 66 69 6c 65 5f 70 67  t $size $file_pg
4c50: 63 6e 74 5d 0a 7d 0a 70 75 74 73 20 22 22 0a 74  cnt].}.puts "".t
4c60: 69 74 6c 65 6c 69 6e 65 20 22 50 61 67 65 20 63  itleline "Page c
4c70: 6f 75 6e 74 73 20 66 6f 72 20 61 6c 6c 20 74 61  ounts for all ta
4c80: 62 6c 65 73 20 61 6e 64 20 69 6e 64 69 63 65 73  bles and indices
4c90: 20 73 65 70 61 72 61 74 65 6c 79 22 0a 70 75 74   separately".put
4ca0: 73 20 22 22 0a 6d 65 6d 20 65 76 61 6c 20 7b 0a  s "".mem eval {.
4cb0: 20 20 53 45 4c 45 43 54 0a 20 20 20 20 20 20 20    SELECT.       
4cc0: 75 70 70 65 72 28 6e 61 6d 65 29 20 41 53 20 6e  upper(name) AS n
4cd0: 6d 2c 0a 20 20 20 20 20 20 20 69 6e 74 28 69 6e  m,.       int(in
4ce0: 74 5f 70 61 67 65 73 2b 6c 65 61 66 5f 70 61 67  t_pages+leaf_pag
4cf0: 65 73 2b 6f 76 66 6c 5f 70 61 67 65 73 29 20 41  es+ovfl_pages) A
4d00: 53 20 73 69 7a 65 0a 20 20 20 20 46 52 4f 4d 20  S size.    FROM 
4d10: 73 70 61 63 65 5f 75 73 65 64 0a 20 20 20 4f 52  space_used.   OR
4d20: 44 45 52 20 42 59 20 73 69 7a 65 2b 30 20 44 45  DER BY size+0 DE
4d30: 53 43 2c 20 6e 61 6d 65 7d 20 7b 7d 20 7b 0a 20  SC, name} {} {. 
4d40: 20 73 74 61 74 6c 69 6e 65 20 24 6e 6d 20 24 73   statline $nm $s
4d50: 69 7a 65 20 5b 70 65 72 63 65 6e 74 20 24 73 69  ize [percent $si
4d60: 7a 65 20 24 66 69 6c 65 5f 70 67 63 6e 74 5d 0a  ze $file_pgcnt].
4d70: 7d 0a 69 66 20 7b 24 69 73 43 6f 6d 70 72 65 73  }.if {$isCompres
4d80: 73 65 64 7d 20 7b 0a 20 20 70 75 74 73 20 22 22  sed} {.  puts ""
4d90: 0a 20 20 74 69 74 6c 65 6c 69 6e 65 20 22 42 79  .  titleline "By
4da0: 74 65 73 20 6f 66 20 64 69 73 6b 20 73 70 61 63  tes of disk spac
4db0: 65 20 75 73 65 64 20 61 66 74 65 72 20 63 6f 6d  e used after com
4dc0: 70 72 65 73 73 69 6f 6e 22 0a 20 20 70 75 74 73  pression".  puts
4dd0: 20 22 22 0a 20 20 73 65 74 20 63 73 75 6d 20 30   "".  set csum 0
4de0: 0a 20 20 6d 65 6d 20 65 76 61 6c 20 7b 53 45 4c  .  mem eval {SEL
4df0: 45 43 54 20 74 62 6c 6e 61 6d 65 2c 0a 20 20 20  ECT tblname,.   
4e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
4e10: 6e 74 28 73 75 6d 28 63 6f 6d 70 72 65 73 73 65  nt(sum(compresse
4e20: 64 5f 73 69 7a 65 29 29 20 2b 0a 20 20 20 20 20  d_size)) +.     
4e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4e40: 20 20 20 20 24 63 6f 6d 70 72 65 73 73 4f 76 65      $compressOve
4e50: 72 68 65 61 64 2a 73 75 6d 28 69 6e 74 5f 70 61  rhead*sum(int_pa
4e60: 67 65 73 2b 6c 65 61 66 5f 70 61 67 65 73 2b 6f  ges+leaf_pages+o
4e70: 76 66 6c 5f 70 61 67 65 73 29 0a 20 20 20 20 20  vfl_pages).     
4e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4e90: 20 20 20 41 53 20 63 73 69 7a 65 0a 20 20 20 20     AS csize.    
4ea0: 20 20 20 20 20 20 46 52 4f 4d 20 73 70 61 63 65        FROM space
4eb0: 5f 75 73 65 64 20 47 52 4f 55 50 20 42 59 20 74  _used GROUP BY t
4ec0: 62 6c 6e 61 6d 65 20 4f 52 44 45 52 20 42 59 20  blname ORDER BY 
4ed0: 63 73 69 7a 65 2b 30 20 44 45 53 43 2c 20 74 62  csize+0 DESC, tb
4ee0: 6c 6e 61 6d 65 7d 20 7b 7d 20 7b 0a 20 20 20 20  lname} {} {.    
4ef0: 69 6e 63 72 20 63 73 75 6d 20 24 63 73 69 7a 65  incr csum $csize
4f00: 0a 20 20 20 20 73 74 61 74 6c 69 6e 65 20 5b 73  .    statline [s
4f10: 74 72 69 6e 67 20 74 6f 75 70 70 65 72 20 24 74  tring toupper $t
4f20: 62 6c 6e 61 6d 65 5d 20 24 63 73 69 7a 65 20 5b  blname] $csize [
4f30: 70 65 72 63 65 6e 74 20 24 63 73 69 7a 65 20 24  percent $csize $
4f40: 74 72 75 65 5f 66 69 6c 65 5f 73 69 7a 65 5d 0a  true_file_size].
4f50: 20 20 7d 0a 20 20 73 65 74 20 6f 76 65 72 68 65    }.  set overhe
4f60: 61 64 20 5b 65 78 70 72 20 7b 24 74 72 75 65 5f  ad [expr {$true_
4f70: 66 69 6c 65 5f 73 69 7a 65 20 2d 20 24 63 73 75  file_size - $csu
4f80: 6d 7d 5d 0a 20 20 69 66 20 7b 24 6f 76 65 72 68  m}].  if {$overh
4f90: 65 61 64 3e 30 7d 20 7b 0a 20 20 20 20 73 74 61  ead>0} {.    sta
4fa0: 74 6c 69 6e 65 20 7b 48 65 61 64 65 72 20 61 6e  tline {Header an
4fb0: 64 20 66 72 65 65 20 73 70 61 63 65 7d 20 24 6f  d free space} $o
4fc0: 76 65 72 68 65 61 64 20 5b 70 65 72 63 65 6e 74  verhead [percent
4fd0: 20 24 6f 76 65 72 68 65 61 64 20 24 74 72 75 65   $overhead $true
4fe0: 5f 66 69 6c 65 5f 73 69 7a 65 5d 0a 20 20 7d 0a  _file_size].  }.
4ff0: 7d 0a 0a 23 20 4f 75 74 70 75 74 20 73 75 62 72  }..# Output subr
5000: 65 70 6f 72 74 73 0a 23 0a 69 66 20 7b 24 6e 69  eports.#.if {$ni
5010: 6e 64 65 78 3e 30 7d 20 7b 0a 20 20 73 75 62 72  ndex>0} {.  subr
5020: 65 70 6f 72 74 20 7b 41 6c 6c 20 74 61 62 6c 65  eport {All table
5030: 73 20 61 6e 64 20 69 6e 64 69 63 65 73 7d 20 31  s and indices} 1
5040: 20 30 0a 7d 0a 73 75 62 72 65 70 6f 72 74 20 7b   0.}.subreport {
5050: 41 6c 6c 20 74 61 62 6c 65 73 7d 20 7b 4e 4f 54  All tables} {NOT
5060: 20 69 73 5f 69 6e 64 65 78 7d 20 30 0a 69 66 20   is_index} 0.if 
5070: 7b 24 6e 69 6e 64 65 78 3e 30 7d 20 7b 0a 20 20  {$nindex>0} {.  
5080: 73 75 62 72 65 70 6f 72 74 20 7b 41 6c 6c 20 69  subreport {All i
5090: 6e 64 69 63 65 73 7d 20 7b 69 73 5f 69 6e 64 65  ndices} {is_inde
50a0: 78 7d 20 30 0a 7d 0a 66 6f 72 65 61 63 68 20 74  x} 0.}.foreach t
50b0: 62 6c 20 5b 6d 65 6d 20 65 76 61 6c 20 7b 53 45  bl [mem eval {SE
50c0: 4c 45 43 54 20 44 49 53 54 49 4e 43 54 20 74 62  LECT DISTINCT tb
50d0: 6c 6e 61 6d 65 20 6e 61 6d 65 20 46 52 4f 4d 20  lname name FROM 
50e0: 73 70 61 63 65 5f 75 73 65 64 0a 20 20 20 20 20  space_used.     
50f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5100: 20 20 4f 52 44 45 52 20 42 59 20 6e 61 6d 65 7d    ORDER BY name}
5110: 5d 20 7b 0a 20 20 73 65 74 20 71 6e 20 5b 71 75  ] {.  set qn [qu
5120: 6f 74 65 20 24 74 62 6c 5d 0a 20 20 73 65 74 20  ote $tbl].  set 
5130: 6e 61 6d 65 20 5b 73 74 72 69 6e 67 20 74 6f 75  name [string tou
5140: 70 70 65 72 20 24 74 62 6c 5d 0a 20 20 73 65 74  pper $tbl].  set
5150: 20 6e 20 5b 6d 65 6d 20 65 76 61 6c 20 7b 53 45   n [mem eval {SE
5160: 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 20 46 52  LECT count(*) FR
5170: 4f 4d 20 73 70 61 63 65 5f 75 73 65 64 20 57 48  OM space_used WH
5180: 45 52 45 20 74 62 6c 6e 61 6d 65 3d 24 74 62 6c  ERE tblname=$tbl
5190: 7d 5d 0a 20 20 69 66 20 7b 24 6e 3e 31 7d 20 7b  }].  if {$n>1} {
51a0: 0a 20 20 20 20 73 65 74 20 69 64 78 6c 69 73 74  .    set idxlist
51b0: 20 5b 6d 65 6d 20 65 76 61 6c 20 22 53 45 4c 45   [mem eval "SELE
51c0: 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73 70 61  CT name FROM spa
51d0: 63 65 5f 75 73 65 64 0a 20 20 20 20 20 20 20 20  ce_used.        
51e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
51f0: 20 20 20 20 57 48 45 52 45 20 74 62 6c 6e 61 6d      WHERE tblnam
5200: 65 3d 27 24 71 6e 27 20 41 4e 44 20 69 73 5f 69  e='$qn' AND is_i
5210: 6e 64 65 78 0a 20 20 20 20 20 20 20 20 20 20 20  ndex.           
5220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5230: 20 4f 52 44 45 52 20 42 59 20 31 22 5d 0a 20 20   ORDER BY 1"].  
5240: 20 20 73 75 62 72 65 70 6f 72 74 20 22 54 61 62    subreport "Tab
5250: 6c 65 20 24 6e 61 6d 65 20 61 6e 64 20 61 6c 6c  le $name and all
5260: 20 69 74 73 20 69 6e 64 69 63 65 73 22 20 22 74   its indices" "t
5270: 62 6c 6e 61 6d 65 3d 27 24 71 6e 27 22 20 30 0a  blname='$qn'" 0.
5280: 20 20 20 20 73 75 62 72 65 70 6f 72 74 20 22 54      subreport "T
5290: 61 62 6c 65 20 24 6e 61 6d 65 20 77 2f 6f 20 61  able $name w/o a
52a0: 6e 79 20 69 6e 64 69 63 65 73 22 20 22 6e 61 6d  ny indices" "nam
52b0: 65 3d 27 24 71 6e 27 22 20 31 0a 20 20 20 20 69  e='$qn'" 1.    i
52c0: 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 69 64 78  f {[llength $idx
52d0: 6c 69 73 74 5d 3e 31 7d 20 7b 0a 20 20 20 20 20  list]>1} {.     
52e0: 20 73 75 62 72 65 70 6f 72 74 20 22 49 6e 64 69   subreport "Indi
52f0: 63 65 73 20 6f 66 20 74 61 62 6c 65 20 24 6e 61  ces of table $na
5300: 6d 65 22 20 22 74 62 6c 6e 61 6d 65 3d 27 24 71  me" "tblname='$q
5310: 6e 27 20 41 4e 44 20 69 73 5f 69 6e 64 65 78 22  n' AND is_index"
5320: 20 30 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72   0.    }.    for
5330: 65 61 63 68 20 69 64 78 20 24 69 64 78 6c 69 73  each idx $idxlis
5340: 74 20 7b 0a 20 20 20 20 20 20 73 65 74 20 71 69  t {.      set qi
5350: 64 78 20 5b 71 75 6f 74 65 20 24 69 64 78 5d 0a  dx [quote $idx].
5360: 20 20 20 20 20 20 73 75 62 72 65 70 6f 72 74 20        subreport 
5370: 22 49 6e 64 65 78 20 5b 73 74 72 69 6e 67 20 74  "Index [string t
5380: 6f 75 70 70 65 72 20 24 69 64 78 5d 20 6f 66 20  oupper $idx] of 
5390: 74 61 62 6c 65 20 24 6e 61 6d 65 22 20 22 6e 61  table $name" "na
53a0: 6d 65 3d 27 24 71 69 64 78 27 22 20 31 0a 20 20  me='$qidx'" 1.  
53b0: 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20    }.  } else {. 
53c0: 20 20 20 73 75 62 72 65 70 6f 72 74 20 22 54 61     subreport "Ta
53d0: 62 6c 65 20 24 6e 61 6d 65 22 20 22 6e 61 6d 65  ble $name" "name
53e0: 3d 27 24 71 6e 27 22 20 31 0a 20 20 7d 0a 7d 0a  ='$qn'" 1.  }.}.
53f0: 0a 23 20 4f 75 74 70 75 74 20 69 6e 73 74 72 75  .# Output instru
5400: 63 74 69 6f 6e 73 20 6f 6e 20 77 68 61 74 20 74  ctions on what t
5410: 68 65 20 6e 75 6d 62 65 72 73 20 61 62 6f 76 65  he numbers above
5420: 20 6d 65 61 6e 2e 0a 23 0a 70 75 74 73 20 22 22   mean..#.puts ""
5430: 0a 74 69 74 6c 65 6c 69 6e 65 20 44 65 66 69 6e  .titleline Defin
5440: 69 74 69 6f 6e 73 0a 70 75 74 73 20 7b 0a 50 61  itions.puts {.Pa
5450: 67 65 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73  ge size in bytes
5460: 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72  ..    The number
5470: 20 6f 66 20 62 79 74 65 73 20 69 6e 20 61 20 73   of bytes in a s
5480: 69 6e 67 6c 65 20 70 61 67 65 20 6f 66 20 74 68  ingle page of th
5490: 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e  e database file.
54a0: 20 20 0a 20 20 20 20 55 73 75 61 6c 6c 79 20 31    .    Usually 1
54b0: 30 32 34 2e 0a 0a 4e 75 6d 62 65 72 20 6f 66 20  024...Number of 
54c0: 70 61 67 65 73 20 69 6e 20 74 68 65 20 77 68 6f  pages in the who
54d0: 6c 65 20 66 69 6c 65 0a 7d 0a 70 75 74 73 20 22  le file.}.puts "
54e0: 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f      The number o
54f0: 66 20 24 70 61 67 65 53 69 7a 65 2d 62 79 74 65  f $pageSize-byte
5500: 20 70 61 67 65 73 20 74 68 61 74 20 67 6f 20 69   pages that go i
5510: 6e 74 6f 20 66 6f 72 6d 69 6e 67 20 74 68 65 20  nto forming the 
5520: 63 6f 6d 70 6c 65 74 65 0a 20 20 20 20 64 61 74  complete.    dat
5530: 61 62 61 73 65 22 0a 70 75 74 73 20 7b 0a 50 61  abase".puts {.Pa
5540: 67 65 73 20 74 68 61 74 20 73 74 6f 72 65 20 64  ges that store d
5550: 61 74 61 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d  ata..    The num
5560: 62 65 72 20 6f 66 20 70 61 67 65 73 20 74 68 61  ber of pages tha
5570: 74 20 73 74 6f 72 65 20 64 61 74 61 2c 20 65 69  t store data, ei
5580: 74 68 65 72 20 61 73 20 70 72 69 6d 61 72 79 20  ther as primary 
5590: 42 2a 54 72 65 65 20 70 61 67 65 73 20 6f 72 0a  B*Tree pages or.
55a0: 20 20 20 20 61 73 20 6f 76 65 72 66 6c 6f 77 20      as overflow 
55b0: 70 61 67 65 73 2e 20 20 54 68 65 20 6e 75 6d 62  pages.  The numb
55c0: 65 72 20 61 74 20 74 68 65 20 72 69 67 68 74 20  er at the right 
55d0: 69 73 20 74 68 65 20 64 61 74 61 20 70 61 67 65  is the data page
55e0: 73 20 64 69 76 69 64 65 64 20 62 79 0a 20 20 20  s divided by.   
55f0: 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65   the total numbe
5600: 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68  r of pages in th
5610: 65 20 66 69 6c 65 2e 0a 0a 50 61 67 65 73 20 6f  e file...Pages o
5620: 6e 20 74 68 65 20 66 72 65 65 6c 69 73 74 0a 0a  n the freelist..
5630: 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f      The number o
5640: 66 20 70 61 67 65 73 20 74 68 61 74 20 61 72 65  f pages that are
5650: 20 6e 6f 74 20 63 75 72 72 65 6e 74 6c 79 20 69   not currently i
5660: 6e 20 75 73 65 20 62 75 74 20 61 72 65 20 72 65  n use but are re
5670: 73 65 72 76 65 64 20 66 6f 72 0a 20 20 20 20 66  served for.    f
5680: 75 74 75 72 65 20 75 73 65 2e 20 20 54 68 65 20  uture use.  The 
5690: 70 65 72 63 65 6e 74 61 67 65 20 61 74 20 74 68  percentage at th
56a0: 65 20 72 69 67 68 74 20 69 73 20 74 68 65 20 6e  e right is the n
56b0: 75 6d 62 65 72 20 6f 66 20 66 72 65 65 6c 69 73  umber of freelis
56c0: 74 20 70 61 67 65 73 0a 20 20 20 20 64 69 76 69  t pages.    divi
56d0: 64 65 64 20 62 79 20 74 68 65 20 74 6f 74 61 6c  ded by the total
56e0: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
56f0: 20 69 6e 20 74 68 65 20 66 69 6c 65 2e 0a 0a 50   in the file...P
5700: 61 67 65 73 20 6f 66 20 61 75 74 6f 2d 76 61 63  ages of auto-vac
5710: 75 75 6d 20 6f 76 65 72 68 65 61 64 0a 0a 20 20  uum overhead..  
5720: 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20    The number of 
5730: 70 61 67 65 73 20 74 68 61 74 20 73 74 6f 72 65  pages that store
5740: 20 64 61 74 61 20 75 73 65 64 20 62 79 20 74 68   data used by th
5750: 65 20 64 61 74 61 62 61 73 65 20 74 6f 20 66 61  e database to fa
5760: 63 69 6c 69 74 61 74 65 0a 20 20 20 20 61 75 74  cilitate.    aut
5770: 6f 2d 76 61 63 75 75 6d 2e 20 54 68 69 73 20 69  o-vacuum. This i
5780: 73 20 7a 65 72 6f 20 66 6f 72 20 64 61 74 61 62  s zero for datab
5790: 61 73 65 73 20 74 68 61 74 20 64 6f 20 6e 6f 74  ases that do not
57a0: 20 73 75 70 70 6f 72 74 20 61 75 74 6f 2d 76 61   support auto-va
57b0: 63 75 75 6d 2e 0a 0a 4e 75 6d 62 65 72 20 6f 66  cuum...Number of
57c0: 20 74 61 62 6c 65 73 20 69 6e 20 74 68 65 20 64   tables in the d
57d0: 61 74 61 62 61 73 65 0a 0a 20 20 20 20 54 68 65  atabase..    The
57e0: 20 6e 75 6d 62 65 72 20 6f 66 20 74 61 62 6c 65   number of table
57f0: 73 20 69 6e 20 74 68 65 20 64 61 74 61 62 61 73  s in the databas
5800: 65 2c 20 69 6e 63 6c 75 64 69 6e 67 20 74 68 65  e, including the
5810: 20 53 51 4c 49 54 45 5f 4d 41 53 54 45 52 20 74   SQLITE_MASTER t
5820: 61 62 6c 65 0a 20 20 20 20 75 73 65 64 20 74 6f  able.    used to
5830: 20 73 74 6f 72 65 20 73 63 68 65 6d 61 20 69 6e   store schema in
5840: 66 6f 72 6d 61 74 69 6f 6e 2e 0a 0a 4e 75 6d 62  formation...Numb
5850: 65 72 20 6f 66 20 69 6e 64 69 63 65 73 0a 0a 20  er of indices.. 
5860: 20 20 20 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d     The total num
5870: 62 65 72 20 6f 66 20 69 6e 64 69 63 65 73 20 69  ber of indices i
5880: 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a  n the database..
5890: 0a 4e 75 6d 62 65 72 20 6f 66 20 64 65 66 69 6e  .Number of defin
58a0: 65 64 20 69 6e 64 69 63 65 73 0a 0a 20 20 20 20  ed indices..    
58b0: 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 69 6e  The number of in
58c0: 64 69 63 65 73 20 63 72 65 61 74 65 64 20 75 73  dices created us
58d0: 69 6e 67 20 61 6e 20 65 78 70 6c 69 63 69 74 20  ing an explicit 
58e0: 43 52 45 41 54 45 20 49 4e 44 45 58 20 73 74 61  CREATE INDEX sta
58f0: 74 65 6d 65 6e 74 2e 0a 0a 4e 75 6d 62 65 72 20  tement...Number 
5900: 6f 66 20 69 6d 70 6c 69 65 64 20 69 6e 64 69 63  of implied indic
5910: 65 73 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d 62  es..    The numb
5920: 65 72 20 6f 66 20 69 6e 64 69 63 65 73 20 75 73  er of indices us
5930: 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20  ed to implement 
5940: 50 52 49 4d 41 52 59 20 4b 45 59 20 6f 72 20 55  PRIMARY KEY or U
5950: 4e 49 51 55 45 20 63 6f 6e 73 74 72 61 69 6e 74  NIQUE constraint
5960: 73 0a 20 20 20 20 6f 6e 20 74 61 62 6c 65 73 2e  s.    on tables.
5970: 0a 0a 53 69 7a 65 20 6f 66 20 74 68 65 20 66 69  ..Size of the fi
5980: 6c 65 20 69 6e 20 62 79 74 65 73 0a 0a 20 20 20  le in bytes..   
5990: 20 54 68 65 20 74 6f 74 61 6c 20 61 6d 6f 75 6e   The total amoun
59a0: 74 20 6f 66 20 64 69 73 6b 20 73 70 61 63 65 20  t of disk space 
59b0: 75 73 65 64 20 62 79 20 74 68 65 20 65 6e 74 69  used by the enti
59c0: 72 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  re database file
59d0: 73 2e 0a 0a 42 79 74 65 73 20 6f 66 20 75 73 65  s...Bytes of use
59e0: 72 20 70 61 79 6c 6f 61 64 20 73 74 6f 72 65 64  r payload stored
59f0: 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61 6c 20  ..    The total 
5a00: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
5a10: 6f 66 20 75 73 65 72 20 70 61 79 6c 6f 61 64 20  of user payload 
5a20: 73 74 6f 72 65 64 20 69 6e 20 74 68 65 20 64 61  stored in the da
5a30: 74 61 62 61 73 65 2e 20 54 68 65 0a 20 20 20 20  tabase. The.    
5a40: 73 63 68 65 6d 61 20 69 6e 66 6f 72 6d 61 74 69  schema informati
5a50: 6f 6e 20 69 6e 20 74 68 65 20 53 51 4c 49 54 45  on in the SQLITE
5a60: 5f 4d 41 53 54 45 52 20 74 61 62 6c 65 20 69 73  _MASTER table is
5a70: 20 6e 6f 74 20 63 6f 75 6e 74 65 64 20 77 68 65   not counted whe
5a80: 6e 0a 20 20 20 20 63 6f 6d 70 75 74 69 6e 67 20  n.    computing 
5a90: 74 68 69 73 20 6e 75 6d 62 65 72 2e 20 20 54 68  this number.  Th
5aa0: 65 20 70 65 72 63 65 6e 74 61 67 65 20 61 74 20  e percentage at 
5ab0: 74 68 65 20 72 69 67 68 74 20 73 68 6f 77 73 20  the right shows 
5ac0: 74 68 65 20 70 61 79 6c 6f 61 64 0a 20 20 20 20  the payload.    
5ad0: 64 69 76 69 64 65 64 20 62 79 20 74 68 65 20 74  divided by the t
5ae0: 6f 74 61 6c 20 66 69 6c 65 20 73 69 7a 65 2e 0a  otal file size..
5af0: 0a 50 65 72 63 65 6e 74 61 67 65 20 6f 66 20 74  .Percentage of t
5b00: 6f 74 61 6c 20 64 61 74 61 62 61 73 65 0a 0a 20  otal database.. 
5b10: 20 20 20 54 68 65 20 61 6d 6f 75 6e 74 20 6f 66     The amount of
5b20: 20 74 68 65 20 63 6f 6d 70 6c 65 74 65 20 64 61   the complete da
5b30: 74 61 62 61 73 65 20 66 69 6c 65 20 74 68 61 74  tabase file that
5b40: 20 69 73 20 64 65 76 6f 74 65 64 20 74 6f 20 73   is devoted to s
5b50: 74 6f 72 69 6e 67 0a 20 20 20 20 69 6e 66 6f 72  toring.    infor
5b60: 6d 61 74 69 6f 6e 20 64 65 73 63 72 69 62 65 64  mation described
5b70: 20 62 79 20 74 68 69 73 20 63 61 74 65 67 6f 72   by this categor
5b80: 79 2e 0a 0a 4e 75 6d 62 65 72 20 6f 66 20 65 6e  y...Number of en
5b90: 74 72 69 65 73 0a 0a 20 20 20 20 54 68 65 20 74  tries..    The t
5ba0: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 42  otal number of B
5bb0: 2d 54 72 65 65 20 6b 65 79 2f 76 61 6c 75 65 20  -Tree key/value 
5bc0: 70 61 69 72 73 20 73 74 6f 72 65 64 20 75 6e 64  pairs stored und
5bd0: 65 72 20 74 68 69 73 20 63 61 74 65 67 6f 72 79  er this category
5be0: 2e 0a 0a 42 79 74 65 73 20 6f 66 20 73 74 6f 72  ...Bytes of stor
5bf0: 61 67 65 20 63 6f 6e 73 75 6d 65 64 0a 0a 20 20  age consumed..  
5c00: 20 20 54 68 65 20 74 6f 74 61 6c 20 61 6d 6f 75    The total amou
5c10: 6e 74 20 6f 66 20 64 69 73 6b 20 73 70 61 63 65  nt of disk space
5c20: 20 72 65 71 75 69 72 65 64 20 74 6f 20 73 74 6f   required to sto
5c30: 72 65 20 61 6c 6c 20 42 2d 54 72 65 65 20 65 6e  re all B-Tree en
5c40: 74 72 69 65 73 0a 20 20 20 20 75 6e 64 65 72 20  tries.    under 
5c50: 74 68 69 73 20 63 61 74 65 67 6f 72 79 2e 20 20  this category.  
5c60: 54 68 65 20 69 73 20 74 68 65 20 74 6f 74 61 6c  The is the total
5c70: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
5c80: 20 75 73 65 64 20 74 69 6d 65 73 0a 20 20 20 20   used times.    
5c90: 74 68 65 20 70 61 67 65 73 20 73 69 7a 65 2e 0a  the pages size..
5ca0: 0a 42 79 74 65 73 20 6f 66 20 70 61 79 6c 6f 61  .Bytes of payloa
5cb0: 64 0a 0a 20 20 20 20 54 68 65 20 61 6d 6f 75 6e  d..    The amoun
5cc0: 74 20 6f 66 20 70 61 79 6c 6f 61 64 20 73 74 6f  t of payload sto
5cd0: 72 65 64 20 75 6e 64 65 72 20 74 68 69 73 20 63  red under this c
5ce0: 61 74 65 67 6f 72 79 2e 20 20 50 61 79 6c 6f 61  ategory.  Payloa
5cf0: 64 20 69 73 20 74 68 65 20 64 61 74 61 0a 20 20  d is the data.  
5d00: 20 20 70 61 72 74 20 6f 66 20 74 61 62 6c 65 20    part of table 
5d10: 65 6e 74 72 69 65 73 20 61 6e 64 20 74 68 65 20  entries and the 
5d20: 6b 65 79 20 70 61 72 74 20 6f 66 20 69 6e 64 65  key part of inde
5d30: 78 20 65 6e 74 72 69 65 73 2e 20 20 54 68 65 20  x entries.  The 
5d40: 70 65 72 63 65 6e 74 61 67 65 0a 20 20 20 20 61  percentage.    a
5d50: 74 20 74 68 65 20 72 69 67 68 74 20 69 73 20 74  t the right is t
5d60: 68 65 20 62 79 74 65 73 20 6f 66 20 70 61 79 6c  he bytes of payl
5d70: 6f 61 64 20 64 69 76 69 64 65 64 20 62 79 20 74  oad divided by t
5d80: 68 65 20 62 79 74 65 73 20 6f 66 20 73 74 6f 72  he bytes of stor
5d90: 61 67 65 20 0a 20 20 20 20 63 6f 6e 73 75 6d 65  age .    consume
5da0: 64 2e 0a 0a 41 76 65 72 61 67 65 20 70 61 79 6c  d...Average payl
5db0: 6f 61 64 20 70 65 72 20 65 6e 74 72 79 0a 0a 20  oad per entry.. 
5dc0: 20 20 20 54 68 65 20 61 76 65 72 61 67 65 20 61     The average a
5dd0: 6d 6f 75 6e 74 20 6f 66 20 70 61 79 6c 6f 61 64  mount of payload
5de0: 20 6f 6e 20 65 61 63 68 20 65 6e 74 72 79 2e 20   on each entry. 
5df0: 20 54 68 69 73 20 69 73 20 6a 75 73 74 20 74 68   This is just th
5e00: 65 20 62 79 74 65 73 20 6f 66 0a 20 20 20 20 70  e bytes of.    p
5e10: 61 79 6c 6f 61 64 20 64 69 76 69 64 65 64 20 62  ayload divided b
5e20: 79 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  y the number of 
5e30: 65 6e 74 72 69 65 73 2e 0a 0a 41 76 65 72 61 67  entries...Averag
5e40: 65 20 75 6e 75 73 65 64 20 62 79 74 65 73 20 70  e unused bytes p
5e50: 65 72 20 65 6e 74 72 79 0a 0a 20 20 20 20 54 68  er entry..    Th
5e60: 65 20 61 76 65 72 61 67 65 20 61 6d 6f 75 6e 74  e average amount
5e70: 20 6f 66 20 66 72 65 65 20 73 70 61 63 65 20 72   of free space r
5e80: 65 6d 61 69 6e 69 6e 67 20 6f 6e 20 61 6c 6c 20  emaining on all 
5e90: 70 61 67 65 73 20 75 6e 64 65 72 20 74 68 69 73  pages under this
5ea0: 0a 20 20 20 20 63 61 74 65 67 6f 72 79 20 6f 6e  .    category on
5eb0: 20 61 20 70 65 72 2d 65 6e 74 72 79 20 62 61 73   a per-entry bas
5ec0: 69 73 2e 20 20 54 68 69 73 20 69 73 20 74 68 65  is.  This is the
5ed0: 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e 75 73 65   number of unuse
5ee0: 64 20 62 79 74 65 73 20 6f 6e 0a 20 20 20 20 61  d bytes on.    a
5ef0: 6c 6c 20 70 61 67 65 73 20 64 69 76 69 64 65 64  ll pages divided
5f00: 20 62 79 20 74 68 65 20 6e 75 6d 62 65 72 20 6f   by the number o
5f10: 66 20 65 6e 74 72 69 65 73 2e 0a 0a 4e 6f 6e 2d  f entries...Non-
5f20: 73 65 71 75 65 6e 74 69 61 6c 20 70 61 67 65 73  sequential pages
5f30: 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72  ..    The number
5f40: 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68 65   of pages in the
5f50: 20 74 61 62 6c 65 20 6f 72 20 69 6e 64 65 78 20   table or index 
5f60: 74 68 61 74 20 61 72 65 20 6f 75 74 20 6f 66 20  that are out of 
5f70: 73 65 71 75 65 6e 63 65 2e 0a 20 20 20 20 4d 61  sequence..    Ma
5f80: 6e 79 20 66 69 6c 65 73 79 73 74 65 6d 73 20 61  ny filesystems a
5f90: 72 65 20 6f 70 74 69 6d 69 7a 65 64 20 66 6f 72  re optimized for
5fa0: 20 73 65 71 75 65 6e 74 69 61 6c 20 66 69 6c 65   sequential file
5fb0: 20 61 63 63 65 73 73 20 73 6f 20 61 20 73 6d 61   access so a sma
5fc0: 6c 6c 0a 20 20 20 20 6e 75 6d 62 65 72 20 6f 66  ll.    number of
5fd0: 20 6e 6f 6e 2d 73 65 71 75 65 6e 74 69 61 6c 20   non-sequential 
5fe0: 70 61 67 65 73 20 6d 69 67 68 74 20 72 65 73 75  pages might resu
5ff0: 6c 74 20 69 6e 20 66 61 73 74 65 72 20 71 75 65  lt in faster que
6000: 72 69 65 73 2c 0a 20 20 20 20 65 73 70 65 63 69  ries,.    especi
6010: 61 6c 6c 79 20 66 6f 72 20 6c 61 72 67 65 72 20  ally for larger 
6020: 64 61 74 61 62 61 73 65 20 66 69 6c 65 73 20 74  database files t
6030: 68 61 74 20 64 6f 20 6e 6f 74 20 66 69 74 20 69  hat do not fit i
6040: 6e 20 74 68 65 20 64 69 73 6b 20 63 61 63 68 65  n the disk cache
6050: 2e 0a 20 20 20 20 4e 6f 74 65 20 74 68 61 74 20  ..    Note that 
6060: 61 66 74 65 72 20 72 75 6e 6e 69 6e 67 20 56 41  after running VA
6070: 43 55 55 4d 2c 20 74 68 65 20 72 6f 6f 74 20 70  CUUM, the root p
6080: 61 67 65 20 6f 66 20 65 61 63 68 20 74 61 62 6c  age of each tabl
6090: 65 20 6f 72 20 69 6e 64 65 78 20 69 73 0a 20 20  e or index is.  
60a0: 20 20 61 74 20 74 68 65 20 62 65 67 69 6e 6e 69    at the beginni
60b0: 6e 67 20 6f 66 20 74 68 65 20 64 61 74 61 62 61  ng of the databa
60c0: 73 65 20 66 69 6c 65 20 61 6e 64 20 61 6c 6c 20  se file and all 
60d0: 6f 74 68 65 72 20 70 61 67 65 73 20 61 72 65 20  other pages are 
60e0: 69 6e 20 61 0a 20 20 20 20 73 65 70 61 72 61 74  in a.    separat
60f0: 65 20 70 61 72 74 20 6f 66 20 74 68 65 20 64 61  e part of the da
6100: 74 61 62 61 73 65 20 66 69 6c 65 2c 20 72 65 73  tabase file, res
6110: 75 6c 74 69 6e 67 20 69 6e 20 61 20 73 69 6e 67  ulting in a sing
6120: 6c 65 20 6e 6f 6e 2d 0a 20 20 20 20 73 65 71 75  le non-.    sequ
6130: 65 6e 74 69 61 6c 20 70 61 67 65 2e 0a 0a 4d 61  ential page...Ma
6140: 78 69 6d 75 6d 20 70 61 79 6c 6f 61 64 20 70 65  ximum payload pe
6150: 72 20 65 6e 74 72 79 0a 0a 20 20 20 20 54 68 65  r entry..    The
6160: 20 6c 61 72 67 65 73 74 20 70 61 79 6c 6f 61 64   largest payload
6170: 20 73 69 7a 65 20 6f 66 20 61 6e 79 20 65 6e 74   size of any ent
6180: 72 79 2e 0a 0a 45 6e 74 72 69 65 73 20 74 68 61  ry...Entries tha
6190: 74 20 75 73 65 20 6f 76 65 72 66 6c 6f 77 0a 0a  t use overflow..
61a0: 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f      The number o
61b0: 66 20 65 6e 74 72 69 65 73 20 74 68 61 74 20 75  f entries that u
61c0: 73 65 72 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20  ser one or more 
61d0: 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 2e 0a  overflow pages..
61e0: 0a 54 6f 74 61 6c 20 70 61 67 65 73 20 75 73 65  .Total pages use
61f0: 64 0a 0a 20 20 20 20 54 68 69 73 20 69 73 20 74  d..    This is t
6200: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  he number of pag
6210: 65 73 20 75 73 65 64 20 74 6f 20 68 6f 6c 64 20  es used to hold 
6220: 61 6c 6c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  all information 
6230: 69 6e 20 74 68 65 20 63 75 72 72 65 6e 74 0a 20  in the current. 
6240: 20 20 20 63 61 74 65 67 6f 72 79 2e 20 20 54 68     category.  Th
6250: 69 73 20 69 73 20 74 68 65 20 73 75 6d 20 6f 66  is is the sum of
6260: 20 69 6e 64 65 78 2c 20 70 72 69 6d 61 72 79 2c   index, primary,
6270: 20 61 6e 64 20 6f 76 65 72 66 6c 6f 77 20 70 61   and overflow pa
6280: 67 65 73 2e 0a 0a 49 6e 64 65 78 20 70 61 67 65  ges...Index page
6290: 73 20 75 73 65 64 0a 0a 20 20 20 20 54 68 69 73  s used..    This
62a0: 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f   is the number o
62b0: 66 20 70 61 67 65 73 20 69 6e 20 61 20 74 61 62  f pages in a tab
62c0: 6c 65 20 42 2d 74 72 65 65 20 74 68 61 74 20 68  le B-tree that h
62d0: 6f 6c 64 20 6f 6e 6c 79 20 6b 65 79 20 28 72 6f  old only key (ro
62e0: 77 69 64 29 0a 20 20 20 20 69 6e 66 6f 72 6d 61  wid).    informa
62f0: 74 69 6f 6e 20 61 6e 64 20 6e 6f 20 64 61 74 61  tion and no data
6300: 2e 0a 0a 50 72 69 6d 61 72 79 20 70 61 67 65 73  ...Primary pages
6310: 20 75 73 65 64 0a 0a 20 20 20 20 54 68 69 73 20   used..    This 
6320: 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  is the number of
6330: 20 42 2d 74 72 65 65 20 70 61 67 65 73 20 74 68   B-tree pages th
6340: 61 74 20 68 6f 6c 64 20 62 6f 74 68 20 6b 65 79  at hold both key
6350: 20 61 6e 64 20 64 61 74 61 2e 0a 0a 4f 76 65 72   and data...Over
6360: 66 6c 6f 77 20 70 61 67 65 73 20 75 73 65 64 0a  flow pages used.
6370: 0a 20 20 20 20 54 68 65 20 74 6f 74 61 6c 20 6e  .    The total n
6380: 75 6d 62 65 72 20 6f 66 20 6f 76 65 72 66 6c 6f  umber of overflo
6390: 77 20 70 61 67 65 73 20 75 73 65 64 20 66 6f 72  w pages used for
63a0: 20 74 68 69 73 20 63 61 74 65 67 6f 72 79 2e 0a   this category..
63b0: 0a 55 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e  .Unused bytes on
63c0: 20 69 6e 64 65 78 20 70 61 67 65 73 0a 0a 20 20   index pages..  
63d0: 20 20 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62    The total numb
63e0: 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 75  er of bytes of u
63f0: 6e 75 73 65 64 20 73 70 61 63 65 20 6f 6e 20 61  nused space on a
6400: 6c 6c 20 69 6e 64 65 78 20 70 61 67 65 73 2e 20  ll index pages. 
6410: 20 54 68 65 0a 20 20 20 20 70 65 72 63 65 6e 74   The.    percent
6420: 61 67 65 20 61 74 20 74 68 65 20 72 69 67 68 74  age at the right
6430: 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f   is the number o
6440: 66 20 75 6e 75 73 65 64 20 62 79 74 65 73 20 64  f unused bytes d
6450: 69 76 69 64 65 64 20 62 79 20 74 68 65 0a 20 20  ivided by the.  
6460: 20 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f    total number o
6470: 66 20 62 79 74 65 73 20 6f 6e 20 69 6e 64 65 78  f bytes on index
6480: 20 70 61 67 65 73 2e 0a 0a 55 6e 75 73 65 64 20   pages...Unused 
6490: 62 79 74 65 73 20 6f 6e 20 70 72 69 6d 61 72 79  bytes on primary
64a0: 20 70 61 67 65 73 0a 0a 20 20 20 20 54 68 65 20   pages..    The 
64b0: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  total number of 
64c0: 62 79 74 65 73 20 6f 66 20 75 6e 75 73 65 64 20  bytes of unused 
64d0: 73 70 61 63 65 20 6f 6e 20 61 6c 6c 20 70 72 69  space on all pri
64e0: 6d 61 72 79 20 70 61 67 65 73 2e 20 20 54 68 65  mary pages.  The
64f0: 0a 20 20 20 20 70 65 72 63 65 6e 74 61 67 65 20  .    percentage 
6500: 61 74 20 74 68 65 20 72 69 67 68 74 20 69 73 20  at the right is 
6510: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e  the number of un
6520: 75 73 65 64 20 62 79 74 65 73 20 64 69 76 69 64  used bytes divid
6530: 65 64 20 62 79 20 74 68 65 0a 20 20 20 20 74 6f  ed by the.    to
6540: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79  tal number of by
6550: 74 65 73 20 6f 6e 20 70 72 69 6d 61 72 79 20 70  tes on primary p
6560: 61 67 65 73 2e 0a 0a 55 6e 75 73 65 64 20 62 79  ages...Unused by
6570: 74 65 73 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20  tes on overflow 
6580: 70 61 67 65 73 0a 0a 20 20 20 20 54 68 65 20 74  pages..    The t
6590: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62  otal number of b
65a0: 79 74 65 73 20 6f 66 20 75 6e 75 73 65 64 20 73  ytes of unused s
65b0: 70 61 63 65 20 6f 6e 20 61 6c 6c 20 6f 76 65 72  pace on all over
65c0: 66 6c 6f 77 20 70 61 67 65 73 2e 20 20 54 68 65  flow pages.  The
65d0: 0a 20 20 20 20 70 65 72 63 65 6e 74 61 67 65 20  .    percentage 
65e0: 61 74 20 74 68 65 20 72 69 67 68 74 20 69 73 20  at the right is 
65f0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e  the number of un
6600: 75 73 65 64 20 62 79 74 65 73 20 64 69 76 69 64  used bytes divid
6610: 65 64 20 62 79 20 74 68 65 0a 20 20 20 20 74 6f  ed by the.    to
6620: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79  tal number of by
6630: 74 65 73 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20  tes on overflow 
6640: 70 61 67 65 73 2e 0a 0a 55 6e 75 73 65 64 20 62  pages...Unused b
6650: 79 74 65 73 20 6f 6e 20 61 6c 6c 20 70 61 67 65  ytes on all page
6660: 73 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61 6c  s..    The total
6670: 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   number of bytes
6680: 20 6f 66 20 75 6e 75 73 65 64 20 73 70 61 63 65   of unused space
6690: 20 6f 6e 20 61 6c 6c 20 70 72 69 6d 61 72 79 20   on all primary 
66a0: 61 6e 64 20 6f 76 65 72 66 6c 6f 77 20 0a 20 20  and overflow .  
66b0: 20 20 70 61 67 65 73 2e 20 20 54 68 65 20 70 65    pages.  The pe
66c0: 72 63 65 6e 74 61 67 65 20 61 74 20 74 68 65 20  rcentage at the 
66d0: 72 69 67 68 74 20 69 73 20 74 68 65 20 6e 75 6d  right is the num
66e0: 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79  ber of unused by
66f0: 74 65 73 20 0a 20 20 20 20 64 69 76 69 64 65 64  tes .    divided
6700: 20 62 79 20 74 68 65 20 74 6f 74 61 6c 20 6e 75   by the total nu
6710: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 2e 0a 7d  mber of bytes..}
6720: 0a 0a 23 20 4f 75 74 70 75 74 20 61 20 64 75 6d  ..# Output a dum
6730: 70 20 6f 66 20 74 68 65 20 69 6e 2d 6d 65 6d 6f  p of the in-memo
6740: 72 79 20 64 61 74 61 62 61 73 65 2e 20 54 68 69  ry database. Thi
6750: 73 20 63 61 6e 20 62 65 20 75 73 65 64 20 66 6f  s can be used fo
6760: 72 20 6d 6f 72 65 0a 23 20 63 6f 6d 70 6c 65 78  r more.# complex
6770: 20 6f 66 66 6c 69 6e 65 20 61 6e 61 6c 79 73 69   offline analysi
6780: 73 2e 0a 23 0a 74 69 74 6c 65 6c 69 6e 65 20 7b  s..#.titleline {
6790: 7d 0a 70 75 74 73 20 22 54 68 65 20 65 6e 74 69  }.puts "The enti
67a0: 72 65 20 74 65 78 74 20 6f 66 20 74 68 69 73 20  re text of this 
67b0: 72 65 70 6f 72 74 20 63 61 6e 20 62 65 20 73 6f  report can be so
67c0: 75 72 63 65 64 20 69 6e 74 6f 20 61 6e 79 20 53  urced into any S
67d0: 51 4c 20 64 61 74 61 62 61 73 65 22 0a 70 75 74  QL database".put
67e0: 73 20 22 65 6e 67 69 6e 65 20 66 6f 72 20 66 75  s "engine for fu
67f0: 72 74 68 65 72 20 61 6e 61 6c 79 73 69 73 2e 20  rther analysis. 
6800: 20 41 6c 6c 20 6f 66 20 74 68 65 20 74 65 78 74   All of the text
6810: 20 61 62 6f 76 65 20 69 73 20 61 6e 20 53 51 4c   above is an SQL
6820: 20 63 6f 6d 6d 65 6e 74 2e 22 0a 70 75 74 73 20   comment.".puts 
6830: 22 54 68 65 20 64 61 74 61 20 75 73 65 64 20 74  "The data used t
6840: 6f 20 67 65 6e 65 72 61 74 65 20 74 68 69 73 20  o generate this 
6850: 72 65 70 6f 72 74 20 66 6f 6c 6c 6f 77 73 3a 22  report follows:"
6860: 0a 70 75 74 73 20 22 2a 2f 22 0a 70 75 74 73 20  .puts "*/".puts 
6870: 22 42 45 47 49 4e 3b 22 0a 70 75 74 73 20 24 74  "BEGIN;".puts $t
6880: 61 62 6c 65 64 65 66 0a 75 6e 73 65 74 20 2d 6e  abledef.unset -n
6890: 6f 63 6f 6d 70 6c 61 69 6e 20 78 0a 6d 65 6d 20  ocomplain x.mem 
68a0: 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 2a 20 46  eval {SELECT * F
68b0: 52 4f 4d 20 73 70 61 63 65 5f 75 73 65 64 7d 20  ROM space_used} 
68c0: 78 20 7b 0a 20 20 70 75 74 73 20 2d 6e 6f 6e 65  x {.  puts -none
68d0: 77 6c 69 6e 65 20 22 49 4e 53 45 52 54 20 49 4e  wline "INSERT IN
68e0: 54 4f 20 73 70 61 63 65 5f 75 73 65 64 20 56 41  TO space_used VA
68f0: 4c 55 45 53 22 0a 20 20 73 65 74 20 73 65 70 20  LUES".  set sep 
6900: 28 0a 20 20 66 6f 72 65 61 63 68 20 63 6f 6c 20  (.  foreach col 
6910: 24 78 28 2a 29 20 7b 0a 20 20 20 20 73 65 74 20  $x(*) {.    set 
6920: 76 20 24 78 28 24 63 6f 6c 29 0a 20 20 20 20 69  v $x($col).    i
6930: 66 20 7b 24 76 3d 3d 22 22 20 7c 7c 20 21 5b 73  f {$v=="" || ![s
6940: 74 72 69 6e 67 20 69 73 20 64 6f 75 62 6c 65 20  tring is double 
6950: 24 76 5d 7d 20 7b 73 65 74 20 76 20 27 5b 71 75  $v]} {set v '[qu
6960: 6f 74 65 20 24 76 5d 27 7d 0a 20 20 20 20 70 75  ote $v]'}.    pu
6970: 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 73  ts -nonewline $s
6980: 65 70 24 76 0a 20 20 20 20 73 65 74 20 73 65 70  ep$v.    set sep
6990: 20 2c 0a 20 20 7d 0a 20 20 70 75 74 73 20 22 29   ,.  }.  puts ")
69a0: 3b 22 0a 7d 0a 70 75 74 73 20 22 43 4f 4d 4d 49  ;".}.puts "COMMI
69b0: 54 3b 22 0a 0a 7d 20 65 72 72 5d 7d 20 7b 0a 20  T;"..} err]} {. 
69c0: 20 70 75 74 73 20 22 45 52 52 4f 52 3a 20 24 65   puts "ERROR: $e
69d0: 72 72 22 0a 20 20 70 75 74 73 20 24 65 72 72 6f  rr".  puts $erro
69e0: 72 49 6e 66 6f 0a 20 20 65 78 69 74 20 31 0a 7d  rInfo.  exit 1.}
69f0: 0a                                               .