/ Hex Artifact Content
Login

Artifact 37485891b4add26cf61495df193c419f36556a32:


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 6d 65  n);.          me
3760: 6d 63 70 79 28 26 61 42 75 66 5b 6e 56 61 72 69  mcpy(&aBuf[nVari
3770: 6e 74 20 2b 20 31 5d 2c 20 65 54 79 70 65 3d 3d  nt + 1], eType==
3780: 53 51 4c 49 54 45 5f 54 45 58 54 20 3f 20 0a 20  SQLITE_TEXT ? . 
3790: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c               sql
37a0: 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28  ite3_value_text(
37b0: 70 56 61 6c 75 65 29 20 3a 20 73 71 6c 69 74 65  pValue) : sqlite
37c0: 33 5f 76 61 6c 75 65 5f 62 6c 6f 62 28 70 56 61  3_value_blob(pVa
37d0: 6c 75 65 29 2c 20 6e 0a 20 20 20 20 20 20 20 20  lue), n.        
37e0: 20 20 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20    );.        }. 
37f0: 20 0a 20 20 20 20 20 20 20 20 6e 42 79 74 65 20   .        nByte 
3800: 3d 20 31 20 2b 20 6e 56 61 72 69 6e 74 20 2b 20  = 1 + nVarint + 
3810: 6e 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  n;.        break
3820: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
3830: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 6e 42 79    }else{.    nBy
3840: 74 65 20 3d 20 31 3b 0a 20 20 20 20 69 66 28 20  te = 1;.    if( 
3850: 61 42 75 66 20 29 20 61 42 75 66 5b 30 5d 20 3d  aBuf ) aBuf[0] =
3860: 20 27 5c 30 27 3b 0a 20 20 7d 0a 0a 20 20 69 66   '\0';.  }..  if
3870: 28 20 70 6e 57 72 69 74 65 20 29 20 2a 70 6e 57  ( pnWrite ) *pnW
3880: 72 69 74 65 20 2b 3d 20 6e 42 79 74 65 3b 0a 20  rite += nByte;. 
3890: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
38a0: 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  K;.}.../*.** Thi
38b0: 73 20 6d 61 63 72 6f 20 69 73 20 75 73 65 64 20  s macro is used 
38c0: 74 6f 20 63 61 6c 63 75 6c 61 74 65 20 68 61 73  to calculate has
38d0: 68 20 6b 65 79 20 76 61 6c 75 65 73 20 66 6f 72  h key values for
38e0: 20 64 61 74 61 20 73 74 72 75 63 74 75 72 65 73   data structures
38f0: 2e 20 49 6e 0a 2a 2a 20 6f 72 64 65 72 20 74 6f  . In.** order to
3900: 20 75 73 65 20 74 68 69 73 20 6d 61 63 72 6f 2c   use this macro,
3910: 20 74 68 65 20 65 6e 74 69 72 65 20 64 61 74 61   the entire data
3920: 20 73 74 72 75 63 74 75 72 65 20 6d 75 73 74 20   structure must 
3930: 62 65 20 72 65 70 72 65 73 65 6e 74 65 64 0a 2a  be represented.*
3940: 2a 20 61 73 20 61 20 73 65 72 69 65 73 20 6f 66  * as a series of
3950: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 65 67 65   unsigned intege
3960: 72 73 2e 20 49 6e 20 6f 72 64 65 72 20 74 6f 20  rs. In order to 
3970: 63 61 6c 63 75 6c 61 74 65 20 61 20 68 61 73 68  calculate a hash
3980: 2d 6b 65 79 20 76 61 6c 75 65 0a 2a 2a 20 66 6f  -key value.** fo
3990: 72 20 61 20 64 61 74 61 20 73 74 72 75 63 74 75  r a data structu
39a0: 72 65 20 72 65 70 72 65 73 65 6e 74 65 64 20 61  re represented a
39b0: 73 20 74 68 72 65 65 20 73 75 63 68 20 69 6e 74  s three such int
39c0: 65 67 65 72 73 2c 20 74 68 65 20 6d 61 63 72 6f  egers, the macro
39d0: 20 6d 61 79 0a 2a 2a 20 74 68 65 6e 20 62 65 20   may.** then be 
39e0: 75 73 65 64 20 61 73 20 66 6f 6c 6c 6f 77 73 3a  used as follows:
39f0: 0a 2a 2a 0a 2a 2a 20 20 20 20 69 6e 74 20 68 61  .**.**    int ha
3a00: 73 68 5f 6b 65 79 5f 76 61 6c 75 65 3b 0a 2a 2a  sh_key_value;.**
3a10: 20 20 20 20 68 61 73 68 5f 6b 65 79 5f 76 61 6c      hash_key_val
3a20: 75 65 20 3d 20 48 41 53 48 5f 41 50 50 45 4e 44  ue = HASH_APPEND
3a30: 28 30 2c 20 3c 76 61 6c 75 65 20 31 3e 29 3b 0a  (0, <value 1>);.
3a40: 2a 2a 20 20 20 20 68 61 73 68 5f 6b 65 79 5f 76  **    hash_key_v
3a50: 61 6c 75 65 20 3d 20 48 41 53 48 5f 41 50 50 45  alue = HASH_APPE
3a60: 4e 44 28 68 61 73 68 5f 6b 65 79 5f 76 61 6c 75  ND(hash_key_valu
3a70: 65 2c 20 3c 76 61 6c 75 65 20 32 3e 29 3b 0a 2a  e, <value 2>);.*
3a80: 2a 20 20 20 20 68 61 73 68 5f 6b 65 79 5f 76 61  *    hash_key_va
3a90: 6c 75 65 20 3d 20 48 41 53 48 5f 41 50 50 45 4e  lue = HASH_APPEN
3aa0: 44 28 68 61 73 68 5f 6b 65 79 5f 76 61 6c 75 65  D(hash_key_value
3ab0: 2c 20 3c 76 61 6c 75 65 20 33 3e 29 3b 0a 2a 2a  , <value 3>);.**
3ac0: 0a 2a 2a 20 49 6e 20 70 72 61 63 74 69 63 65 2c  .** In practice,
3ad0: 20 74 68 65 20 64 61 74 61 20 73 74 72 75 63 74   the data struct
3ae0: 75 72 65 73 20 74 68 69 73 20 6d 61 63 72 6f 20  ures this macro 
3af0: 69 73 20 75 73 65 64 20 66 6f 72 20 61 72 65 20  is used for are 
3b00: 74 68 65 20 70 72 69 6d 61 72 79 0a 2a 2a 20 6b  the primary.** k
3b10: 65 79 20 76 61 6c 75 65 73 20 6f 66 20 6d 6f 64  ey values of mod
3b20: 69 66 69 65 64 20 72 6f 77 73 2e 0a 2a 2f 0a 23  ified rows..*/.#
3b30: 64 65 66 69 6e 65 20 48 41 53 48 5f 41 50 50 45  define HASH_APPE
3b40: 4e 44 28 68 61 73 68 2c 20 61 64 64 29 20 28 28  ND(hash, add) ((
3b50: 68 61 73 68 29 20 3c 3c 20 33 29 20 5e 20 28 68  hash) << 3) ^ (h
3b60: 61 73 68 29 20 5e 20 28 75 6e 73 69 67 6e 65 64  ash) ^ (unsigned
3b70: 20 69 6e 74 29 28 61 64 64 29 0a 0a 2f 2a 0a 2a   int)(add)../*.*
3b80: 2a 20 41 70 70 65 6e 64 20 74 68 65 20 68 61 73  * Append the has
3b90: 68 20 6f 66 20 74 68 65 20 36 34 2d 62 69 74 20  h of the 64-bit 
3ba0: 69 6e 74 65 67 65 72 20 70 61 73 73 65 64 20 61  integer passed a
3bb0: 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67  s the second arg
3bc0: 75 6d 65 6e 74 20 74 6f 20 74 68 65 0a 2a 2a 20  ument to the.** 
3bd0: 68 61 73 68 2d 6b 65 79 20 76 61 6c 75 65 20 70  hash-key value p
3be0: 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69 72  assed as the fir
3bf0: 73 74 2e 20 52 65 74 75 72 6e 20 74 68 65 20 6e  st. Return the n
3c00: 65 77 20 68 61 73 68 2d 6b 65 79 20 76 61 6c 75  ew hash-key valu
3c10: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 75 6e 73  e..*/.static uns
3c20: 69 67 6e 65 64 20 69 6e 74 20 73 65 73 73 69 6f  igned int sessio
3c30: 6e 48 61 73 68 41 70 70 65 6e 64 49 36 34 28 75  nHashAppendI64(u
3c40: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 2c 20 69  nsigned int h, i
3c50: 36 34 20 69 29 7b 0a 20 20 68 20 3d 20 48 41 53  64 i){.  h = HAS
3c60: 48 5f 41 50 50 45 4e 44 28 68 2c 20 69 20 26 20  H_APPEND(h, i & 
3c70: 30 78 46 46 46 46 46 46 46 46 29 3b 0a 20 20 72  0xFFFFFFFF);.  r
3c80: 65 74 75 72 6e 20 48 41 53 48 5f 41 50 50 45 4e  eturn HASH_APPEN
3c90: 44 28 68 2c 20 28 69 3e 3e 33 32 29 26 30 78 46  D(h, (i>>32)&0xF
3ca0: 46 46 46 46 46 46 46 29 3b 0a 7d 0a 0a 2f 2a 0a  FFFFFFF);.}../*.
3cb0: 2a 2a 20 41 70 70 65 6e 64 20 74 68 65 20 68 61  ** Append the ha
3cc0: 73 68 20 6f 66 20 74 68 65 20 62 6c 6f 62 20 70  sh of the blob p
3cd0: 61 73 73 65 64 20 76 69 61 20 74 68 65 20 73 65  assed via the se
3ce0: 63 6f 6e 64 20 61 6e 64 20 74 68 69 72 64 20 61  cond and third a
3cf0: 72 67 75 6d 65 6e 74 73 20 74 6f 20 0a 2a 2a 20  rguments to .** 
3d00: 74 68 65 20 68 61 73 68 2d 6b 65 79 20 76 61 6c  the hash-key val
3d10: 75 65 20 70 61 73 73 65 64 20 61 73 20 74 68 65  ue passed as the
3d20: 20 66 69 72 73 74 2e 20 52 65 74 75 72 6e 20 74   first. Return t
3d30: 68 65 20 6e 65 77 20 68 61 73 68 2d 6b 65 79 20  he new hash-key 
3d40: 76 61 6c 75 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  value..*/.static
3d50: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 73 65   unsigned int se
3d60: 73 73 69 6f 6e 48 61 73 68 41 70 70 65 6e 64 42  ssionHashAppendB
3d70: 6c 6f 62 28 75 6e 73 69 67 6e 65 64 20 69 6e 74  lob(unsigned int
3d80: 20 68 2c 20 69 6e 74 20 6e 2c 20 63 6f 6e 73 74   h, int n, const
3d90: 20 75 38 20 2a 7a 29 7b 0a 20 20 69 6e 74 20 69   u8 *z){.  int i
3da0: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e  ;.  for(i=0; i<n
3db0: 3b 20 69 2b 2b 29 20 68 20 3d 20 48 41 53 48 5f  ; i++) h = HASH_
3dc0: 41 50 50 45 4e 44 28 68 2c 20 7a 5b 69 5d 29 3b  APPEND(h, z[i]);
3dd0: 0a 20 20 72 65 74 75 72 6e 20 68 3b 0a 7d 0a 0a  .  return h;.}..
3de0: 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 74 68 65  /*.** Append the
3df0: 20 68 61 73 68 20 6f 66 20 74 68 65 20 64 61 74   hash of the dat
3e00: 61 20 74 79 70 65 20 70 61 73 73 65 64 20 61 73  a type passed as
3e10: 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67 75   the second argu
3e20: 6d 65 6e 74 20 74 6f 20 74 68 65 0a 2a 2a 20 68  ment to the.** h
3e30: 61 73 68 2d 6b 65 79 20 76 61 6c 75 65 20 70 61  ash-key value pa
3e40: 73 73 65 64 20 61 73 20 74 68 65 20 66 69 72 73  ssed as the firs
3e50: 74 2e 20 52 65 74 75 72 6e 20 74 68 65 20 6e 65  t. Return the ne
3e60: 77 20 68 61 73 68 2d 6b 65 79 20 76 61 6c 75 65  w hash-key value
3e70: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 75 6e 73 69  ..*/.static unsi
3e80: 67 6e 65 64 20 69 6e 74 20 73 65 73 73 69 6f 6e  gned int session
3e90: 48 61 73 68 41 70 70 65 6e 64 54 79 70 65 28 75  HashAppendType(u
3ea0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 2c 20 69  nsigned int h, i
3eb0: 6e 74 20 65 54 79 70 65 29 7b 0a 20 20 72 65 74  nt eType){.  ret
3ec0: 75 72 6e 20 48 41 53 48 5f 41 50 50 45 4e 44 28  urn HASH_APPEND(
3ed0: 68 2c 20 65 54 79 70 65 29 3b 0a 7d 0a 0a 2f 2a  h, eType);.}../*
3ee0: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
3ef0: 6e 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 63 61  n may only be ca
3f00: 6c 6c 65 64 20 66 72 6f 6d 20 77 69 74 68 69 6e  lled from within
3f10: 20 61 20 70 72 65 2d 75 70 64 61 74 65 20 63 61   a pre-update ca
3f20: 6c 6c 62 61 63 6b 2e 0a 2a 2a 20 49 74 20 63 61  llback..** It ca
3f30: 6c 63 75 6c 61 74 65 73 20 61 20 68 61 73 68 20  lculates a hash 
3f40: 62 61 73 65 64 20 6f 6e 20 74 68 65 20 70 72 69  based on the pri
3f50: 6d 61 72 79 20 6b 65 79 20 76 61 6c 75 65 73 20  mary key values 
3f60: 6f 66 20 74 68 65 20 6f 6c 64 2e 2a 20 6f 72 20  of the old.* or 
3f70: 0a 2a 2a 20 6e 65 77 2e 2a 20 72 6f 77 20 63 75  .** new.* row cu
3f80: 72 72 65 6e 74 6c 79 20 61 76 61 69 6c 61 62 6c  rrently availabl
3f90: 65 20 61 6e 64 2c 20 61 73 73 75 6d 69 6e 67 20  e and, assuming 
3fa0: 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c  no error occurs,
3fb0: 20 77 72 69 74 65 73 20 69 74 20 74 6f 0a 2a 2a   writes it to.**
3fc0: 20 2a 70 69 48 61 73 68 20 62 65 66 6f 72 65 20   *piHash before 
3fd0: 72 65 74 75 72 6e 69 6e 67 2e 20 49 66 20 74 68  returning. If th
3fe0: 65 20 70 72 69 6d 61 72 79 20 6b 65 79 20 63 6f  e primary key co
3ff0: 6e 74 61 69 6e 73 20 6f 6e 65 20 6f 72 20 6d 6f  ntains one or mo
4000: 72 65 20 4e 55 4c 4c 0a 2a 2a 20 76 61 6c 75 65  re NULL.** value
4010: 73 2c 20 2a 70 62 4e 75 6c 6c 50 4b 20 69 73 20  s, *pbNullPK is 
4020: 73 65 74 20 74 6f 20 74 72 75 65 20 62 65 66 6f  set to true befo
4030: 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2a  re returning..**
4040: 0a 2a 2a 20 49 66 20 61 6e 20 65 72 72 6f 72 20  .** If an error 
4050: 6f 63 63 75 72 73 2c 20 61 6e 20 53 51 4c 69 74  occurs, an SQLit
4060: 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69 73 20  e error code is 
4070: 72 65 74 75 72 6e 65 64 20 61 6e 64 20 74 68 65  returned and the
4080: 20 66 69 6e 61 6c 20 76 61 6c 75 65 73 0a 2a 2a   final values.**
4090: 20 6f 66 20 2a 70 69 48 61 73 68 20 61 73 6e 20   of *piHash asn 
40a0: 2a 70 62 4e 75 6c 6c 50 4b 20 61 72 65 20 75 6e  *pbNullPK are un
40b0: 64 65 66 69 6e 65 64 2e 20 4f 74 68 65 72 77 69  defined. Otherwi
40c0: 73 65 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73  se, SQLITE_OK is
40d0: 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20 61 6e 64   returned.** and
40e0: 20 74 68 65 20 6f 75 74 70 75 74 20 76 61 72 69   the output vari
40f0: 61 62 6c 65 73 20 61 72 65 20 73 65 74 20 61 73  ables are set as
4100: 20 64 65 73 63 72 69 62 65 64 20 61 62 6f 76 65   described above
4110: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
4120: 73 65 73 73 69 6f 6e 50 72 65 75 70 64 61 74 65  sessionPreupdate
4130: 48 61 73 68 28 0a 20 20 73 71 6c 69 74 65 33 5f  Hash(.  sqlite3_
4140: 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f  session *pSessio
4150: 6e 2c 20 20 20 20 20 20 2f 2a 20 53 65 73 73 69  n,      /* Sessi
4160: 6f 6e 20 6f 62 6a 65 63 74 20 74 68 61 74 20 6f  on object that o
4170: 77 6e 73 20 70 54 61 62 20 2a 2f 0a 20 20 53 65  wns pTab */.  Se
4180: 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62  ssionTable *pTab
4190: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
41a0: 20 53 65 73 73 69 6f 6e 20 74 61 62 6c 65 20 68   Session table h
41b0: 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 62  andle */.  int b
41c0: 4e 65 77 2c 20 20 20 20 20 20 20 20 20 20 20 20  New,            
41d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
41e0: 75 65 20 74 6f 20 68 61 73 68 20 74 68 65 20 6e  ue to hash the n
41f0: 65 77 2e 2a 20 50 4b 20 2a 2f 0a 20 20 69 6e 74  ew.* PK */.  int
4200: 20 2a 70 69 48 61 73 68 2c 20 20 20 20 20 20 20   *piHash,       
4210: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4220: 4f 55 54 3a 20 48 61 73 68 20 76 61 6c 75 65 20  OUT: Hash value 
4230: 2a 2f 0a 20 20 69 6e 74 20 2a 70 62 4e 75 6c 6c  */.  int *pbNull
4240: 50 4b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  PK              
4250: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 72 75       /* OUT: Tru
4260: 65 20 69 66 20 74 68 65 72 65 20 61 72 65 20 4e  e if there are N
4270: 55 4c 4c 20 76 61 6c 75 65 73 20 69 6e 20 50 4b  ULL values in PK
4280: 20 2a 2f 0a 29 7b 0a 20 20 75 6e 73 69 67 6e 65   */.){.  unsigne
4290: 64 20 69 6e 74 20 68 20 3d 20 30 3b 20 20 20 20  d int h = 0;    
42a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68           /* Hash
42b0: 20 76 61 6c 75 65 20 74 6f 20 72 65 74 75 72 6e   value to return
42c0: 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20   */.  int i;    
42d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
42e0: 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f        /* Used to
42f0: 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67 68   iterate through
4300: 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 0a 20 20 61   columns */..  a
4310: 73 73 65 72 74 28 20 2a 70 62 4e 75 6c 6c 50 4b  ssert( *pbNullPK
4320: 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==0 );.  assert(
4330: 20 70 54 61 62 2d 3e 6e 43 6f 6c 3d 3d 70 53 65   pTab->nCol==pSe
4340: 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 43 6f 75  ssion->hook.xCou
4350: 6e 74 28 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f  nt(pSession->hoo
4360: 6b 2e 70 43 74 78 29 20 29 3b 0a 20 20 66 6f 72  k.pCtx) );.  for
4370: 28 69 3d 30 3b 20 69 3c 70 54 61 62 2d 3e 6e 43  (i=0; i<pTab->nC
4380: 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66  ol; i++){.    if
4390: 28 20 70 54 61 62 2d 3e 61 62 50 4b 5b 69 5d 20  ( pTab->abPK[i] 
43a0: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72 63 3b  ){.      int rc;
43b0: 0a 20 20 20 20 20 20 69 6e 74 20 65 54 79 70 65  .      int eType
43c0: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
43d0: 76 61 6c 75 65 20 2a 70 56 61 6c 3b 0a 0a 20 20  value *pVal;..  
43e0: 20 20 20 20 69 66 28 20 62 4e 65 77 20 29 7b 0a      if( bNew ){.
43f0: 20 20 20 20 20 20 20 20 72 63 20 3d 20 70 53 65          rc = pSe
4400: 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 4e 65 77  ssion->hook.xNew
4410: 28 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e  (pSession->hook.
4420: 70 43 74 78 2c 20 69 2c 20 26 70 56 61 6c 29 3b  pCtx, i, &pVal);
4430: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
4440: 20 20 20 20 20 20 72 63 20 3d 20 70 53 65 73 73        rc = pSess
4450: 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 4f 6c 64 28 70  ion->hook.xOld(p
4460: 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 70 43  Session->hook.pC
4470: 74 78 2c 20 69 2c 20 26 70 56 61 6c 29 3b 0a 20  tx, i, &pVal);. 
4480: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
4490: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
44a0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20   return rc;..   
44b0: 20 20 20 65 54 79 70 65 20 3d 20 73 71 6c 69 74     eType = sqlit
44c0: 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 70 56  e3_value_type(pV
44d0: 61 6c 29 3b 0a 20 20 20 20 20 20 68 20 3d 20 73  al);.      h = s
44e0: 65 73 73 69 6f 6e 48 61 73 68 41 70 70 65 6e 64  essionHashAppend
44f0: 54 79 70 65 28 68 2c 20 65 54 79 70 65 29 3b 0a  Type(h, eType);.
4500: 20 20 20 20 20 20 69 66 28 20 65 54 79 70 65 3d        if( eType=
4510: 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20  =SQLITE_INTEGER 
4520: 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45  || eType==SQLITE
4530: 5f 46 4c 4f 41 54 20 29 7b 0a 20 20 20 20 20 20  _FLOAT ){.      
4540: 20 20 69 36 34 20 69 56 61 6c 3b 0a 20 20 20 20    i64 iVal;.    
4550: 20 20 20 20 69 66 28 20 65 54 79 70 65 3d 3d 53      if( eType==S
4560: 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b  QLITE_INTEGER ){
4570: 0a 20 20 20 20 20 20 20 20 20 20 69 56 61 6c 20  .          iVal 
4580: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
4590: 69 6e 74 36 34 28 70 56 61 6c 29 3b 0a 20 20 20  int64(pVal);.   
45a0: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
45b0: 20 20 20 20 20 20 64 6f 75 62 6c 65 20 72 56 61        double rVa
45c0: 6c 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  l = sqlite3_valu
45d0: 65 5f 64 6f 75 62 6c 65 28 70 56 61 6c 29 3b 0a  e_double(pVal);.
45e0: 20 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74            assert
45f0: 28 20 73 69 7a 65 6f 66 28 69 56 61 6c 29 3d 3d  ( sizeof(iVal)==
4600: 38 20 26 26 20 73 69 7a 65 6f 66 28 72 56 61 6c  8 && sizeof(rVal
4610: 29 3d 3d 38 20 29 3b 0a 20 20 20 20 20 20 20 20  )==8 );.        
4620: 20 20 6d 65 6d 63 70 79 28 26 69 56 61 6c 2c 20    memcpy(&iVal, 
4630: 26 72 56 61 6c 2c 20 38 29 3b 0a 20 20 20 20 20  &rVal, 8);.     
4640: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 68 20 3d     }.        h =
4650: 20 73 65 73 73 69 6f 6e 48 61 73 68 41 70 70 65   sessionHashAppe
4660: 6e 64 49 36 34 28 68 2c 20 69 56 61 6c 29 3b 0a  ndI64(h, iVal);.
4670: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
4680: 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 54 45  eType==SQLITE_TE
4690: 58 54 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c  XT || eType==SQL
46a0: 49 54 45 5f 42 4c 4f 42 20 29 7b 0a 20 20 20 20  ITE_BLOB ){.    
46b0: 20 20 20 20 63 6f 6e 73 74 20 75 38 20 2a 7a 3b      const u8 *z;
46c0: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 3b 0a  .        int n;.
46d0: 20 20 20 20 20 20 20 20 69 66 28 20 65 54 79 70          if( eTyp
46e0: 65 3d 3d 53 51 4c 49 54 45 5f 54 45 58 54 20 29  e==SQLITE_TEXT )
46f0: 7b 0a 20 20 20 20 20 20 20 20 20 20 7a 20 3d 20  {.          z = 
4700: 28 63 6f 6e 73 74 20 75 38 20 2a 29 73 71 6c 69  (const u8 *)sqli
4710: 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 70  te3_value_text(p
4720: 56 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 7d 65  Val);.        }e
4730: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 7a  lse{.          z
4740: 20 3d 20 28 63 6f 6e 73 74 20 75 38 20 2a 29 73   = (const u8 *)s
4750: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 6c 6f  qlite3_value_blo
4760: 62 28 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 20  b(pVal);.       
4770: 20 7d 0a 20 20 20 20 20 20 20 20 6e 20 3d 20 73   }.        n = s
4780: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 79 74  qlite3_value_byt
4790: 65 73 28 70 56 61 6c 29 3b 0a 20 20 20 20 20 20  es(pVal);.      
47a0: 20 20 69 66 28 20 21 7a 20 26 26 20 28 65 54 79    if( !z && (eTy
47b0: 70 65 21 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 20  pe!=SQLITE_BLOB 
47c0: 7c 7c 20 6e 3e 30 29 20 29 20 72 65 74 75 72 6e  || n>0) ) return
47d0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
47e0: 20 20 20 20 20 20 20 68 20 3d 20 73 65 73 73 69         h = sessi
47f0: 6f 6e 48 61 73 68 41 70 70 65 6e 64 42 6c 6f 62  onHashAppendBlob
4800: 28 68 2c 20 6e 2c 20 7a 29 3b 0a 20 20 20 20 20  (h, n, z);.     
4810: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
4820: 61 73 73 65 72 74 28 20 65 54 79 70 65 3d 3d 53  assert( eType==S
4830: 51 4c 49 54 45 5f 4e 55 4c 4c 20 29 3b 0a 20 20  QLITE_NULL );.  
4840: 20 20 20 20 20 20 2a 70 62 4e 75 6c 6c 50 4b 20        *pbNullPK 
4850: 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  = 1;.      }.   
4860: 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 69 48 61 73   }.  }..  *piHas
4870: 68 20 3d 20 28 68 20 25 20 70 54 61 62 2d 3e 6e  h = (h % pTab->n
4880: 43 68 61 6e 67 65 29 3b 0a 20 20 72 65 74 75 72  Change);.  retur
4890: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
48a0: 2f 2a 0a 2a 2a 20 54 68 65 20 62 75 66 66 65 72  /*.** The buffer
48b0: 20 74 68 61 74 20 74 68 65 20 61 72 67 75 6d 65   that the argume
48c0: 6e 74 20 70 6f 69 6e 74 73 20 74 6f 20 63 6f 6e  nt points to con
48d0: 74 61 69 6e 73 20 61 20 73 65 72 69 61 6c 69 7a  tains a serializ
48e0: 65 64 20 53 51 4c 20 76 61 6c 75 65 2e 0a 2a 2a  ed SQL value..**
48f0: 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62   Return the numb
4900: 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 73  er of bytes of s
4910: 70 61 63 65 20 6f 63 63 75 70 69 65 64 20 62 79  pace occupied by
4920: 20 74 68 65 20 76 61 6c 75 65 20 28 69 6e 63 6c   the value (incl
4930: 75 64 69 6e 67 0a 2a 2a 20 74 68 65 20 74 79 70  uding.** the typ
4940: 65 20 62 79 74 65 29 2e 0a 2a 2f 0a 73 74 61 74  e byte)..*/.stat
4950: 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 53 65  ic int sessionSe
4960: 72 69 61 6c 4c 65 6e 28 75 38 20 2a 61 29 7b 0a  rialLen(u8 *a){.
4970: 20 20 69 6e 74 20 65 20 3d 20 2a 61 3b 0a 20 20    int e = *a;.  
4980: 69 6e 74 20 6e 3b 0a 20 20 69 66 28 20 65 3d 3d  int n;.  if( e==
4990: 30 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20  0 ) return 1;.  
49a0: 69 66 28 20 65 3d 3d 53 51 4c 49 54 45 5f 4e 55  if( e==SQLITE_NU
49b0: 4c 4c 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20  LL ) return 1;. 
49c0: 20 69 66 28 20 65 3d 3d 53 51 4c 49 54 45 5f 49   if( e==SQLITE_I
49d0: 4e 54 45 47 45 52 20 7c 7c 20 65 3d 3d 53 51 4c  NTEGER || e==SQL
49e0: 49 54 45 5f 46 4c 4f 41 54 20 29 20 72 65 74 75  ITE_FLOAT ) retu
49f0: 72 6e 20 39 3b 0a 20 20 72 65 74 75 72 6e 20 73  rn 9;.  return s
4a00: 65 73 73 69 6f 6e 56 61 72 69 6e 74 47 65 74 28  essionVarintGet(
4a10: 26 61 5b 31 5d 2c 20 26 6e 29 20 2b 20 31 20 2b  &a[1], &n) + 1 +
4a20: 20 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 42 61 73   n;.}../*.** Bas
4a30: 65 64 20 6f 6e 20 74 68 65 20 70 72 69 6d 61 72  ed on the primar
4a40: 79 20 6b 65 79 20 76 61 6c 75 65 73 20 73 74 6f  y key values sto
4a50: 72 65 64 20 69 6e 20 63 68 61 6e 67 65 20 61 52  red in change aR
4a60: 65 63 6f 72 64 2c 20 63 61 6c 63 75 6c 61 74 65  ecord, calculate
4a70: 20 61 0a 2a 2a 20 68 61 73 68 20 6b 65 79 2e 20   a.** hash key. 
4a80: 41 73 73 75 6d 65 20 74 68 65 20 68 61 73 20 74  Assume the has t
4a90: 61 62 6c 65 20 68 61 73 20 6e 42 75 63 6b 65 74  able has nBucket
4aa0: 20 62 75 63 6b 65 74 73 2e 20 54 68 65 20 68 61   buckets. The ha
4ab0: 73 68 20 6b 65 79 73 0a 2a 2a 20 63 61 6c 63 75  sh keys.** calcu
4ac0: 6c 61 74 65 64 20 62 79 20 74 68 69 73 20 66 75  lated by this fu
4ad0: 6e 63 74 69 6f 6e 20 61 72 65 20 63 6f 6d 70 61  nction are compa
4ae0: 74 69 62 6c 65 20 77 69 74 68 20 74 68 6f 73 65  tible with those
4af0: 20 63 61 6c 63 75 6c 61 74 65 64 20 62 79 0a 2a   calculated by.*
4b00: 2a 20 73 65 73 73 69 6f 6e 50 72 65 75 70 64 61  * sessionPreupda
4b10: 74 65 48 61 73 68 28 29 2e 0a 2a 2a 0a 2a 2a 20  teHash()..**.** 
4b20: 54 68 65 20 62 50 6b 4f 6e 6c 79 20 61 72 67 75  The bPkOnly argu
4b30: 6d 65 6e 74 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f  ment is non-zero
4b40: 20 69 66 20 74 68 65 20 72 65 63 6f 72 64 20 61   if the record a
4b50: 74 20 61 52 65 63 6f 72 64 5b 5d 20 69 73 20 66  t aRecord[] is f
4b60: 72 6f 6d 0a 2a 2a 20 61 20 70 61 74 63 68 73 65  rom.** a patchse
4b70: 74 20 44 45 4c 45 54 45 2e 20 49 6e 20 74 68 69  t DELETE. In thi
4b80: 73 20 63 61 73 65 20 74 68 65 20 6e 6f 6e 2d 50  s case the non-P
4b90: 4b 20 66 69 65 6c 64 73 20 61 72 65 20 6f 6d 69  K fields are omi
4ba0: 74 74 65 64 20 65 6e 74 69 72 65 6c 79 2e 0a 2a  tted entirely..*
4bb0: 2f 0a 73 74 61 74 69 63 20 75 6e 73 69 67 6e 65  /.static unsigne
4bc0: 64 20 69 6e 74 20 73 65 73 73 69 6f 6e 43 68 61  d int sessionCha
4bd0: 6e 67 65 48 61 73 68 28 0a 20 20 53 65 73 73 69  ngeHash(.  Sessi
4be0: 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 20  onTable *pTab,  
4bf0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61             /* Ta
4c00: 62 6c 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20  ble handle */.  
4c10: 69 6e 74 20 62 50 6b 4f 6e 6c 79 2c 20 20 20 20  int bPkOnly,    
4c20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4c30: 2f 2a 20 52 65 63 6f 72 64 20 63 6f 6e 73 69 73  /* Record consis
4c40: 74 73 20 6f 66 20 50 4b 20 66 69 65 6c 64 73 20  ts of PK fields 
4c50: 6f 6e 6c 79 20 2a 2f 0a 20 20 75 38 20 2a 61 52  only */.  u8 *aR
4c60: 65 63 6f 72 64 2c 20 20 20 20 20 20 20 20 20 20  ecord,          
4c70: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 61            /* Cha
4c80: 6e 67 65 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20  nge record */.  
4c90: 69 6e 74 20 6e 42 75 63 6b 65 74 20 20 20 20 20  int nBucket     
4ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4cb0: 2f 2a 20 41 73 73 75 6d 65 20 74 68 69 73 20 6d  /* Assume this m
4cc0: 61 6e 79 20 62 75 63 6b 65 74 73 20 69 6e 20 68  any buckets in h
4cd0: 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 29 7b 0a  ash table */.){.
4ce0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68    unsigned int h
4cf0: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
4d00: 20 20 2f 2a 20 56 61 6c 75 65 20 74 6f 20 72 65    /* Value to re
4d10: 74 75 72 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 3b  turn */.  int i;
4d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4d30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65            /* Use
4d40: 64 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72  d to iterate thr
4d50: 6f 75 67 68 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a  ough columns */.
4d60: 20 20 75 38 20 2a 61 20 3d 20 61 52 65 63 6f 72    u8 *a = aRecor
4d70: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
4d80: 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65    /* Used to ite
4d90: 72 61 74 65 20 74 68 72 6f 75 67 68 20 63 68 61  rate through cha
4da0: 6e 67 65 20 72 65 63 6f 72 64 20 2a 2f 0a 0a 20  nge record */.. 
4db0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61 62   for(i=0; i<pTab
4dc0: 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20  ->nCol; i++){.  
4dd0: 20 20 69 6e 74 20 65 54 79 70 65 20 3d 20 2a 61    int eType = *a
4de0: 3b 0a 20 20 20 20 69 6e 74 20 69 73 50 4b 20 3d  ;.    int isPK =
4df0: 20 70 54 61 62 2d 3e 61 62 50 4b 5b 69 5d 3b 0a   pTab->abPK[i];.
4e00: 20 20 20 20 69 66 28 20 62 50 6b 4f 6e 6c 79 20      if( bPkOnly 
4e10: 26 26 20 69 73 50 4b 3d 3d 30 20 29 20 63 6f 6e  && isPK==0 ) con
4e20: 74 69 6e 75 65 3b 0a 0a 20 20 20 20 2f 2a 20 49  tinue;..    /* I
4e30: 74 20 69 73 20 6e 6f 74 20 70 6f 73 73 69 62 6c  t is not possibl
4e40: 65 20 66 6f 72 20 65 54 79 70 65 20 74 6f 20 62  e for eType to b
4e50: 65 20 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 68 65  e SQLITE_NULL he
4e60: 72 65 2e 20 54 68 65 20 73 65 73 73 69 6f 6e 20  re. The session 
4e70: 0a 20 20 20 20 2a 2a 20 6d 6f 64 75 6c 65 20 64  .    ** module d
4e80: 6f 65 73 20 6e 6f 74 20 72 65 63 6f 72 64 20 63  oes not record c
4e90: 68 61 6e 67 65 73 20 66 6f 72 20 72 6f 77 73 20  hanges for rows 
4ea0: 77 69 74 68 20 4e 55 4c 4c 20 76 61 6c 75 65 73  with NULL values
4eb0: 20 73 74 6f 72 65 64 20 69 6e 0a 20 20 20 20 2a   stored in.    *
4ec0: 2a 20 70 72 69 6d 61 72 79 20 6b 65 79 20 63 6f  * primary key co
4ed0: 6c 75 6d 6e 73 2e 20 2a 2f 0a 20 20 20 20 61 73  lumns. */.    as
4ee0: 73 65 72 74 28 20 65 54 79 70 65 3d 3d 53 51 4c  sert( eType==SQL
4ef0: 49 54 45 5f 49 4e 54 45 47 45 52 20 7c 7c 20 65  ITE_INTEGER || e
4f00: 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 46 4c 4f  Type==SQLITE_FLO
4f10: 41 54 20 0a 20 20 20 20 20 20 20 20 20 7c 7c 20  AT .         || 
4f20: 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 54 45  eType==SQLITE_TE
4f30: 58 54 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c  XT || eType==SQL
4f40: 49 54 45 5f 42 4c 4f 42 20 0a 20 20 20 20 20 20  ITE_BLOB .      
4f50: 20 20 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c     || eType==SQL
4f60: 49 54 45 5f 4e 55 4c 4c 20 7c 7c 20 65 54 79 70  ITE_NULL || eTyp
4f70: 65 3d 3d 30 20 0a 20 20 20 20 29 3b 0a 20 20 20  e==0 .    );.   
4f80: 20 61 73 73 65 72 74 28 20 21 69 73 50 4b 20 7c   assert( !isPK |
4f90: 7c 20 28 65 54 79 70 65 21 3d 30 20 26 26 20 65  | (eType!=0 && e
4fa0: 54 79 70 65 21 3d 53 51 4c 49 54 45 5f 4e 55 4c  Type!=SQLITE_NUL
4fb0: 4c 29 20 29 3b 0a 0a 20 20 20 20 69 66 28 20 69  L) );..    if( i
4fc0: 73 50 4b 20 29 7b 0a 20 20 20 20 20 20 61 2b 2b  sPK ){.      a++
4fd0: 3b 0a 20 20 20 20 20 20 68 20 3d 20 73 65 73 73  ;.      h = sess
4fe0: 69 6f 6e 48 61 73 68 41 70 70 65 6e 64 54 79 70  ionHashAppendTyp
4ff0: 65 28 68 2c 20 65 54 79 70 65 29 3b 0a 20 20 20  e(h, eType);.   
5000: 20 20 20 69 66 28 20 65 54 79 70 65 3d 3d 53 51     if( eType==SQ
5010: 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 7c 7c 20  LITE_INTEGER || 
5020: 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 46 4c  eType==SQLITE_FL
5030: 4f 41 54 20 29 7b 0a 20 20 20 20 20 20 20 20 68  OAT ){.        h
5040: 20 3d 20 73 65 73 73 69 6f 6e 48 61 73 68 41 70   = sessionHashAp
5050: 70 65 6e 64 49 36 34 28 68 2c 20 73 65 73 73 69  pendI64(h, sessi
5060: 6f 6e 47 65 74 49 36 34 28 61 29 29 3b 0a 20 20  onGetI64(a));.  
5070: 20 20 20 20 20 20 61 20 2b 3d 20 38 3b 0a 20 20        a += 8;.  
5080: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
5090: 20 20 20 69 6e 74 20 6e 3b 20 0a 20 20 20 20 20     int n; .     
50a0: 20 20 20 61 20 2b 3d 20 73 65 73 73 69 6f 6e 56     a += sessionV
50b0: 61 72 69 6e 74 47 65 74 28 61 2c 20 26 6e 29 3b  arintGet(a, &n);
50c0: 0a 20 20 20 20 20 20 20 20 68 20 3d 20 73 65 73  .        h = ses
50d0: 73 69 6f 6e 48 61 73 68 41 70 70 65 6e 64 42 6c  sionHashAppendBl
50e0: 6f 62 28 68 2c 20 6e 2c 20 61 29 3b 0a 20 20 20  ob(h, n, a);.   
50f0: 20 20 20 20 20 61 20 2b 3d 20 6e 3b 0a 20 20 20       a += n;.   
5100: 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 7b 0a     }.    }else{.
5110: 20 20 20 20 20 20 61 20 2b 3d 20 73 65 73 73 69        a += sessi
5120: 6f 6e 53 65 72 69 61 6c 4c 65 6e 28 61 29 3b 0a  onSerialLen(a);.
5130: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
5140: 72 6e 20 28 68 20 25 20 6e 42 75 63 6b 65 74 29  rn (h % nBucket)
5150: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 72 67 75 6d  ;.}../*.** Argum
5160: 65 6e 74 73 20 61 4c 65 66 74 20 61 6e 64 20 61  ents aLeft and a
5170: 52 69 67 68 74 20 61 72 65 20 70 6f 69 6e 74 65  Right are pointe
5180: 72 73 20 74 6f 20 63 68 61 6e 67 65 20 72 65 63  rs to change rec
5190: 6f 72 64 73 20 66 6f 72 20 74 61 62 6c 65 20 70  ords for table p
51a0: 54 61 62 2e 0a 2a 2a 20 54 68 69 73 20 66 75 6e  Tab..** This fun
51b0: 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 74 72  ction returns tr
51c0: 75 65 20 69 66 20 74 68 65 20 74 77 6f 20 72 65  ue if the two re
51d0: 63 6f 72 64 73 20 61 70 70 6c 79 20 74 6f 20 74  cords apply to t
51e0: 68 65 20 73 61 6d 65 20 72 6f 77 20 28 69 2e 65  he same row (i.e
51f0: 2e 0a 2a 2a 20 68 61 76 65 20 74 68 65 20 73 61  ..** have the sa
5200: 6d 65 20 76 61 6c 75 65 73 20 73 74 6f 72 65 64  me values stored
5210: 20 69 6e 20 74 68 65 20 70 72 69 6d 61 72 79 20   in the primary 
5220: 6b 65 79 20 63 6f 6c 75 6d 6e 73 29 2c 20 6f 72  key columns), or
5230: 20 66 61 6c 73 65 20 0a 2a 2a 20 6f 74 68 65 72   false .** other
5240: 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  wise..*/.static 
5250: 69 6e 74 20 73 65 73 73 69 6f 6e 43 68 61 6e 67  int sessionChang
5260: 65 45 71 75 61 6c 28 0a 20 20 53 65 73 73 69 6f  eEqual(.  Sessio
5270: 6e 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 20 20  nTable *pTab,   
5280: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62            /* Tab
5290: 6c 65 20 75 73 65 64 20 66 6f 72 20 50 4b 20 64  le used for PK d
52a0: 65 66 69 6e 69 74 69 6f 6e 20 2a 2f 0a 20 20 69  efinition */.  i
52b0: 6e 74 20 62 4c 65 66 74 50 6b 4f 6e 6c 79 2c 20  nt bLeftPkOnly, 
52c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
52d0: 2a 20 54 72 75 65 20 69 66 20 61 4c 65 66 74 5b  * True if aLeft[
52e0: 5d 20 63 6f 6e 74 61 69 6e 73 20 50 4b 20 66 69  ] contains PK fi
52f0: 65 6c 64 73 20 6f 6e 6c 79 20 2a 2f 0a 20 20 75  elds only */.  u
5300: 38 20 2a 61 4c 65 66 74 2c 20 20 20 20 20 20 20  8 *aLeft,       
5310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5320: 2a 20 43 68 61 6e 67 65 20 72 65 63 6f 72 64 20  * Change record 
5330: 2a 2f 0a 20 20 69 6e 74 20 62 52 69 67 68 74 50  */.  int bRightP
5340: 6b 4f 6e 6c 79 2c 20 20 20 20 20 20 20 20 20 20  kOnly,          
5350: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
5360: 61 52 69 67 68 74 5b 5d 20 63 6f 6e 74 61 69 6e  aRight[] contain
5370: 73 20 50 4b 20 66 69 65 6c 64 73 20 6f 6e 6c 79  s PK fields only
5380: 20 2a 2f 0a 20 20 75 38 20 2a 61 52 69 67 68 74   */.  u8 *aRight
5390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
53a0: 20 20 20 20 20 20 2f 2a 20 43 68 61 6e 67 65 20        /* Change 
53b0: 72 65 63 6f 72 64 20 2a 2f 0a 29 7b 0a 20 20 75  record */.){.  u
53c0: 38 20 2a 61 31 20 3d 20 61 4c 65 66 74 3b 20 20  8 *a1 = aLeft;  
53d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
53e0: 2a 20 43 75 72 73 6f 72 20 74 6f 20 69 74 65 72  * Cursor to iter
53f0: 61 74 65 20 74 68 72 6f 75 67 68 20 61 4c 65 66  ate through aLef
5400: 74 20 2a 2f 0a 20 20 75 38 20 2a 61 32 20 3d 20  t */.  u8 *a2 = 
5410: 61 52 69 67 68 74 3b 20 20 20 20 20 20 20 20 20  aRight;         
5420: 20 20 20 20 20 20 20 2f 2a 20 43 75 72 73 6f 72         /* Cursor
5430: 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f   to iterate thro
5440: 75 67 68 20 61 52 69 67 68 74 20 2a 2f 0a 20 20  ugh aRight */.  
5450: 69 6e 74 20 69 43 6f 6c 3b 20 20 20 20 20 20 20  int iCol;       
5460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5470: 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72 61  /* Used to itera
5480: 74 65 20 74 68 72 6f 75 67 68 20 74 61 62 6c 65  te through table
5490: 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 0a 20 20 66   columns */..  f
54a0: 6f 72 28 69 43 6f 6c 3d 30 3b 20 69 43 6f 6c 3c  or(iCol=0; iCol<
54b0: 70 54 61 62 2d 3e 6e 43 6f 6c 3b 20 69 43 6f 6c  pTab->nCol; iCol
54c0: 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 70 54 61  ++){.    if( pTa
54d0: 62 2d 3e 61 62 50 4b 5b 69 43 6f 6c 5d 20 29 7b  b->abPK[iCol] ){
54e0: 0a 20 20 20 20 20 20 69 6e 74 20 6e 31 20 3d 20  .      int n1 = 
54f0: 73 65 73 73 69 6f 6e 53 65 72 69 61 6c 4c 65 6e  sessionSerialLen
5500: 28 61 31 29 3b 0a 20 20 20 20 20 20 69 6e 74 20  (a1);.      int 
5510: 6e 32 20 3d 20 73 65 73 73 69 6f 6e 53 65 72 69  n2 = sessionSeri
5520: 61 6c 4c 65 6e 28 61 32 29 3b 0a 0a 20 20 20 20  alLen(a2);..    
5530: 20 20 69 66 28 20 70 54 61 62 2d 3e 61 62 50 4b    if( pTab->abPK
5540: 5b 69 43 6f 6c 5d 20 26 26 20 28 6e 31 21 3d 6e  [iCol] && (n1!=n
5550: 32 20 7c 7c 20 6d 65 6d 63 6d 70 28 61 31 2c 20  2 || memcmp(a1, 
5560: 61 32 2c 20 6e 31 29 29 20 29 7b 0a 20 20 20 20  a2, n1)) ){.    
5570: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20      return 0;.  
5580: 20 20 20 20 7d 0a 20 20 20 20 20 20 61 31 20 2b      }.      a1 +
5590: 3d 20 6e 31 3b 0a 20 20 20 20 20 20 61 32 20 2b  = n1;.      a2 +
55a0: 3d 20 6e 32 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  = n2;.    }else{
55b0: 0a 20 20 20 20 20 20 69 66 28 20 62 4c 65 66 74  .      if( bLeft
55c0: 50 6b 4f 6e 6c 79 3d 3d 30 20 29 20 61 31 20 2b  PkOnly==0 ) a1 +
55d0: 3d 20 73 65 73 73 69 6f 6e 53 65 72 69 61 6c 4c  = sessionSerialL
55e0: 65 6e 28 61 31 29 3b 0a 20 20 20 20 20 20 69 66  en(a1);.      if
55f0: 28 20 62 52 69 67 68 74 50 6b 4f 6e 6c 79 3d 3d  ( bRightPkOnly==
5600: 30 20 29 20 61 32 20 2b 3d 20 73 65 73 73 69 6f  0 ) a2 += sessio
5610: 6e 53 65 72 69 61 6c 4c 65 6e 28 61 32 29 3b 0a  nSerialLen(a2);.
5620: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
5630: 75 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn 1;.}../*.** 
5640: 41 72 67 75 6d 65 6e 74 73 20 61 4c 65 66 74 20  Arguments aLeft 
5650: 61 6e 64 20 61 52 69 67 68 74 20 62 6f 74 68 20  and aRight both 
5660: 70 6f 69 6e 74 20 74 6f 20 62 75 66 66 65 72 73  point to buffers
5670: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 63 68 61 6e   containing chan
5680: 67 65 0a 2a 2a 20 72 65 63 6f 72 64 73 20 77 69  ge.** records wi
5690: 74 68 20 6e 43 6f 6c 20 63 6f 6c 75 6d 6e 73 2e  th nCol columns.
56a0: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 22   This function "
56b0: 6d 65 72 67 65 73 22 20 74 68 65 20 74 77 6f 20  merges" the two 
56c0: 72 65 63 6f 72 64 73 20 69 6e 74 6f 0a 2a 2a 20  records into.** 
56d0: 61 20 73 69 6e 67 6c 65 20 72 65 63 6f 72 64 73  a single records
56e0: 20 77 68 69 63 68 20 69 73 20 77 72 69 74 74 65   which is writte
56f0: 6e 20 74 6f 20 74 68 65 20 62 75 66 66 65 72 20  n to the buffer 
5700: 61 74 20 2a 70 61 4f 75 74 2e 20 2a 70 61 4f 75  at *paOut. *paOu
5710: 74 20 69 73 0a 2a 2a 20 74 68 65 6e 20 73 65 74  t is.** then set
5720: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 6f 6e 65   to point to one
5730: 20 62 79 74 65 20 61 66 74 65 72 20 74 68 65 20   byte after the 
5740: 6c 61 73 74 20 62 79 74 65 20 77 72 69 74 74 65  last byte writte
5750: 6e 20 62 65 66 6f 72 65 20 0a 2a 2a 20 72 65 74  n before .** ret
5760: 75 72 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 54 68  urning..**.** Th
5770: 65 20 6d 65 72 67 69 6e 67 20 6f 66 20 72 65 63  e merging of rec
5780: 6f 72 64 73 20 69 73 20 64 6f 6e 65 20 61 73 20  ords is done as 
5790: 66 6f 6c 6c 6f 77 73 3a 20 46 6f 72 20 65 61 63  follows: For eac
57a0: 68 20 63 6f 6c 75 6d 6e 2c 20 69 66 20 74 68 65  h column, if the
57b0: 20 0a 2a 2a 20 61 52 69 67 68 74 20 72 65 63 6f   .** aRight reco
57c0: 72 64 20 63 6f 6e 74 61 69 6e 73 20 61 20 76 61  rd contains a va
57d0: 6c 75 65 20 66 6f 72 20 74 68 65 20 63 6f 6c 75  lue for the colu
57e0: 6d 6e 2c 20 63 6f 70 79 20 74 68 65 20 76 61 6c  mn, copy the val
57f0: 75 65 20 66 72 6f 6d 0a 2a 2a 20 74 68 65 69 72  ue from.** their
5800: 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20  . Otherwise, if 
5810: 61 4c 65 66 74 20 63 6f 6e 74 61 69 6e 73 20 61  aLeft contains a
5820: 20 76 61 6c 75 65 2c 20 63 6f 70 79 20 69 74 2e   value, copy it.
5830: 20 49 66 20 6e 65 69 74 68 65 72 0a 2a 2a 20 72   If neither.** r
5840: 65 63 6f 72 64 20 63 6f 6e 74 61 69 6e 73 20 61  ecord contains a
5850: 20 76 61 6c 75 65 20 66 6f 72 20 61 20 67 69 76   value for a giv
5860: 65 6e 20 63 6f 6c 75 6d 6e 2c 20 74 68 65 6e 20  en column, then 
5870: 6e 65 69 74 68 65 72 20 64 6f 65 73 20 74 68 65  neither does the
5880: 0a 2a 2a 20 6f 75 74 70 75 74 20 72 65 63 6f 72  .** output recor
5890: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
58a0: 64 20 73 65 73 73 69 6f 6e 4d 65 72 67 65 52 65  d sessionMergeRe
58b0: 63 6f 72 64 28 0a 20 20 75 38 20 2a 2a 70 61 4f  cord(.  u8 **paO
58c0: 75 74 2c 20 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c  ut, .  int nCol,
58d0: 0a 20 20 75 38 20 2a 61 4c 65 66 74 2c 0a 20 20  .  u8 *aLeft,.  
58e0: 75 38 20 2a 61 52 69 67 68 74 0a 29 7b 0a 20 20  u8 *aRight.){.  
58f0: 75 38 20 2a 61 31 20 3d 20 61 4c 65 66 74 3b 20  u8 *a1 = aLeft; 
5900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5910: 2f 2a 20 43 75 72 73 6f 72 20 75 73 65 64 20 74  /* Cursor used t
5920: 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67  o iterate throug
5930: 68 20 61 4c 65 66 74 20 2a 2f 0a 20 20 75 38 20  h aLeft */.  u8 
5940: 2a 61 32 20 3d 20 61 52 69 67 68 74 3b 20 20 20  *a2 = aRight;   
5950: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5960: 43 75 72 73 6f 72 20 75 73 65 64 20 74 6f 20 69  Cursor used to i
5970: 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 61  terate through a
5980: 52 69 67 68 74 20 2a 2f 0a 20 20 75 38 20 2a 61  Right */.  u8 *a
5990: 4f 75 74 20 3d 20 2a 70 61 4f 75 74 3b 20 20 20  Out = *paOut;   
59a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 75             /* Ou
59b0: 74 70 75 74 20 63 75 72 73 6f 72 20 2a 2f 0a 20  tput cursor */. 
59c0: 20 69 6e 74 20 69 43 6f 6c 3b 20 20 20 20 20 20   int iCol;      
59d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
59e0: 20 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72   /* Used to iter
59f0: 61 74 65 20 66 72 6f 6d 20 30 20 74 6f 20 6e 43  ate from 0 to nC
5a00: 6f 6c 20 2a 2f 0a 0a 20 20 66 6f 72 28 69 43 6f  ol */..  for(iCo
5a10: 6c 3d 30 3b 20 69 43 6f 6c 3c 6e 43 6f 6c 3b 20  l=0; iCol<nCol; 
5a20: 69 43 6f 6c 2b 2b 29 7b 0a 20 20 20 20 69 6e 74  iCol++){.    int
5a30: 20 6e 31 20 3d 20 73 65 73 73 69 6f 6e 53 65 72   n1 = sessionSer
5a40: 69 61 6c 4c 65 6e 28 61 31 29 3b 0a 20 20 20 20  ialLen(a1);.    
5a50: 69 6e 74 20 6e 32 20 3d 20 73 65 73 73 69 6f 6e  int n2 = session
5a60: 53 65 72 69 61 6c 4c 65 6e 28 61 32 29 3b 0a 20  SerialLen(a2);. 
5a70: 20 20 20 69 66 28 20 2a 61 32 20 29 7b 0a 20 20     if( *a2 ){.  
5a80: 20 20 20 20 6d 65 6d 63 70 79 28 61 4f 75 74 2c      memcpy(aOut,
5a90: 20 61 32 2c 20 6e 32 29 3b 0a 20 20 20 20 20 20   a2, n2);.      
5aa0: 61 4f 75 74 20 2b 3d 20 6e 32 3b 0a 20 20 20 20  aOut += n2;.    
5ab0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6d 65 6d  }else{.      mem
5ac0: 63 70 79 28 61 4f 75 74 2c 20 61 31 2c 20 6e 31  cpy(aOut, a1, n1
5ad0: 29 3b 0a 20 20 20 20 20 20 61 4f 75 74 20 2b 3d  );.      aOut +=
5ae0: 20 6e 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61   n1;.    }.    a
5af0: 31 20 2b 3d 20 6e 31 3b 0a 20 20 20 20 61 32 20  1 += n1;.    a2 
5b00: 2b 3d 20 6e 32 3b 0a 20 20 7d 0a 0a 20 20 2a 70  += n2;.  }..  *p
5b10: 61 4f 75 74 20 3d 20 61 4f 75 74 3b 0a 7d 0a 0a  aOut = aOut;.}..
5b20: 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 61 20  /*.** This is a 
5b30: 68 65 6c 70 65 72 20 66 75 6e 63 74 69 6f 6e 20  helper function 
5b40: 75 73 65 64 20 62 79 20 73 65 73 73 69 6f 6e 4d  used by sessionM
5b50: 65 72 67 65 55 70 64 61 74 65 28 29 2e 0a 2a 2a  ergeUpdate()..**
5b60: 0a 2a 2a 20 57 68 65 6e 20 74 68 69 73 20 66 75  .** When this fu
5b70: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
5b80: 2c 20 62 6f 74 68 20 2a 70 61 4f 6e 65 20 61 6e  , both *paOne an
5b90: 64 20 2a 70 61 54 77 6f 20 70 6f 69 6e 74 20 74  d *paTwo point t
5ba0: 6f 20 61 20 76 61 6c 75 65 20 0a 2a 2a 20 77 69  o a value .** wi
5bb0: 74 68 69 6e 20 61 20 63 68 61 6e 67 65 20 72 65  thin a change re
5bc0: 63 6f 72 64 2e 20 42 65 66 6f 72 65 20 69 74 20  cord. Before it 
5bd0: 72 65 74 75 72 6e 73 2c 20 62 6f 74 68 20 68 61  returns, both ha
5be0: 76 65 20 62 65 65 6e 20 61 64 76 61 6e 63 65 64  ve been advanced
5bf0: 20 73 6f 20 0a 2a 2a 20 61 73 20 74 6f 20 70 6f   so .** as to po
5c00: 69 6e 74 20 74 6f 20 74 68 65 20 6e 65 78 74 20  int to the next 
5c10: 76 61 6c 75 65 20 69 6e 20 74 68 65 20 72 65 63  value in the rec
5c20: 6f 72 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 2c 20 77  ord..**.** If, w
5c30: 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f  hen this functio
5c40: 6e 20 69 73 20 63 61 6c 6c 65 64 2c 20 2a 70 61  n is called, *pa
5c50: 54 77 6f 20 70 6f 69 6e 74 73 20 74 6f 20 61 20  Two points to a 
5c60: 76 61 6c 69 64 20 76 61 6c 75 65 20 28 69 2e 65  valid value (i.e
5c70: 2e 0a 2a 2a 20 2a 70 61 54 77 6f 5b 30 5d 20 69  ..** *paTwo[0] i
5c80: 73 20 6e 6f 74 20 30 78 30 30 20 2d 20 74 68 65  s not 0x00 - the
5c90: 20 22 6e 6f 20 76 61 6c 75 65 22 20 70 6c 61 63   "no value" plac
5ca0: 65 68 6f 6c 64 65 72 29 2c 20 61 20 63 6f 70 79  eholder), a copy
5cb0: 20 6f 66 20 74 68 65 20 2a 70 61 54 77 6f 0a 2a   of the *paTwo.*
5cc0: 2a 20 70 6f 69 6e 74 65 72 20 69 73 20 72 65 74  * pointer is ret
5cd0: 75 72 6e 65 64 20 61 6e 64 20 2a 70 6e 56 61 6c  urned and *pnVal
5ce0: 20 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e   is set to the n
5cf0: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69  umber of bytes i
5d00: 6e 20 74 68 65 20 0a 2a 2a 20 73 65 72 69 61 6c  n the .** serial
5d10: 69 7a 65 64 20 76 61 6c 75 65 2e 20 4f 74 68 65  ized value. Othe
5d20: 72 77 69 73 65 2c 20 61 20 63 6f 70 79 20 6f 66  rwise, a copy of
5d30: 20 2a 70 61 4f 6e 65 20 69 73 20 72 65 74 75 72   *paOne is retur
5d40: 6e 65 64 20 61 6e 64 20 2a 70 6e 56 61 6c 0a 2a  ned and *pnVal.*
5d50: 2a 20 73 65 74 20 74 6f 20 74 68 65 20 6e 75 6d  * set to the num
5d60: 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
5d70: 74 68 65 20 76 61 6c 75 65 20 61 74 20 2a 70 61  the value at *pa
5d80: 4f 6e 65 2e 20 49 66 20 2a 70 61 4f 6e 65 20 70  One. If *paOne p
5d90: 6f 69 6e 74 73 0a 2a 2a 20 74 6f 20 74 68 65 20  oints.** to the 
5da0: 22 6e 6f 20 76 61 6c 75 65 22 20 70 6c 61 63 65  "no value" place
5db0: 68 6f 6c 64 65 72 2c 20 2a 70 6e 56 61 6c 20 69  holder, *pnVal i
5dc0: 73 20 73 65 74 20 74 6f 20 31 2e 20 49 6e 20 6f  s set to 1. In o
5dd0: 74 68 65 72 20 77 6f 72 64 73 3a 0a 2a 2a 0a 2a  ther words:.**.*
5de0: 2a 20 20 20 69 66 28 20 2a 70 61 54 77 6f 20 69  *   if( *paTwo i
5df0: 73 20 76 61 6c 69 64 20 29 20 72 65 74 75 72 6e  s valid ) return
5e00: 20 2a 70 61 54 77 6f 3b 0a 2a 2a 20 20 20 72 65   *paTwo;.**   re
5e10: 74 75 72 6e 20 2a 70 61 4f 6e 65 3b 0a 2a 2a 0a  turn *paOne;.**.
5e20: 2a 2f 0a 73 74 61 74 69 63 20 75 38 20 2a 73 65  */.static u8 *se
5e30: 73 73 69 6f 6e 4d 65 72 67 65 56 61 6c 75 65 28  ssionMergeValue(
5e40: 0a 20 20 75 38 20 2a 2a 70 61 4f 6e 65 2c 20 20  .  u8 **paOne,  
5e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e60: 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 4c 65     /* IN/OUT: Le
5e70: 66 74 2d 68 61 6e 64 20 62 75 66 66 65 72 20 70  ft-hand buffer p
5e80: 6f 69 6e 74 65 72 20 2a 2f 0a 20 20 75 38 20 2a  ointer */.  u8 *
5e90: 2a 70 61 54 77 6f 2c 20 20 20 20 20 20 20 20 20  *paTwo,         
5ea0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
5eb0: 4e 2f 4f 55 54 3a 20 52 69 67 68 74 2d 68 61 6e  N/OUT: Right-han
5ec0: 64 20 62 75 66 66 65 72 20 70 6f 69 6e 74 65 72  d buffer pointer
5ed0: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 56 61 6c   */.  int *pnVal
5ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ef0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 42 79        /* OUT: By
5f00: 74 65 73 20 69 6e 20 72 65 74 75 72 6e 65 64 20  tes in returned 
5f10: 76 61 6c 75 65 20 2a 2f 0a 29 7b 0a 20 20 75 38  value */.){.  u8
5f20: 20 2a 61 31 20 3d 20 2a 70 61 4f 6e 65 3b 0a 20   *a1 = *paOne;. 
5f30: 20 75 38 20 2a 61 32 20 3d 20 2a 70 61 54 77 6f   u8 *a2 = *paTwo
5f40: 3b 0a 20 20 75 38 20 2a 70 52 65 74 20 3d 20 30  ;.  u8 *pRet = 0
5f50: 3b 0a 20 20 69 6e 74 20 6e 31 3b 0a 0a 20 20 61  ;.  int n1;..  a
5f60: 73 73 65 72 74 28 20 61 31 20 29 3b 0a 20 20 69  ssert( a1 );.  i
5f70: 66 28 20 61 32 20 29 7b 0a 20 20 20 20 69 6e 74  f( a2 ){.    int
5f80: 20 6e 32 20 3d 20 73 65 73 73 69 6f 6e 53 65 72   n2 = sessionSer
5f90: 69 61 6c 4c 65 6e 28 61 32 29 3b 0a 20 20 20 20  ialLen(a2);.    
5fa0: 69 66 28 20 2a 61 32 20 29 7b 0a 20 20 20 20 20  if( *a2 ){.     
5fb0: 20 2a 70 6e 56 61 6c 20 3d 20 6e 32 3b 0a 20 20   *pnVal = n2;.  
5fc0: 20 20 20 20 70 52 65 74 20 3d 20 61 32 3b 0a 20      pRet = a2;. 
5fd0: 20 20 20 7d 0a 20 20 20 20 2a 70 61 54 77 6f 20     }.    *paTwo 
5fe0: 3d 20 26 61 32 5b 6e 32 5d 3b 0a 20 20 7d 0a 0a  = &a2[n2];.  }..
5ff0: 20 20 6e 31 20 3d 20 73 65 73 73 69 6f 6e 53 65    n1 = sessionSe
6000: 72 69 61 6c 4c 65 6e 28 61 31 29 3b 0a 20 20 69  rialLen(a1);.  i
6010: 66 28 20 70 52 65 74 3d 3d 30 20 29 7b 0a 20 20  f( pRet==0 ){.  
6020: 20 20 2a 70 6e 56 61 6c 20 3d 20 6e 31 3b 0a 20    *pnVal = n1;. 
6030: 20 20 20 70 52 65 74 20 3d 20 61 31 3b 0a 20 20     pRet = a1;.  
6040: 7d 0a 20 20 2a 70 61 4f 6e 65 20 3d 20 26 61 31  }.  *paOne = &a1
6050: 5b 6e 31 5d 3b 0a 0a 20 20 72 65 74 75 72 6e 20  [n1];..  return 
6060: 70 52 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  pRet;.}../*.** T
6070: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
6080: 75 73 65 64 20 62 79 20 63 68 61 6e 67 65 73 65  used by changese
6090: 74 5f 63 6f 6e 63 61 74 28 29 20 74 6f 20 6d 65  t_concat() to me
60a0: 72 67 65 20 74 77 6f 20 55 50 44 41 54 45 20 63  rge two UPDATE c
60b0: 68 61 6e 67 65 73 0a 2a 2a 20 6f 6e 20 74 68 65  hanges.** on the
60c0: 20 73 61 6d 65 20 72 6f 77 2e 0a 2a 2f 0a 73 74   same row..*/.st
60d0: 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e  atic int session
60e0: 4d 65 72 67 65 55 70 64 61 74 65 28 0a 20 20 75  MergeUpdate(.  u
60f0: 38 20 2a 2a 70 61 4f 75 74 2c 20 20 20 20 20 20  8 **paOut,      
6100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6110: 2a 20 49 4e 2f 4f 55 54 3a 20 50 6f 69 6e 74 65  * IN/OUT: Pointe
6120: 72 20 74 6f 20 6f 75 74 70 75 74 20 62 75 66 66  r to output buff
6130: 65 72 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 54  er */.  SessionT
6140: 61 62 6c 65 20 2a 70 54 61 62 2c 20 20 20 20 20  able *pTab,     
6150: 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62 6c 65          /* Table
6160: 20 63 68 61 6e 67 65 20 70 65 72 74 61 69 6e 73   change pertains
6170: 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 62 50 61   to */.  int bPa
6180: 74 63 68 73 65 74 2c 20 20 20 20 20 20 20 20 20  tchset,         
6190: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
61a0: 20 69 66 20 72 65 63 6f 72 64 73 20 61 72 65 20   if records are 
61b0: 70 61 74 63 68 73 65 74 20 72 65 63 6f 72 64 73  patchset records
61c0: 20 2a 2f 0a 20 20 75 38 20 2a 61 4f 6c 64 52 65   */.  u8 *aOldRe
61d0: 63 6f 72 64 31 2c 20 20 20 20 20 20 20 20 20 20  cord1,          
61e0: 20 20 20 20 20 20 2f 2a 20 6f 6c 64 2e 2a 20 72        /* old.* r
61f0: 65 63 6f 72 64 20 66 6f 72 20 66 69 72 73 74 20  ecord for first 
6200: 63 68 61 6e 67 65 20 2a 2f 0a 20 20 75 38 20 2a  change */.  u8 *
6210: 61 4f 6c 64 52 65 63 6f 72 64 32 2c 20 20 20 20  aOldRecord2,    
6220: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 6f              /* o
6230: 6c 64 2e 2a 20 72 65 63 6f 72 64 20 66 6f 72 20  ld.* record for 
6240: 73 65 63 6f 6e 64 20 63 68 61 6e 67 65 20 2a 2f  second change */
6250: 0a 20 20 75 38 20 2a 61 4e 65 77 52 65 63 6f 72  .  u8 *aNewRecor
6260: 64 31 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  d1,             
6270: 20 20 20 2f 2a 20 6e 65 77 2e 2a 20 72 65 63 6f     /* new.* reco
6280: 72 64 20 66 6f 72 20 66 69 72 73 74 20 63 68 61  rd for first cha
6290: 6e 67 65 20 2a 2f 0a 20 20 75 38 20 2a 61 4e 65  nge */.  u8 *aNe
62a0: 77 52 65 63 6f 72 64 32 20 20 20 20 20 20 20 20  wRecord2        
62b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 6e 65 77 2e           /* new.
62c0: 2a 20 72 65 63 6f 72 64 20 66 6f 72 20 73 65 63  * record for sec
62d0: 6f 6e 64 20 63 68 61 6e 67 65 20 2a 2f 0a 29 7b  ond change */.){
62e0: 0a 20 20 75 38 20 2a 61 4f 6c 64 31 20 3d 20 61  .  u8 *aOld1 = a
62f0: 4f 6c 64 52 65 63 6f 72 64 31 3b 0a 20 20 75 38  OldRecord1;.  u8
6300: 20 2a 61 4f 6c 64 32 20 3d 20 61 4f 6c 64 52 65   *aOld2 = aOldRe
6310: 63 6f 72 64 32 3b 0a 20 20 75 38 20 2a 61 4e 65  cord2;.  u8 *aNe
6320: 77 31 20 3d 20 61 4e 65 77 52 65 63 6f 72 64 31  w1 = aNewRecord1
6330: 3b 0a 20 20 75 38 20 2a 61 4e 65 77 32 20 3d 20  ;.  u8 *aNew2 = 
6340: 61 4e 65 77 52 65 63 6f 72 64 32 3b 0a 0a 20 20  aNewRecord2;..  
6350: 75 38 20 2a 61 4f 75 74 20 3d 20 2a 70 61 4f 75  u8 *aOut = *paOu
6360: 74 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 69  t;.  int i;..  i
6370: 66 28 20 62 50 61 74 63 68 73 65 74 3d 3d 30 20  f( bPatchset==0 
6380: 29 7b 0a 20 20 20 20 69 6e 74 20 62 52 65 71 75  ){.    int bRequ
6390: 69 72 65 64 20 3d 20 30 3b 0a 0a 20 20 20 20 61  ired = 0;..    a
63a0: 73 73 65 72 74 28 20 61 4f 6c 64 52 65 63 6f 72  ssert( aOldRecor
63b0: 64 31 20 26 26 20 61 4e 65 77 52 65 63 6f 72 64  d1 && aNewRecord
63c0: 31 20 29 3b 0a 0a 20 20 20 20 2f 2a 20 57 72 69  1 );..    /* Wri
63d0: 74 65 20 74 68 65 20 6f 6c 64 2e 2a 20 76 65 63  te the old.* vec
63e0: 74 6f 72 20 66 69 72 73 74 2e 20 2a 2f 0a 20 20  tor first. */.  
63f0: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61    for(i=0; i<pTa
6400: 62 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20  b->nCol; i++){. 
6410: 20 20 20 20 20 69 6e 74 20 6e 4f 6c 64 3b 0a 20       int nOld;. 
6420: 20 20 20 20 20 75 38 20 2a 61 4f 6c 64 3b 0a 20       u8 *aOld;. 
6430: 20 20 20 20 20 69 6e 74 20 6e 4e 65 77 3b 0a 20       int nNew;. 
6440: 20 20 20 20 20 75 38 20 2a 61 4e 65 77 3b 0a 0a       u8 *aNew;..
6450: 20 20 20 20 20 20 61 4f 6c 64 20 3d 20 73 65 73        aOld = ses
6460: 73 69 6f 6e 4d 65 72 67 65 56 61 6c 75 65 28 26  sionMergeValue(&
6470: 61 4f 6c 64 31 2c 20 26 61 4f 6c 64 32 2c 20 26  aOld1, &aOld2, &
6480: 6e 4f 6c 64 29 3b 0a 20 20 20 20 20 20 61 4e 65  nOld);.      aNe
6490: 77 20 3d 20 73 65 73 73 69 6f 6e 4d 65 72 67 65  w = sessionMerge
64a0: 56 61 6c 75 65 28 26 61 4e 65 77 31 2c 20 26 61  Value(&aNew1, &a
64b0: 4e 65 77 32 2c 20 26 6e 4e 65 77 29 3b 0a 20 20  New2, &nNew);.  
64c0: 20 20 20 20 69 66 28 20 70 54 61 62 2d 3e 61 62      if( pTab->ab
64d0: 50 4b 5b 69 5d 20 7c 7c 20 6e 4f 6c 64 21 3d 6e  PK[i] || nOld!=n
64e0: 4e 65 77 20 7c 7c 20 6d 65 6d 63 6d 70 28 61 4f  New || memcmp(aO
64f0: 6c 64 2c 20 61 4e 65 77 2c 20 6e 4e 65 77 29 20  ld, aNew, nNew) 
6500: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70  ){.        if( p
6510: 54 61 62 2d 3e 61 62 50 4b 5b 69 5d 3d 3d 30 20  Tab->abPK[i]==0 
6520: 29 20 62 52 65 71 75 69 72 65 64 20 3d 20 31 3b  ) bRequired = 1;
6530: 0a 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28  .        memcpy(
6540: 61 4f 75 74 2c 20 61 4f 6c 64 2c 20 6e 4f 6c 64  aOut, aOld, nOld
6550: 29 3b 0a 20 20 20 20 20 20 20 20 61 4f 75 74 20  );.        aOut 
6560: 2b 3d 20 6e 4f 6c 64 3b 0a 20 20 20 20 20 20 7d  += nOld;.      }
6570: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 2a 28  else{.        *(
6580: 61 4f 75 74 2b 2b 29 20 3d 20 27 5c 30 27 3b 0a  aOut++) = '\0';.
6590: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20        }.    }.. 
65a0: 20 20 20 69 66 28 20 21 62 52 65 71 75 69 72 65     if( !bRequire
65b0: 64 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20  d ) return 0;.  
65c0: 7d 0a 0a 20 20 2f 2a 20 57 72 69 74 65 20 74 68  }..  /* Write th
65d0: 65 20 6e 65 77 2e 2a 20 76 65 63 74 6f 72 20 2a  e new.* vector *
65e0: 2f 0a 20 20 61 4f 6c 64 31 20 3d 20 61 4f 6c 64  /.  aOld1 = aOld
65f0: 52 65 63 6f 72 64 31 3b 0a 20 20 61 4f 6c 64 32  Record1;.  aOld2
6600: 20 3d 20 61 4f 6c 64 52 65 63 6f 72 64 32 3b 0a   = aOldRecord2;.
6610: 20 20 61 4e 65 77 31 20 3d 20 61 4e 65 77 52 65    aNew1 = aNewRe
6620: 63 6f 72 64 31 3b 0a 20 20 61 4e 65 77 32 20 3d  cord1;.  aNew2 =
6630: 20 61 4e 65 77 52 65 63 6f 72 64 32 3b 0a 20 20   aNewRecord2;.  
6640: 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61 62 2d  for(i=0; i<pTab-
6650: 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20  >nCol; i++){.   
6660: 20 69 6e 74 20 6e 4f 6c 64 3b 0a 20 20 20 20 75   int nOld;.    u
6670: 38 20 2a 61 4f 6c 64 3b 0a 20 20 20 20 69 6e 74  8 *aOld;.    int
6680: 20 6e 4e 65 77 3b 0a 20 20 20 20 75 38 20 2a 61   nNew;.    u8 *a
6690: 4e 65 77 3b 0a 0a 20 20 20 20 61 4f 6c 64 20 3d  New;..    aOld =
66a0: 20 73 65 73 73 69 6f 6e 4d 65 72 67 65 56 61 6c   sessionMergeVal
66b0: 75 65 28 26 61 4f 6c 64 31 2c 20 26 61 4f 6c 64  ue(&aOld1, &aOld
66c0: 32 2c 20 26 6e 4f 6c 64 29 3b 0a 20 20 20 20 61  2, &nOld);.    a
66d0: 4e 65 77 20 3d 20 73 65 73 73 69 6f 6e 4d 65 72  New = sessionMer
66e0: 67 65 56 61 6c 75 65 28 26 61 4e 65 77 31 2c 20  geValue(&aNew1, 
66f0: 26 61 4e 65 77 32 2c 20 26 6e 4e 65 77 29 3b 0a  &aNew2, &nNew);.
6700: 20 20 20 20 69 66 28 20 62 50 61 74 63 68 73 65      if( bPatchse
6710: 74 3d 3d 30 20 0a 20 20 20 20 20 26 26 20 28 70  t==0 .     && (p
6720: 54 61 62 2d 3e 61 62 50 4b 5b 69 5d 20 7c 7c 20  Tab->abPK[i] || 
6730: 28 6e 4f 6c 64 3d 3d 6e 4e 65 77 20 26 26 20 30  (nOld==nNew && 0
6740: 3d 3d 6d 65 6d 63 6d 70 28 61 4f 6c 64 2c 20 61  ==memcmp(aOld, a
6750: 4e 65 77 2c 20 6e 4e 65 77 29 29 29 20 0a 20 20  New, nNew))) .  
6760: 20 20 29 7b 0a 20 20 20 20 20 20 2a 28 61 4f 75    ){.      *(aOu
6770: 74 2b 2b 29 20 3d 20 27 5c 30 27 3b 0a 20 20 20  t++) = '\0';.   
6780: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6d 65   }else{.      me
6790: 6d 63 70 79 28 61 4f 75 74 2c 20 61 4e 65 77 2c  mcpy(aOut, aNew,
67a0: 20 6e 4e 65 77 29 3b 0a 20 20 20 20 20 20 61 4f   nNew);.      aO
67b0: 75 74 20 2b 3d 20 6e 4e 65 77 3b 0a 20 20 20 20  ut += nNew;.    
67c0: 7d 0a 20 20 7d 0a 0a 20 20 2a 70 61 4f 75 74 20  }.  }..  *paOut 
67d0: 3d 20 61 4f 75 74 3b 0a 20 20 72 65 74 75 72 6e  = aOut;.  return
67e0: 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69   1;.}../*.** Thi
67f0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 6f 6e  s function is on
6800: 6c 79 20 63 61 6c 6c 65 64 20 66 72 6f 6d 20 77  ly called from w
6810: 69 74 68 69 6e 20 61 20 70 72 65 2d 75 70 64 61  ithin a pre-upda
6820: 74 65 2d 68 6f 6f 6b 20 63 61 6c 6c 62 61 63 6b  te-hook callback
6830: 2e 0a 2a 2a 20 49 74 20 64 65 74 65 72 6d 69 6e  ..** It determin
6840: 65 73 20 69 66 20 74 68 65 20 63 75 72 72 65 6e  es if the curren
6850: 74 20 70 72 65 2d 75 70 64 61 74 65 2d 68 6f 6f  t pre-update-hoo
6860: 6b 20 63 68 61 6e 67 65 20 61 66 66 65 63 74 73  k change affects
6870: 20 74 68 65 20 73 61 6d 65 20 72 6f 77 0a 2a 2a   the same row.**
6880: 20 61 73 20 74 68 65 20 63 68 61 6e 67 65 20 73   as the change s
6890: 74 6f 72 65 64 20 69 6e 20 61 72 67 75 6d 65 6e  tored in argumen
68a0: 74 20 70 43 68 61 6e 67 65 2e 20 49 66 20 73 6f  t pChange. If so
68b0: 2c 20 69 74 20 72 65 74 75 72 6e 73 20 74 72 75  , it returns tru
68c0: 65 2e 20 4f 74 68 65 72 77 69 73 65 0a 2a 2a 20  e. Otherwise.** 
68d0: 69 66 20 74 68 65 20 70 72 65 2d 75 70 64 61 74  if the pre-updat
68e0: 65 2d 68 6f 6f 6b 20 64 6f 65 73 20 6e 6f 74 20  e-hook does not 
68f0: 61 66 66 65 63 74 20 74 68 65 20 73 61 6d 65 20  affect the same 
6900: 72 6f 77 20 61 73 20 70 43 68 61 6e 67 65 2c 20  row as pChange, 
6910: 69 74 20 72 65 74 75 72 6e 73 0a 2a 2a 20 66 61  it returns.** fa
6920: 6c 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  lse..*/.static i
6930: 6e 74 20 73 65 73 73 69 6f 6e 50 72 65 75 70 64  nt sessionPreupd
6940: 61 74 65 45 71 75 61 6c 28 0a 20 20 73 71 6c 69  ateEqual(.  sqli
6950: 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65  te3_session *pSe
6960: 73 73 69 6f 6e 2c 20 20 20 20 20 20 2f 2a 20 53  ssion,      /* S
6970: 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 74 68  ession object th
6980: 61 74 20 6f 77 6e 73 20 53 65 73 73 69 6f 6e 54  at owns SessionT
6990: 61 62 6c 65 20 2a 2f 0a 20 20 53 65 73 73 69 6f  able */.  Sessio
69a0: 6e 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 20 20  nTable *pTab,   
69b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62            /* Tab
69c0: 6c 65 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  le associated wi
69d0: 74 68 20 63 68 61 6e 67 65 20 2a 2f 0a 20 20 53  th change */.  S
69e0: 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 70 43  essionChange *pC
69f0: 68 61 6e 67 65 2c 20 20 20 20 20 20 20 20 20 2f  hange,         /
6a00: 2a 20 43 68 61 6e 67 65 20 74 6f 20 63 6f 6d 70  * Change to comp
6a10: 61 72 65 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20  are to */.  int 
6a20: 6f 70 20 20 20 20 20 20 20 20 20 20 20 20 20 20  op              
6a30: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
6a40: 75 72 72 65 6e 74 20 70 72 65 2d 75 70 64 61 74  urrent pre-updat
6a50: 65 20 6f 70 65 72 61 74 69 6f 6e 20 2a 2f 0a 29  e operation */.)
6a60: 7b 0a 20 20 69 6e 74 20 69 43 6f 6c 3b 20 20 20  {.  int iCol;   
6a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a80: 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69      /* Used to i
6a90: 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 63  terate through c
6aa0: 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 75 38 20 2a  olumns */.  u8 *
6ab0: 61 20 3d 20 70 43 68 61 6e 67 65 2d 3e 61 52 65  a = pChange->aRe
6ac0: 63 6f 72 64 3b 20 20 20 20 20 20 20 2f 2a 20 43  cord;       /* C
6ad0: 75 72 73 6f 72 20 75 73 65 64 20 74 6f 20 73 63  ursor used to sc
6ae0: 61 6e 20 63 68 61 6e 67 65 20 72 65 63 6f 72 64  an change record
6af0: 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 6f   */..  assert( o
6b00: 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52 54  p==SQLITE_INSERT
6b10: 20 7c 7c 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 55   || op==SQLITE_U
6b20: 50 44 41 54 45 20 7c 7c 20 6f 70 3d 3d 53 51 4c  PDATE || op==SQL
6b30: 49 54 45 5f 44 45 4c 45 54 45 20 29 3b 0a 20 20  ITE_DELETE );.  
6b40: 66 6f 72 28 69 43 6f 6c 3d 30 3b 20 69 43 6f 6c  for(iCol=0; iCol
6b50: 3c 70 54 61 62 2d 3e 6e 43 6f 6c 3b 20 69 43 6f  <pTab->nCol; iCo
6b60: 6c 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 21 70  l++){.    if( !p
6b70: 54 61 62 2d 3e 61 62 50 4b 5b 69 43 6f 6c 5d 20  Tab->abPK[iCol] 
6b80: 29 7b 0a 20 20 20 20 20 20 61 20 2b 3d 20 73 65  ){.      a += se
6b90: 73 73 69 6f 6e 53 65 72 69 61 6c 4c 65 6e 28 61  ssionSerialLen(a
6ba0: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
6bb0: 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75      sqlite3_valu
6bc0: 65 20 2a 70 56 61 6c 3b 20 20 20 20 20 20 20 20  e *pVal;        
6bd0: 2f 2a 20 56 61 6c 75 65 20 72 65 74 75 72 6e 65  /* Value returne
6be0: 64 20 62 79 20 70 72 65 75 70 64 61 74 65 5f 6e  d by preupdate_n
6bf0: 65 77 2f 6f 6c 64 20 2a 2f 0a 20 20 20 20 20 20  ew/old */.      
6c00: 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
6c10: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45              /* E
6c20: 72 72 6f 72 20 63 6f 64 65 20 66 72 6f 6d 20 70  rror code from p
6c30: 72 65 75 70 64 61 74 65 5f 6e 65 77 2f 6f 6c 64  reupdate_new/old
6c40: 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 65 54   */.      int eT
6c50: 79 70 65 20 3d 20 2a 61 2b 2b 3b 20 20 20 20 20  ype = *a++;     
6c60: 20 20 20 20 20 20 2f 2a 20 54 79 70 65 20 6f 66        /* Type of
6c70: 20 76 61 6c 75 65 20 66 72 6f 6d 20 63 68 61 6e   value from chan
6c80: 67 65 20 72 65 63 6f 72 64 20 2a 2f 0a 0a 20 20  ge record */..  
6c90: 20 20 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f      /* The follo
6ca0: 77 69 6e 67 20 63 61 6c 6c 73 20 74 6f 20 70 72  wing calls to pr
6cb0: 65 75 70 64 61 74 65 5f 6e 65 77 28 29 20 61 6e  eupdate_new() an
6cc0: 64 20 70 72 65 75 70 64 61 74 65 5f 6f 6c 64 28  d preupdate_old(
6cd0: 29 20 63 61 6e 20 6e 6f 74 0a 20 20 20 20 20 20  ) can not.      
6ce0: 2a 2a 20 66 61 69 6c 2e 20 54 68 69 73 20 69 73  ** fail. This is
6cf0: 20 62 65 63 61 75 73 65 20 74 68 65 79 20 63 61   because they ca
6d00: 63 68 65 20 74 68 65 69 72 20 72 65 74 75 72 6e  che their return
6d10: 20 76 61 6c 75 65 73 2c 20 61 6e 64 20 62 79 20   values, and by 
6d20: 74 68 65 0a 20 20 20 20 20 20 2a 2a 20 74 69 6d  the.      ** tim
6d30: 65 20 63 6f 6e 74 72 6f 6c 20 66 6c 6f 77 73 20  e control flows 
6d40: 74 6f 20 68 65 72 65 20 74 68 65 79 20 68 61 76  to here they hav
6d50: 65 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 63  e already been c
6d60: 61 6c 6c 65 64 20 6f 6e 63 65 20 66 72 6f 6d 0a  alled once from.
6d70: 20 20 20 20 20 20 2a 2a 20 77 69 74 68 69 6e 20        ** within 
6d80: 73 65 73 73 69 6f 6e 50 72 65 75 70 64 61 74 65  sessionPreupdate
6d90: 48 61 73 68 28 29 2e 20 54 68 65 20 66 69 72 73  Hash(). The firs
6da0: 74 20 74 77 6f 20 61 73 73 65 72 74 73 20 62 65  t two asserts be
6db0: 6c 6f 77 20 76 65 72 69 66 79 0a 20 20 20 20 20  low verify.     
6dc0: 20 2a 2a 20 74 68 69 73 20 28 74 68 61 74 20 74   ** this (that t
6dd0: 68 65 20 6d 65 74 68 6f 64 20 68 61 73 20 61 6c  he method has al
6de0: 72 65 61 64 79 20 62 65 65 6e 20 63 61 6c 6c 65  ready been calle
6df0: 64 29 2e 20 2a 2f 0a 20 20 20 20 20 20 69 66 28  d). */.      if(
6e00: 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 53 45   op==SQLITE_INSE
6e10: 52 54 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a  RT ){.        /*
6e20: 20 61 73 73 65 72 74 28 20 64 62 2d 3e 70 50 72   assert( db->pPr
6e30: 65 55 70 64 61 74 65 2d 3e 70 4e 65 77 55 6e 70  eUpdate->pNewUnp
6e40: 61 63 6b 65 64 20 7c 7c 20 64 62 2d 3e 70 50 72  acked || db->pPr
6e50: 65 55 70 64 61 74 65 2d 3e 61 4e 65 77 20 29 3b  eUpdate->aNew );
6e60: 20 2a 2f 0a 20 20 20 20 20 20 20 20 72 63 20 3d   */.        rc =
6e70: 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e   pSession->hook.
6e80: 78 4e 65 77 28 70 53 65 73 73 69 6f 6e 2d 3e 68  xNew(pSession->h
6e90: 6f 6f 6b 2e 70 43 74 78 2c 20 69 43 6f 6c 2c 20  ook.pCtx, iCol, 
6ea0: 26 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 7d 65  &pVal);.      }e
6eb0: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20  lse{.        /* 
6ec0: 61 73 73 65 72 74 28 20 64 62 2d 3e 70 50 72 65  assert( db->pPre
6ed0: 55 70 64 61 74 65 2d 3e 70 55 6e 70 61 63 6b 65  Update->pUnpacke
6ee0: 64 20 29 3b 20 2a 2f 0a 20 20 20 20 20 20 20 20  d ); */.        
6ef0: 72 63 20 3d 20 70 53 65 73 73 69 6f 6e 2d 3e 68  rc = pSession->h
6f00: 6f 6f 6b 2e 78 4f 6c 64 28 70 53 65 73 73 69 6f  ook.xOld(pSessio
6f10: 6e 2d 3e 68 6f 6f 6b 2e 70 43 74 78 2c 20 69 43  n->hook.pCtx, iC
6f20: 6f 6c 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20 20  ol, &pVal);.    
6f30: 20 20 7d 0a 20 20 20 20 20 20 61 73 73 65 72 74    }.      assert
6f40: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
6f50: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 73 71 6c  );.      if( sql
6f60: 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
6f70: 70 56 61 6c 29 21 3d 65 54 79 70 65 20 29 20 72  pVal)!=eType ) r
6f80: 65 74 75 72 6e 20 30 3b 0a 0a 20 20 20 20 20 20  eturn 0;..      
6f90: 2f 2a 20 41 20 53 65 73 73 69 6f 6e 43 68 61 6e  /* A SessionChan
6fa0: 67 65 20 6f 62 6a 65 63 74 20 6e 65 76 65 72 20  ge object never 
6fb0: 68 61 73 20 61 20 4e 55 4c 4c 20 76 61 6c 75 65  has a NULL value
6fc0: 20 69 6e 20 61 20 50 4b 20 63 6f 6c 75 6d 6e 20   in a PK column 
6fd0: 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  */.      assert(
6fe0: 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49   eType==SQLITE_I
6ff0: 4e 54 45 47 45 52 20 7c 7c 20 65 54 79 70 65 3d  NTEGER || eType=
7000: 3d 53 51 4c 49 54 45 5f 46 4c 4f 41 54 0a 20 20  =SQLITE_FLOAT.  
7010: 20 20 20 20 20 20 20 20 20 7c 7c 20 65 54 79 70           || eTyp
7020: 65 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 20 20  e==SQLITE_BLOB  
7030: 20 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49    || eType==SQLI
7040: 54 45 5f 54 45 58 54 0a 20 20 20 20 20 20 29 3b  TE_TEXT.      );
7050: 0a 0a 20 20 20 20 20 20 69 66 28 20 65 54 79 70  ..      if( eTyp
7060: 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45  e==SQLITE_INTEGE
7070: 52 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49  R || eType==SQLI
7080: 54 45 5f 46 4c 4f 41 54 20 29 7b 0a 20 20 20 20  TE_FLOAT ){.    
7090: 20 20 20 20 69 36 34 20 69 56 61 6c 20 3d 20 73      i64 iVal = s
70a0: 65 73 73 69 6f 6e 47 65 74 49 36 34 28 61 29 3b  essionGetI64(a);
70b0: 0a 20 20 20 20 20 20 20 20 61 20 2b 3d 20 38 3b  .        a += 8;
70c0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 65 54 79  .        if( eTy
70d0: 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47  pe==SQLITE_INTEG
70e0: 45 52 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  ER ){.          
70f0: 69 66 28 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  if( sqlite3_valu
7100: 65 5f 69 6e 74 36 34 28 70 56 61 6c 29 21 3d 69  e_int64(pVal)!=i
7110: 56 61 6c 20 29 20 72 65 74 75 72 6e 20 30 3b 0a  Val ) return 0;.
7120: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
7130: 20 20 20 20 20 20 20 20 20 64 6f 75 62 6c 65 20           double 
7140: 72 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 20 20  rVal;.          
7150: 61 73 73 65 72 74 28 20 73 69 7a 65 6f 66 28 69  assert( sizeof(i
7160: 56 61 6c 29 3d 3d 38 20 26 26 20 73 69 7a 65 6f  Val)==8 && sizeo
7170: 66 28 72 56 61 6c 29 3d 3d 38 20 29 3b 0a 20 20  f(rVal)==8 );.  
7180: 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26          memcpy(&
7190: 72 56 61 6c 2c 20 26 69 56 61 6c 2c 20 38 29 3b  rVal, &iVal, 8);
71a0: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 73  .          if( s
71b0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 64 6f 75  qlite3_value_dou
71c0: 62 6c 65 28 70 56 61 6c 29 21 3d 72 56 61 6c 20  ble(pVal)!=rVal 
71d0: 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20  ) return 0;.    
71e0: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73      }.      }els
71f0: 65 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e  e{.        int n
7200: 3b 0a 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20  ;.        const 
7210: 75 38 20 2a 7a 3b 0a 20 20 20 20 20 20 20 20 61  u8 *z;.        a
7220: 20 2b 3d 20 73 65 73 73 69 6f 6e 56 61 72 69 6e   += sessionVarin
7230: 74 47 65 74 28 61 2c 20 26 6e 29 3b 0a 20 20 20  tGet(a, &n);.   
7240: 20 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33       if( sqlite3
7250: 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 70 56 61  _value_bytes(pVa
7260: 6c 29 21 3d 6e 20 29 20 72 65 74 75 72 6e 20 30  l)!=n ) return 0
7270: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 65 54  ;.        if( eT
7280: 79 70 65 3d 3d 53 51 4c 49 54 45 5f 54 45 58 54  ype==SQLITE_TEXT
7290: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 7a 20   ){.          z 
72a0: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
72b0: 74 65 78 74 28 70 56 61 6c 29 3b 0a 20 20 20 20  text(pVal);.    
72c0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
72d0: 20 20 20 20 20 7a 20 3d 20 73 71 6c 69 74 65 33       z = sqlite3
72e0: 5f 76 61 6c 75 65 5f 62 6c 6f 62 28 70 56 61 6c  _value_blob(pVal
72f0: 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  );.        }.   
7300: 20 20 20 20 20 69 66 28 20 6d 65 6d 63 6d 70 28       if( memcmp(
7310: 61 2c 20 7a 2c 20 6e 29 20 29 20 72 65 74 75 72  a, z, n) ) retur
7320: 6e 20 30 3b 0a 20 20 20 20 20 20 20 20 61 20 2b  n 0;.        a +
7330: 3d 20 6e 3b 0a 20 20 20 20 20 20 20 20 62 72 65  = n;.        bre
7340: 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
7350: 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  }.  }..  return 
7360: 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 72  1;.}../*.** If r
7370: 65 71 75 69 72 65 64 2c 20 67 72 6f 77 20 74 68  equired, grow th
7380: 65 20 68 61 73 68 20 74 61 62 6c 65 20 75 73 65  e hash table use
7390: 64 20 74 6f 20 73 74 6f 72 65 20 63 68 61 6e 67  d to store chang
73a0: 65 73 20 6f 6e 20 74 61 62 6c 65 20 70 54 61 62  es on table pTab
73b0: 20 0a 2a 2a 20 28 70 61 72 74 20 6f 66 20 74 68   .** (part of th
73c0: 65 20 73 65 73 73 69 6f 6e 20 70 53 65 73 73 69  e session pSessi
73d0: 6f 6e 29 2e 20 49 66 20 61 20 66 61 74 61 6c 20  on). If a fatal 
73e0: 4f 4f 4d 20 65 72 72 6f 72 20 6f 63 63 75 72 73  OOM error occurs
73f0: 2c 20 73 65 74 20 74 68 65 0a 2a 2a 20 73 65 73  , set the.** ses
7400: 73 69 6f 6e 20 6f 62 6a 65 63 74 20 74 6f 20 66  sion object to f
7410: 61 69 6c 65 64 20 61 6e 64 20 72 65 74 75 72 6e  ailed and return
7420: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 2e 20 4f   SQLITE_ERROR. O
7430: 74 68 65 72 77 69 73 65 2c 20 72 65 74 75 72 6e  therwise, return
7440: 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a  .** SQLITE_OK..*
7450: 2a 0a 2a 2a 20 49 74 20 69 73 20 70 6f 73 73 69  *.** It is possi
7460: 62 6c 65 20 74 68 61 74 20 61 20 6e 6f 6e 2d 66  ble that a non-f
7470: 61 74 61 6c 20 4f 4f 4d 20 65 72 72 6f 72 20 6f  atal OOM error o
7480: 63 63 75 72 73 20 69 6e 20 74 68 69 73 20 66 75  ccurs in this fu
7490: 6e 63 74 69 6f 6e 2e 20 49 6e 0a 2a 2a 20 74 68  nction. In.** th
74a0: 61 74 20 63 61 73 65 20 74 68 65 20 68 61 73 68  at case the hash
74b0: 2d 74 61 62 6c 65 20 64 6f 65 73 20 6e 6f 74 20  -table does not 
74c0: 67 72 6f 77 2c 20 62 75 74 20 53 51 4c 49 54 45  grow, but SQLITE
74d0: 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20  _OK is returned 
74e0: 61 6e 79 77 61 79 2e 0a 2a 2a 20 47 72 6f 77 69  anyway..** Growi
74f0: 6e 67 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  ng the hash tabl
7500: 65 20 69 6e 20 74 68 69 73 20 63 61 73 65 20 69  e in this case i
7510: 73 20 61 20 70 65 72 66 6f 72 6d 61 6e 63 65 20  s a performance 
7520: 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 20 6f 6e 6c  optimization onl
7530: 79 2c 0a 2a 2a 20 69 74 20 69 73 20 6e 6f 74 20  y,.** it is not 
7540: 72 65 71 75 69 72 65 64 20 66 6f 72 20 63 6f 72  required for cor
7550: 72 65 63 74 20 6f 70 65 72 61 74 69 6f 6e 2e 0a  rect operation..
7560: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
7570: 73 73 69 6f 6e 47 72 6f 77 48 61 73 68 28 69 6e  ssionGrowHash(in
7580: 74 20 62 50 61 74 63 68 73 65 74 2c 20 53 65 73  t bPatchset, Ses
7590: 73 69 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62 29  sionTable *pTab)
75a0: 7b 0a 20 20 69 66 28 20 70 54 61 62 2d 3e 6e 43  {.  if( pTab->nC
75b0: 68 61 6e 67 65 3d 3d 30 20 7c 7c 20 70 54 61 62  hange==0 || pTab
75c0: 2d 3e 6e 45 6e 74 72 79 3e 3d 28 70 54 61 62 2d  ->nEntry>=(pTab-
75d0: 3e 6e 43 68 61 6e 67 65 2f 32 29 20 29 7b 0a 20  >nChange/2) ){. 
75e0: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 53 65     int i;.    Se
75f0: 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 2a 61 70  ssionChange **ap
7600: 4e 65 77 3b 0a 20 20 20 20 69 6e 74 20 6e 4e 65  New;.    int nNe
7610: 77 20 3d 20 28 70 54 61 62 2d 3e 6e 43 68 61 6e  w = (pTab->nChan
7620: 67 65 20 3f 20 70 54 61 62 2d 3e 6e 43 68 61 6e  ge ? pTab->nChan
7630: 67 65 20 3a 20 31 32 38 29 20 2a 20 32 3b 0a 0a  ge : 128) * 2;..
7640: 20 20 20 20 61 70 4e 65 77 20 3d 20 28 53 65 73      apNew = (Ses
7650: 73 69 6f 6e 43 68 61 6e 67 65 20 2a 2a 29 73 71  sionChange **)sq
7660: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a  lite3_malloc(siz
7670: 65 6f 66 28 53 65 73 73 69 6f 6e 43 68 61 6e 67  eof(SessionChang
7680: 65 20 2a 29 20 2a 20 6e 4e 65 77 29 3b 0a 20 20  e *) * nNew);.  
7690: 20 20 69 66 28 20 61 70 4e 65 77 3d 3d 30 20 29    if( apNew==0 )
76a0: 7b 0a 20 20 20 20 20 20 69 66 28 20 70 54 61 62  {.      if( pTab
76b0: 2d 3e 6e 43 68 61 6e 67 65 3d 3d 30 20 29 7b 0a  ->nChange==0 ){.
76c0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 53          return S
76d0: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20  QLITE_ERROR;.   
76e0: 20 20 20 7d 0a 20 20 20 20 20 20 72 65 74 75 72     }.      retur
76f0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20  n SQLITE_OK;.   
7700: 20 7d 0a 20 20 20 20 6d 65 6d 73 65 74 28 61 70   }.    memset(ap
7710: 4e 65 77 2c 20 30 2c 20 73 69 7a 65 6f 66 28 53  New, 0, sizeof(S
7720: 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 29 20  essionChange *) 
7730: 2a 20 6e 4e 65 77 29 3b 0a 0a 20 20 20 20 66 6f  * nNew);..    fo
7740: 72 28 69 3d 30 3b 20 69 3c 70 54 61 62 2d 3e 6e  r(i=0; i<pTab->n
7750: 43 68 61 6e 67 65 3b 20 69 2b 2b 29 7b 0a 20 20  Change; i++){.  
7760: 20 20 20 20 53 65 73 73 69 6f 6e 43 68 61 6e 67      SessionChang
7770: 65 20 2a 70 3b 0a 20 20 20 20 20 20 53 65 73 73  e *p;.      Sess
7780: 69 6f 6e 43 68 61 6e 67 65 20 2a 70 4e 65 78 74  ionChange *pNext
7790: 3b 0a 20 20 20 20 20 20 66 6f 72 28 70 3d 70 54  ;.      for(p=pT
77a0: 61 62 2d 3e 61 70 43 68 61 6e 67 65 5b 69 5d 3b  ab->apChange[i];
77b0: 20 70 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20   p; p=pNext){.  
77c0: 20 20 20 20 20 20 69 6e 74 20 62 50 6b 4f 6e 6c        int bPkOnl
77d0: 79 20 3d 20 28 70 2d 3e 6f 70 3d 3d 53 51 4c 49  y = (p->op==SQLI
77e0: 54 45 5f 44 45 4c 45 54 45 20 26 26 20 62 50 61  TE_DELETE && bPa
77f0: 74 63 68 73 65 74 29 3b 0a 20 20 20 20 20 20 20  tchset);.       
7800: 20 69 6e 74 20 69 48 61 73 68 20 3d 20 73 65 73   int iHash = ses
7810: 73 69 6f 6e 43 68 61 6e 67 65 48 61 73 68 28 70  sionChangeHash(p
7820: 54 61 62 2c 20 62 50 6b 4f 6e 6c 79 2c 20 70 2d  Tab, bPkOnly, p-
7830: 3e 61 52 65 63 6f 72 64 2c 20 6e 4e 65 77 29 3b  >aRecord, nNew);
7840: 0a 20 20 20 20 20 20 20 20 70 4e 65 78 74 20 3d  .        pNext =
7850: 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20   p->pNext;.     
7860: 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 61 70     p->pNext = ap
7870: 4e 65 77 5b 69 48 61 73 68 5d 3b 0a 20 20 20 20  New[iHash];.    
7880: 20 20 20 20 61 70 4e 65 77 5b 69 48 61 73 68 5d      apNew[iHash]
7890: 20 3d 20 70 3b 0a 20 20 20 20 20 20 7d 0a 20 20   = p;.      }.  
78a0: 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69 74 65 33    }..    sqlite3
78b0: 5f 66 72 65 65 28 70 54 61 62 2d 3e 61 70 43 68  _free(pTab->apCh
78c0: 61 6e 67 65 29 3b 0a 20 20 20 20 70 54 61 62 2d  ange);.    pTab-
78d0: 3e 6e 43 68 61 6e 67 65 20 3d 20 6e 4e 65 77 3b  >nChange = nNew;
78e0: 0a 20 20 20 20 70 54 61 62 2d 3e 61 70 43 68 61  .    pTab->apCha
78f0: 6e 67 65 20 3d 20 61 70 4e 65 77 3b 0a 20 20 7d  nge = apNew;.  }
7900: 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ..  return SQLIT
7910: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  E_OK;.}../*.** T
7920: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 71 75 65  his function que
7930: 72 69 65 73 20 74 68 65 20 64 61 74 61 62 61 73  ries the databas
7940: 65 20 66 6f 72 20 74 68 65 20 6e 61 6d 65 73 20  e for the names 
7950: 6f 66 20 74 68 65 20 63 6f 6c 75 6d 6e 73 20 6f  of the columns o
7960: 66 20 74 61 62 6c 65 0a 2a 2a 20 7a 54 68 69 73  f table.** zThis
7970: 2c 20 69 6e 20 73 63 68 65 6d 61 20 7a 44 62 2e  , in schema zDb.
7980: 20 49 74 20 69 73 20 65 78 70 65 63 74 65 64 20   It is expected 
7990: 74 68 61 74 20 74 68 65 20 74 61 62 6c 65 20 68  that the table h
79a0: 61 73 20 6e 43 6f 6c 20 63 6f 6c 75 6d 6e 73 2e  as nCol columns.
79b0: 20 49 66 0a 2a 2a 20 6e 6f 74 2c 20 53 51 4c 49   If.** not, SQLI
79c0: 54 45 5f 53 43 48 45 4d 41 20 69 73 20 72 65 74  TE_SCHEMA is ret
79d0: 75 72 6e 65 64 20 61 6e 64 20 6e 6f 6e 65 20 6f  urned and none o
79e0: 66 20 74 68 65 20 6f 75 74 70 75 74 20 76 61 72  f the output var
79f0: 69 61 62 6c 65 73 20 61 72 65 0a 2a 2a 20 70 6f  iables are.** po
7a00: 70 75 6c 61 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 4f  pulated..**.** O
7a10: 74 68 65 72 77 69 73 65 2c 20 69 66 20 74 68 65  therwise, if the
7a20: 79 20 61 72 65 20 6e 6f 74 20 4e 55 4c 4c 2c 20  y are not NULL, 
7a30: 76 61 72 69 61 62 6c 65 20 2a 70 6e 43 6f 6c 20  variable *pnCol 
7a40: 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e 75  is set to the nu
7a50: 6d 62 65 72 0a 2a 2a 20 6f 66 20 63 6f 6c 75 6d  mber.** of colum
7a60: 6e 73 20 69 6e 20 74 68 65 20 64 61 74 61 62 61  ns in the databa
7a70: 73 65 20 74 61 62 6c 65 20 61 6e 64 20 76 61 72  se table and var
7a80: 69 61 62 6c 65 20 2a 70 7a 54 61 62 20 69 73 20  iable *pzTab is 
7a90: 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  set to point to 
7aa0: 61 0a 2a 2a 20 6e 75 6c 2d 74 65 72 6d 69 6e 61  a.** nul-termina
7ab0: 74 65 64 20 63 6f 70 79 20 6f 66 20 74 68 65 20  ted copy of the 
7ac0: 74 61 62 6c 65 20 6e 61 6d 65 2e 20 2a 70 61 7a  table name. *paz
7ad0: 43 6f 6c 20 28 69 66 20 6e 6f 74 20 4e 55 4c 4c  Col (if not NULL
7ae0: 29 20 69 73 20 73 65 74 20 74 6f 0a 2a 2a 20 70  ) is set to.** p
7af0: 6f 69 6e 74 20 74 6f 20 61 6e 20 61 72 72 61 79  oint to an array
7b00: 20 6f 66 20 70 6f 69 6e 74 65 72 73 20 74 6f 20   of pointers to 
7b10: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 2e 20 41 6e  column names. An
7b20: 64 20 2a 70 61 62 50 4b 20 28 61 67 61 69 6e 2c  d *pabPK (again,
7b30: 20 69 66 20 6e 6f 74 0a 2a 2a 20 4e 55 4c 4c 29   if not.** NULL)
7b40: 20 69 73 20 73 65 74 20 74 6f 20 70 6f 69 6e 74   is set to point
7b50: 20 74 6f 20 61 6e 20 61 72 72 61 79 20 6f 66 20   to an array of 
7b60: 62 6f 6f 6c 65 61 6e 73 20 2d 20 74 72 75 65 20  booleans - true 
7b70: 69 66 20 74 68 65 20 63 6f 72 72 65 73 70 6f 6e  if the correspon
7b80: 64 69 6e 67 0a 2a 2a 20 63 6f 6c 75 6d 6e 20 69  ding.** column i
7b90: 73 20 70 61 72 74 20 6f 66 20 74 68 65 20 70 72  s part of the pr
7ba0: 69 6d 61 72 79 20 6b 65 79 2e 0a 2a 2a 0a 2a 2a  imary key..**.**
7bb0: 20 46 6f 72 20 65 78 61 6d 70 6c 65 2c 20 69 66   For example, if
7bc0: 20 74 68 65 20 74 61 62 6c 65 20 69 73 20 64 65   the table is de
7bd0: 63 6c 61 72 65 64 20 61 73 3a 0a 2a 2a 0a 2a 2a  clared as:.**.**
7be0: 20 20 20 20 20 43 52 45 41 54 45 20 54 41 42 4c       CREATE TABL
7bf0: 45 20 74 62 6c 31 28 77 2c 20 78 2c 20 79 2c 20  E tbl1(w, x, y, 
7c00: 7a 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 77  z, PRIMARY KEY(w
7c10: 2c 20 7a 29 29 3b 0a 2a 2a 0a 2a 2a 20 54 68 65  , z));.**.** The
7c20: 6e 20 74 68 65 20 66 6f 75 72 20 6f 75 74 70 75  n the four outpu
7c30: 74 20 76 61 72 69 61 62 6c 65 73 20 61 72 65 20  t variables are 
7c40: 70 6f 70 75 6c 61 74 65 64 20 61 73 20 66 6f 6c  populated as fol
7c50: 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  lows:.**.**     
7c60: 2a 70 6e 43 6f 6c 20 20 3d 20 34 0a 2a 2a 20 20  *pnCol  = 4.**  
7c70: 20 20 20 2a 70 7a 54 61 62 20 20 3d 20 22 74 62     *pzTab  = "tb
7c80: 6c 31 22 0a 2a 2a 20 20 20 20 20 2a 70 61 7a 43  l1".**     *pazC
7c90: 6f 6c 20 3d 20 7b 22 77 22 2c 20 22 78 22 2c 20  ol = {"w", "x", 
7ca0: 22 79 22 2c 20 22 7a 22 7d 0a 2a 2a 20 20 20 20  "y", "z"}.**    
7cb0: 20 2a 70 61 62 50 4b 20 20 3d 20 7b 31 2c 20 30   *pabPK  = {1, 0
7cc0: 2c 20 30 2c 20 31 7d 0a 2a 2a 0a 2a 2a 20 41 6c  , 0, 1}.**.** Al
7cd0: 6c 20 72 65 74 75 72 6e 65 64 20 62 75 66 66 65  l returned buffe
7ce0: 72 73 20 61 72 65 20 70 61 72 74 20 6f 66 20 74  rs are part of t
7cf0: 68 65 20 73 61 6d 65 20 73 69 6e 67 6c 65 20 61  he same single a
7d00: 6c 6c 6f 63 61 74 69 6f 6e 2c 20 77 68 69 63 68  llocation, which
7d10: 20 6d 75 73 74 0a 2a 2a 20 62 65 20 66 72 65 65   must.** be free
7d20: 64 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f  d using sqlite3_
7d30: 66 72 65 65 28 29 20 62 79 20 74 68 65 20 63 61  free() by the ca
7d40: 6c 6c 65 72 2e 20 49 66 20 70 61 7a 43 6f 6c 20  ller. If pazCol 
7d50: 77 61 73 20 6e 6f 74 20 4e 55 4c 4c 2c 20 74 68  was not NULL, th
7d60: 65 6e 0a 2a 2a 20 70 6f 69 6e 74 65 72 20 2a 70  en.** pointer *p
7d70: 61 7a 43 6f 6c 20 73 68 6f 75 6c 64 20 62 65 20  azCol should be 
7d80: 66 72 65 65 64 20 74 6f 20 72 65 6c 65 61 73 65  freed to release
7d90: 20 61 6c 6c 20 6d 65 6d 6f 72 79 2e 20 4f 74 68   all memory. Oth
7da0: 65 72 77 69 73 65 2c 20 70 6f 69 6e 74 65 72 0a  erwise, pointer.
7db0: 2a 2a 20 2a 70 61 62 50 4b 2e 20 49 74 20 69 73  ** *pabPK. It is
7dc0: 20 69 6c 6c 65 67 61 6c 20 66 6f 72 20 62 6f 74   illegal for bot
7dd0: 68 20 70 61 7a 43 6f 6c 20 61 6e 64 20 70 61 62  h pazCol and pab
7de0: 50 4b 20 74 6f 20 62 65 20 4e 55 4c 4c 2e 0a 2a  PK to be NULL..*
7df0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73  /.static int ses
7e00: 73 69 6f 6e 54 61 62 6c 65 49 6e 66 6f 28 0a 20  sionTableInfo(. 
7e10: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20   sqlite3 *db,   
7e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7e30: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 63 6f 6e   /* Database con
7e40: 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 63 6f 6e  nection */.  con
7e50: 73 74 20 63 68 61 72 20 2a 7a 44 62 2c 20 20 20  st char *zDb,   
7e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7e70: 4e 61 6d 65 20 6f 66 20 61 74 74 61 63 68 65 64  Name of attached
7e80: 20 64 61 74 61 62 61 73 65 20 28 65 2e 67 2e 20   database (e.g. 
7e90: 22 6d 61 69 6e 22 29 20 2a 2f 0a 20 20 63 6f 6e  "main") */.  con
7ea0: 73 74 20 63 68 61 72 20 2a 7a 54 68 69 73 2c 20  st char *zThis, 
7eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7ec0: 54 61 62 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20 20  Table name */.  
7ed0: 69 6e 74 20 2a 70 6e 43 6f 6c 2c 20 20 20 20 20  int *pnCol,     
7ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7ef0: 2f 2a 20 4f 55 54 3a 20 6e 75 6d 62 65 72 20 6f  /* OUT: number o
7f00: 66 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 63  f columns */.  c
7f10: 6f 6e 73 74 20 63 68 61 72 20 2a 2a 70 7a 54 61  onst char **pzTa
7f20: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  b,             /
7f30: 2a 20 4f 55 54 3a 20 43 6f 70 79 20 6f 66 20 7a  * OUT: Copy of z
7f40: 54 68 69 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  This */.  const 
7f50: 63 68 61 72 20 2a 2a 2a 70 61 7a 43 6f 6c 2c 20  char ***pazCol, 
7f60: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
7f70: 3a 20 41 72 72 61 79 20 6f 66 20 63 6f 6c 75 6d  : Array of colum
7f80: 6e 20 6e 61 6d 65 73 20 66 6f 72 20 74 61 62 6c  n names for tabl
7f90: 65 20 2a 2f 0a 20 20 75 38 20 2a 2a 70 61 62 50  e */.  u8 **pabP
7fa0: 4b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  K               
7fb0: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 41         /* OUT: A
7fc0: 72 72 61 79 20 6f 66 20 62 6f 6f 6c 65 61 6e 73  rray of booleans
7fd0: 20 2d 20 74 72 75 65 20 66 6f 72 20 50 4b 20 63   - true for PK c
7fe0: 6f 6c 20 2a 2f 0a 29 7b 0a 20 20 63 68 61 72 20  ol */.){.  char 
7ff0: 2a 7a 50 72 61 67 6d 61 3b 0a 20 20 73 71 6c 69  *zPragma;.  sqli
8000: 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b  te3_stmt *pStmt;
8010: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74  .  int rc;.  int
8020: 20 6e 42 79 74 65 3b 0a 20 20 69 6e 74 20 6e 44   nByte;.  int nD
8030: 62 43 6f 6c 20 3d 20 30 3b 0a 20 20 69 6e 74 20  bCol = 0;.  int 
8040: 6e 54 68 69 73 3b 0a 20 20 69 6e 74 20 69 3b 0a  nThis;.  int i;.
8050: 20 20 75 38 20 2a 70 41 6c 6c 6f 63 20 3d 20 30    u8 *pAlloc = 0
8060: 3b 0a 20 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6c  ;.  char **azCol
8070: 20 3d 20 30 3b 0a 20 20 75 38 20 2a 61 62 50 4b   = 0;.  u8 *abPK
8080: 20 3d 20 30 3b 0a 0a 20 20 61 73 73 65 72 74 28   = 0;..  assert(
8090: 20 70 61 7a 43 6f 6c 20 26 26 20 70 61 62 50 4b   pazCol && pabPK
80a0: 20 29 3b 0a 0a 20 20 6e 54 68 69 73 20 3d 20 73   );..  nThis = s
80b0: 71 6c 69 74 65 33 53 74 72 6c 65 6e 33 30 28 7a  qlite3Strlen30(z
80c0: 54 68 69 73 29 3b 0a 20 20 7a 50 72 61 67 6d 61  This);.  zPragma
80d0: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
80e0: 74 66 28 22 50 52 41 47 4d 41 20 27 25 71 27 2e  tf("PRAGMA '%q'.
80f0: 74 61 62 6c 65 5f 69 6e 66 6f 28 27 25 71 27 29  table_info('%q')
8100: 22 2c 20 7a 44 62 2c 20 7a 54 68 69 73 29 3b 0a  ", zDb, zThis);.
8110: 20 20 69 66 28 20 21 7a 50 72 61 67 6d 61 20 29    if( !zPragma )
8120: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
8130: 4f 4d 45 4d 3b 0a 0a 20 20 72 63 20 3d 20 73 71  OMEM;..  rc = sq
8140: 6c 69 74 65 33 5f 70 72 65 70 61 72 65 5f 76 32  lite3_prepare_v2
8150: 28 64 62 2c 20 7a 50 72 61 67 6d 61 2c 20 2d 31  (db, zPragma, -1
8160: 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20  , &pStmt, 0);.  
8170: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 50 72  sqlite3_free(zPr
8180: 61 67 6d 61 29 3b 0a 20 20 69 66 28 20 72 63 21  agma);.  if( rc!
8190: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
81a0: 75 72 6e 20 72 63 3b 0a 0a 20 20 6e 42 79 74 65  urn rc;..  nByte
81b0: 20 3d 20 6e 54 68 69 73 20 2b 20 31 3b 0a 20 20   = nThis + 1;.  
81c0: 77 68 69 6c 65 28 20 53 51 4c 49 54 45 5f 52 4f  while( SQLITE_RO
81d0: 57 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65 70 28  W==sqlite3_step(
81e0: 70 53 74 6d 74 29 20 29 7b 0a 20 20 20 20 6e 42  pStmt) ){.    nB
81f0: 79 74 65 20 2b 3d 20 73 71 6c 69 74 65 33 5f 63  yte += sqlite3_c
8200: 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70 53 74 6d  olumn_bytes(pStm
8210: 74 2c 20 31 29 3b 0a 20 20 20 20 6e 44 62 43 6f  t, 1);.    nDbCo
8220: 6c 2b 2b 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20  l++;.  }.  rc = 
8230: 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70 53  sqlite3_reset(pS
8240: 74 6d 74 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d  tmt);..  if( rc=
8250: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
8260: 20 20 6e 42 79 74 65 20 2b 3d 20 6e 44 62 43 6f    nByte += nDbCo
8270: 6c 20 2a 20 28 73 69 7a 65 6f 66 28 63 6f 6e 73  l * (sizeof(cons
8280: 74 20 63 68 61 72 20 2a 29 20 2b 20 73 69 7a 65  t char *) + size
8290: 6f 66 28 75 38 29 20 2b 20 31 29 3b 0a 20 20 20  of(u8) + 1);.   
82a0: 20 70 41 6c 6c 6f 63 20 3d 20 73 71 6c 69 74 65   pAlloc = sqlite
82b0: 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b  3_malloc(nByte);
82c0: 0a 20 20 20 20 69 66 28 20 70 41 6c 6c 6f 63 3d  .    if( pAlloc=
82d0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  =0 ){.      rc =
82e0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
82f0: 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 72     }.  }.  if( r
8300: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
8310: 20 20 20 20 61 7a 43 6f 6c 20 3d 20 28 63 68 61      azCol = (cha
8320: 72 20 2a 2a 29 70 41 6c 6c 6f 63 3b 0a 20 20 20  r **)pAlloc;.   
8330: 20 70 41 6c 6c 6f 63 20 3d 20 28 75 38 20 2a 29   pAlloc = (u8 *)
8340: 26 61 7a 43 6f 6c 5b 6e 44 62 43 6f 6c 5d 3b 0a  &azCol[nDbCol];.
8350: 20 20 20 20 61 62 50 4b 20 3d 20 28 75 38 20 2a      abPK = (u8 *
8360: 29 70 41 6c 6c 6f 63 3b 0a 20 20 20 20 70 41 6c  )pAlloc;.    pAl
8370: 6c 6f 63 20 3d 20 26 61 62 50 4b 5b 6e 44 62 43  loc = &abPK[nDbC
8380: 6f 6c 5d 3b 0a 20 20 20 20 69 66 28 20 70 7a 54  ol];.    if( pzT
8390: 61 62 20 29 7b 0a 20 20 20 20 20 20 6d 65 6d 63  ab ){.      memc
83a0: 70 79 28 70 41 6c 6c 6f 63 2c 20 7a 54 68 69 73  py(pAlloc, zThis
83b0: 2c 20 6e 54 68 69 73 2b 31 29 3b 0a 20 20 20 20  , nThis+1);.    
83c0: 20 20 2a 70 7a 54 61 62 20 3d 20 28 63 68 61 72    *pzTab = (char
83d0: 20 2a 29 70 41 6c 6c 6f 63 3b 0a 20 20 20 20 20   *)pAlloc;.     
83e0: 20 70 41 6c 6c 6f 63 20 2b 3d 20 6e 54 68 69 73   pAlloc += nThis
83f0: 2b 31 3b 0a 20 20 20 20 7d 0a 20 20 0a 20 20 20  +1;.    }.  .   
8400: 20 69 20 3d 20 30 3b 0a 20 20 20 20 77 68 69 6c   i = 0;.    whil
8410: 65 28 20 53 51 4c 49 54 45 5f 52 4f 57 3d 3d 73  e( SQLITE_ROW==s
8420: 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d  qlite3_step(pStm
8430: 74 29 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  t) ){.      int 
8440: 6e 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 5f  nName = sqlite3_
8450: 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70 53 74  column_bytes(pSt
8460: 6d 74 2c 20 31 29 3b 0a 20 20 20 20 20 20 63 6f  mt, 1);.      co
8470: 6e 73 74 20 75 6e 73 69 67 6e 65 64 20 63 68 61  nst unsigned cha
8480: 72 20 2a 7a 4e 61 6d 65 20 3d 20 73 71 6c 69 74  r *zName = sqlit
8490: 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70  e3_column_text(p
84a0: 53 74 6d 74 2c 20 31 29 3b 0a 20 20 20 20 20 20  Stmt, 1);.      
84b0: 69 66 28 20 7a 4e 61 6d 65 3d 3d 30 20 29 20 62  if( zName==0 ) b
84c0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 6d 65 6d 63  reak;.      memc
84d0: 70 79 28 70 41 6c 6c 6f 63 2c 20 7a 4e 61 6d 65  py(pAlloc, zName
84e0: 2c 20 6e 4e 61 6d 65 2b 31 29 3b 0a 20 20 20 20  , nName+1);.    
84f0: 20 20 61 7a 43 6f 6c 5b 69 5d 20 3d 20 28 63 68    azCol[i] = (ch
8500: 61 72 20 2a 29 70 41 6c 6c 6f 63 3b 0a 20 20 20  ar *)pAlloc;.   
8510: 20 20 20 70 41 6c 6c 6f 63 20 2b 3d 20 6e 4e 61     pAlloc += nNa
8520: 6d 65 2b 31 3b 0a 20 20 20 20 20 20 61 62 50 4b  me+1;.      abPK
8530: 5b 69 5d 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  [i] = sqlite3_co
8540: 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d 74 2c 20  lumn_int(pStmt, 
8550: 35 29 3b 0a 20 20 20 20 20 20 69 2b 2b 3b 0a 20  5);.      i++;. 
8560: 20 20 20 7d 0a 20 20 20 20 72 63 20 3d 20 73 71     }.    rc = sq
8570: 6c 69 74 65 33 5f 72 65 73 65 74 28 70 53 74 6d  lite3_reset(pStm
8580: 74 29 3b 0a 20 20 0a 20 20 7d 0a 0a 20 20 2f 2a  t);.  .  }..  /*
8590: 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   If successful, 
85a0: 70 6f 70 75 6c 61 74 65 20 74 68 65 20 6f 75 74  populate the out
85b0: 70 75 74 20 76 61 72 69 61 62 6c 65 73 2e 20 4f  put variables. O
85c0: 74 68 65 72 77 69 73 65 2c 20 7a 65 72 6f 20 74  therwise, zero t
85d0: 68 65 6d 20 61 6e 64 0a 20 20 2a 2a 20 66 72 65  hem and.  ** fre
85e0: 65 20 61 6e 79 20 61 6c 6c 6f 63 61 74 69 6f 6e  e any allocation
85f0: 20 6d 61 64 65 2e 20 41 6e 20 65 72 72 6f 72 20   made. An error 
8600: 63 6f 64 65 20 77 69 6c 6c 20 62 65 20 72 65 74  code will be ret
8610: 75 72 6e 65 64 20 69 6e 20 74 68 69 73 20 63 61  urned in this ca
8620: 73 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 72  se..  */.  if( r
8630: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
8640: 20 20 20 20 2a 70 61 7a 43 6f 6c 20 3d 20 28 63      *pazCol = (c
8650: 6f 6e 73 74 20 63 68 61 72 20 2a 2a 29 61 7a 43  onst char **)azC
8660: 6f 6c 3b 0a 20 20 20 20 2a 70 61 62 50 4b 20 3d  ol;.    *pabPK =
8670: 20 61 62 50 4b 3b 0a 20 20 20 20 2a 70 6e 43 6f   abPK;.    *pnCo
8680: 6c 20 3d 20 6e 44 62 43 6f 6c 3b 0a 20 20 7d 65  l = nDbCol;.  }e
8690: 6c 73 65 7b 0a 20 20 20 20 2a 70 61 7a 43 6f 6c  lse{.    *pazCol
86a0: 20 3d 20 30 3b 0a 20 20 20 20 2a 70 61 62 50 4b   = 0;.    *pabPK
86b0: 20 3d 20 30 3b 0a 20 20 20 20 2a 70 6e 43 6f 6c   = 0;.    *pnCol
86c0: 20 3d 20 30 3b 0a 20 20 20 20 69 66 28 20 70 7a   = 0;.    if( pz
86d0: 54 61 62 20 29 20 2a 70 7a 54 61 62 20 3d 20 30  Tab ) *pzTab = 0
86e0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
86f0: 65 65 28 61 7a 43 6f 6c 29 3b 0a 20 20 7d 0a 20  ee(azCol);.  }. 
8700: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
8710: 65 28 70 53 74 6d 74 29 3b 0a 20 20 72 65 74 75  e(pStmt);.  retu
8720: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
8730: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
8740: 20 6f 6e 6c 79 20 63 61 6c 6c 65 64 20 66 72 6f   only called fro
8750: 6d 20 77 69 74 68 69 6e 20 61 20 70 72 65 2d 75  m within a pre-u
8760: 70 64 61 74 65 20 68 61 6e 64 6c 65 72 20 66 6f  pdate handler fo
8770: 72 20 61 0a 2a 2a 20 77 72 69 74 65 20 74 6f 20  r a.** write to 
8780: 74 61 62 6c 65 20 70 54 61 62 2c 20 70 61 72 74  table pTab, part
8790: 20 6f 66 20 73 65 73 73 69 6f 6e 20 70 53 65 73   of session pSes
87a0: 73 69 6f 6e 2e 20 49 66 20 74 68 69 73 20 69 73  sion. If this is
87b0: 20 74 68 65 20 66 69 72 73 74 0a 2a 2a 20 77 72   the first.** wr
87c0: 69 74 65 20 74 6f 20 74 68 69 73 20 74 61 62 6c  ite to this tabl
87d0: 65 2c 20 69 6e 69 74 61 6c 69 7a 65 20 74 68 65  e, initalize the
87e0: 20 53 65 73 73 69 6f 6e 54 61 62 6c 65 2e 6e 43   SessionTable.nC
87f0: 6f 6c 2c 20 61 7a 43 6f 6c 5b 5d 20 61 6e 64 0a  ol, azCol[] and.
8800: 2a 2a 20 61 62 50 4b 5b 5d 20 61 72 72 61 79 73  ** abPK[] arrays
8810: 20 61 63 63 6f 72 64 69 6e 67 6c 79 2e 0a 2a 2a   accordingly..**
8820: 0a 2a 2a 20 49 66 20 61 6e 20 65 72 72 6f 72 20  .** If an error 
8830: 6f 63 63 75 72 73 2c 20 61 6e 20 65 72 72 6f 72  occurs, an error
8840: 20 63 6f 64 65 20 69 73 20 73 74 6f 72 65 64 20   code is stored 
8850: 69 6e 20 73 71 6c 69 74 65 33 5f 73 65 73 73 69  in sqlite3_sessi
8860: 6f 6e 2e 72 63 20 61 6e 64 0a 2a 2a 20 6e 6f 6e  on.rc and.** non
8870: 2d 7a 65 72 6f 20 72 65 74 75 72 6e 65 64 2e 20  -zero returned. 
8880: 4f 72 2c 20 69 66 20 6e 6f 20 65 72 72 6f 72 20  Or, if no error 
8890: 6f 63 63 75 72 73 20 62 75 74 20 74 68 65 20 74  occurs but the t
88a0: 61 62 6c 65 20 68 61 73 20 6e 6f 20 70 72 69 6d  able has no prim
88b0: 61 72 79 0a 2a 2a 20 6b 65 79 2c 20 73 71 6c 69  ary.** key, sqli
88c0: 74 65 33 5f 73 65 73 73 69 6f 6e 2e 72 63 20 69  te3_session.rc i
88d0: 73 20 6c 65 66 74 20 73 65 74 20 74 6f 20 53 51  s left set to SQ
88e0: 4c 49 54 45 5f 4f 4b 20 61 6e 64 20 6e 6f 6e 2d  LITE_OK and non-
88f0: 7a 65 72 6f 20 72 65 74 75 72 6e 65 64 20 74 6f  zero returned to
8900: 0a 2a 2a 20 69 6e 64 69 63 61 74 65 20 74 68 61  .** indicate tha
8910: 74 20 75 70 64 61 74 65 73 20 6f 6e 20 74 68 69  t updates on thi
8920: 73 20 74 61 62 6c 65 20 73 68 6f 75 6c 64 20 62  s table should b
8930: 65 20 69 67 6e 6f 72 65 64 2e 20 53 65 73 73 69  e ignored. Sessi
8940: 6f 6e 54 61 62 6c 65 2e 61 62 50 4b 20 0a 2a 2a  onTable.abPK .**
8950: 20 69 73 20 73 65 74 20 74 6f 20 4e 55 4c 4c 20   is set to NULL 
8960: 69 6e 20 74 68 69 73 20 63 61 73 65 2e 0a 2a 2f  in this case..*/
8970: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73  .static int sess
8980: 69 6f 6e 49 6e 69 74 54 61 62 6c 65 28 73 71 6c  ionInitTable(sql
8990: 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53  ite3_session *pS
89a0: 65 73 73 69 6f 6e 2c 20 53 65 73 73 69 6f 6e 54  ession, SessionT
89b0: 61 62 6c 65 20 2a 70 54 61 62 29 7b 0a 20 20 69  able *pTab){.  i
89c0: 66 28 20 70 54 61 62 2d 3e 6e 43 6f 6c 3d 3d 30  f( pTab->nCol==0
89d0: 20 29 7b 0a 20 20 20 20 75 38 20 2a 61 62 50 4b   ){.    u8 *abPK
89e0: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 54  ;.    assert( pT
89f0: 61 62 2d 3e 61 7a 43 6f 6c 3d 3d 30 20 7c 7c 20  ab->azCol==0 || 
8a00: 70 54 61 62 2d 3e 61 62 50 4b 3d 3d 30 20 29 3b  pTab->abPK==0 );
8a10: 0a 20 20 20 20 70 53 65 73 73 69 6f 6e 2d 3e 72  .    pSession->r
8a20: 63 20 3d 20 73 65 73 73 69 6f 6e 54 61 62 6c 65  c = sessionTable
8a30: 49 6e 66 6f 28 70 53 65 73 73 69 6f 6e 2d 3e 64  Info(pSession->d
8a40: 62 2c 20 70 53 65 73 73 69 6f 6e 2d 3e 7a 44 62  b, pSession->zDb
8a50: 2c 20 0a 20 20 20 20 20 20 20 20 70 54 61 62 2d  , .        pTab-
8a60: 3e 7a 4e 61 6d 65 2c 20 26 70 54 61 62 2d 3e 6e  >zName, &pTab->n
8a70: 43 6f 6c 2c 20 30 2c 20 26 70 54 61 62 2d 3e 61  Col, 0, &pTab->a
8a80: 7a 43 6f 6c 2c 20 26 61 62 50 4b 0a 20 20 20 20  zCol, &abPK.    
8a90: 29 3b 0a 20 20 20 20 69 66 28 20 70 53 65 73 73  );.    if( pSess
8aa0: 69 6f 6e 2d 3e 72 63 3d 3d 53 51 4c 49 54 45 5f  ion->rc==SQLITE_
8ab0: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  OK ){.      int 
8ac0: 69 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30  i;.      for(i=0
8ad0: 3b 20 69 3c 70 54 61 62 2d 3e 6e 43 6f 6c 3b 20  ; i<pTab->nCol; 
8ae0: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 69 66  i++){.        if
8af0: 28 20 61 62 50 4b 5b 69 5d 20 29 7b 0a 20 20 20  ( abPK[i] ){.   
8b00: 20 20 20 20 20 20 20 70 54 61 62 2d 3e 61 62 50         pTab->abP
8b10: 4b 20 3d 20 61 62 50 4b 3b 0a 20 20 20 20 20 20  K = abPK;.      
8b20: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
8b30: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
8b40: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
8b50: 28 70 53 65 73 73 69 6f 6e 2d 3e 72 63 20 7c 7c  (pSession->rc ||
8b60: 20 70 54 61 62 2d 3e 61 62 50 4b 3d 3d 30 29 3b   pTab->abPK==0);
8b70: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
8b80: 75 6e 63 74 69 6f 6e 20 69 73 20 6f 6e 6c 79 20  unction is only 
8b90: 63 61 6c 6c 65 64 20 66 72 6f 6d 20 77 69 74 68  called from with
8ba0: 20 61 20 70 72 65 2d 75 70 64 61 74 65 2d 68 6f   a pre-update-ho
8bb0: 6f 6b 20 72 65 70 6f 72 74 69 6e 67 20 61 20 0a  ok reporting a .
8bc0: 2a 2a 20 63 68 61 6e 67 65 20 6f 6e 20 74 61 62  ** change on tab
8bd0: 6c 65 20 70 54 61 62 20 28 61 74 74 61 63 68 65  le pTab (attache
8be0: 64 20 74 6f 20 73 65 73 73 69 6f 6e 20 70 53 65  d to session pSe
8bf0: 73 73 69 6f 6e 29 2e 20 54 68 65 20 74 79 70 65  ssion). The type
8c00: 20 6f 66 20 63 68 61 6e 67 65 0a 2a 2a 20 28 55   of change.** (U
8c10: 50 44 41 54 45 2c 20 49 4e 53 45 52 54 2c 20 44  PDATE, INSERT, D
8c20: 45 4c 45 54 45 29 20 69 73 20 73 70 65 63 69 66  ELETE) is specif
8c30: 69 65 64 20 62 79 20 74 68 65 20 66 69 72 73 74  ied by the first
8c40: 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a   argument..**.**
8c50: 20 55 6e 6c 65 73 73 20 6f 6e 65 20 69 73 20 61   Unless one is a
8c60: 6c 72 65 61 64 79 20 70 72 65 73 65 6e 74 20 6f  lready present o
8c70: 72 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  r an error occur
8c80: 73 2c 20 61 6e 20 65 6e 74 72 79 20 69 73 20 61  s, an entry is a
8c90: 64 64 65 64 0a 2a 2a 20 74 6f 20 74 68 65 20 63  dded.** to the c
8ca0: 68 61 6e 67 65 64 2d 72 6f 77 73 20 68 61 73 68  hanged-rows hash
8cb0: 20 74 61 62 6c 65 20 61 73 73 6f 63 69 61 74 65   table associate
8cc0: 64 20 77 69 74 68 20 74 61 62 6c 65 20 70 54 61  d with table pTa
8cd0: 62 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  b..*/.static voi
8ce0: 64 20 73 65 73 73 69 6f 6e 50 72 65 75 70 64 61  d sessionPreupda
8cf0: 74 65 4f 6e 65 43 68 61 6e 67 65 28 0a 20 20 69  teOneChange(.  i
8d00: 6e 74 20 6f 70 2c 20 20 20 20 20 20 20 20 20 20  nt op,          
8d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8d20: 2a 20 4f 6e 65 20 6f 66 20 53 51 4c 49 54 45 5f  * One of SQLITE_
8d30: 55 50 44 41 54 45 2c 20 49 4e 53 45 52 54 2c 20  UPDATE, INSERT, 
8d40: 44 45 4c 45 54 45 20 2a 2f 0a 20 20 73 71 6c 69  DELETE */.  sqli
8d50: 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65  te3_session *pSe
8d60: 73 73 69 6f 6e 2c 20 20 20 20 20 20 2f 2a 20 53  ssion,      /* S
8d70: 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 70 54  ession object pT
8d80: 61 62 20 69 73 20 61 74 74 61 63 68 65 64 20 74  ab is attached t
8d90: 6f 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 54 61  o */.  SessionTa
8da0: 62 6c 65 20 2a 70 54 61 62 20 20 20 20 20 20 20  ble *pTab       
8db0: 20 20 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20         /* Table 
8dc0: 74 68 61 74 20 63 68 61 6e 67 65 20 61 70 70 6c  that change appl
8dd0: 69 65 73 20 74 6f 20 2a 2f 0a 29 7b 0a 20 20 69  ies to */.){.  i
8de0: 6e 74 20 69 48 61 73 68 3b 20 0a 20 20 69 6e 74  nt iHash; .  int
8df0: 20 62 4e 75 6c 6c 20 3d 20 30 3b 20 0a 20 20 69   bNull = 0; .  i
8e00: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
8e10: 4b 3b 0a 0a 20 20 69 66 28 20 70 53 65 73 73 69  K;..  if( pSessi
8e20: 6f 6e 2d 3e 72 63 20 29 20 72 65 74 75 72 6e 3b  on->rc ) return;
8e30: 0a 0a 20 20 2f 2a 20 4c 6f 61 64 20 74 61 62 6c  ..  /* Load tabl
8e40: 65 20 64 65 74 61 69 6c 73 20 69 66 20 72 65 71  e details if req
8e50: 75 69 72 65 64 20 2a 2f 0a 20 20 69 66 28 20 73  uired */.  if( s
8e60: 65 73 73 69 6f 6e 49 6e 69 74 54 61 62 6c 65 28  essionInitTable(
8e70: 70 53 65 73 73 69 6f 6e 2c 20 70 54 61 62 29 20  pSession, pTab) 
8e80: 29 20 72 65 74 75 72 6e 3b 0a 0a 20 20 2f 2a 20  ) return;..  /* 
8e90: 43 68 65 63 6b 20 74 68 65 20 6e 75 6d 62 65 72  Check the number
8ea0: 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74   of columns in t
8eb0: 68 69 73 20 78 50 72 65 55 70 64 61 74 65 20 63  his xPreUpdate c
8ec0: 61 6c 6c 20 6d 61 74 63 68 65 73 20 74 68 65 20  all matches the 
8ed0: 0a 20 20 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20  .  ** number of 
8ee0: 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 68 65 20 74  columns in the t
8ef0: 61 62 6c 65 2e 20 20 2a 2f 0a 20 20 69 66 28 20  able.  */.  if( 
8f00: 70 54 61 62 2d 3e 6e 43 6f 6c 21 3d 70 53 65 73  pTab->nCol!=pSes
8f10: 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 43 6f 75 6e  sion->hook.xCoun
8f20: 74 28 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b  t(pSession->hook
8f30: 2e 70 43 74 78 29 20 29 7b 0a 20 20 20 20 70 53  .pCtx) ){.    pS
8f40: 65 73 73 69 6f 6e 2d 3e 72 63 20 3d 20 53 51 4c  ession->rc = SQL
8f50: 49 54 45 5f 53 43 48 45 4d 41 3b 0a 20 20 20 20  ITE_SCHEMA;.    
8f60: 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 0a 20 20 2f  return;.  }..  /
8f70: 2a 20 47 72 6f 77 20 74 68 65 20 68 61 73 68 20  * Grow the hash 
8f80: 74 61 62 6c 65 20 69 66 20 72 65 71 75 69 72 65  table if require
8f90: 64 20 2a 2f 0a 20 20 69 66 28 20 73 65 73 73 69  d */.  if( sessi
8fa0: 6f 6e 47 72 6f 77 48 61 73 68 28 30 2c 20 70 54  onGrowHash(0, pT
8fb0: 61 62 29 20 29 7b 0a 20 20 20 20 70 53 65 73 73  ab) ){.    pSess
8fc0: 69 6f 6e 2d 3e 72 63 20 3d 20 53 51 4c 49 54 45  ion->rc = SQLITE
8fd0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 72 65 74 75  _NOMEM;.    retu
8fe0: 72 6e 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 61  rn;.  }..  /* Ca
8ff0: 6c 63 75 6c 61 74 65 20 74 68 65 20 68 61 73 68  lculate the hash
9000: 2d 6b 65 79 20 66 6f 72 20 74 68 69 73 20 63 68  -key for this ch
9010: 61 6e 67 65 2e 20 49 66 20 74 68 65 20 70 72 69  ange. If the pri
9020: 6d 61 72 79 20 6b 65 79 20 6f 66 20 74 68 65 20  mary key of the 
9030: 72 6f 77 0a 20 20 2a 2a 20 69 6e 63 6c 75 64 65  row.  ** include
9040: 73 20 61 20 4e 55 4c 4c 20 76 61 6c 75 65 2c 20  s a NULL value, 
9050: 65 78 69 74 20 65 61 72 6c 79 2e 20 53 75 63 68  exit early. Such
9060: 20 63 68 61 6e 67 65 73 20 61 72 65 20 69 67 6e   changes are ign
9070: 6f 72 65 64 20 62 79 20 74 68 65 0a 20 20 2a 2a  ored by the.  **
9080: 20 73 65 73 73 69 6f 6e 20 6d 6f 64 75 6c 65 2e   session module.
9090: 20 2a 2f 0a 20 20 72 63 20 3d 20 73 65 73 73 69   */.  rc = sessi
90a0: 6f 6e 50 72 65 75 70 64 61 74 65 48 61 73 68 28  onPreupdateHash(
90b0: 70 53 65 73 73 69 6f 6e 2c 20 70 54 61 62 2c 20  pSession, pTab, 
90c0: 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52  op==SQLITE_INSER
90d0: 54 2c 20 26 69 48 61 73 68 2c 20 26 62 4e 75 6c  T, &iHash, &bNul
90e0: 6c 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  l);.  if( rc!=SQ
90f0: 4c 49 54 45 5f 4f 4b 20 29 20 67 6f 74 6f 20 65  LITE_OK ) goto e
9100: 72 72 6f 72 5f 6f 75 74 3b 0a 0a 20 20 69 66 28  rror_out;..  if(
9110: 20 62 4e 75 6c 6c 3d 3d 30 20 29 7b 0a 20 20 20   bNull==0 ){.   
9120: 20 2f 2a 20 53 65 61 72 63 68 20 74 68 65 20 68   /* Search the h
9130: 61 73 68 20 74 61 62 6c 65 20 66 6f 72 20 61 6e  ash table for an
9140: 20 65 78 69 73 74 69 6e 67 20 72 65 63 6f 72 64   existing record
9150: 20 66 6f 72 20 74 68 69 73 20 72 6f 77 2e 20 2a   for this row. *
9160: 2f 0a 20 20 20 20 53 65 73 73 69 6f 6e 43 68 61  /.    SessionCha
9170: 6e 67 65 20 2a 70 43 3b 0a 20 20 20 20 66 6f 72  nge *pC;.    for
9180: 28 70 43 3d 70 54 61 62 2d 3e 61 70 43 68 61 6e  (pC=pTab->apChan
9190: 67 65 5b 69 48 61 73 68 5d 3b 20 70 43 3b 20 70  ge[iHash]; pC; p
91a0: 43 3d 70 43 2d 3e 70 4e 65 78 74 29 7b 0a 20 20  C=pC->pNext){.  
91b0: 20 20 20 20 69 66 28 20 73 65 73 73 69 6f 6e 50      if( sessionP
91c0: 72 65 75 70 64 61 74 65 45 71 75 61 6c 28 70 53  reupdateEqual(pS
91d0: 65 73 73 69 6f 6e 2c 20 70 54 61 62 2c 20 70 43  ession, pTab, pC
91e0: 2c 20 6f 70 29 20 29 20 62 72 65 61 6b 3b 0a 20  , op) ) break;. 
91f0: 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 70 43     }..    if( pC
9200: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  ==0 ){.      /* 
9210: 43 72 65 61 74 65 20 61 20 6e 65 77 20 63 68 61  Create a new cha
9220: 6e 67 65 20 6f 62 6a 65 63 74 20 63 6f 6e 74 61  nge object conta
9230: 69 6e 69 6e 67 20 61 6c 6c 20 74 68 65 20 6f 6c  ining all the ol
9240: 64 20 76 61 6c 75 65 73 20 28 69 66 0a 20 20 20  d values (if.   
9250: 20 20 20 2a 2a 20 74 68 69 73 20 69 73 20 61 6e     ** this is an
9260: 20 53 51 4c 49 54 45 5f 55 50 44 41 54 45 20 6f   SQLITE_UPDATE o
9270: 72 20 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 29  r SQLITE_DELETE)
9280: 2c 20 6f 72 20 6a 75 73 74 20 74 68 65 20 50 4b  , or just the PK
9290: 0a 20 20 20 20 20 20 2a 2a 20 76 61 6c 75 65 73  .      ** values
92a0: 20 28 69 66 20 74 68 69 73 20 69 73 20 61 6e 20   (if this is an 
92b0: 49 4e 53 45 52 54 29 2e 20 2a 2f 0a 20 20 20 20  INSERT). */.    
92c0: 20 20 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20    SessionChange 
92d0: 2a 70 43 68 61 6e 67 65 3b 20 2f 2a 20 4e 65 77  *pChange; /* New
92e0: 20 63 68 61 6e 67 65 20 6f 62 6a 65 63 74 20 2a   change object *
92f0: 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74  /.      int nByt
9300: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
9310: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74  /* Number of byt
9320: 65 73 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a  es to allocate *
9330: 2f 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 20 20  /.      int i;  
9340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9350: 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72 61  /* Used to itera
9360: 74 65 20 74 68 72 6f 75 67 68 20 63 6f 6c 75 6d  te through colum
9370: 6e 73 20 2a 2f 0a 20 20 0a 20 20 20 20 20 20 61  ns */.  .      a
9380: 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54  ssert( rc==SQLIT
9390: 45 5f 4f 4b 20 29 3b 0a 20 20 20 20 20 20 70 54  E_OK );.      pT
93a0: 61 62 2d 3e 6e 45 6e 74 72 79 2b 2b 3b 0a 20 20  ab->nEntry++;.  
93b0: 0a 20 20 20 20 20 20 2f 2a 20 46 69 67 75 72 65  .      /* Figure
93c0: 20 6f 75 74 20 68 6f 77 20 6c 61 72 67 65 20 61   out how large a
93d0: 6e 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 73 20  n allocation is 
93e0: 72 65 71 75 69 72 65 64 20 2a 2f 0a 20 20 20 20  required */.    
93f0: 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66    nByte = sizeof
9400: 28 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 29 3b  (SessionChange);
9410: 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  .      for(i=0; 
9420: 69 3c 70 54 61 62 2d 3e 6e 43 6f 6c 3b 20 69 2b  i<pTab->nCol; i+
9430: 2b 29 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69  +){.        sqli
9440: 74 65 33 5f 76 61 6c 75 65 20 2a 70 20 3d 20 30  te3_value *p = 0
9450: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 6f 70  ;.        if( op
9460: 21 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 20  !=SQLITE_INSERT 
9470: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 54 45 53  ){.          TES
9480: 54 4f 4e 4c 59 28 69 6e 74 20 74 72 63 20 3d 20  TONLY(int trc = 
9490: 29 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b  ) pSession->hook
94a0: 2e 78 4f 6c 64 28 70 53 65 73 73 69 6f 6e 2d 3e  .xOld(pSession->
94b0: 68 6f 6f 6b 2e 70 43 74 78 2c 20 69 2c 20 26 70  hook.pCtx, i, &p
94c0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 61 73 73  );.          ass
94d0: 65 72 74 28 20 74 72 63 3d 3d 53 51 4c 49 54 45  ert( trc==SQLITE
94e0: 5f 4f 4b 20 29 3b 0a 20 20 20 20 20 20 20 20 7d  _OK );.        }
94f0: 65 6c 73 65 20 69 66 28 20 70 54 61 62 2d 3e 61  else if( pTab->a
9500: 62 50 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20  bPK[i] ){.      
9510: 20 20 20 20 54 45 53 54 4f 4e 4c 59 28 69 6e 74      TESTONLY(int
9520: 20 74 72 63 20 3d 20 29 20 70 53 65 73 73 69 6f   trc = ) pSessio
9530: 6e 2d 3e 68 6f 6f 6b 2e 78 4e 65 77 28 70 53 65  n->hook.xNew(pSe
9540: 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 70 43 74 78  ssion->hook.pCtx
9550: 2c 20 69 2c 20 26 70 29 3b 0a 20 20 20 20 20 20  , i, &p);.      
9560: 20 20 20 20 61 73 73 65 72 74 28 20 74 72 63 3d      assert( trc=
9570: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20  =SQLITE_OK );.  
9580: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20        }..       
9590: 20 2f 2a 20 54 68 69 73 20 6d 61 79 20 66 61 69   /* This may fai
95a0: 6c 20 69 66 20 53 51 4c 69 74 65 20 76 61 6c 75  l if SQLite valu
95b0: 65 20 70 20 63 6f 6e 74 61 69 6e 73 20 61 20 75  e p contains a u
95c0: 74 66 2d 31 36 20 73 74 72 69 6e 67 20 74 68 61  tf-16 string tha
95d0: 74 20 6d 75 73 74 0a 20 20 20 20 20 20 20 20 2a  t must.        *
95e0: 2a 20 62 65 20 63 6f 6e 76 65 72 74 65 64 20 74  * be converted t
95f0: 6f 20 75 74 66 2d 38 20 61 6e 64 20 61 6e 20 4f  o utf-8 and an O
9600: 4f 4d 20 65 72 72 6f 72 20 6f 63 63 75 72 73 20  OM error occurs 
9610: 77 68 69 6c 65 20 64 6f 69 6e 67 20 73 6f 2e 20  while doing so. 
9620: 2a 2f 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  */.        rc = 
9630: 73 65 73 73 69 6f 6e 53 65 72 69 61 6c 69 7a 65  sessionSerialize
9640: 56 61 6c 75 65 28 30 2c 20 70 2c 20 26 6e 42 79  Value(0, p, &nBy
9650: 74 65 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  te);.        if(
9660: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
9670: 20 67 6f 74 6f 20 65 72 72 6f 72 5f 6f 75 74 3b   goto error_out;
9680: 0a 20 20 20 20 20 20 7d 0a 20 20 0a 20 20 20 20  .      }.  .    
9690: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74 68    /* Allocate th
96a0: 65 20 63 68 61 6e 67 65 20 6f 62 6a 65 63 74 20  e change object 
96b0: 2a 2f 0a 20 20 20 20 20 20 70 43 68 61 6e 67 65  */.      pChange
96c0: 20 3d 20 28 53 65 73 73 69 6f 6e 43 68 61 6e 67   = (SessionChang
96d0: 65 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  e *)sqlite3_mall
96e0: 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20 20  oc(nByte);.     
96f0: 20 69 66 28 20 21 70 43 68 61 6e 67 65 20 29 7b   if( !pChange ){
9700: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51  .        rc = SQ
9710: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
9720: 20 20 20 20 67 6f 74 6f 20 65 72 72 6f 72 5f 6f      goto error_o
9730: 75 74 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  ut;.      }else{
9740: 0a 20 20 20 20 20 20 20 20 6d 65 6d 73 65 74 28  .        memset(
9750: 70 43 68 61 6e 67 65 2c 20 30 2c 20 73 69 7a 65  pChange, 0, size
9760: 6f 66 28 53 65 73 73 69 6f 6e 43 68 61 6e 67 65  of(SessionChange
9770: 29 29 3b 0a 20 20 20 20 20 20 20 20 70 43 68 61  ));.        pCha
9780: 6e 67 65 2d 3e 61 52 65 63 6f 72 64 20 3d 20 28  nge->aRecord = (
9790: 75 38 20 2a 29 26 70 43 68 61 6e 67 65 5b 31 5d  u8 *)&pChange[1]
97a0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 0a 20 20 20  ;.      }.  .   
97b0: 20 20 20 2f 2a 20 50 6f 70 75 6c 61 74 65 20 74     /* Populate t
97c0: 68 65 20 63 68 61 6e 67 65 20 6f 62 6a 65 63 74  he change object
97d0: 2e 20 4e 6f 6e 65 20 6f 66 20 74 68 65 20 70 72  . None of the pr
97e0: 65 75 70 64 61 74 65 5f 6f 6c 64 28 29 2c 0a 20  eupdate_old(),. 
97f0: 20 20 20 20 20 2a 2a 20 70 72 65 75 70 64 61 74       ** preupdat
9800: 65 5f 6e 65 77 28 29 20 6f 72 20 53 65 72 69 61  e_new() or Seria
9810: 6c 69 7a 65 56 61 6c 75 65 28 29 20 63 61 6c 6c  lizeValue() call
9820: 73 20 62 65 6c 6f 77 20 6d 61 79 20 66 61 69 6c  s below may fail
9830: 20 61 73 20 61 6c 6c 0a 20 20 20 20 20 20 2a 2a   as all.      **
9840: 20 72 65 71 75 69 72 65 64 20 76 61 6c 75 65 73   required values
9850: 20 61 6e 64 20 65 6e 63 6f 64 69 6e 67 73 20 68   and encodings h
9860: 61 76 65 20 61 6c 72 65 61 64 79 20 62 65 65 6e  ave already been
9870: 20 63 61 63 68 65 64 20 69 6e 20 6d 65 6d 6f 72   cached in memor
9880: 79 2e 0a 20 20 20 20 20 20 2a 2a 20 49 74 20 69  y..      ** It i
9890: 73 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65 20 66  s not possible f
98a0: 6f 72 20 61 6e 20 4f 4f 4d 20 74 6f 20 6f 63 63  or an OOM to occ
98b0: 75 72 20 69 6e 20 74 68 69 73 20 62 6c 6f 63 6b  ur in this block
98c0: 2e 20 2a 2f 0a 20 20 20 20 20 20 6e 42 79 74 65  . */.      nByte
98d0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 66 6f 72 28   = 0;.      for(
98e0: 69 3d 30 3b 20 69 3c 70 54 61 62 2d 3e 6e 43 6f  i=0; i<pTab->nCo
98f0: 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20  l; i++){.       
9900: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
9910: 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 69  p = 0;.        i
9920: 66 28 20 6f 70 21 3d 53 51 4c 49 54 45 5f 49 4e  f( op!=SQLITE_IN
9930: 53 45 52 54 20 29 7b 0a 20 20 20 20 20 20 20 20  SERT ){.        
9940: 20 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b    pSession->hook
9950: 2e 78 4f 6c 64 28 70 53 65 73 73 69 6f 6e 2d 3e  .xOld(pSession->
9960: 68 6f 6f 6b 2e 70 43 74 78 2c 20 69 2c 20 26 70  hook.pCtx, i, &p
9970: 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65  );.        }else
9980: 20 69 66 28 20 70 54 61 62 2d 3e 61 62 50 4b 5b   if( pTab->abPK[
9990: 69 5d 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  i] ){.          
99a0: 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78  pSession->hook.x
99b0: 4e 65 77 28 70 53 65 73 73 69 6f 6e 2d 3e 68 6f  New(pSession->ho
99c0: 6f 6b 2e 70 43 74 78 2c 20 69 2c 20 26 70 29 3b  ok.pCtx, i, &p);
99d0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
99e0: 20 20 20 73 65 73 73 69 6f 6e 53 65 72 69 61 6c     sessionSerial
99f0: 69 7a 65 56 61 6c 75 65 28 26 70 43 68 61 6e 67  izeValue(&pChang
9a00: 65 2d 3e 61 52 65 63 6f 72 64 5b 6e 42 79 74 65  e->aRecord[nByte
9a10: 5d 2c 20 70 2c 20 26 6e 42 79 74 65 29 3b 0a 20  ], p, &nByte);. 
9a20: 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a       }..      /*
9a30: 20 41 64 64 20 74 68 65 20 63 68 61 6e 67 65 20   Add the change 
9a40: 74 6f 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c  to the hash-tabl
9a50: 65 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 70  e */.      if( p
9a60: 53 65 73 73 69 6f 6e 2d 3e 62 49 6e 64 69 72 65  Session->bIndire
9a70: 63 74 20 7c 7c 20 70 53 65 73 73 69 6f 6e 2d 3e  ct || pSession->
9a80: 68 6f 6f 6b 2e 78 44 65 70 74 68 28 70 53 65 73  hook.xDepth(pSes
9a90: 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 70 43 74 78 29  sion->hook.pCtx)
9aa0: 20 29 7b 0a 20 20 20 20 20 20 20 20 70 43 68 61   ){.        pCha
9ab0: 6e 67 65 2d 3e 62 49 6e 64 69 72 65 63 74 20 3d  nge->bIndirect =
9ac0: 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20   1;.      }.    
9ad0: 20 20 70 43 68 61 6e 67 65 2d 3e 6e 52 65 63 6f    pChange->nReco
9ae0: 72 64 20 3d 20 6e 42 79 74 65 3b 0a 20 20 20 20  rd = nByte;.    
9af0: 20 20 70 43 68 61 6e 67 65 2d 3e 6f 70 20 3d 20    pChange->op = 
9b00: 6f 70 3b 0a 20 20 20 20 20 20 70 43 68 61 6e 67  op;.      pChang
9b10: 65 2d 3e 70 4e 65 78 74 20 3d 20 70 54 61 62 2d  e->pNext = pTab-
9b20: 3e 61 70 43 68 61 6e 67 65 5b 69 48 61 73 68 5d  >apChange[iHash]
9b30: 3b 0a 20 20 20 20 20 20 70 54 61 62 2d 3e 61 70  ;.      pTab->ap
9b40: 43 68 61 6e 67 65 5b 69 48 61 73 68 5d 20 3d 20  Change[iHash] = 
9b50: 70 43 68 61 6e 67 65 3b 0a 0a 20 20 20 20 7d 65  pChange;..    }e
9b60: 6c 73 65 20 69 66 28 20 70 43 2d 3e 62 49 6e 64  lse if( pC->bInd
9b70: 69 72 65 63 74 20 29 7b 0a 20 20 20 20 20 20 2f  irect ){.      /
9b80: 2a 20 49 66 20 74 68 65 20 65 78 69 73 74 69 6e  * If the existin
9b90: 67 20 63 68 61 6e 67 65 20 69 73 20 63 6f 6e 73  g change is cons
9ba0: 69 64 65 72 65 64 20 22 69 6e 64 69 72 65 63 74  idered "indirect
9bb0: 22 2c 20 62 75 74 20 74 68 69 73 20 63 75 72 72  ", but this curr
9bc0: 65 6e 74 0a 20 20 20 20 20 20 2a 2a 20 63 68 61  ent.      ** cha
9bd0: 6e 67 65 20 69 73 20 22 64 69 72 65 63 74 22 2c  nge is "direct",
9be0: 20 6d 61 72 6b 20 74 68 65 20 63 68 61 6e 67 65   mark the change
9bf0: 20 6f 62 6a 65 63 74 20 61 73 20 64 69 72 65 63   object as direc
9c00: 74 2e 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20  t. */.      if( 
9c10: 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78  pSession->hook.x
9c20: 44 65 70 74 68 28 70 53 65 73 73 69 6f 6e 2d 3e  Depth(pSession->
9c30: 68 6f 6f 6b 2e 70 43 74 78 29 3d 3d 30 20 0a 20  hook.pCtx)==0 . 
9c40: 20 20 20 20 20 20 26 26 20 70 53 65 73 73 69 6f        && pSessio
9c50: 6e 2d 3e 62 49 6e 64 69 72 65 63 74 3d 3d 30 20  n->bIndirect==0 
9c60: 0a 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20  .      ){.      
9c70: 20 20 70 43 2d 3e 62 49 6e 64 69 72 65 63 74 20    pC->bIndirect 
9c80: 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  = 0;.      }.   
9c90: 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20   }.  }..  /* If 
9ca0: 61 6e 20 65 72 72 6f 72 20 68 61 73 20 6f 63 63  an error has occ
9cb0: 75 72 72 65 64 2c 20 6d 61 72 6b 20 74 68 65 20  urred, mark the 
9cc0: 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 61  session object a
9cd0: 73 20 66 61 69 6c 65 64 2e 20 2a 2f 0a 20 65 72  s failed. */. er
9ce0: 72 6f 72 5f 6f 75 74 3a 0a 20 20 69 66 28 20 72  ror_out:.  if( r
9cf0: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
9d00: 20 20 20 20 70 53 65 73 73 69 6f 6e 2d 3e 72 63      pSession->rc
9d10: 20 3d 20 72 63 3b 0a 20 20 7d 0a 7d 0a 0a 73 74   = rc;.  }.}..st
9d20: 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e  atic int session
9d30: 46 69 6e 64 54 61 62 6c 65 28 0a 20 20 73 71 6c  FindTable(.  sql
9d40: 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53  ite3_session *pS
9d50: 65 73 73 69 6f 6e 2c 20 0a 20 20 63 6f 6e 73 74  ession, .  const
9d60: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20 20   char *zName,.  
9d70: 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 2a 70  SessionTable **p
9d80: 70 54 61 62 0a 29 7b 0a 20 20 69 6e 74 20 72 63  pTab.){.  int rc
9d90: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
9da0: 69 6e 74 20 6e 4e 61 6d 65 20 3d 20 73 71 6c 69  int nName = sqli
9db0: 74 65 33 53 74 72 6c 65 6e 33 30 28 7a 4e 61 6d  te3Strlen30(zNam
9dc0: 65 29 3b 0a 20 20 53 65 73 73 69 6f 6e 54 61 62  e);.  SessionTab
9dd0: 6c 65 20 2a 70 52 65 74 3b 0a 0a 20 20 2f 2a 20  le *pRet;..  /* 
9de0: 53 65 61 72 63 68 20 66 6f 72 20 61 6e 20 65 78  Search for an ex
9df0: 69 73 74 69 6e 67 20 74 61 62 6c 65 20 2a 2f 0a  isting table */.
9e00: 20 20 66 6f 72 28 70 52 65 74 3d 70 53 65 73 73    for(pRet=pSess
9e10: 69 6f 6e 2d 3e 70 54 61 62 6c 65 3b 20 70 52 65  ion->pTable; pRe
9e20: 74 3b 20 70 52 65 74 3d 70 52 65 74 2d 3e 70 4e  t; pRet=pRet->pN
9e30: 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20 30 3d  ext){.    if( 0=
9e40: 3d 73 71 6c 69 74 65 33 5f 73 74 72 6e 69 63 6d  =sqlite3_strnicm
9e50: 70 28 70 52 65 74 2d 3e 7a 4e 61 6d 65 2c 20 7a  p(pRet->zName, z
9e60: 4e 61 6d 65 2c 20 6e 4e 61 6d 65 2b 31 29 20 29  Name, nName+1) )
9e70: 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 69   break;.  }..  i
9e80: 66 28 20 70 52 65 74 3d 3d 30 20 26 26 20 70 53  f( pRet==0 && pS
9e90: 65 73 73 69 6f 6e 2d 3e 62 41 75 74 6f 41 74 74  ession->bAutoAtt
9ea0: 61 63 68 20 29 7b 0a 20 20 20 20 2f 2a 20 49 66  ach ){.    /* If
9eb0: 20 74 68 65 72 65 20 69 73 20 61 20 74 61 62 6c   there is a tabl
9ec0: 65 2d 66 69 6c 74 65 72 20 63 6f 6e 66 69 67 75  e-filter configu
9ed0: 72 65 64 2c 20 69 6e 76 6f 6b 65 20 69 74 2e 20  red, invoke it. 
9ee0: 49 66 20 69 74 20 72 65 74 75 72 6e 73 20 30 2c  If it returns 0,
9ef0: 0a 20 20 20 20 2a 2a 20 64 6f 20 6e 6f 74 20 61  .    ** do not a
9f00: 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20 61 64 64  utomatically add
9f10: 20 74 68 65 20 6e 65 77 20 74 61 62 6c 65 2e 20   the new table. 
9f20: 2a 2f 0a 20 20 20 20 69 66 28 20 70 53 65 73 73  */.    if( pSess
9f30: 69 6f 6e 2d 3e 78 54 61 62 6c 65 46 69 6c 74 65  ion->xTableFilte
9f40: 72 3d 3d 30 0a 20 20 20 20 20 7c 7c 20 70 53 65  r==0.     || pSe
9f50: 73 73 69 6f 6e 2d 3e 78 54 61 62 6c 65 46 69 6c  ssion->xTableFil
9f60: 74 65 72 28 70 53 65 73 73 69 6f 6e 2d 3e 70 46  ter(pSession->pF
9f70: 69 6c 74 65 72 43 74 78 2c 20 7a 4e 61 6d 65 29  ilterCtx, zName)
9f80: 20 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 72   .    ){.      r
9f90: 63 20 3d 20 73 71 6c 69 74 65 33 73 65 73 73 69  c = sqlite3sessi
9fa0: 6f 6e 5f 61 74 74 61 63 68 28 70 53 65 73 73 69  on_attach(pSessi
9fb0: 6f 6e 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 20 20  on, zName);.    
9fc0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
9fd0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 66  _OK ){.        f
9fe0: 6f 72 28 70 52 65 74 3d 70 53 65 73 73 69 6f 6e  or(pRet=pSession
9ff0: 2d 3e 70 54 61 62 6c 65 3b 20 70 52 65 74 2d 3e  ->pTable; pRet->
a000: 70 4e 65 78 74 3b 20 70 52 65 74 3d 70 52 65 74  pNext; pRet=pRet
a010: 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 20 20 20 20  ->pNext);.      
a020: 20 20 61 73 73 65 72 74 28 20 30 3d 3d 73 71 6c    assert( 0==sql
a030: 69 74 65 33 5f 73 74 72 6e 69 63 6d 70 28 70 52  ite3_strnicmp(pR
a040: 65 74 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65  et->zName, zName
a050: 2c 20 6e 4e 61 6d 65 2b 31 29 20 29 3b 0a 20 20  , nName+1) );.  
a060: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
a070: 0a 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53  .  assert( rc==S
a080: 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 52 65 74  QLITE_OK || pRet
a090: 3d 3d 30 20 29 3b 0a 20 20 2a 70 70 54 61 62 20  ==0 );.  *ppTab 
a0a0: 3d 20 70 52 65 74 3b 0a 20 20 72 65 74 75 72 6e  = pRet;.  return
a0b0: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
a0c0: 65 20 27 70 72 65 2d 75 70 64 61 74 65 27 20 68  e 'pre-update' h
a0d0: 6f 6f 6b 20 72 65 67 69 73 74 65 72 65 64 20 62  ook registered b
a0e0: 79 20 74 68 69 73 20 6d 6f 64 75 6c 65 20 77 69  y this module wi
a0f0: 74 68 20 53 51 4c 69 74 65 20 64 61 74 61 62 61  th SQLite databa
a100: 73 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ses..*/.static v
a110: 6f 69 64 20 78 50 72 65 55 70 64 61 74 65 28 0a  oid xPreUpdate(.
a120: 20 20 76 6f 69 64 20 2a 70 43 74 78 2c 20 20 20    void *pCtx,   
a130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a140: 20 20 2f 2a 20 43 6f 70 79 20 6f 66 20 74 68 69    /* Copy of thi
a150: 72 64 20 61 72 67 20 74 6f 20 70 72 65 75 70 64  rd arg to preupd
a160: 61 74 65 5f 68 6f 6f 6b 28 29 20 2a 2f 0a 20 20  ate_hook() */.  
a170: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20  sqlite3 *db,    
a180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a190: 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e 64  /* Database hand
a1a0: 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6f 70 2c 20  le */.  int op, 
a1b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a1c0: 20 20 20 20 20 20 20 20 2f 2a 20 53 51 4c 49 54          /* SQLIT
a1d0: 45 5f 55 50 44 41 54 45 2c 20 44 45 4c 45 54 45  E_UPDATE, DELETE
a1e0: 20 6f 72 20 49 4e 53 45 52 54 20 2a 2f 0a 20 20   or INSERT */.  
a1f0: 63 68 61 72 20 63 6f 6e 73 74 20 2a 7a 44 62 2c  char const *zDb,
a200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a210: 2f 2a 20 44 61 74 61 62 61 73 65 20 6e 61 6d 65  /* Database name
a220: 20 2a 2f 0a 20 20 63 68 61 72 20 63 6f 6e 73 74   */.  char const
a230: 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 20 20 20 20   *zName,        
a240: 20 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20 6e        /* Table n
a250: 61 6d 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ame */.  sqlite3
a260: 5f 69 6e 74 36 34 20 69 4b 65 79 31 2c 20 20 20  _int64 iKey1,   
a270: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 6f 77 69           /* Rowi
a280: 64 20 6f 66 20 72 6f 77 20 61 62 6f 75 74 20 74  d of row about t
a290: 6f 20 62 65 20 64 65 6c 65 74 65 64 2f 75 70 64  o be deleted/upd
a2a0: 61 74 65 64 20 2a 2f 0a 20 20 73 71 6c 69 74 65  ated */.  sqlite
a2b0: 33 5f 69 6e 74 36 34 20 69 4b 65 79 32 20 20 20  3_int64 iKey2   
a2c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 77            /* New
a2d0: 20 72 6f 77 69 64 20 76 61 6c 75 65 20 28 66 6f   rowid value (fo
a2e0: 72 20 61 20 72 6f 77 69 64 20 55 50 44 41 54 45  r a rowid UPDATE
a2f0: 29 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65  ) */.){.  sqlite
a300: 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73  3_session *pSess
a310: 69 6f 6e 3b 0a 20 20 69 6e 74 20 6e 44 62 20 3d  ion;.  int nDb =
a320: 20 73 71 6c 69 74 65 33 53 74 72 6c 65 6e 33 30   sqlite3Strlen30
a330: 28 7a 44 62 29 3b 0a 0a 20 20 61 73 73 65 72 74  (zDb);..  assert
a340: 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  ( sqlite3_mutex_
a350: 68 65 6c 64 28 64 62 2d 3e 6d 75 74 65 78 29 20  held(db->mutex) 
a360: 29 3b 0a 0a 20 20 66 6f 72 28 70 53 65 73 73 69  );..  for(pSessi
a370: 6f 6e 3d 28 73 71 6c 69 74 65 33 5f 73 65 73 73  on=(sqlite3_sess
a380: 69 6f 6e 20 2a 29 70 43 74 78 3b 20 70 53 65 73  ion *)pCtx; pSes
a390: 73 69 6f 6e 3b 20 70 53 65 73 73 69 6f 6e 3d 70  sion; pSession=p
a3a0: 53 65 73 73 69 6f 6e 2d 3e 70 4e 65 78 74 29 7b  Session->pNext){
a3b0: 0a 20 20 20 20 53 65 73 73 69 6f 6e 54 61 62 6c  .    SessionTabl
a3c0: 65 20 2a 70 54 61 62 3b 0a 0a 20 20 20 20 2f 2a  e *pTab;..    /*
a3d0: 20 49 66 20 74 68 69 73 20 73 65 73 73 69 6f 6e   If this session
a3e0: 20 69 73 20 61 74 74 61 63 68 65 64 20 74 6f 20   is attached to 
a3f0: 61 20 64 69 66 66 65 72 65 6e 74 20 64 61 74 61  a different data
a400: 62 61 73 65 20 28 22 6d 61 69 6e 22 2c 20 22 74  base ("main", "t
a410: 65 6d 70 22 20 0a 20 20 20 20 2a 2a 20 65 74 63  emp" .    ** etc
a420: 2e 29 2c 20 6f 72 20 69 66 20 69 74 20 69 73 20  .), or if it is 
a430: 6e 6f 74 20 63 75 72 72 65 6e 74 6c 79 20 65 6e  not currently en
a440: 61 62 6c 65 64 2c 20 74 68 65 72 65 20 69 73 20  abled, there is 
a450: 6e 6f 74 68 69 6e 67 20 74 6f 20 64 6f 2e 20 53  nothing to do. S
a460: 6b 69 70 20 0a 20 20 20 20 2a 2a 20 74 6f 20 74  kip .    ** to t
a470: 68 65 20 6e 65 78 74 20 73 65 73 73 69 6f 6e 20  he next session 
a480: 6f 62 6a 65 63 74 20 61 74 74 61 63 68 65 64 20  object attached 
a490: 74 6f 20 74 68 69 73 20 64 61 74 61 62 61 73 65  to this database
a4a0: 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 53 65  . */.    if( pSe
a4b0: 73 73 69 6f 6e 2d 3e 62 45 6e 61 62 6c 65 3d 3d  ssion->bEnable==
a4c0: 30 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20  0 ) continue;.  
a4d0: 20 20 69 66 28 20 70 53 65 73 73 69 6f 6e 2d 3e    if( pSession->
a4e0: 72 63 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20  rc ) continue;. 
a4f0: 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 73     if( sqlite3_s
a500: 74 72 6e 69 63 6d 70 28 7a 44 62 2c 20 70 53 65  trnicmp(zDb, pSe
a510: 73 73 69 6f 6e 2d 3e 7a 44 62 2c 20 6e 44 62 2b  ssion->zDb, nDb+
a520: 31 29 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 0a  1) ) continue;..
a530: 20 20 20 20 70 53 65 73 73 69 6f 6e 2d 3e 72 63      pSession->rc
a540: 20 3d 20 73 65 73 73 69 6f 6e 46 69 6e 64 54 61   = sessionFindTa
a550: 62 6c 65 28 70 53 65 73 73 69 6f 6e 2c 20 7a 4e  ble(pSession, zN
a560: 61 6d 65 2c 20 26 70 54 61 62 29 3b 0a 20 20 20  ame, &pTab);.   
a570: 20 69 66 28 20 70 54 61 62 20 29 7b 0a 20 20 20   if( pTab ){.   
a580: 20 20 20 61 73 73 65 72 74 28 20 70 53 65 73 73     assert( pSess
a590: 69 6f 6e 2d 3e 72 63 3d 3d 53 51 4c 49 54 45 5f  ion->rc==SQLITE_
a5a0: 4f 4b 20 29 3b 0a 20 20 20 20 20 20 73 65 73 73  OK );.      sess
a5b0: 69 6f 6e 50 72 65 75 70 64 61 74 65 4f 6e 65 43  ionPreupdateOneC
a5c0: 68 61 6e 67 65 28 6f 70 2c 20 70 53 65 73 73 69  hange(op, pSessi
a5d0: 6f 6e 2c 20 70 54 61 62 29 3b 0a 20 20 20 20 20  on, pTab);.     
a5e0: 20 69 66 28 20 6f 70 3d 3d 53 51 4c 49 54 45 5f   if( op==SQLITE_
a5f0: 55 50 44 41 54 45 20 29 7b 0a 20 20 20 20 20 20  UPDATE ){.      
a600: 20 20 73 65 73 73 69 6f 6e 50 72 65 75 70 64 61    sessionPreupda
a610: 74 65 4f 6e 65 43 68 61 6e 67 65 28 53 51 4c 49  teOneChange(SQLI
a620: 54 45 5f 49 4e 53 45 52 54 2c 20 70 53 65 73 73  TE_INSERT, pSess
a630: 69 6f 6e 2c 20 70 54 61 62 29 3b 0a 20 20 20 20  ion, pTab);.    
a640: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a    }.    }.  }.}.
a650: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 70 72 65 2d 75  ./*.** The pre-u
a660: 70 64 61 74 65 20 68 6f 6f 6b 20 69 6d 70 6c 65  pdate hook imple
a670: 6d 65 6e 74 61 74 69 6f 6e 73 2e 0a 2a 2f 0a 73  mentations..*/.s
a680: 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f  tatic int sessio
a690: 6e 50 72 65 75 70 64 61 74 65 4f 6c 64 28 76 6f  nPreupdateOld(vo
a6a0: 69 64 20 2a 70 43 74 78 2c 20 69 6e 74 20 69 56  id *pCtx, int iV
a6b0: 61 6c 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  al, sqlite3_valu
a6c0: 65 20 2a 2a 70 70 56 61 6c 29 7b 0a 20 20 72 65  e **ppVal){.  re
a6d0: 74 75 72 6e 20 73 71 6c 69 74 65 33 5f 70 72 65  turn sqlite3_pre
a6e0: 75 70 64 61 74 65 5f 6f 6c 64 28 28 73 71 6c 69  update_old((sqli
a6f0: 74 65 33 2a 29 70 43 74 78 2c 20 69 56 61 6c 2c  te3*)pCtx, iVal,
a700: 20 70 70 56 61 6c 29 3b 0a 7d 0a 73 74 61 74 69   ppVal);.}.stati
a710: 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 50 72 65  c int sessionPre
a720: 75 70 64 61 74 65 4e 65 77 28 76 6f 69 64 20 2a  updateNew(void *
a730: 70 43 74 78 2c 20 69 6e 74 20 69 56 61 6c 2c 20  pCtx, int iVal, 
a740: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
a750: 70 70 56 61 6c 29 7b 0a 20 20 72 65 74 75 72 6e  ppVal){.  return
a760: 20 73 71 6c 69 74 65 33 5f 70 72 65 75 70 64 61   sqlite3_preupda
a770: 74 65 5f 6e 65 77 28 28 73 71 6c 69 74 65 33 2a  te_new((sqlite3*
a780: 29 70 43 74 78 2c 20 69 56 61 6c 2c 20 70 70 56  )pCtx, iVal, ppV
a790: 61 6c 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e  al);.}.static in
a7a0: 74 20 73 65 73 73 69 6f 6e 50 72 65 75 70 64 61  t sessionPreupda
a7b0: 74 65 43 6f 75 6e 74 28 76 6f 69 64 20 2a 70 43  teCount(void *pC
a7c0: 74 78 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 71  tx){.  return sq
a7d0: 6c 69 74 65 33 5f 70 72 65 75 70 64 61 74 65 5f  lite3_preupdate_
a7e0: 63 6f 75 6e 74 28 28 73 71 6c 69 74 65 33 2a 29  count((sqlite3*)
a7f0: 70 43 74 78 29 3b 0a 7d 0a 73 74 61 74 69 63 20  pCtx);.}.static 
a800: 69 6e 74 20 73 65 73 73 69 6f 6e 50 72 65 75 70  int sessionPreup
a810: 64 61 74 65 44 65 70 74 68 28 76 6f 69 64 20 2a  dateDepth(void *
a820: 70 43 74 78 29 7b 0a 20 20 72 65 74 75 72 6e 20  pCtx){.  return 
a830: 73 71 6c 69 74 65 33 5f 70 72 65 75 70 64 61 74  sqlite3_preupdat
a840: 65 5f 64 65 70 74 68 28 28 73 71 6c 69 74 65 33  e_depth((sqlite3
a850: 2a 29 70 43 74 78 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  *)pCtx);.}../*.*
a860: 2a 20 49 6e 73 74 61 6c 6c 20 74 68 65 20 70 72  * Install the pr
a870: 65 2d 75 70 64 61 74 65 20 68 6f 6f 6b 73 20 6f  e-update hooks o
a880: 6e 20 74 68 65 20 73 65 73 73 69 6f 6e 20 6f 62  n the session ob
a890: 6a 65 63 74 20 70 61 73 73 65 64 20 61 73 20 74  ject passed as t
a8a0: 68 65 20 6f 6e 6c 79 0a 2a 2a 20 61 72 67 75 6d  he only.** argum
a8b0: 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ent..*/.static v
a8c0: 6f 69 64 20 73 65 73 73 69 6f 6e 50 72 65 75 70  oid sessionPreup
a8d0: 64 61 74 65 48 6f 6f 6b 73 28 0a 20 20 73 71 6c  dateHooks(.  sql
a8e0: 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53  ite3_session *pS
a8f0: 65 73 73 69 6f 6e 0a 29 7b 0a 20 20 70 53 65 73  ession.){.  pSes
a900: 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 70 43 74 78 20  sion->hook.pCtx 
a910: 3d 20 28 76 6f 69 64 2a 29 70 53 65 73 73 69 6f  = (void*)pSessio
a920: 6e 2d 3e 64 62 3b 0a 20 20 70 53 65 73 73 69 6f  n->db;.  pSessio
a930: 6e 2d 3e 68 6f 6f 6b 2e 78 4f 6c 64 20 3d 20 73  n->hook.xOld = s
a940: 65 73 73 69 6f 6e 50 72 65 75 70 64 61 74 65 4f  essionPreupdateO
a950: 6c 64 3b 0a 20 20 70 53 65 73 73 69 6f 6e 2d 3e  ld;.  pSession->
a960: 68 6f 6f 6b 2e 78 4e 65 77 20 3d 20 73 65 73 73  hook.xNew = sess
a970: 69 6f 6e 50 72 65 75 70 64 61 74 65 4e 65 77 3b  ionPreupdateNew;
a980: 0a 20 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f  .  pSession->hoo
a990: 6b 2e 78 43 6f 75 6e 74 20 3d 20 73 65 73 73 69  k.xCount = sessi
a9a0: 6f 6e 50 72 65 75 70 64 61 74 65 43 6f 75 6e 74  onPreupdateCount
a9b0: 3b 0a 20 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f  ;.  pSession->ho
a9c0: 6f 6b 2e 78 44 65 70 74 68 20 3d 20 73 65 73 73  ok.xDepth = sess
a9d0: 69 6f 6e 50 72 65 75 70 64 61 74 65 44 65 70 74  ionPreupdateDept
a9e0: 68 3b 0a 7d 0a 0a 74 79 70 65 64 65 66 20 73 74  h;.}..typedef st
a9f0: 72 75 63 74 20 53 65 73 73 69 6f 6e 44 69 66 66  ruct SessionDiff
aa00: 43 74 78 20 53 65 73 73 69 6f 6e 44 69 66 66 43  Ctx SessionDiffC
aa10: 74 78 3b 0a 73 74 72 75 63 74 20 53 65 73 73 69  tx;.struct Sessi
aa20: 6f 6e 44 69 66 66 43 74 78 20 7b 0a 20 20 73 71  onDiffCtx {.  sq
aa30: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
aa40: 74 3b 0a 20 20 69 6e 74 20 6e 4f 6c 64 4f 66 66  t;.  int nOldOff
aa50: 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20  ;.};../*.** The 
aa60: 64 69 66 66 20 68 6f 6f 6b 20 69 6d 70 6c 65 6d  diff hook implem
aa70: 65 6e 74 61 74 69 6f 6e 73 2e 0a 2a 2f 0a 73 74  entations..*/.st
aa80: 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e  atic int session
aa90: 44 69 66 66 4f 6c 64 28 76 6f 69 64 20 2a 70 43  DiffOld(void *pC
aaa0: 74 78 2c 20 69 6e 74 20 69 56 61 6c 2c 20 73 71  tx, int iVal, sq
aab0: 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 70 70  lite3_value **pp
aac0: 56 61 6c 29 7b 0a 20 20 53 65 73 73 69 6f 6e 44  Val){.  SessionD
aad0: 69 66 66 43 74 78 20 2a 70 20 3d 20 28 53 65 73  iffCtx *p = (Ses
aae0: 73 69 6f 6e 44 69 66 66 43 74 78 2a 29 70 43 74  sionDiffCtx*)pCt
aaf0: 78 3b 0a 20 20 2a 70 70 56 61 6c 20 3d 20 73 71  x;.  *ppVal = sq
ab00: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c  lite3_column_val
ab10: 75 65 28 70 2d 3e 70 53 74 6d 74 2c 20 69 56 61  ue(p->pStmt, iVa
ab20: 6c 2b 70 2d 3e 6e 4f 6c 64 4f 66 66 29 3b 0a 20  l+p->nOldOff);. 
ab30: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
ab40: 4b 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20  K;.}.static int 
ab50: 73 65 73 73 69 6f 6e 44 69 66 66 4e 65 77 28 76  sessionDiffNew(v
ab60: 6f 69 64 20 2a 70 43 74 78 2c 20 69 6e 74 20 69  oid *pCtx, int i
ab70: 56 61 6c 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c  Val, sqlite3_val
ab80: 75 65 20 2a 2a 70 70 56 61 6c 29 7b 0a 20 20 53  ue **ppVal){.  S
ab90: 65 73 73 69 6f 6e 44 69 66 66 43 74 78 20 2a 70  essionDiffCtx *p
aba0: 20 3d 20 28 53 65 73 73 69 6f 6e 44 69 66 66 43   = (SessionDiffC
abb0: 74 78 2a 29 70 43 74 78 3b 0a 20 20 2a 70 70 56  tx*)pCtx;.  *ppV
abc0: 61 6c 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c  al = sqlite3_col
abd0: 75 6d 6e 5f 76 61 6c 75 65 28 70 2d 3e 70 53 74  umn_value(p->pSt
abe0: 6d 74 2c 20 69 56 61 6c 29 3b 0a 20 20 20 72 65  mt, iVal);.   re
abf0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
ac00: 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73  }.static int ses
ac10: 73 69 6f 6e 44 69 66 66 43 6f 75 6e 74 28 76 6f  sionDiffCount(vo
ac20: 69 64 20 2a 70 43 74 78 29 7b 0a 20 20 53 65 73  id *pCtx){.  Ses
ac30: 73 69 6f 6e 44 69 66 66 43 74 78 20 2a 70 20 3d  sionDiffCtx *p =
ac40: 20 28 53 65 73 73 69 6f 6e 44 69 66 66 43 74 78   (SessionDiffCtx
ac50: 2a 29 70 43 74 78 3b 0a 20 20 72 65 74 75 72 6e  *)pCtx;.  return
ac60: 20 70 2d 3e 6e 4f 6c 64 4f 66 66 20 3f 20 70 2d   p->nOldOff ? p-
ac70: 3e 6e 4f 6c 64 4f 66 66 20 3a 20 73 71 6c 69 74  >nOldOff : sqlit
ac80: 65 33 5f 63 6f 6c 75 6d 6e 5f 63 6f 75 6e 74 28  e3_column_count(
ac90: 70 2d 3e 70 53 74 6d 74 29 3b 0a 7d 0a 73 74 61  p->pStmt);.}.sta
aca0: 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 44  tic int sessionD
acb0: 69 66 66 44 65 70 74 68 28 76 6f 69 64 20 2a 70  iffDepth(void *p
acc0: 43 74 78 29 7b 0a 20 20 72 65 74 75 72 6e 20 30  Ctx){.  return 0
acd0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 73 74 61  ;.}../*.** Insta
ace0: 6c 6c 20 74 68 65 20 64 69 66 66 20 68 6f 6f 6b  ll the diff hook
acf0: 73 20 6f 6e 20 74 68 65 20 73 65 73 73 69 6f 6e  s on the session
ad00: 20 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20 61   object passed a
ad10: 73 20 74 68 65 20 6f 6e 6c 79 0a 2a 2a 20 61 72  s the only.** ar
ad20: 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69  gument..*/.stati
ad30: 63 20 76 6f 69 64 20 73 65 73 73 69 6f 6e 44 69  c void sessionDi
ad40: 66 66 48 6f 6f 6b 73 28 0a 20 20 73 71 6c 69 74  ffHooks(.  sqlit
ad50: 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73  e3_session *pSes
ad60: 73 69 6f 6e 2c 0a 20 20 53 65 73 73 69 6f 6e 44  sion,.  SessionD
ad70: 69 66 66 43 74 78 20 2a 70 44 69 66 66 43 74 78  iffCtx *pDiffCtx
ad80: 0a 29 7b 0a 20 20 70 53 65 73 73 69 6f 6e 2d 3e  .){.  pSession->
ad90: 68 6f 6f 6b 2e 70 43 74 78 20 3d 20 28 76 6f 69  hook.pCtx = (voi
ada0: 64 2a 29 70 44 69 66 66 43 74 78 3b 0a 20 20 70  d*)pDiffCtx;.  p
adb0: 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 4f  Session->hook.xO
adc0: 6c 64 20 3d 20 73 65 73 73 69 6f 6e 44 69 66 66  ld = sessionDiff
add0: 4f 6c 64 3b 0a 20 20 70 53 65 73 73 69 6f 6e 2d  Old;.  pSession-
ade0: 3e 68 6f 6f 6b 2e 78 4e 65 77 20 3d 20 73 65 73  >hook.xNew = ses
adf0: 73 69 6f 6e 44 69 66 66 4e 65 77 3b 0a 20 20 70  sionDiffNew;.  p
ae00: 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 43  Session->hook.xC
ae10: 6f 75 6e 74 20 3d 20 73 65 73 73 69 6f 6e 44 69  ount = sessionDi
ae20: 66 66 43 6f 75 6e 74 3b 0a 20 20 70 53 65 73 73  ffCount;.  pSess
ae30: 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 44 65 70 74 68  ion->hook.xDepth
ae40: 20 3d 20 73 65 73 73 69 6f 6e 44 69 66 66 44 65   = sessionDiffDe
ae50: 70 74 68 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63  pth;.}..static c
ae60: 68 61 72 20 2a 73 65 73 73 69 6f 6e 45 78 70 72  har *sessionExpr
ae70: 43 6f 6d 70 61 72 65 50 4b 28 0a 20 20 69 6e 74  ComparePK(.  int
ae80: 20 6e 43 6f 6c 2c 0a 20 20 63 6f 6e 73 74 20 63   nCol,.  const c
ae90: 68 61 72 20 2a 7a 44 62 31 2c 20 63 6f 6e 73 74  har *zDb1, const
aea0: 20 63 68 61 72 20 2a 7a 44 62 32 2c 20 0a 20 20   char *zDb2, .  
aeb0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 62  const char *zTab
aec0: 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ,.  const char *
aed0: 2a 61 7a 43 6f 6c 2c 20 75 38 20 2a 61 62 50 4b  *azCol, u8 *abPK
aee0: 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63  .){.  int i;.  c
aef0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 65 70 20  onst char *zSep 
af00: 3d 20 22 22 3b 0a 20 20 63 68 61 72 20 2a 7a 52  = "";.  char *zR
af10: 65 74 20 3d 20 30 3b 0a 0a 20 20 66 6f 72 28 69  et = 0;..  for(i
af20: 3d 30 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29  =0; i<nCol; i++)
af30: 7b 0a 20 20 20 20 69 66 28 20 61 62 50 4b 5b 69  {.    if( abPK[i
af40: 5d 20 29 7b 0a 20 20 20 20 20 20 7a 52 65 74 20  ] ){.      zRet 
af50: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
af60: 66 28 22 25 7a 25 73 5c 22 25 77 5c 22 2e 5c 22  f("%z%s\"%w\".\"
af70: 25 77 5c 22 2e 5c 22 25 77 5c 22 3d 5c 22 25 77  %w\".\"%w\"=\"%w
af80: 5c 22 2e 5c 22 25 77 5c 22 2e 5c 22 25 77 5c 22  \".\"%w\".\"%w\"
af90: 22 2c 0a 20 20 20 20 20 20 20 20 20 20 7a 52 65  ",.          zRe
afa0: 74 2c 20 7a 53 65 70 2c 20 7a 44 62 31 2c 20 7a  t, zSep, zDb1, z
afb0: 54 61 62 2c 20 61 7a 43 6f 6c 5b 69 5d 2c 20 7a  Tab, azCol[i], z
afc0: 44 62 32 2c 20 7a 54 61 62 2c 20 61 7a 43 6f 6c  Db2, zTab, azCol
afd0: 5b 69 5d 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  [i].      );.   
afe0: 20 20 20 7a 53 65 70 20 3d 20 22 20 41 4e 44 20     zSep = " AND 
aff0: 22 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 52 65  ";.      if( zRe
b000: 74 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20  t==0 ) break;.  
b010: 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
b020: 6e 20 7a 52 65 74 3b 0a 7d 0a 0a 73 74 61 74 69  n zRet;.}..stati
b030: 63 20 63 68 61 72 20 2a 73 65 73 73 69 6f 6e 45  c char *sessionE
b040: 78 70 72 43 6f 6d 70 61 72 65 4f 74 68 65 72 28  xprCompareOther(
b050: 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c 0a 20 20 63  .  int nCol,.  c
b060: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62 31 2c  onst char *zDb1,
b070: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62   const char *zDb
b080: 32 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  2, .  const char
b090: 20 2a 7a 54 61 62 2c 0a 20 20 63 6f 6e 73 74 20   *zTab,.  const 
b0a0: 63 68 61 72 20 2a 2a 61 7a 43 6f 6c 2c 20 75 38  char **azCol, u8
b0b0: 20 2a 61 62 50 4b 0a 29 7b 0a 20 20 69 6e 74 20   *abPK.){.  int 
b0c0: 69 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  i;.  const char 
b0d0: 2a 7a 53 65 70 20 3d 20 22 22 3b 0a 20 20 63 68  *zSep = "";.  ch
b0e0: 61 72 20 2a 7a 52 65 74 20 3d 20 30 3b 0a 20 20  ar *zRet = 0;.  
b0f0: 69 6e 74 20 62 48 61 76 65 20 3d 20 30 3b 0a 0a  int bHave = 0;..
b100: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43 6f    for(i=0; i<nCo
b110: 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  l; i++){.    if(
b120: 20 61 62 50 4b 5b 69 5d 3d 3d 30 20 29 7b 0a 20   abPK[i]==0 ){. 
b130: 20 20 20 20 20 62 48 61 76 65 20 3d 20 31 3b 0a       bHave = 1;.
b140: 20 20 20 20 20 20 7a 52 65 74 20 3d 20 73 71 6c        zRet = sql
b150: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20 20  ite3_mprintf(.  
b160: 20 20 20 20 20 20 20 20 22 25 7a 25 73 5c 22 25          "%z%s\"%
b170: 77 5c 22 2e 5c 22 25 77 5c 22 2e 5c 22 25 77 5c  w\".\"%w\".\"%w\
b180: 22 20 49 53 20 4e 4f 54 20 5c 22 25 77 5c 22 2e  " IS NOT \"%w\".
b190: 5c 22 25 77 5c 22 2e 5c 22 25 77 5c 22 22 2c 0a  \"%w\".\"%w\"",.
b1a0: 20 20 20 20 20 20 20 20 20 20 7a 52 65 74 2c 20            zRet, 
b1b0: 7a 53 65 70 2c 20 7a 44 62 31 2c 20 7a 54 61 62  zSep, zDb1, zTab
b1c0: 2c 20 61 7a 43 6f 6c 5b 69 5d 2c 20 7a 44 62 32  , azCol[i], zDb2
b1d0: 2c 20 7a 54 61 62 2c 20 61 7a 43 6f 6c 5b 69 5d  , zTab, azCol[i]
b1e0: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20  .      );.      
b1f0: 7a 53 65 70 20 3d 20 22 20 4f 52 20 22 3b 0a 20  zSep = " OR ";. 
b200: 20 20 20 20 20 69 66 28 20 7a 52 65 74 3d 3d 30       if( zRet==0
b210: 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a   ) break;.    }.
b220: 20 20 7d 0a 0a 20 20 69 66 28 20 62 48 61 76 65    }..  if( bHave
b230: 3d 3d 30 20 29 7b 0a 20 20 20 20 61 73 73 65 72  ==0 ){.    asser
b240: 74 28 20 7a 52 65 74 3d 3d 30 20 29 3b 0a 20 20  t( zRet==0 );.  
b250: 20 20 7a 52 65 74 20 3d 20 73 71 6c 69 74 65 33    zRet = sqlite3
b260: 5f 6d 70 72 69 6e 74 66 28 22 30 22 29 3b 0a 20  _mprintf("0");. 
b270: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 7a 52 65   }..  return zRe
b280: 74 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61  t;.}..static cha
b290: 72 20 2a 73 65 73 73 69 6f 6e 53 65 6c 65 63 74  r *sessionSelect
b2a0: 46 69 6e 64 4e 65 77 28 0a 20 20 69 6e 74 20 6e  FindNew(.  int n
b2b0: 43 6f 6c 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61  Col,.  const cha
b2c0: 72 20 2a 7a 44 62 31 2c 20 20 20 20 20 20 2f 2a  r *zDb1,      /*
b2d0: 20 50 69 63 6b 20 72 6f 77 73 20 69 6e 20 74 68   Pick rows in th
b2e0: 69 73 20 64 62 20 6f 6e 6c 79 20 2a 2f 0a 20 20  is db only */.  
b2f0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62 32  const char *zDb2
b300: 2c 20 20 20 20 20 20 2f 2a 20 42 75 74 20 6e 6f  ,      /* But no
b310: 74 20 69 6e 20 74 68 69 73 20 6f 6e 65 20 2a 2f  t in this one */
b320: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
b330: 54 62 6c 2c 20 20 20 20 20 20 2f 2a 20 54 61 62  Tbl,      /* Tab
b340: 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f 6e  le name */.  con
b350: 73 74 20 63 68 61 72 20 2a 7a 45 78 70 72 0a 29  st char *zExpr.)
b360: 7b 0a 20 20 63 68 61 72 20 2a 7a 52 65 74 20 3d  {.  char *zRet =
b370: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
b380: 28 0a 20 20 20 20 20 20 22 53 45 4c 45 43 54 20  (.      "SELECT 
b390: 2a 20 46 52 4f 4d 20 5c 22 25 77 5c 22 2e 5c 22  * FROM \"%w\".\"
b3a0: 25 77 5c 22 20 57 48 45 52 45 20 4e 4f 54 20 45  %w\" WHERE NOT E
b3b0: 58 49 53 54 53 20 28 22 0a 20 20 20 20 20 20 22  XISTS (".      "
b3c0: 20 20 53 45 4c 45 43 54 20 31 20 46 52 4f 4d 20    SELECT 1 FROM 
b3d0: 5c 22 25 77 5c 22 2e 5c 22 25 77 5c 22 20 57 48  \"%w\".\"%w\" WH
b3e0: 45 52 45 20 25 73 22 0a 20 20 20 20 20 20 22 29  ERE %s".      ")
b3f0: 22 2c 0a 20 20 20 20 20 20 7a 44 62 31 2c 20 7a  ",.      zDb1, z
b400: 54 62 6c 2c 20 7a 44 62 32 2c 20 7a 54 62 6c 2c  Tbl, zDb2, zTbl,
b410: 20 7a 45 78 70 72 0a 20 20 29 3b 0a 20 20 72 65   zExpr.  );.  re
b420: 74 75 72 6e 20 7a 52 65 74 3b 0a 7d 0a 0a 73 74  turn zRet;.}..st
b430: 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e  atic int session
b440: 44 69 66 66 46 69 6e 64 4e 65 77 28 0a 20 20 69  DiffFindNew(.  i
b450: 6e 74 20 6f 70 2c 0a 20 20 73 71 6c 69 74 65 33  nt op,.  sqlite3
b460: 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69  _session *pSessi
b470: 6f 6e 2c 0a 20 20 53 65 73 73 69 6f 6e 54 61 62  on,.  SessionTab
b480: 6c 65 20 2a 70 54 61 62 2c 0a 20 20 63 6f 6e 73  le *pTab,.  cons
b490: 74 20 63 68 61 72 20 2a 7a 44 62 31 2c 0a 20 20  t char *zDb1,.  
b4a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62 32  const char *zDb2
b4b0: 2c 0a 20 20 63 68 61 72 20 2a 7a 45 78 70 72 0a  ,.  char *zExpr.
b4c0: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
b4d0: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 63 68 61 72 20  LITE_OK;.  char 
b4e0: 2a 7a 53 74 6d 74 20 3d 20 73 65 73 73 69 6f 6e  *zStmt = session
b4f0: 53 65 6c 65 63 74 46 69 6e 64 4e 65 77 28 70 54  SelectFindNew(pT
b500: 61 62 2d 3e 6e 43 6f 6c 2c 20 7a 44 62 31 2c 20  ab->nCol, zDb1, 
b510: 7a 44 62 32 2c 20 70 54 61 62 2d 3e 7a 4e 61 6d  zDb2, pTab->zNam
b520: 65 2c 7a 45 78 70 72 29 3b 0a 0a 20 20 69 66 28  e,zExpr);..  if(
b530: 20 7a 53 74 6d 74 3d 3d 30 20 29 7b 0a 20 20 20   zStmt==0 ){.   
b540: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
b550: 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  EM;.  }else{.   
b560: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
b570: 53 74 6d 74 3b 0a 20 20 20 20 72 63 20 3d 20 73  Stmt;.    rc = s
b580: 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28 70  qlite3_prepare(p
b590: 53 65 73 73 69 6f 6e 2d 3e 64 62 2c 20 7a 53 74  Session->db, zSt
b5a0: 6d 74 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20  mt, -1, &pStmt, 
b5b0: 30 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  0);.    if( rc==
b5c0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
b5d0: 20 20 20 53 65 73 73 69 6f 6e 44 69 66 66 43 74     SessionDiffCt
b5e0: 78 20 2a 70 44 69 66 66 43 74 78 20 3d 20 28 53  x *pDiffCtx = (S
b5f0: 65 73 73 69 6f 6e 44 69 66 66 43 74 78 2a 29 70  essionDiffCtx*)p
b600: 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 70 43  Session->hook.pC
b610: 74 78 3b 0a 20 20 20 20 20 20 70 44 69 66 66 43  tx;.      pDiffC
b620: 74 78 2d 3e 70 53 74 6d 74 20 3d 20 70 53 74 6d  tx->pStmt = pStm
b630: 74 3b 0a 20 20 20 20 20 20 70 44 69 66 66 43 74  t;.      pDiffCt
b640: 78 2d 3e 6e 4f 6c 64 4f 66 66 20 3d 20 30 3b 0a  x->nOldOff = 0;.
b650: 20 20 20 20 20 20 77 68 69 6c 65 28 20 53 51 4c        while( SQL
b660: 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33  ITE_ROW==sqlite3
b670: 5f 73 74 65 70 28 70 53 74 6d 74 29 20 29 7b 0a  _step(pStmt) ){.
b680: 20 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 50          sessionP
b690: 72 65 75 70 64 61 74 65 4f 6e 65 43 68 61 6e 67  reupdateOneChang
b6a0: 65 28 6f 70 2c 20 70 53 65 73 73 69 6f 6e 2c 20  e(op, pSession, 
b6b0: 70 54 61 62 29 3b 0a 20 20 20 20 20 20 7d 0a 20  pTab);.      }. 
b6c0: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
b6d0: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74  3_finalize(pStmt
b6e0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c  );.    }.    sql
b6f0: 69 74 65 33 5f 66 72 65 65 28 7a 53 74 6d 74 29  ite3_free(zStmt)
b700: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
b710: 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  rc;.}..static in
b720: 74 20 73 65 73 73 69 6f 6e 44 69 66 66 46 69 6e  t sessionDiffFin
b730: 64 4d 6f 64 69 66 69 65 64 28 0a 20 20 73 71 6c  dModified(.  sql
b740: 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53  ite3_session *pS
b750: 65 73 73 69 6f 6e 2c 20 0a 20 20 53 65 73 73 69  ession, .  Sessi
b760: 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 0a  onTable *pTab, .
b770: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46    const char *zF
b780: 72 6f 6d 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68  rom, .  const ch
b790: 61 72 20 2a 7a 45 78 70 72 0a 29 7b 0a 20 20 69  ar *zExpr.){.  i
b7a0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
b7b0: 4b 3b 0a 0a 20 20 63 68 61 72 20 2a 7a 45 78 70  K;..  char *zExp
b7c0: 72 32 20 3d 20 73 65 73 73 69 6f 6e 45 78 70 72  r2 = sessionExpr
b7d0: 43 6f 6d 70 61 72 65 4f 74 68 65 72 28 70 54 61  CompareOther(pTa
b7e0: 62 2d 3e 6e 43 6f 6c 2c 0a 20 20 20 20 20 20 70  b->nCol,.      p
b7f0: 53 65 73 73 69 6f 6e 2d 3e 7a 44 62 2c 20 7a 46  Session->zDb, zF
b800: 72 6f 6d 2c 20 70 54 61 62 2d 3e 7a 4e 61 6d 65  rom, pTab->zName
b810: 2c 20 70 54 61 62 2d 3e 61 7a 43 6f 6c 2c 20 70  , pTab->azCol, p
b820: 54 61 62 2d 3e 61 62 50 4b 0a 20 20 29 3b 0a 20  Tab->abPK.  );. 
b830: 20 69 66 28 20 7a 45 78 70 72 32 3d 3d 30 20 29   if( zExpr2==0 )
b840: 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54  {.    rc = SQLIT
b850: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65  E_NOMEM;.  }else
b860: 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 74 6d  {.    char *zStm
b870: 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  t = sqlite3_mpri
b880: 6e 74 66 28 0a 20 20 20 20 20 20 20 20 22 53 45  ntf(.        "SE
b890: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 5c 22 25 77  LECT * FROM \"%w
b8a0: 5c 22 2e 5c 22 25 77 5c 22 2c 20 5c 22 25 77 5c  \".\"%w\", \"%w\
b8b0: 22 2e 5c 22 25 77 5c 22 20 57 48 45 52 45 20 25  ".\"%w\" WHERE %
b8c0: 73 20 41 4e 44 20 28 25 7a 29 22 2c 0a 20 20 20  s AND (%z)",.   
b8d0: 20 20 20 20 20 70 53 65 73 73 69 6f 6e 2d 3e 7a       pSession->z
b8e0: 44 62 2c 20 70 54 61 62 2d 3e 7a 4e 61 6d 65 2c  Db, pTab->zName,
b8f0: 20 7a 46 72 6f 6d 2c 20 70 54 61 62 2d 3e 7a 4e   zFrom, pTab->zN
b900: 61 6d 65 2c 20 7a 45 78 70 72 2c 20 7a 45 78 70  ame, zExpr, zExp
b910: 72 32 0a 20 20 20 20 29 3b 0a 20 20 20 20 69 66  r2.    );.    if
b920: 28 20 7a 53 74 6d 74 3d 3d 30 20 29 7b 0a 20 20  ( zStmt==0 ){.  
b930: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
b940: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c 73 65  NOMEM;.    }else
b950: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
b960: 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 20 20 20  stmt *pStmt;.   
b970: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
b980: 70 72 65 70 61 72 65 28 70 53 65 73 73 69 6f 6e  prepare(pSession
b990: 2d 3e 64 62 2c 20 7a 53 74 6d 74 2c 20 2d 31 2c  ->db, zStmt, -1,
b9a0: 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 0a 20 20   &pStmt, 0);..  
b9b0: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
b9c0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  TE_OK ){.       
b9d0: 20 53 65 73 73 69 6f 6e 44 69 66 66 43 74 78 20   SessionDiffCtx 
b9e0: 2a 70 44 69 66 66 43 74 78 20 3d 20 28 53 65 73  *pDiffCtx = (Ses
b9f0: 73 69 6f 6e 44 69 66 66 43 74 78 2a 29 70 53 65  sionDiffCtx*)pSe
ba00: 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 70 43 74 78  ssion->hook.pCtx
ba10: 3b 0a 20 20 20 20 20 20 20 20 70 44 69 66 66 43  ;.        pDiffC
ba20: 74 78 2d 3e 70 53 74 6d 74 20 3d 20 70 53 74 6d  tx->pStmt = pStm
ba30: 74 3b 0a 20 20 20 20 20 20 20 20 70 44 69 66 66  t;.        pDiff
ba40: 43 74 78 2d 3e 6e 4f 6c 64 4f 66 66 20 3d 20 70  Ctx->nOldOff = p
ba50: 54 61 62 2d 3e 6e 43 6f 6c 3b 0a 20 20 20 20 20  Tab->nCol;.     
ba60: 20 20 20 77 68 69 6c 65 28 20 53 51 4c 49 54 45     while( SQLITE
ba70: 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33 5f 73 74  _ROW==sqlite3_st
ba80: 65 70 28 70 53 74 6d 74 29 20 29 7b 0a 20 20 20  ep(pStmt) ){.   
ba90: 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 50 72         sessionPr
baa0: 65 75 70 64 61 74 65 4f 6e 65 43 68 61 6e 67 65  eupdateOneChange
bab0: 28 53 51 4c 49 54 45 5f 55 50 44 41 54 45 2c 20  (SQLITE_UPDATE, 
bac0: 70 53 65 73 73 69 6f 6e 2c 20 70 54 61 62 29 3b  pSession, pTab);
bad0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
bae0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
baf0: 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b  finalize(pStmt);
bb00: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73  .      }.      s
bb10: 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53 74 6d  qlite3_free(zStm
bb20: 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  t);.    }.  }.. 
bb30: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69   return rc;.}..i
bb40: 6e 74 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f  nt sqlite3sessio
bb50: 6e 5f 64 69 66 66 28 0a 20 20 73 71 6c 69 74 65  n_diff(.  sqlite
bb60: 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73  3_session *pSess
bb70: 69 6f 6e 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61  ion,.  const cha
bb80: 72 20 2a 7a 46 72 6f 6d 2c 0a 20 20 63 6f 6e 73  r *zFrom,.  cons
bb90: 74 20 63 68 61 72 20 2a 7a 54 62 6c 2c 0a 20 20  t char *zTbl,.  
bba0: 63 68 61 72 20 2a 2a 70 7a 45 72 72 4d 73 67 0a  char **pzErrMsg.
bbb0: 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  ){.  const char 
bbc0: 2a 7a 44 62 20 3d 20 70 53 65 73 73 69 6f 6e 2d  *zDb = pSession-
bbd0: 3e 7a 44 62 3b 0a 20 20 69 6e 74 20 72 63 20 3d  >zDb;.  int rc =
bbe0: 20 70 53 65 73 73 69 6f 6e 2d 3e 72 63 3b 0a 20   pSession->rc;. 
bbf0: 20 53 65 73 73 69 6f 6e 44 69 66 66 43 74 78 20   SessionDiffCtx 
bc00: 64 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 64 2c  d;..  memset(&d,
bc10: 20 30 2c 20 73 69 7a 65 6f 66 28 64 29 29 3b 0a   0, sizeof(d));.
bc20: 20 20 73 65 73 73 69 6f 6e 44 69 66 66 48 6f 6f    sessionDiffHoo
bc30: 6b 73 28 70 53 65 73 73 69 6f 6e 2c 20 26 64 29  ks(pSession, &d)
bc40: 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74  ;..  sqlite3_mut
bc50: 65 78 5f 65 6e 74 65 72 28 73 71 6c 69 74 65 33  ex_enter(sqlite3
bc60: 5f 64 62 5f 6d 75 74 65 78 28 70 53 65 73 73 69  _db_mutex(pSessi
bc70: 6f 6e 2d 3e 64 62 29 29 3b 0a 20 20 69 66 28 20  on->db));.  if( 
bc80: 70 7a 45 72 72 4d 73 67 20 29 20 2a 70 7a 45 72  pzErrMsg ) *pzEr
bc90: 72 4d 73 67 20 3d 20 30 3b 0a 20 20 69 66 28 20  rMsg = 0;.  if( 
bca0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
bcb0: 0a 20 20 20 20 63 68 61 72 20 2a 7a 45 78 70 72  .    char *zExpr
bcc0: 20 3d 20 30 3b 0a 20 20 20 20 73 71 6c 69 74 65   = 0;.    sqlite
bcd0: 33 20 2a 64 62 20 3d 20 70 53 65 73 73 69 6f 6e  3 *db = pSession
bce0: 2d 3e 64 62 3b 0a 20 20 20 20 53 65 73 73 69 6f  ->db;.    Sessio
bcf0: 6e 54 61 62 6c 65 20 2a 70 54 6f 3b 20 20 20 20  nTable *pTo;    
bd00: 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62 6c 65          /* Table
bd10: 20 7a 54 62 6c 20 2a 2f 0a 0a 20 20 20 20 2f 2a   zTbl */..    /*
bd20: 20 4c 6f 63 61 74 65 20 61 6e 64 20 69 66 20 6e   Locate and if n
bd30: 65 63 65 73 73 61 72 79 20 69 6e 69 74 69 61 6c  ecessary initial
bd40: 69 7a 65 20 74 68 65 20 74 61 72 67 65 74 20 74  ize the target t
bd50: 61 62 6c 65 20 6f 62 6a 65 63 74 20 2a 2f 0a 20  able object */. 
bd60: 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 46     rc = sessionF
bd70: 69 6e 64 54 61 62 6c 65 28 70 53 65 73 73 69 6f  indTable(pSessio
bd80: 6e 2c 20 7a 54 62 6c 2c 20 26 70 54 6f 29 3b 0a  n, zTbl, &pTo);.
bd90: 20 20 20 20 69 66 28 20 70 54 6f 3d 3d 30 20 29      if( pTo==0 )
bda0: 20 67 6f 74 6f 20 64 69 66 66 5f 6f 75 74 3b 0a   goto diff_out;.
bdb0: 20 20 20 20 69 66 28 20 73 65 73 73 69 6f 6e 49      if( sessionI
bdc0: 6e 69 74 54 61 62 6c 65 28 70 53 65 73 73 69 6f  nitTable(pSessio
bdd0: 6e 2c 20 70 54 6f 29 20 29 7b 0a 20 20 20 20 20  n, pTo) ){.     
bde0: 20 72 63 20 3d 20 70 53 65 73 73 69 6f 6e 2d 3e   rc = pSession->
bdf0: 72 63 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 64  rc;.      goto d
be00: 69 66 66 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 0a  iff_out;.    }..
be10: 20 20 20 20 2f 2a 20 43 68 65 63 6b 20 74 68 65      /* Check the
be20: 20 74 61 62 6c 65 20 73 63 68 65 6d 61 73 20 6d   table schemas m
be30: 61 74 63 68 20 2a 2f 0a 20 20 20 20 69 66 28 20  atch */.    if( 
be40: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
be50: 0a 20 20 20 20 20 20 69 6e 74 20 62 48 61 73 50  .      int bHasP
be60: 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 6e 74  k = 0;.      int
be70: 20 62 4d 69 73 6d 61 74 63 68 20 3d 20 30 3b 0a   bMismatch = 0;.
be80: 20 20 20 20 20 20 69 6e 74 20 6e 43 6f 6c 3b 20        int nCol; 
be90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bea0: 20 20 2f 2a 20 43 6f 6c 75 6d 6e 73 20 69 6e 20    /* Columns in 
beb0: 7a 46 72 6f 6d 2e 7a 54 62 6c 20 2a 2f 0a 20 20  zFrom.zTbl */.  
bec0: 20 20 20 20 75 38 20 2a 61 62 50 4b 3b 0a 20 20      u8 *abPK;.  
bed0: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
bee0: 2a 61 7a 43 6f 6c 20 3d 20 30 3b 0a 20 20 20 20  *azCol = 0;.    
bef0: 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 54 61    rc = sessionTa
bf00: 62 6c 65 49 6e 66 6f 28 64 62 2c 20 7a 46 72 6f  bleInfo(db, zFro
bf10: 6d 2c 20 7a 54 62 6c 2c 20 26 6e 43 6f 6c 2c 20  m, zTbl, &nCol, 
bf20: 30 2c 20 26 61 7a 43 6f 6c 2c 20 26 61 62 50 4b  0, &azCol, &abPK
bf30: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  );.      if( rc=
bf40: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
bf50: 20 20 20 20 20 20 69 66 28 20 70 54 6f 2d 3e 6e        if( pTo->n
bf60: 43 6f 6c 21 3d 6e 43 6f 6c 20 29 7b 0a 20 20 20  Col!=nCol ){.   
bf70: 20 20 20 20 20 20 20 62 4d 69 73 6d 61 74 63 68         bMismatch
bf80: 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 65   = 1;.        }e
bf90: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 69  lse{.          i
bfa0: 6e 74 20 69 3b 0a 20 20 20 20 20 20 20 20 20 20  nt i;.          
bfb0: 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c 3b  for(i=0; i<nCol;
bfc0: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20   i++){.         
bfd0: 20 20 20 69 66 28 20 70 54 6f 2d 3e 61 62 50 4b     if( pTo->abPK
bfe0: 5b 69 5d 21 3d 61 62 50 4b 5b 69 5d 20 29 20 62  [i]!=abPK[i] ) b
bff0: 4d 69 73 6d 61 74 63 68 20 3d 20 31 3b 0a 20 20  Mismatch = 1;.  
c000: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 73 71            if( sq
c010: 6c 69 74 65 33 5f 73 74 72 69 63 6d 70 28 61 7a  lite3_stricmp(az
c020: 43 6f 6c 5b 69 5d 2c 20 70 54 6f 2d 3e 61 7a 43  Col[i], pTo->azC
c030: 6f 6c 5b 69 5d 29 20 29 20 62 4d 69 73 6d 61 74  ol[i]) ) bMismat
c040: 63 68 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20  ch = 1;.        
c050: 20 20 20 20 69 66 28 20 61 62 50 4b 5b 69 5d 20      if( abPK[i] 
c060: 29 20 62 48 61 73 50 6b 20 3d 20 31 3b 0a 20 20  ) bHasPk = 1;.  
c070: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
c080: 20 20 7d 0a 0a 20 20 20 20 20 20 7d 0a 20 20 20    }..      }.   
c090: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
c0a0: 28 63 68 61 72 2a 29 61 7a 43 6f 6c 29 3b 0a 20  (char*)azCol);. 
c0b0: 20 20 20 20 20 69 66 28 20 62 4d 69 73 6d 61 74       if( bMismat
c0c0: 63 68 20 29 7b 0a 20 20 20 20 20 20 20 20 2a 70  ch ){.        *p
c0d0: 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c 69 74 65  zErrMsg = sqlite
c0e0: 33 5f 6d 70 72 69 6e 74 66 28 22 74 61 62 6c 65  3_mprintf("table
c0f0: 20 73 63 68 65 6d 61 73 20 64 6f 20 6e 6f 74 20   schemas do not 
c100: 6d 61 74 63 68 22 29 3b 0a 20 20 20 20 20 20 20  match");.       
c110: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 53 43 48   rc = SQLITE_SCH
c120: 45 4d 41 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  EMA;.      }.   
c130: 20 20 20 69 66 28 20 62 48 61 73 50 6b 3d 3d 30     if( bHasPk==0
c140: 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 49   ){.        /* I
c150: 67 6e 6f 72 65 20 74 61 62 6c 65 73 20 77 69 74  gnore tables wit
c160: 68 20 6e 6f 20 70 72 69 6d 61 72 79 20 6b 65 79  h no primary key
c170: 73 20 2a 2f 0a 20 20 20 20 20 20 20 20 67 6f 74  s */.        got
c180: 6f 20 64 69 66 66 5f 6f 75 74 3b 0a 20 20 20 20  o diff_out;.    
c190: 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69    }.    }..    i
c1a0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
c1b0: 20 29 7b 0a 20 20 20 20 20 20 7a 45 78 70 72 20   ){.      zExpr 
c1c0: 3d 20 73 65 73 73 69 6f 6e 45 78 70 72 43 6f 6d  = sessionExprCom
c1d0: 70 61 72 65 50 4b 28 70 54 6f 2d 3e 6e 43 6f 6c  parePK(pTo->nCol
c1e0: 2c 20 0a 20 20 20 20 20 20 20 20 20 20 7a 44 62  , .          zDb
c1f0: 2c 20 7a 46 72 6f 6d 2c 20 70 54 6f 2d 3e 7a 4e  , zFrom, pTo->zN
c200: 61 6d 65 2c 20 70 54 6f 2d 3e 61 7a 43 6f 6c 2c  ame, pTo->azCol,
c210: 20 70 54 6f 2d 3e 61 62 50 4b 0a 20 20 20 20 20   pTo->abPK.     
c220: 20 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f   );.    }..    /
c230: 2a 20 46 69 6e 64 20 6e 65 77 20 72 6f 77 73 20  * Find new rows 
c240: 2a 2f 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  */.    if( rc==S
c250: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
c260: 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 44 69    rc = sessionDi
c270: 66 66 46 69 6e 64 4e 65 77 28 53 51 4c 49 54 45  ffFindNew(SQLITE
c280: 5f 49 4e 53 45 52 54 2c 20 70 53 65 73 73 69 6f  _INSERT, pSessio
c290: 6e 2c 20 70 54 6f 2c 20 7a 44 62 2c 20 7a 46 72  n, pTo, zDb, zFr
c2a0: 6f 6d 2c 20 7a 45 78 70 72 29 3b 0a 20 20 20 20  om, zExpr);.    
c2b0: 7d 0a 0a 20 20 20 20 2f 2a 20 46 69 6e 64 20 6f  }..    /* Find o
c2c0: 6c 64 20 72 6f 77 73 20 2a 2f 0a 20 20 20 20 69  ld rows */.    i
c2d0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
c2e0: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73   ){.      rc = s
c2f0: 65 73 73 69 6f 6e 44 69 66 66 46 69 6e 64 4e 65  essionDiffFindNe
c300: 77 28 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 2c  w(SQLITE_DELETE,
c310: 20 70 53 65 73 73 69 6f 6e 2c 20 70 54 6f 2c 20   pSession, pTo, 
c320: 7a 46 72 6f 6d 2c 20 7a 44 62 2c 20 7a 45 78 70  zFrom, zDb, zExp
c330: 72 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  r);.    }..    /
c340: 2a 20 46 69 6e 64 20 6d 6f 64 69 66 69 65 64 20  * Find modified 
c350: 72 6f 77 73 20 2a 2f 0a 20 20 20 20 69 66 28 20  rows */.    if( 
c360: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
c370: 0a 20 20 20 20 20 20 72 63 20 3d 20 73 65 73 73  .      rc = sess
c380: 69 6f 6e 44 69 66 66 46 69 6e 64 4d 6f 64 69 66  ionDiffFindModif
c390: 69 65 64 28 70 53 65 73 73 69 6f 6e 2c 20 70 54  ied(pSession, pT
c3a0: 6f 2c 20 7a 46 72 6f 6d 2c 20 7a 45 78 70 72 29  o, zFrom, zExpr)
c3b0: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 71 6c  ;.    }..    sql
c3c0: 69 74 65 33 5f 66 72 65 65 28 7a 45 78 70 72 29  ite3_free(zExpr)
c3d0: 3b 0a 20 20 7d 0a 0a 20 64 69 66 66 5f 6f 75 74  ;.  }.. diff_out
c3e0: 3a 0a 20 20 73 65 73 73 69 6f 6e 50 72 65 75 70  :.  sessionPreup
c3f0: 64 61 74 65 48 6f 6f 6b 73 28 70 53 65 73 73 69  dateHooks(pSessi
c400: 6f 6e 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 6d  on);.  sqlite3_m
c410: 75 74 65 78 5f 6c 65 61 76 65 28 73 71 6c 69 74  utex_leave(sqlit
c420: 65 33 5f 64 62 5f 6d 75 74 65 78 28 70 53 65 73  e3_db_mutex(pSes
c430: 73 69 6f 6e 2d 3e 64 62 29 29 3b 0a 20 20 72 65  sion->db));.  re
c440: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
c450: 2a 20 43 72 65 61 74 65 20 61 20 73 65 73 73 69  * Create a sessi
c460: 6f 6e 20 6f 62 6a 65 63 74 2e 20 54 68 69 73 20  on object. This 
c470: 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 77  session object w
c480: 69 6c 6c 20 72 65 63 6f 72 64 20 63 68 61 6e 67  ill record chang
c490: 65 73 20 74 6f 0a 2a 2a 20 64 61 74 61 62 61 73  es to.** databas
c4a0: 65 20 7a 44 62 20 61 74 74 61 63 68 65 64 20 74  e zDb attached t
c4b0: 6f 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 64 62 2e  o connection db.
c4c0: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 73  .*/.int sqlite3s
c4d0: 65 73 73 69 6f 6e 5f 63 72 65 61 74 65 28 0a 20  ession_create(. 
c4e0: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20   sqlite3 *db,   
c4f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c500: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e   /* Database han
c510: 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  dle */.  const c
c520: 68 61 72 20 2a 7a 44 62 2c 20 20 20 20 20 20 20  har *zDb,       
c530: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65           /* Name
c540: 20 6f 66 20 64 62 20 28 65 2e 67 2e 20 22 6d 61   of db (e.g. "ma
c550: 69 6e 22 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65  in") */.  sqlite
c560: 33 5f 73 65 73 73 69 6f 6e 20 2a 2a 70 70 53 65  3_session **ppSe
c570: 73 73 69 6f 6e 20 20 20 20 20 2f 2a 20 4f 55 54  ssion     /* OUT
c580: 3a 20 4e 65 77 20 73 65 73 73 69 6f 6e 20 6f 62  : New session ob
c590: 6a 65 63 74 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c  ject */.){.  sql
c5a0: 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 4e  ite3_session *pN
c5b0: 65 77 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ew;          /* 
c5c0: 4e 65 77 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20  Newly allocated 
c5d0: 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 2a  session object *
c5e0: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73 65 73 73  /.  sqlite3_sess
c5f0: 69 6f 6e 20 2a 70 4f 6c 64 3b 20 20 20 20 20 20  ion *pOld;      
c600: 20 20 20 20 2f 2a 20 53 65 73 73 69 6f 6e 20 6f      /* Session o
c610: 62 6a 65 63 74 20 61 6c 72 65 61 64 79 20 61 74  bject already at
c620: 74 61 63 68 65 64 20 74 6f 20 64 62 20 2a 2f 0a  tached to db */.
c630: 20 20 69 6e 74 20 6e 44 62 20 3d 20 73 71 6c 69    int nDb = sqli
c640: 74 65 33 53 74 72 6c 65 6e 33 30 28 7a 44 62 29  te3Strlen30(zDb)
c650: 3b 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66 20 7a  ; /* Length of z
c660: 44 62 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 0a  Db in bytes */..
c670: 20 20 2f 2a 20 5a 65 72 6f 20 74 68 65 20 6f 75    /* Zero the ou
c680: 74 70 75 74 20 76 61 6c 75 65 20 69 6e 20 63 61  tput value in ca
c690: 73 65 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  se an error occu
c6a0: 72 73 2e 20 2a 2f 0a 20 20 2a 70 70 53 65 73 73  rs. */.  *ppSess
c6b0: 69 6f 6e 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 41  ion = 0;..  /* A
c6c0: 6c 6c 6f 63 61 74 65 20 61 6e 64 20 70 6f 70 75  llocate and popu
c6d0: 6c 61 74 65 20 74 68 65 20 6e 65 77 20 73 65 73  late the new ses
c6e0: 73 69 6f 6e 20 6f 62 6a 65 63 74 2e 20 2a 2f 0a  sion object. */.
c6f0: 20 20 70 4e 65 77 20 3d 20 28 73 71 6c 69 74 65    pNew = (sqlite
c700: 33 5f 73 65 73 73 69 6f 6e 20 2a 29 73 71 6c 69  3_session *)sqli
c710: 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
c720: 66 28 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f  f(sqlite3_sessio
c730: 6e 29 20 2b 20 6e 44 62 20 2b 20 31 29 3b 0a 20  n) + nDb + 1);. 
c740: 20 69 66 28 20 21 70 4e 65 77 20 29 20 72 65 74   if( !pNew ) ret
c750: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
c760: 3b 0a 20 20 6d 65 6d 73 65 74 28 70 4e 65 77 2c  ;.  memset(pNew,
c770: 20 30 2c 20 73 69 7a 65 6f 66 28 73 71 6c 69 74   0, sizeof(sqlit
c780: 65 33 5f 73 65 73 73 69 6f 6e 29 29 3b 0a 20 20  e3_session));.  
c790: 70 4e 65 77 2d 3e 64 62 20 3d 20 64 62 3b 0a 20  pNew->db = db;. 
c7a0: 20 70 4e 65 77 2d 3e 7a 44 62 20 3d 20 28 63 68   pNew->zDb = (ch
c7b0: 61 72 20 2a 29 26 70 4e 65 77 5b 31 5d 3b 0a 20  ar *)&pNew[1];. 
c7c0: 20 70 4e 65 77 2d 3e 62 45 6e 61 62 6c 65 20 3d   pNew->bEnable =
c7d0: 20 31 3b 0a 20 20 6d 65 6d 63 70 79 28 70 4e 65   1;.  memcpy(pNe
c7e0: 77 2d 3e 7a 44 62 2c 20 7a 44 62 2c 20 6e 44 62  w->zDb, zDb, nDb
c7f0: 2b 31 29 3b 0a 20 20 73 65 73 73 69 6f 6e 50 72  +1);.  sessionPr
c800: 65 75 70 64 61 74 65 48 6f 6f 6b 73 28 70 4e 65  eupdateHooks(pNe
c810: 77 29 3b 0a 0a 20 20 2f 2a 20 41 64 64 20 74 68  w);..  /* Add th
c820: 65 20 6e 65 77 20 73 65 73 73 69 6f 6e 20 6f 62  e new session ob
c830: 6a 65 63 74 20 74 6f 20 74 68 65 20 6c 69 6e 6b  ject to the link
c840: 65 64 20 6c 69 73 74 20 6f 66 20 73 65 73 73 69  ed list of sessi
c850: 6f 6e 20 6f 62 6a 65 63 74 73 20 0a 20 20 2a 2a  on objects .  **
c860: 20 61 74 74 61 63 68 65 64 20 74 6f 20 64 61 74   attached to dat
c870: 61 62 61 73 65 20 68 61 6e 64 6c 65 20 24 64 62  abase handle $db
c880: 2e 20 44 6f 20 74 68 69 73 20 75 6e 64 65 72 20  . Do this under 
c890: 74 68 65 20 63 6f 76 65 72 20 6f 66 20 74 68 65  the cover of the
c8a0: 20 64 62 0a 20 20 2a 2a 20 68 61 6e 64 6c 65 20   db.  ** handle 
c8b0: 6d 75 74 65 78 2e 20 20 2a 2f 0a 20 20 73 71 6c  mutex.  */.  sql
c8c0: 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72  ite3_mutex_enter
c8d0: 28 73 71 6c 69 74 65 33 5f 64 62 5f 6d 75 74 65  (sqlite3_db_mute
c8e0: 78 28 64 62 29 29 3b 0a 20 20 70 4f 6c 64 20 3d  x(db));.  pOld =
c8f0: 20 28 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f   (sqlite3_sessio
c900: 6e 2a 29 73 71 6c 69 74 65 33 5f 70 72 65 75 70  n*)sqlite3_preup
c910: 64 61 74 65 5f 68 6f 6f 6b 28 64 62 2c 20 78 50  date_hook(db, xP
c920: 72 65 55 70 64 61 74 65 2c 20 28 76 6f 69 64 2a  reUpdate, (void*
c930: 29 70 4e 65 77 29 3b 0a 20 20 70 4e 65 77 2d 3e  )pNew);.  pNew->
c940: 70 4e 65 78 74 20 3d 20 70 4f 6c 64 3b 0a 20 20  pNext = pOld;.  
c950: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65  sqlite3_mutex_le
c960: 61 76 65 28 73 71 6c 69 74 65 33 5f 64 62 5f 6d  ave(sqlite3_db_m
c970: 75 74 65 78 28 64 62 29 29 3b 0a 0a 20 20 2a 70  utex(db));..  *p
c980: 70 53 65 73 73 69 6f 6e 20 3d 20 70 4e 65 77 3b  pSession = pNew;
c990: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
c9a0: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72  _OK;.}../*.** Fr
c9b0: 65 65 20 74 68 65 20 6c 69 73 74 20 6f 66 20 74  ee the list of t
c9c0: 61 62 6c 65 20 6f 62 6a 65 63 74 73 20 70 61 73  able objects pas
c9d0: 73 65 64 20 61 73 20 74 68 65 20 66 69 72 73 74  sed as the first
c9e0: 20 61 72 67 75 6d 65 6e 74 2e 20 54 68 65 20 63   argument. The c
c9f0: 6f 6e 74 65 6e 74 73 0a 2a 2a 20 6f 66 20 74 68  ontents.** of th
ca00: 65 20 63 68 61 6e 67 65 64 2d 72 6f 77 73 20 68  e changed-rows h
ca10: 61 73 68 20 74 61 62 6c 65 73 20 61 72 65 20 61  ash tables are a
ca20: 6c 73 6f 20 64 65 6c 65 74 65 64 2e 0a 2a 2f 0a  lso deleted..*/.
ca30: 73 74 61 74 69 63 20 76 6f 69 64 20 73 65 73 73  static void sess
ca40: 69 6f 6e 44 65 6c 65 74 65 54 61 62 6c 65 28 53  ionDeleteTable(S
ca50: 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70 4c 69  essionTable *pLi
ca60: 73 74 29 7b 0a 20 20 53 65 73 73 69 6f 6e 54 61  st){.  SessionTa
ca70: 62 6c 65 20 2a 70 4e 65 78 74 3b 0a 20 20 53 65  ble *pNext;.  Se
ca80: 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62  ssionTable *pTab
ca90: 3b 0a 0a 20 20 66 6f 72 28 70 54 61 62 3d 70 4c  ;..  for(pTab=pL
caa0: 69 73 74 3b 20 70 54 61 62 3b 20 70 54 61 62 3d  ist; pTab; pTab=
cab0: 70 4e 65 78 74 29 7b 0a 20 20 20 20 69 6e 74 20  pNext){.    int 
cac0: 69 3b 0a 20 20 20 20 70 4e 65 78 74 20 3d 20 70  i;.    pNext = p
cad0: 54 61 62 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  Tab->pNext;.    
cae0: 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61 62 2d  for(i=0; i<pTab-
caf0: 3e 6e 43 68 61 6e 67 65 3b 20 69 2b 2b 29 7b 0a  >nChange; i++){.
cb00: 20 20 20 20 20 20 53 65 73 73 69 6f 6e 43 68 61        SessionCha
cb10: 6e 67 65 20 2a 70 3b 0a 20 20 20 20 20 20 53 65  nge *p;.      Se
cb20: 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 70 4e 65  ssionChange *pNe
cb30: 78 74 43 68 61 6e 67 65 3b 0a 20 20 20 20 20 20  xtChange;.      
cb40: 66 6f 72 28 70 3d 70 54 61 62 2d 3e 61 70 43 68  for(p=pTab->apCh
cb50: 61 6e 67 65 5b 69 5d 3b 20 70 3b 20 70 3d 70 4e  ange[i]; p; p=pN
cb60: 65 78 74 43 68 61 6e 67 65 29 7b 0a 20 20 20 20  extChange){.    
cb70: 20 20 20 20 70 4e 65 78 74 43 68 61 6e 67 65 20      pNextChange 
cb80: 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  = p->pNext;.    
cb90: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
cba0: 28 70 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  (p);.      }.   
cbb0: 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66   }.    sqlite3_f
cbc0: 72 65 65 28 28 63 68 61 72 2a 29 70 54 61 62 2d  ree((char*)pTab-
cbd0: 3e 61 7a 43 6f 6c 29 3b 20 20 2f 2a 20 63 61 73  >azCol);  /* cas
cbe0: 74 20 77 6f 72 6b 73 20 61 72 6f 75 6e 64 20 56  t works around V
cbf0: 43 2b 2b 20 62 75 67 20 2a 2f 0a 20 20 20 20 73  C++ bug */.    s
cc00: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 54 61 62  qlite3_free(pTab
cc10: 2d 3e 61 70 43 68 61 6e 67 65 29 3b 0a 20 20 20  ->apChange);.   
cc20: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 54   sqlite3_free(pT
cc30: 61 62 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  ab);.  }.}../*.*
cc40: 2a 20 44 65 6c 65 74 65 20 61 20 73 65 73 73 69  * Delete a sessi
cc50: 6f 6e 20 6f 62 6a 65 63 74 20 70 72 65 76 69 6f  on object previo
cc60: 75 73 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20 75  usly allocated u
cc70: 73 69 6e 67 20 73 71 6c 69 74 65 33 73 65 73 73  sing sqlite3sess
cc80: 69 6f 6e 5f 63 72 65 61 74 65 28 29 2e 0a 2a 2f  ion_create()..*/
cc90: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 73 65 73  .void sqlite3ses
cca0: 73 69 6f 6e 5f 64 65 6c 65 74 65 28 73 71 6c 69  sion_delete(sqli
ccb0: 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65  te3_session *pSe
ccc0: 73 73 69 6f 6e 29 7b 0a 20 20 73 71 6c 69 74 65  ssion){.  sqlite
ccd0: 33 20 2a 64 62 20 3d 20 70 53 65 73 73 69 6f 6e  3 *db = pSession
cce0: 2d 3e 64 62 3b 0a 20 20 73 71 6c 69 74 65 33 5f  ->db;.  sqlite3_
ccf0: 73 65 73 73 69 6f 6e 20 2a 70 48 65 61 64 3b 0a  session *pHead;.
cd00: 20 20 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f    sqlite3_sessio
cd10: 6e 20 2a 2a 70 70 3b 0a 0a 20 20 2f 2a 20 55 6e  n **pp;..  /* Un
cd20: 6c 69 6e 6b 20 74 68 65 20 73 65 73 73 69 6f 6e  link the session
cd30: 20 66 72 6f 6d 20 74 68 65 20 6c 69 6e 6b 65 64   from the linked
cd40: 20 6c 69 73 74 20 6f 66 20 73 65 73 73 69 6f 6e   list of session
cd50: 73 20 61 74 74 61 63 68 65 64 20 74 6f 20 74 68  s attached to th
cd60: 65 0a 20 20 2a 2a 20 64 61 74 61 62 61 73 65 20  e.  ** database 
cd70: 68 61 6e 64 6c 65 2e 20 48 6f 6c 64 20 74 68 65  handle. Hold the
cd80: 20 64 62 20 6d 75 74 65 78 20 77 68 69 6c 65 20   db mutex while 
cd90: 64 6f 69 6e 67 20 73 6f 2e 20 20 2a 2f 0a 20 20  doing so.  */.  
cda0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e  sqlite3_mutex_en
cdb0: 74 65 72 28 73 71 6c 69 74 65 33 5f 64 62 5f 6d  ter(sqlite3_db_m
cdc0: 75 74 65 78 28 64 62 29 29 3b 0a 20 20 70 48 65  utex(db));.  pHe
cdd0: 61 64 20 3d 20 28 73 71 6c 69 74 65 33 5f 73 65  ad = (sqlite3_se
cde0: 73 73 69 6f 6e 2a 29 73 71 6c 69 74 65 33 5f 70  ssion*)sqlite3_p
cdf0: 72 65 75 70 64 61 74 65 5f 68 6f 6f 6b 28 64 62  reupdate_hook(db
ce00: 2c 20 30 2c 20 30 29 3b 0a 20 20 66 6f 72 28 70  , 0, 0);.  for(p
ce10: 70 3d 26 70 48 65 61 64 3b 20 41 4c 57 41 59 53  p=&pHead; ALWAYS
ce20: 28 28 2a 70 70 29 21 3d 30 29 3b 20 70 70 3d 26  ((*pp)!=0); pp=&
ce30: 28 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29 29 7b  ((*pp)->pNext)){
ce40: 0a 20 20 20 20 69 66 28 20 28 2a 70 70 29 3d 3d  .    if( (*pp)==
ce50: 70 53 65 73 73 69 6f 6e 20 29 7b 0a 20 20 20 20  pSession ){.    
ce60: 20 20 2a 70 70 20 3d 20 28 2a 70 70 29 2d 3e 70    *pp = (*pp)->p
ce70: 4e 65 78 74 3b 0a 20 20 20 20 20 20 69 66 28 20  Next;.      if( 
ce80: 70 48 65 61 64 20 29 20 73 71 6c 69 74 65 33 5f  pHead ) sqlite3_
ce90: 70 72 65 75 70 64 61 74 65 5f 68 6f 6f 6b 28 64  preupdate_hook(d
cea0: 62 2c 20 78 50 72 65 55 70 64 61 74 65 2c 20 28  b, xPreUpdate, (
ceb0: 76 6f 69 64 2a 29 70 48 65 61 64 29 3b 0a 20 20  void*)pHead);.  
cec0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d      break;.    }
ced0: 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 6d  .  }.  sqlite3_m
cee0: 75 74 65 78 5f 6c 65 61 76 65 28 73 71 6c 69 74  utex_leave(sqlit
cef0: 65 33 5f 64 62 5f 6d 75 74 65 78 28 64 62 29 29  e3_db_mutex(db))
cf00: 3b 0a 0a 20 20 2f 2a 20 44 65 6c 65 74 65 20 61  ;..  /* Delete a
cf10: 6c 6c 20 61 74 74 61 63 68 65 64 20 74 61 62 6c  ll attached tabl
cf20: 65 20 6f 62 6a 65 63 74 73 2e 20 41 6e 64 20 74  e objects. And t
cf30: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
cf40: 68 65 69 72 20 0a 20 20 2a 2a 20 61 73 73 6f 63  heir .  ** assoc
cf50: 69 61 74 65 64 20 68 61 73 68 2d 74 61 62 6c 65  iated hash-table
cf60: 73 2e 20 2a 2f 0a 20 20 73 65 73 73 69 6f 6e 44  s. */.  sessionD
cf70: 65 6c 65 74 65 54 61 62 6c 65 28 70 53 65 73 73  eleteTable(pSess
cf80: 69 6f 6e 2d 3e 70 54 61 62 6c 65 29 3b 0a 0a 20  ion->pTable);.. 
cf90: 20 2f 2a 20 46 72 65 65 20 74 68 65 20 73 65 73   /* Free the ses
cfa0: 73 69 6f 6e 20 6f 62 6a 65 63 74 20 69 74 73 65  sion object itse
cfb0: 6c 66 2e 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  lf. */.  sqlite3
cfc0: 5f 66 72 65 65 28 70 53 65 73 73 69 6f 6e 29 3b  _free(pSession);
cfd0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61 20  .}../*.** Set a 
cfe0: 74 61 62 6c 65 20 66 69 6c 74 65 72 20 6f 6e 20  table filter on 
cff0: 61 20 53 65 73 73 69 6f 6e 20 4f 62 6a 65 63 74  a Session Object
d000: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
d010: 33 73 65 73 73 69 6f 6e 5f 74 61 62 6c 65 5f 66  3session_table_f
d020: 69 6c 74 65 72 28 0a 20 20 73 71 6c 69 74 65 33  ilter(.  sqlite3
d030: 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69  _session *pSessi
d040: 6f 6e 2c 20 0a 20 20 69 6e 74 28 2a 78 46 69 6c  on, .  int(*xFil
d050: 74 65 72 29 28 76 6f 69 64 2a 2c 20 63 6f 6e 73  ter)(void*, cons
d060: 74 20 63 68 61 72 2a 29 2c 0a 20 20 76 6f 69 64  t char*),.  void
d070: 20 2a 70 43 74 78 20 20 20 20 20 20 20 20 20 20   *pCtx          
d080: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
d090: 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 70 61  irst argument pa
d0a0: 73 73 65 64 20 74 6f 20 78 46 69 6c 74 65 72 20  ssed to xFilter 
d0b0: 2a 2f 0a 29 7b 0a 20 20 70 53 65 73 73 69 6f 6e  */.){.  pSession
d0c0: 2d 3e 62 41 75 74 6f 41 74 74 61 63 68 20 3d 20  ->bAutoAttach = 
d0d0: 31 3b 0a 20 20 70 53 65 73 73 69 6f 6e 2d 3e 70  1;.  pSession->p
d0e0: 46 69 6c 74 65 72 43 74 78 20 3d 20 70 43 74 78  FilterCtx = pCtx
d0f0: 3b 0a 20 20 70 53 65 73 73 69 6f 6e 2d 3e 78 54  ;.  pSession->xT
d100: 61 62 6c 65 46 69 6c 74 65 72 20 3d 20 78 46 69  ableFilter = xFi
d110: 6c 74 65 72 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  lter;.}../*.** A
d120: 74 74 61 63 68 20 61 20 74 61 62 6c 65 20 74 6f  ttach a table to
d130: 20 61 20 73 65 73 73 69 6f 6e 2e 20 41 6c 6c 20   a session. All 
d140: 73 75 62 73 65 71 75 65 6e 74 20 63 68 61 6e 67  subsequent chang
d150: 65 73 20 6d 61 64 65 20 74 6f 20 74 68 65 20 74  es made to the t
d160: 61 62 6c 65 0a 2a 2a 20 77 68 69 6c 65 20 74 68  able.** while th
d170: 65 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74  e session object
d180: 20 69 73 20 65 6e 61 62 6c 65 64 20 77 69 6c 6c   is enabled will
d190: 20 62 65 20 72 65 63 6f 72 64 65 64 2e 0a 2a 2a   be recorded..**
d1a0: 0a 2a 2a 20 4f 6e 6c 79 20 74 61 62 6c 65 73 20  .** Only tables 
d1b0: 74 68 61 74 20 68 61 76 65 20 61 20 50 52 49 4d  that have a PRIM
d1c0: 41 52 59 20 4b 45 59 20 64 65 66 69 6e 65 64 20  ARY KEY defined 
d1d0: 6d 61 79 20 62 65 20 61 74 74 61 63 68 65 64 2e  may be attached.
d1e0: 20 49 74 20 64 6f 65 73 0a 2a 2a 20 6e 6f 74 20   It does.** not 
d1f0: 6d 61 74 74 65 72 20 69 66 20 74 68 65 20 50 52  matter if the PR
d200: 49 4d 41 52 59 20 4b 45 59 20 69 73 20 61 6e 20  IMARY KEY is an 
d210: 22 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59  "INTEGER PRIMARY
d220: 20 4b 45 59 22 20 28 72 6f 77 69 64 20 61 6c 69   KEY" (rowid ali
d230: 61 73 29 0a 2a 2a 20 6f 72 20 6e 6f 74 2e 0a 2a  as).** or not..*
d240: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 73 65 73  /.int sqlite3ses
d250: 73 69 6f 6e 5f 61 74 74 61 63 68 28 0a 20 20 73  sion_attach(.  s
d260: 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a  qlite3_session *
d270: 70 53 65 73 73 69 6f 6e 2c 20 20 20 20 20 20 2f  pSession,      /
d280: 2a 20 53 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74  * Session object
d290: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
d2a0: 20 2a 7a 4e 61 6d 65 20 20 20 20 20 20 20 20 20   *zName         
d2b0: 20 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20 6e        /* Table n
d2c0: 61 6d 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  ame */.){.  int 
d2d0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
d2e0: 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
d2f0: 65 6e 74 65 72 28 73 71 6c 69 74 65 33 5f 64 62  enter(sqlite3_db
d300: 5f 6d 75 74 65 78 28 70 53 65 73 73 69 6f 6e 2d  _mutex(pSession-
d310: 3e 64 62 29 29 3b 0a 0a 20 20 69 66 28 20 21 7a  >db));..  if( !z
d320: 4e 61 6d 65 20 29 7b 0a 20 20 20 20 70 53 65 73  Name ){.    pSes
d330: 73 69 6f 6e 2d 3e 62 41 75 74 6f 41 74 74 61 63  sion->bAutoAttac
d340: 68 20 3d 20 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a  h = 1;.  }else{.
d350: 20 20 20 20 53 65 73 73 69 6f 6e 54 61 62 6c 65      SessionTable
d360: 20 2a 70 54 61 62 3b 20 20 20 20 20 20 20 20 20   *pTab;         
d370: 20 20 2f 2a 20 4e 65 77 20 74 61 62 6c 65 20 6f    /* New table o
d380: 62 6a 65 63 74 20 28 69 66 20 72 65 71 75 69 72  bject (if requir
d390: 65 64 29 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e  ed) */.    int n
d3a0: 4e 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20  Name;           
d3b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
d3c0: 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 73  er of bytes in s
d3d0: 74 72 69 6e 67 20 7a 4e 61 6d 65 20 2a 2f 0a 0a  tring zName */..
d3e0: 20 20 20 20 2f 2a 20 46 69 72 73 74 20 73 65 61      /* First sea
d3f0: 72 63 68 20 66 6f 72 20 61 6e 20 65 78 69 73 74  rch for an exist
d400: 69 6e 67 20 65 6e 74 72 79 2e 20 49 66 20 6f 6e  ing entry. If on
d410: 65 20 69 73 20 66 6f 75 6e 64 2c 20 74 68 69 73  e is found, this
d420: 20 63 61 6c 6c 20 69 73 0a 20 20 20 20 2a 2a 20   call is.    ** 
d430: 61 20 6e 6f 2d 6f 70 2e 20 52 65 74 75 72 6e 20  a no-op. Return 
d440: 65 61 72 6c 79 2e 20 2a 2f 0a 20 20 20 20 6e 4e  early. */.    nN
d450: 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 53 74 72  ame = sqlite3Str
d460: 6c 65 6e 33 30 28 7a 4e 61 6d 65 29 3b 0a 20 20  len30(zName);.  
d470: 20 20 66 6f 72 28 70 54 61 62 3d 70 53 65 73 73    for(pTab=pSess
d480: 69 6f 6e 2d 3e 70 54 61 62 6c 65 3b 20 70 54 61  ion->pTable; pTa
d490: 62 3b 20 70 54 61 62 3d 70 54 61 62 2d 3e 70 4e  b; pTab=pTab->pN
d4a0: 65 78 74 29 7b 0a 20 20 20 20 20 20 69 66 28 20  ext){.      if( 
d4b0: 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 6e 69  0==sqlite3_strni
d4c0: 63 6d 70 28 70 54 61 62 2d 3e 7a 4e 61 6d 65 2c  cmp(pTab->zName,
d4d0: 20 7a 4e 61 6d 65 2c 20 6e 4e 61 6d 65 2b 31 29   zName, nName+1)
d4e0: 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a   ) break;.    }.
d4f0: 0a 20 20 20 20 69 66 28 20 21 70 54 61 62 20 29  .    if( !pTab )
d500: 7b 0a 20 20 20 20 20 20 2f 2a 20 41 6c 6c 6f 63  {.      /* Alloc
d510: 61 74 65 20 6e 65 77 20 53 65 73 73 69 6f 6e 54  ate new SessionT
d520: 61 62 6c 65 20 6f 62 6a 65 63 74 2e 20 2a 2f 0a  able object. */.
d530: 20 20 20 20 20 20 70 54 61 62 20 3d 20 28 53 65        pTab = (Se
d540: 73 73 69 6f 6e 54 61 62 6c 65 20 2a 29 73 71 6c  ssionTable *)sql
d550: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65  ite3_malloc(size
d560: 6f 66 28 53 65 73 73 69 6f 6e 54 61 62 6c 65 29  of(SessionTable)
d570: 20 2b 20 6e 4e 61 6d 65 20 2b 20 31 29 3b 0a 20   + nName + 1);. 
d580: 20 20 20 20 20 69 66 28 20 21 70 54 61 62 20 29       if( !pTab )
d590: 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53  {.        rc = S
d5a0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
d5b0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
d5c0: 20 20 2f 2a 20 50 6f 70 75 6c 61 74 65 20 74 68    /* Populate th
d5d0: 65 20 6e 65 77 20 53 65 73 73 69 6f 6e 54 61 62  e new SessionTab
d5e0: 6c 65 20 6f 62 6a 65 63 74 20 61 6e 64 20 6c 69  le object and li
d5f0: 6e 6b 20 69 74 20 69 6e 74 6f 20 74 68 65 20 6c  nk it into the l
d600: 69 73 74 2e 0a 20 20 20 20 20 20 20 20 2a 2a 20  ist..        ** 
d610: 54 68 65 20 6e 65 77 20 6f 62 6a 65 63 74 20 6d  The new object m
d620: 75 73 74 20 62 65 20 6c 69 6e 6b 65 64 20 6f 6e  ust be linked on
d630: 74 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68  to the end of th
d640: 65 20 6c 69 73 74 2c 20 6e 6f 74 20 0a 20 20 20  e list, not .   
d650: 20 20 20 20 20 2a 2a 20 73 69 6d 70 6c 79 20 61       ** simply a
d660: 64 64 65 64 20 74 6f 20 74 68 65 20 73 74 61 72  dded to the star
d670: 74 20 6f 66 20 69 74 20 69 6e 20 6f 72 64 65 72  t of it in order
d680: 20 74 6f 20 65 6e 73 75 72 65 20 74 68 61 74 20   to ensure that 
d690: 74 61 62 6c 65 73 0a 20 20 20 20 20 20 20 20 2a  tables.        *
d6a0: 2a 20 61 70 70 65 61 72 20 69 6e 20 74 68 65 20  * appear in the 
d6b0: 63 6f 72 72 65 63 74 20 6f 72 64 65 72 20 77 68  correct order wh
d6c0: 65 6e 20 61 20 63 68 61 6e 67 65 73 65 74 20 6f  en a changeset o
d6d0: 72 20 70 61 74 63 68 73 65 74 20 69 73 0a 20 20  r patchset is.  
d6e0: 20 20 20 20 20 20 2a 2a 20 65 76 65 6e 74 75 61        ** eventua
d6f0: 6c 6c 79 20 67 65 6e 65 72 61 74 65 64 2e 20 2a  lly generated. *
d700: 2f 0a 20 20 20 20 20 20 20 20 53 65 73 73 69 6f  /.        Sessio
d710: 6e 54 61 62 6c 65 20 2a 2a 70 70 54 61 62 3b 0a  nTable **ppTab;.
d720: 20 20 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70          memset(p
d730: 54 61 62 2c 20 30 2c 20 73 69 7a 65 6f 66 28 53  Tab, 0, sizeof(S
d740: 65 73 73 69 6f 6e 54 61 62 6c 65 29 29 3b 0a 20  essionTable));. 
d750: 20 20 20 20 20 20 20 70 54 61 62 2d 3e 7a 4e 61         pTab->zNa
d760: 6d 65 20 3d 20 28 63 68 61 72 20 2a 29 26 70 54  me = (char *)&pT
d770: 61 62 5b 31 5d 3b 0a 20 20 20 20 20 20 20 20 6d  ab[1];.        m
d780: 65 6d 63 70 79 28 70 54 61 62 2d 3e 7a 4e 61 6d  emcpy(pTab->zNam
d790: 65 2c 20 7a 4e 61 6d 65 2c 20 6e 4e 61 6d 65 2b  e, zName, nName+
d7a0: 31 29 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28  1);.        for(
d7b0: 70 70 54 61 62 3d 26 70 53 65 73 73 69 6f 6e 2d  ppTab=&pSession-
d7c0: 3e 70 54 61 62 6c 65 3b 20 2a 70 70 54 61 62 3b  >pTable; *ppTab;
d7d0: 20 70 70 54 61 62 3d 26 28 2a 70 70 54 61 62 29   ppTab=&(*ppTab)
d7e0: 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 20 20 20 20  ->pNext);.      
d7f0: 20 20 2a 70 70 54 61 62 20 3d 20 70 54 61 62 3b    *ppTab = pTab;
d800: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
d810: 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75   }..  sqlite3_mu
d820: 74 65 78 5f 6c 65 61 76 65 28 73 71 6c 69 74 65  tex_leave(sqlite
d830: 33 5f 64 62 5f 6d 75 74 65 78 28 70 53 65 73 73  3_db_mutex(pSess
d840: 69 6f 6e 2d 3e 64 62 29 29 3b 0a 20 20 72 65 74  ion->db));.  ret
d850: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
d860: 20 45 6e 73 75 72 65 20 74 68 61 74 20 74 68 65   Ensure that the
d870: 72 65 20 69 73 20 72 6f 6f 6d 20 69 6e 20 74 68  re is room in th
d880: 65 20 62 75 66 66 65 72 20 74 6f 20 61 70 70 65  e buffer to appe
d890: 6e 64 20 6e 42 79 74 65 20 62 79 74 65 73 20 6f  nd nByte bytes o
d8a0: 66 20 64 61 74 61 2e 0a 2a 2a 20 49 66 20 6e 6f  f data..** If no
d8b0: 74 2c 20 75 73 65 20 73 71 6c 69 74 65 33 5f 72  t, use sqlite3_r
d8c0: 65 61 6c 6c 6f 63 28 29 20 74 6f 20 67 72 6f 77  ealloc() to grow
d8d0: 20 74 68 65 20 62 75 66 66 65 72 20 73 6f 20 74   the buffer so t
d8e0: 68 61 74 20 74 68 65 72 65 20 69 73 2e 0a 2a 2a  hat there is..**
d8f0: 0a 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75  .** If successfu
d900: 6c 2c 20 72 65 74 75 72 6e 20 7a 65 72 6f 2e 20  l, return zero. 
d910: 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20 61 6e  Otherwise, if an
d920: 20 4f 4f 4d 20 63 6f 6e 64 69 74 69 6f 6e 20 69   OOM condition i
d930: 73 20 65 6e 63 6f 75 6e 74 65 72 65 64 2c 0a 2a  s encountered,.*
d940: 2a 20 73 65 74 20 2a 70 52 63 20 74 6f 20 53 51  * set *pRc to SQ
d950: 4c 49 54 45 5f 4e 4f 4d 45 4d 20 61 6e 64 20 72  LITE_NOMEM and r
d960: 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a  eturn non-zero..
d970: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
d980: 73 73 69 6f 6e 42 75 66 66 65 72 47 72 6f 77 28  ssionBufferGrow(
d990: 53 65 73 73 69 6f 6e 42 75 66 66 65 72 20 2a 70  SessionBuffer *p
d9a0: 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20 69 6e 74  , int nByte, int
d9b0: 20 2a 70 52 63 29 7b 0a 20 20 69 66 28 20 2a 70   *pRc){.  if( *p
d9c0: 52 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  Rc==SQLITE_OK &&
d9d0: 20 70 2d 3e 6e 41 6c 6c 6f 63 2d 70 2d 3e 6e 42   p->nAlloc-p->nB
d9e0: 75 66 3c 6e 42 79 74 65 20 29 7b 0a 20 20 20 20  uf<nByte ){.    
d9f0: 75 38 20 2a 61 4e 65 77 3b 0a 20 20 20 20 69 6e  u8 *aNew;.    in
da00: 74 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e 41 6c 6c  t nNew = p->nAll
da10: 6f 63 20 3f 20 70 2d 3e 6e 41 6c 6c 6f 63 20 3a  oc ? p->nAlloc :
da20: 20 31 32 38 3b 0a 20 20 20 20 64 6f 20 7b 0a 20   128;.    do {. 
da30: 20 20 20 20 20 6e 4e 65 77 20 3d 20 6e 4e 65 77       nNew = nNew
da40: 2a 32 3b 0a 20 20 20 20 7d 77 68 69 6c 65 28 20  *2;.    }while( 
da50: 6e 4e 65 77 3c 28 70 2d 3e 6e 42 75 66 2b 6e 42  nNew<(p->nBuf+nB
da60: 79 74 65 29 20 29 3b 0a 0a 20 20 20 20 61 4e 65  yte) );..    aNe
da70: 77 20 3d 20 28 75 38 20 2a 29 73 71 6c 69 74 65  w = (u8 *)sqlite
da80: 33 5f 72 65 61 6c 6c 6f 63 28 70 2d 3e 61 42 75  3_realloc(p->aBu
da90: 66 2c 20 6e 4e 65 77 29 3b 0a 20 20 20 20 69 66  f, nNew);.    if
daa0: 28 20 30 3d 3d 61 4e 65 77 20 29 7b 0a 20 20 20  ( 0==aNew ){.   
dab0: 20 20 20 2a 70 52 63 20 3d 20 53 51 4c 49 54 45     *pRc = SQLITE
dac0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c 73  _NOMEM;.    }els
dad0: 65 7b 0a 20 20 20 20 20 20 70 2d 3e 61 42 75 66  e{.      p->aBuf
dae0: 20 3d 20 61 4e 65 77 3b 0a 20 20 20 20 20 20 70   = aNew;.      p
daf0: 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 6e 4e 65 77 3b  ->nAlloc = nNew;
db00: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
db10: 75 72 6e 20 28 2a 70 52 63 21 3d 53 51 4c 49 54  urn (*pRc!=SQLIT
db20: 45 5f 4f 4b 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  E_OK);.}../*.** 
db30: 41 70 70 65 6e 64 20 74 68 65 20 76 61 6c 75 65  Append the value
db40: 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 73   passed as the s
db50: 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 74  econd argument t
db60: 6f 20 74 68 65 20 62 75 66 66 65 72 20 70 61 73  o the buffer pas
db70: 73 65 64 0a 2a 2a 20 61 73 20 74 68 65 20 66 69  sed.** as the fi
db80: 72 73 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  rst..**.** This 
db90: 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f  function is a no
dba0: 2d 6f 70 20 69 66 20 2a 70 52 63 20 69 73 20 6e  -op if *pRc is n
dbb0: 6f 6e 2d 7a 65 72 6f 20 77 68 65 6e 20 69 74 20  on-zero when it 
dbc0: 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2a 20 4f 74  is called..** Ot
dbd0: 68 65 72 77 69 73 65 2c 20 69 66 20 61 6e 20 65  herwise, if an e
dbe0: 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 2a 70 52  rror occurs, *pR
dbf0: 63 20 69 73 20 73 65 74 20 74 6f 20 61 6e 20 53  c is set to an S
dc00: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
dc10: 0a 2a 2a 20 62 65 66 6f 72 65 20 72 65 74 75 72  .** before retur
dc20: 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ning..*/.static 
dc30: 76 6f 69 64 20 73 65 73 73 69 6f 6e 41 70 70 65  void sessionAppe
dc40: 6e 64 56 61 6c 75 65 28 53 65 73 73 69 6f 6e 42  ndValue(SessionB
dc50: 75 66 66 65 72 20 2a 70 2c 20 73 71 6c 69 74 65  uffer *p, sqlite
dc60: 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c 2c 20 69  3_value *pVal, i
dc70: 6e 74 20 2a 70 52 63 29 7b 0a 20 20 69 6e 74 20  nt *pRc){.  int 
dc80: 72 63 20 3d 20 2a 70 52 63 3b 0a 20 20 69 66 28  rc = *pRc;.  if(
dc90: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
dca0: 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20  {.    int nByte 
dcb0: 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d 20 73 65  = 0;.    rc = se
dcc0: 73 73 69 6f 6e 53 65 72 69 61 6c 69 7a 65 56 61  ssionSerializeVa
dcd0: 6c 75 65 28 30 2c 20 70 56 61 6c 2c 20 26 6e 42  lue(0, pVal, &nB
dce0: 79 74 65 29 3b 0a 20 20 20 20 73 65 73 73 69 6f  yte);.    sessio
dcf0: 6e 42 75 66 66 65 72 47 72 6f 77 28 70 2c 20 6e  nBufferGrow(p, n
dd00: 42 79 74 65 2c 20 26 72 63 29 3b 0a 20 20 20 20  Byte, &rc);.    
dd10: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
dd20: 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  K ){.      rc = 
dd30: 73 65 73 73 69 6f 6e 53 65 72 69 61 6c 69 7a 65  sessionSerialize
dd40: 56 61 6c 75 65 28 26 70 2d 3e 61 42 75 66 5b 70  Value(&p->aBuf[p
dd50: 2d 3e 6e 42 75 66 5d 2c 20 70 56 61 6c 2c 20 30  ->nBuf], pVal, 0
dd60: 29 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 42 75 66  );.      p->nBuf
dd70: 20 2b 3d 20 6e 42 79 74 65 3b 0a 20 20 20 20 7d   += nByte;.    }
dd80: 65 6c 73 65 7b 0a 20 20 20 20 20 20 2a 70 52 63  else{.      *pRc
dd90: 20 3d 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d   = rc;.    }.  }
dda0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
ddb0: 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d  unction is a no-
ddc0: 6f 70 20 69 66 20 2a 70 52 63 20 69 73 20 6f 74  op if *pRc is ot
ddd0: 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45 5f  her than SQLITE_
dde0: 4f 4b 20 77 68 65 6e 20 69 74 20 69 73 20 0a 2a  OK when it is .*
ddf0: 2a 20 63 61 6c 6c 65 64 2e 20 4f 74 68 65 72 77  * called. Otherw
de00: 69 73 65 2c 20 61 70 70 65 6e 64 20 61 20 73 69  ise, append a si
de10: 6e 67 6c 65 20 62 79 74 65 20 74 6f 20 74 68 65  ngle byte to the
de20: 20 62 75 66 66 65 72 2e 20 0a 2a 2a 0a 2a 2a 20   buffer. .**.** 
de30: 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74  If an OOM condit
de40: 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e 74 65 72  ion is encounter
de50: 65 64 2c 20 73 65 74 20 2a 70 52 63 20 74 6f 20  ed, set *pRc to 
de60: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 62 65 66  SQLITE_NOMEM bef
de70: 6f 72 65 0a 2a 2a 20 72 65 74 75 72 6e 69 6e 67  ore.** returning
de80: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
de90: 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 79   sessionAppendBy
dea0: 74 65 28 53 65 73 73 69 6f 6e 42 75 66 66 65 72  te(SessionBuffer
deb0: 20 2a 70 2c 20 75 38 20 76 2c 20 69 6e 74 20 2a   *p, u8 v, int *
dec0: 70 52 63 29 7b 0a 20 20 69 66 28 20 30 3d 3d 73  pRc){.  if( 0==s
ded0: 65 73 73 69 6f 6e 42 75 66 66 65 72 47 72 6f 77  essionBufferGrow
dee0: 28 70 2c 20 31 2c 20 70 52 63 29 20 29 7b 0a 20  (p, 1, pRc) ){. 
def0: 20 20 20 70 2d 3e 61 42 75 66 5b 70 2d 3e 6e 42     p->aBuf[p->nB
df00: 75 66 2b 2b 5d 20 3d 20 76 3b 0a 20 20 7d 0a 7d  uf++] = v;.  }.}
df10: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
df20: 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70  ction is a no-op
df30: 20 69 66 20 2a 70 52 63 20 69 73 20 6f 74 68 65   if *pRc is othe
df40: 72 20 74 68 61 6e 20 53 51 4c 49 54 45 5f 4f 4b  r than SQLITE_OK
df50: 20 77 68 65 6e 20 69 74 20 69 73 20 0a 2a 2a 20   when it is .** 
df60: 63 61 6c 6c 65 64 2e 20 4f 74 68 65 72 77 69 73  called. Otherwis
df70: 65 2c 20 61 70 70 65 6e 64 20 61 20 73 69 6e 67  e, append a sing
df80: 6c 65 20 76 61 72 69 6e 74 20 74 6f 20 74 68 65  le varint to the
df90: 20 62 75 66 66 65 72 2e 20 0a 2a 2a 0a 2a 2a 20   buffer. .**.** 
dfa0: 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74  If an OOM condit
dfb0: 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e 74 65 72  ion is encounter
dfc0: 65 64 2c 20 73 65 74 20 2a 70 52 63 20 74 6f 20  ed, set *pRc to 
dfd0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 62 65 66  SQLITE_NOMEM bef
dfe0: 6f 72 65 0a 2a 2a 20 72 65 74 75 72 6e 69 6e 67  ore.** returning
dff0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
e000: 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 56 61   sessionAppendVa
e010: 72 69 6e 74 28 53 65 73 73 69 6f 6e 42 75 66 66  rint(SessionBuff
e020: 65 72 20 2a 70 2c 20 69 6e 74 20 76 2c 20 69 6e  er *p, int v, in
e030: 74 20 2a 70 52 63 29 7b 0a 20 20 69 66 28 20 30  t *pRc){.  if( 0
e040: 3d 3d 73 65 73 73 69 6f 6e 42 75 66 66 65 72 47  ==sessionBufferG
e050: 72 6f 77 28 70 2c 20 39 2c 20 70 52 63 29 20 29  row(p, 9, pRc) )
e060: 7b 0a 20 20 20 20 70 2d 3e 6e 42 75 66 20 2b 3d  {.    p->nBuf +=
e070: 20 73 65 73 73 69 6f 6e 56 61 72 69 6e 74 50 75   sessionVarintPu
e080: 74 28 26 70 2d 3e 61 42 75 66 5b 70 2d 3e 6e 42  t(&p->aBuf[p->nB
e090: 75 66 5d 2c 20 76 29 3b 0a 20 20 7d 0a 7d 0a 0a  uf], v);.  }.}..
e0a0: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
e0b0: 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 20 69  ion is a no-op i
e0c0: 66 20 2a 70 52 63 20 69 73 20 6f 74 68 65 72 20  f *pRc is other 
e0d0: 74 68 61 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 77  than SQLITE_OK w
e0e0: 68 65 6e 20 69 74 20 69 73 20 0a 2a 2a 20 63 61  hen it is .** ca
e0f0: 6c 6c 65 64 2e 20 4f 74 68 65 72 77 69 73 65 2c  lled. Otherwise,
e100: 20 61 70 70 65 6e 64 20 61 20 62 6c 6f 62 20 6f   append a blob o
e110: 66 20 64 61 74 61 20 74 6f 20 74 68 65 20 62 75  f data to the bu
e120: 66 66 65 72 2e 20 0a 2a 2a 0a 2a 2a 20 49 66 20  ffer. .**.** If 
e130: 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74 69 6f 6e  an OOM condition
e140: 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65 64 2c   is encountered,
e150: 20 73 65 74 20 2a 70 52 63 20 74 6f 20 53 51 4c   set *pRc to SQL
e160: 49 54 45 5f 4e 4f 4d 45 4d 20 62 65 66 6f 72 65  ITE_NOMEM before
e170: 0a 2a 2a 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a  .** returning..*
e180: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 65  /.static void se
e190: 73 73 69 6f 6e 41 70 70 65 6e 64 42 6c 6f 62 28  ssionAppendBlob(
e1a0: 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66 65 72  .  SessionBuffer
e1b0: 20 2a 70 2c 20 0a 20 20 63 6f 6e 73 74 20 75 38   *p, .  const u8
e1c0: 20 2a 61 42 6c 6f 62 2c 20 0a 20 20 69 6e 74 20   *aBlob, .  int 
e1d0: 6e 42 6c 6f 62 2c 20 0a 20 20 69 6e 74 20 2a 70  nBlob, .  int *p
e1e0: 52 63 0a 29 7b 0a 20 20 69 66 28 20 30 3d 3d 73  Rc.){.  if( 0==s
e1f0: 65 73 73 69 6f 6e 42 75 66 66 65 72 47 72 6f 77  essionBufferGrow
e200: 28 70 2c 20 6e 42 6c 6f 62 2c 20 70 52 63 29 20  (p, nBlob, pRc) 
e210: 29 7b 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70  ){.    memcpy(&p
e220: 2d 3e 61 42 75 66 5b 70 2d 3e 6e 42 75 66 5d 2c  ->aBuf[p->nBuf],
e230: 20 61 42 6c 6f 62 2c 20 6e 42 6c 6f 62 29 3b 0a   aBlob, nBlob);.
e240: 20 20 20 20 70 2d 3e 6e 42 75 66 20 2b 3d 20 6e      p->nBuf += n
e250: 42 6c 6f 62 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  Blob;.  }.}../*.
e260: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
e270: 20 69 73 20 61 20 6e 6f 2d 6f 70 20 69 66 20 2a   is a no-op if *
e280: 70 52 63 20 69 73 20 6f 74 68 65 72 20 74 68 61  pRc is other tha
e290: 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 77 68 65 6e  n SQLITE_OK when
e2a0: 20 69 74 20 69 73 20 0a 2a 2a 20 63 61 6c 6c 65   it is .** calle
e2b0: 64 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 61 70  d. Otherwise, ap
e2c0: 70 65 6e 64 20 61 20 73 74 72 69 6e 67 20 74 6f  pend a string to
e2d0: 20 74 68 65 20 62 75 66 66 65 72 2e 20 41 6c 6c   the buffer. All
e2e0: 20 62 79 74 65 73 20 69 6e 20 74 68 65 20 73 74   bytes in the st
e2f0: 72 69 6e 67 0a 2a 2a 20 75 70 20 74 6f 20 28 62  ring.** up to (b
e300: 75 74 20 6e 6f 74 20 69 6e 63 6c 75 64 69 6e 67  ut not including
e310: 29 20 74 68 65 20 6e 75 6c 2d 74 65 72 6d 69 6e  ) the nul-termin
e320: 61 74 6f 72 20 61 72 65 20 77 72 69 74 74 65 6e  ator are written
e330: 20 74 6f 20 74 68 65 20 62 75 66 66 65 72 2e 0a   to the buffer..
e340: 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20  **.** If an OOM 
e350: 63 6f 6e 64 69 74 69 6f 6e 20 69 73 20 65 6e 63  condition is enc
e360: 6f 75 6e 74 65 72 65 64 2c 20 73 65 74 20 2a 70  ountered, set *p
e370: 52 63 20 74 6f 20 53 51 4c 49 54 45 5f 4e 4f 4d  Rc to SQLITE_NOM
e380: 45 4d 20 62 65 66 6f 72 65 0a 2a 2a 20 72 65 74  EM before.** ret
e390: 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69  urning..*/.stati
e3a0: 63 20 76 6f 69 64 20 73 65 73 73 69 6f 6e 41 70  c void sessionAp
e3b0: 70 65 6e 64 53 74 72 28 0a 20 20 53 65 73 73 69  pendStr(.  Sessi
e3c0: 6f 6e 42 75 66 66 65 72 20 2a 70 2c 20 0a 20 20  onBuffer *p, .  
e3d0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 74 72  const char *zStr
e3e0: 2c 20 0a 20 20 69 6e 74 20 2a 70 52 63 0a 29 7b  , .  int *pRc.){
e3f0: 0a 20 20 69 6e 74 20 6e 53 74 72 20 3d 20 73 71  .  int nStr = sq
e400: 6c 69 74 65 33 53 74 72 6c 65 6e 33 30 28 7a 53  lite3Strlen30(zS
e410: 74 72 29 3b 0a 20 20 69 66 28 20 30 3d 3d 73 65  tr);.  if( 0==se
e420: 73 73 69 6f 6e 42 75 66 66 65 72 47 72 6f 77 28  ssionBufferGrow(
e430: 70 2c 20 6e 53 74 72 2c 20 70 52 63 29 20 29 7b  p, nStr, pRc) ){
e440: 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d 3e  .    memcpy(&p->
e450: 61 42 75 66 5b 70 2d 3e 6e 42 75 66 5d 2c 20 7a  aBuf[p->nBuf], z
e460: 53 74 72 2c 20 6e 53 74 72 29 3b 0a 20 20 20 20  Str, nStr);.    
e470: 70 2d 3e 6e 42 75 66 20 2b 3d 20 6e 53 74 72 3b  p->nBuf += nStr;
e480: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  .  }.}../*.** Th
e490: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 61  is function is a
e4a0: 20 6e 6f 2d 6f 70 20 69 66 20 2a 70 52 63 20 69   no-op if *pRc i
e4b0: 73 20 6f 74 68 65 72 20 74 68 61 6e 20 53 51 4c  s other than SQL
e4c0: 49 54 45 5f 4f 4b 20 77 68 65 6e 20 69 74 20 69  ITE_OK when it i
e4d0: 73 20 0a 2a 2a 20 63 61 6c 6c 65 64 2e 20 4f 74  s .** called. Ot
e4e0: 68 65 72 77 69 73 65 2c 20 61 70 70 65 6e 64 20  herwise, append 
e4f0: 74 68 65 20 73 74 72 69 6e 67 20 72 65 70 72 65  the string repre
e500: 73 65 6e 74 61 74 69 6f 6e 20 6f 66 20 69 6e 74  sentation of int
e510: 65 67 65 72 20 69 56 61 6c 0a 2a 2a 20 74 6f 20  eger iVal.** to 
e520: 74 68 65 20 62 75 66 66 65 72 2e 20 4e 6f 20 6e  the buffer. No n
e530: 75 6c 2d 74 65 72 6d 69 6e 61 74 6f 72 20 69 73  ul-terminator is
e540: 20 77 72 69 74 74 65 6e 2e 0a 2a 2a 0a 2a 2a 20   written..**.** 
e550: 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74  If an OOM condit
e560: 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e 74 65 72  ion is encounter
e570: 65 64 2c 20 73 65 74 20 2a 70 52 63 20 74 6f 20  ed, set *pRc to 
e580: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 62 65 66  SQLITE_NOMEM bef
e590: 6f 72 65 0a 2a 2a 20 72 65 74 75 72 6e 69 6e 67  ore.** returning
e5a0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
e5b0: 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49 6e   sessionAppendIn
e5c0: 74 65 67 65 72 28 0a 20 20 53 65 73 73 69 6f 6e  teger(.  Session
e5d0: 42 75 66 66 65 72 20 2a 70 2c 20 20 20 20 20 20  Buffer *p,      
e5e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66           /* Buff
e5f0: 65 72 20 74 6f 20 61 70 70 65 6e 64 20 74 6f 20  er to append to 
e600: 2a 2f 0a 20 20 69 6e 74 20 69 56 61 6c 2c 20 20  */.  int iVal,  
e610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e620: 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 74 6f       /* Value to
e630: 20 77 72 69 74 65 20 74 68 65 20 73 74 72 69 6e   write the strin
e640: 67 20 72 65 70 2e 20 6f 66 20 2a 2f 0a 20 20 69  g rep. of */.  i
e650: 6e 74 20 2a 70 52 63 20 20 20 20 20 20 20 20 20  nt *pRc         
e660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
e670: 2a 20 49 4e 2f 4f 55 54 3a 20 45 72 72 6f 72 20  * IN/OUT: Error 
e680: 63 6f 64 65 20 2a 2f 0a 29 7b 0a 20 20 63 68 61  code */.){.  cha
e690: 72 20 61 42 75 66 5b 32 34 5d 3b 0a 20 20 73 71  r aBuf[24];.  sq
e6a0: 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74 66 28 73  lite3_snprintf(s
e6b0: 69 7a 65 6f 66 28 61 42 75 66 29 2d 31 2c 20 61  izeof(aBuf)-1, a
e6c0: 42 75 66 2c 20 22 25 64 22 2c 20 69 56 61 6c 29  Buf, "%d", iVal)
e6d0: 3b 0a 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e  ;.  sessionAppen
e6e0: 64 53 74 72 28 70 2c 20 61 42 75 66 2c 20 70 52  dStr(p, aBuf, pR
e6f0: 63 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  c);.}../*.** Thi
e700: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20  s function is a 
e710: 6e 6f 2d 6f 70 20 69 66 20 2a 70 52 63 20 69 73  no-op if *pRc is
e720: 20 6f 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49   other than SQLI
e730: 54 45 5f 4f 4b 20 77 68 65 6e 20 69 74 20 69 73  TE_OK when it is
e740: 20 0a 2a 2a 20 63 61 6c 6c 65 64 2e 20 4f 74 68   .** called. Oth
e750: 65 72 77 69 73 65 2c 20 61 70 70 65 6e 64 20 74  erwise, append t
e760: 68 65 20 73 74 72 69 6e 67 20 7a 53 74 72 20 65  he string zStr e
e770: 6e 63 6c 6f 73 65 64 20 69 6e 20 71 75 6f 74 65  nclosed in quote
e780: 73 20 28 22 29 20 61 6e 64 0a 2a 2a 20 77 69 74  s (") and.** wit
e790: 68 20 61 6e 79 20 65 6d 62 65 64 64 65 64 20 71  h any embedded q
e7a0: 75 6f 74 65 20 63 68 61 72 61 63 74 65 72 73 20  uote characters 
e7b0: 65 73 63 61 70 65 64 20 74 6f 20 74 68 65 20 62  escaped to the b
e7c0: 75 66 66 65 72 2e 20 4e 6f 20 0a 2a 2a 20 6e 75  uffer. No .** nu
e7d0: 6c 2d 74 65 72 6d 69 6e 61 74 6f 72 20 62 79 74  l-terminator byt
e7e0: 65 20 69 73 20 77 72 69 74 74 65 6e 2e 0a 2a 2a  e is written..**
e7f0: 0a 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 63 6f  .** If an OOM co
e800: 6e 64 69 74 69 6f 6e 20 69 73 20 65 6e 63 6f 75  ndition is encou
e810: 6e 74 65 72 65 64 2c 20 73 65 74 20 2a 70 52 63  ntered, set *pRc
e820: 20 74 6f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d   to SQLITE_NOMEM
e830: 20 62 65 66 6f 72 65 0a 2a 2a 20 72 65 74 75 72   before.** retur
e840: 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ning..*/.static 
e850: 76 6f 69 64 20 73 65 73 73 69 6f 6e 41 70 70 65  void sessionAppe
e860: 6e 64 49 64 65 6e 74 28 0a 20 20 53 65 73 73 69  ndIdent(.  Sessi
e870: 6f 6e 42 75 66 66 65 72 20 2a 70 2c 20 20 20 20  onBuffer *p,    
e880: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75             /* Bu
e890: 66 66 65 72 20 74 6f 20 61 20 61 70 70 65 6e 64  ffer to a append
e8a0: 20 74 6f 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63   to */.  const c
e8b0: 68 61 72 20 2a 7a 53 74 72 2c 20 20 20 20 20 20  har *zStr,      
e8c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74 72 69           /* Stri
e8d0: 6e 67 20 74 6f 20 71 75 6f 74 65 2c 20 65 73 63  ng to quote, esc
e8e0: 61 70 65 20 61 6e 64 20 61 70 70 65 6e 64 20 2a  ape and append *
e8f0: 2f 0a 20 20 69 6e 74 20 2a 70 52 63 20 20 20 20  /.  int *pRc    
e900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e910: 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 45      /* IN/OUT: E
e920: 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 29 7b 0a  rror code */.){.
e930: 20 20 69 6e 74 20 6e 53 74 72 20 3d 20 73 71 6c    int nStr = sql
e940: 69 74 65 33 53 74 72 6c 65 6e 33 30 28 7a 53 74  ite3Strlen30(zSt
e950: 72 29 2a 32 20 2b 20 32 20 2b 20 31 3b 0a 20 20  r)*2 + 2 + 1;.  
e960: 69 66 28 20 30 3d 3d 73 65 73 73 69 6f 6e 42 75  if( 0==sessionBu
e970: 66 66 65 72 47 72 6f 77 28 70 2c 20 6e 53 74 72  fferGrow(p, nStr
e980: 2c 20 70 52 63 29 20 29 7b 0a 20 20 20 20 63 68  , pRc) ){.    ch
e990: 61 72 20 2a 7a 4f 75 74 20 3d 20 28 63 68 61 72  ar *zOut = (char
e9a0: 20 2a 29 26 70 2d 3e 61 42 75 66 5b 70 2d 3e 6e   *)&p->aBuf[p->n
e9b0: 42 75 66 5d 3b 0a 20 20 20 20 63 6f 6e 73 74 20  Buf];.    const 
e9c0: 63 68 61 72 20 2a 7a 49 6e 20 3d 20 7a 53 74 72  char *zIn = zStr
e9d0: 3b 0a 20 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20  ;.    *zOut++ = 
e9e0: 27 22 27 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  '"';.    while( 
e9f0: 2a 7a 49 6e 20 29 7b 0a 20 20 20 20 20 20 69 66  *zIn ){.      if
ea00: 28 20 2a 7a 49 6e 3d 3d 27 22 27 20 29 20 2a 7a  ( *zIn=='"' ) *z
ea10: 4f 75 74 2b 2b 20 3d 20 27 22 27 3b 0a 20 20 20  Out++ = '"';.   
ea20: 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20 2a 28 7a     *zOut++ = *(z
ea30: 49 6e 2b 2b 29 3b 0a 20 20 20 20 7d 0a 20 20 20  In++);.    }.   
ea40: 20 2a 7a 4f 75 74 2b 2b 20 3d 20 27 22 27 3b 0a   *zOut++ = '"';.
ea50: 20 20 20 20 70 2d 3e 6e 42 75 66 20 3d 20 28 69      p->nBuf = (i
ea60: 6e 74 29 28 28 75 38 20 2a 29 7a 4f 75 74 20 2d  nt)((u8 *)zOut -
ea70: 20 70 2d 3e 61 42 75 66 29 3b 0a 20 20 7d 0a 7d   p->aBuf);.  }.}
ea80: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
ea90: 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70  ction is a no-op
eaa0: 20 69 66 20 2a 70 52 63 20 69 73 20 6f 74 68 65   if *pRc is othe
eab0: 72 20 74 68 61 6e 20 53 51 4c 49 54 45 5f 4f 4b  r than SQLITE_OK
eac0: 20 77 68 65 6e 20 69 74 20 69 73 0a 2a 2a 20 63   when it is.** c
ead0: 61 6c 6c 65 64 2e 20 4f 74 68 65 72 77 73 65 2c  alled. Otherwse,
eae0: 20 69 74 20 61 70 70 65 6e 64 73 20 74 68 65 20   it appends the 
eaf0: 73 65 72 69 61 6c 69 7a 65 64 20 76 65 72 73 69  serialized versi
eb00: 6f 6e 20 6f 66 20 74 68 65 20 76 61 6c 75 65 20  on of the value 
eb10: 73 74 6f 72 65 64 0a 2a 2a 20 69 6e 20 63 6f 6c  stored.** in col
eb20: 75 6d 6e 20 69 43 6f 6c 20 6f 66 20 74 68 65 20  umn iCol of the 
eb30: 72 6f 77 20 74 68 61 74 20 53 51 4c 20 73 74 61  row that SQL sta
eb40: 74 65 6d 65 6e 74 20 70 53 74 6d 74 20 63 75 72  tement pStmt cur
eb50: 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73 0a 2a 2a  rently points.**
eb60: 20 74 6f 20 74 6f 20 74 68 65 20 62 75 66 66 65   to to the buffe
eb70: 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  r..*/.static voi
eb80: 64 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 43  d sessionAppendC
eb90: 6f 6c 28 0a 20 20 53 65 73 73 69 6f 6e 42 75 66  ol(.  SessionBuf
eba0: 66 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20  fer *p,         
ebb0: 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
ebc0: 74 6f 20 61 70 70 65 6e 64 20 74 6f 20 2a 2f 0a  to append to */.
ebd0: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
ebe0: 70 53 74 6d 74 2c 20 20 20 20 20 20 20 20 20 20  pStmt,          
ebf0: 20 20 2f 2a 20 48 61 6e 64 6c 65 20 70 6f 69 6e    /* Handle poin
ec00: 74 69 6e 67 20 74 6f 20 72 6f 77 20 63 6f 6e 74  ting to row cont
ec10: 61 69 6e 69 6e 67 20 76 61 6c 75 65 20 2a 2f 0a  aining value */.
ec20: 20 20 69 6e 74 20 69 43 6f 6c 2c 20 20 20 20 20    int iCol,     
ec30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ec40: 20 20 2f 2a 20 43 6f 6c 75 6d 6e 20 74 6f 20 72    /* Column to r
ec50: 65 61 64 20 76 61 6c 75 65 20 66 72 6f 6d 20 2a  ead value from *
ec60: 2f 0a 20 20 69 6e 74 20 2a 70 52 63 20 20 20 20  /.  int *pRc    
ec70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ec80: 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 45      /* IN/OUT: E
ec90: 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 29 7b 0a  rror code */.){.
eca0: 20 20 69 66 28 20 2a 70 52 63 3d 3d 53 51 4c 49    if( *pRc==SQLI
ecb0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74  TE_OK ){.    int
ecc0: 20 65 54 79 70 65 20 3d 20 73 71 6c 69 74 65 33   eType = sqlite3
ecd0: 5f 63 6f 6c 75 6d 6e 5f 74 79 70 65 28 70 53 74  _column_type(pSt
ece0: 6d 74 2c 20 69 43 6f 6c 29 3b 0a 20 20 20 20 73  mt, iCol);.    s
ecf0: 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65  essionAppendByte
ed00: 28 70 2c 20 28 75 38 29 65 54 79 70 65 2c 20 70  (p, (u8)eType, p
ed10: 52 63 29 3b 0a 20 20 20 20 69 66 28 20 65 54 79  Rc);.    if( eTy
ed20: 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47  pe==SQLITE_INTEG
ed30: 45 52 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c  ER || eType==SQL
ed40: 49 54 45 5f 46 4c 4f 41 54 20 29 7b 0a 20 20 20  ITE_FLOAT ){.   
ed50: 20 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34     sqlite3_int64
ed60: 20 69 3b 0a 20 20 20 20 20 20 75 38 20 61 42 75   i;.      u8 aBu
ed70: 66 5b 38 5d 3b 0a 20 20 20 20 20 20 69 66 28 20  f[8];.      if( 
ed80: 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e  eType==SQLITE_IN
ed90: 54 45 47 45 52 20 29 7b 0a 20 20 20 20 20 20 20  TEGER ){.       
eda0: 20 69 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c   i = sqlite3_col
edb0: 75 6d 6e 5f 69 6e 74 36 34 28 70 53 74 6d 74 2c  umn_int64(pStmt,
edc0: 20 69 43 6f 6c 29 3b 0a 20 20 20 20 20 20 7d 65   iCol);.      }e
edd0: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 64 6f 75  lse{.        dou
ede0: 62 6c 65 20 72 20 3d 20 73 71 6c 69 74 65 33 5f  ble r = sqlite3_
edf0: 63 6f 6c 75 6d 6e 5f 64 6f 75 62 6c 65 28 70 53  column_double(pS
ee00: 74 6d 74 2c 20 69 43 6f 6c 29 3b 0a 20 20 20 20  tmt, iCol);.    
ee10: 20 20 20 20 6d 65 6d 63 70 79 28 26 69 2c 20 26      memcpy(&i, &
ee20: 72 2c 20 38 29 3b 0a 20 20 20 20 20 20 7d 0a 20  r, 8);.      }. 
ee30: 20 20 20 20 20 73 65 73 73 69 6f 6e 50 75 74 49       sessionPutI
ee40: 36 34 28 61 42 75 66 2c 20 69 29 3b 0a 20 20 20  64(aBuf, i);.   
ee50: 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
ee60: 42 6c 6f 62 28 70 2c 20 61 42 75 66 2c 20 38 2c  Blob(p, aBuf, 8,
ee70: 20 70 52 63 29 3b 0a 20 20 20 20 7d 0a 20 20 20   pRc);.    }.   
ee80: 20 69 66 28 20 65 54 79 70 65 3d 3d 53 51 4c 49   if( eType==SQLI
ee90: 54 45 5f 42 4c 4f 42 20 7c 7c 20 65 54 79 70 65  TE_BLOB || eType
eea0: 3d 3d 53 51 4c 49 54 45 5f 54 45 58 54 20 29 7b  ==SQLITE_TEXT ){
eeb0: 0a 20 20 20 20 20 20 75 38 20 2a 7a 3b 0a 20 20  .      u8 *z;.  
eec0: 20 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20      int nByte;. 
eed0: 20 20 20 20 20 69 66 28 20 65 54 79 70 65 3d 3d       if( eType==
eee0: 53 51 4c 49 54 45 5f 42 4c 4f 42 20 29 7b 0a 20  SQLITE_BLOB ){. 
eef0: 20 20 20 20 20 20 20 7a 20 3d 20 28 75 38 20 2a         z = (u8 *
ef00: 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f  )sqlite3_column_
ef10: 62 6c 6f 62 28 70 53 74 6d 74 2c 20 69 43 6f 6c  blob(pStmt, iCol
ef20: 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  );.      }else{.
ef30: 20 20 20 20 20 20 20 20 7a 20 3d 20 28 75 38 20          z = (u8 
ef40: 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  *)sqlite3_column
ef50: 5f 74 65 78 74 28 70 53 74 6d 74 2c 20 69 43 6f  _text(pStmt, iCo
ef60: 6c 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  l);.      }.    
ef70: 20 20 6e 42 79 74 65 20 3d 20 73 71 6c 69 74 65    nByte = sqlite
ef80: 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70  3_column_bytes(p
ef90: 53 74 6d 74 2c 20 69 43 6f 6c 29 3b 0a 20 20 20  Stmt, iCol);.   
efa0: 20 20 20 69 66 28 20 7a 20 7c 7c 20 28 65 54 79     if( z || (eTy
efb0: 70 65 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 20  pe==SQLITE_BLOB 
efc0: 26 26 20 6e 42 79 74 65 3d 3d 30 29 20 29 7b 0a  && nByte==0) ){.
efd0: 20 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41          sessionA
efe0: 70 70 65 6e 64 56 61 72 69 6e 74 28 70 2c 20 6e  ppendVarint(p, n
eff0: 42 79 74 65 2c 20 70 52 63 29 3b 0a 20 20 20 20  Byte, pRc);.    
f000: 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e      sessionAppen
f010: 64 42 6c 6f 62 28 70 2c 20 7a 2c 20 6e 42 79 74  dBlob(p, z, nByt
f020: 65 2c 20 70 52 63 29 3b 0a 20 20 20 20 20 20 7d  e, pRc);.      }
f030: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 2a 70  else{.        *p
f040: 52 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  Rc = SQLITE_NOME
f050: 4d 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  M;.      }.    }
f060: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 0a 2a 2a  .  }.}../*.**.**
f070: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 61   This function a
f080: 70 70 65 6e 64 73 20 61 6e 20 75 70 64 61 74 65  ppends an update
f090: 20 63 68 61 6e 67 65 20 74 6f 20 74 68 65 20 62   change to the b
f0a0: 75 66 66 65 72 20 28 73 65 65 20 74 68 65 20 63  uffer (see the c
f0b0: 6f 6d 6d 65 6e 74 73 20 0a 2a 2a 20 75 6e 64 65  omments .** unde
f0c0: 72 20 22 43 48 41 4e 47 45 53 45 54 20 46 4f 52  r "CHANGESET FOR
f0d0: 4d 41 54 22 20 61 74 20 74 68 65 20 74 6f 70 20  MAT" at the top 
f0e0: 6f 66 20 74 68 65 20 66 69 6c 65 29 2e 20 41 6e  of the file). An
f0f0: 20 75 70 64 61 74 65 20 63 68 61 6e 67 65 20 0a   update change .
f100: 2a 2a 20 63 6f 6e 73 69 73 74 73 20 6f 66 3a 0a  ** consists of:.
f110: 2a 2a 0a 2a 2a 20 20 20 31 20 62 79 74 65 3a 20  **.**   1 byte: 
f120: 20 53 51 4c 49 54 45 5f 55 50 44 41 54 45 20 28   SQLITE_UPDATE (
f130: 30 78 31 37 29 0a 2a 2a 20 20 20 6e 20 62 79 74  0x17).**   n byt
f140: 65 73 3a 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64  es: old.* record
f150: 20 28 73 65 65 20 52 45 43 4f 52 44 20 46 4f 52   (see RECORD FOR
f160: 4d 41 54 29 0a 2a 2a 20 20 20 6d 20 62 79 74 65  MAT).**   m byte
f170: 73 3a 20 6e 65 77 2e 2a 20 72 65 63 6f 72 64 20  s: new.* record 
f180: 28 73 65 65 20 52 45 43 4f 52 44 20 46 4f 52 4d  (see RECORD FORM
f190: 41 54 29 0a 2a 2a 0a 2a 2a 20 54 68 65 20 53 65  AT).**.** The Se
f1a0: 73 73 69 6f 6e 43 68 61 6e 67 65 20 6f 62 6a 65  ssionChange obje
f1b0: 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68 65  ct passed as the
f1c0: 20 74 68 69 72 64 20 61 72 67 75 6d 65 6e 74 20   third argument 
f1d0: 63 6f 6e 74 61 69 6e 73 20 74 68 65 0a 2a 2a 20  contains the.** 
f1e0: 76 61 6c 75 65 73 20 74 68 61 74 20 77 65 72 65  values that were
f1f0: 20 73 74 6f 72 65 64 20 69 6e 20 74 68 65 20 72   stored in the r
f200: 6f 77 20 77 68 65 6e 20 74 68 65 20 73 65 73 73  ow when the sess
f210: 69 6f 6e 20 62 65 67 61 6e 20 28 74 68 65 20 6f  ion began (the o
f220: 6c 64 2e 2a 0a 2a 2a 20 76 61 6c 75 65 73 29 2e  ld.*.** values).
f230: 20 54 68 65 20 73 74 61 74 65 6d 65 6e 74 20 68   The statement h
f240: 61 6e 64 6c 65 20 70 61 73 73 65 64 20 61 73 20  andle passed as 
f250: 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d  the second argum
f260: 65 6e 74 20 70 6f 69 6e 74 73 0a 2a 2a 20 61 74  ent points.** at
f270: 20 74 68 65 20 63 75 72 72 65 6e 74 20 76 65 72   the current ver
f280: 73 69 6f 6e 20 6f 66 20 74 68 65 20 72 6f 77 20  sion of the row 
f290: 28 74 68 65 20 6e 65 77 2e 2a 20 76 61 6c 75 65  (the new.* value
f2a0: 73 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6c 6c  s)..**.** If all
f2b0: 20 6f 66 20 74 68 65 20 6f 6c 64 2e 2a 20 76 61   of the old.* va
f2c0: 6c 75 65 73 20 61 72 65 20 65 71 75 61 6c 20 74  lues are equal t
f2d0: 6f 20 74 68 65 69 72 20 63 6f 72 72 65 73 70 6f  o their correspo
f2e0: 6e 64 69 6e 67 20 6e 65 77 2e 2a 20 76 61 6c 75  nding new.* valu
f2f0: 65 0a 2a 2a 20 28 69 2e 65 2e 20 6e 6f 74 68 69  e.** (i.e. nothi
f300: 6e 67 20 68 61 73 20 63 68 61 6e 67 65 64 29 2c  ng has changed),
f310: 20 74 68 65 6e 20 6e 6f 20 64 61 74 61 20 61 74   then no data at
f320: 20 61 6c 6c 20 69 73 20 61 70 70 65 6e 64 65 64   all is appended
f330: 20 74 6f 20 74 68 65 20 62 75 66 66 65 72 2e 0a   to the buffer..
f340: 2a 2a 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c  **.** Otherwise,
f350: 20 74 68 65 20 6f 6c 64 2e 2a 20 72 65 63 6f 72   the old.* recor
f360: 64 20 63 6f 6e 74 61 69 6e 73 20 61 6c 6c 20 70  d contains all p
f370: 72 69 6d 61 72 79 20 6b 65 79 20 76 61 6c 75 65  rimary key value
f380: 73 20 61 6e 64 20 74 68 65 20 0a 2a 2a 20 6f 72  s and the .** or
f390: 69 67 69 6e 61 6c 20 76 61 6c 75 65 73 20 6f 66  iginal values of
f3a0: 20 61 6e 79 20 66 69 65 6c 64 73 20 74 68 61 74   any fields that
f3b0: 20 68 61 76 65 20 62 65 65 6e 20 6d 6f 64 69 66   have been modif
f3c0: 69 65 64 2e 20 54 68 65 20 6e 65 77 2e 2a 20 72  ied. The new.* r
f3d0: 65 63 6f 72 64 20 0a 2a 2a 20 63 6f 6e 74 61 69  ecord .** contai
f3e0: 6e 73 20 74 68 65 20 6e 65 77 20 76 61 6c 75 65  ns the new value
f3f0: 73 20 6f 66 20 6f 6e 6c 79 20 74 68 6f 73 65 20  s of only those 
f400: 66 69 65 6c 64 73 20 74 68 61 74 20 68 61 76 65  fields that have
f410: 20 62 65 65 6e 20 6d 6f 64 69 66 69 65 64 2e 0a   been modified..
f420: 2a 2f 20 0a 73 74 61 74 69 63 20 69 6e 74 20 73  */ .static int s
f430: 65 73 73 69 6f 6e 41 70 70 65 6e 64 55 70 64 61  essionAppendUpda
f440: 74 65 28 0a 20 20 53 65 73 73 69 6f 6e 42 75 66  te(.  SessionBuf
f450: 66 65 72 20 2a 70 42 75 66 2c 20 20 20 20 20 20  fer *pBuf,      
f460: 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
f470: 74 6f 20 61 70 70 65 6e 64 20 74 6f 20 2a 2f 0a  to append to */.
f480: 20 20 69 6e 74 20 62 50 61 74 63 68 73 65 74 2c    int bPatchset,
f490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f4a0: 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 22 70    /* True for "p
f4b0: 61 74 63 68 73 65 74 22 2c 20 30 20 66 6f 72 20  atchset", 0 for 
f4c0: 22 63 68 61 6e 67 65 73 65 74 22 20 2a 2f 0a 20  "changeset" */. 
f4d0: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
f4e0: 53 74 6d 74 2c 20 20 20 20 20 20 20 20 20 20 20  Stmt,           
f4f0: 20 2f 2a 20 53 74 61 74 65 6d 65 6e 74 20 68 61   /* Statement ha
f500: 6e 64 6c 65 20 70 6f 69 6e 74 69 6e 67 20 61 74  ndle pointing at
f510: 20 6e 65 77 20 72 6f 77 20 2a 2f 0a 20 20 53 65   new row */.  Se
f520: 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 70 2c 20  ssionChange *p, 
f530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
f540: 20 4f 62 6a 65 63 74 20 63 6f 6e 74 61 69 6e 69   Object containi
f550: 6e 67 20 6f 6c 64 20 76 61 6c 75 65 73 20 2a 2f  ng old values */
f560: 0a 20 20 75 38 20 2a 61 62 50 4b 20 20 20 20 20  .  u8 *abPK     
f570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f580: 20 20 20 2f 2a 20 42 6f 6f 6c 65 61 6e 20 61 72     /* Boolean ar
f590: 72 61 79 20 2d 20 74 72 75 65 20 66 6f 72 20 50  ray - true for P
f5a0: 4b 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 29 7b 0a  K columns */.){.
f5b0: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
f5c0: 45 5f 4f 4b 3b 0a 20 20 53 65 73 73 69 6f 6e 42  E_OK;.  SessionB
f5d0: 75 66 66 65 72 20 62 75 66 32 20 3d 20 7b 30 2c  uffer buf2 = {0,
f5e0: 30 2c 30 7d 3b 20 2f 2a 20 42 75 66 66 65 72 20  0,0}; /* Buffer 
f5f0: 74 6f 20 61 63 63 75 6d 75 6c 61 74 65 20 6e 65  to accumulate ne
f600: 77 2e 2a 20 72 65 63 6f 72 64 20 69 6e 20 2a 2f  w.* record in */
f610: 0a 20 20 69 6e 74 20 62 4e 6f 6f 70 20 3d 20 31  .  int bNoop = 1
f620: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
f630: 20 2f 2a 20 53 65 74 20 74 6f 20 7a 65 72 6f 20   /* Set to zero 
f640: 69 66 20 61 6e 79 20 76 61 6c 75 65 73 20 61 72  if any values ar
f650: 65 20 6d 6f 64 69 66 69 65 64 20 2a 2f 0a 20 20  e modified */.  
f660: 69 6e 74 20 6e 52 65 77 69 6e 64 20 3d 20 70 42  int nRewind = pB
f670: 75 66 2d 3e 6e 42 75 66 3b 20 20 20 20 20 2f 2a  uf->nBuf;     /*
f680: 20 53 65 74 20 74 6f 20 7a 65 72 6f 20 69 66 20   Set to zero if 
f690: 61 6e 79 20 76 61 6c 75 65 73 20 61 72 65 20 6d  any values are m
f6a0: 6f 64 69 66 69 65 64 20 2a 2f 0a 20 20 69 6e 74  odified */.  int
f6b0: 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
f6c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73             /* Us
f6d0: 65 64 20 74 6f 20 69 74 65 72 61 74 65 20 74 68  ed to iterate th
f6e0: 72 6f 75 67 68 20 63 6f 6c 75 6d 6e 73 20 2a 2f  rough columns */
f6f0: 0a 20 20 75 38 20 2a 70 43 73 72 20 3d 20 70 2d  .  u8 *pCsr = p-
f700: 3e 61 52 65 63 6f 72 64 3b 20 20 20 20 20 20 20  >aRecord;       
f710: 20 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72   /* Used to iter
f720: 61 74 65 20 74 68 72 6f 75 67 68 20 6f 6c 64 2e  ate through old.
f730: 2a 20 76 61 6c 75 65 73 20 2a 2f 0a 0a 20 20 73  * values */..  s
f740: 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65  essionAppendByte
f750: 28 70 42 75 66 2c 20 53 51 4c 49 54 45 5f 55 50  (pBuf, SQLITE_UP
f760: 44 41 54 45 2c 20 26 72 63 29 3b 0a 20 20 73 65  DATE, &rc);.  se
f770: 73 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28  ssionAppendByte(
f780: 70 42 75 66 2c 20 70 2d 3e 62 49 6e 64 69 72 65  pBuf, p->bIndire
f790: 63 74 2c 20 26 72 63 29 3b 0a 20 20 66 6f 72 28  ct, &rc);.  for(
f7a0: 69 3d 30 3b 20 69 3c 73 71 6c 69 74 65 33 5f 63  i=0; i<sqlite3_c
f7b0: 6f 6c 75 6d 6e 5f 63 6f 75 6e 74 28 70 53 74 6d  olumn_count(pStm
f7c0: 74 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e  t); i++){.    in
f7d0: 74 20 62 43 68 61 6e 67 65 64 20 3d 20 30 3b 0a  t bChanged = 0;.
f7e0: 20 20 20 20 69 6e 74 20 6e 41 64 76 61 6e 63 65      int nAdvance
f7f0: 3b 0a 20 20 20 20 69 6e 74 20 65 54 79 70 65 20  ;.    int eType 
f800: 3d 20 2a 70 43 73 72 3b 0a 20 20 20 20 73 77 69  = *pCsr;.    swi
f810: 74 63 68 28 20 65 54 79 70 65 20 29 7b 0a 20 20  tch( eType ){.  
f820: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
f830: 4e 55 4c 4c 3a 0a 20 20 20 20 20 20 20 20 6e 41  NULL:.        nA
f840: 64 76 61 6e 63 65 20 3d 20 31 3b 0a 20 20 20 20  dvance = 1;.    
f850: 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f      if( sqlite3_
f860: 63 6f 6c 75 6d 6e 5f 74 79 70 65 28 70 53 74 6d  column_type(pStm
f870: 74 2c 20 69 29 21 3d 53 51 4c 49 54 45 5f 4e 55  t, i)!=SQLITE_NU
f880: 4c 4c 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  LL ){.          
f890: 62 43 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20 20  bChanged = 1;.  
f8a0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
f8b0: 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63 61  break;..      ca
f8c0: 73 65 20 53 51 4c 49 54 45 5f 46 4c 4f 41 54 3a  se SQLITE_FLOAT:
f8d0: 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
f8e0: 54 45 5f 49 4e 54 45 47 45 52 3a 20 7b 0a 20 20  TE_INTEGER: {.  
f8f0: 20 20 20 20 20 20 6e 41 64 76 61 6e 63 65 20 3d        nAdvance =
f900: 20 39 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20   9;.        if( 
f910: 65 54 79 70 65 3d 3d 73 71 6c 69 74 65 33 5f 63  eType==sqlite3_c
f920: 6f 6c 75 6d 6e 5f 74 79 70 65 28 70 53 74 6d 74  olumn_type(pStmt
f930: 2c 20 69 29 20 29 7b 0a 20 20 20 20 20 20 20 20  , i) ){.        
f940: 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20    sqlite3_int64 
f950: 69 56 61 6c 20 3d 20 73 65 73 73 69 6f 6e 47 65  iVal = sessionGe
f960: 74 49 36 34 28 26 70 43 73 72 5b 31 5d 29 3b 0a  tI64(&pCsr[1]);.
f970: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 65 54            if( eT
f980: 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45  ype==SQLITE_INTE
f990: 47 45 52 20 29 7b 0a 20 20 20 20 20 20 20 20 20  GER ){.         
f9a0: 20 20 20 69 66 28 20 69 56 61 6c 3d 3d 73 71 6c     if( iVal==sql
f9b0: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36  ite3_column_int6
f9c0: 34 28 70 53 74 6d 74 2c 20 69 29 20 29 20 62 72  4(pStmt, i) ) br
f9d0: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  eak;.          }
f9e0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20  else{.          
f9f0: 20 20 64 6f 75 62 6c 65 20 64 56 61 6c 3b 0a 20    double dVal;. 
fa00: 20 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63 70             memcp
fa10: 79 28 26 64 56 61 6c 2c 20 26 69 56 61 6c 2c 20  y(&dVal, &iVal, 
fa20: 38 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  8);.            
fa30: 69 66 28 20 64 56 61 6c 3d 3d 73 71 6c 69 74 65  if( dVal==sqlite
fa40: 33 5f 63 6f 6c 75 6d 6e 5f 64 6f 75 62 6c 65 28  3_column_double(
fa50: 70 53 74 6d 74 2c 20 69 29 20 29 20 62 72 65 61  pStmt, i) ) brea
fa60: 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20  k;.          }. 
fa70: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
fa80: 20 62 43 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20   bChanged = 1;. 
fa90: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
faa0: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 64 65 66      }..      def
fab0: 61 75 6c 74 3a 20 7b 0a 20 20 20 20 20 20 20 20  ault: {.        
fac0: 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20 20 20  int nByte;.     
fad0: 20 20 20 69 6e 74 20 6e 48 64 72 20 3d 20 31 20     int nHdr = 1 
fae0: 2b 20 73 65 73 73 69 6f 6e 56 61 72 69 6e 74 47  + sessionVarintG
faf0: 65 74 28 26 70 43 73 72 5b 31 5d 2c 20 26 6e 42  et(&pCsr[1], &nB
fb00: 79 74 65 29 3b 0a 20 20 20 20 20 20 20 20 61 73  yte);.        as
fb10: 73 65 72 74 28 20 65 54 79 70 65 3d 3d 53 51 4c  sert( eType==SQL
fb20: 49 54 45 5f 54 45 58 54 20 7c 7c 20 65 54 79 70  ITE_TEXT || eTyp
fb30: 65 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 20 29  e==SQLITE_BLOB )
fb40: 3b 0a 20 20 20 20 20 20 20 20 6e 41 64 76 61 6e  ;.        nAdvan
fb50: 63 65 20 3d 20 6e 48 64 72 20 2b 20 6e 42 79 74  ce = nHdr + nByt
fb60: 65 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 65  e;.        if( e
fb70: 54 79 70 65 3d 3d 73 71 6c 69 74 65 33 5f 63 6f  Type==sqlite3_co
fb80: 6c 75 6d 6e 5f 74 79 70 65 28 70 53 74 6d 74 2c  lumn_type(pStmt,
fb90: 20 69 29 20 0a 20 20 20 20 20 20 20 20 20 26 26   i) .         &&
fba0: 20 6e 42 79 74 65 3d 3d 73 71 6c 69 74 65 33 5f   nByte==sqlite3_
fbb0: 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70 53 74  column_bytes(pSt
fbc0: 6d 74 2c 20 69 29 20 0a 20 20 20 20 20 20 20 20  mt, i) .        
fbd0: 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 26 70   && 0==memcmp(&p
fbe0: 43 73 72 5b 6e 48 64 72 5d 2c 20 73 71 6c 69 74  Csr[nHdr], sqlit
fbf0: 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f 62 28 70  e3_column_blob(p
fc00: 53 74 6d 74 2c 20 69 29 2c 20 6e 42 79 74 65 29  Stmt, i), nByte)
fc10: 0a 20 20 20 20 20 20 20 20 29 7b 0a 20 20 20 20  .        ){.    
fc20: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
fc30: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 62       }.        b
fc40: 43 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20 20 20  Changed = 1;.   
fc50: 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20     }.    }..    
fc60: 2f 2a 20 49 66 20 61 74 20 6c 65 61 73 74 20 6f  /* If at least o
fc70: 6e 65 20 66 69 65 6c 64 20 68 61 73 20 62 65 65  ne field has bee
fc80: 6e 20 6d 6f 64 69 66 69 65 64 2c 20 74 68 69 73  n modified, this
fc90: 20 69 73 20 6e 6f 74 20 61 20 6e 6f 2d 6f 70 2e   is not a no-op.
fca0: 20 2a 2f 0a 20 20 20 20 69 66 28 20 62 43 68 61   */.    if( bCha
fcb0: 6e 67 65 64 20 29 20 62 4e 6f 6f 70 20 3d 20 30  nged ) bNoop = 0
fcc0: 3b 0a 0a 20 20 20 20 2f 2a 20 41 64 64 20 61 20  ;..    /* Add a 
fcd0: 66 69 65 6c 64 20 74 6f 20 74 68 65 20 6f 6c 64  field to the old
fce0: 2e 2a 20 72 65 63 6f 72 64 2e 20 54 68 69 73 20  .* record. This 
fcf0: 69 73 20 6f 6d 69 74 74 65 64 20 69 66 20 74 68  is omitted if th
fd00: 69 73 20 6d 6f 64 75 6c 65 73 20 69 73 0a 20 20  is modules is.  
fd10: 20 20 2a 2a 20 63 75 72 72 65 6e 74 6c 79 20 67    ** currently g
fd20: 65 6e 65 72 61 74 69 6e 67 20 61 20 70 61 74 63  enerating a patc
fd30: 68 73 65 74 2e 20 2a 2f 0a 20 20 20 20 69 66 28  hset. */.    if(
fd40: 20 62 50 61 74 63 68 73 65 74 3d 3d 30 20 29 7b   bPatchset==0 ){
fd50: 0a 20 20 20 20 20 20 69 66 28 20 62 43 68 61 6e  .      if( bChan
fd60: 67 65 64 20 7c 7c 20 61 62 50 4b 5b 69 5d 20 29  ged || abPK[i] )
fd70: 7b 0a 20 20 20 20 20 20 20 20 73 65 73 73 69 6f  {.        sessio
fd80: 6e 41 70 70 65 6e 64 42 6c 6f 62 28 70 42 75 66  nAppendBlob(pBuf
fd90: 2c 20 70 43 73 72 2c 20 6e 41 64 76 61 6e 63 65  , pCsr, nAdvance
fda0: 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 7d 65  , &rc);.      }e
fdb0: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 73 65 73  lse{.        ses
fdc0: 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 70  sionAppendByte(p
fdd0: 42 75 66 2c 20 30 2c 20 26 72 63 29 3b 0a 20 20  Buf, 0, &rc);.  
fde0: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20      }.    }..   
fdf0: 20 2f 2a 20 41 64 64 20 61 20 66 69 65 6c 64 20   /* Add a field 
fe00: 74 6f 20 74 68 65 20 6e 65 77 2e 2a 20 72 65 63  to the new.* rec
fe10: 6f 72 64 2e 20 4f 72 20 74 68 65 20 6f 6e 6c 79  ord. Or the only
fe20: 20 72 65 63 6f 72 64 20 69 66 20 63 75 72 72 65   record if curre
fe30: 6e 74 6c 79 0a 20 20 20 20 2a 2a 20 67 65 6e 65  ntly.    ** gene
fe40: 72 61 74 69 6e 67 20 61 20 70 61 74 63 68 73 65  rating a patchse
fe50: 74 2e 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 62  t.  */.    if( b
fe60: 43 68 61 6e 67 65 64 20 7c 7c 20 28 62 50 61 74  Changed || (bPat
fe70: 63 68 73 65 74 20 26 26 20 61 62 50 4b 5b 69 5d  chset && abPK[i]
fe80: 29 20 29 7b 0a 20 20 20 20 20 20 73 65 73 73 69  ) ){.      sessi
fe90: 6f 6e 41 70 70 65 6e 64 43 6f 6c 28 26 62 75 66  onAppendCol(&buf
fea0: 32 2c 20 70 53 74 6d 74 2c 20 69 2c 20 26 72 63  2, pStmt, i, &rc
feb0: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
fec0: 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e      sessionAppen
fed0: 64 42 79 74 65 28 26 62 75 66 32 2c 20 30 2c 20  dByte(&buf2, 0, 
fee0: 26 72 63 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  &rc);.    }..   
fef0: 20 70 43 73 72 20 2b 3d 20 6e 41 64 76 61 6e 63   pCsr += nAdvanc
ff00: 65 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 62 4e  e;.  }..  if( bN
ff10: 6f 6f 70 20 29 7b 0a 20 20 20 20 70 42 75 66 2d  oop ){.    pBuf-
ff20: 3e 6e 42 75 66 20 3d 20 6e 52 65 77 69 6e 64 3b  >nBuf = nRewind;
ff30: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 65  .  }else{.    se
ff40: 73 73 69 6f 6e 41 70 70 65 6e 64 42 6c 6f 62 28  ssionAppendBlob(
ff50: 70 42 75 66 2c 20 62 75 66 32 2e 61 42 75 66 2c  pBuf, buf2.aBuf,
ff60: 20 62 75 66 32 2e 6e 42 75 66 2c 20 26 72 63 29   buf2.nBuf, &rc)
ff70: 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  ;.  }.  sqlite3_
ff80: 66 72 65 65 28 62 75 66 32 2e 61 42 75 66 29 3b  free(buf2.aBuf);
ff90: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
ffa0: 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 61  ../*.** Append a
ffb0: 20 44 45 4c 45 54 45 20 63 68 61 6e 67 65 20 74   DELETE change t
ffc0: 6f 20 74 68 65 20 62 75 66 66 65 72 20 70 61 73  o the buffer pas
ffd0: 73 65 64 20 61 73 20 74 68 65 20 66 69 72 73 74  sed as the first
ffe0: 20 61 72 67 75 6d 65 6e 74 2e 20 55 73 65 0a 2a   argument. Use.*
fff0: 2a 20 74 68 65 20 63 68 61 6e 67 65 73 65 74 20  * the changeset 
10000 66 6f 72 6d 61 74 20 69 66 20 61 72 67 75 6d 65  format if argume
10010 6e 74 20 62 50 61 74 63 68 73 65 74 20 69 73 20  nt bPatchset is 
10020 7a 65 72 6f 2c 20 6f 72 20 74 68 65 20 70 61 74  zero, or the pat
10030 63 68 73 65 74 0a 2a 2a 20 66 6f 72 6d 61 74 20  chset.** format 
10040 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74  otherwise..*/.st
10050 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e  atic int session
10060 41 70 70 65 6e 64 44 65 6c 65 74 65 28 0a 20 20  AppendDelete(.  
10070 53 65 73 73 69 6f 6e 42 75 66 66 65 72 20 2a 70  SessionBuffer *p
10080 42 75 66 2c 20 20 20 20 20 20 20 20 20 20 20 20  Buf,            
10090 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 61 70 70  /* Buffer to app
100a0 65 6e 64 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20  end to */.  int 
100b0 62 50 61 74 63 68 73 65 74 2c 20 20 20 20 20 20  bPatchset,      
100c0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
100d0 72 75 65 20 66 6f 72 20 22 70 61 74 63 68 73 65  rue for "patchse
100e0 74 22 2c 20 30 20 66 6f 72 20 22 63 68 61 6e 67  t", 0 for "chang
100f0 65 73 65 74 22 20 2a 2f 0a 20 20 53 65 73 73 69  eset" */.  Sessi
10100 6f 6e 43 68 61 6e 67 65 20 2a 70 2c 20 20 20 20  onChange *p,    
10110 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 62             /* Ob
10120 6a 65 63 74 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ject containing 
10130 6f 6c 64 20 76 61 6c 75 65 73 20 2a 2f 0a 20 20  old values */.  
10140 69 6e 74 20 6e 43 6f 6c 2c 20 20 20 20 20 20 20  int nCol,       
10150 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10160 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c  /* Number of col
10170 75 6d 6e 73 20 69 6e 20 74 61 62 6c 65 20 2a 2f  umns in table */
10180 0a 20 20 75 38 20 2a 61 62 50 4b 20 20 20 20 20  .  u8 *abPK     
10190 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
101a0 20 20 20 2f 2a 20 42 6f 6f 6c 65 61 6e 20 61 72     /* Boolean ar
101b0 72 61 79 20 2d 20 74 72 75 65 20 66 6f 72 20 50  ray - true for P
101c0 4b 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 29 7b 0a  K columns */.){.
101d0 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
101e0 45 5f 4f 4b 3b 0a 0a 20 20 73 65 73 73 69 6f 6e  E_OK;..  session
101f0 41 70 70 65 6e 64 42 79 74 65 28 70 42 75 66 2c  AppendByte(pBuf,
10200 20 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 2c 20   SQLITE_DELETE, 
10210 26 72 63 29 3b 0a 20 20 73 65 73 73 69 6f 6e 41  &rc);.  sessionA
10220 70 70 65 6e 64 42 79 74 65 28 70 42 75 66 2c 20  ppendByte(pBuf, 
10230 70 2d 3e 62 49 6e 64 69 72 65 63 74 2c 20 26 72  p->bIndirect, &r
10240 63 29 3b 0a 0a 20 20 69 66 28 20 62 50 61 74 63  c);..  if( bPatc
10250 68 73 65 74 3d 3d 30 20 29 7b 0a 20 20 20 20 73  hset==0 ){.    s
10260 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 6c 6f 62  essionAppendBlob
10270 28 70 42 75 66 2c 20 70 2d 3e 61 52 65 63 6f 72  (pBuf, p->aRecor
10280 64 2c 20 70 2d 3e 6e 52 65 63 6f 72 64 2c 20 26  d, p->nRecord, &
10290 72 63 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  rc);.  }else{.  
102a0 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 75 38 20    int i;.    u8 
102b0 2a 61 20 3d 20 70 2d 3e 61 52 65 63 6f 72 64 3b  *a = p->aRecord;
102c0 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  .    for(i=0; i<
102d0 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  nCol; i++){.    
102e0 20 20 75 38 20 2a 70 53 74 61 72 74 20 3d 20 61    u8 *pStart = a
102f0 3b 0a 20 20 20 20 20 20 69 6e 74 20 65 54 79 70  ;.      int eTyp
10300 65 20 3d 20 2a 61 2b 2b 3b 0a 0a 20 20 20 20 20  e = *a++;..     
10310 20 73 77 69 74 63 68 28 20 65 54 79 70 65 20 29   switch( eType )
10320 7b 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 30  {.        case 0
10330 3a 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 53  :.        case S
10340 51 4c 49 54 45 5f 4e 55 4c 4c 3a 0a 20 20 20 20  QLITE_NULL:.    
10350 20 20 20 20 20 20 61 73 73 65 72 74 28 20 61 62        assert( ab
10360 50 4b 5b 69 5d 3d 3d 30 20 29 3b 0a 20 20 20 20  PK[i]==0 );.    
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 63 61 73 65 20 53 51 4c 49 54        case SQLIT
10390 45 5f 46 4c 4f 41 54 3a 0a 20 20 20 20 20 20 20  E_FLOAT:.       
103a0 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 54   case SQLITE_INT
103b0 45 47 45 52 3a 0a 20 20 20 20 20 20 20 20 20 20  EGER:.          
103c0 61 20 2b 3d 20 38 3b 0a 20 20 20 20 20 20 20 20  a += 8;.        
103d0 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20    break;..      
103e0 20 20 64 65 66 61 75 6c 74 3a 20 7b 0a 20 20 20    default: {.   
103f0 20 20 20 20 20 20 20 69 6e 74 20 6e 3b 0a 20 20         int n;.  
10400 20 20 20 20 20 20 20 20 61 20 2b 3d 20 73 65 73          a += ses
10410 73 69 6f 6e 56 61 72 69 6e 74 47 65 74 28 61 2c  sionVarintGet(a,
10420 20 26 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20   &n);.          
10430 61 20 2b 3d 20 6e 3b 0a 20 20 20 20 20 20 20 20  a += n;.        
10440 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20    break;.       
10450 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20   }.      }.     
10460 20 69 66 28 20 61 62 50 4b 5b 69 5d 20 29 7b 0a   if( abPK[i] ){.
10470 20 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41          sessionA
10480 70 70 65 6e 64 42 6c 6f 62 28 70 42 75 66 2c 20  ppendBlob(pBuf, 
10490 70 53 74 61 72 74 2c 20 28 69 6e 74 29 28 61 2d  pStart, (int)(a-
104a0 70 53 74 61 72 74 29 2c 20 26 72 63 29 3b 0a 20  pStart), &rc);. 
104b0 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
104c0 20 61 73 73 65 72 74 28 20 28 61 20 2d 20 70 2d   assert( (a - p-
104d0 3e 61 52 65 63 6f 72 64 29 3d 3d 70 2d 3e 6e 52  >aRecord)==p->nR
104e0 65 63 6f 72 64 20 29 3b 0a 20 20 7d 0a 0a 20 20  ecord );.  }..  
104f0 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
10500 0a 2a 2a 20 46 6f 72 6d 75 6c 61 74 65 20 61 6e  .** Formulate an
10510 64 20 70 72 65 70 61 72 65 20 61 20 53 45 4c 45  d prepare a SELE
10520 43 54 20 73 74 61 74 65 6d 65 6e 74 20 74 6f 20  CT statement to 
10530 72 65 74 72 69 65 76 65 20 61 20 72 6f 77 20 66  retrieve a row f
10540 72 6f 6d 20 74 61 62 6c 65 0a 2a 2a 20 7a 54 61  rom table.** zTa
10550 62 20 69 6e 20 64 61 74 61 62 61 73 65 20 7a 44  b in database zD
10560 62 20 62 61 73 65 64 20 6f 6e 20 69 74 73 20 70  b based on its p
10570 72 69 6d 61 72 79 20 6b 65 79 2e 20 69 2e 65 2e  rimary key. i.e.
10580 0a 2a 2a 0a 2a 2a 20 20 20 53 45 4c 45 43 54 20  .**.**   SELECT 
10590 2a 20 46 52 4f 4d 20 7a 44 62 2e 7a 54 61 62 20  * FROM zDb.zTab 
105a0 57 48 45 52 45 20 70 6b 31 20 3d 20 3f 20 41 4e  WHERE pk1 = ? AN
105b0 44 20 70 6b 32 20 3d 20 3f 20 41 4e 44 20 2e 2e  D pk2 = ? AND ..
105c0 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
105d0 73 65 73 73 69 6f 6e 53 65 6c 65 63 74 53 74 6d  sessionSelectStm
105e0 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  t(.  sqlite3 *db
105f0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
10600 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
10610 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e   handle */.  con
10620 73 74 20 63 68 61 72 20 2a 7a 44 62 2c 20 20 20  st char *zDb,   
10630 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
10640 44 61 74 61 62 61 73 65 20 6e 61 6d 65 20 2a 2f  Database name */
10650 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
10660 54 61 62 2c 20 20 20 20 20 20 20 20 20 20 20 20  Tab,            
10670 20 20 20 2f 2a 20 54 61 62 6c 65 20 6e 61 6d 65     /* Table name
10680 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c 20   */.  int nCol, 
10690 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
106a0 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
106b0 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 61  of columns in ta
106c0 62 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  ble */.  const c
106d0 68 61 72 20 2a 2a 61 7a 43 6f 6c 2c 20 20 20 20  har **azCol,    
106e0 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65           /* Name
106f0 73 20 6f 66 20 74 61 62 6c 65 20 63 6f 6c 75 6d  s of table colum
10700 6e 73 20 2a 2f 0a 20 20 75 38 20 2a 61 62 50 4b  ns */.  u8 *abPK
10710 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
10720 20 20 20 20 20 20 20 20 2f 2a 20 50 52 49 4d 41          /* PRIMA
10730 52 59 20 4b 45 59 20 20 61 72 72 61 79 20 2a 2f  RY KEY  array */
10740 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
10750 2a 2a 70 70 53 74 6d 74 20 20 20 20 20 20 20 20  **ppStmt        
10760 20 20 20 2f 2a 20 4f 55 54 3a 20 50 72 65 70 61     /* OUT: Prepa
10770 72 65 64 20 53 45 4c 45 43 54 20 73 74 61 74 65  red SELECT state
10780 6d 65 6e 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  ment */.){.  int
10790 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
107a0 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 6f 6e 73  .  int i;.  cons
107b0 74 20 63 68 61 72 20 2a 7a 53 65 70 20 3d 20 22  t char *zSep = "
107c0 22 3b 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66  ";.  SessionBuff
107d0 65 72 20 62 75 66 20 3d 20 7b 30 2c 20 30 2c 20  er buf = {0, 0, 
107e0 30 7d 3b 0a 0a 20 20 73 65 73 73 69 6f 6e 41 70  0};..  sessionAp
107f0 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 53  pendStr(&buf, "S
10800 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 22 2c 20  ELECT * FROM ", 
10810 26 72 63 29 3b 0a 20 20 73 65 73 73 69 6f 6e 41  &rc);.  sessionA
10820 70 70 65 6e 64 49 64 65 6e 74 28 26 62 75 66 2c  ppendIdent(&buf,
10830 20 7a 44 62 2c 20 26 72 63 29 3b 0a 20 20 73 65   zDb, &rc);.  se
10840 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26  ssionAppendStr(&
10850 62 75 66 2c 20 22 2e 22 2c 20 26 72 63 29 3b 0a  buf, ".", &rc);.
10860 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49    sessionAppendI
10870 64 65 6e 74 28 26 62 75 66 2c 20 7a 54 61 62 2c  dent(&buf, zTab,
10880 20 26 72 63 29 3b 0a 20 20 73 65 73 73 69 6f 6e   &rc);.  session
10890 41 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20  AppendStr(&buf, 
108a0 22 20 57 48 45 52 45 20 22 2c 20 26 72 63 29 3b  " WHERE ", &rc);
108b0 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43  .  for(i=0; i<nC
108c0 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66  ol; i++){.    if
108d0 28 20 61 62 50 4b 5b 69 5d 20 29 7b 0a 20 20 20  ( abPK[i] ){.   
108e0 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
108f0 53 74 72 28 26 62 75 66 2c 20 7a 53 65 70 2c 20  Str(&buf, zSep, 
10900 26 72 63 29 3b 0a 20 20 20 20 20 20 73 65 73 73  &rc);.      sess
10910 69 6f 6e 41 70 70 65 6e 64 49 64 65 6e 74 28 26  ionAppendIdent(&
10920 62 75 66 2c 20 61 7a 43 6f 6c 5b 69 5d 2c 20 26  buf, azCol[i], &
10930 72 63 29 3b 0a 20 20 20 20 20 20 73 65 73 73 69  rc);.      sessi
10940 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75 66  onAppendStr(&buf
10950 2c 20 22 20 3d 20 3f 22 2c 20 26 72 63 29 3b 0a  , " = ?", &rc);.
10960 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70        sessionApp
10970 65 6e 64 49 6e 74 65 67 65 72 28 26 62 75 66 2c  endInteger(&buf,
10980 20 69 2b 31 2c 20 26 72 63 29 3b 0a 20 20 20 20   i+1, &rc);.    
10990 20 20 7a 53 65 70 20 3d 20 22 20 41 4e 44 20 22    zSep = " AND "
109a0 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66  ;.    }.  }.  if
109b0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
109c0 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  ){.    rc = sqli
109d0 74 65 33 5f 70 72 65 70 61 72 65 5f 76 32 28 64  te3_prepare_v2(d
109e0 62 2c 20 28 63 68 61 72 20 2a 29 62 75 66 2e 61  b, (char *)buf.a
109f0 42 75 66 2c 20 62 75 66 2e 6e 42 75 66 2c 20 70  Buf, buf.nBuf, p
10a00 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 7d 0a 20  pStmt, 0);.  }. 
10a10 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 62 75   sqlite3_free(bu
10a20 66 2e 61 42 75 66 29 3b 0a 20 20 72 65 74 75 72  f.aBuf);.  retur
10a30 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 42  n rc;.}../*.** B
10a40 69 6e 64 20 74 68 65 20 50 52 49 4d 41 52 59 20  ind the PRIMARY 
10a50 4b 45 59 20 76 61 6c 75 65 73 20 66 72 6f 6d 20  KEY values from 
10a60 74 68 65 20 63 68 61 6e 67 65 20 70 61 73 73 65  the change passe
10a70 64 20 69 6e 20 61 72 67 75 6d 65 6e 74 20 70 43  d in argument pC
10a80 68 61 6e 67 65 0a 2a 2a 20 74 6f 20 74 68 65 20  hange.** to the 
10a90 53 45 4c 45 43 54 20 73 74 61 74 65 6d 65 6e 74  SELECT statement
10aa0 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66   passed as the f
10ab0 69 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 20 54  irst argument. T
10ac0 68 65 20 53 45 4c 45 43 54 20 73 74 61 74 65 6d  he SELECT statem
10ad0 65 6e 74 0a 2a 2a 20 69 73 20 61 73 20 70 72 65  ent.** is as pre
10ae0 70 61 72 65 64 20 62 79 20 66 75 6e 63 74 69 6f  pared by functio
10af0 6e 20 73 65 73 73 69 6f 6e 53 65 6c 65 63 74 53  n sessionSelectS
10b00 74 6d 74 28 29 2e 0a 2a 2a 0a 2a 2a 20 52 65 74  tmt()..**.** Ret
10b10 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66  urn SQLITE_OK if
10b20 20 61 6c 6c 20 50 4b 20 76 61 6c 75 65 73 20 61   all PK values a
10b30 72 65 20 73 75 63 63 65 73 73 66 75 6c 6c 79 20  re successfully 
10b40 62 6f 75 6e 64 2c 20 6f 72 20 61 6e 20 53 51 4c  bound, or an SQL
10b50 69 74 65 0a 2a 2a 20 65 72 72 6f 72 20 63 6f 64  ite.** error cod
10b60 65 20 28 65 2e 67 2e 20 53 51 4c 49 54 45 5f 4e  e (e.g. SQLITE_N
10b70 4f 4d 45 4d 29 20 6f 74 68 65 72 77 69 73 65 2e  OMEM) otherwise.
10b80 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73  .*/.static int s
10b90 65 73 73 69 6f 6e 53 65 6c 65 63 74 42 69 6e 64  essionSelectBind
10ba0 28 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74  (.  sqlite3_stmt
10bb0 20 2a 70 53 65 6c 65 63 74 2c 20 20 20 20 20 20   *pSelect,      
10bc0 20 20 20 20 2f 2a 20 53 45 4c 45 43 54 20 66 72      /* SELECT fr
10bd0 6f 6d 20 73 65 73 73 69 6f 6e 53 65 6c 65 63 74  om sessionSelect
10be0 53 74 6d 74 28 29 20 2a 2f 0a 20 20 69 6e 74 20  Stmt() */.  int 
10bf0 6e 43 6f 6c 2c 20 20 20 20 20 20 20 20 20 20 20  nCol,           
10c00 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
10c10 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73  umber of columns
10c20 20 69 6e 20 74 61 62 6c 65 20 2a 2f 0a 20 20 75   in table */.  u
10c30 38 20 2a 61 62 50 4b 2c 20 20 20 20 20 20 20 20  8 *abPK,        
10c40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
10c50 2a 20 50 52 49 4d 41 52 59 20 4b 45 59 20 61 72  * PRIMARY KEY ar
10c60 72 61 79 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e  ray */.  Session
10c70 43 68 61 6e 67 65 20 2a 70 43 68 61 6e 67 65 20  Change *pChange 
10c80 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 61 6e           /* Chan
10c90 67 65 20 73 74 72 75 63 74 75 72 65 20 2a 2f 0a  ge structure */.
10ca0 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e  ){.  int i;.  in
10cb0 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
10cc0 3b 0a 20 20 75 38 20 2a 61 20 3d 20 70 43 68 61  ;.  u8 *a = pCha
10cd0 6e 67 65 2d 3e 61 52 65 63 6f 72 64 3b 0a 0a 20  nge->aRecord;.. 
10ce0 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c   for(i=0; i<nCol
10cf0 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f   && rc==SQLITE_O
10d00 4b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74  K; i++){.    int
10d10 20 65 54 79 70 65 20 3d 20 2a 61 2b 2b 3b 0a 0a   eType = *a++;..
10d20 20 20 20 20 73 77 69 74 63 68 28 20 65 54 79 70      switch( eTyp
10d30 65 20 29 7b 0a 20 20 20 20 20 20 63 61 73 65 20  e ){.      case 
10d40 30 3a 0a 20 20 20 20 20 20 63 61 73 65 20 53 51  0:.      case SQ
10d50 4c 49 54 45 5f 4e 55 4c 4c 3a 0a 20 20 20 20 20  LITE_NULL:.     
10d60 20 20 20 61 73 73 65 72 74 28 20 61 62 50 4b 5b     assert( abPK[
10d70 69 5d 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 20  i]==0 );.       
10d80 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63   break;..      c
10d90 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 54 45 47  ase SQLITE_INTEG
10da0 45 52 3a 20 7b 0a 20 20 20 20 20 20 20 20 69 66  ER: {.        if
10db0 28 20 61 62 50 4b 5b 69 5d 20 29 7b 0a 20 20 20  ( abPK[i] ){.   
10dc0 20 20 20 20 20 20 20 69 36 34 20 69 56 61 6c 20         i64 iVal 
10dd0 3d 20 73 65 73 73 69 6f 6e 47 65 74 49 36 34 28  = sessionGetI64(
10de0 61 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63  a);.          rc
10df0 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f   = sqlite3_bind_
10e00 69 6e 74 36 34 28 70 53 65 6c 65 63 74 2c 20 69  int64(pSelect, i
10e10 2b 31 2c 20 69 56 61 6c 29 3b 0a 20 20 20 20 20  +1, iVal);.     
10e20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 61 20 2b     }.        a +
10e30 3d 20 38 3b 0a 20 20 20 20 20 20 20 20 62 72 65  = 8;.        bre
10e40 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20  ak;.      }..   
10e50 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 46     case SQLITE_F
10e60 4c 4f 41 54 3a 20 7b 0a 20 20 20 20 20 20 20 20  LOAT: {.        
10e70 69 66 28 20 61 62 50 4b 5b 69 5d 20 29 7b 0a 20  if( abPK[i] ){. 
10e80 20 20 20 20 20 20 20 20 20 64 6f 75 62 6c 65 20           double 
10e90 72 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 20 20  rVal;.          
10ea0 69 36 34 20 69 56 61 6c 20 3d 20 73 65 73 73 69  i64 iVal = sessi
10eb0 6f 6e 47 65 74 49 36 34 28 61 29 3b 0a 20 20 20  onGetI64(a);.   
10ec0 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 72         memcpy(&r
10ed0 56 61 6c 2c 20 26 69 56 61 6c 2c 20 38 29 3b 0a  Val, &iVal, 8);.
10ee0 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 73            rc = s
10ef0 71 6c 69 74 65 33 5f 62 69 6e 64 5f 64 6f 75 62  qlite3_bind_doub
10f00 6c 65 28 70 53 65 6c 65 63 74 2c 20 69 2b 31 2c  le(pSelect, i+1,
10f10 20 72 56 61 6c 29 3b 0a 20 20 20 20 20 20 20 20   rVal);.        
10f20 7d 0a 20 20 20 20 20 20 20 20 61 20 2b 3d 20 38  }.        a += 8
10f30 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
10f40 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
10f50 63 61 73 65 20 53 51 4c 49 54 45 5f 54 45 58 54  case SQLITE_TEXT
10f60 3a 20 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20  : {.        int 
10f70 6e 3b 0a 20 20 20 20 20 20 20 20 61 20 2b 3d 20  n;.        a += 
10f80 73 65 73 73 69 6f 6e 56 61 72 69 6e 74 47 65 74  sessionVarintGet
10f90 28 61 2c 20 26 6e 29 3b 0a 20 20 20 20 20 20 20  (a, &n);.       
10fa0 20 69 66 28 20 61 62 50 4b 5b 69 5d 20 29 7b 0a   if( abPK[i] ){.
10fb0 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 73            rc = s
10fc0 71 6c 69 74 65 33 5f 62 69 6e 64 5f 74 65 78 74  qlite3_bind_text
10fd0 28 70 53 65 6c 65 63 74 2c 20 69 2b 31 2c 20 28  (pSelect, i+1, (
10fe0 63 68 61 72 20 2a 29 61 2c 20 6e 2c 20 53 51 4c  char *)a, n, SQL
10ff0 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a  ITE_TRANSIENT);.
11000 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
11010 20 20 61 20 2b 3d 20 6e 3b 0a 20 20 20 20 20 20    a += n;.      
11020 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d    break;.      }
11030 0a 0a 20 20 20 20 20 20 64 65 66 61 75 6c 74 3a  ..      default:
11040 20 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e   {.        int n
11050 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  ;.        assert
11060 28 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f  ( eType==SQLITE_
11070 42 4c 4f 42 20 29 3b 0a 20 20 20 20 20 20 20 20  BLOB );.        
11080 61 20 2b 3d 20 73 65 73 73 69 6f 6e 56 61 72 69  a += sessionVari
11090 6e 74 47 65 74 28 61 2c 20 26 6e 29 3b 0a 20 20  ntGet(a, &n);.  
110a0 20 20 20 20 20 20 69 66 28 20 61 62 50 4b 5b 69        if( abPK[i
110b0 5d 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72  ] ){.          r
110c0 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64  c = sqlite3_bind
110d0 5f 62 6c 6f 62 28 70 53 65 6c 65 63 74 2c 20 69  _blob(pSelect, i
110e0 2b 31 2c 20 61 2c 20 6e 2c 20 53 51 4c 49 54 45  +1, a, n, SQLITE
110f0 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 20  _TRANSIENT);.   
11100 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 61       }.        a
11110 20 2b 3d 20 6e 3b 0a 20 20 20 20 20 20 20 20 62   += n;.        b
11120 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  reak;.      }.  
11130 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
11140 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  n rc;.}../*.** T
11150 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
11160 61 20 6e 6f 2d 6f 70 20 69 66 20 2a 70 52 63 20  a no-op if *pRc 
11170 69 73 20 73 65 74 20 74 6f 20 6f 74 68 65 72 20  is set to other 
11180 74 68 61 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 77  than SQLITE_OK w
11190 68 65 6e 20 69 74 0a 2a 2a 20 69 73 20 63 61 6c  hen it.** is cal
111a0 6c 65 64 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  led. Otherwise, 
111b0 61 70 70 65 6e 64 20 61 20 73 65 72 69 61 6c 69  append a seriali
111c0 7a 65 64 20 74 61 62 6c 65 20 68 65 61 64 65 72  zed table header
111d0 20 28 70 61 72 74 20 6f 66 20 74 68 65 20 62 69   (part of the bi
111e0 6e 61 72 79 20 0a 2a 2a 20 63 68 61 6e 67 65 73  nary .** changes
111f0 65 74 20 66 6f 72 6d 61 74 29 20 74 6f 20 62 75  et format) to bu
11200 66 66 65 72 20 2a 70 42 75 66 2e 20 49 66 20 61  ffer *pBuf. If a
11210 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20  n error occurs, 
11220 73 65 74 20 2a 70 52 63 20 74 6f 20 61 6e 0a 2a  set *pRc to an.*
11230 2a 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  * SQLite error c
11240 6f 64 65 20 62 65 66 6f 72 65 20 72 65 74 75 72  ode before retur
11250 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ning..*/.static 
11260 76 6f 69 64 20 73 65 73 73 69 6f 6e 41 70 70 65  void sessionAppe
11270 6e 64 54 61 62 6c 65 48 64 72 28 0a 20 20 53 65  ndTableHdr(.  Se
11280 73 73 69 6f 6e 42 75 66 66 65 72 20 2a 70 42 75  ssionBuffer *pBu
11290 66 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  f,            /*
112a0 20 41 70 70 65 6e 64 20 68 65 61 64 65 72 20 74   Append header t
112b0 6f 20 74 68 69 73 20 62 75 66 66 65 72 20 2a 2f  o this buffer */
112c0 0a 20 20 69 6e 74 20 62 50 61 74 63 68 73 65 74  .  int bPatchset
112d0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
112e0 20 20 20 2f 2a 20 55 73 65 20 74 68 65 20 70 61     /* Use the pa
112f0 74 63 68 73 65 74 20 66 6f 72 6d 61 74 20 69 66  tchset format if
11300 20 74 72 75 65 20 2a 2f 0a 20 20 53 65 73 73 69   true */.  Sessi
11310 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 20  onTable *pTab,  
11320 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61             /* Ta
11330 62 6c 65 20 6f 62 6a 65 63 74 20 74 6f 20 61 70  ble object to ap
11340 70 65 6e 64 20 68 65 61 64 65 72 20 66 6f 72 20  pend header for 
11350 2a 2f 0a 20 20 69 6e 74 20 2a 70 52 63 20 20 20  */.  int *pRc   
11360 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11370 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20       /* IN/OUT: 
11380 45 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 29 7b  Error code */.){
11390 0a 20 20 2f 2a 20 57 72 69 74 65 20 61 20 74 61  .  /* Write a ta
113a0 62 6c 65 20 68 65 61 64 65 72 20 2a 2f 0a 20 20  ble header */.  
113b0 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 79 74  sessionAppendByt
113c0 65 28 70 42 75 66 2c 20 28 62 50 61 74 63 68 73  e(pBuf, (bPatchs
113d0 65 74 20 3f 20 27 50 27 20 3a 20 27 54 27 29 2c  et ? 'P' : 'T'),
113e0 20 70 52 63 29 3b 0a 20 20 73 65 73 73 69 6f 6e   pRc);.  session
113f0 41 70 70 65 6e 64 56 61 72 69 6e 74 28 70 42 75  AppendVarint(pBu
11400 66 2c 20 70 54 61 62 2d 3e 6e 43 6f 6c 2c 20 70  f, pTab->nCol, p
11410 52 63 29 3b 0a 20 20 73 65 73 73 69 6f 6e 41 70  Rc);.  sessionAp
11420 70 65 6e 64 42 6c 6f 62 28 70 42 75 66 2c 20 70  pendBlob(pBuf, p
11430 54 61 62 2d 3e 61 62 50 4b 2c 20 70 54 61 62 2d  Tab->abPK, pTab-
11440 3e 6e 43 6f 6c 2c 20 70 52 63 29 3b 0a 20 20 73  >nCol, pRc);.  s
11450 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 6c 6f 62  essionAppendBlob
11460 28 70 42 75 66 2c 20 28 75 38 20 2a 29 70 54 61  (pBuf, (u8 *)pTa
11470 62 2d 3e 7a 4e 61 6d 65 2c 20 28 69 6e 74 29 73  b->zName, (int)s
11480 74 72 6c 65 6e 28 70 54 61 62 2d 3e 7a 4e 61 6d  trlen(pTab->zNam
11490 65 29 2b 31 2c 20 70 52 63 29 3b 0a 7d 0a 0a 2f  e)+1, pRc);.}../
114a0 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65 20 65 69  *.** Generate ei
114b0 74 68 65 72 20 61 20 63 68 61 6e 67 65 73 65 74  ther a changeset
114c0 20 28 69 66 20 61 72 67 75 6d 65 6e 74 20 62 50   (if argument bP
114d0 61 74 63 68 73 65 74 20 69 73 20 7a 65 72 6f 29  atchset is zero)
114e0 20 6f 72 20 61 20 70 61 74 63 68 73 65 74 0a 2a   or a patchset.*
114f0 2a 20 28 69 66 20 69 74 20 69 73 20 6e 6f 6e 2d  * (if it is non-
11500 7a 65 72 6f 29 20 62 61 73 65 64 20 6f 6e 20 74  zero) based on t
11510 68 65 20 63 75 72 72 65 6e 74 20 63 6f 6e 74 65  he current conte
11520 6e 74 73 20 6f 66 20 74 68 65 20 73 65 73 73 69  nts of the sessi
11530 6f 6e 20 6f 62 6a 65 63 74 0a 2a 2a 20 70 61 73  on object.** pas
11540 73 65 64 20 61 73 20 74 68 65 20 66 69 72 73 74  sed as the first
11550 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a   argument..**.**
11560 20 49 66 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63   If no error occ
11570 75 72 73 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69  urs, SQLITE_OK i
11580 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 74  s returned and t
11590 68 65 20 6e 65 77 20 63 68 61 6e 67 65 73 65 74  he new changeset
115a0 2f 70 61 74 63 68 73 65 74 0a 2a 2a 20 73 74 6f  /patchset.** sto
115b0 72 65 64 20 69 6e 20 6f 75 74 70 75 74 20 76 61  red in output va
115c0 72 69 61 62 6c 65 73 20 2a 70 6e 43 68 61 6e 67  riables *pnChang
115d0 65 73 65 74 20 61 6e 64 20 2a 70 70 43 68 61 6e  eset and *ppChan
115e0 67 65 73 65 74 2e 20 4f 72 2c 20 69 66 20 61 6e  geset. Or, if an
115f0 20 65 72 72 6f 72 0a 2a 2a 20 6f 63 63 75 72 73   error.** occurs
11600 2c 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  , an SQLite erro
11610 72 20 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e  r code is return
11620 65 64 20 61 6e 64 20 62 6f 74 68 20 6f 75 74 70  ed and both outp
11630 75 74 20 76 61 72 69 61 62 6c 65 73 20 73 65 74  ut variables set
11640 20 0a 2a 2a 20 74 6f 20 30 2e 0a 2a 2f 0a 73 74   .** to 0..*/.st
11650 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e  atic int session
11660 47 65 6e 65 72 61 74 65 43 68 61 6e 67 65 73 65  GenerateChangese
11670 74 28 0a 20 20 73 71 6c 69 74 65 33 5f 73 65 73  t(.  sqlite3_ses
11680 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f 6e 2c 20  sion *pSession, 
11690 20 20 20 20 20 2f 2a 20 53 65 73 73 69 6f 6e 20       /* Session 
116a0 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e 74 20  object */.  int 
116b0 62 50 61 74 63 68 73 65 74 2c 20 20 20 20 20 20  bPatchset,      
116c0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
116d0 72 75 65 20 66 6f 72 20 70 61 74 63 68 73 65 74  rue for patchset
116e0 2c 20 66 61 6c 73 65 20 66 6f 72 20 63 68 61 6e  , false for chan
116f0 67 65 73 65 74 20 2a 2f 0a 20 20 69 6e 74 20 28  geset */.  int (
11700 2a 78 4f 75 74 70 75 74 29 28 76 6f 69 64 20 2a  *xOutput)(void *
11710 70 4f 75 74 2c 20 63 6f 6e 73 74 20 76 6f 69 64  pOut, const void
11720 20 2a 70 44 61 74 61 2c 20 69 6e 74 20 6e 44 61   *pData, int nDa
11730 74 61 29 2c 0a 20 20 76 6f 69 64 20 2a 70 4f 75  ta),.  void *pOu
11740 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
11750 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20         /* First 
11760 61 72 67 75 6d 65 6e 74 20 66 6f 72 20 78 4f 75  argument for xOu
11770 74 70 75 74 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  tput */.  int *p
11780 6e 43 68 61 6e 67 65 73 65 74 2c 20 20 20 20 20  nChangeset,     
11790 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
117a0 3a 20 53 69 7a 65 20 6f 66 20 62 75 66 66 65 72  : Size of buffer
117b0 20 61 74 20 2a 70 70 43 68 61 6e 67 65 73 65 74   at *ppChangeset
117c0 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 2a 70 70 43   */.  void **ppC
117d0 68 61 6e 67 65 73 65 74 20 20 20 20 20 20 20 20  hangeset        
117e0 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 42 75        /* OUT: Bu
117f0 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ffer containing 
11800 63 68 61 6e 67 65 73 65 74 20 2a 2f 0a 29 7b 0a  changeset */.){.
11810 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20 3d 20    sqlite3 *db = 
11820 70 53 65 73 73 69 6f 6e 2d 3e 64 62 3b 20 20 20  pSession->db;   
11830 20 20 2f 2a 20 53 6f 75 72 63 65 20 64 61 74 61    /* Source data
11840 62 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20  base handle */. 
11850 20 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70   SessionTable *p
11860 54 61 62 3b 20 20 20 20 20 20 20 20 20 20 20 20  Tab;            
11870 20 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72   /* Used to iter
11880 61 74 65 20 74 68 72 6f 75 67 68 20 61 74 74 61  ate through atta
11890 63 68 65 64 20 74 61 62 6c 65 73 20 2a 2f 0a 20  ched tables */. 
118a0 20 53 65 73 73 69 6f 6e 42 75 66 66 65 72 20 62   SessionBuffer b
118b0 75 66 20 3d 20 7b 30 2c 30 2c 30 7d 3b 20 20 20  uf = {0,0,0};   
118c0 20 2f 2a 20 42 75 66 66 65 72 20 69 6e 20 77 68   /* Buffer in wh
118d0 69 63 68 20 74 6f 20 61 63 63 75 6d 6c 61 74 65  ich to accumlate
118e0 20 63 68 61 6e 67 65 73 65 74 20 2a 2f 0a 20 20   changeset */.  
118f0 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
11900 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11910 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
11920 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 78 4f 75  /..  assert( xOu
11930 74 70 75 74 3d 3d 30 20 7c 7c 20 28 70 6e 43 68  tput==0 || (pnCh
11940 61 6e 67 65 73 65 74 3d 3d 30 20 26 26 20 70 70  angeset==0 && pp
11950 43 68 61 6e 67 65 73 65 74 3d 3d 30 20 29 20 29  Changeset==0 ) )
11960 3b 0a 0a 20 20 2f 2a 20 5a 65 72 6f 20 74 68 65  ;..  /* Zero the
11970 20 6f 75 74 70 75 74 20 76 61 72 69 61 62 6c 65   output variable
11980 73 20 69 6e 20 63 61 73 65 20 61 6e 20 65 72 72  s in case an err
11990 6f 72 20 6f 63 63 75 72 73 2e 20 49 66 20 74 68  or occurs. If th
119a0 69 73 20 73 65 73 73 69 6f 6e 0a 20 20 2a 2a 20  is session.  ** 
119b0 6f 62 6a 65 63 74 20 69 73 20 61 6c 72 65 61 64  object is alread
119c0 79 20 69 6e 20 74 68 65 20 65 72 72 6f 72 20 73  y in the error s
119d0 74 61 74 65 20 28 73 71 6c 69 74 65 33 5f 73 65  tate (sqlite3_se
119e0 73 73 69 6f 6e 2e 72 63 20 21 3d 20 53 51 4c 49  ssion.rc != SQLI
119f0 54 45 5f 4f 4b 29 2c 0a 20 20 2a 2a 20 74 68 69  TE_OK),.  ** thi
11a00 73 20 63 61 6c 6c 20 77 69 6c 6c 20 62 65 20 61  s call will be a
11a10 20 6e 6f 2d 6f 70 2e 20 20 2a 2f 0a 20 20 69 66   no-op.  */.  if
11a20 28 20 78 4f 75 74 70 75 74 3d 3d 30 20 29 7b 0a  ( xOutput==0 ){.
11a30 20 20 20 20 2a 70 6e 43 68 61 6e 67 65 73 65 74      *pnChangeset
11a40 20 3d 20 30 3b 0a 20 20 20 20 2a 70 70 43 68 61   = 0;.    *ppCha
11a50 6e 67 65 73 65 74 20 3d 20 30 3b 0a 20 20 7d 0a  ngeset = 0;.  }.
11a60 0a 20 20 69 66 28 20 70 53 65 73 73 69 6f 6e 2d  .  if( pSession-
11a70 3e 72 63 20 29 20 72 65 74 75 72 6e 20 70 53 65  >rc ) return pSe
11a80 73 73 69 6f 6e 2d 3e 72 63 3b 0a 20 20 72 63 20  ssion->rc;.  rc 
11a90 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 70  = sqlite3_exec(p
11aa0 53 65 73 73 69 6f 6e 2d 3e 64 62 2c 20 22 53 41  Session->db, "SA
11ab0 56 45 50 4f 49 4e 54 20 63 68 61 6e 67 65 73 65  VEPOINT changese
11ac0 74 22 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20  t", 0, 0, 0);.  
11ad0 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
11ae0 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a  K ) return rc;..
11af0 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
11b00 65 6e 74 65 72 28 73 71 6c 69 74 65 33 5f 64 62  enter(sqlite3_db
11b10 5f 6d 75 74 65 78 28 64 62 29 29 3b 0a 0a 20 20  _mutex(db));..  
11b20 66 6f 72 28 70 54 61 62 3d 70 53 65 73 73 69 6f  for(pTab=pSessio
11b30 6e 2d 3e 70 54 61 62 6c 65 3b 20 72 63 3d 3d 53  n->pTable; rc==S
11b40 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 54 61 62  QLITE_OK && pTab
11b50 3b 20 70 54 61 62 3d 70 54 61 62 2d 3e 70 4e 65  ; pTab=pTab->pNe
11b60 78 74 29 7b 0a 20 20 20 20 69 66 28 20 70 54 61  xt){.    if( pTa
11b70 62 2d 3e 6e 45 6e 74 72 79 20 29 7b 0a 20 20 20  b->nEntry ){.   
11b80 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
11b90 4e 61 6d 65 20 3d 20 70 54 61 62 2d 3e 7a 4e 61  Name = pTab->zNa
11ba0 6d 65 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 43  me;.      int nC
11bb0 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ol;             
11bc0 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
11bd0 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 61  of columns in ta
11be0 62 6c 65 20 2a 2f 0a 20 20 20 20 20 20 75 38 20  ble */.      u8 
11bf0 2a 61 62 50 4b 3b 20 20 20 20 20 20 20 20 20 20  *abPK;          
11c00 20 20 20 20 20 20 20 20 20 2f 2a 20 50 72 69 6d           /* Prim
11c10 61 72 79 20 6b 65 79 20 61 72 72 61 79 20 2a 2f  ary key array */
11c20 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61  .      const cha
11c30 72 20 2a 2a 61 7a 43 6f 6c 20 3d 20 30 3b 20 20  r **azCol = 0;  
11c40 20 20 20 2f 2a 20 54 61 62 6c 65 20 63 6f 6c 75     /* Table colu
11c50 6d 6e 73 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74  mns */.      int
11c60 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
11c70 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64           /* Used
11c80 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f   to iterate thro
11c90 75 67 68 20 68 61 73 68 20 62 75 63 6b 65 74 73  ugh hash buckets
11ca0 20 2a 2f 0a 20 20 20 20 20 20 73 71 6c 69 74 65   */.      sqlite
11cb0 33 5f 73 74 6d 74 20 2a 70 53 65 6c 20 3d 20 30  3_stmt *pSel = 0
11cc0 3b 20 20 20 20 20 2f 2a 20 53 45 4c 45 43 54 20  ;     /* SELECT 
11cd0 73 74 61 74 65 6d 65 6e 74 20 74 6f 20 71 75 65  statement to que
11ce0 72 79 20 74 61 62 6c 65 20 70 54 61 62 20 2a 2f  ry table pTab */
11cf0 0a 20 20 20 20 20 20 69 6e 74 20 6e 52 65 77 69  .      int nRewi
11d00 6e 64 20 3d 20 62 75 66 2e 6e 42 75 66 3b 20 20  nd = buf.nBuf;  
11d10 20 20 20 2f 2a 20 49 6e 69 74 69 61 6c 20 73 69     /* Initial si
11d20 7a 65 20 6f 66 20 77 72 69 74 65 20 62 75 66 66  ze of write buff
11d30 65 72 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20  er */.      int 
11d40 6e 4e 6f 6f 70 3b 20 20 20 20 20 20 20 20 20 20  nNoop;          
11d50 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
11d60 6f 66 20 62 75 66 66 65 72 20 61 66 74 65 72 20  of buffer after 
11d70 77 72 69 74 69 6e 67 20 74 62 6c 20 68 65 61 64  writing tbl head
11d80 65 72 20 2a 2f 0a 0a 20 20 20 20 20 20 2f 2a 20  er */..      /* 
11d90 43 68 65 63 6b 20 74 68 65 20 74 61 62 6c 65 20  Check the table 
11da0 73 63 68 65 6d 61 20 69 73 20 73 74 69 6c 6c 20  schema is still 
11db0 4f 6b 2e 20 2a 2f 0a 20 20 20 20 20 20 72 63 20  Ok. */.      rc 
11dc0 3d 20 73 65 73 73 69 6f 6e 54 61 62 6c 65 49 6e  = sessionTableIn
11dd0 66 6f 28 64 62 2c 20 70 53 65 73 73 69 6f 6e 2d  fo(db, pSession-
11de0 3e 7a 44 62 2c 20 7a 4e 61 6d 65 2c 20 26 6e 43  >zDb, zName, &nC
11df0 6f 6c 2c 20 30 2c 20 26 61 7a 43 6f 6c 2c 20 26  ol, 0, &azCol, &
11e00 61 62 50 4b 29 3b 0a 20 20 20 20 20 20 69 66 28  abPK);.      if(
11e10 20 21 72 63 20 26 26 20 28 70 54 61 62 2d 3e 6e   !rc && (pTab->n
11e20 43 6f 6c 21 3d 6e 43 6f 6c 20 7c 7c 20 6d 65 6d  Col!=nCol || mem
11e30 63 6d 70 28 61 62 50 4b 2c 20 70 54 61 62 2d 3e  cmp(abPK, pTab->
11e40 61 62 50 4b 2c 20 6e 43 6f 6c 29 29 20 29 7b 0a  abPK, nCol)) ){.
11e50 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
11e60 49 54 45 5f 53 43 48 45 4d 41 3b 0a 20 20 20 20  ITE_SCHEMA;.    
11e70 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 57 72    }..      /* Wr
11e80 69 74 65 20 61 20 74 61 62 6c 65 20 68 65 61 64  ite a table head
11e90 65 72 20 2a 2f 0a 20 20 20 20 20 20 73 65 73 73  er */.      sess
11ea0 69 6f 6e 41 70 70 65 6e 64 54 61 62 6c 65 48 64  ionAppendTableHd
11eb0 72 28 26 62 75 66 2c 20 62 50 61 74 63 68 73 65  r(&buf, bPatchse
11ec0 74 2c 20 70 54 61 62 2c 20 26 72 63 29 3b 0a 0a  t, pTab, &rc);..
11ed0 20 20 20 20 20 20 2f 2a 20 42 75 69 6c 64 20 61        /* Build a
11ee0 6e 64 20 63 6f 6d 70 69 6c 65 20 61 20 73 74 61  nd compile a sta
11ef0 74 65 6d 65 6e 74 20 74 6f 20 65 78 65 63 75 74  tement to execut
11f00 65 3a 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20  e: */.      if( 
11f10 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
11f20 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 65  .        rc = se
11f30 73 73 69 6f 6e 53 65 6c 65 63 74 53 74 6d 74 28  ssionSelectStmt(
11f40 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 62 2c  .            db,
11f50 20 70 53 65 73 73 69 6f 6e 2d 3e 7a 44 62 2c 20   pSession->zDb, 
11f60 7a 4e 61 6d 65 2c 20 6e 43 6f 6c 2c 20 61 7a 43  zName, nCol, azC
11f70 6f 6c 2c 20 61 62 50 4b 2c 20 26 70 53 65 6c 29  ol, abPK, &pSel)
11f80 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  ;.      }..     
11f90 20 6e 4e 6f 6f 70 20 3d 20 62 75 66 2e 6e 42 75   nNoop = buf.nBu
11fa0 66 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30  f;.      for(i=0
11fb0 3b 20 69 3c 70 54 61 62 2d 3e 6e 43 68 61 6e 67  ; i<pTab->nChang
11fc0 65 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f  e && rc==SQLITE_
11fd0 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  OK; i++){.      
11fe0 20 20 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20    SessionChange 
11ff0 2a 70 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 55  *p;         /* U
12000 73 65 64 20 74 6f 20 69 74 65 72 61 74 65 20 74  sed to iterate t
12010 68 72 6f 75 67 68 20 63 68 61 6e 67 65 73 20 2a  hrough changes *
12020 2f 0a 0a 20 20 20 20 20 20 20 20 66 6f 72 28 70  /..        for(p
12030 3d 70 54 61 62 2d 3e 61 70 43 68 61 6e 67 65 5b  =pTab->apChange[
12040 69 5d 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  i]; rc==SQLITE_O
12050 4b 20 26 26 20 70 3b 20 70 3d 70 2d 3e 70 4e 65  K && p; p=p->pNe
12060 78 74 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72  xt){.          r
12070 63 20 3d 20 73 65 73 73 69 6f 6e 53 65 6c 65 63  c = sessionSelec
12080 74 42 69 6e 64 28 70 53 65 6c 2c 20 6e 43 6f 6c  tBind(pSel, nCol
12090 2c 20 61 62 50 4b 2c 20 70 29 3b 0a 20 20 20 20  , abPK, p);.    
120a0 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
120b0 4c 49 54 45 5f 4f 4b 20 29 20 63 6f 6e 74 69 6e  LITE_OK ) contin
120c0 75 65 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66  ue;.          if
120d0 28 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70  ( sqlite3_step(p
120e0 53 65 6c 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57  Sel)==SQLITE_ROW
120f0 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
12100 69 66 28 20 70 2d 3e 6f 70 3d 3d 53 51 4c 49 54  if( p->op==SQLIT
12110 45 5f 49 4e 53 45 52 54 20 29 7b 0a 20 20 20 20  E_INSERT ){.    
12120 20 20 20 20 20 20 20 20 20 20 69 6e 74 20 69 43            int iC
12130 6f 6c 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  ol;.            
12140 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42    sessionAppendB
12150 79 74 65 28 26 62 75 66 2c 20 53 51 4c 49 54 45  yte(&buf, SQLITE
12160 5f 49 4e 53 45 52 54 2c 20 26 72 63 29 3b 0a 20  _INSERT, &rc);. 
12170 20 20 20 20 20 20 20 20 20 20 20 20 20 73 65 73               ses
12180 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 26  sionAppendByte(&
12190 62 75 66 2c 20 70 2d 3e 62 49 6e 64 69 72 65 63  buf, p->bIndirec
121a0 74 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20  t, &rc);.       
121b0 20 20 20 20 20 20 20 66 6f 72 28 69 43 6f 6c 3d         for(iCol=
121c0 30 3b 20 69 43 6f 6c 3c 6e 43 6f 6c 3b 20 69 43  0; iCol<nCol; iC
121d0 6f 6c 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20  ol++){.         
121e0 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70         sessionAp
121f0 70 65 6e 64 43 6f 6c 28 26 62 75 66 2c 20 70 53  pendCol(&buf, pS
12200 65 6c 2c 20 69 43 6f 6c 2c 20 26 72 63 29 3b 0a  el, iCol, &rc);.
12210 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a                }.
12220 20 20 20 20 20 20 20 20 20 20 20 20 7d 65 6c 73              }els
12230 65 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e{.             
12240 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 41 70 70   rc = sessionApp
12250 65 6e 64 55 70 64 61 74 65 28 26 62 75 66 2c 20  endUpdate(&buf, 
12260 62 50 61 74 63 68 73 65 74 2c 20 70 53 65 6c 2c  bPatchset, pSel,
12270 20 70 2c 20 61 62 50 4b 29 3b 0a 20 20 20 20 20   p, abPK);.     
12280 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
12290 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70 2d 3e     }else if( p->
122a0 6f 70 21 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52  op!=SQLITE_INSER
122b0 54 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  T ){.           
122c0 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 41 70 70   rc = sessionApp
122d0 65 6e 64 44 65 6c 65 74 65 28 26 62 75 66 2c 20  endDelete(&buf, 
122e0 62 50 61 74 63 68 73 65 74 2c 20 70 2c 20 6e 43  bPatchset, p, nC
122f0 6f 6c 2c 20 61 62 50 4b 29 3b 0a 20 20 20 20 20  ol, abPK);.     
12300 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
12310 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
12320 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  OK ){.          
12330 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 72    rc = sqlite3_r
12340 65 73 65 74 28 70 53 65 6c 29 3b 0a 20 20 20 20  eset(pSel);.    
12350 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20        }..       
12360 20 20 20 2f 2a 20 49 66 20 74 68 65 20 62 75 66     /* If the buf
12370 66 65 72 20 69 73 20 6e 6f 77 20 6c 61 72 67 65  fer is now large
12380 72 20 74 68 61 6e 20 53 45 53 53 49 4f 4e 53 5f  r than SESSIONS_
12390 53 54 52 4d 5f 43 48 55 4e 4b 5f 53 49 5a 45 2c  STRM_CHUNK_SIZE,
123a0 20 70 61 73 73 0a 20 20 20 20 20 20 20 20 20 20   pass.          
123b0 2a 2a 20 69 74 73 20 63 6f 6e 74 65 6e 74 73 20  ** its contents 
123c0 74 6f 20 74 68 65 20 78 4f 75 74 70 75 74 28 29  to the xOutput()
123d0 20 63 61 6c 6c 62 61 63 6b 2e 20 2a 2f 0a 20 20   callback. */.  
123e0 20 20 20 20 20 20 20 20 69 66 28 20 78 4f 75 74          if( xOut
123f0 70 75 74 20 0a 20 20 20 20 20 20 20 20 20 20 20  put .           
12400 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  && rc==SQLITE_OK
12410 20 0a 20 20 20 20 20 20 20 20 20 20 20 26 26 20   .           && 
12420 62 75 66 2e 6e 42 75 66 3e 6e 4e 6f 6f 70 20 0a  buf.nBuf>nNoop .
12430 20 20 20 20 20 20 20 20 20 20 20 26 26 20 62 75             && bu
12440 66 2e 6e 42 75 66 3e 53 45 53 53 49 4f 4e 53 5f  f.nBuf>SESSIONS_
12450 53 54 52 4d 5f 43 48 55 4e 4b 5f 53 49 5a 45 20  STRM_CHUNK_SIZE 
12460 0a 20 20 20 20 20 20 20 20 20 20 29 7b 0a 20 20  .          ){.  
12470 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 78            rc = x
12480 4f 75 74 70 75 74 28 70 4f 75 74 2c 20 28 76 6f  Output(pOut, (vo
12490 69 64 2a 29 62 75 66 2e 61 42 75 66 2c 20 62 75  id*)buf.aBuf, bu
124a0 66 2e 6e 42 75 66 29 3b 0a 20 20 20 20 20 20 20  f.nBuf);.       
124b0 20 20 20 20 20 6e 4e 6f 6f 70 20 3d 20 2d 31 3b       nNoop = -1;
124c0 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 75 66  .            buf
124d0 2e 6e 42 75 66 20 3d 20 30 3b 0a 20 20 20 20 20  .nBuf = 0;.     
124e0 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20       }..        
124f0 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  }.      }..     
12500 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
12510 65 28 70 53 65 6c 29 3b 0a 20 20 20 20 20 20 69  e(pSel);.      i
12520 66 28 20 62 75 66 2e 6e 42 75 66 3d 3d 6e 4e 6f  f( buf.nBuf==nNo
12530 6f 70 20 29 7b 0a 20 20 20 20 20 20 20 20 62 75  op ){.        bu
12540 66 2e 6e 42 75 66 20 3d 20 6e 52 65 77 69 6e 64  f.nBuf = nRewind
12550 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
12560 73 71 6c 69 74 65 33 5f 66 72 65 65 28 28 63 68  sqlite3_free((ch
12570 61 72 2a 29 61 7a 43 6f 6c 29 3b 20 20 2f 2a 20  ar*)azCol);  /* 
12580 63 61 73 74 20 77 6f 72 6b 73 20 61 72 6f 75 6e  cast works aroun
12590 64 20 56 43 2b 2b 20 62 75 67 20 2a 2f 0a 20 20  d VC++ bug */.  
125a0 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72    }.  }..  if( r
125b0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
125c0 20 20 20 20 69 66 28 20 78 4f 75 74 70 75 74 3d      if( xOutput=
125d0 3d 30 20 29 7b 0a 20 20 20 20 20 20 2a 70 6e 43  =0 ){.      *pnC
125e0 68 61 6e 67 65 73 65 74 20 3d 20 62 75 66 2e 6e  hangeset = buf.n
125f0 42 75 66 3b 0a 20 20 20 20 20 20 2a 70 70 43 68  Buf;.      *ppCh
12600 61 6e 67 65 73 65 74 20 3d 20 62 75 66 2e 61 42  angeset = buf.aB
12610 75 66 3b 0a 20 20 20 20 20 20 62 75 66 2e 61 42  uf;.      buf.aB
12620 75 66 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73  uf = 0;.    }els
12630 65 20 69 66 28 20 62 75 66 2e 6e 42 75 66 3e 30  e if( buf.nBuf>0
12640 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 78   ){.      rc = x
12650 4f 75 74 70 75 74 28 70 4f 75 74 2c 20 28 76 6f  Output(pOut, (vo
12660 69 64 2a 29 62 75 66 2e 61 42 75 66 2c 20 62 75  id*)buf.aBuf, bu
12670 66 2e 6e 42 75 66 29 3b 0a 20 20 20 20 7d 0a 20  f.nBuf);.    }. 
12680 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f 66 72   }..  sqlite3_fr
12690 65 65 28 62 75 66 2e 61 42 75 66 29 3b 0a 20 20  ee(buf.aBuf);.  
126a0 73 71 6c 69 74 65 33 5f 65 78 65 63 28 64 62 2c  sqlite3_exec(db,
126b0 20 22 52 45 4c 45 41 53 45 20 63 68 61 6e 67 65   "RELEASE change
126c0 73 65 74 22 2c 20 30 2c 20 30 2c 20 30 29 3b 0a  set", 0, 0, 0);.
126d0 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
126e0 6c 65 61 76 65 28 73 71 6c 69 74 65 33 5f 64 62  leave(sqlite3_db
126f0 5f 6d 75 74 65 78 28 64 62 29 29 3b 0a 20 20 72  _mutex(db));.  r
12700 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
12710 2a 2a 20 4f 62 74 61 69 6e 20 61 20 63 68 61 6e  ** Obtain a chan
12720 67 65 73 65 74 20 6f 62 6a 65 63 74 20 63 6f 6e  geset object con
12730 74 61 69 6e 69 6e 67 20 61 6c 6c 20 63 68 61 6e  taining all chan
12740 67 65 73 20 72 65 63 6f 72 64 65 64 20 62 79 20  ges recorded by 
12750 74 68 65 20 0a 2a 2a 20 73 65 73 73 69 6f 6e 20  the .** session 
12760 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20 61 73  object passed as
12770 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d   the first argum
12780 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 49 74 20 69 73  ent..**.** It is
12790 20 74 68 65 20 72 65 73 70 6f 6e 73 69 62 69 6c   the responsibil
127a0 69 74 79 20 6f 66 20 74 68 65 20 63 61 6c 6c 65  ity of the calle
127b0 72 20 74 6f 20 65 76 65 6e 74 75 61 6c 6c 79 20  r to eventually 
127c0 66 72 65 65 20 74 68 65 20 62 75 66 66 65 72 20  free the buffer 
127d0 0a 2a 2a 20 75 73 69 6e 67 20 73 71 6c 69 74 65  .** using sqlite
127e0 33 5f 66 72 65 65 28 29 2e 0a 2a 2f 0a 69 6e 74  3_free()..*/.int
127f0 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f   sqlite3session_
12800 63 68 61 6e 67 65 73 65 74 28 0a 20 20 73 71 6c  changeset(.  sql
12810 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53  ite3_session *pS
12820 65 73 73 69 6f 6e 2c 20 20 20 20 20 20 2f 2a 20  ession,      /* 
12830 53 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 2a  Session object *
12840 2f 0a 20 20 69 6e 74 20 2a 70 6e 43 68 61 6e 67  /.  int *pnChang
12850 65 73 65 74 2c 20 20 20 20 20 20 20 20 20 20 20  eset,           
12860 20 20 20 20 2f 2a 20 4f 55 54 3a 20 53 69 7a 65      /* OUT: Size
12870 20 6f 66 20 62 75 66 66 65 72 20 61 74 20 2a 70   of buffer at *p
12880 70 43 68 61 6e 67 65 73 65 74 20 2a 2f 0a 20 20  pChangeset */.  
12890 76 6f 69 64 20 2a 2a 70 70 43 68 61 6e 67 65 73  void **ppChanges
128a0 65 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20  et              
128b0 2f 2a 20 4f 55 54 3a 20 42 75 66 66 65 72 20 63  /* OUT: Buffer c
128c0 6f 6e 74 61 69 6e 69 6e 67 20 63 68 61 6e 67 65  ontaining change
128d0 73 65 74 20 2a 2f 0a 29 7b 0a 20 20 72 65 74 75  set */.){.  retu
128e0 72 6e 20 73 65 73 73 69 6f 6e 47 65 6e 65 72 61  rn sessionGenera
128f0 74 65 43 68 61 6e 67 65 73 65 74 28 70 53 65 73  teChangeset(pSes
12900 73 69 6f 6e 2c 20 30 2c 20 30 2c 20 30 2c 20 70  sion, 0, 0, 0, p
12910 6e 43 68 61 6e 67 65 73 65 74 2c 20 70 70 43 68  nChangeset, ppCh
12920 61 6e 67 65 73 65 74 29 3b 0a 7d 0a 0a 2f 2a 0a  angeset);.}../*.
12930 2a 2a 20 53 74 72 65 61 6d 69 6e 67 20 76 65 72  ** Streaming ver
12940 73 69 6f 6e 20 6f 66 20 73 71 6c 69 74 65 33 73  sion of sqlite3s
12950 65 73 73 69 6f 6e 5f 63 68 61 6e 67 65 73 65 74  ession_changeset
12960 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ()..*/.int sqlit
12970 65 33 73 65 73 73 69 6f 6e 5f 63 68 61 6e 67 65  e3session_change
12980 73 65 74 5f 73 74 72 6d 28 0a 20 20 73 71 6c 69  set_strm(.  sqli
12990 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65  te3_session *pSe
129a0 73 73 69 6f 6e 2c 0a 20 20 69 6e 74 20 28 2a 78  ssion,.  int (*x
129b0 4f 75 74 70 75 74 29 28 76 6f 69 64 20 2a 70 4f  Output)(void *pO
129c0 75 74 2c 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a  ut, const void *
129d0 70 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74 61  pData, int nData
129e0 29 2c 0a 20 20 76 6f 69 64 20 2a 70 4f 75 74 0a  ),.  void *pOut.
129f0 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 65 73 73  ){.  return sess
12a00 69 6f 6e 47 65 6e 65 72 61 74 65 43 68 61 6e 67  ionGenerateChang
12a10 65 73 65 74 28 70 53 65 73 73 69 6f 6e 2c 20 30  eset(pSession, 0
12a20 2c 20 78 4f 75 74 70 75 74 2c 20 70 4f 75 74 2c  , xOutput, pOut,
12a30 20 30 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   0, 0);.}../*.**
12a40 20 53 74 72 65 61 6d 69 6e 67 20 76 65 72 73 69   Streaming versi
12a50 6f 6e 20 6f 66 20 73 71 6c 69 74 65 33 73 65 73  on of sqlite3ses
12a60 73 69 6f 6e 5f 70 61 74 63 68 73 65 74 28 29 2e  sion_patchset().
12a70 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 73  .*/.int sqlite3s
12a80 65 73 73 69 6f 6e 5f 70 61 74 63 68 73 65 74 5f  ession_patchset_
12a90 73 74 72 6d 28 0a 20 20 73 71 6c 69 74 65 33 5f  strm(.  sqlite3_
12aa0 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f  session *pSessio
12ab0 6e 2c 0a 20 20 69 6e 74 20 28 2a 78 4f 75 74 70  n,.  int (*xOutp
12ac0 75 74 29 28 76 6f 69 64 20 2a 70 4f 75 74 2c 20  ut)(void *pOut, 
12ad0 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 44 61 74  const void *pDat
12ae0 61 2c 20 69 6e 74 20 6e 44 61 74 61 29 2c 0a 20  a, int nData),. 
12af0 20 76 6f 69 64 20 2a 70 4f 75 74 0a 29 7b 0a 20   void *pOut.){. 
12b00 20 72 65 74 75 72 6e 20 73 65 73 73 69 6f 6e 47   return sessionG
12b10 65 6e 65 72 61 74 65 43 68 61 6e 67 65 73 65 74  enerateChangeset
12b20 28 70 53 65 73 73 69 6f 6e 2c 20 31 2c 20 78 4f  (pSession, 1, xO
12b30 75 74 70 75 74 2c 20 70 4f 75 74 2c 20 30 2c 20  utput, pOut, 0, 
12b40 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 62 74  0);.}../*.** Obt
12b50 61 69 6e 20 61 20 70 61 74 63 68 73 65 74 20 6f  ain a patchset o
12b60 62 6a 65 63 74 20 63 6f 6e 74 61 69 6e 69 6e 67  bject containing
12b70 20 61 6c 6c 20 63 68 61 6e 67 65 73 20 72 65 63   all changes rec
12b80 6f 72 64 65 64 20 62 79 20 74 68 65 20 0a 2a 2a  orded by the .**
12b90 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20   session object 
12ba0 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69  passed as the fi
12bb0 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a  rst argument..**
12bc0 0a 2a 2a 20 49 74 20 69 73 20 74 68 65 20 72 65  .** It is the re
12bd0 73 70 6f 6e 73 69 62 69 6c 69 74 79 20 6f 66 20  sponsibility of 
12be0 74 68 65 20 63 61 6c 6c 65 72 20 74 6f 20 65 76  the caller to ev
12bf0 65 6e 74 75 61 6c 6c 79 20 66 72 65 65 20 74 68  entually free th
12c00 65 20 62 75 66 66 65 72 20 0a 2a 2a 20 75 73 69  e buffer .** usi
12c10 6e 67 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  ng sqlite3_free(
12c20 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  )..*/.int sqlite
12c30 33 73 65 73 73 69 6f 6e 5f 70 61 74 63 68 73 65  3session_patchse
12c40 74 28 0a 20 20 73 71 6c 69 74 65 33 5f 73 65 73  t(.  sqlite3_ses
12c50 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f 6e 2c 20  sion *pSession, 
12c60 20 20 20 20 20 2f 2a 20 53 65 73 73 69 6f 6e 20       /* Session 
12c70 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e 74 20  object */.  int 
12c80 2a 70 6e 50 61 74 63 68 73 65 74 2c 20 20 20 20  *pnPatchset,    
12c90 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
12ca0 55 54 3a 20 53 69 7a 65 20 6f 66 20 62 75 66 66  UT: Size of buff
12cb0 65 72 20 61 74 20 2a 70 70 43 68 61 6e 67 65 73  er at *ppChanges
12cc0 65 74 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 2a 70  et */.  void **p
12cd0 70 50 61 74 63 68 73 65 74 20 20 20 20 20 20 20  pPatchset       
12ce0 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
12cf0 42 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e  Buffer containin
12d00 67 20 63 68 61 6e 67 65 73 65 74 20 2a 2f 0a 29  g changeset */.)
12d10 7b 0a 20 20 72 65 74 75 72 6e 20 73 65 73 73 69  {.  return sessi
12d20 6f 6e 47 65 6e 65 72 61 74 65 43 68 61 6e 67 65  onGenerateChange
12d30 73 65 74 28 70 53 65 73 73 69 6f 6e 2c 20 31 2c  set(pSession, 1,
12d40 20 30 2c 20 30 2c 20 70 6e 50 61 74 63 68 73 65   0, 0, pnPatchse
12d50 74 2c 20 70 70 50 61 74 63 68 73 65 74 29 3b 0a  t, ppPatchset);.
12d60 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 61 62 6c 65 20  }../*.** Enable 
12d70 6f 72 20 64 69 73 61 62 6c 65 20 74 68 65 20 73  or disable the s
12d80 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 70 61  ession object pa
12d90 73 73 65 64 20 61 73 20 74 68 65 20 66 69 72 73  ssed as the firs
12da0 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 69  t argument..*/.i
12db0 6e 74 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f  nt sqlite3sessio
12dc0 6e 5f 65 6e 61 62 6c 65 28 73 71 6c 69 74 65 33  n_enable(sqlite3
12dd0 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69  _session *pSessi
12de0 6f 6e 2c 20 69 6e 74 20 62 45 6e 61 62 6c 65 29  on, int bEnable)
12df0 7b 0a 20 20 69 6e 74 20 72 65 74 3b 0a 20 20 73  {.  int ret;.  s
12e00 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74  qlite3_mutex_ent
12e10 65 72 28 73 71 6c 69 74 65 33 5f 64 62 5f 6d 75  er(sqlite3_db_mu
12e20 74 65 78 28 70 53 65 73 73 69 6f 6e 2d 3e 64 62  tex(pSession->db
12e30 29 29 3b 0a 20 20 69 66 28 20 62 45 6e 61 62 6c  ));.  if( bEnabl
12e40 65 3e 3d 30 20 29 7b 0a 20 20 20 20 70 53 65 73  e>=0 ){.    pSes
12e50 73 69 6f 6e 2d 3e 62 45 6e 61 62 6c 65 20 3d 20  sion->bEnable = 
12e60 62 45 6e 61 62 6c 65 3b 0a 20 20 7d 0a 20 20 72  bEnable;.  }.  r
12e70 65 74 20 3d 20 70 53 65 73 73 69 6f 6e 2d 3e 62  et = pSession->b
12e80 45 6e 61 62 6c 65 3b 0a 20 20 73 71 6c 69 74 65  Enable;.  sqlite
12e90 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 73 71  3_mutex_leave(sq
12ea0 6c 69 74 65 33 5f 64 62 5f 6d 75 74 65 78 28 70  lite3_db_mutex(p
12eb0 53 65 73 73 69 6f 6e 2d 3e 64 62 29 29 3b 0a 20  Session->db));. 
12ec0 20 72 65 74 75 72 6e 20 72 65 74 3b 0a 7d 0a 0a   return ret;.}..
12ed0 2f 2a 0a 2a 2a 20 45 6e 61 62 6c 65 20 6f 72 20  /*.** Enable or 
12ee0 64 69 73 61 62 6c 65 20 74 68 65 20 73 65 73 73  disable the sess
12ef0 69 6f 6e 20 6f 62 6a 65 63 74 20 70 61 73 73 65  ion object passe
12f00 64 20 61 73 20 74 68 65 20 66 69 72 73 74 20 61  d as the first a
12f10 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 69 6e 74 20  rgument..*/.int 
12f20 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 69  sqlite3session_i
12f30 6e 64 69 72 65 63 74 28 73 71 6c 69 74 65 33 5f  ndirect(sqlite3_
12f40 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f  session *pSessio
12f50 6e 2c 20 69 6e 74 20 62 49 6e 64 69 72 65 63 74  n, int bIndirect
12f60 29 7b 0a 20 20 69 6e 74 20 72 65 74 3b 0a 20 20  ){.  int ret;.  
12f70 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e  sqlite3_mutex_en
12f80 74 65 72 28 73 71 6c 69 74 65 33 5f 64 62 5f 6d  ter(sqlite3_db_m
12f90 75 74 65 78 28 70 53 65 73 73 69 6f 6e 2d 3e 64  utex(pSession->d
12fa0 62 29 29 3b 0a 20 20 69 66 28 20 62 49 6e 64 69  b));.  if( bIndi
12fb0 72 65 63 74 3e 3d 30 20 29 7b 0a 20 20 20 20 70  rect>=0 ){.    p
12fc0 53 65 73 73 69 6f 6e 2d 3e 62 49 6e 64 69 72 65  Session->bIndire
12fd0 63 74 20 3d 20 62 49 6e 64 69 72 65 63 74 3b 0a  ct = bIndirect;.
12fe0 20 20 7d 0a 20 20 72 65 74 20 3d 20 70 53 65 73    }.  ret = pSes
12ff0 73 69 6f 6e 2d 3e 62 49 6e 64 69 72 65 63 74 3b  sion->bIndirect;
13000 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  .  sqlite3_mutex
13010 5f 6c 65 61 76 65 28 73 71 6c 69 74 65 33 5f 64  _leave(sqlite3_d
13020 62 5f 6d 75 74 65 78 28 70 53 65 73 73 69 6f 6e  b_mutex(pSession
13030 2d 3e 64 62 29 29 3b 0a 20 20 72 65 74 75 72 6e  ->db));.  return
13040 20 72 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52   ret;.}../*.** R
13050 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 74 68  eturn true if th
13060 65 72 65 20 68 61 76 65 20 62 65 65 6e 20 6e 6f  ere have been no
13070 20 63 68 61 6e 67 65 73 20 74 6f 20 6d 6f 6e 69   changes to moni
13080 74 6f 72 65 64 20 74 61 62 6c 65 73 20 72 65 63  tored tables rec
13090 6f 72 64 65 64 0a 2a 2a 20 62 79 20 74 68 65 20  orded.** by the 
130a0 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 70  session object p
130b0 61 73 73 65 64 20 61 73 20 74 68 65 20 6f 6e 6c  assed as the onl
130c0 79 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 69  y argument..*/.i
130d0 6e 74 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f  nt sqlite3sessio
130e0 6e 5f 69 73 65 6d 70 74 79 28 73 71 6c 69 74 65  n_isempty(sqlite
130f0 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73  3_session *pSess
13100 69 6f 6e 29 7b 0a 20 20 69 6e 74 20 72 65 74 20  ion){.  int ret 
13110 3d 20 30 3b 0a 20 20 53 65 73 73 69 6f 6e 54 61  = 0;.  SessionTa
13120 62 6c 65 20 2a 70 54 61 62 3b 0a 0a 20 20 73 71  ble *pTab;..  sq
13130 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65  lite3_mutex_ente
13140 72 28 73 71 6c 69 74 65 33 5f 64 62 5f 6d 75 74  r(sqlite3_db_mut
13150 65 78 28 70 53 65 73 73 69 6f 6e 2d 3e 64 62 29  ex(pSession->db)
13160 29 3b 0a 20 20 66 6f 72 28 70 54 61 62 3d 70 53  );.  for(pTab=pS
13170 65 73 73 69 6f 6e 2d 3e 70 54 61 62 6c 65 3b 20  ession->pTable; 
13180 70 54 61 62 20 26 26 20 72 65 74 3d 3d 30 3b 20  pTab && ret==0; 
13190 70 54 61 62 3d 70 54 61 62 2d 3e 70 4e 65 78 74  pTab=pTab->pNext
131a0 29 7b 0a 20 20 20 20 72 65 74 20 3d 20 28 70 54  ){.    ret = (pT
131b0 61 62 2d 3e 6e 45 6e 74 72 79 3e 30 29 3b 0a 20  ab->nEntry>0);. 
131c0 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74   }.  sqlite3_mut
131d0 65 78 5f 6c 65 61 76 65 28 73 71 6c 69 74 65 33  ex_leave(sqlite3
131e0 5f 64 62 5f 6d 75 74 65 78 28 70 53 65 73 73 69  _db_mutex(pSessi
131f0 6f 6e 2d 3e 64 62 29 29 3b 0a 0a 20 20 72 65 74  on->db));..  ret
13200 75 72 6e 20 28 72 65 74 3d 3d 30 29 3b 0a 7d 0a  urn (ret==0);.}.
13210 0a 2f 2a 0a 2a 2a 20 44 6f 20 74 68 65 20 77 6f  ./*.** Do the wo
13220 72 6b 20 66 6f 72 20 65 69 74 68 65 72 20 73 71  rk for either sq
13230 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 73  lite3changeset_s
13240 74 61 72 74 28 29 20 6f 72 20 73 74 61 72 74 5f  tart() or start_
13250 73 74 72 6d 28 29 2e 0a 2a 2f 0a 73 74 61 74 69  strm()..*/.stati
13260 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 43 68 61  c int sessionCha
13270 6e 67 65 73 65 74 53 74 61 72 74 28 0a 20 20 73  ngesetStart(.  s
13280 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74  qlite3_changeset
13290 5f 69 74 65 72 20 2a 2a 70 70 2c 20 20 20 20 2f  _iter **pp,    /
132a0 2a 20 4f 55 54 3a 20 43 68 61 6e 67 65 73 65 74  * OUT: Changeset
132b0 20 69 74 65 72 61 74 6f 72 20 68 61 6e 64 6c 65   iterator handle
132c0 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 49 6e 70   */.  int (*xInp
132d0 75 74 29 28 76 6f 69 64 20 2a 70 49 6e 2c 20 76  ut)(void *pIn, v
132e0 6f 69 64 20 2a 70 44 61 74 61 2c 20 69 6e 74 20  oid *pData, int 
132f0 2a 70 6e 44 61 74 61 29 2c 0a 20 20 76 6f 69 64  *pnData),.  void
13300 20 2a 70 49 6e 2c 0a 20 20 69 6e 74 20 6e 43 68   *pIn,.  int nCh
13310 61 6e 67 65 73 65 74 2c 20 20 20 20 20 20 20 20  angeset,        
13320 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
13330 20 6f 66 20 62 75 66 66 65 72 20 70 43 68 61 6e   of buffer pChan
13340 67 65 73 65 74 20 69 6e 20 62 79 74 65 73 20 2a  geset in bytes *
13350 2f 0a 20 20 76 6f 69 64 20 2a 70 43 68 61 6e 67  /.  void *pChang
13360 65 73 65 74 20 20 20 20 20 20 20 20 20 20 20 20  eset            
13370 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74      /* Pointer t
13380 6f 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69 6e  o buffer contain
13390 69 6e 67 20 63 68 61 6e 67 65 73 65 74 20 2a 2f  ing changeset */
133a0 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 63 68  .){.  sqlite3_ch
133b0 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a 70 52  angeset_iter *pR
133c0 65 74 3b 20 20 20 2f 2a 20 49 74 65 72 61 74 6f  et;   /* Iterato
133d0 72 20 74 6f 20 72 65 74 75 72 6e 20 2a 2f 0a 20  r to return */. 
133e0 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20   int nByte;     
133f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13400 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79   /* Number of by
13410 74 65 73 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20  tes to allocate 
13420 66 6f 72 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a  for iterator */.
13430 0a 20 20 61 73 73 65 72 74 28 20 78 49 6e 70 75  .  assert( xInpu
13440 74 3d 3d 30 20 7c 7c 20 28 70 43 68 61 6e 67 65  t==0 || (pChange
13450 73 65 74 3d 3d 30 20 26 26 20 6e 43 68 61 6e 67  set==0 && nChang
13460 65 73 65 74 3d 3d 30 29 20 29 3b 0a 0a 20 20 2f  eset==0) );..  /
13470 2a 20 5a 65 72 6f 20 74 68 65 20 6f 75 74 70 75  * Zero the outpu
13480 74 20 76 61 72 69 61 62 6c 65 20 69 6e 20 63 61  t variable in ca
13490 73 65 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  se an error occu
134a0 72 73 2e 20 2a 2f 0a 20 20 2a 70 70 20 3d 20 30  rs. */.  *pp = 0
134b0 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65  ;..  /* Allocate
134c0 20 61 6e 64 20 69 6e 69 74 69 61 6c 69 7a 65 20   and initialize 
134d0 74 68 65 20 69 74 65 72 61 74 6f 72 20 73 74 72  the iterator str
134e0 75 63 74 75 72 65 2e 20 2a 2f 0a 20 20 6e 42 79  ucture. */.  nBy
134f0 74 65 20 3d 20 73 69 7a 65 6f 66 28 73 71 6c 69  te = sizeof(sqli
13500 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74  te3_changeset_it
13510 65 72 29 3b 0a 20 20 70 52 65 74 20 3d 20 28 73  er);.  pRet = (s
13520 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74  qlite3_changeset
13530 5f 69 74 65 72 20 2a 29 73 71 6c 69 74 65 33 5f  _iter *)sqlite3_
13540 6d 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20  malloc(nByte);. 
13550 20 69 66 28 20 21 70 52 65 74 20 29 20 72 65 74   if( !pRet ) ret
13560 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
13570 3b 0a 20 20 6d 65 6d 73 65 74 28 70 52 65 74 2c  ;.  memset(pRet,
13580 20 30 2c 20 73 69 7a 65 6f 66 28 73 71 6c 69 74   0, sizeof(sqlit
13590 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65  e3_changeset_ite
135a0 72 29 29 3b 0a 20 20 70 52 65 74 2d 3e 69 6e 2e  r));.  pRet->in.
135b0 61 44 61 74 61 20 3d 20 28 75 38 20 2a 29 70 43  aData = (u8 *)pC
135c0 68 61 6e 67 65 73 65 74 3b 0a 20 20 70 52 65 74  hangeset;.  pRet
135d0 2d 3e 69 6e 2e 6e 44 61 74 61 20 3d 20 6e 43 68  ->in.nData = nCh
135e0 61 6e 67 65 73 65 74 3b 0a 20 20 70 52 65 74 2d  angeset;.  pRet-
135f0 3e 69 6e 2e 78 49 6e 70 75 74 20 3d 20 78 49 6e  >in.xInput = xIn
13600 70 75 74 3b 0a 20 20 70 52 65 74 2d 3e 69 6e 2e  put;.  pRet->in.
13610 70 49 6e 20 3d 20 70 49 6e 3b 0a 20 20 70 52 65  pIn = pIn;.  pRe
13620 74 2d 3e 69 6e 2e 62 45 6f 66 20 3d 20 28 78 49  t->in.bEof = (xI
13630 6e 70 75 74 20 3f 20 30 20 3a 20 31 29 3b 0a 0a  nput ? 0 : 1);..
13640 20 20 2f 2a 20 50 6f 70 75 6c 61 74 65 20 74 68    /* Populate th
13650 65 20 6f 75 74 70 75 74 20 76 61 72 69 61 62 6c  e output variabl
13660 65 20 61 6e 64 20 72 65 74 75 72 6e 20 73 75 63  e and return suc
13670 63 65 73 73 2e 20 2a 2f 0a 20 20 2a 70 70 20 3d  cess. */.  *pp =
13680 20 70 52 65 74 3b 0a 20 20 72 65 74 75 72 6e 20   pRet;.  return 
13690 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
136a0 0a 2a 2a 20 43 72 65 61 74 65 20 61 6e 20 69 74  .** Create an it
136b0 65 72 61 74 6f 72 20 75 73 65 64 20 74 6f 20 69  erator used to i
136c0 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 74  terate through t
136d0 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61  he contents of a
136e0 20 63 68 61 6e 67 65 73 65 74 2e 0a 2a 2f 0a 69   changeset..*/.i
136f0 6e 74 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65  nt sqlite3change
13700 73 65 74 5f 73 74 61 72 74 28 0a 20 20 73 71 6c  set_start(.  sql
13710 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69  ite3_changeset_i
13720 74 65 72 20 2a 2a 70 70 2c 20 20 20 20 2f 2a 20  ter **pp,    /* 
13730 4f 55 54 3a 20 43 68 61 6e 67 65 73 65 74 20 69  OUT: Changeset i
13740 74 65 72 61 74 6f 72 20 68 61 6e 64 6c 65 20 2a  terator handle *
13750 2f 0a 20 20 69 6e 74 20 6e 43 68 61 6e 67 65 73  /.  int nChanges
13760 65 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  et,             
13770 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 62      /* Size of b
13780 75 66 66 65 72 20 70 43 68 61 6e 67 65 73 65 74  uffer pChangeset
13790 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 76   in bytes */.  v
137a0 6f 69 64 20 2a 70 43 68 61 6e 67 65 73 65 74 20  oid *pChangeset 
137b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
137c0 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 62 75 66  * Pointer to buf
137d0 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 63  fer containing c
137e0 68 61 6e 67 65 73 65 74 20 2a 2f 0a 29 7b 0a 20  hangeset */.){. 
137f0 20 72 65 74 75 72 6e 20 73 65 73 73 69 6f 6e 43   return sessionC
13800 68 61 6e 67 65 73 65 74 53 74 61 72 74 28 70 70  hangesetStart(pp
13810 2c 20 30 2c 20 30 2c 20 6e 43 68 61 6e 67 65 73  , 0, 0, nChanges
13820 65 74 2c 20 70 43 68 61 6e 67 65 73 65 74 29 3b  et, pChangeset);
13830 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 74 72 65 61 6d  .}../*.** Stream
13840 69 6e 67 20 76 65 72 73 69 6f 6e 20 6f 66 20 73  ing version of s
13850 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
13860 73 74 61 72 74 28 29 2e 0a 2a 2f 0a 69 6e 74 20  start()..*/.int 
13870 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
13880 5f 73 74 61 72 74 5f 73 74 72 6d 28 0a 20 20 73  _start_strm(.  s
13890 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74  qlite3_changeset
138a0 5f 69 74 65 72 20 2a 2a 70 70 2c 20 20 20 20 2f  _iter **pp,    /
138b0 2a 20 4f 55 54 3a 20 43 68 61 6e 67 65 73 65 74  * OUT: Changeset
138c0 20 69 74 65 72 61 74 6f 72 20 68 61 6e 64 6c 65   iterator handle
138d0 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 49 6e 70   */.  int (*xInp
138e0 75 74 29 28 76 6f 69 64 20 2a 70 49 6e 2c 20 76  ut)(void *pIn, v
138f0 6f 69 64 20 2a 70 44 61 74 61 2c 20 69 6e 74 20  oid *pData, int 
13900 2a 70 6e 44 61 74 61 29 2c 0a 20 20 76 6f 69 64  *pnData),.  void
13910 20 2a 70 49 6e 0a 29 7b 0a 20 20 72 65 74 75 72   *pIn.){.  retur
13920 6e 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73  n sessionChanges
13930 65 74 53 74 61 72 74 28 70 70 2c 20 78 49 6e 70  etStart(pp, xInp
13940 75 74 2c 20 70 49 6e 2c 20 30 2c 20 30 29 3b 0a  ut, pIn, 0, 0);.
13950 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 20  }../*.** If the 
13960 53 65 73 73 69 6f 6e 49 6e 70 75 74 20 6f 62 6a  SessionInput obj
13970 65 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68  ect passed as th
13980 65 20 6f 6e 6c 79 20 61 72 67 75 6d 65 6e 74 20  e only argument 
13990 69 73 20 61 20 73 74 72 65 61 6d 69 6e 67 0a 2a  is a streaming.*
139a0 2a 20 6f 62 6a 65 63 74 20 61 6e 64 20 74 68 65  * object and the
139b0 20 62 75 66 66 65 72 20 69 73 20 66 75 6c 6c 2c   buffer is full,
139c0 20 64 69 73 63 61 72 64 20 73 6f 6d 65 20 64 61   discard some da
139d0 74 61 20 74 6f 20 66 72 65 65 20 75 70 20 73 70  ta to free up sp
139e0 61 63 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ace..*/.static v
139f0 6f 69 64 20 73 65 73 73 69 6f 6e 44 69 73 63 61  oid sessionDisca
13a00 72 64 44 61 74 61 28 53 65 73 73 69 6f 6e 49 6e  rdData(SessionIn
13a10 70 75 74 20 2a 70 49 6e 29 7b 0a 20 20 69 66 28  put *pIn){.  if(
13a20 20 70 49 6e 2d 3e 62 45 6f 66 20 26 26 20 70 49   pIn->bEof && pI
13a30 6e 2d 3e 78 49 6e 70 75 74 20 26 26 20 70 49 6e  n->xInput && pIn
13a40 2d 3e 69 4e 65 78 74 3e 3d 53 45 53 53 49 4f 4e  ->iNext>=SESSION
13a50 53 5f 53 54 52 4d 5f 43 48 55 4e 4b 5f 53 49 5a  S_STRM_CHUNK_SIZ
13a60 45 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 4d 6f  E ){.    int nMo
13a70 76 65 20 3d 20 70 49 6e 2d 3e 62 75 66 2e 6e 42  ve = pIn->buf.nB
13a80 75 66 20 2d 20 70 49 6e 2d 3e 69 4e 65 78 74 3b  uf - pIn->iNext;
13a90 0a 20 20 20 20 61 73 73 65 72 74 28 20 6e 4d 6f  .    assert( nMo
13aa0 76 65 3e 3d 30 20 29 3b 0a 20 20 20 20 69 66 28  ve>=0 );.    if(
13ab0 20 6e 4d 6f 76 65 3e 30 20 29 7b 0a 20 20 20 20   nMove>0 ){.    
13ac0 20 20 6d 65 6d 6d 6f 76 65 28 70 49 6e 2d 3e 62    memmove(pIn->b
13ad0 75 66 2e 61 42 75 66 2c 20 26 70 49 6e 2d 3e 62  uf.aBuf, &pIn->b
13ae0 75 66 2e 61 42 75 66 5b 70 49 6e 2d 3e 69 4e 65  uf.aBuf[pIn->iNe
13af0 78 74 5d 2c 20 6e 4d 6f 76 65 29 3b 0a 20 20 20  xt], nMove);.   
13b00 20 7d 0a 20 20 20 20 70 49 6e 2d 3e 62 75 66 2e   }.    pIn->buf.
13b10 6e 42 75 66 20 2d 3d 20 70 49 6e 2d 3e 69 4e 65  nBuf -= pIn->iNe
13b20 78 74 3b 0a 20 20 20 20 70 49 6e 2d 3e 69 4e 65  xt;.    pIn->iNe
13b30 78 74 20 3d 20 30 3b 0a 20 20 20 20 70 49 6e 2d  xt = 0;.    pIn-
13b40 3e 6e 44 61 74 61 20 3d 20 70 49 6e 2d 3e 62 75  >nData = pIn->bu
13b50 66 2e 6e 42 75 66 3b 0a 20 20 7d 0a 7d 0a 0a 2f  f.nBuf;.  }.}../
13b60 2a 0a 2a 2a 20 45 6e 73 75 72 65 20 74 68 61 74  *.** Ensure that
13b70 20 74 68 65 72 65 20 61 72 65 20 61 74 20 6c 65   there are at le
13b80 61 73 74 20 6e 42 79 74 65 20 62 79 74 65 73 20  ast nByte bytes 
13b90 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65  available in the
13ba0 20 62 75 66 66 65 72 2e 20 4f 72 2c 0a 2a 2a 20   buffer. Or,.** 
13bb0 69 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f 74  if there are not
13bc0 20 6e 42 79 74 65 20 62 79 74 65 73 20 72 65 6d   nByte bytes rem
13bd0 61 69 6e 69 6e 67 20 69 6e 20 74 68 65 20 69 6e  aining in the in
13be0 70 75 74 2c 20 74 68 61 74 20 61 6c 6c 20 61 76  put, that all av
13bf0 61 69 6c 61 62 6c 65 0a 2a 2a 20 64 61 74 61 20  ailable.** data 
13c00 69 73 20 69 6e 20 74 68 65 20 62 75 66 66 65 72  is in the buffer
13c10 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61  ..**.** Return a
13c20 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  n SQLite error c
13c30 6f 64 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20  ode if an error 
13c40 6f 63 63 75 72 73 2c 20 6f 72 20 53 51 4c 49 54  occurs, or SQLIT
13c50 45 5f 4f 4b 20 6f 74 68 65 72 77 69 73 65 2e 0a  E_OK otherwise..
13c60 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
13c70 73 73 69 6f 6e 49 6e 70 75 74 42 75 66 66 65 72  ssionInputBuffer
13c80 28 53 65 73 73 69 6f 6e 49 6e 70 75 74 20 2a 70  (SessionInput *p
13c90 49 6e 2c 20 69 6e 74 20 6e 42 79 74 65 29 7b 0a  In, int nByte){.
13ca0 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
13cb0 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70 49 6e 2d  E_OK;.  if( pIn-
13cc0 3e 78 49 6e 70 75 74 20 29 7b 0a 20 20 20 20 77  >xInput ){.    w
13cd0 68 69 6c 65 28 20 21 70 49 6e 2d 3e 62 45 6f 66  hile( !pIn->bEof
13ce0 20 26 26 20 28 70 49 6e 2d 3e 69 4e 65 78 74 2b   && (pIn->iNext+
13cf0 6e 42 79 74 65 29 3e 3d 70 49 6e 2d 3e 6e 44 61  nByte)>=pIn->nDa
13d00 74 61 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45  ta && rc==SQLITE
13d10 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  _OK ){.      int
13d20 20 6e 4e 65 77 20 3d 20 53 45 53 53 49 4f 4e 53   nNew = SESSIONS
13d30 5f 53 54 52 4d 5f 43 48 55 4e 4b 5f 53 49 5a 45  _STRM_CHUNK_SIZE
13d40 3b 0a 0a 20 20 20 20 20 20 69 66 28 20 70 49 6e  ;..      if( pIn
13d50 2d 3e 62 4e 6f 44 69 73 63 61 72 64 3d 3d 30 20  ->bNoDiscard==0 
13d60 29 20 73 65 73 73 69 6f 6e 44 69 73 63 61 72 64  ) sessionDiscard
13d70 44 61 74 61 28 70 49 6e 29 3b 0a 20 20 20 20 20  Data(pIn);.     
13d80 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d   if( SQLITE_OK==
13d90 73 65 73 73 69 6f 6e 42 75 66 66 65 72 47 72 6f  sessionBufferGro
13da0 77 28 26 70 49 6e 2d 3e 62 75 66 2c 20 6e 4e 65  w(&pIn->buf, nNe
13db0 77 2c 20 26 72 63 29 20 29 7b 0a 20 20 20 20 20  w, &rc) ){.     
13dc0 20 20 20 72 63 20 3d 20 70 49 6e 2d 3e 78 49 6e     rc = pIn->xIn
13dd0 70 75 74 28 70 49 6e 2d 3e 70 49 6e 2c 20 26 70  put(pIn->pIn, &p
13de0 49 6e 2d 3e 62 75 66 2e 61 42 75 66 5b 70 49 6e  In->buf.aBuf[pIn
13df0 2d 3e 62 75 66 2e 6e 42 75 66 5d 2c 20 26 6e 4e  ->buf.nBuf], &nN
13e00 65 77 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  ew);.        if(
13e10 20 6e 4e 65 77 3d 3d 30 20 29 7b 0a 20 20 20 20   nNew==0 ){.    
13e20 20 20 20 20 20 20 70 49 6e 2d 3e 62 45 6f 66 20        pIn->bEof 
13e30 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  = 1;.        }el
13e40 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 70 49  se{.          pI
13e50 6e 2d 3e 62 75 66 2e 6e 42 75 66 20 2b 3d 20 6e  n->buf.nBuf += n
13e60 4e 65 77 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  New;.        }. 
13e70 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 70 49       }..      pI
13e80 6e 2d 3e 61 44 61 74 61 20 3d 20 70 49 6e 2d 3e  n->aData = pIn->
13e90 62 75 66 2e 61 42 75 66 3b 0a 20 20 20 20 20 20  buf.aBuf;.      
13ea0 70 49 6e 2d 3e 6e 44 61 74 61 20 3d 20 70 49 6e  pIn->nData = pIn
13eb0 2d 3e 62 75 66 2e 6e 42 75 66 3b 0a 20 20 20 20  ->buf.nBuf;.    
13ec0 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  }.  }.  return r
13ed0 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 68 65 6e  c;.}../*.** When
13ee0 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
13ef0 73 20 63 61 6c 6c 65 64 2c 20 2a 70 70 52 65 63  s called, *ppRec
13f00 20 70 6f 69 6e 74 73 20 74 6f 20 74 68 65 20 73   points to the s
13f10 74 61 72 74 20 6f 66 20 61 20 72 65 63 6f 72 64  tart of a record
13f20 0a 2a 2a 20 74 68 61 74 20 63 6f 6e 74 61 69 6e  .** that contain
13f30 73 20 6e 43 6f 6c 20 76 61 6c 75 65 73 2e 20 54  s nCol values. T
13f40 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 61 64 76  his function adv
13f50 61 6e 63 65 73 20 74 68 65 20 70 6f 69 6e 74 65  ances the pointe
13f60 72 20 2a 70 70 52 65 63 0a 2a 2a 20 75 6e 74 69  r *ppRec.** unti
13f70 6c 20 69 74 20 70 6f 69 6e 74 73 20 74 6f 20 74  l it points to t
13f80 68 65 20 62 79 74 65 20 69 6d 6d 65 64 69 61 74  he byte immediat
13f90 65 6c 79 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68  ely following th
13fa0 61 74 20 72 65 63 6f 72 64 2e 0a 2a 2f 0a 73 74  at record..*/.st
13fb0 61 74 69 63 20 76 6f 69 64 20 73 65 73 73 69 6f  atic void sessio
13fc0 6e 53 6b 69 70 52 65 63 6f 72 64 28 0a 20 20 75  nSkipRecord(.  u
13fd0 38 20 2a 2a 70 70 52 65 63 2c 20 20 20 20 20 20  8 **ppRec,      
13fe0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
13ff0 2a 20 49 4e 2f 4f 55 54 3a 20 52 65 63 6f 72 64  * IN/OUT: Record
14000 20 70 6f 69 6e 74 65 72 20 2a 2f 0a 20 20 69 6e   pointer */.  in
14010 74 20 6e 43 6f 6c 20 20 20 20 20 20 20 20 20 20  t nCol          
14020 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
14030 20 4e 75 6d 62 65 72 20 6f 66 20 76 61 6c 75 65   Number of value
14040 73 20 69 6e 20 72 65 63 6f 72 64 20 2a 2f 0a 29  s in record */.)
14050 7b 0a 20 20 75 38 20 2a 61 52 65 63 20 3d 20 2a  {.  u8 *aRec = *
14060 70 70 52 65 63 3b 0a 20 20 69 6e 74 20 69 3b 0a  ppRec;.  int i;.
14070 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43 6f    for(i=0; i<nCo
14080 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74  l; i++){.    int
14090 20 65 54 79 70 65 20 3d 20 2a 61 52 65 63 2b 2b   eType = *aRec++
140a0 3b 0a 20 20 20 20 69 66 28 20 65 54 79 70 65 3d  ;.    if( eType=
140b0 3d 53 51 4c 49 54 45 5f 54 45 58 54 20 7c 7c 20  =SQLITE_TEXT || 
140c0 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 42 4c  eType==SQLITE_BL
140d0 4f 42 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  OB ){.      int 
140e0 6e 42 79 74 65 3b 0a 20 20 20 20 20 20 61 52 65  nByte;.      aRe
140f0 63 20 2b 3d 20 73 65 73 73 69 6f 6e 56 61 72 69  c += sessionVari
14100 6e 74 47 65 74 28 28 75 38 2a 29 61 52 65 63 2c  ntGet((u8*)aRec,
14110 20 26 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20   &nByte);.      
14120 61 52 65 63 20 2b 3d 20 6e 42 79 74 65 3b 0a 20  aRec += nByte;. 
14130 20 20 20 7d 65 6c 73 65 20 69 66 28 20 65 54 79     }else if( eTy
14140 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47  pe==SQLITE_INTEG
14150 45 52 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c  ER || eType==SQL
14160 49 54 45 5f 46 4c 4f 41 54 20 29 7b 0a 20 20 20  ITE_FLOAT ){.   
14170 20 20 20 61 52 65 63 20 2b 3d 20 38 3b 0a 20 20     aRec += 8;.  
14180 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 52 65    }.  }..  *ppRe
14190 63 20 3d 20 61 52 65 63 3b 0a 7d 0a 0a 2f 2a 0a  c = aRec;.}../*.
141a0 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
141b0 20 73 65 74 73 20 74 68 65 20 76 61 6c 75 65 20   sets the value 
141c0 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 76  of the sqlite3_v
141d0 61 6c 75 65 20 6f 62 6a 65 63 74 20 70 61 73 73  alue object pass
141e0 65 64 20 61 73 20 74 68 65 0a 2a 2a 20 66 69 72  ed as the.** fir
141f0 73 74 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 61  st argument to a
14200 20 63 6f 70 79 20 6f 66 20 74 68 65 20 73 74 72   copy of the str
14210 69 6e 67 20 6f 72 20 62 6c 6f 62 20 68 65 6c 64  ing or blob held
14220 20 69 6e 20 74 68 65 20 61 44 61 74 61 5b 5d 20   in the aData[] 
14230 0a 2a 2a 20 62 75 66 66 65 72 2e 20 53 51 4c 49  .** buffer. SQLI
14240 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65  TE_OK is returne
14250 64 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c  d if successful,
14260 20 6f 72 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d   or SQLITE_NOMEM
14270 20 69 66 20 61 6e 20 4f 4f 4d 0a 2a 2a 20 65 72   if an OOM.** er
14280 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73  ror occurs..*/.s
14290 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f  tatic int sessio
142a0 6e 56 61 6c 75 65 53 65 74 53 74 72 28 0a 20 20  nValueSetStr(.  
142b0 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70  sqlite3_value *p
142c0 56 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20  Val,            
142d0 2f 2a 20 53 65 74 20 74 68 65 20 76 61 6c 75 65  /* Set the value
142e0 20 6f 66 20 74 68 69 73 20 6f 62 6a 65 63 74 20   of this object 
142f0 2a 2f 0a 20 20 75 38 20 2a 61 44 61 74 61 2c 20  */.  u8 *aData, 
14300 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14310 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 63       /* Buffer c
14320 6f 6e 74 61 69 6e 69 6e 67 20 73 74 72 69 6e 67  ontaining string
14330 20 6f 72 20 62 6c 6f 62 20 64 61 74 61 20 2a 2f   or blob data */
14340 0a 20 20 69 6e 74 20 6e 44 61 74 61 2c 20 20 20  .  int nData,   
14350 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14360 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 62 75     /* Size of bu
14370 66 66 65 72 20 61 44 61 74 61 5b 5d 20 69 6e 20  ffer aData[] in 
14380 62 79 74 65 73 20 2a 2f 0a 20 20 75 38 20 65 6e  bytes */.  u8 en
14390 63 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c               
143a0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74             /* St
143b0 72 69 6e 67 20 65 6e 63 6f 64 69 6e 67 20 28 30  ring encoding (0
143c0 20 66 6f 72 20 62 6c 6f 62 73 29 20 2a 2f 0a 29   for blobs) */.)
143d0 7b 0a 20 20 2f 2a 20 49 6e 20 74 68 65 6f 72 79  {.  /* In theory
143e0 20 74 68 69 73 20 63 6f 64 65 20 63 6f 75 6c 64   this code could
143f0 20 6a 75 73 74 20 70 61 73 73 20 53 51 4c 49 54   just pass SQLIT
14400 45 5f 54 52 41 4e 53 49 45 4e 54 20 61 73 20 74  E_TRANSIENT as t
14410 68 65 20 66 69 6e 61 6c 0a 20 20 2a 2a 20 61 72  he final.  ** ar
14420 67 75 6d 65 6e 74 20 74 6f 20 73 71 6c 69 74 65  gument to sqlite
14430 33 56 61 6c 75 65 53 65 74 53 74 72 28 29 20 61  3ValueSetStr() a
14440 6e 64 20 68 61 76 65 20 74 68 65 20 63 6f 70 79  nd have the copy
14450 20 63 72 65 61 74 65 64 20 0a 20 20 2a 2a 20 61   created .  ** a
14460 75 74 6f 6d 61 74 69 63 61 6c 6c 79 2e 20 42 75  utomatically. Bu
14470 74 20 64 6f 69 6e 67 20 73 6f 20 6d 61 6b 65 73  t doing so makes
14480 20 69 74 20 64 69 66 66 69 63 75 6c 74 20 74 6f   it difficult to
14490 20 64 65 74 65 63 74 20 61 6e 79 20 4f 4f 4d 0a   detect any OOM.
144a0 20 20 2a 2a 20 65 72 72 6f 72 2e 20 48 65 6e 63    ** error. Henc
144b0 65 20 74 68 65 20 63 6f 64 65 20 74 6f 20 63 72  e the code to cr
144c0 65 61 74 65 20 74 68 65 20 63 6f 70 79 20 65 78  eate the copy ex
144d0 74 65 72 6e 61 6c 6c 79 2e 20 2a 2f 0a 20 20 75  ternally. */.  u
144e0 38 20 2a 61 43 6f 70 79 20 3d 20 73 71 6c 69 74  8 *aCopy = sqlit
144f0 65 33 5f 6d 61 6c 6c 6f 63 28 6e 44 61 74 61 2b  e3_malloc(nData+
14500 31 29 3b 0a 20 20 69 66 28 20 61 43 6f 70 79 3d  1);.  if( aCopy=
14510 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  =0 ) return SQLI
14520 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d 65 6d 63  TE_NOMEM;.  memc
14530 70 79 28 61 43 6f 70 79 2c 20 61 44 61 74 61 2c  py(aCopy, aData,
14540 20 6e 44 61 74 61 29 3b 0a 20 20 73 71 6c 69 74   nData);.  sqlit
14550 65 33 56 61 6c 75 65 53 65 74 53 74 72 28 70 56  e3ValueSetStr(pV
14560 61 6c 2c 20 6e 44 61 74 61 2c 20 28 63 68 61 72  al, nData, (char
14570 2a 29 61 43 6f 70 79 2c 20 65 6e 63 2c 20 73 71  *)aCopy, enc, sq
14580 6c 69 74 65 33 5f 66 72 65 65 29 3b 0a 20 20 72  lite3_free);.  r
14590 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
145a0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 73 65 72 69  .}../*.** Deseri
145b0 61 6c 69 7a 65 20 61 20 73 69 6e 67 6c 65 20 72  alize a single r
145c0 65 63 6f 72 64 20 66 72 6f 6d 20 61 20 62 75 66  ecord from a buf
145d0 66 65 72 20 69 6e 20 6d 65 6d 6f 72 79 2e 20 53  fer in memory. S
145e0 65 65 20 22 52 45 43 4f 52 44 20 46 4f 52 4d 41  ee "RECORD FORMA
145f0 54 22 0a 2a 2a 20 66 6f 72 20 64 65 74 61 69 6c  T".** for detail
14600 73 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 74 68  s..**.** When th
14610 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
14620 61 6c 6c 65 64 2c 20 2a 70 61 43 68 61 6e 67 65  alled, *paChange
14630 20 70 6f 69 6e 74 73 20 74 6f 20 74 68 65 20 73   points to the s
14640 74 61 72 74 20 6f 66 20 74 68 65 20 72 65 63 6f  tart of the reco
14650 72 64 0a 2a 2a 20 74 6f 20 64 65 73 65 72 69 61  rd.** to deseria
14660 6c 69 7a 65 2e 20 41 73 73 75 6d 69 6e 67 20 6e  lize. Assuming n
14670 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20  o error occurs, 
14680 2a 70 61 43 68 61 6e 67 65 20 69 73 20 73 65 74  *paChange is set
14690 20 74 6f 20 70 6f 69 6e 74 20 74 6f 0a 2a 2a 20   to point to.** 
146a0 6f 6e 65 20 62 79 74 65 20 61 66 74 65 72 20 74  one byte after t
146b0 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 73 61  he end of the sa
146c0 6d 65 20 72 65 63 6f 72 64 20 62 65 66 6f 72 65  me record before
146d0 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72   this function r
146e0 65 74 75 72 6e 73 2e 0a 2a 2a 20 49 66 20 74 68  eturns..** If th
146f0 65 20 61 72 67 75 6d 65 6e 74 20 61 62 50 4b 20  e argument abPK 
14700 69 73 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 74 68  is NULL, then th
14710 65 20 72 65 63 6f 72 64 20 63 6f 6e 74 61 69 6e  e record contain
14720 73 20 6e 43 6f 6c 20 76 61 6c 75 65 73 2e 20 4f  s nCol values. O
14730 72 2c 0a 2a 2a 20 69 66 20 61 62 50 4b 20 69 73  r,.** if abPK is
14740 20 6f 74 68 65 72 20 74 68 61 6e 20 4e 55 4c 4c   other than NULL
14750 2c 20 74 68 65 6e 20 74 68 65 20 72 65 63 6f 72  , then the recor
14760 64 20 63 6f 6e 74 61 69 6e 73 20 6f 6e 6c 79 20  d contains only 
14770 74 68 65 20 50 4b 20 66 69 65 6c 64 73 0a 2a 2a  the PK fields.**
14780 20 28 69 6e 20 6f 74 68 65 72 20 77 6f 72 64 73   (in other words
14790 2c 20 69 74 20 69 73 20 61 20 70 61 74 63 68 73  , it is a patchs
147a0 65 74 20 44 45 4c 45 54 45 20 72 65 63 6f 72 64  et DELETE record
147b0 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63  )..**.** If succ
147c0 65 73 73 66 75 6c 2c 20 65 61 63 68 20 65 6c 65  essful, each ele
147d0 6d 65 6e 74 20 6f 66 20 74 68 65 20 61 70 4f 75  ment of the apOu
147e0 74 5b 5d 20 61 72 72 61 79 20 28 61 6c 6c 6f 63  t[] array (alloc
147f0 61 74 65 64 20 62 79 20 74 68 65 20 63 61 6c 6c  ated by the call
14800 65 72 29 0a 2a 2a 20 69 73 20 73 65 74 20 74 6f  er).** is set to
14810 20 70 6f 69 6e 74 20 74 6f 20 61 6e 20 73 71 6c   point to an sql
14820 69 74 65 33 5f 76 61 6c 75 65 20 6f 62 6a 65 63  ite3_value objec
14830 74 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65  t containing the
14840 20 76 61 6c 75 65 20 72 65 61 64 0a 2a 2a 20 66   value read.** f
14850 72 6f 6d 20 74 68 65 20 63 6f 72 72 65 73 70 6f  rom the correspo
14860 6e 64 69 6e 67 20 70 6f 73 69 74 69 6f 6e 20 69  nding position i
14870 6e 20 74 68 65 20 72 65 63 6f 72 64 2e 20 49 66  n the record. If
14880 20 74 68 61 74 20 76 61 6c 75 65 20 69 73 20 6e   that value is n
14890 6f 74 0a 2a 2a 20 69 6e 63 6c 75 64 65 64 20 69  ot.** included i
148a0 6e 20 74 68 65 20 72 65 63 6f 72 64 20 28 69 2e  n the record (i.
148b0 65 2e 20 62 65 63 61 75 73 65 20 74 68 65 20 72  e. because the r
148c0 65 63 6f 72 64 20 69 73 20 70 61 72 74 20 6f 66  ecord is part of
148d0 20 61 6e 20 55 50 44 41 54 45 20 63 68 61 6e 67   an UPDATE chang
148e0 65 0a 2a 2a 20 61 6e 64 20 74 68 65 20 66 69 65  e.** and the fie
148f0 6c 64 20 77 61 73 20 6e 6f 74 20 6d 6f 64 69 66  ld was not modif
14900 69 65 64 29 2c 20 74 68 65 20 63 6f 72 72 65 73  ied), the corres
14910 70 6f 6e 64 69 6e 67 20 65 6c 65 6d 65 6e 74 20  ponding element 
14920 6f 66 20 61 70 4f 75 74 5b 5d 20 69 73 0a 2a 2a  of apOut[] is.**
14930 20 73 65 74 20 74 6f 20 4e 55 4c 4c 2e 0a 2a 2a   set to NULL..**
14940 0a 2a 2a 20 49 74 20 69 73 20 74 68 65 20 72 65  .** It is the re
14950 73 70 6f 6e 73 69 62 69 6c 69 74 79 20 6f 66 20  sponsibility of 
14960 74 68 65 20 63 61 6c 6c 65 72 20 74 6f 20 66 72  the caller to fr
14970 65 65 20 61 6c 6c 20 73 71 6c 69 74 65 5f 76 61  ee all sqlite_va
14980 6c 75 65 20 73 74 72 75 63 74 75 72 65 73 0a 2a  lue structures.*
14990 2a 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f  * using sqlite3_
149a0 66 72 65 65 28 29 2e 0a 2a 2a 0a 2a 2a 20 49 66  free()..**.** If
149b0 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
149c0 2c 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  , an SQLite erro
149d0 72 20 63 6f 64 65 20 28 65 2e 67 2e 20 53 51 4c  r code (e.g. SQL
149e0 49 54 45 5f 4e 4f 4d 45 4d 29 20 69 73 20 72 65  ITE_NOMEM) is re
149f0 74 75 72 6e 65 64 2e 0a 2a 2a 20 54 68 65 20 61  turned..** The a
14a00 70 4f 75 74 5b 5d 20 61 72 72 61 79 20 6d 61 79  pOut[] array may
14a10 20 68 61 76 65 20 62 65 65 6e 20 70 61 72 74 69   have been parti
14a20 61 6c 6c 79 20 70 6f 70 75 6c 61 74 65 64 20 69  ally populated i
14a30 6e 20 74 68 69 73 20 63 61 73 65 2e 0a 2a 2f 0a  n this case..*/.
14a40 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69  static int sessi
14a50 6f 6e 52 65 61 64 52 65 63 6f 72 64 28 0a 20 20  onReadRecord(.  
14a60 53 65 73 73 69 6f 6e 49 6e 70 75 74 20 2a 70 49  SessionInput *pI
14a70 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n,              
14a80 2f 2a 20 49 6e 70 75 74 20 64 61 74 61 20 2a 2f  /* Input data */
14a90 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c 20 20 20 20  .  int nCol,    
14aa0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14ab0 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
14ac0 76 61 6c 75 65 73 20 69 6e 20 72 65 63 6f 72 64  values in record
14ad0 20 2a 2f 0a 20 20 75 38 20 2a 61 62 50 4b 2c 20   */.  u8 *abPK, 
14ae0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14af0 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f        /* Array o
14b00 66 20 70 72 69 6d 61 72 79 20 6b 65 79 20 66 6c  f primary key fl
14b10 61 67 73 2c 20 6f 72 20 4e 55 4c 4c 20 2a 2f 0a  ags, or NULL */.
14b20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
14b30 2a 2a 61 70 4f 75 74 20 20 20 20 20 20 20 20 20  **apOut         
14b40 20 20 2f 2a 20 57 72 69 74 65 20 76 61 6c 75 65    /* Write value
14b50 73 20 74 6f 20 74 68 69 73 20 61 72 72 61 79 20  s to this array 
14b60 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 20 20  */.){.  int i;  
14b70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14b80 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20          /* Used 
14b90 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75  to iterate throu
14ba0 67 68 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20  gh columns */.  
14bb0 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
14bc0 4f 4b 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20  OK;..  for(i=0; 
14bd0 69 3c 6e 43 6f 6c 20 26 26 20 72 63 3d 3d 53 51  i<nCol && rc==SQ
14be0 4c 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20  LITE_OK; i++){. 
14bf0 20 20 20 69 6e 74 20 65 54 79 70 65 20 3d 20 30     int eType = 0
14c00 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
14c10 20 2f 2a 20 54 79 70 65 20 6f 66 20 76 61 6c 75   /* Type of valu
14c20 65 20 28 53 51 4c 49 54 45 5f 4e 55 4c 4c 2c 20  e (SQLITE_NULL, 
14c30 54 45 58 54 20 65 74 63 2e 29 20 2a 2f 0a 20 20  TEXT etc.) */.  
14c40 20 20 69 66 28 20 61 62 50 4b 20 26 26 20 61 62    if( abPK && ab
14c50 50 4b 5b 69 5d 3d 3d 30 20 29 20 63 6f 6e 74 69  PK[i]==0 ) conti
14c60 6e 75 65 3b 0a 20 20 20 20 72 63 20 3d 20 73 65  nue;.    rc = se
14c70 73 73 69 6f 6e 49 6e 70 75 74 42 75 66 66 65 72  ssionInputBuffer
14c80 28 70 49 6e 2c 20 39 29 3b 0a 20 20 20 20 69 66  (pIn, 9);.    if
14c90 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
14ca0 29 7b 0a 20 20 20 20 20 20 65 54 79 70 65 20 3d  ){.      eType =
14cb0 20 70 49 6e 2d 3e 61 44 61 74 61 5b 70 49 6e 2d   pIn->aData[pIn-
14cc0 3e 69 4e 65 78 74 2b 2b 5d 3b 0a 20 20 20 20 7d  >iNext++];.    }
14cd0 0a 0a 20 20 20 20 61 73 73 65 72 74 28 20 61 70  ..    assert( ap
14ce0 4f 75 74 5b 69 5d 3d 3d 30 20 29 3b 0a 20 20 20  Out[i]==0 );.   
14cf0 20 69 66 28 20 65 54 79 70 65 20 29 7b 0a 20 20   if( eType ){.  
14d00 20 20 20 20 61 70 4f 75 74 5b 69 5d 20 3d 20 73      apOut[i] = s
14d10 71 6c 69 74 65 33 56 61 6c 75 65 4e 65 77 28 30  qlite3ValueNew(0
14d20 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21 61 70  );.      if( !ap
14d30 4f 75 74 5b 69 5d 20 29 20 72 63 20 3d 20 53 51  Out[i] ) rc = SQ
14d40 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
14d50 7d 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  }..    if( rc==S
14d60 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
14d70 20 20 75 38 20 2a 61 56 61 6c 20 3d 20 26 70 49    u8 *aVal = &pI
14d80 6e 2d 3e 61 44 61 74 61 5b 70 49 6e 2d 3e 69 4e  n->aData[pIn->iN
14d90 65 78 74 5d 3b 0a 20 20 20 20 20 20 69 66 28 20  ext];.      if( 
14da0 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 54 45  eType==SQLITE_TE
14db0 58 54 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c  XT || eType==SQL
14dc0 49 54 45 5f 42 4c 4f 42 20 29 7b 0a 20 20 20 20  ITE_BLOB ){.    
14dd0 20 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20      int nByte;. 
14de0 20 20 20 20 20 20 20 70 49 6e 2d 3e 69 4e 65 78         pIn->iNex
14df0 74 20 2b 3d 20 73 65 73 73 69 6f 6e 56 61 72 69  t += sessionVari
14e00 6e 74 47 65 74 28 61 56 61 6c 2c 20 26 6e 42 79  ntGet(aVal, &nBy
14e10 74 65 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20  te);.        rc 
14e20 3d 20 73 65 73 73 69 6f 6e 49 6e 70 75 74 42 75  = sessionInputBu
14e30 66 66 65 72 28 70 49 6e 2c 20 6e 42 79 74 65 29  ffer(pIn, nByte)
14e40 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
14e50 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
14e60 20 20 20 20 20 20 20 20 20 75 38 20 65 6e 63 20           u8 enc 
14e70 3d 20 28 65 54 79 70 65 3d 3d 53 51 4c 49 54 45  = (eType==SQLITE
14e80 5f 54 45 58 54 20 3f 20 53 51 4c 49 54 45 5f 55  _TEXT ? SQLITE_U
14e90 54 46 38 20 3a 20 30 29 3b 0a 20 20 20 20 20 20  TF8 : 0);.      
14ea0 20 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e      rc = session
14eb0 56 61 6c 75 65 53 65 74 53 74 72 28 61 70 4f 75  ValueSetStr(apOu
14ec0 74 5b 69 5d 2c 26 70 49 6e 2d 3e 61 44 61 74 61  t[i],&pIn->aData
14ed0 5b 70 49 6e 2d 3e 69 4e 65 78 74 5d 2c 6e 42 79  [pIn->iNext],nBy
14ee0 74 65 2c 65 6e 63 29 3b 0a 20 20 20 20 20 20 20  te,enc);.       
14ef0 20 7d 0a 20 20 20 20 20 20 20 20 70 49 6e 2d 3e   }.        pIn->
14f00 69 4e 65 78 74 20 2b 3d 20 6e 42 79 74 65 3b 0a  iNext += nByte;.
14f10 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
14f20 28 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f  ( eType==SQLITE_
14f30 49 4e 54 45 47 45 52 20 7c 7c 20 65 54 79 70 65  INTEGER || eType
14f40 3d 3d 53 51 4c 49 54 45 5f 46 4c 4f 41 54 20 29  ==SQLITE_FLOAT )
14f50 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65  {.        sqlite
14f60 33 5f 69 6e 74 36 34 20 76 20 3d 20 73 65 73 73  3_int64 v = sess
14f70 69 6f 6e 47 65 74 49 36 34 28 61 56 61 6c 29 3b  ionGetI64(aVal);
14f80 0a 20 20 20 20 20 20 20 20 69 66 28 20 65 54 79  .        if( eTy
14f90 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47  pe==SQLITE_INTEG
14fa0 45 52 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  ER ){.          
14fb0 73 71 6c 69 74 65 33 56 64 62 65 4d 65 6d 53 65  sqlite3VdbeMemSe
14fc0 74 49 6e 74 36 34 28 61 70 4f 75 74 5b 69 5d 2c  tInt64(apOut[i],
14fd0 20 76 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c   v);.        }el
14fe0 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 64 6f  se{.          do
14ff0 75 62 6c 65 20 64 3b 0a 20 20 20 20 20 20 20 20  uble d;.        
15000 20 20 6d 65 6d 63 70 79 28 26 64 2c 20 26 76 2c    memcpy(&d, &v,
15010 20 38 29 3b 0a 20 20 20 20 20 20 20 20 20 20 73   8);.          s
15020 71 6c 69 74 65 33 56 64 62 65 4d 65 6d 53 65 74  qlite3VdbeMemSet
15030 44 6f 75 62 6c 65 28 61 70 4f 75 74 5b 69 5d 2c  Double(apOut[i],
15040 20 64 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20   d);.        }. 
15050 20 20 20 20 20 20 20 70 49 6e 2d 3e 69 4e 65 78         pIn->iNex
15060 74 20 2b 3d 20 38 3b 0a 20 20 20 20 20 20 7d 0a  t += 8;.      }.
15070 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
15080 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
15090 20 54 68 65 20 69 6e 70 75 74 20 70 6f 69 6e 74   The input point
150a0 65 72 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69  er currently poi
150b0 6e 74 73 20 74 6f 20 74 68 65 20 73 65 63 6f 6e  nts to the secon
150c0 64 20 62 79 74 65 20 6f 66 20 61 20 74 61 62 6c  d byte of a tabl
150d0 65 2d 68 65 61 64 65 72 2e 0a 2a 2a 20 53 70 65  e-header..** Spe
150e0 63 69 66 69 63 61 6c 6c 79 2c 20 74 6f 20 74 68  cifically, to th
150f0 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a 0a 2a 2a 0a  e following:.**.
15100 2a 2a 20 20 20 2b 20 6e 75 6d 62 65 72 20 6f 66  **   + number of
15110 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 61 62 6c   columns in tabl
15120 65 20 28 76 61 72 69 6e 74 29 0a 2a 2a 20 20 20  e (varint).**   
15130 2b 20 61 72 72 61 79 20 6f 66 20 50 4b 20 66 6c  + array of PK fl
15140 61 67 73 20 28 31 20 62 79 74 65 20 70 65 72 20  ags (1 byte per 
15150 63 6f 6c 75 6d 6e 29 2c 0a 2a 2a 20 20 20 2b 20  column),.**   + 
15160 74 61 62 6c 65 20 6e 61 6d 65 20 28 6e 75 6c 20  table name (nul 
15170 74 65 72 6d 69 6e 61 74 65 64 29 2e 0a 2a 2a 0a  terminated)..**.
15180 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
15190 20 65 6e 73 75 72 65 73 20 74 68 61 74 20 61 6c   ensures that al
151a0 6c 20 6f 66 20 74 68 65 20 61 62 6f 76 65 20 69  l of the above i
151b0 73 20 70 72 65 73 65 6e 74 20 69 6e 20 74 68 65  s present in the
151c0 20 69 6e 70 75 74 20 0a 2a 2a 20 62 75 66 66 65   input .** buffe
151d0 72 20 28 69 2e 65 2e 20 74 68 61 74 20 69 74 20  r (i.e. that it 
151e0 63 61 6e 20 62 65 20 61 63 63 65 73 73 65 64 20  can be accessed 
151f0 77 69 74 68 6f 75 74 20 61 6e 79 20 63 61 6c 6c  without any call
15200 73 20 74 6f 20 78 49 6e 70 75 74 28 29 29 2e 0a  s to xInput())..
15210 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c  ** If successful
15220 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72  , SQLITE_OK is r
15230 65 74 75 72 6e 65 64 2e 20 4f 74 68 65 72 77 69  eturned. Otherwi
15240 73 65 2c 20 61 6e 20 53 51 4c 69 74 65 20 65 72  se, an SQLite er
15250 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 20 54 68 65  ror code..** The
15260 20 69 6e 70 75 74 20 70 6f 69 6e 74 65 72 20 69   input pointer i
15270 73 20 6e 6f 74 20 6d 6f 76 65 64 2e 0a 2a 2f 0a  s not moved..*/.
15280 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69  static int sessi
15290 6f 6e 43 68 61 6e 67 65 73 65 74 42 75 66 66 65  onChangesetBuffe
152a0 72 54 62 6c 68 64 72 28 53 65 73 73 69 6f 6e 49  rTblhdr(SessionI
152b0 6e 70 75 74 20 2a 70 49 6e 2c 20 69 6e 74 20 2a  nput *pIn, int *
152c0 70 6e 42 79 74 65 29 7b 0a 20 20 69 6e 74 20 72  pnByte){.  int r
152d0 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
152e0 20 69 6e 74 20 6e 43 6f 6c 20 3d 20 30 3b 0a 20   int nCol = 0;. 
152f0 20 69 6e 74 20 6e 52 65 61 64 20 3d 20 30 3b 0a   int nRead = 0;.
15300 0a 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 49  .  rc = sessionI
15310 6e 70 75 74 42 75 66 66 65 72 28 70 49 6e 2c 20  nputBuffer(pIn, 
15320 39 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  9);.  if( rc==SQ
15330 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 6e  LITE_OK ){.    n
15340 52 65 61 64 20 2b 3d 20 73 65 73 73 69 6f 6e 56  Read += sessionV
15350 61 72 69 6e 74 47 65 74 28 26 70 49 6e 2d 3e 61  arintGet(&pIn->a
15360 44 61 74 61 5b 70 49 6e 2d 3e 69 4e 65 78 74 20  Data[pIn->iNext 
15370 2b 20 6e 52 65 61 64 5d 2c 20 26 6e 43 6f 6c 29  + nRead], &nCol)
15380 3b 0a 20 20 20 20 72 63 20 3d 20 73 65 73 73 69  ;.    rc = sessi
15390 6f 6e 49 6e 70 75 74 42 75 66 66 65 72 28 70 49  onInputBuffer(pI
153a0 6e 2c 20 6e 52 65 61 64 2b 6e 43 6f 6c 2b 31 30  n, nRead+nCol+10
153b0 30 29 3b 0a 20 20 20 20 6e 52 65 61 64 20 2b 3d  0);.    nRead +=
153c0 20 6e 43 6f 6c 3b 0a 20 20 7d 0a 0a 20 20 77 68   nCol;.  }..  wh
153d0 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ile( rc==SQLITE_
153e0 4f 4b 20 29 7b 0a 20 20 20 20 77 68 69 6c 65 28  OK ){.    while(
153f0 20 28 70 49 6e 2d 3e 69 4e 65 78 74 20 2b 20 6e   (pIn->iNext + n
15400 52 65 61 64 29 3c 70 49 6e 2d 3e 6e 44 61 74 61  Read)<pIn->nData
15410 20 26 26 20 70 49 6e 2d 3e 61 44 61 74 61 5b 70   && pIn->aData[p
15420 49 6e 2d 3e 69 4e 65 78 74 20 2b 20 6e 52 65 61  In->iNext + nRea
15430 64 5d 20 29 7b 0a 20 20 20 20 20 20 6e 52 65 61  d] ){.      nRea
15440 64 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  d++;.    }.    i
15450 66 28 20 28 70 49 6e 2d 3e 69 4e 65 78 74 20 2b  f( (pIn->iNext +
15460 20 6e 52 65 61 64 29 3c 70 49 6e 2d 3e 6e 44 61   nRead)<pIn->nDa
15470 74 61 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  ta ) break;.    
15480 72 63 20 3d 20 73 65 73 73 69 6f 6e 49 6e 70 75  rc = sessionInpu
15490 74 42 75 66 66 65 72 28 70 49 6e 2c 20 6e 52 65  tBuffer(pIn, nRe
154a0 61 64 20 2b 20 31 30 30 29 3b 0a 20 20 7d 0a 20  ad + 100);.  }. 
154b0 20 2a 70 6e 42 79 74 65 20 3d 20 6e 52 65 61 64   *pnByte = nRead
154c0 2b 31 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  +1;.  return rc;
154d0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 69 6e  .}../*.** The in
154e0 70 75 74 20 70 6f 69 6e 74 65 72 20 63 75 72 72  put pointer curr
154f0 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f 20  ently points to 
15500 74 68 65 20 66 69 72 73 74 20 62 79 74 65 20 6f  the first byte o
15510 66 20 74 68 65 20 66 69 72 73 74 20 66 69 65 6c  f the first fiel
15520 64 0a 2a 2a 20 6f 66 20 61 20 72 65 63 6f 72 64  d.** of a record
15530 20 63 6f 6e 73 69 73 74 69 6e 67 20 6f 66 20 6e   consisting of n
15540 43 6f 6c 20 63 6f 6c 75 6d 6e 73 2e 20 54 68 69  Col columns. Thi
15550 73 20 66 75 6e 63 74 69 6f 6e 20 65 6e 73 75 72  s function ensur
15560 65 73 20 74 68 65 20 65 6e 74 69 72 65 0a 2a 2a  es the entire.**
15570 20 72 65 63 6f 72 64 20 69 73 20 62 75 66 66 65   record is buffe
15580 72 65 64 2e 20 49 74 20 64 6f 65 73 20 6e 6f 74  red. It does not
15590 20 6d 6f 76 65 20 74 68 65 20 69 6e 70 75 74 20   move the input 
155a0 70 6f 69 6e 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 49  pointer..**.** I
155b0 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 53 51  f successful, SQ
155c0 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72  LITE_OK is retur
155d0 6e 65 64 20 61 6e 64 20 2a 70 6e 42 79 74 65 20  ned and *pnByte 
155e0 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 73 69  is set to the si
155f0 7a 65 20 6f 66 0a 2a 2a 20 74 68 65 20 72 65 63  ze of.** the rec
15600 6f 72 64 20 69 6e 20 62 79 74 65 73 2e 20 4f 74  ord in bytes. Ot
15610 68 65 72 77 69 73 65 2c 20 61 6e 20 53 51 4c 69  herwise, an SQLi
15620 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69 73  te error code is
15630 20 72 65 74 75 72 6e 65 64 2e 20 54 68 65 0a 2a   returned. The.*
15640 2a 20 66 69 6e 61 6c 20 76 61 6c 75 65 20 6f 66  * final value of
15650 20 2a 70 6e 42 79 74 65 20 69 73 20 75 6e 64 65   *pnByte is unde
15660 66 69 6e 65 64 20 69 6e 20 74 68 69 73 20 63 61  fined in this ca
15670 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  se..*/.static in
15680 74 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73  t sessionChanges
15690 65 74 42 75 66 66 65 72 52 65 63 6f 72 64 28 0a  etBufferRecord(.
156a0 20 20 53 65 73 73 69 6f 6e 49 6e 70 75 74 20 2a    SessionInput *
156b0 70 49 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  pIn,            
156c0 20 20 2f 2a 20 49 6e 70 75 74 20 64 61 74 61 20    /* Input data 
156d0 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c 20 20  */.  int nCol,  
156e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
156f0 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
15700 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 72 65 63  f columns in rec
15710 6f 72 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e  ord */.  int *pn
15720 42 79 74 65 20 20 20 20 20 20 20 20 20 20 20 20  Byte            
15730 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
15740 20 53 69 7a 65 20 6f 66 20 72 65 63 6f 72 64 20   Size of record 
15750 69 6e 20 62 79 74 65 73 20 2a 2f 0a 29 7b 0a 20  in bytes */.){. 
15760 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
15770 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 42 79 74 65  _OK;.  int nByte
15780 20 3d 20 30 3b 0a 20 20 69 6e 74 20 69 3b 0a 20   = 0;.  int i;. 
15790 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51   for(i=0; rc==SQ
157a0 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e 43 6f  LITE_OK && i<nCo
157b0 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74  l; i++){.    int
157c0 20 65 54 79 70 65 3b 0a 20 20 20 20 72 63 20 3d   eType;.    rc =
157d0 20 73 65 73 73 69 6f 6e 49 6e 70 75 74 42 75 66   sessionInputBuf
157e0 66 65 72 28 70 49 6e 2c 20 6e 42 79 74 65 20 2b  fer(pIn, nByte +
157f0 20 31 30 29 3b 0a 20 20 20 20 69 66 28 20 72 63   10);.    if( rc
15800 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
15810 20 20 20 20 20 65 54 79 70 65 20 3d 20 70 49 6e       eType = pIn
15820 2d 3e 61 44 61 74 61 5b 70 49 6e 2d 3e 69 4e 65  ->aData[pIn->iNe
15830 78 74 20 2b 20 6e 42 79 74 65 2b 2b 5d 3b 0a 20  xt + nByte++];. 
15840 20 20 20 20 20 69 66 28 20 65 54 79 70 65 3d 3d       if( eType==
15850 53 51 4c 49 54 45 5f 54 45 58 54 20 7c 7c 20 65  SQLITE_TEXT || e
15860 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f  Type==SQLITE_BLO
15870 42 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74  B ){.        int
15880 20 6e 3b 0a 20 20 20 20 20 20 20 20 6e 42 79 74   n;.        nByt
15890 65 20 2b 3d 20 73 65 73 73 69 6f 6e 56 61 72 69  e += sessionVari
158a0 6e 74 47 65 74 28 26 70 49 6e 2d 3e 61 44 61 74  ntGet(&pIn->aDat
158b0 61 5b 70 49 6e 2d 3e 69 4e 65 78 74 2b 6e 42 79  a[pIn->iNext+nBy
158c0 74 65 5d 2c 20 26 6e 29 3b 0a 20 20 20 20 20 20  te], &n);.      
158d0 20 20 6e 42 79 74 65 20 2b 3d 20 6e 3b 0a 20 20    nByte += n;.  
158e0 20 20 20 20 20 20 72 63 20 3d 20 73 65 73 73 69        rc = sessi
158f0 6f 6e 49 6e 70 75 74 42 75 66 66 65 72 28 70 49  onInputBuffer(pI
15900 6e 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 20  n, nByte);.     
15910 20 7d 65 6c 73 65 20 69 66 28 20 65 54 79 70 65   }else if( eType
15920 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52  ==SQLITE_INTEGER
15930 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49 54   || eType==SQLIT
15940 45 5f 46 4c 4f 41 54 20 29 7b 0a 20 20 20 20 20  E_FLOAT ){.     
15950 20 20 20 6e 42 79 74 65 20 2b 3d 20 38 3b 0a 20     nByte += 8;. 
15960 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
15970 0a 20 20 2a 70 6e 42 79 74 65 20 3d 20 6e 42 79  .  *pnByte = nBy
15980 74 65 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  te;.  return rc;
15990 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 69 6e  .}../*.** The in
159a0 70 75 74 20 70 6f 69 6e 74 65 72 20 63 75 72 72  put pointer curr
159b0 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f 20  ently points to 
159c0 74 68 65 20 73 65 63 6f 6e 64 20 62 79 74 65 20  the second byte 
159d0 6f 66 20 61 20 74 61 62 6c 65 2d 68 65 61 64 65  of a table-heade
159e0 72 2e 0a 2a 2a 20 53 70 65 63 69 66 69 63 61 6c  r..** Specifical
159f0 6c 79 2c 20 74 6f 20 74 68 65 20 66 6f 6c 6c 6f  ly, to the follo
15a00 77 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 2b 20  wing:.**.**   + 
15a10 6e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e  number of column
15a20 73 20 69 6e 20 74 61 62 6c 65 20 28 76 61 72 69  s in table (vari
15a30 6e 74 29 0a 2a 2a 20 20 20 2b 20 61 72 72 61 79  nt).**   + array
15a40 20 6f 66 20 50 4b 20 66 6c 61 67 73 20 28 31 20   of PK flags (1 
15a50 62 79 74 65 20 70 65 72 20 63 6f 6c 75 6d 6e 29  byte per column)
15a60 2c 0a 2a 2a 20 20 20 2b 20 74 61 62 6c 65 20 6e  ,.**   + table n
15a70 61 6d 65 20 28 6e 75 6c 20 74 65 72 6d 69 6e 61  ame (nul termina
15a80 74 65 64 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  ted)..**.** This
15a90 20 66 75 6e 63 74 69 6f 6e 20 64 65 63 6f 64 65   function decode
15aa0 73 20 74 68 65 20 74 61 62 6c 65 2d 68 65 61 64  s the table-head
15ab0 65 72 20 61 6e 64 20 70 6f 70 75 6c 61 74 65 73  er and populates
15ac0 20 74 68 65 20 70 2d 3e 6e 43 6f 6c 2c 20 0a 2a   the p->nCol, .*
15ad0 2a 20 70 2d 3e 7a 54 61 62 20 61 6e 64 20 70 2d  * p->zTab and p-
15ae0 3e 61 62 50 4b 5b 5d 20 76 61 72 69 61 62 6c 65  >abPK[] variable
15af0 73 20 61 63 63 6f 72 64 69 6e 67 6c 79 2e 20 54  s accordingly. T
15b00 68 65 20 70 2d 3e 61 70 56 61 6c 75 65 5b 5d 20  he p->apValue[] 
15b10 61 72 72 61 79 20 69 73 20 0a 2a 2a 20 61 6c 73  array is .** als
15b20 6f 20 61 6c 6c 6f 63 61 74 65 64 20 6f 72 20 72  o allocated or r
15b30 65 73 69 7a 65 64 20 61 63 63 6f 72 64 69 6e 67  esized according
15b40 20 74 6f 20 74 68 65 20 6e 65 77 20 76 61 6c 75   to the new valu
15b50 65 20 6f 66 20 70 2d 3e 6e 43 6f 6c 2e 20 54 68  e of p->nCol. Th
15b60 65 0a 2a 2a 20 69 6e 70 75 74 20 70 6f 69 6e 74  e.** input point
15b70 65 72 20 69 73 20 6c 65 66 74 20 70 6f 69 6e 74  er is left point
15b80 69 6e 67 20 74 6f 20 74 68 65 20 62 79 74 65 20  ing to the byte 
15b90 66 6f 6c 6c 6f 77 69 6e 67 20 74 68 65 20 74 61  following the ta
15ba0 62 6c 65 20 68 65 61 64 65 72 2e 0a 2a 2a 0a 2a  ble header..**.*
15bb0 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c  * If successful,
15bc0 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65   SQLITE_OK is re
15bd0 74 75 72 6e 65 64 2e 20 4f 74 68 65 72 77 69 73  turned. Otherwis
15be0 65 2c 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  e, an SQLite err
15bf0 6f 72 20 63 6f 64 65 0a 2a 2a 20 69 73 20 72 65  or code.** is re
15c00 74 75 72 6e 65 64 20 61 6e 64 20 74 68 65 20 66  turned and the f
15c10 69 6e 61 6c 20 76 61 6c 75 65 73 20 6f 66 20 74  inal values of t
15c20 68 65 20 76 61 72 69 6f 75 73 20 66 69 65 6c 64  he various field
15c30 73 20 65 6e 75 6d 65 72 61 74 65 64 20 61 62 6f  s enumerated abo
15c40 76 65 0a 2a 2a 20 61 72 65 20 75 6e 64 65 66 69  ve.** are undefi
15c50 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ned..*/.static i
15c60 6e 74 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65  nt sessionChange
15c70 73 65 74 52 65 61 64 54 62 6c 68 64 72 28 73 71  setReadTblhdr(sq
15c80 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f  lite3_changeset_
15c90 69 74 65 72 20 2a 70 29 7b 0a 20 20 69 6e 74 20  iter *p){.  int 
15ca0 72 63 3b 0a 20 20 69 6e 74 20 6e 43 6f 70 79 3b  rc;.  int nCopy;
15cb0 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 72 63  .  assert( p->rc
15cc0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 0a  ==SQLITE_OK );..
15cd0 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 43 68    rc = sessionCh
15ce0 61 6e 67 65 73 65 74 42 75 66 66 65 72 54 62 6c  angesetBufferTbl
15cf0 68 64 72 28 26 70 2d 3e 69 6e 2c 20 26 6e 43 6f  hdr(&p->in, &nCo
15d00 70 79 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  py);.  if( rc==S
15d10 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
15d20 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20 20 69  int nByte;.    i
15d30 6e 74 20 6e 56 61 72 69 6e 74 3b 0a 20 20 20 20  nt nVarint;.    
15d40 6e 56 61 72 69 6e 74 20 3d 20 73 65 73 73 69 6f  nVarint = sessio
15d50 6e 56 61 72 69 6e 74 47 65 74 28 26 70 2d 3e 69  nVarintGet(&p->i
15d60 6e 2e 61 44 61 74 61 5b 70 2d 3e 69 6e 2e 69 4e  n.aData[p->in.iN
15d70 65 78 74 5d 2c 20 26 70 2d 3e 6e 43 6f 6c 29 3b  ext], &p->nCol);
15d80 0a 20 20 20 20 6e 43 6f 70 79 20 2d 3d 20 6e 56  .    nCopy -= nV
15d90 61 72 69 6e 74 3b 0a 20 20 20 20 70 2d 3e 69 6e  arint;.    p->in
15da0 2e 69 4e 65 78 74 20 2b 3d 20 6e 56 61 72 69 6e  .iNext += nVarin
15db0 74 3b 0a 20 20 20 20 6e 42 79 74 65 20 3d 20 70  t;.    nByte = p
15dc0 2d 3e 6e 43 6f 6c 20 2a 20 73 69 7a 65 6f 66 28  ->nCol * sizeof(
15dd0 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 2a 29 20  sqlite3_value*) 
15de0 2a 20 32 20 2b 20 6e 43 6f 70 79 3b 0a 20 20 20  * 2 + nCopy;.   
15df0 20 70 2d 3e 74 62 6c 68 64 72 2e 6e 42 75 66 20   p->tblhdr.nBuf 
15e00 3d 20 30 3b 0a 20 20 20 20 73 65 73 73 69 6f 6e  = 0;.    session
15e10 42 75 66 66 65 72 47 72 6f 77 28 26 70 2d 3e 74  BufferGrow(&p->t
15e20 62 6c 68 64 72 2c 20 6e 42 79 74 65 2c 20 26 72  blhdr, nByte, &r
15e30 63 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72  c);.  }..  if( r
15e40 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
15e50 20 20 20 20 69 6e 74 20 69 50 4b 20 3d 20 73 69      int iPK = si
15e60 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f 76 61 6c  zeof(sqlite3_val
15e70 75 65 2a 29 2a 70 2d 3e 6e 43 6f 6c 2a 32 3b 0a  ue*)*p->nCol*2;.
15e80 20 20 20 20 6d 65 6d 73 65 74 28 70 2d 3e 74 62      memset(p->tb
15e90 6c 68 64 72 2e 61 42 75 66 2c 20 30 2c 20 69 50  lhdr.aBuf, 0, iP
15ea0 4b 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 26  K);.    memcpy(&
15eb0 70 2d 3e 74 62 6c 68 64 72 2e 61 42 75 66 5b 69  p->tblhdr.aBuf[i
15ec0 50 4b 5d 2c 20 26 70 2d 3e 69 6e 2e 61 44 61 74  PK], &p->in.aDat
15ed0 61 5b 70 2d 3e 69 6e 2e 69 4e 65 78 74 5d 2c 20  a[p->in.iNext], 
15ee0 6e 43 6f 70 79 29 3b 0a 20 20 20 20 70 2d 3e 69  nCopy);.    p->i
15ef0 6e 2e 69 4e 65 78 74 20 2b 3d 20 6e 43 6f 70 79  n.iNext += nCopy
15f00 3b 0a 20 20 7d 0a 0a 20 20 70 2d 3e 61 70 56 61  ;.  }..  p->apVa
15f10 6c 75 65 20 3d 20 28 73 71 6c 69 74 65 33 5f 76  lue = (sqlite3_v
15f20 61 6c 75 65 2a 2a 29 70 2d 3e 74 62 6c 68 64 72  alue**)p->tblhdr
15f30 2e 61 42 75 66 3b 0a 20 20 70 2d 3e 61 62 50 4b  .aBuf;.  p->abPK
15f40 20 3d 20 28 75 38 2a 29 26 70 2d 3e 61 70 56 61   = (u8*)&p->apVa
15f50 6c 75 65 5b 70 2d 3e 6e 43 6f 6c 2a 32 5d 3b 0a  lue[p->nCol*2];.
15f60 20 20 70 2d 3e 7a 54 61 62 20 3d 20 28 63 68 61    p->zTab = (cha
15f70 72 2a 29 26 70 2d 3e 61 62 50 4b 5b 70 2d 3e 6e  r*)&p->abPK[p->n
15f80 43 6f 6c 5d 3b 0a 20 20 72 65 74 75 72 6e 20 28  Col];.  return (
15f90 70 2d 3e 72 63 20 3d 20 72 63 29 3b 0a 7d 0a 0a  p->rc = rc);.}..
15fa0 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 74 68  /*.** Advance th
15fb0 65 20 63 68 61 6e 67 65 73 65 74 20 69 74 65 72  e changeset iter
15fc0 61 74 6f 72 20 74 6f 20 74 68 65 20 6e 65 78 74  ator to the next
15fd0 20 63 68 61 6e 67 65 2e 0a 2a 2a 0a 2a 2a 20 49   change..**.** I
15fe0 66 20 62 6f 74 68 20 70 61 52 65 63 20 61 6e 64  f both paRec and
15ff0 20 70 6e 52 65 63 20 61 72 65 20 4e 55 4c 4c 2c   pnRec are NULL,
16000 20 74 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74   then this funct
16010 69 6f 6e 20 77 6f 72 6b 73 20 6c 69 6b 65 20 74  ion works like t
16020 68 65 20 70 75 62 6c 69 63 0a 2a 2a 20 41 50 49  he public.** API
16030 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
16040 74 5f 6e 65 78 74 28 29 2e 20 49 66 20 53 51 4c  t_next(). If SQL
16050 49 54 45 5f 52 4f 57 20 69 73 20 72 65 74 75 72  ITE_ROW is retur
16060 6e 65 64 2c 20 74 68 65 6e 20 74 68 65 0a 2a 2a  ned, then the.**
16070 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
16080 74 5f 6e 65 77 28 29 20 61 6e 64 20 6f 6c 64 28  t_new() and old(
16090 29 20 41 50 49 73 20 6d 61 79 20 62 65 20 75 73  ) APIs may be us
160a0 65 64 20 74 6f 20 71 75 65 72 79 20 66 6f 72 20  ed to query for 
160b0 76 61 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 4f 74  values..**.** Ot
160c0 68 65 72 77 69 73 65 2c 20 69 66 20 70 61 52 65  herwise, if paRe
160d0 63 20 61 6e 64 20 70 6e 52 65 63 20 61 72 65 20  c and pnRec are 
160e0 6e 6f 74 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 61  not NULL, then a
160f0 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20   pointer to the 
16100 63 68 61 6e 67 65 0a 2a 2a 20 72 65 63 6f 72 64  change.** record
16110 20 69 73 20 77 72 69 74 74 65 6e 20 74 6f 20 2a   is written to *
16120 70 61 52 65 63 20 62 65 66 6f 72 65 20 72 65 74  paRec before ret
16130 75 72 6e 69 6e 67 20 61 6e 64 20 74 68 65 20 6e  urning and the n
16140 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69  umber of bytes i
16150 6e 0a 2a 2a 20 74 68 65 20 72 65 63 6f 72 64 20  n.** the record 
16160 74 6f 20 2a 70 6e 52 65 63 2e 0a 2a 2a 0a 2a 2a  to *pnRec..**.**
16170 20 45 69 74 68 65 72 20 77 61 79 2c 20 74 68 69   Either way, thi
16180 73 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72  s function retur
16190 6e 73 20 53 51 4c 49 54 45 5f 52 4f 57 20 69 66  ns SQLITE_ROW if
161a0 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 69 73   the iterator is
161b0 20 0a 2a 2a 20 73 75 63 63 65 73 73 66 75 6c 6c   .** successfull
161c0 79 20 61 64 76 61 6e 63 65 64 20 74 6f 20 74 68  y advanced to th
161d0 65 20 6e 65 78 74 20 63 68 61 6e 67 65 20 69 6e  e next change in
161e0 20 74 68 65 20 63 68 61 6e 67 65 73 65 74 2c 20   the changeset, 
161f0 61 6e 20 53 51 4c 69 74 65 20 0a 2a 2a 20 65 72  an SQLite .** er
16200 72 6f 72 20 63 6f 64 65 20 69 66 20 61 6e 20 65  ror code if an e
16210 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 6f 72 20  rror occurs, or 
16220 53 51 4c 49 54 45 5f 44 4f 4e 45 20 69 66 20 74  SQLITE_DONE if t
16230 68 65 72 65 20 61 72 65 20 6e 6f 20 66 75 72 74  here are no furt
16240 68 65 72 20 0a 2a 2a 20 63 68 61 6e 67 65 73 20  her .** changes 
16250 69 6e 20 74 68 65 20 63 68 61 6e 67 65 73 65 74  in the changeset
16260 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
16270 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65 74  sessionChangeset
16280 4e 65 78 74 28 0a 20 20 73 71 6c 69 74 65 33 5f  Next(.  sqlite3_
16290 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a  changeset_iter *
162a0 70 2c 20 20 20 20 20 20 2f 2a 20 43 68 61 6e 67  p,      /* Chang
162b0 65 73 65 74 20 69 74 65 72 61 74 6f 72 20 2a 2f  eset iterator */
162c0 0a 20 20 75 38 20 2a 2a 70 61 52 65 63 2c 20 20  .  u8 **paRec,  
162d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
162e0 20 20 20 2f 2a 20 49 66 20 6e 6f 6e 2d 4e 55 4c     /* If non-NUL
162f0 4c 2c 20 73 74 6f 72 65 20 72 65 63 6f 72 64 20  L, store record 
16300 70 6f 69 6e 74 65 72 20 68 65 72 65 20 2a 2f 0a  pointer here */.
16310 20 20 69 6e 74 20 2a 70 6e 52 65 63 20 20 20 20    int *pnRec    
16320 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16330 20 20 2f 2a 20 49 66 20 6e 6f 6e 2d 4e 55 4c 4c    /* If non-NULL
16340 2c 20 73 74 6f 72 65 20 73 69 7a 65 20 6f 66 20  , store size of 
16350 72 65 63 6f 72 64 20 68 65 72 65 20 2a 2f 0a 29  record here */.)
16360 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 75 38 20  {.  int i;.  u8 
16370 6f 70 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 28  op;..  assert( (
16380 70 61 52 65 63 3d 3d 30 20 26 26 20 70 6e 52 65  paRec==0 && pnRe
16390 63 3d 3d 30 29 20 7c 7c 20 28 70 61 52 65 63 20  c==0) || (paRec 
163a0 26 26 20 70 6e 52 65 63 29 20 29 3b 0a 0a 20 20  && pnRec) );..  
163b0 2f 2a 20 49 66 20 74 68 65 20 69 74 65 72 61 74  /* If the iterat
163c0 6f 72 20 69 73 20 69 6e 20 74 68 65 20 65 72 72  or is in the err
163d0 6f 72 2d 73 74 61 74 65 2c 20 72 65 74 75 72 6e  or-state, return
163e0 20 69 6d 6d 65 64 69 61 74 65 6c 79 2e 20 2a 2f   immediately. */
163f0 0a 20 20 69 66 28 20 70 2d 3e 72 63 21 3d 53 51  .  if( p->rc!=SQ
16400 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
16410 20 70 2d 3e 72 63 3b 0a 0a 20 20 2f 2a 20 46 72   p->rc;..  /* Fr
16420 65 65 20 74 68 65 20 63 75 72 72 65 6e 74 20 63  ee the current c
16430 6f 6e 74 65 6e 74 73 20 6f 66 20 70 2d 3e 61 70  ontents of p->ap
16440 56 61 6c 75 65 5b 5d 2c 20 69 66 20 61 6e 79 2e  Value[], if any.
16450 20 2a 2f 0a 20 20 69 66 28 20 70 2d 3e 61 70 56   */.  if( p->apV
16460 61 6c 75 65 20 29 7b 0a 20 20 20 20 66 6f 72 28  alue ){.    for(
16470 69 3d 30 3b 20 69 3c 70 2d 3e 6e 43 6f 6c 2a 32  i=0; i<p->nCol*2
16480 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73 71  ; i++){.      sq
16490 6c 69 74 65 33 56 61 6c 75 65 46 72 65 65 28 70  lite3ValueFree(p
164a0 2d 3e 61 70 56 61 6c 75 65 5b 69 5d 29 3b 0a 20  ->apValue[i]);. 
164b0 20 20 20 7d 0a 20 20 20 20 6d 65 6d 73 65 74 28     }.    memset(
164c0 70 2d 3e 61 70 56 61 6c 75 65 2c 20 30 2c 20 73  p->apValue, 0, s
164d0 69 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f 76 61  izeof(sqlite3_va
164e0 6c 75 65 2a 29 2a 70 2d 3e 6e 43 6f 6c 2a 32 29  lue*)*p->nCol*2)
164f0 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4d 61 6b 65  ;.  }..  /* Make
16500 20 73 75 72 65 20 74 68 65 20 62 75 66 66 65 72   sure the buffer
16510 20 63 6f 6e 74 61 69 6e 73 20 61 74 20 6c 65 61   contains at lea
16520 73 74 20 31 30 20 62 79 74 65 73 20 6f 66 20 69  st 10 bytes of i
16530 6e 70 75 74 20 64 61 74 61 2c 20 6f 72 20 61 6c  nput data, or al
16540 6c 0a 20 20 2a 2a 20 72 65 6d 61 69 6e 69 6e 67  l.  ** remaining
16550 20 64 61 74 61 20 69 66 20 74 68 65 72 65 20 61   data if there a
16560 72 65 20 6c 65 73 73 20 74 68 61 6e 20 31 30 20  re less than 10 
16570 62 79 74 65 73 20 61 76 61 69 6c 61 62 6c 65 2e  bytes available.
16580 20 54 68 69 73 20 69 73 0a 20 20 2a 2a 20 73 75   This is.  ** su
16590 66 66 69 63 69 65 6e 74 20 65 69 74 68 65 72 20  fficient either 
165a0 66 6f 72 20 74 68 65 20 27 54 27 20 6f 72 20 27  for the 'T' or '
165b0 50 27 20 62 79 74 65 20 61 6e 64 20 74 68 65 20  P' byte and the 
165c0 76 61 72 69 6e 74 20 74 68 61 74 20 66 6f 6c 6c  varint that foll
165d0 6f 77 73 0a 20 20 2a 2a 20 69 74 2c 20 6f 72 20  ows.  ** it, or 
165e0 66 6f 72 20 74 68 65 20 74 77 6f 20 73 69 6e 67  for the two sing
165f0 6c 65 20 62 79 74 65 20 76 61 6c 75 65 73 20 6f  le byte values o
16600 74 68 65 72 77 69 73 65 2e 20 2a 2f 0a 20 20 70  therwise. */.  p
16610 2d 3e 72 63 20 3d 20 73 65 73 73 69 6f 6e 49 6e  ->rc = sessionIn
16620 70 75 74 42 75 66 66 65 72 28 26 70 2d 3e 69 6e  putBuffer(&p->in
16630 2c 20 32 29 3b 0a 20 20 69 66 28 20 70 2d 3e 72  , 2);.  if( p->r
16640 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
16650 65 74 75 72 6e 20 70 2d 3e 72 63 3b 0a 0a 20 20  eturn p->rc;..  
16660 2f 2a 20 49 66 20 74 68 65 20 69 74 65 72 61 74  /* If the iterat
16670 6f 72 20 69 73 20 61 6c 72 65 61 64 79 20 61 74  or is already at
16680 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20   the end of the 
16690 63 68 61 6e 67 65 73 65 74 2c 20 72 65 74 75 72  changeset, retur
166a0 6e 20 44 4f 4e 45 2e 20 2a 2f 0a 20 20 69 66 28  n DONE. */.  if(
166b0 20 70 2d 3e 69 6e 2e 69 4e 65 78 74 3e 3d 70 2d   p->in.iNext>=p-
166c0 3e 69 6e 2e 6e 44 61 74 61 20 29 7b 0a 20 20 20  >in.nData ){.   
166d0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 44   return SQLITE_D
166e0 4f 4e 45 3b 0a 20 20 7d 0a 0a 20 20 73 65 73 73  ONE;.  }..  sess
166f0 69 6f 6e 44 69 73 63 61 72 64 44 61 74 61 28 26  ionDiscardData(&
16700 70 2d 3e 69 6e 29 3b 0a 20 20 70 2d 3e 69 6e 2e  p->in);.  p->in.
16710 69 43 75 72 72 65 6e 74 20 3d 20 70 2d 3e 69 6e  iCurrent = p->in
16720 2e 69 4e 65 78 74 3b 0a 0a 20 20 6f 70 20 3d 20  .iNext;..  op = 
16730 70 2d 3e 69 6e 2e 61 44 61 74 61 5b 70 2d 3e 69  p->in.aData[p->i
16740 6e 2e 69 4e 65 78 74 2b 2b 5d 3b 0a 20 20 69 66  n.iNext++];.  if
16750 28 20 6f 70 3d 3d 27 54 27 20 7c 7c 20 6f 70 3d  ( op=='T' || op=
16760 3d 27 50 27 20 29 7b 0a 20 20 20 20 70 2d 3e 62  ='P' ){.    p->b
16770 50 61 74 63 68 73 65 74 20 3d 20 28 6f 70 3d 3d  Patchset = (op==
16780 27 50 27 29 3b 0a 20 20 20 20 69 66 28 20 73 65  'P');.    if( se
16790 73 73 69 6f 6e 43 68 61 6e 67 65 73 65 74 52 65  ssionChangesetRe
167a0 61 64 54 62 6c 68 64 72 28 70 29 20 29 20 72 65  adTblhdr(p) ) re
167b0 74 75 72 6e 20 70 2d 3e 72 63 3b 0a 20 20 20 20  turn p->rc;.    
167c0 69 66 28 20 28 70 2d 3e 72 63 20 3d 20 73 65 73  if( (p->rc = ses
167d0 73 69 6f 6e 49 6e 70 75 74 42 75 66 66 65 72 28  sionInputBuffer(
167e0 26 70 2d 3e 69 6e 2c 20 32 29 29 20 29 20 72 65  &p->in, 2)) ) re
167f0 74 75 72 6e 20 70 2d 3e 72 63 3b 0a 20 20 20 20  turn p->rc;.    
16800 70 2d 3e 69 6e 2e 69 43 75 72 72 65 6e 74 20 3d  p->in.iCurrent =
16810 20 70 2d 3e 69 6e 2e 69 4e 65 78 74 3b 0a 20 20   p->in.iNext;.  
16820 20 20 6f 70 20 3d 20 70 2d 3e 69 6e 2e 61 44 61    op = p->in.aDa
16830 74 61 5b 70 2d 3e 69 6e 2e 69 4e 65 78 74 2b 2b  ta[p->in.iNext++
16840 5d 3b 0a 20 20 7d 0a 0a 20 20 70 2d 3e 6f 70 20  ];.  }..  p->op 
16850 3d 20 6f 70 3b 0a 20 20 70 2d 3e 62 49 6e 64 69  = op;.  p->bIndi
16860 72 65 63 74 20 3d 20 70 2d 3e 69 6e 2e 61 44 61  rect = p->in.aDa
16870 74 61 5b 70 2d 3e 69 6e 2e 69 4e 65 78 74 2b 2b  ta[p->in.iNext++
16880 5d 3b 0a 20 20 69 66 28 20 70 2d 3e 6f 70 21 3d  ];.  if( p->op!=
16890 53 51 4c 49 54 45 5f 55 50 44 41 54 45 20 26 26  SQLITE_UPDATE &&
168a0 20 70 2d 3e 6f 70 21 3d 53 51 4c 49 54 45 5f 44   p->op!=SQLITE_D
168b0 45 4c 45 54 45 20 26 26 20 70 2d 3e 6f 70 21 3d  ELETE && p->op!=
168c0 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 20 29 7b  SQLITE_INSERT ){
168d0 0a 20 20 20 20 72 65 74 75 72 6e 20 28 70 2d 3e  .    return (p->
168e0 72 63 20 3d 20 53 51 4c 49 54 45 5f 43 4f 52 52  rc = SQLITE_CORR
168f0 55 50 54 5f 42 4b 50 54 29 3b 0a 20 20 7d 0a 0a  UPT_BKPT);.  }..
16900 20 20 69 66 28 20 70 61 52 65 63 20 29 7b 20 0a    if( paRec ){ .
16910 20 20 20 20 69 6e 74 20 6e 56 61 6c 3b 20 20 20      int nVal;   
16920 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16930 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 76    /* Number of v
16940 61 6c 75 65 73 20 74 6f 20 62 75 66 66 65 72 20  alues to buffer 
16950 2a 2f 0a 20 20 20 20 69 66 28 20 70 2d 3e 62 50  */.    if( p->bP
16960 61 74 63 68 73 65 74 3d 3d 30 20 26 26 20 6f 70  atchset==0 && op
16970 3d 3d 53 51 4c 49 54 45 5f 55 50 44 41 54 45 20  ==SQLITE_UPDATE 
16980 29 7b 0a 20 20 20 20 20 20 6e 56 61 6c 20 3d 20  ){.      nVal = 
16990 70 2d 3e 6e 43 6f 6c 20 2a 20 32 3b 0a 20 20 20  p->nCol * 2;.   
169a0 20 7d 65 6c 73 65 20 69 66 28 20 70 2d 3e 62 50   }else if( p->bP
169b0 61 74 63 68 73 65 74 20 26 26 20 6f 70 3d 3d 53  atchset && op==S
169c0 51 4c 49 54 45 5f 44 45 4c 45 54 45 20 29 7b 0a  QLITE_DELETE ){.
169d0 20 20 20 20 20 20 6e 56 61 6c 20 3d 20 30 3b 0a        nVal = 0;.
169e0 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69        for(i=0; i
169f0 3c 70 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 20 69  <p->nCol; i++) i
16a00 66 28 20 70 2d 3e 61 62 50 4b 5b 69 5d 20 29 20  f( p->abPK[i] ) 
16a10 6e 56 61 6c 2b 2b 3b 0a 20 20 20 20 7d 65 6c 73  nVal++;.    }els
16a20 65 7b 0a 20 20 20 20 20 20 6e 56 61 6c 20 3d 20  e{.      nVal = 
16a30 70 2d 3e 6e 43 6f 6c 3b 0a 20 20 20 20 7d 0a 20  p->nCol;.    }. 
16a40 20 20 20 70 2d 3e 72 63 20 3d 20 73 65 73 73 69     p->rc = sessi
16a50 6f 6e 43 68 61 6e 67 65 73 65 74 42 75 66 66 65  onChangesetBuffe
16a60 72 52 65 63 6f 72 64 28 26 70 2d 3e 69 6e 2c 20  rRecord(&p->in, 
16a70 6e 56 61 6c 2c 20 70 6e 52 65 63 29 3b 0a 20 20  nVal, pnRec);.  
16a80 20 20 69 66 28 20 70 2d 3e 72 63 21 3d 53 51 4c    if( p->rc!=SQL
16a90 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
16aa0 70 2d 3e 72 63 3b 0a 20 20 20 20 2a 70 61 52 65  p->rc;.    *paRe
16ab0 63 20 3d 20 26 70 2d 3e 69 6e 2e 61 44 61 74 61  c = &p->in.aData
16ac0 5b 70 2d 3e 69 6e 2e 69 4e 65 78 74 5d 3b 0a 20  [p->in.iNext];. 
16ad0 20 20 20 70 2d 3e 69 6e 2e 69 4e 65 78 74 20 2b     p->in.iNext +
16ae0 3d 20 2a 70 6e 52 65 63 3b 0a 20 20 7d 65 6c 73  = *pnRec;.  }els
16af0 65 7b 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74 68  e{..    /* If th
16b00 69 73 20 69 73 20 61 6e 20 55 50 44 41 54 45 20  is is an UPDATE 
16b10 6f 72 20 44 45 4c 45 54 45 2c 20 72 65 61 64 20  or DELETE, read 
16b20 74 68 65 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64  the old.* record
16b30 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 2d 3e  . */.    if( p->
16b40 6f 70 21 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52  op!=SQLITE_INSER
16b50 54 20 26 26 20 28 70 2d 3e 62 50 61 74 63 68 73  T && (p->bPatchs
16b60 65 74 3d 3d 30 20 7c 7c 20 70 2d 3e 6f 70 3d 3d  et==0 || p->op==
16b70 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 29 20 29  SQLITE_DELETE) )
16b80 7b 0a 20 20 20 20 20 20 75 38 20 2a 61 62 50 4b  {.      u8 *abPK
16b90 20 3d 20 70 2d 3e 62 50 61 74 63 68 73 65 74 20   = p->bPatchset 
16ba0 3f 20 70 2d 3e 61 62 50 4b 20 3a 20 30 3b 0a 20  ? p->abPK : 0;. 
16bb0 20 20 20 20 20 70 2d 3e 72 63 20 3d 20 73 65 73       p->rc = ses
16bc0 73 69 6f 6e 52 65 61 64 52 65 63 6f 72 64 28 26  sionReadRecord(&
16bd0 70 2d 3e 69 6e 2c 20 70 2d 3e 6e 43 6f 6c 2c 20  p->in, p->nCol, 
16be0 61 62 50 4b 2c 20 70 2d 3e 61 70 56 61 6c 75 65  abPK, p->apValue
16bf0 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 2d 3e  );.      if( p->
16c00 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
16c10 72 65 74 75 72 6e 20 70 2d 3e 72 63 3b 0a 20 20  return p->rc;.  
16c20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74    }..    /* If t
16c30 68 69 73 20 69 73 20 61 6e 20 49 4e 53 45 52 54  his is an INSERT
16c40 20 6f 72 20 55 50 44 41 54 45 2c 20 72 65 61 64   or UPDATE, read
16c50 20 74 68 65 20 6e 65 77 2e 2a 20 72 65 63 6f 72   the new.* recor
16c60 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 2d  d. */.    if( p-
16c70 3e 6f 70 21 3d 53 51 4c 49 54 45 5f 44 45 4c 45  >op!=SQLITE_DELE
16c80 54 45 20 29 7b 0a 20 20 20 20 20 20 70 2d 3e 72  TE ){.      p->r
16c90 63 20 3d 20 73 65 73 73 69 6f 6e 52 65 61 64 52  c = sessionReadR
16ca0 65 63 6f 72 64 28 26 70 2d 3e 69 6e 2c 20 70 2d  ecord(&p->in, p-
16cb0 3e 6e 43 6f 6c 2c 20 30 2c 20 26 70 2d 3e 61 70  >nCol, 0, &p->ap
16cc0 56 61 6c 75 65 5b 70 2d 3e 6e 43 6f 6c 5d 29 3b  Value[p->nCol]);
16cd0 0a 20 20 20 20 20 20 69 66 28 20 70 2d 3e 72 63  .      if( p->rc
16ce0 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
16cf0 74 75 72 6e 20 70 2d 3e 72 63 3b 0a 20 20 20 20  turn p->rc;.    
16d00 7d 0a 0a 20 20 20 20 69 66 28 20 70 2d 3e 62 50  }..    if( p->bP
16d10 61 74 63 68 73 65 74 20 26 26 20 70 2d 3e 6f 70  atchset && p->op
16d20 3d 3d 53 51 4c 49 54 45 5f 55 50 44 41 54 45 20  ==SQLITE_UPDATE 
16d30 29 7b 0a 20 20 20 20 20 20 2f 2a 20 49 66 20 74  ){.      /* If t
16d40 68 69 73 20 69 73 20 61 6e 20 55 50 44 41 54 45  his is an UPDATE
16d50 20 74 68 61 74 20 69 73 20 70 61 72 74 20 6f 66   that is part of
16d60 20 61 20 70 61 74 63 68 73 65 74 2c 20 74 68 65   a patchset, the
16d70 6e 20 61 6c 6c 20 50 4b 20 61 6e 64 0a 20 20 20  n all PK and.   
16d80 20 20 20 2a 2a 20 6d 6f 64 69 66 69 65 64 20 66     ** modified f
16d90 69 65 6c 64 73 20 61 72 65 20 70 72 65 73 65 6e  ields are presen
16da0 74 20 69 6e 20 74 68 65 20 6e 65 77 2e 2a 20 72  t in the new.* r
16db0 65 63 6f 72 64 2e 20 54 68 65 20 6f 6c 64 2e 2a  ecord. The old.*
16dc0 20 72 65 63 6f 72 64 0a 20 20 20 20 20 20 2a 2a   record.      **
16dd0 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20 63 6f   is currently co
16de0 6d 70 6c 65 74 65 6c 79 20 65 6d 70 74 79 2e 20  mpletely empty. 
16df0 54 68 69 73 20 62 6c 6f 63 6b 20 73 68 69 66 74  This block shift
16e00 73 20 74 68 65 20 50 4b 20 66 69 65 6c 64 73 20  s the PK fields 
16e10 66 72 6f 6d 0a 20 20 20 20 20 20 2a 2a 20 6e 65  from.      ** ne
16e20 77 2e 2a 20 74 6f 20 6f 6c 64 2e 2a 2c 20 74 6f  w.* to old.*, to
16e30 20 61 63 63 6f 6d 6d 6f 64 61 74 65 20 74 68 65   accommodate the
16e40 20 63 6f 64 65 20 74 68 61 74 20 72 65 61 64 73   code that reads
16e50 20 74 68 65 73 65 20 61 72 72 61 79 73 2e 20 20   these arrays.  
16e60 2a 2f 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30  */.      for(i=0
16e70 3b 20 69 3c 70 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b  ; i<p->nCol; i++
16e80 29 7b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  ){.        asser
16e90 74 28 20 70 2d 3e 61 70 56 61 6c 75 65 5b 69 5d  t( p->apValue[i]
16ea0 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 20 20 61  ==0 );.        a
16eb0 73 73 65 72 74 28 20 70 2d 3e 61 62 50 4b 5b 69  ssert( p->abPK[i
16ec0 5d 3d 3d 30 20 7c 7c 20 70 2d 3e 61 70 56 61 6c  ]==0 || p->apVal
16ed0 75 65 5b 69 2b 70 2d 3e 6e 43 6f 6c 5d 20 29 3b  ue[i+p->nCol] );
16ee0 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 2d 3e  .        if( p->
16ef0 61 62 50 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20  abPK[i] ){.     
16f00 20 20 20 20 20 70 2d 3e 61 70 56 61 6c 75 65 5b       p->apValue[
16f10 69 5d 20 3d 20 70 2d 3e 61 70 56 61 6c 75 65 5b  i] = p->apValue[
16f20 69 2b 70 2d 3e 6e 43 6f 6c 5d 3b 0a 20 20 20 20  i+p->nCol];.    
16f30 20 20 20 20 20 20 70 2d 3e 61 70 56 61 6c 75 65        p->apValue
16f40 5b 69 2b 70 2d 3e 6e 43 6f 6c 5d 20 3d 20 30 3b  [i+p->nCol] = 0;
16f50 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
16f60 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
16f70 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 52 4f  return SQLITE_RO
16f80 57 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61  W;.}../*.** Adva
16f90 6e 63 65 20 61 6e 20 69 74 65 72 61 74 6f 72 20  nce an iterator 
16fa0 63 72 65 61 74 65 64 20 62 79 20 73 71 6c 69 74  created by sqlit
16fb0 65 33 63 68 61 6e 67 65 73 65 74 5f 73 74 61 72  e3changeset_star
16fc0 74 28 29 20 74 6f 20 74 68 65 20 6e 65 78 74 0a  t() to the next.
16fd0 2a 2a 20 63 68 61 6e 67 65 20 69 6e 20 74 68 65  ** change in the
16fe0 20 63 68 61 6e 67 65 73 65 74 2e 20 54 68 69 73   changeset. This
16ff0 20 66 75 6e 63 74 69 6f 6e 20 6d 61 79 20 72 65   function may re
17000 74 75 72 6e 20 53 51 4c 49 54 45 5f 52 4f 57 2c  turn SQLITE_ROW,
17010 20 53 51 4c 49 54 45 5f 44 4f 4e 45 0a 2a 2a 20   SQLITE_DONE.** 
17020 6f 72 20 53 51 4c 49 54 45 5f 43 4f 52 52 55 50  or SQLITE_CORRUP
17030 54 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 75  T..**.** This fu
17040 6e 63 74 69 6f 6e 20 6d 61 79 20 6e 6f 74 20 62  nction may not b
17050 65 20 63 61 6c 6c 65 64 20 6f 6e 20 69 74 65 72  e called on iter
17060 61 74 6f 72 73 20 70 61 73 73 65 64 20 74 6f 20  ators passed to 
17070 61 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c  a conflict handl
17080 65 72 0a 2a 2a 20 63 61 6c 6c 62 61 63 6b 20 62  er.** callback b
17090 79 20 63 68 61 6e 67 65 73 65 74 5f 61 70 70 6c  y changeset_appl
170a0 79 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  y()..*/.int sqli
170b0 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6e 65 78  te3changeset_nex
170c0 74 28 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65  t(sqlite3_change
170d0 73 65 74 5f 69 74 65 72 20 2a 70 29 7b 0a 20 20  set_iter *p){.  
170e0 72 65 74 75 72 6e 20 73 65 73 73 69 6f 6e 43 68  return sessionCh
170f0 61 6e 67 65 73 65 74 4e 65 78 74 28 70 2c 20 30  angesetNext(p, 0
17100 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  , 0);.}../*.** T
17110 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 66 75 6e  he following fun
17120 63 74 69 6f 6e 20 65 78 74 72 61 63 74 73 20 69  ction extracts i
17130 6e 66 6f 72 6d 61 74 69 6f 6e 20 6f 6e 20 74 68  nformation on th
17140 65 20 63 75 72 72 65 6e 74 20 63 68 61 6e 67 65  e current change
17150 0a 2a 2a 20 66 72 6f 6d 20 61 20 63 68 61 6e 67  .** from a chang
17160 65 73 65 74 20 69 74 65 72 61 74 6f 72 2e 20 49  eset iterator. I
17170 74 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 63 61  t may only be ca
17180 6c 6c 65 64 20 61 66 74 65 72 20 63 68 61 6e 67  lled after chang
17190 65 73 65 74 5f 6e 65 78 74 28 29 0a 2a 2a 20 68  eset_next().** h
171a0 61 73 20 72 65 74 75 72 6e 65 64 20 53 51 4c 49  as returned SQLI
171b0 54 45 5f 52 4f 57 2e 0a 2a 2f 0a 69 6e 74 20 73  TE_ROW..*/.int s
171c0 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
171d0 6f 70 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 68  op(.  sqlite3_ch
171e0 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a 70 49  angeset_iter *pI
171f0 74 65 72 2c 20 20 2f 2a 20 49 74 65 72 61 74 6f  ter,  /* Iterato
17200 72 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f  r handle */.  co
17210 6e 73 74 20 63 68 61 72 20 2a 2a 70 7a 54 61 62  nst char **pzTab
17220 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
17230 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20 74 6f   OUT: Pointer to
17240 20 74 61 62 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20   table name */. 
17250 20 69 6e 74 20 2a 70 6e 43 6f 6c 2c 20 20 20 20   int *pnCol,    
17260 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17270 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d 62 65 72 20   /* OUT: Number 
17280 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 61  of columns in ta
17290 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 4f  ble */.  int *pO
172a0 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p,              
172b0 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
172c0 20 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 2c 20   SQLITE_INSERT, 
172d0 44 45 4c 45 54 45 20 6f 72 20 55 50 44 41 54 45  DELETE or UPDATE
172e0 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 62 49 6e 64   */.  int *pbInd
172f0 69 72 65 63 74 20 20 20 20 20 20 20 20 20 20 20  irect           
17300 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 72        /* OUT: Tr
17310 75 65 20 69 66 20 63 68 61 6e 67 65 20 69 73 20  ue if change is 
17320 69 6e 64 69 72 65 63 74 20 2a 2f 0a 29 7b 0a 20  indirect */.){. 
17330 20 2a 70 4f 70 20 3d 20 70 49 74 65 72 2d 3e 6f   *pOp = pIter->o
17340 70 3b 0a 20 20 2a 70 6e 43 6f 6c 20 3d 20 70 49  p;.  *pnCol = pI
17350 74 65 72 2d 3e 6e 43 6f 6c 3b 0a 20 20 2a 70 7a  ter->nCol;.  *pz
17360 54 61 62 20 3d 20 70 49 74 65 72 2d 3e 7a 54 61  Tab = pIter->zTa
17370 62 3b 0a 20 20 69 66 28 20 70 62 49 6e 64 69 72  b;.  if( pbIndir
17380 65 63 74 20 29 20 2a 70 62 49 6e 64 69 72 65 63  ect ) *pbIndirec
17390 74 20 3d 20 70 49 74 65 72 2d 3e 62 49 6e 64 69  t = pIter->bIndi
173a0 72 65 63 74 3b 0a 20 20 72 65 74 75 72 6e 20 53  rect;.  return S
173b0 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
173c0 2a 2a 20 52 65 74 75 72 6e 20 69 6e 66 6f 72 6d  ** Return inform
173d0 61 74 69 6f 6e 20 72 65 67 61 72 64 69 6e 67 20  ation regarding 
173e0 74 68 65 20 50 52 49 4d 41 52 59 20 4b 45 59 20  the PRIMARY KEY 
173f0 61 6e 64 20 6e 75 6d 62 65 72 20 6f 66 20 63 6f  and number of co
17400 6c 75 6d 6e 73 20 69 6e 0a 2a 2a 20 74 68 65 20  lumns in.** the 
17410 64 61 74 61 62 61 73 65 20 74 61 62 6c 65 20 61  database table a
17420 66 66 65 63 74 65 64 20 62 79 20 74 68 65 20 63  ffected by the c
17430 68 61 6e 67 65 20 74 68 61 74 20 70 49 74 65 72  hange that pIter
17440 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74   currently point
17450 73 0a 2a 2a 20 74 6f 2e 20 54 68 69 73 20 66 75  s.** to. This fu
17460 6e 63 74 69 6f 6e 20 6d 61 79 20 6f 6e 6c 79 20  nction may only 
17470 62 65 20 63 61 6c 6c 65 64 20 61 66 74 65 72 20  be called after 
17480 63 68 61 6e 67 65 73 65 74 5f 6e 65 78 74 28 29  changeset_next()
17490 20 72 65 74 75 72 6e 73 0a 2a 2a 20 53 51 4c 49   returns.** SQLI
174a0 54 45 5f 52 4f 57 2e 0a 2a 2f 0a 69 6e 74 20 73  TE_ROW..*/.int s
174b0 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
174c0 70 6b 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 68  pk(.  sqlite3_ch
174d0 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a 70 49  angeset_iter *pI
174e0 74 65 72 2c 20 20 2f 2a 20 49 74 65 72 61 74 6f  ter,  /* Iterato
174f0 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 75 6e  r object */.  un
17500 73 69 67 6e 65 64 20 63 68 61 72 20 2a 2a 70 61  signed char **pa
17510 62 50 4b 2c 20 20 20 20 20 20 20 20 20 20 2f 2a  bPK,          /*
17520 20 4f 55 54 3a 20 41 72 72 61 79 20 6f 66 20 62   OUT: Array of b
17530 6f 6f 6c 65 61 6e 20 2d 20 74 72 75 65 20 66 6f  oolean - true fo
17540 72 20 50 4b 20 63 6f 6c 73 20 2a 2f 0a 20 20 69  r PK cols */.  i
17550 6e 74 20 2a 70 6e 43 6f 6c 20 20 20 20 20 20 20  nt *pnCol       
17560 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
17570 2a 20 4f 55 54 3a 20 4e 75 6d 62 65 72 20 6f 66  * OUT: Number of
17580 20 65 6e 74 72 69 65 73 20 69 6e 20 6f 75 74 70   entries in outp
17590 75 74 20 61 72 72 61 79 20 2a 2f 0a 29 7b 0a 20  ut array */.){. 
175a0 20 2a 70 61 62 50 4b 20 3d 20 70 49 74 65 72 2d   *pabPK = pIter-
175b0 3e 61 62 50 4b 3b 0a 20 20 69 66 28 20 70 6e 43  >abPK;.  if( pnC
175c0 6f 6c 20 29 20 2a 70 6e 43 6f 6c 20 3d 20 70 49  ol ) *pnCol = pI
175d0 74 65 72 2d 3e 6e 43 6f 6c 3b 0a 20 20 72 65 74  ter->nCol;.  ret
175e0 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
175f0 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
17600 63 74 69 6f 6e 20 6d 61 79 20 6f 6e 6c 79 20 62  ction may only b
17610 65 20 63 61 6c 6c 65 64 20 77 68 69 6c 65 20 74  e called while t
17620 68 65 20 69 74 65 72 61 74 6f 72 20 69 73 20 70  he iterator is p
17630 6f 69 6e 74 69 6e 67 20 74 6f 20 61 6e 0a 2a 2a  ointing to an.**
17640 20 53 51 4c 49 54 45 5f 55 50 44 41 54 45 20 6f   SQLITE_UPDATE o
17650 72 20 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 20  r SQLITE_DELETE 
17660 63 68 61 6e 67 65 20 28 73 65 65 20 73 71 6c 69  change (see sqli
17670 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f 70 28  te3changeset_op(
17680 29 29 2e 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65  ))..** Otherwise
17690 2c 20 53 51 4c 49 54 45 5f 4d 49 53 55 53 45 20  , SQLITE_MISUSE 
176a0 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a  is returned..**.
176b0 2a 2a 20 49 74 20 73 65 74 73 20 2a 70 70 56 61  ** It sets *ppVa
176c0 6c 75 65 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  lue to point to 
176d0 61 6e 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  an sqlite3_value
176e0 20 73 74 72 75 63 74 75 72 65 20 63 6f 6e 74 61   structure conta
176f0 69 6e 69 6e 67 20 74 68 65 0a 2a 2a 20 69 56 61  ining the.** iVa
17700 6c 27 74 68 20 76 61 6c 75 65 20 69 6e 20 74 68  l'th value in th
17710 65 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 2e 20  e old.* record. 
17720 4f 72 2c 20 69 66 20 74 68 61 74 20 70 61 72 74  Or, if that part
17730 69 63 75 6c 61 72 20 76 61 6c 75 65 20 69 73 20  icular value is 
17740 6e 6f 74 0a 2a 2a 20 69 6e 63 6c 75 64 65 64 20  not.** included 
17750 69 6e 20 74 68 65 20 72 65 63 6f 72 64 20 28 62  in the record (b
17760 65 63 61 75 73 65 20 74 68 65 20 63 68 61 6e 67  ecause the chang
17770 65 20 69 73 20 61 6e 20 55 50 44 41 54 45 20 61  e is an UPDATE a
17780 6e 64 20 74 68 65 20 66 69 65 6c 64 0a 2a 2a 20  nd the field.** 
17790 77 61 73 20 6e 6f 74 20 6d 6f 64 69 66 69 65 64  was not modified
177a0 20 61 6e 64 20 69 73 20 6e 6f 74 20 61 20 50 4b   and is not a PK
177b0 20 63 6f 6c 75 6d 6e 29 2c 20 73 65 74 20 2a 70   column), set *p
177c0 70 56 61 6c 75 65 20 74 6f 20 4e 55 4c 4c 2e 0a  pValue to NULL..
177d0 2a 2a 0a 2a 2a 20 49 66 20 76 61 6c 75 65 20 69  **.** If value i
177e0 56 61 6c 20 69 73 20 6f 75 74 2d 6f 66 2d 72 61  Val is out-of-ra
177f0 6e 67 65 2c 20 53 51 4c 49 54 45 5f 52 41 4e 47  nge, SQLITE_RANG
17800 45 20 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e  E is returned an
17810 64 20 2a 70 70 56 61 6c 75 65 20 69 73 0a 2a 2a  d *ppValue is.**
17820 20 6e 6f 74 20 6d 6f 64 69 66 69 65 64 2e 20 4f   not modified. O
17830 74 68 65 72 77 69 73 65 2c 20 53 51 4c 49 54 45  therwise, SQLITE
17840 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  _OK..*/.int sqli
17850 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f 6c 64  te3changeset_old
17860 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e  (.  sqlite3_chan
17870 67 65 73 65 74 5f 69 74 65 72 20 2a 70 49 74 65  geset_iter *pIte
17880 72 2c 20 20 2f 2a 20 43 68 61 6e 67 65 73 65 74  r,  /* Changeset
17890 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69   iterator */.  i
178a0 6e 74 20 69 56 61 6c 2c 20 20 20 20 20 20 20 20  nt iVal,        
178b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
178c0 2a 20 49 6e 64 65 78 20 6f 66 20 6f 6c 64 2e 2a  * Index of old.*
178d0 20 76 61 6c 75 65 20 74 6f 20 72 65 74 72 69 65   value to retrie
178e0 76 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  ve */.  sqlite3_
178f0 76 61 6c 75 65 20 2a 2a 70 70 56 61 6c 75 65 20  value **ppValue 
17900 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
17910 4f 6c 64 20 76 61 6c 75 65 20 28 6f 72 20 4e 55  Old value (or NU
17920 4c 4c 20 70 6f 69 6e 74 65 72 29 20 2a 2f 0a 29  LL pointer) */.)
17930 7b 0a 20 20 69 66 28 20 70 49 74 65 72 2d 3e 6f  {.  if( pIter->o
17940 70 21 3d 53 51 4c 49 54 45 5f 55 50 44 41 54 45  p!=SQLITE_UPDATE
17950 20 26 26 20 70 49 74 65 72 2d 3e 6f 70 21 3d 53   && pIter->op!=S
17960 51 4c 49 54 45 5f 44 45 4c 45 54 45 20 29 7b 0a  QLITE_DELETE ){.
17970 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
17980 45 5f 4d 49 53 55 53 45 3b 0a 20 20 7d 0a 20 20  E_MISUSE;.  }.  
17990 69 66 28 20 69 56 61 6c 3c 30 20 7c 7c 20 69 56  if( iVal<0 || iV
179a0 61 6c 3e 3d 70 49 74 65 72 2d 3e 6e 43 6f 6c 20  al>=pIter->nCol 
179b0 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
179c0 4c 49 54 45 5f 52 41 4e 47 45 3b 0a 20 20 7d 0a  LITE_RANGE;.  }.
179d0 20 20 2a 70 70 56 61 6c 75 65 20 3d 20 70 49 74    *ppValue = pIt
179e0 65 72 2d 3e 61 70 56 61 6c 75 65 5b 69 56 61 6c  er->apValue[iVal
179f0 5d 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  ];.  return SQLI
17a00 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
17a10 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 6d 61  This function ma
17a20 79 20 6f 6e 6c 79 20 62 65 20 63 61 6c 6c 65 64  y only be called
17a30 20 77 68 69 6c 65 20 74 68 65 20 69 74 65 72 61   while the itera
17a40 74 6f 72 20 69 73 20 70 6f 69 6e 74 69 6e 67 20  tor is pointing 
17a50 74 6f 20 61 6e 0a 2a 2a 20 53 51 4c 49 54 45 5f  to an.** SQLITE_
17a60 55 50 44 41 54 45 20 6f 72 20 53 51 4c 49 54 45  UPDATE or SQLITE
17a70 5f 49 4e 53 45 52 54 20 63 68 61 6e 67 65 20 28  _INSERT change (
17a80 73 65 65 20 73 71 6c 69 74 65 33 63 68 61 6e 67  see sqlite3chang
17a90 65 73 65 74 5f 6f 70 28 29 29 2e 0a 2a 2a 20 4f  eset_op())..** O
17aa0 74 68 65 72 77 69 73 65 2c 20 53 51 4c 49 54 45  therwise, SQLITE
17ab0 5f 4d 49 53 55 53 45 20 69 73 20 72 65 74 75 72  _MISUSE is retur
17ac0 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 74 20 73 65  ned..**.** It se
17ad0 74 73 20 2a 70 70 56 61 6c 75 65 20 74 6f 20 70  ts *ppValue to p
17ae0 6f 69 6e 74 20 74 6f 20 61 6e 20 73 71 6c 69 74  oint to an sqlit
17af0 65 33 5f 76 61 6c 75 65 20 73 74 72 75 63 74 75  e3_value structu
17b00 72 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68  re containing th
17b10 65 0a 2a 2a 20 69 56 61 6c 27 74 68 20 76 61 6c  e.** iVal'th val
17b20 75 65 20 69 6e 20 74 68 65 20 6e 65 77 2e 2a 20  ue in the new.* 
17b30 72 65 63 6f 72 64 2e 20 4f 72 2c 20 69 66 20 74  record. Or, if t
17b40 68 61 74 20 70 61 72 74 69 63 75 6c 61 72 20 76  hat particular v
17b50 61 6c 75 65 20 69 73 20 6e 6f 74 0a 2a 2a 20 69  alue is not.** i
17b60 6e 63 6c 75 64 65 64 20 69 6e 20 74 68 65 20 72  ncluded in the r
17b70 65 63 6f 72 64 20 28 62 65 63 61 75 73 65 20 74  ecord (because t
17b80 68 65 20 63 68 61 6e 67 65 20 69 73 20 61 6e 20  he change is an 
17b90 55 50 44 41 54 45 20 61 6e 64 20 74 68 65 20 66  UPDATE and the f
17ba0 69 65 6c 64 0a 2a 2a 20 77 61 73 20 6e 6f 74 20  ield.** was not 
17bb0 6d 6f 64 69 66 69 65 64 29 2c 20 73 65 74 20 2a  modified), set *
17bc0 70 70 56 61 6c 75 65 20 74 6f 20 4e 55 4c 4c 2e  ppValue to NULL.
17bd0 0a 2a 2a 0a 2a 2a 20 49 66 20 76 61 6c 75 65 20  .**.** If value 
17be0 69 56 61 6c 20 69 73 20 6f 75 74 2d 6f 66 2d 72  iVal is out-of-r
17bf0 61 6e 67 65 2c 20 53 51 4c 49 54 45 5f 52 41 4e  ange, SQLITE_RAN
17c00 47 45 20 69 73 20 72 65 74 75 72 6e 65 64 20 61  GE is returned a
17c10 6e 64 20 2a 70 70 56 61 6c 75 65 20 69 73 0a 2a  nd *ppValue is.*
17c20 2a 20 6e 6f 74 20 6d 6f 64 69 66 69 65 64 2e 20  * not modified. 
17c30 4f 74 68 65 72 77 69 73 65 2c 20 53 51 4c 49 54  Otherwise, SQLIT
17c40 45 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  E_OK..*/.int sql
17c50 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6e 65  ite3changeset_ne
17c60 77 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 68 61  w(.  sqlite3_cha
17c70 6e 67 65 73 65 74 5f 69 74 65 72 20 2a 70 49 74  ngeset_iter *pIt
17c80 65 72 2c 20 20 2f 2a 20 43 68 61 6e 67 65 73 65  er,  /* Changese
17c90 74 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20  t iterator */.  
17ca0 69 6e 74 20 69 56 61 6c 2c 20 20 20 20 20 20 20  int iVal,       
17cb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17cc0 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6e 65 77 2e  /* Index of new.
17cd0 2a 20 76 61 6c 75 65 20 74 6f 20 72 65 74 72 69  * value to retri
17ce0 65 76 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  eve */.  sqlite3
17cf0 5f 76 61 6c 75 65 20 2a 2a 70 70 56 61 6c 75 65  _value **ppValue
17d00 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
17d10 20 4e 65 77 20 76 61 6c 75 65 20 28 6f 72 20 4e   New value (or N
17d20 55 4c 4c 20 70 6f 69 6e 74 65 72 29 20 2a 2f 0a  ULL pointer) */.
17d30 29 7b 0a 20 20 69 66 28 20 70 49 74 65 72 2d 3e  ){.  if( pIter->
17d40 6f 70 21 3d 53 51 4c 49 54 45 5f 55 50 44 41 54  op!=SQLITE_UPDAT
17d50 45 20 26 26 20 70 49 74 65 72 2d 3e 6f 70 21 3d  E && pIter->op!=
17d60 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 20 29 7b  SQLITE_INSERT ){
17d70 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
17d80 54 45 5f 4d 49 53 55 53 45 3b 0a 20 20 7d 0a 20  TE_MISUSE;.  }. 
17d90 20 69 66 28 20 69 56 61 6c 3c 30 20 7c 7c 20 69   if( iVal<0 || i
17da0 56 61 6c 3e 3d 70 49 74 65 72 2d 3e 6e 43 6f 6c  Val>=pIter->nCol
17db0 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
17dc0 51 4c 49 54 45 5f 52 41 4e 47 45 3b 0a 20 20 7d  QLITE_RANGE;.  }
17dd0 0a 20 20 2a 70 70 56 61 6c 75 65 20 3d 20 70 49  .  *ppValue = pI
17de0 74 65 72 2d 3e 61 70 56 61 6c 75 65 5b 70 49 74  ter->apValue[pIt
17df0 65 72 2d 3e 6e 43 6f 6c 2b 69 56 61 6c 5d 3b 0a  er->nCol+iVal];.
17e00 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
17e10 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65  OK;.}../*.** The
17e20 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 77 6f 20 6d   following two m
17e30 61 63 72 6f 73 20 61 72 65 20 75 73 65 64 20 69  acros are used i
17e40 6e 74 65 72 6e 61 6c 6c 79 2e 20 54 68 65 79 20  nternally. They 
17e50 61 72 65 20 73 69 6d 69 6c 61 72 20 74 6f 20 74  are similar to t
17e60 68 65 0a 2a 2a 20 73 71 6c 69 74 65 33 63 68 61  he.** sqlite3cha
17e70 6e 67 65 73 65 74 5f 6e 65 77 28 29 20 61 6e 64  ngeset_new() and
17e80 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
17e90 74 5f 6f 6c 64 28 29 20 66 75 6e 63 74 69 6f 6e  t_old() function
17ea0 73 2c 20 65 78 63 65 70 74 20 74 68 61 74 0a 2a  s, except that.*
17eb0 2a 20 74 68 65 79 20 6f 6d 69 74 20 61 6c 6c 20  * they omit all 
17ec0 65 72 72 6f 72 20 63 68 65 63 6b 69 6e 67 20 61  error checking a
17ed0 6e 64 20 72 65 74 75 72 6e 20 61 20 70 6f 69 6e  nd return a poin
17ee0 74 65 72 20 74 6f 20 74 68 65 20 72 65 71 75 65  ter to the reque
17ef0 73 74 65 64 20 76 61 6c 75 65 2e 0a 2a 2f 0a 23  sted value..*/.#
17f00 64 65 66 69 6e 65 20 73 65 73 73 69 6f 6e 43 68  define sessionCh
17f10 61 6e 67 65 73 65 74 4e 65 77 28 70 49 74 65 72  angesetNew(pIter
17f20 2c 20 69 56 61 6c 29 20 28 70 49 74 65 72 29 2d  , iVal) (pIter)-
17f30 3e 61 70 56 61 6c 75 65 5b 28 70 49 74 65 72 29  >apValue[(pIter)
17f40 2d 3e 6e 43 6f 6c 2b 28 69 56 61 6c 29 5d 0a 23  ->nCol+(iVal)].#
17f50 64 65 66 69 6e 65 20 73 65 73 73 69 6f 6e 43 68  define sessionCh
17f60 61 6e 67 65 73 65 74 4f 6c 64 28 70 49 74 65 72  angesetOld(pIter
17f70 2c 20 69 56 61 6c 29 20 28 70 49 74 65 72 29 2d  , iVal) (pIter)-
17f80 3e 61 70 56 61 6c 75 65 5b 28 69 56 61 6c 29 5d  >apValue[(iVal)]
17f90 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
17fa0 63 74 69 6f 6e 20 6d 61 79 20 6f 6e 6c 79 20 62  ction may only b
17fb0 65 20 63 61 6c 6c 65 64 20 77 69 74 68 20 61 20  e called with a 
17fc0 63 68 61 6e 67 65 73 65 74 20 69 74 65 72 61 74  changeset iterat
17fd0 6f 72 20 74 68 61 74 20 68 61 73 20 62 65 65 6e  or that has been
17fe0 0a 2a 2a 20 70 61 73 73 65 64 20 74 6f 20 61 6e  .** passed to an
17ff0 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45   SQLITE_CHANGESE
18000 54 5f 44 41 54 41 20 6f 72 20 53 51 4c 49 54 45  T_DATA or SQLITE
18010 5f 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c  _CHANGESET_CONFL
18020 49 43 54 20 0a 2a 2a 20 63 6f 6e 66 6c 69 63 74  ICT .** conflict
18030 2d 68 61 6e 64 6c 65 72 20 66 75 6e 63 74 69 6f  -handler functio
18040 6e 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 53 51  n. Otherwise, SQ
18050 4c 49 54 45 5f 4d 49 53 55 53 45 20 69 73 20 72  LITE_MISUSE is r
18060 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 49  eturned..**.** I
18070 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 2a 70  f successful, *p
18080 70 56 61 6c 75 65 20 69 73 20 73 65 74 20 74 6f  pValue is set to
18090 20 70 6f 69 6e 74 20 74 6f 20 61 6e 20 73 71 6c   point to an sql
180a0 69 74 65 33 5f 76 61 6c 75 65 20 73 74 72 75 63  ite3_value struc
180b0 74 75 72 65 0a 2a 2a 20 63 6f 6e 74 61 69 6e 69  ture.** containi
180c0 6e 67 20 74 68 65 20 69 56 61 6c 27 74 68 20 76  ng the iVal'th v
180d0 61 6c 75 65 20 6f 66 20 74 68 65 20 63 6f 6e 66  alue of the conf
180e0 6c 69 63 74 69 6e 67 20 72 65 63 6f 72 64 2e 0a  licting record..
180f0 2a 2a 0a 2a 2a 20 49 66 20 76 61 6c 75 65 20 69  **.** If value i
18100 56 61 6c 20 69 73 20 6f 75 74 2d 6f 66 2d 72 61  Val is out-of-ra
18110 6e 67 65 20 6f 72 20 73 6f 6d 65 20 6f 74 68 65  nge or some othe
18120 72 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20  r error occurs, 
18130 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 0a  an SQLite error.
18140 2a 2a 20 63 6f 64 65 20 69 73 20 72 65 74 75 72  ** code is retur
18150 6e 65 64 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  ned. Otherwise, 
18160 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2f 0a 69 6e  SQLITE_OK..*/.in
18170 74 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  t sqlite3changes
18180 65 74 5f 63 6f 6e 66 6c 69 63 74 28 0a 20 20 73  et_conflict(.  s
18190 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74  qlite3_changeset
181a0 5f 69 74 65 72 20 2a 70 49 74 65 72 2c 20 20 2f  _iter *pIter,  /
181b0 2a 20 43 68 61 6e 67 65 73 65 74 20 69 74 65 72  * Changeset iter
181c0 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 69 56  ator */.  int iV
181d0 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
181e0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64            /* Ind
181f0 65 78 20 6f 66 20 63 6f 6e 66 6c 69 63 74 20 72  ex of conflict r
18200 65 63 6f 72 64 20 76 61 6c 75 65 20 74 6f 20 66  ecord value to f
18210 65 74 63 68 20 2a 2f 0a 20 20 73 71 6c 69 74 65  etch */.  sqlite
18220 33 5f 76 61 6c 75 65 20 2a 2a 70 70 56 61 6c 75  3_value **ppValu
18230 65 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54  e         /* OUT
18240 3a 20 56 61 6c 75 65 20 66 72 6f 6d 20 63 6f 6e  : Value from con
18250 66 6c 69 63 74 69 6e 67 20 72 6f 77 20 2a 2f 0a  flicting row */.
18260 29 7b 0a 20 20 69 66 28 20 21 70 49 74 65 72 2d  ){.  if( !pIter-
18270 3e 70 43 6f 6e 66 6c 69 63 74 20 29 7b 0a 20 20  >pConflict ){.  
18280 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
18290 4d 49 53 55 53 45 3b 0a 20 20 7d 0a 20 20 69 66  MISUSE;.  }.  if
182a0 28 20 69 56 61 6c 3c 30 20 7c 7c 20 69 56 61 6c  ( iVal<0 || iVal
182b0 3e 3d 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  >=sqlite3_column
182c0 5f 63 6f 75 6e 74 28 70 49 74 65 72 2d 3e 70 43  _count(pIter->pC
182d0 6f 6e 66 6c 69 63 74 29 20 29 7b 0a 20 20 20 20  onflict) ){.    
182e0 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 52 41  return SQLITE_RA
182f0 4e 47 45 3b 0a 20 20 7d 0a 20 20 2a 70 70 56 61  NGE;.  }.  *ppVa
18300 6c 75 65 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  lue = sqlite3_co
18310 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 49 74 65 72  lumn_value(pIter
18320 2d 3e 70 43 6f 6e 66 6c 69 63 74 2c 20 69 56 61  ->pConflict, iVa
18330 6c 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  l);.  return SQL
18340 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
18350 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 6d   This function m
18360 61 79 20 6f 6e 6c 79 20 62 65 20 63 61 6c 6c 65  ay only be calle
18370 64 20 77 69 74 68 20 61 6e 20 69 74 65 72 61 74  d with an iterat
18380 6f 72 20 70 61 73 73 65 64 20 74 6f 20 61 6e 0a  or passed to an.
18390 2a 2a 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45  ** SQLITE_CHANGE
183a0 53 45 54 5f 46 4f 52 45 49 47 4e 5f 4b 45 59 20  SET_FOREIGN_KEY 
183b0 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65 72  conflict handler
183c0 20 63 61 6c 6c 62 61 63 6b 2e 20 49 6e 20 74 68   callback. In th
183d0 69 73 20 63 61 73 65 0a 2a 2a 20 69 74 20 73 65  is case.** it se
183e0 74 73 20 74 68 65 20 6f 75 74 70 75 74 20 76 61  ts the output va
183f0 72 69 61 62 6c 65 20 74 6f 20 74 68 65 20 74 6f  riable to the to
18400 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 6b 6e  tal number of kn
18410 6f 77 6e 20 66 6f 72 65 69 67 6e 20 6b 65 79 0a  own foreign key.
18420 2a 2a 20 76 69 6f 6c 61 74 69 6f 6e 73 20 69 6e  ** violations in
18430 20 74 68 65 20 64 65 73 74 69 6e 61 74 69 6f 6e   the destination
18440 20 64 61 74 61 62 61 73 65 20 61 6e 64 20 72 65   database and re
18450 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 4f 4b 2e  turns SQLITE_OK.
18460 0a 2a 2a 0a 2a 2a 20 49 6e 20 61 6c 6c 20 6f 74  .**.** In all ot
18470 68 65 72 20 63 61 73 65 73 20 74 68 69 73 20 66  her cases this f
18480 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 20  unction returns 
18490 53 51 4c 49 54 45 5f 4d 49 53 55 53 45 2e 0a 2a  SQLITE_MISUSE..*
184a0 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 63 68 61  /.int sqlite3cha
184b0 6e 67 65 73 65 74 5f 66 6b 5f 63 6f 6e 66 6c 69  ngeset_fk_confli
184c0 63 74 73 28 0a 20 20 73 71 6c 69 74 65 33 5f 63  cts(.  sqlite3_c
184d0 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a 70  hangeset_iter *p
184e0 49 74 65 72 2c 20 20 2f 2a 20 43 68 61 6e 67 65  Iter,  /* Change
184f0 73 65 74 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a  set iterator */.
18500 20 20 69 6e 74 20 2a 70 6e 4f 75 74 20 20 20 20    int *pnOut    
18510 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18520 20 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d 62 65 72    /* OUT: Number
18530 20 6f 66 20 46 4b 20 76 69 6f 6c 61 74 69 6f 6e   of FK violation
18540 73 20 2a 2f 0a 29 7b 0a 20 20 69 66 28 20 70 49  s */.){.  if( pI
18550 74 65 72 2d 3e 70 43 6f 6e 66 6c 69 63 74 20 7c  ter->pConflict |
18560 7c 20 70 49 74 65 72 2d 3e 61 70 56 61 6c 75 65  | pIter->apValue
18570 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
18580 51 4c 49 54 45 5f 4d 49 53 55 53 45 3b 0a 20 20  QLITE_MISUSE;.  
18590 7d 0a 20 20 2a 70 6e 4f 75 74 20 3d 20 70 49 74  }.  *pnOut = pIt
185a0 65 72 2d 3e 6e 43 6f 6c 3b 0a 20 20 72 65 74 75  er->nCol;.  retu
185b0 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
185c0 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 61 6c 69 7a 65  ../*.** Finalize
185d0 20 61 6e 20 69 74 65 72 61 74 6f 72 20 61 6c 6c   an iterator all
185e0 6f 63 61 74 65 64 20 77 69 74 68 20 73 71 6c 69  ocated with sqli
185f0 74 65 33 63 68 61 6e 67 65 73 65 74 5f 73 74 61  te3changeset_sta
18600 72 74 28 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  rt()..**.** This
18610 20 66 75 6e 63 74 69 6f 6e 20 6d 61 79 20 6e 6f   function may no
18620 74 20 62 65 20 63 61 6c 6c 65 64 20 6f 6e 20 69  t be called on i
18630 74 65 72 61 74 6f 72 73 20 70 61 73 73 65 64 20  terators passed 
18640 74 6f 20 61 20 63 6f 6e 66 6c 69 63 74 20 68 61  to a conflict ha
18650 6e 64 6c 65 72 0a 2a 2a 20 63 61 6c 6c 62 61 63  ndler.** callbac
18660 6b 20 62 79 20 63 68 61 6e 67 65 73 65 74 5f 61  k by changeset_a
18670 70 70 6c 79 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73  pply()..*/.int s
18680 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
18690 66 69 6e 61 6c 69 7a 65 28 73 71 6c 69 74 65 33  finalize(sqlite3
186a0 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20  _changeset_iter 
186b0 2a 70 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  *p){.  int rc = 
186c0 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28  SQLITE_OK;.  if(
186d0 20 70 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b   p ){.    int i;
186e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
186f0 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20          /* Used 
18700 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75  to iterate throu
18710 67 68 20 70 2d 3e 61 70 56 61 6c 75 65 5b 5d 20  gh p->apValue[] 
18720 2a 2f 0a 20 20 20 20 72 63 20 3d 20 70 2d 3e 72  */.    rc = p->r
18730 63 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 61 70  c;.    if( p->ap
18740 56 61 6c 75 65 20 29 7b 0a 20 20 20 20 20 20 66  Value ){.      f
18750 6f 72 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 43 6f  or(i=0; i<p->nCo
18760 6c 2a 32 3b 20 69 2b 2b 29 20 73 71 6c 69 74 65  l*2; i++) sqlite
18770 33 56 61 6c 75 65 46 72 65 65 28 70 2d 3e 61 70  3ValueFree(p->ap
18780 56 61 6c 75 65 5b 69 5d 29 3b 0a 20 20 20 20 7d  Value[i]);.    }
18790 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
187a0 65 28 70 2d 3e 74 62 6c 68 64 72 2e 61 42 75 66  e(p->tblhdr.aBuf
187b0 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
187c0 72 65 65 28 70 2d 3e 69 6e 2e 62 75 66 2e 61 42  ree(p->in.buf.aB
187d0 75 66 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  uf);.    sqlite3
187e0 5f 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a 20 20  _free(p);.  }.  
187f0 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74  return rc;.}..st
18800 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e  atic int session
18810 43 68 61 6e 67 65 73 65 74 49 6e 76 65 72 74 28  ChangesetInvert(
18820 0a 20 20 53 65 73 73 69 6f 6e 49 6e 70 75 74 20  .  SessionInput 
18830 2a 70 49 6e 70 75 74 2c 20 20 20 20 20 20 20 20  *pInput,        
18840 20 20 20 2f 2a 20 49 6e 70 75 74 20 63 68 61 6e     /* Input chan
18850 67 65 73 65 74 20 2a 2f 0a 20 20 69 6e 74 20 28  geset */.  int (
18860 2a 78 4f 75 74 70 75 74 29 28 76 6f 69 64 20 2a  *xOutput)(void *
18870 70 4f 75 74 2c 20 63 6f 6e 73 74 20 76 6f 69 64  pOut, const void
18880 20 2a 70 44 61 74 61 2c 20 69 6e 74 20 6e 44 61   *pData, int nDa
18890 74 61 29 2c 0a 20 20 76 6f 69 64 20 2a 70 4f 75  ta),.  void *pOu
188a0 74 2c 0a 20 20 69 6e 74 20 2a 70 6e 49 6e 76 65  t,.  int *pnInve
188b0 72 74 65 64 2c 20 20 20 20 20 20 20 20 20 20 20  rted,           
188c0 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d       /* OUT: Num
188d0 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
188e0 6f 75 74 70 75 74 20 63 68 61 6e 67 65 73 65 74  output changeset
188f0 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 2a 70 70 49   */.  void **ppI
18900 6e 76 65 72 74 65 64 20 20 20 20 20 20 20 20 20  nverted         
18910 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 49 6e        /* OUT: In
18920 76 65 72 73 65 20 6f 66 20 70 43 68 61 6e 67 65  verse of pChange
18930 73 65 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  set */.){.  int 
18940 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20  rc = SQLITE_OK; 
18950 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
18960 65 74 75 72 6e 20 76 61 6c 75 65 20 2a 2f 0a 20  eturn value */. 
18970 20 53 65 73 73 69 6f 6e 42 75 66 66 65 72 20 73   SessionBuffer s
18980 4f 75 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  Out;            
18990 20 2f 2a 20 4f 75 74 70 75 74 20 62 75 66 66 65   /* Output buffe
189a0 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 20  r */.  int nCol 
189b0 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
189c0 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
189d0 20 6f 66 20 63 6f 6c 73 20 69 6e 20 63 75 72 72   of cols in curr
189e0 65 6e 74 20 74 61 62 6c 65 20 2a 2f 0a 20 20 75  ent table */.  u
189f0 38 20 2a 61 62 50 4b 20 3d 20 30 3b 20 20 20 20  8 *abPK = 0;    
18a00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
18a10 2a 20 50 4b 20 61 72 72 61 79 20 66 6f 72 20 63  * PK array for c
18a20 75 72 72 65 6e 74 20 74 61 62 6c 65 20 2a 2f 0a  urrent table */.
18a30 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
18a40 2a 2a 61 70 56 61 6c 20 3d 20 30 3b 20 20 20 20  **apVal = 0;    
18a50 20 20 2f 2a 20 53 70 61 63 65 20 66 6f 72 20 76    /* Space for v
18a60 61 6c 75 65 73 20 66 6f 72 20 55 50 44 41 54 45  alues for UPDATE
18a70 20 69 6e 76 65 72 73 69 6f 6e 20 2a 2f 0a 20 20   inversion */.  
18a80 53 65 73 73 69 6f 6e 42 75 66 66 65 72 20 73 50  SessionBuffer sP
18a90 4b 20 3d 20 7b 30 2c 20 30 2c 20 30 7d 3b 20 20  K = {0, 0, 0};  
18aa0 2f 2a 20 50 4b 20 61 72 72 61 79 20 66 6f 72 20  /* PK array for 
18ab0 63 75 72 72 65 6e 74 20 74 61 62 6c 65 20 2a 2f  current table */
18ac0 0a 0a 20 20 2f 2a 20 49 6e 69 74 69 61 6c 69 7a  ..  /* Initializ
18ad0 65 20 74 68 65 20 6f 75 74 70 75 74 20 62 75 66  e the output buf
18ae0 66 65 72 20 2a 2f 0a 20 20 6d 65 6d 73 65 74 28  fer */.  memset(
18af0 26 73 4f 75 74 2c 20 30 2c 20 73 69 7a 65 6f 66  &sOut, 0, sizeof
18b00 28 53 65 73 73 69 6f 6e 42 75 66 66 65 72 29 29  (SessionBuffer))
18b10 3b 0a 0a 20 20 2f 2a 20 5a 65 72 6f 20 74 68 65  ;..  /* Zero the
18b20 20 6f 75 74 70 75 74 20 76 61 72 69 61 62 6c 65   output variable
18b30 73 20 69 6e 20 63 61 73 65 20 61 6e 20 65 72 72  s in case an err
18b40 6f 72 20 6f 63 63 75 72 73 2e 20 2a 2f 0a 20 20  or occurs. */.  
18b50 69 66 28 20 70 70 49 6e 76 65 72 74 65 64 20 29  if( ppInverted )
18b60 7b 0a 20 20 20 20 2a 70 70 49 6e 76 65 72 74 65  {.    *ppInverte
18b70 64 20 3d 20 30 3b 0a 20 20 20 20 2a 70 6e 49 6e  d = 0;.    *pnIn
18b80 76 65 72 74 65 64 20 3d 20 30 3b 0a 20 20 7d 0a  verted = 0;.  }.
18b90 0a 20 20 77 68 69 6c 65 28 20 31 20 29 7b 0a 20  .  while( 1 ){. 
18ba0 20 20 20 75 38 20 65 54 79 70 65 3b 0a 0a 20 20     u8 eType;..  
18bb0 20 20 2f 2a 20 54 65 73 74 20 66 6f 72 20 45 4f    /* Test for EO
18bc0 46 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 28 72  F. */.    if( (r
18bd0 63 20 3d 20 73 65 73 73 69 6f 6e 49 6e 70 75 74  c = sessionInput
18be0 42 75 66 66 65 72 28 70 49 6e 70 75 74 2c 20 32  Buffer(pInput, 2
18bf0 29 29 20 29 20 67 6f 74 6f 20 66 69 6e 69 73 68  )) ) goto finish
18c00 65 64 5f 69 6e 76 65 72 74 3b 0a 20 20 20 20 69  ed_invert;.    i
18c10 66 28 20 70 49 6e 70 75 74 2d 3e 69 4e 65 78 74  f( pInput->iNext
18c20 3e 3d 70 49 6e 70 75 74 2d 3e 6e 44 61 74 61 20  >=pInput->nData 
18c30 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 65 54 79  ) break;.    eTy
18c40 70 65 20 3d 20 70 49 6e 70 75 74 2d 3e 61 44 61  pe = pInput->aDa
18c50 74 61 5b 70 49 6e 70 75 74 2d 3e 69 4e 65 78 74  ta[pInput->iNext
18c60 5d 3b 0a 0a 20 20 20 20 73 77 69 74 63 68 28 20  ];..    switch( 
18c70 65 54 79 70 65 20 29 7b 0a 20 20 20 20 20 20 63  eType ){.      c
18c80 61 73 65 20 27 54 27 3a 20 7b 0a 20 20 20 20 20  ase 'T': {.     
18c90 20 20 20 2f 2a 20 41 20 27 74 61 62 6c 65 27 20     /* A 'table' 
18ca0 72 65 63 6f 72 64 20 63 6f 6e 73 69 73 74 73 20  record consists 
18cb0 6f 66 3a 0a 20 20 20 20 20 20 20 20 2a 2a 0a 20  of:.        **. 
18cc0 20 20 20 20 20 20 20 2a 2a 20 20 20 2a 20 41 20         **   * A 
18cd0 63 6f 6e 73 74 61 6e 74 20 27 54 27 20 63 68 61  constant 'T' cha
18ce0 72 61 63 74 65 72 2c 0a 20 20 20 20 20 20 20 20  racter,.        
18cf0 2a 2a 20 20 20 2a 20 4e 75 6d 62 65 72 20 6f 66  **   * Number of
18d00 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 73 61 69 64   columns in said
18d10 20 74 61 62 6c 65 20 28 61 20 76 61 72 69 6e 74   table (a varint
18d20 29 2c 0a 20 20 20 20 20 20 20 20 2a 2a 20 20 20  ),.        **   
18d30 2a 20 41 6e 20 61 72 72 61 79 20 6f 66 20 6e 43  * An array of nC
18d40 6f 6c 20 62 79 74 65 73 20 28 73 50 4b 29 2c 0a  ol bytes (sPK),.
18d50 20 20 20 20 20 20 20 20 2a 2a 20 20 20 2a 20 41          **   * A
18d60 20 6e 75 6c 2d 74 65 72 6d 69 6e 61 74 65 64 20   nul-terminated 
18d70 74 61 62 6c 65 20 6e 61 6d 65 2e 0a 20 20 20 20  table name..    
18d80 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 69      */.        i
18d90 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20 20 20 20  nt nByte;.      
18da0 20 20 69 6e 74 20 6e 56 61 72 3b 0a 20 20 20 20    int nVar;.    
18db0 20 20 20 20 70 49 6e 70 75 74 2d 3e 69 4e 65 78      pInput->iNex
18dc0 74 2b 2b 3b 0a 20 20 20 20 20 20 20 20 69 66 28  t++;.        if(
18dd0 20 28 72 63 20 3d 20 73 65 73 73 69 6f 6e 43 68   (rc = sessionCh
18de0 61 6e 67 65 73 65 74 42 75 66 66 65 72 54 62 6c  angesetBufferTbl
18df0 68 64 72 28 70 49 6e 70 75 74 2c 20 26 6e 42 79  hdr(pInput, &nBy
18e00 74 65 29 29 20 29 7b 0a 20 20 20 20 20 20 20 20  te)) ){.        
18e10 20 20 67 6f 74 6f 20 66 69 6e 69 73 68 65 64 5f    goto finished_
18e20 69 6e 76 65 72 74 3b 0a 20 20 20 20 20 20 20 20  invert;.        
18e30 7d 0a 20 20 20 20 20 20 20 20 6e 56 61 72 20 3d  }.        nVar =
18e40 20 73 65 73 73 69 6f 6e 56 61 72 69 6e 74 47 65   sessionVarintGe
18e50 74 28 26 70 49 6e 70 75 74 2d 3e 61 44 61 74 61  t(&pInput->aData
18e60 5b 70 49 6e 70 75 74 2d 3e 69 4e 65 78 74 5d 2c  [pInput->iNext],
18e70 20 26 6e 43 6f 6c 29 3b 0a 20 20 20 20 20 20 20   &nCol);.       
18e80 20 73 50 4b 2e 6e 42 75 66 20 3d 20 30 3b 0a 20   sPK.nBuf = 0;. 
18e90 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70         sessionAp
18ea0 70 65 6e 64 42 6c 6f 62 28 26 73 50 4b 2c 20 26  pendBlob(&sPK, &
18eb0 70 49 6e 70 75 74 2d 3e 61 44 61 74 61 5b 70 49  pInput->aData[pI
18ec0 6e 70 75 74 2d 3e 69 4e 65 78 74 2b 6e 56 61 72  nput->iNext+nVar
18ed0 5d 2c 20 6e 43 6f 6c 2c 20 26 72 63 29 3b 0a 20  ], nCol, &rc);. 
18ee0 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70         sessionAp
18ef0 70 65 6e 64 42 79 74 65 28 26 73 4f 75 74 2c 20  pendByte(&sOut, 
18f00 65 54 79 70 65 2c 20 26 72 63 29 3b 0a 20 20 20  eType, &rc);.   
18f10 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65       sessionAppe
18f20 6e 64 42 6c 6f 62 28 26 73 4f 75 74 2c 20 26 70  ndBlob(&sOut, &p
18f30 49 6e 70 75 74 2d 3e 61 44 61 74 61 5b 70 49 6e  Input->aData[pIn
18f40 70 75 74 2d 3e 69 4e 65 78 74 5d 2c 20 6e 42 79  put->iNext], nBy
18f50 74 65 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20  te, &rc);.      
18f60 20 20 69 66 28 20 72 63 20 29 20 67 6f 74 6f 20    if( rc ) goto 
18f70 66 69 6e 69 73 68 65 64 5f 69 6e 76 65 72 74 3b  finished_invert;
18f80 0a 0a 20 20 20 20 20 20 20 20 70 49 6e 70 75 74  ..        pInput
18f90 2d 3e 69 4e 65 78 74 20 2b 3d 20 6e 42 79 74 65  ->iNext += nByte
18fa0 3b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65  ;.        sqlite
18fb0 33 5f 66 72 65 65 28 61 70 56 61 6c 29 3b 0a 20  3_free(apVal);. 
18fc0 20 20 20 20 20 20 20 61 70 56 61 6c 20 3d 20 30         apVal = 0
18fd0 3b 0a 20 20 20 20 20 20 20 20 61 62 50 4b 20 3d  ;.        abPK =
18fe0 20 73 50 4b 2e 61 42 75 66 3b 0a 20 20 20 20 20   sPK.aBuf;.     
18ff0 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
19000 7d 0a 0a 20 20 20 20 20 20 63 61 73 65 20 53 51  }..      case SQ
19010 4c 49 54 45 5f 49 4e 53 45 52 54 3a 0a 20 20 20  LITE_INSERT:.   
19020 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 44     case SQLITE_D
19030 45 4c 45 54 45 3a 20 7b 0a 20 20 20 20 20 20 20  ELETE: {.       
19040 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20 20   int nByte;.    
19050 20 20 20 20 69 6e 74 20 62 49 6e 64 69 72 65 63      int bIndirec
19060 74 20 3d 20 70 49 6e 70 75 74 2d 3e 61 44 61 74  t = pInput->aDat
19070 61 5b 70 49 6e 70 75 74 2d 3e 69 4e 65 78 74 2b  a[pInput->iNext+
19080 31 5d 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20  1];.        int 
19090 65 54 79 70 65 32 20 3d 20 28 65 54 79 70 65 3d  eType2 = (eType=
190a0 3d 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 20 3f  =SQLITE_DELETE ?
190b0 20 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 20 3a   SQLITE_INSERT :
190c0 20 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 29 3b   SQLITE_DELETE);
190d0 0a 20 20 20 20 20 20 20 20 70 49 6e 70 75 74 2d  .        pInput-
190e0 3e 69 4e 65 78 74 20 2b 3d 20 32 3b 0a 20 20 20  >iNext += 2;.   
190f0 20 20 20 20 20 61 73 73 65 72 74 28 20 72 63 3d       assert( rc=
19100 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20  =SQLITE_OK );.  
19110 20 20 20 20 20 20 72 63 20 3d 20 73 65 73 73 69        rc = sessi
19120 6f 6e 43 68 61 6e 67 65 73 65 74 42 75 66 66 65  onChangesetBuffe
19130 72 52 65 63 6f 72 64 28 70 49 6e 70 75 74 2c 20  rRecord(pInput, 
19140 6e 43 6f 6c 2c 20 26 6e 42 79 74 65 29 3b 0a 20  nCol, &nByte);. 
19150 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70         sessionAp
19160 70 65 6e 64 42 79 74 65 28 26 73 4f 75 74 2c 20  pendByte(&sOut, 
19170 65 54 79 70 65 32 2c 20 26 72 63 29 3b 0a 20 20  eType2, &rc);.  
19180 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70        sessionApp
19190 65 6e 64 42 79 74 65 28 26 73 4f 75 74 2c 20 62  endByte(&sOut, b
191a0 49 6e 64 69 72 65 63 74 2c 20 26 72 63 29 3b 0a  Indirect, &rc);.
191b0 20 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41          sessionA
191c0 70 70 65 6e 64 42 6c 6f 62 28 26 73 4f 75 74 2c  ppendBlob(&sOut,
191d0 20 26 70 49 6e 70 75 74 2d 3e 61 44 61 74 61 5b   &pInput->aData[
191e0 70 49 6e 70 75 74 2d 3e 69 4e 65 78 74 5d 2c 20  pInput->iNext], 
191f0 6e 42 79 74 65 2c 20 26 72 63 29 3b 0a 20 20 20  nByte, &rc);.   
19200 20 20 20 20 20 70 49 6e 70 75 74 2d 3e 69 4e 65       pInput->iNe
19210 78 74 20 2b 3d 20 6e 42 79 74 65 3b 0a 20 20 20  xt += nByte;.   
19220 20 20 20 20 20 69 66 28 20 72 63 20 29 20 67 6f       if( rc ) go
19230 74 6f 20 66 69 6e 69 73 68 65 64 5f 69 6e 76 65  to finished_inve
19240 72 74 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  rt;.        brea
19250 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  k;.      }..    
19260 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 55 50    case SQLITE_UP
19270 44 41 54 45 3a 20 7b 0a 20 20 20 20 20 20 20 20  DATE: {.        
19280 69 6e 74 20 69 43 6f 6c 3b 0a 0a 20 20 20 20 20  int iCol;..     
19290 20 20 20 69 66 28 20 30 3d 3d 61 70 56 61 6c 20     if( 0==apVal 
192a0 29 7b 0a 20 20 20 20 20 20 20 20 20 20 61 70 56  ){.          apV
192b0 61 6c 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 61  al = (sqlite3_va
192c0 6c 75 65 20 2a 2a 29 73 71 6c 69 74 65 33 5f 6d  lue **)sqlite3_m
192d0 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 61 70 56  alloc(sizeof(apV
192e0 61 6c 5b 30 5d 29 2a 6e 43 6f 6c 2a 32 29 3b 0a  al[0])*nCol*2);.
192f0 20 20 20 20 20 20 20 20 20 20 69 66 28 20 30 3d            if( 0=
19300 3d 61 70 56 61 6c 20 29 7b 0a 20 20 20 20 20 20  =apVal ){.      
19310 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
19320 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 20  E_NOMEM;.       
19330 20 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73 68       goto finish
19340 65 64 5f 69 6e 76 65 72 74 3b 0a 20 20 20 20 20  ed_invert;.     
19350 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
19360 20 6d 65 6d 73 65 74 28 61 70 56 61 6c 2c 20 30   memset(apVal, 0
19370 2c 20 73 69 7a 65 6f 66 28 61 70 56 61 6c 5b 30  , sizeof(apVal[0
19380 5d 29 2a 6e 43 6f 6c 2a 32 29 3b 0a 20 20 20 20  ])*nCol*2);.    
19390 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 2f      }..        /
193a0 2a 20 57 72 69 74 65 20 74 68 65 20 68 65 61 64  * Write the head
193b0 65 72 20 66 6f 72 20 74 68 65 20 6e 65 77 20 55  er for the new U
193c0 50 44 41 54 45 20 63 68 61 6e 67 65 2e 20 53 61  PDATE change. Sa
193d0 6d 65 20 61 73 20 74 68 65 20 6f 72 69 67 69 6e  me as the origin
193e0 61 6c 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20 73  al. */.        s
193f0 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65  essionAppendByte
19400 28 26 73 4f 75 74 2c 20 65 54 79 70 65 2c 20 26  (&sOut, eType, &
19410 72 63 29 3b 0a 20 20 20 20 20 20 20 20 73 65 73  rc);.        ses
19420 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 26  sionAppendByte(&
19430 73 4f 75 74 2c 20 70 49 6e 70 75 74 2d 3e 61 44  sOut, pInput->aD
19440 61 74 61 5b 70 49 6e 70 75 74 2d 3e 69 4e 65 78  ata[pInput->iNex
19450 74 2b 31 5d 2c 20 26 72 63 29 3b 0a 0a 20 20 20  t+1], &rc);..   
19460 20 20 20 20 20 2f 2a 20 52 65 61 64 20 74 68 65       /* Read the
19470 20 6f 6c 64 2e 2a 20 61 6e 64 20 6e 65 77 2e 2a   old.* and new.*
19480 20 72 65 63 6f 72 64 73 20 66 6f 72 20 74 68 65   records for the
19490 20 75 70 64 61 74 65 20 63 68 61 6e 67 65 2e 20   update change. 
194a0 2a 2f 0a 20 20 20 20 20 20 20 20 70 49 6e 70 75  */.        pInpu
194b0 74 2d 3e 69 4e 65 78 74 20 2b 3d 20 32 3b 0a 20  t->iNext += 2;. 
194c0 20 20 20 20 20 20 20 72 63 20 3d 20 73 65 73 73         rc = sess
194d0 69 6f 6e 52 65 61 64 52 65 63 6f 72 64 28 70 49  ionReadRecord(pI
194e0 6e 70 75 74 2c 20 6e 43 6f 6c 2c 20 30 2c 20 26  nput, nCol, 0, &
194f0 61 70 56 61 6c 5b 30 5d 29 3b 0a 20 20 20 20 20  apVal[0]);.     
19500 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
19510 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
19520 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 52 65    rc = sessionRe
19530 61 64 52 65 63 6f 72 64 28 70 49 6e 70 75 74 2c  adRecord(pInput,
19540 20 6e 43 6f 6c 2c 20 30 2c 20 26 61 70 56 61 6c   nCol, 0, &apVal
19550 5b 6e 43 6f 6c 5d 29 3b 0a 20 20 20 20 20 20 20  [nCol]);.       
19560 20 7d 0a 0a 20 20 20 20 20 20 20 20 2f 2a 20 57   }..        /* W
19570 72 69 74 65 20 74 68 65 20 6e 65 77 20 6f 6c 64  rite the new old
19580 2e 2a 20 72 65 63 6f 72 64 2e 20 43 6f 6e 73 69  .* record. Consi
19590 73 74 73 20 6f 66 20 74 68 65 20 50 4b 20 63 6f  sts of the PK co
195a0 6c 75 6d 6e 73 20 66 72 6f 6d 20 74 68 65 0a 20  lumns from the. 
195b0 20 20 20 20 20 20 20 2a 2a 20 6f 72 69 67 69 6e         ** origin
195c0 61 6c 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 2c  al old.* record,
195d0 20 61 6e 64 20 74 68 65 20 6f 74 68 65 72 20 76   and the other v
195e0 61 6c 75 65 73 20 66 72 6f 6d 20 74 68 65 20 6f  alues from the o
195f0 72 69 67 69 6e 61 6c 0a 20 20 20 20 20 20 20 20  riginal.        
19600 2a 2a 20 6e 65 77 2e 2a 20 72 65 63 6f 72 64 2e  ** new.* record.
19610 20 2a 2f 0a 20 20 20 20 20 20 20 20 66 6f 72 28   */.        for(
19620 69 43 6f 6c 3d 30 3b 20 69 43 6f 6c 3c 6e 43 6f  iCol=0; iCol<nCo
19630 6c 3b 20 69 43 6f 6c 2b 2b 29 7b 0a 20 20 20 20  l; iCol++){.    
19640 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61        sqlite3_va
19650 6c 75 65 20 2a 70 56 61 6c 20 3d 20 61 70 56 61  lue *pVal = apVa
19660 6c 5b 69 43 6f 6c 20 2b 20 28 61 62 50 4b 5b 69  l[iCol + (abPK[i
19670 43 6f 6c 5d 20 3f 20 30 20 3a 20 6e 43 6f 6c 29  Col] ? 0 : nCol)
19680 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 73 65 73  ];.          ses
19690 73 69 6f 6e 41 70 70 65 6e 64 56 61 6c 75 65 28  sionAppendValue(
196a0 26 73 4f 75 74 2c 20 70 56 61 6c 2c 20 26 72 63  &sOut, pVal, &rc
196b0 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20  );.        }..  
196c0 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74        /* Write t
196d0 68 65 20 6e 65 77 20 6e 65 77 2e 2a 20 72 65 63  he new new.* rec
196e0 6f 72 64 2e 20 43 6f 6e 73 69 73 74 73 20 6f 66  ord. Consists of
196f0 20 61 20 63 6f 70 79 20 6f 66 20 61 6c 6c 20 76   a copy of all v
19700 61 6c 75 65 73 0a 20 20 20 20 20 20 20 20 2a 2a  alues.        **
19710 20 66 72 6f 6d 20 74 68 65 20 6f 72 69 67 69 6e   from the origin
19720 61 6c 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 2c  al old.* record,
19730 20 65 78 63 65 70 74 20 66 6f 72 20 74 68 65 20   except for the 
19740 50 4b 20 63 6f 6c 75 6d 6e 73 2c 20 77 68 69 63  PK columns, whic
19750 68 0a 20 20 20 20 20 20 20 20 2a 2a 20 61 72 65  h.        ** are
19760 20 73 65 74 20 74 6f 20 22 75 6e 64 65 66 69 6e   set to "undefin
19770 65 64 22 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20  ed". */.        
19780 66 6f 72 28 69 43 6f 6c 3d 30 3b 20 69 43 6f 6c  for(iCol=0; iCol
19790 3c 6e 43 6f 6c 3b 20 69 43 6f 6c 2b 2b 29 7b 0a  <nCol; iCol++){.
197a0 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65            sqlite
197b0 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c 20 3d 20  3_value *pVal = 
197c0 28 61 62 50 4b 5b 69 43 6f 6c 5d 20 3f 20 30 20  (abPK[iCol] ? 0 
197d0 3a 20 61 70 56 61 6c 5b 69 43 6f 6c 5d 29 3b 0a  : apVal[iCol]);.
197e0 20 20 20 20 20 20 20 20 20 20 73 65 73 73 69 6f            sessio
197f0 6e 41 70 70 65 6e 64 56 61 6c 75 65 28 26 73 4f  nAppendValue(&sO
19800 75 74 2c 20 70 56 61 6c 2c 20 26 72 63 29 3b 0a  ut, pVal, &rc);.
19810 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20          }..     
19820 20 20 20 66 6f 72 28 69 43 6f 6c 3d 30 3b 20 69     for(iCol=0; i
19830 43 6f 6c 3c 6e 43 6f 6c 2a 32 3b 20 69 43 6f 6c  Col<nCol*2; iCol
19840 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 73  ++){.          s
19850 71 6c 69 74 65 33 56 61 6c 75 65 46 72 65 65 28  qlite3ValueFree(
19860 61 70 56 61 6c 5b 69 43 6f 6c 5d 29 3b 0a 20 20  apVal[iCol]);.  
19870 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
19880 6d 65 6d 73 65 74 28 61 70 56 61 6c 2c 20 30 2c  memset(apVal, 0,
19890 20 73 69 7a 65 6f 66 28 61 70 56 61 6c 5b 30 5d   sizeof(apVal[0]
198a0 29 2a 6e 43 6f 6c 2a 32 29 3b 0a 20 20 20 20 20  )*nCol*2);.     
198b0 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
198c0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
198d0 20 20 67 6f 74 6f 20 66 69 6e 69 73 68 65 64 5f    goto finished_
198e0 69 6e 76 65 72 74 3b 0a 20 20 20 20 20 20 20 20  invert;.        
198f0 7d 0a 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  }..        break
19900 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  ;.      }..     
19910 20 64 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20   default:.      
19920 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 43 4f    rc = SQLITE_CO
19930 52 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20 20 20  RRUPT_BKPT;.    
19940 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73 68 65      goto finishe
19950 64 5f 69 6e 76 65 72 74 3b 0a 20 20 20 20 7d 0a  d_invert;.    }.
19960 0a 20 20 20 20 61 73 73 65 72 74 28 20 72 63 3d  .    assert( rc=
19970 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20  =SQLITE_OK );.  
19980 20 20 69 66 28 20 78 4f 75 74 70 75 74 20 26 26    if( xOutput &&
19990 20 73 4f 75 74 2e 6e 42 75 66 3e 3d 53 45 53 53   sOut.nBuf>=SESS
199a0 49 4f 4e 53 5f 53 54 52 4d 5f 43 48 55 4e 4b 5f  IONS_STRM_CHUNK_
199b0 53 49 5a 45 20 29 7b 0a 20 20 20 20 20 20 72 63  SIZE ){.      rc
199c0 20 3d 20 78 4f 75 74 70 75 74 28 70 4f 75 74 2c   = xOutput(pOut,
199d0 20 73 4f 75 74 2e 61 42 75 66 2c 20 73 4f 75 74   sOut.aBuf, sOut
199e0 2e 6e 42 75 66 29 3b 0a 20 20 20 20 20 20 73 4f  .nBuf);.      sO
199f0 75 74 2e 6e 42 75 66 20 3d 20 30 3b 0a 20 20 20  ut.nBuf = 0;.   
19a00 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
19a10 45 5f 4f 4b 20 29 20 67 6f 74 6f 20 66 69 6e 69  E_OK ) goto fini
19a20 73 68 65 64 5f 69 6e 76 65 72 74 3b 0a 20 20 20  shed_invert;.   
19a30 20 7d 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74   }.  }..  assert
19a40 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
19a50 29 3b 0a 20 20 69 66 28 20 70 6e 49 6e 76 65 72  );.  if( pnInver
19a60 74 65 64 20 29 7b 0a 20 20 20 20 2a 70 6e 49 6e  ted ){.    *pnIn
19a70 76 65 72 74 65 64 20 3d 20 73 4f 75 74 2e 6e 42  verted = sOut.nB
19a80 75 66 3b 0a 20 20 20 20 2a 70 70 49 6e 76 65 72  uf;.    *ppInver
19a90 74 65 64 20 3d 20 73 4f 75 74 2e 61 42 75 66 3b  ted = sOut.aBuf;
19aa0 0a 20 20 20 20 73 4f 75 74 2e 61 42 75 66 20 3d  .    sOut.aBuf =
19ab0 20 30 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20   0;.  }else if( 
19ac0 73 4f 75 74 2e 6e 42 75 66 3e 30 20 29 7b 0a 20  sOut.nBuf>0 ){. 
19ad0 20 20 20 72 63 20 3d 20 78 4f 75 74 70 75 74 28     rc = xOutput(
19ae0 70 4f 75 74 2c 20 73 4f 75 74 2e 61 42 75 66 2c  pOut, sOut.aBuf,
19af0 20 73 4f 75 74 2e 6e 42 75 66 29 3b 0a 20 20 7d   sOut.nBuf);.  }
19b00 0a 0a 20 66 69 6e 69 73 68 65 64 5f 69 6e 76 65  .. finished_inve
19b10 72 74 3a 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  rt:.  sqlite3_fr
19b20 65 65 28 73 4f 75 74 2e 61 42 75 66 29 3b 0a 20  ee(sOut.aBuf);. 
19b30 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 70   sqlite3_free(ap
19b40 56 61 6c 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  Val);.  sqlite3_
19b50 66 72 65 65 28 73 50 4b 2e 61 42 75 66 29 3b 0a  free(sPK.aBuf);.
19b60 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
19b70 0a 2f 2a 0a 2a 2a 20 49 6e 76 65 72 74 20 61 20  ./*.** Invert a 
19b80 63 68 61 6e 67 65 73 65 74 20 6f 62 6a 65 63 74  changeset object
19b90 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
19ba0 63 68 61 6e 67 65 73 65 74 5f 69 6e 76 65 72 74  changeset_invert
19bb0 28 0a 20 20 69 6e 74 20 6e 43 68 61 6e 67 65 73  (.  int nChanges
19bc0 65 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  et,             
19bd0 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
19be0 20 62 79 74 65 73 20 69 6e 20 69 6e 70 75 74 20   bytes in input 
19bf0 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20  */.  const void 
19c00 2a 70 43 68 61 6e 67 65 73 65 74 2c 20 20 20 20  *pChangeset,    
19c10 20 20 20 20 20 2f 2a 20 49 6e 70 75 74 20 63 68       /* Input ch
19c20 61 6e 67 65 73 65 74 20 2a 2f 0a 20 20 69 6e 74  angeset */.  int
19c30 20 2a 70 6e 49 6e 76 65 72 74 65 64 2c 20 20 20   *pnInverted,   
19c40 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
19c50 4f 55 54 3a 20 4e 75 6d 62 65 72 20 6f 66 20 62  OUT: Number of b
19c60 79 74 65 73 20 69 6e 20 6f 75 74 70 75 74 20 63  ytes in output c
19c70 68 61 6e 67 65 73 65 74 20 2a 2f 0a 20 20 76 6f  hangeset */.  vo
19c80 69 64 20 2a 2a 70 70 49 6e 76 65 72 74 65 64 20  id **ppInverted 
19c90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
19ca0 20 4f 55 54 3a 20 49 6e 76 65 72 73 65 20 6f 66   OUT: Inverse of
19cb0 20 70 43 68 61 6e 67 65 73 65 74 20 2a 2f 0a 29   pChangeset */.)
19cc0 7b 0a 20 20 53 65 73 73 69 6f 6e 49 6e 70 75 74  {.  SessionInput
19cd0 20 73 49 6e 70 75 74 3b 0a 0a 20 20 2f 2a 20 53   sInput;..  /* S
19ce0 65 74 20 75 70 20 74 68 65 20 69 6e 70 75 74 20  et up the input 
19cf0 73 74 72 65 61 6d 20 2a 2f 0a 20 20 6d 65 6d 73  stream */.  mems
19d00 65 74 28 26 73 49 6e 70 75 74 2c 20 30 2c 20 73  et(&sInput, 0, s
19d10 69 7a 65 6f 66 28 53 65 73 73 69 6f 6e 49 6e 70  izeof(SessionInp
19d20 75 74 29 29 3b 0a 20 20 73 49 6e 70 75 74 2e 6e  ut));.  sInput.n
19d30 44 61 74 61 20 3d 20 6e 43 68 61 6e 67 65 73 65  Data = nChangese
19d40 74 3b 0a 20 20 73 49 6e 70 75 74 2e 61 44 61 74  t;.  sInput.aDat
19d50 61 20 3d 20 28 75 38 2a 29 70 43 68 61 6e 67 65  a = (u8*)pChange
19d60 73 65 74 3b 0a 0a 20 20 72 65 74 75 72 6e 20 73  set;..  return s
19d70 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65 74 49  essionChangesetI
19d80 6e 76 65 72 74 28 26 73 49 6e 70 75 74 2c 20 30  nvert(&sInput, 0
19d90 2c 20 30 2c 20 70 6e 49 6e 76 65 72 74 65 64 2c  , 0, pnInverted,
19da0 20 70 70 49 6e 76 65 72 74 65 64 29 3b 0a 7d 0a   ppInverted);.}.
19db0 0a 2f 2a 0a 2a 2a 20 53 74 72 65 61 6d 69 6e 67  ./*.** Streaming
19dc0 20 76 65 72 73 69 6f 6e 20 6f 66 20 73 71 6c 69   version of sqli
19dd0 74 65 33 63 68 61 6e 67 65 73 65 74 5f 69 6e 76  te3changeset_inv
19de0 65 72 74 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71  ert()..*/.int sq
19df0 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 69  lite3changeset_i
19e00 6e 76 65 72 74 5f 73 74 72 6d 28 0a 20 20 69 6e  nvert_strm(.  in
19e10 74 20 28 2a 78 49 6e 70 75 74 29 28 76 6f 69 64  t (*xInput)(void
19e20 20 2a 70 49 6e 2c 20 76 6f 69 64 20 2a 70 44 61   *pIn, void *pDa
19e30 74 61 2c 20 69 6e 74 20 2a 70 6e 44 61 74 61 29  ta, int *pnData)
19e40 2c 0a 20 20 76 6f 69 64 20 2a 70 49 6e 2c 0a 20  ,.  void *pIn,. 
19e50 20 69 6e 74 20 28 2a 78 4f 75 74 70 75 74 29 28   int (*xOutput)(
19e60 76 6f 69 64 20 2a 70 4f 75 74 2c 20 63 6f 6e 73  void *pOut, cons
19e70 74 20 76 6f 69 64 20 2a 70 44 61 74 61 2c 20 69  t void *pData, i
19e80 6e 74 20 6e 44 61 74 61 29 2c 0a 20 20 76 6f 69  nt nData),.  voi
19e90 64 20 2a 70 4f 75 74 0a 29 7b 0a 20 20 53 65 73  d *pOut.){.  Ses
19ea0 73 69 6f 6e 49 6e 70 75 74 20 73 49 6e 70 75 74  sionInput sInput
19eb0 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 2f  ;.  int rc;..  /
19ec0 2a 20 53 65 74 20 75 70 20 74 68 65 20 69 6e 70  * Set up the inp
19ed0 75 74 20 73 74 72 65 61 6d 20 2a 2f 0a 20 20 6d  ut stream */.  m
19ee0 65 6d 73 65 74 28 26 73 49 6e 70 75 74 2c 20 30  emset(&sInput, 0
19ef0 2c 20 73 69 7a 65 6f 66 28 53 65 73 73 69 6f 6e  , sizeof(Session
19f00 49 6e 70 75 74 29 29 3b 0a 20 20 73 49 6e 70 75  Input));.  sInpu
19f10 74 2e 78 49 6e 70 75 74 20 3d 20 78 49 6e 70 75  t.xInput = xInpu
19f20 74 3b 0a 20 20 73 49 6e 70 75 74 2e 70 49 6e 20  t;.  sInput.pIn 
19f30 3d 20 70 49 6e 3b 0a 0a 20 20 72 63 20 3d 20 73  = pIn;..  rc = s
19f40 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65 74 49  essionChangesetI
19f50 6e 76 65 72 74 28 26 73 49 6e 70 75 74 2c 20 78  nvert(&sInput, x
19f60 4f 75 74 70 75 74 2c 20 70 4f 75 74 2c 20 30 2c  Output, pOut, 0,
19f70 20 30 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66   0);.  sqlite3_f
19f80 72 65 65 28 73 49 6e 70 75 74 2e 62 75 66 2e 61  ree(sInput.buf.a
19f90 42 75 66 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  Buf);.  return r
19fa0 63 3b 0a 7d 0a 0a 74 79 70 65 64 65 66 20 73 74  c;.}..typedef st
19fb0 72 75 63 74 20 53 65 73 73 69 6f 6e 41 70 70 6c  ruct SessionAppl
19fc0 79 43 74 78 20 53 65 73 73 69 6f 6e 41 70 70 6c  yCtx SessionAppl
19fd0 79 43 74 78 3b 0a 73 74 72 75 63 74 20 53 65 73  yCtx;.struct Ses
19fe0 73 69 6f 6e 41 70 70 6c 79 43 74 78 20 7b 0a 20  sionApplyCtx {. 
19ff0 20 73 71 6c 69 74 65 33 20 2a 64 62 3b 0a 20 20   sqlite3 *db;.  
1a000 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 44  sqlite3_stmt *pD
1a010 65 6c 65 74 65 3b 20 20 20 20 20 20 20 20 20 20  elete;          
1a020 2f 2a 20 44 45 4c 45 54 45 20 73 74 61 74 65 6d  /* DELETE statem
1a030 65 6e 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ent */.  sqlite3
1a040 5f 73 74 6d 74 20 2a 70 55 70 64 61 74 65 3b 20  _stmt *pUpdate; 
1a050 20 20 20 20 20 20 20 20 20 2f 2a 20 55 50 44 41           /* UPDA
1a060 54 45 20 73 74 61 74 65 6d 65 6e 74 20 2a 2f 0a  TE statement */.
1a070 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
1a080 70 49 6e 73 65 72 74 3b 20 20 20 20 20 20 20 20  pInsert;        
1a090 20 20 2f 2a 20 49 4e 53 45 52 54 20 73 74 61 74    /* INSERT stat
1a0a0 65 6d 65 6e 74 20 2a 2f 0a 20 20 73 71 6c 69 74  ement */.  sqlit
1a0b0 65 33 5f 73 74 6d 74 20 2a 70 53 65 6c 65 63 74  e3_stmt *pSelect
1a0c0 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 45  ;          /* SE
1a0d0 4c 45 43 54 20 73 74 61 74 65 6d 65 6e 74 20 2a  LECT statement *
1a0e0 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 3b 20 20 20  /.  int nCol;   
1a0f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a100 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61      /* Size of a
1a110 7a 43 6f 6c 5b 5d 20 61 6e 64 20 61 62 50 4b 5b  zCol[] and abPK[
1a120 5d 20 61 72 72 61 79 73 20 2a 2f 0a 20 20 63 6f  ] arrays */.  co
1a130 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6c  nst char **azCol
1a140 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
1a150 20 41 72 72 61 79 20 6f 66 20 63 6f 6c 75 6d 6e   Array of column
1a160 20 6e 61 6d 65 73 20 2a 2f 0a 20 20 75 38 20 2a   names */.  u8 *
1a170 61 62 50 4b 3b 20 20 20 20 20 20 20 20 20 20 20  abPK;           
1a180 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
1a190 6f 6f 6c 65 61 6e 20 61 72 72 61 79 20 2d 20 74  oolean array - t
1a1a0 72 75 65 20 69 66 20 63 6f 6c 75 6d 6e 20 69 73  rue if column is
1a1b0 20 69 6e 20 50 4b 20 2a 2f 0a 0a 20 20 69 6e 74   in PK */..  int
1a1c0 20 62 44 65 66 65 72 43 6f 6e 73 74 72 61 69 6e   bDeferConstrain
1a1d0 74 73 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ts;          /* 
1a1e0 54 72 75 65 20 74 6f 20 64 65 66 65 72 20 63 6f  True to defer co
1a1f0 6e 73 74 72 61 69 6e 74 73 20 2a 2f 0a 20 20 53  nstraints */.  S
1a200 65 73 73 69 6f 6e 42 75 66 66 65 72 20 63 6f 6e  essionBuffer con
1a210 73 74 72 61 69 6e 74 73 3b 20 20 20 20 20 20 2f  straints;      /
1a220 2a 20 44 65 66 65 72 72 65 64 20 63 6f 6e 73 74  * Deferred const
1a230 72 61 69 6e 74 73 20 61 72 65 20 73 74 6f 72 65  raints are store
1a240 64 20 68 65 72 65 20 2a 2f 0a 7d 3b 0a 0a 2f 2a  d here */.};../*
1a250 0a 2a 2a 20 46 6f 72 6d 75 6c 61 74 65 20 61 20  .** Formulate a 
1a260 73 74 61 74 65 6d 65 6e 74 20 74 6f 20 44 45 4c  statement to DEL
1a270 45 54 45 20 61 20 72 6f 77 20 66 72 6f 6d 20 64  ETE a row from d
1a280 61 74 61 62 61 73 65 20 64 62 2e 20 41 73 73 75  atabase db. Assu
1a290 6d 69 6e 67 20 61 20 74 61 62 6c 65 0a 2a 2a 20  ming a table.** 
1a2a0 73 74 72 75 63 74 75 72 65 20 6c 69 6b 65 20 74  structure like t
1a2b0 68 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 43  his:.**.**     C
1a2c0 52 45 41 54 45 20 54 41 42 4c 45 20 78 28 61 2c  REATE TABLE x(a,
1a2d0 20 62 2c 20 63 2c 20 64 2c 20 50 52 49 4d 41 52   b, c, d, PRIMAR
1a2e0 59 20 4b 45 59 28 61 2c 20 63 29 29 3b 0a 2a 2a  Y KEY(a, c));.**
1a2f0 0a 2a 2a 20 54 68 65 20 44 45 4c 45 54 45 20 73  .** The DELETE s
1a300 74 61 74 65 6d 65 6e 74 20 6c 6f 6f 6b 73 20 6c  tatement looks l
1a310 69 6b 65 20 74 68 69 73 3a 0a 2a 2a 0a 2a 2a 20  ike this:.**.** 
1a320 20 20 20 20 44 45 4c 45 54 45 20 46 52 4f 4d 20      DELETE FROM 
1a330 78 20 57 48 45 52 45 20 61 20 3d 20 3a 31 20 41  x WHERE a = :1 A
1a340 4e 44 20 63 20 3d 20 3a 33 20 41 4e 44 20 28 3a  ND c = :3 AND (:
1a350 35 20 4f 52 20 62 20 49 53 20 3a 32 20 41 4e 44  5 OR b IS :2 AND
1a360 20 64 20 49 53 20 3a 34 29 0a 2a 2a 0a 2a 2a 20   d IS :4).**.** 
1a370 56 61 72 69 61 62 6c 65 20 3a 35 20 28 6e 43 6f  Variable :5 (nCo
1a380 6c 2b 31 29 20 69 73 20 61 20 62 6f 6f 6c 65 61  l+1) is a boolea
1a390 6e 2e 20 49 74 20 73 68 6f 75 6c 64 20 62 65 20  n. It should be 
1a3a0 73 65 74 20 74 6f 20 30 20 69 66 20 77 65 20 72  set to 0 if we r
1a3b0 65 71 75 69 72 65 0a 2a 2a 20 6d 61 74 63 68 69  equire.** matchi
1a3c0 6e 67 20 62 20 61 6e 64 20 64 20 76 61 6c 75 65  ng b and d value
1a3d0 73 2c 20 6f 72 20 31 20 6f 74 68 65 72 77 69 73  s, or 1 otherwis
1a3e0 65 2e 20 54 68 65 20 73 65 63 6f 6e 64 20 63 61  e. The second ca
1a3f0 73 65 20 63 6f 6d 65 73 20 75 70 20 69 66 20 74  se comes up if t
1a400 68 65 0a 2a 2a 20 63 6f 6e 66 6c 69 63 74 20 68  he.** conflict h
1a410 61 6e 64 6c 65 72 20 69 73 20 69 6e 76 6f 6b 65  andler is invoke
1a420 64 20 77 69 74 68 20 4e 4f 54 46 4f 55 4e 44 20  d with NOTFOUND 
1a430 61 6e 64 20 72 65 74 75 72 6e 73 20 43 48 41 4e  and returns CHAN
1a440 47 45 53 45 54 5f 52 45 50 4c 41 43 45 2e 0a 2a  GESET_REPLACE..*
1a450 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66  *.** If successf
1a460 75 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73  ul, SQLITE_OK is
1a470 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 53 65   returned and Se
1a480 73 73 69 6f 6e 41 70 70 6c 79 43 74 78 2e 70 44  ssionApplyCtx.pD
1a490 65 6c 65 74 65 20 69 73 20 6c 65 66 74 0a 2a 2a  elete is left.**
1a4a0 20 70 6f 69 6e 74 69 6e 67 20 74 6f 20 74 68 65   pointing to the
1a4b0 20 70 72 65 70 61 72 65 64 20 76 65 72 73 69 6f   prepared versio
1a4c0 6e 20 6f 66 20 74 68 65 20 53 51 4c 20 73 74 61  n of the SQL sta
1a4d0 74 65 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69  tement..*/.stati
1a4e0 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 44 65 6c  c int sessionDel
1a4f0 65 74 65 52 6f 77 28 0a 20 20 73 71 6c 69 74 65  eteRow(.  sqlite
1a500 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20  3 *db,          
1a510 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
1a520 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a  abase handle */.
1a530 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54    const char *zT
1a540 61 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ab,             
1a550 20 20 2f 2a 20 54 61 62 6c 65 20 6e 61 6d 65 20    /* Table name 
1a560 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 41 70 70 6c  */.  SessionAppl
1a570 79 43 74 78 20 2a 70 20 20 20 20 20 20 20 20 20  yCtx *p         
1a580 20 20 20 20 20 2f 2a 20 53 65 73 73 69 6f 6e 20       /* Session 
1a590 63 68 61 6e 67 65 73 65 74 2d 61 70 70 6c 79 20  changeset-apply 
1a5a0 63 6f 6e 74 65 78 74 20 2a 2f 0a 29 7b 0a 20 20  context */.){.  
1a5b0 69 6e 74 20 69 3b 0a 20 20 63 6f 6e 73 74 20 63  int i;.  const c
1a5c0 68 61 72 20 2a 7a 53 65 70 20 3d 20 22 22 3b 0a  har *zSep = "";.
1a5d0 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
1a5e0 45 5f 4f 4b 3b 0a 20 20 53 65 73 73 69 6f 6e 42  E_OK;.  SessionB
1a5f0 75 66 66 65 72 20 62 75 66 20 3d 20 7b 30 2c 20  uffer buf = {0, 
1a600 30 2c 20 30 7d 3b 0a 20 20 69 6e 74 20 6e 50 6b  0, 0};.  int nPk
1a610 20 3d 20 30 3b 0a 0a 20 20 73 65 73 73 69 6f 6e   = 0;..  session
1a620 41 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20  AppendStr(&buf, 
1a630 22 44 45 4c 45 54 45 20 46 52 4f 4d 20 22 2c 20  "DELETE FROM ", 
1a640 26 72 63 29 3b 0a 20 20 73 65 73 73 69 6f 6e 41  &rc);.  sessionA
1a650 70 70 65 6e 64 49 64 65 6e 74 28 26 62 75 66 2c  ppendIdent(&buf,
1a660 20 7a 54 61 62 2c 20 26 72 63 29 3b 0a 20 20 73   zTab, &rc);.  s
1a670 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28  essionAppendStr(
1a680 26 62 75 66 2c 20 22 20 57 48 45 52 45 20 22 2c  &buf, " WHERE ",
1a690 20 26 72 63 29 3b 0a 0a 20 20 66 6f 72 28 69 3d   &rc);..  for(i=
1a6a0 30 3b 20 69 3c 70 2d 3e 6e 43 6f 6c 3b 20 69 2b  0; i<p->nCol; i+
1a6b0 2b 29 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e 61  +){.    if( p->a
1a6c0 62 50 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20  bPK[i] ){.      
1a6d0 6e 50 6b 2b 2b 3b 0a 20 20 20 20 20 20 73 65 73  nPk++;.      ses
1a6e0 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62  sionAppendStr(&b
1a6f0 75 66 2c 20 7a 53 65 70 2c 20 26 72 63 29 3b 0a  uf, zSep, &rc);.
1a700 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70        sessionApp
1a710 65 6e 64 49 64 65 6e 74 28 26 62 75 66 2c 20 70  endIdent(&buf, p
1a720 2d 3e 61 7a 43 6f 6c 5b 69 5d 2c 20 26 72 63 29  ->azCol[i], &rc)
1a730 3b 0a 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41  ;.      sessionA
1a740 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22  ppendStr(&buf, "
1a750 20 3d 20 3f 22 2c 20 26 72 63 29 3b 0a 20 20 20   = ?", &rc);.   
1a760 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
1a770 49 6e 74 65 67 65 72 28 26 62 75 66 2c 20 69 2b  Integer(&buf, i+
1a780 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 7a  1, &rc);.      z
1a790 53 65 70 20 3d 20 22 20 41 4e 44 20 22 3b 0a 20  Sep = " AND ";. 
1a7a0 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20     }.  }..  if( 
1a7b0 6e 50 6b 3c 70 2d 3e 6e 43 6f 6c 20 29 7b 0a 20  nPk<p->nCol ){. 
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 41 4e 44 20  Str(&buf, " AND 
1a7e0 28 3f 22 2c 20 26 72 63 29 3b 0a 20 20 20 20 73  (?", &rc);.    s
1a7f0 65 73 73 69 6f 6e 41 70 70 65 6e 64 49 6e 74 65  essionAppendInte
1a800 67 65 72 28 26 62 75 66 2c 20 70 2d 3e 6e 43 6f  ger(&buf, p->nCo
1a810 6c 2b 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 73  l+1, &rc);.    s
1a820 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28  essionAppendStr(
1a830 26 62 75 66 2c 20 22 20 4f 52 20 22 2c 20 26 72  &buf, " OR ", &r
1a840 63 29 3b 0a 0a 20 20 20 20 7a 53 65 70 20 3d 20  c);..    zSep = 
1a850 22 22 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b  "";.    for(i=0;
1a860 20 69 3c 70 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29   i<p->nCol; i++)
1a870 7b 0a 20 20 20 20 20 20 69 66 28 20 21 70 2d 3e  {.      if( !p->
1a880 61 62 50 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20  abPK[i] ){.     
1a890 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
1a8a0 53 74 72 28 26 62 75 66 2c 20 7a 53 65 70 2c 20  Str(&buf, zSep, 
1a8b0 26 72 63 29 3b 0a 20 20 20 20 20 20 20 20 73 65  &rc);.        se
1a8c0 73 73 69 6f 6e 41 70 70 65 6e 64 49 64 65 6e 74  ssionAppendIdent
1a8d0 28 26 62 75 66 2c 20 70 2d 3e 61 7a 43 6f 6c 5b  (&buf, p->azCol[
1a8e0 69 5d 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20  i], &rc);.      
1a8f0 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53    sessionAppendS
1a900 74 72 28 26 62 75 66 2c 20 22 20 49 53 20 3f 22  tr(&buf, " IS ?"
1a910 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20 20  , &rc);.        
1a920 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49 6e 74  sessionAppendInt
1a930 65 67 65 72 28 26 62 75 66 2c 20 69 2b 31 2c 20  eger(&buf, i+1, 
1a940 26 72 63 29 3b 0a 20 20 20 20 20 20 20 20 7a 53  &rc);.        zS
1a950 65 70 20 3d 20 22 41 4e 44 20 22 3b 0a 20 20 20  ep = "AND ";.   
1a960 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 73     }.    }.    s
1a970 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28  essionAppendStr(
1a980 26 62 75 66 2c 20 22 29 22 2c 20 26 72 63 29 3b  &buf, ")", &rc);
1a990 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
1a9a0 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
1a9b0 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72   rc = sqlite3_pr
1a9c0 65 70 61 72 65 5f 76 32 28 64 62 2c 20 28 63 68  epare_v2(db, (ch
1a9d0 61 72 20 2a 29 62 75 66 2e 61 42 75 66 2c 20 62  ar *)buf.aBuf, b
1a9e0 75 66 2e 6e 42 75 66 2c 20 26 70 2d 3e 70 44 65  uf.nBuf, &p->pDe
1a9f0 6c 65 74 65 2c 20 30 29 3b 0a 20 20 7d 0a 20 20  lete, 0);.  }.  
1aa00 73 71 6c 69 74 65 33 5f 66 72 65 65 28 62 75 66  sqlite3_free(buf
1aa10 2e 61 42 75 66 29 3b 0a 0a 20 20 72 65 74 75 72  .aBuf);..  retur
1aa20 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46  n rc;.}../*.** F
1aa30 6f 72 6d 75 6c 61 74 65 20 61 6e 64 20 70 72 65  ormulate and pre
1aa40 70 61 72 65 20 61 20 73 74 61 74 65 6d 65 6e 74  pare a statement
1aa50 20 74 6f 20 55 50 44 41 54 45 20 61 20 72 6f 77   to UPDATE a row
1aa60 20 66 72 6f 6d 20 64 61 74 61 62 61 73 65 20 64   from database d
1aa70 62 2e 20 0a 2a 2a 20 41 73 73 75 6d 69 6e 67 20  b. .** Assuming 
1aa80 61 20 74 61 62 6c 65 20 73 74 72 75 63 74 75 72  a table structur
1aa90 65 20 6c 69 6b 65 20 74 68 69 73 3a 0a 2a 2a 0a  e like this:.**.
1aaa0 2a 2a 20 20 20 20 20 43 52 45 41 54 45 20 54 41  **     CREATE TA
1aab0 42 4c 45 20 78 28 61 2c 20 62 2c 20 63 2c 20 64  BLE x(a, b, c, d
1aac0 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 61 2c  , PRIMARY KEY(a,
1aad0 20 63 29 29 3b 0a 2a 2a 0a 2a 2a 20 54 68 65 20   c));.**.** The 
1aae0 55 50 44 41 54 45 20 73 74 61 74 65 6d 65 6e 74  UPDATE statement
1aaf0 20 6c 6f 6f 6b 73 20 6c 69 6b 65 20 74 68 69 73   looks like this
1ab00 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 55 50 44 41  :.**.**     UPDA
1ab10 54 45 20 78 20 53 45 54 0a 2a 2a 20 20 20 20 20  TE x SET.**     
1ab20 61 20 3d 20 43 41 53 45 20 57 48 45 4e 20 3f 32  a = CASE WHEN ?2
1ab30 20 20 54 48 45 4e 20 3f 33 20 20 45 4c 53 45 20    THEN ?3  ELSE 
1ab40 61 20 45 4e 44 2c 0a 2a 2a 20 20 20 20 20 62 20  a END,.**     b 
1ab50 3d 20 43 41 53 45 20 57 48 45 4e 20 3f 35 20 20  = CASE WHEN ?5  
1ab60 54 48 45 4e 20 3f 36 20 20 45 4c 53 45 20 62 20  THEN ?6  ELSE b 
1ab70 45 4e 44 2c 0a 2a 2a 20 20 20 20 20 63 20 3d 20  END,.**     c = 
1ab80 43 41 53 45 20 57 48 45 4e 20 3f 38 20 20 54 48  CASE WHEN ?8  TH
1ab90 45 4e 20 3f 39 20 20 45 4c 53 45 20 63 20 45 4e  EN ?9  ELSE c EN
1aba0 44 2c 0a 2a 2a 20 20 20 20 20 64 20 3d 20 43 41  D,.**     d = CA
1abb0 53 45 20 57 48 45 4e 20 3f 31 31 20 54 48 45 4e  SE WHEN ?11 THEN
1abc0 20 3f 31 32 20 45 4c 53 45 20 64 20 45 4e 44 0a   ?12 ELSE d END.
1abd0 2a 2a 20 20 20 20 20 57 48 45 52 45 20 61 20 3d  **     WHERE a =
1abe0 20 3f 31 20 41 4e 44 20 63 20 3d 20 3f 37 20 41   ?1 AND c = ?7 A
1abf0 4e 44 20 28 3f 31 33 20 4f 52 20 0a 2a 2a 20 20  ND (?13 OR .**  
1ac00 20 20 20 20 20 28 3f 35 3d 3d 30 20 4f 52 20 62       (?5==0 OR b
1ac10 20 49 53 20 3f 34 29 20 41 4e 44 20 28 3f 31 31   IS ?4) AND (?11
1ac20 3d 3d 30 20 4f 52 20 64 20 49 53 20 3f 31 30 29  ==0 OR d IS ?10)
1ac30 20 41 4e 44 0a 2a 2a 20 20 20 20 20 29 0a 2a 2a   AND.**     ).**
1ac40 0a 2a 2a 20 46 6f 72 20 65 61 63 68 20 63 6f 6c  .** For each col
1ac50 75 6d 6e 20 69 6e 20 74 68 65 20 74 61 62 6c 65  umn in the table
1ac60 2c 20 74 68 65 72 65 20 61 72 65 20 74 68 72 65  , there are thre
1ac70 65 20 76 61 72 69 61 62 6c 65 73 20 74 6f 20 62  e variables to b
1ac80 69 6e 64 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 3f  ind:.**.**     ?
1ac90 28 69 2a 33 2b 31 29 20 20 20 20 54 68 65 20 6f  (i*3+1)    The o
1aca0 6c 64 2e 2a 20 76 61 6c 75 65 20 6f 66 20 74 68  ld.* value of th
1acb0 65 20 63 6f 6c 75 6d 6e 2c 20 69 66 20 61 6e 79  e column, if any
1acc0 2e 0a 2a 2a 20 20 20 20 20 3f 28 69 2a 33 2b 32  ..**     ?(i*3+2
1acd0 29 20 20 20 20 41 20 62 6f 6f 6c 65 61 6e 20 66  )    A boolean f
1ace0 6c 61 67 20 69 6e 64 69 63 61 74 69 6e 67 20 74  lag indicating t
1acf0 68 61 74 20 74 68 65 20 76 61 6c 75 65 20 69 73  hat the value is
1ad00 20 62 65 69 6e 67 20 6d 6f 64 69 66 69 65 64 2e   being modified.
1ad10 0a 2a 2a 20 20 20 20 20 3f 28 69 2a 33 2b 33 29  .**     ?(i*3+3)
1ad20 20 20 20 20 54 68 65 20 6e 65 77 2e 2a 20 76 61      The new.* va
1ad30 6c 75 65 20 6f 66 20 74 68 65 20 63 6f 6c 75 6d  lue of the colum
1ad40 6e 2c 20 69 66 20 61 6e 79 2e 0a 2a 2a 0a 2a 2a  n, if any..**.**
1ad50 20 41 6c 73 6f 2c 20 61 20 62 6f 6f 6c 65 61 6e   Also, a boolean
1ad60 20 66 6c 61 67 20 74 68 61 74 2c 20 69 66 20 73   flag that, if s
1ad70 65 74 20 74 6f 20 74 72 75 65 2c 20 63 61 75 73  et to true, caus
1ad80 65 73 20 74 68 65 20 73 74 61 74 65 6d 65 6e 74  es the statement
1ad90 20 74 6f 20 75 70 64 61 74 65 0a 2a 2a 20 61 20   to update.** a 
1ada0 72 6f 77 20 65 76 65 6e 20 69 66 20 74 68 65 20  row even if the 
1adb0 6e 6f 6e 2d 50 4b 20 76 61 6c 75 65 73 20 64 6f  non-PK values do
1adc0 20 6e 6f 74 20 6d 61 74 63 68 2e 20 54 68 69 73   not match. This
1add0 20 69 73 20 72 65 71 75 69 72 65 64 20 69 66 20   is required if 
1ade0 74 68 65 0a 2a 2a 20 63 6f 6e 66 6c 69 63 74 2d  the.** conflict-
1adf0 68 61 6e 64 6c 65 72 20 69 73 20 69 6e 76 6f 6b  handler is invok
1ae00 65 64 20 77 69 74 68 20 43 48 41 4e 47 45 53 45  ed with CHANGESE
1ae10 54 5f 44 41 54 41 20 61 6e 64 20 72 65 74 75 72  T_DATA and retur
1ae20 6e 73 0a 2a 2a 20 43 48 41 4e 47 45 53 45 54 5f  ns.** CHANGESET_
1ae30 52 45 50 4c 41 43 45 2e 20 54 68 69 73 20 69 73  REPLACE. This is
1ae40 20 76 61 72 69 61 62 6c 65 20 22 3f 28 6e 43 6f   variable "?(nCo
1ae50 6c 2a 33 2b 31 29 22 2e 0a 2a 2a 0a 2a 2a 20 49  l*3+1)"..**.** I
1ae60 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 53 51  f successful, SQ
1ae70 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72  LITE_OK is retur
1ae80 6e 65 64 20 61 6e 64 20 53 65 73 73 69 6f 6e 41  ned and SessionA
1ae90 70 70 6c 79 43 74 78 2e 70 55 70 64 61 74 65 20  pplyCtx.pUpdate 
1aea0 69 73 20 6c 65 66 74 0a 2a 2a 20 70 6f 69 6e 74  is left.** point
1aeb0 69 6e 67 20 74 6f 20 74 68 65 20 70 72 65 70 61  ing to the prepa
1aec0 72 65 64 20 76 65 72 73 69 6f 6e 20 6f 66 20 74  red version of t
1aed0 68 65 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74  he SQL statement
1aee0 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
1aef0 73 65 73 73 69 6f 6e 55 70 64 61 74 65 52 6f 77  sessionUpdateRow
1af00 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
1af10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1af20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
1af30 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73  handle */.  cons
1af40 74 20 63 68 61 72 20 2a 7a 54 61 62 2c 20 20 20  t char *zTab,   
1af50 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
1af60 61 62 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 53  able name */.  S
1af70 65 73 73 69 6f 6e 41 70 70 6c 79 43 74 78 20 2a  essionApplyCtx *
1af80 70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  p              /
1af90 2a 20 53 65 73 73 69 6f 6e 20 63 68 61 6e 67 65  * Session change
1afa0 73 65 74 2d 61 70 70 6c 79 20 63 6f 6e 74 65 78  set-apply contex
1afb0 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63  t */.){.  int rc
1afc0 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
1afd0 69 6e 74 20 69 3b 0a 20 20 63 6f 6e 73 74 20 63  int i;.  const c
1afe0 68 61 72 20 2a 7a 53 65 70 20 3d 20 22 22 3b 0a  har *zSep = "";.
1aff0 20 20 53 65 73 73 69 6f 6e 42 75 66 66 65 72 20    SessionBuffer 
1b000 62 75 66 20 3d 20 7b 30 2c 20 30 2c 20 30 7d 3b  buf = {0, 0, 0};
1b010 0a 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20 22 55  ..  /* Append "U
1b020 50 44 41 54 45 20 74 62 6c 20 53 45 54 20 22 20  PDATE tbl SET " 
1b030 2a 2f 0a 20 20 73 65 73 73 69 6f 6e 41 70 70 65  */.  sessionAppe
1b040 6e 64 53 74 72 28 26 62 75 66 2c 20 22 55 50 44  ndStr(&buf, "UPD
1b050 41 54 45 20 22 2c 20 26 72 63 29 3b 0a 20 20 73  ATE ", &rc);.  s
1b060 65 73 73 69 6f 6e 41 70 70 65 6e 64 49 64 65 6e  essionAppendIden
1b070 74 28 26 62 75 66 2c 20 7a 54 61 62 2c 20 26 72  t(&buf, zTab, &r
1b080 63 29 3b 0a 20 20 73 65 73 73 69 6f 6e 41 70 70  c);.  sessionApp
1b090 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 20 53  endStr(&buf, " S
1b0a0 45 54 20 22 2c 20 26 72 63 29 3b 0a 0a 20 20 2f  ET ", &rc);..  /
1b0b0 2a 20 41 70 70 65 6e 64 20 74 68 65 20 61 73 73  * Append the ass
1b0c0 69 67 6e 6d 65 6e 74 73 20 2a 2f 0a 20 20 66 6f  ignments */.  fo
1b0d0 72 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 43 6f 6c  r(i=0; i<p->nCol
1b0e0 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 73 65 73 73  ; i++){.    sess
1b0f0 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75  ionAppendStr(&bu
1b100 66 2c 20 7a 53 65 70 2c 20 26 72 63 29 3b 0a 20  f, zSep, &rc);. 
1b110 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
1b120 49 64 65 6e 74 28 26 62 75 66 2c 20 70 2d 3e 61  Ident(&buf, p->a
1b130 7a 43 6f 6c 5b 69 5d 2c 20 26 72 63 29 3b 0a 20  zCol[i], &rc);. 
1b140 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
1b150 53 74 72 28 26 62 75 66 2c 20 22 20 3d 20 43 41  Str(&buf, " = CA
1b160 53 45 20 57 48 45 4e 20 3f 22 2c 20 26 72 63 29  SE WHEN ?", &rc)
1b170 3b 0a 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70  ;.    sessionApp
1b180 65 6e 64 49 6e 74 65 67 65 72 28 26 62 75 66 2c  endInteger(&buf,
1b190 20 69 2a 33 2b 32 2c 20 26 72 63 29 3b 0a 20 20   i*3+2, &rc);.  
1b1a0 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53    sessionAppendS
1b1b0 74 72 28 26 62 75 66 2c 20 22 20 54 48 45 4e 20  tr(&buf, " THEN 
1b1c0 3f 22 2c 20 26 72 63 29 3b 0a 20 20 20 20 73 65  ?", &rc);.    se
1b1d0 73 73 69 6f 6e 41 70 70 65 6e 64 49 6e 74 65 67  ssionAppendInteg
1b1e0 65 72 28 26 62 75 66 2c 20 69 2a 33 2b 33 2c 20  er(&buf, i*3+3, 
1b1f0 26 72 63 29 3b 0a 20 20 20 20 73 65 73 73 69 6f  &rc);.    sessio
1b200 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c  nAppendStr(&buf,
1b210 20 22 20 45 4c 53 45 20 22 2c 20 26 72 63 29 3b   " ELSE ", &rc);
1b220 0a 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65  .    sessionAppe
1b230 6e 64 49 64 65 6e 74 28 26 62 75 66 2c 20 70 2d  ndIdent(&buf, p-
1b240 3e 61 7a 43 6f 6c 5b 69 5d 2c 20 26 72 63 29 3b  >azCol[i], &rc);
1b250 0a 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65  .    sessionAppe
1b260 6e 64 53 74 72 28 26 62 75 66 2c 20 22 20 45 4e  ndStr(&buf, " EN
1b270 44 22 2c 20 26 72 63 29 3b 0a 20 20 20 20 7a 53  D", &rc);.    zS
1b280 65 70 20 3d 20 22 2c 20 22 3b 0a 20 20 7d 0a 0a  ep = ", ";.  }..
1b290 20 20 2f 2a 20 41 70 70 65 6e 64 20 74 68 65 20    /* Append the 
1b2a0 50 4b 20 70 61 72 74 20 6f 66 20 74 68 65 20 57  PK part of the W
1b2b0 48 45 52 45 20 63 6c 61 75 73 65 20 2a 2f 0a 20  HERE clause */. 
1b2c0 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74   sessionAppendSt
1b2d0 72 28 26 62 75 66 2c 20 22 20 57 48 45 52 45 20  r(&buf, " WHERE 
1b2e0 22 2c 20 26 72 63 29 3b 0a 20 20 66 6f 72 28 69  ", &rc);.  for(i
1b2f0 3d 30 3b 20 69 3c 70 2d 3e 6e 43 6f 6c 3b 20 69  =0; i<p->nCol; i
1b300 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e  ++){.    if( p->
1b310 61 62 50 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20  abPK[i] ){.     
1b320 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49 64   sessionAppendId
1b330 65 6e 74 28 26 62 75 66 2c 20 70 2d 3e 61 7a 43  ent(&buf, p->azC
1b340 6f 6c 5b 69 5d 2c 20 26 72 63 29 3b 0a 20 20 20  ol[i], &rc);.   
1b350 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
1b360 53 74 72 28 26 62 75 66 2c 20 22 20 3d 20 3f 22  Str(&buf, " = ?"
1b370 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 73 65  , &rc);.      se
1b380 73 73 69 6f 6e 41 70 70 65 6e 64 49 6e 74 65 67  ssionAppendInteg
1b390 65 72 28 26 62 75 66 2c 20 69 2a 33 2b 31 2c 20  er(&buf, i*3+1, 
1b3a0 26 72 63 29 3b 0a 20 20 20 20 20 20 73 65 73 73  &rc);.      sess
1b3b0 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75  ionAppendStr(&bu
1b3c0 66 2c 20 22 20 41 4e 44 20 22 2c 20 26 72 63 29  f, " AND ", &rc)
1b3d0 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f  ;.    }.  }..  /
1b3e0 2a 20 41 70 70 65 6e 64 20 74 68 65 20 6e 6f 6e  * Append the non
1b3f0 2d 50 4b 20 70 61 72 74 20 6f 66 20 74 68 65 20  -PK part of the 
1b400 57 48 45 52 45 20 63 6c 61 75 73 65 20 2a 2f 0a  WHERE clause */.
1b410 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53    sessionAppendS
1b420 74 72 28 26 62 75 66 2c 20 22 20 28 3f 22 2c 20  tr(&buf, " (?", 
1b430 26 72 63 29 3b 0a 20 20 73 65 73 73 69 6f 6e 41  &rc);.  sessionA
1b440 70 70 65 6e 64 49 6e 74 65 67 65 72 28 26 62 75  ppendInteger(&bu
1b450 66 2c 20 70 2d 3e 6e 43 6f 6c 2a 33 2b 31 2c 20  f, p->nCol*3+1, 
1b460 26 72 63 29 3b 0a 20 20 73 65 73 73 69 6f 6e 41  &rc);.  sessionA
1b470 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22  ppendStr(&buf, "
1b480 20 4f 52 20 31 22 2c 20 26 72 63 29 3b 0a 20 20   OR 1", &rc);.  
1b490 66 6f 72 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 43  for(i=0; i<p->nC
1b4a0 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66  ol; i++){.    if
1b4b0 28 20 21 70 2d 3e 61 62 50 4b 5b 69 5d 20 29 7b  ( !p->abPK[i] ){
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 20  pendStr(&buf, " 
1b4e0 41 4e 44 20 28 3f 22 2c 20 26 72 63 29 3b 0a 20  AND (?", &rc);. 
1b4f0 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65       sessionAppe
1b500 6e 64 49 6e 74 65 67 65 72 28 26 62 75 66 2c 20  ndInteger(&buf, 
1b510 69 2a 33 2b 32 2c 20 26 72 63 29 3b 0a 20 20 20  i*3+2, &rc);.   
1b520 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
1b530 53 74 72 28 26 62 75 66 2c 20 22 3d 30 20 4f 52  Str(&buf, "=0 OR
1b540 20 22 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20   ", &rc);.      
1b550 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49 64 65  sessionAppendIde
1b560 6e 74 28 26 62 75 66 2c 20 70 2d 3e 61 7a 43 6f  nt(&buf, p->azCo
1b570 6c 5b 69 5d 2c 20 26 72 63 29 3b 0a 20 20 20 20  l[i], &rc);.    
1b580 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53    sessionAppendS
1b590 74 72 28 26 62 75 66 2c 20 22 20 49 53 20 3f 22  tr(&buf, " IS ?"
1b5a0 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 73 65  , &rc);.      se
1b5b0 73 73 69 6f 6e 41 70 70 65 6e 64 49 6e 74 65 67  ssionAppendInteg
1b5c0 65 72 28 26 62 75 66 2c 20 69 2a 33 2b 31 2c 20  er(&buf, i*3+1, 
1b5d0 26 72 63 29 3b 0a 20 20 20 20 20 20 73 65 73 73  &rc);.      sess
1b5e0 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75  ionAppendStr(&bu
1b5f0 66 2c 20 22 29 22 2c 20 26 72 63 29 3b 0a 20 20  f, ")", &rc);.  
1b600 20 20 7d 0a 20 20 7d 0a 20 20 73 65 73 73 69 6f    }.  }.  sessio
1b610 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c  nAppendStr(&buf,
1b620 20 22 29 22 2c 20 26 72 63 29 3b 0a 0a 20 20 69   ")", &rc);..  i
1b630 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
1b640 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   ){.    rc = sql
1b650 69 74 65 33 5f 70 72 65 70 61 72 65 5f 76 32 28  ite3_prepare_v2(
1b660 64 62 2c 20 28 63 68 61 72 20 2a 29 62 75 66 2e  db, (char *)buf.
1b670 61 42 75 66 2c 20 62 75 66 2e 6e 42 75 66 2c 20  aBuf, buf.nBuf, 
1b680 26 70 2d 3e 70 55 70 64 61 74 65 2c 20 30 29 3b  &p->pUpdate, 0);
1b690 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66  .  }.  sqlite3_f
1b6a0 72 65 65 28 62 75 66 2e 61 42 75 66 29 3b 0a 0a  ree(buf.aBuf);..
1b6b0 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
1b6c0 2f 2a 0a 2a 2a 20 46 6f 72 6d 75 6c 61 74 65 20  /*.** Formulate 
1b6d0 61 6e 64 20 70 72 65 70 61 72 65 20 61 6e 20 53  and prepare an S
1b6e0 51 4c 20 73 74 61 74 65 6d 65 6e 74 20 74 6f 20  QL statement to 
1b6f0 71 75 65 72 79 20 74 61 62 6c 65 20 7a 54 61 62  query table zTab
1b700 20 62 79 20 70 72 69 6d 61 72 79 0a 2a 2a 20 6b   by primary.** k
1b710 65 79 2e 20 41 73 73 75 6d 69 6e 67 20 74 68 65  ey. Assuming the
1b720 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 61 62 6c 65   following table
1b730 20 73 74 72 75 63 74 75 72 65 3a 0a 2a 2a 0a 2a   structure:.**.*
1b740 2a 20 20 20 20 20 43 52 45 41 54 45 20 54 41 42  *     CREATE TAB
1b750 4c 45 20 78 28 61 2c 20 62 2c 20 63 2c 20 64 2c  LE x(a, b, c, d,
1b760 20 50 52 49 4d 41 52 59 20 4b 45 59 28 61 2c 20   PRIMARY KEY(a, 
1b770 63 29 29 3b 0a 2a 2a 0a 2a 2a 20 54 68 65 20 53  c));.**.** The S
1b780 45 4c 45 43 54 20 73 74 61 74 65 6d 65 6e 74 20  ELECT statement 
1b790 6c 6f 6f 6b 73 20 6c 69 6b 65 20 74 68 69 73 3a  looks like this:
1b7a0 0a 2a 2a 0a 2a 2a 20 20 20 20 20 53 45 4c 45 43  .**.**     SELEC
1b7b0 54 20 2a 20 46 52 4f 4d 20 78 20 57 48 45 52 45  T * FROM x WHERE
1b7c0 20 61 20 3d 20 3f 31 20 41 4e 44 20 63 20 3d 20   a = ?1 AND c = 
1b7d0 3f 33 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63  ?3.**.** If succ
1b7e0 65 73 73 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f  essful, SQLITE_O
1b7f0 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e  K is returned an
1b800 64 20 53 65 73 73 69 6f 6e 41 70 70 6c 79 43 74  d SessionApplyCt
1b810 78 2e 70 53 65 6c 65 63 74 20 69 73 20 6c 65 66  x.pSelect is lef
1b820 74 0a 2a 2a 20 70 6f 69 6e 74 69 6e 67 20 74 6f  t.** pointing to
1b830 20 74 68 65 20 70 72 65 70 61 72 65 64 20 76 65   the prepared ve
1b840 72 73 69 6f 6e 20 6f 66 20 74 68 65 20 53 51 4c  rsion of the SQL
1b850 20 73 74 61 74 65 6d 65 6e 74 2e 0a 2a 2f 0a 73   statement..*/.s
1b860 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f  tatic int sessio
1b870 6e 53 65 6c 65 63 74 52 6f 77 28 0a 20 20 73 71  nSelectRow(.  sq
1b880 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20  lite3 *db,      
1b890 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1b8a0 20 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65   Database handle
1b8b0 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
1b8c0 20 2a 7a 54 61 62 2c 20 20 20 20 20 20 20 20 20   *zTab,         
1b8d0 20 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20 6e        /* Table n
1b8e0 61 6d 65 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e  ame */.  Session
1b8f0 41 70 70 6c 79 43 74 78 20 2a 70 20 20 20 20 20  ApplyCtx *p     
1b900 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 73 73           /* Sess
1b910 69 6f 6e 20 63 68 61 6e 67 65 73 65 74 2d 61 70  ion changeset-ap
1b920 70 6c 79 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 29  ply context */.)
1b930 7b 0a 20 20 72 65 74 75 72 6e 20 73 65 73 73 69  {.  return sessi
1b940 6f 6e 53 65 6c 65 63 74 53 74 6d 74 28 0a 20 20  onSelectStmt(.  
1b950 20 20 20 20 64 62 2c 20 22 6d 61 69 6e 22 2c 20      db, "main", 
1b960 7a 54 61 62 2c 20 70 2d 3e 6e 43 6f 6c 2c 20 70  zTab, p->nCol, p
1b970 2d 3e 61 7a 43 6f 6c 2c 20 70 2d 3e 61 62 50 4b  ->azCol, p->abPK
1b980 2c 20 26 70 2d 3e 70 53 65 6c 65 63 74 29 3b 0a  , &p->pSelect);.
1b990 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6f 72 6d 75 6c 61  }../*.** Formula
1b9a0 74 65 20 61 6e 64 20 70 72 65 70 61 72 65 20 61  te and prepare a
1b9b0 6e 20 49 4e 53 45 52 54 20 73 74 61 74 65 6d 65  n INSERT stateme
1b9c0 6e 74 20 74 6f 20 61 64 64 20 61 20 72 65 63 6f  nt to add a reco
1b9d0 72 64 20 74 6f 20 74 61 62 6c 65 20 7a 54 61 62  rd to table zTab
1b9e0 2e 0a 2a 2a 20 46 6f 72 20 65 78 61 6d 70 6c 65  ..** For example
1b9f0 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 49 4e 53 45  :.**.**     INSE
1ba00 52 54 20 49 4e 54 4f 20 6d 61 69 6e 2e 22 7a 54  RT INTO main."zT
1ba10 61 62 22 20 56 41 4c 55 45 53 28 3f 31 2c 20 3f  ab" VALUES(?1, ?
1ba20 32 2c 20 3f 33 20 2e 2e 2e 29 3b 0a 2a 2a 0a 2a  2, ?3 ...);.**.*
1ba30 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c  * If successful,
1ba40 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65   SQLITE_OK is re
1ba50 74 75 72 6e 65 64 20 61 6e 64 20 53 65 73 73 69  turned and Sessi
1ba60 6f 6e 41 70 70 6c 79 43 74 78 2e 70 49 6e 73 65  onApplyCtx.pInse
1ba70 72 74 20 69 73 20 6c 65 66 74 0a 2a 2a 20 70 6f  rt is left.** po
1ba80 69 6e 74 69 6e 67 20 74 6f 20 74 68 65 20 70 72  inting to the pr
1ba90 65 70 61 72 65 64 20 76 65 72 73 69 6f 6e 20 6f  epared version o
1baa0 66 20 74 68 65 20 53 51 4c 20 73 74 61 74 65 6d  f the SQL statem
1bab0 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ent..*/.static i
1bac0 6e 74 20 73 65 73 73 69 6f 6e 49 6e 73 65 72 74  nt sessionInsert
1bad0 52 6f 77 28 0a 20 20 73 71 6c 69 74 65 33 20 2a  Row(.  sqlite3 *
1bae0 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  db,             
1baf0 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61         /* Databa
1bb00 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 63  se handle */.  c
1bb10 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 62 2c  onst char *zTab,
1bb20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1bb30 2a 20 54 61 62 6c 65 20 6e 61 6d 65 20 2a 2f 0a  * Table name */.
1bb40 20 20 53 65 73 73 69 6f 6e 41 70 70 6c 79 43 74    SessionApplyCt
1bb50 78 20 2a 70 20 20 20 20 20 20 20 20 20 20 20 20  x *p            
1bb60 20 20 2f 2a 20 53 65 73 73 69 6f 6e 20 63 68 61    /* Session cha
1bb70 6e 67 65 73 65 74 2d 61 70 70 6c 79 20 63 6f 6e  ngeset-apply con
1bb80 74 65 78 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  text */.){.  int
1bb90 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
1bba0 0a 20 20 69 6e 74 20 69 3b 0a 20 20 53 65 73 73  .  int i;.  Sess
1bbb0 69 6f 6e 42 75 66 66 65 72 20 62 75 66 20 3d 20  ionBuffer buf = 
1bbc0 7b 30 2c 20 30 2c 20 30 7d 3b 0a 0a 20 20 73 65  {0, 0, 0};..  se
1bbd0 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26  ssionAppendStr(&
1bbe0 62 75 66 2c 20 22 49 4e 53 45 52 54 20 49 4e 54  buf, "INSERT INT
1bbf0 4f 20 6d 61 69 6e 2e 22 2c 20 26 72 63 29 3b 0a  O main.", &rc);.
1bc00 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49    sessionAppendI
1bc10 64 65 6e 74 28 26 62 75 66 2c 20 7a 54 61 62 2c  dent(&buf, zTab,
1bc20 20 26 72 63 29 3b 0a 20 20 73 65 73 73 69 6f 6e   &rc);.  session
1bc30 41 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20  AppendStr(&buf, 
1bc40 22 20 56 41 4c 55 45 53 28 3f 22 2c 20 26 72 63  " VALUES(?", &rc
1bc50 29 3b 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c  );.  for(i=1; i<
1bc60 70 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20  p->nCol; i++){. 
1bc70 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
1bc80 53 74 72 28 26 62 75 66 2c 20 22 2c 20 3f 22 2c  Str(&buf, ", ?",
1bc90 20 26 72 63 29 3b 0a 20 20 7d 0a 20 20 73 65 73   &rc);.  }.  ses
1bca0 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62  sionAppendStr(&b
1bcb0 75 66 2c 20 22 29 22 2c 20 26 72 63 29 3b 0a 0a  uf, ")", &rc);..
1bcc0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
1bcd0 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
1bce0 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 5f  sqlite3_prepare_
1bcf0 76 32 28 64 62 2c 20 28 63 68 61 72 20 2a 29 62  v2(db, (char *)b
1bd00 75 66 2e 61 42 75 66 2c 20 62 75 66 2e 6e 42 75  uf.aBuf, buf.nBu
1bd10 66 2c 20 26 70 2d 3e 70 49 6e 73 65 72 74 2c 20  f, &p->pInsert, 
1bd20 30 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65  0);.  }.  sqlite
1bd30 33 5f 66 72 65 65 28 62 75 66 2e 61 42 75 66 29  3_free(buf.aBuf)
1bd40 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
1bd50 0a 0a 2f 2a 0a 2a 2a 20 41 20 77 72 61 70 70 65  ../*.** A wrappe
1bd60 72 20 61 72 6f 75 6e 64 20 73 71 6c 69 74 65 33  r around sqlite3
1bd70 5f 62 69 6e 64 5f 76 61 6c 75 65 28 29 20 74 68  _bind_value() th
1bd80 61 74 20 64 65 74 65 63 74 73 20 61 6e 20 65 78  at detects an ex
1bd90 74 72 61 20 70 72 6f 62 6c 65 6d 2e 20 0a 2a 2a  tra problem. .**
1bda0 20 53 65 65 20 63 6f 6d 6d 65 6e 74 73 20 69 6e   See comments in
1bdb0 20 74 68 65 20 62 6f 64 79 20 6f 66 20 74 68 69   the body of thi
1bdc0 73 20 66 75 6e 63 74 69 6f 6e 20 66 6f 72 20 64  s function for d
1bdd0 65 74 61 69 6c 73 2e 0a 2a 2f 0a 73 74 61 74 69  etails..*/.stati
1bde0 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 42 69 6e  c int sessionBin
1bdf0 64 56 61 6c 75 65 28 0a 20 20 73 71 6c 69 74 65  dValue(.  sqlite
1be00 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 2c 20 20  3_stmt *pStmt,  
1be10 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74 61            /* Sta
1be20 74 65 6d 65 6e 74 20 74 6f 20 62 69 6e 64 20 76  tement to bind v
1be30 61 6c 75 65 20 74 6f 20 2a 2f 0a 20 20 69 6e 74  alue to */.  int
1be40 20 69 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   i,             
1be50 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1be60 50 61 72 61 6d 65 74 65 72 20 6e 75 6d 62 65 72  Parameter number
1be70 20 74 6f 20 62 69 6e 64 20 74 6f 20 2a 2f 0a 20   to bind to */. 
1be80 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
1be90 70 56 61 6c 20 20 20 20 20 20 20 20 20 20 20 20  pVal            
1bea0 20 2f 2a 20 56 61 6c 75 65 20 74 6f 20 62 69 6e   /* Value to bin
1beb0 64 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 65 54  d */.){.  int eT
1bec0 79 70 65 20 3d 20 73 71 6c 69 74 65 33 5f 76 61  ype = sqlite3_va
1bed0 6c 75 65 5f 74 79 70 65 28 70 56 61 6c 29 3b 0a  lue_type(pVal);.
1bee0 20 20 2f 2a 20 43 4f 56 45 52 41 47 45 3a 20 54    /* COVERAGE: T
1bef0 68 65 20 28 70 56 61 6c 2d 3e 7a 3d 3d 30 29 20  he (pVal->z==0) 
1bf00 62 72 61 6e 63 68 20 69 73 20 6e 65 76 65 72 20  branch is never 
1bf10 74 72 75 65 20 75 73 69 6e 67 20 63 75 72 72 65  true using curre
1bf20 6e 74 20 76 65 72 73 69 6f 6e 73 0a 20 20 2a 2a  nt versions.  **
1bf30 20 6f 66 20 53 51 4c 69 74 65 2e 20 49 66 20 61   of SQLite. If a
1bf40 20 6d 61 6c 6c 6f 63 20 66 61 69 6c 73 20 69 6e   malloc fails in
1bf50 20 61 6e 20 73 71 6c 69 74 65 33 5f 76 61 6c 75   an sqlite3_valu
1bf60 65 5f 78 78 78 28 29 20 66 75 6e 63 74 69 6f 6e  e_xxx() function
1bf70 2c 20 65 69 74 68 65 72 0a 20 20 2a 2a 20 74 68  , either.  ** th
1bf80 65 20 28 70 56 61 6c 2d 3e 7a 29 20 76 61 72 69  e (pVal->z) vari
1bf90 61 62 6c 65 20 72 65 6d 61 69 6e 73 20 61 73 20  able remains as 
1bfa0 69 74 20 77 61 73 20 6f 72 20 74 68 65 20 74 79  it was or the ty
1bfb0 70 65 20 6f 66 20 74 68 65 20 76 61 6c 75 65 20  pe of the value 
1bfc0 69 73 0a 20 20 2a 2a 20 73 65 74 20 74 6f 20 53  is.  ** set to S
1bfd0 51 4c 49 54 45 5f 4e 55 4c 4c 2e 20 20 2a 2f 0a  QLITE_NULL.  */.
1bfe0 20 20 69 66 28 20 28 65 54 79 70 65 3d 3d 53 51    if( (eType==SQ
1bff0 4c 49 54 45 5f 54 45 58 54 20 7c 7c 20 65 54 79  LITE_TEXT || eTy
1c000 70 65 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 29  pe==SQLITE_BLOB)
1c010 20 26 26 20 70 56 61 6c 2d 3e 7a 3d 3d 30 20 29   && pVal->z==0 )
1c020 7b 0a 20 20 20 20 2f 2a 20 54 68 69 73 20 63 6f  {.    /* This co
1c030 6e 64 69 74 69 6f 6e 20 6f 63 63 75 72 73 20 77  ndition occurs w
1c040 68 65 6e 20 61 6e 20 65 61 72 6c 69 65 72 20 4f  hen an earlier O
1c050 4f 4d 20 69 6e 20 61 20 63 61 6c 6c 20 74 6f 0a  OM in a call to.
1c060 20 20 20 20 2a 2a 20 73 71 6c 69 74 65 33 5f 76      ** sqlite3_v
1c070 61 6c 75 65 5f 74 65 78 74 28 29 20 6f 72 20 73  alue_text() or s
1c080 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 6c 6f  qlite3_value_blo
1c090 62 28 29 20 28 70 65 72 68 61 70 73 20 66 72 6f  b() (perhaps fro
1c0a0 6d 20 77 69 74 68 69 6e 0a 20 20 20 20 2a 2a 20  m within.    ** 
1c0b0 61 20 63 6f 6e 66 6c 69 63 74 2d 68 61 6e 64 6c  a conflict-handl
1c0c0 65 72 29 20 68 61 73 20 7a 65 72 6f 65 64 20 74  er) has zeroed t
1c0d0 68 65 20 70 56 61 6c 2d 3e 7a 20 70 6f 69 6e 74  he pVal->z point
1c0e0 65 72 2e 20 52 65 74 75 72 6e 20 4e 4f 4d 45 4d  er. Return NOMEM
1c0f0 2e 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 20  . */.    return 
1c100 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
1c110 7d 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  }.  return sqlit
1c120 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53  e3_bind_value(pS
1c130 74 6d 74 2c 20 69 2c 20 70 56 61 6c 29 3b 0a 7d  tmt, i, pVal);.}
1c140 0a 0a 2f 2a 0a 2a 2a 20 49 74 65 72 61 74 6f 72  ../*.** Iterator
1c150 20 70 49 74 65 72 20 6d 75 73 74 20 70 6f 69 6e   pIter must poin
1c160 74 20 74 6f 20 61 6e 20 53 51 4c 49 54 45 5f 49  t to an SQLITE_I
1c170 4e 53 45 52 54 20 65 6e 74 72 79 2e 20 54 68 69  NSERT entry. Thi
1c180 73 20 66 75 6e 63 74 69 6f 6e 20 0a 2a 2a 20 74  s function .** t
1c190 72 61 6e 73 66 65 72 73 20 6e 65 77 2e 2a 20 76  ransfers new.* v
1c1a0 61 6c 75 65 73 20 66 72 6f 6d 20 74 68 65 20 63  alues from the c
1c1b0 75 72 72 65 6e 74 20 69 74 65 72 61 74 6f 72 20  urrent iterator 
1c1c0 65 6e 74 72 79 20 74 6f 20 73 74 61 74 65 6d 65  entry to stateme
1c1d0 6e 74 0a 2a 2a 20 70 53 74 6d 74 2e 20 54 68 65  nt.** pStmt. The
1c1e0 20 74 61 62 6c 65 20 62 65 69 6e 67 20 69 6e 73   table being ins
1c1f0 65 72 74 65 64 20 69 6e 74 6f 20 68 61 73 20 6e  erted into has n
1c200 43 6f 6c 20 63 6f 6c 75 6d 6e 73 2e 0a 2a 2a 0a  Col columns..**.
1c210 2a 2a 20 4e 65 77 2e 2a 20 76 61 6c 75 65 20 24  ** New.* value $
1c220 69 20 66 72 6f 6d 20 74 68 65 20 69 74 65 72 61  i from the itera
1c230 74 6f 72 20 69 73 20 62 6f 75 6e 64 20 74 6f 20  tor is bound to 
1c240 76 61 72 69 61 62 6c 65 20 28 24 69 2b 31 29 20  variable ($i+1) 
1c250 6f 66 20 0a 2a 2a 20 73 74 61 74 65 6d 65 6e 74  of .** statement
1c260 20 70 53 74 6d 74 2e 20 49 66 20 70 61 72 61 6d   pStmt. If param
1c270 65 74 65 72 20 61 62 50 4b 20 69 73 20 4e 55 4c  eter abPK is NUL
1c280 4c 2c 20 61 6c 6c 20 76 61 6c 75 65 73 20 66 72  L, all values fr
1c290 6f 6d 20 30 20 74 6f 20 28 6e 43 6f 6c 2d 31 29  om 0 to (nCol-1)
1c2a0 0a 2a 2a 20 61 72 65 20 74 72 61 6e 73 66 65 72  .** are transfer
1c2b0 65 64 20 74 6f 20 74 68 65 20 73 74 61 74 65 6d  ed to the statem
1c2c0 65 6e 74 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  ent. Otherwise, 
1c2d0 69 66 20 61 62 50 4b 20 69 73 20 6e 6f 74 20 4e  if abPK is not N
1c2e0 55 4c 4c 2c 20 69 74 20 70 6f 69 6e 74 73 0a 2a  ULL, it points.*
1c2f0 2a 20 74 6f 20 61 6e 20 61 72 72 61 79 20 6e 43  * to an array nC
1c300 6f 6c 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 73  ol elements in s
1c310 69 7a 65 2e 20 49 6e 20 74 68 69 73 20 63 61 73  ize. In this cas
1c320 65 20 6f 6e 6c 79 20 74 68 6f 73 65 20 76 61 6c  e only those val
1c330 75 65 73 20 66 6f 72 20 0a 2a 2a 20 77 68 69 63  ues for .** whic
1c340 68 20 61 62 50 4b 5b 24 69 5d 20 69 73 20 74 72  h abPK[$i] is tr
1c350 75 65 20 61 72 65 20 72 65 61 64 20 66 72 6f 6d  ue are read from
1c360 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 61 6e   the iterator an
1c370 64 20 62 6f 75 6e 64 20 74 6f 20 74 68 65 20 0a  d bound to the .
1c380 2a 2a 20 73 74 61 74 65 6d 65 6e 74 2e 0a 2a 2a  ** statement..**
1c390 0a 2a 2a 20 41 6e 20 53 51 4c 69 74 65 20 65 72  .** An SQLite er
1c3a0 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74 75  ror code is retu
1c3b0 72 6e 65 64 20 69 66 20 61 6e 20 65 72 72 6f 72  rned if an error
1c3c0 20 6f 63 63 75 72 73 2e 20 4f 74 68 65 72 77 69   occurs. Otherwi
1c3d0 73 65 2c 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a  se, SQLITE_OK..*
1c3e0 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73  /.static int ses
1c3f0 73 69 6f 6e 42 69 6e 64 52 6f 77 28 0a 20 20 73  sionBindRow(.  s
1c400 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74  qlite3_changeset
1c410 5f 69 74 65 72 20 2a 70 49 74 65 72 2c 20 20 2f  _iter *pIter,  /
1c420 2a 20 49 74 65 72 61 74 6f 72 20 74 6f 20 72 65  * Iterator to re
1c430 61 64 20 76 61 6c 75 65 73 20 66 72 6f 6d 20 2a  ad values from *
1c440 2f 0a 20 20 69 6e 74 28 2a 78 56 61 6c 75 65 29  /.  int(*xValue)
1c450 28 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73  (sqlite3_changes
1c460 65 74 5f 69 74 65 72 20 2a 2c 20 69 6e 74 2c 20  et_iter *, int, 
1c470 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
1c480 29 2c 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c 20 20  ),.  int nCol,  
1c490 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c4a0 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
1c4b0 66 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 75  f columns */.  u
1c4c0 38 20 2a 61 62 50 4b 2c 20 20 20 20 20 20 20 20  8 *abPK,        
1c4d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1c4e0 2a 20 49 66 20 6e 6f 74 20 4e 55 4c 4c 2c 20 62  * If not NULL, b
1c4f0 69 6e 64 20 6f 6e 6c 79 20 69 66 20 74 72 75 65  ind only if true
1c500 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73 74   */.  sqlite3_st
1c510 6d 74 20 2a 70 53 74 6d 74 20 20 20 20 20 20 20  mt *pStmt       
1c520 20 20 20 20 20 20 2f 2a 20 42 69 6e 64 20 76 61        /* Bind va
1c530 6c 75 65 73 20 74 6f 20 74 68 69 73 20 73 74 61  lues to this sta
1c540 74 65 6d 65 6e 74 20 2a 2f 0a 29 7b 0a 20 20 69  tement */.){.  i
1c550 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72 63 20 3d  nt i;.  int rc =
1c560 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2f   SQLITE_OK;..  /
1c570 2a 20 4e 65 69 74 68 65 72 20 73 71 6c 69 74 65  * Neither sqlite
1c580 33 63 68 61 6e 67 65 73 65 74 5f 6f 6c 64 20 6f  3changeset_old o
1c590 72 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  r sqlite3changes
1c5a0 65 74 5f 6e 65 77 20 63 61 6e 20 66 61 69 6c 20  et_new can fail 
1c5b0 69 66 20 74 68 65 0a 20 20 2a 2a 20 61 72 67 75  if the.  ** argu
1c5c0 6d 65 6e 74 20 69 74 65 72 61 74 6f 72 20 70 6f  ment iterator po
1c5d0 69 6e 74 73 20 74 6f 20 61 20 73 75 69 74 61 62  ints to a suitab
1c5e0 6c 65 20 65 6e 74 72 79 2e 20 4d 61 6b 65 20 73  le entry. Make s
1c5f0 75 72 65 20 74 68 61 74 20 78 56 61 6c 75 65 20  ure that xValue 
1c600 0a 20 20 2a 2a 20 69 73 20 6f 6e 65 20 6f 66 20  .  ** is one of 
1c610 74 68 65 73 65 20 74 6f 20 67 75 61 72 61 6e 74  these to guarant
1c620 65 65 20 74 68 61 74 20 69 74 20 69 73 20 73 61  ee that it is sa
1c630 66 65 20 74 6f 20 69 67 6e 6f 72 65 20 74 68 65  fe to ignore the
1c640 20 72 65 74 75 72 6e 20 0a 20 20 2a 2a 20 69 6e   return .  ** in
1c650 20 74 68 65 20 63 6f 64 65 20 62 65 6c 6f 77 2e   the code below.
1c660 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 78 56   */.  assert( xV
1c670 61 6c 75 65 3d 3d 73 71 6c 69 74 65 33 63 68 61  alue==sqlite3cha
1c680 6e 67 65 73 65 74 5f 6f 6c 64 20 7c 7c 20 78 56  ngeset_old || xV
1c690 61 6c 75 65 3d 3d 73 71 6c 69 74 65 33 63 68 61  alue==sqlite3cha
1c6a0 6e 67 65 73 65 74 5f 6e 65 77 20 29 3b 0a 0a 20  ngeset_new );.. 
1c6b0 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51   for(i=0; rc==SQ
1c6c0 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e 43 6f  LITE_OK && i<nCo
1c6d0 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  l; i++){.    if(
1c6e0 20 21 61 62 50 4b 20 7c 7c 20 61 62 50 4b 5b 69   !abPK || abPK[i
1c6f0 5d 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  ] ){.      sqlit
1c700 65 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c 3b 0a  e3_value *pVal;.
1c710 20 20 20 20 20 20 28 76 6f 69 64 29 78 56 61 6c        (void)xVal
1c720 75 65 28 70 49 74 65 72 2c 20 69 2c 20 26 70 56  ue(pIter, i, &pV
1c730 61 6c 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  al);.      rc = 
1c740 73 65 73 73 69 6f 6e 42 69 6e 64 56 61 6c 75 65  sessionBindValue
1c750 28 70 53 74 6d 74 2c 20 69 2b 31 2c 20 70 56 61  (pStmt, i+1, pVa
1c760 6c 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  l);.    }.  }.  
1c770 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
1c780 0a 2a 2a 20 53 51 4c 20 73 74 61 74 65 6d 65 6e  .** SQL statemen
1c790 74 20 70 53 65 6c 65 63 74 20 69 73 20 61 73 20  t pSelect is as 
1c7a0 67 65 6e 65 72 61 74 65 64 20 62 79 20 74 68 65  generated by the
1c7b0 20 73 65 73 73 69 6f 6e 53 65 6c 65 63 74 52 6f   sessionSelectRo
1c7c0 77 28 29 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2a  w() function..**
1c7d0 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 62   This function b
1c7e0 69 6e 64 73 20 74 68 65 20 70 72 69 6d 61 72 79  inds the primary
1c7f0 20 6b 65 79 20 76 61 6c 75 65 73 20 66 72 6f 6d   key values from
1c800 20 74 68 65 20 63 68 61 6e 67 65 20 74 68 61 74   the change that
1c810 20 63 68 61 6e 67 65 73 65 74 0a 2a 2a 20 69 74   changeset.** it
1c820 65 72 61 74 6f 72 20 70 49 74 65 72 20 70 6f 69  erator pIter poi
1c830 6e 74 73 20 74 6f 20 74 6f 20 74 68 65 20 53 45  nts to to the SE
1c840 4c 45 43 54 20 61 6e 64 20 61 74 74 65 6d 70 74  LECT and attempt
1c850 73 20 74 6f 20 73 65 65 6b 20 74 6f 20 74 68 65  s to seek to the
1c860 20 74 61 62 6c 65 0a 2a 2a 20 65 6e 74 72 79 2e   table.** entry.
1c870 20 49 66 20 61 20 72 6f 77 20 69 73 20 66 6f 75   If a row is fou
1c880 6e 64 2c 20 74 68 65 20 53 45 4c 45 43 54 20 73  nd, the SELECT s
1c890 74 61 74 65 6d 65 6e 74 20 6c 65 66 74 20 70 6f  tatement left po
1c8a0 69 6e 74 69 6e 67 20 61 74 20 74 68 65 20 72 6f  inting at the ro
1c8b0 77 20 0a 2a 2a 20 61 6e 64 20 53 51 4c 49 54 45  w .** and SQLITE
1c8c0 5f 52 4f 57 20 69 73 20 72 65 74 75 72 6e 65 64  _ROW is returned
1c8d0 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20  . Otherwise, if 
1c8e0 6e 6f 20 72 6f 77 20 69 73 20 66 6f 75 6e 64 20  no row is found 
1c8f0 61 6e 64 20 6e 6f 20 65 72 72 6f 72 0a 2a 2a 20  and no error.** 
1c900 68 61 73 20 6f 63 63 75 72 65 64 2c 20 74 68 65  has occured, the
1c910 20 73 74 61 74 65 6d 65 6e 74 20 69 73 20 72 65   statement is re
1c920 73 65 74 20 61 6e 64 20 53 51 4c 49 54 45 5f 4f  set and SQLITE_O
1c930 4b 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 49  K is returned. I
1c940 66 20 61 6e 0a 2a 2a 20 65 72 72 6f 72 20 6f 63  f an.** error oc
1c950 63 75 72 73 2c 20 74 68 65 20 73 74 61 74 65 6d  curs, the statem
1c960 65 6e 74 20 69 73 20 72 65 73 65 74 20 61 6e 64  ent is reset and
1c970 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
1c980 20 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65   code is returne
1c990 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 69 73  d..**.** If this
1c9a0 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e   function return
1c9b0 73 20 53 51 4c 49 54 45 5f 52 4f 57 2c 20 74 68  s SQLITE_ROW, th
1c9c0 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 65 76  e caller must ev
1c9d0 65 6e 74 75 61 6c 6c 79 20 72 65 73 65 74 28 29  entually reset()
1c9e0 20 0a 2a 2a 20 73 74 61 74 65 6d 65 6e 74 20 70   .** statement p
1c9f0 53 65 6c 65 63 74 2e 20 49 66 20 61 6e 79 20 6f  Select. If any o
1ca00 74 68 65 72 20 76 61 6c 75 65 20 69 73 20 72 65  ther value is re
1ca10 74 75 72 6e 65 64 2c 20 74 68 65 20 73 74 61 74  turned, the stat
1ca20 65 6d 65 6e 74 20 64 6f 65 73 0a 2a 2a 20 6e 6f  ement does.** no
1ca30 74 20 72 65 71 75 69 72 65 20 61 20 72 65 73 65  t require a rese
1ca40 74 28 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  t()..**.** If th
1ca50 65 20 69 74 65 72 61 74 6f 72 20 63 75 72 72 65  e iterator curre
1ca60 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f 20 61  ntly points to a
1ca70 6e 20 49 4e 53 45 52 54 20 72 65 63 6f 72 64 2c  n INSERT record,
1ca80 20 62 69 6e 64 20 76 61 6c 75 65 73 20 66 72 6f   bind values fro
1ca90 6d 20 74 68 65 0a 2a 2a 20 6e 65 77 2e 2a 20 72  m the.** new.* r
1caa0 65 63 6f 72 64 20 74 6f 20 74 68 65 20 53 45 4c  ecord to the SEL
1cab0 45 43 54 20 73 74 61 74 65 6d 65 6e 74 2e 20 4f  ECT statement. O
1cac0 72 2c 20 69 66 20 69 74 20 70 6f 69 6e 74 73 20  r, if it points 
1cad0 74 6f 20 61 20 44 45 4c 45 54 45 20 6f 72 0a 2a  to a DELETE or.*
1cae0 2a 20 55 50 44 41 54 45 2c 20 62 69 6e 64 20 76  * UPDATE, bind v
1caf0 61 6c 75 65 73 20 66 72 6f 6d 20 74 68 65 20 6f  alues from the o
1cb00 6c 64 2e 2a 20 72 65 63 6f 72 64 2e 20 0a 2a 2f  ld.* record. .*/
1cb10 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73  .static int sess
1cb20 69 6f 6e 53 65 65 6b 54 6f 52 6f 77 28 0a 20 20  ionSeekToRow(.  
1cb30 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20  sqlite3 *db,    
1cb40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cb50 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e 64  /* Database hand
1cb60 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  le */.  sqlite3_
1cb70 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a  changeset_iter *
1cb80 70 49 74 65 72 2c 20 20 2f 2a 20 43 68 61 6e 67  pIter,  /* Chang
1cb90 65 73 65 74 20 69 74 65 72 61 74 6f 72 20 2a 2f  eset iterator */
1cba0 0a 20 20 75 38 20 2a 61 62 50 4b 2c 20 20 20 20  .  u8 *abPK,    
1cbb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cbc0 20 20 20 2f 2a 20 50 72 69 6d 61 72 79 20 6b 65     /* Primary ke
1cbd0 79 20 66 6c 61 67 73 20 61 72 72 61 79 20 2a 2f  y flags array */
1cbe0 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
1cbf0 2a 70 53 65 6c 65 63 74 20 20 20 20 20 20 20 20  *pSelect        
1cc00 20 20 20 2f 2a 20 53 45 4c 45 43 54 20 73 74 61     /* SELECT sta
1cc10 74 65 6d 65 6e 74 20 66 72 6f 6d 20 73 65 73 73  tement from sess
1cc20 69 6f 6e 53 65 6c 65 63 74 52 6f 77 28 29 20 2a  ionSelectRow() *
1cc30 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20  /.){.  int rc;  
1cc40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cc50 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
1cc60 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 6e   code */.  int n
1cc70 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  Col;            
1cc80 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
1cc90 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20  mber of columns 
1cca0 69 6e 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e  in table */.  in
1ccb0 74 20 6f 70 3b 20 20 20 20 20 20 20 20 20 20 20  t op;           
1ccc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1ccd0 20 43 68 61 6e 67 73 65 74 20 6f 70 65 72 61 74   Changset operat
1cce0 69 6f 6e 20 28 53 51 4c 49 54 45 5f 55 50 44 41  ion (SQLITE_UPDA
1ccf0 54 45 20 65 74 63 2e 29 20 2a 2f 0a 20 20 63 6f  TE etc.) */.  co
1cd00 6e 73 74 20 63 68 61 72 20 2a 7a 44 75 6d 6d 79  nst char *zDummy
1cd10 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
1cd20 20 55 6e 75 73 65 64 20 2a 2f 0a 0a 20 20 73 71   Unused */..  sq
1cd30 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f  lite3changeset_o
1cd40 70 28 70 49 74 65 72 2c 20 26 7a 44 75 6d 6d 79  p(pIter, &zDummy
1cd50 2c 20 26 6e 43 6f 6c 2c 20 26 6f 70 2c 20 30 29  , &nCol, &op, 0)
1cd60 3b 0a 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e  ;.  rc = session
1cd70 42 69 6e 64 52 6f 77 28 70 49 74 65 72 2c 20 0a  BindRow(pIter, .
1cd80 20 20 20 20 20 20 6f 70 3d 3d 53 51 4c 49 54 45        op==SQLITE
1cd90 5f 49 4e 53 45 52 54 20 3f 20 73 71 6c 69 74 65  _INSERT ? sqlite
1cda0 33 63 68 61 6e 67 65 73 65 74 5f 6e 65 77 20 3a  3changeset_new :
1cdb0 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
1cdc0 74 5f 6f 6c 64 2c 0a 20 20 20 20 20 20 6e 43 6f  t_old,.      nCo
1cdd0 6c 2c 20 61 62 50 4b 2c 20 70 53 65 6c 65 63 74  l, abPK, pSelect
1cde0 0a 20 20 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d  .  );..  if( rc=
1cdf0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
1ce00 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 73    rc = sqlite3_s
1ce10 74 65 70 28 70 53 65 6c 65 63 74 29 3b 0a 20 20  tep(pSelect);.  
1ce20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
1ce30 5f 52 4f 57 20 29 20 72 63 20 3d 20 73 71 6c 69  _ROW ) rc = sqli
1ce40 74 65 33 5f 72 65 73 65 74 28 70 53 65 6c 65 63  te3_reset(pSelec
1ce50 74 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  t);.  }..  retur
1ce60 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  n rc;.}../*.** I
1ce70 6e 76 6f 6b 65 20 74 68 65 20 63 6f 6e 66 6c 69  nvoke the confli
1ce80 63 74 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 74  ct handler for t
1ce90 68 65 20 63 68 61 6e 67 65 20 74 68 61 74 20 74  he change that t
1cea0 68 65 20 63 68 61 6e 67 65 73 65 74 20 69 74 65  he changeset ite
1ceb0 72 61 74 6f 72 0a 2a 2a 20 63 75 72 72 65 6e 74  rator.** current
1cec0 6c 79 20 70 6f 69 6e 74 73 20 74 6f 2e 0a 2a 2a  ly points to..**
1ced0 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20 65 54 79  .** Argument eTy
1cee0 70 65 20 6d 75 73 74 20 62 65 20 65 69 74 68 65  pe must be eithe
1cef0 72 20 43 48 41 4e 47 45 53 45 54 5f 44 41 54 41  r CHANGESET_DATA
1cf00 20 6f 72 20 43 48 41 4e 47 45 53 45 54 5f 43 4f   or CHANGESET_CO
1cf10 4e 46 4c 49 43 54 2e 0a 2a 2a 20 49 66 20 61 72  NFLICT..** If ar
1cf20 67 75 6d 65 6e 74 20 70 62 52 65 70 6c 61 63 65  gument pbReplace
1cf30 20 69 73 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 74   is NULL, then t
1cf40 68 65 20 74 79 70 65 20 6f 66 20 63 6f 6e 66 6c  he type of confl
1cf50 69 63 74 20 68 61 6e 64 6c 65 72 20 69 6e 76 6f  ict handler invo
1cf60 6b 65 64 0a 2a 2a 20 64 65 70 65 6e 64 73 20 73  ked.** depends s
1cf70 6f 6c 65 6c 79 20 6f 6e 20 65 54 79 70 65 2c 20  olely on eType, 
1cf80 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a  as follows:.**.*
1cf90 2a 20 20 20 20 65 54 79 70 65 20 76 61 6c 75 65  *    eType value
1cfa0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cfb0 20 56 61 6c 75 65 20 70 61 73 73 65 64 20 74 6f   Value passed to
1cfc0 20 78 43 6f 6e 66 6c 69 63 74 0a 2a 2a 20 20 20   xConflict.**   
1cfd0 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d   ---------------
1cfe0 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1cff0 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1d000 2d 2d 0a 2a 2a 20 20 20 20 43 48 41 4e 47 45 53  --.**    CHANGES
1d010 45 54 5f 44 41 54 41 20 20 20 20 20 20 20 20 20  ET_DATA         
1d020 20 20 20 20 20 43 48 41 4e 47 45 53 45 54 5f 4e       CHANGESET_N
1d030 4f 54 46 4f 55 4e 44 0a 2a 2a 20 20 20 20 43 48  OTFOUND.**    CH
1d040 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49 43 54  ANGESET_CONFLICT
1d050 20 20 20 20 20 20 20 20 20 20 43 48 41 4e 47 45            CHANGE
1d060 53 45 54 5f 43 4f 4e 53 54 52 41 49 4e 54 0a 2a  SET_CONSTRAINT.*
1d070 2a 0a 2a 2a 20 4f 72 2c 20 69 66 20 70 62 52 65  *.** Or, if pbRe
1d080 70 6c 61 63 65 20 69 73 20 6e 6f 74 20 4e 55 4c  place is not NUL
1d090 4c 2c 20 74 68 65 6e 20 61 6e 20 61 74 74 65 6d  L, then an attem
1d0a0 70 74 20 69 73 20 6d 61 64 65 20 74 6f 20 66 69  pt is made to fi
1d0b0 6e 64 20 61 6e 20 65 78 69 73 74 69 6e 67 0a 2a  nd an existing.*
1d0c0 2a 20 72 65 63 6f 72 64 20 77 69 74 68 20 74 68  * record with th
1d0d0 65 20 73 61 6d 65 20 70 72 69 6d 61 72 79 20 6b  e same primary k
1d0e0 65 79 20 61 73 20 74 68 65 20 72 65 63 6f 72 64  ey as the record
1d0f0 20 61 62 6f 75 74 20 74 6f 20 62 65 20 64 65 6c   about to be del
1d100 65 74 65 64 2c 20 75 70 64 61 74 65 64 0a 2a 2a  eted, updated.**
1d110 20 6f 72 20 69 6e 73 65 72 74 65 64 2e 20 49 66   or inserted. If
1d120 20 73 75 63 68 20 61 20 72 65 63 6f 72 64 20 63   such a record c
1d130 61 6e 20 62 65 20 66 6f 75 6e 64 2c 20 69 74 20  an be found, it 
1d140 69 73 20 61 76 61 69 6c 61 62 6c 65 20 74 6f 20  is available to 
1d150 74 68 65 20 63 6f 6e 66 6c 69 63 74 0a 2a 2a 20  the conflict.** 
1d160 68 61 6e 64 6c 65 72 20 61 73 20 74 68 65 20 22  handler as the "
1d170 63 6f 6e 66 6c 69 63 74 69 6e 67 22 20 72 65 63  conflicting" rec
1d180 6f 72 64 2e 20 49 6e 20 74 68 69 73 20 63 61 73  ord. In this cas
1d190 65 20 74 68 65 20 74 79 70 65 20 6f 66 20 63 6f  e the type of co
1d1a0 6e 66 6c 69 63 74 0a 2a 2a 20 68 61 6e 64 6c 65  nflict.** handle
1d1b0 72 20 69 6e 76 6f 6b 65 64 20 69 73 20 61 73 20  r invoked is as 
1d1c0 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20  follows:.**.**  
1d1d0 20 20 65 54 79 70 65 20 76 61 6c 75 65 20 20 20    eType value   
1d1e0 20 20 20 20 20 20 50 4b 20 52 65 63 6f 72 64 20        PK Record 
1d1f0 66 6f 75 6e 64 3f 20 20 20 56 61 6c 75 65 20 70  found?   Value p
1d200 61 73 73 65 64 20 74 6f 20 78 43 6f 6e 66 6c 69  assed to xConfli
1d210 63 74 0a 2a 2a 20 20 20 20 2d 2d 2d 2d 2d 2d 2d  ct.**    -------
1d220 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1d230 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1d240 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1d250 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 2a 2a 20 20 20 20  ---------.**    
1d260 43 48 41 4e 47 45 53 45 54 5f 44 41 54 41 20 20  CHANGESET_DATA  
1d270 20 20 20 20 59 65 73 20 20 20 20 20 20 20 20 20      Yes         
1d280 20 20 20 20 20 20 20 43 48 41 4e 47 45 53 45 54         CHANGESET
1d290 5f 44 41 54 41 0a 2a 2a 20 20 20 20 43 48 41 4e  _DATA.**    CHAN
1d2a0 47 45 53 45 54 5f 44 41 54 41 20 20 20 20 20 20  GESET_DATA      
1d2b0 4e 6f 20 20 20 20 20 20 20 20 20 20 20 20 20 20  No              
1d2c0 20 20 20 43 48 41 4e 47 45 53 45 54 5f 4e 4f 54     CHANGESET_NOT
1d2d0 46 4f 55 4e 44 0a 2a 2a 20 20 20 20 43 48 41 4e  FOUND.**    CHAN
1d2e0 47 45 53 45 54 5f 43 4f 4e 46 4c 49 43 54 20 20  GESET_CONFLICT  
1d2f0 59 65 73 20 20 20 20 20 20 20 20 20 20 20 20 20  Yes             
1d300 20 20 20 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e     CHANGESET_CON
1d310 46 4c 49 43 54 0a 2a 2a 20 20 20 20 43 48 41 4e  FLICT.**    CHAN
1d320 47 45 53 45 54 5f 43 4f 4e 46 4c 49 43 54 20 20  GESET_CONFLICT  
1d330 4e 6f 20 20 20 20 20 20 20 20 20 20 20 20 20 20  No              
1d340 20 20 20 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e     CHANGESET_CON
1d350 53 54 52 41 49 4e 54 0a 2a 2a 0a 2a 2a 20 49 66  STRAINT.**.** If
1d360 20 70 62 52 65 70 6c 61 63 65 20 69 73 20 6e 6f   pbReplace is no
1d370 74 20 4e 55 4c 4c 2c 20 61 6e 64 20 61 20 72 65  t NULL, and a re
1d380 63 6f 72 64 20 77 69 74 68 20 61 20 6d 61 74 63  cord with a matc
1d390 68 69 6e 67 20 50 4b 20 69 73 20 66 6f 75 6e 64  hing PK is found
1d3a0 2c 20 61 6e 64 0a 2a 2a 20 74 68 65 20 63 6f 6e  , and.** the con
1d3b0 66 6c 69 63 74 20 68 61 6e 64 6c 65 72 20 66 75  flict handler fu
1d3c0 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 53  nction returns S
1d3d0 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f  QLITE_CHANGESET_
1d3e0 52 45 50 4c 41 43 45 2c 20 2a 70 62 52 65 70 6c  REPLACE, *pbRepl
1d3f0 61 63 65 0a 2a 2a 20 69 73 20 73 65 74 20 74 6f  ace.** is set to
1d400 20 6e 6f 6e 2d 7a 65 72 6f 20 62 65 66 6f 72 65   non-zero before
1d410 20 72 65 74 75 72 6e 69 6e 67 20 53 51 4c 49 54   returning SQLIT
1d420 45 5f 4f 4b 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74  E_OK..**.** If t
1d430 68 65 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64  he conflict hand
1d440 6c 65 72 20 72 65 74 75 72 6e 73 20 53 51 4c 49  ler returns SQLI
1d450 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 41 42 4f  TE_CHANGESET_ABO
1d460 52 54 2c 20 53 51 4c 49 54 45 5f 41 42 4f 52 54  RT, SQLITE_ABORT
1d470 20 69 73 0a 2a 2a 20 72 65 74 75 72 6e 65 64 2e   is.** returned.
1d480 20 4f 72 2c 20 69 66 20 74 68 65 20 63 6f 6e 66   Or, if the conf
1d490 6c 69 63 74 20 68 61 6e 64 6c 65 72 20 72 65 74  lict handler ret
1d4a0 75 72 6e 73 20 61 6e 20 69 6e 76 61 6c 69 64 20  urns an invalid 
1d4b0 76 61 6c 75 65 2c 20 0a 2a 2a 20 53 51 4c 49 54  value, .** SQLIT
1d4c0 45 5f 4d 49 53 55 53 45 2e 20 49 66 20 74 68 65  E_MISUSE. If the
1d4d0 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65   conflict handle
1d4e0 72 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45  r returns SQLITE
1d4f0 5f 43 48 41 4e 47 45 53 45 54 5f 4f 4d 49 54 2c  _CHANGESET_OMIT,
1d500 0a 2a 2a 20 74 68 69 73 20 66 75 6e 63 74 69 6f  .** this functio
1d510 6e 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45  n returns SQLITE
1d520 5f 4f 4b 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  _OK..*/.static i
1d530 6e 74 20 73 65 73 73 69 6f 6e 43 6f 6e 66 6c 69  nt sessionConfli
1d540 63 74 48 61 6e 64 6c 65 72 28 0a 20 20 69 6e 74  ctHandler(.  int
1d550 20 65 54 79 70 65 2c 20 20 20 20 20 20 20 20 20   eType,         
1d560 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1d570 45 69 74 68 65 72 20 43 48 41 4e 47 45 53 45 54  Either CHANGESET
1d580 5f 44 41 54 41 20 6f 72 20 43 4f 4e 46 4c 49 43  _DATA or CONFLIC
1d590 54 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 41 70  T */.  SessionAp
1d5a0 70 6c 79 43 74 78 20 2a 70 2c 20 20 20 20 20 20  plyCtx *p,      
1d5b0 20 20 20 20 20 20 20 2f 2a 20 63 68 61 6e 67 65         /* change
1d5c0 73 65 74 5f 61 70 70 6c 79 28 29 20 63 6f 6e 74  set_apply() cont
1d5d0 65 78 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ext */.  sqlite3
1d5e0 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20  _changeset_iter 
1d5f0 2a 70 49 74 65 72 2c 20 20 2f 2a 20 43 68 61 6e  *pIter,  /* Chan
1d600 67 65 73 65 74 20 69 74 65 72 61 74 6f 72 20 2a  geset iterator *
1d610 2f 0a 20 20 69 6e 74 28 2a 78 43 6f 6e 66 6c 69  /.  int(*xConfli
1d620 63 74 29 28 76 6f 69 64 20 2a 2c 20 69 6e 74 2c  ct)(void *, int,
1d630 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73   sqlite3_changes
1d640 65 74 5f 69 74 65 72 2a 29 2c 0a 20 20 76 6f 69  et_iter*),.  voi
1d650 64 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20  d *pCtx,        
1d660 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1d670 46 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 66  First argument f
1d680 6f 72 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64  or conflict hand
1d690 6c 65 72 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 62  ler */.  int *pb
1d6a0 52 65 70 6c 61 63 65 20 20 20 20 20 20 20 20 20  Replace         
1d6b0 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
1d6c0 20 53 65 74 20 74 6f 20 74 72 75 65 20 69 66 20   Set to true if 
1d6d0 50 4b 20 72 6f 77 20 69 73 20 66 6f 75 6e 64 20  PK row is found 
1d6e0 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 65 73 20  */.){.  int res 
1d6f0 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
1d700 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65          /* Value
1d710 20 72 65 74 75 72 6e 65 64 20 62 79 20 63 6f 6e   returned by con
1d720 66 6c 69 63 74 20 68 61 6e 64 6c 65 72 20 2a 2f  flict handler */
1d730 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74  .  int rc;.  int
1d740 20 6e 43 6f 6c 3b 0a 20 20 69 6e 74 20 6f 70 3b   nCol;.  int op;
1d750 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
1d760 44 75 6d 6d 79 3b 0a 0a 20 20 73 71 6c 69 74 65  Dummy;..  sqlite
1d770 33 63 68 61 6e 67 65 73 65 74 5f 6f 70 28 70 49  3changeset_op(pI
1d780 74 65 72 2c 20 26 7a 44 75 6d 6d 79 2c 20 26 6e  ter, &zDummy, &n
1d790 43 6f 6c 2c 20 26 6f 70 2c 20 30 29 3b 0a 0a 20  Col, &op, 0);.. 
1d7a0 20 61 73 73 65 72 74 28 20 65 54 79 70 65 3d 3d   assert( eType==
1d7b0 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54  SQLITE_CHANGESET
1d7c0 5f 43 4f 4e 46 4c 49 43 54 20 7c 7c 20 65 54 79  _CONFLICT || eTy
1d7d0 70 65 3d 3d 53 51 4c 49 54 45 5f 43 48 41 4e 47  pe==SQLITE_CHANG
1d7e0 45 53 45 54 5f 44 41 54 41 20 29 3b 0a 20 20 61  ESET_DATA );.  a
1d7f0 73 73 65 72 74 28 20 53 51 4c 49 54 45 5f 43 48  ssert( SQLITE_CH
1d800 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49 43 54  ANGESET_CONFLICT
1d810 2b 31 3d 3d 53 51 4c 49 54 45 5f 43 48 41 4e 47  +1==SQLITE_CHANG
1d820 45 53 45 54 5f 43 4f 4e 53 54 52 41 49 4e 54 20  ESET_CONSTRAINT 
1d830 29 3b 0a 20 20 61 73 73 65 72 74 28 20 53 51 4c  );.  assert( SQL
1d840 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 44 41  ITE_CHANGESET_DA
1d850 54 41 2b 31 3d 3d 53 51 4c 49 54 45 5f 43 48 41  TA+1==SQLITE_CHA
1d860 4e 47 45 53 45 54 5f 4e 4f 54 46 4f 55 4e 44 20  NGESET_NOTFOUND 
1d870 29 3b 0a 0a 20 20 2f 2a 20 42 69 6e 64 20 74 68  );..  /* Bind th
1d880 65 20 6e 65 77 2e 2a 20 50 52 49 4d 41 52 59 20  e new.* PRIMARY 
1d890 4b 45 59 20 76 61 6c 75 65 73 20 74 6f 20 74 68  KEY values to th
1d8a0 65 20 53 45 4c 45 43 54 20 73 74 61 74 65 6d 65  e SELECT stateme
1d8b0 6e 74 2e 20 2a 2f 0a 20 20 69 66 28 20 70 62 52  nt. */.  if( pbR
1d8c0 65 70 6c 61 63 65 20 29 7b 0a 20 20 20 20 72 63  eplace ){.    rc
1d8d0 20 3d 20 73 65 73 73 69 6f 6e 53 65 65 6b 54 6f   = sessionSeekTo
1d8e0 52 6f 77 28 70 2d 3e 64 62 2c 20 70 49 74 65 72  Row(p->db, pIter
1d8f0 2c 20 70 2d 3e 61 62 50 4b 2c 20 70 2d 3e 70 53  , p->abPK, p->pS
1d900 65 6c 65 63 74 29 3b 0a 20 20 7d 65 6c 73 65 7b  elect);.  }else{
1d910 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
1d920 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  _OK;.  }..  if( 
1d930 72 63 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29  rc==SQLITE_ROW )
1d940 7b 0a 20 20 20 20 2f 2a 20 54 68 65 72 65 20 65  {.    /* There e
1d950 78 69 73 74 73 20 61 6e 6f 74 68 65 72 20 72 6f  xists another ro
1d960 77 20 77 69 74 68 20 74 68 65 20 6e 65 77 2e 2a  w with the new.*
1d970 20 70 72 69 6d 61 72 79 20 6b 65 79 2e 20 2a 2f   primary key. */
1d980 0a 20 20 20 20 70 49 74 65 72 2d 3e 70 43 6f 6e  .    pIter->pCon
1d990 66 6c 69 63 74 20 3d 20 70 2d 3e 70 53 65 6c 65  flict = p->pSele
1d9a0 63 74 3b 0a 20 20 20 20 72 65 73 20 3d 20 78 43  ct;.    res = xC
1d9b0 6f 6e 66 6c 69 63 74 28 70 43 74 78 2c 20 65 54  onflict(pCtx, eT
1d9c0 79 70 65 2c 20 70 49 74 65 72 29 3b 0a 20 20 20  ype, pIter);.   
1d9d0 20 70 49 74 65 72 2d 3e 70 43 6f 6e 66 6c 69 63   pIter->pConflic
1d9e0 74 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d 20  t = 0;.    rc = 
1d9f0 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70 2d  sqlite3_reset(p-
1da00 3e 70 53 65 6c 65 63 74 29 3b 0a 20 20 7d 65 6c  >pSelect);.  }el
1da10 73 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  se if( rc==SQLIT
1da20 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 66 28 20  E_OK ){.    if( 
1da30 70 2d 3e 62 44 65 66 65 72 43 6f 6e 73 74 72 61  p->bDeferConstra
1da40 69 6e 74 73 20 26 26 20 65 54 79 70 65 3d 3d 53  ints && eType==S
1da50 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f  QLITE_CHANGESET_
1da60 43 4f 4e 46 4c 49 43 54 20 29 7b 0a 20 20 20 20  CONFLICT ){.    
1da70 20 20 2f 2a 20 49 6e 73 74 65 61 64 20 6f 66 20    /* Instead of 
1da80 69 6e 76 6f 6b 69 6e 67 20 74 68 65 20 63 6f 6e  invoking the con
1da90 66 6c 69 63 74 20 68 61 6e 64 6c 65 72 2c 20 61  flict handler, a
1daa0 70 70 65 6e 64 20 74 68 65 20 63 68 61 6e 67 65  ppend the change
1dab0 20 62 6c 6f 62 0a 20 20 20 20 20 20 2a 2a 20 74   blob.      ** t
1dac0 6f 20 74 68 65 20 53 65 73 73 69 6f 6e 41 70 70  o the SessionApp
1dad0 6c 79 43 74 78 2e 63 6f 6e 73 74 72 61 69 6e 74  lyCtx.constraint
1dae0 73 20 62 75 66 66 65 72 2e 20 2a 2f 0a 20 20 20  s buffer. */.   
1daf0 20 20 20 75 38 20 2a 61 42 6c 6f 62 20 3d 20 26     u8 *aBlob = &
1db00 70 49 74 65 72 2d 3e 69 6e 2e 61 44 61 74 61 5b  pIter->in.aData[
1db10 70 49 74 65 72 2d 3e 69 6e 2e 69 43 75 72 72 65  pIter->in.iCurre
1db20 6e 74 5d 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e  nt];.      int n
1db30 42 6c 6f 62 20 3d 20 70 49 74 65 72 2d 3e 69 6e  Blob = pIter->in
1db40 2e 69 4e 65 78 74 20 2d 20 70 49 74 65 72 2d 3e  .iNext - pIter->
1db50 69 6e 2e 69 43 75 72 72 65 6e 74 3b 0a 20 20 20  in.iCurrent;.   
1db60 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
1db70 42 6c 6f 62 28 26 70 2d 3e 63 6f 6e 73 74 72 61  Blob(&p->constra
1db80 69 6e 74 73 2c 20 61 42 6c 6f 62 2c 20 6e 42 6c  ints, aBlob, nBl
1db90 6f 62 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20  ob, &rc);.      
1dba0 72 65 73 20 3d 20 53 51 4c 49 54 45 5f 43 48 41  res = SQLITE_CHA
1dbb0 4e 47 45 53 45 54 5f 4f 4d 49 54 3b 0a 20 20 20  NGESET_OMIT;.   
1dbc0 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a   }else{.      /*
1dbd0 20 4e 6f 20 6f 74 68 65 72 20 72 6f 77 20 77 69   No other row wi
1dbe0 74 68 20 74 68 65 20 6e 65 77 2e 2a 20 70 72 69  th the new.* pri
1dbf0 6d 61 72 79 20 6b 65 79 2e 20 2a 2f 0a 20 20 20  mary key. */.   
1dc00 20 20 20 72 65 73 20 3d 20 78 43 6f 6e 66 6c 69     res = xConfli
1dc10 63 74 28 70 43 74 78 2c 20 65 54 79 70 65 2b 31  ct(pCtx, eType+1
1dc20 2c 20 70 49 74 65 72 29 3b 0a 20 20 20 20 20 20  , pIter);.      
1dc30 69 66 28 20 72 65 73 3d 3d 53 51 4c 49 54 45 5f  if( res==SQLITE_
1dc40 43 48 41 4e 47 45 53 45 54 5f 52 45 50 4c 41 43  CHANGESET_REPLAC
1dc50 45 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  E ) rc = SQLITE_
1dc60 4d 49 53 55 53 45 3b 0a 20 20 20 20 7d 0a 20 20  MISUSE;.    }.  
1dc70 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
1dc80 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 77  ITE_OK ){.    sw
1dc90 69 74 63 68 28 20 72 65 73 20 29 7b 0a 20 20 20  itch( res ){.   
1dca0 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 43     case SQLITE_C
1dcb0 48 41 4e 47 45 53 45 54 5f 52 45 50 4c 41 43 45  HANGESET_REPLACE
1dcc0 3a 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  :.        assert
1dcd0 28 20 70 62 52 65 70 6c 61 63 65 20 29 3b 0a 20  ( pbReplace );. 
1dce0 20 20 20 20 20 20 20 2a 70 62 52 65 70 6c 61 63         *pbReplac
1dcf0 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 62  e = 1;.        b
1dd00 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63 61 73  reak;..      cas
1dd10 65 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53  e SQLITE_CHANGES
1dd20 45 54 5f 4f 4d 49 54 3a 0a 20 20 20 20 20 20 20  ET_OMIT:.       
1dd30 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63   break;..      c
1dd40 61 73 65 20 53 51 4c 49 54 45 5f 43 48 41 4e 47  ase SQLITE_CHANG
1dd50 45 53 45 54 5f 41 42 4f 52 54 3a 0a 20 20 20 20  ESET_ABORT:.    
1dd60 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
1dd70 41 42 4f 52 54 3b 0a 20 20 20 20 20 20 20 20 62  ABORT;.        b
1dd80 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 64 65 66  reak;..      def
1dd90 61 75 6c 74 3a 0a 20 20 20 20 20 20 20 20 72 63  ault:.        rc
1dda0 20 3d 20 53 51 4c 49 54 45 5f 4d 49 53 55 53 45   = SQLITE_MISUSE
1ddb0 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
1ddc0 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
1ddd0 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
1dde0 2a 20 41 74 74 65 6d 70 74 20 74 6f 20 61 70 70  * Attempt to app
1ddf0 6c 79 20 74 68 65 20 63 68 61 6e 67 65 20 74 68  ly the change th
1de00 61 74 20 74 68 65 20 69 74 65 72 61 74 6f 72 20  at the iterator 
1de10 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69  passed as the fi
1de20 72 73 74 20 61 72 67 75 6d 65 6e 74 0a 2a 2a 20  rst argument.** 
1de30 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73  currently points
1de40 20 74 6f 20 74 6f 20 74 68 65 20 64 61 74 61 62   to to the datab
1de50 61 73 65 2e 20 49 66 20 61 20 63 6f 6e 66 6c 69  ase. If a confli
1de60 63 74 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65  ct is encountere
1de70 64 2c 20 69 6e 76 6f 6b 65 0a 2a 2a 20 74 68 65  d, invoke.** the
1de80 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65   conflict handle
1de90 72 20 63 61 6c 6c 62 61 63 6b 2e 0a 2a 2a 0a 2a  r callback..**.*
1dea0 2a 20 49 66 20 61 72 67 75 6d 65 6e 74 20 70 62  * If argument pb
1deb0 52 65 74 72 79 20 69 73 20 4e 55 4c 4c 2c 20 74  Retry is NULL, t
1dec0 68 65 6e 20 69 67 6e 6f 72 65 20 61 6e 79 20 43  hen ignore any C
1ded0 48 41 4e 47 45 53 45 54 5f 44 41 54 41 20 63 6f  HANGESET_DATA co
1dee0 6e 66 6c 69 63 74 2e 20 49 66 0a 2a 2a 20 6f 6e  nflict. If.** on
1def0 65 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65 64  e is encountered
1df00 2c 20 75 70 64 61 74 65 20 6f 72 20 64 65 6c 65  , update or dele
1df10 74 65 20 74 68 65 20 72 6f 77 20 77 69 74 68 20  te the row with 
1df20 74 68 65 20 6d 61 74 63 68 69 6e 67 20 70 72 69  the matching pri
1df30 6d 61 72 79 20 6b 65 79 0a 2a 2a 20 69 6e 73 74  mary key.** inst
1df40 65 61 64 2e 20 4f 72 2c 20 69 66 20 70 62 52 65  ead. Or, if pbRe
1df50 74 72 79 20 69 73 20 6e 6f 74 20 4e 55 4c 4c 20  try is not NULL 
1df60 61 6e 64 20 61 20 43 48 41 4e 47 45 53 45 54 5f  and a CHANGESET_
1df70 44 41 54 41 20 63 6f 6e 66 6c 69 63 74 20 6f 63  DATA conflict oc
1df80 63 75 72 73 2c 0a 2a 2a 20 69 6e 76 6f 6b 65 20  curs,.** invoke 
1df90 74 68 65 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e  the conflict han
1dfa0 64 6c 65 72 2e 20 49 66 20 69 74 20 72 65 74 75  dler. If it retu
1dfb0 72 6e 73 20 43 48 41 4e 47 45 53 45 54 5f 52 45  rns CHANGESET_RE
1dfc0 50 4c 41 43 45 2c 20 73 65 74 20 2a 70 62 52 65  PLACE, set *pbRe
1dfd0 74 72 79 0a 2a 2a 20 74 6f 20 74 72 75 65 20 62  try.** to true b
1dfe0 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
1dff0 20 49 6e 20 74 68 69 73 20 63 61 73 65 20 74 68   In this case th
1e000 65 20 63 61 6c 6c 65 72 20 77 69 6c 6c 20 69 6e  e caller will in
1e010 76 6f 6b 65 20 74 68 69 73 20 66 75 6e 63 74 69  voke this functi
1e020 6f 6e 0a 2a 2a 20 61 67 61 69 6e 2c 20 74 68 69  on.** again, thi
1e030 73 20 74 69 6d 65 20 77 69 74 68 20 70 62 52 65  s time with pbRe
1e040 74 72 79 20 73 65 74 20 74 6f 20 4e 55 4c 4c 2e  try set to NULL.
1e050 0a 2a 2a 0a 2a 2a 20 49 66 20 61 72 67 75 6d 65  .**.** If argume
1e060 6e 74 20 70 62 52 65 70 6c 61 63 65 20 69 73 20  nt pbReplace is 
1e070 4e 55 4c 4c 20 61 6e 64 20 61 20 43 48 41 4e 47  NULL and a CHANG
1e080 45 53 45 54 5f 43 4f 4e 46 4c 49 43 54 20 63 6f  ESET_CONFLICT co
1e090 6e 66 6c 69 63 74 20 69 73 20 0a 2a 2a 20 65 6e  nflict is .** en
1e0a0 63 6f 75 6e 74 65 72 65 64 20 69 6e 76 6f 6b 65  countered invoke
1e0b0 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 20 68 61   the conflict ha
1e0c0 6e 64 6c 65 72 20 77 69 74 68 20 43 48 41 4e 47  ndler with CHANG
1e0d0 45 53 45 54 5f 43 4f 4e 53 54 52 41 49 4e 54 20  ESET_CONSTRAINT 
1e0e0 69 6e 73 74 65 61 64 2e 0a 2a 2a 20 4f 72 2c 20  instead..** Or, 
1e0f0 69 66 20 70 62 52 65 70 6c 61 63 65 20 69 73 20  if pbReplace is 
1e100 6e 6f 74 20 4e 55 4c 4c 2c 20 69 6e 76 6f 6b 65  not NULL, invoke
1e110 20 69 74 20 77 69 74 68 20 43 48 41 4e 47 45 53   it with CHANGES
1e120 45 54 5f 43 4f 4e 46 4c 49 43 54 2e 20 49 66 20  ET_CONFLICT. If 
1e130 73 75 63 68 0a 2a 2a 20 61 6e 20 69 6e 76 6f 63  such.** an invoc
1e140 61 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 53 51  ation returns SQ
1e150 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 52  LITE_CHANGESET_R
1e160 45 50 4c 41 43 45 2c 20 73 65 74 20 2a 70 62 52  EPLACE, set *pbR
1e170 65 70 6c 61 63 65 20 74 6f 20 74 72 75 65 0a 2a  eplace to true.*
1e180 2a 20 62 65 66 6f 72 65 20 72 65 74 72 79 69 6e  * before retryin
1e190 67 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65 20  g. In this case 
1e1a0 74 68 65 20 63 61 6c 6c 65 72 20 61 74 74 65 6d  the caller attem
1e1b0 70 74 73 20 74 6f 20 72 65 6d 6f 76 65 20 74 68  pts to remove th
1e1c0 65 20 63 6f 6e 66 6c 69 63 74 69 6e 67 0a 2a 2a  e conflicting.**
1e1d0 20 72 6f 77 20 62 65 66 6f 72 65 20 69 6e 76 6f   row before invo
1e1e0 6b 69 6e 67 20 74 68 69 73 20 66 75 6e 63 74 69  king this functi
1e1f0 6f 6e 20 61 67 61 69 6e 2c 20 74 68 69 73 20 74  on again, this t
1e200 69 6d 65 20 77 69 74 68 20 70 62 52 65 70 6c 61  ime with pbRepla
1e210 63 65 20 73 65 74 20 0a 2a 2a 20 74 6f 20 4e 55  ce set .** to NU
1e220 4c 4c 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 79  LL..**.** If any
1e230 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65   conflict handle
1e240 72 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45  r returns SQLITE
1e250 5f 43 48 41 4e 47 45 53 45 54 5f 41 42 4f 52 54  _CHANGESET_ABORT
1e260 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 0a  , this function.
1e270 2a 2a 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54  ** returns SQLIT
1e280 45 5f 41 42 4f 52 54 2e 20 4f 74 68 65 72 77 69  E_ABORT. Otherwi
1e290 73 65 2c 20 69 66 20 6e 6f 20 65 72 72 6f 72 20  se, if no error 
1e2a0 6f 63 63 75 72 73 2c 20 53 51 4c 49 54 45 5f 4f  occurs, SQLITE_O
1e2b0 4b 20 69 73 20 0a 2a 2a 20 72 65 74 75 72 6e 65  K is .** returne
1e2c0 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
1e2d0 20 73 65 73 73 69 6f 6e 41 70 70 6c 79 4f 6e 65   sessionApplyOne
1e2e0 4f 70 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 68  Op(.  sqlite3_ch
1e2f0 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a 70 49  angeset_iter *pI
1e300 74 65 72 2c 20 20 2f 2a 20 43 68 61 6e 67 65 73  ter,  /* Changes
1e310 65 74 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20  et iterator */. 
1e320 20 53 65 73 73 69 6f 6e 41 70 70 6c 79 43 74 78   SessionApplyCtx
1e330 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20 20   *p,            
1e340 20 2f 2a 20 63 68 61 6e 67 65 73 65 74 5f 61 70   /* changeset_ap
1e350 70 6c 79 28 29 20 63 6f 6e 74 65 78 74 20 2a 2f  ply() context */
1e360 0a 20 20 69 6e 74 28 2a 78 43 6f 6e 66 6c 69 63  .  int(*xConflic
1e370 74 29 28 76 6f 69 64 20 2a 2c 20 69 6e 74 2c 20  t)(void *, int, 
1e380 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65  sqlite3_changese
1e390 74 5f 69 74 65 72 20 2a 29 2c 0a 20 20 76 6f 69  t_iter *),.  voi
1e3a0 64 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20  d *pCtx,        
1e3b0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1e3c0 46 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 66  First argument f
1e3d0 6f 72 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 20  or the conflict 
1e3e0 68 61 6e 64 6c 65 72 20 2a 2f 0a 20 20 69 6e 74  handler */.  int
1e3f0 20 2a 70 62 52 65 70 6c 61 63 65 2c 20 20 20 20   *pbReplace,    
1e400 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1e410 4f 55 54 3a 20 54 72 75 65 20 74 6f 20 72 65 6d  OUT: True to rem
1e420 6f 76 65 20 50 4b 20 72 6f 77 20 61 6e 64 20 72  ove PK row and r
1e430 65 74 72 79 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  etry */.  int *p
1e440 62 52 65 74 72 79 20 20 20 20 20 20 20 20 20 20  bRetry          
1e450 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
1e460 3a 20 54 72 75 65 20 74 6f 20 72 65 74 72 79 2e  : True to retry.
1e470 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63   */.){.  const c
1e480 68 61 72 20 2a 7a 44 75 6d 6d 79 3b 0a 20 20 69  har *zDummy;.  i
1e490 6e 74 20 6f 70 3b 0a 20 20 69 6e 74 20 6e 43 6f  nt op;.  int nCo
1e4a0 6c 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  l;.  int rc = SQ
1e4b0 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 61 73 73 65  LITE_OK;..  asse
1e4c0 72 74 28 20 70 2d 3e 70 44 65 6c 65 74 65 20 26  rt( p->pDelete &
1e4d0 26 20 70 2d 3e 70 55 70 64 61 74 65 20 26 26 20  & p->pUpdate && 
1e4e0 70 2d 3e 70 49 6e 73 65 72 74 20 26 26 20 70 2d  p->pInsert && p-
1e4f0 3e 70 53 65 6c 65 63 74 20 29 3b 0a 20 20 61 73  >pSelect );.  as
1e500 73 65 72 74 28 20 70 2d 3e 61 7a 43 6f 6c 20 26  sert( p->azCol &
1e510 26 20 70 2d 3e 61 62 50 4b 20 29 3b 0a 20 20 61  & p->abPK );.  a
1e520 73 73 65 72 74 28 20 21 70 62 52 65 70 6c 61 63  ssert( !pbReplac
1e530 65 20 7c 7c 20 2a 70 62 52 65 70 6c 61 63 65 3d  e || *pbReplace=
1e540 3d 30 20 29 3b 0a 0a 20 20 73 71 6c 69 74 65 33  =0 );..  sqlite3
1e550 63 68 61 6e 67 65 73 65 74 5f 6f 70 28 70 49 74  changeset_op(pIt
1e560 65 72 2c 20 26 7a 44 75 6d 6d 79 2c 20 26 6e 43  er, &zDummy, &nC
1e570 6f 6c 2c 20 26 6f 70 2c 20 30 29 3b 0a 0a 20 20  ol, &op, 0);..  
1e580 69 66 28 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 44  if( op==SQLITE_D
1e590 45 4c 45 54 45 20 29 7b 0a 0a 20 20 20 20 2f 2a  ELETE ){..    /*
1e5a0 20 42 69 6e 64 20 76 61 6c 75 65 73 20 74 6f 20   Bind values to 
1e5b0 74 68 65 20 44 45 4c 45 54 45 20 73 74 61 74 65  the DELETE state
1e5c0 6d 65 6e 74 2e 20 49 66 20 63 6f 6e 66 6c 69 63  ment. If conflic
1e5d0 74 20 68 61 6e 64 6c 69 6e 67 20 69 73 20 72 65  t handling is re
1e5e0 71 75 69 72 65 64 2c 0a 20 20 20 20 2a 2a 20 62  quired,.    ** b
1e5f0 69 6e 64 20 76 61 6c 75 65 73 20 66 6f 72 20 61  ind values for a
1e600 6c 6c 20 63 6f 6c 75 6d 6e 73 20 61 6e 64 20 73  ll columns and s
1e610 65 74 20 62 6f 75 6e 64 20 76 61 72 69 61 62 6c  et bound variabl
1e620 65 20 28 6e 43 6f 6c 2b 31 29 20 74 6f 20 74 72  e (nCol+1) to tr
1e630 75 65 2e 0a 20 20 20 20 2a 2a 20 4f 72 2c 20 69  ue..    ** Or, i
1e640 66 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c  f conflict handl
1e650 69 6e 67 20 69 73 20 6e 6f 74 20 72 65 71 75 69  ing is not requi
1e660 72 65 64 2c 20 62 69 6e 64 20 6a 75 73 74 20 74  red, bind just t
1e670 68 65 20 50 4b 20 63 6f 6c 75 6d 6e 0a 20 20 20  he PK column.   
1e680 20 2a 2a 20 76 61 6c 75 65 73 20 61 6e 64 2c 20   ** values and, 
1e690 69 66 20 69 74 20 65 78 69 73 74 73 2c 20 73 65  if it exists, se
1e6a0 74 20 28 6e 43 6f 6c 2b 31 29 20 74 6f 20 66 61  t (nCol+1) to fa
1e6b0 6c 73 65 2e 20 43 6f 6e 66 6c 69 63 74 20 68 61  lse. Conflict ha
1e6c0 6e 64 6c 69 6e 67 0a 20 20 20 20 2a 2a 20 69 73  ndling.    ** is
1e6d0 20 6e 6f 74 20 72 65 71 75 69 72 65 64 20 69 66   not required if
1e6e0 3a 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20  :.    **.    ** 
1e6f0 20 20 2a 20 74 68 69 73 20 69 73 20 61 20 70 61    * this is a pa
1e700 74 63 68 73 65 74 2c 20 6f 72 0a 20 20 20 20 2a  tchset, or.    *
1e710 2a 20 20 20 2a 20 28 70 62 52 65 74 72 79 3d 3d  *   * (pbRetry==
1e720 30 29 2c 20 6f 72 0a 20 20 20 20 2a 2a 20 20 20  0), or.    **   
1e730 2a 20 61 6c 6c 20 63 6f 6c 75 6d 6e 73 20 6f 66  * all columns of
1e740 20 74 68 65 20 74 61 62 6c 65 20 61 72 65 20 50   the table are P
1e750 4b 20 63 6f 6c 75 6d 6e 73 20 28 69 6e 20 74 68  K columns (in th
1e760 69 73 20 63 61 73 65 20 74 68 65 72 65 20 69 73  is case there is
1e770 0a 20 20 20 20 2a 2a 20 20 20 20 20 6e 6f 20 28  .    **     no (
1e780 6e 43 6f 6c 2b 31 29 20 76 61 72 69 61 62 6c 65  nCol+1) variable
1e790 20 74 6f 20 62 69 6e 64 20 74 6f 29 2e 0a 20 20   to bind to)..  
1e7a0 20 20 2a 2f 0a 20 20 20 20 75 38 20 2a 61 62 50    */.    u8 *abP
1e7b0 4b 20 3d 20 28 70 49 74 65 72 2d 3e 62 50 61 74  K = (pIter->bPat
1e7c0 63 68 73 65 74 20 3f 20 70 2d 3e 61 62 50 4b 20  chset ? p->abPK 
1e7d0 3a 20 30 29 3b 0a 20 20 20 20 72 63 20 3d 20 73  : 0);.    rc = s
1e7e0 65 73 73 69 6f 6e 42 69 6e 64 52 6f 77 28 70 49  essionBindRow(pI
1e7f0 74 65 72 2c 20 73 71 6c 69 74 65 33 63 68 61 6e  ter, sqlite3chan
1e800 67 65 73 65 74 5f 6f 6c 64 2c 20 6e 43 6f 6c 2c  geset_old, nCol,
1e810 20 61 62 50 4b 2c 20 70 2d 3e 70 44 65 6c 65 74   abPK, p->pDelet
1e820 65 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  e);.    if( rc==
1e830 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 73 71 6c  SQLITE_OK && sql
1e840 69 74 65 33 5f 62 69 6e 64 5f 70 61 72 61 6d 65  ite3_bind_parame
1e850 74 65 72 5f 63 6f 75 6e 74 28 70 2d 3e 70 44 65  ter_count(p->pDe
1e860 6c 65 74 65 29 3e 6e 43 6f 6c 20 29 7b 0a 20 20  lete)>nCol ){.  
1e870 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
1e880 5f 62 69 6e 64 5f 69 6e 74 28 70 2d 3e 70 44 65  _bind_int(p->pDe
1e890 6c 65 74 65 2c 20 6e 43 6f 6c 2b 31 2c 20 28 70  lete, nCol+1, (p
1e8a0 62 52 65 74 72 79 3d 3d 30 20 7c 7c 20 61 62 50  bRetry==0 || abP
1e8b0 4b 29 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  K));.    }.    i
1e8c0 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
1e8d0 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
1e8e0 20 20 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28     sqlite3_step(
1e8f0 70 2d 3e 70 44 65 6c 65 74 65 29 3b 0a 20 20 20  p->pDelete);.   
1e900 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 72 65   rc = sqlite3_re
1e910 73 65 74 28 70 2d 3e 70 44 65 6c 65 74 65 29 3b  set(p->pDelete);
1e920 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
1e930 49 54 45 5f 4f 4b 20 26 26 20 73 71 6c 69 74 65  ITE_OK && sqlite
1e940 33 5f 63 68 61 6e 67 65 73 28 70 2d 3e 64 62 29  3_changes(p->db)
1e950 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20  ==0 ){.      rc 
1e960 3d 20 73 65 73 73 69 6f 6e 43 6f 6e 66 6c 69 63  = sessionConflic
1e970 74 48 61 6e 64 6c 65 72 28 0a 20 20 20 20 20 20  tHandler(.      
1e980 20 20 20 20 53 51 4c 49 54 45 5f 43 48 41 4e 47      SQLITE_CHANG
1e990 45 53 45 54 5f 44 41 54 41 2c 20 70 2c 20 70 49  ESET_DATA, p, pI
1e9a0 74 65 72 2c 20 78 43 6f 6e 66 6c 69 63 74 2c 20  ter, xConflict, 
1e9b0 70 43 74 78 2c 20 70 62 52 65 74 72 79 0a 20 20  pCtx, pbRetry.  
1e9c0 20 20 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65      );.    }else
1e9d0 20 69 66 28 20 28 72 63 26 30 78 66 66 29 3d 3d   if( (rc&0xff)==
1e9e0 53 51 4c 49 54 45 5f 43 4f 4e 53 54 52 41 49 4e  SQLITE_CONSTRAIN
1e9f0 54 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  T ){.      rc = 
1ea00 73 65 73 73 69 6f 6e 43 6f 6e 66 6c 69 63 74 48  sessionConflictH
1ea10 61 6e 64 6c 65 72 28 0a 20 20 20 20 20 20 20 20  andler(.        
1ea20 20 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53    SQLITE_CHANGES
1ea30 45 54 5f 43 4f 4e 46 4c 49 43 54 2c 20 70 2c 20  ET_CONFLICT, p, 
1ea40 70 49 74 65 72 2c 20 78 43 6f 6e 66 6c 69 63 74  pIter, xConflict
1ea50 2c 20 70 43 74 78 2c 20 30 0a 20 20 20 20 20 20  , pCtx, 0.      
1ea60 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 7d 65 6c 73  );.    }..  }els
1ea70 65 20 69 66 28 20 6f 70 3d 3d 53 51 4c 49 54 45  e if( op==SQLITE
1ea80 5f 55 50 44 41 54 45 20 29 7b 0a 20 20 20 20 69  _UPDATE ){.    i
1ea90 6e 74 20 69 3b 0a 0a 20 20 20 20 2f 2a 20 42 69  nt i;..    /* Bi
1eaa0 6e 64 20 76 61 6c 75 65 73 20 74 6f 20 74 68 65  nd values to the
1eab0 20 55 50 44 41 54 45 20 73 74 61 74 65 6d 65 6e   UPDATE statemen
1eac0 74 2e 20 2a 2f 0a 20 20 20 20 66 6f 72 28 69 3d  t. */.    for(i=
1ead0 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  0; rc==SQLITE_OK
1eae0 20 26 26 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29   && i<nCol; i++)
1eaf0 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
1eb00 76 61 6c 75 65 20 2a 70 4f 6c 64 20 3d 20 73 65  value *pOld = se
1eb10 73 73 69 6f 6e 43 68 61 6e 67 65 73 65 74 4f 6c  ssionChangesetOl
1eb20 64 28 70 49 74 65 72 2c 20 69 29 3b 0a 20 20 20  d(pIter, i);.   
1eb30 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65     sqlite3_value
1eb40 20 2a 70 4e 65 77 20 3d 20 73 65 73 73 69 6f 6e   *pNew = session
1eb50 43 68 61 6e 67 65 73 65 74 4e 65 77 28 70 49 74  ChangesetNew(pIt
1eb60 65 72 2c 20 69 29 3b 0a 0a 20 20 20 20 20 20 73  er, i);..      s
1eb70 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 28  qlite3_bind_int(
1eb80 70 2d 3e 70 55 70 64 61 74 65 2c 20 69 2a 33 2b  p->pUpdate, i*3+
1eb90 32 2c 20 21 21 70 4e 65 77 29 3b 0a 20 20 20 20  2, !!pNew);.    
1eba0 20 20 69 66 28 20 70 4f 6c 64 20 29 7b 0a 20 20    if( pOld ){.  
1ebb0 20 20 20 20 20 20 72 63 20 3d 20 73 65 73 73 69        rc = sessi
1ebc0 6f 6e 42 69 6e 64 56 61 6c 75 65 28 70 2d 3e 70  onBindValue(p->p
1ebd0 55 70 64 61 74 65 2c 20 69 2a 33 2b 31 2c 20 70  Update, i*3+1, p
1ebe0 4f 6c 64 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  Old);.      }.  
1ebf0 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
1ec00 54 45 5f 4f 4b 20 26 26 20 70 4e 65 77 20 29 7b  TE_OK && pNew ){
1ec10 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 65  .        rc = se
1ec20 73 73 69 6f 6e 42 69 6e 64 56 61 6c 75 65 28 70  ssionBindValue(p
1ec30 2d 3e 70 55 70 64 61 74 65 2c 20 69 2a 33 2b 33  ->pUpdate, i*3+3
1ec40 2c 20 70 4e 65 77 29 3b 0a 20 20 20 20 20 20 7d  , pNew);.      }
1ec50 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72  .    }.    if( r
1ec60 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
1ec70 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 62 69        sqlite3_bi
1ec80 6e 64 5f 69 6e 74 28 70 2d 3e 70 55 70 64 61 74  nd_int(p->pUpdat
1ec90 65 2c 20 6e 43 6f 6c 2a 33 2b 31 2c 20 70 62 52  e, nCol*3+1, pbR
1eca0 65 74 72 79 3d 3d 30 20 7c 7c 20 70 49 74 65 72  etry==0 || pIter
1ecb0 2d 3e 62 50 61 74 63 68 73 65 74 29 3b 0a 20 20  ->bPatchset);.  
1ecc0 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 21 3d    }.    if( rc!=
1ecd0 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
1ece0 72 6e 20 72 63 3b 0a 0a 20 20 20 20 2f 2a 20 41  rn rc;..    /* A
1ecf0 74 74 65 6d 70 74 20 74 68 65 20 55 50 44 41 54  ttempt the UPDAT
1ed00 45 2e 20 49 6e 20 74 68 65 20 63 61 73 65 20 6f  E. In the case o
1ed10 66 20 61 20 4e 4f 54 46 4f 55 4e 44 20 6f 72 20  f a NOTFOUND or 
1ed20 44 41 54 41 20 63 6f 6e 66 6c 69 63 74 2c 0a 20  DATA conflict,. 
1ed30 20 20 20 2a 2a 20 74 68 65 20 72 65 73 75 6c 74     ** the result
1ed40 20 77 69 6c 6c 20 62 65 20 53 51 4c 49 54 45 5f   will be SQLITE_
1ed50 4f 4b 20 77 69 74 68 20 30 20 72 6f 77 73 20 6d  OK with 0 rows m
1ed60 6f 64 69 66 69 65 64 2e 20 2a 2f 0a 20 20 20 20  odified. */.    
1ed70 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 2d 3e  sqlite3_step(p->
1ed80 70 55 70 64 61 74 65 29 3b 0a 20 20 20 20 72 63  pUpdate);.    rc
1ed90 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74   = sqlite3_reset
1eda0 28 70 2d 3e 70 55 70 64 61 74 65 29 3b 0a 0a 20  (p->pUpdate);.. 
1edb0 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
1edc0 45 5f 4f 4b 20 26 26 20 73 71 6c 69 74 65 33 5f  E_OK && sqlite3_
1edd0 63 68 61 6e 67 65 73 28 70 2d 3e 64 62 29 3d 3d  changes(p->db)==
1ede0 30 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 41 20  0 ){.      /* A 
1edf0 4e 4f 54 46 4f 55 4e 44 20 6f 72 20 44 41 54 41  NOTFOUND or DATA
1ee00 20 65 72 72 6f 72 2e 20 53 65 61 72 63 68 20 74   error. Search t
1ee10 68 65 20 74 61 62 6c 65 20 74 6f 20 73 65 65 20  he table to see 
1ee20 69 66 20 69 74 20 63 6f 6e 74 61 69 6e 73 0a 20  if it contains. 
1ee30 20 20 20 20 20 2a 2a 20 61 20 72 6f 77 20 77 69       ** a row wi
1ee40 74 68 20 61 20 6d 61 74 63 68 69 6e 67 20 70 72  th a matching pr
1ee50 69 6d 61 72 79 20 6b 65 79 2e 20 49 66 20 73 6f  imary key. If so
1ee60 2c 20 74 68 69 73 20 69 73 20 61 20 44 41 54 41  , this is a DATA
1ee70 20 63 6f 6e 66 6c 69 63 74 2e 0a 20 20 20 20 20   conflict..     
1ee80 20 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 69   ** Otherwise, i
1ee90 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20 70 72  f there is no pr
1eea0 69 6d 61 72 79 20 6b 65 79 20 6d 61 74 63 68 2c  imary key match,
1eeb0 20 69 74 20 69 73 20 61 20 4e 4f 54 46 4f 55 4e   it is a NOTFOUN
1eec0 44 2e 20 2a 2f 0a 0a 20 20 20 20 20 20 72 63 20  D. */..      rc 
1eed0 3d 20 73 65 73 73 69 6f 6e 43 6f 6e 66 6c 69 63  = sessionConflic
1eee0 74 48 61 6e 64 6c 65 72 28 0a 20 20 20 20 20 20  tHandler(.      
1eef0 20 20 20 20 53 51 4c 49 54 45 5f 43 48 41 4e 47      SQLITE_CHANG
1ef00 45 53 45 54 5f 44 41 54 41 2c 20 70 2c 20 70 49  ESET_DATA, p, pI
1ef10 74 65 72 2c 20 78 43 6f 6e 66 6c 69 63 74 2c 20  ter, xConflict, 
1ef20 70 43 74 78 2c 20 70 62 52 65 74 72 79 0a 20 20  pCtx, pbRetry.  
1ef30 20 20 20 20 29 3b 0a 0a 20 20 20 20 7d 65 6c 73      );..    }els
1ef40 65 20 69 66 28 20 28 72 63 26 30 78 66 66 29 3d  e if( (rc&0xff)=
1ef50 3d 53 51 4c 49 54 45 5f 43 4f 4e 53 54 52 41 49  =SQLITE_CONSTRAI
1ef60 4e 54 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 54  NT ){.      /* T
1ef70 68 69 73 20 69 73 20 61 6c 77 61 79 73 20 61 20  his is always a 
1ef80 43 4f 4e 53 54 52 41 49 4e 54 20 63 6f 6e 66 6c  CONSTRAINT confl
1ef90 69 63 74 2e 20 2a 2f 0a 20 20 20 20 20 20 72 63  ict. */.      rc
1efa0 20 3d 20 73 65 73 73 69 6f 6e 43 6f 6e 66 6c 69   = sessionConfli
1efb0 63 74 48 61 6e 64 6c 65 72 28 0a 20 20 20 20 20  ctHandler(.     
1efc0 20 20 20 20 20 53 51 4c 49 54 45 5f 43 48 41 4e       SQLITE_CHAN
1efd0 47 45 53 45 54 5f 43 4f 4e 46 4c 49 43 54 2c 20  GESET_CONFLICT, 
1efe0 70 2c 20 70 49 74 65 72 2c 20 78 43 6f 6e 66 6c  p, pIter, xConfl
1eff0 69 63 74 2c 20 70 43 74 78 2c 20 30 0a 20 20 20  ict, pCtx, 0.   
1f000 20 20 20 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 7d     );.    }..  }
1f010 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74  else{.    assert
1f020 28 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 53  ( op==SQLITE_INS
1f030 45 52 54 20 29 3b 0a 20 20 20 20 72 63 20 3d 20  ERT );.    rc = 
1f040 73 65 73 73 69 6f 6e 42 69 6e 64 52 6f 77 28 70  sessionBindRow(p
1f050 49 74 65 72 2c 20 73 71 6c 69 74 65 33 63 68 61  Iter, sqlite3cha
1f060 6e 67 65 73 65 74 5f 6e 65 77 2c 20 6e 43 6f 6c  ngeset_new, nCol
1f070 2c 20 30 2c 20 70 2d 3e 70 49 6e 73 65 72 74 29  , 0, p->pInsert)
1f080 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
1f090 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
1f0a0 20 72 63 3b 0a 0a 20 20 20 20 73 71 6c 69 74 65   rc;..    sqlite
1f0b0 33 5f 73 74 65 70 28 70 2d 3e 70 49 6e 73 65 72  3_step(p->pInser
1f0c0 74 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c  t);.    rc = sql
1f0d0 69 74 65 33 5f 72 65 73 65 74 28 70 2d 3e 70 49  ite3_reset(p->pI
1f0e0 6e 73 65 72 74 29 3b 0a 20 20 20 20 69 66 28 20  nsert);.    if( 
1f0f0 28 72 63 26 30 78 66 66 29 3d 3d 53 51 4c 49 54  (rc&0xff)==SQLIT
1f100 45 5f 43 4f 4e 53 54 52 41 49 4e 54 20 29 7b 0a  E_CONSTRAINT ){.
1f110 20 20 20 20 20 20 72 63 20 3d 20 73 65 73 73 69        rc = sessi
1f120 6f 6e 43 6f 6e 66 6c 69 63 74 48 61 6e 64 6c 65  onConflictHandle
1f130 72 28 0a 20 20 20 20 20 20 20 20 20 20 53 51 4c  r(.          SQL
1f140 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 43 4f  ITE_CHANGESET_CO
1f150 4e 46 4c 49 43 54 2c 20 70 2c 20 70 49 74 65 72  NFLICT, p, pIter
1f160 2c 20 78 43 6f 6e 66 6c 69 63 74 2c 20 70 43 74  , xConflict, pCt
1f170 78 2c 20 70 62 52 65 70 6c 61 63 65 0a 20 20 20  x, pbReplace.   
1f180 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a     );.    }.  }.
1f190 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
1f1a0 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74 20 74  ./*.** Attempt t
1f1b0 6f 20 61 70 70 6c 79 20 74 68 65 20 63 68 61 6e  o apply the chan
1f1c0 67 65 20 74 68 61 74 20 74 68 65 20 69 74 65 72  ge that the iter
1f1d0 61 74 6f 72 20 70 61 73 73 65 64 20 61 73 20 74  ator passed as t
1f1e0 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e  he first argumen
1f1f0 74 0a 2a 2a 20 63 75 72 72 65 6e 74 6c 79 20 70  t.** currently p
1f200 6f 69 6e 74 73 20 74 6f 20 74 6f 20 74 68 65 20  oints to to the 
1f210 64 61 74 61 62 61 73 65 2e 20 49 66 20 61 20 63  database. If a c
1f220 6f 6e 66 6c 69 63 74 20 69 73 20 65 6e 63 6f 75  onflict is encou
1f230 6e 74 65 72 65 64 2c 20 69 6e 76 6f 6b 65 0a 2a  ntered, invoke.*
1f240 2a 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 20 68  * the conflict h
1f250 61 6e 64 6c 65 72 20 63 61 6c 6c 62 61 63 6b 2e  andler callback.
1f260 0a 2a 2a 0a 2a 2a 20 54 68 65 20 64 69 66 66 65  .**.** The diffe
1f270 72 65 6e 63 65 20 62 65 74 77 65 65 6e 20 74 68  rence between th
1f280 69 73 20 66 75 6e 63 74 69 6f 6e 20 61 6e 64 20  is function and 
1f290 73 65 73 73 69 6f 6e 41 70 70 6c 79 4f 6e 65 28  sessionApplyOne(
1f2a0 29 20 69 73 20 74 68 61 74 20 74 68 69 73 0a 2a  ) is that this.*
1f2b0 2a 20 66 75 6e 63 74 69 6f 6e 20 68 61 6e 64 6c  * function handl
1f2c0 65 73 20 74 68 65 20 63 61 73 65 20 77 68 65 72  es the case wher
1f2d0 65 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 2d 68  e the conflict-h
1f2e0 61 6e 64 6c 65 72 20 69 73 20 69 6e 76 6f 6b 65  andler is invoke
1f2f0 64 20 61 6e 64 20 0a 2a 2a 20 72 65 74 75 72 6e  d and .** return
1f300 73 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53  s SQLITE_CHANGES
1f310 45 54 5f 52 45 50 4c 41 43 45 20 2d 20 69 6e 64  ET_REPLACE - ind
1f320 69 63 61 74 69 6e 67 20 74 68 61 74 20 74 68 65  icating that the
1f330 20 63 68 61 6e 67 65 20 73 68 6f 75 6c 64 20 62   change should b
1f340 65 0a 2a 2a 20 72 65 74 72 69 65 64 20 69 6e 20  e.** retried in 
1f350 73 6f 6d 65 20 6d 61 6e 6e 65 72 2e 0a 2a 2f 0a  some manner..*/.
1f360 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69  static int sessi
1f370 6f 6e 41 70 70 6c 79 4f 6e 65 57 69 74 68 52 65  onApplyOneWithRe
1f380 74 72 79 28 0a 20 20 73 71 6c 69 74 65 33 20 2a  try(.  sqlite3 *
1f390 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  db,             
1f3a0 20 20 20 20 20 20 20 2f 2a 20 41 70 70 6c 79 20         /* Apply 
1f3b0 63 68 61 6e 67 65 20 74 6f 20 22 6d 61 69 6e 22  change to "main"
1f3c0 20 64 62 20 6f 66 20 74 68 69 73 20 68 61 6e 64   db of this hand
1f3d0 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  le */.  sqlite3_
1f3e0 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a  changeset_iter *
1f3f0 70 49 74 65 72 2c 20 20 2f 2a 20 43 68 61 6e 67  pIter,  /* Chang
1f400 65 73 65 74 20 69 74 65 72 61 74 6f 72 20 74 6f  eset iterator to
1f410 20 72 65 61 64 20 63 68 61 6e 67 65 20 66 72 6f   read change fro
1f420 6d 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 41 70  m */.  SessionAp
1f430 70 6c 79 43 74 78 20 2a 70 41 70 70 6c 79 2c 20  plyCtx *pApply, 
1f440 20 20 20 20 20 20 20 2f 2a 20 41 70 70 6c 79 20         /* Apply 
1f450 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74  context */.  int
1f460 28 2a 78 43 6f 6e 66 6c 69 63 74 29 28 76 6f 69  (*xConflict)(voi
1f470 64 2a 2c 20 69 6e 74 2c 20 73 71 6c 69 74 65 33  d*, int, sqlite3
1f480 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 2a  _changeset_iter*
1f490 29 2c 0a 20 20 76 6f 69 64 20 2a 70 43 74 78 20  ),.  void *pCtx 
1f4a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f4b0 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 61 72       /* First ar
1f4c0 67 75 6d 65 6e 74 20 70 61 73 73 65 64 20 74 6f  gument passed to
1f4d0 20 78 43 6f 6e 66 6c 69 63 74 20 2a 2f 0a 29 7b   xConflict */.){
1f4e0 0a 20 20 69 6e 74 20 62 52 65 70 6c 61 63 65 20  .  int bReplace 
1f4f0 3d 20 30 3b 0a 20 20 69 6e 74 20 62 52 65 74 72  = 0;.  int bRetr
1f500 79 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 3b  y = 0;.  int rc;
1f510 0a 0a 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e  ..  rc = session
1f520 41 70 70 6c 79 4f 6e 65 4f 70 28 70 49 74 65 72  ApplyOneOp(pIter
1f530 2c 20 70 41 70 70 6c 79 2c 20 78 43 6f 6e 66 6c  , pApply, xConfl
1f540 69 63 74 2c 20 70 43 74 78 2c 20 26 62 52 65 70  ict, pCtx, &bRep
1f550 6c 61 63 65 2c 20 26 62 52 65 74 72 79 29 3b 0a  lace, &bRetry);.
1f560 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51    assert( rc==SQ
1f570 4c 49 54 45 5f 4f 4b 20 7c 7c 20 28 62 52 65 74  LITE_OK || (bRet
1f580 72 79 3d 3d 30 20 26 26 20 62 52 65 70 6c 61 63  ry==0 && bReplac
1f590 65 3d 3d 30 29 20 29 3b 0a 0a 20 20 2f 2a 20 49  e==0) );..  /* I
1f5a0 66 20 74 68 65 20 62 52 65 74 72 79 20 66 6c 61  f the bRetry fla
1f5b0 67 20 69 73 20 73 65 74 2c 20 74 68 65 20 63 68  g is set, the ch
1f5c0 61 6e 67 65 20 68 61 73 20 6e 6f 74 20 62 65 65  ange has not bee
1f5d0 6e 20 61 70 70 6c 69 65 64 20 64 75 65 20 74 6f  n applied due to
1f5e0 20 61 6e 0a 20 20 2a 2a 20 53 51 4c 49 54 45 5f   an.  ** SQLITE_
1f5f0 43 48 41 4e 47 45 53 45 54 5f 44 41 54 41 20 70  CHANGESET_DATA p
1f600 72 6f 62 6c 65 6d 20 28 69 2e 65 2e 20 74 68 69  roblem (i.e. thi
1f610 73 20 69 73 20 61 6e 20 55 50 44 41 54 45 20 6f  s is an UPDATE o
1f620 72 20 44 45 4c 45 54 45 20 61 6e 64 0a 20 20 2a  r DELETE and.  *
1f630 2a 20 61 20 72 6f 77 20 77 69 74 68 20 74 68 65  * a row with the
1f640 20 63 6f 72 72 65 63 74 20 50 4b 20 69 73 20 70   correct PK is p
1f650 72 65 73 65 6e 74 20 69 6e 20 74 68 65 20 64 62  resent in the db
1f660 2c 20 62 75 74 20 6f 6e 65 20 6f 72 20 6d 6f 72  , but one or mor
1f670 65 20 6f 74 68 65 72 0a 20 20 2a 2a 20 66 69 65  e other.  ** fie
1f680 6c 64 73 20 64 6f 20 6e 6f 74 20 63 6f 6e 74 61  lds do not conta
1f690 69 6e 20 74 68 65 20 65 78 70 65 63 74 65 64 20  in the expected 
1f6a0 76 61 6c 75 65 73 29 20 61 6e 64 20 74 68 65 20  values) and the 
1f6b0 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65 72  conflict handler
1f6c0 20 0a 20 20 2a 2a 20 72 65 74 75 72 6e 65 64 20   .  ** returned 
1f6d0 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54  SQLITE_CHANGESET
1f6e0 5f 52 45 50 4c 41 43 45 2e 20 49 6e 20 74 68 69  _REPLACE. In thi
1f6f0 73 20 63 61 73 65 20 72 65 74 72 79 20 74 68 65  s case retry the
1f700 20 6f 70 65 72 61 74 69 6f 6e 2c 0a 20 20 2a 2a   operation,.  **
1f710 20 62 75 74 20 70 61 73 73 20 4e 55 4c 4c 20 61   but pass NULL a
1f720 73 20 74 68 65 20 66 69 6e 61 6c 20 61 72 67 75  s the final argu
1f730 6d 65 6e 74 20 73 6f 20 74 68 61 74 20 73 65 73  ment so that ses
1f740 73 69 6f 6e 41 70 70 6c 79 4f 6e 65 4f 70 28 29  sionApplyOneOp()
1f750 20 69 67 6e 6f 72 65 73 0a 20 20 2a 2a 20 74 68   ignores.  ** th
1f760 65 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53  e SQLITE_CHANGES
1f770 45 54 5f 44 41 54 41 20 70 72 6f 62 6c 65 6d 2e  ET_DATA problem.
1f780 20 20 2a 2f 0a 20 20 69 66 28 20 62 52 65 74 72    */.  if( bRetr
1f790 79 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  y ){.    assert(
1f7a0 20 70 49 74 65 72 2d 3e 6f 70 3d 3d 53 51 4c 49   pIter->op==SQLI
1f7b0 54 45 5f 55 50 44 41 54 45 20 7c 7c 20 70 49 74  TE_UPDATE || pIt
1f7c0 65 72 2d 3e 6f 70 3d 3d 53 51 4c 49 54 45 5f 44  er->op==SQLITE_D
1f7d0 45 4c 45 54 45 20 29 3b 0a 20 20 20 20 72 63 20  ELETE );.    rc 
1f7e0 3d 20 73 65 73 73 69 6f 6e 41 70 70 6c 79 4f 6e  = sessionApplyOn
1f7f0 65 4f 70 28 70 49 74 65 72 2c 20 70 41 70 70 6c  eOp(pIter, pAppl
1f800 79 2c 20 78 43 6f 6e 66 6c 69 63 74 2c 20 70 43  y, xConflict, pC
1f810 74 78 2c 20 30 2c 20 30 29 3b 0a 20 20 7d 0a 0a  tx, 0, 0);.  }..
1f820 20 20 2f 2a 20 49 66 20 74 68 65 20 62 52 65 70    /* If the bRep
1f830 6c 61 63 65 20 66 6c 61 67 20 69 73 20 73 65 74  lace flag is set
1f840 2c 20 74 68 65 20 63 68 61 6e 67 65 20 69 73 20  , the change is 
1f850 61 6e 20 49 4e 53 45 52 54 20 74 68 61 74 20 68  an INSERT that h
1f860 61 73 20 6e 6f 74 0a 20 20 2a 2a 20 62 65 65 6e  as not.  ** been
1f870 20 70 65 72 66 6f 72 6d 65 64 20 62 65 63 61 75   performed becau
1f880 73 65 20 74 68 65 20 64 61 74 61 62 61 73 65 20  se the database 
1f890 61 6c 72 65 61 64 79 20 63 6f 6e 74 61 69 6e 73  already contains
1f8a0 20 61 20 72 6f 77 20 77 69 74 68 20 74 68 65 0a   a row with the.
1f8b0 20 20 2a 2a 20 73 70 65 63 69 66 69 65 64 20 70    ** specified p
1f8c0 72 69 6d 61 72 79 20 6b 65 79 20 61 6e 64 20 74  rimary key and t
1f8d0 68 65 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64  he conflict hand
1f8e0 6c 65 72 20 72 65 74 75 72 6e 65 64 0a 20 20 2a  ler returned.  *
1f8f0 2a 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53  * SQLITE_CHANGES
1f900 45 54 5f 52 45 50 4c 41 43 45 2e 20 49 6e 20 74  ET_REPLACE. In t
1f910 68 69 73 20 63 61 73 65 20 72 65 6d 6f 76 65 20  his case remove 
1f920 74 68 65 20 63 6f 6e 66 6c 69 63 74 69 6e 67 20  the conflicting 
1f930 72 6f 77 0a 20 20 2a 2a 20 62 65 66 6f 72 65 20  row.  ** before 
1f940 72 65 61 74 74 65 6d 70 74 69 6e 67 20 74 68 65  reattempting the
1f950 20 49 4e 53 45 52 54 2e 20 20 2a 2f 0a 20 20 65   INSERT.  */.  e
1f960 6c 73 65 20 69 66 28 20 62 52 65 70 6c 61 63 65  lse if( bReplace
1f970 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20   ){.    assert( 
1f980 70 49 74 65 72 2d 3e 6f 70 3d 3d 53 51 4c 49 54  pIter->op==SQLIT
1f990 45 5f 49 4e 53 45 52 54 20 29 3b 0a 20 20 20 20  E_INSERT );.    
1f9a0 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65  rc = sqlite3_exe
1f9b0 63 28 64 62 2c 20 22 53 41 56 45 50 4f 49 4e 54  c(db, "SAVEPOINT
1f9c0 20 72 65 70 6c 61 63 65 5f 6f 70 22 2c 20 30 2c   replace_op", 0,
1f9d0 20 30 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20   0, 0);.    if( 
1f9e0 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
1f9f0 0a 20 20 20 20 20 20 72 63 20 3d 20 73 65 73 73  .      rc = sess
1fa00 69 6f 6e 42 69 6e 64 52 6f 77 28 70 49 74 65 72  ionBindRow(pIter
1fa10 2c 20 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c  , .          sql
1fa20 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6e 65  ite3changeset_ne
1fa30 77 2c 20 70 41 70 70 6c 79 2d 3e 6e 43 6f 6c 2c  w, pApply->nCol,
1fa40 20 70 41 70 70 6c 79 2d 3e 61 62 50 4b 2c 20 70   pApply->abPK, p
1fa50 41 70 70 6c 79 2d 3e 70 44 65 6c 65 74 65 29 3b  Apply->pDelete);
1fa60 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 62  .      sqlite3_b
1fa70 69 6e 64 5f 69 6e 74 28 70 41 70 70 6c 79 2d 3e  ind_int(pApply->
1fa80 70 44 65 6c 65 74 65 2c 20 70 41 70 70 6c 79 2d  pDelete, pApply-
1fa90 3e 6e 43 6f 6c 2b 31 2c 20 31 29 3b 0a 20 20 20  >nCol+1, 1);.   
1faa0 20 7d 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53   }.    if( rc==S
1fab0 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
1fac0 20 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70    sqlite3_step(p
1fad0 41 70 70 6c 79 2d 3e 70 44 65 6c 65 74 65 29 3b  Apply->pDelete);
1fae0 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
1faf0 74 65 33 5f 72 65 73 65 74 28 70 41 70 70 6c 79  te3_reset(pApply
1fb00 2d 3e 70 44 65 6c 65 74 65 29 3b 0a 20 20 20 20  ->pDelete);.    
1fb10 7d 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  }.    if( rc==SQ
1fb20 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
1fb30 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 41 70 70   rc = sessionApp
1fb40 6c 79 4f 6e 65 4f 70 28 70 49 74 65 72 2c 20 70  lyOneOp(pIter, p
1fb50 41 70 70 6c 79 2c 20 78 43 6f 6e 66 6c 69 63 74  Apply, xConflict
1fb60 2c 20 70 43 74 78 2c 20 30 2c 20 30 29 3b 0a 20  , pCtx, 0, 0);. 
1fb70 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 3d     }.    if( rc=
1fb80 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
1fb90 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
1fba0 5f 65 78 65 63 28 64 62 2c 20 22 52 45 4c 45 41  _exec(db, "RELEA
1fbb0 53 45 20 72 65 70 6c 61 63 65 5f 6f 70 22 2c 20  SE replace_op", 
1fbc0 30 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 7d 0a  0, 0, 0);.    }.
1fbd0 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
1fbe0 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 72 79  ;.}../*.** Retry
1fbf0 20 74 68 65 20 63 68 61 6e 67 65 73 20 61 63 63   the changes acc
1fc00 75 6d 75 6c 61 74 65 64 20 69 6e 20 74 68 65 20  umulated in the 
1fc10 70 41 70 70 6c 79 2d 3e 63 6f 6e 73 74 72 61 69  pApply->constrai
1fc20 6e 74 73 20 62 75 66 66 65 72 2e 0a 2a 2f 0a 73  nts buffer..*/.s
1fc30 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f  tatic int sessio
1fc40 6e 52 65 74 72 79 43 6f 6e 73 74 72 61 69 6e 74  nRetryConstraint
1fc50 73 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  s(.  sqlite3 *db
1fc60 2c 20 0a 20 20 69 6e 74 20 62 50 61 74 63 68 73  , .  int bPatchs
1fc70 65 74 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  et,.  const char
1fc80 20 2a 7a 54 61 62 2c 0a 20 20 53 65 73 73 69 6f   *zTab,.  Sessio
1fc90 6e 41 70 70 6c 79 43 74 78 20 2a 70 41 70 70 6c  nApplyCtx *pAppl
1fca0 79 2c 0a 20 20 69 6e 74 28 2a 78 43 6f 6e 66 6c  y,.  int(*xConfl
1fcb0 69 63 74 29 28 76 6f 69 64 2a 2c 20 69 6e 74 2c  ict)(void*, int,
1fcc0 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73   sqlite3_changes
1fcd0 65 74 5f 69 74 65 72 2a 29 2c 0a 20 20 76 6f 69  et_iter*),.  voi
1fce0 64 20 2a 70 43 74 78 20 20 20 20 20 20 20 20 20  d *pCtx         
1fcf0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1fd00 46 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 70  First argument p
1fd10 61 73 73 65 64 20 74 6f 20 78 43 6f 6e 66 6c 69  assed to xConfli
1fd20 63 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  ct */.){.  int r
1fd30 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a  c = SQLITE_OK;..
1fd40 20 20 77 68 69 6c 65 28 20 70 41 70 70 6c 79 2d    while( pApply-
1fd50 3e 63 6f 6e 73 74 72 61 69 6e 74 73 2e 6e 42 75  >constraints.nBu
1fd60 66 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  f ){.    sqlite3
1fd70 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20  _changeset_iter 
1fd80 2a 70 49 74 65 72 32 20 3d 20 30 3b 0a 20 20 20  *pIter2 = 0;.   
1fd90 20 53 65 73 73 69 6f 6e 42 75 66 66 65 72 20 63   SessionBuffer c
1fda0 6f 6e 73 20 3d 20 70 41 70 70 6c 79 2d 3e 63 6f  ons = pApply->co
1fdb0 6e 73 74 72 61 69 6e 74 73 3b 0a 20 20 20 20 6d  nstraints;.    m
1fdc0 65 6d 73 65 74 28 26 70 41 70 70 6c 79 2d 3e 63  emset(&pApply->c
1fdd0 6f 6e 73 74 72 61 69 6e 74 73 2c 20 30 2c 20 73  onstraints, 0, s
1fde0 69 7a 65 6f 66 28 53 65 73 73 69 6f 6e 42 75 66  izeof(SessionBuf
1fdf0 66 65 72 29 29 3b 0a 0a 20 20 20 20 72 63 20 3d  fer));..    rc =
1fe00 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65   sessionChangese
1fe10 74 53 74 61 72 74 28 26 70 49 74 65 72 32 2c 20  tStart(&pIter2, 
1fe20 30 2c 20 30 2c 20 63 6f 6e 73 2e 6e 42 75 66 2c  0, 0, cons.nBuf,
1fe30 20 63 6f 6e 73 2e 61 42 75 66 29 3b 0a 20 20 20   cons.aBuf);.   
1fe40 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
1fe50 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  OK ){.      int 
1fe60 6e 42 79 74 65 20 3d 20 32 2a 70 41 70 70 6c 79  nByte = 2*pApply
1fe70 2d 3e 6e 43 6f 6c 2a 73 69 7a 65 6f 66 28 73 71  ->nCol*sizeof(sq
1fe80 6c 69 74 65 33 5f 76 61 6c 75 65 2a 29 3b 0a 20  lite3_value*);. 
1fe90 20 20 20 20 20 69 6e 74 20 72 63 32 3b 0a 20 20       int rc2;.  
1fea0 20 20 20 20 70 49 74 65 72 32 2d 3e 62 50 61 74      pIter2->bPat
1feb0 63 68 73 65 74 20 3d 20 62 50 61 74 63 68 73 65  chset = bPatchse
1fec0 74 3b 0a 20 20 20 20 20 20 70 49 74 65 72 32 2d  t;.      pIter2-
1fed0 3e 7a 54 61 62 20 3d 20 28 63 68 61 72 2a 29 7a  >zTab = (char*)z
1fee0 54 61 62 3b 0a 20 20 20 20 20 20 70 49 74 65 72  Tab;.      pIter
1fef0 32 2d 3e 6e 43 6f 6c 20 3d 20 70 41 70 70 6c 79  2->nCol = pApply
1ff00 2d 3e 6e 43 6f 6c 3b 0a 20 20 20 20 20 20 70 49  ->nCol;.      pI
1ff10 74 65 72 32 2d 3e 61 62 50 4b 20 3d 20 70 41 70  ter2->abPK = pAp
1ff20 70 6c 79 2d 3e 61 62 50 4b 3b 0a 20 20 20 20 20  ply->abPK;.     
1ff30 20 73 65 73 73 69 6f 6e 42 75 66 66 65 72 47 72   sessionBufferGr
1ff40 6f 77 28 26 70 49 74 65 72 32 2d 3e 74 62 6c 68  ow(&pIter2->tblh
1ff50 64 72 2c 20 6e 42 79 74 65 2c 20 26 72 63 29 3b  dr, nByte, &rc);
1ff60 0a 20 20 20 20 20 20 70 49 74 65 72 32 2d 3e 61  .      pIter2->a
1ff70 70 56 61 6c 75 65 20 3d 20 28 73 71 6c 69 74 65  pValue = (sqlite
1ff80 33 5f 76 61 6c 75 65 2a 2a 29 70 49 74 65 72 32  3_value**)pIter2
1ff90 2d 3e 74 62 6c 68 64 72 2e 61 42 75 66 3b 0a 20  ->tblhdr.aBuf;. 
1ffa0 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
1ffb0 49 54 45 5f 4f 4b 20 29 20 6d 65 6d 73 65 74 28  ITE_OK ) memset(
1ffc0 70 49 74 65 72 32 2d 3e 61 70 56 61 6c 75 65 2c  pIter2->apValue,
1ffd0 20 30 2c 20 6e 42 79 74 65 29 3b 0a 0a 20 20 20   0, nByte);..   
1ffe0 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51     while( rc==SQ
1fff0 4c 49 54 45 5f 4f 4b 20 26 26 20 53 51 4c 49 54  LITE_OK && SQLIT
20000 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33 63 68  E_ROW==sqlite3ch
20010 61 6e 67 65 73 65 74 5f 6e 65 78 74 28 70 49 74  angeset_next(pIt
20020 65 72 32 29 20 29 7b 0a 20 20 20 20 20 20 20 20  er2) ){.        
20030 72 63 20 3d 20 73 65 73 73 69 6f 6e 41 70 70 6c  rc = sessionAppl
20040 79 4f 6e 65 57 69 74 68 52 65 74 72 79 28 64 62  yOneWithRetry(db
20050 2c 20 70 49 74 65 72 32 2c 20 70 41 70 70 6c 79  , pIter2, pApply
20060 2c 20 78 43 6f 6e 66 6c 69 63 74 2c 20 70 43 74  , xConflict, pCt
20070 78 29 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20  x);.      }..   
20080 20 20 20 72 63 32 20 3d 20 73 71 6c 69 74 65 33     rc2 = sqlite3
20090 63 68 61 6e 67 65 73 65 74 5f 66 69 6e 61 6c 69  changeset_finali
200a0 7a 65 28 70 49 74 65 72 32 29 3b 0a 20 20 20 20  ze(pIter2);.    
200b0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
200c0 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63 32 3b 0a  _OK ) rc = rc2;.
200d0 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74      }.    assert
200e0 28 20 70 41 70 70 6c 79 2d 3e 62 44 65 66 65 72  ( pApply->bDefer
200f0 43 6f 6e 73 74 72 61 69 6e 74 73 20 7c 7c 20 70  Constraints || p
20100 41 70 70 6c 79 2d 3e 63 6f 6e 73 74 72 61 69 6e  Apply->constrain
20110 74 73 2e 6e 42 75 66 3d 3d 30 20 29 3b 0a 0a 20  ts.nBuf==0 );.. 
20120 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
20130 63 6f 6e 73 2e 61 42 75 66 29 3b 0a 20 20 20 20  cons.aBuf);.    
20140 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
20150 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 69  K ) break;.    i
20160 66 28 20 70 41 70 70 6c 79 2d 3e 63 6f 6e 73 74  f( pApply->const
20170 72 61 69 6e 74 73 2e 6e 42 75 66 3e 3d 63 6f 6e  raints.nBuf>=con
20180 73 2e 6e 42 75 66 20 29 7b 0a 20 20 20 20 20 20  s.nBuf ){.      
20190 2f 2a 20 4e 6f 20 70 72 6f 67 72 65 73 73 20 77  /* No progress w
201a0 61 73 20 6d 61 64 65 20 6f 6e 20 74 68 65 20 6c  as made on the l
201b0 61 73 74 20 72 6f 75 6e 64 2e 20 2a 2f 0a 20 20  ast round. */.  
201c0 20 20 20 20 70 41 70 70 6c 79 2d 3e 62 44 65 66      pApply->bDef
201d0 65 72 43 6f 6e 73 74 72 61 69 6e 74 73 20 3d 20  erConstraints = 
201e0 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  0;.    }.  }..  
201f0 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
20200 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20 70 49 74  .** Argument pIt
20210 65 72 20 69 73 20 61 20 63 68 61 6e 67 65 73 65  er is a changese
20220 74 20 69 74 65 72 61 74 6f 72 20 74 68 61 74 20  t iterator that 
20230 68 61 73 20 62 65 65 6e 20 69 6e 69 74 69 61 6c  has been initial
20240 69 7a 65 64 2c 20 62 75 74 0a 2a 2a 20 6e 6f 74  ized, but.** not
20250 20 79 65 74 20 70 61 73 73 65 64 20 74 6f 20 73   yet passed to s
20260 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
20270 6e 65 78 74 28 29 2e 20 54 68 69 73 20 66 75 6e  next(). This fun
20280 63 74 69 6f 6e 20 61 70 70 6c 69 65 73 20 74 68  ction applies th
20290 65 20 0a 2a 2a 20 63 68 61 6e 67 65 73 65 74 20  e .** changeset 
202a0 74 6f 20 74 68 65 20 6d 61 69 6e 20 64 61 74 61  to the main data
202b0 62 61 73 65 20 61 74 74 61 63 68 65 64 20 74 6f  base attached to
202c0 20 68 61 6e 64 6c 65 20 22 64 62 22 2e 20 54 68   handle "db". Th
202d0 65 20 73 75 70 70 6c 69 65 64 0a 2a 2a 20 63 6f  e supplied.** co
202e0 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65 72 20 63  nflict handler c
202f0 61 6c 6c 62 61 63 6b 20 69 73 20 69 6e 76 6f 6b  allback is invok
20300 65 64 20 74 6f 20 72 65 73 6f 6c 76 65 20 61 6e  ed to resolve an
20310 79 20 63 6f 6e 66 6c 69 63 74 73 20 65 6e 63 6f  y conflicts enco
20320 75 6e 74 65 72 65 64 0a 2a 2a 20 77 68 69 6c 65  untered.** while
20330 20 61 70 70 6c 79 69 6e 67 20 74 68 65 20 63 68   applying the ch
20340 61 6e 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ange..*/.static 
20350 69 6e 74 20 73 65 73 73 69 6f 6e 43 68 61 6e 67  int sessionChang
20360 65 73 65 74 41 70 70 6c 79 28 0a 20 20 73 71 6c  esetApply(.  sql
20370 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20  ite3 *db,       
20380 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
20390 41 70 70 6c 79 20 63 68 61 6e 67 65 20 74 6f 20  Apply change to 
203a0 22 6d 61 69 6e 22 20 64 62 20 6f 66 20 74 68 69  "main" db of thi
203b0 73 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 73 71  s handle */.  sq
203c0 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f  lite3_changeset_
203d0 69 74 65 72 20 2a 70 49 74 65 72 2c 20 20 2f 2a  iter *pIter,  /*
203e0 20 43 68 61 6e 67 65 73 65 74 20 74 6f 20 61 70   Changeset to ap
203f0 70 6c 79 20 2a 2f 0a 20 20 69 6e 74 28 2a 78 46  ply */.  int(*xF
20400 69 6c 74 65 72 29 28 0a 20 20 20 20 76 6f 69 64  ilter)(.    void
20410 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20   *pCtx,         
20420 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 70            /* Cop
20430 79 20 6f 66 20 73 69 78 74 68 20 61 72 67 20 74  y of sixth arg t
20440 6f 20 5f 61 70 70 6c 79 28 29 20 2a 2f 0a 20 20  o _apply() */.  
20450 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54    const char *zT
20460 61 62 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ab              
20470 2f 2a 20 54 61 62 6c 65 20 6e 61 6d 65 20 2a 2f  /* Table name */
20480 0a 20 20 29 2c 0a 20 20 69 6e 74 28 2a 78 43 6f  .  ),.  int(*xCo
20490 6e 66 6c 69 63 74 29 28 0a 20 20 20 20 76 6f 69  nflict)(.    voi
204a0 64 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20  d *pCtx,        
204b0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
204c0 70 79 20 6f 66 20 66 69 66 74 68 20 61 72 67 20  py of fifth arg 
204d0 74 6f 20 5f 61 70 70 6c 79 28 29 20 2a 2f 0a 20  to _apply() */. 
204e0 20 20 20 69 6e 74 20 65 43 6f 6e 66 6c 69 63 74     int eConflict
204f0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
20500 20 2f 2a 20 44 41 54 41 2c 20 4d 49 53 53 49 4e   /* DATA, MISSIN
20510 47 2c 20 43 4f 4e 46 4c 49 43 54 2c 20 43 4f 4e  G, CONFLICT, CON
20520 53 54 52 41 49 4e 54 20 2a 2f 0a 20 20 20 20 73  STRAINT */.    s
20530 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74  qlite3_changeset
20540 5f 69 74 65 72 20 2a 70 20 20 20 20 20 2f 2a 20  _iter *p     /* 
20550 48 61 6e 64 6c 65 20 64 65 73 63 72 69 62 69 6e  Handle describin
20560 67 20 63 68 61 6e 67 65 20 61 6e 64 20 63 6f 6e  g change and con
20570 66 6c 69 63 74 20 2a 2f 0a 20 20 29 2c 0a 20 20  flict */.  ),.  
20580 76 6f 69 64 20 2a 70 43 74 78 20 20 20 20 20 20  void *pCtx      
20590 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
205a0 2f 2a 20 46 69 72 73 74 20 61 72 67 75 6d 65 6e  /* First argumen
205b0 74 20 70 61 73 73 65 64 20 74 6f 20 78 43 6f 6e  t passed to xCon
205c0 66 6c 69 63 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e  flict */.){.  in
205d0 74 20 73 63 68 65 6d 61 4d 69 73 6d 61 74 63 68  t schemaMismatch
205e0 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 3b 20   = 0;.  int rc; 
205f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20600 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
20610 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 63 6f 6e 73  n code */.  cons
20620 74 20 63 68 61 72 20 2a 7a 54 61 62 20 3d 20 30  t char *zTab = 0
20630 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e  ;           /* N
20640 61 6d 65 20 6f 66 20 63 75 72 72 65 6e 74 20 74  ame of current t
20650 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 54  able */.  int nT
20660 61 62 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  ab = 0;         
20670 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 73            /* Res
20680 75 6c 74 20 6f 66 20 73 71 6c 69 74 65 33 53 74  ult of sqlite3St
20690 72 6c 65 6e 33 30 28 7a 54 61 62 29 20 2a 2f 0a  rlen30(zTab) */.
206a0 20 20 53 65 73 73 69 6f 6e 41 70 70 6c 79 43 74    SessionApplyCt
206b0 78 20 73 41 70 70 6c 79 3b 20 20 20 20 20 20 20  x sApply;       
206c0 20 20 2f 2a 20 63 68 61 6e 67 65 73 65 74 5f 61    /* changeset_a
206d0 70 70 6c 79 28 29 20 63 6f 6e 74 65 78 74 20 6f  pply() context o
206e0 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e 74 20 62  bject */.  int b
206f0 50 61 74 63 68 73 65 74 3b 0a 0a 20 20 61 73 73  Patchset;..  ass
20700 65 72 74 28 20 78 43 6f 6e 66 6c 69 63 74 21 3d  ert( xConflict!=
20710 30 20 29 3b 0a 0a 20 20 70 49 74 65 72 2d 3e 69  0 );..  pIter->i
20720 6e 2e 62 4e 6f 44 69 73 63 61 72 64 20 3d 20 31  n.bNoDiscard = 1
20730 3b 0a 20 20 6d 65 6d 73 65 74 28 26 73 41 70 70  ;.  memset(&sApp
20740 6c 79 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73 41  ly, 0, sizeof(sA
20750 70 70 6c 79 29 29 3b 0a 20 20 73 71 6c 69 74 65  pply));.  sqlite
20760 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 73 71  3_mutex_enter(sq
20770 6c 69 74 65 33 5f 64 62 5f 6d 75 74 65 78 28 64  lite3_db_mutex(d
20780 62 29 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69  b));.  rc = sqli
20790 74 65 33 5f 65 78 65 63 28 64 62 2c 20 22 53 41  te3_exec(db, "SA
207a0 56 45 50 4f 49 4e 54 20 63 68 61 6e 67 65 73 65  VEPOINT changese
207b0 74 5f 61 70 70 6c 79 22 2c 20 30 2c 20 30 2c 20  t_apply", 0, 0, 
207c0 30 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  0);.  if( rc==SQ
207d0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
207e0 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63  c = sqlite3_exec
207f0 28 64 62 2c 20 22 50 52 41 47 4d 41 20 64 65 66  (db, "PRAGMA def
20800 65 72 5f 66 6f 72 65 69 67 6e 5f 6b 65 79 73 20  er_foreign_keys 
20810 3d 20 31 22 2c 20 30 2c 20 30 2c 20 30 29 3b 0a  = 1", 0, 0, 0);.
20820 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 72 63 3d    }.  while( rc=
20830 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 53 51  =SQLITE_OK && SQ
20840 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65  LITE_ROW==sqlite
20850 33 63 68 61 6e 67 65 73 65 74 5f 6e 65 78 74 28  3changeset_next(
20860 70 49 74 65 72 29 20 29 7b 0a 20 20 20 20 69 6e  pIter) ){.    in
20870 74 20 6e 43 6f 6c 3b 0a 20 20 20 20 69 6e 74 20  t nCol;.    int 
20880 6f 70 3b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68  op;.    const ch
20890 61 72 20 2a 7a 4e 65 77 3b 0a 20 20 20 20 0a 20  ar *zNew;.    . 
208a0 20 20 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65     sqlite3change
208b0 73 65 74 5f 6f 70 28 70 49 74 65 72 2c 20 26 7a  set_op(pIter, &z
208c0 4e 65 77 2c 20 26 6e 43 6f 6c 2c 20 26 6f 70 2c  New, &nCol, &op,
208d0 20 30 29 3b 0a 0a 20 20 20 20 69 66 28 20 7a 54   0);..    if( zT
208e0 61 62 3d 3d 30 20 7c 7c 20 73 71 6c 69 74 65 33  ab==0 || sqlite3
208f0 5f 73 74 72 6e 69 63 6d 70 28 7a 4e 65 77 2c 20  _strnicmp(zNew, 
20900 7a 54 61 62 2c 20 6e 54 61 62 2b 31 29 20 29 7b  zTab, nTab+1) ){
20910 0a 20 20 20 20 20 20 75 38 20 2a 61 62 50 4b 3b  .      u8 *abPK;
20920 0a 0a 20 20 20 20 20 20 72 63 20 3d 20 73 65 73  ..      rc = ses
20930 73 69 6f 6e 52 65 74 72 79 43 6f 6e 73 74 72 61  sionRetryConstra
20940 69 6e 74 73 28 0a 20 20 20 20 20 20 20 20 20 20  ints(.          
20950 64 62 2c 20 70 49 74 65 72 2d 3e 62 50 61 74 63  db, pIter->bPatc
20960 68 73 65 74 2c 20 7a 54 61 62 2c 20 26 73 41 70  hset, zTab, &sAp
20970 70 6c 79 2c 20 78 43 6f 6e 66 6c 69 63 74 2c 20  ply, xConflict, 
20980 70 43 74 78 0a 20 20 20 20 20 20 29 3b 0a 20 20  pCtx.      );.  
20990 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
209a0 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 0a  TE_OK ) break;..
209b0 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
209c0 65 65 28 28 63 68 61 72 2a 29 73 41 70 70 6c 79  ee((char*)sApply
209d0 2e 61 7a 43 6f 6c 29 3b 20 20 2f 2a 20 63 61 73  .azCol);  /* cas
209e0 74 20 77 6f 72 6b 73 20 61 72 6f 75 6e 64 20 56  t works around V
209f0 43 2b 2b 20 62 75 67 20 2a 2f 0a 20 20 20 20 20  C++ bug */.     
20a00 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
20a10 65 28 73 41 70 70 6c 79 2e 70 44 65 6c 65 74 65  e(sApply.pDelete
20a20 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  );.      sqlite3
20a30 5f 66 69 6e 61 6c 69 7a 65 28 73 41 70 70 6c 79  _finalize(sApply
20a40 2e 70 55 70 64 61 74 65 29 3b 20 0a 20 20 20 20  .pUpdate); .    
20a50 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
20a60 7a 65 28 73 41 70 70 6c 79 2e 70 49 6e 73 65 72  ze(sApply.pInser
20a70 74 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  t);.      sqlite
20a80 33 5f 66 69 6e 61 6c 69 7a 65 28 73 41 70 70 6c  3_finalize(sAppl
20a90 79 2e 70 53 65 6c 65 63 74 29 3b 0a 20 20 20 20  y.pSelect);.    
20aa0 20 20 6d 65 6d 73 65 74 28 26 73 41 70 70 6c 79    memset(&sApply
20ab0 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73 41 70 70  , 0, sizeof(sApp
20ac0 6c 79 29 29 3b 0a 20 20 20 20 20 20 73 41 70 70  ly));.      sApp
20ad0 6c 79 2e 64 62 20 3d 20 64 62 3b 0a 20 20 20 20  ly.db = db;.    
20ae0 20 20 73 41 70 70 6c 79 2e 62 44 65 66 65 72 43    sApply.bDeferC
20af0 6f 6e 73 74 72 61 69 6e 74 73 20 3d 20 31 3b 0a  onstraints = 1;.
20b00 0a 20 20 20 20 20 20 2f 2a 20 49 66 20 61 6e 20  .      /* If an 
20b10 78 46 69 6c 74 65 72 28 29 20 63 61 6c 6c 62 61  xFilter() callba
20b20 63 6b 20 77 61 73 20 73 70 65 63 69 66 69 65 64  ck was specified
20b30 2c 20 69 6e 76 6f 6b 65 20 69 74 20 6e 6f 77 2e  , invoke it now.
20b40 20 49 66 20 74 68 65 20 0a 20 20 20 20 20 20 2a   If the .      *
20b50 2a 20 78 46 69 6c 74 65 72 20 63 61 6c 6c 62 61  * xFilter callba
20b60 63 6b 20 72 65 74 75 72 6e 73 20 7a 65 72 6f 2c  ck returns zero,
20b70 20 73 6b 69 70 20 74 68 69 73 20 74 61 62 6c 65   skip this table
20b80 2e 20 49 66 20 69 74 20 72 65 74 75 72 6e 73 0a  . If it returns.
20b90 20 20 20 20 20 20 2a 2a 20 6e 6f 6e 2d 7a 65 72        ** non-zer
20ba0 6f 2c 20 70 72 6f 63 65 65 64 2e 20 2a 2f 0a 20  o, proceed. */. 
20bb0 20 20 20 20 20 73 63 68 65 6d 61 4d 69 73 6d 61       schemaMisma
20bc0 74 63 68 20 3d 20 28 78 46 69 6c 74 65 72 20 26  tch = (xFilter &
20bd0 26 20 28 30 3d 3d 78 46 69 6c 74 65 72 28 70 43  & (0==xFilter(pC
20be0 74 78 2c 20 7a 4e 65 77 29 29 29 3b 0a 20 20 20  tx, zNew)));.   
20bf0 20 20 20 69 66 28 20 73 63 68 65 6d 61 4d 69 73     if( schemaMis
20c00 6d 61 74 63 68 20 29 7b 0a 20 20 20 20 20 20 20  match ){.       
20c10 20 7a 54 61 62 20 3d 20 73 71 6c 69 74 65 33 5f   zTab = sqlite3_
20c20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 4e  mprintf("%s", zN
20c30 65 77 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  ew);.        if(
20c40 20 7a 54 61 62 3d 3d 30 20 29 7b 0a 20 20 20 20   zTab==0 ){.    
20c50 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
20c60 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 20  E_NOMEM;.       
20c70 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
20c80 20 20 7d 0a 20 20 20 20 20 20 20 20 6e 54 61 62    }.        nTab
20c90 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28 7a   = (int)strlen(z
20ca0 54 61 62 29 3b 0a 20 20 20 20 20 20 20 20 73 41  Tab);.        sA
20cb0 70 70 6c 79 2e 61 7a 43 6f 6c 20 3d 20 28 63 6f  pply.azCol = (co
20cc0 6e 73 74 20 63 68 61 72 20 2a 2a 29 7a 54 61 62  nst char **)zTab
20cd0 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
20ce0 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 63 68         sqlite3ch
20cf0 61 6e 67 65 73 65 74 5f 70 6b 28 70 49 74 65 72  angeset_pk(pIter
20d00 2c 20 26 61 62 50 4b 2c 20 30 29 3b 0a 20 20 20  , &abPK, 0);.   
20d10 20 20 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f       rc = sessio
20d20 6e 54 61 62 6c 65 49 6e 66 6f 28 0a 20 20 20 20  nTableInfo(.    
20d30 20 20 20 20 20 20 20 20 64 62 2c 20 22 6d 61 69          db, "mai
20d40 6e 22 2c 20 7a 4e 65 77 2c 20 26 73 41 70 70 6c  n", zNew, &sAppl
20d50 79 2e 6e 43 6f 6c 2c 20 26 7a 54 61 62 2c 20 26  y.nCol, &zTab, &
20d60 73 41 70 70 6c 79 2e 61 7a 43 6f 6c 2c 20 26 73  sApply.azCol, &s
20d70 41 70 70 6c 79 2e 61 62 50 4b 0a 20 20 20 20 20  Apply.abPK.     
20d80 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 69 66     );.        if
20d90 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
20da0 29 20 62 72 65 61 6b 3b 0a 20 20 0a 20 20 20 20  ) break;.  .    
20db0 20 20 20 20 69 66 28 20 73 41 70 70 6c 79 2e 6e      if( sApply.n
20dc0 43 6f 6c 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  Col==0 ){.      
20dd0 20 20 20 20 73 63 68 65 6d 61 4d 69 73 6d 61 74      schemaMismat
20de0 63 68 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20  ch = 1;.        
20df0 20 20 73 71 6c 69 74 65 33 5f 6c 6f 67 28 53 51    sqlite3_log(SQ
20e00 4c 49 54 45 5f 53 43 48 45 4d 41 2c 20 0a 20 20  LITE_SCHEMA, .  
20e10 20 20 20 20 20 20 20 20 20 20 20 20 22 73 71 6c              "sql
20e20 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 61 70  ite3changeset_ap
20e30 70 6c 79 28 29 3a 20 6e 6f 20 73 75 63 68 20 74  ply(): no such t
20e40 61 62 6c 65 3a 20 25 73 22 2c 20 7a 54 61 62 0a  able: %s", zTab.
20e50 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20            );.   
20e60 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 65       }.        e
20e70 6c 73 65 20 69 66 28 20 73 41 70 70 6c 79 2e 6e  lse if( sApply.n
20e80 43 6f 6c 21 3d 6e 43 6f 6c 20 29 7b 0a 20 20 20  Col!=nCol ){.   
20e90 20 20 20 20 20 20 20 73 63 68 65 6d 61 4d 69 73         schemaMis
20ea0 6d 61 74 63 68 20 3d 20 31 3b 0a 20 20 20 20 20  match = 1;.     
20eb0 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6c 6f 67       sqlite3_log
20ec0 28 53 51 4c 49 54 45 5f 53 43 48 45 4d 41 2c 20  (SQLITE_SCHEMA, 
20ed0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22  .              "
20ee0 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
20ef0 5f 61 70 70 6c 79 28 29 3a 20 74 61 62 6c 65 20  _apply(): table 
20f00 25 73 20 68 61 73 20 25 64 20 63 6f 6c 75 6d 6e  %s has %d column
20f10 73 2c 20 65 78 70 65 63 74 65 64 20 25 64 22 2c  s, expected %d",
20f20 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20   .              
20f30 7a 54 61 62 2c 20 73 41 70 70 6c 79 2e 6e 43 6f  zTab, sApply.nCo
20f40 6c 2c 20 6e 43 6f 6c 0a 20 20 20 20 20 20 20 20  l, nCol.        
20f50 20 20 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20    );.        }. 
20f60 20 20 20 20 20 20 20 65 6c 73 65 20 69 66 28 20         else if( 
20f70 6d 65 6d 63 6d 70 28 73 41 70 70 6c 79 2e 61 62  memcmp(sApply.ab
20f80 50 4b 2c 20 61 62 50 4b 2c 20 6e 43 6f 6c 29 21  PK, abPK, nCol)!
20f90 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  =0 ){.          
20fa0 73 63 68 65 6d 61 4d 69 73 6d 61 74 63 68 20 3d  schemaMismatch =
20fb0 20 31 3b 0a 20 20 20 20 20 20 20 20 20 20 73 71   1;.          sq
20fc0 6c 69 74 65 33 5f 6c 6f 67 28 53 51 4c 49 54 45  lite3_log(SQLITE
20fd0 5f 53 43 48 45 4d 41 2c 20 22 73 71 6c 69 74 65  _SCHEMA, "sqlite
20fe0 33 63 68 61 6e 67 65 73 65 74 5f 61 70 70 6c 79  3changeset_apply
20ff0 28 29 3a 20 22 0a 20 20 20 20 20 20 20 20 20 20  (): ".          
21000 20 20 20 20 22 70 72 69 6d 61 72 79 20 6b 65 79      "primary key
21010 20 6d 69 73 6d 61 74 63 68 20 66 6f 72 20 74 61   mismatch for ta
21020 62 6c 65 20 25 73 22 2c 20 7a 54 61 62 0a 20 20  ble %s", zTab.  
21030 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20          );.     
21040 20 20 20 7d 0a 20 20 20 20 20 20 20 20 65 6c 73     }.        els
21050 65 20 69 66 28 20 0a 20 20 20 20 20 20 20 20 20  e if( .         
21060 20 20 20 28 72 63 20 3d 20 73 65 73 73 69 6f 6e     (rc = session
21070 53 65 6c 65 63 74 52 6f 77 28 64 62 2c 20 7a 54  SelectRow(db, zT
21080 61 62 2c 20 26 73 41 70 70 6c 79 29 29 0a 20 20  ab, &sApply)).  
21090 20 20 20 20 20 20 20 7c 7c 20 28 72 63 20 3d 20         || (rc = 
210a0 73 65 73 73 69 6f 6e 55 70 64 61 74 65 52 6f 77  sessionUpdateRow
210b0 28 64 62 2c 20 7a 54 61 62 2c 20 26 73 41 70 70  (db, zTab, &sApp
210c0 6c 79 29 29 0a 20 20 20 20 20 20 20 20 20 7c 7c  ly)).         ||
210d0 20 28 72 63 20 3d 20 73 65 73 73 69 6f 6e 44 65   (rc = sessionDe
210e0 6c 65 74 65 52 6f 77 28 64 62 2c 20 7a 54 61 62  leteRow(db, zTab
210f0 2c 20 26 73 41 70 70 6c 79 29 29 0a 20 20 20 20  , &sApply)).    
21100 20 20 20 20 20 7c 7c 20 28 72 63 20 3d 20 73 65       || (rc = se
21110 73 73 69 6f 6e 49 6e 73 65 72 74 52 6f 77 28 64  ssionInsertRow(d
21120 62 2c 20 7a 54 61 62 2c 20 26 73 41 70 70 6c 79  b, zTab, &sApply
21130 29 29 0a 20 20 20 20 20 20 20 20 29 7b 0a 20 20  )).        ){.  
21140 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
21150 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
21160 20 6e 54 61 62 20 3d 20 73 71 6c 69 74 65 33 53   nTab = sqlite3S
21170 74 72 6c 65 6e 33 30 28 7a 54 61 62 29 3b 0a 20  trlen30(zTab);. 
21180 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
21190 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20 69 73    /* If there is
211a0 20 61 20 73 63 68 65 6d 61 20 6d 69 73 6d 61 74   a schema mismat
211b0 63 68 20 6f 6e 20 74 68 65 20 63 75 72 72 65 6e  ch on the curren
211c0 74 20 74 61 62 6c 65 2c 20 70 72 6f 63 65 65 64  t table, proceed
211d0 20 74 6f 20 74 68 65 0a 20 20 20 20 2a 2a 20 6e   to the.    ** n
211e0 65 78 74 20 63 68 61 6e 67 65 2e 20 41 20 6c 6f  ext change. A lo
211f0 67 20 6d 65 73 73 61 67 65 20 68 61 73 20 61 6c  g message has al
21200 72 65 61 64 79 20 62 65 65 6e 20 69 73 73 75 65  ready been issue
21210 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 73 63  d. */.    if( sc
21220 68 65 6d 61 4d 69 73 6d 61 74 63 68 20 29 20 63  hemaMismatch ) c
21230 6f 6e 74 69 6e 75 65 3b 0a 0a 20 20 20 20 72 63  ontinue;..    rc
21240 20 3d 20 73 65 73 73 69 6f 6e 41 70 70 6c 79 4f   = sessionApplyO
21250 6e 65 57 69 74 68 52 65 74 72 79 28 64 62 2c 20  neWithRetry(db, 
21260 70 49 74 65 72 2c 20 26 73 41 70 70 6c 79 2c 20  pIter, &sApply, 
21270 78 43 6f 6e 66 6c 69 63 74 2c 20 70 43 74 78 29  xConflict, pCtx)
21280 3b 0a 20 20 7d 0a 0a 20 20 62 50 61 74 63 68 73  ;.  }..  bPatchs
21290 65 74 20 3d 20 70 49 74 65 72 2d 3e 62 50 61 74  et = pIter->bPat
212a0 63 68 73 65 74 3b 0a 20 20 69 66 28 20 72 63 3d  chset;.  if( rc=
212b0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
212c0 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 63 68    rc = sqlite3ch
212d0 61 6e 67 65 73 65 74 5f 66 69 6e 61 6c 69 7a 65  angeset_finalize
212e0 28 70 49 74 65 72 29 3b 0a 20 20 7d 65 6c 73 65  (pIter);.  }else
212f0 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 63 68 61  {.    sqlite3cha
21300 6e 67 65 73 65 74 5f 66 69 6e 61 6c 69 7a 65 28  ngeset_finalize(
21310 70 49 74 65 72 29 3b 0a 20 20 7d 0a 0a 20 20 69  pIter);.  }..  i
21320 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
21330 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 65 73   ){.    rc = ses
21340 73 69 6f 6e 52 65 74 72 79 43 6f 6e 73 74 72 61  sionRetryConstra
21350 69 6e 74 73 28 64 62 2c 20 62 50 61 74 63 68 73  ints(db, bPatchs
21360 65 74 2c 20 7a 54 61 62 2c 20 26 73 41 70 70 6c  et, zTab, &sAppl
21370 79 2c 20 78 43 6f 6e 66 6c 69 63 74 2c 20 70 43  y, xConflict, pC
21380 74 78 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  tx);.  }..  if( 
21390 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
213a0 0a 20 20 20 20 69 6e 74 20 6e 46 6b 2c 20 6e 6f  .    int nFk, no
213b0 74 55 73 65 64 3b 0a 20 20 20 20 73 71 6c 69 74  tUsed;.    sqlit
213c0 65 33 5f 64 62 5f 73 74 61 74 75 73 28 64 62 2c  e3_db_status(db,
213d0 20 53 51 4c 49 54 45 5f 44 42 53 54 41 54 55 53   SQLITE_DBSTATUS
213e0 5f 44 45 46 45 52 52 45 44 5f 46 4b 53 2c 20 26  _DEFERRED_FKS, &
213f0 6e 46 6b 2c 20 26 6e 6f 74 55 73 65 64 2c 20 30  nFk, &notUsed, 0
21400 29 3b 0a 20 20 20 20 69 66 28 20 6e 46 6b 21 3d  );.    if( nFk!=
21410 30 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72  0 ){.      int r
21420 65 73 20 3d 20 53 51 4c 49 54 45 5f 43 48 41 4e  es = SQLITE_CHAN
21430 47 45 53 45 54 5f 41 42 4f 52 54 3b 0a 20 20 20  GESET_ABORT;.   
21440 20 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67     sqlite3_chang
21450 65 73 65 74 5f 69 74 65 72 20 73 49 74 65 72 3b  eset_iter sIter;
21460 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28 26 73  .      memset(&s
21470 49 74 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28  Iter, 0, sizeof(
21480 73 49 74 65 72 29 29 3b 0a 20 20 20 20 20 20 73  sIter));.      s
21490 49 74 65 72 2e 6e 43 6f 6c 20 3d 20 6e 46 6b 3b  Iter.nCol = nFk;
214a0 0a 20 20 20 20 20 20 72 65 73 20 3d 20 78 43 6f  .      res = xCo
214b0 6e 66 6c 69 63 74 28 70 43 74 78 2c 20 53 51 4c  nflict(pCtx, SQL
214c0 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 46 4f  ITE_CHANGESET_FO
214d0 52 45 49 47 4e 5f 4b 45 59 2c 20 26 73 49 74 65  REIGN_KEY, &sIte
214e0 72 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 65  r);.      if( re
214f0 73 21 3d 53 51 4c 49 54 45 5f 43 48 41 4e 47 45  s!=SQLITE_CHANGE
21500 53 45 54 5f 4f 4d 49 54 20 29 7b 0a 20 20 20 20  SET_OMIT ){.    
21510 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
21520 43 4f 4e 53 54 52 41 49 4e 54 3b 0a 20 20 20 20  CONSTRAINT;.    
21530 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20    }.    }.  }.  
21540 73 71 6c 69 74 65 33 5f 65 78 65 63 28 64 62 2c  sqlite3_exec(db,
21550 20 22 50 52 41 47 4d 41 20 64 65 66 65 72 5f 66   "PRAGMA defer_f
21560 6f 72 65 69 67 6e 5f 6b 65 79 73 20 3d 20 30 22  oreign_keys = 0"
21570 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 0a 20 20 69  , 0, 0, 0);..  i
21580 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
21590 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   ){.    rc = sql
215a0 69 74 65 33 5f 65 78 65 63 28 64 62 2c 20 22 52  ite3_exec(db, "R
215b0 45 4c 45 41 53 45 20 63 68 61 6e 67 65 73 65 74  ELEASE changeset
215c0 5f 61 70 70 6c 79 22 2c 20 30 2c 20 30 2c 20 30  _apply", 0, 0, 0
215d0 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
215e0 73 71 6c 69 74 65 33 5f 65 78 65 63 28 64 62 2c  sqlite3_exec(db,
215f0 20 22 52 4f 4c 4c 42 41 43 4b 20 54 4f 20 63 68   "ROLLBACK TO ch
21600 61 6e 67 65 73 65 74 5f 61 70 70 6c 79 22 2c 20  angeset_apply", 
21610 30 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 73 71  0, 0, 0);.    sq
21620 6c 69 74 65 33 5f 65 78 65 63 28 64 62 2c 20 22  lite3_exec(db, "
21630 52 45 4c 45 41 53 45 20 63 68 61 6e 67 65 73 65  RELEASE changese
21640 74 5f 61 70 70 6c 79 22 2c 20 30 2c 20 30 2c 20  t_apply", 0, 0, 
21650 30 29 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74  0);.  }..  sqlit
21660 65 33 5f 66 69 6e 61 6c 69 7a 65 28 73 41 70 70  e3_finalize(sApp
21670 6c 79 2e 70 49 6e 73 65 72 74 29 3b 0a 20 20 73  ly.pInsert);.  s
21680 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
21690 73 41 70 70 6c 79 2e 70 44 65 6c 65 74 65 29 3b  sApply.pDelete);
216a0 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c  .  sqlite3_final
216b0 69 7a 65 28 73 41 70 70 6c 79 2e 70 55 70 64 61  ize(sApply.pUpda
216c0 74 65 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  te);.  sqlite3_f
216d0 69 6e 61 6c 69 7a 65 28 73 41 70 70 6c 79 2e 70  inalize(sApply.p
216e0 53 65 6c 65 63 74 29 3b 0a 20 20 73 71 6c 69 74  Select);.  sqlit
216f0 65 33 5f 66 72 65 65 28 28 63 68 61 72 2a 29 73  e3_free((char*)s
21700 41 70 70 6c 79 2e 61 7a 43 6f 6c 29 3b 20 20 2f  Apply.azCol);  /
21710 2a 20 63 61 73 74 20 77 6f 72 6b 73 20 61 72 6f  * cast works aro
21720 75 6e 64 20 56 43 2b 2b 20 62 75 67 20 2a 2f 0a  und VC++ bug */.
21730 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 28    sqlite3_free((
21740 63 68 61 72 2a 29 73 41 70 70 6c 79 2e 63 6f 6e  char*)sApply.con
21750 73 74 72 61 69 6e 74 73 2e 61 42 75 66 29 3b 0a  straints.aBuf);.
21760 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
21770 6c 65 61 76 65 28 73 71 6c 69 74 65 33 5f 64 62  leave(sqlite3_db
21780 5f 6d 75 74 65 78 28 64 62 29 29 3b 0a 20 20 72  _mutex(db));.  r
21790 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
217a0 2a 2a 20 41 70 70 6c 79 20 74 68 65 20 63 68 61  ** Apply the cha
217b0 6e 67 65 73 65 74 20 70 61 73 73 65 64 20 76 69  ngeset passed vi
217c0 61 20 70 43 68 61 6e 67 65 73 65 74 2f 6e 43 68  a pChangeset/nCh
217d0 61 6e 67 65 73 65 74 20 74 6f 20 74 68 65 20 6d  angeset to the m
217e0 61 69 6e 20 64 61 74 61 62 61 73 65 0a 2a 2a 20  ain database.** 
217f0 61 74 74 61 63 68 65 64 20 74 6f 20 68 61 6e 64  attached to hand
21800 6c 65 20 22 64 62 22 2e 20 49 6e 76 6f 6b 65 20  le "db". Invoke 
21810 74 68 65 20 73 75 70 70 6c 69 65 64 20 63 6f 6e  the supplied con
21820 66 6c 69 63 74 20 68 61 6e 64 6c 65 72 20 63 61  flict handler ca
21830 6c 6c 62 61 63 6b 0a 2a 2a 20 74 6f 20 72 65 73  llback.** to res
21840 6f 6c 76 65 20 61 6e 79 20 63 6f 6e 66 6c 69 63  olve any conflic
21850 74 73 20 65 6e 63 6f 75 6e 74 65 72 65 64 20 77  ts encountered w
21860 68 69 6c 65 20 61 70 70 6c 79 69 6e 67 20 74 68  hile applying th
21870 65 20 63 68 61 6e 67 65 2e 0a 2a 2f 0a 69 6e 74  e change..*/.int
21880 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
21890 74 5f 61 70 70 6c 79 28 0a 20 20 73 71 6c 69 74  t_apply(.  sqlit
218a0 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20  e3 *db,         
218b0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 70             /* Ap
218c0 70 6c 79 20 63 68 61 6e 67 65 20 74 6f 20 22 6d  ply change to "m
218d0 61 69 6e 22 20 64 62 20 6f 66 20 74 68 69 73 20  ain" db of this 
218e0 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20  handle */.  int 
218f0 6e 43 68 61 6e 67 65 73 65 74 2c 20 20 20 20 20  nChangeset,     
21900 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
21910 69 7a 65 20 6f 66 20 63 68 61 6e 67 65 73 65 74  ize of changeset
21920 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 76   in bytes */.  v
21930 6f 69 64 20 2a 70 43 68 61 6e 67 65 73 65 74 2c  oid *pChangeset,
21940 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
21950 2a 20 43 68 61 6e 67 65 73 65 74 20 62 6c 6f 62  * Changeset blob
21960 20 2a 2f 0a 20 20 69 6e 74 28 2a 78 46 69 6c 74   */.  int(*xFilt
21970 65 72 29 28 0a 20 20 20 20 76 6f 69 64 20 2a 70  er)(.    void *p
21980 43 74 78 2c 20 20 20 20 20 20 20 20 20 20 20 20  Ctx,            
21990 20 20 20 20 20 20 20 2f 2a 20 43 6f 70 79 20 6f         /* Copy o
219a0 66 20 73 69 78 74 68 20 61 72 67 20 74 6f 20 5f  f sixth arg to _
219b0 61 70 70 6c 79 28 29 20 2a 2f 0a 20 20 20 20 63  apply() */.    c
219c0 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 62 20  onst char *zTab 
219d0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
219e0 54 61 62 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20 20  Table name */.  
219f0 29 2c 0a 20 20 69 6e 74 28 2a 78 43 6f 6e 66 6c  ),.  int(*xConfl
21a00 69 63 74 29 28 0a 20 20 20 20 76 6f 69 64 20 2a  ict)(.    void *
21a10 70 43 74 78 2c 20 20 20 20 20 20 20 20 20 20 20  pCtx,           
21a20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 70 79 20          /* Copy 
21a30 6f 66 20 66 69 66 74 68 20 61 72 67 20 74 6f 20  of fifth arg to 
21a40 5f 61 70 70 6c 79 28 29 20 2a 2f 0a 20 20 20 20  _apply() */.    
21a50 69 6e 74 20 65 43 6f 6e 66 6c 69 63 74 2c 20 20  int eConflict,  
21a60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
21a70 20 44 41 54 41 2c 20 4d 49 53 53 49 4e 47 2c 20   DATA, MISSING, 
21a80 43 4f 4e 46 4c 49 43 54 2c 20 43 4f 4e 53 54 52  CONFLICT, CONSTR
21a90 41 49 4e 54 20 2a 2f 0a 20 20 20 20 73 71 6c 69  AINT */.    sqli
21aa0 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74  te3_changeset_it
21ab0 65 72 20 2a 70 20 20 20 20 20 2f 2a 20 48 61 6e  er *p     /* Han
21ac0 64 6c 65 20 64 65 73 63 72 69 62 69 6e 67 20 63  dle describing c
21ad0 68 61 6e 67 65 20 61 6e 64 20 63 6f 6e 66 6c 69  hange and confli
21ae0 63 74 20 2a 2f 0a 20 20 29 2c 0a 20 20 76 6f 69  ct */.  ),.  voi
21af0 64 20 2a 70 43 74 78 20 20 20 20 20 20 20 20 20  d *pCtx         
21b00 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
21b10 46 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 70  First argument p
21b20 61 73 73 65 64 20 74 6f 20 78 43 6f 6e 66 6c 69  assed to xConfli
21b30 63 74 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69 74  ct */.){.  sqlit
21b40 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65  e3_changeset_ite
21b50 72 20 2a 70 49 74 65 72 3b 20 20 2f 2a 20 49 74  r *pIter;  /* It
21b60 65 72 61 74 6f 72 20 74 6f 20 73 6b 69 70 20 74  erator to skip t
21b70 68 72 6f 75 67 68 20 63 68 61 6e 67 65 73 65 74  hrough changeset
21b80 20 2a 2f 20 20 0a 20 20 69 6e 74 20 72 63 20 3d   */  .  int rc =
21b90 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
21ba0 74 5f 73 74 61 72 74 28 26 70 49 74 65 72 2c 20  t_start(&pIter, 
21bb0 6e 43 68 61 6e 67 65 73 65 74 2c 20 70 43 68 61  nChangeset, pCha
21bc0 6e 67 65 73 65 74 29 3b 0a 20 20 69 66 28 20 72  ngeset);.  if( r
21bd0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
21be0 20 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e      rc = session
21bf0 43 68 61 6e 67 65 73 65 74 41 70 70 6c 79 28 64  ChangesetApply(d
21c00 62 2c 20 70 49 74 65 72 2c 20 78 46 69 6c 74 65  b, pIter, xFilte
21c10 72 2c 20 78 43 6f 6e 66 6c 69 63 74 2c 20 70 43  r, xConflict, pC
21c20 74 78 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  tx);.  }.  retur
21c30 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  n rc;.}../*.** A
21c40 70 70 6c 79 20 74 68 65 20 63 68 61 6e 67 65 73  pply the changes
21c50 65 74 20 70 61 73 73 65 64 20 76 69 61 20 78 49  et passed via xI
21c60 6e 70 75 74 2f 70 49 6e 20 74 6f 20 74 68 65 20  nput/pIn to the 
21c70 6d 61 69 6e 20 64 61 74 61 62 61 73 65 0a 2a 2a  main database.**
21c80 20 61 74 74 61 63 68 65 64 20 74 6f 20 68 61 6e   attached to han
21c90 64 6c 65 20 22 64 62 22 2e 20 49 6e 76 6f 6b 65  dle "db". Invoke
21ca0 20 74 68 65 20 73 75 70 70 6c 69 65 64 20 63 6f   the supplied co
21cb0 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65 72 20 63  nflict handler c
21cc0 61 6c 6c 62 61 63 6b 0a 2a 2a 20 74 6f 20 72 65  allback.** to re
21cd0 73 6f 6c 76 65 20 61 6e 79 20 63 6f 6e 66 6c 69  solve any confli
21ce0 63 74 73 20 65 6e 63 6f 75 6e 74 65 72 65 64 20  cts encountered 
21cf0 77 68 69 6c 65 20 61 70 70 6c 79 69 6e 67 20 74  while applying t
21d00 68 65 20 63 68 61 6e 67 65 2e 0a 2a 2f 0a 69 6e  he change..*/.in
21d10 74 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  t sqlite3changes
21d20 65 74 5f 61 70 70 6c 79 5f 73 74 72 6d 28 0a 20  et_apply_strm(. 
21d30 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20   sqlite3 *db,   
21d40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21d50 20 2f 2a 20 41 70 70 6c 79 20 63 68 61 6e 67 65   /* Apply change
21d60 20 74 6f 20 22 6d 61 69 6e 22 20 64 62 20 6f 66   to "main" db of
21d70 20 74 68 69 73 20 68 61 6e 64 6c 65 20 2a 2f 0a   this handle */.
21d80 20 20 69 6e 74 20 28 2a 78 49 6e 70 75 74 29 28    int (*xInput)(
21d90 76 6f 69 64 20 2a 70 49 6e 2c 20 76 6f 69 64 20  void *pIn, void 
21da0 2a 70 44 61 74 61 2c 20 69 6e 74 20 2a 70 6e 44  *pData, int *pnD
21db0 61 74 61 29 2c 20 2f 2a 20 49 6e 70 75 74 20 66  ata), /* Input f
21dc0 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69  unction */.  voi
21dd0 64 20 2a 70 49 6e 2c 20 20 20 20 20 20 20 20 20  d *pIn,         
21de0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21df0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21e00 20 2f 2a 20 46 69 72 73 74 20 61 72 67 20 66 6f   /* First arg fo
21e10 72 20 78 49 6e 70 75 74 20 2a 2f 0a 20 20 69 6e  r xInput */.  in
21e20 74 28 2a 78 46 69 6c 74 65 72 29 28 0a 20 20 20  t(*xFilter)(.   
21e30 20 76 6f 69 64 20 2a 70 43 74 78 2c 20 20 20 20   void *pCtx,    
21e40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
21e50 2a 20 43 6f 70 79 20 6f 66 20 73 69 78 74 68 20  * Copy of sixth 
21e60 61 72 67 20 74 6f 20 5f 61 70 70 6c 79 28 29 20  arg to _apply() 
21e70 2a 2f 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61  */.    const cha
21e80 72 20 2a 7a 54 61 62 20 20 20 20 20 20 20 20 20  r *zTab         
21e90 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20 6e 61       /* Table na
21ea0 6d 65 20 2a 2f 0a 20 20 29 2c 0a 20 20 69 6e 74  me */.  ),.  int
21eb0 28 2a 78 43 6f 6e 66 6c 69 63 74 29 28 0a 20 20  (*xConflict)(.  
21ec0 20 20 76 6f 69 64 20 2a 70 43 74 78 2c 20 20 20    void *pCtx,   
21ed0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21ee0 2f 2a 20 43 6f 70 79 20 6f 66 20 73 69 78 74 68  /* Copy of sixth
21ef0 20 61 72 67 20 74 6f 20 5f 61 70 70 6c 79 28 29   arg to _apply()
21f00 20 2a 2f 0a 20 20 20 20 69 6e 74 20 65 43 6f 6e   */.    int eCon
21f10 66 6c 69 63 74 2c 20 20 20 20 20 20 20 20 20 20  flict,          
21f20 20 20 20 20 20 20 2f 2a 20 44 41 54 41 2c 20 4d        /* DATA, M
21f30 49 53 53 49 4e 47 2c 20 43 4f 4e 46 4c 49 43 54  ISSING, CONFLICT
21f40 2c 20 43 4f 4e 53 54 52 41 49 4e 54 20 2a 2f 0a  , CONSTRAINT */.
21f50 20 20 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e      sqlite3_chan
21f60 67 65 73 65 74 5f 69 74 65 72 20 2a 70 20 20 20  geset_iter *p   
21f70 20 20 2f 2a 20 48 61 6e 64 6c 65 20 64 65 73 63    /* Handle desc
21f80 72 69 62 69 6e 67 20 63 68 61 6e 67 65 20 61 6e  ribing change an
21f90 64 20 63 6f 6e 66 6c 69 63 74 20 2a 2f 0a 20 20  d conflict */.  
21fa0 29 2c 0a 20 20 76 6f 69 64 20 2a 70 43 74 78 20  ),.  void *pCtx 
21fb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21fc0 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 61 72       /* First ar
21fd0 67 75 6d 65 6e 74 20 70 61 73 73 65 64 20 74 6f  gument passed to
21fe0 20 78 43 6f 6e 66 6c 69 63 74 20 2a 2f 0a 29 7b   xConflict */.){
21ff0 0a 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67  .  sqlite3_chang
22000 65 73 65 74 5f 69 74 65 72 20 2a 70 49 74 65 72  eset_iter *pIter
22010 3b 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 74  ;  /* Iterator t
22020 6f 20 73 6b 69 70 20 74 68 72 6f 75 67 68 20 63  o skip through c
22030 68 61 6e 67 65 73 65 74 20 2a 2f 20 20 0a 20 20  hangeset */  .  
22040 69 6e 74 20 72 63 20 3d 20 73 71 6c 69 74 65 33  int rc = sqlite3
22050 63 68 61 6e 67 65 73 65 74 5f 73 74 61 72 74 5f  changeset_start_
22060 73 74 72 6d 28 26 70 49 74 65 72 2c 20 78 49 6e  strm(&pIter, xIn
22070 70 75 74 2c 20 70 49 6e 29 3b 0a 20 20 69 66 28  put, pIn);.  if(
22080 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
22090 7b 0a 20 20 20 20 72 63 20 3d 20 73 65 73 73 69  {.    rc = sessi
220a0 6f 6e 43 68 61 6e 67 65 73 65 74 41 70 70 6c 79  onChangesetApply
220b0 28 64 62 2c 20 70 49 74 65 72 2c 20 78 46 69 6c  (db, pIter, xFil
220c0 74 65 72 2c 20 78 43 6f 6e 66 6c 69 63 74 2c 20  ter, xConflict, 
220d0 70 43 74 78 29 3b 0a 20 20 7d 0a 20 20 72 65 74  pCtx);.  }.  ret
220e0 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
220f0 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 67   sqlite3_changeg
22100 72 6f 75 70 20 68 61 6e 64 6c 65 2e 0a 2a 2f 0a  roup handle..*/.
22110 73 74 72 75 63 74 20 73 71 6c 69 74 65 33 5f 63  struct sqlite3_c
22120 68 61 6e 67 65 67 72 6f 75 70 20 7b 0a 20 20 69  hangegroup {.  i
22130 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
22140 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
22150 2a 20 45 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a  * Error code */.
22160 20 20 69 6e 74 20 62 50 61 74 63 68 3b 20 20 20    int bPatch;   
22170 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22180 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 61 63 63    /* True to acc
22190 75 6d 75 6c 61 74 65 20 70 61 74 63 68 73 65 74  umulate patchset
221a0 73 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 54 61  s */.  SessionTa
221b0 62 6c 65 20 2a 70 4c 69 73 74 3b 20 20 20 20 20  ble *pList;     
221c0 20 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f         /* List o
221d0 66 20 74 61 62 6c 65 73 20 69 6e 20 63 75 72 72  f tables in curr
221e0 65 6e 74 20 70 61 74 63 68 20 2a 2f 0a 7d 3b 0a  ent patch */.};.
221f0 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
22200 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74  tion is called t
22210 6f 20 6d 65 72 67 65 20 74 77 6f 20 63 68 61 6e  o merge two chan
22220 67 65 73 20 74 6f 20 74 68 65 20 73 61 6d 65 20  ges to the same 
22230 72 6f 77 20 74 6f 67 65 74 68 65 72 20 61 73 0a  row together as.
22240 2a 2a 20 70 61 72 74 20 6f 66 20 61 6e 20 73 71  ** part of an sq
22250 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 63  lite3changeset_c
22260 6f 6e 63 61 74 28 29 20 6f 70 65 72 61 74 69 6f  oncat() operatio
22270 6e 2e 20 41 20 6e 65 77 20 63 68 61 6e 67 65 20  n. A new change 
22280 6f 62 6a 65 63 74 20 69 73 0a 2a 2a 20 61 6c 6c  object is.** all
22290 6f 63 61 74 65 64 20 61 6e 64 20 61 20 70 6f 69  ocated and a poi
222a0 6e 74 65 72 20 74 6f 20 69 74 20 73 74 6f 72 65  nter to it store
222b0 64 20 69 6e 20 2a 70 70 4e 65 77 2e 0a 2a 2f 0a  d in *ppNew..*/.
222c0 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69  static int sessi
222d0 6f 6e 43 68 61 6e 67 65 4d 65 72 67 65 28 0a 20  onChangeMerge(. 
222e0 20 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70   SessionTable *p
222f0 54 61 62 2c 20 20 20 20 20 20 20 20 20 20 20 20  Tab,            
22300 20 2f 2a 20 54 61 62 6c 65 20 73 74 72 75 63 74   /* Table struct
22310 75 72 65 20 2a 2f 0a 20 20 69 6e 74 20 62 50 61  ure */.  int bPa
22320 74 63 68 73 65 74 2c 20 20 20 20 20 20 20 20 20  tchset,         
22330 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
22340 20 66 6f 72 20 70 61 74 63 68 73 65 74 73 20 2a   for patchsets *
22350 2f 0a 20 20 53 65 73 73 69 6f 6e 43 68 61 6e 67  /.  SessionChang
22360 65 20 2a 70 45 78 69 73 74 2c 20 20 20 20 20 20  e *pExist,      
22370 20 20 20 20 2f 2a 20 45 78 69 73 74 69 6e 67 20      /* Existing 
22380 63 68 61 6e 67 65 20 2a 2f 0a 20 20 69 6e 74 20  change */.  int 
22390 6f 70 32 2c 20 20 20 20 20 20 20 20 20 20 20 20  op2,            
223a0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
223b0 65 63 6f 6e 64 20 63 68 61 6e 67 65 20 6f 70 65  econd change ope
223c0 72 61 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20  ration */.  int 
223d0 62 49 6e 64 69 72 65 63 74 2c 20 20 20 20 20 20  bIndirect,      
223e0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
223f0 72 75 65 20 69 66 20 73 65 63 6f 6e 64 20 63 68  rue if second ch
22400 61 6e 67 65 20 69 73 20 69 6e 64 69 72 65 63 74  ange is indirect
22410 20 2a 2f 0a 20 20 75 38 20 2a 61 52 65 63 2c 20   */.  u8 *aRec, 
22420 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22430 20 20 20 20 20 20 2f 2a 20 53 65 63 6f 6e 64 20        /* Second 
22440 63 68 61 6e 67 65 20 72 65 63 6f 72 64 20 2a 2f  change record */
22450 0a 20 20 69 6e 74 20 6e 52 65 63 2c 20 20 20 20  .  int nRec,    
22460 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22470 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
22480 62 79 74 65 73 20 69 6e 20 61 52 65 63 20 2a 2f  bytes in aRec */
22490 0a 20 20 53 65 73 73 69 6f 6e 43 68 61 6e 67 65  .  SessionChange
224a0 20 2a 2a 70 70 4e 65 77 20 20 20 20 20 20 20 20   **ppNew        
224b0 20 20 20 2f 2a 20 4f 55 54 3a 20 4d 65 72 67 65     /* OUT: Merge
224c0 64 20 63 68 61 6e 67 65 20 2a 2f 0a 29 7b 0a 20  d change */.){. 
224d0 20 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a   SessionChange *
224e0 70 4e 65 77 20 3d 20 30 3b 0a 0a 20 20 69 66 28  pNew = 0;..  if(
224f0 20 21 70 45 78 69 73 74 20 29 7b 0a 20 20 20 20   !pExist ){.    
22500 70 4e 65 77 20 3d 20 28 53 65 73 73 69 6f 6e 43  pNew = (SessionC
22510 68 61 6e 67 65 20 2a 29 73 71 6c 69 74 65 33 5f  hange *)sqlite3_
22520 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 53 65  malloc(sizeof(Se
22530 73 73 69 6f 6e 43 68 61 6e 67 65 29 20 2b 20 6e  ssionChange) + n
22540 52 65 63 29 3b 0a 20 20 20 20 69 66 28 20 21 70  Rec);.    if( !p
22550 4e 65 77 20 29 7b 0a 20 20 20 20 20 20 72 65 74  New ){.      ret
22560 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
22570 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d 73  ;.    }.    mems
22580 65 74 28 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65  et(pNew, 0, size
22590 6f 66 28 53 65 73 73 69 6f 6e 43 68 61 6e 67 65  of(SessionChange
225a0 29 29 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 6f 70  ));.    pNew->op
225b0 20 3d 20 6f 70 32 3b 0a 20 20 20 20 70 4e 65 77   = op2;.    pNew
225c0 2d 3e 62 49 6e 64 69 72 65 63 74 20 3d 20 62 49  ->bIndirect = bI
225d0 6e 64 69 72 65 63 74 3b 0a 20 20 20 20 70 4e 65  ndirect;.    pNe
225e0 77 2d 3e 6e 52 65 63 6f 72 64 20 3d 20 6e 52 65  w->nRecord = nRe
225f0 63 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 61 52 65  c;.    pNew->aRe
22600 63 6f 72 64 20 3d 20 28 75 38 2a 29 26 70 4e 65  cord = (u8*)&pNe
22610 77 5b 31 5d 3b 0a 20 20 20 20 6d 65 6d 63 70 79  w[1];.    memcpy
22620 28 70 4e 65 77 2d 3e 61 52 65 63 6f 72 64 2c 20  (pNew->aRecord, 
22630 61 52 65 63 2c 20 6e 52 65 63 29 3b 0a 20 20 7d  aRec, nRec);.  }
22640 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20 6f 70  else{.    int op
22650 31 20 3d 20 70 45 78 69 73 74 2d 3e 6f 70 3b 0a  1 = pExist->op;.
22660 0a 20 20 20 20 2f 2a 20 0a 20 20 20 20 2a 2a 20  .    /* .    ** 
22670 20 20 6f 70 31 3d 49 4e 53 45 52 54 2c 20 6f 70    op1=INSERT, op
22680 32 3d 49 4e 53 45 52 54 20 20 20 20 20 20 2d 3e  2=INSERT      ->
22690 20 20 20 20 20 20 55 6e 73 75 70 70 6f 72 74 65        Unsupporte
226a0 64 2e 20 44 69 73 63 61 72 64 20 6f 70 32 2e 0a  d. Discard op2..
226b0 20 20 20 20 2a 2a 20 20 20 6f 70 31 3d 49 4e 53      **   op1=INS
226c0 45 52 54 2c 20 6f 70 32 3d 55 50 44 41 54 45 20  ERT, op2=UPDATE 
226d0 20 20 20 20 20 2d 3e 20 20 20 20 20 20 49 4e 53       ->      INS
226e0 45 52 54 2e 0a 20 20 20 20 2a 2a 20 20 20 6f 70  ERT..    **   op
226f0 31 3d 49 4e 53 45 52 54 2c 20 6f 70 32 3d 44 45  1=INSERT, op2=DE
22700 4c 45 54 45 20 20 20 20 20 20 2d 3e 20 20 20 20  LETE      ->    
22710 20 20 28 6e 6f 6e 65 29 0a 20 20 20 20 2a 2a 0a    (none).    **.
22720 20 20 20 20 2a 2a 20 20 20 6f 70 31 3d 55 50 44      **   op1=UPD
22730 41 54 45 2c 20 6f 70 32 3d 49 4e 53 45 52 54 20  ATE, op2=INSERT 
22740 20 20 20 20 20 2d 3e 20 20 20 20 20 20 55 6e 73       ->      Uns
22750 75 70 70 6f 72 74 65 64 2e 20 44 69 73 63 61 72  upported. Discar
22760 64 20 6f 70 32 2e 0a 20 20 20 20 2a 2a 20 20 20  d op2..    **   
22770 6f 70 31 3d 55 50 44 41 54 45 2c 20 6f 70 32 3d  op1=UPDATE, op2=
22780 55 50 44 41 54 45 20 20 20 20 20 20 2d 3e 20 20  UPDATE      ->  
22790 20 20 20 20 55 50 44 41 54 45 2e 0a 20 20 20 20      UPDATE..    
227a0 2a 2a 20 20 20 6f 70 31 3d 55 50 44 41 54 45 2c  **   op1=UPDATE,
227b0 20 6f 70 32 3d 44 45 4c 45 54 45 20 20 20 20 20   op2=DELETE     
227c0 20 2d 3e 20 20 20 20 20 20 44 45 4c 45 54 45 2e   ->      DELETE.
227d0 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 20  .    **.    **  
227e0 20 6f 70 31 3d 44 45 4c 45 54 45 2c 20 6f 70 32   op1=DELETE, op2
227f0 3d 49 4e 53 45 52 54 20 20 20 20 20 20 2d 3e 20  =INSERT      -> 
22800 20 20 20 20 20 55 50 44 41 54 45 2e 0a 20 20 20       UPDATE..   
22810 20 2a 2a 20 20 20 6f 70 31 3d 44 45 4c 45 54 45   **   op1=DELETE
22820 2c 20 6f 70 32 3d 55 50 44 41 54 45 20 20 20 20  , op2=UPDATE    
22830 20 20 2d 3e 20 20 20 20 20 20 55 6e 73 75 70 70    ->      Unsupp
22840 6f 72 74 65 64 2e 20 44 69 73 63 61 72 64 20 6f  orted. Discard o
22850 70 32 2e 0a 20 20 20 20 2a 2a 20 20 20 6f 70 31  p2..    **   op1
22860 3d 44 45 4c 45 54 45 2c 20 6f 70 32 3d 44 45 4c  =DELETE, op2=DEL
22870 45 54 45 20 20 20 20 20 20 2d 3e 20 20 20 20 20  ETE      ->     
22880 20 55 6e 73 75 70 70 6f 72 74 65 64 2e 20 44 69   Unsupported. Di
22890 73 63 61 72 64 20 6f 70 32 2e 0a 20 20 20 20 2a  scard op2..    *
228a0 2f 20 20 20 0a 20 20 20 20 69 66 28 20 28 6f 70  /   .    if( (op
228b0 31 3d 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52 54  1==SQLITE_INSERT
228c0 20 26 26 20 6f 70 32 3d 3d 53 51 4c 49 54 45 5f   && op2==SQLITE_
228d0 49 4e 53 45 52 54 29 0a 20 20 20 20 20 7c 7c 20  INSERT).     || 
228e0 28 6f 70 31 3d 3d 53 51 4c 49 54 45 5f 55 50 44  (op1==SQLITE_UPD
228f0 41 54 45 20 26 26 20 6f 70 32 3d 3d 53 51 4c 49  ATE && op2==SQLI
22900 54 45 5f 49 4e 53 45 52 54 29 0a 20 20 20 20 20  TE_INSERT).     
22910 7c 7c 20 28 6f 70 31 3d 3d 53 51 4c 49 54 45 5f  || (op1==SQLITE_
22920 44 45 4c 45 54 45 20 26 26 20 6f 70 32 3d 3d 53  DELETE && op2==S
22930 51 4c 49 54 45 5f 55 50 44 41 54 45 29 0a 20 20  QLITE_UPDATE).  
22940 20 20 20 7c 7c 20 28 6f 70 31 3d 3d 53 51 4c 49     || (op1==SQLI
22950 54 45 5f 44 45 4c 45 54 45 20 26 26 20 6f 70 32  TE_DELETE && op2
22960 3d 3d 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 29  ==SQLITE_DELETE)
22970 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 70 4e  .    ){.      pN
22980 65 77 20 3d 20 70 45 78 69 73 74 3b 0a 20 20 20  ew = pExist;.   
22990 20 7d 65 6c 73 65 20 69 66 28 20 6f 70 31 3d 3d   }else if( op1==
229a0 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 20 26 26  SQLITE_INSERT &&
229b0 20 6f 70 32 3d 3d 53 51 4c 49 54 45 5f 44 45 4c   op2==SQLITE_DEL
229c0 45 54 45 20 29 7b 0a 20 20 20 20 20 20 73 71 6c  ETE ){.      sql
229d0 69 74 65 33 5f 66 72 65 65 28 70 45 78 69 73 74  ite3_free(pExist
229e0 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  );.      assert(
229f0 20 70 4e 65 77 3d 3d 30 20 29 3b 0a 20 20 20 20   pNew==0 );.    
22a00 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 75 38 20  }else{.      u8 
22a10 2a 61 45 78 69 73 74 20 3d 20 70 45 78 69 73 74  *aExist = pExist
22a20 2d 3e 61 52 65 63 6f 72 64 3b 0a 20 20 20 20 20  ->aRecord;.     
22a30 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20 20   int nByte;.    
22a40 20 20 75 38 20 2a 61 43 73 72 3b 0a 0a 20 20 20    u8 *aCsr;..   
22a50 20 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 61     /* Allocate a
22a60 20 6e 65 77 20 53 65 73 73 69 6f 6e 43 68 61 6e   new SessionChan
22a70 67 65 20 6f 62 6a 65 63 74 2e 20 45 6e 73 75 72  ge object. Ensur
22a80 65 20 74 68 61 74 20 74 68 65 20 61 52 65 63 6f  e that the aReco
22a90 72 64 5b 5d 0a 20 20 20 20 20 20 2a 2a 20 62 75  rd[].      ** bu
22aa0 66 66 65 72 20 6f 66 20 74 68 65 20 6e 65 77 20  ffer of the new 
22ab0 6f 62 6a 65 63 74 20 69 73 20 6c 61 72 67 65 20  object is large 
22ac0 65 6e 6f 75 67 68 20 74 6f 20 68 6f 6c 64 20 61  enough to hold a
22ad0 6e 79 20 72 65 63 6f 72 64 20 74 68 61 74 0a 20  ny record that. 
22ae0 20 20 20 20 20 2a 2a 20 6d 61 79 20 62 65 20 67       ** may be g
22af0 65 6e 65 72 61 74 65 64 20 62 79 20 63 6f 6d 62  enerated by comb
22b00 69 6e 69 6e 67 20 74 68 65 20 69 6e 70 75 74 20  ining the input 
22b10 72 65 63 6f 72 64 73 2e 20 20 2a 2f 0a 20 20 20  records.  */.   
22b20 20 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f     nByte = sizeo
22b30 66 28 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 29  f(SessionChange)
22b40 20 2b 20 70 45 78 69 73 74 2d 3e 6e 52 65 63 6f   + pExist->nReco
22b50 72 64 20 2b 20 6e 52 65 63 3b 0a 20 20 20 20 20  rd + nRec;.     
22b60 20 70 4e 65 77 20 3d 20 28 53 65 73 73 69 6f 6e   pNew = (Session
22b70 43 68 61 6e 67 65 20 2a 29 73 71 6c 69 74 65 33  Change *)sqlite3
22b80 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a  _malloc(nByte);.
22b90 20 20 20 20 20 20 69 66 28 20 21 70 4e 65 77 20        if( !pNew 
22ba0 29 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74  ){.        sqlit
22bb0 65 33 5f 66 72 65 65 28 70 45 78 69 73 74 29 3b  e3_free(pExist);
22bc0 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
22bd0 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
22be0 20 20 20 20 7d 0a 20 20 20 20 20 20 6d 65 6d 73      }.      mems
22bf0 65 74 28 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65  et(pNew, 0, size
22c00 6f 66 28 53 65 73 73 69 6f 6e 43 68 61 6e 67 65  of(SessionChange
22c10 29 29 3b 0a 20 20 20 20 20 20 70 4e 65 77 2d 3e  ));.      pNew->
22c20 62 49 6e 64 69 72 65 63 74 20 3d 20 28 62 49 6e  bIndirect = (bIn
22c30 64 69 72 65 63 74 20 26 26 20 70 45 78 69 73 74  direct && pExist
22c40 2d 3e 62 49 6e 64 69 72 65 63 74 29 3b 0a 20 20  ->bIndirect);.  
22c50 20 20 20 20 61 43 73 72 20 3d 20 70 4e 65 77 2d      aCsr = pNew-
22c60 3e 61 52 65 63 6f 72 64 20 3d 20 28 75 38 20 2a  >aRecord = (u8 *
22c70 29 26 70 4e 65 77 5b 31 5d 3b 0a 0a 20 20 20 20  )&pNew[1];..    
22c80 20 20 69 66 28 20 6f 70 31 3d 3d 53 51 4c 49 54    if( op1==SQLIT
22c90 45 5f 49 4e 53 45 52 54 20 29 7b 20 20 20 20 20  E_INSERT ){     
22ca0 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 53 45 52          /* INSER
22cb0 54 20 2b 20 55 50 44 41 54 45 20 2a 2f 0a 20 20  T + UPDATE */.  
22cc0 20 20 20 20 20 20 75 38 20 2a 61 31 20 3d 20 61        u8 *a1 = a
22cd0 52 65 63 3b 0a 20 20 20 20 20 20 20 20 61 73 73  Rec;.        ass
22ce0 65 72 74 28 20 6f 70 32 3d 3d 53 51 4c 49 54 45  ert( op2==SQLITE
22cf0 5f 55 50 44 41 54 45 20 29 3b 0a 20 20 20 20 20  _UPDATE );.     
22d00 20 20 20 70 4e 65 77 2d 3e 6f 70 20 3d 20 53 51     pNew->op = SQ
22d10 4c 49 54 45 5f 49 4e 53 45 52 54 3b 0a 20 20 20  LITE_INSERT;.   
22d20 20 20 20 20 20 69 66 28 20 62 50 61 74 63 68 73       if( bPatchs
22d30 65 74 3d 3d 30 20 29 20 73 65 73 73 69 6f 6e 53  et==0 ) sessionS
22d40 6b 69 70 52 65 63 6f 72 64 28 26 61 31 2c 20 70  kipRecord(&a1, p
22d50 54 61 62 2d 3e 6e 43 6f 6c 29 3b 0a 20 20 20 20  Tab->nCol);.    
22d60 20 20 20 20 73 65 73 73 69 6f 6e 4d 65 72 67 65      sessionMerge
22d70 52 65 63 6f 72 64 28 26 61 43 73 72 2c 20 70 54  Record(&aCsr, pT
22d80 61 62 2d 3e 6e 43 6f 6c 2c 20 61 45 78 69 73 74  ab->nCol, aExist
22d90 2c 20 61 31 29 3b 0a 20 20 20 20 20 20 7d 65 6c  , a1);.      }el
22da0 73 65 20 69 66 28 20 6f 70 31 3d 3d 53 51 4c 49  se if( op1==SQLI
22db0 54 45 5f 44 45 4c 45 54 45 20 29 7b 20 20 20 20  TE_DELETE ){    
22dc0 20 20 20 2f 2a 20 44 45 4c 45 54 45 20 2b 20 49     /* DELETE + I
22dd0 4e 53 45 52 54 20 2a 2f 0a 20 20 20 20 20 20 20  NSERT */.       
22de0 20 61 73 73 65 72 74 28 20 6f 70 32 3d 3d 53 51   assert( op2==SQ
22df0 4c 49 54 45 5f 49 4e 53 45 52 54 20 29 3b 0a 20  LITE_INSERT );. 
22e00 20 20 20 20 20 20 20 70 4e 65 77 2d 3e 6f 70 20         pNew->op 
22e10 3d 20 53 51 4c 49 54 45 5f 55 50 44 41 54 45 3b  = SQLITE_UPDATE;
22e20 0a 20 20 20 20 20 20 20 20 69 66 28 20 62 50 61  .        if( bPa
22e30 74 63 68 73 65 74 20 29 7b 0a 20 20 20 20 20 20  tchset ){.      
22e40 20 20 20 20 6d 65 6d 63 70 79 28 61 43 73 72 2c      memcpy(aCsr,
22e50 20 61 52 65 63 2c 20 6e 52 65 63 29 3b 0a 20 20   aRec, nRec);.  
22e60 20 20 20 20 20 20 20 20 61 43 73 72 20 2b 3d 20          aCsr += 
22e70 6e 52 65 63 3b 0a 20 20 20 20 20 20 20 20 7d 65  nRec;.        }e
22e80 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 69  lse{.          i
22e90 66 28 20 30 3d 3d 73 65 73 73 69 6f 6e 4d 65 72  f( 0==sessionMer
22ea0 67 65 55 70 64 61 74 65 28 26 61 43 73 72 2c 20  geUpdate(&aCsr, 
22eb0 70 54 61 62 2c 20 62 50 61 74 63 68 73 65 74 2c  pTab, bPatchset,
22ec0 20 61 45 78 69 73 74 2c 20 30 2c 61 52 65 63 2c   aExist, 0,aRec,
22ed0 30 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  0) ){.          
22ee0 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
22ef0 4e 65 77 29 3b 0a 20 20 20 20 20 20 20 20 20 20  New);.          
22f00 20 20 70 4e 65 77 20 3d 20 30 3b 0a 20 20 20 20    pNew = 0;.    
22f10 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
22f20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66  }.      }else if
22f30 28 20 6f 70 32 3d 3d 53 51 4c 49 54 45 5f 55 50  ( op2==SQLITE_UP
22f40 44 41 54 45 20 29 7b 20 20 20 20 20 20 20 2f 2a  DATE ){       /*
22f50 20 55 50 44 41 54 45 20 2b 20 55 50 44 41 54 45   UPDATE + UPDATE
22f60 20 2a 2f 0a 20 20 20 20 20 20 20 20 75 38 20 2a   */.        u8 *
22f70 61 31 20 3d 20 61 45 78 69 73 74 3b 0a 20 20 20  a1 = aExist;.   
22f80 20 20 20 20 20 75 38 20 2a 61 32 20 3d 20 61 52       u8 *a2 = aR
22f90 65 63 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65  ec;.        asse
22fa0 72 74 28 20 6f 70 31 3d 3d 53 51 4c 49 54 45 5f  rt( op1==SQLITE_
22fb0 55 50 44 41 54 45 20 29 3b 0a 20 20 20 20 20 20  UPDATE );.      
22fc0 20 20 69 66 28 20 62 50 61 74 63 68 73 65 74 3d    if( bPatchset=
22fd0 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  =0 ){.          
22fe0 73 65 73 73 69 6f 6e 53 6b 69 70 52 65 63 6f 72  sessionSkipRecor
22ff0 64 28 26 61 31 2c 20 70 54 61 62 2d 3e 6e 43 6f  d(&a1, pTab->nCo
23000 6c 29 3b 0a 20 20 20 20 20 20 20 20 20 20 73 65  l);.          se
23010 73 73 69 6f 6e 53 6b 69 70 52 65 63 6f 72 64 28  ssionSkipRecord(
23020 26 61 32 2c 20 70 54 61 62 2d 3e 6e 43 6f 6c 29  &a2, pTab->nCol)
23030 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
23040 20 20 20 20 70 4e 65 77 2d 3e 6f 70 20 3d 20 53      pNew->op = S
23050 51 4c 49 54 45 5f 55 50 44 41 54 45 3b 0a 20 20  QLITE_UPDATE;.  
23060 20 20 20 20 20 20 69 66 28 20 30 3d 3d 73 65 73        if( 0==ses
23070 73 69 6f 6e 4d 65 72 67 65 55 70 64 61 74 65 28  sionMergeUpdate(
23080 26 61 43 73 72 2c 20 70 54 61 62 2c 20 62 50 61  &aCsr, pTab, bPa
23090 74 63 68 73 65 74 2c 20 61 52 65 63 2c 20 61 45  tchset, aRec, aE
230a0 78 69 73 74 2c 61 31 2c 61 32 29 20 29 7b 0a 20  xist,a1,a2) ){. 
230b0 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33           sqlite3
230c0 5f 66 72 65 65 28 70 4e 65 77 29 3b 0a 20 20 20  _free(pNew);.   
230d0 20 20 20 20 20 20 20 70 4e 65 77 20 3d 20 30 3b         pNew = 0;
230e0 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
230f0 20 7d 65 6c 73 65 7b 20 20 20 20 20 20 20 20 20   }else{         
23100 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
23110 20 20 20 20 20 20 20 2f 2a 20 55 50 44 41 54 45         /* UPDATE
23120 20 2b 20 44 45 4c 45 54 45 20 2a 2f 0a 20 20 20   + DELETE */.   
23130 20 20 20 20 20 61 73 73 65 72 74 28 20 6f 70 31       assert( op1
23140 3d 3d 53 51 4c 49 54 45 5f 55 50 44 41 54 45 20  ==SQLITE_UPDATE 
23150 26 26 20 6f 70 32 3d 3d 53 51 4c 49 54 45 5f 44  && op2==SQLITE_D
23160 45 4c 45 54 45 20 29 3b 0a 20 20 20 20 20 20 20  ELETE );.       
23170 20 70 4e 65 77 2d 3e 6f 70 20 3d 20 53 51 4c 49   pNew->op = SQLI
23180 54 45 5f 44 45 4c 45 54 45 3b 0a 20 20 20 20 20  TE_DELETE;.     
23190 20 20 20 69 66 28 20 62 50 61 74 63 68 73 65 74     if( bPatchset
231a0 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6d 65   ){.          me
231b0 6d 63 70 79 28 61 43 73 72 2c 20 61 52 65 63 2c  mcpy(aCsr, aRec,
231c0 20 6e 52 65 63 29 3b 0a 20 20 20 20 20 20 20 20   nRec);.        
231d0 20 20 61 43 73 72 20 2b 3d 20 6e 52 65 63 3b 0a    aCsr += nRec;.
231e0 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
231f0 20 20 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e           session
23200 4d 65 72 67 65 52 65 63 6f 72 64 28 26 61 43 73  MergeRecord(&aCs
23210 72 2c 20 70 54 61 62 2d 3e 6e 43 6f 6c 2c 20 61  r, pTab->nCol, a
23220 52 65 63 2c 20 61 45 78 69 73 74 29 3b 0a 20 20  Rec, aExist);.  
23230 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
23240 0a 20 20 20 20 20 20 69 66 28 20 70 4e 65 77 20  .      if( pNew 
23250 29 7b 0a 20 20 20 20 20 20 20 20 70 4e 65 77 2d  ){.        pNew-
23260 3e 6e 52 65 63 6f 72 64 20 3d 20 28 69 6e 74 29  >nRecord = (int)
23270 28 61 43 73 72 20 2d 20 70 4e 65 77 2d 3e 61 52  (aCsr - pNew->aR
23280 65 63 6f 72 64 29 3b 0a 20 20 20 20 20 20 7d 0a  ecord);.      }.
23290 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
232a0 65 65 28 70 45 78 69 73 74 29 3b 0a 20 20 20 20  ee(pExist);.    
232b0 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 4e 65 77 20  }.  }..  *ppNew 
232c0 3d 20 70 4e 65 77 3b 0a 20 20 72 65 74 75 72 6e  = pNew;.  return
232d0 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
232e0 2a 0a 2a 2a 20 41 64 64 20 61 6c 6c 20 63 68 61  *.** Add all cha
232f0 6e 67 65 73 20 69 6e 20 74 68 65 20 63 68 61 6e  nges in the chan
23300 67 65 73 65 74 20 74 72 61 76 65 72 73 65 64 20  geset traversed 
23310 62 79 20 74 68 65 20 69 74 65 72 61 74 6f 72 20  by the iterator 
23320 70 61 73 73 65 64 20 61 73 0a 2a 2a 20 74 68 65  passed as.** the
23330 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20   first argument 
23340 74 6f 20 74 68 65 20 63 68 61 6e 67 65 67 72 6f  to the changegro
23350 75 70 20 68 61 73 68 20 74 61 62 6c 65 73 2e 0a  up hash tables..
23360 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
23370 73 73 69 6f 6e 43 68 61 6e 67 65 73 65 74 54 6f  ssionChangesetTo
23380 48 61 73 68 28 0a 20 20 73 71 6c 69 74 65 33 5f  Hash(.  sqlite3_
23390 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a  changeset_iter *
233a0 70 49 74 65 72 2c 20 20 20 2f 2a 20 49 74 65 72  pIter,   /* Iter
233b0 61 74 6f 72 20 74 6f 20 72 65 61 64 20 66 72 6f  ator to read fro
233c0 6d 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 63  m */.  sqlite3_c
233d0 68 61 6e 67 65 67 72 6f 75 70 20 2a 70 47 72 70  hangegroup *pGrp
233e0 20 20 20 20 20 20 20 20 2f 2a 20 43 68 61 6e 67          /* Chang
233f0 65 67 72 6f 75 70 20 6f 62 6a 65 63 74 20 74 6f  egroup object to
23400 20 61 64 64 20 63 68 61 6e 67 65 73 65 74 20 74   add changeset t
23410 6f 20 2a 2f 0a 29 7b 0a 20 20 75 38 20 2a 61 52  o */.){.  u8 *aR
23420 65 63 3b 0a 20 20 69 6e 74 20 6e 52 65 63 3b 0a  ec;.  int nRec;.
23430 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
23440 45 5f 4f 4b 3b 0a 20 20 53 65 73 73 69 6f 6e 54  E_OK;.  SessionT
23450 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 30 3b 0a  able *pTab = 0;.
23460 0a 0a 20 20 77 68 69 6c 65 28 20 53 51 4c 49 54  ..  while( SQLIT
23470 45 5f 52 4f 57 3d 3d 73 65 73 73 69 6f 6e 43 68  E_ROW==sessionCh
23480 61 6e 67 65 73 65 74 4e 65 78 74 28 70 49 74 65  angesetNext(pIte
23490 72 2c 20 26 61 52 65 63 2c 20 26 6e 52 65 63 29  r, &aRec, &nRec)
234a0 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68   ){.    const ch
234b0 61 72 20 2a 7a 4e 65 77 3b 0a 20 20 20 20 69 6e  ar *zNew;.    in
234c0 74 20 6e 43 6f 6c 3b 0a 20 20 20 20 69 6e 74 20  t nCol;.    int 
234d0 6f 70 3b 0a 20 20 20 20 69 6e 74 20 69 48 61 73  op;.    int iHas
234e0 68 3b 0a 20 20 20 20 69 6e 74 20 62 49 6e 64 69  h;.    int bIndi
234f0 72 65 63 74 3b 0a 20 20 20 20 53 65 73 73 69 6f  rect;.    Sessio
23500 6e 43 68 61 6e 67 65 20 2a 70 43 68 61 6e 67 65  nChange *pChange
23510 3b 0a 20 20 20 20 53 65 73 73 69 6f 6e 43 68 61  ;.    SessionCha
23520 6e 67 65 20 2a 70 45 78 69 73 74 20 3d 20 30 3b  nge *pExist = 0;
23530 0a 20 20 20 20 53 65 73 73 69 6f 6e 43 68 61 6e  .    SessionChan
23540 67 65 20 2a 2a 70 70 3b 0a 0a 20 20 20 20 69 66  ge **pp;..    if
23550 28 20 70 47 72 70 2d 3e 70 4c 69 73 74 3d 3d 30  ( pGrp->pList==0
23560 20 29 7b 0a 20 20 20 20 20 20 70 47 72 70 2d 3e   ){.      pGrp->
23570 62 50 61 74 63 68 20 3d 20 70 49 74 65 72 2d 3e  bPatch = pIter->
23580 62 50 61 74 63 68 73 65 74 3b 0a 20 20 20 20 7d  bPatchset;.    }
23590 65 6c 73 65 20 69 66 28 20 70 49 74 65 72 2d 3e  else if( pIter->
235a0 62 50 61 74 63 68 73 65 74 21 3d 70 47 72 70 2d  bPatchset!=pGrp-
235b0 3e 62 50 61 74 63 68 20 29 7b 0a 20 20 20 20 20  >bPatch ){.     
235c0 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52   rc = SQLITE_ERR
235d0 4f 52 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  OR;.      break;
235e0 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69  .    }..    sqli
235f0 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f 70 28  te3changeset_op(
23600 70 49 74 65 72 2c 20 26 7a 4e 65 77 2c 20 26 6e  pIter, &zNew, &n
23610 43 6f 6c 2c 20 26 6f 70 2c 20 26 62 49 6e 64 69  Col, &op, &bIndi
23620 72 65 63 74 29 3b 0a 20 20 20 20 69 66 28 20 21  rect);.    if( !
23630 70 54 61 62 20 7c 7c 20 73 71 6c 69 74 65 33 5f  pTab || sqlite3_
23640 73 74 72 69 63 6d 70 28 7a 4e 65 77 2c 20 70 54  stricmp(zNew, pT
23650 61 62 2d 3e 7a 4e 61 6d 65 29 20 29 7b 0a 20 20  ab->zName) ){.  
23660 20 20 20 20 2f 2a 20 53 65 61 72 63 68 20 74 68      /* Search th
23670 65 20 6c 69 73 74 20 66 6f 72 20 61 20 6d 61 74  e list for a mat
23680 63 68 69 6e 67 20 74 61 62 6c 65 20 2a 2f 0a 20  ching table */. 
23690 20 20 20 20 20 69 6e 74 20 6e 4e 65 77 20 3d 20       int nNew = 
236a0 28 69 6e 74 29 73 74 72 6c 65 6e 28 7a 4e 65 77  (int)strlen(zNew
236b0 29 3b 0a 20 20 20 20 20 20 75 38 20 2a 61 62 50  );.      u8 *abP
236c0 4b 3b 0a 0a 20 20 20 20 20 20 73 71 6c 69 74 65  K;..      sqlite
236d0 33 63 68 61 6e 67 65 73 65 74 5f 70 6b 28 70 49  3changeset_pk(pI
236e0 74 65 72 2c 20 26 61 62 50 4b 2c 20 30 29 3b 0a  ter, &abPK, 0);.
236f0 20 20 20 20 20 20 66 6f 72 28 70 54 61 62 20 3d        for(pTab =
23700 20 70 47 72 70 2d 3e 70 4c 69 73 74 3b 20 70 54   pGrp->pList; pT
23710 61 62 3b 20 70 54 61 62 3d 70 54 61 62 2d 3e 70  ab; pTab=pTab->p
23720 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 20 20 69  Next){.        i
23730 66 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74  f( 0==sqlite3_st
23740 72 6e 69 63 6d 70 28 70 54 61 62 2d 3e 7a 4e 61  rnicmp(pTab->zNa
23750 6d 65 2c 20 7a 4e 65 77 2c 20 6e 4e 65 77 2b 31  me, zNew, nNew+1
23760 29 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  ) ) break;.     
23770 20 7d 0a 20 20 20 20 20 20 69 66 28 20 21 70 54   }.      if( !pT
23780 61 62 20 29 7b 0a 20 20 20 20 20 20 20 20 53 65  ab ){.        Se
23790 73 73 69 6f 6e 54 61 62 6c 65 20 2a 2a 70 70 54  ssionTable **ppT
237a0 61 62 3b 0a 0a 20 20 20 20 20 20 20 20 70 54 61  ab;..        pTa
237b0 62 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  b = sqlite3_mall
237c0 6f 63 28 73 69 7a 65 6f 66 28 53 65 73 73 69 6f  oc(sizeof(Sessio
237d0 6e 54 61 62 6c 65 29 20 2b 20 6e 43 6f 6c 20 2b  nTable) + nCol +
237e0 20 6e 4e 65 77 2b 31 29 3b 0a 20 20 20 20 20 20   nNew+1);.      
237f0 20 20 69 66 28 20 21 70 54 61 62 20 29 7b 0a 20    if( !pTab ){. 
23800 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51           rc = SQ
23810 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
23820 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
23830 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 6d       }.        m
23840 65 6d 73 65 74 28 70 54 61 62 2c 20 30 2c 20 73  emset(pTab, 0, s
23850 69 7a 65 6f 66 28 53 65 73 73 69 6f 6e 54 61 62  izeof(SessionTab
23860 6c 65 29 29 3b 0a 20 20 20 20 20 20 20 20 70 54  le));.        pT
23870 61 62 2d 3e 6e 43 6f 6c 20 3d 20 6e 43 6f 6c 3b  ab->nCol = nCol;
23880 0a 20 20 20 20 20 20 20 20 70 54 61 62 2d 3e 61  .        pTab->a
23890 62 50 4b 20 3d 20 28 75 38 2a 29 26 70 54 61 62  bPK = (u8*)&pTab
238a0 5b 31 5d 3b 0a 20 20 20 20 20 20 20 20 6d 65 6d  [1];.        mem
238b0 63 70 79 28 70 54 61 62 2d 3e 61 62 50 4b 2c 20  cpy(pTab->abPK, 
238c0 61 62 50 4b 2c 20 6e 43 6f 6c 29 3b 0a 20 20 20  abPK, nCol);.   
238d0 20 20 20 20 20 70 54 61 62 2d 3e 7a 4e 61 6d 65       pTab->zName
238e0 20 3d 20 28 63 68 61 72 2a 29 26 70 54 61 62 2d   = (char*)&pTab-
238f0 3e 61 62 50 4b 5b 6e 43 6f 6c 5d 3b 0a 20 20 20  >abPK[nCol];.   
23900 20 20 20 20 20 6d 65 6d 63 70 79 28 70 54 61 62       memcpy(pTab
23910 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e 65 77 2c 20 6e  ->zName, zNew, n
23920 4e 65 77 2b 31 29 3b 0a 0a 20 20 20 20 20 20 20  New+1);..       
23930 20 2f 2a 20 54 68 65 20 6e 65 77 20 6f 62 6a 65   /* The new obje
23940 63 74 20 6d 75 73 74 20 62 65 20 6c 69 6e 6b 65  ct must be linke
23950 64 20 6f 6e 20 74 6f 20 74 68 65 20 65 6e 64 20  d on to the end 
23960 6f 66 20 74 68 65 20 6c 69 73 74 2c 20 6e 6f 74  of the list, not
23970 0a 20 20 20 20 20 20 20 20 2a 2a 20 73 69 6d 70  .        ** simp
23980 6c 79 20 61 64 64 65 64 20 74 6f 20 74 68 65 20  ly added to the 
23990 73 74 61 72 74 20 6f 66 20 69 74 2e 20 54 68 69  start of it. Thi
239a0 73 20 69 73 20 74 6f 20 65 6e 73 75 72 65 20 74  s is to ensure t
239b0 68 61 74 20 74 68 65 0a 20 20 20 20 20 20 20 20  hat the.        
239c0 2a 2a 20 74 61 62 6c 65 73 20 77 69 74 68 69 6e  ** tables within
239d0 20 74 68 65 20 6f 75 74 70 75 74 20 6f 66 20 73   the output of s
239e0 71 6c 69 74 65 33 63 68 61 6e 67 65 67 72 6f 75  qlite3changegrou
239f0 70 5f 6f 75 74 70 75 74 28 29 20 61 72 65 20 69  p_output() are i
23a00 6e 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 74 68  n .        ** th
23a10 65 20 72 69 67 68 74 20 6f 72 64 65 72 2e 20 20  e right order.  
23a20 2a 2f 0a 20 20 20 20 20 20 20 20 66 6f 72 28 70  */.        for(p
23a30 70 54 61 62 3d 26 70 47 72 70 2d 3e 70 4c 69 73  pTab=&pGrp->pLis
23a40 74 3b 20 2a 70 70 54 61 62 3b 20 70 70 54 61 62  t; *ppTab; ppTab
23a50 3d 26 28 2a 70 70 54 61 62 29 2d 3e 70 4e 65 78  =&(*ppTab)->pNex
23a60 74 29 3b 0a 20 20 20 20 20 20 20 20 2a 70 70 54  t);.        *ppT
23a70 61 62 20 3d 20 70 54 61 62 3b 0a 20 20 20 20 20  ab = pTab;.     
23a80 20 7d 65 6c 73 65 20 69 66 28 20 70 54 61 62 2d   }else if( pTab-
23a90 3e 6e 43 6f 6c 21 3d 6e 43 6f 6c 20 7c 7c 20 6d  >nCol!=nCol || m
23aa0 65 6d 63 6d 70 28 70 54 61 62 2d 3e 61 62 50 4b  emcmp(pTab->abPK
23ab0 2c 20 61 62 50 4b 2c 20 6e 43 6f 6c 29 20 29 7b  , abPK, nCol) ){
23ac0 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51  .        rc = SQ
23ad0 4c 49 54 45 5f 53 43 48 45 4d 41 3b 0a 20 20 20  LITE_SCHEMA;.   
23ae0 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
23af0 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69    }.    }..    i
23b00 66 28 20 73 65 73 73 69 6f 6e 47 72 6f 77 48 61  f( sessionGrowHa
23b10 73 68 28 70 49 74 65 72 2d 3e 62 50 61 74 63 68  sh(pIter->bPatch
23b20 73 65 74 2c 20 70 54 61 62 29 20 29 7b 0a 20 20  set, pTab) ){.  
23b30 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
23b40 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 62 72 65  NOMEM;.      bre
23b50 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 48  ak;.    }.    iH
23b60 61 73 68 20 3d 20 73 65 73 73 69 6f 6e 43 68 61  ash = sessionCha
23b70 6e 67 65 48 61 73 68 28 0a 20 20 20 20 20 20 20  ngeHash(.       
23b80 20 70 54 61 62 2c 20 28 70 49 74 65 72 2d 3e 62   pTab, (pIter->b
23b90 50 61 74 63 68 73 65 74 20 26 26 20 6f 70 3d 3d  Patchset && op==
23ba0 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 29 2c 20  SQLITE_DELETE), 
23bb0 61 52 65 63 2c 20 70 54 61 62 2d 3e 6e 43 68 61  aRec, pTab->nCha
23bc0 6e 67 65 0a 20 20 20 20 29 3b 0a 0a 20 20 20 20  nge.    );..    
23bd0 2f 2a 20 53 65 61 72 63 68 20 66 6f 72 20 65 78  /* Search for ex
23be0 69 73 74 69 6e 67 20 65 6e 74 72 79 2e 20 49 66  isting entry. If
23bf0 20 66 6f 75 6e 64 2c 20 72 65 6d 6f 76 65 20 69   found, remove i
23c00 74 20 66 72 6f 6d 20 74 68 65 20 68 61 73 68 20  t from the hash 
23c10 74 61 62 6c 65 2e 20 0a 20 20 20 20 2a 2a 20 43  table. .    ** C
23c20 6f 64 65 20 62 65 6c 6f 77 20 6d 61 79 20 6c 69  ode below may li
23c30 6e 6b 20 69 74 20 62 61 63 6b 20 69 6e 2e 0a 20  nk it back in.. 
23c40 20 20 20 2a 2f 0a 20 20 20 20 66 6f 72 28 70 70     */.    for(pp
23c50 3d 26 70 54 61 62 2d 3e 61 70 43 68 61 6e 67 65  =&pTab->apChange
23c60 5b 69 48 61 73 68 5d 3b 20 2a 70 70 3b 20 70 70  [iHash]; *pp; pp
23c70 3d 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29 7b  =&(*pp)->pNext){
23c80 0a 20 20 20 20 20 20 69 6e 74 20 62 50 6b 4f 6e  .      int bPkOn
23c90 6c 79 31 20 3d 20 30 3b 0a 20 20 20 20 20 20 69  ly1 = 0;.      i
23ca0 6e 74 20 62 50 6b 4f 6e 6c 79 32 20 3d 20 30 3b  nt bPkOnly2 = 0;
23cb0 0a 20 20 20 20 20 20 69 66 28 20 70 49 74 65 72  .      if( pIter
23cc0 2d 3e 62 50 61 74 63 68 73 65 74 20 29 7b 0a 20  ->bPatchset ){. 
23cd0 20 20 20 20 20 20 20 62 50 6b 4f 6e 6c 79 31 20         bPkOnly1 
23ce0 3d 20 28 2a 70 70 29 2d 3e 6f 70 3d 3d 53 51 4c  = (*pp)->op==SQL
23cf0 49 54 45 5f 44 45 4c 45 54 45 3b 0a 20 20 20 20  ITE_DELETE;.    
23d00 20 20 20 20 62 50 6b 4f 6e 6c 79 32 20 3d 20 6f      bPkOnly2 = o
23d10 70 3d 3d 53 51 4c 49 54 45 5f 44 45 4c 45 54 45  p==SQLITE_DELETE
23d20 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
23d30 69 66 28 20 73 65 73 73 69 6f 6e 43 68 61 6e 67  if( sessionChang
23d40 65 45 71 75 61 6c 28 70 54 61 62 2c 20 62 50 6b  eEqual(pTab, bPk
23d50 4f 6e 6c 79 31 2c 20 28 2a 70 70 29 2d 3e 61 52  Only1, (*pp)->aR
23d60 65 63 6f 72 64 2c 20 62 50 6b 4f 6e 6c 79 32 2c  ecord, bPkOnly2,
23d70 20 61 52 65 63 29 20 29 7b 0a 20 20 20 20 20 20   aRec) ){.      
23d80 20 20 70 45 78 69 73 74 20 3d 20 2a 70 70 3b 0a    pExist = *pp;.
23d90 20 20 20 20 20 20 20 20 2a 70 70 20 3d 20 28 2a          *pp = (*
23da0 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  pp)->pNext;.    
23db0 20 20 20 20 70 54 61 62 2d 3e 6e 45 6e 74 72 79      pTab->nEntry
23dc0 2d 2d 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  --;.        brea
23dd0 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  k;.      }.    }
23de0 0a 0a 20 20 20 20 72 63 20 3d 20 73 65 73 73 69  ..    rc = sessi
23df0 6f 6e 43 68 61 6e 67 65 4d 65 72 67 65 28 70 54  onChangeMerge(pT
23e00 61 62 2c 20 0a 20 20 20 20 20 20 20 20 70 49 74  ab, .        pIt
23e10 65 72 2d 3e 62 50 61 74 63 68 73 65 74 2c 20 70  er->bPatchset, p
23e20 45 78 69 73 74 2c 20 6f 70 2c 20 62 49 6e 64 69  Exist, op, bIndi
23e30 72 65 63 74 2c 20 61 52 65 63 2c 20 6e 52 65 63  rect, aRec, nRec
23e40 2c 20 26 70 43 68 61 6e 67 65 0a 20 20 20 20 29  , &pChange.    )
23e50 3b 0a 20 20 20 20 69 66 28 20 72 63 20 29 20 62  ;.    if( rc ) b
23e60 72 65 61 6b 3b 0a 20 20 20 20 69 66 28 20 70 43  reak;.    if( pC
23e70 68 61 6e 67 65 20 29 7b 0a 20 20 20 20 20 20 70  hange ){.      p
23e80 43 68 61 6e 67 65 2d 3e 70 4e 65 78 74 20 3d 20  Change->pNext = 
23e90 70 54 61 62 2d 3e 61 70 43 68 61 6e 67 65 5b 69  pTab->apChange[i
23ea0 48 61 73 68 5d 3b 0a 20 20 20 20 20 20 70 54 61  Hash];.      pTa
23eb0 62 2d 3e 61 70 43 68 61 6e 67 65 5b 69 48 61 73  b->apChange[iHas
23ec0 68 5d 20 3d 20 70 43 68 61 6e 67 65 3b 0a 20 20  h] = pChange;.  
23ed0 20 20 20 20 70 54 61 62 2d 3e 6e 45 6e 74 72 79      pTab->nEntry
23ee0 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  ++;.    }.  }.. 
23ef0 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
23f00 4f 4b 20 29 20 72 63 20 3d 20 70 49 74 65 72 2d  OK ) rc = pIter-
23f10 3e 72 63 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  >rc;.  return rc
23f20 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 72 69 61  ;.}../*.** Seria
23f30 6c 69 7a 65 20 61 20 63 68 61 6e 67 65 73 65 74  lize a changeset
23f40 20 28 6f 72 20 70 61 74 63 68 73 65 74 29 20 62   (or patchset) b
23f50 61 73 65 64 20 6f 6e 20 61 6c 6c 20 63 68 61 6e  ased on all chan
23f60 67 65 73 65 74 73 20 28 6f 72 20 70 61 74 63 68  gesets (or patch
23f70 73 65 74 73 29 0a 2a 2a 20 61 64 64 65 64 20 74  sets).** added t
23f80 6f 20 74 68 65 20 63 68 61 6e 67 65 67 72 6f 75  o the changegrou
23f90 70 20 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20  p object passed 
23fa0 61 73 20 74 68 65 20 66 69 72 73 74 20 61 72 67  as the first arg
23fb0 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  ument..**.** If 
23fc0 78 4f 75 74 70 75 74 20 69 73 20 6e 6f 74 20 4e  xOutput is not N
23fd0 55 4c 4c 2c 20 74 68 65 6e 20 74 68 65 20 63 68  ULL, then the ch
23fe0 61 6e 67 65 73 65 74 2f 70 61 74 63 68 73 65 74  angeset/patchset
23ff0 20 69 73 20 72 65 74 75 72 6e 65 64 20 74 6f 20   is returned to 
24000 74 68 65 0a 2a 2a 20 75 73 65 72 20 76 69 61 20  the.** user via 
24010 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 63 61 6c 6c  one or more call
24020 73 20 74 6f 20 78 4f 75 74 70 75 74 2c 20 61 73  s to xOutput, as
24030 20 77 69 74 68 20 74 68 65 20 6f 74 68 65 72 20   with the other 
24040 73 74 72 65 61 6d 69 6e 67 0a 2a 2a 20 69 6e 74  streaming.** int
24050 65 72 66 61 63 65 73 2e 20 0a 2a 2a 0a 2a 2a 20  erfaces. .**.** 
24060 4f 72 2c 20 69 66 20 78 4f 75 74 70 75 74 20 69  Or, if xOutput i
24070 73 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 28 2a 70  s NULL, then (*p
24080 70 4f 75 74 29 20 69 73 20 70 6f 70 75 6c 61 74  pOut) is populat
24090 65 64 20 77 69 74 68 20 61 20 70 6f 69 6e 74 65  ed with a pointe
240a0 72 20 74 6f 20 61 0a 2a 2a 20 62 75 66 66 65 72  r to a.** buffer
240b0 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20   containing the 
240c0 6f 75 74 70 75 74 20 63 68 61 6e 67 65 73 65 74  output changeset
240d0 20 62 65 66 6f 72 65 20 74 68 69 73 20 66 75 6e   before this fun
240e0 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e 20 49  ction returns. I
240f0 6e 0a 2a 2a 20 74 68 69 73 20 63 61 73 65 20 28  n.** this case (
24100 2a 70 6e 4f 75 74 29 20 69 73 20 73 65 74 20 74  *pnOut) is set t
24110 6f 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68  o the size of th
24120 65 20 6f 75 74 70 75 74 20 62 75 66 66 65 72 20  e output buffer 
24130 69 6e 20 62 79 74 65 73 2e 20 49 74 0a 2a 2a 20  in bytes. It.** 
24140 69 73 20 74 68 65 20 72 65 73 70 6f 6e 73 69 62  is the responsib
24150 69 6c 69 74 79 20 6f 66 20 74 68 65 20 63 61 6c  ility of the cal
24160 6c 65 72 20 74 6f 20 66 72 65 65 20 74 68 65 20  ler to free the 
24170 6f 75 74 70 75 74 20 62 75 66 66 65 72 20 75 73  output buffer us
24180 69 6e 67 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 66  ing.** sqlite3_f
24190 72 65 65 28 29 20 77 68 65 6e 20 69 74 20 69 73  ree() when it is
241a0 20 6e 6f 20 6c 6f 6e 67 65 72 20 72 65 71 75 69   no longer requi
241b0 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75  red..**.** If su
241c0 63 63 65 73 73 66 75 6c 2c 20 53 51 4c 49 54 45  ccessful, SQLITE
241d0 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 2e  _OK is returned.
241e0 20 4f 72 2c 20 69 66 20 61 6e 20 65 72 72 6f 72   Or, if an error
241f0 20 6f 63 63 75 72 73 2c 20 61 6e 20 53 51 4c 69   occurs, an SQLi
24200 74 65 0a 2a 2a 20 65 72 72 6f 72 20 63 6f 64 65  te.** error code
24210 2e 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  . If an error oc
24220 63 75 72 73 20 61 6e 64 20 78 4f 75 74 70 75 74  curs and xOutput
24230 20 69 73 20 4e 55 4c 4c 2c 20 28 2a 70 70 4f 75   is NULL, (*ppOu
24240 74 29 20 61 6e 64 20 28 2a 70 6e 4f 75 74 29 0a  t) and (*pnOut).
24250 2a 2a 20 61 72 65 20 62 6f 74 68 20 73 65 74 20  ** are both set 
24260 74 6f 20 30 20 62 65 66 6f 72 65 20 72 65 74 75  to 0 before retu
24270 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63  rning..*/.static
24280 20 69 6e 74 20 73 65 73 73 69 6f 6e 43 68 61 6e   int sessionChan
24290 67 65 67 72 6f 75 70 4f 75 74 70 75 74 28 0a 20  gegroupOutput(. 
242a0 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 67   sqlite3_changeg
242b0 72 6f 75 70 20 2a 70 47 72 70 2c 0a 20 20 69 6e  roup *pGrp,.  in
242c0 74 20 28 2a 78 4f 75 74 70 75 74 29 28 76 6f 69  t (*xOutput)(voi
242d0 64 20 2a 70 4f 75 74 2c 20 63 6f 6e 73 74 20 76  d *pOut, const v
242e0 6f 69 64 20 2a 70 44 61 74 61 2c 20 69 6e 74 20  oid *pData, int 
242f0 6e 44 61 74 61 29 2c 0a 20 20 76 6f 69 64 20 2a  nData),.  void *
24300 70 4f 75 74 2c 0a 20 20 69 6e 74 20 2a 70 6e 4f  pOut,.  int *pnO
24310 75 74 2c 0a 20 20 76 6f 69 64 20 2a 2a 70 70 4f  ut,.  void **ppO
24320 75 74 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  ut.){.  int rc =
24330 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 53 65   SQLITE_OK;.  Se
24340 73 73 69 6f 6e 42 75 66 66 65 72 20 62 75 66 20  ssionBuffer buf 
24350 3d 20 7b 30 2c 20 30 2c 20 30 7d 3b 0a 20 20 53  = {0, 0, 0};.  S
24360 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70 54 61  essionTable *pTa
24370 62 3b 0a 20 20 61 73 73 65 72 74 28 20 78 4f 75  b;.  assert( xOu
24380 74 70 75 74 3d 3d 30 20 7c 7c 20 28 70 70 4f 75  tput==0 || (ppOu
24390 74 3d 3d 30 20 26 26 20 70 6e 4f 75 74 3d 3d 30  t==0 && pnOut==0
243a0 29 20 29 3b 0a 0a 20 20 2f 2a 20 43 72 65 61 74  ) );..  /* Creat
243b0 65 20 74 68 65 20 73 65 72 69 61 6c 69 7a 65 64  e the serialized
243c0 20 6f 75 74 70 75 74 20 63 68 61 6e 67 65 73 65   output changese
243d0 74 20 62 61 73 65 64 20 6f 6e 20 74 68 65 20 63  t based on the c
243e0 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 0a 20  ontents of the. 
243f0 20 2a 2a 20 68 61 73 68 20 74 61 62 6c 65 73 20   ** hash tables 
24400 61 74 74 61 63 68 65 64 20 74 6f 20 74 68 65 20  attached to the 
24410 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 6f 62 6a  SessionTable obj
24420 65 63 74 73 20 69 6e 20 6c 69 73 74 20 70 2d 3e  ects in list p->
24430 70 4c 69 73 74 2e 20 0a 20 20 2a 2f 0a 20 20 66  pList. .  */.  f
24440 6f 72 28 70 54 61 62 3d 70 47 72 70 2d 3e 70 4c  or(pTab=pGrp->pL
24450 69 73 74 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ist; rc==SQLITE_
24460 4f 4b 20 26 26 20 70 54 61 62 3b 20 70 54 61 62  OK && pTab; pTab
24470 3d 70 54 61 62 2d 3e 70 4e 65 78 74 29 7b 0a 20  =pTab->pNext){. 
24480 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 69 66     int i;.    if
24490 28 20 70 54 61 62 2d 3e 6e 45 6e 74 72 79 3d 3d  ( pTab->nEntry==
244a0 30 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 0a 20  0 ) continue;.. 
244b0 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
244c0 54 61 62 6c 65 48 64 72 28 26 62 75 66 2c 20 70  TableHdr(&buf, p
244d0 47 72 70 2d 3e 62 50 61 74 63 68 2c 20 70 54 61  Grp->bPatch, pTa
244e0 62 2c 20 26 72 63 29 3b 0a 20 20 20 20 66 6f 72  b, &rc);.    for
244f0 28 69 3d 30 3b 20 69 3c 70 54 61 62 2d 3e 6e 43  (i=0; i<pTab->nC
24500 68 61 6e 67 65 3b 20 69 2b 2b 29 7b 0a 20 20 20  hange; i++){.   
24510 20 20 20 53 65 73 73 69 6f 6e 43 68 61 6e 67 65     SessionChange
24520 20 2a 70 3b 0a 20 20 20 20 20 20 66 6f 72 28 70   *p;.      for(p
24530 3d 70 54 61 62 2d 3e 61 70 43 68 61 6e 67 65 5b  =pTab->apChange[
24540 69 5d 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78  i]; p; p=p->pNex
24550 74 29 7b 0a 20 20 20 20 20 20 20 20 73 65 73 73  t){.        sess
24560 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 26 62  ionAppendByte(&b
24570 75 66 2c 20 70 2d 3e 6f 70 2c 20 26 72 63 29 3b  uf, p->op, &rc);
24580 0a 20 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e  .        session
24590 41 70 70 65 6e 64 42 79 74 65 28 26 62 75 66 2c  AppendByte(&buf,
245a0 20 70 2d 3e 62 49 6e 64 69 72 65 63 74 2c 20 26   p->bIndirect, &
245b0 72 63 29 3b 0a 20 20 20 20 20 20 20 20 73 65 73  rc);.        ses
245c0 73 69 6f 6e 41 70 70 65 6e 64 42 6c 6f 62 28 26  sionAppendBlob(&
245d0 62 75 66 2c 20 70 2d 3e 61 52 65 63 6f 72 64 2c  buf, p->aRecord,
245e0 20 70 2d 3e 6e 52 65 63 6f 72 64 2c 20 26 72 63   p->nRecord, &rc
245f0 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
24600 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ..    if( rc==SQ
24610 4c 49 54 45 5f 4f 4b 20 26 26 20 78 4f 75 74 70  LITE_OK && xOutp
24620 75 74 20 26 26 20 62 75 66 2e 6e 42 75 66 3e 3d  ut && buf.nBuf>=
24630 53 45 53 53 49 4f 4e 53 5f 53 54 52 4d 5f 43 48  SESSIONS_STRM_CH
24640 55 4e 4b 5f 53 49 5a 45 20 29 7b 0a 20 20 20 20  UNK_SIZE ){.    
24650 20 20 72 63 20 3d 20 78 4f 75 74 70 75 74 28 70    rc = xOutput(p
24660 4f 75 74 2c 20 62 75 66 2e 61 42 75 66 2c 20 62  Out, buf.aBuf, b
24670 75 66 2e 6e 42 75 66 29 3b 0a 20 20 20 20 20 20  uf.nBuf);.      
24680 62 75 66 2e 6e 42 75 66 20 3d 20 30 3b 0a 20 20  buf.nBuf = 0;.  
24690 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72    }.  }..  if( r
246a0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
246b0 20 20 20 20 69 66 28 20 78 4f 75 74 70 75 74 20      if( xOutput 
246c0 29 7b 0a 20 20 20 20 20 20 69 66 28 20 62 75 66  ){.      if( buf
246d0 2e 6e 42 75 66 3e 30 20 29 20 72 63 20 3d 20 78  .nBuf>0 ) rc = x
246e0 4f 75 74 70 75 74 28 70 4f 75 74 2c 20 62 75 66  Output(pOut, buf
246f0 2e 61 42 75 66 2c 20 62 75 66 2e 6e 42 75 66 29  .aBuf, buf.nBuf)
24700 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
24710 20 20 20 2a 70 70 4f 75 74 20 3d 20 62 75 66 2e     *ppOut = buf.
24720 61 42 75 66 3b 0a 20 20 20 20 20 20 2a 70 6e 4f  aBuf;.      *pnO
24730 75 74 20 3d 20 62 75 66 2e 6e 42 75 66 3b 0a 20  ut = buf.nBuf;. 
24740 20 20 20 20 20 62 75 66 2e 61 42 75 66 20 3d 20       buf.aBuf = 
24750 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73  0;.    }.  }.  s
24760 71 6c 69 74 65 33 5f 66 72 65 65 28 62 75 66 2e  qlite3_free(buf.
24770 61 42 75 66 29 3b 0a 0a 20 20 72 65 74 75 72 6e  aBuf);..  return
24780 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 6c   rc;.}../*.** Al
24790 6c 6f 63 61 74 65 20 61 20 6e 65 77 2c 20 65 6d  locate a new, em
247a0 70 74 79 2c 20 73 71 6c 69 74 65 33 5f 63 68 61  pty, sqlite3_cha
247b0 6e 67 65 67 72 6f 75 70 2e 0a 2a 2f 0a 69 6e 74  ngegroup..*/.int
247c0 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 67 72   sqlite3changegr
247d0 6f 75 70 5f 6e 65 77 28 73 71 6c 69 74 65 33 5f  oup_new(sqlite3_
247e0 63 68 61 6e 67 65 67 72 6f 75 70 20 2a 2a 70 70  changegroup **pp
247f0 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
24800 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20  LITE_OK;        
24810 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
24820 6f 64 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ode */.  sqlite3
24830 5f 63 68 61 6e 67 65 67 72 6f 75 70 20 2a 70 3b  _changegroup *p;
24840 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 20           /* New 
24850 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 70 20 3d 20  object */.  p = 
24860 28 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 67  (sqlite3_changeg
24870 72 6f 75 70 2a 29 73 71 6c 69 74 65 33 5f 6d 61  roup*)sqlite3_ma
24880 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 73 71 6c 69  lloc(sizeof(sqli
24890 74 65 33 5f 63 68 61 6e 67 65 67 72 6f 75 70 29  te3_changegroup)
248a0 29 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20 29 7b  );.  if( p==0 ){
248b0 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
248c0 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b  _NOMEM;.  }else{
248d0 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 2c 20 30  .    memset(p, 0
248e0 2c 20 73 69 7a 65 6f 66 28 73 71 6c 69 74 65 33  , sizeof(sqlite3
248f0 5f 63 68 61 6e 67 65 67 72 6f 75 70 29 29 3b 0a  _changegroup));.
24900 20 20 7d 0a 20 20 2a 70 70 20 3d 20 70 3b 0a 20    }.  *pp = p;. 
24910 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
24920 2a 0a 2a 2a 20 41 64 64 20 74 68 65 20 63 68 61  *.** Add the cha
24930 6e 67 65 73 65 74 20 63 75 72 72 65 6e 74 6c 79  ngeset currently
24940 20 73 74 6f 72 65 64 20 69 6e 20 62 75 66 66 65   stored in buffe
24950 72 20 70 44 61 74 61 2c 20 73 69 7a 65 20 6e 44  r pData, size nD
24960 61 74 61 20 62 79 74 65 73 2c 0a 2a 2a 20 74 6f  ata bytes,.** to
24970 20 63 68 61 6e 67 65 73 65 74 2d 67 72 6f 75 70   changeset-group
24980 20 70 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74   p..*/.int sqlit
24990 65 33 63 68 61 6e 67 65 67 72 6f 75 70 5f 61 64  e3changegroup_ad
249a0 64 28 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65  d(sqlite3_change
249b0 67 72 6f 75 70 20 2a 70 47 72 70 2c 20 69 6e 74  group *pGrp, int
249c0 20 6e 44 61 74 61 2c 20 76 6f 69 64 20 2a 70 44   nData, void *pD
249d0 61 74 61 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f  ata){.  sqlite3_
249e0 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a  changeset_iter *
249f0 70 49 74 65 72 3b 20 20 2f 2a 20 49 74 65 72 61  pIter;  /* Itera
24a00 74 6f 72 20 6f 70 65 6e 65 64 20 6f 6e 20 70 44  tor opened on pD
24a10 61 74 61 2f 6e 44 61 74 61 20 2a 2f 0a 20 20 69  ata/nData */.  i
24a20 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
24a30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
24a40 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
24a50 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ..  rc = sqlite3
24a60 63 68 61 6e 67 65 73 65 74 5f 73 74 61 72 74 28  changeset_start(
24a70 26 70 49 74 65 72 2c 20 6e 44 61 74 61 2c 20 70  &pIter, nData, p
24a80 44 61 74 61 29 3b 0a 20 20 69 66 28 20 72 63 3d  Data);.  if( rc=
24a90 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
24aa0 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 43 68    rc = sessionCh
24ab0 61 6e 67 65 73 65 74 54 6f 48 61 73 68 28 70 49  angesetToHash(pI
24ac0 74 65 72 2c 20 70 47 72 70 29 3b 0a 20 20 7d 0a  ter, pGrp);.  }.
24ad0 20 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73    sqlite3changes
24ae0 65 74 5f 66 69 6e 61 6c 69 7a 65 28 70 49 74 65  et_finalize(pIte
24af0 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  r);.  return rc;
24b00 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 62 74 61 69 6e  .}../*.** Obtain
24b10 20 61 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69   a buffer contai
24b20 6e 69 6e 67 20 61 20 63 68 61 6e 67 65 73 65 74  ning a changeset
24b30 20 72 65 70 72 65 73 65 6e 74 69 6e 67 20 74 68   representing th
24b40 65 20 63 6f 6e 63 61 74 65 6e 61 74 69 6f 6e 0a  e concatenation.
24b50 2a 2a 20 6f 66 20 61 6c 6c 20 63 68 61 6e 67 65  ** of all change
24b60 73 65 74 73 20 61 64 64 65 64 20 74 6f 20 74 68  sets added to th
24b70 65 20 67 72 6f 75 70 20 73 6f 20 66 61 72 2e 0a  e group so far..
24b80 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 63 68  */.int sqlite3ch
24b90 61 6e 67 65 67 72 6f 75 70 5f 6f 75 74 70 75 74  angegroup_output
24ba0 28 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 63 68  (.    sqlite3_ch
24bb0 61 6e 67 65 67 72 6f 75 70 20 2a 70 47 72 70 2c  angegroup *pGrp,
24bc0 0a 20 20 20 20 69 6e 74 20 2a 70 6e 44 61 74 61  .    int *pnData
24bd0 2c 0a 20 20 20 20 76 6f 69 64 20 2a 2a 70 70 44  ,.    void **ppD
24be0 61 74 61 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20  ata.){.  return 
24bf0 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 67 72 6f  sessionChangegro
24c00 75 70 4f 75 74 70 75 74 28 70 47 72 70 2c 20 30  upOutput(pGrp, 0
24c10 2c 20 30 2c 20 70 6e 44 61 74 61 2c 20 70 70 44  , 0, pnData, ppD
24c20 61 74 61 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  ata);.}../*.** S
24c30 74 72 65 61 6d 69 6e 67 20 76 65 72 73 69 6f 6e  treaming version
24c40 73 20 6f 66 20 63 68 61 6e 67 65 67 72 6f 75 70  s of changegroup
24c50 5f 61 64 64 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73  _add()..*/.int s
24c60 71 6c 69 74 65 33 63 68 61 6e 67 65 67 72 6f 75  qlite3changegrou
24c70 70 5f 61 64 64 5f 73 74 72 6d 28 0a 20 20 73 71  p_add_strm(.  sq
24c80 6c 69 74 65 33 5f 63 68 61 6e 67 65 67 72 6f 75  lite3_changegrou
24c90 70 20 2a 70 47 72 70 2c 0a 20 20 69 6e 74 20 28  p *pGrp,.  int (
24ca0 2a 78 49 6e 70 75 74 29 28 76 6f 69 64 20 2a 70  *xInput)(void *p
24cb0 49 6e 2c 20 76 6f 69 64 20 2a 70 44 61 74 61 2c  In, void *pData,
24cc0 20 69 6e 74 20 2a 70 6e 44 61 74 61 29 2c 0a 20   int *pnData),. 
24cd0 20 76 6f 69 64 20 2a 70 49 6e 0a 29 7b 0a 20 20   void *pIn.){.  
24ce0 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65  sqlite3_changese
24cf0 74 5f 69 74 65 72 20 2a 70 49 74 65 72 3b 20 20  t_iter *pIter;  
24d00 2f 2a 20 49 74 65 72 61 74 6f 72 20 6f 70 65 6e  /* Iterator open
24d10 65 64 20 6f 6e 20 70 44 61 74 61 2f 6e 44 61 74  ed on pData/nDat
24d20 61 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20 20  a */.  int rc;  
24d30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24d40 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
24d50 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 72 63 20 3d   code */..  rc =
24d60 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
24d70 74 5f 73 74 61 72 74 5f 73 74 72 6d 28 26 70 49  t_start_strm(&pI
24d80 74 65 72 2c 20 78 49 6e 70 75 74 2c 20 70 49 6e  ter, xInput, pIn
24d90 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  );.  if( rc==SQL
24da0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
24db0 20 3d 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65   = sessionChange
24dc0 73 65 74 54 6f 48 61 73 68 28 70 49 74 65 72 2c  setToHash(pIter,
24dd0 20 70 47 72 70 29 3b 0a 20 20 7d 0a 20 20 73 71   pGrp);.  }.  sq
24de0 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 66  lite3changeset_f
24df0 69 6e 61 6c 69 7a 65 28 70 49 74 65 72 29 3b 0a  inalize(pIter);.
24e00 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
24e10 2f 2a 0a 2a 2a 20 53 74 72 65 61 6d 69 6e 67 20  /*.** Streaming 
24e20 76 65 72 73 69 6f 6e 73 20 6f 66 20 63 68 61 6e  versions of chan
24e30 67 65 67 72 6f 75 70 5f 6f 75 74 70 75 74 28 29  gegroup_output()
24e40 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
24e50 63 68 61 6e 67 65 67 72 6f 75 70 5f 6f 75 74 70  changegroup_outp
24e60 75 74 5f 73 74 72 6d 28 0a 20 20 73 71 6c 69 74  ut_strm(.  sqlit
24e70 65 33 5f 63 68 61 6e 67 65 67 72 6f 75 70 20 2a  e3_changegroup *
24e80 70 47 72 70 2c 0a 20 20 69 6e 74 20 28 2a 78 4f  pGrp,.  int (*xO
24e90 75 74 70 75 74 29 28 76 6f 69 64 20 2a 70 4f 75  utput)(void *pOu
24ea0 74 2c 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70  t, const void *p
24eb0 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74 61 29  Data, int nData)
24ec0 2c 20 0a 20 20 76 6f 69 64 20 2a 70 4f 75 74 0a  , .  void *pOut.
24ed0 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 65 73 73  ){.  return sess
24ee0 69 6f 6e 43 68 61 6e 67 65 67 72 6f 75 70 4f 75  ionChangegroupOu
24ef0 74 70 75 74 28 70 47 72 70 2c 20 78 4f 75 74 70  tput(pGrp, xOutp
24f00 75 74 2c 20 70 4f 75 74 2c 20 30 2c 20 30 29 3b  ut, pOut, 0, 0);
24f10 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c 65 74 65  .}../*.** Delete
24f20 20 61 20 63 68 61 6e 67 65 67 72 6f 75 70 20 6f   a changegroup o
24f30 62 6a 65 63 74 2e 0a 2a 2f 0a 76 6f 69 64 20 73  bject..*/.void s
24f40 71 6c 69 74 65 33 63 68 61 6e 67 65 67 72 6f 75  qlite3changegrou
24f50 70 5f 64 65 6c 65 74 65 28 73 71 6c 69 74 65 33  p_delete(sqlite3
24f60 5f 63 68 61 6e 67 65 67 72 6f 75 70 20 2a 70 47  _changegroup *pG
24f70 72 70 29 7b 0a 20 20 69 66 28 20 70 47 72 70 20  rp){.  if( pGrp 
24f80 29 7b 0a 20 20 20 20 73 65 73 73 69 6f 6e 44 65  ){.    sessionDe
24f90 6c 65 74 65 54 61 62 6c 65 28 70 47 72 70 2d 3e  leteTable(pGrp->
24fa0 70 4c 69 73 74 29 3b 0a 20 20 20 20 73 71 6c 69  pList);.    sqli
24fb0 74 65 33 5f 66 72 65 65 28 70 47 72 70 29 3b 0a  te3_free(pGrp);.
24fc0 20 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 43 6f    }.}../* .** Co
24fd0 6d 62 69 6e 65 20 74 77 6f 20 63 68 61 6e 67 65  mbine two change
24fe0 73 65 74 73 20 74 6f 67 65 74 68 65 72 2e 0a 2a  sets together..*
24ff0 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 63 68 61  /.int sqlite3cha
25000 6e 67 65 73 65 74 5f 63 6f 6e 63 61 74 28 0a 20  ngeset_concat(. 
25010 20 69 6e 74 20 6e 4c 65 66 74 2c 20 20 20 20 20   int nLeft,     
25020 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
25030 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79   /* Number of by
25040 74 65 73 20 69 6e 20 6c 68 73 20 69 6e 70 75 74  tes in lhs input
25050 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 4c 65 66   */.  void *pLef
25060 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
25070 20 20 20 20 20 20 2f 2a 20 4c 68 73 20 69 6e 70        /* Lhs inp
25080 75 74 20 63 68 61 6e 67 65 73 65 74 20 2a 2f 0a  ut changeset */.
25090 20 20 69 6e 74 20 6e 52 69 67 68 74 20 20 20 20    int nRight    
250a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
250b0 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62    /* Number of b
250c0 79 74 65 73 20 69 6e 20 72 68 73 20 69 6e 70 75  ytes in rhs inpu
250d0 74 20 2a 2f 2c 0a 20 20 76 6f 69 64 20 2a 70 52  t */,.  void *pR
250e0 69 67 68 74 2c 20 20 20 20 20 20 20 20 20 20 20  ight,           
250f0 20 20 20 20 20 20 20 20 2f 2a 20 52 68 73 20 69          /* Rhs i
25100 6e 70 75 74 20 63 68 61 6e 67 65 73 65 74 20 2a  nput changeset *
25110 2f 0a 20 20 69 6e 74 20 2a 70 6e 4f 75 74 2c 20  /.  int *pnOut, 
25120 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
25130 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d 62      /* OUT: Numb
25140 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 6f  er of bytes in o
25150 75 74 70 75 74 20 63 68 61 6e 67 65 73 65 74 20  utput changeset 
25160 2a 2f 0a 20 20 76 6f 69 64 20 2a 2a 70 70 4f 75  */.  void **ppOu
25170 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t               
25180 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 63 68 61       /* OUT: cha
25190 6e 67 65 73 65 74 20 28 6c 65 66 74 20 3c 63 6f  ngeset (left <co
251a0 6e 63 61 74 3e 20 72 69 67 68 74 29 20 2a 2f 0a  ncat> right) */.
251b0 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 63 68 61  ){.  sqlite3_cha
251c0 6e 67 65 67 72 6f 75 70 20 2a 70 47 72 70 3b 0a  ngegroup *pGrp;.
251d0 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 72 63 20    int rc;..  rc 
251e0 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 67  = sqlite3changeg
251f0 72 6f 75 70 5f 6e 65 77 28 26 70 47 72 70 29 3b  roup_new(&pGrp);
25200 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
25210 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
25220 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 67 72   sqlite3changegr
25230 6f 75 70 5f 61 64 64 28 70 47 72 70 2c 20 6e 4c  oup_add(pGrp, nL
25240 65 66 74 2c 20 70 4c 65 66 74 29 3b 0a 20 20 7d  eft, pLeft);.  }
25250 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
25260 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
25270 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 67 72   sqlite3changegr
25280 6f 75 70 5f 61 64 64 28 70 47 72 70 2c 20 6e 52  oup_add(pGrp, nR
25290 69 67 68 74 2c 20 70 52 69 67 68 74 29 3b 0a 20  ight, pRight);. 
252a0 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c   }.  if( rc==SQL
252b0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
252c0 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65   = sqlite3change
252d0 67 72 6f 75 70 5f 6f 75 74 70 75 74 28 70 47 72  group_output(pGr
252e0 70 2c 20 70 6e 4f 75 74 2c 20 70 70 4f 75 74 29  p, pnOut, ppOut)
252f0 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 63  ;.  }.  sqlite3c
25300 68 61 6e 67 65 67 72 6f 75 70 5f 64 65 6c 65 74  hangegroup_delet
25310 65 28 70 47 72 70 29 3b 0a 0a 20 20 72 65 74 75  e(pGrp);..  retu
25320 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
25330 53 74 72 65 61 6d 69 6e 67 20 76 65 72 73 69 6f  Streaming versio
25340 6e 20 6f 66 20 73 71 6c 69 74 65 33 63 68 61 6e  n of sqlite3chan
25350 67 65 73 65 74 5f 63 6f 6e 63 61 74 28 29 2e 0a  geset_concat()..
25360 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 63 68  */.int sqlite3ch
25370 61 6e 67 65 73 65 74 5f 63 6f 6e 63 61 74 5f 73  angeset_concat_s
25380 74 72 6d 28 0a 20 20 69 6e 74 20 28 2a 78 49 6e  trm(.  int (*xIn
25390 70 75 74 41 29 28 76 6f 69 64 20 2a 70 49 6e 2c  putA)(void *pIn,
253a0 20 76 6f 69 64 20 2a 70 44 61 74 61 2c 20 69 6e   void *pData, in
253b0 74 20 2a 70 6e 44 61 74 61 29 2c 0a 20 20 76 6f  t *pnData),.  vo
253c0 69 64 20 2a 70 49 6e 41 2c 0a 20 20 69 6e 74 20  id *pInA,.  int 
253d0 28 2a 78 49 6e 70 75 74 42 29 28 76 6f 69 64 20  (*xInputB)(void 
253e0 2a 70 49 6e 2c 20 76 6f 69 64 20 2a 70 44 61 74  *pIn, void *pDat
253f0 61 2c 20 69 6e 74 20 2a 70 6e 44 61 74 61 29 2c  a, int *pnData),
25400 0a 20 20 76 6f 69 64 20 2a 70 49 6e 42 2c 0a 20  .  void *pInB,. 
25410 20 69 6e 74 20 28 2a 78 4f 75 74 70 75 74 29 28   int (*xOutput)(
25420 76 6f 69 64 20 2a 70 4f 75 74 2c 20 63 6f 6e 73  void *pOut, cons
25430 74 20 76 6f 69 64 20 2a 70 44 61 74 61 2c 20 69  t void *pData, i
25440 6e 74 20 6e 44 61 74 61 29 2c 0a 20 20 76 6f 69  nt nData),.  voi
25450 64 20 2a 70 4f 75 74 0a 29 7b 0a 20 20 73 71 6c  d *pOut.){.  sql
25460 69 74 65 33 5f 63 68 61 6e 67 65 67 72 6f 75 70  ite3_changegroup
25470 20 2a 70 47 72 70 3b 0a 20 20 69 6e 74 20 72 63   *pGrp;.  int rc
25480 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  ;..  rc = sqlite
25490 33 63 68 61 6e 67 65 67 72 6f 75 70 5f 6e 65 77  3changegroup_new
254a0 28 26 70 47 72 70 29 3b 0a 20 20 69 66 28 20 72  (&pGrp);.  if( r
254b0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
254c0 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
254d0 63 68 61 6e 67 65 67 72 6f 75 70 5f 61 64 64 5f  changegroup_add_
254e0 73 74 72 6d 28 70 47 72 70 2c 20 78 49 6e 70 75  strm(pGrp, xInpu
254f0 74 41 2c 20 70 49 6e 41 29 3b 0a 20 20 7d 0a 20  tA, pInA);.  }. 
25500 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
25510 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73  OK ){.    rc = s
25520 71 6c 69 74 65 33 63 68 61 6e 67 65 67 72 6f 75  qlite3changegrou
25530 70 5f 61 64 64 5f 73 74 72 6d 28 70 47 72 70 2c  p_add_strm(pGrp,
25540 20 78 49 6e 70 75 74 42 2c 20 70 49 6e 42 29 3b   xInputB, pInB);
25550 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53  .  }.  if( rc==S
25560 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
25570 72 63 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e  rc = sqlite3chan
25580 67 65 67 72 6f 75 70 5f 6f 75 74 70 75 74 5f 73  gegroup_output_s
25590 74 72 6d 28 70 47 72 70 2c 20 78 4f 75 74 70 75  trm(pGrp, xOutpu
255a0 74 2c 20 70 4f 75 74 29 3b 0a 20 20 7d 0a 20 20  t, pOut);.  }.  
255b0 73 71 6c 69 74 65 33 63 68 61 6e 67 65 67 72 6f  sqlite3changegro
255c0 75 70 5f 64 65 6c 65 74 65 28 70 47 72 70 29 3b  up_delete(pGrp);
255d0 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
255e0 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49  ..#endif /* SQLI
255f0 54 45 5f 45 4e 41 42 4c 45 5f 53 45 53 53 49 4f  TE_ENABLE_SESSIO
25600 4e 20 26 26 20 53 51 4c 49 54 45 5f 45 4e 41 42  N && SQLITE_ENAB
25610 4c 45 5f 50 52 45 55 50 44 41 54 45 5f 48 4f 4f  LE_PREUPDATE_HOO
25620 4b 20 2a 2f 0a                                   K */.