/ Hex Artifact Content
Login

Artifact c61a43396368ec00dc127f7bc647e9bd6a4ee5fb:


0000: 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c  .#if defined(SQL
0010: 49 54 45 5f 45 4e 41 42 4c 45 5f 53 45 53 53 49  ITE_ENABLE_SESSI
0020: 4f 4e 29 20 26 26 20 64 65 66 69 6e 65 64 28 53  ON) && defined(S
0030: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 50 52 45  QLITE_ENABLE_PRE
0040: 55 50 44 41 54 45 5f 48 4f 4f 4b 29 0a 23 69 6e  UPDATE_HOOK).#in
0050: 63 6c 75 64 65 20 22 73 71 6c 69 74 65 33 73 65  clude "sqlite3se
0060: 73 73 69 6f 6e 2e 68 22 0a 23 69 6e 63 6c 75 64  ssion.h".#includ
0070: 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a 23 69 6e  e <assert.h>.#in
0080: 63 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e  clude <string.h>
0090: 0a 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45  ..#ifndef SQLITE
00a0: 5f 41 4d 41 4c 47 41 4d 41 54 49 4f 4e 0a 23 20  _AMALGAMATION.# 
00b0: 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65 49  include "sqliteI
00c0: 6e 74 2e 68 22 0a 23 20 69 6e 63 6c 75 64 65 20  nt.h".# include 
00d0: 22 76 64 62 65 49 6e 74 2e 68 22 0a 23 65 6e 64  "vdbeInt.h".#end
00e0: 69 66 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75  if..typedef stru
00f0: 63 74 20 53 65 73 73 69 6f 6e 54 61 62 6c 65 20  ct SessionTable 
0100: 53 65 73 73 69 6f 6e 54 61 62 6c 65 3b 0a 74 79  SessionTable;.ty
0110: 70 65 64 65 66 20 73 74 72 75 63 74 20 53 65 73  pedef struct Ses
0120: 73 69 6f 6e 43 68 61 6e 67 65 20 53 65 73 73 69  sionChange Sessi
0130: 6f 6e 43 68 61 6e 67 65 3b 0a 74 79 70 65 64 65  onChange;.typede
0140: 66 20 73 74 72 75 63 74 20 53 65 73 73 69 6f 6e  f struct Session
0150: 42 75 66 66 65 72 20 53 65 73 73 69 6f 6e 42 75  Buffer SessionBu
0160: 66 66 65 72 3b 0a 74 79 70 65 64 65 66 20 73 74  ffer;.typedef st
0170: 72 75 63 74 20 53 65 73 73 69 6f 6e 49 6e 70 75  ruct SessionInpu
0180: 74 20 53 65 73 73 69 6f 6e 49 6e 70 75 74 3b 0a  t SessionInput;.
0190: 0a 2f 2a 0a 2a 2a 20 4d 69 6e 69 6d 75 6d 20 63  ./*.** Minimum c
01a0: 68 75 6e 6b 20 73 69 7a 65 20 75 73 65 64 20 62  hunk size used b
01b0: 79 20 73 74 72 65 61 6d 69 6e 67 20 76 65 72 73  y streaming vers
01c0: 69 6f 6e 73 20 6f 66 20 66 75 6e 63 74 69 6f 6e  ions of function
01d0: 73 2e 0a 2a 2f 0a 23 69 66 6e 64 65 66 20 53 45  s..*/.#ifndef SE
01e0: 53 53 49 4f 4e 53 5f 53 54 52 4d 5f 43 48 55 4e  SSIONS_STRM_CHUN
01f0: 4b 5f 53 49 5a 45 0a 23 20 69 66 64 65 66 20 53  K_SIZE.# ifdef S
0200: 51 4c 49 54 45 5f 54 45 53 54 0a 23 20 20 20 64  QLITE_TEST.#   d
0210: 65 66 69 6e 65 20 53 45 53 53 49 4f 4e 53 5f 53  efine SESSIONS_S
0220: 54 52 4d 5f 43 48 55 4e 4b 5f 53 49 5a 45 20 36  TRM_CHUNK_SIZE 6
0230: 34 0a 23 20 65 6c 73 65 0a 23 20 20 20 64 65 66  4.# else.#   def
0240: 69 6e 65 20 53 45 53 53 49 4f 4e 53 5f 53 54 52  ine SESSIONS_STR
0250: 4d 5f 43 48 55 4e 4b 5f 53 49 5a 45 20 31 30 32  M_CHUNK_SIZE 102
0260: 34 0a 23 20 65 6e 64 69 66 0a 23 65 6e 64 69 66  4.# endif.#endif
0270: 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ..typedef struct
0280: 20 53 65 73 73 69 6f 6e 48 6f 6f 6b 20 53 65 73   SessionHook Ses
0290: 73 69 6f 6e 48 6f 6f 6b 3b 0a 73 74 72 75 63 74  sionHook;.struct
02a0: 20 53 65 73 73 69 6f 6e 48 6f 6f 6b 20 7b 0a 20   SessionHook {. 
02b0: 20 76 6f 69 64 20 2a 70 43 74 78 3b 0a 20 20 69   void *pCtx;.  i
02c0: 6e 74 20 28 2a 78 4f 6c 64 29 28 76 6f 69 64 2a  nt (*xOld)(void*
02d0: 2c 69 6e 74 2c 73 71 6c 69 74 65 33 5f 76 61 6c  ,int,sqlite3_val
02e0: 75 65 2a 2a 29 3b 0a 20 20 69 6e 74 20 28 2a 78  ue**);.  int (*x
02f0: 4e 65 77 29 28 76 6f 69 64 2a 2c 69 6e 74 2c 73  New)(void*,int,s
0300: 71 6c 69 74 65 33 5f 76 61 6c 75 65 2a 2a 29 3b  qlite3_value**);
0310: 0a 20 20 69 6e 74 20 28 2a 78 43 6f 75 6e 74 29  .  int (*xCount)
0320: 28 76 6f 69 64 2a 29 3b 0a 20 20 69 6e 74 20 28  (void*);.  int (
0330: 2a 78 44 65 70 74 68 29 28 76 6f 69 64 2a 29 3b  *xDepth)(void*);
0340: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 53 65 73 73 69  .};../*.** Sessi
0350: 6f 6e 20 68 61 6e 64 6c 65 20 73 74 72 75 63 74  on handle struct
0360: 75 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 73  ure..*/.struct s
0370: 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 7b  qlite3_session {
0380: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b 20  .  sqlite3 *db; 
0390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
03a0: 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68     /* Database h
03b0: 61 6e 64 6c 65 20 73 65 73 73 69 6f 6e 20 69 73  andle session is
03c0: 20 61 74 74 61 63 68 65 64 20 74 6f 20 2a 2f 0a   attached to */.
03d0: 20 20 63 68 61 72 20 2a 7a 44 62 3b 20 20 20 20    char *zDb;    
03e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
03f0: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 64 61 74    /* Name of dat
0400: 61 62 61 73 65 20 73 65 73 73 69 6f 6e 20 69 73  abase session is
0410: 20 61 74 74 61 63 68 65 64 20 74 6f 20 2a 2f 0a   attached to */.
0420: 20 20 69 6e 74 20 62 45 6e 61 62 6c 65 3b 20 20    int bEnable;  
0430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0440: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 63 75 72    /* True if cur
0450: 72 65 6e 74 6c 79 20 72 65 63 6f 72 64 69 6e 67  rently recording
0460: 20 2a 2f 0a 20 20 69 6e 74 20 62 49 6e 64 69 72   */.  int bIndir
0470: 65 63 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ect;            
0480: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
0490: 20 61 6c 6c 20 63 68 61 6e 67 65 73 20 61 72 65   all changes are
04a0: 20 69 6e 64 69 72 65 63 74 20 2a 2f 0a 20 20 69   indirect */.  i
04b0: 6e 74 20 62 41 75 74 6f 41 74 74 61 63 68 3b 20  nt bAutoAttach; 
04c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
04d0: 2a 20 54 72 75 65 20 74 6f 20 61 75 74 6f 2d 61  * True to auto-a
04e0: 74 74 61 63 68 20 74 61 62 6c 65 73 20 2a 2f 0a  ttach tables */.
04f0: 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
0500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0510: 20 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20 69 66    /* Non-zero if
0520: 20 61 6e 20 65 72 72 6f 72 20 68 61 73 20 6f 63   an error has oc
0530: 63 75 72 72 65 64 20 2a 2f 0a 20 20 76 6f 69 64  curred */.  void
0540: 20 2a 70 46 69 6c 74 65 72 43 74 78 3b 20 20 20   *pFilterCtx;   
0550: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
0560: 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 74 6f  irst argument to
0570: 20 70 61 73 73 20 74 6f 20 78 54 61 62 6c 65 46   pass to xTableF
0580: 69 6c 74 65 72 20 2a 2f 0a 20 20 69 6e 74 20 28  ilter */.  int (
0590: 2a 78 54 61 62 6c 65 46 69 6c 74 65 72 29 28 76  *xTableFilter)(v
05a0: 6f 69 64 20 2a 70 43 74 78 2c 20 63 6f 6e 73 74  oid *pCtx, const
05b0: 20 63 68 61 72 20 2a 7a 54 61 62 29 3b 0a 20 20   char *zTab);.  
05c0: 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20  sqlite3_session 
05d0: 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20  *pNext;         
05e0: 2f 2a 20 4e 65 78 74 20 73 65 73 73 69 6f 6e 20  /* Next session 
05f0: 6f 62 6a 65 63 74 20 6f 6e 20 73 61 6d 65 20 64  object on same d
0600: 62 2e 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 54  b. */.  SessionT
0610: 61 62 6c 65 20 2a 70 54 61 62 6c 65 3b 20 20 20  able *pTable;   
0620: 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20          /* List 
0630: 6f 66 20 61 74 74 61 63 68 65 64 20 74 61 62 6c  of attached tabl
0640: 65 73 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 48  es */.  SessionH
0650: 6f 6f 6b 20 68 6f 6f 6b 3b 20 20 20 20 20 20 20  ook hook;       
0660: 20 20 20 20 20 20 20 20 2f 2a 20 41 50 49 73 20          /* APIs 
0670: 74 6f 20 67 72 61 62 20 6e 65 77 20 61 6e 64 20  to grab new and 
0680: 6f 6c 64 20 64 61 74 61 20 77 69 74 68 20 2a 2f  old data with */
0690: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 49 6e 73 74 61  .};../*.** Insta
06a0: 6e 63 65 73 20 6f 66 20 74 68 69 73 20 73 74 72  nces of this str
06b0: 75 63 74 75 72 65 20 61 72 65 20 75 73 65 64 20  ucture are used 
06c0: 74 6f 20 62 75 69 6c 64 20 73 74 72 69 6e 67 73  to build strings
06d0: 20 6f 72 20 62 69 6e 61 72 79 20 72 65 63 6f 72   or binary recor
06e0: 64 73 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 53 65  ds..*/.struct Se
06f0: 73 73 69 6f 6e 42 75 66 66 65 72 20 7b 0a 20 20  ssionBuffer {.  
0700: 75 38 20 2a 61 42 75 66 3b 20 20 20 20 20 20 20  u8 *aBuf;       
0710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0720: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 63 68  /* Pointer to ch
0730: 61 6e 67 65 73 65 74 20 62 75 66 66 65 72 20 2a  angeset buffer *
0740: 2f 0a 20 20 69 6e 74 20 6e 42 75 66 3b 20 20 20  /.  int nBuf;   
0750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0760: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 62      /* Size of b
0770: 75 66 66 65 72 20 61 42 75 66 20 2a 2f 0a 20 20  uffer aBuf */.  
0780: 69 6e 74 20 6e 41 6c 6c 6f 63 3b 20 20 20 20 20  int nAlloc;     
0790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07a0: 2f 2a 20 53 69 7a 65 20 6f 66 20 61 6c 6c 6f 63  /* Size of alloc
07b0: 61 74 69 6f 6e 20 63 6f 6e 74 61 69 6e 69 6e 67  ation containing
07c0: 20 61 42 75 66 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a   aBuf */.};../*.
07d0: 2a 2a 20 41 6e 20 6f 62 6a 65 63 74 20 6f 66 20  ** An object of 
07e0: 74 68 69 73 20 74 79 70 65 20 69 73 20 75 73 65  this type is use
07f0: 64 20 69 6e 74 65 72 6e 61 6c 6c 79 20 61 73 20  d internally as 
0800: 61 6e 20 61 62 73 74 72 61 63 74 69 6f 6e 20 66  an abstraction f
0810: 6f 72 20 0a 2a 2a 20 69 6e 70 75 74 20 64 61 74  or .** input dat
0820: 61 2e 20 49 6e 70 75 74 20 64 61 74 61 20 6d 61  a. Input data ma
0830: 79 20 62 65 20 73 75 70 70 6c 69 65 64 20 65 69  y be supplied ei
0840: 74 68 65 72 20 61 73 20 61 20 73 69 6e 67 6c 65  ther as a single
0850: 20 6c 61 72 67 65 20 62 75 66 66 65 72 0a 2a 2a   large buffer.**
0860: 20 28 65 2e 67 2e 20 73 71 6c 69 74 65 33 63 68   (e.g. sqlite3ch
0870: 61 6e 67 65 73 65 74 5f 73 74 61 72 74 28 29 29  angeset_start())
0880: 20 6f 72 20 75 73 69 6e 67 20 61 20 73 74 72 65   or using a stre
0890: 61 6d 20 66 75 6e 63 74 69 6f 6e 20 28 65 2e 67  am function (e.g
08a0: 2e 0a 2a 2a 20 20 73 71 6c 69 74 65 33 63 68 61  ..**  sqlite3cha
08b0: 6e 67 65 73 65 74 5f 73 74 61 72 74 5f 73 74 72  ngeset_start_str
08c0: 6d 28 29 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  m())..*/.struct 
08d0: 53 65 73 73 69 6f 6e 49 6e 70 75 74 20 7b 0a 20  SessionInput {. 
08e0: 20 69 6e 74 20 62 4e 6f 44 69 73 63 61 72 64 3b   int bNoDiscard;
08f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0900: 20 2f 2a 20 49 66 20 74 72 75 65 2c 20 64 69 73   /* If true, dis
0910: 63 61 72 64 20 6e 6f 20 64 61 74 61 20 2a 2f 0a  card no data */.
0920: 20 20 69 6e 74 20 69 43 75 72 72 65 6e 74 3b 20    int iCurrent; 
0930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0940: 20 20 2f 2a 20 4f 66 66 73 65 74 20 69 6e 20 61    /* Offset in a
0950: 44 61 74 61 5b 5d 20 6f 66 20 63 75 72 72 65 6e  Data[] of curren
0960: 74 20 63 68 61 6e 67 65 20 2a 2f 0a 20 20 69 6e  t change */.  in
0970: 74 20 69 4e 65 78 74 3b 20 20 20 20 20 20 20 20  t iNext;        
0980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0990: 20 4f 66 66 73 65 74 20 69 6e 20 61 44 61 74 61   Offset in aData
09a0: 5b 5d 20 6f 66 20 6e 65 78 74 20 63 68 61 6e 67  [] of next chang
09b0: 65 20 2a 2f 0a 20 20 75 38 20 2a 61 44 61 74 61  e */.  u8 *aData
09c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
09d0: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
09e0: 72 20 74 6f 20 62 75 66 66 65 72 20 63 6f 6e 74  r to buffer cont
09f0: 61 69 6e 69 6e 67 20 63 68 61 6e 67 65 73 65 74  aining changeset
0a00: 20 2a 2f 0a 20 20 69 6e 74 20 6e 44 61 74 61 3b   */.  int nData;
0a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a20: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
0a30: 6f 66 20 62 79 74 65 73 20 69 6e 20 61 44 61 74  of bytes in aDat
0a40: 61 20 2a 2f 0a 0a 20 20 53 65 73 73 69 6f 6e 42  a */..  SessionB
0a50: 75 66 66 65 72 20 62 75 66 3b 20 20 20 20 20 20  uffer buf;      
0a60: 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65          /* Curre
0a70: 6e 74 20 72 65 61 64 20 62 75 66 66 65 72 20 2a  nt read buffer *
0a80: 2f 0a 20 20 69 6e 74 20 28 2a 78 49 6e 70 75 74  /.  int (*xInput
0a90: 29 28 76 6f 69 64 2a 2c 20 76 6f 69 64 2a 2c 20  )(void*, void*, 
0aa0: 69 6e 74 2a 29 3b 20 20 20 20 20 20 20 20 2f 2a  int*);        /*
0ab0: 20 49 6e 70 75 74 20 73 74 72 65 61 6d 20 63 61   Input stream ca
0ac0: 6c 6c 20 28 6f 72 20 4e 55 4c 4c 29 20 2a 2f 0a  ll (or NULL) */.
0ad0: 20 20 76 6f 69 64 20 2a 70 49 6e 3b 20 20 20 20    void *pIn;    
0ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0af0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
0b00: 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 74 6f  irst argument to
0b10: 20 78 49 6e 70 75 74 20 2a 2f 0a 20 20 69 6e 74   xInput */.  int
0b20: 20 62 45 6f 66 3b 20 20 20 20 20 20 20 20 20 20   bEof;          
0b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0b40: 53 65 74 20 74 6f 20 74 72 75 65 20 61 66 74 65  Set to true afte
0b50: 72 20 78 49 6e 70 75 74 20 66 69 6e 69 73 68 65  r xInput finishe
0b60: 64 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 53  d */.};../*.** S
0b70: 74 72 75 63 74 75 72 65 20 66 6f 72 20 63 68 61  tructure for cha
0b80: 6e 67 65 73 65 74 20 69 74 65 72 61 74 6f 72 73  ngeset iterators
0b90: 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 73 71 6c 69  ..*/.struct sqli
0ba0: 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74  te3_changeset_it
0bb0: 65 72 20 7b 0a 20 20 53 65 73 73 69 6f 6e 49 6e  er {.  SessionIn
0bc0: 70 75 74 20 69 6e 3b 20 20 20 20 20 20 20 20 20  put in;         
0bd0: 20 20 20 20 20 20 20 2f 2a 20 49 6e 70 75 74 20         /* Input 
0be0: 62 75 66 66 65 72 20 6f 72 20 73 74 72 65 61 6d  buffer or stream
0bf0: 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 42 75 66   */.  SessionBuf
0c00: 66 65 72 20 74 62 6c 68 64 72 3b 20 20 20 20 20  fer tblhdr;     
0c10: 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
0c20: 74 6f 20 68 6f 6c 64 20 61 70 56 61 6c 75 65 2f  to hold apValue/
0c30: 7a 54 61 62 2f 61 62 50 4b 2f 20 2a 2f 0a 20 20  zTab/abPK/ */.  
0c40: 69 6e 74 20 62 50 61 74 63 68 73 65 74 3b 20 20  int bPatchset;  
0c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c60: 2f 2a 20 54 72 75 65 20 69 66 20 74 68 69 73 20  /* True if this 
0c70: 69 73 20 61 20 70 61 74 63 68 73 65 74 20 2a 2f  is a patchset */
0c80: 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
0c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ca0: 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 65     /* Iterator e
0cb0: 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 20 20 73  rror code */.  s
0cc0: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 43 6f  qlite3_stmt *pCo
0cd0: 6e 66 6c 69 63 74 3b 20 20 20 20 20 20 20 20 2f  nflict;        /
0ce0: 2a 20 50 6f 69 6e 74 73 20 74 6f 20 63 6f 6e 66  * Points to conf
0cf0: 6c 69 63 74 69 6e 67 20 72 6f 77 2c 20 69 66 20  licting row, if 
0d00: 61 6e 79 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a  any */.  char *z
0d10: 54 61 62 3b 20 20 20 20 20 20 20 20 20 20 20 20  Tab;            
0d20: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72           /* Curr
0d30: 65 6e 74 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69  ent table */.  i
0d40: 6e 74 20 6e 43 6f 6c 3b 20 20 20 20 20 20 20 20  nt nCol;        
0d50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0d60: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75  * Number of colu
0d70: 6d 6e 73 20 69 6e 20 7a 54 61 62 20 2a 2f 0a 20  mns in zTab */. 
0d80: 20 69 6e 74 20 6f 70 3b 20 20 20 20 20 20 20 20   int op;        
0d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0da0: 20 2f 2a 20 43 75 72 72 65 6e 74 20 6f 70 65 72   /* Current oper
0db0: 61 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 62  ation */.  int b
0dc0: 49 6e 64 69 72 65 63 74 3b 20 20 20 20 20 20 20  Indirect;       
0dd0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
0de0: 75 65 20 69 66 20 63 75 72 72 65 6e 74 20 63 68  ue if current ch
0df0: 61 6e 67 65 20 77 61 73 20 69 6e 64 69 72 65 63  ange was indirec
0e00: 74 20 2a 2f 0a 20 20 75 38 20 2a 61 62 50 4b 3b  t */.  u8 *abPK;
0e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e20: 20 20 20 20 20 20 20 2f 2a 20 50 72 69 6d 61 72         /* Primar
0e30: 79 20 6b 65 79 20 61 72 72 61 79 20 2a 2f 0a 20  y key array */. 
0e40: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
0e50: 2a 61 70 56 61 6c 75 65 3b 20 20 20 20 20 20 20  *apValue;       
0e60: 20 2f 2a 20 6f 6c 64 2e 2a 20 61 6e 64 20 6e 65   /* old.* and ne
0e70: 77 2e 2a 20 76 61 6c 75 65 73 20 2a 2f 0a 7d 3b  w.* values */.};
0e80: 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 73 65 73  ../*.** Each ses
0e90: 73 69 6f 6e 20 6f 62 6a 65 63 74 20 6d 61 69 6e  sion object main
0ea0: 74 61 69 6e 73 20 61 20 73 65 74 20 6f 66 20 74  tains a set of t
0eb0: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 74 72  he following str
0ec0: 75 63 74 75 72 65 73 2c 20 6f 6e 65 0a 2a 2a 20  uctures, one.** 
0ed0: 66 6f 72 20 65 61 63 68 20 74 61 62 6c 65 20 74  for each table t
0ee0: 68 65 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63  he session objec
0ef0: 74 20 69 73 20 6d 6f 6e 69 74 6f 72 69 6e 67 2e  t is monitoring.
0f00: 20 54 68 65 20 73 74 72 75 63 74 75 72 65 73 20   The structures 
0f10: 61 72 65 0a 2a 2a 20 73 74 6f 72 65 64 20 69 6e  are.** stored in
0f20: 20 61 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 73   a linked list s
0f30: 74 61 72 74 69 6e 67 20 61 74 20 73 71 6c 69 74  tarting at sqlit
0f40: 65 33 5f 73 65 73 73 69 6f 6e 2e 70 54 61 62 6c  e3_session.pTabl
0f50: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6b 65 79  e..**.** The key
0f60: 73 20 6f 66 20 74 68 65 20 53 65 73 73 69 6f 6e  s of the Session
0f70: 54 61 62 6c 65 2e 61 43 68 61 6e 67 65 5b 5d 20  Table.aChange[] 
0f80: 68 61 73 68 20 74 61 62 6c 65 20 61 72 65 20 61  hash table are a
0f90: 6c 6c 20 72 6f 77 73 20 74 68 61 74 20 68 61 76  ll rows that hav
0fa0: 65 0a 2a 2a 20 62 65 65 6e 20 6d 6f 64 69 66 69  e.** been modifi
0fb0: 65 64 20 69 6e 20 61 6e 79 20 77 61 79 20 73 69  ed in any way si
0fc0: 6e 63 65 20 74 68 65 20 73 65 73 73 69 6f 6e 20  nce the session 
0fd0: 6f 62 6a 65 63 74 20 77 61 73 20 61 74 74 61 63  object was attac
0fe0: 68 65 64 20 74 6f 20 74 68 65 0a 2a 2a 20 74 61  hed to the.** ta
0ff0: 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 64  ble..**.** The d
1000: 61 74 61 20 61 73 73 6f 63 69 61 74 65 64 20 77  ata associated w
1010: 69 74 68 20 65 61 63 68 20 68 61 73 68 2d 74 61  ith each hash-ta
1020: 62 6c 65 20 65 6e 74 72 79 20 69 73 20 61 20 73  ble entry is a s
1030: 74 72 75 63 74 75 72 65 20 63 6f 6e 74 61 69 6e  tructure contain
1040: 69 6e 67 0a 2a 2a 20 61 20 73 75 62 73 65 74 20  ing.** a subset 
1050: 6f 66 20 74 68 65 20 69 6e 69 74 69 61 6c 20 76  of the initial v
1060: 61 6c 75 65 73 20 74 68 61 74 20 74 68 65 20 6d  alues that the m
1070: 6f 64 69 66 69 65 64 20 72 6f 77 20 63 6f 6e 74  odified row cont
1080: 61 69 6e 65 64 20 61 74 20 74 68 65 0a 2a 2a 20  ained at the.** 
1090: 73 74 61 72 74 20 6f 66 20 74 68 65 20 73 65 73  start of the ses
10a0: 73 69 6f 6e 2e 20 4f 72 20 6e 6f 20 69 6e 69 74  sion. Or no init
10b0: 69 61 6c 20 76 61 6c 75 65 73 20 69 66 20 74 68  ial values if th
10c0: 65 20 72 6f 77 20 77 61 73 20 69 6e 73 65 72 74  e row was insert
10d0: 65 64 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 53 65  ed..*/.struct Se
10e0: 73 73 69 6f 6e 54 61 62 6c 65 20 7b 0a 20 20 53  ssionTable {.  S
10f0: 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70 4e 65  essionTable *pNe
1100: 78 74 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 61 6d  xt;.  char *zNam
1110: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
1120: 20 20 20 20 20 20 2f 2a 20 4c 6f 63 61 6c 20 6e        /* Local n
1130: 61 6d 65 20 6f 66 20 74 61 62 6c 65 20 2a 2f 0a  ame of table */.
1140: 20 20 69 6e 74 20 6e 43 6f 6c 3b 20 20 20 20 20    int nCol;     
1150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1160: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63    /* Number of c
1170: 6f 6c 75 6d 6e 73 20 69 6e 20 74 61 62 6c 65 20  olumns in table 
1180: 7a 4e 61 6d 65 20 2a 2f 0a 20 20 63 6f 6e 73 74  zName */.  const
1190: 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6c 3b 20 20   char **azCol;  
11a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
11b0: 6c 75 6d 6e 20 6e 61 6d 65 73 20 2a 2f 0a 20 20  lumn names */.  
11c0: 75 38 20 2a 61 62 50 4b 3b 20 20 20 20 20 20 20  u8 *abPK;       
11d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11e0: 2f 2a 20 41 72 72 61 79 20 6f 66 20 70 72 69 6d  /* Array of prim
11f0: 61 72 79 20 6b 65 79 20 66 6c 61 67 73 20 2a 2f  ary key flags */
1200: 0a 20 20 69 6e 74 20 6e 45 6e 74 72 79 3b 20 20  .  int nEntry;  
1210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1220: 20 20 20 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d 62     /* Total numb
1230: 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e  er of entries in
1240: 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20   hash table */. 
1250: 20 69 6e 74 20 6e 43 68 61 6e 67 65 3b 20 20 20   int nChange;   
1260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1270: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61 70 43 68   /* Size of apCh
1280: 61 6e 67 65 5b 5d 20 61 72 72 61 79 20 2a 2f 0a  ange[] array */.
1290: 20 20 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20    SessionChange 
12a0: 2a 2a 61 70 43 68 61 6e 67 65 3b 20 20 20 20 20  **apChange;     
12b0: 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20    /* Hash table 
12c0: 62 75 63 6b 65 74 73 20 2a 2f 0a 7d 3b 0a 0a 2f  buckets */.};../
12d0: 2a 20 0a 2a 2a 20 52 45 43 4f 52 44 20 46 4f 52  * .** RECORD FOR
12e0: 4d 41 54 3a 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66  MAT:.**.** The f
12f0: 6f 6c 6c 6f 77 69 6e 67 20 72 65 63 6f 72 64 20  ollowing record 
1300: 66 6f 72 6d 61 74 20 69 73 20 73 69 6d 69 6c 61  format is simila
1310: 72 20 74 6f 20 28 62 75 74 20 6e 6f 74 20 63 6f  r to (but not co
1320: 6d 70 61 74 69 62 6c 65 20 77 69 74 68 29 20 74  mpatible with) t
1330: 68 61 74 20 0a 2a 2a 20 75 73 65 64 20 69 6e 20  hat .** used in 
1340: 53 51 4c 69 74 65 20 64 61 74 61 62 61 73 65 20  SQLite database 
1350: 66 69 6c 65 73 2e 20 54 68 69 73 20 66 6f 72 6d  files. This form
1360: 61 74 20 69 73 20 75 73 65 64 20 61 73 20 70 61  at is used as pa
1370: 72 74 20 6f 66 20 74 68 65 20 0a 2a 2a 20 63 68  rt of the .** ch
1380: 61 6e 67 65 2d 73 65 74 20 62 69 6e 61 72 79 20  ange-set binary 
1390: 66 6f 72 6d 61 74 2c 20 61 6e 64 20 73 6f 20 6d  format, and so m
13a0: 75 73 74 20 62 65 20 61 72 63 68 69 74 65 63 74  ust be architect
13b0: 75 72 65 20 69 6e 64 65 70 65 6e 64 65 6e 74 2e  ure independent.
13c0: 0a 2a 2a 0a 2a 2a 20 55 6e 6c 69 6b 65 20 74 68  .**.** Unlike th
13d0: 65 20 53 51 4c 69 74 65 20 64 61 74 61 62 61 73  e SQLite databas
13e0: 65 20 72 65 63 6f 72 64 20 66 6f 72 6d 61 74 2c  e record format,
13f0: 20 65 61 63 68 20 66 69 65 6c 64 20 69 73 20 73   each field is s
1400: 65 6c 66 2d 63 6f 6e 74 61 69 6e 65 64 20 2d 0a  elf-contained -.
1410: 2a 2a 20 74 68 65 72 65 20 69 73 20 6e 6f 20 73  ** there is no s
1420: 65 70 61 72 61 74 69 6f 6e 20 6f 66 20 68 65 61  eparation of hea
1430: 64 65 72 20 61 6e 64 20 64 61 74 61 2e 20 45 61  der and data. Ea
1440: 63 68 20 66 69 65 6c 64 20 62 65 67 69 6e 73 20  ch field begins 
1450: 77 69 74 68 20 61 0a 2a 2a 20 73 69 6e 67 6c 65  with a.** single
1460: 20 62 79 74 65 20 64 65 73 63 72 69 62 69 6e 67   byte describing
1470: 20 69 74 73 20 74 79 70 65 2c 20 61 73 20 66 6f   its type, as fo
1480: 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20  llows:.**.**    
1490: 20 20 20 30 78 30 30 3a 20 55 6e 64 65 66 69 6e     0x00: Undefin
14a0: 65 64 20 76 61 6c 75 65 2e 0a 2a 2a 20 20 20 20  ed value..**    
14b0: 20 20 20 30 78 30 31 3a 20 49 6e 74 65 67 65 72     0x01: Integer
14c0: 20 76 61 6c 75 65 2e 0a 2a 2a 20 20 20 20 20 20   value..**      
14d0: 20 30 78 30 32 3a 20 52 65 61 6c 20 76 61 6c 75   0x02: Real valu
14e0: 65 2e 0a 2a 2a 20 20 20 20 20 20 20 30 78 30 33  e..**       0x03
14f0: 3a 20 54 65 78 74 20 76 61 6c 75 65 2e 0a 2a 2a  : Text value..**
1500: 20 20 20 20 20 20 20 30 78 30 34 3a 20 42 6c 6f         0x04: Blo
1510: 62 20 76 61 6c 75 65 2e 0a 2a 2a 20 20 20 20 20  b value..**     
1520: 20 20 30 78 30 35 3a 20 53 51 4c 20 4e 55 4c 4c    0x05: SQL NULL
1530: 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 4e 6f   value..**.** No
1540: 74 65 20 74 68 61 74 20 74 68 65 20 61 62 6f 76  te that the abov
1550: 65 20 6d 61 74 63 68 20 74 68 65 20 64 65 66 69  e match the defi
1560: 6e 69 74 69 6f 6e 73 20 6f 66 20 53 51 4c 49 54  nitions of SQLIT
1570: 45 5f 49 4e 54 45 47 45 52 2c 20 53 51 4c 49 54  E_INTEGER, SQLIT
1580: 45 5f 54 45 58 54 0a 2a 2a 20 61 6e 64 20 73 6f  E_TEXT.** and so
1590: 20 6f 6e 20 69 6e 20 73 71 6c 69 74 65 33 2e 68   on in sqlite3.h
15a0: 2e 20 46 6f 72 20 75 6e 64 65 66 69 6e 65 64 20  . For undefined 
15b0: 61 6e 64 20 4e 55 4c 4c 20 76 61 6c 75 65 73 2c  and NULL values,
15c0: 20 74 68 65 20 66 69 65 6c 64 20 63 6f 6e 73 69   the field consi
15d0: 73 74 73 0a 2a 2a 20 6f 6e 6c 79 20 6f 66 20 74  sts.** only of t
15e0: 68 65 20 73 69 6e 67 6c 65 20 74 79 70 65 20 62  he single type b
15f0: 79 74 65 2e 20 46 6f 72 20 6f 74 68 65 72 20 74  yte. For other t
1600: 79 70 65 73 20 6f 66 20 76 61 6c 75 65 73 2c 20  ypes of values, 
1610: 74 68 65 20 74 79 70 65 20 62 79 74 65 0a 2a 2a  the type byte.**
1620: 20 69 73 20 66 6f 6c 6c 6f 77 65 64 20 62 79 3a   is followed by:
1630: 0a 2a 2a 0a 2a 2a 20 20 20 54 65 78 74 20 76 61  .**.**   Text va
1640: 6c 75 65 73 3a 0a 2a 2a 20 20 20 20 20 41 20 76  lues:.**     A v
1650: 61 72 69 6e 74 20 63 6f 6e 74 61 69 6e 69 6e 67  arint containing
1660: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62   the number of b
1670: 79 74 65 73 20 69 6e 20 74 68 65 20 76 61 6c 75  ytes in the valu
1680: 65 20 28 65 6e 63 6f 64 65 64 20 75 73 69 6e 67  e (encoded using
1690: 0a 2a 2a 20 20 20 20 20 55 54 46 2d 38 29 2e 20  .**     UTF-8). 
16a0: 46 6f 6c 6c 6f 77 65 64 20 62 79 20 61 20 62 75  Followed by a bu
16b0: 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ffer containing 
16c0: 74 68 65 20 55 54 46 2d 38 20 72 65 70 72 65 73  the UTF-8 repres
16d0: 65 6e 74 61 74 69 6f 6e 0a 2a 2a 20 20 20 20 20  entation.**     
16e0: 6f 66 20 74 68 65 20 74 65 78 74 20 76 61 6c 75  of the text valu
16f0: 65 2e 20 54 68 65 72 65 20 69 73 20 6e 6f 20 6e  e. There is no n
1700: 75 6c 20 74 65 72 6d 69 6e 61 74 6f 72 2e 0a 2a  ul terminator..*
1710: 2a 0a 2a 2a 20 20 20 42 6c 6f 62 20 76 61 6c 75  *.**   Blob valu
1720: 65 73 3a 0a 2a 2a 20 20 20 20 20 41 20 76 61 72  es:.**     A var
1730: 69 6e 74 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74  int containing t
1740: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  he number of byt
1750: 65 73 20 69 6e 20 74 68 65 20 76 61 6c 75 65 2c  es in the value,
1760: 20 66 6f 6c 6c 6f 77 65 64 20 62 79 0a 2a 2a 20   followed by.** 
1770: 20 20 20 20 61 20 62 75 66 66 65 72 20 63 6f 6e      a buffer con
1780: 74 61 69 6e 69 6e 67 20 74 68 65 20 76 61 6c 75  taining the valu
1790: 65 20 69 74 73 65 6c 66 2e 0a 2a 2a 0a 2a 2a 20  e itself..**.** 
17a0: 20 20 49 6e 74 65 67 65 72 20 76 61 6c 75 65 73    Integer values
17b0: 3a 0a 2a 2a 20 20 20 20 20 41 6e 20 38 2d 62 79  :.**     An 8-by
17c0: 74 65 20 62 69 67 2d 65 6e 64 69 61 6e 20 69 6e  te big-endian in
17d0: 74 65 67 65 72 20 76 61 6c 75 65 2e 0a 2a 2a 0a  teger value..**.
17e0: 2a 2a 20 20 20 52 65 61 6c 20 76 61 6c 75 65 73  **   Real values
17f0: 3a 0a 2a 2a 20 20 20 20 20 41 6e 20 38 2d 62 79  :.**     An 8-by
1800: 74 65 20 62 69 67 2d 65 6e 64 69 61 6e 20 49 45  te big-endian IE
1810: 45 45 20 37 35 34 2d 32 30 30 38 20 72 65 61 6c  EE 754-2008 real
1820: 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 56 61   value..**.** Va
1830: 72 69 6e 74 20 76 61 6c 75 65 73 20 61 72 65 20  rint values are 
1840: 65 6e 63 6f 64 65 64 20 69 6e 20 74 68 65 20 73  encoded in the s
1850: 61 6d 65 20 77 61 79 20 61 73 20 76 61 72 69 6e  ame way as varin
1860: 74 73 20 69 6e 20 74 68 65 20 53 51 4c 69 74 65  ts in the SQLite
1870: 20 0a 2a 2a 20 72 65 63 6f 72 64 20 66 6f 72 6d   .** record form
1880: 61 74 2e 0a 2a 2a 0a 2a 2a 20 43 48 41 4e 47 45  at..**.** CHANGE
1890: 53 45 54 20 46 4f 52 4d 41 54 3a 0a 2a 2a 0a 2a  SET FORMAT:.**.*
18a0: 2a 20 41 20 63 68 61 6e 67 65 73 65 74 20 69 73  * A changeset is
18b0: 20 61 20 63 6f 6c 6c 65 63 74 69 6f 6e 20 6f 66   a collection of
18c0: 20 44 45 4c 45 54 45 2c 20 55 50 44 41 54 45 20   DELETE, UPDATE 
18d0: 61 6e 64 20 49 4e 53 45 52 54 20 6f 70 65 72 61  and INSERT opera
18e0: 74 69 6f 6e 73 20 6f 6e 0a 2a 2a 20 6f 6e 65 20  tions on.** one 
18f0: 6f 72 20 6d 6f 72 65 20 74 61 62 6c 65 73 2e 20  or more tables. 
1900: 4f 70 65 72 61 74 69 6f 6e 73 20 6f 6e 20 61 20  Operations on a 
1910: 73 69 6e 67 6c 65 20 74 61 62 6c 65 20 61 72 65  single table are
1920: 20 67 72 6f 75 70 65 64 20 74 6f 67 65 74 68 65   grouped togethe
1930: 72 2c 0a 2a 2a 20 62 75 74 20 6d 61 79 20 6f 63  r,.** but may oc
1940: 63 75 72 20 69 6e 20 61 6e 79 20 6f 72 64 65 72  cur in any order
1950: 20 28 69 2e 65 2e 20 64 65 6c 65 74 65 73 2c 20   (i.e. deletes, 
1960: 75 70 64 61 74 65 73 20 61 6e 64 20 69 6e 73 65  updates and inse
1970: 72 74 73 20 61 72 65 20 61 6c 6c 0a 2a 2a 20 6d  rts are all.** m
1980: 69 78 65 64 20 74 6f 67 65 74 68 65 72 29 2e 0a  ixed together)..
1990: 2a 2a 0a 2a 2a 20 45 61 63 68 20 67 72 6f 75 70  **.** Each group
19a0: 20 6f 66 20 63 68 61 6e 67 65 73 20 62 65 67 69   of changes begi
19b0: 6e 73 20 77 69 74 68 20 61 20 74 61 62 6c 65 20  ns with a table 
19c0: 68 65 61 64 65 72 3a 0a 2a 2a 0a 2a 2a 20 20 20  header:.**.**   
19d0: 31 20 62 79 74 65 3a 20 43 6f 6e 73 74 61 6e 74  1 byte: Constant
19e0: 20 30 78 35 34 20 28 63 61 70 69 74 61 6c 20 27   0x54 (capital '
19f0: 54 27 29 0a 2a 2a 20 20 20 56 61 72 69 6e 74 3a  T').**   Varint:
1a00: 20 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d   Number of colum
1a10: 6e 73 20 69 6e 20 74 68 65 20 74 61 62 6c 65 2e  ns in the table.
1a20: 0a 2a 2a 20 20 20 6e 43 6f 6c 20 62 79 74 65 73  .**   nCol bytes
1a30: 3a 20 30 78 30 31 20 66 6f 72 20 50 4b 20 63 6f  : 0x01 for PK co
1a40: 6c 75 6d 6e 73 2c 20 30 78 30 30 20 6f 74 68 65  lumns, 0x00 othe
1a50: 72 77 69 73 65 2e 0a 2a 2a 20 20 20 4e 20 62 79  rwise..**   N by
1a60: 74 65 73 3a 20 55 6e 71 75 61 6c 69 66 69 65 64  tes: Unqualified
1a70: 20 74 61 62 6c 65 20 6e 61 6d 65 20 28 65 6e 63   table name (enc
1a80: 6f 64 65 64 20 75 73 69 6e 67 20 55 54 46 2d 38  oded using UTF-8
1a90: 29 2e 20 4e 75 6c 2d 74 65 72 6d 69 6e 61 74 65  ). Nul-terminate
1aa0: 64 2e 0a 2a 2a 0a 2a 2a 20 46 6f 6c 6c 6f 77 65  d..**.** Followe
1ab0: 64 20 62 79 20 6f 6e 65 20 6f 72 20 6d 6f 72 65  d by one or more
1ac0: 20 63 68 61 6e 67 65 73 20 74 6f 20 74 68 65 20   changes to the 
1ad0: 74 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 31  table..**.**   1
1ae0: 20 62 79 74 65 3a 20 45 69 74 68 65 72 20 53 51   byte: Either SQ
1af0: 4c 49 54 45 5f 49 4e 53 45 52 54 20 28 30 78 31  LITE_INSERT (0x1
1b00: 32 29 2c 20 55 50 44 41 54 45 20 28 30 78 31 37  2), UPDATE (0x17
1b10: 29 20 6f 72 20 44 45 4c 45 54 45 20 28 30 78 30  ) or DELETE (0x0
1b20: 39 29 2e 0a 2a 2a 20 20 20 31 20 62 79 74 65 3a  9)..**   1 byte:
1b30: 20 54 68 65 20 22 69 6e 64 69 72 65 63 74 2d 63   The "indirect-c
1b40: 68 61 6e 67 65 22 20 66 6c 61 67 2e 0a 2a 2a 20  hange" flag..** 
1b50: 20 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 3a 20    old.* record: 
1b60: 28 64 65 6c 65 74 65 20 61 6e 64 20 75 70 64 61  (delete and upda
1b70: 74 65 20 6f 6e 6c 79 29 0a 2a 2a 20 20 20 6e 65  te only).**   ne
1b80: 77 2e 2a 20 72 65 63 6f 72 64 3a 20 28 69 6e 73  w.* record: (ins
1b90: 65 72 74 20 61 6e 64 20 75 70 64 61 74 65 20 6f  ert and update o
1ba0: 6e 6c 79 29 0a 2a 2a 0a 2a 2a 20 54 68 65 20 22  nly).**.** The "
1bb0: 6f 6c 64 2e 2a 22 20 61 6e 64 20 22 6e 65 77 2e  old.*" and "new.
1bc0: 2a 22 20 72 65 63 6f 72 64 73 2c 20 69 66 20 70  *" records, if p
1bd0: 72 65 73 65 6e 74 2c 20 61 72 65 20 4e 20 66 69  resent, are N fi
1be0: 65 6c 64 20 72 65 63 6f 72 64 73 20 69 6e 20 74  eld records in t
1bf0: 68 65 0a 2a 2a 20 66 6f 72 6d 61 74 20 64 65 73  he.** format des
1c00: 63 72 69 62 65 64 20 61 62 6f 76 65 20 75 6e 64  cribed above und
1c10: 65 72 20 22 52 45 43 4f 52 44 20 46 4f 52 4d 41  er "RECORD FORMA
1c20: 54 22 2c 20 77 68 65 72 65 20 4e 20 69 73 20 74  T", where N is t
1c30: 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a 2a 2a 20  he number of.** 
1c40: 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 68 65 20 74  columns in the t
1c50: 61 62 6c 65 2e 20 54 68 65 20 69 27 74 68 20 66  able. The i'th f
1c60: 69 65 6c 64 20 6f 66 20 65 61 63 68 20 72 65 63  ield of each rec
1c70: 6f 72 64 20 69 73 20 61 73 73 6f 63 69 61 74 65  ord is associate
1c80: 64 20 77 69 74 68 0a 2a 2a 20 74 68 65 20 69 27  d with.** the i'
1c90: 74 68 20 63 6f 6c 75 6d 6e 20 6f 66 20 74 68 65  th column of the
1ca0: 20 74 61 62 6c 65 2c 20 63 6f 75 6e 74 69 6e 67   table, counting
1cb0: 20 66 72 6f 6d 20 6c 65 66 74 20 74 6f 20 72 69   from left to ri
1cc0: 67 68 74 20 69 6e 20 74 68 65 20 6f 72 64 65 72  ght in the order
1cd0: 0a 2a 2a 20 69 6e 20 77 68 69 63 68 20 63 6f 6c  .** in which col
1ce0: 75 6d 6e 73 20 77 65 72 65 20 64 65 63 6c 61 72  umns were declar
1cf0: 65 64 20 69 6e 20 74 68 65 20 43 52 45 41 54 45  ed in the CREATE
1d00: 20 54 41 42 4c 45 20 73 74 61 74 65 6d 65 6e 74   TABLE statement
1d10: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6e 65 77 2e  ..**.** The new.
1d20: 2a 20 72 65 63 6f 72 64 20 74 68 61 74 20 69 73  * record that is
1d30: 20 70 61 72 74 20 6f 66 20 65 61 63 68 20 49 4e   part of each IN
1d40: 53 45 52 54 20 63 68 61 6e 67 65 20 63 6f 6e 74  SERT change cont
1d50: 61 69 6e 73 20 74 68 65 20 76 61 6c 75 65 73 0a  ains the values.
1d60: 2a 2a 20 74 68 61 74 20 6d 61 6b 65 20 75 70 20  ** that make up 
1d70: 74 68 65 20 6e 65 77 20 72 6f 77 2e 20 53 69 6d  the new row. Sim
1d80: 69 6c 61 72 6c 79 2c 20 74 68 65 20 6f 6c 64 2e  ilarly, the old.
1d90: 2a 20 72 65 63 6f 72 64 20 74 68 61 74 20 69 73  * record that is
1da0: 20 70 61 72 74 20 6f 66 20 65 61 63 68 0a 2a 2a   part of each.**
1db0: 20 44 45 4c 45 54 45 20 63 68 61 6e 67 65 20 63   DELETE change c
1dc0: 6f 6e 74 61 69 6e 73 20 74 68 65 20 76 61 6c 75  ontains the valu
1dd0: 65 73 20 74 68 61 74 20 6d 61 64 65 20 75 70 20  es that made up 
1de0: 74 68 65 20 72 6f 77 20 74 68 61 74 20 77 61 73  the row that was
1df0: 20 64 65 6c 65 74 65 64 20 0a 2a 2a 20 66 72 6f   deleted .** fro
1e00: 6d 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 20  m the database. 
1e10: 49 6e 20 74 68 65 20 63 68 61 6e 67 65 73 65 74  In the changeset
1e20: 20 66 6f 72 6d 61 74 2c 20 74 68 65 20 72 65 63   format, the rec
1e30: 6f 72 64 73 20 74 68 61 74 20 61 72 65 20 70 61  ords that are pa
1e40: 72 74 0a 2a 2a 20 6f 66 20 49 4e 53 45 52 54 20  rt.** of INSERT 
1e50: 6f 72 20 44 45 4c 45 54 45 20 63 68 61 6e 67 65  or DELETE change
1e60: 73 20 6e 65 76 65 72 20 63 6f 6e 74 61 69 6e 20  s never contain 
1e70: 61 6e 79 20 75 6e 64 65 66 69 6e 65 64 20 28 74  any undefined (t
1e80: 79 70 65 20 62 79 74 65 20 30 78 30 30 29 0a 2a  ype byte 0x00).*
1e90: 2a 20 66 69 65 6c 64 73 2e 0a 2a 2a 0a 2a 2a 20  * fields..**.** 
1ea0: 57 69 74 68 69 6e 20 74 68 65 20 6f 6c 64 2e 2a  Within the old.*
1eb0: 20 72 65 63 6f 72 64 20 61 73 73 6f 63 69 61 74   record associat
1ec0: 65 64 20 77 69 74 68 20 61 6e 20 55 50 44 41 54  ed with an UPDAT
1ed0: 45 20 63 68 61 6e 67 65 2c 20 61 6c 6c 20 66 69  E change, all fi
1ee0: 65 6c 64 73 0a 2a 2a 20 61 73 73 6f 63 69 61 74  elds.** associat
1ef0: 65 64 20 77 69 74 68 20 74 61 62 6c 65 20 63 6f  ed with table co
1f00: 6c 75 6d 6e 73 20 74 68 61 74 20 61 72 65 20 6e  lumns that are n
1f10: 6f 74 20 50 52 49 4d 41 52 59 20 4b 45 59 20 63  ot PRIMARY KEY c
1f20: 6f 6c 75 6d 6e 73 20 61 6e 64 20 61 72 65 0a 2a  olumns and are.*
1f30: 2a 20 6e 6f 74 20 6d 6f 64 69 66 69 65 64 20 62  * not modified b
1f40: 79 20 74 68 65 20 55 50 44 41 54 45 20 63 68 61  y the UPDATE cha
1f50: 6e 67 65 20 61 72 65 20 73 65 74 20 74 6f 20 22  nge are set to "
1f60: 75 6e 64 65 66 69 6e 65 64 22 2e 20 4f 74 68 65  undefined". Othe
1f70: 72 20 66 69 65 6c 64 73 0a 2a 2a 20 61 72 65 20  r fields.** are 
1f80: 73 65 74 20 74 6f 20 74 68 65 20 76 61 6c 75 65  set to the value
1f90: 73 20 74 68 61 74 20 6d 61 64 65 20 75 70 20 74  s that made up t
1fa0: 68 65 20 72 6f 77 20 62 65 66 6f 72 65 20 74 68  he row before th
1fb0: 65 20 55 50 44 41 54 45 20 74 68 61 74 20 74 68  e UPDATE that th
1fc0: 65 0a 2a 2a 20 63 68 61 6e 67 65 20 72 65 63 6f  e.** change reco
1fd0: 72 64 73 20 74 6f 6f 6b 20 70 6c 61 63 65 2e 20  rds took place. 
1fe0: 57 69 74 68 69 6e 20 74 68 65 20 6e 65 77 2e 2a  Within the new.*
1ff0: 20 72 65 63 6f 72 64 2c 20 66 69 65 6c 64 73 20   record, fields 
2000: 61 73 73 6f 63 69 61 74 65 64 20 0a 2a 2a 20 77  associated .** w
2010: 69 74 68 20 74 61 62 6c 65 20 63 6f 6c 75 6d 6e  ith table column
2020: 73 20 6d 6f 64 69 66 69 65 64 20 62 79 20 74 68  s modified by th
2030: 65 20 55 50 44 41 54 45 20 63 68 61 6e 67 65 20  e UPDATE change 
2040: 63 6f 6e 74 61 69 6e 20 74 68 65 20 6e 65 77 20  contain the new 
2050: 0a 2a 2a 20 76 61 6c 75 65 73 2e 20 46 69 65 6c  .** values. Fiel
2060: 64 73 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  ds associated wi
2070: 74 68 20 74 61 62 6c 65 20 63 6f 6c 75 6d 6e 73  th table columns
2080: 20 74 68 61 74 20 61 72 65 20 6e 6f 74 20 6d 6f   that are not mo
2090: 64 69 66 69 65 64 0a 2a 2a 20 61 72 65 20 73 65  dified.** are se
20a0: 74 20 74 6f 20 22 75 6e 64 65 66 69 6e 65 64 22  t to "undefined"
20b0: 2e 0a 2a 2a 0a 2a 2a 20 50 41 54 43 48 53 45 54  ..**.** PATCHSET
20c0: 20 46 4f 52 4d 41 54 3a 0a 2a 2a 0a 2a 2a 20 41   FORMAT:.**.** A
20d0: 20 70 61 74 63 68 73 65 74 20 69 73 20 61 6c 73   patchset is als
20e0: 6f 20 61 20 63 6f 6c 6c 65 63 74 69 6f 6e 20 6f  o a collection o
20f0: 66 20 63 68 61 6e 67 65 73 2e 20 49 74 20 69 73  f changes. It is
2100: 20 73 69 6d 69 6c 61 72 20 74 6f 20 61 20 63 68   similar to a ch
2110: 61 6e 67 65 73 65 74 2c 0a 2a 2a 20 62 75 74 20  angeset,.** but 
2120: 6c 65 61 76 65 73 20 75 6e 64 65 66 69 6e 65 64  leaves undefined
2130: 20 74 68 6f 73 65 20 66 69 65 6c 64 73 20 74 68   those fields th
2140: 61 74 20 61 72 65 20 6e 6f 74 20 75 73 65 66 75  at are not usefu
2150: 6c 20 69 66 20 6e 6f 20 63 6f 6e 66 6c 69 63 74  l if no conflict
2160: 0a 2a 2a 20 72 65 73 6f 6c 75 74 69 6f 6e 20 69  .** resolution i
2170: 73 20 72 65 71 75 69 72 65 64 20 77 68 65 6e 20  s required when 
2180: 61 70 70 6c 79 69 6e 67 20 74 68 65 20 63 68 61  applying the cha
2190: 6e 67 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 45 61  ngeset..**.** Ea
21a0: 63 68 20 67 72 6f 75 70 20 6f 66 20 63 68 61 6e  ch group of chan
21b0: 67 65 73 20 62 65 67 69 6e 73 20 77 69 74 68 20  ges begins with 
21c0: 61 20 74 61 62 6c 65 20 68 65 61 64 65 72 3a 0a  a table header:.
21d0: 2a 2a 0a 2a 2a 20 20 20 31 20 62 79 74 65 3a 20  **.**   1 byte: 
21e0: 43 6f 6e 73 74 61 6e 74 20 30 78 35 30 20 28 63  Constant 0x50 (c
21f0: 61 70 69 74 61 6c 20 27 50 27 29 0a 2a 2a 20 20  apital 'P').**  
2200: 20 56 61 72 69 6e 74 3a 20 4e 75 6d 62 65 72 20   Varint: Number 
2210: 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 68  of columns in th
2220: 65 20 74 61 62 6c 65 2e 0a 2a 2a 20 20 20 6e 43  e table..**   nC
2230: 6f 6c 20 62 79 74 65 73 3a 20 30 78 30 31 20 66  ol bytes: 0x01 f
2240: 6f 72 20 50 4b 20 63 6f 6c 75 6d 6e 73 2c 20 30  or PK columns, 0
2250: 78 30 30 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a  x00 otherwise..*
2260: 2a 20 20 20 4e 20 62 79 74 65 73 3a 20 55 6e 71  *   N bytes: Unq
2270: 75 61 6c 69 66 69 65 64 20 74 61 62 6c 65 20 6e  ualified table n
2280: 61 6d 65 20 28 65 6e 63 6f 64 65 64 20 75 73 69  ame (encoded usi
2290: 6e 67 20 55 54 46 2d 38 29 2e 20 4e 75 6c 2d 74  ng UTF-8). Nul-t
22a0: 65 72 6d 69 6e 61 74 65 64 2e 0a 2a 2a 0a 2a 2a  erminated..**.**
22b0: 20 46 6f 6c 6c 6f 77 65 64 20 62 79 20 6f 6e 65   Followed by one
22c0: 20 6f 72 20 6d 6f 72 65 20 63 68 61 6e 67 65 73   or more changes
22d0: 20 74 6f 20 74 68 65 20 74 61 62 6c 65 2e 0a 2a   to the table..*
22e0: 2a 0a 2a 2a 20 20 20 31 20 62 79 74 65 3a 20 45  *.**   1 byte: E
22f0: 69 74 68 65 72 20 53 51 4c 49 54 45 5f 49 4e 53  ither SQLITE_INS
2300: 45 52 54 20 28 30 78 31 32 29 2c 20 55 50 44 41  ERT (0x12), UPDA
2310: 54 45 20 28 30 78 31 37 29 20 6f 72 20 44 45 4c  TE (0x17) or DEL
2320: 45 54 45 20 28 30 78 30 39 29 2e 0a 2a 2a 20 20  ETE (0x09)..**  
2330: 20 31 20 62 79 74 65 3a 20 54 68 65 20 22 69 6e   1 byte: The "in
2340: 64 69 72 65 63 74 2d 63 68 61 6e 67 65 22 20 66  direct-change" f
2350: 6c 61 67 2e 0a 2a 2a 20 20 20 73 69 6e 67 6c 65  lag..**   single
2360: 20 72 65 63 6f 72 64 3a 20 28 50 4b 20 66 69 65   record: (PK fie
2370: 6c 64 73 20 66 6f 72 20 44 45 4c 45 54 45 2c 20  lds for DELETE, 
2380: 50 4b 20 61 6e 64 20 6d 6f 64 69 66 69 65 64 20  PK and modified 
2390: 66 69 65 6c 64 73 20 66 6f 72 20 55 50 44 41 54  fields for UPDAT
23a0: 45 2c 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20  E,.**           
23b0: 20 20 20 20 20 20 20 20 66 75 6c 6c 20 72 65 63          full rec
23c0: 6f 72 64 20 66 6f 72 20 49 4e 53 45 52 54 29 2e  ord for INSERT).
23d0: 0a 2a 2a 0a 2a 2a 20 41 73 20 69 6e 20 74 68 65  .**.** As in the
23e0: 20 63 68 61 6e 67 65 73 65 74 20 66 6f 72 6d 61   changeset forma
23f0: 74 2c 20 65 61 63 68 20 66 69 65 6c 64 20 6f 66  t, each field of
2400: 20 74 68 65 20 73 69 6e 67 6c 65 20 72 65 63 6f   the single reco
2410: 72 64 20 74 68 61 74 20 69 73 20 70 61 72 74 0a  rd that is part.
2420: 2a 2a 20 6f 66 20 61 20 70 61 74 63 68 73 65 74  ** of a patchset
2430: 20 63 68 61 6e 67 65 20 69 73 20 61 73 73 6f 63   change is assoc
2440: 69 61 74 65 64 20 77 69 74 68 20 74 68 65 20 63  iated with the c
2450: 6f 72 72 65 73 70 6f 6e 64 69 6e 67 6c 79 20 70  orrespondingly p
2460: 6f 73 69 74 69 6f 6e 65 64 0a 2a 2a 20 74 61 62  ositioned.** tab
2470: 6c 65 20 63 6f 6c 75 6d 6e 2c 20 63 6f 75 6e 74  le column, count
2480: 69 6e 67 20 66 72 6f 6d 20 6c 65 66 74 20 74 6f  ing from left to
2490: 20 72 69 67 68 74 20 77 69 74 68 69 6e 20 74 68   right within th
24a0: 65 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 0a  e CREATE TABLE .
24b0: 2a 2a 20 73 74 61 74 65 6d 65 6e 74 2e 0a 2a 2a  ** statement..**
24c0: 0a 2a 2a 20 46 6f 72 20 61 20 44 45 4c 45 54 45  .** For a DELETE
24d0: 20 63 68 61 6e 67 65 2c 20 61 6c 6c 20 66 69 65   change, all fie
24e0: 6c 64 73 20 77 69 74 68 69 6e 20 74 68 65 20 72  lds within the r
24f0: 65 63 6f 72 64 20 65 78 63 65 70 74 20 74 68 6f  ecord except tho
2500: 73 65 20 61 73 73 6f 63 69 61 74 65 64 0a 2a 2a  se associated.**
2510: 20 77 69 74 68 20 50 52 49 4d 41 52 59 20 4b 45   with PRIMARY KE
2520: 59 20 63 6f 6c 75 6d 6e 73 20 61 72 65 20 73 65  Y columns are se
2530: 74 20 74 6f 20 22 75 6e 64 65 66 69 6e 65 64 22  t to "undefined"
2540: 2e 20 54 68 65 20 50 52 49 4d 41 52 59 20 4b 45  . The PRIMARY KE
2550: 59 20 66 69 65 6c 64 73 0a 2a 2a 20 63 6f 6e 74  Y fields.** cont
2560: 61 69 6e 20 74 68 65 20 76 61 6c 75 65 73 20 69  ain the values i
2570: 64 65 6e 74 69 66 79 69 6e 67 20 74 68 65 20 72  dentifying the r
2580: 6f 77 20 74 6f 20 64 65 6c 65 74 65 2e 0a 2a 2a  ow to delete..**
2590: 0a 2a 2a 20 46 6f 72 20 61 6e 20 55 50 44 41 54  .** For an UPDAT
25a0: 45 20 63 68 61 6e 67 65 2c 20 61 6c 6c 20 66 69  E change, all fi
25b0: 65 6c 64 73 20 65 78 63 65 70 74 20 74 68 6f 73  elds except thos
25c0: 65 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74  e associated wit
25d0: 68 20 50 52 49 4d 41 52 59 20 4b 45 59 0a 2a 2a  h PRIMARY KEY.**
25e0: 20 63 6f 6c 75 6d 6e 73 20 61 6e 64 20 63 6f 6c   columns and col
25f0: 75 6d 6e 73 20 74 68 61 74 20 61 72 65 20 6d 6f  umns that are mo
2600: 64 69 66 69 65 64 20 62 79 20 74 68 65 20 55 50  dified by the UP
2610: 44 41 54 45 20 61 72 65 20 73 65 74 20 74 6f 20  DATE are set to 
2620: 22 75 6e 64 65 66 69 6e 65 64 22 2e 0a 2a 2a 20  "undefined"..** 
2630: 50 52 49 4d 41 52 59 20 4b 45 59 20 66 69 65 6c  PRIMARY KEY fiel
2640: 64 73 20 63 6f 6e 74 61 69 6e 20 74 68 65 20 76  ds contain the v
2650: 61 6c 75 65 73 20 69 64 65 6e 74 69 66 79 69 6e  alues identifyin
2660: 67 20 74 68 65 20 74 61 62 6c 65 20 72 6f 77 20  g the table row 
2670: 74 6f 20 75 70 64 61 74 65 2c 0a 2a 2a 20 61 6e  to update,.** an
2680: 64 20 66 69 65 6c 64 73 20 61 73 73 6f 63 69 61  d fields associa
2690: 74 65 64 20 77 69 74 68 20 6d 6f 64 69 66 69 65  ted with modifie
26a0: 64 20 63 6f 6c 75 6d 6e 73 20 63 6f 6e 74 61 69  d columns contai
26b0: 6e 20 74 68 65 20 6e 65 77 20 63 6f 6c 75 6d 6e  n the new column
26c0: 20 76 61 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 54   values..**.** T
26d0: 68 65 20 72 65 63 6f 72 64 73 20 61 73 73 6f 63  he records assoc
26e0: 69 61 74 65 64 20 77 69 74 68 20 49 4e 53 45 52  iated with INSER
26f0: 54 20 63 68 61 6e 67 65 73 20 61 72 65 20 69 6e  T changes are in
2700: 20 74 68 65 20 73 61 6d 65 20 66 6f 72 6d 61 74   the same format
2710: 20 61 73 20 66 6f 72 0a 2a 2a 20 63 68 61 6e 67   as for.** chang
2720: 65 73 65 74 73 2e 20 49 74 20 69 73 20 6e 6f 74  esets. It is not
2730: 20 70 6f 73 73 69 62 6c 65 20 66 6f 72 20 61 20   possible for a 
2740: 72 65 63 6f 72 64 20 61 73 73 6f 63 69 61 74 65  record associate
2750: 64 20 77 69 74 68 20 61 6e 20 49 4e 53 45 52 54  d with an INSERT
2760: 0a 2a 2a 20 63 68 61 6e 67 65 20 74 6f 20 63 6f  .** change to co
2770: 6e 74 61 69 6e 20 61 20 66 69 65 6c 64 20 73 65  ntain a field se
2780: 74 20 74 6f 20 22 75 6e 64 65 66 69 6e 65 64 22  t to "undefined"
2790: 2e 0a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 46 6f 72 20  ..*/../*.** For 
27a0: 65 61 63 68 20 72 6f 77 20 6d 6f 64 69 66 69 65  each row modifie
27b0: 64 20 64 75 72 69 6e 67 20 61 20 73 65 73 73 69  d during a sessi
27c0: 6f 6e 2c 20 74 68 65 72 65 20 65 78 69 73 74 73  on, there exists
27d0: 20 61 20 73 69 6e 67 6c 65 20 69 6e 73 74 61 6e   a single instan
27e0: 63 65 20 6f 66 0a 2a 2a 20 74 68 69 73 20 73 74  ce of.** this st
27f0: 72 75 63 74 75 72 65 20 73 74 6f 72 65 64 20 69  ructure stored i
2800: 6e 20 61 20 53 65 73 73 69 6f 6e 54 61 62 6c 65  n a SessionTable
2810: 2e 61 43 68 61 6e 67 65 5b 5d 20 68 61 73 68 20  .aChange[] hash 
2820: 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 72 75 63 74  table..*/.struct
2830: 20 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 7b   SessionChange {
2840: 0a 20 20 69 6e 74 20 6f 70 3b 20 20 20 20 20 20  .  int op;      
2850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2860: 20 20 20 2f 2a 20 4f 6e 65 20 6f 66 20 55 50 44     /* One of UPD
2870: 41 54 45 2c 20 44 45 4c 45 54 45 2c 20 49 4e 53  ATE, DELETE, INS
2880: 45 52 54 20 2a 2f 0a 20 20 69 6e 74 20 62 49 6e  ERT */.  int bIn
2890: 64 69 72 65 63 74 3b 20 20 20 20 20 20 20 20 20  direct;         
28a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
28b0: 20 69 66 20 74 68 69 73 20 63 68 61 6e 67 65 20   if this change 
28c0: 69 73 20 22 69 6e 64 69 72 65 63 74 22 20 2a 2f  is "indirect" */
28d0: 0a 20 20 69 6e 74 20 6e 52 65 63 6f 72 64 3b 20  .  int nRecord; 
28e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
28f0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
2900: 62 79 74 65 73 20 69 6e 20 62 75 66 66 65 72 20  bytes in buffer 
2910: 61 52 65 63 6f 72 64 5b 5d 20 2a 2f 0a 20 20 75  aRecord[] */.  u
2920: 38 20 2a 61 52 65 63 6f 72 64 3b 20 20 20 20 20  8 *aRecord;     
2930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2940: 2a 20 42 75 66 66 65 72 20 63 6f 6e 74 61 69 6e  * Buffer contain
2950: 69 6e 67 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64  ing old.* record
2960: 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 43 68 61   */.  SessionCha
2970: 6e 67 65 20 2a 70 4e 65 78 74 3b 20 20 20 20 20  nge *pNext;     
2980: 20 20 20 20 20 20 2f 2a 20 46 6f 72 20 68 61 73        /* For has
2990: 68 2d 74 61 62 6c 65 20 63 6f 6c 6c 69 73 69 6f  h-table collisio
29a0: 6e 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  ns */.};../*.** 
29b0: 57 72 69 74 65 20 61 20 76 61 72 69 6e 74 20 77  Write a varint w
29c0: 69 74 68 20 76 61 6c 75 65 20 69 56 61 6c 20 69  ith value iVal i
29d0: 6e 74 6f 20 74 68 65 20 62 75 66 66 65 72 20 61  nto the buffer a
29e0: 74 20 61 42 75 66 2e 20 52 65 74 75 72 6e 20 74  t aBuf. Return t
29f0: 68 65 20 0a 2a 2a 20 6e 75 6d 62 65 72 20 6f 66  he .** number of
2a00: 20 62 79 74 65 73 20 77 72 69 74 74 65 6e 2e 0a   bytes written..
2a10: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
2a20: 73 73 69 6f 6e 56 61 72 69 6e 74 50 75 74 28 75  ssionVarintPut(u
2a30: 38 20 2a 61 42 75 66 2c 20 69 6e 74 20 69 56 61  8 *aBuf, int iVa
2a40: 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 75 74  l){.  return put
2a50: 56 61 72 69 6e 74 33 32 28 61 42 75 66 2c 20 69  Varint32(aBuf, i
2a60: 56 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  Val);.}../*.** R
2a70: 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72  eturn the number
2a80: 20 6f 66 20 62 79 74 65 73 20 72 65 71 75 69 72   of bytes requir
2a90: 65 64 20 74 6f 20 73 74 6f 72 65 20 76 61 6c 75  ed to store valu
2aa0: 65 20 69 56 61 6c 20 61 73 20 61 20 76 61 72 69  e iVal as a vari
2ab0: 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  nt..*/.static in
2ac0: 74 20 73 65 73 73 69 6f 6e 56 61 72 69 6e 74 4c  t sessionVarintL
2ad0: 65 6e 28 69 6e 74 20 69 56 61 6c 29 7b 0a 20 20  en(int iVal){.  
2ae0: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 56 61  return sqlite3Va
2af0: 72 69 6e 74 4c 65 6e 28 69 56 61 6c 29 3b 0a 7d  rintLen(iVal);.}
2b00: 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 61 20 76  ../*.** Read a v
2b10: 61 72 69 6e 74 20 76 61 6c 75 65 20 66 72 6f 6d  arint value from
2b20: 20 61 42 75 66 5b 5d 20 69 6e 74 6f 20 2a 70 69   aBuf[] into *pi
2b30: 56 61 6c 2e 20 52 65 74 75 72 6e 20 74 68 65 20  Val. Return the 
2b40: 6e 75 6d 62 65 72 20 6f 66 20 0a 2a 2a 20 62 79  number of .** by
2b50: 74 65 73 20 72 65 61 64 2e 0a 2a 2f 0a 73 74 61  tes read..*/.sta
2b60: 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 56  tic int sessionV
2b70: 61 72 69 6e 74 47 65 74 28 75 38 20 2a 61 42 75  arintGet(u8 *aBu
2b80: 66 2c 20 69 6e 74 20 2a 70 69 56 61 6c 29 7b 0a  f, int *piVal){.
2b90: 20 20 72 65 74 75 72 6e 20 67 65 74 56 61 72 69    return getVari
2ba0: 6e 74 33 32 28 61 42 75 66 2c 20 2a 70 69 56 61  nt32(aBuf, *piVa
2bb0: 6c 29 3b 0a 7d 0a 0a 2f 2a 20 4c 6f 61 64 20 61  l);.}../* Load a
2bc0: 6e 20 75 6e 61 6c 69 67 6e 65 64 20 61 6e 64 20  n unaligned and 
2bd0: 75 6e 73 69 67 6e 65 64 20 33 32 2d 62 69 74 20  unsigned 32-bit 
2be0: 69 6e 74 65 67 65 72 20 2a 2f 0a 23 64 65 66 69  integer */.#defi
2bf0: 6e 65 20 53 45 53 53 49 4f 4e 5f 55 49 4e 54 33  ne SESSION_UINT3
2c00: 32 28 78 29 20 28 28 28 75 33 32 29 28 78 29 5b  2(x) (((u32)(x)[
2c10: 30 5d 3c 3c 32 34 29 7c 28 28 78 29 5b 31 5d 3c  0]<<24)|((x)[1]<
2c20: 3c 31 36 29 7c 28 28 78 29 5b 32 5d 3c 3c 38 29  <16)|((x)[2]<<8)
2c30: 7c 28 78 29 5b 33 5d 29 0a 0a 2f 2a 0a 2a 2a 20  |(x)[3])../*.** 
2c40: 52 65 61 64 20 61 20 36 34 2d 62 69 74 20 62 69  Read a 64-bit bi
2c50: 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67 65 72  g-endian integer
2c60: 20 76 61 6c 75 65 20 66 72 6f 6d 20 62 75 66 66   value from buff
2c70: 65 72 20 61 52 65 63 5b 5d 2e 20 52 65 74 75 72  er aRec[]. Retur
2c80: 6e 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 20 72  n.** the value r
2c90: 65 61 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73  ead..*/.static s
2ca0: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 73 65 73  qlite3_int64 ses
2cb0: 73 69 6f 6e 47 65 74 49 36 34 28 75 38 20 2a 61  sionGetI64(u8 *a
2cc0: 52 65 63 29 7b 0a 20 20 75 36 34 20 78 20 3d 20  Rec){.  u64 x = 
2cd0: 53 45 53 53 49 4f 4e 5f 55 49 4e 54 33 32 28 61  SESSION_UINT32(a
2ce0: 52 65 63 29 3b 0a 20 20 75 33 32 20 79 20 3d 20  Rec);.  u32 y = 
2cf0: 53 45 53 53 49 4f 4e 5f 55 49 4e 54 33 32 28 61  SESSION_UINT32(a
2d00: 52 65 63 2b 34 29 3b 0a 20 20 78 20 3d 20 28 78  Rec+4);.  x = (x
2d10: 3c 3c 33 32 29 20 2b 20 79 3b 0a 20 20 72 65 74  <<32) + y;.  ret
2d20: 75 72 6e 20 28 73 71 6c 69 74 65 33 5f 69 6e 74  urn (sqlite3_int
2d30: 36 34 29 78 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57  64)x;.}../*.** W
2d40: 72 69 74 65 20 61 20 36 34 2d 62 69 74 20 62 69  rite a 64-bit bi
2d50: 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67 65 72  g-endian integer
2d60: 20 76 61 6c 75 65 20 74 6f 20 74 68 65 20 62 75   value to the bu
2d70: 66 66 65 72 20 61 42 75 66 5b 5d 2e 0a 2a 2f 0a  ffer aBuf[]..*/.
2d80: 73 74 61 74 69 63 20 76 6f 69 64 20 73 65 73 73  static void sess
2d90: 69 6f 6e 50 75 74 49 36 34 28 75 38 20 2a 61 42  ionPutI64(u8 *aB
2da0: 75 66 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  uf, sqlite3_int6
2db0: 34 20 69 29 7b 0a 20 20 61 42 75 66 5b 30 5d 20  4 i){.  aBuf[0] 
2dc0: 3d 20 28 69 3e 3e 35 36 29 20 26 20 30 78 46 46  = (i>>56) & 0xFF
2dd0: 3b 0a 20 20 61 42 75 66 5b 31 5d 20 3d 20 28 69  ;.  aBuf[1] = (i
2de0: 3e 3e 34 38 29 20 26 20 30 78 46 46 3b 0a 20 20  >>48) & 0xFF;.  
2df0: 61 42 75 66 5b 32 5d 20 3d 20 28 69 3e 3e 34 30  aBuf[2] = (i>>40
2e00: 29 20 26 20 30 78 46 46 3b 0a 20 20 61 42 75 66  ) & 0xFF;.  aBuf
2e10: 5b 33 5d 20 3d 20 28 69 3e 3e 33 32 29 20 26 20  [3] = (i>>32) & 
2e20: 30 78 46 46 3b 0a 20 20 61 42 75 66 5b 34 5d 20  0xFF;.  aBuf[4] 
2e30: 3d 20 28 69 3e 3e 32 34 29 20 26 20 30 78 46 46  = (i>>24) & 0xFF
2e40: 3b 0a 20 20 61 42 75 66 5b 35 5d 20 3d 20 28 69  ;.  aBuf[5] = (i
2e50: 3e 3e 31 36 29 20 26 20 30 78 46 46 3b 0a 20 20  >>16) & 0xFF;.  
2e60: 61 42 75 66 5b 36 5d 20 3d 20 28 69 3e 3e 20 38  aBuf[6] = (i>> 8
2e70: 29 20 26 20 30 78 46 46 3b 0a 20 20 61 42 75 66  ) & 0xFF;.  aBuf
2e80: 5b 37 5d 20 3d 20 28 69 3e 3e 20 30 29 20 26 20  [7] = (i>> 0) & 
2e90: 30 78 46 46 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  0xFF;.}../*.** T
2ea0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
2eb0: 75 73 65 64 20 74 6f 20 73 65 72 69 61 6c 69 7a  used to serializ
2ec0: 65 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  e the contents o
2ed0: 66 20 76 61 6c 75 65 20 70 56 61 6c 75 65 20 28  f value pValue (
2ee0: 73 65 65 0a 2a 2a 20 63 6f 6d 6d 65 6e 74 20 74  see.** comment t
2ef0: 69 74 6c 65 64 20 22 52 45 43 4f 52 44 20 46 4f  itled "RECORD FO
2f00: 52 4d 41 54 22 20 61 62 6f 76 65 29 2e 0a 2a 2a  RMAT" above)..**
2f10: 0a 2a 2a 20 49 66 20 69 74 20 69 73 20 6e 6f 6e  .** If it is non
2f20: 2d 4e 55 4c 4c 2c 20 74 68 65 20 73 65 72 69 61  -NULL, the seria
2f30: 6c 69 7a 65 64 20 66 6f 72 6d 20 6f 66 20 74 68  lized form of th
2f40: 65 20 76 61 6c 75 65 20 69 73 20 77 72 69 74 74  e value is writt
2f50: 65 6e 20 74 6f 20 0a 2a 2a 20 62 75 66 66 65 72  en to .** buffer
2f60: 20 61 42 75 66 2e 20 2a 70 6e 57 72 69 74 65 20   aBuf. *pnWrite 
2f70: 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e 75  is set to the nu
2f80: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 77 72  mber of bytes wr
2f90: 69 74 74 65 6e 20 62 65 66 6f 72 65 0a 2a 2a 20  itten before.** 
2fa0: 72 65 74 75 72 6e 69 6e 67 2e 20 4f 72 2c 20 69  returning. Or, i
2fb0: 66 20 61 42 75 66 20 69 73 20 4e 55 4c 4c 2c 20  f aBuf is NULL, 
2fc0: 74 68 65 20 6f 6e 6c 79 20 74 68 69 6e 67 20 74  the only thing t
2fd0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 64 6f 65  his function doe
2fe0: 73 20 69 73 0a 2a 2a 20 73 65 74 20 2a 70 6e 57  s is.** set *pnW
2ff0: 72 69 74 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6e  rite..**.** If n
3000: 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20  o error occurs, 
3010: 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74  SQLITE_OK is ret
3020: 75 72 6e 65 64 2e 20 4f 72 2c 20 69 66 20 61 6e  urned. Or, if an
3030: 20 4f 4f 4d 20 65 72 72 6f 72 20 6f 63 63 75 72   OOM error occur
3040: 73 0a 2a 2a 20 77 69 74 68 69 6e 20 61 20 63 61  s.** within a ca
3050: 6c 6c 20 74 6f 20 73 71 6c 69 74 65 33 5f 76 61  ll to sqlite3_va
3060: 6c 75 65 5f 74 65 78 74 28 29 20 28 6d 61 79 20  lue_text() (may 
3070: 66 61 69 6c 20 69 66 20 74 68 65 20 64 62 20 69  fail if the db i
3080: 73 20 75 74 66 2d 31 36 29 29 20 0a 2a 2a 20 53  s utf-16)) .** S
3090: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 69 73 20 72  QLITE_NOMEM is r
30a0: 65 74 75 72 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74  eturned..*/.stat
30b0: 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 53 65  ic int sessionSe
30c0: 72 69 61 6c 69 7a 65 56 61 6c 75 65 28 0a 20 20  rializeValue(.  
30d0: 75 38 20 2a 61 42 75 66 2c 20 20 20 20 20 20 20  u8 *aBuf,       
30e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
30f0: 2f 2a 20 49 66 20 6e 6f 6e 2d 4e 55 4c 4c 2c 20  /* If non-NULL, 
3100: 77 72 69 74 65 20 73 65 72 69 61 6c 69 7a 65 64  write serialized
3110: 20 76 61 6c 75 65 20 68 65 72 65 20 2a 2f 0a 20   value here */. 
3120: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
3130: 70 56 61 6c 75 65 2c 20 20 20 20 20 20 20 20 20  pValue,         
3140: 20 2f 2a 20 56 61 6c 75 65 20 74 6f 20 73 65 72   /* Value to ser
3150: 69 61 6c 69 7a 65 20 2a 2f 0a 20 20 69 6e 74 20  ialize */.  int 
3160: 2a 70 6e 57 72 69 74 65 20 20 20 20 20 20 20 20  *pnWrite        
3170: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
3180: 4e 2f 4f 55 54 3a 20 49 6e 63 72 65 6d 65 6e 74  N/OUT: Increment
3190: 20 62 79 20 62 79 74 65 73 20 77 72 69 74 74 65   by bytes writte
31a0: 6e 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e 42  n */.){.  int nB
31b0: 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  yte;            
31c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
31d0: 65 20 6f 66 20 73 65 72 69 61 6c 69 7a 65 64 20  e of serialized 
31e0: 76 61 6c 75 65 20 69 6e 20 62 79 74 65 73 20 2a  value in bytes *
31f0: 2f 0a 0a 20 20 69 66 28 20 70 56 61 6c 75 65 20  /..  if( pValue 
3200: 29 7b 0a 20 20 20 20 69 6e 74 20 65 54 79 70 65  ){.    int eType
3210: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
3220: 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 74 79       /* Value ty
3230: 70 65 20 28 53 51 4c 49 54 45 5f 4e 55 4c 4c 2c  pe (SQLITE_NULL,
3240: 20 54 45 58 54 20 65 74 63 2e 29 20 2a 2f 0a 20   TEXT etc.) */. 
3250: 20 0a 20 20 20 20 65 54 79 70 65 20 3d 20 73 71   .    eType = sq
3260: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65  lite3_value_type
3270: 28 70 56 61 6c 75 65 29 3b 0a 20 20 20 20 69 66  (pValue);.    if
3280: 28 20 61 42 75 66 20 29 20 61 42 75 66 5b 30 5d  ( aBuf ) aBuf[0]
3290: 20 3d 20 65 54 79 70 65 3b 0a 20 20 0a 20 20 20   = eType;.  .   
32a0: 20 73 77 69 74 63 68 28 20 65 54 79 70 65 20 29   switch( eType )
32b0: 7b 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c  {.      case SQL
32c0: 49 54 45 5f 4e 55 4c 4c 3a 20 0a 20 20 20 20 20  ITE_NULL: .     
32d0: 20 20 20 6e 42 79 74 65 20 3d 20 31 3b 0a 20 20     nByte = 1;.  
32e0: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 0a        break;.  .
32f0: 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54        case SQLIT
3300: 45 5f 49 4e 54 45 47 45 52 3a 20 0a 20 20 20 20  E_INTEGER: .    
3310: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 46 4c    case SQLITE_FL
3320: 4f 41 54 3a 0a 20 20 20 20 20 20 20 20 69 66 28  OAT:.        if(
3330: 20 61 42 75 66 20 29 7b 0a 20 20 20 20 20 20 20   aBuf ){.       
3340: 20 20 20 2f 2a 20 54 4f 44 4f 3a 20 53 51 4c 69     /* TODO: SQLi
3350: 74 65 20 64 6f 65 73 20 73 6f 6d 65 74 68 69 6e  te does somethin
3360: 67 20 73 70 65 63 69 61 6c 20 74 6f 20 64 65 61  g special to dea
3370: 6c 20 77 69 74 68 20 6d 69 78 65 64 2d 65 6e 64  l with mixed-end
3380: 69 61 6e 0a 20 20 20 20 20 20 20 20 20 20 2a 2a  ian.          **
3390: 20 66 6c 6f 61 74 69 6e 67 20 70 6f 69 6e 74 20   floating point 
33a0: 76 61 6c 75 65 73 20 28 65 2e 67 2e 20 41 52 4d  values (e.g. ARM
33b0: 37 29 2e 20 54 68 69 73 20 63 6f 64 65 20 70 72  7). This code pr
33c0: 6f 62 61 62 6c 79 20 73 68 6f 75 6c 64 0a 20 20  obably should.  
33d0: 20 20 20 20 20 20 20 20 2a 2a 20 74 6f 6f 2e 20          ** too. 
33e0: 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 75 36   */.          u6
33f0: 34 20 69 3b 0a 20 20 20 20 20 20 20 20 20 20 69  4 i;.          i
3400: 66 28 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45  f( eType==SQLITE
3410: 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20 20 20 20  _INTEGER ){.    
3420: 20 20 20 20 20 20 20 20 69 20 3d 20 28 75 36 34          i = (u64
3430: 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69  )sqlite3_value_i
3440: 6e 74 36 34 28 70 56 61 6c 75 65 29 3b 0a 20 20  nt64(pValue);.  
3450: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
3460: 20 20 20 20 20 20 20 20 20 20 20 64 6f 75 62 6c             doubl
3470: 65 20 72 3b 0a 20 20 20 20 20 20 20 20 20 20 20  e r;.           
3480: 20 61 73 73 65 72 74 28 20 73 69 7a 65 6f 66 28   assert( sizeof(
3490: 64 6f 75 62 6c 65 29 3d 3d 38 20 26 26 20 73 69  double)==8 && si
34a0: 7a 65 6f 66 28 75 36 34 29 3d 3d 38 20 29 3b 0a  zeof(u64)==8 );.
34b0: 20 20 20 20 20 20 20 20 20 20 20 20 72 20 3d 20              r = 
34c0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 64 6f  sqlite3_value_do
34d0: 75 62 6c 65 28 70 56 61 6c 75 65 29 3b 0a 20 20  uble(pValue);.  
34e0: 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79            memcpy
34f0: 28 26 69 2c 20 26 72 2c 20 38 29 3b 0a 20 20 20  (&i, &r, 8);.   
3500: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
3510: 20 20 20 73 65 73 73 69 6f 6e 50 75 74 49 36 34     sessionPutI64
3520: 28 26 61 42 75 66 5b 31 5d 2c 20 69 29 3b 0a 20  (&aBuf[1], i);. 
3530: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
3540: 20 6e 42 79 74 65 20 3d 20 39 3b 20 0a 20 20 20   nByte = 9; .   
3550: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 0a 20       break;.  . 
3560: 20 20 20 20 20 64 65 66 61 75 6c 74 3a 20 7b 0a       default: {.
3570: 20 20 20 20 20 20 20 20 75 38 20 2a 7a 3b 0a 20          u8 *z;. 
3580: 20 20 20 20 20 20 20 69 6e 74 20 6e 3b 0a 20 20         int n;.  
3590: 20 20 20 20 20 20 69 6e 74 20 6e 56 61 72 69 6e        int nVarin
35a0: 74 3b 0a 20 20 0a 20 20 20 20 20 20 20 20 61 73  t;.  .        as
35b0: 73 65 72 74 28 20 65 54 79 70 65 3d 3d 53 51 4c  sert( eType==SQL
35c0: 49 54 45 5f 54 45 58 54 20 7c 7c 20 65 54 79 70  ITE_TEXT || eTyp
35d0: 65 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 20 29  e==SQLITE_BLOB )
35e0: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 65 54  ;.        if( eT
35f0: 79 70 65 3d 3d 53 51 4c 49 54 45 5f 54 45 58 54  ype==SQLITE_TEXT
3600: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 7a 20   ){.          z 
3610: 3d 20 28 75 38 20 2a 29 73 71 6c 69 74 65 33 5f  = (u8 *)sqlite3_
3620: 76 61 6c 75 65 5f 74 65 78 74 28 70 56 61 6c 75  value_text(pValu
3630: 65 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73  e);.        }els
3640: 65 7b 0a 20 20 20 20 20 20 20 20 20 20 7a 20 3d  e{.          z =
3650: 20 28 75 38 20 2a 29 73 71 6c 69 74 65 33 5f 76   (u8 *)sqlite3_v
3660: 61 6c 75 65 5f 62 6c 6f 62 28 70 56 61 6c 75 65  alue_blob(pValue
3670: 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  );.        }.   
3680: 20 20 20 20 20 6e 20 3d 20 73 71 6c 69 74 65 33       n = sqlite3
3690: 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 70 56 61  _value_bytes(pVa
36a0: 6c 75 65 29 3b 0a 20 20 20 20 20 20 20 20 69 66  lue);.        if
36b0: 28 20 7a 3d 3d 30 20 26 26 20 28 65 54 79 70 65  ( z==0 && (eType
36c0: 21 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 20 7c 7c  !=SQLITE_BLOB ||
36d0: 20 6e 3e 30 29 20 29 20 72 65 74 75 72 6e 20 53   n>0) ) return S
36e0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
36f0: 20 20 20 20 20 6e 56 61 72 69 6e 74 20 3d 20 73       nVarint = s
3700: 65 73 73 69 6f 6e 56 61 72 69 6e 74 4c 65 6e 28  essionVarintLen(
3710: 6e 29 3b 0a 20 20 0a 20 20 20 20 20 20 20 20 69  n);.  .        i
3720: 66 28 20 61 42 75 66 20 29 7b 0a 20 20 20 20 20  f( aBuf ){.     
3730: 20 20 20 20 20 73 65 73 73 69 6f 6e 56 61 72 69       sessionVari
3740: 6e 74 50 75 74 28 26 61 42 75 66 5b 31 5d 2c 20  ntPut(&aBuf[1], 
3750: 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66  n);.          if
3760: 28 20 6e 20 29 20 6d 65 6d 63 70 79 28 26 61 42  ( n ) memcpy(&aB
3770: 75 66 5b 6e 56 61 72 69 6e 74 20 2b 20 31 5d 2c  uf[nVarint + 1],
3780: 20 7a 2c 20 6e 29 3b 0a 20 20 20 20 20 20 20 20   z, n);.        
3790: 7d 0a 20 20 0a 20 20 20 20 20 20 20 20 6e 42 79  }.  .        nBy
37a0: 74 65 20 3d 20 31 20 2b 20 6e 56 61 72 69 6e 74  te = 1 + nVarint
37b0: 20 2b 20 6e 3b 0a 20 20 20 20 20 20 20 20 62 72   + n;.        br
37c0: 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  eak;.      }.   
37d0: 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20   }.  }else{.    
37e0: 6e 42 79 74 65 20 3d 20 31 3b 0a 20 20 20 20 69  nByte = 1;.    i
37f0: 66 28 20 61 42 75 66 20 29 20 61 42 75 66 5b 30  f( aBuf ) aBuf[0
3800: 5d 20 3d 20 27 5c 30 27 3b 0a 20 20 7d 0a 0a 20  ] = '\0';.  }.. 
3810: 20 69 66 28 20 70 6e 57 72 69 74 65 20 29 20 2a   if( pnWrite ) *
3820: 70 6e 57 72 69 74 65 20 2b 3d 20 6e 42 79 74 65  pnWrite += nByte
3830: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
3840: 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  E_OK;.}.../*.** 
3850: 54 68 69 73 20 6d 61 63 72 6f 20 69 73 20 75 73  This macro is us
3860: 65 64 20 74 6f 20 63 61 6c 63 75 6c 61 74 65 20  ed to calculate 
3870: 68 61 73 68 20 6b 65 79 20 76 61 6c 75 65 73 20  hash key values 
3880: 66 6f 72 20 64 61 74 61 20 73 74 72 75 63 74 75  for data structu
3890: 72 65 73 2e 20 49 6e 0a 2a 2a 20 6f 72 64 65 72  res. In.** order
38a0: 20 74 6f 20 75 73 65 20 74 68 69 73 20 6d 61 63   to use this mac
38b0: 72 6f 2c 20 74 68 65 20 65 6e 74 69 72 65 20 64  ro, the entire d
38c0: 61 74 61 20 73 74 72 75 63 74 75 72 65 20 6d 75  ata structure mu
38d0: 73 74 20 62 65 20 72 65 70 72 65 73 65 6e 74 65  st be represente
38e0: 64 0a 2a 2a 20 61 73 20 61 20 73 65 72 69 65 73  d.** as a series
38f0: 20 6f 66 20 75 6e 73 69 67 6e 65 64 20 69 6e 74   of unsigned int
3900: 65 67 65 72 73 2e 20 49 6e 20 6f 72 64 65 72 20  egers. In order 
3910: 74 6f 20 63 61 6c 63 75 6c 61 74 65 20 61 20 68  to calculate a h
3920: 61 73 68 2d 6b 65 79 20 76 61 6c 75 65 0a 2a 2a  ash-key value.**
3930: 20 66 6f 72 20 61 20 64 61 74 61 20 73 74 72 75   for a data stru
3940: 63 74 75 72 65 20 72 65 70 72 65 73 65 6e 74 65  cture represente
3950: 64 20 61 73 20 74 68 72 65 65 20 73 75 63 68 20  d as three such 
3960: 69 6e 74 65 67 65 72 73 2c 20 74 68 65 20 6d 61  integers, the ma
3970: 63 72 6f 20 6d 61 79 0a 2a 2a 20 74 68 65 6e 20  cro may.** then 
3980: 62 65 20 75 73 65 64 20 61 73 20 66 6f 6c 6c 6f  be used as follo
3990: 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 69 6e 74  ws:.**.**    int
39a0: 20 68 61 73 68 5f 6b 65 79 5f 76 61 6c 75 65 3b   hash_key_value;
39b0: 0a 2a 2a 20 20 20 20 68 61 73 68 5f 6b 65 79 5f  .**    hash_key_
39c0: 76 61 6c 75 65 20 3d 20 48 41 53 48 5f 41 50 50  value = HASH_APP
39d0: 45 4e 44 28 30 2c 20 3c 76 61 6c 75 65 20 31 3e  END(0, <value 1>
39e0: 29 3b 0a 2a 2a 20 20 20 20 68 61 73 68 5f 6b 65  );.**    hash_ke
39f0: 79 5f 76 61 6c 75 65 20 3d 20 48 41 53 48 5f 41  y_value = HASH_A
3a00: 50 50 45 4e 44 28 68 61 73 68 5f 6b 65 79 5f 76  PPEND(hash_key_v
3a10: 61 6c 75 65 2c 20 3c 76 61 6c 75 65 20 32 3e 29  alue, <value 2>)
3a20: 3b 0a 2a 2a 20 20 20 20 68 61 73 68 5f 6b 65 79  ;.**    hash_key
3a30: 5f 76 61 6c 75 65 20 3d 20 48 41 53 48 5f 41 50  _value = HASH_AP
3a40: 50 45 4e 44 28 68 61 73 68 5f 6b 65 79 5f 76 61  PEND(hash_key_va
3a50: 6c 75 65 2c 20 3c 76 61 6c 75 65 20 33 3e 29 3b  lue, <value 3>);
3a60: 0a 2a 2a 0a 2a 2a 20 49 6e 20 70 72 61 63 74 69  .**.** In practi
3a70: 63 65 2c 20 74 68 65 20 64 61 74 61 20 73 74 72  ce, the data str
3a80: 75 63 74 75 72 65 73 20 74 68 69 73 20 6d 61 63  uctures this mac
3a90: 72 6f 20 69 73 20 75 73 65 64 20 66 6f 72 20 61  ro is used for a
3aa0: 72 65 20 74 68 65 20 70 72 69 6d 61 72 79 0a 2a  re the primary.*
3ab0: 2a 20 6b 65 79 20 76 61 6c 75 65 73 20 6f 66 20  * key values of 
3ac0: 6d 6f 64 69 66 69 65 64 20 72 6f 77 73 2e 0a 2a  modified rows..*
3ad0: 2f 0a 23 64 65 66 69 6e 65 20 48 41 53 48 5f 41  /.#define HASH_A
3ae0: 50 50 45 4e 44 28 68 61 73 68 2c 20 61 64 64 29  PPEND(hash, add)
3af0: 20 28 28 68 61 73 68 29 20 3c 3c 20 33 29 20 5e   ((hash) << 3) ^
3b00: 20 28 68 61 73 68 29 20 5e 20 28 75 6e 73 69 67   (hash) ^ (unsig
3b10: 6e 65 64 20 69 6e 74 29 28 61 64 64 29 0a 0a 2f  ned int)(add)../
3b20: 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 74 68 65 20  *.** Append the 
3b30: 68 61 73 68 20 6f 66 20 74 68 65 20 36 34 2d 62  hash of the 64-b
3b40: 69 74 20 69 6e 74 65 67 65 72 20 70 61 73 73 65  it integer passe
3b50: 64 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64 20  d as the second 
3b60: 61 72 67 75 6d 65 6e 74 20 74 6f 20 74 68 65 0a  argument to the.
3b70: 2a 2a 20 68 61 73 68 2d 6b 65 79 20 76 61 6c 75  ** hash-key valu
3b80: 65 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20  e passed as the 
3b90: 66 69 72 73 74 2e 20 52 65 74 75 72 6e 20 74 68  first. Return th
3ba0: 65 20 6e 65 77 20 68 61 73 68 2d 6b 65 79 20 76  e new hash-key v
3bb0: 61 6c 75 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  alue..*/.static 
3bc0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 73 65 73  unsigned int ses
3bd0: 73 69 6f 6e 48 61 73 68 41 70 70 65 6e 64 49 36  sionHashAppendI6
3be0: 34 28 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68  4(unsigned int h
3bf0: 2c 20 69 36 34 20 69 29 7b 0a 20 20 68 20 3d 20  , i64 i){.  h = 
3c00: 48 41 53 48 5f 41 50 50 45 4e 44 28 68 2c 20 69  HASH_APPEND(h, i
3c10: 20 26 20 30 78 46 46 46 46 46 46 46 46 29 3b 0a   & 0xFFFFFFFF);.
3c20: 20 20 72 65 74 75 72 6e 20 48 41 53 48 5f 41 50    return HASH_AP
3c30: 50 45 4e 44 28 68 2c 20 28 69 3e 3e 33 32 29 26  PEND(h, (i>>32)&
3c40: 30 78 46 46 46 46 46 46 46 46 29 3b 0a 7d 0a 0a  0xFFFFFFFF);.}..
3c50: 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 74 68 65  /*.** Append the
3c60: 20 68 61 73 68 20 6f 66 20 74 68 65 20 62 6c 6f   hash of the blo
3c70: 62 20 70 61 73 73 65 64 20 76 69 61 20 74 68 65  b passed via the
3c80: 20 73 65 63 6f 6e 64 20 61 6e 64 20 74 68 69 72   second and thir
3c90: 64 20 61 72 67 75 6d 65 6e 74 73 20 74 6f 20 0a  d arguments to .
3ca0: 2a 2a 20 74 68 65 20 68 61 73 68 2d 6b 65 79 20  ** the hash-key 
3cb0: 76 61 6c 75 65 20 70 61 73 73 65 64 20 61 73 20  value passed as 
3cc0: 74 68 65 20 66 69 72 73 74 2e 20 52 65 74 75 72  the first. Retur
3cd0: 6e 20 74 68 65 20 6e 65 77 20 68 61 73 68 2d 6b  n the new hash-k
3ce0: 65 79 20 76 61 6c 75 65 2e 0a 2a 2f 0a 73 74 61  ey value..*/.sta
3cf0: 74 69 63 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  tic unsigned int
3d00: 20 73 65 73 73 69 6f 6e 48 61 73 68 41 70 70 65   sessionHashAppe
3d10: 6e 64 42 6c 6f 62 28 75 6e 73 69 67 6e 65 64 20  ndBlob(unsigned 
3d20: 69 6e 74 20 68 2c 20 69 6e 74 20 6e 2c 20 63 6f  int h, int n, co
3d30: 6e 73 74 20 75 38 20 2a 7a 29 7b 0a 20 20 69 6e  nst u8 *z){.  in
3d40: 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  t i;.  for(i=0; 
3d50: 69 3c 6e 3b 20 69 2b 2b 29 20 68 20 3d 20 48 41  i<n; i++) h = HA
3d60: 53 48 5f 41 50 50 45 4e 44 28 68 2c 20 7a 5b 69  SH_APPEND(h, z[i
3d70: 5d 29 3b 0a 20 20 72 65 74 75 72 6e 20 68 3b 0a  ]);.  return h;.
3d80: 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20  }../*.** Append 
3d90: 74 68 65 20 68 61 73 68 20 6f 66 20 74 68 65 20  the hash of the 
3da0: 64 61 74 61 20 74 79 70 65 20 70 61 73 73 65 64  data type passed
3db0: 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61   as the second a
3dc0: 72 67 75 6d 65 6e 74 20 74 6f 20 74 68 65 0a 2a  rgument to the.*
3dd0: 2a 20 68 61 73 68 2d 6b 65 79 20 76 61 6c 75 65  * hash-key value
3de0: 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66   passed as the f
3df0: 69 72 73 74 2e 20 52 65 74 75 72 6e 20 74 68 65  irst. Return the
3e00: 20 6e 65 77 20 68 61 73 68 2d 6b 65 79 20 76 61   new hash-key va
3e10: 6c 75 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 75  lue..*/.static u
3e20: 6e 73 69 67 6e 65 64 20 69 6e 74 20 73 65 73 73  nsigned int sess
3e30: 69 6f 6e 48 61 73 68 41 70 70 65 6e 64 54 79 70  ionHashAppendTyp
3e40: 65 28 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68  e(unsigned int h
3e50: 2c 20 69 6e 74 20 65 54 79 70 65 29 7b 0a 20 20  , int eType){.  
3e60: 72 65 74 75 72 6e 20 48 41 53 48 5f 41 50 50 45  return HASH_APPE
3e70: 4e 44 28 68 2c 20 65 54 79 70 65 29 3b 0a 7d 0a  ND(h, eType);.}.
3e80: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
3e90: 74 69 6f 6e 20 6d 61 79 20 6f 6e 6c 79 20 62 65  tion may only be
3ea0: 20 63 61 6c 6c 65 64 20 66 72 6f 6d 20 77 69 74   called from wit
3eb0: 68 69 6e 20 61 20 70 72 65 2d 75 70 64 61 74 65  hin a pre-update
3ec0: 20 63 61 6c 6c 62 61 63 6b 2e 0a 2a 2a 20 49 74   callback..** It
3ed0: 20 63 61 6c 63 75 6c 61 74 65 73 20 61 20 68 61   calculates a ha
3ee0: 73 68 20 62 61 73 65 64 20 6f 6e 20 74 68 65 20  sh based on the 
3ef0: 70 72 69 6d 61 72 79 20 6b 65 79 20 76 61 6c 75  primary key valu
3f00: 65 73 20 6f 66 20 74 68 65 20 6f 6c 64 2e 2a 20  es of the old.* 
3f10: 6f 72 20 0a 2a 2a 20 6e 65 77 2e 2a 20 72 6f 77  or .** new.* row
3f20: 20 63 75 72 72 65 6e 74 6c 79 20 61 76 61 69 6c   currently avail
3f30: 61 62 6c 65 20 61 6e 64 2c 20 61 73 73 75 6d 69  able and, assumi
3f40: 6e 67 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75  ng no error occu
3f50: 72 73 2c 20 77 72 69 74 65 73 20 69 74 20 74 6f  rs, writes it to
3f60: 0a 2a 2a 20 2a 70 69 48 61 73 68 20 62 65 66 6f  .** *piHash befo
3f70: 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 20 49 66  re returning. If
3f80: 20 74 68 65 20 70 72 69 6d 61 72 79 20 6b 65 79   the primary key
3f90: 20 63 6f 6e 74 61 69 6e 73 20 6f 6e 65 20 6f 72   contains one or
3fa0: 20 6d 6f 72 65 20 4e 55 4c 4c 0a 2a 2a 20 76 61   more NULL.** va
3fb0: 6c 75 65 73 2c 20 2a 70 62 4e 75 6c 6c 50 4b 20  lues, *pbNullPK 
3fc0: 69 73 20 73 65 74 20 74 6f 20 74 72 75 65 20 62  is set to true b
3fd0: 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
3fe0: 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 65 72 72  .**.** If an err
3ff0: 6f 72 20 6f 63 63 75 72 73 2c 20 61 6e 20 53 51  or occurs, an SQ
4000: 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20  Lite error code 
4010: 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20  is returned and 
4020: 74 68 65 20 66 69 6e 61 6c 20 76 61 6c 75 65 73  the final values
4030: 0a 2a 2a 20 6f 66 20 2a 70 69 48 61 73 68 20 61  .** of *piHash a
4040: 73 6e 20 2a 70 62 4e 75 6c 6c 50 4b 20 61 72 65  sn *pbNullPK are
4050: 20 75 6e 64 65 66 69 6e 65 64 2e 20 4f 74 68 65   undefined. Othe
4060: 72 77 69 73 65 2c 20 53 51 4c 49 54 45 5f 4f 4b  rwise, SQLITE_OK
4070: 20 69 73 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20   is returned.** 
4080: 61 6e 64 20 74 68 65 20 6f 75 74 70 75 74 20 76  and the output v
4090: 61 72 69 61 62 6c 65 73 20 61 72 65 20 73 65 74  ariables are set
40a0: 20 61 73 20 64 65 73 63 72 69 62 65 64 20 61 62   as described ab
40b0: 6f 76 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ove..*/.static i
40c0: 6e 74 20 73 65 73 73 69 6f 6e 50 72 65 75 70 64  nt sessionPreupd
40d0: 61 74 65 48 61 73 68 28 0a 20 20 73 71 6c 69 74  ateHash(.  sqlit
40e0: 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73  e3_session *pSes
40f0: 73 69 6f 6e 2c 20 20 20 20 20 20 2f 2a 20 53 65  sion,      /* Se
4100: 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 74 68 61  ssion object tha
4110: 74 20 6f 77 6e 73 20 70 54 61 62 20 2a 2f 0a 20  t owns pTab */. 
4120: 20 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70   SessionTable *p
4130: 54 61 62 2c 20 20 20 20 20 20 20 20 20 20 20 20  Tab,            
4140: 20 2f 2a 20 53 65 73 73 69 6f 6e 20 74 61 62 6c   /* Session tabl
4150: 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e  e handle */.  in
4160: 74 20 62 4e 65 77 2c 20 20 20 20 20 20 20 20 20  t bNew,         
4170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4180: 20 54 72 75 65 20 74 6f 20 68 61 73 68 20 74 68   True to hash th
4190: 65 20 6e 65 77 2e 2a 20 50 4b 20 2a 2f 0a 20 20  e new.* PK */.  
41a0: 69 6e 74 20 2a 70 69 48 61 73 68 2c 20 20 20 20  int *piHash,    
41b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
41c0: 2f 2a 20 4f 55 54 3a 20 48 61 73 68 20 76 61 6c  /* OUT: Hash val
41d0: 75 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 62 4e  ue */.  int *pbN
41e0: 75 6c 6c 50 4b 20 20 20 20 20 20 20 20 20 20 20  ullPK           
41f0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
4200: 54 72 75 65 20 69 66 20 74 68 65 72 65 20 61 72  True if there ar
4210: 65 20 4e 55 4c 4c 20 76 61 6c 75 65 73 20 69 6e  e NULL values in
4220: 20 50 4b 20 2a 2f 0a 29 7b 0a 20 20 75 6e 73 69   PK */.){.  unsi
4230: 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 30 3b 20  gned int h = 0; 
4240: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48              /* H
4250: 61 73 68 20 76 61 6c 75 65 20 74 6f 20 72 65 74  ash value to ret
4260: 75 72 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20  urn */.  int i; 
4270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4280: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64           /* Used
4290: 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f   to iterate thro
42a0: 75 67 68 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 0a  ugh columns */..
42b0: 20 20 61 73 73 65 72 74 28 20 2a 70 62 4e 75 6c    assert( *pbNul
42c0: 6c 50 4b 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65  lPK==0 );.  asse
42d0: 72 74 28 20 70 54 61 62 2d 3e 6e 43 6f 6c 3d 3d  rt( pTab->nCol==
42e0: 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78  pSession->hook.x
42f0: 43 6f 75 6e 74 28 70 53 65 73 73 69 6f 6e 2d 3e  Count(pSession->
4300: 68 6f 6f 6b 2e 70 43 74 78 29 20 29 3b 0a 20 20  hook.pCtx) );.  
4310: 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61 62 2d  for(i=0; i<pTab-
4320: 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20  >nCol; i++){.   
4330: 20 69 66 28 20 70 54 61 62 2d 3e 61 62 50 4b 5b   if( pTab->abPK[
4340: 69 5d 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  i] ){.      int 
4350: 72 63 3b 0a 20 20 20 20 20 20 69 6e 74 20 65 54  rc;.      int eT
4360: 79 70 65 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  ype;.      sqlit
4370: 65 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c 3b 0a  e3_value *pVal;.
4380: 0a 20 20 20 20 20 20 69 66 28 20 62 4e 65 77 20  .      if( bNew 
4390: 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  ){.        rc = 
43a0: 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78  pSession->hook.x
43b0: 4e 65 77 28 70 53 65 73 73 69 6f 6e 2d 3e 68 6f  New(pSession->ho
43c0: 6f 6b 2e 70 43 74 78 2c 20 69 2c 20 26 70 56 61  ok.pCtx, i, &pVa
43d0: 6c 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  l);.      }else{
43e0: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 70 53  .        rc = pS
43f0: 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 4f 6c  ession->hook.xOl
4400: 64 28 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b  d(pSession->hook
4410: 2e 70 43 74 78 2c 20 69 2c 20 26 70 56 61 6c 29  .pCtx, i, &pVal)
4420: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
4430: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
4440: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a  K ) return rc;..
4450: 20 20 20 20 20 20 65 54 79 70 65 20 3d 20 73 71        eType = sq
4460: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65  lite3_value_type
4470: 28 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 68 20  (pVal);.      h 
4480: 3d 20 73 65 73 73 69 6f 6e 48 61 73 68 41 70 70  = sessionHashApp
4490: 65 6e 64 54 79 70 65 28 68 2c 20 65 54 79 70 65  endType(h, eType
44a0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 65 54 79  );.      if( eTy
44b0: 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47  pe==SQLITE_INTEG
44c0: 45 52 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c  ER || eType==SQL
44d0: 49 54 45 5f 46 4c 4f 41 54 20 29 7b 0a 20 20 20  ITE_FLOAT ){.   
44e0: 20 20 20 20 20 69 36 34 20 69 56 61 6c 3b 0a 20       i64 iVal;. 
44f0: 20 20 20 20 20 20 20 69 66 28 20 65 54 79 70 65         if( eType
4500: 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52  ==SQLITE_INTEGER
4510: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 56   ){.          iV
4520: 61 6c 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c  al = sqlite3_val
4530: 75 65 5f 69 6e 74 36 34 28 70 56 61 6c 29 3b 0a  ue_int64(pVal);.
4540: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
4550: 20 20 20 20 20 20 20 20 20 64 6f 75 62 6c 65 20           double 
4560: 72 56 61 6c 20 3d 20 73 71 6c 69 74 65 33 5f 76  rVal = sqlite3_v
4570: 61 6c 75 65 5f 64 6f 75 62 6c 65 28 70 56 61 6c  alue_double(pVal
4580: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 61 73 73  );.          ass
4590: 65 72 74 28 20 73 69 7a 65 6f 66 28 69 56 61 6c  ert( sizeof(iVal
45a0: 29 3d 3d 38 20 26 26 20 73 69 7a 65 6f 66 28 72  )==8 && sizeof(r
45b0: 56 61 6c 29 3d 3d 38 20 29 3b 0a 20 20 20 20 20  Val)==8 );.     
45c0: 20 20 20 20 20 6d 65 6d 63 70 79 28 26 69 56 61       memcpy(&iVa
45d0: 6c 2c 20 26 72 56 61 6c 2c 20 38 29 3b 0a 20 20  l, &rVal, 8);.  
45e0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
45f0: 68 20 3d 20 73 65 73 73 69 6f 6e 48 61 73 68 41  h = sessionHashA
4600: 70 70 65 6e 64 49 36 34 28 68 2c 20 69 56 61 6c  ppendI64(h, iVal
4610: 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69  );.      }else i
4620: 66 28 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45  f( eType==SQLITE
4630: 5f 54 45 58 54 20 7c 7c 20 65 54 79 70 65 3d 3d  _TEXT || eType==
4640: 53 51 4c 49 54 45 5f 42 4c 4f 42 20 29 7b 0a 20  SQLITE_BLOB ){. 
4650: 20 20 20 20 20 20 20 63 6f 6e 73 74 20 75 38 20         const u8 
4660: 2a 7a 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20  *z;.        int 
4670: 6e 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 65  n;.        if( e
4680: 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 54 45 58  Type==SQLITE_TEX
4690: 54 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 7a  T ){.          z
46a0: 20 3d 20 28 63 6f 6e 73 74 20 75 38 20 2a 29 73   = (const u8 *)s
46b0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78  qlite3_value_tex
46c0: 74 28 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 20  t(pVal);.       
46d0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
46e0: 20 20 7a 20 3d 20 28 63 6f 6e 73 74 20 75 38 20    z = (const u8 
46f0: 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  *)sqlite3_value_
4700: 62 6c 6f 62 28 70 56 61 6c 29 3b 0a 20 20 20 20  blob(pVal);.    
4710: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 6e 20      }.        n 
4720: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
4730: 62 79 74 65 73 28 70 56 61 6c 29 3b 0a 20 20 20  bytes(pVal);.   
4740: 20 20 20 20 20 69 66 28 20 21 7a 20 26 26 20 28       if( !z && (
4750: 65 54 79 70 65 21 3d 53 51 4c 49 54 45 5f 42 4c  eType!=SQLITE_BL
4760: 4f 42 20 7c 7c 20 6e 3e 30 29 20 29 20 72 65 74  OB || n>0) ) ret
4770: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
4780: 3b 0a 20 20 20 20 20 20 20 20 68 20 3d 20 73 65  ;.        h = se
4790: 73 73 69 6f 6e 48 61 73 68 41 70 70 65 6e 64 42  ssionHashAppendB
47a0: 6c 6f 62 28 68 2c 20 6e 2c 20 7a 29 3b 0a 20 20  lob(h, n, z);.  
47b0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
47c0: 20 20 20 61 73 73 65 72 74 28 20 65 54 79 70 65     assert( eType
47d0: 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29 3b  ==SQLITE_NULL );
47e0: 0a 20 20 20 20 20 20 20 20 2a 70 62 4e 75 6c 6c  .        *pbNull
47f0: 50 4b 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a  PK = 1;.      }.
4800: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 69      }.  }..  *pi
4810: 48 61 73 68 20 3d 20 28 68 20 25 20 70 54 61 62  Hash = (h % pTab
4820: 2d 3e 6e 43 68 61 6e 67 65 29 3b 0a 20 20 72 65  ->nChange);.  re
4830: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
4840: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 62 75 66  }../*.** The buf
4850: 66 65 72 20 74 68 61 74 20 74 68 65 20 61 72 67  fer that the arg
4860: 75 6d 65 6e 74 20 70 6f 69 6e 74 73 20 74 6f 20  ument points to 
4870: 63 6f 6e 74 61 69 6e 73 20 61 20 73 65 72 69 61  contains a seria
4880: 6c 69 7a 65 64 20 53 51 4c 20 76 61 6c 75 65 2e  lized SQL value.
4890: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 6e  .** Return the n
48a0: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f  umber of bytes o
48b0: 66 20 73 70 61 63 65 20 6f 63 63 75 70 69 65 64  f space occupied
48c0: 20 62 79 20 74 68 65 20 76 61 6c 75 65 20 28 69   by the value (i
48d0: 6e 63 6c 75 64 69 6e 67 0a 2a 2a 20 74 68 65 20  ncluding.** the 
48e0: 74 79 70 65 20 62 79 74 65 29 2e 0a 2a 2f 0a 73  type byte)..*/.s
48f0: 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f  tatic int sessio
4900: 6e 53 65 72 69 61 6c 4c 65 6e 28 75 38 20 2a 61  nSerialLen(u8 *a
4910: 29 7b 0a 20 20 69 6e 74 20 65 20 3d 20 2a 61 3b  ){.  int e = *a;
4920: 0a 20 20 69 6e 74 20 6e 3b 0a 20 20 69 66 28 20  .  int n;.  if( 
4930: 65 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 31 3b  e==0 ) return 1;
4940: 0a 20 20 69 66 28 20 65 3d 3d 53 51 4c 49 54 45  .  if( e==SQLITE
4950: 5f 4e 55 4c 4c 20 29 20 72 65 74 75 72 6e 20 31  _NULL ) return 1
4960: 3b 0a 20 20 69 66 28 20 65 3d 3d 53 51 4c 49 54  ;.  if( e==SQLIT
4970: 45 5f 49 4e 54 45 47 45 52 20 7c 7c 20 65 3d 3d  E_INTEGER || e==
4980: 53 51 4c 49 54 45 5f 46 4c 4f 41 54 20 29 20 72  SQLITE_FLOAT ) r
4990: 65 74 75 72 6e 20 39 3b 0a 20 20 72 65 74 75 72  eturn 9;.  retur
49a0: 6e 20 73 65 73 73 69 6f 6e 56 61 72 69 6e 74 47  n sessionVarintG
49b0: 65 74 28 26 61 5b 31 5d 2c 20 26 6e 29 20 2b 20  et(&a[1], &n) + 
49c0: 31 20 2b 20 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  1 + n;.}../*.** 
49d0: 42 61 73 65 64 20 6f 6e 20 74 68 65 20 70 72 69  Based on the pri
49e0: 6d 61 72 79 20 6b 65 79 20 76 61 6c 75 65 73 20  mary key values 
49f0: 73 74 6f 72 65 64 20 69 6e 20 63 68 61 6e 67 65  stored in change
4a00: 20 61 52 65 63 6f 72 64 2c 20 63 61 6c 63 75 6c   aRecord, calcul
4a10: 61 74 65 20 61 0a 2a 2a 20 68 61 73 68 20 6b 65  ate a.** hash ke
4a20: 79 2e 20 41 73 73 75 6d 65 20 74 68 65 20 68 61  y. Assume the ha
4a30: 73 20 74 61 62 6c 65 20 68 61 73 20 6e 42 75 63  s table has nBuc
4a40: 6b 65 74 20 62 75 63 6b 65 74 73 2e 20 54 68 65  ket buckets. The
4a50: 20 68 61 73 68 20 6b 65 79 73 0a 2a 2a 20 63 61   hash keys.** ca
4a60: 6c 63 75 6c 61 74 65 64 20 62 79 20 74 68 69 73  lculated by this
4a70: 20 66 75 6e 63 74 69 6f 6e 20 61 72 65 20 63 6f   function are co
4a80: 6d 70 61 74 69 62 6c 65 20 77 69 74 68 20 74 68  mpatible with th
4a90: 6f 73 65 20 63 61 6c 63 75 6c 61 74 65 64 20 62  ose calculated b
4aa0: 79 0a 2a 2a 20 73 65 73 73 69 6f 6e 50 72 65 75  y.** sessionPreu
4ab0: 70 64 61 74 65 48 61 73 68 28 29 2e 0a 2a 2a 0a  pdateHash()..**.
4ac0: 2a 2a 20 54 68 65 20 62 50 6b 4f 6e 6c 79 20 61  ** The bPkOnly a
4ad0: 72 67 75 6d 65 6e 74 20 69 73 20 6e 6f 6e 2d 7a  rgument is non-z
4ae0: 65 72 6f 20 69 66 20 74 68 65 20 72 65 63 6f 72  ero if the recor
4af0: 64 20 61 74 20 61 52 65 63 6f 72 64 5b 5d 20 69  d at aRecord[] i
4b00: 73 20 66 72 6f 6d 0a 2a 2a 20 61 20 70 61 74 63  s from.** a patc
4b10: 68 73 65 74 20 44 45 4c 45 54 45 2e 20 49 6e 20  hset DELETE. In 
4b20: 74 68 69 73 20 63 61 73 65 20 74 68 65 20 6e 6f  this case the no
4b30: 6e 2d 50 4b 20 66 69 65 6c 64 73 20 61 72 65 20  n-PK fields are 
4b40: 6f 6d 69 74 74 65 64 20 65 6e 74 69 72 65 6c 79  omitted entirely
4b50: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 75 6e 73 69  ..*/.static unsi
4b60: 67 6e 65 64 20 69 6e 74 20 73 65 73 73 69 6f 6e  gned int session
4b70: 43 68 61 6e 67 65 48 61 73 68 28 0a 20 20 53 65  ChangeHash(.  Se
4b80: 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62  ssionTable *pTab
4b90: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
4ba0: 20 54 61 62 6c 65 20 68 61 6e 64 6c 65 20 2a 2f   Table handle */
4bb0: 0a 20 20 69 6e 74 20 62 50 6b 4f 6e 6c 79 2c 20  .  int bPkOnly, 
4bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4bd0: 20 20 20 2f 2a 20 52 65 63 6f 72 64 20 63 6f 6e     /* Record con
4be0: 73 69 73 74 73 20 6f 66 20 50 4b 20 66 69 65 6c  sists of PK fiel
4bf0: 64 73 20 6f 6e 6c 79 20 2a 2f 0a 20 20 75 38 20  ds only */.  u8 
4c00: 2a 61 52 65 63 6f 72 64 2c 20 20 20 20 20 20 20  *aRecord,       
4c10: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4c20: 43 68 61 6e 67 65 20 72 65 63 6f 72 64 20 2a 2f  Change record */
4c30: 0a 20 20 69 6e 74 20 6e 42 75 63 6b 65 74 20 20  .  int nBucket  
4c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4c50: 20 20 20 2f 2a 20 41 73 73 75 6d 65 20 74 68 69     /* Assume thi
4c60: 73 20 6d 61 6e 79 20 62 75 63 6b 65 74 73 20 69  s many buckets i
4c70: 6e 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a  n hash table */.
4c80: 29 7b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  ){.  unsigned in
4c90: 74 20 68 20 3d 20 30 3b 20 20 20 20 20 20 20 20  t h = 0;        
4ca0: 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 74 6f       /* Value to
4cb0: 20 72 65 74 75 72 6e 20 2a 2f 0a 20 20 69 6e 74   return */.  int
4cc0: 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
4cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4ce0: 55 73 65 64 20 74 6f 20 69 74 65 72 61 74 65 20  Used to iterate 
4cf0: 74 68 72 6f 75 67 68 20 63 6f 6c 75 6d 6e 73 20  through columns 
4d00: 2a 2f 0a 20 20 75 38 20 2a 61 20 3d 20 61 52 65  */.  u8 *a = aRe
4d10: 63 6f 72 64 3b 20 20 20 20 20 20 20 20 20 20 20  cord;           
4d20: 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20       /* Used to 
4d30: 69 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20  iterate through 
4d40: 63 68 61 6e 67 65 20 72 65 63 6f 72 64 20 2a 2f  change record */
4d50: 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70  ..  for(i=0; i<p
4d60: 54 61 62 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b  Tab->nCol; i++){
4d70: 0a 20 20 20 20 69 6e 74 20 65 54 79 70 65 20 3d  .    int eType =
4d80: 20 2a 61 3b 0a 20 20 20 20 69 6e 74 20 69 73 50   *a;.    int isP
4d90: 4b 20 3d 20 70 54 61 62 2d 3e 61 62 50 4b 5b 69  K = pTab->abPK[i
4da0: 5d 3b 0a 20 20 20 20 69 66 28 20 62 50 6b 4f 6e  ];.    if( bPkOn
4db0: 6c 79 20 26 26 20 69 73 50 4b 3d 3d 30 20 29 20  ly && isPK==0 ) 
4dc0: 63 6f 6e 74 69 6e 75 65 3b 0a 0a 20 20 20 20 2f  continue;..    /
4dd0: 2a 20 49 74 20 69 73 20 6e 6f 74 20 70 6f 73 73  * It is not poss
4de0: 69 62 6c 65 20 66 6f 72 20 65 54 79 70 65 20 74  ible for eType t
4df0: 6f 20 62 65 20 53 51 4c 49 54 45 5f 4e 55 4c 4c  o be SQLITE_NULL
4e00: 20 68 65 72 65 2e 20 54 68 65 20 73 65 73 73 69   here. The sessi
4e10: 6f 6e 20 0a 20 20 20 20 2a 2a 20 6d 6f 64 75 6c  on .    ** modul
4e20: 65 20 64 6f 65 73 20 6e 6f 74 20 72 65 63 6f 72  e does not recor
4e30: 64 20 63 68 61 6e 67 65 73 20 66 6f 72 20 72 6f  d changes for ro
4e40: 77 73 20 77 69 74 68 20 4e 55 4c 4c 20 76 61 6c  ws with NULL val
4e50: 75 65 73 20 73 74 6f 72 65 64 20 69 6e 0a 20 20  ues stored in.  
4e60: 20 20 2a 2a 20 70 72 69 6d 61 72 79 20 6b 65 79    ** primary key
4e70: 20 63 6f 6c 75 6d 6e 73 2e 20 2a 2f 0a 20 20 20   columns. */.   
4e80: 20 61 73 73 65 72 74 28 20 65 54 79 70 65 3d 3d   assert( eType==
4e90: 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 7c  SQLITE_INTEGER |
4ea0: 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f  | eType==SQLITE_
4eb0: 46 4c 4f 41 54 20 0a 20 20 20 20 20 20 20 20 20  FLOAT .         
4ec0: 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45  || eType==SQLITE
4ed0: 5f 54 45 58 54 20 7c 7c 20 65 54 79 70 65 3d 3d  _TEXT || eType==
4ee0: 53 51 4c 49 54 45 5f 42 4c 4f 42 20 0a 20 20 20  SQLITE_BLOB .   
4ef0: 20 20 20 20 20 20 7c 7c 20 65 54 79 70 65 3d 3d        || eType==
4f00: 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 7c 7c 20 65  SQLITE_NULL || e
4f10: 54 79 70 65 3d 3d 30 20 0a 20 20 20 20 29 3b 0a  Type==0 .    );.
4f20: 20 20 20 20 61 73 73 65 72 74 28 20 21 69 73 50      assert( !isP
4f30: 4b 20 7c 7c 20 28 65 54 79 70 65 21 3d 30 20 26  K || (eType!=0 &
4f40: 26 20 65 54 79 70 65 21 3d 53 51 4c 49 54 45 5f  & eType!=SQLITE_
4f50: 4e 55 4c 4c 29 20 29 3b 0a 0a 20 20 20 20 69 66  NULL) );..    if
4f60: 28 20 69 73 50 4b 20 29 7b 0a 20 20 20 20 20 20  ( isPK ){.      
4f70: 61 2b 2b 3b 0a 20 20 20 20 20 20 68 20 3d 20 73  a++;.      h = s
4f80: 65 73 73 69 6f 6e 48 61 73 68 41 70 70 65 6e 64  essionHashAppend
4f90: 54 79 70 65 28 68 2c 20 65 54 79 70 65 29 3b 0a  Type(h, eType);.
4fa0: 20 20 20 20 20 20 69 66 28 20 65 54 79 70 65 3d        if( eType=
4fb0: 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20  =SQLITE_INTEGER 
4fc0: 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45  || eType==SQLITE
4fd0: 5f 46 4c 4f 41 54 20 29 7b 0a 20 20 20 20 20 20  _FLOAT ){.      
4fe0: 20 20 68 20 3d 20 73 65 73 73 69 6f 6e 48 61 73    h = sessionHas
4ff0: 68 41 70 70 65 6e 64 49 36 34 28 68 2c 20 73 65  hAppendI64(h, se
5000: 73 73 69 6f 6e 47 65 74 49 36 34 28 61 29 29 3b  ssionGetI64(a));
5010: 0a 20 20 20 20 20 20 20 20 61 20 2b 3d 20 38 3b  .        a += 8;
5020: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
5030: 20 20 20 20 20 20 69 6e 74 20 6e 3b 20 0a 20 20        int n; .  
5040: 20 20 20 20 20 20 61 20 2b 3d 20 73 65 73 73 69        a += sessi
5050: 6f 6e 56 61 72 69 6e 74 47 65 74 28 61 2c 20 26  onVarintGet(a, &
5060: 6e 29 3b 0a 20 20 20 20 20 20 20 20 68 20 3d 20  n);.        h = 
5070: 73 65 73 73 69 6f 6e 48 61 73 68 41 70 70 65 6e  sessionHashAppen
5080: 64 42 6c 6f 62 28 68 2c 20 6e 2c 20 61 29 3b 0a  dBlob(h, n, a);.
5090: 20 20 20 20 20 20 20 20 61 20 2b 3d 20 6e 3b 0a          a += n;.
50a0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73        }.    }els
50b0: 65 7b 0a 20 20 20 20 20 20 61 20 2b 3d 20 73 65  e{.      a += se
50c0: 73 73 69 6f 6e 53 65 72 69 61 6c 4c 65 6e 28 61  ssionSerialLen(a
50d0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72  );.    }.  }.  r
50e0: 65 74 75 72 6e 20 28 68 20 25 20 6e 42 75 63 6b  eturn (h % nBuck
50f0: 65 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 72  et);.}../*.** Ar
5100: 67 75 6d 65 6e 74 73 20 61 4c 65 66 74 20 61 6e  guments aLeft an
5110: 64 20 61 52 69 67 68 74 20 61 72 65 20 70 6f 69  d aRight are poi
5120: 6e 74 65 72 73 20 74 6f 20 63 68 61 6e 67 65 20  nters to change 
5130: 72 65 63 6f 72 64 73 20 66 6f 72 20 74 61 62 6c  records for tabl
5140: 65 20 70 54 61 62 2e 0a 2a 2a 20 54 68 69 73 20  e pTab..** This 
5150: 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73  function returns
5160: 20 74 72 75 65 20 69 66 20 74 68 65 20 74 77 6f   true if the two
5170: 20 72 65 63 6f 72 64 73 20 61 70 70 6c 79 20 74   records apply t
5180: 6f 20 74 68 65 20 73 61 6d 65 20 72 6f 77 20 28  o the same row (
5190: 69 2e 65 2e 0a 2a 2a 20 68 61 76 65 20 74 68 65  i.e..** have the
51a0: 20 73 61 6d 65 20 76 61 6c 75 65 73 20 73 74 6f   same values sto
51b0: 72 65 64 20 69 6e 20 74 68 65 20 70 72 69 6d 61  red in the prima
51c0: 72 79 20 6b 65 79 20 63 6f 6c 75 6d 6e 73 29 2c  ry key columns),
51d0: 20 6f 72 20 66 61 6c 73 65 20 0a 2a 2a 20 6f 74   or false .** ot
51e0: 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74  herwise..*/.stat
51f0: 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 43 68  ic int sessionCh
5200: 61 6e 67 65 45 71 75 61 6c 28 0a 20 20 53 65 73  angeEqual(.  Ses
5210: 73 69 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62 2c  sionTable *pTab,
5220: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5230: 54 61 62 6c 65 20 75 73 65 64 20 66 6f 72 20 50  Table used for P
5240: 4b 20 64 65 66 69 6e 69 74 69 6f 6e 20 2a 2f 0a  K definition */.
5250: 20 20 69 6e 74 20 62 4c 65 66 74 50 6b 4f 6e 6c    int bLeftPkOnl
5260: 79 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  y,              
5270: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 61 4c 65    /* True if aLe
5280: 66 74 5b 5d 20 63 6f 6e 74 61 69 6e 73 20 50 4b  ft[] contains PK
5290: 20 66 69 65 6c 64 73 20 6f 6e 6c 79 20 2a 2f 0a   fields only */.
52a0: 20 20 75 38 20 2a 61 4c 65 66 74 2c 20 20 20 20    u8 *aLeft,    
52b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
52c0: 20 20 2f 2a 20 43 68 61 6e 67 65 20 72 65 63 6f    /* Change reco
52d0: 72 64 20 2a 2f 0a 20 20 69 6e 74 20 62 52 69 67  rd */.  int bRig
52e0: 68 74 50 6b 4f 6e 6c 79 2c 20 20 20 20 20 20 20  htPkOnly,       
52f0: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
5300: 69 66 20 61 52 69 67 68 74 5b 5d 20 63 6f 6e 74  if aRight[] cont
5310: 61 69 6e 73 20 50 4b 20 66 69 65 6c 64 73 20 6f  ains PK fields o
5320: 6e 6c 79 20 2a 2f 0a 20 20 75 38 20 2a 61 52 69  nly */.  u8 *aRi
5330: 67 68 74 20 20 20 20 20 20 20 20 20 20 20 20 20  ght             
5340: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 61 6e           /* Chan
5350: 67 65 20 72 65 63 6f 72 64 20 2a 2f 0a 29 7b 0a  ge record */.){.
5360: 20 20 75 38 20 2a 61 31 20 3d 20 61 4c 65 66 74    u8 *a1 = aLeft
5370: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
5380: 20 20 2f 2a 20 43 75 72 73 6f 72 20 74 6f 20 69    /* Cursor to i
5390: 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 61  terate through a
53a0: 4c 65 66 74 20 2a 2f 0a 20 20 75 38 20 2a 61 32  Left */.  u8 *a2
53b0: 20 3d 20 61 52 69 67 68 74 3b 20 20 20 20 20 20   = aRight;      
53c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72            /* Cur
53d0: 73 6f 72 20 74 6f 20 69 74 65 72 61 74 65 20 74  sor to iterate t
53e0: 68 72 6f 75 67 68 20 61 52 69 67 68 74 20 2a 2f  hrough aRight */
53f0: 0a 20 20 69 6e 74 20 69 43 6f 6c 3b 20 20 20 20  .  int iCol;    
5400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5410: 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69 74     /* Used to it
5420: 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 74 61  erate through ta
5430: 62 6c 65 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 0a  ble columns */..
5440: 20 20 66 6f 72 28 69 43 6f 6c 3d 30 3b 20 69 43    for(iCol=0; iC
5450: 6f 6c 3c 70 54 61 62 2d 3e 6e 43 6f 6c 3b 20 69  ol<pTab->nCol; i
5460: 43 6f 6c 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20  Col++){.    if( 
5470: 70 54 61 62 2d 3e 61 62 50 4b 5b 69 43 6f 6c 5d  pTab->abPK[iCol]
5480: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 31   ){.      int n1
5490: 20 3d 20 73 65 73 73 69 6f 6e 53 65 72 69 61 6c   = sessionSerial
54a0: 4c 65 6e 28 61 31 29 3b 0a 20 20 20 20 20 20 69  Len(a1);.      i
54b0: 6e 74 20 6e 32 20 3d 20 73 65 73 73 69 6f 6e 53  nt n2 = sessionS
54c0: 65 72 69 61 6c 4c 65 6e 28 61 32 29 3b 0a 0a 20  erialLen(a2);.. 
54d0: 20 20 20 20 20 69 66 28 20 70 54 61 62 2d 3e 61       if( pTab->a
54e0: 62 50 4b 5b 69 43 6f 6c 5d 20 26 26 20 28 6e 31  bPK[iCol] && (n1
54f0: 21 3d 6e 32 20 7c 7c 20 6d 65 6d 63 6d 70 28 61  !=n2 || memcmp(a
5500: 31 2c 20 61 32 2c 20 6e 31 29 29 20 29 7b 0a 20  1, a2, n1)) ){. 
5510: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 30 3b         return 0;
5520: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61  .      }.      a
5530: 31 20 2b 3d 20 6e 31 3b 0a 20 20 20 20 20 20 61  1 += n1;.      a
5540: 32 20 2b 3d 20 6e 32 3b 0a 20 20 20 20 7d 65 6c  2 += n2;.    }el
5550: 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20 62 4c  se{.      if( bL
5560: 65 66 74 50 6b 4f 6e 6c 79 3d 3d 30 20 29 20 61  eftPkOnly==0 ) a
5570: 31 20 2b 3d 20 73 65 73 73 69 6f 6e 53 65 72 69  1 += sessionSeri
5580: 61 6c 4c 65 6e 28 61 31 29 3b 0a 20 20 20 20 20  alLen(a1);.     
5590: 20 69 66 28 20 62 52 69 67 68 74 50 6b 4f 6e 6c   if( bRightPkOnl
55a0: 79 3d 3d 30 20 29 20 61 32 20 2b 3d 20 73 65 73  y==0 ) a2 += ses
55b0: 73 69 6f 6e 53 65 72 69 61 6c 4c 65 6e 28 61 32  sionSerialLen(a2
55c0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
55d0: 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a  return 1;.}../*.
55e0: 2a 2a 20 41 72 67 75 6d 65 6e 74 73 20 61 4c 65  ** Arguments aLe
55f0: 66 74 20 61 6e 64 20 61 52 69 67 68 74 20 62 6f  ft and aRight bo
5600: 74 68 20 70 6f 69 6e 74 20 74 6f 20 62 75 66 66  th point to buff
5610: 65 72 73 20 63 6f 6e 74 61 69 6e 69 6e 67 20 63  ers containing c
5620: 68 61 6e 67 65 0a 2a 2a 20 72 65 63 6f 72 64 73  hange.** records
5630: 20 77 69 74 68 20 6e 43 6f 6c 20 63 6f 6c 75 6d   with nCol colum
5640: 6e 73 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f  ns. This functio
5650: 6e 20 22 6d 65 72 67 65 73 22 20 74 68 65 20 74  n "merges" the t
5660: 77 6f 20 72 65 63 6f 72 64 73 20 69 6e 74 6f 0a  wo records into.
5670: 2a 2a 20 61 20 73 69 6e 67 6c 65 20 72 65 63 6f  ** a single reco
5680: 72 64 73 20 77 68 69 63 68 20 69 73 20 77 72 69  rds which is wri
5690: 74 74 65 6e 20 74 6f 20 74 68 65 20 62 75 66 66  tten to the buff
56a0: 65 72 20 61 74 20 2a 70 61 4f 75 74 2e 20 2a 70  er at *paOut. *p
56b0: 61 4f 75 74 20 69 73 0a 2a 2a 20 74 68 65 6e 20  aOut is.** then 
56c0: 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  set to point to 
56d0: 6f 6e 65 20 62 79 74 65 20 61 66 74 65 72 20 74  one byte after t
56e0: 68 65 20 6c 61 73 74 20 62 79 74 65 20 77 72 69  he last byte wri
56f0: 74 74 65 6e 20 62 65 66 6f 72 65 20 0a 2a 2a 20  tten before .** 
5700: 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a  returning..**.**
5710: 20 54 68 65 20 6d 65 72 67 69 6e 67 20 6f 66 20   The merging of 
5720: 72 65 63 6f 72 64 73 20 69 73 20 64 6f 6e 65 20  records is done 
5730: 61 73 20 66 6f 6c 6c 6f 77 73 3a 20 46 6f 72 20  as follows: For 
5740: 65 61 63 68 20 63 6f 6c 75 6d 6e 2c 20 69 66 20  each column, if 
5750: 74 68 65 20 0a 2a 2a 20 61 52 69 67 68 74 20 72  the .** aRight r
5760: 65 63 6f 72 64 20 63 6f 6e 74 61 69 6e 73 20 61  ecord contains a
5770: 20 76 61 6c 75 65 20 66 6f 72 20 74 68 65 20 63   value for the c
5780: 6f 6c 75 6d 6e 2c 20 63 6f 70 79 20 74 68 65 20  olumn, copy the 
5790: 76 61 6c 75 65 20 66 72 6f 6d 0a 2a 2a 20 74 68  value from.** th
57a0: 65 69 72 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  eir. Otherwise, 
57b0: 69 66 20 61 4c 65 66 74 20 63 6f 6e 74 61 69 6e  if aLeft contain
57c0: 73 20 61 20 76 61 6c 75 65 2c 20 63 6f 70 79 20  s a value, copy 
57d0: 69 74 2e 20 49 66 20 6e 65 69 74 68 65 72 0a 2a  it. If neither.*
57e0: 2a 20 72 65 63 6f 72 64 20 63 6f 6e 74 61 69 6e  * record contain
57f0: 73 20 61 20 76 61 6c 75 65 20 66 6f 72 20 61 20  s a value for a 
5800: 67 69 76 65 6e 20 63 6f 6c 75 6d 6e 2c 20 74 68  given column, th
5810: 65 6e 20 6e 65 69 74 68 65 72 20 64 6f 65 73 20  en neither does 
5820: 74 68 65 0a 2a 2a 20 6f 75 74 70 75 74 20 72 65  the.** output re
5830: 63 6f 72 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  cord..*/.static 
5840: 76 6f 69 64 20 73 65 73 73 69 6f 6e 4d 65 72 67  void sessionMerg
5850: 65 52 65 63 6f 72 64 28 0a 20 20 75 38 20 2a 2a  eRecord(.  u8 **
5860: 70 61 4f 75 74 2c 20 0a 20 20 69 6e 74 20 6e 43  paOut, .  int nC
5870: 6f 6c 2c 0a 20 20 75 38 20 2a 61 4c 65 66 74 2c  ol,.  u8 *aLeft,
5880: 0a 20 20 75 38 20 2a 61 52 69 67 68 74 0a 29 7b  .  u8 *aRight.){
5890: 0a 20 20 75 38 20 2a 61 31 20 3d 20 61 4c 65 66  .  u8 *a1 = aLef
58a0: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
58b0: 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 75 73 65     /* Cursor use
58c0: 64 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72  d to iterate thr
58d0: 6f 75 67 68 20 61 4c 65 66 74 20 2a 2f 0a 20 20  ough aLeft */.  
58e0: 75 38 20 2a 61 32 20 3d 20 61 52 69 67 68 74 3b  u8 *a2 = aRight;
58f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5900: 2f 2a 20 43 75 72 73 6f 72 20 75 73 65 64 20 74  /* Cursor used t
5910: 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67  o iterate throug
5920: 68 20 61 52 69 67 68 74 20 2a 2f 0a 20 20 75 38  h aRight */.  u8
5930: 20 2a 61 4f 75 74 20 3d 20 2a 70 61 4f 75 74 3b   *aOut = *paOut;
5940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5950: 20 4f 75 74 70 75 74 20 63 75 72 73 6f 72 20 2a   Output cursor *
5960: 2f 0a 20 20 69 6e 74 20 69 43 6f 6c 3b 20 20 20  /.  int iCol;   
5970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5980: 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69      /* Used to i
5990: 74 65 72 61 74 65 20 66 72 6f 6d 20 30 20 74 6f  terate from 0 to
59a0: 20 6e 43 6f 6c 20 2a 2f 0a 0a 20 20 66 6f 72 28   nCol */..  for(
59b0: 69 43 6f 6c 3d 30 3b 20 69 43 6f 6c 3c 6e 43 6f  iCol=0; iCol<nCo
59c0: 6c 3b 20 69 43 6f 6c 2b 2b 29 7b 0a 20 20 20 20  l; iCol++){.    
59d0: 69 6e 74 20 6e 31 20 3d 20 73 65 73 73 69 6f 6e  int n1 = session
59e0: 53 65 72 69 61 6c 4c 65 6e 28 61 31 29 3b 0a 20  SerialLen(a1);. 
59f0: 20 20 20 69 6e 74 20 6e 32 20 3d 20 73 65 73 73     int n2 = sess
5a00: 69 6f 6e 53 65 72 69 61 6c 4c 65 6e 28 61 32 29  ionSerialLen(a2)
5a10: 3b 0a 20 20 20 20 69 66 28 20 2a 61 32 20 29 7b  ;.    if( *a2 ){
5a20: 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28 61 4f  .      memcpy(aO
5a30: 75 74 2c 20 61 32 2c 20 6e 32 29 3b 0a 20 20 20  ut, a2, n2);.   
5a40: 20 20 20 61 4f 75 74 20 2b 3d 20 6e 32 3b 0a 20     aOut += n2;. 
5a50: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
5a60: 6d 65 6d 63 70 79 28 61 4f 75 74 2c 20 61 31 2c  memcpy(aOut, a1,
5a70: 20 6e 31 29 3b 0a 20 20 20 20 20 20 61 4f 75 74   n1);.      aOut
5a80: 20 2b 3d 20 6e 31 3b 0a 20 20 20 20 7d 0a 20 20   += n1;.    }.  
5a90: 20 20 61 31 20 2b 3d 20 6e 31 3b 0a 20 20 20 20    a1 += n1;.    
5aa0: 61 32 20 2b 3d 20 6e 32 3b 0a 20 20 7d 0a 0a 20  a2 += n2;.  }.. 
5ab0: 20 2a 70 61 4f 75 74 20 3d 20 61 4f 75 74 3b 0a   *paOut = aOut;.
5ac0: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73  }../*.** This is
5ad0: 20 61 20 68 65 6c 70 65 72 20 66 75 6e 63 74 69   a helper functi
5ae0: 6f 6e 20 75 73 65 64 20 62 79 20 73 65 73 73 69  on used by sessi
5af0: 6f 6e 4d 65 72 67 65 55 70 64 61 74 65 28 29 2e  onMergeUpdate().
5b00: 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 74 68 69 73  .**.** When this
5b10: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
5b20: 6c 65 64 2c 20 62 6f 74 68 20 2a 70 61 4f 6e 65  led, both *paOne
5b30: 20 61 6e 64 20 2a 70 61 54 77 6f 20 70 6f 69 6e   and *paTwo poin
5b40: 74 20 74 6f 20 61 20 76 61 6c 75 65 20 0a 2a 2a  t to a value .**
5b50: 20 77 69 74 68 69 6e 20 61 20 63 68 61 6e 67 65   within a change
5b60: 20 72 65 63 6f 72 64 2e 20 42 65 66 6f 72 65 20   record. Before 
5b70: 69 74 20 72 65 74 75 72 6e 73 2c 20 62 6f 74 68  it returns, both
5b80: 20 68 61 76 65 20 62 65 65 6e 20 61 64 76 61 6e   have been advan
5b90: 63 65 64 20 73 6f 20 0a 2a 2a 20 61 73 20 74 6f  ced so .** as to
5ba0: 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 6e 65   point to the ne
5bb0: 78 74 20 76 61 6c 75 65 20 69 6e 20 74 68 65 20  xt value in the 
5bc0: 72 65 63 6f 72 64 2e 0a 2a 2a 0a 2a 2a 20 49 66  record..**.** If
5bd0: 2c 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63  , when this func
5be0: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2c 20  tion is called, 
5bf0: 2a 70 61 54 77 6f 20 70 6f 69 6e 74 73 20 74 6f  *paTwo points to
5c00: 20 61 20 76 61 6c 69 64 20 76 61 6c 75 65 20 28   a valid value (
5c10: 69 2e 65 2e 0a 2a 2a 20 2a 70 61 54 77 6f 5b 30  i.e..** *paTwo[0
5c20: 5d 20 69 73 20 6e 6f 74 20 30 78 30 30 20 2d 20  ] is not 0x00 - 
5c30: 74 68 65 20 22 6e 6f 20 76 61 6c 75 65 22 20 70  the "no value" p
5c40: 6c 61 63 65 68 6f 6c 64 65 72 29 2c 20 61 20 63  laceholder), a c
5c50: 6f 70 79 20 6f 66 20 74 68 65 20 2a 70 61 54 77  opy of the *paTw
5c60: 6f 0a 2a 2a 20 70 6f 69 6e 74 65 72 20 69 73 20  o.** pointer is 
5c70: 72 65 74 75 72 6e 65 64 20 61 6e 64 20 2a 70 6e  returned and *pn
5c80: 56 61 6c 20 69 73 20 73 65 74 20 74 6f 20 74 68  Val is set to th
5c90: 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  e number of byte
5ca0: 73 20 69 6e 20 74 68 65 20 0a 2a 2a 20 73 65 72  s in the .** ser
5cb0: 69 61 6c 69 7a 65 64 20 76 61 6c 75 65 2e 20 4f  ialized value. O
5cc0: 74 68 65 72 77 69 73 65 2c 20 61 20 63 6f 70 79  therwise, a copy
5cd0: 20 6f 66 20 2a 70 61 4f 6e 65 20 69 73 20 72 65   of *paOne is re
5ce0: 74 75 72 6e 65 64 20 61 6e 64 20 2a 70 6e 56 61  turned and *pnVa
5cf0: 6c 0a 2a 2a 20 73 65 74 20 74 6f 20 74 68 65 20  l.** set to the 
5d00: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
5d10: 69 6e 20 74 68 65 20 76 61 6c 75 65 20 61 74 20  in the value at 
5d20: 2a 70 61 4f 6e 65 2e 20 49 66 20 2a 70 61 4f 6e  *paOne. If *paOn
5d30: 65 20 70 6f 69 6e 74 73 0a 2a 2a 20 74 6f 20 74  e points.** to t
5d40: 68 65 20 22 6e 6f 20 76 61 6c 75 65 22 20 70 6c  he "no value" pl
5d50: 61 63 65 68 6f 6c 64 65 72 2c 20 2a 70 6e 56 61  aceholder, *pnVa
5d60: 6c 20 69 73 20 73 65 74 20 74 6f 20 31 2e 20 49  l is set to 1. I
5d70: 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 3a 0a 2a  n other words:.*
5d80: 2a 0a 2a 2a 20 20 20 69 66 28 20 2a 70 61 54 77  *.**   if( *paTw
5d90: 6f 20 69 73 20 76 61 6c 69 64 20 29 20 72 65 74  o is valid ) ret
5da0: 75 72 6e 20 2a 70 61 54 77 6f 3b 0a 2a 2a 20 20  urn *paTwo;.**  
5db0: 20 72 65 74 75 72 6e 20 2a 70 61 4f 6e 65 3b 0a   return *paOne;.
5dc0: 2a 2a 0a 2a 2f 0a 73 74 61 74 69 63 20 75 38 20  **.*/.static u8 
5dd0: 2a 73 65 73 73 69 6f 6e 4d 65 72 67 65 56 61 6c  *sessionMergeVal
5de0: 75 65 28 0a 20 20 75 38 20 2a 2a 70 61 4f 6e 65  ue(.  u8 **paOne
5df0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
5e00: 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a        /* IN/OUT:
5e10: 20 4c 65 66 74 2d 68 61 6e 64 20 62 75 66 66 65   Left-hand buffe
5e20: 72 20 70 6f 69 6e 74 65 72 20 2a 2f 0a 20 20 75  r pointer */.  u
5e30: 38 20 2a 2a 70 61 54 77 6f 2c 20 20 20 20 20 20  8 **paTwo,      
5e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5e50: 2a 20 49 4e 2f 4f 55 54 3a 20 52 69 67 68 74 2d  * IN/OUT: Right-
5e60: 68 61 6e 64 20 62 75 66 66 65 72 20 70 6f 69 6e  hand buffer poin
5e70: 74 65 72 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e  ter */.  int *pn
5e80: 56 61 6c 20 20 20 20 20 20 20 20 20 20 20 20 20  Val             
5e90: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
5ea0: 20 42 79 74 65 73 20 69 6e 20 72 65 74 75 72 6e   Bytes in return
5eb0: 65 64 20 76 61 6c 75 65 20 2a 2f 0a 29 7b 0a 20  ed value */.){. 
5ec0: 20 75 38 20 2a 61 31 20 3d 20 2a 70 61 4f 6e 65   u8 *a1 = *paOne
5ed0: 3b 0a 20 20 75 38 20 2a 61 32 20 3d 20 2a 70 61  ;.  u8 *a2 = *pa
5ee0: 54 77 6f 3b 0a 20 20 75 38 20 2a 70 52 65 74 20  Two;.  u8 *pRet 
5ef0: 3d 20 30 3b 0a 20 20 69 6e 74 20 6e 31 3b 0a 0a  = 0;.  int n1;..
5f00: 20 20 61 73 73 65 72 74 28 20 61 31 20 29 3b 0a    assert( a1 );.
5f10: 20 20 69 66 28 20 61 32 20 29 7b 0a 20 20 20 20    if( a2 ){.    
5f20: 69 6e 74 20 6e 32 20 3d 20 73 65 73 73 69 6f 6e  int n2 = session
5f30: 53 65 72 69 61 6c 4c 65 6e 28 61 32 29 3b 0a 20  SerialLen(a2);. 
5f40: 20 20 20 69 66 28 20 2a 61 32 20 29 7b 0a 20 20     if( *a2 ){.  
5f50: 20 20 20 20 2a 70 6e 56 61 6c 20 3d 20 6e 32 3b      *pnVal = n2;
5f60: 0a 20 20 20 20 20 20 70 52 65 74 20 3d 20 61 32  .      pRet = a2
5f70: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 2a 70 61 54  ;.    }.    *paT
5f80: 77 6f 20 3d 20 26 61 32 5b 6e 32 5d 3b 0a 20 20  wo = &a2[n2];.  
5f90: 7d 0a 0a 20 20 6e 31 20 3d 20 73 65 73 73 69 6f  }..  n1 = sessio
5fa0: 6e 53 65 72 69 61 6c 4c 65 6e 28 61 31 29 3b 0a  nSerialLen(a1);.
5fb0: 20 20 69 66 28 20 70 52 65 74 3d 3d 30 20 29 7b    if( pRet==0 ){
5fc0: 0a 20 20 20 20 2a 70 6e 56 61 6c 20 3d 20 6e 31  .    *pnVal = n1
5fd0: 3b 0a 20 20 20 20 70 52 65 74 20 3d 20 61 31 3b  ;.    pRet = a1;
5fe0: 0a 20 20 7d 0a 20 20 2a 70 61 4f 6e 65 20 3d 20  .  }.  *paOne = 
5ff0: 26 61 31 5b 6e 31 5d 3b 0a 0a 20 20 72 65 74 75  &a1[n1];..  retu
6000: 72 6e 20 70 52 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a  rn pRet;.}../*.*
6010: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
6020: 69 73 20 75 73 65 64 20 62 79 20 63 68 61 6e 67  is used by chang
6030: 65 73 65 74 5f 63 6f 6e 63 61 74 28 29 20 74 6f  eset_concat() to
6040: 20 6d 65 72 67 65 20 74 77 6f 20 55 50 44 41 54   merge two UPDAT
6050: 45 20 63 68 61 6e 67 65 73 0a 2a 2a 20 6f 6e 20  E changes.** on 
6060: 74 68 65 20 73 61 6d 65 20 72 6f 77 2e 0a 2a 2f  the same row..*/
6070: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73  .static int sess
6080: 69 6f 6e 4d 65 72 67 65 55 70 64 61 74 65 28 0a  ionMergeUpdate(.
6090: 20 20 75 38 20 2a 2a 70 61 4f 75 74 2c 20 20 20    u8 **paOut,   
60a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60b0: 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 50 6f 69    /* IN/OUT: Poi
60c0: 6e 74 65 72 20 74 6f 20 6f 75 74 70 75 74 20 62  nter to output b
60d0: 75 66 66 65 72 20 2a 2f 0a 20 20 53 65 73 73 69  uffer */.  Sessi
60e0: 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 20  onTable *pTab,  
60f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61             /* Ta
6100: 62 6c 65 20 63 68 61 6e 67 65 20 70 65 72 74 61  ble change perta
6110: 69 6e 73 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20  ins to */.  int 
6120: 62 50 61 74 63 68 73 65 74 2c 20 20 20 20 20 20  bPatchset,      
6130: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
6140: 72 75 65 20 69 66 20 72 65 63 6f 72 64 73 20 61  rue if records a
6150: 72 65 20 70 61 74 63 68 73 65 74 20 72 65 63 6f  re patchset reco
6160: 72 64 73 20 2a 2f 0a 20 20 75 38 20 2a 61 4f 6c  rds */.  u8 *aOl
6170: 64 52 65 63 6f 72 64 31 2c 20 20 20 20 20 20 20  dRecord1,       
6180: 20 20 20 20 20 20 20 20 20 2f 2a 20 6f 6c 64 2e           /* old.
6190: 2a 20 72 65 63 6f 72 64 20 66 6f 72 20 66 69 72  * record for fir
61a0: 73 74 20 63 68 61 6e 67 65 20 2a 2f 0a 20 20 75  st change */.  u
61b0: 38 20 2a 61 4f 6c 64 52 65 63 6f 72 64 32 2c 20  8 *aOldRecord2, 
61c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
61d0: 2a 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 20 66  * old.* record f
61e0: 6f 72 20 73 65 63 6f 6e 64 20 63 68 61 6e 67 65  or second change
61f0: 20 2a 2f 0a 20 20 75 38 20 2a 61 4e 65 77 52 65   */.  u8 *aNewRe
6200: 63 6f 72 64 31 2c 20 20 20 20 20 20 20 20 20 20  cord1,          
6210: 20 20 20 20 20 20 2f 2a 20 6e 65 77 2e 2a 20 72        /* new.* r
6220: 65 63 6f 72 64 20 66 6f 72 20 66 69 72 73 74 20  ecord for first 
6230: 63 68 61 6e 67 65 20 2a 2f 0a 20 20 75 38 20 2a  change */.  u8 *
6240: 61 4e 65 77 52 65 63 6f 72 64 32 20 20 20 20 20  aNewRecord2     
6250: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 6e              /* n
6260: 65 77 2e 2a 20 72 65 63 6f 72 64 20 66 6f 72 20  ew.* record for 
6270: 73 65 63 6f 6e 64 20 63 68 61 6e 67 65 20 2a 2f  second change */
6280: 0a 29 7b 0a 20 20 75 38 20 2a 61 4f 6c 64 31 20  .){.  u8 *aOld1 
6290: 3d 20 61 4f 6c 64 52 65 63 6f 72 64 31 3b 0a 20  = aOldRecord1;. 
62a0: 20 75 38 20 2a 61 4f 6c 64 32 20 3d 20 61 4f 6c   u8 *aOld2 = aOl
62b0: 64 52 65 63 6f 72 64 32 3b 0a 20 20 75 38 20 2a  dRecord2;.  u8 *
62c0: 61 4e 65 77 31 20 3d 20 61 4e 65 77 52 65 63 6f  aNew1 = aNewReco
62d0: 72 64 31 3b 0a 20 20 75 38 20 2a 61 4e 65 77 32  rd1;.  u8 *aNew2
62e0: 20 3d 20 61 4e 65 77 52 65 63 6f 72 64 32 3b 0a   = aNewRecord2;.
62f0: 0a 20 20 75 38 20 2a 61 4f 75 74 20 3d 20 2a 70  .  u8 *aOut = *p
6300: 61 4f 75 74 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a  aOut;.  int i;..
6310: 20 20 69 66 28 20 62 50 61 74 63 68 73 65 74 3d    if( bPatchset=
6320: 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 62 52  =0 ){.    int bR
6330: 65 71 75 69 72 65 64 20 3d 20 30 3b 0a 0a 20 20  equired = 0;..  
6340: 20 20 61 73 73 65 72 74 28 20 61 4f 6c 64 52 65    assert( aOldRe
6350: 63 6f 72 64 31 20 26 26 20 61 4e 65 77 52 65 63  cord1 && aNewRec
6360: 6f 72 64 31 20 29 3b 0a 0a 20 20 20 20 2f 2a 20  ord1 );..    /* 
6370: 57 72 69 74 65 20 74 68 65 20 6f 6c 64 2e 2a 20  Write the old.* 
6380: 76 65 63 74 6f 72 20 66 69 72 73 74 2e 20 2a 2f  vector first. */
6390: 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  .    for(i=0; i<
63a0: 70 54 61 62 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29  pTab->nCol; i++)
63b0: 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4f 6c 64  {.      int nOld
63c0: 3b 0a 20 20 20 20 20 20 75 38 20 2a 61 4f 6c 64  ;.      u8 *aOld
63d0: 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e 65 77  ;.      int nNew
63e0: 3b 0a 20 20 20 20 20 20 75 38 20 2a 61 4e 65 77  ;.      u8 *aNew
63f0: 3b 0a 0a 20 20 20 20 20 20 61 4f 6c 64 20 3d 20  ;..      aOld = 
6400: 73 65 73 73 69 6f 6e 4d 65 72 67 65 56 61 6c 75  sessionMergeValu
6410: 65 28 26 61 4f 6c 64 31 2c 20 26 61 4f 6c 64 32  e(&aOld1, &aOld2
6420: 2c 20 26 6e 4f 6c 64 29 3b 0a 20 20 20 20 20 20  , &nOld);.      
6430: 61 4e 65 77 20 3d 20 73 65 73 73 69 6f 6e 4d 65  aNew = sessionMe
6440: 72 67 65 56 61 6c 75 65 28 26 61 4e 65 77 31 2c  rgeValue(&aNew1,
6450: 20 26 61 4e 65 77 32 2c 20 26 6e 4e 65 77 29 3b   &aNew2, &nNew);
6460: 0a 20 20 20 20 20 20 69 66 28 20 70 54 61 62 2d  .      if( pTab-
6470: 3e 61 62 50 4b 5b 69 5d 20 7c 7c 20 6e 4f 6c 64  >abPK[i] || nOld
6480: 21 3d 6e 4e 65 77 20 7c 7c 20 6d 65 6d 63 6d 70  !=nNew || memcmp
6490: 28 61 4f 6c 64 2c 20 61 4e 65 77 2c 20 6e 4e 65  (aOld, aNew, nNe
64a0: 77 29 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  w) ){.        if
64b0: 28 20 70 54 61 62 2d 3e 61 62 50 4b 5b 69 5d 3d  ( pTab->abPK[i]=
64c0: 3d 30 20 29 20 62 52 65 71 75 69 72 65 64 20 3d  =0 ) bRequired =
64d0: 20 31 3b 0a 20 20 20 20 20 20 20 20 6d 65 6d 63   1;.        memc
64e0: 70 79 28 61 4f 75 74 2c 20 61 4f 6c 64 2c 20 6e  py(aOut, aOld, n
64f0: 4f 6c 64 29 3b 0a 20 20 20 20 20 20 20 20 61 4f  Old);.        aO
6500: 75 74 20 2b 3d 20 6e 4f 6c 64 3b 0a 20 20 20 20  ut += nOld;.    
6510: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
6520: 20 2a 28 61 4f 75 74 2b 2b 29 20 3d 20 27 5c 30   *(aOut++) = '\0
6530: 27 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  ';.      }.    }
6540: 0a 0a 20 20 20 20 69 66 28 20 21 62 52 65 71 75  ..    if( !bRequ
6550: 69 72 65 64 20 29 20 72 65 74 75 72 6e 20 30 3b  ired ) return 0;
6560: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 57 72 69 74 65  .  }..  /* Write
6570: 20 74 68 65 20 6e 65 77 2e 2a 20 76 65 63 74 6f   the new.* vecto
6580: 72 20 2a 2f 0a 20 20 61 4f 6c 64 31 20 3d 20 61  r */.  aOld1 = a
6590: 4f 6c 64 52 65 63 6f 72 64 31 3b 0a 20 20 61 4f  OldRecord1;.  aO
65a0: 6c 64 32 20 3d 20 61 4f 6c 64 52 65 63 6f 72 64  ld2 = aOldRecord
65b0: 32 3b 0a 20 20 61 4e 65 77 31 20 3d 20 61 4e 65  2;.  aNew1 = aNe
65c0: 77 52 65 63 6f 72 64 31 3b 0a 20 20 61 4e 65 77  wRecord1;.  aNew
65d0: 32 20 3d 20 61 4e 65 77 52 65 63 6f 72 64 32 3b  2 = aNewRecord2;
65e0: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54  .  for(i=0; i<pT
65f0: 61 62 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a  ab->nCol; i++){.
6600: 20 20 20 20 69 6e 74 20 6e 4f 6c 64 3b 0a 20 20      int nOld;.  
6610: 20 20 75 38 20 2a 61 4f 6c 64 3b 0a 20 20 20 20    u8 *aOld;.    
6620: 69 6e 74 20 6e 4e 65 77 3b 0a 20 20 20 20 75 38  int nNew;.    u8
6630: 20 2a 61 4e 65 77 3b 0a 0a 20 20 20 20 61 4f 6c   *aNew;..    aOl
6640: 64 20 3d 20 73 65 73 73 69 6f 6e 4d 65 72 67 65  d = sessionMerge
6650: 56 61 6c 75 65 28 26 61 4f 6c 64 31 2c 20 26 61  Value(&aOld1, &a
6660: 4f 6c 64 32 2c 20 26 6e 4f 6c 64 29 3b 0a 20 20  Old2, &nOld);.  
6670: 20 20 61 4e 65 77 20 3d 20 73 65 73 73 69 6f 6e    aNew = session
6680: 4d 65 72 67 65 56 61 6c 75 65 28 26 61 4e 65 77  MergeValue(&aNew
6690: 31 2c 20 26 61 4e 65 77 32 2c 20 26 6e 4e 65 77  1, &aNew2, &nNew
66a0: 29 3b 0a 20 20 20 20 69 66 28 20 62 50 61 74 63  );.    if( bPatc
66b0: 68 73 65 74 3d 3d 30 20 0a 20 20 20 20 20 26 26  hset==0 .     &&
66c0: 20 28 70 54 61 62 2d 3e 61 62 50 4b 5b 69 5d 20   (pTab->abPK[i] 
66d0: 7c 7c 20 28 6e 4f 6c 64 3d 3d 6e 4e 65 77 20 26  || (nOld==nNew &
66e0: 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 61 4f 6c 64  & 0==memcmp(aOld
66f0: 2c 20 61 4e 65 77 2c 20 6e 4e 65 77 29 29 29 20  , aNew, nNew))) 
6700: 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 2a 28  .    ){.      *(
6710: 61 4f 75 74 2b 2b 29 20 3d 20 27 5c 30 27 3b 0a  aOut++) = '\0';.
6720: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
6730: 20 6d 65 6d 63 70 79 28 61 4f 75 74 2c 20 61 4e   memcpy(aOut, aN
6740: 65 77 2c 20 6e 4e 65 77 29 3b 0a 20 20 20 20 20  ew, nNew);.     
6750: 20 61 4f 75 74 20 2b 3d 20 6e 4e 65 77 3b 0a 20   aOut += nNew;. 
6760: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 61 4f     }.  }..  *paO
6770: 75 74 20 3d 20 61 4f 75 74 3b 0a 20 20 72 65 74  ut = aOut;.  ret
6780: 75 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn 1;.}../*.** 
6790: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
67a0: 20 6f 6e 6c 79 20 63 61 6c 6c 65 64 20 66 72 6f   only called fro
67b0: 6d 20 77 69 74 68 69 6e 20 61 20 70 72 65 2d 75  m within a pre-u
67c0: 70 64 61 74 65 2d 68 6f 6f 6b 20 63 61 6c 6c 62  pdate-hook callb
67d0: 61 63 6b 2e 0a 2a 2a 20 49 74 20 64 65 74 65 72  ack..** It deter
67e0: 6d 69 6e 65 73 20 69 66 20 74 68 65 20 63 75 72  mines if the cur
67f0: 72 65 6e 74 20 70 72 65 2d 75 70 64 61 74 65 2d  rent pre-update-
6800: 68 6f 6f 6b 20 63 68 61 6e 67 65 20 61 66 66 65  hook change affe
6810: 63 74 73 20 74 68 65 20 73 61 6d 65 20 72 6f 77  cts the same row
6820: 0a 2a 2a 20 61 73 20 74 68 65 20 63 68 61 6e 67  .** as the chang
6830: 65 20 73 74 6f 72 65 64 20 69 6e 20 61 72 67 75  e stored in argu
6840: 6d 65 6e 74 20 70 43 68 61 6e 67 65 2e 20 49 66  ment pChange. If
6850: 20 73 6f 2c 20 69 74 20 72 65 74 75 72 6e 73 20   so, it returns 
6860: 74 72 75 65 2e 20 4f 74 68 65 72 77 69 73 65 0a  true. Otherwise.
6870: 2a 2a 20 69 66 20 74 68 65 20 70 72 65 2d 75 70  ** if the pre-up
6880: 64 61 74 65 2d 68 6f 6f 6b 20 64 6f 65 73 20 6e  date-hook does n
6890: 6f 74 20 61 66 66 65 63 74 20 74 68 65 20 73 61  ot affect the sa
68a0: 6d 65 20 72 6f 77 20 61 73 20 70 43 68 61 6e 67  me row as pChang
68b0: 65 2c 20 69 74 20 72 65 74 75 72 6e 73 0a 2a 2a  e, it returns.**
68c0: 20 66 61 6c 73 65 2e 0a 2a 2f 0a 73 74 61 74 69   false..*/.stati
68d0: 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 50 72 65  c int sessionPre
68e0: 75 70 64 61 74 65 45 71 75 61 6c 28 0a 20 20 73  updateEqual(.  s
68f0: 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a  qlite3_session *
6900: 70 53 65 73 73 69 6f 6e 2c 20 20 20 20 20 20 2f  pSession,      /
6910: 2a 20 53 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74  * Session object
6920: 20 74 68 61 74 20 6f 77 6e 73 20 53 65 73 73 69   that owns Sessi
6930: 6f 6e 54 61 62 6c 65 20 2a 2f 0a 20 20 53 65 73  onTable */.  Ses
6940: 73 69 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62 2c  sionTable *pTab,
6950: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6960: 54 61 62 6c 65 20 61 73 73 6f 63 69 61 74 65 64  Table associated
6970: 20 77 69 74 68 20 63 68 61 6e 67 65 20 2a 2f 0a   with change */.
6980: 20 20 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20    SessionChange 
6990: 2a 70 43 68 61 6e 67 65 2c 20 20 20 20 20 20 20  *pChange,       
69a0: 20 20 2f 2a 20 43 68 61 6e 67 65 20 74 6f 20 63    /* Change to c
69b0: 6f 6d 70 61 72 65 20 74 6f 20 2a 2f 0a 20 20 69  ompare to */.  i
69c0: 6e 74 20 6f 70 20 20 20 20 20 20 20 20 20 20 20  nt op           
69d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
69e0: 2a 20 43 75 72 72 65 6e 74 20 70 72 65 2d 75 70  * Current pre-up
69f0: 64 61 74 65 20 6f 70 65 72 61 74 69 6f 6e 20 2a  date operation *
6a00: 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 43 6f 6c 3b  /.){.  int iCol;
6a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a20: 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74         /* Used t
6a30: 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67  o iterate throug
6a40: 68 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 75  h columns */.  u
6a50: 38 20 2a 61 20 3d 20 70 43 68 61 6e 67 65 2d 3e  8 *a = pChange->
6a60: 61 52 65 63 6f 72 64 3b 20 20 20 20 20 20 20 2f  aRecord;       /
6a70: 2a 20 43 75 72 73 6f 72 20 75 73 65 64 20 74 6f  * Cursor used to
6a80: 20 73 63 61 6e 20 63 68 61 6e 67 65 20 72 65 63   scan change rec
6a90: 6f 72 64 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74  ord */..  assert
6aa0: 28 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 53  ( op==SQLITE_INS
6ab0: 45 52 54 20 7c 7c 20 6f 70 3d 3d 53 51 4c 49 54  ERT || op==SQLIT
6ac0: 45 5f 55 50 44 41 54 45 20 7c 7c 20 6f 70 3d 3d  E_UPDATE || op==
6ad0: 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 20 29 3b  SQLITE_DELETE );
6ae0: 0a 20 20 66 6f 72 28 69 43 6f 6c 3d 30 3b 20 69  .  for(iCol=0; i
6af0: 43 6f 6c 3c 70 54 61 62 2d 3e 6e 43 6f 6c 3b 20  Col<pTab->nCol; 
6b00: 69 43 6f 6c 2b 2b 29 7b 0a 20 20 20 20 69 66 28  iCol++){.    if(
6b10: 20 21 70 54 61 62 2d 3e 61 62 50 4b 5b 69 43 6f   !pTab->abPK[iCo
6b20: 6c 5d 20 29 7b 0a 20 20 20 20 20 20 61 20 2b 3d  l] ){.      a +=
6b30: 20 73 65 73 73 69 6f 6e 53 65 72 69 61 6c 4c 65   sessionSerialLe
6b40: 6e 28 61 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  n(a);.    }else{
6b50: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76  .      sqlite3_v
6b60: 61 6c 75 65 20 2a 70 56 61 6c 3b 20 20 20 20 20  alue *pVal;     
6b70: 20 20 20 2f 2a 20 56 61 6c 75 65 20 72 65 74 75     /* Value retu
6b80: 72 6e 65 64 20 62 79 20 70 72 65 75 70 64 61 74  rned by preupdat
6b90: 65 5f 6e 65 77 2f 6f 6c 64 20 2a 2f 0a 20 20 20  e_new/old */.   
6ba0: 20 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20     int rc;      
6bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6bc0: 2a 20 45 72 72 6f 72 20 63 6f 64 65 20 66 72 6f  * Error code fro
6bd0: 6d 20 70 72 65 75 70 64 61 74 65 5f 6e 65 77 2f  m preupdate_new/
6be0: 6f 6c 64 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74  old */.      int
6bf0: 20 65 54 79 70 65 20 3d 20 2a 61 2b 2b 3b 20 20   eType = *a++;  
6c00: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 79 70 65           /* Type
6c10: 20 6f 66 20 76 61 6c 75 65 20 66 72 6f 6d 20 63   of value from c
6c20: 68 61 6e 67 65 20 72 65 63 6f 72 64 20 2a 2f 0a  hange record */.
6c30: 0a 20 20 20 20 20 20 2f 2a 20 54 68 65 20 66 6f  .      /* The fo
6c40: 6c 6c 6f 77 69 6e 67 20 63 61 6c 6c 73 20 74 6f  llowing calls to
6c50: 20 70 72 65 75 70 64 61 74 65 5f 6e 65 77 28 29   preupdate_new()
6c60: 20 61 6e 64 20 70 72 65 75 70 64 61 74 65 5f 6f   and preupdate_o
6c70: 6c 64 28 29 20 63 61 6e 20 6e 6f 74 0a 20 20 20  ld() can not.   
6c80: 20 20 20 2a 2a 20 66 61 69 6c 2e 20 54 68 69 73     ** fail. This
6c90: 20 69 73 20 62 65 63 61 75 73 65 20 74 68 65 79   is because they
6ca0: 20 63 61 63 68 65 20 74 68 65 69 72 20 72 65 74   cache their ret
6cb0: 75 72 6e 20 76 61 6c 75 65 73 2c 20 61 6e 64 20  urn values, and 
6cc0: 62 79 20 74 68 65 0a 20 20 20 20 20 20 2a 2a 20  by the.      ** 
6cd0: 74 69 6d 65 20 63 6f 6e 74 72 6f 6c 20 66 6c 6f  time control flo
6ce0: 77 73 20 74 6f 20 68 65 72 65 20 74 68 65 79 20  ws to here they 
6cf0: 68 61 76 65 20 61 6c 72 65 61 64 79 20 62 65 65  have already bee
6d00: 6e 20 63 61 6c 6c 65 64 20 6f 6e 63 65 20 66 72  n called once fr
6d10: 6f 6d 0a 20 20 20 20 20 20 2a 2a 20 77 69 74 68  om.      ** with
6d20: 69 6e 20 73 65 73 73 69 6f 6e 50 72 65 75 70 64  in sessionPreupd
6d30: 61 74 65 48 61 73 68 28 29 2e 20 54 68 65 20 66  ateHash(). The f
6d40: 69 72 73 74 20 74 77 6f 20 61 73 73 65 72 74 73  irst two asserts
6d50: 20 62 65 6c 6f 77 20 76 65 72 69 66 79 0a 20 20   below verify.  
6d60: 20 20 20 20 2a 2a 20 74 68 69 73 20 28 74 68 61      ** this (tha
6d70: 74 20 74 68 65 20 6d 65 74 68 6f 64 20 68 61 73  t the method has
6d80: 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 63 61   already been ca
6d90: 6c 6c 65 64 29 2e 20 2a 2f 0a 20 20 20 20 20 20  lled). */.      
6da0: 69 66 28 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 49  if( op==SQLITE_I
6db0: 4e 53 45 52 54 20 29 7b 0a 20 20 20 20 20 20 20  NSERT ){.       
6dc0: 20 2f 2a 20 61 73 73 65 72 74 28 20 64 62 2d 3e   /* assert( db->
6dd0: 70 50 72 65 55 70 64 61 74 65 2d 3e 70 4e 65 77  pPreUpdate->pNew
6de0: 55 6e 70 61 63 6b 65 64 20 7c 7c 20 64 62 2d 3e  Unpacked || db->
6df0: 70 50 72 65 55 70 64 61 74 65 2d 3e 61 4e 65 77  pPreUpdate->aNew
6e00: 20 29 3b 20 2a 2f 0a 20 20 20 20 20 20 20 20 72   ); */.        r
6e10: 63 20 3d 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f  c = pSession->ho
6e20: 6f 6b 2e 78 4e 65 77 28 70 53 65 73 73 69 6f 6e  ok.xNew(pSession
6e30: 2d 3e 68 6f 6f 6b 2e 70 43 74 78 2c 20 69 43 6f  ->hook.pCtx, iCo
6e40: 6c 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20 20 20  l, &pVal);.     
6e50: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
6e60: 2f 2a 20 61 73 73 65 72 74 28 20 64 62 2d 3e 70  /* assert( db->p
6e70: 50 72 65 55 70 64 61 74 65 2d 3e 70 55 6e 70 61  PreUpdate->pUnpa
6e80: 63 6b 65 64 20 29 3b 20 2a 2f 0a 20 20 20 20 20  cked ); */.     
6e90: 20 20 20 72 63 20 3d 20 70 53 65 73 73 69 6f 6e     rc = pSession
6ea0: 2d 3e 68 6f 6f 6b 2e 78 4f 6c 64 28 70 53 65 73  ->hook.xOld(pSes
6eb0: 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 70 43 74 78 2c  sion->hook.pCtx,
6ec0: 20 69 43 6f 6c 2c 20 26 70 56 61 6c 29 3b 0a 20   iCol, &pVal);. 
6ed0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61 73 73       }.      ass
6ee0: 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ert( rc==SQLITE_
6ef0: 4f 4b 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20  OK );.      if( 
6f00: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79  sqlite3_value_ty
6f10: 70 65 28 70 56 61 6c 29 21 3d 65 54 79 70 65 20  pe(pVal)!=eType 
6f20: 29 20 72 65 74 75 72 6e 20 30 3b 0a 0a 20 20 20  ) return 0;..   
6f30: 20 20 20 2f 2a 20 41 20 53 65 73 73 69 6f 6e 43     /* A SessionC
6f40: 68 61 6e 67 65 20 6f 62 6a 65 63 74 20 6e 65 76  hange object nev
6f50: 65 72 20 68 61 73 20 61 20 4e 55 4c 4c 20 76 61  er has a NULL va
6f60: 6c 75 65 20 69 6e 20 61 20 50 4b 20 63 6f 6c 75  lue in a PK colu
6f70: 6d 6e 20 2a 2f 0a 20 20 20 20 20 20 61 73 73 65  mn */.      asse
6f80: 72 74 28 20 65 54 79 70 65 3d 3d 53 51 4c 49 54  rt( eType==SQLIT
6f90: 45 5f 49 4e 54 45 47 45 52 20 7c 7c 20 65 54 79  E_INTEGER || eTy
6fa0: 70 65 3d 3d 53 51 4c 49 54 45 5f 46 4c 4f 41 54  pe==SQLITE_FLOAT
6fb0: 0a 20 20 20 20 20 20 20 20 20 20 20 7c 7c 20 65  .           || e
6fc0: 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f  Type==SQLITE_BLO
6fd0: 42 20 20 20 20 7c 7c 20 65 54 79 70 65 3d 3d 53  B    || eType==S
6fe0: 51 4c 49 54 45 5f 54 45 58 54 0a 20 20 20 20 20  QLITE_TEXT.     
6ff0: 20 29 3b 0a 0a 20 20 20 20 20 20 69 66 28 20 65   );..      if( e
7000: 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54  Type==SQLITE_INT
7010: 45 47 45 52 20 7c 7c 20 65 54 79 70 65 3d 3d 53  EGER || eType==S
7020: 51 4c 49 54 45 5f 46 4c 4f 41 54 20 29 7b 0a 20  QLITE_FLOAT ){. 
7030: 20 20 20 20 20 20 20 69 36 34 20 69 56 61 6c 20         i64 iVal 
7040: 3d 20 73 65 73 73 69 6f 6e 47 65 74 49 36 34 28  = sessionGetI64(
7050: 61 29 3b 0a 20 20 20 20 20 20 20 20 61 20 2b 3d  a);.        a +=
7060: 20 38 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20   8;.        if( 
7070: 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e  eType==SQLITE_IN
7080: 54 45 47 45 52 20 29 7b 0a 20 20 20 20 20 20 20  TEGER ){.       
7090: 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 76     if( sqlite3_v
70a0: 61 6c 75 65 5f 69 6e 74 36 34 28 70 56 61 6c 29  alue_int64(pVal)
70b0: 21 3d 69 56 61 6c 20 29 20 72 65 74 75 72 6e 20  !=iVal ) return 
70c0: 30 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65  0;.        }else
70d0: 7b 0a 20 20 20 20 20 20 20 20 20 20 64 6f 75 62  {.          doub
70e0: 6c 65 20 72 56 61 6c 3b 0a 20 20 20 20 20 20 20  le rVal;.       
70f0: 20 20 20 61 73 73 65 72 74 28 20 73 69 7a 65 6f     assert( sizeo
7100: 66 28 69 56 61 6c 29 3d 3d 38 20 26 26 20 73 69  f(iVal)==8 && si
7110: 7a 65 6f 66 28 72 56 61 6c 29 3d 3d 38 20 29 3b  zeof(rVal)==8 );
7120: 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63 70  .          memcp
7130: 79 28 26 72 56 61 6c 2c 20 26 69 56 61 6c 2c 20  y(&rVal, &iVal, 
7140: 38 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66  8);.          if
7150: 28 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  ( sqlite3_value_
7160: 64 6f 75 62 6c 65 28 70 56 61 6c 29 21 3d 72 56  double(pVal)!=rV
7170: 61 6c 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20  al ) return 0;. 
7180: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
7190: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69 6e  else{.        in
71a0: 74 20 6e 3b 0a 20 20 20 20 20 20 20 20 63 6f 6e  t n;.        con
71b0: 73 74 20 75 38 20 2a 7a 3b 0a 20 20 20 20 20 20  st u8 *z;.      
71c0: 20 20 61 20 2b 3d 20 73 65 73 73 69 6f 6e 56 61    a += sessionVa
71d0: 72 69 6e 74 47 65 74 28 61 2c 20 26 6e 29 3b 0a  rintGet(a, &n);.
71e0: 20 20 20 20 20 20 20 20 69 66 28 20 73 71 6c 69          if( sqli
71f0: 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28  te3_value_bytes(
7200: 70 56 61 6c 29 21 3d 6e 20 29 20 72 65 74 75 72  pVal)!=n ) retur
7210: 6e 20 30 3b 0a 20 20 20 20 20 20 20 20 69 66 28  n 0;.        if(
7220: 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 54   eType==SQLITE_T
7230: 45 58 54 20 29 7b 0a 20 20 20 20 20 20 20 20 20  EXT ){.         
7240: 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c   z = sqlite3_val
7250: 75 65 5f 74 65 78 74 28 70 56 61 6c 29 3b 0a 20  ue_text(pVal);. 
7260: 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20         }else{.  
7270: 20 20 20 20 20 20 20 20 7a 20 3d 20 73 71 6c 69          z = sqli
7280: 74 65 33 5f 76 61 6c 75 65 5f 62 6c 6f 62 28 70  te3_value_blob(p
7290: 56 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  Val);.        }.
72a0: 20 20 20 20 20 20 20 20 69 66 28 20 6d 65 6d 63          if( memc
72b0: 6d 70 28 61 2c 20 7a 2c 20 6e 29 20 29 20 72 65  mp(a, z, n) ) re
72c0: 74 75 72 6e 20 30 3b 0a 20 20 20 20 20 20 20 20  turn 0;.        
72d0: 61 20 2b 3d 20 6e 3b 0a 20 20 20 20 20 20 20 20  a += n;.        
72e0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20  break;.      }. 
72f0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
7300: 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  rn 1;.}../*.** I
7310: 66 20 72 65 71 75 69 72 65 64 2c 20 67 72 6f 77  f required, grow
7320: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   the hash table 
7330: 75 73 65 64 20 74 6f 20 73 74 6f 72 65 20 63 68  used to store ch
7340: 61 6e 67 65 73 20 6f 6e 20 74 61 62 6c 65 20 70  anges on table p
7350: 54 61 62 20 0a 2a 2a 20 28 70 61 72 74 20 6f 66  Tab .** (part of
7360: 20 74 68 65 20 73 65 73 73 69 6f 6e 20 70 53 65   the session pSe
7370: 73 73 69 6f 6e 29 2e 20 49 66 20 61 20 66 61 74  ssion). If a fat
7380: 61 6c 20 4f 4f 4d 20 65 72 72 6f 72 20 6f 63 63  al OOM error occ
7390: 75 72 73 2c 20 73 65 74 20 74 68 65 0a 2a 2a 20  urs, set the.** 
73a0: 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 74  session object t
73b0: 6f 20 66 61 69 6c 65 64 20 61 6e 64 20 72 65 74  o failed and ret
73c0: 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  urn SQLITE_ERROR
73d0: 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 72 65 74  . Otherwise, ret
73e0: 75 72 6e 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b  urn.** SQLITE_OK
73f0: 2e 0a 2a 2a 0a 2a 2a 20 49 74 20 69 73 20 70 6f  ..**.** It is po
7400: 73 73 69 62 6c 65 20 74 68 61 74 20 61 20 6e 6f  ssible that a no
7410: 6e 2d 66 61 74 61 6c 20 4f 4f 4d 20 65 72 72 6f  n-fatal OOM erro
7420: 72 20 6f 63 63 75 72 73 20 69 6e 20 74 68 69 73  r occurs in this
7430: 20 66 75 6e 63 74 69 6f 6e 2e 20 49 6e 0a 2a 2a   function. In.**
7440: 20 74 68 61 74 20 63 61 73 65 20 74 68 65 20 68   that case the h
7450: 61 73 68 2d 74 61 62 6c 65 20 64 6f 65 73 20 6e  ash-table does n
7460: 6f 74 20 67 72 6f 77 2c 20 62 75 74 20 53 51 4c  ot grow, but SQL
7470: 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e  ITE_OK is return
7480: 65 64 20 61 6e 79 77 61 79 2e 0a 2a 2a 20 47 72  ed anyway..** Gr
7490: 6f 77 69 6e 67 20 74 68 65 20 68 61 73 68 20 74  owing the hash t
74a0: 61 62 6c 65 20 69 6e 20 74 68 69 73 20 63 61 73  able in this cas
74b0: 65 20 69 73 20 61 20 70 65 72 66 6f 72 6d 61 6e  e is a performan
74c0: 63 65 20 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 20  ce optimization 
74d0: 6f 6e 6c 79 2c 0a 2a 2a 20 69 74 20 69 73 20 6e  only,.** it is n
74e0: 6f 74 20 72 65 71 75 69 72 65 64 20 66 6f 72 20  ot required for 
74f0: 63 6f 72 72 65 63 74 20 6f 70 65 72 61 74 69 6f  correct operatio
7500: 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  n..*/.static int
7510: 20 73 65 73 73 69 6f 6e 47 72 6f 77 48 61 73 68   sessionGrowHash
7520: 28 69 6e 74 20 62 50 61 74 63 68 73 65 74 2c 20  (int bPatchset, 
7530: 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70 54  SessionTable *pT
7540: 61 62 29 7b 0a 20 20 69 66 28 20 70 54 61 62 2d  ab){.  if( pTab-
7550: 3e 6e 43 68 61 6e 67 65 3d 3d 30 20 7c 7c 20 70  >nChange==0 || p
7560: 54 61 62 2d 3e 6e 45 6e 74 72 79 3e 3d 28 70 54  Tab->nEntry>=(pT
7570: 61 62 2d 3e 6e 43 68 61 6e 67 65 2f 32 29 20 29  ab->nChange/2) )
7580: 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20  {.    int i;.   
7590: 20 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a   SessionChange *
75a0: 2a 61 70 4e 65 77 3b 0a 20 20 20 20 69 6e 74 20  *apNew;.    int 
75b0: 6e 4e 65 77 20 3d 20 28 70 54 61 62 2d 3e 6e 43  nNew = (pTab->nC
75c0: 68 61 6e 67 65 20 3f 20 70 54 61 62 2d 3e 6e 43  hange ? pTab->nC
75d0: 68 61 6e 67 65 20 3a 20 31 32 38 29 20 2a 20 32  hange : 128) * 2
75e0: 3b 0a 0a 20 20 20 20 61 70 4e 65 77 20 3d 20 28  ;..    apNew = (
75f0: 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 2a  SessionChange **
7600: 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28  )sqlite3_malloc(
7610: 73 69 7a 65 6f 66 28 53 65 73 73 69 6f 6e 43 68  sizeof(SessionCh
7620: 61 6e 67 65 20 2a 29 20 2a 20 6e 4e 65 77 29 3b  ange *) * nNew);
7630: 0a 20 20 20 20 69 66 28 20 61 70 4e 65 77 3d 3d  .    if( apNew==
7640: 30 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70  0 ){.      if( p
7650: 54 61 62 2d 3e 6e 43 68 61 6e 67 65 3d 3d 30 20  Tab->nChange==0 
7660: 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ){.        retur
7670: 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  n SQLITE_ERROR;.
7680: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72 65        }.      re
7690: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
76a0: 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d 73 65 74      }.    memset
76b0: 28 61 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65 6f  (apNew, 0, sizeo
76c0: 66 28 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20  f(SessionChange 
76d0: 2a 29 20 2a 20 6e 4e 65 77 29 3b 0a 0a 20 20 20  *) * nNew);..   
76e0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61 62   for(i=0; i<pTab
76f0: 2d 3e 6e 43 68 61 6e 67 65 3b 20 69 2b 2b 29 7b  ->nChange; i++){
7700: 0a 20 20 20 20 20 20 53 65 73 73 69 6f 6e 43 68  .      SessionCh
7710: 61 6e 67 65 20 2a 70 3b 0a 20 20 20 20 20 20 53  ange *p;.      S
7720: 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 70 4e  essionChange *pN
7730: 65 78 74 3b 0a 20 20 20 20 20 20 66 6f 72 28 70  ext;.      for(p
7740: 3d 70 54 61 62 2d 3e 61 70 43 68 61 6e 67 65 5b  =pTab->apChange[
7750: 69 5d 3b 20 70 3b 20 70 3d 70 4e 65 78 74 29 7b  i]; p; p=pNext){
7760: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 62 50 6b  .        int bPk
7770: 4f 6e 6c 79 20 3d 20 28 70 2d 3e 6f 70 3d 3d 53  Only = (p->op==S
7780: 51 4c 49 54 45 5f 44 45 4c 45 54 45 20 26 26 20  QLITE_DELETE && 
7790: 62 50 61 74 63 68 73 65 74 29 3b 0a 20 20 20 20  bPatchset);.    
77a0: 20 20 20 20 69 6e 74 20 69 48 61 73 68 20 3d 20      int iHash = 
77b0: 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 48 61 73  sessionChangeHas
77c0: 68 28 70 54 61 62 2c 20 62 50 6b 4f 6e 6c 79 2c  h(pTab, bPkOnly,
77d0: 20 70 2d 3e 61 52 65 63 6f 72 64 2c 20 6e 4e 65   p->aRecord, nNe
77e0: 77 29 3b 0a 20 20 20 20 20 20 20 20 70 4e 65 78  w);.        pNex
77f0: 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20  t = p->pNext;.  
7800: 20 20 20 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d        p->pNext =
7810: 20 61 70 4e 65 77 5b 69 48 61 73 68 5d 3b 0a 20   apNew[iHash];. 
7820: 20 20 20 20 20 20 20 61 70 4e 65 77 5b 69 48 61         apNew[iHa
7830: 73 68 5d 20 3d 20 70 3b 0a 20 20 20 20 20 20 7d  sh] = p;.      }
7840: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69  .    }..    sqli
7850: 74 65 33 5f 66 72 65 65 28 70 54 61 62 2d 3e 61  te3_free(pTab->a
7860: 70 43 68 61 6e 67 65 29 3b 0a 20 20 20 20 70 54  pChange);.    pT
7870: 61 62 2d 3e 6e 43 68 61 6e 67 65 20 3d 20 6e 4e  ab->nChange = nN
7880: 65 77 3b 0a 20 20 20 20 70 54 61 62 2d 3e 61 70  ew;.    pTab->ap
7890: 43 68 61 6e 67 65 20 3d 20 61 70 4e 65 77 3b 0a  Change = apNew;.
78a0: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51    }..  return SQ
78b0: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  LITE_OK;.}../*.*
78c0: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
78d0: 71 75 65 72 69 65 73 20 74 68 65 20 64 61 74 61  queries the data
78e0: 62 61 73 65 20 66 6f 72 20 74 68 65 20 6e 61 6d  base for the nam
78f0: 65 73 20 6f 66 20 74 68 65 20 63 6f 6c 75 6d 6e  es of the column
7900: 73 20 6f 66 20 74 61 62 6c 65 0a 2a 2a 20 7a 54  s of table.** zT
7910: 68 69 73 2c 20 69 6e 20 73 63 68 65 6d 61 20 7a  his, in schema z
7920: 44 62 2e 20 49 74 20 69 73 20 65 78 70 65 63 74  Db. It is expect
7930: 65 64 20 74 68 61 74 20 74 68 65 20 74 61 62 6c  ed that the tabl
7940: 65 20 68 61 73 20 6e 43 6f 6c 20 63 6f 6c 75 6d  e has nCol colum
7950: 6e 73 2e 20 49 66 0a 2a 2a 20 6e 6f 74 2c 20 53  ns. If.** not, S
7960: 51 4c 49 54 45 5f 53 43 48 45 4d 41 20 69 73 20  QLITE_SCHEMA is 
7970: 72 65 74 75 72 6e 65 64 20 61 6e 64 20 6e 6f 6e  returned and non
7980: 65 20 6f 66 20 74 68 65 20 6f 75 74 70 75 74 20  e of the output 
7990: 76 61 72 69 61 62 6c 65 73 20 61 72 65 0a 2a 2a  variables are.**
79a0: 20 70 6f 70 75 6c 61 74 65 64 2e 0a 2a 2a 0a 2a   populated..**.*
79b0: 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20  * Otherwise, if 
79c0: 74 68 65 79 20 61 72 65 20 6e 6f 74 20 4e 55 4c  they are not NUL
79d0: 4c 2c 20 76 61 72 69 61 62 6c 65 20 2a 70 6e 43  L, variable *pnC
79e0: 6f 6c 20 69 73 20 73 65 74 20 74 6f 20 74 68 65  ol is set to the
79f0: 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20 63 6f   number.** of co
7a00: 6c 75 6d 6e 73 20 69 6e 20 74 68 65 20 64 61 74  lumns in the dat
7a10: 61 62 61 73 65 20 74 61 62 6c 65 20 61 6e 64 20  abase table and 
7a20: 76 61 72 69 61 62 6c 65 20 2a 70 7a 54 61 62 20  variable *pzTab 
7a30: 69 73 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20  is set to point 
7a40: 74 6f 20 61 0a 2a 2a 20 6e 75 6c 2d 74 65 72 6d  to a.** nul-term
7a50: 69 6e 61 74 65 64 20 63 6f 70 79 20 6f 66 20 74  inated copy of t
7a60: 68 65 20 74 61 62 6c 65 20 6e 61 6d 65 2e 20 2a  he table name. *
7a70: 70 61 7a 43 6f 6c 20 28 69 66 20 6e 6f 74 20 4e  pazCol (if not N
7a80: 55 4c 4c 29 20 69 73 20 73 65 74 20 74 6f 0a 2a  ULL) is set to.*
7a90: 2a 20 70 6f 69 6e 74 20 74 6f 20 61 6e 20 61 72  * point to an ar
7aa0: 72 61 79 20 6f 66 20 70 6f 69 6e 74 65 72 73 20  ray of pointers 
7ab0: 74 6f 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 2e  to column names.
7ac0: 20 41 6e 64 20 2a 70 61 62 50 4b 20 28 61 67 61   And *pabPK (aga
7ad0: 69 6e 2c 20 69 66 20 6e 6f 74 0a 2a 2a 20 4e 55  in, if not.** NU
7ae0: 4c 4c 29 20 69 73 20 73 65 74 20 74 6f 20 70 6f  LL) is set to po
7af0: 69 6e 74 20 74 6f 20 61 6e 20 61 72 72 61 79 20  int to an array 
7b00: 6f 66 20 62 6f 6f 6c 65 61 6e 73 20 2d 20 74 72  of booleans - tr
7b10: 75 65 20 69 66 20 74 68 65 20 63 6f 72 72 65 73  ue if the corres
7b20: 70 6f 6e 64 69 6e 67 0a 2a 2a 20 63 6f 6c 75 6d  ponding.** colum
7b30: 6e 20 69 73 20 70 61 72 74 20 6f 66 20 74 68 65  n is part of the
7b40: 20 70 72 69 6d 61 72 79 20 6b 65 79 2e 0a 2a 2a   primary key..**
7b50: 0a 2a 2a 20 46 6f 72 20 65 78 61 6d 70 6c 65 2c  .** For example,
7b60: 20 69 66 20 74 68 65 20 74 61 62 6c 65 20 69 73   if the table is
7b70: 20 64 65 63 6c 61 72 65 64 20 61 73 3a 0a 2a 2a   declared as:.**
7b80: 0a 2a 2a 20 20 20 20 20 43 52 45 41 54 45 20 54  .**     CREATE T
7b90: 41 42 4c 45 20 74 62 6c 31 28 77 2c 20 78 2c 20  ABLE tbl1(w, x, 
7ba0: 79 2c 20 7a 2c 20 50 52 49 4d 41 52 59 20 4b 45  y, z, PRIMARY KE
7bb0: 59 28 77 2c 20 7a 29 29 3b 0a 2a 2a 0a 2a 2a 20  Y(w, z));.**.** 
7bc0: 54 68 65 6e 20 74 68 65 20 66 6f 75 72 20 6f 75  Then the four ou
7bd0: 74 70 75 74 20 76 61 72 69 61 62 6c 65 73 20 61  tput variables a
7be0: 72 65 20 70 6f 70 75 6c 61 74 65 64 20 61 73 20  re populated as 
7bf0: 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20  follows:.**.**  
7c00: 20 20 20 2a 70 6e 43 6f 6c 20 20 3d 20 34 0a 2a     *pnCol  = 4.*
7c10: 2a 20 20 20 20 20 2a 70 7a 54 61 62 20 20 3d 20  *     *pzTab  = 
7c20: 22 74 62 6c 31 22 0a 2a 2a 20 20 20 20 20 2a 70  "tbl1".**     *p
7c30: 61 7a 43 6f 6c 20 3d 20 7b 22 77 22 2c 20 22 78  azCol = {"w", "x
7c40: 22 2c 20 22 79 22 2c 20 22 7a 22 7d 0a 2a 2a 20  ", "y", "z"}.** 
7c50: 20 20 20 20 2a 70 61 62 50 4b 20 20 3d 20 7b 31      *pabPK  = {1
7c60: 2c 20 30 2c 20 30 2c 20 31 7d 0a 2a 2a 0a 2a 2a  , 0, 0, 1}.**.**
7c70: 20 41 6c 6c 20 72 65 74 75 72 6e 65 64 20 62 75   All returned bu
7c80: 66 66 65 72 73 20 61 72 65 20 70 61 72 74 20 6f  ffers are part o
7c90: 66 20 74 68 65 20 73 61 6d 65 20 73 69 6e 67 6c  f the same singl
7ca0: 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 2c 20 77 68  e allocation, wh
7cb0: 69 63 68 20 6d 75 73 74 0a 2a 2a 20 62 65 20 66  ich must.** be f
7cc0: 72 65 65 64 20 75 73 69 6e 67 20 73 71 6c 69 74  reed using sqlit
7cd0: 65 33 5f 66 72 65 65 28 29 20 62 79 20 74 68 65  e3_free() by the
7ce0: 20 63 61 6c 6c 65 72 2e 20 49 66 20 70 61 7a 43   caller. If pazC
7cf0: 6f 6c 20 77 61 73 20 6e 6f 74 20 4e 55 4c 4c 2c  ol was not NULL,
7d00: 20 74 68 65 6e 0a 2a 2a 20 70 6f 69 6e 74 65 72   then.** pointer
7d10: 20 2a 70 61 7a 43 6f 6c 20 73 68 6f 75 6c 64 20   *pazCol should 
7d20: 62 65 20 66 72 65 65 64 20 74 6f 20 72 65 6c 65  be freed to rele
7d30: 61 73 65 20 61 6c 6c 20 6d 65 6d 6f 72 79 2e 20  ase all memory. 
7d40: 4f 74 68 65 72 77 69 73 65 2c 20 70 6f 69 6e 74  Otherwise, point
7d50: 65 72 0a 2a 2a 20 2a 70 61 62 50 4b 2e 20 49 74  er.** *pabPK. It
7d60: 20 69 73 20 69 6c 6c 65 67 61 6c 20 66 6f 72 20   is illegal for 
7d70: 62 6f 74 68 20 70 61 7a 43 6f 6c 20 61 6e 64 20  both pazCol and 
7d80: 70 61 62 50 4b 20 74 6f 20 62 65 20 4e 55 4c 4c  pabPK to be NULL
7d90: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
7da0: 73 65 73 73 69 6f 6e 54 61 62 6c 65 49 6e 66 6f  sessionTableInfo
7db0: 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
7dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7dd0: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
7de0: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20  connection */.  
7df0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62 2c  const char *zDb,
7e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7e10: 2f 2a 20 4e 61 6d 65 20 6f 66 20 61 74 74 61 63  /* Name of attac
7e20: 68 65 64 20 64 61 74 61 62 61 73 65 20 28 65 2e  hed database (e.
7e30: 67 2e 20 22 6d 61 69 6e 22 29 20 2a 2f 0a 20 20  g. "main") */.  
7e40: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 68 69  const char *zThi
7e50: 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s,              
7e60: 2f 2a 20 54 61 62 6c 65 20 6e 61 6d 65 20 2a 2f  /* Table name */
7e70: 0a 20 20 69 6e 74 20 2a 70 6e 43 6f 6c 2c 20 20  .  int *pnCol,  
7e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7e90: 20 20 20 2f 2a 20 4f 55 54 3a 20 6e 75 6d 62 65     /* OUT: numbe
7ea0: 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a  r of columns */.
7eb0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 70    const char **p
7ec0: 7a 54 61 62 2c 20 20 20 20 20 20 20 20 20 20 20  zTab,           
7ed0: 20 20 2f 2a 20 4f 55 54 3a 20 43 6f 70 79 20 6f    /* OUT: Copy o
7ee0: 66 20 7a 54 68 69 73 20 2a 2f 0a 20 20 63 6f 6e  f zThis */.  con
7ef0: 73 74 20 63 68 61 72 20 2a 2a 2a 70 61 7a 43 6f  st char ***pazCo
7f00: 6c 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  l,           /* 
7f10: 4f 55 54 3a 20 41 72 72 61 79 20 6f 66 20 63 6f  OUT: Array of co
7f20: 6c 75 6d 6e 20 6e 61 6d 65 73 20 66 6f 72 20 74  lumn names for t
7f30: 61 62 6c 65 20 2a 2f 0a 20 20 75 38 20 2a 2a 70  able */.  u8 **p
7f40: 61 62 50 4b 20 20 20 20 20 20 20 20 20 20 20 20  abPK            
7f50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
7f60: 3a 20 41 72 72 61 79 20 6f 66 20 62 6f 6f 6c 65  : Array of boole
7f70: 61 6e 73 20 2d 20 74 72 75 65 20 66 6f 72 20 50  ans - true for P
7f80: 4b 20 63 6f 6c 20 2a 2f 0a 29 7b 0a 20 20 63 68  K col */.){.  ch
7f90: 61 72 20 2a 7a 50 72 61 67 6d 61 3b 0a 20 20 73  ar *zPragma;.  s
7fa0: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
7fb0: 6d 74 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  mt;.  int rc;.  
7fc0: 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 69 6e 74  int nByte;.  int
7fd0: 20 6e 44 62 43 6f 6c 20 3d 20 30 3b 0a 20 20 69   nDbCol = 0;.  i
7fe0: 6e 74 20 6e 54 68 69 73 3b 0a 20 20 69 6e 74 20  nt nThis;.  int 
7ff0: 69 3b 0a 20 20 75 38 20 2a 70 41 6c 6c 6f 63 20  i;.  u8 *pAlloc 
8000: 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 2a 61 7a  = 0;.  char **az
8010: 43 6f 6c 20 3d 20 30 3b 0a 20 20 75 38 20 2a 61  Col = 0;.  u8 *a
8020: 62 50 4b 20 3d 20 30 3b 0a 0a 20 20 61 73 73 65  bPK = 0;..  asse
8030: 72 74 28 20 70 61 7a 43 6f 6c 20 26 26 20 70 61  rt( pazCol && pa
8040: 62 50 4b 20 29 3b 0a 0a 20 20 6e 54 68 69 73 20  bPK );..  nThis 
8050: 3d 20 73 71 6c 69 74 65 33 53 74 72 6c 65 6e 33  = sqlite3Strlen3
8060: 30 28 7a 54 68 69 73 29 3b 0a 20 20 7a 50 72 61  0(zThis);.  zPra
8070: 67 6d 61 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  gma = sqlite3_mp
8080: 72 69 6e 74 66 28 22 50 52 41 47 4d 41 20 27 25  rintf("PRAGMA '%
8090: 71 27 2e 74 61 62 6c 65 5f 69 6e 66 6f 28 27 25  q'.table_info('%
80a0: 71 27 29 22 2c 20 7a 44 62 2c 20 7a 54 68 69 73  q')", zDb, zThis
80b0: 29 3b 0a 20 20 69 66 28 20 21 7a 50 72 61 67 6d  );.  if( !zPragm
80c0: 61 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  a ) return SQLIT
80d0: 45 5f 4e 4f 4d 45 4d 3b 0a 0a 20 20 72 63 20 3d  E_NOMEM;..  rc =
80e0: 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65   sqlite3_prepare
80f0: 5f 76 32 28 64 62 2c 20 7a 50 72 61 67 6d 61 2c  _v2(db, zPragma,
8100: 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b   -1, &pStmt, 0);
8110: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
8120: 7a 50 72 61 67 6d 61 29 3b 0a 20 20 69 66 28 20  zPragma);.  if( 
8130: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
8140: 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 6e 42  return rc;..  nB
8150: 79 74 65 20 3d 20 6e 54 68 69 73 20 2b 20 31 3b  yte = nThis + 1;
8160: 0a 20 20 77 68 69 6c 65 28 20 53 51 4c 49 54 45  .  while( SQLITE
8170: 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33 5f 73 74  _ROW==sqlite3_st
8180: 65 70 28 70 53 74 6d 74 29 20 29 7b 0a 20 20 20  ep(pStmt) ){.   
8190: 20 6e 42 79 74 65 20 2b 3d 20 73 71 6c 69 74 65   nByte += sqlite
81a0: 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70  3_column_bytes(p
81b0: 53 74 6d 74 2c 20 31 29 3b 0a 20 20 20 20 6e 44  Stmt, 1);.    nD
81c0: 62 43 6f 6c 2b 2b 3b 0a 20 20 7d 0a 20 20 72 63  bCol++;.  }.  rc
81d0: 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74   = sqlite3_reset
81e0: 28 70 53 74 6d 74 29 3b 0a 0a 20 20 69 66 28 20  (pStmt);..  if( 
81f0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
8200: 0a 20 20 20 20 6e 42 79 74 65 20 2b 3d 20 6e 44  .    nByte += nD
8210: 62 43 6f 6c 20 2a 20 28 73 69 7a 65 6f 66 28 63  bCol * (sizeof(c
8220: 6f 6e 73 74 20 63 68 61 72 20 2a 29 20 2b 20 73  onst char *) + s
8230: 69 7a 65 6f 66 28 75 38 29 20 2b 20 31 29 3b 0a  izeof(u8) + 1);.
8240: 20 20 20 20 70 41 6c 6c 6f 63 20 3d 20 73 71 6c      pAlloc = sql
8250: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74  ite3_malloc(nByt
8260: 65 29 3b 0a 20 20 20 20 69 66 28 20 70 41 6c 6c  e);.    if( pAll
8270: 6f 63 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72  oc==0 ){.      r
8280: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
8290: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66  ;.    }.  }.  if
82a0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
82b0: 29 7b 0a 20 20 20 20 61 7a 43 6f 6c 20 3d 20 28  ){.    azCol = (
82c0: 63 68 61 72 20 2a 2a 29 70 41 6c 6c 6f 63 3b 0a  char **)pAlloc;.
82d0: 20 20 20 20 70 41 6c 6c 6f 63 20 3d 20 28 75 38      pAlloc = (u8
82e0: 20 2a 29 26 61 7a 43 6f 6c 5b 6e 44 62 43 6f 6c   *)&azCol[nDbCol
82f0: 5d 3b 0a 20 20 20 20 61 62 50 4b 20 3d 20 28 75  ];.    abPK = (u
8300: 38 20 2a 29 70 41 6c 6c 6f 63 3b 0a 20 20 20 20  8 *)pAlloc;.    
8310: 70 41 6c 6c 6f 63 20 3d 20 26 61 62 50 4b 5b 6e  pAlloc = &abPK[n
8320: 44 62 43 6f 6c 5d 3b 0a 20 20 20 20 69 66 28 20  DbCol];.    if( 
8330: 70 7a 54 61 62 20 29 7b 0a 20 20 20 20 20 20 6d  pzTab ){.      m
8340: 65 6d 63 70 79 28 70 41 6c 6c 6f 63 2c 20 7a 54  emcpy(pAlloc, zT
8350: 68 69 73 2c 20 6e 54 68 69 73 2b 31 29 3b 0a 20  his, nThis+1);. 
8360: 20 20 20 20 20 2a 70 7a 54 61 62 20 3d 20 28 63       *pzTab = (c
8370: 68 61 72 20 2a 29 70 41 6c 6c 6f 63 3b 0a 20 20  har *)pAlloc;.  
8380: 20 20 20 20 70 41 6c 6c 6f 63 20 2b 3d 20 6e 54      pAlloc += nT
8390: 68 69 73 2b 31 3b 0a 20 20 20 20 7d 0a 20 20 0a  his+1;.    }.  .
83a0: 20 20 20 20 69 20 3d 20 30 3b 0a 20 20 20 20 77      i = 0;.    w
83b0: 68 69 6c 65 28 20 53 51 4c 49 54 45 5f 52 4f 57  hile( SQLITE_ROW
83c0: 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70  ==sqlite3_step(p
83d0: 53 74 6d 74 29 20 29 7b 0a 20 20 20 20 20 20 69  Stmt) ){.      i
83e0: 6e 74 20 6e 4e 61 6d 65 20 3d 20 73 71 6c 69 74  nt nName = sqlit
83f0: 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28  e3_column_bytes(
8400: 70 53 74 6d 74 2c 20 31 29 3b 0a 20 20 20 20 20  pStmt, 1);.     
8410: 20 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64 20   const unsigned 
8420: 63 68 61 72 20 2a 7a 4e 61 6d 65 20 3d 20 73 71  char *zName = sq
8430: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78  lite3_column_tex
8440: 74 28 70 53 74 6d 74 2c 20 31 29 3b 0a 20 20 20  t(pStmt, 1);.   
8450: 20 20 20 69 66 28 20 7a 4e 61 6d 65 3d 3d 30 20     if( zName==0 
8460: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 6d  ) break;.      m
8470: 65 6d 63 70 79 28 70 41 6c 6c 6f 63 2c 20 7a 4e  emcpy(pAlloc, zN
8480: 61 6d 65 2c 20 6e 4e 61 6d 65 2b 31 29 3b 0a 20  ame, nName+1);. 
8490: 20 20 20 20 20 61 7a 43 6f 6c 5b 69 5d 20 3d 20       azCol[i] = 
84a0: 28 63 68 61 72 20 2a 29 70 41 6c 6c 6f 63 3b 0a  (char *)pAlloc;.
84b0: 20 20 20 20 20 20 70 41 6c 6c 6f 63 20 2b 3d 20        pAlloc += 
84c0: 6e 4e 61 6d 65 2b 31 3b 0a 20 20 20 20 20 20 61  nName+1;.      a
84d0: 62 50 4b 5b 69 5d 20 3d 20 73 71 6c 69 74 65 33  bPK[i] = sqlite3
84e0: 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d  _column_int(pStm
84f0: 74 2c 20 35 29 3b 0a 20 20 20 20 20 20 69 2b 2b  t, 5);.      i++
8500: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 63 20 3d  ;.    }.    rc =
8510: 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70   sqlite3_reset(p
8520: 53 74 6d 74 29 3b 0a 20 20 0a 20 20 7d 0a 0a 20  Stmt);.  .  }.. 
8530: 20 2f 2a 20 49 66 20 73 75 63 63 65 73 73 66 75   /* If successfu
8540: 6c 2c 20 70 6f 70 75 6c 61 74 65 20 74 68 65 20  l, populate the 
8550: 6f 75 74 70 75 74 20 76 61 72 69 61 62 6c 65 73  output variables
8560: 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 7a 65 72  . Otherwise, zer
8570: 6f 20 74 68 65 6d 20 61 6e 64 0a 20 20 2a 2a 20  o them and.  ** 
8580: 66 72 65 65 20 61 6e 79 20 61 6c 6c 6f 63 61 74  free any allocat
8590: 69 6f 6e 20 6d 61 64 65 2e 20 41 6e 20 65 72 72  ion made. An err
85a0: 6f 72 20 63 6f 64 65 20 77 69 6c 6c 20 62 65 20  or code will be 
85b0: 72 65 74 75 72 6e 65 64 20 69 6e 20 74 68 69 73  returned in this
85c0: 20 63 61 73 65 2e 0a 20 20 2a 2f 0a 20 20 69 66   case..  */.  if
85d0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
85e0: 29 7b 0a 20 20 20 20 2a 70 61 7a 43 6f 6c 20 3d  ){.    *pazCol =
85f0: 20 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 29   (const char **)
8600: 61 7a 43 6f 6c 3b 0a 20 20 20 20 2a 70 61 62 50  azCol;.    *pabP
8610: 4b 20 3d 20 61 62 50 4b 3b 0a 20 20 20 20 2a 70  K = abPK;.    *p
8620: 6e 43 6f 6c 20 3d 20 6e 44 62 43 6f 6c 3b 0a 20  nCol = nDbCol;. 
8630: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2a 70 61 7a   }else{.    *paz
8640: 43 6f 6c 20 3d 20 30 3b 0a 20 20 20 20 2a 70 61  Col = 0;.    *pa
8650: 62 50 4b 20 3d 20 30 3b 0a 20 20 20 20 2a 70 6e  bPK = 0;.    *pn
8660: 43 6f 6c 20 3d 20 30 3b 0a 20 20 20 20 69 66 28  Col = 0;.    if(
8670: 20 70 7a 54 61 62 20 29 20 2a 70 7a 54 61 62 20   pzTab ) *pzTab 
8680: 3d 20 30 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  = 0;.    sqlite3
8690: 5f 66 72 65 65 28 61 7a 43 6f 6c 29 3b 0a 20 20  _free(azCol);.  
86a0: 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  }.  sqlite3_fina
86b0: 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 72  lize(pStmt);.  r
86c0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
86d0: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
86e0: 20 69 73 20 6f 6e 6c 79 20 63 61 6c 6c 65 64 20   is only called 
86f0: 66 72 6f 6d 20 77 69 74 68 69 6e 20 61 20 70 72  from within a pr
8700: 65 2d 75 70 64 61 74 65 20 68 61 6e 64 6c 65 72  e-update handler
8710: 20 66 6f 72 20 61 0a 2a 2a 20 77 72 69 74 65 20   for a.** write 
8720: 74 6f 20 74 61 62 6c 65 20 70 54 61 62 2c 20 70  to table pTab, p
8730: 61 72 74 20 6f 66 20 73 65 73 73 69 6f 6e 20 70  art of session p
8740: 53 65 73 73 69 6f 6e 2e 20 49 66 20 74 68 69 73  Session. If this
8750: 20 69 73 20 74 68 65 20 66 69 72 73 74 0a 2a 2a   is the first.**
8760: 20 77 72 69 74 65 20 74 6f 20 74 68 69 73 20 74   write to this t
8770: 61 62 6c 65 2c 20 69 6e 69 74 61 6c 69 7a 65 20  able, initalize 
8780: 74 68 65 20 53 65 73 73 69 6f 6e 54 61 62 6c 65  the SessionTable
8790: 2e 6e 43 6f 6c 2c 20 61 7a 43 6f 6c 5b 5d 20 61  .nCol, azCol[] a
87a0: 6e 64 0a 2a 2a 20 61 62 50 4b 5b 5d 20 61 72 72  nd.** abPK[] arr
87b0: 61 79 73 20 61 63 63 6f 72 64 69 6e 67 6c 79 2e  ays accordingly.
87c0: 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 65 72 72  .**.** If an err
87d0: 6f 72 20 6f 63 63 75 72 73 2c 20 61 6e 20 65 72  or occurs, an er
87e0: 72 6f 72 20 63 6f 64 65 20 69 73 20 73 74 6f 72  ror code is stor
87f0: 65 64 20 69 6e 20 73 71 6c 69 74 65 33 5f 73 65  ed in sqlite3_se
8800: 73 73 69 6f 6e 2e 72 63 20 61 6e 64 0a 2a 2a 20  ssion.rc and.** 
8810: 6e 6f 6e 2d 7a 65 72 6f 20 72 65 74 75 72 6e 65  non-zero returne
8820: 64 2e 20 4f 72 2c 20 69 66 20 6e 6f 20 65 72 72  d. Or, if no err
8830: 6f 72 20 6f 63 63 75 72 73 20 62 75 74 20 74 68  or occurs but th
8840: 65 20 74 61 62 6c 65 20 68 61 73 20 6e 6f 20 70  e table has no p
8850: 72 69 6d 61 72 79 0a 2a 2a 20 6b 65 79 2c 20 73  rimary.** key, s
8860: 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 2e 72  qlite3_session.r
8870: 63 20 69 73 20 6c 65 66 74 20 73 65 74 20 74 6f  c is left set to
8880: 20 53 51 4c 49 54 45 5f 4f 4b 20 61 6e 64 20 6e   SQLITE_OK and n
8890: 6f 6e 2d 7a 65 72 6f 20 72 65 74 75 72 6e 65 64  on-zero returned
88a0: 20 74 6f 0a 2a 2a 20 69 6e 64 69 63 61 74 65 20   to.** indicate 
88b0: 74 68 61 74 20 75 70 64 61 74 65 73 20 6f 6e 20  that updates on 
88c0: 74 68 69 73 20 74 61 62 6c 65 20 73 68 6f 75 6c  this table shoul
88d0: 64 20 62 65 20 69 67 6e 6f 72 65 64 2e 20 53 65  d be ignored. Se
88e0: 73 73 69 6f 6e 54 61 62 6c 65 2e 61 62 50 4b 20  ssionTable.abPK 
88f0: 0a 2a 2a 20 69 73 20 73 65 74 20 74 6f 20 4e 55  .** is set to NU
8900: 4c 4c 20 69 6e 20 74 68 69 73 20 63 61 73 65 2e  LL in this case.
8910: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73  .*/.static int s
8920: 65 73 73 69 6f 6e 49 6e 69 74 54 61 62 6c 65 28  essionInitTable(
8930: 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20  sqlite3_session 
8940: 2a 70 53 65 73 73 69 6f 6e 2c 20 53 65 73 73 69  *pSession, Sessi
8950: 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62 29 7b 0a  onTable *pTab){.
8960: 20 20 69 66 28 20 70 54 61 62 2d 3e 6e 43 6f 6c    if( pTab->nCol
8970: 3d 3d 30 20 29 7b 0a 20 20 20 20 75 38 20 2a 61  ==0 ){.    u8 *a
8980: 62 50 4b 3b 0a 20 20 20 20 61 73 73 65 72 74 28  bPK;.    assert(
8990: 20 70 54 61 62 2d 3e 61 7a 43 6f 6c 3d 3d 30 20   pTab->azCol==0 
89a0: 7c 7c 20 70 54 61 62 2d 3e 61 62 50 4b 3d 3d 30  || pTab->abPK==0
89b0: 20 29 3b 0a 20 20 20 20 70 53 65 73 73 69 6f 6e   );.    pSession
89c0: 2d 3e 72 63 20 3d 20 73 65 73 73 69 6f 6e 54 61  ->rc = sessionTa
89d0: 62 6c 65 49 6e 66 6f 28 70 53 65 73 73 69 6f 6e  bleInfo(pSession
89e0: 2d 3e 64 62 2c 20 70 53 65 73 73 69 6f 6e 2d 3e  ->db, pSession->
89f0: 7a 44 62 2c 20 0a 20 20 20 20 20 20 20 20 70 54  zDb, .        pT
8a00: 61 62 2d 3e 7a 4e 61 6d 65 2c 20 26 70 54 61 62  ab->zName, &pTab
8a10: 2d 3e 6e 43 6f 6c 2c 20 30 2c 20 26 70 54 61 62  ->nCol, 0, &pTab
8a20: 2d 3e 61 7a 43 6f 6c 2c 20 26 61 62 50 4b 0a 20  ->azCol, &abPK. 
8a30: 20 20 20 29 3b 0a 20 20 20 20 69 66 28 20 70 53     );.    if( pS
8a40: 65 73 73 69 6f 6e 2d 3e 72 63 3d 3d 53 51 4c 49  ession->rc==SQLI
8a50: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69  TE_OK ){.      i
8a60: 6e 74 20 69 3b 0a 20 20 20 20 20 20 66 6f 72 28  nt i;.      for(
8a70: 69 3d 30 3b 20 69 3c 70 54 61 62 2d 3e 6e 43 6f  i=0; i<pTab->nCo
8a80: 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20  l; i++){.       
8a90: 20 69 66 28 20 61 62 50 4b 5b 69 5d 20 29 7b 0a   if( abPK[i] ){.
8aa0: 20 20 20 20 20 20 20 20 20 20 70 54 61 62 2d 3e            pTab->
8ab0: 61 62 50 4b 20 3d 20 61 62 50 4b 3b 0a 20 20 20  abPK = abPK;.   
8ac0: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
8ad0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
8ae0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
8af0: 72 6e 20 28 70 53 65 73 73 69 6f 6e 2d 3e 72 63  rn (pSession->rc
8b00: 20 7c 7c 20 70 54 61 62 2d 3e 61 62 50 4b 3d 3d   || pTab->abPK==
8b10: 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  0);.}../*.** Thi
8b20: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 6f 6e  s function is on
8b30: 6c 79 20 63 61 6c 6c 65 64 20 66 72 6f 6d 20 77  ly called from w
8b40: 69 74 68 20 61 20 70 72 65 2d 75 70 64 61 74 65  ith a pre-update
8b50: 2d 68 6f 6f 6b 20 72 65 70 6f 72 74 69 6e 67 20  -hook reporting 
8b60: 61 20 0a 2a 2a 20 63 68 61 6e 67 65 20 6f 6e 20  a .** change on 
8b70: 74 61 62 6c 65 20 70 54 61 62 20 28 61 74 74 61  table pTab (atta
8b80: 63 68 65 64 20 74 6f 20 73 65 73 73 69 6f 6e 20  ched to session 
8b90: 70 53 65 73 73 69 6f 6e 29 2e 20 54 68 65 20 74  pSession). The t
8ba0: 79 70 65 20 6f 66 20 63 68 61 6e 67 65 0a 2a 2a  ype of change.**
8bb0: 20 28 55 50 44 41 54 45 2c 20 49 4e 53 45 52 54   (UPDATE, INSERT
8bc0: 2c 20 44 45 4c 45 54 45 29 20 69 73 20 73 70 65  , DELETE) is spe
8bd0: 63 69 66 69 65 64 20 62 79 20 74 68 65 20 66 69  cified by the fi
8be0: 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a  rst argument..**
8bf0: 0a 2a 2a 20 55 6e 6c 65 73 73 20 6f 6e 65 20 69  .** Unless one i
8c00: 73 20 61 6c 72 65 61 64 79 20 70 72 65 73 65 6e  s already presen
8c10: 74 20 6f 72 20 61 6e 20 65 72 72 6f 72 20 6f 63  t or an error oc
8c20: 63 75 72 73 2c 20 61 6e 20 65 6e 74 72 79 20 69  curs, an entry i
8c30: 73 20 61 64 64 65 64 0a 2a 2a 20 74 6f 20 74 68  s added.** to th
8c40: 65 20 63 68 61 6e 67 65 64 2d 72 6f 77 73 20 68  e changed-rows h
8c50: 61 73 68 20 74 61 62 6c 65 20 61 73 73 6f 63 69  ash table associ
8c60: 61 74 65 64 20 77 69 74 68 20 74 61 62 6c 65 20  ated with table 
8c70: 70 54 61 62 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  pTab..*/.static 
8c80: 76 6f 69 64 20 73 65 73 73 69 6f 6e 50 72 65 75  void sessionPreu
8c90: 70 64 61 74 65 4f 6e 65 43 68 61 6e 67 65 28 0a  pdateOneChange(.
8ca0: 20 20 69 6e 74 20 6f 70 2c 20 20 20 20 20 20 20    int op,       
8cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8cc0: 20 20 2f 2a 20 4f 6e 65 20 6f 66 20 53 51 4c 49    /* One of SQLI
8cd0: 54 45 5f 55 50 44 41 54 45 2c 20 49 4e 53 45 52  TE_UPDATE, INSER
8ce0: 54 2c 20 44 45 4c 45 54 45 20 2a 2f 0a 20 20 73  T, DELETE */.  s
8cf0: 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a  qlite3_session *
8d00: 70 53 65 73 73 69 6f 6e 2c 20 20 20 20 20 20 2f  pSession,      /
8d10: 2a 20 53 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74  * Session object
8d20: 20 70 54 61 62 20 69 73 20 61 74 74 61 63 68 65   pTab is attache
8d30: 64 20 74 6f 20 2a 2f 0a 20 20 53 65 73 73 69 6f  d to */.  Sessio
8d40: 6e 54 61 62 6c 65 20 2a 70 54 61 62 20 20 20 20  nTable *pTab    
8d50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62            /* Tab
8d60: 6c 65 20 74 68 61 74 20 63 68 61 6e 67 65 20 61  le that change a
8d70: 70 70 6c 69 65 73 20 74 6f 20 2a 2f 0a 29 7b 0a  pplies to */.){.
8d80: 20 20 69 6e 74 20 69 48 61 73 68 3b 20 0a 20 20    int iHash; .  
8d90: 69 6e 74 20 62 4e 75 6c 6c 20 3d 20 30 3b 20 0a  int bNull = 0; .
8da0: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
8db0: 45 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 70 53 65  E_OK;..  if( pSe
8dc0: 73 73 69 6f 6e 2d 3e 72 63 20 29 20 72 65 74 75  ssion->rc ) retu
8dd0: 72 6e 3b 0a 0a 20 20 2f 2a 20 4c 6f 61 64 20 74  rn;..  /* Load t
8de0: 61 62 6c 65 20 64 65 74 61 69 6c 73 20 69 66 20  able details if 
8df0: 72 65 71 75 69 72 65 64 20 2a 2f 0a 20 20 69 66  required */.  if
8e00: 28 20 73 65 73 73 69 6f 6e 49 6e 69 74 54 61 62  ( sessionInitTab
8e10: 6c 65 28 70 53 65 73 73 69 6f 6e 2c 20 70 54 61  le(pSession, pTa
8e20: 62 29 20 29 20 72 65 74 75 72 6e 3b 0a 0a 20 20  b) ) return;..  
8e30: 2f 2a 20 43 68 65 63 6b 20 74 68 65 20 6e 75 6d  /* Check the num
8e40: 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69  ber of columns i
8e50: 6e 20 74 68 69 73 20 78 50 72 65 55 70 64 61 74  n this xPreUpdat
8e60: 65 20 63 61 6c 6c 20 6d 61 74 63 68 65 73 20 74  e call matches t
8e70: 68 65 20 0a 20 20 2a 2a 20 6e 75 6d 62 65 72 20  he .  ** number 
8e80: 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 68  of columns in th
8e90: 65 20 74 61 62 6c 65 2e 20 20 2a 2f 0a 20 20 69  e table.  */.  i
8ea0: 66 28 20 70 54 61 62 2d 3e 6e 43 6f 6c 21 3d 70  f( pTab->nCol!=p
8eb0: 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 43  Session->hook.xC
8ec0: 6f 75 6e 74 28 70 53 65 73 73 69 6f 6e 2d 3e 68  ount(pSession->h
8ed0: 6f 6f 6b 2e 70 43 74 78 29 20 29 7b 0a 20 20 20  ook.pCtx) ){.   
8ee0: 20 70 53 65 73 73 69 6f 6e 2d 3e 72 63 20 3d 20   pSession->rc = 
8ef0: 53 51 4c 49 54 45 5f 53 43 48 45 4d 41 3b 0a 20  SQLITE_SCHEMA;. 
8f00: 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 0a     return;.  }..
8f10: 20 20 2f 2a 20 47 72 6f 77 20 74 68 65 20 68 61    /* Grow the ha
8f20: 73 68 20 74 61 62 6c 65 20 69 66 20 72 65 71 75  sh table if requ
8f30: 69 72 65 64 20 2a 2f 0a 20 20 69 66 28 20 73 65  ired */.  if( se
8f40: 73 73 69 6f 6e 47 72 6f 77 48 61 73 68 28 30 2c  ssionGrowHash(0,
8f50: 20 70 54 61 62 29 20 29 7b 0a 20 20 20 20 70 53   pTab) ){.    pS
8f60: 65 73 73 69 6f 6e 2d 3e 72 63 20 3d 20 53 51 4c  ession->rc = SQL
8f70: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 72  ITE_NOMEM;.    r
8f80: 65 74 75 72 6e 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  eturn;.  }..  /*
8f90: 20 43 61 6c 63 75 6c 61 74 65 20 74 68 65 20 68   Calculate the h
8fa0: 61 73 68 2d 6b 65 79 20 66 6f 72 20 74 68 69 73  ash-key for this
8fb0: 20 63 68 61 6e 67 65 2e 20 49 66 20 74 68 65 20   change. If the 
8fc0: 70 72 69 6d 61 72 79 20 6b 65 79 20 6f 66 20 74  primary key of t
8fd0: 68 65 20 72 6f 77 0a 20 20 2a 2a 20 69 6e 63 6c  he row.  ** incl
8fe0: 75 64 65 73 20 61 20 4e 55 4c 4c 20 76 61 6c 75  udes a NULL valu
8ff0: 65 2c 20 65 78 69 74 20 65 61 72 6c 79 2e 20 53  e, exit early. S
9000: 75 63 68 20 63 68 61 6e 67 65 73 20 61 72 65 20  uch changes are 
9010: 69 67 6e 6f 72 65 64 20 62 79 20 74 68 65 0a 20  ignored by the. 
9020: 20 2a 2a 20 73 65 73 73 69 6f 6e 20 6d 6f 64 75   ** session modu
9030: 6c 65 2e 20 2a 2f 0a 20 20 72 63 20 3d 20 73 65  le. */.  rc = se
9040: 73 73 69 6f 6e 50 72 65 75 70 64 61 74 65 48 61  ssionPreupdateHa
9050: 73 68 28 70 53 65 73 73 69 6f 6e 2c 20 70 54 61  sh(pSession, pTa
9060: 62 2c 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e  b, op==SQLITE_IN
9070: 53 45 52 54 2c 20 26 69 48 61 73 68 2c 20 26 62  SERT, &iHash, &b
9080: 4e 75 6c 6c 29 3b 0a 20 20 69 66 28 20 72 63 21  Null);.  if( rc!
9090: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 67 6f 74  =SQLITE_OK ) got
90a0: 6f 20 65 72 72 6f 72 5f 6f 75 74 3b 0a 0a 20 20  o error_out;..  
90b0: 69 66 28 20 62 4e 75 6c 6c 3d 3d 30 20 29 7b 0a  if( bNull==0 ){.
90c0: 20 20 20 20 2f 2a 20 53 65 61 72 63 68 20 74 68      /* Search th
90d0: 65 20 68 61 73 68 20 74 61 62 6c 65 20 66 6f 72  e hash table for
90e0: 20 61 6e 20 65 78 69 73 74 69 6e 67 20 72 65 63   an existing rec
90f0: 6f 72 64 20 66 6f 72 20 74 68 69 73 20 72 6f 77  ord for this row
9100: 2e 20 2a 2f 0a 20 20 20 20 53 65 73 73 69 6f 6e  . */.    Session
9110: 43 68 61 6e 67 65 20 2a 70 43 3b 0a 20 20 20 20  Change *pC;.    
9120: 66 6f 72 28 70 43 3d 70 54 61 62 2d 3e 61 70 43  for(pC=pTab->apC
9130: 68 61 6e 67 65 5b 69 48 61 73 68 5d 3b 20 70 43  hange[iHash]; pC
9140: 3b 20 70 43 3d 70 43 2d 3e 70 4e 65 78 74 29 7b  ; pC=pC->pNext){
9150: 0a 20 20 20 20 20 20 69 66 28 20 73 65 73 73 69  .      if( sessi
9160: 6f 6e 50 72 65 75 70 64 61 74 65 45 71 75 61 6c  onPreupdateEqual
9170: 28 70 53 65 73 73 69 6f 6e 2c 20 70 54 61 62 2c  (pSession, pTab,
9180: 20 70 43 2c 20 6f 70 29 20 29 20 62 72 65 61 6b   pC, op) ) break
9190: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  ;.    }..    if(
91a0: 20 70 43 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20   pC==0 ){.      
91b0: 2f 2a 20 43 72 65 61 74 65 20 61 20 6e 65 77 20  /* Create a new 
91c0: 63 68 61 6e 67 65 20 6f 62 6a 65 63 74 20 63 6f  change object co
91d0: 6e 74 61 69 6e 69 6e 67 20 61 6c 6c 20 74 68 65  ntaining all the
91e0: 20 6f 6c 64 20 76 61 6c 75 65 73 20 28 69 66 0a   old values (if.
91f0: 20 20 20 20 20 20 2a 2a 20 74 68 69 73 20 69 73        ** this is
9200: 20 61 6e 20 53 51 4c 49 54 45 5f 55 50 44 41 54   an SQLITE_UPDAT
9210: 45 20 6f 72 20 53 51 4c 49 54 45 5f 44 45 4c 45  E or SQLITE_DELE
9220: 54 45 29 2c 20 6f 72 20 6a 75 73 74 20 74 68 65  TE), or just the
9230: 20 50 4b 0a 20 20 20 20 20 20 2a 2a 20 76 61 6c   PK.      ** val
9240: 75 65 73 20 28 69 66 20 74 68 69 73 20 69 73 20  ues (if this is 
9250: 61 6e 20 49 4e 53 45 52 54 29 2e 20 2a 2f 0a 20  an INSERT). */. 
9260: 20 20 20 20 20 53 65 73 73 69 6f 6e 43 68 61 6e       SessionChan
9270: 67 65 20 2a 70 43 68 61 6e 67 65 3b 20 2f 2a 20  ge *pChange; /* 
9280: 4e 65 77 20 63 68 61 6e 67 65 20 6f 62 6a 65 63  New change objec
9290: 74 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e  t */.      int n
92a0: 42 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20  Byte;           
92b0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
92c0: 62 79 74 65 73 20 74 6f 20 61 6c 6c 6f 63 61 74  bytes to allocat
92d0: 65 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 69  e */.      int i
92e0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
92f0: 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69 74     /* Used to it
9300: 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 63 6f  erate through co
9310: 6c 75 6d 6e 73 20 2a 2f 0a 20 20 0a 20 20 20 20  lumns */.  .    
9320: 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51    assert( rc==SQ
9330: 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 20 20 20  LITE_OK );.     
9340: 20 70 54 61 62 2d 3e 6e 45 6e 74 72 79 2b 2b 3b   pTab->nEntry++;
9350: 0a 20 20 0a 20 20 20 20 20 20 2f 2a 20 46 69 67  .  .      /* Fig
9360: 75 72 65 20 6f 75 74 20 68 6f 77 20 6c 61 72 67  ure out how larg
9370: 65 20 61 6e 20 61 6c 6c 6f 63 61 74 69 6f 6e 20  e an allocation 
9380: 69 73 20 72 65 71 75 69 72 65 64 20 2a 2f 0a 20  is required */. 
9390: 20 20 20 20 20 6e 42 79 74 65 20 3d 20 73 69 7a       nByte = siz
93a0: 65 6f 66 28 53 65 73 73 69 6f 6e 43 68 61 6e 67  eof(SessionChang
93b0: 65 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d  e);.      for(i=
93c0: 30 3b 20 69 3c 70 54 61 62 2d 3e 6e 43 6f 6c 3b  0; i<pTab->nCol;
93d0: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 73   i++){.        s
93e0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 20  qlite3_value *p 
93f0: 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 69 66 28  = 0;.        if(
9400: 20 6f 70 21 3d 53 51 4c 49 54 45 5f 49 4e 53 45   op!=SQLITE_INSE
9410: 52 54 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  RT ){.          
9420: 54 45 53 54 4f 4e 4c 59 28 69 6e 74 20 74 72 63  TESTONLY(int trc
9430: 20 3d 20 29 20 70 53 65 73 73 69 6f 6e 2d 3e 68   = ) pSession->h
9440: 6f 6f 6b 2e 78 4f 6c 64 28 70 53 65 73 73 69 6f  ook.xOld(pSessio
9450: 6e 2d 3e 68 6f 6f 6b 2e 70 43 74 78 2c 20 69 2c  n->hook.pCtx, i,
9460: 20 26 70 29 3b 0a 20 20 20 20 20 20 20 20 20 20   &p);.          
9470: 61 73 73 65 72 74 28 20 74 72 63 3d 3d 53 51 4c  assert( trc==SQL
9480: 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 20 20 20 20  ITE_OK );.      
9490: 20 20 7d 65 6c 73 65 20 69 66 28 20 70 54 61 62    }else if( pTab
94a0: 2d 3e 61 62 50 4b 5b 69 5d 20 29 7b 0a 20 20 20  ->abPK[i] ){.   
94b0: 20 20 20 20 20 20 20 54 45 53 54 4f 4e 4c 59 28         TESTONLY(
94c0: 69 6e 74 20 74 72 63 20 3d 20 29 20 70 53 65 73  int trc = ) pSes
94d0: 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 4e 65 77 28  sion->hook.xNew(
94e0: 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 70  pSession->hook.p
94f0: 43 74 78 2c 20 69 2c 20 26 70 29 3b 0a 20 20 20  Ctx, i, &p);.   
9500: 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20 74         assert( t
9510: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b  rc==SQLITE_OK );
9520: 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  .        }..    
9530: 20 20 20 20 2f 2a 20 54 68 69 73 20 6d 61 79 20      /* This may 
9540: 66 61 69 6c 20 69 66 20 53 51 4c 69 74 65 20 76  fail if SQLite v
9550: 61 6c 75 65 20 70 20 63 6f 6e 74 61 69 6e 73 20  alue p contains 
9560: 61 20 75 74 66 2d 31 36 20 73 74 72 69 6e 67 20  a utf-16 string 
9570: 74 68 61 74 20 6d 75 73 74 0a 20 20 20 20 20 20  that must.      
9580: 20 20 2a 2a 20 62 65 20 63 6f 6e 76 65 72 74 65    ** be converte
9590: 64 20 74 6f 20 75 74 66 2d 38 20 61 6e 64 20 61  d to utf-8 and a
95a0: 6e 20 4f 4f 4d 20 65 72 72 6f 72 20 6f 63 63 75  n OOM error occu
95b0: 72 73 20 77 68 69 6c 65 20 64 6f 69 6e 67 20 73  rs while doing s
95c0: 6f 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20 72 63  o. */.        rc
95d0: 20 3d 20 73 65 73 73 69 6f 6e 53 65 72 69 61 6c   = sessionSerial
95e0: 69 7a 65 56 61 6c 75 65 28 30 2c 20 70 2c 20 26  izeValue(0, p, &
95f0: 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20 20 20  nByte);.        
9600: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
9610: 4b 20 29 20 67 6f 74 6f 20 65 72 72 6f 72 5f 6f  K ) goto error_o
9620: 75 74 3b 0a 20 20 20 20 20 20 7d 0a 20 20 0a 20  ut;.      }.  . 
9630: 20 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65       /* Allocate
9640: 20 74 68 65 20 63 68 61 6e 67 65 20 6f 62 6a 65   the change obje
9650: 63 74 20 2a 2f 0a 20 20 20 20 20 20 70 43 68 61  ct */.      pCha
9660: 6e 67 65 20 3d 20 28 53 65 73 73 69 6f 6e 43 68  nge = (SessionCh
9670: 61 6e 67 65 20 2a 29 73 71 6c 69 74 65 33 5f 6d  ange *)sqlite3_m
9680: 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20  alloc(nByte);.  
9690: 20 20 20 20 69 66 28 20 21 70 43 68 61 6e 67 65      if( !pChange
96a0: 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d   ){.        rc =
96b0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
96c0: 20 20 20 20 20 20 20 67 6f 74 6f 20 65 72 72 6f         goto erro
96d0: 72 5f 6f 75 74 3b 0a 20 20 20 20 20 20 7d 65 6c  r_out;.      }el
96e0: 73 65 7b 0a 20 20 20 20 20 20 20 20 6d 65 6d 73  se{.        mems
96f0: 65 74 28 70 43 68 61 6e 67 65 2c 20 30 2c 20 73  et(pChange, 0, s
9700: 69 7a 65 6f 66 28 53 65 73 73 69 6f 6e 43 68 61  izeof(SessionCha
9710: 6e 67 65 29 29 3b 0a 20 20 20 20 20 20 20 20 70  nge));.        p
9720: 43 68 61 6e 67 65 2d 3e 61 52 65 63 6f 72 64 20  Change->aRecord 
9730: 3d 20 28 75 38 20 2a 29 26 70 43 68 61 6e 67 65  = (u8 *)&pChange
9740: 5b 31 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20 0a  [1];.      }.  .
9750: 20 20 20 20 20 20 2f 2a 20 50 6f 70 75 6c 61 74        /* Populat
9760: 65 20 74 68 65 20 63 68 61 6e 67 65 20 6f 62 6a  e the change obj
9770: 65 63 74 2e 20 4e 6f 6e 65 20 6f 66 20 74 68 65  ect. None of the
9780: 20 70 72 65 75 70 64 61 74 65 5f 6f 6c 64 28 29   preupdate_old()
9790: 2c 0a 20 20 20 20 20 20 2a 2a 20 70 72 65 75 70  ,.      ** preup
97a0: 64 61 74 65 5f 6e 65 77 28 29 20 6f 72 20 53 65  date_new() or Se
97b0: 72 69 61 6c 69 7a 65 56 61 6c 75 65 28 29 20 63  rializeValue() c
97c0: 61 6c 6c 73 20 62 65 6c 6f 77 20 6d 61 79 20 66  alls below may f
97d0: 61 69 6c 20 61 73 20 61 6c 6c 0a 20 20 20 20 20  ail as all.     
97e0: 20 2a 2a 20 72 65 71 75 69 72 65 64 20 76 61 6c   ** required val
97f0: 75 65 73 20 61 6e 64 20 65 6e 63 6f 64 69 6e 67  ues and encoding
9800: 73 20 68 61 76 65 20 61 6c 72 65 61 64 79 20 62  s have already b
9810: 65 65 6e 20 63 61 63 68 65 64 20 69 6e 20 6d 65  een cached in me
9820: 6d 6f 72 79 2e 0a 20 20 20 20 20 20 2a 2a 20 49  mory..      ** I
9830: 74 20 69 73 20 6e 6f 74 20 70 6f 73 73 69 62 6c  t is not possibl
9840: 65 20 66 6f 72 20 61 6e 20 4f 4f 4d 20 74 6f 20  e for an OOM to 
9850: 6f 63 63 75 72 20 69 6e 20 74 68 69 73 20 62 6c  occur in this bl
9860: 6f 63 6b 2e 20 2a 2f 0a 20 20 20 20 20 20 6e 42  ock. */.      nB
9870: 79 74 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 66  yte = 0;.      f
9880: 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61 62 2d 3e  or(i=0; i<pTab->
9890: 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  nCol; i++){.    
98a0: 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75      sqlite3_valu
98b0: 65 20 2a 70 20 3d 20 30 3b 0a 20 20 20 20 20 20  e *p = 0;.      
98c0: 20 20 69 66 28 20 6f 70 21 3d 53 51 4c 49 54 45    if( op!=SQLITE
98d0: 5f 49 4e 53 45 52 54 20 29 7b 0a 20 20 20 20 20  _INSERT ){.     
98e0: 20 20 20 20 20 70 53 65 73 73 69 6f 6e 2d 3e 68       pSession->h
98f0: 6f 6f 6b 2e 78 4f 6c 64 28 70 53 65 73 73 69 6f  ook.xOld(pSessio
9900: 6e 2d 3e 68 6f 6f 6b 2e 70 43 74 78 2c 20 69 2c  n->hook.pCtx, i,
9910: 20 26 70 29 3b 0a 20 20 20 20 20 20 20 20 7d 65   &p);.        }e
9920: 6c 73 65 20 69 66 28 20 70 54 61 62 2d 3e 61 62  lse if( pTab->ab
9930: 50 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20 20  PK[i] ){.       
9940: 20 20 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f     pSession->hoo
9950: 6b 2e 78 4e 65 77 28 70 53 65 73 73 69 6f 6e 2d  k.xNew(pSession-
9960: 3e 68 6f 6f 6b 2e 70 43 74 78 2c 20 69 2c 20 26  >hook.pCtx, i, &
9970: 70 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  p);.        }.  
9980: 20 20 20 20 20 20 73 65 73 73 69 6f 6e 53 65 72        sessionSer
9990: 69 61 6c 69 7a 65 56 61 6c 75 65 28 26 70 43 68  ializeValue(&pCh
99a0: 61 6e 67 65 2d 3e 61 52 65 63 6f 72 64 5b 6e 42  ange->aRecord[nB
99b0: 79 74 65 5d 2c 20 70 2c 20 26 6e 42 79 74 65 29  yte], p, &nByte)
99c0: 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  ;.      }..     
99d0: 20 2f 2a 20 41 64 64 20 74 68 65 20 63 68 61 6e   /* Add the chan
99e0: 67 65 20 74 6f 20 74 68 65 20 68 61 73 68 2d 74  ge to the hash-t
99f0: 61 62 6c 65 20 2a 2f 0a 20 20 20 20 20 20 69 66  able */.      if
9a00: 28 20 70 53 65 73 73 69 6f 6e 2d 3e 62 49 6e 64  ( pSession->bInd
9a10: 69 72 65 63 74 20 7c 7c 20 70 53 65 73 73 69 6f  irect || pSessio
9a20: 6e 2d 3e 68 6f 6f 6b 2e 78 44 65 70 74 68 28 70  n->hook.xDepth(p
9a30: 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 70 43  Session->hook.pC
9a40: 74 78 29 20 29 7b 0a 20 20 20 20 20 20 20 20 70  tx) ){.        p
9a50: 43 68 61 6e 67 65 2d 3e 62 49 6e 64 69 72 65 63  Change->bIndirec
9a60: 74 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20  t = 1;.      }. 
9a70: 20 20 20 20 20 70 43 68 61 6e 67 65 2d 3e 6e 52       pChange->nR
9a80: 65 63 6f 72 64 20 3d 20 6e 42 79 74 65 3b 0a 20  ecord = nByte;. 
9a90: 20 20 20 20 20 70 43 68 61 6e 67 65 2d 3e 6f 70       pChange->op
9aa0: 20 3d 20 6f 70 3b 0a 20 20 20 20 20 20 70 43 68   = op;.      pCh
9ab0: 61 6e 67 65 2d 3e 70 4e 65 78 74 20 3d 20 70 54  ange->pNext = pT
9ac0: 61 62 2d 3e 61 70 43 68 61 6e 67 65 5b 69 48 61  ab->apChange[iHa
9ad0: 73 68 5d 3b 0a 20 20 20 20 20 20 70 54 61 62 2d  sh];.      pTab-
9ae0: 3e 61 70 43 68 61 6e 67 65 5b 69 48 61 73 68 5d  >apChange[iHash]
9af0: 20 3d 20 70 43 68 61 6e 67 65 3b 0a 0a 20 20 20   = pChange;..   
9b00: 20 7d 65 6c 73 65 20 69 66 28 20 70 43 2d 3e 62   }else if( pC->b
9b10: 49 6e 64 69 72 65 63 74 20 29 7b 0a 20 20 20 20  Indirect ){.    
9b20: 20 20 2f 2a 20 49 66 20 74 68 65 20 65 78 69 73    /* If the exis
9b30: 74 69 6e 67 20 63 68 61 6e 67 65 20 69 73 20 63  ting change is c
9b40: 6f 6e 73 69 64 65 72 65 64 20 22 69 6e 64 69 72  onsidered "indir
9b50: 65 63 74 22 2c 20 62 75 74 20 74 68 69 73 20 63  ect", but this c
9b60: 75 72 72 65 6e 74 0a 20 20 20 20 20 20 2a 2a 20  urrent.      ** 
9b70: 63 68 61 6e 67 65 20 69 73 20 22 64 69 72 65 63  change is "direc
9b80: 74 22 2c 20 6d 61 72 6b 20 74 68 65 20 63 68 61  t", mark the cha
9b90: 6e 67 65 20 6f 62 6a 65 63 74 20 61 73 20 64 69  nge object as di
9ba0: 72 65 63 74 2e 20 2a 2f 0a 20 20 20 20 20 20 69  rect. */.      i
9bb0: 66 28 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f  f( pSession->hoo
9bc0: 6b 2e 78 44 65 70 74 68 28 70 53 65 73 73 69 6f  k.xDepth(pSessio
9bd0: 6e 2d 3e 68 6f 6f 6b 2e 70 43 74 78 29 3d 3d 30  n->hook.pCtx)==0
9be0: 20 0a 20 20 20 20 20 20 20 26 26 20 70 53 65 73   .       && pSes
9bf0: 73 69 6f 6e 2d 3e 62 49 6e 64 69 72 65 63 74 3d  sion->bIndirect=
9c00: 3d 30 20 0a 20 20 20 20 20 20 29 7b 0a 20 20 20  =0 .      ){.   
9c10: 20 20 20 20 20 70 43 2d 3e 62 49 6e 64 69 72 65       pC->bIndire
9c20: 63 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a  ct = 0;.      }.
9c30: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20      }.  }..  /* 
9c40: 49 66 20 61 6e 20 65 72 72 6f 72 20 68 61 73 20  If an error has 
9c50: 6f 63 63 75 72 72 65 64 2c 20 6d 61 72 6b 20 74  occurred, mark t
9c60: 68 65 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63  he session objec
9c70: 74 20 61 73 20 66 61 69 6c 65 64 2e 20 2a 2f 0a  t as failed. */.
9c80: 20 65 72 72 6f 72 5f 6f 75 74 3a 0a 20 20 69 66   error_out:.  if
9c90: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
9ca0: 29 7b 0a 20 20 20 20 70 53 65 73 73 69 6f 6e 2d  ){.    pSession-
9cb0: 3e 72 63 20 3d 20 72 63 3b 0a 20 20 7d 0a 7d 0a  >rc = rc;.  }.}.
9cc0: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73  .static int sess
9cd0: 69 6f 6e 46 69 6e 64 54 61 62 6c 65 28 0a 20 20  ionFindTable(.  
9ce0: 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20  sqlite3_session 
9cf0: 2a 70 53 65 73 73 69 6f 6e 2c 20 0a 20 20 63 6f  *pSession, .  co
9d00: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c  nst char *zName,
9d10: 0a 20 20 53 65 73 73 69 6f 6e 54 61 62 6c 65 20  .  SessionTable 
9d20: 2a 2a 70 70 54 61 62 0a 29 7b 0a 20 20 69 6e 74  **ppTab.){.  int
9d30: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
9d40: 0a 20 20 69 6e 74 20 6e 4e 61 6d 65 20 3d 20 73  .  int nName = s
9d50: 71 6c 69 74 65 33 53 74 72 6c 65 6e 33 30 28 7a  qlite3Strlen30(z
9d60: 4e 61 6d 65 29 3b 0a 20 20 53 65 73 73 69 6f 6e  Name);.  Session
9d70: 54 61 62 6c 65 20 2a 70 52 65 74 3b 0a 0a 20 20  Table *pRet;..  
9d80: 2f 2a 20 53 65 61 72 63 68 20 66 6f 72 20 61 6e  /* Search for an
9d90: 20 65 78 69 73 74 69 6e 67 20 74 61 62 6c 65 20   existing table 
9da0: 2a 2f 0a 20 20 66 6f 72 28 70 52 65 74 3d 70 53  */.  for(pRet=pS
9db0: 65 73 73 69 6f 6e 2d 3e 70 54 61 62 6c 65 3b 20  ession->pTable; 
9dc0: 70 52 65 74 3b 20 70 52 65 74 3d 70 52 65 74 2d  pRet; pRet=pRet-
9dd0: 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 69 66 28  >pNext){.    if(
9de0: 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 6e   0==sqlite3_strn
9df0: 69 63 6d 70 28 70 52 65 74 2d 3e 7a 4e 61 6d 65  icmp(pRet->zName
9e00: 2c 20 7a 4e 61 6d 65 2c 20 6e 4e 61 6d 65 2b 31  , zName, nName+1
9e10: 29 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a  ) ) break;.  }..
9e20: 20 20 69 66 28 20 70 52 65 74 3d 3d 30 20 26 26    if( pRet==0 &&
9e30: 20 70 53 65 73 73 69 6f 6e 2d 3e 62 41 75 74 6f   pSession->bAuto
9e40: 41 74 74 61 63 68 20 29 7b 0a 20 20 20 20 2f 2a  Attach ){.    /*
9e50: 20 49 66 20 74 68 65 72 65 20 69 73 20 61 20 74   If there is a t
9e60: 61 62 6c 65 2d 66 69 6c 74 65 72 20 63 6f 6e 66  able-filter conf
9e70: 69 67 75 72 65 64 2c 20 69 6e 76 6f 6b 65 20 69  igured, invoke i
9e80: 74 2e 20 49 66 20 69 74 20 72 65 74 75 72 6e 73  t. If it returns
9e90: 20 30 2c 0a 20 20 20 20 2a 2a 20 64 6f 20 6e 6f   0,.    ** do no
9ea0: 74 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20  t automatically 
9eb0: 61 64 64 20 74 68 65 20 6e 65 77 20 74 61 62 6c  add the new tabl
9ec0: 65 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 53  e. */.    if( pS
9ed0: 65 73 73 69 6f 6e 2d 3e 78 54 61 62 6c 65 46 69  ession->xTableFi
9ee0: 6c 74 65 72 3d 3d 30 0a 20 20 20 20 20 7c 7c 20  lter==0.     || 
9ef0: 70 53 65 73 73 69 6f 6e 2d 3e 78 54 61 62 6c 65  pSession->xTable
9f00: 46 69 6c 74 65 72 28 70 53 65 73 73 69 6f 6e 2d  Filter(pSession-
9f10: 3e 70 46 69 6c 74 65 72 43 74 78 2c 20 7a 4e 61  >pFilterCtx, zNa
9f20: 6d 65 29 20 0a 20 20 20 20 29 7b 0a 20 20 20 20  me) .    ){.    
9f30: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 73 65    rc = sqlite3se
9f40: 73 73 69 6f 6e 5f 61 74 74 61 63 68 28 70 53 65  ssion_attach(pSe
9f50: 73 73 69 6f 6e 2c 20 7a 4e 61 6d 65 29 3b 0a 20  ssion, zName);. 
9f60: 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
9f70: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
9f80: 20 20 66 6f 72 28 70 52 65 74 3d 70 53 65 73 73    for(pRet=pSess
9f90: 69 6f 6e 2d 3e 70 54 61 62 6c 65 3b 20 70 52 65  ion->pTable; pRe
9fa0: 74 2d 3e 70 4e 65 78 74 3b 20 70 52 65 74 3d 70  t->pNext; pRet=p
9fb0: 52 65 74 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 20  Ret->pNext);.   
9fc0: 20 20 20 20 20 61 73 73 65 72 74 28 20 30 3d 3d       assert( 0==
9fd0: 73 71 6c 69 74 65 33 5f 73 74 72 6e 69 63 6d 70  sqlite3_strnicmp
9fe0: 28 70 52 65 74 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e  (pRet->zName, zN
9ff0: 61 6d 65 2c 20 6e 4e 61 6d 65 2b 31 29 20 29 3b  ame, nName+1) );
a000: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
a010: 20 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 72 63   }..  assert( rc
a020: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70  ==SQLITE_OK || p
a030: 52 65 74 3d 3d 30 20 29 3b 0a 20 20 2a 70 70 54  Ret==0 );.  *ppT
a040: 61 62 20 3d 20 70 52 65 74 3b 0a 20 20 72 65 74  ab = pRet;.  ret
a050: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
a060: 20 54 68 65 20 27 70 72 65 2d 75 70 64 61 74 65   The 'pre-update
a070: 27 20 68 6f 6f 6b 20 72 65 67 69 73 74 65 72 65  ' hook registere
a080: 64 20 62 79 20 74 68 69 73 20 6d 6f 64 75 6c 65  d by this module
a090: 20 77 69 74 68 20 53 51 4c 69 74 65 20 64 61 74   with SQLite dat
a0a0: 61 62 61 73 65 73 2e 0a 2a 2f 0a 73 74 61 74 69  abases..*/.stati
a0b0: 63 20 76 6f 69 64 20 78 50 72 65 55 70 64 61 74  c void xPreUpdat
a0c0: 65 28 0a 20 20 76 6f 69 64 20 2a 70 43 74 78 2c  e(.  void *pCtx,
a0d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a0e0: 20 20 20 20 20 2f 2a 20 43 6f 70 79 20 6f 66 20       /* Copy of 
a0f0: 74 68 69 72 64 20 61 72 67 20 74 6f 20 70 72 65  third arg to pre
a100: 75 70 64 61 74 65 5f 68 6f 6f 6b 28 29 20 2a 2f  update_hook() */
a110: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  .  sqlite3 *db, 
a120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a130: 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68     /* Database h
a140: 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6f  andle */.  int o
a150: 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p,              
a160: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 51             /* SQ
a170: 4c 49 54 45 5f 55 50 44 41 54 45 2c 20 44 45 4c  LITE_UPDATE, DEL
a180: 45 54 45 20 6f 72 20 49 4e 53 45 52 54 20 2a 2f  ETE or INSERT */
a190: 0a 20 20 63 68 61 72 20 63 6f 6e 73 74 20 2a 7a  .  char const *z
a1a0: 44 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  Db,             
a1b0: 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 6e     /* Database n
a1c0: 61 6d 65 20 2a 2f 0a 20 20 63 68 61 72 20 63 6f  ame */.  char co
a1d0: 6e 73 74 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 20  nst *zName,     
a1e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62 6c           /* Tabl
a1f0: 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 73 71 6c 69  e name */.  sqli
a200: 74 65 33 5f 69 6e 74 36 34 20 69 4b 65 79 31 2c  te3_int64 iKey1,
a210: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
a220: 6f 77 69 64 20 6f 66 20 72 6f 77 20 61 62 6f 75  owid of row abou
a230: 74 20 74 6f 20 62 65 20 64 65 6c 65 74 65 64 2f  t to be deleted/
a240: 75 70 64 61 74 65 64 20 2a 2f 0a 20 20 73 71 6c  updated */.  sql
a250: 69 74 65 33 5f 69 6e 74 36 34 20 69 4b 65 79 32  ite3_int64 iKey2
a260: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
a270: 4e 65 77 20 72 6f 77 69 64 20 76 61 6c 75 65 20  New rowid value 
a280: 28 66 6f 72 20 61 20 72 6f 77 69 64 20 55 50 44  (for a rowid UPD
a290: 41 54 45 29 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c  ATE) */.){.  sql
a2a0: 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53  ite3_session *pS
a2b0: 65 73 73 69 6f 6e 3b 0a 20 20 69 6e 74 20 6e 44  ession;.  int nD
a2c0: 62 20 3d 20 73 71 6c 69 74 65 33 53 74 72 6c 65  b = sqlite3Strle
a2d0: 6e 33 30 28 7a 44 62 29 3b 0a 0a 20 20 61 73 73  n30(zDb);..  ass
a2e0: 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74  ert( sqlite3_mut
a2f0: 65 78 5f 68 65 6c 64 28 64 62 2d 3e 6d 75 74 65  ex_held(db->mute
a300: 78 29 20 29 3b 0a 0a 20 20 66 6f 72 28 70 53 65  x) );..  for(pSe
a310: 73 73 69 6f 6e 3d 28 73 71 6c 69 74 65 33 5f 73  ssion=(sqlite3_s
a320: 65 73 73 69 6f 6e 20 2a 29 70 43 74 78 3b 20 70  ession *)pCtx; p
a330: 53 65 73 73 69 6f 6e 3b 20 70 53 65 73 73 69 6f  Session; pSessio
a340: 6e 3d 70 53 65 73 73 69 6f 6e 2d 3e 70 4e 65 78  n=pSession->pNex
a350: 74 29 7b 0a 20 20 20 20 53 65 73 73 69 6f 6e 54  t){.    SessionT
a360: 61 62 6c 65 20 2a 70 54 61 62 3b 0a 0a 20 20 20  able *pTab;..   
a370: 20 2f 2a 20 49 66 20 74 68 69 73 20 73 65 73 73   /* If this sess
a380: 69 6f 6e 20 69 73 20 61 74 74 61 63 68 65 64 20  ion is attached 
a390: 74 6f 20 61 20 64 69 66 66 65 72 65 6e 74 20 64  to a different d
a3a0: 61 74 61 62 61 73 65 20 28 22 6d 61 69 6e 22 2c  atabase ("main",
a3b0: 20 22 74 65 6d 70 22 20 0a 20 20 20 20 2a 2a 20   "temp" .    ** 
a3c0: 65 74 63 2e 29 2c 20 6f 72 20 69 66 20 69 74 20  etc.), or if it 
a3d0: 69 73 20 6e 6f 74 20 63 75 72 72 65 6e 74 6c 79  is not currently
a3e0: 20 65 6e 61 62 6c 65 64 2c 20 74 68 65 72 65 20   enabled, there 
a3f0: 69 73 20 6e 6f 74 68 69 6e 67 20 74 6f 20 64 6f  is nothing to do
a400: 2e 20 53 6b 69 70 20 0a 20 20 20 20 2a 2a 20 74  . Skip .    ** t
a410: 6f 20 74 68 65 20 6e 65 78 74 20 73 65 73 73 69  o the next sessi
a420: 6f 6e 20 6f 62 6a 65 63 74 20 61 74 74 61 63 68  on object attach
a430: 65 64 20 74 6f 20 74 68 69 73 20 64 61 74 61 62  ed to this datab
a440: 61 73 65 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20  ase. */.    if( 
a450: 70 53 65 73 73 69 6f 6e 2d 3e 62 45 6e 61 62 6c  pSession->bEnabl
a460: 65 3d 3d 30 20 29 20 63 6f 6e 74 69 6e 75 65 3b  e==0 ) continue;
a470: 0a 20 20 20 20 69 66 28 20 70 53 65 73 73 69 6f  .    if( pSessio
a480: 6e 2d 3e 72 63 20 29 20 63 6f 6e 74 69 6e 75 65  n->rc ) continue
a490: 3b 0a 20 20 20 20 69 66 28 20 73 71 6c 69 74 65  ;.    if( sqlite
a4a0: 33 5f 73 74 72 6e 69 63 6d 70 28 7a 44 62 2c 20  3_strnicmp(zDb, 
a4b0: 70 53 65 73 73 69 6f 6e 2d 3e 7a 44 62 2c 20 6e  pSession->zDb, n
a4c0: 44 62 2b 31 29 20 29 20 63 6f 6e 74 69 6e 75 65  Db+1) ) continue
a4d0: 3b 0a 0a 20 20 20 20 70 53 65 73 73 69 6f 6e 2d  ;..    pSession-
a4e0: 3e 72 63 20 3d 20 73 65 73 73 69 6f 6e 46 69 6e  >rc = sessionFin
a4f0: 64 54 61 62 6c 65 28 70 53 65 73 73 69 6f 6e 2c  dTable(pSession,
a500: 20 7a 4e 61 6d 65 2c 20 26 70 54 61 62 29 3b 0a   zName, &pTab);.
a510: 20 20 20 20 69 66 28 20 70 54 61 62 20 29 7b 0a      if( pTab ){.
a520: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 53        assert( pS
a530: 65 73 73 69 6f 6e 2d 3e 72 63 3d 3d 53 51 4c 49  ession->rc==SQLI
a540: 54 45 5f 4f 4b 20 29 3b 0a 20 20 20 20 20 20 73  TE_OK );.      s
a550: 65 73 73 69 6f 6e 50 72 65 75 70 64 61 74 65 4f  essionPreupdateO
a560: 6e 65 43 68 61 6e 67 65 28 6f 70 2c 20 70 53 65  neChange(op, pSe
a570: 73 73 69 6f 6e 2c 20 70 54 61 62 29 3b 0a 20 20  ssion, pTab);.  
a580: 20 20 20 20 69 66 28 20 6f 70 3d 3d 53 51 4c 49      if( op==SQLI
a590: 54 45 5f 55 50 44 41 54 45 20 29 7b 0a 20 20 20  TE_UPDATE ){.   
a5a0: 20 20 20 20 20 73 65 73 73 69 6f 6e 50 72 65 75       sessionPreu
a5b0: 70 64 61 74 65 4f 6e 65 43 68 61 6e 67 65 28 53  pdateOneChange(S
a5c0: 51 4c 49 54 45 5f 49 4e 53 45 52 54 2c 20 70 53  QLITE_INSERT, pS
a5d0: 65 73 73 69 6f 6e 2c 20 70 54 61 62 29 3b 0a 20  ession, pTab);. 
a5e0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
a5f0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 70 72  .}../*.** The pr
a600: 65 2d 75 70 64 61 74 65 20 68 6f 6f 6b 20 69 6d  e-update hook im
a610: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 73 2e 0a 2a  plementations..*
a620: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73  /.static int ses
a630: 73 69 6f 6e 50 72 65 75 70 64 61 74 65 4f 6c 64  sionPreupdateOld
a640: 28 76 6f 69 64 20 2a 70 43 74 78 2c 20 69 6e 74  (void *pCtx, int
a650: 20 69 56 61 6c 2c 20 73 71 6c 69 74 65 33 5f 76   iVal, sqlite3_v
a660: 61 6c 75 65 20 2a 2a 70 70 56 61 6c 29 7b 0a 20  alue **ppVal){. 
a670: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 5f   return sqlite3_
a680: 70 72 65 75 70 64 61 74 65 5f 6f 6c 64 28 28 73  preupdate_old((s
a690: 71 6c 69 74 65 33 2a 29 70 43 74 78 2c 20 69 56  qlite3*)pCtx, iV
a6a0: 61 6c 2c 20 70 70 56 61 6c 29 3b 0a 7d 0a 73 74  al, ppVal);.}.st
a6b0: 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e  atic int session
a6c0: 50 72 65 75 70 64 61 74 65 4e 65 77 28 76 6f 69  PreupdateNew(voi
a6d0: 64 20 2a 70 43 74 78 2c 20 69 6e 74 20 69 56 61  d *pCtx, int iVa
a6e0: 6c 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  l, sqlite3_value
a6f0: 20 2a 2a 70 70 56 61 6c 29 7b 0a 20 20 72 65 74   **ppVal){.  ret
a700: 75 72 6e 20 73 71 6c 69 74 65 33 5f 70 72 65 75  urn sqlite3_preu
a710: 70 64 61 74 65 5f 6e 65 77 28 28 73 71 6c 69 74  pdate_new((sqlit
a720: 65 33 2a 29 70 43 74 78 2c 20 69 56 61 6c 2c 20  e3*)pCtx, iVal, 
a730: 70 70 56 61 6c 29 3b 0a 7d 0a 73 74 61 74 69 63  ppVal);.}.static
a740: 20 69 6e 74 20 73 65 73 73 69 6f 6e 50 72 65 75   int sessionPreu
a750: 70 64 61 74 65 43 6f 75 6e 74 28 76 6f 69 64 20  pdateCount(void 
a760: 2a 70 43 74 78 29 7b 0a 20 20 72 65 74 75 72 6e  *pCtx){.  return
a770: 20 73 71 6c 69 74 65 33 5f 70 72 65 75 70 64 61   sqlite3_preupda
a780: 74 65 5f 63 6f 75 6e 74 28 28 73 71 6c 69 74 65  te_count((sqlite
a790: 33 2a 29 70 43 74 78 29 3b 0a 7d 0a 73 74 61 74  3*)pCtx);.}.stat
a7a0: 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 50 72  ic int sessionPr
a7b0: 65 75 70 64 61 74 65 44 65 70 74 68 28 76 6f 69  eupdateDepth(voi
a7c0: 64 20 2a 70 43 74 78 29 7b 0a 20 20 72 65 74 75  d *pCtx){.  retu
a7d0: 72 6e 20 73 71 6c 69 74 65 33 5f 70 72 65 75 70  rn sqlite3_preup
a7e0: 64 61 74 65 5f 64 65 70 74 68 28 28 73 71 6c 69  date_depth((sqli
a7f0: 74 65 33 2a 29 70 43 74 78 29 3b 0a 7d 0a 0a 2f  te3*)pCtx);.}../
a800: 2a 0a 2a 2a 20 49 6e 73 74 61 6c 6c 20 74 68 65  *.** Install the
a810: 20 70 72 65 2d 75 70 64 61 74 65 20 68 6f 6f 6b   pre-update hook
a820: 73 20 6f 6e 20 74 68 65 20 73 65 73 73 69 6f 6e  s on the session
a830: 20 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20 61   object passed a
a840: 73 20 74 68 65 20 6f 6e 6c 79 0a 2a 2a 20 61 72  s the only.** ar
a850: 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69  gument..*/.stati
a860: 63 20 76 6f 69 64 20 73 65 73 73 69 6f 6e 50 72  c void sessionPr
a870: 65 75 70 64 61 74 65 48 6f 6f 6b 73 28 0a 20 20  eupdateHooks(.  
a880: 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20  sqlite3_session 
a890: 2a 70 53 65 73 73 69 6f 6e 0a 29 7b 0a 20 20 70  *pSession.){.  p
a8a0: 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 70 43  Session->hook.pC
a8b0: 74 78 20 3d 20 28 76 6f 69 64 2a 29 70 53 65 73  tx = (void*)pSes
a8c0: 73 69 6f 6e 2d 3e 64 62 3b 0a 20 20 70 53 65 73  sion->db;.  pSes
a8d0: 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 4f 6c 64 20  sion->hook.xOld 
a8e0: 3d 20 73 65 73 73 69 6f 6e 50 72 65 75 70 64 61  = sessionPreupda
a8f0: 74 65 4f 6c 64 3b 0a 20 20 70 53 65 73 73 69 6f  teOld;.  pSessio
a900: 6e 2d 3e 68 6f 6f 6b 2e 78 4e 65 77 20 3d 20 73  n->hook.xNew = s
a910: 65 73 73 69 6f 6e 50 72 65 75 70 64 61 74 65 4e  essionPreupdateN
a920: 65 77 3b 0a 20 20 70 53 65 73 73 69 6f 6e 2d 3e  ew;.  pSession->
a930: 68 6f 6f 6b 2e 78 43 6f 75 6e 74 20 3d 20 73 65  hook.xCount = se
a940: 73 73 69 6f 6e 50 72 65 75 70 64 61 74 65 43 6f  ssionPreupdateCo
a950: 75 6e 74 3b 0a 20 20 70 53 65 73 73 69 6f 6e 2d  unt;.  pSession-
a960: 3e 68 6f 6f 6b 2e 78 44 65 70 74 68 20 3d 20 73  >hook.xDepth = s
a970: 65 73 73 69 6f 6e 50 72 65 75 70 64 61 74 65 44  essionPreupdateD
a980: 65 70 74 68 3b 0a 7d 0a 0a 74 79 70 65 64 65 66  epth;.}..typedef
a990: 20 73 74 72 75 63 74 20 53 65 73 73 69 6f 6e 44   struct SessionD
a9a0: 69 66 66 43 74 78 20 53 65 73 73 69 6f 6e 44 69  iffCtx SessionDi
a9b0: 66 66 43 74 78 3b 0a 73 74 72 75 63 74 20 53 65  ffCtx;.struct Se
a9c0: 73 73 69 6f 6e 44 69 66 66 43 74 78 20 7b 0a 20  ssionDiffCtx {. 
a9d0: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
a9e0: 53 74 6d 74 3b 0a 20 20 69 6e 74 20 6e 4f 6c 64  Stmt;.  int nOld
a9f0: 4f 66 66 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54  Off;.};../*.** T
aa00: 68 65 20 64 69 66 66 20 68 6f 6f 6b 20 69 6d 70  he diff hook imp
aa10: 6c 65 6d 65 6e 74 61 74 69 6f 6e 73 2e 0a 2a 2f  lementations..*/
aa20: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73  .static int sess
aa30: 69 6f 6e 44 69 66 66 4f 6c 64 28 76 6f 69 64 20  ionDiffOld(void 
aa40: 2a 70 43 74 78 2c 20 69 6e 74 20 69 56 61 6c 2c  *pCtx, int iVal,
aa50: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
aa60: 2a 70 70 56 61 6c 29 7b 0a 20 20 53 65 73 73 69  *ppVal){.  Sessi
aa70: 6f 6e 44 69 66 66 43 74 78 20 2a 70 20 3d 20 28  onDiffCtx *p = (
aa80: 53 65 73 73 69 6f 6e 44 69 66 66 43 74 78 2a 29  SessionDiffCtx*)
aa90: 70 43 74 78 3b 0a 20 20 2a 70 70 56 61 6c 20 3d  pCtx;.  *ppVal =
aaa0: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
aab0: 76 61 6c 75 65 28 70 2d 3e 70 53 74 6d 74 2c 20  value(p->pStmt, 
aac0: 69 56 61 6c 2b 70 2d 3e 6e 4f 6c 64 4f 66 66 29  iVal+p->nOldOff)
aad0: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
aae0: 45 5f 4f 4b 3b 0a 7d 0a 73 74 61 74 69 63 20 69  E_OK;.}.static i
aaf0: 6e 74 20 73 65 73 73 69 6f 6e 44 69 66 66 4e 65  nt sessionDiffNe
ab00: 77 28 76 6f 69 64 20 2a 70 43 74 78 2c 20 69 6e  w(void *pCtx, in
ab10: 74 20 69 56 61 6c 2c 20 73 71 6c 69 74 65 33 5f  t iVal, sqlite3_
ab20: 76 61 6c 75 65 20 2a 2a 70 70 56 61 6c 29 7b 0a  value **ppVal){.
ab30: 20 20 53 65 73 73 69 6f 6e 44 69 66 66 43 74 78    SessionDiffCtx
ab40: 20 2a 70 20 3d 20 28 53 65 73 73 69 6f 6e 44 69   *p = (SessionDi
ab50: 66 66 43 74 78 2a 29 70 43 74 78 3b 0a 20 20 2a  ffCtx*)pCtx;.  *
ab60: 70 70 56 61 6c 20 3d 20 73 71 6c 69 74 65 33 5f  ppVal = sqlite3_
ab70: 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 2d 3e  column_value(p->
ab80: 70 53 74 6d 74 2c 20 69 56 61 6c 29 3b 0a 20 20  pStmt, iVal);.  
ab90: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
aba0: 4b 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20  K;.}.static int 
abb0: 73 65 73 73 69 6f 6e 44 69 66 66 43 6f 75 6e 74  sessionDiffCount
abc0: 28 76 6f 69 64 20 2a 70 43 74 78 29 7b 0a 20 20  (void *pCtx){.  
abd0: 53 65 73 73 69 6f 6e 44 69 66 66 43 74 78 20 2a  SessionDiffCtx *
abe0: 70 20 3d 20 28 53 65 73 73 69 6f 6e 44 69 66 66  p = (SessionDiff
abf0: 43 74 78 2a 29 70 43 74 78 3b 0a 20 20 72 65 74  Ctx*)pCtx;.  ret
ac00: 75 72 6e 20 70 2d 3e 6e 4f 6c 64 4f 66 66 20 3f  urn p->nOldOff ?
ac10: 20 70 2d 3e 6e 4f 6c 64 4f 66 66 20 3a 20 73 71   p->nOldOff : sq
ac20: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 63 6f 75  lite3_column_cou
ac30: 6e 74 28 70 2d 3e 70 53 74 6d 74 29 3b 0a 7d 0a  nt(p->pStmt);.}.
ac40: 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69  static int sessi
ac50: 6f 6e 44 69 66 66 44 65 70 74 68 28 76 6f 69 64  onDiffDepth(void
ac60: 20 2a 70 43 74 78 29 7b 0a 20 20 72 65 74 75 72   *pCtx){.  retur
ac70: 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e  n 0;.}../*.** In
ac80: 73 74 61 6c 6c 20 74 68 65 20 64 69 66 66 20 68  stall the diff h
ac90: 6f 6f 6b 73 20 6f 6e 20 74 68 65 20 73 65 73 73  ooks on the sess
aca0: 69 6f 6e 20 6f 62 6a 65 63 74 20 70 61 73 73 65  ion object passe
acb0: 64 20 61 73 20 74 68 65 20 6f 6e 6c 79 0a 2a 2a  d as the only.**
acc0: 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74   argument..*/.st
acd0: 61 74 69 63 20 76 6f 69 64 20 73 65 73 73 69 6f  atic void sessio
ace0: 6e 44 69 66 66 48 6f 6f 6b 73 28 0a 20 20 73 71  nDiffHooks(.  sq
acf0: 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70  lite3_session *p
ad00: 53 65 73 73 69 6f 6e 2c 0a 20 20 53 65 73 73 69  Session,.  Sessi
ad10: 6f 6e 44 69 66 66 43 74 78 20 2a 70 44 69 66 66  onDiffCtx *pDiff
ad20: 43 74 78 0a 29 7b 0a 20 20 70 53 65 73 73 69 6f  Ctx.){.  pSessio
ad30: 6e 2d 3e 68 6f 6f 6b 2e 70 43 74 78 20 3d 20 28  n->hook.pCtx = (
ad40: 76 6f 69 64 2a 29 70 44 69 66 66 43 74 78 3b 0a  void*)pDiffCtx;.
ad50: 20 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b    pSession->hook
ad60: 2e 78 4f 6c 64 20 3d 20 73 65 73 73 69 6f 6e 44  .xOld = sessionD
ad70: 69 66 66 4f 6c 64 3b 0a 20 20 70 53 65 73 73 69  iffOld;.  pSessi
ad80: 6f 6e 2d 3e 68 6f 6f 6b 2e 78 4e 65 77 20 3d 20  on->hook.xNew = 
ad90: 73 65 73 73 69 6f 6e 44 69 66 66 4e 65 77 3b 0a  sessionDiffNew;.
ada0: 20 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b    pSession->hook
adb0: 2e 78 43 6f 75 6e 74 20 3d 20 73 65 73 73 69 6f  .xCount = sessio
adc0: 6e 44 69 66 66 43 6f 75 6e 74 3b 0a 20 20 70 53  nDiffCount;.  pS
add0: 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 44 65  ession->hook.xDe
ade0: 70 74 68 20 3d 20 73 65 73 73 69 6f 6e 44 69 66  pth = sessionDif
adf0: 66 44 65 70 74 68 3b 0a 7d 0a 0a 73 74 61 74 69  fDepth;.}..stati
ae00: 63 20 63 68 61 72 20 2a 73 65 73 73 69 6f 6e 45  c char *sessionE
ae10: 78 70 72 43 6f 6d 70 61 72 65 50 4b 28 0a 20 20  xprComparePK(.  
ae20: 69 6e 74 20 6e 43 6f 6c 2c 0a 20 20 63 6f 6e 73  int nCol,.  cons
ae30: 74 20 63 68 61 72 20 2a 7a 44 62 31 2c 20 63 6f  t char *zDb1, co
ae40: 6e 73 74 20 63 68 61 72 20 2a 7a 44 62 32 2c 20  nst char *zDb2, 
ae50: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
ae60: 54 61 62 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61  Tab,.  const cha
ae70: 72 20 2a 2a 61 7a 43 6f 6c 2c 20 75 38 20 2a 61  r **azCol, u8 *a
ae80: 62 50 4b 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a  bPK.){.  int i;.
ae90: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53    const char *zS
aea0: 65 70 20 3d 20 22 22 3b 0a 20 20 63 68 61 72 20  ep = "";.  char 
aeb0: 2a 7a 52 65 74 20 3d 20 30 3b 0a 0a 20 20 66 6f  *zRet = 0;..  fo
aec0: 72 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c 3b 20 69  r(i=0; i<nCol; i
aed0: 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 61 62 50  ++){.    if( abP
aee0: 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20 7a 52  K[i] ){.      zR
aef0: 65 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  et = sqlite3_mpr
af00: 69 6e 74 66 28 22 25 7a 25 73 5c 22 25 77 5c 22  intf("%z%s\"%w\"
af10: 2e 5c 22 25 77 5c 22 2e 5c 22 25 77 5c 22 3d 5c  .\"%w\".\"%w\"=\
af20: 22 25 77 5c 22 2e 5c 22 25 77 5c 22 2e 5c 22 25  "%w\".\"%w\".\"%
af30: 77 5c 22 22 2c 0a 20 20 20 20 20 20 20 20 20 20  w\"",.          
af40: 7a 52 65 74 2c 20 7a 53 65 70 2c 20 7a 44 62 31  zRet, zSep, zDb1
af50: 2c 20 7a 54 61 62 2c 20 61 7a 43 6f 6c 5b 69 5d  , zTab, azCol[i]
af60: 2c 20 7a 44 62 32 2c 20 7a 54 61 62 2c 20 61 7a  , zDb2, zTab, az
af70: 43 6f 6c 5b 69 5d 0a 20 20 20 20 20 20 29 3b 0a  Col[i].      );.
af80: 20 20 20 20 20 20 7a 53 65 70 20 3d 20 22 20 41        zSep = " A
af90: 4e 44 20 22 3b 0a 20 20 20 20 20 20 69 66 28 20  ND ";.      if( 
afa0: 7a 52 65 74 3d 3d 30 20 29 20 62 72 65 61 6b 3b  zRet==0 ) break;
afb0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
afc0: 74 75 72 6e 20 7a 52 65 74 3b 0a 7d 0a 0a 73 74  turn zRet;.}..st
afd0: 61 74 69 63 20 63 68 61 72 20 2a 73 65 73 73 69  atic char *sessi
afe0: 6f 6e 45 78 70 72 43 6f 6d 70 61 72 65 4f 74 68  onExprCompareOth
aff0: 65 72 28 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c 0a  er(.  int nCol,.
b000: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44    const char *zD
b010: 62 31 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  b1, const char *
b020: 7a 44 62 32 2c 20 0a 20 20 63 6f 6e 73 74 20 63  zDb2, .  const c
b030: 68 61 72 20 2a 7a 54 61 62 2c 0a 20 20 63 6f 6e  har *zTab,.  con
b040: 73 74 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6c 2c  st char **azCol,
b050: 20 75 38 20 2a 61 62 50 4b 0a 29 7b 0a 20 20 69   u8 *abPK.){.  i
b060: 6e 74 20 69 3b 0a 20 20 63 6f 6e 73 74 20 63 68  nt i;.  const ch
b070: 61 72 20 2a 7a 53 65 70 20 3d 20 22 22 3b 0a 20  ar *zSep = "";. 
b080: 20 63 68 61 72 20 2a 7a 52 65 74 20 3d 20 30 3b   char *zRet = 0;
b090: 0a 20 20 69 6e 74 20 62 48 61 76 65 20 3d 20 30  .  int bHave = 0
b0a0: 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  ;..  for(i=0; i<
b0b0: 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  nCol; i++){.    
b0c0: 69 66 28 20 61 62 50 4b 5b 69 5d 3d 3d 30 20 29  if( abPK[i]==0 )
b0d0: 7b 0a 20 20 20 20 20 20 62 48 61 76 65 20 3d 20  {.      bHave = 
b0e0: 31 3b 0a 20 20 20 20 20 20 7a 52 65 74 20 3d 20  1;.      zRet = 
b0f0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
b100: 0a 20 20 20 20 20 20 20 20 20 20 22 25 7a 25 73  .          "%z%s
b110: 5c 22 25 77 5c 22 2e 5c 22 25 77 5c 22 2e 5c 22  \"%w\".\"%w\".\"
b120: 25 77 5c 22 20 49 53 20 4e 4f 54 20 5c 22 25 77  %w\" IS NOT \"%w
b130: 5c 22 2e 5c 22 25 77 5c 22 2e 5c 22 25 77 5c 22  \".\"%w\".\"%w\"
b140: 22 2c 0a 20 20 20 20 20 20 20 20 20 20 7a 52 65  ",.          zRe
b150: 74 2c 20 7a 53 65 70 2c 20 7a 44 62 31 2c 20 7a  t, zSep, zDb1, z
b160: 54 61 62 2c 20 61 7a 43 6f 6c 5b 69 5d 2c 20 7a  Tab, azCol[i], z
b170: 44 62 32 2c 20 7a 54 61 62 2c 20 61 7a 43 6f 6c  Db2, zTab, azCol
b180: 5b 69 5d 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  [i].      );.   
b190: 20 20 20 7a 53 65 70 20 3d 20 22 20 4f 52 20 22     zSep = " OR "
b1a0: 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 52 65 74  ;.      if( zRet
b1b0: 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  ==0 ) break;.   
b1c0: 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 62 48   }.  }..  if( bH
b1d0: 61 76 65 3d 3d 30 20 29 7b 0a 20 20 20 20 61 73  ave==0 ){.    as
b1e0: 73 65 72 74 28 20 7a 52 65 74 3d 3d 30 20 29 3b  sert( zRet==0 );
b1f0: 0a 20 20 20 20 7a 52 65 74 20 3d 20 73 71 6c 69  .    zRet = sqli
b200: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 30 22 29  te3_mprintf("0")
b210: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
b220: 7a 52 65 74 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  zRet;.}..static 
b230: 63 68 61 72 20 2a 73 65 73 73 69 6f 6e 53 65 6c  char *sessionSel
b240: 65 63 74 46 69 6e 64 4e 65 77 28 0a 20 20 69 6e  ectFindNew(.  in
b250: 74 20 6e 43 6f 6c 2c 0a 20 20 63 6f 6e 73 74 20  t nCol,.  const 
b260: 63 68 61 72 20 2a 7a 44 62 31 2c 20 20 20 20 20  char *zDb1,     
b270: 20 2f 2a 20 50 69 63 6b 20 72 6f 77 73 20 69 6e   /* Pick rows in
b280: 20 74 68 69 73 20 64 62 20 6f 6e 6c 79 20 2a 2f   this db only */
b290: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
b2a0: 44 62 32 2c 20 20 20 20 20 20 2f 2a 20 42 75 74  Db2,      /* But
b2b0: 20 6e 6f 74 20 69 6e 20 74 68 69 73 20 6f 6e 65   not in this one
b2c0: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
b2d0: 20 2a 7a 54 62 6c 2c 20 20 20 20 20 20 2f 2a 20   *zTbl,      /* 
b2e0: 54 61 62 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20 20  Table name */.  
b2f0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45 78 70  const char *zExp
b300: 72 0a 29 7b 0a 20 20 63 68 61 72 20 2a 7a 52 65  r.){.  char *zRe
b310: 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  t = sqlite3_mpri
b320: 6e 74 66 28 0a 20 20 20 20 20 20 22 53 45 4c 45  ntf(.      "SELE
b330: 43 54 20 2a 20 46 52 4f 4d 20 5c 22 25 77 5c 22  CT * FROM \"%w\"
b340: 2e 5c 22 25 77 5c 22 20 57 48 45 52 45 20 4e 4f  .\"%w\" WHERE NO
b350: 54 20 45 58 49 53 54 53 20 28 22 0a 20 20 20 20  T EXISTS (".    
b360: 20 20 22 20 20 53 45 4c 45 43 54 20 31 20 46 52    "  SELECT 1 FR
b370: 4f 4d 20 5c 22 25 77 5c 22 2e 5c 22 25 77 5c 22  OM \"%w\".\"%w\"
b380: 20 57 48 45 52 45 20 25 73 22 0a 20 20 20 20 20   WHERE %s".     
b390: 20 22 29 22 2c 0a 20 20 20 20 20 20 7a 44 62 31   ")",.      zDb1
b3a0: 2c 20 7a 54 62 6c 2c 20 7a 44 62 32 2c 20 7a 54  , zTbl, zDb2, zT
b3b0: 62 6c 2c 20 7a 45 78 70 72 0a 20 20 29 3b 0a 20  bl, zExpr.  );. 
b3c0: 20 72 65 74 75 72 6e 20 7a 52 65 74 3b 0a 7d 0a   return zRet;.}.
b3d0: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73  .static int sess
b3e0: 69 6f 6e 44 69 66 66 46 69 6e 64 4e 65 77 28 0a  ionDiffFindNew(.
b3f0: 20 20 69 6e 74 20 6f 70 2c 0a 20 20 73 71 6c 69    int op,.  sqli
b400: 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65  te3_session *pSe
b410: 73 73 69 6f 6e 2c 0a 20 20 53 65 73 73 69 6f 6e  ssion,.  Session
b420: 54 61 62 6c 65 20 2a 70 54 61 62 2c 0a 20 20 63  Table *pTab,.  c
b430: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62 31 2c  onst char *zDb1,
b440: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
b450: 44 62 32 2c 0a 20 20 63 68 61 72 20 2a 7a 45 78  Db2,.  char *zEx
b460: 70 72 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  pr.){.  int rc =
b470: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 63 68   SQLITE_OK;.  ch
b480: 61 72 20 2a 7a 53 74 6d 74 20 3d 20 73 65 73 73  ar *zStmt = sess
b490: 69 6f 6e 53 65 6c 65 63 74 46 69 6e 64 4e 65 77  ionSelectFindNew
b4a0: 28 70 54 61 62 2d 3e 6e 43 6f 6c 2c 20 7a 44 62  (pTab->nCol, zDb
b4b0: 31 2c 20 7a 44 62 32 2c 20 70 54 61 62 2d 3e 7a  1, zDb2, pTab->z
b4c0: 4e 61 6d 65 2c 7a 45 78 70 72 29 3b 0a 0a 20 20  Name,zExpr);..  
b4d0: 69 66 28 20 7a 53 74 6d 74 3d 3d 30 20 29 7b 0a  if( zStmt==0 ){.
b4e0: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
b4f0: 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a  NOMEM;.  }else{.
b500: 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74      sqlite3_stmt
b510: 20 2a 70 53 74 6d 74 3b 0a 20 20 20 20 72 63 20   *pStmt;.    rc 
b520: 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72  = sqlite3_prepar
b530: 65 28 70 53 65 73 73 69 6f 6e 2d 3e 64 62 2c 20  e(pSession->db, 
b540: 7a 53 74 6d 74 2c 20 2d 31 2c 20 26 70 53 74 6d  zStmt, -1, &pStm
b550: 74 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 72  t, 0);.    if( r
b560: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
b570: 20 20 20 20 20 20 53 65 73 73 69 6f 6e 44 69 66        SessionDif
b580: 66 43 74 78 20 2a 70 44 69 66 66 43 74 78 20 3d  fCtx *pDiffCtx =
b590: 20 28 53 65 73 73 69 6f 6e 44 69 66 66 43 74 78   (SessionDiffCtx
b5a0: 2a 29 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b  *)pSession->hook
b5b0: 2e 70 43 74 78 3b 0a 20 20 20 20 20 20 70 44 69  .pCtx;.      pDi
b5c0: 66 66 43 74 78 2d 3e 70 53 74 6d 74 20 3d 20 70  ffCtx->pStmt = p
b5d0: 53 74 6d 74 3b 0a 20 20 20 20 20 20 70 44 69 66  Stmt;.      pDif
b5e0: 66 43 74 78 2d 3e 6e 4f 6c 64 4f 66 66 20 3d 20  fCtx->nOldOff = 
b5f0: 30 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20  0;.      while( 
b600: 53 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69  SQLITE_ROW==sqli
b610: 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 20  te3_step(pStmt) 
b620: 29 7b 0a 20 20 20 20 20 20 20 20 73 65 73 73 69  ){.        sessi
b630: 6f 6e 50 72 65 75 70 64 61 74 65 4f 6e 65 43 68  onPreupdateOneCh
b640: 61 6e 67 65 28 6f 70 2c 20 70 53 65 73 73 69 6f  ange(op, pSessio
b650: 6e 2c 20 70 54 61 62 29 3b 0a 20 20 20 20 20 20  n, pTab);.      
b660: 7d 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  }.      rc = sql
b670: 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53  ite3_finalize(pS
b680: 74 6d 74 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  tmt);.    }.    
b690: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53 74  sqlite3_free(zSt
b6a0: 6d 74 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  mt);.  }..  retu
b6b0: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
b6c0: 20 69 6e 74 20 73 65 73 73 69 6f 6e 44 69 66 66   int sessionDiff
b6d0: 46 69 6e 64 4d 6f 64 69 66 69 65 64 28 0a 20 20  FindModified(.  
b6e0: 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20  sqlite3_session 
b6f0: 2a 70 53 65 73 73 69 6f 6e 2c 20 0a 20 20 53 65  *pSession, .  Se
b700: 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62  ssionTable *pTab
b710: 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  , .  const char 
b720: 2a 7a 46 72 6f 6d 2c 20 0a 20 20 63 6f 6e 73 74  *zFrom, .  const
b730: 20 63 68 61 72 20 2a 7a 45 78 70 72 0a 29 7b 0a   char *zExpr.){.
b740: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
b750: 45 5f 4f 4b 3b 0a 0a 20 20 63 68 61 72 20 2a 7a  E_OK;..  char *z
b760: 45 78 70 72 32 20 3d 20 73 65 73 73 69 6f 6e 45  Expr2 = sessionE
b770: 78 70 72 43 6f 6d 70 61 72 65 4f 74 68 65 72 28  xprCompareOther(
b780: 70 54 61 62 2d 3e 6e 43 6f 6c 2c 0a 20 20 20 20  pTab->nCol,.    
b790: 20 20 70 53 65 73 73 69 6f 6e 2d 3e 7a 44 62 2c    pSession->zDb,
b7a0: 20 7a 46 72 6f 6d 2c 20 70 54 61 62 2d 3e 7a 4e   zFrom, pTab->zN
b7b0: 61 6d 65 2c 20 70 54 61 62 2d 3e 61 7a 43 6f 6c  ame, pTab->azCol
b7c0: 2c 20 70 54 61 62 2d 3e 61 62 50 4b 0a 20 20 29  , pTab->abPK.  )
b7d0: 3b 0a 20 20 69 66 28 20 7a 45 78 70 72 32 3d 3d  ;.  if( zExpr2==
b7e0: 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  0 ){.    rc = SQ
b7f0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65  LITE_NOMEM;.  }e
b800: 6c 73 65 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a  lse{.    char *z
b810: 53 74 6d 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d  Stmt = sqlite3_m
b820: 70 72 69 6e 74 66 28 0a 20 20 20 20 20 20 20 20  printf(.        
b830: 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 5c  "SELECT * FROM \
b840: 22 25 77 5c 22 2e 5c 22 25 77 5c 22 2c 20 5c 22  "%w\".\"%w\", \"
b850: 25 77 5c 22 2e 5c 22 25 77 5c 22 20 57 48 45 52  %w\".\"%w\" WHER
b860: 45 20 25 73 20 41 4e 44 20 28 25 7a 29 22 2c 0a  E %s AND (%z)",.
b870: 20 20 20 20 20 20 20 20 70 53 65 73 73 69 6f 6e          pSession
b880: 2d 3e 7a 44 62 2c 20 70 54 61 62 2d 3e 7a 4e 61  ->zDb, pTab->zNa
b890: 6d 65 2c 20 7a 46 72 6f 6d 2c 20 70 54 61 62 2d  me, zFrom, pTab-
b8a0: 3e 7a 4e 61 6d 65 2c 20 7a 45 78 70 72 2c 20 7a  >zName, zExpr, z
b8b0: 45 78 70 72 32 0a 20 20 20 20 29 3b 0a 20 20 20  Expr2.    );.   
b8c0: 20 69 66 28 20 7a 53 74 6d 74 3d 3d 30 20 29 7b   if( zStmt==0 ){
b8d0: 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
b8e0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65  TE_NOMEM;.    }e
b8f0: 6c 73 65 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  lse{.      sqlit
b900: 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a  e3_stmt *pStmt;.
b910: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
b920: 65 33 5f 70 72 65 70 61 72 65 28 70 53 65 73 73  e3_prepare(pSess
b930: 69 6f 6e 2d 3e 64 62 2c 20 7a 53 74 6d 74 2c 20  ion->db, zStmt, 
b940: 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a  -1, &pStmt, 0);.
b950: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
b960: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
b970: 20 20 20 20 53 65 73 73 69 6f 6e 44 69 66 66 43      SessionDiffC
b980: 74 78 20 2a 70 44 69 66 66 43 74 78 20 3d 20 28  tx *pDiffCtx = (
b990: 53 65 73 73 69 6f 6e 44 69 66 66 43 74 78 2a 29  SessionDiffCtx*)
b9a0: 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 70  pSession->hook.p
b9b0: 43 74 78 3b 0a 20 20 20 20 20 20 20 20 70 44 69  Ctx;.        pDi
b9c0: 66 66 43 74 78 2d 3e 70 53 74 6d 74 20 3d 20 70  ffCtx->pStmt = p
b9d0: 53 74 6d 74 3b 0a 20 20 20 20 20 20 20 20 70 44  Stmt;.        pD
b9e0: 69 66 66 43 74 78 2d 3e 6e 4f 6c 64 4f 66 66 20  iffCtx->nOldOff 
b9f0: 3d 20 70 54 61 62 2d 3e 6e 43 6f 6c 3b 0a 20 20  = pTab->nCol;.  
ba00: 20 20 20 20 20 20 77 68 69 6c 65 28 20 53 51 4c        while( SQL
ba10: 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33  ITE_ROW==sqlite3
ba20: 5f 73 74 65 70 28 70 53 74 6d 74 29 20 29 7b 0a  _step(pStmt) ){.
ba30: 20 20 20 20 20 20 20 20 20 20 73 65 73 73 69 6f            sessio
ba40: 6e 50 72 65 75 70 64 61 74 65 4f 6e 65 43 68 61  nPreupdateOneCha
ba50: 6e 67 65 28 53 51 4c 49 54 45 5f 55 50 44 41 54  nge(SQLITE_UPDAT
ba60: 45 2c 20 70 53 65 73 73 69 6f 6e 2c 20 70 54 61  E, pSession, pTa
ba70: 62 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  b);.        }.  
ba80: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
ba90: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d  e3_finalize(pStm
baa0: 74 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  t);.      }.    
bab0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
bac0: 53 74 6d 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  Stmt);.    }.  }
bad0: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
bae0: 0a 0a 69 6e 74 20 73 71 6c 69 74 65 33 73 65 73  ..int sqlite3ses
baf0: 73 69 6f 6e 5f 64 69 66 66 28 0a 20 20 73 71 6c  sion_diff(.  sql
bb00: 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53  ite3_session *pS
bb10: 65 73 73 69 6f 6e 2c 0a 20 20 63 6f 6e 73 74 20  ession,.  const 
bb20: 63 68 61 72 20 2a 7a 46 72 6f 6d 2c 0a 20 20 63  char *zFrom,.  c
bb30: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 62 6c 2c  onst char *zTbl,
bb40: 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 4d  .  char **pzErrM
bb50: 73 67 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68  sg.){.  const ch
bb60: 61 72 20 2a 7a 44 62 20 3d 20 70 53 65 73 73 69  ar *zDb = pSessi
bb70: 6f 6e 2d 3e 7a 44 62 3b 0a 20 20 69 6e 74 20 72  on->zDb;.  int r
bb80: 63 20 3d 20 70 53 65 73 73 69 6f 6e 2d 3e 72 63  c = pSession->rc
bb90: 3b 0a 20 20 53 65 73 73 69 6f 6e 44 69 66 66 43  ;.  SessionDiffC
bba0: 74 78 20 64 3b 0a 0a 20 20 6d 65 6d 73 65 74 28  tx d;..  memset(
bbb0: 26 64 2c 20 30 2c 20 73 69 7a 65 6f 66 28 64 29  &d, 0, sizeof(d)
bbc0: 29 3b 0a 20 20 73 65 73 73 69 6f 6e 44 69 66 66  );.  sessionDiff
bbd0: 48 6f 6f 6b 73 28 70 53 65 73 73 69 6f 6e 2c 20  Hooks(pSession, 
bbe0: 26 64 29 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f  &d);..  sqlite3_
bbf0: 6d 75 74 65 78 5f 65 6e 74 65 72 28 73 71 6c 69  mutex_enter(sqli
bc00: 74 65 33 5f 64 62 5f 6d 75 74 65 78 28 70 53 65  te3_db_mutex(pSe
bc10: 73 73 69 6f 6e 2d 3e 64 62 29 29 3b 0a 20 20 69  ssion->db));.  i
bc20: 66 28 20 70 7a 45 72 72 4d 73 67 20 29 20 2a 70  f( pzErrMsg ) *p
bc30: 7a 45 72 72 4d 73 67 20 3d 20 30 3b 0a 20 20 69  zErrMsg = 0;.  i
bc40: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
bc50: 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 45   ){.    char *zE
bc60: 78 70 72 20 3d 20 30 3b 0a 20 20 20 20 73 71 6c  xpr = 0;.    sql
bc70: 69 74 65 33 20 2a 64 62 20 3d 20 70 53 65 73 73  ite3 *db = pSess
bc80: 69 6f 6e 2d 3e 64 62 3b 0a 20 20 20 20 53 65 73  ion->db;.    Ses
bc90: 73 69 6f 6e 54 61 62 6c 65 20 2a 70 54 6f 3b 20  sionTable *pTo; 
bca0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61             /* Ta
bcb0: 62 6c 65 20 7a 54 62 6c 20 2a 2f 0a 0a 20 20 20  ble zTbl */..   
bcc0: 20 2f 2a 20 4c 6f 63 61 74 65 20 61 6e 64 20 69   /* Locate and i
bcd0: 66 20 6e 65 63 65 73 73 61 72 79 20 69 6e 69 74  f necessary init
bce0: 69 61 6c 69 7a 65 20 74 68 65 20 74 61 72 67 65  ialize the targe
bcf0: 74 20 74 61 62 6c 65 20 6f 62 6a 65 63 74 20 2a  t table object *
bd00: 2f 0a 20 20 20 20 72 63 20 3d 20 73 65 73 73 69  /.    rc = sessi
bd10: 6f 6e 46 69 6e 64 54 61 62 6c 65 28 70 53 65 73  onFindTable(pSes
bd20: 73 69 6f 6e 2c 20 7a 54 62 6c 2c 20 26 70 54 6f  sion, zTbl, &pTo
bd30: 29 3b 0a 20 20 20 20 69 66 28 20 70 54 6f 3d 3d  );.    if( pTo==
bd40: 30 20 29 20 67 6f 74 6f 20 64 69 66 66 5f 6f 75  0 ) goto diff_ou
bd50: 74 3b 0a 20 20 20 20 69 66 28 20 73 65 73 73 69  t;.    if( sessi
bd60: 6f 6e 49 6e 69 74 54 61 62 6c 65 28 70 53 65 73  onInitTable(pSes
bd70: 73 69 6f 6e 2c 20 70 54 6f 29 20 29 7b 0a 20 20  sion, pTo) ){.  
bd80: 20 20 20 20 72 63 20 3d 20 70 53 65 73 73 69 6f      rc = pSessio
bd90: 6e 2d 3e 72 63 3b 0a 20 20 20 20 20 20 67 6f 74  n->rc;.      got
bda0: 6f 20 64 69 66 66 5f 6f 75 74 3b 0a 20 20 20 20  o diff_out;.    
bdb0: 7d 0a 0a 20 20 20 20 2f 2a 20 43 68 65 63 6b 20  }..    /* Check 
bdc0: 74 68 65 20 74 61 62 6c 65 20 73 63 68 65 6d 61  the table schema
bdd0: 73 20 6d 61 74 63 68 20 2a 2f 0a 20 20 20 20 69  s match */.    i
bde0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
bdf0: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 62 48   ){.      int bH
be00: 61 73 50 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20  asPk = 0;.      
be10: 69 6e 74 20 62 4d 69 73 6d 61 74 63 68 20 3d 20  int bMismatch = 
be20: 30 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 43 6f  0;.      int nCo
be30: 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l;              
be40: 20 20 20 20 20 2f 2a 20 43 6f 6c 75 6d 6e 73 20       /* Columns 
be50: 69 6e 20 7a 46 72 6f 6d 2e 7a 54 62 6c 20 2a 2f  in zFrom.zTbl */
be60: 0a 20 20 20 20 20 20 75 38 20 2a 61 62 50 4b 3b  .      u8 *abPK;
be70: 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61  .      const cha
be80: 72 20 2a 2a 61 7a 43 6f 6c 20 3d 20 30 3b 0a 20  r **azCol = 0;. 
be90: 20 20 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f       rc = sessio
bea0: 6e 54 61 62 6c 65 49 6e 66 6f 28 64 62 2c 20 7a  nTableInfo(db, z
beb0: 46 72 6f 6d 2c 20 7a 54 62 6c 2c 20 26 6e 43 6f  From, zTbl, &nCo
bec0: 6c 2c 20 30 2c 20 26 61 7a 43 6f 6c 2c 20 26 61  l, 0, &azCol, &a
bed0: 62 50 4b 29 3b 0a 20 20 20 20 20 20 69 66 28 20  bPK);.      if( 
bee0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
bef0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 54 6f  .        if( pTo
bf00: 2d 3e 6e 43 6f 6c 21 3d 6e 43 6f 6c 20 29 7b 0a  ->nCol!=nCol ){.
bf10: 20 20 20 20 20 20 20 20 20 20 62 4d 69 73 6d 61            bMisma
bf20: 74 63 68 20 3d 20 31 3b 0a 20 20 20 20 20 20 20  tch = 1;.       
bf30: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
bf40: 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 20    int i;.       
bf50: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43     for(i=0; i<nC
bf60: 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  ol; i++){.      
bf70: 20 20 20 20 20 20 69 66 28 20 70 54 6f 2d 3e 61        if( pTo->a
bf80: 62 50 4b 5b 69 5d 21 3d 61 62 50 4b 5b 69 5d 20  bPK[i]!=abPK[i] 
bf90: 29 20 62 4d 69 73 6d 61 74 63 68 20 3d 20 31 3b  ) bMismatch = 1;
bfa0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28  .            if(
bfb0: 20 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d 70   sqlite3_stricmp
bfc0: 28 61 7a 43 6f 6c 5b 69 5d 2c 20 70 54 6f 2d 3e  (azCol[i], pTo->
bfd0: 61 7a 43 6f 6c 5b 69 5d 29 20 29 20 62 4d 69 73  azCol[i]) ) bMis
bfe0: 6d 61 74 63 68 20 3d 20 31 3b 0a 20 20 20 20 20  match = 1;.     
bff0: 20 20 20 20 20 20 20 69 66 28 20 61 62 50 4b 5b         if( abPK[
c000: 69 5d 20 29 20 62 48 61 73 50 6b 20 3d 20 31 3b  i] ) bHasPk = 1;
c010: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
c020: 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 7d 0a       }..      }.
c030: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
c040: 65 65 28 28 63 68 61 72 2a 29 61 7a 43 6f 6c 29  ee((char*)azCol)
c050: 3b 0a 20 20 20 20 20 20 69 66 28 20 62 4d 69 73  ;.      if( bMis
c060: 6d 61 74 63 68 20 29 7b 0a 20 20 20 20 20 20 20  match ){.       
c070: 20 2a 70 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c   *pzErrMsg = sql
c080: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 74 61  ite3_mprintf("ta
c090: 62 6c 65 20 73 63 68 65 6d 61 73 20 64 6f 20 6e  ble schemas do n
c0a0: 6f 74 20 6d 61 74 63 68 22 29 3b 0a 20 20 20 20  ot match");.    
c0b0: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
c0c0: 53 43 48 45 4d 41 3b 0a 20 20 20 20 20 20 7d 0a  SCHEMA;.      }.
c0d0: 20 20 20 20 20 20 69 66 28 20 62 48 61 73 50 6b        if( bHasPk
c0e0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 2f  ==0 ){.        /
c0f0: 2a 20 49 67 6e 6f 72 65 20 74 61 62 6c 65 73 20  * Ignore tables 
c100: 77 69 74 68 20 6e 6f 20 70 72 69 6d 61 72 79 20  with no primary 
c110: 6b 65 79 73 20 2a 2f 0a 20 20 20 20 20 20 20 20  keys */.        
c120: 67 6f 74 6f 20 64 69 66 66 5f 6f 75 74 3b 0a 20  goto diff_out;. 
c130: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
c140: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
c150: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 7a 45 78  _OK ){.      zEx
c160: 70 72 20 3d 20 73 65 73 73 69 6f 6e 45 78 70 72  pr = sessionExpr
c170: 43 6f 6d 70 61 72 65 50 4b 28 70 54 6f 2d 3e 6e  ComparePK(pTo->n
c180: 43 6f 6c 2c 20 0a 20 20 20 20 20 20 20 20 20 20  Col, .          
c190: 7a 44 62 2c 20 7a 46 72 6f 6d 2c 20 70 54 6f 2d  zDb, zFrom, pTo-
c1a0: 3e 7a 4e 61 6d 65 2c 20 70 54 6f 2d 3e 61 7a 43  >zName, pTo->azC
c1b0: 6f 6c 2c 20 70 54 6f 2d 3e 61 62 50 4b 0a 20 20  ol, pTo->abPK.  
c1c0: 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 0a 20 20      );.    }..  
c1d0: 20 20 2f 2a 20 46 69 6e 64 20 6e 65 77 20 72 6f    /* Find new ro
c1e0: 77 73 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63  ws */.    if( rc
c1f0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
c200: 20 20 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f       rc = sessio
c210: 6e 44 69 66 66 46 69 6e 64 4e 65 77 28 53 51 4c  nDiffFindNew(SQL
c220: 49 54 45 5f 49 4e 53 45 52 54 2c 20 70 53 65 73  ITE_INSERT, pSes
c230: 73 69 6f 6e 2c 20 70 54 6f 2c 20 7a 44 62 2c 20  sion, pTo, zDb, 
c240: 7a 46 72 6f 6d 2c 20 7a 45 78 70 72 29 3b 0a 20  zFrom, zExpr);. 
c250: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 46 69 6e     }..    /* Fin
c260: 64 20 6f 6c 64 20 72 6f 77 73 20 2a 2f 0a 20 20  d old rows */.  
c270: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
c280: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20  _OK ){.      rc 
c290: 3d 20 73 65 73 73 69 6f 6e 44 69 66 66 46 69 6e  = sessionDiffFin
c2a0: 64 4e 65 77 28 53 51 4c 49 54 45 5f 44 45 4c 45  dNew(SQLITE_DELE
c2b0: 54 45 2c 20 70 53 65 73 73 69 6f 6e 2c 20 70 54  TE, pSession, pT
c2c0: 6f 2c 20 7a 46 72 6f 6d 2c 20 7a 44 62 2c 20 7a  o, zFrom, zDb, z
c2d0: 45 78 70 72 29 3b 0a 20 20 20 20 7d 0a 0a 20 20  Expr);.    }..  
c2e0: 20 20 2f 2a 20 46 69 6e 64 20 6d 6f 64 69 66 69    /* Find modifi
c2f0: 65 64 20 72 6f 77 73 20 2a 2f 0a 20 20 20 20 69  ed rows */.    i
c300: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
c310: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73   ){.      rc = s
c320: 65 73 73 69 6f 6e 44 69 66 66 46 69 6e 64 4d 6f  essionDiffFindMo
c330: 64 69 66 69 65 64 28 70 53 65 73 73 69 6f 6e 2c  dified(pSession,
c340: 20 70 54 6f 2c 20 7a 46 72 6f 6d 2c 20 7a 45 78   pTo, zFrom, zEx
c350: 70 72 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  pr);.    }..    
c360: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 45 78  sqlite3_free(zEx
c370: 70 72 29 3b 0a 20 20 7d 0a 0a 20 64 69 66 66 5f  pr);.  }.. diff_
c380: 6f 75 74 3a 0a 20 20 73 65 73 73 69 6f 6e 50 72  out:.  sessionPr
c390: 65 75 70 64 61 74 65 48 6f 6f 6b 73 28 70 53 65  eupdateHooks(pSe
c3a0: 73 73 69 6f 6e 29 3b 0a 20 20 73 71 6c 69 74 65  ssion);.  sqlite
c3b0: 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 73 71  3_mutex_leave(sq
c3c0: 6c 69 74 65 33 5f 64 62 5f 6d 75 74 65 78 28 70  lite3_db_mutex(p
c3d0: 53 65 73 73 69 6f 6e 2d 3e 64 62 29 29 3b 0a 20  Session->db));. 
c3e0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
c3f0: 2a 0a 2a 2a 20 43 72 65 61 74 65 20 61 20 73 65  *.** Create a se
c400: 73 73 69 6f 6e 20 6f 62 6a 65 63 74 2e 20 54 68  ssion object. Th
c410: 69 73 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63  is session objec
c420: 74 20 77 69 6c 6c 20 72 65 63 6f 72 64 20 63 68  t will record ch
c430: 61 6e 67 65 73 20 74 6f 0a 2a 2a 20 64 61 74 61  anges to.** data
c440: 62 61 73 65 20 7a 44 62 20 61 74 74 61 63 68 65  base zDb attache
c450: 64 20 74 6f 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  d to connection 
c460: 64 62 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  db..*/.int sqlit
c470: 65 33 73 65 73 73 69 6f 6e 5f 63 72 65 61 74 65  e3session_create
c480: 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
c490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c4a0: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
c4b0: 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73  handle */.  cons
c4c0: 74 20 63 68 61 72 20 2a 7a 44 62 2c 20 20 20 20  t char *zDb,    
c4d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
c4e0: 61 6d 65 20 6f 66 20 64 62 20 28 65 2e 67 2e 20  ame of db (e.g. 
c4f0: 22 6d 61 69 6e 22 29 20 2a 2f 0a 20 20 73 71 6c  "main") */.  sql
c500: 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 2a 70  ite3_session **p
c510: 70 53 65 73 73 69 6f 6e 20 20 20 20 20 2f 2a 20  pSession     /* 
c520: 4f 55 54 3a 20 4e 65 77 20 73 65 73 73 69 6f 6e  OUT: New session
c530: 20 6f 62 6a 65 63 74 20 2a 2f 0a 29 7b 0a 20 20   object */.){.  
c540: 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20  sqlite3_session 
c550: 2a 70 4e 65 77 3b 20 20 20 20 20 20 20 20 20 20  *pNew;          
c560: 2f 2a 20 4e 65 77 6c 79 20 61 6c 6c 6f 63 61 74  /* Newly allocat
c570: 65 64 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63  ed session objec
c580: 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73  t */.  sqlite3_s
c590: 65 73 73 69 6f 6e 20 2a 70 4f 6c 64 3b 20 20 20  ession *pOld;   
c5a0: 20 20 20 20 20 20 20 2f 2a 20 53 65 73 73 69 6f         /* Sessio
c5b0: 6e 20 6f 62 6a 65 63 74 20 61 6c 72 65 61 64 79  n object already
c5c0: 20 61 74 74 61 63 68 65 64 20 74 6f 20 64 62 20   attached to db 
c5d0: 2a 2f 0a 20 20 69 6e 74 20 6e 44 62 20 3d 20 73  */.  int nDb = s
c5e0: 71 6c 69 74 65 33 53 74 72 6c 65 6e 33 30 28 7a  qlite3Strlen30(z
c5f0: 44 62 29 3b 20 2f 2a 20 4c 65 6e 67 74 68 20 6f  Db); /* Length o
c600: 66 20 7a 44 62 20 69 6e 20 62 79 74 65 73 20 2a  f zDb in bytes *
c610: 2f 0a 0a 20 20 2f 2a 20 5a 65 72 6f 20 74 68 65  /..  /* Zero the
c620: 20 6f 75 74 70 75 74 20 76 61 6c 75 65 20 69 6e   output value in
c630: 20 63 61 73 65 20 61 6e 20 65 72 72 6f 72 20 6f   case an error o
c640: 63 63 75 72 73 2e 20 2a 2f 0a 20 20 2a 70 70 53  ccurs. */.  *ppS
c650: 65 73 73 69 6f 6e 20 3d 20 30 3b 0a 0a 20 20 2f  ession = 0;..  /
c660: 2a 20 41 6c 6c 6f 63 61 74 65 20 61 6e 64 20 70  * Allocate and p
c670: 6f 70 75 6c 61 74 65 20 74 68 65 20 6e 65 77 20  opulate the new 
c680: 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 2e 20  session object. 
c690: 2a 2f 0a 20 20 70 4e 65 77 20 3d 20 28 73 71 6c  */.  pNew = (sql
c6a0: 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 29 73  ite3_session *)s
c6b0: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69  qlite3_malloc(si
c6c0: 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f 73 65 73  zeof(sqlite3_ses
c6d0: 73 69 6f 6e 29 20 2b 20 6e 44 62 20 2b 20 31 29  sion) + nDb + 1)
c6e0: 3b 0a 20 20 69 66 28 20 21 70 4e 65 77 20 29 20  ;.  if( !pNew ) 
c6f0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
c700: 4d 45 4d 3b 0a 20 20 6d 65 6d 73 65 74 28 70 4e  MEM;.  memset(pN
c710: 65 77 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73 71  ew, 0, sizeof(sq
c720: 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 29 29 3b  lite3_session));
c730: 0a 20 20 70 4e 65 77 2d 3e 64 62 20 3d 20 64 62  .  pNew->db = db
c740: 3b 0a 20 20 70 4e 65 77 2d 3e 7a 44 62 20 3d 20  ;.  pNew->zDb = 
c750: 28 63 68 61 72 20 2a 29 26 70 4e 65 77 5b 31 5d  (char *)&pNew[1]
c760: 3b 0a 20 20 70 4e 65 77 2d 3e 62 45 6e 61 62 6c  ;.  pNew->bEnabl
c770: 65 20 3d 20 31 3b 0a 20 20 6d 65 6d 63 70 79 28  e = 1;.  memcpy(
c780: 70 4e 65 77 2d 3e 7a 44 62 2c 20 7a 44 62 2c 20  pNew->zDb, zDb, 
c790: 6e 44 62 2b 31 29 3b 0a 20 20 73 65 73 73 69 6f  nDb+1);.  sessio
c7a0: 6e 50 72 65 75 70 64 61 74 65 48 6f 6f 6b 73 28  nPreupdateHooks(
c7b0: 70 4e 65 77 29 3b 0a 0a 20 20 2f 2a 20 41 64 64  pNew);..  /* Add
c7c0: 20 74 68 65 20 6e 65 77 20 73 65 73 73 69 6f 6e   the new session
c7d0: 20 6f 62 6a 65 63 74 20 74 6f 20 74 68 65 20 6c   object to the l
c7e0: 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20 73 65  inked list of se
c7f0: 73 73 69 6f 6e 20 6f 62 6a 65 63 74 73 20 0a 20  ssion objects . 
c800: 20 2a 2a 20 61 74 74 61 63 68 65 64 20 74 6f 20   ** attached to 
c810: 64 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20  database handle 
c820: 24 64 62 2e 20 44 6f 20 74 68 69 73 20 75 6e 64  $db. Do this und
c830: 65 72 20 74 68 65 20 63 6f 76 65 72 20 6f 66 20  er the cover of 
c840: 74 68 65 20 64 62 0a 20 20 2a 2a 20 68 61 6e 64  the db.  ** hand
c850: 6c 65 20 6d 75 74 65 78 2e 20 20 2a 2f 0a 20 20  le mutex.  */.  
c860: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e  sqlite3_mutex_en
c870: 74 65 72 28 73 71 6c 69 74 65 33 5f 64 62 5f 6d  ter(sqlite3_db_m
c880: 75 74 65 78 28 64 62 29 29 3b 0a 20 20 70 4f 6c  utex(db));.  pOl
c890: 64 20 3d 20 28 73 71 6c 69 74 65 33 5f 73 65 73  d = (sqlite3_ses
c8a0: 73 69 6f 6e 2a 29 73 71 6c 69 74 65 33 5f 70 72  sion*)sqlite3_pr
c8b0: 65 75 70 64 61 74 65 5f 68 6f 6f 6b 28 64 62 2c  eupdate_hook(db,
c8c0: 20 78 50 72 65 55 70 64 61 74 65 2c 20 28 76 6f   xPreUpdate, (vo
c8d0: 69 64 2a 29 70 4e 65 77 29 3b 0a 20 20 70 4e 65  id*)pNew);.  pNe
c8e0: 77 2d 3e 70 4e 65 78 74 20 3d 20 70 4f 6c 64 3b  w->pNext = pOld;
c8f0: 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  .  sqlite3_mutex
c900: 5f 6c 65 61 76 65 28 73 71 6c 69 74 65 33 5f 64  _leave(sqlite3_d
c910: 62 5f 6d 75 74 65 78 28 64 62 29 29 3b 0a 0a 20  b_mutex(db));.. 
c920: 20 2a 70 70 53 65 73 73 69 6f 6e 20 3d 20 70 4e   *ppSession = pN
c930: 65 77 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  ew;.  return SQL
c940: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
c950: 20 46 72 65 65 20 74 68 65 20 6c 69 73 74 20 6f   Free the list o
c960: 66 20 74 61 62 6c 65 20 6f 62 6a 65 63 74 73 20  f table objects 
c970: 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69  passed as the fi
c980: 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 20 54 68  rst argument. Th
c990: 65 20 63 6f 6e 74 65 6e 74 73 0a 2a 2a 20 6f 66  e contents.** of
c9a0: 20 74 68 65 20 63 68 61 6e 67 65 64 2d 72 6f 77   the changed-row
c9b0: 73 20 68 61 73 68 20 74 61 62 6c 65 73 20 61 72  s hash tables ar
c9c0: 65 20 61 6c 73 6f 20 64 65 6c 65 74 65 64 2e 0a  e also deleted..
c9d0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73  */.static void s
c9e0: 65 73 73 69 6f 6e 44 65 6c 65 74 65 54 61 62 6c  essionDeleteTabl
c9f0: 65 28 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a  e(SessionTable *
ca00: 70 4c 69 73 74 29 7b 0a 20 20 53 65 73 73 69 6f  pList){.  Sessio
ca10: 6e 54 61 62 6c 65 20 2a 70 4e 65 78 74 3b 0a 20  nTable *pNext;. 
ca20: 20 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70   SessionTable *p
ca30: 54 61 62 3b 0a 0a 20 20 66 6f 72 28 70 54 61 62  Tab;..  for(pTab
ca40: 3d 70 4c 69 73 74 3b 20 70 54 61 62 3b 20 70 54  =pList; pTab; pT
ca50: 61 62 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 69  ab=pNext){.    i
ca60: 6e 74 20 69 3b 0a 20 20 20 20 70 4e 65 78 74 20  nt i;.    pNext 
ca70: 3d 20 70 54 61 62 2d 3e 70 4e 65 78 74 3b 0a 20  = pTab->pNext;. 
ca80: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54     for(i=0; i<pT
ca90: 61 62 2d 3e 6e 43 68 61 6e 67 65 3b 20 69 2b 2b  ab->nChange; i++
caa0: 29 7b 0a 20 20 20 20 20 20 53 65 73 73 69 6f 6e  ){.      Session
cab0: 43 68 61 6e 67 65 20 2a 70 3b 0a 20 20 20 20 20  Change *p;.     
cac0: 20 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a   SessionChange *
cad0: 70 4e 65 78 74 43 68 61 6e 67 65 3b 0a 20 20 20  pNextChange;.   
cae0: 20 20 20 66 6f 72 28 70 3d 70 54 61 62 2d 3e 61     for(p=pTab->a
caf0: 70 43 68 61 6e 67 65 5b 69 5d 3b 20 70 3b 20 70  pChange[i]; p; p
cb00: 3d 70 4e 65 78 74 43 68 61 6e 67 65 29 7b 0a 20  =pNextChange){. 
cb10: 20 20 20 20 20 20 20 70 4e 65 78 74 43 68 61 6e         pNextChan
cb20: 67 65 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20  ge = p->pNext;. 
cb30: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66         sqlite3_f
cb40: 72 65 65 28 70 29 3b 0a 20 20 20 20 20 20 7d 0a  ree(p);.      }.
cb50: 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65      }.    sqlite
cb60: 33 5f 66 72 65 65 28 28 63 68 61 72 2a 29 70 54  3_free((char*)pT
cb70: 61 62 2d 3e 61 7a 43 6f 6c 29 3b 20 20 2f 2a 20  ab->azCol);  /* 
cb80: 63 61 73 74 20 77 6f 72 6b 73 20 61 72 6f 75 6e  cast works aroun
cb90: 64 20 56 43 2b 2b 20 62 75 67 20 2a 2f 0a 20 20  d VC++ bug */.  
cba0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
cbb0: 54 61 62 2d 3e 61 70 43 68 61 6e 67 65 29 3b 0a  Tab->apChange);.
cbc0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
cbd0: 28 70 54 61 62 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  (pTab);.  }.}../
cbe0: 2a 0a 2a 2a 20 44 65 6c 65 74 65 20 61 20 73 65  *.** Delete a se
cbf0: 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 70 72 65  ssion object pre
cc00: 76 69 6f 75 73 6c 79 20 61 6c 6c 6f 63 61 74 65  viously allocate
cc10: 64 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 73  d using sqlite3s
cc20: 65 73 73 69 6f 6e 5f 63 72 65 61 74 65 28 29 2e  ession_create().
cc30: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
cc40: 73 65 73 73 69 6f 6e 5f 64 65 6c 65 74 65 28 73  session_delete(s
cc50: 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a  qlite3_session *
cc60: 70 53 65 73 73 69 6f 6e 29 7b 0a 20 20 73 71 6c  pSession){.  sql
cc70: 69 74 65 33 20 2a 64 62 20 3d 20 70 53 65 73 73  ite3 *db = pSess
cc80: 69 6f 6e 2d 3e 64 62 3b 0a 20 20 73 71 6c 69 74  ion->db;.  sqlit
cc90: 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 48 65 61  e3_session *pHea
cca0: 64 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 65 73  d;.  sqlite3_ses
ccb0: 73 69 6f 6e 20 2a 2a 70 70 3b 0a 0a 20 20 2f 2a  sion **pp;..  /*
ccc0: 20 55 6e 6c 69 6e 6b 20 74 68 65 20 73 65 73 73   Unlink the sess
ccd0: 69 6f 6e 20 66 72 6f 6d 20 74 68 65 20 6c 69 6e  ion from the lin
cce0: 6b 65 64 20 6c 69 73 74 20 6f 66 20 73 65 73 73  ked list of sess
ccf0: 69 6f 6e 73 20 61 74 74 61 63 68 65 64 20 74 6f  ions attached to
cd00: 20 74 68 65 0a 20 20 2a 2a 20 64 61 74 61 62 61   the.  ** databa
cd10: 73 65 20 68 61 6e 64 6c 65 2e 20 48 6f 6c 64 20  se handle. Hold 
cd20: 74 68 65 20 64 62 20 6d 75 74 65 78 20 77 68 69  the db mutex whi
cd30: 6c 65 20 64 6f 69 6e 67 20 73 6f 2e 20 20 2a 2f  le doing so.  */
cd40: 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  .  sqlite3_mutex
cd50: 5f 65 6e 74 65 72 28 73 71 6c 69 74 65 33 5f 64  _enter(sqlite3_d
cd60: 62 5f 6d 75 74 65 78 28 64 62 29 29 3b 0a 20 20  b_mutex(db));.  
cd70: 70 48 65 61 64 20 3d 20 28 73 71 6c 69 74 65 33  pHead = (sqlite3
cd80: 5f 73 65 73 73 69 6f 6e 2a 29 73 71 6c 69 74 65  _session*)sqlite
cd90: 33 5f 70 72 65 75 70 64 61 74 65 5f 68 6f 6f 6b  3_preupdate_hook
cda0: 28 64 62 2c 20 30 2c 20 30 29 3b 0a 20 20 66 6f  (db, 0, 0);.  fo
cdb0: 72 28 70 70 3d 26 70 48 65 61 64 3b 20 41 4c 57  r(pp=&pHead; ALW
cdc0: 41 59 53 28 28 2a 70 70 29 21 3d 30 29 3b 20 70  AYS((*pp)!=0); p
cdd0: 70 3d 26 28 28 2a 70 70 29 2d 3e 70 4e 65 78 74  p=&((*pp)->pNext
cde0: 29 29 7b 0a 20 20 20 20 69 66 28 20 28 2a 70 70  )){.    if( (*pp
cdf0: 29 3d 3d 70 53 65 73 73 69 6f 6e 20 29 7b 0a 20  )==pSession ){. 
ce00: 20 20 20 20 20 2a 70 70 20 3d 20 28 2a 70 70 29       *pp = (*pp)
ce10: 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 69  ->pNext;.      i
ce20: 66 28 20 70 48 65 61 64 20 29 20 73 71 6c 69 74  f( pHead ) sqlit
ce30: 65 33 5f 70 72 65 75 70 64 61 74 65 5f 68 6f 6f  e3_preupdate_hoo
ce40: 6b 28 64 62 2c 20 78 50 72 65 55 70 64 61 74 65  k(db, xPreUpdate
ce50: 2c 20 28 76 6f 69 64 2a 29 70 48 65 61 64 29 3b  , (void*)pHead);
ce60: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
ce70: 20 20 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65    }.  }.  sqlite
ce80: 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 73 71  3_mutex_leave(sq
ce90: 6c 69 74 65 33 5f 64 62 5f 6d 75 74 65 78 28 64  lite3_db_mutex(d
cea0: 62 29 29 3b 0a 0a 20 20 2f 2a 20 44 65 6c 65 74  b));..  /* Delet
ceb0: 65 20 61 6c 6c 20 61 74 74 61 63 68 65 64 20 74  e all attached t
cec0: 61 62 6c 65 20 6f 62 6a 65 63 74 73 2e 20 41 6e  able objects. An
ced0: 64 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  d the contents o
cee0: 66 20 74 68 65 69 72 20 0a 20 20 2a 2a 20 61 73  f their .  ** as
cef0: 73 6f 63 69 61 74 65 64 20 68 61 73 68 2d 74 61  sociated hash-ta
cf00: 62 6c 65 73 2e 20 2a 2f 0a 20 20 73 65 73 73 69  bles. */.  sessi
cf10: 6f 6e 44 65 6c 65 74 65 54 61 62 6c 65 28 70 53  onDeleteTable(pS
cf20: 65 73 73 69 6f 6e 2d 3e 70 54 61 62 6c 65 29 3b  ession->pTable);
cf30: 0a 0a 20 20 2f 2a 20 46 72 65 65 20 74 68 65 20  ..  /* Free the 
cf40: 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 69  session object i
cf50: 74 73 65 6c 66 2e 20 2a 2f 0a 20 20 73 71 6c 69  tself. */.  sqli
cf60: 74 65 33 5f 66 72 65 65 28 70 53 65 73 73 69 6f  te3_free(pSessio
cf70: 6e 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74  n);.}../*.** Set
cf80: 20 61 20 74 61 62 6c 65 20 66 69 6c 74 65 72 20   a table filter 
cf90: 6f 6e 20 61 20 53 65 73 73 69 6f 6e 20 4f 62 6a  on a Session Obj
cfa0: 65 63 74 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  ect..*/.void sql
cfb0: 69 74 65 33 73 65 73 73 69 6f 6e 5f 74 61 62 6c  ite3session_tabl
cfc0: 65 5f 66 69 6c 74 65 72 28 0a 20 20 73 71 6c 69  e_filter(.  sqli
cfd0: 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65  te3_session *pSe
cfe0: 73 73 69 6f 6e 2c 20 0a 20 20 69 6e 74 28 2a 78  ssion, .  int(*x
cff0: 46 69 6c 74 65 72 29 28 76 6f 69 64 2a 2c 20 63  Filter)(void*, c
d000: 6f 6e 73 74 20 63 68 61 72 2a 29 2c 0a 20 20 76  onst char*),.  v
d010: 6f 69 64 20 2a 70 43 74 78 20 20 20 20 20 20 20  oid *pCtx       
d020: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
d030: 2a 20 46 69 72 73 74 20 61 72 67 75 6d 65 6e 74  * First argument
d040: 20 70 61 73 73 65 64 20 74 6f 20 78 46 69 6c 74   passed to xFilt
d050: 65 72 20 2a 2f 0a 29 7b 0a 20 20 70 53 65 73 73  er */.){.  pSess
d060: 69 6f 6e 2d 3e 62 41 75 74 6f 41 74 74 61 63 68  ion->bAutoAttach
d070: 20 3d 20 31 3b 0a 20 20 70 53 65 73 73 69 6f 6e   = 1;.  pSession
d080: 2d 3e 70 46 69 6c 74 65 72 43 74 78 20 3d 20 70  ->pFilterCtx = p
d090: 43 74 78 3b 0a 20 20 70 53 65 73 73 69 6f 6e 2d  Ctx;.  pSession-
d0a0: 3e 78 54 61 62 6c 65 46 69 6c 74 65 72 20 3d 20  >xTableFilter = 
d0b0: 78 46 69 6c 74 65 72 3b 0a 7d 0a 0a 2f 2a 0a 2a  xFilter;.}../*.*
d0c0: 2a 20 41 74 74 61 63 68 20 61 20 74 61 62 6c 65  * Attach a table
d0d0: 20 74 6f 20 61 20 73 65 73 73 69 6f 6e 2e 20 41   to a session. A
d0e0: 6c 6c 20 73 75 62 73 65 71 75 65 6e 74 20 63 68  ll subsequent ch
d0f0: 61 6e 67 65 73 20 6d 61 64 65 20 74 6f 20 74 68  anges made to th
d100: 65 20 74 61 62 6c 65 0a 2a 2a 20 77 68 69 6c 65  e table.** while
d110: 20 74 68 65 20 73 65 73 73 69 6f 6e 20 6f 62 6a   the session obj
d120: 65 63 74 20 69 73 20 65 6e 61 62 6c 65 64 20 77  ect is enabled w
d130: 69 6c 6c 20 62 65 20 72 65 63 6f 72 64 65 64 2e  ill be recorded.
d140: 0a 2a 2a 0a 2a 2a 20 4f 6e 6c 79 20 74 61 62 6c  .**.** Only tabl
d150: 65 73 20 74 68 61 74 20 68 61 76 65 20 61 20 50  es that have a P
d160: 52 49 4d 41 52 59 20 4b 45 59 20 64 65 66 69 6e  RIMARY KEY defin
d170: 65 64 20 6d 61 79 20 62 65 20 61 74 74 61 63 68  ed may be attach
d180: 65 64 2e 20 49 74 20 64 6f 65 73 0a 2a 2a 20 6e  ed. It does.** n
d190: 6f 74 20 6d 61 74 74 65 72 20 69 66 20 74 68 65  ot matter if the
d1a0: 20 50 52 49 4d 41 52 59 20 4b 45 59 20 69 73 20   PRIMARY KEY is 
d1b0: 61 6e 20 22 49 4e 54 45 47 45 52 20 50 52 49 4d  an "INTEGER PRIM
d1c0: 41 52 59 20 4b 45 59 22 20 28 72 6f 77 69 64 20  ARY KEY" (rowid 
d1d0: 61 6c 69 61 73 29 0a 2a 2a 20 6f 72 20 6e 6f 74  alias).** or not
d1e0: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
d1f0: 73 65 73 73 69 6f 6e 5f 61 74 74 61 63 68 28 0a  session_attach(.
d200: 20 20 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f    sqlite3_sessio
d210: 6e 20 2a 70 53 65 73 73 69 6f 6e 2c 20 20 20 20  n *pSession,    
d220: 20 20 2f 2a 20 53 65 73 73 69 6f 6e 20 6f 62 6a    /* Session obj
d230: 65 63 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  ect */.  const c
d240: 68 61 72 20 2a 7a 4e 61 6d 65 20 20 20 20 20 20  har *zName      
d250: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62 6c           /* Tabl
d260: 65 20 6e 61 6d 65 20 2a 2f 0a 29 7b 0a 20 20 69  e name */.){.  i
d270: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
d280: 4b 3b 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74  K;.  sqlite3_mut
d290: 65 78 5f 65 6e 74 65 72 28 73 71 6c 69 74 65 33  ex_enter(sqlite3
d2a0: 5f 64 62 5f 6d 75 74 65 78 28 70 53 65 73 73 69  _db_mutex(pSessi
d2b0: 6f 6e 2d 3e 64 62 29 29 3b 0a 0a 20 20 69 66 28  on->db));..  if(
d2c0: 20 21 7a 4e 61 6d 65 20 29 7b 0a 20 20 20 20 70   !zName ){.    p
d2d0: 53 65 73 73 69 6f 6e 2d 3e 62 41 75 74 6f 41 74  Session->bAutoAt
d2e0: 74 61 63 68 20 3d 20 31 3b 0a 20 20 7d 65 6c 73  tach = 1;.  }els
d2f0: 65 7b 0a 20 20 20 20 53 65 73 73 69 6f 6e 54 61  e{.    SessionTa
d300: 62 6c 65 20 2a 70 54 61 62 3b 20 20 20 20 20 20  ble *pTab;      
d310: 20 20 20 20 20 2f 2a 20 4e 65 77 20 74 61 62 6c       /* New tabl
d320: 65 20 6f 62 6a 65 63 74 20 28 69 66 20 72 65 71  e object (if req
d330: 75 69 72 65 64 29 20 2a 2f 0a 20 20 20 20 69 6e  uired) */.    in
d340: 74 20 6e 4e 61 6d 65 3b 20 20 20 20 20 20 20 20  t nName;        
d350: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
d360: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69  umber of bytes i
d370: 6e 20 73 74 72 69 6e 67 20 7a 4e 61 6d 65 20 2a  n string zName *
d380: 2f 0a 0a 20 20 20 20 2f 2a 20 46 69 72 73 74 20  /..    /* First 
d390: 73 65 61 72 63 68 20 66 6f 72 20 61 6e 20 65 78  search for an ex
d3a0: 69 73 74 69 6e 67 20 65 6e 74 72 79 2e 20 49 66  isting entry. If
d3b0: 20 6f 6e 65 20 69 73 20 66 6f 75 6e 64 2c 20 74   one is found, t
d3c0: 68 69 73 20 63 61 6c 6c 20 69 73 0a 20 20 20 20  his call is.    
d3d0: 2a 2a 20 61 20 6e 6f 2d 6f 70 2e 20 52 65 74 75  ** a no-op. Retu
d3e0: 72 6e 20 65 61 72 6c 79 2e 20 2a 2f 0a 20 20 20  rn early. */.   
d3f0: 20 6e 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33   nName = sqlite3
d400: 53 74 72 6c 65 6e 33 30 28 7a 4e 61 6d 65 29 3b  Strlen30(zName);
d410: 0a 20 20 20 20 66 6f 72 28 70 54 61 62 3d 70 53  .    for(pTab=pS
d420: 65 73 73 69 6f 6e 2d 3e 70 54 61 62 6c 65 3b 20  ession->pTable; 
d430: 70 54 61 62 3b 20 70 54 61 62 3d 70 54 61 62 2d  pTab; pTab=pTab-
d440: 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 69  >pNext){.      i
d450: 66 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74  f( 0==sqlite3_st
d460: 72 6e 69 63 6d 70 28 70 54 61 62 2d 3e 7a 4e 61  rnicmp(pTab->zNa
d470: 6d 65 2c 20 7a 4e 61 6d 65 2c 20 6e 4e 61 6d 65  me, zName, nName
d480: 2b 31 29 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  +1) ) break;.   
d490: 20 7d 0a 0a 20 20 20 20 69 66 28 20 21 70 54 61   }..    if( !pTa
d4a0: 62 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 41 6c  b ){.      /* Al
d4b0: 6c 6f 63 61 74 65 20 6e 65 77 20 53 65 73 73 69  locate new Sessi
d4c0: 6f 6e 54 61 62 6c 65 20 6f 62 6a 65 63 74 2e 20  onTable object. 
d4d0: 2a 2f 0a 20 20 20 20 20 20 70 54 61 62 20 3d 20  */.      pTab = 
d4e0: 28 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 29  (SessionTable *)
d4f0: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73  sqlite3_malloc(s
d500: 69 7a 65 6f 66 28 53 65 73 73 69 6f 6e 54 61 62  izeof(SessionTab
d510: 6c 65 29 20 2b 20 6e 4e 61 6d 65 20 2b 20 31 29  le) + nName + 1)
d520: 3b 0a 20 20 20 20 20 20 69 66 28 20 21 70 54 61  ;.      if( !pTa
d530: 62 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  b ){.        rc 
d540: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
d550: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
d560: 20 20 20 20 20 2f 2a 20 50 6f 70 75 6c 61 74 65       /* Populate
d570: 20 74 68 65 20 6e 65 77 20 53 65 73 73 69 6f 6e   the new Session
d580: 54 61 62 6c 65 20 6f 62 6a 65 63 74 20 61 6e 64  Table object and
d590: 20 6c 69 6e 6b 20 69 74 20 69 6e 74 6f 20 74 68   link it into th
d5a0: 65 20 6c 69 73 74 2e 0a 20 20 20 20 20 20 20 20  e list..        
d5b0: 2a 2a 20 54 68 65 20 6e 65 77 20 6f 62 6a 65 63  ** The new objec
d5c0: 74 20 6d 75 73 74 20 62 65 20 6c 69 6e 6b 65 64  t must be linked
d5d0: 20 6f 6e 74 6f 20 74 68 65 20 65 6e 64 20 6f 66   onto the end of
d5e0: 20 74 68 65 20 6c 69 73 74 2c 20 6e 6f 74 20 0a   the list, not .
d5f0: 20 20 20 20 20 20 20 20 2a 2a 20 73 69 6d 70 6c          ** simpl
d600: 79 20 61 64 64 65 64 20 74 6f 20 74 68 65 20 73  y added to the s
d610: 74 61 72 74 20 6f 66 20 69 74 20 69 6e 20 6f 72  tart of it in or
d620: 64 65 72 20 74 6f 20 65 6e 73 75 72 65 20 74 68  der to ensure th
d630: 61 74 20 74 61 62 6c 65 73 0a 20 20 20 20 20 20  at tables.      
d640: 20 20 2a 2a 20 61 70 70 65 61 72 20 69 6e 20 74    ** appear in t
d650: 68 65 20 63 6f 72 72 65 63 74 20 6f 72 64 65 72  he correct order
d660: 20 77 68 65 6e 20 61 20 63 68 61 6e 67 65 73 65   when a changese
d670: 74 20 6f 72 20 70 61 74 63 68 73 65 74 20 69 73  t or patchset is
d680: 0a 20 20 20 20 20 20 20 20 2a 2a 20 65 76 65 6e  .        ** even
d690: 74 75 61 6c 6c 79 20 67 65 6e 65 72 61 74 65 64  tually generated
d6a0: 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20 53 65 73  . */.        Ses
d6b0: 73 69 6f 6e 54 61 62 6c 65 20 2a 2a 70 70 54 61  sionTable **ppTa
d6c0: 62 3b 0a 20 20 20 20 20 20 20 20 6d 65 6d 73 65  b;.        memse
d6d0: 74 28 70 54 61 62 2c 20 30 2c 20 73 69 7a 65 6f  t(pTab, 0, sizeo
d6e0: 66 28 53 65 73 73 69 6f 6e 54 61 62 6c 65 29 29  f(SessionTable))
d6f0: 3b 0a 20 20 20 20 20 20 20 20 70 54 61 62 2d 3e  ;.        pTab->
d700: 7a 4e 61 6d 65 20 3d 20 28 63 68 61 72 20 2a 29  zName = (char *)
d710: 26 70 54 61 62 5b 31 5d 3b 0a 20 20 20 20 20 20  &pTab[1];.      
d720: 20 20 6d 65 6d 63 70 79 28 70 54 61 62 2d 3e 7a    memcpy(pTab->z
d730: 4e 61 6d 65 2c 20 7a 4e 61 6d 65 2c 20 6e 4e 61  Name, zName, nNa
d740: 6d 65 2b 31 29 3b 0a 20 20 20 20 20 20 20 20 66  me+1);.        f
d750: 6f 72 28 70 70 54 61 62 3d 26 70 53 65 73 73 69  or(ppTab=&pSessi
d760: 6f 6e 2d 3e 70 54 61 62 6c 65 3b 20 2a 70 70 54  on->pTable; *ppT
d770: 61 62 3b 20 70 70 54 61 62 3d 26 28 2a 70 70 54  ab; ppTab=&(*ppT
d780: 61 62 29 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 20  ab)->pNext);.   
d790: 20 20 20 20 20 2a 70 70 54 61 62 20 3d 20 70 54       *ppTab = pT
d7a0: 61 62 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ab;.      }.    
d7b0: 7d 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33  }.  }..  sqlite3
d7c0: 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 73 71 6c  _mutex_leave(sql
d7d0: 69 74 65 33 5f 64 62 5f 6d 75 74 65 78 28 70 53  ite3_db_mutex(pS
d7e0: 65 73 73 69 6f 6e 2d 3e 64 62 29 29 3b 0a 20 20  ession->db));.  
d7f0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
d800: 0a 2a 2a 20 45 6e 73 75 72 65 20 74 68 61 74 20  .** Ensure that 
d810: 74 68 65 72 65 20 69 73 20 72 6f 6f 6d 20 69 6e  there is room in
d820: 20 74 68 65 20 62 75 66 66 65 72 20 74 6f 20 61   the buffer to a
d830: 70 70 65 6e 64 20 6e 42 79 74 65 20 62 79 74 65  ppend nByte byte
d840: 73 20 6f 66 20 64 61 74 61 2e 0a 2a 2a 20 49 66  s of data..** If
d850: 20 6e 6f 74 2c 20 75 73 65 20 73 71 6c 69 74 65   not, use sqlite
d860: 33 5f 72 65 61 6c 6c 6f 63 28 29 20 74 6f 20 67  3_realloc() to g
d870: 72 6f 77 20 74 68 65 20 62 75 66 66 65 72 20 73  row the buffer s
d880: 6f 20 74 68 61 74 20 74 68 65 72 65 20 69 73 2e  o that there is.
d890: 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65 73  .**.** If succes
d8a0: 73 66 75 6c 2c 20 72 65 74 75 72 6e 20 7a 65 72  sful, return zer
d8b0: 6f 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66  o. Otherwise, if
d8c0: 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74 69 6f   an OOM conditio
d8d0: 6e 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65 64  n is encountered
d8e0: 2c 0a 2a 2a 20 73 65 74 20 2a 70 52 63 20 74 6f  ,.** set *pRc to
d8f0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 61 6e   SQLITE_NOMEM an
d900: 64 20 72 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72  d return non-zer
d910: 6f 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  o..*/.static int
d920: 20 73 65 73 73 69 6f 6e 42 75 66 66 65 72 47 72   sessionBufferGr
d930: 6f 77 28 53 65 73 73 69 6f 6e 42 75 66 66 65 72  ow(SessionBuffer
d940: 20 2a 70 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20   *p, int nByte, 
d950: 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 69 66 28  int *pRc){.  if(
d960: 20 2a 70 52 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b   *pRc==SQLITE_OK
d970: 20 26 26 20 70 2d 3e 6e 41 6c 6c 6f 63 2d 70 2d   && p->nAlloc-p-
d980: 3e 6e 42 75 66 3c 6e 42 79 74 65 20 29 7b 0a 20  >nBuf<nByte ){. 
d990: 20 20 20 75 38 20 2a 61 4e 65 77 3b 0a 20 20 20     u8 *aNew;.   
d9a0: 20 69 6e 74 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e   int nNew = p->n
d9b0: 41 6c 6c 6f 63 20 3f 20 70 2d 3e 6e 41 6c 6c 6f  Alloc ? p->nAllo
d9c0: 63 20 3a 20 31 32 38 3b 0a 20 20 20 20 64 6f 20  c : 128;.    do 
d9d0: 7b 0a 20 20 20 20 20 20 6e 4e 65 77 20 3d 20 6e  {.      nNew = n
d9e0: 4e 65 77 2a 32 3b 0a 20 20 20 20 7d 77 68 69 6c  New*2;.    }whil
d9f0: 65 28 20 6e 4e 65 77 3c 28 70 2d 3e 6e 42 75 66  e( nNew<(p->nBuf
da00: 2b 6e 42 79 74 65 29 20 29 3b 0a 0a 20 20 20 20  +nByte) );..    
da10: 61 4e 65 77 20 3d 20 28 75 38 20 2a 29 73 71 6c  aNew = (u8 *)sql
da20: 69 74 65 33 5f 72 65 61 6c 6c 6f 63 28 70 2d 3e  ite3_realloc(p->
da30: 61 42 75 66 2c 20 6e 4e 65 77 29 3b 0a 20 20 20  aBuf, nNew);.   
da40: 20 69 66 28 20 30 3d 3d 61 4e 65 77 20 29 7b 0a   if( 0==aNew ){.
da50: 20 20 20 20 20 20 2a 70 52 63 20 3d 20 53 51 4c        *pRc = SQL
da60: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d  ITE_NOMEM;.    }
da70: 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 2d 3e 61  else{.      p->a
da80: 42 75 66 20 3d 20 61 4e 65 77 3b 0a 20 20 20 20  Buf = aNew;.    
da90: 20 20 70 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 6e 4e    p->nAlloc = nN
daa0: 65 77 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  ew;.    }.  }.  
dab0: 72 65 74 75 72 6e 20 28 2a 70 52 63 21 3d 53 51  return (*pRc!=SQ
dac0: 4c 49 54 45 5f 4f 4b 29 3b 0a 7d 0a 0a 2f 2a 0a  LITE_OK);.}../*.
dad0: 2a 2a 20 41 70 70 65 6e 64 20 74 68 65 20 76 61  ** Append the va
dae0: 6c 75 65 20 70 61 73 73 65 64 20 61 73 20 74 68  lue passed as th
daf0: 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e  e second argumen
db00: 74 20 74 6f 20 74 68 65 20 62 75 66 66 65 72 20  t to the buffer 
db10: 70 61 73 73 65 64 0a 2a 2a 20 61 73 20 74 68 65  passed.** as the
db20: 20 66 69 72 73 74 2e 0a 2a 2a 0a 2a 2a 20 54 68   first..**.** Th
db30: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 61  is function is a
db40: 20 6e 6f 2d 6f 70 20 69 66 20 2a 70 52 63 20 69   no-op if *pRc i
db50: 73 20 6e 6f 6e 2d 7a 65 72 6f 20 77 68 65 6e 20  s non-zero when 
db60: 69 74 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2a  it is called..**
db70: 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20 61   Otherwise, if a
db80: 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20  n error occurs, 
db90: 2a 70 52 63 20 69 73 20 73 65 74 20 74 6f 20 61  *pRc is set to a
dba0: 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  n SQLite error c
dbb0: 6f 64 65 0a 2a 2a 20 62 65 66 6f 72 65 20 72 65  ode.** before re
dbc0: 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74  turning..*/.stat
dbd0: 69 63 20 76 6f 69 64 20 73 65 73 73 69 6f 6e 41  ic void sessionA
dbe0: 70 70 65 6e 64 56 61 6c 75 65 28 53 65 73 73 69  ppendValue(Sessi
dbf0: 6f 6e 42 75 66 66 65 72 20 2a 70 2c 20 73 71 6c  onBuffer *p, sql
dc00: 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c  ite3_value *pVal
dc10: 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 69  , int *pRc){.  i
dc20: 6e 74 20 72 63 20 3d 20 2a 70 52 63 3b 0a 20 20  nt rc = *pRc;.  
dc30: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
dc40: 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79  K ){.    int nBy
dc50: 74 65 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d  te = 0;.    rc =
dc60: 20 73 65 73 73 69 6f 6e 53 65 72 69 61 6c 69 7a   sessionSerializ
dc70: 65 56 61 6c 75 65 28 30 2c 20 70 56 61 6c 2c 20  eValue(0, pVal, 
dc80: 26 6e 42 79 74 65 29 3b 0a 20 20 20 20 73 65 73  &nByte);.    ses
dc90: 73 69 6f 6e 42 75 66 66 65 72 47 72 6f 77 28 70  sionBufferGrow(p
dca0: 2c 20 6e 42 79 74 65 2c 20 26 72 63 29 3b 0a 20  , nByte, &rc);. 
dcb0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
dcc0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63  E_OK ){.      rc
dcd0: 20 3d 20 73 65 73 73 69 6f 6e 53 65 72 69 61 6c   = sessionSerial
dce0: 69 7a 65 56 61 6c 75 65 28 26 70 2d 3e 61 42 75  izeValue(&p->aBu
dcf0: 66 5b 70 2d 3e 6e 42 75 66 5d 2c 20 70 56 61 6c  f[p->nBuf], pVal
dd00: 2c 20 30 29 3b 0a 20 20 20 20 20 20 70 2d 3e 6e  , 0);.      p->n
dd10: 42 75 66 20 2b 3d 20 6e 42 79 74 65 3b 0a 20 20  Buf += nByte;.  
dd20: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2a    }else{.      *
dd30: 70 52 63 20 3d 20 72 63 3b 0a 20 20 20 20 7d 0a  pRc = rc;.    }.
dd40: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69    }.}../*.** Thi
dd50: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20  s function is a 
dd60: 6e 6f 2d 6f 70 20 69 66 20 2a 70 52 63 20 69 73  no-op if *pRc is
dd70: 20 6f 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49   other than SQLI
dd80: 54 45 5f 4f 4b 20 77 68 65 6e 20 69 74 20 69 73  TE_OK when it is
dd90: 20 0a 2a 2a 20 63 61 6c 6c 65 64 2e 20 4f 74 68   .** called. Oth
dda0: 65 72 77 69 73 65 2c 20 61 70 70 65 6e 64 20 61  erwise, append a
ddb0: 20 73 69 6e 67 6c 65 20 62 79 74 65 20 74 6f 20   single byte to 
ddc0: 74 68 65 20 62 75 66 66 65 72 2e 20 0a 2a 2a 0a  the buffer. .**.
ddd0: 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e  ** If an OOM con
dde0: 64 69 74 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e  dition is encoun
ddf0: 74 65 72 65 64 2c 20 73 65 74 20 2a 70 52 63 20  tered, set *pRc 
de00: 74 6f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20  to SQLITE_NOMEM 
de10: 62 65 66 6f 72 65 0a 2a 2a 20 72 65 74 75 72 6e  before.** return
de20: 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ing..*/.static v
de30: 6f 69 64 20 73 65 73 73 69 6f 6e 41 70 70 65 6e  oid sessionAppen
de40: 64 42 79 74 65 28 53 65 73 73 69 6f 6e 42 75 66  dByte(SessionBuf
de50: 66 65 72 20 2a 70 2c 20 75 38 20 76 2c 20 69 6e  fer *p, u8 v, in
de60: 74 20 2a 70 52 63 29 7b 0a 20 20 69 66 28 20 30  t *pRc){.  if( 0
de70: 3d 3d 73 65 73 73 69 6f 6e 42 75 66 66 65 72 47  ==sessionBufferG
de80: 72 6f 77 28 70 2c 20 31 2c 20 70 52 63 29 20 29  row(p, 1, pRc) )
de90: 7b 0a 20 20 20 20 70 2d 3e 61 42 75 66 5b 70 2d  {.    p->aBuf[p-
dea0: 3e 6e 42 75 66 2b 2b 5d 20 3d 20 76 3b 0a 20 20  >nBuf++] = v;.  
deb0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  }.}../*.** This 
dec0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f  function is a no
ded0: 2d 6f 70 20 69 66 20 2a 70 52 63 20 69 73 20 6f  -op if *pRc is o
dee0: 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45  ther than SQLITE
def0: 5f 4f 4b 20 77 68 65 6e 20 69 74 20 69 73 20 0a  _OK when it is .
df00: 2a 2a 20 63 61 6c 6c 65 64 2e 20 4f 74 68 65 72  ** called. Other
df10: 77 69 73 65 2c 20 61 70 70 65 6e 64 20 61 20 73  wise, append a s
df20: 69 6e 67 6c 65 20 76 61 72 69 6e 74 20 74 6f 20  ingle varint to 
df30: 74 68 65 20 62 75 66 66 65 72 2e 20 0a 2a 2a 0a  the buffer. .**.
df40: 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e  ** If an OOM con
df50: 64 69 74 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e  dition is encoun
df60: 74 65 72 65 64 2c 20 73 65 74 20 2a 70 52 63 20  tered, set *pRc 
df70: 74 6f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20  to SQLITE_NOMEM 
df80: 62 65 66 6f 72 65 0a 2a 2a 20 72 65 74 75 72 6e  before.** return
df90: 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ing..*/.static v
dfa0: 6f 69 64 20 73 65 73 73 69 6f 6e 41 70 70 65 6e  oid sessionAppen
dfb0: 64 56 61 72 69 6e 74 28 53 65 73 73 69 6f 6e 42  dVarint(SessionB
dfc0: 75 66 66 65 72 20 2a 70 2c 20 69 6e 74 20 76 2c  uffer *p, int v,
dfd0: 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 69 66   int *pRc){.  if
dfe0: 28 20 30 3d 3d 73 65 73 73 69 6f 6e 42 75 66 66  ( 0==sessionBuff
dff0: 65 72 47 72 6f 77 28 70 2c 20 39 2c 20 70 52 63  erGrow(p, 9, pRc
e000: 29 20 29 7b 0a 20 20 20 20 70 2d 3e 6e 42 75 66  ) ){.    p->nBuf
e010: 20 2b 3d 20 73 65 73 73 69 6f 6e 56 61 72 69 6e   += sessionVarin
e020: 74 50 75 74 28 26 70 2d 3e 61 42 75 66 5b 70 2d  tPut(&p->aBuf[p-
e030: 3e 6e 42 75 66 5d 2c 20 76 29 3b 0a 20 20 7d 0a  >nBuf], v);.  }.
e040: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
e050: 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f  nction is a no-o
e060: 70 20 69 66 20 2a 70 52 63 20 69 73 20 6f 74 68  p if *pRc is oth
e070: 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45 5f 4f  er than SQLITE_O
e080: 4b 20 77 68 65 6e 20 69 74 20 69 73 20 0a 2a 2a  K when it is .**
e090: 20 63 61 6c 6c 65 64 2e 20 4f 74 68 65 72 77 69   called. Otherwi
e0a0: 73 65 2c 20 61 70 70 65 6e 64 20 61 20 62 6c 6f  se, append a blo
e0b0: 62 20 6f 66 20 64 61 74 61 20 74 6f 20 74 68 65  b of data to the
e0c0: 20 62 75 66 66 65 72 2e 20 0a 2a 2a 0a 2a 2a 20   buffer. .**.** 
e0d0: 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74  If an OOM condit
e0e0: 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e 74 65 72  ion is encounter
e0f0: 65 64 2c 20 73 65 74 20 2a 70 52 63 20 74 6f 20  ed, set *pRc to 
e100: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 62 65 66  SQLITE_NOMEM bef
e110: 6f 72 65 0a 2a 2a 20 72 65 74 75 72 6e 69 6e 67  ore.** returning
e120: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
e130: 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 6c   sessionAppendBl
e140: 6f 62 28 0a 20 20 53 65 73 73 69 6f 6e 42 75 66  ob(.  SessionBuf
e150: 66 65 72 20 2a 70 2c 20 0a 20 20 63 6f 6e 73 74  fer *p, .  const
e160: 20 75 38 20 2a 61 42 6c 6f 62 2c 20 0a 20 20 69   u8 *aBlob, .  i
e170: 6e 74 20 6e 42 6c 6f 62 2c 20 0a 20 20 69 6e 74  nt nBlob, .  int
e180: 20 2a 70 52 63 0a 29 7b 0a 20 20 69 66 28 20 6e   *pRc.){.  if( n
e190: 42 6c 6f 62 3e 30 20 26 26 20 30 3d 3d 73 65 73  Blob>0 && 0==ses
e1a0: 73 69 6f 6e 42 75 66 66 65 72 47 72 6f 77 28 70  sionBufferGrow(p
e1b0: 2c 20 6e 42 6c 6f 62 2c 20 70 52 63 29 20 29 7b  , nBlob, pRc) ){
e1c0: 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d 3e  .    memcpy(&p->
e1d0: 61 42 75 66 5b 70 2d 3e 6e 42 75 66 5d 2c 20 61  aBuf[p->nBuf], a
e1e0: 42 6c 6f 62 2c 20 6e 42 6c 6f 62 29 3b 0a 20 20  Blob, nBlob);.  
e1f0: 20 20 70 2d 3e 6e 42 75 66 20 2b 3d 20 6e 42 6c    p->nBuf += nBl
e200: 6f 62 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  ob;.  }.}../*.**
e210: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
e220: 73 20 61 20 6e 6f 2d 6f 70 20 69 66 20 2a 70 52  s a no-op if *pR
e230: 63 20 69 73 20 6f 74 68 65 72 20 74 68 61 6e 20  c is other than 
e240: 53 51 4c 49 54 45 5f 4f 4b 20 77 68 65 6e 20 69  SQLITE_OK when i
e250: 74 20 69 73 20 0a 2a 2a 20 63 61 6c 6c 65 64 2e  t is .** called.
e260: 20 4f 74 68 65 72 77 69 73 65 2c 20 61 70 70 65   Otherwise, appe
e270: 6e 64 20 61 20 73 74 72 69 6e 67 20 74 6f 20 74  nd a string to t
e280: 68 65 20 62 75 66 66 65 72 2e 20 41 6c 6c 20 62  he buffer. All b
e290: 79 74 65 73 20 69 6e 20 74 68 65 20 73 74 72 69  ytes in the stri
e2a0: 6e 67 0a 2a 2a 20 75 70 20 74 6f 20 28 62 75 74  ng.** up to (but
e2b0: 20 6e 6f 74 20 69 6e 63 6c 75 64 69 6e 67 29 20   not including) 
e2c0: 74 68 65 20 6e 75 6c 2d 74 65 72 6d 69 6e 61 74  the nul-terminat
e2d0: 6f 72 20 61 72 65 20 77 72 69 74 74 65 6e 20 74  or are written t
e2e0: 6f 20 74 68 65 20 62 75 66 66 65 72 2e 0a 2a 2a  o the buffer..**
e2f0: 0a 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 63 6f  .** If an OOM co
e300: 6e 64 69 74 69 6f 6e 20 69 73 20 65 6e 63 6f 75  ndition is encou
e310: 6e 74 65 72 65 64 2c 20 73 65 74 20 2a 70 52 63  ntered, set *pRc
e320: 20 74 6f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d   to SQLITE_NOMEM
e330: 20 62 65 66 6f 72 65 0a 2a 2a 20 72 65 74 75 72   before.** retur
e340: 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ning..*/.static 
e350: 76 6f 69 64 20 73 65 73 73 69 6f 6e 41 70 70 65  void sessionAppe
e360: 6e 64 53 74 72 28 0a 20 20 53 65 73 73 69 6f 6e  ndStr(.  Session
e370: 42 75 66 66 65 72 20 2a 70 2c 20 0a 20 20 63 6f  Buffer *p, .  co
e380: 6e 73 74 20 63 68 61 72 20 2a 7a 53 74 72 2c 20  nst char *zStr, 
e390: 0a 20 20 69 6e 74 20 2a 70 52 63 0a 29 7b 0a 20  .  int *pRc.){. 
e3a0: 20 69 6e 74 20 6e 53 74 72 20 3d 20 73 71 6c 69   int nStr = sqli
e3b0: 74 65 33 53 74 72 6c 65 6e 33 30 28 7a 53 74 72  te3Strlen30(zStr
e3c0: 29 3b 0a 20 20 69 66 28 20 30 3d 3d 73 65 73 73  );.  if( 0==sess
e3d0: 69 6f 6e 42 75 66 66 65 72 47 72 6f 77 28 70 2c  ionBufferGrow(p,
e3e0: 20 6e 53 74 72 2c 20 70 52 63 29 20 29 7b 0a 20   nStr, pRc) ){. 
e3f0: 20 20 20 6d 65 6d 63 70 79 28 26 70 2d 3e 61 42     memcpy(&p->aB
e400: 75 66 5b 70 2d 3e 6e 42 75 66 5d 2c 20 7a 53 74  uf[p->nBuf], zSt
e410: 72 2c 20 6e 53 74 72 29 3b 0a 20 20 20 20 70 2d  r, nStr);.    p-
e420: 3e 6e 42 75 66 20 2b 3d 20 6e 53 74 72 3b 0a 20  >nBuf += nStr;. 
e430: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73   }.}../*.** This
e440: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e   function is a n
e450: 6f 2d 6f 70 20 69 66 20 2a 70 52 63 20 69 73 20  o-op if *pRc is 
e460: 6f 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54  other than SQLIT
e470: 45 5f 4f 4b 20 77 68 65 6e 20 69 74 20 69 73 20  E_OK when it is 
e480: 0a 2a 2a 20 63 61 6c 6c 65 64 2e 20 4f 74 68 65  .** called. Othe
e490: 72 77 69 73 65 2c 20 61 70 70 65 6e 64 20 74 68  rwise, append th
e4a0: 65 20 73 74 72 69 6e 67 20 72 65 70 72 65 73 65  e string represe
e4b0: 6e 74 61 74 69 6f 6e 20 6f 66 20 69 6e 74 65 67  ntation of integ
e4c0: 65 72 20 69 56 61 6c 0a 2a 2a 20 74 6f 20 74 68  er iVal.** to th
e4d0: 65 20 62 75 66 66 65 72 2e 20 4e 6f 20 6e 75 6c  e buffer. No nul
e4e0: 2d 74 65 72 6d 69 6e 61 74 6f 72 20 69 73 20 77  -terminator is w
e4f0: 72 69 74 74 65 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66  ritten..**.** If
e500: 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74 69 6f   an OOM conditio
e510: 6e 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65 64  n is encountered
e520: 2c 20 73 65 74 20 2a 70 52 63 20 74 6f 20 53 51  , set *pRc to SQ
e530: 4c 49 54 45 5f 4e 4f 4d 45 4d 20 62 65 66 6f 72  LITE_NOMEM befor
e540: 65 0a 2a 2a 20 72 65 74 75 72 6e 69 6e 67 2e 0a  e.** returning..
e550: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73  */.static void s
e560: 65 73 73 69 6f 6e 41 70 70 65 6e 64 49 6e 74 65  essionAppendInte
e570: 67 65 72 28 0a 20 20 53 65 73 73 69 6f 6e 42 75  ger(.  SessionBu
e580: 66 66 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20  ffer *p,        
e590: 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72         /* Buffer
e5a0: 20 74 6f 20 61 70 70 65 6e 64 20 74 6f 20 2a 2f   to append to */
e5b0: 0a 20 20 69 6e 74 20 69 56 61 6c 2c 20 20 20 20  .  int iVal,    
e5c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e5d0: 20 20 20 2f 2a 20 56 61 6c 75 65 20 74 6f 20 77     /* Value to w
e5e0: 72 69 74 65 20 74 68 65 20 73 74 72 69 6e 67 20  rite the string 
e5f0: 72 65 70 2e 20 6f 66 20 2a 2f 0a 20 20 69 6e 74  rep. of */.  int
e600: 20 2a 70 52 63 20 20 20 20 20 20 20 20 20 20 20   *pRc           
e610: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
e620: 49 4e 2f 4f 55 54 3a 20 45 72 72 6f 72 20 63 6f  IN/OUT: Error co
e630: 64 65 20 2a 2f 0a 29 7b 0a 20 20 63 68 61 72 20  de */.){.  char 
e640: 61 42 75 66 5b 32 34 5d 3b 0a 20 20 73 71 6c 69  aBuf[24];.  sqli
e650: 74 65 33 5f 73 6e 70 72 69 6e 74 66 28 73 69 7a  te3_snprintf(siz
e660: 65 6f 66 28 61 42 75 66 29 2d 31 2c 20 61 42 75  eof(aBuf)-1, aBu
e670: 66 2c 20 22 25 64 22 2c 20 69 56 61 6c 29 3b 0a  f, "%d", iVal);.
e680: 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53    sessionAppendS
e690: 74 72 28 70 2c 20 61 42 75 66 2c 20 70 52 63 29  tr(p, aBuf, pRc)
e6a0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
e6b0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f  function is a no
e6c0: 2d 6f 70 20 69 66 20 2a 70 52 63 20 69 73 20 6f  -op if *pRc is o
e6d0: 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45  ther than SQLITE
e6e0: 5f 4f 4b 20 77 68 65 6e 20 69 74 20 69 73 20 0a  _OK when it is .
e6f0: 2a 2a 20 63 61 6c 6c 65 64 2e 20 4f 74 68 65 72  ** called. Other
e700: 77 69 73 65 2c 20 61 70 70 65 6e 64 20 74 68 65  wise, append the
e710: 20 73 74 72 69 6e 67 20 7a 53 74 72 20 65 6e 63   string zStr enc
e720: 6c 6f 73 65 64 20 69 6e 20 71 75 6f 74 65 73 20  losed in quotes 
e730: 28 22 29 20 61 6e 64 0a 2a 2a 20 77 69 74 68 20  (") and.** with 
e740: 61 6e 79 20 65 6d 62 65 64 64 65 64 20 71 75 6f  any embedded quo
e750: 74 65 20 63 68 61 72 61 63 74 65 72 73 20 65 73  te characters es
e760: 63 61 70 65 64 20 74 6f 20 74 68 65 20 62 75 66  caped to the buf
e770: 66 65 72 2e 20 4e 6f 20 0a 2a 2a 20 6e 75 6c 2d  fer. No .** nul-
e780: 74 65 72 6d 69 6e 61 74 6f 72 20 62 79 74 65 20  terminator byte 
e790: 69 73 20 77 72 69 74 74 65 6e 2e 0a 2a 2a 0a 2a  is written..**.*
e7a0: 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64  * If an OOM cond
e7b0: 69 74 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e 74  ition is encount
e7c0: 65 72 65 64 2c 20 73 65 74 20 2a 70 52 63 20 74  ered, set *pRc t
e7d0: 6f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 62  o SQLITE_NOMEM b
e7e0: 65 66 6f 72 65 0a 2a 2a 20 72 65 74 75 72 6e 69  efore.** returni
e7f0: 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ng..*/.static vo
e800: 69 64 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64  id sessionAppend
e810: 49 64 65 6e 74 28 0a 20 20 53 65 73 73 69 6f 6e  Ident(.  Session
e820: 42 75 66 66 65 72 20 2a 70 2c 20 20 20 20 20 20  Buffer *p,      
e830: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66           /* Buff
e840: 65 72 20 74 6f 20 61 20 61 70 70 65 6e 64 20 74  er to a append t
e850: 6f 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  o */.  const cha
e860: 72 20 2a 7a 53 74 72 2c 20 20 20 20 20 20 20 20  r *zStr,        
e870: 20 20 20 20 20 20 20 2f 2a 20 53 74 72 69 6e 67         /* String
e880: 20 74 6f 20 71 75 6f 74 65 2c 20 65 73 63 61 70   to quote, escap
e890: 65 20 61 6e 64 20 61 70 70 65 6e 64 20 2a 2f 0a  e and append */.
e8a0: 20 20 69 6e 74 20 2a 70 52 63 20 20 20 20 20 20    int *pRc      
e8b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e8c0: 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 45 72 72    /* IN/OUT: Err
e8d0: 6f 72 20 63 6f 64 65 20 2a 2f 0a 29 7b 0a 20 20  or code */.){.  
e8e0: 69 6e 74 20 6e 53 74 72 20 3d 20 73 71 6c 69 74  int nStr = sqlit
e8f0: 65 33 53 74 72 6c 65 6e 33 30 28 7a 53 74 72 29  e3Strlen30(zStr)
e900: 2a 32 20 2b 20 32 20 2b 20 31 3b 0a 20 20 69 66  *2 + 2 + 1;.  if
e910: 28 20 30 3d 3d 73 65 73 73 69 6f 6e 42 75 66 66  ( 0==sessionBuff
e920: 65 72 47 72 6f 77 28 70 2c 20 6e 53 74 72 2c 20  erGrow(p, nStr, 
e930: 70 52 63 29 20 29 7b 0a 20 20 20 20 63 68 61 72  pRc) ){.    char
e940: 20 2a 7a 4f 75 74 20 3d 20 28 63 68 61 72 20 2a   *zOut = (char *
e950: 29 26 70 2d 3e 61 42 75 66 5b 70 2d 3e 6e 42 75  )&p->aBuf[p->nBu
e960: 66 5d 3b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68  f];.    const ch
e970: 61 72 20 2a 7a 49 6e 20 3d 20 7a 53 74 72 3b 0a  ar *zIn = zStr;.
e980: 20 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20 27 22      *zOut++ = '"
e990: 27 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 2a 7a  ';.    while( *z
e9a0: 49 6e 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  In ){.      if( 
e9b0: 2a 7a 49 6e 3d 3d 27 22 27 20 29 20 2a 7a 4f 75  *zIn=='"' ) *zOu
e9c0: 74 2b 2b 20 3d 20 27 22 27 3b 0a 20 20 20 20 20  t++ = '"';.     
e9d0: 20 2a 7a 4f 75 74 2b 2b 20 3d 20 2a 28 7a 49 6e   *zOut++ = *(zIn
e9e0: 2b 2b 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 2a  ++);.    }.    *
e9f0: 7a 4f 75 74 2b 2b 20 3d 20 27 22 27 3b 0a 20 20  zOut++ = '"';.  
ea00: 20 20 70 2d 3e 6e 42 75 66 20 3d 20 28 69 6e 74    p->nBuf = (int
ea10: 29 28 28 75 38 20 2a 29 7a 4f 75 74 20 2d 20 70  )((u8 *)zOut - p
ea20: 2d 3e 61 42 75 66 29 3b 0a 20 20 7d 0a 7d 0a 0a  ->aBuf);.  }.}..
ea30: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
ea40: 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 20 69  ion is a no-op i
ea50: 66 20 2a 70 52 63 20 69 73 20 6f 74 68 65 72 20  f *pRc is other 
ea60: 74 68 61 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 77  than SQLITE_OK w
ea70: 68 65 6e 20 69 74 20 69 73 0a 2a 2a 20 63 61 6c  hen it is.** cal
ea80: 6c 65 64 2e 20 4f 74 68 65 72 77 73 65 2c 20 69  led. Otherwse, i
ea90: 74 20 61 70 70 65 6e 64 73 20 74 68 65 20 73 65  t appends the se
eaa0: 72 69 61 6c 69 7a 65 64 20 76 65 72 73 69 6f 6e  rialized version
eab0: 20 6f 66 20 74 68 65 20 76 61 6c 75 65 20 73 74   of the value st
eac0: 6f 72 65 64 0a 2a 2a 20 69 6e 20 63 6f 6c 75 6d  ored.** in colum
ead0: 6e 20 69 43 6f 6c 20 6f 66 20 74 68 65 20 72 6f  n iCol of the ro
eae0: 77 20 74 68 61 74 20 53 51 4c 20 73 74 61 74 65  w that SQL state
eaf0: 6d 65 6e 74 20 70 53 74 6d 74 20 63 75 72 72 65  ment pStmt curre
eb00: 6e 74 6c 79 20 70 6f 69 6e 74 73 0a 2a 2a 20 74  ntly points.** t
eb10: 6f 20 74 6f 20 74 68 65 20 62 75 66 66 65 72 2e  o to the buffer.
eb20: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
eb30: 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 43 6f 6c  sessionAppendCol
eb40: 28 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66 65  (.  SessionBuffe
eb50: 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20  r *p,           
eb60: 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f      /* Buffer to
eb70: 20 61 70 70 65 6e 64 20 74 6f 20 2a 2f 0a 20 20   append to */.  
eb80: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53  sqlite3_stmt *pS
eb90: 74 6d 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  tmt,            
eba0: 2f 2a 20 48 61 6e 64 6c 65 20 70 6f 69 6e 74 69  /* Handle pointi
ebb0: 6e 67 20 74 6f 20 72 6f 77 20 63 6f 6e 74 61 69  ng to row contai
ebc0: 6e 69 6e 67 20 76 61 6c 75 65 20 2a 2f 0a 20 20  ning value */.  
ebd0: 69 6e 74 20 69 43 6f 6c 2c 20 20 20 20 20 20 20  int iCol,       
ebe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ebf0: 2f 2a 20 43 6f 6c 75 6d 6e 20 74 6f 20 72 65 61  /* Column to rea
ec00: 64 20 76 61 6c 75 65 20 66 72 6f 6d 20 2a 2f 0a  d value from */.
ec10: 20 20 69 6e 74 20 2a 70 52 63 20 20 20 20 20 20    int *pRc      
ec20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ec30: 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 45 72 72    /* IN/OUT: Err
ec40: 6f 72 20 63 6f 64 65 20 2a 2f 0a 29 7b 0a 20 20  or code */.){.  
ec50: 69 66 28 20 2a 70 52 63 3d 3d 53 51 4c 49 54 45  if( *pRc==SQLITE
ec60: 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 65  _OK ){.    int e
ec70: 54 79 70 65 20 3d 20 73 71 6c 69 74 65 33 5f 63  Type = sqlite3_c
ec80: 6f 6c 75 6d 6e 5f 74 79 70 65 28 70 53 74 6d 74  olumn_type(pStmt
ec90: 2c 20 69 43 6f 6c 29 3b 0a 20 20 20 20 73 65 73  , iCol);.    ses
eca0: 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 70  sionAppendByte(p
ecb0: 2c 20 28 75 38 29 65 54 79 70 65 2c 20 70 52 63  , (u8)eType, pRc
ecc0: 29 3b 0a 20 20 20 20 69 66 28 20 65 54 79 70 65  );.    if( eType
ecd0: 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52  ==SQLITE_INTEGER
ece0: 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49 54   || eType==SQLIT
ecf0: 45 5f 46 4c 4f 41 54 20 29 7b 0a 20 20 20 20 20  E_FLOAT ){.     
ed00: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69   sqlite3_int64 i
ed10: 3b 0a 20 20 20 20 20 20 75 38 20 61 42 75 66 5b  ;.      u8 aBuf[
ed20: 38 5d 3b 0a 20 20 20 20 20 20 69 66 28 20 65 54  8];.      if( eT
ed30: 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45  ype==SQLITE_INTE
ed40: 47 45 52 20 29 7b 0a 20 20 20 20 20 20 20 20 69  GER ){.        i
ed50: 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d   = sqlite3_colum
ed60: 6e 5f 69 6e 74 36 34 28 70 53 74 6d 74 2c 20 69  n_int64(pStmt, i
ed70: 43 6f 6c 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73  Col);.      }els
ed80: 65 7b 0a 20 20 20 20 20 20 20 20 64 6f 75 62 6c  e{.        doubl
ed90: 65 20 72 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  e r = sqlite3_co
eda0: 6c 75 6d 6e 5f 64 6f 75 62 6c 65 28 70 53 74 6d  lumn_double(pStm
edb0: 74 2c 20 69 43 6f 6c 29 3b 0a 20 20 20 20 20 20  t, iCol);.      
edc0: 20 20 6d 65 6d 63 70 79 28 26 69 2c 20 26 72 2c    memcpy(&i, &r,
edd0: 20 38 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20   8);.      }.   
ede0: 20 20 20 73 65 73 73 69 6f 6e 50 75 74 49 36 34     sessionPutI64
edf0: 28 61 42 75 66 2c 20 69 29 3b 0a 20 20 20 20 20  (aBuf, i);.     
ee00: 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 6c   sessionAppendBl
ee10: 6f 62 28 70 2c 20 61 42 75 66 2c 20 38 2c 20 70  ob(p, aBuf, 8, p
ee20: 52 63 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  Rc);.    }.    i
ee30: 66 28 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45  f( eType==SQLITE
ee40: 5f 42 4c 4f 42 20 7c 7c 20 65 54 79 70 65 3d 3d  _BLOB || eType==
ee50: 53 51 4c 49 54 45 5f 54 45 58 54 20 29 7b 0a 20  SQLITE_TEXT ){. 
ee60: 20 20 20 20 20 75 38 20 2a 7a 3b 0a 20 20 20 20       u8 *z;.    
ee70: 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20    int nByte;.   
ee80: 20 20 20 69 66 28 20 65 54 79 70 65 3d 3d 53 51     if( eType==SQ
ee90: 4c 49 54 45 5f 42 4c 4f 42 20 29 7b 0a 20 20 20  LITE_BLOB ){.   
eea0: 20 20 20 20 20 7a 20 3d 20 28 75 38 20 2a 29 73       z = (u8 *)s
eeb0: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c  qlite3_column_bl
eec0: 6f 62 28 70 53 74 6d 74 2c 20 69 43 6f 6c 29 3b  ob(pStmt, iCol);
eed0: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
eee0: 20 20 20 20 20 20 7a 20 3d 20 28 75 38 20 2a 29        z = (u8 *)
eef0: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74  sqlite3_column_t
ef00: 65 78 74 28 70 53 74 6d 74 2c 20 69 43 6f 6c 29  ext(pStmt, iCol)
ef10: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
ef20: 6e 42 79 74 65 20 3d 20 73 71 6c 69 74 65 33 5f  nByte = sqlite3_
ef30: 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70 53 74  column_bytes(pSt
ef40: 6d 74 2c 20 69 43 6f 6c 29 3b 0a 20 20 20 20 20  mt, iCol);.     
ef50: 20 69 66 28 20 7a 20 7c 7c 20 28 65 54 79 70 65   if( z || (eType
ef60: 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 20 26 26  ==SQLITE_BLOB &&
ef70: 20 6e 42 79 74 65 3d 3d 30 29 20 29 7b 0a 20 20   nByte==0) ){.  
ef80: 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70        sessionApp
ef90: 65 6e 64 56 61 72 69 6e 74 28 70 2c 20 6e 42 79  endVarint(p, nBy
efa0: 74 65 2c 20 70 52 63 29 3b 0a 20 20 20 20 20 20  te, pRc);.      
efb0: 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42    sessionAppendB
efc0: 6c 6f 62 28 70 2c 20 7a 2c 20 6e 42 79 74 65 2c  lob(p, z, nByte,
efd0: 20 70 52 63 29 3b 0a 20 20 20 20 20 20 7d 65 6c   pRc);.      }el
efe0: 73 65 7b 0a 20 20 20 20 20 20 20 20 2a 70 52 63  se{.        *pRc
eff0: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
f000: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
f010: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 0a 2a 2a 20 54   }.}../*.**.** T
f020: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 61 70 70  his function app
f030: 65 6e 64 73 20 61 6e 20 75 70 64 61 74 65 20 63  ends an update c
f040: 68 61 6e 67 65 20 74 6f 20 74 68 65 20 62 75 66  hange to the buf
f050: 66 65 72 20 28 73 65 65 20 74 68 65 20 63 6f 6d  fer (see the com
f060: 6d 65 6e 74 73 20 0a 2a 2a 20 75 6e 64 65 72 20  ments .** under 
f070: 22 43 48 41 4e 47 45 53 45 54 20 46 4f 52 4d 41  "CHANGESET FORMA
f080: 54 22 20 61 74 20 74 68 65 20 74 6f 70 20 6f 66  T" at the top of
f090: 20 74 68 65 20 66 69 6c 65 29 2e 20 41 6e 20 75   the file). An u
f0a0: 70 64 61 74 65 20 63 68 61 6e 67 65 20 0a 2a 2a  pdate change .**
f0b0: 20 63 6f 6e 73 69 73 74 73 20 6f 66 3a 0a 2a 2a   consists of:.**
f0c0: 0a 2a 2a 20 20 20 31 20 62 79 74 65 3a 20 20 53  .**   1 byte:  S
f0d0: 51 4c 49 54 45 5f 55 50 44 41 54 45 20 28 30 78  QLITE_UPDATE (0x
f0e0: 31 37 29 0a 2a 2a 20 20 20 6e 20 62 79 74 65 73  17).**   n bytes
f0f0: 3a 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 20 28  : old.* record (
f100: 73 65 65 20 52 45 43 4f 52 44 20 46 4f 52 4d 41  see RECORD FORMA
f110: 54 29 0a 2a 2a 20 20 20 6d 20 62 79 74 65 73 3a  T).**   m bytes:
f120: 20 6e 65 77 2e 2a 20 72 65 63 6f 72 64 20 28 73   new.* record (s
f130: 65 65 20 52 45 43 4f 52 44 20 46 4f 52 4d 41 54  ee RECORD FORMAT
f140: 29 0a 2a 2a 0a 2a 2a 20 54 68 65 20 53 65 73 73  ).**.** The Sess
f150: 69 6f 6e 43 68 61 6e 67 65 20 6f 62 6a 65 63 74  ionChange object
f160: 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 74   passed as the t
f170: 68 69 72 64 20 61 72 67 75 6d 65 6e 74 20 63 6f  hird argument co
f180: 6e 74 61 69 6e 73 20 74 68 65 0a 2a 2a 20 76 61  ntains the.** va
f190: 6c 75 65 73 20 74 68 61 74 20 77 65 72 65 20 73  lues that were s
f1a0: 74 6f 72 65 64 20 69 6e 20 74 68 65 20 72 6f 77  tored in the row
f1b0: 20 77 68 65 6e 20 74 68 65 20 73 65 73 73 69 6f   when the sessio
f1c0: 6e 20 62 65 67 61 6e 20 28 74 68 65 20 6f 6c 64  n began (the old
f1d0: 2e 2a 0a 2a 2a 20 76 61 6c 75 65 73 29 2e 20 54  .*.** values). T
f1e0: 68 65 20 73 74 61 74 65 6d 65 6e 74 20 68 61 6e  he statement han
f1f0: 64 6c 65 20 70 61 73 73 65 64 20 61 73 20 74 68  dle passed as th
f200: 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e  e second argumen
f210: 74 20 70 6f 69 6e 74 73 0a 2a 2a 20 61 74 20 74  t points.** at t
f220: 68 65 20 63 75 72 72 65 6e 74 20 76 65 72 73 69  he current versi
f230: 6f 6e 20 6f 66 20 74 68 65 20 72 6f 77 20 28 74  on of the row (t
f240: 68 65 20 6e 65 77 2e 2a 20 76 61 6c 75 65 73 29  he new.* values)
f250: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6c 6c 20 6f  ..**.** If all o
f260: 66 20 74 68 65 20 6f 6c 64 2e 2a 20 76 61 6c 75  f the old.* valu
f270: 65 73 20 61 72 65 20 65 71 75 61 6c 20 74 6f 20  es are equal to 
f280: 74 68 65 69 72 20 63 6f 72 72 65 73 70 6f 6e 64  their correspond
f290: 69 6e 67 20 6e 65 77 2e 2a 20 76 61 6c 75 65 0a  ing new.* value.
f2a0: 2a 2a 20 28 69 2e 65 2e 20 6e 6f 74 68 69 6e 67  ** (i.e. nothing
f2b0: 20 68 61 73 20 63 68 61 6e 67 65 64 29 2c 20 74   has changed), t
f2c0: 68 65 6e 20 6e 6f 20 64 61 74 61 20 61 74 20 61  hen no data at a
f2d0: 6c 6c 20 69 73 20 61 70 70 65 6e 64 65 64 20 74  ll is appended t
f2e0: 6f 20 74 68 65 20 62 75 66 66 65 72 2e 0a 2a 2a  o the buffer..**
f2f0: 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 74  .** Otherwise, t
f300: 68 65 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 20  he old.* record 
f310: 63 6f 6e 74 61 69 6e 73 20 61 6c 6c 20 70 72 69  contains all pri
f320: 6d 61 72 79 20 6b 65 79 20 76 61 6c 75 65 73 20  mary key values 
f330: 61 6e 64 20 74 68 65 20 0a 2a 2a 20 6f 72 69 67  and the .** orig
f340: 69 6e 61 6c 20 76 61 6c 75 65 73 20 6f 66 20 61  inal values of a
f350: 6e 79 20 66 69 65 6c 64 73 20 74 68 61 74 20 68  ny fields that h
f360: 61 76 65 20 62 65 65 6e 20 6d 6f 64 69 66 69 65  ave been modifie
f370: 64 2e 20 54 68 65 20 6e 65 77 2e 2a 20 72 65 63  d. The new.* rec
f380: 6f 72 64 20 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73  ord .** contains
f390: 20 74 68 65 20 6e 65 77 20 76 61 6c 75 65 73 20   the new values 
f3a0: 6f 66 20 6f 6e 6c 79 20 74 68 6f 73 65 20 66 69  of only those fi
f3b0: 65 6c 64 73 20 74 68 61 74 20 68 61 76 65 20 62  elds that have b
f3c0: 65 65 6e 20 6d 6f 64 69 66 69 65 64 2e 0a 2a 2f  een modified..*/
f3d0: 20 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73   .static int ses
f3e0: 73 69 6f 6e 41 70 70 65 6e 64 55 70 64 61 74 65  sionAppendUpdate
f3f0: 28 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66 65  (.  SessionBuffe
f400: 72 20 2a 70 42 75 66 2c 20 20 20 20 20 20 20 20  r *pBuf,        
f410: 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f      /* Buffer to
f420: 20 61 70 70 65 6e 64 20 74 6f 20 2a 2f 0a 20 20   append to */.  
f430: 69 6e 74 20 62 50 61 74 63 68 73 65 74 2c 20 20  int bPatchset,  
f440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f450: 2f 2a 20 54 72 75 65 20 66 6f 72 20 22 70 61 74  /* True for "pat
f460: 63 68 73 65 74 22 2c 20 30 20 66 6f 72 20 22 63  chset", 0 for "c
f470: 68 61 6e 67 65 73 65 74 22 20 2a 2f 0a 20 20 73  hangeset" */.  s
f480: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
f490: 6d 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  mt,            /
f4a0: 2a 20 53 74 61 74 65 6d 65 6e 74 20 68 61 6e 64  * Statement hand
f4b0: 6c 65 20 70 6f 69 6e 74 69 6e 67 20 61 74 20 6e  le pointing at n
f4c0: 65 77 20 72 6f 77 20 2a 2f 0a 20 20 53 65 73 73  ew row */.  Sess
f4d0: 69 6f 6e 43 68 61 6e 67 65 20 2a 70 2c 20 20 20  ionChange *p,   
f4e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
f4f0: 62 6a 65 63 74 20 63 6f 6e 74 61 69 6e 69 6e 67  bject containing
f500: 20 6f 6c 64 20 76 61 6c 75 65 73 20 2a 2f 0a 20   old values */. 
f510: 20 75 38 20 2a 61 62 50 4b 20 20 20 20 20 20 20   u8 *abPK       
f520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f530: 20 2f 2a 20 42 6f 6f 6c 65 61 6e 20 61 72 72 61   /* Boolean arra
f540: 79 20 2d 20 74 72 75 65 20 66 6f 72 20 50 4b 20  y - true for PK 
f550: 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 29 7b 0a 20 20  columns */.){.  
f560: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
f570: 4f 4b 3b 0a 20 20 53 65 73 73 69 6f 6e 42 75 66  OK;.  SessionBuf
f580: 66 65 72 20 62 75 66 32 20 3d 20 7b 30 2c 30 2c  fer buf2 = {0,0,
f590: 30 7d 3b 20 2f 2a 20 42 75 66 66 65 72 20 74 6f  0}; /* Buffer to
f5a0: 20 61 63 63 75 6d 75 6c 61 74 65 20 6e 65 77 2e   accumulate new.
f5b0: 2a 20 72 65 63 6f 72 64 20 69 6e 20 2a 2f 0a 20  * record in */. 
f5c0: 20 69 6e 74 20 62 4e 6f 6f 70 20 3d 20 31 3b 20   int bNoop = 1; 
f5d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
f5e0: 2a 20 53 65 74 20 74 6f 20 7a 65 72 6f 20 69 66  * Set to zero if
f5f0: 20 61 6e 79 20 76 61 6c 75 65 73 20 61 72 65 20   any values are 
f600: 6d 6f 64 69 66 69 65 64 20 2a 2f 0a 20 20 69 6e  modified */.  in
f610: 74 20 6e 52 65 77 69 6e 64 20 3d 20 70 42 75 66  t nRewind = pBuf
f620: 2d 3e 6e 42 75 66 3b 20 20 20 20 20 2f 2a 20 53  ->nBuf;     /* S
f630: 65 74 20 74 6f 20 7a 65 72 6f 20 69 66 20 61 6e  et to zero if an
f640: 79 20 76 61 6c 75 65 73 20 61 72 65 20 6d 6f 64  y values are mod
f650: 69 66 69 65 64 20 2a 2f 0a 20 20 69 6e 74 20 69  ified */.  int i
f660: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
f670: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64           /* Used
f680: 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f   to iterate thro
f690: 75 67 68 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 20  ugh columns */. 
f6a0: 20 75 38 20 2a 70 43 73 72 20 3d 20 70 2d 3e 61   u8 *pCsr = p->a
f6b0: 52 65 63 6f 72 64 3b 20 20 20 20 20 20 20 20 2f  Record;        /
f6c0: 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72 61 74  * Used to iterat
f6d0: 65 20 74 68 72 6f 75 67 68 20 6f 6c 64 2e 2a 20  e through old.* 
f6e0: 76 61 6c 75 65 73 20 2a 2f 0a 0a 20 20 73 65 73  values */..  ses
f6f0: 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 70  sionAppendByte(p
f700: 42 75 66 2c 20 53 51 4c 49 54 45 5f 55 50 44 41  Buf, SQLITE_UPDA
f710: 54 45 2c 20 26 72 63 29 3b 0a 20 20 73 65 73 73  TE, &rc);.  sess
f720: 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 70 42  ionAppendByte(pB
f730: 75 66 2c 20 70 2d 3e 62 49 6e 64 69 72 65 63 74  uf, p->bIndirect
f740: 2c 20 26 72 63 29 3b 0a 20 20 66 6f 72 28 69 3d  , &rc);.  for(i=
f750: 30 3b 20 69 3c 73 71 6c 69 74 65 33 5f 63 6f 6c  0; i<sqlite3_col
f760: 75 6d 6e 5f 63 6f 75 6e 74 28 70 53 74 6d 74 29  umn_count(pStmt)
f770: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 20  ; i++){.    int 
f780: 62 43 68 61 6e 67 65 64 20 3d 20 30 3b 0a 20 20  bChanged = 0;.  
f790: 20 20 69 6e 74 20 6e 41 64 76 61 6e 63 65 3b 0a    int nAdvance;.
f7a0: 20 20 20 20 69 6e 74 20 65 54 79 70 65 20 3d 20      int eType = 
f7b0: 2a 70 43 73 72 3b 0a 20 20 20 20 73 77 69 74 63  *pCsr;.    switc
f7c0: 68 28 20 65 54 79 70 65 20 29 7b 0a 20 20 20 20  h( eType ){.    
f7d0: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 4e 55    case SQLITE_NU
f7e0: 4c 4c 3a 0a 20 20 20 20 20 20 20 20 6e 41 64 76  LL:.        nAdv
f7f0: 61 6e 63 65 20 3d 20 31 3b 0a 20 20 20 20 20 20  ance = 1;.      
f800: 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 63 6f    if( sqlite3_co
f810: 6c 75 6d 6e 5f 74 79 70 65 28 70 53 74 6d 74 2c  lumn_type(pStmt,
f820: 20 69 29 21 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c   i)!=SQLITE_NULL
f830: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 62 43   ){.          bC
f840: 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20 20 20 20  hanged = 1;.    
f850: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 62 72      }.        br
f860: 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63 61 73 65  eak;..      case
f870: 20 53 51 4c 49 54 45 5f 46 4c 4f 41 54 3a 0a 20   SQLITE_FLOAT:. 
f880: 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45       case SQLITE
f890: 5f 49 4e 54 45 47 45 52 3a 20 7b 0a 20 20 20 20  _INTEGER: {.    
f8a0: 20 20 20 20 6e 41 64 76 61 6e 63 65 20 3d 20 39      nAdvance = 9
f8b0: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 65 54  ;.        if( eT
f8c0: 79 70 65 3d 3d 73 71 6c 69 74 65 33 5f 63 6f 6c  ype==sqlite3_col
f8d0: 75 6d 6e 5f 74 79 70 65 28 70 53 74 6d 74 2c 20  umn_type(pStmt, 
f8e0: 69 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  i) ){.          
f8f0: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 56  sqlite3_int64 iV
f900: 61 6c 20 3d 20 73 65 73 73 69 6f 6e 47 65 74 49  al = sessionGetI
f910: 36 34 28 26 70 43 73 72 5b 31 5d 29 3b 0a 20 20  64(&pCsr[1]);.  
f920: 20 20 20 20 20 20 20 20 69 66 28 20 65 54 79 70          if( eTyp
f930: 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45  e==SQLITE_INTEGE
f940: 52 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  R ){.           
f950: 20 69 66 28 20 69 56 61 6c 3d 3d 73 71 6c 69 74   if( iVal==sqlit
f960: 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28  e3_column_int64(
f970: 70 53 74 6d 74 2c 20 69 29 20 29 20 62 72 65 61  pStmt, i) ) brea
f980: 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 65 6c  k;.          }el
f990: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  se{.            
f9a0: 64 6f 75 62 6c 65 20 64 56 61 6c 3b 0a 20 20 20  double dVal;.   
f9b0: 20 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28           memcpy(
f9c0: 26 64 56 61 6c 2c 20 26 69 56 61 6c 2c 20 38 29  &dVal, &iVal, 8)
f9d0: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  ;.            if
f9e0: 28 20 64 56 61 6c 3d 3d 73 71 6c 69 74 65 33 5f  ( dVal==sqlite3_
f9f0: 63 6f 6c 75 6d 6e 5f 64 6f 75 62 6c 65 28 70 53  column_double(pS
fa00: 74 6d 74 2c 20 69 29 20 29 20 62 72 65 61 6b 3b  tmt, i) ) break;
fa10: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
fa20: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 62       }.        b
fa30: 43 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20 20 20  Changed = 1;.   
fa40: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
fa50: 20 20 7d 0a 0a 20 20 20 20 20 20 64 65 66 61 75    }..      defau
fa60: 6c 74 3a 20 7b 0a 20 20 20 20 20 20 20 20 69 6e  lt: {.        in
fa70: 74 20 6e 3b 0a 20 20 20 20 20 20 20 20 69 6e 74  t n;.        int
fa80: 20 6e 48 64 72 20 3d 20 31 20 2b 20 73 65 73 73   nHdr = 1 + sess
fa90: 69 6f 6e 56 61 72 69 6e 74 47 65 74 28 26 70 43  ionVarintGet(&pC
faa0: 73 72 5b 31 5d 2c 20 26 6e 29 3b 0a 20 20 20 20  sr[1], &n);.    
fab0: 20 20 20 20 61 73 73 65 72 74 28 20 65 54 79 70      assert( eTyp
fac0: 65 3d 3d 53 51 4c 49 54 45 5f 54 45 58 54 20 7c  e==SQLITE_TEXT |
fad0: 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f  | eType==SQLITE_
fae0: 42 4c 4f 42 20 29 3b 0a 20 20 20 20 20 20 20 20  BLOB );.        
faf0: 6e 41 64 76 61 6e 63 65 20 3d 20 6e 48 64 72 20  nAdvance = nHdr 
fb00: 2b 20 6e 3b 0a 20 20 20 20 20 20 20 20 69 66 28  + n;.        if(
fb10: 20 65 54 79 70 65 3d 3d 73 71 6c 69 74 65 33 5f   eType==sqlite3_
fb20: 63 6f 6c 75 6d 6e 5f 74 79 70 65 28 70 53 74 6d  column_type(pStm
fb30: 74 2c 20 69 29 20 0a 20 20 20 20 20 20 20 20 20  t, i) .         
fb40: 26 26 20 6e 3d 3d 73 71 6c 69 74 65 33 5f 63 6f  && n==sqlite3_co
fb50: 6c 75 6d 6e 5f 62 79 74 65 73 28 70 53 74 6d 74  lumn_bytes(pStmt
fb60: 2c 20 69 29 20 0a 20 20 20 20 20 20 20 20 20 26  , i) .         &
fb70: 26 20 28 6e 3d 3d 30 20 7c 7c 20 30 3d 3d 6d 65  & (n==0 || 0==me
fb80: 6d 63 6d 70 28 26 70 43 73 72 5b 6e 48 64 72 5d  mcmp(&pCsr[nHdr]
fb90: 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  , sqlite3_column
fba0: 5f 62 6c 6f 62 28 70 53 74 6d 74 2c 20 69 29 2c  _blob(pStmt, i),
fbb0: 20 6e 29 29 0a 20 20 20 20 20 20 20 20 29 7b 0a   n)).        ){.
fbc0: 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b            break;
fbd0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
fbe0: 20 20 20 62 43 68 61 6e 67 65 64 20 3d 20 31 3b     bChanged = 1;
fbf0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
fc00: 20 20 20 20 2f 2a 20 49 66 20 61 74 20 6c 65 61      /* If at lea
fc10: 73 74 20 6f 6e 65 20 66 69 65 6c 64 20 68 61 73  st one field has
fc20: 20 62 65 65 6e 20 6d 6f 64 69 66 69 65 64 2c 20   been modified, 
fc30: 74 68 69 73 20 69 73 20 6e 6f 74 20 61 20 6e 6f  this is not a no
fc40: 2d 6f 70 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20  -op. */.    if( 
fc50: 62 43 68 61 6e 67 65 64 20 29 20 62 4e 6f 6f 70  bChanged ) bNoop
fc60: 20 3d 20 30 3b 0a 0a 20 20 20 20 2f 2a 20 41 64   = 0;..    /* Ad
fc70: 64 20 61 20 66 69 65 6c 64 20 74 6f 20 74 68 65  d a field to the
fc80: 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 2e 20 54   old.* record. T
fc90: 68 69 73 20 69 73 20 6f 6d 69 74 74 65 64 20 69  his is omitted i
fca0: 66 20 74 68 69 73 20 6d 6f 64 75 6c 65 73 20 69  f this modules i
fcb0: 73 0a 20 20 20 20 2a 2a 20 63 75 72 72 65 6e 74  s.    ** current
fcc0: 6c 79 20 67 65 6e 65 72 61 74 69 6e 67 20 61 20  ly generating a 
fcd0: 70 61 74 63 68 73 65 74 2e 20 2a 2f 0a 20 20 20  patchset. */.   
fce0: 20 69 66 28 20 62 50 61 74 63 68 73 65 74 3d 3d   if( bPatchset==
fcf0: 30 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 62  0 ){.      if( b
fd00: 43 68 61 6e 67 65 64 20 7c 7c 20 61 62 50 4b 5b  Changed || abPK[
fd10: 69 5d 20 29 7b 0a 20 20 20 20 20 20 20 20 73 65  i] ){.        se
fd20: 73 73 69 6f 6e 41 70 70 65 6e 64 42 6c 6f 62 28  ssionAppendBlob(
fd30: 70 42 75 66 2c 20 70 43 73 72 2c 20 6e 41 64 76  pBuf, pCsr, nAdv
fd40: 61 6e 63 65 2c 20 26 72 63 29 3b 0a 20 20 20 20  ance, &rc);.    
fd50: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
fd60: 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 79   sessionAppendBy
fd70: 74 65 28 70 42 75 66 2c 20 30 2c 20 26 72 63 29  te(pBuf, 0, &rc)
fd80: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
fd90: 0a 20 20 20 20 2f 2a 20 41 64 64 20 61 20 66 69  .    /* Add a fi
fda0: 65 6c 64 20 74 6f 20 74 68 65 20 6e 65 77 2e 2a  eld to the new.*
fdb0: 20 72 65 63 6f 72 64 2e 20 4f 72 20 74 68 65 20   record. Or the 
fdc0: 6f 6e 6c 79 20 72 65 63 6f 72 64 20 69 66 20 63  only record if c
fdd0: 75 72 72 65 6e 74 6c 79 0a 20 20 20 20 2a 2a 20  urrently.    ** 
fde0: 67 65 6e 65 72 61 74 69 6e 67 20 61 20 70 61 74  generating a pat
fdf0: 63 68 73 65 74 2e 20 20 2a 2f 0a 20 20 20 20 69  chset.  */.    i
fe00: 66 28 20 62 43 68 61 6e 67 65 64 20 7c 7c 20 28  f( bChanged || (
fe10: 62 50 61 74 63 68 73 65 74 20 26 26 20 61 62 50  bPatchset && abP
fe20: 4b 5b 69 5d 29 20 29 7b 0a 20 20 20 20 20 20 73  K[i]) ){.      s
fe30: 65 73 73 69 6f 6e 41 70 70 65 6e 64 43 6f 6c 28  essionAppendCol(
fe40: 26 62 75 66 32 2c 20 70 53 74 6d 74 2c 20 69 2c  &buf2, pStmt, i,
fe50: 20 26 72 63 29 3b 0a 20 20 20 20 7d 65 6c 73 65   &rc);.    }else
fe60: 7b 0a 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41  {.      sessionA
fe70: 70 70 65 6e 64 42 79 74 65 28 26 62 75 66 32 2c  ppendByte(&buf2,
fe80: 20 30 2c 20 26 72 63 29 3b 0a 20 20 20 20 7d 0a   0, &rc);.    }.
fe90: 0a 20 20 20 20 70 43 73 72 20 2b 3d 20 6e 41 64  .    pCsr += nAd
fea0: 76 61 6e 63 65 3b 0a 20 20 7d 0a 0a 20 20 69 66  vance;.  }..  if
feb0: 28 20 62 4e 6f 6f 70 20 29 7b 0a 20 20 20 20 70  ( bNoop ){.    p
fec0: 42 75 66 2d 3e 6e 42 75 66 20 3d 20 6e 52 65 77  Buf->nBuf = nRew
fed0: 69 6e 64 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  ind;.  }else{.  
fee0: 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42    sessionAppendB
fef0: 6c 6f 62 28 70 42 75 66 2c 20 62 75 66 32 2e 61  lob(pBuf, buf2.a
ff00: 42 75 66 2c 20 62 75 66 32 2e 6e 42 75 66 2c 20  Buf, buf2.nBuf, 
ff10: 26 72 63 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69  &rc);.  }.  sqli
ff20: 74 65 33 5f 66 72 65 65 28 62 75 66 32 2e 61 42  te3_free(buf2.aB
ff30: 75 66 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72  uf);..  return r
ff40: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65  c;.}../*.** Appe
ff50: 6e 64 20 61 20 44 45 4c 45 54 45 20 63 68 61 6e  nd a DELETE chan
ff60: 67 65 20 74 6f 20 74 68 65 20 62 75 66 66 65 72  ge to the buffer
ff70: 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66   passed as the f
ff80: 69 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 20 55  irst argument. U
ff90: 73 65 0a 2a 2a 20 74 68 65 20 63 68 61 6e 67 65  se.** the change
ffa0: 73 65 74 20 66 6f 72 6d 61 74 20 69 66 20 61 72  set format if ar
ffb0: 67 75 6d 65 6e 74 20 62 50 61 74 63 68 73 65 74  gument bPatchset
ffc0: 20 69 73 20 7a 65 72 6f 2c 20 6f 72 20 74 68 65   is zero, or the
ffd0: 20 70 61 74 63 68 73 65 74 0a 2a 2a 20 66 6f 72   patchset.** for
ffe0: 6d 61 74 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a  mat otherwise..*
fff0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73  /.static int ses
10000 73 69 6f 6e 41 70 70 65 6e 64 44 65 6c 65 74 65  sionAppendDelete
10010 28 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66 65  (.  SessionBuffe
10020 72 20 2a 70 42 75 66 2c 20 20 20 20 20 20 20 20  r *pBuf,        
10030 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f      /* Buffer to
10040 20 61 70 70 65 6e 64 20 74 6f 20 2a 2f 0a 20 20   append to */.  
10050 69 6e 74 20 62 50 61 74 63 68 73 65 74 2c 20 20  int bPatchset,  
10060 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10070 2f 2a 20 54 72 75 65 20 66 6f 72 20 22 70 61 74  /* True for "pat
10080 63 68 73 65 74 22 2c 20 30 20 66 6f 72 20 22 63  chset", 0 for "c
10090 68 61 6e 67 65 73 65 74 22 20 2a 2f 0a 20 20 53  hangeset" */.  S
100a0 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 70 2c  essionChange *p,
100b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
100c0 2a 20 4f 62 6a 65 63 74 20 63 6f 6e 74 61 69 6e  * Object contain
100d0 69 6e 67 20 6f 6c 64 20 76 61 6c 75 65 73 20 2a  ing old values *
100e0 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c 20 20 20  /.  int nCol,   
100f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10100 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
10110 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 61 62 6c   columns in tabl
10120 65 20 2a 2f 0a 20 20 75 38 20 2a 61 62 50 4b 20  e */.  u8 *abPK 
10130 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10140 20 20 20 20 20 20 20 2f 2a 20 42 6f 6f 6c 65 61         /* Boolea
10150 6e 20 61 72 72 61 79 20 2d 20 74 72 75 65 20 66  n array - true f
10160 6f 72 20 50 4b 20 63 6f 6c 75 6d 6e 73 20 2a 2f  or PK columns */
10170 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
10180 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 73 65 73  QLITE_OK;..  ses
10190 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 70  sionAppendByte(p
101a0 42 75 66 2c 20 53 51 4c 49 54 45 5f 44 45 4c 45  Buf, SQLITE_DELE
101b0 54 45 2c 20 26 72 63 29 3b 0a 20 20 73 65 73 73  TE, &rc);.  sess
101c0 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 70 42  ionAppendByte(pB
101d0 75 66 2c 20 70 2d 3e 62 49 6e 64 69 72 65 63 74  uf, p->bIndirect
101e0 2c 20 26 72 63 29 3b 0a 0a 20 20 69 66 28 20 62  , &rc);..  if( b
101f0 50 61 74 63 68 73 65 74 3d 3d 30 20 29 7b 0a 20  Patchset==0 ){. 
10200 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
10210 42 6c 6f 62 28 70 42 75 66 2c 20 70 2d 3e 61 52  Blob(pBuf, p->aR
10220 65 63 6f 72 64 2c 20 70 2d 3e 6e 52 65 63 6f 72  ecord, p->nRecor
10230 64 2c 20 26 72 63 29 3b 0a 20 20 7d 65 6c 73 65  d, &rc);.  }else
10240 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20  {.    int i;.   
10250 20 75 38 20 2a 61 20 3d 20 70 2d 3e 61 52 65 63   u8 *a = p->aRec
10260 6f 72 64 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30  ord;.    for(i=0
10270 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a  ; i<nCol; i++){.
10280 20 20 20 20 20 20 75 38 20 2a 70 53 74 61 72 74        u8 *pStart
10290 20 3d 20 61 3b 0a 20 20 20 20 20 20 69 6e 74 20   = a;.      int 
102a0 65 54 79 70 65 20 3d 20 2a 61 2b 2b 3b 0a 0a 20  eType = *a++;.. 
102b0 20 20 20 20 20 73 77 69 74 63 68 28 20 65 54 79       switch( eTy
102c0 70 65 20 29 7b 0a 20 20 20 20 20 20 20 20 63 61  pe ){.        ca
102d0 73 65 20 30 3a 0a 20 20 20 20 20 20 20 20 63 61  se 0:.        ca
102e0 73 65 20 53 51 4c 49 54 45 5f 4e 55 4c 4c 3a 0a  se SQLITE_NULL:.
102f0 20 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74            assert
10300 28 20 61 62 50 4b 5b 69 5d 3d 3d 30 20 29 3b 0a  ( abPK[i]==0 );.
10310 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b            break;
10320 0a 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 53  ..        case S
10330 51 4c 49 54 45 5f 46 4c 4f 41 54 3a 0a 20 20 20  QLITE_FLOAT:.   
10340 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45       case SQLITE
10350 5f 49 4e 54 45 47 45 52 3a 0a 20 20 20 20 20 20  _INTEGER:.      
10360 20 20 20 20 61 20 2b 3d 20 38 3b 0a 20 20 20 20      a += 8;.    
10370 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20        break;..  
10380 20 20 20 20 20 20 64 65 66 61 75 6c 74 3a 20 7b        default: {
10390 0a 20 20 20 20 20 20 20 20 20 20 69 6e 74 20 6e  .          int n
103a0 3b 0a 20 20 20 20 20 20 20 20 20 20 61 20 2b 3d  ;.          a +=
103b0 20 73 65 73 73 69 6f 6e 56 61 72 69 6e 74 47 65   sessionVarintGe
103c0 74 28 61 2c 20 26 6e 29 3b 0a 20 20 20 20 20 20  t(a, &n);.      
103d0 20 20 20 20 61 20 2b 3d 20 6e 3b 0a 20 20 20 20      a += n;.    
103e0 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
103f0 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
10400 20 20 20 20 20 69 66 28 20 61 62 50 4b 5b 69 5d       if( abPK[i]
10410 20 29 7b 0a 20 20 20 20 20 20 20 20 73 65 73 73   ){.        sess
10420 69 6f 6e 41 70 70 65 6e 64 42 6c 6f 62 28 70 42  ionAppendBlob(pB
10430 75 66 2c 20 70 53 74 61 72 74 2c 20 28 69 6e 74  uf, pStart, (int
10440 29 28 61 2d 70 53 74 61 72 74 29 2c 20 26 72 63  )(a-pStart), &rc
10450 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
10460 0a 20 20 20 20 61 73 73 65 72 74 28 20 28 61 20  .    assert( (a 
10470 2d 20 70 2d 3e 61 52 65 63 6f 72 64 29 3d 3d 70  - p->aRecord)==p
10480 2d 3e 6e 52 65 63 6f 72 64 20 29 3b 0a 20 20 7d  ->nRecord );.  }
10490 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
104a0 0a 0a 2f 2a 0a 2a 2a 20 46 6f 72 6d 75 6c 61 74  ../*.** Formulat
104b0 65 20 61 6e 64 20 70 72 65 70 61 72 65 20 61 20  e and prepare a 
104c0 53 45 4c 45 43 54 20 73 74 61 74 65 6d 65 6e 74  SELECT statement
104d0 20 74 6f 20 72 65 74 72 69 65 76 65 20 61 20 72   to retrieve a r
104e0 6f 77 20 66 72 6f 6d 20 74 61 62 6c 65 0a 2a 2a  ow from table.**
104f0 20 7a 54 61 62 20 69 6e 20 64 61 74 61 62 61 73   zTab in databas
10500 65 20 7a 44 62 20 62 61 73 65 64 20 6f 6e 20 69  e zDb based on i
10510 74 73 20 70 72 69 6d 61 72 79 20 6b 65 79 2e 20  ts primary key. 
10520 69 2e 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 53 45 4c  i.e..**.**   SEL
10530 45 43 54 20 2a 20 46 52 4f 4d 20 7a 44 62 2e 7a  ECT * FROM zDb.z
10540 54 61 62 20 57 48 45 52 45 20 70 6b 31 20 3d 20  Tab WHERE pk1 = 
10550 3f 20 41 4e 44 20 70 6b 32 20 3d 20 3f 20 41 4e  ? AND pk2 = ? AN
10560 44 20 2e 2e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  D ....*/.static 
10570 69 6e 74 20 73 65 73 73 69 6f 6e 53 65 6c 65 63  int sessionSelec
10580 74 53 74 6d 74 28 0a 20 20 73 71 6c 69 74 65 33  tStmt(.  sqlite3
10590 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20 20   *db,           
105a0 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
105b0 62 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20  base handle */. 
105c0 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62   const char *zDb
105d0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
105e0 20 2f 2a 20 44 61 74 61 62 61 73 65 20 6e 61 6d   /* Database nam
105f0 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  e */.  const cha
10600 72 20 2a 7a 54 61 62 2c 20 20 20 20 20 20 20 20  r *zTab,        
10610 20 20 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20         /* Table 
10620 6e 61 6d 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 43  name */.  int nC
10630 6f 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ol,             
10640 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
10650 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69  ber of columns i
10660 6e 20 74 61 62 6c 65 20 2a 2f 0a 20 20 63 6f 6e  n table */.  con
10670 73 74 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6c 2c  st char **azCol,
10680 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
10690 4e 61 6d 65 73 20 6f 66 20 74 61 62 6c 65 20 63  Names of table c
106a0 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 75 38 20 2a  olumns */.  u8 *
106b0 61 62 50 4b 2c 20 20 20 20 20 20 20 20 20 20 20  abPK,           
106c0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
106d0 52 49 4d 41 52 59 20 4b 45 59 20 20 61 72 72 61  RIMARY KEY  arra
106e0 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73  y */.  sqlite3_s
106f0 74 6d 74 20 2a 2a 70 70 53 74 6d 74 20 20 20 20  tmt **ppStmt    
10700 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 50         /* OUT: P
10710 72 65 70 61 72 65 64 20 53 45 4c 45 43 54 20 73  repared SELECT s
10720 74 61 74 65 6d 65 6e 74 20 2a 2f 0a 29 7b 0a 20  tatement */.){. 
10730 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
10740 5f 4f 4b 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  _OK;.  int i;.  
10750 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 65 70  const char *zSep
10760 20 3d 20 22 22 3b 0a 20 20 53 65 73 73 69 6f 6e   = "";.  Session
10770 42 75 66 66 65 72 20 62 75 66 20 3d 20 7b 30 2c  Buffer buf = {0,
10780 20 30 2c 20 30 7d 3b 0a 0a 20 20 73 65 73 73 69   0, 0};..  sessi
10790 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75 66  onAppendStr(&buf
107a0 2c 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d  , "SELECT * FROM
107b0 20 22 2c 20 26 72 63 29 3b 0a 20 20 73 65 73 73   ", &rc);.  sess
107c0 69 6f 6e 41 70 70 65 6e 64 49 64 65 6e 74 28 26  ionAppendIdent(&
107d0 62 75 66 2c 20 7a 44 62 2c 20 26 72 63 29 3b 0a  buf, zDb, &rc);.
107e0 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53    sessionAppendS
107f0 74 72 28 26 62 75 66 2c 20 22 2e 22 2c 20 26 72  tr(&buf, ".", &r
10800 63 29 3b 0a 20 20 73 65 73 73 69 6f 6e 41 70 70  c);.  sessionApp
10810 65 6e 64 49 64 65 6e 74 28 26 62 75 66 2c 20 7a  endIdent(&buf, z
10820 54 61 62 2c 20 26 72 63 29 3b 0a 20 20 73 65 73  Tab, &rc);.  ses
10830 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62  sionAppendStr(&b
10840 75 66 2c 20 22 20 57 48 45 52 45 20 22 2c 20 26  uf, " WHERE ", &
10850 72 63 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  rc);.  for(i=0; 
10860 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20  i<nCol; i++){.  
10870 20 20 69 66 28 20 61 62 50 4b 5b 69 5d 20 29 7b    if( abPK[i] ){
10880 0a 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70  .      sessionAp
10890 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 7a 53  pendStr(&buf, zS
108a0 65 70 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20  ep, &rc);.      
108b0 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49 64 65  sessionAppendIde
108c0 6e 74 28 26 62 75 66 2c 20 61 7a 43 6f 6c 5b 69  nt(&buf, azCol[i
108d0 5d 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 73  ], &rc);.      s
108e0 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28  essionAppendStr(
108f0 26 62 75 66 2c 20 22 20 3d 20 3f 22 2c 20 26 72  &buf, " = ?", &r
10900 63 29 3b 0a 20 20 20 20 20 20 73 65 73 73 69 6f  c);.      sessio
10910 6e 41 70 70 65 6e 64 49 6e 74 65 67 65 72 28 26  nAppendInteger(&
10920 62 75 66 2c 20 69 2b 31 2c 20 26 72 63 29 3b 0a  buf, i+1, &rc);.
10930 20 20 20 20 20 20 7a 53 65 70 20 3d 20 22 20 41        zSep = " A
10940 4e 44 20 22 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  ND ";.    }.  }.
10950 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
10960 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
10970 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 5f  sqlite3_prepare_
10980 76 32 28 64 62 2c 20 28 63 68 61 72 20 2a 29 62  v2(db, (char *)b
10990 75 66 2e 61 42 75 66 2c 20 62 75 66 2e 6e 42 75  uf.aBuf, buf.nBu
109a0 66 2c 20 70 70 53 74 6d 74 2c 20 30 29 3b 0a 20  f, ppStmt, 0);. 
109b0 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65   }.  sqlite3_fre
109c0 65 28 62 75 66 2e 61 42 75 66 29 3b 0a 20 20 72  e(buf.aBuf);.  r
109d0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
109e0 2a 2a 20 42 69 6e 64 20 74 68 65 20 50 52 49 4d  ** Bind the PRIM
109f0 41 52 59 20 4b 45 59 20 76 61 6c 75 65 73 20 66  ARY KEY values f
10a00 72 6f 6d 20 74 68 65 20 63 68 61 6e 67 65 20 70  rom the change p
10a10 61 73 73 65 64 20 69 6e 20 61 72 67 75 6d 65 6e  assed in argumen
10a20 74 20 70 43 68 61 6e 67 65 0a 2a 2a 20 74 6f 20  t pChange.** to 
10a30 74 68 65 20 53 45 4c 45 43 54 20 73 74 61 74 65  the SELECT state
10a40 6d 65 6e 74 20 70 61 73 73 65 64 20 61 73 20 74  ment passed as t
10a50 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e  he first argumen
10a60 74 2e 20 54 68 65 20 53 45 4c 45 43 54 20 73 74  t. The SELECT st
10a70 61 74 65 6d 65 6e 74 0a 2a 2a 20 69 73 20 61 73  atement.** is as
10a80 20 70 72 65 70 61 72 65 64 20 62 79 20 66 75 6e   prepared by fun
10a90 63 74 69 6f 6e 20 73 65 73 73 69 6f 6e 53 65 6c  ction sessionSel
10aa0 65 63 74 53 74 6d 74 28 29 2e 0a 2a 2a 0a 2a 2a  ectStmt()..**.**
10ab0 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   Return SQLITE_O
10ac0 4b 20 69 66 20 61 6c 6c 20 50 4b 20 76 61 6c 75  K if all PK valu
10ad0 65 73 20 61 72 65 20 73 75 63 63 65 73 73 66 75  es are successfu
10ae0 6c 6c 79 20 62 6f 75 6e 64 2c 20 6f 72 20 61 6e  lly bound, or an
10af0 20 53 51 4c 69 74 65 0a 2a 2a 20 65 72 72 6f 72   SQLite.** error
10b00 20 63 6f 64 65 20 28 65 2e 67 2e 20 53 51 4c 49   code (e.g. SQLI
10b10 54 45 5f 4e 4f 4d 45 4d 29 20 6f 74 68 65 72 77  TE_NOMEM) otherw
10b20 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ise..*/.static i
10b30 6e 74 20 73 65 73 73 69 6f 6e 53 65 6c 65 63 74  nt sessionSelect
10b40 42 69 6e 64 28 0a 20 20 73 71 6c 69 74 65 33 5f  Bind(.  sqlite3_
10b50 73 74 6d 74 20 2a 70 53 65 6c 65 63 74 2c 20 20  stmt *pSelect,  
10b60 20 20 20 20 20 20 20 20 2f 2a 20 53 45 4c 45 43          /* SELEC
10b70 54 20 66 72 6f 6d 20 73 65 73 73 69 6f 6e 53 65  T from sessionSe
10b80 6c 65 63 74 53 74 6d 74 28 29 20 2a 2f 0a 20 20  lectStmt() */.  
10b90 69 6e 74 20 6e 43 6f 6c 2c 20 20 20 20 20 20 20  int nCol,       
10ba0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10bb0 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c  /* Number of col
10bc0 75 6d 6e 73 20 69 6e 20 74 61 62 6c 65 20 2a 2f  umns in table */
10bd0 0a 20 20 75 38 20 2a 61 62 50 4b 2c 20 20 20 20  .  u8 *abPK,    
10be0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10bf0 20 20 20 2f 2a 20 50 52 49 4d 41 52 59 20 4b 45     /* PRIMARY KE
10c00 59 20 61 72 72 61 79 20 2a 2f 0a 20 20 53 65 73  Y array */.  Ses
10c10 73 69 6f 6e 43 68 61 6e 67 65 20 2a 70 43 68 61  sionChange *pCha
10c20 6e 67 65 20 20 20 20 20 20 20 20 20 20 2f 2a 20  nge          /* 
10c30 43 68 61 6e 67 65 20 73 74 72 75 63 74 75 72 65  Change structure
10c40 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a   */.){.  int i;.
10c50 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
10c60 45 5f 4f 4b 3b 0a 20 20 75 38 20 2a 61 20 3d 20  E_OK;.  u8 *a = 
10c70 70 43 68 61 6e 67 65 2d 3e 61 52 65 63 6f 72 64  pChange->aRecord
10c80 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  ;..  for(i=0; i<
10c90 6e 43 6f 6c 20 26 26 20 72 63 3d 3d 53 51 4c 49  nCol && rc==SQLI
10ca0 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20 20  TE_OK; i++){.   
10cb0 20 69 6e 74 20 65 54 79 70 65 20 3d 20 2a 61 2b   int eType = *a+
10cc0 2b 3b 0a 0a 20 20 20 20 73 77 69 74 63 68 28 20  +;..    switch( 
10cd0 65 54 79 70 65 20 29 7b 0a 20 20 20 20 20 20 63  eType ){.      c
10ce0 61 73 65 20 30 3a 0a 20 20 20 20 20 20 63 61 73  ase 0:.      cas
10cf0 65 20 53 51 4c 49 54 45 5f 4e 55 4c 4c 3a 0a 20  e SQLITE_NULL:. 
10d00 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20 61         assert( a
10d10 62 50 4b 5b 69 5d 3d 3d 30 20 29 3b 0a 20 20 20  bPK[i]==0 );.   
10d20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20       break;..   
10d30 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49     case SQLITE_I
10d40 4e 54 45 47 45 52 3a 20 7b 0a 20 20 20 20 20 20  NTEGER: {.      
10d50 20 20 69 66 28 20 61 62 50 4b 5b 69 5d 20 29 7b    if( abPK[i] ){
10d60 0a 20 20 20 20 20 20 20 20 20 20 69 36 34 20 69  .          i64 i
10d70 56 61 6c 20 3d 20 73 65 73 73 69 6f 6e 47 65 74  Val = sessionGet
10d80 49 36 34 28 61 29 3b 0a 20 20 20 20 20 20 20 20  I64(a);.        
10d90 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62    rc = sqlite3_b
10da0 69 6e 64 5f 69 6e 74 36 34 28 70 53 65 6c 65 63  ind_int64(pSelec
10db0 74 2c 20 69 2b 31 2c 20 69 56 61 6c 29 3b 0a 20  t, i+1, iVal);. 
10dc0 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
10dd0 20 61 20 2b 3d 20 38 3b 0a 20 20 20 20 20 20 20   a += 8;.       
10de0 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
10df0 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
10e00 54 45 5f 46 4c 4f 41 54 3a 20 7b 0a 20 20 20 20  TE_FLOAT: {.    
10e10 20 20 20 20 69 66 28 20 61 62 50 4b 5b 69 5d 20      if( abPK[i] 
10e20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 64 6f 75  ){.          dou
10e30 62 6c 65 20 72 56 61 6c 3b 0a 20 20 20 20 20 20  ble rVal;.      
10e40 20 20 20 20 69 36 34 20 69 56 61 6c 20 3d 20 73      i64 iVal = s
10e50 65 73 73 69 6f 6e 47 65 74 49 36 34 28 61 29 3b  essionGetI64(a);
10e60 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63 70  .          memcp
10e70 79 28 26 72 56 61 6c 2c 20 26 69 56 61 6c 2c 20  y(&rVal, &iVal, 
10e80 38 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63  8);.          rc
10e90 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f   = sqlite3_bind_
10ea0 64 6f 75 62 6c 65 28 70 53 65 6c 65 63 74 2c 20  double(pSelect, 
10eb0 69 2b 31 2c 20 72 56 61 6c 29 3b 0a 20 20 20 20  i+1, rVal);.    
10ec0 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 61 20      }.        a 
10ed0 2b 3d 20 38 3b 0a 20 20 20 20 20 20 20 20 62 72  += 8;.        br
10ee0 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20  eak;.      }..  
10ef0 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
10f00 54 45 58 54 3a 20 7b 0a 20 20 20 20 20 20 20 20  TEXT: {.        
10f10 69 6e 74 20 6e 3b 0a 20 20 20 20 20 20 20 20 61  int n;.        a
10f20 20 2b 3d 20 73 65 73 73 69 6f 6e 56 61 72 69 6e   += sessionVarin
10f30 74 47 65 74 28 61 2c 20 26 6e 29 3b 0a 20 20 20  tGet(a, &n);.   
10f40 20 20 20 20 20 69 66 28 20 61 62 50 4b 5b 69 5d       if( abPK[i]
10f50 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63   ){.          rc
10f60 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f   = sqlite3_bind_
10f70 74 65 78 74 28 70 53 65 6c 65 63 74 2c 20 69 2b  text(pSelect, i+
10f80 31 2c 20 28 63 68 61 72 20 2a 29 61 2c 20 6e 2c  1, (char *)a, n,
10f90 20 53 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e   SQLITE_TRANSIEN
10fa0 54 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  T);.        }.  
10fb0 20 20 20 20 20 20 61 20 2b 3d 20 6e 3b 0a 20 20        a += n;.  
10fc0 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
10fd0 20 20 20 7d 0a 0a 20 20 20 20 20 20 64 65 66 61     }..      defa
10fe0 75 6c 74 3a 20 7b 0a 20 20 20 20 20 20 20 20 69  ult: {.        i
10ff0 6e 74 20 6e 3b 0a 20 20 20 20 20 20 20 20 61 73  nt n;.        as
11000 73 65 72 74 28 20 65 54 79 70 65 3d 3d 53 51 4c  sert( eType==SQL
11010 49 54 45 5f 42 4c 4f 42 20 29 3b 0a 20 20 20 20  ITE_BLOB );.    
11020 20 20 20 20 61 20 2b 3d 20 73 65 73 73 69 6f 6e      a += session
11030 56 61 72 69 6e 74 47 65 74 28 61 2c 20 26 6e 29  VarintGet(a, &n)
11040 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 61 62  ;.        if( ab
11050 50 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20 20  PK[i] ){.       
11060 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
11070 62 69 6e 64 5f 62 6c 6f 62 28 70 53 65 6c 65 63  bind_blob(pSelec
11080 74 2c 20 69 2b 31 2c 20 61 2c 20 6e 2c 20 53 51  t, i+1, a, n, SQ
11090 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b  LITE_TRANSIENT);
110a0 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
110b0 20 20 20 61 20 2b 3d 20 6e 3b 0a 20 20 20 20 20     a += n;.     
110c0 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
110d0 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  }.    }.  }..  r
110e0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
110f0 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
11100 20 69 73 20 61 20 6e 6f 2d 6f 70 20 69 66 20 2a   is a no-op if *
11110 70 52 63 20 69 73 20 73 65 74 20 74 6f 20 6f 74  pRc is set to ot
11120 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45 5f  her than SQLITE_
11130 4f 4b 20 77 68 65 6e 20 69 74 0a 2a 2a 20 69 73  OK when it.** is
11140 20 63 61 6c 6c 65 64 2e 20 4f 74 68 65 72 77 69   called. Otherwi
11150 73 65 2c 20 61 70 70 65 6e 64 20 61 20 73 65 72  se, append a ser
11160 69 61 6c 69 7a 65 64 20 74 61 62 6c 65 20 68 65  ialized table he
11170 61 64 65 72 20 28 70 61 72 74 20 6f 66 20 74 68  ader (part of th
11180 65 20 62 69 6e 61 72 79 20 0a 2a 2a 20 63 68 61  e binary .** cha
11190 6e 67 65 73 65 74 20 66 6f 72 6d 61 74 29 20 74  ngeset format) t
111a0 6f 20 62 75 66 66 65 72 20 2a 70 42 75 66 2e 20  o buffer *pBuf. 
111b0 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  If an error occu
111c0 72 73 2c 20 73 65 74 20 2a 70 52 63 20 74 6f 20  rs, set *pRc to 
111d0 61 6e 0a 2a 2a 20 53 51 4c 69 74 65 20 65 72 72  an.** SQLite err
111e0 6f 72 20 63 6f 64 65 20 62 65 66 6f 72 65 20 72  or code before r
111f0 65 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61  eturning..*/.sta
11200 74 69 63 20 76 6f 69 64 20 73 65 73 73 69 6f 6e  tic void session
11210 41 70 70 65 6e 64 54 61 62 6c 65 48 64 72 28 0a  AppendTableHdr(.
11220 20 20 53 65 73 73 69 6f 6e 42 75 66 66 65 72 20    SessionBuffer 
11230 2a 70 42 75 66 2c 20 20 20 20 20 20 20 20 20 20  *pBuf,          
11240 20 20 2f 2a 20 41 70 70 65 6e 64 20 68 65 61 64    /* Append head
11250 65 72 20 74 6f 20 74 68 69 73 20 62 75 66 66 65  er to this buffe
11260 72 20 2a 2f 0a 20 20 69 6e 74 20 62 50 61 74 63  r */.  int bPatc
11270 68 73 65 74 2c 20 20 20 20 20 20 20 20 20 20 20  hset,           
11280 20 20 20 20 20 20 20 2f 2a 20 55 73 65 20 74 68         /* Use th
11290 65 20 70 61 74 63 68 73 65 74 20 66 6f 72 6d 61  e patchset forma
112a0 74 20 69 66 20 74 72 75 65 20 2a 2f 0a 20 20 53  t if true */.  S
112b0 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70 54 61  essionTable *pTa
112c0 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  b,             /
112d0 2a 20 54 61 62 6c 65 20 6f 62 6a 65 63 74 20 74  * Table object t
112e0 6f 20 61 70 70 65 6e 64 20 68 65 61 64 65 72 20  o append header 
112f0 66 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 52  for */.  int *pR
11300 63 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c               
11310 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f           /* IN/O
11320 55 54 3a 20 45 72 72 6f 72 20 63 6f 64 65 20 2a  UT: Error code *
11330 2f 0a 29 7b 0a 20 20 2f 2a 20 57 72 69 74 65 20  /.){.  /* Write 
11340 61 20 74 61 62 6c 65 20 68 65 61 64 65 72 20 2a  a table header *
11350 2f 0a 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e  /.  sessionAppen
11360 64 42 79 74 65 28 70 42 75 66 2c 20 28 62 50 61  dByte(pBuf, (bPa
11370 74 63 68 73 65 74 20 3f 20 27 50 27 20 3a 20 27  tchset ? 'P' : '
11380 54 27 29 2c 20 70 52 63 29 3b 0a 20 20 73 65 73  T'), pRc);.  ses
11390 73 69 6f 6e 41 70 70 65 6e 64 56 61 72 69 6e 74  sionAppendVarint
113a0 28 70 42 75 66 2c 20 70 54 61 62 2d 3e 6e 43 6f  (pBuf, pTab->nCo
113b0 6c 2c 20 70 52 63 29 3b 0a 20 20 73 65 73 73 69  l, pRc);.  sessi
113c0 6f 6e 41 70 70 65 6e 64 42 6c 6f 62 28 70 42 75  onAppendBlob(pBu
113d0 66 2c 20 70 54 61 62 2d 3e 61 62 50 4b 2c 20 70  f, pTab->abPK, p
113e0 54 61 62 2d 3e 6e 43 6f 6c 2c 20 70 52 63 29 3b  Tab->nCol, pRc);
113f0 0a 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64  .  sessionAppend
11400 42 6c 6f 62 28 70 42 75 66 2c 20 28 75 38 20 2a  Blob(pBuf, (u8 *
11410 29 70 54 61 62 2d 3e 7a 4e 61 6d 65 2c 20 28 69  )pTab->zName, (i
11420 6e 74 29 73 74 72 6c 65 6e 28 70 54 61 62 2d 3e  nt)strlen(pTab->
11430 7a 4e 61 6d 65 29 2b 31 2c 20 70 52 63 29 3b 0a  zName)+1, pRc);.
11440 7d 0a 0a 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61 74  }../*.** Generat
11450 65 20 65 69 74 68 65 72 20 61 20 63 68 61 6e 67  e either a chang
11460 65 73 65 74 20 28 69 66 20 61 72 67 75 6d 65 6e  eset (if argumen
11470 74 20 62 50 61 74 63 68 73 65 74 20 69 73 20 7a  t bPatchset is z
11480 65 72 6f 29 20 6f 72 20 61 20 70 61 74 63 68 73  ero) or a patchs
11490 65 74 0a 2a 2a 20 28 69 66 20 69 74 20 69 73 20  et.** (if it is 
114a0 6e 6f 6e 2d 7a 65 72 6f 29 20 62 61 73 65 64 20  non-zero) based 
114b0 6f 6e 20 74 68 65 20 63 75 72 72 65 6e 74 20 63  on the current c
114c0 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 73  ontents of the s
114d0 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 0a 2a 2a  ession object.**
114e0 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66   passed as the f
114f0 69 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a  irst argument..*
11500 2a 0a 2a 2a 20 49 66 20 6e 6f 20 65 72 72 6f 72  *.** If no error
11510 20 6f 63 63 75 72 73 2c 20 53 51 4c 49 54 45 5f   occurs, SQLITE_
11520 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 61  OK is returned a
11530 6e 64 20 74 68 65 20 6e 65 77 20 63 68 61 6e 67  nd the new chang
11540 65 73 65 74 2f 70 61 74 63 68 73 65 74 0a 2a 2a  eset/patchset.**
11550 20 73 74 6f 72 65 64 20 69 6e 20 6f 75 74 70 75   stored in outpu
11560 74 20 76 61 72 69 61 62 6c 65 73 20 2a 70 6e 43  t variables *pnC
11570 68 61 6e 67 65 73 65 74 20 61 6e 64 20 2a 70 70  hangeset and *pp
11580 43 68 61 6e 67 65 73 65 74 2e 20 4f 72 2c 20 69  Changeset. Or, i
11590 66 20 61 6e 20 65 72 72 6f 72 0a 2a 2a 20 6f 63  f an error.** oc
115a0 63 75 72 73 2c 20 61 6e 20 53 51 4c 69 74 65 20  curs, an SQLite 
115b0 65 72 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65  error code is re
115c0 74 75 72 6e 65 64 20 61 6e 64 20 62 6f 74 68 20  turned and both 
115d0 6f 75 74 70 75 74 20 76 61 72 69 61 62 6c 65 73  output variables
115e0 20 73 65 74 20 0a 2a 2a 20 74 6f 20 30 2e 0a 2a   set .** to 0..*
115f0 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73  /.static int ses
11600 73 69 6f 6e 47 65 6e 65 72 61 74 65 43 68 61 6e  sionGenerateChan
11610 67 65 73 65 74 28 0a 20 20 73 71 6c 69 74 65 33  geset(.  sqlite3
11620 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69  _session *pSessi
11630 6f 6e 2c 20 20 20 20 20 20 2f 2a 20 53 65 73 73  on,      /* Sess
11640 69 6f 6e 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20  ion object */.  
11650 69 6e 74 20 62 50 61 74 63 68 73 65 74 2c 20 20  int bPatchset,  
11660 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11670 2f 2a 20 54 72 75 65 20 66 6f 72 20 70 61 74 63  /* True for patc
11680 68 73 65 74 2c 20 66 61 6c 73 65 20 66 6f 72 20  hset, false for 
11690 63 68 61 6e 67 65 73 65 74 20 2a 2f 0a 20 20 69  changeset */.  i
116a0 6e 74 20 28 2a 78 4f 75 74 70 75 74 29 28 76 6f  nt (*xOutput)(vo
116b0 69 64 20 2a 70 4f 75 74 2c 20 63 6f 6e 73 74 20  id *pOut, const 
116c0 76 6f 69 64 20 2a 70 44 61 74 61 2c 20 69 6e 74  void *pData, int
116d0 20 6e 44 61 74 61 29 2c 0a 20 20 76 6f 69 64 20   nData),.  void 
116e0 2a 70 4f 75 74 2c 20 20 20 20 20 20 20 20 20 20  *pOut,          
116f0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69             /* Fi
11700 72 73 74 20 61 72 67 75 6d 65 6e 74 20 66 6f 72  rst argument for
11710 20 78 4f 75 74 70 75 74 20 2a 2f 0a 20 20 69 6e   xOutput */.  in
11720 74 20 2a 70 6e 43 68 61 6e 67 65 73 65 74 2c 20  t *pnChangeset, 
11730 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
11740 20 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20 62 75   OUT: Size of bu
11750 66 66 65 72 20 61 74 20 2a 70 70 43 68 61 6e 67  ffer at *ppChang
11760 65 73 65 74 20 2a 2f 0a 20 20 76 6f 69 64 20 2a  eset */.  void *
11770 2a 70 70 43 68 61 6e 67 65 73 65 74 20 20 20 20  *ppChangeset    
11780 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
11790 3a 20 42 75 66 66 65 72 20 63 6f 6e 74 61 69 6e  : Buffer contain
117a0 69 6e 67 20 63 68 61 6e 67 65 73 65 74 20 2a 2f  ing changeset */
117b0 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  .){.  sqlite3 *d
117c0 62 20 3d 20 70 53 65 73 73 69 6f 6e 2d 3e 64 62  b = pSession->db
117d0 3b 20 20 20 20 20 2f 2a 20 53 6f 75 72 63 65 20  ;     /* Source 
117e0 64 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20  database handle 
117f0 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 54 61 62 6c  */.  SessionTabl
11800 65 20 2a 70 54 61 62 3b 20 20 20 20 20 20 20 20  e *pTab;        
11810 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20       /* Used to 
11820 69 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20  iterate through 
11830 61 74 74 61 63 68 65 64 20 74 61 62 6c 65 73 20  attached tables 
11840 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66  */.  SessionBuff
11850 65 72 20 62 75 66 20 3d 20 7b 30 2c 30 2c 30 7d  er buf = {0,0,0}
11860 3b 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 69  ;    /* Buffer i
11870 6e 20 77 68 69 63 68 20 74 6f 20 61 63 63 75 6d  n which to accum
11880 6c 61 74 65 20 63 68 61 6e 67 65 73 65 74 20 2a  late changeset *
11890 2f 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  /.  int rc;     
118a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
118b0 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f      /* Return co
118c0 64 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28  de */..  assert(
118d0 20 78 4f 75 74 70 75 74 3d 3d 30 20 7c 7c 20 28   xOutput==0 || (
118e0 70 6e 43 68 61 6e 67 65 73 65 74 3d 3d 30 20 26  pnChangeset==0 &
118f0 26 20 70 70 43 68 61 6e 67 65 73 65 74 3d 3d 30  & ppChangeset==0
11900 20 29 20 29 3b 0a 0a 20 20 2f 2a 20 5a 65 72 6f   ) );..  /* Zero
11910 20 74 68 65 20 6f 75 74 70 75 74 20 76 61 72 69   the output vari
11920 61 62 6c 65 73 20 69 6e 20 63 61 73 65 20 61 6e  ables in case an
11930 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 20 49   error occurs. I
11940 66 20 74 68 69 73 20 73 65 73 73 69 6f 6e 0a 20  f this session. 
11950 20 2a 2a 20 6f 62 6a 65 63 74 20 69 73 20 61 6c   ** object is al
11960 72 65 61 64 79 20 69 6e 20 74 68 65 20 65 72 72  ready in the err
11970 6f 72 20 73 74 61 74 65 20 28 73 71 6c 69 74 65  or state (sqlite
11980 33 5f 73 65 73 73 69 6f 6e 2e 72 63 20 21 3d 20  3_session.rc != 
11990 53 51 4c 49 54 45 5f 4f 4b 29 2c 0a 20 20 2a 2a  SQLITE_OK),.  **
119a0 20 74 68 69 73 20 63 61 6c 6c 20 77 69 6c 6c 20   this call will 
119b0 62 65 20 61 20 6e 6f 2d 6f 70 2e 20 20 2a 2f 0a  be a no-op.  */.
119c0 20 20 69 66 28 20 78 4f 75 74 70 75 74 3d 3d 30    if( xOutput==0
119d0 20 29 7b 0a 20 20 20 20 2a 70 6e 43 68 61 6e 67   ){.    *pnChang
119e0 65 73 65 74 20 3d 20 30 3b 0a 20 20 20 20 2a 70  eset = 0;.    *p
119f0 70 43 68 61 6e 67 65 73 65 74 20 3d 20 30 3b 0a  pChangeset = 0;.
11a00 20 20 7d 0a 0a 20 20 69 66 28 20 70 53 65 73 73    }..  if( pSess
11a10 69 6f 6e 2d 3e 72 63 20 29 20 72 65 74 75 72 6e  ion->rc ) return
11a20 20 70 53 65 73 73 69 6f 6e 2d 3e 72 63 3b 0a 20   pSession->rc;. 
11a30 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78   rc = sqlite3_ex
11a40 65 63 28 70 53 65 73 73 69 6f 6e 2d 3e 64 62 2c  ec(pSession->db,
11a50 20 22 53 41 56 45 50 4f 49 4e 54 20 63 68 61 6e   "SAVEPOINT chan
11a60 67 65 73 65 74 22 2c 20 30 2c 20 30 2c 20 30 29  geset", 0, 0, 0)
11a70 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
11a80 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
11a90 63 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75  c;..  sqlite3_mu
11aa0 74 65 78 5f 65 6e 74 65 72 28 73 71 6c 69 74 65  tex_enter(sqlite
11ab0 33 5f 64 62 5f 6d 75 74 65 78 28 64 62 29 29 3b  3_db_mutex(db));
11ac0 0a 0a 20 20 66 6f 72 28 70 54 61 62 3d 70 53 65  ..  for(pTab=pSe
11ad0 73 73 69 6f 6e 2d 3e 70 54 61 62 6c 65 3b 20 72  ssion->pTable; r
11ae0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
11af0 70 54 61 62 3b 20 70 54 61 62 3d 70 54 61 62 2d  pTab; pTab=pTab-
11b00 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 69 66 28  >pNext){.    if(
11b10 20 70 54 61 62 2d 3e 6e 45 6e 74 72 79 20 29 7b   pTab->nEntry ){
11b20 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61  .      const cha
11b30 72 20 2a 7a 4e 61 6d 65 20 3d 20 70 54 61 62 2d  r *zName = pTab-
11b40 3e 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 20 69 6e  >zName;.      in
11b50 74 20 6e 43 6f 6c 3b 20 20 20 20 20 20 20 20 20  t nCol;         
11b60 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
11b70 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69  ber of columns i
11b80 6e 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20 20  n table */.     
11b90 20 75 38 20 2a 61 62 50 4b 3b 20 20 20 20 20 20   u8 *abPK;      
11ba0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
11bb0 50 72 69 6d 61 72 79 20 6b 65 79 20 61 72 72 61  Primary key arra
11bc0 79 20 2a 2f 0a 20 20 20 20 20 20 63 6f 6e 73 74  y */.      const
11bd0 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6c 20 3d 20   char **azCol = 
11be0 30 3b 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20  0;     /* Table 
11bf0 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 20 20 20  columns */.     
11c00 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20   int i;         
11c10 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
11c20 55 73 65 64 20 74 6f 20 69 74 65 72 61 74 65 20  Used to iterate 
11c30 74 68 72 6f 75 67 68 20 68 61 73 68 20 62 75 63  through hash buc
11c40 6b 65 74 73 20 2a 2f 0a 20 20 20 20 20 20 73 71  kets */.      sq
11c50 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 65 6c  lite3_stmt *pSel
11c60 20 3d 20 30 3b 20 20 20 20 20 2f 2a 20 53 45 4c   = 0;     /* SEL
11c70 45 43 54 20 73 74 61 74 65 6d 65 6e 74 20 74 6f  ECT statement to
11c80 20 71 75 65 72 79 20 74 61 62 6c 65 20 70 54 61   query table pTa
11c90 62 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e  b */.      int n
11ca0 52 65 77 69 6e 64 20 3d 20 62 75 66 2e 6e 42 75  Rewind = buf.nBu
11cb0 66 3b 20 20 20 20 20 2f 2a 20 49 6e 69 74 69 61  f;     /* Initia
11cc0 6c 20 73 69 7a 65 20 6f 66 20 77 72 69 74 65 20  l size of write 
11cd0 62 75 66 66 65 72 20 2a 2f 0a 20 20 20 20 20 20  buffer */.      
11ce0 69 6e 74 20 6e 4e 6f 6f 70 3b 20 20 20 20 20 20  int nNoop;      
11cf0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
11d00 69 7a 65 20 6f 66 20 62 75 66 66 65 72 20 61 66  ize of buffer af
11d10 74 65 72 20 77 72 69 74 69 6e 67 20 74 62 6c 20  ter writing tbl 
11d20 68 65 61 64 65 72 20 2a 2f 0a 0a 20 20 20 20 20  header */..     
11d30 20 2f 2a 20 43 68 65 63 6b 20 74 68 65 20 74 61   /* Check the ta
11d40 62 6c 65 20 73 63 68 65 6d 61 20 69 73 20 73 74  ble schema is st
11d50 69 6c 6c 20 4f 6b 2e 20 2a 2f 0a 20 20 20 20 20  ill Ok. */.     
11d60 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 54 61 62   rc = sessionTab
11d70 6c 65 49 6e 66 6f 28 64 62 2c 20 70 53 65 73 73  leInfo(db, pSess
11d80 69 6f 6e 2d 3e 7a 44 62 2c 20 7a 4e 61 6d 65 2c  ion->zDb, zName,
11d90 20 26 6e 43 6f 6c 2c 20 30 2c 20 26 61 7a 43 6f   &nCol, 0, &azCo
11da0 6c 2c 20 26 61 62 50 4b 29 3b 0a 20 20 20 20 20  l, &abPK);.     
11db0 20 69 66 28 20 21 72 63 20 26 26 20 28 70 54 61   if( !rc && (pTa
11dc0 62 2d 3e 6e 43 6f 6c 21 3d 6e 43 6f 6c 20 7c 7c  b->nCol!=nCol ||
11dd0 20 6d 65 6d 63 6d 70 28 61 62 50 4b 2c 20 70 54   memcmp(abPK, pT
11de0 61 62 2d 3e 61 62 50 4b 2c 20 6e 43 6f 6c 29 29  ab->abPK, nCol))
11df0 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d   ){.        rc =
11e00 20 53 51 4c 49 54 45 5f 53 43 48 45 4d 41 3b 0a   SQLITE_SCHEMA;.
11e10 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f        }..      /
11e20 2a 20 57 72 69 74 65 20 61 20 74 61 62 6c 65 20  * Write a table 
11e30 68 65 61 64 65 72 20 2a 2f 0a 20 20 20 20 20 20  header */.      
11e40 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 54 61 62  sessionAppendTab
11e50 6c 65 48 64 72 28 26 62 75 66 2c 20 62 50 61 74  leHdr(&buf, bPat
11e60 63 68 73 65 74 2c 20 70 54 61 62 2c 20 26 72 63  chset, pTab, &rc
11e70 29 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 42 75 69  );..      /* Bui
11e80 6c 64 20 61 6e 64 20 63 6f 6d 70 69 6c 65 20 61  ld and compile a
11e90 20 73 74 61 74 65 6d 65 6e 74 20 74 6f 20 65 78   statement to ex
11ea0 65 63 75 74 65 3a 20 2a 2f 0a 20 20 20 20 20 20  ecute: */.      
11eb0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
11ec0 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  K ){.        rc 
11ed0 3d 20 73 65 73 73 69 6f 6e 53 65 6c 65 63 74 53  = sessionSelectS
11ee0 74 6d 74 28 0a 20 20 20 20 20 20 20 20 20 20 20  tmt(.           
11ef0 20 64 62 2c 20 70 53 65 73 73 69 6f 6e 2d 3e 7a   db, pSession->z
11f00 44 62 2c 20 7a 4e 61 6d 65 2c 20 6e 43 6f 6c 2c  Db, zName, nCol,
11f10 20 61 7a 43 6f 6c 2c 20 61 62 50 4b 2c 20 26 70   azCol, abPK, &p
11f20 53 65 6c 29 3b 0a 20 20 20 20 20 20 7d 0a 0a 20  Sel);.      }.. 
11f30 20 20 20 20 20 6e 4e 6f 6f 70 20 3d 20 62 75 66       nNoop = buf
11f40 2e 6e 42 75 66 3b 0a 20 20 20 20 20 20 66 6f 72  .nBuf;.      for
11f50 28 69 3d 30 3b 20 69 3c 70 54 61 62 2d 3e 6e 43  (i=0; i<pTab->nC
11f60 68 61 6e 67 65 20 26 26 20 72 63 3d 3d 53 51 4c  hange && rc==SQL
11f70 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20  ITE_OK; i++){.  
11f80 20 20 20 20 20 20 53 65 73 73 69 6f 6e 43 68 61        SessionCha
11f90 6e 67 65 20 2a 70 3b 20 20 20 20 20 20 20 20 20  nge *p;         
11fa0 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72 61  /* Used to itera
11fb0 74 65 20 74 68 72 6f 75 67 68 20 63 68 61 6e 67  te through chang
11fc0 65 73 20 2a 2f 0a 0a 20 20 20 20 20 20 20 20 66  es */..        f
11fd0 6f 72 28 70 3d 70 54 61 62 2d 3e 61 70 43 68 61  or(p=pTab->apCha
11fe0 6e 67 65 5b 69 5d 3b 20 72 63 3d 3d 53 51 4c 49  nge[i]; rc==SQLI
11ff0 54 45 5f 4f 4b 20 26 26 20 70 3b 20 70 3d 70 2d  TE_OK && p; p=p-
12000 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 20  >pNext){.       
12010 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 53     rc = sessionS
12020 65 6c 65 63 74 42 69 6e 64 28 70 53 65 6c 2c 20  electBind(pSel, 
12030 6e 43 6f 6c 2c 20 61 62 50 4b 2c 20 70 29 3b 0a  nCol, abPK, p);.
12040 20 20 20 20 20 20 20 20 20 20 69 66 28 20 72 63            if( rc
12050 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 63 6f  !=SQLITE_OK ) co
12060 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 20 20  ntinue;.        
12070 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 73 74    if( sqlite3_st
12080 65 70 28 70 53 65 6c 29 3d 3d 53 51 4c 49 54 45  ep(pSel)==SQLITE
12090 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 20 20  _ROW ){.        
120a0 20 20 20 20 69 66 28 20 70 2d 3e 6f 70 3d 3d 53      if( p->op==S
120b0 51 4c 49 54 45 5f 49 4e 53 45 52 54 20 29 7b 0a  QLITE_INSERT ){.
120c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e                in
120d0 74 20 69 43 6f 6c 3b 0a 20 20 20 20 20 20 20 20  t iCol;.        
120e0 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70        sessionApp
120f0 65 6e 64 42 79 74 65 28 26 62 75 66 2c 20 53 51  endByte(&buf, SQ
12100 4c 49 54 45 5f 49 4e 53 45 52 54 2c 20 26 72 63  LITE_INSERT, &rc
12110 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  );.             
12120 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 79   sessionAppendBy
12130 74 65 28 26 62 75 66 2c 20 70 2d 3e 62 49 6e 64  te(&buf, p->bInd
12140 69 72 65 63 74 2c 20 26 72 63 29 3b 0a 20 20 20  irect, &rc);.   
12150 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 28 69             for(i
12160 43 6f 6c 3d 30 3b 20 69 43 6f 6c 3c 6e 43 6f 6c  Col=0; iCol<nCol
12170 3b 20 69 43 6f 6c 2b 2b 29 7b 0a 20 20 20 20 20  ; iCol++){.     
12180 20 20 20 20 20 20 20 20 20 20 20 73 65 73 73 69             sessi
12190 6f 6e 41 70 70 65 6e 64 43 6f 6c 28 26 62 75 66  onAppendCol(&buf
121a0 2c 20 70 53 65 6c 2c 20 69 43 6f 6c 2c 20 26 72  , pSel, iCol, &r
121b0 63 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  c);.            
121c0 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20    }.            
121d0 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20  }else{.         
121e0 20 20 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f       rc = sessio
121f0 6e 41 70 70 65 6e 64 55 70 64 61 74 65 28 26 62  nAppendUpdate(&b
12200 75 66 2c 20 62 50 61 74 63 68 73 65 74 2c 20 70  uf, bPatchset, p
12210 53 65 6c 2c 20 70 2c 20 61 62 50 4b 29 3b 0a 20  Sel, p, abPK);. 
12220 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20             }.   
12230 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28         }else if(
12240 20 70 2d 3e 6f 70 21 3d 53 51 4c 49 54 45 5f 49   p->op!=SQLITE_I
12250 4e 53 45 52 54 20 29 7b 0a 20 20 20 20 20 20 20  NSERT ){.       
12260 20 20 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f       rc = sessio
12270 6e 41 70 70 65 6e 64 44 65 6c 65 74 65 28 26 62  nAppendDelete(&b
12280 75 66 2c 20 62 50 61 74 63 68 73 65 74 2c 20 70  uf, bPatchset, p
12290 2c 20 6e 43 6f 6c 2c 20 61 62 50 4b 29 3b 0a 20  , nCol, abPK);. 
122a0 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
122b0 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
122c0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
122d0 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
122e0 65 33 5f 72 65 73 65 74 28 70 53 65 6c 29 3b 0a  e3_reset(pSel);.
122f0 20 20 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20            }..   
12300 20 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65         /* If the
12310 20 62 75 66 66 65 72 20 69 73 20 6e 6f 77 20 6c   buffer is now l
12320 61 72 67 65 72 20 74 68 61 6e 20 53 45 53 53 49  arger than SESSI
12330 4f 4e 53 5f 53 54 52 4d 5f 43 48 55 4e 4b 5f 53  ONS_STRM_CHUNK_S
12340 49 5a 45 2c 20 70 61 73 73 0a 20 20 20 20 20 20  IZE, pass.      
12350 20 20 20 20 2a 2a 20 69 74 73 20 63 6f 6e 74 65      ** its conte
12360 6e 74 73 20 74 6f 20 74 68 65 20 78 4f 75 74 70  nts to the xOutp
12370 75 74 28 29 20 63 61 6c 6c 62 61 63 6b 2e 20 2a  ut() callback. *
12380 2f 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  /.          if( 
12390 78 4f 75 74 70 75 74 20 0a 20 20 20 20 20 20 20  xOutput .       
123a0 20 20 20 20 26 26 20 72 63 3d 3d 53 51 4c 49 54      && rc==SQLIT
123b0 45 5f 4f 4b 20 0a 20 20 20 20 20 20 20 20 20 20  E_OK .          
123c0 20 26 26 20 62 75 66 2e 6e 42 75 66 3e 6e 4e 6f   && buf.nBuf>nNo
123d0 6f 70 20 0a 20 20 20 20 20 20 20 20 20 20 20 26  op .           &
123e0 26 20 62 75 66 2e 6e 42 75 66 3e 53 45 53 53 49  & buf.nBuf>SESSI
123f0 4f 4e 53 5f 53 54 52 4d 5f 43 48 55 4e 4b 5f 53  ONS_STRM_CHUNK_S
12400 49 5a 45 20 0a 20 20 20 20 20 20 20 20 20 20 29  IZE .          )
12410 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 63  {.            rc
12420 20 3d 20 78 4f 75 74 70 75 74 28 70 4f 75 74 2c   = xOutput(pOut,
12430 20 28 76 6f 69 64 2a 29 62 75 66 2e 61 42 75 66   (void*)buf.aBuf
12440 2c 20 62 75 66 2e 6e 42 75 66 29 3b 0a 20 20 20  , buf.nBuf);.   
12450 20 20 20 20 20 20 20 20 20 6e 4e 6f 6f 70 20 3d           nNoop =
12460 20 2d 31 3b 0a 20 20 20 20 20 20 20 20 20 20 20   -1;.           
12470 20 62 75 66 2e 6e 42 75 66 20 3d 20 30 3b 0a 20   buf.nBuf = 0;. 
12480 20 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20           }..    
12490 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a 20      }.      }.. 
124a0 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6e       sqlite3_fin
124b0 61 6c 69 7a 65 28 70 53 65 6c 29 3b 0a 20 20 20  alize(pSel);.   
124c0 20 20 20 69 66 28 20 62 75 66 2e 6e 42 75 66 3d     if( buf.nBuf=
124d0 3d 6e 4e 6f 6f 70 20 29 7b 0a 20 20 20 20 20 20  =nNoop ){.      
124e0 20 20 62 75 66 2e 6e 42 75 66 20 3d 20 6e 52 65    buf.nBuf = nRe
124f0 77 69 6e 64 3b 0a 20 20 20 20 20 20 7d 0a 20 20  wind;.      }.  
12500 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
12510 28 28 63 68 61 72 2a 29 61 7a 43 6f 6c 29 3b 20  ((char*)azCol); 
12520 20 2f 2a 20 63 61 73 74 20 77 6f 72 6b 73 20 61   /* cast works a
12530 72 6f 75 6e 64 20 56 43 2b 2b 20 62 75 67 20 2a  round VC++ bug *
12540 2f 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  /.    }.  }..  i
12550 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
12560 20 29 7b 0a 20 20 20 20 69 66 28 20 78 4f 75 74   ){.    if( xOut
12570 70 75 74 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  put==0 ){.      
12580 2a 70 6e 43 68 61 6e 67 65 73 65 74 20 3d 20 62  *pnChangeset = b
12590 75 66 2e 6e 42 75 66 3b 0a 20 20 20 20 20 20 2a  uf.nBuf;.      *
125a0 70 70 43 68 61 6e 67 65 73 65 74 20 3d 20 62 75  ppChangeset = bu
125b0 66 2e 61 42 75 66 3b 0a 20 20 20 20 20 20 62 75  f.aBuf;.      bu
125c0 66 2e 61 42 75 66 20 3d 20 30 3b 0a 20 20 20 20  f.aBuf = 0;.    
125d0 7d 65 6c 73 65 20 69 66 28 20 62 75 66 2e 6e 42  }else if( buf.nB
125e0 75 66 3e 30 20 29 7b 0a 20 20 20 20 20 20 72 63  uf>0 ){.      rc
125f0 20 3d 20 78 4f 75 74 70 75 74 28 70 4f 75 74 2c   = xOutput(pOut,
12600 20 28 76 6f 69 64 2a 29 62 75 66 2e 61 42 75 66   (void*)buf.aBuf
12610 2c 20 62 75 66 2e 6e 42 75 66 29 3b 0a 20 20 20  , buf.nBuf);.   
12620 20 7d 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65   }.  }..  sqlite
12630 33 5f 66 72 65 65 28 62 75 66 2e 61 42 75 66 29  3_free(buf.aBuf)
12640 3b 0a 20 20 73 71 6c 69 74 65 33 5f 65 78 65 63  ;.  sqlite3_exec
12650 28 64 62 2c 20 22 52 45 4c 45 41 53 45 20 63 68  (db, "RELEASE ch
12660 61 6e 67 65 73 65 74 22 2c 20 30 2c 20 30 2c 20  angeset", 0, 0, 
12670 30 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75  0);.  sqlite3_mu
12680 74 65 78 5f 6c 65 61 76 65 28 73 71 6c 69 74 65  tex_leave(sqlite
12690 33 5f 64 62 5f 6d 75 74 65 78 28 64 62 29 29 3b  3_db_mutex(db));
126a0 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
126b0 0a 2f 2a 0a 2a 2a 20 4f 62 74 61 69 6e 20 61 20  ./*.** Obtain a 
126c0 63 68 61 6e 67 65 73 65 74 20 6f 62 6a 65 63 74  changeset object
126d0 20 63 6f 6e 74 61 69 6e 69 6e 67 20 61 6c 6c 20   containing all 
126e0 63 68 61 6e 67 65 73 20 72 65 63 6f 72 64 65 64  changes recorded
126f0 20 62 79 20 74 68 65 20 0a 2a 2a 20 73 65 73 73   by the .** sess
12700 69 6f 6e 20 6f 62 6a 65 63 74 20 70 61 73 73 65  ion object passe
12710 64 20 61 73 20 74 68 65 20 66 69 72 73 74 20 61  d as the first a
12720 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 49  rgument..**.** I
12730 74 20 69 73 20 74 68 65 20 72 65 73 70 6f 6e 73  t is the respons
12740 69 62 69 6c 69 74 79 20 6f 66 20 74 68 65 20 63  ibility of the c
12750 61 6c 6c 65 72 20 74 6f 20 65 76 65 6e 74 75 61  aller to eventua
12760 6c 6c 79 20 66 72 65 65 20 74 68 65 20 62 75 66  lly free the buf
12770 66 65 72 20 0a 2a 2a 20 75 73 69 6e 67 20 73 71  fer .** using sq
12780 6c 69 74 65 33 5f 66 72 65 65 28 29 2e 0a 2a 2f  lite3_free()..*/
12790 0a 69 6e 74 20 73 71 6c 69 74 65 33 73 65 73 73  .int sqlite3sess
127a0 69 6f 6e 5f 63 68 61 6e 67 65 73 65 74 28 0a 20  ion_changeset(. 
127b0 20 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e   sqlite3_session
127c0 20 2a 70 53 65 73 73 69 6f 6e 2c 20 20 20 20 20   *pSession,     
127d0 20 2f 2a 20 53 65 73 73 69 6f 6e 20 6f 62 6a 65   /* Session obje
127e0 63 74 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 43  ct */.  int *pnC
127f0 68 61 6e 67 65 73 65 74 2c 20 20 20 20 20 20 20  hangeset,       
12800 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
12810 53 69 7a 65 20 6f 66 20 62 75 66 66 65 72 20 61  Size of buffer a
12820 74 20 2a 70 70 43 68 61 6e 67 65 73 65 74 20 2a  t *ppChangeset *
12830 2f 0a 20 20 76 6f 69 64 20 2a 2a 70 70 43 68 61  /.  void **ppCha
12840 6e 67 65 73 65 74 20 20 20 20 20 20 20 20 20 20  ngeset          
12850 20 20 20 20 2f 2a 20 4f 55 54 3a 20 42 75 66 66      /* OUT: Buff
12860 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 63 68  er containing ch
12870 61 6e 67 65 73 65 74 20 2a 2f 0a 29 7b 0a 20 20  angeset */.){.  
12880 72 65 74 75 72 6e 20 73 65 73 73 69 6f 6e 47 65  return sessionGe
12890 6e 65 72 61 74 65 43 68 61 6e 67 65 73 65 74 28  nerateChangeset(
128a0 70 53 65 73 73 69 6f 6e 2c 20 30 2c 20 30 2c 20  pSession, 0, 0, 
128b0 30 2c 20 70 6e 43 68 61 6e 67 65 73 65 74 2c 20  0, pnChangeset, 
128c0 70 70 43 68 61 6e 67 65 73 65 74 29 3b 0a 7d 0a  ppChangeset);.}.
128d0 0a 2f 2a 0a 2a 2a 20 53 74 72 65 61 6d 69 6e 67  ./*.** Streaming
128e0 20 76 65 72 73 69 6f 6e 20 6f 66 20 73 71 6c 69   version of sqli
128f0 74 65 33 73 65 73 73 69 6f 6e 5f 63 68 61 6e 67  te3session_chang
12900 65 73 65 74 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73  eset()..*/.int s
12910 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 63 68  qlite3session_ch
12920 61 6e 67 65 73 65 74 5f 73 74 72 6d 28 0a 20 20  angeset_strm(.  
12930 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20  sqlite3_session 
12940 2a 70 53 65 73 73 69 6f 6e 2c 0a 20 20 69 6e 74  *pSession,.  int
12950 20 28 2a 78 4f 75 74 70 75 74 29 28 76 6f 69 64   (*xOutput)(void
12960 20 2a 70 4f 75 74 2c 20 63 6f 6e 73 74 20 76 6f   *pOut, const vo
12970 69 64 20 2a 70 44 61 74 61 2c 20 69 6e 74 20 6e  id *pData, int n
12980 44 61 74 61 29 2c 0a 20 20 76 6f 69 64 20 2a 70  Data),.  void *p
12990 4f 75 74 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20  Out.){.  return 
129a0 73 65 73 73 69 6f 6e 47 65 6e 65 72 61 74 65 43  sessionGenerateC
129b0 68 61 6e 67 65 73 65 74 28 70 53 65 73 73 69 6f  hangeset(pSessio
129c0 6e 2c 20 30 2c 20 78 4f 75 74 70 75 74 2c 20 70  n, 0, xOutput, p
129d0 4f 75 74 2c 20 30 2c 20 30 29 3b 0a 7d 0a 0a 2f  Out, 0, 0);.}../
129e0 2a 0a 2a 2a 20 53 74 72 65 61 6d 69 6e 67 20 76  *.** Streaming v
129f0 65 72 73 69 6f 6e 20 6f 66 20 73 71 6c 69 74 65  ersion of sqlite
12a00 33 73 65 73 73 69 6f 6e 5f 70 61 74 63 68 73 65  3session_patchse
12a10 74 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  t()..*/.int sqli
12a20 74 65 33 73 65 73 73 69 6f 6e 5f 70 61 74 63 68  te3session_patch
12a30 73 65 74 5f 73 74 72 6d 28 0a 20 20 73 71 6c 69  set_strm(.  sqli
12a40 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65  te3_session *pSe
12a50 73 73 69 6f 6e 2c 0a 20 20 69 6e 74 20 28 2a 78  ssion,.  int (*x
12a60 4f 75 74 70 75 74 29 28 76 6f 69 64 20 2a 70 4f  Output)(void *pO
12a70 75 74 2c 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a  ut, const void *
12a80 70 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74 61  pData, int nData
12a90 29 2c 0a 20 20 76 6f 69 64 20 2a 70 4f 75 74 0a  ),.  void *pOut.
12aa0 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 65 73 73  ){.  return sess
12ab0 69 6f 6e 47 65 6e 65 72 61 74 65 43 68 61 6e 67  ionGenerateChang
12ac0 65 73 65 74 28 70 53 65 73 73 69 6f 6e 2c 20 31  eset(pSession, 1
12ad0 2c 20 78 4f 75 74 70 75 74 2c 20 70 4f 75 74 2c  , xOutput, pOut,
12ae0 20 30 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   0, 0);.}../*.**
12af0 20 4f 62 74 61 69 6e 20 61 20 70 61 74 63 68 73   Obtain a patchs
12b00 65 74 20 6f 62 6a 65 63 74 20 63 6f 6e 74 61 69  et object contai
12b10 6e 69 6e 67 20 61 6c 6c 20 63 68 61 6e 67 65 73  ning all changes
12b20 20 72 65 63 6f 72 64 65 64 20 62 79 20 74 68 65   recorded by the
12b30 20 0a 2a 2a 20 73 65 73 73 69 6f 6e 20 6f 62 6a   .** session obj
12b40 65 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68  ect passed as th
12b50 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
12b60 2e 0a 2a 2a 0a 2a 2a 20 49 74 20 69 73 20 74 68  ..**.** It is th
12b70 65 20 72 65 73 70 6f 6e 73 69 62 69 6c 69 74 79  e responsibility
12b80 20 6f 66 20 74 68 65 20 63 61 6c 6c 65 72 20 74   of the caller t
12b90 6f 20 65 76 65 6e 74 75 61 6c 6c 79 20 66 72 65  o eventually fre
12ba0 65 20 74 68 65 20 62 75 66 66 65 72 20 0a 2a 2a  e the buffer .**
12bb0 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 66   using sqlite3_f
12bc0 72 65 65 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71  ree()..*/.int sq
12bd0 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 70 61 74  lite3session_pat
12be0 63 68 73 65 74 28 0a 20 20 73 71 6c 69 74 65 33  chset(.  sqlite3
12bf0 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69  _session *pSessi
12c00 6f 6e 2c 20 20 20 20 20 20 2f 2a 20 53 65 73 73  on,      /* Sess
12c10 69 6f 6e 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20  ion object */.  
12c20 69 6e 74 20 2a 70 6e 50 61 74 63 68 73 65 74 2c  int *pnPatchset,
12c30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12c40 2f 2a 20 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20  /* OUT: Size of 
12c50 62 75 66 66 65 72 20 61 74 20 2a 70 70 43 68 61  buffer at *ppCha
12c60 6e 67 65 73 65 74 20 2a 2f 0a 20 20 76 6f 69 64  ngeset */.  void
12c70 20 2a 2a 70 70 50 61 74 63 68 73 65 74 20 20 20   **ppPatchset   
12c80 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
12c90 55 54 3a 20 42 75 66 66 65 72 20 63 6f 6e 74 61  UT: Buffer conta
12ca0 69 6e 69 6e 67 20 63 68 61 6e 67 65 73 65 74 20  ining changeset 
12cb0 2a 2f 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20 73  */.){.  return s
12cc0 65 73 73 69 6f 6e 47 65 6e 65 72 61 74 65 43 68  essionGenerateCh
12cd0 61 6e 67 65 73 65 74 28 70 53 65 73 73 69 6f 6e  angeset(pSession
12ce0 2c 20 31 2c 20 30 2c 20 30 2c 20 70 6e 50 61 74  , 1, 0, 0, pnPat
12cf0 63 68 73 65 74 2c 20 70 70 50 61 74 63 68 73 65  chset, ppPatchse
12d00 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 61  t);.}../*.** Ena
12d10 62 6c 65 20 6f 72 20 64 69 73 61 62 6c 65 20 74  ble or disable t
12d20 68 65 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63  he session objec
12d30 74 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20  t passed as the 
12d40 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 0a  first argument..
12d50 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 73 65  */.int sqlite3se
12d60 73 73 69 6f 6e 5f 65 6e 61 62 6c 65 28 73 71 6c  ssion_enable(sql
12d70 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53  ite3_session *pS
12d80 65 73 73 69 6f 6e 2c 20 69 6e 74 20 62 45 6e 61  ession, int bEna
12d90 62 6c 65 29 7b 0a 20 20 69 6e 74 20 72 65 74 3b  ble){.  int ret;
12da0 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  .  sqlite3_mutex
12db0 5f 65 6e 74 65 72 28 73 71 6c 69 74 65 33 5f 64  _enter(sqlite3_d
12dc0 62 5f 6d 75 74 65 78 28 70 53 65 73 73 69 6f 6e  b_mutex(pSession
12dd0 2d 3e 64 62 29 29 3b 0a 20 20 69 66 28 20 62 45  ->db));.  if( bE
12de0 6e 61 62 6c 65 3e 3d 30 20 29 7b 0a 20 20 20 20  nable>=0 ){.    
12df0 70 53 65 73 73 69 6f 6e 2d 3e 62 45 6e 61 62 6c  pSession->bEnabl
12e00 65 20 3d 20 62 45 6e 61 62 6c 65 3b 0a 20 20 7d  e = bEnable;.  }
12e10 0a 20 20 72 65 74 20 3d 20 70 53 65 73 73 69 6f  .  ret = pSessio
12e20 6e 2d 3e 62 45 6e 61 62 6c 65 3b 0a 20 20 73 71  n->bEnable;.  sq
12e30 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76  lite3_mutex_leav
12e40 65 28 73 71 6c 69 74 65 33 5f 64 62 5f 6d 75 74  e(sqlite3_db_mut
12e50 65 78 28 70 53 65 73 73 69 6f 6e 2d 3e 64 62 29  ex(pSession->db)
12e60 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 65 74 3b  );.  return ret;
12e70 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 61 62 6c 65  .}../*.** Enable
12e80 20 6f 72 20 64 69 73 61 62 6c 65 20 74 68 65 20   or disable the 
12e90 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 70  session object p
12ea0 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69 72  assed as the fir
12eb0 73 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a  st argument..*/.
12ec0 69 6e 74 20 73 71 6c 69 74 65 33 73 65 73 73 69  int sqlite3sessi
12ed0 6f 6e 5f 69 6e 64 69 72 65 63 74 28 73 71 6c 69  on_indirect(sqli
12ee0 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65  te3_session *pSe
12ef0 73 73 69 6f 6e 2c 20 69 6e 74 20 62 49 6e 64 69  ssion, int bIndi
12f00 72 65 63 74 29 7b 0a 20 20 69 6e 74 20 72 65 74  rect){.  int ret
12f10 3b 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  ;.  sqlite3_mute
12f20 78 5f 65 6e 74 65 72 28 73 71 6c 69 74 65 33 5f  x_enter(sqlite3_
12f30 64 62 5f 6d 75 74 65 78 28 70 53 65 73 73 69 6f  db_mutex(pSessio
12f40 6e 2d 3e 64 62 29 29 3b 0a 20 20 69 66 28 20 62  n->db));.  if( b
12f50 49 6e 64 69 72 65 63 74 3e 3d 30 20 29 7b 0a 20  Indirect>=0 ){. 
12f60 20 20 20 70 53 65 73 73 69 6f 6e 2d 3e 62 49 6e     pSession->bIn
12f70 64 69 72 65 63 74 20 3d 20 62 49 6e 64 69 72 65  direct = bIndire
12f80 63 74 3b 0a 20 20 7d 0a 20 20 72 65 74 20 3d 20  ct;.  }.  ret = 
12f90 70 53 65 73 73 69 6f 6e 2d 3e 62 49 6e 64 69 72  pSession->bIndir
12fa0 65 63 74 3b 0a 20 20 73 71 6c 69 74 65 33 5f 6d  ect;.  sqlite3_m
12fb0 75 74 65 78 5f 6c 65 61 76 65 28 73 71 6c 69 74  utex_leave(sqlit
12fc0 65 33 5f 64 62 5f 6d 75 74 65 78 28 70 53 65 73  e3_db_mutex(pSes
12fd0 73 69 6f 6e 2d 3e 64 62 29 29 3b 0a 20 20 72 65  sion->db));.  re
12fe0 74 75 72 6e 20 72 65 74 3b 0a 7d 0a 0a 2f 2a 0a  turn ret;.}../*.
12ff0 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65 20 69  ** Return true i
13000 66 20 74 68 65 72 65 20 68 61 76 65 20 62 65 65  f there have bee
13010 6e 20 6e 6f 20 63 68 61 6e 67 65 73 20 74 6f 20  n no changes to 
13020 6d 6f 6e 69 74 6f 72 65 64 20 74 61 62 6c 65 73  monitored tables
13030 20 72 65 63 6f 72 64 65 64 0a 2a 2a 20 62 79 20   recorded.** by 
13040 74 68 65 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65  the session obje
13050 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68 65  ct passed as the
13060 20 6f 6e 6c 79 20 61 72 67 75 6d 65 6e 74 2e 0a   only argument..
13070 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 73 65  */.int sqlite3se
13080 73 73 69 6f 6e 5f 69 73 65 6d 70 74 79 28 73 71  ssion_isempty(sq
13090 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70  lite3_session *p
130a0 53 65 73 73 69 6f 6e 29 7b 0a 20 20 69 6e 74 20  Session){.  int 
130b0 72 65 74 20 3d 20 30 3b 0a 20 20 53 65 73 73 69  ret = 0;.  Sessi
130c0 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62 3b 0a 0a  onTable *pTab;..
130d0 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
130e0 65 6e 74 65 72 28 73 71 6c 69 74 65 33 5f 64 62  enter(sqlite3_db
130f0 5f 6d 75 74 65 78 28 70 53 65 73 73 69 6f 6e 2d  _mutex(pSession-
13100 3e 64 62 29 29 3b 0a 20 20 66 6f 72 28 70 54 61  >db));.  for(pTa
13110 62 3d 70 53 65 73 73 69 6f 6e 2d 3e 70 54 61 62  b=pSession->pTab
13120 6c 65 3b 20 70 54 61 62 20 26 26 20 72 65 74 3d  le; pTab && ret=
13130 3d 30 3b 20 70 54 61 62 3d 70 54 61 62 2d 3e 70  =0; pTab=pTab->p
13140 4e 65 78 74 29 7b 0a 20 20 20 20 72 65 74 20 3d  Next){.    ret =
13150 20 28 70 54 61 62 2d 3e 6e 45 6e 74 72 79 3e 30   (pTab->nEntry>0
13160 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33  );.  }.  sqlite3
13170 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 73 71 6c  _mutex_leave(sql
13180 69 74 65 33 5f 64 62 5f 6d 75 74 65 78 28 70 53  ite3_db_mutex(pS
13190 65 73 73 69 6f 6e 2d 3e 64 62 29 29 3b 0a 0a 20  ession->db));.. 
131a0 20 72 65 74 75 72 6e 20 28 72 65 74 3d 3d 30 29   return (ret==0)
131b0 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 74 68  ;.}../*.** Do th
131c0 65 20 77 6f 72 6b 20 66 6f 72 20 65 69 74 68 65  e work for eithe
131d0 72 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  r sqlite3changes
131e0 65 74 5f 73 74 61 72 74 28 29 20 6f 72 20 73 74  et_start() or st
131f0 61 72 74 5f 73 74 72 6d 28 29 2e 0a 2a 2f 0a 73  art_strm()..*/.s
13200 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f  tatic int sessio
13210 6e 43 68 61 6e 67 65 73 65 74 53 74 61 72 74 28  nChangesetStart(
13220 0a 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67  .  sqlite3_chang
13230 65 73 65 74 5f 69 74 65 72 20 2a 2a 70 70 2c 20  eset_iter **pp, 
13240 20 20 20 2f 2a 20 4f 55 54 3a 20 43 68 61 6e 67     /* OUT: Chang
13250 65 73 65 74 20 69 74 65 72 61 74 6f 72 20 68 61  eset iterator ha
13260 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 28 2a  ndle */.  int (*
13270 78 49 6e 70 75 74 29 28 76 6f 69 64 20 2a 70 49  xInput)(void *pI
13280 6e 2c 20 76 6f 69 64 20 2a 70 44 61 74 61 2c 20  n, void *pData, 
13290 69 6e 74 20 2a 70 6e 44 61 74 61 29 2c 0a 20 20  int *pnData),.  
132a0 76 6f 69 64 20 2a 70 49 6e 2c 0a 20 20 69 6e 74  void *pIn,.  int
132b0 20 6e 43 68 61 6e 67 65 73 65 74 2c 20 20 20 20   nChangeset,    
132c0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
132d0 53 69 7a 65 20 6f 66 20 62 75 66 66 65 72 20 70  Size of buffer p
132e0 43 68 61 6e 67 65 73 65 74 20 69 6e 20 62 79 74  Changeset in byt
132f0 65 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 43  es */.  void *pC
13300 68 61 6e 67 65 73 65 74 20 20 20 20 20 20 20 20  hangeset        
13310 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74          /* Point
13320 65 72 20 74 6f 20 62 75 66 66 65 72 20 63 6f 6e  er to buffer con
13330 74 61 69 6e 69 6e 67 20 63 68 61 6e 67 65 73 65  taining changese
13340 74 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65  t */.){.  sqlite
13350 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72  3_changeset_iter
13360 20 2a 70 52 65 74 3b 20 20 20 2f 2a 20 49 74 65   *pRet;   /* Ite
13370 72 61 74 6f 72 20 74 6f 20 72 65 74 75 72 6e 20  rator to return 
13380 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b 20  */.  int nByte; 
13390 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
133a0 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
133b0 66 20 62 79 74 65 73 20 74 6f 20 61 6c 6c 6f 63  f bytes to alloc
133c0 61 74 65 20 66 6f 72 20 69 74 65 72 61 74 6f 72  ate for iterator
133d0 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 78   */..  assert( x
133e0 49 6e 70 75 74 3d 3d 30 20 7c 7c 20 28 70 43 68  Input==0 || (pCh
133f0 61 6e 67 65 73 65 74 3d 3d 30 20 26 26 20 6e 43  angeset==0 && nC
13400 68 61 6e 67 65 73 65 74 3d 3d 30 29 20 29 3b 0a  hangeset==0) );.
13410 0a 20 20 2f 2a 20 5a 65 72 6f 20 74 68 65 20 6f  .  /* Zero the o
13420 75 74 70 75 74 20 76 61 72 69 61 62 6c 65 20 69  utput variable i
13430 6e 20 63 61 73 65 20 61 6e 20 65 72 72 6f 72 20  n case an error 
13440 6f 63 63 75 72 73 2e 20 2a 2f 0a 20 20 2a 70 70  occurs. */.  *pp
13450 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f   = 0;..  /* Allo
13460 63 61 74 65 20 61 6e 64 20 69 6e 69 74 69 61 6c  cate and initial
13470 69 7a 65 20 74 68 65 20 69 74 65 72 61 74 6f 72  ize the iterator
13480 20 73 74 72 75 63 74 75 72 65 2e 20 2a 2f 0a 20   structure. */. 
13490 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28   nByte = sizeof(
134a0 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65  sqlite3_changese
134b0 74 5f 69 74 65 72 29 3b 0a 20 20 70 52 65 74 20  t_iter);.  pRet 
134c0 3d 20 28 73 71 6c 69 74 65 33 5f 63 68 61 6e 67  = (sqlite3_chang
134d0 65 73 65 74 5f 69 74 65 72 20 2a 29 73 71 6c 69  eset_iter *)sqli
134e0 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74 65  te3_malloc(nByte
134f0 29 3b 0a 20 20 69 66 28 20 21 70 52 65 74 20 29  );.  if( !pRet )
13500 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
13510 4f 4d 45 4d 3b 0a 20 20 6d 65 6d 73 65 74 28 70  OMEM;.  memset(p
13520 52 65 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73  Ret, 0, sizeof(s
13530 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74  qlite3_changeset
13540 5f 69 74 65 72 29 29 3b 0a 20 20 70 52 65 74 2d  _iter));.  pRet-
13550 3e 69 6e 2e 61 44 61 74 61 20 3d 20 28 75 38 20  >in.aData = (u8 
13560 2a 29 70 43 68 61 6e 67 65 73 65 74 3b 0a 20 20  *)pChangeset;.  
13570 70 52 65 74 2d 3e 69 6e 2e 6e 44 61 74 61 20 3d  pRet->in.nData =
13580 20 6e 43 68 61 6e 67 65 73 65 74 3b 0a 20 20 70   nChangeset;.  p
13590 52 65 74 2d 3e 69 6e 2e 78 49 6e 70 75 74 20 3d  Ret->in.xInput =
135a0 20 78 49 6e 70 75 74 3b 0a 20 20 70 52 65 74 2d   xInput;.  pRet-
135b0 3e 69 6e 2e 70 49 6e 20 3d 20 70 49 6e 3b 0a 20  >in.pIn = pIn;. 
135c0 20 70 52 65 74 2d 3e 69 6e 2e 62 45 6f 66 20 3d   pRet->in.bEof =
135d0 20 28 78 49 6e 70 75 74 20 3f 20 30 20 3a 20 31   (xInput ? 0 : 1
135e0 29 3b 0a 0a 20 20 2f 2a 20 50 6f 70 75 6c 61 74  );..  /* Populat
135f0 65 20 74 68 65 20 6f 75 74 70 75 74 20 76 61 72  e the output var
13600 69 61 62 6c 65 20 61 6e 64 20 72 65 74 75 72 6e  iable and return
13610 20 73 75 63 63 65 73 73 2e 20 2a 2f 0a 20 20 2a   success. */.  *
13620 70 70 20 3d 20 70 52 65 74 3b 0a 20 20 72 65 74  pp = pRet;.  ret
13630 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
13640 0a 0a 2f 2a 0a 2a 2a 20 43 72 65 61 74 65 20 61  ../*.** Create a
13650 6e 20 69 74 65 72 61 74 6f 72 20 75 73 65 64 20  n iterator used 
13660 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75  to iterate throu
13670 67 68 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  gh the contents 
13680 6f 66 20 61 20 63 68 61 6e 67 65 73 65 74 2e 0a  of a changeset..
13690 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 63 68  */.int sqlite3ch
136a0 61 6e 67 65 73 65 74 5f 73 74 61 72 74 28 0a 20  angeset_start(. 
136b0 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73   sqlite3_changes
136c0 65 74 5f 69 74 65 72 20 2a 2a 70 70 2c 20 20 20  et_iter **pp,   
136d0 20 2f 2a 20 4f 55 54 3a 20 43 68 61 6e 67 65 73   /* OUT: Changes
136e0 65 74 20 69 74 65 72 61 74 6f 72 20 68 61 6e 64  et iterator hand
136f0 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 68 61  le */.  int nCha
13700 6e 67 65 73 65 74 2c 20 20 20 20 20 20 20 20 20  ngeset,         
13710 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
13720 6f 66 20 62 75 66 66 65 72 20 70 43 68 61 6e 67  of buffer pChang
13730 65 73 65 74 20 69 6e 20 62 79 74 65 73 20 2a 2f  eset in bytes */
13740 0a 20 20 76 6f 69 64 20 2a 70 43 68 61 6e 67 65  .  void *pChange
13750 73 65 74 20 20 20 20 20 20 20 20 20 20 20 20 20  set             
13760 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
13770 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69   buffer containi
13780 6e 67 20 63 68 61 6e 67 65 73 65 74 20 2a 2f 0a  ng changeset */.
13790 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 65 73 73  ){.  return sess
137a0 69 6f 6e 43 68 61 6e 67 65 73 65 74 53 74 61 72  ionChangesetStar
137b0 74 28 70 70 2c 20 30 2c 20 30 2c 20 6e 43 68 61  t(pp, 0, 0, nCha
137c0 6e 67 65 73 65 74 2c 20 70 43 68 61 6e 67 65 73  ngeset, pChanges
137d0 65 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 74  et);.}../*.** St
137e0 72 65 61 6d 69 6e 67 20 76 65 72 73 69 6f 6e 20  reaming version 
137f0 6f 66 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65  of sqlite3change
13800 73 65 74 5f 73 74 61 72 74 28 29 2e 0a 2a 2f 0a  set_start()..*/.
13810 69 6e 74 20 73 71 6c 69 74 65 33 63 68 61 6e 67  int sqlite3chang
13820 65 73 65 74 5f 73 74 61 72 74 5f 73 74 72 6d 28  eset_start_strm(
13830 0a 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67  .  sqlite3_chang
13840 65 73 65 74 5f 69 74 65 72 20 2a 2a 70 70 2c 20  eset_iter **pp, 
13850 20 20 20 2f 2a 20 4f 55 54 3a 20 43 68 61 6e 67     /* OUT: Chang
13860 65 73 65 74 20 69 74 65 72 61 74 6f 72 20 68 61  eset iterator ha
13870 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 28 2a  ndle */.  int (*
13880 78 49 6e 70 75 74 29 28 76 6f 69 64 20 2a 70 49  xInput)(void *pI
13890 6e 2c 20 76 6f 69 64 20 2a 70 44 61 74 61 2c 20  n, void *pData, 
138a0 69 6e 74 20 2a 70 6e 44 61 74 61 29 2c 0a 20 20  int *pnData),.  
138b0 76 6f 69 64 20 2a 70 49 6e 0a 29 7b 0a 20 20 72  void *pIn.){.  r
138c0 65 74 75 72 6e 20 73 65 73 73 69 6f 6e 43 68 61  eturn sessionCha
138d0 6e 67 65 73 65 74 53 74 61 72 74 28 70 70 2c 20  ngesetStart(pp, 
138e0 78 49 6e 70 75 74 2c 20 70 49 6e 2c 20 30 2c 20  xInput, pIn, 0, 
138f0 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20  0);.}../*.** If 
13900 74 68 65 20 53 65 73 73 69 6f 6e 49 6e 70 75 74  the SessionInput
13910 20 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20 61   object passed a
13920 73 20 74 68 65 20 6f 6e 6c 79 20 61 72 67 75 6d  s the only argum
13930 65 6e 74 20 69 73 20 61 20 73 74 72 65 61 6d 69  ent is a streami
13940 6e 67 0a 2a 2a 20 6f 62 6a 65 63 74 20 61 6e 64  ng.** object and
13950 20 74 68 65 20 62 75 66 66 65 72 20 69 73 20 66   the buffer is f
13960 75 6c 6c 2c 20 64 69 73 63 61 72 64 20 73 6f 6d  ull, discard som
13970 65 20 64 61 74 61 20 74 6f 20 66 72 65 65 20 75  e data to free u
13980 70 20 73 70 61 63 65 2e 0a 2a 2f 0a 73 74 61 74  p space..*/.stat
13990 69 63 20 76 6f 69 64 20 73 65 73 73 69 6f 6e 44  ic void sessionD
139a0 69 73 63 61 72 64 44 61 74 61 28 53 65 73 73 69  iscardData(Sessi
139b0 6f 6e 49 6e 70 75 74 20 2a 70 49 6e 29 7b 0a 20  onInput *pIn){. 
139c0 20 69 66 28 20 70 49 6e 2d 3e 62 45 6f 66 20 26   if( pIn->bEof &
139d0 26 20 70 49 6e 2d 3e 78 49 6e 70 75 74 20 26 26  & pIn->xInput &&
139e0 20 70 49 6e 2d 3e 69 4e 65 78 74 3e 3d 53 45 53   pIn->iNext>=SES
139f0 53 49 4f 4e 53 5f 53 54 52 4d 5f 43 48 55 4e 4b  SIONS_STRM_CHUNK
13a00 5f 53 49 5a 45 20 29 7b 0a 20 20 20 20 69 6e 74  _SIZE ){.    int
13a10 20 6e 4d 6f 76 65 20 3d 20 70 49 6e 2d 3e 62 75   nMove = pIn->bu
13a20 66 2e 6e 42 75 66 20 2d 20 70 49 6e 2d 3e 69 4e  f.nBuf - pIn->iN
13a30 65 78 74 3b 0a 20 20 20 20 61 73 73 65 72 74 28  ext;.    assert(
13a40 20 6e 4d 6f 76 65 3e 3d 30 20 29 3b 0a 20 20 20   nMove>=0 );.   
13a50 20 69 66 28 20 6e 4d 6f 76 65 3e 30 20 29 7b 0a   if( nMove>0 ){.
13a60 20 20 20 20 20 20 6d 65 6d 6d 6f 76 65 28 70 49        memmove(pI
13a70 6e 2d 3e 62 75 66 2e 61 42 75 66 2c 20 26 70 49  n->buf.aBuf, &pI
13a80 6e 2d 3e 62 75 66 2e 61 42 75 66 5b 70 49 6e 2d  n->buf.aBuf[pIn-
13a90 3e 69 4e 65 78 74 5d 2c 20 6e 4d 6f 76 65 29 3b  >iNext], nMove);
13aa0 0a 20 20 20 20 7d 0a 20 20 20 20 70 49 6e 2d 3e  .    }.    pIn->
13ab0 62 75 66 2e 6e 42 75 66 20 2d 3d 20 70 49 6e 2d  buf.nBuf -= pIn-
13ac0 3e 69 4e 65 78 74 3b 0a 20 20 20 20 70 49 6e 2d  >iNext;.    pIn-
13ad0 3e 69 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20  >iNext = 0;.    
13ae0 70 49 6e 2d 3e 6e 44 61 74 61 20 3d 20 70 49 6e  pIn->nData = pIn
13af0 2d 3e 62 75 66 2e 6e 42 75 66 3b 0a 20 20 7d 0a  ->buf.nBuf;.  }.
13b00 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 73 75 72 65 20  }../*.** Ensure 
13b10 74 68 61 74 20 74 68 65 72 65 20 61 72 65 20 61  that there are a
13b20 74 20 6c 65 61 73 74 20 6e 42 79 74 65 20 62 79  t least nByte by
13b30 74 65 73 20 61 76 61 69 6c 61 62 6c 65 20 69 6e  tes available in
13b40 20 74 68 65 20 62 75 66 66 65 72 2e 20 4f 72 2c   the buffer. Or,
13b50 0a 2a 2a 20 69 66 20 74 68 65 72 65 20 61 72 65  .** if there are
13b60 20 6e 6f 74 20 6e 42 79 74 65 20 62 79 74 65 73   not nByte bytes
13b70 20 72 65 6d 61 69 6e 69 6e 67 20 69 6e 20 74 68   remaining in th
13b80 65 20 69 6e 70 75 74 2c 20 74 68 61 74 20 61 6c  e input, that al
13b90 6c 20 61 76 61 69 6c 61 62 6c 65 0a 2a 2a 20 64  l available.** d
13ba0 61 74 61 20 69 73 20 69 6e 20 74 68 65 20 62 75  ata is in the bu
13bb0 66 66 65 72 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75  ffer..**.** Retu
13bc0 72 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  rn an SQLite err
13bd0 6f 72 20 63 6f 64 65 20 69 66 20 61 6e 20 65 72  or code if an er
13be0 72 6f 72 20 6f 63 63 75 72 73 2c 20 6f 72 20 53  ror occurs, or S
13bf0 51 4c 49 54 45 5f 4f 4b 20 6f 74 68 65 72 77 69  QLITE_OK otherwi
13c00 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  se..*/.static in
13c10 74 20 73 65 73 73 69 6f 6e 49 6e 70 75 74 42 75  t sessionInputBu
13c20 66 66 65 72 28 53 65 73 73 69 6f 6e 49 6e 70 75  ffer(SessionInpu
13c30 74 20 2a 70 49 6e 2c 20 69 6e 74 20 6e 42 79 74  t *pIn, int nByt
13c40 65 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  e){.  int rc = S
13c50 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20  QLITE_OK;.  if( 
13c60 70 49 6e 2d 3e 78 49 6e 70 75 74 20 29 7b 0a 20  pIn->xInput ){. 
13c70 20 20 20 77 68 69 6c 65 28 20 21 70 49 6e 2d 3e     while( !pIn->
13c80 62 45 6f 66 20 26 26 20 28 70 49 6e 2d 3e 69 4e  bEof && (pIn->iN
13c90 65 78 74 2b 6e 42 79 74 65 29 3e 3d 70 49 6e 2d  ext+nByte)>=pIn-
13ca0 3e 6e 44 61 74 61 20 26 26 20 72 63 3d 3d 53 51  >nData && rc==SQ
13cb0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
13cc0 20 69 6e 74 20 6e 4e 65 77 20 3d 20 53 45 53 53   int nNew = SESS
13cd0 49 4f 4e 53 5f 53 54 52 4d 5f 43 48 55 4e 4b 5f  IONS_STRM_CHUNK_
13ce0 53 49 5a 45 3b 0a 0a 20 20 20 20 20 20 69 66 28  SIZE;..      if(
13cf0 20 70 49 6e 2d 3e 62 4e 6f 44 69 73 63 61 72 64   pIn->bNoDiscard
13d00 3d 3d 30 20 29 20 73 65 73 73 69 6f 6e 44 69 73  ==0 ) sessionDis
13d10 63 61 72 64 44 61 74 61 28 70 49 6e 29 3b 0a 20  cardData(pIn);. 
13d20 20 20 20 20 20 69 66 28 20 53 51 4c 49 54 45 5f       if( SQLITE_
13d30 4f 4b 3d 3d 73 65 73 73 69 6f 6e 42 75 66 66 65  OK==sessionBuffe
13d40 72 47 72 6f 77 28 26 70 49 6e 2d 3e 62 75 66 2c  rGrow(&pIn->buf,
13d50 20 6e 4e 65 77 2c 20 26 72 63 29 20 29 7b 0a 20   nNew, &rc) ){. 
13d60 20 20 20 20 20 20 20 72 63 20 3d 20 70 49 6e 2d         rc = pIn-
13d70 3e 78 49 6e 70 75 74 28 70 49 6e 2d 3e 70 49 6e  >xInput(pIn->pIn
13d80 2c 20 26 70 49 6e 2d 3e 62 75 66 2e 61 42 75 66  , &pIn->buf.aBuf
13d90 5b 70 49 6e 2d 3e 62 75 66 2e 6e 42 75 66 5d 2c  [pIn->buf.nBuf],
13da0 20 26 6e 4e 65 77 29 3b 0a 20 20 20 20 20 20 20   &nNew);.       
13db0 20 69 66 28 20 6e 4e 65 77 3d 3d 30 20 29 7b 0a   if( nNew==0 ){.
13dc0 20 20 20 20 20 20 20 20 20 20 70 49 6e 2d 3e 62            pIn->b
13dd0 45 6f 66 20 3d 20 31 3b 0a 20 20 20 20 20 20 20  Eof = 1;.       
13de0 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
13df0 20 20 70 49 6e 2d 3e 62 75 66 2e 6e 42 75 66 20    pIn->buf.nBuf 
13e00 2b 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 20  += nNew;.       
13e10 20 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20   }.      }..    
13e20 20 20 70 49 6e 2d 3e 61 44 61 74 61 20 3d 20 70    pIn->aData = p
13e30 49 6e 2d 3e 62 75 66 2e 61 42 75 66 3b 0a 20 20  In->buf.aBuf;.  
13e40 20 20 20 20 70 49 6e 2d 3e 6e 44 61 74 61 20 3d      pIn->nData =
13e50 20 70 49 6e 2d 3e 62 75 66 2e 6e 42 75 66 3b 0a   pIn->buf.nBuf;.
13e60 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
13e70 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
13e80 57 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69  When this functi
13e90 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2c 20 2a 70  on is called, *p
13ea0 70 52 65 63 20 70 6f 69 6e 74 73 20 74 6f 20 74  pRec points to t
13eb0 68 65 20 73 74 61 72 74 20 6f 66 20 61 20 72 65  he start of a re
13ec0 63 6f 72 64 0a 2a 2a 20 74 68 61 74 20 63 6f 6e  cord.** that con
13ed0 74 61 69 6e 73 20 6e 43 6f 6c 20 76 61 6c 75 65  tains nCol value
13ee0 73 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  s. This function
13ef0 20 61 64 76 61 6e 63 65 73 20 74 68 65 20 70 6f   advances the po
13f00 69 6e 74 65 72 20 2a 70 70 52 65 63 0a 2a 2a 20  inter *ppRec.** 
13f10 75 6e 74 69 6c 20 69 74 20 70 6f 69 6e 74 73 20  until it points 
13f20 74 6f 20 74 68 65 20 62 79 74 65 20 69 6d 6d 65  to the byte imme
13f30 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 69 6e  diately followin
13f40 67 20 74 68 61 74 20 72 65 63 6f 72 64 2e 0a 2a  g that record..*
13f50 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 65  /.static void se
13f60 73 73 69 6f 6e 53 6b 69 70 52 65 63 6f 72 64 28  ssionSkipRecord(
13f70 0a 20 20 75 38 20 2a 2a 70 70 52 65 63 2c 20 20  .  u8 **ppRec,  
13f80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13f90 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 52 65     /* IN/OUT: Re
13fa0 63 6f 72 64 20 70 6f 69 6e 74 65 72 20 2a 2f 0a  cord pointer */.
13fb0 20 20 69 6e 74 20 6e 43 6f 6c 20 20 20 20 20 20    int nCol      
13fc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13fd0 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 76    /* Number of v
13fe0 61 6c 75 65 73 20 69 6e 20 72 65 63 6f 72 64 20  alues in record 
13ff0 2a 2f 0a 29 7b 0a 20 20 75 38 20 2a 61 52 65 63  */.){.  u8 *aRec
14000 20 3d 20 2a 70 70 52 65 63 3b 0a 20 20 69 6e 74   = *ppRec;.  int
14010 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69   i;.  for(i=0; i
14020 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20  <nCol; i++){.   
14030 20 69 6e 74 20 65 54 79 70 65 20 3d 20 2a 61 52   int eType = *aR
14040 65 63 2b 2b 3b 0a 20 20 20 20 69 66 28 20 65 54  ec++;.    if( eT
14050 79 70 65 3d 3d 53 51 4c 49 54 45 5f 54 45 58 54  ype==SQLITE_TEXT
14060 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49 54   || eType==SQLIT
14070 45 5f 42 4c 4f 42 20 29 7b 0a 20 20 20 20 20 20  E_BLOB ){.      
14080 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20 20 20  int nByte;.     
14090 20 61 52 65 63 20 2b 3d 20 73 65 73 73 69 6f 6e   aRec += session
140a0 56 61 72 69 6e 74 47 65 74 28 28 75 38 2a 29 61  VarintGet((u8*)a
140b0 52 65 63 2c 20 26 6e 42 79 74 65 29 3b 0a 20 20  Rec, &nByte);.  
140c0 20 20 20 20 61 52 65 63 20 2b 3d 20 6e 42 79 74      aRec += nByt
140d0 65 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  e;.    }else if(
140e0 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49   eType==SQLITE_I
140f0 4e 54 45 47 45 52 20 7c 7c 20 65 54 79 70 65 3d  NTEGER || eType=
14100 3d 53 51 4c 49 54 45 5f 46 4c 4f 41 54 20 29 7b  =SQLITE_FLOAT ){
14110 0a 20 20 20 20 20 20 61 52 65 63 20 2b 3d 20 38  .      aRec += 8
14120 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a  ;.    }.  }..  *
14130 70 70 52 65 63 20 3d 20 61 52 65 63 3b 0a 7d 0a  ppRec = aRec;.}.
14140 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
14150 74 69 6f 6e 20 73 65 74 73 20 74 68 65 20 76 61  tion sets the va
14160 6c 75 65 20 6f 66 20 74 68 65 20 73 71 6c 69 74  lue of the sqlit
14170 65 33 5f 76 61 6c 75 65 20 6f 62 6a 65 63 74 20  e3_value object 
14180 70 61 73 73 65 64 20 61 73 20 74 68 65 0a 2a 2a  passed as the.**
14190 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20   first argument 
141a0 74 6f 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65  to a copy of the
141b0 20 73 74 72 69 6e 67 20 6f 72 20 62 6c 6f 62 20   string or blob 
141c0 68 65 6c 64 20 69 6e 20 74 68 65 20 61 44 61 74  held in the aDat
141d0 61 5b 5d 20 0a 2a 2a 20 62 75 66 66 65 72 2e 20  a[] .** buffer. 
141e0 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74  SQLITE_OK is ret
141f0 75 72 6e 65 64 20 69 66 20 73 75 63 63 65 73 73  urned if success
14200 66 75 6c 2c 20 6f 72 20 53 51 4c 49 54 45 5f 4e  ful, or SQLITE_N
14210 4f 4d 45 4d 20 69 66 20 61 6e 20 4f 4f 4d 0a 2a  OMEM if an OOM.*
14220 2a 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a  * error occurs..
14230 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
14240 73 73 69 6f 6e 56 61 6c 75 65 53 65 74 53 74 72  ssionValueSetStr
14250 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  (.  sqlite3_valu
14260 65 20 2a 70 56 61 6c 2c 20 20 20 20 20 20 20 20  e *pVal,        
14270 20 20 20 20 2f 2a 20 53 65 74 20 74 68 65 20 76      /* Set the v
14280 61 6c 75 65 20 6f 66 20 74 68 69 73 20 6f 62 6a  alue of this obj
14290 65 63 74 20 2a 2f 0a 20 20 75 38 20 2a 61 44 61  ect */.  u8 *aDa
142a0 74 61 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ta,             
142b0 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66           /* Buff
142c0 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 73 74  er containing st
142d0 72 69 6e 67 20 6f 72 20 62 6c 6f 62 20 64 61 74  ring or blob dat
142e0 61 20 2a 2f 0a 20 20 69 6e 74 20 6e 44 61 74 61  a */.  int nData
142f0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
14300 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
14310 66 20 62 75 66 66 65 72 20 61 44 61 74 61 5b 5d  f buffer aData[]
14320 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 75   in bytes */.  u
14330 38 20 65 6e 63 20 20 20 20 20 20 20 20 20 20 20  8 enc           
14340 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
14350 2a 20 53 74 72 69 6e 67 20 65 6e 63 6f 64 69 6e  * String encodin
14360 67 20 28 30 20 66 6f 72 20 62 6c 6f 62 73 29 20  g (0 for blobs) 
14370 2a 2f 0a 29 7b 0a 20 20 2f 2a 20 49 6e 20 74 68  */.){.  /* In th
14380 65 6f 72 79 20 74 68 69 73 20 63 6f 64 65 20 63  eory this code c
14390 6f 75 6c 64 20 6a 75 73 74 20 70 61 73 73 20 53  ould just pass S
143a0 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 20  QLITE_TRANSIENT 
143b0 61 73 20 74 68 65 20 66 69 6e 61 6c 0a 20 20 2a  as the final.  *
143c0 2a 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 73 71  * argument to sq
143d0 6c 69 74 65 33 56 61 6c 75 65 53 65 74 53 74 72  lite3ValueSetStr
143e0 28 29 20 61 6e 64 20 68 61 76 65 20 74 68 65 20  () and have the 
143f0 63 6f 70 79 20 63 72 65 61 74 65 64 20 0a 20 20  copy created .  
14400 2a 2a 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79  ** automatically
14410 2e 20 42 75 74 20 64 6f 69 6e 67 20 73 6f 20 6d  . But doing so m
14420 61 6b 65 73 20 69 74 20 64 69 66 66 69 63 75 6c  akes it difficul
14430 74 20 74 6f 20 64 65 74 65 63 74 20 61 6e 79 20  t to detect any 
14440 4f 4f 4d 0a 20 20 2a 2a 20 65 72 72 6f 72 2e 20  OOM.  ** error. 
14450 48 65 6e 63 65 20 74 68 65 20 63 6f 64 65 20 74  Hence the code t
14460 6f 20 63 72 65 61 74 65 20 74 68 65 20 63 6f 70  o create the cop
14470 79 20 65 78 74 65 72 6e 61 6c 6c 79 2e 20 2a 2f  y externally. */
14480 0a 20 20 75 38 20 2a 61 43 6f 70 79 20 3d 20 73  .  u8 *aCopy = s
14490 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 44  qlite3_malloc(nD
144a0 61 74 61 2b 31 29 3b 0a 20 20 69 66 28 20 61 43  ata+1);.  if( aC
144b0 6f 70 79 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  opy==0 ) return 
144c0 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
144d0 6d 65 6d 63 70 79 28 61 43 6f 70 79 2c 20 61 44  memcpy(aCopy, aD
144e0 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 73  ata, nData);.  s
144f0 71 6c 69 74 65 33 56 61 6c 75 65 53 65 74 53 74  qlite3ValueSetSt
14500 72 28 70 56 61 6c 2c 20 6e 44 61 74 61 2c 20 28  r(pVal, nData, (
14510 63 68 61 72 2a 29 61 43 6f 70 79 2c 20 65 6e 63  char*)aCopy, enc
14520 2c 20 73 71 6c 69 74 65 33 5f 66 72 65 65 29 3b  , sqlite3_free);
14530 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
14540 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65  _OK;.}../*.** De
14550 73 65 72 69 61 6c 69 7a 65 20 61 20 73 69 6e 67  serialize a sing
14560 6c 65 20 72 65 63 6f 72 64 20 66 72 6f 6d 20 61  le record from a
14570 20 62 75 66 66 65 72 20 69 6e 20 6d 65 6d 6f 72   buffer in memor
14580 79 2e 20 53 65 65 20 22 52 45 43 4f 52 44 20 46  y. See "RECORD F
14590 4f 52 4d 41 54 22 0a 2a 2a 20 66 6f 72 20 64 65  ORMAT".** for de
145a0 74 61 69 6c 73 2e 0a 2a 2a 0a 2a 2a 20 57 68 65  tails..**.** Whe
145b0 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
145c0 69 73 20 63 61 6c 6c 65 64 2c 20 2a 70 61 43 68  is called, *paCh
145d0 61 6e 67 65 20 70 6f 69 6e 74 73 20 74 6f 20 74  ange points to t
145e0 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20  he start of the 
145f0 72 65 63 6f 72 64 0a 2a 2a 20 74 6f 20 64 65 73  record.** to des
14600 65 72 69 61 6c 69 7a 65 2e 20 41 73 73 75 6d 69  erialize. Assumi
14610 6e 67 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75  ng no error occu
14620 72 73 2c 20 2a 70 61 43 68 61 6e 67 65 20 69 73  rs, *paChange is
14630 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f   set to point to
14640 0a 2a 2a 20 6f 6e 65 20 62 79 74 65 20 61 66 74  .** one byte aft
14650 65 72 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68  er the end of th
14660 65 20 73 61 6d 65 20 72 65 63 6f 72 64 20 62 65  e same record be
14670 66 6f 72 65 20 74 68 69 73 20 66 75 6e 63 74 69  fore this functi
14680 6f 6e 20 72 65 74 75 72 6e 73 2e 0a 2a 2a 20 49  on returns..** I
14690 66 20 74 68 65 20 61 72 67 75 6d 65 6e 74 20 61  f the argument a
146a0 62 50 4b 20 69 73 20 4e 55 4c 4c 2c 20 74 68 65  bPK is NULL, the
146b0 6e 20 74 68 65 20 72 65 63 6f 72 64 20 63 6f 6e  n the record con
146c0 74 61 69 6e 73 20 6e 43 6f 6c 20 76 61 6c 75 65  tains nCol value
146d0 73 2e 20 4f 72 2c 0a 2a 2a 20 69 66 20 61 62 50  s. Or,.** if abP
146e0 4b 20 69 73 20 6f 74 68 65 72 20 74 68 61 6e 20  K is other than 
146f0 4e 55 4c 4c 2c 20 74 68 65 6e 20 74 68 65 20 72  NULL, then the r
14700 65 63 6f 72 64 20 63 6f 6e 74 61 69 6e 73 20 6f  ecord contains o
14710 6e 6c 79 20 74 68 65 20 50 4b 20 66 69 65 6c 64  nly the PK field
14720 73 0a 2a 2a 20 28 69 6e 20 6f 74 68 65 72 20 77  s.** (in other w
14730 6f 72 64 73 2c 20 69 74 20 69 73 20 61 20 70 61  ords, it is a pa
14740 74 63 68 73 65 74 20 44 45 4c 45 54 45 20 72 65  tchset DELETE re
14750 63 6f 72 64 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  cord)..**.** If 
14760 73 75 63 63 65 73 73 66 75 6c 2c 20 65 61 63 68  successful, each
14770 20 65 6c 65 6d 65 6e 74 20 6f 66 20 74 68 65 20   element of the 
14780 61 70 4f 75 74 5b 5d 20 61 72 72 61 79 20 28 61  apOut[] array (a
14790 6c 6c 6f 63 61 74 65 64 20 62 79 20 74 68 65 20  llocated by the 
147a0 63 61 6c 6c 65 72 29 0a 2a 2a 20 69 73 20 73 65  caller).** is se
147b0 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 61 6e  t to point to an
147c0 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 6f   sqlite3_value o
147d0 62 6a 65 63 74 20 63 6f 6e 74 61 69 6e 69 6e 67  bject containing
147e0 20 74 68 65 20 76 61 6c 75 65 20 72 65 61 64 0a   the value read.
147f0 2a 2a 20 66 72 6f 6d 20 74 68 65 20 63 6f 72 72  ** from the corr
14800 65 73 70 6f 6e 64 69 6e 67 20 70 6f 73 69 74 69  esponding positi
14810 6f 6e 20 69 6e 20 74 68 65 20 72 65 63 6f 72 64  on in the record
14820 2e 20 49 66 20 74 68 61 74 20 76 61 6c 75 65 20  . If that value 
14830 69 73 20 6e 6f 74 0a 2a 2a 20 69 6e 63 6c 75 64  is not.** includ
14840 65 64 20 69 6e 20 74 68 65 20 72 65 63 6f 72 64  ed in the record
14850 20 28 69 2e 65 2e 20 62 65 63 61 75 73 65 20 74   (i.e. because t
14860 68 65 20 72 65 63 6f 72 64 20 69 73 20 70 61 72  he record is par
14870 74 20 6f 66 20 61 6e 20 55 50 44 41 54 45 20 63  t of an UPDATE c
14880 68 61 6e 67 65 0a 2a 2a 20 61 6e 64 20 74 68 65  hange.** and the
14890 20 66 69 65 6c 64 20 77 61 73 20 6e 6f 74 20 6d   field was not m
148a0 6f 64 69 66 69 65 64 29 2c 20 74 68 65 20 63 6f  odified), the co
148b0 72 72 65 73 70 6f 6e 64 69 6e 67 20 65 6c 65 6d  rresponding elem
148c0 65 6e 74 20 6f 66 20 61 70 4f 75 74 5b 5d 20 69  ent of apOut[] i
148d0 73 0a 2a 2a 20 73 65 74 20 74 6f 20 4e 55 4c 4c  s.** set to NULL
148e0 2e 0a 2a 2a 0a 2a 2a 20 49 74 20 69 73 20 74 68  ..**.** It is th
148f0 65 20 72 65 73 70 6f 6e 73 69 62 69 6c 69 74 79  e responsibility
14900 20 6f 66 20 74 68 65 20 63 61 6c 6c 65 72 20 74   of the caller t
14910 6f 20 66 72 65 65 20 61 6c 6c 20 73 71 6c 69 74  o free all sqlit
14920 65 5f 76 61 6c 75 65 20 73 74 72 75 63 74 75 72  e_value structur
14930 65 73 0a 2a 2a 20 75 73 69 6e 67 20 73 71 6c 69  es.** using sqli
14940 74 65 33 5f 66 72 65 65 28 29 2e 0a 2a 2a 0a 2a  te3_free()..**.*
14950 2a 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  * If an error oc
14960 63 75 72 73 2c 20 61 6e 20 53 51 4c 69 74 65 20  curs, an SQLite 
14970 65 72 72 6f 72 20 63 6f 64 65 20 28 65 2e 67 2e  error code (e.g.
14980 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 20 69   SQLITE_NOMEM) i
14990 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 20 54  s returned..** T
149a0 68 65 20 61 70 4f 75 74 5b 5d 20 61 72 72 61 79  he apOut[] array
149b0 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20 70   may have been p
149c0 61 72 74 69 61 6c 6c 79 20 70 6f 70 75 6c 61 74  artially populat
149d0 65 64 20 69 6e 20 74 68 69 73 20 63 61 73 65 2e  ed in this case.
149e0 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73  .*/.static int s
149f0 65 73 73 69 6f 6e 52 65 61 64 52 65 63 6f 72 64  essionReadRecord
14a00 28 0a 20 20 53 65 73 73 69 6f 6e 49 6e 70 75 74  (.  SessionInput
14a10 20 2a 70 49 6e 2c 20 20 20 20 20 20 20 20 20 20   *pIn,          
14a20 20 20 20 20 2f 2a 20 49 6e 70 75 74 20 64 61 74      /* Input dat
14a30 61 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c  a */.  int nCol,
14a40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14a50 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
14a60 20 6f 66 20 76 61 6c 75 65 73 20 69 6e 20 72 65   of values in re
14a70 63 6f 72 64 20 2a 2f 0a 20 20 75 38 20 2a 61 62  cord */.  u8 *ab
14a80 50 4b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  PK,             
14a90 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72            /* Arr
14aa0 61 79 20 6f 66 20 70 72 69 6d 61 72 79 20 6b 65  ay of primary ke
14ab0 79 20 66 6c 61 67 73 2c 20 6f 72 20 4e 55 4c 4c  y flags, or NULL
14ac0 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61   */.  sqlite3_va
14ad0 6c 75 65 20 2a 2a 61 70 4f 75 74 20 20 20 20 20  lue **apOut     
14ae0 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 76        /* Write v
14af0 61 6c 75 65 73 20 74 6f 20 74 68 69 73 20 61 72  alues to this ar
14b00 72 61 79 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  ray */.){.  int 
14b10 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
14b20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55              /* U
14b30 73 65 64 20 74 6f 20 69 74 65 72 61 74 65 20 74  sed to iterate t
14b40 68 72 6f 75 67 68 20 63 6f 6c 75 6d 6e 73 20 2a  hrough columns *
14b50 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  /.  int rc = SQL
14b60 49 54 45 5f 4f 4b 3b 0a 0a 20 20 66 6f 72 28 69  ITE_OK;..  for(i
14b70 3d 30 3b 20 69 3c 6e 43 6f 6c 20 26 26 20 72 63  =0; i<nCol && rc
14b80 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 2b 2b  ==SQLITE_OK; i++
14b90 29 7b 0a 20 20 20 20 69 6e 74 20 65 54 79 70 65  ){.    int eType
14ba0 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
14bb0 20 20 20 20 20 2f 2a 20 54 79 70 65 20 6f 66 20       /* Type of 
14bc0 76 61 6c 75 65 20 28 53 51 4c 49 54 45 5f 4e 55  value (SQLITE_NU
14bd0 4c 4c 2c 20 54 45 58 54 20 65 74 63 2e 29 20 2a  LL, TEXT etc.) *
14be0 2f 0a 20 20 20 20 69 66 28 20 61 62 50 4b 20 26  /.    if( abPK &
14bf0 26 20 61 62 50 4b 5b 69 5d 3d 3d 30 20 29 20 63  & abPK[i]==0 ) c
14c00 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 72 63 20  ontinue;.    rc 
14c10 3d 20 73 65 73 73 69 6f 6e 49 6e 70 75 74 42 75  = sessionInputBu
14c20 66 66 65 72 28 70 49 6e 2c 20 39 29 3b 0a 20 20  ffer(pIn, 9);.  
14c30 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
14c40 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 65 54 79  _OK ){.      eTy
14c50 70 65 20 3d 20 70 49 6e 2d 3e 61 44 61 74 61 5b  pe = pIn->aData[
14c60 70 49 6e 2d 3e 69 4e 65 78 74 2b 2b 5d 3b 0a 20  pIn->iNext++];. 
14c70 20 20 20 7d 0a 0a 20 20 20 20 61 73 73 65 72 74     }..    assert
14c80 28 20 61 70 4f 75 74 5b 69 5d 3d 3d 30 20 29 3b  ( apOut[i]==0 );
14c90 0a 20 20 20 20 69 66 28 20 65 54 79 70 65 20 29  .    if( eType )
14ca0 7b 0a 20 20 20 20 20 20 61 70 4f 75 74 5b 69 5d  {.      apOut[i]
14cb0 20 3d 20 73 71 6c 69 74 65 33 56 61 6c 75 65 4e   = sqlite3ValueN
14cc0 65 77 28 30 29 3b 0a 20 20 20 20 20 20 69 66 28  ew(0);.      if(
14cd0 20 21 61 70 4f 75 74 5b 69 5d 20 29 20 72 63 20   !apOut[i] ) rc 
14ce0 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
14cf0 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72      }..    if( r
14d00 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
14d10 20 20 20 20 20 20 75 38 20 2a 61 56 61 6c 20 3d        u8 *aVal =
14d20 20 26 70 49 6e 2d 3e 61 44 61 74 61 5b 70 49 6e   &pIn->aData[pIn
14d30 2d 3e 69 4e 65 78 74 5d 3b 0a 20 20 20 20 20 20  ->iNext];.      
14d40 69 66 28 20 65 54 79 70 65 3d 3d 53 51 4c 49 54  if( eType==SQLIT
14d50 45 5f 54 45 58 54 20 7c 7c 20 65 54 79 70 65 3d  E_TEXT || eType=
14d60 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 20 29 7b 0a  =SQLITE_BLOB ){.
14d70 20 20 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74          int nByt
14d80 65 3b 0a 20 20 20 20 20 20 20 20 70 49 6e 2d 3e  e;.        pIn->
14d90 69 4e 65 78 74 20 2b 3d 20 73 65 73 73 69 6f 6e  iNext += session
14da0 56 61 72 69 6e 74 47 65 74 28 61 56 61 6c 2c 20  VarintGet(aVal, 
14db0 26 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20 20  &nByte);.       
14dc0 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 49 6e 70   rc = sessionInp
14dd0 75 74 42 75 66 66 65 72 28 70 49 6e 2c 20 6e 42  utBuffer(pIn, nB
14de0 79 74 65 29 3b 0a 20 20 20 20 20 20 20 20 69 66  yte);.        if
14df0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
14e00 29 7b 0a 20 20 20 20 20 20 20 20 20 20 75 38 20  ){.          u8 
14e10 65 6e 63 20 3d 20 28 65 54 79 70 65 3d 3d 53 51  enc = (eType==SQ
14e20 4c 49 54 45 5f 54 45 58 54 20 3f 20 53 51 4c 49  LITE_TEXT ? SQLI
14e30 54 45 5f 55 54 46 38 20 3a 20 30 29 3b 0a 20 20  TE_UTF8 : 0);.  
14e40 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 65 73          rc = ses
14e50 73 69 6f 6e 56 61 6c 75 65 53 65 74 53 74 72 28  sionValueSetStr(
14e60 61 70 4f 75 74 5b 69 5d 2c 26 70 49 6e 2d 3e 61  apOut[i],&pIn->a
14e70 44 61 74 61 5b 70 49 6e 2d 3e 69 4e 65 78 74 5d  Data[pIn->iNext]
14e80 2c 6e 42 79 74 65 2c 65 6e 63 29 3b 0a 20 20 20  ,nByte,enc);.   
14e90 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 70       }.        p
14ea0 49 6e 2d 3e 69 4e 65 78 74 20 2b 3d 20 6e 42 79  In->iNext += nBy
14eb0 74 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  te;.      }.    
14ec0 20 20 69 66 28 20 65 54 79 70 65 3d 3d 53 51 4c    if( eType==SQL
14ed0 49 54 45 5f 49 4e 54 45 47 45 52 20 7c 7c 20 65  ITE_INTEGER || e
14ee0 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 46 4c 4f  Type==SQLITE_FLO
14ef0 41 54 20 29 7b 0a 20 20 20 20 20 20 20 20 73 71  AT ){.        sq
14f00 6c 69 74 65 33 5f 69 6e 74 36 34 20 76 20 3d 20  lite3_int64 v = 
14f10 73 65 73 73 69 6f 6e 47 65 74 49 36 34 28 61 56  sessionGetI64(aV
14f20 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  al);.        if(
14f30 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49   eType==SQLITE_I
14f40 4e 54 45 47 45 52 20 29 7b 0a 20 20 20 20 20 20  NTEGER ){.      
14f50 20 20 20 20 73 71 6c 69 74 65 33 56 64 62 65 4d      sqlite3VdbeM
14f60 65 6d 53 65 74 49 6e 74 36 34 28 61 70 4f 75 74  emSetInt64(apOut
14f70 5b 69 5d 2c 20 76 29 3b 0a 20 20 20 20 20 20 20  [i], v);.       
14f80 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
14f90 20 20 64 6f 75 62 6c 65 20 64 3b 0a 20 20 20 20    double d;.    
14fa0 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 64 2c        memcpy(&d,
14fb0 20 26 76 2c 20 38 29 3b 0a 20 20 20 20 20 20 20   &v, 8);.       
14fc0 20 20 20 73 71 6c 69 74 65 33 56 64 62 65 4d 65     sqlite3VdbeMe
14fd0 6d 53 65 74 44 6f 75 62 6c 65 28 61 70 4f 75 74  mSetDouble(apOut
14fe0 5b 69 5d 2c 20 64 29 3b 0a 20 20 20 20 20 20 20  [i], d);.       
14ff0 20 7d 0a 20 20 20 20 20 20 20 20 70 49 6e 2d 3e   }.        pIn->
15000 69 4e 65 78 74 20 2b 3d 20 38 3b 0a 20 20 20 20  iNext += 8;.    
15010 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20    }.    }.  }.. 
15020 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
15030 2a 0a 2a 2a 20 54 68 65 20 69 6e 70 75 74 20 70  *.** The input p
15040 6f 69 6e 74 65 72 20 63 75 72 72 65 6e 74 6c 79  ointer currently
15050 20 70 6f 69 6e 74 73 20 74 6f 20 74 68 65 20 73   points to the s
15060 65 63 6f 6e 64 20 62 79 74 65 20 6f 66 20 61 20  econd byte of a 
15070 74 61 62 6c 65 2d 68 65 61 64 65 72 2e 0a 2a 2a  table-header..**
15080 20 53 70 65 63 69 66 69 63 61 6c 6c 79 2c 20 74   Specifically, t
15090 6f 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a  o the following:
150a0 0a 2a 2a 0a 2a 2a 20 20 20 2b 20 6e 75 6d 62 65  .**.**   + numbe
150b0 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20  r of columns in 
150c0 74 61 62 6c 65 20 28 76 61 72 69 6e 74 29 0a 2a  table (varint).*
150d0 2a 20 20 20 2b 20 61 72 72 61 79 20 6f 66 20 50  *   + array of P
150e0 4b 20 66 6c 61 67 73 20 28 31 20 62 79 74 65 20  K flags (1 byte 
150f0 70 65 72 20 63 6f 6c 75 6d 6e 29 2c 0a 2a 2a 20  per column),.** 
15100 20 20 2b 20 74 61 62 6c 65 20 6e 61 6d 65 20 28    + table name (
15110 6e 75 6c 20 74 65 72 6d 69 6e 61 74 65 64 29 2e  nul terminated).
15120 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  .**.** This func
15130 74 69 6f 6e 20 65 6e 73 75 72 65 73 20 74 68 61  tion ensures tha
15140 74 20 61 6c 6c 20 6f 66 20 74 68 65 20 61 62 6f  t all of the abo
15150 76 65 20 69 73 20 70 72 65 73 65 6e 74 20 69 6e  ve is present in
15160 20 74 68 65 20 69 6e 70 75 74 20 0a 2a 2a 20 62   the input .** b
15170 75 66 66 65 72 20 28 69 2e 65 2e 20 74 68 61 74  uffer (i.e. that
15180 20 69 74 20 63 61 6e 20 62 65 20 61 63 63 65 73   it can be acces
15190 73 65 64 20 77 69 74 68 6f 75 74 20 61 6e 79 20  sed without any 
151a0 63 61 6c 6c 73 20 74 6f 20 78 49 6e 70 75 74 28  calls to xInput(
151b0 29 29 2e 0a 2a 2a 20 49 66 20 73 75 63 63 65 73  ))..** If succes
151c0 73 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b 20  sful, SQLITE_OK 
151d0 69 73 20 72 65 74 75 72 6e 65 64 2e 20 4f 74 68  is returned. Oth
151e0 65 72 77 69 73 65 2c 20 61 6e 20 53 51 4c 69 74  erwise, an SQLit
151f0 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a  e error code..**
15200 20 54 68 65 20 69 6e 70 75 74 20 70 6f 69 6e 74   The input point
15210 65 72 20 69 73 20 6e 6f 74 20 6d 6f 76 65 64 2e  er is not moved.
15220 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73  .*/.static int s
15230 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65 74 42  essionChangesetB
15240 75 66 66 65 72 54 62 6c 68 64 72 28 53 65 73 73  ufferTblhdr(Sess
15250 69 6f 6e 49 6e 70 75 74 20 2a 70 49 6e 2c 20 69  ionInput *pIn, i
15260 6e 74 20 2a 70 6e 42 79 74 65 29 7b 0a 20 20 69  nt *pnByte){.  i
15270 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
15280 4b 3b 0a 20 20 69 6e 74 20 6e 43 6f 6c 20 3d 20  K;.  int nCol = 
15290 30 3b 0a 20 20 69 6e 74 20 6e 52 65 61 64 20 3d  0;.  int nRead =
152a0 20 30 3b 0a 0a 20 20 72 63 20 3d 20 73 65 73 73   0;..  rc = sess
152b0 69 6f 6e 49 6e 70 75 74 42 75 66 66 65 72 28 70  ionInputBuffer(p
152c0 49 6e 2c 20 39 29 3b 0a 20 20 69 66 28 20 72 63  In, 9);.  if( rc
152d0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
152e0 20 20 20 6e 52 65 61 64 20 2b 3d 20 73 65 73 73     nRead += sess
152f0 69 6f 6e 56 61 72 69 6e 74 47 65 74 28 26 70 49  ionVarintGet(&pI
15300 6e 2d 3e 61 44 61 74 61 5b 70 49 6e 2d 3e 69 4e  n->aData[pIn->iN
15310 65 78 74 20 2b 20 6e 52 65 61 64 5d 2c 20 26 6e  ext + nRead], &n
15320 43 6f 6c 29 3b 0a 20 20 20 20 72 63 20 3d 20 73  Col);.    rc = s
15330 65 73 73 69 6f 6e 49 6e 70 75 74 42 75 66 66 65  essionInputBuffe
15340 72 28 70 49 6e 2c 20 6e 52 65 61 64 2b 6e 43 6f  r(pIn, nRead+nCo
15350 6c 2b 31 30 30 29 3b 0a 20 20 20 20 6e 52 65 61  l+100);.    nRea
15360 64 20 2b 3d 20 6e 43 6f 6c 3b 0a 20 20 7d 0a 0a  d += nCol;.  }..
15370 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c    while( rc==SQL
15380 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 77 68  ITE_OK ){.    wh
15390 69 6c 65 28 20 28 70 49 6e 2d 3e 69 4e 65 78 74  ile( (pIn->iNext
153a0 20 2b 20 6e 52 65 61 64 29 3c 70 49 6e 2d 3e 6e   + nRead)<pIn->n
153b0 44 61 74 61 20 26 26 20 70 49 6e 2d 3e 61 44 61  Data && pIn->aDa
153c0 74 61 5b 70 49 6e 2d 3e 69 4e 65 78 74 20 2b 20  ta[pIn->iNext + 
153d0 6e 52 65 61 64 5d 20 29 7b 0a 20 20 20 20 20 20  nRead] ){.      
153e0 6e 52 65 61 64 2b 2b 3b 0a 20 20 20 20 7d 0a 20  nRead++;.    }. 
153f0 20 20 20 69 66 28 20 28 70 49 6e 2d 3e 69 4e 65     if( (pIn->iNe
15400 78 74 20 2b 20 6e 52 65 61 64 29 3c 70 49 6e 2d  xt + nRead)<pIn-
15410 3e 6e 44 61 74 61 20 29 20 62 72 65 61 6b 3b 0a  >nData ) break;.
15420 20 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e      rc = session
15430 49 6e 70 75 74 42 75 66 66 65 72 28 70 49 6e 2c  InputBuffer(pIn,
15440 20 6e 52 65 61 64 20 2b 20 31 30 30 29 3b 0a 20   nRead + 100);. 
15450 20 7d 0a 20 20 2a 70 6e 42 79 74 65 20 3d 20 6e   }.  *pnByte = n
15460 52 65 61 64 2b 31 3b 0a 20 20 72 65 74 75 72 6e  Read+1;.  return
15470 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
15480 65 20 69 6e 70 75 74 20 70 6f 69 6e 74 65 72 20  e input pointer 
15490 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73  currently points
154a0 20 74 6f 20 74 68 65 20 66 69 72 73 74 20 62 79   to the first by
154b0 74 65 20 6f 66 20 74 68 65 20 66 69 72 73 74 20  te of the first 
154c0 66 69 65 6c 64 0a 2a 2a 20 6f 66 20 61 20 72 65  field.** of a re
154d0 63 6f 72 64 20 63 6f 6e 73 69 73 74 69 6e 67 20  cord consisting 
154e0 6f 66 20 6e 43 6f 6c 20 63 6f 6c 75 6d 6e 73 2e  of nCol columns.
154f0 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 65   This function e
15500 6e 73 75 72 65 73 20 74 68 65 20 65 6e 74 69 72  nsures the entir
15510 65 0a 2a 2a 20 72 65 63 6f 72 64 20 69 73 20 62  e.** record is b
15520 75 66 66 65 72 65 64 2e 20 49 74 20 64 6f 65 73  uffered. It does
15530 20 6e 6f 74 20 6d 6f 76 65 20 74 68 65 20 69 6e   not move the in
15540 70 75 74 20 70 6f 69 6e 74 65 72 2e 0a 2a 2a 0a  put pointer..**.
15550 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c  ** If successful
15560 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72  , SQLITE_OK is r
15570 65 74 75 72 6e 65 64 20 61 6e 64 20 2a 70 6e 42  eturned and *pnB
15580 79 74 65 20 69 73 20 73 65 74 20 74 6f 20 74 68  yte is set to th
15590 65 20 73 69 7a 65 20 6f 66 0a 2a 2a 20 74 68 65  e size of.** the
155a0 20 72 65 63 6f 72 64 20 69 6e 20 62 79 74 65 73   record in bytes
155b0 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 61 6e 20  . Otherwise, an 
155c0 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
155d0 65 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 54  e is returned. T
155e0 68 65 0a 2a 2a 20 66 69 6e 61 6c 20 76 61 6c 75  he.** final valu
155f0 65 20 6f 66 20 2a 70 6e 42 79 74 65 20 69 73 20  e of *pnByte is 
15600 75 6e 64 65 66 69 6e 65 64 20 69 6e 20 74 68 69  undefined in thi
15610 73 20 63 61 73 65 2e 0a 2a 2f 0a 73 74 61 74 69  s case..*/.stati
15620 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 43 68 61  c int sessionCha
15630 6e 67 65 73 65 74 42 75 66 66 65 72 52 65 63 6f  ngesetBufferReco
15640 72 64 28 0a 20 20 53 65 73 73 69 6f 6e 49 6e 70  rd(.  SessionInp
15650 75 74 20 2a 70 49 6e 2c 20 20 20 20 20 20 20 20  ut *pIn,        
15660 20 20 20 20 20 20 2f 2a 20 49 6e 70 75 74 20 64        /* Input d
15670 61 74 61 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f  ata */.  int nCo
15680 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
15690 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
156a0 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e  er of columns in
156b0 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20 69 6e 74   record */.  int
156c0 20 2a 70 6e 42 79 74 65 20 20 20 20 20 20 20 20   *pnByte        
156d0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
156e0 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20 72 65 63  OUT: Size of rec
156f0 6f 72 64 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  ord in bytes */.
15700 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
15710 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e  LITE_OK;.  int n
15720 42 79 74 65 20 3d 20 30 3b 0a 20 20 69 6e 74 20  Byte = 0;.  int 
15730 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 72 63  i;.  for(i=0; rc
15740 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69  ==SQLITE_OK && i
15750 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20  <nCol; i++){.   
15760 20 69 6e 74 20 65 54 79 70 65 3b 0a 20 20 20 20   int eType;.    
15770 72 63 20 3d 20 73 65 73 73 69 6f 6e 49 6e 70 75  rc = sessionInpu
15780 74 42 75 66 66 65 72 28 70 49 6e 2c 20 6e 42 79  tBuffer(pIn, nBy
15790 74 65 20 2b 20 31 30 29 3b 0a 20 20 20 20 69 66  te + 10);.    if
157a0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
157b0 29 7b 0a 20 20 20 20 20 20 65 54 79 70 65 20 3d  ){.      eType =
157c0 20 70 49 6e 2d 3e 61 44 61 74 61 5b 70 49 6e 2d   pIn->aData[pIn-
157d0 3e 69 4e 65 78 74 20 2b 20 6e 42 79 74 65 2b 2b  >iNext + nByte++
157e0 5d 3b 0a 20 20 20 20 20 20 69 66 28 20 65 54 79  ];.      if( eTy
157f0 70 65 3d 3d 53 51 4c 49 54 45 5f 54 45 58 54 20  pe==SQLITE_TEXT 
15800 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45  || eType==SQLITE
15810 5f 42 4c 4f 42 20 29 7b 0a 20 20 20 20 20 20 20  _BLOB ){.       
15820 20 69 6e 74 20 6e 3b 0a 20 20 20 20 20 20 20 20   int n;.        
15830 6e 42 79 74 65 20 2b 3d 20 73 65 73 73 69 6f 6e  nByte += session
15840 56 61 72 69 6e 74 47 65 74 28 26 70 49 6e 2d 3e  VarintGet(&pIn->
15850 61 44 61 74 61 5b 70 49 6e 2d 3e 69 4e 65 78 74  aData[pIn->iNext
15860 2b 6e 42 79 74 65 5d 2c 20 26 6e 29 3b 0a 20 20  +nByte], &n);.  
15870 20 20 20 20 20 20 6e 42 79 74 65 20 2b 3d 20 6e        nByte += n
15880 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73  ;.        rc = s
15890 65 73 73 69 6f 6e 49 6e 70 75 74 42 75 66 66 65  essionInputBuffe
158a0 72 28 70 49 6e 2c 20 6e 42 79 74 65 29 3b 0a 20  r(pIn, nByte);. 
158b0 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 65       }else if( e
158c0 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54  Type==SQLITE_INT
158d0 45 47 45 52 20 7c 7c 20 65 54 79 70 65 3d 3d 53  EGER || eType==S
158e0 51 4c 49 54 45 5f 46 4c 4f 41 54 20 29 7b 0a 20  QLITE_FLOAT ){. 
158f0 20 20 20 20 20 20 20 6e 42 79 74 65 20 2b 3d 20         nByte += 
15900 38 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  8;.      }.    }
15910 0a 20 20 7d 0a 20 20 2a 70 6e 42 79 74 65 20 3d  .  }.  *pnByte =
15920 20 6e 42 79 74 65 3b 0a 20 20 72 65 74 75 72 6e   nByte;.  return
15930 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
15940 65 20 69 6e 70 75 74 20 70 6f 69 6e 74 65 72 20  e input pointer 
15950 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73  currently points
15960 20 74 6f 20 74 68 65 20 73 65 63 6f 6e 64 20 62   to the second b
15970 79 74 65 20 6f 66 20 61 20 74 61 62 6c 65 2d 68  yte of a table-h
15980 65 61 64 65 72 2e 0a 2a 2a 20 53 70 65 63 69 66  eader..** Specif
15990 69 63 61 6c 6c 79 2c 20 74 6f 20 74 68 65 20 66  ically, to the f
159a0 6f 6c 6c 6f 77 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20  ollowing:.**.** 
159b0 20 20 2b 20 6e 75 6d 62 65 72 20 6f 66 20 63 6f    + number of co
159c0 6c 75 6d 6e 73 20 69 6e 20 74 61 62 6c 65 20 28  lumns in table (
159d0 76 61 72 69 6e 74 29 0a 2a 2a 20 20 20 2b 20 61  varint).**   + a
159e0 72 72 61 79 20 6f 66 20 50 4b 20 66 6c 61 67 73  rray of PK flags
159f0 20 28 31 20 62 79 74 65 20 70 65 72 20 63 6f 6c   (1 byte per col
15a00 75 6d 6e 29 2c 0a 2a 2a 20 20 20 2b 20 74 61 62  umn),.**   + tab
15a10 6c 65 20 6e 61 6d 65 20 28 6e 75 6c 20 74 65 72  le name (nul ter
15a20 6d 69 6e 61 74 65 64 29 2e 0a 2a 2a 0a 2a 2a 20  minated)..**.** 
15a30 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 64 65  This function de
15a40 63 6f 64 65 73 20 74 68 65 20 74 61 62 6c 65 2d  codes the table-
15a50 68 65 61 64 65 72 20 61 6e 64 20 70 6f 70 75 6c  header and popul
15a60 61 74 65 73 20 74 68 65 20 70 2d 3e 6e 43 6f 6c  ates the p->nCol
15a70 2c 20 0a 2a 2a 20 70 2d 3e 7a 54 61 62 20 61 6e  , .** p->zTab an
15a80 64 20 70 2d 3e 61 62 50 4b 5b 5d 20 76 61 72 69  d p->abPK[] vari
15a90 61 62 6c 65 73 20 61 63 63 6f 72 64 69 6e 67 6c  ables accordingl
15aa0 79 2e 20 54 68 65 20 70 2d 3e 61 70 56 61 6c 75  y. The p->apValu
15ab0 65 5b 5d 20 61 72 72 61 79 20 69 73 20 0a 2a 2a  e[] array is .**
15ac0 20 61 6c 73 6f 20 61 6c 6c 6f 63 61 74 65 64 20   also allocated 
15ad0 6f 72 20 72 65 73 69 7a 65 64 20 61 63 63 6f 72  or resized accor
15ae0 64 69 6e 67 20 74 6f 20 74 68 65 20 6e 65 77 20  ding to the new 
15af0 76 61 6c 75 65 20 6f 66 20 70 2d 3e 6e 43 6f 6c  value of p->nCol
15b00 2e 20 54 68 65 0a 2a 2a 20 69 6e 70 75 74 20 70  . The.** input p
15b10 6f 69 6e 74 65 72 20 69 73 20 6c 65 66 74 20 70  ointer is left p
15b20 6f 69 6e 74 69 6e 67 20 74 6f 20 74 68 65 20 62  ointing to the b
15b30 79 74 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68  yte following th
15b40 65 20 74 61 62 6c 65 20 68 65 61 64 65 72 2e 0a  e table header..
15b50 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65 73 73  **.** If success
15b60 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69  ful, SQLITE_OK i
15b70 73 20 72 65 74 75 72 6e 65 64 2e 20 4f 74 68 65  s returned. Othe
15b80 72 77 69 73 65 2c 20 61 6e 20 53 51 4c 69 74 65  rwise, an SQLite
15b90 20 65 72 72 6f 72 20 63 6f 64 65 0a 2a 2a 20 69   error code.** i
15ba0 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 74  s returned and t
15bb0 68 65 20 66 69 6e 61 6c 20 76 61 6c 75 65 73 20  he final values 
15bc0 6f 66 20 74 68 65 20 76 61 72 69 6f 75 73 20 66  of the various f
15bd0 69 65 6c 64 73 20 65 6e 75 6d 65 72 61 74 65 64  ields enumerated
15be0 20 61 62 6f 76 65 0a 2a 2a 20 61 72 65 20 75 6e   above.** are un
15bf0 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74  defined..*/.stat
15c00 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 43 68  ic int sessionCh
15c10 61 6e 67 65 73 65 74 52 65 61 64 54 62 6c 68 64  angesetReadTblhd
15c20 72 28 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65  r(sqlite3_change
15c30 73 65 74 5f 69 74 65 72 20 2a 70 29 7b 0a 20 20  set_iter *p){.  
15c40 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 6e 43  int rc;.  int nC
15c50 6f 70 79 3b 0a 20 20 61 73 73 65 72 74 28 20 70  opy;.  assert( p
15c60 2d 3e 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ->rc==SQLITE_OK 
15c70 29 3b 0a 0a 20 20 72 63 20 3d 20 73 65 73 73 69  );..  rc = sessi
15c80 6f 6e 43 68 61 6e 67 65 73 65 74 42 75 66 66 65  onChangesetBuffe
15c90 72 54 62 6c 68 64 72 28 26 70 2d 3e 69 6e 2c 20  rTblhdr(&p->in, 
15ca0 26 6e 43 6f 70 79 29 3b 0a 20 20 69 66 28 20 72  &nCopy);.  if( r
15cb0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
15cc0 20 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20      int nByte;. 
15cd0 20 20 20 69 6e 74 20 6e 56 61 72 69 6e 74 3b 0a     int nVarint;.
15ce0 20 20 20 20 6e 56 61 72 69 6e 74 20 3d 20 73 65      nVarint = se
15cf0 73 73 69 6f 6e 56 61 72 69 6e 74 47 65 74 28 26  ssionVarintGet(&
15d00 70 2d 3e 69 6e 2e 61 44 61 74 61 5b 70 2d 3e 69  p->in.aData[p->i
15d10 6e 2e 69 4e 65 78 74 5d 2c 20 26 70 2d 3e 6e 43  n.iNext], &p->nC
15d20 6f 6c 29 3b 0a 20 20 20 20 6e 43 6f 70 79 20 2d  ol);.    nCopy -
15d30 3d 20 6e 56 61 72 69 6e 74 3b 0a 20 20 20 20 70  = nVarint;.    p
15d40 2d 3e 69 6e 2e 69 4e 65 78 74 20 2b 3d 20 6e 56  ->in.iNext += nV
15d50 61 72 69 6e 74 3b 0a 20 20 20 20 6e 42 79 74 65  arint;.    nByte
15d60 20 3d 20 70 2d 3e 6e 43 6f 6c 20 2a 20 73 69 7a   = p->nCol * siz
15d70 65 6f 66 28 73 71 6c 69 74 65 33 5f 76 61 6c 75  eof(sqlite3_valu
15d80 65 2a 29 20 2a 20 32 20 2b 20 6e 43 6f 70 79 3b  e*) * 2 + nCopy;
15d90 0a 20 20 20 20 70 2d 3e 74 62 6c 68 64 72 2e 6e  .    p->tblhdr.n
15da0 42 75 66 20 3d 20 30 3b 0a 20 20 20 20 73 65 73  Buf = 0;.    ses
15db0 73 69 6f 6e 42 75 66 66 65 72 47 72 6f 77 28 26  sionBufferGrow(&
15dc0 70 2d 3e 74 62 6c 68 64 72 2c 20 6e 42 79 74 65  p->tblhdr, nByte
15dd0 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 69  , &rc);.  }..  i
15de0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
15df0 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 50 4b 20   ){.    int iPK 
15e00 3d 20 73 69 7a 65 6f 66 28 73 71 6c 69 74 65 33  = sizeof(sqlite3
15e10 5f 76 61 6c 75 65 2a 29 2a 70 2d 3e 6e 43 6f 6c  _value*)*p->nCol
15e20 2a 32 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28 70  *2;.    memset(p
15e30 2d 3e 74 62 6c 68 64 72 2e 61 42 75 66 2c 20 30  ->tblhdr.aBuf, 0
15e40 2c 20 69 50 4b 29 3b 0a 20 20 20 20 6d 65 6d 63  , iPK);.    memc
15e50 70 79 28 26 70 2d 3e 74 62 6c 68 64 72 2e 61 42  py(&p->tblhdr.aB
15e60 75 66 5b 69 50 4b 5d 2c 20 26 70 2d 3e 69 6e 2e  uf[iPK], &p->in.
15e70 61 44 61 74 61 5b 70 2d 3e 69 6e 2e 69 4e 65 78  aData[p->in.iNex
15e80 74 5d 2c 20 6e 43 6f 70 79 29 3b 0a 20 20 20 20  t], nCopy);.    
15e90 70 2d 3e 69 6e 2e 69 4e 65 78 74 20 2b 3d 20 6e  p->in.iNext += n
15ea0 43 6f 70 79 3b 0a 20 20 7d 0a 0a 20 20 70 2d 3e  Copy;.  }..  p->
15eb0 61 70 56 61 6c 75 65 20 3d 20 28 73 71 6c 69 74  apValue = (sqlit
15ec0 65 33 5f 76 61 6c 75 65 2a 2a 29 70 2d 3e 74 62  e3_value**)p->tb
15ed0 6c 68 64 72 2e 61 42 75 66 3b 0a 20 20 70 2d 3e  lhdr.aBuf;.  p->
15ee0 61 62 50 4b 20 3d 20 28 75 38 2a 29 26 70 2d 3e  abPK = (u8*)&p->
15ef0 61 70 56 61 6c 75 65 5b 70 2d 3e 6e 43 6f 6c 2a  apValue[p->nCol*
15f00 32 5d 3b 0a 20 20 70 2d 3e 7a 54 61 62 20 3d 20  2];.  p->zTab = 
15f10 28 63 68 61 72 2a 29 26 70 2d 3e 61 62 50 4b 5b  (char*)&p->abPK[
15f20 70 2d 3e 6e 43 6f 6c 5d 3b 0a 20 20 72 65 74 75  p->nCol];.  retu
15f30 72 6e 20 28 70 2d 3e 72 63 20 3d 20 72 63 29 3b  rn (p->rc = rc);
15f40 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63  .}../*.** Advanc
15f50 65 20 74 68 65 20 63 68 61 6e 67 65 73 65 74 20  e the changeset 
15f60 69 74 65 72 61 74 6f 72 20 74 6f 20 74 68 65 20  iterator to the 
15f70 6e 65 78 74 20 63 68 61 6e 67 65 2e 0a 2a 2a 0a  next change..**.
15f80 2a 2a 20 49 66 20 62 6f 74 68 20 70 61 52 65 63  ** If both paRec
15f90 20 61 6e 64 20 70 6e 52 65 63 20 61 72 65 20 4e   and pnRec are N
15fa0 55 4c 4c 2c 20 74 68 65 6e 20 74 68 69 73 20 66  ULL, then this f
15fb0 75 6e 63 74 69 6f 6e 20 77 6f 72 6b 73 20 6c 69  unction works li
15fc0 6b 65 20 74 68 65 20 70 75 62 6c 69 63 0a 2a 2a  ke the public.**
15fd0 20 41 50 49 20 73 71 6c 69 74 65 33 63 68 61 6e   API sqlite3chan
15fe0 67 65 73 65 74 5f 6e 65 78 74 28 29 2e 20 49 66  geset_next(). If
15ff0 20 53 51 4c 49 54 45 5f 52 4f 57 20 69 73 20 72   SQLITE_ROW is r
16000 65 74 75 72 6e 65 64 2c 20 74 68 65 6e 20 74 68  eturned, then th
16010 65 0a 2a 2a 20 73 71 6c 69 74 65 33 63 68 61 6e  e.** sqlite3chan
16020 67 65 73 65 74 5f 6e 65 77 28 29 20 61 6e 64 20  geset_new() and 
16030 6f 6c 64 28 29 20 41 50 49 73 20 6d 61 79 20 62  old() APIs may b
16040 65 20 75 73 65 64 20 74 6f 20 71 75 65 72 79 20  e used to query 
16050 66 6f 72 20 76 61 6c 75 65 73 2e 0a 2a 2a 0a 2a  for values..**.*
16060 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20  * Otherwise, if 
16070 70 61 52 65 63 20 61 6e 64 20 70 6e 52 65 63 20  paRec and pnRec 
16080 61 72 65 20 6e 6f 74 20 4e 55 4c 4c 2c 20 74 68  are not NULL, th
16090 65 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20  en a pointer to 
160a0 74 68 65 20 63 68 61 6e 67 65 0a 2a 2a 20 72 65  the change.** re
160b0 63 6f 72 64 20 69 73 20 77 72 69 74 74 65 6e 20  cord is written 
160c0 74 6f 20 2a 70 61 52 65 63 20 62 65 66 6f 72 65  to *paRec before
160d0 20 72 65 74 75 72 6e 69 6e 67 20 61 6e 64 20 74   returning and t
160e0 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  he number of byt
160f0 65 73 20 69 6e 0a 2a 2a 20 74 68 65 20 72 65 63  es in.** the rec
16100 6f 72 64 20 74 6f 20 2a 70 6e 52 65 63 2e 0a 2a  ord to *pnRec..*
16110 2a 0a 2a 2a 20 45 69 74 68 65 72 20 77 61 79 2c  *.** Either way,
16120 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72   this function r
16130 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 52 4f  eturns SQLITE_RO
16140 57 20 69 66 20 74 68 65 20 69 74 65 72 61 74 6f  W if the iterato
16150 72 20 69 73 20 0a 2a 2a 20 73 75 63 63 65 73 73  r is .** success
16160 66 75 6c 6c 79 20 61 64 76 61 6e 63 65 64 20 74  fully advanced t
16170 6f 20 74 68 65 20 6e 65 78 74 20 63 68 61 6e 67  o the next chang
16180 65 20 69 6e 20 74 68 65 20 63 68 61 6e 67 65 73  e in the changes
16190 65 74 2c 20 61 6e 20 53 51 4c 69 74 65 20 0a 2a  et, an SQLite .*
161a0 2a 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20  * error code if 
161b0 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c  an error occurs,
161c0 20 6f 72 20 53 51 4c 49 54 45 5f 44 4f 4e 45 20   or SQLITE_DONE 
161d0 69 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20  if there are no 
161e0 66 75 72 74 68 65 72 20 0a 2a 2a 20 63 68 61 6e  further .** chan
161f0 67 65 73 20 69 6e 20 74 68 65 20 63 68 61 6e 67  ges in the chang
16200 65 73 65 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  eset..*/.static 
16210 69 6e 74 20 73 65 73 73 69 6f 6e 43 68 61 6e 67  int sessionChang
16220 65 73 65 74 4e 65 78 74 28 0a 20 20 73 71 6c 69  esetNext(.  sqli
16230 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74  te3_changeset_it
16240 65 72 20 2a 70 2c 20 20 20 20 20 20 2f 2a 20 43  er *p,      /* C
16250 68 61 6e 67 65 73 65 74 20 69 74 65 72 61 74 6f  hangeset iterato
16260 72 20 2a 2f 0a 20 20 75 38 20 2a 2a 70 61 52 65  r */.  u8 **paRe
16270 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c,              
16280 20 20 20 20 20 20 20 2f 2a 20 49 66 20 6e 6f 6e         /* If non
16290 2d 4e 55 4c 4c 2c 20 73 74 6f 72 65 20 72 65 63  -NULL, store rec
162a0 6f 72 64 20 70 6f 69 6e 74 65 72 20 68 65 72 65  ord pointer here
162b0 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 52 65 63   */.  int *pnRec
162c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
162d0 20 20 20 20 20 20 2f 2a 20 49 66 20 6e 6f 6e 2d        /* If non-
162e0 4e 55 4c 4c 2c 20 73 74 6f 72 65 20 73 69 7a 65  NULL, store size
162f0 20 6f 66 20 72 65 63 6f 72 64 20 68 65 72 65 20   of record here 
16300 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  */.){.  int i;. 
16310 20 75 38 20 6f 70 3b 0a 0a 20 20 61 73 73 65 72   u8 op;..  asser
16320 74 28 20 28 70 61 52 65 63 3d 3d 30 20 26 26 20  t( (paRec==0 && 
16330 70 6e 52 65 63 3d 3d 30 29 20 7c 7c 20 28 70 61  pnRec==0) || (pa
16340 52 65 63 20 26 26 20 70 6e 52 65 63 29 20 29 3b  Rec && pnRec) );
16350 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 69 74  ..  /* If the it
16360 65 72 61 74 6f 72 20 69 73 20 69 6e 20 74 68 65  erator is in the
16370 20 65 72 72 6f 72 2d 73 74 61 74 65 2c 20 72 65   error-state, re
16380 74 75 72 6e 20 69 6d 6d 65 64 69 61 74 65 6c 79  turn immediately
16390 2e 20 2a 2f 0a 20 20 69 66 28 20 70 2d 3e 72 63  . */.  if( p->rc
163a0 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
163b0 74 75 72 6e 20 70 2d 3e 72 63 3b 0a 0a 20 20 2f  turn p->rc;..  /
163c0 2a 20 46 72 65 65 20 74 68 65 20 63 75 72 72 65  * Free the curre
163d0 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 70  nt contents of p
163e0 2d 3e 61 70 56 61 6c 75 65 5b 5d 2c 20 69 66 20  ->apValue[], if 
163f0 61 6e 79 2e 20 2a 2f 0a 20 20 69 66 28 20 70 2d  any. */.  if( p-
16400 3e 61 70 56 61 6c 75 65 20 29 7b 0a 20 20 20 20  >apValue ){.    
16410 66 6f 72 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 43  for(i=0; i<p->nC
16420 6f 6c 2a 32 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  ol*2; i++){.    
16430 20 20 73 71 6c 69 74 65 33 56 61 6c 75 65 46 72    sqlite3ValueFr
16440 65 65 28 70 2d 3e 61 70 56 61 6c 75 65 5b 69 5d  ee(p->apValue[i]
16450 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d  );.    }.    mem
16460 73 65 74 28 70 2d 3e 61 70 56 61 6c 75 65 2c 20  set(p->apValue, 
16470 30 2c 20 73 69 7a 65 6f 66 28 73 71 6c 69 74 65  0, sizeof(sqlite
16480 33 5f 76 61 6c 75 65 2a 29 2a 70 2d 3e 6e 43 6f  3_value*)*p->nCo
16490 6c 2a 32 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  l*2);.  }..  /* 
164a0 4d 61 6b 65 20 73 75 72 65 20 74 68 65 20 62 75  Make sure the bu
164b0 66 66 65 72 20 63 6f 6e 74 61 69 6e 73 20 61 74  ffer contains at
164c0 20 6c 65 61 73 74 20 31 30 20 62 79 74 65 73 20   least 10 bytes 
164d0 6f 66 20 69 6e 70 75 74 20 64 61 74 61 2c 20 6f  of input data, o
164e0 72 20 61 6c 6c 0a 20 20 2a 2a 20 72 65 6d 61 69  r all.  ** remai
164f0 6e 69 6e 67 20 64 61 74 61 20 69 66 20 74 68 65  ning data if the
16500 72 65 20 61 72 65 20 6c 65 73 73 20 74 68 61 6e  re are less than
16510 20 31 30 20 62 79 74 65 73 20 61 76 61 69 6c 61   10 bytes availa
16520 62 6c 65 2e 20 54 68 69 73 20 69 73 0a 20 20 2a  ble. This is.  *
16530 2a 20 73 75 66 66 69 63 69 65 6e 74 20 65 69 74  * sufficient eit
16540 68 65 72 20 66 6f 72 20 74 68 65 20 27 54 27 20  her for the 'T' 
16550 6f 72 20 27 50 27 20 62 79 74 65 20 61 6e 64 20  or 'P' byte and 
16560 74 68 65 20 76 61 72 69 6e 74 20 74 68 61 74 20  the varint that 
16570 66 6f 6c 6c 6f 77 73 0a 20 20 2a 2a 20 69 74 2c  follows.  ** it,
16580 20 6f 72 20 66 6f 72 20 74 68 65 20 74 77 6f 20   or for the two 
16590 73 69 6e 67 6c 65 20 62 79 74 65 20 76 61 6c 75  single byte valu
165a0 65 73 20 6f 74 68 65 72 77 69 73 65 2e 20 2a 2f  es otherwise. */
165b0 0a 20 20 70 2d 3e 72 63 20 3d 20 73 65 73 73 69  .  p->rc = sessi
165c0 6f 6e 49 6e 70 75 74 42 75 66 66 65 72 28 26 70  onInputBuffer(&p
165d0 2d 3e 69 6e 2c 20 32 29 3b 0a 20 20 69 66 28 20  ->in, 2);.  if( 
165e0 70 2d 3e 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  p->rc!=SQLITE_OK
165f0 20 29 20 72 65 74 75 72 6e 20 70 2d 3e 72 63 3b   ) return p->rc;
16600 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 69 74  ..  /* If the it
16610 65 72 61 74 6f 72 20 69 73 20 61 6c 72 65 61 64  erator is alread
16620 79 20 61 74 20 74 68 65 20 65 6e 64 20 6f 66 20  y at the end of 
16630 74 68 65 20 63 68 61 6e 67 65 73 65 74 2c 20 72  the changeset, r
16640 65 74 75 72 6e 20 44 4f 4e 45 2e 20 2a 2f 0a 20  eturn DONE. */. 
16650 20 69 66 28 20 70 2d 3e 69 6e 2e 69 4e 65 78 74   if( p->in.iNext
16660 3e 3d 70 2d 3e 69 6e 2e 6e 44 61 74 61 20 29 7b  >=p->in.nData ){
16670 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
16680 54 45 5f 44 4f 4e 45 3b 0a 20 20 7d 0a 0a 20 20  TE_DONE;.  }..  
16690 73 65 73 73 69 6f 6e 44 69 73 63 61 72 64 44 61  sessionDiscardDa
166a0 74 61 28 26 70 2d 3e 69 6e 29 3b 0a 20 20 70 2d  ta(&p->in);.  p-
166b0 3e 69 6e 2e 69 43 75 72 72 65 6e 74 20 3d 20 70  >in.iCurrent = p
166c0 2d 3e 69 6e 2e 69 4e 65 78 74 3b 0a 0a 20 20 6f  ->in.iNext;..  o
166d0 70 20 3d 20 70 2d 3e 69 6e 2e 61 44 61 74 61 5b  p = p->in.aData[
166e0 70 2d 3e 69 6e 2e 69 4e 65 78 74 2b 2b 5d 3b 0a  p->in.iNext++];.
166f0 20 20 69 66 28 20 6f 70 3d 3d 27 54 27 20 7c 7c    if( op=='T' ||
16700 20 6f 70 3d 3d 27 50 27 20 29 7b 0a 20 20 20 20   op=='P' ){.    
16710 70 2d 3e 62 50 61 74 63 68 73 65 74 20 3d 20 28  p->bPatchset = (
16720 6f 70 3d 3d 27 50 27 29 3b 0a 20 20 20 20 69 66  op=='P');.    if
16730 28 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73  ( sessionChanges
16740 65 74 52 65 61 64 54 62 6c 68 64 72 28 70 29 20  etReadTblhdr(p) 
16750 29 20 72 65 74 75 72 6e 20 70 2d 3e 72 63 3b 0a  ) return p->rc;.
16760 20 20 20 20 69 66 28 20 28 70 2d 3e 72 63 20 3d      if( (p->rc =
16770 20 73 65 73 73 69 6f 6e 49 6e 70 75 74 42 75 66   sessionInputBuf
16780 66 65 72 28 26 70 2d 3e 69 6e 2c 20 32 29 29 20  fer(&p->in, 2)) 
16790 29 20 72 65 74 75 72 6e 20 70 2d 3e 72 63 3b 0a  ) return p->rc;.
167a0 20 20 20 20 70 2d 3e 69 6e 2e 69 43 75 72 72 65      p->in.iCurre
167b0 6e 74 20 3d 20 70 2d 3e 69 6e 2e 69 4e 65 78 74  nt = p->in.iNext
167c0 3b 0a 20 20 20 20 6f 70 20 3d 20 70 2d 3e 69 6e  ;.    op = p->in
167d0 2e 61 44 61 74 61 5b 70 2d 3e 69 6e 2e 69 4e 65  .aData[p->in.iNe
167e0 78 74 2b 2b 5d 3b 0a 20 20 7d 0a 0a 20 20 70 2d  xt++];.  }..  p-
167f0 3e 6f 70 20 3d 20 6f 70 3b 0a 20 20 70 2d 3e 62  >op = op;.  p->b
16800 49 6e 64 69 72 65 63 74 20 3d 20 70 2d 3e 69 6e  Indirect = p->in
16810 2e 61 44 61 74 61 5b 70 2d 3e 69 6e 2e 69 4e 65  .aData[p->in.iNe
16820 78 74 2b 2b 5d 3b 0a 20 20 69 66 28 20 70 2d 3e  xt++];.  if( p->
16830 6f 70 21 3d 53 51 4c 49 54 45 5f 55 50 44 41 54  op!=SQLITE_UPDAT
16840 45 20 26 26 20 70 2d 3e 6f 70 21 3d 53 51 4c 49  E && p->op!=SQLI
16850 54 45 5f 44 45 4c 45 54 45 20 26 26 20 70 2d 3e  TE_DELETE && p->
16860 6f 70 21 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52  op!=SQLITE_INSER
16870 54 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  T ){.    return 
16880 28 70 2d 3e 72 63 20 3d 20 53 51 4c 49 54 45 5f  (p->rc = SQLITE_
16890 43 4f 52 52 55 50 54 5f 42 4b 50 54 29 3b 0a 20  CORRUPT_BKPT);. 
168a0 20 7d 0a 0a 20 20 69 66 28 20 70 61 52 65 63 20   }..  if( paRec 
168b0 29 7b 20 0a 20 20 20 20 69 6e 74 20 6e 56 61 6c  ){ .    int nVal
168c0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
168d0 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
168e0 6f 66 20 76 61 6c 75 65 73 20 74 6f 20 62 75 66  of values to buf
168f0 66 65 72 20 2a 2f 0a 20 20 20 20 69 66 28 20 70  fer */.    if( p
16900 2d 3e 62 50 61 74 63 68 73 65 74 3d 3d 30 20 26  ->bPatchset==0 &
16910 26 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 55 50 44  & op==SQLITE_UPD
16920 41 54 45 20 29 7b 0a 20 20 20 20 20 20 6e 56 61  ATE ){.      nVa
16930 6c 20 3d 20 70 2d 3e 6e 43 6f 6c 20 2a 20 32 3b  l = p->nCol * 2;
16940 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70  .    }else if( p
16950 2d 3e 62 50 61 74 63 68 73 65 74 20 26 26 20 6f  ->bPatchset && o
16960 70 3d 3d 53 51 4c 49 54 45 5f 44 45 4c 45 54 45  p==SQLITE_DELETE
16970 20 29 7b 0a 20 20 20 20 20 20 6e 56 61 6c 20 3d   ){.      nVal =
16980 20 30 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d   0;.      for(i=
16990 30 3b 20 69 3c 70 2d 3e 6e 43 6f 6c 3b 20 69 2b  0; i<p->nCol; i+
169a0 2b 29 20 69 66 28 20 70 2d 3e 61 62 50 4b 5b 69  +) if( p->abPK[i
169b0 5d 20 29 20 6e 56 61 6c 2b 2b 3b 0a 20 20 20 20  ] ) nVal++;.    
169c0 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6e 56 61  }else{.      nVa
169d0 6c 20 3d 20 70 2d 3e 6e 43 6f 6c 3b 0a 20 20 20  l = p->nCol;.   
169e0 20 7d 0a 20 20 20 20 70 2d 3e 72 63 20 3d 20 73   }.    p->rc = s
169f0 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65 74 42  essionChangesetB
16a00 75 66 66 65 72 52 65 63 6f 72 64 28 26 70 2d 3e  ufferRecord(&p->
16a10 69 6e 2c 20 6e 56 61 6c 2c 20 70 6e 52 65 63 29  in, nVal, pnRec)
16a20 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 72 63 21  ;.    if( p->rc!
16a30 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
16a40 75 72 6e 20 70 2d 3e 72 63 3b 0a 20 20 20 20 2a  urn p->rc;.    *
16a50 70 61 52 65 63 20 3d 20 26 70 2d 3e 69 6e 2e 61  paRec = &p->in.a
16a60 44 61 74 61 5b 70 2d 3e 69 6e 2e 69 4e 65 78 74  Data[p->in.iNext
16a70 5d 3b 0a 20 20 20 20 70 2d 3e 69 6e 2e 69 4e 65  ];.    p->in.iNe
16a80 78 74 20 2b 3d 20 2a 70 6e 52 65 63 3b 0a 20 20  xt += *pnRec;.  
16a90 7d 65 6c 73 65 7b 0a 0a 20 20 20 20 2f 2a 20 49  }else{..    /* I
16aa0 66 20 74 68 69 73 20 69 73 20 61 6e 20 55 50 44  f this is an UPD
16ab0 41 54 45 20 6f 72 20 44 45 4c 45 54 45 2c 20 72  ATE or DELETE, r
16ac0 65 61 64 20 74 68 65 20 6f 6c 64 2e 2a 20 72 65  ead the old.* re
16ad0 63 6f 72 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28  cord. */.    if(
16ae0 20 70 2d 3e 6f 70 21 3d 53 51 4c 49 54 45 5f 49   p->op!=SQLITE_I
16af0 4e 53 45 52 54 20 26 26 20 28 70 2d 3e 62 50 61  NSERT && (p->bPa
16b00 74 63 68 73 65 74 3d 3d 30 20 7c 7c 20 70 2d 3e  tchset==0 || p->
16b10 6f 70 3d 3d 53 51 4c 49 54 45 5f 44 45 4c 45 54  op==SQLITE_DELET
16b20 45 29 20 29 7b 0a 20 20 20 20 20 20 75 38 20 2a  E) ){.      u8 *
16b30 61 62 50 4b 20 3d 20 70 2d 3e 62 50 61 74 63 68  abPK = p->bPatch
16b40 73 65 74 20 3f 20 70 2d 3e 61 62 50 4b 20 3a 20  set ? p->abPK : 
16b50 30 3b 0a 20 20 20 20 20 20 70 2d 3e 72 63 20 3d  0;.      p->rc =
16b60 20 73 65 73 73 69 6f 6e 52 65 61 64 52 65 63 6f   sessionReadReco
16b70 72 64 28 26 70 2d 3e 69 6e 2c 20 70 2d 3e 6e 43  rd(&p->in, p->nC
16b80 6f 6c 2c 20 61 62 50 4b 2c 20 70 2d 3e 61 70 56  ol, abPK, p->apV
16b90 61 6c 75 65 29 3b 0a 20 20 20 20 20 20 69 66 28  alue);.      if(
16ba0 20 70 2d 3e 72 63 21 3d 53 51 4c 49 54 45 5f 4f   p->rc!=SQLITE_O
16bb0 4b 20 29 20 72 65 74 75 72 6e 20 70 2d 3e 72 63  K ) return p->rc
16bc0 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20  ;.    }..    /* 
16bd0 49 66 20 74 68 69 73 20 69 73 20 61 6e 20 49 4e  If this is an IN
16be0 53 45 52 54 20 6f 72 20 55 50 44 41 54 45 2c 20  SERT or UPDATE, 
16bf0 72 65 61 64 20 74 68 65 20 6e 65 77 2e 2a 20 72  read the new.* r
16c00 65 63 6f 72 64 2e 20 2a 2f 0a 20 20 20 20 69 66  ecord. */.    if
16c10 28 20 70 2d 3e 6f 70 21 3d 53 51 4c 49 54 45 5f  ( p->op!=SQLITE_
16c20 44 45 4c 45 54 45 20 29 7b 0a 20 20 20 20 20 20  DELETE ){.      
16c30 70 2d 3e 72 63 20 3d 20 73 65 73 73 69 6f 6e 52  p->rc = sessionR
16c40 65 61 64 52 65 63 6f 72 64 28 26 70 2d 3e 69 6e  eadRecord(&p->in
16c50 2c 20 70 2d 3e 6e 43 6f 6c 2c 20 30 2c 20 26 70  , p->nCol, 0, &p
16c60 2d 3e 61 70 56 61 6c 75 65 5b 70 2d 3e 6e 43 6f  ->apValue[p->nCo
16c70 6c 5d 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70  l]);.      if( p
16c80 2d 3e 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ->rc!=SQLITE_OK 
16c90 29 20 72 65 74 75 72 6e 20 70 2d 3e 72 63 3b 0a  ) return p->rc;.
16ca0 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 70      }..    if( p
16cb0 2d 3e 62 50 61 74 63 68 73 65 74 20 26 26 20 70  ->bPatchset && p
16cc0 2d 3e 6f 70 3d 3d 53 51 4c 49 54 45 5f 55 50 44  ->op==SQLITE_UPD
16cd0 41 54 45 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  ATE ){.      /* 
16ce0 49 66 20 74 68 69 73 20 69 73 20 61 6e 20 55 50  If this is an UP
16cf0 44 41 54 45 20 74 68 61 74 20 69 73 20 70 61 72  DATE that is par
16d00 74 20 6f 66 20 61 20 70 61 74 63 68 73 65 74 2c  t of a patchset,
16d10 20 74 68 65 6e 20 61 6c 6c 20 50 4b 20 61 6e 64   then all PK and
16d20 0a 20 20 20 20 20 20 2a 2a 20 6d 6f 64 69 66 69  .      ** modifi
16d30 65 64 20 66 69 65 6c 64 73 20 61 72 65 20 70 72  ed fields are pr
16d40 65 73 65 6e 74 20 69 6e 20 74 68 65 20 6e 65 77  esent in the new
16d50 2e 2a 20 72 65 63 6f 72 64 2e 20 54 68 65 20 6f  .* record. The o
16d60 6c 64 2e 2a 20 72 65 63 6f 72 64 0a 20 20 20 20  ld.* record.    
16d70 20 20 2a 2a 20 69 73 20 63 75 72 72 65 6e 74 6c    ** is currentl
16d80 79 20 63 6f 6d 70 6c 65 74 65 6c 79 20 65 6d 70  y completely emp
16d90 74 79 2e 20 54 68 69 73 20 62 6c 6f 63 6b 20 73  ty. This block s
16da0 68 69 66 74 73 20 74 68 65 20 50 4b 20 66 69 65  hifts the PK fie
16db0 6c 64 73 20 66 72 6f 6d 0a 20 20 20 20 20 20 2a  lds from.      *
16dc0 2a 20 6e 65 77 2e 2a 20 74 6f 20 6f 6c 64 2e 2a  * new.* to old.*
16dd0 2c 20 74 6f 20 61 63 63 6f 6d 6d 6f 64 61 74 65  , to accommodate
16de0 20 74 68 65 20 63 6f 64 65 20 74 68 61 74 20 72   the code that r
16df0 65 61 64 73 20 74 68 65 73 65 20 61 72 72 61 79  eads these array
16e00 73 2e 20 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72  s.  */.      for
16e10 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 43 6f 6c 3b  (i=0; i<p->nCol;
16e20 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 61   i++){.        a
16e30 73 73 65 72 74 28 20 70 2d 3e 61 70 56 61 6c 75  ssert( p->apValu
16e40 65 5b 69 5d 3d 3d 30 20 29 3b 0a 20 20 20 20 20  e[i]==0 );.     
16e50 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61 62     assert( p->ab
16e60 50 4b 5b 69 5d 3d 3d 30 20 7c 7c 20 70 2d 3e 61  PK[i]==0 || p->a
16e70 70 56 61 6c 75 65 5b 69 2b 70 2d 3e 6e 43 6f 6c  pValue[i+p->nCol
16e80 5d 20 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  ] );.        if(
16e90 20 70 2d 3e 61 62 50 4b 5b 69 5d 20 29 7b 0a 20   p->abPK[i] ){. 
16ea0 20 20 20 20 20 20 20 20 20 70 2d 3e 61 70 56 61           p->apVa
16eb0 6c 75 65 5b 69 5d 20 3d 20 70 2d 3e 61 70 56 61  lue[i] = p->apVa
16ec0 6c 75 65 5b 69 2b 70 2d 3e 6e 43 6f 6c 5d 3b 0a  lue[i+p->nCol];.
16ed0 20 20 20 20 20 20 20 20 20 20 70 2d 3e 61 70 56            p->apV
16ee0 61 6c 75 65 5b 69 2b 70 2d 3e 6e 43 6f 6c 5d 20  alue[i+p->nCol] 
16ef0 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  = 0;.        }. 
16f00 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
16f10 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ..  return SQLIT
16f20 45 5f 52 4f 57 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  E_ROW;.}../*.** 
16f30 41 64 76 61 6e 63 65 20 61 6e 20 69 74 65 72 61  Advance an itera
16f40 74 6f 72 20 63 72 65 61 74 65 64 20 62 79 20 73  tor created by s
16f50 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
16f60 73 74 61 72 74 28 29 20 74 6f 20 74 68 65 20 6e  start() to the n
16f70 65 78 74 0a 2a 2a 20 63 68 61 6e 67 65 20 69 6e  ext.** change in
16f80 20 74 68 65 20 63 68 61 6e 67 65 73 65 74 2e 20   the changeset. 
16f90 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 6d 61  This function ma
16fa0 79 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  y return SQLITE_
16fb0 52 4f 57 2c 20 53 51 4c 49 54 45 5f 44 4f 4e 45  ROW, SQLITE_DONE
16fc0 0a 2a 2a 20 6f 72 20 53 51 4c 49 54 45 5f 43 4f  .** or SQLITE_CO
16fd0 52 52 55 50 54 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  RRUPT..**.** Thi
16fe0 73 20 66 75 6e 63 74 69 6f 6e 20 6d 61 79 20 6e  s function may n
16ff0 6f 74 20 62 65 20 63 61 6c 6c 65 64 20 6f 6e 20  ot be called on 
17000 69 74 65 72 61 74 6f 72 73 20 70 61 73 73 65 64  iterators passed
17010 20 74 6f 20 61 20 63 6f 6e 66 6c 69 63 74 20 68   to a conflict h
17020 61 6e 64 6c 65 72 0a 2a 2a 20 63 61 6c 6c 62 61  andler.** callba
17030 63 6b 20 62 79 20 63 68 61 6e 67 65 73 65 74 5f  ck by changeset_
17040 61 70 70 6c 79 28 29 2e 0a 2a 2f 0a 69 6e 74 20  apply()..*/.int 
17050 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
17060 5f 6e 65 78 74 28 73 71 6c 69 74 65 33 5f 63 68  _next(sqlite3_ch
17070 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a 70 29  angeset_iter *p)
17080 7b 0a 20 20 72 65 74 75 72 6e 20 73 65 73 73 69  {.  return sessi
17090 6f 6e 43 68 61 6e 67 65 73 65 74 4e 65 78 74 28  onChangesetNext(
170a0 70 2c 20 30 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a  p, 0, 0);.}../*.
170b0 2a 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  ** The following
170c0 20 66 75 6e 63 74 69 6f 6e 20 65 78 74 72 61 63   function extrac
170d0 74 73 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 6f  ts information o
170e0 6e 20 74 68 65 20 63 75 72 72 65 6e 74 20 63 68  n the current ch
170f0 61 6e 67 65 0a 2a 2a 20 66 72 6f 6d 20 61 20 63  ange.** from a c
17100 68 61 6e 67 65 73 65 74 20 69 74 65 72 61 74 6f  hangeset iterato
17110 72 2e 20 49 74 20 6d 61 79 20 6f 6e 6c 79 20 62  r. It may only b
17120 65 20 63 61 6c 6c 65 64 20 61 66 74 65 72 20 63  e called after c
17130 68 61 6e 67 65 73 65 74 5f 6e 65 78 74 28 29 0a  hangeset_next().
17140 2a 2a 20 68 61 73 20 72 65 74 75 72 6e 65 64 20  ** has returned 
17150 53 51 4c 49 54 45 5f 52 4f 57 2e 0a 2a 2f 0a 69  SQLITE_ROW..*/.i
17160 6e 74 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65  nt sqlite3change
17170 73 65 74 5f 6f 70 28 0a 20 20 73 71 6c 69 74 65  set_op(.  sqlite
17180 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72  3_changeset_iter
17190 20 2a 70 49 74 65 72 2c 20 20 2f 2a 20 49 74 65   *pIter,  /* Ite
171a0 72 61 74 6f 72 20 68 61 6e 64 6c 65 20 2a 2f 0a  rator handle */.
171b0 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 70    const char **p
171c0 7a 54 61 62 2c 20 20 20 20 20 20 20 20 20 20 20  zTab,           
171d0 20 20 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65    /* OUT: Pointe
171e0 72 20 74 6f 20 74 61 62 6c 65 20 6e 61 6d 65 20  r to table name 
171f0 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 43 6f 6c 2c  */.  int *pnCol,
17200 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17210 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d       /* OUT: Num
17220 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69  ber of columns i
17230 6e 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74  n table */.  int
17240 20 2a 70 4f 70 2c 20 20 20 20 20 20 20 20 20 20   *pOp,          
17250 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
17260 4f 55 54 3a 20 53 51 4c 49 54 45 5f 49 4e 53 45  OUT: SQLITE_INSE
17270 52 54 2c 20 44 45 4c 45 54 45 20 6f 72 20 55 50  RT, DELETE or UP
17280 44 41 54 45 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  DATE */.  int *p
17290 62 49 6e 64 69 72 65 63 74 20 20 20 20 20 20 20  bIndirect       
172a0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
172b0 3a 20 54 72 75 65 20 69 66 20 63 68 61 6e 67 65  : True if change
172c0 20 69 73 20 69 6e 64 69 72 65 63 74 20 2a 2f 0a   is indirect */.
172d0 29 7b 0a 20 20 2a 70 4f 70 20 3d 20 70 49 74 65  ){.  *pOp = pIte
172e0 72 2d 3e 6f 70 3b 0a 20 20 2a 70 6e 43 6f 6c 20  r->op;.  *pnCol 
172f0 3d 20 70 49 74 65 72 2d 3e 6e 43 6f 6c 3b 0a 20  = pIter->nCol;. 
17300 20 2a 70 7a 54 61 62 20 3d 20 70 49 74 65 72 2d   *pzTab = pIter-
17310 3e 7a 54 61 62 3b 0a 20 20 69 66 28 20 70 62 49  >zTab;.  if( pbI
17320 6e 64 69 72 65 63 74 20 29 20 2a 70 62 49 6e 64  ndirect ) *pbInd
17330 69 72 65 63 74 20 3d 20 70 49 74 65 72 2d 3e 62  irect = pIter->b
17340 49 6e 64 69 72 65 63 74 3b 0a 20 20 72 65 74 75  Indirect;.  retu
17350 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
17360 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 69 6e  ./*.** Return in
17370 66 6f 72 6d 61 74 69 6f 6e 20 72 65 67 61 72 64  formation regard
17380 69 6e 67 20 74 68 65 20 50 52 49 4d 41 52 59 20  ing the PRIMARY 
17390 4b 45 59 20 61 6e 64 20 6e 75 6d 62 65 72 20 6f  KEY and number o
173a0 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 0a 2a 2a 20  f columns in.** 
173b0 74 68 65 20 64 61 74 61 62 61 73 65 20 74 61 62  the database tab
173c0 6c 65 20 61 66 66 65 63 74 65 64 20 62 79 20 74  le affected by t
173d0 68 65 20 63 68 61 6e 67 65 20 74 68 61 74 20 70  he change that p
173e0 49 74 65 72 20 63 75 72 72 65 6e 74 6c 79 20 70  Iter currently p
173f0 6f 69 6e 74 73 0a 2a 2a 20 74 6f 2e 20 54 68 69  oints.** to. Thi
17400 73 20 66 75 6e 63 74 69 6f 6e 20 6d 61 79 20 6f  s function may o
17410 6e 6c 79 20 62 65 20 63 61 6c 6c 65 64 20 61 66  nly be called af
17420 74 65 72 20 63 68 61 6e 67 65 73 65 74 5f 6e 65  ter changeset_ne
17430 78 74 28 29 20 72 65 74 75 72 6e 73 0a 2a 2a 20  xt() returns.** 
17440 53 51 4c 49 54 45 5f 52 4f 57 2e 0a 2a 2f 0a 69  SQLITE_ROW..*/.i
17450 6e 74 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65  nt sqlite3change
17460 73 65 74 5f 70 6b 28 0a 20 20 73 71 6c 69 74 65  set_pk(.  sqlite
17470 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72  3_changeset_iter
17480 20 2a 70 49 74 65 72 2c 20 20 2f 2a 20 49 74 65   *pIter,  /* Ite
17490 72 61 74 6f 72 20 6f 62 6a 65 63 74 20 2a 2f 0a  rator object */.
174a0 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20    unsigned char 
174b0 2a 2a 70 61 62 50 4b 2c 20 20 20 20 20 20 20 20  **pabPK,        
174c0 20 20 2f 2a 20 4f 55 54 3a 20 41 72 72 61 79 20    /* OUT: Array 
174d0 6f 66 20 62 6f 6f 6c 65 61 6e 20 2d 20 74 72 75  of boolean - tru
174e0 65 20 66 6f 72 20 50 4b 20 63 6f 6c 73 20 2a 2f  e for PK cols */
174f0 0a 20 20 69 6e 74 20 2a 70 6e 43 6f 6c 20 20 20  .  int *pnCol   
17500 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17510 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d 62 65     /* OUT: Numbe
17520 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20  r of entries in 
17530 6f 75 74 70 75 74 20 61 72 72 61 79 20 2a 2f 0a  output array */.
17540 29 7b 0a 20 20 2a 70 61 62 50 4b 20 3d 20 70 49  ){.  *pabPK = pI
17550 74 65 72 2d 3e 61 62 50 4b 3b 0a 20 20 69 66 28  ter->abPK;.  if(
17560 20 70 6e 43 6f 6c 20 29 20 2a 70 6e 43 6f 6c 20   pnCol ) *pnCol 
17570 3d 20 70 49 74 65 72 2d 3e 6e 43 6f 6c 3b 0a 20  = pIter->nCol;. 
17580 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
17590 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  K;.}../*.** This
175a0 20 66 75 6e 63 74 69 6f 6e 20 6d 61 79 20 6f 6e   function may on
175b0 6c 79 20 62 65 20 63 61 6c 6c 65 64 20 77 68 69  ly be called whi
175c0 6c 65 20 74 68 65 20 69 74 65 72 61 74 6f 72 20  le the iterator 
175d0 69 73 20 70 6f 69 6e 74 69 6e 67 20 74 6f 20 61  is pointing to a
175e0 6e 0a 2a 2a 20 53 51 4c 49 54 45 5f 55 50 44 41  n.** SQLITE_UPDA
175f0 54 45 20 6f 72 20 53 51 4c 49 54 45 5f 44 45 4c  TE or SQLITE_DEL
17600 45 54 45 20 63 68 61 6e 67 65 20 28 73 65 65 20  ETE change (see 
17610 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
17620 5f 6f 70 28 29 29 2e 0a 2a 2a 20 4f 74 68 65 72  _op())..** Other
17630 77 69 73 65 2c 20 53 51 4c 49 54 45 5f 4d 49 53  wise, SQLITE_MIS
17640 55 53 45 20 69 73 20 72 65 74 75 72 6e 65 64 2e  USE is returned.
17650 0a 2a 2a 0a 2a 2a 20 49 74 20 73 65 74 73 20 2a  .**.** It sets *
17660 70 70 56 61 6c 75 65 20 74 6f 20 70 6f 69 6e 74  ppValue to point
17670 20 74 6f 20 61 6e 20 73 71 6c 69 74 65 33 5f 76   to an sqlite3_v
17680 61 6c 75 65 20 73 74 72 75 63 74 75 72 65 20 63  alue structure c
17690 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 0a 2a 2a  ontaining the.**
176a0 20 69 56 61 6c 27 74 68 20 76 61 6c 75 65 20 69   iVal'th value i
176b0 6e 20 74 68 65 20 6f 6c 64 2e 2a 20 72 65 63 6f  n the old.* reco
176c0 72 64 2e 20 4f 72 2c 20 69 66 20 74 68 61 74 20  rd. Or, if that 
176d0 70 61 72 74 69 63 75 6c 61 72 20 76 61 6c 75 65  particular value
176e0 20 69 73 20 6e 6f 74 0a 2a 2a 20 69 6e 63 6c 75   is not.** inclu
176f0 64 65 64 20 69 6e 20 74 68 65 20 72 65 63 6f 72  ded in the recor
17700 64 20 28 62 65 63 61 75 73 65 20 74 68 65 20 63  d (because the c
17710 68 61 6e 67 65 20 69 73 20 61 6e 20 55 50 44 41  hange is an UPDA
17720 54 45 20 61 6e 64 20 74 68 65 20 66 69 65 6c 64  TE and the field
17730 0a 2a 2a 20 77 61 73 20 6e 6f 74 20 6d 6f 64 69  .** was not modi
17740 66 69 65 64 20 61 6e 64 20 69 73 20 6e 6f 74 20  fied and is not 
17750 61 20 50 4b 20 63 6f 6c 75 6d 6e 29 2c 20 73 65  a PK column), se
17760 74 20 2a 70 70 56 61 6c 75 65 20 74 6f 20 4e 55  t *ppValue to NU
17770 4c 4c 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 76 61 6c  LL..**.** If val
17780 75 65 20 69 56 61 6c 20 69 73 20 6f 75 74 2d 6f  ue iVal is out-o
17790 66 2d 72 61 6e 67 65 2c 20 53 51 4c 49 54 45 5f  f-range, SQLITE_
177a0 52 41 4e 47 45 20 69 73 20 72 65 74 75 72 6e 65  RANGE is returne
177b0 64 20 61 6e 64 20 2a 70 70 56 61 6c 75 65 20 69  d and *ppValue i
177c0 73 0a 2a 2a 20 6e 6f 74 20 6d 6f 64 69 66 69 65  s.** not modifie
177d0 64 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 53 51  d. Otherwise, SQ
177e0 4c 49 54 45 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74 20  LITE_OK..*/.int 
177f0 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
17800 5f 6f 6c 64 28 0a 20 20 73 71 6c 69 74 65 33 5f  _old(.  sqlite3_
17810 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a  changeset_iter *
17820 70 49 74 65 72 2c 20 20 2f 2a 20 43 68 61 6e 67  pIter,  /* Chang
17830 65 73 65 74 20 69 74 65 72 61 74 6f 72 20 2a 2f  eset iterator */
17840 0a 20 20 69 6e 74 20 69 56 61 6c 2c 20 20 20 20  .  int iVal,    
17850 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17860 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6f     /* Index of o
17870 6c 64 2e 2a 20 76 61 6c 75 65 20 74 6f 20 72 65  ld.* value to re
17880 74 72 69 65 76 65 20 2a 2f 0a 20 20 73 71 6c 69  trieve */.  sqli
17890 74 65 33 5f 76 61 6c 75 65 20 2a 2a 70 70 56 61  te3_value **ppVa
178a0 6c 75 65 20 20 20 20 20 20 20 20 20 2f 2a 20 4f  lue         /* O
178b0 55 54 3a 20 4f 6c 64 20 76 61 6c 75 65 20 28 6f  UT: Old value (o
178c0 72 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 29 20  r NULL pointer) 
178d0 2a 2f 0a 29 7b 0a 20 20 69 66 28 20 70 49 74 65  */.){.  if( pIte
178e0 72 2d 3e 6f 70 21 3d 53 51 4c 49 54 45 5f 55 50  r->op!=SQLITE_UP
178f0 44 41 54 45 20 26 26 20 70 49 74 65 72 2d 3e 6f  DATE && pIter->o
17900 70 21 3d 53 51 4c 49 54 45 5f 44 45 4c 45 54 45  p!=SQLITE_DELETE
17910 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
17920 51 4c 49 54 45 5f 4d 49 53 55 53 45 3b 0a 20 20  QLITE_MISUSE;.  
17930 7d 0a 20 20 69 66 28 20 69 56 61 6c 3c 30 20 7c  }.  if( iVal<0 |
17940 7c 20 69 56 61 6c 3e 3d 70 49 74 65 72 2d 3e 6e  | iVal>=pIter->n
17950 43 6f 6c 20 29 7b 0a 20 20 20 20 72 65 74 75 72  Col ){.    retur
17960 6e 20 53 51 4c 49 54 45 5f 52 41 4e 47 45 3b 0a  n SQLITE_RANGE;.
17970 20 20 7d 0a 20 20 2a 70 70 56 61 6c 75 65 20 3d    }.  *ppValue =
17980 20 70 49 74 65 72 2d 3e 61 70 56 61 6c 75 65 5b   pIter->apValue[
17990 69 56 61 6c 5d 3b 0a 20 20 72 65 74 75 72 6e 20  iVal];.  return 
179a0 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
179b0 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
179c0 6e 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 63 61  n may only be ca
179d0 6c 6c 65 64 20 77 68 69 6c 65 20 74 68 65 20 69  lled while the i
179e0 74 65 72 61 74 6f 72 20 69 73 20 70 6f 69 6e 74  terator is point
179f0 69 6e 67 20 74 6f 20 61 6e 0a 2a 2a 20 53 51 4c  ing to an.** SQL
17a00 49 54 45 5f 55 50 44 41 54 45 20 6f 72 20 53 51  ITE_UPDATE or SQ
17a10 4c 49 54 45 5f 49 4e 53 45 52 54 20 63 68 61 6e  LITE_INSERT chan
17a20 67 65 20 28 73 65 65 20 73 71 6c 69 74 65 33 63  ge (see sqlite3c
17a30 68 61 6e 67 65 73 65 74 5f 6f 70 28 29 29 2e 0a  hangeset_op())..
17a40 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 53 51  ** Otherwise, SQ
17a50 4c 49 54 45 5f 4d 49 53 55 53 45 20 69 73 20 72  LITE_MISUSE is r
17a60 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 49  eturned..**.** I
17a70 74 20 73 65 74 73 20 2a 70 70 56 61 6c 75 65 20  t sets *ppValue 
17a80 74 6f 20 70 6f 69 6e 74 20 74 6f 20 61 6e 20 73  to point to an s
17a90 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 73 74 72  qlite3_value str
17aa0 75 63 74 75 72 65 20 63 6f 6e 74 61 69 6e 69 6e  ucture containin
17ab0 67 20 74 68 65 0a 2a 2a 20 69 56 61 6c 27 74 68  g the.** iVal'th
17ac0 20 76 61 6c 75 65 20 69 6e 20 74 68 65 20 6e 65   value in the ne
17ad0 77 2e 2a 20 72 65 63 6f 72 64 2e 20 4f 72 2c 20  w.* record. Or, 
17ae0 69 66 20 74 68 61 74 20 70 61 72 74 69 63 75 6c  if that particul
17af0 61 72 20 76 61 6c 75 65 20 69 73 20 6e 6f 74 0a  ar value is not.
17b00 2a 2a 20 69 6e 63 6c 75 64 65 64 20 69 6e 20 74  ** included in t
17b10 68 65 20 72 65 63 6f 72 64 20 28 62 65 63 61 75  he record (becau
17b20 73 65 20 74 68 65 20 63 68 61 6e 67 65 20 69 73  se the change is
17b30 20 61 6e 20 55 50 44 41 54 45 20 61 6e 64 20 74   an UPDATE and t
17b40 68 65 20 66 69 65 6c 64 0a 2a 2a 20 77 61 73 20  he field.** was 
17b50 6e 6f 74 20 6d 6f 64 69 66 69 65 64 29 2c 20 73  not modified), s
17b60 65 74 20 2a 70 70 56 61 6c 75 65 20 74 6f 20 4e  et *ppValue to N
17b70 55 4c 4c 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 76 61  ULL..**.** If va
17b80 6c 75 65 20 69 56 61 6c 20 69 73 20 6f 75 74 2d  lue iVal is out-
17b90 6f 66 2d 72 61 6e 67 65 2c 20 53 51 4c 49 54 45  of-range, SQLITE
17ba0 5f 52 41 4e 47 45 20 69 73 20 72 65 74 75 72 6e  _RANGE is return
17bb0 65 64 20 61 6e 64 20 2a 70 70 56 61 6c 75 65 20  ed and *ppValue 
17bc0 69 73 0a 2a 2a 20 6e 6f 74 20 6d 6f 64 69 66 69  is.** not modifi
17bd0 65 64 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 53  ed. Otherwise, S
17be0 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74  QLITE_OK..*/.int
17bf0 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
17c00 74 5f 6e 65 77 28 0a 20 20 73 71 6c 69 74 65 33  t_new(.  sqlite3
17c10 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20  _changeset_iter 
17c20 2a 70 49 74 65 72 2c 20 20 2f 2a 20 43 68 61 6e  *pIter,  /* Chan
17c30 67 65 73 65 74 20 69 74 65 72 61 74 6f 72 20 2a  geset iterator *
17c40 2f 0a 20 20 69 6e 74 20 69 56 61 6c 2c 20 20 20  /.  int iVal,   
17c50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17c60 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20      /* Index of 
17c70 6e 65 77 2e 2a 20 76 61 6c 75 65 20 74 6f 20 72  new.* value to r
17c80 65 74 72 69 65 76 65 20 2a 2f 0a 20 20 73 71 6c  etrieve */.  sql
17c90 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 70 70 56  ite3_value **ppV
17ca0 61 6c 75 65 20 20 20 20 20 20 20 20 20 2f 2a 20  alue         /* 
17cb0 4f 55 54 3a 20 4e 65 77 20 76 61 6c 75 65 20 28  OUT: New value (
17cc0 6f 72 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 29  or NULL pointer)
17cd0 20 2a 2f 0a 29 7b 0a 20 20 69 66 28 20 70 49 74   */.){.  if( pIt
17ce0 65 72 2d 3e 6f 70 21 3d 53 51 4c 49 54 45 5f 55  er->op!=SQLITE_U
17cf0 50 44 41 54 45 20 26 26 20 70 49 74 65 72 2d 3e  PDATE && pIter->
17d00 6f 70 21 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52  op!=SQLITE_INSER
17d10 54 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  T ){.    return 
17d20 53 51 4c 49 54 45 5f 4d 49 53 55 53 45 3b 0a 20  SQLITE_MISUSE;. 
17d30 20 7d 0a 20 20 69 66 28 20 69 56 61 6c 3c 30 20   }.  if( iVal<0 
17d40 7c 7c 20 69 56 61 6c 3e 3d 70 49 74 65 72 2d 3e  || iVal>=pIter->
17d50 6e 43 6f 6c 20 29 7b 0a 20 20 20 20 72 65 74 75  nCol ){.    retu
17d60 72 6e 20 53 51 4c 49 54 45 5f 52 41 4e 47 45 3b  rn SQLITE_RANGE;
17d70 0a 20 20 7d 0a 20 20 2a 70 70 56 61 6c 75 65 20  .  }.  *ppValue 
17d80 3d 20 70 49 74 65 72 2d 3e 61 70 56 61 6c 75 65  = pIter->apValue
17d90 5b 70 49 74 65 72 2d 3e 6e 43 6f 6c 2b 69 56 61  [pIter->nCol+iVa
17da0 6c 5d 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  l];.  return SQL
17db0 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
17dc0 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74   The following t
17dd0 77 6f 20 6d 61 63 72 6f 73 20 61 72 65 20 75 73  wo macros are us
17de0 65 64 20 69 6e 74 65 72 6e 61 6c 6c 79 2e 20 54  ed internally. T
17df0 68 65 79 20 61 72 65 20 73 69 6d 69 6c 61 72 20  hey are similar 
17e00 74 6f 20 74 68 65 0a 2a 2a 20 73 71 6c 69 74 65  to the.** sqlite
17e10 33 63 68 61 6e 67 65 73 65 74 5f 6e 65 77 28 29  3changeset_new()
17e20 20 61 6e 64 20 73 71 6c 69 74 65 33 63 68 61 6e   and sqlite3chan
17e30 67 65 73 65 74 5f 6f 6c 64 28 29 20 66 75 6e 63  geset_old() func
17e40 74 69 6f 6e 73 2c 20 65 78 63 65 70 74 20 74 68  tions, except th
17e50 61 74 0a 2a 2a 20 74 68 65 79 20 6f 6d 69 74 20  at.** they omit 
17e60 61 6c 6c 20 65 72 72 6f 72 20 63 68 65 63 6b 69  all error checki
17e70 6e 67 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20  ng and return a 
17e80 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 72  pointer to the r
17e90 65 71 75 65 73 74 65 64 20 76 61 6c 75 65 2e 0a  equested value..
17ea0 2a 2f 0a 23 64 65 66 69 6e 65 20 73 65 73 73 69  */.#define sessi
17eb0 6f 6e 43 68 61 6e 67 65 73 65 74 4e 65 77 28 70  onChangesetNew(p
17ec0 49 74 65 72 2c 20 69 56 61 6c 29 20 28 70 49 74  Iter, iVal) (pIt
17ed0 65 72 29 2d 3e 61 70 56 61 6c 75 65 5b 28 70 49  er)->apValue[(pI
17ee0 74 65 72 29 2d 3e 6e 43 6f 6c 2b 28 69 56 61 6c  ter)->nCol+(iVal
17ef0 29 5d 0a 23 64 65 66 69 6e 65 20 73 65 73 73 69  )].#define sessi
17f00 6f 6e 43 68 61 6e 67 65 73 65 74 4f 6c 64 28 70  onChangesetOld(p
17f10 49 74 65 72 2c 20 69 56 61 6c 29 20 28 70 49 74  Iter, iVal) (pIt
17f20 65 72 29 2d 3e 61 70 56 61 6c 75 65 5b 28 69 56  er)->apValue[(iV
17f30 61 6c 29 5d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  al)]../*.** This
17f40 20 66 75 6e 63 74 69 6f 6e 20 6d 61 79 20 6f 6e   function may on
17f50 6c 79 20 62 65 20 63 61 6c 6c 65 64 20 77 69 74  ly be called wit
17f60 68 20 61 20 63 68 61 6e 67 65 73 65 74 20 69 74  h a changeset it
17f70 65 72 61 74 6f 72 20 74 68 61 74 20 68 61 73 20  erator that has 
17f80 62 65 65 6e 0a 2a 2a 20 70 61 73 73 65 64 20 74  been.** passed t
17f90 6f 20 61 6e 20 53 51 4c 49 54 45 5f 43 48 41 4e  o an SQLITE_CHAN
17fa0 47 45 53 45 54 5f 44 41 54 41 20 6f 72 20 53 51  GESET_DATA or SQ
17fb0 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 43  LITE_CHANGESET_C
17fc0 4f 4e 46 4c 49 43 54 20 0a 2a 2a 20 63 6f 6e 66  ONFLICT .** conf
17fd0 6c 69 63 74 2d 68 61 6e 64 6c 65 72 20 66 75 6e  lict-handler fun
17fe0 63 74 69 6f 6e 2e 20 4f 74 68 65 72 77 69 73 65  ction. Otherwise
17ff0 2c 20 53 51 4c 49 54 45 5f 4d 49 53 55 53 45 20  , SQLITE_MISUSE 
18000 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a  is returned..**.
18010 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c  ** If successful
18020 2c 20 2a 70 70 56 61 6c 75 65 20 69 73 20 73 65  , *ppValue is se
18030 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 61 6e  t to point to an
18040 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 73   sqlite3_value s
18050 74 72 75 63 74 75 72 65 0a 2a 2a 20 63 6f 6e 74  tructure.** cont
18060 61 69 6e 69 6e 67 20 74 68 65 20 69 56 61 6c 27  aining the iVal'
18070 74 68 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20  th value of the 
18080 63 6f 6e 66 6c 69 63 74 69 6e 67 20 72 65 63 6f  conflicting reco
18090 72 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 76 61 6c  rd..**.** If val
180a0 75 65 20 69 56 61 6c 20 69 73 20 6f 75 74 2d 6f  ue iVal is out-o
180b0 66 2d 72 61 6e 67 65 20 6f 72 20 73 6f 6d 65 20  f-range or some 
180c0 6f 74 68 65 72 20 65 72 72 6f 72 20 6f 63 63 75  other error occu
180d0 72 73 2c 20 61 6e 20 53 51 4c 69 74 65 20 65 72  rs, an SQLite er
180e0 72 6f 72 0a 2a 2a 20 63 6f 64 65 20 69 73 20 72  ror.** code is r
180f0 65 74 75 72 6e 65 64 2e 20 4f 74 68 65 72 77 69  eturned. Otherwi
18100 73 65 2c 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a  se, SQLITE_OK..*
18110 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 63 68 61  /.int sqlite3cha
18120 6e 67 65 73 65 74 5f 63 6f 6e 66 6c 69 63 74 28  ngeset_conflict(
18130 0a 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67  .  sqlite3_chang
18140 65 73 65 74 5f 69 74 65 72 20 2a 70 49 74 65 72  eset_iter *pIter
18150 2c 20 20 2f 2a 20 43 68 61 6e 67 65 73 65 74 20  ,  /* Changeset 
18160 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69 6e  iterator */.  in
18170 74 20 69 56 61 6c 2c 20 20 20 20 20 20 20 20 20  t iVal,         
18180 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
18190 20 49 6e 64 65 78 20 6f 66 20 63 6f 6e 66 6c 69   Index of confli
181a0 63 74 20 72 65 63 6f 72 64 20 76 61 6c 75 65 20  ct record value 
181b0 74 6f 20 66 65 74 63 68 20 2a 2f 0a 20 20 73 71  to fetch */.  sq
181c0 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 70 70  lite3_value **pp
181d0 56 61 6c 75 65 20 20 20 20 20 20 20 20 20 2f 2a  Value         /*
181e0 20 4f 55 54 3a 20 56 61 6c 75 65 20 66 72 6f 6d   OUT: Value from
181f0 20 63 6f 6e 66 6c 69 63 74 69 6e 67 20 72 6f 77   conflicting row
18200 20 2a 2f 0a 29 7b 0a 20 20 69 66 28 20 21 70 49   */.){.  if( !pI
18210 74 65 72 2d 3e 70 43 6f 6e 66 6c 69 63 74 20 29  ter->pConflict )
18220 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  {.    return SQL
18230 49 54 45 5f 4d 49 53 55 53 45 3b 0a 20 20 7d 0a  ITE_MISUSE;.  }.
18240 20 20 69 66 28 20 69 56 61 6c 3c 30 20 7c 7c 20    if( iVal<0 || 
18250 69 56 61 6c 3e 3d 73 71 6c 69 74 65 33 5f 63 6f  iVal>=sqlite3_co
18260 6c 75 6d 6e 5f 63 6f 75 6e 74 28 70 49 74 65 72  lumn_count(pIter
18270 2d 3e 70 43 6f 6e 66 6c 69 63 74 29 20 29 7b 0a  ->pConflict) ){.
18280 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
18290 45 5f 52 41 4e 47 45 3b 0a 20 20 7d 0a 20 20 2a  E_RANGE;.  }.  *
182a0 70 70 56 61 6c 75 65 20 3d 20 73 71 6c 69 74 65  ppValue = sqlite
182b0 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28 70  3_column_value(p
182c0 49 74 65 72 2d 3e 70 43 6f 6e 66 6c 69 63 74 2c  Iter->pConflict,
182d0 20 69 56 61 6c 29 3b 0a 20 20 72 65 74 75 72 6e   iVal);.  return
182e0 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
182f0 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
18300 6f 6e 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 63  on may only be c
18310 61 6c 6c 65 64 20 77 69 74 68 20 61 6e 20 69 74  alled with an it
18320 65 72 61 74 6f 72 20 70 61 73 73 65 64 20 74 6f  erator passed to
18330 20 61 6e 0a 2a 2a 20 53 51 4c 49 54 45 5f 43 48   an.** SQLITE_CH
18340 41 4e 47 45 53 45 54 5f 46 4f 52 45 49 47 4e 5f  ANGESET_FOREIGN_
18350 4b 45 59 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e  KEY conflict han
18360 64 6c 65 72 20 63 61 6c 6c 62 61 63 6b 2e 20 49  dler callback. I
18370 6e 20 74 68 69 73 20 63 61 73 65 0a 2a 2a 20 69  n this case.** i
18380 74 20 73 65 74 73 20 74 68 65 20 6f 75 74 70 75  t sets the outpu
18390 74 20 76 61 72 69 61 62 6c 65 20 74 6f 20 74 68  t variable to th
183a0 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f  e total number o
183b0 66 20 6b 6e 6f 77 6e 20 66 6f 72 65 69 67 6e 20  f known foreign 
183c0 6b 65 79 0a 2a 2a 20 76 69 6f 6c 61 74 69 6f 6e  key.** violation
183d0 73 20 69 6e 20 74 68 65 20 64 65 73 74 69 6e 61  s in the destina
183e0 74 69 6f 6e 20 64 61 74 61 62 61 73 65 20 61 6e  tion database an
183f0 64 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45  d returns SQLITE
18400 5f 4f 4b 2e 0a 2a 2a 0a 2a 2a 20 49 6e 20 61 6c  _OK..**.** In al
18410 6c 20 6f 74 68 65 72 20 63 61 73 65 73 20 74 68  l other cases th
18420 69 73 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75  is function retu
18430 72 6e 73 20 53 51 4c 49 54 45 5f 4d 49 53 55 53  rns SQLITE_MISUS
18440 45 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  E..*/.int sqlite
18450 33 63 68 61 6e 67 65 73 65 74 5f 66 6b 5f 63 6f  3changeset_fk_co
18460 6e 66 6c 69 63 74 73 28 0a 20 20 73 71 6c 69 74  nflicts(.  sqlit
18470 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65  e3_changeset_ite
18480 72 20 2a 70 49 74 65 72 2c 20 20 2f 2a 20 43 68  r *pIter,  /* Ch
18490 61 6e 67 65 73 65 74 20 69 74 65 72 61 74 6f 72  angeset iterator
184a0 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4f 75 74   */.  int *pnOut
184b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
184c0 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 75        /* OUT: Nu
184d0 6d 62 65 72 20 6f 66 20 46 4b 20 76 69 6f 6c 61  mber of FK viola
184e0 74 69 6f 6e 73 20 2a 2f 0a 29 7b 0a 20 20 69 66  tions */.){.  if
184f0 28 20 70 49 74 65 72 2d 3e 70 43 6f 6e 66 6c 69  ( pIter->pConfli
18500 63 74 20 7c 7c 20 70 49 74 65 72 2d 3e 61 70 56  ct || pIter->apV
18510 61 6c 75 65 20 29 7b 0a 20 20 20 20 72 65 74 75  alue ){.    retu
18520 72 6e 20 53 51 4c 49 54 45 5f 4d 49 53 55 53 45  rn SQLITE_MISUSE
18530 3b 0a 20 20 7d 0a 20 20 2a 70 6e 4f 75 74 20 3d  ;.  }.  *pnOut =
18540 20 70 49 74 65 72 2d 3e 6e 43 6f 6c 3b 0a 20 20   pIter->nCol;.  
18550 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
18560 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 61  ;.}.../*.** Fina
18570 6c 69 7a 65 20 61 6e 20 69 74 65 72 61 74 6f 72  lize an iterator
18580 20 61 6c 6c 6f 63 61 74 65 64 20 77 69 74 68 20   allocated with 
18590 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
185a0 5f 73 74 61 72 74 28 29 2e 0a 2a 2a 0a 2a 2a 20  _start()..**.** 
185b0 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 6d 61  This function ma
185c0 79 20 6e 6f 74 20 62 65 20 63 61 6c 6c 65 64 20  y not be called 
185d0 6f 6e 20 69 74 65 72 61 74 6f 72 73 20 70 61 73  on iterators pas
185e0 73 65 64 20 74 6f 20 61 20 63 6f 6e 66 6c 69 63  sed to a conflic
185f0 74 20 68 61 6e 64 6c 65 72 0a 2a 2a 20 63 61 6c  t handler.** cal
18600 6c 62 61 63 6b 20 62 79 20 63 68 61 6e 67 65 73  lback by changes
18610 65 74 5f 61 70 70 6c 79 28 29 2e 0a 2a 2f 0a 69  et_apply()..*/.i
18620 6e 74 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65  nt sqlite3change
18630 73 65 74 5f 66 69 6e 61 6c 69 7a 65 28 73 71 6c  set_finalize(sql
18640 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69  ite3_changeset_i
18650 74 65 72 20 2a 70 29 7b 0a 20 20 69 6e 74 20 72  ter *p){.  int r
18660 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
18670 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 69 6e   if( p ){.    in
18680 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20  t i;            
18690 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55              /* U
186a0 73 65 64 20 74 6f 20 69 74 65 72 61 74 65 20 74  sed to iterate t
186b0 68 72 6f 75 67 68 20 70 2d 3e 61 70 56 61 6c 75  hrough p->apValu
186c0 65 5b 5d 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20  e[] */.    rc = 
186d0 70 2d 3e 72 63 3b 0a 20 20 20 20 69 66 28 20 70  p->rc;.    if( p
186e0 2d 3e 61 70 56 61 6c 75 65 20 29 7b 0a 20 20 20  ->apValue ){.   
186f0 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 2d     for(i=0; i<p-
18700 3e 6e 43 6f 6c 2a 32 3b 20 69 2b 2b 29 20 73 71  >nCol*2; i++) sq
18710 6c 69 74 65 33 56 61 6c 75 65 46 72 65 65 28 70  lite3ValueFree(p
18720 2d 3e 61 70 56 61 6c 75 65 5b 69 5d 29 3b 0a 20  ->apValue[i]);. 
18730 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33     }.    sqlite3
18740 5f 66 72 65 65 28 70 2d 3e 74 62 6c 68 64 72 2e  _free(p->tblhdr.
18750 61 42 75 66 29 3b 0a 20 20 20 20 73 71 6c 69 74  aBuf);.    sqlit
18760 65 33 5f 66 72 65 65 28 70 2d 3e 69 6e 2e 62 75  e3_free(p->in.bu
18770 66 2e 61 42 75 66 29 3b 0a 20 20 20 20 73 71 6c  f.aBuf);.    sql
18780 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20  ite3_free(p);.  
18790 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
187a0 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73  ..static int ses
187b0 73 69 6f 6e 43 68 61 6e 67 65 73 65 74 49 6e 76  sionChangesetInv
187c0 65 72 74 28 0a 20 20 53 65 73 73 69 6f 6e 49 6e  ert(.  SessionIn
187d0 70 75 74 20 2a 70 49 6e 70 75 74 2c 20 20 20 20  put *pInput,    
187e0 20 20 20 20 20 20 20 2f 2a 20 49 6e 70 75 74 20         /* Input 
187f0 63 68 61 6e 67 65 73 65 74 20 2a 2f 0a 20 20 69  changeset */.  i
18800 6e 74 20 28 2a 78 4f 75 74 70 75 74 29 28 76 6f  nt (*xOutput)(vo
18810 69 64 20 2a 70 4f 75 74 2c 20 63 6f 6e 73 74 20  id *pOut, const 
18820 76 6f 69 64 20 2a 70 44 61 74 61 2c 20 69 6e 74  void *pData, int
18830 20 6e 44 61 74 61 29 2c 0a 20 20 76 6f 69 64 20   nData),.  void 
18840 2a 70 4f 75 74 2c 0a 20 20 69 6e 74 20 2a 70 6e  *pOut,.  int *pn
18850 49 6e 76 65 72 74 65 64 2c 20 20 20 20 20 20 20  Inverted,       
18860 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
18870 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   Number of bytes
18880 20 69 6e 20 6f 75 74 70 75 74 20 63 68 61 6e 67   in output chang
18890 65 73 65 74 20 2a 2f 0a 20 20 76 6f 69 64 20 2a  eset */.  void *
188a0 2a 70 70 49 6e 76 65 72 74 65 64 20 20 20 20 20  *ppInverted     
188b0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
188c0 3a 20 49 6e 76 65 72 73 65 20 6f 66 20 70 43 68  : Inverse of pCh
188d0 61 6e 67 65 73 65 74 20 2a 2f 0a 29 7b 0a 20 20  angeset */.){.  
188e0 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
188f0 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  OK;             
18900 2f 2a 20 52 65 74 75 72 6e 20 76 61 6c 75 65 20  /* Return value 
18910 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66  */.  SessionBuff
18920 65 72 20 73 4f 75 74 3b 20 20 20 20 20 20 20 20  er sOut;        
18930 20 20 20 20 20 2f 2a 20 4f 75 74 70 75 74 20 62       /* Output b
18940 75 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e  uffer */.  int n
18950 43 6f 6c 20 3d 20 30 3b 20 20 20 20 20 20 20 20  Col = 0;        
18960 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
18970 6d 62 65 72 20 6f 66 20 63 6f 6c 73 20 69 6e 20  mber of cols in 
18980 63 75 72 72 65 6e 74 20 74 61 62 6c 65 20 2a 2f  current table */
18990 0a 20 20 75 38 20 2a 61 62 50 4b 20 3d 20 30 3b  .  u8 *abPK = 0;
189a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
189b0 20 20 20 2f 2a 20 50 4b 20 61 72 72 61 79 20 66     /* PK array f
189c0 6f 72 20 63 75 72 72 65 6e 74 20 74 61 62 6c 65  or current table
189d0 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61   */.  sqlite3_va
189e0 6c 75 65 20 2a 2a 61 70 56 61 6c 20 3d 20 30 3b  lue **apVal = 0;
189f0 20 20 20 20 20 20 2f 2a 20 53 70 61 63 65 20 66        /* Space f
18a00 6f 72 20 76 61 6c 75 65 73 20 66 6f 72 20 55 50  or values for UP
18a10 44 41 54 45 20 69 6e 76 65 72 73 69 6f 6e 20 2a  DATE inversion *
18a20 2f 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66 65  /.  SessionBuffe
18a30 72 20 73 50 4b 20 3d 20 7b 30 2c 20 30 2c 20 30  r sPK = {0, 0, 0
18a40 7d 3b 20 20 2f 2a 20 50 4b 20 61 72 72 61 79 20  };  /* PK array 
18a50 66 6f 72 20 63 75 72 72 65 6e 74 20 74 61 62 6c  for current tabl
18a60 65 20 2a 2f 0a 0a 20 20 2f 2a 20 49 6e 69 74 69  e */..  /* Initi
18a70 61 6c 69 7a 65 20 74 68 65 20 6f 75 74 70 75 74  alize the output
18a80 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 6d 65 6d   buffer */.  mem
18a90 73 65 74 28 26 73 4f 75 74 2c 20 30 2c 20 73 69  set(&sOut, 0, si
18aa0 7a 65 6f 66 28 53 65 73 73 69 6f 6e 42 75 66 66  zeof(SessionBuff
18ab0 65 72 29 29 3b 0a 0a 20 20 2f 2a 20 5a 65 72 6f  er));..  /* Zero
18ac0 20 74 68 65 20 6f 75 74 70 75 74 20 76 61 72 69   the output vari
18ad0 61 62 6c 65 73 20 69 6e 20 63 61 73 65 20 61 6e  ables in case an
18ae0 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 20 2a   error occurs. *
18af0 2f 0a 20 20 69 66 28 20 70 70 49 6e 76 65 72 74  /.  if( ppInvert
18b00 65 64 20 29 7b 0a 20 20 20 20 2a 70 70 49 6e 76  ed ){.    *ppInv
18b10 65 72 74 65 64 20 3d 20 30 3b 0a 20 20 20 20 2a  erted = 0;.    *
18b20 70 6e 49 6e 76 65 72 74 65 64 20 3d 20 30 3b 0a  pnInverted = 0;.
18b30 20 20 7d 0a 0a 20 20 77 68 69 6c 65 28 20 31 20    }..  while( 1 
18b40 29 7b 0a 20 20 20 20 75 38 20 65 54 79 70 65 3b  ){.    u8 eType;
18b50 0a 0a 20 20 20 20 2f 2a 20 54 65 73 74 20 66 6f  ..    /* Test fo
18b60 72 20 45 4f 46 2e 20 2a 2f 0a 20 20 20 20 69 66  r EOF. */.    if
18b70 28 20 28 72 63 20 3d 20 73 65 73 73 69 6f 6e 49  ( (rc = sessionI
18b80 6e 70 75 74 42 75 66 66 65 72 28 70 49 6e 70 75  nputBuffer(pInpu
18b90 74 2c 20 32 29 29 20 29 20 67 6f 74 6f 20 66 69  t, 2)) ) goto fi
18ba0 6e 69 73 68 65 64 5f 69 6e 76 65 72 74 3b 0a 20  nished_invert;. 
18bb0 20 20 20 69 66 28 20 70 49 6e 70 75 74 2d 3e 69     if( pInput->i
18bc0 4e 65 78 74 3e 3d 70 49 6e 70 75 74 2d 3e 6e 44  Next>=pInput->nD
18bd0 61 74 61 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  ata ) break;.   
18be0 20 65 54 79 70 65 20 3d 20 70 49 6e 70 75 74 2d   eType = pInput-
18bf0 3e 61 44 61 74 61 5b 70 49 6e 70 75 74 2d 3e 69  >aData[pInput->i
18c00 4e 65 78 74 5d 3b 0a 0a 20 20 20 20 73 77 69 74  Next];..    swit
18c10 63 68 28 20 65 54 79 70 65 20 29 7b 0a 20 20 20  ch( eType ){.   
18c20 20 20 20 63 61 73 65 20 27 54 27 3a 20 7b 0a 20     case 'T': {. 
18c30 20 20 20 20 20 20 20 2f 2a 20 41 20 27 74 61 62         /* A 'tab
18c40 6c 65 27 20 72 65 63 6f 72 64 20 63 6f 6e 73 69  le' record consi
18c50 73 74 73 20 6f 66 3a 0a 20 20 20 20 20 20 20 20  sts of:.        
18c60 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 20 20  **.        **   
18c70 2a 20 41 20 63 6f 6e 73 74 61 6e 74 20 27 54 27  * A constant 'T'
18c80 20 63 68 61 72 61 63 74 65 72 2c 0a 20 20 20 20   character,.    
18c90 20 20 20 20 2a 2a 20 20 20 2a 20 4e 75 6d 62 65      **   * Numbe
18ca0 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20  r of columns in 
18cb0 73 61 69 64 20 74 61 62 6c 65 20 28 61 20 76 61  said table (a va
18cc0 72 69 6e 74 29 2c 0a 20 20 20 20 20 20 20 20 2a  rint),.        *
18cd0 2a 20 20 20 2a 20 41 6e 20 61 72 72 61 79 20 6f  *   * An array o
18ce0 66 20 6e 43 6f 6c 20 62 79 74 65 73 20 28 73 50  f nCol bytes (sP
18cf0 4b 29 2c 0a 20 20 20 20 20 20 20 20 2a 2a 20 20  K),.        **  
18d00 20 2a 20 41 20 6e 75 6c 2d 74 65 72 6d 69 6e 61   * A nul-termina
18d10 74 65 64 20 74 61 62 6c 65 20 6e 61 6d 65 2e 0a  ted table name..
18d20 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20          */.     
18d30 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20     int nByte;.  
18d40 20 20 20 20 20 20 69 6e 74 20 6e 56 61 72 3b 0a        int nVar;.
18d50 20 20 20 20 20 20 20 20 70 49 6e 70 75 74 2d 3e          pInput->
18d60 69 4e 65 78 74 2b 2b 3b 0a 20 20 20 20 20 20 20  iNext++;.       
18d70 20 69 66 28 20 28 72 63 20 3d 20 73 65 73 73 69   if( (rc = sessi
18d80 6f 6e 43 68 61 6e 67 65 73 65 74 42 75 66 66 65  onChangesetBuffe
18d90 72 54 62 6c 68 64 72 28 70 49 6e 70 75 74 2c 20  rTblhdr(pInput, 
18da0 26 6e 42 79 74 65 29 29 20 29 7b 0a 20 20 20 20  &nByte)) ){.    
18db0 20 20 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73        goto finis
18dc0 68 65 64 5f 69 6e 76 65 72 74 3b 0a 20 20 20 20  hed_invert;.    
18dd0 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 6e 56      }.        nV
18de0 61 72 20 3d 20 73 65 73 73 69 6f 6e 56 61 72 69  ar = sessionVari
18df0 6e 74 47 65 74 28 26 70 49 6e 70 75 74 2d 3e 61  ntGet(&pInput->a
18e00 44 61 74 61 5b 70 49 6e 70 75 74 2d 3e 69 4e 65  Data[pInput->iNe
18e10 78 74 5d 2c 20 26 6e 43 6f 6c 29 3b 0a 20 20 20  xt], &nCol);.   
18e20 20 20 20 20 20 73 50 4b 2e 6e 42 75 66 20 3d 20       sPK.nBuf = 
18e30 30 3b 0a 20 20 20 20 20 20 20 20 73 65 73 73 69  0;.        sessi
18e40 6f 6e 41 70 70 65 6e 64 42 6c 6f 62 28 26 73 50  onAppendBlob(&sP
18e50 4b 2c 20 26 70 49 6e 70 75 74 2d 3e 61 44 61 74  K, &pInput->aDat
18e60 61 5b 70 49 6e 70 75 74 2d 3e 69 4e 65 78 74 2b  a[pInput->iNext+
18e70 6e 56 61 72 5d 2c 20 6e 43 6f 6c 2c 20 26 72 63  nVar], nCol, &rc
18e80 29 3b 0a 20 20 20 20 20 20 20 20 73 65 73 73 69  );.        sessi
18e90 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 26 73 4f  onAppendByte(&sO
18ea0 75 74 2c 20 65 54 79 70 65 2c 20 26 72 63 29 3b  ut, eType, &rc);
18eb0 0a 20 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e  .        session
18ec0 41 70 70 65 6e 64 42 6c 6f 62 28 26 73 4f 75 74  AppendBlob(&sOut
18ed0 2c 20 26 70 49 6e 70 75 74 2d 3e 61 44 61 74 61  , &pInput->aData
18ee0 5b 70 49 6e 70 75 74 2d 3e 69 4e 65 78 74 5d 2c  [pInput->iNext],
18ef0 20 6e 42 79 74 65 2c 20 26 72 63 29 3b 0a 20 20   nByte, &rc);.  
18f00 20 20 20 20 20 20 69 66 28 20 72 63 20 29 20 67        if( rc ) g
18f10 6f 74 6f 20 66 69 6e 69 73 68 65 64 5f 69 6e 76  oto finished_inv
18f20 65 72 74 3b 0a 0a 20 20 20 20 20 20 20 20 70 49  ert;..        pI
18f30 6e 70 75 74 2d 3e 69 4e 65 78 74 20 2b 3d 20 6e  nput->iNext += n
18f40 42 79 74 65 3b 0a 20 20 20 20 20 20 20 20 73 71  Byte;.        sq
18f50 6c 69 74 65 33 5f 66 72 65 65 28 61 70 56 61 6c  lite3_free(apVal
18f60 29 3b 0a 20 20 20 20 20 20 20 20 61 70 56 61 6c  );.        apVal
18f70 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 61 62   = 0;.        ab
18f80 50 4b 20 3d 20 73 50 4b 2e 61 42 75 66 3b 0a 20  PK = sPK.aBuf;. 
18f90 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
18fa0 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 63 61 73      }..      cas
18fb0 65 20 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 3a  e SQLITE_INSERT:
18fc0 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
18fd0 54 45 5f 44 45 4c 45 54 45 3a 20 7b 0a 20 20 20  TE_DELETE: {.   
18fe0 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a       int nByte;.
18ff0 20 20 20 20 20 20 20 20 69 6e 74 20 62 49 6e 64          int bInd
19000 69 72 65 63 74 20 3d 20 70 49 6e 70 75 74 2d 3e  irect = pInput->
19010 61 44 61 74 61 5b 70 49 6e 70 75 74 2d 3e 69 4e  aData[pInput->iN
19020 65 78 74 2b 31 5d 3b 0a 20 20 20 20 20 20 20 20  ext+1];.        
19030 69 6e 74 20 65 54 79 70 65 32 20 3d 20 28 65 54  int eType2 = (eT
19040 79 70 65 3d 3d 53 51 4c 49 54 45 5f 44 45 4c 45  ype==SQLITE_DELE
19050 54 45 20 3f 20 53 51 4c 49 54 45 5f 49 4e 53 45  TE ? SQLITE_INSE
19060 52 54 20 3a 20 53 51 4c 49 54 45 5f 44 45 4c 45  RT : SQLITE_DELE
19070 54 45 29 3b 0a 20 20 20 20 20 20 20 20 70 49 6e  TE);.        pIn
19080 70 75 74 2d 3e 69 4e 65 78 74 20 2b 3d 20 32 3b  put->iNext += 2;
19090 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28  .        assert(
190a0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
190b0 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73  ;.        rc = s
190c0 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65 74 42  essionChangesetB
190d0 75 66 66 65 72 52 65 63 6f 72 64 28 70 49 6e 70  ufferRecord(pInp
190e0 75 74 2c 20 6e 43 6f 6c 2c 20 26 6e 42 79 74 65  ut, nCol, &nByte
190f0 29 3b 0a 20 20 20 20 20 20 20 20 73 65 73 73 69  );.        sessi
19100 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 26 73 4f  onAppendByte(&sO
19110 75 74 2c 20 65 54 79 70 65 32 2c 20 26 72 63 29  ut, eType2, &rc)
19120 3b 0a 20 20 20 20 20 20 20 20 73 65 73 73 69 6f  ;.        sessio
19130 6e 41 70 70 65 6e 64 42 79 74 65 28 26 73 4f 75  nAppendByte(&sOu
19140 74 2c 20 62 49 6e 64 69 72 65 63 74 2c 20 26 72  t, bIndirect, &r
19150 63 29 3b 0a 20 20 20 20 20 20 20 20 73 65 73 73  c);.        sess
19160 69 6f 6e 41 70 70 65 6e 64 42 6c 6f 62 28 26 73  ionAppendBlob(&s
19170 4f 75 74 2c 20 26 70 49 6e 70 75 74 2d 3e 61 44  Out, &pInput->aD
19180 61 74 61 5b 70 49 6e 70 75 74 2d 3e 69 4e 65 78  ata[pInput->iNex
19190 74 5d 2c 20 6e 42 79 74 65 2c 20 26 72 63 29 3b  t], nByte, &rc);
191a0 0a 20 20 20 20 20 20 20 20 70 49 6e 70 75 74 2d  .        pInput-
191b0 3e 69 4e 65 78 74 20 2b 3d 20 6e 42 79 74 65 3b  >iNext += nByte;
191c0 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63 20  .        if( rc 
191d0 29 20 67 6f 74 6f 20 66 69 6e 69 73 68 65 64 5f  ) goto finished_
191e0 69 6e 76 65 72 74 3b 0a 20 20 20 20 20 20 20 20  invert;.        
191f0 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a  break;.      }..
19200 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54        case SQLIT
19210 45 5f 55 50 44 41 54 45 3a 20 7b 0a 20 20 20 20  E_UPDATE: {.    
19220 20 20 20 20 69 6e 74 20 69 43 6f 6c 3b 0a 0a 20      int iCol;.. 
19230 20 20 20 20 20 20 20 69 66 28 20 30 3d 3d 61 70         if( 0==ap
19240 56 61 6c 20 29 7b 0a 20 20 20 20 20 20 20 20 20  Val ){.         
19250 20 61 70 56 61 6c 20 3d 20 28 73 71 6c 69 74 65   apVal = (sqlite
19260 33 5f 76 61 6c 75 65 20 2a 2a 29 73 71 6c 69 74  3_value **)sqlit
19270 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66  e3_malloc(sizeof
19280 28 61 70 56 61 6c 5b 30 5d 29 2a 6e 43 6f 6c 2a  (apVal[0])*nCol*
19290 32 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66  2);.          if
192a0 28 20 30 3d 3d 61 70 56 61 6c 20 29 7b 0a 20 20  ( 0==apVal ){.  
192b0 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 53            rc = S
192c0 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
192d0 20 20 20 20 20 20 20 20 20 67 6f 74 6f 20 66 69           goto fi
192e0 6e 69 73 68 65 64 5f 69 6e 76 65 72 74 3b 0a 20  nished_invert;. 
192f0 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
19300 20 20 20 20 20 6d 65 6d 73 65 74 28 61 70 56 61       memset(apVa
19310 6c 2c 20 30 2c 20 73 69 7a 65 6f 66 28 61 70 56  l, 0, sizeof(apV
19320 61 6c 5b 30 5d 29 2a 6e 43 6f 6c 2a 32 29 3b 0a  al[0])*nCol*2);.
19330 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20          }..     
19340 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20     /* Write the 
19350 68 65 61 64 65 72 20 66 6f 72 20 74 68 65 20 6e  header for the n
19360 65 77 20 55 50 44 41 54 45 20 63 68 61 6e 67 65  ew UPDATE change
19370 2e 20 53 61 6d 65 20 61 73 20 74 68 65 20 6f 72  . Same as the or
19380 69 67 69 6e 61 6c 2e 20 2a 2f 0a 20 20 20 20 20  iginal. */.     
19390 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
193a0 42 79 74 65 28 26 73 4f 75 74 2c 20 65 54 79 70  Byte(&sOut, eTyp
193b0 65 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20  e, &rc);.       
193c0 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 79   sessionAppendBy
193d0 74 65 28 26 73 4f 75 74 2c 20 70 49 6e 70 75 74  te(&sOut, pInput
193e0 2d 3e 61 44 61 74 61 5b 70 49 6e 70 75 74 2d 3e  ->aData[pInput->
193f0 69 4e 65 78 74 2b 31 5d 2c 20 26 72 63 29 3b 0a  iNext+1], &rc);.
19400 0a 20 20 20 20 20 20 20 20 2f 2a 20 52 65 61 64  .        /* Read
19410 20 74 68 65 20 6f 6c 64 2e 2a 20 61 6e 64 20 6e   the old.* and n
19420 65 77 2e 2a 20 72 65 63 6f 72 64 73 20 66 6f 72  ew.* records for
19430 20 74 68 65 20 75 70 64 61 74 65 20 63 68 61 6e   the update chan
19440 67 65 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20 70  ge. */.        p
19450 49 6e 70 75 74 2d 3e 69 4e 65 78 74 20 2b 3d 20  Input->iNext += 
19460 32 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  2;.        rc = 
19470 73 65 73 73 69 6f 6e 52 65 61 64 52 65 63 6f 72  sessionReadRecor
19480 64 28 70 49 6e 70 75 74 2c 20 6e 43 6f 6c 2c 20  d(pInput, nCol, 
19490 30 2c 20 26 61 70 56 61 6c 5b 30 5d 29 3b 0a 20  0, &apVal[0]);. 
194a0 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
194b0 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
194c0 20 20 20 20 20 20 72 63 20 3d 20 73 65 73 73 69        rc = sessi
194d0 6f 6e 52 65 61 64 52 65 63 6f 72 64 28 70 49 6e  onReadRecord(pIn
194e0 70 75 74 2c 20 6e 43 6f 6c 2c 20 30 2c 20 26 61  put, nCol, 0, &a
194f0 70 56 61 6c 5b 6e 43 6f 6c 5d 29 3b 0a 20 20 20  pVal[nCol]);.   
19500 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20       }..        
19510 2f 2a 20 57 72 69 74 65 20 74 68 65 20 6e 65 77  /* Write the new
19520 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 2e 20 43   old.* record. C
19530 6f 6e 73 69 73 74 73 20 6f 66 20 74 68 65 20 50  onsists of the P
19540 4b 20 63 6f 6c 75 6d 6e 73 20 66 72 6f 6d 20 74  K columns from t
19550 68 65 0a 20 20 20 20 20 20 20 20 2a 2a 20 6f 72  he.        ** or
19560 69 67 69 6e 61 6c 20 6f 6c 64 2e 2a 20 72 65 63  iginal old.* rec
19570 6f 72 64 2c 20 61 6e 64 20 74 68 65 20 6f 74 68  ord, and the oth
19580 65 72 20 76 61 6c 75 65 73 20 66 72 6f 6d 20 74  er values from t
19590 68 65 20 6f 72 69 67 69 6e 61 6c 0a 20 20 20 20  he original.    
195a0 20 20 20 20 2a 2a 20 6e 65 77 2e 2a 20 72 65 63      ** new.* rec
195b0 6f 72 64 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20  ord. */.        
195c0 66 6f 72 28 69 43 6f 6c 3d 30 3b 20 69 43 6f 6c  for(iCol=0; iCol
195d0 3c 6e 43 6f 6c 3b 20 69 43 6f 6c 2b 2b 29 7b 0a  <nCol; iCol++){.
195e0 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65            sqlite
195f0 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c 20 3d 20  3_value *pVal = 
19600 61 70 56 61 6c 5b 69 43 6f 6c 20 2b 20 28 61 62  apVal[iCol + (ab
19610 50 4b 5b 69 43 6f 6c 5d 20 3f 20 30 20 3a 20 6e  PK[iCol] ? 0 : n
19620 43 6f 6c 29 5d 3b 0a 20 20 20 20 20 20 20 20 20  Col)];.         
19630 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 56 61   sessionAppendVa
19640 6c 75 65 28 26 73 4f 75 74 2c 20 70 56 61 6c 2c  lue(&sOut, pVal,
19650 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20 20 7d   &rc);.        }
19660 0a 0a 20 20 20 20 20 20 20 20 2f 2a 20 57 72 69  ..        /* Wri
19670 74 65 20 74 68 65 20 6e 65 77 20 6e 65 77 2e 2a  te the new new.*
19680 20 72 65 63 6f 72 64 2e 20 43 6f 6e 73 69 73 74   record. Consist
19690 73 20 6f 66 20 61 20 63 6f 70 79 20 6f 66 20 61  s of a copy of a
196a0 6c 6c 20 76 61 6c 75 65 73 0a 20 20 20 20 20 20  ll values.      
196b0 20 20 2a 2a 20 66 72 6f 6d 20 74 68 65 20 6f 72    ** from the or
196c0 69 67 69 6e 61 6c 20 6f 6c 64 2e 2a 20 72 65 63  iginal old.* rec
196d0 6f 72 64 2c 20 65 78 63 65 70 74 20 66 6f 72 20  ord, except for 
196e0 74 68 65 20 50 4b 20 63 6f 6c 75 6d 6e 73 2c 20  the PK columns, 
196f0 77 68 69 63 68 0a 20 20 20 20 20 20 20 20 2a 2a  which.        **
19700 20 61 72 65 20 73 65 74 20 74 6f 20 22 75 6e 64   are set to "und
19710 65 66 69 6e 65 64 22 2e 20 2a 2f 0a 20 20 20 20  efined". */.    
19720 20 20 20 20 66 6f 72 28 69 43 6f 6c 3d 30 3b 20      for(iCol=0; 
19730 69 43 6f 6c 3c 6e 43 6f 6c 3b 20 69 43 6f 6c 2b  iCol<nCol; iCol+
19740 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 73 71  +){.          sq
19750 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56 61  lite3_value *pVa
19760 6c 20 3d 20 28 61 62 50 4b 5b 69 43 6f 6c 5d 20  l = (abPK[iCol] 
19770 3f 20 30 20 3a 20 61 70 56 61 6c 5b 69 43 6f 6c  ? 0 : apVal[iCol
19780 5d 29 3b 0a 20 20 20 20 20 20 20 20 20 20 73 65  ]);.          se
19790 73 73 69 6f 6e 41 70 70 65 6e 64 56 61 6c 75 65  ssionAppendValue
197a0 28 26 73 4f 75 74 2c 20 70 56 61 6c 2c 20 26 72  (&sOut, pVal, &r
197b0 63 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20  c);.        }.. 
197c0 20 20 20 20 20 20 20 66 6f 72 28 69 43 6f 6c 3d         for(iCol=
197d0 30 3b 20 69 43 6f 6c 3c 6e 43 6f 6c 2a 32 3b 20  0; iCol<nCol*2; 
197e0 69 43 6f 6c 2b 2b 29 7b 0a 20 20 20 20 20 20 20  iCol++){.       
197f0 20 20 20 73 71 6c 69 74 65 33 56 61 6c 75 65 46     sqlite3ValueF
19800 72 65 65 28 61 70 56 61 6c 5b 69 43 6f 6c 5d 29  ree(apVal[iCol])
19810 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
19820 20 20 20 20 6d 65 6d 73 65 74 28 61 70 56 61 6c      memset(apVal
19830 2c 20 30 2c 20 73 69 7a 65 6f 66 28 61 70 56 61  , 0, sizeof(apVa
19840 6c 5b 30 5d 29 2a 6e 43 6f 6c 2a 32 29 3b 0a 20  l[0])*nCol*2);. 
19850 20 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53         if( rc!=S
19860 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
19870 20 20 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73        goto finis
19880 68 65 64 5f 69 6e 76 65 72 74 3b 0a 20 20 20 20  hed_invert;.    
19890 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 62      }..        b
198a0 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20  reak;.      }.. 
198b0 20 20 20 20 20 64 65 66 61 75 6c 74 3a 0a 20 20       default:.  
198c0 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
198d0 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54 3b 0a  E_CORRUPT_BKPT;.
198e0 20 20 20 20 20 20 20 20 67 6f 74 6f 20 66 69 6e          goto fin
198f0 69 73 68 65 64 5f 69 6e 76 65 72 74 3b 0a 20 20  ished_invert;.  
19900 20 20 7d 0a 0a 20 20 20 20 61 73 73 65 72 74 28    }..    assert(
19910 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
19920 3b 0a 20 20 20 20 69 66 28 20 78 4f 75 74 70 75  ;.    if( xOutpu
19930 74 20 26 26 20 73 4f 75 74 2e 6e 42 75 66 3e 3d  t && sOut.nBuf>=
19940 53 45 53 53 49 4f 4e 53 5f 53 54 52 4d 5f 43 48  SESSIONS_STRM_CH
19950 55 4e 4b 5f 53 49 5a 45 20 29 7b 0a 20 20 20 20  UNK_SIZE ){.    
19960 20 20 72 63 20 3d 20 78 4f 75 74 70 75 74 28 70    rc = xOutput(p
19970 4f 75 74 2c 20 73 4f 75 74 2e 61 42 75 66 2c 20  Out, sOut.aBuf, 
19980 73 4f 75 74 2e 6e 42 75 66 29 3b 0a 20 20 20 20  sOut.nBuf);.    
19990 20 20 73 4f 75 74 2e 6e 42 75 66 20 3d 20 30 3b    sOut.nBuf = 0;
199a0 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53  .      if( rc!=S
199b0 51 4c 49 54 45 5f 4f 4b 20 29 20 67 6f 74 6f 20  QLITE_OK ) goto 
199c0 66 69 6e 69 73 68 65 64 5f 69 6e 76 65 72 74 3b  finished_invert;
199d0 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 61 73  .    }.  }..  as
199e0 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45  sert( rc==SQLITE
199f0 5f 4f 4b 20 29 3b 0a 20 20 69 66 28 20 70 6e 49  _OK );.  if( pnI
19a00 6e 76 65 72 74 65 64 20 29 7b 0a 20 20 20 20 2a  nverted ){.    *
19a10 70 6e 49 6e 76 65 72 74 65 64 20 3d 20 73 4f 75  pnInverted = sOu
19a20 74 2e 6e 42 75 66 3b 0a 20 20 20 20 2a 70 70 49  t.nBuf;.    *ppI
19a30 6e 76 65 72 74 65 64 20 3d 20 73 4f 75 74 2e 61  nverted = sOut.a
19a40 42 75 66 3b 0a 20 20 20 20 73 4f 75 74 2e 61 42  Buf;.    sOut.aB
19a50 75 66 20 3d 20 30 3b 0a 20 20 7d 65 6c 73 65 20  uf = 0;.  }else 
19a60 69 66 28 20 73 4f 75 74 2e 6e 42 75 66 3e 30 20  if( sOut.nBuf>0 
19a70 29 7b 0a 20 20 20 20 72 63 20 3d 20 78 4f 75 74  ){.    rc = xOut
19a80 70 75 74 28 70 4f 75 74 2c 20 73 4f 75 74 2e 61  put(pOut, sOut.a
19a90 42 75 66 2c 20 73 4f 75 74 2e 6e 42 75 66 29 3b  Buf, sOut.nBuf);
19aa0 0a 20 20 7d 0a 0a 20 66 69 6e 69 73 68 65 64 5f  .  }.. finished_
19ab0 69 6e 76 65 72 74 3a 0a 20 20 73 71 6c 69 74 65  invert:.  sqlite
19ac0 33 5f 66 72 65 65 28 73 4f 75 74 2e 61 42 75 66  3_free(sOut.aBuf
19ad0 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
19ae0 65 28 61 70 56 61 6c 29 3b 0a 20 20 73 71 6c 69  e(apVal);.  sqli
19af0 74 65 33 5f 66 72 65 65 28 73 50 4b 2e 61 42 75  te3_free(sPK.aBu
19b00 66 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  f);.  return rc;
19b10 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 49 6e 76 65 72  .}.../*.** Inver
19b20 74 20 61 20 63 68 61 6e 67 65 73 65 74 20 6f 62  t a changeset ob
19b30 6a 65 63 74 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  ject..*/.int sql
19b40 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 69 6e  ite3changeset_in
19b50 76 65 72 74 28 0a 20 20 69 6e 74 20 6e 43 68 61  vert(.  int nCha
19b60 6e 67 65 73 65 74 2c 20 20 20 20 20 20 20 20 20  ngeset,         
19b70 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
19b80 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 69 6e  r of bytes in in
19b90 70 75 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 76  put */.  const v
19ba0 6f 69 64 20 2a 70 43 68 61 6e 67 65 73 65 74 2c  oid *pChangeset,
19bb0 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 70 75           /* Inpu
19bc0 74 20 63 68 61 6e 67 65 73 65 74 20 2a 2f 0a 20  t changeset */. 
19bd0 20 69 6e 74 20 2a 70 6e 49 6e 76 65 72 74 65 64   int *pnInverted
19be0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
19bf0 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d 62 65 72 20   /* OUT: Number 
19c00 6f 66 20 62 79 74 65 73 20 69 6e 20 6f 75 74 70  of bytes in outp
19c10 75 74 20 63 68 61 6e 67 65 73 65 74 20 2a 2f 0a  ut changeset */.
19c20 20 20 76 6f 69 64 20 2a 2a 70 70 49 6e 76 65 72    void **ppInver
19c30 74 65 64 20 20 20 20 20 20 20 20 20 20 20 20 20  ted             
19c40 20 20 2f 2a 20 4f 55 54 3a 20 49 6e 76 65 72 73    /* OUT: Invers
19c50 65 20 6f 66 20 70 43 68 61 6e 67 65 73 65 74 20  e of pChangeset 
19c60 2a 2f 0a 29 7b 0a 20 20 53 65 73 73 69 6f 6e 49  */.){.  SessionI
19c70 6e 70 75 74 20 73 49 6e 70 75 74 3b 0a 0a 20 20  nput sInput;..  
19c80 2f 2a 20 53 65 74 20 75 70 20 74 68 65 20 69 6e  /* Set up the in
19c90 70 75 74 20 73 74 72 65 61 6d 20 2a 2f 0a 20 20  put stream */.  
19ca0 6d 65 6d 73 65 74 28 26 73 49 6e 70 75 74 2c 20  memset(&sInput, 
19cb0 30 2c 20 73 69 7a 65 6f 66 28 53 65 73 73 69 6f  0, sizeof(Sessio
19cc0 6e 49 6e 70 75 74 29 29 3b 0a 20 20 73 49 6e 70  nInput));.  sInp
19cd0 75 74 2e 6e 44 61 74 61 20 3d 20 6e 43 68 61 6e  ut.nData = nChan
19ce0 67 65 73 65 74 3b 0a 20 20 73 49 6e 70 75 74 2e  geset;.  sInput.
19cf0 61 44 61 74 61 20 3d 20 28 75 38 2a 29 70 43 68  aData = (u8*)pCh
19d00 61 6e 67 65 73 65 74 3b 0a 0a 20 20 72 65 74 75  angeset;..  retu
19d10 72 6e 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65  rn sessionChange
19d20 73 65 74 49 6e 76 65 72 74 28 26 73 49 6e 70 75  setInvert(&sInpu
19d30 74 2c 20 30 2c 20 30 2c 20 70 6e 49 6e 76 65 72  t, 0, 0, pnInver
19d40 74 65 64 2c 20 70 70 49 6e 76 65 72 74 65 64 29  ted, ppInverted)
19d50 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 74 72 65 61  ;.}../*.** Strea
19d60 6d 69 6e 67 20 76 65 72 73 69 6f 6e 20 6f 66 20  ming version of 
19d70 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
19d80 5f 69 6e 76 65 72 74 28 29 2e 0a 2a 2f 0a 69 6e  _invert()..*/.in
19d90 74 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  t sqlite3changes
19da0 65 74 5f 69 6e 76 65 72 74 5f 73 74 72 6d 28 0a  et_invert_strm(.
19db0 20 20 69 6e 74 20 28 2a 78 49 6e 70 75 74 29 28    int (*xInput)(
19dc0 76 6f 69 64 20 2a 70 49 6e 2c 20 76 6f 69 64 20  void *pIn, void 
19dd0 2a 70 44 61 74 61 2c 20 69 6e 74 20 2a 70 6e 44  *pData, int *pnD
19de0 61 74 61 29 2c 0a 20 20 76 6f 69 64 20 2a 70 49  ata),.  void *pI
19df0 6e 2c 0a 20 20 69 6e 74 20 28 2a 78 4f 75 74 70  n,.  int (*xOutp
19e00 75 74 29 28 76 6f 69 64 20 2a 70 4f 75 74 2c 20  ut)(void *pOut, 
19e10 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 44 61 74  const void *pDat
19e20 61 2c 20 69 6e 74 20 6e 44 61 74 61 29 2c 0a 20  a, int nData),. 
19e30 20 76 6f 69 64 20 2a 70 4f 75 74 0a 29 7b 0a 20   void *pOut.){. 
19e40 20 53 65 73 73 69 6f 6e 49 6e 70 75 74 20 73 49   SessionInput sI
19e50 6e 70 75 74 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  nput;.  int rc;.
19e60 0a 20 20 2f 2a 20 53 65 74 20 75 70 20 74 68 65  .  /* Set up the
19e70 20 69 6e 70 75 74 20 73 74 72 65 61 6d 20 2a 2f   input stream */
19e80 0a 20 20 6d 65 6d 73 65 74 28 26 73 49 6e 70 75  .  memset(&sInpu
19e90 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28 53 65 73  t, 0, sizeof(Ses
19ea0 73 69 6f 6e 49 6e 70 75 74 29 29 3b 0a 20 20 73  sionInput));.  s
19eb0 49 6e 70 75 74 2e 78 49 6e 70 75 74 20 3d 20 78  Input.xInput = x
19ec0 49 6e 70 75 74 3b 0a 20 20 73 49 6e 70 75 74 2e  Input;.  sInput.
19ed0 70 49 6e 20 3d 20 70 49 6e 3b 0a 0a 20 20 72 63  pIn = pIn;..  rc
19ee0 20 3d 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65   = sessionChange
19ef0 73 65 74 49 6e 76 65 72 74 28 26 73 49 6e 70 75  setInvert(&sInpu
19f00 74 2c 20 78 4f 75 74 70 75 74 2c 20 70 4f 75 74  t, xOutput, pOut
19f10 2c 20 30 2c 20 30 29 3b 0a 20 20 73 71 6c 69 74  , 0, 0);.  sqlit
19f20 65 33 5f 66 72 65 65 28 73 49 6e 70 75 74 2e 62  e3_free(sInput.b
19f30 75 66 2e 61 42 75 66 29 3b 0a 20 20 72 65 74 75  uf.aBuf);.  retu
19f40 72 6e 20 72 63 3b 0a 7d 0a 0a 74 79 70 65 64 65  rn rc;.}..typede
19f50 66 20 73 74 72 75 63 74 20 53 65 73 73 69 6f 6e  f struct Session
19f60 41 70 70 6c 79 43 74 78 20 53 65 73 73 69 6f 6e  ApplyCtx Session
19f70 41 70 70 6c 79 43 74 78 3b 0a 73 74 72 75 63 74  ApplyCtx;.struct
19f80 20 53 65 73 73 69 6f 6e 41 70 70 6c 79 43 74 78   SessionApplyCtx
19f90 20 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62   {.  sqlite3 *db
19fa0 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74  ;.  sqlite3_stmt
19fb0 20 2a 70 44 65 6c 65 74 65 3b 20 20 20 20 20 20   *pDelete;      
19fc0 20 20 20 20 2f 2a 20 44 45 4c 45 54 45 20 73 74      /* DELETE st
19fd0 61 74 65 6d 65 6e 74 20 2a 2f 0a 20 20 73 71 6c  atement */.  sql
19fe0 69 74 65 33 5f 73 74 6d 74 20 2a 70 55 70 64 61  ite3_stmt *pUpda
19ff0 74 65 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20  te;          /* 
1a000 55 50 44 41 54 45 20 73 74 61 74 65 6d 65 6e 74  UPDATE statement
1a010 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73 74   */.  sqlite3_st
1a020 6d 74 20 2a 70 49 6e 73 65 72 74 3b 20 20 20 20  mt *pInsert;    
1a030 20 20 20 20 20 20 2f 2a 20 49 4e 53 45 52 54 20        /* INSERT 
1a040 73 74 61 74 65 6d 65 6e 74 20 2a 2f 0a 20 20 73  statement */.  s
1a050 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 65  qlite3_stmt *pSe
1a060 6c 65 63 74 3b 20 20 20 20 20 20 20 20 20 20 2f  lect;          /
1a070 2a 20 53 45 4c 45 43 54 20 73 74 61 74 65 6d 65  * SELECT stateme
1a080 6e 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c  nt */.  int nCol
1a090 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1a0a0 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
1a0b0 6f 66 20 61 7a 43 6f 6c 5b 5d 20 61 6e 64 20 61  of azCol[] and a
1a0c0 62 50 4b 5b 5d 20 61 72 72 61 79 73 20 2a 2f 0a  bPK[] arrays */.
1a0d0 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61    const char **a
1a0e0 7a 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20  zCol;           
1a0f0 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 63 6f    /* Array of co
1a100 6c 75 6d 6e 20 6e 61 6d 65 73 20 2a 2f 0a 20 20  lumn names */.  
1a110 75 38 20 2a 61 62 50 4b 3b 20 20 20 20 20 20 20  u8 *abPK;       
1a120 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a130 2f 2a 20 42 6f 6f 6c 65 61 6e 20 61 72 72 61 79  /* Boolean array
1a140 20 2d 20 74 72 75 65 20 69 66 20 63 6f 6c 75 6d   - true if colum
1a150 6e 20 69 73 20 69 6e 20 50 4b 20 2a 2f 0a 0a 20  n is in PK */.. 
1a160 20 69 6e 74 20 62 44 65 66 65 72 43 6f 6e 73 74   int bDeferConst
1a170 72 61 69 6e 74 73 3b 20 20 20 20 20 20 20 20 20  raints;         
1a180 20 2f 2a 20 54 72 75 65 20 74 6f 20 64 65 66 65   /* True to defe
1a190 72 20 63 6f 6e 73 74 72 61 69 6e 74 73 20 2a 2f  r constraints */
1a1a0 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66 65 72  .  SessionBuffer
1a1b0 20 63 6f 6e 73 74 72 61 69 6e 74 73 3b 20 20 20   constraints;   
1a1c0 20 20 20 2f 2a 20 44 65 66 65 72 72 65 64 20 63     /* Deferred c
1a1d0 6f 6e 73 74 72 61 69 6e 74 73 20 61 72 65 20 73  onstraints are s
1a1e0 74 6f 72 65 64 20 68 65 72 65 20 2a 2f 0a 7d 3b  tored here */.};
1a1f0 0a 0a 2f 2a 0a 2a 2a 20 46 6f 72 6d 75 6c 61 74  ../*.** Formulat
1a200 65 20 61 20 73 74 61 74 65 6d 65 6e 74 20 74 6f  e a statement to
1a210 20 44 45 4c 45 54 45 20 61 20 72 6f 77 20 66 72   DELETE a row fr
1a220 6f 6d 20 64 61 74 61 62 61 73 65 20 64 62 2e 20  om database db. 
1a230 41 73 73 75 6d 69 6e 67 20 61 20 74 61 62 6c 65  Assuming a table
1a240 0a 2a 2a 20 73 74 72 75 63 74 75 72 65 20 6c 69  .** structure li
1a250 6b 65 20 74 68 69 73 3a 0a 2a 2a 0a 2a 2a 20 20  ke this:.**.**  
1a260 20 20 20 43 52 45 41 54 45 20 54 41 42 4c 45 20     CREATE TABLE 
1a270 78 28 61 2c 20 62 2c 20 63 2c 20 64 2c 20 50 52  x(a, b, c, d, PR
1a280 49 4d 41 52 59 20 4b 45 59 28 61 2c 20 63 29 29  IMARY KEY(a, c))
1a290 3b 0a 2a 2a 0a 2a 2a 20 54 68 65 20 44 45 4c 45  ;.**.** The DELE
1a2a0 54 45 20 73 74 61 74 65 6d 65 6e 74 20 6c 6f 6f  TE statement loo
1a2b0 6b 73 20 6c 69 6b 65 20 74 68 69 73 3a 0a 2a 2a  ks like this:.**
1a2c0 0a 2a 2a 20 20 20 20 20 44 45 4c 45 54 45 20 46  .**     DELETE F
1a2d0 52 4f 4d 20 78 20 57 48 45 52 45 20 61 20 3d 20  ROM x WHERE a = 
1a2e0 3a 31 20 41 4e 44 20 63 20 3d 20 3a 33 20 41 4e  :1 AND c = :3 AN
1a2f0 44 20 28 3a 35 20 4f 52 20 62 20 49 53 20 3a 32  D (:5 OR b IS :2
1a300 20 41 4e 44 20 64 20 49 53 20 3a 34 29 0a 2a 2a   AND d IS :4).**
1a310 0a 2a 2a 20 56 61 72 69 61 62 6c 65 20 3a 35 20  .** Variable :5 
1a320 28 6e 43 6f 6c 2b 31 29 20 69 73 20 61 20 62 6f  (nCol+1) is a bo
1a330 6f 6c 65 61 6e 2e 20 49 74 20 73 68 6f 75 6c 64  olean. It should
1a340 20 62 65 20 73 65 74 20 74 6f 20 30 20 69 66 20   be set to 0 if 
1a350 77 65 20 72 65 71 75 69 72 65 0a 2a 2a 20 6d 61  we require.** ma
1a360 74 63 68 69 6e 67 20 62 20 61 6e 64 20 64 20 76  tching b and d v
1a370 61 6c 75 65 73 2c 20 6f 72 20 31 20 6f 74 68 65  alues, or 1 othe
1a380 72 77 69 73 65 2e 20 54 68 65 20 73 65 63 6f 6e  rwise. The secon
1a390 64 20 63 61 73 65 20 63 6f 6d 65 73 20 75 70 20  d case comes up 
1a3a0 69 66 20 74 68 65 0a 2a 2a 20 63 6f 6e 66 6c 69  if the.** confli
1a3b0 63 74 20 68 61 6e 64 6c 65 72 20 69 73 20 69 6e  ct handler is in
1a3c0 76 6f 6b 65 64 20 77 69 74 68 20 4e 4f 54 46 4f  voked with NOTFO
1a3d0 55 4e 44 20 61 6e 64 20 72 65 74 75 72 6e 73 20  UND and returns 
1a3e0 43 48 41 4e 47 45 53 45 54 5f 52 45 50 4c 41 43  CHANGESET_REPLAC
1a3f0 45 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63  E..**.** If succ
1a400 65 73 73 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f  essful, SQLITE_O
1a410 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e  K is returned an
1a420 64 20 53 65 73 73 69 6f 6e 41 70 70 6c 79 43 74  d SessionApplyCt
1a430 78 2e 70 44 65 6c 65 74 65 20 69 73 20 6c 65 66  x.pDelete is lef
1a440 74 0a 2a 2a 20 70 6f 69 6e 74 69 6e 67 20 74 6f  t.** pointing to
1a450 20 74 68 65 20 70 72 65 70 61 72 65 64 20 76 65   the prepared ve
1a460 72 73 69 6f 6e 20 6f 66 20 74 68 65 20 53 51 4c  rsion of the SQL
1a470 20 73 74 61 74 65 6d 65 6e 74 2e 0a 2a 2f 0a 73   statement..*/.s
1a480 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f  tatic int sessio
1a490 6e 44 65 6c 65 74 65 52 6f 77 28 0a 20 20 73 71  nDeleteRow(.  sq
1a4a0 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20  lite3 *db,      
1a4b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1a4c0 20 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65   Database handle
1a4d0 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
1a4e0 20 2a 7a 54 61 62 2c 20 20 20 20 20 20 20 20 20   *zTab,         
1a4f0 20 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20 6e        /* Table n
1a500 61 6d 65 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e  ame */.  Session
1a510 41 70 70 6c 79 43 74 78 20 2a 70 20 20 20 20 20  ApplyCtx *p     
1a520 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 73 73           /* Sess
1a530 69 6f 6e 20 63 68 61 6e 67 65 73 65 74 2d 61 70  ion changeset-ap
1a540 70 6c 79 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 29  ply context */.)
1a550 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 6f 6e  {.  int i;.  con
1a560 73 74 20 63 68 61 72 20 2a 7a 53 65 70 20 3d 20  st char *zSep = 
1a570 22 22 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  "";.  int rc = S
1a580 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 53 65 73 73  QLITE_OK;.  Sess
1a590 69 6f 6e 42 75 66 66 65 72 20 62 75 66 20 3d 20  ionBuffer buf = 
1a5a0 7b 30 2c 20 30 2c 20 30 7d 3b 0a 20 20 69 6e 74  {0, 0, 0};.  int
1a5b0 20 6e 50 6b 20 3d 20 30 3b 0a 0a 20 20 73 65 73   nPk = 0;..  ses
1a5c0 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62  sionAppendStr(&b
1a5d0 75 66 2c 20 22 44 45 4c 45 54 45 20 46 52 4f 4d  uf, "DELETE FROM
1a5e0 20 22 2c 20 26 72 63 29 3b 0a 20 20 73 65 73 73   ", &rc);.  sess
1a5f0 69 6f 6e 41 70 70 65 6e 64 49 64 65 6e 74 28 26  ionAppendIdent(&
1a600 62 75 66 2c 20 7a 54 61 62 2c 20 26 72 63 29 3b  buf, zTab, &rc);
1a610 0a 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64  .  sessionAppend
1a620 53 74 72 28 26 62 75 66 2c 20 22 20 57 48 45 52  Str(&buf, " WHER
1a630 45 20 22 2c 20 26 72 63 29 3b 0a 0a 20 20 66 6f  E ", &rc);..  fo
1a640 72 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 43 6f 6c  r(i=0; i<p->nCol
1a650 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20  ; i++){.    if( 
1a660 70 2d 3e 61 62 50 4b 5b 69 5d 20 29 7b 0a 20 20  p->abPK[i] ){.  
1a670 20 20 20 20 6e 50 6b 2b 2b 3b 0a 20 20 20 20 20      nPk++;.     
1a680 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74   sessionAppendSt
1a690 72 28 26 62 75 66 2c 20 7a 53 65 70 2c 20 26 72  r(&buf, zSep, &r
1a6a0 63 29 3b 0a 20 20 20 20 20 20 73 65 73 73 69 6f  c);.      sessio
1a6b0 6e 41 70 70 65 6e 64 49 64 65 6e 74 28 26 62 75  nAppendIdent(&bu
1a6c0 66 2c 20 70 2d 3e 61 7a 43 6f 6c 5b 69 5d 2c 20  f, p->azCol[i], 
1a6d0 26 72 63 29 3b 0a 20 20 20 20 20 20 73 65 73 73  &rc);.      sess
1a6e0 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75  ionAppendStr(&bu
1a6f0 66 2c 20 22 20 3d 20 3f 22 2c 20 26 72 63 29 3b  f, " = ?", &rc);
1a700 0a 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70  .      sessionAp
1a710 70 65 6e 64 49 6e 74 65 67 65 72 28 26 62 75 66  pendInteger(&buf
1a720 2c 20 69 2b 31 2c 20 26 72 63 29 3b 0a 20 20 20  , i+1, &rc);.   
1a730 20 20 20 7a 53 65 70 20 3d 20 22 20 41 4e 44 20     zSep = " AND 
1a740 22 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  ";.    }.  }..  
1a750 69 66 28 20 6e 50 6b 3c 70 2d 3e 6e 43 6f 6c 20  if( nPk<p->nCol 
1a760 29 7b 0a 20 20 20 20 73 65 73 73 69 6f 6e 41 70  ){.    sessionAp
1a770 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 20  pendStr(&buf, " 
1a780 41 4e 44 20 28 3f 22 2c 20 26 72 63 29 3b 0a 20  AND (?", &rc);. 
1a790 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
1a7a0 49 6e 74 65 67 65 72 28 26 62 75 66 2c 20 70 2d  Integer(&buf, p-
1a7b0 3e 6e 43 6f 6c 2b 31 2c 20 26 72 63 29 3b 0a 20  >nCol+1, &rc);. 
1a7c0 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
1a7d0 53 74 72 28 26 62 75 66 2c 20 22 20 4f 52 20 22  Str(&buf, " OR "
1a7e0 2c 20 26 72 63 29 3b 0a 0a 20 20 20 20 7a 53 65  , &rc);..    zSe
1a7f0 70 20 3d 20 22 22 3b 0a 20 20 20 20 66 6f 72 28  p = "";.    for(
1a800 69 3d 30 3b 20 69 3c 70 2d 3e 6e 43 6f 6c 3b 20  i=0; i<p->nCol; 
1a810 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20  i++){.      if( 
1a820 21 70 2d 3e 61 62 50 4b 5b 69 5d 20 29 7b 0a 20  !p->abPK[i] ){. 
1a830 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70         sessionAp
1a840 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 7a 53  pendStr(&buf, zS
1a850 65 70 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20  ep, &rc);.      
1a860 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49    sessionAppendI
1a870 64 65 6e 74 28 26 62 75 66 2c 20 70 2d 3e 61 7a  dent(&buf, p->az
1a880 43 6f 6c 5b 69 5d 2c 20 26 72 63 29 3b 0a 20 20  Col[i], &rc);.  
1a890 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70        sessionApp
1a8a0 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 20 49  endStr(&buf, " I
1a8b0 53 20 3f 22 2c 20 26 72 63 29 3b 0a 20 20 20 20  S ?", &rc);.    
1a8c0 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e      sessionAppen
1a8d0 64 49 6e 74 65 67 65 72 28 26 62 75 66 2c 20 69  dInteger(&buf, i
1a8e0 2b 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20  +1, &rc);.      
1a8f0 20 20 7a 53 65 70 20 3d 20 22 41 4e 44 20 22 3b    zSep = "AND ";
1a900 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
1a910 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
1a920 53 74 72 28 26 62 75 66 2c 20 22 29 22 2c 20 26  Str(&buf, ")", &
1a930 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  rc);.  }..  if( 
1a940 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
1a950 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
1a960 33 5f 70 72 65 70 61 72 65 5f 76 32 28 64 62 2c  3_prepare_v2(db,
1a970 20 28 63 68 61 72 20 2a 29 62 75 66 2e 61 42 75   (char *)buf.aBu
1a980 66 2c 20 62 75 66 2e 6e 42 75 66 2c 20 26 70 2d  f, buf.nBuf, &p-
1a990 3e 70 44 65 6c 65 74 65 2c 20 30 29 3b 0a 20 20  >pDelete, 0);.  
1a9a0 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  }.  sqlite3_free
1a9b0 28 62 75 66 2e 61 42 75 66 29 3b 0a 0a 20 20 72  (buf.aBuf);..  r
1a9c0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
1a9d0 2a 2a 20 46 6f 72 6d 75 6c 61 74 65 20 61 6e 64  ** Formulate and
1a9e0 20 70 72 65 70 61 72 65 20 61 20 73 74 61 74 65   prepare a state
1a9f0 6d 65 6e 74 20 74 6f 20 55 50 44 41 54 45 20 61  ment to UPDATE a
1aa00 20 72 6f 77 20 66 72 6f 6d 20 64 61 74 61 62 61   row from databa
1aa10 73 65 20 64 62 2e 20 0a 2a 2a 20 41 73 73 75 6d  se db. .** Assum
1aa20 69 6e 67 20 61 20 74 61 62 6c 65 20 73 74 72 75  ing a table stru
1aa30 63 74 75 72 65 20 6c 69 6b 65 20 74 68 69 73 3a  cture like this:
1aa40 0a 2a 2a 0a 2a 2a 20 20 20 20 20 43 52 45 41 54  .**.**     CREAT
1aa50 45 20 54 41 42 4c 45 20 78 28 61 2c 20 62 2c 20  E TABLE x(a, b, 
1aa60 63 2c 20 64 2c 20 50 52 49 4d 41 52 59 20 4b 45  c, d, PRIMARY KE
1aa70 59 28 61 2c 20 63 29 29 3b 0a 2a 2a 0a 2a 2a 20  Y(a, c));.**.** 
1aa80 54 68 65 20 55 50 44 41 54 45 20 73 74 61 74 65  The UPDATE state
1aa90 6d 65 6e 74 20 6c 6f 6f 6b 73 20 6c 69 6b 65 20  ment looks like 
1aaa0 74 68 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  this:.**.**     
1aab0 55 50 44 41 54 45 20 78 20 53 45 54 0a 2a 2a 20  UPDATE x SET.** 
1aac0 20 20 20 20 61 20 3d 20 43 41 53 45 20 57 48 45      a = CASE WHE
1aad0 4e 20 3f 32 20 20 54 48 45 4e 20 3f 33 20 20 45  N ?2  THEN ?3  E
1aae0 4c 53 45 20 61 20 45 4e 44 2c 0a 2a 2a 20 20 20  LSE a END,.**   
1aaf0 20 20 62 20 3d 20 43 41 53 45 20 57 48 45 4e 20    b = CASE WHEN 
1ab00 3f 35 20 20 54 48 45 4e 20 3f 36 20 20 45 4c 53  ?5  THEN ?6  ELS
1ab10 45 20 62 20 45 4e 44 2c 0a 2a 2a 20 20 20 20 20  E b END,.**     
1ab20 63 20 3d 20 43 41 53 45 20 57 48 45 4e 20 3f 38  c = CASE WHEN ?8
1ab30 20 20 54 48 45 4e 20 3f 39 20 20 45 4c 53 45 20    THEN ?9  ELSE 
1ab40 63 20 45 4e 44 2c 0a 2a 2a 20 20 20 20 20 64 20  c END,.**     d 
1ab50 3d 20 43 41 53 45 20 57 48 45 4e 20 3f 31 31 20  = CASE WHEN ?11 
1ab60 54 48 45 4e 20 3f 31 32 20 45 4c 53 45 20 64 20  THEN ?12 ELSE d 
1ab70 45 4e 44 0a 2a 2a 20 20 20 20 20 57 48 45 52 45  END.**     WHERE
1ab80 20 61 20 3d 20 3f 31 20 41 4e 44 20 63 20 3d 20   a = ?1 AND c = 
1ab90 3f 37 20 41 4e 44 20 28 3f 31 33 20 4f 52 20 0a  ?7 AND (?13 OR .
1aba0 2a 2a 20 20 20 20 20 20 20 28 3f 35 3d 3d 30 20  **       (?5==0 
1abb0 4f 52 20 62 20 49 53 20 3f 34 29 20 41 4e 44 20  OR b IS ?4) AND 
1abc0 28 3f 31 31 3d 3d 30 20 4f 52 20 64 20 49 53 20  (?11==0 OR d IS 
1abd0 3f 31 30 29 20 41 4e 44 0a 2a 2a 20 20 20 20 20  ?10) AND.**     
1abe0 29 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 65 61 63 68  ).**.** For each
1abf0 20 63 6f 6c 75 6d 6e 20 69 6e 20 74 68 65 20 74   column in the t
1ac00 61 62 6c 65 2c 20 74 68 65 72 65 20 61 72 65 20  able, there are 
1ac10 74 68 72 65 65 20 76 61 72 69 61 62 6c 65 73 20  three variables 
1ac20 74 6f 20 62 69 6e 64 3a 0a 2a 2a 0a 2a 2a 20 20  to bind:.**.**  
1ac30 20 20 20 3f 28 69 2a 33 2b 31 29 20 20 20 20 54     ?(i*3+1)    T
1ac40 68 65 20 6f 6c 64 2e 2a 20 76 61 6c 75 65 20 6f  he old.* value o
1ac50 66 20 74 68 65 20 63 6f 6c 75 6d 6e 2c 20 69 66  f the column, if
1ac60 20 61 6e 79 2e 0a 2a 2a 20 20 20 20 20 3f 28 69   any..**     ?(i
1ac70 2a 33 2b 32 29 20 20 20 20 41 20 62 6f 6f 6c 65  *3+2)    A boole
1ac80 61 6e 20 66 6c 61 67 20 69 6e 64 69 63 61 74 69  an flag indicati
1ac90 6e 67 20 74 68 61 74 20 74 68 65 20 76 61 6c 75  ng that the valu
1aca0 65 20 69 73 20 62 65 69 6e 67 20 6d 6f 64 69 66  e is being modif
1acb0 69 65 64 2e 0a 2a 2a 20 20 20 20 20 3f 28 69 2a  ied..**     ?(i*
1acc0 33 2b 33 29 20 20 20 20 54 68 65 20 6e 65 77 2e  3+3)    The new.
1acd0 2a 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 63  * value of the c
1ace0 6f 6c 75 6d 6e 2c 20 69 66 20 61 6e 79 2e 0a 2a  olumn, if any..*
1acf0 2a 0a 2a 2a 20 41 6c 73 6f 2c 20 61 20 62 6f 6f  *.** Also, a boo
1ad00 6c 65 61 6e 20 66 6c 61 67 20 74 68 61 74 2c 20  lean flag that, 
1ad10 69 66 20 73 65 74 20 74 6f 20 74 72 75 65 2c 20  if set to true, 
1ad20 63 61 75 73 65 73 20 74 68 65 20 73 74 61 74 65  causes the state
1ad30 6d 65 6e 74 20 74 6f 20 75 70 64 61 74 65 0a 2a  ment to update.*
1ad40 2a 20 61 20 72 6f 77 20 65 76 65 6e 20 69 66 20  * a row even if 
1ad50 74 68 65 20 6e 6f 6e 2d 50 4b 20 76 61 6c 75 65  the non-PK value
1ad60 73 20 64 6f 20 6e 6f 74 20 6d 61 74 63 68 2e 20  s do not match. 
1ad70 54 68 69 73 20 69 73 20 72 65 71 75 69 72 65 64  This is required
1ad80 20 69 66 20 74 68 65 0a 2a 2a 20 63 6f 6e 66 6c   if the.** confl
1ad90 69 63 74 2d 68 61 6e 64 6c 65 72 20 69 73 20 69  ict-handler is i
1ada0 6e 76 6f 6b 65 64 20 77 69 74 68 20 43 48 41 4e  nvoked with CHAN
1adb0 47 45 53 45 54 5f 44 41 54 41 20 61 6e 64 20 72  GESET_DATA and r
1adc0 65 74 75 72 6e 73 0a 2a 2a 20 43 48 41 4e 47 45  eturns.** CHANGE
1add0 53 45 54 5f 52 45 50 4c 41 43 45 2e 20 54 68 69  SET_REPLACE. Thi
1ade0 73 20 69 73 20 76 61 72 69 61 62 6c 65 20 22 3f  s is variable "?
1adf0 28 6e 43 6f 6c 2a 33 2b 31 29 22 2e 0a 2a 2a 0a  (nCol*3+1)"..**.
1ae00 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c  ** If successful
1ae10 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72  , SQLITE_OK is r
1ae20 65 74 75 72 6e 65 64 20 61 6e 64 20 53 65 73 73  eturned and Sess
1ae30 69 6f 6e 41 70 70 6c 79 43 74 78 2e 70 55 70 64  ionApplyCtx.pUpd
1ae40 61 74 65 20 69 73 20 6c 65 66 74 0a 2a 2a 20 70  ate is left.** p
1ae50 6f 69 6e 74 69 6e 67 20 74 6f 20 74 68 65 20 70  ointing to the p
1ae60 72 65 70 61 72 65 64 20 76 65 72 73 69 6f 6e 20  repared version 
1ae70 6f 66 20 74 68 65 20 53 51 4c 20 73 74 61 74 65  of the SQL state
1ae80 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ment..*/.static 
1ae90 69 6e 74 20 73 65 73 73 69 6f 6e 55 70 64 61 74  int sessionUpdat
1aea0 65 52 6f 77 28 0a 20 20 73 71 6c 69 74 65 33 20  eRow(.  sqlite3 
1aeb0 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20  *db,            
1aec0 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
1aed0 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20  ase handle */.  
1aee0 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 62  const char *zTab
1aef0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1af00 2f 2a 20 54 61 62 6c 65 20 6e 61 6d 65 20 2a 2f  /* Table name */
1af10 0a 20 20 53 65 73 73 69 6f 6e 41 70 70 6c 79 43  .  SessionApplyC
1af20 74 78 20 2a 70 20 20 20 20 20 20 20 20 20 20 20  tx *p           
1af30 20 20 20 2f 2a 20 53 65 73 73 69 6f 6e 20 63 68     /* Session ch
1af40 61 6e 67 65 73 65 74 2d 61 70 70 6c 79 20 63 6f  angeset-apply co
1af50 6e 74 65 78 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e  ntext */.){.  in
1af60 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
1af70 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 6f 6e  ;.  int i;.  con
1af80 73 74 20 63 68 61 72 20 2a 7a 53 65 70 20 3d 20  st char *zSep = 
1af90 22 22 3b 0a 20 20 53 65 73 73 69 6f 6e 42 75 66  "";.  SessionBuf
1afa0 66 65 72 20 62 75 66 20 3d 20 7b 30 2c 20 30 2c  fer buf = {0, 0,
1afb0 20 30 7d 3b 0a 0a 20 20 2f 2a 20 41 70 70 65 6e   0};..  /* Appen
1afc0 64 20 22 55 50 44 41 54 45 20 74 62 6c 20 53 45  d "UPDATE tbl SE
1afd0 54 20 22 20 2a 2f 0a 20 20 73 65 73 73 69 6f 6e  T " */.  session
1afe0 41 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20  AppendStr(&buf, 
1aff0 22 55 50 44 41 54 45 20 22 2c 20 26 72 63 29 3b  "UPDATE ", &rc);
1b000 0a 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64  .  sessionAppend
1b010 49 64 65 6e 74 28 26 62 75 66 2c 20 7a 54 61 62  Ident(&buf, zTab
1b020 2c 20 26 72 63 29 3b 0a 20 20 73 65 73 73 69 6f  , &rc);.  sessio
1b030 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c  nAppendStr(&buf,
1b040 20 22 20 53 45 54 20 22 2c 20 26 72 63 29 3b 0a   " SET ", &rc);.
1b050 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20 74 68 65  .  /* Append the
1b060 20 61 73 73 69 67 6e 6d 65 6e 74 73 20 2a 2f 0a   assignments */.
1b070 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 2d 3e    for(i=0; i<p->
1b080 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  nCol; i++){.    
1b090 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72  sessionAppendStr
1b0a0 28 26 62 75 66 2c 20 7a 53 65 70 2c 20 26 72 63  (&buf, zSep, &rc
1b0b0 29 3b 0a 20 20 20 20 73 65 73 73 69 6f 6e 41 70  );.    sessionAp
1b0c0 70 65 6e 64 49 64 65 6e 74 28 26 62 75 66 2c 20  pendIdent(&buf, 
1b0d0 70 2d 3e 61 7a 43 6f 6c 5b 69 5d 2c 20 26 72 63  p->azCol[i], &rc
1b0e0 29 3b 0a 20 20 20 20 73 65 73 73 69 6f 6e 41 70  );.    sessionAp
1b0f0 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 20  pendStr(&buf, " 
1b100 3d 20 43 41 53 45 20 57 48 45 4e 20 3f 22 2c 20  = CASE WHEN ?", 
1b110 26 72 63 29 3b 0a 20 20 20 20 73 65 73 73 69 6f  &rc);.    sessio
1b120 6e 41 70 70 65 6e 64 49 6e 74 65 67 65 72 28 26  nAppendInteger(&
1b130 62 75 66 2c 20 69 2a 33 2b 32 2c 20 26 72 63 29  buf, i*3+2, &rc)
1b140 3b 0a 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70  ;.    sessionApp
1b150 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 20 54  endStr(&buf, " T
1b160 48 45 4e 20 3f 22 2c 20 26 72 63 29 3b 0a 20 20  HEN ?", &rc);.  
1b170 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49    sessionAppendI
1b180 6e 74 65 67 65 72 28 26 62 75 66 2c 20 69 2a 33  nteger(&buf, i*3
1b190 2b 33 2c 20 26 72 63 29 3b 0a 20 20 20 20 73 65  +3, &rc);.    se
1b1a0 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26  ssionAppendStr(&
1b1b0 62 75 66 2c 20 22 20 45 4c 53 45 20 22 2c 20 26  buf, " ELSE ", &
1b1c0 72 63 29 3b 0a 20 20 20 20 73 65 73 73 69 6f 6e  rc);.    session
1b1d0 41 70 70 65 6e 64 49 64 65 6e 74 28 26 62 75 66  AppendIdent(&buf
1b1e0 2c 20 70 2d 3e 61 7a 43 6f 6c 5b 69 5d 2c 20 26  , p->azCol[i], &
1b1f0 72 63 29 3b 0a 20 20 20 20 73 65 73 73 69 6f 6e  rc);.    session
1b200 41 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20  AppendStr(&buf, 
1b210 22 20 45 4e 44 22 2c 20 26 72 63 29 3b 0a 20 20  " END", &rc);.  
1b220 20 20 7a 53 65 70 20 3d 20 22 2c 20 22 3b 0a 20    zSep = ", ";. 
1b230 20 7d 0a 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20   }..  /* Append 
1b240 74 68 65 20 50 4b 20 70 61 72 74 20 6f 66 20 74  the PK part of t
1b250 68 65 20 57 48 45 52 45 20 63 6c 61 75 73 65 20  he WHERE clause 
1b260 2a 2f 0a 20 20 73 65 73 73 69 6f 6e 41 70 70 65  */.  sessionAppe
1b270 6e 64 53 74 72 28 26 62 75 66 2c 20 22 20 57 48  ndStr(&buf, " WH
1b280 45 52 45 20 22 2c 20 26 72 63 29 3b 0a 20 20 66  ERE ", &rc);.  f
1b290 6f 72 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 43 6f  or(i=0; i<p->nCo
1b2a0 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  l; i++){.    if(
1b2b0 20 70 2d 3e 61 62 50 4b 5b 69 5d 20 29 7b 0a 20   p->abPK[i] ){. 
1b2c0 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65       sessionAppe
1b2d0 6e 64 49 64 65 6e 74 28 26 62 75 66 2c 20 70 2d  ndIdent(&buf, p-
1b2e0 3e 61 7a 43 6f 6c 5b 69 5d 2c 20 26 72 63 29 3b  >azCol[i], &rc);
1b2f0 0a 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70  .      sessionAp
1b300 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 20  pendStr(&buf, " 
1b310 3d 20 3f 22 2c 20 26 72 63 29 3b 0a 20 20 20 20  = ?", &rc);.    
1b320 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49    sessionAppendI
1b330 6e 74 65 67 65 72 28 26 62 75 66 2c 20 69 2a 33  nteger(&buf, i*3
1b340 2b 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20  +1, &rc);.      
1b350 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72  sessionAppendStr
1b360 28 26 62 75 66 2c 20 22 20 41 4e 44 20 22 2c 20  (&buf, " AND ", 
1b370 26 72 63 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  &rc);.    }.  }.
1b380 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20 74 68 65  .  /* Append the
1b390 20 6e 6f 6e 2d 50 4b 20 70 61 72 74 20 6f 66 20   non-PK part of 
1b3a0 74 68 65 20 57 48 45 52 45 20 63 6c 61 75 73 65  the WHERE clause
1b3b0 20 2a 2f 0a 20 20 73 65 73 73 69 6f 6e 41 70 70   */.  sessionApp
1b3c0 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 20 28  endStr(&buf, " (
1b3d0 3f 22 2c 20 26 72 63 29 3b 0a 20 20 73 65 73 73  ?", &rc);.  sess
1b3e0 69 6f 6e 41 70 70 65 6e 64 49 6e 74 65 67 65 72  ionAppendInteger
1b3f0 28 26 62 75 66 2c 20 70 2d 3e 6e 43 6f 6c 2a 33  (&buf, p->nCol*3
1b400 2b 31 2c 20 26 72 63 29 3b 0a 20 20 73 65 73 73  +1, &rc);.  sess
1b410 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75  ionAppendStr(&bu
1b420 66 2c 20 22 20 4f 52 20 31 22 2c 20 26 72 63 29  f, " OR 1", &rc)
1b430 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70  ;.  for(i=0; i<p
1b440 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20  ->nCol; i++){.  
1b450 20 20 69 66 28 20 21 70 2d 3e 61 62 50 4b 5b 69    if( !p->abPK[i
1b460 5d 20 29 7b 0a 20 20 20 20 20 20 73 65 73 73 69  ] ){.      sessi
1b470 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75 66  onAppendStr(&buf
1b480 2c 20 22 20 41 4e 44 20 28 3f 22 2c 20 26 72 63  , " AND (?", &rc
1b490 29 3b 0a 20 20 20 20 20 20 73 65 73 73 69 6f 6e  );.      session
1b4a0 41 70 70 65 6e 64 49 6e 74 65 67 65 72 28 26 62  AppendInteger(&b
1b4b0 75 66 2c 20 69 2a 33 2b 32 2c 20 26 72 63 29 3b  uf, i*3+2, &rc);
1b4c0 0a 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70  .      sessionAp
1b4d0 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 3d  pendStr(&buf, "=
1b4e0 30 20 4f 52 20 22 2c 20 26 72 63 29 3b 0a 20 20  0 OR ", &rc);.  
1b4f0 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e      sessionAppen
1b500 64 49 64 65 6e 74 28 26 62 75 66 2c 20 70 2d 3e  dIdent(&buf, p->
1b510 61 7a 43 6f 6c 5b 69 5d 2c 20 26 72 63 29 3b 0a  azCol[i], &rc);.
1b520 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70        sessionApp
1b530 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 20 49  endStr(&buf, " I
1b540 53 20 3f 22 2c 20 26 72 63 29 3b 0a 20 20 20 20  S ?", &rc);.    
1b550 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49    sessionAppendI
1b560 6e 74 65 67 65 72 28 26 62 75 66 2c 20 69 2a 33  nteger(&buf, i*3
1b570 2b 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20  +1, &rc);.      
1b580 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72  sessionAppendStr
1b590 28 26 62 75 66 2c 20 22 29 22 2c 20 26 72 63 29  (&buf, ")", &rc)
1b5a0 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73 65  ;.    }.  }.  se
1b5b0 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26  ssionAppendStr(&
1b5c0 62 75 66 2c 20 22 29 22 2c 20 26 72 63 29 3b 0a  buf, ")", &rc);.
1b5d0 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
1b5e0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
1b5f0 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65   sqlite3_prepare
1b600 5f 76 32 28 64 62 2c 20 28 63 68 61 72 20 2a 29  _v2(db, (char *)
1b610 62 75 66 2e 61 42 75 66 2c 20 62 75 66 2e 6e 42  buf.aBuf, buf.nB
1b620 75 66 2c 20 26 70 2d 3e 70 55 70 64 61 74 65 2c  uf, &p->pUpdate,
1b630 20 30 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74   0);.  }.  sqlit
1b640 65 33 5f 66 72 65 65 28 62 75 66 2e 61 42 75 66  e3_free(buf.aBuf
1b650 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  );..  return rc;
1b660 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6f 72 6d 75 6c  .}../*.** Formul
1b670 61 74 65 20 61 6e 64 20 70 72 65 70 61 72 65 20  ate and prepare 
1b680 61 6e 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74  an SQL statement
1b690 20 74 6f 20 71 75 65 72 79 20 74 61 62 6c 65 20   to query table 
1b6a0 7a 54 61 62 20 62 79 20 70 72 69 6d 61 72 79 0a  zTab by primary.
1b6b0 2a 2a 20 6b 65 79 2e 20 41 73 73 75 6d 69 6e 67  ** key. Assuming
1b6c0 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74   the following t
1b6d0 61 62 6c 65 20 73 74 72 75 63 74 75 72 65 3a 0a  able structure:.
1b6e0 2a 2a 0a 2a 2a 20 20 20 20 20 43 52 45 41 54 45  **.**     CREATE
1b6f0 20 54 41 42 4c 45 20 78 28 61 2c 20 62 2c 20 63   TABLE x(a, b, c
1b700 2c 20 64 2c 20 50 52 49 4d 41 52 59 20 4b 45 59  , d, PRIMARY KEY
1b710 28 61 2c 20 63 29 29 3b 0a 2a 2a 0a 2a 2a 20 54  (a, c));.**.** T
1b720 68 65 20 53 45 4c 45 43 54 20 73 74 61 74 65 6d  he SELECT statem
1b730 65 6e 74 20 6c 6f 6f 6b 73 20 6c 69 6b 65 20 74  ent looks like t
1b740 68 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 53  his:.**.**     S
1b750 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 78 20 57  ELECT * FROM x W
1b760 48 45 52 45 20 61 20 3d 20 3f 31 20 41 4e 44 20  HERE a = ?1 AND 
1b770 63 20 3d 20 3f 33 0a 2a 2a 0a 2a 2a 20 49 66 20  c = ?3.**.** If 
1b780 73 75 63 63 65 73 73 66 75 6c 2c 20 53 51 4c 49  successful, SQLI
1b790 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65  TE_OK is returne
1b7a0 64 20 61 6e 64 20 53 65 73 73 69 6f 6e 41 70 70  d and SessionApp
1b7b0 6c 79 43 74 78 2e 70 53 65 6c 65 63 74 20 69 73  lyCtx.pSelect is
1b7c0 20 6c 65 66 74 0a 2a 2a 20 70 6f 69 6e 74 69 6e   left.** pointin
1b7d0 67 20 74 6f 20 74 68 65 20 70 72 65 70 61 72 65  g to the prepare
1b7e0 64 20 76 65 72 73 69 6f 6e 20 6f 66 20 74 68 65  d version of the
1b7f0 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 2e 0a   SQL statement..
1b800 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
1b810 73 73 69 6f 6e 53 65 6c 65 63 74 52 6f 77 28 0a  ssionSelectRow(.
1b820 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20    sqlite3 *db,  
1b830 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b840 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61    /* Database ha
1b850 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  ndle */.  const 
1b860 63 68 61 72 20 2a 7a 54 61 62 2c 20 20 20 20 20  char *zTab,     
1b870 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62            /* Tab
1b880 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 53 65 73  le name */.  Ses
1b890 73 69 6f 6e 41 70 70 6c 79 43 74 78 20 2a 70 20  sionApplyCtx *p 
1b8a0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1b8b0 53 65 73 73 69 6f 6e 20 63 68 61 6e 67 65 73 65  Session changese
1b8c0 74 2d 61 70 70 6c 79 20 63 6f 6e 74 65 78 74 20  t-apply context 
1b8d0 2a 2f 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20 73  */.){.  return s
1b8e0 65 73 73 69 6f 6e 53 65 6c 65 63 74 53 74 6d 74  essionSelectStmt
1b8f0 28 0a 20 20 20 20 20 20 64 62 2c 20 22 6d 61 69  (.      db, "mai
1b900 6e 22 2c 20 7a 54 61 62 2c 20 70 2d 3e 6e 43 6f  n", zTab, p->nCo
1b910 6c 2c 20 70 2d 3e 61 7a 43 6f 6c 2c 20 70 2d 3e  l, p->azCol, p->
1b920 61 62 50 4b 2c 20 26 70 2d 3e 70 53 65 6c 65 63  abPK, &p->pSelec
1b930 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6f 72  t);.}../*.** For
1b940 6d 75 6c 61 74 65 20 61 6e 64 20 70 72 65 70 61  mulate and prepa
1b950 72 65 20 61 6e 20 49 4e 53 45 52 54 20 73 74 61  re an INSERT sta
1b960 74 65 6d 65 6e 74 20 74 6f 20 61 64 64 20 61 20  tement to add a 
1b970 72 65 63 6f 72 64 20 74 6f 20 74 61 62 6c 65 20  record to table 
1b980 7a 54 61 62 2e 0a 2a 2a 20 46 6f 72 20 65 78 61  zTab..** For exa
1b990 6d 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  mple:.**.**     
1b9a0 49 4e 53 45 52 54 20 49 4e 54 4f 20 6d 61 69 6e  INSERT INTO main
1b9b0 2e 22 7a 54 61 62 22 20 56 41 4c 55 45 53 28 3f  ."zTab" VALUES(?
1b9c0 31 2c 20 3f 32 2c 20 3f 33 20 2e 2e 2e 29 3b 0a  1, ?2, ?3 ...);.
1b9d0 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65 73 73  **.** If success
1b9e0 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69  ful, SQLITE_OK i
1b9f0 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 53  s returned and S
1ba00 65 73 73 69 6f 6e 41 70 70 6c 79 43 74 78 2e 70  essionApplyCtx.p
1ba10 49 6e 73 65 72 74 20 69 73 20 6c 65 66 74 0a 2a  Insert is left.*
1ba20 2a 20 70 6f 69 6e 74 69 6e 67 20 74 6f 20 74 68  * pointing to th
1ba30 65 20 70 72 65 70 61 72 65 64 20 76 65 72 73 69  e prepared versi
1ba40 6f 6e 20 6f 66 20 74 68 65 20 53 51 4c 20 73 74  on of the SQL st
1ba50 61 74 65 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74  atement..*/.stat
1ba60 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 49 6e  ic int sessionIn
1ba70 73 65 72 74 52 6f 77 28 0a 20 20 73 71 6c 69 74  sertRow(.  sqlit
1ba80 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20  e3 *db,         
1ba90 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
1baa0 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f  tabase handle */
1bab0 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
1bac0 54 61 62 2c 20 20 20 20 20 20 20 20 20 20 20 20  Tab,            
1bad0 20 20 20 2f 2a 20 54 61 62 6c 65 20 6e 61 6d 65     /* Table name
1bae0 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 41 70 70   */.  SessionApp
1baf0 6c 79 43 74 78 20 2a 70 20 20 20 20 20 20 20 20  lyCtx *p        
1bb00 20 20 20 20 20 20 2f 2a 20 53 65 73 73 69 6f 6e        /* Session
1bb10 20 63 68 61 6e 67 65 73 65 74 2d 61 70 70 6c 79   changeset-apply
1bb20 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 29 7b 0a 20   context */.){. 
1bb30 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
1bb40 5f 4f 4b 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  _OK;.  int i;.  
1bb50 53 65 73 73 69 6f 6e 42 75 66 66 65 72 20 62 75  SessionBuffer bu
1bb60 66 20 3d 20 7b 30 2c 20 30 2c 20 30 7d 3b 0a 0a  f = {0, 0, 0};..
1bb70 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53    sessionAppendS
1bb80 74 72 28 26 62 75 66 2c 20 22 49 4e 53 45 52 54  tr(&buf, "INSERT
1bb90 20 49 4e 54 4f 20 6d 61 69 6e 2e 22 2c 20 26 72   INTO main.", &r
1bba0 63 29 3b 0a 20 20 73 65 73 73 69 6f 6e 41 70 70  c);.  sessionApp
1bbb0 65 6e 64 49 64 65 6e 74 28 26 62 75 66 2c 20 7a  endIdent(&buf, z
1bbc0 54 61 62 2c 20 26 72 63 29 3b 0a 20 20 73 65 73  Tab, &rc);.  ses
1bbd0 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62  sionAppendStr(&b
1bbe0 75 66 2c 20 22 20 56 41 4c 55 45 53 28 3f 22 2c  uf, " VALUES(?",
1bbf0 20 26 72 63 29 3b 0a 20 20 66 6f 72 28 69 3d 31   &rc);.  for(i=1
1bc00 3b 20 69 3c 70 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b  ; i<p->nCol; i++
1bc10 29 7b 0a 20 20 20 20 73 65 73 73 69 6f 6e 41 70  ){.    sessionAp
1bc20 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 2c  pendStr(&buf, ",
1bc30 20 3f 22 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 20   ?", &rc);.  }. 
1bc40 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74   sessionAppendSt
1bc50 72 28 26 62 75 66 2c 20 22 29 22 2c 20 26 72 63  r(&buf, ")", &rc
1bc60 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  );..  if( rc==SQ
1bc70 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
1bc80 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70  c = sqlite3_prep
1bc90 61 72 65 5f 76 32 28 64 62 2c 20 28 63 68 61 72  are_v2(db, (char
1bca0 20 2a 29 62 75 66 2e 61 42 75 66 2c 20 62 75 66   *)buf.aBuf, buf
1bcb0 2e 6e 42 75 66 2c 20 26 70 2d 3e 70 49 6e 73 65  .nBuf, &p->pInse
1bcc0 72 74 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 73 71  rt, 0);.  }.  sq
1bcd0 6c 69 74 65 33 5f 66 72 65 65 28 62 75 66 2e 61  lite3_free(buf.a
1bce0 42 75 66 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  Buf);.  return r
1bcf0 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 20 77 72  c;.}../*.** A wr
1bd00 61 70 70 65 72 20 61 72 6f 75 6e 64 20 73 71 6c  apper around sql
1bd10 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28  ite3_bind_value(
1bd20 29 20 74 68 61 74 20 64 65 74 65 63 74 73 20 61  ) that detects a
1bd30 6e 20 65 78 74 72 61 20 70 72 6f 62 6c 65 6d 2e  n extra problem.
1bd40 20 0a 2a 2a 20 53 65 65 20 63 6f 6d 6d 65 6e 74   .** See comment
1bd50 73 20 69 6e 20 74 68 65 20 62 6f 64 79 20 6f 66  s in the body of
1bd60 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 66   this function f
1bd70 6f 72 20 64 65 74 61 69 6c 73 2e 0a 2a 2f 0a 73  or details..*/.s
1bd80 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f  tatic int sessio
1bd90 6e 42 69 6e 64 56 61 6c 75 65 28 0a 20 20 73 71  nBindValue(.  sq
1bda0 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
1bdb0 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  t,            /*
1bdc0 20 53 74 61 74 65 6d 65 6e 74 20 74 6f 20 62 69   Statement to bi
1bdd0 6e 64 20 76 61 6c 75 65 20 74 6f 20 2a 2f 0a 20  nd value to */. 
1bde0 20 69 6e 74 20 69 2c 20 20 20 20 20 20 20 20 20   int i,         
1bdf0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1be00 20 2f 2a 20 50 61 72 61 6d 65 74 65 72 20 6e 75   /* Parameter nu
1be10 6d 62 65 72 20 74 6f 20 62 69 6e 64 20 74 6f 20  mber to bind to 
1be20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c  */.  sqlite3_val
1be30 75 65 20 2a 70 56 61 6c 20 20 20 20 20 20 20 20  ue *pVal        
1be40 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 74 6f       /* Value to
1be50 20 62 69 6e 64 20 2a 2f 0a 29 7b 0a 20 20 69 6e   bind */.){.  in
1be60 74 20 65 54 79 70 65 20 3d 20 73 71 6c 69 74 65  t eType = sqlite
1be70 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 70 56 61  3_value_type(pVa
1be80 6c 29 3b 0a 20 20 2f 2a 20 43 4f 56 45 52 41 47  l);.  /* COVERAG
1be90 45 3a 20 54 68 65 20 28 70 56 61 6c 2d 3e 7a 3d  E: The (pVal->z=
1bea0 3d 30 29 20 62 72 61 6e 63 68 20 69 73 20 6e 65  =0) branch is ne
1beb0 76 65 72 20 74 72 75 65 20 75 73 69 6e 67 20 63  ver true using c
1bec0 75 72 72 65 6e 74 20 76 65 72 73 69 6f 6e 73 0a  urrent versions.
1bed0 20 20 2a 2a 20 6f 66 20 53 51 4c 69 74 65 2e 20    ** of SQLite. 
1bee0 49 66 20 61 20 6d 61 6c 6c 6f 63 20 66 61 69 6c  If a malloc fail
1bef0 73 20 69 6e 20 61 6e 20 73 71 6c 69 74 65 33 5f  s in an sqlite3_
1bf00 76 61 6c 75 65 5f 78 78 78 28 29 20 66 75 6e 63  value_xxx() func
1bf10 74 69 6f 6e 2c 20 65 69 74 68 65 72 0a 20 20 2a  tion, either.  *
1bf20 2a 20 74 68 65 20 28 70 56 61 6c 2d 3e 7a 29 20  * the (pVal->z) 
1bf30 76 61 72 69 61 62 6c 65 20 72 65 6d 61 69 6e 73  variable remains
1bf40 20 61 73 20 69 74 20 77 61 73 20 6f 72 20 74 68   as it was or th
1bf50 65 20 74 79 70 65 20 6f 66 20 74 68 65 20 76 61  e type of the va
1bf60 6c 75 65 20 69 73 0a 20 20 2a 2a 20 73 65 74 20  lue is.  ** set 
1bf70 74 6f 20 53 51 4c 49 54 45 5f 4e 55 4c 4c 2e 20  to SQLITE_NULL. 
1bf80 20 2a 2f 0a 20 20 69 66 28 20 28 65 54 79 70 65   */.  if( (eType
1bf90 3d 3d 53 51 4c 49 54 45 5f 54 45 58 54 20 7c 7c  ==SQLITE_TEXT ||
1bfa0 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 42   eType==SQLITE_B
1bfb0 4c 4f 42 29 20 26 26 20 70 56 61 6c 2d 3e 7a 3d  LOB) && pVal->z=
1bfc0 3d 30 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 69  =0 ){.    /* Thi
1bfd0 73 20 63 6f 6e 64 69 74 69 6f 6e 20 6f 63 63 75  s condition occu
1bfe0 72 73 20 77 68 65 6e 20 61 6e 20 65 61 72 6c 69  rs when an earli
1bff0 65 72 20 4f 4f 4d 20 69 6e 20 61 20 63 61 6c 6c  er OOM in a call
1c000 20 74 6f 0a 20 20 20 20 2a 2a 20 73 71 6c 69 74   to.    ** sqlit
1c010 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 29 20  e3_value_text() 
1c020 6f 72 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  or sqlite3_value
1c030 5f 62 6c 6f 62 28 29 20 28 70 65 72 68 61 70 73  _blob() (perhaps
1c040 20 66 72 6f 6d 20 77 69 74 68 69 6e 0a 20 20 20   from within.   
1c050 20 2a 2a 20 61 20 63 6f 6e 66 6c 69 63 74 2d 68   ** a conflict-h
1c060 61 6e 64 6c 65 72 29 20 68 61 73 20 7a 65 72 6f  andler) has zero
1c070 65 64 20 74 68 65 20 70 56 61 6c 2d 3e 7a 20 70  ed the pVal->z p
1c080 6f 69 6e 74 65 72 2e 20 52 65 74 75 72 6e 20 4e  ointer. Return N
1c090 4f 4d 45 4d 2e 20 2a 2f 0a 20 20 20 20 72 65 74  OMEM. */.    ret
1c0a0 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
1c0b0 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73  ;.  }.  return s
1c0c0 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75  qlite3_bind_valu
1c0d0 65 28 70 53 74 6d 74 2c 20 69 2c 20 70 56 61 6c  e(pStmt, i, pVal
1c0e0 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 74 65 72  );.}../*.** Iter
1c0f0 61 74 6f 72 20 70 49 74 65 72 20 6d 75 73 74 20  ator pIter must 
1c100 70 6f 69 6e 74 20 74 6f 20 61 6e 20 53 51 4c 49  point to an SQLI
1c110 54 45 5f 49 4e 53 45 52 54 20 65 6e 74 72 79 2e  TE_INSERT entry.
1c120 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 0a   This function .
1c130 2a 2a 20 74 72 61 6e 73 66 65 72 73 20 6e 65 77  ** transfers new
1c140 2e 2a 20 76 61 6c 75 65 73 20 66 72 6f 6d 20 74  .* values from t
1c150 68 65 20 63 75 72 72 65 6e 74 20 69 74 65 72 61  he current itera
1c160 74 6f 72 20 65 6e 74 72 79 20 74 6f 20 73 74 61  tor entry to sta
1c170 74 65 6d 65 6e 74 0a 2a 2a 20 70 53 74 6d 74 2e  tement.** pStmt.
1c180 20 54 68 65 20 74 61 62 6c 65 20 62 65 69 6e 67   The table being
1c190 20 69 6e 73 65 72 74 65 64 20 69 6e 74 6f 20 68   inserted into h
1c1a0 61 73 20 6e 43 6f 6c 20 63 6f 6c 75 6d 6e 73 2e  as nCol columns.
1c1b0 0a 2a 2a 0a 2a 2a 20 4e 65 77 2e 2a 20 76 61 6c  .**.** New.* val
1c1c0 75 65 20 24 69 20 66 72 6f 6d 20 74 68 65 20 69  ue $i from the i
1c1d0 74 65 72 61 74 6f 72 20 69 73 20 62 6f 75 6e 64  terator is bound
1c1e0 20 74 6f 20 76 61 72 69 61 62 6c 65 20 28 24 69   to variable ($i
1c1f0 2b 31 29 20 6f 66 20 0a 2a 2a 20 73 74 61 74 65  +1) of .** state
1c200 6d 65 6e 74 20 70 53 74 6d 74 2e 20 49 66 20 70  ment pStmt. If p
1c210 61 72 61 6d 65 74 65 72 20 61 62 50 4b 20 69 73  arameter abPK is
1c220 20 4e 55 4c 4c 2c 20 61 6c 6c 20 76 61 6c 75 65   NULL, all value
1c230 73 20 66 72 6f 6d 20 30 20 74 6f 20 28 6e 43 6f  s from 0 to (nCo
1c240 6c 2d 31 29 0a 2a 2a 20 61 72 65 20 74 72 61 6e  l-1).** are tran
1c250 73 66 65 72 65 64 20 74 6f 20 74 68 65 20 73 74  sfered to the st
1c260 61 74 65 6d 65 6e 74 2e 20 4f 74 68 65 72 77 69  atement. Otherwi
1c270 73 65 2c 20 69 66 20 61 62 50 4b 20 69 73 20 6e  se, if abPK is n
1c280 6f 74 20 4e 55 4c 4c 2c 20 69 74 20 70 6f 69 6e  ot NULL, it poin
1c290 74 73 0a 2a 2a 20 74 6f 20 61 6e 20 61 72 72 61  ts.** to an arra
1c2a0 79 20 6e 43 6f 6c 20 65 6c 65 6d 65 6e 74 73 20  y nCol elements 
1c2b0 69 6e 20 73 69 7a 65 2e 20 49 6e 20 74 68 69 73  in size. In this
1c2c0 20 63 61 73 65 20 6f 6e 6c 79 20 74 68 6f 73 65   case only those
1c2d0 20 76 61 6c 75 65 73 20 66 6f 72 20 0a 2a 2a 20   values for .** 
1c2e0 77 68 69 63 68 20 61 62 50 4b 5b 24 69 5d 20 69  which abPK[$i] i
1c2f0 73 20 74 72 75 65 20 61 72 65 20 72 65 61 64 20  s true are read 
1c300 66 72 6f 6d 20 74 68 65 20 69 74 65 72 61 74 6f  from the iterato
1c310 72 20 61 6e 64 20 62 6f 75 6e 64 20 74 6f 20 74  r and bound to t
1c320 68 65 20 0a 2a 2a 20 73 74 61 74 65 6d 65 6e 74  he .** statement
1c330 2e 0a 2a 2a 0a 2a 2a 20 41 6e 20 53 51 4c 69 74  ..**.** An SQLit
1c340 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69 73 20  e error code is 
1c350 72 65 74 75 72 6e 65 64 20 69 66 20 61 6e 20 65  returned if an e
1c360 72 72 6f 72 20 6f 63 63 75 72 73 2e 20 4f 74 68  rror occurs. Oth
1c370 65 72 77 69 73 65 2c 20 53 51 4c 49 54 45 5f 4f  erwise, SQLITE_O
1c380 4b 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  K..*/.static int
1c390 20 73 65 73 73 69 6f 6e 42 69 6e 64 52 6f 77 28   sessionBindRow(
1c3a0 0a 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67  .  sqlite3_chang
1c3b0 65 73 65 74 5f 69 74 65 72 20 2a 70 49 74 65 72  eset_iter *pIter
1c3c0 2c 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 74  ,  /* Iterator t
1c3d0 6f 20 72 65 61 64 20 76 61 6c 75 65 73 20 66 72  o read values fr
1c3e0 6f 6d 20 2a 2f 0a 20 20 69 6e 74 28 2a 78 56 61  om */.  int(*xVa
1c3f0 6c 75 65 29 28 73 71 6c 69 74 65 33 5f 63 68 61  lue)(sqlite3_cha
1c400 6e 67 65 73 65 74 5f 69 74 65 72 20 2a 2c 20 69  ngeset_iter *, i
1c410 6e 74 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  nt, sqlite3_valu
1c420 65 20 2a 2a 29 2c 0a 20 20 69 6e 74 20 6e 43 6f  e **),.  int nCo
1c430 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
1c440 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
1c450 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 2a 2f  er of columns */
1c460 0a 20 20 75 38 20 2a 61 62 50 4b 2c 20 20 20 20  .  u8 *abPK,    
1c470 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c480 20 20 20 2f 2a 20 49 66 20 6e 6f 74 20 4e 55 4c     /* If not NUL
1c490 4c 2c 20 62 69 6e 64 20 6f 6e 6c 79 20 69 66 20  L, bind only if 
1c4a0 74 72 75 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65  true */.  sqlite
1c4b0 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 20 20  3_stmt *pStmt   
1c4c0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 69 6e            /* Bin
1c4d0 64 20 76 61 6c 75 65 73 20 74 6f 20 74 68 69 73  d values to this
1c4e0 20 73 74 61 74 65 6d 65 6e 74 20 2a 2f 0a 29 7b   statement */.){
1c4f0 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20  .  int i;.  int 
1c500 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
1c510 0a 20 20 2f 2a 20 4e 65 69 74 68 65 72 20 73 71  .  /* Neither sq
1c520 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f  lite3changeset_o
1c530 6c 64 20 6f 72 20 73 71 6c 69 74 65 33 63 68 61  ld or sqlite3cha
1c540 6e 67 65 73 65 74 5f 6e 65 77 20 63 61 6e 20 66  ngeset_new can f
1c550 61 69 6c 20 69 66 20 74 68 65 0a 20 20 2a 2a 20  ail if the.  ** 
1c560 61 72 67 75 6d 65 6e 74 20 69 74 65 72 61 74 6f  argument iterato
1c570 72 20 70 6f 69 6e 74 73 20 74 6f 20 61 20 73 75  r points to a su
1c580 69 74 61 62 6c 65 20 65 6e 74 72 79 2e 20 4d 61  itable entry. Ma
1c590 6b 65 20 73 75 72 65 20 74 68 61 74 20 78 56 61  ke sure that xVa
1c5a0 6c 75 65 20 0a 20 20 2a 2a 20 69 73 20 6f 6e 65  lue .  ** is one
1c5b0 20 6f 66 20 74 68 65 73 65 20 74 6f 20 67 75 61   of these to gua
1c5c0 72 61 6e 74 65 65 20 74 68 61 74 20 69 74 20 69  rantee that it i
1c5d0 73 20 73 61 66 65 20 74 6f 20 69 67 6e 6f 72 65  s safe to ignore
1c5e0 20 74 68 65 20 72 65 74 75 72 6e 20 0a 20 20 2a   the return .  *
1c5f0 2a 20 69 6e 20 74 68 65 20 63 6f 64 65 20 62 65  * in the code be
1c600 6c 6f 77 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74  low. */.  assert
1c610 28 20 78 56 61 6c 75 65 3d 3d 73 71 6c 69 74 65  ( xValue==sqlite
1c620 33 63 68 61 6e 67 65 73 65 74 5f 6f 6c 64 20 7c  3changeset_old |
1c630 7c 20 78 56 61 6c 75 65 3d 3d 73 71 6c 69 74 65  | xValue==sqlite
1c640 33 63 68 61 6e 67 65 73 65 74 5f 6e 65 77 20 29  3changeset_new )
1c650 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 72 63  ;..  for(i=0; rc
1c660 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69  ==SQLITE_OK && i
1c670 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20  <nCol; i++){.   
1c680 20 69 66 28 20 21 61 62 50 4b 20 7c 7c 20 61 62   if( !abPK || ab
1c690 50 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20 73  PK[i] ){.      s
1c6a0 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56  qlite3_value *pV
1c6b0 61 6c 3b 0a 20 20 20 20 20 20 28 76 6f 69 64 29  al;.      (void)
1c6c0 78 56 61 6c 75 65 28 70 49 74 65 72 2c 20 69 2c  xValue(pIter, i,
1c6d0 20 26 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 72   &pVal);.      r
1c6e0 63 20 3d 20 73 65 73 73 69 6f 6e 42 69 6e 64 56  c = sessionBindV
1c6f0 61 6c 75 65 28 70 53 74 6d 74 2c 20 69 2b 31 2c  alue(pStmt, i+1,
1c700 20 70 56 61 6c 29 3b 0a 20 20 20 20 7d 0a 20 20   pVal);.    }.  
1c710 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
1c720 0a 0a 2f 2a 0a 2a 2a 20 53 51 4c 20 73 74 61 74  ../*.** SQL stat
1c730 65 6d 65 6e 74 20 70 53 65 6c 65 63 74 20 69 73  ement pSelect is
1c740 20 61 73 20 67 65 6e 65 72 61 74 65 64 20 62 79   as generated by
1c750 20 74 68 65 20 73 65 73 73 69 6f 6e 53 65 6c 65   the sessionSele
1c760 63 74 52 6f 77 28 29 20 66 75 6e 63 74 69 6f 6e  ctRow() function
1c770 2e 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  ..** This functi
1c780 6f 6e 20 62 69 6e 64 73 20 74 68 65 20 70 72 69  on binds the pri
1c790 6d 61 72 79 20 6b 65 79 20 76 61 6c 75 65 73 20  mary key values 
1c7a0 66 72 6f 6d 20 74 68 65 20 63 68 61 6e 67 65 20  from the change 
1c7b0 74 68 61 74 20 63 68 61 6e 67 65 73 65 74 0a 2a  that changeset.*
1c7c0 2a 20 69 74 65 72 61 74 6f 72 20 70 49 74 65 72  * iterator pIter
1c7d0 20 70 6f 69 6e 74 73 20 74 6f 20 74 6f 20 74 68   points to to th
1c7e0 65 20 53 45 4c 45 43 54 20 61 6e 64 20 61 74 74  e SELECT and att
1c7f0 65 6d 70 74 73 20 74 6f 20 73 65 65 6b 20 74 6f  empts to seek to
1c800 20 74 68 65 20 74 61 62 6c 65 0a 2a 2a 20 65 6e   the table.** en
1c810 74 72 79 2e 20 49 66 20 61 20 72 6f 77 20 69 73  try. If a row is
1c820 20 66 6f 75 6e 64 2c 20 74 68 65 20 53 45 4c 45   found, the SELE
1c830 43 54 20 73 74 61 74 65 6d 65 6e 74 20 6c 65 66  CT statement lef
1c840 74 20 70 6f 69 6e 74 69 6e 67 20 61 74 20 74 68  t pointing at th
1c850 65 20 72 6f 77 20 0a 2a 2a 20 61 6e 64 20 53 51  e row .** and SQ
1c860 4c 49 54 45 5f 52 4f 57 20 69 73 20 72 65 74 75  LITE_ROW is retu
1c870 72 6e 65 64 2e 20 4f 74 68 65 72 77 69 73 65 2c  rned. Otherwise,
1c880 20 69 66 20 6e 6f 20 72 6f 77 20 69 73 20 66 6f   if no row is fo
1c890 75 6e 64 20 61 6e 64 20 6e 6f 20 65 72 72 6f 72  und and no error
1c8a0 0a 2a 2a 20 68 61 73 20 6f 63 63 75 72 65 64 2c  .** has occured,
1c8b0 20 74 68 65 20 73 74 61 74 65 6d 65 6e 74 20 69   the statement i
1c8c0 73 20 72 65 73 65 74 20 61 6e 64 20 53 51 4c 49  s reset and SQLI
1c8d0 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65  TE_OK is returne
1c8e0 64 2e 20 49 66 20 61 6e 0a 2a 2a 20 65 72 72 6f  d. If an.** erro
1c8f0 72 20 6f 63 63 75 72 73 2c 20 74 68 65 20 73 74  r occurs, the st
1c900 61 74 65 6d 65 6e 74 20 69 73 20 72 65 73 65 74  atement is reset
1c910 20 61 6e 64 20 61 6e 20 53 51 4c 69 74 65 20 65   and an SQLite e
1c920 72 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74  rror code is ret
1c930 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  urned..**.** If 
1c940 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72 65  this function re
1c950 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 52 4f 57  turns SQLITE_ROW
1c960 2c 20 74 68 65 20 63 61 6c 6c 65 72 20 6d 75 73  , the caller mus
1c970 74 20 65 76 65 6e 74 75 61 6c 6c 79 20 72 65 73  t eventually res
1c980 65 74 28 29 20 0a 2a 2a 20 73 74 61 74 65 6d 65  et() .** stateme
1c990 6e 74 20 70 53 65 6c 65 63 74 2e 20 49 66 20 61  nt pSelect. If a
1c9a0 6e 79 20 6f 74 68 65 72 20 76 61 6c 75 65 20 69  ny other value i
1c9b0 73 20 72 65 74 75 72 6e 65 64 2c 20 74 68 65 20  s returned, the 
1c9c0 73 74 61 74 65 6d 65 6e 74 20 64 6f 65 73 0a 2a  statement does.*
1c9d0 2a 20 6e 6f 74 20 72 65 71 75 69 72 65 20 61 20  * not require a 
1c9e0 72 65 73 65 74 28 29 2e 0a 2a 2a 0a 2a 2a 20 49  reset()..**.** I
1c9f0 66 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 63  f the iterator c
1ca00 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20  urrently points 
1ca10 74 6f 20 61 6e 20 49 4e 53 45 52 54 20 72 65 63  to an INSERT rec
1ca20 6f 72 64 2c 20 62 69 6e 64 20 76 61 6c 75 65 73  ord, bind values
1ca30 20 66 72 6f 6d 20 74 68 65 0a 2a 2a 20 6e 65 77   from the.** new
1ca40 2e 2a 20 72 65 63 6f 72 64 20 74 6f 20 74 68 65  .* record to the
1ca50 20 53 45 4c 45 43 54 20 73 74 61 74 65 6d 65 6e   SELECT statemen
1ca60 74 2e 20 4f 72 2c 20 69 66 20 69 74 20 70 6f 69  t. Or, if it poi
1ca70 6e 74 73 20 74 6f 20 61 20 44 45 4c 45 54 45 20  nts to a DELETE 
1ca80 6f 72 0a 2a 2a 20 55 50 44 41 54 45 2c 20 62 69  or.** UPDATE, bi
1ca90 6e 64 20 76 61 6c 75 65 73 20 66 72 6f 6d 20 74  nd values from t
1caa0 68 65 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 2e  he old.* record.
1cab0 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20   .*/.static int 
1cac0 73 65 73 73 69 6f 6e 53 65 65 6b 54 6f 52 6f 77  sessionSeekToRow
1cad0 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
1cae0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1caf0 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
1cb00 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 73 71 6c 69  handle */.  sqli
1cb10 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74  te3_changeset_it
1cb20 65 72 20 2a 70 49 74 65 72 2c 20 20 2f 2a 20 43  er *pIter,  /* C
1cb30 68 61 6e 67 65 73 65 74 20 69 74 65 72 61 74 6f  hangeset iterato
1cb40 72 20 2a 2f 0a 20 20 75 38 20 2a 61 62 50 4b 2c  r */.  u8 *abPK,
1cb50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cb60 20 20 20 20 20 20 20 2f 2a 20 50 72 69 6d 61 72         /* Primar
1cb70 79 20 6b 65 79 20 66 6c 61 67 73 20 61 72 72 61  y key flags arra
1cb80 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73  y */.  sqlite3_s
1cb90 74 6d 74 20 2a 70 53 65 6c 65 63 74 20 20 20 20  tmt *pSelect    
1cba0 20 20 20 20 20 20 20 2f 2a 20 53 45 4c 45 43 54         /* SELECT
1cbb0 20 73 74 61 74 65 6d 65 6e 74 20 66 72 6f 6d 20   statement from 
1cbc0 73 65 73 73 69 6f 6e 53 65 6c 65 63 74 52 6f 77  sessionSelectRow
1cbd0 28 29 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  () */.){.  int r
1cbe0 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
1cbf0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
1cc00 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69  turn code */.  i
1cc10 6e 74 20 6e 43 6f 6c 3b 20 20 20 20 20 20 20 20  nt nCol;        
1cc20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1cc30 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75  * Number of colu
1cc40 6d 6e 73 20 69 6e 20 74 61 62 6c 65 20 2a 2f 0a  mns in table */.
1cc50 20 20 69 6e 74 20 6f 70 3b 20 20 20 20 20 20 20    int op;       
1cc60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cc70 20 20 2f 2a 20 43 68 61 6e 67 73 65 74 20 6f 70    /* Changset op
1cc80 65 72 61 74 69 6f 6e 20 28 53 51 4c 49 54 45 5f  eration (SQLITE_
1cc90 55 50 44 41 54 45 20 65 74 63 2e 29 20 2a 2f 0a  UPDATE etc.) */.
1cca0 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44    const char *zD
1ccb0 75 6d 6d 79 3b 20 20 20 20 20 20 20 20 20 20 20  ummy;           
1ccc0 20 20 2f 2a 20 55 6e 75 73 65 64 20 2a 2f 0a 0a    /* Unused */..
1ccd0 20 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73    sqlite3changes
1cce0 65 74 5f 6f 70 28 70 49 74 65 72 2c 20 26 7a 44  et_op(pIter, &zD
1ccf0 75 6d 6d 79 2c 20 26 6e 43 6f 6c 2c 20 26 6f 70  ummy, &nCol, &op
1cd00 2c 20 30 29 3b 0a 20 20 72 63 20 3d 20 73 65 73  , 0);.  rc = ses
1cd10 73 69 6f 6e 42 69 6e 64 52 6f 77 28 70 49 74 65  sionBindRow(pIte
1cd20 72 2c 20 0a 20 20 20 20 20 20 6f 70 3d 3d 53 51  r, .      op==SQ
1cd30 4c 49 54 45 5f 49 4e 53 45 52 54 20 3f 20 73 71  LITE_INSERT ? sq
1cd40 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6e  lite3changeset_n
1cd50 65 77 20 3a 20 73 71 6c 69 74 65 33 63 68 61 6e  ew : sqlite3chan
1cd60 67 65 73 65 74 5f 6f 6c 64 2c 0a 20 20 20 20 20  geset_old,.     
1cd70 20 6e 43 6f 6c 2c 20 61 62 50 4b 2c 20 70 53 65   nCol, abPK, pSe
1cd80 6c 65 63 74 0a 20 20 29 3b 0a 0a 20 20 69 66 28  lect.  );..  if(
1cd90 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
1cda0 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
1cdb0 65 33 5f 73 74 65 70 28 70 53 65 6c 65 63 74 29  e3_step(pSelect)
1cdc0 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
1cdd0 4c 49 54 45 5f 52 4f 57 20 29 20 72 63 20 3d 20  LITE_ROW ) rc = 
1cde0 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70 53  sqlite3_reset(pS
1cdf0 65 6c 65 63 74 29 3b 0a 20 20 7d 0a 0a 20 20 72  elect);.  }..  r
1ce00 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
1ce10 2a 2a 20 49 6e 76 6f 6b 65 20 74 68 65 20 63 6f  ** Invoke the co
1ce20 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65 72 20 66  nflict handler f
1ce30 6f 72 20 74 68 65 20 63 68 61 6e 67 65 20 74 68  or the change th
1ce40 61 74 20 74 68 65 20 63 68 61 6e 67 65 73 65 74  at the changeset
1ce50 20 69 74 65 72 61 74 6f 72 0a 2a 2a 20 63 75 72   iterator.** cur
1ce60 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f  rently points to
1ce70 2e 0a 2a 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e 74  ..**.** Argument
1ce80 20 65 54 79 70 65 20 6d 75 73 74 20 62 65 20 65   eType must be e
1ce90 69 74 68 65 72 20 43 48 41 4e 47 45 53 45 54 5f  ither CHANGESET_
1cea0 44 41 54 41 20 6f 72 20 43 48 41 4e 47 45 53 45  DATA or CHANGESE
1ceb0 54 5f 43 4f 4e 46 4c 49 43 54 2e 0a 2a 2a 20 49  T_CONFLICT..** I
1cec0 66 20 61 72 67 75 6d 65 6e 74 20 70 62 52 65 70  f argument pbRep
1ced0 6c 61 63 65 20 69 73 20 4e 55 4c 4c 2c 20 74 68  lace is NULL, th
1cee0 65 6e 20 74 68 65 20 74 79 70 65 20 6f 66 20 63  en the type of c
1cef0 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65 72 20  onflict handler 
1cf00 69 6e 76 6f 6b 65 64 0a 2a 2a 20 64 65 70 65 6e  invoked.** depen
1cf10 64 73 20 73 6f 6c 65 6c 79 20 6f 6e 20 65 54 79  ds solely on eTy
1cf20 70 65 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a  pe, as follows:.
1cf30 2a 2a 0a 2a 2a 20 20 20 20 65 54 79 70 65 20 76  **.**    eType v
1cf40 61 6c 75 65 20 20 20 20 20 20 20 20 20 20 20 20  alue            
1cf50 20 20 20 20 20 56 61 6c 75 65 20 70 61 73 73 65       Value passe
1cf60 64 20 74 6f 20 78 43 6f 6e 66 6c 69 63 74 0a 2a  d to xConflict.*
1cf70 2a 20 20 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  *    -----------
1cf80 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1cf90 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1cfa0 2d 2d 2d 2d 2d 2d 0a 2a 2a 20 20 20 20 43 48 41  ------.**    CHA
1cfb0 4e 47 45 53 45 54 5f 44 41 54 41 20 20 20 20 20  NGESET_DATA     
1cfc0 20 20 20 20 20 20 20 20 20 43 48 41 4e 47 45 53           CHANGES
1cfd0 45 54 5f 4e 4f 54 46 4f 55 4e 44 0a 2a 2a 20 20  ET_NOTFOUND.**  
1cfe0 20 20 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46    CHANGESET_CONF
1cff0 4c 49 43 54 20 20 20 20 20 20 20 20 20 20 43 48  LICT          CH
1d000 41 4e 47 45 53 45 54 5f 43 4f 4e 53 54 52 41 49  ANGESET_CONSTRAI
1d010 4e 54 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 69 66 20  NT.**.** Or, if 
1d020 70 62 52 65 70 6c 61 63 65 20 69 73 20 6e 6f 74  pbReplace is not
1d030 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 61 6e 20 61   NULL, then an a
1d040 74 74 65 6d 70 74 20 69 73 20 6d 61 64 65 20 74  ttempt is made t
1d050 6f 20 66 69 6e 64 20 61 6e 20 65 78 69 73 74 69  o find an existi
1d060 6e 67 0a 2a 2a 20 72 65 63 6f 72 64 20 77 69 74  ng.** record wit
1d070 68 20 74 68 65 20 73 61 6d 65 20 70 72 69 6d 61  h the same prima
1d080 72 79 20 6b 65 79 20 61 73 20 74 68 65 20 72 65  ry key as the re
1d090 63 6f 72 64 20 61 62 6f 75 74 20 74 6f 20 62 65  cord about to be
1d0a0 20 64 65 6c 65 74 65 64 2c 20 75 70 64 61 74 65   deleted, update
1d0b0 64 0a 2a 2a 20 6f 72 20 69 6e 73 65 72 74 65 64  d.** or inserted
1d0c0 2e 20 49 66 20 73 75 63 68 20 61 20 72 65 63 6f  . If such a reco
1d0d0 72 64 20 63 61 6e 20 62 65 20 66 6f 75 6e 64 2c  rd can be found,
1d0e0 20 69 74 20 69 73 20 61 76 61 69 6c 61 62 6c 65   it is available
1d0f0 20 74 6f 20 74 68 65 20 63 6f 6e 66 6c 69 63 74   to the conflict
1d100 0a 2a 2a 20 68 61 6e 64 6c 65 72 20 61 73 20 74  .** handler as t
1d110 68 65 20 22 63 6f 6e 66 6c 69 63 74 69 6e 67 22  he "conflicting"
1d120 20 72 65 63 6f 72 64 2e 20 49 6e 20 74 68 69 73   record. In this
1d130 20 63 61 73 65 20 74 68 65 20 74 79 70 65 20 6f   case the type o
1d140 66 20 63 6f 6e 66 6c 69 63 74 0a 2a 2a 20 68 61  f conflict.** ha
1d150 6e 64 6c 65 72 20 69 6e 76 6f 6b 65 64 20 69 73  ndler invoked is
1d160 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a   as follows:.**.
1d170 2a 2a 20 20 20 20 65 54 79 70 65 20 76 61 6c 75  **    eType valu
1d180 65 20 20 20 20 20 20 20 20 20 50 4b 20 52 65 63  e         PK Rec
1d190 6f 72 64 20 66 6f 75 6e 64 3f 20 20 20 56 61 6c  ord found?   Val
1d1a0 75 65 20 70 61 73 73 65 64 20 74 6f 20 78 43 6f  ue passed to xCo
1d1b0 6e 66 6c 69 63 74 0a 2a 2a 20 20 20 20 2d 2d 2d  nflict.**    ---
1d1c0 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1d1d0 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1d1e0 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1d1f0 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 2a 2a  -------------.**
1d200 20 20 20 20 43 48 41 4e 47 45 53 45 54 5f 44 41      CHANGESET_DA
1d210 54 41 20 20 20 20 20 20 59 65 73 20 20 20 20 20  TA      Yes     
1d220 20 20 20 20 20 20 20 20 20 20 20 43 48 41 4e 47             CHANG
1d230 45 53 45 54 5f 44 41 54 41 0a 2a 2a 20 20 20 20  ESET_DATA.**    
1d240 43 48 41 4e 47 45 53 45 54 5f 44 41 54 41 20 20  CHANGESET_DATA  
1d250 20 20 20 20 4e 6f 20 20 20 20 20 20 20 20 20 20      No          
1d260 20 20 20 20 20 20 20 43 48 41 4e 47 45 53 45 54         CHANGESET
1d270 5f 4e 4f 54 46 4f 55 4e 44 0a 2a 2a 20 20 20 20  _NOTFOUND.**    
1d280 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49  CHANGESET_CONFLI
1d290 43 54 20 20 59 65 73 20 20 20 20 20 20 20 20 20  CT  Yes         
1d2a0 20 20 20 20 20 20 20 43 48 41 4e 47 45 53 45 54         CHANGESET
1d2b0 5f 43 4f 4e 46 4c 49 43 54 0a 2a 2a 20 20 20 20  _CONFLICT.**    
1d2c0 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49  CHANGESET_CONFLI
1d2d0 43 54 20 20 4e 6f 20 20 20 20 20 20 20 20 20 20  CT  No          
1d2e0 20 20 20 20 20 20 20 43 48 41 4e 47 45 53 45 54         CHANGESET
1d2f0 5f 43 4f 4e 53 54 52 41 49 4e 54 0a 2a 2a 0a 2a  _CONSTRAINT.**.*
1d300 2a 20 49 66 20 70 62 52 65 70 6c 61 63 65 20 69  * If pbReplace i
1d310 73 20 6e 6f 74 20 4e 55 4c 4c 2c 20 61 6e 64 20  s not NULL, and 
1d320 61 20 72 65 63 6f 72 64 20 77 69 74 68 20 61 20  a record with a 
1d330 6d 61 74 63 68 69 6e 67 20 50 4b 20 69 73 20 66  matching PK is f
1d340 6f 75 6e 64 2c 20 61 6e 64 0a 2a 2a 20 74 68 65  ound, and.** the
1d350 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65   conflict handle
1d360 72 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72  r function retur
1d370 6e 73 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45  ns SQLITE_CHANGE
1d380 53 45 54 5f 52 45 50 4c 41 43 45 2c 20 2a 70 62  SET_REPLACE, *pb
1d390 52 65 70 6c 61 63 65 0a 2a 2a 20 69 73 20 73 65  Replace.** is se
1d3a0 74 20 74 6f 20 6e 6f 6e 2d 7a 65 72 6f 20 62 65  t to non-zero be
1d3b0 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 20 53  fore returning S
1d3c0 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2a 0a 2a 2a 20  QLITE_OK..**.** 
1d3d0 49 66 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 20  If the conflict 
1d3e0 68 61 6e 64 6c 65 72 20 72 65 74 75 72 6e 73 20  handler returns 
1d3f0 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54  SQLITE_CHANGESET
1d400 5f 41 42 4f 52 54 2c 20 53 51 4c 49 54 45 5f 41  _ABORT, SQLITE_A
1d410 42 4f 52 54 20 69 73 0a 2a 2a 20 72 65 74 75 72  BORT is.** retur
1d420 6e 65 64 2e 20 4f 72 2c 20 69 66 20 74 68 65 20  ned. Or, if the 
1d430 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65 72  conflict handler
1d440 20 72 65 74 75 72 6e 73 20 61 6e 20 69 6e 76 61   returns an inva
1d450 6c 69 64 20 76 61 6c 75 65 2c 20 0a 2a 2a 20 53  lid value, .** S
1d460 51 4c 49 54 45 5f 4d 49 53 55 53 45 2e 20 49 66  QLITE_MISUSE. If
1d470 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 20 68 61   the conflict ha
1d480 6e 64 6c 65 72 20 72 65 74 75 72 6e 73 20 53 51  ndler returns SQ
1d490 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 4f  LITE_CHANGESET_O
1d4a0 4d 49 54 2c 0a 2a 2a 20 74 68 69 73 20 66 75 6e  MIT,.** this fun
1d4b0 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 53 51  ction returns SQ
1d4c0 4c 49 54 45 5f 4f 4b 2e 0a 2a 2f 0a 73 74 61 74  LITE_OK..*/.stat
1d4d0 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 43 6f  ic int sessionCo
1d4e0 6e 66 6c 69 63 74 48 61 6e 64 6c 65 72 28 0a 20  nflictHandler(. 
1d4f0 20 69 6e 74 20 65 54 79 70 65 2c 20 20 20 20 20   int eType,     
1d500 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d510 20 2f 2a 20 45 69 74 68 65 72 20 43 48 41 4e 47   /* Either CHANG
1d520 45 53 45 54 5f 44 41 54 41 20 6f 72 20 43 4f 4e  ESET_DATA or CON
1d530 46 4c 49 43 54 20 2a 2f 0a 20 20 53 65 73 73 69  FLICT */.  Sessi
1d540 6f 6e 41 70 70 6c 79 43 74 78 20 2a 70 2c 20 20  onApplyCtx *p,  
1d550 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 63 68             /* ch
1d560 61 6e 67 65 73 65 74 5f 61 70 70 6c 79 28 29 20  angeset_apply() 
1d570 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 73 71 6c  context */.  sql
1d580 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69  ite3_changeset_i
1d590 74 65 72 20 2a 70 49 74 65 72 2c 20 20 2f 2a 20  ter *pIter,  /* 
1d5a0 43 68 61 6e 67 65 73 65 74 20 69 74 65 72 61 74  Changeset iterat
1d5b0 6f 72 20 2a 2f 0a 20 20 69 6e 74 28 2a 78 43 6f  or */.  int(*xCo
1d5c0 6e 66 6c 69 63 74 29 28 76 6f 69 64 20 2a 2c 20  nflict)(void *, 
1d5d0 69 6e 74 2c 20 73 71 6c 69 74 65 33 5f 63 68 61  int, sqlite3_cha
1d5e0 6e 67 65 73 65 74 5f 69 74 65 72 2a 29 2c 0a 20  ngeset_iter*),. 
1d5f0 20 76 6f 69 64 20 2a 70 43 74 78 2c 20 20 20 20   void *pCtx,    
1d600 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d610 20 2f 2a 20 46 69 72 73 74 20 61 72 67 75 6d 65   /* First argume
1d620 6e 74 20 66 6f 72 20 63 6f 6e 66 6c 69 63 74 20  nt for conflict 
1d630 68 61 6e 64 6c 65 72 20 2a 2f 0a 20 20 69 6e 74  handler */.  int
1d640 20 2a 70 62 52 65 70 6c 61 63 65 20 20 20 20 20   *pbReplace     
1d650 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1d660 4f 55 54 3a 20 53 65 74 20 74 6f 20 74 72 75 65  OUT: Set to true
1d670 20 69 66 20 50 4b 20 72 6f 77 20 69 73 20 66 6f   if PK row is fo
1d680 75 6e 64 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  und */.){.  int 
1d690 72 65 73 20 3d 20 30 3b 20 20 20 20 20 20 20 20  res = 0;        
1d6a0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56              /* V
1d6b0 61 6c 75 65 20 72 65 74 75 72 6e 65 64 20 62 79  alue returned by
1d6c0 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65   conflict handle
1d6d0 72 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 0a 20  r */.  int rc;. 
1d6e0 20 69 6e 74 20 6e 43 6f 6c 3b 0a 20 20 69 6e 74   int nCol;.  int
1d6f0 20 6f 70 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61   op;.  const cha
1d700 72 20 2a 7a 44 75 6d 6d 79 3b 0a 0a 20 20 73 71  r *zDummy;..  sq
1d710 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f  lite3changeset_o
1d720 70 28 70 49 74 65 72 2c 20 26 7a 44 75 6d 6d 79  p(pIter, &zDummy
1d730 2c 20 26 6e 43 6f 6c 2c 20 26 6f 70 2c 20 30 29  , &nCol, &op, 0)
1d740 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 65 54 79  ;..  assert( eTy
1d750 70 65 3d 3d 53 51 4c 49 54 45 5f 43 48 41 4e 47  pe==SQLITE_CHANG
1d760 45 53 45 54 5f 43 4f 4e 46 4c 49 43 54 20 7c 7c  ESET_CONFLICT ||
1d770 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 43   eType==SQLITE_C
1d780 48 41 4e 47 45 53 45 54 5f 44 41 54 41 20 29 3b  HANGESET_DATA );
1d790 0a 20 20 61 73 73 65 72 74 28 20 53 51 4c 49 54  .  assert( SQLIT
1d7a0 45 5f 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46  E_CHANGESET_CONF
1d7b0 4c 49 43 54 2b 31 3d 3d 53 51 4c 49 54 45 5f 43  LICT+1==SQLITE_C
1d7c0 48 41 4e 47 45 53 45 54 5f 43 4f 4e 53 54 52 41  HANGESET_CONSTRA
1d7d0 49 4e 54 20 29 3b 0a 20 20 61 73 73 65 72 74 28  INT );.  assert(
1d7e0 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45   SQLITE_CHANGESE
1d7f0 54 5f 44 41 54 41 2b 31 3d 3d 53 51 4c 49 54 45  T_DATA+1==SQLITE
1d800 5f 43 48 41 4e 47 45 53 45 54 5f 4e 4f 54 46 4f  _CHANGESET_NOTFO
1d810 55 4e 44 20 29 3b 0a 0a 20 20 2f 2a 20 42 69 6e  UND );..  /* Bin
1d820 64 20 74 68 65 20 6e 65 77 2e 2a 20 50 52 49 4d  d the new.* PRIM
1d830 41 52 59 20 4b 45 59 20 76 61 6c 75 65 73 20 74  ARY KEY values t
1d840 6f 20 74 68 65 20 53 45 4c 45 43 54 20 73 74 61  o the SELECT sta
1d850 74 65 6d 65 6e 74 2e 20 2a 2f 0a 20 20 69 66 28  tement. */.  if(
1d860 20 70 62 52 65 70 6c 61 63 65 20 29 7b 0a 20 20   pbReplace ){.  
1d870 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 53 65    rc = sessionSe
1d880 65 6b 54 6f 52 6f 77 28 70 2d 3e 64 62 2c 20 70  ekToRow(p->db, p
1d890 49 74 65 72 2c 20 70 2d 3e 61 62 50 4b 2c 20 70  Iter, p->abPK, p
1d8a0 2d 3e 70 53 65 6c 65 63 74 29 3b 0a 20 20 7d 65  ->pSelect);.  }e
1d8b0 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  lse{.    rc = SQ
1d8c0 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20  LITE_OK;.  }..  
1d8d0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52  if( rc==SQLITE_R
1d8e0 4f 57 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 65  OW ){.    /* The
1d8f0 72 65 20 65 78 69 73 74 73 20 61 6e 6f 74 68 65  re exists anothe
1d900 72 20 72 6f 77 20 77 69 74 68 20 74 68 65 20 6e  r row with the n
1d910 65 77 2e 2a 20 70 72 69 6d 61 72 79 20 6b 65 79  ew.* primary key
1d920 2e 20 2a 2f 0a 20 20 20 20 70 49 74 65 72 2d 3e  . */.    pIter->
1d930 70 43 6f 6e 66 6c 69 63 74 20 3d 20 70 2d 3e 70  pConflict = p->p
1d940 53 65 6c 65 63 74 3b 0a 20 20 20 20 72 65 73 20  Select;.    res 
1d950 3d 20 78 43 6f 6e 66 6c 69 63 74 28 70 43 74 78  = xConflict(pCtx
1d960 2c 20 65 54 79 70 65 2c 20 70 49 74 65 72 29 3b  , eType, pIter);
1d970 0a 20 20 20 20 70 49 74 65 72 2d 3e 70 43 6f 6e  .    pIter->pCon
1d980 66 6c 69 63 74 20 3d 20 30 3b 0a 20 20 20 20 72  flict = 0;.    r
1d990 63 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65  c = sqlite3_rese
1d9a0 74 28 70 2d 3e 70 53 65 6c 65 63 74 29 3b 0a 20  t(p->pSelect);. 
1d9b0 20 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d 53   }else if( rc==S
1d9c0 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
1d9d0 69 66 28 20 70 2d 3e 62 44 65 66 65 72 43 6f 6e  if( p->bDeferCon
1d9e0 73 74 72 61 69 6e 74 73 20 26 26 20 65 54 79 70  straints && eTyp
1d9f0 65 3d 3d 53 51 4c 49 54 45 5f 43 48 41 4e 47 45  e==SQLITE_CHANGE
1da00 53 45 54 5f 43 4f 4e 46 4c 49 43 54 20 29 7b 0a  SET_CONFLICT ){.
1da10 20 20 20 20 20 20 2f 2a 20 49 6e 73 74 65 61 64        /* Instead
1da20 20 6f 66 20 69 6e 76 6f 6b 69 6e 67 20 74 68 65   of invoking the
1da30 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65   conflict handle
1da40 72 2c 20 61 70 70 65 6e 64 20 74 68 65 20 63 68  r, append the ch
1da50 61 6e 67 65 20 62 6c 6f 62 0a 20 20 20 20 20 20  ange blob.      
1da60 2a 2a 20 74 6f 20 74 68 65 20 53 65 73 73 69 6f  ** to the Sessio
1da70 6e 41 70 70 6c 79 43 74 78 2e 63 6f 6e 73 74 72  nApplyCtx.constr
1da80 61 69 6e 74 73 20 62 75 66 66 65 72 2e 20 2a 2f  aints buffer. */
1da90 0a 20 20 20 20 20 20 75 38 20 2a 61 42 6c 6f 62  .      u8 *aBlob
1daa0 20 3d 20 26 70 49 74 65 72 2d 3e 69 6e 2e 61 44   = &pIter->in.aD
1dab0 61 74 61 5b 70 49 74 65 72 2d 3e 69 6e 2e 69 43  ata[pIter->in.iC
1dac0 75 72 72 65 6e 74 5d 3b 0a 20 20 20 20 20 20 69  urrent];.      i
1dad0 6e 74 20 6e 42 6c 6f 62 20 3d 20 70 49 74 65 72  nt nBlob = pIter
1dae0 2d 3e 69 6e 2e 69 4e 65 78 74 20 2d 20 70 49 74  ->in.iNext - pIt
1daf0 65 72 2d 3e 69 6e 2e 69 43 75 72 72 65 6e 74 3b  er->in.iCurrent;
1db00 0a 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70  .      sessionAp
1db10 70 65 6e 64 42 6c 6f 62 28 26 70 2d 3e 63 6f 6e  pendBlob(&p->con
1db20 73 74 72 61 69 6e 74 73 2c 20 61 42 6c 6f 62 2c  straints, aBlob,
1db30 20 6e 42 6c 6f 62 2c 20 26 72 63 29 3b 0a 20 20   nBlob, &rc);.  
1db40 20 20 20 20 72 65 73 20 3d 20 53 51 4c 49 54 45      res = SQLITE
1db50 5f 43 48 41 4e 47 45 53 45 54 5f 4f 4d 49 54 3b  _CHANGESET_OMIT;
1db60 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
1db70 20 20 2f 2a 20 4e 6f 20 6f 74 68 65 72 20 72 6f    /* No other ro
1db80 77 20 77 69 74 68 20 74 68 65 20 6e 65 77 2e 2a  w with the new.*
1db90 20 70 72 69 6d 61 72 79 20 6b 65 79 2e 20 2a 2f   primary key. */
1dba0 0a 20 20 20 20 20 20 72 65 73 20 3d 20 78 43 6f  .      res = xCo
1dbb0 6e 66 6c 69 63 74 28 70 43 74 78 2c 20 65 54 79  nflict(pCtx, eTy
1dbc0 70 65 2b 31 2c 20 70 49 74 65 72 29 3b 0a 20 20  pe+1, pIter);.  
1dbd0 20 20 20 20 69 66 28 20 72 65 73 3d 3d 53 51 4c      if( res==SQL
1dbe0 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 52 45  ITE_CHANGESET_RE
1dbf0 50 4c 41 43 45 20 29 20 72 63 20 3d 20 53 51 4c  PLACE ) rc = SQL
1dc00 49 54 45 5f 4d 49 53 55 53 45 3b 0a 20 20 20 20  ITE_MISUSE;.    
1dc10 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  }.  }..  if( rc=
1dc20 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
1dc30 20 20 73 77 69 74 63 68 28 20 72 65 73 20 29 7b    switch( res ){
1dc40 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
1dc50 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 52 45 50  TE_CHANGESET_REP
1dc60 4c 41 43 45 3a 0a 20 20 20 20 20 20 20 20 61 73  LACE:.        as
1dc70 73 65 72 74 28 20 70 62 52 65 70 6c 61 63 65 20  sert( pbReplace 
1dc80 29 3b 0a 20 20 20 20 20 20 20 20 2a 70 62 52 65  );.        *pbRe
1dc90 70 6c 61 63 65 20 3d 20 31 3b 0a 20 20 20 20 20  place = 1;.     
1dca0 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20     break;..     
1dcb0 20 63 61 73 65 20 53 51 4c 49 54 45 5f 43 48 41   case SQLITE_CHA
1dcc0 4e 47 45 53 45 54 5f 4f 4d 49 54 3a 0a 20 20 20  NGESET_OMIT:.   
1dcd0 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20       break;..   
1dce0 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 43     case SQLITE_C
1dcf0 48 41 4e 47 45 53 45 54 5f 41 42 4f 52 54 3a 0a  HANGESET_ABORT:.
1dd00 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
1dd10 49 54 45 5f 41 42 4f 52 54 3b 0a 20 20 20 20 20  ITE_ABORT;.     
1dd20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20     break;..     
1dd30 20 64 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20   default:.      
1dd40 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4d 49    rc = SQLITE_MI
1dd50 53 55 53 45 3b 0a 20 20 20 20 20 20 20 20 62 72  SUSE;.        br
1dd60 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  eak;.    }.  }..
1dd70 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
1dd80 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74 20 74 6f  /*.** Attempt to
1dd90 20 61 70 70 6c 79 20 74 68 65 20 63 68 61 6e 67   apply the chang
1dda0 65 20 74 68 61 74 20 74 68 65 20 69 74 65 72 61  e that the itera
1ddb0 74 6f 72 20 70 61 73 73 65 64 20 61 73 20 74 68  tor passed as th
1ddc0 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
1ddd0 0a 2a 2a 20 63 75 72 72 65 6e 74 6c 79 20 70 6f  .** currently po
1dde0 69 6e 74 73 20 74 6f 20 74 6f 20 74 68 65 20 64  ints to to the d
1ddf0 61 74 61 62 61 73 65 2e 20 49 66 20 61 20 63 6f  atabase. If a co
1de00 6e 66 6c 69 63 74 20 69 73 20 65 6e 63 6f 75 6e  nflict is encoun
1de10 74 65 72 65 64 2c 20 69 6e 76 6f 6b 65 0a 2a 2a  tered, invoke.**
1de20 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 20 68 61   the conflict ha
1de30 6e 64 6c 65 72 20 63 61 6c 6c 62 61 63 6b 2e 0a  ndler callback..
1de40 2a 2a 0a 2a 2a 20 49 66 20 61 72 67 75 6d 65 6e  **.** If argumen
1de50 74 20 70 62 52 65 74 72 79 20 69 73 20 4e 55 4c  t pbRetry is NUL
1de60 4c 2c 20 74 68 65 6e 20 69 67 6e 6f 72 65 20 61  L, then ignore a
1de70 6e 79 20 43 48 41 4e 47 45 53 45 54 5f 44 41 54  ny CHANGESET_DAT
1de80 41 20 63 6f 6e 66 6c 69 63 74 2e 20 49 66 0a 2a  A conflict. If.*
1de90 2a 20 6f 6e 65 20 69 73 20 65 6e 63 6f 75 6e 74  * one is encount
1dea0 65 72 65 64 2c 20 75 70 64 61 74 65 20 6f 72 20  ered, update or 
1deb0 64 65 6c 65 74 65 20 74 68 65 20 72 6f 77 20 77  delete the row w
1dec0 69 74 68 20 74 68 65 20 6d 61 74 63 68 69 6e 67  ith the matching
1ded0 20 70 72 69 6d 61 72 79 20 6b 65 79 0a 2a 2a 20   primary key.** 
1dee0 69 6e 73 74 65 61 64 2e 20 4f 72 2c 20 69 66 20  instead. Or, if 
1def0 70 62 52 65 74 72 79 20 69 73 20 6e 6f 74 20 4e  pbRetry is not N
1df00 55 4c 4c 20 61 6e 64 20 61 20 43 48 41 4e 47 45  ULL and a CHANGE
1df10 53 45 54 5f 44 41 54 41 20 63 6f 6e 66 6c 69 63  SET_DATA conflic
1df20 74 20 6f 63 63 75 72 73 2c 0a 2a 2a 20 69 6e 76  t occurs,.** inv
1df30 6f 6b 65 20 74 68 65 20 63 6f 6e 66 6c 69 63 74  oke the conflict
1df40 20 68 61 6e 64 6c 65 72 2e 20 49 66 20 69 74 20   handler. If it 
1df50 72 65 74 75 72 6e 73 20 43 48 41 4e 47 45 53 45  returns CHANGESE
1df60 54 5f 52 45 50 4c 41 43 45 2c 20 73 65 74 20 2a  T_REPLACE, set *
1df70 70 62 52 65 74 72 79 0a 2a 2a 20 74 6f 20 74 72  pbRetry.** to tr
1df80 75 65 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e  ue before return
1df90 69 6e 67 2e 20 49 6e 20 74 68 69 73 20 63 61 73  ing. In this cas
1dfa0 65 20 74 68 65 20 63 61 6c 6c 65 72 20 77 69 6c  e the caller wil
1dfb0 6c 20 69 6e 76 6f 6b 65 20 74 68 69 73 20 66 75  l invoke this fu
1dfc0 6e 63 74 69 6f 6e 0a 2a 2a 20 61 67 61 69 6e 2c  nction.** again,
1dfd0 20 74 68 69 73 20 74 69 6d 65 20 77 69 74 68 20   this time with 
1dfe0 70 62 52 65 74 72 79 20 73 65 74 20 74 6f 20 4e  pbRetry set to N
1dff0 55 4c 4c 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 72  ULL..**.** If ar
1e000 67 75 6d 65 6e 74 20 70 62 52 65 70 6c 61 63 65  gument pbReplace
1e010 20 69 73 20 4e 55 4c 4c 20 61 6e 64 20 61 20 43   is NULL and a C
1e020 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49 43  HANGESET_CONFLIC
1e030 54 20 63 6f 6e 66 6c 69 63 74 20 69 73 20 0a 2a  T conflict is .*
1e040 2a 20 65 6e 63 6f 75 6e 74 65 72 65 64 20 69 6e  * encountered in
1e050 76 6f 6b 65 20 74 68 65 20 63 6f 6e 66 6c 69 63  voke the conflic
1e060 74 20 68 61 6e 64 6c 65 72 20 77 69 74 68 20 43  t handler with C
1e070 48 41 4e 47 45 53 45 54 5f 43 4f 4e 53 54 52 41  HANGESET_CONSTRA
1e080 49 4e 54 20 69 6e 73 74 65 61 64 2e 0a 2a 2a 20  INT instead..** 
1e090 4f 72 2c 20 69 66 20 70 62 52 65 70 6c 61 63 65  Or, if pbReplace
1e0a0 20 69 73 20 6e 6f 74 20 4e 55 4c 4c 2c 20 69 6e   is not NULL, in
1e0b0 76 6f 6b 65 20 69 74 20 77 69 74 68 20 43 48 41  voke it with CHA
1e0c0 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49 43 54 2e  NGESET_CONFLICT.
1e0d0 20 49 66 20 73 75 63 68 0a 2a 2a 20 61 6e 20 69   If such.** an i
1e0e0 6e 76 6f 63 61 74 69 6f 6e 20 72 65 74 75 72 6e  nvocation return
1e0f0 73 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53  s SQLITE_CHANGES
1e100 45 54 5f 52 45 50 4c 41 43 45 2c 20 73 65 74 20  ET_REPLACE, set 
1e110 2a 70 62 52 65 70 6c 61 63 65 20 74 6f 20 74 72  *pbReplace to tr
1e120 75 65 0a 2a 2a 20 62 65 66 6f 72 65 20 72 65 74  ue.** before ret
1e130 72 79 69 6e 67 2e 20 49 6e 20 74 68 69 73 20 63  rying. In this c
1e140 61 73 65 20 74 68 65 20 63 61 6c 6c 65 72 20 61  ase the caller a
1e150 74 74 65 6d 70 74 73 20 74 6f 20 72 65 6d 6f 76  ttempts to remov
1e160 65 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 69 6e  e the conflictin
1e170 67 0a 2a 2a 20 72 6f 77 20 62 65 66 6f 72 65 20  g.** row before 
1e180 69 6e 76 6f 6b 69 6e 67 20 74 68 69 73 20 66 75  invoking this fu
1e190 6e 63 74 69 6f 6e 20 61 67 61 69 6e 2c 20 74 68  nction again, th
1e1a0 69 73 20 74 69 6d 65 20 77 69 74 68 20 70 62 52  is time with pbR
1e1b0 65 70 6c 61 63 65 20 73 65 74 20 0a 2a 2a 20 74  eplace set .** t
1e1c0 6f 20 4e 55 4c 4c 2e 0a 2a 2a 0a 2a 2a 20 49 66  o NULL..**.** If
1e1d0 20 61 6e 79 20 63 6f 6e 66 6c 69 63 74 20 68 61   any conflict ha
1e1e0 6e 64 6c 65 72 20 72 65 74 75 72 6e 73 20 53 51  ndler returns SQ
1e1f0 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 41  LITE_CHANGESET_A
1e200 42 4f 52 54 2c 20 74 68 69 73 20 66 75 6e 63 74  BORT, this funct
1e210 69 6f 6e 0a 2a 2a 20 72 65 74 75 72 6e 73 20 53  ion.** returns S
1e220 51 4c 49 54 45 5f 41 42 4f 52 54 2e 20 4f 74 68  QLITE_ABORT. Oth
1e230 65 72 77 69 73 65 2c 20 69 66 20 6e 6f 20 65 72  erwise, if no er
1e240 72 6f 72 20 6f 63 63 75 72 73 2c 20 53 51 4c 49  ror occurs, SQLI
1e250 54 45 5f 4f 4b 20 69 73 20 0a 2a 2a 20 72 65 74  TE_OK is .** ret
1e260 75 72 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  urned..*/.static
1e270 20 69 6e 74 20 73 65 73 73 69 6f 6e 41 70 70 6c   int sessionAppl
1e280 79 4f 6e 65 4f 70 28 0a 20 20 73 71 6c 69 74 65  yOneOp(.  sqlite
1e290 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72  3_changeset_iter
1e2a0 20 2a 70 49 74 65 72 2c 20 20 2f 2a 20 43 68 61   *pIter,  /* Cha
1e2b0 6e 67 65 73 65 74 20 69 74 65 72 61 74 6f 72 20  ngeset iterator 
1e2c0 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 41 70 70 6c  */.  SessionAppl
1e2d0 79 43 74 78 20 2a 70 2c 20 20 20 20 20 20 20 20  yCtx *p,        
1e2e0 20 20 20 20 20 2f 2a 20 63 68 61 6e 67 65 73 65       /* changese
1e2f0 74 5f 61 70 70 6c 79 28 29 20 63 6f 6e 74 65 78  t_apply() contex
1e300 74 20 2a 2f 0a 20 20 69 6e 74 28 2a 78 43 6f 6e  t */.  int(*xCon
1e310 66 6c 69 63 74 29 28 76 6f 69 64 20 2a 2c 20 69  flict)(void *, i
1e320 6e 74 2c 20 73 71 6c 69 74 65 33 5f 63 68 61 6e  nt, sqlite3_chan
1e330 67 65 73 65 74 5f 69 74 65 72 20 2a 29 2c 0a 20  geset_iter *),. 
1e340 20 76 6f 69 64 20 2a 70 43 74 78 2c 20 20 20 20   void *pCtx,    
1e350 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e360 20 2f 2a 20 46 69 72 73 74 20 61 72 67 75 6d 65   /* First argume
1e370 6e 74 20 66 6f 72 20 74 68 65 20 63 6f 6e 66 6c  nt for the confl
1e380 69 63 74 20 68 61 6e 64 6c 65 72 20 2a 2f 0a 20  ict handler */. 
1e390 20 69 6e 74 20 2a 70 62 52 65 70 6c 61 63 65 2c   int *pbReplace,
1e3a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e3b0 20 2f 2a 20 4f 55 54 3a 20 54 72 75 65 20 74 6f   /* OUT: True to
1e3c0 20 72 65 6d 6f 76 65 20 50 4b 20 72 6f 77 20 61   remove PK row a
1e3d0 6e 64 20 72 65 74 72 79 20 2a 2f 0a 20 20 69 6e  nd retry */.  in
1e3e0 74 20 2a 70 62 52 65 74 72 79 20 20 20 20 20 20  t *pbRetry      
1e3f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1e400 20 4f 55 54 3a 20 54 72 75 65 20 74 6f 20 72 65   OUT: True to re
1e410 74 72 79 2e 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e  try. */.){.  con
1e420 73 74 20 63 68 61 72 20 2a 7a 44 75 6d 6d 79 3b  st char *zDummy;
1e430 0a 20 20 69 6e 74 20 6f 70 3b 0a 20 20 69 6e 74  .  int op;.  int
1e440 20 6e 43 6f 6c 3b 0a 20 20 69 6e 74 20 72 63 20   nCol;.  int rc 
1e450 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20  = SQLITE_OK;..  
1e460 61 73 73 65 72 74 28 20 70 2d 3e 70 44 65 6c 65  assert( p->pDele
1e470 74 65 20 26 26 20 70 2d 3e 70 55 70 64 61 74 65  te && p->pUpdate
1e480 20 26 26 20 70 2d 3e 70 49 6e 73 65 72 74 20 26   && p->pInsert &
1e490 26 20 70 2d 3e 70 53 65 6c 65 63 74 20 29 3b 0a  & p->pSelect );.
1e4a0 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61 7a 43    assert( p->azC
1e4b0 6f 6c 20 26 26 20 70 2d 3e 61 62 50 4b 20 29 3b  ol && p->abPK );
1e4c0 0a 20 20 61 73 73 65 72 74 28 20 21 70 62 52 65  .  assert( !pbRe
1e4d0 70 6c 61 63 65 20 7c 7c 20 2a 70 62 52 65 70 6c  place || *pbRepl
1e4e0 61 63 65 3d 3d 30 20 29 3b 0a 0a 20 20 73 71 6c  ace==0 );..  sql
1e4f0 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f 70  ite3changeset_op
1e500 28 70 49 74 65 72 2c 20 26 7a 44 75 6d 6d 79 2c  (pIter, &zDummy,
1e510 20 26 6e 43 6f 6c 2c 20 26 6f 70 2c 20 30 29 3b   &nCol, &op, 0);
1e520 0a 0a 20 20 69 66 28 20 6f 70 3d 3d 53 51 4c 49  ..  if( op==SQLI
1e530 54 45 5f 44 45 4c 45 54 45 20 29 7b 0a 0a 20 20  TE_DELETE ){..  
1e540 20 20 2f 2a 20 42 69 6e 64 20 76 61 6c 75 65 73    /* Bind values
1e550 20 74 6f 20 74 68 65 20 44 45 4c 45 54 45 20 73   to the DELETE s
1e560 74 61 74 65 6d 65 6e 74 2e 20 49 66 20 63 6f 6e  tatement. If con
1e570 66 6c 69 63 74 20 68 61 6e 64 6c 69 6e 67 20 69  flict handling i
1e580 73 20 72 65 71 75 69 72 65 64 2c 0a 20 20 20 20  s required,.    
1e590 2a 2a 20 62 69 6e 64 20 76 61 6c 75 65 73 20 66  ** bind values f
1e5a0 6f 72 20 61 6c 6c 20 63 6f 6c 75 6d 6e 73 20 61  or all columns a
1e5b0 6e 64 20 73 65 74 20 62 6f 75 6e 64 20 76 61 72  nd set bound var
1e5c0 69 61 62 6c 65 20 28 6e 43 6f 6c 2b 31 29 20 74  iable (nCol+1) t
1e5d0 6f 20 74 72 75 65 2e 0a 20 20 20 20 2a 2a 20 4f  o true..    ** O
1e5e0 72 2c 20 69 66 20 63 6f 6e 66 6c 69 63 74 20 68  r, if conflict h
1e5f0 61 6e 64 6c 69 6e 67 20 69 73 20 6e 6f 74 20 72  andling is not r
1e600 65 71 75 69 72 65 64 2c 20 62 69 6e 64 20 6a 75  equired, bind ju
1e610 73 74 20 74 68 65 20 50 4b 20 63 6f 6c 75 6d 6e  st the PK column
1e620 0a 20 20 20 20 2a 2a 20 76 61 6c 75 65 73 20 61  .    ** values a
1e630 6e 64 2c 20 69 66 20 69 74 20 65 78 69 73 74 73  nd, if it exists
1e640 2c 20 73 65 74 20 28 6e 43 6f 6c 2b 31 29 20 74  , set (nCol+1) t
1e650 6f 20 66 61 6c 73 65 2e 20 43 6f 6e 66 6c 69 63  o false. Conflic
1e660 74 20 68 61 6e 64 6c 69 6e 67 0a 20 20 20 20 2a  t handling.    *
1e670 2a 20 69 73 20 6e 6f 74 20 72 65 71 75 69 72 65  * is not require
1e680 64 20 69 66 3a 0a 20 20 20 20 2a 2a 0a 20 20 20  d if:.    **.   
1e690 20 2a 2a 20 20 20 2a 20 74 68 69 73 20 69 73 20   **   * this is 
1e6a0 61 20 70 61 74 63 68 73 65 74 2c 20 6f 72 0a 20  a patchset, or. 
1e6b0 20 20 20 2a 2a 20 20 20 2a 20 28 70 62 52 65 74     **   * (pbRet
1e6c0 72 79 3d 3d 30 29 2c 20 6f 72 0a 20 20 20 20 2a  ry==0), or.    *
1e6d0 2a 20 20 20 2a 20 61 6c 6c 20 63 6f 6c 75 6d 6e  *   * all column
1e6e0 73 20 6f 66 20 74 68 65 20 74 61 62 6c 65 20 61  s of the table a
1e6f0 72 65 20 50 4b 20 63 6f 6c 75 6d 6e 73 20 28 69  re PK columns (i
1e700 6e 20 74 68 69 73 20 63 61 73 65 20 74 68 65 72  n this case ther
1e710 65 20 69 73 0a 20 20 20 20 2a 2a 20 20 20 20 20  e is.    **     
1e720 6e 6f 20 28 6e 43 6f 6c 2b 31 29 20 76 61 72 69  no (nCol+1) vari
1e730 61 62 6c 65 20 74 6f 20 62 69 6e 64 20 74 6f 29  able to bind to)
1e740 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 75 38 20  ..    */.    u8 
1e750 2a 61 62 50 4b 20 3d 20 28 70 49 74 65 72 2d 3e  *abPK = (pIter->
1e760 62 50 61 74 63 68 73 65 74 20 3f 20 70 2d 3e 61  bPatchset ? p->a
1e770 62 50 4b 20 3a 20 30 29 3b 0a 20 20 20 20 72 63  bPK : 0);.    rc
1e780 20 3d 20 73 65 73 73 69 6f 6e 42 69 6e 64 52 6f   = sessionBindRo
1e790 77 28 70 49 74 65 72 2c 20 73 71 6c 69 74 65 33  w(pIter, sqlite3
1e7a0 63 68 61 6e 67 65 73 65 74 5f 6f 6c 64 2c 20 6e  changeset_old, n
1e7b0 43 6f 6c 2c 20 61 62 50 4b 2c 20 70 2d 3e 70 44  Col, abPK, p->pD
1e7c0 65 6c 65 74 65 29 3b 0a 20 20 20 20 69 66 28 20  elete);.    if( 
1e7d0 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
1e7e0 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 70 61   sqlite3_bind_pa
1e7f0 72 61 6d 65 74 65 72 5f 63 6f 75 6e 74 28 70 2d  rameter_count(p-
1e800 3e 70 44 65 6c 65 74 65 29 3e 6e 43 6f 6c 20 29  >pDelete)>nCol )
1e810 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  {.      rc = sql
1e820 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 28 70 2d  ite3_bind_int(p-
1e830 3e 70 44 65 6c 65 74 65 2c 20 6e 43 6f 6c 2b 31  >pDelete, nCol+1
1e840 2c 20 28 70 62 52 65 74 72 79 3d 3d 30 20 7c 7c  , (pbRetry==0 ||
1e850 20 61 62 50 4b 29 29 3b 0a 20 20 20 20 7d 0a 20   abPK));.    }. 
1e860 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
1e870 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  E_OK ) return rc
1e880 3b 0a 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73  ;..    sqlite3_s
1e890 74 65 70 28 70 2d 3e 70 44 65 6c 65 74 65 29 3b  tep(p->pDelete);
1e8a0 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
1e8b0 33 5f 72 65 73 65 74 28 70 2d 3e 70 44 65 6c 65  3_reset(p->pDele
1e8c0 74 65 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d  te);.    if( rc=
1e8d0 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 73 71  =SQLITE_OK && sq
1e8e0 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 28 70 2d  lite3_changes(p-
1e8f0 3e 64 62 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  >db)==0 ){.     
1e900 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 43 6f 6e   rc = sessionCon
1e910 66 6c 69 63 74 48 61 6e 64 6c 65 72 28 0a 20 20  flictHandler(.  
1e920 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 43          SQLITE_C
1e930 48 41 4e 47 45 53 45 54 5f 44 41 54 41 2c 20 70  HANGESET_DATA, p
1e940 2c 20 70 49 74 65 72 2c 20 78 43 6f 6e 66 6c 69  , pIter, xConfli
1e950 63 74 2c 20 70 43 74 78 2c 20 70 62 52 65 74 72  ct, pCtx, pbRetr
1e960 79 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d  y.      );.    }
1e970 65 6c 73 65 20 69 66 28 20 28 72 63 26 30 78 66  else if( (rc&0xf
1e980 66 29 3d 3d 53 51 4c 49 54 45 5f 43 4f 4e 53 54  f)==SQLITE_CONST
1e990 52 41 49 4e 54 20 29 7b 0a 20 20 20 20 20 20 72  RAINT ){.      r
1e9a0 63 20 3d 20 73 65 73 73 69 6f 6e 43 6f 6e 66 6c  c = sessionConfl
1e9b0 69 63 74 48 61 6e 64 6c 65 72 28 0a 20 20 20 20  ictHandler(.    
1e9c0 20 20 20 20 20 20 53 51 4c 49 54 45 5f 43 48 41        SQLITE_CHA
1e9d0 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49 43 54 2c  NGESET_CONFLICT,
1e9e0 20 70 2c 20 70 49 74 65 72 2c 20 78 43 6f 6e 66   p, pIter, xConf
1e9f0 6c 69 63 74 2c 20 70 43 74 78 2c 20 30 0a 20 20  lict, pCtx, 0.  
1ea00 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 0a 20 20      );.    }..  
1ea10 7d 65 6c 73 65 20 69 66 28 20 6f 70 3d 3d 53 51  }else if( op==SQ
1ea20 4c 49 54 45 5f 55 50 44 41 54 45 20 29 7b 0a 20  LITE_UPDATE ){. 
1ea30 20 20 20 69 6e 74 20 69 3b 0a 0a 20 20 20 20 2f     int i;..    /
1ea40 2a 20 42 69 6e 64 20 76 61 6c 75 65 73 20 74 6f  * Bind values to
1ea50 20 74 68 65 20 55 50 44 41 54 45 20 73 74 61 74   the UPDATE stat
1ea60 65 6d 65 6e 74 2e 20 2a 2f 0a 20 20 20 20 66 6f  ement. */.    fo
1ea70 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54  r(i=0; rc==SQLIT
1ea80 45 5f 4f 4b 20 26 26 20 69 3c 6e 43 6f 6c 3b 20  E_OK && i<nCol; 
1ea90 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73 71 6c 69  i++){.      sqli
1eaa0 74 65 33 5f 76 61 6c 75 65 20 2a 70 4f 6c 64 20  te3_value *pOld 
1eab0 3d 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73  = sessionChanges
1eac0 65 74 4f 6c 64 28 70 49 74 65 72 2c 20 69 29 3b  etOld(pIter, i);
1ead0 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76  .      sqlite3_v
1eae0 61 6c 75 65 20 2a 70 4e 65 77 20 3d 20 73 65 73  alue *pNew = ses
1eaf0 73 69 6f 6e 43 68 61 6e 67 65 73 65 74 4e 65 77  sionChangesetNew
1eb00 28 70 49 74 65 72 2c 20 69 29 3b 0a 0a 20 20 20  (pIter, i);..   
1eb10 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f     sqlite3_bind_
1eb20 69 6e 74 28 70 2d 3e 70 55 70 64 61 74 65 2c 20  int(p->pUpdate, 
1eb30 69 2a 33 2b 32 2c 20 21 21 70 4e 65 77 29 3b 0a  i*3+2, !!pNew);.
1eb40 20 20 20 20 20 20 69 66 28 20 70 4f 6c 64 20 29        if( pOld )
1eb50 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73  {.        rc = s
1eb60 65 73 73 69 6f 6e 42 69 6e 64 56 61 6c 75 65 28  essionBindValue(
1eb70 70 2d 3e 70 55 70 64 61 74 65 2c 20 69 2a 33 2b  p->pUpdate, i*3+
1eb80 31 2c 20 70 4f 6c 64 29 3b 0a 20 20 20 20 20 20  1, pOld);.      
1eb90 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  }.      if( rc==
1eba0 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 4e 65  SQLITE_OK && pNe
1ebb0 77 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  w ){.        rc 
1ebc0 3d 20 73 65 73 73 69 6f 6e 42 69 6e 64 56 61 6c  = sessionBindVal
1ebd0 75 65 28 70 2d 3e 70 55 70 64 61 74 65 2c 20 69  ue(p->pUpdate, i
1ebe0 2a 33 2b 33 2c 20 70 4e 65 77 29 3b 0a 20 20 20  *3+3, pNew);.   
1ebf0 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69     }.    }.    i
1ec00 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
1ec10 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   ){.      sqlite
1ec20 33 5f 62 69 6e 64 5f 69 6e 74 28 70 2d 3e 70 55  3_bind_int(p->pU
1ec30 70 64 61 74 65 2c 20 6e 43 6f 6c 2a 33 2b 31 2c  pdate, nCol*3+1,
1ec40 20 70 62 52 65 74 72 79 3d 3d 30 20 7c 7c 20 70   pbRetry==0 || p
1ec50 49 74 65 72 2d 3e 62 50 61 74 63 68 73 65 74 29  Iter->bPatchset)
1ec60 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
1ec70 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
1ec80 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20 20  return rc;..    
1ec90 2f 2a 20 41 74 74 65 6d 70 74 20 74 68 65 20 55  /* Attempt the U
1eca0 50 44 41 54 45 2e 20 49 6e 20 74 68 65 20 63 61  PDATE. In the ca
1ecb0 73 65 20 6f 66 20 61 20 4e 4f 54 46 4f 55 4e 44  se of a NOTFOUND
1ecc0 20 6f 72 20 44 41 54 41 20 63 6f 6e 66 6c 69 63   or DATA conflic
1ecd0 74 2c 0a 20 20 20 20 2a 2a 20 74 68 65 20 72 65  t,.    ** the re
1ece0 73 75 6c 74 20 77 69 6c 6c 20 62 65 20 53 51 4c  sult will be SQL
1ecf0 49 54 45 5f 4f 4b 20 77 69 74 68 20 30 20 72 6f  ITE_OK with 0 ro
1ed00 77 73 20 6d 6f 64 69 66 69 65 64 2e 20 2a 2f 0a  ws modified. */.
1ed10 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 65 70      sqlite3_step
1ed20 28 70 2d 3e 70 55 70 64 61 74 65 29 3b 0a 20 20  (p->pUpdate);.  
1ed30 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 72    rc = sqlite3_r
1ed40 65 73 65 74 28 70 2d 3e 70 55 70 64 61 74 65 29  eset(p->pUpdate)
1ed50 3b 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  ;..    if( rc==S
1ed60 51 4c 49 54 45 5f 4f 4b 20 26 26 20 73 71 6c 69  QLITE_OK && sqli
1ed70 74 65 33 5f 63 68 61 6e 67 65 73 28 70 2d 3e 64  te3_changes(p->d
1ed80 62 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 2f  b)==0 ){.      /
1ed90 2a 20 41 20 4e 4f 54 46 4f 55 4e 44 20 6f 72 20  * A NOTFOUND or 
1eda0 44 41 54 41 20 65 72 72 6f 72 2e 20 53 65 61 72  DATA error. Sear
1edb0 63 68 20 74 68 65 20 74 61 62 6c 65 20 74 6f 20  ch the table to 
1edc0 73 65 65 20 69 66 20 69 74 20 63 6f 6e 74 61 69  see if it contai
1edd0 6e 73 0a 20 20 20 20 20 20 2a 2a 20 61 20 72 6f  ns.      ** a ro
1ede0 77 20 77 69 74 68 20 61 20 6d 61 74 63 68 69 6e  w with a matchin
1edf0 67 20 70 72 69 6d 61 72 79 20 6b 65 79 2e 20 49  g primary key. I
1ee00 66 20 73 6f 2c 20 74 68 69 73 20 69 73 20 61 20  f so, this is a 
1ee10 44 41 54 41 20 63 6f 6e 66 6c 69 63 74 2e 0a 20  DATA conflict.. 
1ee20 20 20 20 20 20 2a 2a 20 4f 74 68 65 72 77 69 73       ** Otherwis
1ee30 65 2c 20 69 66 20 74 68 65 72 65 20 69 73 20 6e  e, if there is n
1ee40 6f 20 70 72 69 6d 61 72 79 20 6b 65 79 20 6d 61  o primary key ma
1ee50 74 63 68 2c 20 69 74 20 69 73 20 61 20 4e 4f 54  tch, it is a NOT
1ee60 46 4f 55 4e 44 2e 20 2a 2f 0a 0a 20 20 20 20 20  FOUND. */..     
1ee70 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 43 6f 6e   rc = sessionCon
1ee80 66 6c 69 63 74 48 61 6e 64 6c 65 72 28 0a 20 20  flictHandler(.  
1ee90 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 43          SQLITE_C
1eea0 48 41 4e 47 45 53 45 54 5f 44 41 54 41 2c 20 70  HANGESET_DATA, p
1eeb0 2c 20 70 49 74 65 72 2c 20 78 43 6f 6e 66 6c 69  , pIter, xConfli
1eec0 63 74 2c 20 70 43 74 78 2c 20 70 62 52 65 74 72  ct, pCtx, pbRetr
1eed0 79 0a 20 20 20 20 20 20 29 3b 0a 0a 20 20 20 20  y.      );..    
1eee0 7d 65 6c 73 65 20 69 66 28 20 28 72 63 26 30 78  }else if( (rc&0x
1eef0 66 66 29 3d 3d 53 51 4c 49 54 45 5f 43 4f 4e 53  ff)==SQLITE_CONS
1ef00 54 52 41 49 4e 54 20 29 7b 0a 20 20 20 20 20 20  TRAINT ){.      
1ef10 2f 2a 20 54 68 69 73 20 69 73 20 61 6c 77 61 79  /* This is alway
1ef20 73 20 61 20 43 4f 4e 53 54 52 41 49 4e 54 20 63  s a CONSTRAINT c
1ef30 6f 6e 66 6c 69 63 74 2e 20 2a 2f 0a 20 20 20 20  onflict. */.    
1ef40 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 43 6f    rc = sessionCo
1ef50 6e 66 6c 69 63 74 48 61 6e 64 6c 65 72 28 0a 20  nflictHandler(. 
1ef60 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
1ef70 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49  CHANGESET_CONFLI
1ef80 43 54 2c 20 70 2c 20 70 49 74 65 72 2c 20 78 43  CT, p, pIter, xC
1ef90 6f 6e 66 6c 69 63 74 2c 20 70 43 74 78 2c 20 30  onflict, pCtx, 0
1efa0 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a  .      );.    }.
1efb0 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73  .  }else{.    as
1efc0 73 65 72 74 28 20 6f 70 3d 3d 53 51 4c 49 54 45  sert( op==SQLITE
1efd0 5f 49 4e 53 45 52 54 20 29 3b 0a 20 20 20 20 72  _INSERT );.    r
1efe0 63 20 3d 20 73 65 73 73 69 6f 6e 42 69 6e 64 52  c = sessionBindR
1eff0 6f 77 28 70 49 74 65 72 2c 20 73 71 6c 69 74 65  ow(pIter, sqlite
1f000 33 63 68 61 6e 67 65 73 65 74 5f 6e 65 77 2c 20  3changeset_new, 
1f010 6e 43 6f 6c 2c 20 30 2c 20 70 2d 3e 70 49 6e 73  nCol, 0, p->pIns
1f020 65 72 74 29 3b 0a 20 20 20 20 69 66 28 20 72 63  ert);.    if( rc
1f030 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
1f040 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20 20 73 71  turn rc;..    sq
1f050 6c 69 74 65 33 5f 73 74 65 70 28 70 2d 3e 70 49  lite3_step(p->pI
1f060 6e 73 65 72 74 29 3b 0a 20 20 20 20 72 63 20 3d  nsert);.    rc =
1f070 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70   sqlite3_reset(p
1f080 2d 3e 70 49 6e 73 65 72 74 29 3b 0a 20 20 20 20  ->pInsert);.    
1f090 69 66 28 20 28 72 63 26 30 78 66 66 29 3d 3d 53  if( (rc&0xff)==S
1f0a0 51 4c 49 54 45 5f 43 4f 4e 53 54 52 41 49 4e 54  QLITE_CONSTRAINT
1f0b0 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73   ){.      rc = s
1f0c0 65 73 73 69 6f 6e 43 6f 6e 66 6c 69 63 74 48 61  essionConflictHa
1f0d0 6e 64 6c 65 72 28 0a 20 20 20 20 20 20 20 20 20  ndler(.         
1f0e0 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45   SQLITE_CHANGESE
1f0f0 54 5f 43 4f 4e 46 4c 49 43 54 2c 20 70 2c 20 70  T_CONFLICT, p, p
1f100 49 74 65 72 2c 20 78 43 6f 6e 66 6c 69 63 74 2c  Iter, xConflict,
1f110 20 70 43 74 78 2c 20 70 62 52 65 70 6c 61 63 65   pCtx, pbReplace
1f120 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a  .      );.    }.
1f130 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
1f140 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d  ;.}../*.** Attem
1f150 70 74 20 74 6f 20 61 70 70 6c 79 20 74 68 65 20  pt to apply the 
1f160 63 68 61 6e 67 65 20 74 68 61 74 20 74 68 65 20  change that the 
1f170 69 74 65 72 61 74 6f 72 20 70 61 73 73 65 64 20  iterator passed 
1f180 61 73 20 74 68 65 20 66 69 72 73 74 20 61 72 67  as the first arg
1f190 75 6d 65 6e 74 0a 2a 2a 20 63 75 72 72 65 6e 74  ument.** current
1f1a0 6c 79 20 70 6f 69 6e 74 73 20 74 6f 20 74 6f 20  ly points to to 
1f1b0 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 49 66  the database. If
1f1c0 20 61 20 63 6f 6e 66 6c 69 63 74 20 69 73 20 65   a conflict is e
1f1d0 6e 63 6f 75 6e 74 65 72 65 64 2c 20 69 6e 76 6f  ncountered, invo
1f1e0 6b 65 0a 2a 2a 20 74 68 65 20 63 6f 6e 66 6c 69  ke.** the confli
1f1f0 63 74 20 68 61 6e 64 6c 65 72 20 63 61 6c 6c 62  ct handler callb
1f200 61 63 6b 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 64  ack..**.** The d
1f210 69 66 66 65 72 65 6e 63 65 20 62 65 74 77 65 65  ifference betwee
1f220 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
1f230 61 6e 64 20 73 65 73 73 69 6f 6e 41 70 70 6c 79  and sessionApply
1f240 4f 6e 65 28 29 20 69 73 20 74 68 61 74 20 74 68  One() is that th
1f250 69 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 68  is.** function h
1f260 61 6e 64 6c 65 73 20 74 68 65 20 63 61 73 65 20  andles the case 
1f270 77 68 65 72 65 20 74 68 65 20 63 6f 6e 66 6c 69  where the confli
1f280 63 74 2d 68 61 6e 64 6c 65 72 20 69 73 20 69 6e  ct-handler is in
1f290 76 6f 6b 65 64 20 61 6e 64 20 0a 2a 2a 20 72 65  voked and .** re
1f2a0 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 43 48 41  turns SQLITE_CHA
1f2b0 4e 47 45 53 45 54 5f 52 45 50 4c 41 43 45 20 2d  NGESET_REPLACE -
1f2c0 20 69 6e 64 69 63 61 74 69 6e 67 20 74 68 61 74   indicating that
1f2d0 20 74 68 65 20 63 68 61 6e 67 65 20 73 68 6f 75   the change shou
1f2e0 6c 64 20 62 65 0a 2a 2a 20 72 65 74 72 69 65 64  ld be.** retried
1f2f0 20 69 6e 20 73 6f 6d 65 20 6d 61 6e 6e 65 72 2e   in some manner.
1f300 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73  .*/.static int s
1f310 65 73 73 69 6f 6e 41 70 70 6c 79 4f 6e 65 57 69  essionApplyOneWi
1f320 74 68 52 65 74 72 79 28 0a 20 20 73 71 6c 69 74  thRetry(.  sqlit
1f330 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20  e3 *db,         
1f340 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 70             /* Ap
1f350 70 6c 79 20 63 68 61 6e 67 65 20 74 6f 20 22 6d  ply change to "m
1f360 61 69 6e 22 20 64 62 20 6f 66 20 74 68 69 73 20  ain" db of this 
1f370 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 73 71 6c 69  handle */.  sqli
1f380 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74  te3_changeset_it
1f390 65 72 20 2a 70 49 74 65 72 2c 20 20 2f 2a 20 43  er *pIter,  /* C
1f3a0 68 61 6e 67 65 73 65 74 20 69 74 65 72 61 74 6f  hangeset iterato
1f3b0 72 20 74 6f 20 72 65 61 64 20 63 68 61 6e 67 65  r to read change
1f3c0 20 66 72 6f 6d 20 2a 2f 0a 20 20 53 65 73 73 69   from */.  Sessi
1f3d0 6f 6e 41 70 70 6c 79 43 74 78 20 2a 70 41 70 70  onApplyCtx *pApp
1f3e0 6c 79 2c 20 20 20 20 20 20 20 20 2f 2a 20 41 70  ly,        /* Ap
1f3f0 70 6c 79 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20  ply context */. 
1f400 20 69 6e 74 28 2a 78 43 6f 6e 66 6c 69 63 74 29   int(*xConflict)
1f410 28 76 6f 69 64 2a 2c 20 69 6e 74 2c 20 73 71 6c  (void*, int, sql
1f420 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69  ite3_changeset_i
1f430 74 65 72 2a 29 2c 0a 20 20 76 6f 69 64 20 2a 70  ter*),.  void *p
1f440 43 74 78 20 20 20 20 20 20 20 20 20 20 20 20 20  Ctx             
1f450 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73           /* Firs
1f460 74 20 61 72 67 75 6d 65 6e 74 20 70 61 73 73 65  t argument passe
1f470 64 20 74 6f 20 78 43 6f 6e 66 6c 69 63 74 20 2a  d to xConflict *
1f480 2f 0a 29 7b 0a 20 20 69 6e 74 20 62 52 65 70 6c  /.){.  int bRepl
1f490 61 63 65 20 3d 20 30 3b 0a 20 20 69 6e 74 20 62  ace = 0;.  int b
1f4a0 52 65 74 72 79 20 3d 20 30 3b 0a 20 20 69 6e 74  Retry = 0;.  int
1f4b0 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73 65 73   rc;..  rc = ses
1f4c0 73 69 6f 6e 41 70 70 6c 79 4f 6e 65 4f 70 28 70  sionApplyOneOp(p
1f4d0 49 74 65 72 2c 20 70 41 70 70 6c 79 2c 20 78 43  Iter, pApply, xC
1f4e0 6f 6e 66 6c 69 63 74 2c 20 70 43 74 78 2c 20 26  onflict, pCtx, &
1f4f0 62 52 65 70 6c 61 63 65 2c 20 26 62 52 65 74 72  bReplace, &bRetr
1f500 79 29 3b 0a 20 20 61 73 73 65 72 74 28 20 72 63  y);.  assert( rc
1f510 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 28  ==SQLITE_OK || (
1f520 62 52 65 74 72 79 3d 3d 30 20 26 26 20 62 52 65  bRetry==0 && bRe
1f530 70 6c 61 63 65 3d 3d 30 29 20 29 3b 0a 0a 20 20  place==0) );..  
1f540 2f 2a 20 49 66 20 74 68 65 20 62 52 65 74 72 79  /* If the bRetry
1f550 20 66 6c 61 67 20 69 73 20 73 65 74 2c 20 74 68   flag is set, th
1f560 65 20 63 68 61 6e 67 65 20 68 61 73 20 6e 6f 74  e change has not
1f570 20 62 65 65 6e 20 61 70 70 6c 69 65 64 20 64 75   been applied du
1f580 65 20 74 6f 20 61 6e 0a 20 20 2a 2a 20 53 51 4c  e to an.  ** SQL
1f590 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 44 41  ITE_CHANGESET_DA
1f5a0 54 41 20 70 72 6f 62 6c 65 6d 20 28 69 2e 65 2e  TA problem (i.e.
1f5b0 20 74 68 69 73 20 69 73 20 61 6e 20 55 50 44 41   this is an UPDA
1f5c0 54 45 20 6f 72 20 44 45 4c 45 54 45 20 61 6e 64  TE or DELETE and
1f5d0 0a 20 20 2a 2a 20 61 20 72 6f 77 20 77 69 74 68  .  ** a row with
1f5e0 20 74 68 65 20 63 6f 72 72 65 63 74 20 50 4b 20   the correct PK 
1f5f0 69 73 20 70 72 65 73 65 6e 74 20 69 6e 20 74 68  is present in th
1f600 65 20 64 62 2c 20 62 75 74 20 6f 6e 65 20 6f 72  e db, but one or
1f610 20 6d 6f 72 65 20 6f 74 68 65 72 0a 20 20 2a 2a   more other.  **
1f620 20 66 69 65 6c 64 73 20 64 6f 20 6e 6f 74 20 63   fields do not c
1f630 6f 6e 74 61 69 6e 20 74 68 65 20 65 78 70 65 63  ontain the expec
1f640 74 65 64 20 76 61 6c 75 65 73 29 20 61 6e 64 20  ted values) and 
1f650 74 68 65 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e  the conflict han
1f660 64 6c 65 72 20 0a 20 20 2a 2a 20 72 65 74 75 72  dler .  ** retur
1f670 6e 65 64 20 53 51 4c 49 54 45 5f 43 48 41 4e 47  ned SQLITE_CHANG
1f680 45 53 45 54 5f 52 45 50 4c 41 43 45 2e 20 49 6e  ESET_REPLACE. In
1f690 20 74 68 69 73 20 63 61 73 65 20 72 65 74 72 79   this case retry
1f6a0 20 74 68 65 20 6f 70 65 72 61 74 69 6f 6e 2c 0a   the operation,.
1f6b0 20 20 2a 2a 20 62 75 74 20 70 61 73 73 20 4e 55    ** but pass NU
1f6c0 4c 4c 20 61 73 20 74 68 65 20 66 69 6e 61 6c 20  LL as the final 
1f6d0 61 72 67 75 6d 65 6e 74 20 73 6f 20 74 68 61 74  argument so that
1f6e0 20 73 65 73 73 69 6f 6e 41 70 70 6c 79 4f 6e 65   sessionApplyOne
1f6f0 4f 70 28 29 20 69 67 6e 6f 72 65 73 0a 20 20 2a  Op() ignores.  *
1f700 2a 20 74 68 65 20 53 51 4c 49 54 45 5f 43 48 41  * the SQLITE_CHA
1f710 4e 47 45 53 45 54 5f 44 41 54 41 20 70 72 6f 62  NGESET_DATA prob
1f720 6c 65 6d 2e 20 20 2a 2f 0a 20 20 69 66 28 20 62  lem.  */.  if( b
1f730 52 65 74 72 79 20 29 7b 0a 20 20 20 20 61 73 73  Retry ){.    ass
1f740 65 72 74 28 20 70 49 74 65 72 2d 3e 6f 70 3d 3d  ert( pIter->op==
1f750 53 51 4c 49 54 45 5f 55 50 44 41 54 45 20 7c 7c  SQLITE_UPDATE ||
1f760 20 70 49 74 65 72 2d 3e 6f 70 3d 3d 53 51 4c 49   pIter->op==SQLI
1f770 54 45 5f 44 45 4c 45 54 45 20 29 3b 0a 20 20 20  TE_DELETE );.   
1f780 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 41 70 70   rc = sessionApp
1f790 6c 79 4f 6e 65 4f 70 28 70 49 74 65 72 2c 20 70  lyOneOp(pIter, p
1f7a0 41 70 70 6c 79 2c 20 78 43 6f 6e 66 6c 69 63 74  Apply, xConflict
1f7b0 2c 20 70 43 74 78 2c 20 30 2c 20 30 29 3b 0a 20  , pCtx, 0, 0);. 
1f7c0 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20   }..  /* If the 
1f7d0 62 52 65 70 6c 61 63 65 20 66 6c 61 67 20 69 73  bReplace flag is
1f7e0 20 73 65 74 2c 20 74 68 65 20 63 68 61 6e 67 65   set, the change
1f7f0 20 69 73 20 61 6e 20 49 4e 53 45 52 54 20 74 68   is an INSERT th
1f800 61 74 20 68 61 73 20 6e 6f 74 0a 20 20 2a 2a 20  at has not.  ** 
1f810 62 65 65 6e 20 70 65 72 66 6f 72 6d 65 64 20 62  been performed b
1f820 65 63 61 75 73 65 20 74 68 65 20 64 61 74 61 62  ecause the datab
1f830 61 73 65 20 61 6c 72 65 61 64 79 20 63 6f 6e 74  ase already cont
1f840 61 69 6e 73 20 61 20 72 6f 77 20 77 69 74 68 20  ains a row with 
1f850 74 68 65 0a 20 20 2a 2a 20 73 70 65 63 69 66 69  the.  ** specifi
1f860 65 64 20 70 72 69 6d 61 72 79 20 6b 65 79 20 61  ed primary key a
1f870 6e 64 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 20  nd the conflict 
1f880 68 61 6e 64 6c 65 72 20 72 65 74 75 72 6e 65 64  handler returned
1f890 0a 20 20 2a 2a 20 53 51 4c 49 54 45 5f 43 48 41  .  ** SQLITE_CHA
1f8a0 4e 47 45 53 45 54 5f 52 45 50 4c 41 43 45 2e 20  NGESET_REPLACE. 
1f8b0 49 6e 20 74 68 69 73 20 63 61 73 65 20 72 65 6d  In this case rem
1f8c0 6f 76 65 20 74 68 65 20 63 6f 6e 66 6c 69 63 74  ove the conflict
1f8d0 69 6e 67 20 72 6f 77 0a 20 20 2a 2a 20 62 65 66  ing row.  ** bef
1f8e0 6f 72 65 20 72 65 61 74 74 65 6d 70 74 69 6e 67  ore reattempting
1f8f0 20 74 68 65 20 49 4e 53 45 52 54 2e 20 20 2a 2f   the INSERT.  */
1f900 0a 20 20 65 6c 73 65 20 69 66 28 20 62 52 65 70  .  else if( bRep
1f910 6c 61 63 65 20 29 7b 0a 20 20 20 20 61 73 73 65  lace ){.    asse
1f920 72 74 28 20 70 49 74 65 72 2d 3e 6f 70 3d 3d 53  rt( pIter->op==S
1f930 51 4c 49 54 45 5f 49 4e 53 45 52 54 20 29 3b 0a  QLITE_INSERT );.
1f940 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
1f950 5f 65 78 65 63 28 64 62 2c 20 22 53 41 56 45 50  _exec(db, "SAVEP
1f960 4f 49 4e 54 20 72 65 70 6c 61 63 65 5f 6f 70 22  OINT replace_op"
1f970 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20  , 0, 0, 0);.    
1f980 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
1f990 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  K ){.      rc = 
1f9a0 73 65 73 73 69 6f 6e 42 69 6e 64 52 6f 77 28 70  sessionBindRow(p
1f9b0 49 74 65 72 2c 20 0a 20 20 20 20 20 20 20 20 20  Iter, .         
1f9c0 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
1f9d0 74 5f 6e 65 77 2c 20 70 41 70 70 6c 79 2d 3e 6e  t_new, pApply->n
1f9e0 43 6f 6c 2c 20 70 41 70 70 6c 79 2d 3e 61 62 50  Col, pApply->abP
1f9f0 4b 2c 20 70 41 70 70 6c 79 2d 3e 70 44 65 6c 65  K, pApply->pDele
1fa00 74 65 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  te);.      sqlit
1fa10 65 33 5f 62 69 6e 64 5f 69 6e 74 28 70 41 70 70  e3_bind_int(pApp
1fa20 6c 79 2d 3e 70 44 65 6c 65 74 65 2c 20 70 41 70  ly->pDelete, pAp
1fa30 70 6c 79 2d 3e 6e 43 6f 6c 2b 31 2c 20 31 29 3b  ply->nCol+1, 1);
1fa40 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72  .    }.    if( r
1fa50 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
1fa60 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74        sqlite3_st
1fa70 65 70 28 70 41 70 70 6c 79 2d 3e 70 44 65 6c 65  ep(pApply->pDele
1fa80 74 65 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  te);.      rc = 
1fa90 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70 41  sqlite3_reset(pA
1faa0 70 70 6c 79 2d 3e 70 44 65 6c 65 74 65 29 3b 0a  pply->pDelete);.
1fab0 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63      }.    if( rc
1fac0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
1fad0 20 20 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f       rc = sessio
1fae0 6e 41 70 70 6c 79 4f 6e 65 4f 70 28 70 49 74 65  nApplyOneOp(pIte
1faf0 72 2c 20 70 41 70 70 6c 79 2c 20 78 43 6f 6e 66  r, pApply, xConf
1fb00 6c 69 63 74 2c 20 70 43 74 78 2c 20 30 2c 20 30  lict, pCtx, 0, 0
1fb10 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  );.    }.    if(
1fb20 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
1fb30 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  {.      rc = sql
1fb40 69 74 65 33 5f 65 78 65 63 28 64 62 2c 20 22 52  ite3_exec(db, "R
1fb50 45 4c 45 41 53 45 20 72 65 70 6c 61 63 65 5f 6f  ELEASE replace_o
1fb60 70 22 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20  p", 0, 0, 0);.  
1fb70 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
1fb80 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  n rc;.}../*.** R
1fb90 65 74 72 79 20 74 68 65 20 63 68 61 6e 67 65 73  etry the changes
1fba0 20 61 63 63 75 6d 75 6c 61 74 65 64 20 69 6e 20   accumulated in 
1fbb0 74 68 65 20 70 41 70 70 6c 79 2d 3e 63 6f 6e 73  the pApply->cons
1fbc0 74 72 61 69 6e 74 73 20 62 75 66 66 65 72 2e 0a  traints buffer..
1fbd0 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
1fbe0 73 73 69 6f 6e 52 65 74 72 79 43 6f 6e 73 74 72  ssionRetryConstr
1fbf0 61 69 6e 74 73 28 0a 20 20 73 71 6c 69 74 65 33  aints(.  sqlite3
1fc00 20 2a 64 62 2c 20 0a 20 20 69 6e 74 20 62 50 61   *db, .  int bPa
1fc10 74 63 68 73 65 74 2c 0a 20 20 63 6f 6e 73 74 20  tchset,.  const 
1fc20 63 68 61 72 20 2a 7a 54 61 62 2c 0a 20 20 53 65  char *zTab,.  Se
1fc30 73 73 69 6f 6e 41 70 70 6c 79 43 74 78 20 2a 70  ssionApplyCtx *p
1fc40 41 70 70 6c 79 2c 0a 20 20 69 6e 74 28 2a 78 43  Apply,.  int(*xC
1fc50 6f 6e 66 6c 69 63 74 29 28 76 6f 69 64 2a 2c 20  onflict)(void*, 
1fc60 69 6e 74 2c 20 73 71 6c 69 74 65 33 5f 63 68 61  int, sqlite3_cha
1fc70 6e 67 65 73 65 74 5f 69 74 65 72 2a 29 2c 0a 20  ngeset_iter*),. 
1fc80 20 76 6f 69 64 20 2a 70 43 74 78 20 20 20 20 20   void *pCtx     
1fc90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fca0 20 2f 2a 20 46 69 72 73 74 20 61 72 67 75 6d 65   /* First argume
1fcb0 6e 74 20 70 61 73 73 65 64 20 74 6f 20 78 43 6f  nt passed to xCo
1fcc0 6e 66 6c 69 63 74 20 2a 2f 0a 29 7b 0a 20 20 69  nflict */.){.  i
1fcd0 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
1fce0 4b 3b 0a 0a 20 20 77 68 69 6c 65 28 20 70 41 70  K;..  while( pAp
1fcf0 70 6c 79 2d 3e 63 6f 6e 73 74 72 61 69 6e 74 73  ply->constraints
1fd00 2e 6e 42 75 66 20 29 7b 0a 20 20 20 20 73 71 6c  .nBuf ){.    sql
1fd10 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69  ite3_changeset_i
1fd20 74 65 72 20 2a 70 49 74 65 72 32 20 3d 20 30 3b  ter *pIter2 = 0;
1fd30 0a 20 20 20 20 53 65 73 73 69 6f 6e 42 75 66 66  .    SessionBuff
1fd40 65 72 20 63 6f 6e 73 20 3d 20 70 41 70 70 6c 79  er cons = pApply
1fd50 2d 3e 63 6f 6e 73 74 72 61 69 6e 74 73 3b 0a 20  ->constraints;. 
1fd60 20 20 20 6d 65 6d 73 65 74 28 26 70 41 70 70 6c     memset(&pAppl
1fd70 79 2d 3e 63 6f 6e 73 74 72 61 69 6e 74 73 2c 20  y->constraints, 
1fd80 30 2c 20 73 69 7a 65 6f 66 28 53 65 73 73 69 6f  0, sizeof(Sessio
1fd90 6e 42 75 66 66 65 72 29 29 3b 0a 0a 20 20 20 20  nBuffer));..    
1fda0 72 63 20 3d 20 73 65 73 73 69 6f 6e 43 68 61 6e  rc = sessionChan
1fdb0 67 65 73 65 74 53 74 61 72 74 28 26 70 49 74 65  gesetStart(&pIte
1fdc0 72 32 2c 20 30 2c 20 30 2c 20 63 6f 6e 73 2e 6e  r2, 0, 0, cons.n
1fdd0 42 75 66 2c 20 63 6f 6e 73 2e 61 42 75 66 29 3b  Buf, cons.aBuf);
1fde0 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
1fdf0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
1fe00 69 6e 74 20 6e 42 79 74 65 20 3d 20 32 2a 70 41  int nByte = 2*pA
1fe10 70 70 6c 79 2d 3e 6e 43 6f 6c 2a 73 69 7a 65 6f  pply->nCol*sizeo
1fe20 66 28 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 2a  f(sqlite3_value*
1fe30 29 3b 0a 20 20 20 20 20 20 69 6e 74 20 72 63 32  );.      int rc2
1fe40 3b 0a 20 20 20 20 20 20 70 49 74 65 72 32 2d 3e  ;.      pIter2->
1fe50 62 50 61 74 63 68 73 65 74 20 3d 20 62 50 61 74  bPatchset = bPat
1fe60 63 68 73 65 74 3b 0a 20 20 20 20 20 20 70 49 74  chset;.      pIt
1fe70 65 72 32 2d 3e 7a 54 61 62 20 3d 20 28 63 68 61  er2->zTab = (cha
1fe80 72 2a 29 7a 54 61 62 3b 0a 20 20 20 20 20 20 70  r*)zTab;.      p
1fe90 49 74 65 72 32 2d 3e 6e 43 6f 6c 20 3d 20 70 41  Iter2->nCol = pA
1fea0 70 70 6c 79 2d 3e 6e 43 6f 6c 3b 0a 20 20 20 20  pply->nCol;.    
1feb0 20 20 70 49 74 65 72 32 2d 3e 61 62 50 4b 20 3d    pIter2->abPK =
1fec0 20 70 41 70 70 6c 79 2d 3e 61 62 50 4b 3b 0a 20   pApply->abPK;. 
1fed0 20 20 20 20 20 73 65 73 73 69 6f 6e 42 75 66 66       sessionBuff
1fee0 65 72 47 72 6f 77 28 26 70 49 74 65 72 32 2d 3e  erGrow(&pIter2->
1fef0 74 62 6c 68 64 72 2c 20 6e 42 79 74 65 2c 20 26  tblhdr, nByte, &
1ff00 72 63 29 3b 0a 20 20 20 20 20 20 70 49 74 65 72  rc);.      pIter
1ff10 32 2d 3e 61 70 56 61 6c 75 65 20 3d 20 28 73 71  2->apValue = (sq
1ff20 6c 69 74 65 33 5f 76 61 6c 75 65 2a 2a 29 70 49  lite3_value**)pI
1ff30 74 65 72 32 2d 3e 74 62 6c 68 64 72 2e 61 42 75  ter2->tblhdr.aBu
1ff40 66 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  f;.      if( rc=
1ff50 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 6d 65 6d  =SQLITE_OK ) mem
1ff60 73 65 74 28 70 49 74 65 72 32 2d 3e 61 70 56 61  set(pIter2->apVa
1ff70 6c 75 65 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a  lue, 0, nByte);.
1ff80 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 72 63  .      while( rc
1ff90 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 53  ==SQLITE_OK && S
1ffa0 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74  QLITE_ROW==sqlit
1ffb0 65 33 63 68 61 6e 67 65 73 65 74 5f 6e 65 78 74  e3changeset_next
1ffc0 28 70 49 74 65 72 32 29 20 29 7b 0a 20 20 20 20  (pIter2) ){.    
1ffd0 20 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e      rc = session
1ffe0 41 70 70 6c 79 4f 6e 65 57 69 74 68 52 65 74 72  ApplyOneWithRetr
1fff0 79 28 64 62 2c 20 70 49 74 65 72 32 2c 20 70 41  y(db, pIter2, pA
20000 70 70 6c 79 2c 20 78 43 6f 6e 66 6c 69 63 74 2c  pply, xConflict,
20010 20 70 43 74 78 29 3b 0a 20 20 20 20 20 20 7d 0a   pCtx);.      }.
20020 0a 20 20 20 20 20 20 72 63 32 20 3d 20 73 71 6c  .      rc2 = sql
20030 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 66 69  ite3changeset_fi
20040 6e 61 6c 69 7a 65 28 70 49 74 65 72 32 29 3b 0a  nalize(pIter2);.
20050 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
20060 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 72  LITE_OK ) rc = r
20070 63 32 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 73  c2;.    }.    as
20080 73 65 72 74 28 20 70 41 70 70 6c 79 2d 3e 62 44  sert( pApply->bD
20090 65 66 65 72 43 6f 6e 73 74 72 61 69 6e 74 73 20  eferConstraints 
200a0 7c 7c 20 70 41 70 70 6c 79 2d 3e 63 6f 6e 73 74  || pApply->const
200b0 72 61 69 6e 74 73 2e 6e 42 75 66 3d 3d 30 20 29  raints.nBuf==0 )
200c0 3b 0a 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  ;..    sqlite3_f
200d0 72 65 65 28 63 6f 6e 73 2e 61 42 75 66 29 3b 0a  ree(cons.aBuf);.
200e0 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
200f0 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20  TE_OK ) break;. 
20100 20 20 20 69 66 28 20 70 41 70 70 6c 79 2d 3e 63     if( pApply->c
20110 6f 6e 73 74 72 61 69 6e 74 73 2e 6e 42 75 66 3e  onstraints.nBuf>
20120 3d 63 6f 6e 73 2e 6e 42 75 66 20 29 7b 0a 20 20  =cons.nBuf ){.  
20130 20 20 20 20 2f 2a 20 4e 6f 20 70 72 6f 67 72 65      /* No progre
20140 73 73 20 77 61 73 20 6d 61 64 65 20 6f 6e 20 74  ss was made on t
20150 68 65 20 6c 61 73 74 20 72 6f 75 6e 64 2e 20 2a  he last round. *
20160 2f 0a 20 20 20 20 20 20 70 41 70 70 6c 79 2d 3e  /.      pApply->
20170 62 44 65 66 65 72 43 6f 6e 73 74 72 61 69 6e 74  bDeferConstraint
20180 73 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d  s = 0;.    }.  }
20190 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
201a0 0a 0a 2f 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e 74  ../*.** Argument
201b0 20 70 49 74 65 72 20 69 73 20 61 20 63 68 61 6e   pIter is a chan
201c0 67 65 73 65 74 20 69 74 65 72 61 74 6f 72 20 74  geset iterator t
201d0 68 61 74 20 68 61 73 20 62 65 65 6e 20 69 6e 69  hat has been ini
201e0 74 69 61 6c 69 7a 65 64 2c 20 62 75 74 0a 2a 2a  tialized, but.**
201f0 20 6e 6f 74 20 79 65 74 20 70 61 73 73 65 64 20   not yet passed 
20200 74 6f 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65  to sqlite3change
20210 73 65 74 5f 6e 65 78 74 28 29 2e 20 54 68 69 73  set_next(). This
20220 20 66 75 6e 63 74 69 6f 6e 20 61 70 70 6c 69 65   function applie
20230 73 20 74 68 65 20 0a 2a 2a 20 63 68 61 6e 67 65  s the .** change
20240 73 65 74 20 74 6f 20 74 68 65 20 6d 61 69 6e 20  set to the main 
20250 64 61 74 61 62 61 73 65 20 61 74 74 61 63 68 65  database attache
20260 64 20 74 6f 20 68 61 6e 64 6c 65 20 22 64 62 22  d to handle "db"
20270 2e 20 54 68 65 20 73 75 70 70 6c 69 65 64 0a 2a  . The supplied.*
20280 2a 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c  * conflict handl
20290 65 72 20 63 61 6c 6c 62 61 63 6b 20 69 73 20 69  er callback is i
202a0 6e 76 6f 6b 65 64 20 74 6f 20 72 65 73 6f 6c 76  nvoked to resolv
202b0 65 20 61 6e 79 20 63 6f 6e 66 6c 69 63 74 73 20  e any conflicts 
202c0 65 6e 63 6f 75 6e 74 65 72 65 64 0a 2a 2a 20 77  encountered.** w
202d0 68 69 6c 65 20 61 70 70 6c 79 69 6e 67 20 74 68  hile applying th
202e0 65 20 63 68 61 6e 67 65 2e 0a 2a 2f 0a 73 74 61  e change..*/.sta
202f0 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 43  tic int sessionC
20300 68 61 6e 67 65 73 65 74 41 70 70 6c 79 28 0a 20  hangesetApply(. 
20310 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20   sqlite3 *db,   
20320 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20330 20 2f 2a 20 41 70 70 6c 79 20 63 68 61 6e 67 65   /* Apply change
20340 20 74 6f 20 22 6d 61 69 6e 22 20 64 62 20 6f 66   to "main" db of
20350 20 74 68 69 73 20 68 61 6e 64 6c 65 20 2a 2f 0a   this handle */.
20360 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65    sqlite3_change
20370 73 65 74 5f 69 74 65 72 20 2a 70 49 74 65 72 2c  set_iter *pIter,
20380 20 20 2f 2a 20 43 68 61 6e 67 65 73 65 74 20 74    /* Changeset t
20390 6f 20 61 70 70 6c 79 20 2a 2f 0a 20 20 69 6e 74  o apply */.  int
203a0 28 2a 78 46 69 6c 74 65 72 29 28 0a 20 20 20 20  (*xFilter)(.    
203b0 76 6f 69 64 20 2a 70 43 74 78 2c 20 20 20 20 20  void *pCtx,     
203c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
203d0 20 43 6f 70 79 20 6f 66 20 73 69 78 74 68 20 61   Copy of sixth a
203e0 72 67 20 74 6f 20 5f 61 70 70 6c 79 28 29 20 2a  rg to _apply() *
203f0 2f 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72  /.    const char
20400 20 2a 7a 54 61 62 20 20 20 20 20 20 20 20 20 20   *zTab          
20410 20 20 20 20 2f 2a 20 54 61 62 6c 65 20 6e 61 6d      /* Table nam
20420 65 20 2a 2f 0a 20 20 29 2c 0a 20 20 69 6e 74 28  e */.  ),.  int(
20430 2a 78 43 6f 6e 66 6c 69 63 74 29 28 0a 20 20 20  *xConflict)(.   
20440 20 76 6f 69 64 20 2a 70 43 74 78 2c 20 20 20 20   void *pCtx,    
20450 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
20460 2a 20 43 6f 70 79 20 6f 66 20 66 69 66 74 68 20  * Copy of fifth 
20470 61 72 67 20 74 6f 20 5f 61 70 70 6c 79 28 29 20  arg to _apply() 
20480 2a 2f 0a 20 20 20 20 69 6e 74 20 65 43 6f 6e 66  */.    int eConf
20490 6c 69 63 74 2c 20 20 20 20 20 20 20 20 20 20 20  lict,           
204a0 20 20 20 20 20 2f 2a 20 44 41 54 41 2c 20 4d 49       /* DATA, MI
204b0 53 53 49 4e 47 2c 20 43 4f 4e 46 4c 49 43 54 2c  SSING, CONFLICT,
204c0 20 43 4f 4e 53 54 52 41 49 4e 54 20 2a 2f 0a 20   CONSTRAINT */. 
204d0 20 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67     sqlite3_chang
204e0 65 73 65 74 5f 69 74 65 72 20 2a 70 20 20 20 20  eset_iter *p    
204f0 20 2f 2a 20 48 61 6e 64 6c 65 20 64 65 73 63 72   /* Handle descr
20500 69 62 69 6e 67 20 63 68 61 6e 67 65 20 61 6e 64  ibing change and
20510 20 63 6f 6e 66 6c 69 63 74 20 2a 2f 0a 20 20 29   conflict */.  )
20520 2c 0a 20 20 76 6f 69 64 20 2a 70 43 74 78 20 20  ,.  void *pCtx  
20530 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20540 20 20 20 20 2f 2a 20 46 69 72 73 74 20 61 72 67      /* First arg
20550 75 6d 65 6e 74 20 70 61 73 73 65 64 20 74 6f 20  ument passed to 
20560 78 43 6f 6e 66 6c 69 63 74 20 2a 2f 0a 29 7b 0a  xConflict */.){.
20570 20 20 69 6e 74 20 73 63 68 65 6d 61 4d 69 73 6d    int schemaMism
20580 61 74 63 68 20 3d 20 30 3b 0a 20 20 69 6e 74 20  atch = 0;.  int 
20590 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rc;             
205a0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
205b0 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
205c0 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 62  const char *zTab
205d0 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
205e0 2f 2a 20 4e 61 6d 65 20 6f 66 20 63 75 72 72 65  /* Name of curre
205f0 6e 74 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e  nt table */.  in
20600 74 20 6e 54 61 62 20 3d 20 30 3b 20 20 20 20 20  t nTab = 0;     
20610 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
20620 20 52 65 73 75 6c 74 20 6f 66 20 73 71 6c 69 74   Result of sqlit
20630 65 33 53 74 72 6c 65 6e 33 30 28 7a 54 61 62 29  e3Strlen30(zTab)
20640 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 41 70 70   */.  SessionApp
20650 6c 79 43 74 78 20 73 41 70 70 6c 79 3b 20 20 20  lyCtx sApply;   
20660 20 20 20 20 20 20 2f 2a 20 63 68 61 6e 67 65 73        /* changes
20670 65 74 5f 61 70 70 6c 79 28 29 20 63 6f 6e 74 65  et_apply() conte
20680 78 74 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69  xt object */.  i
20690 6e 74 20 62 50 61 74 63 68 73 65 74 3b 0a 0a 20  nt bPatchset;.. 
206a0 20 61 73 73 65 72 74 28 20 78 43 6f 6e 66 6c 69   assert( xConfli
206b0 63 74 21 3d 30 20 29 3b 0a 0a 20 20 70 49 74 65  ct!=0 );..  pIte
206c0 72 2d 3e 69 6e 2e 62 4e 6f 44 69 73 63 61 72 64  r->in.bNoDiscard
206d0 20 3d 20 31 3b 0a 20 20 6d 65 6d 73 65 74 28 26   = 1;.  memset(&
206e0 73 41 70 70 6c 79 2c 20 30 2c 20 73 69 7a 65 6f  sApply, 0, sizeo
206f0 66 28 73 41 70 70 6c 79 29 29 3b 0a 20 20 73 71  f(sApply));.  sq
20700 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65  lite3_mutex_ente
20710 72 28 73 71 6c 69 74 65 33 5f 64 62 5f 6d 75 74  r(sqlite3_db_mut
20720 65 78 28 64 62 29 29 3b 0a 20 20 72 63 20 3d 20  ex(db));.  rc = 
20730 73 71 6c 69 74 65 33 5f 65 78 65 63 28 64 62 2c  sqlite3_exec(db,
20740 20 22 53 41 56 45 50 4f 49 4e 54 20 63 68 61 6e   "SAVEPOINT chan
20750 67 65 73 65 74 5f 61 70 70 6c 79 22 2c 20 30 2c  geset_apply", 0,
20760 20 30 2c 20 30 29 3b 0a 20 20 69 66 28 20 72 63   0, 0);.  if( rc
20770 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
20780 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
20790 65 78 65 63 28 64 62 2c 20 22 50 52 41 47 4d 41  exec(db, "PRAGMA
207a0 20 64 65 66 65 72 5f 66 6f 72 65 69 67 6e 5f 6b   defer_foreign_k
207b0 65 79 73 20 3d 20 31 22 2c 20 30 2c 20 30 2c 20  eys = 1", 0, 0, 
207c0 30 29 3b 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28  0);.  }.  while(
207d0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
207e0 26 20 53 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 71  & SQLITE_ROW==sq
207f0 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6e  lite3changeset_n
20800 65 78 74 28 70 49 74 65 72 29 20 29 7b 0a 20 20  ext(pIter) ){.  
20810 20 20 69 6e 74 20 6e 43 6f 6c 3b 0a 20 20 20 20    int nCol;.    
20820 69 6e 74 20 6f 70 3b 0a 20 20 20 20 63 6f 6e 73  int op;.    cons
20830 74 20 63 68 61 72 20 2a 7a 4e 65 77 3b 0a 20 20  t char *zNew;.  
20840 20 20 0a 20 20 20 20 73 71 6c 69 74 65 33 63 68    .    sqlite3ch
20850 61 6e 67 65 73 65 74 5f 6f 70 28 70 49 74 65 72  angeset_op(pIter
20860 2c 20 26 7a 4e 65 77 2c 20 26 6e 43 6f 6c 2c 20  , &zNew, &nCol, 
20870 26 6f 70 2c 20 30 29 3b 0a 0a 20 20 20 20 69 66  &op, 0);..    if
20880 28 20 7a 54 61 62 3d 3d 30 20 7c 7c 20 73 71 6c  ( zTab==0 || sql
20890 69 74 65 33 5f 73 74 72 6e 69 63 6d 70 28 7a 4e  ite3_strnicmp(zN
208a0 65 77 2c 20 7a 54 61 62 2c 20 6e 54 61 62 2b 31  ew, zTab, nTab+1
208b0 29 20 29 7b 0a 20 20 20 20 20 20 75 38 20 2a 61  ) ){.      u8 *a
208c0 62 50 4b 3b 0a 0a 20 20 20 20 20 20 72 63 20 3d  bPK;..      rc =
208d0 20 73 65 73 73 69 6f 6e 52 65 74 72 79 43 6f 6e   sessionRetryCon
208e0 73 74 72 61 69 6e 74 73 28 0a 20 20 20 20 20 20  straints(.      
208f0 20 20 20 20 64 62 2c 20 70 49 74 65 72 2d 3e 62      db, pIter->b
20900 50 61 74 63 68 73 65 74 2c 20 7a 54 61 62 2c 20  Patchset, zTab, 
20910 26 73 41 70 70 6c 79 2c 20 78 43 6f 6e 66 6c 69  &sApply, xConfli
20920 63 74 2c 20 70 43 74 78 0a 20 20 20 20 20 20 29  ct, pCtx.      )
20930 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  ;.      if( rc!=
20940 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61  SQLITE_OK ) brea
20950 6b 3b 0a 0a 20 20 20 20 20 20 73 71 6c 69 74 65  k;..      sqlite
20960 33 5f 66 72 65 65 28 28 63 68 61 72 2a 29 73 41  3_free((char*)sA
20970 70 70 6c 79 2e 61 7a 43 6f 6c 29 3b 20 20 2f 2a  pply.azCol);  /*
20980 20 63 61 73 74 20 77 6f 72 6b 73 20 61 72 6f 75   cast works arou
20990 6e 64 20 56 43 2b 2b 20 62 75 67 20 2a 2f 0a 20  nd VC++ bug */. 
209a0 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6e       sqlite3_fin
209b0 61 6c 69 7a 65 28 73 41 70 70 6c 79 2e 70 44 65  alize(sApply.pDe
209c0 6c 65 74 65 29 3b 0a 20 20 20 20 20 20 73 71 6c  lete);.      sql
209d0 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 73 41  ite3_finalize(sA
209e0 70 70 6c 79 2e 70 55 70 64 61 74 65 29 3b 20 0a  pply.pUpdate); .
209f0 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69        sqlite3_fi
20a00 6e 61 6c 69 7a 65 28 73 41 70 70 6c 79 2e 70 49  nalize(sApply.pI
20a10 6e 73 65 72 74 29 3b 0a 20 20 20 20 20 20 73 71  nsert);.      sq
20a20 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 73  lite3_finalize(s
20a30 41 70 70 6c 79 2e 70 53 65 6c 65 63 74 29 3b 0a  Apply.pSelect);.
20a40 20 20 20 20 20 20 6d 65 6d 73 65 74 28 26 73 41        memset(&sA
20a50 70 70 6c 79 2c 20 30 2c 20 73 69 7a 65 6f 66 28  pply, 0, sizeof(
20a60 73 41 70 70 6c 79 29 29 3b 0a 20 20 20 20 20 20  sApply));.      
20a70 73 41 70 70 6c 79 2e 64 62 20 3d 20 64 62 3b 0a  sApply.db = db;.
20a80 20 20 20 20 20 20 73 41 70 70 6c 79 2e 62 44 65        sApply.bDe
20a90 66 65 72 43 6f 6e 73 74 72 61 69 6e 74 73 20 3d  ferConstraints =
20aa0 20 31 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 49 66   1;..      /* If
20ab0 20 61 6e 20 78 46 69 6c 74 65 72 28 29 20 63 61   an xFilter() ca
20ac0 6c 6c 62 61 63 6b 20 77 61 73 20 73 70 65 63 69  llback was speci
20ad0 66 69 65 64 2c 20 69 6e 76 6f 6b 65 20 69 74 20  fied, invoke it 
20ae0 6e 6f 77 2e 20 49 66 20 74 68 65 20 0a 20 20 20  now. If the .   
20af0 20 20 20 2a 2a 20 78 46 69 6c 74 65 72 20 63 61     ** xFilter ca
20b00 6c 6c 62 61 63 6b 20 72 65 74 75 72 6e 73 20 7a  llback returns z
20b10 65 72 6f 2c 20 73 6b 69 70 20 74 68 69 73 20 74  ero, skip this t
20b20 61 62 6c 65 2e 20 49 66 20 69 74 20 72 65 74 75  able. If it retu
20b30 72 6e 73 0a 20 20 20 20 20 20 2a 2a 20 6e 6f 6e  rns.      ** non
20b40 2d 7a 65 72 6f 2c 20 70 72 6f 63 65 65 64 2e 20  -zero, proceed. 
20b50 2a 2f 0a 20 20 20 20 20 20 73 63 68 65 6d 61 4d  */.      schemaM
20b60 69 73 6d 61 74 63 68 20 3d 20 28 78 46 69 6c 74  ismatch = (xFilt
20b70 65 72 20 26 26 20 28 30 3d 3d 78 46 69 6c 74 65  er && (0==xFilte
20b80 72 28 70 43 74 78 2c 20 7a 4e 65 77 29 29 29 3b  r(pCtx, zNew)));
20b90 0a 20 20 20 20 20 20 69 66 28 20 73 63 68 65 6d  .      if( schem
20ba0 61 4d 69 73 6d 61 74 63 68 20 29 7b 0a 20 20 20  aMismatch ){.   
20bb0 20 20 20 20 20 7a 54 61 62 20 3d 20 73 71 6c 69       zTab = sqli
20bc0 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 22  te3_mprintf("%s"
20bd0 2c 20 7a 4e 65 77 29 3b 0a 20 20 20 20 20 20 20  , zNew);.       
20be0 20 69 66 28 20 7a 54 61 62 3d 3d 30 20 29 7b 0a   if( zTab==0 ){.
20bf0 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 53            rc = S
20c00 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
20c10 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
20c20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
20c30 6e 54 61 62 20 3d 20 28 69 6e 74 29 73 74 72 6c  nTab = (int)strl
20c40 65 6e 28 7a 54 61 62 29 3b 0a 20 20 20 20 20 20  en(zTab);.      
20c50 20 20 73 41 70 70 6c 79 2e 61 7a 43 6f 6c 20 3d    sApply.azCol =
20c60 20 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 29   (const char **)
20c70 7a 54 61 62 3b 0a 20 20 20 20 20 20 7d 65 6c 73  zTab;.      }els
20c80 65 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74  e{.        sqlit
20c90 65 33 63 68 61 6e 67 65 73 65 74 5f 70 6b 28 70  e3changeset_pk(p
20ca0 49 74 65 72 2c 20 26 61 62 50 4b 2c 20 30 29 3b  Iter, &abPK, 0);
20cb0 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 65  .        rc = se
20cc0 73 73 69 6f 6e 54 61 62 6c 65 49 6e 66 6f 28 0a  ssionTableInfo(.
20cd0 20 20 20 20 20 20 20 20 20 20 20 20 64 62 2c 20              db, 
20ce0 22 6d 61 69 6e 22 2c 20 7a 4e 65 77 2c 20 26 73  "main", zNew, &s
20cf0 41 70 70 6c 79 2e 6e 43 6f 6c 2c 20 26 7a 54 61  Apply.nCol, &zTa
20d00 62 2c 20 26 73 41 70 70 6c 79 2e 61 7a 43 6f 6c  b, &sApply.azCol
20d10 2c 20 26 73 41 70 70 6c 79 2e 61 62 50 4b 0a 20  , &sApply.abPK. 
20d20 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20         );.      
20d30 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
20d40 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 0a  _OK ) break;.  .
20d50 20 20 20 20 20 20 20 20 69 66 28 20 73 41 70 70          if( sApp
20d60 6c 79 2e 6e 43 6f 6c 3d 3d 30 20 29 7b 0a 20 20  ly.nCol==0 ){.  
20d70 20 20 20 20 20 20 20 20 73 63 68 65 6d 61 4d 69          schemaMi
20d80 73 6d 61 74 63 68 20 3d 20 31 3b 0a 20 20 20 20  smatch = 1;.    
20d90 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6c 6f        sqlite3_lo
20da0 67 28 53 51 4c 49 54 45 5f 53 43 48 45 4d 41 2c  g(SQLITE_SCHEMA,
20db0 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20   .              
20dc0 22 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65  "sqlite3changese
20dd0 74 5f 61 70 70 6c 79 28 29 3a 20 6e 6f 20 73 75  t_apply(): no su
20de0 63 68 20 74 61 62 6c 65 3a 20 25 73 22 2c 20 7a  ch table: %s", z
20df0 54 61 62 0a 20 20 20 20 20 20 20 20 20 20 29 3b  Tab.          );
20e00 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
20e10 20 20 20 65 6c 73 65 20 69 66 28 20 73 41 70 70     else if( sApp
20e20 6c 79 2e 6e 43 6f 6c 21 3d 6e 43 6f 6c 20 29 7b  ly.nCol!=nCol ){
20e30 0a 20 20 20 20 20 20 20 20 20 20 73 63 68 65 6d  .          schem
20e40 61 4d 69 73 6d 61 74 63 68 20 3d 20 31 3b 0a 20  aMismatch = 1;. 
20e50 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33           sqlite3
20e60 5f 6c 6f 67 28 53 51 4c 49 54 45 5f 53 43 48 45  _log(SQLITE_SCHE
20e70 4d 41 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20  MA, .           
20e80 20 20 20 22 73 71 6c 69 74 65 33 63 68 61 6e 67     "sqlite3chang
20e90 65 73 65 74 5f 61 70 70 6c 79 28 29 3a 20 74 61  eset_apply(): ta
20ea0 62 6c 65 20 25 73 20 68 61 73 20 25 64 20 63 6f  ble %s has %d co
20eb0 6c 75 6d 6e 73 2c 20 65 78 70 65 63 74 65 64 20  lumns, expected 
20ec0 25 64 22 2c 20 0a 20 20 20 20 20 20 20 20 20 20  %d", .          
20ed0 20 20 20 20 7a 54 61 62 2c 20 73 41 70 70 6c 79      zTab, sApply
20ee0 2e 6e 43 6f 6c 2c 20 6e 43 6f 6c 0a 20 20 20 20  .nCol, nCol.    
20ef0 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20        );.       
20f00 20 7d 0a 20 20 20 20 20 20 20 20 65 6c 73 65 20   }.        else 
20f10 69 66 28 20 6d 65 6d 63 6d 70 28 73 41 70 70 6c  if( memcmp(sAppl
20f20 79 2e 61 62 50 4b 2c 20 61 62 50 4b 2c 20 6e 43  y.abPK, abPK, nC
20f30 6f 6c 29 21 3d 30 20 29 7b 0a 20 20 20 20 20 20  ol)!=0 ){.      
20f40 20 20 20 20 73 63 68 65 6d 61 4d 69 73 6d 61 74      schemaMismat
20f50 63 68 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20  ch = 1;.        
20f60 20 20 73 71 6c 69 74 65 33 5f 6c 6f 67 28 53 51    sqlite3_log(SQ
20f70 4c 49 54 45 5f 53 43 48 45 4d 41 2c 20 22 73 71  LITE_SCHEMA, "sq
20f80 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 61  lite3changeset_a
20f90 70 70 6c 79 28 29 3a 20 22 0a 20 20 20 20 20 20  pply(): ".      
20fa0 20 20 20 20 20 20 20 20 22 70 72 69 6d 61 72 79          "primary
20fb0 20 6b 65 79 20 6d 69 73 6d 61 74 63 68 20 66 6f   key mismatch fo
20fc0 72 20 74 61 62 6c 65 20 25 73 22 2c 20 7a 54 61  r table %s", zTa
20fd0 62 0a 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20  b.          );. 
20fe0 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
20ff0 20 65 6c 73 65 20 69 66 28 20 0a 20 20 20 20 20   else if( .     
21000 20 20 20 20 20 20 20 28 72 63 20 3d 20 73 65 73         (rc = ses
21010 73 69 6f 6e 53 65 6c 65 63 74 52 6f 77 28 64 62  sionSelectRow(db
21020 2c 20 7a 54 61 62 2c 20 26 73 41 70 70 6c 79 29  , zTab, &sApply)
21030 29 0a 20 20 20 20 20 20 20 20 20 7c 7c 20 28 72  ).         || (r
21040 63 20 3d 20 73 65 73 73 69 6f 6e 55 70 64 61 74  c = sessionUpdat
21050 65 52 6f 77 28 64 62 2c 20 7a 54 61 62 2c 20 26  eRow(db, zTab, &
21060 73 41 70 70 6c 79 29 29 0a 20 20 20 20 20 20 20  sApply)).       
21070 20 20 7c 7c 20 28 72 63 20 3d 20 73 65 73 73 69    || (rc = sessi
21080 6f 6e 44 65 6c 65 74 65 52 6f 77 28 64 62 2c 20  onDeleteRow(db, 
21090 7a 54 61 62 2c 20 26 73 41 70 70 6c 79 29 29 0a  zTab, &sApply)).
210a0 20 20 20 20 20 20 20 20 20 7c 7c 20 28 72 63 20           || (rc 
210b0 3d 20 73 65 73 73 69 6f 6e 49 6e 73 65 72 74 52  = sessionInsertR
210c0 6f 77 28 64 62 2c 20 7a 54 61 62 2c 20 26 73 41  ow(db, zTab, &sA
210d0 70 70 6c 79 29 29 0a 20 20 20 20 20 20 20 20 29  pply)).        )
210e0 7b 0a 20 20 20 20 20 20 20 20 20 20 62 72 65 61  {.          brea
210f0 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  k;.        }.   
21100 20 20 20 20 20 6e 54 61 62 20 3d 20 73 71 6c 69       nTab = sqli
21110 74 65 33 53 74 72 6c 65 6e 33 30 28 7a 54 61 62  te3Strlen30(zTab
21120 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
21130 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 65 72  ..    /* If ther
21140 65 20 69 73 20 61 20 73 63 68 65 6d 61 20 6d 69  e is a schema mi
21150 73 6d 61 74 63 68 20 6f 6e 20 74 68 65 20 63 75  smatch on the cu
21160 72 72 65 6e 74 20 74 61 62 6c 65 2c 20 70 72 6f  rrent table, pro
21170 63 65 65 64 20 74 6f 20 74 68 65 0a 20 20 20 20  ceed to the.    
21180 2a 2a 20 6e 65 78 74 20 63 68 61 6e 67 65 2e 20  ** next change. 
21190 41 20 6c 6f 67 20 6d 65 73 73 61 67 65 20 68 61  A log message ha
211a0 73 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 69  s already been i
211b0 73 73 75 65 64 2e 20 2a 2f 0a 20 20 20 20 69 66  ssued. */.    if
211c0 28 20 73 63 68 65 6d 61 4d 69 73 6d 61 74 63 68  ( schemaMismatch
211d0 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 0a 20 20   ) continue;..  
211e0 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 41 70    rc = sessionAp
211f0 70 6c 79 4f 6e 65 57 69 74 68 52 65 74 72 79 28  plyOneWithRetry(
21200 64 62 2c 20 70 49 74 65 72 2c 20 26 73 41 70 70  db, pIter, &sApp
21210 6c 79 2c 20 78 43 6f 6e 66 6c 69 63 74 2c 20 70  ly, xConflict, p
21220 43 74 78 29 3b 0a 20 20 7d 0a 0a 20 20 62 50 61  Ctx);.  }..  bPa
21230 74 63 68 73 65 74 20 3d 20 70 49 74 65 72 2d 3e  tchset = pIter->
21240 62 50 61 74 63 68 73 65 74 3b 0a 20 20 69 66 28  bPatchset;.  if(
21250 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
21260 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
21270 65 33 63 68 61 6e 67 65 73 65 74 5f 66 69 6e 61  e3changeset_fina
21280 6c 69 7a 65 28 70 49 74 65 72 29 3b 0a 20 20 7d  lize(pIter);.  }
21290 65 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69 74 65  else{.    sqlite
212a0 33 63 68 61 6e 67 65 73 65 74 5f 66 69 6e 61 6c  3changeset_final
212b0 69 7a 65 28 70 49 74 65 72 29 3b 0a 20 20 7d 0a  ize(pIter);.  }.
212c0 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
212d0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
212e0 20 73 65 73 73 69 6f 6e 52 65 74 72 79 43 6f 6e   sessionRetryCon
212f0 73 74 72 61 69 6e 74 73 28 64 62 2c 20 62 50 61  straints(db, bPa
21300 74 63 68 73 65 74 2c 20 7a 54 61 62 2c 20 26 73  tchset, zTab, &s
21310 41 70 70 6c 79 2c 20 78 43 6f 6e 66 6c 69 63 74  Apply, xConflict
21320 2c 20 70 43 74 78 29 3b 0a 20 20 7d 0a 0a 20 20  , pCtx);.  }..  
21330 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
21340 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 46 6b  K ){.    int nFk
21350 2c 20 6e 6f 74 55 73 65 64 3b 0a 20 20 20 20 73  , notUsed;.    s
21360 71 6c 69 74 65 33 5f 64 62 5f 73 74 61 74 75 73  qlite3_db_status
21370 28 64 62 2c 20 53 51 4c 49 54 45 5f 44 42 53 54  (db, SQLITE_DBST
21380 41 54 55 53 5f 44 45 46 45 52 52 45 44 5f 46 4b  ATUS_DEFERRED_FK
21390 53 2c 20 26 6e 46 6b 2c 20 26 6e 6f 74 55 73 65  S, &nFk, &notUse
213a0 64 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 6e  d, 0);.    if( n
213b0 46 6b 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 69  Fk!=0 ){.      i
213c0 6e 74 20 72 65 73 20 3d 20 53 51 4c 49 54 45 5f  nt res = SQLITE_
213d0 43 48 41 4e 47 45 53 45 54 5f 41 42 4f 52 54 3b  CHANGESET_ABORT;
213e0 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 63  .      sqlite3_c
213f0 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 73 49  hangeset_iter sI
21400 74 65 72 3b 0a 20 20 20 20 20 20 6d 65 6d 73 65  ter;.      memse
21410 74 28 26 73 49 74 65 72 2c 20 30 2c 20 73 69 7a  t(&sIter, 0, siz
21420 65 6f 66 28 73 49 74 65 72 29 29 3b 0a 20 20 20  eof(sIter));.   
21430 20 20 20 73 49 74 65 72 2e 6e 43 6f 6c 20 3d 20     sIter.nCol = 
21440 6e 46 6b 3b 0a 20 20 20 20 20 20 72 65 73 20 3d  nFk;.      res =
21450 20 78 43 6f 6e 66 6c 69 63 74 28 70 43 74 78 2c   xConflict(pCtx,
21460 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45   SQLITE_CHANGESE
21470 54 5f 46 4f 52 45 49 47 4e 5f 4b 45 59 2c 20 26  T_FOREIGN_KEY, &
21480 73 49 74 65 72 29 3b 0a 20 20 20 20 20 20 69 66  sIter);.      if
21490 28 20 72 65 73 21 3d 53 51 4c 49 54 45 5f 43 48  ( res!=SQLITE_CH
214a0 41 4e 47 45 53 45 54 5f 4f 4d 49 54 20 29 7b 0a  ANGESET_OMIT ){.
214b0 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
214c0 49 54 45 5f 43 4f 4e 53 54 52 41 49 4e 54 3b 0a  ITE_CONSTRAINT;.
214d0 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
214e0 7d 0a 20 20 73 71 6c 69 74 65 33 5f 65 78 65 63  }.  sqlite3_exec
214f0 28 64 62 2c 20 22 50 52 41 47 4d 41 20 64 65 66  (db, "PRAGMA def
21500 65 72 5f 66 6f 72 65 69 67 6e 5f 6b 65 79 73 20  er_foreign_keys 
21510 3d 20 30 22 2c 20 30 2c 20 30 2c 20 30 29 3b 0a  = 0", 0, 0, 0);.
21520 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
21530 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
21540 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 64 62   sqlite3_exec(db
21550 2c 20 22 52 45 4c 45 41 53 45 20 63 68 61 6e 67  , "RELEASE chang
21560 65 73 65 74 5f 61 70 70 6c 79 22 2c 20 30 2c 20  eset_apply", 0, 
21570 30 2c 20 30 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  0, 0);.  }else{.
21580 20 20 20 20 73 71 6c 69 74 65 33 5f 65 78 65 63      sqlite3_exec
21590 28 64 62 2c 20 22 52 4f 4c 4c 42 41 43 4b 20 54  (db, "ROLLBACK T
215a0 4f 20 63 68 61 6e 67 65 73 65 74 5f 61 70 70 6c  O changeset_appl
215b0 79 22 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20  y", 0, 0, 0);.  
215c0 20 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 64    sqlite3_exec(d
215d0 62 2c 20 22 52 45 4c 45 41 53 45 20 63 68 61 6e  b, "RELEASE chan
215e0 67 65 73 65 74 5f 61 70 70 6c 79 22 2c 20 30 2c  geset_apply", 0,
215f0 20 30 2c 20 30 29 3b 0a 20 20 7d 0a 0a 20 20 73   0, 0);.  }..  s
21600 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
21610 73 41 70 70 6c 79 2e 70 49 6e 73 65 72 74 29 3b  sApply.pInsert);
21620 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c  .  sqlite3_final
21630 69 7a 65 28 73 41 70 70 6c 79 2e 70 44 65 6c 65  ize(sApply.pDele
21640 74 65 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  te);.  sqlite3_f
21650 69 6e 61 6c 69 7a 65 28 73 41 70 70 6c 79 2e 70  inalize(sApply.p
21660 55 70 64 61 74 65 29 3b 0a 20 20 73 71 6c 69 74  Update);.  sqlit
21670 65 33 5f 66 69 6e 61 6c 69 7a 65 28 73 41 70 70  e3_finalize(sApp
21680 6c 79 2e 70 53 65 6c 65 63 74 29 3b 0a 20 20 73  ly.pSelect);.  s
21690 71 6c 69 74 65 33 5f 66 72 65 65 28 28 63 68 61  qlite3_free((cha
216a0 72 2a 29 73 41 70 70 6c 79 2e 61 7a 43 6f 6c 29  r*)sApply.azCol)
216b0 3b 20 20 2f 2a 20 63 61 73 74 20 77 6f 72 6b 73  ;  /* cast works
216c0 20 61 72 6f 75 6e 64 20 56 43 2b 2b 20 62 75 67   around VC++ bug
216d0 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 72   */.  sqlite3_fr
216e0 65 65 28 28 63 68 61 72 2a 29 73 41 70 70 6c 79  ee((char*)sApply
216f0 2e 63 6f 6e 73 74 72 61 69 6e 74 73 2e 61 42 75  .constraints.aBu
21700 66 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75  f);.  sqlite3_mu
21710 74 65 78 5f 6c 65 61 76 65 28 73 71 6c 69 74 65  tex_leave(sqlite
21720 33 5f 64 62 5f 6d 75 74 65 78 28 64 62 29 29 3b  3_db_mutex(db));
21730 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
21740 0a 2f 2a 0a 2a 2a 20 41 70 70 6c 79 20 74 68 65  ./*.** Apply the
21750 20 63 68 61 6e 67 65 73 65 74 20 70 61 73 73 65   changeset passe
21760 64 20 76 69 61 20 70 43 68 61 6e 67 65 73 65 74  d via pChangeset
21770 2f 6e 43 68 61 6e 67 65 73 65 74 20 74 6f 20 74  /nChangeset to t
21780 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65  he main database
21790 0a 2a 2a 20 61 74 74 61 63 68 65 64 20 74 6f 20  .** attached to 
217a0 68 61 6e 64 6c 65 20 22 64 62 22 2e 20 49 6e 76  handle "db". Inv
217b0 6f 6b 65 20 74 68 65 20 73 75 70 70 6c 69 65 64  oke the supplied
217c0 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65   conflict handle
217d0 72 20 63 61 6c 6c 62 61 63 6b 0a 2a 2a 20 74 6f  r callback.** to
217e0 20 72 65 73 6f 6c 76 65 20 61 6e 79 20 63 6f 6e   resolve any con
217f0 66 6c 69 63 74 73 20 65 6e 63 6f 75 6e 74 65 72  flicts encounter
21800 65 64 20 77 68 69 6c 65 20 61 70 70 6c 79 69 6e  ed while applyin
21810 67 20 74 68 65 20 63 68 61 6e 67 65 2e 0a 2a 2f  g the change..*/
21820 0a 69 6e 74 20 73 71 6c 69 74 65 33 63 68 61 6e  .int sqlite3chan
21830 67 65 73 65 74 5f 61 70 70 6c 79 28 0a 20 20 73  geset_apply(.  s
21840 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20  qlite3 *db,     
21850 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
21860 2a 20 41 70 70 6c 79 20 63 68 61 6e 67 65 20 74  * Apply change t
21870 6f 20 22 6d 61 69 6e 22 20 64 62 20 6f 66 20 74  o "main" db of t
21880 68 69 73 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20  his handle */.  
21890 69 6e 74 20 6e 43 68 61 6e 67 65 73 65 74 2c 20  int nChangeset, 
218a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
218b0 2f 2a 20 53 69 7a 65 20 6f 66 20 63 68 61 6e 67  /* Size of chang
218c0 65 73 65 74 20 69 6e 20 62 79 74 65 73 20 2a 2f  eset in bytes */
218d0 0a 20 20 76 6f 69 64 20 2a 70 43 68 61 6e 67 65  .  void *pChange
218e0 73 65 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  set,            
218f0 20 20 20 2f 2a 20 43 68 61 6e 67 65 73 65 74 20     /* Changeset 
21900 62 6c 6f 62 20 2a 2f 0a 20 20 69 6e 74 28 2a 78  blob */.  int(*x
21910 46 69 6c 74 65 72 29 28 0a 20 20 20 20 76 6f 69  Filter)(.    voi
21920 64 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20  d *pCtx,        
21930 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
21940 70 79 20 6f 66 20 73 69 78 74 68 20 61 72 67 20  py of sixth arg 
21950 74 6f 20 5f 61 70 70 6c 79 28 29 20 2a 2f 0a 20  to _apply() */. 
21960 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
21970 54 61 62 20 20 20 20 20 20 20 20 20 20 20 20 20  Tab             
21980 20 2f 2a 20 54 61 62 6c 65 20 6e 61 6d 65 20 2a   /* Table name *
21990 2f 0a 20 20 29 2c 0a 20 20 69 6e 74 28 2a 78 43  /.  ),.  int(*xC
219a0 6f 6e 66 6c 69 63 74 29 28 0a 20 20 20 20 76 6f  onflict)(.    vo
219b0 69 64 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20  id *pCtx,       
219c0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
219d0 6f 70 79 20 6f 66 20 66 69 66 74 68 20 61 72 67  opy of fifth arg
219e0 20 74 6f 20 5f 61 70 70 6c 79 28 29 20 2a 2f 0a   to _apply() */.
219f0 20 20 20 20 69 6e 74 20 65 43 6f 6e 66 6c 69 63      int eConflic
21a00 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
21a10 20 20 2f 2a 20 44 41 54 41 2c 20 4d 49 53 53 49    /* DATA, MISSI
21a20 4e 47 2c 20 43 4f 4e 46 4c 49 43 54 2c 20 43 4f  NG, CONFLICT, CO
21a30 4e 53 54 52 41 49 4e 54 20 2a 2f 0a 20 20 20 20  NSTRAINT */.    
21a40 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65  sqlite3_changese
21a50 74 5f 69 74 65 72 20 2a 70 20 20 20 20 20 2f 2a  t_iter *p     /*
21a60 20 48 61 6e 64 6c 65 20 64 65 73 63 72 69 62 69   Handle describi
21a70 6e 67 20 63 68 61 6e 67 65 20 61 6e 64 20 63 6f  ng change and co
21a80 6e 66 6c 69 63 74 20 2a 2f 0a 20 20 29 2c 0a 20  nflict */.  ),. 
21a90 20 76 6f 69 64 20 2a 70 43 74 78 20 20 20 20 20   void *pCtx     
21aa0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21ab0 20 2f 2a 20 46 69 72 73 74 20 61 72 67 75 6d 65   /* First argume
21ac0 6e 74 20 70 61 73 73 65 64 20 74 6f 20 78 43 6f  nt passed to xCo
21ad0 6e 66 6c 69 63 74 20 2a 2f 0a 29 7b 0a 20 20 73  nflict */.){.  s
21ae0 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74  qlite3_changeset
21af0 5f 69 74 65 72 20 2a 70 49 74 65 72 3b 20 20 2f  _iter *pIter;  /
21b00 2a 20 49 74 65 72 61 74 6f 72 20 74 6f 20 73 6b  * Iterator to sk
21b10 69 70 20 74 68 72 6f 75 67 68 20 63 68 61 6e 67  ip through chang
21b20 65 73 65 74 20 2a 2f 20 20 0a 20 20 69 6e 74 20  eset */  .  int 
21b30 72 63 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e  rc = sqlite3chan
21b40 67 65 73 65 74 5f 73 74 61 72 74 28 26 70 49 74  geset_start(&pIt
21b50 65 72 2c 20 6e 43 68 61 6e 67 65 73 65 74 2c 20  er, nChangeset, 
21b60 70 43 68 61 6e 67 65 73 65 74 29 3b 0a 20 20 69  pChangeset);.  i
21b70 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
21b80 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 65 73   ){.    rc = ses
21b90 73 69 6f 6e 43 68 61 6e 67 65 73 65 74 41 70 70  sionChangesetApp
21ba0 6c 79 28 64 62 2c 20 70 49 74 65 72 2c 20 78 46  ly(db, pIter, xF
21bb0 69 6c 74 65 72 2c 20 78 43 6f 6e 66 6c 69 63 74  ilter, xConflict
21bc0 2c 20 70 43 74 78 29 3b 0a 20 20 7d 0a 20 20 72  , pCtx);.  }.  r
21bd0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
21be0 2a 2a 20 41 70 70 6c 79 20 74 68 65 20 63 68 61  ** Apply the cha
21bf0 6e 67 65 73 65 74 20 70 61 73 73 65 64 20 76 69  ngeset passed vi
21c00 61 20 78 49 6e 70 75 74 2f 70 49 6e 20 74 6f 20  a xInput/pIn to 
21c10 74 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73  the main databas
21c20 65 0a 2a 2a 20 61 74 74 61 63 68 65 64 20 74 6f  e.** attached to
21c30 20 68 61 6e 64 6c 65 20 22 64 62 22 2e 20 49 6e   handle "db". In
21c40 76 6f 6b 65 20 74 68 65 20 73 75 70 70 6c 69 65  voke the supplie
21c50 64 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c  d conflict handl
21c60 65 72 20 63 61 6c 6c 62 61 63 6b 0a 2a 2a 20 74  er callback.** t
21c70 6f 20 72 65 73 6f 6c 76 65 20 61 6e 79 20 63 6f  o resolve any co
21c80 6e 66 6c 69 63 74 73 20 65 6e 63 6f 75 6e 74 65  nflicts encounte
21c90 72 65 64 20 77 68 69 6c 65 20 61 70 70 6c 79 69  red while applyi
21ca0 6e 67 20 74 68 65 20 63 68 61 6e 67 65 2e 0a 2a  ng the change..*
21cb0 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 63 68 61  /.int sqlite3cha
21cc0 6e 67 65 73 65 74 5f 61 70 70 6c 79 5f 73 74 72  ngeset_apply_str
21cd0 6d 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  m(.  sqlite3 *db
21ce0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
21cf0 20 20 20 20 20 2f 2a 20 41 70 70 6c 79 20 63 68       /* Apply ch
21d00 61 6e 67 65 20 74 6f 20 22 6d 61 69 6e 22 20 64  ange to "main" d
21d10 62 20 6f 66 20 74 68 69 73 20 68 61 6e 64 6c 65  b of this handle
21d20 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 49 6e 70   */.  int (*xInp
21d30 75 74 29 28 76 6f 69 64 20 2a 70 49 6e 2c 20 76  ut)(void *pIn, v
21d40 6f 69 64 20 2a 70 44 61 74 61 2c 20 69 6e 74 20  oid *pData, int 
21d50 2a 70 6e 44 61 74 61 29 2c 20 2f 2a 20 49 6e 70  *pnData), /* Inp
21d60 75 74 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20  ut function */. 
21d70 20 76 6f 69 64 20 2a 70 49 6e 2c 20 20 20 20 20   void *pIn,     
21d80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21d90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21da0 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 61 72       /* First ar
21db0 67 20 66 6f 72 20 78 49 6e 70 75 74 20 2a 2f 0a  g for xInput */.
21dc0 20 20 69 6e 74 28 2a 78 46 69 6c 74 65 72 29 28    int(*xFilter)(
21dd0 0a 20 20 20 20 76 6f 69 64 20 2a 70 43 74 78 2c  .    void *pCtx,
21de0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21df0 20 20 20 2f 2a 20 43 6f 70 79 20 6f 66 20 73 69     /* Copy of si
21e00 78 74 68 20 61 72 67 20 74 6f 20 5f 61 70 70 6c  xth arg to _appl
21e10 79 28 29 20 2a 2f 0a 20 20 20 20 63 6f 6e 73 74  y() */.    const
21e20 20 63 68 61 72 20 2a 7a 54 61 62 20 20 20 20 20   char *zTab     
21e30 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62 6c           /* Tabl
21e40 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 29 2c 0a 20  e name */.  ),. 
21e50 20 69 6e 74 28 2a 78 43 6f 6e 66 6c 69 63 74 29   int(*xConflict)
21e60 28 0a 20 20 20 20 76 6f 69 64 20 2a 70 43 74 78  (.    void *pCtx
21e70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
21e80 20 20 20 20 2f 2a 20 43 6f 70 79 20 6f 66 20 73      /* Copy of s
21e90 69 78 74 68 20 61 72 67 20 74 6f 20 5f 61 70 70  ixth arg to _app
21ea0 6c 79 28 29 20 2a 2f 0a 20 20 20 20 69 6e 74 20  ly() */.    int 
21eb0 65 43 6f 6e 66 6c 69 63 74 2c 20 20 20 20 20 20  eConflict,      
21ec0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 41 54            /* DAT
21ed0 41 2c 20 4d 49 53 53 49 4e 47 2c 20 43 4f 4e 46  A, MISSING, CONF
21ee0 4c 49 43 54 2c 20 43 4f 4e 53 54 52 41 49 4e 54  LICT, CONSTRAINT
21ef0 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   */.    sqlite3_
21f00 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a  changeset_iter *
21f10 70 20 20 20 20 20 2f 2a 20 48 61 6e 64 6c 65 20  p     /* Handle 
21f20 64 65 73 63 72 69 62 69 6e 67 20 63 68 61 6e 67  describing chang
21f30 65 20 61 6e 64 20 63 6f 6e 66 6c 69 63 74 20 2a  e and conflict *
21f40 2f 0a 20 20 29 2c 0a 20 20 76 6f 69 64 20 2a 70  /.  ),.  void *p
21f50 43 74 78 20 20 20 20 20 20 20 20 20 20 20 20 20  Ctx             
21f60 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73           /* Firs
21f70 74 20 61 72 67 75 6d 65 6e 74 20 70 61 73 73 65  t argument passe
21f80 64 20 74 6f 20 78 43 6f 6e 66 6c 69 63 74 20 2a  d to xConflict *
21f90 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 63  /.){.  sqlite3_c
21fa0 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a 70  hangeset_iter *p
21fb0 49 74 65 72 3b 20 20 2f 2a 20 49 74 65 72 61 74  Iter;  /* Iterat
21fc0 6f 72 20 74 6f 20 73 6b 69 70 20 74 68 72 6f 75  or to skip throu
21fd0 67 68 20 63 68 61 6e 67 65 73 65 74 20 2a 2f 20  gh changeset */ 
21fe0 20 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c   .  int rc = sql
21ff0 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 73 74  ite3changeset_st
22000 61 72 74 5f 73 74 72 6d 28 26 70 49 74 65 72 2c  art_strm(&pIter,
22010 20 78 49 6e 70 75 74 2c 20 70 49 6e 29 3b 0a 20   xInput, pIn);. 
22020 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
22030 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73  OK ){.    rc = s
22040 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65 74 41  essionChangesetA
22050 70 70 6c 79 28 64 62 2c 20 70 49 74 65 72 2c 20  pply(db, pIter, 
22060 78 46 69 6c 74 65 72 2c 20 78 43 6f 6e 66 6c 69  xFilter, xConfli
22070 63 74 2c 20 70 43 74 78 29 3b 0a 20 20 7d 0a 20  ct, pCtx);.  }. 
22080 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
22090 2a 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 63 68 61  *.** sqlite3_cha
220a0 6e 67 65 67 72 6f 75 70 20 68 61 6e 64 6c 65 2e  ngegroup handle.
220b0 0a 2a 2f 0a 73 74 72 75 63 74 20 73 71 6c 69 74  .*/.struct sqlit
220c0 65 33 5f 63 68 61 6e 67 65 67 72 6f 75 70 20 7b  e3_changegroup {
220d0 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
220e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
220f0 20 20 20 2f 2a 20 45 72 72 6f 72 20 63 6f 64 65     /* Error code
22100 20 2a 2f 0a 20 20 69 6e 74 20 62 50 61 74 63 68   */.  int bPatch
22110 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
22120 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f        /* True to
22130 20 61 63 63 75 6d 75 6c 61 74 65 20 70 61 74 63   accumulate patc
22140 68 73 65 74 73 20 2a 2f 0a 20 20 53 65 73 73 69  hsets */.  Sessi
22150 6f 6e 54 61 62 6c 65 20 2a 70 4c 69 73 74 3b 20  onTable *pList; 
22160 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69             /* Li
22170 73 74 20 6f 66 20 74 61 62 6c 65 73 20 69 6e 20  st of tables in 
22180 63 75 72 72 65 6e 74 20 70 61 74 63 68 20 2a 2f  current patch */
22190 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  .};../*.** This 
221a0 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
221b0 65 64 20 74 6f 20 6d 65 72 67 65 20 74 77 6f 20  ed to merge two 
221c0 63 68 61 6e 67 65 73 20 74 6f 20 74 68 65 20 73  changes to the s
221d0 61 6d 65 20 72 6f 77 20 74 6f 67 65 74 68 65 72  ame row together
221e0 20 61 73 0a 2a 2a 20 70 61 72 74 20 6f 66 20 61   as.** part of a
221f0 6e 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  n sqlite3changes
22200 65 74 5f 63 6f 6e 63 61 74 28 29 20 6f 70 65 72  et_concat() oper
22210 61 74 69 6f 6e 2e 20 41 20 6e 65 77 20 63 68 61  ation. A new cha
22220 6e 67 65 20 6f 62 6a 65 63 74 20 69 73 0a 2a 2a  nge object is.**
22230 20 61 6c 6c 6f 63 61 74 65 64 20 61 6e 64 20 61   allocated and a
22240 20 70 6f 69 6e 74 65 72 20 74 6f 20 69 74 20 73   pointer to it s
22250 74 6f 72 65 64 20 69 6e 20 2a 70 70 4e 65 77 2e  tored in *ppNew.
22260 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73  .*/.static int s
22270 65 73 73 69 6f 6e 43 68 61 6e 67 65 4d 65 72 67  essionChangeMerg
22280 65 28 0a 20 20 53 65 73 73 69 6f 6e 54 61 62 6c  e(.  SessionTabl
22290 65 20 2a 70 54 61 62 2c 20 20 20 20 20 20 20 20  e *pTab,        
222a0 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20 73 74       /* Table st
222b0 72 75 63 74 75 72 65 20 2a 2f 0a 20 20 69 6e 74  ructure */.  int
222c0 20 62 50 61 74 63 68 73 65 74 2c 20 20 20 20 20   bPatchset,     
222d0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
222e0 54 72 75 65 20 66 6f 72 20 70 61 74 63 68 73 65  True for patchse
222f0 74 73 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 43  ts */.  SessionC
22300 68 61 6e 67 65 20 2a 70 45 78 69 73 74 2c 20 20  hange *pExist,  
22310 20 20 20 20 20 20 20 20 2f 2a 20 45 78 69 73 74          /* Exist
22320 69 6e 67 20 63 68 61 6e 67 65 20 2a 2f 0a 20 20  ing change */.  
22330 69 6e 74 20 6f 70 32 2c 20 20 20 20 20 20 20 20  int op2,        
22340 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22350 2f 2a 20 53 65 63 6f 6e 64 20 63 68 61 6e 67 65  /* Second change
22360 20 6f 70 65 72 61 74 69 6f 6e 20 2a 2f 0a 20 20   operation */.  
22370 69 6e 74 20 62 49 6e 64 69 72 65 63 74 2c 20 20  int bIndirect,  
22380 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22390 2f 2a 20 54 72 75 65 20 69 66 20 73 65 63 6f 6e  /* True if secon
223a0 64 20 63 68 61 6e 67 65 20 69 73 20 69 6e 64 69  d change is indi
223b0 72 65 63 74 20 2a 2f 0a 20 20 75 38 20 2a 61 52  rect */.  u8 *aR
223c0 65 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ec,             
223d0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 63            /* Sec
223e0 6f 6e 64 20 63 68 61 6e 67 65 20 72 65 63 6f 72  ond change recor
223f0 64 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 63 2c  d */.  int nRec,
22400 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22410 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
22420 20 6f 66 20 62 79 74 65 73 20 69 6e 20 61 52 65   of bytes in aRe
22430 63 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 43 68  c */.  SessionCh
22440 61 6e 67 65 20 2a 2a 70 70 4e 65 77 20 20 20 20  ange **ppNew    
22450 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4d         /* OUT: M
22460 65 72 67 65 64 20 63 68 61 6e 67 65 20 2a 2f 0a  erged change */.
22470 29 7b 0a 20 20 53 65 73 73 69 6f 6e 43 68 61 6e  ){.  SessionChan
22480 67 65 20 2a 70 4e 65 77 20 3d 20 30 3b 0a 0a 20  ge *pNew = 0;.. 
22490 20 69 66 28 20 21 70 45 78 69 73 74 20 29 7b 0a   if( !pExist ){.
224a0 20 20 20 20 70 4e 65 77 20 3d 20 28 53 65 73 73      pNew = (Sess
224b0 69 6f 6e 43 68 61 6e 67 65 20 2a 29 73 71 6c 69  ionChange *)sqli
224c0 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
224d0 66 28 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 29  f(SessionChange)
224e0 20 2b 20 6e 52 65 63 29 3b 0a 20 20 20 20 69 66   + nRec);.    if
224f0 28 20 21 70 4e 65 77 20 29 7b 0a 20 20 20 20 20  ( !pNew ){.     
22500 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
22510 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20  OMEM;.    }.    
22520 6d 65 6d 73 65 74 28 70 4e 65 77 2c 20 30 2c 20  memset(pNew, 0, 
22530 73 69 7a 65 6f 66 28 53 65 73 73 69 6f 6e 43 68  sizeof(SessionCh
22540 61 6e 67 65 29 29 3b 0a 20 20 20 20 70 4e 65 77  ange));.    pNew
22550 2d 3e 6f 70 20 3d 20 6f 70 32 3b 0a 20 20 20 20  ->op = op2;.    
22560 70 4e 65 77 2d 3e 62 49 6e 64 69 72 65 63 74 20  pNew->bIndirect 
22570 3d 20 62 49 6e 64 69 72 65 63 74 3b 0a 20 20 20  = bIndirect;.   
22580 20 70 4e 65 77 2d 3e 6e 52 65 63 6f 72 64 20 3d   pNew->nRecord =
22590 20 6e 52 65 63 3b 0a 20 20 20 20 70 4e 65 77 2d   nRec;.    pNew-
225a0 3e 61 52 65 63 6f 72 64 20 3d 20 28 75 38 2a 29  >aRecord = (u8*)
225b0 26 70 4e 65 77 5b 31 5d 3b 0a 20 20 20 20 6d 65  &pNew[1];.    me
225c0 6d 63 70 79 28 70 4e 65 77 2d 3e 61 52 65 63 6f  mcpy(pNew->aReco
225d0 72 64 2c 20 61 52 65 63 2c 20 6e 52 65 63 29 3b  rd, aRec, nRec);
225e0 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e  .  }else{.    in
225f0 74 20 6f 70 31 20 3d 20 70 45 78 69 73 74 2d 3e  t op1 = pExist->
22600 6f 70 3b 0a 0a 20 20 20 20 2f 2a 20 0a 20 20 20  op;..    /* .   
22610 20 2a 2a 20 20 20 6f 70 31 3d 49 4e 53 45 52 54   **   op1=INSERT
22620 2c 20 6f 70 32 3d 49 4e 53 45 52 54 20 20 20 20  , op2=INSERT    
22630 20 20 2d 3e 20 20 20 20 20 20 55 6e 73 75 70 70    ->      Unsupp
22640 6f 72 74 65 64 2e 20 44 69 73 63 61 72 64 20 6f  orted. Discard o
22650 70 32 2e 0a 20 20 20 20 2a 2a 20 20 20 6f 70 31  p2..    **   op1
22660 3d 49 4e 53 45 52 54 2c 20 6f 70 32 3d 55 50 44  =INSERT, op2=UPD
22670 41 54 45 20 20 20 20 20 20 2d 3e 20 20 20 20 20  ATE      ->     
22680 20 49 4e 53 45 52 54 2e 0a 20 20 20 20 2a 2a 20   INSERT..    ** 
22690 20 20 6f 70 31 3d 49 4e 53 45 52 54 2c 20 6f 70    op1=INSERT, op
226a0 32 3d 44 45 4c 45 54 45 20 20 20 20 20 20 2d 3e  2=DELETE      ->
226b0 20 20 20 20 20 20 28 6e 6f 6e 65 29 0a 20 20 20        (none).   
226c0 20 2a 2a 0a 20 20 20 20 2a 2a 20 20 20 6f 70 31   **.    **   op1
226d0 3d 55 50 44 41 54 45 2c 20 6f 70 32 3d 49 4e 53  =UPDATE, op2=INS
226e0 45 52 54 20 20 20 20 20 20 2d 3e 20 20 20 20 20  ERT      ->     
226f0 20 55 6e 73 75 70 70 6f 72 74 65 64 2e 20 44 69   Unsupported. Di
22700 73 63 61 72 64 20 6f 70 32 2e 0a 20 20 20 20 2a  scard op2..    *
22710 2a 20 20 20 6f 70 31 3d 55 50 44 41 54 45 2c 20  *   op1=UPDATE, 
22720 6f 70 32 3d 55 50 44 41 54 45 20 20 20 20 20 20  op2=UPDATE      
22730 2d 3e 20 20 20 20 20 20 55 50 44 41 54 45 2e 0a  ->      UPDATE..
22740 20 20 20 20 2a 2a 20 20 20 6f 70 31 3d 55 50 44      **   op1=UPD
22750 41 54 45 2c 20 6f 70 32 3d 44 45 4c 45 54 45 20  ATE, op2=DELETE 
22760 20 20 20 20 20 2d 3e 20 20 20 20 20 20 44 45 4c       ->      DEL
22770 45 54 45 2e 0a 20 20 20 20 2a 2a 0a 20 20 20 20  ETE..    **.    
22780 2a 2a 20 20 20 6f 70 31 3d 44 45 4c 45 54 45 2c  **   op1=DELETE,
22790 20 6f 70 32 3d 49 4e 53 45 52 54 20 20 20 20 20   op2=INSERT     
227a0 20 2d 3e 20 20 20 20 20 20 55 50 44 41 54 45 2e   ->      UPDATE.
227b0 0a 20 20 20 20 2a 2a 20 20 20 6f 70 31 3d 44 45  .    **   op1=DE
227c0 4c 45 54 45 2c 20 6f 70 32 3d 55 50 44 41 54 45  LETE, op2=UPDATE
227d0 20 20 20 20 20 20 2d 3e 20 20 20 20 20 20 55 6e        ->      Un
227e0 73 75 70 70 6f 72 74 65 64 2e 20 44 69 73 63 61  supported. Disca
227f0 72 64 20 6f 70 32 2e 0a 20 20 20 20 2a 2a 20 20  rd op2..    **  
22800 20 6f 70 31 3d 44 45 4c 45 54 45 2c 20 6f 70 32   op1=DELETE, op2
22810 3d 44 45 4c 45 54 45 20 20 20 20 20 20 2d 3e 20  =DELETE      -> 
22820 20 20 20 20 20 55 6e 73 75 70 70 6f 72 74 65 64       Unsupported
22830 2e 20 44 69 73 63 61 72 64 20 6f 70 32 2e 0a 20  . Discard op2.. 
22840 20 20 20 2a 2f 20 20 20 0a 20 20 20 20 69 66 28     */   .    if(
22850 20 28 6f 70 31 3d 3d 53 51 4c 49 54 45 5f 49 4e   (op1==SQLITE_IN
22860 53 45 52 54 20 26 26 20 6f 70 32 3d 3d 53 51 4c  SERT && op2==SQL
22870 49 54 45 5f 49 4e 53 45 52 54 29 0a 20 20 20 20  ITE_INSERT).    
22880 20 7c 7c 20 28 6f 70 31 3d 3d 53 51 4c 49 54 45   || (op1==SQLITE
22890 5f 55 50 44 41 54 45 20 26 26 20 6f 70 32 3d 3d  _UPDATE && op2==
228a0 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 29 0a 20  SQLITE_INSERT). 
228b0 20 20 20 20 7c 7c 20 28 6f 70 31 3d 3d 53 51 4c      || (op1==SQL
228c0 49 54 45 5f 44 45 4c 45 54 45 20 26 26 20 6f 70  ITE_DELETE && op
228d0 32 3d 3d 53 51 4c 49 54 45 5f 55 50 44 41 54 45  2==SQLITE_UPDATE
228e0 29 0a 20 20 20 20 20 7c 7c 20 28 6f 70 31 3d 3d  ).     || (op1==
228f0 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 20 26 26  SQLITE_DELETE &&
22900 20 6f 70 32 3d 3d 53 51 4c 49 54 45 5f 44 45 4c   op2==SQLITE_DEL
22910 45 54 45 29 0a 20 20 20 20 29 7b 0a 20 20 20 20  ETE).    ){.    
22920 20 20 70 4e 65 77 20 3d 20 70 45 78 69 73 74 3b    pNew = pExist;
22930 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 6f  .    }else if( o
22940 70 31 3d 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52  p1==SQLITE_INSER
22950 54 20 26 26 20 6f 70 32 3d 3d 53 51 4c 49 54 45  T && op2==SQLITE
22960 5f 44 45 4c 45 54 45 20 29 7b 0a 20 20 20 20 20  _DELETE ){.     
22970 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 45   sqlite3_free(pE
22980 78 69 73 74 29 3b 0a 20 20 20 20 20 20 61 73 73  xist);.      ass
22990 65 72 74 28 20 70 4e 65 77 3d 3d 30 20 29 3b 0a  ert( pNew==0 );.
229a0 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
229b0 20 75 38 20 2a 61 45 78 69 73 74 20 3d 20 70 45   u8 *aExist = pE
229c0 78 69 73 74 2d 3e 61 52 65 63 6f 72 64 3b 0a 20  xist->aRecord;. 
229d0 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a       int nByte;.
229e0 20 20 20 20 20 20 75 38 20 2a 61 43 73 72 3b 0a        u8 *aCsr;.
229f0 0a 20 20 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61  .      /* Alloca
22a00 74 65 20 61 20 6e 65 77 20 53 65 73 73 69 6f 6e  te a new Session
22a10 43 68 61 6e 67 65 20 6f 62 6a 65 63 74 2e 20 45  Change object. E
22a20 6e 73 75 72 65 20 74 68 61 74 20 74 68 65 20 61  nsure that the a
22a30 52 65 63 6f 72 64 5b 5d 0a 20 20 20 20 20 20 2a  Record[].      *
22a40 2a 20 62 75 66 66 65 72 20 6f 66 20 74 68 65 20  * buffer of the 
22a50 6e 65 77 20 6f 62 6a 65 63 74 20 69 73 20 6c 61  new object is la
22a60 72 67 65 20 65 6e 6f 75 67 68 20 74 6f 20 68 6f  rge enough to ho
22a70 6c 64 20 61 6e 79 20 72 65 63 6f 72 64 20 74 68  ld any record th
22a80 61 74 0a 20 20 20 20 20 20 2a 2a 20 6d 61 79 20  at.      ** may 
22a90 62 65 20 67 65 6e 65 72 61 74 65 64 20 62 79 20  be generated by 
22aa0 63 6f 6d 62 69 6e 69 6e 67 20 74 68 65 20 69 6e  combining the in
22ab0 70 75 74 20 72 65 63 6f 72 64 73 2e 20 20 2a 2f  put records.  */
22ac0 0a 20 20 20 20 20 20 6e 42 79 74 65 20 3d 20 73  .      nByte = s
22ad0 69 7a 65 6f 66 28 53 65 73 73 69 6f 6e 43 68 61  izeof(SessionCha
22ae0 6e 67 65 29 20 2b 20 70 45 78 69 73 74 2d 3e 6e  nge) + pExist->n
22af0 52 65 63 6f 72 64 20 2b 20 6e 52 65 63 3b 0a 20  Record + nRec;. 
22b00 20 20 20 20 20 70 4e 65 77 20 3d 20 28 53 65 73       pNew = (Ses
22b10 73 69 6f 6e 43 68 61 6e 67 65 20 2a 29 73 71 6c  sionChange *)sql
22b20 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74  ite3_malloc(nByt
22b30 65 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21 70  e);.      if( !p
22b40 4e 65 77 20 29 7b 0a 20 20 20 20 20 20 20 20 73  New ){.        s
22b50 71 6c 69 74 65 33 5f 66 72 65 65 28 70 45 78 69  qlite3_free(pExi
22b60 73 74 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74  st);.        ret
22b70 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
22b80 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
22b90 6d 65 6d 73 65 74 28 70 4e 65 77 2c 20 30 2c 20  memset(pNew, 0, 
22ba0 73 69 7a 65 6f 66 28 53 65 73 73 69 6f 6e 43 68  sizeof(SessionCh
22bb0 61 6e 67 65 29 29 3b 0a 20 20 20 20 20 20 70 4e  ange));.      pN
22bc0 65 77 2d 3e 62 49 6e 64 69 72 65 63 74 20 3d 20  ew->bIndirect = 
22bd0 28 62 49 6e 64 69 72 65 63 74 20 26 26 20 70 45  (bIndirect && pE
22be0 78 69 73 74 2d 3e 62 49 6e 64 69 72 65 63 74 29  xist->bIndirect)
22bf0 3b 0a 20 20 20 20 20 20 61 43 73 72 20 3d 20 70  ;.      aCsr = p
22c00 4e 65 77 2d 3e 61 52 65 63 6f 72 64 20 3d 20 28  New->aRecord = (
22c10 75 38 20 2a 29 26 70 4e 65 77 5b 31 5d 3b 0a 0a  u8 *)&pNew[1];..
22c20 20 20 20 20 20 20 69 66 28 20 6f 70 31 3d 3d 53        if( op1==S
22c30 51 4c 49 54 45 5f 49 4e 53 45 52 54 20 29 7b 20  QLITE_INSERT ){ 
22c40 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
22c50 4e 53 45 52 54 20 2b 20 55 50 44 41 54 45 20 2a  NSERT + UPDATE *
22c60 2f 0a 20 20 20 20 20 20 20 20 75 38 20 2a 61 31  /.        u8 *a1
22c70 20 3d 20 61 52 65 63 3b 0a 20 20 20 20 20 20 20   = aRec;.       
22c80 20 61 73 73 65 72 74 28 20 6f 70 32 3d 3d 53 51   assert( op2==SQ
22c90 4c 49 54 45 5f 55 50 44 41 54 45 20 29 3b 0a 20  LITE_UPDATE );. 
22ca0 20 20 20 20 20 20 20 70 4e 65 77 2d 3e 6f 70 20         pNew->op 
22cb0 3d 20 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 3b  = SQLITE_INSERT;
22cc0 0a 20 20 20 20 20 20 20 20 69 66 28 20 62 50 61  .        if( bPa
22cd0 74 63 68 73 65 74 3d 3d 30 20 29 20 73 65 73 73  tchset==0 ) sess
22ce0 69 6f 6e 53 6b 69 70 52 65 63 6f 72 64 28 26 61  ionSkipRecord(&a
22cf0 31 2c 20 70 54 61 62 2d 3e 6e 43 6f 6c 29 3b 0a  1, pTab->nCol);.
22d00 20 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 4d          sessionM
22d10 65 72 67 65 52 65 63 6f 72 64 28 26 61 43 73 72  ergeRecord(&aCsr
22d20 2c 20 70 54 61 62 2d 3e 6e 43 6f 6c 2c 20 61 45  , pTab->nCol, aE
22d30 78 69 73 74 2c 20 61 31 29 3b 0a 20 20 20 20 20  xist, a1);.     
22d40 20 7d 65 6c 73 65 20 69 66 28 20 6f 70 31 3d 3d   }else if( op1==
22d50 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 20 29 7b  SQLITE_DELETE ){
22d60 20 20 20 20 20 20 20 2f 2a 20 44 45 4c 45 54 45         /* DELETE
22d70 20 2b 20 49 4e 53 45 52 54 20 2a 2f 0a 20 20 20   + INSERT */.   
22d80 20 20 20 20 20 61 73 73 65 72 74 28 20 6f 70 32       assert( op2
22d90 3d 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 20  ==SQLITE_INSERT 
22da0 29 3b 0a 20 20 20 20 20 20 20 20 70 4e 65 77 2d  );.        pNew-
22db0 3e 6f 70 20 3d 20 53 51 4c 49 54 45 5f 55 50 44  >op = SQLITE_UPD
22dc0 41 54 45 3b 0a 20 20 20 20 20 20 20 20 69 66 28  ATE;.        if(
22dd0 20 62 50 61 74 63 68 73 65 74 20 29 7b 0a 20 20   bPatchset ){.  
22de0 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 61          memcpy(a
22df0 43 73 72 2c 20 61 52 65 63 2c 20 6e 52 65 63 29  Csr, aRec, nRec)
22e00 3b 0a 20 20 20 20 20 20 20 20 20 20 61 43 73 72  ;.          aCsr
22e10 20 2b 3d 20 6e 52 65 63 3b 0a 20 20 20 20 20 20   += nRec;.      
22e20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
22e30 20 20 20 69 66 28 20 30 3d 3d 73 65 73 73 69 6f     if( 0==sessio
22e40 6e 4d 65 72 67 65 55 70 64 61 74 65 28 26 61 43  nMergeUpdate(&aC
22e50 73 72 2c 20 70 54 61 62 2c 20 62 50 61 74 63 68  sr, pTab, bPatch
22e60 73 65 74 2c 20 61 45 78 69 73 74 2c 20 30 2c 61  set, aExist, 0,a
22e70 52 65 63 2c 30 29 20 29 7b 0a 20 20 20 20 20 20  Rec,0) ){.      
22e80 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
22e90 65 65 28 70 4e 65 77 29 3b 0a 20 20 20 20 20 20  ee(pNew);.      
22ea0 20 20 20 20 20 20 70 4e 65 77 20 3d 20 30 3b 0a        pNew = 0;.
22eb0 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
22ec0 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73      }.      }els
22ed0 65 20 69 66 28 20 6f 70 32 3d 3d 53 51 4c 49 54  e if( op2==SQLIT
22ee0 45 5f 55 50 44 41 54 45 20 29 7b 20 20 20 20 20  E_UPDATE ){     
22ef0 20 20 2f 2a 20 55 50 44 41 54 45 20 2b 20 55 50    /* UPDATE + UP
22f00 44 41 54 45 20 2a 2f 0a 20 20 20 20 20 20 20 20  DATE */.        
22f10 75 38 20 2a 61 31 20 3d 20 61 45 78 69 73 74 3b  u8 *a1 = aExist;
22f20 0a 20 20 20 20 20 20 20 20 75 38 20 2a 61 32 20  .        u8 *a2 
22f30 3d 20 61 52 65 63 3b 0a 20 20 20 20 20 20 20 20  = aRec;.        
22f40 61 73 73 65 72 74 28 20 6f 70 31 3d 3d 53 51 4c  assert( op1==SQL
22f50 49 54 45 5f 55 50 44 41 54 45 20 29 3b 0a 20 20  ITE_UPDATE );.  
22f60 20 20 20 20 20 20 69 66 28 20 62 50 61 74 63 68        if( bPatch
22f70 73 65 74 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  set==0 ){.      
22f80 20 20 20 20 73 65 73 73 69 6f 6e 53 6b 69 70 52      sessionSkipR
22f90 65 63 6f 72 64 28 26 61 31 2c 20 70 54 61 62 2d  ecord(&a1, pTab-
22fa0 3e 6e 43 6f 6c 29 3b 0a 20 20 20 20 20 20 20 20  >nCol);.        
22fb0 20 20 73 65 73 73 69 6f 6e 53 6b 69 70 52 65 63    sessionSkipRec
22fc0 6f 72 64 28 26 61 32 2c 20 70 54 61 62 2d 3e 6e  ord(&a2, pTab->n
22fd0 43 6f 6c 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  Col);.        }.
22fe0 20 20 20 20 20 20 20 20 70 4e 65 77 2d 3e 6f 70          pNew->op
22ff0 20 3d 20 53 51 4c 49 54 45 5f 55 50 44 41 54 45   = SQLITE_UPDATE
23000 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 30 3d  ;.        if( 0=
23010 3d 73 65 73 73 69 6f 6e 4d 65 72 67 65 55 70 64  =sessionMergeUpd
23020 61 74 65 28 26 61 43 73 72 2c 20 70 54 61 62 2c  ate(&aCsr, pTab,
23030 20 62 50 61 74 63 68 73 65 74 2c 20 61 52 65 63   bPatchset, aRec
23040 2c 20 61 45 78 69 73 74 2c 61 31 2c 61 32 29 20  , aExist,a1,a2) 
23050 29 7b 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c  ){.          sql
23060 69 74 65 33 5f 66 72 65 65 28 70 4e 65 77 29 3b  ite3_free(pNew);
23070 0a 20 20 20 20 20 20 20 20 20 20 70 4e 65 77 20  .          pNew 
23080 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  = 0;.        }. 
23090 20 20 20 20 20 7d 65 6c 73 65 7b 20 20 20 20 20       }else{     
230a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
230b0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 50             /* UP
230c0 44 41 54 45 20 2b 20 44 45 4c 45 54 45 20 2a 2f  DATE + DELETE */
230d0 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28  .        assert(
230e0 20 6f 70 31 3d 3d 53 51 4c 49 54 45 5f 55 50 44   op1==SQLITE_UPD
230f0 41 54 45 20 26 26 20 6f 70 32 3d 3d 53 51 4c 49  ATE && op2==SQLI
23100 54 45 5f 44 45 4c 45 54 45 20 29 3b 0a 20 20 20  TE_DELETE );.   
23110 20 20 20 20 20 70 4e 65 77 2d 3e 6f 70 20 3d 20       pNew->op = 
23120 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 3b 0a 20  SQLITE_DELETE;. 
23130 20 20 20 20 20 20 20 69 66 28 20 62 50 61 74 63         if( bPatc
23140 68 73 65 74 20 29 7b 0a 20 20 20 20 20 20 20 20  hset ){.        
23150 20 20 6d 65 6d 63 70 79 28 61 43 73 72 2c 20 61    memcpy(aCsr, a
23160 52 65 63 2c 20 6e 52 65 63 29 3b 0a 20 20 20 20  Rec, nRec);.    
23170 20 20 20 20 20 20 61 43 73 72 20 2b 3d 20 6e 52        aCsr += nR
23180 65 63 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73  ec;.        }els
23190 65 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65 73  e{.          ses
231a0 73 69 6f 6e 4d 65 72 67 65 52 65 63 6f 72 64 28  sionMergeRecord(
231b0 26 61 43 73 72 2c 20 70 54 61 62 2d 3e 6e 43 6f  &aCsr, pTab->nCo
231c0 6c 2c 20 61 52 65 63 2c 20 61 45 78 69 73 74 29  l, aRec, aExist)
231d0 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
231e0 20 20 7d 0a 0a 20 20 20 20 20 20 69 66 28 20 70    }..      if( p
231f0 4e 65 77 20 29 7b 0a 20 20 20 20 20 20 20 20 70  New ){.        p
23200 4e 65 77 2d 3e 6e 52 65 63 6f 72 64 20 3d 20 28  New->nRecord = (
23210 69 6e 74 29 28 61 43 73 72 20 2d 20 70 4e 65 77  int)(aCsr - pNew
23220 2d 3e 61 52 65 63 6f 72 64 29 3b 0a 20 20 20 20  ->aRecord);.    
23230 20 20 7d 0a 20 20 20 20 20 20 73 71 6c 69 74 65    }.      sqlite
23240 33 5f 66 72 65 65 28 70 45 78 69 73 74 29 3b 0a  3_free(pExist);.
23250 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70      }.  }..  *pp
23260 4e 65 77 20 3d 20 70 4e 65 77 3b 0a 20 20 72 65  New = pNew;.  re
23270 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
23280 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 6c 6c  }../*.** Add all
23290 20 63 68 61 6e 67 65 73 20 69 6e 20 74 68 65 20   changes in the 
232a0 63 68 61 6e 67 65 73 65 74 20 74 72 61 76 65 72  changeset traver
232b0 73 65 64 20 62 79 20 74 68 65 20 69 74 65 72 61  sed by the itera
232c0 74 6f 72 20 70 61 73 73 65 64 20 61 73 0a 2a 2a  tor passed as.**
232d0 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d   the first argum
232e0 65 6e 74 20 74 6f 20 74 68 65 20 63 68 61 6e 67  ent to the chang
232f0 65 67 72 6f 75 70 20 68 61 73 68 20 74 61 62 6c  egroup hash tabl
23300 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  es..*/.static in
23310 74 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73  t sessionChanges
23320 65 74 54 6f 48 61 73 68 28 0a 20 20 73 71 6c 69  etToHash(.  sqli
23330 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74  te3_changeset_it
23340 65 72 20 2a 70 49 74 65 72 2c 20 20 20 2f 2a 20  er *pIter,   /* 
23350 49 74 65 72 61 74 6f 72 20 74 6f 20 72 65 61 64  Iterator to read
23360 20 66 72 6f 6d 20 2a 2f 0a 20 20 73 71 6c 69 74   from */.  sqlit
23370 65 33 5f 63 68 61 6e 67 65 67 72 6f 75 70 20 2a  e3_changegroup *
23380 70 47 72 70 20 20 20 20 20 20 20 20 2f 2a 20 43  pGrp        /* C
23390 68 61 6e 67 65 67 72 6f 75 70 20 6f 62 6a 65 63  hangegroup objec
233a0 74 20 74 6f 20 61 64 64 20 63 68 61 6e 67 65 73  t to add changes
233b0 65 74 20 74 6f 20 2a 2f 0a 29 7b 0a 20 20 75 38  et to */.){.  u8
233c0 20 2a 61 52 65 63 3b 0a 20 20 69 6e 74 20 6e 52   *aRec;.  int nR
233d0 65 63 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  ec;.  int rc = S
233e0 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 53 65 73 73  QLITE_OK;.  Sess
233f0 69 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62 20 3d  ionTable *pTab =
23400 20 30 3b 0a 0a 0a 20 20 77 68 69 6c 65 28 20 53   0;...  while( S
23410 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 65 73 73 69  QLITE_ROW==sessi
23420 6f 6e 43 68 61 6e 67 65 73 65 74 4e 65 78 74 28  onChangesetNext(
23430 70 49 74 65 72 2c 20 26 61 52 65 63 2c 20 26 6e  pIter, &aRec, &n
23440 52 65 63 29 20 29 7b 0a 20 20 20 20 63 6f 6e 73  Rec) ){.    cons
23450 74 20 63 68 61 72 20 2a 7a 4e 65 77 3b 0a 20 20  t char *zNew;.  
23460 20 20 69 6e 74 20 6e 43 6f 6c 3b 0a 20 20 20 20    int nCol;.    
23470 69 6e 74 20 6f 70 3b 0a 20 20 20 20 69 6e 74 20  int op;.    int 
23480 69 48 61 73 68 3b 0a 20 20 20 20 69 6e 74 20 62  iHash;.    int b
23490 49 6e 64 69 72 65 63 74 3b 0a 20 20 20 20 53 65  Indirect;.    Se
234a0 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 70 43 68  ssionChange *pCh
234b0 61 6e 67 65 3b 0a 20 20 20 20 53 65 73 73 69 6f  ange;.    Sessio
234c0 6e 43 68 61 6e 67 65 20 2a 70 45 78 69 73 74 20  nChange *pExist 
234d0 3d 20 30 3b 0a 20 20 20 20 53 65 73 73 69 6f 6e  = 0;.    Session
234e0 43 68 61 6e 67 65 20 2a 2a 70 70 3b 0a 0a 20 20  Change **pp;..  
234f0 20 20 69 66 28 20 70 47 72 70 2d 3e 70 4c 69 73    if( pGrp->pLis
23500 74 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 47  t==0 ){.      pG
23510 72 70 2d 3e 62 50 61 74 63 68 20 3d 20 70 49 74  rp->bPatch = pIt
23520 65 72 2d 3e 62 50 61 74 63 68 73 65 74 3b 0a 20  er->bPatchset;. 
23530 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70 49 74     }else if( pIt
23540 65 72 2d 3e 62 50 61 74 63 68 73 65 74 21 3d 70  er->bPatchset!=p
23550 47 72 70 2d 3e 62 50 61 74 63 68 20 29 7b 0a 20  Grp->bPatch ){. 
23560 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
23570 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 62 72  _ERROR;.      br
23580 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  eak;.    }..    
23590 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
235a0 5f 6f 70 28 70 49 74 65 72 2c 20 26 7a 4e 65 77  _op(pIter, &zNew
235b0 2c 20 26 6e 43 6f 6c 2c 20 26 6f 70 2c 20 26 62  , &nCol, &op, &b
235c0 49 6e 64 69 72 65 63 74 29 3b 0a 20 20 20 20 69  Indirect);.    i
235d0 66 28 20 21 70 54 61 62 20 7c 7c 20 73 71 6c 69  f( !pTab || sqli
235e0 74 65 33 5f 73 74 72 69 63 6d 70 28 7a 4e 65 77  te3_stricmp(zNew
235f0 2c 20 70 54 61 62 2d 3e 7a 4e 61 6d 65 29 20 29  , pTab->zName) )
23600 7b 0a 20 20 20 20 20 20 2f 2a 20 53 65 61 72 63  {.      /* Searc
23610 68 20 74 68 65 20 6c 69 73 74 20 66 6f 72 20 61  h the list for a
23620 20 6d 61 74 63 68 69 6e 67 20 74 61 62 6c 65 20   matching table 
23630 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e 65  */.      int nNe
23640 77 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28  w = (int)strlen(
23650 7a 4e 65 77 29 3b 0a 20 20 20 20 20 20 75 38 20  zNew);.      u8 
23660 2a 61 62 50 4b 3b 0a 0a 20 20 20 20 20 20 73 71  *abPK;..      sq
23670 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 70  lite3changeset_p
23680 6b 28 70 49 74 65 72 2c 20 26 61 62 50 4b 2c 20  k(pIter, &abPK, 
23690 30 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 70 54  0);.      for(pT
236a0 61 62 20 3d 20 70 47 72 70 2d 3e 70 4c 69 73 74  ab = pGrp->pList
236b0 3b 20 70 54 61 62 3b 20 70 54 61 62 3d 70 54 61  ; pTab; pTab=pTa
236c0 62 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20  b->pNext){.     
236d0 20 20 20 69 66 28 20 30 3d 3d 73 71 6c 69 74 65     if( 0==sqlite
236e0 33 5f 73 74 72 6e 69 63 6d 70 28 70 54 61 62 2d  3_strnicmp(pTab-
236f0 3e 7a 4e 61 6d 65 2c 20 7a 4e 65 77 2c 20 6e 4e  >zName, zNew, nN
23700 65 77 2b 31 29 20 29 20 62 72 65 61 6b 3b 0a 20  ew+1) ) break;. 
23710 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
23720 20 21 70 54 61 62 20 29 7b 0a 20 20 20 20 20 20   !pTab ){.      
23730 20 20 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a    SessionTable *
23740 2a 70 70 54 61 62 3b 0a 0a 20 20 20 20 20 20 20  *ppTab;..       
23750 20 70 54 61 62 20 3d 20 73 71 6c 69 74 65 33 5f   pTab = sqlite3_
23760 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 53 65  malloc(sizeof(Se
23770 73 73 69 6f 6e 54 61 62 6c 65 29 20 2b 20 6e 43  ssionTable) + nC
23780 6f 6c 20 2b 20 6e 4e 65 77 2b 31 29 3b 0a 20 20  ol + nNew+1);.  
23790 20 20 20 20 20 20 69 66 28 20 21 70 54 61 62 20        if( !pTab 
237a0 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  ){.          rc 
237b0 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
237c0 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b            break;
237d0 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
237e0 20 20 20 6d 65 6d 73 65 74 28 70 54 61 62 2c 20     memset(pTab, 
237f0 30 2c 20 73 69 7a 65 6f 66 28 53 65 73 73 69 6f  0, sizeof(Sessio
23800 6e 54 61 62 6c 65 29 29 3b 0a 20 20 20 20 20 20  nTable));.      
23810 20 20 70 54 61 62 2d 3e 6e 43 6f 6c 20 3d 20 6e    pTab->nCol = n
23820 43 6f 6c 3b 0a 20 20 20 20 20 20 20 20 70 54 61  Col;.        pTa
23830 62 2d 3e 61 62 50 4b 20 3d 20 28 75 38 2a 29 26  b->abPK = (u8*)&
23840 70 54 61 62 5b 31 5d 3b 0a 20 20 20 20 20 20 20  pTab[1];.       
23850 20 6d 65 6d 63 70 79 28 70 54 61 62 2d 3e 61 62   memcpy(pTab->ab
23860 50 4b 2c 20 61 62 50 4b 2c 20 6e 43 6f 6c 29 3b  PK, abPK, nCol);
23870 0a 20 20 20 20 20 20 20 20 70 54 61 62 2d 3e 7a  .        pTab->z
23880 4e 61 6d 65 20 3d 20 28 63 68 61 72 2a 29 26 70  Name = (char*)&p
23890 54 61 62 2d 3e 61 62 50 4b 5b 6e 43 6f 6c 5d 3b  Tab->abPK[nCol];
238a0 0a 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28  .        memcpy(
238b0 70 54 61 62 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e 65  pTab->zName, zNe
238c0 77 2c 20 6e 4e 65 77 2b 31 29 3b 0a 0a 20 20 20  w, nNew+1);..   
238d0 20 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77 20       /* The new 
238e0 6f 62 6a 65 63 74 20 6d 75 73 74 20 62 65 20 6c  object must be l
238f0 69 6e 6b 65 64 20 6f 6e 20 74 6f 20 74 68 65 20  inked on to the 
23900 65 6e 64 20 6f 66 20 74 68 65 20 6c 69 73 74 2c  end of the list,
23910 20 6e 6f 74 0a 20 20 20 20 20 20 20 20 2a 2a 20   not.        ** 
23920 73 69 6d 70 6c 79 20 61 64 64 65 64 20 74 6f 20  simply added to 
23930 74 68 65 20 73 74 61 72 74 20 6f 66 20 69 74 2e  the start of it.
23940 20 54 68 69 73 20 69 73 20 74 6f 20 65 6e 73 75   This is to ensu
23950 72 65 20 74 68 61 74 20 74 68 65 0a 20 20 20 20  re that the.    
23960 20 20 20 20 2a 2a 20 74 61 62 6c 65 73 20 77 69      ** tables wi
23970 74 68 69 6e 20 74 68 65 20 6f 75 74 70 75 74 20  thin the output 
23980 6f 66 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65  of sqlite3change
23990 67 72 6f 75 70 5f 6f 75 74 70 75 74 28 29 20 61  group_output() a
239a0 72 65 20 69 6e 20 0a 20 20 20 20 20 20 20 20 2a  re in .        *
239b0 2a 20 74 68 65 20 72 69 67 68 74 20 6f 72 64 65  * the right orde
239c0 72 2e 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 66  r.  */.        f
239d0 6f 72 28 70 70 54 61 62 3d 26 70 47 72 70 2d 3e  or(ppTab=&pGrp->
239e0 70 4c 69 73 74 3b 20 2a 70 70 54 61 62 3b 20 70  pList; *ppTab; p
239f0 70 54 61 62 3d 26 28 2a 70 70 54 61 62 29 2d 3e  pTab=&(*ppTab)->
23a00 70 4e 65 78 74 29 3b 0a 20 20 20 20 20 20 20 20  pNext);.        
23a10 2a 70 70 54 61 62 20 3d 20 70 54 61 62 3b 0a 20  *ppTab = pTab;. 
23a20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70       }else if( p
23a30 54 61 62 2d 3e 6e 43 6f 6c 21 3d 6e 43 6f 6c 20  Tab->nCol!=nCol 
23a40 7c 7c 20 6d 65 6d 63 6d 70 28 70 54 61 62 2d 3e  || memcmp(pTab->
23a50 61 62 50 4b 2c 20 61 62 50 4b 2c 20 6e 43 6f 6c  abPK, abPK, nCol
23a60 29 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  ) ){.        rc 
23a70 3d 20 53 51 4c 49 54 45 5f 53 43 48 45 4d 41 3b  = SQLITE_SCHEMA;
23a80 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
23a90 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20        }.    }.. 
23aa0 20 20 20 69 66 28 20 73 65 73 73 69 6f 6e 47 72     if( sessionGr
23ab0 6f 77 48 61 73 68 28 70 49 74 65 72 2d 3e 62 50  owHash(pIter->bP
23ac0 61 74 63 68 73 65 74 2c 20 70 54 61 62 29 20 29  atchset, pTab) )
23ad0 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
23ae0 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
23af0 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20   break;.    }.  
23b00 20 20 69 48 61 73 68 20 3d 20 73 65 73 73 69 6f    iHash = sessio
23b10 6e 43 68 61 6e 67 65 48 61 73 68 28 0a 20 20 20  nChangeHash(.   
23b20 20 20 20 20 20 70 54 61 62 2c 20 28 70 49 74 65       pTab, (pIte
23b30 72 2d 3e 62 50 61 74 63 68 73 65 74 20 26 26 20  r->bPatchset && 
23b40 6f 70 3d 3d 53 51 4c 49 54 45 5f 44 45 4c 45 54  op==SQLITE_DELET
23b50 45 29 2c 20 61 52 65 63 2c 20 70 54 61 62 2d 3e  E), aRec, pTab->
23b60 6e 43 68 61 6e 67 65 0a 20 20 20 20 29 3b 0a 0a  nChange.    );..
23b70 20 20 20 20 2f 2a 20 53 65 61 72 63 68 20 66 6f      /* Search fo
23b80 72 20 65 78 69 73 74 69 6e 67 20 65 6e 74 72 79  r existing entry
23b90 2e 20 49 66 20 66 6f 75 6e 64 2c 20 72 65 6d 6f  . If found, remo
23ba0 76 65 20 69 74 20 66 72 6f 6d 20 74 68 65 20 68  ve it from the h
23bb0 61 73 68 20 74 61 62 6c 65 2e 20 0a 20 20 20 20  ash table. .    
23bc0 2a 2a 20 43 6f 64 65 20 62 65 6c 6f 77 20 6d 61  ** Code below ma
23bd0 79 20 6c 69 6e 6b 20 69 74 20 62 61 63 6b 20 69  y link it back i
23be0 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 66 6f  n..    */.    fo
23bf0 72 28 70 70 3d 26 70 54 61 62 2d 3e 61 70 43 68  r(pp=&pTab->apCh
23c00 61 6e 67 65 5b 69 48 61 73 68 5d 3b 20 2a 70 70  ange[iHash]; *pp
23c10 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70 4e 65  ; pp=&(*pp)->pNe
23c20 78 74 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 62  xt){.      int b
23c30 50 6b 4f 6e 6c 79 31 20 3d 20 30 3b 0a 20 20 20  PkOnly1 = 0;.   
23c40 20 20 20 69 6e 74 20 62 50 6b 4f 6e 6c 79 32 20     int bPkOnly2 
23c50 3d 20 30 3b 0a 20 20 20 20 20 20 69 66 28 20 70  = 0;.      if( p
23c60 49 74 65 72 2d 3e 62 50 61 74 63 68 73 65 74 20  Iter->bPatchset 
23c70 29 7b 0a 20 20 20 20 20 20 20 20 62 50 6b 4f 6e  ){.        bPkOn
23c80 6c 79 31 20 3d 20 28 2a 70 70 29 2d 3e 6f 70 3d  ly1 = (*pp)->op=
23c90 3d 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 3b 0a  =SQLITE_DELETE;.
23ca0 20 20 20 20 20 20 20 20 62 50 6b 4f 6e 6c 79 32          bPkOnly2
23cb0 20 3d 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 44 45   = op==SQLITE_DE
23cc0 4c 45 54 45 3b 0a 20 20 20 20 20 20 7d 0a 20 20  LETE;.      }.  
23cd0 20 20 20 20 69 66 28 20 73 65 73 73 69 6f 6e 43      if( sessionC
23ce0 68 61 6e 67 65 45 71 75 61 6c 28 70 54 61 62 2c  hangeEqual(pTab,
23cf0 20 62 50 6b 4f 6e 6c 79 31 2c 20 28 2a 70 70 29   bPkOnly1, (*pp)
23d00 2d 3e 61 52 65 63 6f 72 64 2c 20 62 50 6b 4f 6e  ->aRecord, bPkOn
23d10 6c 79 32 2c 20 61 52 65 63 29 20 29 7b 0a 20 20  ly2, aRec) ){.  
23d20 20 20 20 20 20 20 70 45 78 69 73 74 20 3d 20 2a        pExist = *
23d30 70 70 3b 0a 20 20 20 20 20 20 20 20 2a 70 70 20  pp;.        *pp 
23d40 3d 20 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a  = (*pp)->pNext;.
23d50 20 20 20 20 20 20 20 20 70 54 61 62 2d 3e 6e 45          pTab->nE
23d60 6e 74 72 79 2d 2d 3b 0a 20 20 20 20 20 20 20 20  ntry--;.        
23d70 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20  break;.      }. 
23d80 20 20 20 7d 0a 0a 20 20 20 20 72 63 20 3d 20 73     }..    rc = s
23d90 65 73 73 69 6f 6e 43 68 61 6e 67 65 4d 65 72 67  essionChangeMerg
23da0 65 28 70 54 61 62 2c 20 0a 20 20 20 20 20 20 20  e(pTab, .       
23db0 20 70 49 74 65 72 2d 3e 62 50 61 74 63 68 73 65   pIter->bPatchse
23dc0 74 2c 20 70 45 78 69 73 74 2c 20 6f 70 2c 20 62  t, pExist, op, b
23dd0 49 6e 64 69 72 65 63 74 2c 20 61 52 65 63 2c 20  Indirect, aRec, 
23de0 6e 52 65 63 2c 20 26 70 43 68 61 6e 67 65 0a 20  nRec, &pChange. 
23df0 20 20 20 29 3b 0a 20 20 20 20 69 66 28 20 72 63     );.    if( rc
23e00 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 69 66   ) break;.    if
23e10 28 20 70 43 68 61 6e 67 65 20 29 7b 0a 20 20 20  ( pChange ){.   
23e20 20 20 20 70 43 68 61 6e 67 65 2d 3e 70 4e 65 78     pChange->pNex
23e30 74 20 3d 20 70 54 61 62 2d 3e 61 70 43 68 61 6e  t = pTab->apChan
23e40 67 65 5b 69 48 61 73 68 5d 3b 0a 20 20 20 20 20  ge[iHash];.     
23e50 20 70 54 61 62 2d 3e 61 70 43 68 61 6e 67 65 5b   pTab->apChange[
23e60 69 48 61 73 68 5d 20 3d 20 70 43 68 61 6e 67 65  iHash] = pChange
23e70 3b 0a 20 20 20 20 20 20 70 54 61 62 2d 3e 6e 45  ;.      pTab->nE
23e80 6e 74 72 79 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20  ntry++;.    }.  
23e90 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
23ea0 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 70 49  ITE_OK ) rc = pI
23eb0 74 65 72 2d 3e 72 63 3b 0a 20 20 72 65 74 75 72  ter->rc;.  retur
23ec0 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  n rc;.}../*.** S
23ed0 65 72 69 61 6c 69 7a 65 20 61 20 63 68 61 6e 67  erialize a chang
23ee0 65 73 65 74 20 28 6f 72 20 70 61 74 63 68 73 65  eset (or patchse
23ef0 74 29 20 62 61 73 65 64 20 6f 6e 20 61 6c 6c 20  t) based on all 
23f00 63 68 61 6e 67 65 73 65 74 73 20 28 6f 72 20 70  changesets (or p
23f10 61 74 63 68 73 65 74 73 29 0a 2a 2a 20 61 64 64  atchsets).** add
23f20 65 64 20 74 6f 20 74 68 65 20 63 68 61 6e 67 65  ed to the change
23f30 67 72 6f 75 70 20 6f 62 6a 65 63 74 20 70 61 73  group object pas
23f40 73 65 64 20 61 73 20 74 68 65 20 66 69 72 73 74  sed as the first
23f50 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a   argument..**.**
23f60 20 49 66 20 78 4f 75 74 70 75 74 20 69 73 20 6e   If xOutput is n
23f70 6f 74 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 74 68  ot NULL, then th
23f80 65 20 63 68 61 6e 67 65 73 65 74 2f 70 61 74 63  e changeset/patc
23f90 68 73 65 74 20 69 73 20 72 65 74 75 72 6e 65 64  hset is returned
23fa0 20 74 6f 20 74 68 65 0a 2a 2a 20 75 73 65 72 20   to the.** user 
23fb0 76 69 61 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20  via one or more 
23fc0 63 61 6c 6c 73 20 74 6f 20 78 4f 75 74 70 75 74  calls to xOutput
23fd0 2c 20 61 73 20 77 69 74 68 20 74 68 65 20 6f 74  , as with the ot
23fe0 68 65 72 20 73 74 72 65 61 6d 69 6e 67 0a 2a 2a  her streaming.**
23ff0 20 69 6e 74 65 72 66 61 63 65 73 2e 20 0a 2a 2a   interfaces. .**
24000 0a 2a 2a 20 4f 72 2c 20 69 66 20 78 4f 75 74 70  .** Or, if xOutp
24010 75 74 20 69 73 20 4e 55 4c 4c 2c 20 74 68 65 6e  ut is NULL, then
24020 20 28 2a 70 70 4f 75 74 29 20 69 73 20 70 6f 70   (*ppOut) is pop
24030 75 6c 61 74 65 64 20 77 69 74 68 20 61 20 70 6f  ulated with a po
24040 69 6e 74 65 72 20 74 6f 20 61 0a 2a 2a 20 62 75  inter to a.** bu
24050 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ffer containing 
24060 74 68 65 20 6f 75 74 70 75 74 20 63 68 61 6e 67  the output chang
24070 65 73 65 74 20 62 65 66 6f 72 65 20 74 68 69 73  eset before this
24080 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e   function return
24090 73 2e 20 49 6e 0a 2a 2a 20 74 68 69 73 20 63 61  s. In.** this ca
240a0 73 65 20 28 2a 70 6e 4f 75 74 29 20 69 73 20 73  se (*pnOut) is s
240b0 65 74 20 74 6f 20 74 68 65 20 73 69 7a 65 20 6f  et to the size o
240c0 66 20 74 68 65 20 6f 75 74 70 75 74 20 62 75 66  f the output buf
240d0 66 65 72 20 69 6e 20 62 79 74 65 73 2e 20 49 74  fer in bytes. It
240e0 0a 2a 2a 20 69 73 20 74 68 65 20 72 65 73 70 6f  .** is the respo
240f0 6e 73 69 62 69 6c 69 74 79 20 6f 66 20 74 68 65  nsibility of the
24100 20 63 61 6c 6c 65 72 20 74 6f 20 66 72 65 65 20   caller to free 
24110 74 68 65 20 6f 75 74 70 75 74 20 62 75 66 66 65  the output buffe
24120 72 20 75 73 69 6e 67 0a 2a 2a 20 73 71 6c 69 74  r using.** sqlit
24130 65 33 5f 66 72 65 65 28 29 20 77 68 65 6e 20 69  e3_free() when i
24140 74 20 69 73 20 6e 6f 20 6c 6f 6e 67 65 72 20 72  t is no longer r
24150 65 71 75 69 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 49  equired..**.** I
24160 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 53 51  f successful, SQ
24170 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72  LITE_OK is retur
24180 6e 65 64 2e 20 4f 72 2c 20 69 66 20 61 6e 20 65  ned. Or, if an e
24190 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 61 6e 20  rror occurs, an 
241a0 53 51 4c 69 74 65 0a 2a 2a 20 65 72 72 6f 72 20  SQLite.** error 
241b0 63 6f 64 65 2e 20 49 66 20 61 6e 20 65 72 72 6f  code. If an erro
241c0 72 20 6f 63 63 75 72 73 20 61 6e 64 20 78 4f 75  r occurs and xOu
241d0 74 70 75 74 20 69 73 20 4e 55 4c 4c 2c 20 28 2a  tput is NULL, (*
241e0 70 70 4f 75 74 29 20 61 6e 64 20 28 2a 70 6e 4f  ppOut) and (*pnO
241f0 75 74 29 0a 2a 2a 20 61 72 65 20 62 6f 74 68 20  ut).** are both 
24200 73 65 74 20 74 6f 20 30 20 62 65 66 6f 72 65 20  set to 0 before 
24210 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74  returning..*/.st
24220 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e  atic int session
24230 43 68 61 6e 67 65 67 72 6f 75 70 4f 75 74 70 75  ChangegroupOutpu
24240 74 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 68 61  t(.  sqlite3_cha
24250 6e 67 65 67 72 6f 75 70 20 2a 70 47 72 70 2c 0a  ngegroup *pGrp,.
24260 20 20 69 6e 74 20 28 2a 78 4f 75 74 70 75 74 29    int (*xOutput)
24270 28 76 6f 69 64 20 2a 70 4f 75 74 2c 20 63 6f 6e  (void *pOut, con
24280 73 74 20 76 6f 69 64 20 2a 70 44 61 74 61 2c 20  st void *pData, 
24290 69 6e 74 20 6e 44 61 74 61 29 2c 0a 20 20 76 6f  int nData),.  vo
242a0 69 64 20 2a 70 4f 75 74 2c 0a 20 20 69 6e 74 20  id *pOut,.  int 
242b0 2a 70 6e 4f 75 74 2c 0a 20 20 76 6f 69 64 20 2a  *pnOut,.  void *
242c0 2a 70 70 4f 75 74 0a 29 7b 0a 20 20 69 6e 74 20  *ppOut.){.  int 
242d0 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
242e0 20 20 53 65 73 73 69 6f 6e 42 75 66 66 65 72 20    SessionBuffer 
242f0 62 75 66 20 3d 20 7b 30 2c 20 30 2c 20 30 7d 3b  buf = {0, 0, 0};
24300 0a 20 20 53 65 73 73 69 6f 6e 54 61 62 6c 65 20  .  SessionTable 
24310 2a 70 54 61 62 3b 0a 20 20 61 73 73 65 72 74 28  *pTab;.  assert(
24320 20 78 4f 75 74 70 75 74 3d 3d 30 20 7c 7c 20 28   xOutput==0 || (
24330 70 70 4f 75 74 3d 3d 30 20 26 26 20 70 6e 4f 75  ppOut==0 && pnOu
24340 74 3d 3d 30 29 20 29 3b 0a 0a 20 20 2f 2a 20 43  t==0) );..  /* C
24350 72 65 61 74 65 20 74 68 65 20 73 65 72 69 61 6c  reate the serial
24360 69 7a 65 64 20 6f 75 74 70 75 74 20 63 68 61 6e  ized output chan
24370 67 65 73 65 74 20 62 61 73 65 64 20 6f 6e 20 74  geset based on t
24380 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
24390 68 65 0a 20 20 2a 2a 20 68 61 73 68 20 74 61 62  he.  ** hash tab
243a0 6c 65 73 20 61 74 74 61 63 68 65 64 20 74 6f 20  les attached to 
243b0 74 68 65 20 53 65 73 73 69 6f 6e 54 61 62 6c 65  the SessionTable
243c0 20 6f 62 6a 65 63 74 73 20 69 6e 20 6c 69 73 74   objects in list
243d0 20 70 2d 3e 70 4c 69 73 74 2e 20 0a 20 20 2a 2f   p->pList. .  */
243e0 0a 20 20 66 6f 72 28 70 54 61 62 3d 70 47 72 70  .  for(pTab=pGrp
243f0 2d 3e 70 4c 69 73 74 3b 20 72 63 3d 3d 53 51 4c  ->pList; rc==SQL
24400 49 54 45 5f 4f 4b 20 26 26 20 70 54 61 62 3b 20  ITE_OK && pTab; 
24410 70 54 61 62 3d 70 54 61 62 2d 3e 70 4e 65 78 74  pTab=pTab->pNext
24420 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20  ){.    int i;.  
24430 20 20 69 66 28 20 70 54 61 62 2d 3e 6e 45 6e 74    if( pTab->nEnt
24440 72 79 3d 3d 30 20 29 20 63 6f 6e 74 69 6e 75 65  ry==0 ) continue
24450 3b 0a 0a 20 20 20 20 73 65 73 73 69 6f 6e 41 70  ;..    sessionAp
24460 70 65 6e 64 54 61 62 6c 65 48 64 72 28 26 62 75  pendTableHdr(&bu
24470 66 2c 20 70 47 72 70 2d 3e 62 50 61 74 63 68 2c  f, pGrp->bPatch,
24480 20 70 54 61 62 2c 20 26 72 63 29 3b 0a 20 20 20   pTab, &rc);.   
24490 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61 62   for(i=0; i<pTab
244a0 2d 3e 6e 43 68 61 6e 67 65 3b 20 69 2b 2b 29 7b  ->nChange; i++){
244b0 0a 20 20 20 20 20 20 53 65 73 73 69 6f 6e 43 68  .      SessionCh
244c0 61 6e 67 65 20 2a 70 3b 0a 20 20 20 20 20 20 66  ange *p;.      f
244d0 6f 72 28 70 3d 70 54 61 62 2d 3e 61 70 43 68 61  or(p=pTab->apCha
244e0 6e 67 65 5b 69 5d 3b 20 70 3b 20 70 3d 70 2d 3e  nge[i]; p; p=p->
244f0 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 20 20  pNext){.        
24500 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 79 74  sessionAppendByt
24510 65 28 26 62 75 66 2c 20 70 2d 3e 6f 70 2c 20 26  e(&buf, p->op, &
24520 72 63 29 3b 0a 20 20 20 20 20 20 20 20 73 65 73  rc);.        ses
24530 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 26  sionAppendByte(&
24540 62 75 66 2c 20 70 2d 3e 62 49 6e 64 69 72 65 63  buf, p->bIndirec
24550 74 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20  t, &rc);.       
24560 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 6c   sessionAppendBl
24570 6f 62 28 26 62 75 66 2c 20 70 2d 3e 61 52 65 63  ob(&buf, p->aRec
24580 6f 72 64 2c 20 70 2d 3e 6e 52 65 63 6f 72 64 2c  ord, p->nRecord,
24590 20 26 72 63 29 3b 0a 20 20 20 20 20 20 7d 0a 20   &rc);.      }. 
245a0 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72 63     }..    if( rc
245b0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 78  ==SQLITE_OK && x
245c0 4f 75 74 70 75 74 20 26 26 20 62 75 66 2e 6e 42  Output && buf.nB
245d0 75 66 3e 3d 53 45 53 53 49 4f 4e 53 5f 53 54 52  uf>=SESSIONS_STR
245e0 4d 5f 43 48 55 4e 4b 5f 53 49 5a 45 20 29 7b 0a  M_CHUNK_SIZE ){.
245f0 20 20 20 20 20 20 72 63 20 3d 20 78 4f 75 74 70        rc = xOutp
24600 75 74 28 70 4f 75 74 2c 20 62 75 66 2e 61 42 75  ut(pOut, buf.aBu
24610 66 2c 20 62 75 66 2e 6e 42 75 66 29 3b 0a 20 20  f, buf.nBuf);.  
24620 20 20 20 20 62 75 66 2e 6e 42 75 66 20 3d 20 30      buf.nBuf = 0
24630 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  ;.    }.  }..  i
24640 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
24650 20 29 7b 0a 20 20 20 20 69 66 28 20 78 4f 75 74   ){.    if( xOut
24660 70 75 74 20 29 7b 0a 20 20 20 20 20 20 69 66 28  put ){.      if(
24670 20 62 75 66 2e 6e 42 75 66 3e 30 20 29 20 72 63   buf.nBuf>0 ) rc
24680 20 3d 20 78 4f 75 74 70 75 74 28 70 4f 75 74 2c   = xOutput(pOut,
24690 20 62 75 66 2e 61 42 75 66 2c 20 62 75 66 2e 6e   buf.aBuf, buf.n
246a0 42 75 66 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  Buf);.    }else{
246b0 0a 20 20 20 20 20 20 2a 70 70 4f 75 74 20 3d 20  .      *ppOut = 
246c0 62 75 66 2e 61 42 75 66 3b 0a 20 20 20 20 20 20  buf.aBuf;.      
246d0 2a 70 6e 4f 75 74 20 3d 20 62 75 66 2e 6e 42 75  *pnOut = buf.nBu
246e0 66 3b 0a 20 20 20 20 20 20 62 75 66 2e 61 42 75  f;.      buf.aBu
246f0 66 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d  f = 0;.    }.  }
24700 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
24710 62 75 66 2e 61 42 75 66 29 3b 0a 0a 20 20 72 65  buf.aBuf);..  re
24720 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
24730 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77  * Allocate a new
24740 2c 20 65 6d 70 74 79 2c 20 73 71 6c 69 74 65 33  , empty, sqlite3
24750 5f 63 68 61 6e 67 65 67 72 6f 75 70 2e 0a 2a 2f  _changegroup..*/
24760 0a 69 6e 74 20 73 71 6c 69 74 65 33 63 68 61 6e  .int sqlite3chan
24770 67 65 67 72 6f 75 70 5f 6e 65 77 28 73 71 6c 69  gegroup_new(sqli
24780 74 65 33 5f 63 68 61 6e 67 65 67 72 6f 75 70 20  te3_changegroup 
24790 2a 2a 70 70 29 7b 0a 20 20 69 6e 74 20 72 63 20  **pp){.  int rc 
247a0 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20  = SQLITE_OK;    
247b0 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
247c0 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 73 71 6c  rn code */.  sql
247d0 69 74 65 33 5f 63 68 61 6e 67 65 67 72 6f 75 70  ite3_changegroup
247e0 20 2a 70 3b 20 20 20 20 20 20 20 20 20 2f 2a 20   *p;         /* 
247f0 4e 65 77 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20  New object */.  
24800 70 20 3d 20 28 73 71 6c 69 74 65 33 5f 63 68 61  p = (sqlite3_cha
24810 6e 67 65 67 72 6f 75 70 2a 29 73 71 6c 69 74 65  ngegroup*)sqlite
24820 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28  3_malloc(sizeof(
24830 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 67 72  sqlite3_changegr
24840 6f 75 70 29 29 3b 0a 20 20 69 66 28 20 70 3d 3d  oup));.  if( p==
24850 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  0 ){.    rc = SQ
24860 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65  LITE_NOMEM;.  }e
24870 6c 73 65 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28  lse{.    memset(
24880 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73 71 6c  p, 0, sizeof(sql
24890 69 74 65 33 5f 63 68 61 6e 67 65 67 72 6f 75 70  ite3_changegroup
248a0 29 29 3b 0a 20 20 7d 0a 20 20 2a 70 70 20 3d 20  ));.  }.  *pp = 
248b0 70 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  p;.  return rc;.
248c0 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 74 68 65  }../*.** Add the
248d0 20 63 68 61 6e 67 65 73 65 74 20 63 75 72 72 65   changeset curre
248e0 6e 74 6c 79 20 73 74 6f 72 65 64 20 69 6e 20 62  ntly stored in b
248f0 75 66 66 65 72 20 70 44 61 74 61 2c 20 73 69 7a  uffer pData, siz
24900 65 20 6e 44 61 74 61 20 62 79 74 65 73 2c 0a 2a  e nData bytes,.*
24910 2a 20 74 6f 20 63 68 61 6e 67 65 73 65 74 2d 67  * to changeset-g
24920 72 6f 75 70 20 70 2e 0a 2a 2f 0a 69 6e 74 20 73  roup p..*/.int s
24930 71 6c 69 74 65 33 63 68 61 6e 67 65 67 72 6f 75  qlite3changegrou
24940 70 5f 61 64 64 28 73 71 6c 69 74 65 33 5f 63 68  p_add(sqlite3_ch
24950 61 6e 67 65 67 72 6f 75 70 20 2a 70 47 72 70 2c  angegroup *pGrp,
24960 20 69 6e 74 20 6e 44 61 74 61 2c 20 76 6f 69 64   int nData, void
24970 20 2a 70 44 61 74 61 29 7b 0a 20 20 73 71 6c 69   *pData){.  sqli
24980 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74  te3_changeset_it
24990 65 72 20 2a 70 49 74 65 72 3b 20 20 2f 2a 20 49  er *pIter;  /* I
249a0 74 65 72 61 74 6f 72 20 6f 70 65 6e 65 64 20 6f  terator opened o
249b0 6e 20 70 44 61 74 61 2f 6e 44 61 74 61 20 2a 2f  n pData/nData */
249c0 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
249d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
249e0 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
249f0 65 20 2a 2f 0a 0a 20 20 72 63 20 3d 20 73 71 6c  e */..  rc = sql
24a00 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 73 74  ite3changeset_st
24a10 61 72 74 28 26 70 49 74 65 72 2c 20 6e 44 61 74  art(&pIter, nDat
24a20 61 2c 20 70 44 61 74 61 29 3b 0a 20 20 69 66 28  a, pData);.  if(
24a30 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
24a40 7b 0a 20 20 20 20 72 63 20 3d 20 73 65 73 73 69  {.    rc = sessi
24a50 6f 6e 43 68 61 6e 67 65 73 65 74 54 6f 48 61 73  onChangesetToHas
24a60 68 28 70 49 74 65 72 2c 20 70 47 72 70 29 3b 0a  h(pIter, pGrp);.
24a70 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 63 68 61    }.  sqlite3cha
24a80 6e 67 65 73 65 74 5f 66 69 6e 61 6c 69 7a 65 28  ngeset_finalize(
24a90 70 49 74 65 72 29 3b 0a 20 20 72 65 74 75 72 6e  pIter);.  return
24aa0 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 62   rc;.}../*.** Ob
24ab0 74 61 69 6e 20 61 20 62 75 66 66 65 72 20 63 6f  tain a buffer co
24ac0 6e 74 61 69 6e 69 6e 67 20 61 20 63 68 61 6e 67  ntaining a chang
24ad0 65 73 65 74 20 72 65 70 72 65 73 65 6e 74 69 6e  eset representin
24ae0 67 20 74 68 65 20 63 6f 6e 63 61 74 65 6e 61 74  g the concatenat
24af0 69 6f 6e 0a 2a 2a 20 6f 66 20 61 6c 6c 20 63 68  ion.** of all ch
24b00 61 6e 67 65 73 65 74 73 20 61 64 64 65 64 20 74  angesets added t
24b10 6f 20 74 68 65 20 67 72 6f 75 70 20 73 6f 20 66  o the group so f
24b20 61 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ar..*/.int sqlit
24b30 65 33 63 68 61 6e 67 65 67 72 6f 75 70 5f 6f 75  e3changegroup_ou
24b40 74 70 75 74 28 0a 20 20 20 20 73 71 6c 69 74 65  tput(.    sqlite
24b50 33 5f 63 68 61 6e 67 65 67 72 6f 75 70 20 2a 70  3_changegroup *p
24b60 47 72 70 2c 0a 20 20 20 20 69 6e 74 20 2a 70 6e  Grp,.    int *pn
24b70 44 61 74 61 2c 0a 20 20 20 20 76 6f 69 64 20 2a  Data,.    void *
24b80 2a 70 70 44 61 74 61 0a 29 7b 0a 20 20 72 65 74  *ppData.){.  ret
24b90 75 72 6e 20 73 65 73 73 69 6f 6e 43 68 61 6e 67  urn sessionChang
24ba0 65 67 72 6f 75 70 4f 75 74 70 75 74 28 70 47 72  egroupOutput(pGr
24bb0 70 2c 20 30 2c 20 30 2c 20 70 6e 44 61 74 61 2c  p, 0, 0, pnData,
24bc0 20 70 70 44 61 74 61 29 3b 0a 7d 0a 0a 2f 2a 0a   ppData);.}../*.
24bd0 2a 2a 20 53 74 72 65 61 6d 69 6e 67 20 76 65 72  ** Streaming ver
24be0 73 69 6f 6e 73 20 6f 66 20 63 68 61 6e 67 65 67  sions of changeg
24bf0 72 6f 75 70 5f 61 64 64 28 29 2e 0a 2a 2f 0a 69  roup_add()..*/.i
24c00 6e 74 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65  nt sqlite3change
24c10 67 72 6f 75 70 5f 61 64 64 5f 73 74 72 6d 28 0a  group_add_strm(.
24c20 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65    sqlite3_change
24c30 67 72 6f 75 70 20 2a 70 47 72 70 2c 0a 20 20 69  group *pGrp,.  i
24c40 6e 74 20 28 2a 78 49 6e 70 75 74 29 28 76 6f 69  nt (*xInput)(voi
24c50 64 20 2a 70 49 6e 2c 20 76 6f 69 64 20 2a 70 44  d *pIn, void *pD
24c60 61 74 61 2c 20 69 6e 74 20 2a 70 6e 44 61 74 61  ata, int *pnData
24c70 29 2c 0a 20 20 76 6f 69 64 20 2a 70 49 6e 0a 29  ),.  void *pIn.)
24c80 7b 0a 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e  {.  sqlite3_chan
24c90 67 65 73 65 74 5f 69 74 65 72 20 2a 70 49 74 65  geset_iter *pIte
24ca0 72 3b 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20  r;  /* Iterator 
24cb0 6f 70 65 6e 65 64 20 6f 6e 20 70 44 61 74 61 2f  opened on pData/
24cc0 6e 44 61 74 61 20 2a 2f 0a 20 20 69 6e 74 20 72  nData */.  int r
24cd0 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
24ce0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
24cf0 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20 20  turn code */..  
24d00 72 63 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e  rc = sqlite3chan
24d10 67 65 73 65 74 5f 73 74 61 72 74 5f 73 74 72 6d  geset_start_strm
24d20 28 26 70 49 74 65 72 2c 20 78 49 6e 70 75 74 2c  (&pIter, xInput,
24d30 20 70 49 6e 29 3b 0a 20 20 69 66 28 20 72 63 3d   pIn);.  if( rc=
24d40 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
24d50 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 43 68    rc = sessionCh
24d60 61 6e 67 65 73 65 74 54 6f 48 61 73 68 28 70 49  angesetToHash(pI
24d70 74 65 72 2c 20 70 47 72 70 29 3b 0a 20 20 7d 0a  ter, pGrp);.  }.
24d80 20 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73    sqlite3changes
24d90 65 74 5f 66 69 6e 61 6c 69 7a 65 28 70 49 74 65  et_finalize(pIte
24da0 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  r);.  return rc;
24db0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 74 72 65 61 6d  .}../*.** Stream
24dc0 69 6e 67 20 76 65 72 73 69 6f 6e 73 20 6f 66 20  ing versions of 
24dd0 63 68 61 6e 67 65 67 72 6f 75 70 5f 6f 75 74 70  changegroup_outp
24de0 75 74 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  ut()..*/.int sql
24df0 69 74 65 33 63 68 61 6e 67 65 67 72 6f 75 70 5f  ite3changegroup_
24e00 6f 75 74 70 75 74 5f 73 74 72 6d 28 0a 20 20 73  output_strm(.  s
24e10 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 67 72 6f  qlite3_changegro
24e20 75 70 20 2a 70 47 72 70 2c 0a 20 20 69 6e 74 20  up *pGrp,.  int 
24e30 28 2a 78 4f 75 74 70 75 74 29 28 76 6f 69 64 20  (*xOutput)(void 
24e40 2a 70 4f 75 74 2c 20 63 6f 6e 73 74 20 76 6f 69  *pOut, const voi
24e50 64 20 2a 70 44 61 74 61 2c 20 69 6e 74 20 6e 44  d *pData, int nD
24e60 61 74 61 29 2c 20 0a 20 20 76 6f 69 64 20 2a 70  ata), .  void *p
24e70 4f 75 74 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20  Out.){.  return 
24e80 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 67 72 6f  sessionChangegro
24e90 75 70 4f 75 74 70 75 74 28 70 47 72 70 2c 20 78  upOutput(pGrp, x
24ea0 4f 75 74 70 75 74 2c 20 70 4f 75 74 2c 20 30 2c  Output, pOut, 0,
24eb0 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65   0);.}../*.** De
24ec0 6c 65 74 65 20 61 20 63 68 61 6e 67 65 67 72 6f  lete a changegro
24ed0 75 70 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 76 6f  up object..*/.vo
24ee0 69 64 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65  id sqlite3change
24ef0 67 72 6f 75 70 5f 64 65 6c 65 74 65 28 73 71 6c  group_delete(sql
24f00 69 74 65 33 5f 63 68 61 6e 67 65 67 72 6f 75 70  ite3_changegroup
24f10 20 2a 70 47 72 70 29 7b 0a 20 20 69 66 28 20 70   *pGrp){.  if( p
24f20 47 72 70 20 29 7b 0a 20 20 20 20 73 65 73 73 69  Grp ){.    sessi
24f30 6f 6e 44 65 6c 65 74 65 54 61 62 6c 65 28 70 47  onDeleteTable(pG
24f40 72 70 2d 3e 70 4c 69 73 74 29 3b 0a 20 20 20 20  rp->pList);.    
24f50 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 47 72  sqlite3_free(pGr
24f60 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a  p);.  }.}../* .*
24f70 2a 20 43 6f 6d 62 69 6e 65 20 74 77 6f 20 63 68  * Combine two ch
24f80 61 6e 67 65 73 65 74 73 20 74 6f 67 65 74 68 65  angesets togethe
24f90 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  r..*/.int sqlite
24fa0 33 63 68 61 6e 67 65 73 65 74 5f 63 6f 6e 63 61  3changeset_conca
24fb0 74 28 0a 20 20 69 6e 74 20 6e 4c 65 66 74 2c 20  t(.  int nLeft, 
24fc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24fd0 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
24fe0 66 20 62 79 74 65 73 20 69 6e 20 6c 68 73 20 69  f bytes in lhs i
24ff0 6e 70 75 74 20 2a 2f 0a 20 20 76 6f 69 64 20 2a  nput */.  void *
25000 70 4c 65 66 74 2c 20 20 20 20 20 20 20 20 20 20  pLeft,          
25010 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 68 73            /* Lhs
25020 20 69 6e 70 75 74 20 63 68 61 6e 67 65 73 65 74   input changeset
25030 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 69 67 68 74   */.  int nRight
25040 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
25050 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
25060 6f 66 20 62 79 74 65 73 20 69 6e 20 72 68 73 20  of bytes in rhs 
25070 69 6e 70 75 74 20 2a 2f 2c 0a 20 20 76 6f 69 64  input */,.  void
25080 20 2a 70 52 69 67 68 74 2c 20 20 20 20 20 20 20   *pRight,       
25090 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
250a0 68 73 20 69 6e 70 75 74 20 63 68 61 6e 67 65 73  hs input changes
250b0 65 74 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4f  et */.  int *pnO
250c0 75 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ut,             
250d0 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
250e0 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  Number of bytes 
250f0 69 6e 20 6f 75 74 70 75 74 20 63 68 61 6e 67 65  in output change
25100 73 65 74 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 2a  set */.  void **
25110 70 70 4f 75 74 20 20 20 20 20 20 20 20 20 20 20  ppOut           
25120 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
25130 20 63 68 61 6e 67 65 73 65 74 20 28 6c 65 66 74   changeset (left
25140 20 3c 63 6f 6e 63 61 74 3e 20 72 69 67 68 74 29   <concat> right)
25150 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33   */.){.  sqlite3
25160 5f 63 68 61 6e 67 65 67 72 6f 75 70 20 2a 70 47  _changegroup *pG
25170 72 70 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20  rp;.  int rc;.. 
25180 20 72 63 20 3d 20 73 71 6c 69 74 65 33 63 68 61   rc = sqlite3cha
25190 6e 67 65 67 72 6f 75 70 5f 6e 65 77 28 26 70 47  ngegroup_new(&pG
251a0 72 70 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  rp);.  if( rc==S
251b0 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
251c0 72 63 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e  rc = sqlite3chan
251d0 67 65 67 72 6f 75 70 5f 61 64 64 28 70 47 72 70  gegroup_add(pGrp
251e0 2c 20 6e 4c 65 66 74 2c 20 70 4c 65 66 74 29 3b  , nLeft, pLeft);
251f0 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53  .  }.  if( rc==S
25200 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
25210 72 63 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e  rc = sqlite3chan
25220 67 65 67 72 6f 75 70 5f 61 64 64 28 70 47 72 70  gegroup_add(pGrp
25230 2c 20 6e 52 69 67 68 74 2c 20 70 52 69 67 68 74  , nRight, pRight
25240 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d  );.  }.  if( rc=
25250 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
25260 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 63 68    rc = sqlite3ch
25270 61 6e 67 65 67 72 6f 75 70 5f 6f 75 74 70 75 74  angegroup_output
25280 28 70 47 72 70 2c 20 70 6e 4f 75 74 2c 20 70 70  (pGrp, pnOut, pp
25290 4f 75 74 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69  Out);.  }.  sqli
252a0 74 65 33 63 68 61 6e 67 65 67 72 6f 75 70 5f 64  te3changegroup_d
252b0 65 6c 65 74 65 28 70 47 72 70 29 3b 0a 0a 20 20  elete(pGrp);..  
252c0 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
252d0 0a 2a 2a 20 53 74 72 65 61 6d 69 6e 67 20 76 65  .** Streaming ve
252e0 72 73 69 6f 6e 20 6f 66 20 73 71 6c 69 74 65 33  rsion of sqlite3
252f0 63 68 61 6e 67 65 73 65 74 5f 63 6f 6e 63 61 74  changeset_concat
25300 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ()..*/.int sqlit
25310 65 33 63 68 61 6e 67 65 73 65 74 5f 63 6f 6e 63  e3changeset_conc
25320 61 74 5f 73 74 72 6d 28 0a 20 20 69 6e 74 20 28  at_strm(.  int (
25330 2a 78 49 6e 70 75 74 41 29 28 76 6f 69 64 20 2a  *xInputA)(void *
25340 70 49 6e 2c 20 76 6f 69 64 20 2a 70 44 61 74 61  pIn, void *pData
25350 2c 20 69 6e 74 20 2a 70 6e 44 61 74 61 29 2c 0a  , int *pnData),.
25360 20 20 76 6f 69 64 20 2a 70 49 6e 41 2c 0a 20 20    void *pInA,.  
25370 69 6e 74 20 28 2a 78 49 6e 70 75 74 42 29 28 76  int (*xInputB)(v
25380 6f 69 64 20 2a 70 49 6e 2c 20 76 6f 69 64 20 2a  oid *pIn, void *
25390 70 44 61 74 61 2c 20 69 6e 74 20 2a 70 6e 44 61  pData, int *pnDa
253a0 74 61 29 2c 0a 20 20 76 6f 69 64 20 2a 70 49 6e  ta),.  void *pIn
253b0 42 2c 0a 20 20 69 6e 74 20 28 2a 78 4f 75 74 70  B,.  int (*xOutp
253c0 75 74 29 28 76 6f 69 64 20 2a 70 4f 75 74 2c 20  ut)(void *pOut, 
253d0 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 44 61 74  const void *pDat
253e0 61 2c 20 69 6e 74 20 6e 44 61 74 61 29 2c 0a 20  a, int nData),. 
253f0 20 76 6f 69 64 20 2a 70 4f 75 74 0a 29 7b 0a 20   void *pOut.){. 
25400 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 67   sqlite3_changeg
25410 72 6f 75 70 20 2a 70 47 72 70 3b 0a 20 20 69 6e  roup *pGrp;.  in
25420 74 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71  t rc;..  rc = sq
25430 6c 69 74 65 33 63 68 61 6e 67 65 67 72 6f 75 70  lite3changegroup
25440 5f 6e 65 77 28 26 70 47 72 70 29 3b 0a 20 20 69  _new(&pGrp);.  i
25450 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
25460 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   ){.    rc = sql
25470 69 74 65 33 63 68 61 6e 67 65 67 72 6f 75 70 5f  ite3changegroup_
25480 61 64 64 5f 73 74 72 6d 28 70 47 72 70 2c 20 78  add_strm(pGrp, x
25490 49 6e 70 75 74 41 2c 20 70 49 6e 41 29 3b 0a 20  InputA, pInA);. 
254a0 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c   }.  if( rc==SQL
254b0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
254c0 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65   = sqlite3change
254d0 67 72 6f 75 70 5f 61 64 64 5f 73 74 72 6d 28 70  group_add_strm(p
254e0 47 72 70 2c 20 78 49 6e 70 75 74 42 2c 20 70 49  Grp, xInputB, pI
254f0 6e 42 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72  nB);.  }.  if( r
25500 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
25510 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
25520 63 68 61 6e 67 65 67 72 6f 75 70 5f 6f 75 74 70  changegroup_outp
25530 75 74 5f 73 74 72 6d 28 70 47 72 70 2c 20 78 4f  ut_strm(pGrp, xO
25540 75 74 70 75 74 2c 20 70 4f 75 74 29 3b 0a 20 20  utput, pOut);.  
25550 7d 0a 20 20 73 71 6c 69 74 65 33 63 68 61 6e 67  }.  sqlite3chang
25560 65 67 72 6f 75 70 5f 64 65 6c 65 74 65 28 70 47  egroup_delete(pG
25570 72 70 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72  rp);..  return r
25580 63 3b 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20  c;.}..#endif /* 
25590 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 53 45  SQLITE_ENABLE_SE
255a0 53 53 49 4f 4e 20 26 26 20 53 51 4c 49 54 45 5f  SSION && SQLITE_
255b0 45 4e 41 42 4c 45 5f 50 52 45 55 50 44 41 54 45  ENABLE_PREUPDATE
255c0 5f 48 4f 4f 4b 20 2a 2f 0a                       _HOOK */.