/ Hex Artifact Content
Login

Artifact f60a242a996a79d59cad6615cec83a9203e17911:


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 47 65 74 20 74  catch {..# Get t
00d0: 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 64  he name of the d
00e0: 61 74 61 62 61 73 65 20 74 6f 20 61 6e 61 6c 79  atabase to analy
00f0: 7a 65 0a 23 0a 23 73 65 74 20 61 72 67 76 20 24  ze.#.#set argv $
0100: 61 72 67 76 30 0a 69 66 20 7b 5b 6c 6c 65 6e 67  argv0.if {[lleng
0110: 74 68 20 24 61 72 67 76 5d 21 3d 31 7d 20 7b 0a  th $argv]!=1} {.
0120: 20 20 70 75 74 73 20 73 74 64 65 72 72 20 22 55    puts stderr "U
0130: 73 61 67 65 3a 20 24 61 72 67 76 30 20 64 61 74  sage: $argv0 dat
0140: 61 62 61 73 65 2d 6e 61 6d 65 22 0a 20 20 65 78  abase-name".  ex
0150: 69 74 20 31 0a 7d 0a 73 65 74 20 66 69 6c 65 5f  it 1.}.set file_
0160: 74 6f 5f 61 6e 61 6c 79 7a 65 20 5b 6c 69 6e 64  to_analyze [lind
0170: 65 78 20 24 61 72 67 76 20 30 5d 0a 69 66 20 7b  ex $argv 0].if {
0180: 21 5b 66 69 6c 65 20 65 78 69 73 74 73 20 24 66  ![file exists $f
0190: 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 5d 7d  ile_to_analyze]}
01a0: 20 7b 0a 20 20 70 75 74 73 20 73 74 64 65 72 72   {.  puts stderr
01b0: 20 22 4e 6f 20 73 75 63 68 20 66 69 6c 65 3a 20   "No such file: 
01c0: 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65  $file_to_analyze
01d0: 22 0a 20 20 65 78 69 74 20 31 0a 7d 0a 69 66 20  ".  exit 1.}.if 
01e0: 7b 21 5b 66 69 6c 65 20 72 65 61 64 61 62 6c 65  {![file readable
01f0: 20 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a   $file_to_analyz
0200: 65 5d 7d 20 7b 0a 20 20 70 75 74 73 20 73 74 64  e]} {.  puts std
0210: 65 72 72 20 22 46 69 6c 65 20 69 73 20 6e 6f 74  err "File is not
0220: 20 72 65 61 64 61 62 6c 65 3a 20 24 66 69 6c 65   readable: $file
0230: 5f 74 6f 5f 61 6e 61 6c 79 7a 65 22 0a 20 20 65  _to_analyze".  e
0240: 78 69 74 20 31 0a 7d 0a 69 66 20 7b 5b 66 69 6c  xit 1.}.if {[fil
0250: 65 20 73 69 7a 65 20 24 66 69 6c 65 5f 74 6f 5f  e size $file_to_
0260: 61 6e 61 6c 79 7a 65 5d 3c 35 31 32 7d 20 7b 0a  analyze]<512} {.
0270: 20 20 70 75 74 73 20 73 74 64 65 72 72 20 22 45    puts stderr "E
0280: 6d 70 74 79 20 6f 72 20 6d 61 6c 66 6f 72 6d 65  mpty or malforme
0290: 64 20 64 61 74 61 62 61 73 65 3a 20 24 66 69 6c  d database: $fil
02a0: 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 22 0a 20 20  e_to_analyze".  
02b0: 65 78 69 74 20 31 0a 7d 0a 0a 23 20 4d 61 78 69  exit 1.}..# Maxi
02c0: 6d 75 6d 20 64 69 73 74 61 6e 63 65 20 62 65 74  mum distance bet
02d0: 77 65 65 6e 20 70 61 67 65 73 20 62 65 66 6f 72  ween pages befor
02e0: 65 20 77 65 20 63 6f 6e 73 69 64 65 72 20 69 74  e we consider it
02f0: 20 61 20 22 67 61 70 22 0a 23 0a 73 65 74 20 4d   a "gap".#.set M
0300: 41 58 47 41 50 20 33 0a 0a 23 20 4f 70 65 6e 20  AXGAP 3..# Open 
0310: 74 68 65 20 64 61 74 61 62 61 73 65 0a 23 0a 73  the database.#.s
0320: 71 6c 69 74 65 33 20 64 62 20 5b 6c 69 6e 64 65  qlite3 db [linde
0330: 78 20 24 61 72 67 76 20 30 5d 0a 73 65 74 20 44  x $argv 0].set D
0340: 42 20 5b 62 74 72 65 65 5f 6f 70 65 6e 20 5b 6c  B [btree_open [l
0350: 69 6e 64 65 78 20 24 61 72 67 76 20 30 5d 20 31  index $argv 0] 1
0360: 30 30 30 20 30 5d 0a 0a 23 20 49 6e 2d 6d 65 6d  000 0]..# In-mem
0370: 6f 72 79 20 64 61 74 61 62 61 73 65 20 66 6f 72  ory database for
0380: 20 63 6f 6c 6c 65 63 74 69 6e 67 20 73 74 61 74   collecting stat
0390: 69 73 74 69 63 73 2e 20 54 68 69 73 20 73 63 72  istics. This scr
03a0: 69 70 74 20 6c 6f 6f 70 73 20 74 68 72 6f 75 67  ipt loops throug
03b0: 68 0a 23 20 74 68 65 20 74 61 62 6c 65 73 20 61  h.# the tables a
03c0: 6e 64 20 69 6e 64 69 63 65 73 20 69 6e 20 74 68  nd indices in th
03d0: 65 20 64 61 74 61 62 61 73 65 20 62 65 69 6e 67  e database being
03e0: 20 61 6e 61 6c 79 7a 65 64 2c 20 61 64 64 69 6e   analyzed, addin
03f0: 67 20 61 20 72 6f 77 20 66 6f 72 20 65 61 63 68  g a row for each
0400: 0a 23 20 74 6f 20 61 6e 20 69 6e 2d 6d 65 6d 6f  .# to an in-memo
0410: 72 79 20 64 61 74 61 62 61 73 65 20 28 66 6f 72  ry database (for
0420: 20 77 68 69 63 68 20 74 68 65 20 73 63 68 65 6d   which the schem
0430: 61 20 69 73 20 73 68 6f 77 6e 20 62 65 6c 6f 77  a is shown below
0440: 29 2e 20 49 74 20 74 68 65 6e 0a 23 20 71 75 65  ). It then.# que
0450: 72 69 65 73 20 74 68 65 20 69 6e 2d 6d 65 6d 6f  ries the in-memo
0460: 72 79 20 64 62 20 74 6f 20 70 72 6f 64 75 63 65  ry db to produce
0470: 20 74 68 65 20 73 70 61 63 65 2d 61 6e 61 6c 79   the space-analy
0480: 73 69 73 20 72 65 70 6f 72 74 2e 0a 23 0a 73 71  sis report..#.sq
0490: 6c 69 74 65 33 20 6d 65 6d 20 3a 6d 65 6d 6f 72  lite3 mem :memor
04a0: 79 3a 0a 73 65 74 20 74 61 62 6c 65 64 65 66 5c  y:.set tabledef\
04b0: 0a 7b 43 52 45 41 54 45 20 54 41 42 4c 45 20 73  .{CREATE TABLE s
04c0: 70 61 63 65 5f 75 73 65 64 28 0a 20 20 20 6e 61  pace_used(.   na
04d0: 6d 65 20 63 6c 6f 62 2c 20 20 20 20 20 20 20 20  me clob,        
04e0: 2d 2d 20 4e 61 6d 65 20 6f 66 20 61 20 74 61 62  -- Name of a tab
04f0: 6c 65 20 6f 72 20 69 6e 64 65 78 20 69 6e 20 74  le or index in t
0500: 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
0510: 0a 20 20 20 74 62 6c 6e 61 6d 65 20 63 6c 6f 62  .   tblname clob
0520: 2c 20 20 20 20 20 2d 2d 20 4e 61 6d 65 20 6f 66  ,     -- Name of
0530: 20 61 73 73 6f 63 69 61 74 65 64 20 74 61 62 6c   associated tabl
0540: 65 0a 20 20 20 69 73 5f 69 6e 64 65 78 20 62 6f  e.   is_index bo
0550: 6f 6c 65 61 6e 2c 20 2d 2d 20 54 52 55 45 20 69  olean, -- TRUE i
0560: 66 20 69 74 20 69 73 20 61 6e 20 69 6e 64 65 78  f it is an index
0570: 2c 20 66 61 6c 73 65 20 66 6f 72 20 61 20 74 61  , false for a ta
0580: 62 6c 65 0a 20 20 20 6e 65 6e 74 72 79 20 69 6e  ble.   nentry in
0590: 74 2c 20 20 20 20 20 20 20 2d 2d 20 4e 75 6d 62  t,       -- Numb
05a0: 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e  er of entries in
05b0: 20 74 68 65 20 42 54 72 65 65 0a 20 20 20 6c 65   the BTree.   le
05c0: 61 66 5f 65 6e 74 72 69 65 73 20 69 6e 74 2c 20  af_entries int, 
05d0: 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 6c 65 61  -- Number of lea
05e0: 66 20 65 6e 74 72 69 65 73 0a 20 20 20 70 61 79  f entries.   pay
05f0: 6c 6f 61 64 20 69 6e 74 2c 20 20 20 20 20 20 2d  load int,      -
0600: 2d 20 54 6f 74 61 6c 20 61 6d 6f 75 6e 74 20 6f  - Total amount o
0610: 66 20 64 61 74 61 20 73 74 6f 72 65 64 20 69 6e  f data stored in
0620: 20 74 68 69 73 20 74 61 62 6c 65 20 6f 72 20 69   this table or i
0630: 6e 64 65 78 0a 20 20 20 6f 76 66 6c 5f 70 61 79  ndex.   ovfl_pay
0640: 6c 6f 61 64 20 69 6e 74 2c 20 2d 2d 20 54 6f 74  load int, -- Tot
0650: 61 6c 20 61 6d 6f 75 6e 74 20 6f 66 20 64 61 74  al amount of dat
0660: 61 20 73 74 6f 72 65 64 20 6f 6e 20 6f 76 65 72  a stored on over
0670: 66 6c 6f 77 20 70 61 67 65 73 0a 20 20 20 6f 76  flow pages.   ov
0680: 66 6c 5f 63 6e 74 20 69 6e 74 2c 20 20 20 20 20  fl_cnt int,     
0690: 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74  -- Number of ent
06a0: 72 69 65 73 20 74 68 61 74 20 75 73 65 20 6f 76  ries that use ov
06b0: 65 72 66 6c 6f 77 0a 20 20 20 6d 78 5f 70 61 79  erflow.   mx_pay
06c0: 6c 6f 61 64 20 69 6e 74 2c 20 20 20 2d 2d 20 4d  load int,   -- M
06d0: 61 78 69 6d 75 6d 20 70 61 79 6c 6f 61 64 20 73  aximum payload s
06e0: 69 7a 65 0a 20 20 20 69 6e 74 5f 70 61 67 65 73  ize.   int_pages
06f0: 20 69 6e 74 2c 20 20 20 20 2d 2d 20 4e 75 6d 62   int,    -- Numb
0700: 65 72 20 6f 66 20 69 6e 74 65 72 69 6f 72 20 70  er of interior p
0710: 61 67 65 73 20 75 73 65 64 0a 20 20 20 6c 65 61  ages used.   lea
0720: 66 5f 70 61 67 65 73 20 69 6e 74 2c 20 20 20 2d  f_pages int,   -
0730: 2d 20 4e 75 6d 62 65 72 20 6f 66 20 6c 65 61 66  - Number of leaf
0740: 20 70 61 67 65 73 20 75 73 65 64 0a 20 20 20 6f   pages used.   o
0750: 76 66 6c 5f 70 61 67 65 73 20 69 6e 74 2c 20 20  vfl_pages int,  
0760: 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 6f 76   -- Number of ov
0770: 65 72 66 6c 6f 77 20 70 61 67 65 73 20 75 73 65  erflow pages use
0780: 64 0a 20 20 20 69 6e 74 5f 75 6e 75 73 65 64 20  d.   int_unused 
0790: 69 6e 74 2c 20 20 20 2d 2d 20 4e 75 6d 62 65 72  int,   -- Number
07a0: 20 6f 66 20 75 6e 75 73 65 64 20 62 79 74 65 73   of unused bytes
07b0: 20 6f 6e 20 69 6e 74 65 72 69 6f 72 20 70 61 67   on interior pag
07c0: 65 73 0a 20 20 20 6c 65 61 66 5f 75 6e 75 73 65  es.   leaf_unuse
07d0: 64 20 69 6e 74 2c 20 20 2d 2d 20 4e 75 6d 62 65  d int,  -- Numbe
07e0: 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79 74 65  r of unused byte
07f0: 73 20 6f 6e 20 70 72 69 6d 61 72 79 20 70 61 67  s on primary pag
0800: 65 73 0a 20 20 20 6f 76 66 6c 5f 75 6e 75 73 65  es.   ovfl_unuse
0810: 64 20 69 6e 74 2c 20 20 2d 2d 20 4e 75 6d 62 65  d int,  -- Numbe
0820: 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79 74 65  r of unused byte
0830: 73 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20 70 61  s on overflow pa
0840: 67 65 73 0a 20 20 20 67 61 70 5f 63 6e 74 20 69  ges.   gap_cnt i
0850: 6e 74 20 20 20 20 20 20 20 2d 2d 20 4e 75 6d 62  nt       -- Numb
0860: 65 72 20 6f 66 20 67 61 70 73 20 69 6e 20 74 68  er of gaps in th
0870: 65 20 70 61 67 65 20 6c 61 79 6f 75 74 0a 29 3b  e page layout.);
0880: 7d 0a 6d 65 6d 20 65 76 61 6c 20 24 74 61 62 6c  }.mem eval $tabl
0890: 65 64 65 66 0a 0a 70 72 6f 63 20 69 6e 74 65 67  edef..proc integ
08a0: 65 72 69 66 79 20 7b 72 65 61 6c 7d 20 7b 0a 20  erify {real} {. 
08b0: 20 72 65 74 75 72 6e 20 5b 65 78 70 72 20 69 6e   return [expr in
08c0: 74 28 24 72 65 61 6c 29 5d 0a 7d 0a 6d 65 6d 20  t($real)].}.mem 
08d0: 66 75 6e 63 74 69 6f 6e 20 69 6e 74 20 69 6e 74  function int int
08e0: 65 67 65 72 69 66 79 0a 0a 23 20 51 75 6f 74 65  egerify..# Quote
08f0: 20 61 20 73 74 72 69 6e 67 20 66 6f 72 20 75 73   a string for us
0900: 65 20 69 6e 20 61 6e 20 53 51 4c 20 71 75 65 72  e in an SQL quer
0910: 79 2e 20 45 78 61 6d 70 6c 65 73 3a 0a 23 0a 23  y. Examples:.#.#
0920: 20 5b 71 75 6f 74 65 20 7b 68 65 6c 6c 6f 20 77   [quote {hello w
0930: 6f 72 6c 64 7d 5d 20 20 20 3d 3d 20 7b 27 68 65  orld}]   == {'he
0940: 6c 6c 6f 20 77 6f 72 6c 64 27 7d 0a 23 20 5b 71  llo world'}.# [q
0950: 75 6f 74 65 20 7b 68 65 6c 6c 6f 20 77 6f 72 6c  uote {hello worl
0960: 64 27 73 7d 5d 20 3d 3d 20 7b 27 68 65 6c 6c 6f  d's}] == {'hello
0970: 20 77 6f 72 6c 64 27 27 73 27 7d 0a 23 0a 70 72   world''s'}.#.pr
0980: 6f 63 20 71 75 6f 74 65 20 7b 74 78 74 7d 20 7b  oc quote {txt} {
0990: 0a 20 20 72 65 67 73 75 62 20 2d 61 6c 6c 20 27  .  regsub -all '
09a0: 20 24 74 78 74 20 27 27 20 71 0a 20 20 72 65 74   $txt '' q.  ret
09b0: 75 72 6e 20 27 24 71 27 0a 7d 0a 0a 23 20 54 68  urn '$q'.}..# Th
09c0: 69 73 20 70 72 6f 63 20 69 73 20 61 20 77 72 61  is proc is a wra
09d0: 70 70 65 72 20 61 72 6f 75 6e 64 20 74 68 65 20  pper around the 
09e0: 62 74 72 65 65 5f 63 75 72 73 6f 72 5f 69 6e 66  btree_cursor_inf
09f0: 6f 20 63 6f 6d 6d 61 6e 64 2e 20 54 68 65 0a 23  o command. The.#
0a00: 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74   second argument
0a10: 20 69 73 20 61 6e 20 6f 70 65 6e 20 62 74 72 65   is an open btre
0a20: 65 20 63 75 72 73 6f 72 20 72 65 74 75 72 6e 65  e cursor returne
0a30: 64 20 62 79 20 5b 62 74 72 65 65 5f 63 75 72 73  d by [btree_curs
0a40: 6f 72 5d 2e 0a 23 20 54 68 65 20 66 69 72 73 74  or]..# The first
0a50: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 74 68 65   argument is the
0a60: 20 6e 61 6d 65 20 6f 66 20 61 6e 20 61 72 72 61   name of an arra
0a70: 79 20 76 61 72 69 61 62 6c 65 20 74 68 61 74 20  y variable that 
0a80: 65 78 69 73 74 73 20 69 6e 0a 23 20 74 68 65 20  exists in.# the 
0a90: 73 63 6f 70 65 20 6f 66 20 74 68 65 20 63 61 6c  scope of the cal
0aa0: 6c 65 72 2e 20 49 66 20 74 68 65 20 74 68 69 72  ler. If the thir
0ab0: 64 20 61 72 67 75 6d 65 6e 74 20 69 73 20 6e 6f  d argument is no
0ac0: 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 0a 23 20 69  n-zero, then.# i
0ad0: 6e 66 6f 20 69 73 20 72 65 74 75 72 6e 65 64 20  nfo is returned 
0ae0: 66 6f 72 20 74 68 65 20 70 61 67 65 20 74 68 61  for the page tha
0af0: 74 20 6c 69 65 73 20 24 75 70 20 65 6e 74 72 69  t lies $up entri
0b00: 65 73 20 75 70 77 61 72 64 73 20 69 6e 20 74 68  es upwards in th
0b10: 65 0a 23 20 74 72 65 65 2d 73 74 72 75 63 74 75  e.# tree-structu
0b20: 72 65 2e 20 28 69 2e 65 2e 20 24 75 70 3d 3d 31  re. (i.e. $up==1
0b30: 20 72 65 74 75 72 6e 73 20 74 68 65 20 70 61 72   returns the par
0b40: 65 6e 74 20 70 61 67 65 2c 20 24 75 70 3d 3d 32  ent page, $up==2
0b50: 20 74 68 65 20 0a 23 20 67 72 61 6e 64 70 61 72   the .# grandpar
0b60: 65 6e 74 20 65 74 63 2e 29 0a 23 0a 23 20 54 68  ent etc.).#.# Th
0b70: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 65 6e 74 72  e following entr
0b80: 69 65 73 20 69 6e 20 74 68 61 74 20 61 72 72 61  ies in that arra
0b90: 79 20 61 72 65 20 66 69 6c 6c 65 64 20 69 6e 20  y are filled in 
0ba0: 77 69 74 68 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  with information
0bb0: 20 72 65 74 72 69 65 76 65 64 0a 23 20 75 73 69   retrieved.# usi
0bc0: 6e 67 20 5b 62 74 72 65 65 5f 63 75 72 73 6f 72  ng [btree_cursor
0bd0: 5f 69 6e 66 6f 5d 3a 0a 23 0a 23 20 20 20 24 61  _info]:.#.#   $a
0be0: 72 72 61 79 76 61 72 28 70 61 67 65 5f 6e 6f 29  rrayvar(page_no)
0bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 3d 20 20               =  
0c00: 54 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72 0a  The page number.
0c10: 23 20 20 20 24 61 72 72 61 79 76 61 72 28 65 6e  #   $arrayvar(en
0c20: 74 72 79 5f 6e 6f 29 20 20 20 20 20 20 20 20 20  try_no)         
0c30: 20 20 20 3d 20 20 54 68 65 20 65 6e 74 72 79 20     =  The entry 
0c40: 6e 75 6d 62 65 72 0a 23 20 20 20 24 61 72 72 61  number.#   $arra
0c50: 79 76 61 72 28 70 61 67 65 5f 65 6e 74 72 69 65  yvar(page_entrie
0c60: 73 29 20 20 20 20 20 20 20 20 3d 20 20 54 6f 74  s)        =  Tot
0c70: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74  al number of ent
0c80: 72 69 65 73 20 6f 6e 20 74 68 69 73 20 70 61 67  ries on this pag
0c90: 65 0a 23 20 20 20 24 61 72 72 61 79 76 61 72 28  e.#   $arrayvar(
0ca0: 63 65 6c 6c 5f 73 69 7a 65 29 20 20 20 20 20 20  cell_size)      
0cb0: 20 20 20 20 20 3d 20 20 43 65 6c 6c 20 73 69 7a       =  Cell siz
0cc0: 65 20 28 6c 6f 63 61 6c 20 70 61 79 6c 6f 61 64  e (local payload
0cd0: 20 2b 20 68 65 61 64 65 72 29 0a 23 20 20 20 24   + header).#   $
0ce0: 61 72 72 61 79 76 61 72 28 70 61 67 65 5f 66 72  arrayvar(page_fr
0cf0: 65 65 62 79 74 65 73 29 20 20 20 20 20 20 3d 20  eebytes)      = 
0d00: 20 4e 75 6d 62 65 72 20 6f 66 20 66 72 65 65 20   Number of free 
0d10: 62 79 74 65 73 20 6f 6e 20 74 68 69 73 20 70 61  bytes on this pa
0d20: 67 65 0a 23 20 20 20 24 61 72 72 61 79 76 61 72  ge.#   $arrayvar
0d30: 28 70 61 67 65 5f 66 72 65 65 62 6c 6f 63 6b 73  (page_freeblocks
0d40: 29 20 20 20 20 20 3d 20 20 4e 75 6d 62 65 72 20  )     =  Number 
0d50: 6f 66 20 66 72 65 65 20 62 6c 6f 63 6b 73 20 6f  of free blocks o
0d60: 6e 20 74 68 65 20 70 61 67 65 0a 23 20 20 20 24  n the page.#   $
0d70: 61 72 72 61 79 76 61 72 28 70 61 79 6c 6f 61 64  arrayvar(payload
0d80: 5f 62 79 74 65 73 29 20 20 20 20 20 20 20 3d 20  _bytes)       = 
0d90: 20 54 6f 74 61 6c 20 70 61 79 6c 6f 61 64 20 73   Total payload s
0da0: 69 7a 65 20 28 6c 6f 63 61 6c 20 2b 20 6f 76 65  ize (local + ove
0db0: 72 66 6c 6f 77 29 0a 23 20 20 20 24 61 72 72 61  rflow).#   $arra
0dc0: 79 76 61 72 28 68 65 61 64 65 72 5f 62 79 74 65  yvar(header_byte
0dd0: 73 29 20 20 20 20 20 20 20 20 3d 20 20 48 65 61  s)        =  Hea
0de0: 64 65 72 20 73 69 7a 65 20 69 6e 20 62 79 74 65  der size in byte
0df0: 73 0a 23 20 20 20 24 61 72 72 61 79 76 61 72 28  s.#   $arrayvar(
0e00: 6c 6f 63 61 6c 5f 70 61 79 6c 6f 61 64 5f 62 79  local_payload_by
0e10: 74 65 73 29 20 3d 20 20 4c 6f 63 61 6c 20 70 61  tes) =  Local pa
0e20: 79 6c 6f 61 64 20 73 69 7a 65 0a 23 20 20 20 24  yload size.#   $
0e30: 61 72 72 61 79 76 61 72 28 70 61 72 65 6e 74 29  arrayvar(parent)
0e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 3d 20                = 
0e50: 20 50 61 72 65 6e 74 20 70 61 67 65 20 6e 75 6d   Parent page num
0e60: 62 65 72 0a 23 20 0a 70 72 6f 63 20 63 75 72 73  ber.# .proc curs
0e70: 6f 72 5f 69 6e 66 6f 20 7b 61 72 72 61 79 76 61  or_info {arrayva
0e80: 72 20 63 73 72 20 7b 75 70 20 30 7d 7d 20 7b 0a  r csr {up 0}} {.
0e90: 20 20 75 70 76 61 72 20 24 61 72 72 61 79 76 61    upvar $arrayva
0ea0: 72 20 61 0a 20 20 66 6f 72 65 61 63 68 20 5b 6c  r a.  foreach [l
0eb0: 69 73 74 20 61 28 70 61 67 65 5f 6e 6f 29 20 5c  ist a(page_no) \
0ec0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0ed0: 20 61 28 65 6e 74 72 79 5f 6e 6f 29 20 5c 0a 20   a(entry_no) \. 
0ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61                 a
0ef0: 28 70 61 67 65 5f 65 6e 74 72 69 65 73 29 20 5c  (page_entries) \
0f00: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0f10: 20 61 28 63 65 6c 6c 5f 73 69 7a 65 29 20 5c 0a   a(cell_size) \.
0f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f30: 61 28 70 61 67 65 5f 66 72 65 65 62 79 74 65 73  a(page_freebytes
0f40: 29 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20  ) \.            
0f50: 20 20 20 20 61 28 70 61 67 65 5f 66 72 65 65 62      a(page_freeb
0f60: 6c 6f 63 6b 73 29 20 5c 0a 20 20 20 20 20 20 20  locks) \.       
0f70: 20 20 20 20 20 20 20 20 20 61 28 70 61 79 6c 6f           a(paylo
0f80: 61 64 5f 62 79 74 65 73 29 20 5c 0a 20 20 20 20  ad_bytes) \.    
0f90: 20 20 20 20 20 20 20 20 20 20 20 20 61 28 68 65              a(he
0fa0: 61 64 65 72 5f 62 79 74 65 73 29 20 5c 0a 20 20  ader_bytes) \.  
0fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 28                a(
0fc0: 6c 6f 63 61 6c 5f 70 61 79 6c 6f 61 64 5f 62 79  local_payload_by
0fd0: 74 65 73 29 20 5c 0a 20 20 20 20 20 20 20 20 20  tes) \.         
0fe0: 20 20 20 20 20 20 20 61 28 70 61 72 65 6e 74 29         a(parent)
0ff0: 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   \.             
1000: 20 20 20 61 28 66 69 72 73 74 5f 6f 76 66 6c 29     a(first_ovfl)
1010: 20 5d 20 5b 62 74 72 65 65 5f 63 75 72 73 6f 72   ] [btree_cursor
1020: 5f 69 6e 66 6f 20 24 63 73 72 20 24 75 70 5d 20  _info $csr $up] 
1030: 62 72 65 61 6b 0a 7d 0a 0a 23 20 44 65 74 65 72  break.}..# Deter
1040: 6d 69 6e 65 20 74 68 65 20 70 61 67 65 2d 73 69  mine the page-si
1050: 7a 65 20 6f 66 20 74 68 65 20 64 61 74 61 62 61  ze of the databa
1060: 73 65 2e 20 54 68 69 73 20 67 6c 6f 62 61 6c 20  se. This global 
1070: 76 61 72 69 61 62 6c 65 20 69 73 20 75 73 65 64  variable is used
1080: 0a 23 20 74 68 72 6f 75 67 68 6f 75 74 20 74 68  .# throughout th
1090: 65 20 73 63 72 69 70 74 2e 0a 23 0a 73 65 74 20  e script..#.set 
10a0: 70 61 67 65 53 69 7a 65 20 5b 64 62 20 65 76 61  pageSize [db eva
10b0: 6c 20 7b 50 52 41 47 4d 41 20 70 61 67 65 5f 73  l {PRAGMA page_s
10c0: 69 7a 65 7d 5d 0a 0a 23 20 41 6e 61 6c 79 7a 65  ize}]..# Analyze
10d0: 20 65 76 65 72 79 20 74 61 62 6c 65 20 69 6e 20   every table in 
10e0: 74 68 65 20 64 61 74 61 62 61 73 65 2c 20 6f 6e  the database, on
10f0: 65 20 61 74 20 61 20 74 69 6d 65 2e 0a 23 0a 23  e at a time..#.#
1100: 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 71   The following q
1110: 75 65 72 79 20 72 65 74 75 72 6e 73 20 74 68 65  uery returns the
1120: 20 6e 61 6d 65 20 61 6e 64 20 72 6f 6f 74 2d 70   name and root-p
1130: 61 67 65 20 6f 66 20 65 61 63 68 20 74 61 62 6c  age of each tabl
1140: 65 20 69 6e 20 74 68 65 0a 23 20 64 61 74 61 62  e in the.# datab
1150: 61 73 65 2c 20 69 6e 63 6c 75 64 69 6e 67 20 74  ase, including t
1160: 68 65 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  he sqlite_master
1170: 20 74 61 62 6c 65 2e 0a 23 0a 73 65 74 20 73 71   table..#.set sq
1180: 6c 20 7b 0a 20 20 53 45 4c 45 43 54 20 6e 61 6d  l {.  SELECT nam
1190: 65 2c 20 72 6f 6f 74 70 61 67 65 20 46 52 4f 4d  e, rootpage FROM
11a0: 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 0a 20   sqlite_master. 
11b0: 20 20 57 48 45 52 45 20 74 79 70 65 3d 27 74 61    WHERE type='ta
11c0: 62 6c 65 27 20 41 4e 44 20 72 6f 6f 74 70 61 67  ble' AND rootpag
11d0: 65 3e 30 0a 20 20 55 4e 49 4f 4e 20 41 4c 4c 0a  e>0.  UNION ALL.
11e0: 20 20 53 45 4c 45 43 54 20 27 73 71 6c 69 74 65    SELECT 'sqlite
11f0: 5f 6d 61 73 74 65 72 27 2c 20 31 0a 20 20 4f 52  _master', 1.  OR
1200: 44 45 52 20 42 59 20 31 0a 7d 0a 73 65 74 20 77  DER BY 1.}.set w
1210: 69 64 65 5a 65 72 6f 20 5b 65 78 70 72 20 7b 31  ideZero [expr {1
1220: 30 30 30 30 30 30 30 30 30 30 20 2d 20 31 30 30  0000000000 - 100
1230: 30 30 30 30 30 30 30 30 7d 5d 0a 66 6f 72 65 61  00000000}].forea
1240: 63 68 20 7b 6e 61 6d 65 20 72 6f 6f 74 70 61 67  ch {name rootpag
1250: 65 7d 20 5b 64 62 20 65 76 61 6c 20 24 73 71 6c  e} [db eval $sql
1260: 5d 20 7b 0a 20 20 70 75 74 73 20 73 74 64 65 72  ] {.  puts stder
1270: 72 20 22 41 6e 61 6c 79 7a 69 6e 67 20 74 61 62  r "Analyzing tab
1280: 6c 65 20 24 6e 61 6d 65 2e 2e 2e 22 0a 0a 20 20  le $name..."..  
1290: 23 20 43 6f 64 65 20 62 65 6c 6f 77 20 74 72 61  # Code below tra
12a0: 76 65 72 73 65 73 20 74 68 65 20 74 61 62 6c 65  verses the table
12b0: 20 62 65 69 6e 67 20 61 6e 61 6c 79 7a 65 64 20   being analyzed 
12c0: 28 74 61 62 6c 65 20 6e 61 6d 65 20 24 6e 61 6d  (table name $nam
12d0: 65 29 2c 20 75 73 69 6e 67 20 74 68 65 0a 20 20  e), using the.  
12e0: 23 20 62 74 72 65 65 20 63 75 72 73 6f 72 20 24  # btree cursor $
12f0: 63 75 72 73 6f 72 2e 20 53 74 61 74 69 73 74 69  cursor. Statisti
1300: 63 73 20 72 65 6c 61 74 65 64 20 74 6f 20 74 61  cs related to ta
1310: 62 6c 65 20 24 6e 61 6d 65 20 61 72 65 20 61 63  ble $name are ac
1320: 63 75 6d 75 6c 61 74 65 64 20 69 6e 0a 20 20 23  cumulated in.  #
1330: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 76   the following v
1340: 61 72 69 61 62 6c 65 73 3a 0a 20 20 23 0a 20 20  ariables:.  #.  
1350: 73 65 74 20 74 6f 74 61 6c 5f 70 61 79 6c 6f 61  set total_payloa
1360: 64 20 24 77 69 64 65 5a 65 72 6f 20 20 20 20 20  d $wideZero     
1370: 20 20 20 3b 23 20 50 61 79 6c 6f 61 64 20 73 70     ;# Payload sp
1380: 61 63 65 20 75 73 65 64 20 62 79 20 61 6c 6c 20  ace used by all 
1390: 65 6e 74 72 69 65 73 0a 20 20 73 65 74 20 74 6f  entries.  set to
13a0: 74 61 6c 5f 6f 76 66 6c 20 24 77 69 64 65 5a 65  tal_ovfl $wideZe
13b0: 72 6f 20 20 20 20 20 20 20 20 20 20 20 3b 23 20  ro           ;# 
13c0: 50 61 79 6c 6f 61 64 20 73 70 61 63 65 20 6f 6e  Payload space on
13d0: 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 0a   overflow pages.
13e0: 20 20 73 65 74 20 75 6e 75 73 65 64 5f 69 6e 74    set unused_int
13f0: 20 24 77 69 64 65 5a 65 72 6f 20 20 20 20 20 20   $wideZero      
1400: 20 20 20 20 20 3b 23 20 55 6e 75 73 65 64 20 73       ;# Unused s
1410: 70 61 63 65 20 6f 6e 20 69 6e 74 65 72 69 6f 72  pace on interior
1420: 20 6e 6f 64 65 73 0a 20 20 73 65 74 20 75 6e 75   nodes.  set unu
1430: 73 65 64 5f 6c 65 61 66 20 24 77 69 64 65 5a 65  sed_leaf $wideZe
1440: 72 6f 20 20 20 20 20 20 20 20 20 20 3b 23 20 55  ro          ;# U
1450: 6e 75 73 65 64 20 73 70 61 63 65 20 6f 6e 20 6c  nused space on l
1460: 65 61 66 20 6e 6f 64 65 73 0a 20 20 73 65 74 20  eaf nodes.  set 
1470: 75 6e 75 73 65 64 5f 6f 76 66 6c 20 24 77 69 64  unused_ovfl $wid
1480: 65 5a 65 72 6f 20 20 20 20 20 20 20 20 20 20 3b  eZero          ;
1490: 23 20 55 6e 75 73 65 64 20 73 70 61 63 65 20 6f  # Unused space o
14a0: 6e 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73  n overflow pages
14b0: 0a 20 20 73 65 74 20 63 6e 74 5f 6f 76 66 6c 20  .  set cnt_ovfl 
14c0: 24 77 69 64 65 5a 65 72 6f 20 20 20 20 20 20 20  $wideZero       
14d0: 20 20 20 20 20 20 3b 23 20 4e 75 6d 62 65 72 20        ;# Number 
14e0: 6f 66 20 65 6e 74 72 69 65 73 20 74 68 61 74 20  of entries that 
14f0: 75 73 65 20 6f 76 65 72 66 6c 6f 77 73 0a 20 20  use overflows.  
1500: 73 65 74 20 63 6e 74 5f 6c 65 61 66 5f 65 6e 74  set cnt_leaf_ent
1510: 72 79 20 24 77 69 64 65 5a 65 72 6f 20 20 20 20  ry $wideZero    
1520: 20 20 20 3b 23 20 4e 75 6d 62 65 72 20 6f 66 20     ;# Number of 
1530: 6c 65 61 66 20 65 6e 74 72 69 65 73 0a 20 20 73  leaf entries.  s
1540: 65 74 20 63 6e 74 5f 69 6e 74 5f 65 6e 74 72 79  et cnt_int_entry
1550: 20 24 77 69 64 65 5a 65 72 6f 20 20 20 20 20 20   $wideZero      
1560: 20 20 3b 23 20 4e 75 6d 62 65 72 20 6f 66 20 69    ;# Number of i
1570: 6e 74 65 72 6f 72 20 65 6e 74 72 69 65 73 0a 20  nteror entries. 
1580: 20 73 65 74 20 6d 78 5f 70 61 79 6c 6f 61 64 20   set mx_payload 
1590: 24 77 69 64 65 5a 65 72 6f 20 20 20 20 20 20 20  $wideZero       
15a0: 20 20 20 20 3b 23 20 4d 61 78 69 6d 75 6d 20 70      ;# Maximum p
15b0: 61 79 6c 6f 61 64 20 73 69 7a 65 0a 20 20 73 65  ayload size.  se
15c0: 74 20 6f 76 66 6c 5f 70 61 67 65 73 20 24 77 69  t ovfl_pages $wi
15d0: 64 65 5a 65 72 6f 20 20 20 20 20 20 20 20 20 20  deZero          
15e0: 20 3b 23 20 4e 75 6d 62 65 72 20 6f 66 20 6f 76   ;# Number of ov
15f0: 65 72 66 6c 6f 77 20 70 61 67 65 73 20 75 73 65  erflow pages use
1600: 64 0a 20 20 73 65 74 20 6c 65 61 66 5f 70 61 67  d.  set leaf_pag
1610: 65 73 20 24 77 69 64 65 5a 65 72 6f 20 20 20 20  es $wideZero    
1620: 20 20 20 20 20 20 20 3b 23 20 4e 75 6d 62 65 72         ;# Number
1630: 20 6f 66 20 6c 65 61 66 20 70 61 67 65 73 0a 20   of leaf pages. 
1640: 20 73 65 74 20 69 6e 74 5f 70 61 67 65 73 20 24   set int_pages $
1650: 77 69 64 65 5a 65 72 6f 20 20 20 20 20 20 20 20  wideZero        
1660: 20 20 20 20 3b 23 20 4e 75 6d 62 65 72 20 6f 66      ;# Number of
1670: 20 69 6e 74 65 72 69 6f 72 20 70 61 67 65 73 0a   interior pages.
1680: 20 20 73 65 74 20 67 61 70 5f 63 6e 74 20 30 20    set gap_cnt 0 
1690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16a0: 20 20 20 20 20 3b 23 20 4e 75 6d 62 65 72 20 6f       ;# Number o
16b0: 66 20 68 6f 6c 65 73 20 69 6e 20 74 68 65 20 70  f holes in the p
16c0: 61 67 65 20 73 65 71 75 65 6e 63 65 0a 20 20 73  age sequence.  s
16d0: 65 74 20 70 72 65 76 5f 70 67 6e 6f 20 30 20 20  et prev_pgno 0  
16e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16f0: 20 20 3b 23 20 4c 61 73 74 20 70 61 67 65 20 6e    ;# Last page n
1700: 75 6d 62 65 72 20 73 65 65 6e 0a 0a 20 20 23 20  umber seen..  # 
1710: 41 73 20 74 68 65 20 62 74 72 65 65 20 69 73 20  As the btree is 
1720: 74 72 61 76 65 72 73 65 64 2c 20 74 68 65 20 61  traversed, the a
1730: 72 72 61 79 20 76 61 72 69 61 62 6c 65 20 24 73  rray variable $s
1740: 65 65 6e 28 24 70 67 6e 6f 29 20 69 73 20 73 65  een($pgno) is se
1750: 74 20 74 6f 20 31 0a 20 20 23 20 74 68 65 20 66  t to 1.  # the f
1760: 69 72 73 74 20 74 69 6d 65 20 70 61 67 65 20 24  irst time page $
1770: 70 67 6e 6f 20 69 73 20 65 6e 63 6f 75 6e 74 65  pgno is encounte
1780: 72 65 64 2e 0a 20 20 23 0a 20 20 63 61 74 63 68  red..  #.  catch
1790: 20 7b 75 6e 73 65 74 20 73 65 65 6e 7d 0a 0a 20   {unset seen}.. 
17a0: 20 23 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67   # The following
17b0: 20 6c 6f 6f 70 20 72 75 6e 73 20 6f 6e 63 65 20   loop runs once 
17c0: 66 6f 72 20 65 61 63 68 20 65 6e 74 72 79 20 69  for each entry i
17d0: 6e 20 74 61 62 6c 65 20 24 6e 61 6d 65 2e 20 54  n table $name. T
17e0: 68 65 20 74 61 62 6c 65 0a 20 20 23 20 69 73 20  he table.  # is 
17f0: 74 72 61 76 65 72 73 65 64 20 75 73 69 6e 67 20  traversed using 
1800: 74 68 65 20 62 74 72 65 65 20 63 75 72 73 6f 72  the btree cursor
1810: 20 73 74 6f 72 65 64 20 69 6e 20 76 61 72 69 61   stored in varia
1820: 62 6c 65 20 24 63 73 72 0a 20 20 23 0a 20 20 73  ble $csr.  #.  s
1830: 65 74 20 63 73 72 20 5b 62 74 72 65 65 5f 63 75  et csr [btree_cu
1840: 72 73 6f 72 20 24 44 42 20 24 72 6f 6f 74 70 61  rsor $DB $rootpa
1850: 67 65 20 30 5d 0a 20 20 66 6f 72 20 7b 62 74 72  ge 0].  for {btr
1860: 65 65 5f 66 69 72 73 74 20 24 63 73 72 7d 20 7b  ee_first $csr} {
1870: 21 5b 62 74 72 65 65 5f 65 6f 66 20 24 63 73 72  ![btree_eof $csr
1880: 5d 7d 20 7b 62 74 72 65 65 5f 6e 65 78 74 20 24  ]} {btree_next $
1890: 63 73 72 7d 20 7b 0a 20 20 20 20 69 6e 63 72 20  csr} {.    incr 
18a0: 63 6e 74 5f 6c 65 61 66 5f 65 6e 74 72 79 0a 0a  cnt_leaf_entry..
18b0: 20 20 20 20 23 20 52 65 74 72 69 65 76 65 20 69      # Retrieve i
18c0: 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74  nformation about
18d0: 20 74 68 65 20 65 6e 74 72 79 20 74 68 65 20 62   the entry the b
18e0: 74 72 65 65 2d 63 75 72 73 6f 72 20 70 6f 69 6e  tree-cursor poin
18f0: 74 73 20 74 6f 20 69 6e 74 6f 0a 20 20 20 20 23  ts to into.    #
1900: 20 74 68 65 20 61 72 72 61 79 20 76 61 72 69 61   the array varia
1910: 62 6c 65 20 24 63 69 20 28 63 75 72 73 6f 72 20  ble $ci (cursor 
1920: 69 6e 66 6f 29 2e 0a 20 20 20 20 23 0a 20 20 20  info)..    #.   
1930: 20 63 75 72 73 6f 72 5f 69 6e 66 6f 20 63 69 20   cursor_info ci 
1940: 24 63 73 72 0a 0a 20 20 20 20 23 20 43 68 65 63  $csr..    # Chec
1950: 6b 20 69 66 20 74 68 65 20 70 61 79 6c 6f 61 64  k if the payload
1960: 20 6f 66 20 74 68 69 73 20 65 6e 74 72 79 20 69   of this entry i
1970: 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 74  s greater than t
1980: 68 65 20 63 75 72 72 65 6e 74 20 0a 20 20 20 20  he current .    
1990: 23 20 24 6d 78 5f 70 61 79 6c 6f 61 64 20 73 74  # $mx_payload st
19a0: 61 74 69 73 74 69 63 20 66 6f 72 20 74 68 65 20  atistic for the 
19b0: 74 61 62 6c 65 2e 20 41 6c 73 6f 20 69 6e 63 72  table. Also incr
19c0: 65 61 73 65 20 74 68 65 20 24 74 6f 74 61 6c 5f  ease the $total_
19d0: 70 61 79 6c 6f 61 64 0a 20 20 20 20 23 20 73 74  payload.    # st
19e0: 61 74 69 73 74 69 63 2e 0a 20 20 20 20 23 0a 20  atistic..    #. 
19f0: 20 20 20 69 66 20 7b 24 63 69 28 70 61 79 6c 6f     if {$ci(paylo
1a00: 61 64 5f 62 79 74 65 73 29 3e 24 6d 78 5f 70 61  ad_bytes)>$mx_pa
1a10: 79 6c 6f 61 64 7d 20 7b 73 65 74 20 6d 78 5f 70  yload} {set mx_p
1a20: 61 79 6c 6f 61 64 20 24 63 69 28 70 61 79 6c 6f  ayload $ci(paylo
1a30: 61 64 5f 62 79 74 65 73 29 7d 0a 20 20 20 20 69  ad_bytes)}.    i
1a40: 6e 63 72 20 74 6f 74 61 6c 5f 70 61 79 6c 6f 61  ncr total_payloa
1a50: 64 20 24 63 69 28 70 61 79 6c 6f 61 64 5f 62 79  d $ci(payload_by
1a60: 74 65 73 29 0a 0a 20 20 20 20 23 20 49 66 20 74  tes)..    # If t
1a70: 68 69 73 20 65 6e 74 72 79 20 75 73 65 73 20 6f  his entry uses o
1a80: 76 65 72 66 6c 6f 77 20 70 61 67 65 73 2c 20 74  verflow pages, t
1a90: 68 65 6e 20 75 70 64 61 74 65 20 74 68 65 20 24  hen update the $
1aa0: 63 6e 74 5f 6f 76 66 6c 2c 20 0a 20 20 20 20 23  cnt_ovfl, .    #
1ab0: 20 24 74 6f 74 61 6c 5f 6f 76 66 6c 2c 20 24 6f   $total_ovfl, $o
1ac0: 76 66 6c 5f 70 61 67 65 73 20 61 6e 64 20 24 75  vfl_pages and $u
1ad0: 6e 75 73 65 64 5f 6f 76 66 6c 20 73 74 61 74 69  nused_ovfl stati
1ae0: 73 74 69 63 73 2e 0a 20 20 20 20 23 0a 20 20 20  stics..    #.   
1af0: 20 73 65 74 20 6f 76 66 6c 20 5b 65 78 70 72 20   set ovfl [expr 
1b00: 7b 24 63 69 28 70 61 79 6c 6f 61 64 5f 62 79 74  {$ci(payload_byt
1b10: 65 73 29 2d 24 63 69 28 6c 6f 63 61 6c 5f 70 61  es)-$ci(local_pa
1b20: 79 6c 6f 61 64 5f 62 79 74 65 73 29 7d 5d 0a 20  yload_bytes)}]. 
1b30: 20 20 20 69 66 20 7b 24 6f 76 66 6c 7d 20 7b 0a     if {$ovfl} {.
1b40: 20 20 20 20 20 20 69 6e 63 72 20 63 6e 74 5f 6f        incr cnt_o
1b50: 76 66 6c 0a 20 20 20 20 20 20 69 6e 63 72 20 74  vfl.      incr t
1b60: 6f 74 61 6c 5f 6f 76 66 6c 20 24 6f 76 66 6c 0a  otal_ovfl $ovfl.
1b70: 20 20 20 20 20 20 73 65 74 20 6e 20 5b 65 78 70        set n [exp
1b80: 72 20 7b 69 6e 74 28 63 65 69 6c 28 24 6f 76 66  r {int(ceil($ovf
1b90: 6c 2f 28 24 70 61 67 65 53 69 7a 65 2d 34 2e 30  l/($pageSize-4.0
1ba0: 29 29 29 7d 5d 0a 20 20 20 20 20 20 69 6e 63 72  )))}].      incr
1bb0: 20 6f 76 66 6c 5f 70 61 67 65 73 20 24 6e 0a 20   ovfl_pages $n. 
1bc0: 20 20 20 20 20 69 6e 63 72 20 75 6e 75 73 65 64       incr unused
1bd0: 5f 6f 76 66 6c 20 5b 65 78 70 72 20 7b 24 6e 2a  _ovfl [expr {$n*
1be0: 28 24 70 61 67 65 53 69 7a 65 2d 34 29 20 2d 20  ($pageSize-4) - 
1bf0: 24 6f 76 66 6c 7d 5d 0a 20 20 20 20 20 20 73 65  $ovfl}].      se
1c00: 74 20 70 67 6c 69 73 74 20 5b 62 74 72 65 65 5f  t pglist [btree_
1c10: 6f 76 66 6c 5f 69 6e 66 6f 20 24 44 42 20 24 63  ovfl_info $DB $c
1c20: 73 72 5d 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b  sr].    } else {
1c30: 0a 20 20 20 20 20 20 73 65 74 20 70 67 6c 69 73  .      set pglis
1c40: 74 20 7b 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20  t {}.    }..    
1c50: 23 20 49 66 20 74 68 69 73 20 69 73 20 74 68 65  # If this is the
1c60: 20 66 69 72 73 74 20 74 61 62 6c 65 20 65 6e 74   first table ent
1c70: 72 79 20 61 6e 61 6c 79 7a 65 64 20 66 6f 72 20  ry analyzed for 
1c80: 74 68 65 20 70 61 67 65 2c 20 74 68 65 6e 20 75  the page, then u
1c90: 70 64 61 74 65 0a 20 20 20 20 23 20 74 68 65 20  pdate.    # the 
1ca0: 70 61 67 65 2d 72 65 6c 61 74 65 64 20 73 74 61  page-related sta
1cb0: 74 69 73 74 69 63 73 20 24 6c 65 61 66 5f 70 61  tistics $leaf_pa
1cc0: 67 65 73 20 61 6e 64 20 24 75 6e 75 73 65 64 5f  ges and $unused_
1cd0: 6c 65 61 66 2e 20 41 6c 73 6f 2c 20 69 66 0a 20  leaf. Also, if. 
1ce0: 20 20 20 23 20 74 68 69 73 20 70 61 67 65 20 68     # this page h
1cf0: 61 73 20 61 20 70 61 72 65 6e 74 20 70 61 67 65  as a parent page
1d00: 20 74 68 61 74 20 68 61 73 20 6e 6f 74 20 62 65   that has not be
1d10: 65 6e 20 61 6e 61 6c 79 7a 65 64 2c 20 72 65 74  en analyzed, ret
1d20: 72 69 65 76 65 0a 20 20 20 20 23 20 69 6e 66 6f  rieve.    # info
1d30: 20 66 6f 72 20 74 68 65 20 70 61 72 65 6e 74 20   for the parent 
1d40: 61 6e 64 20 75 70 64 61 74 65 20 73 74 61 74 69  and update stati
1d50: 73 74 69 63 73 20 66 6f 72 20 69 74 20 74 6f 6f  stics for it too
1d60: 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66 20 7b  ..    #.    if {
1d70: 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 73 65  ![info exists se
1d80: 65 6e 28 24 63 69 28 70 61 67 65 5f 6e 6f 29 29  en($ci(page_no))
1d90: 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 73  ]} {.      set s
1da0: 65 65 6e 28 24 63 69 28 70 61 67 65 5f 6e 6f 29  een($ci(page_no)
1db0: 29 20 31 0a 20 20 20 20 20 20 69 6e 63 72 20 6c  ) 1.      incr l
1dc0: 65 61 66 5f 70 61 67 65 73 0a 20 20 20 20 20 20  eaf_pages.      
1dd0: 69 6e 63 72 20 75 6e 75 73 65 64 5f 6c 65 61 66  incr unused_leaf
1de0: 20 24 63 69 28 70 61 67 65 5f 66 72 65 65 62 79   $ci(page_freeby
1df0: 74 65 73 29 0a 20 20 20 20 20 20 73 65 74 20 70  tes).      set p
1e00: 67 6c 69 73 74 20 22 24 63 69 28 70 61 67 65 5f  glist "$ci(page_
1e10: 6e 6f 29 20 24 70 67 6c 69 73 74 22 0a 0a 20 20  no) $pglist"..  
1e20: 20 20 20 20 23 20 4e 6f 77 20 63 68 65 63 6b 20      # Now check 
1e30: 69 66 20 74 68 65 20 70 61 67 65 20 68 61 73 20  if the page has 
1e40: 61 20 70 61 72 65 6e 74 20 74 68 61 74 20 68 61  a parent that ha
1e50: 73 20 6e 6f 74 20 62 65 65 6e 20 61 6e 61 6c 79  s not been analy
1e60: 7a 65 64 2e 20 49 66 0a 20 20 20 20 20 20 23 20  zed. If.      # 
1e70: 73 6f 2c 20 75 70 64 61 74 65 20 74 68 65 20 24  so, update the $
1e80: 69 6e 74 5f 70 61 67 65 73 2c 20 24 63 6e 74 5f  int_pages, $cnt_
1e90: 69 6e 74 5f 65 6e 74 72 79 20 61 6e 64 20 24 75  int_entry and $u
1ea0: 6e 75 73 65 64 5f 69 6e 74 20 73 74 61 74 69 73  nused_int statis
1eb0: 74 69 63 73 0a 20 20 20 20 20 20 23 20 61 63 63  tics.      # acc
1ec0: 6f 72 64 69 6e 67 6c 79 2e 20 54 68 65 6e 20 63  ordingly. Then c
1ed0: 68 65 63 6b 20 69 66 20 74 68 65 20 70 61 72 65  heck if the pare
1ee0: 6e 74 20 70 61 67 65 20 68 61 73 20 61 20 70 61  nt page has a pa
1ef0: 72 65 6e 74 20 74 68 61 74 20 68 61 73 0a 20 20  rent that has.  
1f00: 20 20 20 20 23 20 6e 6f 74 20 79 65 74 20 62 65      # not yet be
1f10: 65 6e 20 61 6e 61 6c 79 7a 65 64 20 65 74 63 2e  en analyzed etc.
1f20: 0a 20 20 20 20 20 20 23 0a 20 20 20 20 20 20 23  .      #.      #
1f30: 20 73 65 74 20 70 61 72 65 6e 74 20 24 63 69 28   set parent $ci(
1f40: 70 61 72 65 6e 74 5f 70 61 67 65 5f 6e 6f 29 0a  parent_page_no).
1f50: 20 20 20 20 20 20 66 6f 72 20 7b 73 65 74 20 75        for {set u
1f60: 70 20 31 7d 20 5c 0a 20 20 20 20 20 20 20 20 20  p 1} \.         
1f70: 20 7b 24 63 69 28 70 61 72 65 6e 74 29 21 3d 30   {$ci(parent)!=0
1f80: 20 26 26 20 21 5b 69 6e 66 6f 20 65 78 69 73 74   && ![info exist
1f90: 73 20 73 65 65 6e 28 24 63 69 28 70 61 72 65 6e  s seen($ci(paren
1fa0: 74 29 29 5d 7d 20 7b 69 6e 63 72 20 75 70 7d 20  t))]} {incr up} 
1fb0: 5c 0a 20 20 20 20 20 20 7b 0a 20 20 20 20 20 20  \.      {.      
1fc0: 20 20 23 20 4d 61 72 6b 20 74 68 65 20 70 61 72    # Mark the par
1fd0: 65 6e 74 20 61 73 20 73 65 65 6e 2e 0a 20 20 20  ent as seen..   
1fe0: 20 20 20 20 20 23 0a 20 20 20 20 20 20 20 20 73       #.        s
1ff0: 65 74 20 73 65 65 6e 28 24 63 69 28 70 61 72 65  et seen($ci(pare
2000: 6e 74 29 29 20 31 0a 0a 20 20 20 20 20 20 20 20  nt)) 1..        
2010: 23 20 52 65 74 72 69 65 76 65 20 69 6e 66 6f 20  # Retrieve info 
2020: 66 6f 72 20 74 68 65 20 70 61 72 65 6e 74 20 61  for the parent a
2030: 6e 64 20 75 70 64 61 74 65 20 73 74 61 74 69 73  nd update statis
2040: 74 69 63 73 2e 0a 20 20 20 20 20 20 20 20 63 75  tics..        cu
2050: 72 73 6f 72 5f 69 6e 66 6f 20 63 69 20 24 63 73  rsor_info ci $cs
2060: 72 20 24 75 70 0a 20 20 20 20 20 20 20 20 69 6e  r $up.        in
2070: 63 72 20 69 6e 74 5f 70 61 67 65 73 0a 20 20 20  cr int_pages.   
2080: 20 20 20 20 20 69 6e 63 72 20 63 6e 74 5f 69 6e       incr cnt_in
2090: 74 5f 65 6e 74 72 79 20 24 63 69 28 70 61 67 65  t_entry $ci(page
20a0: 5f 65 6e 74 72 69 65 73 29 0a 20 20 20 20 20 20  _entries).      
20b0: 20 20 69 6e 63 72 20 75 6e 75 73 65 64 5f 69 6e    incr unused_in
20c0: 74 20 24 63 69 28 70 61 67 65 5f 66 72 65 65 62  t $ci(page_freeb
20d0: 79 74 65 73 29 0a 0a 20 20 20 20 20 20 20 20 23  ytes)..        #
20e0: 20 70 61 72 65 6e 74 20 70 61 67 65 73 20 63 6f   parent pages co
20f0: 6d 65 20 62 65 66 6f 72 65 20 74 68 65 69 72 20  me before their 
2100: 66 69 72 73 74 20 63 68 69 6c 64 0a 20 20 20 20  first child.    
2110: 20 20 20 20 73 65 74 20 70 67 6c 69 73 74 20 22      set pglist "
2120: 24 63 69 28 70 61 67 65 5f 6e 6f 29 20 24 70 67  $ci(page_no) $pg
2130: 6c 69 73 74 22 0a 20 20 20 20 20 20 7d 0a 20 20  list".      }.  
2140: 20 20 7d 0a 0a 20 20 20 20 23 20 43 68 65 63 6b    }..    # Check
2150: 20 74 68 65 20 70 61 67 65 20 6c 69 73 74 20 66   the page list f
2160: 6f 72 20 66 72 61 67 6d 65 6e 74 61 74 69 6f 6e  or fragmentation
2170: 0a 20 20 20 20 23 0a 20 20 20 20 66 6f 72 65 61  .    #.    forea
2180: 63 68 20 70 67 20 24 70 67 6c 69 73 74 20 7b 0a  ch pg $pglist {.
2190: 20 20 20 20 20 20 69 66 20 7b 24 70 67 21 3d 24        if {$pg!=$
21a0: 70 72 65 76 5f 70 67 6e 6f 2b 31 20 26 26 20 24  prev_pgno+1 && $
21b0: 70 72 65 76 5f 70 67 6e 6f 3e 30 7d 20 7b 0a 20  prev_pgno>0} {. 
21c0: 20 20 20 20 20 20 20 69 6e 63 72 20 67 61 70 5f         incr gap_
21d0: 63 6e 74 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  cnt.      }.    
21e0: 20 20 73 65 74 20 70 72 65 76 5f 70 67 6e 6f 20    set prev_pgno 
21f0: 24 70 67 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  $pg.    }.  }.  
2200: 62 74 72 65 65 5f 63 6c 6f 73 65 5f 63 75 72 73  btree_close_curs
2210: 6f 72 20 24 63 73 72 0a 0a 20 20 23 20 48 61 6e  or $csr..  # Han
2220: 64 6c 65 20 74 68 65 20 73 70 65 63 69 61 6c 20  dle the special 
2230: 63 61 73 65 20 77 68 65 72 65 20 61 20 74 61 62  case where a tab
2240: 6c 65 20 63 6f 6e 74 61 69 6e 73 20 6e 6f 20 64  le contains no d
2250: 61 74 61 2e 20 49 6e 20 74 68 69 73 20 63 61 73  ata. In this cas
2260: 65 0a 20 20 23 20 61 6c 6c 20 73 74 61 74 69 73  e.  # all statis
2270: 74 69 63 73 20 61 72 65 20 7a 65 72 6f 2c 20 65  tics are zero, e
2280: 78 63 65 70 74 20 66 6f 72 20 74 68 65 20 6e 75  xcept for the nu
2290: 6d 62 65 72 20 6f 66 20 6c 65 61 66 20 70 61 67  mber of leaf pag
22a0: 65 73 20 28 31 29 20 61 6e 64 0a 20 20 23 20 74  es (1) and.  # t
22b0: 68 65 20 75 6e 75 73 65 64 20 62 79 74 65 73 20  he unused bytes 
22c0: 6f 6e 20 6c 65 61 66 20 70 61 67 65 73 20 28 24  on leaf pages ($
22d0: 70 61 67 65 53 69 7a 65 20 2d 20 38 29 2e 0a 20  pageSize - 8).. 
22e0: 20 23 0a 20 20 23 20 41 6e 20 65 78 63 65 70 74   #.  # An except
22f0: 69 6f 6e 20 74 6f 20 74 68 65 20 61 62 6f 76 65  ion to the above
2300: 20 69 73 20 74 68 65 20 73 71 6c 69 74 65 5f 6d   is the sqlite_m
2310: 61 73 74 65 72 20 74 61 62 6c 65 2e 20 49 66 20  aster table. If 
2320: 69 74 20 69 73 20 65 6d 70 74 79 0a 20 20 23 20  it is empty.  # 
2330: 74 68 65 6e 20 61 6c 6c 20 73 74 61 74 69 73 74  then all statist
2340: 69 63 73 20 61 72 65 20 7a 65 72 6f 20 65 78 63  ics are zero exc
2350: 65 70 74 20 66 6f 72 20 74 68 65 20 6e 75 6d 62  ept for the numb
2360: 65 72 20 6f 66 20 6c 65 61 66 20 70 61 67 65 73  er of leaf pages
2370: 20 28 31 29 2c 0a 20 20 23 20 61 6e 64 20 74 68   (1),.  # and th
2380: 65 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e 75 73  e number of unus
2390: 65 64 20 62 79 74 65 73 20 6f 6e 20 6c 65 61 66  ed bytes on leaf
23a0: 20 70 61 67 65 73 20 28 24 70 61 67 65 53 69 7a   pages ($pageSiz
23b0: 65 20 2d 20 31 31 32 29 2e 0a 20 20 23 0a 20 20  e - 112)..  #.  
23c0: 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 5b 61 72  if {[llength [ar
23d0: 72 61 79 20 6e 61 6d 65 73 20 73 65 65 6e 5d 5d  ray names seen]]
23e0: 3d 3d 30 7d 20 7b 0a 20 20 20 20 73 65 74 20 6c  ==0} {.    set l
23f0: 65 61 66 5f 70 61 67 65 73 20 31 0a 20 20 20 20  eaf_pages 1.    
2400: 69 66 20 7b 24 72 6f 6f 74 70 61 67 65 3d 3d 31  if {$rootpage==1
2410: 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 75 6e  } {.      set un
2420: 75 73 65 64 5f 6c 65 61 66 20 5b 65 78 70 72 20  used_leaf [expr 
2430: 7b 24 70 61 67 65 53 69 7a 65 2d 31 31 32 7d 5d  {$pageSize-112}]
2440: 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  .    } else {.  
2450: 20 20 20 20 73 65 74 20 75 6e 75 73 65 64 5f 6c      set unused_l
2460: 65 61 66 20 5b 65 78 70 72 20 7b 24 70 61 67 65  eaf [expr {$page
2470: 53 69 7a 65 2d 38 7d 5d 0a 20 20 20 20 7d 0a 20  Size-8}].    }. 
2480: 20 7d 0a 0a 20 20 23 20 49 6e 73 65 72 74 20 74   }..  # Insert t
2490: 68 65 20 73 74 61 74 69 73 74 69 63 73 20 66 6f  he statistics fo
24a0: 72 20 74 68 65 20 74 61 62 6c 65 20 61 6e 61 6c  r the table anal
24b0: 79 7a 65 64 20 69 6e 74 6f 20 74 68 65 20 69 6e  yzed into the in
24c0: 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62 61 73 65  -memory database
24d0: 2e 0a 20 20 23 0a 20 20 73 65 74 20 73 71 6c 20  ..  #.  set sql 
24e0: 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 73 70 61  "INSERT INTO spa
24f0: 63 65 5f 75 73 65 64 20 56 41 4c 55 45 53 28 22  ce_used VALUES("
2500: 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 5b 71  .  append sql [q
2510: 75 6f 74 65 20 24 6e 61 6d 65 5d 0a 20 20 61 70  uote $name].  ap
2520: 70 65 6e 64 20 73 71 6c 20 22 2c 5b 71 75 6f 74  pend sql ",[quot
2530: 65 20 24 6e 61 6d 65 5d 22 0a 20 20 61 70 70 65  e $name]".  appe
2540: 6e 64 20 73 71 6c 20 22 2c 30 22 0a 20 20 61 70  nd sql ",0".  ap
2550: 70 65 6e 64 20 73 71 6c 20 22 2c 5b 65 78 70 72  pend sql ",[expr
2560: 20 7b 24 63 6e 74 5f 6c 65 61 66 5f 65 6e 74 72   {$cnt_leaf_entr
2570: 79 2b 24 63 6e 74 5f 69 6e 74 5f 65 6e 74 72 79  y+$cnt_int_entry
2580: 7d 5d 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c  }]".  append sql
2590: 20 22 2c 24 63 6e 74 5f 6c 65 61 66 5f 65 6e 74   ",$cnt_leaf_ent
25a0: 72 79 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c  ry".  append sql
25b0: 20 22 2c 24 74 6f 74 61 6c 5f 70 61 79 6c 6f 61   ",$total_payloa
25c0: 64 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20  d".  append sql 
25d0: 22 2c 24 74 6f 74 61 6c 5f 6f 76 66 6c 22 0a 20  ",$total_ovfl". 
25e0: 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 63   append sql ",$c
25f0: 6e 74 5f 6f 76 66 6c 22 0a 20 20 61 70 70 65 6e  nt_ovfl".  appen
2600: 64 20 73 71 6c 20 22 2c 24 6d 78 5f 70 61 79 6c  d sql ",$mx_payl
2610: 6f 61 64 22 0a 20 20 61 70 70 65 6e 64 20 73 71  oad".  append sq
2620: 6c 20 22 2c 24 69 6e 74 5f 70 61 67 65 73 22 0a  l ",$int_pages".
2630: 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 24    append sql ",$
2640: 6c 65 61 66 5f 70 61 67 65 73 22 0a 20 20 61 70  leaf_pages".  ap
2650: 70 65 6e 64 20 73 71 6c 20 22 2c 24 6f 76 66 6c  pend sql ",$ovfl
2660: 5f 70 61 67 65 73 22 0a 20 20 61 70 70 65 6e 64  _pages".  append
2670: 20 73 71 6c 20 22 2c 24 75 6e 75 73 65 64 5f 69   sql ",$unused_i
2680: 6e 74 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c  nt".  append sql
2690: 20 22 2c 24 75 6e 75 73 65 64 5f 6c 65 61 66 22   ",$unused_leaf"
26a0: 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c  .  append sql ",
26b0: 24 75 6e 75 73 65 64 5f 6f 76 66 6c 22 0a 20 20  $unused_ovfl".  
26c0: 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 67 61  append sql ",$ga
26d0: 70 5f 63 6e 74 22 0a 20 20 61 70 70 65 6e 64 20  p_cnt".  append 
26e0: 73 71 6c 20 29 3b 0a 20 20 6d 65 6d 20 65 76 61  sql );.  mem eva
26f0: 6c 20 24 73 71 6c 0a 7d 0a 0a 23 20 41 6e 61 6c  l $sql.}..# Anal
2700: 79 7a 65 20 65 76 65 72 79 20 69 6e 64 65 78 20  yze every index 
2710: 69 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 2c  in the database,
2720: 20 6f 6e 65 20 61 74 20 61 20 74 69 6d 65 2e 0a   one at a time..
2730: 23 0a 23 20 54 68 65 20 71 75 65 72 79 20 62 65  #.# The query be
2740: 6c 6f 77 20 72 65 74 75 72 6e 73 20 74 68 65 20  low returns the 
2750: 6e 61 6d 65 2c 20 61 73 73 6f 63 69 61 74 65 64  name, associated
2760: 20 74 61 62 6c 65 20 61 6e 64 20 72 6f 6f 74 2d   table and root-
2770: 70 61 67 65 20 6e 75 6d 62 65 72 20 0a 23 20 66  page number .# f
2780: 6f 72 20 65 76 65 72 79 20 69 6e 64 65 78 20 69  or every index i
2790: 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a  n the database..
27a0: 23 0a 73 65 74 20 73 71 6c 20 7b 0a 20 20 53 45  #.set sql {.  SE
27b0: 4c 45 43 54 20 6e 61 6d 65 2c 20 74 62 6c 5f 6e  LECT name, tbl_n
27c0: 61 6d 65 2c 20 72 6f 6f 74 70 61 67 65 20 46 52  ame, rootpage FR
27d0: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
27e0: 20 57 48 45 52 45 20 74 79 70 65 3d 27 69 6e 64   WHERE type='ind
27f0: 65 78 27 0a 20 20 4f 52 44 45 52 20 42 59 20 32  ex'.  ORDER BY 2
2800: 2c 20 31 0a 7d 0a 66 6f 72 65 61 63 68 20 7b 6e  , 1.}.foreach {n
2810: 61 6d 65 20 74 62 6c 5f 6e 61 6d 65 20 72 6f 6f  ame tbl_name roo
2820: 74 70 61 67 65 7d 20 5b 64 62 20 65 76 61 6c 20  tpage} [db eval 
2830: 24 73 71 6c 5d 20 7b 0a 20 20 70 75 74 73 20 73  $sql] {.  puts s
2840: 74 64 65 72 72 20 22 41 6e 61 6c 79 7a 69 6e 67  tderr "Analyzing
2850: 20 69 6e 64 65 78 20 24 6e 61 6d 65 20 6f 66 20   index $name of 
2860: 74 61 62 6c 65 20 24 74 62 6c 5f 6e 61 6d 65 2e  table $tbl_name.
2870: 2e 2e 22 0a 0a 20 20 23 20 43 6f 64 65 20 62 65  .."..  # Code be
2880: 6c 6f 77 20 74 72 61 76 65 72 73 65 73 20 74 68  low traverses th
2890: 65 20 69 6e 64 65 78 20 62 65 69 6e 67 20 61 6e  e index being an
28a0: 61 6c 79 7a 65 64 20 28 69 6e 64 65 78 20 6e 61  alyzed (index na
28b0: 6d 65 20 24 6e 61 6d 65 29 2c 20 75 73 69 6e 67  me $name), using
28c0: 20 74 68 65 0a 20 20 23 20 62 74 72 65 65 20 63   the.  # btree c
28d0: 75 72 73 6f 72 20 24 63 75 72 73 6f 72 2e 20 53  ursor $cursor. S
28e0: 74 61 74 69 73 74 69 63 73 20 72 65 6c 61 74 65  tatistics relate
28f0: 64 20 74 6f 20 69 6e 64 65 78 20 24 6e 61 6d 65  d to index $name
2900: 20 61 72 65 20 61 63 63 75 6d 75 6c 61 74 65 64   are accumulated
2910: 20 69 6e 0a 20 20 23 20 74 68 65 20 66 6f 6c 6c   in.  # the foll
2920: 6f 77 69 6e 67 20 76 61 72 69 61 62 6c 65 73 3a  owing variables:
2930: 0a 20 20 23 0a 20 20 73 65 74 20 74 6f 74 61 6c  .  #.  set total
2940: 5f 70 61 79 6c 6f 61 64 20 24 77 69 64 65 5a 65  _payload $wideZe
2950: 72 6f 20 20 20 20 20 20 20 20 3b 23 20 50 61 79  ro        ;# Pay
2960: 6c 6f 61 64 20 73 70 61 63 65 20 75 73 65 64 20  load space used 
2970: 62 79 20 61 6c 6c 20 65 6e 74 72 69 65 73 0a 20  by all entries. 
2980: 20 73 65 74 20 74 6f 74 61 6c 5f 6f 76 66 6c 20   set total_ovfl 
2990: 24 77 69 64 65 5a 65 72 6f 20 20 20 20 20 20 20  $wideZero       
29a0: 20 20 20 20 3b 23 20 50 61 79 6c 6f 61 64 20 73      ;# Payload s
29b0: 70 61 63 65 20 6f 6e 20 6f 76 65 72 66 6c 6f 77  pace on overflow
29c0: 20 70 61 67 65 73 0a 20 20 73 65 74 20 75 6e 75   pages.  set unu
29d0: 73 65 64 5f 6c 65 61 66 20 24 77 69 64 65 5a 65  sed_leaf $wideZe
29e0: 72 6f 20 20 20 20 20 20 20 20 20 20 3b 23 20 55  ro          ;# U
29f0: 6e 75 73 65 64 20 73 70 61 63 65 20 6f 6e 20 6c  nused space on l
2a00: 65 61 66 20 6e 6f 64 65 73 0a 20 20 73 65 74 20  eaf nodes.  set 
2a10: 75 6e 75 73 65 64 5f 6f 76 66 6c 20 24 77 69 64  unused_ovfl $wid
2a20: 65 5a 65 72 6f 20 20 20 20 20 20 20 20 20 20 3b  eZero          ;
2a30: 23 20 55 6e 75 73 65 64 20 73 70 61 63 65 20 6f  # Unused space o
2a40: 6e 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73  n overflow pages
2a50: 0a 20 20 73 65 74 20 63 6e 74 5f 6f 76 66 6c 20  .  set cnt_ovfl 
2a60: 24 77 69 64 65 5a 65 72 6f 20 20 20 20 20 20 20  $wideZero       
2a70: 20 20 20 20 20 20 3b 23 20 4e 75 6d 62 65 72 20        ;# Number 
2a80: 6f 66 20 65 6e 74 72 69 65 73 20 74 68 61 74 20  of entries that 
2a90: 75 73 65 20 6f 76 65 72 66 6c 6f 77 73 0a 20 20  use overflows.  
2aa0: 73 65 74 20 63 6e 74 5f 6c 65 61 66 5f 65 6e 74  set cnt_leaf_ent
2ab0: 72 79 20 24 77 69 64 65 5a 65 72 6f 20 20 20 20  ry $wideZero    
2ac0: 20 20 20 3b 23 20 4e 75 6d 62 65 72 20 6f 66 20     ;# Number of 
2ad0: 6c 65 61 66 20 65 6e 74 72 69 65 73 0a 20 20 73  leaf entries.  s
2ae0: 65 74 20 6d 78 5f 70 61 79 6c 6f 61 64 20 24 77  et mx_payload $w
2af0: 69 64 65 5a 65 72 6f 20 20 20 20 20 20 20 20 20  ideZero         
2b00: 20 20 3b 23 20 4d 61 78 69 6d 75 6d 20 70 61 79    ;# Maximum pay
2b10: 6c 6f 61 64 20 73 69 7a 65 0a 20 20 73 65 74 20  load size.  set 
2b20: 6f 76 66 6c 5f 70 61 67 65 73 20 24 77 69 64 65  ovfl_pages $wide
2b30: 5a 65 72 6f 20 20 20 20 20 20 20 20 20 20 20 3b  Zero           ;
2b40: 23 20 4e 75 6d 62 65 72 20 6f 66 20 6f 76 65 72  # Number of over
2b50: 66 6c 6f 77 20 70 61 67 65 73 20 75 73 65 64 0a  flow pages used.
2b60: 20 20 73 65 74 20 6c 65 61 66 5f 70 61 67 65 73    set leaf_pages
2b70: 20 24 77 69 64 65 5a 65 72 6f 20 20 20 20 20 20   $wideZero      
2b80: 20 20 20 20 20 3b 23 20 4e 75 6d 62 65 72 20 6f       ;# Number o
2b90: 66 20 6c 65 61 66 20 70 61 67 65 73 0a 20 20 73  f leaf pages.  s
2ba0: 65 74 20 67 61 70 5f 63 6e 74 20 30 20 20 20 20  et gap_cnt 0    
2bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2bc0: 20 20 3b 23 20 4e 75 6d 62 65 72 20 6f 66 20 68    ;# Number of h
2bd0: 6f 6c 65 73 20 69 6e 20 74 68 65 20 70 61 67 65  oles in the page
2be0: 20 73 65 71 75 65 6e 63 65 0a 20 20 73 65 74 20   sequence.  set 
2bf0: 70 72 65 76 5f 70 67 6e 6f 20 30 20 20 20 20 20  prev_pgno 0     
2c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 3b                 ;
2c10: 23 20 4c 61 73 74 20 70 61 67 65 20 6e 75 6d 62  # Last page numb
2c20: 65 72 20 73 65 65 6e 0a 0a 20 20 23 20 41 73 20  er seen..  # As 
2c30: 74 68 65 20 62 74 72 65 65 20 69 73 20 74 72 61  the btree is tra
2c40: 76 65 72 73 65 64 2c 20 74 68 65 20 61 72 72 61  versed, the arra
2c50: 79 20 76 61 72 69 61 62 6c 65 20 24 73 65 65 6e  y variable $seen
2c60: 28 24 70 67 6e 6f 29 20 69 73 20 73 65 74 20 74  ($pgno) is set t
2c70: 6f 20 31 0a 20 20 23 20 74 68 65 20 66 69 72 73  o 1.  # the firs
2c80: 74 20 74 69 6d 65 20 70 61 67 65 20 24 70 67 6e  t time page $pgn
2c90: 6f 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65 64  o is encountered
2ca0: 2e 0a 20 20 23 0a 20 20 63 61 74 63 68 20 7b 75  ..  #.  catch {u
2cb0: 6e 73 65 74 20 73 65 65 6e 7d 0a 0a 20 20 23 20  nset seen}..  # 
2cc0: 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6c 6f  The following lo
2cd0: 6f 70 20 72 75 6e 73 20 6f 6e 63 65 20 66 6f 72  op runs once for
2ce0: 20 65 61 63 68 20 65 6e 74 72 79 20 69 6e 20 69   each entry in i
2cf0: 6e 64 65 78 20 24 6e 61 6d 65 2e 20 54 68 65 20  ndex $name. The 
2d00: 69 6e 64 65 78 0a 20 20 23 20 69 73 20 74 72 61  index.  # is tra
2d10: 76 65 72 73 65 64 20 75 73 69 6e 67 20 74 68 65  versed using the
2d20: 20 62 74 72 65 65 20 63 75 72 73 6f 72 20 73 74   btree cursor st
2d30: 6f 72 65 64 20 69 6e 20 76 61 72 69 61 62 6c 65  ored in variable
2d40: 20 24 63 73 72 0a 20 20 23 0a 20 20 73 65 74 20   $csr.  #.  set 
2d50: 63 73 72 20 5b 62 74 72 65 65 5f 63 75 72 73 6f  csr [btree_curso
2d60: 72 20 24 44 42 20 24 72 6f 6f 74 70 61 67 65 20  r $DB $rootpage 
2d70: 30 5d 0a 20 20 66 6f 72 20 7b 62 74 72 65 65 5f  0].  for {btree_
2d80: 66 69 72 73 74 20 24 63 73 72 7d 20 7b 21 5b 62  first $csr} {![b
2d90: 74 72 65 65 5f 65 6f 66 20 24 63 73 72 5d 7d 20  tree_eof $csr]} 
2da0: 7b 62 74 72 65 65 5f 6e 65 78 74 20 24 63 73 72  {btree_next $csr
2db0: 7d 20 7b 0a 20 20 20 20 69 6e 63 72 20 63 6e 74  } {.    incr cnt
2dc0: 5f 6c 65 61 66 5f 65 6e 74 72 79 0a 0a 20 20 20  _leaf_entry..   
2dd0: 20 23 20 52 65 74 72 69 65 76 65 20 69 6e 66 6f   # Retrieve info
2de0: 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 74 68  rmation about th
2df0: 65 20 65 6e 74 72 79 20 74 68 65 20 62 74 72 65  e entry the btre
2e00: 65 2d 63 75 72 73 6f 72 20 70 6f 69 6e 74 73 20  e-cursor points 
2e10: 74 6f 20 69 6e 74 6f 0a 20 20 20 20 23 20 74 68  to into.    # th
2e20: 65 20 61 72 72 61 79 20 76 61 72 69 61 62 6c 65  e array variable
2e30: 20 24 63 69 20 28 63 75 72 73 6f 72 20 69 6e 66   $ci (cursor inf
2e40: 6f 29 2e 0a 20 20 20 20 23 0a 20 20 20 20 63 75  o)..    #.    cu
2e50: 72 73 6f 72 5f 69 6e 66 6f 20 63 69 20 24 63 73  rsor_info ci $cs
2e60: 72 0a 0a 20 20 20 20 23 20 43 68 65 63 6b 20 69  r..    # Check i
2e70: 66 20 74 68 65 20 70 61 79 6c 6f 61 64 20 6f 66  f the payload of
2e80: 20 74 68 69 73 20 65 6e 74 72 79 20 69 73 20 67   this entry is g
2e90: 72 65 61 74 65 72 20 74 68 61 6e 20 74 68 65 20  reater than the 
2ea0: 63 75 72 72 65 6e 74 20 0a 20 20 20 20 23 20 24  current .    # $
2eb0: 6d 78 5f 70 61 79 6c 6f 61 64 20 73 74 61 74 69  mx_payload stati
2ec0: 73 74 69 63 20 66 6f 72 20 74 68 65 20 74 61 62  stic for the tab
2ed0: 6c 65 2e 20 41 6c 73 6f 20 69 6e 63 72 65 61 73  le. Also increas
2ee0: 65 20 74 68 65 20 24 74 6f 74 61 6c 5f 70 61 79  e the $total_pay
2ef0: 6c 6f 61 64 0a 20 20 20 20 23 20 73 74 61 74 69  load.    # stati
2f00: 73 74 69 63 2e 0a 20 20 20 20 23 0a 20 20 20 20  stic..    #.    
2f10: 73 65 74 20 70 61 79 6c 6f 61 64 20 5b 62 74 72  set payload [btr
2f20: 65 65 5f 6b 65 79 73 69 7a 65 20 24 63 73 72 5d  ee_keysize $csr]
2f30: 0a 20 20 20 20 69 66 20 7b 24 70 61 79 6c 6f 61  .    if {$payloa
2f40: 64 3e 24 6d 78 5f 70 61 79 6c 6f 61 64 7d 20 7b  d>$mx_payload} {
2f50: 73 65 74 20 6d 78 5f 70 61 79 6c 6f 61 64 20 24  set mx_payload $
2f60: 70 61 79 6c 6f 61 64 7d 0a 20 20 20 20 69 6e 63  payload}.    inc
2f70: 72 20 74 6f 74 61 6c 5f 70 61 79 6c 6f 61 64 20  r total_payload 
2f80: 24 70 61 79 6c 6f 61 64 0a 0a 20 20 20 20 23 20  $payload..    # 
2f90: 49 66 20 74 68 69 73 20 65 6e 74 72 79 20 75 73  If this entry us
2fa0: 65 73 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65  es overflow page
2fb0: 73 2c 20 74 68 65 6e 20 75 70 64 61 74 65 20 74  s, then update t
2fc0: 68 65 20 24 63 6e 74 5f 6f 76 66 6c 2c 20 0a 20  he $cnt_ovfl, . 
2fd0: 20 20 20 23 20 24 74 6f 74 61 6c 5f 6f 76 66 6c     # $total_ovfl
2fe0: 2c 20 24 6f 76 66 6c 5f 70 61 67 65 73 20 61 6e  , $ovfl_pages an
2ff0: 64 20 24 75 6e 75 73 65 64 5f 6f 76 66 6c 20 73  d $unused_ovfl s
3000: 74 61 74 69 73 74 69 63 73 2e 0a 20 20 20 20 23  tatistics..    #
3010: 0a 20 20 20 20 73 65 74 20 6f 76 66 6c 20 5b 65  .    set ovfl [e
3020: 78 70 72 20 7b 24 70 61 79 6c 6f 61 64 2d 24 63  xpr {$payload-$c
3030: 69 28 6c 6f 63 61 6c 5f 70 61 79 6c 6f 61 64 5f  i(local_payload_
3040: 62 79 74 65 73 29 7d 5d 0a 20 20 20 20 69 66 20  bytes)}].    if 
3050: 7b 24 6f 76 66 6c 7d 20 7b 0a 20 20 20 20 20 20  {$ovfl} {.      
3060: 69 6e 63 72 20 63 6e 74 5f 6f 76 66 6c 0a 20 20  incr cnt_ovfl.  
3070: 20 20 20 20 69 6e 63 72 20 74 6f 74 61 6c 5f 6f      incr total_o
3080: 76 66 6c 20 24 6f 76 66 6c 0a 20 20 20 20 20 20  vfl $ovfl.      
3090: 73 65 74 20 6e 20 5b 65 78 70 72 20 7b 69 6e 74  set n [expr {int
30a0: 28 63 65 69 6c 28 24 6f 76 66 6c 2f 28 24 70 61  (ceil($ovfl/($pa
30b0: 67 65 53 69 7a 65 2d 34 2e 30 29 29 29 7d 5d 0a  geSize-4.0)))}].
30c0: 20 20 20 20 20 20 69 6e 63 72 20 6f 76 66 6c 5f        incr ovfl_
30d0: 70 61 67 65 73 20 24 6e 0a 20 20 20 20 20 20 69  pages $n.      i
30e0: 6e 63 72 20 75 6e 75 73 65 64 5f 6f 76 66 6c 20  ncr unused_ovfl 
30f0: 5b 65 78 70 72 20 7b 24 6e 2a 28 24 70 61 67 65  [expr {$n*($page
3100: 53 69 7a 65 2d 34 29 20 2d 20 24 6f 76 66 6c 7d  Size-4) - $ovfl}
3110: 5d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 49  ].    }..    # I
3120: 66 20 74 68 69 73 20 69 73 20 74 68 65 20 66 69  f this is the fi
3130: 72 73 74 20 74 61 62 6c 65 20 65 6e 74 72 79 20  rst table entry 
3140: 61 6e 61 6c 79 7a 65 64 20 66 6f 72 20 74 68 65  analyzed for the
3150: 20 70 61 67 65 2c 20 74 68 65 6e 20 75 70 64 61   page, then upda
3160: 74 65 0a 20 20 20 20 23 20 74 68 65 20 70 61 67  te.    # the pag
3170: 65 2d 72 65 6c 61 74 65 64 20 73 74 61 74 69 73  e-related statis
3180: 74 69 63 73 20 24 6c 65 61 66 5f 70 61 67 65 73  tics $leaf_pages
3190: 20 61 6e 64 20 24 75 6e 75 73 65 64 5f 6c 65 61   and $unused_lea
31a0: 66 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66 20  f..    #.    if 
31b0: 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 73  {![info exists s
31c0: 65 65 6e 28 24 63 69 28 70 61 67 65 5f 6e 6f 29  een($ci(page_no)
31d0: 29 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20  )]} {.      set 
31e0: 73 65 65 6e 28 24 63 69 28 70 61 67 65 5f 6e 6f  seen($ci(page_no
31f0: 29 29 20 31 0a 20 20 20 20 20 20 69 6e 63 72 20  )) 1.      incr 
3200: 6c 65 61 66 5f 70 61 67 65 73 0a 20 20 20 20 20  leaf_pages.     
3210: 20 69 6e 63 72 20 75 6e 75 73 65 64 5f 6c 65 61   incr unused_lea
3220: 66 20 24 63 69 28 70 61 67 65 5f 66 72 65 65 62  f $ci(page_freeb
3230: 79 74 65 73 29 0a 20 20 20 20 20 20 73 65 74 20  ytes).      set 
3240: 70 67 20 24 63 69 28 70 61 67 65 5f 6e 6f 29 0a  pg $ci(page_no).
3250: 20 20 20 20 20 20 69 66 20 7b 24 70 72 65 76 5f        if {$prev_
3260: 70 67 6e 6f 3e 30 20 26 26 20 24 70 67 21 3d 24  pgno>0 && $pg!=$
3270: 70 72 65 76 5f 70 67 6e 6f 2b 31 7d 20 7b 0a 20  prev_pgno+1} {. 
3280: 20 20 20 20 20 20 20 69 6e 63 72 20 67 61 70 5f         incr gap_
3290: 63 6e 74 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  cnt.      }.    
32a0: 20 20 73 65 74 20 70 72 65 76 5f 70 67 6e 6f 20    set prev_pgno 
32b0: 24 63 69 28 70 61 67 65 5f 6e 6f 29 0a 20 20 20  $ci(page_no).   
32c0: 20 7d 0a 20 20 7d 0a 20 20 62 74 72 65 65 5f 63   }.  }.  btree_c
32d0: 6c 6f 73 65 5f 63 75 72 73 6f 72 20 24 63 73 72  lose_cursor $csr
32e0: 0a 0a 20 20 23 20 48 61 6e 64 6c 65 20 74 68 65  ..  # Handle the
32f0: 20 73 70 65 63 69 61 6c 20 63 61 73 65 20 77 68   special case wh
3300: 65 72 65 20 61 20 69 6e 64 65 78 20 63 6f 6e 74  ere a index cont
3310: 61 69 6e 73 20 6e 6f 20 64 61 74 61 2e 20 49 6e  ains no data. In
3320: 20 74 68 69 73 20 63 61 73 65 0a 20 20 23 20 61   this case.  # a
3330: 6c 6c 20 73 74 61 74 69 73 74 69 63 73 20 61 72  ll statistics ar
3340: 65 20 7a 65 72 6f 2c 20 65 78 63 65 70 74 20 66  e zero, except f
3350: 6f 72 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  or the number of
3360: 20 6c 65 61 66 20 70 61 67 65 73 20 28 31 29 20   leaf pages (1) 
3370: 61 6e 64 0a 20 20 23 20 74 68 65 20 75 6e 75 73  and.  # the unus
3380: 65 64 20 62 79 74 65 73 20 6f 6e 20 6c 65 61 66  ed bytes on leaf
3390: 20 70 61 67 65 73 20 28 24 70 61 67 65 53 69 7a   pages ($pageSiz
33a0: 65 20 2d 20 38 29 2e 0a 20 20 23 0a 20 20 69 66  e - 8)..  #.  if
33b0: 20 7b 5b 6c 6c 65 6e 67 74 68 20 5b 61 72 72 61   {[llength [arra
33c0: 79 20 6e 61 6d 65 73 20 73 65 65 6e 5d 5d 3d 3d  y names seen]]==
33d0: 30 7d 20 7b 0a 20 20 20 20 73 65 74 20 6c 65 61  0} {.    set lea
33e0: 66 5f 70 61 67 65 73 20 31 0a 20 20 20 20 73 65  f_pages 1.    se
33f0: 74 20 75 6e 75 73 65 64 5f 6c 65 61 66 20 5b 65  t unused_leaf [e
3400: 78 70 72 20 7b 24 70 61 67 65 53 69 7a 65 2d 38  xpr {$pageSize-8
3410: 7d 5d 0a 20 20 7d 0a 0a 20 20 23 20 49 6e 73 65  }].  }..  # Inse
3420: 72 74 20 74 68 65 20 73 74 61 74 69 73 74 69 63  rt the statistic
3430: 73 20 66 6f 72 20 74 68 65 20 69 6e 64 65 78 20  s for the index 
3440: 61 6e 61 6c 79 7a 65 64 20 69 6e 74 6f 20 74 68  analyzed into th
3450: 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61  e in-memory data
3460: 62 61 73 65 2e 0a 20 20 23 0a 20 20 73 65 74 20  base..  #.  set 
3470: 73 71 6c 20 22 49 4e 53 45 52 54 20 49 4e 54 4f  sql "INSERT INTO
3480: 20 73 70 61 63 65 5f 75 73 65 64 20 56 41 4c 55   space_used VALU
3490: 45 53 28 22 0a 20 20 61 70 70 65 6e 64 20 73 71  ES(".  append sq
34a0: 6c 20 5b 71 75 6f 74 65 20 24 6e 61 6d 65 5d 0a  l [quote $name].
34b0: 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 5b    append sql ",[
34c0: 71 75 6f 74 65 20 24 74 62 6c 5f 6e 61 6d 65 5d  quote $tbl_name]
34d0: 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22  ".  append sql "
34e0: 2c 31 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c  ,1".  append sql
34f0: 20 22 2c 24 63 6e 74 5f 6c 65 61 66 5f 65 6e 74   ",$cnt_leaf_ent
3500: 72 79 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c  ry".  append sql
3510: 20 22 2c 24 63 6e 74 5f 6c 65 61 66 5f 65 6e 74   ",$cnt_leaf_ent
3520: 72 79 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c  ry".  append sql
3530: 20 22 2c 24 74 6f 74 61 6c 5f 70 61 79 6c 6f 61   ",$total_payloa
3540: 64 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20  d".  append sql 
3550: 22 2c 24 74 6f 74 61 6c 5f 6f 76 66 6c 22 0a 20  ",$total_ovfl". 
3560: 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 63   append sql ",$c
3570: 6e 74 5f 6f 76 66 6c 22 0a 20 20 61 70 70 65 6e  nt_ovfl".  appen
3580: 64 20 73 71 6c 20 22 2c 24 6d 78 5f 70 61 79 6c  d sql ",$mx_payl
3590: 6f 61 64 22 0a 20 20 61 70 70 65 6e 64 20 73 71  oad".  append sq
35a0: 6c 20 22 2c 30 22 0a 20 20 61 70 70 65 6e 64 20  l ",0".  append 
35b0: 73 71 6c 20 22 2c 24 6c 65 61 66 5f 70 61 67 65  sql ",$leaf_page
35c0: 73 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20  s".  append sql 
35d0: 22 2c 24 6f 76 66 6c 5f 70 61 67 65 73 22 0a 20  ",$ovfl_pages". 
35e0: 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 30 22   append sql ",0"
35f0: 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c  .  append sql ",
3600: 24 75 6e 75 73 65 64 5f 6c 65 61 66 22 0a 20 20  $unused_leaf".  
3610: 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 75 6e  append sql ",$un
3620: 75 73 65 64 5f 6f 76 66 6c 22 0a 20 20 61 70 70  used_ovfl".  app
3630: 65 6e 64 20 73 71 6c 20 22 2c 24 67 61 70 5f 63  end sql ",$gap_c
3640: 6e 74 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c  nt".  append sql
3650: 20 29 3b 0a 20 20 6d 65 6d 20 65 76 61 6c 20 24   );.  mem eval $
3660: 73 71 6c 0a 7d 0a 0a 23 20 47 65 6e 65 72 61 74  sql.}..# Generat
3670: 65 20 61 20 73 69 6e 67 6c 65 20 6c 69 6e 65 20  e a single line 
3680: 6f 66 20 6f 75 74 70 75 74 20 69 6e 20 74 68 65  of output in the
3690: 20 73 74 61 74 69 73 74 69 63 73 20 73 65 63 74   statistics sect
36a0: 69 6f 6e 20 6f 66 20 74 68 65 0a 23 20 72 65 70  ion of the.# rep
36b0: 6f 72 74 2e 0a 23 0a 70 72 6f 63 20 73 74 61 74  ort..#.proc stat
36c0: 6c 69 6e 65 20 7b 74 69 74 6c 65 20 76 61 6c 75  line {title valu
36d0: 65 20 7b 65 78 74 72 61 20 7b 7d 7d 7d 20 7b 0a  e {extra {}}} {.
36e0: 20 20 73 65 74 20 6c 65 6e 20 5b 73 74 72 69 6e    set len [strin
36f0: 67 20 6c 65 6e 67 74 68 20 24 74 69 74 6c 65 5d  g length $title]
3700: 0a 20 20 73 65 74 20 64 6f 74 73 20 5b 73 74 72  .  set dots [str
3710: 69 6e 67 20 72 61 6e 67 65 20 7b 2e 2e 2e 2e 2e  ing range {.....
3720: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e  ................
3730: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e  ................
3740: 2e 7d 20 24 6c 65 6e 20 65 6e 64 5d 0a 20 20 73  .} $len end].  s
3750: 65 74 20 6c 65 6e 20 5b 73 74 72 69 6e 67 20 6c  et len [string l
3760: 65 6e 67 74 68 20 24 76 61 6c 75 65 5d 0a 20 20  ength $value].  
3770: 73 65 74 20 73 70 32 20 5b 73 74 72 69 6e 67 20  set sp2 [string 
3780: 72 61 6e 67 65 20 7b 20 20 20 20 20 20 20 20 20  range {         
3790: 20 7d 20 24 6c 65 6e 20 65 6e 64 5d 0a 20 20 69   } $len end].  i
37a0: 66 20 7b 24 65 78 74 72 61 20 6e 65 20 22 22 7d  f {$extra ne ""}
37b0: 20 7b 0a 20 20 20 20 73 65 74 20 65 78 74 72 61   {.    set extra
37c0: 20 22 20 24 65 78 74 72 61 22 0a 20 20 7d 0a 20   " $extra".  }. 
37d0: 20 70 75 74 73 20 22 24 74 69 74 6c 65 24 64 6f   puts "$title$do
37e0: 74 73 20 24 76 61 6c 75 65 24 73 70 32 24 65 78  ts $value$sp2$ex
37f0: 74 72 61 22 0a 7d 0a 0a 23 20 47 65 6e 65 72 61  tra".}..# Genera
3800: 74 65 20 61 20 66 6f 72 6d 61 74 74 65 64 20 70  te a formatted p
3810: 65 72 63 65 6e 74 61 67 65 20 76 61 6c 75 65 20  ercentage value 
3820: 66 6f 72 20 24 6e 75 6d 2f 24 64 65 6e 6f 6d 0a  for $num/$denom.
3830: 23 0a 70 72 6f 63 20 70 65 72 63 65 6e 74 20 7b  #.proc percent {
3840: 6e 75 6d 20 64 65 6e 6f 6d 20 7b 6f 66 20 7b 7d  num denom {of {}
3850: 7d 7d 20 7b 0a 20 20 69 66 20 7b 24 64 65 6e 6f  }} {.  if {$deno
3860: 6d 3d 3d 30 2e 30 7d 20 7b 72 65 74 75 72 6e 20  m==0.0} {return 
3870: 22 22 7d 0a 20 20 73 65 74 20 76 20 5b 65 78 70  ""}.  set v [exp
3880: 72 20 7b 24 6e 75 6d 2a 31 30 30 2e 30 2f 24 64  r {$num*100.0/$d
3890: 65 6e 6f 6d 7d 5d 0a 20 20 73 65 74 20 6f 66 20  enom}].  set of 
38a0: 7b 7d 0a 20 20 69 66 20 7b 24 76 3d 3d 31 30 30  {}.  if {$v==100
38b0: 2e 30 20 7c 7c 20 24 76 3c 30 2e 30 30 31 20 7c  .0 || $v<0.001 |
38c0: 7c 20 28 24 76 3e 31 2e 30 20 26 26 20 24 76 3c  | ($v>1.0 && $v<
38d0: 39 39 2e 30 29 7d 20 7b 0a 20 20 20 20 72 65 74  99.0)} {.    ret
38e0: 75 72 6e 20 5b 66 6f 72 6d 61 74 20 7b 25 35 2e  urn [format {%5.
38f0: 31 66 25 25 20 25 73 7d 20 24 76 20 24 6f 66 5d  1f%% %s} $v $of]
3900: 0a 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 76 3c  .  } elseif {$v<
3910: 30 2e 31 20 7c 7c 20 24 76 3e 39 39 2e 39 7d 20  0.1 || $v>99.9} 
3920: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 5b 66 6f  {.    return [fo
3930: 72 6d 61 74 20 7b 25 37 2e 33 66 25 25 20 25 73  rmat {%7.3f%% %s
3940: 7d 20 24 76 20 24 6f 66 5d 0a 20 20 7d 20 65 6c  } $v $of].  } el
3950: 73 65 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  se {.    return 
3960: 5b 66 6f 72 6d 61 74 20 7b 25 36 2e 32 66 25 25  [format {%6.2f%%
3970: 20 25 73 7d 20 24 76 20 24 6f 66 5d 0a 20 20 7d   %s} $v $of].  }
3980: 0a 7d 0a 0a 70 72 6f 63 20 64 69 76 69 64 65 20  .}..proc divide 
3990: 7b 6e 75 6d 20 64 65 6e 6f 6d 7d 20 7b 0a 20 20  {num denom} {.  
39a0: 69 66 20 7b 24 64 65 6e 6f 6d 3d 3d 30 7d 20 7b  if {$denom==0} {
39b0: 72 65 74 75 72 6e 20 30 2e 30 7d 0a 20 20 72 65  return 0.0}.  re
39c0: 74 75 72 6e 20 5b 66 6f 72 6d 61 74 20 25 2e 32  turn [format %.2
39d0: 66 20 5b 65 78 70 72 20 64 6f 75 62 6c 65 28 24  f [expr double($
39e0: 6e 75 6d 29 2f 64 6f 75 62 6c 65 28 24 64 65 6e  num)/double($den
39f0: 6f 6d 29 5d 5d 0a 7d 0a 0a 23 20 47 65 6e 65 72  om)]].}..# Gener
3a00: 61 74 65 20 61 20 73 75 62 72 65 70 6f 72 74 20  ate a subreport 
3a10: 74 68 61 74 20 63 6f 76 65 72 73 20 73 6f 6d 65  that covers some
3a20: 20 73 75 62 73 65 74 20 6f 66 20 74 68 65 20 64   subset of the d
3a30: 61 74 61 62 61 73 65 2e 0a 23 20 74 68 65 20 24  atabase..# the $
3a40: 77 68 65 72 65 20 63 6c 61 75 73 65 20 64 65 74  where clause det
3a50: 65 72 6d 69 6e 65 73 20 77 68 69 63 68 20 73 75  ermines which su
3a60: 62 73 65 74 20 74 6f 20 61 6e 61 6c 79 7a 65 2e  bset to analyze.
3a70: 0a 23 0a 70 72 6f 63 20 73 75 62 72 65 70 6f 72  .#.proc subrepor
3a80: 74 20 7b 74 69 74 6c 65 20 77 68 65 72 65 7d 20  t {title where} 
3a90: 7b 0a 20 20 67 6c 6f 62 61 6c 20 70 61 67 65 53  {.  global pageS
3aa0: 69 7a 65 20 66 69 6c 65 5f 70 67 63 6e 74 0a 0a  ize file_pgcnt..
3ab0: 20 20 23 20 51 75 65 72 79 20 74 68 65 20 69 6e    # Query the in
3ac0: 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62 61 73 65  -memory database
3ad0: 20 66 6f 72 20 74 68 65 20 73 75 6d 20 6f 66 20   for the sum of 
3ae0: 76 61 72 69 6f 75 73 20 73 74 61 74 69 73 74 69  various statisti
3af0: 63 73 20 0a 20 20 23 20 66 6f 72 20 74 68 65 20  cs .  # for the 
3b00: 73 75 62 73 65 74 20 6f 66 20 74 61 62 6c 65 73  subset of tables
3b10: 2f 69 6e 64 69 63 65 73 20 69 64 65 6e 74 69 66  /indices identif
3b20: 69 65 64 20 62 79 20 74 68 65 20 57 48 45 52 45  ied by the WHERE
3b30: 20 63 6c 61 75 73 65 20 69 6e 0a 20 20 23 20 24   clause in.  # $
3b40: 77 68 65 72 65 2e 20 4e 6f 74 65 20 74 68 61 74  where. Note that
3b50: 20 65 76 65 6e 20 69 66 20 74 68 65 20 57 48 45   even if the WHE
3b60: 52 45 20 63 6c 61 75 73 65 20 6d 61 74 63 68 65  RE clause matche
3b70: 73 20 6e 6f 20 72 6f 77 73 2c 20 74 68 65 0a 20  s no rows, the. 
3b80: 20 23 20 66 6f 6c 6c 6f 77 69 6e 67 20 71 75 65   # following que
3b90: 72 79 20 72 65 74 75 72 6e 73 20 65 78 61 63 74  ry returns exact
3ba0: 6c 79 20 6f 6e 65 20 72 6f 77 20 28 62 65 63 61  ly one row (beca
3bb0: 75 73 65 20 69 74 20 69 73 20 61 6e 20 61 67 67  use it is an agg
3bc0: 72 65 67 61 74 65 29 2e 0a 20 20 23 0a 20 20 23  regate)..  #.  #
3bd0: 20 54 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20   The results of 
3be0: 74 68 65 20 71 75 65 72 79 20 61 72 65 20 73 74  the query are st
3bf0: 6f 72 65 64 20 64 69 72 65 63 74 6c 79 20 62 79  ored directly by
3c00: 20 53 51 4c 69 74 65 20 69 6e 74 6f 20 6c 6f 63   SQLite into loc
3c10: 61 6c 20 0a 20 20 23 20 76 61 72 69 61 62 6c 65  al .  # variable
3c20: 73 20 28 69 2e 65 2e 20 24 6e 65 6e 74 72 79 2c  s (i.e. $nentry,
3c30: 20 24 6e 6c 65 61 66 20 65 74 63 2e 29 2e 0a 20   $nleaf etc.).. 
3c40: 20 23 0a 20 20 6d 65 6d 20 65 76 61 6c 20 22 0a   #.  mem eval ".
3c50: 20 20 20 20 53 45 4c 45 43 54 0a 20 20 20 20 20      SELECT.     
3c60: 20 69 6e 74 28 73 75 6d 28 6e 65 6e 74 72 79 29   int(sum(nentry)
3c70: 29 20 41 53 20 6e 65 6e 74 72 79 2c 0a 20 20 20  ) AS nentry,.   
3c80: 20 20 20 69 6e 74 28 73 75 6d 28 6c 65 61 66 5f     int(sum(leaf_
3c90: 65 6e 74 72 69 65 73 29 29 20 41 53 20 6e 6c 65  entries)) AS nle
3ca0: 61 66 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75  af,.      int(su
3cb0: 6d 28 70 61 79 6c 6f 61 64 29 29 20 41 53 20 70  m(payload)) AS p
3cc0: 61 79 6c 6f 61 64 2c 0a 20 20 20 20 20 20 69 6e  ayload,.      in
3cd0: 74 28 73 75 6d 28 6f 76 66 6c 5f 70 61 79 6c 6f  t(sum(ovfl_paylo
3ce0: 61 64 29 29 20 41 53 20 6f 76 66 6c 5f 70 61 79  ad)) AS ovfl_pay
3cf0: 6c 6f 61 64 2c 0a 20 20 20 20 20 20 6d 61 78 28  load,.      max(
3d00: 6d 78 5f 70 61 79 6c 6f 61 64 29 20 41 53 20 6d  mx_payload) AS m
3d10: 78 5f 70 61 79 6c 6f 61 64 2c 0a 20 20 20 20 20  x_payload,.     
3d20: 20 69 6e 74 28 73 75 6d 28 6f 76 66 6c 5f 63 6e   int(sum(ovfl_cn
3d30: 74 29 29 20 61 73 20 6f 76 66 6c 5f 63 6e 74 2c  t)) as ovfl_cnt,
3d40: 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d 28 6c  .      int(sum(l
3d50: 65 61 66 5f 70 61 67 65 73 29 29 20 41 53 20 6c  eaf_pages)) AS l
3d60: 65 61 66 5f 70 61 67 65 73 2c 0a 20 20 20 20 20  eaf_pages,.     
3d70: 20 69 6e 74 28 73 75 6d 28 69 6e 74 5f 70 61 67   int(sum(int_pag
3d80: 65 73 29 29 20 41 53 20 69 6e 74 5f 70 61 67 65  es)) AS int_page
3d90: 73 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d  s,.      int(sum
3da0: 28 6f 76 66 6c 5f 70 61 67 65 73 29 29 20 41 53  (ovfl_pages)) AS
3db0: 20 6f 76 66 6c 5f 70 61 67 65 73 2c 0a 20 20 20   ovfl_pages,.   
3dc0: 20 20 20 69 6e 74 28 73 75 6d 28 6c 65 61 66 5f     int(sum(leaf_
3dd0: 75 6e 75 73 65 64 29 29 20 41 53 20 6c 65 61 66  unused)) AS leaf
3de0: 5f 75 6e 75 73 65 64 2c 0a 20 20 20 20 20 20 69  _unused,.      i
3df0: 6e 74 28 73 75 6d 28 69 6e 74 5f 75 6e 75 73 65  nt(sum(int_unuse
3e00: 64 29 29 20 41 53 20 69 6e 74 5f 75 6e 75 73 65  d)) AS int_unuse
3e10: 64 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d  d,.      int(sum
3e20: 28 6f 76 66 6c 5f 75 6e 75 73 65 64 29 29 20 41  (ovfl_unused)) A
3e30: 53 20 6f 76 66 6c 5f 75 6e 75 73 65 64 2c 0a 20  S ovfl_unused,. 
3e40: 20 20 20 20 20 69 6e 74 28 73 75 6d 28 67 61 70       int(sum(gap
3e50: 5f 63 6e 74 29 29 20 41 53 20 67 61 70 5f 63 6e  _cnt)) AS gap_cn
3e60: 74 0a 20 20 20 20 46 52 4f 4d 20 73 70 61 63 65  t.    FROM space
3e70: 5f 75 73 65 64 20 57 48 45 52 45 20 24 77 68 65  _used WHERE $whe
3e80: 72 65 22 20 7b 7d 20 7b 7d 0a 0a 20 20 23 20 4f  re" {} {}..  # O
3e90: 75 74 70 75 74 20 74 68 65 20 73 75 62 2d 72 65  utput the sub-re
3ea0: 70 6f 72 74 20 74 69 74 6c 65 2c 20 6e 69 63 65  port title, nice
3eb0: 6c 79 20 64 65 63 6f 72 61 74 65 64 20 77 69 74  ly decorated wit
3ec0: 68 20 2a 20 63 68 61 72 61 63 74 65 72 73 2e 0a  h * characters..
3ed0: 20 20 23 0a 20 20 70 75 74 73 20 22 22 0a 20 20    #.  puts "".  
3ee0: 73 65 74 20 6c 65 6e 20 5b 73 74 72 69 6e 67 20  set len [string 
3ef0: 6c 65 6e 67 74 68 20 24 74 69 74 6c 65 5d 0a 20  length $title]. 
3f00: 20 73 65 74 20 73 74 61 72 73 20 5b 73 74 72 69   set stars [stri
3f10: 6e 67 20 72 65 70 65 61 74 20 2a 20 5b 65 78 70  ng repeat * [exp
3f20: 72 20 36 35 2d 24 6c 65 6e 5d 5d 0a 20 20 70 75  r 65-$len]].  pu
3f30: 74 73 20 22 2a 2a 2a 20 24 74 69 74 6c 65 20 24  ts "*** $title $
3f40: 73 74 61 72 73 22 0a 20 20 70 75 74 73 20 22 22  stars".  puts ""
3f50: 0a 0a 20 20 23 20 43 61 6c 63 75 6c 61 74 65 20  ..  # Calculate 
3f60: 73 74 61 74 69 73 74 69 63 73 20 61 6e 64 20 73  statistics and s
3f70: 74 6f 72 65 20 74 68 65 20 72 65 73 75 6c 74 73  tore the results
3f80: 20 69 6e 20 54 43 4c 20 76 61 72 69 61 62 6c 65   in TCL variable
3f90: 73 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 20  s, as follows:. 
3fa0: 20 23 0a 20 20 23 20 74 6f 74 61 6c 5f 70 61 67   #.  # total_pag
3fb0: 65 73 3a 20 44 61 74 61 62 61 73 65 20 70 61 67  es: Database pag
3fc0: 65 73 20 63 6f 6e 73 75 6d 65 64 2e 0a 20 20 23  es consumed..  #
3fd0: 20 74 6f 74 61 6c 5f 70 61 67 65 73 5f 70 65 72   total_pages_per
3fe0: 63 65 6e 74 3a 20 50 61 67 65 73 20 63 6f 6e 73  cent: Pages cons
3ff0: 75 6d 65 64 20 61 73 20 61 20 70 65 72 63 65 6e  umed as a percen
4000: 74 61 67 65 20 6f 66 20 74 68 65 20 66 69 6c 65  tage of the file
4010: 2e 0a 20 20 23 20 73 74 6f 72 61 67 65 3a 20 42  ..  # storage: B
4020: 79 74 65 73 20 63 6f 6e 73 75 6d 65 64 2e 0a 20  ytes consumed.. 
4030: 20 23 20 70 61 79 6c 6f 61 64 5f 70 65 72 63 65   # payload_perce
4040: 6e 74 3a 20 50 61 79 6c 6f 61 64 20 62 79 74 65  nt: Payload byte
4050: 73 20 75 73 65 64 20 61 73 20 61 20 70 65 72 63  s used as a perc
4060: 65 6e 74 61 67 65 20 6f 66 20 24 73 74 6f 72 61  entage of $stora
4070: 67 65 2e 0a 20 20 23 20 74 6f 74 61 6c 5f 75 6e  ge..  # total_un
4080: 75 73 65 64 3a 20 55 6e 75 73 65 64 20 62 79 74  used: Unused byt
4090: 65 73 20 6f 6e 20 70 61 67 65 73 2e 0a 20 20 23  es on pages..  #
40a0: 20 61 76 67 5f 70 61 79 6c 6f 61 64 3a 20 41 76   avg_payload: Av
40b0: 65 72 61 67 65 20 70 61 79 6c 6f 61 64 20 70 65  erage payload pe
40c0: 72 20 62 74 72 65 65 20 65 6e 74 72 79 2e 0a 20  r btree entry.. 
40d0: 20 23 20 61 76 67 5f 66 61 6e 6f 75 74 3a 20 41   # avg_fanout: A
40e0: 76 65 72 61 67 65 20 66 61 6e 6f 75 74 20 66 6f  verage fanout fo
40f0: 72 20 69 6e 74 65 72 6e 61 6c 20 70 61 67 65 73  r internal pages
4100: 2e 0a 20 20 23 20 61 76 67 5f 75 6e 75 73 65 64  ..  # avg_unused
4110: 3a 20 41 76 65 72 61 67 65 20 75 6e 75 73 65 64  : Average unused
4120: 20 62 79 74 65 73 20 70 65 72 20 62 74 72 65 65   bytes per btree
4130: 20 65 6e 74 72 79 2e 0a 20 20 23 20 6f 76 66 6c   entry..  # ovfl
4140: 5f 63 6e 74 5f 70 65 72 63 65 6e 74 3a 20 50 65  _cnt_percent: Pe
4150: 72 63 65 6e 74 61 67 65 20 6f 66 20 62 74 72 65  rcentage of btre
4160: 65 20 65 6e 74 72 69 65 73 20 74 68 61 74 20 75  e entries that u
4170: 73 65 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65  se overflow page
4180: 73 2e 0a 20 20 23 0a 20 20 73 65 74 20 74 6f 74  s..  #.  set tot
4190: 61 6c 5f 70 61 67 65 73 20 5b 65 78 70 72 20 7b  al_pages [expr {
41a0: 24 6c 65 61 66 5f 70 61 67 65 73 2b 24 69 6e 74  $leaf_pages+$int
41b0: 5f 70 61 67 65 73 2b 24 6f 76 66 6c 5f 70 61 67  _pages+$ovfl_pag
41c0: 65 73 7d 5d 0a 20 20 73 65 74 20 74 6f 74 61 6c  es}].  set total
41d0: 5f 70 61 67 65 73 5f 70 65 72 63 65 6e 74 20 5b  _pages_percent [
41e0: 70 65 72 63 65 6e 74 20 24 74 6f 74 61 6c 5f 70  percent $total_p
41f0: 61 67 65 73 20 24 66 69 6c 65 5f 70 67 63 6e 74  ages $file_pgcnt
4200: 5d 0a 20 20 73 65 74 20 73 74 6f 72 61 67 65 20  ].  set storage 
4210: 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c 5f 70 61  [expr {$total_pa
4220: 67 65 73 2a 24 70 61 67 65 53 69 7a 65 7d 5d 0a  ges*$pageSize}].
4230: 20 20 73 65 74 20 70 61 79 6c 6f 61 64 5f 70 65    set payload_pe
4240: 72 63 65 6e 74 20 5b 70 65 72 63 65 6e 74 20 24  rcent [percent $
4250: 70 61 79 6c 6f 61 64 20 24 73 74 6f 72 61 67 65  payload $storage
4260: 20 7b 6f 66 20 73 74 6f 72 61 67 65 20 63 6f 6e   {of storage con
4270: 73 75 6d 65 64 7d 5d 0a 20 20 73 65 74 20 74 6f  sumed}].  set to
4280: 74 61 6c 5f 75 6e 75 73 65 64 20 5b 65 78 70 72  tal_unused [expr
4290: 20 7b 24 6f 76 66 6c 5f 75 6e 75 73 65 64 2b 24   {$ovfl_unused+$
42a0: 69 6e 74 5f 75 6e 75 73 65 64 2b 24 6c 65 61 66  int_unused+$leaf
42b0: 5f 75 6e 75 73 65 64 7d 5d 0a 20 20 73 65 74 20  _unused}].  set 
42c0: 61 76 67 5f 70 61 79 6c 6f 61 64 20 5b 64 69 76  avg_payload [div
42d0: 69 64 65 20 24 70 61 79 6c 6f 61 64 20 24 6e 6c  ide $payload $nl
42e0: 65 61 66 5d 0a 20 20 73 65 74 20 61 76 67 5f 75  eaf].  set avg_u
42f0: 6e 75 73 65 64 20 5b 64 69 76 69 64 65 20 24 74  nused [divide $t
4300: 6f 74 61 6c 5f 75 6e 75 73 65 64 20 24 6e 6c 65  otal_unused $nle
4310: 61 66 5d 0a 20 20 69 66 20 7b 24 69 6e 74 5f 70  af].  if {$int_p
4320: 61 67 65 73 3e 30 7d 20 7b 0a 20 20 20 20 23 20  ages>0} {.    # 
4330: 54 4f 44 4f 3a 20 49 73 20 74 68 69 73 20 66 6f  TODO: Is this fo
4340: 72 6d 75 6c 61 20 63 6f 72 72 65 63 74 3f 0a 20  rmula correct?. 
4350: 20 20 20 73 65 74 20 6e 54 61 62 20 5b 6d 65 6d     set nTab [mem
4360: 20 65 76 61 6c 20 22 0a 20 20 20 20 20 20 53 45   eval ".      SE
4370: 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 20 46 52  LECT count(*) FR
4380: 4f 4d 20 28 0a 20 20 20 20 20 20 20 20 20 20 53  OM (.          S
4390: 45 4c 45 43 54 20 44 49 53 54 49 4e 43 54 20 74  ELECT DISTINCT t
43a0: 62 6c 6e 61 6d 65 20 46 52 4f 4d 20 73 70 61 63  blname FROM spac
43b0: 65 5f 75 73 65 64 20 57 48 45 52 45 20 24 77 68  e_used WHERE $wh
43c0: 65 72 65 20 41 4e 44 20 69 73 5f 69 6e 64 65 78  ere AND is_index
43d0: 3d 30 0a 20 20 20 20 20 20 29 0a 20 20 20 20 22  =0.      ).    "
43e0: 5d 0a 20 20 20 20 73 65 74 20 61 76 67 5f 66 61  ].    set avg_fa
43f0: 6e 6f 75 74 20 5b 6d 65 6d 20 65 76 61 6c 20 22  nout [mem eval "
4400: 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 28 73  .      SELECT (s
4410: 75 6d 28 6c 65 61 66 5f 70 61 67 65 73 2b 69 6e  um(leaf_pages+in
4420: 74 5f 70 61 67 65 73 29 2d 24 6e 54 61 62 29 2f  t_pages)-$nTab)/
4430: 73 75 6d 28 69 6e 74 5f 70 61 67 65 73 29 20 46  sum(int_pages) F
4440: 52 4f 4d 20 73 70 61 63 65 5f 75 73 65 64 0a 20  ROM space_used. 
4450: 20 20 20 20 20 20 20 20 20 57 48 45 52 45 20 24           WHERE $
4460: 77 68 65 72 65 20 41 4e 44 20 69 73 5f 69 6e 64  where AND is_ind
4470: 65 78 20 3d 20 30 0a 20 20 20 20 22 5d 0a 20 20  ex = 0.    "].  
4480: 20 20 73 65 74 20 61 76 67 5f 66 61 6e 6f 75 74    set avg_fanout
4490: 20 5b 66 6f 72 6d 61 74 20 25 2e 32 66 20 24 61   [format %.2f $a
44a0: 76 67 5f 66 61 6e 6f 75 74 5d 0a 20 20 7d 0a 20  vg_fanout].  }. 
44b0: 20 73 65 74 20 6f 76 66 6c 5f 63 6e 74 5f 70 65   set ovfl_cnt_pe
44c0: 72 63 65 6e 74 20 5b 70 65 72 63 65 6e 74 20 24  rcent [percent $
44d0: 6f 76 66 6c 5f 63 6e 74 20 24 6e 6c 65 61 66 20  ovfl_cnt $nleaf 
44e0: 7b 6f 66 20 61 6c 6c 20 65 6e 74 72 69 65 73 7d  {of all entries}
44f0: 5d 0a 0a 20 20 23 20 50 72 69 6e 74 20 6f 75 74  ]..  # Print out
4500: 20 74 68 65 20 73 75 62 2d 72 65 70 6f 72 74 20   the sub-report 
4510: 73 74 61 74 69 73 74 69 63 73 2e 0a 20 20 23 0a  statistics..  #.
4520: 20 20 73 74 61 74 6c 69 6e 65 20 7b 50 65 72 63    statline {Perc
4530: 65 6e 74 61 67 65 20 6f 66 20 74 6f 74 61 6c 20  entage of total 
4540: 64 61 74 61 62 61 73 65 7d 20 24 74 6f 74 61 6c  database} $total
4550: 5f 70 61 67 65 73 5f 70 65 72 63 65 6e 74 0a 20  _pages_percent. 
4560: 20 73 74 61 74 6c 69 6e 65 20 7b 4e 75 6d 62 65   statline {Numbe
4570: 72 20 6f 66 20 65 6e 74 72 69 65 73 7d 20 24 6e  r of entries} $n
4580: 6c 65 61 66 0a 20 20 73 74 61 74 6c 69 6e 65 20  leaf.  statline 
4590: 7b 42 79 74 65 73 20 6f 66 20 73 74 6f 72 61 67  {Bytes of storag
45a0: 65 20 63 6f 6e 73 75 6d 65 64 7d 20 24 73 74 6f  e consumed} $sto
45b0: 72 61 67 65 0a 20 20 73 74 61 74 6c 69 6e 65 20  rage.  statline 
45c0: 7b 42 79 74 65 73 20 6f 66 20 70 61 79 6c 6f 61  {Bytes of payloa
45d0: 64 7d 20 24 70 61 79 6c 6f 61 64 20 24 70 61 79  d} $payload $pay
45e0: 6c 6f 61 64 5f 70 65 72 63 65 6e 74 0a 20 20 73  load_percent.  s
45f0: 74 61 74 6c 69 6e 65 20 7b 41 76 65 72 61 67 65  tatline {Average
4600: 20 70 61 79 6c 6f 61 64 20 70 65 72 20 65 6e 74   payload per ent
4610: 72 79 7d 20 24 61 76 67 5f 70 61 79 6c 6f 61 64  ry} $avg_payload
4620: 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 41 76 65  .  statline {Ave
4630: 72 61 67 65 20 75 6e 75 73 65 64 20 62 79 74 65  rage unused byte
4640: 73 20 70 65 72 20 65 6e 74 72 79 7d 20 24 61 76  s per entry} $av
4650: 67 5f 75 6e 75 73 65 64 0a 20 20 69 66 20 7b 5b  g_unused.  if {[
4660: 69 6e 66 6f 20 65 78 69 73 74 73 20 61 76 67 5f  info exists avg_
4670: 66 61 6e 6f 75 74 5d 7d 20 7b 0a 20 20 20 20 73  fanout]} {.    s
4680: 74 61 74 6c 69 6e 65 20 7b 41 76 65 72 61 67 65  tatline {Average
4690: 20 66 61 6e 6f 75 74 7d 20 24 61 76 67 5f 66 61   fanout} $avg_fa
46a0: 6e 6f 75 74 0a 20 20 7d 0a 20 20 69 66 20 7b 24  nout.  }.  if {$
46b0: 74 6f 74 61 6c 5f 70 61 67 65 73 3e 31 7d 20 7b  total_pages>1} {
46c0: 0a 20 20 20 20 73 65 74 20 66 72 61 67 6d 65 6e  .    set fragmen
46d0: 74 61 74 69 6f 6e 20 5b 70 65 72 63 65 6e 74 20  tation [percent 
46e0: 24 67 61 70 5f 63 6e 74 20 5b 65 78 70 72 20 7b  $gap_cnt [expr {
46f0: 24 74 6f 74 61 6c 5f 70 61 67 65 73 2d 31 7d 5d  $total_pages-1}]
4700: 20 7b 66 72 61 67 6d 65 6e 74 61 74 69 6f 6e 7d   {fragmentation}
4710: 5d 0a 20 20 20 20 73 74 61 74 6c 69 6e 65 20 7b  ].    statline {
4720: 46 72 61 67 6d 65 6e 74 61 74 69 6f 6e 7d 20 24  Fragmentation} $
4730: 66 72 61 67 6d 65 6e 74 61 74 69 6f 6e 0a 20 20  fragmentation.  
4740: 7d 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 4d 61  }.  statline {Ma
4750: 78 69 6d 75 6d 20 70 61 79 6c 6f 61 64 20 70 65  ximum payload pe
4760: 72 20 65 6e 74 72 79 7d 20 24 6d 78 5f 70 61 79  r entry} $mx_pay
4770: 6c 6f 61 64 0a 20 20 73 74 61 74 6c 69 6e 65 20  load.  statline 
4780: 7b 45 6e 74 72 69 65 73 20 74 68 61 74 20 75 73  {Entries that us
4790: 65 20 6f 76 65 72 66 6c 6f 77 7d 20 24 6f 76 66  e overflow} $ovf
47a0: 6c 5f 63 6e 74 20 24 6f 76 66 6c 5f 63 6e 74 5f  l_cnt $ovfl_cnt_
47b0: 70 65 72 63 65 6e 74 0a 20 20 69 66 20 7b 24 69  percent.  if {$i
47c0: 6e 74 5f 70 61 67 65 73 3e 30 7d 20 7b 0a 20 20  nt_pages>0} {.  
47d0: 20 20 73 74 61 74 6c 69 6e 65 20 7b 49 6e 64 65    statline {Inde
47e0: 78 20 70 61 67 65 73 20 75 73 65 64 7d 20 24 69  x pages used} $i
47f0: 6e 74 5f 70 61 67 65 73 0a 20 20 7d 0a 20 20 73  nt_pages.  }.  s
4800: 74 61 74 6c 69 6e 65 20 7b 50 72 69 6d 61 72 79  tatline {Primary
4810: 20 70 61 67 65 73 20 75 73 65 64 7d 20 24 6c 65   pages used} $le
4820: 61 66 5f 70 61 67 65 73 0a 20 20 73 74 61 74 6c  af_pages.  statl
4830: 69 6e 65 20 7b 4f 76 65 72 66 6c 6f 77 20 70 61  ine {Overflow pa
4840: 67 65 73 20 75 73 65 64 7d 20 24 6f 76 66 6c 5f  ges used} $ovfl_
4850: 70 61 67 65 73 0a 20 20 73 74 61 74 6c 69 6e 65  pages.  statline
4860: 20 7b 54 6f 74 61 6c 20 70 61 67 65 73 20 75 73   {Total pages us
4870: 65 64 7d 20 24 74 6f 74 61 6c 5f 70 61 67 65 73  ed} $total_pages
4880: 0a 20 20 69 66 20 7b 24 69 6e 74 5f 75 6e 75 73  .  if {$int_unus
4890: 65 64 3e 30 7d 20 7b 0a 20 20 20 20 73 65 74 20  ed>0} {.    set 
48a0: 69 6e 74 5f 75 6e 75 73 65 64 5f 70 65 72 63 65  int_unused_perce
48b0: 6e 74 20 5c 0a 20 20 20 20 20 20 20 20 20 5b 70  nt \.         [p
48c0: 65 72 63 65 6e 74 20 24 69 6e 74 5f 75 6e 75 73  ercent $int_unus
48d0: 65 64 20 5b 65 78 70 72 20 7b 24 69 6e 74 5f 70  ed [expr {$int_p
48e0: 61 67 65 73 2a 24 70 61 67 65 53 69 7a 65 7d 5d  ages*$pageSize}]
48f0: 20 7b 6f 66 20 69 6e 64 65 78 20 73 70 61 63 65   {of index space
4900: 7d 5d 0a 20 20 20 20 73 74 61 74 6c 69 6e 65 20  }].    statline 
4910: 22 55 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e  "Unused bytes on
4920: 20 69 6e 64 65 78 20 70 61 67 65 73 22 20 24 69   index pages" $i
4930: 6e 74 5f 75 6e 75 73 65 64 20 24 69 6e 74 5f 75  nt_unused $int_u
4940: 6e 75 73 65 64 5f 70 65 72 63 65 6e 74 0a 20 20  nused_percent.  
4950: 7d 0a 20 20 73 74 61 74 6c 69 6e 65 20 22 55 6e  }.  statline "Un
4960: 75 73 65 64 20 62 79 74 65 73 20 6f 6e 20 70 72  used bytes on pr
4970: 69 6d 61 72 79 20 70 61 67 65 73 22 20 24 6c 65  imary pages" $le
4980: 61 66 5f 75 6e 75 73 65 64 20 5c 0a 20 20 20 20  af_unused \.    
4990: 20 5b 70 65 72 63 65 6e 74 20 24 6c 65 61 66 5f   [percent $leaf_
49a0: 75 6e 75 73 65 64 20 5b 65 78 70 72 20 7b 24 6c  unused [expr {$l
49b0: 65 61 66 5f 70 61 67 65 73 2a 24 70 61 67 65 53  eaf_pages*$pageS
49c0: 69 7a 65 7d 5d 20 7b 6f 66 20 70 72 69 6d 61 72  ize}] {of primar
49d0: 79 20 73 70 61 63 65 7d 5d 0a 20 20 73 74 61 74  y space}].  stat
49e0: 6c 69 6e 65 20 22 55 6e 75 73 65 64 20 62 79 74  line "Unused byt
49f0: 65 73 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20 70  es on overflow p
4a00: 61 67 65 73 22 20 24 6f 76 66 6c 5f 75 6e 75 73  ages" $ovfl_unus
4a10: 65 64 20 5c 0a 20 20 20 20 20 5b 70 65 72 63 65  ed \.     [perce
4a20: 6e 74 20 24 6f 76 66 6c 5f 75 6e 75 73 65 64 20  nt $ovfl_unused 
4a30: 5b 65 78 70 72 20 7b 24 6f 76 66 6c 5f 70 61 67  [expr {$ovfl_pag
4a40: 65 73 2a 24 70 61 67 65 53 69 7a 65 7d 5d 20 7b  es*$pageSize}] {
4a50: 6f 66 20 6f 76 65 72 66 6c 6f 77 20 73 70 61 63  of overflow spac
4a60: 65 7d 5d 0a 20 20 73 74 61 74 6c 69 6e 65 20 22  e}].  statline "
4a70: 55 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e 20  Unused bytes on 
4a80: 61 6c 6c 20 70 61 67 65 73 22 20 24 74 6f 74 61  all pages" $tota
4a90: 6c 5f 75 6e 75 73 65 64 20 5c 0a 20 20 20 20 20  l_unused \.     
4aa0: 20 20 20 20 20 20 20 20 20 20 5b 70 65 72 63 65            [perce
4ab0: 6e 74 20 24 74 6f 74 61 6c 5f 75 6e 75 73 65 64  nt $total_unused
4ac0: 20 24 73 74 6f 72 61 67 65 20 7b 6f 66 20 61 6c   $storage {of al
4ad0: 6c 20 73 70 61 63 65 7d 5d 0a 20 20 72 65 74 75  l space}].  retu
4ae0: 72 6e 20 31 0a 7d 0a 0a 23 20 43 61 6c 63 75 6c  rn 1.}..# Calcul
4af0: 61 74 65 20 74 68 65 20 6f 76 65 72 68 65 61 64  ate the overhead
4b00: 20 69 6e 20 70 61 67 65 73 20 63 61 75 73 65 64   in pages caused
4b10: 20 62 79 20 61 75 74 6f 2d 76 61 63 75 75 6d 2e   by auto-vacuum.
4b20: 20 0a 23 0a 23 20 54 68 69 73 20 70 72 6f 63 65   .#.# This proce
4b30: 64 75 72 65 20 63 61 6c 63 75 6c 61 74 65 73 20  dure calculates 
4b40: 61 6e 64 20 72 65 74 75 72 6e 73 20 74 68 65 20  and returns the 
4b50: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
4b60: 75 73 65 64 20 62 79 20 74 68 65 20 0a 23 20 61  used by the .# a
4b70: 75 74 6f 2d 76 61 63 75 75 6d 20 27 70 6f 69 6e  uto-vacuum 'poin
4b80: 74 65 72 2d 6d 61 70 27 2e 20 49 66 20 74 68 65  ter-map'. If the
4b90: 20 64 61 74 61 62 61 73 65 20 64 6f 65 73 20 6e   database does n
4ba0: 6f 74 20 73 75 70 70 6f 72 74 20 61 75 74 6f 2d  ot support auto-
4bb0: 76 61 63 75 75 6d 2c 0a 23 20 74 68 65 6e 20 30  vacuum,.# then 0
4bc0: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 54 68   is returned. Th
4bd0: 65 20 74 77 6f 20 61 72 67 75 6d 65 6e 74 73 20  e two arguments 
4be0: 61 72 65 20 74 68 65 20 73 69 7a 65 20 6f 66 20  are the size of 
4bf0: 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
4c00: 65 20 69 6e 0a 23 20 70 61 67 65 73 20 61 6e 64  e in.# pages and
4c10: 20 74 68 65 20 70 61 67 65 20 73 69 7a 65 20 75   the page size u
4c20: 73 65 64 20 62 79 20 74 68 65 20 64 61 74 61 62  sed by the datab
4c30: 61 73 65 20 28 69 6e 20 62 79 74 65 73 29 2e 0a  ase (in bytes)..
4c40: 70 72 6f 63 20 61 75 74 6f 76 61 63 75 75 6d 5f  proc autovacuum_
4c50: 6f 76 65 72 68 65 61 64 20 7b 66 69 6c 65 50 61  overhead {filePa
4c60: 67 65 73 20 70 61 67 65 53 69 7a 65 7d 20 7b 0a  ges pageSize} {.
4c70: 0a 20 20 23 20 52 65 61 64 20 74 68 65 20 76 61  .  # Read the va
4c80: 6c 75 65 20 6f 66 20 6d 65 74 61 20 34 2e 20 49  lue of meta 4. I
4c90: 66 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e  f non-zero, then
4ca0: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 73 75   the database su
4cb0: 70 70 6f 72 74 73 0a 20 20 23 20 61 75 74 6f 2d  pports.  # auto-
4cc0: 76 61 63 75 75 6d 2e 20 49 74 20 77 6f 75 6c 64  vacuum. It would
4cd0: 20 62 65 20 70 6f 73 73 69 62 6c 65 20 74 6f 20   be possible to 
4ce0: 75 73 65 20 22 50 52 41 47 4d 41 20 61 75 74 6f  use "PRAGMA auto
4cf0: 5f 76 61 63 75 75 6d 22 20 69 6e 73 74 65 61 64  _vacuum" instead
4d00: 2c 0a 20 20 23 20 62 75 74 20 74 68 61 74 20 77  ,.  # but that w
4d10: 6f 75 6c 64 20 6e 6f 74 20 77 6f 72 6b 20 69 66  ould not work if
4d20: 20 74 68 65 20 53 51 4c 49 54 45 5f 4f 4d 49 54   the SQLITE_OMIT
4d30: 5f 50 52 41 47 4d 41 20 6d 61 63 72 6f 20 77 61  _PRAGMA macro wa
4d40: 73 20 64 65 66 69 6e 65 64 0a 20 20 23 20 77 68  s defined.  # wh
4d50: 65 6e 20 74 68 65 20 6c 69 62 72 61 72 79 20 77  en the library w
4d60: 61 73 20 62 75 69 6c 74 2e 0a 20 20 73 65 74 20  as built..  set 
4d70: 6d 65 74 61 34 20 5b 6c 69 6e 64 65 78 20 5b 62  meta4 [lindex [b
4d80: 74 72 65 65 5f 67 65 74 5f 6d 65 74 61 20 24 3a  tree_get_meta $:
4d90: 3a 44 42 5d 20 34 5d 0a 0a 20 20 23 20 49 66 20  :DB] 4]..  # If 
4da0: 74 68 65 20 64 61 74 61 62 61 73 65 20 69 73 20  the database is 
4db0: 6e 6f 74 20 61 6e 20 61 75 74 6f 2d 76 61 63 75  not an auto-vacu
4dc0: 75 6d 20 64 61 74 61 62 61 73 65 20 6f 72 20 74  um database or t
4dd0: 68 65 20 66 69 6c 65 20 63 6f 6e 73 69 73 74 73  he file consists
4de0: 0a 20 20 23 20 6f 66 20 6f 6e 65 20 70 61 67 65  .  # of one page
4df0: 20 6f 6e 6c 79 20 74 68 65 6e 20 74 68 65 72 65   only then there
4e00: 20 69 73 20 6e 6f 20 6f 76 65 72 68 65 61 64 20   is no overhead 
4e10: 66 6f 72 20 61 75 74 6f 2d 76 61 63 75 75 6d 2e  for auto-vacuum.
4e20: 20 52 65 74 75 72 6e 20 7a 65 72 6f 2e 0a 20 20   Return zero..  
4e30: 69 66 20 7b 30 3d 3d 24 6d 65 74 61 34 20 7c 7c  if {0==$meta4 ||
4e40: 20 24 66 69 6c 65 50 61 67 65 73 3d 3d 31 7d 20   $filePages==1} 
4e50: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 0a 20  {.    return 0. 
4e60: 20 7d 0a 0a 20 20 23 20 54 68 65 20 6e 75 6d 62   }..  # The numb
4e70: 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 6f 6e  er of entries on
4e80: 20 65 61 63 68 20 70 6f 69 6e 74 65 72 20 6d 61   each pointer ma
4e90: 70 20 70 61 67 65 2e 20 54 68 65 20 6c 61 79 6f  p page. The layo
4ea0: 75 74 20 6f 66 20 74 68 65 0a 20 20 23 20 64 61  ut of the.  # da
4eb0: 74 61 62 61 73 65 20 66 69 6c 65 20 69 73 20 6f  tabase file is o
4ec0: 6e 65 20 70 6f 69 6e 74 65 72 2d 6d 61 70 20 70  ne pointer-map p
4ed0: 61 67 65 2c 20 66 6f 6c 6c 6f 77 65 64 20 62 79  age, followed by
4ee0: 20 24 70 74 72 73 50 65 72 50 61 67 65 20 6f 74   $ptrsPerPage ot
4ef0: 68 65 72 0a 20 20 23 20 70 61 67 65 73 2c 20 66  her.  # pages, f
4f00: 6f 6c 6c 6f 77 65 64 20 62 79 20 61 20 70 6f 69  ollowed by a poi
4f10: 6e 74 65 72 2d 6d 61 70 20 70 61 67 65 20 65 74  nter-map page et
4f20: 63 2e 20 54 68 65 20 66 69 72 73 74 20 70 6f 69  c. The first poi
4f30: 6e 74 65 72 2d 6d 61 70 20 70 61 67 65 0a 20 20  nter-map page.  
4f40: 23 20 69 73 20 74 68 65 20 73 65 63 6f 6e 64 20  # is the second 
4f50: 70 61 67 65 20 6f 66 20 74 68 65 20 66 69 6c 65  page of the file
4f60: 20 6f 76 65 72 61 6c 6c 2e 0a 20 20 73 65 74 20   overall..  set 
4f70: 70 74 72 73 50 65 72 50 61 67 65 20 5b 65 78 70  ptrsPerPage [exp
4f80: 72 20 64 6f 75 62 6c 65 28 24 70 61 67 65 53 69  r double($pageSi
4f90: 7a 65 2f 35 29 5d 0a 0a 20 20 23 20 52 65 74 75  ze/5)]..  # Retu
4fa0: 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  rn the number of
4fb0: 20 70 6f 69 6e 74 65 72 20 6d 61 70 20 70 61 67   pointer map pag
4fc0: 65 73 20 69 6e 20 74 68 65 20 64 61 74 61 62 61  es in the databa
4fd0: 73 65 2e 0a 20 20 72 65 74 75 72 6e 20 5b 65 78  se..  return [ex
4fe0: 70 72 20 69 6e 74 28 63 65 69 6c 28 20 28 24 66  pr int(ceil( ($f
4ff0: 69 6c 65 50 61 67 65 73 2d 31 2e 30 29 2f 28 24  ilePages-1.0)/($
5000: 70 74 72 73 50 65 72 50 61 67 65 2b 31 2e 30 29  ptrsPerPage+1.0)
5010: 20 29 29 5d 0a 7d 0a 0a 0a 23 20 43 61 6c 63 75   ))].}...# Calcu
5020: 6c 61 74 65 20 74 68 65 20 73 75 6d 6d 61 72 79  late the summary
5030: 20 73 74 61 74 69 73 74 69 63 73 20 66 6f 72 20   statistics for 
5040: 74 68 65 20 64 61 74 61 62 61 73 65 20 61 6e 64  the database and
5050: 20 73 74 6f 72 65 20 74 68 65 20 72 65 73 75 6c   store the resul
5060: 74 73 0a 23 20 69 6e 20 54 43 4c 20 76 61 72 69  ts.# in TCL vari
5070: 61 62 6c 65 73 2e 20 54 68 65 79 20 61 72 65 20  ables. They are 
5080: 6f 75 74 70 75 74 20 62 65 6c 6f 77 2e 20 56 61  output below. Va
5090: 72 69 61 62 6c 65 73 20 61 72 65 20 61 73 20 66  riables are as f
50a0: 6f 6c 6c 6f 77 73 3a 0a 23 0a 23 20 70 61 67 65  ollows:.#.# page
50b0: 53 69 7a 65 3a 20 20 20 20 20 20 53 69 7a 65 20  Size:      Size 
50c0: 6f 66 20 65 61 63 68 20 70 61 67 65 20 69 6e 20  of each page in 
50d0: 62 79 74 65 73 2e 0a 23 20 66 69 6c 65 5f 62 79  bytes..# file_by
50e0: 74 65 73 3a 20 20 20 20 46 69 6c 65 20 73 69 7a  tes:    File siz
50f0: 65 20 69 6e 20 62 79 74 65 73 2e 0a 23 20 66 69  e in bytes..# fi
5100: 6c 65 5f 70 67 63 6e 74 3a 20 20 20 20 4e 75 6d  le_pgcnt:    Num
5110: 62 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20  ber of pages in 
5120: 74 68 65 20 66 69 6c 65 2e 0a 23 20 66 69 6c 65  the file..# file
5130: 5f 70 67 63 6e 74 32 3a 20 20 20 4e 75 6d 62 65  _pgcnt2:   Numbe
5140: 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68  r of pages in th
5150: 65 20 66 69 6c 65 20 28 63 61 6c 63 75 6c 61 74  e file (calculat
5160: 65 64 29 2e 0a 23 20 61 76 5f 70 67 63 6e 74 3a  ed)..# av_pgcnt:
5170: 20 20 20 20 20 20 50 61 67 65 73 20 63 6f 6e 73        Pages cons
5180: 75 6d 65 64 20 62 79 20 74 68 65 20 61 75 74 6f  umed by the auto
5190: 2d 76 61 63 75 75 6d 20 70 6f 69 6e 74 65 72 2d  -vacuum pointer-
51a0: 6d 61 70 2e 0a 23 20 61 76 5f 70 65 72 63 65 6e  map..# av_percen
51b0: 74 3a 20 20 20 20 50 65 72 63 65 6e 74 61 67 65  t:    Percentage
51c0: 20 6f 66 20 74 68 65 20 66 69 6c 65 20 63 6f 6e   of the file con
51d0: 73 75 6d 65 64 20 62 79 20 61 75 74 6f 2d 76 61  sumed by auto-va
51e0: 63 75 75 6d 20 70 6f 69 6e 74 65 72 2d 6d 61 70  cuum pointer-map
51f0: 2e 0a 23 20 69 6e 75 73 65 5f 70 67 63 6e 74 3a  ..# inuse_pgcnt:
5200: 20 20 20 44 61 74 61 20 70 61 67 65 73 20 69 6e     Data pages in
5210: 20 74 68 65 20 66 69 6c 65 2e 0a 23 20 69 6e 75   the file..# inu
5220: 73 65 5f 70 65 72 63 65 6e 74 3a 20 50 65 72 63  se_percent: Perc
5230: 65 6e 74 61 67 65 20 6f 66 20 70 61 67 65 73 20  entage of pages 
5240: 75 73 65 64 20 74 6f 20 73 74 6f 72 65 20 64 61  used to store da
5250: 74 61 2e 0a 23 20 66 72 65 65 5f 70 67 63 6e 74  ta..# free_pgcnt
5260: 3a 20 20 20 20 46 72 65 65 20 70 61 67 65 73 20  :    Free pages 
5270: 63 61 6c 63 75 6c 61 74 65 64 20 61 73 20 28 3c  calculated as (<
5280: 74 6f 74 61 6c 20 70 61 67 65 73 3e 20 2d 20 3c  total pages> - <
5290: 69 6e 2d 75 73 65 20 70 61 67 65 73 3e 29 0a 23  in-use pages>).#
52a0: 20 66 72 65 65 5f 70 67 63 6e 74 32 3a 20 20 20   free_pgcnt2:   
52b0: 46 72 65 65 20 70 61 67 65 73 20 69 6e 20 74 68  Free pages in th
52c0: 65 20 66 69 6c 65 20 61 63 63 6f 72 64 69 6e 67  e file according
52d0: 20 74 6f 20 74 68 65 20 66 69 6c 65 20 68 65 61   to the file hea
52e0: 64 65 72 2e 0a 23 20 66 72 65 65 5f 70 65 72 63  der..# free_perc
52f0: 65 6e 74 3a 20 20 50 65 72 63 65 6e 74 61 67 65  ent:  Percentage
5300: 20 6f 66 20 66 69 6c 65 20 63 6f 6e 73 75 6d 65   of file consume
5310: 64 20 62 79 20 66 72 65 65 20 70 61 67 65 73 20  d by free pages 
5320: 28 63 61 6c 63 75 6c 61 74 65 64 29 2e 0a 23 20  (calculated)..# 
5330: 66 72 65 65 5f 70 65 72 63 65 6e 74 32 3a 20 50  free_percent2: P
5340: 65 72 63 65 6e 74 61 67 65 20 6f 66 20 66 69 6c  ercentage of fil
5350: 65 20 63 6f 6e 73 75 6d 65 64 20 62 79 20 66 72  e consumed by fr
5360: 65 65 20 70 61 67 65 73 20 28 68 65 61 64 65 72  ee pages (header
5370: 29 2e 0a 23 20 6e 74 61 62 6c 65 3a 20 20 20 20  )..# ntable:    
5380: 20 20 20 20 4e 75 6d 62 65 72 20 6f 66 20 74 61      Number of ta
5390: 62 6c 65 73 20 69 6e 20 74 68 65 20 64 62 2e 0a  bles in the db..
53a0: 23 20 6e 69 6e 64 65 78 3a 20 20 20 20 20 20 20  # nindex:       
53b0: 20 4e 75 6d 62 65 72 20 6f 66 20 69 6e 64 69 63   Number of indic
53c0: 65 73 20 69 6e 20 74 68 65 20 64 62 2e 0a 23 20  es in the db..# 
53d0: 6e 61 75 74 6f 69 6e 64 65 78 3a 20 20 20 20 4e  nautoindex:    N
53e0: 75 6d 62 65 72 20 6f 66 20 69 6e 64 69 63 65 73  umber of indices
53f0: 20 63 72 65 61 74 65 64 20 61 75 74 6f 6d 61 74   created automat
5400: 69 63 61 6c 6c 79 2e 0a 23 20 6e 6d 61 6e 69 6e  ically..# nmanin
5410: 64 65 78 3a 20 20 20 20 20 4e 75 6d 62 65 72 20  dex:     Number 
5420: 6f 66 20 69 6e 64 69 63 65 73 20 63 72 65 61 74  of indices creat
5430: 65 64 20 6d 61 6e 75 61 6c 6c 79 2e 0a 23 20 75  ed manually..# u
5440: 73 65 72 5f 70 61 79 6c 6f 61 64 3a 20 20 4e 75  ser_payload:  Nu
5450: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66  mber of bytes of
5460: 20 70 61 79 6c 6f 61 64 20 69 6e 20 74 61 62 6c   payload in tabl
5470: 65 20 62 74 72 65 65 73 20 0a 23 20 20 20 20 20  e btrees .#     
5480: 20 20 20 20 20 20 20 20 20 20 20 28 6e 6f 74 20             (not 
5490: 69 6e 63 6c 75 64 69 6e 67 20 73 71 6c 69 74 65  including sqlite
54a0: 5f 6d 61 73 74 65 72 29 0a 23 20 75 73 65 72 5f  _master).# user_
54b0: 70 65 72 63 65 6e 74 3a 20 20 24 75 73 65 72 5f  percent:  $user_
54c0: 70 61 79 6c 6f 61 64 20 61 73 20 61 20 70 65 72  payload as a per
54d0: 63 65 6e 74 61 67 65 20 6f 66 20 74 6f 74 61 6c  centage of total
54e0: 20 66 69 6c 65 20 73 69 7a 65 2e 0a 0a 73 65 74   file size...set
54f0: 20 66 69 6c 65 5f 62 79 74 65 73 20 20 5b 66 69   file_bytes  [fi
5500: 6c 65 20 73 69 7a 65 20 24 66 69 6c 65 5f 74 6f  le size $file_to
5510: 5f 61 6e 61 6c 79 7a 65 5d 0a 73 65 74 20 66 69  _analyze].set fi
5520: 6c 65 5f 70 67 63 6e 74 20 20 5b 65 78 70 72 20  le_pgcnt  [expr 
5530: 7b 24 66 69 6c 65 5f 62 79 74 65 73 2f 24 70 61  {$file_bytes/$pa
5540: 67 65 53 69 7a 65 7d 5d 0a 0a 73 65 74 20 61 76  geSize}]..set av
5550: 5f 70 67 63 6e 74 20 20 20 20 5b 61 75 74 6f 76  _pgcnt    [autov
5560: 61 63 75 75 6d 5f 6f 76 65 72 68 65 61 64 20 24  acuum_overhead $
5570: 66 69 6c 65 5f 70 67 63 6e 74 20 24 70 61 67 65  file_pgcnt $page
5580: 53 69 7a 65 5d 0a 73 65 74 20 61 76 5f 70 65 72  Size].set av_per
5590: 63 65 6e 74 20 20 5b 70 65 72 63 65 6e 74 20 24  cent  [percent $
55a0: 61 76 5f 70 67 63 6e 74 20 24 66 69 6c 65 5f 70  av_pgcnt $file_p
55b0: 67 63 6e 74 5d 0a 0a 73 65 74 20 73 71 6c 20 7b  gcnt]..set sql {
55c0: 53 45 4c 45 43 54 20 73 75 6d 28 6c 65 61 66 5f  SELECT sum(leaf_
55d0: 70 61 67 65 73 2b 69 6e 74 5f 70 61 67 65 73 2b  pages+int_pages+
55e0: 6f 76 66 6c 5f 70 61 67 65 73 29 20 46 52 4f 4d  ovfl_pages) FROM
55f0: 20 73 70 61 63 65 5f 75 73 65 64 7d 0a 73 65 74   space_used}.set
5600: 20 69 6e 75 73 65 5f 70 67 63 6e 74 20 20 20 5b   inuse_pgcnt   [
5610: 65 78 70 72 20 69 6e 74 28 5b 6d 65 6d 20 65 76  expr int([mem ev
5620: 61 6c 20 24 73 71 6c 5d 29 5d 0a 73 65 74 20 69  al $sql])].set i
5630: 6e 75 73 65 5f 70 65 72 63 65 6e 74 20 5b 70 65  nuse_percent [pe
5640: 72 63 65 6e 74 20 24 69 6e 75 73 65 5f 70 67 63  rcent $inuse_pgc
5650: 6e 74 20 24 66 69 6c 65 5f 70 67 63 6e 74 5d 0a  nt $file_pgcnt].
5660: 0a 73 65 74 20 66 72 65 65 5f 70 67 63 6e 74 20  .set free_pgcnt 
5670: 20 20 20 5b 65 78 70 72 20 24 66 69 6c 65 5f 70     [expr $file_p
5680: 67 63 6e 74 2d 24 69 6e 75 73 65 5f 70 67 63 6e  gcnt-$inuse_pgcn
5690: 74 2d 24 61 76 5f 70 67 63 6e 74 5d 0a 73 65 74  t-$av_pgcnt].set
56a0: 20 66 72 65 65 5f 70 65 72 63 65 6e 74 20 20 5b   free_percent  [
56b0: 70 65 72 63 65 6e 74 20 24 66 72 65 65 5f 70 67  percent $free_pg
56c0: 63 6e 74 20 24 66 69 6c 65 5f 70 67 63 6e 74 5d  cnt $file_pgcnt]
56d0: 0a 73 65 74 20 66 72 65 65 5f 70 67 63 6e 74 32  .set free_pgcnt2
56e0: 20 20 20 5b 6c 69 6e 64 65 78 20 5b 62 74 72 65     [lindex [btre
56f0: 65 5f 67 65 74 5f 6d 65 74 61 20 24 44 42 5d 20  e_get_meta $DB] 
5700: 30 5d 0a 73 65 74 20 66 72 65 65 5f 70 65 72 63  0].set free_perc
5710: 65 6e 74 32 20 5b 70 65 72 63 65 6e 74 20 24 66  ent2 [percent $f
5720: 72 65 65 5f 70 67 63 6e 74 32 20 24 66 69 6c 65  ree_pgcnt2 $file
5730: 5f 70 67 63 6e 74 5d 0a 0a 73 65 74 20 66 69 6c  _pgcnt]..set fil
5740: 65 5f 70 67 63 6e 74 32 20 5b 65 78 70 72 20 7b  e_pgcnt2 [expr {
5750: 24 69 6e 75 73 65 5f 70 67 63 6e 74 2b 24 66 72  $inuse_pgcnt+$fr
5760: 65 65 5f 70 67 63 6e 74 32 2b 24 61 76 5f 70 67  ee_pgcnt2+$av_pg
5770: 63 6e 74 7d 5d 0a 0a 73 65 74 20 6e 74 61 62 6c  cnt}]..set ntabl
5780: 65 20 5b 64 62 20 65 76 61 6c 20 7b 53 45 4c 45  e [db eval {SELE
5790: 43 54 20 63 6f 75 6e 74 28 2a 29 2b 31 20 46 52  CT count(*)+1 FR
57a0: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
57b0: 20 57 48 45 52 45 20 74 79 70 65 3d 27 74 61 62   WHERE type='tab
57c0: 6c 65 27 7d 5d 0a 73 65 74 20 6e 69 6e 64 65 78  le'}].set nindex
57d0: 20 5b 64 62 20 65 76 61 6c 20 7b 53 45 4c 45 43   [db eval {SELEC
57e0: 54 20 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20  T count(*) FROM 
57f0: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48  sqlite_master WH
5800: 45 52 45 20 74 79 70 65 3d 27 69 6e 64 65 78 27  ERE type='index'
5810: 7d 5d 0a 73 65 74 20 73 71 6c 20 7b 53 45 4c 45  }].set sql {SELE
5820: 43 54 20 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d  CT count(*) FROM
5830: 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57   sqlite_master W
5840: 48 45 52 45 20 6e 61 6d 65 20 4c 49 4b 45 20 27  HERE name LIKE '
5850: 73 71 6c 69 74 65 5f 61 75 74 6f 69 6e 64 65 78  sqlite_autoindex
5860: 25 27 7d 0a 73 65 74 20 6e 61 75 74 6f 69 6e 64  %'}.set nautoind
5870: 65 78 20 5b 64 62 20 65 76 61 6c 20 24 73 71 6c  ex [db eval $sql
5880: 5d 0a 73 65 74 20 6e 6d 61 6e 69 6e 64 65 78 20  ].set nmanindex 
5890: 5b 65 78 70 72 20 7b 24 6e 69 6e 64 65 78 2d 24  [expr {$nindex-$
58a0: 6e 61 75 74 6f 69 6e 64 65 78 7d 5d 0a 0a 23 20  nautoindex}]..# 
58b0: 73 65 74 20 74 6f 74 61 6c 5f 70 61 79 6c 6f 61  set total_payloa
58c0: 64 20 5b 6d 65 6d 20 65 76 61 6c 20 22 53 45 4c  d [mem eval "SEL
58d0: 45 43 54 20 73 75 6d 28 70 61 79 6c 6f 61 64 29  ECT sum(payload)
58e0: 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73 65 64   FROM space_used
58f0: 22 5d 0a 73 65 74 20 75 73 65 72 5f 70 61 79 6c  "].set user_payl
5900: 6f 61 64 20 5b 6d 65 6d 20 6f 6e 65 20 7b 53 45  oad [mem one {SE
5910: 4c 45 43 54 20 69 6e 74 28 73 75 6d 28 70 61 79  LECT int(sum(pay
5920: 6c 6f 61 64 29 29 20 46 52 4f 4d 20 73 70 61 63  load)) FROM spac
5930: 65 5f 75 73 65 64 0a 20 20 20 20 20 57 48 45 52  e_used.     WHER
5940: 45 20 4e 4f 54 20 69 73 5f 69 6e 64 65 78 20 41  E NOT is_index A
5950: 4e 44 20 6e 61 6d 65 20 4e 4f 54 20 4c 49 4b 45  ND name NOT LIKE
5960: 20 27 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 27   'sqlite_master'
5970: 7d 5d 0a 73 65 74 20 75 73 65 72 5f 70 65 72 63  }].set user_perc
5980: 65 6e 74 20 5b 70 65 72 63 65 6e 74 20 24 75 73  ent [percent $us
5990: 65 72 5f 70 61 79 6c 6f 61 64 20 24 66 69 6c 65  er_payload $file
59a0: 5f 62 79 74 65 73 5d 0a 0a 23 20 4f 75 74 70 75  _bytes]..# Outpu
59b0: 74 20 74 68 65 20 73 75 6d 6d 61 72 79 20 73 74  t the summary st
59c0: 61 74 69 73 74 69 63 73 20 63 61 6c 63 75 6c 61  atistics calcula
59d0: 74 65 64 20 61 62 6f 76 65 2e 0a 23 0a 70 75 74  ted above..#.put
59e0: 73 20 22 2f 2a 2a 20 44 69 73 6b 2d 53 70 61 63  s "/** Disk-Spac
59f0: 65 20 55 74 69 6c 69 7a 61 74 69 6f 6e 20 52 65  e Utilization Re
5a00: 70 6f 72 74 20 46 6f 72 20 24 66 69 6c 65 5f 74  port For $file_t
5a10: 6f 5f 61 6e 61 6c 79 7a 65 22 0a 63 61 74 63 68  o_analyze".catch
5a20: 20 7b 0a 20 20 70 75 74 73 20 22 2a 2a 2a 20 41   {.  puts "*** A
5a30: 73 20 6f 66 20 5b 63 6c 6f 63 6b 20 66 6f 72 6d  s of [clock form
5a40: 61 74 20 5b 63 6c 6f 63 6b 20 73 65 63 6f 6e 64  at [clock second
5a50: 73 5d 20 2d 66 6f 72 6d 61 74 20 7b 25 59 2d 25  s] -format {%Y-%
5a60: 62 2d 25 64 20 25 48 3a 25 4d 3a 25 53 7d 5d 22  b-%d %H:%M:%S}]"
5a70: 0a 7d 0a 70 75 74 73 20 22 22 0a 73 74 61 74 6c  .}.puts "".statl
5a80: 69 6e 65 20 7b 50 61 67 65 20 73 69 7a 65 20 69  ine {Page size i
5a90: 6e 20 62 79 74 65 73 7d 20 24 70 61 67 65 53 69  n bytes} $pageSi
5aa0: 7a 65 0a 73 74 61 74 6c 69 6e 65 20 7b 50 61 67  ze.statline {Pag
5ab0: 65 73 20 69 6e 20 74 68 65 20 77 68 6f 6c 65 20  es in the whole 
5ac0: 66 69 6c 65 20 28 6d 65 61 73 75 72 65 64 29 7d  file (measured)}
5ad0: 20 24 66 69 6c 65 5f 70 67 63 6e 74 0a 73 74 61   $file_pgcnt.sta
5ae0: 74 6c 69 6e 65 20 7b 50 61 67 65 73 20 69 6e 20  tline {Pages in 
5af0: 74 68 65 20 77 68 6f 6c 65 20 66 69 6c 65 20 28  the whole file (
5b00: 63 61 6c 63 75 6c 61 74 65 64 29 7d 20 24 66 69  calculated)} $fi
5b10: 6c 65 5f 70 67 63 6e 74 32 0a 73 74 61 74 6c 69  le_pgcnt2.statli
5b20: 6e 65 20 7b 50 61 67 65 73 20 74 68 61 74 20 73  ne {Pages that s
5b30: 74 6f 72 65 20 64 61 74 61 7d 20 24 69 6e 75 73  tore data} $inus
5b40: 65 5f 70 67 63 6e 74 20 24 69 6e 75 73 65 5f 70  e_pgcnt $inuse_p
5b50: 65 72 63 65 6e 74 0a 73 74 61 74 6c 69 6e 65 20  ercent.statline 
5b60: 7b 50 61 67 65 73 20 6f 6e 20 74 68 65 20 66 72  {Pages on the fr
5b70: 65 65 6c 69 73 74 20 28 70 65 72 20 68 65 61 64  eelist (per head
5b80: 65 72 29 7d 20 24 66 72 65 65 5f 70 67 63 6e 74  er)} $free_pgcnt
5b90: 32 20 24 66 72 65 65 5f 70 65 72 63 65 6e 74 32  2 $free_percent2
5ba0: 0a 73 74 61 74 6c 69 6e 65 20 7b 50 61 67 65 73  .statline {Pages
5bb0: 20 6f 6e 20 74 68 65 20 66 72 65 65 6c 69 73 74   on the freelist
5bc0: 20 28 63 61 6c 63 75 6c 61 74 65 64 29 7d 20 24   (calculated)} $
5bd0: 66 72 65 65 5f 70 67 63 6e 74 20 24 66 72 65 65  free_pgcnt $free
5be0: 5f 70 65 72 63 65 6e 74 0a 73 74 61 74 6c 69 6e  _percent.statlin
5bf0: 65 20 7b 50 61 67 65 73 20 6f 66 20 61 75 74 6f  e {Pages of auto
5c00: 2d 76 61 63 75 75 6d 20 6f 76 65 72 68 65 61 64  -vacuum overhead
5c10: 7d 20 24 61 76 5f 70 67 63 6e 74 20 24 61 76 5f  } $av_pgcnt $av_
5c20: 70 65 72 63 65 6e 74 0a 73 74 61 74 6c 69 6e 65  percent.statline
5c30: 20 7b 4e 75 6d 62 65 72 20 6f 66 20 74 61 62 6c   {Number of tabl
5c40: 65 73 20 69 6e 20 74 68 65 20 64 61 74 61 62 61  es in the databa
5c50: 73 65 7d 20 24 6e 74 61 62 6c 65 0a 73 74 61 74  se} $ntable.stat
5c60: 6c 69 6e 65 20 7b 4e 75 6d 62 65 72 20 6f 66 20  line {Number of 
5c70: 69 6e 64 69 63 65 73 7d 20 24 6e 69 6e 64 65 78  indices} $nindex
5c80: 0a 73 74 61 74 6c 69 6e 65 20 7b 4e 75 6d 62 65  .statline {Numbe
5c90: 72 20 6f 66 20 6e 61 6d 65 64 20 69 6e 64 69 63  r of named indic
5ca0: 65 73 7d 20 24 6e 6d 61 6e 69 6e 64 65 78 0a 73  es} $nmanindex.s
5cb0: 74 61 74 6c 69 6e 65 20 7b 41 75 74 6f 6d 61 74  tatline {Automat
5cc0: 69 63 61 6c 6c 79 20 67 65 6e 65 72 61 74 65 64  ically generated
5cd0: 20 69 6e 64 69 63 65 73 7d 20 24 6e 61 75 74 6f   indices} $nauto
5ce0: 69 6e 64 65 78 0a 73 74 61 74 6c 69 6e 65 20 7b  index.statline {
5cf0: 53 69 7a 65 20 6f 66 20 74 68 65 20 66 69 6c 65  Size of the file
5d00: 20 69 6e 20 62 79 74 65 73 7d 20 24 66 69 6c 65   in bytes} $file
5d10: 5f 62 79 74 65 73 0a 73 74 61 74 6c 69 6e 65 20  _bytes.statline 
5d20: 7b 42 79 74 65 73 20 6f 66 20 75 73 65 72 20 70  {Bytes of user p
5d30: 61 79 6c 6f 61 64 20 73 74 6f 72 65 64 7d 20 24  ayload stored} $
5d40: 75 73 65 72 5f 70 61 79 6c 6f 61 64 20 24 75 73  user_payload $us
5d50: 65 72 5f 70 65 72 63 65 6e 74 0a 0a 23 20 4f 75  er_percent..# Ou
5d60: 74 70 75 74 20 74 61 62 6c 65 20 72 61 6e 6b 69  tput table ranki
5d70: 6e 67 73 0a 23 0a 70 75 74 73 20 22 22 0a 70 75  ngs.#.puts "".pu
5d80: 74 73 20 22 2a 2a 2a 20 50 61 67 65 20 63 6f 75  ts "*** Page cou
5d90: 6e 74 73 20 66 6f 72 20 61 6c 6c 20 74 61 62 6c  nts for all tabl
5da0: 65 73 20 77 69 74 68 20 74 68 65 69 72 20 69 6e  es with their in
5db0: 64 69 63 65 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  dices **********
5dc0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 70 75 74 73  **********".puts
5dd0: 20 22 22 0a 6d 65 6d 20 65 76 61 6c 20 7b 53 45   "".mem eval {SE
5de0: 4c 45 43 54 20 74 62 6c 6e 61 6d 65 2c 20 63 6f  LECT tblname, co
5df0: 75 6e 74 28 2a 29 20 41 53 20 63 6e 74 2c 20 0a  unt(*) AS cnt, .
5e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e                in
5e10: 74 28 73 75 6d 28 69 6e 74 5f 70 61 67 65 73 2b  t(sum(int_pages+
5e20: 6c 65 61 66 5f 70 61 67 65 73 2b 6f 76 66 6c 5f  leaf_pages+ovfl_
5e30: 70 61 67 65 73 29 29 20 41 53 20 73 69 7a 65 0a  pages)) AS size.
5e40: 20 20 20 20 20 20 20 20 20 20 46 52 4f 4d 20 73            FROM s
5e50: 70 61 63 65 5f 75 73 65 64 20 47 52 4f 55 50 20  pace_used GROUP 
5e60: 42 59 20 74 62 6c 6e 61 6d 65 20 4f 52 44 45 52  BY tblname ORDER
5e70: 20 42 59 20 73 69 7a 65 2b 30 20 44 45 53 43 2c   BY size+0 DESC,
5e80: 20 74 62 6c 6e 61 6d 65 7d 20 7b 7d 20 7b 0a 20   tblname} {} {. 
5e90: 20 73 74 61 74 6c 69 6e 65 20 5b 73 74 72 69 6e   statline [strin
5ea0: 67 20 74 6f 75 70 70 65 72 20 24 74 62 6c 6e 61  g toupper $tblna
5eb0: 6d 65 5d 20 24 73 69 7a 65 20 5b 70 65 72 63 65  me] $size [perce
5ec0: 6e 74 20 24 73 69 7a 65 20 24 66 69 6c 65 5f 70  nt $size $file_p
5ed0: 67 63 6e 74 5d 0a 7d 0a 0a 23 20 4f 75 74 70 75  gcnt].}..# Outpu
5ee0: 74 20 73 75 62 72 65 70 6f 72 74 73 0a 23 0a 69  t subreports.#.i
5ef0: 66 20 7b 24 6e 69 6e 64 65 78 3e 30 7d 20 7b 0a  f {$nindex>0} {.
5f00: 20 20 73 75 62 72 65 70 6f 72 74 20 7b 41 6c 6c    subreport {All
5f10: 20 74 61 62 6c 65 73 20 61 6e 64 20 69 6e 64 69   tables and indi
5f20: 63 65 73 7d 20 31 0a 7d 0a 73 75 62 72 65 70 6f  ces} 1.}.subrepo
5f30: 72 74 20 7b 41 6c 6c 20 74 61 62 6c 65 73 7d 20  rt {All tables} 
5f40: 7b 4e 4f 54 20 69 73 5f 69 6e 64 65 78 7d 0a 69  {NOT is_index}.i
5f50: 66 20 7b 24 6e 69 6e 64 65 78 3e 30 7d 20 7b 0a  f {$nindex>0} {.
5f60: 20 20 73 75 62 72 65 70 6f 72 74 20 7b 41 6c 6c    subreport {All
5f70: 20 69 6e 64 69 63 65 73 7d 20 7b 69 73 5f 69 6e   indices} {is_in
5f80: 64 65 78 7d 0a 7d 0a 66 6f 72 65 61 63 68 20 74  dex}.}.foreach t
5f90: 62 6c 20 5b 6d 65 6d 20 65 76 61 6c 20 7b 53 45  bl [mem eval {SE
5fa0: 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73  LECT name FROM s
5fb0: 70 61 63 65 5f 75 73 65 64 20 57 48 45 52 45 20  pace_used WHERE 
5fc0: 4e 4f 54 20 69 73 5f 69 6e 64 65 78 0a 20 20 20  NOT is_index.   
5fd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5fe0: 20 20 20 20 4f 52 44 45 52 20 42 59 20 6e 61 6d      ORDER BY nam
5ff0: 65 7d 5d 20 7b 0a 20 20 72 65 67 73 75 62 20 27  e}] {.  regsub '
6000: 20 24 74 62 6c 20 27 27 20 71 6e 0a 20 20 73 65   $tbl '' qn.  se
6010: 74 20 6e 61 6d 65 20 5b 73 74 72 69 6e 67 20 74  t name [string t
6020: 6f 75 70 70 65 72 20 24 74 62 6c 5d 0a 20 20 73  oupper $tbl].  s
6030: 65 74 20 6e 20 5b 6d 65 6d 20 65 76 61 6c 20 22  et n [mem eval "
6040: 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 20  SELECT count(*) 
6050: 46 52 4f 4d 20 73 70 61 63 65 5f 75 73 65 64 20  FROM space_used 
6060: 57 48 45 52 45 20 74 62 6c 6e 61 6d 65 3d 27 24  WHERE tblname='$
6070: 71 6e 27 22 5d 0a 20 20 69 66 20 7b 24 6e 3e 31  qn'"].  if {$n>1
6080: 7d 20 7b 0a 20 20 20 20 73 75 62 72 65 70 6f 72  } {.    subrepor
6090: 74 20 22 54 61 62 6c 65 20 24 6e 61 6d 65 20 61  t "Table $name a
60a0: 6e 64 20 61 6c 6c 20 69 74 73 20 69 6e 64 69 63  nd all its indic
60b0: 65 73 22 20 22 74 62 6c 6e 61 6d 65 3d 27 24 71  es" "tblname='$q
60c0: 6e 27 22 0a 20 20 20 20 73 75 62 72 65 70 6f 72  n'".    subrepor
60d0: 74 20 22 54 61 62 6c 65 20 24 6e 61 6d 65 20 77  t "Table $name w
60e0: 2f 6f 20 61 6e 79 20 69 6e 64 69 63 65 73 22 20  /o any indices" 
60f0: 22 6e 61 6d 65 3d 27 24 71 6e 27 22 0a 20 20 20  "name='$qn'".   
6100: 20 73 75 62 72 65 70 6f 72 74 20 22 49 6e 64 69   subreport "Indi
6110: 63 65 73 20 6f 66 20 74 61 62 6c 65 20 24 6e 61  ces of table $na
6120: 6d 65 22 20 22 74 62 6c 6e 61 6d 65 3d 27 24 71  me" "tblname='$q
6130: 6e 27 20 41 4e 44 20 69 73 5f 69 6e 64 65 78 22  n' AND is_index"
6140: 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20  .  } else {.    
6150: 73 75 62 72 65 70 6f 72 74 20 22 54 61 62 6c 65  subreport "Table
6160: 20 24 6e 61 6d 65 22 20 22 6e 61 6d 65 3d 27 24   $name" "name='$
6170: 71 6e 27 22 0a 20 20 7d 0a 7d 0a 0a 23 20 4f 75  qn'".  }.}..# Ou
6180: 74 70 75 74 20 69 6e 73 74 72 75 63 74 69 6f 6e  tput instruction
6190: 73 20 6f 6e 20 77 68 61 74 20 74 68 65 20 6e 75  s on what the nu
61a0: 6d 62 65 72 73 20 61 62 6f 76 65 20 6d 65 61 6e  mbers above mean
61b0: 2e 0a 23 0a 70 75 74 73 20 7b 0a 2a 2a 2a 20 44  ..#.puts {.*** D
61c0: 65 66 69 6e 69 74 69 6f 6e 73 20 2a 2a 2a 2a 2a  efinitions *****
61d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
61e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
61f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6200: 2a 0a 0a 50 61 67 65 20 73 69 7a 65 20 69 6e 20  *..Page size in 
6210: 62 79 74 65 73 0a 0a 20 20 20 20 54 68 65 20 6e  bytes..    The n
6220: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69  umber of bytes i
6230: 6e 20 61 20 73 69 6e 67 6c 65 20 70 61 67 65 20  n a single page 
6240: 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20  of the database 
6250: 66 69 6c 65 2e 20 20 0a 20 20 20 20 55 73 75 61  file.  .    Usua
6260: 6c 6c 79 20 31 30 32 34 2e 0a 0a 4e 75 6d 62 65  lly 1024...Numbe
6270: 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68  r of pages in th
6280: 65 20 77 68 6f 6c 65 20 66 69 6c 65 0a 7d 0a 70  e whole file.}.p
6290: 75 74 73 20 5c 0a 22 20 20 20 20 54 68 65 20 6e  uts \."    The n
62a0: 75 6d 62 65 72 20 6f 66 20 24 70 61 67 65 53 69  umber of $pageSi
62b0: 7a 65 2d 62 79 74 65 20 70 61 67 65 73 20 74 68  ze-byte pages th
62c0: 61 74 20 67 6f 20 69 6e 74 6f 20 66 6f 72 6d 69  at go into formi
62d0: 6e 67 20 74 68 65 20 63 6f 6d 70 6c 65 74 65 0a  ng the complete.
62e0: 20 20 20 20 64 61 74 61 62 61 73 65 22 0a 70 75      database".pu
62f0: 74 73 20 5c 0a 7b 0a 50 61 67 65 73 20 74 68 61  ts \.{.Pages tha
6300: 74 20 73 74 6f 72 65 20 64 61 74 61 0a 0a 20 20  t store data..  
6310: 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20    The number of 
6320: 70 61 67 65 73 20 74 68 61 74 20 73 74 6f 72 65  pages that store
6330: 20 64 61 74 61 2c 20 65 69 74 68 65 72 20 61 73   data, either as
6340: 20 70 72 69 6d 61 72 79 20 42 2a 54 72 65 65 20   primary B*Tree 
6350: 70 61 67 65 73 20 6f 72 0a 20 20 20 20 61 73 20  pages or.    as 
6360: 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 2e 20  overflow pages. 
6370: 20 54 68 65 20 6e 75 6d 62 65 72 20 61 74 20 74   The number at t
6380: 68 65 20 72 69 67 68 74 20 69 73 20 74 68 65 20  he right is the 
6390: 64 61 74 61 20 70 61 67 65 73 20 64 69 76 69 64  data pages divid
63a0: 65 64 20 62 79 0a 20 20 20 20 74 68 65 20 74 6f  ed by.    the to
63b0: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  tal number of pa
63c0: 67 65 73 20 69 6e 20 74 68 65 20 66 69 6c 65 2e  ges in the file.
63d0: 0a 0a 50 61 67 65 73 20 6f 6e 20 74 68 65 20 66  ..Pages on the f
63e0: 72 65 65 6c 69 73 74 0a 0a 20 20 20 20 54 68 65  reelist..    The
63f0: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
6400: 20 74 68 61 74 20 61 72 65 20 6e 6f 74 20 63 75   that are not cu
6410: 72 72 65 6e 74 6c 79 20 69 6e 20 75 73 65 20 62  rrently in use b
6420: 75 74 20 61 72 65 20 72 65 73 65 72 76 65 64 20  ut are reserved 
6430: 66 6f 72 0a 20 20 20 20 66 75 74 75 72 65 20 75  for.    future u
6440: 73 65 2e 20 20 54 68 65 20 70 65 72 63 65 6e 74  se.  The percent
6450: 61 67 65 20 61 74 20 74 68 65 20 72 69 67 68 74  age at the right
6460: 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f   is the number o
6470: 66 20 66 72 65 65 6c 69 73 74 20 70 61 67 65 73  f freelist pages
6480: 0a 20 20 20 20 64 69 76 69 64 65 64 20 62 79 20  .    divided by 
6490: 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72  the total number
64a0: 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68 65   of pages in the
64b0: 20 66 69 6c 65 2e 0a 0a 50 61 67 65 73 20 6f 66   file...Pages of
64c0: 20 61 75 74 6f 2d 76 61 63 75 75 6d 20 6f 76 65   auto-vacuum ove
64d0: 72 68 65 61 64 0a 0a 20 20 20 20 54 68 65 20 6e  rhead..    The n
64e0: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 74  umber of pages t
64f0: 68 61 74 20 73 74 6f 72 65 20 64 61 74 61 20 75  hat store data u
6500: 73 65 64 20 62 79 20 74 68 65 20 64 61 74 61 62  sed by the datab
6510: 61 73 65 20 74 6f 20 66 61 63 69 6c 69 74 61 74  ase to facilitat
6520: 65 0a 20 20 20 20 61 75 74 6f 2d 76 61 63 75 75  e.    auto-vacuu
6530: 6d 2e 20 54 68 69 73 20 69 73 20 7a 65 72 6f 20  m. This is zero 
6540: 66 6f 72 20 64 61 74 61 62 61 73 65 73 20 74 68  for databases th
6550: 61 74 20 64 6f 20 6e 6f 74 20 73 75 70 70 6f 72  at do not suppor
6560: 74 20 61 75 74 6f 2d 76 61 63 75 75 6d 2e 0a 0a  t auto-vacuum...
6570: 4e 75 6d 62 65 72 20 6f 66 20 74 61 62 6c 65 73  Number of tables
6580: 20 69 6e 20 74 68 65 20 64 61 74 61 62 61 73 65   in the database
6590: 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72  ..    The number
65a0: 20 6f 66 20 74 61 62 6c 65 73 20 69 6e 20 74 68   of tables in th
65b0: 65 20 64 61 74 61 62 61 73 65 2c 20 69 6e 63 6c  e database, incl
65c0: 75 64 69 6e 67 20 74 68 65 20 53 51 4c 49 54 45  uding the SQLITE
65d0: 5f 4d 41 53 54 45 52 20 74 61 62 6c 65 0a 20 20  _MASTER table.  
65e0: 20 20 75 73 65 64 20 74 6f 20 73 74 6f 72 65 20    used to store 
65f0: 73 63 68 65 6d 61 20 69 6e 66 6f 72 6d 61 74 69  schema informati
6600: 6f 6e 2e 0a 0a 4e 75 6d 62 65 72 20 6f 66 20 69  on...Number of i
6610: 6e 64 69 63 65 73 0a 0a 20 20 20 20 54 68 65 20  ndices..    The 
6620: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  total number of 
6630: 69 6e 64 69 63 65 73 20 69 6e 20 74 68 65 20 64  indices in the d
6640: 61 74 61 62 61 73 65 2e 0a 0a 4e 75 6d 62 65 72  atabase...Number
6650: 20 6f 66 20 6e 61 6d 65 64 20 69 6e 64 69 63 65   of named indice
6660: 73 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d 62 65  s..    The numbe
6670: 72 20 6f 66 20 69 6e 64 69 63 65 73 20 63 72 65  r of indices cre
6680: 61 74 65 64 20 75 73 69 6e 67 20 61 6e 20 65 78  ated using an ex
6690: 70 6c 69 63 69 74 20 43 52 45 41 54 45 20 49 4e  plicit CREATE IN
66a0: 44 45 58 20 73 74 61 74 65 6d 65 6e 74 2e 0a 0a  DEX statement...
66b0: 41 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20 67 65  Automatically ge
66c0: 6e 65 72 61 74 65 64 20 69 6e 64 69 63 65 73 0a  nerated indices.
66d0: 0a 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20  .    The number 
66e0: 6f 66 20 69 6e 64 69 63 65 73 20 75 73 65 64 20  of indices used 
66f0: 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 50 52 49  to implement PRI
6700: 4d 41 52 59 20 4b 45 59 20 6f 72 20 55 4e 49 51  MARY KEY or UNIQ
6710: 55 45 20 63 6f 6e 73 74 72 61 69 6e 74 73 0a 20  UE constraints. 
6720: 20 20 20 6f 6e 20 74 61 62 6c 65 73 2e 0a 0a 53     on tables...S
6730: 69 7a 65 20 6f 66 20 74 68 65 20 66 69 6c 65 20  ize of the file 
6740: 69 6e 20 62 79 74 65 73 0a 0a 20 20 20 20 54 68  in bytes..    Th
6750: 65 20 74 6f 74 61 6c 20 61 6d 6f 75 6e 74 20 6f  e total amount o
6760: 66 20 64 69 73 6b 20 73 70 61 63 65 20 75 73 65  f disk space use
6770: 64 20 62 79 20 74 68 65 20 65 6e 74 69 72 65 20  d by the entire 
6780: 64 61 74 61 62 61 73 65 20 66 69 6c 65 73 2e 0a  database files..
6790: 0a 42 79 74 65 73 20 6f 66 20 75 73 65 72 20 70  .Bytes of user p
67a0: 61 79 6c 6f 61 64 20 73 74 6f 72 65 64 0a 0a 20  ayload stored.. 
67b0: 20 20 20 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d     The total num
67c0: 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20  ber of bytes of 
67d0: 75 73 65 72 20 70 61 79 6c 6f 61 64 20 73 74 6f  user payload sto
67e0: 72 65 64 20 69 6e 20 74 68 65 20 64 61 74 61 62  red in the datab
67f0: 61 73 65 2e 20 54 68 65 0a 20 20 20 20 73 63 68  ase. The.    sch
6800: 65 6d 61 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  ema information 
6810: 69 6e 20 74 68 65 20 53 51 4c 49 54 45 5f 4d 41  in the SQLITE_MA
6820: 53 54 45 52 20 74 61 62 6c 65 20 69 73 20 6e 6f  STER table is no
6830: 74 20 63 6f 75 6e 74 65 64 20 77 68 65 6e 0a 20  t counted when. 
6840: 20 20 20 63 6f 6d 70 75 74 69 6e 67 20 74 68 69     computing thi
6850: 73 20 6e 75 6d 62 65 72 2e 20 20 54 68 65 20 70  s number.  The p
6860: 65 72 63 65 6e 74 61 67 65 20 61 74 20 74 68 65  ercentage at the
6870: 20 72 69 67 68 74 20 73 68 6f 77 73 20 74 68 65   right shows the
6880: 20 70 61 79 6c 6f 61 64 0a 20 20 20 20 64 69 76   payload.    div
6890: 69 64 65 64 20 62 79 20 74 68 65 20 74 6f 74 61  ided by the tota
68a0: 6c 20 66 69 6c 65 20 73 69 7a 65 2e 0a 0a 50 65  l file size...Pe
68b0: 72 63 65 6e 74 61 67 65 20 6f 66 20 74 6f 74 61  rcentage of tota
68c0: 6c 20 64 61 74 61 62 61 73 65 0a 0a 20 20 20 20  l database..    
68d0: 54 68 65 20 61 6d 6f 75 6e 74 20 6f 66 20 74 68  The amount of th
68e0: 65 20 63 6f 6d 70 6c 65 74 65 20 64 61 74 61 62  e complete datab
68f0: 61 73 65 20 66 69 6c 65 20 74 68 61 74 20 69 73  ase file that is
6900: 20 64 65 76 6f 74 65 64 20 74 6f 20 73 74 6f 72   devoted to stor
6910: 69 6e 67 0a 20 20 20 20 69 6e 66 6f 72 6d 61 74  ing.    informat
6920: 69 6f 6e 20 64 65 73 63 72 69 62 65 64 20 62 79  ion described by
6930: 20 74 68 69 73 20 63 61 74 65 67 6f 72 79 2e 0a   this category..
6940: 0a 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69  .Number of entri
6950: 65 73 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61  es..    The tota
6960: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 42 2d 54 72  l number of B-Tr
6970: 65 65 20 6b 65 79 2f 76 61 6c 75 65 20 70 61 69  ee key/value pai
6980: 72 73 20 73 74 6f 72 65 64 20 75 6e 64 65 72 20  rs stored under 
6990: 74 68 69 73 20 63 61 74 65 67 6f 72 79 2e 0a 0a  this category...
69a0: 42 79 74 65 73 20 6f 66 20 73 74 6f 72 61 67 65  Bytes of storage
69b0: 20 63 6f 6e 73 75 6d 65 64 0a 0a 20 20 20 20 54   consumed..    T
69c0: 68 65 20 74 6f 74 61 6c 20 61 6d 6f 75 6e 74 20  he total amount 
69d0: 6f 66 20 64 69 73 6b 20 73 70 61 63 65 20 72 65  of disk space re
69e0: 71 75 69 72 65 64 20 74 6f 20 73 74 6f 72 65 20  quired to store 
69f0: 61 6c 6c 20 42 2d 54 72 65 65 20 65 6e 74 72 69  all B-Tree entri
6a00: 65 73 0a 20 20 20 20 75 6e 64 65 72 20 74 68 69  es.    under thi
6a10: 73 20 63 61 74 65 67 6f 72 79 2e 20 20 54 68 65  s category.  The
6a20: 20 69 73 20 74 68 65 20 74 6f 74 61 6c 20 6e 75   is the total nu
6a30: 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 75 73  mber of pages us
6a40: 65 64 20 74 69 6d 65 73 0a 20 20 20 20 74 68 65  ed times.    the
6a50: 20 70 61 67 65 73 20 73 69 7a 65 2e 0a 0a 42 79   pages size...By
6a60: 74 65 73 20 6f 66 20 70 61 79 6c 6f 61 64 0a 0a  tes of payload..
6a70: 20 20 20 20 54 68 65 20 61 6d 6f 75 6e 74 20 6f      The amount o
6a80: 66 20 70 61 79 6c 6f 61 64 20 73 74 6f 72 65 64  f payload stored
6a90: 20 75 6e 64 65 72 20 74 68 69 73 20 63 61 74 65   under this cate
6aa0: 67 6f 72 79 2e 20 20 50 61 79 6c 6f 61 64 20 69  gory.  Payload i
6ab0: 73 20 74 68 65 20 64 61 74 61 0a 20 20 20 20 70  s the data.    p
6ac0: 61 72 74 20 6f 66 20 74 61 62 6c 65 20 65 6e 74  art of table ent
6ad0: 72 69 65 73 20 61 6e 64 20 74 68 65 20 6b 65 79  ries and the key
6ae0: 20 70 61 72 74 20 6f 66 20 69 6e 64 65 78 20 65   part of index e
6af0: 6e 74 72 69 65 73 2e 20 20 54 68 65 20 70 65 72  ntries.  The per
6b00: 63 65 6e 74 61 67 65 0a 20 20 20 20 61 74 20 74  centage.    at t
6b10: 68 65 20 72 69 67 68 74 20 69 73 20 74 68 65 20  he right is the 
6b20: 62 79 74 65 73 20 6f 66 20 70 61 79 6c 6f 61 64  bytes of payload
6b30: 20 64 69 76 69 64 65 64 20 62 79 20 74 68 65 20   divided by the 
6b40: 62 79 74 65 73 20 6f 66 20 73 74 6f 72 61 67 65  bytes of storage
6b50: 20 0a 20 20 20 20 63 6f 6e 73 75 6d 65 64 2e 0a   .    consumed..
6b60: 0a 41 76 65 72 61 67 65 20 70 61 79 6c 6f 61 64  .Average payload
6b70: 20 70 65 72 20 65 6e 74 72 79 0a 0a 20 20 20 20   per entry..    
6b80: 54 68 65 20 61 76 65 72 61 67 65 20 61 6d 6f 75  The average amou
6b90: 6e 74 20 6f 66 20 70 61 79 6c 6f 61 64 20 6f 6e  nt of payload on
6ba0: 20 65 61 63 68 20 65 6e 74 72 79 2e 20 20 54 68   each entry.  Th
6bb0: 69 73 20 69 73 20 6a 75 73 74 20 74 68 65 20 62  is is just the b
6bc0: 79 74 65 73 20 6f 66 0a 20 20 20 20 70 61 79 6c  ytes of.    payl
6bd0: 6f 61 64 20 64 69 76 69 64 65 64 20 62 79 20 74  oad divided by t
6be0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74  he number of ent
6bf0: 72 69 65 73 2e 0a 0a 41 76 65 72 61 67 65 20 75  ries...Average u
6c00: 6e 75 73 65 64 20 62 79 74 65 73 20 70 65 72 20  nused bytes per 
6c10: 65 6e 74 72 79 0a 0a 20 20 20 20 54 68 65 20 61  entry..    The a
6c20: 76 65 72 61 67 65 20 61 6d 6f 75 6e 74 20 6f 66  verage amount of
6c30: 20 66 72 65 65 20 73 70 61 63 65 20 72 65 6d 61   free space rema
6c40: 69 6e 69 6e 67 20 6f 6e 20 61 6c 6c 20 70 61 67  ining on all pag
6c50: 65 73 20 75 6e 64 65 72 20 74 68 69 73 0a 20 20  es under this.  
6c60: 20 20 63 61 74 65 67 6f 72 79 20 6f 6e 20 61 20    category on a 
6c70: 70 65 72 2d 65 6e 74 72 79 20 62 61 73 69 73 2e  per-entry basis.
6c80: 20 20 54 68 69 73 20 69 73 20 74 68 65 20 6e 75    This is the nu
6c90: 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62  mber of unused b
6ca0: 79 74 65 73 20 6f 6e 0a 20 20 20 20 61 6c 6c 20  ytes on.    all 
6cb0: 70 61 67 65 73 20 64 69 76 69 64 65 64 20 62 79  pages divided by
6cc0: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 65   the number of e
6cd0: 6e 74 72 69 65 73 2e 0a 0a 46 72 61 67 6d 65 6e  ntries...Fragmen
6ce0: 74 61 74 69 6f 6e 0a 0a 20 20 20 20 54 68 65 20  tation..    The 
6cf0: 70 65 72 63 65 6e 74 61 67 65 20 6f 66 20 70 61  percentage of pa
6d00: 67 65 73 20 69 6e 20 74 68 65 20 74 61 62 6c 65  ges in the table
6d10: 20 6f 72 20 69 6e 64 65 78 20 74 68 61 74 20 61   or index that a
6d20: 72 65 20 6e 6f 74 0a 20 20 20 20 63 6f 6e 73 65  re not.    conse
6d30: 63 75 74 69 76 65 20 69 6e 20 74 68 65 20 64 69  cutive in the di
6d40: 73 6b 20 66 69 6c 65 2e 20 20 4d 61 6e 79 20 66  sk file.  Many f
6d50: 69 6c 65 73 79 73 74 65 6d 73 20 61 72 65 20 6f  ilesystems are o
6d60: 70 74 69 6d 69 7a 65 64 0a 20 20 20 20 66 6f 72  ptimized.    for
6d70: 20 73 65 71 75 65 6e 74 69 61 6c 20 66 69 6c 65   sequential file
6d80: 20 61 63 63 65 73 73 20 73 6f 20 73 6d 61 6c 6c   access so small
6d90: 65 72 20 66 72 61 67 6d 65 6e 74 61 74 69 6f 6e  er fragmentation
6da0: 20 6e 75 6d 62 65 72 73 20 0a 20 20 20 20 73 6f   numbers .    so
6db0: 6d 65 74 69 6d 65 73 20 72 65 73 75 6c 74 20 69  metimes result i
6dc0: 6e 20 66 61 73 74 65 72 20 71 75 65 72 69 65 73  n faster queries
6dd0: 2c 20 65 73 70 65 63 69 61 6c 6c 79 20 66 6f 72  , especially for
6de0: 20 6c 61 72 67 65 72 0a 20 20 20 20 64 61 74 61   larger.    data
6df0: 62 61 73 65 20 66 69 6c 65 73 20 74 68 61 74 20  base files that 
6e00: 64 6f 20 6e 6f 74 20 66 69 74 20 69 6e 20 74 68  do not fit in th
6e10: 65 20 64 69 73 6b 20 63 61 63 68 65 2e 0a 0a 4d  e disk cache...M
6e20: 61 78 69 6d 75 6d 20 70 61 79 6c 6f 61 64 20 70  aximum payload p
6e30: 65 72 20 65 6e 74 72 79 0a 0a 20 20 20 20 54 68  er entry..    Th
6e40: 65 20 6c 61 72 67 65 73 74 20 70 61 79 6c 6f 61  e largest payloa
6e50: 64 20 73 69 7a 65 20 6f 66 20 61 6e 79 20 65 6e  d size of any en
6e60: 74 72 79 2e 0a 0a 45 6e 74 72 69 65 73 20 74 68  try...Entries th
6e70: 61 74 20 75 73 65 20 6f 76 65 72 66 6c 6f 77 0a  at use overflow.
6e80: 0a 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20  .    The number 
6e90: 6f 66 20 65 6e 74 72 69 65 73 20 74 68 61 74 20  of entries that 
6ea0: 75 73 65 72 20 6f 6e 65 20 6f 72 20 6d 6f 72 65  user one or more
6eb0: 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 2e   overflow pages.
6ec0: 0a 0a 54 6f 74 61 6c 20 70 61 67 65 73 20 75 73  ..Total pages us
6ed0: 65 64 0a 0a 20 20 20 20 54 68 69 73 20 69 73 20  ed..    This is 
6ee0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  the number of pa
6ef0: 67 65 73 20 75 73 65 64 20 74 6f 20 68 6f 6c 64  ges used to hold
6f00: 20 61 6c 6c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e   all information
6f10: 20 69 6e 20 74 68 65 20 63 75 72 72 65 6e 74 0a   in the current.
6f20: 20 20 20 20 63 61 74 65 67 6f 72 79 2e 20 20 54      category.  T
6f30: 68 69 73 20 69 73 20 74 68 65 20 73 75 6d 20 6f  his is the sum o
6f40: 66 20 69 6e 64 65 78 2c 20 70 72 69 6d 61 72 79  f index, primary
6f50: 2c 20 61 6e 64 20 6f 76 65 72 66 6c 6f 77 20 70  , and overflow p
6f60: 61 67 65 73 2e 0a 0a 49 6e 64 65 78 20 70 61 67  ages...Index pag
6f70: 65 73 20 75 73 65 64 0a 0a 20 20 20 20 54 68 69  es used..    Thi
6f80: 73 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20  s is the number 
6f90: 6f 66 20 70 61 67 65 73 20 69 6e 20 61 20 74 61  of pages in a ta
6fa0: 62 6c 65 20 42 2d 74 72 65 65 20 74 68 61 74 20  ble B-tree that 
6fb0: 68 6f 6c 64 20 6f 6e 6c 79 20 6b 65 79 20 28 72  hold only key (r
6fc0: 6f 77 69 64 29 0a 20 20 20 20 69 6e 66 6f 72 6d  owid).    inform
6fd0: 61 74 69 6f 6e 20 61 6e 64 20 6e 6f 20 64 61 74  ation and no dat
6fe0: 61 2e 0a 0a 50 72 69 6d 61 72 79 20 70 61 67 65  a...Primary page
6ff0: 73 20 75 73 65 64 0a 0a 20 20 20 20 54 68 69 73  s used..    This
7000: 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f   is the number o
7010: 66 20 42 2d 74 72 65 65 20 70 61 67 65 73 20 74  f B-tree pages t
7020: 68 61 74 20 68 6f 6c 64 20 62 6f 74 68 20 6b 65  hat hold both ke
7030: 79 20 61 6e 64 20 64 61 74 61 2e 0a 0a 4f 76 65  y and data...Ove
7040: 72 66 6c 6f 77 20 70 61 67 65 73 20 75 73 65 64  rflow pages used
7050: 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61 6c 20  ..    The total 
7060: 6e 75 6d 62 65 72 20 6f 66 20 6f 76 65 72 66 6c  number of overfl
7070: 6f 77 20 70 61 67 65 73 20 75 73 65 64 20 66 6f  ow pages used fo
7080: 72 20 74 68 69 73 20 63 61 74 65 67 6f 72 79 2e  r this category.
7090: 0a 0a 55 6e 75 73 65 64 20 62 79 74 65 73 20 6f  ..Unused bytes o
70a0: 6e 20 69 6e 64 65 78 20 70 61 67 65 73 0a 0a 20  n index pages.. 
70b0: 20 20 20 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d     The total num
70c0: 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20  ber of bytes of 
70d0: 75 6e 75 73 65 64 20 73 70 61 63 65 20 6f 6e 20  unused space on 
70e0: 61 6c 6c 20 69 6e 64 65 78 20 70 61 67 65 73 2e  all index pages.
70f0: 20 20 54 68 65 0a 20 20 20 20 70 65 72 63 65 6e    The.    percen
7100: 74 61 67 65 20 61 74 20 74 68 65 20 72 69 67 68  tage at the righ
7110: 74 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20  t is the number 
7120: 6f 66 20 75 6e 75 73 65 64 20 62 79 74 65 73 20  of unused bytes 
7130: 64 69 76 69 64 65 64 20 62 79 20 74 68 65 0a 20  divided by the. 
7140: 20 20 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20     total number 
7150: 6f 66 20 62 79 74 65 73 20 6f 6e 20 69 6e 64 65  of bytes on inde
7160: 78 20 70 61 67 65 73 2e 0a 0a 55 6e 75 73 65 64  x pages...Unused
7170: 20 62 79 74 65 73 20 6f 6e 20 70 72 69 6d 61 72   bytes on primar
7180: 79 20 70 61 67 65 73 0a 0a 20 20 20 20 54 68 65  y pages..    The
7190: 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66   total number of
71a0: 20 62 79 74 65 73 20 6f 66 20 75 6e 75 73 65 64   bytes of unused
71b0: 20 73 70 61 63 65 20 6f 6e 20 61 6c 6c 20 70 72   space on all pr
71c0: 69 6d 61 72 79 20 70 61 67 65 73 2e 20 20 54 68  imary pages.  Th
71d0: 65 0a 20 20 20 20 70 65 72 63 65 6e 74 61 67 65  e.    percentage
71e0: 20 61 74 20 74 68 65 20 72 69 67 68 74 20 69 73   at the right is
71f0: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 75   the number of u
7200: 6e 75 73 65 64 20 62 79 74 65 73 20 64 69 76 69  nused bytes divi
7210: 64 65 64 20 62 79 20 74 68 65 0a 20 20 20 20 74  ded by the.    t
7220: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62  otal number of b
7230: 79 74 65 73 20 6f 6e 20 70 72 69 6d 61 72 79 20  ytes on primary 
7240: 70 61 67 65 73 2e 0a 0a 55 6e 75 73 65 64 20 62  pages...Unused b
7250: 79 74 65 73 20 6f 6e 20 6f 76 65 72 66 6c 6f 77  ytes on overflow
7260: 20 70 61 67 65 73 0a 0a 20 20 20 20 54 68 65 20   pages..    The 
7270: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  total number of 
7280: 62 79 74 65 73 20 6f 66 20 75 6e 75 73 65 64 20  bytes of unused 
7290: 73 70 61 63 65 20 6f 6e 20 61 6c 6c 20 6f 76 65  space on all ove
72a0: 72 66 6c 6f 77 20 70 61 67 65 73 2e 20 20 54 68  rflow pages.  Th
72b0: 65 0a 20 20 20 20 70 65 72 63 65 6e 74 61 67 65  e.    percentage
72c0: 20 61 74 20 74 68 65 20 72 69 67 68 74 20 69 73   at the right is
72d0: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 75   the number of u
72e0: 6e 75 73 65 64 20 62 79 74 65 73 20 64 69 76 69  nused bytes divi
72f0: 64 65 64 20 62 79 20 74 68 65 0a 20 20 20 20 74  ded by the.    t
7300: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62  otal number of b
7310: 79 74 65 73 20 6f 6e 20 6f 76 65 72 66 6c 6f 77  ytes on overflow
7320: 20 70 61 67 65 73 2e 0a 0a 55 6e 75 73 65 64 20   pages...Unused 
7330: 62 79 74 65 73 20 6f 6e 20 61 6c 6c 20 70 61 67  bytes on all pag
7340: 65 73 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61  es..    The tota
7350: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  l number of byte
7360: 73 20 6f 66 20 75 6e 75 73 65 64 20 73 70 61 63  s of unused spac
7370: 65 20 6f 6e 20 61 6c 6c 20 70 72 69 6d 61 72 79  e on all primary
7380: 20 61 6e 64 20 6f 76 65 72 66 6c 6f 77 20 0a 20   and overflow . 
7390: 20 20 20 70 61 67 65 73 2e 20 20 54 68 65 20 70     pages.  The p
73a0: 65 72 63 65 6e 74 61 67 65 20 61 74 20 74 68 65  ercentage at the
73b0: 20 72 69 67 68 74 20 69 73 20 74 68 65 20 6e 75   right is the nu
73c0: 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62  mber of unused b
73d0: 79 74 65 73 20 0a 20 20 20 20 64 69 76 69 64 65  ytes .    divide
73e0: 64 20 62 79 20 74 68 65 20 74 6f 74 61 6c 20 6e  d by the total n
73f0: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 2e 0a  umber of bytes..
7400: 7d 0a 0a 23 20 4f 75 74 70 75 74 20 61 20 64 75  }..# Output a du
7410: 6d 70 20 6f 66 20 74 68 65 20 69 6e 2d 6d 65 6d  mp of the in-mem
7420: 6f 72 79 20 64 61 74 61 62 61 73 65 2e 20 54 68  ory database. Th
7430: 69 73 20 63 61 6e 20 62 65 20 75 73 65 64 20 66  is can be used f
7440: 6f 72 20 6d 6f 72 65 0a 23 20 63 6f 6d 70 6c 65  or more.# comple
7450: 78 20 6f 66 66 6c 69 6e 65 20 61 6e 61 6c 79 73  x offline analys
7460: 69 73 2e 0a 23 0a 70 75 74 73 20 22 2a 2a 2a 2a  is..#.puts "****
7470: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7480: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7490: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
74a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
74b0: 2a 2a 22 0a 70 75 74 73 20 22 54 68 65 20 65 6e  **".puts "The en
74c0: 74 69 72 65 20 74 65 78 74 20 6f 66 20 74 68 69  tire text of thi
74d0: 73 20 72 65 70 6f 72 74 20 63 61 6e 20 62 65 20  s report can be 
74e0: 73 6f 75 72 63 65 64 20 69 6e 74 6f 20 61 6e 79  sourced into any
74f0: 20 53 51 4c 20 64 61 74 61 62 61 73 65 22 0a 70   SQL database".p
7500: 75 74 73 20 22 65 6e 67 69 6e 65 20 66 6f 72 20  uts "engine for 
7510: 66 75 72 74 68 65 72 20 61 6e 61 6c 79 73 69 73  further analysis
7520: 2e 20 20 41 6c 6c 20 6f 66 20 74 68 65 20 74 65  .  All of the te
7530: 78 74 20 61 62 6f 76 65 20 69 73 20 61 6e 20 53  xt above is an S
7540: 51 4c 20 63 6f 6d 6d 65 6e 74 2e 22 0a 70 75 74  QL comment.".put
7550: 73 20 22 54 68 65 20 64 61 74 61 20 75 73 65 64  s "The data used
7560: 20 74 6f 20 67 65 6e 65 72 61 74 65 20 74 68 69   to generate thi
7570: 73 20 72 65 70 6f 72 74 20 66 6f 6c 6c 6f 77 73  s report follows
7580: 3a 22 0a 70 75 74 73 20 22 2a 2f 22 0a 70 75 74  :".puts "*/".put
7590: 73 20 22 42 45 47 49 4e 3b 22 0a 70 75 74 73 20  s "BEGIN;".puts 
75a0: 24 74 61 62 6c 65 64 65 66 0a 75 6e 73 65 74 20  $tabledef.unset 
75b0: 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 78 0a 6d 65  -nocomplain x.me
75c0: 6d 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 2a  m eval {SELECT *
75d0: 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73 65 64   FROM space_used
75e0: 7d 20 78 20 7b 0a 20 20 70 75 74 73 20 2d 6e 6f  } x {.  puts -no
75f0: 6e 65 77 6c 69 6e 65 20 22 49 4e 53 45 52 54 20  newline "INSERT 
7600: 49 4e 54 4f 20 73 70 61 63 65 5f 75 73 65 64 20  INTO space_used 
7610: 56 41 4c 55 45 53 22 0a 20 20 73 65 74 20 73 65  VALUES".  set se
7620: 70 20 28 0a 20 20 66 6f 72 65 61 63 68 20 63 6f  p (.  foreach co
7630: 6c 20 24 78 28 2a 29 20 7b 0a 20 20 20 20 73 65  l $x(*) {.    se
7640: 74 20 76 20 24 78 28 24 63 6f 6c 29 0a 20 20 20  t v $x($col).   
7650: 20 69 66 20 7b 24 76 3d 3d 22 22 20 7c 7c 20 21   if {$v=="" || !
7660: 5b 73 74 72 69 6e 67 20 69 73 20 64 6f 75 62 6c  [string is doubl
7670: 65 20 24 76 5d 7d 20 7b 73 65 74 20 76 20 5b 71  e $v]} {set v [q
7680: 75 6f 74 65 20 24 76 5d 7d 0a 20 20 20 20 70 75  uote $v]}.    pu
7690: 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 73  ts -nonewline $s
76a0: 65 70 24 76 0a 20 20 20 20 73 65 74 20 73 65 70  ep$v.    set sep
76b0: 20 2c 0a 20 20 7d 0a 20 20 70 75 74 73 20 22 29   ,.  }.  puts ")
76c0: 3b 22 0a 7d 0a 70 75 74 73 20 22 43 4f 4d 4d 49  ;".}.puts "COMMI
76d0: 54 3b 22 0a 0a 7d 20 65 72 72 5d 7d 20 7b 0a 20  T;"..} err]} {. 
76e0: 20 70 75 74 73 20 22 45 52 52 4f 52 3a 20 24 65   puts "ERROR: $e
76f0: 72 72 22 0a 20 20 70 75 74 73 20 24 65 72 72 6f  rr".  puts $erro
7700: 72 49 6e 66 6f 0a 20 20 65 78 69 74 20 31 0a 7d  rInfo.  exit 1.}
7710: 0a                                               .