/ Hex Artifact Content
Login

Artifact 5a26205111e6fa856d9b1535b1637744dcdb930b:


0000: 2f 2a 0a 2a 2a 20 32 30 31 35 2d 30 34 2d 30 36  /*.** 2015-04-06
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a  ***************.
0170: 2a 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 61 20  **.** This is a 
0180: 75 74 69 6c 69 74 79 20 70 72 6f 67 72 61 6d 20  utility program 
0190: 74 68 61 74 20 63 6f 6d 70 75 74 65 73 20 74 68  that computes th
01a0: 65 20 64 69 66 66 65 72 65 6e 63 65 73 20 69 6e  e differences in
01b0: 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20 62 65 74 77   content.** betw
01c0: 65 65 6e 20 74 77 6f 20 53 51 4c 69 74 65 20 64  een two SQLite d
01d0: 61 74 61 62 61 73 65 73 2e 0a 2a 2a 0a 2a 2a 20  atabases..**.** 
01e0: 54 6f 20 63 6f 6d 70 69 6c 65 2c 20 73 69 6d 70  To compile, simp
01f0: 6c 79 20 6c 69 6e 6b 20 61 67 61 69 6e 73 74 20  ly link against 
0200: 53 51 4c 69 74 65 2e 0a 2a 2a 0a 2a 2a 20 53 65  SQLite..**.** Se
0210: 65 20 74 68 65 20 73 68 6f 77 48 65 6c 70 28 29  e the showHelp()
0220: 20 72 6f 75 74 69 6e 65 20 62 65 6c 6f 77 20 66   routine below f
0230: 6f 72 20 61 20 62 72 69 65 66 20 64 65 73 63 72  or a brief descr
0240: 69 70 74 69 6f 6e 20 6f 66 20 68 6f 77 20 74 6f  iption of how to
0250: 0a 2a 2a 20 72 75 6e 20 74 68 65 20 75 74 69 6c  .** run the util
0260: 69 74 79 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65  ity..*/.#include
0270: 20 3c 73 74 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c   <stdio.h>.#incl
0280: 75 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23  ude <stdlib.h>.#
0290: 69 6e 63 6c 75 64 65 20 3c 73 74 64 61 72 67 2e  include <stdarg.
02a0: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 63 74 79  h>.#include <cty
02b0: 70 65 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  pe.h>.#include <
02c0: 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75  string.h>.#inclu
02d0: 64 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a 23 69  de <assert.h>.#i
02e0: 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65 33 2e  nclude "sqlite3.
02f0: 68 22 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 67 6c  h"../*.** All gl
0300: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20 61  obal variables a
0310: 72 65 20 67 61 74 68 65 72 65 64 20 69 6e 74 6f  re gathered into
0320: 20 74 68 65 20 22 67 22 20 73 69 6e 67 6c 65 74   the "g" singlet
0330: 6f 6e 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 47 6c  on..*/.struct Gl
0340: 6f 62 61 6c 56 61 72 73 20 7b 0a 20 20 63 6f 6e  obalVars {.  con
0350: 73 74 20 63 68 61 72 20 2a 7a 41 72 67 76 30 3b  st char *zArgv0;
0360: 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f         /* Name o
0370: 66 20 70 72 6f 67 72 61 6d 20 2a 2f 0a 20 20 69  f program */.  i
0380: 6e 74 20 62 53 63 68 65 6d 61 4f 6e 6c 79 3b 20  nt bSchemaOnly; 
0390: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e 6c 79           /* Only
03a0: 20 73 68 6f 77 20 73 63 68 65 6d 61 20 64 69 66   show schema dif
03b0: 66 65 72 65 6e 63 65 73 20 2a 2f 0a 20 20 69 6e  ferences */.  in
03c0: 74 20 62 53 63 68 65 6d 61 50 4b 3b 20 20 20 20  t bSchemaPK;    
03d0: 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 20 74          /* Use t
03e0: 68 65 20 73 63 68 65 6d 61 2d 64 65 66 69 6e 65  he schema-define
03f0: 64 20 50 4b 2c 20 6e 6f 74 20 74 68 65 20 74 72  d PK, not the tr
0400: 75 65 20 50 4b 20 2a 2f 0a 20 20 75 6e 73 69 67  ue PK */.  unsig
0410: 6e 65 64 20 66 44 65 62 75 67 3b 20 20 20 20 20  ned fDebug;     
0420: 20 20 20 20 20 2f 2a 20 44 65 62 75 67 20 66 6c       /* Debug fl
0430: 61 67 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ags */.  sqlite3
0440: 20 2a 64 62 3b 20 20 20 20 20 20 20 20 20 20 20   *db;           
0450: 20 20 20 2f 2a 20 54 68 65 20 64 61 74 61 62 61     /* The databa
0460: 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f  se connection */
0470: 0a 7d 20 67 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c  .} g;../*.** All
0480: 6f 77 65 64 20 76 61 6c 75 65 73 20 66 6f 72 20  owed values for 
0490: 67 2e 66 44 65 62 75 67 0a 2a 2f 0a 23 64 65 66  g.fDebug.*/.#def
04a0: 69 6e 65 20 44 45 42 55 47 5f 43 4f 4c 55 4d 4e  ine DEBUG_COLUMN
04b0: 5f 4e 41 4d 45 53 20 20 30 78 30 30 30 30 30 31  _NAMES  0x000001
04c0: 0a 23 64 65 66 69 6e 65 20 44 45 42 55 47 5f 44  .#define DEBUG_D
04d0: 49 46 46 5f 53 51 4c 20 20 20 20 20 20 30 78 30  IFF_SQL      0x0
04e0: 30 30 30 30 32 0a 0a 2f 2a 0a 2a 2a 20 44 79 6e  00002../*.** Dyn
04f0: 61 6d 69 63 20 73 74 72 69 6e 67 20 6f 62 6a 65  amic string obje
0500: 63 74 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74  ct.*/.typedef st
0510: 72 75 63 74 20 53 74 72 20 53 74 72 3b 0a 73 74  ruct Str Str;.st
0520: 72 75 63 74 20 53 74 72 20 7b 0a 20 20 63 68 61  ruct Str {.  cha
0530: 72 20 2a 7a 3b 20 20 20 20 20 20 20 20 2f 2a 20  r *z;        /* 
0540: 54 65 78 74 20 6f 66 20 74 68 65 20 73 74 72 69  Text of the stri
0550: 6e 67 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 6c 6c  ng */.  int nAll
0560: 6f 63 3b 20 20 20 20 20 2f 2a 20 42 79 74 65 73  oc;     /* Bytes
0570: 20 61 6c 6c 6f 63 61 74 65 64 20 69 6e 20 7a 5b   allocated in z[
0580: 5d 20 2a 2f 0a 20 20 69 6e 74 20 6e 55 73 65 64  ] */.  int nUsed
0590: 3b 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20  ;      /* Bytes 
05a0: 61 63 74 75 61 6c 6c 79 20 75 73 65 64 20 69 6e  actually used in
05b0: 20 7a 5b 5d 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a   z[] */.};../*.*
05c0: 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61 20 53  * Initialize a S
05d0: 74 72 20 6f 62 6a 65 63 74 0a 2a 2f 0a 73 74 61  tr object.*/.sta
05e0: 74 69 63 20 76 6f 69 64 20 73 74 72 49 6e 69 74  tic void strInit
05f0: 28 53 74 72 20 2a 70 29 7b 0a 20 20 70 2d 3e 7a  (Str *p){.  p->z
0600: 20 3d 20 30 3b 0a 20 20 70 2d 3e 6e 41 6c 6c 6f   = 0;.  p->nAllo
0610: 63 20 3d 20 30 3b 0a 20 20 70 2d 3e 6e 55 73 65  c = 0;.  p->nUse
0620: 64 20 3d 20 30 3b 0a 7d 0a 20 20 0a 2f 2a 0a 2a  d = 0;.}.  ./*.*
0630: 2a 20 50 72 69 6e 74 20 61 6e 20 65 72 72 6f 72  * Print an error
0640: 20 72 65 73 75 6c 74 69 6e 67 20 66 72 6f 6d 20   resulting from 
0650: 66 61 75 6c 74 69 6e 67 20 63 6f 6d 6d 61 6e 64  faulting command
0660: 2d 6c 69 6e 65 20 61 72 67 75 6d 65 6e 74 73 20  -line arguments 
0670: 61 6e 64 0a 2a 2a 20 61 62 6f 72 74 20 74 68 65  and.** abort the
0680: 20 70 72 6f 67 72 61 6d 2e 0a 2a 2f 0a 73 74 61   program..*/.sta
0690: 74 69 63 20 76 6f 69 64 20 63 6d 64 6c 69 6e 65  tic void cmdline
06a0: 45 72 72 6f 72 28 63 6f 6e 73 74 20 63 68 61 72  Error(const char
06b0: 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b   *zFormat, ...){
06c0: 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20  .  va_list ap;. 
06d0: 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c   fprintf(stderr,
06e0: 20 22 25 73 3a 20 22 2c 20 67 2e 7a 41 72 67 76   "%s: ", g.zArgv
06f0: 30 29 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61  0);.  va_start(a
0700: 70 2c 20 7a 46 6f 72 6d 61 74 29 3b 0a 20 20 76  p, zFormat);.  v
0710: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
0720: 7a 46 6f 72 6d 61 74 2c 20 61 70 29 3b 0a 20 20  zFormat, ap);.  
0730: 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 66 70  va_end(ap);.  fp
0740: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 5c  rintf(stderr, "\
0750: 6e 5c 22 25 73 20 2d 2d 68 65 6c 70 5c 22 20 66  n\"%s --help\" f
0760: 6f 72 20 6d 6f 72 65 20 68 65 6c 70 5c 6e 22 2c  or more help\n",
0770: 20 67 2e 7a 41 72 67 76 30 29 3b 0a 20 20 65 78   g.zArgv0);.  ex
0780: 69 74 28 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  it(1);.}../*.** 
0790: 50 72 69 6e 74 20 61 6e 20 65 72 72 6f 72 20 6d  Print an error m
07a0: 65 73 73 61 67 65 20 66 6f 72 20 61 6e 20 65 72  essage for an er
07b0: 72 6f 72 20 74 68 61 74 20 6f 63 63 75 72 73 20  ror that occurs 
07c0: 61 74 20 72 75 6e 74 69 6d 65 2c 20 74 68 65 6e  at runtime, then
07d0: 0a 2a 2a 20 61 62 6f 72 74 20 74 68 65 20 70 72  .** abort the pr
07e0: 6f 67 72 61 6d 2e 0a 2a 2f 0a 73 74 61 74 69 63  ogram..*/.static
07f0: 20 76 6f 69 64 20 72 75 6e 74 69 6d 65 45 72 72   void runtimeErr
0800: 6f 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  or(const char *z
0810: 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20  Format, ...){.  
0820: 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 66 70  va_list ap;.  fp
0830: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25  rintf(stderr, "%
0840: 73 3a 20 22 2c 20 67 2e 7a 41 72 67 76 30 29 3b  s: ", g.zArgv0);
0850: 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20  .  va_start(ap, 
0860: 7a 46 6f 72 6d 61 74 29 3b 0a 20 20 76 66 70 72  zFormat);.  vfpr
0870: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 7a 46 6f  intf(stderr, zFo
0880: 72 6d 61 74 2c 20 61 70 29 3b 0a 20 20 76 61 5f  rmat, ap);.  va_
0890: 65 6e 64 28 61 70 29 3b 0a 20 20 66 70 72 69 6e  end(ap);.  fprin
08a0: 74 66 28 73 74 64 65 72 72 2c 20 22 5c 6e 22 29  tf(stderr, "\n")
08b0: 3b 0a 20 20 65 78 69 74 28 31 29 3b 0a 7d 0a 0a  ;.  exit(1);.}..
08c0: 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6c 6c 20 6d  /*.** Free all m
08d0: 65 6d 6f 72 79 20 68 65 6c 64 20 62 79 20 61 20  emory held by a 
08e0: 53 74 72 20 6f 62 6a 65 63 74 0a 2a 2f 0a 73 74  Str object.*/.st
08f0: 61 74 69 63 20 76 6f 69 64 20 73 74 72 46 72 65  atic void strFre
0900: 65 28 53 74 72 20 2a 70 29 7b 0a 20 20 73 71 6c  e(Str *p){.  sql
0910: 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a 29 3b  ite3_free(p->z);
0920: 0a 20 20 73 74 72 49 6e 69 74 28 70 29 3b 0a 7d  .  strInit(p);.}
0930: 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 66 6f 72 6d  ../*.** Add form
0940: 61 74 74 65 64 20 74 65 78 74 20 74 6f 20 74 68  atted text to th
0950: 65 20 65 6e 64 20 6f 66 20 61 20 53 74 72 20 6f  e end of a Str o
0960: 62 6a 65 63 74 0a 2a 2f 0a 73 74 61 74 69 63 20  bject.*/.static 
0970: 76 6f 69 64 20 73 74 72 50 72 69 6e 74 66 28 53  void strPrintf(S
0980: 74 72 20 2a 70 2c 20 63 6f 6e 73 74 20 63 68 61  tr *p, const cha
0990: 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29  r *zFormat, ...)
09a0: 7b 0a 20 20 69 6e 74 20 6e 4e 65 77 3b 0a 20 20  {.  int nNew;.  
09b0: 66 6f 72 28 3b 3b 29 7b 0a 20 20 20 20 69 66 28  for(;;){.    if(
09c0: 20 70 2d 3e 7a 20 29 7b 0a 20 20 20 20 20 20 76   p->z ){.      v
09d0: 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 20 20 20  a_list ap;.     
09e0: 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46   va_start(ap, zF
09f0: 6f 72 6d 61 74 29 3b 0a 20 20 20 20 20 20 73 71  ormat);.      sq
0a00: 6c 69 74 65 33 5f 76 73 6e 70 72 69 6e 74 66 28  lite3_vsnprintf(
0a10: 70 2d 3e 6e 41 6c 6c 6f 63 2d 70 2d 3e 6e 55 73  p->nAlloc-p->nUs
0a20: 65 64 2c 20 70 2d 3e 7a 2b 70 2d 3e 6e 55 73 65  ed, p->z+p->nUse
0a30: 64 2c 20 7a 46 6f 72 6d 61 74 2c 20 61 70 29 3b  d, zFormat, ap);
0a40: 0a 20 20 20 20 20 20 76 61 5f 65 6e 64 28 61 70  .      va_end(ap
0a50: 29 3b 0a 20 20 20 20 20 20 6e 4e 65 77 20 3d 20  );.      nNew = 
0a60: 28 69 6e 74 29 73 74 72 6c 65 6e 28 70 2d 3e 7a  (int)strlen(p->z
0a70: 20 2b 20 70 2d 3e 6e 55 73 65 64 29 3b 0a 20 20   + p->nUsed);.  
0a80: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6e    }else{.      n
0a90: 4e 65 77 20 3d 20 70 2d 3e 6e 41 6c 6c 6f 63 3b  New = p->nAlloc;
0aa0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70  .    }.    if( p
0ab0: 2d 3e 6e 55 73 65 64 2b 6e 4e 65 77 20 3c 20 70  ->nUsed+nNew < p
0ac0: 2d 3e 6e 41 6c 6c 6f 63 2d 31 20 29 7b 0a 20 20  ->nAlloc-1 ){.  
0ad0: 20 20 20 20 70 2d 3e 6e 55 73 65 64 20 2b 3d 20      p->nUsed += 
0ae0: 6e 4e 65 77 3b 0a 20 20 20 20 20 20 62 72 65 61  nNew;.      brea
0af0: 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d 3e  k;.    }.    p->
0b00: 6e 41 6c 6c 6f 63 20 3d 20 70 2d 3e 6e 41 6c 6c  nAlloc = p->nAll
0b10: 6f 63 2a 32 20 2b 20 31 30 30 30 3b 0a 20 20 20  oc*2 + 1000;.   
0b20: 20 70 2d 3e 7a 20 3d 20 73 71 6c 69 74 65 33 5f   p->z = sqlite3_
0b30: 72 65 61 6c 6c 6f 63 28 70 2d 3e 7a 2c 20 70 2d  realloc(p->z, p-
0b40: 3e 6e 41 6c 6c 6f 63 29 3b 0a 20 20 20 20 69 66  >nAlloc);.    if
0b50: 28 20 70 2d 3e 7a 3d 3d 30 20 29 20 72 75 6e 74  ( p->z==0 ) runt
0b60: 69 6d 65 45 72 72 6f 72 28 22 6f 75 74 20 6f 66  imeError("out of
0b70: 20 6d 65 6d 6f 72 79 22 29 3b 0a 20 20 7d 0a 7d   memory");.  }.}
0b80: 0a 0a 0a 0a 2f 2a 20 53 61 66 65 6c 79 20 71 75  ..../* Safely qu
0b90: 6f 74 65 20 61 6e 20 53 51 4c 20 69 64 65 6e 74  ote an SQL ident
0ba0: 69 66 69 65 72 2e 20 20 55 73 65 20 74 68 65 20  ifier.  Use the 
0bb0: 6d 69 6e 69 6d 75 6d 20 61 6d 6f 75 6e 74 20 6f  minimum amount o
0bc0: 66 20 74 72 61 6e 73 66 6f 72 6d 61 74 69 6f 6e  f transformation
0bd0: 0a 2a 2a 20 6e 65 63 65 73 73 61 72 79 20 74 6f  .** necessary to
0be0: 20 61 6c 6c 6f 77 20 74 68 65 20 73 74 72 69 6e   allow the strin
0bf0: 67 20 74 6f 20 62 65 20 75 73 65 64 20 77 69 74  g to be used wit
0c00: 68 20 25 73 2e 0a 2a 2a 0a 2a 2a 20 53 70 61 63  h %s..**.** Spac
0c10: 65 20 74 6f 20 68 6f 6c 64 20 74 68 65 20 72 65  e to hold the re
0c20: 74 75 72 6e 65 64 20 73 74 72 69 6e 67 20 69 73  turned string is
0c30: 20 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d 20 73   obtained from s
0c40: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 29 2e  qlite3_malloc().
0c50: 20 20 54 68 65 0a 2a 2a 20 63 61 6c 6c 65 72 20    The.** caller 
0c60: 69 73 20 72 65 73 70 6f 6e 73 69 62 6c 65 20 66  is responsible f
0c70: 6f 72 20 65 6e 73 75 72 69 6e 67 20 74 68 69 73  or ensuring this
0c80: 20 73 70 61 63 65 20 69 73 20 66 72 65 65 64 20   space is freed 
0c90: 77 68 65 6e 20 6e 6f 20 6c 6f 6e 67 65 72 0a 2a  when no longer.*
0ca0: 2a 20 6e 65 65 64 65 64 2e 0a 2a 2f 0a 73 74 61  * needed..*/.sta
0cb0: 74 69 63 20 63 68 61 72 20 2a 73 61 66 65 49 64  tic char *safeId
0cc0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 49 64  (const char *zId
0cd0: 29 7b 0a 20 20 2f 2a 20 41 6c 6c 20 53 51 4c 69  ){.  /* All SQLi
0ce0: 74 65 20 6b 65 79 77 6f 72 64 73 2c 20 69 6e 20  te keywords, in 
0cf0: 61 6c 70 68 61 62 65 74 69 63 61 6c 20 6f 72 64  alphabetical ord
0d00: 65 72 20 2a 2f 0a 20 20 73 74 61 74 69 63 20 63  er */.  static c
0d10: 6f 6e 73 74 20 63 68 61 72 20 2a 61 7a 4b 65 79  onst char *azKey
0d20: 77 6f 72 64 73 5b 5d 20 3d 20 7b 0a 20 20 20 20  words[] = {.    
0d30: 22 41 42 4f 52 54 22 2c 20 22 41 43 54 49 4f 4e  "ABORT", "ACTION
0d40: 22 2c 20 22 41 44 44 22 2c 20 22 41 46 54 45 52  ", "ADD", "AFTER
0d50: 22 2c 20 22 41 4c 4c 22 2c 20 22 41 4c 54 45 52  ", "ALL", "ALTER
0d60: 22 2c 20 22 41 4e 41 4c 59 5a 45 22 2c 20 22 41  ", "ANALYZE", "A
0d70: 4e 44 22 2c 20 22 41 53 22 2c 0a 20 20 20 20 22  ND", "AS",.    "
0d80: 41 53 43 22 2c 20 22 41 54 54 41 43 48 22 2c 20  ASC", "ATTACH", 
0d90: 22 41 55 54 4f 49 4e 43 52 45 4d 45 4e 54 22 2c  "AUTOINCREMENT",
0da0: 20 22 42 45 46 4f 52 45 22 2c 20 22 42 45 47 49   "BEFORE", "BEGI
0db0: 4e 22 2c 20 22 42 45 54 57 45 45 4e 22 2c 20 22  N", "BETWEEN", "
0dc0: 42 59 22 2c 0a 20 20 20 20 22 43 41 53 43 41 44  BY",.    "CASCAD
0dd0: 45 22 2c 20 22 43 41 53 45 22 2c 20 22 43 41 53  E", "CASE", "CAS
0de0: 54 22 2c 20 22 43 48 45 43 4b 22 2c 20 22 43 4f  T", "CHECK", "CO
0df0: 4c 4c 41 54 45 22 2c 20 22 43 4f 4c 55 4d 4e 22  LLATE", "COLUMN"
0e00: 2c 20 22 43 4f 4d 4d 49 54 22 2c 0a 20 20 20 20  , "COMMIT",.    
0e10: 22 43 4f 4e 46 4c 49 43 54 22 2c 20 22 43 4f 4e  "CONFLICT", "CON
0e20: 53 54 52 41 49 4e 54 22 2c 20 22 43 52 45 41 54  STRAINT", "CREAT
0e30: 45 22 2c 20 22 43 52 4f 53 53 22 2c 20 22 43 55  E", "CROSS", "CU
0e40: 52 52 45 4e 54 5f 44 41 54 45 22 2c 0a 20 20 20  RRENT_DATE",.   
0e50: 20 22 43 55 52 52 45 4e 54 5f 54 49 4d 45 22 2c   "CURRENT_TIME",
0e60: 20 22 43 55 52 52 45 4e 54 5f 54 49 4d 45 53 54   "CURRENT_TIMEST
0e70: 41 4d 50 22 2c 20 22 44 41 54 41 42 41 53 45 22  AMP", "DATABASE"
0e80: 2c 20 22 44 45 46 41 55 4c 54 22 2c 20 22 44 45  , "DEFAULT", "DE
0e90: 46 45 52 52 41 42 4c 45 22 2c 0a 20 20 20 20 22  FERRABLE",.    "
0ea0: 44 45 46 45 52 52 45 44 22 2c 20 22 44 45 4c 45  DEFERRED", "DELE
0eb0: 54 45 22 2c 20 22 44 45 53 43 22 2c 20 22 44 45  TE", "DESC", "DE
0ec0: 54 41 43 48 22 2c 20 22 44 49 53 54 49 4e 43 54  TACH", "DISTINCT
0ed0: 22 2c 20 22 44 52 4f 50 22 2c 20 22 45 41 43 48  ", "DROP", "EACH
0ee0: 22 2c 0a 20 20 20 20 22 45 4c 53 45 22 2c 20 22  ",.    "ELSE", "
0ef0: 45 4e 44 22 2c 20 22 45 53 43 41 50 45 22 2c 20  END", "ESCAPE", 
0f00: 22 45 58 43 45 50 54 22 2c 20 22 45 58 43 4c 55  "EXCEPT", "EXCLU
0f10: 53 49 56 45 22 2c 20 22 45 58 49 53 54 53 22 2c  SIVE", "EXISTS",
0f20: 20 22 45 58 50 4c 41 49 4e 22 2c 0a 20 20 20 20   "EXPLAIN",.    
0f30: 22 46 41 49 4c 22 2c 20 22 46 4f 52 22 2c 20 22  "FAIL", "FOR", "
0f40: 46 4f 52 45 49 47 4e 22 2c 20 22 46 52 4f 4d 22  FOREIGN", "FROM"
0f50: 2c 20 22 46 55 4c 4c 22 2c 20 22 47 4c 4f 42 22  , "FULL", "GLOB"
0f60: 2c 20 22 47 52 4f 55 50 22 2c 20 22 48 41 56 49  , "GROUP", "HAVI
0f70: 4e 47 22 2c 20 22 49 46 22 2c 0a 20 20 20 20 22  NG", "IF",.    "
0f80: 49 47 4e 4f 52 45 22 2c 20 22 49 4d 4d 45 44 49  IGNORE", "IMMEDI
0f90: 41 54 45 22 2c 20 22 49 4e 22 2c 20 22 49 4e 44  ATE", "IN", "IND
0fa0: 45 58 22 2c 20 22 49 4e 44 45 58 45 44 22 2c 20  EX", "INDEXED", 
0fb0: 22 49 4e 49 54 49 41 4c 4c 59 22 2c 20 22 49 4e  "INITIALLY", "IN
0fc0: 4e 45 52 22 2c 0a 20 20 20 20 22 49 4e 53 45 52  NER",.    "INSER
0fd0: 54 22 2c 20 22 49 4e 53 54 45 41 44 22 2c 20 22  T", "INSTEAD", "
0fe0: 49 4e 54 45 52 53 45 43 54 22 2c 20 22 49 4e 54  INTERSECT", "INT
0ff0: 4f 22 2c 20 22 49 53 22 2c 20 22 49 53 4e 55 4c  O", "IS", "ISNUL
1000: 4c 22 2c 20 22 4a 4f 49 4e 22 2c 20 22 4b 45 59  L", "JOIN", "KEY
1010: 22 2c 0a 20 20 20 20 22 4c 45 46 54 22 2c 20 22  ",.    "LEFT", "
1020: 4c 49 4b 45 22 2c 20 22 4c 49 4d 49 54 22 2c 20  LIKE", "LIMIT", 
1030: 22 4d 41 54 43 48 22 2c 20 22 4e 41 54 55 52 41  "MATCH", "NATURA
1040: 4c 22 2c 20 22 4e 4f 22 2c 20 22 4e 4f 54 22 2c  L", "NO", "NOT",
1050: 20 22 4e 4f 54 4e 55 4c 4c 22 2c 0a 20 20 20 20   "NOTNULL",.    
1060: 22 4e 55 4c 4c 22 2c 20 22 4f 46 22 2c 20 22 4f  "NULL", "OF", "O
1070: 46 46 53 45 54 22 2c 20 22 4f 4e 22 2c 20 22 4f  FFSET", "ON", "O
1080: 52 22 2c 20 22 4f 52 44 45 52 22 2c 20 22 4f 55  R", "ORDER", "OU
1090: 54 45 52 22 2c 20 22 50 4c 41 4e 22 2c 20 22 50  TER", "PLAN", "P
10a0: 52 41 47 4d 41 22 2c 0a 20 20 20 20 22 50 52 49  RAGMA",.    "PRI
10b0: 4d 41 52 59 22 2c 20 22 51 55 45 52 59 22 2c 20  MARY", "QUERY", 
10c0: 22 52 41 49 53 45 22 2c 20 22 52 45 43 55 52 53  "RAISE", "RECURS
10d0: 49 56 45 22 2c 20 22 52 45 46 45 52 45 4e 43 45  IVE", "REFERENCE
10e0: 53 22 2c 20 22 52 45 47 45 58 50 22 2c 0a 20 20  S", "REGEXP",.  
10f0: 20 20 22 52 45 49 4e 44 45 58 22 2c 20 22 52 45    "REINDEX", "RE
1100: 4c 45 41 53 45 22 2c 20 22 52 45 4e 41 4d 45 22  LEASE", "RENAME"
1110: 2c 20 22 52 45 50 4c 41 43 45 22 2c 20 22 52 45  , "REPLACE", "RE
1120: 53 54 52 49 43 54 22 2c 20 22 52 49 47 48 54 22  STRICT", "RIGHT"
1130: 2c 0a 20 20 20 20 22 52 4f 4c 4c 42 41 43 4b 22  ,.    "ROLLBACK"
1140: 2c 20 22 52 4f 57 22 2c 20 22 53 41 56 45 50 4f  , "ROW", "SAVEPO
1150: 49 4e 54 22 2c 20 22 53 45 4c 45 43 54 22 2c 20  INT", "SELECT", 
1160: 22 53 45 54 22 2c 20 22 54 41 42 4c 45 22 2c 20  "SET", "TABLE", 
1170: 22 54 45 4d 50 22 2c 0a 20 20 20 20 22 54 45 4d  "TEMP",.    "TEM
1180: 50 4f 52 41 52 59 22 2c 20 22 54 48 45 4e 22 2c  PORARY", "THEN",
1190: 20 22 54 4f 22 2c 20 22 54 52 41 4e 53 41 43 54   "TO", "TRANSACT
11a0: 49 4f 4e 22 2c 20 22 54 52 49 47 47 45 52 22 2c  ION", "TRIGGER",
11b0: 20 22 55 4e 49 4f 4e 22 2c 20 22 55 4e 49 51 55   "UNION", "UNIQU
11c0: 45 22 2c 0a 20 20 20 20 22 55 50 44 41 54 45 22  E",.    "UPDATE"
11d0: 2c 20 22 55 53 49 4e 47 22 2c 20 22 56 41 43 55  , "USING", "VACU
11e0: 55 4d 22 2c 20 22 56 41 4c 55 45 53 22 2c 20 22  UM", "VALUES", "
11f0: 56 49 45 57 22 2c 20 22 56 49 52 54 55 41 4c 22  VIEW", "VIRTUAL"
1200: 2c 20 22 57 48 45 4e 22 2c 20 22 57 48 45 52 45  , "WHEN", "WHERE
1210: 22 2c 0a 20 20 20 20 22 57 49 54 48 22 2c 20 22  ",.    "WITH", "
1220: 57 49 54 48 4f 55 54 22 2c 0a 20 20 7d 3b 0a 20  WITHOUT",.  };. 
1230: 20 69 6e 74 20 6c 77 72 2c 20 75 70 72 2c 20 6d   int lwr, upr, m
1240: 69 64 2c 20 63 2c 20 69 2c 20 78 3b 0a 20 20 69  id, c, i, x;.  i
1250: 66 28 20 7a 49 64 5b 30 5d 3d 3d 30 20 29 20 72  f( zId[0]==0 ) r
1260: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 5f 6d 70  eturn sqlite3_mp
1270: 72 69 6e 74 66 28 22 5c 22 5c 22 22 29 3b 0a 20  rintf("\"\"");. 
1280: 20 66 6f 72 28 69 3d 78 3d 30 3b 20 28 63 20 3d   for(i=x=0; (c =
1290: 20 7a 49 64 5b 69 5d 29 21 3d 30 3b 20 69 2b 2b   zId[i])!=0; i++
12a0: 29 7b 0a 20 20 20 20 69 66 28 20 21 69 73 61 6c  ){.    if( !isal
12b0: 70 68 61 28 63 29 20 26 26 20 63 21 3d 27 5f 27  pha(c) && c!='_'
12c0: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 69 3e   ){.      if( i>
12d0: 30 20 26 26 20 69 73 64 69 67 69 74 28 63 29 20  0 && isdigit(c) 
12e0: 29 7b 0a 20 20 20 20 20 20 20 20 78 2b 2b 3b 0a  ){.        x++;.
12f0: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
1300: 20 20 20 20 20 72 65 74 75 72 6e 20 73 71 6c 69       return sqli
1310: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 5c 22 25  te3_mprintf("\"%
1320: 77 5c 22 22 2c 20 7a 49 64 29 3b 0a 20 20 20 20  w\"", zId);.    
1330: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20    }.    }.  }.  
1340: 69 66 28 20 78 20 29 20 72 65 74 75 72 6e 20 73  if( x ) return s
1350: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
1360: 25 73 22 2c 20 7a 49 64 29 3b 0a 20 20 6c 77 72  %s", zId);.  lwr
1370: 20 3d 20 30 3b 0a 20 20 75 70 72 20 3d 20 73 69   = 0;.  upr = si
1380: 7a 65 6f 66 28 61 7a 4b 65 79 77 6f 72 64 73 29  zeof(azKeywords)
1390: 2f 73 69 7a 65 6f 66 28 61 7a 4b 65 79 77 6f 72  /sizeof(azKeywor
13a0: 64 73 5b 30 5d 29 20 2d 20 31 3b 0a 20 20 77 68  ds[0]) - 1;.  wh
13b0: 69 6c 65 28 20 6c 77 72 3c 3d 75 70 72 20 29 7b  ile( lwr<=upr ){
13c0: 0a 20 20 20 20 6d 69 64 20 3d 20 28 6c 77 72 2b  .    mid = (lwr+
13d0: 75 70 72 29 2f 32 3b 0a 20 20 20 20 63 20 3d 20  upr)/2;.    c = 
13e0: 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d 70 28  sqlite3_stricmp(
13f0: 61 7a 4b 65 79 77 6f 72 64 73 5b 6d 69 64 5d 2c  azKeywords[mid],
1400: 20 7a 49 64 29 3b 0a 20 20 20 20 69 66 28 20 63   zId);.    if( c
1410: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 73 71 6c  ==0 ) return sql
1420: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 5c 22  ite3_mprintf("\"
1430: 25 77 5c 22 22 2c 20 7a 49 64 29 3b 0a 20 20 20  %w\"", zId);.   
1440: 20 69 66 28 20 63 3c 30 20 29 7b 0a 20 20 20 20   if( c<0 ){.    
1450: 20 20 6c 77 72 20 3d 20 6d 69 64 2b 31 3b 0a 20    lwr = mid+1;. 
1460: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
1470: 75 70 72 20 3d 20 6d 69 64 2d 31 3b 0a 20 20 20  upr = mid-1;.   
1480: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
1490: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
14a0: 22 25 73 22 2c 20 7a 49 64 29 3b 0a 7d 0a 0a 2f  "%s", zId);.}../
14b0: 2a 0a 2a 2a 20 50 72 65 70 61 72 65 20 61 20 6e  *.** Prepare a n
14c0: 65 77 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74  ew SQL statement
14d0: 2e 20 20 50 72 69 6e 74 20 61 6e 20 65 72 72 6f  .  Print an erro
14e0: 72 20 61 6e 64 20 61 62 6f 72 74 20 69 66 20 61  r and abort if a
14f0: 6e 79 74 68 69 6e 67 0a 2a 2a 20 67 6f 65 73 20  nything.** goes 
1500: 77 72 6f 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63  wrong..*/.static
1510: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 64   sqlite3_stmt *d
1520: 62 5f 76 70 72 65 70 61 72 65 28 63 6f 6e 73 74  b_vprepare(const
1530: 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 20   char *zFormat, 
1540: 76 61 5f 6c 69 73 74 20 61 70 29 7b 0a 20 20 63  va_list ap){.  c
1550: 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 69 6e 74  har *zSql;.  int
1560: 20 72 63 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73   rc;.  sqlite3_s
1570: 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 0a 20 20 7a  tmt *pStmt;..  z
1580: 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f 76 6d  Sql = sqlite3_vm
1590: 70 72 69 6e 74 66 28 7a 46 6f 72 6d 61 74 2c 20  printf(zFormat, 
15a0: 61 70 29 3b 0a 20 20 69 66 28 20 7a 53 71 6c 3d  ap);.  if( zSql=
15b0: 3d 30 20 29 20 72 75 6e 74 69 6d 65 45 72 72 6f  =0 ) runtimeErro
15c0: 72 28 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79  r("out of memory
15d0: 22 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  ");.  rc = sqlit
15e0: 65 33 5f 70 72 65 70 61 72 65 5f 76 32 28 67 2e  e3_prepare_v2(g.
15f0: 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70  db, zSql, -1, &p
1600: 53 74 6d 74 2c 20 30 29 3b 0a 20 20 69 66 28 20  Stmt, 0);.  if( 
1610: 72 63 20 29 7b 0a 20 20 20 20 72 75 6e 74 69 6d  rc ){.    runtim
1620: 65 45 72 72 6f 72 28 22 53 51 4c 20 73 74 61 74  eError("SQL stat
1630: 65 6d 65 6e 74 20 65 72 72 6f 72 3a 20 25 73 5c  ement error: %s\
1640: 6e 5c 22 25 73 5c 22 22 2c 20 73 71 6c 69 74 65  n\"%s\"", sqlite
1650: 33 5f 65 72 72 6d 73 67 28 67 2e 64 62 29 2c 0a  3_errmsg(g.db),.
1660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1670: 20 7a 53 71 6c 29 3b 0a 20 20 7d 0a 20 20 73 71   zSql);.  }.  sq
1680: 6c 69 74 65 33 5f 66 72 65 65 28 7a 53 71 6c 29  lite3_free(zSql)
1690: 3b 0a 20 20 72 65 74 75 72 6e 20 70 53 74 6d 74  ;.  return pStmt
16a0: 3b 0a 7d 0a 73 74 61 74 69 63 20 73 71 6c 69 74  ;.}.static sqlit
16b0: 65 33 5f 73 74 6d 74 20 2a 64 62 5f 70 72 65 70  e3_stmt *db_prep
16c0: 61 72 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  are(const char *
16d0: 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20  zFormat, ...){. 
16e0: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 73   va_list ap;.  s
16f0: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
1700: 6d 74 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61  mt;.  va_start(a
1710: 70 2c 20 7a 46 6f 72 6d 61 74 29 3b 0a 20 20 70  p, zFormat);.  p
1720: 53 74 6d 74 20 3d 20 64 62 5f 76 70 72 65 70 61  Stmt = db_vprepa
1730: 72 65 28 7a 46 6f 72 6d 61 74 2c 20 61 70 29 3b  re(zFormat, ap);
1740: 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20  .  va_end(ap);. 
1750: 20 72 65 74 75 72 6e 20 70 53 74 6d 74 3b 0a 7d   return pStmt;.}
1760: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 20 6c  ../*.** Free a l
1770: 69 73 74 20 6f 66 20 73 74 72 69 6e 67 73 0a 2a  ist of strings.*
1780: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6e 61  /.static void na
1790: 6d 65 6c 69 73 74 46 72 65 65 28 63 68 61 72 20  melistFree(char 
17a0: 2a 2a 61 7a 29 7b 0a 20 20 69 66 28 20 61 7a 20  **az){.  if( az 
17b0: 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20  ){.    int i;.  
17c0: 20 20 66 6f 72 28 69 3d 30 3b 20 61 7a 5b 69 5d    for(i=0; az[i]
17d0: 3b 20 69 2b 2b 29 20 73 71 6c 69 74 65 33 5f 66  ; i++) sqlite3_f
17e0: 72 65 65 28 61 7a 5b 69 5d 29 3b 0a 20 20 20 20  ree(az[i]);.    
17f0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 7a 29  sqlite3_free(az)
1800: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  ;.  }.}../*.** R
1810: 65 74 75 72 6e 20 61 20 6c 69 73 74 20 6f 66 20  eturn a list of 
1820: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 66 6f 72  column names for
1830: 20 74 68 65 20 74 61 62 6c 65 20 7a 44 62 2e 7a   the table zDb.z
1840: 54 61 62 2e 20 20 53 70 61 63 65 20 74 6f 0a 2a  Tab.  Space to.*
1850: 2a 20 68 6f 6c 64 20 74 68 65 20 6c 69 73 74 20  * hold the list 
1860: 69 73 20 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d  is obtained from
1870: 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28   sqlite3_malloc(
1880: 29 20 61 6e 64 20 73 68 6f 75 6c 64 20 72 65 6c  ) and should rel
1890: 65 61 73 65 64 0a 2a 2a 20 75 73 69 6e 67 20 6e  eased.** using n
18a0: 61 6d 65 6c 69 73 74 46 72 65 65 28 29 20 77 68  amelistFree() wh
18b0: 65 6e 20 6e 6f 20 6c 6f 6e 67 65 72 20 6e 65 65  en no longer nee
18c0: 64 65 64 2e 0a 2a 2a 0a 2a 2a 20 50 72 69 6d 61  ded..**.** Prima
18d0: 72 79 20 6b 65 79 20 63 6f 6c 75 6d 6e 73 20 61  ry key columns a
18e0: 72 65 20 6c 69 73 74 65 64 20 66 69 72 73 74 2c  re listed first,
18f0: 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 64 61 74   followed by dat
1900: 61 20 63 6f 6c 75 6d 6e 73 2e 0a 2a 2a 20 54 68  a columns..** Th
1910: 65 20 6e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75  e number of colu
1920: 6d 6e 73 20 69 6e 20 74 68 65 20 70 72 69 6d 61  mns in the prima
1930: 72 79 20 6b 65 79 20 69 73 20 72 65 74 75 72 6e  ry key is return
1940: 65 64 20 69 6e 20 2a 70 6e 50 6b 65 79 2e 0a 2a  ed in *pnPkey..*
1950: 2a 0a 2a 2a 20 4e 6f 72 6d 61 6c 6c 79 2c 20 74  *.** Normally, t
1960: 68 65 20 22 70 72 69 6d 61 72 79 20 6b 65 79 22  he "primary key"
1970: 20 69 6e 20 74 68 65 20 70 72 65 76 69 6f 75 73   in the previous
1980: 20 73 65 6e 74 65 6e 63 65 20 69 73 20 74 68 65   sentence is the
1990: 20 74 72 75 65 0a 2a 2a 20 70 72 69 6d 61 72 79   true.** primary
19a0: 20 6b 65 79 20 2d 20 74 68 65 20 72 6f 77 69 64   key - the rowid
19b0: 20 6f 72 20 49 4e 54 45 47 45 52 20 50 52 49 4d   or INTEGER PRIM
19c0: 41 52 59 20 4b 45 59 20 66 6f 72 20 6f 72 64 69  ARY KEY for ordi
19d0: 6e 61 72 79 20 74 61 62 6c 65 73 0a 2a 2a 20 6f  nary tables.** o
19e0: 72 20 74 68 65 20 64 65 63 6c 61 72 65 64 20 50  r the declared P
19f0: 52 49 4d 41 52 59 20 4b 45 59 20 66 6f 72 20 57  RIMARY KEY for W
1a00: 49 54 48 4f 55 54 20 52 4f 57 49 44 20 74 61 62  ITHOUT ROWID tab
1a10: 6c 65 73 2e 20 20 48 6f 77 65 76 65 72 2c 20 69  les.  However, i
1a20: 66 0a 2a 2a 20 74 68 65 20 67 2e 62 53 63 68 65  f.** the g.bSche
1a30: 6d 61 50 4b 20 66 6c 61 67 20 69 73 20 73 65 74  maPK flag is set
1a40: 2c 20 74 68 65 6e 20 74 68 65 20 73 63 68 65 6d  , then the schem
1a50: 61 2d 64 65 66 69 6e 65 64 20 50 52 49 4d 41 52  a-defined PRIMAR
1a60: 59 20 4b 45 59 20 69 73 0a 2a 2a 20 75 73 65 64  Y KEY is.** used
1a70: 20 69 6e 20 61 6c 6c 20 63 61 73 65 73 2e 20 20   in all cases.  
1a80: 49 6e 20 74 68 61 74 20 63 61 73 65 2c 20 65 6e  In that case, en
1a90: 74 72 69 65 73 20 74 68 61 74 20 68 61 76 65 20  tries that have 
1aa0: 4e 55 4c 4c 20 76 61 6c 75 65 73 20 69 6e 0a 2a  NULL values in.*
1ab0: 2a 20 61 6e 79 20 6f 66 20 74 68 65 69 72 20 70  * any of their p
1ac0: 72 69 6d 61 72 79 20 6b 65 79 20 66 69 65 6c 64  rimary key field
1ad0: 73 20 77 69 6c 6c 20 62 65 20 65 78 63 6c 75 64  s will be exclud
1ae0: 65 64 20 66 72 6f 6d 20 74 68 65 20 61 6e 61 6c  ed from the anal
1af0: 79 73 69 73 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74  ysis..**.** If t
1b00: 68 65 20 70 72 69 6d 61 72 79 20 6b 65 79 20 66  he primary key f
1b10: 6f 72 20 61 20 74 61 62 6c 65 20 69 73 20 74 68  or a table is th
1b20: 65 20 72 6f 77 69 64 20 62 75 74 20 72 6f 77 69  e rowid but rowi
1b30: 64 20 69 73 20 69 6e 61 63 63 65 73 73 69 62 6c  d is inaccessibl
1b40: 65 2c 0a 2a 2a 20 74 68 65 6e 20 74 68 69 73 20  e,.** then this 
1b50: 72 6f 75 74 69 6e 65 20 72 65 74 75 72 6e 73 20  routine returns 
1b60: 61 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2e 0a  a NULL pointer..
1b70: 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65 73 3a 0a  **.** Examples:.
1b80: 2a 2a 20 20 20 20 43 52 45 41 54 45 20 54 41 42  **    CREATE TAB
1b90: 4c 45 20 74 31 28 61 20 49 4e 54 20 55 4e 49 51  LE t1(a INT UNIQ
1ba0: 55 45 2c 20 62 20 49 4e 54 45 47 45 52 2c 20 63  UE, b INTEGER, c
1bb0: 20 54 45 58 54 2c 20 50 52 49 4d 41 52 59 20 4b   TEXT, PRIMARY K
1bc0: 45 59 28 63 29 29 3b 0a 2a 2a 20 20 20 20 2a 70  EY(c));.**    *p
1bd0: 6e 50 4b 65 79 20 3d 20 31 3b 0a 2a 2a 20 20 20  nPKey = 1;.**   
1be0: 20 61 7a 20 3d 20 7b 20 22 72 6f 77 69 64 22 2c   az = { "rowid",
1bf0: 20 22 61 22 2c 20 22 62 22 2c 20 22 63 22 2c 20   "a", "b", "c", 
1c00: 30 20 7d 20 20 2f 2f 20 4e 6f 72 6d 61 6c 20 63  0 }  // Normal c
1c10: 61 73 65 0a 2a 2a 20 20 20 20 61 7a 20 3d 20 7b  ase.**    az = {
1c20: 20 22 63 22 2c 20 22 61 22 2c 20 22 62 22 2c 20   "c", "a", "b", 
1c30: 30 20 7d 20 20 20 20 20 20 20 20 20 20 20 2f 2f  0 }           //
1c40: 20 67 2e 62 53 63 68 65 6d 61 50 4b 3d 3d 31 0a   g.bSchemaPK==1.
1c50: 2a 2a 0a 2a 2a 20 20 20 20 43 52 45 41 54 45 20  **.**    CREATE 
1c60: 54 41 42 4c 45 20 74 32 28 61 20 49 4e 54 20 55  TABLE t2(a INT U
1c70: 4e 49 51 55 45 2c 20 62 20 49 4e 54 45 47 45 52  NIQUE, b INTEGER
1c80: 2c 20 63 20 54 45 58 54 2c 20 50 52 49 4d 41 52  , c TEXT, PRIMAR
1c90: 59 20 4b 45 59 28 62 29 29 3b 0a 2a 2a 20 20 20  Y KEY(b));.**   
1ca0: 20 2a 70 6e 50 4b 65 79 20 3d 20 31 3b 0a 2a 2a   *pnPKey = 1;.**
1cb0: 20 20 20 20 61 7a 20 3d 20 7b 20 22 62 22 2c 20      az = { "b", 
1cc0: 22 61 22 2c 20 22 63 22 2c 20 30 20 7d 0a 2a 2a  "a", "c", 0 }.**
1cd0: 0a 2a 2a 20 20 20 20 43 52 45 41 54 45 20 54 41  .**    CREATE TA
1ce0: 42 4c 45 20 74 33 28 78 2c 79 2c 7a 2c 50 52 49  BLE t3(x,y,z,PRI
1cf0: 4d 41 52 59 20 4b 45 59 28 79 2c 7a 29 29 3b 0a  MARY KEY(y,z));.
1d00: 2a 2a 20 20 20 20 2a 70 6e 50 4b 65 79 20 3d 20  **    *pnPKey = 
1d10: 31 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  1               
1d20: 20 20 20 20 20 20 20 20 20 20 2f 2f 20 4e 6f 72            // Nor
1d30: 6d 61 6c 20 63 61 73 65 0a 2a 2a 20 20 20 20 61  mal case.**    a
1d40: 7a 20 3d 20 7b 20 22 72 6f 77 69 64 22 2c 20 22  z = { "rowid", "
1d50: 78 22 2c 20 22 79 22 2c 20 22 7a 22 2c 20 30 20  x", "y", "z", 0 
1d60: 7d 20 20 2f 2f 20 4e 6f 72 6d 61 6c 20 63 61 73  }  // Normal cas
1d70: 65 0a 2a 2a 20 20 20 20 2a 70 6e 50 4b 65 79 20  e.**    *pnPKey 
1d80: 3d 20 32 20 20 20 20 20 20 20 20 20 20 20 20 20  = 2             
1d90: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2f 20 67              // g
1da0: 2e 62 53 63 68 65 6d 61 50 4b 3d 3d 31 0a 2a 2a  .bSchemaPK==1.**
1db0: 20 20 20 20 61 7a 20 3d 20 7b 20 22 79 22 2c 20      az = { "y", 
1dc0: 22 78 22 2c 20 22 7a 22 2c 20 30 20 7d 20 20 20  "x", "z", 0 }   
1dd0: 20 20 20 20 20 20 20 20 2f 2f 20 67 2e 62 53 63          // g.bSc
1de0: 68 65 6d 61 50 4b 3d 3d 31 0a 2a 2a 0a 2a 2a 20  hemaPK==1.**.** 
1df0: 20 20 20 43 52 45 41 54 45 20 54 41 42 4c 45 20     CREATE TABLE 
1e00: 74 34 28 78 2c 79 2c 7a 2c 50 52 49 4d 41 52 59  t4(x,y,z,PRIMARY
1e10: 20 4b 45 59 28 79 2c 7a 29 29 20 57 49 54 48 4f   KEY(y,z)) WITHO
1e20: 55 54 20 52 4f 57 49 44 3b 0a 2a 2a 20 20 20 20  UT ROWID;.**    
1e30: 2a 70 6e 50 4b 65 79 20 3d 20 32 0a 2a 2a 20 20  *pnPKey = 2.**  
1e40: 20 20 61 7a 20 3d 20 7b 20 22 79 22 2c 20 22 7a    az = { "y", "z
1e50: 22 2c 20 22 78 22 2c 20 30 20 7d 0a 2a 2a 0a 2a  ", "x", 0 }.**.*
1e60: 2a 20 20 20 20 43 52 45 41 54 45 20 54 41 42 4c  *    CREATE TABL
1e70: 45 20 74 35 28 72 6f 77 69 64 2c 5f 72 6f 77 69  E t5(rowid,_rowi
1e80: 64 5f 2c 6f 69 64 29 3b 0a 2a 2a 20 20 20 20 61  d_,oid);.**    a
1e90: 7a 20 3d 20 30 20 20 20 20 20 2f 2f 20 54 68 65  z = 0     // The
1ea0: 20 72 6f 77 69 64 20 69 73 20 6e 6f 74 20 61 63   rowid is not ac
1eb0: 63 65 73 73 69 62 6c 65 0a 2a 2f 0a 73 74 61 74  cessible.*/.stat
1ec0: 69 63 20 63 68 61 72 20 2a 2a 63 6f 6c 75 6d 6e  ic char **column
1ed0: 4e 61 6d 65 73 28 0a 20 20 63 6f 6e 73 74 20 63  Names(.  const c
1ee0: 68 61 72 20 2a 7a 44 62 2c 20 20 20 20 20 20 20  har *zDb,       
1ef0: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
1f00: 62 61 73 65 20 28 22 6d 61 69 6e 22 20 6f 72 20  base ("main" or 
1f10: 22 61 75 78 22 29 20 74 6f 20 71 75 65 72 79 20  "aux") to query 
1f20: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
1f30: 2a 7a 54 61 62 2c 20 20 20 20 20 20 20 20 20 20  *zTab,          
1f40: 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20       /* Name of 
1f50: 74 61 62 6c 65 20 74 6f 20 72 65 74 75 72 6e 20  table to return 
1f60: 64 65 74 61 69 6c 73 20 6f 66 20 2a 2f 0a 20 20  details of */.  
1f70: 69 6e 74 20 2a 70 6e 50 4b 65 79 2c 20 20 20 20  int *pnPKey,    
1f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f90: 2f 2a 20 4f 55 54 3a 20 4e 75 6d 62 65 72 20 6f  /* OUT: Number o
1fa0: 66 20 50 4b 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a  f PK columns */.
1fb0: 20 20 69 6e 74 20 2a 70 62 52 6f 77 69 64 20 20    int *pbRowid  
1fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fd0: 20 20 2f 2a 20 4f 55 54 3a 20 54 72 75 65 20 69    /* OUT: True i
1fe0: 66 20 50 4b 20 69 73 20 61 6e 20 69 6d 70 6c 69  f PK is an impli
1ff0: 63 69 74 20 72 6f 77 69 64 20 2a 2f 0a 29 7b 0a  cit rowid */.){.
2000: 20 20 63 68 61 72 20 2a 2a 61 7a 20 3d 20 30 3b    char **az = 0;
2010: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69             /* Li
2020: 73 74 20 6f 66 20 63 6f 6c 75 6d 6e 20 6e 61 6d  st of column nam
2030: 65 73 20 74 6f 20 62 65 20 72 65 74 75 72 6e 65  es to be returne
2040: 64 20 2a 2f 0a 20 20 69 6e 74 20 6e 61 7a 20 3d  d */.  int naz =
2050: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
2060: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74  /* Number of ent
2070: 72 69 65 73 20 69 6e 20 61 7a 5b 5d 20 2a 2f 0a  ries in az[] */.
2080: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
2090: 70 53 74 6d 74 3b 20 20 20 20 20 2f 2a 20 53 51  pStmt;     /* SQ
20a0: 4c 20 73 74 61 74 65 6d 65 6e 74 20 62 65 69 6e  L statement bein
20b0: 67 20 72 75 6e 20 2a 2f 0a 20 20 63 68 61 72 20  g run */.  char 
20c0: 2a 7a 50 6b 49 64 78 4e 61 6d 65 20 3d 20 30 3b  *zPkIdxName = 0;
20d0: 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74      /* Name of t
20e0: 68 65 20 50 52 49 4d 41 52 59 20 4b 45 59 20 69  he PRIMARY KEY i
20f0: 6e 64 65 78 20 2a 2f 0a 20 20 69 6e 74 20 74 72  ndex */.  int tr
2100: 75 65 50 6b 20 3d 20 30 3b 20 20 20 20 20 20 20  uePk = 0;       
2110: 20 20 20 2f 2a 20 50 52 41 47 4d 41 20 74 61 62     /* PRAGMA tab
2120: 6c 65 5f 69 6e 66 6f 20 69 6e 64 65 6e 74 69 66  le_info indentif
2130: 69 65 73 20 74 68 65 20 50 4b 20 74 6f 20 75 73  ies the PK to us
2140: 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 4b 20 3d  e */.  int nPK =
2150: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
2160: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 50 52 49  /* Number of PRI
2170: 4d 41 52 59 20 4b 45 59 20 63 6f 6c 75 6d 6e 73  MARY KEY columns
2180: 20 2a 2f 0a 20 20 69 6e 74 20 69 2c 20 6a 3b 20   */.  int i, j; 
2190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
21a0: 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 73 20  * Loop counters 
21b0: 2a 2f 0a 0a 20 20 69 66 28 20 67 2e 62 53 63 68  */..  if( g.bSch
21c0: 65 6d 61 50 4b 3d 3d 30 20 29 7b 0a 20 20 20 20  emaPK==0 ){.    
21d0: 2f 2a 20 4e 6f 72 6d 61 6c 20 63 61 73 65 3a 20  /* Normal case: 
21e0: 20 46 69 67 75 72 65 20 6f 75 74 20 77 68 61 74   Figure out what
21f0: 20 74 68 65 20 74 72 75 65 20 70 72 69 6d 61 72   the true primar
2200: 79 20 6b 65 79 20 69 73 20 66 6f 72 20 74 68 65  y key is for the
2210: 20 74 61 62 6c 65 2e 0a 20 20 20 20 2a 2a 20 20   table..    **  
2220: 20 2a 20 20 46 6f 72 20 57 49 54 48 4f 55 54 20   *  For WITHOUT 
2230: 52 4f 57 49 44 20 74 61 62 6c 65 73 2c 20 74 68  ROWID tables, th
2240: 65 20 74 72 75 65 20 70 72 69 6d 61 72 79 20 6b  e true primary k
2250: 65 79 20 69 73 20 74 68 65 20 73 61 6d 65 20 61  ey is the same a
2260: 73 0a 20 20 20 20 2a 2a 20 20 20 20 20 20 74 68  s.    **      th
2270: 65 20 73 63 68 65 6d 61 20 50 52 49 4d 41 52 59  e schema PRIMARY
2280: 20 4b 45 59 2c 20 77 68 69 63 68 20 69 73 20 67   KEY, which is g
2290: 75 61 72 61 6e 74 65 65 64 20 74 6f 20 62 65 20  uaranteed to be 
22a0: 70 72 65 73 65 6e 74 2e 0a 20 20 20 20 2a 2a 20  present..    ** 
22b0: 20 20 2a 20 20 46 6f 72 20 72 6f 77 69 64 20 74    *  For rowid t
22c0: 61 62 6c 65 73 20 77 69 74 68 20 61 6e 20 49 4e  ables with an IN
22d0: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45  TEGER PRIMARY KE
22e0: 59 2c 20 74 68 65 20 74 72 75 65 20 70 72 69 6d  Y, the true prim
22f0: 61 72 79 0a 20 20 20 20 2a 2a 20 20 20 20 20 20  ary.    **      
2300: 6b 65 79 20 69 73 20 74 68 65 20 49 4e 54 45 47  key is the INTEG
2310: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2e 0a  ER PRIMARY KEY..
2320: 20 20 20 20 2a 2a 20 20 20 2a 20 20 46 6f 72 20      **   *  For 
2330: 61 6c 6c 20 6f 74 68 65 72 20 72 6f 77 69 64 20  all other rowid 
2340: 74 61 62 6c 65 73 2c 20 74 68 65 20 72 6f 77 69  tables, the rowi
2350: 64 20 69 73 20 74 68 65 20 74 72 75 65 20 70 72  d is the true pr
2360: 69 6d 61 72 79 20 6b 65 79 2e 0a 20 20 20 20 2a  imary key..    *
2370: 2f 0a 20 20 20 20 70 53 74 6d 74 20 3d 20 64 62  /.    pStmt = db
2380: 5f 70 72 65 70 61 72 65 28 22 50 52 41 47 4d 41  _prepare("PRAGMA
2390: 20 25 73 2e 69 6e 64 65 78 5f 6c 69 73 74 3d 25   %s.index_list=%
23a0: 51 22 2c 20 7a 44 62 2c 20 7a 54 61 62 29 3b 0a  Q", zDb, zTab);.
23b0: 20 20 20 20 77 68 69 6c 65 28 20 53 51 4c 49 54      while( SQLIT
23c0: 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33 5f 73  E_ROW==sqlite3_s
23d0: 74 65 70 28 70 53 74 6d 74 29 20 29 7b 0a 20 20  tep(pStmt) ){.  
23e0: 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f      if( sqlite3_
23f0: 73 74 72 69 63 6d 70 28 28 63 6f 6e 73 74 20 63  stricmp((const c
2400: 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c  har*)sqlite3_col
2410: 75 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 33  umn_text(pStmt,3
2420: 29 2c 22 70 6b 22 29 3d 3d 30 20 29 7b 0a 20 20  ),"pk")==0 ){.  
2430: 20 20 20 20 20 20 7a 50 6b 49 64 78 4e 61 6d 65        zPkIdxName
2440: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
2450: 74 66 28 22 25 73 22 2c 20 73 71 6c 69 74 65 33  tf("%s", sqlite3
2460: 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 53 74  _column_text(pSt
2470: 6d 74 2c 20 31 29 29 3b 0a 20 20 20 20 20 20 20  mt, 1));.       
2480: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
2490: 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65      }.    sqlite
24a0: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74  3_finalize(pStmt
24b0: 29 3b 0a 20 20 20 20 69 66 28 20 7a 50 6b 49 64  );.    if( zPkId
24c0: 78 4e 61 6d 65 20 29 7b 0a 20 20 20 20 20 20 69  xName ){.      i
24d0: 6e 74 20 6e 4b 65 79 20 3d 20 30 3b 0a 20 20 20  nt nKey = 0;.   
24e0: 20 20 20 69 6e 74 20 6e 43 6f 6c 20 3d 20 30 3b     int nCol = 0;
24f0: 0a 20 20 20 20 20 20 74 72 75 65 50 6b 20 3d 20  .      truePk = 
2500: 30 3b 0a 20 20 20 20 20 20 70 53 74 6d 74 20 3d  0;.      pStmt =
2510: 20 64 62 5f 70 72 65 70 61 72 65 28 22 50 52 41   db_prepare("PRA
2520: 47 4d 41 20 25 73 2e 69 6e 64 65 78 5f 78 69 6e  GMA %s.index_xin
2530: 66 6f 3d 25 51 22 2c 20 7a 44 62 2c 20 7a 50 6b  fo=%Q", zDb, zPk
2540: 49 64 78 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20  IdxName);.      
2550: 77 68 69 6c 65 28 20 53 51 4c 49 54 45 5f 52 4f  while( SQLITE_RO
2560: 57 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65 70 28  W==sqlite3_step(
2570: 70 53 74 6d 74 29 20 29 7b 0a 20 20 20 20 20 20  pStmt) ){.      
2580: 20 20 6e 43 6f 6c 2b 2b 3b 0a 20 20 20 20 20 20    nCol++;.      
2590: 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 63 6f    if( sqlite3_co
25a0: 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d 74 2c 35  lumn_int(pStmt,5
25b0: 29 20 29 7b 20 6e 4b 65 79 2b 2b 3b 20 63 6f 6e  ) ){ nKey++; con
25c0: 74 69 6e 75 65 3b 20 7d 0a 20 20 20 20 20 20 20  tinue; }.       
25d0: 20 69 66 28 20 73 71 6c 69 74 65 33 5f 63 6f 6c   if( sqlite3_col
25e0: 75 6d 6e 5f 69 6e 74 28 70 53 74 6d 74 2c 31 29  umn_int(pStmt,1)
25f0: 3e 3d 30 20 29 20 74 72 75 65 50 6b 20 3d 20 31  >=0 ) truePk = 1
2600: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
2610: 69 66 28 20 6e 43 6f 6c 3d 3d 6e 4b 65 79 20 29  if( nCol==nKey )
2620: 20 74 72 75 65 50 6b 20 3d 20 31 3b 0a 20 20 20   truePk = 1;.   
2630: 20 20 20 69 66 28 20 74 72 75 65 50 6b 20 29 7b     if( truePk ){
2640: 0a 20 20 20 20 20 20 20 20 6e 50 4b 20 3d 20 6e  .        nPK = n
2650: 4b 65 79 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  Key;.      }else
2660: 7b 0a 20 20 20 20 20 20 20 20 6e 50 4b 20 3d 20  {.        nPK = 
2670: 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  1;.      }.     
2680: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
2690: 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 20 20  e(pStmt);.      
26a0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 50 6b  sqlite3_free(zPk
26b0: 49 64 78 4e 61 6d 65 29 3b 0a 20 20 20 20 7d 65  IdxName);.    }e
26c0: 6c 73 65 7b 0a 20 20 20 20 20 20 74 72 75 65 50  lse{.      trueP
26d0: 6b 20 3d 20 31 3b 0a 20 20 20 20 20 20 6e 50 4b  k = 1;.      nPK
26e0: 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20   = 1;.    }.    
26f0: 70 53 74 6d 74 20 3d 20 64 62 5f 70 72 65 70 61  pStmt = db_prepa
2700: 72 65 28 22 50 52 41 47 4d 41 20 25 73 2e 74 61  re("PRAGMA %s.ta
2710: 62 6c 65 5f 69 6e 66 6f 3d 25 51 22 2c 20 7a 44  ble_info=%Q", zD
2720: 62 2c 20 7a 54 61 62 29 3b 0a 20 20 7d 65 6c 73  b, zTab);.  }els
2730: 65 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20 67 2e  e{.    /* The g.
2740: 62 53 63 68 65 6d 61 50 4b 3d 3d 31 20 63 61 73  bSchemaPK==1 cas
2750: 65 3a 20 20 55 73 65 20 77 68 61 74 65 76 65 72  e:  Use whatever
2760: 20 70 72 69 6d 61 72 79 20 6b 65 79 20 69 73 20   primary key is 
2770: 64 65 63 6c 61 72 65 64 0a 20 20 20 20 2a 2a 20  declared.    ** 
2780: 69 6e 20 74 68 65 20 73 63 68 65 6d 61 2e 20 20  in the schema.  
2790: 54 68 65 20 22 72 6f 77 69 64 22 20 77 69 6c 6c  The "rowid" will
27a0: 20 73 74 69 6c 6c 20 62 65 20 75 73 65 64 20 61   still be used a
27b0: 73 20 74 68 65 20 70 72 69 6d 61 72 79 20 6b 65  s the primary ke
27c0: 79 0a 20 20 20 20 2a 2a 20 69 66 20 74 68 65 20  y.    ** if the 
27d0: 74 61 62 6c 65 20 64 65 66 69 6e 69 74 69 6f 6e  table definition
27e0: 20 64 6f 65 73 20 6e 6f 74 20 63 6f 6e 74 61 69   does not contai
27f0: 6e 20 61 20 50 52 49 4d 41 52 59 20 4b 45 59 2e  n a PRIMARY KEY.
2800: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6e 50 4b 20  .    */.    nPK 
2810: 3d 20 30 3b 0a 20 20 20 20 70 53 74 6d 74 20 3d  = 0;.    pStmt =
2820: 20 64 62 5f 70 72 65 70 61 72 65 28 22 50 52 41   db_prepare("PRA
2830: 47 4d 41 20 25 73 2e 74 61 62 6c 65 5f 69 6e 66  GMA %s.table_inf
2840: 6f 3d 25 51 22 2c 20 7a 44 62 2c 20 7a 54 61 62  o=%Q", zDb, zTab
2850: 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 53 51  );.    while( SQ
2860: 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65  LITE_ROW==sqlite
2870: 33 5f 73 74 65 70 28 70 53 74 6d 74 29 20 29 7b  3_step(pStmt) ){
2880: 0a 20 20 20 20 20 20 69 66 28 20 73 71 6c 69 74  .      if( sqlit
2890: 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53  e3_column_int(pS
28a0: 74 6d 74 2c 35 29 3e 30 20 29 20 6e 50 4b 2b 2b  tmt,5)>0 ) nPK++
28b0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69  ;.    }.    sqli
28c0: 74 65 33 5f 72 65 73 65 74 28 70 53 74 6d 74 29  te3_reset(pStmt)
28d0: 3b 0a 20 20 20 20 69 66 28 20 6e 50 4b 3d 3d 30  ;.    if( nPK==0
28e0: 20 29 20 6e 50 4b 20 3d 20 31 3b 0a 20 20 20 20   ) nPK = 1;.    
28f0: 74 72 75 65 50 6b 20 3d 20 31 3b 0a 20 20 7d 0a  truePk = 1;.  }.
2900: 20 20 2a 70 6e 50 4b 65 79 20 3d 20 6e 50 4b 3b    *pnPKey = nPK;
2910: 0a 20 20 6e 61 7a 20 3d 20 6e 50 4b 3b 0a 20 20  .  naz = nPK;.  
2920: 61 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c  az = sqlite3_mal
2930: 6c 6f 63 28 20 73 69 7a 65 6f 66 28 63 68 61 72  loc( sizeof(char
2940: 2a 29 2a 28 6e 50 4b 2b 31 29 20 29 3b 0a 20 20  *)*(nPK+1) );.  
2950: 69 66 28 20 61 7a 3d 3d 30 20 29 20 72 75 6e 74  if( az==0 ) runt
2960: 69 6d 65 45 72 72 6f 72 28 22 6f 75 74 20 6f 66  imeError("out of
2970: 20 6d 65 6d 6f 72 79 22 29 3b 0a 20 20 6d 65 6d   memory");.  mem
2980: 73 65 74 28 61 7a 2c 20 30 2c 20 73 69 7a 65 6f  set(az, 0, sizeo
2990: 66 28 63 68 61 72 2a 29 2a 28 6e 50 4b 2b 31 29  f(char*)*(nPK+1)
29a0: 29 3b 0a 20 20 77 68 69 6c 65 28 20 53 51 4c 49  );.  while( SQLI
29b0: 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33 5f  TE_ROW==sqlite3_
29c0: 73 74 65 70 28 70 53 74 6d 74 29 20 29 7b 0a 20  step(pStmt) ){. 
29d0: 20 20 20 69 6e 74 20 69 50 4b 65 79 3b 0a 20 20     int iPKey;.  
29e0: 20 20 69 66 28 20 74 72 75 65 50 6b 20 26 26 20    if( truePk && 
29f0: 28 69 50 4b 65 79 20 3d 20 73 71 6c 69 74 65 33  (iPKey = sqlite3
2a00: 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d  _column_int(pStm
2a10: 74 2c 35 29 29 3e 30 20 29 7b 0a 20 20 20 20 20  t,5))>0 ){.     
2a20: 20 61 7a 5b 69 50 4b 65 79 2d 31 5d 20 3d 20 73   az[iPKey-1] = s
2a30: 61 66 65 49 64 28 28 63 68 61 72 2a 29 73 71 6c  afeId((char*)sql
2a40: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74  ite3_column_text
2a50: 28 70 53 74 6d 74 2c 31 29 29 3b 0a 20 20 20 20  (pStmt,1));.    
2a60: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 61 7a 20  }else{.      az 
2a70: 3d 20 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f  = sqlite3_reallo
2a80: 63 28 61 7a 2c 20 73 69 7a 65 6f 66 28 63 68 61  c(az, sizeof(cha
2a90: 72 2a 29 2a 28 6e 61 7a 2b 32 29 20 29 3b 0a 20  r*)*(naz+2) );. 
2aa0: 20 20 20 20 20 69 66 28 20 61 7a 3d 3d 30 20 29       if( az==0 )
2ab0: 20 72 75 6e 74 69 6d 65 45 72 72 6f 72 28 22 6f   runtimeError("o
2ac0: 75 74 20 6f 66 20 6d 65 6d 6f 72 79 22 29 3b 0a  ut of memory");.
2ad0: 20 20 20 20 20 20 61 7a 5b 6e 61 7a 2b 2b 5d 20        az[naz++] 
2ae0: 3d 20 73 61 66 65 49 64 28 28 63 68 61 72 2a 29  = safeId((char*)
2af0: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74  sqlite3_column_t
2b00: 65 78 74 28 70 53 74 6d 74 2c 31 29 29 3b 0a 20  ext(pStmt,1));. 
2b10: 20 20 20 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74     }.  }.  sqlit
2b20: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d  e3_finalize(pStm
2b30: 74 29 3b 0a 20 20 69 66 28 20 61 7a 20 29 20 61  t);.  if( az ) a
2b40: 7a 5b 6e 61 7a 5d 20 3d 20 30 3b 0a 0a 20 20 2f  z[naz] = 0;..  /
2b50: 2a 20 49 66 20 69 74 20 69 73 20 6e 6f 6e 2d 4e  * If it is non-N
2b60: 55 4c 4c 2c 20 73 65 74 20 2a 70 62 52 6f 77 69  ULL, set *pbRowi
2b70: 64 20 74 6f 20 69 6e 64 69 63 61 74 65 20 77 68  d to indicate wh
2b80: 65 74 68 65 72 20 6f 72 20 6e 6f 74 20 74 68 65  ether or not the
2b90: 20 50 4b 20 6f 66 20 0a 20 20 2a 2a 20 74 68 69   PK of .  ** thi
2ba0: 73 20 74 61 62 6c 65 20 69 73 20 61 6e 20 69 6d  s table is an im
2bb0: 70 6c 69 63 69 74 20 72 6f 77 69 64 20 28 2a 70  plicit rowid (*p
2bc0: 62 52 6f 77 69 64 3d 3d 31 29 20 6f 72 20 6e 6f  bRowid==1) or no
2bd0: 74 20 28 2a 70 62 52 6f 77 69 64 3d 3d 30 29 2e  t (*pbRowid==0).
2be0: 20 20 2a 2f 0a 20 20 69 66 28 20 70 62 52 6f 77    */.  if( pbRow
2bf0: 69 64 20 29 20 2a 70 62 52 6f 77 69 64 20 3d 20  id ) *pbRowid = 
2c00: 28 61 7a 5b 30 5d 3d 3d 30 29 3b 0a 0a 20 20 2f  (az[0]==0);..  /
2c10: 2a 20 49 66 20 74 68 69 73 20 74 61 62 6c 65 20  * If this table 
2c20: 68 61 73 20 61 6e 20 69 6d 70 6c 69 63 69 74 20  has an implicit 
2c30: 72 6f 77 69 64 20 66 6f 72 20 61 20 50 4b 2c 20  rowid for a PK, 
2c40: 66 69 67 75 72 65 20 6f 75 74 20 68 6f 77 20 74  figure out how t
2c50: 6f 20 72 65 66 65 72 0a 20 20 2a 2a 20 74 6f 20  o refer.  ** to 
2c60: 69 74 2e 20 54 68 65 72 65 20 61 72 65 20 74 68  it. There are th
2c70: 72 65 65 20 6f 70 74 69 6f 6e 73 20 2d 20 22 72  ree options - "r
2c80: 6f 77 69 64 22 2c 20 22 5f 72 6f 77 69 64 5f 22  owid", "_rowid_"
2c90: 20 61 6e 64 20 22 6f 69 64 22 2e 20 41 6e 79 0a   and "oid". Any.
2ca0: 20 20 2a 2a 20 6f 66 20 74 68 65 73 65 20 77 69    ** of these wi
2cb0: 6c 6c 20 77 6f 72 6b 2c 20 75 6e 6c 65 73 73 20  ll work, unless 
2cc0: 74 68 65 20 74 61 62 6c 65 20 68 61 73 20 61 6e  the table has an
2cd0: 20 65 78 70 6c 69 63 69 74 20 63 6f 6c 75 6d 6e   explicit column
2ce0: 20 6f 66 20 74 68 65 0a 20 20 2a 2a 20 73 61 6d   of the.  ** sam
2cf0: 65 20 6e 61 6d 65 2e 20 20 2a 2f 0a 20 20 69 66  e name.  */.  if
2d00: 28 20 61 7a 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20  ( az[0]==0 ){.  
2d10: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 7a    const char *az
2d20: 52 6f 77 69 64 5b 5d 20 3d 20 7b 20 22 72 6f 77  Rowid[] = { "row
2d30: 69 64 22 2c 20 22 5f 72 6f 77 69 64 5f 22 2c 20  id", "_rowid_", 
2d40: 22 6f 69 64 22 20 7d 3b 0a 20 20 20 20 66 6f 72  "oid" };.    for
2d50: 28 69 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61  (i=0; i<sizeof(a
2d60: 7a 52 6f 77 69 64 29 2f 73 69 7a 65 6f 66 28 61  zRowid)/sizeof(a
2d70: 7a 52 6f 77 69 64 5b 30 5d 29 3b 20 69 2b 2b 29  zRowid[0]); i++)
2d80: 7b 0a 20 20 20 20 20 20 66 6f 72 28 6a 3d 31 3b  {.      for(j=1;
2d90: 20 6a 3c 6e 61 7a 3b 20 6a 2b 2b 29 7b 0a 20 20   j<naz; j++){.  
2da0: 20 20 20 20 20 20 69 66 28 20 73 71 6c 69 74 65        if( sqlite
2db0: 33 5f 73 74 72 69 63 6d 70 28 61 7a 5b 6a 5d 2c  3_stricmp(az[j],
2dc0: 20 61 7a 52 6f 77 69 64 5b 69 5d 29 3d 3d 30 20   azRowid[i])==0 
2dd0: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d  ) break;.      }
2de0: 0a 20 20 20 20 20 20 69 66 28 20 6a 3e 3d 6e 61  .      if( j>=na
2df0: 7a 20 29 7b 0a 20 20 20 20 20 20 20 20 61 7a 5b  z ){.        az[
2e00: 30 5d 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  0] = sqlite3_mpr
2e10: 69 6e 74 66 28 22 25 73 22 2c 20 61 7a 52 6f 77  intf("%s", azRow
2e20: 69 64 5b 69 5d 29 3b 0a 20 20 20 20 20 20 20 20  id[i]);.        
2e30: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20  break;.      }. 
2e40: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 61 7a 5b     }.    if( az[
2e50: 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 66  0]==0 ){.      f
2e60: 6f 72 28 69 3d 31 3b 20 69 3c 6e 61 7a 3b 20 69  or(i=1; i<naz; i
2e70: 2b 2b 29 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ++) sqlite3_free
2e80: 28 61 7a 5b 69 5d 29 3b 0a 20 20 20 20 20 20 73  (az[i]);.      s
2e90: 71 6c 69 74 65 33 5f 66 72 65 65 28 61 7a 29 3b  qlite3_free(az);
2ea0: 0a 20 20 20 20 20 20 61 7a 20 3d 20 30 3b 0a 20  .      az = 0;. 
2eb0: 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
2ec0: 6e 20 61 7a 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50  n az;.}../*.** P
2ed0: 72 69 6e 74 20 74 68 65 20 73 71 6c 69 74 65 33  rint the sqlite3
2ee0: 5f 76 61 6c 75 65 20 58 20 61 73 20 61 6e 20 53  _value X as an S
2ef0: 51 4c 20 6c 69 74 65 72 61 6c 2e 0a 2a 2f 0a 73  QL literal..*/.s
2f00: 74 61 74 69 63 20 76 6f 69 64 20 70 72 69 6e 74  tatic void print
2f10: 51 75 6f 74 65 64 28 46 49 4c 45 20 2a 6f 75 74  Quoted(FILE *out
2f20: 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20  , sqlite3_value 
2f30: 2a 58 29 7b 0a 20 20 73 77 69 74 63 68 28 20 73  *X){.  switch( s
2f40: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70  qlite3_value_typ
2f50: 65 28 58 29 20 29 7b 0a 20 20 20 20 63 61 73 65  e(X) ){.    case
2f60: 20 53 51 4c 49 54 45 5f 46 4c 4f 41 54 3a 20 7b   SQLITE_FLOAT: {
2f70: 0a 20 20 20 20 20 20 64 6f 75 62 6c 65 20 72 31  .      double r1
2f80: 3b 0a 20 20 20 20 20 20 63 68 61 72 20 7a 42 75  ;.      char zBu
2f90: 66 5b 35 30 5d 3b 0a 20 20 20 20 20 20 72 31 20  f[50];.      r1 
2fa0: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
2fb0: 64 6f 75 62 6c 65 28 58 29 3b 0a 20 20 20 20 20  double(X);.     
2fc0: 20 73 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74   sqlite3_snprint
2fd0: 66 28 73 69 7a 65 6f 66 28 7a 42 75 66 29 2c 20  f(sizeof(zBuf), 
2fe0: 7a 42 75 66 2c 20 22 25 21 2e 31 35 67 22 2c 20  zBuf, "%!.15g", 
2ff0: 72 31 29 3b 0a 20 20 20 20 20 20 66 70 72 69 6e  r1);.      fprin
3000: 74 66 28 6f 75 74 2c 20 22 25 73 22 2c 20 7a 42  tf(out, "%s", zB
3010: 75 66 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b  uf);.      break
3020: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63 61 73 65  ;.    }.    case
3030: 20 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 3a   SQLITE_INTEGER:
3040: 20 7b 0a 20 20 20 20 20 20 66 70 72 69 6e 74 66   {.      fprintf
3050: 28 6f 75 74 2c 20 22 25 6c 6c 64 22 2c 20 73 71  (out, "%lld", sq
3060: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74 36  lite3_value_int6
3070: 34 28 58 29 29 3b 0a 20 20 20 20 20 20 62 72 65  4(X));.      bre
3080: 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63 61  ak;.    }.    ca
3090: 73 65 20 53 51 4c 49 54 45 5f 42 4c 4f 42 3a 20  se SQLITE_BLOB: 
30a0: 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 75 6e  {.      const un
30b0: 73 69 67 6e 65 64 20 63 68 61 72 20 2a 7a 42 6c  signed char *zBl
30c0: 6f 62 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c  ob = sqlite3_val
30d0: 75 65 5f 62 6c 6f 62 28 58 29 3b 0a 20 20 20 20  ue_blob(X);.    
30e0: 20 20 69 6e 74 20 6e 42 6c 6f 62 20 3d 20 73 71    int nBlob = sq
30f0: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65  lite3_value_byte
3100: 73 28 58 29 3b 0a 20 20 20 20 20 20 69 66 28 20  s(X);.      if( 
3110: 7a 42 6c 6f 62 20 29 7b 0a 20 20 20 20 20 20 20  zBlob ){.       
3120: 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 20 20   int i;.        
3130: 66 70 72 69 6e 74 66 28 6f 75 74 2c 20 22 78 27  fprintf(out, "x'
3140: 22 29 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28  ");.        for(
3150: 69 3d 30 3b 20 69 3c 6e 42 6c 6f 62 3b 20 69 2b  i=0; i<nBlob; i+
3160: 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 66 70  +){.          fp
3170: 72 69 6e 74 66 28 6f 75 74 2c 20 22 25 30 32 78  rintf(out, "%02x
3180: 22 2c 20 7a 42 6c 6f 62 5b 69 5d 29 3b 0a 20 20  ", zBlob[i]);.  
3190: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
31a0: 66 70 72 69 6e 74 66 28 6f 75 74 2c 20 22 27 22  fprintf(out, "'"
31b0: 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  );.      }else{.
31c0: 20 20 20 20 20 20 20 20 66 70 72 69 6e 74 66 28          fprintf(
31d0: 6f 75 74 2c 20 22 4e 55 4c 4c 22 29 3b 0a 20 20  out, "NULL");.  
31e0: 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61      }.      brea
31f0: 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63 61 73  k;.    }.    cas
3200: 65 20 53 51 4c 49 54 45 5f 54 45 58 54 3a 20 7b  e SQLITE_TEXT: {
3210: 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 75 6e 73  .      const uns
3220: 69 67 6e 65 64 20 63 68 61 72 20 2a 7a 41 72 67  igned char *zArg
3230: 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65   = sqlite3_value
3240: 5f 74 65 78 74 28 58 29 3b 0a 20 20 20 20 20 20  _text(X);.      
3250: 69 6e 74 20 69 2c 20 6a 3b 0a 0a 20 20 20 20 20  int i, j;..     
3260: 20 69 66 28 20 7a 41 72 67 3d 3d 30 20 29 7b 0a   if( zArg==0 ){.
3270: 20 20 20 20 20 20 20 20 66 70 72 69 6e 74 66 28          fprintf(
3280: 6f 75 74 2c 20 22 4e 55 4c 4c 22 29 3b 0a 20 20  out, "NULL");.  
3290: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
32a0: 20 20 20 66 70 72 69 6e 74 66 28 6f 75 74 2c 20     fprintf(out, 
32b0: 22 27 22 29 3b 0a 20 20 20 20 20 20 20 20 66 6f  "'");.        fo
32c0: 72 28 69 3d 6a 3d 30 3b 20 7a 41 72 67 5b 69 5d  r(i=j=0; zArg[i]
32d0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
32e0: 20 20 69 66 28 20 7a 41 72 67 5b 69 5d 3d 3d 27    if( zArg[i]=='
32f0: 5c 27 27 20 29 7b 0a 20 20 20 20 20 20 20 20 20  \'' ){.         
3300: 20 20 20 66 70 72 69 6e 74 66 28 6f 75 74 2c 20     fprintf(out, 
3310: 22 25 2e 2a 73 27 22 2c 20 69 2d 6a 2b 31 2c 20  "%.*s'", i-j+1, 
3320: 26 7a 41 72 67 5b 6a 5d 29 3b 0a 20 20 20 20 20  &zArg[j]);.     
3330: 20 20 20 20 20 20 20 6a 20 3d 20 69 2b 31 3b 0a         j = i+1;.
3340: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
3350: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 66 70      }.        fp
3360: 72 69 6e 74 66 28 6f 75 74 2c 20 22 25 73 27 22  rintf(out, "%s'"
3370: 2c 20 26 7a 41 72 67 5b 6a 5d 29 3b 0a 20 20 20  , &zArg[j]);.   
3380: 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b     }.      break
3390: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63 61 73 65  ;.    }.    case
33a0: 20 53 51 4c 49 54 45 5f 4e 55 4c 4c 3a 20 7b 0a   SQLITE_NULL: {.
33b0: 20 20 20 20 20 20 66 70 72 69 6e 74 66 28 6f 75        fprintf(ou
33c0: 74 2c 20 22 4e 55 4c 4c 22 29 3b 0a 20 20 20 20  t, "NULL");.    
33d0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20    break;.    }. 
33e0: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 75 74 70   }.}../*.** Outp
33f0: 75 74 20 53 51 4c 20 74 68 61 74 20 77 69 6c 6c  ut SQL that will
3400: 20 72 65 63 72 65 61 74 65 20 74 68 65 20 61 75   recreate the au
3410: 78 2e 7a 54 61 62 20 74 61 62 6c 65 2e 0a 2a 2f  x.zTab table..*/
3420: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64 75 6d  .static void dum
3430: 70 5f 74 61 62 6c 65 28 63 6f 6e 73 74 20 63 68  p_table(const ch
3440: 61 72 20 2a 7a 54 61 62 2c 20 46 49 4c 45 20 2a  ar *zTab, FILE *
3450: 6f 75 74 29 7b 0a 20 20 63 68 61 72 20 2a 7a 49  out){.  char *zI
3460: 64 20 3d 20 73 61 66 65 49 64 28 7a 54 61 62 29  d = safeId(zTab)
3470: 3b 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65  ; /* Name of the
3480: 20 74 61 62 6c 65 20 2a 2f 0a 20 20 63 68 61 72   table */.  char
3490: 20 2a 2a 61 7a 20 3d 20 30 3b 20 20 20 20 20 20   **az = 0;      
34a0: 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66        /* List of
34b0: 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 69 6e   columns */.  in
34c0: 74 20 6e 50 6b 3b 20 20 20 20 20 20 20 20 20 20  t nPk;          
34d0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
34e0: 72 20 6f 66 20 74 72 75 65 20 70 72 69 6d 61 72  r of true primar
34f0: 79 20 6b 65 79 20 63 6f 6c 75 6d 6e 73 20 2a 2f  y key columns */
3500: 0a 20 20 69 6e 74 20 6e 43 6f 6c 3b 20 20 20 20  .  int nCol;    
3510: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3520: 4e 75 6d 62 65 72 20 6f 66 20 64 61 74 61 20 63  Number of data c
3530: 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 69 6e 74 20  olumns */.  int 
3540: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
3550: 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f        /* Loop co
3560: 75 6e 74 65 72 20 2a 2f 0a 20 20 73 71 6c 69 74  unter */.  sqlit
3570: 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 20  e3_stmt *pStmt; 
3580: 20 20 20 20 20 2f 2a 20 53 51 4c 20 73 74 61 74       /* SQL stat
3590: 65 6d 65 6e 74 20 2a 2f 0a 20 20 63 6f 6e 73 74  ement */.  const
35a0: 20 63 68 61 72 20 2a 7a 53 65 70 3b 20 20 20 20   char *zSep;    
35b0: 20 20 20 20 20 2f 2a 20 53 65 70 61 72 61 74 6f       /* Separato
35c0: 72 20 73 74 72 69 6e 67 20 2a 2f 0a 20 20 53 74  r string */.  St
35d0: 72 20 69 6e 73 3b 20 20 20 20 20 20 20 20 20 20  r ins;          
35e0: 20 20 20 20 20 20 20 20 2f 2a 20 42 65 67 69 6e          /* Begin
35f0: 6e 69 6e 67 20 6f 66 20 74 68 65 20 49 4e 53 45  ning of the INSE
3600: 52 54 20 73 74 61 74 65 6d 65 6e 74 20 2a 2f 0a  RT statement */.
3610: 0a 20 20 70 53 74 6d 74 20 3d 20 64 62 5f 70 72  .  pStmt = db_pr
3620: 65 70 61 72 65 28 22 53 45 4c 45 43 54 20 73 71  epare("SELECT sq
3630: 6c 20 46 52 4f 4d 20 61 75 78 2e 73 71 6c 69 74  l FROM aux.sqlit
3640: 65 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 6e  e_master WHERE n
3650: 61 6d 65 3d 25 51 22 2c 20 7a 54 61 62 29 3b 0a  ame=%Q", zTab);.
3660: 20 20 69 66 28 20 53 51 4c 49 54 45 5f 52 4f 57    if( SQLITE_ROW
3670: 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70  ==sqlite3_step(p
3680: 53 74 6d 74 29 20 29 7b 0a 20 20 20 20 66 70 72  Stmt) ){.    fpr
3690: 69 6e 74 66 28 6f 75 74 2c 20 22 25 73 3b 5c 6e  intf(out, "%s;\n
36a0: 22 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  ", sqlite3_colum
36b0: 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 30 29 29  n_text(pStmt,0))
36c0: 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  ;.  }.  sqlite3_
36d0: 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b  finalize(pStmt);
36e0: 0a 20 20 69 66 28 20 21 67 2e 62 53 63 68 65 6d  .  if( !g.bSchem
36f0: 61 4f 6e 6c 79 20 29 7b 0a 20 20 20 20 61 7a 20  aOnly ){.    az 
3700: 3d 20 63 6f 6c 75 6d 6e 4e 61 6d 65 73 28 22 61  = columnNames("a
3710: 75 78 22 2c 20 7a 54 61 62 2c 20 26 6e 50 6b 2c  ux", zTab, &nPk,
3720: 20 30 29 3b 0a 20 20 20 20 73 74 72 49 6e 69 74   0);.    strInit
3730: 28 26 69 6e 73 29 3b 0a 20 20 20 20 69 66 28 20  (&ins);.    if( 
3740: 61 7a 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70  az==0 ){.      p
3750: 53 74 6d 74 20 3d 20 64 62 5f 70 72 65 70 61 72  Stmt = db_prepar
3760: 65 28 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d  e("SELECT * FROM
3770: 20 61 75 78 2e 25 73 22 2c 20 7a 49 64 29 3b 0a   aux.%s", zId);.
3780: 20 20 20 20 20 20 73 74 72 50 72 69 6e 74 66 28        strPrintf(
3790: 26 69 6e 73 2c 22 49 4e 53 45 52 54 20 49 4e 54  &ins,"INSERT INT
37a0: 4f 20 25 73 20 56 41 4c 55 45 53 22 2c 20 7a 49  O %s VALUES", zI
37b0: 64 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  d);.    }else{. 
37c0: 20 20 20 20 20 53 74 72 20 73 71 6c 3b 0a 20 20       Str sql;.  
37d0: 20 20 20 20 73 74 72 49 6e 69 74 28 26 73 71 6c      strInit(&sql
37e0: 29 3b 0a 20 20 20 20 20 20 7a 53 65 70 20 3d 20  );.      zSep = 
37f0: 20 22 53 45 4c 45 43 54 22 3b 0a 20 20 20 20 20   "SELECT";.     
3800: 20 66 6f 72 28 69 3d 30 3b 20 61 7a 5b 69 5d 3b   for(i=0; az[i];
3810: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 73   i++){.        s
3820: 74 72 50 72 69 6e 74 66 28 26 73 71 6c 2c 20 22  trPrintf(&sql, "
3830: 25 73 20 25 73 22 2c 20 7a 53 65 70 2c 20 61 7a  %s %s", zSep, az
3840: 5b 69 5d 29 3b 0a 20 20 20 20 20 20 20 20 7a 53  [i]);.        zS
3850: 65 70 20 3d 20 22 2c 22 3b 0a 20 20 20 20 20 20  ep = ",";.      
3860: 7d 0a 20 20 20 20 20 20 73 74 72 50 72 69 6e 74  }.      strPrint
3870: 66 28 26 73 71 6c 2c 22 20 46 52 4f 4d 20 61 75  f(&sql," FROM au
3880: 78 2e 25 73 22 2c 20 7a 49 64 29 3b 0a 20 20 20  x.%s", zId);.   
3890: 20 20 20 7a 53 65 70 20 3d 20 22 20 4f 52 44 45     zSep = " ORDE
38a0: 52 20 42 59 22 3b 0a 20 20 20 20 20 20 66 6f 72  R BY";.      for
38b0: 28 69 3d 31 3b 20 69 3c 3d 6e 50 6b 3b 20 69 2b  (i=1; i<=nPk; i+
38c0: 2b 29 7b 0a 20 20 20 20 20 20 20 20 73 74 72 50  +){.        strP
38d0: 72 69 6e 74 66 28 26 73 71 6c 2c 20 22 25 73 20  rintf(&sql, "%s 
38e0: 25 64 22 2c 20 7a 53 65 70 2c 20 69 29 3b 0a 20  %d", zSep, i);. 
38f0: 20 20 20 20 20 20 20 7a 53 65 70 20 3d 20 22 2c         zSep = ",
3900: 22 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  ";.      }.     
3910: 20 70 53 74 6d 74 20 3d 20 64 62 5f 70 72 65 70   pStmt = db_prep
3920: 61 72 65 28 22 25 73 22 2c 20 73 71 6c 2e 7a 29  are("%s", sql.z)
3930: 3b 0a 20 20 20 20 20 20 73 74 72 46 72 65 65 28  ;.      strFree(
3940: 26 73 71 6c 29 3b 0a 20 20 20 20 20 20 73 74 72  &sql);.      str
3950: 50 72 69 6e 74 66 28 26 69 6e 73 2c 20 22 49 4e  Printf(&ins, "IN
3960: 53 45 52 54 20 49 4e 54 4f 20 25 73 22 2c 20 7a  SERT INTO %s", z
3970: 49 64 29 3b 0a 20 20 20 20 20 20 7a 53 65 70 20  Id);.      zSep 
3980: 3d 20 22 28 22 3b 0a 20 20 20 20 20 20 66 6f 72  = "(";.      for
3990: 28 69 3d 30 3b 20 61 7a 5b 69 5d 3b 20 69 2b 2b  (i=0; az[i]; i++
39a0: 29 7b 0a 20 20 20 20 20 20 20 20 73 74 72 50 72  ){.        strPr
39b0: 69 6e 74 66 28 26 69 6e 73 2c 20 22 25 73 25 73  intf(&ins, "%s%s
39c0: 22 2c 20 7a 53 65 70 2c 20 61 7a 5b 69 5d 29 3b  ", zSep, az[i]);
39d0: 0a 20 20 20 20 20 20 20 20 7a 53 65 70 20 3d 20  .        zSep = 
39e0: 22 2c 22 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ",";.      }.   
39f0: 20 20 20 73 74 72 50 72 69 6e 74 66 28 26 69 6e     strPrintf(&in
3a00: 73 2c 22 29 20 56 41 4c 55 45 53 22 29 3b 0a 20  s,") VALUES");. 
3a10: 20 20 20 20 20 6e 61 6d 65 6c 69 73 74 46 72 65       namelistFre
3a20: 65 28 61 7a 29 3b 0a 20 20 20 20 7d 0a 20 20 20  e(az);.    }.   
3a30: 20 6e 43 6f 6c 20 3d 20 73 71 6c 69 74 65 33 5f   nCol = sqlite3_
3a40: 63 6f 6c 75 6d 6e 5f 63 6f 75 6e 74 28 70 53 74  column_count(pSt
3a50: 6d 74 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  mt);.    while( 
3a60: 53 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69  SQLITE_ROW==sqli
3a70: 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 20  te3_step(pStmt) 
3a80: 29 7b 0a 20 20 20 20 20 20 66 70 72 69 6e 74 66  ){.      fprintf
3a90: 28 6f 75 74 2c 20 22 25 73 22 2c 69 6e 73 2e 7a  (out, "%s",ins.z
3aa0: 29 3b 0a 20 20 20 20 20 20 7a 53 65 70 20 3d 20  );.      zSep = 
3ab0: 22 28 22 3b 0a 20 20 20 20 20 20 66 6f 72 28 69  "(";.      for(i
3ac0: 3d 30 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29  =0; i<nCol; i++)
3ad0: 7b 0a 20 20 20 20 20 20 20 20 66 70 72 69 6e 74  {.        fprint
3ae0: 66 28 6f 75 74 2c 20 22 25 73 22 2c 7a 53 65 70  f(out, "%s",zSep
3af0: 29 3b 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74  );.        print
3b00: 51 75 6f 74 65 64 28 6f 75 74 2c 20 73 71 6c 69  Quoted(out, sqli
3b10: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65  te3_column_value
3b20: 28 70 53 74 6d 74 2c 69 29 29 3b 0a 20 20 20 20  (pStmt,i));.    
3b30: 20 20 20 20 7a 53 65 70 20 3d 20 22 2c 22 3b 0a      zSep = ",";.
3b40: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 66 70        }.      fp
3b50: 72 69 6e 74 66 28 6f 75 74 2c 20 22 29 3b 5c 6e  rintf(out, ");\n
3b60: 22 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71  ");.    }.    sq
3b70: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
3b80: 53 74 6d 74 29 3b 0a 20 20 20 20 73 74 72 46 72  Stmt);.    strFr
3b90: 65 65 28 26 69 6e 73 29 3b 0a 20 20 7d 20 2f 2a  ee(&ins);.  } /*
3ba0: 20 65 6e 64 69 66 20 21 67 2e 62 53 63 68 65 6d   endif !g.bSchem
3bb0: 61 4f 6e 6c 79 20 2a 2f 0a 20 20 70 53 74 6d 74  aOnly */.  pStmt
3bc0: 20 3d 20 64 62 5f 70 72 65 70 61 72 65 28 22 53   = db_prepare("S
3bd0: 45 4c 45 43 54 20 73 71 6c 20 46 52 4f 4d 20 61  ELECT sql FROM a
3be0: 75 78 2e 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  ux.sqlite_master
3bf0: 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ".              
3c00: 20 20 20 20 20 20 20 22 20 57 48 45 52 45 20 74         " WHERE t
3c10: 79 70 65 3d 27 69 6e 64 65 78 27 20 41 4e 44 20  ype='index' AND 
3c20: 74 62 6c 5f 6e 61 6d 65 3d 25 51 20 41 4e 44 20  tbl_name=%Q AND 
3c30: 73 71 6c 20 49 53 20 4e 4f 54 20 4e 55 4c 4c 22  sql IS NOT NULL"
3c40: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
3c50: 20 20 20 20 20 20 20 7a 54 61 62 29 3b 0a 20 20         zTab);.  
3c60: 77 68 69 6c 65 28 20 53 51 4c 49 54 45 5f 52 4f  while( SQLITE_RO
3c70: 57 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65 70 28  W==sqlite3_step(
3c80: 70 53 74 6d 74 29 20 29 7b 0a 20 20 20 20 66 70  pStmt) ){.    fp
3c90: 72 69 6e 74 66 28 6f 75 74 2c 20 22 25 73 3b 5c  rintf(out, "%s;\
3ca0: 6e 22 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  n", sqlite3_colu
3cb0: 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 30 29  mn_text(pStmt,0)
3cc0: 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33  );.  }.  sqlite3
3cd0: 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29  _finalize(pStmt)
3ce0: 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70  ;.}.../*.** Comp
3cf0: 75 74 65 20 61 6c 6c 20 64 69 66 66 65 72 65 6e  ute all differen
3d00: 63 65 73 20 66 6f 72 20 61 20 73 69 6e 67 6c 65  ces for a single
3d10: 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69   table..*/.stati
3d20: 63 20 76 6f 69 64 20 64 69 66 66 5f 6f 6e 65 5f  c void diff_one_
3d30: 74 61 62 6c 65 28 63 6f 6e 73 74 20 63 68 61 72  table(const char
3d40: 20 2a 7a 54 61 62 2c 20 46 49 4c 45 20 2a 6f 75   *zTab, FILE *ou
3d50: 74 29 7b 0a 20 20 63 68 61 72 20 2a 7a 49 64 20  t){.  char *zId 
3d60: 3d 20 73 61 66 65 49 64 28 7a 54 61 62 29 3b 20  = safeId(zTab); 
3d70: 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 61 62 6c 65  /* Name of table
3d80: 20 28 74 72 61 6e 73 6c 61 74 65 64 20 66 6f 72   (translated for
3d90: 20 75 73 20 69 6e 20 53 51 4c 29 20 2a 2f 0a 20   us in SQL) */. 
3da0: 20 63 68 61 72 20 2a 2a 61 7a 20 3d 20 30 3b 20   char **az = 0; 
3db0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
3dc0: 6c 75 6d 6e 73 20 69 6e 20 6d 61 69 6e 20 2a 2f  lumns in main */
3dd0: 0a 20 20 63 68 61 72 20 2a 2a 61 7a 32 20 3d 20  .  char **az2 = 
3de0: 30 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  0;           /* 
3df0: 43 6f 6c 75 6d 6e 73 20 69 6e 20 61 75 78 20 2a  Columns in aux *
3e00: 2f 0a 20 20 69 6e 74 20 6e 50 6b 3b 20 20 20 20  /.  int nPk;    
3e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3e20: 20 50 72 69 6d 61 72 79 20 6b 65 79 20 63 6f 6c   Primary key col
3e30: 75 6d 6e 73 20 69 6e 20 6d 61 69 6e 20 2a 2f 0a  umns in main */.
3e40: 20 20 69 6e 74 20 6e 50 6b 32 3b 20 20 20 20 20    int nPk2;     
3e50: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
3e60: 72 69 6d 61 72 79 20 6b 65 79 20 63 6f 6c 75 6d  rimary key colum
3e70: 6e 73 20 69 6e 20 61 75 78 20 2a 2f 0a 20 20 69  ns in aux */.  i
3e80: 6e 74 20 6e 20 3d 20 30 3b 20 20 20 20 20 20 20  nt n = 0;       
3e90: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
3ea0: 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e  er of columns in
3eb0: 20 6d 61 69 6e 20 2a 2f 0a 20 20 69 6e 74 20 6e   main */.  int n
3ec0: 32 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  2;              
3ed0: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
3ee0: 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 61 75 78  f columns in aux
3ef0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 51 3b 20 20 20   */.  int nQ;   
3f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3f10: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 6f 75 74  /* Number of out
3f20: 70 75 74 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74  put columns in t
3f30: 68 65 20 64 69 66 66 20 71 75 65 72 79 20 2a 2f  he diff query */
3f40: 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20  .  int i;       
3f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3f60: 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a  Loop counter */.
3f70: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53    const char *zS
3f80: 65 70 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 53  ep;         /* S
3f90: 65 70 61 72 61 74 6f 72 20 73 74 72 69 6e 67 20  eparator string 
3fa0: 2a 2f 0a 20 20 53 74 72 20 73 71 6c 3b 20 20 20  */.  Str sql;   
3fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3fc0: 2a 20 43 6f 6d 70 61 72 69 73 6f 6e 20 71 75 65  * Comparison que
3fd0: 72 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  ry */.  sqlite3_
3fe0: 73 74 6d 74 20 2a 70 53 74 6d 74 3b 20 20 20 20  stmt *pStmt;    
3ff0: 20 20 2f 2a 20 51 75 65 72 79 20 73 74 61 74 65    /* Query state
4000: 6d 65 6e 74 20 74 6f 20 64 6f 20 74 68 65 20 64  ment to do the d
4010: 69 66 66 20 2a 2f 0a 0a 20 20 73 74 72 49 6e 69  iff */..  strIni
4020: 74 28 26 73 71 6c 29 3b 0a 20 20 69 66 28 20 67  t(&sql);.  if( g
4030: 2e 66 44 65 62 75 67 3d 3d 44 45 42 55 47 5f 43  .fDebug==DEBUG_C
4040: 4f 4c 55 4d 4e 5f 4e 41 4d 45 53 20 29 7b 0a 20  OLUMN_NAMES ){. 
4050: 20 20 20 2f 2a 20 53 69 6d 70 6c 79 20 72 75 6e     /* Simply run
4060: 20 63 6f 6c 75 6d 6e 4e 61 6d 65 73 28 29 20 6f   columnNames() o
4070: 6e 20 61 6c 6c 20 74 61 62 6c 65 73 20 6f 66 20  n all tables of 
4080: 74 68 65 20 6f 72 69 67 69 6e 0a 20 20 20 20 2a  the origin.    *
4090: 2a 20 64 61 74 61 62 61 73 65 20 61 6e 64 20 73  * database and s
40a0: 68 6f 77 20 74 68 65 20 72 65 73 75 6c 74 73 2e  how the results.
40b0: 20 20 54 68 69 73 20 69 73 20 75 73 65 64 20 66    This is used f
40c0: 6f 72 20 74 65 73 74 69 6e 67 0a 20 20 20 20 2a  or testing.    *
40d0: 2a 20 61 6e 64 20 64 65 62 75 67 67 69 6e 67 20  * and debugging 
40e0: 6f 66 20 74 68 65 20 63 6f 6c 75 6d 6e 4e 61 6d  of the columnNam
40f0: 65 73 28 29 20 66 75 6e 63 74 69 6f 6e 2e 0a 20  es() function.. 
4100: 20 20 20 2a 2f 0a 20 20 20 20 61 7a 20 3d 20 63     */.    az = c
4110: 6f 6c 75 6d 6e 4e 61 6d 65 73 28 22 61 75 78 22  olumnNames("aux"
4120: 2c 7a 54 61 62 2c 20 26 6e 50 6b 2c 20 30 29 3b  ,zTab, &nPk, 0);
4130: 0a 20 20 20 20 69 66 28 20 61 7a 3d 3d 30 20 29  .    if( az==0 )
4140: 7b 0a 20 20 20 20 20 20 70 72 69 6e 74 66 28 22  {.      printf("
4150: 52 6f 77 69 64 20 6e 6f 74 20 61 63 63 65 73 73  Rowid not access
4160: 69 62 6c 65 20 66 6f 72 20 25 73 5c 6e 22 2c 20  ible for %s\n", 
4170: 7a 49 64 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  zId);.    }else{
4180: 0a 20 20 20 20 20 20 70 72 69 6e 74 66 28 22 25  .      printf("%
4190: 73 3a 22 2c 20 7a 49 64 29 3b 0a 20 20 20 20 20  s:", zId);.     
41a0: 20 66 6f 72 28 69 3d 30 3b 20 61 7a 5b 69 5d 3b   for(i=0; az[i];
41b0: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 70   i++){.        p
41c0: 72 69 6e 74 66 28 22 20 25 73 22 2c 20 61 7a 5b  rintf(" %s", az[
41d0: 69 5d 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  i]);.        if(
41e0: 20 69 2b 31 3d 3d 6e 50 6b 20 29 20 70 72 69 6e   i+1==nPk ) prin
41f0: 74 66 28 22 20 2a 22 29 3b 0a 20 20 20 20 20 20  tf(" *");.      
4200: 7d 0a 20 20 20 20 20 20 70 72 69 6e 74 66 28 22  }.      printf("
4210: 5c 6e 22 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  \n");.    }.    
4220: 67 6f 74 6f 20 65 6e 64 5f 64 69 66 66 5f 6f 6e  goto end_diff_on
4230: 65 5f 74 61 62 6c 65 3b 0a 20 20 7d 0a 20 20 20  e_table;.  }.   
4240: 20 0a 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33   ..  if( sqlite3
4250: 5f 74 61 62 6c 65 5f 63 6f 6c 75 6d 6e 5f 6d 65  _table_column_me
4260: 74 61 64 61 74 61 28 67 2e 64 62 2c 22 61 75 78  tadata(g.db,"aux
4270: 22 2c 7a 54 61 62 2c 30 2c 30 2c 30 2c 30 2c 30  ",zTab,0,0,0,0,0
4280: 2c 30 29 20 29 7b 0a 20 20 20 20 69 66 28 20 21  ,0) ){.    if( !
4290: 73 71 6c 69 74 65 33 5f 74 61 62 6c 65 5f 63 6f  sqlite3_table_co
42a0: 6c 75 6d 6e 5f 6d 65 74 61 64 61 74 61 28 67 2e  lumn_metadata(g.
42b0: 64 62 2c 22 6d 61 69 6e 22 2c 7a 54 61 62 2c 30  db,"main",zTab,0
42c0: 2c 30 2c 30 2c 30 2c 30 2c 30 29 20 29 7b 0a 20  ,0,0,0,0,0) ){. 
42d0: 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20 6d 69       /* Table mi
42e0: 73 73 69 6e 67 20 66 72 6f 6d 20 73 65 63 6f 6e  ssing from secon
42f0: 64 20 64 61 74 61 62 61 73 65 2e 20 2a 2f 0a 20  d database. */. 
4300: 20 20 20 20 20 66 70 72 69 6e 74 66 28 6f 75 74       fprintf(out
4310: 2c 20 22 44 52 4f 50 20 54 41 42 4c 45 20 25 73  , "DROP TABLE %s
4320: 3b 5c 6e 22 2c 20 7a 49 64 29 3b 0a 20 20 20 20  ;\n", zId);.    
4330: 7d 0a 20 20 20 20 67 6f 74 6f 20 65 6e 64 5f 64  }.    goto end_d
4340: 69 66 66 5f 6f 6e 65 5f 74 61 62 6c 65 3b 0a 20  iff_one_table;. 
4350: 20 7d 0a 0a 20 20 69 66 28 20 73 71 6c 69 74 65   }..  if( sqlite
4360: 33 5f 74 61 62 6c 65 5f 63 6f 6c 75 6d 6e 5f 6d  3_table_column_m
4370: 65 74 61 64 61 74 61 28 67 2e 64 62 2c 22 6d 61  etadata(g.db,"ma
4380: 69 6e 22 2c 7a 54 61 62 2c 30 2c 30 2c 30 2c 30  in",zTab,0,0,0,0
4390: 2c 30 2c 30 29 20 29 7b 0a 20 20 20 20 2f 2a 20  ,0,0) ){.    /* 
43a0: 54 61 62 6c 65 20 6d 69 73 73 69 6e 67 20 66 72  Table missing fr
43b0: 6f 6d 20 73 6f 75 72 63 65 20 2a 2f 0a 20 20 20  om source */.   
43c0: 20 64 75 6d 70 5f 74 61 62 6c 65 28 7a 54 61 62   dump_table(zTab
43d0: 2c 20 6f 75 74 29 3b 0a 20 20 20 20 67 6f 74 6f  , out);.    goto
43e0: 20 65 6e 64 5f 64 69 66 66 5f 6f 6e 65 5f 74 61   end_diff_one_ta
43f0: 62 6c 65 3b 0a 20 20 7d 0a 0a 20 20 61 7a 20 3d  ble;.  }..  az =
4400: 20 63 6f 6c 75 6d 6e 4e 61 6d 65 73 28 22 6d 61   columnNames("ma
4410: 69 6e 22 2c 20 7a 54 61 62 2c 20 26 6e 50 6b 2c  in", zTab, &nPk,
4420: 20 30 29 3b 0a 20 20 61 7a 32 20 3d 20 63 6f 6c   0);.  az2 = col
4430: 75 6d 6e 4e 61 6d 65 73 28 22 61 75 78 22 2c 20  umnNames("aux", 
4440: 7a 54 61 62 2c 20 26 6e 50 6b 32 2c 20 30 29 3b  zTab, &nPk2, 0);
4450: 0a 20 20 69 66 28 20 61 7a 20 26 26 20 61 7a 32  .  if( az && az2
4460: 20 29 7b 0a 20 20 20 20 66 6f 72 28 6e 3d 30 3b   ){.    for(n=0;
4470: 20 61 7a 5b 6e 5d 20 26 26 20 61 7a 32 5b 6e 5d   az[n] && az2[n]
4480: 3b 20 6e 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66  ; n++){.      if
4490: 28 20 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d  ( sqlite3_stricm
44a0: 70 28 61 7a 5b 6e 5d 2c 61 7a 32 5b 6e 5d 29 21  p(az[n],az2[n])!
44b0: 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  =0 ) break;.    
44c0: 7d 0a 20 20 7d 0a 20 20 69 66 28 20 61 7a 3d 3d  }.  }.  if( az==
44d0: 30 0a 20 20 20 7c 7c 20 61 7a 32 3d 3d 30 0a 20  0.   || az2==0. 
44e0: 20 20 7c 7c 20 6e 50 6b 21 3d 6e 50 6b 32 0a 20    || nPk!=nPk2. 
44f0: 20 20 7c 7c 20 61 7a 5b 6e 5d 0a 20 20 29 7b 0a    || az[n].  ){.
4500: 20 20 20 20 2f 2a 20 53 63 68 65 6d 61 20 6d 69      /* Schema mi
4510: 73 6d 61 74 63 68 20 2a 2f 0a 20 20 20 20 66 70  smatch */.    fp
4520: 72 69 6e 74 66 28 6f 75 74 2c 20 22 44 52 4f 50  rintf(out, "DROP
4530: 20 54 41 42 4c 45 20 25 73 3b 20 2d 2d 20 64 75   TABLE %s; -- du
4540: 65 20 74 6f 20 73 63 68 65 6d 61 20 6d 69 73 6d  e to schema mism
4550: 61 74 63 68 5c 6e 22 2c 20 7a 49 64 29 3b 0a 20  atch\n", zId);. 
4560: 20 20 20 64 75 6d 70 5f 74 61 62 6c 65 28 7a 54     dump_table(zT
4570: 61 62 2c 20 6f 75 74 29 3b 0a 20 20 20 20 67 6f  ab, out);.    go
4580: 74 6f 20 65 6e 64 5f 64 69 66 66 5f 6f 6e 65 5f  to end_diff_one_
4590: 74 61 62 6c 65 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  table;.  }..  /*
45a0: 20 42 75 69 6c 64 20 74 68 65 20 63 6f 6d 70 61   Build the compa
45b0: 72 69 73 6f 6e 20 71 75 65 72 79 20 2a 2f 0a 20  rison query */. 
45c0: 20 66 6f 72 28 6e 32 3d 6e 3b 20 61 7a 32 5b 6e   for(n2=n; az2[n
45d0: 32 5d 3b 20 6e 32 2b 2b 29 7b 0a 20 20 20 20 66  2]; n2++){.    f
45e0: 70 72 69 6e 74 66 28 6f 75 74 2c 20 22 41 4c 54  printf(out, "ALT
45f0: 45 52 20 54 41 42 4c 45 20 25 73 20 41 44 44 20  ER TABLE %s ADD 
4600: 43 4f 4c 55 4d 4e 20 25 73 3b 5c 6e 22 2c 20 7a  COLUMN %s;\n", z
4610: 49 64 2c 20 73 61 66 65 49 64 28 61 7a 32 5b 6e  Id, safeId(az2[n
4620: 32 5d 29 29 3b 0a 20 20 7d 0a 20 20 6e 51 20 3d  2]));.  }.  nQ =
4630: 20 6e 50 6b 32 2b 31 2b 32 2a 28 6e 32 2d 6e 50   nPk2+1+2*(n2-nP
4640: 6b 32 29 3b 0a 20 20 69 66 28 20 6e 32 3e 6e 50  k2);.  if( n2>nP
4650: 6b 32 20 29 7b 0a 20 20 20 20 7a 53 65 70 20 3d  k2 ){.    zSep =
4660: 20 22 53 45 4c 45 43 54 20 22 3b 0a 20 20 20 20   "SELECT ";.    
4670: 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 50 6b 3b 20  for(i=0; i<nPk; 
4680: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73 74 72 50  i++){.      strP
4690: 72 69 6e 74 66 28 26 73 71 6c 2c 20 22 25 73 42  rintf(&sql, "%sB
46a0: 2e 25 73 22 2c 20 7a 53 65 70 2c 20 61 7a 5b 69  .%s", zSep, az[i
46b0: 5d 29 3b 0a 20 20 20 20 20 20 7a 53 65 70 20 3d  ]);.      zSep =
46c0: 20 22 2c 20 22 3b 0a 20 20 20 20 7d 0a 20 20 20   ", ";.    }.   
46d0: 20 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c 2c   strPrintf(&sql,
46e0: 20 22 2c 20 31 25 73 20 2d 2d 20 63 68 61 6e 67   ", 1%s -- chang
46f0: 65 64 20 72 6f 77 5c 6e 22 2c 20 6e 50 6b 3d 3d  ed row\n", nPk==
4700: 6e 20 3f 20 22 22 20 3a 20 22 2c 22 29 3b 0a 20  n ? "" : ",");. 
4710: 20 20 20 77 68 69 6c 65 28 20 61 7a 5b 69 5d 20     while( az[i] 
4720: 29 7b 0a 20 20 20 20 20 20 73 74 72 50 72 69 6e  ){.      strPrin
4730: 74 66 28 26 73 71 6c 2c 20 22 20 20 20 20 20 20  tf(&sql, "      
4740: 20 41 2e 25 73 20 49 53 20 4e 4f 54 20 42 2e 25   A.%s IS NOT B.%
4750: 73 2c 20 42 2e 25 73 25 73 5c 6e 22 2c 0a 20 20  s, B.%s%s\n",.  
4760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 7a                az
4770: 5b 69 5d 2c 20 61 7a 32 5b 69 5d 2c 20 61 7a 32  [i], az2[i], az2
4780: 5b 69 5d 2c 20 61 7a 32 5b 69 2b 31 5d 3d 3d 30  [i], az2[i+1]==0
4790: 20 3f 20 22 22 20 3a 20 22 2c 22 29 3b 0a 20 20   ? "" : ",");.  
47a0: 20 20 20 20 69 2b 2b 3b 0a 20 20 20 20 7d 0a 20      i++;.    }. 
47b0: 20 20 20 77 68 69 6c 65 28 20 61 7a 32 5b 69 5d     while( az2[i]
47c0: 20 29 7b 0a 20 20 20 20 20 20 73 74 72 50 72 69   ){.      strPri
47d0: 6e 74 66 28 26 73 71 6c 2c 20 22 20 20 20 20 20  ntf(&sql, "     
47e0: 20 20 42 2e 25 73 20 49 53 20 4e 4f 54 20 4e 55    B.%s IS NOT NU
47f0: 4c 4c 2c 20 42 2e 25 73 25 73 5c 6e 22 2c 0a 20  LL, B.%s%s\n",. 
4800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61                 a
4810: 7a 32 5b 69 5d 2c 20 61 7a 32 5b 69 5d 2c 20 61  z2[i], az2[i], a
4820: 7a 32 5b 69 2b 31 5d 3d 3d 30 20 3f 20 22 22 20  z2[i+1]==0 ? "" 
4830: 3a 20 22 2c 22 29 3b 0a 20 20 20 20 20 20 69 2b  : ",");.      i+
4840: 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 74 72  +;.    }.    str
4850: 50 72 69 6e 74 66 28 26 73 71 6c 2c 20 22 20 20  Printf(&sql, "  
4860: 46 52 4f 4d 20 6d 61 69 6e 2e 25 73 20 41 2c 20  FROM main.%s A, 
4870: 61 75 78 2e 25 73 20 42 5c 6e 22 2c 20 7a 49 64  aux.%s B\n", zId
4880: 2c 20 7a 49 64 29 3b 0a 20 20 20 20 7a 53 65 70  , zId);.    zSep
4890: 20 3d 20 22 20 57 48 45 52 45 22 3b 0a 20 20 20   = " WHERE";.   
48a0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 50 6b 3b   for(i=0; i<nPk;
48b0: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73 74 72   i++){.      str
48c0: 50 72 69 6e 74 66 28 26 73 71 6c 2c 20 22 25 73  Printf(&sql, "%s
48d0: 20 41 2e 25 73 3d 42 2e 25 73 22 2c 20 7a 53 65   A.%s=B.%s", zSe
48e0: 70 2c 20 61 7a 5b 69 5d 2c 20 61 7a 5b 69 5d 29  p, az[i], az[i])
48f0: 3b 0a 20 20 20 20 20 20 7a 53 65 70 20 3d 20 22  ;.      zSep = "
4900: 20 41 4e 44 22 3b 0a 20 20 20 20 7d 0a 20 20 20   AND";.    }.   
4910: 20 7a 53 65 70 20 3d 20 22 5c 6e 20 20 20 41 4e   zSep = "\n   AN
4920: 44 20 28 22 3b 0a 20 20 20 20 77 68 69 6c 65 28  D (";.    while(
4930: 20 61 7a 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20   az[i] ){.      
4940: 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c 2c 20  strPrintf(&sql, 
4950: 22 25 73 41 2e 25 73 20 49 53 20 4e 4f 54 20 42  "%sA.%s IS NOT B
4960: 2e 25 73 25 73 5c 6e 22 2c 0a 20 20 20 20 20 20  .%s%s\n",.      
4970: 20 20 20 20 20 20 20 20 20 20 7a 53 65 70 2c 20            zSep, 
4980: 61 7a 5b 69 5d 2c 20 61 7a 32 5b 69 5d 2c 20 61  az[i], az2[i], a
4990: 7a 32 5b 69 2b 31 5d 3d 3d 30 20 3f 20 22 29 22  z2[i+1]==0 ? ")"
49a0: 20 3a 20 22 22 29 3b 0a 20 20 20 20 20 20 7a 53   : "");.      zS
49b0: 65 70 20 3d 20 22 20 20 20 20 20 20 20 20 4f 52  ep = "        OR
49c0: 20 22 3b 0a 20 20 20 20 20 20 69 2b 2b 3b 0a 20   ";.      i++;. 
49d0: 20 20 20 7d 0a 20 20 20 20 77 68 69 6c 65 28 20     }.    while( 
49e0: 61 7a 32 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20  az2[i] ){.      
49f0: 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c 2c 20  strPrintf(&sql, 
4a00: 22 25 73 42 2e 25 73 20 49 53 20 4e 4f 54 20 4e  "%sB.%s IS NOT N
4a10: 55 4c 4c 25 73 5c 6e 22 2c 0a 20 20 20 20 20 20  ULL%s\n",.      
4a20: 20 20 20 20 20 20 20 20 20 20 7a 53 65 70 2c 20            zSep, 
4a30: 61 7a 32 5b 69 5d 2c 20 61 7a 32 5b 69 2b 31 5d  az2[i], az2[i+1]
4a40: 3d 3d 30 20 3f 20 22 29 22 20 3a 20 22 22 29 3b  ==0 ? ")" : "");
4a50: 0a 20 20 20 20 20 20 7a 53 65 70 20 3d 20 22 20  .      zSep = " 
4a60: 20 20 20 20 20 20 20 4f 52 20 22 3b 0a 20 20 20         OR ";.   
4a70: 20 20 20 69 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20     i++;.    }.  
4a80: 20 20 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c    strPrintf(&sql
4a90: 2c 20 22 20 55 4e 49 4f 4e 20 41 4c 4c 5c 6e 22  , " UNION ALL\n"
4aa0: 29 3b 0a 20 20 7d 0a 20 20 7a 53 65 70 20 3d 20  );.  }.  zSep = 
4ab0: 22 53 45 4c 45 43 54 20 22 3b 0a 20 20 66 6f 72  "SELECT ";.  for
4ac0: 28 69 3d 30 3b 20 69 3c 6e 50 6b 3b 20 69 2b 2b  (i=0; i<nPk; i++
4ad0: 29 7b 0a 20 20 20 20 73 74 72 50 72 69 6e 74 66  ){.    strPrintf
4ae0: 28 26 73 71 6c 2c 20 22 25 73 41 2e 25 73 22 2c  (&sql, "%sA.%s",
4af0: 20 7a 53 65 70 2c 20 61 7a 5b 69 5d 29 3b 0a 20   zSep, az[i]);. 
4b00: 20 20 20 7a 53 65 70 20 3d 20 22 2c 20 22 3b 0a     zSep = ", ";.
4b10: 20 20 7d 0a 20 20 73 74 72 50 72 69 6e 74 66 28    }.  strPrintf(
4b20: 26 73 71 6c 2c 20 22 2c 20 32 25 73 20 2d 2d 20  &sql, ", 2%s -- 
4b30: 64 65 6c 65 74 65 64 20 72 6f 77 5c 6e 22 2c 20  deleted row\n", 
4b40: 6e 50 6b 3d 3d 6e 20 3f 20 22 22 20 3a 20 22 2c  nPk==n ? "" : ",
4b50: 22 29 3b 0a 20 20 77 68 69 6c 65 28 20 61 7a 32  ");.  while( az2
4b60: 5b 69 5d 20 29 7b 0a 20 20 20 20 73 74 72 50 72  [i] ){.    strPr
4b70: 69 6e 74 66 28 26 73 71 6c 2c 20 22 20 20 20 20  intf(&sql, "    
4b80: 20 20 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 25 73 5c     NULL, NULL%s\
4b90: 6e 22 2c 20 69 3d 3d 6e 32 2d 31 20 3f 20 22 22  n", i==n2-1 ? ""
4ba0: 20 3a 20 22 2c 22 29 3b 0a 20 20 20 20 69 2b 2b   : ",");.    i++
4bb0: 3b 0a 20 20 7d 0a 20 20 73 74 72 50 72 69 6e 74  ;.  }.  strPrint
4bc0: 66 28 26 73 71 6c 2c 20 22 20 20 46 52 4f 4d 20  f(&sql, "  FROM 
4bd0: 6d 61 69 6e 2e 25 73 20 41 5c 6e 22 2c 20 7a 49  main.%s A\n", zI
4be0: 64 29 3b 0a 20 20 73 74 72 50 72 69 6e 74 66 28  d);.  strPrintf(
4bf0: 26 73 71 6c 2c 20 22 20 57 48 45 52 45 20 4e 4f  &sql, " WHERE NO
4c00: 54 20 45 58 49 53 54 53 28 53 45 4c 45 43 54 20  T EXISTS(SELECT 
4c10: 31 20 46 52 4f 4d 20 61 75 78 2e 25 73 20 42 5c  1 FROM aux.%s B\
4c20: 6e 22 2c 20 7a 49 64 29 3b 0a 20 20 7a 53 65 70  n", zId);.  zSep
4c30: 20 3d 20 20 20 20 20 20 20 20 20 20 22 20 20 20   =          "   
4c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4c50: 57 48 45 52 45 22 3b 0a 20 20 66 6f 72 28 69 3d  WHERE";.  for(i=
4c60: 30 3b 20 69 3c 6e 50 6b 3b 20 69 2b 2b 29 7b 0a  0; i<nPk; i++){.
4c70: 20 20 20 20 73 74 72 50 72 69 6e 74 66 28 26 73      strPrintf(&s
4c80: 71 6c 2c 20 22 25 73 20 41 2e 25 73 3d 42 2e 25  ql, "%s A.%s=B.%
4c90: 73 22 2c 20 7a 53 65 70 2c 20 61 7a 5b 69 5d 2c  s", zSep, az[i],
4ca0: 20 61 7a 5b 69 5d 29 3b 0a 20 20 20 20 7a 53 65   az[i]);.    zSe
4cb0: 70 20 3d 20 22 20 41 4e 44 22 3b 0a 20 20 7d 0a  p = " AND";.  }.
4cc0: 20 20 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c    strPrintf(&sql
4cd0: 2c 20 22 29 5c 6e 22 29 3b 0a 20 20 7a 53 65 70  , ")\n");.  zSep
4ce0: 20 3d 20 22 20 55 4e 49 4f 4e 20 41 4c 4c 5c 6e   = " UNION ALL\n
4cf0: 53 45 4c 45 43 54 20 22 3b 0a 20 20 66 6f 72 28  SELECT ";.  for(
4d00: 69 3d 30 3b 20 69 3c 6e 50 6b 3b 20 69 2b 2b 29  i=0; i<nPk; i++)
4d10: 7b 0a 20 20 20 20 73 74 72 50 72 69 6e 74 66 28  {.    strPrintf(
4d20: 26 73 71 6c 2c 20 22 25 73 42 2e 25 73 22 2c 20  &sql, "%sB.%s", 
4d30: 7a 53 65 70 2c 20 61 7a 5b 69 5d 29 3b 0a 20 20  zSep, az[i]);.  
4d40: 20 20 7a 53 65 70 20 3d 20 22 2c 20 22 3b 0a 20    zSep = ", ";. 
4d50: 20 7d 0a 20 20 73 74 72 50 72 69 6e 74 66 28 26   }.  strPrintf(&
4d60: 73 71 6c 2c 20 22 2c 20 33 25 73 20 2d 2d 20 69  sql, ", 3%s -- i
4d70: 6e 73 65 72 74 65 64 20 72 6f 77 5c 6e 22 2c 20  nserted row\n", 
4d80: 6e 50 6b 3d 3d 6e 20 3f 20 22 22 20 3a 20 22 2c  nPk==n ? "" : ",
4d90: 22 29 3b 0a 20 20 77 68 69 6c 65 28 20 61 7a 32  ");.  while( az2
4da0: 5b 69 5d 20 29 7b 0a 20 20 20 20 73 74 72 50 72  [i] ){.    strPr
4db0: 69 6e 74 66 28 26 73 71 6c 2c 20 22 20 20 20 20  intf(&sql, "    
4dc0: 20 20 20 31 2c 20 42 2e 25 73 25 73 5c 6e 22 2c     1, B.%s%s\n",
4dd0: 20 61 7a 32 5b 69 5d 2c 20 61 7a 32 5b 69 2b 31   az2[i], az2[i+1
4de0: 5d 3d 3d 30 20 3f 20 22 22 20 3a 20 22 2c 22 29  ]==0 ? "" : ",")
4df0: 3b 0a 20 20 20 20 69 2b 2b 3b 0a 20 20 7d 0a 20  ;.    i++;.  }. 
4e00: 20 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c 2c   strPrintf(&sql,
4e10: 20 22 20 20 46 52 4f 4d 20 61 75 78 2e 25 73 20   "  FROM aux.%s 
4e20: 42 5c 6e 22 2c 20 7a 49 64 29 3b 0a 20 20 73 74  B\n", zId);.  st
4e30: 72 50 72 69 6e 74 66 28 26 73 71 6c 2c 20 22 20  rPrintf(&sql, " 
4e40: 57 48 45 52 45 20 4e 4f 54 20 45 58 49 53 54 53  WHERE NOT EXISTS
4e50: 28 53 45 4c 45 43 54 20 31 20 46 52 4f 4d 20 6d  (SELECT 1 FROM m
4e60: 61 69 6e 2e 25 73 20 41 5c 6e 22 2c 20 7a 49 64  ain.%s A\n", zId
4e70: 29 3b 0a 20 20 7a 53 65 70 20 3d 20 20 20 20 20  );.  zSep =     
4e80: 20 20 20 20 20 22 20 20 20 20 20 20 20 20 20 20       "          
4e90: 20 20 20 20 20 20 20 20 20 57 48 45 52 45 22 3b           WHERE";
4ea0: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 50  .  for(i=0; i<nP
4eb0: 6b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 73 74 72  k; i++){.    str
4ec0: 50 72 69 6e 74 66 28 26 73 71 6c 2c 20 22 25 73  Printf(&sql, "%s
4ed0: 20 41 2e 25 73 3d 42 2e 25 73 22 2c 20 7a 53 65   A.%s=B.%s", zSe
4ee0: 70 2c 20 61 7a 5b 69 5d 2c 20 61 7a 5b 69 5d 29  p, az[i], az[i])
4ef0: 3b 0a 20 20 20 20 7a 53 65 70 20 3d 20 22 20 41  ;.    zSep = " A
4f00: 4e 44 22 3b 0a 20 20 7d 0a 20 20 73 74 72 50 72  ND";.  }.  strPr
4f10: 69 6e 74 66 28 26 73 71 6c 2c 20 22 29 5c 6e 20  intf(&sql, ")\n 
4f20: 4f 52 44 45 52 20 42 59 22 29 3b 0a 20 20 7a 53  ORDER BY");.  zS
4f30: 65 70 20 3d 20 22 20 22 3b 0a 20 20 66 6f 72 28  ep = " ";.  for(
4f40: 69 3d 31 3b 20 69 3c 3d 6e 50 6b 3b 20 69 2b 2b  i=1; i<=nPk; i++
4f50: 29 7b 0a 20 20 20 20 73 74 72 50 72 69 6e 74 66  ){.    strPrintf
4f60: 28 26 73 71 6c 2c 20 22 25 73 25 64 22 2c 20 7a  (&sql, "%s%d", z
4f70: 53 65 70 2c 20 69 29 3b 0a 20 20 20 20 7a 53 65  Sep, i);.    zSe
4f80: 70 20 3d 20 22 2c 20 22 3b 0a 20 20 7d 0a 20 20  p = ", ";.  }.  
4f90: 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c 2c 20  strPrintf(&sql, 
4fa0: 22 3b 5c 6e 22 29 3b 0a 0a 20 20 69 66 28 20 67  ";\n");..  if( g
4fb0: 2e 66 44 65 62 75 67 20 26 20 44 45 42 55 47 5f  .fDebug & DEBUG_
4fc0: 44 49 46 46 5f 53 51 4c 20 29 7b 20 0a 20 20 20  DIFF_SQL ){ .   
4fd0: 20 70 72 69 6e 74 66 28 22 53 51 4c 20 66 6f 72   printf("SQL for
4fe0: 20 25 73 3a 5c 6e 25 73 5c 6e 22 2c 20 7a 49 64   %s:\n%s\n", zId
4ff0: 2c 20 73 71 6c 2e 7a 29 3b 0a 20 20 20 20 67 6f  , sql.z);.    go
5000: 74 6f 20 65 6e 64 5f 64 69 66 66 5f 6f 6e 65 5f  to end_diff_one_
5010: 74 61 62 6c 65 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  table;.  }..  /*
5020: 20 44 72 6f 70 20 69 6e 64 65 78 65 73 20 74 68   Drop indexes th
5030: 61 74 20 61 72 65 20 6d 69 73 73 69 6e 67 20 69  at are missing i
5040: 6e 20 74 68 65 20 64 65 73 74 69 6e 61 74 69 6f  n the destinatio
5050: 6e 20 2a 2f 0a 20 20 70 53 74 6d 74 20 3d 20 64  n */.  pStmt = d
5060: 62 5f 70 72 65 70 61 72 65 28 0a 20 20 20 20 22  b_prepare(.    "
5070: 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d  SELECT name FROM
5080: 20 6d 61 69 6e 2e 73 71 6c 69 74 65 5f 6d 61 73   main.sqlite_mas
5090: 74 65 72 22 0a 20 20 20 20 22 20 57 48 45 52 45  ter".    " WHERE
50a0: 20 74 79 70 65 3d 27 69 6e 64 65 78 27 20 41 4e   type='index' AN
50b0: 44 20 74 62 6c 5f 6e 61 6d 65 3d 25 51 22 0a 20  D tbl_name=%Q". 
50c0: 20 20 20 22 20 20 20 41 4e 44 20 73 71 6c 20 49     "   AND sql I
50d0: 53 20 4e 4f 54 20 4e 55 4c 4c 22 0a 20 20 20 20  S NOT NULL".    
50e0: 22 20 20 20 41 4e 44 20 73 71 6c 20 4e 4f 54 20  "   AND sql NOT 
50f0: 49 4e 20 28 53 45 4c 45 43 54 20 73 71 6c 20 46  IN (SELECT sql F
5100: 52 4f 4d 20 61 75 78 2e 73 71 6c 69 74 65 5f 6d  ROM aux.sqlite_m
5110: 61 73 74 65 72 22 0a 20 20 20 20 22 20 20 20 20  aster".    "    
5120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5130: 57 48 45 52 45 20 74 79 70 65 3d 27 69 6e 64 65  WHERE type='inde
5140: 78 27 20 41 4e 44 20 74 62 6c 5f 6e 61 6d 65 3d  x' AND tbl_name=
5150: 25 51 22 0a 20 20 20 20 22 20 20 20 20 20 20 20  %Q".    "       
5160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 41                 A
5170: 4e 44 20 73 71 6c 20 49 53 20 4e 4f 54 20 4e 55  ND sql IS NOT NU
5180: 4c 4c 29 22 2c 0a 20 20 20 20 7a 54 61 62 2c 20  LL)",.    zTab, 
5190: 7a 54 61 62 29 3b 0a 20 20 77 68 69 6c 65 28 20  zTab);.  while( 
51a0: 53 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69  SQLITE_ROW==sqli
51b0: 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 20  te3_step(pStmt) 
51c0: 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 20 3d  ){.    char *z =
51d0: 20 73 61 66 65 49 64 28 28 63 6f 6e 73 74 20 63   safeId((const c
51e0: 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c  har*)sqlite3_col
51f0: 75 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 30  umn_text(pStmt,0
5200: 29 29 3b 0a 20 20 20 20 66 70 72 69 6e 74 66 28  ));.    fprintf(
5210: 6f 75 74 2c 20 22 44 52 4f 50 20 49 4e 44 45 58  out, "DROP INDEX
5220: 20 25 73 3b 5c 6e 22 2c 20 7a 29 3b 0a 20 20 20   %s;\n", z);.   
5230: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 29   sqlite3_free(z)
5240: 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  ;.  }.  sqlite3_
5250: 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b  finalize(pStmt);
5260: 0a 0a 20 20 2f 2a 20 52 75 6e 20 74 68 65 20 71  ..  /* Run the q
5270: 75 65 72 79 20 61 6e 64 20 6f 75 74 70 75 74 20  uery and output 
5280: 64 69 66 66 65 72 65 6e 63 65 73 20 2a 2f 0a 20  differences */. 
5290: 20 69 66 28 20 21 67 2e 62 53 63 68 65 6d 61 4f   if( !g.bSchemaO
52a0: 6e 6c 79 20 29 7b 0a 20 20 20 20 70 53 74 6d 74  nly ){.    pStmt
52b0: 20 3d 20 64 62 5f 70 72 65 70 61 72 65 28 73 71   = db_prepare(sq
52c0: 6c 2e 7a 29 3b 0a 20 20 20 20 77 68 69 6c 65 28  l.z);.    while(
52d0: 20 53 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c   SQLITE_ROW==sql
52e0: 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29  ite3_step(pStmt)
52f0: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 54   ){.      int iT
5300: 79 70 65 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  ype = sqlite3_co
5310: 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d 74 2c 20  lumn_int(pStmt, 
5320: 6e 50 6b 29 3b 0a 20 20 20 20 20 20 69 66 28 20  nPk);.      if( 
5330: 69 54 79 70 65 3d 3d 31 20 7c 7c 20 69 54 79 70  iType==1 || iTyp
5340: 65 3d 3d 32 20 29 7b 0a 20 20 20 20 20 20 20 20  e==2 ){.        
5350: 69 66 28 20 69 54 79 70 65 3d 3d 31 20 29 7b 20  if( iType==1 ){ 
5360: 20 20 20 20 20 20 2f 2a 20 43 68 61 6e 67 65 20        /* Change 
5370: 74 68 65 20 63 6f 6e 74 65 6e 74 20 6f 66 20 61  the content of a
5380: 20 72 6f 77 20 2a 2f 0a 20 20 20 20 20 20 20 20   row */.        
5390: 20 20 66 70 72 69 6e 74 66 28 6f 75 74 2c 20 22    fprintf(out, "
53a0: 55 50 44 41 54 45 20 25 73 22 2c 20 7a 49 64 29  UPDATE %s", zId)
53b0: 3b 0a 20 20 20 20 20 20 20 20 20 20 7a 53 65 70  ;.          zSep
53c0: 20 3d 20 22 20 53 45 54 22 3b 0a 20 20 20 20 20   = " SET";.     
53d0: 20 20 20 20 20 66 6f 72 28 69 3d 6e 50 6b 2b 31       for(i=nPk+1
53e0: 3b 20 69 3c 6e 51 3b 20 69 2b 3d 32 29 7b 0a 20  ; i<nQ; i+=2){. 
53f0: 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20 73             if( s
5400: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e  qlite3_column_in
5410: 74 28 70 53 74 6d 74 2c 69 29 3d 3d 30 20 29 20  t(pStmt,i)==0 ) 
5420: 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20  continue;.      
5430: 20 20 20 20 20 20 66 70 72 69 6e 74 66 28 6f 75        fprintf(ou
5440: 74 2c 20 22 25 73 20 25 73 3d 22 2c 20 7a 53 65  t, "%s %s=", zSe
5450: 70 2c 20 61 7a 32 5b 28 69 2b 6e 50 6b 2d 31 29  p, az2[(i+nPk-1)
5460: 2f 32 5d 29 3b 0a 20 20 20 20 20 20 20 20 20 20  /2]);.          
5470: 20 20 7a 53 65 70 20 3d 20 22 2c 22 3b 0a 20 20    zSep = ",";.  
5480: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 51            printQ
5490: 75 6f 74 65 64 28 6f 75 74 2c 20 73 71 6c 69 74  uoted(out, sqlit
54a0: 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28  e3_column_value(
54b0: 70 53 74 6d 74 2c 69 2b 31 29 29 3b 0a 20 20 20  pStmt,i+1));.   
54c0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
54d0: 20 7d 65 6c 73 65 7b 20 20 20 20 20 20 20 20 20   }else{         
54e0: 20 20 20 20 20 20 20 2f 2a 20 44 65 6c 65 74 65         /* Delete
54f0: 20 61 20 72 6f 77 20 2a 2f 0a 20 20 20 20 20 20   a row */.      
5500: 20 20 20 20 66 70 72 69 6e 74 66 28 6f 75 74 2c      fprintf(out,
5510: 20 22 44 45 4c 45 54 45 20 46 52 4f 4d 20 25 73   "DELETE FROM %s
5520: 22 2c 20 7a 49 64 29 3b 0a 20 20 20 20 20 20 20  ", zId);.       
5530: 20 7d 0a 20 20 20 20 20 20 20 20 7a 53 65 70 20   }.        zSep 
5540: 3d 20 22 20 57 48 45 52 45 22 3b 0a 20 20 20 20  = " WHERE";.    
5550: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e      for(i=0; i<n
5560: 50 6b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  Pk; i++){.      
5570: 20 20 20 20 66 70 72 69 6e 74 66 28 6f 75 74 2c      fprintf(out,
5580: 20 22 25 73 20 25 73 3d 22 2c 20 7a 53 65 70 2c   "%s %s=", zSep,
5590: 20 61 7a 32 5b 69 5d 29 3b 0a 20 20 20 20 20 20   az2[i]);.      
55a0: 20 20 20 20 70 72 69 6e 74 51 75 6f 74 65 64 28      printQuoted(
55b0: 6f 75 74 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c  out, sqlite3_col
55c0: 75 6d 6e 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c  umn_value(pStmt,
55d0: 69 29 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7a  i));.          z
55e0: 53 65 70 20 3d 20 22 20 41 4e 44 22 3b 0a 20 20  Sep = " AND";.  
55f0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
5600: 66 70 72 69 6e 74 66 28 6f 75 74 2c 20 22 3b 5c  fprintf(out, ";\
5610: 6e 22 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  n");.      }else
5620: 7b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  {               
5630: 20 20 20 2f 2a 20 49 6e 73 65 72 74 20 61 20 72     /* Insert a r
5640: 6f 77 20 2a 2f 0a 20 20 20 20 20 20 20 20 66 70  ow */.        fp
5650: 72 69 6e 74 66 28 6f 75 74 2c 20 22 49 4e 53 45  rintf(out, "INSE
5660: 52 54 20 49 4e 54 4f 20 25 73 28 25 73 22 2c 20  RT INTO %s(%s", 
5670: 7a 49 64 2c 20 61 7a 32 5b 30 5d 29 3b 0a 20 20  zId, az2[0]);.  
5680: 20 20 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 61        for(i=1; a
5690: 7a 32 5b 69 5d 3b 20 69 2b 2b 29 20 66 70 72 69  z2[i]; i++) fpri
56a0: 6e 74 66 28 6f 75 74 2c 20 22 2c 25 73 22 2c 20  ntf(out, ",%s", 
56b0: 61 7a 32 5b 69 5d 29 3b 0a 20 20 20 20 20 20 20  az2[i]);.       
56c0: 20 66 70 72 69 6e 74 66 28 6f 75 74 2c 20 22 29   fprintf(out, ")
56d0: 20 56 41 4c 55 45 53 22 29 3b 0a 20 20 20 20 20   VALUES");.     
56e0: 20 20 20 7a 53 65 70 20 3d 20 22 28 22 3b 0a 20     zSep = "(";. 
56f0: 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20         for(i=0; 
5700: 69 3c 6e 50 6b 32 3b 20 69 2b 2b 29 7b 0a 20 20  i<nPk2; i++){.  
5710: 20 20 20 20 20 20 20 20 66 70 72 69 6e 74 66 28          fprintf(
5720: 6f 75 74 2c 20 22 25 73 22 2c 20 7a 53 65 70 29  out, "%s", zSep)
5730: 3b 0a 20 20 20 20 20 20 20 20 20 20 7a 53 65 70  ;.          zSep
5740: 20 3d 20 22 2c 22 3b 0a 20 20 20 20 20 20 20 20   = ",";.        
5750: 20 20 70 72 69 6e 74 51 75 6f 74 65 64 28 6f 75    printQuoted(ou
5760: 74 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  t, sqlite3_colum
5770: 6e 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 69 29  n_value(pStmt,i)
5780: 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  );.        }.   
5790: 20 20 20 20 20 66 6f 72 28 69 3d 6e 50 6b 32 2b       for(i=nPk2+
57a0: 32 3b 20 69 3c 6e 51 3b 20 69 2b 3d 32 29 7b 0a  2; i<nQ; i+=2){.
57b0: 20 20 20 20 20 20 20 20 20 20 66 70 72 69 6e 74            fprint
57c0: 66 28 6f 75 74 2c 20 22 2c 22 29 3b 0a 20 20 20  f(out, ",");.   
57d0: 20 20 20 20 20 20 20 70 72 69 6e 74 51 75 6f 74         printQuot
57e0: 65 64 28 6f 75 74 2c 20 73 71 6c 69 74 65 33 5f  ed(out, sqlite3_
57f0: 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 53 74  column_value(pSt
5800: 6d 74 2c 69 29 29 3b 0a 20 20 20 20 20 20 20 20  mt,i));.        
5810: 7d 0a 20 20 20 20 20 20 20 20 66 70 72 69 6e 74  }.        fprint
5820: 66 28 6f 75 74 2c 20 22 29 3b 5c 6e 22 29 3b 0a  f(out, ");\n");.
5830: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
5840: 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
5850: 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 7d 20 2f  ze(pStmt);.  } /
5860: 2a 20 65 6e 64 69 66 20 21 67 2e 62 53 63 68 65  * endif !g.bSche
5870: 6d 61 4f 6e 6c 79 20 2a 2f 0a 0a 20 20 2f 2a 20  maOnly */..  /* 
5880: 43 72 65 61 74 65 20 69 6e 64 65 78 65 73 20 74  Create indexes t
5890: 68 61 74 20 61 72 65 20 6d 69 73 73 69 6e 67 20  hat are missing 
58a0: 69 6e 20 74 68 65 20 73 6f 75 72 63 65 20 2a 2f  in the source */
58b0: 0a 20 20 70 53 74 6d 74 20 3d 20 64 62 5f 70 72  .  pStmt = db_pr
58c0: 65 70 61 72 65 28 0a 20 20 20 20 22 53 45 4c 45  epare(.    "SELE
58d0: 43 54 20 73 71 6c 20 46 52 4f 4d 20 61 75 78 2e  CT sql FROM aux.
58e0: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 22 0a 20  sqlite_master". 
58f0: 20 20 20 22 20 57 48 45 52 45 20 74 79 70 65 3d     " WHERE type=
5900: 27 69 6e 64 65 78 27 20 41 4e 44 20 74 62 6c 5f  'index' AND tbl_
5910: 6e 61 6d 65 3d 25 51 22 0a 20 20 20 20 22 20 20  name=%Q".    "  
5920: 20 41 4e 44 20 73 71 6c 20 49 53 20 4e 4f 54 20   AND sql IS NOT 
5930: 4e 55 4c 4c 22 0a 20 20 20 20 22 20 20 20 41 4e  NULL".    "   AN
5940: 44 20 73 71 6c 20 4e 4f 54 20 49 4e 20 28 53 45  D sql NOT IN (SE
5950: 4c 45 43 54 20 73 71 6c 20 46 52 4f 4d 20 6d 61  LECT sql FROM ma
5960: 69 6e 2e 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  in.sqlite_master
5970: 22 0a 20 20 20 20 22 20 20 20 20 20 20 20 20 20  ".    "         
5980: 20 20 20 20 20 20 20 20 20 20 20 57 48 45 52 45             WHERE
5990: 20 74 79 70 65 3d 27 69 6e 64 65 78 27 20 41 4e   type='index' AN
59a0: 44 20 74 62 6c 5f 6e 61 6d 65 3d 25 51 22 0a 20  D tbl_name=%Q". 
59b0: 20 20 20 22 20 20 20 20 20 20 20 20 20 20 20 20     "            
59c0: 20 20 20 20 20 20 20 20 20 20 41 4e 44 20 73 71            AND sq
59d0: 6c 20 49 53 20 4e 4f 54 20 4e 55 4c 4c 29 22 2c  l IS NOT NULL)",
59e0: 0a 20 20 20 20 7a 54 61 62 2c 20 7a 54 61 62 29  .    zTab, zTab)
59f0: 3b 0a 20 20 77 68 69 6c 65 28 20 53 51 4c 49 54  ;.  while( SQLIT
5a00: 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33 5f 73  E_ROW==sqlite3_s
5a10: 74 65 70 28 70 53 74 6d 74 29 20 29 7b 0a 20 20  tep(pStmt) ){.  
5a20: 20 20 66 70 72 69 6e 74 66 28 6f 75 74 2c 20 22    fprintf(out, "
5a30: 25 73 3b 5c 6e 22 2c 20 73 71 6c 69 74 65 33 5f  %s;\n", sqlite3_
5a40: 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 53 74 6d  column_text(pStm
5a50: 74 2c 30 29 29 3b 0a 20 20 7d 0a 20 20 73 71 6c  t,0));.  }.  sql
5a60: 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53  ite3_finalize(pS
5a70: 74 6d 74 29 3b 0a 0a 65 6e 64 5f 64 69 66 66 5f  tmt);..end_diff_
5a80: 6f 6e 65 5f 74 61 62 6c 65 3a 0a 20 20 73 74 72  one_table:.  str
5a90: 46 72 65 65 28 26 73 71 6c 29 3b 0a 20 20 73 71  Free(&sql);.  sq
5aa0: 6c 69 74 65 33 5f 66 72 65 65 28 7a 49 64 29 3b  lite3_free(zId);
5ab0: 0a 20 20 6e 61 6d 65 6c 69 73 74 46 72 65 65 28  .  namelistFree(
5ac0: 61 7a 29 3b 0a 20 20 6e 61 6d 65 6c 69 73 74 46  az);.  namelistF
5ad0: 72 65 65 28 61 7a 32 29 3b 0a 20 20 72 65 74 75  ree(az2);.  retu
5ae0: 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65  rn;.}../*.** Che
5af0: 63 6b 20 74 68 61 74 20 74 61 62 6c 65 20 7a 54  ck that table zT
5b00: 61 62 20 65 78 69 73 74 73 20 61 6e 64 20 68 61  ab exists and ha
5b10: 73 20 74 68 65 20 73 61 6d 65 20 73 63 68 65 6d  s the same schem
5b20: 61 20 69 6e 20 62 6f 74 68 20 74 68 65 20 22 6d  a in both the "m
5b30: 61 69 6e 22 0a 2a 2a 20 61 6e 64 20 22 61 75 78  ain".** and "aux
5b40: 22 20 64 61 74 61 62 61 73 65 73 20 63 75 72 72  " databases curr
5b50: 65 6e 74 6c 79 20 6f 70 65 6e 65 64 20 62 79 20  ently opened by 
5b60: 74 68 65 20 67 6c 6f 62 61 6c 20 64 62 20 68 61  the global db ha
5b70: 6e 64 6c 65 2e 20 49 66 20 74 68 65 79 0a 2a 2a  ndle. If they.**
5b80: 20 64 6f 20 6e 6f 74 2c 20 6f 75 74 70 75 74 20   do not, output 
5b90: 61 6e 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65  an error message
5ba0: 20 6f 6e 20 73 74 64 65 72 72 20 61 6e 64 20 65   on stderr and e
5bb0: 78 69 74 28 31 29 2e 20 4f 74 68 65 72 77 69 73  xit(1). Otherwis
5bc0: 65 2c 20 69 66 0a 2a 2a 20 74 68 65 20 73 63 68  e, if.** the sch
5bd0: 65 6d 61 73 20 64 6f 20 6d 61 74 63 68 2c 20 72  emas do match, r
5be0: 65 74 75 72 6e 20 63 6f 6e 74 72 6f 6c 20 74 6f  eturn control to
5bf0: 20 74 68 65 20 63 61 6c 6c 65 72 2e 0a 2a 2f 0a   the caller..*/.
5c00: 73 74 61 74 69 63 20 76 6f 69 64 20 63 68 65 63  static void chec
5c10: 6b 53 63 68 65 6d 61 73 4d 61 74 63 68 28 63 6f  kSchemasMatch(co
5c20: 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 62 29 7b  nst char *zTab){
5c30: 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
5c40: 2a 70 53 74 6d 74 20 3d 20 64 62 5f 70 72 65 70  *pStmt = db_prep
5c50: 61 72 65 28 0a 20 20 20 20 20 20 22 53 45 4c 45  are(.      "SELE
5c60: 43 54 20 41 2e 73 71 6c 3d 42 2e 73 71 6c 20 46  CT A.sql=B.sql F
5c70: 52 4f 4d 20 6d 61 69 6e 2e 73 71 6c 69 74 65 5f  ROM main.sqlite_
5c80: 6d 61 73 74 65 72 20 41 2c 20 61 75 78 2e 73 71  master A, aux.sq
5c90: 6c 69 74 65 5f 6d 61 73 74 65 72 20 42 22 0a 20  lite_master B". 
5ca0: 20 20 20 20 20 22 20 57 48 45 52 45 20 41 2e 6e       " WHERE A.n
5cb0: 61 6d 65 3d 25 51 20 41 4e 44 20 42 2e 6e 61 6d  ame=%Q AND B.nam
5cc0: 65 3d 25 51 22 2c 20 7a 54 61 62 2c 20 7a 54 61  e=%Q", zTab, zTa
5cd0: 62 0a 20 20 29 3b 0a 20 20 69 66 28 20 53 51 4c  b.  );.  if( SQL
5ce0: 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33  ITE_ROW==sqlite3
5cf0: 5f 73 74 65 70 28 70 53 74 6d 74 29 20 29 7b 0a  _step(pStmt) ){.
5d00: 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f      if( sqlite3_
5d10: 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d 74  column_int(pStmt
5d20: 2c 30 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  ,0)==0 ){.      
5d30: 72 75 6e 74 69 6d 65 45 72 72 6f 72 28 22 73 63  runtimeError("sc
5d40: 68 65 6d 61 20 63 68 61 6e 67 65 73 20 66 6f 72  hema changes for
5d50: 20 74 61 62 6c 65 20 25 73 22 2c 20 73 61 66 65   table %s", safe
5d60: 49 64 28 7a 54 61 62 29 29 3b 0a 20 20 20 20 7d  Id(zTab));.    }
5d70: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 75  .  }else{.    ru
5d80: 6e 74 69 6d 65 45 72 72 6f 72 28 22 74 61 62 6c  ntimeError("tabl
5d90: 65 20 25 73 20 6d 69 73 73 69 6e 67 20 66 72 6f  e %s missing fro
5da0: 6d 20 6f 6e 65 20 6f 72 20 62 6f 74 68 20 64 61  m one or both da
5db0: 74 61 62 61 73 65 73 22 2c 20 73 61 66 65 49 64  tabases", safeId
5dc0: 28 7a 54 61 62 29 29 3b 0a 20 20 7d 0a 20 20 73  (zTab));.  }.  s
5dd0: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
5de0: 70 53 74 6d 74 29 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a  pStmt);.}../****
5df0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5e00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5e10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5e20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5e30: 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 54 68 65 20 66 6f  ******.** The fo
5e40: 6c 6c 6f 77 69 6e 67 20 63 6f 64 65 20 69 73 20  llowing code is 
5e50: 63 6f 70 69 65 64 20 66 72 6f 6d 20 66 6f 73 73  copied from foss
5e60: 69 6c 2e 20 49 74 20 69 73 20 75 73 65 64 20 74  il. It is used t
5e70: 6f 20 67 65 6e 65 72 61 74 65 20 74 68 65 0a 2a  o generate the.*
5e80: 2a 20 66 6f 73 73 69 6c 20 64 65 6c 74 61 20 62  * fossil delta b
5e90: 6c 6f 62 73 20 73 6f 6d 65 74 69 6d 65 73 20 75  lobs sometimes u
5ea0: 73 65 64 20 69 6e 20 52 42 55 20 75 70 64 61 74  sed in RBU updat
5eb0: 65 20 72 65 63 6f 72 64 73 2e 0a 2a 2f 0a 0a 74  e records..*/..t
5ec0: 79 70 65 64 65 66 20 75 6e 73 69 67 6e 65 64 20  ypedef unsigned 
5ed0: 73 68 6f 72 74 20 75 31 36 3b 0a 74 79 70 65 64  short u16;.typed
5ee0: 65 66 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  ef unsigned int 
5ef0: 75 33 32 3b 0a 74 79 70 65 64 65 66 20 75 6e 73  u32;.typedef uns
5f00: 69 67 6e 65 64 20 63 68 61 72 20 75 38 3b 0a 0a  igned char u8;..
5f10: 2f 2a 0a 2a 2a 20 54 68 65 20 77 69 64 74 68 20  /*.** The width 
5f20: 6f 66 20 61 20 68 61 73 68 20 77 69 6e 64 6f 77  of a hash window
5f30: 20 69 6e 20 62 79 74 65 73 2e 20 20 54 68 65 20   in bytes.  The 
5f40: 61 6c 67 6f 72 69 74 68 6d 20 6f 6e 6c 79 20 77  algorithm only w
5f50: 6f 72 6b 73 20 69 66 20 74 68 69 73 0a 2a 2a 20  orks if this.** 
5f60: 69 73 20 61 20 70 6f 77 65 72 20 6f 66 20 32 2e  is a power of 2.
5f70: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 4e 48 41 53  .*/.#define NHAS
5f80: 48 20 31 36 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20  H 16../*.** The 
5f90: 63 75 72 72 65 6e 74 20 73 74 61 74 65 20 6f 66  current state of
5fa0: 20 74 68 65 20 72 6f 6c 6c 69 6e 67 20 68 61 73   the rolling has
5fb0: 68 2e 0a 2a 2a 0a 2a 2a 20 7a 5b 5d 20 68 6f 6c  h..**.** z[] hol
5fc0: 64 73 20 74 68 65 20 76 61 6c 75 65 73 20 74 68  ds the values th
5fd0: 61 74 20 68 61 76 65 20 62 65 65 6e 20 68 61 73  at have been has
5fe0: 68 65 64 2e 20 20 7a 5b 5d 20 69 73 20 61 20 63  hed.  z[] is a c
5ff0: 69 72 63 75 6c 61 72 20 62 75 66 66 65 72 2e 0a  ircular buffer..
6000: 2a 2a 20 7a 5b 69 5d 20 69 73 20 74 68 65 20 66  ** z[i] is the f
6010: 69 72 73 74 20 65 6e 74 72 79 20 61 6e 64 20 7a  irst entry and z
6020: 5b 28 69 2b 4e 48 41 53 48 2d 31 29 25 4e 48 41  [(i+NHASH-1)%NHA
6030: 53 48 5d 20 69 73 20 74 68 65 20 6c 61 73 74 20  SH] is the last 
6040: 65 6e 74 72 79 20 6f 66 0a 2a 2a 20 74 68 65 20  entry of.** the 
6050: 77 69 6e 64 6f 77 2e 0a 2a 2a 0a 2a 2a 20 48 61  window..**.** Ha
6060: 73 68 2e 61 20 69 73 20 74 68 65 20 73 75 6d 20  sh.a is the sum 
6070: 6f 66 20 61 6c 6c 20 65 6c 65 6d 65 6e 74 73 20  of all elements 
6080: 6f 66 20 68 61 73 68 2e 7a 5b 5d 2e 20 20 48 61  of hash.z[].  Ha
6090: 73 68 2e 62 20 69 73 20 61 20 77 65 69 67 68 74  sh.b is a weight
60a0: 65 64 0a 2a 2a 20 73 75 6d 2e 20 20 48 61 73 68  ed.** sum.  Hash
60b0: 2e 62 20 69 73 20 7a 5b 69 5d 2a 4e 48 41 53 48  .b is z[i]*NHASH
60c0: 20 2b 20 7a 5b 69 2b 31 5d 2a 28 4e 48 41 53 48   + z[i+1]*(NHASH
60d0: 2d 31 29 20 2b 20 2e 2e 2e 20 2b 20 7a 5b 69 2b  -1) + ... + z[i+
60e0: 4e 48 41 53 48 2d 31 5d 2a 31 2e 0a 2a 2a 20 28  NHASH-1]*1..** (
60f0: 45 61 63 68 20 69 6e 64 65 78 20 66 6f 72 20 7a  Each index for z
6100: 5b 5d 20 73 68 6f 75 6c 64 20 62 65 20 6d 6f 64  [] should be mod
6110: 75 6c 65 20 4e 48 41 53 48 2c 20 6f 66 20 63 6f  ule NHASH, of co
6120: 75 72 73 65 2e 20 20 54 68 65 20 25 4e 48 41 53  urse.  The %NHAS
6130: 48 20 6f 70 65 72 61 74 6f 72 0a 2a 2a 20 69 73  H operator.** is
6140: 20 6f 6d 69 74 74 65 64 20 69 6e 20 74 68 65 20   omitted in the 
6150: 70 72 69 6f 72 20 65 78 70 72 65 73 73 69 6f 6e  prior expression
6160: 20 66 6f 72 20 62 72 65 76 69 74 79 2e 29 0a 2a   for brevity.).*
6170: 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  /.typedef struct
6180: 20 68 61 73 68 20 68 61 73 68 3b 0a 73 74 72 75   hash hash;.stru
6190: 63 74 20 68 61 73 68 20 7b 0a 20 20 75 31 36 20  ct hash {.  u16 
61a0: 61 2c 20 62 3b 20 20 20 20 20 20 20 20 20 2f 2a  a, b;         /*
61b0: 20 48 61 73 68 20 76 61 6c 75 65 73 20 2a 2f 0a   Hash values */.
61c0: 20 20 75 31 36 20 69 3b 20 20 20 20 20 20 20 20    u16 i;        
61d0: 20 20 20 20 2f 2a 20 53 74 61 72 74 20 6f 66 20      /* Start of 
61e0: 74 68 65 20 68 61 73 68 20 77 69 6e 64 6f 77 20  the hash window 
61f0: 2a 2f 0a 20 20 63 68 61 72 20 7a 5b 4e 48 41 53  */.  char z[NHAS
6200: 48 5d 3b 20 20 20 20 2f 2a 20 54 68 65 20 76 61  H];    /* The va
6210: 6c 75 65 73 20 74 68 61 74 20 68 61 76 65 20 62  lues that have b
6220: 65 65 6e 20 68 61 73 68 65 64 20 2a 2f 0a 7d 3b  een hashed */.};
6230: 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69  ../*.** Initiali
6240: 7a 65 20 74 68 65 20 72 6f 6c 6c 69 6e 67 20 68  ze the rolling h
6250: 61 73 68 20 75 73 69 6e 67 20 74 68 65 20 66 69  ash using the fi
6260: 72 73 74 20 4e 48 41 53 48 20 63 68 61 72 61 63  rst NHASH charac
6270: 74 65 72 73 20 6f 66 20 7a 5b 5d 0a 2a 2f 0a 73  ters of z[].*/.s
6280: 74 61 74 69 63 20 76 6f 69 64 20 68 61 73 68 5f  tatic void hash_
6290: 69 6e 69 74 28 68 61 73 68 20 2a 70 48 61 73 68  init(hash *pHash
62a0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 29  , const char *z)
62b0: 7b 0a 20 20 75 31 36 20 61 2c 20 62 2c 20 69 3b  {.  u16 a, b, i;
62c0: 0a 20 20 61 20 3d 20 62 20 3d 20 30 3b 0a 20 20  .  a = b = 0;.  
62d0: 66 6f 72 28 69 3d 30 3b 20 69 3c 4e 48 41 53 48  for(i=0; i<NHASH
62e0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 61 20 2b 3d  ; i++){.    a +=
62f0: 20 7a 5b 69 5d 3b 0a 20 20 20 20 62 20 2b 3d 20   z[i];.    b += 
6300: 28 4e 48 41 53 48 2d 69 29 2a 7a 5b 69 5d 3b 0a  (NHASH-i)*z[i];.
6310: 20 20 20 20 70 48 61 73 68 2d 3e 7a 5b 69 5d 20      pHash->z[i] 
6320: 3d 20 7a 5b 69 5d 3b 0a 20 20 7d 0a 20 20 70 48  = z[i];.  }.  pH
6330: 61 73 68 2d 3e 61 20 3d 20 61 20 26 20 30 78 66  ash->a = a & 0xf
6340: 66 66 66 3b 0a 20 20 70 48 61 73 68 2d 3e 62 20  fff;.  pHash->b 
6350: 3d 20 62 20 26 20 30 78 66 66 66 66 3b 0a 20 20  = b & 0xffff;.  
6360: 70 48 61 73 68 2d 3e 69 20 3d 20 30 3b 0a 7d 0a  pHash->i = 0;.}.
6370: 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 74  ./*.** Advance t
6380: 68 65 20 72 6f 6c 6c 69 6e 67 20 68 61 73 68 20  he rolling hash 
6390: 62 79 20 61 20 73 69 6e 67 6c 65 20 63 68 61 72  by a single char
63a0: 61 63 74 65 72 20 22 63 22 0a 2a 2f 0a 73 74 61  acter "c".*/.sta
63b0: 74 69 63 20 76 6f 69 64 20 68 61 73 68 5f 6e 65  tic void hash_ne
63c0: 78 74 28 68 61 73 68 20 2a 70 48 61 73 68 2c 20  xt(hash *pHash, 
63d0: 69 6e 74 20 63 29 7b 0a 20 20 75 31 36 20 6f 6c  int c){.  u16 ol
63e0: 64 20 3d 20 70 48 61 73 68 2d 3e 7a 5b 70 48 61  d = pHash->z[pHa
63f0: 73 68 2d 3e 69 5d 3b 0a 20 20 70 48 61 73 68 2d  sh->i];.  pHash-
6400: 3e 7a 5b 70 48 61 73 68 2d 3e 69 5d 20 3d 20 28  >z[pHash->i] = (
6410: 63 68 61 72 29 63 3b 0a 20 20 70 48 61 73 68 2d  char)c;.  pHash-
6420: 3e 69 20 3d 20 28 70 48 61 73 68 2d 3e 69 2b 31  >i = (pHash->i+1
6430: 29 26 28 4e 48 41 53 48 2d 31 29 3b 0a 20 20 70  )&(NHASH-1);.  p
6440: 48 61 73 68 2d 3e 61 20 3d 20 70 48 61 73 68 2d  Hash->a = pHash-
6450: 3e 61 20 2d 20 6f 6c 64 20 2b 20 28 63 68 61 72  >a - old + (char
6460: 29 63 3b 0a 20 20 70 48 61 73 68 2d 3e 62 20 3d  )c;.  pHash->b =
6470: 20 70 48 61 73 68 2d 3e 62 20 2d 20 4e 48 41 53   pHash->b - NHAS
6480: 48 2a 6f 6c 64 20 2b 20 70 48 61 73 68 2d 3e 61  H*old + pHash->a
6490: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
64a0: 6e 20 61 20 33 32 2d 62 69 74 20 68 61 73 68 20  n a 32-bit hash 
64b0: 76 61 6c 75 65 0a 2a 2f 0a 73 74 61 74 69 63 20  value.*/.static 
64c0: 75 33 32 20 68 61 73 68 5f 33 32 62 69 74 28 68  u32 hash_32bit(h
64d0: 61 73 68 20 2a 70 48 61 73 68 29 7b 0a 20 20 72  ash *pHash){.  r
64e0: 65 74 75 72 6e 20 28 70 48 61 73 68 2d 3e 61 20  eturn (pHash->a 
64f0: 26 20 30 78 66 66 66 66 29 20 7c 20 28 28 28 75  & 0xffff) | (((u
6500: 33 32 29 28 70 48 61 73 68 2d 3e 62 20 26 20 30  32)(pHash->b & 0
6510: 78 66 66 66 66 29 29 3c 3c 31 36 29 3b 0a 7d 0a  xffff))<<16);.}.
6520: 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 61 6e 20  ./*.** Write an 
6530: 62 61 73 65 2d 36 34 20 69 6e 74 65 67 65 72 20  base-64 integer 
6540: 69 6e 74 6f 20 74 68 65 20 67 69 76 65 6e 20 62  into the given b
6550: 75 66 66 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63  uffer..*/.static
6560: 20 76 6f 69 64 20 70 75 74 49 6e 74 28 75 6e 73   void putInt(uns
6570: 69 67 6e 65 64 20 69 6e 74 20 76 2c 20 63 68 61  igned int v, cha
6580: 72 20 2a 2a 70 7a 29 7b 0a 20 20 73 74 61 74 69  r **pz){.  stati
6590: 63 20 63 6f 6e 73 74 20 63 68 61 72 20 7a 44 69  c const char zDi
65a0: 67 69 74 73 5b 5d 20 3d 0a 20 20 20 20 22 30 31  gits[] =.    "01
65b0: 32 33 34 35 36 37 38 39 41 42 43 44 45 46 47 48  23456789ABCDEFGH
65c0: 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58  IJKLMNOPQRSTUVWX
65d0: 59 5a 5f 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d  YZ_abcdefghijklm
65e0: 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7e 22 3b  nopqrstuvwxyz~";
65f0: 0a 20 20 2f 2a 20 20 31 32 33 34 35 36 37 38 39  .  /*  123456789
6600: 20 31 32 33 34 35 36 37 38 39 20 31 32 33 34 35   123456789 12345
6610: 36 37 38 39 20 31 32 33 34 35 36 37 38 39 20 31  6789 123456789 1
6620: 32 33 34 35 36 37 38 39 20 31 32 33 34 35 36 37  23456789 1234567
6630: 38 39 20 31 32 33 20 2a 2f 0a 20 20 69 6e 74 20  89 123 */.  int 
6640: 69 2c 20 6a 3b 0a 20 20 63 68 61 72 20 7a 42 75  i, j;.  char zBu
6650: 66 5b 32 30 5d 3b 0a 20 20 69 66 28 20 76 3d 3d  f[20];.  if( v==
6660: 30 20 29 7b 0a 20 20 20 20 2a 28 2a 70 7a 29 2b  0 ){.    *(*pz)+
6670: 2b 20 3d 20 27 30 27 3b 0a 20 20 20 20 72 65 74  + = '0';.    ret
6680: 75 72 6e 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 69  urn;.  }.  for(i
6690: 3d 30 3b 20 76 3e 30 3b 20 69 2b 2b 2c 20 76 3e  =0; v>0; i++, v>
66a0: 3e 3d 36 29 7b 0a 20 20 20 20 7a 42 75 66 5b 69  >=6){.    zBuf[i
66b0: 5d 20 3d 20 7a 44 69 67 69 74 73 5b 76 26 30 78  ] = zDigits[v&0x
66c0: 33 66 5d 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 6a  3f];.  }.  for(j
66d0: 3d 69 2d 31 3b 20 6a 3e 3d 30 3b 20 6a 2d 2d 29  =i-1; j>=0; j--)
66e0: 7b 0a 20 20 20 20 2a 28 2a 70 7a 29 2b 2b 20 3d  {.    *(*pz)++ =
66f0: 20 7a 42 75 66 5b 6a 5d 3b 0a 20 20 7d 0a 7d 0a   zBuf[j];.  }.}.
6700: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  ./*.** Return th
6710: 65 20 6e 75 6d 62 65 72 20 64 69 67 69 74 73 20  e number digits 
6720: 69 6e 20 74 68 65 20 62 61 73 65 2d 36 34 20 72  in the base-64 r
6730: 65 70 72 65 73 65 6e 74 61 74 69 6f 6e 20 6f 66  epresentation of
6740: 20 61 20 70 6f 73 69 74 69 76 65 20 69 6e 74 65   a positive inte
6750: 67 65 72 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ger.*/.static in
6760: 74 20 64 69 67 69 74 5f 63 6f 75 6e 74 28 69 6e  t digit_count(in
6770: 74 20 76 29 7b 0a 20 20 75 6e 73 69 67 6e 65 64  t v){.  unsigned
6780: 20 69 6e 74 20 69 2c 20 78 3b 0a 20 20 66 6f 72   int i, x;.  for
6790: 28 69 3d 31 2c 20 78 3d 36 34 3b 20 28 75 6e 73  (i=1, x=64; (uns
67a0: 69 67 6e 65 64 20 69 6e 74 29 76 3e 3d 78 3b 20  igned int)v>=x; 
67b0: 69 2b 2b 2c 20 78 20 3c 3c 3d 20 36 29 7b 7d 0a  i++, x <<= 6){}.
67c0: 20 20 72 65 74 75 72 6e 20 69 3b 0a 7d 0a 0a 2f    return i;.}../
67d0: 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 61 20 33  *.** Compute a 3
67e0: 32 2d 62 69 74 20 63 68 65 63 6b 73 75 6d 20 6f  2-bit checksum o
67f0: 6e 20 74 68 65 20 4e 2d 62 79 74 65 20 62 75 66  n the N-byte buf
6800: 66 65 72 2e 20 20 52 65 74 75 72 6e 20 74 68 65  fer.  Return the
6810: 20 72 65 73 75 6c 74 2e 0a 2a 2f 0a 73 74 61 74   result..*/.stat
6820: 69 63 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  ic unsigned int 
6830: 63 68 65 63 6b 73 75 6d 28 63 6f 6e 73 74 20 63  checksum(const c
6840: 68 61 72 20 2a 7a 49 6e 2c 20 73 69 7a 65 5f 74  har *zIn, size_t
6850: 20 4e 29 7b 0a 20 20 63 6f 6e 73 74 20 75 6e 73   N){.  const uns
6860: 69 67 6e 65 64 20 63 68 61 72 20 2a 7a 20 3d 20  igned char *z = 
6870: 28 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64 20  (const unsigned 
6880: 63 68 61 72 20 2a 29 7a 49 6e 3b 0a 20 20 75 6e  char *)zIn;.  un
6890: 73 69 67 6e 65 64 20 73 75 6d 30 20 3d 20 30 3b  signed sum0 = 0;
68a0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 73 75 6d 31  .  unsigned sum1
68b0: 20 3d 20 30 3b 0a 20 20 75 6e 73 69 67 6e 65 64   = 0;.  unsigned
68c0: 20 73 75 6d 32 20 3d 20 30 3b 0a 20 20 75 6e 73   sum2 = 0;.  uns
68d0: 69 67 6e 65 64 20 73 75 6d 33 20 3d 20 30 3b 0a  igned sum3 = 0;.
68e0: 20 20 77 68 69 6c 65 28 4e 20 3e 3d 20 31 36 29    while(N >= 16)
68f0: 7b 0a 20 20 20 20 73 75 6d 30 20 2b 3d 20 28 28  {.    sum0 += ((
6900: 75 6e 73 69 67 6e 65 64 29 7a 5b 30 5d 20 2b 20  unsigned)z[0] + 
6910: 7a 5b 34 5d 20 2b 20 7a 5b 38 5d 20 2b 20 7a 5b  z[4] + z[8] + z[
6920: 31 32 5d 29 3b 0a 20 20 20 20 73 75 6d 31 20 2b  12]);.    sum1 +
6930: 3d 20 28 28 75 6e 73 69 67 6e 65 64 29 7a 5b 31  = ((unsigned)z[1
6940: 5d 20 2b 20 7a 5b 35 5d 20 2b 20 7a 5b 39 5d 20  ] + z[5] + z[9] 
6950: 2b 20 7a 5b 31 33 5d 29 3b 0a 20 20 20 20 73 75  + z[13]);.    su
6960: 6d 32 20 2b 3d 20 28 28 75 6e 73 69 67 6e 65 64  m2 += ((unsigned
6970: 29 7a 5b 32 5d 20 2b 20 7a 5b 36 5d 20 2b 20 7a  )z[2] + z[6] + z
6980: 5b 31 30 5d 2b 20 7a 5b 31 34 5d 29 3b 0a 20 20  [10]+ z[14]);.  
6990: 20 20 73 75 6d 33 20 2b 3d 20 28 28 75 6e 73 69    sum3 += ((unsi
69a0: 67 6e 65 64 29 7a 5b 33 5d 20 2b 20 7a 5b 37 5d  gned)z[3] + z[7]
69b0: 20 2b 20 7a 5b 31 31 5d 2b 20 7a 5b 31 35 5d 29   + z[11]+ z[15])
69c0: 3b 0a 20 20 20 20 7a 20 2b 3d 20 31 36 3b 0a 20  ;.    z += 16;. 
69d0: 20 20 20 4e 20 2d 3d 20 31 36 3b 0a 20 20 7d 0a     N -= 16;.  }.
69e0: 20 20 77 68 69 6c 65 28 4e 20 3e 3d 20 34 29 7b    while(N >= 4){
69f0: 0a 20 20 20 20 73 75 6d 30 20 2b 3d 20 7a 5b 30  .    sum0 += z[0
6a00: 5d 3b 0a 20 20 20 20 73 75 6d 31 20 2b 3d 20 7a  ];.    sum1 += z
6a10: 5b 31 5d 3b 0a 20 20 20 20 73 75 6d 32 20 2b 3d  [1];.    sum2 +=
6a20: 20 7a 5b 32 5d 3b 0a 20 20 20 20 73 75 6d 33 20   z[2];.    sum3 
6a30: 2b 3d 20 7a 5b 33 5d 3b 0a 20 20 20 20 7a 20 2b  += z[3];.    z +
6a40: 3d 20 34 3b 0a 20 20 20 20 4e 20 2d 3d 20 34 3b  = 4;.    N -= 4;
6a50: 0a 20 20 7d 0a 20 20 73 75 6d 33 20 2b 3d 20 28  .  }.  sum3 += (
6a60: 73 75 6d 32 20 3c 3c 20 38 29 20 2b 20 28 73 75  sum2 << 8) + (su
6a70: 6d 31 20 3c 3c 20 31 36 29 20 2b 20 28 73 75 6d  m1 << 16) + (sum
6a80: 30 20 3c 3c 20 32 34 29 3b 0a 20 20 73 77 69 74  0 << 24);.  swit
6a90: 63 68 28 4e 29 7b 0a 20 20 20 20 63 61 73 65 20  ch(N){.    case 
6aa0: 33 3a 20 20 20 73 75 6d 33 20 2b 3d 20 28 7a 5b  3:   sum3 += (z[
6ab0: 32 5d 20 3c 3c 20 38 29 3b 0a 20 20 20 20 63 61  2] << 8);.    ca
6ac0: 73 65 20 32 3a 20 20 20 73 75 6d 33 20 2b 3d 20  se 2:   sum3 += 
6ad0: 28 7a 5b 31 5d 20 3c 3c 20 31 36 29 3b 0a 20 20  (z[1] << 16);.  
6ae0: 20 20 63 61 73 65 20 31 3a 20 20 20 73 75 6d 33    case 1:   sum3
6af0: 20 2b 3d 20 28 7a 5b 30 5d 20 3c 3c 20 32 34 29   += (z[0] << 24)
6b00: 3b 0a 20 20 20 20 64 65 66 61 75 6c 74 3a 20 20  ;.    default:  
6b10: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73  ;.  }.  return s
6b20: 75 6d 33 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72  um3;.}../*.** Cr
6b30: 65 61 74 65 20 61 20 6e 65 77 20 64 65 6c 74 61  eate a new delta
6b40: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 64 65 6c 74  ..**.** The delt
6b50: 61 20 69 73 20 77 72 69 74 74 65 6e 20 69 6e 74  a is written int
6b60: 6f 20 61 20 70 72 65 61 6c 6c 6f 63 61 74 65 64  o a preallocated
6b70: 20 62 75 66 66 65 72 2c 20 7a 44 65 6c 74 61 2c   buffer, zDelta,
6b80: 20 77 68 69 63 68 0a 2a 2a 20 73 68 6f 75 6c 64   which.** should
6b90: 20 62 65 20 61 74 20 6c 65 61 73 74 20 36 30 20   be at least 60 
6ba0: 62 79 74 65 73 20 6c 6f 6e 67 65 72 20 74 68 61  bytes longer tha
6bb0: 6e 20 74 68 65 20 74 61 72 67 65 74 20 66 69 6c  n the target fil
6bc0: 65 2c 20 7a 4f 75 74 2e 0a 2a 2a 20 54 68 65 20  e, zOut..** The 
6bd0: 64 65 6c 74 61 20 73 74 72 69 6e 67 20 77 69 6c  delta string wil
6be0: 6c 20 62 65 20 4e 55 4c 2d 74 65 72 6d 69 6e 61  l be NUL-termina
6bf0: 74 65 64 2c 20 62 75 74 20 69 74 20 6d 69 67 68  ted, but it migh
6c00: 74 20 61 6c 73 6f 20 63 6f 6e 74 61 69 6e 0a 2a  t also contain.*
6c10: 2a 20 65 6d 62 65 64 64 65 64 20 4e 55 4c 20 63  * embedded NUL c
6c20: 68 61 72 61 63 74 65 72 73 20 69 66 20 65 69 74  haracters if eit
6c30: 68 65 72 20 74 68 65 20 7a 53 72 63 20 6f 72 20  her the zSrc or 
6c40: 7a 4f 75 74 20 66 69 6c 65 73 20 61 72 65 0a 2a  zOut files are.*
6c50: 2a 20 62 69 6e 61 72 79 2e 20 20 54 68 69 73 20  * binary.  This 
6c60: 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73  function returns
6c70: 20 74 68 65 20 6c 65 6e 67 74 68 20 6f 66 20 74   the length of t
6c80: 68 65 20 64 65 6c 74 61 20 73 74 72 69 6e 67 0a  he delta string.
6c90: 2a 2a 20 69 6e 20 62 79 74 65 73 2c 20 65 78 63  ** in bytes, exc
6ca0: 6c 75 64 69 6e 67 20 74 68 65 20 66 69 6e 61 6c  luding the final
6cb0: 20 4e 55 4c 20 74 65 72 6d 69 6e 61 74 6f 72 20   NUL terminator 
6cc0: 63 68 61 72 61 63 74 65 72 2e 0a 2a 2a 0a 2a 2a  character..**.**
6cd0: 20 4f 75 74 70 75 74 20 46 6f 72 6d 61 74 3a 0a   Output Format:.
6ce0: 2a 2a 0a 2a 2a 20 54 68 65 20 64 65 6c 74 61 20  **.** The delta 
6cf0: 62 65 67 69 6e 73 20 77 69 74 68 20 61 20 62 61  begins with a ba
6d00: 73 65 36 34 20 6e 75 6d 62 65 72 20 66 6f 6c 6c  se64 number foll
6d10: 6f 77 65 64 20 62 79 20 61 20 6e 65 77 6c 69 6e  owed by a newlin
6d20: 65 2e 20 20 54 68 69 73 0a 2a 2a 20 6e 75 6d 62  e.  This.** numb
6d30: 65 72 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72  er is the number
6d40: 20 6f 66 20 62 79 74 65 73 20 69 6e 20 74 68 65   of bytes in the
6d50: 20 54 41 52 47 45 54 20 66 69 6c 65 2e 20 20 54   TARGET file.  T
6d60: 68 75 73 2c 20 67 69 76 65 6e 20 61 0a 2a 2a 20  hus, given a.** 
6d70: 64 65 6c 74 61 20 66 69 6c 65 20 7a 2c 20 61 20  delta file z, a 
6d80: 70 72 6f 67 72 61 6d 20 63 61 6e 20 63 6f 6d 70  program can comp
6d90: 75 74 65 20 74 68 65 20 73 69 7a 65 20 6f 66 20  ute the size of 
6da0: 74 68 65 20 6f 75 74 70 75 74 20 66 69 6c 65 0a  the output file.
6db0: 2a 2a 20 73 69 6d 70 6c 79 20 62 79 20 72 65 61  ** simply by rea
6dc0: 64 69 6e 67 20 74 68 65 20 66 69 72 73 74 20 6c  ding the first l
6dd0: 69 6e 65 20 61 6e 64 20 64 65 63 6f 64 69 6e 67  ine and decoding
6de0: 20 74 68 65 20 62 61 73 65 2d 36 34 20 6e 75 6d   the base-64 num
6df0: 62 65 72 0a 2a 2a 20 66 6f 75 6e 64 20 74 68 65  ber.** found the
6e00: 72 65 2e 20 20 54 68 65 20 64 65 6c 74 61 5f 6f  re.  The delta_o
6e10: 75 74 70 75 74 5f 73 69 7a 65 28 29 20 72 6f 75  utput_size() rou
6e20: 74 69 6e 65 20 64 6f 65 73 20 65 78 61 63 74 6c  tine does exactl
6e30: 79 20 74 68 69 73 2e 0a 2a 2a 0a 2a 2a 20 41 66  y this..**.** Af
6e40: 74 65 72 20 74 68 65 20 69 6e 69 74 69 61 6c 20  ter the initial 
6e50: 73 69 7a 65 20 6e 75 6d 62 65 72 2c 20 74 68 65  size number, the
6e60: 20 64 65 6c 74 61 20 63 6f 6e 73 69 73 74 73 20   delta consists 
6e70: 6f 66 20 61 20 73 65 72 69 65 73 20 6f 66 0a 2a  of a series of.*
6e80: 2a 20 6c 69 74 65 72 61 6c 20 74 65 78 74 20 73  * literal text s
6e90: 65 67 6d 65 6e 74 73 20 61 6e 64 20 63 6f 6d 6d  egments and comm
6ea0: 61 6e 64 73 20 74 6f 20 63 6f 70 79 20 66 72 6f  ands to copy fro
6eb0: 6d 20 74 68 65 20 53 4f 55 52 43 45 20 66 69 6c  m the SOURCE fil
6ec0: 65 2e 0a 2a 2a 20 41 20 63 6f 70 79 20 63 6f 6d  e..** A copy com
6ed0: 6d 61 6e 64 20 6c 6f 6f 6b 73 20 6c 69 6b 65 20  mand looks like 
6ee0: 74 68 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  this:.**.**     
6ef0: 4e 4e 4e 40 4d 4d 4d 2c 0a 2a 2a 0a 2a 2a 20 77  NNN@MMM,.**.** w
6f00: 68 65 72 65 20 4e 4e 4e 20 69 73 20 74 68 65 20  here NNN is the 
6f10: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
6f20: 74 6f 20 62 65 20 63 6f 70 69 65 64 20 61 6e 64  to be copied and
6f30: 20 4d 4d 4d 20 69 73 20 74 68 65 20 6f 66 66 73   MMM is the offs
6f40: 65 74 0a 2a 2a 20 69 6e 74 6f 20 74 68 65 20 73  et.** into the s
6f50: 6f 75 72 63 65 20 66 69 6c 65 20 6f 66 20 74 68  ource file of th
6f60: 65 20 66 69 72 73 74 20 62 79 74 65 20 28 62 6f  e first byte (bo
6f70: 74 68 20 62 61 73 65 2d 36 34 29 2e 20 20 20 49  th base-64).   I
6f80: 66 20 4e 4e 4e 20 69 73 20 30 0a 2a 2a 20 69 74  f NNN is 0.** it
6f90: 20 6d 65 61 6e 73 20 63 6f 70 79 20 74 68 65 20   means copy the 
6fa0: 72 65 73 74 20 6f 66 20 74 68 65 20 69 6e 70 75  rest of the inpu
6fb0: 74 20 66 69 6c 65 2e 20 20 4c 69 74 65 72 61 6c  t file.  Literal
6fc0: 20 74 65 78 74 20 69 73 20 6c 69 6b 65 20 74 68   text is like th
6fd0: 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 4e 4e  is:.**.**     NN
6fe0: 4e 3a 54 54 54 54 54 0a 2a 2a 0a 2a 2a 20 77 68  N:TTTTT.**.** wh
6ff0: 65 72 65 20 4e 4e 4e 20 69 73 20 74 68 65 20 6e  ere NNN is the n
7000: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f  umber of bytes o
7010: 66 20 74 65 78 74 20 28 62 61 73 65 2d 36 34 29  f text (base-64)
7020: 20 61 6e 64 20 54 54 54 54 54 20 69 73 20 74 68   and TTTTT is th
7030: 65 20 74 65 78 74 2e 0a 2a 2a 0a 2a 2a 20 54 68  e text..**.** Th
7040: 65 20 6c 61 73 74 20 74 65 72 6d 20 69 73 20 6f  e last term is o
7050: 66 20 74 68 65 20 66 6f 72 6d 0a 2a 2a 0a 2a 2a  f the form.**.**
7060: 20 20 20 20 20 4e 4e 4e 3b 0a 2a 2a 0a 2a 2a 20       NNN;.**.** 
7070: 49 6e 20 74 68 69 73 20 63 61 73 65 2c 20 4e 4e  In this case, NN
7080: 4e 20 69 73 20 61 20 33 32 2d 62 69 74 20 62 69  N is a 32-bit bi
7090: 67 65 6e 64 69 61 6e 20 63 68 65 63 6b 73 75 6d  gendian checksum
70a0: 20 6f 66 20 74 68 65 20 6f 75 74 70 75 74 20 66   of the output f
70b0: 69 6c 65 0a 2a 2a 20 74 68 61 74 20 63 61 6e 20  ile.** that can 
70c0: 62 65 20 75 73 65 64 20 74 6f 20 76 65 72 69 66  be used to verif
70d0: 79 20 74 68 61 74 20 74 68 65 20 64 65 6c 74 61  y that the delta
70e0: 20 61 70 70 6c 69 65 64 20 63 6f 72 72 65 63 74   applied correct
70f0: 6c 79 2e 20 20 41 6c 6c 0a 2a 2a 20 6e 75 6d 62  ly.  All.** numb
7100: 65 72 73 20 61 72 65 20 69 6e 20 62 61 73 65 2d  ers are in base-
7110: 36 34 2e 0a 2a 2a 0a 2a 2a 20 50 75 72 65 20 74  64..**.** Pure t
7120: 65 78 74 20 66 69 6c 65 73 20 67 65 6e 65 72 61  ext files genera
7130: 74 65 20 61 20 70 75 72 65 20 74 65 78 74 20 64  te a pure text d
7140: 65 6c 74 61 2e 20 20 42 69 6e 61 72 79 20 66 69  elta.  Binary fi
7150: 6c 65 73 20 67 65 6e 65 72 61 74 65 20 61 0a 2a  les generate a.*
7160: 2a 20 64 65 6c 74 61 20 74 68 61 74 20 6d 61 79  * delta that may
7170: 20 63 6f 6e 74 61 69 6e 20 73 6f 6d 65 20 62 69   contain some bi
7180: 6e 61 72 79 20 64 61 74 61 2e 0a 2a 2a 0a 2a 2a  nary data..**.**
7190: 20 41 6c 67 6f 72 69 74 68 6d 3a 0a 2a 2a 0a 2a   Algorithm:.**.*
71a0: 2a 20 54 68 65 20 65 6e 63 6f 64 65 72 20 66 69  * The encoder fi
71b0: 72 73 74 20 62 75 69 6c 64 73 20 61 20 68 61 73  rst builds a has
71c0: 68 20 74 61 62 6c 65 20 74 6f 20 68 65 6c 70 20  h table to help 
71d0: 69 74 20 66 69 6e 64 20 6d 61 74 63 68 69 6e 67  it find matching
71e0: 0a 2a 2a 20 70 61 74 74 65 72 6e 73 20 69 6e 20  .** patterns in 
71f0: 74 68 65 20 73 6f 75 72 63 65 20 66 69 6c 65 2e  the source file.
7200: 20 20 31 36 2d 62 79 74 65 20 63 68 75 6e 6b 73    16-byte chunks
7210: 20 6f 66 20 74 68 65 20 73 6f 75 72 63 65 20 66   of the source f
7220: 69 6c 65 0a 2a 2a 20 73 61 6d 70 6c 65 64 20 61  ile.** sampled a
7230: 74 20 65 76 65 6e 6c 79 20 73 70 61 63 65 64 20  t evenly spaced 
7240: 69 6e 74 65 72 76 61 6c 73 20 61 72 65 20 75 73  intervals are us
7250: 65 64 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 74  ed to populate t
7260: 68 65 20 68 61 73 68 0a 2a 2a 20 74 61 62 6c 65  he hash.** table
7270: 2e 0a 2a 2a 0a 2a 2a 20 4e 65 78 74 20 77 65 20  ..**.** Next we 
7280: 62 65 67 69 6e 20 73 63 61 6e 6e 69 6e 67 20 74  begin scanning t
7290: 68 65 20 74 61 72 67 65 74 20 66 69 6c 65 20 75  he target file u
72a0: 73 69 6e 67 20 61 20 73 6c 69 64 69 6e 67 20 31  sing a sliding 1
72b0: 36 2d 62 79 74 65 0a 2a 2a 20 77 69 6e 64 6f 77  6-byte.** window
72c0: 2e 20 20 54 68 65 20 68 61 73 68 20 6f 66 20 74  .  The hash of t
72d0: 68 65 20 31 36 2d 62 79 74 65 20 77 69 6e 64 6f  he 16-byte windo
72e0: 77 20 69 6e 20 74 68 65 20 74 61 72 67 65 74 20  w in the target 
72f0: 69 73 20 75 73 65 64 20 74 6f 0a 2a 2a 20 73 65  is used to.** se
7300: 61 72 63 68 20 66 6f 72 20 61 20 6d 61 74 63 68  arch for a match
7310: 69 6e 67 20 73 65 63 74 69 6f 6e 20 69 6e 20 74  ing section in t
7320: 68 65 20 73 6f 75 72 63 65 20 66 69 6c 65 2e 20  he source file. 
7330: 20 57 68 65 6e 20 61 20 6d 61 74 63 68 0a 2a 2a   When a match.**
7340: 20 69 73 20 66 6f 75 6e 64 2c 20 61 20 63 6f 70   is found, a cop
7350: 79 20 63 6f 6d 6d 61 6e 64 20 69 73 20 61 64 64  y command is add
7360: 65 64 20 74 6f 20 74 68 65 20 64 65 6c 74 61 2e  ed to the delta.
7370: 20 20 41 6e 20 65 66 66 6f 72 74 20 69 73 0a 2a    An effort is.*
7380: 2a 20 6d 61 64 65 20 74 6f 20 65 78 74 65 6e 64  * made to extend
7390: 20 74 68 65 20 6d 61 74 63 68 69 6e 67 20 73 65   the matching se
73a0: 63 74 69 6f 6e 20 74 6f 20 72 65 67 69 6f 6e 73  ction to regions
73b0: 20 74 68 61 74 20 63 6f 6d 65 20 62 65 66 6f 72   that come befor
73c0: 65 0a 2a 2a 20 61 6e 64 20 61 66 74 65 72 20 74  e.** and after t
73d0: 68 65 20 31 36 2d 62 79 74 65 20 68 61 73 68 20  he 16-byte hash 
73e0: 77 69 6e 64 6f 77 2e 20 20 41 20 63 6f 70 79 20  window.  A copy 
73f0: 63 6f 6d 6d 61 6e 64 20 69 73 20 6f 6e 6c 79 20  command is only 
7400: 69 73 73 75 65 64 0a 2a 2a 20 69 66 20 74 68 65  issued.** if the
7410: 20 72 65 73 75 6c 74 20 77 6f 75 6c 64 20 75 73   result would us
7420: 65 20 6c 65 73 73 20 73 70 61 63 65 20 74 68 61  e less space tha
7430: 74 20 6a 75 73 74 20 71 75 6f 74 69 6e 67 20 74  t just quoting t
7440: 68 65 20 74 65 78 74 0a 2a 2a 20 6c 69 74 65 72  he text.** liter
7450: 61 6c 6c 79 2e 20 4c 69 74 65 72 61 6c 20 74 65  ally. Literal te
7460: 78 74 20 69 73 20 61 64 64 65 64 20 74 6f 20 74  xt is added to t
7470: 68 65 20 64 65 6c 74 61 20 66 6f 72 20 73 65 63  he delta for sec
7480: 74 69 6f 6e 73 20 74 68 61 74 0a 2a 2a 20 64 6f  tions that.** do
7490: 20 6e 6f 74 20 6d 61 74 63 68 20 6f 72 20 77 68   not match or wh
74a0: 69 63 68 20 63 61 6e 20 6e 6f 74 20 62 65 20 65  ich can not be e
74b0: 6e 63 6f 64 65 64 20 65 66 66 69 63 69 65 6e 74  ncoded efficient
74c0: 6c 79 20 75 73 69 6e 67 20 63 6f 70 79 0a 2a 2a  ly using copy.**
74d0: 20 63 6f 6d 6d 61 6e 64 73 2e 0a 2a 2f 0a 73 74   commands..*/.st
74e0: 61 74 69 63 20 69 6e 74 20 72 62 75 44 65 6c 74  atic int rbuDelt
74f0: 61 43 72 65 61 74 65 28 0a 20 20 63 6f 6e 73 74  aCreate(.  const
7500: 20 63 68 61 72 20 2a 7a 53 72 63 2c 20 20 20 20   char *zSrc,    
7510: 20 20 2f 2a 20 54 68 65 20 73 6f 75 72 63 65 20    /* The source 
7520: 6f 72 20 70 61 74 74 65 72 6e 20 66 69 6c 65 20  or pattern file 
7530: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
7540: 74 20 6c 65 6e 53 72 63 2c 20 20 20 2f 2a 20 4c  t lenSrc,   /* L
7550: 65 6e 67 74 68 20 6f 66 20 74 68 65 20 73 6f 75  ength of the sou
7560: 72 63 65 20 66 69 6c 65 20 2a 2f 0a 20 20 63 6f  rce file */.  co
7570: 6e 73 74 20 63 68 61 72 20 2a 7a 4f 75 74 2c 20  nst char *zOut, 
7580: 20 20 20 20 20 2f 2a 20 54 68 65 20 74 61 72 67       /* The targ
7590: 65 74 20 66 69 6c 65 20 2a 2f 0a 20 20 75 6e 73  et file */.  uns
75a0: 69 67 6e 65 64 20 69 6e 74 20 6c 65 6e 4f 75 74  igned int lenOut
75b0: 2c 20 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66  ,   /* Length of
75c0: 20 74 68 65 20 74 61 72 67 65 74 20 66 69 6c 65   the target file
75d0: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 44 65 6c   */.  char *zDel
75e0: 74 61 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ta           /* 
75f0: 57 72 69 74 65 20 74 68 65 20 64 65 6c 74 61 20  Write the delta 
7600: 69 6e 74 6f 20 74 68 69 73 20 62 75 66 66 65 72  into this buffer
7610: 20 2a 2f 0a 29 7b 0a 20 20 75 6e 73 69 67 6e 65   */.){.  unsigne
7620: 64 20 69 6e 74 20 69 2c 20 62 61 73 65 3b 0a 20  d int i, base;. 
7630: 20 63 68 61 72 20 2a 7a 4f 72 69 67 44 65 6c 74   char *zOrigDelt
7640: 61 20 3d 20 7a 44 65 6c 74 61 3b 0a 20 20 68 61  a = zDelta;.  ha
7650: 73 68 20 68 3b 0a 20 20 69 6e 74 20 6e 48 61 73  sh h;.  int nHas
7660: 68 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  h;              
7670: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
7680: 68 61 73 68 20 74 61 62 6c 65 20 65 6e 74 72 69  hash table entri
7690: 65 73 20 2a 2f 0a 20 20 69 6e 74 20 2a 6c 61 6e  es */.  int *lan
76a0: 64 6d 61 72 6b 3b 20 20 20 20 20 20 20 20 20 20  dmark;          
76b0: 20 20 20 2f 2a 20 50 72 69 6d 61 72 79 20 68 61     /* Primary ha
76c0: 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e  sh table */.  in
76d0: 74 20 2a 63 6f 6c 6c 69 64 65 3b 20 20 20 20 20  t *collide;     
76e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6c 6c           /* Coll
76f0: 69 73 69 6f 6e 20 63 68 61 69 6e 20 2a 2f 0a 20  ision chain */. 
7700: 20 69 6e 74 20 6c 61 73 74 52 65 61 64 20 3d 20   int lastRead = 
7710: 2d 31 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 4c  -1;         /* L
7720: 61 73 74 20 62 79 74 65 20 6f 66 20 7a 53 72 63  ast byte of zSrc
7730: 20 72 65 61 64 20 62 79 20 61 20 43 4f 50 59 20   read by a COPY 
7740: 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 0a 20 20 2f 2a  command */..  /*
7750: 20 41 64 64 20 74 68 65 20 74 61 72 67 65 74 20   Add the target 
7760: 66 69 6c 65 20 73 69 7a 65 20 74 6f 20 74 68 65  file size to the
7770: 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20 74 68   beginning of th
7780: 65 20 64 65 6c 74 61 0a 20 20 2a 2f 0a 20 20 70  e delta.  */.  p
7790: 75 74 49 6e 74 28 6c 65 6e 4f 75 74 2c 20 26 7a  utInt(lenOut, &z
77a0: 44 65 6c 74 61 29 3b 0a 20 20 2a 28 7a 44 65 6c  Delta);.  *(zDel
77b0: 74 61 2b 2b 29 20 3d 20 27 5c 6e 27 3b 0a 0a 20  ta++) = '\n';.. 
77c0: 20 2f 2a 20 49 66 20 74 68 65 20 73 6f 75 72 63   /* If the sourc
77d0: 65 20 66 69 6c 65 20 69 73 20 76 65 72 79 20 73  e file is very s
77e0: 6d 61 6c 6c 2c 20 69 74 20 6d 65 61 6e 73 20 74  mall, it means t
77f0: 68 61 74 20 77 65 20 68 61 76 65 20 6e 6f 0a 20  hat we have no. 
7800: 20 2a 2a 20 63 68 61 6e 63 65 20 6f 66 20 65 76   ** chance of ev
7810: 65 72 20 64 6f 69 6e 67 20 61 20 63 6f 70 79 20  er doing a copy 
7820: 63 6f 6d 6d 61 6e 64 2e 20 20 4a 75 73 74 20 6f  command.  Just o
7830: 75 74 70 75 74 20 61 20 73 69 6e 67 6c 65 0a 20  utput a single. 
7840: 20 2a 2a 20 6c 69 74 65 72 61 6c 20 73 65 67 6d   ** literal segm
7850: 65 6e 74 20 66 6f 72 20 74 68 65 20 65 6e 74 69  ent for the enti
7860: 72 65 20 74 61 72 67 65 74 20 61 6e 64 20 65 78  re target and ex
7870: 69 74 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 6c  it..  */.  if( l
7880: 65 6e 53 72 63 3c 3d 4e 48 41 53 48 20 29 7b 0a  enSrc<=NHASH ){.
7890: 20 20 20 20 70 75 74 49 6e 74 28 6c 65 6e 4f 75      putInt(lenOu
78a0: 74 2c 20 26 7a 44 65 6c 74 61 29 3b 0a 20 20 20  t, &zDelta);.   
78b0: 20 2a 28 7a 44 65 6c 74 61 2b 2b 29 20 3d 20 27   *(zDelta++) = '
78c0: 3a 27 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 7a  :';.    memcpy(z
78d0: 44 65 6c 74 61 2c 20 7a 4f 75 74 2c 20 6c 65 6e  Delta, zOut, len
78e0: 4f 75 74 29 3b 0a 20 20 20 20 7a 44 65 6c 74 61  Out);.    zDelta
78f0: 20 2b 3d 20 6c 65 6e 4f 75 74 3b 0a 20 20 20 20   += lenOut;.    
7900: 70 75 74 49 6e 74 28 63 68 65 63 6b 73 75 6d 28  putInt(checksum(
7910: 7a 4f 75 74 2c 20 6c 65 6e 4f 75 74 29 2c 20 26  zOut, lenOut), &
7920: 7a 44 65 6c 74 61 29 3b 0a 20 20 20 20 2a 28 7a  zDelta);.    *(z
7930: 44 65 6c 74 61 2b 2b 29 20 3d 20 27 3b 27 3b 0a  Delta++) = ';';.
7940: 20 20 20 20 72 65 74 75 72 6e 20 28 69 6e 74 29      return (int)
7950: 28 7a 44 65 6c 74 61 20 2d 20 7a 4f 72 69 67 44  (zDelta - zOrigD
7960: 65 6c 74 61 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  elta);.  }..  /*
7970: 20 43 6f 6d 70 75 74 65 20 74 68 65 20 68 61 73   Compute the has
7980: 68 20 74 61 62 6c 65 20 75 73 65 64 20 74 6f 20  h table used to 
7990: 6c 6f 63 61 74 65 20 6d 61 74 63 68 69 6e 67 20  locate matching 
79a0: 73 65 63 74 69 6f 6e 73 20 69 6e 20 74 68 65 0a  sections in the.
79b0: 20 20 2a 2a 20 73 6f 75 72 63 65 20 66 69 6c 65    ** source file
79c0: 2e 0a 20 20 2a 2f 0a 20 20 6e 48 61 73 68 20 3d  ..  */.  nHash =
79d0: 20 6c 65 6e 53 72 63 2f 4e 48 41 53 48 3b 0a 20   lenSrc/NHASH;. 
79e0: 20 63 6f 6c 6c 69 64 65 20 3d 20 73 71 6c 69 74   collide = sqlit
79f0: 65 33 5f 6d 61 6c 6c 6f 63 28 20 6e 48 61 73 68  e3_malloc( nHash
7a00: 2a 32 2a 73 69 7a 65 6f 66 28 69 6e 74 29 20 29  *2*sizeof(int) )
7a10: 3b 0a 20 20 6c 61 6e 64 6d 61 72 6b 20 3d 20 26  ;.  landmark = &
7a20: 63 6f 6c 6c 69 64 65 5b 6e 48 61 73 68 5d 3b 0a  collide[nHash];.
7a30: 20 20 6d 65 6d 73 65 74 28 6c 61 6e 64 6d 61 72    memset(landmar
7a40: 6b 2c 20 2d 31 2c 20 6e 48 61 73 68 2a 73 69 7a  k, -1, nHash*siz
7a50: 65 6f 66 28 69 6e 74 29 29 3b 0a 20 20 6d 65 6d  eof(int));.  mem
7a60: 73 65 74 28 63 6f 6c 6c 69 64 65 2c 20 2d 31 2c  set(collide, -1,
7a70: 20 6e 48 61 73 68 2a 73 69 7a 65 6f 66 28 69 6e   nHash*sizeof(in
7a80: 74 29 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  t));.  for(i=0; 
7a90: 69 3c 6c 65 6e 53 72 63 2d 4e 48 41 53 48 3b 20  i<lenSrc-NHASH; 
7aa0: 69 2b 3d 4e 48 41 53 48 29 7b 0a 20 20 20 20 69  i+=NHASH){.    i
7ab0: 6e 74 20 68 76 3b 0a 20 20 20 20 68 61 73 68 5f  nt hv;.    hash_
7ac0: 69 6e 69 74 28 26 68 2c 20 26 7a 53 72 63 5b 69  init(&h, &zSrc[i
7ad0: 5d 29 3b 0a 20 20 20 20 68 76 20 3d 20 68 61 73  ]);.    hv = has
7ae0: 68 5f 33 32 62 69 74 28 26 68 29 20 25 20 6e 48  h_32bit(&h) % nH
7af0: 61 73 68 3b 0a 20 20 20 20 63 6f 6c 6c 69 64 65  ash;.    collide
7b00: 5b 69 2f 4e 48 41 53 48 5d 20 3d 20 6c 61 6e 64  [i/NHASH] = land
7b10: 6d 61 72 6b 5b 68 76 5d 3b 0a 20 20 20 20 6c 61  mark[hv];.    la
7b20: 6e 64 6d 61 72 6b 5b 68 76 5d 20 3d 20 69 2f 4e  ndmark[hv] = i/N
7b30: 48 41 53 48 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  HASH;.  }..  /* 
7b40: 42 65 67 69 6e 20 73 63 61 6e 6e 69 6e 67 20 74  Begin scanning t
7b50: 68 65 20 74 61 72 67 65 74 20 66 69 6c 65 20 61  he target file a
7b60: 6e 64 20 67 65 6e 65 72 61 74 69 6e 67 20 63 6f  nd generating co
7b70: 70 79 20 63 6f 6d 6d 61 6e 64 73 20 61 6e 64 0a  py commands and.
7b80: 20 20 2a 2a 20 6c 69 74 65 72 61 6c 20 73 65 63    ** literal sec
7b90: 74 69 6f 6e 73 20 6f 66 20 74 68 65 20 64 65 6c  tions of the del
7ba0: 74 61 2e 0a 20 20 2a 2f 0a 20 20 62 61 73 65 20  ta..  */.  base 
7bb0: 3d 20 30 3b 20 20 20 20 2f 2a 20 57 65 20 68 61  = 0;    /* We ha
7bc0: 76 65 20 61 6c 72 65 61 64 79 20 67 65 6e 65 72  ve already gener
7bd0: 61 74 65 64 20 65 76 65 72 79 74 68 69 6e 67 20  ated everything 
7be0: 62 65 66 6f 72 65 20 7a 4f 75 74 5b 62 61 73 65  before zOut[base
7bf0: 5d 20 2a 2f 0a 20 20 77 68 69 6c 65 28 20 62 61  ] */.  while( ba
7c00: 73 65 2b 4e 48 41 53 48 3c 6c 65 6e 4f 75 74 20  se+NHASH<lenOut 
7c10: 29 7b 0a 20 20 20 20 69 6e 74 20 69 53 72 63 2c  ){.    int iSrc,
7c20: 20 69 42 6c 6f 63 6b 3b 0a 20 20 20 20 69 6e 74   iBlock;.    int
7c30: 20 62 65 73 74 43 6e 74 2c 20 62 65 73 74 4f 66   bestCnt, bestOf
7c40: 73 74 3d 30 2c 20 62 65 73 74 4c 69 74 73 7a 3d  st=0, bestLitsz=
7c50: 30 3b 0a 20 20 20 20 68 61 73 68 5f 69 6e 69 74  0;.    hash_init
7c60: 28 26 68 2c 20 26 7a 4f 75 74 5b 62 61 73 65 5d  (&h, &zOut[base]
7c70: 29 3b 0a 20 20 20 20 69 20 3d 20 30 3b 20 20 20  );.    i = 0;   
7c80: 20 20 2f 2a 20 54 72 79 69 6e 67 20 74 6f 20 6d    /* Trying to m
7c90: 61 74 63 68 20 61 20 6c 61 6e 64 6d 61 72 6b 20  atch a landmark 
7ca0: 61 67 61 69 6e 73 74 20 7a 4f 75 74 5b 62 61 73  against zOut[bas
7cb0: 65 2b 69 5d 20 2a 2f 0a 20 20 20 20 62 65 73 74  e+i] */.    best
7cc0: 43 6e 74 20 3d 20 30 3b 0a 20 20 20 20 77 68 69  Cnt = 0;.    whi
7cd0: 6c 65 28 20 31 20 29 7b 0a 20 20 20 20 20 20 69  le( 1 ){.      i
7ce0: 6e 74 20 68 76 3b 0a 20 20 20 20 20 20 69 6e 74  nt hv;.      int
7cf0: 20 6c 69 6d 69 74 20 3d 20 32 35 30 3b 0a 0a 20   limit = 250;.. 
7d00: 20 20 20 20 20 68 76 20 3d 20 68 61 73 68 5f 33       hv = hash_3
7d10: 32 62 69 74 28 26 68 29 20 25 20 6e 48 61 73 68  2bit(&h) % nHash
7d20: 3b 0a 20 20 20 20 20 20 69 42 6c 6f 63 6b 20 3d  ;.      iBlock =
7d30: 20 6c 61 6e 64 6d 61 72 6b 5b 68 76 5d 3b 0a 20   landmark[hv];. 
7d40: 20 20 20 20 20 77 68 69 6c 65 28 20 69 42 6c 6f       while( iBlo
7d50: 63 6b 3e 3d 30 20 26 26 20 28 6c 69 6d 69 74 2d  ck>=0 && (limit-
7d60: 2d 29 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20  -)>0 ){.        
7d70: 2f 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 54 68  /*.        ** Th
7d80: 65 20 68 61 73 68 20 77 69 6e 64 6f 77 20 68 61  e hash window ha
7d90: 73 20 69 64 65 6e 74 69 66 69 65 64 20 61 20 70  s identified a p
7da0: 6f 74 65 6e 74 69 61 6c 20 6d 61 74 63 68 20 61  otential match a
7db0: 67 61 69 6e 73 74 0a 20 20 20 20 20 20 20 20 2a  gainst.        *
7dc0: 2a 20 6c 61 6e 64 6d 61 72 6b 20 62 6c 6f 63 6b  * landmark block
7dd0: 20 69 42 6c 6f 63 6b 2e 20 20 42 75 74 20 77 65   iBlock.  But we
7de0: 20 6e 65 65 64 20 74 6f 20 69 6e 76 65 73 74 69   need to investi
7df0: 67 61 74 65 20 66 75 72 74 68 65 72 2e 0a 20 20  gate further..  
7e00: 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20        **.       
7e10: 20 2a 2a 20 4c 6f 6f 6b 20 66 6f 72 20 61 20 72   ** Look for a r
7e20: 65 67 69 6f 6e 20 69 6e 20 7a 4f 75 74 20 74 68  egion in zOut th
7e30: 61 74 20 6d 61 74 63 68 65 73 20 7a 53 72 63 2e  at matches zSrc.
7e40: 20 41 6e 63 68 6f 72 20 74 68 65 20 73 65 61 72   Anchor the sear
7e50: 63 68 0a 20 20 20 20 20 20 20 20 2a 2a 20 61 74  ch.        ** at
7e60: 20 7a 53 72 63 5b 69 53 72 63 5d 20 61 6e 64 20   zSrc[iSrc] and 
7e70: 7a 4f 75 74 5b 62 61 73 65 2b 69 5d 2e 20 20 44  zOut[base+i].  D
7e80: 6f 20 6e 6f 74 20 69 6e 63 6c 75 64 65 20 61 6e  o not include an
7e90: 79 74 68 69 6e 67 20 70 72 69 6f 72 20 74 6f 0a  ything prior to.
7ea0: 20 20 20 20 20 20 20 20 2a 2a 20 7a 4f 75 74 5b          ** zOut[
7eb0: 62 61 73 65 5d 20 6f 72 20 61 66 74 65 72 20 7a  base] or after z
7ec0: 4f 75 74 5b 6f 75 74 4c 65 6e 5d 20 6e 6f 72 20  Out[outLen] nor 
7ed0: 61 6e 79 74 68 69 6e 67 20 61 66 74 65 72 20 7a  anything after z
7ee0: 53 72 63 5b 73 72 63 4c 65 6e 5d 2e 0a 20 20 20  Src[srcLen]..   
7ef0: 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20       **.        
7f00: 2a 2a 20 53 65 74 20 63 6e 74 20 65 71 75 61 6c  ** Set cnt equal
7f10: 20 74 6f 20 74 68 65 20 6c 65 6e 67 74 68 20 6f   to the length o
7f20: 66 20 74 68 65 20 6d 61 74 63 68 20 61 6e 64 20  f the match and 
7f30: 73 65 74 20 6f 66 73 74 20 73 6f 20 74 68 61 74  set ofst so that
7f40: 0a 20 20 20 20 20 20 20 20 2a 2a 20 7a 53 72 63  .        ** zSrc
7f50: 5b 6f 66 73 74 5d 20 69 73 20 74 68 65 20 66 69  [ofst] is the fi
7f60: 72 73 74 20 65 6c 65 6d 65 6e 74 20 6f 66 20 74  rst element of t
7f70: 68 65 20 6d 61 74 63 68 2e 20 20 6c 69 74 73 7a  he match.  litsz
7f80: 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 0a 20   is the number. 
7f90: 20 20 20 20 20 20 20 2a 2a 20 6f 66 20 63 68 61         ** of cha
7fa0: 72 61 63 74 65 72 73 20 62 65 74 77 65 65 6e 20  racters between 
7fb0: 7a 4f 75 74 5b 62 61 73 65 5d 20 61 6e 64 20 74  zOut[base] and t
7fc0: 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20  he beginning of 
7fd0: 74 68 65 20 6d 61 74 63 68 2e 0a 20 20 20 20 20  the match..     
7fe0: 20 20 20 2a 2a 20 73 7a 20 77 69 6c 6c 20 62 65     ** sz will be
7ff0: 20 74 68 65 20 6f 76 65 72 68 65 61 64 20 28 69   the overhead (i
8000: 6e 20 62 79 74 65 73 29 20 6e 65 65 64 65 64 20  n bytes) needed 
8010: 74 6f 20 65 6e 63 6f 64 65 20 74 68 65 20 63 6f  to encode the co
8020: 70 79 0a 20 20 20 20 20 20 20 20 2a 2a 20 63 6f  py.        ** co
8030: 6d 6d 61 6e 64 2e 20 20 4f 6e 6c 79 20 67 65 6e  mmand.  Only gen
8040: 65 72 61 74 65 20 63 6f 70 79 20 63 6f 6d 6d 61  erate copy comma
8050: 6e 64 20 69 66 20 74 68 65 20 6f 76 65 72 68 65  nd if the overhe
8060: 61 64 20 6f 66 20 74 68 65 0a 20 20 20 20 20 20  ad of the.      
8070: 20 20 2a 2a 20 63 6f 70 79 20 63 6f 6d 6d 61 6e    ** copy comman
8080: 64 20 69 73 20 6c 65 73 73 20 74 68 61 6e 20 74  d is less than t
8090: 68 65 20 61 6d 6f 75 6e 74 20 6f 66 20 6c 69 74  he amount of lit
80a0: 65 72 61 6c 20 74 65 78 74 20 74 6f 20 62 65 20  eral text to be 
80b0: 63 6f 70 69 65 64 2e 0a 20 20 20 20 20 20 20 20  copied..        
80c0: 2a 2f 0a 20 20 20 20 20 20 20 20 69 6e 74 20 63  */.        int c
80d0: 6e 74 2c 20 6f 66 73 74 2c 20 6c 69 74 73 7a 3b  nt, ofst, litsz;
80e0: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6a 2c 20  .        int j, 
80f0: 6b 2c 20 78 2c 20 79 3b 0a 20 20 20 20 20 20 20  k, x, y;.       
8100: 20 69 6e 74 20 73 7a 3b 0a 0a 20 20 20 20 20 20   int sz;..      
8110: 20 20 2f 2a 20 42 65 67 69 6e 6e 69 6e 67 20 61    /* Beginning a
8120: 74 20 69 53 72 63 2c 20 6d 61 74 63 68 20 66 6f  t iSrc, match fo
8130: 72 77 61 72 64 73 20 61 73 20 66 61 72 20 61 73  rwards as far as
8140: 20 77 65 20 63 61 6e 2e 20 20 6a 20 63 6f 75 6e   we can.  j coun
8150: 74 73 0a 20 20 20 20 20 20 20 20 2a 2a 20 74 68  ts.        ** th
8160: 65 20 6e 75 6d 62 65 72 20 6f 66 20 63 68 61 72  e number of char
8170: 61 63 74 65 72 73 20 74 68 61 74 20 6d 61 74 63  acters that matc
8180: 68 20 2a 2f 0a 20 20 20 20 20 20 20 20 69 53 72  h */.        iSr
8190: 63 20 3d 20 69 42 6c 6f 63 6b 2a 4e 48 41 53 48  c = iBlock*NHASH
81a0: 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28 0a 20  ;.        for(. 
81b0: 20 20 20 20 20 20 20 20 20 6a 3d 30 2c 20 78 3d           j=0, x=
81c0: 69 53 72 63 2c 20 79 3d 62 61 73 65 2b 69 3b 0a  iSrc, y=base+i;.
81d0: 20 20 20 20 20 20 20 20 20 20 28 75 6e 73 69 67            (unsig
81e0: 6e 65 64 20 69 6e 74 29 78 3c 6c 65 6e 53 72 63  ned int)x<lenSrc
81f0: 20 26 26 20 28 75 6e 73 69 67 6e 65 64 20 69 6e   && (unsigned in
8200: 74 29 79 3c 6c 65 6e 4f 75 74 3b 0a 20 20 20 20  t)y<lenOut;.    
8210: 20 20 20 20 20 20 6a 2b 2b 2c 20 78 2b 2b 2c 20        j++, x++, 
8220: 79 2b 2b 0a 20 20 20 20 20 20 20 20 29 7b 0a 20  y++.        ){. 
8230: 20 20 20 20 20 20 20 20 20 69 66 28 20 7a 53 72           if( zSr
8240: 63 5b 78 5d 21 3d 7a 4f 75 74 5b 79 5d 20 29 20  c[x]!=zOut[y] ) 
8250: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d  break;.        }
8260: 0a 20 20 20 20 20 20 20 20 6a 2d 2d 3b 0a 0a 20  .        j--;.. 
8270: 20 20 20 20 20 20 20 2f 2a 20 42 65 67 69 6e 6e         /* Beginn
8280: 69 6e 67 20 61 74 20 69 53 72 63 2d 31 2c 20 6d  ing at iSrc-1, m
8290: 61 74 63 68 20 62 61 63 6b 77 61 72 64 73 20 61  atch backwards a
82a0: 73 20 66 61 72 20 61 73 20 77 65 20 63 61 6e 2e  s far as we can.
82b0: 20 20 6b 20 63 6f 75 6e 74 73 0a 20 20 20 20 20    k counts.     
82c0: 20 20 20 2a 2a 20 74 68 65 20 6e 75 6d 62 65 72     ** the number
82d0: 20 6f 66 20 63 68 61 72 61 63 74 65 72 73 20 74   of characters t
82e0: 68 61 74 20 6d 61 74 63 68 20 2a 2f 0a 20 20 20  hat match */.   
82f0: 20 20 20 20 20 66 6f 72 28 6b 3d 31 3b 20 6b 3c       for(k=1; k<
8300: 69 53 72 63 20 26 26 20 28 75 6e 73 69 67 6e 65  iSrc && (unsigne
8310: 64 20 69 6e 74 29 6b 3c 3d 69 3b 20 6b 2b 2b 29  d int)k<=i; k++)
8320: 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  {.          if( 
8330: 7a 53 72 63 5b 69 53 72 63 2d 6b 5d 21 3d 7a 4f  zSrc[iSrc-k]!=zO
8340: 75 74 5b 62 61 73 65 2b 69 2d 6b 5d 20 29 20 62  ut[base+i-k] ) b
8350: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a  reak;.        }.
8360: 20 20 20 20 20 20 20 20 6b 2d 2d 3b 0a 0a 20 20          k--;..  
8370: 20 20 20 20 20 20 2f 2a 20 43 6f 6d 70 75 74 65        /* Compute
8380: 20 74 68 65 20 6f 66 66 73 65 74 20 61 6e 64 20   the offset and 
8390: 73 69 7a 65 20 6f 66 20 74 68 65 20 6d 61 74 63  size of the matc
83a0: 68 69 6e 67 20 72 65 67 69 6f 6e 20 2a 2f 0a 20  hing region */. 
83b0: 20 20 20 20 20 20 20 6f 66 73 74 20 3d 20 69 53         ofst = iS
83c0: 72 63 2d 6b 3b 0a 20 20 20 20 20 20 20 20 63 6e  rc-k;.        cn
83d0: 74 20 3d 20 6a 2b 6b 2b 31 3b 0a 20 20 20 20 20  t = j+k+1;.     
83e0: 20 20 20 6c 69 74 73 7a 20 3d 20 69 2d 6b 3b 20     litsz = i-k; 
83f0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79   /* Number of by
8400: 74 65 73 20 6f 66 20 6c 69 74 65 72 61 6c 20 74  tes of literal t
8410: 65 78 74 20 62 65 66 6f 72 65 20 74 68 65 20 63  ext before the c
8420: 6f 70 79 20 2a 2f 0a 20 20 20 20 20 20 20 20 2f  opy */.        /
8430: 2a 20 73 7a 20 77 69 6c 6c 20 68 6f 6c 64 20 74  * sz will hold t
8440: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  he number of byt
8450: 65 73 20 6e 65 65 64 65 64 20 74 6f 20 65 6e 63  es needed to enc
8460: 6f 64 65 20 74 68 65 20 22 69 6e 73 65 72 74 22  ode the "insert"
8470: 0a 20 20 20 20 20 20 20 20 2a 2a 20 63 6f 6d 6d  .        ** comm
8480: 61 6e 64 20 61 6e 64 20 74 68 65 20 63 6f 70 79  and and the copy
8490: 20 63 6f 6d 6d 61 6e 64 2c 20 6e 6f 74 20 63 6f   command, not co
84a0: 75 6e 74 69 6e 67 20 74 68 65 20 22 69 6e 73 65  unting the "inse
84b0: 72 74 22 20 74 65 78 74 20 2a 2f 0a 20 20 20 20  rt" text */.    
84c0: 20 20 20 20 73 7a 20 3d 20 64 69 67 69 74 5f 63      sz = digit_c
84d0: 6f 75 6e 74 28 69 2d 6b 29 2b 64 69 67 69 74 5f  ount(i-k)+digit_
84e0: 63 6f 75 6e 74 28 63 6e 74 29 2b 64 69 67 69 74  count(cnt)+digit
84f0: 5f 63 6f 75 6e 74 28 6f 66 73 74 29 2b 33 3b 0a  _count(ofst)+3;.
8500: 20 20 20 20 20 20 20 20 69 66 28 20 63 6e 74 3e          if( cnt>
8510: 3d 73 7a 20 26 26 20 63 6e 74 3e 62 65 73 74 43  =sz && cnt>bestC
8520: 6e 74 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  nt ){.          
8530: 2f 2a 20 52 65 6d 65 6d 62 65 72 20 74 68 69 73  /* Remember this
8540: 20 6d 61 74 63 68 20 6f 6e 6c 79 20 69 66 20 69   match only if i
8550: 74 20 69 73 20 74 68 65 20 62 65 73 74 20 73 6f  t is the best so
8560: 20 66 61 72 20 61 6e 64 20 69 74 0a 20 20 20 20   far and it.    
8570: 20 20 20 20 20 20 2a 2a 20 64 6f 65 73 20 6e 6f        ** does no
8580: 74 20 69 6e 63 72 65 61 73 65 20 74 68 65 20 66  t increase the f
8590: 69 6c 65 20 73 69 7a 65 20 2a 2f 0a 20 20 20 20  ile size */.    
85a0: 20 20 20 20 20 20 62 65 73 74 43 6e 74 20 3d 20        bestCnt = 
85b0: 63 6e 74 3b 0a 20 20 20 20 20 20 20 20 20 20 62  cnt;.          b
85c0: 65 73 74 4f 66 73 74 20 3d 20 69 53 72 63 2d 6b  estOfst = iSrc-k
85d0: 3b 0a 20 20 20 20 20 20 20 20 20 20 62 65 73 74  ;.          best
85e0: 4c 69 74 73 7a 20 3d 20 6c 69 74 73 7a 3b 0a 20  Litsz = litsz;. 
85f0: 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20         }..      
8600: 20 20 2f 2a 20 43 68 65 63 6b 20 74 68 65 20 6e    /* Check the n
8610: 65 78 74 20 6d 61 74 63 68 69 6e 67 20 62 6c 6f  ext matching blo
8620: 63 6b 20 2a 2f 0a 20 20 20 20 20 20 20 20 69 42  ck */.        iB
8630: 6c 6f 63 6b 20 3d 20 63 6f 6c 6c 69 64 65 5b 69  lock = collide[i
8640: 42 6c 6f 63 6b 5d 3b 0a 20 20 20 20 20 20 7d 0a  Block];.      }.
8650: 0a 20 20 20 20 20 20 2f 2a 20 57 65 20 68 61 76  .      /* We hav
8660: 65 20 61 20 63 6f 70 79 20 63 6f 6d 6d 61 6e 64  e a copy command
8670: 20 74 68 61 74 20 64 6f 65 73 20 6e 6f 74 20 63   that does not c
8680: 61 75 73 65 20 74 68 65 20 64 65 6c 74 61 20 74  ause the delta t
8690: 6f 20 62 65 20 6c 61 72 67 65 72 0a 20 20 20 20  o be larger.    
86a0: 20 20 2a 2a 20 74 68 61 6e 20 61 20 6c 69 74 65    ** than a lite
86b0: 72 61 6c 20 69 6e 73 65 72 74 2e 20 20 53 6f 20  ral insert.  So 
86c0: 61 64 64 20 74 68 65 20 63 6f 70 79 20 63 6f 6d  add the copy com
86d0: 6d 61 6e 64 20 74 6f 20 74 68 65 20 64 65 6c 74  mand to the delt
86e0: 61 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20  a..      */.    
86f0: 20 20 69 66 28 20 62 65 73 74 43 6e 74 3e 30 20    if( bestCnt>0 
8700: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 62  ){.        if( b
8710: 65 73 74 4c 69 74 73 7a 3e 30 20 29 7b 0a 20 20  estLitsz>0 ){.  
8720: 20 20 20 20 20 20 20 20 2f 2a 20 41 64 64 20 61          /* Add a
8730: 6e 20 69 6e 73 65 72 74 20 63 6f 6d 6d 61 6e 64  n insert command
8740: 20 62 65 66 6f 72 65 20 74 68 65 20 63 6f 70 79   before the copy
8750: 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 70 75   */.          pu
8760: 74 49 6e 74 28 62 65 73 74 4c 69 74 73 7a 2c 26  tInt(bestLitsz,&
8770: 7a 44 65 6c 74 61 29 3b 0a 20 20 20 20 20 20 20  zDelta);.       
8780: 20 20 20 2a 28 7a 44 65 6c 74 61 2b 2b 29 20 3d     *(zDelta++) =
8790: 20 27 3a 27 3b 0a 20 20 20 20 20 20 20 20 20 20   ':';.          
87a0: 6d 65 6d 63 70 79 28 7a 44 65 6c 74 61 2c 20 26  memcpy(zDelta, &
87b0: 7a 4f 75 74 5b 62 61 73 65 5d 2c 20 62 65 73 74  zOut[base], best
87c0: 4c 69 74 73 7a 29 3b 0a 20 20 20 20 20 20 20 20  Litsz);.        
87d0: 20 20 7a 44 65 6c 74 61 20 2b 3d 20 62 65 73 74    zDelta += best
87e0: 4c 69 74 73 7a 3b 0a 20 20 20 20 20 20 20 20 20  Litsz;.         
87f0: 20 62 61 73 65 20 2b 3d 20 62 65 73 74 4c 69 74   base += bestLit
8800: 73 7a 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  sz;.        }.  
8810: 20 20 20 20 20 20 62 61 73 65 20 2b 3d 20 62 65        base += be
8820: 73 74 43 6e 74 3b 0a 20 20 20 20 20 20 20 20 70  stCnt;.        p
8830: 75 74 49 6e 74 28 62 65 73 74 43 6e 74 2c 20 26  utInt(bestCnt, &
8840: 7a 44 65 6c 74 61 29 3b 0a 20 20 20 20 20 20 20  zDelta);.       
8850: 20 2a 28 7a 44 65 6c 74 61 2b 2b 29 20 3d 20 27   *(zDelta++) = '
8860: 40 27 3b 0a 20 20 20 20 20 20 20 20 70 75 74 49  @';.        putI
8870: 6e 74 28 62 65 73 74 4f 66 73 74 2c 20 26 7a 44  nt(bestOfst, &zD
8880: 65 6c 74 61 29 3b 0a 20 20 20 20 20 20 20 20 2a  elta);.        *
8890: 28 7a 44 65 6c 74 61 2b 2b 29 20 3d 20 27 2c 27  (zDelta++) = ','
88a0: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 62 65  ;.        if( be
88b0: 73 74 4f 66 73 74 20 2b 20 62 65 73 74 43 6e 74  stOfst + bestCnt
88c0: 20 2d 31 20 3e 20 6c 61 73 74 52 65 61 64 20 29   -1 > lastRead )
88d0: 7b 0a 20 20 20 20 20 20 20 20 20 20 6c 61 73 74  {.          last
88e0: 52 65 61 64 20 3d 20 62 65 73 74 4f 66 73 74 20  Read = bestOfst 
88f0: 2b 20 62 65 73 74 43 6e 74 20 2d 20 31 3b 0a 20  + bestCnt - 1;. 
8900: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
8910: 20 62 65 73 74 43 6e 74 20 3d 20 30 3b 0a 20 20   bestCnt = 0;.  
8920: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
8930: 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 49     }..      /* I
8940: 66 20 77 65 20 72 65 61 63 68 20 74 68 69 73 20  f we reach this 
8950: 70 6f 69 6e 74 2c 20 69 74 20 6d 65 61 6e 73 20  point, it means 
8960: 6e 6f 20 6d 61 74 63 68 20 69 73 20 66 6f 75 6e  no match is foun
8970: 64 20 73 6f 20 66 61 72 20 2a 2f 0a 20 20 20 20  d so far */.    
8980: 20 20 69 66 28 20 62 61 73 65 2b 69 2b 4e 48 41    if( base+i+NHA
8990: 53 48 3e 3d 6c 65 6e 4f 75 74 20 29 7b 0a 20 20  SH>=lenOut ){.  
89a0: 20 20 20 20 20 20 2f 2a 20 57 65 20 68 61 76 65        /* We have
89b0: 20 72 65 61 63 68 65 64 20 74 68 65 20 65 6e 64   reached the end
89c0: 20 6f 66 20 74 68 65 20 66 69 6c 65 20 61 6e 64   of the file and
89d0: 20 68 61 76 65 20 6e 6f 74 20 66 6f 75 6e 64 20   have not found 
89e0: 61 6e 79 0a 20 20 20 20 20 20 20 20 2a 2a 20 6d  any.        ** m
89f0: 61 74 63 68 65 73 2e 20 20 44 6f 20 61 6e 20 22  atches.  Do an "
8a00: 69 6e 73 65 72 74 22 20 66 6f 72 20 65 76 65 72  insert" for ever
8a10: 79 74 68 69 6e 67 20 74 68 61 74 20 64 6f 65 73  ything that does
8a20: 20 6e 6f 74 20 6d 61 74 63 68 20 2a 2f 0a 20 20   not match */.  
8a30: 20 20 20 20 20 20 70 75 74 49 6e 74 28 6c 65 6e        putInt(len
8a40: 4f 75 74 2d 62 61 73 65 2c 20 26 7a 44 65 6c 74  Out-base, &zDelt
8a50: 61 29 3b 0a 20 20 20 20 20 20 20 20 2a 28 7a 44  a);.        *(zD
8a60: 65 6c 74 61 2b 2b 29 20 3d 20 27 3a 27 3b 0a 20  elta++) = ':';. 
8a70: 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 7a 44         memcpy(zD
8a80: 65 6c 74 61 2c 20 26 7a 4f 75 74 5b 62 61 73 65  elta, &zOut[base
8a90: 5d 2c 20 6c 65 6e 4f 75 74 2d 62 61 73 65 29 3b  ], lenOut-base);
8aa0: 0a 20 20 20 20 20 20 20 20 7a 44 65 6c 74 61 20  .        zDelta 
8ab0: 2b 3d 20 6c 65 6e 4f 75 74 2d 62 61 73 65 3b 0a  += lenOut-base;.
8ac0: 20 20 20 20 20 20 20 20 62 61 73 65 20 3d 20 6c          base = l
8ad0: 65 6e 4f 75 74 3b 0a 20 20 20 20 20 20 20 20 62  enOut;.        b
8ae0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20  reak;.      }.. 
8af0: 20 20 20 20 20 2f 2a 20 41 64 76 61 6e 63 65 20       /* Advance 
8b00: 74 68 65 20 68 61 73 68 20 62 79 20 6f 6e 65 20  the hash by one 
8b10: 63 68 61 72 61 63 74 65 72 2e 20 20 4b 65 65 70  character.  Keep
8b20: 20 6c 6f 6f 6b 69 6e 67 20 66 6f 72 20 61 20 6d   looking for a m
8b30: 61 74 63 68 20 2a 2f 0a 20 20 20 20 20 20 68 61  atch */.      ha
8b40: 73 68 5f 6e 65 78 74 28 26 68 2c 20 7a 4f 75 74  sh_next(&h, zOut
8b50: 5b 62 61 73 65 2b 69 2b 4e 48 41 53 48 5d 29 3b  [base+i+NHASH]);
8b60: 0a 20 20 20 20 20 20 69 2b 2b 3b 0a 20 20 20 20  .      i++;.    
8b70: 7d 0a 20 20 7d 0a 20 20 2f 2a 20 4f 75 74 70 75  }.  }.  /* Outpu
8b80: 74 20 61 20 66 69 6e 61 6c 20 22 69 6e 73 65 72  t a final "inser
8b90: 74 22 20 72 65 63 6f 72 64 20 74 6f 20 67 65 74  t" record to get
8ba0: 20 61 6c 6c 20 74 68 65 20 74 65 78 74 20 61 74   all the text at
8bb0: 20 74 68 65 20 65 6e 64 20 6f 66 0a 20 20 2a 2a   the end of.  **
8bc0: 20 74 68 65 20 66 69 6c 65 20 74 68 61 74 20 64   the file that d
8bd0: 6f 65 73 20 6e 6f 74 20 6d 61 74 63 68 20 61 6e  oes not match an
8be0: 79 74 68 69 6e 67 20 69 6e 20 74 68 65 20 73 6f  ything in the so
8bf0: 75 72 63 65 20 66 69 6c 65 2e 0a 20 20 2a 2f 0a  urce file..  */.
8c00: 20 20 69 66 28 20 62 61 73 65 3c 6c 65 6e 4f 75    if( base<lenOu
8c10: 74 20 29 7b 0a 20 20 20 20 70 75 74 49 6e 74 28  t ){.    putInt(
8c20: 6c 65 6e 4f 75 74 2d 62 61 73 65 2c 20 26 7a 44  lenOut-base, &zD
8c30: 65 6c 74 61 29 3b 0a 20 20 20 20 2a 28 7a 44 65  elta);.    *(zDe
8c40: 6c 74 61 2b 2b 29 20 3d 20 27 3a 27 3b 0a 20 20  lta++) = ':';.  
8c50: 20 20 6d 65 6d 63 70 79 28 7a 44 65 6c 74 61 2c    memcpy(zDelta,
8c60: 20 26 7a 4f 75 74 5b 62 61 73 65 5d 2c 20 6c 65   &zOut[base], le
8c70: 6e 4f 75 74 2d 62 61 73 65 29 3b 0a 20 20 20 20  nOut-base);.    
8c80: 7a 44 65 6c 74 61 20 2b 3d 20 6c 65 6e 4f 75 74  zDelta += lenOut
8c90: 2d 62 61 73 65 3b 0a 20 20 7d 0a 20 20 2f 2a 20  -base;.  }.  /* 
8ca0: 4f 75 74 70 75 74 20 74 68 65 20 66 69 6e 61 6c  Output the final
8cb0: 20 63 68 65 63 6b 73 75 6d 20 72 65 63 6f 72 64   checksum record
8cc0: 2e 20 2a 2f 0a 20 20 70 75 74 49 6e 74 28 63 68  . */.  putInt(ch
8cd0: 65 63 6b 73 75 6d 28 7a 4f 75 74 2c 20 6c 65 6e  ecksum(zOut, len
8ce0: 4f 75 74 29 2c 20 26 7a 44 65 6c 74 61 29 3b 0a  Out), &zDelta);.
8cf0: 20 20 2a 28 7a 44 65 6c 74 61 2b 2b 29 20 3d 20    *(zDelta++) = 
8d00: 27 3b 27 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  ';';.  sqlite3_f
8d10: 72 65 65 28 63 6f 6c 6c 69 64 65 29 3b 0a 20 20  ree(collide);.  
8d20: 72 65 74 75 72 6e 20 28 69 6e 74 29 28 7a 44 65  return (int)(zDe
8d30: 6c 74 61 20 2d 20 7a 4f 72 69 67 44 65 6c 74 61  lta - zOrigDelta
8d40: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 64 20  );.}../*.** End 
8d50: 6f 66 20 63 6f 64 65 20 63 6f 70 69 65 64 20 66  of code copied f
8d60: 72 6f 6d 20 66 6f 73 73 69 6c 2e 0a 2a 2a 2a 2a  rom fossil..****
8d70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8d80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8d90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8da0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8db0: 2a 2a 2a 2a 2a 2a 2f 0a 0a 73 74 61 74 69 63 20  ******/..static 
8dc0: 76 6f 69 64 20 73 74 72 50 72 69 6e 74 66 41 72  void strPrintfAr
8dd0: 72 61 79 28 0a 20 20 53 74 72 20 2a 70 53 74 72  ray(.  Str *pStr
8de0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8df0: 20 20 20 20 20 20 20 2f 2a 20 53 74 72 69 6e 67         /* String
8e00: 20 6f 62 6a 65 63 74 20 74 6f 20 61 70 70 65 6e   object to appen
8e10: 64 20 74 6f 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  d to */.  const 
8e20: 63 68 61 72 20 2a 7a 53 65 70 2c 20 20 20 20 20  char *zSep,     
8e30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 70            /* Sep
8e40: 61 72 61 74 6f 72 20 73 74 72 69 6e 67 20 2a 2f  arator string */
8e50: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
8e60: 46 6d 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  Fmt,            
8e70: 20 20 20 2f 2a 20 46 6f 72 6d 61 74 20 66 6f 72     /* Format for
8e80: 20 65 61 63 68 20 65 6e 74 72 79 20 2a 2f 0a 20   each entry */. 
8e90: 20 63 68 61 72 20 2a 2a 61 7a 2c 20 69 6e 74 20   char **az, int 
8ea0: 6e 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n               
8eb0: 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 73 74 72   /* Array of str
8ec0: 69 6e 67 73 20 26 20 69 74 73 20 73 69 7a 65 20  ings & its size 
8ed0: 28 6f 72 20 2d 31 29 20 2a 2f 0a 29 7b 0a 20 20  (or -1) */.){.  
8ee0: 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30  int i;.  for(i=0
8ef0: 3b 20 61 7a 5b 69 5d 20 26 26 20 28 69 3c 6e 20  ; az[i] && (i<n 
8f00: 7c 7c 20 6e 3c 30 29 3b 20 69 2b 2b 29 7b 0a 20  || n<0); i++){. 
8f10: 20 20 20 69 66 28 20 69 21 3d 30 20 29 20 73 74     if( i!=0 ) st
8f20: 72 50 72 69 6e 74 66 28 70 53 74 72 2c 20 22 25  rPrintf(pStr, "%
8f30: 73 22 2c 20 7a 53 65 70 29 3b 0a 20 20 20 20 73  s", zSep);.    s
8f40: 74 72 50 72 69 6e 74 66 28 70 53 74 72 2c 20 7a  trPrintf(pStr, z
8f50: 46 6d 74 2c 20 61 7a 5b 69 5d 2c 20 61 7a 5b 69  Fmt, az[i], az[i
8f60: 5d 2c 20 61 7a 5b 69 5d 29 3b 0a 20 20 7d 0a 7d  ], az[i]);.  }.}
8f70: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 67 65  ..static void ge
8f80: 74 52 62 75 64 69 66 66 51 75 65 72 79 28 0a 20  tRbudiffQuery(. 
8f90: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61   const char *zTa
8fa0: 62 2c 0a 20 20 63 68 61 72 20 2a 2a 61 7a 43 6f  b,.  char **azCo
8fb0: 6c 2c 0a 20 20 69 6e 74 20 6e 50 4b 2c 0a 20 20  l,.  int nPK,.  
8fc0: 69 6e 74 20 62 4f 74 61 52 6f 77 69 64 2c 0a 20  int bOtaRowid,. 
8fd0: 20 53 74 72 20 2a 70 53 71 6c 0a 29 7b 0a 20 20   Str *pSql.){.  
8fe0: 69 6e 74 20 69 3b 0a 0a 20 20 2f 2a 20 46 69 72  int i;..  /* Fir
8ff0: 73 74 20 74 68 65 20 6e 65 77 6c 79 20 69 6e 73  st the newly ins
9000: 65 72 74 65 64 20 72 6f 77 73 3a 20 2a 2a 2f 20  erted rows: **/ 
9010: 0a 20 20 73 74 72 50 72 69 6e 74 66 28 70 53 71  .  strPrintf(pSq
9020: 6c 2c 20 22 53 45 4c 45 43 54 20 22 29 3b 0a 20  l, "SELECT ");. 
9030: 20 73 74 72 50 72 69 6e 74 66 41 72 72 61 79 28   strPrintfArray(
9040: 70 53 71 6c 2c 20 22 2c 20 22 2c 20 22 25 73 22  pSql, ", ", "%s"
9050: 2c 20 61 7a 43 6f 6c 2c 20 2d 31 29 3b 0a 20 20  , azCol, -1);.  
9060: 73 74 72 50 72 69 6e 74 66 28 70 53 71 6c 2c 20  strPrintf(pSql, 
9070: 22 2c 20 30 2c 20 22 29 3b 20 20 20 20 20 20 20  ", 0, ");       
9080: 2f 2a 20 53 65 74 20 6f 74 61 5f 63 6f 6e 74 72  /* Set ota_contr
9090: 6f 6c 20 74 6f 20 30 20 66 6f 72 20 61 6e 20 69  ol to 0 for an i
90a0: 6e 73 65 72 74 20 2a 2f 0a 20 20 73 74 72 50 72  nsert */.  strPr
90b0: 69 6e 74 66 41 72 72 61 79 28 70 53 71 6c 2c 20  intfArray(pSql, 
90c0: 22 2c 20 22 2c 20 22 4e 55 4c 4c 22 2c 20 61 7a  ", ", "NULL", az
90d0: 43 6f 6c 2c 20 2d 31 29 3b 0a 20 20 73 74 72 50  Col, -1);.  strP
90e0: 72 69 6e 74 66 28 70 53 71 6c 2c 20 22 20 46 52  rintf(pSql, " FR
90f0: 4f 4d 20 61 75 78 2e 25 51 20 41 53 20 6e 20 57  OM aux.%Q AS n W
9100: 48 45 52 45 20 4e 4f 54 20 45 58 49 53 54 53 20  HERE NOT EXISTS 
9110: 28 5c 6e 22 2c 20 7a 54 61 62 29 3b 0a 20 20 73  (\n", zTab);.  s
9120: 74 72 50 72 69 6e 74 66 28 70 53 71 6c 2c 20 22  trPrintf(pSql, "
9130: 20 20 20 20 53 45 4c 45 43 54 20 31 20 46 52 4f      SELECT 1 FRO
9140: 4d 20 22 2c 20 7a 54 61 62 29 3b 0a 20 20 73 74  M ", zTab);.  st
9150: 72 50 72 69 6e 74 66 28 70 53 71 6c 2c 20 22 20  rPrintf(pSql, " 
9160: 6d 61 69 6e 2e 25 51 20 41 53 20 6f 20 57 48 45  main.%Q AS o WHE
9170: 52 45 20 22 2c 20 7a 54 61 62 29 3b 0a 20 20 73  RE ", zTab);.  s
9180: 74 72 50 72 69 6e 74 66 41 72 72 61 79 28 70 53  trPrintfArray(pS
9190: 71 6c 2c 20 22 20 41 4e 44 20 22 2c 20 22 28 6e  ql, " AND ", "(n
91a0: 2e 25 51 20 49 53 20 6f 2e 25 51 29 22 2c 20 61  .%Q IS o.%Q)", a
91b0: 7a 43 6f 6c 2c 20 6e 50 4b 29 3b 0a 20 20 73 74  zCol, nPK);.  st
91c0: 72 50 72 69 6e 74 66 28 70 53 71 6c 2c 20 22 5c  rPrintf(pSql, "\
91d0: 6e 29 22 29 3b 0a 0a 20 20 2f 2a 20 44 65 6c 65  n)");..  /* Dele
91e0: 74 65 64 20 72 6f 77 73 3a 20 2a 2f 0a 20 20 73  ted rows: */.  s
91f0: 74 72 50 72 69 6e 74 66 28 70 53 71 6c 2c 20 22  trPrintf(pSql, "
9200: 5c 6e 55 4e 49 4f 4e 20 41 4c 4c 5c 6e 53 45 4c  \nUNION ALL\nSEL
9210: 45 43 54 20 22 29 3b 0a 20 20 73 74 72 50 72 69  ECT ");.  strPri
9220: 6e 74 66 41 72 72 61 79 28 70 53 71 6c 2c 20 22  ntfArray(pSql, "
9230: 2c 20 22 2c 20 22 25 73 22 2c 20 61 7a 43 6f 6c  , ", "%s", azCol
9240: 2c 20 6e 50 4b 29 3b 0a 20 20 69 66 28 20 61 7a  , nPK);.  if( az
9250: 43 6f 6c 5b 6e 50 4b 5d 20 29 7b 0a 20 20 20 20  Col[nPK] ){.    
9260: 73 74 72 50 72 69 6e 74 66 28 70 53 71 6c 2c 20  strPrintf(pSql, 
9270: 22 2c 20 22 29 3b 0a 20 20 20 20 73 74 72 50 72  ", ");.    strPr
9280: 69 6e 74 66 41 72 72 61 79 28 70 53 71 6c 2c 20  intfArray(pSql, 
9290: 22 2c 20 22 2c 20 22 4e 55 4c 4c 22 2c 20 26 61  ", ", "NULL", &a
92a0: 7a 43 6f 6c 5b 6e 50 4b 5d 2c 20 2d 31 29 3b 0a  zCol[nPK], -1);.
92b0: 20 20 7d 0a 20 20 73 74 72 50 72 69 6e 74 66 28    }.  strPrintf(
92c0: 70 53 71 6c 2c 20 22 2c 20 31 2c 20 22 29 3b 20  pSql, ", 1, "); 
92d0: 20 20 20 20 20 20 2f 2a 20 53 65 74 20 6f 74 61        /* Set ota
92e0: 5f 63 6f 6e 74 72 6f 6c 20 74 6f 20 31 20 66 6f  _control to 1 fo
92f0: 72 20 61 20 64 65 6c 65 74 65 20 2a 2f 0a 20 20  r a delete */.  
9300: 73 74 72 50 72 69 6e 74 66 41 72 72 61 79 28 70  strPrintfArray(p
9310: 53 71 6c 2c 20 22 2c 20 22 2c 20 22 4e 55 4c 4c  Sql, ", ", "NULL
9320: 22 2c 20 61 7a 43 6f 6c 2c 20 2d 31 29 3b 0a 20  ", azCol, -1);. 
9330: 20 73 74 72 50 72 69 6e 74 66 28 70 53 71 6c 2c   strPrintf(pSql,
9340: 20 22 20 46 52 4f 4d 20 6d 61 69 6e 2e 25 51 20   " FROM main.%Q 
9350: 41 53 20 6e 20 57 48 45 52 45 20 4e 4f 54 20 45  AS n WHERE NOT E
9360: 58 49 53 54 53 20 28 5c 6e 22 2c 20 7a 54 61 62  XISTS (\n", zTab
9370: 29 3b 0a 20 20 73 74 72 50 72 69 6e 74 66 28 70  );.  strPrintf(p
9380: 53 71 6c 2c 20 22 20 20 20 20 53 45 4c 45 43 54  Sql, "    SELECT
9390: 20 31 20 46 52 4f 4d 20 22 2c 20 7a 54 61 62 29   1 FROM ", zTab)
93a0: 3b 0a 20 20 73 74 72 50 72 69 6e 74 66 28 70 53  ;.  strPrintf(pS
93b0: 71 6c 2c 20 22 20 61 75 78 2e 25 51 20 41 53 20  ql, " aux.%Q AS 
93c0: 6f 20 57 48 45 52 45 20 22 2c 20 7a 54 61 62 29  o WHERE ", zTab)
93d0: 3b 0a 20 20 73 74 72 50 72 69 6e 74 66 41 72 72  ;.  strPrintfArr
93e0: 61 79 28 70 53 71 6c 2c 20 22 20 41 4e 44 20 22  ay(pSql, " AND "
93f0: 2c 20 22 28 6e 2e 25 51 20 49 53 20 6f 2e 25 51  , "(n.%Q IS o.%Q
9400: 29 22 2c 20 61 7a 43 6f 6c 2c 20 6e 50 4b 29 3b  )", azCol, nPK);
9410: 0a 20 20 73 74 72 50 72 69 6e 74 66 28 70 53 71  .  strPrintf(pSq
9420: 6c 2c 20 22 5c 6e 29 20 22 29 3b 0a 0a 20 20 2f  l, "\n) ");..  /
9430: 2a 20 55 70 64 61 74 65 64 20 72 6f 77 73 2e 20  * Updated rows. 
9440: 49 66 20 61 6c 6c 20 74 61 62 6c 65 20 63 6f 6c  If all table col
9450: 75 6d 6e 73 20 61 72 65 20 70 61 72 74 20 6f 66  umns are part of
9460: 20 74 68 65 20 70 72 69 6d 61 72 79 20 6b 65 79   the primary key
9470: 2c 20 74 68 65 72 65 20 0a 20 20 2a 2a 20 63 61  , there .  ** ca
9480: 6e 20 62 65 20 6e 6f 20 75 70 64 61 74 65 73 2e  n be no updates.
9490: 20 49 6e 20 74 68 69 73 20 63 61 73 65 20 74 68   In this case th
94a0: 69 73 20 70 61 72 74 20 6f 66 20 74 68 65 20 63  is part of the c
94b0: 6f 6d 70 6f 75 6e 64 20 53 45 4c 45 43 54 20 63  ompound SELECT c
94c0: 61 6e 0a 20 20 2a 2a 20 62 65 20 6f 6d 69 74 74  an.  ** be omitt
94d0: 65 64 20 61 6c 74 6f 67 65 74 68 65 72 2e 20 2a  ed altogether. *
94e0: 2f 0a 20 20 69 66 28 20 61 7a 43 6f 6c 5b 6e 50  /.  if( azCol[nP
94f0: 4b 5d 20 29 7b 0a 20 20 20 20 73 74 72 50 72 69  K] ){.    strPri
9500: 6e 74 66 28 70 53 71 6c 2c 20 22 5c 6e 55 4e 49  ntf(pSql, "\nUNI
9510: 4f 4e 20 41 4c 4c 5c 6e 53 45 4c 45 43 54 20 22  ON ALL\nSELECT "
9520: 29 3b 0a 20 20 20 20 73 74 72 50 72 69 6e 74 66  );.    strPrintf
9530: 41 72 72 61 79 28 70 53 71 6c 2c 20 22 2c 20 22  Array(pSql, ", "
9540: 2c 20 22 6e 2e 25 73 22 2c 20 61 7a 43 6f 6c 2c  , "n.%s", azCol,
9550: 20 6e 50 4b 29 3b 0a 20 20 20 20 73 74 72 50 72   nPK);.    strPr
9560: 69 6e 74 66 28 70 53 71 6c 2c 20 22 2c 5c 6e 22  intf(pSql, ",\n"
9570: 29 3b 0a 20 20 20 20 73 74 72 50 72 69 6e 74 66  );.    strPrintf
9580: 41 72 72 61 79 28 70 53 71 6c 2c 20 22 20 2c 5c  Array(pSql, " ,\
9590: 6e 22 2c 20 0a 20 20 20 20 20 20 20 20 22 20 20  n", .        "  
95a0: 20 20 43 41 53 45 20 57 48 45 4e 20 6e 2e 25 73    CASE WHEN n.%s
95b0: 20 49 53 20 6f 2e 25 73 20 54 48 45 4e 20 4e 55   IS o.%s THEN NU
95c0: 4c 4c 20 45 4c 53 45 20 6e 2e 25 73 20 45 4e 44  LL ELSE n.%s END
95d0: 22 2c 20 26 61 7a 43 6f 6c 5b 6e 50 4b 5d 2c 20  ", &azCol[nPK], 
95e0: 2d 31 0a 20 20 20 20 29 3b 0a 0a 20 20 20 20 69  -1.    );..    i
95f0: 66 28 20 62 4f 74 61 52 6f 77 69 64 3d 3d 30 20  f( bOtaRowid==0 
9600: 29 7b 0a 20 20 20 20 20 20 73 74 72 50 72 69 6e  ){.      strPrin
9610: 74 66 28 70 53 71 6c 2c 20 22 2c 20 27 22 29 3b  tf(pSql, ", '");
9620: 0a 20 20 20 20 20 20 73 74 72 50 72 69 6e 74 66  .      strPrintf
9630: 41 72 72 61 79 28 70 53 71 6c 2c 20 22 22 2c 20  Array(pSql, "", 
9640: 22 2e 22 2c 20 61 7a 43 6f 6c 2c 20 6e 50 4b 29  ".", azCol, nPK)
9650: 3b 0a 20 20 20 20 20 20 73 74 72 50 72 69 6e 74  ;.      strPrint
9660: 66 28 70 53 71 6c 2c 20 22 27 20 7c 7c 5c 6e 22  f(pSql, "' ||\n"
9670: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
9680: 20 20 20 20 73 74 72 50 72 69 6e 74 66 28 70 53      strPrintf(pS
9690: 71 6c 2c 20 22 2c 5c 6e 22 29 3b 0a 20 20 20 20  ql, ",\n");.    
96a0: 7d 0a 20 20 20 20 73 74 72 50 72 69 6e 74 66 41  }.    strPrintfA
96b0: 72 72 61 79 28 70 53 71 6c 2c 20 22 20 7c 7c 5c  rray(pSql, " ||\
96c0: 6e 22 2c 20 0a 20 20 20 20 20 20 20 20 22 20 20  n", .        "  
96d0: 20 20 43 41 53 45 20 57 48 45 4e 20 6e 2e 25 73    CASE WHEN n.%s
96e0: 20 49 53 20 6f 2e 25 73 20 54 48 45 4e 20 27 2e   IS o.%s THEN '.
96f0: 27 20 45 4c 53 45 20 27 78 27 20 45 4e 44 22 2c  ' ELSE 'x' END",
9700: 20 26 61 7a 43 6f 6c 5b 6e 50 4b 5d 2c 20 2d 31   &azCol[nPK], -1
9710: 0a 20 20 20 20 29 3b 0a 20 20 20 20 73 74 72 50  .    );.    strP
9720: 72 69 6e 74 66 28 70 53 71 6c 2c 20 22 5c 6e 41  rintf(pSql, "\nA
9730: 53 20 6f 74 61 5f 63 6f 6e 74 72 6f 6c 2c 20 22  S ota_control, "
9740: 29 3b 0a 20 20 20 20 73 74 72 50 72 69 6e 74 66  );.    strPrintf
9750: 41 72 72 61 79 28 70 53 71 6c 2c 20 22 2c 20 22  Array(pSql, ", "
9760: 2c 20 22 4e 55 4c 4c 22 2c 20 61 7a 43 6f 6c 2c  , "NULL", azCol,
9770: 20 6e 50 4b 29 3b 0a 20 20 20 20 73 74 72 50 72   nPK);.    strPr
9780: 69 6e 74 66 28 70 53 71 6c 2c 20 22 2c 5c 6e 22  intf(pSql, ",\n"
9790: 29 3b 0a 20 20 20 20 73 74 72 50 72 69 6e 74 66  );.    strPrintf
97a0: 41 72 72 61 79 28 70 53 71 6c 2c 20 22 20 2c 5c  Array(pSql, " ,\
97b0: 6e 22 2c 20 0a 20 20 20 20 20 20 20 20 22 20 20  n", .        "  
97c0: 20 20 43 41 53 45 20 57 48 45 4e 20 6e 2e 25 73    CASE WHEN n.%s
97d0: 20 49 53 20 6f 2e 25 73 20 54 48 45 4e 20 4e 55   IS o.%s THEN NU
97e0: 4c 4c 20 45 4c 53 45 20 6f 2e 25 73 20 45 4e 44  LL ELSE o.%s END
97f0: 22 2c 20 26 61 7a 43 6f 6c 5b 6e 50 4b 5d 2c 20  ", &azCol[nPK], 
9800: 2d 31 0a 20 20 20 20 29 3b 0a 0a 20 20 20 20 73  -1.    );..    s
9810: 74 72 50 72 69 6e 74 66 28 70 53 71 6c 2c 20 22  trPrintf(pSql, "
9820: 5c 6e 46 52 4f 4d 20 6d 61 69 6e 2e 25 51 20 41  \nFROM main.%Q A
9830: 53 20 6f 2c 20 61 75 78 2e 25 51 20 41 53 20 6e  S o, aux.%Q AS n
9840: 5c 6e 57 48 45 52 45 20 22 2c 20 7a 54 61 62 2c  \nWHERE ", zTab,
9850: 20 7a 54 61 62 29 3b 0a 20 20 20 20 73 74 72 50   zTab);.    strP
9860: 72 69 6e 74 66 41 72 72 61 79 28 70 53 71 6c 2c  rintfArray(pSql,
9870: 20 22 20 41 4e 44 20 22 2c 20 22 28 6e 2e 25 51   " AND ", "(n.%Q
9880: 20 49 53 20 6f 2e 25 51 29 22 2c 20 61 7a 43 6f   IS o.%Q)", azCo
9890: 6c 2c 20 6e 50 4b 29 3b 0a 20 20 20 20 73 74 72  l, nPK);.    str
98a0: 50 72 69 6e 74 66 28 70 53 71 6c 2c 20 22 20 41  Printf(pSql, " A
98b0: 4e 44 20 6f 74 61 5f 63 6f 6e 74 72 6f 6c 20 4c  ND ota_control L
98c0: 49 4b 45 20 27 25 25 78 25 25 27 22 29 3b 0a 20  IKE '%%x%%'");. 
98d0: 20 7d 0a 0a 20 20 2f 2a 20 4e 6f 77 20 61 64 64   }..  /* Now add
98e0: 20 61 6e 20 4f 52 44 45 52 20 42 59 20 63 6c 61   an ORDER BY cla
98f0: 75 73 65 20 74 6f 20 73 6f 72 74 20 65 76 65 72  use to sort ever
9900: 79 74 68 69 6e 67 20 62 79 20 50 4b 2e 20 2a 2f  ything by PK. */
9910: 0a 20 20 73 74 72 50 72 69 6e 74 66 28 70 53 71  .  strPrintf(pSq
9920: 6c 2c 20 22 5c 6e 4f 52 44 45 52 20 42 59 20 22  l, "\nORDER BY "
9930: 29 3b 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c  );.  for(i=1; i<
9940: 3d 6e 50 4b 3b 20 69 2b 2b 29 20 73 74 72 50 72  =nPK; i++) strPr
9950: 69 6e 74 66 28 70 53 71 6c 2c 20 22 25 73 25 64  intf(pSql, "%s%d
9960: 22 2c 20 28 28 69 3e 31 29 3f 22 2c 20 22 3a 22  ", ((i>1)?", ":"
9970: 22 29 2c 20 69 29 3b 0a 7d 0a 0a 73 74 61 74 69  "), i);.}..stati
9980: 63 20 76 6f 69 64 20 72 62 75 64 69 66 66 5f 6f  c void rbudiff_o
9990: 6e 65 5f 74 61 62 6c 65 28 63 6f 6e 73 74 20 63  ne_table(const c
99a0: 68 61 72 20 2a 7a 54 61 62 2c 20 46 49 4c 45 20  har *zTab, FILE 
99b0: 2a 6f 75 74 29 7b 0a 20 20 69 6e 74 20 62 4f 74  *out){.  int bOt
99c0: 61 52 6f 77 69 64 3b 20 20 20 20 20 20 20 20 20  aRowid;         
99d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
99e0: 20 74 6f 20 75 73 65 20 61 6e 20 6f 74 61 5f 72   to use an ota_r
99f0: 6f 77 69 64 20 63 6f 6c 75 6d 6e 20 2a 2f 0a 20  owid column */. 
9a00: 20 69 6e 74 20 6e 50 4b 3b 20 20 20 20 20 20 20   int nPK;       
9a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9a20: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 72   /* Number of pr
9a30: 69 6d 61 72 79 20 6b 65 79 20 63 6f 6c 75 6d 6e  imary key column
9a40: 73 20 69 6e 20 74 61 62 6c 65 20 2a 2f 0a 20 20  s in table */.  
9a50: 63 68 61 72 20 2a 2a 61 7a 43 6f 6c 3b 20 20 20  char **azCol;   
9a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9a70: 2f 2a 20 4e 55 4c 4c 20 74 65 72 6d 69 6e 61 74  /* NULL terminat
9a80: 65 64 20 61 72 72 61 79 20 6f 66 20 63 6f 6c 20  ed array of col 
9a90: 6e 61 6d 65 73 20 2a 2f 0a 20 20 69 6e 74 20 69  names */.  int i
9aa0: 3b 0a 20 20 69 6e 74 20 6e 43 6f 6c 3b 0a 20 20  ;.  int nCol;.  
9ab0: 53 74 72 20 63 74 20 3d 20 7b 30 2c 20 30 2c 20  Str ct = {0, 0, 
9ac0: 30 7d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  0};             
9ad0: 2f 2a 20 54 68 65 20 22 43 52 45 41 54 45 20 54  /* The "CREATE T
9ae0: 41 42 4c 45 20 64 61 74 61 5f 78 78 78 22 20 73  ABLE data_xxx" s
9af0: 74 61 74 65 6d 65 6e 74 20 2a 2f 0a 20 20 53 74  tatement */.  St
9b00: 72 20 73 71 6c 20 3d 20 7b 30 2c 20 30 2c 20 30  r sql = {0, 0, 0
9b10: 7d 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  };            /*
9b20: 20 51 75 65 72 79 20 74 6f 20 66 69 6e 64 20 64   Query to find d
9b30: 69 66 66 65 72 65 6e 63 65 73 20 2a 2f 0a 20 20  ifferences */.  
9b40: 53 74 72 20 69 6e 73 65 72 74 20 3d 20 7b 30 2c  Str insert = {0,
9b50: 20 30 2c 20 30 7d 3b 20 20 20 20 20 20 20 20 20   0, 0};         
9b60: 2f 2a 20 46 69 72 73 74 20 70 61 72 74 20 6f 66  /* First part of
9b70: 20 6f 75 74 70 75 74 20 49 4e 53 45 52 54 20 73   output INSERT s
9b80: 74 61 74 65 6d 65 6e 74 20 2a 2f 0a 20 20 73 71  tatement */.  sq
9b90: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
9ba0: 74 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 2d 2d 72  t = 0;..  /* --r
9bb0: 62 75 20 6d 6f 64 65 20 6d 75 73 74 20 75 73 65  bu mode must use
9bc0: 20 72 65 61 6c 20 70 72 69 6d 61 72 79 20 6b 65   real primary ke
9bd0: 79 73 2e 20 2a 2f 0a 20 20 67 2e 62 53 63 68 65  ys. */.  g.bSche
9be0: 6d 61 50 4b 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20  maPK = 1;..  /* 
9bf0: 43 68 65 63 6b 20 74 68 61 74 20 74 68 65 20 73  Check that the s
9c00: 63 68 65 6d 61 73 20 6f 66 20 74 68 65 20 74 77  chemas of the tw
9c10: 6f 20 74 61 62 6c 65 73 20 6d 61 74 63 68 2e 20  o tables match. 
9c20: 45 78 69 74 20 65 61 72 6c 79 20 6f 74 68 65 72  Exit early other
9c30: 77 69 73 65 2e 20 2a 2f 0a 20 20 63 68 65 63 6b  wise. */.  check
9c40: 53 63 68 65 6d 61 73 4d 61 74 63 68 28 7a 54 61  SchemasMatch(zTa
9c50: 62 29 3b 0a 0a 20 20 2f 2a 20 47 72 61 62 20 74  b);..  /* Grab t
9c60: 68 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20  he column names 
9c70: 61 6e 64 20 50 4b 20 64 65 74 61 69 6c 73 20 66  and PK details f
9c80: 6f 72 20 74 68 65 20 74 61 62 6c 65 28 73 29 2e  or the table(s).
9c90: 20 49 66 20 6e 6f 20 75 73 61 62 6c 65 20 50 4b   If no usable PK
9ca0: 0a 20 20 2a 2a 20 63 6f 6c 75 6d 6e 73 20 61 72  .  ** columns ar
9cb0: 65 20 66 6f 75 6e 64 2c 20 62 61 69 6c 20 6f 75  e found, bail ou
9cc0: 74 20 65 61 72 6c 79 2e 20 20 2a 2f 0a 20 20 61  t early.  */.  a
9cd0: 7a 43 6f 6c 20 3d 20 63 6f 6c 75 6d 6e 4e 61 6d  zCol = columnNam
9ce0: 65 73 28 22 6d 61 69 6e 22 2c 20 7a 54 61 62 2c  es("main", zTab,
9cf0: 20 26 6e 50 4b 2c 20 26 62 4f 74 61 52 6f 77 69   &nPK, &bOtaRowi
9d00: 64 29 3b 0a 20 20 69 66 28 20 61 7a 43 6f 6c 3d  d);.  if( azCol=
9d10: 3d 30 20 29 7b 0a 20 20 20 20 72 75 6e 74 69 6d  =0 ){.    runtim
9d20: 65 45 72 72 6f 72 28 22 74 61 62 6c 65 20 25 73  eError("table %s
9d30: 20 68 61 73 20 6e 6f 20 75 73 61 62 6c 65 20 50   has no usable P
9d40: 4b 20 63 6f 6c 75 6d 6e 73 22 2c 20 7a 54 61 62  K columns", zTab
9d50: 29 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 6e 43 6f  );.  }.  for(nCo
9d60: 6c 3d 30 3b 20 61 7a 43 6f 6c 5b 6e 43 6f 6c 5d  l=0; azCol[nCol]
9d70: 3b 20 6e 43 6f 6c 2b 2b 29 3b 0a 0a 20 20 2f 2a  ; nCol++);..  /*
9d80: 20 42 75 69 6c 64 20 61 6e 64 20 6f 75 74 70 75   Build and outpu
9d90: 74 20 74 68 65 20 43 52 45 41 54 45 20 54 41 42  t the CREATE TAB
9da0: 4c 45 20 73 74 61 74 65 6d 65 6e 74 20 66 6f 72  LE statement for
9db0: 20 74 68 65 20 64 61 74 61 5f 78 78 78 20 74 61   the data_xxx ta
9dc0: 62 6c 65 20 2a 2f 0a 20 20 73 74 72 50 72 69 6e  ble */.  strPrin
9dd0: 74 66 28 26 63 74 2c 20 22 43 52 45 41 54 45 20  tf(&ct, "CREATE 
9de0: 54 41 42 4c 45 20 49 46 20 4e 4f 54 20 45 58 49  TABLE IF NOT EXI
9df0: 53 54 53 20 27 64 61 74 61 5f 25 71 27 28 22 2c  STS 'data_%q'(",
9e00: 20 7a 54 61 62 29 3b 0a 20 20 69 66 28 20 62 4f   zTab);.  if( bO
9e10: 74 61 52 6f 77 69 64 20 29 20 73 74 72 50 72 69  taRowid ) strPri
9e20: 6e 74 66 28 26 63 74 2c 20 22 72 62 75 5f 72 6f  ntf(&ct, "rbu_ro
9e30: 77 69 64 2c 20 22 29 3b 0a 20 20 73 74 72 50 72  wid, ");.  strPr
9e40: 69 6e 74 66 41 72 72 61 79 28 26 63 74 2c 20 22  intfArray(&ct, "
9e50: 2c 20 22 2c 20 22 25 73 22 2c 20 26 61 7a 43 6f  , ", "%s", &azCo
9e60: 6c 5b 62 4f 74 61 52 6f 77 69 64 5d 2c 20 2d 31  l[bOtaRowid], -1
9e70: 29 3b 0a 20 20 73 74 72 50 72 69 6e 74 66 28 26  );.  strPrintf(&
9e80: 63 74 2c 20 22 2c 20 72 62 75 5f 63 6f 6e 74 72  ct, ", rbu_contr
9e90: 6f 6c 29 3b 22 29 3b 0a 0a 20 20 2f 2a 20 47 65  ol);");..  /* Ge
9ea0: 74 20 74 68 65 20 53 51 4c 20 66 6f 72 20 74 68  t the SQL for th
9eb0: 65 20 71 75 65 72 79 20 74 6f 20 72 65 74 72 69  e query to retri
9ec0: 65 76 65 20 64 61 74 61 20 66 72 6f 6d 20 74 68  eve data from th
9ed0: 65 20 74 77 6f 20 64 61 74 61 62 61 73 65 73 20  e two databases 
9ee0: 2a 2f 0a 20 20 67 65 74 52 62 75 64 69 66 66 51  */.  getRbudiffQ
9ef0: 75 65 72 79 28 7a 54 61 62 2c 20 61 7a 43 6f 6c  uery(zTab, azCol
9f00: 2c 20 6e 50 4b 2c 20 62 4f 74 61 52 6f 77 69 64  , nPK, bOtaRowid
9f10: 2c 20 26 73 71 6c 29 3b 0a 0a 20 20 2f 2a 20 42  , &sql);..  /* B
9f20: 75 69 6c 64 20 74 68 65 20 66 69 72 73 74 20 70  uild the first p
9f30: 61 72 74 20 6f 66 20 74 68 65 20 49 4e 53 45 52  art of the INSER
9f40: 54 20 73 74 61 74 65 6d 65 6e 74 20 6f 75 74 70  T statement outp
9f50: 75 74 20 66 6f 72 20 65 61 63 68 20 72 6f 77 0a  ut for each row.
9f60: 20 20 2a 2a 20 69 6e 20 74 68 65 20 64 61 74 61    ** in the data
9f70: 5f 78 78 78 20 74 61 62 6c 65 2e 20 2a 2f 0a 20  _xxx table. */. 
9f80: 20 73 74 72 50 72 69 6e 74 66 28 26 69 6e 73 65   strPrintf(&inse
9f90: 72 74 2c 20 22 49 4e 53 45 52 54 20 49 4e 54 4f  rt, "INSERT INTO
9fa0: 20 27 64 61 74 61 5f 25 71 27 20 28 22 2c 20 7a   'data_%q' (", z
9fb0: 54 61 62 29 3b 0a 20 20 69 66 28 20 62 4f 74 61  Tab);.  if( bOta
9fc0: 52 6f 77 69 64 20 29 20 73 74 72 50 72 69 6e 74  Rowid ) strPrint
9fd0: 66 28 26 69 6e 73 65 72 74 2c 20 22 72 62 75 5f  f(&insert, "rbu_
9fe0: 72 6f 77 69 64 2c 20 22 29 3b 0a 20 20 73 74 72  rowid, ");.  str
9ff0: 50 72 69 6e 74 66 41 72 72 61 79 28 26 69 6e 73  PrintfArray(&ins
a000: 65 72 74 2c 20 22 2c 20 22 2c 20 22 25 73 22 2c  ert, ", ", "%s",
a010: 20 26 61 7a 43 6f 6c 5b 62 4f 74 61 52 6f 77 69   &azCol[bOtaRowi
a020: 64 5d 2c 20 2d 31 29 3b 0a 20 20 73 74 72 50 72  d], -1);.  strPr
a030: 69 6e 74 66 28 26 69 6e 73 65 72 74 2c 20 22 2c  intf(&insert, ",
a040: 20 72 62 75 5f 63 6f 6e 74 72 6f 6c 29 20 56 41   rbu_control) VA
a050: 4c 55 45 53 28 22 29 3b 0a 0a 20 20 70 53 74 6d  LUES(");..  pStm
a060: 74 20 3d 20 64 62 5f 70 72 65 70 61 72 65 28 22  t = db_prepare("
a070: 25 73 22 2c 20 73 71 6c 2e 7a 29 3b 0a 0a 20 20  %s", sql.z);..  
a080: 77 68 69 6c 65 28 20 73 71 6c 69 74 65 33 5f 73  while( sqlite3_s
a090: 74 65 70 28 70 53 74 6d 74 29 3d 3d 53 51 4c 49  tep(pStmt)==SQLI
a0a0: 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 0a 20  TE_ROW ){.    . 
a0b0: 20 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69 73     /* If this is
a0c0: 20 74 68 65 20 66 69 72 73 74 20 72 6f 77 20 6f   the first row o
a0d0: 75 74 70 75 74 2c 20 70 72 69 6e 74 20 6f 75 74  utput, print out
a0e0: 20 74 68 65 20 43 52 45 41 54 45 20 54 41 42 4c   the CREATE TABL
a0f0: 45 20 0a 20 20 20 20 2a 2a 20 73 74 61 74 65 6d  E .    ** statem
a100: 65 6e 74 20 66 69 72 73 74 2e 20 41 6e 64 20 74  ent first. And t
a110: 68 65 6e 20 73 65 74 20 63 74 2e 7a 20 74 6f 20  hen set ct.z to 
a120: 4e 55 4c 4c 20 73 6f 20 74 68 61 74 20 69 74 20  NULL so that it 
a130: 69 73 20 6e 6f 74 20 0a 20 20 20 20 2a 2a 20 70  is not .    ** p
a140: 72 69 6e 74 65 64 20 61 67 61 69 6e 2e 20 20 2a  rinted again.  *
a150: 2f 0a 20 20 20 20 69 66 28 20 63 74 2e 7a 20 29  /.    if( ct.z )
a160: 7b 0a 20 20 20 20 20 20 66 70 72 69 6e 74 66 28  {.      fprintf(
a170: 6f 75 74 2c 20 22 25 73 5c 6e 22 2c 20 63 74 2e  out, "%s\n", ct.
a180: 7a 29 3b 0a 20 20 20 20 20 20 73 74 72 46 72 65  z);.      strFre
a190: 65 28 26 63 74 29 3b 0a 20 20 20 20 7d 0a 0a 20  e(&ct);.    }.. 
a1a0: 20 20 20 2f 2a 20 4f 75 74 70 75 74 20 74 68 65     /* Output the
a1b0: 20 66 69 72 73 74 20 70 61 72 74 20 6f 66 20 74   first part of t
a1c0: 68 65 20 49 4e 53 45 52 54 20 73 74 61 74 65 6d  he INSERT statem
a1d0: 65 6e 74 20 2a 2f 0a 20 20 20 20 66 70 72 69 6e  ent */.    fprin
a1e0: 74 66 28 6f 75 74 2c 20 22 25 73 22 2c 20 69 6e  tf(out, "%s", in
a1f0: 73 65 72 74 2e 7a 29 3b 0a 0a 20 20 20 20 69 66  sert.z);..    if
a200: 28 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  ( sqlite3_column
a210: 5f 74 79 70 65 28 70 53 74 6d 74 2c 20 6e 43 6f  _type(pStmt, nCo
a220: 6c 29 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47  l)==SQLITE_INTEG
a230: 45 52 20 29 7b 0a 20 20 20 20 20 20 66 6f 72 28  ER ){.      for(
a240: 69 3d 30 3b 20 69 3c 3d 6e 43 6f 6c 3b 20 69 2b  i=0; i<=nCol; i+
a250: 2b 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20  +){.        if( 
a260: 69 3e 30 20 29 20 66 70 72 69 6e 74 66 28 6f 75  i>0 ) fprintf(ou
a270: 74 2c 20 22 2c 20 22 29 3b 0a 20 20 20 20 20 20  t, ", ");.      
a280: 20 20 70 72 69 6e 74 51 75 6f 74 65 64 28 6f 75    printQuoted(ou
a290: 74 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  t, sqlite3_colum
a2a0: 6e 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 20 69  n_value(pStmt, i
a2b0: 29 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ));.      }.    
a2c0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 68 61  }else{.      cha
a2d0: 72 20 2a 7a 4f 74 61 43 6f 6e 74 72 6f 6c 3b 0a  r *zOtaControl;.
a2e0: 20 20 20 20 20 20 69 6e 74 20 6e 4f 74 61 43 6f        int nOtaCo
a2f0: 6e 74 72 6f 6c 20 3d 20 73 71 6c 69 74 65 33 5f  ntrol = sqlite3_
a300: 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70 53 74  column_bytes(pSt
a310: 6d 74 2c 20 6e 43 6f 6c 29 3b 0a 0a 20 20 20 20  mt, nCol);..    
a320: 20 20 7a 4f 74 61 43 6f 6e 74 72 6f 6c 20 3d 20    zOtaControl = 
a330: 28 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 6d  (char*)sqlite3_m
a340: 61 6c 6c 6f 63 28 6e 4f 74 61 43 6f 6e 74 72 6f  alloc(nOtaContro
a350: 6c 29 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79  l);.      memcpy
a360: 28 7a 4f 74 61 43 6f 6e 74 72 6f 6c 2c 20 73 71  (zOtaControl, sq
a370: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78  lite3_column_tex
a380: 74 28 70 53 74 6d 74 2c 20 6e 43 6f 6c 29 2c 20  t(pStmt, nCol), 
a390: 6e 4f 74 61 43 6f 6e 74 72 6f 6c 2b 31 29 3b 0a  nOtaControl+1);.
a3a0: 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  .      for(i=0; 
a3b0: 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20  i<nCol; i++){.  
a3c0: 20 20 20 20 20 20 69 6e 74 20 62 44 6f 6e 65 20        int bDone 
a3d0: 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 69 66 28  = 0;.        if(
a3e0: 20 69 3e 3d 6e 50 4b 20 0a 20 20 20 20 20 20 20   i>=nPK .       
a3f0: 20 20 20 20 20 26 26 20 73 71 6c 69 74 65 33 5f       && sqlite3_
a400: 63 6f 6c 75 6d 6e 5f 74 79 70 65 28 70 53 74 6d  column_type(pStm
a410: 74 2c 20 69 29 3d 3d 53 51 4c 49 54 45 5f 42 4c  t, i)==SQLITE_BL
a420: 4f 42 0a 20 20 20 20 20 20 20 20 20 20 20 20 26  OB.            &
a430: 26 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  & sqlite3_column
a440: 5f 74 79 70 65 28 70 53 74 6d 74 2c 20 6e 43 6f  _type(pStmt, nCo
a450: 6c 2b 31 2b 69 29 3d 3d 53 51 4c 49 54 45 5f 42  l+1+i)==SQLITE_B
a460: 4c 4f 42 0a 20 20 20 20 20 20 20 20 29 7b 0a 20  LOB.        ){. 
a470: 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63           const c
a480: 68 61 72 20 2a 61 53 72 63 20 3d 20 73 71 6c 69  har *aSrc = sqli
a490: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f 62 28  te3_column_blob(
a4a0: 70 53 74 6d 74 2c 20 6e 43 6f 6c 2b 31 2b 69 29  pStmt, nCol+1+i)
a4b0: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 6e 74 20  ;.          int 
a4c0: 6e 53 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 63  nSrc = sqlite3_c
a4d0: 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70 53 74 6d  olumn_bytes(pStm
a4e0: 74 2c 20 6e 43 6f 6c 2b 31 2b 69 29 3b 0a 20 20  t, nCol+1+i);.  
a4f0: 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68          const ch
a500: 61 72 20 2a 61 46 69 6e 61 6c 20 3d 20 73 71 6c  ar *aFinal = sql
a510: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f 62  ite3_column_blob
a520: 28 70 53 74 6d 74 2c 20 69 29 3b 0a 20 20 20 20  (pStmt, i);.    
a530: 20 20 20 20 20 20 69 6e 74 20 6e 46 69 6e 61 6c        int nFinal
a540: 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d   = sqlite3_colum
a550: 6e 5f 62 79 74 65 73 28 70 53 74 6d 74 2c 20 69  n_bytes(pStmt, i
a560: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 63 68 61  );.          cha
a570: 72 20 2a 61 44 65 6c 74 61 3b 0a 20 20 20 20 20  r *aDelta;.     
a580: 20 20 20 20 20 69 6e 74 20 6e 44 65 6c 74 61 3b       int nDelta;
a590: 0a 0a 20 20 20 20 20 20 20 20 20 20 61 44 65 6c  ..          aDel
a5a0: 74 61 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c  ta = sqlite3_mal
a5b0: 6c 6f 63 28 6e 46 69 6e 61 6c 20 2b 20 36 30 29  loc(nFinal + 60)
a5c0: 3b 0a 20 20 20 20 20 20 20 20 20 20 6e 44 65 6c  ;.          nDel
a5d0: 74 61 20 3d 20 72 62 75 44 65 6c 74 61 43 72 65  ta = rbuDeltaCre
a5e0: 61 74 65 28 61 53 72 63 2c 20 6e 53 72 63 2c 20  ate(aSrc, nSrc, 
a5f0: 61 46 69 6e 61 6c 2c 20 6e 46 69 6e 61 6c 2c 20  aFinal, nFinal, 
a600: 61 44 65 6c 74 61 29 3b 0a 20 20 20 20 20 20 20  aDelta);.       
a610: 20 20 20 69 66 28 20 6e 44 65 6c 74 61 3c 6e 46     if( nDelta<nF
a620: 69 6e 61 6c 20 29 7b 0a 20 20 20 20 20 20 20 20  inal ){.        
a630: 20 20 20 20 69 6e 74 20 6a 3b 0a 20 20 20 20 20      int j;.     
a640: 20 20 20 20 20 20 20 66 70 72 69 6e 74 66 28 6f         fprintf(o
a650: 75 74 2c 20 22 78 27 22 29 3b 0a 20 20 20 20 20  ut, "x'");.     
a660: 20 20 20 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20         for(j=0; 
a670: 6a 3c 6e 44 65 6c 74 61 3b 20 6a 2b 2b 29 20 66  j<nDelta; j++) f
a680: 70 72 69 6e 74 66 28 6f 75 74 2c 20 22 25 30 32  printf(out, "%02
a690: 78 22 2c 20 28 75 38 29 61 44 65 6c 74 61 5b 6a  x", (u8)aDelta[j
a6a0: 5d 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  ]);.            
a6b0: 66 70 72 69 6e 74 66 28 6f 75 74 2c 20 22 27 22  fprintf(out, "'"
a6c0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7a  );.            z
a6d0: 4f 74 61 43 6f 6e 74 72 6f 6c 5b 69 2d 62 4f 74  OtaControl[i-bOt
a6e0: 61 52 6f 77 69 64 5d 20 3d 20 27 66 27 3b 0a 20  aRowid] = 'f';. 
a6f0: 20 20 20 20 20 20 20 20 20 20 20 62 44 6f 6e 65             bDone
a700: 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 20 20   = 1;.          
a710: 7d 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c 69  }.          sqli
a720: 74 65 33 5f 66 72 65 65 28 61 44 65 6c 74 61 29  te3_free(aDelta)
a730: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20  ;.        }..   
a740: 20 20 20 20 20 69 66 28 20 62 44 6f 6e 65 3d 3d       if( bDone==
a750: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70  0 ){.          p
a760: 72 69 6e 74 51 75 6f 74 65 64 28 6f 75 74 2c 20  rintQuoted(out, 
a770: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76  sqlite3_column_v
a780: 61 6c 75 65 28 70 53 74 6d 74 2c 20 69 29 29 3b  alue(pStmt, i));
a790: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
a7a0: 20 20 20 66 70 72 69 6e 74 66 28 6f 75 74 2c 20     fprintf(out, 
a7b0: 22 2c 20 22 29 3b 0a 20 20 20 20 20 20 7d 0a 20  ", ");.      }. 
a7c0: 20 20 20 20 20 66 70 72 69 6e 74 66 28 6f 75 74       fprintf(out
a7d0: 2c 20 22 27 25 73 27 22 2c 20 7a 4f 74 61 43 6f  , "'%s'", zOtaCo
a7e0: 6e 74 72 6f 6c 29 3b 0a 20 20 20 20 20 20 73 71  ntrol);.      sq
a7f0: 6c 69 74 65 33 5f 66 72 65 65 28 7a 4f 74 61 43  lite3_free(zOtaC
a800: 6f 6e 74 72 6f 6c 29 3b 0a 20 20 20 20 7d 0a 0a  ontrol);.    }..
a810: 20 20 20 20 2f 2a 20 41 6e 64 20 74 68 65 20 63      /* And the c
a820: 6c 6f 73 69 6e 67 20 62 72 61 63 6b 65 74 20 6f  losing bracket o
a830: 66 20 74 68 65 20 69 6e 73 65 72 74 20 73 74 61  f the insert sta
a840: 74 65 6d 65 6e 74 20 2a 2f 0a 20 20 20 20 66 70  tement */.    fp
a850: 72 69 6e 74 66 28 6f 75 74 2c 20 22 29 3b 5c 6e  rintf(out, ");\n
a860: 22 29 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74  ");.  }..  sqlit
a870: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d  e3_finalize(pStm
a880: 74 29 3b 0a 0a 20 20 73 74 72 46 72 65 65 28 26  t);..  strFree(&
a890: 63 74 29 3b 0a 20 20 73 74 72 46 72 65 65 28 26  ct);.  strFree(&
a8a0: 73 71 6c 29 3b 0a 20 20 73 74 72 46 72 65 65 28  sql);.  strFree(
a8b0: 26 69 6e 73 65 72 74 29 3b 0a 7d 0a 0a 2f 2a 0a  &insert);.}../*.
a8c0: 2a 2a 20 44 69 73 70 6c 61 79 20 61 20 73 75 6d  ** Display a sum
a8d0: 6d 61 72 79 20 6f 66 20 64 69 66 66 65 72 65 6e  mary of differen
a8e0: 63 65 73 20 62 65 74 77 65 65 6e 20 74 77 6f 20  ces between two 
a8f0: 76 65 72 73 69 6f 6e 73 20 6f 66 20 74 68 65 20  versions of the 
a900: 73 61 6d 65 0a 2a 2a 20 74 61 62 6c 65 20 74 61  same.** table ta
a910: 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 2a 20 20  ble..**.**   *  
a920: 4e 75 6d 62 65 72 20 6f 66 20 72 6f 77 73 20 63  Number of rows c
a930: 68 61 6e 67 65 64 0a 2a 2a 20 20 20 2a 20 20 4e  hanged.**   *  N
a940: 75 6d 62 65 72 20 6f 66 20 72 6f 77 73 20 61 64  umber of rows ad
a950: 64 65 64 0a 2a 2a 20 20 20 2a 20 20 4e 75 6d 62  ded.**   *  Numb
a960: 65 72 20 6f 66 20 72 6f 77 73 20 64 65 6c 65 74  er of rows delet
a970: 65 64 0a 2a 2a 20 20 20 2a 20 20 4e 75 6d 62 65  ed.**   *  Numbe
a980: 72 20 6f 66 20 69 64 65 6e 74 69 63 61 6c 20 72  r of identical r
a990: 6f 77 73 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ows.*/.static vo
a9a0: 69 64 20 73 75 6d 6d 61 72 69 7a 65 5f 6f 6e 65  id summarize_one
a9b0: 5f 74 61 62 6c 65 28 63 6f 6e 73 74 20 63 68 61  _table(const cha
a9c0: 72 20 2a 7a 54 61 62 2c 20 46 49 4c 45 20 2a 6f  r *zTab, FILE *o
a9d0: 75 74 29 7b 0a 20 20 63 68 61 72 20 2a 7a 49 64  ut){.  char *zId
a9e0: 20 3d 20 73 61 66 65 49 64 28 7a 54 61 62 29 3b   = safeId(zTab);
a9f0: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 61 62 6c   /* Name of tabl
aa00: 65 20 28 74 72 61 6e 73 6c 61 74 65 64 20 66 6f  e (translated fo
aa10: 72 20 75 73 20 69 6e 20 53 51 4c 29 20 2a 2f 0a  r us in SQL) */.
aa20: 20 20 63 68 61 72 20 2a 2a 61 7a 20 3d 20 30 3b    char **az = 0;
aa30: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
aa40: 6f 6c 75 6d 6e 73 20 69 6e 20 6d 61 69 6e 20 2a  olumns in main *
aa50: 2f 0a 20 20 63 68 61 72 20 2a 2a 61 7a 32 20 3d  /.  char **az2 =
aa60: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a   0;           /*
aa70: 20 43 6f 6c 75 6d 6e 73 20 69 6e 20 61 75 78 20   Columns in aux 
aa80: 2a 2f 0a 20 20 69 6e 74 20 6e 50 6b 3b 20 20 20  */.  int nPk;   
aa90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
aaa0: 2a 20 50 72 69 6d 61 72 79 20 6b 65 79 20 63 6f  * Primary key co
aab0: 6c 75 6d 6e 73 20 69 6e 20 6d 61 69 6e 20 2a 2f  lumns in main */
aac0: 0a 20 20 69 6e 74 20 6e 50 6b 32 3b 20 20 20 20  .  int nPk2;    
aad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
aae0: 50 72 69 6d 61 72 79 20 6b 65 79 20 63 6f 6c 75  Primary key colu
aaf0: 6d 6e 73 20 69 6e 20 61 75 78 20 2a 2f 0a 20 20  mns in aux */.  
ab00: 69 6e 74 20 6e 20 3d 20 30 3b 20 20 20 20 20 20  int n = 0;      
ab10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
ab20: 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69  ber of columns i
ab30: 6e 20 6d 61 69 6e 20 2a 2f 0a 20 20 69 6e 74 20  n main */.  int 
ab40: 6e 32 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  n2;             
ab50: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
ab60: 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 61 75  of columns in au
ab70: 78 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20  x */.  int i;   
ab80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ab90: 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72   /* Loop counter
aba0: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
abb0: 20 2a 7a 53 65 70 3b 20 20 20 20 20 20 20 20 20   *zSep;         
abc0: 2f 2a 20 53 65 70 61 72 61 74 6f 72 20 73 74 72  /* Separator str
abd0: 69 6e 67 20 2a 2f 0a 20 20 53 74 72 20 73 71 6c  ing */.  Str sql
abe0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
abf0: 20 20 20 2f 2a 20 43 6f 6d 70 61 72 69 73 6f 6e     /* Comparison
ac00: 20 71 75 65 72 79 20 2a 2f 0a 20 20 73 71 6c 69   query */.  sqli
ac10: 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b  te3_stmt *pStmt;
ac20: 20 20 20 20 20 20 2f 2a 20 51 75 65 72 79 20 73        /* Query s
ac30: 74 61 74 65 6d 65 6e 74 20 74 6f 20 64 6f 20 74  tatement to do t
ac40: 68 65 20 64 69 66 66 20 2a 2f 0a 20 20 73 71 6c  he diff */.  sql
ac50: 69 74 65 33 5f 69 6e 74 36 34 20 6e 55 70 64 61  ite3_int64 nUpda
ac60: 74 65 3b 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72  te;    /* Number
ac70: 20 6f 66 20 75 70 64 61 74 65 64 20 72 6f 77 73   of updated rows
ac80: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e   */.  sqlite3_in
ac90: 74 36 34 20 6e 55 6e 63 68 61 6e 67 65 64 3b 20  t64 nUnchanged; 
aca0: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 75 6e 6d  /* Number of unm
acb0: 6f 64 69 66 69 65 64 20 72 6f 77 73 20 2a 2f 0a  odified rows */.
acc0: 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20    sqlite3_int64 
acd0: 6e 44 65 6c 65 74 65 3b 20 20 20 20 2f 2a 20 4e  nDelete;    /* N
ace0: 75 6d 62 65 72 20 6f 66 20 64 65 6c 65 74 65 64  umber of deleted
acf0: 20 72 6f 77 73 20 2a 2f 0a 20 20 73 71 6c 69 74   rows */.  sqlit
ad00: 65 33 5f 69 6e 74 36 34 20 6e 49 6e 73 65 72 74  e3_int64 nInsert
ad10: 3b 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f  ;    /* Number o
ad20: 66 20 69 6e 73 65 72 74 65 64 20 72 6f 77 73 20  f inserted rows 
ad30: 2a 2f 0a 0a 20 20 73 74 72 49 6e 69 74 28 26 73  */..  strInit(&s
ad40: 71 6c 29 3b 0a 20 20 69 66 28 20 73 71 6c 69 74  ql);.  if( sqlit
ad50: 65 33 5f 74 61 62 6c 65 5f 63 6f 6c 75 6d 6e 5f  e3_table_column_
ad60: 6d 65 74 61 64 61 74 61 28 67 2e 64 62 2c 22 61  metadata(g.db,"a
ad70: 75 78 22 2c 7a 54 61 62 2c 30 2c 30 2c 30 2c 30  ux",zTab,0,0,0,0
ad80: 2c 30 2c 30 29 20 29 7b 0a 20 20 20 20 69 66 28  ,0,0) ){.    if(
ad90: 20 21 73 71 6c 69 74 65 33 5f 74 61 62 6c 65 5f   !sqlite3_table_
ada0: 63 6f 6c 75 6d 6e 5f 6d 65 74 61 64 61 74 61 28  column_metadata(
adb0: 67 2e 64 62 2c 22 6d 61 69 6e 22 2c 7a 54 61 62  g.db,"main",zTab
adc0: 2c 30 2c 30 2c 30 2c 30 2c 30 2c 30 29 20 29 7b  ,0,0,0,0,0,0) ){
add0: 0a 20 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20  .      /* Table 
ade0: 6d 69 73 73 69 6e 67 20 66 72 6f 6d 20 73 65 63  missing from sec
adf0: 6f 6e 64 20 64 61 74 61 62 61 73 65 2e 20 2a 2f  ond database. */
ae00: 0a 20 20 20 20 20 20 66 70 72 69 6e 74 66 28 6f  .      fprintf(o
ae10: 75 74 2c 20 22 25 73 3a 20 6d 69 73 73 69 6e 67  ut, "%s: missing
ae20: 20 66 72 6f 6d 20 73 65 63 6f 6e 64 20 64 61 74   from second dat
ae30: 61 62 61 73 65 5c 6e 22 2c 20 7a 54 61 62 29 3b  abase\n", zTab);
ae40: 0a 20 20 20 20 7d 0a 20 20 20 20 67 6f 74 6f 20  .    }.    goto 
ae50: 65 6e 64 5f 73 75 6d 6d 61 72 69 7a 65 5f 6f 6e  end_summarize_on
ae60: 65 5f 74 61 62 6c 65 3b 0a 20 20 7d 0a 0a 20 20  e_table;.  }..  
ae70: 69 66 28 20 73 71 6c 69 74 65 33 5f 74 61 62 6c  if( sqlite3_tabl
ae80: 65 5f 63 6f 6c 75 6d 6e 5f 6d 65 74 61 64 61 74  e_column_metadat
ae90: 61 28 67 2e 64 62 2c 22 6d 61 69 6e 22 2c 7a 54  a(g.db,"main",zT
aea0: 61 62 2c 30 2c 30 2c 30 2c 30 2c 30 2c 30 29 20  ab,0,0,0,0,0,0) 
aeb0: 29 7b 0a 20 20 20 20 2f 2a 20 54 61 62 6c 65 20  ){.    /* Table 
aec0: 6d 69 73 73 69 6e 67 20 66 72 6f 6d 20 73 6f 75  missing from sou
aed0: 72 63 65 20 2a 2f 0a 20 20 20 20 66 70 72 69 6e  rce */.    fprin
aee0: 74 66 28 6f 75 74 2c 20 22 25 73 3a 20 6d 69 73  tf(out, "%s: mis
aef0: 73 69 6e 67 20 66 72 6f 6d 20 66 69 72 73 74 20  sing from first 
af00: 64 61 74 61 62 61 73 65 5c 6e 22 2c 20 7a 54 61  database\n", zTa
af10: 62 29 3b 0a 20 20 20 20 67 6f 74 6f 20 65 6e 64  b);.    goto end
af20: 5f 73 75 6d 6d 61 72 69 7a 65 5f 6f 6e 65 5f 74  _summarize_one_t
af30: 61 62 6c 65 3b 0a 20 20 7d 0a 0a 20 20 61 7a 20  able;.  }..  az 
af40: 3d 20 63 6f 6c 75 6d 6e 4e 61 6d 65 73 28 22 6d  = columnNames("m
af50: 61 69 6e 22 2c 20 7a 54 61 62 2c 20 26 6e 50 6b  ain", zTab, &nPk
af60: 2c 20 30 29 3b 0a 20 20 61 7a 32 20 3d 20 63 6f  , 0);.  az2 = co
af70: 6c 75 6d 6e 4e 61 6d 65 73 28 22 61 75 78 22 2c  lumnNames("aux",
af80: 20 7a 54 61 62 2c 20 26 6e 50 6b 32 2c 20 30 29   zTab, &nPk2, 0)
af90: 3b 0a 20 20 69 66 28 20 61 7a 20 26 26 20 61 7a  ;.  if( az && az
afa0: 32 20 29 7b 0a 20 20 20 20 66 6f 72 28 6e 3d 30  2 ){.    for(n=0
afb0: 3b 20 61 7a 5b 6e 5d 3b 20 6e 2b 2b 29 7b 0a 20  ; az[n]; n++){. 
afc0: 20 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33       if( sqlite3
afd0: 5f 73 74 72 69 63 6d 70 28 61 7a 5b 6e 5d 2c 61  _stricmp(az[n],a
afe0: 7a 32 5b 6e 5d 29 21 3d 30 20 29 20 62 72 65 61  z2[n])!=0 ) brea
aff0: 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69  k;.    }.  }.  i
b000: 66 28 20 61 7a 3d 3d 30 0a 20 20 20 7c 7c 20 61  f( az==0.   || a
b010: 7a 32 3d 3d 30 0a 20 20 20 7c 7c 20 6e 50 6b 21  z2==0.   || nPk!
b020: 3d 6e 50 6b 32 0a 20 20 20 7c 7c 20 61 7a 5b 6e  =nPk2.   || az[n
b030: 5d 0a 20 20 29 7b 0a 20 20 20 20 2f 2a 20 53 63  ].  ){.    /* Sc
b040: 68 65 6d 61 20 6d 69 73 6d 61 74 63 68 20 2a 2f  hema mismatch */
b050: 0a 20 20 20 20 66 70 72 69 6e 74 66 28 6f 75 74  .    fprintf(out
b060: 2c 20 22 25 73 3a 20 69 6e 63 6f 6d 70 61 74 69  , "%s: incompati
b070: 62 6c 65 20 73 63 68 65 6d 61 5c 6e 22 2c 20 7a  ble schema\n", z
b080: 54 61 62 29 3b 0a 20 20 20 20 67 6f 74 6f 20 65  Tab);.    goto e
b090: 6e 64 5f 73 75 6d 6d 61 72 69 7a 65 5f 6f 6e 65  nd_summarize_one
b0a0: 5f 74 61 62 6c 65 3b 0a 20 20 7d 0a 0a 20 20 2f  _table;.  }..  /
b0b0: 2a 20 42 75 69 6c 64 20 74 68 65 20 63 6f 6d 70  * Build the comp
b0c0: 61 72 69 73 6f 6e 20 71 75 65 72 79 20 2a 2f 0a  arison query */.
b0d0: 20 20 66 6f 72 28 6e 32 3d 6e 3b 20 61 7a 5b 6e    for(n2=n; az[n
b0e0: 32 5d 3b 20 6e 32 2b 2b 29 7b 7d 0a 20 20 73 74  2]; n2++){}.  st
b0f0: 72 50 72 69 6e 74 66 28 26 73 71 6c 2c 20 22 53  rPrintf(&sql, "S
b100: 45 4c 45 43 54 20 31 2c 20 63 6f 75 6e 74 28 2a  ELECT 1, count(*
b110: 29 22 29 3b 0a 20 20 69 66 28 20 6e 32 3d 3d 6e  )");.  if( n2==n
b120: 50 6b 32 20 29 7b 0a 20 20 20 20 73 74 72 50 72  Pk2 ){.    strPr
b130: 69 6e 74 66 28 26 73 71 6c 2c 20 22 2c 20 30 5c  intf(&sql, ", 0\
b140: 6e 22 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  n");.  }else{.  
b150: 20 20 7a 53 65 70 20 3d 20 22 2c 20 73 75 6d 28    zSep = ", sum(
b160: 22 3b 0a 20 20 20 20 66 6f 72 28 69 3d 6e 50 6b  ";.    for(i=nPk
b170: 3b 20 61 7a 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20  ; az[i]; i++){. 
b180: 20 20 20 20 20 73 74 72 50 72 69 6e 74 66 28 26       strPrintf(&
b190: 73 71 6c 2c 20 22 25 73 41 2e 25 73 20 49 53 20  sql, "%sA.%s IS 
b1a0: 4e 4f 54 20 42 2e 25 73 22 2c 20 7a 53 65 70 2c  NOT B.%s", zSep,
b1b0: 20 61 7a 5b 69 5d 2c 20 61 7a 5b 69 5d 29 3b 0a   az[i], az[i]);.
b1c0: 20 20 20 20 20 20 7a 53 65 70 20 3d 20 22 20 4f        zSep = " O
b1d0: 52 20 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73  R ";.    }.    s
b1e0: 74 72 50 72 69 6e 74 66 28 26 73 71 6c 2c 20 22  trPrintf(&sql, "
b1f0: 29 5c 6e 22 29 3b 0a 20 20 7d 0a 20 20 73 74 72  )\n");.  }.  str
b200: 50 72 69 6e 74 66 28 26 73 71 6c 2c 20 22 20 20  Printf(&sql, "  
b210: 46 52 4f 4d 20 6d 61 69 6e 2e 25 73 20 41 2c 20  FROM main.%s A, 
b220: 61 75 78 2e 25 73 20 42 5c 6e 22 2c 20 7a 49 64  aux.%s B\n", zId
b230: 2c 20 7a 49 64 29 3b 0a 20 20 7a 53 65 70 20 3d  , zId);.  zSep =
b240: 20 22 20 57 48 45 52 45 22 3b 0a 20 20 66 6f 72   " WHERE";.  for
b250: 28 69 3d 30 3b 20 69 3c 6e 50 6b 3b 20 69 2b 2b  (i=0; i<nPk; i++
b260: 29 7b 0a 20 20 20 20 73 74 72 50 72 69 6e 74 66  ){.    strPrintf
b270: 28 26 73 71 6c 2c 20 22 25 73 20 41 2e 25 73 3d  (&sql, "%s A.%s=
b280: 42 2e 25 73 22 2c 20 7a 53 65 70 2c 20 61 7a 5b  B.%s", zSep, az[
b290: 69 5d 2c 20 61 7a 5b 69 5d 29 3b 0a 20 20 20 20  i], az[i]);.    
b2a0: 7a 53 65 70 20 3d 20 22 20 41 4e 44 22 3b 0a 20  zSep = " AND";. 
b2b0: 20 7d 0a 20 20 73 74 72 50 72 69 6e 74 66 28 26   }.  strPrintf(&
b2c0: 73 71 6c 2c 20 22 20 55 4e 49 4f 4e 20 41 4c 4c  sql, " UNION ALL
b2d0: 5c 6e 22 29 3b 0a 20 20 73 74 72 50 72 69 6e 74  \n");.  strPrint
b2e0: 66 28 26 73 71 6c 2c 20 22 53 45 4c 45 43 54 20  f(&sql, "SELECT 
b2f0: 32 2c 20 63 6f 75 6e 74 28 2a 29 2c 20 30 5c 6e  2, count(*), 0\n
b300: 22 29 3b 0a 20 20 73 74 72 50 72 69 6e 74 66 28  ");.  strPrintf(
b310: 26 73 71 6c 2c 20 22 20 20 46 52 4f 4d 20 6d 61  &sql, "  FROM ma
b320: 69 6e 2e 25 73 20 41 5c 6e 22 2c 20 7a 49 64 29  in.%s A\n", zId)
b330: 3b 0a 20 20 73 74 72 50 72 69 6e 74 66 28 26 73  ;.  strPrintf(&s
b340: 71 6c 2c 20 22 20 57 48 45 52 45 20 4e 4f 54 20  ql, " WHERE NOT 
b350: 45 58 49 53 54 53 28 53 45 4c 45 43 54 20 31 20  EXISTS(SELECT 1 
b360: 46 52 4f 4d 20 61 75 78 2e 25 73 20 42 20 22 2c  FROM aux.%s B ",
b370: 20 7a 49 64 29 3b 0a 20 20 7a 53 65 70 20 3d 20   zId);.  zSep = 
b380: 22 57 48 45 52 45 22 3b 0a 20 20 66 6f 72 28 69  "WHERE";.  for(i
b390: 3d 30 3b 20 69 3c 6e 50 6b 3b 20 69 2b 2b 29 7b  =0; i<nPk; i++){
b3a0: 0a 20 20 20 20 73 74 72 50 72 69 6e 74 66 28 26  .    strPrintf(&
b3b0: 73 71 6c 2c 20 22 25 73 20 41 2e 25 73 3d 42 2e  sql, "%s A.%s=B.
b3c0: 25 73 22 2c 20 7a 53 65 70 2c 20 61 7a 5b 69 5d  %s", zSep, az[i]
b3d0: 2c 20 61 7a 5b 69 5d 29 3b 0a 20 20 20 20 7a 53  , az[i]);.    zS
b3e0: 65 70 20 3d 20 22 20 41 4e 44 22 3b 0a 20 20 7d  ep = " AND";.  }
b3f0: 0a 20 20 73 74 72 50 72 69 6e 74 66 28 26 73 71  .  strPrintf(&sq
b400: 6c 2c 20 22 29 5c 6e 22 29 3b 0a 20 20 73 74 72  l, ")\n");.  str
b410: 50 72 69 6e 74 66 28 26 73 71 6c 2c 20 22 20 55  Printf(&sql, " U
b420: 4e 49 4f 4e 20 41 4c 4c 5c 6e 22 29 3b 0a 20 20  NION ALL\n");.  
b430: 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c 2c 20  strPrintf(&sql, 
b440: 22 53 45 4c 45 43 54 20 33 2c 20 63 6f 75 6e 74  "SELECT 3, count
b450: 28 2a 29 2c 20 30 5c 6e 22 29 3b 0a 20 20 73 74  (*), 0\n");.  st
b460: 72 50 72 69 6e 74 66 28 26 73 71 6c 2c 20 22 20  rPrintf(&sql, " 
b470: 20 46 52 4f 4d 20 61 75 78 2e 25 73 20 42 5c 6e   FROM aux.%s B\n
b480: 22 2c 20 7a 49 64 29 3b 0a 20 20 73 74 72 50 72  ", zId);.  strPr
b490: 69 6e 74 66 28 26 73 71 6c 2c 20 22 20 57 48 45  intf(&sql, " WHE
b4a0: 52 45 20 4e 4f 54 20 45 58 49 53 54 53 28 53 45  RE NOT EXISTS(SE
b4b0: 4c 45 43 54 20 31 20 46 52 4f 4d 20 6d 61 69 6e  LECT 1 FROM main
b4c0: 2e 25 73 20 41 20 22 2c 20 7a 49 64 29 3b 0a 20  .%s A ", zId);. 
b4d0: 20 7a 53 65 70 20 3d 20 22 57 48 45 52 45 22 3b   zSep = "WHERE";
b4e0: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 50  .  for(i=0; i<nP
b4f0: 6b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 73 74 72  k; i++){.    str
b500: 50 72 69 6e 74 66 28 26 73 71 6c 2c 20 22 25 73  Printf(&sql, "%s
b510: 20 41 2e 25 73 3d 42 2e 25 73 22 2c 20 7a 53 65   A.%s=B.%s", zSe
b520: 70 2c 20 61 7a 5b 69 5d 2c 20 61 7a 5b 69 5d 29  p, az[i], az[i])
b530: 3b 0a 20 20 20 20 7a 53 65 70 20 3d 20 22 20 41  ;.    zSep = " A
b540: 4e 44 22 3b 0a 20 20 7d 0a 20 20 73 74 72 50 72  ND";.  }.  strPr
b550: 69 6e 74 66 28 26 73 71 6c 2c 20 22 29 5c 6e 20  intf(&sql, ")\n 
b560: 4f 52 44 45 52 20 42 59 20 31 3b 5c 6e 22 29 3b  ORDER BY 1;\n");
b570: 0a 0a 20 20 69 66 28 20 28 67 2e 66 44 65 62 75  ..  if( (g.fDebu
b580: 67 20 26 20 44 45 42 55 47 5f 44 49 46 46 5f 53  g & DEBUG_DIFF_S
b590: 51 4c 29 21 3d 30 20 29 7b 20 0a 20 20 20 20 70  QL)!=0 ){ .    p
b5a0: 72 69 6e 74 66 28 22 53 51 4c 20 66 6f 72 20 25  rintf("SQL for %
b5b0: 73 3a 5c 6e 25 73 5c 6e 22 2c 20 7a 49 64 2c 20  s:\n%s\n", zId, 
b5c0: 73 71 6c 2e 7a 29 3b 0a 20 20 20 20 67 6f 74 6f  sql.z);.    goto
b5d0: 20 65 6e 64 5f 73 75 6d 6d 61 72 69 7a 65 5f 6f   end_summarize_o
b5e0: 6e 65 5f 74 61 62 6c 65 3b 0a 20 20 7d 0a 0a 20  ne_table;.  }.. 
b5f0: 20 2f 2a 20 52 75 6e 20 74 68 65 20 71 75 65 72   /* Run the quer
b600: 79 20 61 6e 64 20 6f 75 74 70 75 74 20 64 69 66  y and output dif
b610: 66 65 72 65 6e 63 65 20 73 75 6d 6d 61 72 79 20  ference summary 
b620: 2a 2f 0a 20 20 70 53 74 6d 74 20 3d 20 64 62 5f  */.  pStmt = db_
b630: 70 72 65 70 61 72 65 28 73 71 6c 2e 7a 29 3b 0a  prepare(sql.z);.
b640: 20 20 6e 55 70 64 61 74 65 20 3d 20 30 3b 0a 20    nUpdate = 0;. 
b650: 20 6e 49 6e 73 65 72 74 20 3d 20 30 3b 0a 20 20   nInsert = 0;.  
b660: 6e 44 65 6c 65 74 65 20 3d 20 30 3b 0a 20 20 6e  nDelete = 0;.  n
b670: 55 6e 63 68 61 6e 67 65 64 20 3d 20 30 3b 0a 20  Unchanged = 0;. 
b680: 20 77 68 69 6c 65 28 20 53 51 4c 49 54 45 5f 52   while( SQLITE_R
b690: 4f 57 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65 70  OW==sqlite3_step
b6a0: 28 70 53 74 6d 74 29 20 29 7b 0a 20 20 20 20 73  (pStmt) ){.    s
b6b0: 77 69 74 63 68 28 20 73 71 6c 69 74 65 33 5f 63  witch( sqlite3_c
b6c0: 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d 74 2c  olumn_int(pStmt,
b6d0: 30 29 20 29 7b 0a 20 20 20 20 20 20 63 61 73 65  0) ){.      case
b6e0: 20 31 3a 0a 20 20 20 20 20 20 20 20 6e 55 70 64   1:.        nUpd
b6f0: 61 74 65 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  ate = sqlite3_co
b700: 6c 75 6d 6e 5f 69 6e 74 36 34 28 70 53 74 6d 74  lumn_int64(pStmt
b710: 2c 32 29 3b 0a 20 20 20 20 20 20 20 20 6e 55 6e  ,2);.        nUn
b720: 63 68 61 6e 67 65 64 20 3d 20 73 71 6c 69 74 65  changed = sqlite
b730: 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28 70  3_column_int64(p
b740: 53 74 6d 74 2c 31 29 20 2d 20 6e 55 70 64 61 74  Stmt,1) - nUpdat
b750: 65 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  e;.        break
b760: 3b 0a 20 20 20 20 20 20 63 61 73 65 20 32 3a 0a  ;.      case 2:.
b770: 20 20 20 20 20 20 20 20 6e 44 65 6c 65 74 65 20          nDelete 
b780: 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
b790: 5f 69 6e 74 36 34 28 70 53 74 6d 74 2c 31 29 3b  _int64(pStmt,1);
b7a0: 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
b7b0: 20 20 20 20 20 20 63 61 73 65 20 33 3a 0a 20 20        case 3:.  
b7c0: 20 20 20 20 20 20 6e 49 6e 73 65 72 74 20 3d 20        nInsert = 
b7d0: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69  sqlite3_column_i
b7e0: 6e 74 36 34 28 70 53 74 6d 74 2c 31 29 3b 0a 20  nt64(pStmt,1);. 
b7f0: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
b800: 20 20 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65    }.  }.  sqlite
b810: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74  3_finalize(pStmt
b820: 29 3b 0a 20 20 66 70 72 69 6e 74 66 28 6f 75 74  );.  fprintf(out
b830: 2c 20 22 25 73 3a 20 25 6c 6c 64 20 63 68 61 6e  , "%s: %lld chan
b840: 67 65 73 2c 20 25 6c 6c 64 20 69 6e 73 65 72 74  ges, %lld insert
b850: 73 2c 20 25 6c 6c 64 20 64 65 6c 65 74 65 73 2c  s, %lld deletes,
b860: 20 25 6c 6c 64 20 75 6e 63 68 61 6e 67 65 64 5c   %lld unchanged\
b870: 6e 22 2c 0a 20 20 20 20 20 20 20 20 20 20 7a 54  n",.          zT
b880: 61 62 2c 20 6e 55 70 64 61 74 65 2c 20 6e 49 6e  ab, nUpdate, nIn
b890: 73 65 72 74 2c 20 6e 44 65 6c 65 74 65 2c 20 6e  sert, nDelete, n
b8a0: 55 6e 63 68 61 6e 67 65 64 29 3b 0a 0a 65 6e 64  Unchanged);..end
b8b0: 5f 73 75 6d 6d 61 72 69 7a 65 5f 6f 6e 65 5f 74  _summarize_one_t
b8c0: 61 62 6c 65 3a 0a 20 20 73 74 72 46 72 65 65 28  able:.  strFree(
b8d0: 26 73 71 6c 29 3b 0a 20 20 73 71 6c 69 74 65 33  &sql);.  sqlite3
b8e0: 5f 66 72 65 65 28 7a 49 64 29 3b 0a 20 20 6e 61  _free(zId);.  na
b8f0: 6d 65 6c 69 73 74 46 72 65 65 28 61 7a 29 3b 0a  melistFree(az);.
b900: 20 20 6e 61 6d 65 6c 69 73 74 46 72 65 65 28 61    namelistFree(a
b910: 7a 32 29 3b 0a 20 20 72 65 74 75 72 6e 3b 0a 7d  z2);.  return;.}
b920: 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 61 20  ../*.** Write a 
b930: 36 34 2d 62 69 74 20 73 69 67 6e 65 64 20 69 6e  64-bit signed in
b940: 74 65 67 65 72 20 61 73 20 61 20 76 61 72 69 6e  teger as a varin
b950: 74 20 6f 6e 74 6f 20 6f 75 74 0a 2a 2f 0a 73 74  t onto out.*/.st
b960: 61 74 69 63 20 76 6f 69 64 20 70 75 74 73 56 61  atic void putsVa
b970: 72 69 6e 74 28 46 49 4c 45 20 2a 6f 75 74 2c 20  rint(FILE *out, 
b980: 73 71 6c 69 74 65 33 5f 75 69 6e 74 36 34 20 76  sqlite3_uint64 v
b990: 29 7b 0a 20 20 69 6e 74 20 69 2c 20 6e 3b 0a 20  ){.  int i, n;. 
b9a0: 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 70   unsigned char p
b9b0: 5b 31 32 5d 3b 0a 20 20 69 66 28 20 76 20 26 20  [12];.  if( v & 
b9c0: 28 28 28 73 71 6c 69 74 65 33 5f 75 69 6e 74 36  (((sqlite3_uint6
b9d0: 34 29 30 78 66 66 30 30 30 30 30 30 29 3c 3c 33  4)0xff000000)<<3
b9e0: 32 29 20 29 7b 0a 20 20 20 20 70 5b 38 5d 20 3d  2) ){.    p[8] =
b9f0: 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 29   (unsigned char)
ba00: 76 3b 0a 20 20 20 20 76 20 3e 3e 3d 20 38 3b 0a  v;.    v >>= 8;.
ba10: 20 20 20 20 66 6f 72 28 69 3d 37 3b 20 69 3e 3d      for(i=7; i>=
ba20: 30 3b 20 69 2d 2d 29 7b 0a 20 20 20 20 20 20 70  0; i--){.      p
ba30: 5b 69 5d 20 3d 20 28 75 6e 73 69 67 6e 65 64 20  [i] = (unsigned 
ba40: 63 68 61 72 29 28 28 76 20 26 20 30 78 37 66 29  char)((v & 0x7f)
ba50: 20 7c 20 30 78 38 30 29 3b 0a 20 20 20 20 20 20   | 0x80);.      
ba60: 76 20 3e 3e 3d 20 37 3b 0a 20 20 20 20 7d 0a 20  v >>= 7;.    }. 
ba70: 20 20 20 66 77 72 69 74 65 28 70 2c 20 38 2c 20     fwrite(p, 8, 
ba80: 31 2c 20 6f 75 74 29 3b 0a 20 20 7d 65 6c 73 65  1, out);.  }else
ba90: 7b 0a 20 20 20 20 6e 20 3d 20 39 3b 0a 20 20 20  {.    n = 9;.   
baa0: 20 64 6f 7b 0a 20 20 20 20 20 20 70 5b 6e 2d 2d   do{.      p[n--
bab0: 5d 20 3d 20 28 75 6e 73 69 67 6e 65 64 20 63 68  ] = (unsigned ch
bac0: 61 72 29 28 28 76 20 26 20 30 78 37 66 29 20 7c  ar)((v & 0x7f) |
bad0: 20 30 78 38 30 29 3b 0a 20 20 20 20 20 20 76 20   0x80);.      v 
bae0: 3e 3e 3d 20 37 3b 0a 20 20 20 20 7d 77 68 69 6c  >>= 7;.    }whil
baf0: 65 28 20 76 21 3d 30 20 29 3b 0a 20 20 20 20 70  e( v!=0 );.    p
bb00: 5b 39 5d 20 26 3d 20 30 78 37 66 3b 0a 20 20 20  [9] &= 0x7f;.   
bb10: 20 66 77 72 69 74 65 28 70 2b 6e 2b 31 2c 20 39   fwrite(p+n+1, 9
bb20: 2d 6e 2c 20 31 2c 20 6f 75 74 29 3b 0a 20 20 7d  -n, 1, out);.  }
bb30: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20  .}../*.** Write 
bb40: 61 6e 20 53 51 4c 69 74 65 20 76 61 6c 75 65 20  an SQLite value 
bb50: 6f 6e 74 6f 20 6f 75 74 2e 0a 2a 2f 0a 73 74 61  onto out..*/.sta
bb60: 74 69 63 20 76 6f 69 64 20 70 75 74 56 61 6c 75  tic void putValu
bb70: 65 28 46 49 4c 45 20 2a 6f 75 74 2c 20 73 71 6c  e(FILE *out, sql
bb80: 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c  ite3_value *pVal
bb90: 29 7b 0a 20 20 69 6e 74 20 69 44 54 79 70 65 20  ){.  int iDType 
bba0: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
bbb0: 74 79 70 65 28 70 56 61 6c 29 3b 0a 20 20 73 71  type(pVal);.  sq
bbc0: 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 58 3b 0a  lite3_int64 iX;.
bbd0: 20 20 64 6f 75 62 6c 65 20 72 58 3b 0a 20 20 73    double rX;.  s
bbe0: 71 6c 69 74 65 33 5f 75 69 6e 74 36 34 20 75 58  qlite3_uint64 uX
bbf0: 3b 0a 20 20 69 6e 74 20 6a 3b 0a 0a 20 20 70 75  ;.  int j;..  pu
bc00: 74 63 28 69 44 54 79 70 65 2c 20 6f 75 74 29 3b  tc(iDType, out);
bc10: 0a 20 20 73 77 69 74 63 68 28 20 69 44 54 79 70  .  switch( iDTyp
bc20: 65 20 29 7b 0a 20 20 20 20 63 61 73 65 20 53 51  e ){.    case SQ
bc30: 4c 49 54 45 5f 49 4e 54 45 47 45 52 3a 0a 20 20  LITE_INTEGER:.  
bc40: 20 20 20 20 69 58 20 3d 20 73 71 6c 69 74 65 33      iX = sqlite3
bc50: 5f 76 61 6c 75 65 5f 69 6e 74 36 34 28 70 56 61  _value_int64(pVa
bc60: 6c 29 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79  l);.      memcpy
bc70: 28 26 75 58 2c 20 26 69 58 2c 20 38 29 3b 0a 20  (&uX, &iX, 8);. 
bc80: 20 20 20 20 20 66 6f 72 28 6a 3d 35 36 3b 20 6a       for(j=56; j
bc90: 3e 3d 30 3b 20 6a 2d 3d 38 29 20 70 75 74 63 28  >=0; j-=8) putc(
bca0: 28 75 58 3e 3e 6a 29 26 30 78 66 66 2c 20 6f 75  (uX>>j)&0xff, ou
bcb0: 74 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  t);.      break;
bcc0: 0a 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45  .    case SQLITE
bcd0: 5f 46 4c 4f 41 54 3a 0a 20 20 20 20 20 20 72 58  _FLOAT:.      rX
bce0: 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65   = sqlite3_value
bcf0: 5f 64 6f 75 62 6c 65 28 70 56 61 6c 29 3b 0a 20  _double(pVal);. 
bd00: 20 20 20 20 20 6d 65 6d 63 70 79 28 26 75 58 2c       memcpy(&uX,
bd10: 20 26 72 58 2c 20 38 29 3b 0a 20 20 20 20 20 20   &rX, 8);.      
bd20: 66 6f 72 28 6a 3d 35 36 3b 20 6a 3e 3d 30 3b 20  for(j=56; j>=0; 
bd30: 6a 2d 3d 38 29 20 70 75 74 63 28 28 75 58 3e 3e  j-=8) putc((uX>>
bd40: 6a 29 26 30 78 66 66 2c 20 6f 75 74 29 3b 0a 20  j)&0xff, out);. 
bd50: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
bd60: 63 61 73 65 20 53 51 4c 49 54 45 5f 54 45 58 54  case SQLITE_TEXT
bd70: 3a 0a 20 20 20 20 20 20 69 58 20 3d 20 73 71 6c  :.      iX = sql
bd80: 69 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73  ite3_value_bytes
bd90: 28 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 70 75  (pVal);.      pu
bda0: 74 73 56 61 72 69 6e 74 28 6f 75 74 2c 20 28 73  tsVarint(out, (s
bdb0: 71 6c 69 74 65 33 5f 75 69 6e 74 36 34 29 69 58  qlite3_uint64)iX
bdc0: 29 3b 0a 20 20 20 20 20 20 66 77 72 69 74 65 28  );.      fwrite(
bdd0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65  sqlite3_value_te
bde0: 78 74 28 70 56 61 6c 29 2c 31 2c 28 73 69 7a 65  xt(pVal),1,(size
bdf0: 5f 74 29 69 58 2c 6f 75 74 29 3b 0a 20 20 20 20  _t)iX,out);.    
be00: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73    break;.    cas
be10: 65 20 53 51 4c 49 54 45 5f 42 4c 4f 42 3a 0a 20  e SQLITE_BLOB:. 
be20: 20 20 20 20 20 69 58 20 3d 20 73 71 6c 69 74 65       iX = sqlite
be30: 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 70 56  3_value_bytes(pV
be40: 61 6c 29 3b 0a 20 20 20 20 20 20 70 75 74 73 56  al);.      putsV
be50: 61 72 69 6e 74 28 6f 75 74 2c 20 28 73 71 6c 69  arint(out, (sqli
be60: 74 65 33 5f 75 69 6e 74 36 34 29 69 58 29 3b 0a  te3_uint64)iX);.
be70: 20 20 20 20 20 20 66 77 72 69 74 65 28 73 71 6c        fwrite(sql
be80: 69 74 65 33 5f 76 61 6c 75 65 5f 62 6c 6f 62 28  ite3_value_blob(
be90: 70 56 61 6c 29 2c 31 2c 28 73 69 7a 65 5f 74 29  pVal),1,(size_t)
bea0: 69 58 2c 6f 75 74 29 3b 0a 20 20 20 20 20 20 62  iX,out);.      b
beb0: 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 53  reak;.    case S
bec0: 51 4c 49 54 45 5f 4e 55 4c 4c 3a 0a 20 20 20 20  QLITE_NULL:.    
bed0: 20 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 7d 0a 0a    break;.  }.}..
bee0: 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65 20 61  /*.** Generate a
bef0: 20 43 48 41 4e 47 45 53 45 54 20 66 6f 72 20 61   CHANGESET for a
bf00: 6c 6c 20 64 69 66 66 65 72 65 6e 63 65 73 20 66  ll differences f
bf10: 72 6f 6d 20 6d 61 69 6e 2e 7a 54 61 62 20 74 6f  rom main.zTab to
bf20: 20 61 75 78 2e 7a 54 61 62 2e 0a 2a 2f 0a 73 74   aux.zTab..*/.st
bf30: 61 74 69 63 20 76 6f 69 64 20 63 68 61 6e 67 65  atic void change
bf40: 73 65 74 5f 6f 6e 65 5f 74 61 62 6c 65 28 63 6f  set_one_table(co
bf50: 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 62 2c 20  nst char *zTab, 
bf60: 46 49 4c 45 20 2a 6f 75 74 29 7b 0a 20 20 73 71  FILE *out){.  sq
bf70: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
bf80: 74 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53  t;          /* S
bf90: 51 4c 20 73 74 61 74 6d 65 6e 74 20 2a 2f 0a 20  QL statment */. 
bfa0: 20 63 68 61 72 20 2a 7a 49 64 20 3d 20 73 61 66   char *zId = saf
bfb0: 65 49 64 28 7a 54 61 62 29 3b 20 20 20 20 20 2f  eId(zTab);     /
bfc0: 2a 20 45 73 63 61 70 65 64 20 6e 61 6d 65 20 6f  * Escaped name o
bfd0: 66 20 74 68 65 20 74 61 62 6c 65 20 2a 2f 0a 20  f the table */. 
bfe0: 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6c 20 3d 20   char **azCol = 
bff0: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  0;             /
c000: 2a 20 4c 69 73 74 20 6f 66 20 65 73 63 61 70 65  * List of escape
c010: 64 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 2a  d column names *
c020: 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 20 3d 20 30  /.  int nCol = 0
c030: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
c040: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63    /* Number of c
c050: 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 69 6e 74 20  olumns */.  int 
c060: 2a 61 69 46 6c 67 20 3d 20 30 3b 20 20 20 20 20  *aiFlg = 0;     
c070: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 30 20 69            /* 0 i
c080: 66 20 63 6f 6c 75 6d 6e 20 69 73 20 6e 6f 74 20  f column is not 
c090: 70 61 72 74 20 6f 66 20 50 4b 20 2a 2f 0a 20 20  part of PK */.  
c0a0: 69 6e 74 20 2a 61 69 50 6b 20 3d 20 30 3b 20 20  int *aiPk = 0;  
c0b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c0c0: 20 43 6f 6c 75 6d 6e 20 6e 75 6d 62 65 72 73 20   Column numbers 
c0d0: 66 6f 72 20 65 61 63 68 20 50 4b 20 63 6f 6c 75  for each PK colu
c0e0: 6d 6e 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 6b 20  mn */.  int nPk 
c0f0: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
c100: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
c110: 6f 66 20 50 52 49 4d 41 52 59 20 4b 45 59 20 63  of PRIMARY KEY c
c120: 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 53 74 72 20  olumns */.  Str 
c130: 73 71 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  sql;            
c140: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 51 4c            /* SQL
c150: 20 66 6f 72 20 74 68 65 20 64 69 66 66 20 71 75   for the diff qu
c160: 65 72 79 20 2a 2f 0a 20 20 69 6e 74 20 69 2c 20  ery */.  int i, 
c170: 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k;              
c180: 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63         /* Loop c
c190: 6f 75 6e 74 65 72 73 20 2a 2f 0a 20 20 63 6f 6e  ounters */.  con
c1a0: 73 74 20 63 68 61 72 20 2a 7a 53 65 70 3b 20 20  st char *zSep;  
c1b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69             /* Li
c1c0: 73 74 20 73 65 70 61 72 61 74 6f 72 20 2a 2f 0a  st separator */.
c1d0: 0a 20 20 2f 2a 20 43 68 65 63 6b 20 74 68 61 74  .  /* Check that
c1e0: 20 74 68 65 20 73 63 68 65 6d 61 73 20 6f 66 20   the schemas of 
c1f0: 74 68 65 20 74 77 6f 20 74 61 62 6c 65 73 20 6d  the two tables m
c200: 61 74 63 68 2e 20 45 78 69 74 20 65 61 72 6c 79  atch. Exit early
c210: 20 6f 74 68 65 72 77 69 73 65 2e 20 2a 2f 0a 20   otherwise. */. 
c220: 20 63 68 65 63 6b 53 63 68 65 6d 61 73 4d 61 74   checkSchemasMat
c230: 63 68 28 7a 54 61 62 29 3b 0a 0a 20 20 70 53 74  ch(zTab);..  pSt
c240: 6d 74 20 3d 20 64 62 5f 70 72 65 70 61 72 65 28  mt = db_prepare(
c250: 22 50 52 41 47 4d 41 20 6d 61 69 6e 2e 74 61 62  "PRAGMA main.tab
c260: 6c 65 5f 69 6e 66 6f 3d 25 51 22 2c 20 7a 54 61  le_info=%Q", zTa
c270: 62 29 3b 0a 20 20 77 68 69 6c 65 28 20 53 51 4c  b);.  while( SQL
c280: 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33  ITE_ROW==sqlite3
c290: 5f 73 74 65 70 28 70 53 74 6d 74 29 20 29 7b 0a  _step(pStmt) ){.
c2a0: 20 20 20 20 6e 43 6f 6c 2b 2b 3b 0a 20 20 20 20      nCol++;.    
c2b0: 61 7a 43 6f 6c 20 3d 20 73 71 6c 69 74 65 33 5f  azCol = sqlite3_
c2c0: 72 65 61 6c 6c 6f 63 28 61 7a 43 6f 6c 2c 20 73  realloc(azCol, s
c2d0: 69 7a 65 6f 66 28 63 68 61 72 2a 29 2a 6e 43 6f  izeof(char*)*nCo
c2e0: 6c 29 3b 0a 20 20 20 20 69 66 28 20 61 7a 43 6f  l);.    if( azCo
c2f0: 6c 3d 3d 30 20 29 20 72 75 6e 74 69 6d 65 45 72  l==0 ) runtimeEr
c300: 72 6f 72 28 22 6f 75 74 20 6f 66 20 6d 65 6d 6f  ror("out of memo
c310: 72 79 22 29 3b 0a 20 20 20 20 61 69 46 6c 67 20  ry");.    aiFlg 
c320: 3d 20 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f  = sqlite3_reallo
c330: 63 28 61 69 46 6c 67 2c 20 73 69 7a 65 6f 66 28  c(aiFlg, sizeof(
c340: 69 6e 74 29 2a 6e 43 6f 6c 29 3b 0a 20 20 20 20  int)*nCol);.    
c350: 69 66 28 20 61 69 46 6c 67 3d 3d 30 20 29 20 72  if( aiFlg==0 ) r
c360: 75 6e 74 69 6d 65 45 72 72 6f 72 28 22 6f 75 74  untimeError("out
c370: 20 6f 66 20 6d 65 6d 6f 72 79 22 29 3b 0a 20 20   of memory");.  
c380: 20 20 61 7a 43 6f 6c 5b 6e 43 6f 6c 2d 31 5d 20    azCol[nCol-1] 
c390: 3d 20 73 61 66 65 49 64 28 28 63 6f 6e 73 74 20  = safeId((const 
c3a0: 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 63 6f  char*)sqlite3_co
c3b0: 6c 75 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c  lumn_text(pStmt,
c3c0: 31 29 29 3b 0a 20 20 20 20 61 69 46 6c 67 5b 6e  1));.    aiFlg[n
c3d0: 43 6f 6c 2d 31 5d 20 3d 20 69 20 3d 20 73 71 6c  Col-1] = i = sql
c3e0: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28  ite3_column_int(
c3f0: 70 53 74 6d 74 2c 35 29 3b 0a 20 20 20 20 69 66  pStmt,5);.    if
c400: 28 20 69 3e 30 20 29 7b 0a 20 20 20 20 20 20 69  ( i>0 ){.      i
c410: 66 28 20 69 3e 6e 50 6b 20 29 7b 0a 20 20 20 20  f( i>nPk ){.    
c420: 20 20 20 20 6e 50 6b 20 3d 20 69 3b 0a 20 20 20      nPk = i;.   
c430: 20 20 20 20 20 61 69 50 6b 20 3d 20 73 71 6c 69       aiPk = sqli
c440: 74 65 33 5f 72 65 61 6c 6c 6f 63 28 61 69 50 6b  te3_realloc(aiPk
c450: 2c 20 73 69 7a 65 6f 66 28 69 6e 74 29 2a 6e 50  , sizeof(int)*nP
c460: 6b 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  k);.        if( 
c470: 61 69 50 6b 3d 3d 30 20 29 20 72 75 6e 74 69 6d  aiPk==0 ) runtim
c480: 65 45 72 72 6f 72 28 22 6f 75 74 20 6f 66 20 6d  eError("out of m
c490: 65 6d 6f 72 79 22 29 3b 0a 20 20 20 20 20 20 7d  emory");.      }
c4a0: 0a 20 20 20 20 20 20 61 69 50 6b 5b 69 2d 31 5d  .      aiPk[i-1]
c4b0: 20 3d 20 6e 43 6f 6c 2d 31 3b 0a 20 20 20 20 7d   = nCol-1;.    }
c4c0: 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66  .  }.  sqlite3_f
c4d0: 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a  inalize(pStmt);.
c4e0: 20 20 69 66 28 20 6e 50 6b 3d 3d 30 20 29 20 67    if( nPk==0 ) g
c4f0: 6f 74 6f 20 65 6e 64 5f 63 68 61 6e 67 65 73 65  oto end_changese
c500: 74 5f 6f 6e 65 5f 74 61 62 6c 65 3b 20 0a 20 20  t_one_table; .  
c510: 73 74 72 49 6e 69 74 28 26 73 71 6c 29 3b 0a 20  strInit(&sql);. 
c520: 20 69 66 28 20 6e 43 6f 6c 3e 6e 50 6b 20 29 7b   if( nCol>nPk ){
c530: 0a 20 20 20 20 73 74 72 50 72 69 6e 74 66 28 26  .    strPrintf(&
c540: 73 71 6c 2c 20 22 53 45 4c 45 43 54 20 25 64 22  sql, "SELECT %d"
c550: 2c 20 53 51 4c 49 54 45 5f 55 50 44 41 54 45 29  , SQLITE_UPDATE)
c560: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69  ;.    for(i=0; i
c570: 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20  <nCol; i++){.   
c580: 20 20 20 69 66 28 20 61 69 46 6c 67 5b 69 5d 20     if( aiFlg[i] 
c590: 29 7b 0a 20 20 20 20 20 20 20 20 73 74 72 50 72  ){.        strPr
c5a0: 69 6e 74 66 28 26 73 71 6c 2c 20 22 2c 5c 6e 20  intf(&sql, ",\n 
c5b0: 20 20 20 20 20 20 41 2e 25 73 22 2c 20 61 7a 43        A.%s", azC
c5c0: 6f 6c 5b 69 5d 29 3b 0a 20 20 20 20 20 20 7d 65  ol[i]);.      }e
c5d0: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 73 74 72  lse{.        str
c5e0: 50 72 69 6e 74 66 28 26 73 71 6c 2c 20 22 2c 5c  Printf(&sql, ",\
c5f0: 6e 20 20 20 20 20 20 20 41 2e 25 73 20 49 53 20  n       A.%s IS 
c600: 4e 4f 54 20 42 2e 25 73 2c 20 41 2e 25 73 2c 20  NOT B.%s, A.%s, 
c610: 42 2e 25 73 22 2c 0a 20 20 20 20 20 20 20 20 20  B.%s",.         
c620: 20 20 20 20 20 20 20 20 20 61 7a 43 6f 6c 5b 69           azCol[i
c630: 5d 2c 20 61 7a 43 6f 6c 5b 69 5d 2c 20 61 7a 43  ], azCol[i], azC
c640: 6f 6c 5b 69 5d 2c 20 61 7a 43 6f 6c 5b 69 5d 29  ol[i], azCol[i])
c650: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
c660: 20 20 20 20 73 74 72 50 72 69 6e 74 66 28 26 73      strPrintf(&s
c670: 71 6c 2c 22 5c 6e 20 20 46 52 4f 4d 20 6d 61 69  ql,"\n  FROM mai
c680: 6e 2e 25 73 20 41 2c 20 61 75 78 2e 25 73 20 42  n.%s A, aux.%s B
c690: 5c 6e 22 2c 20 7a 49 64 2c 20 7a 49 64 29 3b 0a  \n", zId, zId);.
c6a0: 20 20 20 20 7a 53 65 70 20 3d 20 22 20 57 48 45      zSep = " WHE
c6b0: 52 45 22 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30  RE";.    for(i=0
c6c0: 3b 20 69 3c 6e 50 6b 3b 20 69 2b 2b 29 7b 0a 20  ; i<nPk; i++){. 
c6d0: 20 20 20 20 20 73 74 72 50 72 69 6e 74 66 28 26       strPrintf(&
c6e0: 73 71 6c 2c 20 22 25 73 20 41 2e 25 73 3d 42 2e  sql, "%s A.%s=B.
c6f0: 25 73 22 2c 20 7a 53 65 70 2c 20 61 7a 43 6f 6c  %s", zSep, azCol
c700: 5b 61 69 50 6b 5b 69 5d 5d 2c 20 61 7a 43 6f 6c  [aiPk[i]], azCol
c710: 5b 61 69 50 6b 5b 69 5d 5d 29 3b 0a 20 20 20 20  [aiPk[i]]);.    
c720: 20 20 7a 53 65 70 20 3d 20 22 20 41 4e 44 22 3b    zSep = " AND";
c730: 0a 20 20 20 20 7d 0a 20 20 20 20 7a 53 65 70 20  .    }.    zSep 
c740: 3d 20 22 5c 6e 20 20 20 41 4e 44 20 28 22 3b 0a  = "\n   AND (";.
c750: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e      for(i=0; i<n
c760: 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  Col; i++){.     
c770: 20 69 66 28 20 61 69 46 6c 67 5b 69 5d 20 29 20   if( aiFlg[i] ) 
c780: 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20  continue;.      
c790: 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c 2c 20  strPrintf(&sql, 
c7a0: 22 25 73 41 2e 25 73 20 49 53 20 4e 4f 54 20 42  "%sA.%s IS NOT B
c7b0: 2e 25 73 22 2c 20 7a 53 65 70 2c 20 61 7a 43 6f  .%s", zSep, azCo
c7c0: 6c 5b 69 5d 2c 20 61 7a 43 6f 6c 5b 69 5d 29 3b  l[i], azCol[i]);
c7d0: 0a 20 20 20 20 20 20 7a 53 65 70 20 3d 20 22 20  .      zSep = " 
c7e0: 4f 52 5c 6e 20 20 20 20 20 20 20 20 22 3b 0a 20  OR\n        ";. 
c7f0: 20 20 20 7d 0a 20 20 20 20 73 74 72 50 72 69 6e     }.    strPrin
c800: 74 66 28 26 73 71 6c 2c 22 29 5c 6e 20 55 4e 49  tf(&sql,")\n UNI
c810: 4f 4e 20 41 4c 4c 5c 6e 22 29 3b 0a 20 20 7d 0a  ON ALL\n");.  }.
c820: 20 20 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c    strPrintf(&sql
c830: 2c 20 22 53 45 4c 45 43 54 20 25 64 22 2c 20 53  , "SELECT %d", S
c840: 51 4c 49 54 45 5f 44 45 4c 45 54 45 29 3b 0a 20  QLITE_DELETE);. 
c850: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c   for(i=0; i<nCol
c860: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20  ; i++){.    if( 
c870: 61 69 46 6c 67 5b 69 5d 20 29 7b 0a 20 20 20 20  aiFlg[i] ){.    
c880: 20 20 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c    strPrintf(&sql
c890: 2c 20 22 2c 5c 6e 20 20 20 20 20 20 20 41 2e 25  , ",\n       A.%
c8a0: 73 22 2c 20 61 7a 43 6f 6c 5b 69 5d 29 3b 0a 20  s", azCol[i]);. 
c8b0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
c8c0: 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c 2c 20  strPrintf(&sql, 
c8d0: 22 2c 5c 6e 20 20 20 20 20 20 20 31 2c 20 41 2e  ",\n       1, A.
c8e0: 25 73 2c 20 4e 55 4c 4c 22 2c 20 61 7a 43 6f 6c  %s, NULL", azCol
c8f0: 5b 69 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  [i]);.    }.  }.
c900: 20 20 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c    strPrintf(&sql
c910: 2c 20 22 5c 6e 20 20 46 52 4f 4d 20 6d 61 69 6e  , "\n  FROM main
c920: 2e 25 73 20 41 5c 6e 22 2c 20 7a 49 64 29 3b 0a  .%s A\n", zId);.
c930: 20 20 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c    strPrintf(&sql
c940: 2c 20 22 20 57 48 45 52 45 20 4e 4f 54 20 45 58  , " WHERE NOT EX
c950: 49 53 54 53 28 53 45 4c 45 43 54 20 31 20 46 52  ISTS(SELECT 1 FR
c960: 4f 4d 20 61 75 78 2e 25 73 20 42 5c 6e 22 2c 20  OM aux.%s B\n", 
c970: 7a 49 64 29 3b 0a 20 20 7a 53 65 70 20 3d 20 20  zId);.  zSep =  
c980: 20 20 20 20 20 20 20 20 22 20 20 20 20 20 20 20          "       
c990: 20 20 20 20 20 20 20 20 20 20 20 20 57 48 45 52              WHER
c9a0: 45 22 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  E";.  for(i=0; i
c9b0: 3c 6e 50 6b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  <nPk; i++){.    
c9c0: 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c 2c 20  strPrintf(&sql, 
c9d0: 22 25 73 20 41 2e 25 73 3d 42 2e 25 73 22 2c 20  "%s A.%s=B.%s", 
c9e0: 7a 53 65 70 2c 20 61 7a 43 6f 6c 5b 61 69 50 6b  zSep, azCol[aiPk
c9f0: 5b 69 5d 5d 2c 20 61 7a 43 6f 6c 5b 61 69 50 6b  [i]], azCol[aiPk
ca00: 5b 69 5d 5d 29 3b 0a 20 20 20 20 7a 53 65 70 20  [i]]);.    zSep 
ca10: 3d 20 22 20 41 4e 44 22 3b 0a 20 20 7d 0a 20 20  = " AND";.  }.  
ca20: 73 74 72 50 72 69 6e 74 66 28 26 73 71 6c 2c 20  strPrintf(&sql, 
ca30: 22 29 5c 6e 20 55 4e 49 4f 4e 20 41 4c 4c 5c 6e  ")\n UNION ALL\n
ca40: 22 29 3b 0a 20 20 73 74 72 50 72 69 6e 74 66 28  ");.  strPrintf(
ca50: 26 73 71 6c 2c 20 22 53 45 4c 45 43 54 20 25 64  &sql, "SELECT %d
ca60: 22 2c 20 53 51 4c 49 54 45 5f 49 4e 53 45 52 54  ", SQLITE_INSERT
ca70: 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  );.  for(i=0; i<
ca80: 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  nCol; i++){.    
ca90: 69 66 28 20 61 69 46 6c 67 5b 69 5d 20 29 7b 0a  if( aiFlg[i] ){.
caa0: 20 20 20 20 20 20 73 74 72 50 72 69 6e 74 66 28        strPrintf(
cab0: 26 73 71 6c 2c 20 22 2c 5c 6e 20 20 20 20 20 20  &sql, ",\n      
cac0: 20 42 2e 25 73 22 2c 20 61 7a 43 6f 6c 5b 69 5d   B.%s", azCol[i]
cad0: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
cae0: 20 20 20 20 73 74 72 50 72 69 6e 74 66 28 26 73      strPrintf(&s
caf0: 71 6c 2c 20 22 2c 5c 6e 20 20 20 20 20 20 20 31  ql, ",\n       1
cb00: 2c 20 4e 55 4c 4c 2c 20 42 2e 25 73 22 2c 20 61  , NULL, B.%s", a
cb10: 7a 43 6f 6c 5b 69 5d 29 3b 0a 20 20 20 20 7d 0a  zCol[i]);.    }.
cb20: 20 20 7d 0a 20 20 73 74 72 50 72 69 6e 74 66 28    }.  strPrintf(
cb30: 26 73 71 6c 2c 20 22 5c 6e 20 20 46 52 4f 4d 20  &sql, "\n  FROM 
cb40: 61 75 78 2e 25 73 20 42 5c 6e 22 2c 20 7a 49 64  aux.%s B\n", zId
cb50: 29 3b 0a 20 20 73 74 72 50 72 69 6e 74 66 28 26  );.  strPrintf(&
cb60: 73 71 6c 2c 20 22 20 57 48 45 52 45 20 4e 4f 54  sql, " WHERE NOT
cb70: 20 45 58 49 53 54 53 28 53 45 4c 45 43 54 20 31   EXISTS(SELECT 1
cb80: 20 46 52 4f 4d 20 6d 61 69 6e 2e 25 73 20 41 5c   FROM main.%s A\
cb90: 6e 22 2c 20 7a 49 64 29 3b 0a 20 20 7a 53 65 70  n", zId);.  zSep
cba0: 20 3d 20 20 20 20 20 20 20 20 20 20 22 20 20 20   =          "   
cbb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cbc0: 57 48 45 52 45 22 3b 0a 20 20 66 6f 72 28 69 3d  WHERE";.  for(i=
cbd0: 30 3b 20 69 3c 6e 50 6b 3b 20 69 2b 2b 29 7b 0a  0; i<nPk; i++){.
cbe0: 20 20 20 20 73 74 72 50 72 69 6e 74 66 28 26 73      strPrintf(&s
cbf0: 71 6c 2c 20 22 25 73 20 41 2e 25 73 3d 42 2e 25  ql, "%s A.%s=B.%
cc00: 73 22 2c 20 7a 53 65 70 2c 20 61 7a 43 6f 6c 5b  s", zSep, azCol[
cc10: 61 69 50 6b 5b 69 5d 5d 2c 20 61 7a 43 6f 6c 5b  aiPk[i]], azCol[
cc20: 61 69 50 6b 5b 69 5d 5d 29 3b 0a 20 20 20 20 7a  aiPk[i]]);.    z
cc30: 53 65 70 20 3d 20 22 20 41 4e 44 22 3b 0a 20 20  Sep = " AND";.  
cc40: 7d 0a 20 20 73 74 72 50 72 69 6e 74 66 28 26 73  }.  strPrintf(&s
cc50: 71 6c 2c 20 22 29 5c 6e 22 29 3b 0a 20 20 73 74  ql, ")\n");.  st
cc60: 72 50 72 69 6e 74 66 28 26 73 71 6c 2c 20 22 20  rPrintf(&sql, " 
cc70: 4f 52 44 45 52 20 42 59 22 29 3b 0a 20 20 7a 53  ORDER BY");.  zS
cc80: 65 70 20 3d 20 22 20 22 3b 0a 20 20 66 6f 72 28  ep = " ";.  for(
cc90: 69 3d 30 3b 20 69 3c 6e 50 6b 3b 20 69 2b 2b 29  i=0; i<nPk; i++)
cca0: 7b 0a 20 20 20 20 73 74 72 50 72 69 6e 74 66 28  {.    strPrintf(
ccb0: 26 73 71 6c 2c 20 22 25 73 20 25 64 22 2c 20 7a  &sql, "%s %d", z
ccc0: 53 65 70 2c 20 61 69 50 6b 5b 69 5d 2b 32 29 3b  Sep, aiPk[i]+2);
ccd0: 0a 20 20 20 20 7a 53 65 70 20 3d 20 22 2c 22 3b  .    zSep = ",";
cce0: 0a 20 20 7d 0a 20 20 73 74 72 50 72 69 6e 74 66  .  }.  strPrintf
ccf0: 28 26 73 71 6c 2c 20 22 3b 5c 6e 22 29 3b 0a 0a  (&sql, ";\n");..
cd00: 20 20 69 66 28 20 67 2e 66 44 65 62 75 67 20 26    if( g.fDebug &
cd10: 20 44 45 42 55 47 5f 44 49 46 46 5f 53 51 4c 20   DEBUG_DIFF_SQL 
cd20: 29 7b 20 0a 20 20 20 20 70 72 69 6e 74 66 28 22  ){ .    printf("
cd30: 53 51 4c 20 66 6f 72 20 25 73 3a 5c 6e 25 73 5c  SQL for %s:\n%s\
cd40: 6e 22 2c 20 7a 49 64 2c 20 73 71 6c 2e 7a 29 3b  n", zId, sql.z);
cd50: 0a 20 20 20 20 67 6f 74 6f 20 65 6e 64 5f 63 68  .    goto end_ch
cd60: 61 6e 67 65 73 65 74 5f 6f 6e 65 5f 74 61 62 6c  angeset_one_tabl
cd70: 65 3b 0a 20 20 7d 0a 0a 20 20 70 75 74 63 28 27  e;.  }..  putc('
cd80: 54 27 2c 20 6f 75 74 29 3b 0a 20 20 70 75 74 73  T', out);.  puts
cd90: 56 61 72 69 6e 74 28 6f 75 74 2c 20 28 73 71 6c  Varint(out, (sql
cda0: 69 74 65 33 5f 75 69 6e 74 36 34 29 6e 43 6f 6c  ite3_uint64)nCol
cdb0: 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  );.  for(i=0; i<
cdc0: 6e 43 6f 6c 3b 20 69 2b 2b 29 20 70 75 74 63 28  nCol; i++) putc(
cdd0: 61 69 46 6c 67 5b 69 5d 21 3d 30 2c 20 6f 75 74  aiFlg[i]!=0, out
cde0: 29 3b 0a 20 20 66 77 72 69 74 65 28 7a 54 61 62  );.  fwrite(zTab
cdf0: 2c 20 31 2c 20 73 74 72 6c 65 6e 28 7a 54 61 62  , 1, strlen(zTab
ce00: 29 2c 20 6f 75 74 29 3b 0a 20 20 70 75 74 63 28  ), out);.  putc(
ce10: 30 2c 20 6f 75 74 29 3b 0a 0a 20 20 70 53 74 6d  0, out);..  pStm
ce20: 74 20 3d 20 64 62 5f 70 72 65 70 61 72 65 28 22  t = db_prepare("
ce30: 25 73 22 2c 20 73 71 6c 2e 7a 29 3b 0a 20 20 77  %s", sql.z);.  w
ce40: 68 69 6c 65 28 20 53 51 4c 49 54 45 5f 52 4f 57  hile( SQLITE_ROW
ce50: 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70  ==sqlite3_step(p
ce60: 53 74 6d 74 29 20 29 7b 0a 20 20 20 20 69 6e 74  Stmt) ){.    int
ce70: 20 69 54 79 70 65 20 3d 20 73 71 6c 69 74 65 33   iType = sqlite3
ce80: 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d  _column_int(pStm
ce90: 74 2c 30 29 3b 0a 20 20 20 20 70 75 74 63 28 69  t,0);.    putc(i
cea0: 54 79 70 65 2c 20 6f 75 74 29 3b 0a 20 20 20 20  Type, out);.    
ceb0: 70 75 74 63 28 30 2c 20 6f 75 74 29 3b 0a 20 20  putc(0, out);.  
cec0: 20 20 73 77 69 74 63 68 28 20 73 71 6c 69 74 65    switch( sqlite
ced0: 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53 74  3_column_int(pSt
cee0: 6d 74 2c 30 29 20 29 7b 0a 20 20 20 20 20 20 63  mt,0) ){.      c
cef0: 61 73 65 20 53 51 4c 49 54 45 5f 55 50 44 41 54  ase SQLITE_UPDAT
cf00: 45 3a 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72  E: {.        for
cf10: 28 6b 3d 31 2c 20 69 3d 30 3b 20 69 3c 6e 43 6f  (k=1, i=0; i<nCo
cf20: 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20  l; i++){.       
cf30: 20 20 20 69 66 28 20 61 69 46 6c 67 5b 69 5d 20     if( aiFlg[i] 
cf40: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  ){.            p
cf50: 75 74 56 61 6c 75 65 28 6f 75 74 2c 20 73 71 6c  utValue(out, sql
cf60: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75  ite3_column_valu
cf70: 65 28 70 53 74 6d 74 2c 6b 29 29 3b 0a 20 20 20  e(pStmt,k));.   
cf80: 20 20 20 20 20 20 20 20 20 6b 2b 2b 3b 0a 20 20           k++;.  
cf90: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66          }else if
cfa0: 28 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  ( sqlite3_column
cfb0: 5f 69 6e 74 28 70 53 74 6d 74 2c 6b 29 20 29 7b  _int(pStmt,k) ){
cfc0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 75 74  .            put
cfd0: 56 61 6c 75 65 28 6f 75 74 2c 20 73 71 6c 69 74  Value(out, sqlit
cfe0: 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28  e3_column_value(
cff0: 70 53 74 6d 74 2c 6b 2b 31 29 29 3b 0a 20 20 20  pStmt,k+1));.   
d000: 20 20 20 20 20 20 20 20 20 6b 20 2b 3d 20 33 3b           k += 3;
d010: 0a 20 20 20 20 20 20 20 20 20 20 7d 65 6c 73 65  .          }else
d020: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 75  {.            pu
d030: 74 63 28 30 2c 20 6f 75 74 29 3b 0a 20 20 20 20  tc(0, out);.    
d040: 20 20 20 20 20 20 20 20 6b 20 2b 3d 20 33 3b 0a          k += 3;.
d050: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
d060: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 66 6f      }.        fo
d070: 72 28 6b 3d 31 2c 20 69 3d 30 3b 20 69 3c 6e 43  r(k=1, i=0; i<nC
d080: 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  ol; i++){.      
d090: 20 20 20 20 69 66 28 20 61 69 46 6c 67 5b 69 5d      if( aiFlg[i]
d0a0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
d0b0: 70 75 74 63 28 30 2c 20 6f 75 74 29 3b 0a 20 20  putc(0, out);.  
d0c0: 20 20 20 20 20 20 20 20 20 20 6b 2b 2b 3b 0a 20            k++;. 
d0d0: 20 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69           }else i
d0e0: 66 28 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  f( sqlite3_colum
d0f0: 6e 5f 69 6e 74 28 70 53 74 6d 74 2c 6b 29 20 29  n_int(pStmt,k) )
d100: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 75  {.            pu
d110: 74 56 61 6c 75 65 28 6f 75 74 2c 20 73 71 6c 69  tValue(out, sqli
d120: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65  te3_column_value
d130: 28 70 53 74 6d 74 2c 6b 2b 32 29 29 3b 0a 20 20  (pStmt,k+2));.  
d140: 20 20 20 20 20 20 20 20 20 20 6b 20 2b 3d 20 33            k += 3
d150: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 65 6c 73  ;.          }els
d160: 65 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  e{.            p
d170: 75 74 63 28 30 2c 20 6f 75 74 29 3b 0a 20 20 20  utc(0, out);.   
d180: 20 20 20 20 20 20 20 20 20 6b 20 2b 3d 20 33 3b           k += 3;
d190: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
d1a0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 62       }.        b
d1b0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  reak;.      }.  
d1c0: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
d1d0: 49 4e 53 45 52 54 3a 20 7b 0a 20 20 20 20 20 20  INSERT: {.      
d1e0: 20 20 66 6f 72 28 6b 3d 31 2c 20 69 3d 30 3b 20    for(k=1, i=0; 
d1f0: 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20  i<nCol; i++){.  
d200: 20 20 20 20 20 20 20 20 69 66 28 20 61 69 46 6c          if( aiFl
d210: 67 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20 20 20  g[i] ){.        
d220: 20 20 20 20 70 75 74 56 61 6c 75 65 28 6f 75 74      putValue(out
d230: 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  , sqlite3_column
d240: 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 6b 29 29  _value(pStmt,k))
d250: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 6b 2b  ;.            k+
d260: 2b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 65 6c  +;.          }el
d270: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  se{.            
d280: 70 75 74 56 61 6c 75 65 28 6f 75 74 2c 20 73 71  putValue(out, sq
d290: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c  lite3_column_val
d2a0: 75 65 28 70 53 74 6d 74 2c 6b 2b 32 29 29 3b 0a  ue(pStmt,k+2));.
d2b0: 20 20 20 20 20 20 20 20 20 20 20 20 6b 20 2b 3d              k +=
d2c0: 20 33 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a   3;.          }.
d2d0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
d2e0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d    break;.      }
d2f0: 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
d300: 54 45 5f 44 45 4c 45 54 45 3a 20 7b 0a 20 20 20  TE_DELETE: {.   
d310: 20 20 20 20 20 66 6f 72 28 6b 3d 31 2c 20 69 3d       for(k=1, i=
d320: 30 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b  0; i<nCol; i++){
d330: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 61  .          if( a
d340: 69 46 6c 67 5b 69 5d 20 29 7b 0a 20 20 20 20 20  iFlg[i] ){.     
d350: 20 20 20 20 20 20 20 70 75 74 56 61 6c 75 65 28         putValue(
d360: 6f 75 74 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c  out, sqlite3_col
d370: 75 6d 6e 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c  umn_value(pStmt,
d380: 6b 29 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  k));.           
d390: 20 6b 2b 2b 3b 0a 20 20 20 20 20 20 20 20 20 20   k++;.          
d3a0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20  }else{.         
d3b0: 20 20 20 70 75 74 56 61 6c 75 65 28 6f 75 74 2c     putValue(out,
d3c0: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
d3d0: 76 61 6c 75 65 28 70 53 74 6d 74 2c 6b 2b 31 29  value(pStmt,k+1)
d3e0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 6b  );.            k
d3f0: 20 2b 3d 20 33 3b 0a 20 20 20 20 20 20 20 20 20   += 3;.         
d400: 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20   }.        }.   
d410: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
d420: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20    }.    }.  }.  
d430: 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65  sqlite3_finalize
d440: 28 70 53 74 6d 74 29 3b 0a 20 20 0a 65 6e 64 5f  (pStmt);.  .end_
d450: 63 68 61 6e 67 65 73 65 74 5f 6f 6e 65 5f 74 61  changeset_one_ta
d460: 62 6c 65 3a 0a 20 20 77 68 69 6c 65 28 20 6e 43  ble:.  while( nC
d470: 6f 6c 3e 30 20 29 20 73 71 6c 69 74 65 33 5f 66  ol>0 ) sqlite3_f
d480: 72 65 65 28 61 7a 43 6f 6c 5b 2d 2d 6e 43 6f 6c  ree(azCol[--nCol
d490: 5d 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  ]);.  sqlite3_fr
d4a0: 65 65 28 61 7a 43 6f 6c 29 3b 0a 20 20 73 71 6c  ee(azCol);.  sql
d4b0: 69 74 65 33 5f 66 72 65 65 28 61 69 50 6b 29 3b  ite3_free(aiPk);
d4c0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
d4d0: 7a 49 64 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50  zId);.}../*.** P
d4e0: 72 69 6e 74 20 73 6b 65 74 63 68 79 20 64 6f 63  rint sketchy doc
d4f0: 75 6d 65 6e 74 61 74 69 6f 6e 20 66 6f 72 20 74  umentation for t
d500: 68 69 73 20 75 74 69 6c 69 74 79 20 70 72 6f 67  his utility prog
d510: 72 61 6d 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ram.*/.static vo
d520: 69 64 20 73 68 6f 77 48 65 6c 70 28 76 6f 69 64  id showHelp(void
d530: 29 7b 0a 20 20 70 72 69 6e 74 66 28 22 55 73 61  ){.  printf("Usa
d540: 67 65 3a 20 25 73 20 5b 6f 70 74 69 6f 6e 73 5d  ge: %s [options]
d550: 20 44 42 31 20 44 42 32 5c 6e 22 2c 20 67 2e 7a   DB1 DB2\n", g.z
d560: 41 72 67 76 30 29 3b 0a 20 20 70 72 69 6e 74 66  Argv0);.  printf
d570: 28 0a 22 4f 75 74 70 75 74 20 53 51 4c 20 74 65  (."Output SQL te
d580: 78 74 20 74 68 61 74 20 77 6f 75 6c 64 20 74 72  xt that would tr
d590: 61 6e 73 66 6f 72 6d 20 44 42 31 20 69 6e 74 6f  ansform DB1 into
d5a0: 20 44 42 32 2e 5c 6e 22 0a 22 4f 70 74 69 6f 6e   DB2.\n"."Option
d5b0: 73 3a 5c 6e 22 0a 22 20 20 2d 2d 63 68 61 6e 67  s:\n"."  --chang
d5c0: 65 73 65 74 20 46 49 4c 45 20 20 20 20 20 20 57  eset FILE      W
d5d0: 72 69 74 65 20 61 20 43 48 41 4e 47 45 53 45 54  rite a CHANGESET
d5e0: 20 69 6e 74 6f 20 46 49 4c 45 5c 6e 22 0a 22 20   into FILE\n"." 
d5f0: 20 2d 4c 7c 2d 2d 6c 69 62 20 4c 49 42 52 41 52   -L|--lib LIBRAR
d600: 59 20 20 20 20 20 20 4c 6f 61 64 20 61 6e 20 53  Y      Load an S
d610: 51 4c 69 74 65 20 65 78 74 65 6e 73 69 6f 6e 20  QLite extension 
d620: 6c 69 62 72 61 72 79 5c 6e 22 0a 22 20 20 2d 2d  library\n"."  --
d630: 70 72 69 6d 61 72 79 6b 65 79 20 20 20 20 20 20  primarykey      
d640: 20 20 20 20 55 73 65 20 73 63 68 65 6d 61 2d 64      Use schema-d
d650: 65 66 69 6e 65 64 20 50 52 49 4d 41 52 59 20 4b  efined PRIMARY K
d660: 45 59 73 5c 6e 22 0a 22 20 20 2d 2d 72 62 75 20  EYs\n"."  --rbu 
d670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d680: 4f 75 74 70 75 74 20 53 51 4c 20 74 6f 20 63 72  Output SQL to cr
d690: 65 61 74 65 2f 70 6f 70 75 6c 61 74 65 20 52 42  eate/populate RB
d6a0: 55 20 74 61 62 6c 65 28 73 29 5c 6e 22 0a 22 20  U table(s)\n"." 
d6b0: 20 2d 2d 73 63 68 65 6d 61 20 20 20 20 20 20 20   --schema       
d6c0: 20 20 20 20 20 20 20 53 68 6f 77 20 6f 6e 6c 79         Show only
d6d0: 20 64 69 66 66 65 72 65 6e 63 65 73 20 69 6e 20   differences in 
d6e0: 74 68 65 20 73 63 68 65 6d 61 5c 6e 22 0a 22 20  the schema\n"." 
d6f0: 20 2d 2d 73 75 6d 6d 61 72 79 20 20 20 20 20 20   --summary      
d700: 20 20 20 20 20 20 20 53 68 6f 77 20 6f 6e 6c 79         Show only
d710: 20 61 20 73 75 6d 6d 61 72 79 20 6f 66 20 74 68   a summary of th
d720: 65 20 64 69 66 66 65 72 65 6e 63 65 73 5c 6e 22  e differences\n"
d730: 0a 22 20 20 2d 2d 74 61 62 6c 65 20 54 41 42 20  ."  --table TAB 
d740: 20 20 20 20 20 20 20 20 20 20 53 68 6f 77 20 6f            Show o
d750: 6e 6c 79 20 64 69 66 66 65 72 65 6e 63 65 73 20  nly differences 
d760: 69 6e 20 74 61 62 6c 65 20 54 41 42 5c 6e 22 0a  in table TAB\n".
d770: 22 20 20 2d 2d 74 72 61 6e 73 61 63 74 69 6f 6e  "  --transaction
d780: 20 20 20 20 20 20 20 20 20 53 68 6f 77 20 53 51           Show SQ
d790: 4c 20 6f 75 74 70 75 74 20 69 6e 73 69 64 65 20  L output inside 
d7a0: 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 5c 6e 22  a transaction\n"
d7b0: 0a 20 20 29 3b 0a 7d 0a 0a 69 6e 74 20 6d 61 69  .  );.}..int mai
d7c0: 6e 28 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72  n(int argc, char
d7d0: 20 2a 2a 61 72 67 76 29 7b 0a 20 20 63 6f 6e 73   **argv){.  cons
d7e0: 74 20 63 68 61 72 20 2a 7a 44 62 31 20 3d 20 30  t char *zDb1 = 0
d7f0: 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ;.  const char *
d800: 7a 44 62 32 20 3d 20 30 3b 0a 20 20 69 6e 74 20  zDb2 = 0;.  int 
d810: 69 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 63  i;.  int rc;.  c
d820: 68 61 72 20 2a 7a 45 72 72 4d 73 67 20 3d 20 30  har *zErrMsg = 0
d830: 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a  ;.  char *zSql;.
d840: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
d850: 70 53 74 6d 74 3b 0a 20 20 63 68 61 72 20 2a 7a  pStmt;.  char *z
d860: 54 61 62 20 3d 20 30 3b 0a 20 20 46 49 4c 45 20  Tab = 0;.  FILE 
d870: 2a 6f 75 74 20 3d 20 73 74 64 6f 75 74 3b 0a 20  *out = stdout;. 
d880: 20 76 6f 69 64 20 28 2a 78 44 69 66 66 29 28 63   void (*xDiff)(c
d890: 6f 6e 73 74 20 63 68 61 72 2a 2c 46 49 4c 45 2a  onst char*,FILE*
d8a0: 29 20 3d 20 64 69 66 66 5f 6f 6e 65 5f 74 61 62  ) = diff_one_tab
d8b0: 6c 65 3b 0a 20 20 69 6e 74 20 6e 45 78 74 20 3d  le;.  int nExt =
d8c0: 20 30 3b 0a 20 20 63 68 61 72 20 2a 2a 61 7a 45   0;.  char **azE
d8d0: 78 74 20 3d 20 30 3b 0a 20 20 69 6e 74 20 75 73  xt = 0;.  int us
d8e0: 65 54 72 61 6e 73 61 63 74 69 6f 6e 20 3d 20 30  eTransaction = 0
d8f0: 3b 0a 20 20 69 6e 74 20 6e 65 76 65 72 55 73 65  ;.  int neverUse
d900: 54 72 61 6e 73 61 63 74 69 6f 6e 20 3d 20 30 3b  Transaction = 0;
d910: 0a 0a 20 20 67 2e 7a 41 72 67 76 30 20 3d 20 61  ..  g.zArgv0 = a
d920: 72 67 76 5b 30 5d 3b 0a 20 20 73 71 6c 69 74 65  rgv[0];.  sqlite
d930: 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f  3_config(SQLITE_
d940: 43 4f 4e 46 49 47 5f 53 49 4e 47 4c 45 54 48 52  CONFIG_SINGLETHR
d950: 45 41 44 29 3b 0a 20 20 66 6f 72 28 69 3d 31 3b  EAD);.  for(i=1;
d960: 20 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20   i<argc; i++){. 
d970: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
d980: 20 3d 20 61 72 67 76 5b 69 5d 3b 0a 20 20 20 20   = argv[i];.    
d990: 69 66 28 20 7a 5b 30 5d 3d 3d 27 2d 27 20 29 7b  if( z[0]=='-' ){
d9a0: 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20  .      z++;.    
d9b0: 20 20 69 66 28 20 7a 5b 30 5d 3d 3d 27 2d 27 20    if( z[0]=='-' 
d9c0: 29 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 69 66 28  ) z++;.      if(
d9d0: 20 73 74 72 63 6d 70 28 7a 2c 22 63 68 61 6e 67   strcmp(z,"chang
d9e0: 65 73 65 74 22 29 3d 3d 30 20 29 7b 0a 20 20 20  eset")==0 ){.   
d9f0: 20 20 20 20 20 69 66 28 20 69 3d 3d 61 72 67 63       if( i==argc
da00: 2d 31 20 29 20 63 6d 64 6c 69 6e 65 45 72 72 6f  -1 ) cmdlineErro
da10: 72 28 22 6d 69 73 73 69 6e 67 20 61 72 67 75 6d  r("missing argum
da20: 65 6e 74 20 74 6f 20 25 73 22 2c 20 61 72 67 76  ent to %s", argv
da30: 5b 69 5d 29 3b 0a 20 20 20 20 20 20 20 20 6f 75  [i]);.        ou
da40: 74 20 3d 20 66 6f 70 65 6e 28 61 72 67 76 5b 2b  t = fopen(argv[+
da50: 2b 69 5d 2c 20 22 77 62 22 29 3b 0a 20 20 20 20  +i], "wb");.    
da60: 20 20 20 20 69 66 28 20 6f 75 74 3d 3d 30 20 29      if( out==0 )
da70: 20 63 6d 64 6c 69 6e 65 45 72 72 6f 72 28 22 63   cmdlineError("c
da80: 61 6e 6e 6f 74 20 6f 70 65 6e 3a 20 25 73 22 2c  annot open: %s",
da90: 20 61 72 67 76 5b 69 5d 29 3b 0a 20 20 20 20 20   argv[i]);.     
daa0: 20 20 20 78 44 69 66 66 20 3d 20 63 68 61 6e 67     xDiff = chang
dab0: 65 73 65 74 5f 6f 6e 65 5f 74 61 62 6c 65 3b 0a  eset_one_table;.
dac0: 20 20 20 20 20 20 20 20 6e 65 76 65 72 55 73 65          neverUse
dad0: 54 72 61 6e 73 61 63 74 69 6f 6e 20 3d 20 31 3b  Transaction = 1;
dae0: 0a 20 20 20 20 20 20 7d 65 6c 73 65 0a 20 20 20  .      }else.   
daf0: 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a 2c     if( strcmp(z,
db00: 22 64 65 62 75 67 22 29 3d 3d 30 20 29 7b 0a 20  "debug")==0 ){. 
db10: 20 20 20 20 20 20 20 69 66 28 20 69 3d 3d 61 72         if( i==ar
db20: 67 63 2d 31 20 29 20 63 6d 64 6c 69 6e 65 45 72  gc-1 ) cmdlineEr
db30: 72 6f 72 28 22 6d 69 73 73 69 6e 67 20 61 72 67  ror("missing arg
db40: 75 6d 65 6e 74 20 74 6f 20 25 73 22 2c 20 61 72  ument to %s", ar
db50: 67 76 5b 69 5d 29 3b 0a 20 20 20 20 20 20 20 20  gv[i]);.        
db60: 67 2e 66 44 65 62 75 67 20 3d 20 73 74 72 74 6f  g.fDebug = strto
db70: 6c 28 61 72 67 76 5b 2b 2b 69 5d 2c 20 30 2c 20  l(argv[++i], 0, 
db80: 30 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 0a  0);.      }else.
db90: 20 20 20 20 20 20 69 66 28 20 73 74 72 63 6d 70        if( strcmp
dba0: 28 7a 2c 22 68 65 6c 70 22 29 3d 3d 30 20 29 7b  (z,"help")==0 ){
dbb0: 0a 20 20 20 20 20 20 20 20 73 68 6f 77 48 65 6c  .        showHel
dbc0: 70 28 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74  p();.        ret
dbd0: 75 72 6e 20 30 3b 0a 20 20 20 20 20 20 7d 65 6c  urn 0;.      }el
dbe0: 73 65 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54  se.#ifndef SQLIT
dbf0: 45 5f 4f 4d 49 54 5f 4c 4f 41 44 5f 45 58 54 45  E_OMIT_LOAD_EXTE
dc00: 4e 53 49 4f 4e 0a 20 20 20 20 20 20 69 66 28 20  NSION.      if( 
dc10: 73 74 72 63 6d 70 28 7a 2c 22 6c 69 62 22 29 3d  strcmp(z,"lib")=
dc20: 3d 30 20 7c 7c 20 73 74 72 63 6d 70 28 7a 2c 22  =0 || strcmp(z,"
dc30: 4c 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  L")==0 ){.      
dc40: 20 20 69 66 28 20 69 3d 3d 61 72 67 63 2d 31 20    if( i==argc-1 
dc50: 29 20 63 6d 64 6c 69 6e 65 45 72 72 6f 72 28 22  ) cmdlineError("
dc60: 6d 69 73 73 69 6e 67 20 61 72 67 75 6d 65 6e 74  missing argument
dc70: 20 74 6f 20 25 73 22 2c 20 61 72 67 76 5b 69 5d   to %s", argv[i]
dc80: 29 3b 0a 20 20 20 20 20 20 20 20 61 7a 45 78 74  );.        azExt
dc90: 20 3d 20 72 65 61 6c 6c 6f 63 28 61 7a 45 78 74   = realloc(azExt
dca0: 2c 20 73 69 7a 65 6f 66 28 61 7a 45 78 74 5b 30  , sizeof(azExt[0
dcb0: 5d 29 2a 28 6e 45 78 74 2b 31 29 29 3b 0a 20 20  ])*(nExt+1));.  
dcc0: 20 20 20 20 20 20 69 66 28 20 61 7a 45 78 74 3d        if( azExt=
dcd0: 3d 30 20 29 20 63 6d 64 6c 69 6e 65 45 72 72 6f  =0 ) cmdlineErro
dce0: 72 28 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79  r("out of memory
dcf0: 22 29 3b 0a 20 20 20 20 20 20 20 20 61 7a 45 78  ");.        azEx
dd00: 74 5b 6e 45 78 74 2b 2b 5d 20 3d 20 61 72 67 76  t[nExt++] = argv
dd10: 5b 2b 2b 69 5d 3b 0a 20 20 20 20 20 20 7d 65 6c  [++i];.      }el
dd20: 73 65 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20  se.#endif.      
dd30: 69 66 28 20 73 74 72 63 6d 70 28 7a 2c 22 70 72  if( strcmp(z,"pr
dd40: 69 6d 61 72 79 6b 65 79 22 29 3d 3d 30 20 29 7b  imarykey")==0 ){
dd50: 0a 20 20 20 20 20 20 20 20 67 2e 62 53 63 68 65  .        g.bSche
dd60: 6d 61 50 4b 20 3d 20 31 3b 0a 20 20 20 20 20 20  maPK = 1;.      
dd70: 7d 65 6c 73 65 0a 20 20 20 20 20 20 69 66 28 20  }else.      if( 
dd80: 73 74 72 63 6d 70 28 7a 2c 22 72 62 75 22 29 3d  strcmp(z,"rbu")=
dd90: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 78 44  =0 ){.        xD
dda0: 69 66 66 20 3d 20 72 62 75 64 69 66 66 5f 6f 6e  iff = rbudiff_on
ddb0: 65 5f 74 61 62 6c 65 3b 0a 20 20 20 20 20 20 7d  e_table;.      }
ddc0: 65 6c 73 65 0a 20 20 20 20 20 20 69 66 28 20 73  else.      if( s
ddd0: 74 72 63 6d 70 28 7a 2c 22 73 63 68 65 6d 61 22  trcmp(z,"schema"
dde0: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  )==0 ){.        
ddf0: 67 2e 62 53 63 68 65 6d 61 4f 6e 6c 79 20 3d 20  g.bSchemaOnly = 
de00: 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 0a 20  1;.      }else. 
de10: 20 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28       if( strcmp(
de20: 7a 2c 22 73 75 6d 6d 61 72 79 22 29 3d 3d 30 20  z,"summary")==0 
de30: 29 7b 0a 20 20 20 20 20 20 20 20 78 44 69 66 66  ){.        xDiff
de40: 20 3d 20 73 75 6d 6d 61 72 69 7a 65 5f 6f 6e 65   = summarize_one
de50: 5f 74 61 62 6c 65 3b 0a 20 20 20 20 20 20 7d 65  _table;.      }e
de60: 6c 73 65 0a 20 20 20 20 20 20 69 66 28 20 73 74  lse.      if( st
de70: 72 63 6d 70 28 7a 2c 22 74 61 62 6c 65 22 29 3d  rcmp(z,"table")=
de80: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  =0 ){.        if
de90: 28 20 69 3d 3d 61 72 67 63 2d 31 20 29 20 63 6d  ( i==argc-1 ) cm
dea0: 64 6c 69 6e 65 45 72 72 6f 72 28 22 6d 69 73 73  dlineError("miss
deb0: 69 6e 67 20 61 72 67 75 6d 65 6e 74 20 74 6f 20  ing argument to 
dec0: 25 73 22 2c 20 61 72 67 76 5b 69 5d 29 3b 0a 20  %s", argv[i]);. 
ded0: 20 20 20 20 20 20 20 7a 54 61 62 20 3d 20 61 72         zTab = ar
dee0: 67 76 5b 2b 2b 69 5d 3b 0a 20 20 20 20 20 20 7d  gv[++i];.      }
def0: 65 6c 73 65 0a 20 20 20 20 20 20 69 66 28 20 73  else.      if( s
df00: 74 72 63 6d 70 28 7a 2c 22 74 72 61 6e 73 61 63  trcmp(z,"transac
df10: 74 69 6f 6e 22 29 3d 3d 30 20 29 7b 0a 20 20 20  tion")==0 ){.   
df20: 20 20 20 20 20 75 73 65 54 72 61 6e 73 61 63 74       useTransact
df30: 69 6f 6e 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d  ion = 1;.      }
df40: 65 6c 73 65 0a 20 20 20 20 20 20 7b 0a 20 20 20  else.      {.   
df50: 20 20 20 20 20 63 6d 64 6c 69 6e 65 45 72 72 6f       cmdlineErro
df60: 72 28 22 75 6e 6b 6e 6f 77 6e 20 6f 70 74 69 6f  r("unknown optio
df70: 6e 3a 20 25 73 22 2c 20 61 72 67 76 5b 69 5d 29  n: %s", argv[i])
df80: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65  ;.      }.    }e
df90: 6c 73 65 20 69 66 28 20 7a 44 62 31 3d 3d 30 20  lse if( zDb1==0 
dfa0: 29 7b 0a 20 20 20 20 20 20 7a 44 62 31 20 3d 20  ){.      zDb1 = 
dfb0: 61 72 67 76 5b 69 5d 3b 0a 20 20 20 20 7d 65 6c  argv[i];.    }el
dfc0: 73 65 20 69 66 28 20 7a 44 62 32 3d 3d 30 20 29  se if( zDb2==0 )
dfd0: 7b 0a 20 20 20 20 20 20 7a 44 62 32 20 3d 20 61  {.      zDb2 = a
dfe0: 72 67 76 5b 69 5d 3b 0a 20 20 20 20 7d 65 6c 73  rgv[i];.    }els
dff0: 65 7b 0a 20 20 20 20 20 20 63 6d 64 6c 69 6e 65  e{.      cmdline
e000: 45 72 72 6f 72 28 22 75 6e 6b 6e 6f 77 6e 20 61  Error("unknown a
e010: 72 67 75 6d 65 6e 74 3a 20 25 73 22 2c 20 61 72  rgument: %s", ar
e020: 67 76 5b 69 5d 29 3b 0a 20 20 20 20 7d 0a 20 20  gv[i]);.    }.  
e030: 7d 0a 20 20 69 66 28 20 7a 44 62 32 3d 3d 30 20  }.  if( zDb2==0 
e040: 29 7b 0a 20 20 20 20 63 6d 64 6c 69 6e 65 45 72  ){.    cmdlineEr
e050: 72 6f 72 28 22 74 77 6f 20 64 61 74 61 62 61 73  ror("two databas
e060: 65 20 61 72 67 75 6d 65 6e 74 73 20 72 65 71 75  e arguments requ
e070: 69 72 65 64 22 29 3b 0a 20 20 7d 0a 20 20 72 63  ired");.  }.  rc
e080: 20 3d 20 73 71 6c 69 74 65 33 5f 6f 70 65 6e 28   = sqlite3_open(
e090: 7a 44 62 31 2c 20 26 67 2e 64 62 29 3b 0a 20 20  zDb1, &g.db);.  
e0a0: 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 63 6d  if( rc ){.    cm
e0b0: 64 6c 69 6e 65 45 72 72 6f 72 28 22 63 61 6e 6e  dlineError("cann
e0c0: 6f 74 20 6f 70 65 6e 20 64 61 74 61 62 61 73 65  ot open database
e0d0: 20 66 69 6c 65 20 5c 22 25 73 5c 22 22 2c 20 7a   file \"%s\"", z
e0e0: 44 62 31 29 3b 0a 20 20 7d 0a 20 20 72 63 20 3d  Db1);.  }.  rc =
e0f0: 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 67 2e   sqlite3_exec(g.
e100: 64 62 2c 20 22 53 45 4c 45 43 54 20 2a 20 46 52  db, "SELECT * FR
e110: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
e120: 22 2c 20 30 2c 20 30 2c 20 26 7a 45 72 72 4d 73  ", 0, 0, &zErrMs
e130: 67 29 3b 0a 20 20 69 66 28 20 72 63 20 7c 7c 20  g);.  if( rc || 
e140: 7a 45 72 72 4d 73 67 20 29 7b 0a 20 20 20 20 63  zErrMsg ){.    c
e150: 6d 64 6c 69 6e 65 45 72 72 6f 72 28 22 5c 22 25  mdlineError("\"%
e160: 73 5c 22 20 64 6f 65 73 20 6e 6f 74 20 61 70 70  s\" does not app
e170: 65 61 72 20 74 6f 20 62 65 20 61 20 76 61 6c 69  ear to be a vali
e180: 64 20 53 51 4c 69 74 65 20 64 61 74 61 62 61 73  d SQLite databas
e190: 65 22 2c 20 7a 44 62 31 29 3b 0a 20 20 7d 0a 23  e", zDb1);.  }.#
e1a0: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d  ifndef SQLITE_OM
e1b0: 49 54 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f  IT_LOAD_EXTENSIO
e1c0: 4e 0a 20 20 73 71 6c 69 74 65 33 5f 65 6e 61 62  N.  sqlite3_enab
e1d0: 6c 65 5f 6c 6f 61 64 5f 65 78 74 65 6e 73 69 6f  le_load_extensio
e1e0: 6e 28 67 2e 64 62 2c 20 31 29 3b 0a 20 20 66 6f  n(g.db, 1);.  fo
e1f0: 72 28 69 3d 30 3b 20 69 3c 6e 45 78 74 3b 20 69  r(i=0; i<nExt; i
e200: 2b 2b 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71  ++){.    rc = sq
e210: 6c 69 74 65 33 5f 6c 6f 61 64 5f 65 78 74 65 6e  lite3_load_exten
e220: 73 69 6f 6e 28 67 2e 64 62 2c 20 61 7a 45 78 74  sion(g.db, azExt
e230: 5b 69 5d 2c 20 30 2c 20 26 7a 45 72 72 4d 73 67  [i], 0, &zErrMsg
e240: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 20 7c 7c  );.    if( rc ||
e250: 20 7a 45 72 72 4d 73 67 20 29 7b 0a 20 20 20 20   zErrMsg ){.    
e260: 20 20 63 6d 64 6c 69 6e 65 45 72 72 6f 72 28 22    cmdlineError("
e270: 65 72 72 6f 72 20 6c 6f 61 64 69 6e 67 20 25 73  error loading %s
e280: 3a 20 25 73 22 2c 20 61 7a 45 78 74 5b 69 5d 2c  : %s", azExt[i],
e290: 20 7a 45 72 72 4d 73 67 29 3b 0a 20 20 20 20 7d   zErrMsg);.    }
e2a0: 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 66 72  .  }.#endif.  fr
e2b0: 65 65 28 61 7a 45 78 74 29 3b 0a 20 20 7a 53 71  ee(azExt);.  zSq
e2c0: 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  l = sqlite3_mpri
e2d0: 6e 74 66 28 22 41 54 54 41 43 48 20 25 51 20 61  ntf("ATTACH %Q a
e2e0: 73 20 61 75 78 3b 22 2c 20 7a 44 62 32 29 3b 0a  s aux;", zDb2);.
e2f0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65    rc = sqlite3_e
e300: 78 65 63 28 67 2e 64 62 2c 20 7a 53 71 6c 2c 20  xec(g.db, zSql, 
e310: 30 2c 20 30 2c 20 26 7a 45 72 72 4d 73 67 29 3b  0, 0, &zErrMsg);
e320: 0a 20 20 69 66 28 20 72 63 20 7c 7c 20 7a 45 72  .  if( rc || zEr
e330: 72 4d 73 67 20 29 7b 0a 20 20 20 20 63 6d 64 6c  rMsg ){.    cmdl
e340: 69 6e 65 45 72 72 6f 72 28 22 63 61 6e 6e 6f 74  ineError("cannot
e350: 20 61 74 74 61 63 68 20 64 61 74 61 62 61 73 65   attach database
e360: 20 5c 22 25 73 5c 22 22 2c 20 7a 44 62 32 29 3b   \"%s\"", zDb2);
e370: 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c 69  .  }.  rc = sqli
e380: 74 65 33 5f 65 78 65 63 28 67 2e 64 62 2c 20 22  te3_exec(g.db, "
e390: 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 61 75  SELECT * FROM au
e3a0: 78 2e 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 22  x.sqlite_master"
e3b0: 2c 20 30 2c 20 30 2c 20 26 7a 45 72 72 4d 73 67  , 0, 0, &zErrMsg
e3c0: 29 3b 0a 20 20 69 66 28 20 72 63 20 7c 7c 20 7a  );.  if( rc || z
e3d0: 45 72 72 4d 73 67 20 29 7b 0a 20 20 20 20 63 6d  ErrMsg ){.    cm
e3e0: 64 6c 69 6e 65 45 72 72 6f 72 28 22 5c 22 25 73  dlineError("\"%s
e3f0: 5c 22 20 64 6f 65 73 20 6e 6f 74 20 61 70 70 65  \" does not appe
e400: 61 72 20 74 6f 20 62 65 20 61 20 76 61 6c 69 64  ar to be a valid
e410: 20 53 51 4c 69 74 65 20 64 61 74 61 62 61 73 65   SQLite database
e420: 22 2c 20 7a 44 62 32 29 3b 0a 20 20 7d 0a 0a 20  ", zDb2);.  }.. 
e430: 20 69 66 28 20 6e 65 76 65 72 55 73 65 54 72 61   if( neverUseTra
e440: 6e 73 61 63 74 69 6f 6e 20 29 20 75 73 65 54 72  nsaction ) useTr
e450: 61 6e 73 61 63 74 69 6f 6e 20 3d 20 30 3b 0a 20  ansaction = 0;. 
e460: 20 69 66 28 20 75 73 65 54 72 61 6e 73 61 63 74   if( useTransact
e470: 69 6f 6e 20 29 20 70 72 69 6e 74 66 28 22 42 45  ion ) printf("BE
e480: 47 49 4e 20 54 52 41 4e 53 41 43 54 49 4f 4e 3b  GIN TRANSACTION;
e490: 5c 6e 22 29 3b 0a 20 20 69 66 28 20 7a 54 61 62  \n");.  if( zTab
e4a0: 20 29 7b 0a 20 20 20 20 78 44 69 66 66 28 7a 54   ){.    xDiff(zT
e4b0: 61 62 2c 20 6f 75 74 29 3b 0a 20 20 7d 65 6c 73  ab, out);.  }els
e4c0: 65 7b 0a 20 20 20 20 2f 2a 20 48 61 6e 64 6c 65  e{.    /* Handle
e4d0: 20 74 61 62 6c 65 73 20 6f 6e 65 20 62 79 20 6f   tables one by o
e4e0: 6e 65 20 2a 2f 0a 20 20 20 20 70 53 74 6d 74 20  ne */.    pStmt 
e4f0: 3d 20 64 62 5f 70 72 65 70 61 72 65 28 0a 20 20  = db_prepare(.  
e500: 20 20 20 20 22 53 45 4c 45 43 54 20 6e 61 6d 65      "SELECT name
e510: 20 46 52 4f 4d 20 6d 61 69 6e 2e 73 71 6c 69 74   FROM main.sqlit
e520: 65 5f 6d 61 73 74 65 72 5c 6e 22 0a 20 20 20 20  e_master\n".    
e530: 20 20 22 20 57 48 45 52 45 20 74 79 70 65 3d 27    " WHERE type='
e540: 74 61 62 6c 65 27 20 41 4e 44 20 73 71 6c 20 4e  table' AND sql N
e550: 4f 54 20 4c 49 4b 45 20 27 43 52 45 41 54 45 20  OT LIKE 'CREATE 
e560: 56 49 52 54 55 41 4c 25 25 27 5c 6e 22 0a 20 20  VIRTUAL%%'\n".  
e570: 20 20 20 20 22 20 55 4e 49 4f 4e 5c 6e 22 0a 20      " UNION\n". 
e580: 20 20 20 20 20 22 53 45 4c 45 43 54 20 6e 61 6d       "SELECT nam
e590: 65 20 46 52 4f 4d 20 61 75 78 2e 73 71 6c 69 74  e FROM aux.sqlit
e5a0: 65 5f 6d 61 73 74 65 72 5c 6e 22 0a 20 20 20 20  e_master\n".    
e5b0: 20 20 22 20 57 48 45 52 45 20 74 79 70 65 3d 27    " WHERE type='
e5c0: 74 61 62 6c 65 27 20 41 4e 44 20 73 71 6c 20 4e  table' AND sql N
e5d0: 4f 54 20 4c 49 4b 45 20 27 43 52 45 41 54 45 20  OT LIKE 'CREATE 
e5e0: 56 49 52 54 55 41 4c 25 25 27 5c 6e 22 0a 20 20  VIRTUAL%%'\n".  
e5f0: 20 20 20 20 22 20 4f 52 44 45 52 20 42 59 20 6e      " ORDER BY n
e600: 61 6d 65 22 0a 20 20 20 20 29 3b 0a 20 20 20 20  ame".    );.    
e610: 77 68 69 6c 65 28 20 53 51 4c 49 54 45 5f 52 4f  while( SQLITE_RO
e620: 57 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65 70 28  W==sqlite3_step(
e630: 70 53 74 6d 74 29 20 29 7b 0a 20 20 20 20 20 20  pStmt) ){.      
e640: 78 44 69 66 66 28 28 63 6f 6e 73 74 20 63 68 61  xDiff((const cha
e650: 72 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  r*)sqlite3_colum
e660: 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 30 29 2c  n_text(pStmt,0),
e670: 20 6f 75 74 29 3b 0a 20 20 20 20 7d 0a 20 20 20   out);.    }.   
e680: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
e690: 65 28 70 53 74 6d 74 29 3b 0a 20 20 7d 0a 20 20  e(pStmt);.  }.  
e6a0: 69 66 28 20 75 73 65 54 72 61 6e 73 61 63 74 69  if( useTransacti
e6b0: 6f 6e 20 29 20 70 72 69 6e 74 66 28 22 43 4f 4d  on ) printf("COM
e6c0: 4d 49 54 3b 5c 6e 22 29 3b 0a 0a 20 20 2f 2a 20  MIT;\n");..  /* 
e6d0: 54 42 44 3a 20 48 61 6e 64 6c 65 20 74 72 69 67  TBD: Handle trig
e6e0: 67 65 72 20 64 69 66 66 65 72 65 6e 63 65 73 20  ger differences 
e6f0: 2a 2f 0a 20 20 2f 2a 20 54 42 44 3a 20 48 61 6e  */.  /* TBD: Han
e700: 64 6c 65 20 76 69 65 77 20 64 69 66 66 65 72 65  dle view differe
e710: 6e 63 65 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65  nces */.  sqlite
e720: 33 5f 63 6c 6f 73 65 28 67 2e 64 62 29 3b 0a 20  3_close(g.db);. 
e730: 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a            return 0;.}.