/ Hex Artifact Content
Login

Artifact 9edfaaa74977ddecd7bbd94e8f844d9b0f6eec22d1d547e806361670db814c1e:


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 76 61 6c 75 65 20 2a 70  sqlite3_value *p
05d0: 5a 65 72 6f 42 6c 6f 62 3b 20 20 20 20 20 20 20  ZeroBlob;       
05e0: 2f 2a 20 56 61 6c 75 65 20 63 6f 6e 74 61 69 6e  /* Value contain
05f0: 69 6e 67 20 58 27 27 20 2a 2f 0a 20 20 73 71 6c  ing X'' */.  sql
0600: 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 4e  ite3_session *pN
0610: 65 78 74 3b 20 20 20 20 20 20 20 20 20 2f 2a 20  ext;         /* 
0620: 4e 65 78 74 20 73 65 73 73 69 6f 6e 20 6f 62 6a  Next session obj
0630: 65 63 74 20 6f 6e 20 73 61 6d 65 20 64 62 2e 20  ect on same db. 
0640: 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 54 61 62 6c  */.  SessionTabl
0650: 65 20 2a 70 54 61 62 6c 65 3b 20 20 20 20 20 20  e *pTable;      
0660: 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20       /* List of 
0670: 61 74 74 61 63 68 65 64 20 74 61 62 6c 65 73 20  attached tables 
0680: 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 48 6f 6f 6b  */.  SessionHook
0690: 20 68 6f 6f 6b 3b 20 20 20 20 20 20 20 20 20 20   hook;          
06a0: 20 20 20 20 20 2f 2a 20 41 50 49 73 20 74 6f 20       /* APIs to 
06b0: 67 72 61 62 20 6e 65 77 20 61 6e 64 20 6f 6c 64  grab new and old
06c0: 20 64 61 74 61 20 77 69 74 68 20 2a 2f 0a 7d 3b   data with */.};
06d0: 0a 0a 2f 2a 0a 2a 2a 20 49 6e 73 74 61 6e 63 65  ../*.** Instance
06e0: 73 20 6f 66 20 74 68 69 73 20 73 74 72 75 63 74  s of this struct
06f0: 75 72 65 20 61 72 65 20 75 73 65 64 20 74 6f 20  ure are used to 
0700: 62 75 69 6c 64 20 73 74 72 69 6e 67 73 20 6f 72  build strings or
0710: 20 62 69 6e 61 72 79 20 72 65 63 6f 72 64 73 2e   binary records.
0720: 0a 2a 2f 0a 73 74 72 75 63 74 20 53 65 73 73 69  .*/.struct Sessi
0730: 6f 6e 42 75 66 66 65 72 20 7b 0a 20 20 75 38 20  onBuffer {.  u8 
0740: 2a 61 42 75 66 3b 20 20 20 20 20 20 20 20 20 20  *aBuf;          
0750: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0760: 50 6f 69 6e 74 65 72 20 74 6f 20 63 68 61 6e 67  Pointer to chang
0770: 65 73 65 74 20 62 75 66 66 65 72 20 2a 2f 0a 20  eset buffer */. 
0780: 20 69 6e 74 20 6e 42 75 66 3b 20 20 20 20 20 20   int nBuf;      
0790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07a0: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 62 75 66 66   /* Size of buff
07b0: 65 72 20 61 42 75 66 20 2a 2f 0a 20 20 69 6e 74  er aBuf */.  int
07c0: 20 6e 41 6c 6c 6f 63 3b 20 20 20 20 20 20 20 20   nAlloc;        
07d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
07e0: 53 69 7a 65 20 6f 66 20 61 6c 6c 6f 63 61 74 69  Size of allocati
07f0: 6f 6e 20 63 6f 6e 74 61 69 6e 69 6e 67 20 61 42  on containing aB
0800: 75 66 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  uf */.};../*.** 
0810: 41 6e 20 6f 62 6a 65 63 74 20 6f 66 20 74 68 69  An object of thi
0820: 73 20 74 79 70 65 20 69 73 20 75 73 65 64 20 69  s type is used i
0830: 6e 74 65 72 6e 61 6c 6c 79 20 61 73 20 61 6e 20  nternally as an 
0840: 61 62 73 74 72 61 63 74 69 6f 6e 20 66 6f 72 20  abstraction for 
0850: 0a 2a 2a 20 69 6e 70 75 74 20 64 61 74 61 2e 20  .** input data. 
0860: 49 6e 70 75 74 20 64 61 74 61 20 6d 61 79 20 62  Input data may b
0870: 65 20 73 75 70 70 6c 69 65 64 20 65 69 74 68 65  e supplied eithe
0880: 72 20 61 73 20 61 20 73 69 6e 67 6c 65 20 6c 61  r as a single la
0890: 72 67 65 20 62 75 66 66 65 72 0a 2a 2a 20 28 65  rge buffer.** (e
08a0: 2e 67 2e 20 73 71 6c 69 74 65 33 63 68 61 6e 67  .g. sqlite3chang
08b0: 65 73 65 74 5f 73 74 61 72 74 28 29 29 20 6f 72  eset_start()) or
08c0: 20 75 73 69 6e 67 20 61 20 73 74 72 65 61 6d 20   using a stream 
08d0: 66 75 6e 63 74 69 6f 6e 20 28 65 2e 67 2e 0a 2a  function (e.g..*
08e0: 2a 20 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65  *  sqlite3change
08f0: 73 65 74 5f 73 74 61 72 74 5f 73 74 72 6d 28 29  set_start_strm()
0900: 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 53 65 73  )..*/.struct Ses
0910: 73 69 6f 6e 49 6e 70 75 74 20 7b 0a 20 20 69 6e  sionInput {.  in
0920: 74 20 62 4e 6f 44 69 73 63 61 72 64 3b 20 20 20  t bNoDiscard;   
0930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0940: 20 49 66 20 74 72 75 65 2c 20 64 69 73 63 61 72   If true, discar
0950: 64 20 6e 6f 20 64 61 74 61 20 2a 2f 0a 20 20 69  d no data */.  i
0960: 6e 74 20 69 43 75 72 72 65 6e 74 3b 20 20 20 20  nt iCurrent;    
0970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0980: 2a 20 4f 66 66 73 65 74 20 69 6e 20 61 44 61 74  * Offset in aDat
0990: 61 5b 5d 20 6f 66 20 63 75 72 72 65 6e 74 20 63  a[] of current c
09a0: 68 61 6e 67 65 20 2a 2f 0a 20 20 69 6e 74 20 69  hange */.  int i
09b0: 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 20  Next;           
09c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66             /* Of
09d0: 66 73 65 74 20 69 6e 20 61 44 61 74 61 5b 5d 20  fset in aData[] 
09e0: 6f 66 20 6e 65 78 74 20 63 68 61 6e 67 65 20 2a  of next change *
09f0: 2f 0a 20 20 75 38 20 2a 61 44 61 74 61 3b 20 20  /.  u8 *aData;  
0a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a10: 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74      /* Pointer t
0a20: 6f 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69 6e  o buffer contain
0a30: 69 6e 67 20 63 68 61 6e 67 65 73 65 74 20 2a 2f  ing changeset */
0a40: 0a 20 20 69 6e 74 20 6e 44 61 74 61 3b 20 20 20  .  int nData;   
0a50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a60: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
0a70: 62 79 74 65 73 20 69 6e 20 61 44 61 74 61 20 2a  bytes in aData *
0a80: 2f 0a 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66  /..  SessionBuff
0a90: 65 72 20 62 75 66 3b 20 20 20 20 20 20 20 20 20  er buf;         
0aa0: 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20       /* Current 
0ab0: 72 65 61 64 20 62 75 66 66 65 72 20 2a 2f 0a 20  read buffer */. 
0ac0: 20 69 6e 74 20 28 2a 78 49 6e 70 75 74 29 28 76   int (*xInput)(v
0ad0: 6f 69 64 2a 2c 20 76 6f 69 64 2a 2c 20 69 6e 74  oid*, void*, int
0ae0: 2a 29 3b 20 20 20 20 20 20 20 20 2f 2a 20 49 6e  *);        /* In
0af0: 70 75 74 20 73 74 72 65 61 6d 20 63 61 6c 6c 20  put stream call 
0b00: 28 6f 72 20 4e 55 4c 4c 29 20 2a 2f 0a 20 20 76  (or NULL) */.  v
0b10: 6f 69 64 20 2a 70 49 6e 3b 20 20 20 20 20 20 20  oid *pIn;       
0b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b30: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73           /* Firs
0b40: 74 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 78 49  t argument to xI
0b50: 6e 70 75 74 20 2a 2f 0a 20 20 69 6e 74 20 62 45  nput */.  int bE
0b60: 6f 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  of;             
0b70: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74            /* Set
0b80: 20 74 6f 20 74 72 75 65 20 61 66 74 65 72 20 78   to true after x
0b90: 49 6e 70 75 74 20 66 69 6e 69 73 68 65 64 20 2a  Input finished *
0ba0: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 53 74 72 75  /.};../*.** Stru
0bb0: 63 74 75 72 65 20 66 6f 72 20 63 68 61 6e 67 65  cture for change
0bc0: 73 65 74 20 69 74 65 72 61 74 6f 72 73 2e 0a 2a  set iterators..*
0bd0: 2f 0a 73 74 72 75 63 74 20 73 71 6c 69 74 65 33  /.struct sqlite3
0be0: 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20  _changeset_iter 
0bf0: 7b 0a 20 20 53 65 73 73 69 6f 6e 49 6e 70 75 74  {.  SessionInput
0c00: 20 69 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20   in;            
0c10: 20 20 20 20 2f 2a 20 49 6e 70 75 74 20 62 75 66      /* Input buf
0c20: 66 65 72 20 6f 72 20 73 74 72 65 61 6d 20 2a 2f  fer or stream */
0c30: 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66 65 72  .  SessionBuffer
0c40: 20 74 62 6c 68 64 72 3b 20 20 20 20 20 20 20 20   tblhdr;        
0c50: 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20     /* Buffer to 
0c60: 68 6f 6c 64 20 61 70 56 61 6c 75 65 2f 7a 54 61  hold apValue/zTa
0c70: 62 2f 61 62 50 4b 2f 20 2a 2f 0a 20 20 69 6e 74  b/abPK/ */.  int
0c80: 20 62 50 61 74 63 68 73 65 74 3b 20 20 20 20 20   bPatchset;     
0c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0ca0: 54 72 75 65 20 69 66 20 74 68 69 73 20 69 73 20  True if this is 
0cb0: 61 20 70 61 74 63 68 73 65 74 20 2a 2f 0a 20 20  a patchset */.  
0cc0: 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
0cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ce0: 2f 2a 20 49 74 65 72 61 74 6f 72 20 65 72 72 6f  /* Iterator erro
0cf0: 72 20 63 6f 64 65 20 2a 2f 0a 20 20 73 71 6c 69  r code */.  sqli
0d00: 74 65 33 5f 73 74 6d 74 20 2a 70 43 6f 6e 66 6c  te3_stmt *pConfl
0d10: 69 63 74 3b 20 20 20 20 20 20 20 20 2f 2a 20 50  ict;        /* P
0d20: 6f 69 6e 74 73 20 74 6f 20 63 6f 6e 66 6c 69 63  oints to conflic
0d30: 74 69 6e 67 20 72 6f 77 2c 20 69 66 20 61 6e 79  ting row, if any
0d40: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 54 61 62   */.  char *zTab
0d50: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0d60: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
0d70: 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20   table */.  int 
0d80: 6e 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20  nCol;           
0d90: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
0da0: 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73  umber of columns
0db0: 20 69 6e 20 7a 54 61 62 20 2a 2f 0a 20 20 69 6e   in zTab */.  in
0dc0: 74 20 6f 70 3b 20 20 20 20 20 20 20 20 20 20 20  t op;           
0dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0de0: 20 43 75 72 72 65 6e 74 20 6f 70 65 72 61 74 69   Current operati
0df0: 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 62 49 6e 64  on */.  int bInd
0e00: 69 72 65 63 74 3b 20 20 20 20 20 20 20 20 20 20  irect;          
0e10: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
0e20: 69 66 20 63 75 72 72 65 6e 74 20 63 68 61 6e 67  if current chang
0e30: 65 20 77 61 73 20 69 6e 64 69 72 65 63 74 20 2a  e was indirect *
0e40: 2f 0a 20 20 75 38 20 2a 61 62 50 4b 3b 20 20 20  /.  u8 *abPK;   
0e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e60: 20 20 20 20 2f 2a 20 50 72 69 6d 61 72 79 20 6b      /* Primary k
0e70: 65 79 20 61 72 72 61 79 20 2a 2f 0a 20 20 73 71  ey array */.  sq
0e80: 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70  lite3_value **ap
0e90: 56 61 6c 75 65 3b 20 20 20 20 20 20 20 20 2f 2a  Value;        /*
0ea0: 20 6f 6c 64 2e 2a 20 61 6e 64 20 6e 65 77 2e 2a   old.* and new.*
0eb0: 20 76 61 6c 75 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f   values */.};../
0ec0: 2a 0a 2a 2a 20 45 61 63 68 20 73 65 73 73 69 6f  *.** Each sessio
0ed0: 6e 20 6f 62 6a 65 63 74 20 6d 61 69 6e 74 61 69  n object maintai
0ee0: 6e 73 20 61 20 73 65 74 20 6f 66 20 74 68 65 20  ns a set of the 
0ef0: 66 6f 6c 6c 6f 77 69 6e 67 20 73 74 72 75 63 74  following struct
0f00: 75 72 65 73 2c 20 6f 6e 65 0a 2a 2a 20 66 6f 72  ures, one.** for
0f10: 20 65 61 63 68 20 74 61 62 6c 65 20 74 68 65 20   each table the 
0f20: 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 69  session object i
0f30: 73 20 6d 6f 6e 69 74 6f 72 69 6e 67 2e 20 54 68  s monitoring. Th
0f40: 65 20 73 74 72 75 63 74 75 72 65 73 20 61 72 65  e structures are
0f50: 0a 2a 2a 20 73 74 6f 72 65 64 20 69 6e 20 61 20  .** stored in a 
0f60: 6c 69 6e 6b 65 64 20 6c 69 73 74 20 73 74 61 72  linked list star
0f70: 74 69 6e 67 20 61 74 20 73 71 6c 69 74 65 33 5f  ting at sqlite3_
0f80: 73 65 73 73 69 6f 6e 2e 70 54 61 62 6c 65 2e 0a  session.pTable..
0f90: 2a 2a 0a 2a 2a 20 54 68 65 20 6b 65 79 73 20 6f  **.** The keys o
0fa0: 66 20 74 68 65 20 53 65 73 73 69 6f 6e 54 61 62  f the SessionTab
0fb0: 6c 65 2e 61 43 68 61 6e 67 65 5b 5d 20 68 61 73  le.aChange[] has
0fc0: 68 20 74 61 62 6c 65 20 61 72 65 20 61 6c 6c 20  h table are all 
0fd0: 72 6f 77 73 20 74 68 61 74 20 68 61 76 65 0a 2a  rows that have.*
0fe0: 2a 20 62 65 65 6e 20 6d 6f 64 69 66 69 65 64 20  * been modified 
0ff0: 69 6e 20 61 6e 79 20 77 61 79 20 73 69 6e 63 65  in any way since
1000: 20 74 68 65 20 73 65 73 73 69 6f 6e 20 6f 62 6a   the session obj
1010: 65 63 74 20 77 61 73 20 61 74 74 61 63 68 65 64  ect was attached
1020: 20 74 6f 20 74 68 65 0a 2a 2a 20 74 61 62 6c 65   to the.** table
1030: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 64 61 74 61  ..**.** The data
1040: 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68   associated with
1050: 20 65 61 63 68 20 68 61 73 68 2d 74 61 62 6c 65   each hash-table
1060: 20 65 6e 74 72 79 20 69 73 20 61 20 73 74 72 75   entry is a stru
1070: 63 74 75 72 65 20 63 6f 6e 74 61 69 6e 69 6e 67  cture containing
1080: 0a 2a 2a 20 61 20 73 75 62 73 65 74 20 6f 66 20  .** a subset of 
1090: 74 68 65 20 69 6e 69 74 69 61 6c 20 76 61 6c 75  the initial valu
10a0: 65 73 20 74 68 61 74 20 74 68 65 20 6d 6f 64 69  es that the modi
10b0: 66 69 65 64 20 72 6f 77 20 63 6f 6e 74 61 69 6e  fied row contain
10c0: 65 64 20 61 74 20 74 68 65 0a 2a 2a 20 73 74 61  ed at the.** sta
10d0: 72 74 20 6f 66 20 74 68 65 20 73 65 73 73 69 6f  rt of the sessio
10e0: 6e 2e 20 4f 72 20 6e 6f 20 69 6e 69 74 69 61 6c  n. Or no initial
10f0: 20 76 61 6c 75 65 73 20 69 66 20 74 68 65 20 72   values if the r
1100: 6f 77 20 77 61 73 20 69 6e 73 65 72 74 65 64 2e  ow was inserted.
1110: 0a 2a 2f 0a 73 74 72 75 63 74 20 53 65 73 73 69  .*/.struct Sessi
1120: 6f 6e 54 61 62 6c 65 20 7b 0a 20 20 53 65 73 73  onTable {.  Sess
1130: 69 6f 6e 54 61 62 6c 65 20 2a 70 4e 65 78 74 3b  ionTable *pNext;
1140: 0a 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 20  .  char *zName; 
1150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1160: 20 20 20 2f 2a 20 4c 6f 63 61 6c 20 6e 61 6d 65     /* Local name
1170: 20 6f 66 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69   of table */.  i
1180: 6e 74 20 6e 43 6f 6c 3b 20 20 20 20 20 20 20 20  nt nCol;        
1190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
11a0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75  * Number of colu
11b0: 6d 6e 73 20 69 6e 20 74 61 62 6c 65 20 7a 4e 61  mns in table zNa
11c0: 6d 65 20 2a 2f 0a 20 20 69 6e 74 20 62 53 74 61  me */.  int bSta
11d0: 74 31 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  t1;             
11e0: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
11f0: 69 66 20 74 68 69 73 20 69 73 20 73 71 6c 69 74  if this is sqlit
1200: 65 5f 73 74 61 74 31 20 2a 2f 0a 20 20 63 6f 6e  e_stat1 */.  con
1210: 73 74 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6c 3b  st char **azCol;
1220: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1230: 43 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 2a 2f 0a  Column names */.
1240: 20 20 75 38 20 2a 61 62 50 4b 3b 20 20 20 20 20    u8 *abPK;     
1250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1260: 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 70 72    /* Array of pr
1270: 69 6d 61 72 79 20 6b 65 79 20 66 6c 61 67 73 20  imary key flags 
1280: 2a 2f 0a 20 20 69 6e 74 20 6e 45 6e 74 72 79 3b  */.  int nEntry;
1290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12a0: 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 6e 75       /* Total nu
12b0: 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20  mber of entries 
12c0: 69 6e 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f  in hash table */
12d0: 0a 20 20 69 6e 74 20 6e 43 68 61 6e 67 65 3b 20  .  int nChange; 
12e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12f0: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61 70     /* Size of ap
1300: 43 68 61 6e 67 65 5b 5d 20 61 72 72 61 79 20 2a  Change[] array *
1310: 2f 0a 20 20 53 65 73 73 69 6f 6e 43 68 61 6e 67  /.  SessionChang
1320: 65 20 2a 2a 61 70 43 68 61 6e 67 65 3b 20 20 20  e **apChange;   
1330: 20 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c      /* Hash tabl
1340: 65 20 62 75 63 6b 65 74 73 20 2a 2f 0a 7d 3b 0a  e buckets */.};.
1350: 0a 2f 2a 20 0a 2a 2a 20 52 45 43 4f 52 44 20 46  ./* .** RECORD F
1360: 4f 52 4d 41 54 3a 0a 2a 2a 0a 2a 2a 20 54 68 65  ORMAT:.**.** The
1370: 20 66 6f 6c 6c 6f 77 69 6e 67 20 72 65 63 6f 72   following recor
1380: 64 20 66 6f 72 6d 61 74 20 69 73 20 73 69 6d 69  d format is simi
1390: 6c 61 72 20 74 6f 20 28 62 75 74 20 6e 6f 74 20  lar to (but not 
13a0: 63 6f 6d 70 61 74 69 62 6c 65 20 77 69 74 68 29  compatible with)
13b0: 20 74 68 61 74 20 0a 2a 2a 20 75 73 65 64 20 69   that .** used i
13c0: 6e 20 53 51 4c 69 74 65 20 64 61 74 61 62 61 73  n SQLite databas
13d0: 65 20 66 69 6c 65 73 2e 20 54 68 69 73 20 66 6f  e files. This fo
13e0: 72 6d 61 74 20 69 73 20 75 73 65 64 20 61 73 20  rmat is used as 
13f0: 70 61 72 74 20 6f 66 20 74 68 65 20 0a 2a 2a 20  part of the .** 
1400: 63 68 61 6e 67 65 2d 73 65 74 20 62 69 6e 61 72  change-set binar
1410: 79 20 66 6f 72 6d 61 74 2c 20 61 6e 64 20 73 6f  y format, and so
1420: 20 6d 75 73 74 20 62 65 20 61 72 63 68 69 74 65   must be archite
1430: 63 74 75 72 65 20 69 6e 64 65 70 65 6e 64 65 6e  cture independen
1440: 74 2e 0a 2a 2a 0a 2a 2a 20 55 6e 6c 69 6b 65 20  t..**.** Unlike 
1450: 74 68 65 20 53 51 4c 69 74 65 20 64 61 74 61 62  the SQLite datab
1460: 61 73 65 20 72 65 63 6f 72 64 20 66 6f 72 6d 61  ase record forma
1470: 74 2c 20 65 61 63 68 20 66 69 65 6c 64 20 69 73  t, each field is
1480: 20 73 65 6c 66 2d 63 6f 6e 74 61 69 6e 65 64 20   self-contained 
1490: 2d 0a 2a 2a 20 74 68 65 72 65 20 69 73 20 6e 6f  -.** there is no
14a0: 20 73 65 70 61 72 61 74 69 6f 6e 20 6f 66 20 68   separation of h
14b0: 65 61 64 65 72 20 61 6e 64 20 64 61 74 61 2e 20  eader and data. 
14c0: 45 61 63 68 20 66 69 65 6c 64 20 62 65 67 69 6e  Each field begin
14d0: 73 20 77 69 74 68 20 61 0a 2a 2a 20 73 69 6e 67  s with a.** sing
14e0: 6c 65 20 62 79 74 65 20 64 65 73 63 72 69 62 69  le byte describi
14f0: 6e 67 20 69 74 73 20 74 79 70 65 2c 20 61 73 20  ng its type, as 
1500: 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20  follows:.**.**  
1510: 20 20 20 20 20 30 78 30 30 3a 20 55 6e 64 65 66       0x00: Undef
1520: 69 6e 65 64 20 76 61 6c 75 65 2e 0a 2a 2a 20 20  ined value..**  
1530: 20 20 20 20 20 30 78 30 31 3a 20 49 6e 74 65 67       0x01: Integ
1540: 65 72 20 76 61 6c 75 65 2e 0a 2a 2a 20 20 20 20  er value..**    
1550: 20 20 20 30 78 30 32 3a 20 52 65 61 6c 20 76 61     0x02: Real va
1560: 6c 75 65 2e 0a 2a 2a 20 20 20 20 20 20 20 30 78  lue..**       0x
1570: 30 33 3a 20 54 65 78 74 20 76 61 6c 75 65 2e 0a  03: Text value..
1580: 2a 2a 20 20 20 20 20 20 20 30 78 30 34 3a 20 42  **       0x04: B
1590: 6c 6f 62 20 76 61 6c 75 65 2e 0a 2a 2a 20 20 20  lob value..**   
15a0: 20 20 20 20 30 78 30 35 3a 20 53 51 4c 20 4e 55      0x05: SQL NU
15b0: 4c 4c 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20  LL value..**.** 
15c0: 4e 6f 74 65 20 74 68 61 74 20 74 68 65 20 61 62  Note that the ab
15d0: 6f 76 65 20 6d 61 74 63 68 20 74 68 65 20 64 65  ove match the de
15e0: 66 69 6e 69 74 69 6f 6e 73 20 6f 66 20 53 51 4c  finitions of SQL
15f0: 49 54 45 5f 49 4e 54 45 47 45 52 2c 20 53 51 4c  ITE_INTEGER, SQL
1600: 49 54 45 5f 54 45 58 54 0a 2a 2a 20 61 6e 64 20  ITE_TEXT.** and 
1610: 73 6f 20 6f 6e 20 69 6e 20 73 71 6c 69 74 65 33  so on in sqlite3
1620: 2e 68 2e 20 46 6f 72 20 75 6e 64 65 66 69 6e 65  .h. For undefine
1630: 64 20 61 6e 64 20 4e 55 4c 4c 20 76 61 6c 75 65  d and NULL value
1640: 73 2c 20 74 68 65 20 66 69 65 6c 64 20 63 6f 6e  s, the field con
1650: 73 69 73 74 73 0a 2a 2a 20 6f 6e 6c 79 20 6f 66  sists.** only of
1660: 20 74 68 65 20 73 69 6e 67 6c 65 20 74 79 70 65   the single type
1670: 20 62 79 74 65 2e 20 46 6f 72 20 6f 74 68 65 72   byte. For other
1680: 20 74 79 70 65 73 20 6f 66 20 76 61 6c 75 65 73   types of values
1690: 2c 20 74 68 65 20 74 79 70 65 20 62 79 74 65 0a  , the type byte.
16a0: 2a 2a 20 69 73 20 66 6f 6c 6c 6f 77 65 64 20 62  ** is followed b
16b0: 79 3a 0a 2a 2a 0a 2a 2a 20 20 20 54 65 78 74 20  y:.**.**   Text 
16c0: 76 61 6c 75 65 73 3a 0a 2a 2a 20 20 20 20 20 41  values:.**     A
16d0: 20 76 61 72 69 6e 74 20 63 6f 6e 74 61 69 6e 69   varint containi
16e0: 6e 67 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  ng the number of
16f0: 20 62 79 74 65 73 20 69 6e 20 74 68 65 20 76 61   bytes in the va
1700: 6c 75 65 20 28 65 6e 63 6f 64 65 64 20 75 73 69  lue (encoded usi
1710: 6e 67 0a 2a 2a 20 20 20 20 20 55 54 46 2d 38 29  ng.**     UTF-8)
1720: 2e 20 46 6f 6c 6c 6f 77 65 64 20 62 79 20 61 20  . Followed by a 
1730: 62 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e  buffer containin
1740: 67 20 74 68 65 20 55 54 46 2d 38 20 72 65 70 72  g the UTF-8 repr
1750: 65 73 65 6e 74 61 74 69 6f 6e 0a 2a 2a 20 20 20  esentation.**   
1760: 20 20 6f 66 20 74 68 65 20 74 65 78 74 20 76 61    of the text va
1770: 6c 75 65 2e 20 54 68 65 72 65 20 69 73 20 6e 6f  lue. There is no
1780: 20 6e 75 6c 20 74 65 72 6d 69 6e 61 74 6f 72 2e   nul terminator.
1790: 0a 2a 2a 0a 2a 2a 20 20 20 42 6c 6f 62 20 76 61  .**.**   Blob va
17a0: 6c 75 65 73 3a 0a 2a 2a 20 20 20 20 20 41 20 76  lues:.**     A v
17b0: 61 72 69 6e 74 20 63 6f 6e 74 61 69 6e 69 6e 67  arint containing
17c0: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62   the number of b
17d0: 79 74 65 73 20 69 6e 20 74 68 65 20 76 61 6c 75  ytes in the valu
17e0: 65 2c 20 66 6f 6c 6c 6f 77 65 64 20 62 79 0a 2a  e, followed by.*
17f0: 2a 20 20 20 20 20 61 20 62 75 66 66 65 72 20 63  *     a buffer c
1800: 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 76 61  ontaining the va
1810: 6c 75 65 20 69 74 73 65 6c 66 2e 0a 2a 2a 0a 2a  lue itself..**.*
1820: 2a 20 20 20 49 6e 74 65 67 65 72 20 76 61 6c 75  *   Integer valu
1830: 65 73 3a 0a 2a 2a 20 20 20 20 20 41 6e 20 38 2d  es:.**     An 8-
1840: 62 79 74 65 20 62 69 67 2d 65 6e 64 69 61 6e 20  byte big-endian 
1850: 69 6e 74 65 67 65 72 20 76 61 6c 75 65 2e 0a 2a  integer value..*
1860: 2a 0a 2a 2a 20 20 20 52 65 61 6c 20 76 61 6c 75  *.**   Real valu
1870: 65 73 3a 0a 2a 2a 20 20 20 20 20 41 6e 20 38 2d  es:.**     An 8-
1880: 62 79 74 65 20 62 69 67 2d 65 6e 64 69 61 6e 20  byte big-endian 
1890: 49 45 45 45 20 37 35 34 2d 32 30 30 38 20 72 65  IEEE 754-2008 re
18a0: 61 6c 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20  al value..**.** 
18b0: 56 61 72 69 6e 74 20 76 61 6c 75 65 73 20 61 72  Varint values ar
18c0: 65 20 65 6e 63 6f 64 65 64 20 69 6e 20 74 68 65  e encoded in the
18d0: 20 73 61 6d 65 20 77 61 79 20 61 73 20 76 61 72   same way as var
18e0: 69 6e 74 73 20 69 6e 20 74 68 65 20 53 51 4c 69  ints in the SQLi
18f0: 74 65 20 0a 2a 2a 20 72 65 63 6f 72 64 20 66 6f  te .** record fo
1900: 72 6d 61 74 2e 0a 2a 2a 0a 2a 2a 20 43 48 41 4e  rmat..**.** CHAN
1910: 47 45 53 45 54 20 46 4f 52 4d 41 54 3a 0a 2a 2a  GESET FORMAT:.**
1920: 0a 2a 2a 20 41 20 63 68 61 6e 67 65 73 65 74 20  .** A changeset 
1930: 69 73 20 61 20 63 6f 6c 6c 65 63 74 69 6f 6e 20  is a collection 
1940: 6f 66 20 44 45 4c 45 54 45 2c 20 55 50 44 41 54  of DELETE, UPDAT
1950: 45 20 61 6e 64 20 49 4e 53 45 52 54 20 6f 70 65  E and INSERT ope
1960: 72 61 74 69 6f 6e 73 20 6f 6e 0a 2a 2a 20 6f 6e  rations on.** on
1970: 65 20 6f 72 20 6d 6f 72 65 20 74 61 62 6c 65 73  e or more tables
1980: 2e 20 4f 70 65 72 61 74 69 6f 6e 73 20 6f 6e 20  . Operations on 
1990: 61 20 73 69 6e 67 6c 65 20 74 61 62 6c 65 20 61  a single table a
19a0: 72 65 20 67 72 6f 75 70 65 64 20 74 6f 67 65 74  re grouped toget
19b0: 68 65 72 2c 0a 2a 2a 20 62 75 74 20 6d 61 79 20  her,.** but may 
19c0: 6f 63 63 75 72 20 69 6e 20 61 6e 79 20 6f 72 64  occur in any ord
19d0: 65 72 20 28 69 2e 65 2e 20 64 65 6c 65 74 65 73  er (i.e. deletes
19e0: 2c 20 75 70 64 61 74 65 73 20 61 6e 64 20 69 6e  , updates and in
19f0: 73 65 72 74 73 20 61 72 65 20 61 6c 6c 0a 2a 2a  serts are all.**
1a00: 20 6d 69 78 65 64 20 74 6f 67 65 74 68 65 72 29   mixed together)
1a10: 2e 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20 67 72 6f  ..**.** Each gro
1a20: 75 70 20 6f 66 20 63 68 61 6e 67 65 73 20 62 65  up of changes be
1a30: 67 69 6e 73 20 77 69 74 68 20 61 20 74 61 62 6c  gins with a tabl
1a40: 65 20 68 65 61 64 65 72 3a 0a 2a 2a 0a 2a 2a 20  e header:.**.** 
1a50: 20 20 31 20 62 79 74 65 3a 20 43 6f 6e 73 74 61    1 byte: Consta
1a60: 6e 74 20 30 78 35 34 20 28 63 61 70 69 74 61 6c  nt 0x54 (capital
1a70: 20 27 54 27 29 0a 2a 2a 20 20 20 56 61 72 69 6e   'T').**   Varin
1a80: 74 3a 20 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c  t: Number of col
1a90: 75 6d 6e 73 20 69 6e 20 74 68 65 20 74 61 62 6c  umns in the tabl
1aa0: 65 2e 0a 2a 2a 20 20 20 6e 43 6f 6c 20 62 79 74  e..**   nCol byt
1ab0: 65 73 3a 20 30 78 30 31 20 66 6f 72 20 50 4b 20  es: 0x01 for PK 
1ac0: 63 6f 6c 75 6d 6e 73 2c 20 30 78 30 30 20 6f 74  columns, 0x00 ot
1ad0: 68 65 72 77 69 73 65 2e 0a 2a 2a 20 20 20 4e 20  herwise..**   N 
1ae0: 62 79 74 65 73 3a 20 55 6e 71 75 61 6c 69 66 69  bytes: Unqualifi
1af0: 65 64 20 74 61 62 6c 65 20 6e 61 6d 65 20 28 65  ed table name (e
1b00: 6e 63 6f 64 65 64 20 75 73 69 6e 67 20 55 54 46  ncoded using UTF
1b10: 2d 38 29 2e 20 4e 75 6c 2d 74 65 72 6d 69 6e 61  -8). Nul-termina
1b20: 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 46 6f 6c 6c 6f  ted..**.** Follo
1b30: 77 65 64 20 62 79 20 6f 6e 65 20 6f 72 20 6d 6f  wed by one or mo
1b40: 72 65 20 63 68 61 6e 67 65 73 20 74 6f 20 74 68  re changes to th
1b50: 65 20 74 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 20  e table..**.**  
1b60: 20 31 20 62 79 74 65 3a 20 45 69 74 68 65 72 20   1 byte: Either 
1b70: 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 20 28 30  SQLITE_INSERT (0
1b80: 78 31 32 29 2c 20 55 50 44 41 54 45 20 28 30 78  x12), UPDATE (0x
1b90: 31 37 29 20 6f 72 20 44 45 4c 45 54 45 20 28 30  17) or DELETE (0
1ba0: 78 30 39 29 2e 0a 2a 2a 20 20 20 31 20 62 79 74  x09)..**   1 byt
1bb0: 65 3a 20 54 68 65 20 22 69 6e 64 69 72 65 63 74  e: The "indirect
1bc0: 2d 63 68 61 6e 67 65 22 20 66 6c 61 67 2e 0a 2a  -change" flag..*
1bd0: 2a 20 20 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64  *   old.* record
1be0: 3a 20 28 64 65 6c 65 74 65 20 61 6e 64 20 75 70  : (delete and up
1bf0: 64 61 74 65 20 6f 6e 6c 79 29 0a 2a 2a 20 20 20  date only).**   
1c00: 6e 65 77 2e 2a 20 72 65 63 6f 72 64 3a 20 28 69  new.* record: (i
1c10: 6e 73 65 72 74 20 61 6e 64 20 75 70 64 61 74 65  nsert and update
1c20: 20 6f 6e 6c 79 29 0a 2a 2a 0a 2a 2a 20 54 68 65   only).**.** The
1c30: 20 22 6f 6c 64 2e 2a 22 20 61 6e 64 20 22 6e 65   "old.*" and "ne
1c40: 77 2e 2a 22 20 72 65 63 6f 72 64 73 2c 20 69 66  w.*" records, if
1c50: 20 70 72 65 73 65 6e 74 2c 20 61 72 65 20 4e 20   present, are N 
1c60: 66 69 65 6c 64 20 72 65 63 6f 72 64 73 20 69 6e  field records in
1c70: 20 74 68 65 0a 2a 2a 20 66 6f 72 6d 61 74 20 64   the.** format d
1c80: 65 73 63 72 69 62 65 64 20 61 62 6f 76 65 20 75  escribed above u
1c90: 6e 64 65 72 20 22 52 45 43 4f 52 44 20 46 4f 52  nder "RECORD FOR
1ca0: 4d 41 54 22 2c 20 77 68 65 72 65 20 4e 20 69 73  MAT", where N is
1cb0: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a 2a   the number of.*
1cc0: 2a 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 68 65  * columns in the
1cd0: 20 74 61 62 6c 65 2e 20 54 68 65 20 69 27 74 68   table. The i'th
1ce0: 20 66 69 65 6c 64 20 6f 66 20 65 61 63 68 20 72   field of each r
1cf0: 65 63 6f 72 64 20 69 73 20 61 73 73 6f 63 69 61  ecord is associa
1d00: 74 65 64 20 77 69 74 68 0a 2a 2a 20 74 68 65 20  ted with.** the 
1d10: 69 27 74 68 20 63 6f 6c 75 6d 6e 20 6f 66 20 74  i'th column of t
1d20: 68 65 20 74 61 62 6c 65 2c 20 63 6f 75 6e 74 69  he table, counti
1d30: 6e 67 20 66 72 6f 6d 20 6c 65 66 74 20 74 6f 20  ng from left to 
1d40: 72 69 67 68 74 20 69 6e 20 74 68 65 20 6f 72 64  right in the ord
1d50: 65 72 0a 2a 2a 20 69 6e 20 77 68 69 63 68 20 63  er.** in which c
1d60: 6f 6c 75 6d 6e 73 20 77 65 72 65 20 64 65 63 6c  olumns were decl
1d70: 61 72 65 64 20 69 6e 20 74 68 65 20 43 52 45 41  ared in the CREA
1d80: 54 45 20 54 41 42 4c 45 20 73 74 61 74 65 6d 65  TE TABLE stateme
1d90: 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6e 65  nt..**.** The ne
1da0: 77 2e 2a 20 72 65 63 6f 72 64 20 74 68 61 74 20  w.* record that 
1db0: 69 73 20 70 61 72 74 20 6f 66 20 65 61 63 68 20  is part of each 
1dc0: 49 4e 53 45 52 54 20 63 68 61 6e 67 65 20 63 6f  INSERT change co
1dd0: 6e 74 61 69 6e 73 20 74 68 65 20 76 61 6c 75 65  ntains the value
1de0: 73 0a 2a 2a 20 74 68 61 74 20 6d 61 6b 65 20 75  s.** that make u
1df0: 70 20 74 68 65 20 6e 65 77 20 72 6f 77 2e 20 53  p the new row. S
1e00: 69 6d 69 6c 61 72 6c 79 2c 20 74 68 65 20 6f 6c  imilarly, the ol
1e10: 64 2e 2a 20 72 65 63 6f 72 64 20 74 68 61 74 20  d.* record that 
1e20: 69 73 20 70 61 72 74 20 6f 66 20 65 61 63 68 0a  is part of each.
1e30: 2a 2a 20 44 45 4c 45 54 45 20 63 68 61 6e 67 65  ** DELETE change
1e40: 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 76 61   contains the va
1e50: 6c 75 65 73 20 74 68 61 74 20 6d 61 64 65 20 75  lues that made u
1e60: 70 20 74 68 65 20 72 6f 77 20 74 68 61 74 20 77  p the row that w
1e70: 61 73 20 64 65 6c 65 74 65 64 20 0a 2a 2a 20 66  as deleted .** f
1e80: 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73 65  rom the database
1e90: 2e 20 49 6e 20 74 68 65 20 63 68 61 6e 67 65 73  . In the changes
1ea0: 65 74 20 66 6f 72 6d 61 74 2c 20 74 68 65 20 72  et format, the r
1eb0: 65 63 6f 72 64 73 20 74 68 61 74 20 61 72 65 20  ecords that are 
1ec0: 70 61 72 74 0a 2a 2a 20 6f 66 20 49 4e 53 45 52  part.** of INSER
1ed0: 54 20 6f 72 20 44 45 4c 45 54 45 20 63 68 61 6e  T or DELETE chan
1ee0: 67 65 73 20 6e 65 76 65 72 20 63 6f 6e 74 61 69  ges never contai
1ef0: 6e 20 61 6e 79 20 75 6e 64 65 66 69 6e 65 64 20  n any undefined 
1f00: 28 74 79 70 65 20 62 79 74 65 20 30 78 30 30 29  (type byte 0x00)
1f10: 0a 2a 2a 20 66 69 65 6c 64 73 2e 0a 2a 2a 0a 2a  .** fields..**.*
1f20: 2a 20 57 69 74 68 69 6e 20 74 68 65 20 6f 6c 64  * Within the old
1f30: 2e 2a 20 72 65 63 6f 72 64 20 61 73 73 6f 63 69  .* record associ
1f40: 61 74 65 64 20 77 69 74 68 20 61 6e 20 55 50 44  ated with an UPD
1f50: 41 54 45 20 63 68 61 6e 67 65 2c 20 61 6c 6c 20  ATE change, all 
1f60: 66 69 65 6c 64 73 0a 2a 2a 20 61 73 73 6f 63 69  fields.** associ
1f70: 61 74 65 64 20 77 69 74 68 20 74 61 62 6c 65 20  ated with table 
1f80: 63 6f 6c 75 6d 6e 73 20 74 68 61 74 20 61 72 65  columns that are
1f90: 20 6e 6f 74 20 50 52 49 4d 41 52 59 20 4b 45 59   not PRIMARY KEY
1fa0: 20 63 6f 6c 75 6d 6e 73 20 61 6e 64 20 61 72 65   columns and are
1fb0: 0a 2a 2a 20 6e 6f 74 20 6d 6f 64 69 66 69 65 64  .** not modified
1fc0: 20 62 79 20 74 68 65 20 55 50 44 41 54 45 20 63   by the UPDATE c
1fd0: 68 61 6e 67 65 20 61 72 65 20 73 65 74 20 74 6f  hange are set to
1fe0: 20 22 75 6e 64 65 66 69 6e 65 64 22 2e 20 4f 74   "undefined". Ot
1ff0: 68 65 72 20 66 69 65 6c 64 73 0a 2a 2a 20 61 72  her fields.** ar
2000: 65 20 73 65 74 20 74 6f 20 74 68 65 20 76 61 6c  e set to the val
2010: 75 65 73 20 74 68 61 74 20 6d 61 64 65 20 75 70  ues that made up
2020: 20 74 68 65 20 72 6f 77 20 62 65 66 6f 72 65 20   the row before 
2030: 74 68 65 20 55 50 44 41 54 45 20 74 68 61 74 20  the UPDATE that 
2040: 74 68 65 0a 2a 2a 20 63 68 61 6e 67 65 20 72 65  the.** change re
2050: 63 6f 72 64 73 20 74 6f 6f 6b 20 70 6c 61 63 65  cords took place
2060: 2e 20 57 69 74 68 69 6e 20 74 68 65 20 6e 65 77  . Within the new
2070: 2e 2a 20 72 65 63 6f 72 64 2c 20 66 69 65 6c 64  .* record, field
2080: 73 20 61 73 73 6f 63 69 61 74 65 64 20 0a 2a 2a  s associated .**
2090: 20 77 69 74 68 20 74 61 62 6c 65 20 63 6f 6c 75   with table colu
20a0: 6d 6e 73 20 6d 6f 64 69 66 69 65 64 20 62 79 20  mns modified by 
20b0: 74 68 65 20 55 50 44 41 54 45 20 63 68 61 6e 67  the UPDATE chang
20c0: 65 20 63 6f 6e 74 61 69 6e 20 74 68 65 20 6e 65  e contain the ne
20d0: 77 20 0a 2a 2a 20 76 61 6c 75 65 73 2e 20 46 69  w .** values. Fi
20e0: 65 6c 64 73 20 61 73 73 6f 63 69 61 74 65 64 20  elds associated 
20f0: 77 69 74 68 20 74 61 62 6c 65 20 63 6f 6c 75 6d  with table colum
2100: 6e 73 20 74 68 61 74 20 61 72 65 20 6e 6f 74 20  ns that are not 
2110: 6d 6f 64 69 66 69 65 64 0a 2a 2a 20 61 72 65 20  modified.** are 
2120: 73 65 74 20 74 6f 20 22 75 6e 64 65 66 69 6e 65  set to "undefine
2130: 64 22 2e 0a 2a 2a 0a 2a 2a 20 50 41 54 43 48 53  d"..**.** PATCHS
2140: 45 54 20 46 4f 52 4d 41 54 3a 0a 2a 2a 0a 2a 2a  ET FORMAT:.**.**
2150: 20 41 20 70 61 74 63 68 73 65 74 20 69 73 20 61   A patchset is a
2160: 6c 73 6f 20 61 20 63 6f 6c 6c 65 63 74 69 6f 6e  lso a collection
2170: 20 6f 66 20 63 68 61 6e 67 65 73 2e 20 49 74 20   of changes. It 
2180: 69 73 20 73 69 6d 69 6c 61 72 20 74 6f 20 61 20  is similar to a 
2190: 63 68 61 6e 67 65 73 65 74 2c 0a 2a 2a 20 62 75  changeset,.** bu
21a0: 74 20 6c 65 61 76 65 73 20 75 6e 64 65 66 69 6e  t leaves undefin
21b0: 65 64 20 74 68 6f 73 65 20 66 69 65 6c 64 73 20  ed those fields 
21c0: 74 68 61 74 20 61 72 65 20 6e 6f 74 20 75 73 65  that are not use
21d0: 66 75 6c 20 69 66 20 6e 6f 20 63 6f 6e 66 6c 69  ful if no confli
21e0: 63 74 0a 2a 2a 20 72 65 73 6f 6c 75 74 69 6f 6e  ct.** resolution
21f0: 20 69 73 20 72 65 71 75 69 72 65 64 20 77 68 65   is required whe
2200: 6e 20 61 70 70 6c 79 69 6e 67 20 74 68 65 20 63  n applying the c
2210: 68 61 6e 67 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20  hangeset..**.** 
2220: 45 61 63 68 20 67 72 6f 75 70 20 6f 66 20 63 68  Each group of ch
2230: 61 6e 67 65 73 20 62 65 67 69 6e 73 20 77 69 74  anges begins wit
2240: 68 20 61 20 74 61 62 6c 65 20 68 65 61 64 65 72  h a table header
2250: 3a 0a 2a 2a 0a 2a 2a 20 20 20 31 20 62 79 74 65  :.**.**   1 byte
2260: 3a 20 43 6f 6e 73 74 61 6e 74 20 30 78 35 30 20  : Constant 0x50 
2270: 28 63 61 70 69 74 61 6c 20 27 50 27 29 0a 2a 2a  (capital 'P').**
2280: 20 20 20 56 61 72 69 6e 74 3a 20 4e 75 6d 62 65     Varint: Numbe
2290: 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20  r of columns in 
22a0: 74 68 65 20 74 61 62 6c 65 2e 0a 2a 2a 20 20 20  the table..**   
22b0: 6e 43 6f 6c 20 62 79 74 65 73 3a 20 30 78 30 31  nCol bytes: 0x01
22c0: 20 66 6f 72 20 50 4b 20 63 6f 6c 75 6d 6e 73 2c   for PK columns,
22d0: 20 30 78 30 30 20 6f 74 68 65 72 77 69 73 65 2e   0x00 otherwise.
22e0: 0a 2a 2a 20 20 20 4e 20 62 79 74 65 73 3a 20 55  .**   N bytes: U
22f0: 6e 71 75 61 6c 69 66 69 65 64 20 74 61 62 6c 65  nqualified table
2300: 20 6e 61 6d 65 20 28 65 6e 63 6f 64 65 64 20 75   name (encoded u
2310: 73 69 6e 67 20 55 54 46 2d 38 29 2e 20 4e 75 6c  sing UTF-8). Nul
2320: 2d 74 65 72 6d 69 6e 61 74 65 64 2e 0a 2a 2a 0a  -terminated..**.
2330: 2a 2a 20 46 6f 6c 6c 6f 77 65 64 20 62 79 20 6f  ** Followed by o
2340: 6e 65 20 6f 72 20 6d 6f 72 65 20 63 68 61 6e 67  ne or more chang
2350: 65 73 20 74 6f 20 74 68 65 20 74 61 62 6c 65 2e  es to the table.
2360: 0a 2a 2a 0a 2a 2a 20 20 20 31 20 62 79 74 65 3a  .**.**   1 byte:
2370: 20 45 69 74 68 65 72 20 53 51 4c 49 54 45 5f 49   Either SQLITE_I
2380: 4e 53 45 52 54 20 28 30 78 31 32 29 2c 20 55 50  NSERT (0x12), UP
2390: 44 41 54 45 20 28 30 78 31 37 29 20 6f 72 20 44  DATE (0x17) or D
23a0: 45 4c 45 54 45 20 28 30 78 30 39 29 2e 0a 2a 2a  ELETE (0x09)..**
23b0: 20 20 20 31 20 62 79 74 65 3a 20 54 68 65 20 22     1 byte: The "
23c0: 69 6e 64 69 72 65 63 74 2d 63 68 61 6e 67 65 22  indirect-change"
23d0: 20 66 6c 61 67 2e 0a 2a 2a 20 20 20 73 69 6e 67   flag..**   sing
23e0: 6c 65 20 72 65 63 6f 72 64 3a 20 28 50 4b 20 66  le record: (PK f
23f0: 69 65 6c 64 73 20 66 6f 72 20 44 45 4c 45 54 45  ields for DELETE
2400: 2c 20 50 4b 20 61 6e 64 20 6d 6f 64 69 66 69 65  , PK and modifie
2410: 64 20 66 69 65 6c 64 73 20 66 6f 72 20 55 50 44  d fields for UPD
2420: 41 54 45 2c 0a 2a 2a 20 20 20 20 20 20 20 20 20  ATE,.**         
2430: 20 20 20 20 20 20 20 20 20 20 66 75 6c 6c 20 72            full r
2440: 65 63 6f 72 64 20 66 6f 72 20 49 4e 53 45 52 54  ecord for INSERT
2450: 29 2e 0a 2a 2a 0a 2a 2a 20 41 73 20 69 6e 20 74  )..**.** As in t
2460: 68 65 20 63 68 61 6e 67 65 73 65 74 20 66 6f 72  he changeset for
2470: 6d 61 74 2c 20 65 61 63 68 20 66 69 65 6c 64 20  mat, each field 
2480: 6f 66 20 74 68 65 20 73 69 6e 67 6c 65 20 72 65  of the single re
2490: 63 6f 72 64 20 74 68 61 74 20 69 73 20 70 61 72  cord that is par
24a0: 74 0a 2a 2a 20 6f 66 20 61 20 70 61 74 63 68 73  t.** of a patchs
24b0: 65 74 20 63 68 61 6e 67 65 20 69 73 20 61 73 73  et change is ass
24c0: 6f 63 69 61 74 65 64 20 77 69 74 68 20 74 68 65  ociated with the
24d0: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 6c 79   correspondingly
24e0: 20 70 6f 73 69 74 69 6f 6e 65 64 0a 2a 2a 20 74   positioned.** t
24f0: 61 62 6c 65 20 63 6f 6c 75 6d 6e 2c 20 63 6f 75  able column, cou
2500: 6e 74 69 6e 67 20 66 72 6f 6d 20 6c 65 66 74 20  nting from left 
2510: 74 6f 20 72 69 67 68 74 20 77 69 74 68 69 6e 20  to right within 
2520: 74 68 65 20 43 52 45 41 54 45 20 54 41 42 4c 45  the CREATE TABLE
2530: 20 0a 2a 2a 20 73 74 61 74 65 6d 65 6e 74 2e 0a   .** statement..
2540: 2a 2a 0a 2a 2a 20 46 6f 72 20 61 20 44 45 4c 45  **.** For a DELE
2550: 54 45 20 63 68 61 6e 67 65 2c 20 61 6c 6c 20 66  TE change, all f
2560: 69 65 6c 64 73 20 77 69 74 68 69 6e 20 74 68 65  ields within the
2570: 20 72 65 63 6f 72 64 20 65 78 63 65 70 74 20 74   record except t
2580: 68 6f 73 65 20 61 73 73 6f 63 69 61 74 65 64 0a  hose associated.
2590: 2a 2a 20 77 69 74 68 20 50 52 49 4d 41 52 59 20  ** with PRIMARY 
25a0: 4b 45 59 20 63 6f 6c 75 6d 6e 73 20 61 72 65 20  KEY columns are 
25b0: 73 65 74 20 74 6f 20 22 75 6e 64 65 66 69 6e 65  set to "undefine
25c0: 64 22 2e 20 54 68 65 20 50 52 49 4d 41 52 59 20  d". The PRIMARY 
25d0: 4b 45 59 20 66 69 65 6c 64 73 0a 2a 2a 20 63 6f  KEY fields.** co
25e0: 6e 74 61 69 6e 20 74 68 65 20 76 61 6c 75 65 73  ntain the values
25f0: 20 69 64 65 6e 74 69 66 79 69 6e 67 20 74 68 65   identifying the
2600: 20 72 6f 77 20 74 6f 20 64 65 6c 65 74 65 2e 0a   row to delete..
2610: 2a 2a 0a 2a 2a 20 46 6f 72 20 61 6e 20 55 50 44  **.** For an UPD
2620: 41 54 45 20 63 68 61 6e 67 65 2c 20 61 6c 6c 20  ATE change, all 
2630: 66 69 65 6c 64 73 20 65 78 63 65 70 74 20 74 68  fields except th
2640: 6f 73 65 20 61 73 73 6f 63 69 61 74 65 64 20 77  ose associated w
2650: 69 74 68 20 50 52 49 4d 41 52 59 20 4b 45 59 0a  ith PRIMARY KEY.
2660: 2a 2a 20 63 6f 6c 75 6d 6e 73 20 61 6e 64 20 63  ** columns and c
2670: 6f 6c 75 6d 6e 73 20 74 68 61 74 20 61 72 65 20  olumns that are 
2680: 6d 6f 64 69 66 69 65 64 20 62 79 20 74 68 65 20  modified by the 
2690: 55 50 44 41 54 45 20 61 72 65 20 73 65 74 20 74  UPDATE are set t
26a0: 6f 20 22 75 6e 64 65 66 69 6e 65 64 22 2e 0a 2a  o "undefined"..*
26b0: 2a 20 50 52 49 4d 41 52 59 20 4b 45 59 20 66 69  * PRIMARY KEY fi
26c0: 65 6c 64 73 20 63 6f 6e 74 61 69 6e 20 74 68 65  elds contain the
26d0: 20 76 61 6c 75 65 73 20 69 64 65 6e 74 69 66 79   values identify
26e0: 69 6e 67 20 74 68 65 20 74 61 62 6c 65 20 72 6f  ing the table ro
26f0: 77 20 74 6f 20 75 70 64 61 74 65 2c 0a 2a 2a 20  w to update,.** 
2700: 61 6e 64 20 66 69 65 6c 64 73 20 61 73 73 6f 63  and fields assoc
2710: 69 61 74 65 64 20 77 69 74 68 20 6d 6f 64 69 66  iated with modif
2720: 69 65 64 20 63 6f 6c 75 6d 6e 73 20 63 6f 6e 74  ied columns cont
2730: 61 69 6e 20 74 68 65 20 6e 65 77 20 63 6f 6c 75  ain the new colu
2740: 6d 6e 20 76 61 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a  mn values..**.**
2750: 20 54 68 65 20 72 65 63 6f 72 64 73 20 61 73 73   The records ass
2760: 6f 63 69 61 74 65 64 20 77 69 74 68 20 49 4e 53  ociated with INS
2770: 45 52 54 20 63 68 61 6e 67 65 73 20 61 72 65 20  ERT changes are 
2780: 69 6e 20 74 68 65 20 73 61 6d 65 20 66 6f 72 6d  in the same form
2790: 61 74 20 61 73 20 66 6f 72 0a 2a 2a 20 63 68 61  at as for.** cha
27a0: 6e 67 65 73 65 74 73 2e 20 49 74 20 69 73 20 6e  ngesets. It is n
27b0: 6f 74 20 70 6f 73 73 69 62 6c 65 20 66 6f 72 20  ot possible for 
27c0: 61 20 72 65 63 6f 72 64 20 61 73 73 6f 63 69 61  a record associa
27d0: 74 65 64 20 77 69 74 68 20 61 6e 20 49 4e 53 45  ted with an INSE
27e0: 52 54 0a 2a 2a 20 63 68 61 6e 67 65 20 74 6f 20  RT.** change to 
27f0: 63 6f 6e 74 61 69 6e 20 61 20 66 69 65 6c 64 20  contain a field 
2800: 73 65 74 20 74 6f 20 22 75 6e 64 65 66 69 6e 65  set to "undefine
2810: 64 22 2e 0a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 46 6f  d"..*/../*.** Fo
2820: 72 20 65 61 63 68 20 72 6f 77 20 6d 6f 64 69 66  r each row modif
2830: 69 65 64 20 64 75 72 69 6e 67 20 61 20 73 65 73  ied during a ses
2840: 73 69 6f 6e 2c 20 74 68 65 72 65 20 65 78 69 73  sion, there exis
2850: 74 73 20 61 20 73 69 6e 67 6c 65 20 69 6e 73 74  ts a single inst
2860: 61 6e 63 65 20 6f 66 0a 2a 2a 20 74 68 69 73 20  ance of.** this 
2870: 73 74 72 75 63 74 75 72 65 20 73 74 6f 72 65 64  structure stored
2880: 20 69 6e 20 61 20 53 65 73 73 69 6f 6e 54 61 62   in a SessionTab
2890: 6c 65 2e 61 43 68 61 6e 67 65 5b 5d 20 68 61 73  le.aChange[] has
28a0: 68 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 72 75  h table..*/.stru
28b0: 63 74 20 53 65 73 73 69 6f 6e 43 68 61 6e 67 65  ct SessionChange
28c0: 20 7b 0a 20 20 69 6e 74 20 6f 70 3b 20 20 20 20   {.  int op;    
28d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
28e0: 20 20 20 20 20 2f 2a 20 4f 6e 65 20 6f 66 20 55       /* One of U
28f0: 50 44 41 54 45 2c 20 44 45 4c 45 54 45 2c 20 49  PDATE, DELETE, I
2900: 4e 53 45 52 54 20 2a 2f 0a 20 20 69 6e 74 20 62  NSERT */.  int b
2910: 49 6e 64 69 72 65 63 74 3b 20 20 20 20 20 20 20  Indirect;       
2920: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
2930: 75 65 20 69 66 20 74 68 69 73 20 63 68 61 6e 67  ue if this chang
2940: 65 20 69 73 20 22 69 6e 64 69 72 65 63 74 22 20  e is "indirect" 
2950: 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 63 6f 72 64  */.  int nRecord
2960: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
2970: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
2980: 66 20 62 79 74 65 73 20 69 6e 20 62 75 66 66 65  f bytes in buffe
2990: 72 20 61 52 65 63 6f 72 64 5b 5d 20 2a 2f 0a 20  r aRecord[] */. 
29a0: 20 75 38 20 2a 61 52 65 63 6f 72 64 3b 20 20 20   u8 *aRecord;   
29b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
29c0: 20 2f 2a 20 42 75 66 66 65 72 20 63 6f 6e 74 61   /* Buffer conta
29d0: 69 6e 69 6e 67 20 6f 6c 64 2e 2a 20 72 65 63 6f  ining old.* reco
29e0: 72 64 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 43  rd */.  SessionC
29f0: 68 61 6e 67 65 20 2a 70 4e 65 78 74 3b 20 20 20  hange *pNext;   
2a00: 20 20 20 20 20 20 20 20 2f 2a 20 46 6f 72 20 68          /* For h
2a10: 61 73 68 2d 74 61 62 6c 65 20 63 6f 6c 6c 69 73  ash-table collis
2a20: 69 6f 6e 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  ions */.};../*.*
2a30: 2a 20 57 72 69 74 65 20 61 20 76 61 72 69 6e 74  * Write a varint
2a40: 20 77 69 74 68 20 76 61 6c 75 65 20 69 56 61 6c   with value iVal
2a50: 20 69 6e 74 6f 20 74 68 65 20 62 75 66 66 65 72   into the buffer
2a60: 20 61 74 20 61 42 75 66 2e 20 52 65 74 75 72 6e   at aBuf. Return
2a70: 20 74 68 65 20 0a 2a 2a 20 6e 75 6d 62 65 72 20   the .** number 
2a80: 6f 66 20 62 79 74 65 73 20 77 72 69 74 74 65 6e  of bytes written
2a90: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2aa0: 73 65 73 73 69 6f 6e 56 61 72 69 6e 74 50 75 74  sessionVarintPut
2ab0: 28 75 38 20 2a 61 42 75 66 2c 20 69 6e 74 20 69  (u8 *aBuf, int i
2ac0: 56 61 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20 70  Val){.  return p
2ad0: 75 74 56 61 72 69 6e 74 33 32 28 61 42 75 66 2c  utVarint32(aBuf,
2ae0: 20 69 56 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   iVal);.}../*.**
2af0: 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62   Return the numb
2b00: 65 72 20 6f 66 20 62 79 74 65 73 20 72 65 71 75  er of bytes requ
2b10: 69 72 65 64 20 74 6f 20 73 74 6f 72 65 20 76 61  ired to store va
2b20: 6c 75 65 20 69 56 61 6c 20 61 73 20 61 20 76 61  lue iVal as a va
2b30: 72 69 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  rint..*/.static 
2b40: 69 6e 74 20 73 65 73 73 69 6f 6e 56 61 72 69 6e  int sessionVarin
2b50: 74 4c 65 6e 28 69 6e 74 20 69 56 61 6c 29 7b 0a  tLen(int iVal){.
2b60: 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33    return sqlite3
2b70: 56 61 72 69 6e 74 4c 65 6e 28 69 56 61 6c 29 3b  VarintLen(iVal);
2b80: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 61  .}../*.** Read a
2b90: 20 76 61 72 69 6e 74 20 76 61 6c 75 65 20 66 72   varint value fr
2ba0: 6f 6d 20 61 42 75 66 5b 5d 20 69 6e 74 6f 20 2a  om aBuf[] into *
2bb0: 70 69 56 61 6c 2e 20 52 65 74 75 72 6e 20 74 68  piVal. Return th
2bc0: 65 20 6e 75 6d 62 65 72 20 6f 66 20 0a 2a 2a 20  e number of .** 
2bd0: 62 79 74 65 73 20 72 65 61 64 2e 0a 2a 2f 0a 73  bytes read..*/.s
2be0: 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f  tatic int sessio
2bf0: 6e 56 61 72 69 6e 74 47 65 74 28 75 38 20 2a 61  nVarintGet(u8 *a
2c00: 42 75 66 2c 20 69 6e 74 20 2a 70 69 56 61 6c 29  Buf, int *piVal)
2c10: 7b 0a 20 20 72 65 74 75 72 6e 20 67 65 74 56 61  {.  return getVa
2c20: 72 69 6e 74 33 32 28 61 42 75 66 2c 20 2a 70 69  rint32(aBuf, *pi
2c30: 56 61 6c 29 3b 0a 7d 0a 0a 2f 2a 20 4c 6f 61 64  Val);.}../* Load
2c40: 20 61 6e 20 75 6e 61 6c 69 67 6e 65 64 20 61 6e   an unaligned an
2c50: 64 20 75 6e 73 69 67 6e 65 64 20 33 32 2d 62 69  d unsigned 32-bi
2c60: 74 20 69 6e 74 65 67 65 72 20 2a 2f 0a 23 64 65  t integer */.#de
2c70: 66 69 6e 65 20 53 45 53 53 49 4f 4e 5f 55 49 4e  fine SESSION_UIN
2c80: 54 33 32 28 78 29 20 28 28 28 75 33 32 29 28 78  T32(x) (((u32)(x
2c90: 29 5b 30 5d 3c 3c 32 34 29 7c 28 28 78 29 5b 31  )[0]<<24)|((x)[1
2ca0: 5d 3c 3c 31 36 29 7c 28 28 78 29 5b 32 5d 3c 3c  ]<<16)|((x)[2]<<
2cb0: 38 29 7c 28 78 29 5b 33 5d 29 0a 0a 2f 2a 0a 2a  8)|(x)[3])../*.*
2cc0: 2a 20 52 65 61 64 20 61 20 36 34 2d 62 69 74 20  * Read a 64-bit 
2cd0: 62 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67  big-endian integ
2ce0: 65 72 20 76 61 6c 75 65 20 66 72 6f 6d 20 62 75  er value from bu
2cf0: 66 66 65 72 20 61 52 65 63 5b 5d 2e 20 52 65 74  ffer aRec[]. Ret
2d00: 75 72 6e 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65  urn.** the value
2d10: 20 72 65 61 64 2e 0a 2a 2f 0a 73 74 61 74 69 63   read..*/.static
2d20: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 73   sqlite3_int64 s
2d30: 65 73 73 69 6f 6e 47 65 74 49 36 34 28 75 38 20  essionGetI64(u8 
2d40: 2a 61 52 65 63 29 7b 0a 20 20 75 36 34 20 78 20  *aRec){.  u64 x 
2d50: 3d 20 53 45 53 53 49 4f 4e 5f 55 49 4e 54 33 32  = SESSION_UINT32
2d60: 28 61 52 65 63 29 3b 0a 20 20 75 33 32 20 79 20  (aRec);.  u32 y 
2d70: 3d 20 53 45 53 53 49 4f 4e 5f 55 49 4e 54 33 32  = SESSION_UINT32
2d80: 28 61 52 65 63 2b 34 29 3b 0a 20 20 78 20 3d 20  (aRec+4);.  x = 
2d90: 28 78 3c 3c 33 32 29 20 2b 20 79 3b 0a 20 20 72  (x<<32) + y;.  r
2da0: 65 74 75 72 6e 20 28 73 71 6c 69 74 65 33 5f 69  eturn (sqlite3_i
2db0: 6e 74 36 34 29 78 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  nt64)x;.}../*.**
2dc0: 20 57 72 69 74 65 20 61 20 36 34 2d 62 69 74 20   Write a 64-bit 
2dd0: 62 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67  big-endian integ
2de0: 65 72 20 76 61 6c 75 65 20 74 6f 20 74 68 65 20  er value to the 
2df0: 62 75 66 66 65 72 20 61 42 75 66 5b 5d 2e 0a 2a  buffer aBuf[]..*
2e00: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 65  /.static void se
2e10: 73 73 69 6f 6e 50 75 74 49 36 34 28 75 38 20 2a  ssionPutI64(u8 *
2e20: 61 42 75 66 2c 20 73 71 6c 69 74 65 33 5f 69 6e  aBuf, sqlite3_in
2e30: 74 36 34 20 69 29 7b 0a 20 20 61 42 75 66 5b 30  t64 i){.  aBuf[0
2e40: 5d 20 3d 20 28 69 3e 3e 35 36 29 20 26 20 30 78  ] = (i>>56) & 0x
2e50: 46 46 3b 0a 20 20 61 42 75 66 5b 31 5d 20 3d 20  FF;.  aBuf[1] = 
2e60: 28 69 3e 3e 34 38 29 20 26 20 30 78 46 46 3b 0a  (i>>48) & 0xFF;.
2e70: 20 20 61 42 75 66 5b 32 5d 20 3d 20 28 69 3e 3e    aBuf[2] = (i>>
2e80: 34 30 29 20 26 20 30 78 46 46 3b 0a 20 20 61 42  40) & 0xFF;.  aB
2e90: 75 66 5b 33 5d 20 3d 20 28 69 3e 3e 33 32 29 20  uf[3] = (i>>32) 
2ea0: 26 20 30 78 46 46 3b 0a 20 20 61 42 75 66 5b 34  & 0xFF;.  aBuf[4
2eb0: 5d 20 3d 20 28 69 3e 3e 32 34 29 20 26 20 30 78  ] = (i>>24) & 0x
2ec0: 46 46 3b 0a 20 20 61 42 75 66 5b 35 5d 20 3d 20  FF;.  aBuf[5] = 
2ed0: 28 69 3e 3e 31 36 29 20 26 20 30 78 46 46 3b 0a  (i>>16) & 0xFF;.
2ee0: 20 20 61 42 75 66 5b 36 5d 20 3d 20 28 69 3e 3e    aBuf[6] = (i>>
2ef0: 20 38 29 20 26 20 30 78 46 46 3b 0a 20 20 61 42   8) & 0xFF;.  aB
2f00: 75 66 5b 37 5d 20 3d 20 28 69 3e 3e 20 30 29 20  uf[7] = (i>> 0) 
2f10: 26 20 30 78 46 46 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  & 0xFF;.}../*.**
2f20: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
2f30: 73 20 75 73 65 64 20 74 6f 20 73 65 72 69 61 6c  s used to serial
2f40: 69 7a 65 20 74 68 65 20 63 6f 6e 74 65 6e 74 73  ize the contents
2f50: 20 6f 66 20 76 61 6c 75 65 20 70 56 61 6c 75 65   of value pValue
2f60: 20 28 73 65 65 0a 2a 2a 20 63 6f 6d 6d 65 6e 74   (see.** comment
2f70: 20 74 69 74 6c 65 64 20 22 52 45 43 4f 52 44 20   titled "RECORD 
2f80: 46 4f 52 4d 41 54 22 20 61 62 6f 76 65 29 2e 0a  FORMAT" above)..
2f90: 2a 2a 0a 2a 2a 20 49 66 20 69 74 20 69 73 20 6e  **.** If it is n
2fa0: 6f 6e 2d 4e 55 4c 4c 2c 20 74 68 65 20 73 65 72  on-NULL, the ser
2fb0: 69 61 6c 69 7a 65 64 20 66 6f 72 6d 20 6f 66 20  ialized form of 
2fc0: 74 68 65 20 76 61 6c 75 65 20 69 73 20 77 72 69  the value is wri
2fd0: 74 74 65 6e 20 74 6f 20 0a 2a 2a 20 62 75 66 66  tten to .** buff
2fe0: 65 72 20 61 42 75 66 2e 20 2a 70 6e 57 72 69 74  er aBuf. *pnWrit
2ff0: 65 20 69 73 20 73 65 74 20 74 6f 20 74 68 65 20  e is set to the 
3000: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
3010: 77 72 69 74 74 65 6e 20 62 65 66 6f 72 65 0a 2a  written before.*
3020: 2a 20 72 65 74 75 72 6e 69 6e 67 2e 20 4f 72 2c  * returning. Or,
3030: 20 69 66 20 61 42 75 66 20 69 73 20 4e 55 4c 4c   if aBuf is NULL
3040: 2c 20 74 68 65 20 6f 6e 6c 79 20 74 68 69 6e 67  , the only thing
3050: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 64   this function d
3060: 6f 65 73 20 69 73 0a 2a 2a 20 73 65 74 20 2a 70  oes is.** set *p
3070: 6e 57 72 69 74 65 2e 0a 2a 2a 0a 2a 2a 20 49 66  nWrite..**.** If
3080: 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73   no error occurs
3090: 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72  , SQLITE_OK is r
30a0: 65 74 75 72 6e 65 64 2e 20 4f 72 2c 20 69 66 20  eturned. Or, if 
30b0: 61 6e 20 4f 4f 4d 20 65 72 72 6f 72 20 6f 63 63  an OOM error occ
30c0: 75 72 73 0a 2a 2a 20 77 69 74 68 69 6e 20 61 20  urs.** within a 
30d0: 63 61 6c 6c 20 74 6f 20 73 71 6c 69 74 65 33 5f  call to sqlite3_
30e0: 76 61 6c 75 65 5f 74 65 78 74 28 29 20 28 6d 61  value_text() (ma
30f0: 79 20 66 61 69 6c 20 69 66 20 74 68 65 20 64 62  y fail if the db
3100: 20 69 73 20 75 74 66 2d 31 36 29 29 20 0a 2a 2a   is utf-16)) .**
3110: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 69 73   SQLITE_NOMEM is
3120: 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2f 0a 73 74   returned..*/.st
3130: 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e  atic int session
3140: 53 65 72 69 61 6c 69 7a 65 56 61 6c 75 65 28 0a  SerializeValue(.
3150: 20 20 75 38 20 2a 61 42 75 66 2c 20 20 20 20 20    u8 *aBuf,     
3160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3170: 20 20 2f 2a 20 49 66 20 6e 6f 6e 2d 4e 55 4c 4c    /* If non-NULL
3180: 2c 20 77 72 69 74 65 20 73 65 72 69 61 6c 69 7a  , write serializ
3190: 65 64 20 76 61 6c 75 65 20 68 65 72 65 20 2a 2f  ed value here */
31a0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  .  sqlite3_value
31b0: 20 2a 70 56 61 6c 75 65 2c 20 20 20 20 20 20 20   *pValue,       
31c0: 20 20 20 2f 2a 20 56 61 6c 75 65 20 74 6f 20 73     /* Value to s
31d0: 65 72 69 61 6c 69 7a 65 20 2a 2f 0a 20 20 69 6e  erialize */.  in
31e0: 74 20 2a 70 6e 57 72 69 74 65 20 20 20 20 20 20  t *pnWrite      
31f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3200: 20 49 4e 2f 4f 55 54 3a 20 49 6e 63 72 65 6d 65   IN/OUT: Increme
3210: 6e 74 20 62 79 20 62 79 74 65 73 20 77 72 69 74  nt by bytes writ
3220: 74 65 6e 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  ten */.){.  int 
3230: 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20 20 20  nByte;          
3240: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
3250: 69 7a 65 20 6f 66 20 73 65 72 69 61 6c 69 7a 65  ize of serialize
3260: 64 20 76 61 6c 75 65 20 69 6e 20 62 79 74 65 73  d value in bytes
3270: 20 2a 2f 0a 0a 20 20 69 66 28 20 70 56 61 6c 75   */..  if( pValu
3280: 65 20 29 7b 0a 20 20 20 20 69 6e 74 20 65 54 79  e ){.    int eTy
3290: 70 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  pe;             
32a0: 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20         /* Value 
32b0: 74 79 70 65 20 28 53 51 4c 49 54 45 5f 4e 55 4c  type (SQLITE_NUL
32c0: 4c 2c 20 54 45 58 54 20 65 74 63 2e 29 20 2a 2f  L, TEXT etc.) */
32d0: 0a 20 20 0a 20 20 20 20 65 54 79 70 65 20 3d 20  .  .    eType = 
32e0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79  sqlite3_value_ty
32f0: 70 65 28 70 56 61 6c 75 65 29 3b 0a 20 20 20 20  pe(pValue);.    
3300: 69 66 28 20 61 42 75 66 20 29 20 61 42 75 66 5b  if( aBuf ) aBuf[
3310: 30 5d 20 3d 20 65 54 79 70 65 3b 0a 20 20 0a 20  0] = eType;.  . 
3320: 20 20 20 73 77 69 74 63 68 28 20 65 54 79 70 65     switch( eType
3330: 20 29 7b 0a 20 20 20 20 20 20 63 61 73 65 20 53   ){.      case S
3340: 51 4c 49 54 45 5f 4e 55 4c 4c 3a 20 0a 20 20 20  QLITE_NULL: .   
3350: 20 20 20 20 20 6e 42 79 74 65 20 3d 20 31 3b 0a       nByte = 1;.
3360: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
3370: 20 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c   .      case SQL
3380: 49 54 45 5f 49 4e 54 45 47 45 52 3a 20 0a 20 20  ITE_INTEGER: .  
3390: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
33a0: 46 4c 4f 41 54 3a 0a 20 20 20 20 20 20 20 20 69  FLOAT:.        i
33b0: 66 28 20 61 42 75 66 20 29 7b 0a 20 20 20 20 20  f( aBuf ){.     
33c0: 20 20 20 20 20 2f 2a 20 54 4f 44 4f 3a 20 53 51       /* TODO: SQ
33d0: 4c 69 74 65 20 64 6f 65 73 20 73 6f 6d 65 74 68  Lite does someth
33e0: 69 6e 67 20 73 70 65 63 69 61 6c 20 74 6f 20 64  ing special to d
33f0: 65 61 6c 20 77 69 74 68 20 6d 69 78 65 64 2d 65  eal with mixed-e
3400: 6e 64 69 61 6e 0a 20 20 20 20 20 20 20 20 20 20  ndian.          
3410: 2a 2a 20 66 6c 6f 61 74 69 6e 67 20 70 6f 69 6e  ** floating poin
3420: 74 20 76 61 6c 75 65 73 20 28 65 2e 67 2e 20 41  t values (e.g. A
3430: 52 4d 37 29 2e 20 54 68 69 73 20 63 6f 64 65 20  RM7). This code 
3440: 70 72 6f 62 61 62 6c 79 20 73 68 6f 75 6c 64 0a  probably should.
3450: 20 20 20 20 20 20 20 20 20 20 2a 2a 20 74 6f 6f            ** too
3460: 2e 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20  .  */.          
3470: 75 36 34 20 69 3b 0a 20 20 20 20 20 20 20 20 20  u64 i;.         
3480: 20 69 66 28 20 65 54 79 70 65 3d 3d 53 51 4c 49   if( eType==SQLI
3490: 54 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20 20  TE_INTEGER ){.  
34a0: 20 20 20 20 20 20 20 20 20 20 69 20 3d 20 28 75            i = (u
34b0: 36 34 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  64)sqlite3_value
34c0: 5f 69 6e 74 36 34 28 70 56 61 6c 75 65 29 3b 0a  _int64(pValue);.
34d0: 20 20 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b            }else{
34e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 6f 75  .            dou
34f0: 62 6c 65 20 72 3b 0a 20 20 20 20 20 20 20 20 20  ble r;.         
3500: 20 20 20 61 73 73 65 72 74 28 20 73 69 7a 65 6f     assert( sizeo
3510: 66 28 64 6f 75 62 6c 65 29 3d 3d 38 20 26 26 20  f(double)==8 && 
3520: 73 69 7a 65 6f 66 28 75 36 34 29 3d 3d 38 20 29  sizeof(u64)==8 )
3530: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 20  ;.            r 
3540: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
3550: 64 6f 75 62 6c 65 28 70 56 61 6c 75 65 29 3b 0a  double(pValue);.
3560: 20 20 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63              memc
3570: 70 79 28 26 69 2c 20 26 72 2c 20 38 29 3b 0a 20  py(&i, &r, 8);. 
3580: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
3590: 20 20 20 20 20 73 65 73 73 69 6f 6e 50 75 74 49       sessionPutI
35a0: 36 34 28 26 61 42 75 66 5b 31 5d 2c 20 69 29 3b  64(&aBuf[1], i);
35b0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
35c0: 20 20 20 6e 42 79 74 65 20 3d 20 39 3b 20 0a 20     nByte = 9; . 
35d0: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
35e0: 0a 20 20 20 20 20 20 64 65 66 61 75 6c 74 3a 20  .      default: 
35f0: 7b 0a 20 20 20 20 20 20 20 20 75 38 20 2a 7a 3b  {.        u8 *z;
3600: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 3b 0a  .        int n;.
3610: 20 20 20 20 20 20 20 20 69 6e 74 20 6e 56 61 72          int nVar
3620: 69 6e 74 3b 0a 20 20 0a 20 20 20 20 20 20 20 20  int;.  .        
3630: 61 73 73 65 72 74 28 20 65 54 79 70 65 3d 3d 53  assert( eType==S
3640: 51 4c 49 54 45 5f 54 45 58 54 20 7c 7c 20 65 54  QLITE_TEXT || eT
3650: 79 70 65 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f 42  ype==SQLITE_BLOB
3660: 20 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20   );.        if( 
3670: 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 54 45  eType==SQLITE_TE
3680: 58 54 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  XT ){.          
3690: 7a 20 3d 20 28 75 38 20 2a 29 73 71 6c 69 74 65  z = (u8 *)sqlite
36a0: 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 70 56 61  3_value_text(pVa
36b0: 6c 75 65 29 3b 0a 20 20 20 20 20 20 20 20 7d 65  lue);.        }e
36c0: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 7a  lse{.          z
36d0: 20 3d 20 28 75 38 20 2a 29 73 71 6c 69 74 65 33   = (u8 *)sqlite3
36e0: 5f 76 61 6c 75 65 5f 62 6c 6f 62 28 70 56 61 6c  _value_blob(pVal
36f0: 75 65 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  ue);.        }. 
3700: 20 20 20 20 20 20 20 6e 20 3d 20 73 71 6c 69 74         n = sqlit
3710: 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 70  e3_value_bytes(p
3720: 56 61 6c 75 65 29 3b 0a 20 20 20 20 20 20 20 20  Value);.        
3730: 69 66 28 20 7a 3d 3d 30 20 26 26 20 28 65 54 79  if( z==0 && (eTy
3740: 70 65 21 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 20  pe!=SQLITE_BLOB 
3750: 7c 7c 20 6e 3e 30 29 20 29 20 72 65 74 75 72 6e  || n>0) ) return
3760: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
3770: 20 20 20 20 20 20 20 6e 56 61 72 69 6e 74 20 3d         nVarint =
3780: 20 73 65 73 73 69 6f 6e 56 61 72 69 6e 74 4c 65   sessionVarintLe
3790: 6e 28 6e 29 3b 0a 20 20 0a 20 20 20 20 20 20 20  n(n);.  .       
37a0: 20 69 66 28 20 61 42 75 66 20 29 7b 0a 20 20 20   if( aBuf ){.   
37b0: 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 56 61         sessionVa
37c0: 72 69 6e 74 50 75 74 28 26 61 42 75 66 5b 31 5d  rintPut(&aBuf[1]
37d0: 2c 20 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20  , n);.          
37e0: 69 66 28 20 6e 20 29 20 6d 65 6d 63 70 79 28 26  if( n ) memcpy(&
37f0: 61 42 75 66 5b 6e 56 61 72 69 6e 74 20 2b 20 31  aBuf[nVarint + 1
3800: 5d 2c 20 7a 2c 20 6e 29 3b 0a 20 20 20 20 20 20  ], z, n);.      
3810: 20 20 7d 0a 20 20 0a 20 20 20 20 20 20 20 20 6e    }.  .        n
3820: 42 79 74 65 20 3d 20 31 20 2b 20 6e 56 61 72 69  Byte = 1 + nVari
3830: 6e 74 20 2b 20 6e 3b 0a 20 20 20 20 20 20 20 20  nt + n;.        
3840: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20  break;.      }. 
3850: 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20     }.  }else{.  
3860: 20 20 6e 42 79 74 65 20 3d 20 31 3b 0a 20 20 20    nByte = 1;.   
3870: 20 69 66 28 20 61 42 75 66 20 29 20 61 42 75 66   if( aBuf ) aBuf
3880: 5b 30 5d 20 3d 20 27 5c 30 27 3b 0a 20 20 7d 0a  [0] = '\0';.  }.
3890: 0a 20 20 69 66 28 20 70 6e 57 72 69 74 65 20 29  .  if( pnWrite )
38a0: 20 2a 70 6e 57 72 69 74 65 20 2b 3d 20 6e 42 79   *pnWrite += nBy
38b0: 74 65 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  te;.  return SQL
38c0: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  ITE_OK;.}.../*.*
38d0: 2a 20 54 68 69 73 20 6d 61 63 72 6f 20 69 73 20  * This macro is 
38e0: 75 73 65 64 20 74 6f 20 63 61 6c 63 75 6c 61 74  used to calculat
38f0: 65 20 68 61 73 68 20 6b 65 79 20 76 61 6c 75 65  e hash key value
3900: 73 20 66 6f 72 20 64 61 74 61 20 73 74 72 75 63  s for data struc
3910: 74 75 72 65 73 2e 20 49 6e 0a 2a 2a 20 6f 72 64  tures. In.** ord
3920: 65 72 20 74 6f 20 75 73 65 20 74 68 69 73 20 6d  er to use this m
3930: 61 63 72 6f 2c 20 74 68 65 20 65 6e 74 69 72 65  acro, the entire
3940: 20 64 61 74 61 20 73 74 72 75 63 74 75 72 65 20   data structure 
3950: 6d 75 73 74 20 62 65 20 72 65 70 72 65 73 65 6e  must be represen
3960: 74 65 64 0a 2a 2a 20 61 73 20 61 20 73 65 72 69  ted.** as a seri
3970: 65 73 20 6f 66 20 75 6e 73 69 67 6e 65 64 20 69  es of unsigned i
3980: 6e 74 65 67 65 72 73 2e 20 49 6e 20 6f 72 64 65  ntegers. In orde
3990: 72 20 74 6f 20 63 61 6c 63 75 6c 61 74 65 20 61  r to calculate a
39a0: 20 68 61 73 68 2d 6b 65 79 20 76 61 6c 75 65 0a   hash-key value.
39b0: 2a 2a 20 66 6f 72 20 61 20 64 61 74 61 20 73 74  ** for a data st
39c0: 72 75 63 74 75 72 65 20 72 65 70 72 65 73 65 6e  ructure represen
39d0: 74 65 64 20 61 73 20 74 68 72 65 65 20 73 75 63  ted as three suc
39e0: 68 20 69 6e 74 65 67 65 72 73 2c 20 74 68 65 20  h integers, the 
39f0: 6d 61 63 72 6f 20 6d 61 79 0a 2a 2a 20 74 68 65  macro may.** the
3a00: 6e 20 62 65 20 75 73 65 64 20 61 73 20 66 6f 6c  n be used as fol
3a10: 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 69  lows:.**.**    i
3a20: 6e 74 20 68 61 73 68 5f 6b 65 79 5f 76 61 6c 75  nt hash_key_valu
3a30: 65 3b 0a 2a 2a 20 20 20 20 68 61 73 68 5f 6b 65  e;.**    hash_ke
3a40: 79 5f 76 61 6c 75 65 20 3d 20 48 41 53 48 5f 41  y_value = HASH_A
3a50: 50 50 45 4e 44 28 30 2c 20 3c 76 61 6c 75 65 20  PPEND(0, <value 
3a60: 31 3e 29 3b 0a 2a 2a 20 20 20 20 68 61 73 68 5f  1>);.**    hash_
3a70: 6b 65 79 5f 76 61 6c 75 65 20 3d 20 48 41 53 48  key_value = HASH
3a80: 5f 41 50 50 45 4e 44 28 68 61 73 68 5f 6b 65 79  _APPEND(hash_key
3a90: 5f 76 61 6c 75 65 2c 20 3c 76 61 6c 75 65 20 32  _value, <value 2
3aa0: 3e 29 3b 0a 2a 2a 20 20 20 20 68 61 73 68 5f 6b  >);.**    hash_k
3ab0: 65 79 5f 76 61 6c 75 65 20 3d 20 48 41 53 48 5f  ey_value = HASH_
3ac0: 41 50 50 45 4e 44 28 68 61 73 68 5f 6b 65 79 5f  APPEND(hash_key_
3ad0: 76 61 6c 75 65 2c 20 3c 76 61 6c 75 65 20 33 3e  value, <value 3>
3ae0: 29 3b 0a 2a 2a 0a 2a 2a 20 49 6e 20 70 72 61 63  );.**.** In prac
3af0: 74 69 63 65 2c 20 74 68 65 20 64 61 74 61 20 73  tice, the data s
3b00: 74 72 75 63 74 75 72 65 73 20 74 68 69 73 20 6d  tructures this m
3b10: 61 63 72 6f 20 69 73 20 75 73 65 64 20 66 6f 72  acro is used for
3b20: 20 61 72 65 20 74 68 65 20 70 72 69 6d 61 72 79   are the primary
3b30: 0a 2a 2a 20 6b 65 79 20 76 61 6c 75 65 73 20 6f  .** key values o
3b40: 66 20 6d 6f 64 69 66 69 65 64 20 72 6f 77 73 2e  f modified rows.
3b50: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 48 41 53 48  .*/.#define HASH
3b60: 5f 41 50 50 45 4e 44 28 68 61 73 68 2c 20 61 64  _APPEND(hash, ad
3b70: 64 29 20 28 28 68 61 73 68 29 20 3c 3c 20 33 29  d) ((hash) << 3)
3b80: 20 5e 20 28 68 61 73 68 29 20 5e 20 28 75 6e 73   ^ (hash) ^ (uns
3b90: 69 67 6e 65 64 20 69 6e 74 29 28 61 64 64 29 0a  igned int)(add).
3ba0: 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 74 68  ./*.** Append th
3bb0: 65 20 68 61 73 68 20 6f 66 20 74 68 65 20 36 34  e hash of the 64
3bc0: 2d 62 69 74 20 69 6e 74 65 67 65 72 20 70 61 73  -bit integer pas
3bd0: 73 65 64 20 61 73 20 74 68 65 20 73 65 63 6f 6e  sed as the secon
3be0: 64 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 74 68  d argument to th
3bf0: 65 0a 2a 2a 20 68 61 73 68 2d 6b 65 79 20 76 61  e.** hash-key va
3c00: 6c 75 65 20 70 61 73 73 65 64 20 61 73 20 74 68  lue passed as th
3c10: 65 20 66 69 72 73 74 2e 20 52 65 74 75 72 6e 20  e first. Return 
3c20: 74 68 65 20 6e 65 77 20 68 61 73 68 2d 6b 65 79  the new hash-key
3c30: 20 76 61 6c 75 65 2e 0a 2a 2f 0a 73 74 61 74 69   value..*/.stati
3c40: 63 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 73  c unsigned int s
3c50: 65 73 73 69 6f 6e 48 61 73 68 41 70 70 65 6e 64  essionHashAppend
3c60: 49 36 34 28 75 6e 73 69 67 6e 65 64 20 69 6e 74  I64(unsigned int
3c70: 20 68 2c 20 69 36 34 20 69 29 7b 0a 20 20 68 20   h, i64 i){.  h 
3c80: 3d 20 48 41 53 48 5f 41 50 50 45 4e 44 28 68 2c  = HASH_APPEND(h,
3c90: 20 69 20 26 20 30 78 46 46 46 46 46 46 46 46 29   i & 0xFFFFFFFF)
3ca0: 3b 0a 20 20 72 65 74 75 72 6e 20 48 41 53 48 5f  ;.  return HASH_
3cb0: 41 50 50 45 4e 44 28 68 2c 20 28 69 3e 3e 33 32  APPEND(h, (i>>32
3cc0: 29 26 30 78 46 46 46 46 46 46 46 46 29 3b 0a 7d  )&0xFFFFFFFF);.}
3cd0: 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 74  ../*.** Append t
3ce0: 68 65 20 68 61 73 68 20 6f 66 20 74 68 65 20 62  he hash of the b
3cf0: 6c 6f 62 20 70 61 73 73 65 64 20 76 69 61 20 74  lob passed via t
3d00: 68 65 20 73 65 63 6f 6e 64 20 61 6e 64 20 74 68  he second and th
3d10: 69 72 64 20 61 72 67 75 6d 65 6e 74 73 20 74 6f  ird arguments to
3d20: 20 0a 2a 2a 20 74 68 65 20 68 61 73 68 2d 6b 65   .** the hash-ke
3d30: 79 20 76 61 6c 75 65 20 70 61 73 73 65 64 20 61  y value passed a
3d40: 73 20 74 68 65 20 66 69 72 73 74 2e 20 52 65 74  s the first. Ret
3d50: 75 72 6e 20 74 68 65 20 6e 65 77 20 68 61 73 68  urn the new hash
3d60: 2d 6b 65 79 20 76 61 6c 75 65 2e 0a 2a 2f 0a 73  -key value..*/.s
3d70: 74 61 74 69 63 20 75 6e 73 69 67 6e 65 64 20 69  tatic unsigned i
3d80: 6e 74 20 73 65 73 73 69 6f 6e 48 61 73 68 41 70  nt sessionHashAp
3d90: 70 65 6e 64 42 6c 6f 62 28 75 6e 73 69 67 6e 65  pendBlob(unsigne
3da0: 64 20 69 6e 74 20 68 2c 20 69 6e 74 20 6e 2c 20  d int h, int n, 
3db0: 63 6f 6e 73 74 20 75 38 20 2a 7a 29 7b 0a 20 20  const u8 *z){.  
3dc0: 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30  int i;.  for(i=0
3dd0: 3b 20 69 3c 6e 3b 20 69 2b 2b 29 20 68 20 3d 20  ; i<n; i++) h = 
3de0: 48 41 53 48 5f 41 50 50 45 4e 44 28 68 2c 20 7a  HASH_APPEND(h, z
3df0: 5b 69 5d 29 3b 0a 20 20 72 65 74 75 72 6e 20 68  [i]);.  return h
3e00: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e  ;.}../*.** Appen
3e10: 64 20 74 68 65 20 68 61 73 68 20 6f 66 20 74 68  d the hash of th
3e20: 65 20 64 61 74 61 20 74 79 70 65 20 70 61 73 73  e data type pass
3e30: 65 64 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64  ed as the second
3e40: 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 74 68 65   argument to the
3e50: 0a 2a 2a 20 68 61 73 68 2d 6b 65 79 20 76 61 6c  .** hash-key val
3e60: 75 65 20 70 61 73 73 65 64 20 61 73 20 74 68 65  ue passed as the
3e70: 20 66 69 72 73 74 2e 20 52 65 74 75 72 6e 20 74   first. Return t
3e80: 68 65 20 6e 65 77 20 68 61 73 68 2d 6b 65 79 20  he new hash-key 
3e90: 76 61 6c 75 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  value..*/.static
3ea0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 73 65   unsigned int se
3eb0: 73 73 69 6f 6e 48 61 73 68 41 70 70 65 6e 64 54  ssionHashAppendT
3ec0: 79 70 65 28 75 6e 73 69 67 6e 65 64 20 69 6e 74  ype(unsigned int
3ed0: 20 68 2c 20 69 6e 74 20 65 54 79 70 65 29 7b 0a   h, int eType){.
3ee0: 20 20 72 65 74 75 72 6e 20 48 41 53 48 5f 41 50    return HASH_AP
3ef0: 50 45 4e 44 28 68 2c 20 65 54 79 70 65 29 3b 0a  PEND(h, eType);.
3f00: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
3f10: 6e 63 74 69 6f 6e 20 6d 61 79 20 6f 6e 6c 79 20  nction may only 
3f20: 62 65 20 63 61 6c 6c 65 64 20 66 72 6f 6d 20 77  be called from w
3f30: 69 74 68 69 6e 20 61 20 70 72 65 2d 75 70 64 61  ithin a pre-upda
3f40: 74 65 20 63 61 6c 6c 62 61 63 6b 2e 0a 2a 2a 20  te callback..** 
3f50: 49 74 20 63 61 6c 63 75 6c 61 74 65 73 20 61 20  It calculates a 
3f60: 68 61 73 68 20 62 61 73 65 64 20 6f 6e 20 74 68  hash based on th
3f70: 65 20 70 72 69 6d 61 72 79 20 6b 65 79 20 76 61  e primary key va
3f80: 6c 75 65 73 20 6f 66 20 74 68 65 20 6f 6c 64 2e  lues of the old.
3f90: 2a 20 6f 72 20 0a 2a 2a 20 6e 65 77 2e 2a 20 72  * or .** new.* r
3fa0: 6f 77 20 63 75 72 72 65 6e 74 6c 79 20 61 76 61  ow currently ava
3fb0: 69 6c 61 62 6c 65 20 61 6e 64 2c 20 61 73 73 75  ilable and, assu
3fc0: 6d 69 6e 67 20 6e 6f 20 65 72 72 6f 72 20 6f 63  ming no error oc
3fd0: 63 75 72 73 2c 20 77 72 69 74 65 73 20 69 74 20  curs, writes it 
3fe0: 74 6f 0a 2a 2a 20 2a 70 69 48 61 73 68 20 62 65  to.** *piHash be
3ff0: 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 20  fore returning. 
4000: 49 66 20 74 68 65 20 70 72 69 6d 61 72 79 20 6b  If the primary k
4010: 65 79 20 63 6f 6e 74 61 69 6e 73 20 6f 6e 65 20  ey contains one 
4020: 6f 72 20 6d 6f 72 65 20 4e 55 4c 4c 0a 2a 2a 20  or more NULL.** 
4030: 76 61 6c 75 65 73 2c 20 2a 70 62 4e 75 6c 6c 50  values, *pbNullP
4040: 4b 20 69 73 20 73 65 74 20 74 6f 20 74 72 75 65  K is set to true
4050: 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e   before returnin
4060: 67 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 65  g..**.** If an e
4070: 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 61 6e 20  rror occurs, an 
4080: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
4090: 65 20 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e  e is returned an
40a0: 64 20 74 68 65 20 66 69 6e 61 6c 20 76 61 6c 75  d the final valu
40b0: 65 73 0a 2a 2a 20 6f 66 20 2a 70 69 48 61 73 68  es.** of *piHash
40c0: 20 61 73 6e 20 2a 70 62 4e 75 6c 6c 50 4b 20 61   asn *pbNullPK a
40d0: 72 65 20 75 6e 64 65 66 69 6e 65 64 2e 20 4f 74  re undefined. Ot
40e0: 68 65 72 77 69 73 65 2c 20 53 51 4c 49 54 45 5f  herwise, SQLITE_
40f0: 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 0a 2a  OK is returned.*
4100: 2a 20 61 6e 64 20 74 68 65 20 6f 75 74 70 75 74  * and the output
4110: 20 76 61 72 69 61 62 6c 65 73 20 61 72 65 20 73   variables are s
4120: 65 74 20 61 73 20 64 65 73 63 72 69 62 65 64 20  et as described 
4130: 61 62 6f 76 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  above..*/.static
4140: 20 69 6e 74 20 73 65 73 73 69 6f 6e 50 72 65 75   int sessionPreu
4150: 70 64 61 74 65 48 61 73 68 28 0a 20 20 73 71 6c  pdateHash(.  sql
4160: 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53  ite3_session *pS
4170: 65 73 73 69 6f 6e 2c 20 20 20 20 20 20 2f 2a 20  ession,      /* 
4180: 53 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 74  Session object t
4190: 68 61 74 20 6f 77 6e 73 20 70 54 61 62 20 2a 2f  hat owns pTab */
41a0: 0a 20 20 53 65 73 73 69 6f 6e 54 61 62 6c 65 20  .  SessionTable 
41b0: 2a 70 54 61 62 2c 20 20 20 20 20 20 20 20 20 20  *pTab,          
41c0: 20 20 20 2f 2a 20 53 65 73 73 69 6f 6e 20 74 61     /* Session ta
41d0: 62 6c 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20  ble handle */.  
41e0: 69 6e 74 20 62 4e 65 77 2c 20 20 20 20 20 20 20  int bNew,       
41f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4200: 2f 2a 20 54 72 75 65 20 74 6f 20 68 61 73 68 20  /* True to hash 
4210: 74 68 65 20 6e 65 77 2e 2a 20 50 4b 20 2a 2f 0a  the new.* PK */.
4220: 20 20 69 6e 74 20 2a 70 69 48 61 73 68 2c 20 20    int *piHash,  
4230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4240: 20 20 2f 2a 20 4f 55 54 3a 20 48 61 73 68 20 76    /* OUT: Hash v
4250: 61 6c 75 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  alue */.  int *p
4260: 62 4e 75 6c 6c 50 4b 20 20 20 20 20 20 20 20 20  bNullPK         
4270: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
4280: 3a 20 54 72 75 65 20 69 66 20 74 68 65 72 65 20  : True if there 
4290: 61 72 65 20 4e 55 4c 4c 20 76 61 6c 75 65 73 20  are NULL values 
42a0: 69 6e 20 50 4b 20 2a 2f 0a 29 7b 0a 20 20 75 6e  in PK */.){.  un
42b0: 73 69 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 30  signed int h = 0
42c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
42d0: 20 48 61 73 68 20 76 61 6c 75 65 20 74 6f 20 72   Hash value to r
42e0: 65 74 75 72 6e 20 2a 2f 0a 20 20 69 6e 74 20 69  eturn */.  int i
42f0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4300: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73             /* Us
4310: 65 64 20 74 6f 20 69 74 65 72 61 74 65 20 74 68  ed to iterate th
4320: 72 6f 75 67 68 20 63 6f 6c 75 6d 6e 73 20 2a 2f  rough columns */
4330: 0a 0a 20 20 61 73 73 65 72 74 28 20 2a 70 62 4e  ..  assert( *pbN
4340: 75 6c 6c 50 4b 3d 3d 30 20 29 3b 0a 20 20 61 73  ullPK==0 );.  as
4350: 73 65 72 74 28 20 70 54 61 62 2d 3e 6e 43 6f 6c  sert( pTab->nCol
4360: 3d 3d 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b  ==pSession->hook
4370: 2e 78 43 6f 75 6e 74 28 70 53 65 73 73 69 6f 6e  .xCount(pSession
4380: 2d 3e 68 6f 6f 6b 2e 70 43 74 78 29 20 29 3b 0a  ->hook.pCtx) );.
4390: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61    for(i=0; i<pTa
43a0: 62 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20  b->nCol; i++){. 
43b0: 20 20 20 69 66 28 20 70 54 61 62 2d 3e 61 62 50     if( pTab->abP
43c0: 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20 69 6e  K[i] ){.      in
43d0: 74 20 72 63 3b 0a 20 20 20 20 20 20 69 6e 74 20  t rc;.      int 
43e0: 65 54 79 70 65 3b 0a 20 20 20 20 20 20 73 71 6c  eType;.      sql
43f0: 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c  ite3_value *pVal
4400: 3b 0a 0a 20 20 20 20 20 20 69 66 28 20 62 4e 65  ;..      if( bNe
4410: 77 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  w ){.        rc 
4420: 3d 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b  = pSession->hook
4430: 2e 78 4e 65 77 28 70 53 65 73 73 69 6f 6e 2d 3e  .xNew(pSession->
4440: 68 6f 6f 6b 2e 70 43 74 78 2c 20 69 2c 20 26 70  hook.pCtx, i, &p
4450: 56 61 6c 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73  Val);.      }els
4460: 65 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  e{.        rc = 
4470: 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78  pSession->hook.x
4480: 4f 6c 64 28 70 53 65 73 73 69 6f 6e 2d 3e 68 6f  Old(pSession->ho
4490: 6f 6b 2e 70 43 74 78 2c 20 69 2c 20 26 70 56 61  ok.pCtx, i, &pVa
44a0: 6c 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  l);.      }.    
44b0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
44c0: 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
44d0: 0a 0a 20 20 20 20 20 20 65 54 79 70 65 20 3d 20  ..      eType = 
44e0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79  sqlite3_value_ty
44f0: 70 65 28 70 56 61 6c 29 3b 0a 20 20 20 20 20 20  pe(pVal);.      
4500: 68 20 3d 20 73 65 73 73 69 6f 6e 48 61 73 68 41  h = sessionHashA
4510: 70 70 65 6e 64 54 79 70 65 28 68 2c 20 65 54 79  ppendType(h, eTy
4520: 70 65 29 3b 0a 20 20 20 20 20 20 69 66 28 20 65  pe);.      if( e
4530: 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54  Type==SQLITE_INT
4540: 45 47 45 52 20 7c 7c 20 65 54 79 70 65 3d 3d 53  EGER || eType==S
4550: 51 4c 49 54 45 5f 46 4c 4f 41 54 20 29 7b 0a 20  QLITE_FLOAT ){. 
4560: 20 20 20 20 20 20 20 69 36 34 20 69 56 61 6c 3b         i64 iVal;
4570: 0a 20 20 20 20 20 20 20 20 69 66 28 20 65 54 79  .        if( eTy
4580: 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47  pe==SQLITE_INTEG
4590: 45 52 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  ER ){.          
45a0: 69 56 61 6c 20 3d 20 73 71 6c 69 74 65 33 5f 76  iVal = sqlite3_v
45b0: 61 6c 75 65 5f 69 6e 74 36 34 28 70 56 61 6c 29  alue_int64(pVal)
45c0: 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b  ;.        }else{
45d0: 0a 20 20 20 20 20 20 20 20 20 20 64 6f 75 62 6c  .          doubl
45e0: 65 20 72 56 61 6c 20 3d 20 73 71 6c 69 74 65 33  e rVal = sqlite3
45f0: 5f 76 61 6c 75 65 5f 64 6f 75 62 6c 65 28 70 56  _value_double(pV
4600: 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 20 20 61  al);.          a
4610: 73 73 65 72 74 28 20 73 69 7a 65 6f 66 28 69 56  ssert( sizeof(iV
4620: 61 6c 29 3d 3d 38 20 26 26 20 73 69 7a 65 6f 66  al)==8 && sizeof
4630: 28 72 56 61 6c 29 3d 3d 38 20 29 3b 0a 20 20 20  (rVal)==8 );.   
4640: 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 69         memcpy(&i
4650: 56 61 6c 2c 20 26 72 56 61 6c 2c 20 38 29 3b 0a  Val, &rVal, 8);.
4660: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
4670: 20 20 68 20 3d 20 73 65 73 73 69 6f 6e 48 61 73    h = sessionHas
4680: 68 41 70 70 65 6e 64 49 36 34 28 68 2c 20 69 56  hAppendI64(h, iV
4690: 61 6c 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  al);.      }else
46a0: 20 69 66 28 20 65 54 79 70 65 3d 3d 53 51 4c 49   if( eType==SQLI
46b0: 54 45 5f 54 45 58 54 20 7c 7c 20 65 54 79 70 65  TE_TEXT || eType
46c0: 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 20 29 7b  ==SQLITE_BLOB ){
46d0: 0a 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 75  .        const u
46e0: 38 20 2a 7a 3b 0a 20 20 20 20 20 20 20 20 69 6e  8 *z;.        in
46f0: 74 20 6e 3b 0a 20 20 20 20 20 20 20 20 69 66 28  t n;.        if(
4700: 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 54   eType==SQLITE_T
4710: 45 58 54 20 29 7b 0a 20 20 20 20 20 20 20 20 20  EXT ){.         
4720: 20 7a 20 3d 20 28 63 6f 6e 73 74 20 75 38 20 2a   z = (const u8 *
4730: 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74  )sqlite3_value_t
4740: 65 78 74 28 70 56 61 6c 29 3b 0a 20 20 20 20 20  ext(pVal);.     
4750: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
4760: 20 20 20 20 7a 20 3d 20 28 63 6f 6e 73 74 20 75      z = (const u
4770: 38 20 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  8 *)sqlite3_valu
4780: 65 5f 62 6c 6f 62 28 70 56 61 6c 29 3b 0a 20 20  e_blob(pVal);.  
4790: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
47a0: 6e 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  n = sqlite3_valu
47b0: 65 5f 62 79 74 65 73 28 70 56 61 6c 29 3b 0a 20  e_bytes(pVal);. 
47c0: 20 20 20 20 20 20 20 69 66 28 20 21 7a 20 26 26         if( !z &&
47d0: 20 28 65 54 79 70 65 21 3d 53 51 4c 49 54 45 5f   (eType!=SQLITE_
47e0: 42 4c 4f 42 20 7c 7c 20 6e 3e 30 29 20 29 20 72  BLOB || n>0) ) r
47f0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
4800: 45 4d 3b 0a 20 20 20 20 20 20 20 20 68 20 3d 20  EM;.        h = 
4810: 73 65 73 73 69 6f 6e 48 61 73 68 41 70 70 65 6e  sessionHashAppen
4820: 64 42 6c 6f 62 28 68 2c 20 6e 2c 20 7a 29 3b 0a  dBlob(h, n, z);.
4830: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
4840: 20 20 20 20 20 61 73 73 65 72 74 28 20 65 54 79       assert( eTy
4850: 70 65 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 20  pe==SQLITE_NULL 
4860: 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  );.        asser
4870: 74 28 20 70 54 61 62 2d 3e 62 53 74 61 74 31 3d  t( pTab->bStat1=
4880: 3d 30 20 7c 7c 20 69 21 3d 31 20 29 3b 0a 20 20  =0 || i!=1 );.  
4890: 20 20 20 20 20 20 2a 70 62 4e 75 6c 6c 50 4b 20        *pbNullPK 
48a0: 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  = 1;.      }.   
48b0: 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 69 48 61 73   }.  }..  *piHas
48c0: 68 20 3d 20 28 68 20 25 20 70 54 61 62 2d 3e 6e  h = (h % pTab->n
48d0: 43 68 61 6e 67 65 29 3b 0a 20 20 72 65 74 75 72  Change);.  retur
48e0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
48f0: 2f 2a 0a 2a 2a 20 54 68 65 20 62 75 66 66 65 72  /*.** The buffer
4900: 20 74 68 61 74 20 74 68 65 20 61 72 67 75 6d 65   that the argume
4910: 6e 74 20 70 6f 69 6e 74 73 20 74 6f 20 63 6f 6e  nt points to con
4920: 74 61 69 6e 73 20 61 20 73 65 72 69 61 6c 69 7a  tains a serializ
4930: 65 64 20 53 51 4c 20 76 61 6c 75 65 2e 0a 2a 2a  ed SQL value..**
4940: 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62   Return the numb
4950: 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 73  er of bytes of s
4960: 70 61 63 65 20 6f 63 63 75 70 69 65 64 20 62 79  pace occupied by
4970: 20 74 68 65 20 76 61 6c 75 65 20 28 69 6e 63 6c   the value (incl
4980: 75 64 69 6e 67 0a 2a 2a 20 74 68 65 20 74 79 70  uding.** the typ
4990: 65 20 62 79 74 65 29 2e 0a 2a 2f 0a 73 74 61 74  e byte)..*/.stat
49a0: 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 53 65  ic int sessionSe
49b0: 72 69 61 6c 4c 65 6e 28 75 38 20 2a 61 29 7b 0a  rialLen(u8 *a){.
49c0: 20 20 69 6e 74 20 65 20 3d 20 2a 61 3b 0a 20 20    int e = *a;.  
49d0: 69 6e 74 20 6e 3b 0a 20 20 69 66 28 20 65 3d 3d  int n;.  if( e==
49e0: 30 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20  0 ) return 1;.  
49f0: 69 66 28 20 65 3d 3d 53 51 4c 49 54 45 5f 4e 55  if( e==SQLITE_NU
4a00: 4c 4c 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20  LL ) return 1;. 
4a10: 20 69 66 28 20 65 3d 3d 53 51 4c 49 54 45 5f 49   if( e==SQLITE_I
4a20: 4e 54 45 47 45 52 20 7c 7c 20 65 3d 3d 53 51 4c  NTEGER || e==SQL
4a30: 49 54 45 5f 46 4c 4f 41 54 20 29 20 72 65 74 75  ITE_FLOAT ) retu
4a40: 72 6e 20 39 3b 0a 20 20 72 65 74 75 72 6e 20 73  rn 9;.  return s
4a50: 65 73 73 69 6f 6e 56 61 72 69 6e 74 47 65 74 28  essionVarintGet(
4a60: 26 61 5b 31 5d 2c 20 26 6e 29 20 2b 20 31 20 2b  &a[1], &n) + 1 +
4a70: 20 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 42 61 73   n;.}../*.** Bas
4a80: 65 64 20 6f 6e 20 74 68 65 20 70 72 69 6d 61 72  ed on the primar
4a90: 79 20 6b 65 79 20 76 61 6c 75 65 73 20 73 74 6f  y key values sto
4aa0: 72 65 64 20 69 6e 20 63 68 61 6e 67 65 20 61 52  red in change aR
4ab0: 65 63 6f 72 64 2c 20 63 61 6c 63 75 6c 61 74 65  ecord, calculate
4ac0: 20 61 0a 2a 2a 20 68 61 73 68 20 6b 65 79 2e 20   a.** hash key. 
4ad0: 41 73 73 75 6d 65 20 74 68 65 20 68 61 73 20 74  Assume the has t
4ae0: 61 62 6c 65 20 68 61 73 20 6e 42 75 63 6b 65 74  able has nBucket
4af0: 20 62 75 63 6b 65 74 73 2e 20 54 68 65 20 68 61   buckets. The ha
4b00: 73 68 20 6b 65 79 73 0a 2a 2a 20 63 61 6c 63 75  sh keys.** calcu
4b10: 6c 61 74 65 64 20 62 79 20 74 68 69 73 20 66 75  lated by this fu
4b20: 6e 63 74 69 6f 6e 20 61 72 65 20 63 6f 6d 70 61  nction are compa
4b30: 74 69 62 6c 65 20 77 69 74 68 20 74 68 6f 73 65  tible with those
4b40: 20 63 61 6c 63 75 6c 61 74 65 64 20 62 79 0a 2a   calculated by.*
4b50: 2a 20 73 65 73 73 69 6f 6e 50 72 65 75 70 64 61  * sessionPreupda
4b60: 74 65 48 61 73 68 28 29 2e 0a 2a 2a 0a 2a 2a 20  teHash()..**.** 
4b70: 54 68 65 20 62 50 6b 4f 6e 6c 79 20 61 72 67 75  The bPkOnly argu
4b80: 6d 65 6e 74 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f  ment is non-zero
4b90: 20 69 66 20 74 68 65 20 72 65 63 6f 72 64 20 61   if the record a
4ba0: 74 20 61 52 65 63 6f 72 64 5b 5d 20 69 73 20 66  t aRecord[] is f
4bb0: 72 6f 6d 0a 2a 2a 20 61 20 70 61 74 63 68 73 65  rom.** a patchse
4bc0: 74 20 44 45 4c 45 54 45 2e 20 49 6e 20 74 68 69  t DELETE. In thi
4bd0: 73 20 63 61 73 65 20 74 68 65 20 6e 6f 6e 2d 50  s case the non-P
4be0: 4b 20 66 69 65 6c 64 73 20 61 72 65 20 6f 6d 69  K fields are omi
4bf0: 74 74 65 64 20 65 6e 74 69 72 65 6c 79 2e 0a 2a  tted entirely..*
4c00: 2f 0a 73 74 61 74 69 63 20 75 6e 73 69 67 6e 65  /.static unsigne
4c10: 64 20 69 6e 74 20 73 65 73 73 69 6f 6e 43 68 61  d int sessionCha
4c20: 6e 67 65 48 61 73 68 28 0a 20 20 53 65 73 73 69  ngeHash(.  Sessi
4c30: 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 20  onTable *pTab,  
4c40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61             /* Ta
4c50: 62 6c 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20  ble handle */.  
4c60: 69 6e 74 20 62 50 6b 4f 6e 6c 79 2c 20 20 20 20  int bPkOnly,    
4c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4c80: 2f 2a 20 52 65 63 6f 72 64 20 63 6f 6e 73 69 73  /* Record consis
4c90: 74 73 20 6f 66 20 50 4b 20 66 69 65 6c 64 73 20  ts of PK fields 
4ca0: 6f 6e 6c 79 20 2a 2f 0a 20 20 75 38 20 2a 61 52  only */.  u8 *aR
4cb0: 65 63 6f 72 64 2c 20 20 20 20 20 20 20 20 20 20  ecord,          
4cc0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 61            /* Cha
4cd0: 6e 67 65 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20  nge record */.  
4ce0: 69 6e 74 20 6e 42 75 63 6b 65 74 20 20 20 20 20  int nBucket     
4cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4d00: 2f 2a 20 41 73 73 75 6d 65 20 74 68 69 73 20 6d  /* Assume this m
4d10: 61 6e 79 20 62 75 63 6b 65 74 73 20 69 6e 20 68  any buckets in h
4d20: 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 29 7b 0a  ash table */.){.
4d30: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68    unsigned int h
4d40: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
4d50: 20 20 2f 2a 20 56 61 6c 75 65 20 74 6f 20 72 65    /* Value to re
4d60: 74 75 72 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 3b  turn */.  int i;
4d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4d80: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65            /* Use
4d90: 64 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72  d to iterate thr
4da0: 6f 75 67 68 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a  ough columns */.
4db0: 20 20 75 38 20 2a 61 20 3d 20 61 52 65 63 6f 72    u8 *a = aRecor
4dc0: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
4dd0: 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65    /* Used to ite
4de0: 72 61 74 65 20 74 68 72 6f 75 67 68 20 63 68 61  rate through cha
4df0: 6e 67 65 20 72 65 63 6f 72 64 20 2a 2f 0a 0a 20  nge record */.. 
4e00: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61 62   for(i=0; i<pTab
4e10: 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20  ->nCol; i++){.  
4e20: 20 20 69 6e 74 20 65 54 79 70 65 20 3d 20 2a 61    int eType = *a
4e30: 3b 0a 20 20 20 20 69 6e 74 20 69 73 50 4b 20 3d  ;.    int isPK =
4e40: 20 70 54 61 62 2d 3e 61 62 50 4b 5b 69 5d 3b 0a   pTab->abPK[i];.
4e50: 20 20 20 20 69 66 28 20 62 50 6b 4f 6e 6c 79 20      if( bPkOnly 
4e60: 26 26 20 69 73 50 4b 3d 3d 30 20 29 20 63 6f 6e  && isPK==0 ) con
4e70: 74 69 6e 75 65 3b 0a 0a 20 20 20 20 2f 2a 20 49  tinue;..    /* I
4e80: 74 20 69 73 20 6e 6f 74 20 70 6f 73 73 69 62 6c  t is not possibl
4e90: 65 20 66 6f 72 20 65 54 79 70 65 20 74 6f 20 62  e for eType to b
4ea0: 65 20 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 68 65  e SQLITE_NULL he
4eb0: 72 65 2e 20 54 68 65 20 73 65 73 73 69 6f 6e 20  re. The session 
4ec0: 0a 20 20 20 20 2a 2a 20 6d 6f 64 75 6c 65 20 64  .    ** module d
4ed0: 6f 65 73 20 6e 6f 74 20 72 65 63 6f 72 64 20 63  oes not record c
4ee0: 68 61 6e 67 65 73 20 66 6f 72 20 72 6f 77 73 20  hanges for rows 
4ef0: 77 69 74 68 20 4e 55 4c 4c 20 76 61 6c 75 65 73  with NULL values
4f00: 20 73 74 6f 72 65 64 20 69 6e 0a 20 20 20 20 2a   stored in.    *
4f10: 2a 20 70 72 69 6d 61 72 79 20 6b 65 79 20 63 6f  * primary key co
4f20: 6c 75 6d 6e 73 2e 20 2a 2f 0a 20 20 20 20 61 73  lumns. */.    as
4f30: 73 65 72 74 28 20 65 54 79 70 65 3d 3d 53 51 4c  sert( eType==SQL
4f40: 49 54 45 5f 49 4e 54 45 47 45 52 20 7c 7c 20 65  ITE_INTEGER || e
4f50: 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 46 4c 4f  Type==SQLITE_FLO
4f60: 41 54 20 0a 20 20 20 20 20 20 20 20 20 7c 7c 20  AT .         || 
4f70: 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 54 45  eType==SQLITE_TE
4f80: 58 54 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c  XT || eType==SQL
4f90: 49 54 45 5f 42 4c 4f 42 20 0a 20 20 20 20 20 20  ITE_BLOB .      
4fa0: 20 20 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c     || eType==SQL
4fb0: 49 54 45 5f 4e 55 4c 4c 20 7c 7c 20 65 54 79 70  ITE_NULL || eTyp
4fc0: 65 3d 3d 30 20 0a 20 20 20 20 29 3b 0a 20 20 20  e==0 .    );.   
4fd0: 20 61 73 73 65 72 74 28 20 21 69 73 50 4b 20 7c   assert( !isPK |
4fe0: 7c 20 28 65 54 79 70 65 21 3d 30 20 26 26 20 65  | (eType!=0 && e
4ff0: 54 79 70 65 21 3d 53 51 4c 49 54 45 5f 4e 55 4c  Type!=SQLITE_NUL
5000: 4c 29 20 29 3b 0a 0a 20 20 20 20 69 66 28 20 69  L) );..    if( i
5010: 73 50 4b 20 29 7b 0a 20 20 20 20 20 20 61 2b 2b  sPK ){.      a++
5020: 3b 0a 20 20 20 20 20 20 68 20 3d 20 73 65 73 73  ;.      h = sess
5030: 69 6f 6e 48 61 73 68 41 70 70 65 6e 64 54 79 70  ionHashAppendTyp
5040: 65 28 68 2c 20 65 54 79 70 65 29 3b 0a 20 20 20  e(h, eType);.   
5050: 20 20 20 69 66 28 20 65 54 79 70 65 3d 3d 53 51     if( eType==SQ
5060: 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 7c 7c 20  LITE_INTEGER || 
5070: 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 46 4c  eType==SQLITE_FL
5080: 4f 41 54 20 29 7b 0a 20 20 20 20 20 20 20 20 68  OAT ){.        h
5090: 20 3d 20 73 65 73 73 69 6f 6e 48 61 73 68 41 70   = sessionHashAp
50a0: 70 65 6e 64 49 36 34 28 68 2c 20 73 65 73 73 69  pendI64(h, sessi
50b0: 6f 6e 47 65 74 49 36 34 28 61 29 29 3b 0a 20 20  onGetI64(a));.  
50c0: 20 20 20 20 20 20 61 20 2b 3d 20 38 3b 0a 20 20        a += 8;.  
50d0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
50e0: 20 20 20 69 6e 74 20 6e 3b 20 0a 20 20 20 20 20     int n; .     
50f0: 20 20 20 61 20 2b 3d 20 73 65 73 73 69 6f 6e 56     a += sessionV
5100: 61 72 69 6e 74 47 65 74 28 61 2c 20 26 6e 29 3b  arintGet(a, &n);
5110: 0a 20 20 20 20 20 20 20 20 68 20 3d 20 73 65 73  .        h = ses
5120: 73 69 6f 6e 48 61 73 68 41 70 70 65 6e 64 42 6c  sionHashAppendBl
5130: 6f 62 28 68 2c 20 6e 2c 20 61 29 3b 0a 20 20 20  ob(h, n, a);.   
5140: 20 20 20 20 20 61 20 2b 3d 20 6e 3b 0a 20 20 20       a += n;.   
5150: 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 7b 0a     }.    }else{.
5160: 20 20 20 20 20 20 61 20 2b 3d 20 73 65 73 73 69        a += sessi
5170: 6f 6e 53 65 72 69 61 6c 4c 65 6e 28 61 29 3b 0a  onSerialLen(a);.
5180: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
5190: 72 6e 20 28 68 20 25 20 6e 42 75 63 6b 65 74 29  rn (h % nBucket)
51a0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 72 67 75 6d  ;.}../*.** Argum
51b0: 65 6e 74 73 20 61 4c 65 66 74 20 61 6e 64 20 61  ents aLeft and a
51c0: 52 69 67 68 74 20 61 72 65 20 70 6f 69 6e 74 65  Right are pointe
51d0: 72 73 20 74 6f 20 63 68 61 6e 67 65 20 72 65 63  rs to change rec
51e0: 6f 72 64 73 20 66 6f 72 20 74 61 62 6c 65 20 70  ords for table p
51f0: 54 61 62 2e 0a 2a 2a 20 54 68 69 73 20 66 75 6e  Tab..** This fun
5200: 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 74 72  ction returns tr
5210: 75 65 20 69 66 20 74 68 65 20 74 77 6f 20 72 65  ue if the two re
5220: 63 6f 72 64 73 20 61 70 70 6c 79 20 74 6f 20 74  cords apply to t
5230: 68 65 20 73 61 6d 65 20 72 6f 77 20 28 69 2e 65  he same row (i.e
5240: 2e 0a 2a 2a 20 68 61 76 65 20 74 68 65 20 73 61  ..** have the sa
5250: 6d 65 20 76 61 6c 75 65 73 20 73 74 6f 72 65 64  me values stored
5260: 20 69 6e 20 74 68 65 20 70 72 69 6d 61 72 79 20   in the primary 
5270: 6b 65 79 20 63 6f 6c 75 6d 6e 73 29 2c 20 6f 72  key columns), or
5280: 20 66 61 6c 73 65 20 0a 2a 2a 20 6f 74 68 65 72   false .** other
5290: 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  wise..*/.static 
52a0: 69 6e 74 20 73 65 73 73 69 6f 6e 43 68 61 6e 67  int sessionChang
52b0: 65 45 71 75 61 6c 28 0a 20 20 53 65 73 73 69 6f  eEqual(.  Sessio
52c0: 6e 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 20 20  nTable *pTab,   
52d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62            /* Tab
52e0: 6c 65 20 75 73 65 64 20 66 6f 72 20 50 4b 20 64  le used for PK d
52f0: 65 66 69 6e 69 74 69 6f 6e 20 2a 2f 0a 20 20 69  efinition */.  i
5300: 6e 74 20 62 4c 65 66 74 50 6b 4f 6e 6c 79 2c 20  nt bLeftPkOnly, 
5310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5320: 2a 20 54 72 75 65 20 69 66 20 61 4c 65 66 74 5b  * True if aLeft[
5330: 5d 20 63 6f 6e 74 61 69 6e 73 20 50 4b 20 66 69  ] contains PK fi
5340: 65 6c 64 73 20 6f 6e 6c 79 20 2a 2f 0a 20 20 75  elds only */.  u
5350: 38 20 2a 61 4c 65 66 74 2c 20 20 20 20 20 20 20  8 *aLeft,       
5360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5370: 2a 20 43 68 61 6e 67 65 20 72 65 63 6f 72 64 20  * Change record 
5380: 2a 2f 0a 20 20 69 6e 74 20 62 52 69 67 68 74 50  */.  int bRightP
5390: 6b 4f 6e 6c 79 2c 20 20 20 20 20 20 20 20 20 20  kOnly,          
53a0: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
53b0: 61 52 69 67 68 74 5b 5d 20 63 6f 6e 74 61 69 6e  aRight[] contain
53c0: 73 20 50 4b 20 66 69 65 6c 64 73 20 6f 6e 6c 79  s PK fields only
53d0: 20 2a 2f 0a 20 20 75 38 20 2a 61 52 69 67 68 74   */.  u8 *aRight
53e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
53f0: 20 20 20 20 20 20 2f 2a 20 43 68 61 6e 67 65 20        /* Change 
5400: 72 65 63 6f 72 64 20 2a 2f 0a 29 7b 0a 20 20 75  record */.){.  u
5410: 38 20 2a 61 31 20 3d 20 61 4c 65 66 74 3b 20 20  8 *a1 = aLeft;  
5420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5430: 2a 20 43 75 72 73 6f 72 20 74 6f 20 69 74 65 72  * Cursor to iter
5440: 61 74 65 20 74 68 72 6f 75 67 68 20 61 4c 65 66  ate through aLef
5450: 74 20 2a 2f 0a 20 20 75 38 20 2a 61 32 20 3d 20  t */.  u8 *a2 = 
5460: 61 52 69 67 68 74 3b 20 20 20 20 20 20 20 20 20  aRight;         
5470: 20 20 20 20 20 20 20 2f 2a 20 43 75 72 73 6f 72         /* Cursor
5480: 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f   to iterate thro
5490: 75 67 68 20 61 52 69 67 68 74 20 2a 2f 0a 20 20  ugh aRight */.  
54a0: 69 6e 74 20 69 43 6f 6c 3b 20 20 20 20 20 20 20  int iCol;       
54b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
54c0: 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72 61  /* Used to itera
54d0: 74 65 20 74 68 72 6f 75 67 68 20 74 61 62 6c 65  te through table
54e0: 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 0a 20 20 66   columns */..  f
54f0: 6f 72 28 69 43 6f 6c 3d 30 3b 20 69 43 6f 6c 3c  or(iCol=0; iCol<
5500: 70 54 61 62 2d 3e 6e 43 6f 6c 3b 20 69 43 6f 6c  pTab->nCol; iCol
5510: 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 70 54 61  ++){.    if( pTa
5520: 62 2d 3e 61 62 50 4b 5b 69 43 6f 6c 5d 20 29 7b  b->abPK[iCol] ){
5530: 0a 20 20 20 20 20 20 69 6e 74 20 6e 31 20 3d 20  .      int n1 = 
5540: 73 65 73 73 69 6f 6e 53 65 72 69 61 6c 4c 65 6e  sessionSerialLen
5550: 28 61 31 29 3b 0a 20 20 20 20 20 20 69 6e 74 20  (a1);.      int 
5560: 6e 32 20 3d 20 73 65 73 73 69 6f 6e 53 65 72 69  n2 = sessionSeri
5570: 61 6c 4c 65 6e 28 61 32 29 3b 0a 0a 20 20 20 20  alLen(a2);..    
5580: 20 20 69 66 28 20 70 54 61 62 2d 3e 61 62 50 4b    if( pTab->abPK
5590: 5b 69 43 6f 6c 5d 20 26 26 20 28 6e 31 21 3d 6e  [iCol] && (n1!=n
55a0: 32 20 7c 7c 20 6d 65 6d 63 6d 70 28 61 31 2c 20  2 || memcmp(a1, 
55b0: 61 32 2c 20 6e 31 29 29 20 29 7b 0a 20 20 20 20  a2, n1)) ){.    
55c0: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20      return 0;.  
55d0: 20 20 20 20 7d 0a 20 20 20 20 20 20 61 31 20 2b      }.      a1 +
55e0: 3d 20 6e 31 3b 0a 20 20 20 20 20 20 61 32 20 2b  = n1;.      a2 +
55f0: 3d 20 6e 32 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  = n2;.    }else{
5600: 0a 20 20 20 20 20 20 69 66 28 20 62 4c 65 66 74  .      if( bLeft
5610: 50 6b 4f 6e 6c 79 3d 3d 30 20 29 20 61 31 20 2b  PkOnly==0 ) a1 +
5620: 3d 20 73 65 73 73 69 6f 6e 53 65 72 69 61 6c 4c  = sessionSerialL
5630: 65 6e 28 61 31 29 3b 0a 20 20 20 20 20 20 69 66  en(a1);.      if
5640: 28 20 62 52 69 67 68 74 50 6b 4f 6e 6c 79 3d 3d  ( bRightPkOnly==
5650: 30 20 29 20 61 32 20 2b 3d 20 73 65 73 73 69 6f  0 ) a2 += sessio
5660: 6e 53 65 72 69 61 6c 4c 65 6e 28 61 32 29 3b 0a  nSerialLen(a2);.
5670: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
5680: 75 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn 1;.}../*.** 
5690: 41 72 67 75 6d 65 6e 74 73 20 61 4c 65 66 74 20  Arguments aLeft 
56a0: 61 6e 64 20 61 52 69 67 68 74 20 62 6f 74 68 20  and aRight both 
56b0: 70 6f 69 6e 74 20 74 6f 20 62 75 66 66 65 72 73  point to buffers
56c0: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 63 68 61 6e   containing chan
56d0: 67 65 0a 2a 2a 20 72 65 63 6f 72 64 73 20 77 69  ge.** records wi
56e0: 74 68 20 6e 43 6f 6c 20 63 6f 6c 75 6d 6e 73 2e  th nCol columns.
56f0: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 22   This function "
5700: 6d 65 72 67 65 73 22 20 74 68 65 20 74 77 6f 20  merges" the two 
5710: 72 65 63 6f 72 64 73 20 69 6e 74 6f 0a 2a 2a 20  records into.** 
5720: 61 20 73 69 6e 67 6c 65 20 72 65 63 6f 72 64 73  a single records
5730: 20 77 68 69 63 68 20 69 73 20 77 72 69 74 74 65   which is writte
5740: 6e 20 74 6f 20 74 68 65 20 62 75 66 66 65 72 20  n to the buffer 
5750: 61 74 20 2a 70 61 4f 75 74 2e 20 2a 70 61 4f 75  at *paOut. *paOu
5760: 74 20 69 73 0a 2a 2a 20 74 68 65 6e 20 73 65 74  t is.** then set
5770: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 6f 6e 65   to point to one
5780: 20 62 79 74 65 20 61 66 74 65 72 20 74 68 65 20   byte after the 
5790: 6c 61 73 74 20 62 79 74 65 20 77 72 69 74 74 65  last byte writte
57a0: 6e 20 62 65 66 6f 72 65 20 0a 2a 2a 20 72 65 74  n before .** ret
57b0: 75 72 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 54 68  urning..**.** Th
57c0: 65 20 6d 65 72 67 69 6e 67 20 6f 66 20 72 65 63  e merging of rec
57d0: 6f 72 64 73 20 69 73 20 64 6f 6e 65 20 61 73 20  ords is done as 
57e0: 66 6f 6c 6c 6f 77 73 3a 20 46 6f 72 20 65 61 63  follows: For eac
57f0: 68 20 63 6f 6c 75 6d 6e 2c 20 69 66 20 74 68 65  h column, if the
5800: 20 0a 2a 2a 20 61 52 69 67 68 74 20 72 65 63 6f   .** aRight reco
5810: 72 64 20 63 6f 6e 74 61 69 6e 73 20 61 20 76 61  rd contains a va
5820: 6c 75 65 20 66 6f 72 20 74 68 65 20 63 6f 6c 75  lue for the colu
5830: 6d 6e 2c 20 63 6f 70 79 20 74 68 65 20 76 61 6c  mn, copy the val
5840: 75 65 20 66 72 6f 6d 0a 2a 2a 20 74 68 65 69 72  ue from.** their
5850: 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20  . Otherwise, if 
5860: 61 4c 65 66 74 20 63 6f 6e 74 61 69 6e 73 20 61  aLeft contains a
5870: 20 76 61 6c 75 65 2c 20 63 6f 70 79 20 69 74 2e   value, copy it.
5880: 20 49 66 20 6e 65 69 74 68 65 72 0a 2a 2a 20 72   If neither.** r
5890: 65 63 6f 72 64 20 63 6f 6e 74 61 69 6e 73 20 61  ecord contains a
58a0: 20 76 61 6c 75 65 20 66 6f 72 20 61 20 67 69 76   value for a giv
58b0: 65 6e 20 63 6f 6c 75 6d 6e 2c 20 74 68 65 6e 20  en column, then 
58c0: 6e 65 69 74 68 65 72 20 64 6f 65 73 20 74 68 65  neither does the
58d0: 0a 2a 2a 20 6f 75 74 70 75 74 20 72 65 63 6f 72  .** output recor
58e0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
58f0: 64 20 73 65 73 73 69 6f 6e 4d 65 72 67 65 52 65  d sessionMergeRe
5900: 63 6f 72 64 28 0a 20 20 75 38 20 2a 2a 70 61 4f  cord(.  u8 **paO
5910: 75 74 2c 20 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c  ut, .  int nCol,
5920: 0a 20 20 75 38 20 2a 61 4c 65 66 74 2c 0a 20 20  .  u8 *aLeft,.  
5930: 75 38 20 2a 61 52 69 67 68 74 0a 29 7b 0a 20 20  u8 *aRight.){.  
5940: 75 38 20 2a 61 31 20 3d 20 61 4c 65 66 74 3b 20  u8 *a1 = aLeft; 
5950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5960: 2f 2a 20 43 75 72 73 6f 72 20 75 73 65 64 20 74  /* Cursor used t
5970: 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67  o iterate throug
5980: 68 20 61 4c 65 66 74 20 2a 2f 0a 20 20 75 38 20  h aLeft */.  u8 
5990: 2a 61 32 20 3d 20 61 52 69 67 68 74 3b 20 20 20  *a2 = aRight;   
59a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
59b0: 43 75 72 73 6f 72 20 75 73 65 64 20 74 6f 20 69  Cursor used to i
59c0: 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 61  terate through a
59d0: 52 69 67 68 74 20 2a 2f 0a 20 20 75 38 20 2a 61  Right */.  u8 *a
59e0: 4f 75 74 20 3d 20 2a 70 61 4f 75 74 3b 20 20 20  Out = *paOut;   
59f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 75             /* Ou
5a00: 74 70 75 74 20 63 75 72 73 6f 72 20 2a 2f 0a 20  tput cursor */. 
5a10: 20 69 6e 74 20 69 43 6f 6c 3b 20 20 20 20 20 20   int iCol;      
5a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a30: 20 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72   /* Used to iter
5a40: 61 74 65 20 66 72 6f 6d 20 30 20 74 6f 20 6e 43  ate from 0 to nC
5a50: 6f 6c 20 2a 2f 0a 0a 20 20 66 6f 72 28 69 43 6f  ol */..  for(iCo
5a60: 6c 3d 30 3b 20 69 43 6f 6c 3c 6e 43 6f 6c 3b 20  l=0; iCol<nCol; 
5a70: 69 43 6f 6c 2b 2b 29 7b 0a 20 20 20 20 69 6e 74  iCol++){.    int
5a80: 20 6e 31 20 3d 20 73 65 73 73 69 6f 6e 53 65 72   n1 = sessionSer
5a90: 69 61 6c 4c 65 6e 28 61 31 29 3b 0a 20 20 20 20  ialLen(a1);.    
5aa0: 69 6e 74 20 6e 32 20 3d 20 73 65 73 73 69 6f 6e  int n2 = session
5ab0: 53 65 72 69 61 6c 4c 65 6e 28 61 32 29 3b 0a 20  SerialLen(a2);. 
5ac0: 20 20 20 69 66 28 20 2a 61 32 20 29 7b 0a 20 20     if( *a2 ){.  
5ad0: 20 20 20 20 6d 65 6d 63 70 79 28 61 4f 75 74 2c      memcpy(aOut,
5ae0: 20 61 32 2c 20 6e 32 29 3b 0a 20 20 20 20 20 20   a2, n2);.      
5af0: 61 4f 75 74 20 2b 3d 20 6e 32 3b 0a 20 20 20 20  aOut += n2;.    
5b00: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6d 65 6d  }else{.      mem
5b10: 63 70 79 28 61 4f 75 74 2c 20 61 31 2c 20 6e 31  cpy(aOut, a1, n1
5b20: 29 3b 0a 20 20 20 20 20 20 61 4f 75 74 20 2b 3d  );.      aOut +=
5b30: 20 6e 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61   n1;.    }.    a
5b40: 31 20 2b 3d 20 6e 31 3b 0a 20 20 20 20 61 32 20  1 += n1;.    a2 
5b50: 2b 3d 20 6e 32 3b 0a 20 20 7d 0a 0a 20 20 2a 70  += n2;.  }..  *p
5b60: 61 4f 75 74 20 3d 20 61 4f 75 74 3b 0a 7d 0a 0a  aOut = aOut;.}..
5b70: 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 61 20  /*.** This is a 
5b80: 68 65 6c 70 65 72 20 66 75 6e 63 74 69 6f 6e 20  helper function 
5b90: 75 73 65 64 20 62 79 20 73 65 73 73 69 6f 6e 4d  used by sessionM
5ba0: 65 72 67 65 55 70 64 61 74 65 28 29 2e 0a 2a 2a  ergeUpdate()..**
5bb0: 0a 2a 2a 20 57 68 65 6e 20 74 68 69 73 20 66 75  .** When this fu
5bc0: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
5bd0: 2c 20 62 6f 74 68 20 2a 70 61 4f 6e 65 20 61 6e  , both *paOne an
5be0: 64 20 2a 70 61 54 77 6f 20 70 6f 69 6e 74 20 74  d *paTwo point t
5bf0: 6f 20 61 20 76 61 6c 75 65 20 0a 2a 2a 20 77 69  o a value .** wi
5c00: 74 68 69 6e 20 61 20 63 68 61 6e 67 65 20 72 65  thin a change re
5c10: 63 6f 72 64 2e 20 42 65 66 6f 72 65 20 69 74 20  cord. Before it 
5c20: 72 65 74 75 72 6e 73 2c 20 62 6f 74 68 20 68 61  returns, both ha
5c30: 76 65 20 62 65 65 6e 20 61 64 76 61 6e 63 65 64  ve been advanced
5c40: 20 73 6f 20 0a 2a 2a 20 61 73 20 74 6f 20 70 6f   so .** as to po
5c50: 69 6e 74 20 74 6f 20 74 68 65 20 6e 65 78 74 20  int to the next 
5c60: 76 61 6c 75 65 20 69 6e 20 74 68 65 20 72 65 63  value in the rec
5c70: 6f 72 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 2c 20 77  ord..**.** If, w
5c80: 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f  hen this functio
5c90: 6e 20 69 73 20 63 61 6c 6c 65 64 2c 20 2a 70 61  n is called, *pa
5ca0: 54 77 6f 20 70 6f 69 6e 74 73 20 74 6f 20 61 20  Two points to a 
5cb0: 76 61 6c 69 64 20 76 61 6c 75 65 20 28 69 2e 65  valid value (i.e
5cc0: 2e 0a 2a 2a 20 2a 70 61 54 77 6f 5b 30 5d 20 69  ..** *paTwo[0] i
5cd0: 73 20 6e 6f 74 20 30 78 30 30 20 2d 20 74 68 65  s not 0x00 - the
5ce0: 20 22 6e 6f 20 76 61 6c 75 65 22 20 70 6c 61 63   "no value" plac
5cf0: 65 68 6f 6c 64 65 72 29 2c 20 61 20 63 6f 70 79  eholder), a copy
5d00: 20 6f 66 20 74 68 65 20 2a 70 61 54 77 6f 0a 2a   of the *paTwo.*
5d10: 2a 20 70 6f 69 6e 74 65 72 20 69 73 20 72 65 74  * pointer is ret
5d20: 75 72 6e 65 64 20 61 6e 64 20 2a 70 6e 56 61 6c  urned and *pnVal
5d30: 20 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e   is set to the n
5d40: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69  umber of bytes i
5d50: 6e 20 74 68 65 20 0a 2a 2a 20 73 65 72 69 61 6c  n the .** serial
5d60: 69 7a 65 64 20 76 61 6c 75 65 2e 20 4f 74 68 65  ized value. Othe
5d70: 72 77 69 73 65 2c 20 61 20 63 6f 70 79 20 6f 66  rwise, a copy of
5d80: 20 2a 70 61 4f 6e 65 20 69 73 20 72 65 74 75 72   *paOne is retur
5d90: 6e 65 64 20 61 6e 64 20 2a 70 6e 56 61 6c 0a 2a  ned and *pnVal.*
5da0: 2a 20 73 65 74 20 74 6f 20 74 68 65 20 6e 75 6d  * set to the num
5db0: 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
5dc0: 74 68 65 20 76 61 6c 75 65 20 61 74 20 2a 70 61  the value at *pa
5dd0: 4f 6e 65 2e 20 49 66 20 2a 70 61 4f 6e 65 20 70  One. If *paOne p
5de0: 6f 69 6e 74 73 0a 2a 2a 20 74 6f 20 74 68 65 20  oints.** to the 
5df0: 22 6e 6f 20 76 61 6c 75 65 22 20 70 6c 61 63 65  "no value" place
5e00: 68 6f 6c 64 65 72 2c 20 2a 70 6e 56 61 6c 20 69  holder, *pnVal i
5e10: 73 20 73 65 74 20 74 6f 20 31 2e 20 49 6e 20 6f  s set to 1. In o
5e20: 74 68 65 72 20 77 6f 72 64 73 3a 0a 2a 2a 0a 2a  ther words:.**.*
5e30: 2a 20 20 20 69 66 28 20 2a 70 61 54 77 6f 20 69  *   if( *paTwo i
5e40: 73 20 76 61 6c 69 64 20 29 20 72 65 74 75 72 6e  s valid ) return
5e50: 20 2a 70 61 54 77 6f 3b 0a 2a 2a 20 20 20 72 65   *paTwo;.**   re
5e60: 74 75 72 6e 20 2a 70 61 4f 6e 65 3b 0a 2a 2a 0a  turn *paOne;.**.
5e70: 2a 2f 0a 73 74 61 74 69 63 20 75 38 20 2a 73 65  */.static u8 *se
5e80: 73 73 69 6f 6e 4d 65 72 67 65 56 61 6c 75 65 28  ssionMergeValue(
5e90: 0a 20 20 75 38 20 2a 2a 70 61 4f 6e 65 2c 20 20  .  u8 **paOne,  
5ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5eb0: 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 4c 65     /* IN/OUT: Le
5ec0: 66 74 2d 68 61 6e 64 20 62 75 66 66 65 72 20 70  ft-hand buffer p
5ed0: 6f 69 6e 74 65 72 20 2a 2f 0a 20 20 75 38 20 2a  ointer */.  u8 *
5ee0: 2a 70 61 54 77 6f 2c 20 20 20 20 20 20 20 20 20  *paTwo,         
5ef0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
5f00: 4e 2f 4f 55 54 3a 20 52 69 67 68 74 2d 68 61 6e  N/OUT: Right-han
5f10: 64 20 62 75 66 66 65 72 20 70 6f 69 6e 74 65 72  d buffer pointer
5f20: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 56 61 6c   */.  int *pnVal
5f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5f40: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 42 79        /* OUT: By
5f50: 74 65 73 20 69 6e 20 72 65 74 75 72 6e 65 64 20  tes in returned 
5f60: 76 61 6c 75 65 20 2a 2f 0a 29 7b 0a 20 20 75 38  value */.){.  u8
5f70: 20 2a 61 31 20 3d 20 2a 70 61 4f 6e 65 3b 0a 20   *a1 = *paOne;. 
5f80: 20 75 38 20 2a 61 32 20 3d 20 2a 70 61 54 77 6f   u8 *a2 = *paTwo
5f90: 3b 0a 20 20 75 38 20 2a 70 52 65 74 20 3d 20 30  ;.  u8 *pRet = 0
5fa0: 3b 0a 20 20 69 6e 74 20 6e 31 3b 0a 0a 20 20 61  ;.  int n1;..  a
5fb0: 73 73 65 72 74 28 20 61 31 20 29 3b 0a 20 20 69  ssert( a1 );.  i
5fc0: 66 28 20 61 32 20 29 7b 0a 20 20 20 20 69 6e 74  f( a2 ){.    int
5fd0: 20 6e 32 20 3d 20 73 65 73 73 69 6f 6e 53 65 72   n2 = sessionSer
5fe0: 69 61 6c 4c 65 6e 28 61 32 29 3b 0a 20 20 20 20  ialLen(a2);.    
5ff0: 69 66 28 20 2a 61 32 20 29 7b 0a 20 20 20 20 20  if( *a2 ){.     
6000: 20 2a 70 6e 56 61 6c 20 3d 20 6e 32 3b 0a 20 20   *pnVal = n2;.  
6010: 20 20 20 20 70 52 65 74 20 3d 20 61 32 3b 0a 20      pRet = a2;. 
6020: 20 20 20 7d 0a 20 20 20 20 2a 70 61 54 77 6f 20     }.    *paTwo 
6030: 3d 20 26 61 32 5b 6e 32 5d 3b 0a 20 20 7d 0a 0a  = &a2[n2];.  }..
6040: 20 20 6e 31 20 3d 20 73 65 73 73 69 6f 6e 53 65    n1 = sessionSe
6050: 72 69 61 6c 4c 65 6e 28 61 31 29 3b 0a 20 20 69  rialLen(a1);.  i
6060: 66 28 20 70 52 65 74 3d 3d 30 20 29 7b 0a 20 20  f( pRet==0 ){.  
6070: 20 20 2a 70 6e 56 61 6c 20 3d 20 6e 31 3b 0a 20    *pnVal = n1;. 
6080: 20 20 20 70 52 65 74 20 3d 20 61 31 3b 0a 20 20     pRet = a1;.  
6090: 7d 0a 20 20 2a 70 61 4f 6e 65 20 3d 20 26 61 31  }.  *paOne = &a1
60a0: 5b 6e 31 5d 3b 0a 0a 20 20 72 65 74 75 72 6e 20  [n1];..  return 
60b0: 70 52 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  pRet;.}../*.** T
60c0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
60d0: 75 73 65 64 20 62 79 20 63 68 61 6e 67 65 73 65  used by changese
60e0: 74 5f 63 6f 6e 63 61 74 28 29 20 74 6f 20 6d 65  t_concat() to me
60f0: 72 67 65 20 74 77 6f 20 55 50 44 41 54 45 20 63  rge two UPDATE c
6100: 68 61 6e 67 65 73 0a 2a 2a 20 6f 6e 20 74 68 65  hanges.** on the
6110: 20 73 61 6d 65 20 72 6f 77 2e 0a 2a 2f 0a 73 74   same row..*/.st
6120: 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e  atic int session
6130: 4d 65 72 67 65 55 70 64 61 74 65 28 0a 20 20 75  MergeUpdate(.  u
6140: 38 20 2a 2a 70 61 4f 75 74 2c 20 20 20 20 20 20  8 **paOut,      
6150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6160: 2a 20 49 4e 2f 4f 55 54 3a 20 50 6f 69 6e 74 65  * IN/OUT: Pointe
6170: 72 20 74 6f 20 6f 75 74 70 75 74 20 62 75 66 66  r to output buff
6180: 65 72 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 54  er */.  SessionT
6190: 61 62 6c 65 20 2a 70 54 61 62 2c 20 20 20 20 20  able *pTab,     
61a0: 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62 6c 65          /* Table
61b0: 20 63 68 61 6e 67 65 20 70 65 72 74 61 69 6e 73   change pertains
61c0: 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 62 50 61   to */.  int bPa
61d0: 74 63 68 73 65 74 2c 20 20 20 20 20 20 20 20 20  tchset,         
61e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
61f0: 20 69 66 20 72 65 63 6f 72 64 73 20 61 72 65 20   if records are 
6200: 70 61 74 63 68 73 65 74 20 72 65 63 6f 72 64 73  patchset records
6210: 20 2a 2f 0a 20 20 75 38 20 2a 61 4f 6c 64 52 65   */.  u8 *aOldRe
6220: 63 6f 72 64 31 2c 20 20 20 20 20 20 20 20 20 20  cord1,          
6230: 20 20 20 20 20 20 2f 2a 20 6f 6c 64 2e 2a 20 72        /* old.* r
6240: 65 63 6f 72 64 20 66 6f 72 20 66 69 72 73 74 20  ecord for first 
6250: 63 68 61 6e 67 65 20 2a 2f 0a 20 20 75 38 20 2a  change */.  u8 *
6260: 61 4f 6c 64 52 65 63 6f 72 64 32 2c 20 20 20 20  aOldRecord2,    
6270: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 6f              /* o
6280: 6c 64 2e 2a 20 72 65 63 6f 72 64 20 66 6f 72 20  ld.* record for 
6290: 73 65 63 6f 6e 64 20 63 68 61 6e 67 65 20 2a 2f  second change */
62a0: 0a 20 20 75 38 20 2a 61 4e 65 77 52 65 63 6f 72  .  u8 *aNewRecor
62b0: 64 31 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  d1,             
62c0: 20 20 20 2f 2a 20 6e 65 77 2e 2a 20 72 65 63 6f     /* new.* reco
62d0: 72 64 20 66 6f 72 20 66 69 72 73 74 20 63 68 61  rd for first cha
62e0: 6e 67 65 20 2a 2f 0a 20 20 75 38 20 2a 61 4e 65  nge */.  u8 *aNe
62f0: 77 52 65 63 6f 72 64 32 20 20 20 20 20 20 20 20  wRecord2        
6300: 20 20 20 20 20 20 20 20 20 2f 2a 20 6e 65 77 2e           /* new.
6310: 2a 20 72 65 63 6f 72 64 20 66 6f 72 20 73 65 63  * record for sec
6320: 6f 6e 64 20 63 68 61 6e 67 65 20 2a 2f 0a 29 7b  ond change */.){
6330: 0a 20 20 75 38 20 2a 61 4f 6c 64 31 20 3d 20 61  .  u8 *aOld1 = a
6340: 4f 6c 64 52 65 63 6f 72 64 31 3b 0a 20 20 75 38  OldRecord1;.  u8
6350: 20 2a 61 4f 6c 64 32 20 3d 20 61 4f 6c 64 52 65   *aOld2 = aOldRe
6360: 63 6f 72 64 32 3b 0a 20 20 75 38 20 2a 61 4e 65  cord2;.  u8 *aNe
6370: 77 31 20 3d 20 61 4e 65 77 52 65 63 6f 72 64 31  w1 = aNewRecord1
6380: 3b 0a 20 20 75 38 20 2a 61 4e 65 77 32 20 3d 20  ;.  u8 *aNew2 = 
6390: 61 4e 65 77 52 65 63 6f 72 64 32 3b 0a 0a 20 20  aNewRecord2;..  
63a0: 75 38 20 2a 61 4f 75 74 20 3d 20 2a 70 61 4f 75  u8 *aOut = *paOu
63b0: 74 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 69  t;.  int i;..  i
63c0: 66 28 20 62 50 61 74 63 68 73 65 74 3d 3d 30 20  f( bPatchset==0 
63d0: 29 7b 0a 20 20 20 20 69 6e 74 20 62 52 65 71 75  ){.    int bRequ
63e0: 69 72 65 64 20 3d 20 30 3b 0a 0a 20 20 20 20 61  ired = 0;..    a
63f0: 73 73 65 72 74 28 20 61 4f 6c 64 52 65 63 6f 72  ssert( aOldRecor
6400: 64 31 20 26 26 20 61 4e 65 77 52 65 63 6f 72 64  d1 && aNewRecord
6410: 31 20 29 3b 0a 0a 20 20 20 20 2f 2a 20 57 72 69  1 );..    /* Wri
6420: 74 65 20 74 68 65 20 6f 6c 64 2e 2a 20 76 65 63  te the old.* vec
6430: 74 6f 72 20 66 69 72 73 74 2e 20 2a 2f 0a 20 20  tor first. */.  
6440: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61    for(i=0; i<pTa
6450: 62 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20  b->nCol; i++){. 
6460: 20 20 20 20 20 69 6e 74 20 6e 4f 6c 64 3b 0a 20       int nOld;. 
6470: 20 20 20 20 20 75 38 20 2a 61 4f 6c 64 3b 0a 20       u8 *aOld;. 
6480: 20 20 20 20 20 69 6e 74 20 6e 4e 65 77 3b 0a 20       int nNew;. 
6490: 20 20 20 20 20 75 38 20 2a 61 4e 65 77 3b 0a 0a       u8 *aNew;..
64a0: 20 20 20 20 20 20 61 4f 6c 64 20 3d 20 73 65 73        aOld = ses
64b0: 73 69 6f 6e 4d 65 72 67 65 56 61 6c 75 65 28 26  sionMergeValue(&
64c0: 61 4f 6c 64 31 2c 20 26 61 4f 6c 64 32 2c 20 26  aOld1, &aOld2, &
64d0: 6e 4f 6c 64 29 3b 0a 20 20 20 20 20 20 61 4e 65  nOld);.      aNe
64e0: 77 20 3d 20 73 65 73 73 69 6f 6e 4d 65 72 67 65  w = sessionMerge
64f0: 56 61 6c 75 65 28 26 61 4e 65 77 31 2c 20 26 61  Value(&aNew1, &a
6500: 4e 65 77 32 2c 20 26 6e 4e 65 77 29 3b 0a 20 20  New2, &nNew);.  
6510: 20 20 20 20 69 66 28 20 70 54 61 62 2d 3e 61 62      if( pTab->ab
6520: 50 4b 5b 69 5d 20 7c 7c 20 6e 4f 6c 64 21 3d 6e  PK[i] || nOld!=n
6530: 4e 65 77 20 7c 7c 20 6d 65 6d 63 6d 70 28 61 4f  New || memcmp(aO
6540: 6c 64 2c 20 61 4e 65 77 2c 20 6e 4e 65 77 29 20  ld, aNew, nNew) 
6550: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70  ){.        if( p
6560: 54 61 62 2d 3e 61 62 50 4b 5b 69 5d 3d 3d 30 20  Tab->abPK[i]==0 
6570: 29 20 62 52 65 71 75 69 72 65 64 20 3d 20 31 3b  ) bRequired = 1;
6580: 0a 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28  .        memcpy(
6590: 61 4f 75 74 2c 20 61 4f 6c 64 2c 20 6e 4f 6c 64  aOut, aOld, nOld
65a0: 29 3b 0a 20 20 20 20 20 20 20 20 61 4f 75 74 20  );.        aOut 
65b0: 2b 3d 20 6e 4f 6c 64 3b 0a 20 20 20 20 20 20 7d  += nOld;.      }
65c0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 2a 28  else{.        *(
65d0: 61 4f 75 74 2b 2b 29 20 3d 20 27 5c 30 27 3b 0a  aOut++) = '\0';.
65e0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20        }.    }.. 
65f0: 20 20 20 69 66 28 20 21 62 52 65 71 75 69 72 65     if( !bRequire
6600: 64 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20  d ) return 0;.  
6610: 7d 0a 0a 20 20 2f 2a 20 57 72 69 74 65 20 74 68  }..  /* Write th
6620: 65 20 6e 65 77 2e 2a 20 76 65 63 74 6f 72 20 2a  e new.* vector *
6630: 2f 0a 20 20 61 4f 6c 64 31 20 3d 20 61 4f 6c 64  /.  aOld1 = aOld
6640: 52 65 63 6f 72 64 31 3b 0a 20 20 61 4f 6c 64 32  Record1;.  aOld2
6650: 20 3d 20 61 4f 6c 64 52 65 63 6f 72 64 32 3b 0a   = aOldRecord2;.
6660: 20 20 61 4e 65 77 31 20 3d 20 61 4e 65 77 52 65    aNew1 = aNewRe
6670: 63 6f 72 64 31 3b 0a 20 20 61 4e 65 77 32 20 3d  cord1;.  aNew2 =
6680: 20 61 4e 65 77 52 65 63 6f 72 64 32 3b 0a 20 20   aNewRecord2;.  
6690: 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61 62 2d  for(i=0; i<pTab-
66a0: 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20  >nCol; i++){.   
66b0: 20 69 6e 74 20 6e 4f 6c 64 3b 0a 20 20 20 20 75   int nOld;.    u
66c0: 38 20 2a 61 4f 6c 64 3b 0a 20 20 20 20 69 6e 74  8 *aOld;.    int
66d0: 20 6e 4e 65 77 3b 0a 20 20 20 20 75 38 20 2a 61   nNew;.    u8 *a
66e0: 4e 65 77 3b 0a 0a 20 20 20 20 61 4f 6c 64 20 3d  New;..    aOld =
66f0: 20 73 65 73 73 69 6f 6e 4d 65 72 67 65 56 61 6c   sessionMergeVal
6700: 75 65 28 26 61 4f 6c 64 31 2c 20 26 61 4f 6c 64  ue(&aOld1, &aOld
6710: 32 2c 20 26 6e 4f 6c 64 29 3b 0a 20 20 20 20 61  2, &nOld);.    a
6720: 4e 65 77 20 3d 20 73 65 73 73 69 6f 6e 4d 65 72  New = sessionMer
6730: 67 65 56 61 6c 75 65 28 26 61 4e 65 77 31 2c 20  geValue(&aNew1, 
6740: 26 61 4e 65 77 32 2c 20 26 6e 4e 65 77 29 3b 0a  &aNew2, &nNew);.
6750: 20 20 20 20 69 66 28 20 62 50 61 74 63 68 73 65      if( bPatchse
6760: 74 3d 3d 30 20 0a 20 20 20 20 20 26 26 20 28 70  t==0 .     && (p
6770: 54 61 62 2d 3e 61 62 50 4b 5b 69 5d 20 7c 7c 20  Tab->abPK[i] || 
6780: 28 6e 4f 6c 64 3d 3d 6e 4e 65 77 20 26 26 20 30  (nOld==nNew && 0
6790: 3d 3d 6d 65 6d 63 6d 70 28 61 4f 6c 64 2c 20 61  ==memcmp(aOld, a
67a0: 4e 65 77 2c 20 6e 4e 65 77 29 29 29 20 0a 20 20  New, nNew))) .  
67b0: 20 20 29 7b 0a 20 20 20 20 20 20 2a 28 61 4f 75    ){.      *(aOu
67c0: 74 2b 2b 29 20 3d 20 27 5c 30 27 3b 0a 20 20 20  t++) = '\0';.   
67d0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6d 65   }else{.      me
67e0: 6d 63 70 79 28 61 4f 75 74 2c 20 61 4e 65 77 2c  mcpy(aOut, aNew,
67f0: 20 6e 4e 65 77 29 3b 0a 20 20 20 20 20 20 61 4f   nNew);.      aO
6800: 75 74 20 2b 3d 20 6e 4e 65 77 3b 0a 20 20 20 20  ut += nNew;.    
6810: 7d 0a 20 20 7d 0a 0a 20 20 2a 70 61 4f 75 74 20  }.  }..  *paOut 
6820: 3d 20 61 4f 75 74 3b 0a 20 20 72 65 74 75 72 6e  = aOut;.  return
6830: 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69   1;.}../*.** Thi
6840: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 6f 6e  s function is on
6850: 6c 79 20 63 61 6c 6c 65 64 20 66 72 6f 6d 20 77  ly called from w
6860: 69 74 68 69 6e 20 61 20 70 72 65 2d 75 70 64 61  ithin a pre-upda
6870: 74 65 2d 68 6f 6f 6b 20 63 61 6c 6c 62 61 63 6b  te-hook callback
6880: 2e 0a 2a 2a 20 49 74 20 64 65 74 65 72 6d 69 6e  ..** It determin
6890: 65 73 20 69 66 20 74 68 65 20 63 75 72 72 65 6e  es if the curren
68a0: 74 20 70 72 65 2d 75 70 64 61 74 65 2d 68 6f 6f  t pre-update-hoo
68b0: 6b 20 63 68 61 6e 67 65 20 61 66 66 65 63 74 73  k change affects
68c0: 20 74 68 65 20 73 61 6d 65 20 72 6f 77 0a 2a 2a   the same row.**
68d0: 20 61 73 20 74 68 65 20 63 68 61 6e 67 65 20 73   as the change s
68e0: 74 6f 72 65 64 20 69 6e 20 61 72 67 75 6d 65 6e  tored in argumen
68f0: 74 20 70 43 68 61 6e 67 65 2e 20 49 66 20 73 6f  t pChange. If so
6900: 2c 20 69 74 20 72 65 74 75 72 6e 73 20 74 72 75  , it returns tru
6910: 65 2e 20 4f 74 68 65 72 77 69 73 65 0a 2a 2a 20  e. Otherwise.** 
6920: 69 66 20 74 68 65 20 70 72 65 2d 75 70 64 61 74  if the pre-updat
6930: 65 2d 68 6f 6f 6b 20 64 6f 65 73 20 6e 6f 74 20  e-hook does not 
6940: 61 66 66 65 63 74 20 74 68 65 20 73 61 6d 65 20  affect the same 
6950: 72 6f 77 20 61 73 20 70 43 68 61 6e 67 65 2c 20  row as pChange, 
6960: 69 74 20 72 65 74 75 72 6e 73 0a 2a 2a 20 66 61  it returns.** fa
6970: 6c 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  lse..*/.static i
6980: 6e 74 20 73 65 73 73 69 6f 6e 50 72 65 75 70 64  nt sessionPreupd
6990: 61 74 65 45 71 75 61 6c 28 0a 20 20 73 71 6c 69  ateEqual(.  sqli
69a0: 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65  te3_session *pSe
69b0: 73 73 69 6f 6e 2c 20 20 20 20 20 20 2f 2a 20 53  ssion,      /* S
69c0: 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 74 68  ession object th
69d0: 61 74 20 6f 77 6e 73 20 53 65 73 73 69 6f 6e 54  at owns SessionT
69e0: 61 62 6c 65 20 2a 2f 0a 20 20 53 65 73 73 69 6f  able */.  Sessio
69f0: 6e 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 20 20  nTable *pTab,   
6a00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62            /* Tab
6a10: 6c 65 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  le associated wi
6a20: 74 68 20 63 68 61 6e 67 65 20 2a 2f 0a 20 20 53  th change */.  S
6a30: 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 70 43  essionChange *pC
6a40: 68 61 6e 67 65 2c 20 20 20 20 20 20 20 20 20 2f  hange,         /
6a50: 2a 20 43 68 61 6e 67 65 20 74 6f 20 63 6f 6d 70  * Change to comp
6a60: 61 72 65 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20  are to */.  int 
6a70: 6f 70 20 20 20 20 20 20 20 20 20 20 20 20 20 20  op              
6a80: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
6a90: 75 72 72 65 6e 74 20 70 72 65 2d 75 70 64 61 74  urrent pre-updat
6aa0: 65 20 6f 70 65 72 61 74 69 6f 6e 20 2a 2f 0a 29  e operation */.)
6ab0: 7b 0a 20 20 69 6e 74 20 69 43 6f 6c 3b 20 20 20  {.  int iCol;   
6ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ad0: 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69      /* Used to i
6ae0: 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 63  terate through c
6af0: 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 75 38 20 2a  olumns */.  u8 *
6b00: 61 20 3d 20 70 43 68 61 6e 67 65 2d 3e 61 52 65  a = pChange->aRe
6b10: 63 6f 72 64 3b 20 20 20 20 20 20 20 2f 2a 20 43  cord;       /* C
6b20: 75 72 73 6f 72 20 75 73 65 64 20 74 6f 20 73 63  ursor used to sc
6b30: 61 6e 20 63 68 61 6e 67 65 20 72 65 63 6f 72 64  an change record
6b40: 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 6f   */..  assert( o
6b50: 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52 54  p==SQLITE_INSERT
6b60: 20 7c 7c 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 55   || op==SQLITE_U
6b70: 50 44 41 54 45 20 7c 7c 20 6f 70 3d 3d 53 51 4c  PDATE || op==SQL
6b80: 49 54 45 5f 44 45 4c 45 54 45 20 29 3b 0a 20 20  ITE_DELETE );.  
6b90: 66 6f 72 28 69 43 6f 6c 3d 30 3b 20 69 43 6f 6c  for(iCol=0; iCol
6ba0: 3c 70 54 61 62 2d 3e 6e 43 6f 6c 3b 20 69 43 6f  <pTab->nCol; iCo
6bb0: 6c 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 21 70  l++){.    if( !p
6bc0: 54 61 62 2d 3e 61 62 50 4b 5b 69 43 6f 6c 5d 20  Tab->abPK[iCol] 
6bd0: 29 7b 0a 20 20 20 20 20 20 61 20 2b 3d 20 73 65  ){.      a += se
6be0: 73 73 69 6f 6e 53 65 72 69 61 6c 4c 65 6e 28 61  ssionSerialLen(a
6bf0: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
6c00: 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75      sqlite3_valu
6c10: 65 20 2a 70 56 61 6c 3b 20 20 20 20 20 20 20 20  e *pVal;        
6c20: 2f 2a 20 56 61 6c 75 65 20 72 65 74 75 72 6e 65  /* Value returne
6c30: 64 20 62 79 20 70 72 65 75 70 64 61 74 65 5f 6e  d by preupdate_n
6c40: 65 77 2f 6f 6c 64 20 2a 2f 0a 20 20 20 20 20 20  ew/old */.      
6c50: 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
6c60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45              /* E
6c70: 72 72 6f 72 20 63 6f 64 65 20 66 72 6f 6d 20 70  rror code from p
6c80: 72 65 75 70 64 61 74 65 5f 6e 65 77 2f 6f 6c 64  reupdate_new/old
6c90: 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 65 54   */.      int eT
6ca0: 79 70 65 20 3d 20 2a 61 2b 2b 3b 20 20 20 20 20  ype = *a++;     
6cb0: 20 20 20 20 20 20 2f 2a 20 54 79 70 65 20 6f 66        /* Type of
6cc0: 20 76 61 6c 75 65 20 66 72 6f 6d 20 63 68 61 6e   value from chan
6cd0: 67 65 20 72 65 63 6f 72 64 20 2a 2f 0a 0a 20 20  ge record */..  
6ce0: 20 20 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f      /* The follo
6cf0: 77 69 6e 67 20 63 61 6c 6c 73 20 74 6f 20 70 72  wing calls to pr
6d00: 65 75 70 64 61 74 65 5f 6e 65 77 28 29 20 61 6e  eupdate_new() an
6d10: 64 20 70 72 65 75 70 64 61 74 65 5f 6f 6c 64 28  d preupdate_old(
6d20: 29 20 63 61 6e 20 6e 6f 74 0a 20 20 20 20 20 20  ) can not.      
6d30: 2a 2a 20 66 61 69 6c 2e 20 54 68 69 73 20 69 73  ** fail. This is
6d40: 20 62 65 63 61 75 73 65 20 74 68 65 79 20 63 61   because they ca
6d50: 63 68 65 20 74 68 65 69 72 20 72 65 74 75 72 6e  che their return
6d60: 20 76 61 6c 75 65 73 2c 20 61 6e 64 20 62 79 20   values, and by 
6d70: 74 68 65 0a 20 20 20 20 20 20 2a 2a 20 74 69 6d  the.      ** tim
6d80: 65 20 63 6f 6e 74 72 6f 6c 20 66 6c 6f 77 73 20  e control flows 
6d90: 74 6f 20 68 65 72 65 20 74 68 65 79 20 68 61 76  to here they hav
6da0: 65 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 63  e already been c
6db0: 61 6c 6c 65 64 20 6f 6e 63 65 20 66 72 6f 6d 0a  alled once from.
6dc0: 20 20 20 20 20 20 2a 2a 20 77 69 74 68 69 6e 20        ** within 
6dd0: 73 65 73 73 69 6f 6e 50 72 65 75 70 64 61 74 65  sessionPreupdate
6de0: 48 61 73 68 28 29 2e 20 54 68 65 20 66 69 72 73  Hash(). The firs
6df0: 74 20 74 77 6f 20 61 73 73 65 72 74 73 20 62 65  t two asserts be
6e00: 6c 6f 77 20 76 65 72 69 66 79 0a 20 20 20 20 20  low verify.     
6e10: 20 2a 2a 20 74 68 69 73 20 28 74 68 61 74 20 74   ** this (that t
6e20: 68 65 20 6d 65 74 68 6f 64 20 68 61 73 20 61 6c  he method has al
6e30: 72 65 61 64 79 20 62 65 65 6e 20 63 61 6c 6c 65  ready been calle
6e40: 64 29 2e 20 2a 2f 0a 20 20 20 20 20 20 69 66 28  d). */.      if(
6e50: 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 53 45   op==SQLITE_INSE
6e60: 52 54 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a  RT ){.        /*
6e70: 20 61 73 73 65 72 74 28 20 64 62 2d 3e 70 50 72   assert( db->pPr
6e80: 65 55 70 64 61 74 65 2d 3e 70 4e 65 77 55 6e 70  eUpdate->pNewUnp
6e90: 61 63 6b 65 64 20 7c 7c 20 64 62 2d 3e 70 50 72  acked || db->pPr
6ea0: 65 55 70 64 61 74 65 2d 3e 61 4e 65 77 20 29 3b  eUpdate->aNew );
6eb0: 20 2a 2f 0a 20 20 20 20 20 20 20 20 72 63 20 3d   */.        rc =
6ec0: 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e   pSession->hook.
6ed0: 78 4e 65 77 28 70 53 65 73 73 69 6f 6e 2d 3e 68  xNew(pSession->h
6ee0: 6f 6f 6b 2e 70 43 74 78 2c 20 69 43 6f 6c 2c 20  ook.pCtx, iCol, 
6ef0: 26 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 7d 65  &pVal);.      }e
6f00: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20  lse{.        /* 
6f10: 61 73 73 65 72 74 28 20 64 62 2d 3e 70 50 72 65  assert( db->pPre
6f20: 55 70 64 61 74 65 2d 3e 70 55 6e 70 61 63 6b 65  Update->pUnpacke
6f30: 64 20 29 3b 20 2a 2f 0a 20 20 20 20 20 20 20 20  d ); */.        
6f40: 72 63 20 3d 20 70 53 65 73 73 69 6f 6e 2d 3e 68  rc = pSession->h
6f50: 6f 6f 6b 2e 78 4f 6c 64 28 70 53 65 73 73 69 6f  ook.xOld(pSessio
6f60: 6e 2d 3e 68 6f 6f 6b 2e 70 43 74 78 2c 20 69 43  n->hook.pCtx, iC
6f70: 6f 6c 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20 20  ol, &pVal);.    
6f80: 20 20 7d 0a 20 20 20 20 20 20 61 73 73 65 72 74    }.      assert
6f90: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
6fa0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 73 71 6c  );.      if( sql
6fb0: 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
6fc0: 70 56 61 6c 29 21 3d 65 54 79 70 65 20 29 20 72  pVal)!=eType ) r
6fd0: 65 74 75 72 6e 20 30 3b 0a 0a 20 20 20 20 20 20  eturn 0;..      
6fe0: 2f 2a 20 41 20 53 65 73 73 69 6f 6e 43 68 61 6e  /* A SessionChan
6ff0: 67 65 20 6f 62 6a 65 63 74 20 6e 65 76 65 72 20  ge object never 
7000: 68 61 73 20 61 20 4e 55 4c 4c 20 76 61 6c 75 65  has a NULL value
7010: 20 69 6e 20 61 20 50 4b 20 63 6f 6c 75 6d 6e 20   in a PK column 
7020: 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  */.      assert(
7030: 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49   eType==SQLITE_I
7040: 4e 54 45 47 45 52 20 7c 7c 20 65 54 79 70 65 3d  NTEGER || eType=
7050: 3d 53 51 4c 49 54 45 5f 46 4c 4f 41 54 0a 20 20  =SQLITE_FLOAT.  
7060: 20 20 20 20 20 20 20 20 20 7c 7c 20 65 54 79 70           || eTyp
7070: 65 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 20 20  e==SQLITE_BLOB  
7080: 20 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49    || eType==SQLI
7090: 54 45 5f 54 45 58 54 0a 20 20 20 20 20 20 29 3b  TE_TEXT.      );
70a0: 0a 0a 20 20 20 20 20 20 69 66 28 20 65 54 79 70  ..      if( eTyp
70b0: 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45  e==SQLITE_INTEGE
70c0: 52 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49  R || eType==SQLI
70d0: 54 45 5f 46 4c 4f 41 54 20 29 7b 0a 20 20 20 20  TE_FLOAT ){.    
70e0: 20 20 20 20 69 36 34 20 69 56 61 6c 20 3d 20 73      i64 iVal = s
70f0: 65 73 73 69 6f 6e 47 65 74 49 36 34 28 61 29 3b  essionGetI64(a);
7100: 0a 20 20 20 20 20 20 20 20 61 20 2b 3d 20 38 3b  .        a += 8;
7110: 0a 20 20 20 20 20 20 20 20 69 66 28 20 65 54 79  .        if( eTy
7120: 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47  pe==SQLITE_INTEG
7130: 45 52 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  ER ){.          
7140: 69 66 28 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  if( sqlite3_valu
7150: 65 5f 69 6e 74 36 34 28 70 56 61 6c 29 21 3d 69  e_int64(pVal)!=i
7160: 56 61 6c 20 29 20 72 65 74 75 72 6e 20 30 3b 0a  Val ) return 0;.
7170: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
7180: 20 20 20 20 20 20 20 20 20 64 6f 75 62 6c 65 20           double 
7190: 72 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 20 20  rVal;.          
71a0: 61 73 73 65 72 74 28 20 73 69 7a 65 6f 66 28 69  assert( sizeof(i
71b0: 56 61 6c 29 3d 3d 38 20 26 26 20 73 69 7a 65 6f  Val)==8 && sizeo
71c0: 66 28 72 56 61 6c 29 3d 3d 38 20 29 3b 0a 20 20  f(rVal)==8 );.  
71d0: 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26          memcpy(&
71e0: 72 56 61 6c 2c 20 26 69 56 61 6c 2c 20 38 29 3b  rVal, &iVal, 8);
71f0: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 73  .          if( s
7200: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 64 6f 75  qlite3_value_dou
7210: 62 6c 65 28 70 56 61 6c 29 21 3d 72 56 61 6c 20  ble(pVal)!=rVal 
7220: 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20  ) return 0;.    
7230: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73      }.      }els
7240: 65 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e  e{.        int n
7250: 3b 0a 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20  ;.        const 
7260: 75 38 20 2a 7a 3b 0a 20 20 20 20 20 20 20 20 61  u8 *z;.        a
7270: 20 2b 3d 20 73 65 73 73 69 6f 6e 56 61 72 69 6e   += sessionVarin
7280: 74 47 65 74 28 61 2c 20 26 6e 29 3b 0a 20 20 20  tGet(a, &n);.   
7290: 20 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33       if( sqlite3
72a0: 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 70 56 61  _value_bytes(pVa
72b0: 6c 29 21 3d 6e 20 29 20 72 65 74 75 72 6e 20 30  l)!=n ) return 0
72c0: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 65 54  ;.        if( eT
72d0: 79 70 65 3d 3d 53 51 4c 49 54 45 5f 54 45 58 54  ype==SQLITE_TEXT
72e0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 7a 20   ){.          z 
72f0: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
7300: 74 65 78 74 28 70 56 61 6c 29 3b 0a 20 20 20 20  text(pVal);.    
7310: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
7320: 20 20 20 20 20 7a 20 3d 20 73 71 6c 69 74 65 33       z = sqlite3
7330: 5f 76 61 6c 75 65 5f 62 6c 6f 62 28 70 56 61 6c  _value_blob(pVal
7340: 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  );.        }.   
7350: 20 20 20 20 20 69 66 28 20 6d 65 6d 63 6d 70 28       if( memcmp(
7360: 61 2c 20 7a 2c 20 6e 29 20 29 20 72 65 74 75 72  a, z, n) ) retur
7370: 6e 20 30 3b 0a 20 20 20 20 20 20 20 20 61 20 2b  n 0;.        a +
7380: 3d 20 6e 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  = n;.      }.   
7390: 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
73a0: 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20   1;.}../*.** If 
73b0: 72 65 71 75 69 72 65 64 2c 20 67 72 6f 77 20 74  required, grow t
73c0: 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 75 73  he hash table us
73d0: 65 64 20 74 6f 20 73 74 6f 72 65 20 63 68 61 6e  ed to store chan
73e0: 67 65 73 20 6f 6e 20 74 61 62 6c 65 20 70 54 61  ges on table pTa
73f0: 62 20 0a 2a 2a 20 28 70 61 72 74 20 6f 66 20 74  b .** (part of t
7400: 68 65 20 73 65 73 73 69 6f 6e 20 70 53 65 73 73  he session pSess
7410: 69 6f 6e 29 2e 20 49 66 20 61 20 66 61 74 61 6c  ion). If a fatal
7420: 20 4f 4f 4d 20 65 72 72 6f 72 20 6f 63 63 75 72   OOM error occur
7430: 73 2c 20 73 65 74 20 74 68 65 0a 2a 2a 20 73 65  s, set the.** se
7440: 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 74 6f 20  ssion object to 
7450: 66 61 69 6c 65 64 20 61 6e 64 20 72 65 74 75 72  failed and retur
7460: 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 2e 20  n SQLITE_ERROR. 
7470: 4f 74 68 65 72 77 69 73 65 2c 20 72 65 74 75 72  Otherwise, retur
7480: 6e 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a  n.** SQLITE_OK..
7490: 2a 2a 0a 2a 2a 20 49 74 20 69 73 20 70 6f 73 73  **.** It is poss
74a0: 69 62 6c 65 20 74 68 61 74 20 61 20 6e 6f 6e 2d  ible that a non-
74b0: 66 61 74 61 6c 20 4f 4f 4d 20 65 72 72 6f 72 20  fatal OOM error 
74c0: 6f 63 63 75 72 73 20 69 6e 20 74 68 69 73 20 66  occurs in this f
74d0: 75 6e 63 74 69 6f 6e 2e 20 49 6e 0a 2a 2a 20 74  unction. In.** t
74e0: 68 61 74 20 63 61 73 65 20 74 68 65 20 68 61 73  hat case the has
74f0: 68 2d 74 61 62 6c 65 20 64 6f 65 73 20 6e 6f 74  h-table does not
7500: 20 67 72 6f 77 2c 20 62 75 74 20 53 51 4c 49 54   grow, but SQLIT
7510: 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64  E_OK is returned
7520: 20 61 6e 79 77 61 79 2e 0a 2a 2a 20 47 72 6f 77   anyway..** Grow
7530: 69 6e 67 20 74 68 65 20 68 61 73 68 20 74 61 62  ing the hash tab
7540: 6c 65 20 69 6e 20 74 68 69 73 20 63 61 73 65 20  le in this case 
7550: 69 73 20 61 20 70 65 72 66 6f 72 6d 61 6e 63 65  is a performance
7560: 20 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 20 6f 6e   optimization on
7570: 6c 79 2c 0a 2a 2a 20 69 74 20 69 73 20 6e 6f 74  ly,.** it is not
7580: 20 72 65 71 75 69 72 65 64 20 66 6f 72 20 63 6f   required for co
7590: 72 72 65 63 74 20 6f 70 65 72 61 74 69 6f 6e 2e  rrect operation.
75a0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73  .*/.static int s
75b0: 65 73 73 69 6f 6e 47 72 6f 77 48 61 73 68 28 69  essionGrowHash(i
75c0: 6e 74 20 62 50 61 74 63 68 73 65 74 2c 20 53 65  nt bPatchset, Se
75d0: 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62  ssionTable *pTab
75e0: 29 7b 0a 20 20 69 66 28 20 70 54 61 62 2d 3e 6e  ){.  if( pTab->n
75f0: 43 68 61 6e 67 65 3d 3d 30 20 7c 7c 20 70 54 61  Change==0 || pTa
7600: 62 2d 3e 6e 45 6e 74 72 79 3e 3d 28 70 54 61 62  b->nEntry>=(pTab
7610: 2d 3e 6e 43 68 61 6e 67 65 2f 32 29 20 29 7b 0a  ->nChange/2) ){.
7620: 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 53      int i;.    S
7630: 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 2a 61  essionChange **a
7640: 70 4e 65 77 3b 0a 20 20 20 20 69 6e 74 20 6e 4e  pNew;.    int nN
7650: 65 77 20 3d 20 28 70 54 61 62 2d 3e 6e 43 68 61  ew = (pTab->nCha
7660: 6e 67 65 20 3f 20 70 54 61 62 2d 3e 6e 43 68 61  nge ? pTab->nCha
7670: 6e 67 65 20 3a 20 31 32 38 29 20 2a 20 32 3b 0a  nge : 128) * 2;.
7680: 0a 20 20 20 20 61 70 4e 65 77 20 3d 20 28 53 65  .    apNew = (Se
7690: 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 2a 29 73  ssionChange **)s
76a0: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69  qlite3_malloc(si
76b0: 7a 65 6f 66 28 53 65 73 73 69 6f 6e 43 68 61 6e  zeof(SessionChan
76c0: 67 65 20 2a 29 20 2a 20 6e 4e 65 77 29 3b 0a 20  ge *) * nNew);. 
76d0: 20 20 20 69 66 28 20 61 70 4e 65 77 3d 3d 30 20     if( apNew==0 
76e0: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 54 61  ){.      if( pTa
76f0: 62 2d 3e 6e 43 68 61 6e 67 65 3d 3d 30 20 29 7b  b->nChange==0 ){
7700: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
7710: 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
7720: 20 20 20 20 7d 0a 20 20 20 20 20 20 72 65 74 75      }.      retu
7730: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20  rn SQLITE_OK;.  
7740: 20 20 7d 0a 20 20 20 20 6d 65 6d 73 65 74 28 61    }.    memset(a
7750: 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65 6f 66 28  pNew, 0, sizeof(
7760: 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 29  SessionChange *)
7770: 20 2a 20 6e 4e 65 77 29 3b 0a 0a 20 20 20 20 66   * nNew);..    f
7780: 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61 62 2d 3e  or(i=0; i<pTab->
7790: 6e 43 68 61 6e 67 65 3b 20 69 2b 2b 29 7b 0a 20  nChange; i++){. 
77a0: 20 20 20 20 20 53 65 73 73 69 6f 6e 43 68 61 6e       SessionChan
77b0: 67 65 20 2a 70 3b 0a 20 20 20 20 20 20 53 65 73  ge *p;.      Ses
77c0: 73 69 6f 6e 43 68 61 6e 67 65 20 2a 70 4e 65 78  sionChange *pNex
77d0: 74 3b 0a 20 20 20 20 20 20 66 6f 72 28 70 3d 70  t;.      for(p=p
77e0: 54 61 62 2d 3e 61 70 43 68 61 6e 67 65 5b 69 5d  Tab->apChange[i]
77f0: 3b 20 70 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20  ; p; p=pNext){. 
7800: 20 20 20 20 20 20 20 69 6e 74 20 62 50 6b 4f 6e         int bPkOn
7810: 6c 79 20 3d 20 28 70 2d 3e 6f 70 3d 3d 53 51 4c  ly = (p->op==SQL
7820: 49 54 45 5f 44 45 4c 45 54 45 20 26 26 20 62 50  ITE_DELETE && bP
7830: 61 74 63 68 73 65 74 29 3b 0a 20 20 20 20 20 20  atchset);.      
7840: 20 20 69 6e 74 20 69 48 61 73 68 20 3d 20 73 65    int iHash = se
7850: 73 73 69 6f 6e 43 68 61 6e 67 65 48 61 73 68 28  ssionChangeHash(
7860: 70 54 61 62 2c 20 62 50 6b 4f 6e 6c 79 2c 20 70  pTab, bPkOnly, p
7870: 2d 3e 61 52 65 63 6f 72 64 2c 20 6e 4e 65 77 29  ->aRecord, nNew)
7880: 3b 0a 20 20 20 20 20 20 20 20 70 4e 65 78 74 20  ;.        pNext 
7890: 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  = p->pNext;.    
78a0: 20 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 61      p->pNext = a
78b0: 70 4e 65 77 5b 69 48 61 73 68 5d 3b 0a 20 20 20  pNew[iHash];.   
78c0: 20 20 20 20 20 61 70 4e 65 77 5b 69 48 61 73 68       apNew[iHash
78d0: 5d 20 3d 20 70 3b 0a 20 20 20 20 20 20 7d 0a 20  ] = p;.      }. 
78e0: 20 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69 74 65     }..    sqlite
78f0: 33 5f 66 72 65 65 28 70 54 61 62 2d 3e 61 70 43  3_free(pTab->apC
7900: 68 61 6e 67 65 29 3b 0a 20 20 20 20 70 54 61 62  hange);.    pTab
7910: 2d 3e 6e 43 68 61 6e 67 65 20 3d 20 6e 4e 65 77  ->nChange = nNew
7920: 3b 0a 20 20 20 20 70 54 61 62 2d 3e 61 70 43 68  ;.    pTab->apCh
7930: 61 6e 67 65 20 3d 20 61 70 4e 65 77 3b 0a 20 20  ange = apNew;.  
7940: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  }..  return SQLI
7950: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
7960: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 71 75  This function qu
7970: 65 72 69 65 73 20 74 68 65 20 64 61 74 61 62 61  eries the databa
7980: 73 65 20 66 6f 72 20 74 68 65 20 6e 61 6d 65 73  se for the names
7990: 20 6f 66 20 74 68 65 20 63 6f 6c 75 6d 6e 73 20   of the columns 
79a0: 6f 66 20 74 61 62 6c 65 0a 2a 2a 20 7a 54 68 69  of table.** zThi
79b0: 73 2c 20 69 6e 20 73 63 68 65 6d 61 20 7a 44 62  s, in schema zDb
79c0: 2e 0a 2a 2a 0a 2a 2a 20 4f 74 68 65 72 77 69 73  ..**.** Otherwis
79d0: 65 2c 20 69 66 20 74 68 65 79 20 61 72 65 20 6e  e, if they are n
79e0: 6f 74 20 4e 55 4c 4c 2c 20 76 61 72 69 61 62 6c  ot NULL, variabl
79f0: 65 20 2a 70 6e 43 6f 6c 20 69 73 20 73 65 74 20  e *pnCol is set 
7a00: 74 6f 20 74 68 65 20 6e 75 6d 62 65 72 0a 2a 2a  to the number.**
7a10: 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74   of columns in t
7a20: 68 65 20 64 61 74 61 62 61 73 65 20 74 61 62 6c  he database tabl
7a30: 65 20 61 6e 64 20 76 61 72 69 61 62 6c 65 20 2a  e and variable *
7a40: 70 7a 54 61 62 20 69 73 20 73 65 74 20 74 6f 20  pzTab is set to 
7a50: 70 6f 69 6e 74 20 74 6f 20 61 0a 2a 2a 20 6e 75  point to a.** nu
7a60: 6c 2d 74 65 72 6d 69 6e 61 74 65 64 20 63 6f 70  l-terminated cop
7a70: 79 20 6f 66 20 74 68 65 20 74 61 62 6c 65 20 6e  y of the table n
7a80: 61 6d 65 2e 20 2a 70 61 7a 43 6f 6c 20 28 69 66  ame. *pazCol (if
7a90: 20 6e 6f 74 20 4e 55 4c 4c 29 20 69 73 20 73 65   not NULL) is se
7aa0: 74 20 74 6f 0a 2a 2a 20 70 6f 69 6e 74 20 74 6f  t to.** point to
7ab0: 20 61 6e 20 61 72 72 61 79 20 6f 66 20 70 6f 69   an array of poi
7ac0: 6e 74 65 72 73 20 74 6f 20 63 6f 6c 75 6d 6e 20  nters to column 
7ad0: 6e 61 6d 65 73 2e 20 41 6e 64 20 2a 70 61 62 50  names. And *pabP
7ae0: 4b 20 28 61 67 61 69 6e 2c 20 69 66 20 6e 6f 74  K (again, if not
7af0: 0a 2a 2a 20 4e 55 4c 4c 29 20 69 73 20 73 65 74  .** NULL) is set
7b00: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 61 6e 20   to point to an 
7b10: 61 72 72 61 79 20 6f 66 20 62 6f 6f 6c 65 61 6e  array of boolean
7b20: 73 20 2d 20 74 72 75 65 20 69 66 20 74 68 65 20  s - true if the 
7b30: 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 0a 2a 2a  corresponding.**
7b40: 20 63 6f 6c 75 6d 6e 20 69 73 20 70 61 72 74 20   column is part 
7b50: 6f 66 20 74 68 65 20 70 72 69 6d 61 72 79 20 6b  of the primary k
7b60: 65 79 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 65 78  ey..**.** For ex
7b70: 61 6d 70 6c 65 2c 20 69 66 20 74 68 65 20 74 61  ample, if the ta
7b80: 62 6c 65 20 69 73 20 64 65 63 6c 61 72 65 64 20  ble is declared 
7b90: 61 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 43 52  as:.**.**     CR
7ba0: 45 41 54 45 20 54 41 42 4c 45 20 74 62 6c 31 28  EATE TABLE tbl1(
7bb0: 77 2c 20 78 2c 20 79 2c 20 7a 2c 20 50 52 49 4d  w, x, y, z, PRIM
7bc0: 41 52 59 20 4b 45 59 28 77 2c 20 7a 29 29 3b 0a  ARY KEY(w, z));.
7bd0: 2a 2a 0a 2a 2a 20 54 68 65 6e 20 74 68 65 20 66  **.** Then the f
7be0: 6f 75 72 20 6f 75 74 70 75 74 20 76 61 72 69 61  our output varia
7bf0: 62 6c 65 73 20 61 72 65 20 70 6f 70 75 6c 61 74  bles are populat
7c00: 65 64 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  ed as follows:.*
7c10: 2a 0a 2a 2a 20 20 20 20 20 2a 70 6e 43 6f 6c 20  *.**     *pnCol 
7c20: 20 3d 20 34 0a 2a 2a 20 20 20 20 20 2a 70 7a 54   = 4.**     *pzT
7c30: 61 62 20 20 3d 20 22 74 62 6c 31 22 0a 2a 2a 20  ab  = "tbl1".** 
7c40: 20 20 20 20 2a 70 61 7a 43 6f 6c 20 3d 20 7b 22      *pazCol = {"
7c50: 77 22 2c 20 22 78 22 2c 20 22 79 22 2c 20 22 7a  w", "x", "y", "z
7c60: 22 7d 0a 2a 2a 20 20 20 20 20 2a 70 61 62 50 4b  "}.**     *pabPK
7c70: 20 20 3d 20 7b 31 2c 20 30 2c 20 30 2c 20 31 7d    = {1, 0, 0, 1}
7c80: 0a 2a 2a 0a 2a 2a 20 41 6c 6c 20 72 65 74 75 72  .**.** All retur
7c90: 6e 65 64 20 62 75 66 66 65 72 73 20 61 72 65 20  ned buffers are 
7ca0: 70 61 72 74 20 6f 66 20 74 68 65 20 73 61 6d 65  part of the same
7cb0: 20 73 69 6e 67 6c 65 20 61 6c 6c 6f 63 61 74 69   single allocati
7cc0: 6f 6e 2c 20 77 68 69 63 68 20 6d 75 73 74 0a 2a  on, which must.*
7cd0: 2a 20 62 65 20 66 72 65 65 64 20 75 73 69 6e 67  * be freed using
7ce0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 29 20   sqlite3_free() 
7cf0: 62 79 20 74 68 65 20 63 61 6c 6c 65 72 0a 2a 2f  by the caller.*/
7d00: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73  .static int sess
7d10: 69 6f 6e 54 61 62 6c 65 49 6e 66 6f 28 0a 20 20  ionTableInfo(.  
7d20: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20  sqlite3 *db,    
7d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7d40: 2f 2a 20 44 61 74 61 62 61 73 65 20 63 6f 6e 6e  /* Database conn
7d50: 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73  ection */.  cons
7d60: 74 20 63 68 61 72 20 2a 7a 44 62 2c 20 20 20 20  t char *zDb,    
7d70: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
7d80: 61 6d 65 20 6f 66 20 61 74 74 61 63 68 65 64 20  ame of attached 
7d90: 64 61 74 61 62 61 73 65 20 28 65 2e 67 2e 20 22  database (e.g. "
7da0: 6d 61 69 6e 22 29 20 2a 2f 0a 20 20 63 6f 6e 73  main") */.  cons
7db0: 74 20 63 68 61 72 20 2a 7a 54 68 69 73 2c 20 20  t char *zThis,  
7dc0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
7dd0: 61 62 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 69  able name */.  i
7de0: 6e 74 20 2a 70 6e 43 6f 6c 2c 20 20 20 20 20 20  nt *pnCol,      
7df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7e00: 2a 20 4f 55 54 3a 20 6e 75 6d 62 65 72 20 6f 66  * OUT: number of
7e10: 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 63 6f   columns */.  co
7e20: 6e 73 74 20 63 68 61 72 20 2a 2a 70 7a 54 61 62  nst char **pzTab
7e30: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
7e40: 20 4f 55 54 3a 20 43 6f 70 79 20 6f 66 20 7a 54   OUT: Copy of zT
7e50: 68 69 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  his */.  const c
7e60: 68 61 72 20 2a 2a 2a 70 61 7a 43 6f 6c 2c 20 20  har ***pazCol,  
7e70: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
7e80: 20 41 72 72 61 79 20 6f 66 20 63 6f 6c 75 6d 6e   Array of column
7e90: 20 6e 61 6d 65 73 20 66 6f 72 20 74 61 62 6c 65   names for table
7ea0: 20 2a 2f 0a 20 20 75 38 20 2a 2a 70 61 62 50 4b   */.  u8 **pabPK
7eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7ec0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 41 72        /* OUT: Ar
7ed0: 72 61 79 20 6f 66 20 62 6f 6f 6c 65 61 6e 73 20  ray of booleans 
7ee0: 2d 20 74 72 75 65 20 66 6f 72 20 50 4b 20 63 6f  - true for PK co
7ef0: 6c 20 2a 2f 0a 29 7b 0a 20 20 63 68 61 72 20 2a  l */.){.  char *
7f00: 7a 50 72 61 67 6d 61 3b 0a 20 20 73 71 6c 69 74  zPragma;.  sqlit
7f10: 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a  e3_stmt *pStmt;.
7f20: 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20    int rc;.  int 
7f30: 6e 42 79 74 65 3b 0a 20 20 69 6e 74 20 6e 44 62  nByte;.  int nDb
7f40: 43 6f 6c 20 3d 20 30 3b 0a 20 20 69 6e 74 20 6e  Col = 0;.  int n
7f50: 54 68 69 73 3b 0a 20 20 69 6e 74 20 69 3b 0a 20  This;.  int i;. 
7f60: 20 75 38 20 2a 70 41 6c 6c 6f 63 20 3d 20 30 3b   u8 *pAlloc = 0;
7f70: 0a 20 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6c 20  .  char **azCol 
7f80: 3d 20 30 3b 0a 20 20 75 38 20 2a 61 62 50 4b 20  = 0;.  u8 *abPK 
7f90: 3d 20 30 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  = 0;..  assert( 
7fa0: 70 61 7a 43 6f 6c 20 26 26 20 70 61 62 50 4b 20  pazCol && pabPK 
7fb0: 29 3b 0a 0a 20 20 6e 54 68 69 73 20 3d 20 73 71  );..  nThis = sq
7fc0: 6c 69 74 65 33 53 74 72 6c 65 6e 33 30 28 7a 54  lite3Strlen30(zT
7fd0: 68 69 73 29 3b 0a 20 20 69 66 28 20 6e 54 68 69  his);.  if( nThi
7fe0: 73 3d 3d 31 32 20 26 26 20 30 3d 3d 73 71 6c 69  s==12 && 0==sqli
7ff0: 74 65 33 5f 73 74 72 69 63 6d 70 28 22 73 71 6c  te3_stricmp("sql
8000: 69 74 65 5f 73 74 61 74 31 22 2c 20 7a 54 68 69  ite_stat1", zThi
8010: 73 29 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73  s) ){.    rc = s
8020: 71 6c 69 74 65 33 5f 74 61 62 6c 65 5f 63 6f 6c  qlite3_table_col
8030: 75 6d 6e 5f 6d 65 74 61 64 61 74 61 28 64 62 2c  umn_metadata(db,
8040: 20 7a 44 62 2c 20 7a 54 68 69 73 2c 20 30 2c 20   zDb, zThis, 0, 
8050: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 29 3b 0a  0, 0, 0, 0, 0);.
8060: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
8070: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 2f  TE_OK ){.      /
8080: 2a 20 46 6f 72 20 73 71 6c 69 74 65 5f 73 74 61  * For sqlite_sta
8090: 74 31 2c 20 70 72 65 74 65 6e 64 20 74 68 61 74  t1, pretend that
80a0: 20 28 74 62 6c 2c 69 64 78 29 20 69 73 20 74 68   (tbl,idx) is th
80b0: 65 20 50 52 49 4d 41 52 59 20 4b 45 59 2e 20 2a  e PRIMARY KEY. *
80c0: 2f 0a 20 20 20 20 20 20 7a 50 72 61 67 6d 61 20  /.      zPragma 
80d0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
80e0: 66 28 0a 20 20 20 20 20 20 20 20 20 20 22 53 45  f(.          "SE
80f0: 4c 45 43 54 20 30 2c 20 27 74 62 6c 27 2c 20 20  LECT 0, 'tbl',  
8100: 27 27 2c 20 30 2c 20 27 27 2c 20 31 20 20 20 20  '', 0, '', 1    
8110: 20 55 4e 49 4f 4e 20 41 4c 4c 20 22 0a 20 20 20   UNION ALL ".   
8120: 20 20 20 20 20 20 20 22 53 45 4c 45 43 54 20 31         "SELECT 1
8130: 2c 20 27 69 64 78 27 2c 20 20 27 27 2c 20 30 2c  , 'idx',  '', 0,
8140: 20 27 27 2c 20 32 20 20 20 20 20 55 4e 49 4f 4e   '', 2     UNION
8150: 20 41 4c 4c 20 22 0a 20 20 20 20 20 20 20 20 20   ALL ".         
8160: 20 22 53 45 4c 45 43 54 20 32 2c 20 27 73 74 61   "SELECT 2, 'sta
8170: 74 27 2c 20 27 27 2c 20 30 2c 20 27 27 2c 20 30  t', '', 0, '', 0
8180: 22 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d  ".      );.    }
8190: 65 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51 4c  else if( rc==SQL
81a0: 49 54 45 5f 45 52 52 4f 52 20 29 7b 0a 20 20 20  ITE_ERROR ){.   
81b0: 20 20 20 7a 50 72 61 67 6d 61 20 3d 20 73 71 6c     zPragma = sql
81c0: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 22 29  ite3_mprintf("")
81d0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
81e0: 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
81f0: 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20    }.  }else{.   
8200: 20 7a 50 72 61 67 6d 61 20 3d 20 73 71 6c 69 74   zPragma = sqlit
8210: 65 33 5f 6d 70 72 69 6e 74 66 28 22 50 52 41 47  e3_mprintf("PRAG
8220: 4d 41 20 27 25 71 27 2e 74 61 62 6c 65 5f 69 6e  MA '%q'.table_in
8230: 66 6f 28 27 25 71 27 29 22 2c 20 7a 44 62 2c 20  fo('%q')", zDb, 
8240: 7a 54 68 69 73 29 3b 0a 20 20 7d 0a 20 20 69 66  zThis);.  }.  if
8250: 28 20 21 7a 50 72 61 67 6d 61 20 29 20 72 65 74  ( !zPragma ) ret
8260: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
8270: 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  ;..  rc = sqlite
8280: 33 5f 70 72 65 70 61 72 65 5f 76 32 28 64 62 2c  3_prepare_v2(db,
8290: 20 7a 50 72 61 67 6d 61 2c 20 2d 31 2c 20 26 70   zPragma, -1, &p
82a0: 53 74 6d 74 2c 20 30 29 3b 0a 20 20 73 71 6c 69  Stmt, 0);.  sqli
82b0: 74 65 33 5f 66 72 65 65 28 7a 50 72 61 67 6d 61  te3_free(zPragma
82c0: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
82d0: 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
82e0: 72 63 3b 0a 0a 20 20 6e 42 79 74 65 20 3d 20 6e  rc;..  nByte = n
82f0: 54 68 69 73 20 2b 20 31 3b 0a 20 20 77 68 69 6c  This + 1;.  whil
8300: 65 28 20 53 51 4c 49 54 45 5f 52 4f 57 3d 3d 73  e( SQLITE_ROW==s
8310: 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d  qlite3_step(pStm
8320: 74 29 20 29 7b 0a 20 20 20 20 6e 42 79 74 65 20  t) ){.    nByte 
8330: 2b 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  += sqlite3_colum
8340: 6e 5f 62 79 74 65 73 28 70 53 74 6d 74 2c 20 31  n_bytes(pStmt, 1
8350: 29 3b 0a 20 20 20 20 6e 44 62 43 6f 6c 2b 2b 3b  );.    nDbCol++;
8360: 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c 69  .  }.  rc = sqli
8370: 74 65 33 5f 72 65 73 65 74 28 70 53 74 6d 74 29  te3_reset(pStmt)
8380: 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  ;..  if( rc==SQL
8390: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 6e 42  ITE_OK ){.    nB
83a0: 79 74 65 20 2b 3d 20 6e 44 62 43 6f 6c 20 2a 20  yte += nDbCol * 
83b0: 28 73 69 7a 65 6f 66 28 63 6f 6e 73 74 20 63 68  (sizeof(const ch
83c0: 61 72 20 2a 29 20 2b 20 73 69 7a 65 6f 66 28 75  ar *) + sizeof(u
83d0: 38 29 20 2b 20 31 29 3b 0a 20 20 20 20 70 41 6c  8) + 1);.    pAl
83e0: 6c 6f 63 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61  loc = sqlite3_ma
83f0: 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20  lloc(nByte);.   
8400: 20 69 66 28 20 70 41 6c 6c 6f 63 3d 3d 30 20 29   if( pAlloc==0 )
8410: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
8420: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d  ITE_NOMEM;.    }
8430: 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53  .  }.  if( rc==S
8440: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
8450: 61 7a 43 6f 6c 20 3d 20 28 63 68 61 72 20 2a 2a  azCol = (char **
8460: 29 70 41 6c 6c 6f 63 3b 0a 20 20 20 20 70 41 6c  )pAlloc;.    pAl
8470: 6c 6f 63 20 3d 20 28 75 38 20 2a 29 26 61 7a 43  loc = (u8 *)&azC
8480: 6f 6c 5b 6e 44 62 43 6f 6c 5d 3b 0a 20 20 20 20  ol[nDbCol];.    
8490: 61 62 50 4b 20 3d 20 28 75 38 20 2a 29 70 41 6c  abPK = (u8 *)pAl
84a0: 6c 6f 63 3b 0a 20 20 20 20 70 41 6c 6c 6f 63 20  loc;.    pAlloc 
84b0: 3d 20 26 61 62 50 4b 5b 6e 44 62 43 6f 6c 5d 3b  = &abPK[nDbCol];
84c0: 0a 20 20 20 20 69 66 28 20 70 7a 54 61 62 20 29  .    if( pzTab )
84d0: 7b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28 70  {.      memcpy(p
84e0: 41 6c 6c 6f 63 2c 20 7a 54 68 69 73 2c 20 6e 54  Alloc, zThis, nT
84f0: 68 69 73 2b 31 29 3b 0a 20 20 20 20 20 20 2a 70  his+1);.      *p
8500: 7a 54 61 62 20 3d 20 28 63 68 61 72 20 2a 29 70  zTab = (char *)p
8510: 41 6c 6c 6f 63 3b 0a 20 20 20 20 20 20 70 41 6c  Alloc;.      pAl
8520: 6c 6f 63 20 2b 3d 20 6e 54 68 69 73 2b 31 3b 0a  loc += nThis+1;.
8530: 20 20 20 20 7d 0a 20 20 0a 20 20 20 20 69 20 3d      }.  .    i =
8540: 20 30 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 53   0;.    while( S
8550: 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74  QLITE_ROW==sqlit
8560: 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 20 29  e3_step(pStmt) )
8570: 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e 61 6d  {.      int nNam
8580: 65 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  e = sqlite3_colu
8590: 6d 6e 5f 62 79 74 65 73 28 70 53 74 6d 74 2c 20  mn_bytes(pStmt, 
85a0: 31 29 3b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20  1);.      const 
85b0: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 7a  unsigned char *z
85c0: 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 5f 63  Name = sqlite3_c
85d0: 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74  olumn_text(pStmt
85e0: 2c 20 31 29 3b 0a 20 20 20 20 20 20 69 66 28 20  , 1);.      if( 
85f0: 7a 4e 61 6d 65 3d 3d 30 20 29 20 62 72 65 61 6b  zName==0 ) break
8600: 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28 70  ;.      memcpy(p
8610: 41 6c 6c 6f 63 2c 20 7a 4e 61 6d 65 2c 20 6e 4e  Alloc, zName, nN
8620: 61 6d 65 2b 31 29 3b 0a 20 20 20 20 20 20 61 7a  ame+1);.      az
8630: 43 6f 6c 5b 69 5d 20 3d 20 28 63 68 61 72 20 2a  Col[i] = (char *
8640: 29 70 41 6c 6c 6f 63 3b 0a 20 20 20 20 20 20 70  )pAlloc;.      p
8650: 41 6c 6c 6f 63 20 2b 3d 20 6e 4e 61 6d 65 2b 31  Alloc += nName+1
8660: 3b 0a 20 20 20 20 20 20 61 62 50 4b 5b 69 5d 20  ;.      abPK[i] 
8670: 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
8680: 5f 69 6e 74 28 70 53 74 6d 74 2c 20 35 29 3b 0a  _int(pStmt, 5);.
8690: 20 20 20 20 20 20 69 2b 2b 3b 0a 20 20 20 20 7d        i++;.    }
86a0: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
86b0: 33 5f 72 65 73 65 74 28 70 53 74 6d 74 29 3b 0a  3_reset(pStmt);.
86c0: 20 20 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20    .  }..  /* If 
86d0: 73 75 63 63 65 73 73 66 75 6c 2c 20 70 6f 70 75  successful, popu
86e0: 6c 61 74 65 20 74 68 65 20 6f 75 74 70 75 74 20  late the output 
86f0: 76 61 72 69 61 62 6c 65 73 2e 20 4f 74 68 65 72  variables. Other
8700: 77 69 73 65 2c 20 7a 65 72 6f 20 74 68 65 6d 20  wise, zero them 
8710: 61 6e 64 0a 20 20 2a 2a 20 66 72 65 65 20 61 6e  and.  ** free an
8720: 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6d 61 64  y allocation mad
8730: 65 2e 20 41 6e 20 65 72 72 6f 72 20 63 6f 64 65  e. An error code
8740: 20 77 69 6c 6c 20 62 65 20 72 65 74 75 72 6e 65   will be returne
8750: 64 20 69 6e 20 74 68 69 73 20 63 61 73 65 2e 0a  d in this case..
8760: 20 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53    */.  if( rc==S
8770: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
8780: 2a 70 61 7a 43 6f 6c 20 3d 20 28 63 6f 6e 73 74  *pazCol = (const
8790: 20 63 68 61 72 20 2a 2a 29 61 7a 43 6f 6c 3b 0a   char **)azCol;.
87a0: 20 20 20 20 2a 70 61 62 50 4b 20 3d 20 61 62 50      *pabPK = abP
87b0: 4b 3b 0a 20 20 20 20 2a 70 6e 43 6f 6c 20 3d 20  K;.    *pnCol = 
87c0: 6e 44 62 43 6f 6c 3b 0a 20 20 7d 65 6c 73 65 7b  nDbCol;.  }else{
87d0: 0a 20 20 20 20 2a 70 61 7a 43 6f 6c 20 3d 20 30  .    *pazCol = 0
87e0: 3b 0a 20 20 20 20 2a 70 61 62 50 4b 20 3d 20 30  ;.    *pabPK = 0
87f0: 3b 0a 20 20 20 20 2a 70 6e 43 6f 6c 20 3d 20 30  ;.    *pnCol = 0
8800: 3b 0a 20 20 20 20 69 66 28 20 70 7a 54 61 62 20  ;.    if( pzTab 
8810: 29 20 2a 70 7a 54 61 62 20 3d 20 30 3b 0a 20 20  ) *pzTab = 0;.  
8820: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61    sqlite3_free(a
8830: 7a 43 6f 6c 29 3b 0a 20 20 7d 0a 20 20 73 71 6c  zCol);.  }.  sql
8840: 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53  ite3_finalize(pS
8850: 74 6d 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  tmt);.  return r
8860: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  c;.}../*.** This
8870: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 6f 6e 6c   function is onl
8880: 79 20 63 61 6c 6c 65 64 20 66 72 6f 6d 20 77 69  y called from wi
8890: 74 68 69 6e 20 61 20 70 72 65 2d 75 70 64 61 74  thin a pre-updat
88a0: 65 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 61 0a  e handler for a.
88b0: 2a 2a 20 77 72 69 74 65 20 74 6f 20 74 61 62 6c  ** write to tabl
88c0: 65 20 70 54 61 62 2c 20 70 61 72 74 20 6f 66 20  e pTab, part of 
88d0: 73 65 73 73 69 6f 6e 20 70 53 65 73 73 69 6f 6e  session pSession
88e0: 2e 20 49 66 20 74 68 69 73 20 69 73 20 74 68 65  . If this is the
88f0: 20 66 69 72 73 74 0a 2a 2a 20 77 72 69 74 65 20   first.** write 
8900: 74 6f 20 74 68 69 73 20 74 61 62 6c 65 2c 20 69  to this table, i
8910: 6e 69 74 61 6c 69 7a 65 20 74 68 65 20 53 65 73  nitalize the Ses
8920: 73 69 6f 6e 54 61 62 6c 65 2e 6e 43 6f 6c 2c 20  sionTable.nCol, 
8930: 61 7a 43 6f 6c 5b 5d 20 61 6e 64 0a 2a 2a 20 61  azCol[] and.** a
8940: 62 50 4b 5b 5d 20 61 72 72 61 79 73 20 61 63 63  bPK[] arrays acc
8950: 6f 72 64 69 6e 67 6c 79 2e 0a 2a 2a 0a 2a 2a 20  ordingly..**.** 
8960: 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  If an error occu
8970: 72 73 2c 20 61 6e 20 65 72 72 6f 72 20 63 6f 64  rs, an error cod
8980: 65 20 69 73 20 73 74 6f 72 65 64 20 69 6e 20 73  e is stored in s
8990: 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 2e 72  qlite3_session.r
89a0: 63 20 61 6e 64 0a 2a 2a 20 6e 6f 6e 2d 7a 65 72  c and.** non-zer
89b0: 6f 20 72 65 74 75 72 6e 65 64 2e 20 4f 72 2c 20  o returned. Or, 
89c0: 69 66 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75  if no error occu
89d0: 72 73 20 62 75 74 20 74 68 65 20 74 61 62 6c 65  rs but the table
89e0: 20 68 61 73 20 6e 6f 20 70 72 69 6d 61 72 79 0a   has no primary.
89f0: 2a 2a 20 6b 65 79 2c 20 73 71 6c 69 74 65 33 5f  ** key, sqlite3_
8a00: 73 65 73 73 69 6f 6e 2e 72 63 20 69 73 20 6c 65  session.rc is le
8a10: 66 74 20 73 65 74 20 74 6f 20 53 51 4c 49 54 45  ft set to SQLITE
8a20: 5f 4f 4b 20 61 6e 64 20 6e 6f 6e 2d 7a 65 72 6f  _OK and non-zero
8a30: 20 72 65 74 75 72 6e 65 64 20 74 6f 0a 2a 2a 20   returned to.** 
8a40: 69 6e 64 69 63 61 74 65 20 74 68 61 74 20 75 70  indicate that up
8a50: 64 61 74 65 73 20 6f 6e 20 74 68 69 73 20 74 61  dates on this ta
8a60: 62 6c 65 20 73 68 6f 75 6c 64 20 62 65 20 69 67  ble should be ig
8a70: 6e 6f 72 65 64 2e 20 53 65 73 73 69 6f 6e 54 61  nored. SessionTa
8a80: 62 6c 65 2e 61 62 50 4b 20 0a 2a 2a 20 69 73 20  ble.abPK .** is 
8a90: 73 65 74 20 74 6f 20 4e 55 4c 4c 20 69 6e 20 74  set to NULL in t
8aa0: 68 69 73 20 63 61 73 65 2e 0a 2a 2f 0a 73 74 61  his case..*/.sta
8ab0: 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 49  tic int sessionI
8ac0: 6e 69 74 54 61 62 6c 65 28 73 71 6c 69 74 65 33  nitTable(sqlite3
8ad0: 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69  _session *pSessi
8ae0: 6f 6e 2c 20 53 65 73 73 69 6f 6e 54 61 62 6c 65  on, SessionTable
8af0: 20 2a 70 54 61 62 29 7b 0a 20 20 69 66 28 20 70   *pTab){.  if( p
8b00: 54 61 62 2d 3e 6e 43 6f 6c 3d 3d 30 20 29 7b 0a  Tab->nCol==0 ){.
8b10: 20 20 20 20 75 38 20 2a 61 62 50 4b 3b 0a 20 20      u8 *abPK;.  
8b20: 20 20 61 73 73 65 72 74 28 20 70 54 61 62 2d 3e    assert( pTab->
8b30: 61 7a 43 6f 6c 3d 3d 30 20 7c 7c 20 70 54 61 62  azCol==0 || pTab
8b40: 2d 3e 61 62 50 4b 3d 3d 30 20 29 3b 0a 20 20 20  ->abPK==0 );.   
8b50: 20 70 53 65 73 73 69 6f 6e 2d 3e 72 63 20 3d 20   pSession->rc = 
8b60: 73 65 73 73 69 6f 6e 54 61 62 6c 65 49 6e 66 6f  sessionTableInfo
8b70: 28 70 53 65 73 73 69 6f 6e 2d 3e 64 62 2c 20 70  (pSession->db, p
8b80: 53 65 73 73 69 6f 6e 2d 3e 7a 44 62 2c 20 0a 20  Session->zDb, . 
8b90: 20 20 20 20 20 20 20 70 54 61 62 2d 3e 7a 4e 61         pTab->zNa
8ba0: 6d 65 2c 20 26 70 54 61 62 2d 3e 6e 43 6f 6c 2c  me, &pTab->nCol,
8bb0: 20 30 2c 20 26 70 54 61 62 2d 3e 61 7a 43 6f 6c   0, &pTab->azCol
8bc0: 2c 20 26 61 62 50 4b 0a 20 20 20 20 29 3b 0a 20  , &abPK.    );. 
8bd0: 20 20 20 69 66 28 20 70 53 65 73 73 69 6f 6e 2d     if( pSession-
8be0: 3e 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29  >rc==SQLITE_OK )
8bf0: 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20  {.      int i;. 
8c00: 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c       for(i=0; i<
8c10: 70 54 61 62 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29  pTab->nCol; i++)
8c20: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 61 62  {.        if( ab
8c30: 50 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20 20  PK[i] ){.       
8c40: 20 20 20 70 54 61 62 2d 3e 61 62 50 4b 20 3d 20     pTab->abPK = 
8c50: 61 62 50 4b 3b 0a 20 20 20 20 20 20 20 20 20 20  abPK;.          
8c60: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d  break;.        }
8c70: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69  .      }.      i
8c80: 66 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74  f( 0==sqlite3_st
8c90: 72 69 63 6d 70 28 22 73 71 6c 69 74 65 5f 73 74  ricmp("sqlite_st
8ca0: 61 74 31 22 2c 20 70 54 61 62 2d 3e 7a 4e 61 6d  at1", pTab->zNam
8cb0: 65 29 20 29 7b 0a 20 20 20 20 20 20 20 20 70 54  e) ){.        pT
8cc0: 61 62 2d 3e 62 53 74 61 74 31 20 3d 20 31 3b 0a  ab->bStat1 = 1;.
8cd0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
8ce0: 7d 0a 20 20 72 65 74 75 72 6e 20 28 70 53 65 73  }.  return (pSes
8cf0: 73 69 6f 6e 2d 3e 72 63 20 7c 7c 20 70 54 61 62  sion->rc || pTab
8d00: 2d 3e 61 62 50 4b 3d 3d 30 29 3b 0a 7d 0a 0a 2f  ->abPK==0);.}../
8d10: 2a 0a 2a 2a 20 56 65 72 73 69 6f 6e 73 20 6f 66  *.** Versions of
8d20: 20 74 68 65 20 66 6f 75 72 20 6d 65 74 68 6f 64   the four method
8d30: 73 20 69 6e 20 6f 62 6a 65 63 74 20 53 65 73 73  s in object Sess
8d40: 69 6f 6e 48 6f 6f 6b 20 66 6f 72 20 75 73 65 20  ionHook for use 
8d50: 77 69 74 68 20 74 68 65 0a 2a 2a 20 73 71 6c 69  with the.** sqli
8d60: 74 65 5f 73 74 61 74 31 20 74 61 62 6c 65 2e 20  te_stat1 table. 
8d70: 54 68 65 20 70 75 72 70 6f 73 65 20 6f 66 20 74  The purpose of t
8d80: 68 69 73 20 69 73 20 74 6f 20 73 75 62 73 74 69  his is to substi
8d90: 74 75 74 65 20 61 20 7a 65 72 6f 2d 6c 65 6e 67  tute a zero-leng
8da0: 74 68 0a 2a 2a 20 62 6c 6f 62 20 65 61 63 68 20  th.** blob each 
8db0: 74 69 6d 65 20 61 20 4e 55 4c 4c 20 76 61 6c 75  time a NULL valu
8dc0: 65 20 69 73 20 72 65 61 64 20 66 72 6f 6d 20 74  e is read from t
8dd0: 68 65 20 22 69 64 78 22 20 63 6f 6c 75 6d 6e 20  he "idx" column 
8de0: 6f 66 20 74 68 65 0a 2a 2a 20 73 71 6c 69 74 65  of the.** sqlite
8df0: 5f 73 74 61 74 31 20 74 61 62 6c 65 2e 0a 2a 2f  _stat1 table..*/
8e00: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
8e10: 53 65 73 73 69 6f 6e 53 74 61 74 31 43 74 78 20  SessionStat1Ctx 
8e20: 53 65 73 73 69 6f 6e 53 74 61 74 31 43 74 78 3b  SessionStat1Ctx;
8e30: 0a 73 74 72 75 63 74 20 53 65 73 73 69 6f 6e 53  .struct SessionS
8e40: 74 61 74 31 43 74 78 20 7b 0a 20 20 53 65 73 73  tat1Ctx {.  Sess
8e50: 69 6f 6e 48 6f 6f 6b 20 68 6f 6f 6b 3b 0a 20 20  ionHook hook;.  
8e60: 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20  sqlite3_session 
8e70: 2a 70 53 65 73 73 69 6f 6e 3b 0a 7d 3b 0a 73 74  *pSession;.};.st
8e80: 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e  atic int session
8e90: 53 74 61 74 31 4f 6c 64 28 76 6f 69 64 20 2a 70  Stat1Old(void *p
8ea0: 43 74 78 2c 20 69 6e 74 20 69 43 6f 6c 2c 20 73  Ctx, int iCol, s
8eb0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 70  qlite3_value **p
8ec0: 70 56 61 6c 29 7b 0a 20 20 53 65 73 73 69 6f 6e  pVal){.  Session
8ed0: 53 74 61 74 31 43 74 78 20 2a 70 20 3d 20 28 53  Stat1Ctx *p = (S
8ee0: 65 73 73 69 6f 6e 53 74 61 74 31 43 74 78 2a 29  essionStat1Ctx*)
8ef0: 70 43 74 78 3b 0a 20 20 73 71 6c 69 74 65 33 5f  pCtx;.  sqlite3_
8f00: 76 61 6c 75 65 20 2a 70 56 61 6c 20 3d 20 30 3b  value *pVal = 0;
8f10: 0a 20 20 69 6e 74 20 72 63 20 3d 20 70 2d 3e 68  .  int rc = p->h
8f20: 6f 6f 6b 2e 78 4f 6c 64 28 70 2d 3e 68 6f 6f 6b  ook.xOld(p->hook
8f30: 2e 70 43 74 78 2c 20 69 43 6f 6c 2c 20 26 70 56  .pCtx, iCol, &pV
8f40: 61 6c 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  al);.  if( rc==S
8f50: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 43 6f 6c  QLITE_OK && iCol
8f60: 3d 3d 31 20 26 26 20 73 71 6c 69 74 65 33 5f 76  ==1 && sqlite3_v
8f70: 61 6c 75 65 5f 74 79 70 65 28 70 56 61 6c 29 3d  alue_type(pVal)=
8f80: 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29 7b 0a  =SQLITE_NULL ){.
8f90: 20 20 20 20 70 56 61 6c 20 3d 20 70 2d 3e 70 53      pVal = p->pS
8fa0: 65 73 73 69 6f 6e 2d 3e 70 5a 65 72 6f 42 6c 6f  ession->pZeroBlo
8fb0: 62 3b 0a 20 20 7d 0a 20 20 2a 70 70 56 61 6c 20  b;.  }.  *ppVal 
8fc0: 3d 20 70 56 61 6c 3b 0a 20 20 72 65 74 75 72 6e  = pVal;.  return
8fd0: 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e   rc;.}.static in
8fe0: 74 20 73 65 73 73 69 6f 6e 53 74 61 74 31 4e 65  t sessionStat1Ne
8ff0: 77 28 76 6f 69 64 20 2a 70 43 74 78 2c 20 69 6e  w(void *pCtx, in
9000: 74 20 69 43 6f 6c 2c 20 73 71 6c 69 74 65 33 5f  t iCol, sqlite3_
9010: 76 61 6c 75 65 20 2a 2a 70 70 56 61 6c 29 7b 0a  value **ppVal){.
9020: 20 20 53 65 73 73 69 6f 6e 53 74 61 74 31 43 74    SessionStat1Ct
9030: 78 20 2a 70 20 3d 20 28 53 65 73 73 69 6f 6e 53  x *p = (SessionS
9040: 74 61 74 31 43 74 78 2a 29 70 43 74 78 3b 0a 20  tat1Ctx*)pCtx;. 
9050: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
9060: 70 56 61 6c 20 3d 20 30 3b 0a 20 20 69 6e 74 20  pVal = 0;.  int 
9070: 72 63 20 3d 20 70 2d 3e 68 6f 6f 6b 2e 78 4e 65  rc = p->hook.xNe
9080: 77 28 70 2d 3e 68 6f 6f 6b 2e 70 43 74 78 2c 20  w(p->hook.pCtx, 
9090: 69 43 6f 6c 2c 20 26 70 56 61 6c 29 3b 0a 20 20  iCol, &pVal);.  
90a0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
90b0: 4b 20 26 26 20 69 43 6f 6c 3d 3d 31 20 26 26 20  K && iCol==1 && 
90c0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79  sqlite3_value_ty
90d0: 70 65 28 70 56 61 6c 29 3d 3d 53 51 4c 49 54 45  pe(pVal)==SQLITE
90e0: 5f 4e 55 4c 4c 20 29 7b 0a 20 20 20 20 70 56 61  _NULL ){.    pVa
90f0: 6c 20 3d 20 70 2d 3e 70 53 65 73 73 69 6f 6e 2d  l = p->pSession-
9100: 3e 70 5a 65 72 6f 42 6c 6f 62 3b 0a 20 20 7d 0a  >pZeroBlob;.  }.
9110: 20 20 2a 70 70 56 61 6c 20 3d 20 70 56 61 6c 3b    *ppVal = pVal;
9120: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
9130: 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69  static int sessi
9140: 6f 6e 53 74 61 74 31 43 6f 75 6e 74 28 76 6f 69  onStat1Count(voi
9150: 64 20 2a 70 43 74 78 29 7b 0a 20 20 53 65 73 73  d *pCtx){.  Sess
9160: 69 6f 6e 53 74 61 74 31 43 74 78 20 2a 70 20 3d  ionStat1Ctx *p =
9170: 20 28 53 65 73 73 69 6f 6e 53 74 61 74 31 43 74   (SessionStat1Ct
9180: 78 2a 29 70 43 74 78 3b 0a 20 20 72 65 74 75 72  x*)pCtx;.  retur
9190: 6e 20 70 2d 3e 68 6f 6f 6b 2e 78 43 6f 75 6e 74  n p->hook.xCount
91a0: 28 70 2d 3e 68 6f 6f 6b 2e 70 43 74 78 29 3b 0a  (p->hook.pCtx);.
91b0: 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73  }.static int ses
91c0: 73 69 6f 6e 53 74 61 74 31 44 65 70 74 68 28 76  sionStat1Depth(v
91d0: 6f 69 64 20 2a 70 43 74 78 29 7b 0a 20 20 53 65  oid *pCtx){.  Se
91e0: 73 73 69 6f 6e 53 74 61 74 31 43 74 78 20 2a 70  ssionStat1Ctx *p
91f0: 20 3d 20 28 53 65 73 73 69 6f 6e 53 74 61 74 31   = (SessionStat1
9200: 43 74 78 2a 29 70 43 74 78 3b 0a 20 20 72 65 74  Ctx*)pCtx;.  ret
9210: 75 72 6e 20 70 2d 3e 68 6f 6f 6b 2e 78 44 65 70  urn p->hook.xDep
9220: 74 68 28 70 2d 3e 68 6f 6f 6b 2e 70 43 74 78 29  th(p->hook.pCtx)
9230: 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  ;.}.../*.** This
9240: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 6f 6e 6c   function is onl
9250: 79 20 63 61 6c 6c 65 64 20 66 72 6f 6d 20 77 69  y called from wi
9260: 74 68 20 61 20 70 72 65 2d 75 70 64 61 74 65 2d  th a pre-update-
9270: 68 6f 6f 6b 20 72 65 70 6f 72 74 69 6e 67 20 61  hook reporting a
9280: 20 0a 2a 2a 20 63 68 61 6e 67 65 20 6f 6e 20 74   .** change on t
9290: 61 62 6c 65 20 70 54 61 62 20 28 61 74 74 61 63  able pTab (attac
92a0: 68 65 64 20 74 6f 20 73 65 73 73 69 6f 6e 20 70  hed to session p
92b0: 53 65 73 73 69 6f 6e 29 2e 20 54 68 65 20 74 79  Session). The ty
92c0: 70 65 20 6f 66 20 63 68 61 6e 67 65 0a 2a 2a 20  pe of change.** 
92d0: 28 55 50 44 41 54 45 2c 20 49 4e 53 45 52 54 2c  (UPDATE, INSERT,
92e0: 20 44 45 4c 45 54 45 29 20 69 73 20 73 70 65 63   DELETE) is spec
92f0: 69 66 69 65 64 20 62 79 20 74 68 65 20 66 69 72  ified by the fir
9300: 73 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a  st argument..**.
9310: 2a 2a 20 55 6e 6c 65 73 73 20 6f 6e 65 20 69 73  ** Unless one is
9320: 20 61 6c 72 65 61 64 79 20 70 72 65 73 65 6e 74   already present
9330: 20 6f 72 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   or an error occ
9340: 75 72 73 2c 20 61 6e 20 65 6e 74 72 79 20 69 73  urs, an entry is
9350: 20 61 64 64 65 64 0a 2a 2a 20 74 6f 20 74 68 65   added.** to the
9360: 20 63 68 61 6e 67 65 64 2d 72 6f 77 73 20 68 61   changed-rows ha
9370: 73 68 20 74 61 62 6c 65 20 61 73 73 6f 63 69 61  sh table associa
9380: 74 65 64 20 77 69 74 68 20 74 61 62 6c 65 20 70  ted with table p
9390: 54 61 62 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  Tab..*/.static v
93a0: 6f 69 64 20 73 65 73 73 69 6f 6e 50 72 65 75 70  oid sessionPreup
93b0: 64 61 74 65 4f 6e 65 43 68 61 6e 67 65 28 0a 20  dateOneChange(. 
93c0: 20 69 6e 74 20 6f 70 2c 20 20 20 20 20 20 20 20   int op,        
93d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
93e0: 20 2f 2a 20 4f 6e 65 20 6f 66 20 53 51 4c 49 54   /* One of SQLIT
93f0: 45 5f 55 50 44 41 54 45 2c 20 49 4e 53 45 52 54  E_UPDATE, INSERT
9400: 2c 20 44 45 4c 45 54 45 20 2a 2f 0a 20 20 73 71  , DELETE */.  sq
9410: 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70  lite3_session *p
9420: 53 65 73 73 69 6f 6e 2c 20 20 20 20 20 20 2f 2a  Session,      /*
9430: 20 53 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20   Session object 
9440: 70 54 61 62 20 69 73 20 61 74 74 61 63 68 65 64  pTab is attached
9450: 20 74 6f 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e   to */.  Session
9460: 54 61 62 6c 65 20 2a 70 54 61 62 20 20 20 20 20  Table *pTab     
9470: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62 6c           /* Tabl
9480: 65 20 74 68 61 74 20 63 68 61 6e 67 65 20 61 70  e that change ap
9490: 70 6c 69 65 73 20 74 6f 20 2a 2f 0a 29 7b 0a 20  plies to */.){. 
94a0: 20 69 6e 74 20 69 48 61 73 68 3b 20 0a 20 20 69   int iHash; .  i
94b0: 6e 74 20 62 4e 75 6c 6c 20 3d 20 30 3b 20 0a 20  nt bNull = 0; . 
94c0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
94d0: 5f 4f 4b 3b 0a 20 20 53 65 73 73 69 6f 6e 53 74  _OK;.  SessionSt
94e0: 61 74 31 43 74 78 20 73 74 61 74 31 20 3d 20 7b  at1Ctx stat1 = {
94f0: 30 7d 3b 0a 0a 20 20 69 66 28 20 70 53 65 73 73  0};..  if( pSess
9500: 69 6f 6e 2d 3e 72 63 20 29 20 72 65 74 75 72 6e  ion->rc ) return
9510: 3b 0a 0a 20 20 2f 2a 20 4c 6f 61 64 20 74 61 62  ;..  /* Load tab
9520: 6c 65 20 64 65 74 61 69 6c 73 20 69 66 20 72 65  le details if re
9530: 71 75 69 72 65 64 20 2a 2f 0a 20 20 69 66 28 20  quired */.  if( 
9540: 73 65 73 73 69 6f 6e 49 6e 69 74 54 61 62 6c 65  sessionInitTable
9550: 28 70 53 65 73 73 69 6f 6e 2c 20 70 54 61 62 29  (pSession, pTab)
9560: 20 29 20 72 65 74 75 72 6e 3b 0a 0a 20 20 2f 2a   ) return;..  /*
9570: 20 43 68 65 63 6b 20 74 68 65 20 6e 75 6d 62 65   Check the numbe
9580: 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20  r of columns in 
9590: 74 68 69 73 20 78 50 72 65 55 70 64 61 74 65 20  this xPreUpdate 
95a0: 63 61 6c 6c 20 6d 61 74 63 68 65 73 20 74 68 65  call matches the
95b0: 20 0a 20 20 2a 2a 20 6e 75 6d 62 65 72 20 6f 66   .  ** number of
95c0: 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 68 65 20   columns in the 
95d0: 74 61 62 6c 65 2e 20 20 2a 2f 0a 20 20 69 66 28  table.  */.  if(
95e0: 20 70 54 61 62 2d 3e 6e 43 6f 6c 21 3d 70 53 65   pTab->nCol!=pSe
95f0: 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 43 6f 75  ssion->hook.xCou
9600: 6e 74 28 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f  nt(pSession->hoo
9610: 6b 2e 70 43 74 78 29 20 29 7b 0a 20 20 20 20 70  k.pCtx) ){.    p
9620: 53 65 73 73 69 6f 6e 2d 3e 72 63 20 3d 20 53 51  Session->rc = SQ
9630: 4c 49 54 45 5f 53 43 48 45 4d 41 3b 0a 20 20 20  LITE_SCHEMA;.   
9640: 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 0a 20 20   return;.  }..  
9650: 2f 2a 20 47 72 6f 77 20 74 68 65 20 68 61 73 68  /* Grow the hash
9660: 20 74 61 62 6c 65 20 69 66 20 72 65 71 75 69 72   table if requir
9670: 65 64 20 2a 2f 0a 20 20 69 66 28 20 73 65 73 73  ed */.  if( sess
9680: 69 6f 6e 47 72 6f 77 48 61 73 68 28 30 2c 20 70  ionGrowHash(0, p
9690: 54 61 62 29 20 29 7b 0a 20 20 20 20 70 53 65 73  Tab) ){.    pSes
96a0: 73 69 6f 6e 2d 3e 72 63 20 3d 20 53 51 4c 49 54  sion->rc = SQLIT
96b0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 72 65 74  E_NOMEM;.    ret
96c0: 75 72 6e 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  urn;.  }..  if( 
96d0: 70 54 61 62 2d 3e 62 53 74 61 74 31 20 29 7b 0a  pTab->bStat1 ){.
96e0: 20 20 20 20 73 74 61 74 31 2e 68 6f 6f 6b 20 3d      stat1.hook =
96f0: 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 3b   pSession->hook;
9700: 0a 20 20 20 20 73 74 61 74 31 2e 70 53 65 73 73  .    stat1.pSess
9710: 69 6f 6e 20 3d 20 70 53 65 73 73 69 6f 6e 3b 0a  ion = pSession;.
9720: 20 20 20 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f      pSession->ho
9730: 6f 6b 2e 70 43 74 78 20 3d 20 28 76 6f 69 64 2a  ok.pCtx = (void*
9740: 29 26 73 74 61 74 31 3b 0a 20 20 20 20 70 53 65  )&stat1;.    pSe
9750: 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 4e 65 77  ssion->hook.xNew
9760: 20 3d 20 73 65 73 73 69 6f 6e 53 74 61 74 31 4e   = sessionStat1N
9770: 65 77 3b 0a 20 20 20 20 70 53 65 73 73 69 6f 6e  ew;.    pSession
9780: 2d 3e 68 6f 6f 6b 2e 78 4f 6c 64 20 3d 20 73 65  ->hook.xOld = se
9790: 73 73 69 6f 6e 53 74 61 74 31 4f 6c 64 3b 0a 20  ssionStat1Old;. 
97a0: 20 20 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f     pSession->hoo
97b0: 6b 2e 78 43 6f 75 6e 74 20 3d 20 73 65 73 73 69  k.xCount = sessi
97c0: 6f 6e 53 74 61 74 31 43 6f 75 6e 74 3b 0a 20 20  onStat1Count;.  
97d0: 20 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b    pSession->hook
97e0: 2e 78 44 65 70 74 68 20 3d 20 73 65 73 73 69 6f  .xDepth = sessio
97f0: 6e 53 74 61 74 31 44 65 70 74 68 3b 0a 20 20 20  nStat1Depth;.   
9800: 20 69 66 28 20 70 53 65 73 73 69 6f 6e 2d 3e 70   if( pSession->p
9810: 5a 65 72 6f 42 6c 6f 62 3d 3d 30 20 29 7b 0a 20  ZeroBlob==0 ){. 
9820: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c       sqlite3_val
9830: 75 65 20 2a 70 20 3d 20 73 71 6c 69 74 65 33 56  ue *p = sqlite3V
9840: 61 6c 75 65 4e 65 77 28 30 29 3b 0a 20 20 20 20  alueNew(0);.    
9850: 20 20 69 66 28 20 70 3d 3d 30 20 29 7b 0a 20 20    if( p==0 ){.  
9860: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
9870: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 20  E_NOMEM;.       
9880: 20 67 6f 74 6f 20 65 72 72 6f 72 5f 6f 75 74 3b   goto error_out;
9890: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73  .      }.      s
98a0: 71 6c 69 74 65 33 56 61 6c 75 65 53 65 74 53 74  qlite3ValueSetSt
98b0: 72 28 70 2c 20 30 2c 20 22 22 2c 20 30 2c 20 53  r(p, 0, "", 0, S
98c0: 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a 20  QLITE_STATIC);. 
98d0: 20 20 20 20 20 70 53 65 73 73 69 6f 6e 2d 3e 70       pSession->p
98e0: 5a 65 72 6f 42 6c 6f 62 20 3d 20 70 3b 0a 20 20  ZeroBlob = p;.  
98f0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 61    }.  }..  /* Ca
9900: 6c 63 75 6c 61 74 65 20 74 68 65 20 68 61 73 68  lculate the hash
9910: 2d 6b 65 79 20 66 6f 72 20 74 68 69 73 20 63 68  -key for this ch
9920: 61 6e 67 65 2e 20 49 66 20 74 68 65 20 70 72 69  ange. If the pri
9930: 6d 61 72 79 20 6b 65 79 20 6f 66 20 74 68 65 20  mary key of the 
9940: 72 6f 77 0a 20 20 2a 2a 20 69 6e 63 6c 75 64 65  row.  ** include
9950: 73 20 61 20 4e 55 4c 4c 20 76 61 6c 75 65 2c 20  s a NULL value, 
9960: 65 78 69 74 20 65 61 72 6c 79 2e 20 53 75 63 68  exit early. Such
9970: 20 63 68 61 6e 67 65 73 20 61 72 65 20 69 67 6e   changes are ign
9980: 6f 72 65 64 20 62 79 20 74 68 65 0a 20 20 2a 2a  ored by the.  **
9990: 20 73 65 73 73 69 6f 6e 20 6d 6f 64 75 6c 65 2e   session module.
99a0: 20 2a 2f 0a 20 20 72 63 20 3d 20 73 65 73 73 69   */.  rc = sessi
99b0: 6f 6e 50 72 65 75 70 64 61 74 65 48 61 73 68 28  onPreupdateHash(
99c0: 70 53 65 73 73 69 6f 6e 2c 20 70 54 61 62 2c 20  pSession, pTab, 
99d0: 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52  op==SQLITE_INSER
99e0: 54 2c 20 26 69 48 61 73 68 2c 20 26 62 4e 75 6c  T, &iHash, &bNul
99f0: 6c 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  l);.  if( rc!=SQ
9a00: 4c 49 54 45 5f 4f 4b 20 29 20 67 6f 74 6f 20 65  LITE_OK ) goto e
9a10: 72 72 6f 72 5f 6f 75 74 3b 0a 0a 20 20 69 66 28  rror_out;..  if(
9a20: 20 62 4e 75 6c 6c 3d 3d 30 20 29 7b 0a 20 20 20   bNull==0 ){.   
9a30: 20 2f 2a 20 53 65 61 72 63 68 20 74 68 65 20 68   /* Search the h
9a40: 61 73 68 20 74 61 62 6c 65 20 66 6f 72 20 61 6e  ash table for an
9a50: 20 65 78 69 73 74 69 6e 67 20 72 65 63 6f 72 64   existing record
9a60: 20 66 6f 72 20 74 68 69 73 20 72 6f 77 2e 20 2a   for this row. *
9a70: 2f 0a 20 20 20 20 53 65 73 73 69 6f 6e 43 68 61  /.    SessionCha
9a80: 6e 67 65 20 2a 70 43 3b 0a 20 20 20 20 66 6f 72  nge *pC;.    for
9a90: 28 70 43 3d 70 54 61 62 2d 3e 61 70 43 68 61 6e  (pC=pTab->apChan
9aa0: 67 65 5b 69 48 61 73 68 5d 3b 20 70 43 3b 20 70  ge[iHash]; pC; p
9ab0: 43 3d 70 43 2d 3e 70 4e 65 78 74 29 7b 0a 20 20  C=pC->pNext){.  
9ac0: 20 20 20 20 69 66 28 20 73 65 73 73 69 6f 6e 50      if( sessionP
9ad0: 72 65 75 70 64 61 74 65 45 71 75 61 6c 28 70 53  reupdateEqual(pS
9ae0: 65 73 73 69 6f 6e 2c 20 70 54 61 62 2c 20 70 43  ession, pTab, pC
9af0: 2c 20 6f 70 29 20 29 20 62 72 65 61 6b 3b 0a 20  , op) ) break;. 
9b00: 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 70 43     }..    if( pC
9b10: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  ==0 ){.      /* 
9b20: 43 72 65 61 74 65 20 61 20 6e 65 77 20 63 68 61  Create a new cha
9b30: 6e 67 65 20 6f 62 6a 65 63 74 20 63 6f 6e 74 61  nge object conta
9b40: 69 6e 69 6e 67 20 61 6c 6c 20 74 68 65 20 6f 6c  ining all the ol
9b50: 64 20 76 61 6c 75 65 73 20 28 69 66 0a 20 20 20  d values (if.   
9b60: 20 20 20 2a 2a 20 74 68 69 73 20 69 73 20 61 6e     ** this is an
9b70: 20 53 51 4c 49 54 45 5f 55 50 44 41 54 45 20 6f   SQLITE_UPDATE o
9b80: 72 20 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 29  r SQLITE_DELETE)
9b90: 2c 20 6f 72 20 6a 75 73 74 20 74 68 65 20 50 4b  , or just the PK
9ba0: 0a 20 20 20 20 20 20 2a 2a 20 76 61 6c 75 65 73  .      ** values
9bb0: 20 28 69 66 20 74 68 69 73 20 69 73 20 61 6e 20   (if this is an 
9bc0: 49 4e 53 45 52 54 29 2e 20 2a 2f 0a 20 20 20 20  INSERT). */.    
9bd0: 20 20 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20    SessionChange 
9be0: 2a 70 43 68 61 6e 67 65 3b 20 2f 2a 20 4e 65 77  *pChange; /* New
9bf0: 20 63 68 61 6e 67 65 20 6f 62 6a 65 63 74 20 2a   change object *
9c00: 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74  /.      int nByt
9c10: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
9c20: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74  /* Number of byt
9c30: 65 73 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a  es to allocate *
9c40: 2f 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 20 20  /.      int i;  
9c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9c60: 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72 61  /* Used to itera
9c70: 74 65 20 74 68 72 6f 75 67 68 20 63 6f 6c 75 6d  te through colum
9c80: 6e 73 20 2a 2f 0a 20 20 0a 20 20 20 20 20 20 61  ns */.  .      a
9c90: 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54  ssert( rc==SQLIT
9ca0: 45 5f 4f 4b 20 29 3b 0a 20 20 20 20 20 20 70 54  E_OK );.      pT
9cb0: 61 62 2d 3e 6e 45 6e 74 72 79 2b 2b 3b 0a 20 20  ab->nEntry++;.  
9cc0: 0a 20 20 20 20 20 20 2f 2a 20 46 69 67 75 72 65  .      /* Figure
9cd0: 20 6f 75 74 20 68 6f 77 20 6c 61 72 67 65 20 61   out how large a
9ce0: 6e 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 73 20  n allocation is 
9cf0: 72 65 71 75 69 72 65 64 20 2a 2f 0a 20 20 20 20  required */.    
9d00: 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66    nByte = sizeof
9d10: 28 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 29 3b  (SessionChange);
9d20: 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  .      for(i=0; 
9d30: 69 3c 70 54 61 62 2d 3e 6e 43 6f 6c 3b 20 69 2b  i<pTab->nCol; i+
9d40: 2b 29 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69  +){.        sqli
9d50: 74 65 33 5f 76 61 6c 75 65 20 2a 70 20 3d 20 30  te3_value *p = 0
9d60: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 6f 70  ;.        if( op
9d70: 21 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 20  !=SQLITE_INSERT 
9d80: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 54 45 53  ){.          TES
9d90: 54 4f 4e 4c 59 28 69 6e 74 20 74 72 63 20 3d 20  TONLY(int trc = 
9da0: 29 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b  ) pSession->hook
9db0: 2e 78 4f 6c 64 28 70 53 65 73 73 69 6f 6e 2d 3e  .xOld(pSession->
9dc0: 68 6f 6f 6b 2e 70 43 74 78 2c 20 69 2c 20 26 70  hook.pCtx, i, &p
9dd0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 61 73 73  );.          ass
9de0: 65 72 74 28 20 74 72 63 3d 3d 53 51 4c 49 54 45  ert( trc==SQLITE
9df0: 5f 4f 4b 20 29 3b 0a 20 20 20 20 20 20 20 20 7d  _OK );.        }
9e00: 65 6c 73 65 20 69 66 28 20 70 54 61 62 2d 3e 61  else if( pTab->a
9e10: 62 50 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20  bPK[i] ){.      
9e20: 20 20 20 20 54 45 53 54 4f 4e 4c 59 28 69 6e 74      TESTONLY(int
9e30: 20 74 72 63 20 3d 20 29 20 70 53 65 73 73 69 6f   trc = ) pSessio
9e40: 6e 2d 3e 68 6f 6f 6b 2e 78 4e 65 77 28 70 53 65  n->hook.xNew(pSe
9e50: 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 70 43 74 78  ssion->hook.pCtx
9e60: 2c 20 69 2c 20 26 70 29 3b 0a 20 20 20 20 20 20  , i, &p);.      
9e70: 20 20 20 20 61 73 73 65 72 74 28 20 74 72 63 3d      assert( trc=
9e80: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20  =SQLITE_OK );.  
9e90: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20        }..       
9ea0: 20 2f 2a 20 54 68 69 73 20 6d 61 79 20 66 61 69   /* This may fai
9eb0: 6c 20 69 66 20 53 51 4c 69 74 65 20 76 61 6c 75  l if SQLite valu
9ec0: 65 20 70 20 63 6f 6e 74 61 69 6e 73 20 61 20 75  e p contains a u
9ed0: 74 66 2d 31 36 20 73 74 72 69 6e 67 20 74 68 61  tf-16 string tha
9ee0: 74 20 6d 75 73 74 0a 20 20 20 20 20 20 20 20 2a  t must.        *
9ef0: 2a 20 62 65 20 63 6f 6e 76 65 72 74 65 64 20 74  * be converted t
9f00: 6f 20 75 74 66 2d 38 20 61 6e 64 20 61 6e 20 4f  o utf-8 and an O
9f10: 4f 4d 20 65 72 72 6f 72 20 6f 63 63 75 72 73 20  OM error occurs 
9f20: 77 68 69 6c 65 20 64 6f 69 6e 67 20 73 6f 2e 20  while doing so. 
9f30: 2a 2f 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  */.        rc = 
9f40: 73 65 73 73 69 6f 6e 53 65 72 69 61 6c 69 7a 65  sessionSerialize
9f50: 56 61 6c 75 65 28 30 2c 20 70 2c 20 26 6e 42 79  Value(0, p, &nBy
9f60: 74 65 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  te);.        if(
9f70: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
9f80: 20 67 6f 74 6f 20 65 72 72 6f 72 5f 6f 75 74 3b   goto error_out;
9f90: 0a 20 20 20 20 20 20 7d 0a 20 20 0a 20 20 20 20  .      }.  .    
9fa0: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74 68    /* Allocate th
9fb0: 65 20 63 68 61 6e 67 65 20 6f 62 6a 65 63 74 20  e change object 
9fc0: 2a 2f 0a 20 20 20 20 20 20 70 43 68 61 6e 67 65  */.      pChange
9fd0: 20 3d 20 28 53 65 73 73 69 6f 6e 43 68 61 6e 67   = (SessionChang
9fe0: 65 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  e *)sqlite3_mall
9ff0: 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20 20  oc(nByte);.     
a000: 20 69 66 28 20 21 70 43 68 61 6e 67 65 20 29 7b   if( !pChange ){
a010: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51  .        rc = SQ
a020: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
a030: 20 20 20 20 67 6f 74 6f 20 65 72 72 6f 72 5f 6f      goto error_o
a040: 75 74 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  ut;.      }else{
a050: 0a 20 20 20 20 20 20 20 20 6d 65 6d 73 65 74 28  .        memset(
a060: 70 43 68 61 6e 67 65 2c 20 30 2c 20 73 69 7a 65  pChange, 0, size
a070: 6f 66 28 53 65 73 73 69 6f 6e 43 68 61 6e 67 65  of(SessionChange
a080: 29 29 3b 0a 20 20 20 20 20 20 20 20 70 43 68 61  ));.        pCha
a090: 6e 67 65 2d 3e 61 52 65 63 6f 72 64 20 3d 20 28  nge->aRecord = (
a0a0: 75 38 20 2a 29 26 70 43 68 61 6e 67 65 5b 31 5d  u8 *)&pChange[1]
a0b0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 0a 20 20 20  ;.      }.  .   
a0c0: 20 20 20 2f 2a 20 50 6f 70 75 6c 61 74 65 20 74     /* Populate t
a0d0: 68 65 20 63 68 61 6e 67 65 20 6f 62 6a 65 63 74  he change object
a0e0: 2e 20 4e 6f 6e 65 20 6f 66 20 74 68 65 20 70 72  . None of the pr
a0f0: 65 75 70 64 61 74 65 5f 6f 6c 64 28 29 2c 0a 20  eupdate_old(),. 
a100: 20 20 20 20 20 2a 2a 20 70 72 65 75 70 64 61 74       ** preupdat
a110: 65 5f 6e 65 77 28 29 20 6f 72 20 53 65 72 69 61  e_new() or Seria
a120: 6c 69 7a 65 56 61 6c 75 65 28 29 20 63 61 6c 6c  lizeValue() call
a130: 73 20 62 65 6c 6f 77 20 6d 61 79 20 66 61 69 6c  s below may fail
a140: 20 61 73 20 61 6c 6c 0a 20 20 20 20 20 20 2a 2a   as all.      **
a150: 20 72 65 71 75 69 72 65 64 20 76 61 6c 75 65 73   required values
a160: 20 61 6e 64 20 65 6e 63 6f 64 69 6e 67 73 20 68   and encodings h
a170: 61 76 65 20 61 6c 72 65 61 64 79 20 62 65 65 6e  ave already been
a180: 20 63 61 63 68 65 64 20 69 6e 20 6d 65 6d 6f 72   cached in memor
a190: 79 2e 0a 20 20 20 20 20 20 2a 2a 20 49 74 20 69  y..      ** It i
a1a0: 73 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65 20 66  s not possible f
a1b0: 6f 72 20 61 6e 20 4f 4f 4d 20 74 6f 20 6f 63 63  or an OOM to occ
a1c0: 75 72 20 69 6e 20 74 68 69 73 20 62 6c 6f 63 6b  ur in this block
a1d0: 2e 20 2a 2f 0a 20 20 20 20 20 20 6e 42 79 74 65  . */.      nByte
a1e0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 66 6f 72 28   = 0;.      for(
a1f0: 69 3d 30 3b 20 69 3c 70 54 61 62 2d 3e 6e 43 6f  i=0; i<pTab->nCo
a200: 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20  l; i++){.       
a210: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
a220: 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 69  p = 0;.        i
a230: 66 28 20 6f 70 21 3d 53 51 4c 49 54 45 5f 49 4e  f( op!=SQLITE_IN
a240: 53 45 52 54 20 29 7b 0a 20 20 20 20 20 20 20 20  SERT ){.        
a250: 20 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b    pSession->hook
a260: 2e 78 4f 6c 64 28 70 53 65 73 73 69 6f 6e 2d 3e  .xOld(pSession->
a270: 68 6f 6f 6b 2e 70 43 74 78 2c 20 69 2c 20 26 70  hook.pCtx, i, &p
a280: 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65  );.        }else
a290: 20 69 66 28 20 70 54 61 62 2d 3e 61 62 50 4b 5b   if( pTab->abPK[
a2a0: 69 5d 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  i] ){.          
a2b0: 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78  pSession->hook.x
a2c0: 4e 65 77 28 70 53 65 73 73 69 6f 6e 2d 3e 68 6f  New(pSession->ho
a2d0: 6f 6b 2e 70 43 74 78 2c 20 69 2c 20 26 70 29 3b  ok.pCtx, i, &p);
a2e0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
a2f0: 20 20 20 73 65 73 73 69 6f 6e 53 65 72 69 61 6c     sessionSerial
a300: 69 7a 65 56 61 6c 75 65 28 26 70 43 68 61 6e 67  izeValue(&pChang
a310: 65 2d 3e 61 52 65 63 6f 72 64 5b 6e 42 79 74 65  e->aRecord[nByte
a320: 5d 2c 20 70 2c 20 26 6e 42 79 74 65 29 3b 0a 20  ], p, &nByte);. 
a330: 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a       }..      /*
a340: 20 41 64 64 20 74 68 65 20 63 68 61 6e 67 65 20   Add the change 
a350: 74 6f 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c  to the hash-tabl
a360: 65 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 70  e */.      if( p
a370: 53 65 73 73 69 6f 6e 2d 3e 62 49 6e 64 69 72 65  Session->bIndire
a380: 63 74 20 7c 7c 20 70 53 65 73 73 69 6f 6e 2d 3e  ct || pSession->
a390: 68 6f 6f 6b 2e 78 44 65 70 74 68 28 70 53 65 73  hook.xDepth(pSes
a3a0: 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 70 43 74 78 29  sion->hook.pCtx)
a3b0: 20 29 7b 0a 20 20 20 20 20 20 20 20 70 43 68 61   ){.        pCha
a3c0: 6e 67 65 2d 3e 62 49 6e 64 69 72 65 63 74 20 3d  nge->bIndirect =
a3d0: 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20   1;.      }.    
a3e0: 20 20 70 43 68 61 6e 67 65 2d 3e 6e 52 65 63 6f    pChange->nReco
a3f0: 72 64 20 3d 20 6e 42 79 74 65 3b 0a 20 20 20 20  rd = nByte;.    
a400: 20 20 70 43 68 61 6e 67 65 2d 3e 6f 70 20 3d 20    pChange->op = 
a410: 6f 70 3b 0a 20 20 20 20 20 20 70 43 68 61 6e 67  op;.      pChang
a420: 65 2d 3e 70 4e 65 78 74 20 3d 20 70 54 61 62 2d  e->pNext = pTab-
a430: 3e 61 70 43 68 61 6e 67 65 5b 69 48 61 73 68 5d  >apChange[iHash]
a440: 3b 0a 20 20 20 20 20 20 70 54 61 62 2d 3e 61 70  ;.      pTab->ap
a450: 43 68 61 6e 67 65 5b 69 48 61 73 68 5d 20 3d 20  Change[iHash] = 
a460: 70 43 68 61 6e 67 65 3b 0a 0a 20 20 20 20 7d 65  pChange;..    }e
a470: 6c 73 65 20 69 66 28 20 70 43 2d 3e 62 49 6e 64  lse if( pC->bInd
a480: 69 72 65 63 74 20 29 7b 0a 20 20 20 20 20 20 2f  irect ){.      /
a490: 2a 20 49 66 20 74 68 65 20 65 78 69 73 74 69 6e  * If the existin
a4a0: 67 20 63 68 61 6e 67 65 20 69 73 20 63 6f 6e 73  g change is cons
a4b0: 69 64 65 72 65 64 20 22 69 6e 64 69 72 65 63 74  idered "indirect
a4c0: 22 2c 20 62 75 74 20 74 68 69 73 20 63 75 72 72  ", but this curr
a4d0: 65 6e 74 0a 20 20 20 20 20 20 2a 2a 20 63 68 61  ent.      ** cha
a4e0: 6e 67 65 20 69 73 20 22 64 69 72 65 63 74 22 2c  nge is "direct",
a4f0: 20 6d 61 72 6b 20 74 68 65 20 63 68 61 6e 67 65   mark the change
a500: 20 6f 62 6a 65 63 74 20 61 73 20 64 69 72 65 63   object as direc
a510: 74 2e 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20  t. */.      if( 
a520: 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78  pSession->hook.x
a530: 44 65 70 74 68 28 70 53 65 73 73 69 6f 6e 2d 3e  Depth(pSession->
a540: 68 6f 6f 6b 2e 70 43 74 78 29 3d 3d 30 20 0a 20  hook.pCtx)==0 . 
a550: 20 20 20 20 20 20 26 26 20 70 53 65 73 73 69 6f        && pSessio
a560: 6e 2d 3e 62 49 6e 64 69 72 65 63 74 3d 3d 30 20  n->bIndirect==0 
a570: 0a 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20  .      ){.      
a580: 20 20 70 43 2d 3e 62 49 6e 64 69 72 65 63 74 20    pC->bIndirect 
a590: 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  = 0;.      }.   
a5a0: 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20   }.  }..  /* If 
a5b0: 61 6e 20 65 72 72 6f 72 20 68 61 73 20 6f 63 63  an error has occ
a5c0: 75 72 72 65 64 2c 20 6d 61 72 6b 20 74 68 65 20  urred, mark the 
a5d0: 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 61  session object a
a5e0: 73 20 66 61 69 6c 65 64 2e 20 2a 2f 0a 20 65 72  s failed. */. er
a5f0: 72 6f 72 5f 6f 75 74 3a 0a 20 20 69 66 28 20 70  ror_out:.  if( p
a600: 54 61 62 2d 3e 62 53 74 61 74 31 20 29 7b 0a 20  Tab->bStat1 ){. 
a610: 20 20 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f     pSession->hoo
a620: 6b 20 3d 20 73 74 61 74 31 2e 68 6f 6f 6b 3b 0a  k = stat1.hook;.
a630: 20 20 7d 0a 20 20 69 66 28 20 72 63 21 3d 53 51    }.  if( rc!=SQ
a640: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70  LITE_OK ){.    p
a650: 53 65 73 73 69 6f 6e 2d 3e 72 63 20 3d 20 72 63  Session->rc = rc
a660: 3b 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20  ;.  }.}..static 
a670: 69 6e 74 20 73 65 73 73 69 6f 6e 46 69 6e 64 54  int sessionFindT
a680: 61 62 6c 65 28 0a 20 20 73 71 6c 69 74 65 33 5f  able(.  sqlite3_
a690: 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f  session *pSessio
a6a0: 6e 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  n, .  const char
a6b0: 20 2a 7a 4e 61 6d 65 2c 0a 20 20 53 65 73 73 69   *zName,.  Sessi
a6c0: 6f 6e 54 61 62 6c 65 20 2a 2a 70 70 54 61 62 0a  onTable **ppTab.
a6d0: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
a6e0: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e  LITE_OK;.  int n
a6f0: 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 53 74  Name = sqlite3St
a700: 72 6c 65 6e 33 30 28 7a 4e 61 6d 65 29 3b 0a 20  rlen30(zName);. 
a710: 20 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70   SessionTable *p
a720: 52 65 74 3b 0a 0a 20 20 2f 2a 20 53 65 61 72 63  Ret;..  /* Searc
a730: 68 20 66 6f 72 20 61 6e 20 65 78 69 73 74 69 6e  h for an existin
a740: 67 20 74 61 62 6c 65 20 2a 2f 0a 20 20 66 6f 72  g table */.  for
a750: 28 70 52 65 74 3d 70 53 65 73 73 69 6f 6e 2d 3e  (pRet=pSession->
a760: 70 54 61 62 6c 65 3b 20 70 52 65 74 3b 20 70 52  pTable; pRet; pR
a770: 65 74 3d 70 52 65 74 2d 3e 70 4e 65 78 74 29 7b  et=pRet->pNext){
a780: 0a 20 20 20 20 69 66 28 20 30 3d 3d 73 71 6c 69  .    if( 0==sqli
a790: 74 65 33 5f 73 74 72 6e 69 63 6d 70 28 70 52 65  te3_strnicmp(pRe
a7a0: 74 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65 2c  t->zName, zName,
a7b0: 20 6e 4e 61 6d 65 2b 31 29 20 29 20 62 72 65 61   nName+1) ) brea
a7c0: 6b 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 52  k;.  }..  if( pR
a7d0: 65 74 3d 3d 30 20 26 26 20 70 53 65 73 73 69 6f  et==0 && pSessio
a7e0: 6e 2d 3e 62 41 75 74 6f 41 74 74 61 63 68 20 29  n->bAutoAttach )
a7f0: 7b 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 65 72  {.    /* If ther
a800: 65 20 69 73 20 61 20 74 61 62 6c 65 2d 66 69 6c  e is a table-fil
a810: 74 65 72 20 63 6f 6e 66 69 67 75 72 65 64 2c 20  ter configured, 
a820: 69 6e 76 6f 6b 65 20 69 74 2e 20 49 66 20 69 74  invoke it. If it
a830: 20 72 65 74 75 72 6e 73 20 30 2c 0a 20 20 20 20   returns 0,.    
a840: 2a 2a 20 64 6f 20 6e 6f 74 20 61 75 74 6f 6d 61  ** do not automa
a850: 74 69 63 61 6c 6c 79 20 61 64 64 20 74 68 65 20  tically add the 
a860: 6e 65 77 20 74 61 62 6c 65 2e 20 2a 2f 0a 20 20  new table. */.  
a870: 20 20 69 66 28 20 70 53 65 73 73 69 6f 6e 2d 3e    if( pSession->
a880: 78 54 61 62 6c 65 46 69 6c 74 65 72 3d 3d 30 0a  xTableFilter==0.
a890: 20 20 20 20 20 7c 7c 20 70 53 65 73 73 69 6f 6e       || pSession
a8a0: 2d 3e 78 54 61 62 6c 65 46 69 6c 74 65 72 28 70  ->xTableFilter(p
a8b0: 53 65 73 73 69 6f 6e 2d 3e 70 46 69 6c 74 65 72  Session->pFilter
a8c0: 43 74 78 2c 20 7a 4e 61 6d 65 29 20 0a 20 20 20  Ctx, zName) .   
a8d0: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73   ){.      rc = s
a8e0: 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 61 74  qlite3session_at
a8f0: 74 61 63 68 28 70 53 65 73 73 69 6f 6e 2c 20 7a  tach(pSession, z
a900: 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20 69 66 28  Name);.      if(
a910: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
a920: 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 28 70 52  {.        for(pR
a930: 65 74 3d 70 53 65 73 73 69 6f 6e 2d 3e 70 54 61  et=pSession->pTa
a940: 62 6c 65 3b 20 70 52 65 74 2d 3e 70 4e 65 78 74  ble; pRet->pNext
a950: 3b 20 70 52 65 74 3d 70 52 65 74 2d 3e 70 4e 65  ; pRet=pRet->pNe
a960: 78 74 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73  xt);.        ass
a970: 65 72 74 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f  ert( 0==sqlite3_
a980: 73 74 72 6e 69 63 6d 70 28 70 52 65 74 2d 3e 7a  strnicmp(pRet->z
a990: 4e 61 6d 65 2c 20 7a 4e 61 6d 65 2c 20 6e 4e 61  Name, zName, nNa
a9a0: 6d 65 2b 31 29 20 29 3b 0a 20 20 20 20 20 20 7d  me+1) );.      }
a9b0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 61 73  .    }.  }..  as
a9c0: 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45  sert( rc==SQLITE
a9d0: 5f 4f 4b 20 7c 7c 20 70 52 65 74 3d 3d 30 20 29  _OK || pRet==0 )
a9e0: 3b 0a 20 20 2a 70 70 54 61 62 20 3d 20 70 52 65  ;.  *ppTab = pRe
a9f0: 74 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  t;.  return rc;.
aa00: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 27 70 72  }../*.** The 'pr
aa10: 65 2d 75 70 64 61 74 65 27 20 68 6f 6f 6b 20 72  e-update' hook r
aa20: 65 67 69 73 74 65 72 65 64 20 62 79 20 74 68 69  egistered by thi
aa30: 73 20 6d 6f 64 75 6c 65 20 77 69 74 68 20 53 51  s module with SQ
aa40: 4c 69 74 65 20 64 61 74 61 62 61 73 65 73 2e 0a  Lite databases..
aa50: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 78  */.static void x
aa60: 50 72 65 55 70 64 61 74 65 28 0a 20 20 76 6f 69  PreUpdate(.  voi
aa70: 64 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20  d *pCtx,        
aa80: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
aa90: 43 6f 70 79 20 6f 66 20 74 68 69 72 64 20 61 72  Copy of third ar
aaa0: 67 20 74 6f 20 70 72 65 75 70 64 61 74 65 5f 68  g to preupdate_h
aab0: 6f 6f 6b 28 29 20 2a 2f 0a 20 20 73 71 6c 69 74  ook() */.  sqlit
aac0: 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20  e3 *db,         
aad0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
aae0: 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f  tabase handle */
aaf0: 0a 20 20 69 6e 74 20 6f 70 2c 20 20 20 20 20 20  .  int op,      
ab00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ab10: 20 20 20 2f 2a 20 53 51 4c 49 54 45 5f 55 50 44     /* SQLITE_UPD
ab20: 41 54 45 2c 20 44 45 4c 45 54 45 20 6f 72 20 49  ATE, DELETE or I
ab30: 4e 53 45 52 54 20 2a 2f 0a 20 20 63 68 61 72 20  NSERT */.  char 
ab40: 63 6f 6e 73 74 20 2a 7a 44 62 2c 20 20 20 20 20  const *zDb,     
ab50: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
ab60: 74 61 62 61 73 65 20 6e 61 6d 65 20 2a 2f 0a 20  tabase name */. 
ab70: 20 63 68 61 72 20 63 6f 6e 73 74 20 2a 7a 4e 61   char const *zNa
ab80: 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  me,             
ab90: 20 2f 2a 20 54 61 62 6c 65 20 6e 61 6d 65 20 2a   /* Table name *
aba0: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  /.  sqlite3_int6
abb0: 34 20 69 4b 65 79 31 2c 20 20 20 20 20 20 20 20  4 iKey1,        
abc0: 20 20 20 20 2f 2a 20 52 6f 77 69 64 20 6f 66 20      /* Rowid of 
abd0: 72 6f 77 20 61 62 6f 75 74 20 74 6f 20 62 65 20  row about to be 
abe0: 64 65 6c 65 74 65 64 2f 75 70 64 61 74 65 64 20  deleted/updated 
abf0: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74  */.  sqlite3_int
ac00: 36 34 20 69 4b 65 79 32 20 20 20 20 20 20 20 20  64 iKey2        
ac10: 20 20 20 20 20 2f 2a 20 4e 65 77 20 72 6f 77 69       /* New rowi
ac20: 64 20 76 61 6c 75 65 20 28 66 6f 72 20 61 20 72  d value (for a r
ac30: 6f 77 69 64 20 55 50 44 41 54 45 29 20 2a 2f 0a  owid UPDATE) */.
ac40: 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 65 73  ){.  sqlite3_ses
ac50: 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f 6e 3b 0a  sion *pSession;.
ac60: 20 20 69 6e 74 20 6e 44 62 20 3d 20 73 71 6c 69    int nDb = sqli
ac70: 74 65 33 53 74 72 6c 65 6e 33 30 28 7a 44 62 29  te3Strlen30(zDb)
ac80: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  ;..  assert( sql
ac90: 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28  ite3_mutex_held(
aca0: 64 62 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 0a 20  db->mutex) );.. 
acb0: 20 66 6f 72 28 70 53 65 73 73 69 6f 6e 3d 28 73   for(pSession=(s
acc0: 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a  qlite3_session *
acd0: 29 70 43 74 78 3b 20 70 53 65 73 73 69 6f 6e 3b  )pCtx; pSession;
ace0: 20 70 53 65 73 73 69 6f 6e 3d 70 53 65 73 73 69   pSession=pSessi
acf0: 6f 6e 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20  on->pNext){.    
ad00: 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70 54  SessionTable *pT
ad10: 61 62 3b 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74  ab;..    /* If t
ad20: 68 69 73 20 73 65 73 73 69 6f 6e 20 69 73 20 61  his session is a
ad30: 74 74 61 63 68 65 64 20 74 6f 20 61 20 64 69 66  ttached to a dif
ad40: 66 65 72 65 6e 74 20 64 61 74 61 62 61 73 65 20  ferent database 
ad50: 28 22 6d 61 69 6e 22 2c 20 22 74 65 6d 70 22 20  ("main", "temp" 
ad60: 0a 20 20 20 20 2a 2a 20 65 74 63 2e 29 2c 20 6f  .    ** etc.), o
ad70: 72 20 69 66 20 69 74 20 69 73 20 6e 6f 74 20 63  r if it is not c
ad80: 75 72 72 65 6e 74 6c 79 20 65 6e 61 62 6c 65 64  urrently enabled
ad90: 2c 20 74 68 65 72 65 20 69 73 20 6e 6f 74 68 69  , there is nothi
ada0: 6e 67 20 74 6f 20 64 6f 2e 20 53 6b 69 70 20 0a  ng to do. Skip .
adb0: 20 20 20 20 2a 2a 20 74 6f 20 74 68 65 20 6e 65      ** to the ne
adc0: 78 74 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63  xt session objec
add0: 74 20 61 74 74 61 63 68 65 64 20 74 6f 20 74 68  t attached to th
ade0: 69 73 20 64 61 74 61 62 61 73 65 2e 20 2a 2f 0a  is database. */.
adf0: 20 20 20 20 69 66 28 20 70 53 65 73 73 69 6f 6e      if( pSession
ae00: 2d 3e 62 45 6e 61 62 6c 65 3d 3d 30 20 29 20 63  ->bEnable==0 ) c
ae10: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 69 66 28  ontinue;.    if(
ae20: 20 70 53 65 73 73 69 6f 6e 2d 3e 72 63 20 29 20   pSession->rc ) 
ae30: 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 69 66  continue;.    if
ae40: 28 20 73 71 6c 69 74 65 33 5f 73 74 72 6e 69 63  ( sqlite3_strnic
ae50: 6d 70 28 7a 44 62 2c 20 70 53 65 73 73 69 6f 6e  mp(zDb, pSession
ae60: 2d 3e 7a 44 62 2c 20 6e 44 62 2b 31 29 20 29 20  ->zDb, nDb+1) ) 
ae70: 63 6f 6e 74 69 6e 75 65 3b 0a 0a 20 20 20 20 70  continue;..    p
ae80: 53 65 73 73 69 6f 6e 2d 3e 72 63 20 3d 20 73 65  Session->rc = se
ae90: 73 73 69 6f 6e 46 69 6e 64 54 61 62 6c 65 28 70  ssionFindTable(p
aea0: 53 65 73 73 69 6f 6e 2c 20 7a 4e 61 6d 65 2c 20  Session, zName, 
aeb0: 26 70 54 61 62 29 3b 0a 20 20 20 20 69 66 28 20  &pTab);.    if( 
aec0: 70 54 61 62 20 29 7b 0a 20 20 20 20 20 20 61 73  pTab ){.      as
aed0: 73 65 72 74 28 20 70 53 65 73 73 69 6f 6e 2d 3e  sert( pSession->
aee0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b  rc==SQLITE_OK );
aef0: 0a 20 20 20 20 20 20 73 65 73 73 69 6f 6e 50 72  .      sessionPr
af00: 65 75 70 64 61 74 65 4f 6e 65 43 68 61 6e 67 65  eupdateOneChange
af10: 28 6f 70 2c 20 70 53 65 73 73 69 6f 6e 2c 20 70  (op, pSession, p
af20: 54 61 62 29 3b 0a 20 20 20 20 20 20 69 66 28 20  Tab);.      if( 
af30: 6f 70 3d 3d 53 51 4c 49 54 45 5f 55 50 44 41 54  op==SQLITE_UPDAT
af40: 45 20 29 7b 0a 20 20 20 20 20 20 20 20 73 65 73  E ){.        ses
af50: 73 69 6f 6e 50 72 65 75 70 64 61 74 65 4f 6e 65  sionPreupdateOne
af60: 43 68 61 6e 67 65 28 53 51 4c 49 54 45 5f 49 4e  Change(SQLITE_IN
af70: 53 45 52 54 2c 20 70 53 65 73 73 69 6f 6e 2c 20  SERT, pSession, 
af80: 70 54 61 62 29 3b 0a 20 20 20 20 20 20 7d 0a 20  pTab);.      }. 
af90: 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a     }.  }.}../*.*
afa0: 2a 20 54 68 65 20 70 72 65 2d 75 70 64 61 74 65  * The pre-update
afb0: 20 68 6f 6f 6b 20 69 6d 70 6c 65 6d 65 6e 74 61   hook implementa
afc0: 74 69 6f 6e 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  tions..*/.static
afd0: 20 69 6e 74 20 73 65 73 73 69 6f 6e 50 72 65 75   int sessionPreu
afe0: 70 64 61 74 65 4f 6c 64 28 76 6f 69 64 20 2a 70  pdateOld(void *p
aff0: 43 74 78 2c 20 69 6e 74 20 69 56 61 6c 2c 20 73  Ctx, int iVal, s
b000: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 70  qlite3_value **p
b010: 70 56 61 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20  pVal){.  return 
b020: 73 71 6c 69 74 65 33 5f 70 72 65 75 70 64 61 74  sqlite3_preupdat
b030: 65 5f 6f 6c 64 28 28 73 71 6c 69 74 65 33 2a 29  e_old((sqlite3*)
b040: 70 43 74 78 2c 20 69 56 61 6c 2c 20 70 70 56 61  pCtx, iVal, ppVa
b050: 6c 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74  l);.}.static int
b060: 20 73 65 73 73 69 6f 6e 50 72 65 75 70 64 61 74   sessionPreupdat
b070: 65 4e 65 77 28 76 6f 69 64 20 2a 70 43 74 78 2c  eNew(void *pCtx,
b080: 20 69 6e 74 20 69 56 61 6c 2c 20 73 71 6c 69 74   int iVal, sqlit
b090: 65 33 5f 76 61 6c 75 65 20 2a 2a 70 70 56 61 6c  e3_value **ppVal
b0a0: 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69  ){.  return sqli
b0b0: 74 65 33 5f 70 72 65 75 70 64 61 74 65 5f 6e 65  te3_preupdate_ne
b0c0: 77 28 28 73 71 6c 69 74 65 33 2a 29 70 43 74 78  w((sqlite3*)pCtx
b0d0: 2c 20 69 56 61 6c 2c 20 70 70 56 61 6c 29 3b 0a  , iVal, ppVal);.
b0e0: 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73  }.static int ses
b0f0: 73 69 6f 6e 50 72 65 75 70 64 61 74 65 43 6f 75  sionPreupdateCou
b100: 6e 74 28 76 6f 69 64 20 2a 70 43 74 78 29 7b 0a  nt(void *pCtx){.
b110: 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33    return sqlite3
b120: 5f 70 72 65 75 70 64 61 74 65 5f 63 6f 75 6e 74  _preupdate_count
b130: 28 28 73 71 6c 69 74 65 33 2a 29 70 43 74 78 29  ((sqlite3*)pCtx)
b140: 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 73  ;.}.static int s
b150: 65 73 73 69 6f 6e 50 72 65 75 70 64 61 74 65 44  essionPreupdateD
b160: 65 70 74 68 28 76 6f 69 64 20 2a 70 43 74 78 29  epth(void *pCtx)
b170: 7b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  {.  return sqlit
b180: 65 33 5f 70 72 65 75 70 64 61 74 65 5f 64 65 70  e3_preupdate_dep
b190: 74 68 28 28 73 71 6c 69 74 65 33 2a 29 70 43 74  th((sqlite3*)pCt
b1a0: 78 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 73  x);.}../*.** Ins
b1b0: 74 61 6c 6c 20 74 68 65 20 70 72 65 2d 75 70 64  tall the pre-upd
b1c0: 61 74 65 20 68 6f 6f 6b 73 20 6f 6e 20 74 68 65  ate hooks on the
b1d0: 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20   session object 
b1e0: 70 61 73 73 65 64 20 61 73 20 74 68 65 20 6f 6e  passed as the on
b1f0: 6c 79 0a 2a 2a 20 61 72 67 75 6d 65 6e 74 2e 0a  ly.** argument..
b200: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73  */.static void s
b210: 65 73 73 69 6f 6e 50 72 65 75 70 64 61 74 65 48  essionPreupdateH
b220: 6f 6f 6b 73 28 0a 20 20 73 71 6c 69 74 65 33 5f  ooks(.  sqlite3_
b230: 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f  session *pSessio
b240: 6e 0a 29 7b 0a 20 20 70 53 65 73 73 69 6f 6e 2d  n.){.  pSession-
b250: 3e 68 6f 6f 6b 2e 70 43 74 78 20 3d 20 28 76 6f  >hook.pCtx = (vo
b260: 69 64 2a 29 70 53 65 73 73 69 6f 6e 2d 3e 64 62  id*)pSession->db
b270: 3b 0a 20 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f  ;.  pSession->ho
b280: 6f 6b 2e 78 4f 6c 64 20 3d 20 73 65 73 73 69 6f  ok.xOld = sessio
b290: 6e 50 72 65 75 70 64 61 74 65 4f 6c 64 3b 0a 20  nPreupdateOld;. 
b2a0: 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e   pSession->hook.
b2b0: 78 4e 65 77 20 3d 20 73 65 73 73 69 6f 6e 50 72  xNew = sessionPr
b2c0: 65 75 70 64 61 74 65 4e 65 77 3b 0a 20 20 70 53  eupdateNew;.  pS
b2d0: 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 43 6f  ession->hook.xCo
b2e0: 75 6e 74 20 3d 20 73 65 73 73 69 6f 6e 50 72 65  unt = sessionPre
b2f0: 75 70 64 61 74 65 43 6f 75 6e 74 3b 0a 20 20 70  updateCount;.  p
b300: 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e 78 44  Session->hook.xD
b310: 65 70 74 68 20 3d 20 73 65 73 73 69 6f 6e 50 72  epth = sessionPr
b320: 65 75 70 64 61 74 65 44 65 70 74 68 3b 0a 7d 0a  eupdateDepth;.}.
b330: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
b340: 53 65 73 73 69 6f 6e 44 69 66 66 43 74 78 20 53  SessionDiffCtx S
b350: 65 73 73 69 6f 6e 44 69 66 66 43 74 78 3b 0a 73  essionDiffCtx;.s
b360: 74 72 75 63 74 20 53 65 73 73 69 6f 6e 44 69 66  truct SessionDif
b370: 66 43 74 78 20 7b 0a 20 20 73 71 6c 69 74 65 33  fCtx {.  sqlite3
b380: 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 20 20  _stmt *pStmt;.  
b390: 69 6e 74 20 6e 4f 6c 64 4f 66 66 3b 0a 7d 3b 0a  int nOldOff;.};.
b3a0: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 64 69 66 66 20  ./*.** The diff 
b3b0: 68 6f 6f 6b 20 69 6d 70 6c 65 6d 65 6e 74 61 74  hook implementat
b3c0: 69 6f 6e 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ions..*/.static 
b3d0: 69 6e 74 20 73 65 73 73 69 6f 6e 44 69 66 66 4f  int sessionDiffO
b3e0: 6c 64 28 76 6f 69 64 20 2a 70 43 74 78 2c 20 69  ld(void *pCtx, i
b3f0: 6e 74 20 69 56 61 6c 2c 20 73 71 6c 69 74 65 33  nt iVal, sqlite3
b400: 5f 76 61 6c 75 65 20 2a 2a 70 70 56 61 6c 29 7b  _value **ppVal){
b410: 0a 20 20 53 65 73 73 69 6f 6e 44 69 66 66 43 74  .  SessionDiffCt
b420: 78 20 2a 70 20 3d 20 28 53 65 73 73 69 6f 6e 44  x *p = (SessionD
b430: 69 66 66 43 74 78 2a 29 70 43 74 78 3b 0a 20 20  iffCtx*)pCtx;.  
b440: 2a 70 70 56 61 6c 20 3d 20 73 71 6c 69 74 65 33  *ppVal = sqlite3
b450: 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 2d  _column_value(p-
b460: 3e 70 53 74 6d 74 2c 20 69 56 61 6c 2b 70 2d 3e  >pStmt, iVal+p->
b470: 6e 4f 6c 64 4f 66 66 29 3b 0a 20 20 72 65 74 75  nOldOff);.  retu
b480: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
b490: 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69  static int sessi
b4a0: 6f 6e 44 69 66 66 4e 65 77 28 76 6f 69 64 20 2a  onDiffNew(void *
b4b0: 70 43 74 78 2c 20 69 6e 74 20 69 56 61 6c 2c 20  pCtx, int iVal, 
b4c0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
b4d0: 70 70 56 61 6c 29 7b 0a 20 20 53 65 73 73 69 6f  ppVal){.  Sessio
b4e0: 6e 44 69 66 66 43 74 78 20 2a 70 20 3d 20 28 53  nDiffCtx *p = (S
b4f0: 65 73 73 69 6f 6e 44 69 66 66 43 74 78 2a 29 70  essionDiffCtx*)p
b500: 43 74 78 3b 0a 20 20 2a 70 70 56 61 6c 20 3d 20  Ctx;.  *ppVal = 
b510: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76  sqlite3_column_v
b520: 61 6c 75 65 28 70 2d 3e 70 53 74 6d 74 2c 20 69  alue(p->pStmt, i
b530: 56 61 6c 29 3b 0a 20 20 20 72 65 74 75 72 6e 20  Val);.   return 
b540: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 73 74 61  SQLITE_OK;.}.sta
b550: 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 44  tic int sessionD
b560: 69 66 66 43 6f 75 6e 74 28 76 6f 69 64 20 2a 70  iffCount(void *p
b570: 43 74 78 29 7b 0a 20 20 53 65 73 73 69 6f 6e 44  Ctx){.  SessionD
b580: 69 66 66 43 74 78 20 2a 70 20 3d 20 28 53 65 73  iffCtx *p = (Ses
b590: 73 69 6f 6e 44 69 66 66 43 74 78 2a 29 70 43 74  sionDiffCtx*)pCt
b5a0: 78 3b 0a 20 20 72 65 74 75 72 6e 20 70 2d 3e 6e  x;.  return p->n
b5b0: 4f 6c 64 4f 66 66 20 3f 20 70 2d 3e 6e 4f 6c 64  OldOff ? p->nOld
b5c0: 4f 66 66 20 3a 20 73 71 6c 69 74 65 33 5f 63 6f  Off : sqlite3_co
b5d0: 6c 75 6d 6e 5f 63 6f 75 6e 74 28 70 2d 3e 70 53  lumn_count(p->pS
b5e0: 74 6d 74 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69  tmt);.}.static i
b5f0: 6e 74 20 73 65 73 73 69 6f 6e 44 69 66 66 44 65  nt sessionDiffDe
b600: 70 74 68 28 76 6f 69 64 20 2a 70 43 74 78 29 7b  pth(void *pCtx){
b610: 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a  .  return 0;.}..
b620: 2f 2a 0a 2a 2a 20 49 6e 73 74 61 6c 6c 20 74 68  /*.** Install th
b630: 65 20 64 69 66 66 20 68 6f 6f 6b 73 20 6f 6e 20  e diff hooks on 
b640: 74 68 65 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65  the session obje
b650: 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68 65  ct passed as the
b660: 20 6f 6e 6c 79 0a 2a 2a 20 61 72 67 75 6d 65 6e   only.** argumen
b670: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  t..*/.static voi
b680: 64 20 73 65 73 73 69 6f 6e 44 69 66 66 48 6f 6f  d sessionDiffHoo
b690: 6b 73 28 0a 20 20 73 71 6c 69 74 65 33 5f 73 65  ks(.  sqlite3_se
b6a0: 73 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f 6e 2c  ssion *pSession,
b6b0: 0a 20 20 53 65 73 73 69 6f 6e 44 69 66 66 43 74  .  SessionDiffCt
b6c0: 78 20 2a 70 44 69 66 66 43 74 78 0a 29 7b 0a 20  x *pDiffCtx.){. 
b6d0: 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b 2e   pSession->hook.
b6e0: 70 43 74 78 20 3d 20 28 76 6f 69 64 2a 29 70 44  pCtx = (void*)pD
b6f0: 69 66 66 43 74 78 3b 0a 20 20 70 53 65 73 73 69  iffCtx;.  pSessi
b700: 6f 6e 2d 3e 68 6f 6f 6b 2e 78 4f 6c 64 20 3d 20  on->hook.xOld = 
b710: 73 65 73 73 69 6f 6e 44 69 66 66 4f 6c 64 3b 0a  sessionDiffOld;.
b720: 20 20 70 53 65 73 73 69 6f 6e 2d 3e 68 6f 6f 6b    pSession->hook
b730: 2e 78 4e 65 77 20 3d 20 73 65 73 73 69 6f 6e 44  .xNew = sessionD
b740: 69 66 66 4e 65 77 3b 0a 20 20 70 53 65 73 73 69  iffNew;.  pSessi
b750: 6f 6e 2d 3e 68 6f 6f 6b 2e 78 43 6f 75 6e 74 20  on->hook.xCount 
b760: 3d 20 73 65 73 73 69 6f 6e 44 69 66 66 43 6f 75  = sessionDiffCou
b770: 6e 74 3b 0a 20 20 70 53 65 73 73 69 6f 6e 2d 3e  nt;.  pSession->
b780: 68 6f 6f 6b 2e 78 44 65 70 74 68 20 3d 20 73 65  hook.xDepth = se
b790: 73 73 69 6f 6e 44 69 66 66 44 65 70 74 68 3b 0a  ssionDiffDepth;.
b7a0: 7d 0a 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a  }..static char *
b7b0: 73 65 73 73 69 6f 6e 45 78 70 72 43 6f 6d 70 61  sessionExprCompa
b7c0: 72 65 50 4b 28 0a 20 20 69 6e 74 20 6e 43 6f 6c  rePK(.  int nCol
b7d0: 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ,.  const char *
b7e0: 7a 44 62 31 2c 20 63 6f 6e 73 74 20 63 68 61 72  zDb1, const char
b7f0: 20 2a 7a 44 62 32 2c 20 0a 20 20 63 6f 6e 73 74   *zDb2, .  const
b800: 20 63 68 61 72 20 2a 7a 54 61 62 2c 0a 20 20 63   char *zTab,.  c
b810: 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a 43 6f  onst char **azCo
b820: 6c 2c 20 75 38 20 2a 61 62 50 4b 0a 29 7b 0a 20  l, u8 *abPK.){. 
b830: 20 69 6e 74 20 69 3b 0a 20 20 63 6f 6e 73 74 20   int i;.  const 
b840: 63 68 61 72 20 2a 7a 53 65 70 20 3d 20 22 22 3b  char *zSep = "";
b850: 0a 20 20 63 68 61 72 20 2a 7a 52 65 74 20 3d 20  .  char *zRet = 
b860: 30 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  0;..  for(i=0; i
b870: 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20  <nCol; i++){.   
b880: 20 69 66 28 20 61 62 50 4b 5b 69 5d 20 29 7b 0a   if( abPK[i] ){.
b890: 20 20 20 20 20 20 7a 52 65 74 20 3d 20 73 71 6c        zRet = sql
b8a0: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 7a  ite3_mprintf("%z
b8b0: 25 73 5c 22 25 77 5c 22 2e 5c 22 25 77 5c 22 2e  %s\"%w\".\"%w\".
b8c0: 5c 22 25 77 5c 22 3d 5c 22 25 77 5c 22 2e 5c 22  \"%w\"=\"%w\".\"
b8d0: 25 77 5c 22 2e 5c 22 25 77 5c 22 22 2c 0a 20 20  %w\".\"%w\"",.  
b8e0: 20 20 20 20 20 20 20 20 7a 52 65 74 2c 20 7a 53          zRet, zS
b8f0: 65 70 2c 20 7a 44 62 31 2c 20 7a 54 61 62 2c 20  ep, zDb1, zTab, 
b900: 61 7a 43 6f 6c 5b 69 5d 2c 20 7a 44 62 32 2c 20  azCol[i], zDb2, 
b910: 7a 54 61 62 2c 20 61 7a 43 6f 6c 5b 69 5d 0a 20  zTab, azCol[i]. 
b920: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 7a 53       );.      zS
b930: 65 70 20 3d 20 22 20 41 4e 44 20 22 3b 0a 20 20  ep = " AND ";.  
b940: 20 20 20 20 69 66 28 20 7a 52 65 74 3d 3d 30 20      if( zRet==0 
b950: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20  ) break;.    }. 
b960: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 7a 52 65   }..  return zRe
b970: 74 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61  t;.}..static cha
b980: 72 20 2a 73 65 73 73 69 6f 6e 45 78 70 72 43 6f  r *sessionExprCo
b990: 6d 70 61 72 65 4f 74 68 65 72 28 0a 20 20 69 6e  mpareOther(.  in
b9a0: 74 20 6e 43 6f 6c 2c 0a 20 20 63 6f 6e 73 74 20  t nCol,.  const 
b9b0: 63 68 61 72 20 2a 7a 44 62 31 2c 20 63 6f 6e 73  char *zDb1, cons
b9c0: 74 20 63 68 61 72 20 2a 7a 44 62 32 2c 20 0a 20  t char *zDb2, . 
b9d0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61   const char *zTa
b9e0: 62 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  b,.  const char 
b9f0: 2a 2a 61 7a 43 6f 6c 2c 20 75 38 20 2a 61 62 50  **azCol, u8 *abP
ba00: 4b 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  K.){.  int i;.  
ba10: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 65 70  const char *zSep
ba20: 20 3d 20 22 22 3b 0a 20 20 63 68 61 72 20 2a 7a   = "";.  char *z
ba30: 52 65 74 20 3d 20 30 3b 0a 20 20 69 6e 74 20 62  Ret = 0;.  int b
ba40: 48 61 76 65 20 3d 20 30 3b 0a 0a 20 20 66 6f 72  Have = 0;..  for
ba50: 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b  (i=0; i<nCol; i+
ba60: 2b 29 7b 0a 20 20 20 20 69 66 28 20 61 62 50 4b  +){.    if( abPK
ba70: 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  [i]==0 ){.      
ba80: 62 48 61 76 65 20 3d 20 31 3b 0a 20 20 20 20 20  bHave = 1;.     
ba90: 20 7a 52 65 74 20 3d 20 73 71 6c 69 74 65 33 5f   zRet = sqlite3_
baa0: 6d 70 72 69 6e 74 66 28 0a 20 20 20 20 20 20 20  mprintf(.       
bab0: 20 20 20 22 25 7a 25 73 5c 22 25 77 5c 22 2e 5c     "%z%s\"%w\".\
bac0: 22 25 77 5c 22 2e 5c 22 25 77 5c 22 20 49 53 20  "%w\".\"%w\" IS 
bad0: 4e 4f 54 20 5c 22 25 77 5c 22 2e 5c 22 25 77 5c  NOT \"%w\".\"%w\
bae0: 22 2e 5c 22 25 77 5c 22 22 2c 0a 20 20 20 20 20  ".\"%w\"",.     
baf0: 20 20 20 20 20 7a 52 65 74 2c 20 7a 53 65 70 2c       zRet, zSep,
bb00: 20 7a 44 62 31 2c 20 7a 54 61 62 2c 20 61 7a 43   zDb1, zTab, azC
bb10: 6f 6c 5b 69 5d 2c 20 7a 44 62 32 2c 20 7a 54 61  ol[i], zDb2, zTa
bb20: 62 2c 20 61 7a 43 6f 6c 5b 69 5d 0a 20 20 20 20  b, azCol[i].    
bb30: 20 20 29 3b 0a 20 20 20 20 20 20 7a 53 65 70 20    );.      zSep 
bb40: 3d 20 22 20 4f 52 20 22 3b 0a 20 20 20 20 20 20  = " OR ";.      
bb50: 69 66 28 20 7a 52 65 74 3d 3d 30 20 29 20 62 72  if( zRet==0 ) br
bb60: 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  eak;.    }.  }..
bb70: 20 20 69 66 28 20 62 48 61 76 65 3d 3d 30 20 29    if( bHave==0 )
bb80: 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 7a 52  {.    assert( zR
bb90: 65 74 3d 3d 30 20 29 3b 0a 20 20 20 20 7a 52 65  et==0 );.    zRe
bba0: 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  t = sqlite3_mpri
bbb0: 6e 74 66 28 22 30 22 29 3b 0a 20 20 7d 0a 0a 20  ntf("0");.  }.. 
bbc0: 20 72 65 74 75 72 6e 20 7a 52 65 74 3b 0a 7d 0a   return zRet;.}.
bbd0: 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 73 65  .static char *se
bbe0: 73 73 69 6f 6e 53 65 6c 65 63 74 46 69 6e 64 4e  ssionSelectFindN
bbf0: 65 77 28 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c 0a  ew(.  int nCol,.
bc00: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44    const char *zD
bc10: 62 31 2c 20 20 20 20 20 20 2f 2a 20 50 69 63 6b  b1,      /* Pick
bc20: 20 72 6f 77 73 20 69 6e 20 74 68 69 73 20 64 62   rows in this db
bc30: 20 6f 6e 6c 79 20 2a 2f 0a 20 20 63 6f 6e 73 74   only */.  const
bc40: 20 63 68 61 72 20 2a 7a 44 62 32 2c 20 20 20 20   char *zDb2,    
bc50: 20 20 2f 2a 20 42 75 74 20 6e 6f 74 20 69 6e 20    /* But not in 
bc60: 74 68 69 73 20 6f 6e 65 20 2a 2f 0a 20 20 63 6f  this one */.  co
bc70: 6e 73 74 20 63 68 61 72 20 2a 7a 54 62 6c 2c 20  nst char *zTbl, 
bc80: 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20 6e 61       /* Table na
bc90: 6d 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  me */.  const ch
bca0: 61 72 20 2a 7a 45 78 70 72 0a 29 7b 0a 20 20 63  ar *zExpr.){.  c
bcb0: 68 61 72 20 2a 7a 52 65 74 20 3d 20 73 71 6c 69  har *zRet = sqli
bcc0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20 20 20  te3_mprintf(.   
bcd0: 20 20 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f     "SELECT * FRO
bce0: 4d 20 5c 22 25 77 5c 22 2e 5c 22 25 77 5c 22 20  M \"%w\".\"%w\" 
bcf0: 57 48 45 52 45 20 4e 4f 54 20 45 58 49 53 54 53  WHERE NOT EXISTS
bd00: 20 28 22 0a 20 20 20 20 20 20 22 20 20 53 45 4c   (".      "  SEL
bd10: 45 43 54 20 31 20 46 52 4f 4d 20 5c 22 25 77 5c  ECT 1 FROM \"%w\
bd20: 22 2e 5c 22 25 77 5c 22 20 57 48 45 52 45 20 25  ".\"%w\" WHERE %
bd30: 73 22 0a 20 20 20 20 20 20 22 29 22 2c 0a 20 20  s".      ")",.  
bd40: 20 20 20 20 7a 44 62 31 2c 20 7a 54 62 6c 2c 20      zDb1, zTbl, 
bd50: 7a 44 62 32 2c 20 7a 54 62 6c 2c 20 7a 45 78 70  zDb2, zTbl, zExp
bd60: 72 0a 20 20 29 3b 0a 20 20 72 65 74 75 72 6e 20  r.  );.  return 
bd70: 7a 52 65 74 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  zRet;.}..static 
bd80: 69 6e 74 20 73 65 73 73 69 6f 6e 44 69 66 66 46  int sessionDiffF
bd90: 69 6e 64 4e 65 77 28 0a 20 20 69 6e 74 20 6f 70  indNew(.  int op
bda0: 2c 0a 20 20 73 71 6c 69 74 65 33 5f 73 65 73 73  ,.  sqlite3_sess
bdb0: 69 6f 6e 20 2a 70 53 65 73 73 69 6f 6e 2c 0a 20  ion *pSession,. 
bdc0: 20 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70   SessionTable *p
bdd0: 54 61 62 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61  Tab,.  const cha
bde0: 72 20 2a 7a 44 62 31 2c 0a 20 20 63 6f 6e 73 74  r *zDb1,.  const
bdf0: 20 63 68 61 72 20 2a 7a 44 62 32 2c 0a 20 20 63   char *zDb2,.  c
be00: 68 61 72 20 2a 7a 45 78 70 72 0a 29 7b 0a 20 20  har *zExpr.){.  
be10: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
be20: 4f 4b 3b 0a 20 20 63 68 61 72 20 2a 7a 53 74 6d  OK;.  char *zStm
be30: 74 20 3d 20 73 65 73 73 69 6f 6e 53 65 6c 65 63  t = sessionSelec
be40: 74 46 69 6e 64 4e 65 77 28 70 54 61 62 2d 3e 6e  tFindNew(pTab->n
be50: 43 6f 6c 2c 20 7a 44 62 31 2c 20 7a 44 62 32 2c  Col, zDb1, zDb2,
be60: 20 70 54 61 62 2d 3e 7a 4e 61 6d 65 2c 7a 45 78   pTab->zName,zEx
be70: 70 72 29 3b 0a 0a 20 20 69 66 28 20 7a 53 74 6d  pr);..  if( zStm
be80: 74 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d  t==0 ){.    rc =
be90: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
bea0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69   }else{.    sqli
beb0: 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b  te3_stmt *pStmt;
bec0: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
bed0: 33 5f 70 72 65 70 61 72 65 28 70 53 65 73 73 69  3_prepare(pSessi
bee0: 6f 6e 2d 3e 64 62 2c 20 7a 53 74 6d 74 2c 20 2d  on->db, zStmt, -
bef0: 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20  1, &pStmt, 0);. 
bf00: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
bf10: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 53 65  E_OK ){.      Se
bf20: 73 73 69 6f 6e 44 69 66 66 43 74 78 20 2a 70 44  ssionDiffCtx *pD
bf30: 69 66 66 43 74 78 20 3d 20 28 53 65 73 73 69 6f  iffCtx = (Sessio
bf40: 6e 44 69 66 66 43 74 78 2a 29 70 53 65 73 73 69  nDiffCtx*)pSessi
bf50: 6f 6e 2d 3e 68 6f 6f 6b 2e 70 43 74 78 3b 0a 20  on->hook.pCtx;. 
bf60: 20 20 20 20 20 70 44 69 66 66 43 74 78 2d 3e 70       pDiffCtx->p
bf70: 53 74 6d 74 20 3d 20 70 53 74 6d 74 3b 0a 20 20  Stmt = pStmt;.  
bf80: 20 20 20 20 70 44 69 66 66 43 74 78 2d 3e 6e 4f      pDiffCtx->nO
bf90: 6c 64 4f 66 66 20 3d 20 30 3b 0a 20 20 20 20 20  ldOff = 0;.     
bfa0: 20 77 68 69 6c 65 28 20 53 51 4c 49 54 45 5f 52   while( SQLITE_R
bfb0: 4f 57 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65 70  OW==sqlite3_step
bfc0: 28 70 53 74 6d 74 29 20 29 7b 0a 20 20 20 20 20  (pStmt) ){.     
bfd0: 20 20 20 73 65 73 73 69 6f 6e 50 72 65 75 70 64     sessionPreupd
bfe0: 61 74 65 4f 6e 65 43 68 61 6e 67 65 28 6f 70 2c  ateOneChange(op,
bff0: 20 70 53 65 73 73 69 6f 6e 2c 20 70 54 61 62 29   pSession, pTab)
c000: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
c010: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e  rc = sqlite3_fin
c020: 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20  alize(pStmt);.  
c030: 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f    }.    sqlite3_
c040: 66 72 65 65 28 7a 53 74 6d 74 29 3b 0a 20 20 7d  free(zStmt);.  }
c050: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
c060: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73  ..static int ses
c070: 73 69 6f 6e 44 69 66 66 46 69 6e 64 4d 6f 64 69  sionDiffFindModi
c080: 66 69 65 64 28 0a 20 20 73 71 6c 69 74 65 33 5f  fied(.  sqlite3_
c090: 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f  session *pSessio
c0a0: 6e 2c 20 0a 20 20 53 65 73 73 69 6f 6e 54 61 62  n, .  SessionTab
c0b0: 6c 65 20 2a 70 54 61 62 2c 20 0a 20 20 63 6f 6e  le *pTab, .  con
c0c0: 73 74 20 63 68 61 72 20 2a 7a 46 72 6f 6d 2c 20  st char *zFrom, 
c0d0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
c0e0: 45 78 70 72 0a 29 7b 0a 20 20 69 6e 74 20 72 63  Expr.){.  int rc
c0f0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20   = SQLITE_OK;.. 
c100: 20 63 68 61 72 20 2a 7a 45 78 70 72 32 20 3d 20   char *zExpr2 = 
c110: 73 65 73 73 69 6f 6e 45 78 70 72 43 6f 6d 70 61  sessionExprCompa
c120: 72 65 4f 74 68 65 72 28 70 54 61 62 2d 3e 6e 43  reOther(pTab->nC
c130: 6f 6c 2c 0a 20 20 20 20 20 20 70 53 65 73 73 69  ol,.      pSessi
c140: 6f 6e 2d 3e 7a 44 62 2c 20 7a 46 72 6f 6d 2c 20  on->zDb, zFrom, 
c150: 70 54 61 62 2d 3e 7a 4e 61 6d 65 2c 20 70 54 61  pTab->zName, pTa
c160: 62 2d 3e 61 7a 43 6f 6c 2c 20 70 54 61 62 2d 3e  b->azCol, pTab->
c170: 61 62 50 4b 0a 20 20 29 3b 0a 20 20 69 66 28 20  abPK.  );.  if( 
c180: 7a 45 78 70 72 32 3d 3d 30 20 29 7b 0a 20 20 20  zExpr2==0 ){.   
c190: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
c1a0: 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  EM;.  }else{.   
c1b0: 20 63 68 61 72 20 2a 7a 53 74 6d 74 20 3d 20 73   char *zStmt = s
c1c0: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a  qlite3_mprintf(.
c1d0: 20 20 20 20 20 20 20 20 22 53 45 4c 45 43 54 20          "SELECT 
c1e0: 2a 20 46 52 4f 4d 20 5c 22 25 77 5c 22 2e 5c 22  * FROM \"%w\".\"
c1f0: 25 77 5c 22 2c 20 5c 22 25 77 5c 22 2e 5c 22 25  %w\", \"%w\".\"%
c200: 77 5c 22 20 57 48 45 52 45 20 25 73 20 41 4e 44  w\" WHERE %s AND
c210: 20 28 25 7a 29 22 2c 0a 20 20 20 20 20 20 20 20   (%z)",.        
c220: 70 53 65 73 73 69 6f 6e 2d 3e 7a 44 62 2c 20 70  pSession->zDb, p
c230: 54 61 62 2d 3e 7a 4e 61 6d 65 2c 20 7a 46 72 6f  Tab->zName, zFro
c240: 6d 2c 20 70 54 61 62 2d 3e 7a 4e 61 6d 65 2c 20  m, pTab->zName, 
c250: 7a 45 78 70 72 2c 20 7a 45 78 70 72 32 0a 20 20  zExpr, zExpr2.  
c260: 20 20 29 3b 0a 20 20 20 20 69 66 28 20 7a 53 74    );.    if( zSt
c270: 6d 74 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72  mt==0 ){.      r
c280: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
c290: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
c2a0: 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20     sqlite3_stmt 
c2b0: 2a 70 53 74 6d 74 3b 0a 20 20 20 20 20 20 72 63  *pStmt;.      rc
c2c0: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
c2d0: 72 65 28 70 53 65 73 73 69 6f 6e 2d 3e 64 62 2c  re(pSession->db,
c2e0: 20 7a 53 74 6d 74 2c 20 2d 31 2c 20 26 70 53 74   zStmt, -1, &pSt
c2f0: 6d 74 2c 20 30 29 3b 0a 0a 20 20 20 20 20 20 69  mt, 0);..      i
c300: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
c310: 20 29 7b 0a 20 20 20 20 20 20 20 20 53 65 73 73   ){.        Sess
c320: 69 6f 6e 44 69 66 66 43 74 78 20 2a 70 44 69 66  ionDiffCtx *pDif
c330: 66 43 74 78 20 3d 20 28 53 65 73 73 69 6f 6e 44  fCtx = (SessionD
c340: 69 66 66 43 74 78 2a 29 70 53 65 73 73 69 6f 6e  iffCtx*)pSession
c350: 2d 3e 68 6f 6f 6b 2e 70 43 74 78 3b 0a 20 20 20  ->hook.pCtx;.   
c360: 20 20 20 20 20 70 44 69 66 66 43 74 78 2d 3e 70       pDiffCtx->p
c370: 53 74 6d 74 20 3d 20 70 53 74 6d 74 3b 0a 20 20  Stmt = pStmt;.  
c380: 20 20 20 20 20 20 70 44 69 66 66 43 74 78 2d 3e        pDiffCtx->
c390: 6e 4f 6c 64 4f 66 66 20 3d 20 70 54 61 62 2d 3e  nOldOff = pTab->
c3a0: 6e 43 6f 6c 3b 0a 20 20 20 20 20 20 20 20 77 68  nCol;.        wh
c3b0: 69 6c 65 28 20 53 51 4c 49 54 45 5f 52 4f 57 3d  ile( SQLITE_ROW=
c3c0: 3d 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53  =sqlite3_step(pS
c3d0: 74 6d 74 29 20 29 7b 0a 20 20 20 20 20 20 20 20  tmt) ){.        
c3e0: 20 20 73 65 73 73 69 6f 6e 50 72 65 75 70 64 61    sessionPreupda
c3f0: 74 65 4f 6e 65 43 68 61 6e 67 65 28 53 51 4c 49  teOneChange(SQLI
c400: 54 45 5f 55 50 44 41 54 45 2c 20 70 53 65 73 73  TE_UPDATE, pSess
c410: 69 6f 6e 2c 20 70 54 61 62 29 3b 0a 20 20 20 20  ion, pTab);.    
c420: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 72 63      }.        rc
c430: 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c   = sqlite3_final
c440: 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20  ize(pStmt);.    
c450: 20 20 7d 0a 20 20 20 20 20 20 73 71 6c 69 74 65    }.      sqlite
c460: 33 5f 66 72 65 65 28 7a 53 74 6d 74 29 3b 0a 20  3_free(zStmt);. 
c470: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
c480: 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74 20 73 71  rn rc;.}..int sq
c490: 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 64 69 66  lite3session_dif
c4a0: 66 28 0a 20 20 73 71 6c 69 74 65 33 5f 73 65 73  f(.  sqlite3_ses
c4b0: 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f 6e 2c 0a  sion *pSession,.
c4c0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46    const char *zF
c4d0: 72 6f 6d 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61  rom,.  const cha
c4e0: 72 20 2a 7a 54 62 6c 2c 0a 20 20 63 68 61 72 20  r *zTbl,.  char 
c4f0: 2a 2a 70 7a 45 72 72 4d 73 67 0a 29 7b 0a 20 20  **pzErrMsg.){.  
c500: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62 20  const char *zDb 
c510: 3d 20 70 53 65 73 73 69 6f 6e 2d 3e 7a 44 62 3b  = pSession->zDb;
c520: 0a 20 20 69 6e 74 20 72 63 20 3d 20 70 53 65 73  .  int rc = pSes
c530: 73 69 6f 6e 2d 3e 72 63 3b 0a 20 20 53 65 73 73  sion->rc;.  Sess
c540: 69 6f 6e 44 69 66 66 43 74 78 20 64 3b 0a 0a 20  ionDiffCtx d;.. 
c550: 20 6d 65 6d 73 65 74 28 26 64 2c 20 30 2c 20 73   memset(&d, 0, s
c560: 69 7a 65 6f 66 28 64 29 29 3b 0a 20 20 73 65 73  izeof(d));.  ses
c570: 73 69 6f 6e 44 69 66 66 48 6f 6f 6b 73 28 70 53  sionDiffHooks(pS
c580: 65 73 73 69 6f 6e 2c 20 26 64 29 3b 0a 0a 20 20  ession, &d);..  
c590: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e  sqlite3_mutex_en
c5a0: 74 65 72 28 73 71 6c 69 74 65 33 5f 64 62 5f 6d  ter(sqlite3_db_m
c5b0: 75 74 65 78 28 70 53 65 73 73 69 6f 6e 2d 3e 64  utex(pSession->d
c5c0: 62 29 29 3b 0a 20 20 69 66 28 20 70 7a 45 72 72  b));.  if( pzErr
c5d0: 4d 73 67 20 29 20 2a 70 7a 45 72 72 4d 73 67 20  Msg ) *pzErrMsg 
c5e0: 3d 20 30 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  = 0;.  if( rc==S
c5f0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
c600: 63 68 61 72 20 2a 7a 45 78 70 72 20 3d 20 30 3b  char *zExpr = 0;
c610: 0a 20 20 20 20 73 71 6c 69 74 65 33 20 2a 64 62  .    sqlite3 *db
c620: 20 3d 20 70 53 65 73 73 69 6f 6e 2d 3e 64 62 3b   = pSession->db;
c630: 0a 20 20 20 20 53 65 73 73 69 6f 6e 54 61 62 6c  .    SessionTabl
c640: 65 20 2a 70 54 6f 3b 20 20 20 20 20 20 20 20 20  e *pTo;         
c650: 20 20 20 2f 2a 20 54 61 62 6c 65 20 7a 54 62 6c     /* Table zTbl
c660: 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 4c 6f 63 61   */..    /* Loca
c670: 74 65 20 61 6e 64 20 69 66 20 6e 65 63 65 73 73  te and if necess
c680: 61 72 79 20 69 6e 69 74 69 61 6c 69 7a 65 20 74  ary initialize t
c690: 68 65 20 74 61 72 67 65 74 20 74 61 62 6c 65 20  he target table 
c6a0: 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 20 20 72 63  object */.    rc
c6b0: 20 3d 20 73 65 73 73 69 6f 6e 46 69 6e 64 54 61   = sessionFindTa
c6c0: 62 6c 65 28 70 53 65 73 73 69 6f 6e 2c 20 7a 54  ble(pSession, zT
c6d0: 62 6c 2c 20 26 70 54 6f 29 3b 0a 20 20 20 20 69  bl, &pTo);.    i
c6e0: 66 28 20 70 54 6f 3d 3d 30 20 29 20 67 6f 74 6f  f( pTo==0 ) goto
c6f0: 20 64 69 66 66 5f 6f 75 74 3b 0a 20 20 20 20 69   diff_out;.    i
c700: 66 28 20 73 65 73 73 69 6f 6e 49 6e 69 74 54 61  f( sessionInitTa
c710: 62 6c 65 28 70 53 65 73 73 69 6f 6e 2c 20 70 54  ble(pSession, pT
c720: 6f 29 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  o) ){.      rc =
c730: 20 70 53 65 73 73 69 6f 6e 2d 3e 72 63 3b 0a 20   pSession->rc;. 
c740: 20 20 20 20 20 67 6f 74 6f 20 64 69 66 66 5f 6f       goto diff_o
c750: 75 74 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  ut;.    }..    /
c760: 2a 20 43 68 65 63 6b 20 74 68 65 20 74 61 62 6c  * Check the tabl
c770: 65 20 73 63 68 65 6d 61 73 20 6d 61 74 63 68 20  e schemas match 
c780: 2a 2f 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  */.    if( rc==S
c790: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
c7a0: 20 20 69 6e 74 20 62 48 61 73 50 6b 20 3d 20 30    int bHasPk = 0
c7b0: 3b 0a 20 20 20 20 20 20 69 6e 74 20 62 4d 69 73  ;.      int bMis
c7c0: 6d 61 74 63 68 20 3d 20 30 3b 0a 20 20 20 20 20  match = 0;.     
c7d0: 20 69 6e 74 20 6e 43 6f 6c 3b 20 20 20 20 20 20   int nCol;      
c7e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c7f0: 43 6f 6c 75 6d 6e 73 20 69 6e 20 7a 46 72 6f 6d  Columns in zFrom
c800: 2e 7a 54 62 6c 20 2a 2f 0a 20 20 20 20 20 20 75  .zTbl */.      u
c810: 38 20 2a 61 62 50 4b 3b 0a 20 20 20 20 20 20 63  8 *abPK;.      c
c820: 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a 43 6f  onst char **azCo
c830: 6c 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 63 20  l = 0;.      rc 
c840: 3d 20 73 65 73 73 69 6f 6e 54 61 62 6c 65 49 6e  = sessionTableIn
c850: 66 6f 28 64 62 2c 20 7a 46 72 6f 6d 2c 20 7a 54  fo(db, zFrom, zT
c860: 62 6c 2c 20 26 6e 43 6f 6c 2c 20 30 2c 20 26 61  bl, &nCol, 0, &a
c870: 7a 43 6f 6c 2c 20 26 61 62 50 4b 29 3b 0a 20 20  zCol, &abPK);.  
c880: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
c890: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  TE_OK ){.       
c8a0: 20 69 66 28 20 70 54 6f 2d 3e 6e 43 6f 6c 21 3d   if( pTo->nCol!=
c8b0: 6e 43 6f 6c 20 29 7b 0a 20 20 20 20 20 20 20 20  nCol ){.        
c8c0: 20 20 62 4d 69 73 6d 61 74 63 68 20 3d 20 31 3b    bMismatch = 1;
c8d0: 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  .        }else{.
c8e0: 20 20 20 20 20 20 20 20 20 20 69 6e 74 20 69 3b            int i;
c8f0: 0a 20 20 20 20 20 20 20 20 20 20 66 6f 72 28 69  .          for(i
c900: 3d 30 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29  =0; i<nCol; i++)
c910: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  {.            if
c920: 28 20 70 54 6f 2d 3e 61 62 50 4b 5b 69 5d 21 3d  ( pTo->abPK[i]!=
c930: 61 62 50 4b 5b 69 5d 20 29 20 62 4d 69 73 6d 61  abPK[i] ) bMisma
c940: 74 63 68 20 3d 20 31 3b 0a 20 20 20 20 20 20 20  tch = 1;.       
c950: 20 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33       if( sqlite3
c960: 5f 73 74 72 69 63 6d 70 28 61 7a 43 6f 6c 5b 69  _stricmp(azCol[i
c970: 5d 2c 20 70 54 6f 2d 3e 61 7a 43 6f 6c 5b 69 5d  ], pTo->azCol[i]
c980: 29 20 29 20 62 4d 69 73 6d 61 74 63 68 20 3d 20  ) ) bMismatch = 
c990: 31 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  1;.            i
c9a0: 66 28 20 61 62 50 4b 5b 69 5d 20 29 20 62 48 61  f( abPK[i] ) bHa
c9b0: 73 50 6b 20 3d 20 31 3b 0a 20 20 20 20 20 20 20  sPk = 1;.       
c9c0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20     }.        }. 
c9d0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73 71 6c       }.      sql
c9e0: 69 74 65 33 5f 66 72 65 65 28 28 63 68 61 72 2a  ite3_free((char*
c9f0: 29 61 7a 43 6f 6c 29 3b 0a 20 20 20 20 20 20 69  )azCol);.      i
ca00: 66 28 20 62 4d 69 73 6d 61 74 63 68 20 29 7b 0a  f( bMismatch ){.
ca10: 20 20 20 20 20 20 20 20 2a 70 7a 45 72 72 4d 73          *pzErrMs
ca20: 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  g = sqlite3_mpri
ca30: 6e 74 66 28 22 74 61 62 6c 65 20 73 63 68 65 6d  ntf("table schem
ca40: 61 73 20 64 6f 20 6e 6f 74 20 6d 61 74 63 68 22  as do not match"
ca50: 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  );.        rc = 
ca60: 53 51 4c 49 54 45 5f 53 43 48 45 4d 41 3b 0a 20  SQLITE_SCHEMA;. 
ca70: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
ca80: 20 62 48 61 73 50 6b 3d 3d 30 20 29 7b 0a 20 20   bHasPk==0 ){.  
ca90: 20 20 20 20 20 20 2f 2a 20 49 67 6e 6f 72 65 20        /* Ignore 
caa0: 74 61 62 6c 65 73 20 77 69 74 68 20 6e 6f 20 70  tables with no p
cab0: 72 69 6d 61 72 79 20 6b 65 79 73 20 2a 2f 0a 20  rimary keys */. 
cac0: 20 20 20 20 20 20 20 67 6f 74 6f 20 64 69 66 66         goto diff
cad0: 5f 6f 75 74 3b 0a 20 20 20 20 20 20 7d 0a 20 20  _out;.      }.  
cae0: 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72 63 3d    }..    if( rc=
caf0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
cb00: 20 20 20 20 7a 45 78 70 72 20 3d 20 73 65 73 73      zExpr = sess
cb10: 69 6f 6e 45 78 70 72 43 6f 6d 70 61 72 65 50 4b  ionExprComparePK
cb20: 28 70 54 6f 2d 3e 6e 43 6f 6c 2c 20 0a 20 20 20  (pTo->nCol, .   
cb30: 20 20 20 20 20 20 20 7a 44 62 2c 20 7a 46 72 6f         zDb, zFro
cb40: 6d 2c 20 70 54 6f 2d 3e 7a 4e 61 6d 65 2c 20 70  m, pTo->zName, p
cb50: 54 6f 2d 3e 61 7a 43 6f 6c 2c 20 70 54 6f 2d 3e  To->azCol, pTo->
cb60: 61 62 50 4b 0a 20 20 20 20 20 20 29 3b 0a 20 20  abPK.      );.  
cb70: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 46 69 6e 64    }..    /* Find
cb80: 20 6e 65 77 20 72 6f 77 73 20 2a 2f 0a 20 20 20   new rows */.   
cb90: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
cba0: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  OK ){.      rc =
cbb0: 20 73 65 73 73 69 6f 6e 44 69 66 66 46 69 6e 64   sessionDiffFind
cbc0: 4e 65 77 28 53 51 4c 49 54 45 5f 49 4e 53 45 52  New(SQLITE_INSER
cbd0: 54 2c 20 70 53 65 73 73 69 6f 6e 2c 20 70 54 6f  T, pSession, pTo
cbe0: 2c 20 7a 44 62 2c 20 7a 46 72 6f 6d 2c 20 7a 45  , zDb, zFrom, zE
cbf0: 78 70 72 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  xpr);.    }..   
cc00: 20 2f 2a 20 46 69 6e 64 20 6f 6c 64 20 72 6f 77   /* Find old row
cc10: 73 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63 3d  s */.    if( rc=
cc20: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
cc30: 20 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e      rc = session
cc40: 44 69 66 66 46 69 6e 64 4e 65 77 28 53 51 4c 49  DiffFindNew(SQLI
cc50: 54 45 5f 44 45 4c 45 54 45 2c 20 70 53 65 73 73  TE_DELETE, pSess
cc60: 69 6f 6e 2c 20 70 54 6f 2c 20 7a 46 72 6f 6d 2c  ion, pTo, zFrom,
cc70: 20 7a 44 62 2c 20 7a 45 78 70 72 29 3b 0a 20 20   zDb, zExpr);.  
cc80: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 46 69 6e 64    }..    /* Find
cc90: 20 6d 6f 64 69 66 69 65 64 20 72 6f 77 73 20 2a   modified rows *
cca0: 2f 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  /.    if( rc==SQ
ccb0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
ccc0: 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 44 69 66   rc = sessionDif
ccd0: 66 46 69 6e 64 4d 6f 64 69 66 69 65 64 28 70 53  fFindModified(pS
cce0: 65 73 73 69 6f 6e 2c 20 70 54 6f 2c 20 7a 46 72  ession, pTo, zFr
ccf0: 6f 6d 2c 20 7a 45 78 70 72 29 3b 0a 20 20 20 20  om, zExpr);.    
cd00: 7d 0a 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  }..    sqlite3_f
cd10: 72 65 65 28 7a 45 78 70 72 29 3b 0a 20 20 7d 0a  ree(zExpr);.  }.
cd20: 0a 20 64 69 66 66 5f 6f 75 74 3a 0a 20 20 73 65  . diff_out:.  se
cd30: 73 73 69 6f 6e 50 72 65 75 70 64 61 74 65 48 6f  ssionPreupdateHo
cd40: 6f 6b 73 28 70 53 65 73 73 69 6f 6e 29 3b 0a 20  oks(pSession);. 
cd50: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c   sqlite3_mutex_l
cd60: 65 61 76 65 28 73 71 6c 69 74 65 33 5f 64 62 5f  eave(sqlite3_db_
cd70: 6d 75 74 65 78 28 70 53 65 73 73 69 6f 6e 2d 3e  mutex(pSession->
cd80: 64 62 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  db));.  return r
cd90: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72 65 61  c;.}../*.** Crea
cda0: 74 65 20 61 20 73 65 73 73 69 6f 6e 20 6f 62 6a  te a session obj
cdb0: 65 63 74 2e 20 54 68 69 73 20 73 65 73 73 69 6f  ect. This sessio
cdc0: 6e 20 6f 62 6a 65 63 74 20 77 69 6c 6c 20 72 65  n object will re
cdd0: 63 6f 72 64 20 63 68 61 6e 67 65 73 20 74 6f 0a  cord changes to.
cde0: 2a 2a 20 64 61 74 61 62 61 73 65 20 7a 44 62 20  ** database zDb 
cdf0: 61 74 74 61 63 68 65 64 20 74 6f 20 63 6f 6e 6e  attached to conn
ce00: 65 63 74 69 6f 6e 20 64 62 2e 0a 2a 2f 0a 69 6e  ection db..*/.in
ce10: 74 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e  t sqlite3session
ce20: 5f 63 72 65 61 74 65 28 0a 20 20 73 71 6c 69 74  _create(.  sqlit
ce30: 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20  e3 *db,         
ce40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
ce50: 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f  tabase handle */
ce60: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
ce70: 44 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  Db,             
ce80: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 64 62     /* Name of db
ce90: 20 28 65 2e 67 2e 20 22 6d 61 69 6e 22 29 20 2a   (e.g. "main") *
cea0: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73 65 73 73  /.  sqlite3_sess
ceb0: 69 6f 6e 20 2a 2a 70 70 53 65 73 73 69 6f 6e 20  ion **ppSession 
cec0: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 65 77 20      /* OUT: New 
ced0: 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 2a  session object *
cee0: 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73  /.){.  sqlite3_s
cef0: 65 73 73 69 6f 6e 20 2a 70 4e 65 77 3b 20 20 20  ession *pNew;   
cf00: 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 6c 79 20         /* Newly 
cf10: 61 6c 6c 6f 63 61 74 65 64 20 73 65 73 73 69 6f  allocated sessio
cf20: 6e 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 73 71  n object */.  sq
cf30: 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70  lite3_session *p
cf40: 4f 6c 64 3b 20 20 20 20 20 20 20 20 20 20 2f 2a  Old;          /*
cf50: 20 53 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20   Session object 
cf60: 61 6c 72 65 61 64 79 20 61 74 74 61 63 68 65 64  already attached
cf70: 20 74 6f 20 64 62 20 2a 2f 0a 20 20 69 6e 74 20   to db */.  int 
cf80: 6e 44 62 20 3d 20 73 71 6c 69 74 65 33 53 74 72  nDb = sqlite3Str
cf90: 6c 65 6e 33 30 28 7a 44 62 29 3b 20 2f 2a 20 4c  len30(zDb); /* L
cfa0: 65 6e 67 74 68 20 6f 66 20 7a 44 62 20 69 6e 20  ength of zDb in 
cfb0: 62 79 74 65 73 20 2a 2f 0a 0a 20 20 2f 2a 20 5a  bytes */..  /* Z
cfc0: 65 72 6f 20 74 68 65 20 6f 75 74 70 75 74 20 76  ero the output v
cfd0: 61 6c 75 65 20 69 6e 20 63 61 73 65 20 61 6e 20  alue in case an 
cfe0: 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 20 2a 2f  error occurs. */
cff0: 0a 20 20 2a 70 70 53 65 73 73 69 6f 6e 20 3d 20  .  *ppSession = 
d000: 30 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74  0;..  /* Allocat
d010: 65 20 61 6e 64 20 70 6f 70 75 6c 61 74 65 20 74  e and populate t
d020: 68 65 20 6e 65 77 20 73 65 73 73 69 6f 6e 20 6f  he new session o
d030: 62 6a 65 63 74 2e 20 2a 2f 0a 20 20 70 4e 65 77  bject. */.  pNew
d040: 20 3d 20 28 73 71 6c 69 74 65 33 5f 73 65 73 73   = (sqlite3_sess
d050: 69 6f 6e 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61  ion *)sqlite3_ma
d060: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 73 71 6c 69  lloc(sizeof(sqli
d070: 74 65 33 5f 73 65 73 73 69 6f 6e 29 20 2b 20 6e  te3_session) + n
d080: 44 62 20 2b 20 31 29 3b 0a 20 20 69 66 28 20 21  Db + 1);.  if( !
d090: 70 4e 65 77 20 29 20 72 65 74 75 72 6e 20 53 51  pNew ) return SQ
d0a0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d 65  LITE_NOMEM;.  me
d0b0: 6d 73 65 74 28 70 4e 65 77 2c 20 30 2c 20 73 69  mset(pNew, 0, si
d0c0: 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f 73 65 73  zeof(sqlite3_ses
d0d0: 73 69 6f 6e 29 29 3b 0a 20 20 70 4e 65 77 2d 3e  sion));.  pNew->
d0e0: 64 62 20 3d 20 64 62 3b 0a 20 20 70 4e 65 77 2d  db = db;.  pNew-
d0f0: 3e 7a 44 62 20 3d 20 28 63 68 61 72 20 2a 29 26  >zDb = (char *)&
d100: 70 4e 65 77 5b 31 5d 3b 0a 20 20 70 4e 65 77 2d  pNew[1];.  pNew-
d110: 3e 62 45 6e 61 62 6c 65 20 3d 20 31 3b 0a 20 20  >bEnable = 1;.  
d120: 6d 65 6d 63 70 79 28 70 4e 65 77 2d 3e 7a 44 62  memcpy(pNew->zDb
d130: 2c 20 7a 44 62 2c 20 6e 44 62 2b 31 29 3b 0a 20  , zDb, nDb+1);. 
d140: 20 73 65 73 73 69 6f 6e 50 72 65 75 70 64 61 74   sessionPreupdat
d150: 65 48 6f 6f 6b 73 28 70 4e 65 77 29 3b 0a 0a 20  eHooks(pNew);.. 
d160: 20 2f 2a 20 41 64 64 20 74 68 65 20 6e 65 77 20   /* Add the new 
d170: 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 74  session object t
d180: 6f 20 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73  o the linked lis
d190: 74 20 6f 66 20 73 65 73 73 69 6f 6e 20 6f 62 6a  t of session obj
d1a0: 65 63 74 73 20 0a 20 20 2a 2a 20 61 74 74 61 63  ects .  ** attac
d1b0: 68 65 64 20 74 6f 20 64 61 74 61 62 61 73 65 20  hed to database 
d1c0: 68 61 6e 64 6c 65 20 24 64 62 2e 20 44 6f 20 74  handle $db. Do t
d1d0: 68 69 73 20 75 6e 64 65 72 20 74 68 65 20 63 6f  his under the co
d1e0: 76 65 72 20 6f 66 20 74 68 65 20 64 62 0a 20 20  ver of the db.  
d1f0: 2a 2a 20 68 61 6e 64 6c 65 20 6d 75 74 65 78 2e  ** handle mutex.
d200: 20 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 6d    */.  sqlite3_m
d210: 75 74 65 78 5f 65 6e 74 65 72 28 73 71 6c 69 74  utex_enter(sqlit
d220: 65 33 5f 64 62 5f 6d 75 74 65 78 28 64 62 29 29  e3_db_mutex(db))
d230: 3b 0a 20 20 70 4f 6c 64 20 3d 20 28 73 71 6c 69  ;.  pOld = (sqli
d240: 74 65 33 5f 73 65 73 73 69 6f 6e 2a 29 73 71 6c  te3_session*)sql
d250: 69 74 65 33 5f 70 72 65 75 70 64 61 74 65 5f 68  ite3_preupdate_h
d260: 6f 6f 6b 28 64 62 2c 20 78 50 72 65 55 70 64 61  ook(db, xPreUpda
d270: 74 65 2c 20 28 76 6f 69 64 2a 29 70 4e 65 77 29  te, (void*)pNew)
d280: 3b 0a 20 20 70 4e 65 77 2d 3e 70 4e 65 78 74 20  ;.  pNew->pNext 
d290: 3d 20 70 4f 6c 64 3b 0a 20 20 73 71 6c 69 74 65  = pOld;.  sqlite
d2a0: 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 73 71  3_mutex_leave(sq
d2b0: 6c 69 74 65 33 5f 64 62 5f 6d 75 74 65 78 28 64  lite3_db_mutex(d
d2c0: 62 29 29 3b 0a 0a 20 20 2a 70 70 53 65 73 73 69  b));..  *ppSessi
d2d0: 6f 6e 20 3d 20 70 4e 65 77 3b 0a 20 20 72 65 74  on = pNew;.  ret
d2e0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
d2f0: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 74 68 65  ../*.** Free the
d300: 20 6c 69 73 74 20 6f 66 20 74 61 62 6c 65 20 6f   list of table o
d310: 62 6a 65 63 74 73 20 70 61 73 73 65 64 20 61 73  bjects passed as
d320: 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d   the first argum
d330: 65 6e 74 2e 20 54 68 65 20 63 6f 6e 74 65 6e 74  ent. The content
d340: 73 0a 2a 2a 20 6f 66 20 74 68 65 20 63 68 61 6e  s.** of the chan
d350: 67 65 64 2d 72 6f 77 73 20 68 61 73 68 20 74 61  ged-rows hash ta
d360: 62 6c 65 73 20 61 72 65 20 61 6c 73 6f 20 64 65  bles are also de
d370: 6c 65 74 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  leted..*/.static
d380: 20 76 6f 69 64 20 73 65 73 73 69 6f 6e 44 65 6c   void sessionDel
d390: 65 74 65 54 61 62 6c 65 28 53 65 73 73 69 6f 6e  eteTable(Session
d3a0: 54 61 62 6c 65 20 2a 70 4c 69 73 74 29 7b 0a 20  Table *pList){. 
d3b0: 20 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70   SessionTable *p
d3c0: 4e 65 78 74 3b 0a 20 20 53 65 73 73 69 6f 6e 54  Next;.  SessionT
d3d0: 61 62 6c 65 20 2a 70 54 61 62 3b 0a 0a 20 20 66  able *pTab;..  f
d3e0: 6f 72 28 70 54 61 62 3d 70 4c 69 73 74 3b 20 70  or(pTab=pList; p
d3f0: 54 61 62 3b 20 70 54 61 62 3d 70 4e 65 78 74 29  Tab; pTab=pNext)
d400: 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20  {.    int i;.   
d410: 20 70 4e 65 78 74 20 3d 20 70 54 61 62 2d 3e 70   pNext = pTab->p
d420: 4e 65 78 74 3b 0a 20 20 20 20 66 6f 72 28 69 3d  Next;.    for(i=
d430: 30 3b 20 69 3c 70 54 61 62 2d 3e 6e 43 68 61 6e  0; i<pTab->nChan
d440: 67 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  ge; i++){.      
d450: 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 70  SessionChange *p
d460: 3b 0a 20 20 20 20 20 20 53 65 73 73 69 6f 6e 43  ;.      SessionC
d470: 68 61 6e 67 65 20 2a 70 4e 65 78 74 43 68 61 6e  hange *pNextChan
d480: 67 65 3b 0a 20 20 20 20 20 20 66 6f 72 28 70 3d  ge;.      for(p=
d490: 70 54 61 62 2d 3e 61 70 43 68 61 6e 67 65 5b 69  pTab->apChange[i
d4a0: 5d 3b 20 70 3b 20 70 3d 70 4e 65 78 74 43 68 61  ]; p; p=pNextCha
d4b0: 6e 67 65 29 7b 0a 20 20 20 20 20 20 20 20 70 4e  nge){.        pN
d4c0: 65 78 74 43 68 61 6e 67 65 20 3d 20 70 2d 3e 70  extChange = p->p
d4d0: 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20 73 71  Next;.        sq
d4e0: 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20  lite3_free(p);. 
d4f0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
d500: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 28 63   sqlite3_free((c
d510: 68 61 72 2a 29 70 54 61 62 2d 3e 61 7a 43 6f 6c  har*)pTab->azCol
d520: 29 3b 20 20 2f 2a 20 63 61 73 74 20 77 6f 72 6b  );  /* cast work
d530: 73 20 61 72 6f 75 6e 64 20 56 43 2b 2b 20 62 75  s around VC++ bu
d540: 67 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33  g */.    sqlite3
d550: 5f 66 72 65 65 28 70 54 61 62 2d 3e 61 70 43 68  _free(pTab->apCh
d560: 61 6e 67 65 29 3b 0a 20 20 20 20 73 71 6c 69 74  ange);.    sqlit
d570: 65 33 5f 66 72 65 65 28 70 54 61 62 29 3b 0a 20  e3_free(pTab);. 
d580: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c 65   }.}../*.** Dele
d590: 74 65 20 61 20 73 65 73 73 69 6f 6e 20 6f 62 6a  te a session obj
d5a0: 65 63 74 20 70 72 65 76 69 6f 75 73 6c 79 20 61  ect previously a
d5b0: 6c 6c 6f 63 61 74 65 64 20 75 73 69 6e 67 20 73  llocated using s
d5c0: 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 63 72  qlite3session_cr
d5d0: 65 61 74 65 28 29 2e 0a 2a 2f 0a 76 6f 69 64 20  eate()..*/.void 
d5e0: 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 64  sqlite3session_d
d5f0: 65 6c 65 74 65 28 73 71 6c 69 74 65 33 5f 73 65  elete(sqlite3_se
d600: 73 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f 6e 29  ssion *pSession)
d610: 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20  {.  sqlite3 *db 
d620: 3d 20 70 53 65 73 73 69 6f 6e 2d 3e 64 62 3b 0a  = pSession->db;.
d630: 20 20 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f    sqlite3_sessio
d640: 6e 20 2a 70 48 65 61 64 3b 0a 20 20 73 71 6c 69  n *pHead;.  sqli
d650: 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 2a 70 70  te3_session **pp
d660: 3b 0a 0a 20 20 2f 2a 20 55 6e 6c 69 6e 6b 20 74  ;..  /* Unlink t
d670: 68 65 20 73 65 73 73 69 6f 6e 20 66 72 6f 6d 20  he session from 
d680: 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20  the linked list 
d690: 6f 66 20 73 65 73 73 69 6f 6e 73 20 61 74 74 61  of sessions atta
d6a0: 63 68 65 64 20 74 6f 20 74 68 65 0a 20 20 2a 2a  ched to the.  **
d6b0: 20 64 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65   database handle
d6c0: 2e 20 48 6f 6c 64 20 74 68 65 20 64 62 20 6d 75  . Hold the db mu
d6d0: 74 65 78 20 77 68 69 6c 65 20 64 6f 69 6e 67 20  tex while doing 
d6e0: 73 6f 2e 20 20 2a 2f 0a 20 20 73 71 6c 69 74 65  so.  */.  sqlite
d6f0: 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 73 71  3_mutex_enter(sq
d700: 6c 69 74 65 33 5f 64 62 5f 6d 75 74 65 78 28 64  lite3_db_mutex(d
d710: 62 29 29 3b 0a 20 20 70 48 65 61 64 20 3d 20 28  b));.  pHead = (
d720: 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 2a  sqlite3_session*
d730: 29 73 71 6c 69 74 65 33 5f 70 72 65 75 70 64 61  )sqlite3_preupda
d740: 74 65 5f 68 6f 6f 6b 28 64 62 2c 20 30 2c 20 30  te_hook(db, 0, 0
d750: 29 3b 0a 20 20 66 6f 72 28 70 70 3d 26 70 48 65  );.  for(pp=&pHe
d760: 61 64 3b 20 41 4c 57 41 59 53 28 28 2a 70 70 29  ad; ALWAYS((*pp)
d770: 21 3d 30 29 3b 20 70 70 3d 26 28 28 2a 70 70 29  !=0); pp=&((*pp)
d780: 2d 3e 70 4e 65 78 74 29 29 7b 0a 20 20 20 20 69  ->pNext)){.    i
d790: 66 28 20 28 2a 70 70 29 3d 3d 70 53 65 73 73 69  f( (*pp)==pSessi
d7a0: 6f 6e 20 29 7b 0a 20 20 20 20 20 20 2a 70 70 20  on ){.      *pp 
d7b0: 3d 20 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a  = (*pp)->pNext;.
d7c0: 20 20 20 20 20 20 69 66 28 20 70 48 65 61 64 20        if( pHead 
d7d0: 29 20 73 71 6c 69 74 65 33 5f 70 72 65 75 70 64  ) sqlite3_preupd
d7e0: 61 74 65 5f 68 6f 6f 6b 28 64 62 2c 20 78 50 72  ate_hook(db, xPr
d7f0: 65 55 70 64 61 74 65 2c 20 28 76 6f 69 64 2a 29  eUpdate, (void*)
d800: 70 48 65 61 64 29 3b 0a 20 20 20 20 20 20 62 72  pHead);.      br
d810: 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  eak;.    }.  }. 
d820: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c   sqlite3_mutex_l
d830: 65 61 76 65 28 73 71 6c 69 74 65 33 5f 64 62 5f  eave(sqlite3_db_
d840: 6d 75 74 65 78 28 64 62 29 29 3b 0a 20 20 73 71  mutex(db));.  sq
d850: 6c 69 74 65 33 56 61 6c 75 65 46 72 65 65 28 70  lite3ValueFree(p
d860: 53 65 73 73 69 6f 6e 2d 3e 70 5a 65 72 6f 42 6c  Session->pZeroBl
d870: 6f 62 29 3b 0a 0a 20 20 2f 2a 20 44 65 6c 65 74  ob);..  /* Delet
d880: 65 20 61 6c 6c 20 61 74 74 61 63 68 65 64 20 74  e all attached t
d890: 61 62 6c 65 20 6f 62 6a 65 63 74 73 2e 20 41 6e  able objects. An
d8a0: 64 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  d the contents o
d8b0: 66 20 74 68 65 69 72 20 0a 20 20 2a 2a 20 61 73  f their .  ** as
d8c0: 73 6f 63 69 61 74 65 64 20 68 61 73 68 2d 74 61  sociated hash-ta
d8d0: 62 6c 65 73 2e 20 2a 2f 0a 20 20 73 65 73 73 69  bles. */.  sessi
d8e0: 6f 6e 44 65 6c 65 74 65 54 61 62 6c 65 28 70 53  onDeleteTable(pS
d8f0: 65 73 73 69 6f 6e 2d 3e 70 54 61 62 6c 65 29 3b  ession->pTable);
d900: 0a 0a 20 20 2f 2a 20 46 72 65 65 20 74 68 65 20  ..  /* Free the 
d910: 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 69  session object i
d920: 74 73 65 6c 66 2e 20 2a 2f 0a 20 20 73 71 6c 69  tself. */.  sqli
d930: 74 65 33 5f 66 72 65 65 28 70 53 65 73 73 69 6f  te3_free(pSessio
d940: 6e 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74  n);.}../*.** Set
d950: 20 61 20 74 61 62 6c 65 20 66 69 6c 74 65 72 20   a table filter 
d960: 6f 6e 20 61 20 53 65 73 73 69 6f 6e 20 4f 62 6a  on a Session Obj
d970: 65 63 74 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  ect..*/.void sql
d980: 69 74 65 33 73 65 73 73 69 6f 6e 5f 74 61 62 6c  ite3session_tabl
d990: 65 5f 66 69 6c 74 65 72 28 0a 20 20 73 71 6c 69  e_filter(.  sqli
d9a0: 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65  te3_session *pSe
d9b0: 73 73 69 6f 6e 2c 20 0a 20 20 69 6e 74 28 2a 78  ssion, .  int(*x
d9c0: 46 69 6c 74 65 72 29 28 76 6f 69 64 2a 2c 20 63  Filter)(void*, c
d9d0: 6f 6e 73 74 20 63 68 61 72 2a 29 2c 0a 20 20 76  onst char*),.  v
d9e0: 6f 69 64 20 2a 70 43 74 78 20 20 20 20 20 20 20  oid *pCtx       
d9f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
da00: 2a 20 46 69 72 73 74 20 61 72 67 75 6d 65 6e 74  * First argument
da10: 20 70 61 73 73 65 64 20 74 6f 20 78 46 69 6c 74   passed to xFilt
da20: 65 72 20 2a 2f 0a 29 7b 0a 20 20 70 53 65 73 73  er */.){.  pSess
da30: 69 6f 6e 2d 3e 62 41 75 74 6f 41 74 74 61 63 68  ion->bAutoAttach
da40: 20 3d 20 31 3b 0a 20 20 70 53 65 73 73 69 6f 6e   = 1;.  pSession
da50: 2d 3e 70 46 69 6c 74 65 72 43 74 78 20 3d 20 70  ->pFilterCtx = p
da60: 43 74 78 3b 0a 20 20 70 53 65 73 73 69 6f 6e 2d  Ctx;.  pSession-
da70: 3e 78 54 61 62 6c 65 46 69 6c 74 65 72 20 3d 20  >xTableFilter = 
da80: 78 46 69 6c 74 65 72 3b 0a 7d 0a 0a 2f 2a 0a 2a  xFilter;.}../*.*
da90: 2a 20 41 74 74 61 63 68 20 61 20 74 61 62 6c 65  * Attach a table
daa0: 20 74 6f 20 61 20 73 65 73 73 69 6f 6e 2e 20 41   to a session. A
dab0: 6c 6c 20 73 75 62 73 65 71 75 65 6e 74 20 63 68  ll subsequent ch
dac0: 61 6e 67 65 73 20 6d 61 64 65 20 74 6f 20 74 68  anges made to th
dad0: 65 20 74 61 62 6c 65 0a 2a 2a 20 77 68 69 6c 65  e table.** while
dae0: 20 74 68 65 20 73 65 73 73 69 6f 6e 20 6f 62 6a   the session obj
daf0: 65 63 74 20 69 73 20 65 6e 61 62 6c 65 64 20 77  ect is enabled w
db00: 69 6c 6c 20 62 65 20 72 65 63 6f 72 64 65 64 2e  ill be recorded.
db10: 0a 2a 2a 0a 2a 2a 20 4f 6e 6c 79 20 74 61 62 6c  .**.** Only tabl
db20: 65 73 20 74 68 61 74 20 68 61 76 65 20 61 20 50  es that have a P
db30: 52 49 4d 41 52 59 20 4b 45 59 20 64 65 66 69 6e  RIMARY KEY defin
db40: 65 64 20 6d 61 79 20 62 65 20 61 74 74 61 63 68  ed may be attach
db50: 65 64 2e 20 49 74 20 64 6f 65 73 0a 2a 2a 20 6e  ed. It does.** n
db60: 6f 74 20 6d 61 74 74 65 72 20 69 66 20 74 68 65  ot matter if the
db70: 20 50 52 49 4d 41 52 59 20 4b 45 59 20 69 73 20   PRIMARY KEY is 
db80: 61 6e 20 22 49 4e 54 45 47 45 52 20 50 52 49 4d  an "INTEGER PRIM
db90: 41 52 59 20 4b 45 59 22 20 28 72 6f 77 69 64 20  ARY KEY" (rowid 
dba0: 61 6c 69 61 73 29 0a 2a 2a 20 6f 72 20 6e 6f 74  alias).** or not
dbb0: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
dbc0: 73 65 73 73 69 6f 6e 5f 61 74 74 61 63 68 28 0a  session_attach(.
dbd0: 20 20 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f    sqlite3_sessio
dbe0: 6e 20 2a 70 53 65 73 73 69 6f 6e 2c 20 20 20 20  n *pSession,    
dbf0: 20 20 2f 2a 20 53 65 73 73 69 6f 6e 20 6f 62 6a    /* Session obj
dc00: 65 63 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  ect */.  const c
dc10: 68 61 72 20 2a 7a 4e 61 6d 65 20 20 20 20 20 20  har *zName      
dc20: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62 6c           /* Tabl
dc30: 65 20 6e 61 6d 65 20 2a 2f 0a 29 7b 0a 20 20 69  e name */.){.  i
dc40: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
dc50: 4b 3b 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74  K;.  sqlite3_mut
dc60: 65 78 5f 65 6e 74 65 72 28 73 71 6c 69 74 65 33  ex_enter(sqlite3
dc70: 5f 64 62 5f 6d 75 74 65 78 28 70 53 65 73 73 69  _db_mutex(pSessi
dc80: 6f 6e 2d 3e 64 62 29 29 3b 0a 0a 20 20 69 66 28  on->db));..  if(
dc90: 20 21 7a 4e 61 6d 65 20 29 7b 0a 20 20 20 20 70   !zName ){.    p
dca0: 53 65 73 73 69 6f 6e 2d 3e 62 41 75 74 6f 41 74  Session->bAutoAt
dcb0: 74 61 63 68 20 3d 20 31 3b 0a 20 20 7d 65 6c 73  tach = 1;.  }els
dcc0: 65 7b 0a 20 20 20 20 53 65 73 73 69 6f 6e 54 61  e{.    SessionTa
dcd0: 62 6c 65 20 2a 70 54 61 62 3b 20 20 20 20 20 20  ble *pTab;      
dce0: 20 20 20 20 20 2f 2a 20 4e 65 77 20 74 61 62 6c       /* New tabl
dcf0: 65 20 6f 62 6a 65 63 74 20 28 69 66 20 72 65 71  e object (if req
dd00: 75 69 72 65 64 29 20 2a 2f 0a 20 20 20 20 69 6e  uired) */.    in
dd10: 74 20 6e 4e 61 6d 65 3b 20 20 20 20 20 20 20 20  t nName;        
dd20: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
dd30: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69  umber of bytes i
dd40: 6e 20 73 74 72 69 6e 67 20 7a 4e 61 6d 65 20 2a  n string zName *
dd50: 2f 0a 0a 20 20 20 20 2f 2a 20 46 69 72 73 74 20  /..    /* First 
dd60: 73 65 61 72 63 68 20 66 6f 72 20 61 6e 20 65 78  search for an ex
dd70: 69 73 74 69 6e 67 20 65 6e 74 72 79 2e 20 49 66  isting entry. If
dd80: 20 6f 6e 65 20 69 73 20 66 6f 75 6e 64 2c 20 74   one is found, t
dd90: 68 69 73 20 63 61 6c 6c 20 69 73 0a 20 20 20 20  his call is.    
dda0: 2a 2a 20 61 20 6e 6f 2d 6f 70 2e 20 52 65 74 75  ** a no-op. Retu
ddb0: 72 6e 20 65 61 72 6c 79 2e 20 2a 2f 0a 20 20 20  rn early. */.   
ddc0: 20 6e 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33   nName = sqlite3
ddd0: 53 74 72 6c 65 6e 33 30 28 7a 4e 61 6d 65 29 3b  Strlen30(zName);
dde0: 0a 20 20 20 20 66 6f 72 28 70 54 61 62 3d 70 53  .    for(pTab=pS
ddf0: 65 73 73 69 6f 6e 2d 3e 70 54 61 62 6c 65 3b 20  ession->pTable; 
de00: 70 54 61 62 3b 20 70 54 61 62 3d 70 54 61 62 2d  pTab; pTab=pTab-
de10: 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 69  >pNext){.      i
de20: 66 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74  f( 0==sqlite3_st
de30: 72 6e 69 63 6d 70 28 70 54 61 62 2d 3e 7a 4e 61  rnicmp(pTab->zNa
de40: 6d 65 2c 20 7a 4e 61 6d 65 2c 20 6e 4e 61 6d 65  me, zName, nName
de50: 2b 31 29 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  +1) ) break;.   
de60: 20 7d 0a 0a 20 20 20 20 69 66 28 20 21 70 54 61   }..    if( !pTa
de70: 62 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 41 6c  b ){.      /* Al
de80: 6c 6f 63 61 74 65 20 6e 65 77 20 53 65 73 73 69  locate new Sessi
de90: 6f 6e 54 61 62 6c 65 20 6f 62 6a 65 63 74 2e 20  onTable object. 
dea0: 2a 2f 0a 20 20 20 20 20 20 70 54 61 62 20 3d 20  */.      pTab = 
deb0: 28 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 29  (SessionTable *)
dec0: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73  sqlite3_malloc(s
ded0: 69 7a 65 6f 66 28 53 65 73 73 69 6f 6e 54 61 62  izeof(SessionTab
dee0: 6c 65 29 20 2b 20 6e 4e 61 6d 65 20 2b 20 31 29  le) + nName + 1)
def0: 3b 0a 20 20 20 20 20 20 69 66 28 20 21 70 54 61  ;.      if( !pTa
df00: 62 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  b ){.        rc 
df10: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
df20: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
df30: 20 20 20 20 20 2f 2a 20 50 6f 70 75 6c 61 74 65       /* Populate
df40: 20 74 68 65 20 6e 65 77 20 53 65 73 73 69 6f 6e   the new Session
df50: 54 61 62 6c 65 20 6f 62 6a 65 63 74 20 61 6e 64  Table object and
df60: 20 6c 69 6e 6b 20 69 74 20 69 6e 74 6f 20 74 68   link it into th
df70: 65 20 6c 69 73 74 2e 0a 20 20 20 20 20 20 20 20  e list..        
df80: 2a 2a 20 54 68 65 20 6e 65 77 20 6f 62 6a 65 63  ** The new objec
df90: 74 20 6d 75 73 74 20 62 65 20 6c 69 6e 6b 65 64  t must be linked
dfa0: 20 6f 6e 74 6f 20 74 68 65 20 65 6e 64 20 6f 66   onto the end of
dfb0: 20 74 68 65 20 6c 69 73 74 2c 20 6e 6f 74 20 0a   the list, not .
dfc0: 20 20 20 20 20 20 20 20 2a 2a 20 73 69 6d 70 6c          ** simpl
dfd0: 79 20 61 64 64 65 64 20 74 6f 20 74 68 65 20 73  y added to the s
dfe0: 74 61 72 74 20 6f 66 20 69 74 20 69 6e 20 6f 72  tart of it in or
dff0: 64 65 72 20 74 6f 20 65 6e 73 75 72 65 20 74 68  der to ensure th
e000: 61 74 20 74 61 62 6c 65 73 0a 20 20 20 20 20 20  at tables.      
e010: 20 20 2a 2a 20 61 70 70 65 61 72 20 69 6e 20 74    ** appear in t
e020: 68 65 20 63 6f 72 72 65 63 74 20 6f 72 64 65 72  he correct order
e030: 20 77 68 65 6e 20 61 20 63 68 61 6e 67 65 73 65   when a changese
e040: 74 20 6f 72 20 70 61 74 63 68 73 65 74 20 69 73  t or patchset is
e050: 0a 20 20 20 20 20 20 20 20 2a 2a 20 65 76 65 6e  .        ** even
e060: 74 75 61 6c 6c 79 20 67 65 6e 65 72 61 74 65 64  tually generated
e070: 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20 53 65 73  . */.        Ses
e080: 73 69 6f 6e 54 61 62 6c 65 20 2a 2a 70 70 54 61  sionTable **ppTa
e090: 62 3b 0a 20 20 20 20 20 20 20 20 6d 65 6d 73 65  b;.        memse
e0a0: 74 28 70 54 61 62 2c 20 30 2c 20 73 69 7a 65 6f  t(pTab, 0, sizeo
e0b0: 66 28 53 65 73 73 69 6f 6e 54 61 62 6c 65 29 29  f(SessionTable))
e0c0: 3b 0a 20 20 20 20 20 20 20 20 70 54 61 62 2d 3e  ;.        pTab->
e0d0: 7a 4e 61 6d 65 20 3d 20 28 63 68 61 72 20 2a 29  zName = (char *)
e0e0: 26 70 54 61 62 5b 31 5d 3b 0a 20 20 20 20 20 20  &pTab[1];.      
e0f0: 20 20 6d 65 6d 63 70 79 28 70 54 61 62 2d 3e 7a    memcpy(pTab->z
e100: 4e 61 6d 65 2c 20 7a 4e 61 6d 65 2c 20 6e 4e 61  Name, zName, nNa
e110: 6d 65 2b 31 29 3b 0a 20 20 20 20 20 20 20 20 66  me+1);.        f
e120: 6f 72 28 70 70 54 61 62 3d 26 70 53 65 73 73 69  or(ppTab=&pSessi
e130: 6f 6e 2d 3e 70 54 61 62 6c 65 3b 20 2a 70 70 54  on->pTable; *ppT
e140: 61 62 3b 20 70 70 54 61 62 3d 26 28 2a 70 70 54  ab; ppTab=&(*ppT
e150: 61 62 29 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 20  ab)->pNext);.   
e160: 20 20 20 20 20 2a 70 70 54 61 62 20 3d 20 70 54       *ppTab = pT
e170: 61 62 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ab;.      }.    
e180: 7d 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33  }.  }..  sqlite3
e190: 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 73 71 6c  _mutex_leave(sql
e1a0: 69 74 65 33 5f 64 62 5f 6d 75 74 65 78 28 70 53  ite3_db_mutex(pS
e1b0: 65 73 73 69 6f 6e 2d 3e 64 62 29 29 3b 0a 20 20  ession->db));.  
e1c0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
e1d0: 0a 2a 2a 20 45 6e 73 75 72 65 20 74 68 61 74 20  .** Ensure that 
e1e0: 74 68 65 72 65 20 69 73 20 72 6f 6f 6d 20 69 6e  there is room in
e1f0: 20 74 68 65 20 62 75 66 66 65 72 20 74 6f 20 61   the buffer to a
e200: 70 70 65 6e 64 20 6e 42 79 74 65 20 62 79 74 65  ppend nByte byte
e210: 73 20 6f 66 20 64 61 74 61 2e 0a 2a 2a 20 49 66  s of data..** If
e220: 20 6e 6f 74 2c 20 75 73 65 20 73 71 6c 69 74 65   not, use sqlite
e230: 33 5f 72 65 61 6c 6c 6f 63 28 29 20 74 6f 20 67  3_realloc() to g
e240: 72 6f 77 20 74 68 65 20 62 75 66 66 65 72 20 73  row the buffer s
e250: 6f 20 74 68 61 74 20 74 68 65 72 65 20 69 73 2e  o that there is.
e260: 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65 73  .**.** If succes
e270: 73 66 75 6c 2c 20 72 65 74 75 72 6e 20 7a 65 72  sful, return zer
e280: 6f 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66  o. Otherwise, if
e290: 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74 69 6f   an OOM conditio
e2a0: 6e 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65 64  n is encountered
e2b0: 2c 0a 2a 2a 20 73 65 74 20 2a 70 52 63 20 74 6f  ,.** set *pRc to
e2c0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 61 6e   SQLITE_NOMEM an
e2d0: 64 20 72 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72  d return non-zer
e2e0: 6f 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  o..*/.static int
e2f0: 20 73 65 73 73 69 6f 6e 42 75 66 66 65 72 47 72   sessionBufferGr
e300: 6f 77 28 53 65 73 73 69 6f 6e 42 75 66 66 65 72  ow(SessionBuffer
e310: 20 2a 70 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20   *p, int nByte, 
e320: 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 69 66 28  int *pRc){.  if(
e330: 20 2a 70 52 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b   *pRc==SQLITE_OK
e340: 20 26 26 20 70 2d 3e 6e 41 6c 6c 6f 63 2d 70 2d   && p->nAlloc-p-
e350: 3e 6e 42 75 66 3c 6e 42 79 74 65 20 29 7b 0a 20  >nBuf<nByte ){. 
e360: 20 20 20 75 38 20 2a 61 4e 65 77 3b 0a 20 20 20     u8 *aNew;.   
e370: 20 69 6e 74 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e   int nNew = p->n
e380: 41 6c 6c 6f 63 20 3f 20 70 2d 3e 6e 41 6c 6c 6f  Alloc ? p->nAllo
e390: 63 20 3a 20 31 32 38 3b 0a 20 20 20 20 64 6f 20  c : 128;.    do 
e3a0: 7b 0a 20 20 20 20 20 20 6e 4e 65 77 20 3d 20 6e  {.      nNew = n
e3b0: 4e 65 77 2a 32 3b 0a 20 20 20 20 7d 77 68 69 6c  New*2;.    }whil
e3c0: 65 28 20 6e 4e 65 77 3c 28 70 2d 3e 6e 42 75 66  e( nNew<(p->nBuf
e3d0: 2b 6e 42 79 74 65 29 20 29 3b 0a 0a 20 20 20 20  +nByte) );..    
e3e0: 61 4e 65 77 20 3d 20 28 75 38 20 2a 29 73 71 6c  aNew = (u8 *)sql
e3f0: 69 74 65 33 5f 72 65 61 6c 6c 6f 63 28 70 2d 3e  ite3_realloc(p->
e400: 61 42 75 66 2c 20 6e 4e 65 77 29 3b 0a 20 20 20  aBuf, nNew);.   
e410: 20 69 66 28 20 30 3d 3d 61 4e 65 77 20 29 7b 0a   if( 0==aNew ){.
e420: 20 20 20 20 20 20 2a 70 52 63 20 3d 20 53 51 4c        *pRc = SQL
e430: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d  ITE_NOMEM;.    }
e440: 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 2d 3e 61  else{.      p->a
e450: 42 75 66 20 3d 20 61 4e 65 77 3b 0a 20 20 20 20  Buf = aNew;.    
e460: 20 20 70 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 6e 4e    p->nAlloc = nN
e470: 65 77 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  ew;.    }.  }.  
e480: 72 65 74 75 72 6e 20 28 2a 70 52 63 21 3d 53 51  return (*pRc!=SQ
e490: 4c 49 54 45 5f 4f 4b 29 3b 0a 7d 0a 0a 2f 2a 0a  LITE_OK);.}../*.
e4a0: 2a 2a 20 41 70 70 65 6e 64 20 74 68 65 20 76 61  ** Append the va
e4b0: 6c 75 65 20 70 61 73 73 65 64 20 61 73 20 74 68  lue passed as th
e4c0: 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e  e second argumen
e4d0: 74 20 74 6f 20 74 68 65 20 62 75 66 66 65 72 20  t to the buffer 
e4e0: 70 61 73 73 65 64 0a 2a 2a 20 61 73 20 74 68 65  passed.** as the
e4f0: 20 66 69 72 73 74 2e 0a 2a 2a 0a 2a 2a 20 54 68   first..**.** Th
e500: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 61  is function is a
e510: 20 6e 6f 2d 6f 70 20 69 66 20 2a 70 52 63 20 69   no-op if *pRc i
e520: 73 20 6e 6f 6e 2d 7a 65 72 6f 20 77 68 65 6e 20  s non-zero when 
e530: 69 74 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2a  it is called..**
e540: 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20 61   Otherwise, if a
e550: 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20  n error occurs, 
e560: 2a 70 52 63 20 69 73 20 73 65 74 20 74 6f 20 61  *pRc is set to a
e570: 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  n SQLite error c
e580: 6f 64 65 0a 2a 2a 20 62 65 66 6f 72 65 20 72 65  ode.** before re
e590: 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74  turning..*/.stat
e5a0: 69 63 20 76 6f 69 64 20 73 65 73 73 69 6f 6e 41  ic void sessionA
e5b0: 70 70 65 6e 64 56 61 6c 75 65 28 53 65 73 73 69  ppendValue(Sessi
e5c0: 6f 6e 42 75 66 66 65 72 20 2a 70 2c 20 73 71 6c  onBuffer *p, sql
e5d0: 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c  ite3_value *pVal
e5e0: 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 69  , int *pRc){.  i
e5f0: 6e 74 20 72 63 20 3d 20 2a 70 52 63 3b 0a 20 20  nt rc = *pRc;.  
e600: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
e610: 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79  K ){.    int nBy
e620: 74 65 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d  te = 0;.    rc =
e630: 20 73 65 73 73 69 6f 6e 53 65 72 69 61 6c 69 7a   sessionSerializ
e640: 65 56 61 6c 75 65 28 30 2c 20 70 56 61 6c 2c 20  eValue(0, pVal, 
e650: 26 6e 42 79 74 65 29 3b 0a 20 20 20 20 73 65 73  &nByte);.    ses
e660: 73 69 6f 6e 42 75 66 66 65 72 47 72 6f 77 28 70  sionBufferGrow(p
e670: 2c 20 6e 42 79 74 65 2c 20 26 72 63 29 3b 0a 20  , nByte, &rc);. 
e680: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
e690: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63  E_OK ){.      rc
e6a0: 20 3d 20 73 65 73 73 69 6f 6e 53 65 72 69 61 6c   = sessionSerial
e6b0: 69 7a 65 56 61 6c 75 65 28 26 70 2d 3e 61 42 75  izeValue(&p->aBu
e6c0: 66 5b 70 2d 3e 6e 42 75 66 5d 2c 20 70 56 61 6c  f[p->nBuf], pVal
e6d0: 2c 20 30 29 3b 0a 20 20 20 20 20 20 70 2d 3e 6e  , 0);.      p->n
e6e0: 42 75 66 20 2b 3d 20 6e 42 79 74 65 3b 0a 20 20  Buf += nByte;.  
e6f0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2a    }else{.      *
e700: 70 52 63 20 3d 20 72 63 3b 0a 20 20 20 20 7d 0a  pRc = rc;.    }.
e710: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69    }.}../*.** Thi
e720: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20  s function is a 
e730: 6e 6f 2d 6f 70 20 69 66 20 2a 70 52 63 20 69 73  no-op if *pRc is
e740: 20 6f 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49   other than SQLI
e750: 54 45 5f 4f 4b 20 77 68 65 6e 20 69 74 20 69 73  TE_OK when it is
e760: 20 0a 2a 2a 20 63 61 6c 6c 65 64 2e 20 4f 74 68   .** called. Oth
e770: 65 72 77 69 73 65 2c 20 61 70 70 65 6e 64 20 61  erwise, append a
e780: 20 73 69 6e 67 6c 65 20 62 79 74 65 20 74 6f 20   single byte to 
e790: 74 68 65 20 62 75 66 66 65 72 2e 20 0a 2a 2a 0a  the buffer. .**.
e7a0: 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e  ** If an OOM con
e7b0: 64 69 74 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e  dition is encoun
e7c0: 74 65 72 65 64 2c 20 73 65 74 20 2a 70 52 63 20  tered, set *pRc 
e7d0: 74 6f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20  to SQLITE_NOMEM 
e7e0: 62 65 66 6f 72 65 0a 2a 2a 20 72 65 74 75 72 6e  before.** return
e7f0: 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ing..*/.static v
e800: 6f 69 64 20 73 65 73 73 69 6f 6e 41 70 70 65 6e  oid sessionAppen
e810: 64 42 79 74 65 28 53 65 73 73 69 6f 6e 42 75 66  dByte(SessionBuf
e820: 66 65 72 20 2a 70 2c 20 75 38 20 76 2c 20 69 6e  fer *p, u8 v, in
e830: 74 20 2a 70 52 63 29 7b 0a 20 20 69 66 28 20 30  t *pRc){.  if( 0
e840: 3d 3d 73 65 73 73 69 6f 6e 42 75 66 66 65 72 47  ==sessionBufferG
e850: 72 6f 77 28 70 2c 20 31 2c 20 70 52 63 29 20 29  row(p, 1, pRc) )
e860: 7b 0a 20 20 20 20 70 2d 3e 61 42 75 66 5b 70 2d  {.    p->aBuf[p-
e870: 3e 6e 42 75 66 2b 2b 5d 20 3d 20 76 3b 0a 20 20  >nBuf++] = v;.  
e880: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  }.}../*.** This 
e890: 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f  function is a no
e8a0: 2d 6f 70 20 69 66 20 2a 70 52 63 20 69 73 20 6f  -op if *pRc is o
e8b0: 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45  ther than SQLITE
e8c0: 5f 4f 4b 20 77 68 65 6e 20 69 74 20 69 73 20 0a  _OK when it is .
e8d0: 2a 2a 20 63 61 6c 6c 65 64 2e 20 4f 74 68 65 72  ** called. Other
e8e0: 77 69 73 65 2c 20 61 70 70 65 6e 64 20 61 20 73  wise, append a s
e8f0: 69 6e 67 6c 65 20 76 61 72 69 6e 74 20 74 6f 20  ingle varint to 
e900: 74 68 65 20 62 75 66 66 65 72 2e 20 0a 2a 2a 0a  the buffer. .**.
e910: 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e  ** If an OOM con
e920: 64 69 74 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e  dition is encoun
e930: 74 65 72 65 64 2c 20 73 65 74 20 2a 70 52 63 20  tered, set *pRc 
e940: 74 6f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20  to SQLITE_NOMEM 
e950: 62 65 66 6f 72 65 0a 2a 2a 20 72 65 74 75 72 6e  before.** return
e960: 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ing..*/.static v
e970: 6f 69 64 20 73 65 73 73 69 6f 6e 41 70 70 65 6e  oid sessionAppen
e980: 64 56 61 72 69 6e 74 28 53 65 73 73 69 6f 6e 42  dVarint(SessionB
e990: 75 66 66 65 72 20 2a 70 2c 20 69 6e 74 20 76 2c  uffer *p, int v,
e9a0: 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 69 66   int *pRc){.  if
e9b0: 28 20 30 3d 3d 73 65 73 73 69 6f 6e 42 75 66 66  ( 0==sessionBuff
e9c0: 65 72 47 72 6f 77 28 70 2c 20 39 2c 20 70 52 63  erGrow(p, 9, pRc
e9d0: 29 20 29 7b 0a 20 20 20 20 70 2d 3e 6e 42 75 66  ) ){.    p->nBuf
e9e0: 20 2b 3d 20 73 65 73 73 69 6f 6e 56 61 72 69 6e   += sessionVarin
e9f0: 74 50 75 74 28 26 70 2d 3e 61 42 75 66 5b 70 2d  tPut(&p->aBuf[p-
ea00: 3e 6e 42 75 66 5d 2c 20 76 29 3b 0a 20 20 7d 0a  >nBuf], v);.  }.
ea10: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
ea20: 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f  nction is a no-o
ea30: 70 20 69 66 20 2a 70 52 63 20 69 73 20 6f 74 68  p if *pRc is oth
ea40: 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45 5f 4f  er than SQLITE_O
ea50: 4b 20 77 68 65 6e 20 69 74 20 69 73 20 0a 2a 2a  K when it is .**
ea60: 20 63 61 6c 6c 65 64 2e 20 4f 74 68 65 72 77 69   called. Otherwi
ea70: 73 65 2c 20 61 70 70 65 6e 64 20 61 20 62 6c 6f  se, append a blo
ea80: 62 20 6f 66 20 64 61 74 61 20 74 6f 20 74 68 65  b of data to the
ea90: 20 62 75 66 66 65 72 2e 20 0a 2a 2a 0a 2a 2a 20   buffer. .**.** 
eaa0: 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74  If an OOM condit
eab0: 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e 74 65 72  ion is encounter
eac0: 65 64 2c 20 73 65 74 20 2a 70 52 63 20 74 6f 20  ed, set *pRc to 
ead0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 62 65 66  SQLITE_NOMEM bef
eae0: 6f 72 65 0a 2a 2a 20 72 65 74 75 72 6e 69 6e 67  ore.** returning
eaf0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
eb00: 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 6c   sessionAppendBl
eb10: 6f 62 28 0a 20 20 53 65 73 73 69 6f 6e 42 75 66  ob(.  SessionBuf
eb20: 66 65 72 20 2a 70 2c 20 0a 20 20 63 6f 6e 73 74  fer *p, .  const
eb30: 20 75 38 20 2a 61 42 6c 6f 62 2c 20 0a 20 20 69   u8 *aBlob, .  i
eb40: 6e 74 20 6e 42 6c 6f 62 2c 20 0a 20 20 69 6e 74  nt nBlob, .  int
eb50: 20 2a 70 52 63 0a 29 7b 0a 20 20 69 66 28 20 6e   *pRc.){.  if( n
eb60: 42 6c 6f 62 3e 30 20 26 26 20 30 3d 3d 73 65 73  Blob>0 && 0==ses
eb70: 73 69 6f 6e 42 75 66 66 65 72 47 72 6f 77 28 70  sionBufferGrow(p
eb80: 2c 20 6e 42 6c 6f 62 2c 20 70 52 63 29 20 29 7b  , nBlob, pRc) ){
eb90: 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d 3e  .    memcpy(&p->
eba0: 61 42 75 66 5b 70 2d 3e 6e 42 75 66 5d 2c 20 61  aBuf[p->nBuf], a
ebb0: 42 6c 6f 62 2c 20 6e 42 6c 6f 62 29 3b 0a 20 20  Blob, nBlob);.  
ebc0: 20 20 70 2d 3e 6e 42 75 66 20 2b 3d 20 6e 42 6c    p->nBuf += nBl
ebd0: 6f 62 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  ob;.  }.}../*.**
ebe0: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
ebf0: 73 20 61 20 6e 6f 2d 6f 70 20 69 66 20 2a 70 52  s a no-op if *pR
ec00: 63 20 69 73 20 6f 74 68 65 72 20 74 68 61 6e 20  c is other than 
ec10: 53 51 4c 49 54 45 5f 4f 4b 20 77 68 65 6e 20 69  SQLITE_OK when i
ec20: 74 20 69 73 20 0a 2a 2a 20 63 61 6c 6c 65 64 2e  t is .** called.
ec30: 20 4f 74 68 65 72 77 69 73 65 2c 20 61 70 70 65   Otherwise, appe
ec40: 6e 64 20 61 20 73 74 72 69 6e 67 20 74 6f 20 74  nd a string to t
ec50: 68 65 20 62 75 66 66 65 72 2e 20 41 6c 6c 20 62  he buffer. All b
ec60: 79 74 65 73 20 69 6e 20 74 68 65 20 73 74 72 69  ytes in the stri
ec70: 6e 67 0a 2a 2a 20 75 70 20 74 6f 20 28 62 75 74  ng.** up to (but
ec80: 20 6e 6f 74 20 69 6e 63 6c 75 64 69 6e 67 29 20   not including) 
ec90: 74 68 65 20 6e 75 6c 2d 74 65 72 6d 69 6e 61 74  the nul-terminat
eca0: 6f 72 20 61 72 65 20 77 72 69 74 74 65 6e 20 74  or are written t
ecb0: 6f 20 74 68 65 20 62 75 66 66 65 72 2e 0a 2a 2a  o the buffer..**
ecc0: 0a 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 63 6f  .** If an OOM co
ecd0: 6e 64 69 74 69 6f 6e 20 69 73 20 65 6e 63 6f 75  ndition is encou
ece0: 6e 74 65 72 65 64 2c 20 73 65 74 20 2a 70 52 63  ntered, set *pRc
ecf0: 20 74 6f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d   to SQLITE_NOMEM
ed00: 20 62 65 66 6f 72 65 0a 2a 2a 20 72 65 74 75 72   before.** retur
ed10: 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ning..*/.static 
ed20: 76 6f 69 64 20 73 65 73 73 69 6f 6e 41 70 70 65  void sessionAppe
ed30: 6e 64 53 74 72 28 0a 20 20 53 65 73 73 69 6f 6e  ndStr(.  Session
ed40: 42 75 66 66 65 72 20 2a 70 2c 20 0a 20 20 63 6f  Buffer *p, .  co
ed50: 6e 73 74 20 63 68 61 72 20 2a 7a 53 74 72 2c 20  nst char *zStr, 
ed60: 0a 20 20 69 6e 74 20 2a 70 52 63 0a 29 7b 0a 20  .  int *pRc.){. 
ed70: 20 69 6e 74 20 6e 53 74 72 20 3d 20 73 71 6c 69   int nStr = sqli
ed80: 74 65 33 53 74 72 6c 65 6e 33 30 28 7a 53 74 72  te3Strlen30(zStr
ed90: 29 3b 0a 20 20 69 66 28 20 30 3d 3d 73 65 73 73  );.  if( 0==sess
eda0: 69 6f 6e 42 75 66 66 65 72 47 72 6f 77 28 70 2c  ionBufferGrow(p,
edb0: 20 6e 53 74 72 2c 20 70 52 63 29 20 29 7b 0a 20   nStr, pRc) ){. 
edc0: 20 20 20 6d 65 6d 63 70 79 28 26 70 2d 3e 61 42     memcpy(&p->aB
edd0: 75 66 5b 70 2d 3e 6e 42 75 66 5d 2c 20 7a 53 74  uf[p->nBuf], zSt
ede0: 72 2c 20 6e 53 74 72 29 3b 0a 20 20 20 20 70 2d  r, nStr);.    p-
edf0: 3e 6e 42 75 66 20 2b 3d 20 6e 53 74 72 3b 0a 20  >nBuf += nStr;. 
ee00: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73   }.}../*.** This
ee10: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e   function is a n
ee20: 6f 2d 6f 70 20 69 66 20 2a 70 52 63 20 69 73 20  o-op if *pRc is 
ee30: 6f 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54  other than SQLIT
ee40: 45 5f 4f 4b 20 77 68 65 6e 20 69 74 20 69 73 20  E_OK when it is 
ee50: 0a 2a 2a 20 63 61 6c 6c 65 64 2e 20 4f 74 68 65  .** called. Othe
ee60: 72 77 69 73 65 2c 20 61 70 70 65 6e 64 20 74 68  rwise, append th
ee70: 65 20 73 74 72 69 6e 67 20 72 65 70 72 65 73 65  e string represe
ee80: 6e 74 61 74 69 6f 6e 20 6f 66 20 69 6e 74 65 67  ntation of integ
ee90: 65 72 20 69 56 61 6c 0a 2a 2a 20 74 6f 20 74 68  er iVal.** to th
eea0: 65 20 62 75 66 66 65 72 2e 20 4e 6f 20 6e 75 6c  e buffer. No nul
eeb0: 2d 74 65 72 6d 69 6e 61 74 6f 72 20 69 73 20 77  -terminator is w
eec0: 72 69 74 74 65 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66  ritten..**.** If
eed0: 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74 69 6f   an OOM conditio
eee0: 6e 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65 64  n is encountered
eef0: 2c 20 73 65 74 20 2a 70 52 63 20 74 6f 20 53 51  , set *pRc to SQ
ef00: 4c 49 54 45 5f 4e 4f 4d 45 4d 20 62 65 66 6f 72  LITE_NOMEM befor
ef10: 65 0a 2a 2a 20 72 65 74 75 72 6e 69 6e 67 2e 0a  e.** returning..
ef20: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73  */.static void s
ef30: 65 73 73 69 6f 6e 41 70 70 65 6e 64 49 6e 74 65  essionAppendInte
ef40: 67 65 72 28 0a 20 20 53 65 73 73 69 6f 6e 42 75  ger(.  SessionBu
ef50: 66 66 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20  ffer *p,        
ef60: 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72         /* Buffer
ef70: 20 74 6f 20 61 70 70 65 6e 64 20 74 6f 20 2a 2f   to append to */
ef80: 0a 20 20 69 6e 74 20 69 56 61 6c 2c 20 20 20 20  .  int iVal,    
ef90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
efa0: 20 20 20 2f 2a 20 56 61 6c 75 65 20 74 6f 20 77     /* Value to w
efb0: 72 69 74 65 20 74 68 65 20 73 74 72 69 6e 67 20  rite the string 
efc0: 72 65 70 2e 20 6f 66 20 2a 2f 0a 20 20 69 6e 74  rep. of */.  int
efd0: 20 2a 70 52 63 20 20 20 20 20 20 20 20 20 20 20   *pRc           
efe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
eff0: 49 4e 2f 4f 55 54 3a 20 45 72 72 6f 72 20 63 6f  IN/OUT: Error co
f000: 64 65 20 2a 2f 0a 29 7b 0a 20 20 63 68 61 72 20  de */.){.  char 
f010: 61 42 75 66 5b 32 34 5d 3b 0a 20 20 73 71 6c 69  aBuf[24];.  sqli
f020: 74 65 33 5f 73 6e 70 72 69 6e 74 66 28 73 69 7a  te3_snprintf(siz
f030: 65 6f 66 28 61 42 75 66 29 2d 31 2c 20 61 42 75  eof(aBuf)-1, aBu
f040: 66 2c 20 22 25 64 22 2c 20 69 56 61 6c 29 3b 0a  f, "%d", iVal);.
f050: 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53    sessionAppendS
f060: 74 72 28 70 2c 20 61 42 75 66 2c 20 70 52 63 29  tr(p, aBuf, pRc)
f070: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
f080: 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f  function is a no
f090: 2d 6f 70 20 69 66 20 2a 70 52 63 20 69 73 20 6f  -op if *pRc is o
f0a0: 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45  ther than SQLITE
f0b0: 5f 4f 4b 20 77 68 65 6e 20 69 74 20 69 73 20 0a  _OK when it is .
f0c0: 2a 2a 20 63 61 6c 6c 65 64 2e 20 4f 74 68 65 72  ** called. Other
f0d0: 77 69 73 65 2c 20 61 70 70 65 6e 64 20 74 68 65  wise, append the
f0e0: 20 73 74 72 69 6e 67 20 7a 53 74 72 20 65 6e 63   string zStr enc
f0f0: 6c 6f 73 65 64 20 69 6e 20 71 75 6f 74 65 73 20  losed in quotes 
f100: 28 22 29 20 61 6e 64 0a 2a 2a 20 77 69 74 68 20  (") and.** with 
f110: 61 6e 79 20 65 6d 62 65 64 64 65 64 20 71 75 6f  any embedded quo
f120: 74 65 20 63 68 61 72 61 63 74 65 72 73 20 65 73  te characters es
f130: 63 61 70 65 64 20 74 6f 20 74 68 65 20 62 75 66  caped to the buf
f140: 66 65 72 2e 20 4e 6f 20 0a 2a 2a 20 6e 75 6c 2d  fer. No .** nul-
f150: 74 65 72 6d 69 6e 61 74 6f 72 20 62 79 74 65 20  terminator byte 
f160: 69 73 20 77 72 69 74 74 65 6e 2e 0a 2a 2a 0a 2a  is written..**.*
f170: 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64  * If an OOM cond
f180: 69 74 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e 74  ition is encount
f190: 65 72 65 64 2c 20 73 65 74 20 2a 70 52 63 20 74  ered, set *pRc t
f1a0: 6f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 62  o SQLITE_NOMEM b
f1b0: 65 66 6f 72 65 0a 2a 2a 20 72 65 74 75 72 6e 69  efore.** returni
f1c0: 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ng..*/.static vo
f1d0: 69 64 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64  id sessionAppend
f1e0: 49 64 65 6e 74 28 0a 20 20 53 65 73 73 69 6f 6e  Ident(.  Session
f1f0: 42 75 66 66 65 72 20 2a 70 2c 20 20 20 20 20 20  Buffer *p,      
f200: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66           /* Buff
f210: 65 72 20 74 6f 20 61 20 61 70 70 65 6e 64 20 74  er to a append t
f220: 6f 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  o */.  const cha
f230: 72 20 2a 7a 53 74 72 2c 20 20 20 20 20 20 20 20  r *zStr,        
f240: 20 20 20 20 20 20 20 2f 2a 20 53 74 72 69 6e 67         /* String
f250: 20 74 6f 20 71 75 6f 74 65 2c 20 65 73 63 61 70   to quote, escap
f260: 65 20 61 6e 64 20 61 70 70 65 6e 64 20 2a 2f 0a  e and append */.
f270: 20 20 69 6e 74 20 2a 70 52 63 20 20 20 20 20 20    int *pRc      
f280: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f290: 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 45 72 72    /* IN/OUT: Err
f2a0: 6f 72 20 63 6f 64 65 20 2a 2f 0a 29 7b 0a 20 20  or code */.){.  
f2b0: 69 6e 74 20 6e 53 74 72 20 3d 20 73 71 6c 69 74  int nStr = sqlit
f2c0: 65 33 53 74 72 6c 65 6e 33 30 28 7a 53 74 72 29  e3Strlen30(zStr)
f2d0: 2a 32 20 2b 20 32 20 2b 20 31 3b 0a 20 20 69 66  *2 + 2 + 1;.  if
f2e0: 28 20 30 3d 3d 73 65 73 73 69 6f 6e 42 75 66 66  ( 0==sessionBuff
f2f0: 65 72 47 72 6f 77 28 70 2c 20 6e 53 74 72 2c 20  erGrow(p, nStr, 
f300: 70 52 63 29 20 29 7b 0a 20 20 20 20 63 68 61 72  pRc) ){.    char
f310: 20 2a 7a 4f 75 74 20 3d 20 28 63 68 61 72 20 2a   *zOut = (char *
f320: 29 26 70 2d 3e 61 42 75 66 5b 70 2d 3e 6e 42 75  )&p->aBuf[p->nBu
f330: 66 5d 3b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68  f];.    const ch
f340: 61 72 20 2a 7a 49 6e 20 3d 20 7a 53 74 72 3b 0a  ar *zIn = zStr;.
f350: 20 20 20 20 2a 7a 4f 75 74 2b 2b 20 3d 20 27 22      *zOut++ = '"
f360: 27 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 2a 7a  ';.    while( *z
f370: 49 6e 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  In ){.      if( 
f380: 2a 7a 49 6e 3d 3d 27 22 27 20 29 20 2a 7a 4f 75  *zIn=='"' ) *zOu
f390: 74 2b 2b 20 3d 20 27 22 27 3b 0a 20 20 20 20 20  t++ = '"';.     
f3a0: 20 2a 7a 4f 75 74 2b 2b 20 3d 20 2a 28 7a 49 6e   *zOut++ = *(zIn
f3b0: 2b 2b 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 2a  ++);.    }.    *
f3c0: 7a 4f 75 74 2b 2b 20 3d 20 27 22 27 3b 0a 20 20  zOut++ = '"';.  
f3d0: 20 20 70 2d 3e 6e 42 75 66 20 3d 20 28 69 6e 74    p->nBuf = (int
f3e0: 29 28 28 75 38 20 2a 29 7a 4f 75 74 20 2d 20 70  )((u8 *)zOut - p
f3f0: 2d 3e 61 42 75 66 29 3b 0a 20 20 7d 0a 7d 0a 0a  ->aBuf);.  }.}..
f400: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
f410: 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 20 69  ion is a no-op i
f420: 66 20 2a 70 52 63 20 69 73 20 6f 74 68 65 72 20  f *pRc is other 
f430: 74 68 61 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 77  than SQLITE_OK w
f440: 68 65 6e 20 69 74 20 69 73 0a 2a 2a 20 63 61 6c  hen it is.** cal
f450: 6c 65 64 2e 20 4f 74 68 65 72 77 73 65 2c 20 69  led. Otherwse, i
f460: 74 20 61 70 70 65 6e 64 73 20 74 68 65 20 73 65  t appends the se
f470: 72 69 61 6c 69 7a 65 64 20 76 65 72 73 69 6f 6e  rialized version
f480: 20 6f 66 20 74 68 65 20 76 61 6c 75 65 20 73 74   of the value st
f490: 6f 72 65 64 0a 2a 2a 20 69 6e 20 63 6f 6c 75 6d  ored.** in colum
f4a0: 6e 20 69 43 6f 6c 20 6f 66 20 74 68 65 20 72 6f  n iCol of the ro
f4b0: 77 20 74 68 61 74 20 53 51 4c 20 73 74 61 74 65  w that SQL state
f4c0: 6d 65 6e 74 20 70 53 74 6d 74 20 63 75 72 72 65  ment pStmt curre
f4d0: 6e 74 6c 79 20 70 6f 69 6e 74 73 0a 2a 2a 20 74  ntly points.** t
f4e0: 6f 20 74 6f 20 74 68 65 20 62 75 66 66 65 72 2e  o to the buffer.
f4f0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
f500: 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 43 6f 6c  sessionAppendCol
f510: 28 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66 65  (.  SessionBuffe
f520: 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20  r *p,           
f530: 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f      /* Buffer to
f540: 20 61 70 70 65 6e 64 20 74 6f 20 2a 2f 0a 20 20   append to */.  
f550: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53  sqlite3_stmt *pS
f560: 74 6d 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  tmt,            
f570: 2f 2a 20 48 61 6e 64 6c 65 20 70 6f 69 6e 74 69  /* Handle pointi
f580: 6e 67 20 74 6f 20 72 6f 77 20 63 6f 6e 74 61 69  ng to row contai
f590: 6e 69 6e 67 20 76 61 6c 75 65 20 2a 2f 0a 20 20  ning value */.  
f5a0: 69 6e 74 20 69 43 6f 6c 2c 20 20 20 20 20 20 20  int iCol,       
f5b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f5c0: 2f 2a 20 43 6f 6c 75 6d 6e 20 74 6f 20 72 65 61  /* Column to rea
f5d0: 64 20 76 61 6c 75 65 20 66 72 6f 6d 20 2a 2f 0a  d value from */.
f5e0: 20 20 69 6e 74 20 2a 70 52 63 20 20 20 20 20 20    int *pRc      
f5f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f600: 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 45 72 72    /* IN/OUT: Err
f610: 6f 72 20 63 6f 64 65 20 2a 2f 0a 29 7b 0a 20 20  or code */.){.  
f620: 69 66 28 20 2a 70 52 63 3d 3d 53 51 4c 49 54 45  if( *pRc==SQLITE
f630: 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 65  _OK ){.    int e
f640: 54 79 70 65 20 3d 20 73 71 6c 69 74 65 33 5f 63  Type = sqlite3_c
f650: 6f 6c 75 6d 6e 5f 74 79 70 65 28 70 53 74 6d 74  olumn_type(pStmt
f660: 2c 20 69 43 6f 6c 29 3b 0a 20 20 20 20 73 65 73  , iCol);.    ses
f670: 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 70  sionAppendByte(p
f680: 2c 20 28 75 38 29 65 54 79 70 65 2c 20 70 52 63  , (u8)eType, pRc
f690: 29 3b 0a 20 20 20 20 69 66 28 20 65 54 79 70 65  );.    if( eType
f6a0: 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52  ==SQLITE_INTEGER
f6b0: 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49 54   || eType==SQLIT
f6c0: 45 5f 46 4c 4f 41 54 20 29 7b 0a 20 20 20 20 20  E_FLOAT ){.     
f6d0: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69   sqlite3_int64 i
f6e0: 3b 0a 20 20 20 20 20 20 75 38 20 61 42 75 66 5b  ;.      u8 aBuf[
f6f0: 38 5d 3b 0a 20 20 20 20 20 20 69 66 28 20 65 54  8];.      if( eT
f700: 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45  ype==SQLITE_INTE
f710: 47 45 52 20 29 7b 0a 20 20 20 20 20 20 20 20 69  GER ){.        i
f720: 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d   = sqlite3_colum
f730: 6e 5f 69 6e 74 36 34 28 70 53 74 6d 74 2c 20 69  n_int64(pStmt, i
f740: 43 6f 6c 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73  Col);.      }els
f750: 65 7b 0a 20 20 20 20 20 20 20 20 64 6f 75 62 6c  e{.        doubl
f760: 65 20 72 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  e r = sqlite3_co
f770: 6c 75 6d 6e 5f 64 6f 75 62 6c 65 28 70 53 74 6d  lumn_double(pStm
f780: 74 2c 20 69 43 6f 6c 29 3b 0a 20 20 20 20 20 20  t, iCol);.      
f790: 20 20 6d 65 6d 63 70 79 28 26 69 2c 20 26 72 2c    memcpy(&i, &r,
f7a0: 20 38 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20   8);.      }.   
f7b0: 20 20 20 73 65 73 73 69 6f 6e 50 75 74 49 36 34     sessionPutI64
f7c0: 28 61 42 75 66 2c 20 69 29 3b 0a 20 20 20 20 20  (aBuf, i);.     
f7d0: 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 6c   sessionAppendBl
f7e0: 6f 62 28 70 2c 20 61 42 75 66 2c 20 38 2c 20 70  ob(p, aBuf, 8, p
f7f0: 52 63 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  Rc);.    }.    i
f800: 66 28 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45  f( eType==SQLITE
f810: 5f 42 4c 4f 42 20 7c 7c 20 65 54 79 70 65 3d 3d  _BLOB || eType==
f820: 53 51 4c 49 54 45 5f 54 45 58 54 20 29 7b 0a 20  SQLITE_TEXT ){. 
f830: 20 20 20 20 20 75 38 20 2a 7a 3b 0a 20 20 20 20       u8 *z;.    
f840: 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20    int nByte;.   
f850: 20 20 20 69 66 28 20 65 54 79 70 65 3d 3d 53 51     if( eType==SQ
f860: 4c 49 54 45 5f 42 4c 4f 42 20 29 7b 0a 20 20 20  LITE_BLOB ){.   
f870: 20 20 20 20 20 7a 20 3d 20 28 75 38 20 2a 29 73       z = (u8 *)s
f880: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c  qlite3_column_bl
f890: 6f 62 28 70 53 74 6d 74 2c 20 69 43 6f 6c 29 3b  ob(pStmt, iCol);
f8a0: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
f8b0: 20 20 20 20 20 20 7a 20 3d 20 28 75 38 20 2a 29        z = (u8 *)
f8c0: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74  sqlite3_column_t
f8d0: 65 78 74 28 70 53 74 6d 74 2c 20 69 43 6f 6c 29  ext(pStmt, iCol)
f8e0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
f8f0: 6e 42 79 74 65 20 3d 20 73 71 6c 69 74 65 33 5f  nByte = sqlite3_
f900: 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70 53 74  column_bytes(pSt
f910: 6d 74 2c 20 69 43 6f 6c 29 3b 0a 20 20 20 20 20  mt, iCol);.     
f920: 20 69 66 28 20 7a 20 7c 7c 20 28 65 54 79 70 65   if( z || (eType
f930: 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 20 26 26  ==SQLITE_BLOB &&
f940: 20 6e 42 79 74 65 3d 3d 30 29 20 29 7b 0a 20 20   nByte==0) ){.  
f950: 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70        sessionApp
f960: 65 6e 64 56 61 72 69 6e 74 28 70 2c 20 6e 42 79  endVarint(p, nBy
f970: 74 65 2c 20 70 52 63 29 3b 0a 20 20 20 20 20 20  te, pRc);.      
f980: 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42    sessionAppendB
f990: 6c 6f 62 28 70 2c 20 7a 2c 20 6e 42 79 74 65 2c  lob(p, z, nByte,
f9a0: 20 70 52 63 29 3b 0a 20 20 20 20 20 20 7d 65 6c   pRc);.      }el
f9b0: 73 65 7b 0a 20 20 20 20 20 20 20 20 2a 70 52 63  se{.        *pRc
f9c0: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
f9d0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
f9e0: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 0a 2a 2a 20 54   }.}../*.**.** T
f9f0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 61 70 70  his function app
fa00: 65 6e 64 73 20 61 6e 20 75 70 64 61 74 65 20 63  ends an update c
fa10: 68 61 6e 67 65 20 74 6f 20 74 68 65 20 62 75 66  hange to the buf
fa20: 66 65 72 20 28 73 65 65 20 74 68 65 20 63 6f 6d  fer (see the com
fa30: 6d 65 6e 74 73 20 0a 2a 2a 20 75 6e 64 65 72 20  ments .** under 
fa40: 22 43 48 41 4e 47 45 53 45 54 20 46 4f 52 4d 41  "CHANGESET FORMA
fa50: 54 22 20 61 74 20 74 68 65 20 74 6f 70 20 6f 66  T" at the top of
fa60: 20 74 68 65 20 66 69 6c 65 29 2e 20 41 6e 20 75   the file). An u
fa70: 70 64 61 74 65 20 63 68 61 6e 67 65 20 0a 2a 2a  pdate change .**
fa80: 20 63 6f 6e 73 69 73 74 73 20 6f 66 3a 0a 2a 2a   consists of:.**
fa90: 0a 2a 2a 20 20 20 31 20 62 79 74 65 3a 20 20 53  .**   1 byte:  S
faa0: 51 4c 49 54 45 5f 55 50 44 41 54 45 20 28 30 78  QLITE_UPDATE (0x
fab0: 31 37 29 0a 2a 2a 20 20 20 6e 20 62 79 74 65 73  17).**   n bytes
fac0: 3a 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 20 28  : old.* record (
fad0: 73 65 65 20 52 45 43 4f 52 44 20 46 4f 52 4d 41  see RECORD FORMA
fae0: 54 29 0a 2a 2a 20 20 20 6d 20 62 79 74 65 73 3a  T).**   m bytes:
faf0: 20 6e 65 77 2e 2a 20 72 65 63 6f 72 64 20 28 73   new.* record (s
fb00: 65 65 20 52 45 43 4f 52 44 20 46 4f 52 4d 41 54  ee RECORD FORMAT
fb10: 29 0a 2a 2a 0a 2a 2a 20 54 68 65 20 53 65 73 73  ).**.** The Sess
fb20: 69 6f 6e 43 68 61 6e 67 65 20 6f 62 6a 65 63 74  ionChange object
fb30: 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 74   passed as the t
fb40: 68 69 72 64 20 61 72 67 75 6d 65 6e 74 20 63 6f  hird argument co
fb50: 6e 74 61 69 6e 73 20 74 68 65 0a 2a 2a 20 76 61  ntains the.** va
fb60: 6c 75 65 73 20 74 68 61 74 20 77 65 72 65 20 73  lues that were s
fb70: 74 6f 72 65 64 20 69 6e 20 74 68 65 20 72 6f 77  tored in the row
fb80: 20 77 68 65 6e 20 74 68 65 20 73 65 73 73 69 6f   when the sessio
fb90: 6e 20 62 65 67 61 6e 20 28 74 68 65 20 6f 6c 64  n began (the old
fba0: 2e 2a 0a 2a 2a 20 76 61 6c 75 65 73 29 2e 20 54  .*.** values). T
fbb0: 68 65 20 73 74 61 74 65 6d 65 6e 74 20 68 61 6e  he statement han
fbc0: 64 6c 65 20 70 61 73 73 65 64 20 61 73 20 74 68  dle passed as th
fbd0: 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e  e second argumen
fbe0: 74 20 70 6f 69 6e 74 73 0a 2a 2a 20 61 74 20 74  t points.** at t
fbf0: 68 65 20 63 75 72 72 65 6e 74 20 76 65 72 73 69  he current versi
fc00: 6f 6e 20 6f 66 20 74 68 65 20 72 6f 77 20 28 74  on of the row (t
fc10: 68 65 20 6e 65 77 2e 2a 20 76 61 6c 75 65 73 29  he new.* values)
fc20: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6c 6c 20 6f  ..**.** If all o
fc30: 66 20 74 68 65 20 6f 6c 64 2e 2a 20 76 61 6c 75  f the old.* valu
fc40: 65 73 20 61 72 65 20 65 71 75 61 6c 20 74 6f 20  es are equal to 
fc50: 74 68 65 69 72 20 63 6f 72 72 65 73 70 6f 6e 64  their correspond
fc60: 69 6e 67 20 6e 65 77 2e 2a 20 76 61 6c 75 65 0a  ing new.* value.
fc70: 2a 2a 20 28 69 2e 65 2e 20 6e 6f 74 68 69 6e 67  ** (i.e. nothing
fc80: 20 68 61 73 20 63 68 61 6e 67 65 64 29 2c 20 74   has changed), t
fc90: 68 65 6e 20 6e 6f 20 64 61 74 61 20 61 74 20 61  hen no data at a
fca0: 6c 6c 20 69 73 20 61 70 70 65 6e 64 65 64 20 74  ll is appended t
fcb0: 6f 20 74 68 65 20 62 75 66 66 65 72 2e 0a 2a 2a  o the buffer..**
fcc0: 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 74  .** Otherwise, t
fcd0: 68 65 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 20  he old.* record 
fce0: 63 6f 6e 74 61 69 6e 73 20 61 6c 6c 20 70 72 69  contains all pri
fcf0: 6d 61 72 79 20 6b 65 79 20 76 61 6c 75 65 73 20  mary key values 
fd00: 61 6e 64 20 74 68 65 20 0a 2a 2a 20 6f 72 69 67  and the .** orig
fd10: 69 6e 61 6c 20 76 61 6c 75 65 73 20 6f 66 20 61  inal values of a
fd20: 6e 79 20 66 69 65 6c 64 73 20 74 68 61 74 20 68  ny fields that h
fd30: 61 76 65 20 62 65 65 6e 20 6d 6f 64 69 66 69 65  ave been modifie
fd40: 64 2e 20 54 68 65 20 6e 65 77 2e 2a 20 72 65 63  d. The new.* rec
fd50: 6f 72 64 20 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73  ord .** contains
fd60: 20 74 68 65 20 6e 65 77 20 76 61 6c 75 65 73 20   the new values 
fd70: 6f 66 20 6f 6e 6c 79 20 74 68 6f 73 65 20 66 69  of only those fi
fd80: 65 6c 64 73 20 74 68 61 74 20 68 61 76 65 20 62  elds that have b
fd90: 65 65 6e 20 6d 6f 64 69 66 69 65 64 2e 0a 2a 2f  een modified..*/
fda0: 20 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73   .static int ses
fdb0: 73 69 6f 6e 41 70 70 65 6e 64 55 70 64 61 74 65  sionAppendUpdate
fdc0: 28 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66 65  (.  SessionBuffe
fdd0: 72 20 2a 70 42 75 66 2c 20 20 20 20 20 20 20 20  r *pBuf,        
fde0: 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f      /* Buffer to
fdf0: 20 61 70 70 65 6e 64 20 74 6f 20 2a 2f 0a 20 20   append to */.  
fe00: 69 6e 74 20 62 50 61 74 63 68 73 65 74 2c 20 20  int bPatchset,  
fe10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fe20: 2f 2a 20 54 72 75 65 20 66 6f 72 20 22 70 61 74  /* True for "pat
fe30: 63 68 73 65 74 22 2c 20 30 20 66 6f 72 20 22 63  chset", 0 for "c
fe40: 68 61 6e 67 65 73 65 74 22 20 2a 2f 0a 20 20 73  hangeset" */.  s
fe50: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
fe60: 6d 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  mt,            /
fe70: 2a 20 53 74 61 74 65 6d 65 6e 74 20 68 61 6e 64  * Statement hand
fe80: 6c 65 20 70 6f 69 6e 74 69 6e 67 20 61 74 20 6e  le pointing at n
fe90: 65 77 20 72 6f 77 20 2a 2f 0a 20 20 53 65 73 73  ew row */.  Sess
fea0: 69 6f 6e 43 68 61 6e 67 65 20 2a 70 2c 20 20 20  ionChange *p,   
feb0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
fec0: 62 6a 65 63 74 20 63 6f 6e 74 61 69 6e 69 6e 67  bject containing
fed0: 20 6f 6c 64 20 76 61 6c 75 65 73 20 2a 2f 0a 20   old values */. 
fee0: 20 75 38 20 2a 61 62 50 4b 20 20 20 20 20 20 20   u8 *abPK       
fef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ff00: 20 2f 2a 20 42 6f 6f 6c 65 61 6e 20 61 72 72 61   /* Boolean arra
ff10: 79 20 2d 20 74 72 75 65 20 66 6f 72 20 50 4b 20  y - true for PK 
ff20: 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 29 7b 0a 20 20  columns */.){.  
ff30: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
ff40: 4f 4b 3b 0a 20 20 53 65 73 73 69 6f 6e 42 75 66  OK;.  SessionBuf
ff50: 66 65 72 20 62 75 66 32 20 3d 20 7b 30 2c 30 2c  fer buf2 = {0,0,
ff60: 30 7d 3b 20 2f 2a 20 42 75 66 66 65 72 20 74 6f  0}; /* Buffer to
ff70: 20 61 63 63 75 6d 75 6c 61 74 65 20 6e 65 77 2e   accumulate new.
ff80: 2a 20 72 65 63 6f 72 64 20 69 6e 20 2a 2f 0a 20  * record in */. 
ff90: 20 69 6e 74 20 62 4e 6f 6f 70 20 3d 20 31 3b 20   int bNoop = 1; 
ffa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
ffb0: 2a 20 53 65 74 20 74 6f 20 7a 65 72 6f 20 69 66  * Set to zero if
ffc0: 20 61 6e 79 20 76 61 6c 75 65 73 20 61 72 65 20   any values are 
ffd0: 6d 6f 64 69 66 69 65 64 20 2a 2f 0a 20 20 69 6e  modified */.  in
ffe0: 74 20 6e 52 65 77 69 6e 64 20 3d 20 70 42 75 66  t nRewind = pBuf
fff0: 2d 3e 6e 42 75 66 3b 20 20 20 20 20 2f 2a 20 53  ->nBuf;     /* S
10000 65 74 20 74 6f 20 7a 65 72 6f 20 69 66 20 61 6e  et to zero if an
10010 79 20 76 61 6c 75 65 73 20 61 72 65 20 6d 6f 64  y values are mod
10020 69 66 69 65 64 20 2a 2f 0a 20 20 69 6e 74 20 69  ified */.  int i
10030 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
10040 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64           /* Used
10050 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f   to iterate thro
10060 75 67 68 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 20  ugh columns */. 
10070 20 75 38 20 2a 70 43 73 72 20 3d 20 70 2d 3e 61   u8 *pCsr = p->a
10080 52 65 63 6f 72 64 3b 20 20 20 20 20 20 20 20 2f  Record;        /
10090 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72 61 74  * Used to iterat
100a0 65 20 74 68 72 6f 75 67 68 20 6f 6c 64 2e 2a 20  e through old.* 
100b0 76 61 6c 75 65 73 20 2a 2f 0a 0a 20 20 73 65 73  values */..  ses
100c0 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 70  sionAppendByte(p
100d0 42 75 66 2c 20 53 51 4c 49 54 45 5f 55 50 44 41  Buf, SQLITE_UPDA
100e0 54 45 2c 20 26 72 63 29 3b 0a 20 20 73 65 73 73  TE, &rc);.  sess
100f0 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 70 42  ionAppendByte(pB
10100 75 66 2c 20 70 2d 3e 62 49 6e 64 69 72 65 63 74  uf, p->bIndirect
10110 2c 20 26 72 63 29 3b 0a 20 20 66 6f 72 28 69 3d  , &rc);.  for(i=
10120 30 3b 20 69 3c 73 71 6c 69 74 65 33 5f 63 6f 6c  0; i<sqlite3_col
10130 75 6d 6e 5f 63 6f 75 6e 74 28 70 53 74 6d 74 29  umn_count(pStmt)
10140 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 20  ; i++){.    int 
10150 62 43 68 61 6e 67 65 64 20 3d 20 30 3b 0a 20 20  bChanged = 0;.  
10160 20 20 69 6e 74 20 6e 41 64 76 61 6e 63 65 3b 0a    int nAdvance;.
10170 20 20 20 20 69 6e 74 20 65 54 79 70 65 20 3d 20      int eType = 
10180 2a 70 43 73 72 3b 0a 20 20 20 20 73 77 69 74 63  *pCsr;.    switc
10190 68 28 20 65 54 79 70 65 20 29 7b 0a 20 20 20 20  h( eType ){.    
101a0 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 4e 55    case SQLITE_NU
101b0 4c 4c 3a 0a 20 20 20 20 20 20 20 20 6e 41 64 76  LL:.        nAdv
101c0 61 6e 63 65 20 3d 20 31 3b 0a 20 20 20 20 20 20  ance = 1;.      
101d0 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 63 6f    if( sqlite3_co
101e0 6c 75 6d 6e 5f 74 79 70 65 28 70 53 74 6d 74 2c  lumn_type(pStmt,
101f0 20 69 29 21 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c   i)!=SQLITE_NULL
10200 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 62 43   ){.          bC
10210 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20 20 20 20  hanged = 1;.    
10220 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 62 72      }.        br
10230 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63 61 73 65  eak;..      case
10240 20 53 51 4c 49 54 45 5f 46 4c 4f 41 54 3a 0a 20   SQLITE_FLOAT:. 
10250 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45       case SQLITE
10260 5f 49 4e 54 45 47 45 52 3a 20 7b 0a 20 20 20 20  _INTEGER: {.    
10270 20 20 20 20 6e 41 64 76 61 6e 63 65 20 3d 20 39      nAdvance = 9
10280 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 65 54  ;.        if( eT
10290 79 70 65 3d 3d 73 71 6c 69 74 65 33 5f 63 6f 6c  ype==sqlite3_col
102a0 75 6d 6e 5f 74 79 70 65 28 70 53 74 6d 74 2c 20  umn_type(pStmt, 
102b0 69 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  i) ){.          
102c0 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 56  sqlite3_int64 iV
102d0 61 6c 20 3d 20 73 65 73 73 69 6f 6e 47 65 74 49  al = sessionGetI
102e0 36 34 28 26 70 43 73 72 5b 31 5d 29 3b 0a 20 20  64(&pCsr[1]);.  
102f0 20 20 20 20 20 20 20 20 69 66 28 20 65 54 79 70          if( eTyp
10300 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45  e==SQLITE_INTEGE
10310 52 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  R ){.           
10320 20 69 66 28 20 69 56 61 6c 3d 3d 73 71 6c 69 74   if( iVal==sqlit
10330 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28  e3_column_int64(
10340 70 53 74 6d 74 2c 20 69 29 20 29 20 62 72 65 61  pStmt, i) ) brea
10350 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 65 6c  k;.          }el
10360 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  se{.            
10370 64 6f 75 62 6c 65 20 64 56 61 6c 3b 0a 20 20 20  double dVal;.   
10380 20 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28           memcpy(
10390 26 64 56 61 6c 2c 20 26 69 56 61 6c 2c 20 38 29  &dVal, &iVal, 8)
103a0 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  ;.            if
103b0 28 20 64 56 61 6c 3d 3d 73 71 6c 69 74 65 33 5f  ( dVal==sqlite3_
103c0 63 6f 6c 75 6d 6e 5f 64 6f 75 62 6c 65 28 70 53  column_double(pS
103d0 74 6d 74 2c 20 69 29 20 29 20 62 72 65 61 6b 3b  tmt, i) ) break;
103e0 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
103f0 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 62       }.        b
10400 43 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20 20 20  Changed = 1;.   
10410 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
10420 20 20 7d 0a 0a 20 20 20 20 20 20 64 65 66 61 75    }..      defau
10430 6c 74 3a 20 7b 0a 20 20 20 20 20 20 20 20 69 6e  lt: {.        in
10440 74 20 6e 3b 0a 20 20 20 20 20 20 20 20 69 6e 74  t n;.        int
10450 20 6e 48 64 72 20 3d 20 31 20 2b 20 73 65 73 73   nHdr = 1 + sess
10460 69 6f 6e 56 61 72 69 6e 74 47 65 74 28 26 70 43  ionVarintGet(&pC
10470 73 72 5b 31 5d 2c 20 26 6e 29 3b 0a 20 20 20 20  sr[1], &n);.    
10480 20 20 20 20 61 73 73 65 72 74 28 20 65 54 79 70      assert( eTyp
10490 65 3d 3d 53 51 4c 49 54 45 5f 54 45 58 54 20 7c  e==SQLITE_TEXT |
104a0 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f  | eType==SQLITE_
104b0 42 4c 4f 42 20 29 3b 0a 20 20 20 20 20 20 20 20  BLOB );.        
104c0 6e 41 64 76 61 6e 63 65 20 3d 20 6e 48 64 72 20  nAdvance = nHdr 
104d0 2b 20 6e 3b 0a 20 20 20 20 20 20 20 20 69 66 28  + n;.        if(
104e0 20 65 54 79 70 65 3d 3d 73 71 6c 69 74 65 33 5f   eType==sqlite3_
104f0 63 6f 6c 75 6d 6e 5f 74 79 70 65 28 70 53 74 6d  column_type(pStm
10500 74 2c 20 69 29 20 0a 20 20 20 20 20 20 20 20 20  t, i) .         
10510 26 26 20 6e 3d 3d 73 71 6c 69 74 65 33 5f 63 6f  && n==sqlite3_co
10520 6c 75 6d 6e 5f 62 79 74 65 73 28 70 53 74 6d 74  lumn_bytes(pStmt
10530 2c 20 69 29 20 0a 20 20 20 20 20 20 20 20 20 26  , i) .         &
10540 26 20 28 6e 3d 3d 30 20 7c 7c 20 30 3d 3d 6d 65  & (n==0 || 0==me
10550 6d 63 6d 70 28 26 70 43 73 72 5b 6e 48 64 72 5d  mcmp(&pCsr[nHdr]
10560 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  , sqlite3_column
10570 5f 62 6c 6f 62 28 70 53 74 6d 74 2c 20 69 29 2c  _blob(pStmt, i),
10580 20 6e 29 29 0a 20 20 20 20 20 20 20 20 29 7b 0a   n)).        ){.
10590 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b            break;
105a0 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
105b0 20 20 20 62 43 68 61 6e 67 65 64 20 3d 20 31 3b     bChanged = 1;
105c0 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
105d0 20 20 20 20 2f 2a 20 49 66 20 61 74 20 6c 65 61      /* If at lea
105e0 73 74 20 6f 6e 65 20 66 69 65 6c 64 20 68 61 73  st one field has
105f0 20 62 65 65 6e 20 6d 6f 64 69 66 69 65 64 2c 20   been modified, 
10600 74 68 69 73 20 69 73 20 6e 6f 74 20 61 20 6e 6f  this is not a no
10610 2d 6f 70 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20  -op. */.    if( 
10620 62 43 68 61 6e 67 65 64 20 29 20 62 4e 6f 6f 70  bChanged ) bNoop
10630 20 3d 20 30 3b 0a 0a 20 20 20 20 2f 2a 20 41 64   = 0;..    /* Ad
10640 64 20 61 20 66 69 65 6c 64 20 74 6f 20 74 68 65  d a field to the
10650 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 2e 20 54   old.* record. T
10660 68 69 73 20 69 73 20 6f 6d 69 74 74 65 64 20 69  his is omitted i
10670 66 20 74 68 69 73 20 6d 6f 64 75 6c 65 73 20 69  f this modules i
10680 73 0a 20 20 20 20 2a 2a 20 63 75 72 72 65 6e 74  s.    ** current
10690 6c 79 20 67 65 6e 65 72 61 74 69 6e 67 20 61 20  ly generating a 
106a0 70 61 74 63 68 73 65 74 2e 20 2a 2f 0a 20 20 20  patchset. */.   
106b0 20 69 66 28 20 62 50 61 74 63 68 73 65 74 3d 3d   if( bPatchset==
106c0 30 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 62  0 ){.      if( b
106d0 43 68 61 6e 67 65 64 20 7c 7c 20 61 62 50 4b 5b  Changed || abPK[
106e0 69 5d 20 29 7b 0a 20 20 20 20 20 20 20 20 73 65  i] ){.        se
106f0 73 73 69 6f 6e 41 70 70 65 6e 64 42 6c 6f 62 28  ssionAppendBlob(
10700 70 42 75 66 2c 20 70 43 73 72 2c 20 6e 41 64 76  pBuf, pCsr, nAdv
10710 61 6e 63 65 2c 20 26 72 63 29 3b 0a 20 20 20 20  ance, &rc);.    
10720 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
10730 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 79   sessionAppendBy
10740 74 65 28 70 42 75 66 2c 20 30 2c 20 26 72 63 29  te(pBuf, 0, &rc)
10750 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
10760 0a 20 20 20 20 2f 2a 20 41 64 64 20 61 20 66 69  .    /* Add a fi
10770 65 6c 64 20 74 6f 20 74 68 65 20 6e 65 77 2e 2a  eld to the new.*
10780 20 72 65 63 6f 72 64 2e 20 4f 72 20 74 68 65 20   record. Or the 
10790 6f 6e 6c 79 20 72 65 63 6f 72 64 20 69 66 20 63  only record if c
107a0 75 72 72 65 6e 74 6c 79 0a 20 20 20 20 2a 2a 20  urrently.    ** 
107b0 67 65 6e 65 72 61 74 69 6e 67 20 61 20 70 61 74  generating a pat
107c0 63 68 73 65 74 2e 20 20 2a 2f 0a 20 20 20 20 69  chset.  */.    i
107d0 66 28 20 62 43 68 61 6e 67 65 64 20 7c 7c 20 28  f( bChanged || (
107e0 62 50 61 74 63 68 73 65 74 20 26 26 20 61 62 50  bPatchset && abP
107f0 4b 5b 69 5d 29 20 29 7b 0a 20 20 20 20 20 20 73  K[i]) ){.      s
10800 65 73 73 69 6f 6e 41 70 70 65 6e 64 43 6f 6c 28  essionAppendCol(
10810 26 62 75 66 32 2c 20 70 53 74 6d 74 2c 20 69 2c  &buf2, pStmt, i,
10820 20 26 72 63 29 3b 0a 20 20 20 20 7d 65 6c 73 65   &rc);.    }else
10830 7b 0a 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41  {.      sessionA
10840 70 70 65 6e 64 42 79 74 65 28 26 62 75 66 32 2c  ppendByte(&buf2,
10850 20 30 2c 20 26 72 63 29 3b 0a 20 20 20 20 7d 0a   0, &rc);.    }.
10860 0a 20 20 20 20 70 43 73 72 20 2b 3d 20 6e 41 64  .    pCsr += nAd
10870 76 61 6e 63 65 3b 0a 20 20 7d 0a 0a 20 20 69 66  vance;.  }..  if
10880 28 20 62 4e 6f 6f 70 20 29 7b 0a 20 20 20 20 70  ( bNoop ){.    p
10890 42 75 66 2d 3e 6e 42 75 66 20 3d 20 6e 52 65 77  Buf->nBuf = nRew
108a0 69 6e 64 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  ind;.  }else{.  
108b0 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42    sessionAppendB
108c0 6c 6f 62 28 70 42 75 66 2c 20 62 75 66 32 2e 61  lob(pBuf, buf2.a
108d0 42 75 66 2c 20 62 75 66 32 2e 6e 42 75 66 2c 20  Buf, buf2.nBuf, 
108e0 26 72 63 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69  &rc);.  }.  sqli
108f0 74 65 33 5f 66 72 65 65 28 62 75 66 32 2e 61 42  te3_free(buf2.aB
10900 75 66 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72  uf);..  return r
10910 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65  c;.}../*.** Appe
10920 6e 64 20 61 20 44 45 4c 45 54 45 20 63 68 61 6e  nd a DELETE chan
10930 67 65 20 74 6f 20 74 68 65 20 62 75 66 66 65 72  ge to the buffer
10940 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66   passed as the f
10950 69 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 20 55  irst argument. U
10960 73 65 0a 2a 2a 20 74 68 65 20 63 68 61 6e 67 65  se.** the change
10970 73 65 74 20 66 6f 72 6d 61 74 20 69 66 20 61 72  set format if ar
10980 67 75 6d 65 6e 74 20 62 50 61 74 63 68 73 65 74  gument bPatchset
10990 20 69 73 20 7a 65 72 6f 2c 20 6f 72 20 74 68 65   is zero, or the
109a0 20 70 61 74 63 68 73 65 74 0a 2a 2a 20 66 6f 72   patchset.** for
109b0 6d 61 74 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a  mat otherwise..*
109c0 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73  /.static int ses
109d0 73 69 6f 6e 41 70 70 65 6e 64 44 65 6c 65 74 65  sionAppendDelete
109e0 28 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66 65  (.  SessionBuffe
109f0 72 20 2a 70 42 75 66 2c 20 20 20 20 20 20 20 20  r *pBuf,        
10a00 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f      /* Buffer to
10a10 20 61 70 70 65 6e 64 20 74 6f 20 2a 2f 0a 20 20   append to */.  
10a20 69 6e 74 20 62 50 61 74 63 68 73 65 74 2c 20 20  int bPatchset,  
10a30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10a40 2f 2a 20 54 72 75 65 20 66 6f 72 20 22 70 61 74  /* True for "pat
10a50 63 68 73 65 74 22 2c 20 30 20 66 6f 72 20 22 63  chset", 0 for "c
10a60 68 61 6e 67 65 73 65 74 22 20 2a 2f 0a 20 20 53  hangeset" */.  S
10a70 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 70 2c  essionChange *p,
10a80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
10a90 2a 20 4f 62 6a 65 63 74 20 63 6f 6e 74 61 69 6e  * Object contain
10aa0 69 6e 67 20 6f 6c 64 20 76 61 6c 75 65 73 20 2a  ing old values *
10ab0 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c 20 20 20  /.  int nCol,   
10ac0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10ad0 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
10ae0 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 61 62 6c   columns in tabl
10af0 65 20 2a 2f 0a 20 20 75 38 20 2a 61 62 50 4b 20  e */.  u8 *abPK 
10b00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10b10 20 20 20 20 20 20 20 2f 2a 20 42 6f 6f 6c 65 61         /* Boolea
10b20 6e 20 61 72 72 61 79 20 2d 20 74 72 75 65 20 66  n array - true f
10b30 6f 72 20 50 4b 20 63 6f 6c 75 6d 6e 73 20 2a 2f  or PK columns */
10b40 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
10b50 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 73 65 73  QLITE_OK;..  ses
10b60 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 70  sionAppendByte(p
10b70 42 75 66 2c 20 53 51 4c 49 54 45 5f 44 45 4c 45  Buf, SQLITE_DELE
10b80 54 45 2c 20 26 72 63 29 3b 0a 20 20 73 65 73 73  TE, &rc);.  sess
10b90 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28 70 42  ionAppendByte(pB
10ba0 75 66 2c 20 70 2d 3e 62 49 6e 64 69 72 65 63 74  uf, p->bIndirect
10bb0 2c 20 26 72 63 29 3b 0a 0a 20 20 69 66 28 20 62  , &rc);..  if( b
10bc0 50 61 74 63 68 73 65 74 3d 3d 30 20 29 7b 0a 20  Patchset==0 ){. 
10bd0 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
10be0 42 6c 6f 62 28 70 42 75 66 2c 20 70 2d 3e 61 52  Blob(pBuf, p->aR
10bf0 65 63 6f 72 64 2c 20 70 2d 3e 6e 52 65 63 6f 72  ecord, p->nRecor
10c00 64 2c 20 26 72 63 29 3b 0a 20 20 7d 65 6c 73 65  d, &rc);.  }else
10c10 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20  {.    int i;.   
10c20 20 75 38 20 2a 61 20 3d 20 70 2d 3e 61 52 65 63   u8 *a = p->aRec
10c30 6f 72 64 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30  ord;.    for(i=0
10c40 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a  ; i<nCol; i++){.
10c50 20 20 20 20 20 20 75 38 20 2a 70 53 74 61 72 74        u8 *pStart
10c60 20 3d 20 61 3b 0a 20 20 20 20 20 20 69 6e 74 20   = a;.      int 
10c70 65 54 79 70 65 20 3d 20 2a 61 2b 2b 3b 0a 0a 20  eType = *a++;.. 
10c80 20 20 20 20 20 73 77 69 74 63 68 28 20 65 54 79       switch( eTy
10c90 70 65 20 29 7b 0a 20 20 20 20 20 20 20 20 63 61  pe ){.        ca
10ca0 73 65 20 30 3a 0a 20 20 20 20 20 20 20 20 63 61  se 0:.        ca
10cb0 73 65 20 53 51 4c 49 54 45 5f 4e 55 4c 4c 3a 0a  se SQLITE_NULL:.
10cc0 20 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74            assert
10cd0 28 20 61 62 50 4b 5b 69 5d 3d 3d 30 20 29 3b 0a  ( abPK[i]==0 );.
10ce0 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b            break;
10cf0 0a 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 53  ..        case S
10d00 51 4c 49 54 45 5f 46 4c 4f 41 54 3a 0a 20 20 20  QLITE_FLOAT:.   
10d10 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45       case SQLITE
10d20 5f 49 4e 54 45 47 45 52 3a 0a 20 20 20 20 20 20  _INTEGER:.      
10d30 20 20 20 20 61 20 2b 3d 20 38 3b 0a 20 20 20 20      a += 8;.    
10d40 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20        break;..  
10d50 20 20 20 20 20 20 64 65 66 61 75 6c 74 3a 20 7b        default: {
10d60 0a 20 20 20 20 20 20 20 20 20 20 69 6e 74 20 6e  .          int n
10d70 3b 0a 20 20 20 20 20 20 20 20 20 20 61 20 2b 3d  ;.          a +=
10d80 20 73 65 73 73 69 6f 6e 56 61 72 69 6e 74 47 65   sessionVarintGe
10d90 74 28 61 2c 20 26 6e 29 3b 0a 20 20 20 20 20 20  t(a, &n);.      
10da0 20 20 20 20 61 20 2b 3d 20 6e 3b 0a 20 20 20 20      a += n;.    
10db0 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
10dc0 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
10dd0 20 20 20 20 20 69 66 28 20 61 62 50 4b 5b 69 5d       if( abPK[i]
10de0 20 29 7b 0a 20 20 20 20 20 20 20 20 73 65 73 73   ){.        sess
10df0 69 6f 6e 41 70 70 65 6e 64 42 6c 6f 62 28 70 42  ionAppendBlob(pB
10e00 75 66 2c 20 70 53 74 61 72 74 2c 20 28 69 6e 74  uf, pStart, (int
10e10 29 28 61 2d 70 53 74 61 72 74 29 2c 20 26 72 63  )(a-pStart), &rc
10e20 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
10e30 0a 20 20 20 20 61 73 73 65 72 74 28 20 28 61 20  .    assert( (a 
10e40 2d 20 70 2d 3e 61 52 65 63 6f 72 64 29 3d 3d 70  - p->aRecord)==p
10e50 2d 3e 6e 52 65 63 6f 72 64 20 29 3b 0a 20 20 7d  ->nRecord );.  }
10e60 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
10e70 0a 0a 2f 2a 0a 2a 2a 20 46 6f 72 6d 75 6c 61 74  ../*.** Formulat
10e80 65 20 61 6e 64 20 70 72 65 70 61 72 65 20 61 20  e and prepare a 
10e90 53 45 4c 45 43 54 20 73 74 61 74 65 6d 65 6e 74  SELECT statement
10ea0 20 74 6f 20 72 65 74 72 69 65 76 65 20 61 20 72   to retrieve a r
10eb0 6f 77 20 66 72 6f 6d 20 74 61 62 6c 65 0a 2a 2a  ow from table.**
10ec0 20 7a 54 61 62 20 69 6e 20 64 61 74 61 62 61 73   zTab in databas
10ed0 65 20 7a 44 62 20 62 61 73 65 64 20 6f 6e 20 69  e zDb based on i
10ee0 74 73 20 70 72 69 6d 61 72 79 20 6b 65 79 2e 20  ts primary key. 
10ef0 69 2e 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 53 45 4c  i.e..**.**   SEL
10f00 45 43 54 20 2a 20 46 52 4f 4d 20 7a 44 62 2e 7a  ECT * FROM zDb.z
10f10 54 61 62 20 57 48 45 52 45 20 70 6b 31 20 3d 20  Tab WHERE pk1 = 
10f20 3f 20 41 4e 44 20 70 6b 32 20 3d 20 3f 20 41 4e  ? AND pk2 = ? AN
10f30 44 20 2e 2e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  D ....*/.static 
10f40 69 6e 74 20 73 65 73 73 69 6f 6e 53 65 6c 65 63  int sessionSelec
10f50 74 53 74 6d 74 28 0a 20 20 73 71 6c 69 74 65 33  tStmt(.  sqlite3
10f60 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20 20   *db,           
10f70 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
10f80 62 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20  base handle */. 
10f90 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62   const char *zDb
10fa0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
10fb0 20 2f 2a 20 44 61 74 61 62 61 73 65 20 6e 61 6d   /* Database nam
10fc0 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  e */.  const cha
10fd0 72 20 2a 7a 54 61 62 2c 20 20 20 20 20 20 20 20  r *zTab,        
10fe0 20 20 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20         /* Table 
10ff0 6e 61 6d 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 43  name */.  int nC
11000 6f 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ol,             
11010 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
11020 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69  ber of columns i
11030 6e 20 74 61 62 6c 65 20 2a 2f 0a 20 20 63 6f 6e  n table */.  con
11040 73 74 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6c 2c  st char **azCol,
11050 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
11060 4e 61 6d 65 73 20 6f 66 20 74 61 62 6c 65 20 63  Names of table c
11070 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 75 38 20 2a  olumns */.  u8 *
11080 61 62 50 4b 2c 20 20 20 20 20 20 20 20 20 20 20  abPK,           
11090 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
110a0 52 49 4d 41 52 59 20 4b 45 59 20 20 61 72 72 61  RIMARY KEY  arra
110b0 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73  y */.  sqlite3_s
110c0 74 6d 74 20 2a 2a 70 70 53 74 6d 74 20 20 20 20  tmt **ppStmt    
110d0 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 50         /* OUT: P
110e0 72 65 70 61 72 65 64 20 53 45 4c 45 43 54 20 73  repared SELECT s
110f0 74 61 74 65 6d 65 6e 74 20 2a 2f 0a 29 7b 0a 20  tatement */.){. 
11100 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
11110 5f 4f 4b 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71  _OK;.  char *zSq
11120 6c 20 3d 20 30 3b 0a 20 20 69 6e 74 20 6e 53 71  l = 0;.  int nSq
11130 6c 20 3d 20 2d 31 3b 0a 0a 20 20 69 66 28 20 30  l = -1;..  if( 0
11140 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d  ==sqlite3_stricm
11150 70 28 22 73 71 6c 69 74 65 5f 73 74 61 74 31 22  p("sqlite_stat1"
11160 2c 20 7a 54 61 62 29 20 29 7b 0a 20 20 20 20 7a  , zTab) ){.    z
11170 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  Sql = sqlite3_mp
11180 72 69 6e 74 66 28 0a 20 20 20 20 20 20 20 20 22  rintf(.        "
11190 53 45 4c 45 43 54 20 74 62 6c 2c 20 3f 32 2c 20  SELECT tbl, ?2, 
111a0 73 74 61 74 20 46 52 4f 4d 20 25 51 2e 73 71 6c  stat FROM %Q.sql
111b0 69 74 65 5f 73 74 61 74 31 20 57 48 45 52 45 20  ite_stat1 WHERE 
111c0 74 62 6c 20 49 53 20 3f 31 20 41 4e 44 20 22 0a  tbl IS ?1 AND ".
111d0 20 20 20 20 20 20 20 20 22 69 64 78 20 49 53 20          "idx IS 
111e0 28 43 41 53 45 20 57 48 45 4e 20 3f 32 3d 58 27  (CASE WHEN ?2=X'
111f0 27 20 54 48 45 4e 20 4e 55 4c 4c 20 45 4c 53 45  ' THEN NULL ELSE
11200 20 3f 32 20 45 4e 44 29 22 2c 20 7a 44 62 0a 20   ?2 END)", zDb. 
11210 20 20 20 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20     );.  }else{. 
11220 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 63 6f     int i;.    co
11230 6e 73 74 20 63 68 61 72 20 2a 7a 53 65 70 20 3d  nst char *zSep =
11240 20 22 22 3b 0a 20 20 20 20 53 65 73 73 69 6f 6e   "";.    Session
11250 42 75 66 66 65 72 20 62 75 66 20 3d 20 7b 30 2c  Buffer buf = {0,
11260 20 30 2c 20 30 7d 3b 0a 0a 20 20 20 20 73 65 73   0, 0};..    ses
11270 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62  sionAppendStr(&b
11280 75 66 2c 20 22 53 45 4c 45 43 54 20 2a 20 46 52  uf, "SELECT * FR
11290 4f 4d 20 22 2c 20 26 72 63 29 3b 0a 20 20 20 20  OM ", &rc);.    
112a0 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49 64 65  sessionAppendIde
112b0 6e 74 28 26 62 75 66 2c 20 7a 44 62 2c 20 26 72  nt(&buf, zDb, &r
112c0 63 29 3b 0a 20 20 20 20 73 65 73 73 69 6f 6e 41  c);.    sessionA
112d0 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22  ppendStr(&buf, "
112e0 2e 22 2c 20 26 72 63 29 3b 0a 20 20 20 20 73 65  .", &rc);.    se
112f0 73 73 69 6f 6e 41 70 70 65 6e 64 49 64 65 6e 74  ssionAppendIdent
11300 28 26 62 75 66 2c 20 7a 54 61 62 2c 20 26 72 63  (&buf, zTab, &rc
11310 29 3b 0a 20 20 20 20 73 65 73 73 69 6f 6e 41 70  );.    sessionAp
11320 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 20  pendStr(&buf, " 
11330 57 48 45 52 45 20 22 2c 20 26 72 63 29 3b 0a 20  WHERE ", &rc);. 
11340 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43     for(i=0; i<nC
11350 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  ol; i++){.      
11360 69 66 28 20 61 62 50 4b 5b 69 5d 20 29 7b 0a 20  if( abPK[i] ){. 
11370 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70         sessionAp
11380 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 7a 53  pendStr(&buf, zS
11390 65 70 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20  ep, &rc);.      
113a0 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49    sessionAppendI
113b0 64 65 6e 74 28 26 62 75 66 2c 20 61 7a 43 6f 6c  dent(&buf, azCol
113c0 5b 69 5d 2c 20 26 72 63 29 3b 0a 20 20 20 20 20  [i], &rc);.     
113d0 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
113e0 53 74 72 28 26 62 75 66 2c 20 22 20 49 53 20 3f  Str(&buf, " IS ?
113f0 22 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20  ", &rc);.       
11400 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49 6e   sessionAppendIn
11410 74 65 67 65 72 28 26 62 75 66 2c 20 69 2b 31 2c  teger(&buf, i+1,
11420 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20 20 7a   &rc);.        z
11430 53 65 70 20 3d 20 22 20 41 4e 44 20 22 3b 0a 20  Sep = " AND ";. 
11440 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
11450 20 7a 53 71 6c 20 3d 20 28 63 68 61 72 2a 29 62   zSql = (char*)b
11460 75 66 2e 61 42 75 66 3b 0a 20 20 20 20 6e 53 71  uf.aBuf;.    nSq
11470 6c 20 3d 20 62 75 66 2e 6e 42 75 66 3b 0a 20 20  l = buf.nBuf;.  
11480 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
11490 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
114a0 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
114b0 72 65 5f 76 32 28 64 62 2c 20 7a 53 71 6c 2c 20  re_v2(db, zSql, 
114c0 6e 53 71 6c 2c 20 70 70 53 74 6d 74 2c 20 30 29  nSql, ppStmt, 0)
114d0 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  ;.  }.  sqlite3_
114e0 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 72 65  free(zSql);.  re
114f0 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
11500 2a 20 42 69 6e 64 20 74 68 65 20 50 52 49 4d 41  * Bind the PRIMA
11510 52 59 20 4b 45 59 20 76 61 6c 75 65 73 20 66 72  RY KEY values fr
11520 6f 6d 20 74 68 65 20 63 68 61 6e 67 65 20 70 61  om the change pa
11530 73 73 65 64 20 69 6e 20 61 72 67 75 6d 65 6e 74  ssed in argument
11540 20 70 43 68 61 6e 67 65 0a 2a 2a 20 74 6f 20 74   pChange.** to t
11550 68 65 20 53 45 4c 45 43 54 20 73 74 61 74 65 6d  he SELECT statem
11560 65 6e 74 20 70 61 73 73 65 64 20 61 73 20 74 68  ent passed as th
11570 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
11580 2e 20 54 68 65 20 53 45 4c 45 43 54 20 73 74 61  . The SELECT sta
11590 74 65 6d 65 6e 74 0a 2a 2a 20 69 73 20 61 73 20  tement.** is as 
115a0 70 72 65 70 61 72 65 64 20 62 79 20 66 75 6e 63  prepared by func
115b0 74 69 6f 6e 20 73 65 73 73 69 6f 6e 53 65 6c 65  tion sessionSele
115c0 63 74 53 74 6d 74 28 29 2e 0a 2a 2a 0a 2a 2a 20  ctStmt()..**.** 
115d0 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  Return SQLITE_OK
115e0 20 69 66 20 61 6c 6c 20 50 4b 20 76 61 6c 75 65   if all PK value
115f0 73 20 61 72 65 20 73 75 63 63 65 73 73 66 75 6c  s are successful
11600 6c 79 20 62 6f 75 6e 64 2c 20 6f 72 20 61 6e 20  ly bound, or an 
11610 53 51 4c 69 74 65 0a 2a 2a 20 65 72 72 6f 72 20  SQLite.** error 
11620 63 6f 64 65 20 28 65 2e 67 2e 20 53 51 4c 49 54  code (e.g. SQLIT
11630 45 5f 4e 4f 4d 45 4d 29 20 6f 74 68 65 72 77 69  E_NOMEM) otherwi
11640 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  se..*/.static in
11650 74 20 73 65 73 73 69 6f 6e 53 65 6c 65 63 74 42  t sessionSelectB
11660 69 6e 64 28 0a 20 20 73 71 6c 69 74 65 33 5f 73  ind(.  sqlite3_s
11670 74 6d 74 20 2a 70 53 65 6c 65 63 74 2c 20 20 20  tmt *pSelect,   
11680 20 20 20 20 20 20 20 2f 2a 20 53 45 4c 45 43 54         /* SELECT
11690 20 66 72 6f 6d 20 73 65 73 73 69 6f 6e 53 65 6c   from sessionSel
116a0 65 63 74 53 74 6d 74 28 29 20 2a 2f 0a 20 20 69  ectStmt() */.  i
116b0 6e 74 20 6e 43 6f 6c 2c 20 20 20 20 20 20 20 20  nt nCol,        
116c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
116d0 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75  * Number of colu
116e0 6d 6e 73 20 69 6e 20 74 61 62 6c 65 20 2a 2f 0a  mns in table */.
116f0 20 20 75 38 20 2a 61 62 50 4b 2c 20 20 20 20 20    u8 *abPK,     
11700 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11710 20 20 2f 2a 20 50 52 49 4d 41 52 59 20 4b 45 59    /* PRIMARY KEY
11720 20 61 72 72 61 79 20 2a 2f 0a 20 20 53 65 73 73   array */.  Sess
11730 69 6f 6e 43 68 61 6e 67 65 20 2a 70 43 68 61 6e  ionChange *pChan
11740 67 65 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43  ge          /* C
11750 68 61 6e 67 65 20 73 74 72 75 63 74 75 72 65 20  hange structure 
11760 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  */.){.  int i;. 
11770 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
11780 5f 4f 4b 3b 0a 20 20 75 38 20 2a 61 20 3d 20 70  _OK;.  u8 *a = p
11790 43 68 61 6e 67 65 2d 3e 61 52 65 63 6f 72 64 3b  Change->aRecord;
117a0 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e  ..  for(i=0; i<n
117b0 43 6f 6c 20 26 26 20 72 63 3d 3d 53 51 4c 49 54  Col && rc==SQLIT
117c0 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  E_OK; i++){.    
117d0 69 6e 74 20 65 54 79 70 65 20 3d 20 2a 61 2b 2b  int eType = *a++
117e0 3b 0a 0a 20 20 20 20 73 77 69 74 63 68 28 20 65  ;..    switch( e
117f0 54 79 70 65 20 29 7b 0a 20 20 20 20 20 20 63 61  Type ){.      ca
11800 73 65 20 30 3a 0a 20 20 20 20 20 20 63 61 73 65  se 0:.      case
11810 20 53 51 4c 49 54 45 5f 4e 55 4c 4c 3a 0a 20 20   SQLITE_NULL:.  
11820 20 20 20 20 20 20 61 73 73 65 72 74 28 20 61 62        assert( ab
11830 50 4b 5b 69 5d 3d 3d 30 20 29 3b 0a 20 20 20 20  PK[i]==0 );.    
11840 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20      break;..    
11850 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e    case SQLITE_IN
11860 54 45 47 45 52 3a 20 7b 0a 20 20 20 20 20 20 20  TEGER: {.       
11870 20 69 66 28 20 61 62 50 4b 5b 69 5d 20 29 7b 0a   if( abPK[i] ){.
11880 20 20 20 20 20 20 20 20 20 20 69 36 34 20 69 56            i64 iV
11890 61 6c 20 3d 20 73 65 73 73 69 6f 6e 47 65 74 49  al = sessionGetI
118a0 36 34 28 61 29 3b 0a 20 20 20 20 20 20 20 20 20  64(a);.         
118b0 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69   rc = sqlite3_bi
118c0 6e 64 5f 69 6e 74 36 34 28 70 53 65 6c 65 63 74  nd_int64(pSelect
118d0 2c 20 69 2b 31 2c 20 69 56 61 6c 29 3b 0a 20 20  , i+1, iVal);.  
118e0 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
118f0 61 20 2b 3d 20 38 3b 0a 20 20 20 20 20 20 20 20  a += 8;.        
11900 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a  break;.      }..
11910 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54        case SQLIT
11920 45 5f 46 4c 4f 41 54 3a 20 7b 0a 20 20 20 20 20  E_FLOAT: {.     
11930 20 20 20 69 66 28 20 61 62 50 4b 5b 69 5d 20 29     if( abPK[i] )
11940 7b 0a 20 20 20 20 20 20 20 20 20 20 64 6f 75 62  {.          doub
11950 6c 65 20 72 56 61 6c 3b 0a 20 20 20 20 20 20 20  le rVal;.       
11960 20 20 20 69 36 34 20 69 56 61 6c 20 3d 20 73 65     i64 iVal = se
11970 73 73 69 6f 6e 47 65 74 49 36 34 28 61 29 3b 0a  ssionGetI64(a);.
11980 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79            memcpy
11990 28 26 72 56 61 6c 2c 20 26 69 56 61 6c 2c 20 38  (&rVal, &iVal, 8
119a0 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  );.          rc 
119b0 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 64  = sqlite3_bind_d
119c0 6f 75 62 6c 65 28 70 53 65 6c 65 63 74 2c 20 69  ouble(pSelect, i
119d0 2b 31 2c 20 72 56 61 6c 29 3b 0a 20 20 20 20 20  +1, rVal);.     
119e0 20 20 20 7d 0a 20 20 20 20 20 20 20 20 61 20 2b     }.        a +
119f0 3d 20 38 3b 0a 20 20 20 20 20 20 20 20 62 72 65  = 8;.        bre
11a00 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20  ak;.      }..   
11a10 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 54     case SQLITE_T
11a20 45 58 54 3a 20 7b 0a 20 20 20 20 20 20 20 20 69  EXT: {.        i
11a30 6e 74 20 6e 3b 0a 20 20 20 20 20 20 20 20 61 20  nt n;.        a 
11a40 2b 3d 20 73 65 73 73 69 6f 6e 56 61 72 69 6e 74  += sessionVarint
11a50 47 65 74 28 61 2c 20 26 6e 29 3b 0a 20 20 20 20  Get(a, &n);.    
11a60 20 20 20 20 69 66 28 20 61 62 50 4b 5b 69 5d 20      if( abPK[i] 
11a70 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  ){.          rc 
11a80 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 74  = sqlite3_bind_t
11a90 65 78 74 28 70 53 65 6c 65 63 74 2c 20 69 2b 31  ext(pSelect, i+1
11aa0 2c 20 28 63 68 61 72 20 2a 29 61 2c 20 6e 2c 20  , (char *)a, n, 
11ab0 53 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54  SQLITE_TRANSIENT
11ac0 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  );.        }.   
11ad0 20 20 20 20 20 61 20 2b 3d 20 6e 3b 0a 20 20 20       a += n;.   
11ae0 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
11af0 20 20 7d 0a 0a 20 20 20 20 20 20 64 65 66 61 75    }..      defau
11b00 6c 74 3a 20 7b 0a 20 20 20 20 20 20 20 20 69 6e  lt: {.        in
11b10 74 20 6e 3b 0a 20 20 20 20 20 20 20 20 61 73 73  t n;.        ass
11b20 65 72 74 28 20 65 54 79 70 65 3d 3d 53 51 4c 49  ert( eType==SQLI
11b30 54 45 5f 42 4c 4f 42 20 29 3b 0a 20 20 20 20 20  TE_BLOB );.     
11b40 20 20 20 61 20 2b 3d 20 73 65 73 73 69 6f 6e 56     a += sessionV
11b50 61 72 69 6e 74 47 65 74 28 61 2c 20 26 6e 29 3b  arintGet(a, &n);
11b60 0a 20 20 20 20 20 20 20 20 69 66 28 20 61 62 50  .        if( abP
11b70 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20 20 20  K[i] ){.        
11b80 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62    rc = sqlite3_b
11b90 69 6e 64 5f 62 6c 6f 62 28 70 53 65 6c 65 63 74  ind_blob(pSelect
11ba0 2c 20 69 2b 31 2c 20 61 2c 20 6e 2c 20 53 51 4c  , i+1, a, n, SQL
11bb0 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a  ITE_TRANSIENT);.
11bc0 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
11bd0 20 20 61 20 2b 3d 20 6e 3b 0a 20 20 20 20 20 20    a += n;.      
11be0 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d    break;.      }
11bf0 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
11c00 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
11c10 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
11c20 69 73 20 61 20 6e 6f 2d 6f 70 20 69 66 20 2a 70  is a no-op if *p
11c30 52 63 20 69 73 20 73 65 74 20 74 6f 20 6f 74 68  Rc is set to oth
11c40 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45 5f 4f  er than SQLITE_O
11c50 4b 20 77 68 65 6e 20 69 74 0a 2a 2a 20 69 73 20  K when it.** is 
11c60 63 61 6c 6c 65 64 2e 20 4f 74 68 65 72 77 69 73  called. Otherwis
11c70 65 2c 20 61 70 70 65 6e 64 20 61 20 73 65 72 69  e, append a seri
11c80 61 6c 69 7a 65 64 20 74 61 62 6c 65 20 68 65 61  alized table hea
11c90 64 65 72 20 28 70 61 72 74 20 6f 66 20 74 68 65  der (part of the
11ca0 20 62 69 6e 61 72 79 20 0a 2a 2a 20 63 68 61 6e   binary .** chan
11cb0 67 65 73 65 74 20 66 6f 72 6d 61 74 29 20 74 6f  geset format) to
11cc0 20 62 75 66 66 65 72 20 2a 70 42 75 66 2e 20 49   buffer *pBuf. I
11cd0 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
11ce0 73 2c 20 73 65 74 20 2a 70 52 63 20 74 6f 20 61  s, set *pRc to a
11cf0 6e 0a 2a 2a 20 53 51 4c 69 74 65 20 65 72 72 6f  n.** SQLite erro
11d00 72 20 63 6f 64 65 20 62 65 66 6f 72 65 20 72 65  r code before re
11d10 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74  turning..*/.stat
11d20 69 63 20 76 6f 69 64 20 73 65 73 73 69 6f 6e 41  ic void sessionA
11d30 70 70 65 6e 64 54 61 62 6c 65 48 64 72 28 0a 20  ppendTableHdr(. 
11d40 20 53 65 73 73 69 6f 6e 42 75 66 66 65 72 20 2a   SessionBuffer *
11d50 70 42 75 66 2c 20 20 20 20 20 20 20 20 20 20 20  pBuf,           
11d60 20 2f 2a 20 41 70 70 65 6e 64 20 68 65 61 64 65   /* Append heade
11d70 72 20 74 6f 20 74 68 69 73 20 62 75 66 66 65 72  r to this buffer
11d80 20 2a 2f 0a 20 20 69 6e 74 20 62 50 61 74 63 68   */.  int bPatch
11d90 73 65 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  set,            
11da0 20 20 20 20 20 20 2f 2a 20 55 73 65 20 74 68 65        /* Use the
11db0 20 70 61 74 63 68 73 65 74 20 66 6f 72 6d 61 74   patchset format
11dc0 20 69 66 20 74 72 75 65 20 2a 2f 0a 20 20 53 65   if true */.  Se
11dd0 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70 54 61 62  ssionTable *pTab
11de0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
11df0 20 54 61 62 6c 65 20 6f 62 6a 65 63 74 20 74 6f   Table object to
11e00 20 61 70 70 65 6e 64 20 68 65 61 64 65 72 20 66   append header f
11e10 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 52 63  or */.  int *pRc
11e20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11e30 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55          /* IN/OU
11e40 54 3a 20 45 72 72 6f 72 20 63 6f 64 65 20 2a 2f  T: Error code */
11e50 0a 29 7b 0a 20 20 2f 2a 20 57 72 69 74 65 20 61  .){.  /* Write a
11e60 20 74 61 62 6c 65 20 68 65 61 64 65 72 20 2a 2f   table header */
11e70 0a 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64  .  sessionAppend
11e80 42 79 74 65 28 70 42 75 66 2c 20 28 62 50 61 74  Byte(pBuf, (bPat
11e90 63 68 73 65 74 20 3f 20 27 50 27 20 3a 20 27 54  chset ? 'P' : 'T
11ea0 27 29 2c 20 70 52 63 29 3b 0a 20 20 73 65 73 73  '), pRc);.  sess
11eb0 69 6f 6e 41 70 70 65 6e 64 56 61 72 69 6e 74 28  ionAppendVarint(
11ec0 70 42 75 66 2c 20 70 54 61 62 2d 3e 6e 43 6f 6c  pBuf, pTab->nCol
11ed0 2c 20 70 52 63 29 3b 0a 20 20 73 65 73 73 69 6f  , pRc);.  sessio
11ee0 6e 41 70 70 65 6e 64 42 6c 6f 62 28 70 42 75 66  nAppendBlob(pBuf
11ef0 2c 20 70 54 61 62 2d 3e 61 62 50 4b 2c 20 70 54  , pTab->abPK, pT
11f00 61 62 2d 3e 6e 43 6f 6c 2c 20 70 52 63 29 3b 0a  ab->nCol, pRc);.
11f10 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42    sessionAppendB
11f20 6c 6f 62 28 70 42 75 66 2c 20 28 75 38 20 2a 29  lob(pBuf, (u8 *)
11f30 70 54 61 62 2d 3e 7a 4e 61 6d 65 2c 20 28 69 6e  pTab->zName, (in
11f40 74 29 73 74 72 6c 65 6e 28 70 54 61 62 2d 3e 7a  t)strlen(pTab->z
11f50 4e 61 6d 65 29 2b 31 2c 20 70 52 63 29 3b 0a 7d  Name)+1, pRc);.}
11f60 0a 0a 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65  ../*.** Generate
11f70 20 65 69 74 68 65 72 20 61 20 63 68 61 6e 67 65   either a change
11f80 73 65 74 20 28 69 66 20 61 72 67 75 6d 65 6e 74  set (if argument
11f90 20 62 50 61 74 63 68 73 65 74 20 69 73 20 7a 65   bPatchset is ze
11fa0 72 6f 29 20 6f 72 20 61 20 70 61 74 63 68 73 65  ro) or a patchse
11fb0 74 0a 2a 2a 20 28 69 66 20 69 74 20 69 73 20 6e  t.** (if it is n
11fc0 6f 6e 2d 7a 65 72 6f 29 20 62 61 73 65 64 20 6f  on-zero) based o
11fd0 6e 20 74 68 65 20 63 75 72 72 65 6e 74 20 63 6f  n the current co
11fe0 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 73 65  ntents of the se
11ff0 73 73 69 6f 6e 20 6f 62 6a 65 63 74 0a 2a 2a 20  ssion object.** 
12000 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69  passed as the fi
12010 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a  rst argument..**
12020 0a 2a 2a 20 49 66 20 6e 6f 20 65 72 72 6f 72 20  .** If no error 
12030 6f 63 63 75 72 73 2c 20 53 51 4c 49 54 45 5f 4f  occurs, SQLITE_O
12040 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e  K is returned an
12050 64 20 74 68 65 20 6e 65 77 20 63 68 61 6e 67 65  d the new change
12060 73 65 74 2f 70 61 74 63 68 73 65 74 0a 2a 2a 20  set/patchset.** 
12070 73 74 6f 72 65 64 20 69 6e 20 6f 75 74 70 75 74  stored in output
12080 20 76 61 72 69 61 62 6c 65 73 20 2a 70 6e 43 68   variables *pnCh
12090 61 6e 67 65 73 65 74 20 61 6e 64 20 2a 70 70 43  angeset and *ppC
120a0 68 61 6e 67 65 73 65 74 2e 20 4f 72 2c 20 69 66  hangeset. Or, if
120b0 20 61 6e 20 65 72 72 6f 72 0a 2a 2a 20 6f 63 63   an error.** occ
120c0 75 72 73 2c 20 61 6e 20 53 51 4c 69 74 65 20 65  urs, an SQLite e
120d0 72 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74  rror code is ret
120e0 75 72 6e 65 64 20 61 6e 64 20 62 6f 74 68 20 6f  urned and both o
120f0 75 74 70 75 74 20 76 61 72 69 61 62 6c 65 73 20  utput variables 
12100 73 65 74 20 0a 2a 2a 20 74 6f 20 30 2e 0a 2a 2f  set .** to 0..*/
12110 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73  .static int sess
12120 69 6f 6e 47 65 6e 65 72 61 74 65 43 68 61 6e 67  ionGenerateChang
12130 65 73 65 74 28 0a 20 20 73 71 6c 69 74 65 33 5f  eset(.  sqlite3_
12140 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f  session *pSessio
12150 6e 2c 20 20 20 20 20 20 2f 2a 20 53 65 73 73 69  n,      /* Sessi
12160 6f 6e 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69  on object */.  i
12170 6e 74 20 62 50 61 74 63 68 73 65 74 2c 20 20 20  nt bPatchset,   
12180 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
12190 2a 20 54 72 75 65 20 66 6f 72 20 70 61 74 63 68  * True for patch
121a0 73 65 74 2c 20 66 61 6c 73 65 20 66 6f 72 20 63  set, false for c
121b0 68 61 6e 67 65 73 65 74 20 2a 2f 0a 20 20 69 6e  hangeset */.  in
121c0 74 20 28 2a 78 4f 75 74 70 75 74 29 28 76 6f 69  t (*xOutput)(voi
121d0 64 20 2a 70 4f 75 74 2c 20 63 6f 6e 73 74 20 76  d *pOut, const v
121e0 6f 69 64 20 2a 70 44 61 74 61 2c 20 69 6e 74 20  oid *pData, int 
121f0 6e 44 61 74 61 29 2c 0a 20 20 76 6f 69 64 20 2a  nData),.  void *
12200 70 4f 75 74 2c 20 20 20 20 20 20 20 20 20 20 20  pOut,           
12210 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72            /* Fir
12220 73 74 20 61 72 67 75 6d 65 6e 74 20 66 6f 72 20  st argument for 
12230 78 4f 75 74 70 75 74 20 2a 2f 0a 20 20 69 6e 74  xOutput */.  int
12240 20 2a 70 6e 43 68 61 6e 67 65 73 65 74 2c 20 20   *pnChangeset,  
12250 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
12260 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20 62 75 66  OUT: Size of buf
12270 66 65 72 20 61 74 20 2a 70 70 43 68 61 6e 67 65  fer at *ppChange
12280 73 65 74 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 2a  set */.  void **
12290 70 70 43 68 61 6e 67 65 73 65 74 20 20 20 20 20  ppChangeset     
122a0 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
122b0 20 42 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69   Buffer containi
122c0 6e 67 20 63 68 61 6e 67 65 73 65 74 20 2a 2f 0a  ng changeset */.
122d0 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  ){.  sqlite3 *db
122e0 20 3d 20 70 53 65 73 73 69 6f 6e 2d 3e 64 62 3b   = pSession->db;
122f0 20 20 20 20 20 2f 2a 20 53 6f 75 72 63 65 20 64       /* Source d
12300 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a  atabase handle *
12310 2f 0a 20 20 53 65 73 73 69 6f 6e 54 61 62 6c 65  /.  SessionTable
12320 20 2a 70 54 61 62 3b 20 20 20 20 20 20 20 20 20   *pTab;         
12330 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69      /* Used to i
12340 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 61  terate through a
12350 74 74 61 63 68 65 64 20 74 61 62 6c 65 73 20 2a  ttached tables *
12360 2f 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66 65  /.  SessionBuffe
12370 72 20 62 75 66 20 3d 20 7b 30 2c 30 2c 30 7d 3b  r buf = {0,0,0};
12380 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 69 6e      /* Buffer in
12390 20 77 68 69 63 68 20 74 6f 20 61 63 63 75 6d 6c   which to accuml
123a0 61 74 65 20 63 68 61 6e 67 65 73 65 74 20 2a 2f  ate changeset */
123b0 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
123c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
123d0 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
123e0 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20  e */..  assert( 
123f0 78 4f 75 74 70 75 74 3d 3d 30 20 7c 7c 20 28 70  xOutput==0 || (p
12400 6e 43 68 61 6e 67 65 73 65 74 3d 3d 30 20 26 26  nChangeset==0 &&
12410 20 70 70 43 68 61 6e 67 65 73 65 74 3d 3d 30 20   ppChangeset==0 
12420 29 20 29 3b 0a 0a 20 20 2f 2a 20 5a 65 72 6f 20  ) );..  /* Zero 
12430 74 68 65 20 6f 75 74 70 75 74 20 76 61 72 69 61  the output varia
12440 62 6c 65 73 20 69 6e 20 63 61 73 65 20 61 6e 20  bles in case an 
12450 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 20 49 66  error occurs. If
12460 20 74 68 69 73 20 73 65 73 73 69 6f 6e 0a 20 20   this session.  
12470 2a 2a 20 6f 62 6a 65 63 74 20 69 73 20 61 6c 72  ** object is alr
12480 65 61 64 79 20 69 6e 20 74 68 65 20 65 72 72 6f  eady in the erro
12490 72 20 73 74 61 74 65 20 28 73 71 6c 69 74 65 33  r state (sqlite3
124a0 5f 73 65 73 73 69 6f 6e 2e 72 63 20 21 3d 20 53  _session.rc != S
124b0 51 4c 49 54 45 5f 4f 4b 29 2c 0a 20 20 2a 2a 20  QLITE_OK),.  ** 
124c0 74 68 69 73 20 63 61 6c 6c 20 77 69 6c 6c 20 62  this call will b
124d0 65 20 61 20 6e 6f 2d 6f 70 2e 20 20 2a 2f 0a 20  e a no-op.  */. 
124e0 20 69 66 28 20 78 4f 75 74 70 75 74 3d 3d 30 20   if( xOutput==0 
124f0 29 7b 0a 20 20 20 20 2a 70 6e 43 68 61 6e 67 65  ){.    *pnChange
12500 73 65 74 20 3d 20 30 3b 0a 20 20 20 20 2a 70 70  set = 0;.    *pp
12510 43 68 61 6e 67 65 73 65 74 20 3d 20 30 3b 0a 20  Changeset = 0;. 
12520 20 7d 0a 0a 20 20 69 66 28 20 70 53 65 73 73 69   }..  if( pSessi
12530 6f 6e 2d 3e 72 63 20 29 20 72 65 74 75 72 6e 20  on->rc ) return 
12540 70 53 65 73 73 69 6f 6e 2d 3e 72 63 3b 0a 20 20  pSession->rc;.  
12550 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65  rc = sqlite3_exe
12560 63 28 70 53 65 73 73 69 6f 6e 2d 3e 64 62 2c 20  c(pSession->db, 
12570 22 53 41 56 45 50 4f 49 4e 54 20 63 68 61 6e 67  "SAVEPOINT chang
12580 65 73 65 74 22 2c 20 30 2c 20 30 2c 20 30 29 3b  eset", 0, 0, 0);
12590 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
125a0 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  E_OK ) return rc
125b0 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74  ;..  sqlite3_mut
125c0 65 78 5f 65 6e 74 65 72 28 73 71 6c 69 74 65 33  ex_enter(sqlite3
125d0 5f 64 62 5f 6d 75 74 65 78 28 64 62 29 29 3b 0a  _db_mutex(db));.
125e0 0a 20 20 66 6f 72 28 70 54 61 62 3d 70 53 65 73  .  for(pTab=pSes
125f0 73 69 6f 6e 2d 3e 70 54 61 62 6c 65 3b 20 72 63  sion->pTable; rc
12600 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70  ==SQLITE_OK && p
12610 54 61 62 3b 20 70 54 61 62 3d 70 54 61 62 2d 3e  Tab; pTab=pTab->
12620 70 4e 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20  pNext){.    if( 
12630 70 54 61 62 2d 3e 6e 45 6e 74 72 79 20 29 7b 0a  pTab->nEntry ){.
12640 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
12650 20 2a 7a 4e 61 6d 65 20 3d 20 70 54 61 62 2d 3e   *zName = pTab->
12660 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 20 69 6e 74  zName;.      int
12670 20 6e 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20   nCol;          
12680 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
12690 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e  er of columns in
126a0 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20 20 20   table */.      
126b0 75 38 20 2a 61 62 50 4b 3b 20 20 20 20 20 20 20  u8 *abPK;       
126c0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
126d0 72 69 6d 61 72 79 20 6b 65 79 20 61 72 72 61 79  rimary key array
126e0 20 2a 2f 0a 20 20 20 20 20 20 63 6f 6e 73 74 20   */.      const 
126f0 63 68 61 72 20 2a 2a 61 7a 43 6f 6c 20 3d 20 30  char **azCol = 0
12700 3b 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20 63  ;     /* Table c
12710 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 20 20 20 20  olumns */.      
12720 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20  int i;          
12730 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55              /* U
12740 73 65 64 20 74 6f 20 69 74 65 72 61 74 65 20 74  sed to iterate t
12750 68 72 6f 75 67 68 20 68 61 73 68 20 62 75 63 6b  hrough hash buck
12760 65 74 73 20 2a 2f 0a 20 20 20 20 20 20 73 71 6c  ets */.      sql
12770 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 65 6c 20  ite3_stmt *pSel 
12780 3d 20 30 3b 20 20 20 20 20 2f 2a 20 53 45 4c 45  = 0;     /* SELE
12790 43 54 20 73 74 61 74 65 6d 65 6e 74 20 74 6f 20  CT statement to 
127a0 71 75 65 72 79 20 74 61 62 6c 65 20 70 54 61 62  query table pTab
127b0 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e 52   */.      int nR
127c0 65 77 69 6e 64 20 3d 20 62 75 66 2e 6e 42 75 66  ewind = buf.nBuf
127d0 3b 20 20 20 20 20 2f 2a 20 49 6e 69 74 69 61 6c  ;     /* Initial
127e0 20 73 69 7a 65 20 6f 66 20 77 72 69 74 65 20 62   size of write b
127f0 75 66 66 65 72 20 2a 2f 0a 20 20 20 20 20 20 69  uffer */.      i
12800 6e 74 20 6e 4e 6f 6f 70 3b 20 20 20 20 20 20 20  nt nNoop;       
12810 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
12820 7a 65 20 6f 66 20 62 75 66 66 65 72 20 61 66 74  ze of buffer aft
12830 65 72 20 77 72 69 74 69 6e 67 20 74 62 6c 20 68  er writing tbl h
12840 65 61 64 65 72 20 2a 2f 0a 0a 20 20 20 20 20 20  eader */..      
12850 2f 2a 20 43 68 65 63 6b 20 74 68 65 20 74 61 62  /* Check the tab
12860 6c 65 20 73 63 68 65 6d 61 20 69 73 20 73 74 69  le schema is sti
12870 6c 6c 20 4f 6b 2e 20 2a 2f 0a 20 20 20 20 20 20  ll Ok. */.      
12880 72 63 20 3d 20 73 65 73 73 69 6f 6e 54 61 62 6c  rc = sessionTabl
12890 65 49 6e 66 6f 28 64 62 2c 20 70 53 65 73 73 69  eInfo(db, pSessi
128a0 6f 6e 2d 3e 7a 44 62 2c 20 7a 4e 61 6d 65 2c 20  on->zDb, zName, 
128b0 26 6e 43 6f 6c 2c 20 30 2c 20 26 61 7a 43 6f 6c  &nCol, 0, &azCol
128c0 2c 20 26 61 62 50 4b 29 3b 0a 20 20 20 20 20 20  , &abPK);.      
128d0 69 66 28 20 21 72 63 20 26 26 20 28 70 54 61 62  if( !rc && (pTab
128e0 2d 3e 6e 43 6f 6c 21 3d 6e 43 6f 6c 20 7c 7c 20  ->nCol!=nCol || 
128f0 6d 65 6d 63 6d 70 28 61 62 50 4b 2c 20 70 54 61  memcmp(abPK, pTa
12900 62 2d 3e 61 62 50 4b 2c 20 6e 43 6f 6c 29 29 20  b->abPK, nCol)) 
12910 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  ){.        rc = 
12920 53 51 4c 49 54 45 5f 53 43 48 45 4d 41 3b 0a 20  SQLITE_SCHEMA;. 
12930 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a       }..      /*
12940 20 57 72 69 74 65 20 61 20 74 61 62 6c 65 20 68   Write a table h
12950 65 61 64 65 72 20 2a 2f 0a 20 20 20 20 20 20 73  eader */.      s
12960 65 73 73 69 6f 6e 41 70 70 65 6e 64 54 61 62 6c  essionAppendTabl
12970 65 48 64 72 28 26 62 75 66 2c 20 62 50 61 74 63  eHdr(&buf, bPatc
12980 68 73 65 74 2c 20 70 54 61 62 2c 20 26 72 63 29  hset, pTab, &rc)
12990 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 42 75 69 6c  ;..      /* Buil
129a0 64 20 61 6e 64 20 63 6f 6d 70 69 6c 65 20 61 20  d and compile a 
129b0 73 74 61 74 65 6d 65 6e 74 20 74 6f 20 65 78 65  statement to exe
129c0 63 75 74 65 3a 20 2a 2f 0a 20 20 20 20 20 20 69  cute: */.      i
129d0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
129e0 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d   ){.        rc =
129f0 20 73 65 73 73 69 6f 6e 53 65 6c 65 63 74 53 74   sessionSelectSt
12a00 6d 74 28 0a 20 20 20 20 20 20 20 20 20 20 20 20  mt(.            
12a10 64 62 2c 20 70 53 65 73 73 69 6f 6e 2d 3e 7a 44  db, pSession->zD
12a20 62 2c 20 7a 4e 61 6d 65 2c 20 6e 43 6f 6c 2c 20  b, zName, nCol, 
12a30 61 7a 43 6f 6c 2c 20 61 62 50 4b 2c 20 26 70 53  azCol, abPK, &pS
12a40 65 6c 29 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20  el);.      }..  
12a50 20 20 20 20 6e 4e 6f 6f 70 20 3d 20 62 75 66 2e      nNoop = buf.
12a60 6e 42 75 66 3b 0a 20 20 20 20 20 20 66 6f 72 28  nBuf;.      for(
12a70 69 3d 30 3b 20 69 3c 70 54 61 62 2d 3e 6e 43 68  i=0; i<pTab->nCh
12a80 61 6e 67 65 20 26 26 20 72 63 3d 3d 53 51 4c 49  ange && rc==SQLI
12a90 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20 20  TE_OK; i++){.   
12aa0 20 20 20 20 20 53 65 73 73 69 6f 6e 43 68 61 6e       SessionChan
12ab0 67 65 20 2a 70 3b 20 20 20 20 20 20 20 20 20 2f  ge *p;         /
12ac0 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72 61 74  * Used to iterat
12ad0 65 20 74 68 72 6f 75 67 68 20 63 68 61 6e 67 65  e through change
12ae0 73 20 2a 2f 0a 0a 20 20 20 20 20 20 20 20 66 6f  s */..        fo
12af0 72 28 70 3d 70 54 61 62 2d 3e 61 70 43 68 61 6e  r(p=pTab->apChan
12b00 67 65 5b 69 5d 3b 20 72 63 3d 3d 53 51 4c 49 54  ge[i]; rc==SQLIT
12b10 45 5f 4f 4b 20 26 26 20 70 3b 20 70 3d 70 2d 3e  E_OK && p; p=p->
12b20 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 20 20  pNext){.        
12b30 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 53 65    rc = sessionSe
12b40 6c 65 63 74 42 69 6e 64 28 70 53 65 6c 2c 20 6e  lectBind(pSel, n
12b50 43 6f 6c 2c 20 61 62 50 4b 2c 20 70 29 3b 0a 20  Col, abPK, p);. 
12b60 20 20 20 20 20 20 20 20 20 69 66 28 20 72 63 21           if( rc!
12b70 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 63 6f 6e  =SQLITE_OK ) con
12b80 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 20 20 20  tinue;.         
12b90 20 69 66 28 20 73 71 6c 69 74 65 33 5f 73 74 65   if( sqlite3_ste
12ba0 70 28 70 53 65 6c 29 3d 3d 53 51 4c 49 54 45 5f  p(pSel)==SQLITE_
12bb0 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ROW ){.         
12bc0 20 20 20 69 66 28 20 70 2d 3e 6f 70 3d 3d 53 51     if( p->op==SQ
12bd0 4c 49 54 45 5f 49 4e 53 45 52 54 20 29 7b 0a 20  LITE_INSERT ){. 
12be0 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74               int
12bf0 20 69 43 6f 6c 3b 0a 20 20 20 20 20 20 20 20 20   iCol;.         
12c00 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65       sessionAppe
12c10 6e 64 42 79 74 65 28 26 62 75 66 2c 20 53 51 4c  ndByte(&buf, SQL
12c20 49 54 45 5f 49 4e 53 45 52 54 2c 20 26 72 63 29  ITE_INSERT, &rc)
12c30 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;.              
12c40 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 79 74  sessionAppendByt
12c50 65 28 26 62 75 66 2c 20 70 2d 3e 62 49 6e 64 69  e(&buf, p->bIndi
12c60 72 65 63 74 2c 20 26 72 63 29 3b 0a 20 20 20 20  rect, &rc);.    
12c70 20 20 20 20 20 20 20 20 20 20 66 6f 72 28 69 43            for(iC
12c80 6f 6c 3d 30 3b 20 69 43 6f 6c 3c 6e 43 6f 6c 3b  ol=0; iCol<nCol;
12c90 20 69 43 6f 6c 2b 2b 29 7b 0a 20 20 20 20 20 20   iCol++){.      
12ca0 20 20 20 20 20 20 20 20 20 20 73 65 73 73 69 6f            sessio
12cb0 6e 41 70 70 65 6e 64 43 6f 6c 28 26 62 75 66 2c  nAppendCol(&buf,
12cc0 20 70 53 65 6c 2c 20 69 43 6f 6c 2c 20 26 72 63   pSel, iCol, &rc
12cd0 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  );.             
12ce0 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d   }.            }
12cf0 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20  else{.          
12d00 20 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e      rc = session
12d10 41 70 70 65 6e 64 55 70 64 61 74 65 28 26 62 75  AppendUpdate(&bu
12d20 66 2c 20 62 50 61 74 63 68 73 65 74 2c 20 70 53  f, bPatchset, pS
12d30 65 6c 2c 20 70 2c 20 61 62 50 4b 29 3b 0a 20 20  el, p, abPK);.  
12d40 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
12d50 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
12d60 70 2d 3e 6f 70 21 3d 53 51 4c 49 54 45 5f 49 4e  p->op!=SQLITE_IN
12d70 53 45 52 54 20 29 7b 0a 20 20 20 20 20 20 20 20  SERT ){.        
12d80 20 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e      rc = session
12d90 41 70 70 65 6e 64 44 65 6c 65 74 65 28 26 62 75  AppendDelete(&bu
12da0 66 2c 20 62 50 61 74 63 68 73 65 74 2c 20 70 2c  f, bPatchset, p,
12db0 20 6e 43 6f 6c 2c 20 61 62 50 4b 29 3b 0a 20 20   nCol, abPK);.  
12dc0 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
12dd0 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
12de0 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  TE_OK ){.       
12df0 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
12e00 33 5f 72 65 73 65 74 28 70 53 65 6c 29 3b 0a 20  3_reset(pSel);. 
12e10 20 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20           }..    
12e20 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20        /* If the 
12e30 62 75 66 66 65 72 20 69 73 20 6e 6f 77 20 6c 61  buffer is now la
12e40 72 67 65 72 20 74 68 61 6e 20 53 45 53 53 49 4f  rger than SESSIO
12e50 4e 53 5f 53 54 52 4d 5f 43 48 55 4e 4b 5f 53 49  NS_STRM_CHUNK_SI
12e60 5a 45 2c 20 70 61 73 73 0a 20 20 20 20 20 20 20  ZE, pass.       
12e70 20 20 20 2a 2a 20 69 74 73 20 63 6f 6e 74 65 6e     ** its conten
12e80 74 73 20 74 6f 20 74 68 65 20 78 4f 75 74 70 75  ts to the xOutpu
12e90 74 28 29 20 63 61 6c 6c 62 61 63 6b 2e 20 2a 2f  t() callback. */
12ea0 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 78  .          if( x
12eb0 4f 75 74 70 75 74 20 0a 20 20 20 20 20 20 20 20  Output .        
12ec0 20 20 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45     && rc==SQLITE
12ed0 5f 4f 4b 20 0a 20 20 20 20 20 20 20 20 20 20 20  _OK .           
12ee0 26 26 20 62 75 66 2e 6e 42 75 66 3e 6e 4e 6f 6f  && buf.nBuf>nNoo
12ef0 70 20 0a 20 20 20 20 20 20 20 20 20 20 20 26 26  p .           &&
12f00 20 62 75 66 2e 6e 42 75 66 3e 53 45 53 53 49 4f   buf.nBuf>SESSIO
12f10 4e 53 5f 53 54 52 4d 5f 43 48 55 4e 4b 5f 53 49  NS_STRM_CHUNK_SI
12f20 5a 45 20 0a 20 20 20 20 20 20 20 20 20 20 29 7b  ZE .          ){
12f30 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 63 20  .            rc 
12f40 3d 20 78 4f 75 74 70 75 74 28 70 4f 75 74 2c 20  = xOutput(pOut, 
12f50 28 76 6f 69 64 2a 29 62 75 66 2e 61 42 75 66 2c  (void*)buf.aBuf,
12f60 20 62 75 66 2e 6e 42 75 66 29 3b 0a 20 20 20 20   buf.nBuf);.    
12f70 20 20 20 20 20 20 20 20 6e 4e 6f 6f 70 20 3d 20          nNoop = 
12f80 2d 31 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  -1;.            
12f90 62 75 66 2e 6e 42 75 66 20 3d 20 30 3b 0a 20 20  buf.nBuf = 0;.  
12fa0 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20          }..     
12fb0 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20     }.      }..  
12fc0 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61      sqlite3_fina
12fd0 6c 69 7a 65 28 70 53 65 6c 29 3b 0a 20 20 20 20  lize(pSel);.    
12fe0 20 20 69 66 28 20 62 75 66 2e 6e 42 75 66 3d 3d    if( buf.nBuf==
12ff0 6e 4e 6f 6f 70 20 29 7b 0a 20 20 20 20 20 20 20  nNoop ){.       
13000 20 62 75 66 2e 6e 42 75 66 20 3d 20 6e 52 65 77   buf.nBuf = nRew
13010 69 6e 64 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ind;.      }.   
13020 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
13030 28 63 68 61 72 2a 29 61 7a 43 6f 6c 29 3b 20 20  (char*)azCol);  
13040 2f 2a 20 63 61 73 74 20 77 6f 72 6b 73 20 61 72  /* cast works ar
13050 6f 75 6e 64 20 56 43 2b 2b 20 62 75 67 20 2a 2f  ound VC++ bug */
13060 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
13070 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
13080 29 7b 0a 20 20 20 20 69 66 28 20 78 4f 75 74 70  ){.    if( xOutp
13090 75 74 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 2a  ut==0 ){.      *
130a0 70 6e 43 68 61 6e 67 65 73 65 74 20 3d 20 62 75  pnChangeset = bu
130b0 66 2e 6e 42 75 66 3b 0a 20 20 20 20 20 20 2a 70  f.nBuf;.      *p
130c0 70 43 68 61 6e 67 65 73 65 74 20 3d 20 62 75 66  pChangeset = buf
130d0 2e 61 42 75 66 3b 0a 20 20 20 20 20 20 62 75 66  .aBuf;.      buf
130e0 2e 61 42 75 66 20 3d 20 30 3b 0a 20 20 20 20 7d  .aBuf = 0;.    }
130f0 65 6c 73 65 20 69 66 28 20 62 75 66 2e 6e 42 75  else if( buf.nBu
13100 66 3e 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20  f>0 ){.      rc 
13110 3d 20 78 4f 75 74 70 75 74 28 70 4f 75 74 2c 20  = xOutput(pOut, 
13120 28 76 6f 69 64 2a 29 62 75 66 2e 61 42 75 66 2c  (void*)buf.aBuf,
13130 20 62 75 66 2e 6e 42 75 66 29 3b 0a 20 20 20 20   buf.nBuf);.    
13140 7d 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33  }.  }..  sqlite3
13150 5f 66 72 65 65 28 62 75 66 2e 61 42 75 66 29 3b  _free(buf.aBuf);
13160 0a 20 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28  .  sqlite3_exec(
13170 64 62 2c 20 22 52 45 4c 45 41 53 45 20 63 68 61  db, "RELEASE cha
13180 6e 67 65 73 65 74 22 2c 20 30 2c 20 30 2c 20 30  ngeset", 0, 0, 0
13190 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74  );.  sqlite3_mut
131a0 65 78 5f 6c 65 61 76 65 28 73 71 6c 69 74 65 33  ex_leave(sqlite3
131b0 5f 64 62 5f 6d 75 74 65 78 28 64 62 29 29 3b 0a  _db_mutex(db));.
131c0 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
131d0 2f 2a 0a 2a 2a 20 4f 62 74 61 69 6e 20 61 20 63  /*.** Obtain a c
131e0 68 61 6e 67 65 73 65 74 20 6f 62 6a 65 63 74 20  hangeset object 
131f0 63 6f 6e 74 61 69 6e 69 6e 67 20 61 6c 6c 20 63  containing all c
13200 68 61 6e 67 65 73 20 72 65 63 6f 72 64 65 64 20  hanges recorded 
13210 62 79 20 74 68 65 20 0a 2a 2a 20 73 65 73 73 69  by the .** sessi
13220 6f 6e 20 6f 62 6a 65 63 74 20 70 61 73 73 65 64  on object passed
13230 20 61 73 20 74 68 65 20 66 69 72 73 74 20 61 72   as the first ar
13240 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 49 74  gument..**.** It
13250 20 69 73 20 74 68 65 20 72 65 73 70 6f 6e 73 69   is the responsi
13260 62 69 6c 69 74 79 20 6f 66 20 74 68 65 20 63 61  bility of the ca
13270 6c 6c 65 72 20 74 6f 20 65 76 65 6e 74 75 61 6c  ller to eventual
13280 6c 79 20 66 72 65 65 20 74 68 65 20 62 75 66 66  ly free the buff
13290 65 72 20 0a 2a 2a 20 75 73 69 6e 67 20 73 71 6c  er .** using sql
132a0 69 74 65 33 5f 66 72 65 65 28 29 2e 0a 2a 2f 0a  ite3_free()..*/.
132b0 69 6e 74 20 73 71 6c 69 74 65 33 73 65 73 73 69  int sqlite3sessi
132c0 6f 6e 5f 63 68 61 6e 67 65 73 65 74 28 0a 20 20  on_changeset(.  
132d0 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20  sqlite3_session 
132e0 2a 70 53 65 73 73 69 6f 6e 2c 20 20 20 20 20 20  *pSession,      
132f0 2f 2a 20 53 65 73 73 69 6f 6e 20 6f 62 6a 65 63  /* Session objec
13300 74 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 43 68  t */.  int *pnCh
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 2f 2a 20 4f 55 54 3a 20 53         /* OUT: S
13330 69 7a 65 20 6f 66 20 62 75 66 66 65 72 20 61 74  ize of buffer at
13340 20 2a 70 70 43 68 61 6e 67 65 73 65 74 20 2a 2f   *ppChangeset */
13350 0a 20 20 76 6f 69 64 20 2a 2a 70 70 43 68 61 6e  .  void **ppChan
13360 67 65 73 65 74 20 20 20 20 20 20 20 20 20 20 20  geset           
13370 20 20 20 2f 2a 20 4f 55 54 3a 20 42 75 66 66 65     /* OUT: Buffe
13380 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 63 68 61  r containing cha
13390 6e 67 65 73 65 74 20 2a 2f 0a 29 7b 0a 20 20 72  ngeset */.){.  r
133a0 65 74 75 72 6e 20 73 65 73 73 69 6f 6e 47 65 6e  eturn sessionGen
133b0 65 72 61 74 65 43 68 61 6e 67 65 73 65 74 28 70  erateChangeset(p
133c0 53 65 73 73 69 6f 6e 2c 20 30 2c 20 30 2c 20 30  Session, 0, 0, 0
133d0 2c 20 70 6e 43 68 61 6e 67 65 73 65 74 2c 20 70  , pnChangeset, p
133e0 70 43 68 61 6e 67 65 73 65 74 29 3b 0a 7d 0a 0a  pChangeset);.}..
133f0 2f 2a 0a 2a 2a 20 53 74 72 65 61 6d 69 6e 67 20  /*.** Streaming 
13400 76 65 72 73 69 6f 6e 20 6f 66 20 73 71 6c 69 74  version of sqlit
13410 65 33 73 65 73 73 69 6f 6e 5f 63 68 61 6e 67 65  e3session_change
13420 73 65 74 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71  set()..*/.int sq
13430 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 63 68 61  lite3session_cha
13440 6e 67 65 73 65 74 5f 73 74 72 6d 28 0a 20 20 73  ngeset_strm(.  s
13450 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a  qlite3_session *
13460 70 53 65 73 73 69 6f 6e 2c 0a 20 20 69 6e 74 20  pSession,.  int 
13470 28 2a 78 4f 75 74 70 75 74 29 28 76 6f 69 64 20  (*xOutput)(void 
13480 2a 70 4f 75 74 2c 20 63 6f 6e 73 74 20 76 6f 69  *pOut, const voi
13490 64 20 2a 70 44 61 74 61 2c 20 69 6e 74 20 6e 44  d *pData, int nD
134a0 61 74 61 29 2c 0a 20 20 76 6f 69 64 20 2a 70 4f  ata),.  void *pO
134b0 75 74 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20 73  ut.){.  return s
134c0 65 73 73 69 6f 6e 47 65 6e 65 72 61 74 65 43 68  essionGenerateCh
134d0 61 6e 67 65 73 65 74 28 70 53 65 73 73 69 6f 6e  angeset(pSession
134e0 2c 20 30 2c 20 78 4f 75 74 70 75 74 2c 20 70 4f  , 0, xOutput, pO
134f0 75 74 2c 20 30 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a  ut, 0, 0);.}../*
13500 0a 2a 2a 20 53 74 72 65 61 6d 69 6e 67 20 76 65  .** Streaming ve
13510 72 73 69 6f 6e 20 6f 66 20 73 71 6c 69 74 65 33  rsion of sqlite3
13520 73 65 73 73 69 6f 6e 5f 70 61 74 63 68 73 65 74  session_patchset
13530 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ()..*/.int sqlit
13540 65 33 73 65 73 73 69 6f 6e 5f 70 61 74 63 68 73  e3session_patchs
13550 65 74 5f 73 74 72 6d 28 0a 20 20 73 71 6c 69 74  et_strm(.  sqlit
13560 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73  e3_session *pSes
13570 73 69 6f 6e 2c 0a 20 20 69 6e 74 20 28 2a 78 4f  sion,.  int (*xO
13580 75 74 70 75 74 29 28 76 6f 69 64 20 2a 70 4f 75  utput)(void *pOu
13590 74 2c 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70  t, const void *p
135a0 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74 61 29  Data, int nData)
135b0 2c 0a 20 20 76 6f 69 64 20 2a 70 4f 75 74 0a 29  ,.  void *pOut.)
135c0 7b 0a 20 20 72 65 74 75 72 6e 20 73 65 73 73 69  {.  return sessi
135d0 6f 6e 47 65 6e 65 72 61 74 65 43 68 61 6e 67 65  onGenerateChange
135e0 73 65 74 28 70 53 65 73 73 69 6f 6e 2c 20 31 2c  set(pSession, 1,
135f0 20 78 4f 75 74 70 75 74 2c 20 70 4f 75 74 2c 20   xOutput, pOut, 
13600 30 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  0, 0);.}../*.** 
13610 4f 62 74 61 69 6e 20 61 20 70 61 74 63 68 73 65  Obtain a patchse
13620 74 20 6f 62 6a 65 63 74 20 63 6f 6e 74 61 69 6e  t object contain
13630 69 6e 67 20 61 6c 6c 20 63 68 61 6e 67 65 73 20  ing all changes 
13640 72 65 63 6f 72 64 65 64 20 62 79 20 74 68 65 20  recorded by the 
13650 0a 2a 2a 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65  .** session obje
13660 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68 65  ct passed as the
13670 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 2e   first argument.
13680 0a 2a 2a 0a 2a 2a 20 49 74 20 69 73 20 74 68 65  .**.** It is the
13690 20 72 65 73 70 6f 6e 73 69 62 69 6c 69 74 79 20   responsibility 
136a0 6f 66 20 74 68 65 20 63 61 6c 6c 65 72 20 74 6f  of the caller to
136b0 20 65 76 65 6e 74 75 61 6c 6c 79 20 66 72 65 65   eventually free
136c0 20 74 68 65 20 62 75 66 66 65 72 20 0a 2a 2a 20   the buffer .** 
136d0 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 66 72  using sqlite3_fr
136e0 65 65 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  ee()..*/.int sql
136f0 69 74 65 33 73 65 73 73 69 6f 6e 5f 70 61 74 63  ite3session_patc
13700 68 73 65 74 28 0a 20 20 73 71 6c 69 74 65 33 5f  hset(.  sqlite3_
13710 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f  session *pSessio
13720 6e 2c 20 20 20 20 20 20 2f 2a 20 53 65 73 73 69  n,      /* Sessi
13730 6f 6e 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69  on object */.  i
13740 6e 74 20 2a 70 6e 50 61 74 63 68 73 65 74 2c 20  nt *pnPatchset, 
13750 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
13760 2a 20 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20 62  * OUT: Size of b
13770 75 66 66 65 72 20 61 74 20 2a 70 70 43 68 61 6e  uffer at *ppChan
13780 67 65 73 65 74 20 2a 2f 0a 20 20 76 6f 69 64 20  geset */.  void 
13790 2a 2a 70 70 50 61 74 63 68 73 65 74 20 20 20 20  **ppPatchset    
137a0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
137b0 54 3a 20 42 75 66 66 65 72 20 63 6f 6e 74 61 69  T: Buffer contai
137c0 6e 69 6e 67 20 63 68 61 6e 67 65 73 65 74 20 2a  ning changeset *
137d0 2f 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 65  /.){.  return se
137e0 73 73 69 6f 6e 47 65 6e 65 72 61 74 65 43 68 61  ssionGenerateCha
137f0 6e 67 65 73 65 74 28 70 53 65 73 73 69 6f 6e 2c  ngeset(pSession,
13800 20 31 2c 20 30 2c 20 30 2c 20 70 6e 50 61 74 63   1, 0, 0, pnPatc
13810 68 73 65 74 2c 20 70 70 50 61 74 63 68 73 65 74  hset, ppPatchset
13820 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 61 62  );.}../*.** Enab
13830 6c 65 20 6f 72 20 64 69 73 61 62 6c 65 20 74 68  le or disable th
13840 65 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74  e session object
13850 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66   passed as the f
13860 69 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a  irst argument..*
13870 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 73 65 73  /.int sqlite3ses
13880 73 69 6f 6e 5f 65 6e 61 62 6c 65 28 73 71 6c 69  sion_enable(sqli
13890 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65  te3_session *pSe
138a0 73 73 69 6f 6e 2c 20 69 6e 74 20 62 45 6e 61 62  ssion, int bEnab
138b0 6c 65 29 7b 0a 20 20 69 6e 74 20 72 65 74 3b 0a  le){.  int ret;.
138c0 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
138d0 65 6e 74 65 72 28 73 71 6c 69 74 65 33 5f 64 62  enter(sqlite3_db
138e0 5f 6d 75 74 65 78 28 70 53 65 73 73 69 6f 6e 2d  _mutex(pSession-
138f0 3e 64 62 29 29 3b 0a 20 20 69 66 28 20 62 45 6e  >db));.  if( bEn
13900 61 62 6c 65 3e 3d 30 20 29 7b 0a 20 20 20 20 70  able>=0 ){.    p
13910 53 65 73 73 69 6f 6e 2d 3e 62 45 6e 61 62 6c 65  Session->bEnable
13920 20 3d 20 62 45 6e 61 62 6c 65 3b 0a 20 20 7d 0a   = bEnable;.  }.
13930 20 20 72 65 74 20 3d 20 70 53 65 73 73 69 6f 6e    ret = pSession
13940 2d 3e 62 45 6e 61 62 6c 65 3b 0a 20 20 73 71 6c  ->bEnable;.  sql
13950 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65  ite3_mutex_leave
13960 28 73 71 6c 69 74 65 33 5f 64 62 5f 6d 75 74 65  (sqlite3_db_mute
13970 78 28 70 53 65 73 73 69 6f 6e 2d 3e 64 62 29 29  x(pSession->db))
13980 3b 0a 20 20 72 65 74 75 72 6e 20 72 65 74 3b 0a  ;.  return ret;.
13990 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 61 62 6c 65 20  }../*.** Enable 
139a0 6f 72 20 64 69 73 61 62 6c 65 20 74 68 65 20 73  or disable the s
139b0 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74 20 70 61  ession object pa
139c0 73 73 65 64 20 61 73 20 74 68 65 20 66 69 72 73  ssed as the firs
139d0 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 69  t argument..*/.i
139e0 6e 74 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f  nt sqlite3sessio
139f0 6e 5f 69 6e 64 69 72 65 63 74 28 73 71 6c 69 74  n_indirect(sqlit
13a00 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73  e3_session *pSes
13a10 73 69 6f 6e 2c 20 69 6e 74 20 62 49 6e 64 69 72  sion, int bIndir
13a20 65 63 74 29 7b 0a 20 20 69 6e 74 20 72 65 74 3b  ect){.  int ret;
13a30 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  .  sqlite3_mutex
13a40 5f 65 6e 74 65 72 28 73 71 6c 69 74 65 33 5f 64  _enter(sqlite3_d
13a50 62 5f 6d 75 74 65 78 28 70 53 65 73 73 69 6f 6e  b_mutex(pSession
13a60 2d 3e 64 62 29 29 3b 0a 20 20 69 66 28 20 62 49  ->db));.  if( bI
13a70 6e 64 69 72 65 63 74 3e 3d 30 20 29 7b 0a 20 20  ndirect>=0 ){.  
13a80 20 20 70 53 65 73 73 69 6f 6e 2d 3e 62 49 6e 64    pSession->bInd
13a90 69 72 65 63 74 20 3d 20 62 49 6e 64 69 72 65 63  irect = bIndirec
13aa0 74 3b 0a 20 20 7d 0a 20 20 72 65 74 20 3d 20 70  t;.  }.  ret = p
13ab0 53 65 73 73 69 6f 6e 2d 3e 62 49 6e 64 69 72 65  Session->bIndire
13ac0 63 74 3b 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75  ct;.  sqlite3_mu
13ad0 74 65 78 5f 6c 65 61 76 65 28 73 71 6c 69 74 65  tex_leave(sqlite
13ae0 33 5f 64 62 5f 6d 75 74 65 78 28 70 53 65 73 73  3_db_mutex(pSess
13af0 69 6f 6e 2d 3e 64 62 29 29 3b 0a 20 20 72 65 74  ion->db));.  ret
13b00 75 72 6e 20 72 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a  urn ret;.}../*.*
13b10 2a 20 52 65 74 75 72 6e 20 74 72 75 65 20 69 66  * Return true if
13b20 20 74 68 65 72 65 20 68 61 76 65 20 62 65 65 6e   there have been
13b30 20 6e 6f 20 63 68 61 6e 67 65 73 20 74 6f 20 6d   no changes to m
13b40 6f 6e 69 74 6f 72 65 64 20 74 61 62 6c 65 73 20  onitored tables 
13b50 72 65 63 6f 72 64 65 64 0a 2a 2a 20 62 79 20 74  recorded.** by t
13b60 68 65 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63  he session objec
13b70 74 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20  t passed as the 
13b80 6f 6e 6c 79 20 61 72 67 75 6d 65 6e 74 2e 0a 2a  only argument..*
13b90 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 73 65 73  /.int sqlite3ses
13ba0 73 69 6f 6e 5f 69 73 65 6d 70 74 79 28 73 71 6c  sion_isempty(sql
13bb0 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53  ite3_session *pS
13bc0 65 73 73 69 6f 6e 29 7b 0a 20 20 69 6e 74 20 72  ession){.  int r
13bd0 65 74 20 3d 20 30 3b 0a 20 20 53 65 73 73 69 6f  et = 0;.  Sessio
13be0 6e 54 61 62 6c 65 20 2a 70 54 61 62 3b 0a 0a 20  nTable *pTab;.. 
13bf0 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65   sqlite3_mutex_e
13c00 6e 74 65 72 28 73 71 6c 69 74 65 33 5f 64 62 5f  nter(sqlite3_db_
13c10 6d 75 74 65 78 28 70 53 65 73 73 69 6f 6e 2d 3e  mutex(pSession->
13c20 64 62 29 29 3b 0a 20 20 66 6f 72 28 70 54 61 62  db));.  for(pTab
13c30 3d 70 53 65 73 73 69 6f 6e 2d 3e 70 54 61 62 6c  =pSession->pTabl
13c40 65 3b 20 70 54 61 62 20 26 26 20 72 65 74 3d 3d  e; pTab && ret==
13c50 30 3b 20 70 54 61 62 3d 70 54 61 62 2d 3e 70 4e  0; pTab=pTab->pN
13c60 65 78 74 29 7b 0a 20 20 20 20 72 65 74 20 3d 20  ext){.    ret = 
13c70 28 70 54 61 62 2d 3e 6e 45 6e 74 72 79 3e 30 29  (pTab->nEntry>0)
13c80 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  ;.  }.  sqlite3_
13c90 6d 75 74 65 78 5f 6c 65 61 76 65 28 73 71 6c 69  mutex_leave(sqli
13ca0 74 65 33 5f 64 62 5f 6d 75 74 65 78 28 70 53 65  te3_db_mutex(pSe
13cb0 73 73 69 6f 6e 2d 3e 64 62 29 29 3b 0a 0a 20 20  ssion->db));..  
13cc0 72 65 74 75 72 6e 20 28 72 65 74 3d 3d 30 29 3b  return (ret==0);
13cd0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 74 68 65  .}../*.** Do the
13ce0 20 77 6f 72 6b 20 66 6f 72 20 65 69 74 68 65 72   work for either
13cf0 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
13d00 74 5f 73 74 61 72 74 28 29 20 6f 72 20 73 74 61  t_start() or sta
13d10 72 74 5f 73 74 72 6d 28 29 2e 0a 2a 2f 0a 73 74  rt_strm()..*/.st
13d20 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e  atic int session
13d30 43 68 61 6e 67 65 73 65 74 53 74 61 72 74 28 0a  ChangesetStart(.
13d40 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65    sqlite3_change
13d50 73 65 74 5f 69 74 65 72 20 2a 2a 70 70 2c 20 20  set_iter **pp,  
13d60 20 20 2f 2a 20 4f 55 54 3a 20 43 68 61 6e 67 65    /* OUT: Change
13d70 73 65 74 20 69 74 65 72 61 74 6f 72 20 68 61 6e  set iterator han
13d80 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78  dle */.  int (*x
13d90 49 6e 70 75 74 29 28 76 6f 69 64 20 2a 70 49 6e  Input)(void *pIn
13da0 2c 20 76 6f 69 64 20 2a 70 44 61 74 61 2c 20 69  , void *pData, i
13db0 6e 74 20 2a 70 6e 44 61 74 61 29 2c 0a 20 20 76  nt *pnData),.  v
13dc0 6f 69 64 20 2a 70 49 6e 2c 0a 20 20 69 6e 74 20  oid *pIn,.  int 
13dd0 6e 43 68 61 6e 67 65 73 65 74 2c 20 20 20 20 20  nChangeset,     
13de0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
13df0 69 7a 65 20 6f 66 20 62 75 66 66 65 72 20 70 43  ize of buffer pC
13e00 68 61 6e 67 65 73 65 74 20 69 6e 20 62 79 74 65  hangeset in byte
13e10 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 43 68  s */.  void *pCh
13e20 61 6e 67 65 73 65 74 20 20 20 20 20 20 20 20 20  angeset         
13e30 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
13e40 72 20 74 6f 20 62 75 66 66 65 72 20 63 6f 6e 74  r to buffer cont
13e50 61 69 6e 69 6e 67 20 63 68 61 6e 67 65 73 65 74  aining changeset
13e60 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33   */.){.  sqlite3
13e70 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20  _changeset_iter 
13e80 2a 70 52 65 74 3b 20 20 20 2f 2a 20 49 74 65 72  *pRet;   /* Iter
13e90 61 74 6f 72 20 74 6f 20 72 65 74 75 72 6e 20 2a  ator to return *
13ea0 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b 20 20  /.  int nByte;  
13eb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13ec0 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
13ed0 20 62 79 74 65 73 20 74 6f 20 61 6c 6c 6f 63 61   bytes to alloca
13ee0 74 65 20 66 6f 72 20 69 74 65 72 61 74 6f 72 20  te for iterator 
13ef0 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 78 49  */..  assert( xI
13f00 6e 70 75 74 3d 3d 30 20 7c 7c 20 28 70 43 68 61  nput==0 || (pCha
13f10 6e 67 65 73 65 74 3d 3d 30 20 26 26 20 6e 43 68  ngeset==0 && nCh
13f20 61 6e 67 65 73 65 74 3d 3d 30 29 20 29 3b 0a 0a  angeset==0) );..
13f30 20 20 2f 2a 20 5a 65 72 6f 20 74 68 65 20 6f 75    /* Zero the ou
13f40 74 70 75 74 20 76 61 72 69 61 62 6c 65 20 69 6e  tput variable in
13f50 20 63 61 73 65 20 61 6e 20 65 72 72 6f 72 20 6f   case an error o
13f60 63 63 75 72 73 2e 20 2a 2f 0a 20 20 2a 70 70 20  ccurs. */.  *pp 
13f70 3d 20 30 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63  = 0;..  /* Alloc
13f80 61 74 65 20 61 6e 64 20 69 6e 69 74 69 61 6c 69  ate and initiali
13f90 7a 65 20 74 68 65 20 69 74 65 72 61 74 6f 72 20  ze the iterator 
13fa0 73 74 72 75 63 74 75 72 65 2e 20 2a 2f 0a 20 20  structure. */.  
13fb0 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 73  nByte = sizeof(s
13fc0 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74  qlite3_changeset
13fd0 5f 69 74 65 72 29 3b 0a 20 20 70 52 65 74 20 3d  _iter);.  pRet =
13fe0 20 28 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65   (sqlite3_change
13ff0 73 65 74 5f 69 74 65 72 20 2a 29 73 71 6c 69 74  set_iter *)sqlit
14000 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74 65 29  e3_malloc(nByte)
14010 3b 0a 20 20 69 66 28 20 21 70 52 65 74 20 29 20  ;.  if( !pRet ) 
14020 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
14030 4d 45 4d 3b 0a 20 20 6d 65 6d 73 65 74 28 70 52  MEM;.  memset(pR
14040 65 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73 71  et, 0, sizeof(sq
14050 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f  lite3_changeset_
14060 69 74 65 72 29 29 3b 0a 20 20 70 52 65 74 2d 3e  iter));.  pRet->
14070 69 6e 2e 61 44 61 74 61 20 3d 20 28 75 38 20 2a  in.aData = (u8 *
14080 29 70 43 68 61 6e 67 65 73 65 74 3b 0a 20 20 70  )pChangeset;.  p
14090 52 65 74 2d 3e 69 6e 2e 6e 44 61 74 61 20 3d 20  Ret->in.nData = 
140a0 6e 43 68 61 6e 67 65 73 65 74 3b 0a 20 20 70 52  nChangeset;.  pR
140b0 65 74 2d 3e 69 6e 2e 78 49 6e 70 75 74 20 3d 20  et->in.xInput = 
140c0 78 49 6e 70 75 74 3b 0a 20 20 70 52 65 74 2d 3e  xInput;.  pRet->
140d0 69 6e 2e 70 49 6e 20 3d 20 70 49 6e 3b 0a 20 20  in.pIn = pIn;.  
140e0 70 52 65 74 2d 3e 69 6e 2e 62 45 6f 66 20 3d 20  pRet->in.bEof = 
140f0 28 78 49 6e 70 75 74 20 3f 20 30 20 3a 20 31 29  (xInput ? 0 : 1)
14100 3b 0a 0a 20 20 2f 2a 20 50 6f 70 75 6c 61 74 65  ;..  /* Populate
14110 20 74 68 65 20 6f 75 74 70 75 74 20 76 61 72 69   the output vari
14120 61 62 6c 65 20 61 6e 64 20 72 65 74 75 72 6e 20  able and return 
14130 73 75 63 63 65 73 73 2e 20 2a 2f 0a 20 20 2a 70  success. */.  *p
14140 70 20 3d 20 70 52 65 74 3b 0a 20 20 72 65 74 75  p = pRet;.  retu
14150 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
14160 0a 2f 2a 0a 2a 2a 20 43 72 65 61 74 65 20 61 6e  ./*.** Create an
14170 20 69 74 65 72 61 74 6f 72 20 75 73 65 64 20 74   iterator used t
14180 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67  o iterate throug
14190 68 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  h the contents o
141a0 66 20 61 20 63 68 61 6e 67 65 73 65 74 2e 0a 2a  f a changeset..*
141b0 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 63 68 61  /.int sqlite3cha
141c0 6e 67 65 73 65 74 5f 73 74 61 72 74 28 0a 20 20  ngeset_start(.  
141d0 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65  sqlite3_changese
141e0 74 5f 69 74 65 72 20 2a 2a 70 70 2c 20 20 20 20  t_iter **pp,    
141f0 2f 2a 20 4f 55 54 3a 20 43 68 61 6e 67 65 73 65  /* OUT: Changese
14200 74 20 69 74 65 72 61 74 6f 72 20 68 61 6e 64 6c  t iterator handl
14210 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 68 61 6e  e */.  int nChan
14220 67 65 73 65 74 2c 20 20 20 20 20 20 20 20 20 20  geset,          
14230 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
14240 66 20 62 75 66 66 65 72 20 70 43 68 61 6e 67 65  f buffer pChange
14250 73 65 74 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  set in bytes */.
14260 20 20 76 6f 69 64 20 2a 70 43 68 61 6e 67 65 73    void *pChanges
14270 65 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20  et              
14280 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
14290 62 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e  buffer containin
142a0 67 20 63 68 61 6e 67 65 73 65 74 20 2a 2f 0a 29  g changeset */.)
142b0 7b 0a 20 20 72 65 74 75 72 6e 20 73 65 73 73 69  {.  return sessi
142c0 6f 6e 43 68 61 6e 67 65 73 65 74 53 74 61 72 74  onChangesetStart
142d0 28 70 70 2c 20 30 2c 20 30 2c 20 6e 43 68 61 6e  (pp, 0, 0, nChan
142e0 67 65 73 65 74 2c 20 70 43 68 61 6e 67 65 73 65  geset, pChangese
142f0 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 74 72  t);.}../*.** Str
14300 65 61 6d 69 6e 67 20 76 65 72 73 69 6f 6e 20 6f  eaming version o
14310 66 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  f sqlite3changes
14320 65 74 5f 73 74 61 72 74 28 29 2e 0a 2a 2f 0a 69  et_start()..*/.i
14330 6e 74 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65  nt sqlite3change
14340 73 65 74 5f 73 74 61 72 74 5f 73 74 72 6d 28 0a  set_start_strm(.
14350 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65    sqlite3_change
14360 73 65 74 5f 69 74 65 72 20 2a 2a 70 70 2c 20 20  set_iter **pp,  
14370 20 20 2f 2a 20 4f 55 54 3a 20 43 68 61 6e 67 65    /* OUT: Change
14380 73 65 74 20 69 74 65 72 61 74 6f 72 20 68 61 6e  set iterator han
14390 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78  dle */.  int (*x
143a0 49 6e 70 75 74 29 28 76 6f 69 64 20 2a 70 49 6e  Input)(void *pIn
143b0 2c 20 76 6f 69 64 20 2a 70 44 61 74 61 2c 20 69  , void *pData, i
143c0 6e 74 20 2a 70 6e 44 61 74 61 29 2c 0a 20 20 76  nt *pnData),.  v
143d0 6f 69 64 20 2a 70 49 6e 0a 29 7b 0a 20 20 72 65  oid *pIn.){.  re
143e0 74 75 72 6e 20 73 65 73 73 69 6f 6e 43 68 61 6e  turn sessionChan
143f0 67 65 73 65 74 53 74 61 72 74 28 70 70 2c 20 78  gesetStart(pp, x
14400 49 6e 70 75 74 2c 20 70 49 6e 2c 20 30 2c 20 30  Input, pIn, 0, 0
14410 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74  );.}../*.** If t
14420 68 65 20 53 65 73 73 69 6f 6e 49 6e 70 75 74 20  he SessionInput 
14430 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20 61 73  object passed as
14440 20 74 68 65 20 6f 6e 6c 79 20 61 72 67 75 6d 65   the only argume
14450 6e 74 20 69 73 20 61 20 73 74 72 65 61 6d 69 6e  nt is a streamin
14460 67 0a 2a 2a 20 6f 62 6a 65 63 74 20 61 6e 64 20  g.** object and 
14470 74 68 65 20 62 75 66 66 65 72 20 69 73 20 66 75  the buffer is fu
14480 6c 6c 2c 20 64 69 73 63 61 72 64 20 73 6f 6d 65  ll, discard some
14490 20 64 61 74 61 20 74 6f 20 66 72 65 65 20 75 70   data to free up
144a0 20 73 70 61 63 65 2e 0a 2a 2f 0a 73 74 61 74 69   space..*/.stati
144b0 63 20 76 6f 69 64 20 73 65 73 73 69 6f 6e 44 69  c void sessionDi
144c0 73 63 61 72 64 44 61 74 61 28 53 65 73 73 69 6f  scardData(Sessio
144d0 6e 49 6e 70 75 74 20 2a 70 49 6e 29 7b 0a 20 20  nInput *pIn){.  
144e0 69 66 28 20 70 49 6e 2d 3e 62 45 6f 66 20 26 26  if( pIn->bEof &&
144f0 20 70 49 6e 2d 3e 78 49 6e 70 75 74 20 26 26 20   pIn->xInput && 
14500 70 49 6e 2d 3e 69 4e 65 78 74 3e 3d 53 45 53 53  pIn->iNext>=SESS
14510 49 4f 4e 53 5f 53 54 52 4d 5f 43 48 55 4e 4b 5f  IONS_STRM_CHUNK_
14520 53 49 5a 45 20 29 7b 0a 20 20 20 20 69 6e 74 20  SIZE ){.    int 
14530 6e 4d 6f 76 65 20 3d 20 70 49 6e 2d 3e 62 75 66  nMove = pIn->buf
14540 2e 6e 42 75 66 20 2d 20 70 49 6e 2d 3e 69 4e 65  .nBuf - pIn->iNe
14550 78 74 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  xt;.    assert( 
14560 6e 4d 6f 76 65 3e 3d 30 20 29 3b 0a 20 20 20 20  nMove>=0 );.    
14570 69 66 28 20 6e 4d 6f 76 65 3e 30 20 29 7b 0a 20  if( nMove>0 ){. 
14580 20 20 20 20 20 6d 65 6d 6d 6f 76 65 28 70 49 6e       memmove(pIn
14590 2d 3e 62 75 66 2e 61 42 75 66 2c 20 26 70 49 6e  ->buf.aBuf, &pIn
145a0 2d 3e 62 75 66 2e 61 42 75 66 5b 70 49 6e 2d 3e  ->buf.aBuf[pIn->
145b0 69 4e 65 78 74 5d 2c 20 6e 4d 6f 76 65 29 3b 0a  iNext], nMove);.
145c0 20 20 20 20 7d 0a 20 20 20 20 70 49 6e 2d 3e 62      }.    pIn->b
145d0 75 66 2e 6e 42 75 66 20 2d 3d 20 70 49 6e 2d 3e  uf.nBuf -= pIn->
145e0 69 4e 65 78 74 3b 0a 20 20 20 20 70 49 6e 2d 3e  iNext;.    pIn->
145f0 69 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 70  iNext = 0;.    p
14600 49 6e 2d 3e 6e 44 61 74 61 20 3d 20 70 49 6e 2d  In->nData = pIn-
14610 3e 62 75 66 2e 6e 42 75 66 3b 0a 20 20 7d 0a 7d  >buf.nBuf;.  }.}
14620 0a 0a 2f 2a 0a 2a 2a 20 45 6e 73 75 72 65 20 74  ../*.** Ensure t
14630 68 61 74 20 74 68 65 72 65 20 61 72 65 20 61 74  hat there are at
14640 20 6c 65 61 73 74 20 6e 42 79 74 65 20 62 79 74   least nByte byt
14650 65 73 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20  es available in 
14660 74 68 65 20 62 75 66 66 65 72 2e 20 4f 72 2c 0a  the buffer. Or,.
14670 2a 2a 20 69 66 20 74 68 65 72 65 20 61 72 65 20  ** if there are 
14680 6e 6f 74 20 6e 42 79 74 65 20 62 79 74 65 73 20  not nByte bytes 
14690 72 65 6d 61 69 6e 69 6e 67 20 69 6e 20 74 68 65  remaining in the
146a0 20 69 6e 70 75 74 2c 20 74 68 61 74 20 61 6c 6c   input, that all
146b0 20 61 76 61 69 6c 61 62 6c 65 0a 2a 2a 20 64 61   available.** da
146c0 74 61 20 69 73 20 69 6e 20 74 68 65 20 62 75 66  ta is in the buf
146d0 66 65 72 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72  fer..**.** Retur
146e0 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  n an SQLite erro
146f0 72 20 63 6f 64 65 20 69 66 20 61 6e 20 65 72 72  r code if an err
14700 6f 72 20 6f 63 63 75 72 73 2c 20 6f 72 20 53 51  or occurs, or SQ
14710 4c 49 54 45 5f 4f 4b 20 6f 74 68 65 72 77 69 73  LITE_OK otherwis
14720 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
14730 20 73 65 73 73 69 6f 6e 49 6e 70 75 74 42 75 66   sessionInputBuf
14740 66 65 72 28 53 65 73 73 69 6f 6e 49 6e 70 75 74  fer(SessionInput
14750 20 2a 70 49 6e 2c 20 69 6e 74 20 6e 42 79 74 65   *pIn, int nByte
14760 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
14770 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70  LITE_OK;.  if( p
14780 49 6e 2d 3e 78 49 6e 70 75 74 20 29 7b 0a 20 20  In->xInput ){.  
14790 20 20 77 68 69 6c 65 28 20 21 70 49 6e 2d 3e 62    while( !pIn->b
147a0 45 6f 66 20 26 26 20 28 70 49 6e 2d 3e 69 4e 65  Eof && (pIn->iNe
147b0 78 74 2b 6e 42 79 74 65 29 3e 3d 70 49 6e 2d 3e  xt+nByte)>=pIn->
147c0 6e 44 61 74 61 20 26 26 20 72 63 3d 3d 53 51 4c  nData && rc==SQL
147d0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
147e0 69 6e 74 20 6e 4e 65 77 20 3d 20 53 45 53 53 49  int nNew = SESSI
147f0 4f 4e 53 5f 53 54 52 4d 5f 43 48 55 4e 4b 5f 53  ONS_STRM_CHUNK_S
14800 49 5a 45 3b 0a 0a 20 20 20 20 20 20 69 66 28 20  IZE;..      if( 
14810 70 49 6e 2d 3e 62 4e 6f 44 69 73 63 61 72 64 3d  pIn->bNoDiscard=
14820 3d 30 20 29 20 73 65 73 73 69 6f 6e 44 69 73 63  =0 ) sessionDisc
14830 61 72 64 44 61 74 61 28 70 49 6e 29 3b 0a 20 20  ardData(pIn);.  
14840 20 20 20 20 69 66 28 20 53 51 4c 49 54 45 5f 4f      if( SQLITE_O
14850 4b 3d 3d 73 65 73 73 69 6f 6e 42 75 66 66 65 72  K==sessionBuffer
14860 47 72 6f 77 28 26 70 49 6e 2d 3e 62 75 66 2c 20  Grow(&pIn->buf, 
14870 6e 4e 65 77 2c 20 26 72 63 29 20 29 7b 0a 20 20  nNew, &rc) ){.  
14880 20 20 20 20 20 20 72 63 20 3d 20 70 49 6e 2d 3e        rc = pIn->
14890 78 49 6e 70 75 74 28 70 49 6e 2d 3e 70 49 6e 2c  xInput(pIn->pIn,
148a0 20 26 70 49 6e 2d 3e 62 75 66 2e 61 42 75 66 5b   &pIn->buf.aBuf[
148b0 70 49 6e 2d 3e 62 75 66 2e 6e 42 75 66 5d 2c 20  pIn->buf.nBuf], 
148c0 26 6e 4e 65 77 29 3b 0a 20 20 20 20 20 20 20 20  &nNew);.        
148d0 69 66 28 20 6e 4e 65 77 3d 3d 30 20 29 7b 0a 20  if( nNew==0 ){. 
148e0 20 20 20 20 20 20 20 20 20 70 49 6e 2d 3e 62 45           pIn->bE
148f0 6f 66 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20  of = 1;.        
14900 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20  }else{.         
14910 20 70 49 6e 2d 3e 62 75 66 2e 6e 42 75 66 20 2b   pIn->buf.nBuf +
14920 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 20 20  = nNew;.        
14930 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  }.      }..     
14940 20 70 49 6e 2d 3e 61 44 61 74 61 20 3d 20 70 49   pIn->aData = pI
14950 6e 2d 3e 62 75 66 2e 61 42 75 66 3b 0a 20 20 20  n->buf.aBuf;.   
14960 20 20 20 70 49 6e 2d 3e 6e 44 61 74 61 20 3d 20     pIn->nData = 
14970 70 49 6e 2d 3e 62 75 66 2e 6e 42 75 66 3b 0a 20  pIn->buf.nBuf;. 
14980 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
14990 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57  n rc;.}../*.** W
149a0 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f  hen this functio
149b0 6e 20 69 73 20 63 61 6c 6c 65 64 2c 20 2a 70 70  n is called, *pp
149c0 52 65 63 20 70 6f 69 6e 74 73 20 74 6f 20 74 68  Rec points to th
149d0 65 20 73 74 61 72 74 20 6f 66 20 61 20 72 65 63  e start of a rec
149e0 6f 72 64 0a 2a 2a 20 74 68 61 74 20 63 6f 6e 74  ord.** that cont
149f0 61 69 6e 73 20 6e 43 6f 6c 20 76 61 6c 75 65 73  ains nCol values
14a00 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
14a10 61 64 76 61 6e 63 65 73 20 74 68 65 20 70 6f 69  advances the poi
14a20 6e 74 65 72 20 2a 70 70 52 65 63 0a 2a 2a 20 75  nter *ppRec.** u
14a30 6e 74 69 6c 20 69 74 20 70 6f 69 6e 74 73 20 74  ntil it points t
14a40 6f 20 74 68 65 20 62 79 74 65 20 69 6d 6d 65 64  o the byte immed
14a50 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 69 6e 67  iately following
14a60 20 74 68 61 74 20 72 65 63 6f 72 64 2e 0a 2a 2f   that record..*/
14a70 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 65 73  .static void ses
14a80 73 69 6f 6e 53 6b 69 70 52 65 63 6f 72 64 28 0a  sionSkipRecord(.
14a90 20 20 75 38 20 2a 2a 70 70 52 65 63 2c 20 20 20    u8 **ppRec,   
14aa0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14ab0 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 52 65 63    /* IN/OUT: Rec
14ac0 6f 72 64 20 70 6f 69 6e 74 65 72 20 2a 2f 0a 20  ord pointer */. 
14ad0 20 69 6e 74 20 6e 43 6f 6c 20 20 20 20 20 20 20   int nCol       
14ae0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14af0 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 76 61   /* Number of va
14b00 6c 75 65 73 20 69 6e 20 72 65 63 6f 72 64 20 2a  lues in record *
14b10 2f 0a 29 7b 0a 20 20 75 38 20 2a 61 52 65 63 20  /.){.  u8 *aRec 
14b20 3d 20 2a 70 70 52 65 63 3b 0a 20 20 69 6e 74 20  = *ppRec;.  int 
14b30 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  i;.  for(i=0; i<
14b40 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  nCol; i++){.    
14b50 69 6e 74 20 65 54 79 70 65 20 3d 20 2a 61 52 65  int eType = *aRe
14b60 63 2b 2b 3b 0a 20 20 20 20 69 66 28 20 65 54 79  c++;.    if( eTy
14b70 70 65 3d 3d 53 51 4c 49 54 45 5f 54 45 58 54 20  pe==SQLITE_TEXT 
14b80 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45  || eType==SQLITE
14b90 5f 42 4c 4f 42 20 29 7b 0a 20 20 20 20 20 20 69  _BLOB ){.      i
14ba0 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20 20 20 20  nt nByte;.      
14bb0 61 52 65 63 20 2b 3d 20 73 65 73 73 69 6f 6e 56  aRec += sessionV
14bc0 61 72 69 6e 74 47 65 74 28 28 75 38 2a 29 61 52  arintGet((u8*)aR
14bd0 65 63 2c 20 26 6e 42 79 74 65 29 3b 0a 20 20 20  ec, &nByte);.   
14be0 20 20 20 61 52 65 63 20 2b 3d 20 6e 42 79 74 65     aRec += nByte
14bf0 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20  ;.    }else if( 
14c00 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e  eType==SQLITE_IN
14c10 54 45 47 45 52 20 7c 7c 20 65 54 79 70 65 3d 3d  TEGER || eType==
14c20 53 51 4c 49 54 45 5f 46 4c 4f 41 54 20 29 7b 0a  SQLITE_FLOAT ){.
14c30 20 20 20 20 20 20 61 52 65 63 20 2b 3d 20 38 3b        aRec += 8;
14c40 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70  .    }.  }..  *p
14c50 70 52 65 63 20 3d 20 61 52 65 63 3b 0a 7d 0a 0a  pRec = aRec;.}..
14c60 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
14c70 69 6f 6e 20 73 65 74 73 20 74 68 65 20 76 61 6c  ion sets the val
14c80 75 65 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  ue of the sqlite
14c90 33 5f 76 61 6c 75 65 20 6f 62 6a 65 63 74 20 70  3_value object p
14ca0 61 73 73 65 64 20 61 73 20 74 68 65 0a 2a 2a 20  assed as the.** 
14cb0 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 74  first argument t
14cc0 6f 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20  o a copy of the 
14cd0 73 74 72 69 6e 67 20 6f 72 20 62 6c 6f 62 20 68  string or blob h
14ce0 65 6c 64 20 69 6e 20 74 68 65 20 61 44 61 74 61  eld in the aData
14cf0 5b 5d 20 0a 2a 2a 20 62 75 66 66 65 72 2e 20 53  [] .** buffer. S
14d00 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75  QLITE_OK is retu
14d10 72 6e 65 64 20 69 66 20 73 75 63 63 65 73 73 66  rned if successf
14d20 75 6c 2c 20 6f 72 20 53 51 4c 49 54 45 5f 4e 4f  ul, or SQLITE_NO
14d30 4d 45 4d 20 69 66 20 61 6e 20 4f 4f 4d 0a 2a 2a  MEM if an OOM.**
14d40 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a   error occurs..*
14d50 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73  /.static int ses
14d60 73 69 6f 6e 56 61 6c 75 65 53 65 74 53 74 72 28  sionValueSetStr(
14d70 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  .  sqlite3_value
14d80 20 2a 70 56 61 6c 2c 20 20 20 20 20 20 20 20 20   *pVal,         
14d90 20 20 20 2f 2a 20 53 65 74 20 74 68 65 20 76 61     /* Set the va
14da0 6c 75 65 20 6f 66 20 74 68 69 73 20 6f 62 6a 65  lue of this obje
14db0 63 74 20 2a 2f 0a 20 20 75 38 20 2a 61 44 61 74  ct */.  u8 *aDat
14dc0 61 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  a,              
14dd0 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65          /* Buffe
14de0 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 73 74 72  r containing str
14df0 69 6e 67 20 6f 72 20 62 6c 6f 62 20 64 61 74 61  ing or blob data
14e00 20 2a 2f 0a 20 20 69 6e 74 20 6e 44 61 74 61 2c   */.  int nData,
14e10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14e20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
14e30 20 62 75 66 66 65 72 20 61 44 61 74 61 5b 5d 20   buffer aData[] 
14e40 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 75 38  in bytes */.  u8
14e50 20 65 6e 63 20 20 20 20 20 20 20 20 20 20 20 20   enc            
14e60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
14e70 20 53 74 72 69 6e 67 20 65 6e 63 6f 64 69 6e 67   String encoding
14e80 20 28 30 20 66 6f 72 20 62 6c 6f 62 73 29 20 2a   (0 for blobs) *
14e90 2f 0a 29 7b 0a 20 20 2f 2a 20 49 6e 20 74 68 65  /.){.  /* In the
14ea0 6f 72 79 20 74 68 69 73 20 63 6f 64 65 20 63 6f  ory this code co
14eb0 75 6c 64 20 6a 75 73 74 20 70 61 73 73 20 53 51  uld just pass SQ
14ec0 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 20 61  LITE_TRANSIENT a
14ed0 73 20 74 68 65 20 66 69 6e 61 6c 0a 20 20 2a 2a  s the final.  **
14ee0 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 73 71 6c   argument to sql
14ef0 69 74 65 33 56 61 6c 75 65 53 65 74 53 74 72 28  ite3ValueSetStr(
14f00 29 20 61 6e 64 20 68 61 76 65 20 74 68 65 20 63  ) and have the c
14f10 6f 70 79 20 63 72 65 61 74 65 64 20 0a 20 20 2a  opy created .  *
14f20 2a 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 2e  * automatically.
14f30 20 42 75 74 20 64 6f 69 6e 67 20 73 6f 20 6d 61   But doing so ma
14f40 6b 65 73 20 69 74 20 64 69 66 66 69 63 75 6c 74  kes it difficult
14f50 20 74 6f 20 64 65 74 65 63 74 20 61 6e 79 20 4f   to detect any O
14f60 4f 4d 0a 20 20 2a 2a 20 65 72 72 6f 72 2e 20 48  OM.  ** error. H
14f70 65 6e 63 65 20 74 68 65 20 63 6f 64 65 20 74 6f  ence the code to
14f80 20 63 72 65 61 74 65 20 74 68 65 20 63 6f 70 79   create the copy
14f90 20 65 78 74 65 72 6e 61 6c 6c 79 2e 20 2a 2f 0a   externally. */.
14fa0 20 20 75 38 20 2a 61 43 6f 70 79 20 3d 20 73 71    u8 *aCopy = sq
14fb0 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 44 61  lite3_malloc(nDa
14fc0 74 61 2b 31 29 3b 0a 20 20 69 66 28 20 61 43 6f  ta+1);.  if( aCo
14fd0 70 79 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53  py==0 ) return S
14fe0 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d  QLITE_NOMEM;.  m
14ff0 65 6d 63 70 79 28 61 43 6f 70 79 2c 20 61 44 61  emcpy(aCopy, aDa
15000 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 73 71  ta, nData);.  sq
15010 6c 69 74 65 33 56 61 6c 75 65 53 65 74 53 74 72  lite3ValueSetStr
15020 28 70 56 61 6c 2c 20 6e 44 61 74 61 2c 20 28 63  (pVal, nData, (c
15030 68 61 72 2a 29 61 43 6f 70 79 2c 20 65 6e 63 2c  har*)aCopy, enc,
15040 20 73 71 6c 69 74 65 33 5f 66 72 65 65 29 3b 0a   sqlite3_free);.
15050 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
15060 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 73  OK;.}../*.** Des
15070 65 72 69 61 6c 69 7a 65 20 61 20 73 69 6e 67 6c  erialize a singl
15080 65 20 72 65 63 6f 72 64 20 66 72 6f 6d 20 61 20  e record from a 
15090 62 75 66 66 65 72 20 69 6e 20 6d 65 6d 6f 72 79  buffer in memory
150a0 2e 20 53 65 65 20 22 52 45 43 4f 52 44 20 46 4f  . See "RECORD FO
150b0 52 4d 41 54 22 0a 2a 2a 20 66 6f 72 20 64 65 74  RMAT".** for det
150c0 61 69 6c 73 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 6e  ails..**.** When
150d0 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
150e0 73 20 63 61 6c 6c 65 64 2c 20 2a 70 61 43 68 61  s called, *paCha
150f0 6e 67 65 20 70 6f 69 6e 74 73 20 74 6f 20 74 68  nge points to th
15100 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 72  e start of the r
15110 65 63 6f 72 64 0a 2a 2a 20 74 6f 20 64 65 73 65  ecord.** to dese
15120 72 69 61 6c 69 7a 65 2e 20 41 73 73 75 6d 69 6e  rialize. Assumin
15130 67 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72  g no error occur
15140 73 2c 20 2a 70 61 43 68 61 6e 67 65 20 69 73 20  s, *paChange is 
15150 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 0a  set to point to.
15160 2a 2a 20 6f 6e 65 20 62 79 74 65 20 61 66 74 65  ** one byte afte
15170 72 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65  r the end of the
15180 20 73 61 6d 65 20 72 65 63 6f 72 64 20 62 65 66   same record bef
15190 6f 72 65 20 74 68 69 73 20 66 75 6e 63 74 69 6f  ore this functio
151a0 6e 20 72 65 74 75 72 6e 73 2e 0a 2a 2a 20 49 66  n returns..** If
151b0 20 74 68 65 20 61 72 67 75 6d 65 6e 74 20 61 62   the argument ab
151c0 50 4b 20 69 73 20 4e 55 4c 4c 2c 20 74 68 65 6e  PK is NULL, then
151d0 20 74 68 65 20 72 65 63 6f 72 64 20 63 6f 6e 74   the record cont
151e0 61 69 6e 73 20 6e 43 6f 6c 20 76 61 6c 75 65 73  ains nCol values
151f0 2e 20 4f 72 2c 0a 2a 2a 20 69 66 20 61 62 50 4b  . Or,.** if abPK
15200 20 69 73 20 6f 74 68 65 72 20 74 68 61 6e 20 4e   is other than N
15210 55 4c 4c 2c 20 74 68 65 6e 20 74 68 65 20 72 65  ULL, then the re
15220 63 6f 72 64 20 63 6f 6e 74 61 69 6e 73 20 6f 6e  cord contains on
15230 6c 79 20 74 68 65 20 50 4b 20 66 69 65 6c 64 73  ly the PK fields
15240 0a 2a 2a 20 28 69 6e 20 6f 74 68 65 72 20 77 6f  .** (in other wo
15250 72 64 73 2c 20 69 74 20 69 73 20 61 20 70 61 74  rds, it is a pat
15260 63 68 73 65 74 20 44 45 4c 45 54 45 20 72 65 63  chset DELETE rec
15270 6f 72 64 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73  ord)..**.** If s
15280 75 63 63 65 73 73 66 75 6c 2c 20 65 61 63 68 20  uccessful, each 
15290 65 6c 65 6d 65 6e 74 20 6f 66 20 74 68 65 20 61  element of the a
152a0 70 4f 75 74 5b 5d 20 61 72 72 61 79 20 28 61 6c  pOut[] array (al
152b0 6c 6f 63 61 74 65 64 20 62 79 20 74 68 65 20 63  located by the c
152c0 61 6c 6c 65 72 29 0a 2a 2a 20 69 73 20 73 65 74  aller).** is set
152d0 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 61 6e 20   to point to an 
152e0 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 6f 62  sqlite3_value ob
152f0 6a 65 63 74 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ject containing 
15300 74 68 65 20 76 61 6c 75 65 20 72 65 61 64 0a 2a  the value read.*
15310 2a 20 66 72 6f 6d 20 74 68 65 20 63 6f 72 72 65  * from the corre
15320 73 70 6f 6e 64 69 6e 67 20 70 6f 73 69 74 69 6f  sponding positio
15330 6e 20 69 6e 20 74 68 65 20 72 65 63 6f 72 64 2e  n in the record.
15340 20 49 66 20 74 68 61 74 20 76 61 6c 75 65 20 69   If that value i
15350 73 20 6e 6f 74 0a 2a 2a 20 69 6e 63 6c 75 64 65  s not.** include
15360 64 20 69 6e 20 74 68 65 20 72 65 63 6f 72 64 20  d in the record 
15370 28 69 2e 65 2e 20 62 65 63 61 75 73 65 20 74 68  (i.e. because th
15380 65 20 72 65 63 6f 72 64 20 69 73 20 70 61 72 74  e record is part
15390 20 6f 66 20 61 6e 20 55 50 44 41 54 45 20 63 68   of an UPDATE ch
153a0 61 6e 67 65 0a 2a 2a 20 61 6e 64 20 74 68 65 20  ange.** and the 
153b0 66 69 65 6c 64 20 77 61 73 20 6e 6f 74 20 6d 6f  field was not mo
153c0 64 69 66 69 65 64 29 2c 20 74 68 65 20 63 6f 72  dified), the cor
153d0 72 65 73 70 6f 6e 64 69 6e 67 20 65 6c 65 6d 65  responding eleme
153e0 6e 74 20 6f 66 20 61 70 4f 75 74 5b 5d 20 69 73  nt of apOut[] is
153f0 0a 2a 2a 20 73 65 74 20 74 6f 20 4e 55 4c 4c 2e  .** set to NULL.
15400 0a 2a 2a 0a 2a 2a 20 49 74 20 69 73 20 74 68 65  .**.** It is the
15410 20 72 65 73 70 6f 6e 73 69 62 69 6c 69 74 79 20   responsibility 
15420 6f 66 20 74 68 65 20 63 61 6c 6c 65 72 20 74 6f  of the caller to
15430 20 66 72 65 65 20 61 6c 6c 20 73 71 6c 69 74 65   free all sqlite
15440 5f 76 61 6c 75 65 20 73 74 72 75 63 74 75 72 65  _value structure
15450 73 0a 2a 2a 20 75 73 69 6e 67 20 73 71 6c 69 74  s.** using sqlit
15460 65 33 5f 66 72 65 65 28 29 2e 0a 2a 2a 0a 2a 2a  e3_free()..**.**
15470 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   If an error occ
15480 75 72 73 2c 20 61 6e 20 53 51 4c 69 74 65 20 65  urs, an SQLite e
15490 72 72 6f 72 20 63 6f 64 65 20 28 65 2e 67 2e 20  rror code (e.g. 
154a0 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 20 69 73  SQLITE_NOMEM) is
154b0 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 20 54 68   returned..** Th
154c0 65 20 61 70 4f 75 74 5b 5d 20 61 72 72 61 79 20  e apOut[] array 
154d0 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20 70 61  may have been pa
154e0 72 74 69 61 6c 6c 79 20 70 6f 70 75 6c 61 74 65  rtially populate
154f0 64 20 69 6e 20 74 68 69 73 20 63 61 73 65 2e 0a  d in this case..
15500 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
15510 73 73 69 6f 6e 52 65 61 64 52 65 63 6f 72 64 28  ssionReadRecord(
15520 0a 20 20 53 65 73 73 69 6f 6e 49 6e 70 75 74 20  .  SessionInput 
15530 2a 70 49 6e 2c 20 20 20 20 20 20 20 20 20 20 20  *pIn,           
15540 20 20 20 2f 2a 20 49 6e 70 75 74 20 64 61 74 61     /* Input data
15550 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c 20   */.  int nCol, 
15560 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15570 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
15580 6f 66 20 76 61 6c 75 65 73 20 69 6e 20 72 65 63  of values in rec
15590 6f 72 64 20 2a 2f 0a 20 20 75 38 20 2a 61 62 50  ord */.  u8 *abP
155a0 4b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  K,              
155b0 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61           /* Arra
155c0 79 20 6f 66 20 70 72 69 6d 61 72 79 20 6b 65 79  y of primary key
155d0 20 66 6c 61 67 73 2c 20 6f 72 20 4e 55 4c 4c 20   flags, or NULL 
155e0 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c  */.  sqlite3_val
155f0 75 65 20 2a 2a 61 70 4f 75 74 20 20 20 20 20 20  ue **apOut      
15600 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 76 61       /* Write va
15610 6c 75 65 73 20 74 6f 20 74 68 69 73 20 61 72 72  lues to this arr
15620 61 79 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69  ay */.){.  int i
15630 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
15640 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73             /* Us
15650 65 64 20 74 6f 20 69 74 65 72 61 74 65 20 74 68  ed to iterate th
15660 72 6f 75 67 68 20 63 6f 6c 75 6d 6e 73 20 2a 2f  rough columns */
15670 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
15680 54 45 5f 4f 4b 3b 0a 0a 20 20 66 6f 72 28 69 3d  TE_OK;..  for(i=
15690 30 3b 20 69 3c 6e 43 6f 6c 20 26 26 20 72 63 3d  0; i<nCol && rc=
156a0 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29  =SQLITE_OK; i++)
156b0 7b 0a 20 20 20 20 69 6e 74 20 65 54 79 70 65 20  {.    int eType 
156c0 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
156d0 20 20 20 20 2f 2a 20 54 79 70 65 20 6f 66 20 76      /* Type of v
156e0 61 6c 75 65 20 28 53 51 4c 49 54 45 5f 4e 55 4c  alue (SQLITE_NUL
156f0 4c 2c 20 54 45 58 54 20 65 74 63 2e 29 20 2a 2f  L, TEXT etc.) */
15700 0a 20 20 20 20 69 66 28 20 61 62 50 4b 20 26 26  .    if( abPK &&
15710 20 61 62 50 4b 5b 69 5d 3d 3d 30 20 29 20 63 6f   abPK[i]==0 ) co
15720 6e 74 69 6e 75 65 3b 0a 20 20 20 20 72 63 20 3d  ntinue;.    rc =
15730 20 73 65 73 73 69 6f 6e 49 6e 70 75 74 42 75 66   sessionInputBuf
15740 66 65 72 28 70 49 6e 2c 20 39 29 3b 0a 20 20 20  fer(pIn, 9);.   
15750 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
15760 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  OK ){.      if( 
15770 70 49 6e 2d 3e 69 4e 65 78 74 3e 3d 70 49 6e 2d  pIn->iNext>=pIn-
15780 3e 6e 44 61 74 61 20 29 7b 0a 20 20 20 20 20 20  >nData ){.      
15790 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 43 4f    rc = SQLITE_CO
157a0 52 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20 20 20  RRUPT_BKPT;.    
157b0 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
157c0 20 65 54 79 70 65 20 3d 20 70 49 6e 2d 3e 61 44   eType = pIn->aD
157d0 61 74 61 5b 70 49 6e 2d 3e 69 4e 65 78 74 2b 2b  ata[pIn->iNext++
157e0 5d 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  ];.        asser
157f0 74 28 20 61 70 4f 75 74 5b 69 5d 3d 3d 30 20 29  t( apOut[i]==0 )
15800 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 65 54  ;.        if( eT
15810 79 70 65 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ype ){.         
15820 20 61 70 4f 75 74 5b 69 5d 20 3d 20 73 71 6c 69   apOut[i] = sqli
15830 74 65 33 56 61 6c 75 65 4e 65 77 28 30 29 3b 0a  te3ValueNew(0);.
15840 20 20 20 20 20 20 20 20 20 20 69 66 28 20 21 61            if( !a
15850 70 4f 75 74 5b 69 5d 20 29 20 72 63 20 3d 20 53  pOut[i] ) rc = S
15860 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
15870 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
15880 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72 63     }..    if( rc
15890 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
158a0 20 20 20 20 20 75 38 20 2a 61 56 61 6c 20 3d 20       u8 *aVal = 
158b0 26 70 49 6e 2d 3e 61 44 61 74 61 5b 70 49 6e 2d  &pIn->aData[pIn-
158c0 3e 69 4e 65 78 74 5d 3b 0a 20 20 20 20 20 20 69  >iNext];.      i
158d0 66 28 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45  f( eType==SQLITE
158e0 5f 54 45 58 54 20 7c 7c 20 65 54 79 70 65 3d 3d  _TEXT || eType==
158f0 53 51 4c 49 54 45 5f 42 4c 4f 42 20 29 7b 0a 20  SQLITE_BLOB ){. 
15900 20 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65         int nByte
15910 3b 0a 20 20 20 20 20 20 20 20 70 49 6e 2d 3e 69  ;.        pIn->i
15920 4e 65 78 74 20 2b 3d 20 73 65 73 73 69 6f 6e 56  Next += sessionV
15930 61 72 69 6e 74 47 65 74 28 61 56 61 6c 2c 20 26  arintGet(aVal, &
15940 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20 20 20  nByte);.        
15950 72 63 20 3d 20 73 65 73 73 69 6f 6e 49 6e 70 75  rc = sessionInpu
15960 74 42 75 66 66 65 72 28 70 49 6e 2c 20 6e 42 79  tBuffer(pIn, nBy
15970 74 65 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  te);.        if(
15980 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
15990 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  {.          if( 
159a0 6e 42 79 74 65 3c 30 20 7c 7c 20 6e 42 79 74 65  nByte<0 || nByte
159b0 3e 70 49 6e 2d 3e 6e 44 61 74 61 2d 70 49 6e 2d  >pIn->nData-pIn-
159c0 3e 69 4e 65 78 74 20 29 7b 0a 20 20 20 20 20 20  >iNext ){.      
159d0 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
159e0 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54 3b 0a  E_CORRUPT_BKPT;.
159f0 20 20 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b            }else{
15a00 0a 20 20 20 20 20 20 20 20 20 20 20 20 75 38 20  .            u8 
15a10 65 6e 63 20 3d 20 28 65 54 79 70 65 3d 3d 53 51  enc = (eType==SQ
15a20 4c 49 54 45 5f 54 45 58 54 20 3f 20 53 51 4c 49  LITE_TEXT ? SQLI
15a30 54 45 5f 55 54 46 38 20 3a 20 30 29 3b 0a 20 20  TE_UTF8 : 0);.  
15a40 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 73            rc = s
15a50 65 73 73 69 6f 6e 56 61 6c 75 65 53 65 74 53 74  essionValueSetSt
15a60 72 28 61 70 4f 75 74 5b 69 5d 2c 26 70 49 6e 2d  r(apOut[i],&pIn-
15a70 3e 61 44 61 74 61 5b 70 49 6e 2d 3e 69 4e 65 78  >aData[pIn->iNex
15a80 74 5d 2c 6e 42 79 74 65 2c 65 6e 63 29 3b 0a 20  t],nByte,enc);. 
15a90 20 20 20 20 20 20 20 20 20 20 20 70 49 6e 2d 3e             pIn->
15aa0 69 4e 65 78 74 20 2b 3d 20 6e 42 79 74 65 3b 0a  iNext += nByte;.
15ab0 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
15ac0 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20      }.      }.  
15ad0 20 20 20 20 69 66 28 20 65 54 79 70 65 3d 3d 53      if( eType==S
15ae0 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 7c 7c  QLITE_INTEGER ||
15af0 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 46   eType==SQLITE_F
15b00 4c 4f 41 54 20 29 7b 0a 20 20 20 20 20 20 20 20  LOAT ){.        
15b10 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 76 20  sqlite3_int64 v 
15b20 3d 20 73 65 73 73 69 6f 6e 47 65 74 49 36 34 28  = sessionGetI64(
15b30 61 56 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 69  aVal);.        i
15b40 66 28 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45  f( eType==SQLITE
15b50 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20 20 20 20  _INTEGER ){.    
15b60 20 20 20 20 20 20 73 71 6c 69 74 65 33 56 64 62        sqlite3Vdb
15b70 65 4d 65 6d 53 65 74 49 6e 74 36 34 28 61 70 4f  eMemSetInt64(apO
15b80 75 74 5b 69 5d 2c 20 76 29 3b 0a 20 20 20 20 20  ut[i], v);.     
15b90 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
15ba0 20 20 20 20 64 6f 75 62 6c 65 20 64 3b 0a 20 20      double d;.  
15bb0 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26          memcpy(&
15bc0 64 2c 20 26 76 2c 20 38 29 3b 0a 20 20 20 20 20  d, &v, 8);.     
15bd0 20 20 20 20 20 73 71 6c 69 74 65 33 56 64 62 65       sqlite3Vdbe
15be0 4d 65 6d 53 65 74 44 6f 75 62 6c 65 28 61 70 4f  MemSetDouble(apO
15bf0 75 74 5b 69 5d 2c 20 64 29 3b 0a 20 20 20 20 20  ut[i], d);.     
15c00 20 20 20 7d 0a 20 20 20 20 20 20 20 20 70 49 6e     }.        pIn
15c10 2d 3e 69 4e 65 78 74 20 2b 3d 20 38 3b 0a 20 20  ->iNext += 8;.  
15c20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
15c30 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
15c40 0a 2f 2a 0a 2a 2a 20 54 68 65 20 69 6e 70 75 74  ./*.** The input
15c50 20 70 6f 69 6e 74 65 72 20 63 75 72 72 65 6e 74   pointer current
15c60 6c 79 20 70 6f 69 6e 74 73 20 74 6f 20 74 68 65  ly points to the
15c70 20 73 65 63 6f 6e 64 20 62 79 74 65 20 6f 66 20   second byte of 
15c80 61 20 74 61 62 6c 65 2d 68 65 61 64 65 72 2e 0a  a table-header..
15c90 2a 2a 20 53 70 65 63 69 66 69 63 61 6c 6c 79 2c  ** Specifically,
15ca0 20 74 6f 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e   to the followin
15cb0 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 2b 20 6e 75 6d  g:.**.**   + num
15cc0 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69  ber of columns i
15cd0 6e 20 74 61 62 6c 65 20 28 76 61 72 69 6e 74 29  n table (varint)
15ce0 0a 2a 2a 20 20 20 2b 20 61 72 72 61 79 20 6f 66  .**   + array of
15cf0 20 50 4b 20 66 6c 61 67 73 20 28 31 20 62 79 74   PK flags (1 byt
15d00 65 20 70 65 72 20 63 6f 6c 75 6d 6e 29 2c 0a 2a  e per column),.*
15d10 2a 20 20 20 2b 20 74 61 62 6c 65 20 6e 61 6d 65  *   + table name
15d20 20 28 6e 75 6c 20 74 65 72 6d 69 6e 61 74 65 64   (nul terminated
15d30 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 75  )..**.** This fu
15d40 6e 63 74 69 6f 6e 20 65 6e 73 75 72 65 73 20 74  nction ensures t
15d50 68 61 74 20 61 6c 6c 20 6f 66 20 74 68 65 20 61  hat all of the a
15d60 62 6f 76 65 20 69 73 20 70 72 65 73 65 6e 74 20  bove is present 
15d70 69 6e 20 74 68 65 20 69 6e 70 75 74 20 0a 2a 2a  in the input .**
15d80 20 62 75 66 66 65 72 20 28 69 2e 65 2e 20 74 68   buffer (i.e. th
15d90 61 74 20 69 74 20 63 61 6e 20 62 65 20 61 63 63  at it can be acc
15da0 65 73 73 65 64 20 77 69 74 68 6f 75 74 20 61 6e  essed without an
15db0 79 20 63 61 6c 6c 73 20 74 6f 20 78 49 6e 70 75  y calls to xInpu
15dc0 74 28 29 29 2e 0a 2a 2a 20 49 66 20 73 75 63 63  t())..** If succ
15dd0 65 73 73 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f  essful, SQLITE_O
15de0 4b 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 4f  K is returned. O
15df0 74 68 65 72 77 69 73 65 2c 20 61 6e 20 53 51 4c  therwise, an SQL
15e00 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a  ite error code..
15e10 2a 2a 20 54 68 65 20 69 6e 70 75 74 20 70 6f 69  ** The input poi
15e20 6e 74 65 72 20 69 73 20 6e 6f 74 20 6d 6f 76 65  nter is not move
15e30 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
15e40 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65   sessionChangese
15e50 74 42 75 66 66 65 72 54 62 6c 68 64 72 28 53 65  tBufferTblhdr(Se
15e60 73 73 69 6f 6e 49 6e 70 75 74 20 2a 70 49 6e 2c  ssionInput *pIn,
15e70 20 69 6e 74 20 2a 70 6e 42 79 74 65 29 7b 0a 20   int *pnByte){. 
15e80 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
15e90 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 43 6f 6c 20  _OK;.  int nCol 
15ea0 3d 20 30 3b 0a 20 20 69 6e 74 20 6e 52 65 61 64  = 0;.  int nRead
15eb0 20 3d 20 30 3b 0a 0a 20 20 72 63 20 3d 20 73 65   = 0;..  rc = se
15ec0 73 73 69 6f 6e 49 6e 70 75 74 42 75 66 66 65 72  ssionInputBuffer
15ed0 28 70 49 6e 2c 20 39 29 3b 0a 20 20 69 66 28 20  (pIn, 9);.  if( 
15ee0 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
15ef0 0a 20 20 20 20 6e 52 65 61 64 20 2b 3d 20 73 65  .    nRead += se
15f00 73 73 69 6f 6e 56 61 72 69 6e 74 47 65 74 28 26  ssionVarintGet(&
15f10 70 49 6e 2d 3e 61 44 61 74 61 5b 70 49 6e 2d 3e  pIn->aData[pIn->
15f20 69 4e 65 78 74 20 2b 20 6e 52 65 61 64 5d 2c 20  iNext + nRead], 
15f30 26 6e 43 6f 6c 29 3b 0a 20 20 20 20 2f 2a 20 54  &nCol);.    /* T
15f40 68 65 20 68 61 72 64 20 75 70 70 65 72 20 6c 69  he hard upper li
15f50 6d 69 74 20 66 6f 72 20 74 68 65 20 6e 75 6d 62  mit for the numb
15f60 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e  er of columns in
15f70 20 61 6e 20 53 51 4c 69 74 65 0a 20 20 20 20 2a   an SQLite.    *
15f80 2a 20 64 61 74 61 62 61 73 65 20 74 61 62 6c 65  * database table
15f90 20 69 73 2c 20 61 63 63 6f 72 64 69 6e 67 20 74   is, according t
15fa0 6f 20 73 71 6c 69 74 65 4c 69 6d 69 74 2e 68 2c  o sqliteLimit.h,
15fb0 20 33 32 36 37 36 2e 20 53 6f 20 0a 20 20 20 20   32676. So .    
15fc0 2a 2a 20 63 6f 6e 73 69 64 65 72 20 61 6e 79 20  ** consider any 
15fd0 74 61 62 6c 65 2d 68 65 61 64 65 72 20 74 68 61  table-header tha
15fe0 74 20 70 75 72 70 6f 72 74 73 20 74 6f 20 68 61  t purports to ha
15ff0 76 65 20 6d 6f 72 65 20 74 68 61 6e 20 36 35 35  ve more than 655
16000 33 36 20 0a 20 20 20 20 2a 2a 20 63 6f 6c 75 6d  36 .    ** colum
16010 6e 73 20 74 6f 20 62 65 20 63 6f 72 72 75 70 74  ns to be corrupt
16020 2e 20 54 68 69 73 20 69 73 20 63 6f 6e 76 65 6e  . This is conven
16030 69 65 6e 74 20 62 65 63 61 75 73 65 20 6f 74 68  ient because oth
16040 65 72 77 69 73 65 2c 20 0a 20 20 20 20 2a 2a 20  erwise, .    ** 
16050 69 66 20 74 68 65 20 28 6e 43 6f 6c 3e 36 35 35  if the (nCol>655
16060 33 36 29 20 63 6f 6e 64 69 74 69 6f 6e 20 62 65  36) condition be
16070 6c 6f 77 20 77 65 72 65 20 6f 6d 69 74 74 65 64  low were omitted
16080 2c 20 61 20 73 75 66 66 69 63 69 65 6e 74 6c 79  , a sufficiently
16090 20 0a 20 20 20 20 2a 2a 20 6c 61 72 67 65 20 76   .    ** large v
160a0 61 6c 75 65 20 66 6f 72 20 6e 43 6f 6c 20 6d 61  alue for nCol ma
160b0 79 20 63 61 75 73 65 20 6e 52 65 61 64 20 74 6f  y cause nRead to
160c0 20 77 72 61 70 20 61 72 6f 75 6e 64 20 61 6e 64   wrap around and
160d0 20 62 65 63 6f 6d 65 20 0a 20 20 20 20 2a 2a 20   become .    ** 
160e0 6e 65 67 61 74 69 76 65 2e 20 4c 65 61 64 69 6e  negative. Leadin
160f0 67 20 74 6f 20 61 20 63 72 61 73 68 2e 20 2a 2f  g to a crash. */
16100 0a 20 20 20 20 69 66 28 20 6e 43 6f 6c 3c 30 20  .    if( nCol<0 
16110 7c 7c 20 6e 43 6f 6c 3e 36 35 35 33 36 20 29 7b  || nCol>65536 ){
16120 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
16130 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54 3b  TE_CORRUPT_BKPT;
16140 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
16150 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 49 6e    rc = sessionIn
16160 70 75 74 42 75 66 66 65 72 28 70 49 6e 2c 20 6e  putBuffer(pIn, n
16170 52 65 61 64 2b 6e 43 6f 6c 2b 31 30 30 29 3b 0a  Read+nCol+100);.
16180 20 20 20 20 20 20 6e 52 65 61 64 20 2b 3d 20 6e        nRead += n
16190 43 6f 6c 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  Col;.    }.  }..
161a0 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c    while( rc==SQL
161b0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 77 68  ITE_OK ){.    wh
161c0 69 6c 65 28 20 28 70 49 6e 2d 3e 69 4e 65 78 74  ile( (pIn->iNext
161d0 20 2b 20 6e 52 65 61 64 29 3c 70 49 6e 2d 3e 6e   + nRead)<pIn->n
161e0 44 61 74 61 20 26 26 20 70 49 6e 2d 3e 61 44 61  Data && pIn->aDa
161f0 74 61 5b 70 49 6e 2d 3e 69 4e 65 78 74 20 2b 20  ta[pIn->iNext + 
16200 6e 52 65 61 64 5d 20 29 7b 0a 20 20 20 20 20 20  nRead] ){.      
16210 6e 52 65 61 64 2b 2b 3b 0a 20 20 20 20 7d 0a 20  nRead++;.    }. 
16220 20 20 20 69 66 28 20 28 70 49 6e 2d 3e 69 4e 65     if( (pIn->iNe
16230 78 74 20 2b 20 6e 52 65 61 64 29 3c 70 49 6e 2d  xt + nRead)<pIn-
16240 3e 6e 44 61 74 61 20 29 20 62 72 65 61 6b 3b 0a  >nData ) break;.
16250 20 20 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e      rc = session
16260 49 6e 70 75 74 42 75 66 66 65 72 28 70 49 6e 2c  InputBuffer(pIn,
16270 20 6e 52 65 61 64 20 2b 20 31 30 30 29 3b 0a 20   nRead + 100);. 
16280 20 7d 0a 20 20 2a 70 6e 42 79 74 65 20 3d 20 6e   }.  *pnByte = n
16290 52 65 61 64 2b 31 3b 0a 20 20 72 65 74 75 72 6e  Read+1;.  return
162a0 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
162b0 65 20 69 6e 70 75 74 20 70 6f 69 6e 74 65 72 20  e input pointer 
162c0 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73  currently points
162d0 20 74 6f 20 74 68 65 20 66 69 72 73 74 20 62 79   to the first by
162e0 74 65 20 6f 66 20 74 68 65 20 66 69 72 73 74 20  te of the first 
162f0 66 69 65 6c 64 0a 2a 2a 20 6f 66 20 61 20 72 65  field.** of a re
16300 63 6f 72 64 20 63 6f 6e 73 69 73 74 69 6e 67 20  cord consisting 
16310 6f 66 20 6e 43 6f 6c 20 63 6f 6c 75 6d 6e 73 2e  of nCol columns.
16320 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 65   This function e
16330 6e 73 75 72 65 73 20 74 68 65 20 65 6e 74 69 72  nsures the entir
16340 65 0a 2a 2a 20 72 65 63 6f 72 64 20 69 73 20 62  e.** record is b
16350 75 66 66 65 72 65 64 2e 20 49 74 20 64 6f 65 73  uffered. It does
16360 20 6e 6f 74 20 6d 6f 76 65 20 74 68 65 20 69 6e   not move the in
16370 70 75 74 20 70 6f 69 6e 74 65 72 2e 0a 2a 2a 0a  put pointer..**.
16380 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c  ** If successful
16390 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72  , SQLITE_OK is r
163a0 65 74 75 72 6e 65 64 20 61 6e 64 20 2a 70 6e 42  eturned and *pnB
163b0 79 74 65 20 69 73 20 73 65 74 20 74 6f 20 74 68  yte is set to th
163c0 65 20 73 69 7a 65 20 6f 66 0a 2a 2a 20 74 68 65  e size of.** the
163d0 20 72 65 63 6f 72 64 20 69 6e 20 62 79 74 65 73   record in bytes
163e0 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 61 6e 20  . Otherwise, an 
163f0 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
16400 65 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 54  e is returned. T
16410 68 65 0a 2a 2a 20 66 69 6e 61 6c 20 76 61 6c 75  he.** final valu
16420 65 20 6f 66 20 2a 70 6e 42 79 74 65 20 69 73 20  e of *pnByte is 
16430 75 6e 64 65 66 69 6e 65 64 20 69 6e 20 74 68 69  undefined in thi
16440 73 20 63 61 73 65 2e 0a 2a 2f 0a 73 74 61 74 69  s case..*/.stati
16450 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 43 68 61  c int sessionCha
16460 6e 67 65 73 65 74 42 75 66 66 65 72 52 65 63 6f  ngesetBufferReco
16470 72 64 28 0a 20 20 53 65 73 73 69 6f 6e 49 6e 70  rd(.  SessionInp
16480 75 74 20 2a 70 49 6e 2c 20 20 20 20 20 20 20 20  ut *pIn,        
16490 20 20 20 20 20 20 2f 2a 20 49 6e 70 75 74 20 64        /* Input d
164a0 61 74 61 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f  ata */.  int nCo
164b0 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
164c0 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
164d0 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e  er of columns in
164e0 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20 69 6e 74   record */.  int
164f0 20 2a 70 6e 42 79 74 65 20 20 20 20 20 20 20 20   *pnByte        
16500 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
16510 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20 72 65 63  OUT: Size of rec
16520 6f 72 64 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  ord in bytes */.
16530 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
16540 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e  LITE_OK;.  int n
16550 42 79 74 65 20 3d 20 30 3b 0a 20 20 69 6e 74 20  Byte = 0;.  int 
16560 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 72 63  i;.  for(i=0; rc
16570 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69  ==SQLITE_OK && i
16580 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20  <nCol; i++){.   
16590 20 69 6e 74 20 65 54 79 70 65 3b 0a 20 20 20 20   int eType;.    
165a0 72 63 20 3d 20 73 65 73 73 69 6f 6e 49 6e 70 75  rc = sessionInpu
165b0 74 42 75 66 66 65 72 28 70 49 6e 2c 20 6e 42 79  tBuffer(pIn, nBy
165c0 74 65 20 2b 20 31 30 29 3b 0a 20 20 20 20 69 66  te + 10);.    if
165d0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
165e0 29 7b 0a 20 20 20 20 20 20 65 54 79 70 65 20 3d  ){.      eType =
165f0 20 70 49 6e 2d 3e 61 44 61 74 61 5b 70 49 6e 2d   pIn->aData[pIn-
16600 3e 69 4e 65 78 74 20 2b 20 6e 42 79 74 65 2b 2b  >iNext + nByte++
16610 5d 3b 0a 20 20 20 20 20 20 69 66 28 20 65 54 79  ];.      if( eTy
16620 70 65 3d 3d 53 51 4c 49 54 45 5f 54 45 58 54 20  pe==SQLITE_TEXT 
16630 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45  || eType==SQLITE
16640 5f 42 4c 4f 42 20 29 7b 0a 20 20 20 20 20 20 20  _BLOB ){.       
16650 20 69 6e 74 20 6e 3b 0a 20 20 20 20 20 20 20 20   int n;.        
16660 6e 42 79 74 65 20 2b 3d 20 73 65 73 73 69 6f 6e  nByte += session
16670 56 61 72 69 6e 74 47 65 74 28 26 70 49 6e 2d 3e  VarintGet(&pIn->
16680 61 44 61 74 61 5b 70 49 6e 2d 3e 69 4e 65 78 74  aData[pIn->iNext
16690 2b 6e 42 79 74 65 5d 2c 20 26 6e 29 3b 0a 20 20  +nByte], &n);.  
166a0 20 20 20 20 20 20 6e 42 79 74 65 20 2b 3d 20 6e        nByte += n
166b0 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73  ;.        rc = s
166c0 65 73 73 69 6f 6e 49 6e 70 75 74 42 75 66 66 65  essionInputBuffe
166d0 72 28 70 49 6e 2c 20 6e 42 79 74 65 29 3b 0a 20  r(pIn, nByte);. 
166e0 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 65       }else if( e
166f0 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54  Type==SQLITE_INT
16700 45 47 45 52 20 7c 7c 20 65 54 79 70 65 3d 3d 53  EGER || eType==S
16710 51 4c 49 54 45 5f 46 4c 4f 41 54 20 29 7b 0a 20  QLITE_FLOAT ){. 
16720 20 20 20 20 20 20 20 6e 42 79 74 65 20 2b 3d 20         nByte += 
16730 38 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  8;.      }.    }
16740 0a 20 20 7d 0a 20 20 2a 70 6e 42 79 74 65 20 3d  .  }.  *pnByte =
16750 20 6e 42 79 74 65 3b 0a 20 20 72 65 74 75 72 6e   nByte;.  return
16760 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
16770 65 20 69 6e 70 75 74 20 70 6f 69 6e 74 65 72 20  e input pointer 
16780 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73  currently points
16790 20 74 6f 20 74 68 65 20 73 65 63 6f 6e 64 20 62   to the second b
167a0 79 74 65 20 6f 66 20 61 20 74 61 62 6c 65 2d 68  yte of a table-h
167b0 65 61 64 65 72 2e 0a 2a 2a 20 53 70 65 63 69 66  eader..** Specif
167c0 69 63 61 6c 6c 79 2c 20 74 6f 20 74 68 65 20 66  ically, to the f
167d0 6f 6c 6c 6f 77 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20  ollowing:.**.** 
167e0 20 20 2b 20 6e 75 6d 62 65 72 20 6f 66 20 63 6f    + number of co
167f0 6c 75 6d 6e 73 20 69 6e 20 74 61 62 6c 65 20 28  lumns in table (
16800 76 61 72 69 6e 74 29 0a 2a 2a 20 20 20 2b 20 61  varint).**   + a
16810 72 72 61 79 20 6f 66 20 50 4b 20 66 6c 61 67 73  rray of PK flags
16820 20 28 31 20 62 79 74 65 20 70 65 72 20 63 6f 6c   (1 byte per col
16830 75 6d 6e 29 2c 0a 2a 2a 20 20 20 2b 20 74 61 62  umn),.**   + tab
16840 6c 65 20 6e 61 6d 65 20 28 6e 75 6c 20 74 65 72  le name (nul ter
16850 6d 69 6e 61 74 65 64 29 2e 0a 2a 2a 0a 2a 2a 20  minated)..**.** 
16860 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 64 65  This function de
16870 63 6f 64 65 73 20 74 68 65 20 74 61 62 6c 65 2d  codes the table-
16880 68 65 61 64 65 72 20 61 6e 64 20 70 6f 70 75 6c  header and popul
16890 61 74 65 73 20 74 68 65 20 70 2d 3e 6e 43 6f 6c  ates the p->nCol
168a0 2c 20 0a 2a 2a 20 70 2d 3e 7a 54 61 62 20 61 6e  , .** p->zTab an
168b0 64 20 70 2d 3e 61 62 50 4b 5b 5d 20 76 61 72 69  d p->abPK[] vari
168c0 61 62 6c 65 73 20 61 63 63 6f 72 64 69 6e 67 6c  ables accordingl
168d0 79 2e 20 54 68 65 20 70 2d 3e 61 70 56 61 6c 75  y. The p->apValu
168e0 65 5b 5d 20 61 72 72 61 79 20 69 73 20 0a 2a 2a  e[] array is .**
168f0 20 61 6c 73 6f 20 61 6c 6c 6f 63 61 74 65 64 20   also allocated 
16900 6f 72 20 72 65 73 69 7a 65 64 20 61 63 63 6f 72  or resized accor
16910 64 69 6e 67 20 74 6f 20 74 68 65 20 6e 65 77 20  ding to the new 
16920 76 61 6c 75 65 20 6f 66 20 70 2d 3e 6e 43 6f 6c  value of p->nCol
16930 2e 20 54 68 65 0a 2a 2a 20 69 6e 70 75 74 20 70  . The.** input p
16940 6f 69 6e 74 65 72 20 69 73 20 6c 65 66 74 20 70  ointer is left p
16950 6f 69 6e 74 69 6e 67 20 74 6f 20 74 68 65 20 62  ointing to the b
16960 79 74 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68  yte following th
16970 65 20 74 61 62 6c 65 20 68 65 61 64 65 72 2e 0a  e table header..
16980 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65 73 73  **.** If success
16990 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69  ful, SQLITE_OK i
169a0 73 20 72 65 74 75 72 6e 65 64 2e 20 4f 74 68 65  s returned. Othe
169b0 72 77 69 73 65 2c 20 61 6e 20 53 51 4c 69 74 65  rwise, an SQLite
169c0 20 65 72 72 6f 72 20 63 6f 64 65 0a 2a 2a 20 69   error code.** i
169d0 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 74  s returned and t
169e0 68 65 20 66 69 6e 61 6c 20 76 61 6c 75 65 73 20  he final values 
169f0 6f 66 20 74 68 65 20 76 61 72 69 6f 75 73 20 66  of the various f
16a00 69 65 6c 64 73 20 65 6e 75 6d 65 72 61 74 65 64  ields enumerated
16a10 20 61 62 6f 76 65 0a 2a 2a 20 61 72 65 20 75 6e   above.** are un
16a20 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74  defined..*/.stat
16a30 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 43 68  ic int sessionCh
16a40 61 6e 67 65 73 65 74 52 65 61 64 54 62 6c 68 64  angesetReadTblhd
16a50 72 28 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65  r(sqlite3_change
16a60 73 65 74 5f 69 74 65 72 20 2a 70 29 7b 0a 20 20  set_iter *p){.  
16a70 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 6e 43  int rc;.  int nC
16a80 6f 70 79 3b 0a 20 20 61 73 73 65 72 74 28 20 70  opy;.  assert( p
16a90 2d 3e 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ->rc==SQLITE_OK 
16aa0 29 3b 0a 0a 20 20 72 63 20 3d 20 73 65 73 73 69  );..  rc = sessi
16ab0 6f 6e 43 68 61 6e 67 65 73 65 74 42 75 66 66 65  onChangesetBuffe
16ac0 72 54 62 6c 68 64 72 28 26 70 2d 3e 69 6e 2c 20  rTblhdr(&p->in, 
16ad0 26 6e 43 6f 70 79 29 3b 0a 20 20 69 66 28 20 72  &nCopy);.  if( r
16ae0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
16af0 20 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20      int nByte;. 
16b00 20 20 20 69 6e 74 20 6e 56 61 72 69 6e 74 3b 0a     int nVarint;.
16b10 20 20 20 20 6e 56 61 72 69 6e 74 20 3d 20 73 65      nVarint = se
16b20 73 73 69 6f 6e 56 61 72 69 6e 74 47 65 74 28 26  ssionVarintGet(&
16b30 70 2d 3e 69 6e 2e 61 44 61 74 61 5b 70 2d 3e 69  p->in.aData[p->i
16b40 6e 2e 69 4e 65 78 74 5d 2c 20 26 70 2d 3e 6e 43  n.iNext], &p->nC
16b50 6f 6c 29 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e  ol);.    if( p->
16b60 6e 43 6f 6c 3e 30 20 29 7b 0a 20 20 20 20 20 20  nCol>0 ){.      
16b70 6e 43 6f 70 79 20 2d 3d 20 6e 56 61 72 69 6e 74  nCopy -= nVarint
16b80 3b 0a 20 20 20 20 20 20 70 2d 3e 69 6e 2e 69 4e  ;.      p->in.iN
16b90 65 78 74 20 2b 3d 20 6e 56 61 72 69 6e 74 3b 0a  ext += nVarint;.
16ba0 20 20 20 20 20 20 6e 42 79 74 65 20 3d 20 70 2d        nByte = p-
16bb0 3e 6e 43 6f 6c 20 2a 20 73 69 7a 65 6f 66 28 73  >nCol * sizeof(s
16bc0 71 6c 69 74 65 33 5f 76 61 6c 75 65 2a 29 20 2a  qlite3_value*) *
16bd0 20 32 20 2b 20 6e 43 6f 70 79 3b 0a 20 20 20 20   2 + nCopy;.    
16be0 20 20 70 2d 3e 74 62 6c 68 64 72 2e 6e 42 75 66    p->tblhdr.nBuf
16bf0 20 3d 20 30 3b 0a 20 20 20 20 20 20 73 65 73 73   = 0;.      sess
16c00 69 6f 6e 42 75 66 66 65 72 47 72 6f 77 28 26 70  ionBufferGrow(&p
16c10 2d 3e 74 62 6c 68 64 72 2c 20 6e 42 79 74 65 2c  ->tblhdr, nByte,
16c20 20 26 72 63 29 3b 0a 20 20 20 20 7d 65 6c 73 65   &rc);.    }else
16c30 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
16c40 49 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54  ITE_CORRUPT_BKPT
16c50 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  ;.    }.  }..  i
16c60 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
16c70 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 50 4b 20   ){.    int iPK 
16c80 3d 20 73 69 7a 65 6f 66 28 73 71 6c 69 74 65 33  = sizeof(sqlite3
16c90 5f 76 61 6c 75 65 2a 29 2a 70 2d 3e 6e 43 6f 6c  _value*)*p->nCol
16ca0 2a 32 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28 70  *2;.    memset(p
16cb0 2d 3e 74 62 6c 68 64 72 2e 61 42 75 66 2c 20 30  ->tblhdr.aBuf, 0
16cc0 2c 20 69 50 4b 29 3b 0a 20 20 20 20 6d 65 6d 63  , iPK);.    memc
16cd0 70 79 28 26 70 2d 3e 74 62 6c 68 64 72 2e 61 42  py(&p->tblhdr.aB
16ce0 75 66 5b 69 50 4b 5d 2c 20 26 70 2d 3e 69 6e 2e  uf[iPK], &p->in.
16cf0 61 44 61 74 61 5b 70 2d 3e 69 6e 2e 69 4e 65 78  aData[p->in.iNex
16d00 74 5d 2c 20 6e 43 6f 70 79 29 3b 0a 20 20 20 20  t], nCopy);.    
16d10 70 2d 3e 69 6e 2e 69 4e 65 78 74 20 2b 3d 20 6e  p->in.iNext += n
16d20 43 6f 70 79 3b 0a 20 20 7d 0a 0a 20 20 70 2d 3e  Copy;.  }..  p->
16d30 61 70 56 61 6c 75 65 20 3d 20 28 73 71 6c 69 74  apValue = (sqlit
16d40 65 33 5f 76 61 6c 75 65 2a 2a 29 70 2d 3e 74 62  e3_value**)p->tb
16d50 6c 68 64 72 2e 61 42 75 66 3b 0a 20 20 70 2d 3e  lhdr.aBuf;.  p->
16d60 61 62 50 4b 20 3d 20 28 75 38 2a 29 26 70 2d 3e  abPK = (u8*)&p->
16d70 61 70 56 61 6c 75 65 5b 70 2d 3e 6e 43 6f 6c 2a  apValue[p->nCol*
16d80 32 5d 3b 0a 20 20 70 2d 3e 7a 54 61 62 20 3d 20  2];.  p->zTab = 
16d90 28 63 68 61 72 2a 29 26 70 2d 3e 61 62 50 4b 5b  (char*)&p->abPK[
16da0 70 2d 3e 6e 43 6f 6c 5d 3b 0a 20 20 72 65 74 75  p->nCol];.  retu
16db0 72 6e 20 28 70 2d 3e 72 63 20 3d 20 72 63 29 3b  rn (p->rc = rc);
16dc0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63  .}../*.** Advanc
16dd0 65 20 74 68 65 20 63 68 61 6e 67 65 73 65 74 20  e the changeset 
16de0 69 74 65 72 61 74 6f 72 20 74 6f 20 74 68 65 20  iterator to the 
16df0 6e 65 78 74 20 63 68 61 6e 67 65 2e 0a 2a 2a 0a  next change..**.
16e00 2a 2a 20 49 66 20 62 6f 74 68 20 70 61 52 65 63  ** If both paRec
16e10 20 61 6e 64 20 70 6e 52 65 63 20 61 72 65 20 4e   and pnRec are N
16e20 55 4c 4c 2c 20 74 68 65 6e 20 74 68 69 73 20 66  ULL, then this f
16e30 75 6e 63 74 69 6f 6e 20 77 6f 72 6b 73 20 6c 69  unction works li
16e40 6b 65 20 74 68 65 20 70 75 62 6c 69 63 0a 2a 2a  ke the public.**
16e50 20 41 50 49 20 73 71 6c 69 74 65 33 63 68 61 6e   API sqlite3chan
16e60 67 65 73 65 74 5f 6e 65 78 74 28 29 2e 20 49 66  geset_next(). If
16e70 20 53 51 4c 49 54 45 5f 52 4f 57 20 69 73 20 72   SQLITE_ROW is r
16e80 65 74 75 72 6e 65 64 2c 20 74 68 65 6e 20 74 68  eturned, then th
16e90 65 0a 2a 2a 20 73 71 6c 69 74 65 33 63 68 61 6e  e.** sqlite3chan
16ea0 67 65 73 65 74 5f 6e 65 77 28 29 20 61 6e 64 20  geset_new() and 
16eb0 6f 6c 64 28 29 20 41 50 49 73 20 6d 61 79 20 62  old() APIs may b
16ec0 65 20 75 73 65 64 20 74 6f 20 71 75 65 72 79 20  e used to query 
16ed0 66 6f 72 20 76 61 6c 75 65 73 2e 0a 2a 2a 0a 2a  for values..**.*
16ee0 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20  * Otherwise, if 
16ef0 70 61 52 65 63 20 61 6e 64 20 70 6e 52 65 63 20  paRec and pnRec 
16f00 61 72 65 20 6e 6f 74 20 4e 55 4c 4c 2c 20 74 68  are not NULL, th
16f10 65 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20  en a pointer to 
16f20 74 68 65 20 63 68 61 6e 67 65 0a 2a 2a 20 72 65  the change.** re
16f30 63 6f 72 64 20 69 73 20 77 72 69 74 74 65 6e 20  cord is written 
16f40 74 6f 20 2a 70 61 52 65 63 20 62 65 66 6f 72 65  to *paRec before
16f50 20 72 65 74 75 72 6e 69 6e 67 20 61 6e 64 20 74   returning and t
16f60 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  he number of byt
16f70 65 73 20 69 6e 0a 2a 2a 20 74 68 65 20 72 65 63  es in.** the rec
16f80 6f 72 64 20 74 6f 20 2a 70 6e 52 65 63 2e 0a 2a  ord to *pnRec..*
16f90 2a 0a 2a 2a 20 45 69 74 68 65 72 20 77 61 79 2c  *.** Either way,
16fa0 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72   this function r
16fb0 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 52 4f  eturns SQLITE_RO
16fc0 57 20 69 66 20 74 68 65 20 69 74 65 72 61 74 6f  W if the iterato
16fd0 72 20 69 73 20 0a 2a 2a 20 73 75 63 63 65 73 73  r is .** success
16fe0 66 75 6c 6c 79 20 61 64 76 61 6e 63 65 64 20 74  fully advanced t
16ff0 6f 20 74 68 65 20 6e 65 78 74 20 63 68 61 6e 67  o the next chang
17000 65 20 69 6e 20 74 68 65 20 63 68 61 6e 67 65 73  e in the changes
17010 65 74 2c 20 61 6e 20 53 51 4c 69 74 65 20 0a 2a  et, an SQLite .*
17020 2a 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20  * error code if 
17030 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c  an error occurs,
17040 20 6f 72 20 53 51 4c 49 54 45 5f 44 4f 4e 45 20   or SQLITE_DONE 
17050 69 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20  if there are no 
17060 66 75 72 74 68 65 72 20 0a 2a 2a 20 63 68 61 6e  further .** chan
17070 67 65 73 20 69 6e 20 74 68 65 20 63 68 61 6e 67  ges in the chang
17080 65 73 65 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  eset..*/.static 
17090 69 6e 74 20 73 65 73 73 69 6f 6e 43 68 61 6e 67  int sessionChang
170a0 65 73 65 74 4e 65 78 74 28 0a 20 20 73 71 6c 69  esetNext(.  sqli
170b0 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74  te3_changeset_it
170c0 65 72 20 2a 70 2c 20 20 20 20 20 20 2f 2a 20 43  er *p,      /* C
170d0 68 61 6e 67 65 73 65 74 20 69 74 65 72 61 74 6f  hangeset iterato
170e0 72 20 2a 2f 0a 20 20 75 38 20 2a 2a 70 61 52 65  r */.  u8 **paRe
170f0 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c,              
17100 20 20 20 20 20 20 20 2f 2a 20 49 66 20 6e 6f 6e         /* If non
17110 2d 4e 55 4c 4c 2c 20 73 74 6f 72 65 20 72 65 63  -NULL, store rec
17120 6f 72 64 20 70 6f 69 6e 74 65 72 20 68 65 72 65  ord pointer here
17130 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 52 65 63   */.  int *pnRec
17140 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17150 20 20 20 20 20 20 2f 2a 20 49 66 20 6e 6f 6e 2d        /* If non-
17160 4e 55 4c 4c 2c 20 73 74 6f 72 65 20 73 69 7a 65  NULL, store size
17170 20 6f 66 20 72 65 63 6f 72 64 20 68 65 72 65 20   of record here 
17180 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  */.){.  int i;. 
17190 20 75 38 20 6f 70 3b 0a 0a 20 20 61 73 73 65 72   u8 op;..  asser
171a0 74 28 20 28 70 61 52 65 63 3d 3d 30 20 26 26 20  t( (paRec==0 && 
171b0 70 6e 52 65 63 3d 3d 30 29 20 7c 7c 20 28 70 61  pnRec==0) || (pa
171c0 52 65 63 20 26 26 20 70 6e 52 65 63 29 20 29 3b  Rec && pnRec) );
171d0 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 69 74  ..  /* If the it
171e0 65 72 61 74 6f 72 20 69 73 20 69 6e 20 74 68 65  erator is in the
171f0 20 65 72 72 6f 72 2d 73 74 61 74 65 2c 20 72 65   error-state, re
17200 74 75 72 6e 20 69 6d 6d 65 64 69 61 74 65 6c 79  turn immediately
17210 2e 20 2a 2f 0a 20 20 69 66 28 20 70 2d 3e 72 63  . */.  if( p->rc
17220 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
17230 74 75 72 6e 20 70 2d 3e 72 63 3b 0a 0a 20 20 2f  turn p->rc;..  /
17240 2a 20 46 72 65 65 20 74 68 65 20 63 75 72 72 65  * Free the curre
17250 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 70  nt contents of p
17260 2d 3e 61 70 56 61 6c 75 65 5b 5d 2c 20 69 66 20  ->apValue[], if 
17270 61 6e 79 2e 20 2a 2f 0a 20 20 69 66 28 20 70 2d  any. */.  if( p-
17280 3e 61 70 56 61 6c 75 65 20 29 7b 0a 20 20 20 20  >apValue ){.    
17290 66 6f 72 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 43  for(i=0; i<p->nC
172a0 6f 6c 2a 32 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  ol*2; i++){.    
172b0 20 20 73 71 6c 69 74 65 33 56 61 6c 75 65 46 72    sqlite3ValueFr
172c0 65 65 28 70 2d 3e 61 70 56 61 6c 75 65 5b 69 5d  ee(p->apValue[i]
172d0 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d  );.    }.    mem
172e0 73 65 74 28 70 2d 3e 61 70 56 61 6c 75 65 2c 20  set(p->apValue, 
172f0 30 2c 20 73 69 7a 65 6f 66 28 73 71 6c 69 74 65  0, sizeof(sqlite
17300 33 5f 76 61 6c 75 65 2a 29 2a 70 2d 3e 6e 43 6f  3_value*)*p->nCo
17310 6c 2a 32 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  l*2);.  }..  /* 
17320 4d 61 6b 65 20 73 75 72 65 20 74 68 65 20 62 75  Make sure the bu
17330 66 66 65 72 20 63 6f 6e 74 61 69 6e 73 20 61 74  ffer contains at
17340 20 6c 65 61 73 74 20 31 30 20 62 79 74 65 73 20   least 10 bytes 
17350 6f 66 20 69 6e 70 75 74 20 64 61 74 61 2c 20 6f  of input data, o
17360 72 20 61 6c 6c 0a 20 20 2a 2a 20 72 65 6d 61 69  r all.  ** remai
17370 6e 69 6e 67 20 64 61 74 61 20 69 66 20 74 68 65  ning data if the
17380 72 65 20 61 72 65 20 6c 65 73 73 20 74 68 61 6e  re are less than
17390 20 31 30 20 62 79 74 65 73 20 61 76 61 69 6c 61   10 bytes availa
173a0 62 6c 65 2e 20 54 68 69 73 20 69 73 0a 20 20 2a  ble. This is.  *
173b0 2a 20 73 75 66 66 69 63 69 65 6e 74 20 65 69 74  * sufficient eit
173c0 68 65 72 20 66 6f 72 20 74 68 65 20 27 54 27 20  her for the 'T' 
173d0 6f 72 20 27 50 27 20 62 79 74 65 20 61 6e 64 20  or 'P' byte and 
173e0 74 68 65 20 76 61 72 69 6e 74 20 74 68 61 74 20  the varint that 
173f0 66 6f 6c 6c 6f 77 73 0a 20 20 2a 2a 20 69 74 2c  follows.  ** it,
17400 20 6f 72 20 66 6f 72 20 74 68 65 20 74 77 6f 20   or for the two 
17410 73 69 6e 67 6c 65 20 62 79 74 65 20 76 61 6c 75  single byte valu
17420 65 73 20 6f 74 68 65 72 77 69 73 65 2e 20 2a 2f  es otherwise. */
17430 0a 20 20 70 2d 3e 72 63 20 3d 20 73 65 73 73 69  .  p->rc = sessi
17440 6f 6e 49 6e 70 75 74 42 75 66 66 65 72 28 26 70  onInputBuffer(&p
17450 2d 3e 69 6e 2c 20 32 29 3b 0a 20 20 69 66 28 20  ->in, 2);.  if( 
17460 70 2d 3e 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  p->rc!=SQLITE_OK
17470 20 29 20 72 65 74 75 72 6e 20 70 2d 3e 72 63 3b   ) return p->rc;
17480 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 69 74  ..  /* If the it
17490 65 72 61 74 6f 72 20 69 73 20 61 6c 72 65 61 64  erator is alread
174a0 79 20 61 74 20 74 68 65 20 65 6e 64 20 6f 66 20  y at the end of 
174b0 74 68 65 20 63 68 61 6e 67 65 73 65 74 2c 20 72  the changeset, r
174c0 65 74 75 72 6e 20 44 4f 4e 45 2e 20 2a 2f 0a 20  eturn DONE. */. 
174d0 20 69 66 28 20 70 2d 3e 69 6e 2e 69 4e 65 78 74   if( p->in.iNext
174e0 3e 3d 70 2d 3e 69 6e 2e 6e 44 61 74 61 20 29 7b  >=p->in.nData ){
174f0 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
17500 54 45 5f 44 4f 4e 45 3b 0a 20 20 7d 0a 0a 20 20  TE_DONE;.  }..  
17510 73 65 73 73 69 6f 6e 44 69 73 63 61 72 64 44 61  sessionDiscardDa
17520 74 61 28 26 70 2d 3e 69 6e 29 3b 0a 20 20 70 2d  ta(&p->in);.  p-
17530 3e 69 6e 2e 69 43 75 72 72 65 6e 74 20 3d 20 70  >in.iCurrent = p
17540 2d 3e 69 6e 2e 69 4e 65 78 74 3b 0a 0a 20 20 6f  ->in.iNext;..  o
17550 70 20 3d 20 70 2d 3e 69 6e 2e 61 44 61 74 61 5b  p = p->in.aData[
17560 70 2d 3e 69 6e 2e 69 4e 65 78 74 2b 2b 5d 3b 0a  p->in.iNext++];.
17570 20 20 77 68 69 6c 65 28 20 6f 70 3d 3d 27 54 27    while( op=='T'
17580 20 7c 7c 20 6f 70 3d 3d 27 50 27 20 29 7b 0a 20   || op=='P' ){. 
17590 20 20 20 70 2d 3e 62 50 61 74 63 68 73 65 74 20     p->bPatchset 
175a0 3d 20 28 6f 70 3d 3d 27 50 27 29 3b 0a 20 20 20  = (op=='P');.   
175b0 20 69 66 28 20 73 65 73 73 69 6f 6e 43 68 61 6e   if( sessionChan
175c0 67 65 73 65 74 52 65 61 64 54 62 6c 68 64 72 28  gesetReadTblhdr(
175d0 70 29 20 29 20 72 65 74 75 72 6e 20 70 2d 3e 72  p) ) return p->r
175e0 63 3b 0a 20 20 20 20 69 66 28 20 28 70 2d 3e 72  c;.    if( (p->r
175f0 63 20 3d 20 73 65 73 73 69 6f 6e 49 6e 70 75 74  c = sessionInput
17600 42 75 66 66 65 72 28 26 70 2d 3e 69 6e 2c 20 32  Buffer(&p->in, 2
17610 29 29 20 29 20 72 65 74 75 72 6e 20 70 2d 3e 72  )) ) return p->r
17620 63 3b 0a 20 20 20 20 70 2d 3e 69 6e 2e 69 43 75  c;.    p->in.iCu
17630 72 72 65 6e 74 20 3d 20 70 2d 3e 69 6e 2e 69 4e  rrent = p->in.iN
17640 65 78 74 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e  ext;.    if( p->
17650 69 6e 2e 69 4e 65 78 74 3e 3d 70 2d 3e 69 6e 2e  in.iNext>=p->in.
17660 6e 44 61 74 61 20 29 20 72 65 74 75 72 6e 20 53  nData ) return S
17670 51 4c 49 54 45 5f 44 4f 4e 45 3b 0a 20 20 20 20  QLITE_DONE;.    
17680 6f 70 20 3d 20 70 2d 3e 69 6e 2e 61 44 61 74 61  op = p->in.aData
17690 5b 70 2d 3e 69 6e 2e 69 4e 65 78 74 2b 2b 5d 3b  [p->in.iNext++];
176a0 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 2d 3e 7a  .  }..  if( p->z
176b0 54 61 62 3d 3d 30 20 29 7b 0a 20 20 20 20 2f 2a  Tab==0 ){.    /*
176c0 20 54 68 65 20 66 69 72 73 74 20 72 65 63 6f 72   The first recor
176d0 64 20 69 6e 20 74 68 65 20 63 68 61 6e 67 65 73  d in the changes
176e0 65 74 20 69 73 20 6e 6f 74 20 61 20 74 61 62 6c  et is not a tabl
176f0 65 20 68 65 61 64 65 72 2e 20 4d 75 73 74 20 62  e header. Must b
17700 65 20 61 0a 20 20 20 20 2a 2a 20 63 6f 72 72 75  e a.    ** corru
17710 70 74 20 63 68 61 6e 67 65 73 65 74 2e 20 2a 2f  pt changeset. */
17720 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e  .    assert( p->
17730 69 6e 2e 69 4e 65 78 74 3d 3d 31 20 29 3b 0a 20  in.iNext==1 );. 
17740 20 20 20 72 65 74 75 72 6e 20 28 70 2d 3e 72 63     return (p->rc
17750 20 3d 20 53 51 4c 49 54 45 5f 43 4f 52 52 55 50   = SQLITE_CORRUP
17760 54 5f 42 4b 50 54 29 3b 0a 20 20 7d 0a 0a 20 20  T_BKPT);.  }..  
17770 70 2d 3e 6f 70 20 3d 20 6f 70 3b 0a 20 20 70 2d  p->op = op;.  p-
17780 3e 62 49 6e 64 69 72 65 63 74 20 3d 20 70 2d 3e  >bIndirect = p->
17790 69 6e 2e 61 44 61 74 61 5b 70 2d 3e 69 6e 2e 69  in.aData[p->in.i
177a0 4e 65 78 74 2b 2b 5d 3b 0a 20 20 69 66 28 20 70  Next++];.  if( p
177b0 2d 3e 6f 70 21 3d 53 51 4c 49 54 45 5f 55 50 44  ->op!=SQLITE_UPD
177c0 41 54 45 20 26 26 20 70 2d 3e 6f 70 21 3d 53 51  ATE && p->op!=SQ
177d0 4c 49 54 45 5f 44 45 4c 45 54 45 20 26 26 20 70  LITE_DELETE && p
177e0 2d 3e 6f 70 21 3d 53 51 4c 49 54 45 5f 49 4e 53  ->op!=SQLITE_INS
177f0 45 52 54 20 29 7b 0a 20 20 20 20 72 65 74 75 72  ERT ){.    retur
17800 6e 20 28 70 2d 3e 72 63 20 3d 20 53 51 4c 49 54  n (p->rc = SQLIT
17810 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54 29 3b  E_CORRUPT_BKPT);
17820 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 61 52 65  .  }..  if( paRe
17830 63 20 29 7b 20 0a 20 20 20 20 69 6e 74 20 6e 56  c ){ .    int nV
17840 61 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  al;             
17850 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
17860 72 20 6f 66 20 76 61 6c 75 65 73 20 74 6f 20 62  r of values to b
17870 75 66 66 65 72 20 2a 2f 0a 20 20 20 20 69 66 28  uffer */.    if(
17880 20 70 2d 3e 62 50 61 74 63 68 73 65 74 3d 3d 30   p->bPatchset==0
17890 20 26 26 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 55   && op==SQLITE_U
178a0 50 44 41 54 45 20 29 7b 0a 20 20 20 20 20 20 6e  PDATE ){.      n
178b0 56 61 6c 20 3d 20 70 2d 3e 6e 43 6f 6c 20 2a 20  Val = p->nCol * 
178c0 32 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  2;.    }else if(
178d0 20 70 2d 3e 62 50 61 74 63 68 73 65 74 20 26 26   p->bPatchset &&
178e0 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 44 45 4c 45   op==SQLITE_DELE
178f0 54 45 20 29 7b 0a 20 20 20 20 20 20 6e 56 61 6c  TE ){.      nVal
17900 20 3d 20 30 3b 0a 20 20 20 20 20 20 66 6f 72 28   = 0;.      for(
17910 69 3d 30 3b 20 69 3c 70 2d 3e 6e 43 6f 6c 3b 20  i=0; i<p->nCol; 
17920 69 2b 2b 29 20 69 66 28 20 70 2d 3e 61 62 50 4b  i++) if( p->abPK
17930 5b 69 5d 20 29 20 6e 56 61 6c 2b 2b 3b 0a 20 20  [i] ) nVal++;.  
17940 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6e    }else{.      n
17950 56 61 6c 20 3d 20 70 2d 3e 6e 43 6f 6c 3b 0a 20  Val = p->nCol;. 
17960 20 20 20 7d 0a 20 20 20 20 70 2d 3e 72 63 20 3d     }.    p->rc =
17970 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65   sessionChangese
17980 74 42 75 66 66 65 72 52 65 63 6f 72 64 28 26 70  tBufferRecord(&p
17990 2d 3e 69 6e 2c 20 6e 56 61 6c 2c 20 70 6e 52 65  ->in, nVal, pnRe
179a0 63 29 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 72  c);.    if( p->r
179b0 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
179c0 65 74 75 72 6e 20 70 2d 3e 72 63 3b 0a 20 20 20  eturn p->rc;.   
179d0 20 2a 70 61 52 65 63 20 3d 20 26 70 2d 3e 69 6e   *paRec = &p->in
179e0 2e 61 44 61 74 61 5b 70 2d 3e 69 6e 2e 69 4e 65  .aData[p->in.iNe
179f0 78 74 5d 3b 0a 20 20 20 20 70 2d 3e 69 6e 2e 69  xt];.    p->in.i
17a00 4e 65 78 74 20 2b 3d 20 2a 70 6e 52 65 63 3b 0a  Next += *pnRec;.
17a10 20 20 7d 65 6c 73 65 7b 0a 0a 20 20 20 20 2f 2a    }else{..    /*
17a20 20 49 66 20 74 68 69 73 20 69 73 20 61 6e 20 55   If this is an U
17a30 50 44 41 54 45 20 6f 72 20 44 45 4c 45 54 45 2c  PDATE or DELETE,
17a40 20 72 65 61 64 20 74 68 65 20 6f 6c 64 2e 2a 20   read the old.* 
17a50 72 65 63 6f 72 64 2e 20 2a 2f 0a 20 20 20 20 69  record. */.    i
17a60 66 28 20 70 2d 3e 6f 70 21 3d 53 51 4c 49 54 45  f( p->op!=SQLITE
17a70 5f 49 4e 53 45 52 54 20 26 26 20 28 70 2d 3e 62  _INSERT && (p->b
17a80 50 61 74 63 68 73 65 74 3d 3d 30 20 7c 7c 20 70  Patchset==0 || p
17a90 2d 3e 6f 70 3d 3d 53 51 4c 49 54 45 5f 44 45 4c  ->op==SQLITE_DEL
17aa0 45 54 45 29 20 29 7b 0a 20 20 20 20 20 20 75 38  ETE) ){.      u8
17ab0 20 2a 61 62 50 4b 20 3d 20 70 2d 3e 62 50 61 74   *abPK = p->bPat
17ac0 63 68 73 65 74 20 3f 20 70 2d 3e 61 62 50 4b 20  chset ? p->abPK 
17ad0 3a 20 30 3b 0a 20 20 20 20 20 20 70 2d 3e 72 63  : 0;.      p->rc
17ae0 20 3d 20 73 65 73 73 69 6f 6e 52 65 61 64 52 65   = sessionReadRe
17af0 63 6f 72 64 28 26 70 2d 3e 69 6e 2c 20 70 2d 3e  cord(&p->in, p->
17b00 6e 43 6f 6c 2c 20 61 62 50 4b 2c 20 70 2d 3e 61  nCol, abPK, p->a
17b10 70 56 61 6c 75 65 29 3b 0a 20 20 20 20 20 20 69  pValue);.      i
17b20 66 28 20 70 2d 3e 72 63 21 3d 53 51 4c 49 54 45  f( p->rc!=SQLITE
17b30 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 70 2d 3e  _OK ) return p->
17b40 72 63 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  rc;.    }..    /
17b50 2a 20 49 66 20 74 68 69 73 20 69 73 20 61 6e 20  * If this is an 
17b60 49 4e 53 45 52 54 20 6f 72 20 55 50 44 41 54 45  INSERT or UPDATE
17b70 2c 20 72 65 61 64 20 74 68 65 20 6e 65 77 2e 2a  , read the new.*
17b80 20 72 65 63 6f 72 64 2e 20 2a 2f 0a 20 20 20 20   record. */.    
17b90 69 66 28 20 70 2d 3e 6f 70 21 3d 53 51 4c 49 54  if( p->op!=SQLIT
17ba0 45 5f 44 45 4c 45 54 45 20 29 7b 0a 20 20 20 20  E_DELETE ){.    
17bb0 20 20 70 2d 3e 72 63 20 3d 20 73 65 73 73 69 6f    p->rc = sessio
17bc0 6e 52 65 61 64 52 65 63 6f 72 64 28 26 70 2d 3e  nReadRecord(&p->
17bd0 69 6e 2c 20 70 2d 3e 6e 43 6f 6c 2c 20 30 2c 20  in, p->nCol, 0, 
17be0 26 70 2d 3e 61 70 56 61 6c 75 65 5b 70 2d 3e 6e  &p->apValue[p->n
17bf0 43 6f 6c 5d 29 3b 0a 20 20 20 20 20 20 69 66 28  Col]);.      if(
17c00 20 70 2d 3e 72 63 21 3d 53 51 4c 49 54 45 5f 4f   p->rc!=SQLITE_O
17c10 4b 20 29 20 72 65 74 75 72 6e 20 70 2d 3e 72 63  K ) return p->rc
17c20 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  ;.    }..    if(
17c30 20 70 2d 3e 62 50 61 74 63 68 73 65 74 20 26 26   p->bPatchset &&
17c40 20 70 2d 3e 6f 70 3d 3d 53 51 4c 49 54 45 5f 55   p->op==SQLITE_U
17c50 50 44 41 54 45 20 29 7b 0a 20 20 20 20 20 20 2f  PDATE ){.      /
17c60 2a 20 49 66 20 74 68 69 73 20 69 73 20 61 6e 20  * If this is an 
17c70 55 50 44 41 54 45 20 74 68 61 74 20 69 73 20 70  UPDATE that is p
17c80 61 72 74 20 6f 66 20 61 20 70 61 74 63 68 73 65  art of a patchse
17c90 74 2c 20 74 68 65 6e 20 61 6c 6c 20 50 4b 20 61  t, then all PK a
17ca0 6e 64 0a 20 20 20 20 20 20 2a 2a 20 6d 6f 64 69  nd.      ** modi
17cb0 66 69 65 64 20 66 69 65 6c 64 73 20 61 72 65 20  fied fields are 
17cc0 70 72 65 73 65 6e 74 20 69 6e 20 74 68 65 20 6e  present in the n
17cd0 65 77 2e 2a 20 72 65 63 6f 72 64 2e 20 54 68 65  ew.* record. The
17ce0 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 0a 20 20   old.* record.  
17cf0 20 20 20 20 2a 2a 20 69 73 20 63 75 72 72 65 6e      ** is curren
17d00 74 6c 79 20 63 6f 6d 70 6c 65 74 65 6c 79 20 65  tly completely e
17d10 6d 70 74 79 2e 20 54 68 69 73 20 62 6c 6f 63 6b  mpty. This block
17d20 20 73 68 69 66 74 73 20 74 68 65 20 50 4b 20 66   shifts the PK f
17d30 69 65 6c 64 73 20 66 72 6f 6d 0a 20 20 20 20 20  ields from.     
17d40 20 2a 2a 20 6e 65 77 2e 2a 20 74 6f 20 6f 6c 64   ** new.* to old
17d50 2e 2a 2c 20 74 6f 20 61 63 63 6f 6d 6d 6f 64 61  .*, to accommoda
17d60 74 65 20 74 68 65 20 63 6f 64 65 20 74 68 61 74  te the code that
17d70 20 72 65 61 64 73 20 74 68 65 73 65 20 61 72 72   reads these arr
17d80 61 79 73 2e 20 20 2a 2f 0a 20 20 20 20 20 20 66  ays.  */.      f
17d90 6f 72 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 43 6f  or(i=0; i<p->nCo
17da0 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20  l; i++){.       
17db0 20 61 73 73 65 72 74 28 20 70 2d 3e 61 70 56 61   assert( p->apVa
17dc0 6c 75 65 5b 69 5d 3d 3d 30 20 29 3b 0a 20 20 20  lue[i]==0 );.   
17dd0 20 20 20 20 20 69 66 28 20 70 2d 3e 61 62 50 4b       if( p->abPK
17de0 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20 20 20 20  [i] ){.         
17df0 20 70 2d 3e 61 70 56 61 6c 75 65 5b 69 5d 20 3d   p->apValue[i] =
17e00 20 70 2d 3e 61 70 56 61 6c 75 65 5b 69 2b 70 2d   p->apValue[i+p-
17e10 3e 6e 43 6f 6c 5d 3b 0a 20 20 20 20 20 20 20 20  >nCol];.        
17e20 20 20 69 66 28 20 70 2d 3e 61 70 56 61 6c 75 65    if( p->apValue
17e30 5b 69 5d 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  [i]==0 ) return 
17e40 28 70 2d 3e 72 63 20 3d 20 53 51 4c 49 54 45 5f  (p->rc = SQLITE_
17e50 43 4f 52 52 55 50 54 5f 42 4b 50 54 29 3b 0a 20  CORRUPT_BKPT);. 
17e60 20 20 20 20 20 20 20 20 20 70 2d 3e 61 70 56 61           p->apVa
17e70 6c 75 65 5b 69 2b 70 2d 3e 6e 43 6f 6c 5d 20 3d  lue[i+p->nCol] =
17e80 20 30 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20   0;.        }.  
17e90 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
17ea0 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
17eb0 5f 52 4f 57 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  _ROW;.}../*.** A
17ec0 64 76 61 6e 63 65 20 61 6e 20 69 74 65 72 61 74  dvance an iterat
17ed0 6f 72 20 63 72 65 61 74 65 64 20 62 79 20 73 71  or created by sq
17ee0 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 73  lite3changeset_s
17ef0 74 61 72 74 28 29 20 74 6f 20 74 68 65 20 6e 65  tart() to the ne
17f00 78 74 0a 2a 2a 20 63 68 61 6e 67 65 20 69 6e 20  xt.** change in 
17f10 74 68 65 20 63 68 61 6e 67 65 73 65 74 2e 20 54  the changeset. T
17f20 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 6d 61 79  his function may
17f30 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 52   return SQLITE_R
17f40 4f 57 2c 20 53 51 4c 49 54 45 5f 44 4f 4e 45 0a  OW, SQLITE_DONE.
17f50 2a 2a 20 6f 72 20 53 51 4c 49 54 45 5f 43 4f 52  ** or SQLITE_COR
17f60 52 55 50 54 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  RUPT..**.** This
17f70 20 66 75 6e 63 74 69 6f 6e 20 6d 61 79 20 6e 6f   function may no
17f80 74 20 62 65 20 63 61 6c 6c 65 64 20 6f 6e 20 69  t be called on i
17f90 74 65 72 61 74 6f 72 73 20 70 61 73 73 65 64 20  terators passed 
17fa0 74 6f 20 61 20 63 6f 6e 66 6c 69 63 74 20 68 61  to a conflict ha
17fb0 6e 64 6c 65 72 0a 2a 2a 20 63 61 6c 6c 62 61 63  ndler.** callbac
17fc0 6b 20 62 79 20 63 68 61 6e 67 65 73 65 74 5f 61  k by changeset_a
17fd0 70 70 6c 79 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73  pply()..*/.int s
17fe0 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
17ff0 6e 65 78 74 28 73 71 6c 69 74 65 33 5f 63 68 61  next(sqlite3_cha
18000 6e 67 65 73 65 74 5f 69 74 65 72 20 2a 70 29 7b  ngeset_iter *p){
18010 0a 20 20 72 65 74 75 72 6e 20 73 65 73 73 69 6f  .  return sessio
18020 6e 43 68 61 6e 67 65 73 65 74 4e 65 78 74 28 70  nChangesetNext(p
18030 2c 20 30 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  , 0, 0);.}../*.*
18040 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  * The following 
18050 66 75 6e 63 74 69 6f 6e 20 65 78 74 72 61 63 74  function extract
18060 73 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 6f 6e  s information on
18070 20 74 68 65 20 63 75 72 72 65 6e 74 20 63 68 61   the current cha
18080 6e 67 65 0a 2a 2a 20 66 72 6f 6d 20 61 20 63 68  nge.** from a ch
18090 61 6e 67 65 73 65 74 20 69 74 65 72 61 74 6f 72  angeset iterator
180a0 2e 20 49 74 20 6d 61 79 20 6f 6e 6c 79 20 62 65  . It may only be
180b0 20 63 61 6c 6c 65 64 20 61 66 74 65 72 20 63 68   called after ch
180c0 61 6e 67 65 73 65 74 5f 6e 65 78 74 28 29 0a 2a  angeset_next().*
180d0 2a 20 68 61 73 20 72 65 74 75 72 6e 65 64 20 53  * has returned S
180e0 51 4c 49 54 45 5f 52 4f 57 2e 0a 2a 2f 0a 69 6e  QLITE_ROW..*/.in
180f0 74 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  t sqlite3changes
18100 65 74 5f 6f 70 28 0a 20 20 73 71 6c 69 74 65 33  et_op(.  sqlite3
18110 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20  _changeset_iter 
18120 2a 70 49 74 65 72 2c 20 20 2f 2a 20 49 74 65 72  *pIter,  /* Iter
18130 61 74 6f 72 20 68 61 6e 64 6c 65 20 2a 2f 0a 20  ator handle */. 
18140 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 70 7a   const char **pz
18150 54 61 62 2c 20 20 20 20 20 20 20 20 20 20 20 20  Tab,            
18160 20 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72   /* OUT: Pointer
18170 20 74 6f 20 74 61 62 6c 65 20 6e 61 6d 65 20 2a   to table name *
18180 2f 0a 20 20 69 6e 74 20 2a 70 6e 43 6f 6c 2c 20  /.  int *pnCol, 
18190 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
181a0 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d 62      /* OUT: Numb
181b0 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e  er of columns in
181c0 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20   table */.  int 
181d0 2a 70 4f 70 2c 20 20 20 20 20 20 20 20 20 20 20  *pOp,           
181e0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
181f0 55 54 3a 20 53 51 4c 49 54 45 5f 49 4e 53 45 52  UT: SQLITE_INSER
18200 54 2c 20 44 45 4c 45 54 45 20 6f 72 20 55 50 44  T, DELETE or UPD
18210 41 54 45 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 62  ATE */.  int *pb
18220 49 6e 64 69 72 65 63 74 20 20 20 20 20 20 20 20  Indirect        
18230 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
18240 20 54 72 75 65 20 69 66 20 63 68 61 6e 67 65 20   True if change 
18250 69 73 20 69 6e 64 69 72 65 63 74 20 2a 2f 0a 29  is indirect */.)
18260 7b 0a 20 20 2a 70 4f 70 20 3d 20 70 49 74 65 72  {.  *pOp = pIter
18270 2d 3e 6f 70 3b 0a 20 20 2a 70 6e 43 6f 6c 20 3d  ->op;.  *pnCol =
18280 20 70 49 74 65 72 2d 3e 6e 43 6f 6c 3b 0a 20 20   pIter->nCol;.  
18290 2a 70 7a 54 61 62 20 3d 20 70 49 74 65 72 2d 3e  *pzTab = pIter->
182a0 7a 54 61 62 3b 0a 20 20 69 66 28 20 70 62 49 6e  zTab;.  if( pbIn
182b0 64 69 72 65 63 74 20 29 20 2a 70 62 49 6e 64 69  direct ) *pbIndi
182c0 72 65 63 74 20 3d 20 70 49 74 65 72 2d 3e 62 49  rect = pIter->bI
182d0 6e 64 69 72 65 63 74 3b 0a 20 20 72 65 74 75 72  ndirect;.  retur
182e0 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
182f0 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 69 6e 66  /*.** Return inf
18300 6f 72 6d 61 74 69 6f 6e 20 72 65 67 61 72 64 69  ormation regardi
18310 6e 67 20 74 68 65 20 50 52 49 4d 41 52 59 20 4b  ng the PRIMARY K
18320 45 59 20 61 6e 64 20 6e 75 6d 62 65 72 20 6f 66  EY and number of
18330 20 63 6f 6c 75 6d 6e 73 20 69 6e 0a 2a 2a 20 74   columns in.** t
18340 68 65 20 64 61 74 61 62 61 73 65 20 74 61 62 6c  he database tabl
18350 65 20 61 66 66 65 63 74 65 64 20 62 79 20 74 68  e affected by th
18360 65 20 63 68 61 6e 67 65 20 74 68 61 74 20 70 49  e change that pI
18370 74 65 72 20 63 75 72 72 65 6e 74 6c 79 20 70 6f  ter currently po
18380 69 6e 74 73 0a 2a 2a 20 74 6f 2e 20 54 68 69 73  ints.** to. This
18390 20 66 75 6e 63 74 69 6f 6e 20 6d 61 79 20 6f 6e   function may on
183a0 6c 79 20 62 65 20 63 61 6c 6c 65 64 20 61 66 74  ly be called aft
183b0 65 72 20 63 68 61 6e 67 65 73 65 74 5f 6e 65 78  er changeset_nex
183c0 74 28 29 20 72 65 74 75 72 6e 73 0a 2a 2a 20 53  t() returns.** S
183d0 51 4c 49 54 45 5f 52 4f 57 2e 0a 2a 2f 0a 69 6e  QLITE_ROW..*/.in
183e0 74 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  t sqlite3changes
183f0 65 74 5f 70 6b 28 0a 20 20 73 71 6c 69 74 65 33  et_pk(.  sqlite3
18400 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20  _changeset_iter 
18410 2a 70 49 74 65 72 2c 20 20 2f 2a 20 49 74 65 72  *pIter,  /* Iter
18420 61 74 6f 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20  ator object */. 
18430 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a   unsigned char *
18440 2a 70 61 62 50 4b 2c 20 20 20 20 20 20 20 20 20  *pabPK,         
18450 20 2f 2a 20 4f 55 54 3a 20 41 72 72 61 79 20 6f   /* OUT: Array o
18460 66 20 62 6f 6f 6c 65 61 6e 20 2d 20 74 72 75 65  f boolean - true
18470 20 66 6f 72 20 50 4b 20 63 6f 6c 73 20 2a 2f 0a   for PK cols */.
18480 20 20 69 6e 74 20 2a 70 6e 43 6f 6c 20 20 20 20    int *pnCol    
18490 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
184a0 20 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d 62 65 72    /* OUT: Number
184b0 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20 6f   of entries in o
184c0 75 74 70 75 74 20 61 72 72 61 79 20 2a 2f 0a 29  utput array */.)
184d0 7b 0a 20 20 2a 70 61 62 50 4b 20 3d 20 70 49 74  {.  *pabPK = pIt
184e0 65 72 2d 3e 61 62 50 4b 3b 0a 20 20 69 66 28 20  er->abPK;.  if( 
184f0 70 6e 43 6f 6c 20 29 20 2a 70 6e 43 6f 6c 20 3d  pnCol ) *pnCol =
18500 20 70 49 74 65 72 2d 3e 6e 43 6f 6c 3b 0a 20 20   pIter->nCol;.  
18510 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
18520 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
18530 66 75 6e 63 74 69 6f 6e 20 6d 61 79 20 6f 6e 6c  function may onl
18540 79 20 62 65 20 63 61 6c 6c 65 64 20 77 68 69 6c  y be called whil
18550 65 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 69  e the iterator i
18560 73 20 70 6f 69 6e 74 69 6e 67 20 74 6f 20 61 6e  s pointing to an
18570 0a 2a 2a 20 53 51 4c 49 54 45 5f 55 50 44 41 54  .** SQLITE_UPDAT
18580 45 20 6f 72 20 53 51 4c 49 54 45 5f 44 45 4c 45  E or SQLITE_DELE
18590 54 45 20 63 68 61 6e 67 65 20 28 73 65 65 20 73  TE change (see s
185a0 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
185b0 6f 70 28 29 29 2e 0a 2a 2a 20 4f 74 68 65 72 77  op())..** Otherw
185c0 69 73 65 2c 20 53 51 4c 49 54 45 5f 4d 49 53 55  ise, SQLITE_MISU
185d0 53 45 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a  SE is returned..
185e0 2a 2a 0a 2a 2a 20 49 74 20 73 65 74 73 20 2a 70  **.** It sets *p
185f0 70 56 61 6c 75 65 20 74 6f 20 70 6f 69 6e 74 20  pValue to point 
18600 74 6f 20 61 6e 20 73 71 6c 69 74 65 33 5f 76 61  to an sqlite3_va
18610 6c 75 65 20 73 74 72 75 63 74 75 72 65 20 63 6f  lue structure co
18620 6e 74 61 69 6e 69 6e 67 20 74 68 65 0a 2a 2a 20  ntaining the.** 
18630 69 56 61 6c 27 74 68 20 76 61 6c 75 65 20 69 6e  iVal'th value in
18640 20 74 68 65 20 6f 6c 64 2e 2a 20 72 65 63 6f 72   the old.* recor
18650 64 2e 20 4f 72 2c 20 69 66 20 74 68 61 74 20 70  d. Or, if that p
18660 61 72 74 69 63 75 6c 61 72 20 76 61 6c 75 65 20  articular value 
18670 69 73 20 6e 6f 74 0a 2a 2a 20 69 6e 63 6c 75 64  is not.** includ
18680 65 64 20 69 6e 20 74 68 65 20 72 65 63 6f 72 64  ed in the record
18690 20 28 62 65 63 61 75 73 65 20 74 68 65 20 63 68   (because the ch
186a0 61 6e 67 65 20 69 73 20 61 6e 20 55 50 44 41 54  ange is an UPDAT
186b0 45 20 61 6e 64 20 74 68 65 20 66 69 65 6c 64 0a  E and the field.
186c0 2a 2a 20 77 61 73 20 6e 6f 74 20 6d 6f 64 69 66  ** was not modif
186d0 69 65 64 20 61 6e 64 20 69 73 20 6e 6f 74 20 61  ied and is not a
186e0 20 50 4b 20 63 6f 6c 75 6d 6e 29 2c 20 73 65 74   PK column), set
186f0 20 2a 70 70 56 61 6c 75 65 20 74 6f 20 4e 55 4c   *ppValue to NUL
18700 4c 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 76 61 6c 75  L..**.** If valu
18710 65 20 69 56 61 6c 20 69 73 20 6f 75 74 2d 6f 66  e iVal is out-of
18720 2d 72 61 6e 67 65 2c 20 53 51 4c 49 54 45 5f 52  -range, SQLITE_R
18730 41 4e 47 45 20 69 73 20 72 65 74 75 72 6e 65 64  ANGE is returned
18740 20 61 6e 64 20 2a 70 70 56 61 6c 75 65 20 69 73   and *ppValue is
18750 0a 2a 2a 20 6e 6f 74 20 6d 6f 64 69 66 69 65 64  .** not modified
18760 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 53 51 4c  . Otherwise, SQL
18770 49 54 45 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74 20 73  ITE_OK..*/.int s
18780 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
18790 6f 6c 64 28 0a 20 20 73 71 6c 69 74 65 33 5f 63  old(.  sqlite3_c
187a0 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a 70  hangeset_iter *p
187b0 49 74 65 72 2c 20 20 2f 2a 20 43 68 61 6e 67 65  Iter,  /* Change
187c0 73 65 74 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a  set iterator */.
187d0 20 20 69 6e 74 20 69 56 61 6c 2c 20 20 20 20 20    int iVal,     
187e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
187f0 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6f 6c    /* Index of ol
18800 64 2e 2a 20 76 61 6c 75 65 20 74 6f 20 72 65 74  d.* value to ret
18810 72 69 65 76 65 20 2a 2f 0a 20 20 73 71 6c 69 74  rieve */.  sqlit
18820 65 33 5f 76 61 6c 75 65 20 2a 2a 70 70 56 61 6c  e3_value **ppVal
18830 75 65 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55  ue         /* OU
18840 54 3a 20 4f 6c 64 20 76 61 6c 75 65 20 28 6f 72  T: Old value (or
18850 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 29 20 2a   NULL pointer) *
18860 2f 0a 29 7b 0a 20 20 69 66 28 20 70 49 74 65 72  /.){.  if( pIter
18870 2d 3e 6f 70 21 3d 53 51 4c 49 54 45 5f 55 50 44  ->op!=SQLITE_UPD
18880 41 54 45 20 26 26 20 70 49 74 65 72 2d 3e 6f 70  ATE && pIter->op
18890 21 3d 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 20  !=SQLITE_DELETE 
188a0 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
188b0 4c 49 54 45 5f 4d 49 53 55 53 45 3b 0a 20 20 7d  LITE_MISUSE;.  }
188c0 0a 20 20 69 66 28 20 69 56 61 6c 3c 30 20 7c 7c  .  if( iVal<0 ||
188d0 20 69 56 61 6c 3e 3d 70 49 74 65 72 2d 3e 6e 43   iVal>=pIter->nC
188e0 6f 6c 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  ol ){.    return
188f0 20 53 51 4c 49 54 45 5f 52 41 4e 47 45 3b 0a 20   SQLITE_RANGE;. 
18900 20 7d 0a 20 20 2a 70 70 56 61 6c 75 65 20 3d 20   }.  *ppValue = 
18910 70 49 74 65 72 2d 3e 61 70 56 61 6c 75 65 5b 69  pIter->apValue[i
18920 56 61 6c 5d 3b 0a 20 20 72 65 74 75 72 6e 20 53  Val];.  return S
18930 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
18940 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
18950 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 63 61 6c   may only be cal
18960 6c 65 64 20 77 68 69 6c 65 20 74 68 65 20 69 74  led while the it
18970 65 72 61 74 6f 72 20 69 73 20 70 6f 69 6e 74 69  erator is pointi
18980 6e 67 20 74 6f 20 61 6e 0a 2a 2a 20 53 51 4c 49  ng to an.** SQLI
18990 54 45 5f 55 50 44 41 54 45 20 6f 72 20 53 51 4c  TE_UPDATE or SQL
189a0 49 54 45 5f 49 4e 53 45 52 54 20 63 68 61 6e 67  ITE_INSERT chang
189b0 65 20 28 73 65 65 20 73 71 6c 69 74 65 33 63 68  e (see sqlite3ch
189c0 61 6e 67 65 73 65 74 5f 6f 70 28 29 29 2e 0a 2a  angeset_op())..*
189d0 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 53 51 4c  * Otherwise, SQL
189e0 49 54 45 5f 4d 49 53 55 53 45 20 69 73 20 72 65  ITE_MISUSE is re
189f0 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 74  turned..**.** It
18a00 20 73 65 74 73 20 2a 70 70 56 61 6c 75 65 20 74   sets *ppValue t
18a10 6f 20 70 6f 69 6e 74 20 74 6f 20 61 6e 20 73 71  o point to an sq
18a20 6c 69 74 65 33 5f 76 61 6c 75 65 20 73 74 72 75  lite3_value stru
18a30 63 74 75 72 65 20 63 6f 6e 74 61 69 6e 69 6e 67  cture containing
18a40 20 74 68 65 0a 2a 2a 20 69 56 61 6c 27 74 68 20   the.** iVal'th 
18a50 76 61 6c 75 65 20 69 6e 20 74 68 65 20 6e 65 77  value in the new
18a60 2e 2a 20 72 65 63 6f 72 64 2e 20 4f 72 2c 20 69  .* record. Or, i
18a70 66 20 74 68 61 74 20 70 61 72 74 69 63 75 6c 61  f that particula
18a80 72 20 76 61 6c 75 65 20 69 73 20 6e 6f 74 0a 2a  r value is not.*
18a90 2a 20 69 6e 63 6c 75 64 65 64 20 69 6e 20 74 68  * included in th
18aa0 65 20 72 65 63 6f 72 64 20 28 62 65 63 61 75 73  e record (becaus
18ab0 65 20 74 68 65 20 63 68 61 6e 67 65 20 69 73 20  e the change is 
18ac0 61 6e 20 55 50 44 41 54 45 20 61 6e 64 20 74 68  an UPDATE and th
18ad0 65 20 66 69 65 6c 64 0a 2a 2a 20 77 61 73 20 6e  e field.** was n
18ae0 6f 74 20 6d 6f 64 69 66 69 65 64 29 2c 20 73 65  ot modified), se
18af0 74 20 2a 70 70 56 61 6c 75 65 20 74 6f 20 4e 55  t *ppValue to NU
18b00 4c 4c 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 76 61 6c  LL..**.** If val
18b10 75 65 20 69 56 61 6c 20 69 73 20 6f 75 74 2d 6f  ue iVal is out-o
18b20 66 2d 72 61 6e 67 65 2c 20 53 51 4c 49 54 45 5f  f-range, SQLITE_
18b30 52 41 4e 47 45 20 69 73 20 72 65 74 75 72 6e 65  RANGE is returne
18b40 64 20 61 6e 64 20 2a 70 70 56 61 6c 75 65 20 69  d and *ppValue i
18b50 73 0a 2a 2a 20 6e 6f 74 20 6d 6f 64 69 66 69 65  s.** not modifie
18b60 64 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 53 51  d. Otherwise, SQ
18b70 4c 49 54 45 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74 20  LITE_OK..*/.int 
18b80 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
18b90 5f 6e 65 77 28 0a 20 20 73 71 6c 69 74 65 33 5f  _new(.  sqlite3_
18ba0 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a  changeset_iter *
18bb0 70 49 74 65 72 2c 20 20 2f 2a 20 43 68 61 6e 67  pIter,  /* Chang
18bc0 65 73 65 74 20 69 74 65 72 61 74 6f 72 20 2a 2f  eset iterator */
18bd0 0a 20 20 69 6e 74 20 69 56 61 6c 2c 20 20 20 20  .  int iVal,    
18be0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18bf0 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6e     /* Index of n
18c00 65 77 2e 2a 20 76 61 6c 75 65 20 74 6f 20 72 65  ew.* value to re
18c10 74 72 69 65 76 65 20 2a 2f 0a 20 20 73 71 6c 69  trieve */.  sqli
18c20 74 65 33 5f 76 61 6c 75 65 20 2a 2a 70 70 56 61  te3_value **ppVa
18c30 6c 75 65 20 20 20 20 20 20 20 20 20 2f 2a 20 4f  lue         /* O
18c40 55 54 3a 20 4e 65 77 20 76 61 6c 75 65 20 28 6f  UT: New value (o
18c50 72 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 29 20  r NULL pointer) 
18c60 2a 2f 0a 29 7b 0a 20 20 69 66 28 20 70 49 74 65  */.){.  if( pIte
18c70 72 2d 3e 6f 70 21 3d 53 51 4c 49 54 45 5f 55 50  r->op!=SQLITE_UP
18c80 44 41 54 45 20 26 26 20 70 49 74 65 72 2d 3e 6f  DATE && pIter->o
18c90 70 21 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52 54  p!=SQLITE_INSERT
18ca0 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
18cb0 51 4c 49 54 45 5f 4d 49 53 55 53 45 3b 0a 20 20  QLITE_MISUSE;.  
18cc0 7d 0a 20 20 69 66 28 20 69 56 61 6c 3c 30 20 7c  }.  if( iVal<0 |
18cd0 7c 20 69 56 61 6c 3e 3d 70 49 74 65 72 2d 3e 6e  | iVal>=pIter->n
18ce0 43 6f 6c 20 29 7b 0a 20 20 20 20 72 65 74 75 72  Col ){.    retur
18cf0 6e 20 53 51 4c 49 54 45 5f 52 41 4e 47 45 3b 0a  n SQLITE_RANGE;.
18d00 20 20 7d 0a 20 20 2a 70 70 56 61 6c 75 65 20 3d    }.  *ppValue =
18d10 20 70 49 74 65 72 2d 3e 61 70 56 61 6c 75 65 5b   pIter->apValue[
18d20 70 49 74 65 72 2d 3e 6e 43 6f 6c 2b 69 56 61 6c  pIter->nCol+iVal
18d30 5d 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  ];.  return SQLI
18d40 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
18d50 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 77  The following tw
18d60 6f 20 6d 61 63 72 6f 73 20 61 72 65 20 75 73 65  o macros are use
18d70 64 20 69 6e 74 65 72 6e 61 6c 6c 79 2e 20 54 68  d internally. Th
18d80 65 79 20 61 72 65 20 73 69 6d 69 6c 61 72 20 74  ey are similar t
18d90 6f 20 74 68 65 0a 2a 2a 20 73 71 6c 69 74 65 33  o the.** sqlite3
18da0 63 68 61 6e 67 65 73 65 74 5f 6e 65 77 28 29 20  changeset_new() 
18db0 61 6e 64 20 73 71 6c 69 74 65 33 63 68 61 6e 67  and sqlite3chang
18dc0 65 73 65 74 5f 6f 6c 64 28 29 20 66 75 6e 63 74  eset_old() funct
18dd0 69 6f 6e 73 2c 20 65 78 63 65 70 74 20 74 68 61  ions, except tha
18de0 74 0a 2a 2a 20 74 68 65 79 20 6f 6d 69 74 20 61  t.** they omit a
18df0 6c 6c 20 65 72 72 6f 72 20 63 68 65 63 6b 69 6e  ll error checkin
18e00 67 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20 70  g and return a p
18e10 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 72 65  ointer to the re
18e20 71 75 65 73 74 65 64 20 76 61 6c 75 65 2e 0a 2a  quested value..*
18e30 2f 0a 23 64 65 66 69 6e 65 20 73 65 73 73 69 6f  /.#define sessio
18e40 6e 43 68 61 6e 67 65 73 65 74 4e 65 77 28 70 49  nChangesetNew(pI
18e50 74 65 72 2c 20 69 56 61 6c 29 20 28 70 49 74 65  ter, iVal) (pIte
18e60 72 29 2d 3e 61 70 56 61 6c 75 65 5b 28 70 49 74  r)->apValue[(pIt
18e70 65 72 29 2d 3e 6e 43 6f 6c 2b 28 69 56 61 6c 29  er)->nCol+(iVal)
18e80 5d 0a 23 64 65 66 69 6e 65 20 73 65 73 73 69 6f  ].#define sessio
18e90 6e 43 68 61 6e 67 65 73 65 74 4f 6c 64 28 70 49  nChangesetOld(pI
18ea0 74 65 72 2c 20 69 56 61 6c 29 20 28 70 49 74 65  ter, iVal) (pIte
18eb0 72 29 2d 3e 61 70 56 61 6c 75 65 5b 28 69 56 61  r)->apValue[(iVa
18ec0 6c 29 5d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  l)]../*.** This 
18ed0 66 75 6e 63 74 69 6f 6e 20 6d 61 79 20 6f 6e 6c  function may onl
18ee0 79 20 62 65 20 63 61 6c 6c 65 64 20 77 69 74 68  y be called with
18ef0 20 61 20 63 68 61 6e 67 65 73 65 74 20 69 74 65   a changeset ite
18f00 72 61 74 6f 72 20 74 68 61 74 20 68 61 73 20 62  rator that has b
18f10 65 65 6e 0a 2a 2a 20 70 61 73 73 65 64 20 74 6f  een.** passed to
18f20 20 61 6e 20 53 51 4c 49 54 45 5f 43 48 41 4e 47   an SQLITE_CHANG
18f30 45 53 45 54 5f 44 41 54 41 20 6f 72 20 53 51 4c  ESET_DATA or SQL
18f40 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 43 4f  ITE_CHANGESET_CO
18f50 4e 46 4c 49 43 54 20 0a 2a 2a 20 63 6f 6e 66 6c  NFLICT .** confl
18f60 69 63 74 2d 68 61 6e 64 6c 65 72 20 66 75 6e 63  ict-handler func
18f70 74 69 6f 6e 2e 20 4f 74 68 65 72 77 69 73 65 2c  tion. Otherwise,
18f80 20 53 51 4c 49 54 45 5f 4d 49 53 55 53 45 20 69   SQLITE_MISUSE i
18f90 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a  s returned..**.*
18fa0 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c  * If successful,
18fb0 20 2a 70 70 56 61 6c 75 65 20 69 73 20 73 65 74   *ppValue is set
18fc0 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 61 6e 20   to point to an 
18fd0 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 73 74  sqlite3_value st
18fe0 72 75 63 74 75 72 65 0a 2a 2a 20 63 6f 6e 74 61  ructure.** conta
18ff0 69 6e 69 6e 67 20 74 68 65 20 69 56 61 6c 27 74  ining the iVal't
19000 68 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 63  h value of the c
19010 6f 6e 66 6c 69 63 74 69 6e 67 20 72 65 63 6f 72  onflicting recor
19020 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 76 61 6c 75  d..**.** If valu
19030 65 20 69 56 61 6c 20 69 73 20 6f 75 74 2d 6f 66  e iVal is out-of
19040 2d 72 61 6e 67 65 20 6f 72 20 73 6f 6d 65 20 6f  -range or some o
19050 74 68 65 72 20 65 72 72 6f 72 20 6f 63 63 75 72  ther error occur
19060 73 2c 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  s, an SQLite err
19070 6f 72 0a 2a 2a 20 63 6f 64 65 20 69 73 20 72 65  or.** code is re
19080 74 75 72 6e 65 64 2e 20 4f 74 68 65 72 77 69 73  turned. Otherwis
19090 65 2c 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2f  e, SQLITE_OK..*/
190a0 0a 69 6e 74 20 73 71 6c 69 74 65 33 63 68 61 6e  .int sqlite3chan
190b0 67 65 73 65 74 5f 63 6f 6e 66 6c 69 63 74 28 0a  geset_conflict(.
190c0 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65    sqlite3_change
190d0 73 65 74 5f 69 74 65 72 20 2a 70 49 74 65 72 2c  set_iter *pIter,
190e0 20 20 2f 2a 20 43 68 61 6e 67 65 73 65 74 20 69    /* Changeset i
190f0 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74  terator */.  int
19100 20 69 56 61 6c 2c 20 20 20 20 20 20 20 20 20 20   iVal,          
19110 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
19120 49 6e 64 65 78 20 6f 66 20 63 6f 6e 66 6c 69 63  Index of conflic
19130 74 20 72 65 63 6f 72 64 20 76 61 6c 75 65 20 74  t record value t
19140 6f 20 66 65 74 63 68 20 2a 2f 0a 20 20 73 71 6c  o fetch */.  sql
19150 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 70 70 56  ite3_value **ppV
19160 61 6c 75 65 20 20 20 20 20 20 20 20 20 2f 2a 20  alue         /* 
19170 4f 55 54 3a 20 56 61 6c 75 65 20 66 72 6f 6d 20  OUT: Value from 
19180 63 6f 6e 66 6c 69 63 74 69 6e 67 20 72 6f 77 20  conflicting row 
19190 2a 2f 0a 29 7b 0a 20 20 69 66 28 20 21 70 49 74  */.){.  if( !pIt
191a0 65 72 2d 3e 70 43 6f 6e 66 6c 69 63 74 20 29 7b  er->pConflict ){
191b0 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
191c0 54 45 5f 4d 49 53 55 53 45 3b 0a 20 20 7d 0a 20  TE_MISUSE;.  }. 
191d0 20 69 66 28 20 69 56 61 6c 3c 30 20 7c 7c 20 69   if( iVal<0 || i
191e0 56 61 6c 3e 3d 70 49 74 65 72 2d 3e 6e 43 6f 6c  Val>=pIter->nCol
191f0 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
19200 51 4c 49 54 45 5f 52 41 4e 47 45 3b 0a 20 20 7d  QLITE_RANGE;.  }
19210 0a 20 20 2a 70 70 56 61 6c 75 65 20 3d 20 73 71  .  *ppValue = sq
19220 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c  lite3_column_val
19230 75 65 28 70 49 74 65 72 2d 3e 70 43 6f 6e 66 6c  ue(pIter->pConfl
19240 69 63 74 2c 20 69 56 61 6c 29 3b 0a 20 20 72 65  ict, iVal);.  re
19250 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
19260 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
19270 6e 63 74 69 6f 6e 20 6d 61 79 20 6f 6e 6c 79 20  nction may only 
19280 62 65 20 63 61 6c 6c 65 64 20 77 69 74 68 20 61  be called with a
19290 6e 20 69 74 65 72 61 74 6f 72 20 70 61 73 73 65  n iterator passe
192a0 64 20 74 6f 20 61 6e 0a 2a 2a 20 53 51 4c 49 54  d to an.** SQLIT
192b0 45 5f 43 48 41 4e 47 45 53 45 54 5f 46 4f 52 45  E_CHANGESET_FORE
192c0 49 47 4e 5f 4b 45 59 20 63 6f 6e 66 6c 69 63 74  IGN_KEY conflict
192d0 20 68 61 6e 64 6c 65 72 20 63 61 6c 6c 62 61 63   handler callbac
192e0 6b 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65 0a  k. In this case.
192f0 2a 2a 20 69 74 20 73 65 74 73 20 74 68 65 20 6f  ** it sets the o
19300 75 74 70 75 74 20 76 61 72 69 61 62 6c 65 20 74  utput variable t
19310 6f 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62  o the total numb
19320 65 72 20 6f 66 20 6b 6e 6f 77 6e 20 66 6f 72 65  er of known fore
19330 69 67 6e 20 6b 65 79 0a 2a 2a 20 76 69 6f 6c 61  ign key.** viola
19340 74 69 6f 6e 73 20 69 6e 20 74 68 65 20 64 65 73  tions in the des
19350 74 69 6e 61 74 69 6f 6e 20 64 61 74 61 62 61 73  tination databas
19360 65 20 61 6e 64 20 72 65 74 75 72 6e 73 20 53 51  e and returns SQ
19370 4c 49 54 45 5f 4f 4b 2e 0a 2a 2a 0a 2a 2a 20 49  LITE_OK..**.** I
19380 6e 20 61 6c 6c 20 6f 74 68 65 72 20 63 61 73 65  n all other case
19390 73 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  s this function 
193a0 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 4d  returns SQLITE_M
193b0 49 53 55 53 45 2e 0a 2a 2f 0a 69 6e 74 20 73 71  ISUSE..*/.int sq
193c0 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 66  lite3changeset_f
193d0 6b 5f 63 6f 6e 66 6c 69 63 74 73 28 0a 20 20 73  k_conflicts(.  s
193e0 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74  qlite3_changeset
193f0 5f 69 74 65 72 20 2a 70 49 74 65 72 2c 20 20 2f  _iter *pIter,  /
19400 2a 20 43 68 61 6e 67 65 73 65 74 20 69 74 65 72  * Changeset iter
19410 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  ator */.  int *p
19420 6e 4f 75 74 20 20 20 20 20 20 20 20 20 20 20 20  nOut            
19430 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
19440 3a 20 4e 75 6d 62 65 72 20 6f 66 20 46 4b 20 76  : Number of FK v
19450 69 6f 6c 61 74 69 6f 6e 73 20 2a 2f 0a 29 7b 0a  iolations */.){.
19460 20 20 69 66 28 20 70 49 74 65 72 2d 3e 70 43 6f    if( pIter->pCo
19470 6e 66 6c 69 63 74 20 7c 7c 20 70 49 74 65 72 2d  nflict || pIter-
19480 3e 61 70 56 61 6c 75 65 20 29 7b 0a 20 20 20 20  >apValue ){.    
19490 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4d 49  return SQLITE_MI
194a0 53 55 53 45 3b 0a 20 20 7d 0a 20 20 2a 70 6e 4f  SUSE;.  }.  *pnO
194b0 75 74 20 3d 20 70 49 74 65 72 2d 3e 6e 43 6f 6c  ut = pIter->nCol
194c0 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
194d0 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  E_OK;.}.../*.** 
194e0 46 69 6e 61 6c 69 7a 65 20 61 6e 20 69 74 65 72  Finalize an iter
194f0 61 74 6f 72 20 61 6c 6c 6f 63 61 74 65 64 20 77  ator allocated w
19500 69 74 68 20 73 71 6c 69 74 65 33 63 68 61 6e 67  ith sqlite3chang
19510 65 73 65 74 5f 73 74 61 72 74 28 29 2e 0a 2a 2a  eset_start()..**
19520 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
19530 6e 20 6d 61 79 20 6e 6f 74 20 62 65 20 63 61 6c  n may not be cal
19540 6c 65 64 20 6f 6e 20 69 74 65 72 61 74 6f 72 73  led on iterators
19550 20 70 61 73 73 65 64 20 74 6f 20 61 20 63 6f 6e   passed to a con
19560 66 6c 69 63 74 20 68 61 6e 64 6c 65 72 0a 2a 2a  flict handler.**
19570 20 63 61 6c 6c 62 61 63 6b 20 62 79 20 63 68 61   callback by cha
19580 6e 67 65 73 65 74 5f 61 70 70 6c 79 28 29 2e 0a  ngeset_apply()..
19590 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 63 68  */.int sqlite3ch
195a0 61 6e 67 65 73 65 74 5f 66 69 6e 61 6c 69 7a 65  angeset_finalize
195b0 28 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73  (sqlite3_changes
195c0 65 74 5f 69 74 65 72 20 2a 70 29 7b 0a 20 20 69  et_iter *p){.  i
195d0 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
195e0 4b 3b 0a 20 20 69 66 28 20 70 20 29 7b 0a 20 20  K;.  if( p ){.  
195f0 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20    int i;        
19600 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19610 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72 61  /* Used to itera
19620 74 65 20 74 68 72 6f 75 67 68 20 70 2d 3e 61 70  te through p->ap
19630 56 61 6c 75 65 5b 5d 20 2a 2f 0a 20 20 20 20 72  Value[] */.    r
19640 63 20 3d 20 70 2d 3e 72 63 3b 0a 20 20 20 20 69  c = p->rc;.    i
19650 66 28 20 70 2d 3e 61 70 56 61 6c 75 65 20 29 7b  f( p->apValue ){
19660 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  .      for(i=0; 
19670 69 3c 70 2d 3e 6e 43 6f 6c 2a 32 3b 20 69 2b 2b  i<p->nCol*2; i++
19680 29 20 73 71 6c 69 74 65 33 56 61 6c 75 65 46 72  ) sqlite3ValueFr
19690 65 65 28 70 2d 3e 61 70 56 61 6c 75 65 5b 69 5d  ee(p->apValue[i]
196a0 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c  );.    }.    sql
196b0 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 74 62 6c  ite3_free(p->tbl
196c0 68 64 72 2e 61 42 75 66 29 3b 0a 20 20 20 20 73  hdr.aBuf);.    s
196d0 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 69  qlite3_free(p->i
196e0 6e 2e 62 75 66 2e 61 42 75 66 29 3b 0a 20 20 20  n.buf.aBuf);.   
196f0 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29   sqlite3_free(p)
19700 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
19710 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
19720 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65   sessionChangese
19730 74 49 6e 76 65 72 74 28 0a 20 20 53 65 73 73 69  tInvert(.  Sessi
19740 6f 6e 49 6e 70 75 74 20 2a 70 49 6e 70 75 74 2c  onInput *pInput,
19750 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
19760 70 75 74 20 63 68 61 6e 67 65 73 65 74 20 2a 2f  put changeset */
19770 0a 20 20 69 6e 74 20 28 2a 78 4f 75 74 70 75 74  .  int (*xOutput
19780 29 28 76 6f 69 64 20 2a 70 4f 75 74 2c 20 63 6f  )(void *pOut, co
19790 6e 73 74 20 76 6f 69 64 20 2a 70 44 61 74 61 2c  nst void *pData,
197a0 20 69 6e 74 20 6e 44 61 74 61 29 2c 0a 20 20 76   int nData),.  v
197b0 6f 69 64 20 2a 70 4f 75 74 2c 0a 20 20 69 6e 74  oid *pOut,.  int
197c0 20 2a 70 6e 49 6e 76 65 72 74 65 64 2c 20 20 20   *pnInverted,   
197d0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
197e0 4f 55 54 3a 20 4e 75 6d 62 65 72 20 6f 66 20 62  OUT: Number of b
197f0 79 74 65 73 20 69 6e 20 6f 75 74 70 75 74 20 63  ytes in output c
19800 68 61 6e 67 65 73 65 74 20 2a 2f 0a 20 20 76 6f  hangeset */.  vo
19810 69 64 20 2a 2a 70 70 49 6e 76 65 72 74 65 64 20  id **ppInverted 
19820 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
19830 20 4f 55 54 3a 20 49 6e 76 65 72 73 65 20 6f 66   OUT: Inverse of
19840 20 70 43 68 61 6e 67 65 73 65 74 20 2a 2f 0a 29   pChangeset */.)
19850 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
19860 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20  ITE_OK;         
19870 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 76 61      /* Return va
19880 6c 75 65 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e  lue */.  Session
19890 42 75 66 66 65 72 20 73 4f 75 74 3b 20 20 20 20  Buffer sOut;    
198a0 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 75 74 70           /* Outp
198b0 75 74 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 69  ut buffer */.  i
198c0 6e 74 20 6e 43 6f 6c 20 3d 20 30 3b 20 20 20 20  nt nCol = 0;    
198d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
198e0 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 73  * Number of cols
198f0 20 69 6e 20 63 75 72 72 65 6e 74 20 74 61 62 6c   in current tabl
19900 65 20 2a 2f 0a 20 20 75 38 20 2a 61 62 50 4b 20  e */.  u8 *abPK 
19910 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
19920 20 20 20 20 20 20 20 2f 2a 20 50 4b 20 61 72 72         /* PK arr
19930 61 79 20 66 6f 72 20 63 75 72 72 65 6e 74 20 74  ay for current t
19940 61 62 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65  able */.  sqlite
19950 33 5f 76 61 6c 75 65 20 2a 2a 61 70 56 61 6c 20  3_value **apVal 
19960 3d 20 30 3b 20 20 20 20 20 20 2f 2a 20 53 70 61  = 0;      /* Spa
19970 63 65 20 66 6f 72 20 76 61 6c 75 65 73 20 66 6f  ce for values fo
19980 72 20 55 50 44 41 54 45 20 69 6e 76 65 72 73 69  r UPDATE inversi
19990 6f 6e 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 42  on */.  SessionB
199a0 75 66 66 65 72 20 73 50 4b 20 3d 20 7b 30 2c 20  uffer sPK = {0, 
199b0 30 2c 20 30 7d 3b 20 20 2f 2a 20 50 4b 20 61 72  0, 0};  /* PK ar
199c0 72 61 79 20 66 6f 72 20 63 75 72 72 65 6e 74 20  ray for current 
199d0 74 61 62 6c 65 20 2a 2f 0a 0a 20 20 2f 2a 20 49  table */..  /* I
199e0 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 6f 75  nitialize the ou
199f0 74 70 75 74 20 62 75 66 66 65 72 20 2a 2f 0a 20  tput buffer */. 
19a00 20 6d 65 6d 73 65 74 28 26 73 4f 75 74 2c 20 30   memset(&sOut, 0
19a10 2c 20 73 69 7a 65 6f 66 28 53 65 73 73 69 6f 6e  , sizeof(Session
19a20 42 75 66 66 65 72 29 29 3b 0a 0a 20 20 2f 2a 20  Buffer));..  /* 
19a30 5a 65 72 6f 20 74 68 65 20 6f 75 74 70 75 74 20  Zero the output 
19a40 76 61 72 69 61 62 6c 65 73 20 69 6e 20 63 61 73  variables in cas
19a50 65 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  e an error occur
19a60 73 2e 20 2a 2f 0a 20 20 69 66 28 20 70 70 49 6e  s. */.  if( ppIn
19a70 76 65 72 74 65 64 20 29 7b 0a 20 20 20 20 2a 70  verted ){.    *p
19a80 70 49 6e 76 65 72 74 65 64 20 3d 20 30 3b 0a 20  pInverted = 0;. 
19a90 20 20 20 2a 70 6e 49 6e 76 65 72 74 65 64 20 3d     *pnInverted =
19aa0 20 30 3b 0a 20 20 7d 0a 0a 20 20 77 68 69 6c 65   0;.  }..  while
19ab0 28 20 31 20 29 7b 0a 20 20 20 20 75 38 20 65 54  ( 1 ){.    u8 eT
19ac0 79 70 65 3b 0a 0a 20 20 20 20 2f 2a 20 54 65 73  ype;..    /* Tes
19ad0 74 20 66 6f 72 20 45 4f 46 2e 20 2a 2f 0a 20 20  t for EOF. */.  
19ae0 20 20 69 66 28 20 28 72 63 20 3d 20 73 65 73 73    if( (rc = sess
19af0 69 6f 6e 49 6e 70 75 74 42 75 66 66 65 72 28 70  ionInputBuffer(p
19b00 49 6e 70 75 74 2c 20 32 29 29 20 29 20 67 6f 74  Input, 2)) ) got
19b10 6f 20 66 69 6e 69 73 68 65 64 5f 69 6e 76 65 72  o finished_inver
19b20 74 3b 0a 20 20 20 20 69 66 28 20 70 49 6e 70 75  t;.    if( pInpu
19b30 74 2d 3e 69 4e 65 78 74 3e 3d 70 49 6e 70 75 74  t->iNext>=pInput
19b40 2d 3e 6e 44 61 74 61 20 29 20 62 72 65 61 6b 3b  ->nData ) break;
19b50 0a 20 20 20 20 65 54 79 70 65 20 3d 20 70 49 6e  .    eType = pIn
19b60 70 75 74 2d 3e 61 44 61 74 61 5b 70 49 6e 70 75  put->aData[pInpu
19b70 74 2d 3e 69 4e 65 78 74 5d 3b 0a 0a 20 20 20 20  t->iNext];..    
19b80 73 77 69 74 63 68 28 20 65 54 79 70 65 20 29 7b  switch( eType ){
19b90 0a 20 20 20 20 20 20 63 61 73 65 20 27 54 27 3a  .      case 'T':
19ba0 20 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 41 20   {.        /* A 
19bb0 27 74 61 62 6c 65 27 20 72 65 63 6f 72 64 20 63  'table' record c
19bc0 6f 6e 73 69 73 74 73 20 6f 66 3a 0a 20 20 20 20  onsists of:.    
19bd0 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20 2a      **.        *
19be0 2a 20 20 20 2a 20 41 20 63 6f 6e 73 74 61 6e 74  *   * A constant
19bf0 20 27 54 27 20 63 68 61 72 61 63 74 65 72 2c 0a   'T' character,.
19c00 20 20 20 20 20 20 20 20 2a 2a 20 20 20 2a 20 4e          **   * N
19c10 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73  umber of columns
19c20 20 69 6e 20 73 61 69 64 20 74 61 62 6c 65 20 28   in said table (
19c30 61 20 76 61 72 69 6e 74 29 2c 0a 20 20 20 20 20  a varint),.     
19c40 20 20 20 2a 2a 20 20 20 2a 20 41 6e 20 61 72 72     **   * An arr
19c50 61 79 20 6f 66 20 6e 43 6f 6c 20 62 79 74 65 73  ay of nCol bytes
19c60 20 28 73 50 4b 29 2c 0a 20 20 20 20 20 20 20 20   (sPK),.        
19c70 2a 2a 20 20 20 2a 20 41 20 6e 75 6c 2d 74 65 72  **   * A nul-ter
19c80 6d 69 6e 61 74 65 64 20 74 61 62 6c 65 20 6e 61  minated table na
19c90 6d 65 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20  me..        */. 
19ca0 20 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65         int nByte
19cb0 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 56  ;.        int nV
19cc0 61 72 3b 0a 20 20 20 20 20 20 20 20 70 49 6e 70  ar;.        pInp
19cd0 75 74 2d 3e 69 4e 65 78 74 2b 2b 3b 0a 20 20 20  ut->iNext++;.   
19ce0 20 20 20 20 20 69 66 28 20 28 72 63 20 3d 20 73       if( (rc = s
19cf0 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65 74 42  essionChangesetB
19d00 75 66 66 65 72 54 62 6c 68 64 72 28 70 49 6e 70  ufferTblhdr(pInp
19d10 75 74 2c 20 26 6e 42 79 74 65 29 29 20 29 7b 0a  ut, &nByte)) ){.
19d20 20 20 20 20 20 20 20 20 20 20 67 6f 74 6f 20 66            goto f
19d30 69 6e 69 73 68 65 64 5f 69 6e 76 65 72 74 3b 0a  inished_invert;.
19d40 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
19d50 20 20 6e 56 61 72 20 3d 20 73 65 73 73 69 6f 6e    nVar = session
19d60 56 61 72 69 6e 74 47 65 74 28 26 70 49 6e 70 75  VarintGet(&pInpu
19d70 74 2d 3e 61 44 61 74 61 5b 70 49 6e 70 75 74 2d  t->aData[pInput-
19d80 3e 69 4e 65 78 74 5d 2c 20 26 6e 43 6f 6c 29 3b  >iNext], &nCol);
19d90 0a 20 20 20 20 20 20 20 20 73 50 4b 2e 6e 42 75  .        sPK.nBu
19da0 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 73  f = 0;.        s
19db0 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 6c 6f 62  essionAppendBlob
19dc0 28 26 73 50 4b 2c 20 26 70 49 6e 70 75 74 2d 3e  (&sPK, &pInput->
19dd0 61 44 61 74 61 5b 70 49 6e 70 75 74 2d 3e 69 4e  aData[pInput->iN
19de0 65 78 74 2b 6e 56 61 72 5d 2c 20 6e 43 6f 6c 2c  ext+nVar], nCol,
19df0 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20 20 73   &rc);.        s
19e00 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65  essionAppendByte
19e10 28 26 73 4f 75 74 2c 20 65 54 79 70 65 2c 20 26  (&sOut, eType, &
19e20 72 63 29 3b 0a 20 20 20 20 20 20 20 20 73 65 73  rc);.        ses
19e30 73 69 6f 6e 41 70 70 65 6e 64 42 6c 6f 62 28 26  sionAppendBlob(&
19e40 73 4f 75 74 2c 20 26 70 49 6e 70 75 74 2d 3e 61  sOut, &pInput->a
19e50 44 61 74 61 5b 70 49 6e 70 75 74 2d 3e 69 4e 65  Data[pInput->iNe
19e60 78 74 5d 2c 20 6e 42 79 74 65 2c 20 26 72 63 29  xt], nByte, &rc)
19e70 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
19e80 20 29 20 67 6f 74 6f 20 66 69 6e 69 73 68 65 64   ) goto finished
19e90 5f 69 6e 76 65 72 74 3b 0a 0a 20 20 20 20 20 20  _invert;..      
19ea0 20 20 70 49 6e 70 75 74 2d 3e 69 4e 65 78 74 20    pInput->iNext 
19eb0 2b 3d 20 6e 42 79 74 65 3b 0a 20 20 20 20 20 20  += nByte;.      
19ec0 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61    sqlite3_free(a
19ed0 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 61  pVal);.        a
19ee0 70 56 61 6c 20 3d 20 30 3b 0a 20 20 20 20 20 20  pVal = 0;.      
19ef0 20 20 61 62 50 4b 20 3d 20 73 50 4b 2e 61 42 75    abPK = sPK.aBu
19f00 66 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  f;.        break
19f10 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  ;.      }..     
19f20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 53   case SQLITE_INS
19f30 45 52 54 3a 0a 20 20 20 20 20 20 63 61 73 65 20  ERT:.      case 
19f40 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 3a 20 7b  SQLITE_DELETE: {
19f50 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 42 79  .        int nBy
19f60 74 65 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20  te;.        int 
19f70 62 49 6e 64 69 72 65 63 74 20 3d 20 70 49 6e 70  bIndirect = pInp
19f80 75 74 2d 3e 61 44 61 74 61 5b 70 49 6e 70 75 74  ut->aData[pInput
19f90 2d 3e 69 4e 65 78 74 2b 31 5d 3b 0a 20 20 20 20  ->iNext+1];.    
19fa0 20 20 20 20 69 6e 74 20 65 54 79 70 65 32 20 3d      int eType2 =
19fb0 20 28 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f   (eType==SQLITE_
19fc0 44 45 4c 45 54 45 20 3f 20 53 51 4c 49 54 45 5f  DELETE ? SQLITE_
19fd0 49 4e 53 45 52 54 20 3a 20 53 51 4c 49 54 45 5f  INSERT : SQLITE_
19fe0 44 45 4c 45 54 45 29 3b 0a 20 20 20 20 20 20 20  DELETE);.       
19ff0 20 70 49 6e 70 75 74 2d 3e 69 4e 65 78 74 20 2b   pInput->iNext +
1a000 3d 20 32 3b 0a 20 20 20 20 20 20 20 20 61 73 73  = 2;.        ass
1a010 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ert( rc==SQLITE_
1a020 4f 4b 20 29 3b 0a 20 20 20 20 20 20 20 20 72 63  OK );.        rc
1a030 20 3d 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65   = sessionChange
1a040 73 65 74 42 75 66 66 65 72 52 65 63 6f 72 64 28  setBufferRecord(
1a050 70 49 6e 70 75 74 2c 20 6e 43 6f 6c 2c 20 26 6e  pInput, nCol, &n
1a060 42 79 74 65 29 3b 0a 20 20 20 20 20 20 20 20 73  Byte);.        s
1a070 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65  essionAppendByte
1a080 28 26 73 4f 75 74 2c 20 65 54 79 70 65 32 2c 20  (&sOut, eType2, 
1a090 26 72 63 29 3b 0a 20 20 20 20 20 20 20 20 73 65  &rc);.        se
1a0a0 73 73 69 6f 6e 41 70 70 65 6e 64 42 79 74 65 28  ssionAppendByte(
1a0b0 26 73 4f 75 74 2c 20 62 49 6e 64 69 72 65 63 74  &sOut, bIndirect
1a0c0 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20 20  , &rc);.        
1a0d0 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42 6c 6f  sessionAppendBlo
1a0e0 62 28 26 73 4f 75 74 2c 20 26 70 49 6e 70 75 74  b(&sOut, &pInput
1a0f0 2d 3e 61 44 61 74 61 5b 70 49 6e 70 75 74 2d 3e  ->aData[pInput->
1a100 69 4e 65 78 74 5d 2c 20 6e 42 79 74 65 2c 20 26  iNext], nByte, &
1a110 72 63 29 3b 0a 20 20 20 20 20 20 20 20 70 49 6e  rc);.        pIn
1a120 70 75 74 2d 3e 69 4e 65 78 74 20 2b 3d 20 6e 42  put->iNext += nB
1a130 79 74 65 3b 0a 20 20 20 20 20 20 20 20 69 66 28  yte;.        if(
1a140 20 72 63 20 29 20 67 6f 74 6f 20 66 69 6e 69 73   rc ) goto finis
1a150 68 65 64 5f 69 6e 76 65 72 74 3b 0a 20 20 20 20  hed_invert;.    
1a160 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
1a170 20 7d 0a 0a 20 20 20 20 20 20 63 61 73 65 20 53   }..      case S
1a180 51 4c 49 54 45 5f 55 50 44 41 54 45 3a 20 7b 0a  QLITE_UPDATE: {.
1a190 20 20 20 20 20 20 20 20 69 6e 74 20 69 43 6f 6c          int iCol
1a1a0 3b 0a 0a 20 20 20 20 20 20 20 20 69 66 28 20 30  ;..        if( 0
1a1b0 3d 3d 61 70 56 61 6c 20 29 7b 0a 20 20 20 20 20  ==apVal ){.     
1a1c0 20 20 20 20 20 61 70 56 61 6c 20 3d 20 28 73 71       apVal = (sq
1a1d0 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 29 73  lite3_value **)s
1a1e0 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69  qlite3_malloc(si
1a1f0 7a 65 6f 66 28 61 70 56 61 6c 5b 30 5d 29 2a 6e  zeof(apVal[0])*n
1a200 43 6f 6c 2a 32 29 3b 0a 20 20 20 20 20 20 20 20  Col*2);.        
1a210 20 20 69 66 28 20 30 3d 3d 61 70 56 61 6c 20 29    if( 0==apVal )
1a220 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 63  {.            rc
1a230 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
1a240 0a 20 20 20 20 20 20 20 20 20 20 20 20 67 6f 74  .            got
1a250 6f 20 66 69 6e 69 73 68 65 64 5f 69 6e 76 65 72  o finished_inver
1a260 74 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20  t;.          }. 
1a270 20 20 20 20 20 20 20 20 20 6d 65 6d 73 65 74 28           memset(
1a280 61 70 56 61 6c 2c 20 30 2c 20 73 69 7a 65 6f 66  apVal, 0, sizeof
1a290 28 61 70 56 61 6c 5b 30 5d 29 2a 6e 43 6f 6c 2a  (apVal[0])*nCol*
1a2a0 32 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20  2);.        }.. 
1a2b0 20 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20         /* Write 
1a2c0 74 68 65 20 68 65 61 64 65 72 20 66 6f 72 20 74  the header for t
1a2d0 68 65 20 6e 65 77 20 55 50 44 41 54 45 20 63 68  he new UPDATE ch
1a2e0 61 6e 67 65 2e 20 53 61 6d 65 20 61 73 20 74 68  ange. Same as th
1a2f0 65 20 6f 72 69 67 69 6e 61 6c 2e 20 2a 2f 0a 20  e original. */. 
1a300 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70         sessionAp
1a310 70 65 6e 64 42 79 74 65 28 26 73 4f 75 74 2c 20  pendByte(&sOut, 
1a320 65 54 79 70 65 2c 20 26 72 63 29 3b 0a 20 20 20  eType, &rc);.   
1a330 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65       sessionAppe
1a340 6e 64 42 79 74 65 28 26 73 4f 75 74 2c 20 70 49  ndByte(&sOut, pI
1a350 6e 70 75 74 2d 3e 61 44 61 74 61 5b 70 49 6e 70  nput->aData[pInp
1a360 75 74 2d 3e 69 4e 65 78 74 2b 31 5d 2c 20 26 72  ut->iNext+1], &r
1a370 63 29 3b 0a 0a 20 20 20 20 20 20 20 20 2f 2a 20  c);..        /* 
1a380 52 65 61 64 20 74 68 65 20 6f 6c 64 2e 2a 20 61  Read the old.* a
1a390 6e 64 20 6e 65 77 2e 2a 20 72 65 63 6f 72 64 73  nd new.* records
1a3a0 20 66 6f 72 20 74 68 65 20 75 70 64 61 74 65 20   for the update 
1a3b0 63 68 61 6e 67 65 2e 20 2a 2f 0a 20 20 20 20 20  change. */.     
1a3c0 20 20 20 70 49 6e 70 75 74 2d 3e 69 4e 65 78 74     pInput->iNext
1a3d0 20 2b 3d 20 32 3b 0a 20 20 20 20 20 20 20 20 72   += 2;.        r
1a3e0 63 20 3d 20 73 65 73 73 69 6f 6e 52 65 61 64 52  c = sessionReadR
1a3f0 65 63 6f 72 64 28 70 49 6e 70 75 74 2c 20 6e 43  ecord(pInput, nC
1a400 6f 6c 2c 20 30 2c 20 26 61 70 56 61 6c 5b 30 5d  ol, 0, &apVal[0]
1a410 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72  );.        if( r
1a420 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
1a430 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 73            rc = s
1a440 65 73 73 69 6f 6e 52 65 61 64 52 65 63 6f 72 64  essionReadRecord
1a450 28 70 49 6e 70 75 74 2c 20 6e 43 6f 6c 2c 20 30  (pInput, nCol, 0
1a460 2c 20 26 61 70 56 61 6c 5b 6e 43 6f 6c 5d 29 3b  , &apVal[nCol]);
1a470 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  .        }..    
1a480 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65      /* Write the
1a490 20 6e 65 77 20 6f 6c 64 2e 2a 20 72 65 63 6f 72   new old.* recor
1a4a0 64 2e 20 43 6f 6e 73 69 73 74 73 20 6f 66 20 74  d. Consists of t
1a4b0 68 65 20 50 4b 20 63 6f 6c 75 6d 6e 73 20 66 72  he PK columns fr
1a4c0 6f 6d 20 74 68 65 0a 20 20 20 20 20 20 20 20 2a  om the.        *
1a4d0 2a 20 6f 72 69 67 69 6e 61 6c 20 6f 6c 64 2e 2a  * original old.*
1a4e0 20 72 65 63 6f 72 64 2c 20 61 6e 64 20 74 68 65   record, and the
1a4f0 20 6f 74 68 65 72 20 76 61 6c 75 65 73 20 66 72   other values fr
1a500 6f 6d 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 0a  om the original.
1a510 20 20 20 20 20 20 20 20 2a 2a 20 6e 65 77 2e 2a          ** new.*
1a520 20 72 65 63 6f 72 64 2e 20 2a 2f 0a 20 20 20 20   record. */.    
1a530 20 20 20 20 66 6f 72 28 69 43 6f 6c 3d 30 3b 20      for(iCol=0; 
1a540 69 43 6f 6c 3c 6e 43 6f 6c 3b 20 69 43 6f 6c 2b  iCol<nCol; iCol+
1a550 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 73 71  +){.          sq
1a560 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56 61  lite3_value *pVa
1a570 6c 20 3d 20 61 70 56 61 6c 5b 69 43 6f 6c 20 2b  l = apVal[iCol +
1a580 20 28 61 62 50 4b 5b 69 43 6f 6c 5d 20 3f 20 30   (abPK[iCol] ? 0
1a590 20 3a 20 6e 43 6f 6c 29 5d 3b 0a 20 20 20 20 20   : nCol)];.     
1a5a0 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65       sessionAppe
1a5b0 6e 64 56 61 6c 75 65 28 26 73 4f 75 74 2c 20 70  ndValue(&sOut, p
1a5c0 56 61 6c 2c 20 26 72 63 29 3b 0a 20 20 20 20 20  Val, &rc);.     
1a5d0 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 2f 2a     }..        /*
1a5e0 20 57 72 69 74 65 20 74 68 65 20 6e 65 77 20 6e   Write the new n
1a5f0 65 77 2e 2a 20 72 65 63 6f 72 64 2e 20 43 6f 6e  ew.* record. Con
1a600 73 69 73 74 73 20 6f 66 20 61 20 63 6f 70 79 20  sists of a copy 
1a610 6f 66 20 61 6c 6c 20 76 61 6c 75 65 73 0a 20 20  of all values.  
1a620 20 20 20 20 20 20 2a 2a 20 66 72 6f 6d 20 74 68        ** from th
1a630 65 20 6f 72 69 67 69 6e 61 6c 20 6f 6c 64 2e 2a  e original old.*
1a640 20 72 65 63 6f 72 64 2c 20 65 78 63 65 70 74 20   record, except 
1a650 66 6f 72 20 74 68 65 20 50 4b 20 63 6f 6c 75 6d  for the PK colum
1a660 6e 73 2c 20 77 68 69 63 68 0a 20 20 20 20 20 20  ns, which.      
1a670 20 20 2a 2a 20 61 72 65 20 73 65 74 20 74 6f 20    ** are set to 
1a680 22 75 6e 64 65 66 69 6e 65 64 22 2e 20 2a 2f 0a  "undefined". */.
1a690 20 20 20 20 20 20 20 20 66 6f 72 28 69 43 6f 6c          for(iCol
1a6a0 3d 30 3b 20 69 43 6f 6c 3c 6e 43 6f 6c 3b 20 69  =0; iCol<nCol; i
1a6b0 43 6f 6c 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  Col++){.        
1a6c0 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
1a6d0 2a 70 56 61 6c 20 3d 20 28 61 62 50 4b 5b 69 43  *pVal = (abPK[iC
1a6e0 6f 6c 5d 20 3f 20 30 20 3a 20 61 70 56 61 6c 5b  ol] ? 0 : apVal[
1a6f0 69 43 6f 6c 5d 29 3b 0a 20 20 20 20 20 20 20 20  iCol]);.        
1a700 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 56    sessionAppendV
1a710 61 6c 75 65 28 26 73 4f 75 74 2c 20 70 56 61 6c  alue(&sOut, pVal
1a720 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20 20  , &rc);.        
1a730 7d 0a 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69  }..        for(i
1a740 43 6f 6c 3d 30 3b 20 69 43 6f 6c 3c 6e 43 6f 6c  Col=0; iCol<nCol
1a750 2a 32 3b 20 69 43 6f 6c 2b 2b 29 7b 0a 20 20 20  *2; iCol++){.   
1a760 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 56 61         sqlite3Va
1a770 6c 75 65 46 72 65 65 28 61 70 56 61 6c 5b 69 43  lueFree(apVal[iC
1a780 6f 6c 5d 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  ol]);.        }.
1a790 20 20 20 20 20 20 20 20 6d 65 6d 73 65 74 28 61          memset(a
1a7a0 70 56 61 6c 2c 20 30 2c 20 73 69 7a 65 6f 66 28  pVal, 0, sizeof(
1a7b0 61 70 56 61 6c 5b 30 5d 29 2a 6e 43 6f 6c 2a 32  apVal[0])*nCol*2
1a7c0 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72  );.        if( r
1a7d0 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
1a7e0 20 20 20 20 20 20 20 20 20 20 67 6f 74 6f 20 66            goto f
1a7f0 69 6e 69 73 68 65 64 5f 69 6e 76 65 72 74 3b 0a  inished_invert;.
1a800 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20          }..     
1a810 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
1a820 7d 0a 0a 20 20 20 20 20 20 64 65 66 61 75 6c 74  }..      default
1a830 3a 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53  :.        rc = S
1a840 51 4c 49 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b  QLITE_CORRUPT_BK
1a850 50 54 3b 0a 20 20 20 20 20 20 20 20 67 6f 74 6f  PT;.        goto
1a860 20 66 69 6e 69 73 68 65 64 5f 69 6e 76 65 72 74   finished_invert
1a870 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 61 73 73  ;.    }..    ass
1a880 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ert( rc==SQLITE_
1a890 4f 4b 20 29 3b 0a 20 20 20 20 69 66 28 20 78 4f  OK );.    if( xO
1a8a0 75 74 70 75 74 20 26 26 20 73 4f 75 74 2e 6e 42  utput && sOut.nB
1a8b0 75 66 3e 3d 53 45 53 53 49 4f 4e 53 5f 53 54 52  uf>=SESSIONS_STR
1a8c0 4d 5f 43 48 55 4e 4b 5f 53 49 5a 45 20 29 7b 0a  M_CHUNK_SIZE ){.
1a8d0 20 20 20 20 20 20 72 63 20 3d 20 78 4f 75 74 70        rc = xOutp
1a8e0 75 74 28 70 4f 75 74 2c 20 73 4f 75 74 2e 61 42  ut(pOut, sOut.aB
1a8f0 75 66 2c 20 73 4f 75 74 2e 6e 42 75 66 29 3b 0a  uf, sOut.nBuf);.
1a900 20 20 20 20 20 20 73 4f 75 74 2e 6e 42 75 66 20        sOut.nBuf 
1a910 3d 20 30 3b 0a 20 20 20 20 20 20 69 66 28 20 72  = 0;.      if( r
1a920 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 67  c!=SQLITE_OK ) g
1a930 6f 74 6f 20 66 69 6e 69 73 68 65 64 5f 69 6e 76  oto finished_inv
1a940 65 72 74 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  ert;.    }.  }..
1a950 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51    assert( rc==SQ
1a960 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 69 66 28  LITE_OK );.  if(
1a970 20 70 6e 49 6e 76 65 72 74 65 64 20 29 7b 0a 20   pnInverted ){. 
1a980 20 20 20 2a 70 6e 49 6e 76 65 72 74 65 64 20 3d     *pnInverted =
1a990 20 73 4f 75 74 2e 6e 42 75 66 3b 0a 20 20 20 20   sOut.nBuf;.    
1a9a0 2a 70 70 49 6e 76 65 72 74 65 64 20 3d 20 73 4f  *ppInverted = sO
1a9b0 75 74 2e 61 42 75 66 3b 0a 20 20 20 20 73 4f 75  ut.aBuf;.    sOu
1a9c0 74 2e 61 42 75 66 20 3d 20 30 3b 0a 20 20 7d 65  t.aBuf = 0;.  }e
1a9d0 6c 73 65 20 69 66 28 20 73 4f 75 74 2e 6e 42 75  lse if( sOut.nBu
1a9e0 66 3e 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  f>0 ){.    rc = 
1a9f0 78 4f 75 74 70 75 74 28 70 4f 75 74 2c 20 73 4f  xOutput(pOut, sO
1aa00 75 74 2e 61 42 75 66 2c 20 73 4f 75 74 2e 6e 42  ut.aBuf, sOut.nB
1aa10 75 66 29 3b 0a 20 20 7d 0a 0a 20 66 69 6e 69 73  uf);.  }.. finis
1aa20 68 65 64 5f 69 6e 76 65 72 74 3a 0a 20 20 73 71  hed_invert:.  sq
1aa30 6c 69 74 65 33 5f 66 72 65 65 28 73 4f 75 74 2e  lite3_free(sOut.
1aa40 61 42 75 66 29 3b 0a 20 20 73 71 6c 69 74 65 33  aBuf);.  sqlite3
1aa50 5f 66 72 65 65 28 61 70 56 61 6c 29 3b 0a 20 20  _free(apVal);.  
1aa60 73 71 6c 69 74 65 33 5f 66 72 65 65 28 73 50 4b  sqlite3_free(sPK
1aa70 2e 61 42 75 66 29 3b 0a 20 20 72 65 74 75 72 6e  .aBuf);.  return
1aa80 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 49   rc;.}.../*.** I
1aa90 6e 76 65 72 74 20 61 20 63 68 61 6e 67 65 73 65  nvert a changese
1aaa0 74 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 69 6e 74  t object..*/.int
1aab0 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
1aac0 74 5f 69 6e 76 65 72 74 28 0a 20 20 69 6e 74 20  t_invert(.  int 
1aad0 6e 43 68 61 6e 67 65 73 65 74 2c 20 20 20 20 20  nChangeset,     
1aae0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
1aaf0 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69  umber of bytes i
1ab00 6e 20 69 6e 70 75 74 20 2a 2f 0a 20 20 63 6f 6e  n input */.  con
1ab10 73 74 20 76 6f 69 64 20 2a 70 43 68 61 6e 67 65  st void *pChange
1ab20 73 65 74 2c 20 20 20 20 20 20 20 20 20 2f 2a 20  set,         /* 
1ab30 49 6e 70 75 74 20 63 68 61 6e 67 65 73 65 74 20  Input changeset 
1ab40 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 49 6e 76 65  */.  int *pnInve
1ab50 72 74 65 64 2c 20 20 20 20 20 20 20 20 20 20 20  rted,           
1ab60 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d       /* OUT: Num
1ab70 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
1ab80 6f 75 74 70 75 74 20 63 68 61 6e 67 65 73 65 74  output changeset
1ab90 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 2a 70 70 49   */.  void **ppI
1aba0 6e 76 65 72 74 65 64 20 20 20 20 20 20 20 20 20  nverted         
1abb0 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 49 6e        /* OUT: In
1abc0 76 65 72 73 65 20 6f 66 20 70 43 68 61 6e 67 65  verse of pChange
1abd0 73 65 74 20 2a 2f 0a 29 7b 0a 20 20 53 65 73 73  set */.){.  Sess
1abe0 69 6f 6e 49 6e 70 75 74 20 73 49 6e 70 75 74 3b  ionInput sInput;
1abf0 0a 0a 20 20 2f 2a 20 53 65 74 20 75 70 20 74 68  ..  /* Set up th
1ac00 65 20 69 6e 70 75 74 20 73 74 72 65 61 6d 20 2a  e input stream *
1ac10 2f 0a 20 20 6d 65 6d 73 65 74 28 26 73 49 6e 70  /.  memset(&sInp
1ac20 75 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28 53 65  ut, 0, sizeof(Se
1ac30 73 73 69 6f 6e 49 6e 70 75 74 29 29 3b 0a 20 20  ssionInput));.  
1ac40 73 49 6e 70 75 74 2e 6e 44 61 74 61 20 3d 20 6e  sInput.nData = n
1ac50 43 68 61 6e 67 65 73 65 74 3b 0a 20 20 73 49 6e  Changeset;.  sIn
1ac60 70 75 74 2e 61 44 61 74 61 20 3d 20 28 75 38 2a  put.aData = (u8*
1ac70 29 70 43 68 61 6e 67 65 73 65 74 3b 0a 0a 20 20  )pChangeset;..  
1ac80 72 65 74 75 72 6e 20 73 65 73 73 69 6f 6e 43 68  return sessionCh
1ac90 61 6e 67 65 73 65 74 49 6e 76 65 72 74 28 26 73  angesetInvert(&s
1aca0 49 6e 70 75 74 2c 20 30 2c 20 30 2c 20 70 6e 49  Input, 0, 0, pnI
1acb0 6e 76 65 72 74 65 64 2c 20 70 70 49 6e 76 65 72  nverted, ppInver
1acc0 74 65 64 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  ted);.}../*.** S
1acd0 74 72 65 61 6d 69 6e 67 20 76 65 72 73 69 6f 6e  treaming version
1ace0 20 6f 66 20 73 71 6c 69 74 65 33 63 68 61 6e 67   of sqlite3chang
1acf0 65 73 65 74 5f 69 6e 76 65 72 74 28 29 2e 0a 2a  eset_invert()..*
1ad00 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 63 68 61  /.int sqlite3cha
1ad10 6e 67 65 73 65 74 5f 69 6e 76 65 72 74 5f 73 74  ngeset_invert_st
1ad20 72 6d 28 0a 20 20 69 6e 74 20 28 2a 78 49 6e 70  rm(.  int (*xInp
1ad30 75 74 29 28 76 6f 69 64 20 2a 70 49 6e 2c 20 76  ut)(void *pIn, v
1ad40 6f 69 64 20 2a 70 44 61 74 61 2c 20 69 6e 74 20  oid *pData, int 
1ad50 2a 70 6e 44 61 74 61 29 2c 0a 20 20 76 6f 69 64  *pnData),.  void
1ad60 20 2a 70 49 6e 2c 0a 20 20 69 6e 74 20 28 2a 78   *pIn,.  int (*x
1ad70 4f 75 74 70 75 74 29 28 76 6f 69 64 20 2a 70 4f  Output)(void *pO
1ad80 75 74 2c 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a  ut, const void *
1ad90 70 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74 61  pData, int nData
1ada0 29 2c 0a 20 20 76 6f 69 64 20 2a 70 4f 75 74 0a  ),.  void *pOut.
1adb0 29 7b 0a 20 20 53 65 73 73 69 6f 6e 49 6e 70 75  ){.  SessionInpu
1adc0 74 20 73 49 6e 70 75 74 3b 0a 20 20 69 6e 74 20  t sInput;.  int 
1add0 72 63 3b 0a 0a 20 20 2f 2a 20 53 65 74 20 75 70  rc;..  /* Set up
1ade0 20 74 68 65 20 69 6e 70 75 74 20 73 74 72 65 61   the input strea
1adf0 6d 20 2a 2f 0a 20 20 6d 65 6d 73 65 74 28 26 73  m */.  memset(&s
1ae00 49 6e 70 75 74 2c 20 30 2c 20 73 69 7a 65 6f 66  Input, 0, sizeof
1ae10 28 53 65 73 73 69 6f 6e 49 6e 70 75 74 29 29 3b  (SessionInput));
1ae20 0a 20 20 73 49 6e 70 75 74 2e 78 49 6e 70 75 74  .  sInput.xInput
1ae30 20 3d 20 78 49 6e 70 75 74 3b 0a 20 20 73 49 6e   = xInput;.  sIn
1ae40 70 75 74 2e 70 49 6e 20 3d 20 70 49 6e 3b 0a 0a  put.pIn = pIn;..
1ae50 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 43 68    rc = sessionCh
1ae60 61 6e 67 65 73 65 74 49 6e 76 65 72 74 28 26 73  angesetInvert(&s
1ae70 49 6e 70 75 74 2c 20 78 4f 75 74 70 75 74 2c 20  Input, xOutput, 
1ae80 70 4f 75 74 2c 20 30 2c 20 30 29 3b 0a 20 20 73  pOut, 0, 0);.  s
1ae90 71 6c 69 74 65 33 5f 66 72 65 65 28 73 49 6e 70  qlite3_free(sInp
1aea0 75 74 2e 62 75 66 2e 61 42 75 66 29 3b 0a 20 20  ut.buf.aBuf);.  
1aeb0 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 74 79  return rc;.}..ty
1aec0 70 65 64 65 66 20 73 74 72 75 63 74 20 53 65 73  pedef struct Ses
1aed0 73 69 6f 6e 41 70 70 6c 79 43 74 78 20 53 65 73  sionApplyCtx Ses
1aee0 73 69 6f 6e 41 70 70 6c 79 43 74 78 3b 0a 73 74  sionApplyCtx;.st
1aef0 72 75 63 74 20 53 65 73 73 69 6f 6e 41 70 70 6c  ruct SessionAppl
1af00 79 43 74 78 20 7b 0a 20 20 73 71 6c 69 74 65 33  yCtx {.  sqlite3
1af10 20 2a 64 62 3b 0a 20 20 73 71 6c 69 74 65 33 5f   *db;.  sqlite3_
1af20 73 74 6d 74 20 2a 70 44 65 6c 65 74 65 3b 20 20  stmt *pDelete;  
1af30 20 20 20 20 20 20 20 20 2f 2a 20 44 45 4c 45 54          /* DELET
1af40 45 20 73 74 61 74 65 6d 65 6e 74 20 2a 2f 0a 20  E statement */. 
1af50 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
1af60 55 70 64 61 74 65 3b 20 20 20 20 20 20 20 20 20  Update;         
1af70 20 2f 2a 20 55 50 44 41 54 45 20 73 74 61 74 65   /* UPDATE state
1af80 6d 65 6e 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65  ment */.  sqlite
1af90 33 5f 73 74 6d 74 20 2a 70 49 6e 73 65 72 74 3b  3_stmt *pInsert;
1afa0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 53            /* INS
1afb0 45 52 54 20 73 74 61 74 65 6d 65 6e 74 20 2a 2f  ERT statement */
1afc0 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
1afd0 2a 70 53 65 6c 65 63 74 3b 20 20 20 20 20 20 20  *pSelect;       
1afe0 20 20 20 2f 2a 20 53 45 4c 45 43 54 20 73 74 61     /* SELECT sta
1aff0 74 65 6d 65 6e 74 20 2a 2f 0a 20 20 69 6e 74 20  tement */.  int 
1b000 6e 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20  nCol;           
1b010 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
1b020 69 7a 65 20 6f 66 20 61 7a 43 6f 6c 5b 5d 20 61  ize of azCol[] a
1b030 6e 64 20 61 62 50 4b 5b 5d 20 61 72 72 61 79 73  nd abPK[] arrays
1b040 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
1b050 20 2a 2a 61 7a 43 6f 6c 3b 20 20 20 20 20 20 20   **azCol;       
1b060 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f        /* Array o
1b070 66 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 2a  f column names *
1b080 2f 0a 20 20 75 38 20 2a 61 62 50 4b 3b 20 20 20  /.  u8 *abPK;   
1b090 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b0a0 20 20 20 20 2f 2a 20 42 6f 6f 6c 65 61 6e 20 61      /* Boolean a
1b0b0 72 72 61 79 20 2d 20 74 72 75 65 20 69 66 20 63  rray - true if c
1b0c0 6f 6c 75 6d 6e 20 69 73 20 69 6e 20 50 4b 20 2a  olumn is in PK *
1b0d0 2f 0a 20 20 69 6e 74 20 62 53 74 61 74 31 3b 20  /.  int bStat1; 
1b0e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b0f0 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 74      /* True if t
1b100 61 62 6c 65 20 69 73 20 73 71 6c 69 74 65 5f 73  able is sqlite_s
1b110 74 61 74 31 20 2a 2f 0a 20 20 69 6e 74 20 62 44  tat1 */.  int bD
1b120 65 66 65 72 43 6f 6e 73 74 72 61 69 6e 74 73 3b  eferConstraints;
1b130 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
1b140 65 20 74 6f 20 64 65 66 65 72 20 63 6f 6e 73 74  e to defer const
1b150 72 61 69 6e 74 73 20 2a 2f 0a 20 20 53 65 73 73  raints */.  Sess
1b160 69 6f 6e 42 75 66 66 65 72 20 63 6f 6e 73 74 72  ionBuffer constr
1b170 61 69 6e 74 73 3b 20 20 20 20 20 20 2f 2a 20 44  aints;      /* D
1b180 65 66 65 72 72 65 64 20 63 6f 6e 73 74 72 61 69  eferred constrai
1b190 6e 74 73 20 61 72 65 20 73 74 6f 72 65 64 20 68  nts are stored h
1b1a0 65 72 65 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a  ere */.};../*.**
1b1b0 20 46 6f 72 6d 75 6c 61 74 65 20 61 20 73 74 61   Formulate a sta
1b1c0 74 65 6d 65 6e 74 20 74 6f 20 44 45 4c 45 54 45  tement to DELETE
1b1d0 20 61 20 72 6f 77 20 66 72 6f 6d 20 64 61 74 61   a row from data
1b1e0 62 61 73 65 20 64 62 2e 20 41 73 73 75 6d 69 6e  base db. Assumin
1b1f0 67 20 61 20 74 61 62 6c 65 0a 2a 2a 20 73 74 72  g a table.** str
1b200 75 63 74 75 72 65 20 6c 69 6b 65 20 74 68 69 73  ucture like this
1b210 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 43 52 45 41  :.**.**     CREA
1b220 54 45 20 54 41 42 4c 45 20 78 28 61 2c 20 62 2c  TE TABLE x(a, b,
1b230 20 63 2c 20 64 2c 20 50 52 49 4d 41 52 59 20 4b   c, d, PRIMARY K
1b240 45 59 28 61 2c 20 63 29 29 3b 0a 2a 2a 0a 2a 2a  EY(a, c));.**.**
1b250 20 54 68 65 20 44 45 4c 45 54 45 20 73 74 61 74   The DELETE stat
1b260 65 6d 65 6e 74 20 6c 6f 6f 6b 73 20 6c 69 6b 65  ement looks like
1b270 20 74 68 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20   this:.**.**    
1b280 20 44 45 4c 45 54 45 20 46 52 4f 4d 20 78 20 57   DELETE FROM x W
1b290 48 45 52 45 20 61 20 3d 20 3a 31 20 41 4e 44 20  HERE a = :1 AND 
1b2a0 63 20 3d 20 3a 33 20 41 4e 44 20 28 3a 35 20 4f  c = :3 AND (:5 O
1b2b0 52 20 62 20 49 53 20 3a 32 20 41 4e 44 20 64 20  R b IS :2 AND d 
1b2c0 49 53 20 3a 34 29 0a 2a 2a 0a 2a 2a 20 56 61 72  IS :4).**.** Var
1b2d0 69 61 62 6c 65 20 3a 35 20 28 6e 43 6f 6c 2b 31  iable :5 (nCol+1
1b2e0 29 20 69 73 20 61 20 62 6f 6f 6c 65 61 6e 2e 20  ) is a boolean. 
1b2f0 49 74 20 73 68 6f 75 6c 64 20 62 65 20 73 65 74  It should be set
1b300 20 74 6f 20 30 20 69 66 20 77 65 20 72 65 71 75   to 0 if we requ
1b310 69 72 65 0a 2a 2a 20 6d 61 74 63 68 69 6e 67 20  ire.** matching 
1b320 62 20 61 6e 64 20 64 20 76 61 6c 75 65 73 2c 20  b and d values, 
1b330 6f 72 20 31 20 6f 74 68 65 72 77 69 73 65 2e 20  or 1 otherwise. 
1b340 54 68 65 20 73 65 63 6f 6e 64 20 63 61 73 65 20  The second case 
1b350 63 6f 6d 65 73 20 75 70 20 69 66 20 74 68 65 0a  comes up if the.
1b360 2a 2a 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64  ** conflict hand
1b370 6c 65 72 20 69 73 20 69 6e 76 6f 6b 65 64 20 77  ler is invoked w
1b380 69 74 68 20 4e 4f 54 46 4f 55 4e 44 20 61 6e 64  ith NOTFOUND and
1b390 20 72 65 74 75 72 6e 73 20 43 48 41 4e 47 45 53   returns CHANGES
1b3a0 45 54 5f 52 45 50 4c 41 43 45 2e 0a 2a 2a 0a 2a  ET_REPLACE..**.*
1b3b0 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c  * If successful,
1b3c0 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65   SQLITE_OK is re
1b3d0 74 75 72 6e 65 64 20 61 6e 64 20 53 65 73 73 69  turned and Sessi
1b3e0 6f 6e 41 70 70 6c 79 43 74 78 2e 70 44 65 6c 65  onApplyCtx.pDele
1b3f0 74 65 20 69 73 20 6c 65 66 74 0a 2a 2a 20 70 6f  te is left.** po
1b400 69 6e 74 69 6e 67 20 74 6f 20 74 68 65 20 70 72  inting to the pr
1b410 65 70 61 72 65 64 20 76 65 72 73 69 6f 6e 20 6f  epared version o
1b420 66 20 74 68 65 20 53 51 4c 20 73 74 61 74 65 6d  f the SQL statem
1b430 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ent..*/.static i
1b440 6e 74 20 73 65 73 73 69 6f 6e 44 65 6c 65 74 65  nt sessionDelete
1b450 52 6f 77 28 0a 20 20 73 71 6c 69 74 65 33 20 2a  Row(.  sqlite3 *
1b460 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  db,             
1b470 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61         /* Databa
1b480 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 63  se handle */.  c
1b490 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 62 2c  onst char *zTab,
1b4a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1b4b0 2a 20 54 61 62 6c 65 20 6e 61 6d 65 20 2a 2f 0a  * Table name */.
1b4c0 20 20 53 65 73 73 69 6f 6e 41 70 70 6c 79 43 74    SessionApplyCt
1b4d0 78 20 2a 70 20 20 20 20 20 20 20 20 20 20 20 20  x *p            
1b4e0 20 20 2f 2a 20 53 65 73 73 69 6f 6e 20 63 68 61    /* Session cha
1b4f0 6e 67 65 73 65 74 2d 61 70 70 6c 79 20 63 6f 6e  ngeset-apply con
1b500 74 65 78 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  text */.){.  int
1b510 20 69 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   i;.  const char
1b520 20 2a 7a 53 65 70 20 3d 20 22 22 3b 0a 20 20 69   *zSep = "";.  i
1b530 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
1b540 4b 3b 0a 20 20 53 65 73 73 69 6f 6e 42 75 66 66  K;.  SessionBuff
1b550 65 72 20 62 75 66 20 3d 20 7b 30 2c 20 30 2c 20  er buf = {0, 0, 
1b560 30 7d 3b 0a 20 20 69 6e 74 20 6e 50 6b 20 3d 20  0};.  int nPk = 
1b570 30 3b 0a 0a 20 20 73 65 73 73 69 6f 6e 41 70 70  0;..  sessionApp
1b580 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 44 45  endStr(&buf, "DE
1b590 4c 45 54 45 20 46 52 4f 4d 20 22 2c 20 26 72 63  LETE FROM ", &rc
1b5a0 29 3b 0a 20 20 73 65 73 73 69 6f 6e 41 70 70 65  );.  sessionAppe
1b5b0 6e 64 49 64 65 6e 74 28 26 62 75 66 2c 20 7a 54  ndIdent(&buf, zT
1b5c0 61 62 2c 20 26 72 63 29 3b 0a 20 20 73 65 73 73  ab, &rc);.  sess
1b5d0 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75  ionAppendStr(&bu
1b5e0 66 2c 20 22 20 57 48 45 52 45 20 22 2c 20 26 72  f, " WHERE ", &r
1b5f0 63 29 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20  c);..  for(i=0; 
1b600 69 3c 70 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b  i<p->nCol; i++){
1b610 0a 20 20 20 20 69 66 28 20 70 2d 3e 61 62 50 4b  .    if( p->abPK
1b620 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20 6e 50 6b  [i] ){.      nPk
1b630 2b 2b 3b 0a 20 20 20 20 20 20 73 65 73 73 69 6f  ++;.      sessio
1b640 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c  nAppendStr(&buf,
1b650 20 7a 53 65 70 2c 20 26 72 63 29 3b 0a 20 20 20   zSep, &rc);.   
1b660 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
1b670 49 64 65 6e 74 28 26 62 75 66 2c 20 70 2d 3e 61  Ident(&buf, p->a
1b680 7a 43 6f 6c 5b 69 5d 2c 20 26 72 63 29 3b 0a 20  zCol[i], &rc);. 
1b690 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65       sessionAppe
1b6a0 6e 64 53 74 72 28 26 62 75 66 2c 20 22 20 3d 20  ndStr(&buf, " = 
1b6b0 3f 22 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20  ?", &rc);.      
1b6c0 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49 6e 74  sessionAppendInt
1b6d0 65 67 65 72 28 26 62 75 66 2c 20 69 2b 31 2c 20  eger(&buf, i+1, 
1b6e0 26 72 63 29 3b 0a 20 20 20 20 20 20 7a 53 65 70  &rc);.      zSep
1b6f0 20 3d 20 22 20 41 4e 44 20 22 3b 0a 20 20 20 20   = " AND ";.    
1b700 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6e 50 6b  }.  }..  if( nPk
1b710 3c 70 2d 3e 6e 43 6f 6c 20 29 7b 0a 20 20 20 20  <p->nCol ){.    
1b720 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72  sessionAppendStr
1b730 28 26 62 75 66 2c 20 22 20 41 4e 44 20 28 3f 22  (&buf, " AND (?"
1b740 2c 20 26 72 63 29 3b 0a 20 20 20 20 73 65 73 73  , &rc);.    sess
1b750 69 6f 6e 41 70 70 65 6e 64 49 6e 74 65 67 65 72  ionAppendInteger
1b760 28 26 62 75 66 2c 20 70 2d 3e 6e 43 6f 6c 2b 31  (&buf, p->nCol+1
1b770 2c 20 26 72 63 29 3b 0a 20 20 20 20 73 65 73 73  , &rc);.    sess
1b780 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75  ionAppendStr(&bu
1b790 66 2c 20 22 20 4f 52 20 22 2c 20 26 72 63 29 3b  f, " OR ", &rc);
1b7a0 0a 0a 20 20 20 20 7a 53 65 70 20 3d 20 22 22 3b  ..    zSep = "";
1b7b0 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  .    for(i=0; i<
1b7c0 70 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20  p->nCol; i++){. 
1b7d0 20 20 20 20 20 69 66 28 20 21 70 2d 3e 61 62 50       if( !p->abP
1b7e0 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20 20 20  K[i] ){.        
1b7f0 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72  sessionAppendStr
1b800 28 26 62 75 66 2c 20 7a 53 65 70 2c 20 26 72 63  (&buf, zSep, &rc
1b810 29 3b 0a 20 20 20 20 20 20 20 20 73 65 73 73 69  );.        sessi
1b820 6f 6e 41 70 70 65 6e 64 49 64 65 6e 74 28 26 62  onAppendIdent(&b
1b830 75 66 2c 20 70 2d 3e 61 7a 43 6f 6c 5b 69 5d 2c  uf, p->azCol[i],
1b840 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20 20 73   &rc);.        s
1b850 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28  essionAppendStr(
1b860 26 62 75 66 2c 20 22 20 49 53 20 3f 22 2c 20 26  &buf, " IS ?", &
1b870 72 63 29 3b 0a 20 20 20 20 20 20 20 20 73 65 73  rc);.        ses
1b880 73 69 6f 6e 41 70 70 65 6e 64 49 6e 74 65 67 65  sionAppendIntege
1b890 72 28 26 62 75 66 2c 20 69 2b 31 2c 20 26 72 63  r(&buf, i+1, &rc
1b8a0 29 3b 0a 20 20 20 20 20 20 20 20 7a 53 65 70 20  );.        zSep 
1b8b0 3d 20 22 41 4e 44 20 22 3b 0a 20 20 20 20 20 20  = "AND ";.      
1b8c0 7d 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 73 73  }.    }.    sess
1b8d0 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75  ionAppendStr(&bu
1b8e0 66 2c 20 22 29 22 2c 20 26 72 63 29 3b 0a 20 20  f, ")", &rc);.  
1b8f0 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
1b900 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
1b910 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
1b920 72 65 5f 76 32 28 64 62 2c 20 28 63 68 61 72 20  re_v2(db, (char 
1b930 2a 29 62 75 66 2e 61 42 75 66 2c 20 62 75 66 2e  *)buf.aBuf, buf.
1b940 6e 42 75 66 2c 20 26 70 2d 3e 70 44 65 6c 65 74  nBuf, &p->pDelet
1b950 65 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 73 71 6c  e, 0);.  }.  sql
1b960 69 74 65 33 5f 66 72 65 65 28 62 75 66 2e 61 42  ite3_free(buf.aB
1b970 75 66 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72  uf);..  return r
1b980 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6f 72 6d  c;.}../*.** Form
1b990 75 6c 61 74 65 20 61 6e 64 20 70 72 65 70 61 72  ulate and prepar
1b9a0 65 20 61 20 73 74 61 74 65 6d 65 6e 74 20 74 6f  e a statement to
1b9b0 20 55 50 44 41 54 45 20 61 20 72 6f 77 20 66 72   UPDATE a row fr
1b9c0 6f 6d 20 64 61 74 61 62 61 73 65 20 64 62 2e 20  om database db. 
1b9d0 0a 2a 2a 20 41 73 73 75 6d 69 6e 67 20 61 20 74  .** Assuming a t
1b9e0 61 62 6c 65 20 73 74 72 75 63 74 75 72 65 20 6c  able structure l
1b9f0 69 6b 65 20 74 68 69 73 3a 0a 2a 2a 0a 2a 2a 20  ike this:.**.** 
1ba00 20 20 20 20 43 52 45 41 54 45 20 54 41 42 4c 45      CREATE TABLE
1ba10 20 78 28 61 2c 20 62 2c 20 63 2c 20 64 2c 20 50   x(a, b, c, d, P
1ba20 52 49 4d 41 52 59 20 4b 45 59 28 61 2c 20 63 29  RIMARY KEY(a, c)
1ba30 29 3b 0a 2a 2a 0a 2a 2a 20 54 68 65 20 55 50 44  );.**.** The UPD
1ba40 41 54 45 20 73 74 61 74 65 6d 65 6e 74 20 6c 6f  ATE statement lo
1ba50 6f 6b 73 20 6c 69 6b 65 20 74 68 69 73 3a 0a 2a  oks like this:.*
1ba60 2a 0a 2a 2a 20 20 20 20 20 55 50 44 41 54 45 20  *.**     UPDATE 
1ba70 78 20 53 45 54 0a 2a 2a 20 20 20 20 20 61 20 3d  x SET.**     a =
1ba80 20 43 41 53 45 20 57 48 45 4e 20 3f 32 20 20 54   CASE WHEN ?2  T
1ba90 48 45 4e 20 3f 33 20 20 45 4c 53 45 20 61 20 45  HEN ?3  ELSE a E
1baa0 4e 44 2c 0a 2a 2a 20 20 20 20 20 62 20 3d 20 43  ND,.**     b = C
1bab0 41 53 45 20 57 48 45 4e 20 3f 35 20 20 54 48 45  ASE WHEN ?5  THE
1bac0 4e 20 3f 36 20 20 45 4c 53 45 20 62 20 45 4e 44  N ?6  ELSE b END
1bad0 2c 0a 2a 2a 20 20 20 20 20 63 20 3d 20 43 41 53  ,.**     c = CAS
1bae0 45 20 57 48 45 4e 20 3f 38 20 20 54 48 45 4e 20  E WHEN ?8  THEN 
1baf0 3f 39 20 20 45 4c 53 45 20 63 20 45 4e 44 2c 0a  ?9  ELSE c END,.
1bb00 2a 2a 20 20 20 20 20 64 20 3d 20 43 41 53 45 20  **     d = CASE 
1bb10 57 48 45 4e 20 3f 31 31 20 54 48 45 4e 20 3f 31  WHEN ?11 THEN ?1
1bb20 32 20 45 4c 53 45 20 64 20 45 4e 44 0a 2a 2a 20  2 ELSE d END.** 
1bb30 20 20 20 20 57 48 45 52 45 20 61 20 3d 20 3f 31      WHERE a = ?1
1bb40 20 41 4e 44 20 63 20 3d 20 3f 37 20 41 4e 44 20   AND c = ?7 AND 
1bb50 28 3f 31 33 20 4f 52 20 0a 2a 2a 20 20 20 20 20  (?13 OR .**     
1bb60 20 20 28 3f 35 3d 3d 30 20 4f 52 20 62 20 49 53    (?5==0 OR b IS
1bb70 20 3f 34 29 20 41 4e 44 20 28 3f 31 31 3d 3d 30   ?4) AND (?11==0
1bb80 20 4f 52 20 64 20 49 53 20 3f 31 30 29 20 41 4e   OR d IS ?10) AN
1bb90 44 0a 2a 2a 20 20 20 20 20 29 0a 2a 2a 0a 2a 2a  D.**     ).**.**
1bba0 20 46 6f 72 20 65 61 63 68 20 63 6f 6c 75 6d 6e   For each column
1bbb0 20 69 6e 20 74 68 65 20 74 61 62 6c 65 2c 20 74   in the table, t
1bbc0 68 65 72 65 20 61 72 65 20 74 68 72 65 65 20 76  here are three v
1bbd0 61 72 69 61 62 6c 65 73 20 74 6f 20 62 69 6e 64  ariables to bind
1bbe0 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 3f 28 69 2a  :.**.**     ?(i*
1bbf0 33 2b 31 29 20 20 20 20 54 68 65 20 6f 6c 64 2e  3+1)    The old.
1bc00 2a 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 63  * value of the c
1bc10 6f 6c 75 6d 6e 2c 20 69 66 20 61 6e 79 2e 0a 2a  olumn, if any..*
1bc20 2a 20 20 20 20 20 3f 28 69 2a 33 2b 32 29 20 20  *     ?(i*3+2)  
1bc30 20 20 41 20 62 6f 6f 6c 65 61 6e 20 66 6c 61 67    A boolean flag
1bc40 20 69 6e 64 69 63 61 74 69 6e 67 20 74 68 61 74   indicating that
1bc50 20 74 68 65 20 76 61 6c 75 65 20 69 73 20 62 65   the value is be
1bc60 69 6e 67 20 6d 6f 64 69 66 69 65 64 2e 0a 2a 2a  ing modified..**
1bc70 20 20 20 20 20 3f 28 69 2a 33 2b 33 29 20 20 20       ?(i*3+3)   
1bc80 20 54 68 65 20 6e 65 77 2e 2a 20 76 61 6c 75 65   The new.* value
1bc90 20 6f 66 20 74 68 65 20 63 6f 6c 75 6d 6e 2c 20   of the column, 
1bca0 69 66 20 61 6e 79 2e 0a 2a 2a 0a 2a 2a 20 41 6c  if any..**.** Al
1bcb0 73 6f 2c 20 61 20 62 6f 6f 6c 65 61 6e 20 66 6c  so, a boolean fl
1bcc0 61 67 20 74 68 61 74 2c 20 69 66 20 73 65 74 20  ag that, if set 
1bcd0 74 6f 20 74 72 75 65 2c 20 63 61 75 73 65 73 20  to true, causes 
1bce0 74 68 65 20 73 74 61 74 65 6d 65 6e 74 20 74 6f  the statement to
1bcf0 20 75 70 64 61 74 65 0a 2a 2a 20 61 20 72 6f 77   update.** a row
1bd00 20 65 76 65 6e 20 69 66 20 74 68 65 20 6e 6f 6e   even if the non
1bd10 2d 50 4b 20 76 61 6c 75 65 73 20 64 6f 20 6e 6f  -PK values do no
1bd20 74 20 6d 61 74 63 68 2e 20 54 68 69 73 20 69 73  t match. This is
1bd30 20 72 65 71 75 69 72 65 64 20 69 66 20 74 68 65   required if the
1bd40 0a 2a 2a 20 63 6f 6e 66 6c 69 63 74 2d 68 61 6e  .** conflict-han
1bd50 64 6c 65 72 20 69 73 20 69 6e 76 6f 6b 65 64 20  dler is invoked 
1bd60 77 69 74 68 20 43 48 41 4e 47 45 53 45 54 5f 44  with CHANGESET_D
1bd70 41 54 41 20 61 6e 64 20 72 65 74 75 72 6e 73 0a  ATA and returns.
1bd80 2a 2a 20 43 48 41 4e 47 45 53 45 54 5f 52 45 50  ** CHANGESET_REP
1bd90 4c 41 43 45 2e 20 54 68 69 73 20 69 73 20 76 61  LACE. This is va
1bda0 72 69 61 62 6c 65 20 22 3f 28 6e 43 6f 6c 2a 33  riable "?(nCol*3
1bdb0 2b 31 29 22 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73  +1)"..**.** If s
1bdc0 75 63 63 65 73 73 66 75 6c 2c 20 53 51 4c 49 54  uccessful, SQLIT
1bdd0 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64  E_OK is returned
1bde0 20 61 6e 64 20 53 65 73 73 69 6f 6e 41 70 70 6c   and SessionAppl
1bdf0 79 43 74 78 2e 70 55 70 64 61 74 65 20 69 73 20  yCtx.pUpdate is 
1be00 6c 65 66 74 0a 2a 2a 20 70 6f 69 6e 74 69 6e 67  left.** pointing
1be10 20 74 6f 20 74 68 65 20 70 72 65 70 61 72 65 64   to the prepared
1be20 20 76 65 72 73 69 6f 6e 20 6f 66 20 74 68 65 20   version of the 
1be30 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 2e 0a 2a  SQL statement..*
1be40 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73  /.static int ses
1be50 73 69 6f 6e 55 70 64 61 74 65 52 6f 77 28 0a 20  sionUpdateRow(. 
1be60 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20   sqlite3 *db,   
1be70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1be80 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e   /* Database han
1be90 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  dle */.  const c
1bea0 68 61 72 20 2a 7a 54 61 62 2c 20 20 20 20 20 20  har *zTab,      
1beb0 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62 6c           /* Tabl
1bec0 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 53 65 73 73  e name */.  Sess
1bed0 69 6f 6e 41 70 70 6c 79 43 74 78 20 2a 70 20 20  ionApplyCtx *p  
1bee0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
1bef0 65 73 73 69 6f 6e 20 63 68 61 6e 67 65 73 65 74  ession changeset
1bf00 2d 61 70 70 6c 79 20 63 6f 6e 74 65 78 74 20 2a  -apply context *
1bf10 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  /.){.  int rc = 
1bf20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74  SQLITE_OK;.  int
1bf30 20 69 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   i;.  const char
1bf40 20 2a 7a 53 65 70 20 3d 20 22 22 3b 0a 20 20 53   *zSep = "";.  S
1bf50 65 73 73 69 6f 6e 42 75 66 66 65 72 20 62 75 66  essionBuffer buf
1bf60 20 3d 20 7b 30 2c 20 30 2c 20 30 7d 3b 0a 0a 20   = {0, 0, 0};.. 
1bf70 20 2f 2a 20 41 70 70 65 6e 64 20 22 55 50 44 41   /* Append "UPDA
1bf80 54 45 20 74 62 6c 20 53 45 54 20 22 20 2a 2f 0a  TE tbl SET " */.
1bf90 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53    sessionAppendS
1bfa0 74 72 28 26 62 75 66 2c 20 22 55 50 44 41 54 45  tr(&buf, "UPDATE
1bfb0 20 22 2c 20 26 72 63 29 3b 0a 20 20 73 65 73 73   ", &rc);.  sess
1bfc0 69 6f 6e 41 70 70 65 6e 64 49 64 65 6e 74 28 26  ionAppendIdent(&
1bfd0 62 75 66 2c 20 7a 54 61 62 2c 20 26 72 63 29 3b  buf, zTab, &rc);
1bfe0 0a 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64  .  sessionAppend
1bff0 53 74 72 28 26 62 75 66 2c 20 22 20 53 45 54 20  Str(&buf, " SET 
1c000 22 2c 20 26 72 63 29 3b 0a 0a 20 20 2f 2a 20 41  ", &rc);..  /* A
1c010 70 70 65 6e 64 20 74 68 65 20 61 73 73 69 67 6e  ppend the assign
1c020 6d 65 6e 74 73 20 2a 2f 0a 20 20 66 6f 72 28 69  ments */.  for(i
1c030 3d 30 3b 20 69 3c 70 2d 3e 6e 43 6f 6c 3b 20 69  =0; i<p->nCol; i
1c040 2b 2b 29 7b 0a 20 20 20 20 73 65 73 73 69 6f 6e  ++){.    session
1c050 41 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20  AppendStr(&buf, 
1c060 7a 53 65 70 2c 20 26 72 63 29 3b 0a 20 20 20 20  zSep, &rc);.    
1c070 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49 64 65  sessionAppendIde
1c080 6e 74 28 26 62 75 66 2c 20 70 2d 3e 61 7a 43 6f  nt(&buf, p->azCo
1c090 6c 5b 69 5d 2c 20 26 72 63 29 3b 0a 20 20 20 20  l[i], &rc);.    
1c0a0 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72  sessionAppendStr
1c0b0 28 26 62 75 66 2c 20 22 20 3d 20 43 41 53 45 20  (&buf, " = CASE 
1c0c0 57 48 45 4e 20 3f 22 2c 20 26 72 63 29 3b 0a 20  WHEN ?", &rc);. 
1c0d0 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64     sessionAppend
1c0e0 49 6e 74 65 67 65 72 28 26 62 75 66 2c 20 69 2a  Integer(&buf, i*
1c0f0 33 2b 32 2c 20 26 72 63 29 3b 0a 20 20 20 20 73  3+2, &rc);.    s
1c100 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28  essionAppendStr(
1c110 26 62 75 66 2c 20 22 20 54 48 45 4e 20 3f 22 2c  &buf, " THEN ?",
1c120 20 26 72 63 29 3b 0a 20 20 20 20 73 65 73 73 69   &rc);.    sessi
1c130 6f 6e 41 70 70 65 6e 64 49 6e 74 65 67 65 72 28  onAppendInteger(
1c140 26 62 75 66 2c 20 69 2a 33 2b 33 2c 20 26 72 63  &buf, i*3+3, &rc
1c150 29 3b 0a 20 20 20 20 73 65 73 73 69 6f 6e 41 70  );.    sessionAp
1c160 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 20  pendStr(&buf, " 
1c170 45 4c 53 45 20 22 2c 20 26 72 63 29 3b 0a 20 20  ELSE ", &rc);.  
1c180 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49    sessionAppendI
1c190 64 65 6e 74 28 26 62 75 66 2c 20 70 2d 3e 61 7a  dent(&buf, p->az
1c1a0 43 6f 6c 5b 69 5d 2c 20 26 72 63 29 3b 0a 20 20  Col[i], &rc);.  
1c1b0 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53    sessionAppendS
1c1c0 74 72 28 26 62 75 66 2c 20 22 20 45 4e 44 22 2c  tr(&buf, " END",
1c1d0 20 26 72 63 29 3b 0a 20 20 20 20 7a 53 65 70 20   &rc);.    zSep 
1c1e0 3d 20 22 2c 20 22 3b 0a 20 20 7d 0a 0a 20 20 2f  = ", ";.  }..  /
1c1f0 2a 20 41 70 70 65 6e 64 20 74 68 65 20 50 4b 20  * Append the PK 
1c200 70 61 72 74 20 6f 66 20 74 68 65 20 57 48 45 52  part of the WHER
1c210 45 20 63 6c 61 75 73 65 20 2a 2f 0a 20 20 73 65  E clause */.  se
1c220 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26  ssionAppendStr(&
1c230 62 75 66 2c 20 22 20 57 48 45 52 45 20 22 2c 20  buf, " WHERE ", 
1c240 26 72 63 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  &rc);.  for(i=0;
1c250 20 69 3c 70 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29   i<p->nCol; i++)
1c260 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e 61 62 50  {.    if( p->abP
1c270 4b 5b 69 5d 20 29 7b 0a 20 20 20 20 20 20 73 65  K[i] ){.      se
1c280 73 73 69 6f 6e 41 70 70 65 6e 64 49 64 65 6e 74  ssionAppendIdent
1c290 28 26 62 75 66 2c 20 70 2d 3e 61 7a 43 6f 6c 5b  (&buf, p->azCol[
1c2a0 69 5d 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20  i], &rc);.      
1c2b0 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72  sessionAppendStr
1c2c0 28 26 62 75 66 2c 20 22 20 3d 20 3f 22 2c 20 26  (&buf, " = ?", &
1c2d0 72 63 29 3b 0a 20 20 20 20 20 20 73 65 73 73 69  rc);.      sessi
1c2e0 6f 6e 41 70 70 65 6e 64 49 6e 74 65 67 65 72 28  onAppendInteger(
1c2f0 26 62 75 66 2c 20 69 2a 33 2b 31 2c 20 26 72 63  &buf, i*3+1, &rc
1c300 29 3b 0a 20 20 20 20 20 20 73 65 73 73 69 6f 6e  );.      session
1c310 41 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20  AppendStr(&buf, 
1c320 22 20 41 4e 44 20 22 2c 20 26 72 63 29 3b 0a 20  " AND ", &rc);. 
1c330 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41     }.  }..  /* A
1c340 70 70 65 6e 64 20 74 68 65 20 6e 6f 6e 2d 50 4b  ppend the non-PK
1c350 20 70 61 72 74 20 6f 66 20 74 68 65 20 57 48 45   part of the WHE
1c360 52 45 20 63 6c 61 75 73 65 20 2a 2f 0a 20 20 73  RE clause */.  s
1c370 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28  essionAppendStr(
1c380 26 62 75 66 2c 20 22 20 28 3f 22 2c 20 26 72 63  &buf, " (?", &rc
1c390 29 3b 0a 20 20 73 65 73 73 69 6f 6e 41 70 70 65  );.  sessionAppe
1c3a0 6e 64 49 6e 74 65 67 65 72 28 26 62 75 66 2c 20  ndInteger(&buf, 
1c3b0 70 2d 3e 6e 43 6f 6c 2a 33 2b 31 2c 20 26 72 63  p->nCol*3+1, &rc
1c3c0 29 3b 0a 20 20 73 65 73 73 69 6f 6e 41 70 70 65  );.  sessionAppe
1c3d0 6e 64 53 74 72 28 26 62 75 66 2c 20 22 20 4f 52  ndStr(&buf, " OR
1c3e0 20 31 22 2c 20 26 72 63 29 3b 0a 20 20 66 6f 72   1", &rc);.  for
1c3f0 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 43 6f 6c 3b  (i=0; i<p->nCol;
1c400 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 21   i++){.    if( !
1c410 70 2d 3e 61 62 50 4b 5b 69 5d 20 29 7b 0a 20 20  p->abPK[i] ){.  
1c420 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e      sessionAppen
1c430 64 53 74 72 28 26 62 75 66 2c 20 22 20 41 4e 44  dStr(&buf, " AND
1c440 20 28 3f 22 2c 20 26 72 63 29 3b 0a 20 20 20 20   (?", &rc);.    
1c450 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49    sessionAppendI
1c460 6e 74 65 67 65 72 28 26 62 75 66 2c 20 69 2a 33  nteger(&buf, i*3
1c470 2b 32 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20  +2, &rc);.      
1c480 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72  sessionAppendStr
1c490 28 26 62 75 66 2c 20 22 3d 30 20 4f 52 20 22 2c  (&buf, "=0 OR ",
1c4a0 20 26 72 63 29 3b 0a 20 20 20 20 20 20 73 65 73   &rc);.      ses
1c4b0 73 69 6f 6e 41 70 70 65 6e 64 49 64 65 6e 74 28  sionAppendIdent(
1c4c0 26 62 75 66 2c 20 70 2d 3e 61 7a 43 6f 6c 5b 69  &buf, p->azCol[i
1c4d0 5d 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 73  ], &rc);.      s
1c4e0 65 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28  essionAppendStr(
1c4f0 26 62 75 66 2c 20 22 20 49 53 20 3f 22 2c 20 26  &buf, " IS ?", &
1c500 72 63 29 3b 0a 20 20 20 20 20 20 73 65 73 73 69  rc);.      sessi
1c510 6f 6e 41 70 70 65 6e 64 49 6e 74 65 67 65 72 28  onAppendInteger(
1c520 26 62 75 66 2c 20 69 2a 33 2b 31 2c 20 26 72 63  &buf, i*3+1, &rc
1c530 29 3b 0a 20 20 20 20 20 20 73 65 73 73 69 6f 6e  );.      session
1c540 41 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20  AppendStr(&buf, 
1c550 22 29 22 2c 20 26 72 63 29 3b 0a 20 20 20 20 7d  ")", &rc);.    }
1c560 0a 20 20 7d 0a 20 20 73 65 73 73 69 6f 6e 41 70  .  }.  sessionAp
1c570 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 29  pendStr(&buf, ")
1c580 22 2c 20 26 72 63 29 3b 0a 0a 20 20 69 66 28 20  ", &rc);..  if( 
1c590 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
1c5a0 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
1c5b0 33 5f 70 72 65 70 61 72 65 5f 76 32 28 64 62 2c  3_prepare_v2(db,
1c5c0 20 28 63 68 61 72 20 2a 29 62 75 66 2e 61 42 75   (char *)buf.aBu
1c5d0 66 2c 20 62 75 66 2e 6e 42 75 66 2c 20 26 70 2d  f, buf.nBuf, &p-
1c5e0 3e 70 55 70 64 61 74 65 2c 20 30 29 3b 0a 20 20  >pUpdate, 0);.  
1c5f0 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  }.  sqlite3_free
1c600 28 62 75 66 2e 61 42 75 66 29 3b 0a 0a 20 20 72  (buf.aBuf);..  r
1c610 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a  eturn rc;.}.../*
1c620 0a 2a 2a 20 46 6f 72 6d 75 6c 61 74 65 20 61 6e  .** Formulate an
1c630 64 20 70 72 65 70 61 72 65 20 61 6e 20 53 51 4c  d prepare an SQL
1c640 20 73 74 61 74 65 6d 65 6e 74 20 74 6f 20 71 75   statement to qu
1c650 65 72 79 20 74 61 62 6c 65 20 7a 54 61 62 20 62  ery table zTab b
1c660 79 20 70 72 69 6d 61 72 79 0a 2a 2a 20 6b 65 79  y primary.** key
1c670 2e 20 41 73 73 75 6d 69 6e 67 20 74 68 65 20 66  . Assuming the f
1c680 6f 6c 6c 6f 77 69 6e 67 20 74 61 62 6c 65 20 73  ollowing table s
1c690 74 72 75 63 74 75 72 65 3a 0a 2a 2a 0a 2a 2a 20  tructure:.**.** 
1c6a0 20 20 20 20 43 52 45 41 54 45 20 54 41 42 4c 45      CREATE TABLE
1c6b0 20 78 28 61 2c 20 62 2c 20 63 2c 20 64 2c 20 50   x(a, b, c, d, P
1c6c0 52 49 4d 41 52 59 20 4b 45 59 28 61 2c 20 63 29  RIMARY KEY(a, c)
1c6d0 29 3b 0a 2a 2a 0a 2a 2a 20 54 68 65 20 53 45 4c  );.**.** The SEL
1c6e0 45 43 54 20 73 74 61 74 65 6d 65 6e 74 20 6c 6f  ECT statement lo
1c6f0 6f 6b 73 20 6c 69 6b 65 20 74 68 69 73 3a 0a 2a  oks like this:.*
1c700 2a 0a 2a 2a 20 20 20 20 20 53 45 4c 45 43 54 20  *.**     SELECT 
1c710 2a 20 46 52 4f 4d 20 78 20 57 48 45 52 45 20 61  * FROM x WHERE a
1c720 20 3d 20 3f 31 20 41 4e 44 20 63 20 3d 20 3f 33   = ?1 AND c = ?3
1c730 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65 73  .**.** If succes
1c740 73 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b 20  sful, SQLITE_OK 
1c750 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20  is returned and 
1c760 53 65 73 73 69 6f 6e 41 70 70 6c 79 43 74 78 2e  SessionApplyCtx.
1c770 70 53 65 6c 65 63 74 20 69 73 20 6c 65 66 74 0a  pSelect is left.
1c780 2a 2a 20 70 6f 69 6e 74 69 6e 67 20 74 6f 20 74  ** pointing to t
1c790 68 65 20 70 72 65 70 61 72 65 64 20 76 65 72 73  he prepared vers
1c7a0 69 6f 6e 20 6f 66 20 74 68 65 20 53 51 4c 20 73  ion of the SQL s
1c7b0 74 61 74 65 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61  tatement..*/.sta
1c7c0 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 53  tic int sessionS
1c7d0 65 6c 65 63 74 52 6f 77 28 0a 20 20 73 71 6c 69  electRow(.  sqli
1c7e0 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20  te3 *db,        
1c7f0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
1c800 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a  atabase handle *
1c810 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
1c820 7a 54 61 62 2c 20 20 20 20 20 20 20 20 20 20 20  zTab,           
1c830 20 20 20 20 2f 2a 20 54 61 62 6c 65 20 6e 61 6d      /* Table nam
1c840 65 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 41 70  e */.  SessionAp
1c850 70 6c 79 43 74 78 20 2a 70 20 20 20 20 20 20 20  plyCtx *p       
1c860 20 20 20 20 20 20 20 2f 2a 20 53 65 73 73 69 6f         /* Sessio
1c870 6e 20 63 68 61 6e 67 65 73 65 74 2d 61 70 70 6c  n changeset-appl
1c880 79 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 29 7b 0a  y context */.){.
1c890 20 20 72 65 74 75 72 6e 20 73 65 73 73 69 6f 6e    return session
1c8a0 53 65 6c 65 63 74 53 74 6d 74 28 0a 20 20 20 20  SelectStmt(.    
1c8b0 20 20 64 62 2c 20 22 6d 61 69 6e 22 2c 20 7a 54    db, "main", zT
1c8c0 61 62 2c 20 70 2d 3e 6e 43 6f 6c 2c 20 70 2d 3e  ab, p->nCol, p->
1c8d0 61 7a 43 6f 6c 2c 20 70 2d 3e 61 62 50 4b 2c 20  azCol, p->abPK, 
1c8e0 26 70 2d 3e 70 53 65 6c 65 63 74 29 3b 0a 7d 0a  &p->pSelect);.}.
1c8f0 0a 2f 2a 0a 2a 2a 20 46 6f 72 6d 75 6c 61 74 65  ./*.** Formulate
1c900 20 61 6e 64 20 70 72 65 70 61 72 65 20 61 6e 20   and prepare an 
1c910 49 4e 53 45 52 54 20 73 74 61 74 65 6d 65 6e 74  INSERT statement
1c920 20 74 6f 20 61 64 64 20 61 20 72 65 63 6f 72 64   to add a record
1c930 20 74 6f 20 74 61 62 6c 65 20 7a 54 61 62 2e 0a   to table zTab..
1c940 2a 2a 20 46 6f 72 20 65 78 61 6d 70 6c 65 3a 0a  ** For example:.
1c950 2a 2a 0a 2a 2a 20 20 20 20 20 49 4e 53 45 52 54  **.**     INSERT
1c960 20 49 4e 54 4f 20 6d 61 69 6e 2e 22 7a 54 61 62   INTO main."zTab
1c970 22 20 56 41 4c 55 45 53 28 3f 31 2c 20 3f 32 2c  " VALUES(?1, ?2,
1c980 20 3f 33 20 2e 2e 2e 29 3b 0a 2a 2a 0a 2a 2a 20   ?3 ...);.**.** 
1c990 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 53  If successful, S
1c9a0 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75  QLITE_OK is retu
1c9b0 72 6e 65 64 20 61 6e 64 20 53 65 73 73 69 6f 6e  rned and Session
1c9c0 41 70 70 6c 79 43 74 78 2e 70 49 6e 73 65 72 74  ApplyCtx.pInsert
1c9d0 20 69 73 20 6c 65 66 74 0a 2a 2a 20 70 6f 69 6e   is left.** poin
1c9e0 74 69 6e 67 20 74 6f 20 74 68 65 20 70 72 65 70  ting to the prep
1c9f0 61 72 65 64 20 76 65 72 73 69 6f 6e 20 6f 66 20  ared version of 
1ca00 74 68 65 20 53 51 4c 20 73 74 61 74 65 6d 65 6e  the SQL statemen
1ca10 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  t..*/.static int
1ca20 20 73 65 73 73 69 6f 6e 49 6e 73 65 72 74 52 6f   sessionInsertRo
1ca30 77 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  w(.  sqlite3 *db
1ca40 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1ca50 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
1ca60 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e   handle */.  con
1ca70 73 74 20 63 68 61 72 20 2a 7a 54 61 62 2c 20 20  st char *zTab,  
1ca80 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1ca90 54 61 62 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20 20  Table name */.  
1caa0 53 65 73 73 69 6f 6e 41 70 70 6c 79 43 74 78 20  SessionApplyCtx 
1cab0 2a 70 20 20 20 20 20 20 20 20 20 20 20 20 20 20  *p              
1cac0 2f 2a 20 53 65 73 73 69 6f 6e 20 63 68 61 6e 67  /* Session chang
1cad0 65 73 65 74 2d 61 70 70 6c 79 20 63 6f 6e 74 65  eset-apply conte
1cae0 78 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  xt */.){.  int r
1caf0 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
1cb00 20 69 6e 74 20 69 3b 0a 20 20 53 65 73 73 69 6f   int i;.  Sessio
1cb10 6e 42 75 66 66 65 72 20 62 75 66 20 3d 20 7b 30  nBuffer buf = {0
1cb20 2c 20 30 2c 20 30 7d 3b 0a 0a 20 20 73 65 73 73  , 0, 0};..  sess
1cb30 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26 62 75  ionAppendStr(&bu
1cb40 66 2c 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20  f, "INSERT INTO 
1cb50 6d 61 69 6e 2e 22 2c 20 26 72 63 29 3b 0a 20 20  main.", &rc);.  
1cb60 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 49 64 65  sessionAppendIde
1cb70 6e 74 28 26 62 75 66 2c 20 7a 54 61 62 2c 20 26  nt(&buf, zTab, &
1cb80 72 63 29 3b 0a 20 20 73 65 73 73 69 6f 6e 41 70  rc);.  sessionAp
1cb90 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20 22 28  pendStr(&buf, "(
1cba0 22 2c 20 26 72 63 29 3b 0a 20 20 66 6f 72 28 69  ", &rc);.  for(i
1cbb0 3d 30 3b 20 69 3c 70 2d 3e 6e 43 6f 6c 3b 20 69  =0; i<p->nCol; i
1cbc0 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 69 21 3d  ++){.    if( i!=
1cbd0 30 20 29 20 73 65 73 73 69 6f 6e 41 70 70 65 6e  0 ) sessionAppen
1cbe0 64 53 74 72 28 26 62 75 66 2c 20 22 2c 20 22 2c  dStr(&buf, ", ",
1cbf0 20 26 72 63 29 3b 0a 20 20 20 20 73 65 73 73 69   &rc);.    sessi
1cc00 6f 6e 41 70 70 65 6e 64 49 64 65 6e 74 28 26 62  onAppendIdent(&b
1cc10 75 66 2c 20 70 2d 3e 61 7a 43 6f 6c 5b 69 5d 2c  uf, p->azCol[i],
1cc20 20 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 73 65   &rc);.  }..  se
1cc30 73 73 69 6f 6e 41 70 70 65 6e 64 53 74 72 28 26  ssionAppendStr(&
1cc40 62 75 66 2c 20 22 29 20 56 41 4c 55 45 53 28 3f  buf, ") VALUES(?
1cc50 22 2c 20 26 72 63 29 3b 0a 20 20 66 6f 72 28 69  ", &rc);.  for(i
1cc60 3d 31 3b 20 69 3c 70 2d 3e 6e 43 6f 6c 3b 20 69  =1; i<p->nCol; i
1cc70 2b 2b 29 7b 0a 20 20 20 20 73 65 73 73 69 6f 6e  ++){.    session
1cc80 41 70 70 65 6e 64 53 74 72 28 26 62 75 66 2c 20  AppendStr(&buf, 
1cc90 22 2c 20 3f 22 2c 20 26 72 63 29 3b 0a 20 20 7d  ", ?", &rc);.  }
1cca0 0a 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64  .  sessionAppend
1ccb0 53 74 72 28 26 62 75 66 2c 20 22 29 22 2c 20 26  Str(&buf, ")", &
1ccc0 72 63 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d  rc);..  if( rc==
1ccd0 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
1cce0 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72   rc = sqlite3_pr
1ccf0 65 70 61 72 65 5f 76 32 28 64 62 2c 20 28 63 68  epare_v2(db, (ch
1cd00 61 72 20 2a 29 62 75 66 2e 61 42 75 66 2c 20 62  ar *)buf.aBuf, b
1cd10 75 66 2e 6e 42 75 66 2c 20 26 70 2d 3e 70 49 6e  uf.nBuf, &p->pIn
1cd20 73 65 72 74 2c 20 30 29 3b 0a 20 20 7d 0a 20 20  sert, 0);.  }.  
1cd30 73 71 6c 69 74 65 33 5f 66 72 65 65 28 62 75 66  sqlite3_free(buf
1cd40 2e 61 42 75 66 29 3b 0a 20 20 72 65 74 75 72 6e  .aBuf);.  return
1cd50 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69   rc;.}..static i
1cd60 6e 74 20 73 65 73 73 69 6f 6e 50 72 65 70 61 72  nt sessionPrepar
1cd70 65 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 73  e(sqlite3 *db, s
1cd80 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 2a 70 70  qlite3_stmt **pp
1cd90 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53  , const char *zS
1cda0 71 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 71  ql){.  return sq
1cdb0 6c 69 74 65 33 5f 70 72 65 70 61 72 65 5f 76 32  lite3_prepare_v2
1cdc0 28 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 70  (db, zSql, -1, p
1cdd0 70 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  p, 0);.}../*.** 
1cde0 50 72 65 70 61 72 65 20 73 74 61 74 65 6d 65 6e  Prepare statemen
1cdf0 74 73 20 66 6f 72 20 61 70 70 6c 79 69 6e 67 20  ts for applying 
1ce00 63 68 61 6e 67 65 73 20 74 6f 20 74 68 65 20 73  changes to the s
1ce10 71 6c 69 74 65 5f 73 74 61 74 31 20 74 61 62 6c  qlite_stat1 tabl
1ce20 65 2e 0a 2a 2a 20 54 68 65 73 65 20 61 72 65 20  e..** These are 
1ce30 73 69 6d 69 6c 61 72 20 74 6f 20 74 68 6f 73 65  similar to those
1ce40 20 63 72 65 61 74 65 64 20 62 79 20 73 65 73 73   created by sess
1ce50 69 6f 6e 53 65 6c 65 63 74 52 6f 77 28 29 2c 0a  ionSelectRow(),.
1ce60 2a 2a 20 73 65 73 73 69 6f 6e 49 6e 73 65 72 74  ** sessionInsert
1ce70 52 6f 77 28 29 2c 20 73 65 73 73 69 6f 6e 55 70  Row(), sessionUp
1ce80 64 61 74 65 52 6f 77 28 29 20 61 6e 64 20 73 65  dateRow() and se
1ce90 73 73 69 6f 6e 44 65 6c 65 74 65 52 6f 77 28 29  ssionDeleteRow()
1cea0 20 66 6f 72 20 0a 2a 2a 20 6f 74 68 65 72 20 74   for .** other t
1ceb0 61 62 6c 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  ables..*/.static
1cec0 20 69 6e 74 20 73 65 73 73 69 6f 6e 53 74 61 74   int sessionStat
1ced0 31 53 71 6c 28 73 71 6c 69 74 65 33 20 2a 64 62  1Sql(sqlite3 *db
1cee0 2c 20 53 65 73 73 69 6f 6e 41 70 70 6c 79 43 74  , SessionApplyCt
1cef0 78 20 2a 70 29 7b 0a 20 20 69 6e 74 20 72 63 20  x *p){.  int rc 
1cf00 3d 20 73 65 73 73 69 6f 6e 53 65 6c 65 63 74 52  = sessionSelectR
1cf10 6f 77 28 64 62 2c 20 22 73 71 6c 69 74 65 5f 73  ow(db, "sqlite_s
1cf20 74 61 74 31 22 2c 20 70 29 3b 0a 20 20 69 66 28  tat1", p);.  if(
1cf30 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
1cf40 7b 0a 20 20 20 20 72 63 20 3d 20 73 65 73 73 69  {.    rc = sessi
1cf50 6f 6e 50 72 65 70 61 72 65 28 64 62 2c 20 26 70  onPrepare(db, &p
1cf60 2d 3e 70 49 6e 73 65 72 74 2c 0a 20 20 20 20 20  ->pInsert,.     
1cf70 20 20 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20     "INSERT INTO 
1cf80 6d 61 69 6e 2e 73 71 6c 69 74 65 5f 73 74 61 74  main.sqlite_stat
1cf90 31 20 56 41 4c 55 45 53 28 3f 31 2c 20 22 0a 20  1 VALUES(?1, ". 
1cfa0 20 20 20 20 20 20 20 22 43 41 53 45 20 57 48 45         "CASE WHE
1cfb0 4e 20 6c 65 6e 67 74 68 28 3f 32 29 3d 30 20 41  N length(?2)=0 A
1cfc0 4e 44 20 74 79 70 65 6f 66 28 3f 32 29 3d 27 62  ND typeof(?2)='b
1cfd0 6c 6f 62 27 20 54 48 45 4e 20 4e 55 4c 4c 20 45  lob' THEN NULL E
1cfe0 4c 53 45 20 3f 32 20 45 4e 44 2c 20 22 0a 20 20  LSE ?2 END, ".  
1cff0 20 20 20 20 20 20 22 3f 33 29 22 0a 20 20 20 20        "?3)".    
1d000 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d  );.  }.  if( rc=
1d010 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
1d020 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 50 72    rc = sessionPr
1d030 65 70 61 72 65 28 64 62 2c 20 26 70 2d 3e 70 55  epare(db, &p->pU
1d040 70 64 61 74 65 2c 0a 20 20 20 20 20 20 20 20 22  pdate,.        "
1d050 55 50 44 41 54 45 20 6d 61 69 6e 2e 73 71 6c 69  UPDATE main.sqli
1d060 74 65 5f 73 74 61 74 31 20 53 45 54 20 22 0a 20  te_stat1 SET ". 
1d070 20 20 20 20 20 20 20 22 74 62 6c 20 3d 20 43 41         "tbl = CA
1d080 53 45 20 57 48 45 4e 20 3f 32 20 54 48 45 4e 20  SE WHEN ?2 THEN 
1d090 3f 33 20 45 4c 53 45 20 74 62 6c 20 45 4e 44 2c  ?3 ELSE tbl END,
1d0a0 20 22 0a 20 20 20 20 20 20 20 20 22 69 64 78 20   ".        "idx 
1d0b0 3d 20 43 41 53 45 20 57 48 45 4e 20 3f 35 20 54  = CASE WHEN ?5 T
1d0c0 48 45 4e 20 3f 36 20 45 4c 53 45 20 69 64 78 20  HEN ?6 ELSE idx 
1d0d0 45 4e 44 2c 20 22 0a 20 20 20 20 20 20 20 20 22  END, ".        "
1d0e0 73 74 61 74 20 3d 20 43 41 53 45 20 57 48 45 4e  stat = CASE WHEN
1d0f0 20 3f 38 20 54 48 45 4e 20 3f 39 20 45 4c 53 45   ?8 THEN ?9 ELSE
1d100 20 73 74 61 74 20 45 4e 44 20 20 22 0a 20 20 20   stat END  ".   
1d110 20 20 20 20 20 22 57 48 45 52 45 20 74 62 6c 3d       "WHERE tbl=
1d120 3f 31 20 41 4e 44 20 69 64 78 20 49 53 20 22 0a  ?1 AND idx IS ".
1d130 20 20 20 20 20 20 20 20 22 43 41 53 45 20 57 48          "CASE WH
1d140 45 4e 20 6c 65 6e 67 74 68 28 3f 34 29 3d 30 20  EN length(?4)=0 
1d150 41 4e 44 20 74 79 70 65 6f 66 28 3f 34 29 3d 27  AND typeof(?4)='
1d160 62 6c 6f 62 27 20 54 48 45 4e 20 4e 55 4c 4c 20  blob' THEN NULL 
1d170 45 4c 53 45 20 3f 34 20 45 4e 44 20 22 0a 20 20  ELSE ?4 END ".  
1d180 20 20 20 20 20 20 22 41 4e 44 20 28 3f 31 30 20        "AND (?10 
1d190 4f 52 20 3f 38 3d 30 20 4f 52 20 73 74 61 74 20  OR ?8=0 OR stat 
1d1a0 49 53 20 3f 37 29 22 0a 20 20 20 20 29 3b 0a 20  IS ?7)".    );. 
1d1b0 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c   }.  if( rc==SQL
1d1c0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
1d1d0 20 3d 20 73 65 73 73 69 6f 6e 50 72 65 70 61 72   = sessionPrepar
1d1e0 65 28 64 62 2c 20 26 70 2d 3e 70 44 65 6c 65 74  e(db, &p->pDelet
1d1f0 65 2c 0a 20 20 20 20 20 20 20 20 22 44 45 4c 45  e,.        "DELE
1d200 54 45 20 46 52 4f 4d 20 6d 61 69 6e 2e 73 71 6c  TE FROM main.sql
1d210 69 74 65 5f 73 74 61 74 31 20 57 48 45 52 45 20  ite_stat1 WHERE 
1d220 74 62 6c 3d 3f 31 20 41 4e 44 20 69 64 78 20 49  tbl=?1 AND idx I
1d230 53 20 22 0a 20 20 20 20 20 20 20 20 22 43 41 53  S ".        "CAS
1d240 45 20 57 48 45 4e 20 6c 65 6e 67 74 68 28 3f 32  E WHEN length(?2
1d250 29 3d 30 20 41 4e 44 20 74 79 70 65 6f 66 28 3f  )=0 AND typeof(?
1d260 32 29 3d 27 62 6c 6f 62 27 20 54 48 45 4e 20 4e  2)='blob' THEN N
1d270 55 4c 4c 20 45 4c 53 45 20 3f 32 20 45 4e 44 20  ULL ELSE ?2 END 
1d280 22 0a 20 20 20 20 20 20 20 20 22 41 4e 44 20 28  ".        "AND (
1d290 3f 34 20 4f 52 20 73 74 61 74 20 49 53 20 3f 33  ?4 OR stat IS ?3
1d2a0 29 22 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 20 20  )".    );.  }.  
1d2b0 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49  assert( rc==SQLI
1d2c0 54 45 5f 4f 4b 20 29 3b 0a 20 20 72 65 74 75 72  TE_OK );.  retur
1d2d0 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  n rc;.}../*.** A
1d2e0 20 77 72 61 70 70 65 72 20 61 72 6f 75 6e 64 20   wrapper around 
1d2f0 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c  sqlite3_bind_val
1d300 75 65 28 29 20 74 68 61 74 20 64 65 74 65 63 74  ue() that detect
1d310 73 20 61 6e 20 65 78 74 72 61 20 70 72 6f 62 6c  s an extra probl
1d320 65 6d 2e 20 0a 2a 2a 20 53 65 65 20 63 6f 6d 6d  em. .** See comm
1d330 65 6e 74 73 20 69 6e 20 74 68 65 20 62 6f 64 79  ents in the body
1d340 20 6f 66 20 74 68 69 73 20 66 75 6e 63 74 69 6f   of this functio
1d350 6e 20 66 6f 72 20 64 65 74 61 69 6c 73 2e 0a 2a  n for details..*
1d360 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 73  /.static int ses
1d370 73 69 6f 6e 42 69 6e 64 56 61 6c 75 65 28 0a 20  sionBindValue(. 
1d380 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
1d390 53 74 6d 74 2c 20 20 20 20 20 20 20 20 20 20 20  Stmt,           
1d3a0 20 2f 2a 20 53 74 61 74 65 6d 65 6e 74 20 74 6f   /* Statement to
1d3b0 20 62 69 6e 64 20 76 61 6c 75 65 20 74 6f 20 2a   bind value to *
1d3c0 2f 0a 20 20 69 6e 74 20 69 2c 20 20 20 20 20 20  /.  int i,      
1d3d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d3e0 20 20 20 20 2f 2a 20 50 61 72 61 6d 65 74 65 72      /* Parameter
1d3f0 20 6e 75 6d 62 65 72 20 74 6f 20 62 69 6e 64 20   number to bind 
1d400 74 6f 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  to */.  sqlite3_
1d410 76 61 6c 75 65 20 2a 70 56 61 6c 20 20 20 20 20  value *pVal     
1d420 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65          /* Value
1d430 20 74 6f 20 62 69 6e 64 20 2a 2f 0a 29 7b 0a 20   to bind */.){. 
1d440 20 69 6e 74 20 65 54 79 70 65 20 3d 20 73 71 6c   int eType = sql
1d450 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
1d460 70 56 61 6c 29 3b 0a 20 20 2f 2a 20 43 4f 56 45  pVal);.  /* COVE
1d470 52 41 47 45 3a 20 54 68 65 20 28 70 56 61 6c 2d  RAGE: The (pVal-
1d480 3e 7a 3d 3d 30 29 20 62 72 61 6e 63 68 20 69 73  >z==0) branch is
1d490 20 6e 65 76 65 72 20 74 72 75 65 20 75 73 69 6e   never true usin
1d4a0 67 20 63 75 72 72 65 6e 74 20 76 65 72 73 69 6f  g current versio
1d4b0 6e 73 0a 20 20 2a 2a 20 6f 66 20 53 51 4c 69 74  ns.  ** of SQLit
1d4c0 65 2e 20 49 66 20 61 20 6d 61 6c 6c 6f 63 20 66  e. If a malloc f
1d4d0 61 69 6c 73 20 69 6e 20 61 6e 20 73 71 6c 69 74  ails in an sqlit
1d4e0 65 33 5f 76 61 6c 75 65 5f 78 78 78 28 29 20 66  e3_value_xxx() f
1d4f0 75 6e 63 74 69 6f 6e 2c 20 65 69 74 68 65 72 0a  unction, either.
1d500 20 20 2a 2a 20 74 68 65 20 28 70 56 61 6c 2d 3e    ** the (pVal->
1d510 7a 29 20 76 61 72 69 61 62 6c 65 20 72 65 6d 61  z) variable rema
1d520 69 6e 73 20 61 73 20 69 74 20 77 61 73 20 6f 72  ins as it was or
1d530 20 74 68 65 20 74 79 70 65 20 6f 66 20 74 68 65   the type of the
1d540 20 76 61 6c 75 65 20 69 73 0a 20 20 2a 2a 20 73   value is.  ** s
1d550 65 74 20 74 6f 20 53 51 4c 49 54 45 5f 4e 55 4c  et to SQLITE_NUL
1d560 4c 2e 20 20 2a 2f 0a 20 20 69 66 28 20 28 65 54  L.  */.  if( (eT
1d570 79 70 65 3d 3d 53 51 4c 49 54 45 5f 54 45 58 54  ype==SQLITE_TEXT
1d580 20 7c 7c 20 65 54 79 70 65 3d 3d 53 51 4c 49 54   || eType==SQLIT
1d590 45 5f 42 4c 4f 42 29 20 26 26 20 70 56 61 6c 2d  E_BLOB) && pVal-
1d5a0 3e 7a 3d 3d 30 20 29 7b 0a 20 20 20 20 2f 2a 20  >z==0 ){.    /* 
1d5b0 54 68 69 73 20 63 6f 6e 64 69 74 69 6f 6e 20 6f  This condition o
1d5c0 63 63 75 72 73 20 77 68 65 6e 20 61 6e 20 65 61  ccurs when an ea
1d5d0 72 6c 69 65 72 20 4f 4f 4d 20 69 6e 20 61 20 63  rlier OOM in a c
1d5e0 61 6c 6c 20 74 6f 0a 20 20 20 20 2a 2a 20 73 71  all to.    ** sq
1d5f0 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74  lite3_value_text
1d600 28 29 20 6f 72 20 73 71 6c 69 74 65 33 5f 76 61  () or sqlite3_va
1d610 6c 75 65 5f 62 6c 6f 62 28 29 20 28 70 65 72 68  lue_blob() (perh
1d620 61 70 73 20 66 72 6f 6d 20 77 69 74 68 69 6e 0a  aps from within.
1d630 20 20 20 20 2a 2a 20 61 20 63 6f 6e 66 6c 69 63      ** a conflic
1d640 74 2d 68 61 6e 64 6c 65 72 29 20 68 61 73 20 7a  t-handler) has z
1d650 65 72 6f 65 64 20 74 68 65 20 70 56 61 6c 2d 3e  eroed the pVal->
1d660 7a 20 70 6f 69 6e 74 65 72 2e 20 52 65 74 75 72  z pointer. Retur
1d670 6e 20 4e 4f 4d 45 4d 2e 20 2a 2f 0a 20 20 20 20  n NOMEM. */.    
1d680 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
1d690 4d 45 4d 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  MEM;.  }.  retur
1d6a0 6e 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76  n sqlite3_bind_v
1d6b0 61 6c 75 65 28 70 53 74 6d 74 2c 20 69 2c 20 70  alue(pStmt, i, p
1d6c0 56 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  Val);.}../*.** I
1d6d0 74 65 72 61 74 6f 72 20 70 49 74 65 72 20 6d 75  terator pIter mu
1d6e0 73 74 20 70 6f 69 6e 74 20 74 6f 20 61 6e 20 53  st point to an S
1d6f0 51 4c 49 54 45 5f 49 4e 53 45 52 54 20 65 6e 74  QLITE_INSERT ent
1d700 72 79 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f  ry. This functio
1d710 6e 20 0a 2a 2a 20 74 72 61 6e 73 66 65 72 73 20  n .** transfers 
1d720 6e 65 77 2e 2a 20 76 61 6c 75 65 73 20 66 72 6f  new.* values fro
1d730 6d 20 74 68 65 20 63 75 72 72 65 6e 74 20 69 74  m the current it
1d740 65 72 61 74 6f 72 20 65 6e 74 72 79 20 74 6f 20  erator entry to 
1d750 73 74 61 74 65 6d 65 6e 74 0a 2a 2a 20 70 53 74  statement.** pSt
1d760 6d 74 2e 20 54 68 65 20 74 61 62 6c 65 20 62 65  mt. The table be
1d770 69 6e 67 20 69 6e 73 65 72 74 65 64 20 69 6e 74  ing inserted int
1d780 6f 20 68 61 73 20 6e 43 6f 6c 20 63 6f 6c 75 6d  o has nCol colum
1d790 6e 73 2e 0a 2a 2a 0a 2a 2a 20 4e 65 77 2e 2a 20  ns..**.** New.* 
1d7a0 76 61 6c 75 65 20 24 69 20 66 72 6f 6d 20 74 68  value $i from th
1d7b0 65 20 69 74 65 72 61 74 6f 72 20 69 73 20 62 6f  e iterator is bo
1d7c0 75 6e 64 20 74 6f 20 76 61 72 69 61 62 6c 65 20  und to variable 
1d7d0 28 24 69 2b 31 29 20 6f 66 20 0a 2a 2a 20 73 74  ($i+1) of .** st
1d7e0 61 74 65 6d 65 6e 74 20 70 53 74 6d 74 2e 20 49  atement pStmt. I
1d7f0 66 20 70 61 72 61 6d 65 74 65 72 20 61 62 50 4b  f parameter abPK
1d800 20 69 73 20 4e 55 4c 4c 2c 20 61 6c 6c 20 76 61   is NULL, all va
1d810 6c 75 65 73 20 66 72 6f 6d 20 30 20 74 6f 20 28  lues from 0 to (
1d820 6e 43 6f 6c 2d 31 29 0a 2a 2a 20 61 72 65 20 74  nCol-1).** are t
1d830 72 61 6e 73 66 65 72 65 64 20 74 6f 20 74 68 65  ransfered to the
1d840 20 73 74 61 74 65 6d 65 6e 74 2e 20 4f 74 68 65   statement. Othe
1d850 72 77 69 73 65 2c 20 69 66 20 61 62 50 4b 20 69  rwise, if abPK i
1d860 73 20 6e 6f 74 20 4e 55 4c 4c 2c 20 69 74 20 70  s not NULL, it p
1d870 6f 69 6e 74 73 0a 2a 2a 20 74 6f 20 61 6e 20 61  oints.** to an a
1d880 72 72 61 79 20 6e 43 6f 6c 20 65 6c 65 6d 65 6e  rray nCol elemen
1d890 74 73 20 69 6e 20 73 69 7a 65 2e 20 49 6e 20 74  ts in size. In t
1d8a0 68 69 73 20 63 61 73 65 20 6f 6e 6c 79 20 74 68  his case only th
1d8b0 6f 73 65 20 76 61 6c 75 65 73 20 66 6f 72 20 0a  ose values for .
1d8c0 2a 2a 20 77 68 69 63 68 20 61 62 50 4b 5b 24 69  ** which abPK[$i
1d8d0 5d 20 69 73 20 74 72 75 65 20 61 72 65 20 72 65  ] is true are re
1d8e0 61 64 20 66 72 6f 6d 20 74 68 65 20 69 74 65 72  ad from the iter
1d8f0 61 74 6f 72 20 61 6e 64 20 62 6f 75 6e 64 20 74  ator and bound t
1d900 6f 20 74 68 65 20 0a 2a 2a 20 73 74 61 74 65 6d  o the .** statem
1d910 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 41 6e 20 53 51  ent..**.** An SQ
1d920 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20  Lite error code 
1d930 69 73 20 72 65 74 75 72 6e 65 64 20 69 66 20 61  is returned if a
1d940 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 20  n error occurs. 
1d950 4f 74 68 65 72 77 69 73 65 2c 20 53 51 4c 49 54  Otherwise, SQLIT
1d960 45 5f 4f 4b 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  E_OK..*/.static 
1d970 69 6e 74 20 73 65 73 73 69 6f 6e 42 69 6e 64 52  int sessionBindR
1d980 6f 77 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 68  ow(.  sqlite3_ch
1d990 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a 70 49  angeset_iter *pI
1d9a0 74 65 72 2c 20 20 2f 2a 20 49 74 65 72 61 74 6f  ter,  /* Iterato
1d9b0 72 20 74 6f 20 72 65 61 64 20 76 61 6c 75 65 73  r to read values
1d9c0 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 6e 74 28 2a   from */.  int(*
1d9d0 78 56 61 6c 75 65 29 28 73 71 6c 69 74 65 33 5f  xValue)(sqlite3_
1d9e0 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a  changeset_iter *
1d9f0 2c 20 69 6e 74 2c 20 73 71 6c 69 74 65 33 5f 76  , int, sqlite3_v
1da00 61 6c 75 65 20 2a 2a 29 2c 0a 20 20 69 6e 74 20  alue **),.  int 
1da10 6e 43 6f 6c 2c 20 20 20 20 20 20 20 20 20 20 20  nCol,           
1da20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
1da30 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73  umber of columns
1da40 20 2a 2f 0a 20 20 75 38 20 2a 61 62 50 4b 2c 20   */.  u8 *abPK, 
1da50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1da60 20 20 20 20 20 20 2f 2a 20 49 66 20 6e 6f 74 20        /* If not 
1da70 4e 55 4c 4c 2c 20 62 69 6e 64 20 6f 6e 6c 79 20  NULL, bind only 
1da80 69 66 20 74 72 75 65 20 2a 2f 0a 20 20 73 71 6c  if true */.  sql
1da90 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74  ite3_stmt *pStmt
1daa0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1dab0 42 69 6e 64 20 76 61 6c 75 65 73 20 74 6f 20 74  Bind values to t
1dac0 68 69 73 20 73 74 61 74 65 6d 65 6e 74 20 2a 2f  his statement */
1dad0 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69  .){.  int i;.  i
1dae0 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
1daf0 4b 3b 0a 0a 20 20 2f 2a 20 4e 65 69 74 68 65 72  K;..  /* Neither
1db00 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
1db10 74 5f 6f 6c 64 20 6f 72 20 73 71 6c 69 74 65 33  t_old or sqlite3
1db20 63 68 61 6e 67 65 73 65 74 5f 6e 65 77 20 63 61  changeset_new ca
1db30 6e 20 66 61 69 6c 20 69 66 20 74 68 65 0a 20 20  n fail if the.  
1db40 2a 2a 20 61 72 67 75 6d 65 6e 74 20 69 74 65 72  ** argument iter
1db50 61 74 6f 72 20 70 6f 69 6e 74 73 20 74 6f 20 61  ator points to a
1db60 20 73 75 69 74 61 62 6c 65 20 65 6e 74 72 79 2e   suitable entry.
1db70 20 4d 61 6b 65 20 73 75 72 65 20 74 68 61 74 20   Make sure that 
1db80 78 56 61 6c 75 65 20 0a 20 20 2a 2a 20 69 73 20  xValue .  ** is 
1db90 6f 6e 65 20 6f 66 20 74 68 65 73 65 20 74 6f 20  one of these to 
1dba0 67 75 61 72 61 6e 74 65 65 20 74 68 61 74 20 69  guarantee that i
1dbb0 74 20 69 73 20 73 61 66 65 20 74 6f 20 69 67 6e  t is safe to ign
1dbc0 6f 72 65 20 74 68 65 20 72 65 74 75 72 6e 20 0a  ore the return .
1dbd0 20 20 2a 2a 20 69 6e 20 74 68 65 20 63 6f 64 65    ** in the code
1dbe0 20 62 65 6c 6f 77 2e 20 2a 2f 0a 20 20 61 73 73   below. */.  ass
1dbf0 65 72 74 28 20 78 56 61 6c 75 65 3d 3d 73 71 6c  ert( xValue==sql
1dc00 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f 6c  ite3changeset_ol
1dc10 64 20 7c 7c 20 78 56 61 6c 75 65 3d 3d 73 71 6c  d || xValue==sql
1dc20 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6e 65  ite3changeset_ne
1dc30 77 20 29 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b  w );..  for(i=0;
1dc40 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
1dc50 26 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a  & i<nCol; i++){.
1dc60 20 20 20 20 69 66 28 20 21 61 62 50 4b 20 7c 7c      if( !abPK ||
1dc70 20 61 62 50 4b 5b 69 5d 20 29 7b 0a 20 20 20 20   abPK[i] ){.    
1dc80 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
1dc90 2a 70 56 61 6c 3b 0a 20 20 20 20 20 20 28 76 6f  *pVal;.      (vo
1dca0 69 64 29 78 56 61 6c 75 65 28 70 49 74 65 72 2c  id)xValue(pIter,
1dcb0 20 69 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20 20   i, &pVal);.    
1dcc0 20 20 69 66 28 20 70 56 61 6c 3d 3d 30 20 29 7b    if( pVal==0 ){
1dcd0 0a 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20  .        /* The 
1dce0 76 61 6c 75 65 20 69 6e 20 74 68 65 20 63 68 61  value in the cha
1dcf0 6e 67 65 73 65 74 20 77 61 73 20 22 75 6e 64 65  ngeset was "unde
1dd00 66 69 6e 65 64 22 2e 20 54 68 69 73 20 69 6e 64  fined". This ind
1dd10 69 63 61 74 65 73 20 61 0a 20 20 20 20 20 20 20  icates a.       
1dd20 20 2a 2a 20 63 6f 72 72 75 70 74 20 63 68 61 6e   ** corrupt chan
1dd30 67 65 73 65 74 20 62 6c 6f 62 2e 20 20 2a 2f 0a  geset blob.  */.
1dd40 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
1dd50 49 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54  ITE_CORRUPT_BKPT
1dd60 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
1dd70 20 20 20 20 20 20 20 72 63 20 3d 20 73 65 73 73         rc = sess
1dd80 69 6f 6e 42 69 6e 64 56 61 6c 75 65 28 70 53 74  ionBindValue(pSt
1dd90 6d 74 2c 20 69 2b 31 2c 20 70 56 61 6c 29 3b 0a  mt, i+1, pVal);.
1dda0 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
1ddb0 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
1ddc0 0a 0a 2f 2a 0a 2a 2a 20 53 51 4c 20 73 74 61 74  ../*.** SQL stat
1ddd0 65 6d 65 6e 74 20 70 53 65 6c 65 63 74 20 69 73  ement pSelect is
1dde0 20 61 73 20 67 65 6e 65 72 61 74 65 64 20 62 79   as generated by
1ddf0 20 74 68 65 20 73 65 73 73 69 6f 6e 53 65 6c 65   the sessionSele
1de00 63 74 52 6f 77 28 29 20 66 75 6e 63 74 69 6f 6e  ctRow() function
1de10 2e 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  ..** This functi
1de20 6f 6e 20 62 69 6e 64 73 20 74 68 65 20 70 72 69  on binds the pri
1de30 6d 61 72 79 20 6b 65 79 20 76 61 6c 75 65 73 20  mary key values 
1de40 66 72 6f 6d 20 74 68 65 20 63 68 61 6e 67 65 20  from the change 
1de50 74 68 61 74 20 63 68 61 6e 67 65 73 65 74 0a 2a  that changeset.*
1de60 2a 20 69 74 65 72 61 74 6f 72 20 70 49 74 65 72  * iterator pIter
1de70 20 70 6f 69 6e 74 73 20 74 6f 20 74 6f 20 74 68   points to to th
1de80 65 20 53 45 4c 45 43 54 20 61 6e 64 20 61 74 74  e SELECT and att
1de90 65 6d 70 74 73 20 74 6f 20 73 65 65 6b 20 74 6f  empts to seek to
1dea0 20 74 68 65 20 74 61 62 6c 65 0a 2a 2a 20 65 6e   the table.** en
1deb0 74 72 79 2e 20 49 66 20 61 20 72 6f 77 20 69 73  try. If a row is
1dec0 20 66 6f 75 6e 64 2c 20 74 68 65 20 53 45 4c 45   found, the SELE
1ded0 43 54 20 73 74 61 74 65 6d 65 6e 74 20 6c 65 66  CT statement lef
1dee0 74 20 70 6f 69 6e 74 69 6e 67 20 61 74 20 74 68  t pointing at th
1def0 65 20 72 6f 77 20 0a 2a 2a 20 61 6e 64 20 53 51  e row .** and SQ
1df00 4c 49 54 45 5f 52 4f 57 20 69 73 20 72 65 74 75  LITE_ROW is retu
1df10 72 6e 65 64 2e 20 4f 74 68 65 72 77 69 73 65 2c  rned. Otherwise,
1df20 20 69 66 20 6e 6f 20 72 6f 77 20 69 73 20 66 6f   if no row is fo
1df30 75 6e 64 20 61 6e 64 20 6e 6f 20 65 72 72 6f 72  und and no error
1df40 0a 2a 2a 20 68 61 73 20 6f 63 63 75 72 65 64 2c  .** has occured,
1df50 20 74 68 65 20 73 74 61 74 65 6d 65 6e 74 20 69   the statement i
1df60 73 20 72 65 73 65 74 20 61 6e 64 20 53 51 4c 49  s reset and SQLI
1df70 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65  TE_OK is returne
1df80 64 2e 20 49 66 20 61 6e 0a 2a 2a 20 65 72 72 6f  d. If an.** erro
1df90 72 20 6f 63 63 75 72 73 2c 20 74 68 65 20 73 74  r occurs, the st
1dfa0 61 74 65 6d 65 6e 74 20 69 73 20 72 65 73 65 74  atement is reset
1dfb0 20 61 6e 64 20 61 6e 20 53 51 4c 69 74 65 20 65   and an SQLite e
1dfc0 72 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74  rror code is ret
1dfd0 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  urned..**.** If 
1dfe0 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72 65  this function re
1dff0 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 52 4f 57  turns SQLITE_ROW
1e000 2c 20 74 68 65 20 63 61 6c 6c 65 72 20 6d 75 73  , the caller mus
1e010 74 20 65 76 65 6e 74 75 61 6c 6c 79 20 72 65 73  t eventually res
1e020 65 74 28 29 20 0a 2a 2a 20 73 74 61 74 65 6d 65  et() .** stateme
1e030 6e 74 20 70 53 65 6c 65 63 74 2e 20 49 66 20 61  nt pSelect. If a
1e040 6e 79 20 6f 74 68 65 72 20 76 61 6c 75 65 20 69  ny other value i
1e050 73 20 72 65 74 75 72 6e 65 64 2c 20 74 68 65 20  s returned, the 
1e060 73 74 61 74 65 6d 65 6e 74 20 64 6f 65 73 0a 2a  statement does.*
1e070 2a 20 6e 6f 74 20 72 65 71 75 69 72 65 20 61 20  * not require a 
1e080 72 65 73 65 74 28 29 2e 0a 2a 2a 0a 2a 2a 20 49  reset()..**.** I
1e090 66 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 63  f the iterator c
1e0a0 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20  urrently points 
1e0b0 74 6f 20 61 6e 20 49 4e 53 45 52 54 20 72 65 63  to an INSERT rec
1e0c0 6f 72 64 2c 20 62 69 6e 64 20 76 61 6c 75 65 73  ord, bind values
1e0d0 20 66 72 6f 6d 20 74 68 65 0a 2a 2a 20 6e 65 77   from the.** new
1e0e0 2e 2a 20 72 65 63 6f 72 64 20 74 6f 20 74 68 65  .* record to the
1e0f0 20 53 45 4c 45 43 54 20 73 74 61 74 65 6d 65 6e   SELECT statemen
1e100 74 2e 20 4f 72 2c 20 69 66 20 69 74 20 70 6f 69  t. Or, if it poi
1e110 6e 74 73 20 74 6f 20 61 20 44 45 4c 45 54 45 20  nts to a DELETE 
1e120 6f 72 0a 2a 2a 20 55 50 44 41 54 45 2c 20 62 69  or.** UPDATE, bi
1e130 6e 64 20 76 61 6c 75 65 73 20 66 72 6f 6d 20 74  nd values from t
1e140 68 65 20 6f 6c 64 2e 2a 20 72 65 63 6f 72 64 2e  he old.* record.
1e150 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20   .*/.static int 
1e160 73 65 73 73 69 6f 6e 53 65 65 6b 54 6f 52 6f 77  sessionSeekToRow
1e170 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
1e180 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e190 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
1e1a0 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 73 71 6c 69  handle */.  sqli
1e1b0 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74  te3_changeset_it
1e1c0 65 72 20 2a 70 49 74 65 72 2c 20 20 2f 2a 20 43  er *pIter,  /* C
1e1d0 68 61 6e 67 65 73 65 74 20 69 74 65 72 61 74 6f  hangeset iterato
1e1e0 72 20 2a 2f 0a 20 20 75 38 20 2a 61 62 50 4b 2c  r */.  u8 *abPK,
1e1f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e200 20 20 20 20 20 20 20 2f 2a 20 50 72 69 6d 61 72         /* Primar
1e210 79 20 6b 65 79 20 66 6c 61 67 73 20 61 72 72 61  y key flags arra
1e220 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73  y */.  sqlite3_s
1e230 74 6d 74 20 2a 70 53 65 6c 65 63 74 20 20 20 20  tmt *pSelect    
1e240 20 20 20 20 20 20 20 2f 2a 20 53 45 4c 45 43 54         /* SELECT
1e250 20 73 74 61 74 65 6d 65 6e 74 20 66 72 6f 6d 20   statement from 
1e260 73 65 73 73 69 6f 6e 53 65 6c 65 63 74 52 6f 77  sessionSelectRow
1e270 28 29 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  () */.){.  int r
1e280 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
1e290 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
1e2a0 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69  turn code */.  i
1e2b0 6e 74 20 6e 43 6f 6c 3b 20 20 20 20 20 20 20 20  nt nCol;        
1e2c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1e2d0 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75  * Number of colu
1e2e0 6d 6e 73 20 69 6e 20 74 61 62 6c 65 20 2a 2f 0a  mns in table */.
1e2f0 20 20 69 6e 74 20 6f 70 3b 20 20 20 20 20 20 20    int op;       
1e300 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e310 20 20 2f 2a 20 43 68 61 6e 67 73 65 74 20 6f 70    /* Changset op
1e320 65 72 61 74 69 6f 6e 20 28 53 51 4c 49 54 45 5f  eration (SQLITE_
1e330 55 50 44 41 54 45 20 65 74 63 2e 29 20 2a 2f 0a  UPDATE etc.) */.
1e340 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44    const char *zD
1e350 75 6d 6d 79 3b 20 20 20 20 20 20 20 20 20 20 20  ummy;           
1e360 20 20 2f 2a 20 55 6e 75 73 65 64 20 2a 2f 0a 0a    /* Unused */..
1e370 20 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73    sqlite3changes
1e380 65 74 5f 6f 70 28 70 49 74 65 72 2c 20 26 7a 44  et_op(pIter, &zD
1e390 75 6d 6d 79 2c 20 26 6e 43 6f 6c 2c 20 26 6f 70  ummy, &nCol, &op
1e3a0 2c 20 30 29 3b 0a 20 20 72 63 20 3d 20 73 65 73  , 0);.  rc = ses
1e3b0 73 69 6f 6e 42 69 6e 64 52 6f 77 28 70 49 74 65  sionBindRow(pIte
1e3c0 72 2c 20 0a 20 20 20 20 20 20 6f 70 3d 3d 53 51  r, .      op==SQ
1e3d0 4c 49 54 45 5f 49 4e 53 45 52 54 20 3f 20 73 71  LITE_INSERT ? sq
1e3e0 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6e  lite3changeset_n
1e3f0 65 77 20 3a 20 73 71 6c 69 74 65 33 63 68 61 6e  ew : sqlite3chan
1e400 67 65 73 65 74 5f 6f 6c 64 2c 0a 20 20 20 20 20  geset_old,.     
1e410 20 6e 43 6f 6c 2c 20 61 62 50 4b 2c 20 70 53 65   nCol, abPK, pSe
1e420 6c 65 63 74 0a 20 20 29 3b 0a 0a 20 20 69 66 28  lect.  );..  if(
1e430 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
1e440 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
1e450 65 33 5f 73 74 65 70 28 70 53 65 6c 65 63 74 29  e3_step(pSelect)
1e460 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
1e470 4c 49 54 45 5f 52 4f 57 20 29 20 72 63 20 3d 20  LITE_ROW ) rc = 
1e480 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70 53  sqlite3_reset(pS
1e490 65 6c 65 63 74 29 3b 0a 20 20 7d 0a 0a 20 20 72  elect);.  }..  r
1e4a0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
1e4b0 2a 2a 20 49 6e 76 6f 6b 65 20 74 68 65 20 63 6f  ** Invoke the co
1e4c0 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65 72 20 66  nflict handler f
1e4d0 6f 72 20 74 68 65 20 63 68 61 6e 67 65 20 74 68  or the change th
1e4e0 61 74 20 74 68 65 20 63 68 61 6e 67 65 73 65 74  at the changeset
1e4f0 20 69 74 65 72 61 74 6f 72 0a 2a 2a 20 63 75 72   iterator.** cur
1e500 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f  rently points to
1e510 2e 0a 2a 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e 74  ..**.** Argument
1e520 20 65 54 79 70 65 20 6d 75 73 74 20 62 65 20 65   eType must be e
1e530 69 74 68 65 72 20 43 48 41 4e 47 45 53 45 54 5f  ither CHANGESET_
1e540 44 41 54 41 20 6f 72 20 43 48 41 4e 47 45 53 45  DATA or CHANGESE
1e550 54 5f 43 4f 4e 46 4c 49 43 54 2e 0a 2a 2a 20 49  T_CONFLICT..** I
1e560 66 20 61 72 67 75 6d 65 6e 74 20 70 62 52 65 70  f argument pbRep
1e570 6c 61 63 65 20 69 73 20 4e 55 4c 4c 2c 20 74 68  lace is NULL, th
1e580 65 6e 20 74 68 65 20 74 79 70 65 20 6f 66 20 63  en the type of c
1e590 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65 72 20  onflict handler 
1e5a0 69 6e 76 6f 6b 65 64 0a 2a 2a 20 64 65 70 65 6e  invoked.** depen
1e5b0 64 73 20 73 6f 6c 65 6c 79 20 6f 6e 20 65 54 79  ds solely on eTy
1e5c0 70 65 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a  pe, as follows:.
1e5d0 2a 2a 0a 2a 2a 20 20 20 20 65 54 79 70 65 20 76  **.**    eType v
1e5e0 61 6c 75 65 20 20 20 20 20 20 20 20 20 20 20 20  alue            
1e5f0 20 20 20 20 20 56 61 6c 75 65 20 70 61 73 73 65       Value passe
1e600 64 20 74 6f 20 78 43 6f 6e 66 6c 69 63 74 0a 2a  d to xConflict.*
1e610 2a 20 20 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  *    -----------
1e620 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1e630 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1e640 2d 2d 2d 2d 2d 2d 0a 2a 2a 20 20 20 20 43 48 41  ------.**    CHA
1e650 4e 47 45 53 45 54 5f 44 41 54 41 20 20 20 20 20  NGESET_DATA     
1e660 20 20 20 20 20 20 20 20 20 43 48 41 4e 47 45 53           CHANGES
1e670 45 54 5f 4e 4f 54 46 4f 55 4e 44 0a 2a 2a 20 20  ET_NOTFOUND.**  
1e680 20 20 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46    CHANGESET_CONF
1e690 4c 49 43 54 20 20 20 20 20 20 20 20 20 20 43 48  LICT          CH
1e6a0 41 4e 47 45 53 45 54 5f 43 4f 4e 53 54 52 41 49  ANGESET_CONSTRAI
1e6b0 4e 54 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 69 66 20  NT.**.** Or, if 
1e6c0 70 62 52 65 70 6c 61 63 65 20 69 73 20 6e 6f 74  pbReplace is not
1e6d0 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 61 6e 20 61   NULL, then an a
1e6e0 74 74 65 6d 70 74 20 69 73 20 6d 61 64 65 20 74  ttempt is made t
1e6f0 6f 20 66 69 6e 64 20 61 6e 20 65 78 69 73 74 69  o find an existi
1e700 6e 67 0a 2a 2a 20 72 65 63 6f 72 64 20 77 69 74  ng.** record wit
1e710 68 20 74 68 65 20 73 61 6d 65 20 70 72 69 6d 61  h the same prima
1e720 72 79 20 6b 65 79 20 61 73 20 74 68 65 20 72 65  ry key as the re
1e730 63 6f 72 64 20 61 62 6f 75 74 20 74 6f 20 62 65  cord about to be
1e740 20 64 65 6c 65 74 65 64 2c 20 75 70 64 61 74 65   deleted, update
1e750 64 0a 2a 2a 20 6f 72 20 69 6e 73 65 72 74 65 64  d.** or inserted
1e760 2e 20 49 66 20 73 75 63 68 20 61 20 72 65 63 6f  . If such a reco
1e770 72 64 20 63 61 6e 20 62 65 20 66 6f 75 6e 64 2c  rd can be found,
1e780 20 69 74 20 69 73 20 61 76 61 69 6c 61 62 6c 65   it is available
1e790 20 74 6f 20 74 68 65 20 63 6f 6e 66 6c 69 63 74   to the conflict
1e7a0 0a 2a 2a 20 68 61 6e 64 6c 65 72 20 61 73 20 74  .** handler as t
1e7b0 68 65 20 22 63 6f 6e 66 6c 69 63 74 69 6e 67 22  he "conflicting"
1e7c0 20 72 65 63 6f 72 64 2e 20 49 6e 20 74 68 69 73   record. In this
1e7d0 20 63 61 73 65 20 74 68 65 20 74 79 70 65 20 6f   case the type o
1e7e0 66 20 63 6f 6e 66 6c 69 63 74 0a 2a 2a 20 68 61  f conflict.** ha
1e7f0 6e 64 6c 65 72 20 69 6e 76 6f 6b 65 64 20 69 73  ndler invoked is
1e800 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a   as follows:.**.
1e810 2a 2a 20 20 20 20 65 54 79 70 65 20 76 61 6c 75  **    eType valu
1e820 65 20 20 20 20 20 20 20 20 20 50 4b 20 52 65 63  e         PK Rec
1e830 6f 72 64 20 66 6f 75 6e 64 3f 20 20 20 56 61 6c  ord found?   Val
1e840 75 65 20 70 61 73 73 65 64 20 74 6f 20 78 43 6f  ue passed to xCo
1e850 6e 66 6c 69 63 74 0a 2a 2a 20 20 20 20 2d 2d 2d  nflict.**    ---
1e860 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1e870 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1e880 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1e890 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 2a 2a  -------------.**
1e8a0 20 20 20 20 43 48 41 4e 47 45 53 45 54 5f 44 41      CHANGESET_DA
1e8b0 54 41 20 20 20 20 20 20 59 65 73 20 20 20 20 20  TA      Yes     
1e8c0 20 20 20 20 20 20 20 20 20 20 20 43 48 41 4e 47             CHANG
1e8d0 45 53 45 54 5f 44 41 54 41 0a 2a 2a 20 20 20 20  ESET_DATA.**    
1e8e0 43 48 41 4e 47 45 53 45 54 5f 44 41 54 41 20 20  CHANGESET_DATA  
1e8f0 20 20 20 20 4e 6f 20 20 20 20 20 20 20 20 20 20      No          
1e900 20 20 20 20 20 20 20 43 48 41 4e 47 45 53 45 54         CHANGESET
1e910 5f 4e 4f 54 46 4f 55 4e 44 0a 2a 2a 20 20 20 20  _NOTFOUND.**    
1e920 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49  CHANGESET_CONFLI
1e930 43 54 20 20 59 65 73 20 20 20 20 20 20 20 20 20  CT  Yes         
1e940 20 20 20 20 20 20 20 43 48 41 4e 47 45 53 45 54         CHANGESET
1e950 5f 43 4f 4e 46 4c 49 43 54 0a 2a 2a 20 20 20 20  _CONFLICT.**    
1e960 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49  CHANGESET_CONFLI
1e970 43 54 20 20 4e 6f 20 20 20 20 20 20 20 20 20 20  CT  No          
1e980 20 20 20 20 20 20 20 43 48 41 4e 47 45 53 45 54         CHANGESET
1e990 5f 43 4f 4e 53 54 52 41 49 4e 54 0a 2a 2a 0a 2a  _CONSTRAINT.**.*
1e9a0 2a 20 49 66 20 70 62 52 65 70 6c 61 63 65 20 69  * If pbReplace i
1e9b0 73 20 6e 6f 74 20 4e 55 4c 4c 2c 20 61 6e 64 20  s not NULL, and 
1e9c0 61 20 72 65 63 6f 72 64 20 77 69 74 68 20 61 20  a record with a 
1e9d0 6d 61 74 63 68 69 6e 67 20 50 4b 20 69 73 20 66  matching PK is f
1e9e0 6f 75 6e 64 2c 20 61 6e 64 0a 2a 2a 20 74 68 65  ound, and.** the
1e9f0 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65   conflict handle
1ea00 72 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72  r function retur
1ea10 6e 73 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45  ns SQLITE_CHANGE
1ea20 53 45 54 5f 52 45 50 4c 41 43 45 2c 20 2a 70 62  SET_REPLACE, *pb
1ea30 52 65 70 6c 61 63 65 0a 2a 2a 20 69 73 20 73 65  Replace.** is se
1ea40 74 20 74 6f 20 6e 6f 6e 2d 7a 65 72 6f 20 62 65  t to non-zero be
1ea50 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 20 53  fore returning S
1ea60 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2a 0a 2a 2a 20  QLITE_OK..**.** 
1ea70 49 66 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 20  If the conflict 
1ea80 68 61 6e 64 6c 65 72 20 72 65 74 75 72 6e 73 20  handler returns 
1ea90 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54  SQLITE_CHANGESET
1eaa0 5f 41 42 4f 52 54 2c 20 53 51 4c 49 54 45 5f 41  _ABORT, SQLITE_A
1eab0 42 4f 52 54 20 69 73 0a 2a 2a 20 72 65 74 75 72  BORT is.** retur
1eac0 6e 65 64 2e 20 4f 72 2c 20 69 66 20 74 68 65 20  ned. Or, if the 
1ead0 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65 72  conflict handler
1eae0 20 72 65 74 75 72 6e 73 20 61 6e 20 69 6e 76 61   returns an inva
1eaf0 6c 69 64 20 76 61 6c 75 65 2c 20 0a 2a 2a 20 53  lid value, .** S
1eb00 51 4c 49 54 45 5f 4d 49 53 55 53 45 2e 20 49 66  QLITE_MISUSE. If
1eb10 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 20 68 61   the conflict ha
1eb20 6e 64 6c 65 72 20 72 65 74 75 72 6e 73 20 53 51  ndler returns SQ
1eb30 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 4f  LITE_CHANGESET_O
1eb40 4d 49 54 2c 0a 2a 2a 20 74 68 69 73 20 66 75 6e  MIT,.** this fun
1eb50 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 53 51  ction returns SQ
1eb60 4c 49 54 45 5f 4f 4b 2e 0a 2a 2f 0a 73 74 61 74  LITE_OK..*/.stat
1eb70 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 43 6f  ic int sessionCo
1eb80 6e 66 6c 69 63 74 48 61 6e 64 6c 65 72 28 0a 20  nflictHandler(. 
1eb90 20 69 6e 74 20 65 54 79 70 65 2c 20 20 20 20 20   int eType,     
1eba0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ebb0 20 2f 2a 20 45 69 74 68 65 72 20 43 48 41 4e 47   /* Either CHANG
1ebc0 45 53 45 54 5f 44 41 54 41 20 6f 72 20 43 4f 4e  ESET_DATA or CON
1ebd0 46 4c 49 43 54 20 2a 2f 0a 20 20 53 65 73 73 69  FLICT */.  Sessi
1ebe0 6f 6e 41 70 70 6c 79 43 74 78 20 2a 70 2c 20 20  onApplyCtx *p,  
1ebf0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 63 68             /* ch
1ec00 61 6e 67 65 73 65 74 5f 61 70 70 6c 79 28 29 20  angeset_apply() 
1ec10 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 73 71 6c  context */.  sql
1ec20 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69  ite3_changeset_i
1ec30 74 65 72 20 2a 70 49 74 65 72 2c 20 20 2f 2a 20  ter *pIter,  /* 
1ec40 43 68 61 6e 67 65 73 65 74 20 69 74 65 72 61 74  Changeset iterat
1ec50 6f 72 20 2a 2f 0a 20 20 69 6e 74 28 2a 78 43 6f  or */.  int(*xCo
1ec60 6e 66 6c 69 63 74 29 28 76 6f 69 64 20 2a 2c 20  nflict)(void *, 
1ec70 69 6e 74 2c 20 73 71 6c 69 74 65 33 5f 63 68 61  int, sqlite3_cha
1ec80 6e 67 65 73 65 74 5f 69 74 65 72 2a 29 2c 0a 20  ngeset_iter*),. 
1ec90 20 76 6f 69 64 20 2a 70 43 74 78 2c 20 20 20 20   void *pCtx,    
1eca0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ecb0 20 2f 2a 20 46 69 72 73 74 20 61 72 67 75 6d 65   /* First argume
1ecc0 6e 74 20 66 6f 72 20 63 6f 6e 66 6c 69 63 74 20  nt for conflict 
1ecd0 68 61 6e 64 6c 65 72 20 2a 2f 0a 20 20 69 6e 74  handler */.  int
1ece0 20 2a 70 62 52 65 70 6c 61 63 65 20 20 20 20 20   *pbReplace     
1ecf0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1ed00 4f 55 54 3a 20 53 65 74 20 74 6f 20 74 72 75 65  OUT: Set to true
1ed10 20 69 66 20 50 4b 20 72 6f 77 20 69 73 20 66 6f   if PK row is fo
1ed20 75 6e 64 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  und */.){.  int 
1ed30 72 65 73 20 3d 20 30 3b 20 20 20 20 20 20 20 20  res = 0;        
1ed40 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56              /* V
1ed50 61 6c 75 65 20 72 65 74 75 72 6e 65 64 20 62 79  alue returned by
1ed60 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65   conflict handle
1ed70 72 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 0a 20  r */.  int rc;. 
1ed80 20 69 6e 74 20 6e 43 6f 6c 3b 0a 20 20 69 6e 74   int nCol;.  int
1ed90 20 6f 70 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61   op;.  const cha
1eda0 72 20 2a 7a 44 75 6d 6d 79 3b 0a 0a 20 20 73 71  r *zDummy;..  sq
1edb0 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f  lite3changeset_o
1edc0 70 28 70 49 74 65 72 2c 20 26 7a 44 75 6d 6d 79  p(pIter, &zDummy
1edd0 2c 20 26 6e 43 6f 6c 2c 20 26 6f 70 2c 20 30 29  , &nCol, &op, 0)
1ede0 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 65 54 79  ;..  assert( eTy
1edf0 70 65 3d 3d 53 51 4c 49 54 45 5f 43 48 41 4e 47  pe==SQLITE_CHANG
1ee00 45 53 45 54 5f 43 4f 4e 46 4c 49 43 54 20 7c 7c  ESET_CONFLICT ||
1ee10 20 65 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 43   eType==SQLITE_C
1ee20 48 41 4e 47 45 53 45 54 5f 44 41 54 41 20 29 3b  HANGESET_DATA );
1ee30 0a 20 20 61 73 73 65 72 74 28 20 53 51 4c 49 54  .  assert( SQLIT
1ee40 45 5f 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46  E_CHANGESET_CONF
1ee50 4c 49 43 54 2b 31 3d 3d 53 51 4c 49 54 45 5f 43  LICT+1==SQLITE_C
1ee60 48 41 4e 47 45 53 45 54 5f 43 4f 4e 53 54 52 41  HANGESET_CONSTRA
1ee70 49 4e 54 20 29 3b 0a 20 20 61 73 73 65 72 74 28  INT );.  assert(
1ee80 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45   SQLITE_CHANGESE
1ee90 54 5f 44 41 54 41 2b 31 3d 3d 53 51 4c 49 54 45  T_DATA+1==SQLITE
1eea0 5f 43 48 41 4e 47 45 53 45 54 5f 4e 4f 54 46 4f  _CHANGESET_NOTFO
1eeb0 55 4e 44 20 29 3b 0a 0a 20 20 2f 2a 20 42 69 6e  UND );..  /* Bin
1eec0 64 20 74 68 65 20 6e 65 77 2e 2a 20 50 52 49 4d  d the new.* PRIM
1eed0 41 52 59 20 4b 45 59 20 76 61 6c 75 65 73 20 74  ARY KEY values t
1eee0 6f 20 74 68 65 20 53 45 4c 45 43 54 20 73 74 61  o the SELECT sta
1eef0 74 65 6d 65 6e 74 2e 20 2a 2f 0a 20 20 69 66 28  tement. */.  if(
1ef00 20 70 62 52 65 70 6c 61 63 65 20 29 7b 0a 20 20   pbReplace ){.  
1ef10 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 53 65    rc = sessionSe
1ef20 65 6b 54 6f 52 6f 77 28 70 2d 3e 64 62 2c 20 70  ekToRow(p->db, p
1ef30 49 74 65 72 2c 20 70 2d 3e 61 62 50 4b 2c 20 70  Iter, p->abPK, p
1ef40 2d 3e 70 53 65 6c 65 63 74 29 3b 0a 20 20 7d 65  ->pSelect);.  }e
1ef50 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  lse{.    rc = SQ
1ef60 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20  LITE_OK;.  }..  
1ef70 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52  if( rc==SQLITE_R
1ef80 4f 57 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 65  OW ){.    /* The
1ef90 72 65 20 65 78 69 73 74 73 20 61 6e 6f 74 68 65  re exists anothe
1efa0 72 20 72 6f 77 20 77 69 74 68 20 74 68 65 20 6e  r row with the n
1efb0 65 77 2e 2a 20 70 72 69 6d 61 72 79 20 6b 65 79  ew.* primary key
1efc0 2e 20 2a 2f 0a 20 20 20 20 70 49 74 65 72 2d 3e  . */.    pIter->
1efd0 70 43 6f 6e 66 6c 69 63 74 20 3d 20 70 2d 3e 70  pConflict = p->p
1efe0 53 65 6c 65 63 74 3b 0a 20 20 20 20 72 65 73 20  Select;.    res 
1eff0 3d 20 78 43 6f 6e 66 6c 69 63 74 28 70 43 74 78  = xConflict(pCtx
1f000 2c 20 65 54 79 70 65 2c 20 70 49 74 65 72 29 3b  , eType, pIter);
1f010 0a 20 20 20 20 70 49 74 65 72 2d 3e 70 43 6f 6e  .    pIter->pCon
1f020 66 6c 69 63 74 20 3d 20 30 3b 0a 20 20 20 20 72  flict = 0;.    r
1f030 63 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65  c = sqlite3_rese
1f040 74 28 70 2d 3e 70 53 65 6c 65 63 74 29 3b 0a 20  t(p->pSelect);. 
1f050 20 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d 53   }else if( rc==S
1f060 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
1f070 69 66 28 20 70 2d 3e 62 44 65 66 65 72 43 6f 6e  if( p->bDeferCon
1f080 73 74 72 61 69 6e 74 73 20 26 26 20 65 54 79 70  straints && eTyp
1f090 65 3d 3d 53 51 4c 49 54 45 5f 43 48 41 4e 47 45  e==SQLITE_CHANGE
1f0a0 53 45 54 5f 43 4f 4e 46 4c 49 43 54 20 29 7b 0a  SET_CONFLICT ){.
1f0b0 20 20 20 20 20 20 2f 2a 20 49 6e 73 74 65 61 64        /* Instead
1f0c0 20 6f 66 20 69 6e 76 6f 6b 69 6e 67 20 74 68 65   of invoking the
1f0d0 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65   conflict handle
1f0e0 72 2c 20 61 70 70 65 6e 64 20 74 68 65 20 63 68  r, append the ch
1f0f0 61 6e 67 65 20 62 6c 6f 62 0a 20 20 20 20 20 20  ange blob.      
1f100 2a 2a 20 74 6f 20 74 68 65 20 53 65 73 73 69 6f  ** to the Sessio
1f110 6e 41 70 70 6c 79 43 74 78 2e 63 6f 6e 73 74 72  nApplyCtx.constr
1f120 61 69 6e 74 73 20 62 75 66 66 65 72 2e 20 2a 2f  aints buffer. */
1f130 0a 20 20 20 20 20 20 75 38 20 2a 61 42 6c 6f 62  .      u8 *aBlob
1f140 20 3d 20 26 70 49 74 65 72 2d 3e 69 6e 2e 61 44   = &pIter->in.aD
1f150 61 74 61 5b 70 49 74 65 72 2d 3e 69 6e 2e 69 43  ata[pIter->in.iC
1f160 75 72 72 65 6e 74 5d 3b 0a 20 20 20 20 20 20 69  urrent];.      i
1f170 6e 74 20 6e 42 6c 6f 62 20 3d 20 70 49 74 65 72  nt nBlob = pIter
1f180 2d 3e 69 6e 2e 69 4e 65 78 74 20 2d 20 70 49 74  ->in.iNext - pIt
1f190 65 72 2d 3e 69 6e 2e 69 43 75 72 72 65 6e 74 3b  er->in.iCurrent;
1f1a0 0a 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70  .      sessionAp
1f1b0 70 65 6e 64 42 6c 6f 62 28 26 70 2d 3e 63 6f 6e  pendBlob(&p->con
1f1c0 73 74 72 61 69 6e 74 73 2c 20 61 42 6c 6f 62 2c  straints, aBlob,
1f1d0 20 6e 42 6c 6f 62 2c 20 26 72 63 29 3b 0a 20 20   nBlob, &rc);.  
1f1e0 20 20 20 20 72 65 73 20 3d 20 53 51 4c 49 54 45      res = SQLITE
1f1f0 5f 43 48 41 4e 47 45 53 45 54 5f 4f 4d 49 54 3b  _CHANGESET_OMIT;
1f200 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
1f210 20 20 2f 2a 20 4e 6f 20 6f 74 68 65 72 20 72 6f    /* No other ro
1f220 77 20 77 69 74 68 20 74 68 65 20 6e 65 77 2e 2a  w with the new.*
1f230 20 70 72 69 6d 61 72 79 20 6b 65 79 2e 20 2a 2f   primary key. */
1f240 0a 20 20 20 20 20 20 72 65 73 20 3d 20 78 43 6f  .      res = xCo
1f250 6e 66 6c 69 63 74 28 70 43 74 78 2c 20 65 54 79  nflict(pCtx, eTy
1f260 70 65 2b 31 2c 20 70 49 74 65 72 29 3b 0a 20 20  pe+1, pIter);.  
1f270 20 20 20 20 69 66 28 20 72 65 73 3d 3d 53 51 4c      if( res==SQL
1f280 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 52 45  ITE_CHANGESET_RE
1f290 50 4c 41 43 45 20 29 20 72 63 20 3d 20 53 51 4c  PLACE ) rc = SQL
1f2a0 49 54 45 5f 4d 49 53 55 53 45 3b 0a 20 20 20 20  ITE_MISUSE;.    
1f2b0 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  }.  }..  if( rc=
1f2c0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
1f2d0 20 20 73 77 69 74 63 68 28 20 72 65 73 20 29 7b    switch( res ){
1f2e0 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
1f2f0 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 52 45 50  TE_CHANGESET_REP
1f300 4c 41 43 45 3a 0a 20 20 20 20 20 20 20 20 61 73  LACE:.        as
1f310 73 65 72 74 28 20 70 62 52 65 70 6c 61 63 65 20  sert( pbReplace 
1f320 29 3b 0a 20 20 20 20 20 20 20 20 2a 70 62 52 65  );.        *pbRe
1f330 70 6c 61 63 65 20 3d 20 31 3b 0a 20 20 20 20 20  place = 1;.     
1f340 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20     break;..     
1f350 20 63 61 73 65 20 53 51 4c 49 54 45 5f 43 48 41   case SQLITE_CHA
1f360 4e 47 45 53 45 54 5f 4f 4d 49 54 3a 0a 20 20 20  NGESET_OMIT:.   
1f370 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20       break;..   
1f380 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 43     case SQLITE_C
1f390 48 41 4e 47 45 53 45 54 5f 41 42 4f 52 54 3a 0a  HANGESET_ABORT:.
1f3a0 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
1f3b0 49 54 45 5f 41 42 4f 52 54 3b 0a 20 20 20 20 20  ITE_ABORT;.     
1f3c0 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20     break;..     
1f3d0 20 64 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20   default:.      
1f3e0 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4d 49    rc = SQLITE_MI
1f3f0 53 55 53 45 3b 0a 20 20 20 20 20 20 20 20 62 72  SUSE;.        br
1f400 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  eak;.    }.  }..
1f410 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
1f420 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74 20 74 6f  /*.** Attempt to
1f430 20 61 70 70 6c 79 20 74 68 65 20 63 68 61 6e 67   apply the chang
1f440 65 20 74 68 61 74 20 74 68 65 20 69 74 65 72 61  e that the itera
1f450 74 6f 72 20 70 61 73 73 65 64 20 61 73 20 74 68  tor passed as th
1f460 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
1f470 0a 2a 2a 20 63 75 72 72 65 6e 74 6c 79 20 70 6f  .** currently po
1f480 69 6e 74 73 20 74 6f 20 74 6f 20 74 68 65 20 64  ints to to the d
1f490 61 74 61 62 61 73 65 2e 20 49 66 20 61 20 63 6f  atabase. If a co
1f4a0 6e 66 6c 69 63 74 20 69 73 20 65 6e 63 6f 75 6e  nflict is encoun
1f4b0 74 65 72 65 64 2c 20 69 6e 76 6f 6b 65 0a 2a 2a  tered, invoke.**
1f4c0 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 20 68 61   the conflict ha
1f4d0 6e 64 6c 65 72 20 63 61 6c 6c 62 61 63 6b 2e 0a  ndler callback..
1f4e0 2a 2a 0a 2a 2a 20 49 66 20 61 72 67 75 6d 65 6e  **.** If argumen
1f4f0 74 20 70 62 52 65 74 72 79 20 69 73 20 4e 55 4c  t pbRetry is NUL
1f500 4c 2c 20 74 68 65 6e 20 69 67 6e 6f 72 65 20 61  L, then ignore a
1f510 6e 79 20 43 48 41 4e 47 45 53 45 54 5f 44 41 54  ny CHANGESET_DAT
1f520 41 20 63 6f 6e 66 6c 69 63 74 2e 20 49 66 0a 2a  A conflict. If.*
1f530 2a 20 6f 6e 65 20 69 73 20 65 6e 63 6f 75 6e 74  * one is encount
1f540 65 72 65 64 2c 20 75 70 64 61 74 65 20 6f 72 20  ered, update or 
1f550 64 65 6c 65 74 65 20 74 68 65 20 72 6f 77 20 77  delete the row w
1f560 69 74 68 20 74 68 65 20 6d 61 74 63 68 69 6e 67  ith the matching
1f570 20 70 72 69 6d 61 72 79 20 6b 65 79 0a 2a 2a 20   primary key.** 
1f580 69 6e 73 74 65 61 64 2e 20 4f 72 2c 20 69 66 20  instead. Or, if 
1f590 70 62 52 65 74 72 79 20 69 73 20 6e 6f 74 20 4e  pbRetry is not N
1f5a0 55 4c 4c 20 61 6e 64 20 61 20 43 48 41 4e 47 45  ULL and a CHANGE
1f5b0 53 45 54 5f 44 41 54 41 20 63 6f 6e 66 6c 69 63  SET_DATA conflic
1f5c0 74 20 6f 63 63 75 72 73 2c 0a 2a 2a 20 69 6e 76  t occurs,.** inv
1f5d0 6f 6b 65 20 74 68 65 20 63 6f 6e 66 6c 69 63 74  oke the conflict
1f5e0 20 68 61 6e 64 6c 65 72 2e 20 49 66 20 69 74 20   handler. If it 
1f5f0 72 65 74 75 72 6e 73 20 43 48 41 4e 47 45 53 45  returns CHANGESE
1f600 54 5f 52 45 50 4c 41 43 45 2c 20 73 65 74 20 2a  T_REPLACE, set *
1f610 70 62 52 65 74 72 79 0a 2a 2a 20 74 6f 20 74 72  pbRetry.** to tr
1f620 75 65 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e  ue before return
1f630 69 6e 67 2e 20 49 6e 20 74 68 69 73 20 63 61 73  ing. In this cas
1f640 65 20 74 68 65 20 63 61 6c 6c 65 72 20 77 69 6c  e the caller wil
1f650 6c 20 69 6e 76 6f 6b 65 20 74 68 69 73 20 66 75  l invoke this fu
1f660 6e 63 74 69 6f 6e 0a 2a 2a 20 61 67 61 69 6e 2c  nction.** again,
1f670 20 74 68 69 73 20 74 69 6d 65 20 77 69 74 68 20   this time with 
1f680 70 62 52 65 74 72 79 20 73 65 74 20 74 6f 20 4e  pbRetry set to N
1f690 55 4c 4c 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 72  ULL..**.** If ar
1f6a0 67 75 6d 65 6e 74 20 70 62 52 65 70 6c 61 63 65  gument pbReplace
1f6b0 20 69 73 20 4e 55 4c 4c 20 61 6e 64 20 61 20 43   is NULL and a C
1f6c0 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49 43  HANGESET_CONFLIC
1f6d0 54 20 63 6f 6e 66 6c 69 63 74 20 69 73 20 0a 2a  T conflict is .*
1f6e0 2a 20 65 6e 63 6f 75 6e 74 65 72 65 64 20 69 6e  * encountered in
1f6f0 76 6f 6b 65 20 74 68 65 20 63 6f 6e 66 6c 69 63  voke the conflic
1f700 74 20 68 61 6e 64 6c 65 72 20 77 69 74 68 20 43  t handler with C
1f710 48 41 4e 47 45 53 45 54 5f 43 4f 4e 53 54 52 41  HANGESET_CONSTRA
1f720 49 4e 54 20 69 6e 73 74 65 61 64 2e 0a 2a 2a 20  INT instead..** 
1f730 4f 72 2c 20 69 66 20 70 62 52 65 70 6c 61 63 65  Or, if pbReplace
1f740 20 69 73 20 6e 6f 74 20 4e 55 4c 4c 2c 20 69 6e   is not NULL, in
1f750 76 6f 6b 65 20 69 74 20 77 69 74 68 20 43 48 41  voke it with CHA
1f760 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49 43 54 2e  NGESET_CONFLICT.
1f770 20 49 66 20 73 75 63 68 0a 2a 2a 20 61 6e 20 69   If such.** an i
1f780 6e 76 6f 63 61 74 69 6f 6e 20 72 65 74 75 72 6e  nvocation return
1f790 73 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53  s SQLITE_CHANGES
1f7a0 45 54 5f 52 45 50 4c 41 43 45 2c 20 73 65 74 20  ET_REPLACE, set 
1f7b0 2a 70 62 52 65 70 6c 61 63 65 20 74 6f 20 74 72  *pbReplace to tr
1f7c0 75 65 0a 2a 2a 20 62 65 66 6f 72 65 20 72 65 74  ue.** before ret
1f7d0 72 79 69 6e 67 2e 20 49 6e 20 74 68 69 73 20 63  rying. In this c
1f7e0 61 73 65 20 74 68 65 20 63 61 6c 6c 65 72 20 61  ase the caller a
1f7f0 74 74 65 6d 70 74 73 20 74 6f 20 72 65 6d 6f 76  ttempts to remov
1f800 65 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 69 6e  e the conflictin
1f810 67 0a 2a 2a 20 72 6f 77 20 62 65 66 6f 72 65 20  g.** row before 
1f820 69 6e 76 6f 6b 69 6e 67 20 74 68 69 73 20 66 75  invoking this fu
1f830 6e 63 74 69 6f 6e 20 61 67 61 69 6e 2c 20 74 68  nction again, th
1f840 69 73 20 74 69 6d 65 20 77 69 74 68 20 70 62 52  is time with pbR
1f850 65 70 6c 61 63 65 20 73 65 74 20 0a 2a 2a 20 74  eplace set .** t
1f860 6f 20 4e 55 4c 4c 2e 0a 2a 2a 0a 2a 2a 20 49 66  o NULL..**.** If
1f870 20 61 6e 79 20 63 6f 6e 66 6c 69 63 74 20 68 61   any conflict ha
1f880 6e 64 6c 65 72 20 72 65 74 75 72 6e 73 20 53 51  ndler returns SQ
1f890 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 41  LITE_CHANGESET_A
1f8a0 42 4f 52 54 2c 20 74 68 69 73 20 66 75 6e 63 74  BORT, this funct
1f8b0 69 6f 6e 0a 2a 2a 20 72 65 74 75 72 6e 73 20 53  ion.** returns S
1f8c0 51 4c 49 54 45 5f 41 42 4f 52 54 2e 20 4f 74 68  QLITE_ABORT. Oth
1f8d0 65 72 77 69 73 65 2c 20 69 66 20 6e 6f 20 65 72  erwise, if no er
1f8e0 72 6f 72 20 6f 63 63 75 72 73 2c 20 53 51 4c 49  ror occurs, SQLI
1f8f0 54 45 5f 4f 4b 20 69 73 20 0a 2a 2a 20 72 65 74  TE_OK is .** ret
1f900 75 72 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  urned..*/.static
1f910 20 69 6e 74 20 73 65 73 73 69 6f 6e 41 70 70 6c   int sessionAppl
1f920 79 4f 6e 65 4f 70 28 0a 20 20 73 71 6c 69 74 65  yOneOp(.  sqlite
1f930 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72  3_changeset_iter
1f940 20 2a 70 49 74 65 72 2c 20 20 2f 2a 20 43 68 61   *pIter,  /* Cha
1f950 6e 67 65 73 65 74 20 69 74 65 72 61 74 6f 72 20  ngeset iterator 
1f960 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 41 70 70 6c  */.  SessionAppl
1f970 79 43 74 78 20 2a 70 2c 20 20 20 20 20 20 20 20  yCtx *p,        
1f980 20 20 20 20 20 2f 2a 20 63 68 61 6e 67 65 73 65       /* changese
1f990 74 5f 61 70 70 6c 79 28 29 20 63 6f 6e 74 65 78  t_apply() contex
1f9a0 74 20 2a 2f 0a 20 20 69 6e 74 28 2a 78 43 6f 6e  t */.  int(*xCon
1f9b0 66 6c 69 63 74 29 28 76 6f 69 64 20 2a 2c 20 69  flict)(void *, i
1f9c0 6e 74 2c 20 73 71 6c 69 74 65 33 5f 63 68 61 6e  nt, sqlite3_chan
1f9d0 67 65 73 65 74 5f 69 74 65 72 20 2a 29 2c 0a 20  geset_iter *),. 
1f9e0 20 76 6f 69 64 20 2a 70 43 74 78 2c 20 20 20 20   void *pCtx,    
1f9f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fa00 20 2f 2a 20 46 69 72 73 74 20 61 72 67 75 6d 65   /* First argume
1fa10 6e 74 20 66 6f 72 20 74 68 65 20 63 6f 6e 66 6c  nt for the confl
1fa20 69 63 74 20 68 61 6e 64 6c 65 72 20 2a 2f 0a 20  ict handler */. 
1fa30 20 69 6e 74 20 2a 70 62 52 65 70 6c 61 63 65 2c   int *pbReplace,
1fa40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fa50 20 2f 2a 20 4f 55 54 3a 20 54 72 75 65 20 74 6f   /* OUT: True to
1fa60 20 72 65 6d 6f 76 65 20 50 4b 20 72 6f 77 20 61   remove PK row a
1fa70 6e 64 20 72 65 74 72 79 20 2a 2f 0a 20 20 69 6e  nd retry */.  in
1fa80 74 20 2a 70 62 52 65 74 72 79 20 20 20 20 20 20  t *pbRetry      
1fa90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1faa0 20 4f 55 54 3a 20 54 72 75 65 20 74 6f 20 72 65   OUT: True to re
1fab0 74 72 79 2e 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e  try. */.){.  con
1fac0 73 74 20 63 68 61 72 20 2a 7a 44 75 6d 6d 79 3b  st char *zDummy;
1fad0 0a 20 20 69 6e 74 20 6f 70 3b 0a 20 20 69 6e 74  .  int op;.  int
1fae0 20 6e 43 6f 6c 3b 0a 20 20 69 6e 74 20 72 63 20   nCol;.  int rc 
1faf0 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20  = SQLITE_OK;..  
1fb00 61 73 73 65 72 74 28 20 70 2d 3e 70 44 65 6c 65  assert( p->pDele
1fb10 74 65 20 26 26 20 70 2d 3e 70 55 70 64 61 74 65  te && p->pUpdate
1fb20 20 26 26 20 70 2d 3e 70 49 6e 73 65 72 74 20 26   && p->pInsert &
1fb30 26 20 70 2d 3e 70 53 65 6c 65 63 74 20 29 3b 0a  & p->pSelect );.
1fb40 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61 7a 43    assert( p->azC
1fb50 6f 6c 20 26 26 20 70 2d 3e 61 62 50 4b 20 29 3b  ol && p->abPK );
1fb60 0a 20 20 61 73 73 65 72 74 28 20 21 70 62 52 65  .  assert( !pbRe
1fb70 70 6c 61 63 65 20 7c 7c 20 2a 70 62 52 65 70 6c  place || *pbRepl
1fb80 61 63 65 3d 3d 30 20 29 3b 0a 0a 20 20 73 71 6c  ace==0 );..  sql
1fb90 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f 70  ite3changeset_op
1fba0 28 70 49 74 65 72 2c 20 26 7a 44 75 6d 6d 79 2c  (pIter, &zDummy,
1fbb0 20 26 6e 43 6f 6c 2c 20 26 6f 70 2c 20 30 29 3b   &nCol, &op, 0);
1fbc0 0a 0a 20 20 69 66 28 20 6f 70 3d 3d 53 51 4c 49  ..  if( op==SQLI
1fbd0 54 45 5f 44 45 4c 45 54 45 20 29 7b 0a 0a 20 20  TE_DELETE ){..  
1fbe0 20 20 2f 2a 20 42 69 6e 64 20 76 61 6c 75 65 73    /* Bind values
1fbf0 20 74 6f 20 74 68 65 20 44 45 4c 45 54 45 20 73   to the DELETE s
1fc00 74 61 74 65 6d 65 6e 74 2e 20 49 66 20 63 6f 6e  tatement. If con
1fc10 66 6c 69 63 74 20 68 61 6e 64 6c 69 6e 67 20 69  flict handling i
1fc20 73 20 72 65 71 75 69 72 65 64 2c 0a 20 20 20 20  s required,.    
1fc30 2a 2a 20 62 69 6e 64 20 76 61 6c 75 65 73 20 66  ** bind values f
1fc40 6f 72 20 61 6c 6c 20 63 6f 6c 75 6d 6e 73 20 61  or all columns a
1fc50 6e 64 20 73 65 74 20 62 6f 75 6e 64 20 76 61 72  nd set bound var
1fc60 69 61 62 6c 65 20 28 6e 43 6f 6c 2b 31 29 20 74  iable (nCol+1) t
1fc70 6f 20 74 72 75 65 2e 0a 20 20 20 20 2a 2a 20 4f  o true..    ** O
1fc80 72 2c 20 69 66 20 63 6f 6e 66 6c 69 63 74 20 68  r, if conflict h
1fc90 61 6e 64 6c 69 6e 67 20 69 73 20 6e 6f 74 20 72  andling is not r
1fca0 65 71 75 69 72 65 64 2c 20 62 69 6e 64 20 6a 75  equired, bind ju
1fcb0 73 74 20 74 68 65 20 50 4b 20 63 6f 6c 75 6d 6e  st the PK column
1fcc0 0a 20 20 20 20 2a 2a 20 76 61 6c 75 65 73 20 61  .    ** values a
1fcd0 6e 64 2c 20 69 66 20 69 74 20 65 78 69 73 74 73  nd, if it exists
1fce0 2c 20 73 65 74 20 28 6e 43 6f 6c 2b 31 29 20 74  , set (nCol+1) t
1fcf0 6f 20 66 61 6c 73 65 2e 20 43 6f 6e 66 6c 69 63  o false. Conflic
1fd00 74 20 68 61 6e 64 6c 69 6e 67 0a 20 20 20 20 2a  t handling.    *
1fd10 2a 20 69 73 20 6e 6f 74 20 72 65 71 75 69 72 65  * is not require
1fd20 64 20 69 66 3a 0a 20 20 20 20 2a 2a 0a 20 20 20  d if:.    **.   
1fd30 20 2a 2a 20 20 20 2a 20 74 68 69 73 20 69 73 20   **   * this is 
1fd40 61 20 70 61 74 63 68 73 65 74 2c 20 6f 72 0a 20  a patchset, or. 
1fd50 20 20 20 2a 2a 20 20 20 2a 20 28 70 62 52 65 74     **   * (pbRet
1fd60 72 79 3d 3d 30 29 2c 20 6f 72 0a 20 20 20 20 2a  ry==0), or.    *
1fd70 2a 20 20 20 2a 20 61 6c 6c 20 63 6f 6c 75 6d 6e  *   * all column
1fd80 73 20 6f 66 20 74 68 65 20 74 61 62 6c 65 20 61  s of the table a
1fd90 72 65 20 50 4b 20 63 6f 6c 75 6d 6e 73 20 28 69  re PK columns (i
1fda0 6e 20 74 68 69 73 20 63 61 73 65 20 74 68 65 72  n this case ther
1fdb0 65 20 69 73 0a 20 20 20 20 2a 2a 20 20 20 20 20  e is.    **     
1fdc0 6e 6f 20 28 6e 43 6f 6c 2b 31 29 20 76 61 72 69  no (nCol+1) vari
1fdd0 61 62 6c 65 20 74 6f 20 62 69 6e 64 20 74 6f 29  able to bind to)
1fde0 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 75 38 20  ..    */.    u8 
1fdf0 2a 61 62 50 4b 20 3d 20 28 70 49 74 65 72 2d 3e  *abPK = (pIter->
1fe00 62 50 61 74 63 68 73 65 74 20 3f 20 70 2d 3e 61  bPatchset ? p->a
1fe10 62 50 4b 20 3a 20 30 29 3b 0a 20 20 20 20 72 63  bPK : 0);.    rc
1fe20 20 3d 20 73 65 73 73 69 6f 6e 42 69 6e 64 52 6f   = sessionBindRo
1fe30 77 28 70 49 74 65 72 2c 20 73 71 6c 69 74 65 33  w(pIter, sqlite3
1fe40 63 68 61 6e 67 65 73 65 74 5f 6f 6c 64 2c 20 6e  changeset_old, n
1fe50 43 6f 6c 2c 20 61 62 50 4b 2c 20 70 2d 3e 70 44  Col, abPK, p->pD
1fe60 65 6c 65 74 65 29 3b 0a 20 20 20 20 69 66 28 20  elete);.    if( 
1fe70 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
1fe80 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 70 61   sqlite3_bind_pa
1fe90 72 61 6d 65 74 65 72 5f 63 6f 75 6e 74 28 70 2d  rameter_count(p-
1fea0 3e 70 44 65 6c 65 74 65 29 3e 6e 43 6f 6c 20 29  >pDelete)>nCol )
1feb0 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  {.      rc = sql
1fec0 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 28 70 2d  ite3_bind_int(p-
1fed0 3e 70 44 65 6c 65 74 65 2c 20 6e 43 6f 6c 2b 31  >pDelete, nCol+1
1fee0 2c 20 28 70 62 52 65 74 72 79 3d 3d 30 20 7c 7c  , (pbRetry==0 ||
1fef0 20 61 62 50 4b 29 29 3b 0a 20 20 20 20 7d 0a 20   abPK));.    }. 
1ff00 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
1ff10 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  E_OK ) return rc
1ff20 3b 0a 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73  ;..    sqlite3_s
1ff30 74 65 70 28 70 2d 3e 70 44 65 6c 65 74 65 29 3b  tep(p->pDelete);
1ff40 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
1ff50 33 5f 72 65 73 65 74 28 70 2d 3e 70 44 65 6c 65  3_reset(p->pDele
1ff60 74 65 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d  te);.    if( rc=
1ff70 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 73 71  =SQLITE_OK && sq
1ff80 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 28 70 2d  lite3_changes(p-
1ff90 3e 64 62 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  >db)==0 ){.     
1ffa0 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 43 6f 6e   rc = sessionCon
1ffb0 66 6c 69 63 74 48 61 6e 64 6c 65 72 28 0a 20 20  flictHandler(.  
1ffc0 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 43          SQLITE_C
1ffd0 48 41 4e 47 45 53 45 54 5f 44 41 54 41 2c 20 70  HANGESET_DATA, p
1ffe0 2c 20 70 49 74 65 72 2c 20 78 43 6f 6e 66 6c 69  , pIter, xConfli
1fff0 63 74 2c 20 70 43 74 78 2c 20 70 62 52 65 74 72  ct, pCtx, pbRetr
20000 79 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d  y.      );.    }
20010 65 6c 73 65 20 69 66 28 20 28 72 63 26 30 78 66  else if( (rc&0xf
20020 66 29 3d 3d 53 51 4c 49 54 45 5f 43 4f 4e 53 54  f)==SQLITE_CONST
20030 52 41 49 4e 54 20 29 7b 0a 20 20 20 20 20 20 72  RAINT ){.      r
20040 63 20 3d 20 73 65 73 73 69 6f 6e 43 6f 6e 66 6c  c = sessionConfl
20050 69 63 74 48 61 6e 64 6c 65 72 28 0a 20 20 20 20  ictHandler(.    
20060 20 20 20 20 20 20 53 51 4c 49 54 45 5f 43 48 41        SQLITE_CHA
20070 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49 43 54 2c  NGESET_CONFLICT,
20080 20 70 2c 20 70 49 74 65 72 2c 20 78 43 6f 6e 66   p, pIter, xConf
20090 6c 69 63 74 2c 20 70 43 74 78 2c 20 30 0a 20 20  lict, pCtx, 0.  
200a0 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 0a 20 20      );.    }..  
200b0 7d 65 6c 73 65 20 69 66 28 20 6f 70 3d 3d 53 51  }else if( op==SQ
200c0 4c 49 54 45 5f 55 50 44 41 54 45 20 29 7b 0a 20  LITE_UPDATE ){. 
200d0 20 20 20 69 6e 74 20 69 3b 0a 0a 20 20 20 20 2f     int i;..    /
200e0 2a 20 42 69 6e 64 20 76 61 6c 75 65 73 20 74 6f  * Bind values to
200f0 20 74 68 65 20 55 50 44 41 54 45 20 73 74 61 74   the UPDATE stat
20100 65 6d 65 6e 74 2e 20 2a 2f 0a 20 20 20 20 66 6f  ement. */.    fo
20110 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54  r(i=0; rc==SQLIT
20120 45 5f 4f 4b 20 26 26 20 69 3c 6e 43 6f 6c 3b 20  E_OK && i<nCol; 
20130 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73 71 6c 69  i++){.      sqli
20140 74 65 33 5f 76 61 6c 75 65 20 2a 70 4f 6c 64 20  te3_value *pOld 
20150 3d 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73  = sessionChanges
20160 65 74 4f 6c 64 28 70 49 74 65 72 2c 20 69 29 3b  etOld(pIter, i);
20170 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76  .      sqlite3_v
20180 61 6c 75 65 20 2a 70 4e 65 77 20 3d 20 73 65 73  alue *pNew = ses
20190 73 69 6f 6e 43 68 61 6e 67 65 73 65 74 4e 65 77  sionChangesetNew
201a0 28 70 49 74 65 72 2c 20 69 29 3b 0a 0a 20 20 20  (pIter, i);..   
201b0 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f     sqlite3_bind_
201c0 69 6e 74 28 70 2d 3e 70 55 70 64 61 74 65 2c 20  int(p->pUpdate, 
201d0 69 2a 33 2b 32 2c 20 21 21 70 4e 65 77 29 3b 0a  i*3+2, !!pNew);.
201e0 20 20 20 20 20 20 69 66 28 20 70 4f 6c 64 20 29        if( pOld )
201f0 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73  {.        rc = s
20200 65 73 73 69 6f 6e 42 69 6e 64 56 61 6c 75 65 28  essionBindValue(
20210 70 2d 3e 70 55 70 64 61 74 65 2c 20 69 2a 33 2b  p->pUpdate, i*3+
20220 31 2c 20 70 4f 6c 64 29 3b 0a 20 20 20 20 20 20  1, pOld);.      
20230 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  }.      if( rc==
20240 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 4e 65  SQLITE_OK && pNe
20250 77 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  w ){.        rc 
20260 3d 20 73 65 73 73 69 6f 6e 42 69 6e 64 56 61 6c  = sessionBindVal
20270 75 65 28 70 2d 3e 70 55 70 64 61 74 65 2c 20 69  ue(p->pUpdate, i
20280 2a 33 2b 33 2c 20 70 4e 65 77 29 3b 0a 20 20 20  *3+3, pNew);.   
20290 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69     }.    }.    i
202a0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
202b0 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   ){.      sqlite
202c0 33 5f 62 69 6e 64 5f 69 6e 74 28 70 2d 3e 70 55  3_bind_int(p->pU
202d0 70 64 61 74 65 2c 20 6e 43 6f 6c 2a 33 2b 31 2c  pdate, nCol*3+1,
202e0 20 70 62 52 65 74 72 79 3d 3d 30 20 7c 7c 20 70   pbRetry==0 || p
202f0 49 74 65 72 2d 3e 62 50 61 74 63 68 73 65 74 29  Iter->bPatchset)
20300 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
20310 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
20320 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20 20  return rc;..    
20330 2f 2a 20 41 74 74 65 6d 70 74 20 74 68 65 20 55  /* Attempt the U
20340 50 44 41 54 45 2e 20 49 6e 20 74 68 65 20 63 61  PDATE. In the ca
20350 73 65 20 6f 66 20 61 20 4e 4f 54 46 4f 55 4e 44  se of a NOTFOUND
20360 20 6f 72 20 44 41 54 41 20 63 6f 6e 66 6c 69 63   or DATA conflic
20370 74 2c 0a 20 20 20 20 2a 2a 20 74 68 65 20 72 65  t,.    ** the re
20380 73 75 6c 74 20 77 69 6c 6c 20 62 65 20 53 51 4c  sult will be SQL
20390 49 54 45 5f 4f 4b 20 77 69 74 68 20 30 20 72 6f  ITE_OK with 0 ro
203a0 77 73 20 6d 6f 64 69 66 69 65 64 2e 20 2a 2f 0a  ws modified. */.
203b0 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 65 70      sqlite3_step
203c0 28 70 2d 3e 70 55 70 64 61 74 65 29 3b 0a 20 20  (p->pUpdate);.  
203d0 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 72    rc = sqlite3_r
203e0 65 73 65 74 28 70 2d 3e 70 55 70 64 61 74 65 29  eset(p->pUpdate)
203f0 3b 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  ;..    if( rc==S
20400 51 4c 49 54 45 5f 4f 4b 20 26 26 20 73 71 6c 69  QLITE_OK && sqli
20410 74 65 33 5f 63 68 61 6e 67 65 73 28 70 2d 3e 64  te3_changes(p->d
20420 62 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 2f  b)==0 ){.      /
20430 2a 20 41 20 4e 4f 54 46 4f 55 4e 44 20 6f 72 20  * A NOTFOUND or 
20440 44 41 54 41 20 65 72 72 6f 72 2e 20 53 65 61 72  DATA error. Sear
20450 63 68 20 74 68 65 20 74 61 62 6c 65 20 74 6f 20  ch the table to 
20460 73 65 65 20 69 66 20 69 74 20 63 6f 6e 74 61 69  see if it contai
20470 6e 73 0a 20 20 20 20 20 20 2a 2a 20 61 20 72 6f  ns.      ** a ro
20480 77 20 77 69 74 68 20 61 20 6d 61 74 63 68 69 6e  w with a matchin
20490 67 20 70 72 69 6d 61 72 79 20 6b 65 79 2e 20 49  g primary key. I
204a0 66 20 73 6f 2c 20 74 68 69 73 20 69 73 20 61 20  f so, this is a 
204b0 44 41 54 41 20 63 6f 6e 66 6c 69 63 74 2e 0a 20  DATA conflict.. 
204c0 20 20 20 20 20 2a 2a 20 4f 74 68 65 72 77 69 73       ** Otherwis
204d0 65 2c 20 69 66 20 74 68 65 72 65 20 69 73 20 6e  e, if there is n
204e0 6f 20 70 72 69 6d 61 72 79 20 6b 65 79 20 6d 61  o primary key ma
204f0 74 63 68 2c 20 69 74 20 69 73 20 61 20 4e 4f 54  tch, it is a NOT
20500 46 4f 55 4e 44 2e 20 2a 2f 0a 0a 20 20 20 20 20  FOUND. */..     
20510 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 43 6f 6e   rc = sessionCon
20520 66 6c 69 63 74 48 61 6e 64 6c 65 72 28 0a 20 20  flictHandler(.  
20530 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 43          SQLITE_C
20540 48 41 4e 47 45 53 45 54 5f 44 41 54 41 2c 20 70  HANGESET_DATA, p
20550 2c 20 70 49 74 65 72 2c 20 78 43 6f 6e 66 6c 69  , pIter, xConfli
20560 63 74 2c 20 70 43 74 78 2c 20 70 62 52 65 74 72  ct, pCtx, pbRetr
20570 79 0a 20 20 20 20 20 20 29 3b 0a 0a 20 20 20 20  y.      );..    
20580 7d 65 6c 73 65 20 69 66 28 20 28 72 63 26 30 78  }else if( (rc&0x
20590 66 66 29 3d 3d 53 51 4c 49 54 45 5f 43 4f 4e 53  ff)==SQLITE_CONS
205a0 54 52 41 49 4e 54 20 29 7b 0a 20 20 20 20 20 20  TRAINT ){.      
205b0 2f 2a 20 54 68 69 73 20 69 73 20 61 6c 77 61 79  /* This is alway
205c0 73 20 61 20 43 4f 4e 53 54 52 41 49 4e 54 20 63  s a CONSTRAINT c
205d0 6f 6e 66 6c 69 63 74 2e 20 2a 2f 0a 20 20 20 20  onflict. */.    
205e0 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 43 6f    rc = sessionCo
205f0 6e 66 6c 69 63 74 48 61 6e 64 6c 65 72 28 0a 20  nflictHandler(. 
20600 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
20610 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49  CHANGESET_CONFLI
20620 43 54 2c 20 70 2c 20 70 49 74 65 72 2c 20 78 43  CT, p, pIter, xC
20630 6f 6e 66 6c 69 63 74 2c 20 70 43 74 78 2c 20 30  onflict, pCtx, 0
20640 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a  .      );.    }.
20650 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73  .  }else{.    as
20660 73 65 72 74 28 20 6f 70 3d 3d 53 51 4c 49 54 45  sert( op==SQLITE
20670 5f 49 4e 53 45 52 54 20 29 3b 0a 20 20 20 20 69  _INSERT );.    i
20680 66 28 20 70 2d 3e 62 53 74 61 74 31 20 29 7b 0a  f( p->bStat1 ){.
20690 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 20 69        /* Check i
206a0 66 20 74 68 65 72 65 20 69 73 20 61 20 63 6f 6e  f there is a con
206b0 66 6c 69 63 74 69 6e 67 20 72 6f 77 2e 20 46 6f  flicting row. Fo
206c0 72 20 73 71 6c 69 74 65 5f 73 74 61 74 31 2c 20  r sqlite_stat1, 
206d0 74 68 69 73 20 6e 65 65 64 73 0a 20 20 20 20 20  this needs.     
206e0 20 2a 2a 20 74 6f 20 62 65 20 64 6f 6e 65 20 75   ** to be done u
206f0 73 69 6e 67 20 61 20 53 45 4c 45 43 54 2c 20 61  sing a SELECT, a
20700 73 20 74 68 65 72 65 20 69 73 20 6e 6f 20 50 52  s there is no PR
20710 49 4d 41 52 59 20 4b 45 59 20 69 6e 20 74 68 65  IMARY KEY in the
20720 20 0a 20 20 20 20 20 20 2a 2a 20 64 61 74 61 62   .      ** datab
20730 61 73 65 20 73 63 68 65 6d 61 20 74 6f 20 74 68  ase schema to th
20740 72 6f 77 20 61 6e 20 65 78 63 65 70 74 69 6f 6e  row an exception
20750 20 69 66 20 61 20 64 75 70 6c 69 63 61 74 65 20   if a duplicate 
20760 69 73 20 69 6e 73 65 72 74 65 64 2e 20 20 2a 2f  is inserted.  */
20770 0a 20 20 20 20 20 20 72 63 20 3d 20 73 65 73 73  .      rc = sess
20780 69 6f 6e 53 65 65 6b 54 6f 52 6f 77 28 70 2d 3e  ionSeekToRow(p->
20790 64 62 2c 20 70 49 74 65 72 2c 20 70 2d 3e 61 62  db, pIter, p->ab
207a0 50 4b 2c 20 70 2d 3e 70 53 65 6c 65 63 74 29 3b  PK, p->pSelect);
207b0 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
207c0 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20  QLITE_ROW ){.   
207d0 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
207e0 5f 43 4f 4e 53 54 52 41 49 4e 54 3b 0a 20 20 20  _CONSTRAINT;.   
207f0 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73       sqlite3_res
20800 65 74 28 70 2d 3e 70 53 65 6c 65 63 74 29 3b 0a  et(p->pSelect);.
20810 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20        }.    }.. 
20820 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
20830 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63  E_OK ){.      rc
20840 20 3d 20 73 65 73 73 69 6f 6e 42 69 6e 64 52 6f   = sessionBindRo
20850 77 28 70 49 74 65 72 2c 20 73 71 6c 69 74 65 33  w(pIter, sqlite3
20860 63 68 61 6e 67 65 73 65 74 5f 6e 65 77 2c 20 6e  changeset_new, n
20870 43 6f 6c 2c 20 30 2c 20 70 2d 3e 70 49 6e 73 65  Col, 0, p->pInse
20880 72 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  rt);.      if( r
20890 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
208a0 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20 20 20  eturn rc;..     
208b0 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 2d   sqlite3_step(p-
208c0 3e 70 49 6e 73 65 72 74 29 3b 0a 20 20 20 20 20  >pInsert);.     
208d0 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 72 65   rc = sqlite3_re
208e0 73 65 74 28 70 2d 3e 70 49 6e 73 65 72 74 29 3b  set(p->pInsert);
208f0 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20  .    }..    if( 
20900 28 72 63 26 30 78 66 66 29 3d 3d 53 51 4c 49 54  (rc&0xff)==SQLIT
20910 45 5f 43 4f 4e 53 54 52 41 49 4e 54 20 29 7b 0a  E_CONSTRAINT ){.
20920 20 20 20 20 20 20 72 63 20 3d 20 73 65 73 73 69        rc = sessi
20930 6f 6e 43 6f 6e 66 6c 69 63 74 48 61 6e 64 6c 65  onConflictHandle
20940 72 28 0a 20 20 20 20 20 20 20 20 20 20 53 51 4c  r(.          SQL
20950 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 43 4f  ITE_CHANGESET_CO
20960 4e 46 4c 49 43 54 2c 20 70 2c 20 70 49 74 65 72  NFLICT, p, pIter
20970 2c 20 78 43 6f 6e 66 6c 69 63 74 2c 20 70 43 74  , xConflict, pCt
20980 78 2c 20 70 62 52 65 70 6c 61 63 65 0a 20 20 20  x, pbReplace.   
20990 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a     );.    }.  }.
209a0 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
209b0 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74 20 74  ./*.** Attempt t
209c0 6f 20 61 70 70 6c 79 20 74 68 65 20 63 68 61 6e  o apply the chan
209d0 67 65 20 74 68 61 74 20 74 68 65 20 69 74 65 72  ge that the iter
209e0 61 74 6f 72 20 70 61 73 73 65 64 20 61 73 20 74  ator passed as t
209f0 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e  he first argumen
20a00 74 0a 2a 2a 20 63 75 72 72 65 6e 74 6c 79 20 70  t.** currently p
20a10 6f 69 6e 74 73 20 74 6f 20 74 6f 20 74 68 65 20  oints to to the 
20a20 64 61 74 61 62 61 73 65 2e 20 49 66 20 61 20 63  database. If a c
20a30 6f 6e 66 6c 69 63 74 20 69 73 20 65 6e 63 6f 75  onflict is encou
20a40 6e 74 65 72 65 64 2c 20 69 6e 76 6f 6b 65 0a 2a  ntered, invoke.*
20a50 2a 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 20 68  * the conflict h
20a60 61 6e 64 6c 65 72 20 63 61 6c 6c 62 61 63 6b 2e  andler callback.
20a70 0a 2a 2a 0a 2a 2a 20 54 68 65 20 64 69 66 66 65  .**.** The diffe
20a80 72 65 6e 63 65 20 62 65 74 77 65 65 6e 20 74 68  rence between th
20a90 69 73 20 66 75 6e 63 74 69 6f 6e 20 61 6e 64 20  is function and 
20aa0 73 65 73 73 69 6f 6e 41 70 70 6c 79 4f 6e 65 28  sessionApplyOne(
20ab0 29 20 69 73 20 74 68 61 74 20 74 68 69 73 0a 2a  ) is that this.*
20ac0 2a 20 66 75 6e 63 74 69 6f 6e 20 68 61 6e 64 6c  * function handl
20ad0 65 73 20 74 68 65 20 63 61 73 65 20 77 68 65 72  es the case wher
20ae0 65 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 2d 68  e the conflict-h
20af0 61 6e 64 6c 65 72 20 69 73 20 69 6e 76 6f 6b 65  andler is invoke
20b00 64 20 61 6e 64 20 0a 2a 2a 20 72 65 74 75 72 6e  d and .** return
20b10 73 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53  s SQLITE_CHANGES
20b20 45 54 5f 52 45 50 4c 41 43 45 20 2d 20 69 6e 64  ET_REPLACE - ind
20b30 69 63 61 74 69 6e 67 20 74 68 61 74 20 74 68 65  icating that the
20b40 20 63 68 61 6e 67 65 20 73 68 6f 75 6c 64 20 62   change should b
20b50 65 0a 2a 2a 20 72 65 74 72 69 65 64 20 69 6e 20  e.** retried in 
20b60 73 6f 6d 65 20 6d 61 6e 6e 65 72 2e 0a 2a 2f 0a  some manner..*/.
20b70 73 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69  static int sessi
20b80 6f 6e 41 70 70 6c 79 4f 6e 65 57 69 74 68 52 65  onApplyOneWithRe
20b90 74 72 79 28 0a 20 20 73 71 6c 69 74 65 33 20 2a  try(.  sqlite3 *
20ba0 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  db,             
20bb0 20 20 20 20 20 20 20 2f 2a 20 41 70 70 6c 79 20         /* Apply 
20bc0 63 68 61 6e 67 65 20 74 6f 20 22 6d 61 69 6e 22  change to "main"
20bd0 20 64 62 20 6f 66 20 74 68 69 73 20 68 61 6e 64   db of this hand
20be0 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  le */.  sqlite3_
20bf0 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a  changeset_iter *
20c00 70 49 74 65 72 2c 20 20 2f 2a 20 43 68 61 6e 67  pIter,  /* Chang
20c10 65 73 65 74 20 69 74 65 72 61 74 6f 72 20 74 6f  eset iterator to
20c20 20 72 65 61 64 20 63 68 61 6e 67 65 20 66 72 6f   read change fro
20c30 6d 20 2a 2f 0a 20 20 53 65 73 73 69 6f 6e 41 70  m */.  SessionAp
20c40 70 6c 79 43 74 78 20 2a 70 41 70 70 6c 79 2c 20  plyCtx *pApply, 
20c50 20 20 20 20 20 20 20 2f 2a 20 41 70 70 6c 79 20         /* Apply 
20c60 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74  context */.  int
20c70 28 2a 78 43 6f 6e 66 6c 69 63 74 29 28 76 6f 69  (*xConflict)(voi
20c80 64 2a 2c 20 69 6e 74 2c 20 73 71 6c 69 74 65 33  d*, int, sqlite3
20c90 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 2a  _changeset_iter*
20ca0 29 2c 0a 20 20 76 6f 69 64 20 2a 70 43 74 78 20  ),.  void *pCtx 
20cb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20cc0 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 61 72       /* First ar
20cd0 67 75 6d 65 6e 74 20 70 61 73 73 65 64 20 74 6f  gument passed to
20ce0 20 78 43 6f 6e 66 6c 69 63 74 20 2a 2f 0a 29 7b   xConflict */.){
20cf0 0a 20 20 69 6e 74 20 62 52 65 70 6c 61 63 65 20  .  int bReplace 
20d00 3d 20 30 3b 0a 20 20 69 6e 74 20 62 52 65 74 72  = 0;.  int bRetr
20d10 79 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 3b  y = 0;.  int rc;
20d20 0a 0a 20 20 72 63 20 3d 20 73 65 73 73 69 6f 6e  ..  rc = session
20d30 41 70 70 6c 79 4f 6e 65 4f 70 28 70 49 74 65 72  ApplyOneOp(pIter
20d40 2c 20 70 41 70 70 6c 79 2c 20 78 43 6f 6e 66 6c  , pApply, xConfl
20d50 69 63 74 2c 20 70 43 74 78 2c 20 26 62 52 65 70  ict, pCtx, &bRep
20d60 6c 61 63 65 2c 20 26 62 52 65 74 72 79 29 3b 0a  lace, &bRetry);.
20d70 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51    assert( rc==SQ
20d80 4c 49 54 45 5f 4f 4b 20 7c 7c 20 28 62 52 65 74  LITE_OK || (bRet
20d90 72 79 3d 3d 30 20 26 26 20 62 52 65 70 6c 61 63  ry==0 && bReplac
20da0 65 3d 3d 30 29 20 29 3b 0a 0a 20 20 2f 2a 20 49  e==0) );..  /* I
20db0 66 20 74 68 65 20 62 52 65 74 72 79 20 66 6c 61  f the bRetry fla
20dc0 67 20 69 73 20 73 65 74 2c 20 74 68 65 20 63 68  g is set, the ch
20dd0 61 6e 67 65 20 68 61 73 20 6e 6f 74 20 62 65 65  ange has not bee
20de0 6e 20 61 70 70 6c 69 65 64 20 64 75 65 20 74 6f  n applied due to
20df0 20 61 6e 0a 20 20 2a 2a 20 53 51 4c 49 54 45 5f   an.  ** SQLITE_
20e00 43 48 41 4e 47 45 53 45 54 5f 44 41 54 41 20 70  CHANGESET_DATA p
20e10 72 6f 62 6c 65 6d 20 28 69 2e 65 2e 20 74 68 69  roblem (i.e. thi
20e20 73 20 69 73 20 61 6e 20 55 50 44 41 54 45 20 6f  s is an UPDATE o
20e30 72 20 44 45 4c 45 54 45 20 61 6e 64 0a 20 20 2a  r DELETE and.  *
20e40 2a 20 61 20 72 6f 77 20 77 69 74 68 20 74 68 65  * a row with the
20e50 20 63 6f 72 72 65 63 74 20 50 4b 20 69 73 20 70   correct PK is p
20e60 72 65 73 65 6e 74 20 69 6e 20 74 68 65 20 64 62  resent in the db
20e70 2c 20 62 75 74 20 6f 6e 65 20 6f 72 20 6d 6f 72  , but one or mor
20e80 65 20 6f 74 68 65 72 0a 20 20 2a 2a 20 66 69 65  e other.  ** fie
20e90 6c 64 73 20 64 6f 20 6e 6f 74 20 63 6f 6e 74 61  lds do not conta
20ea0 69 6e 20 74 68 65 20 65 78 70 65 63 74 65 64 20  in the expected 
20eb0 76 61 6c 75 65 73 29 20 61 6e 64 20 74 68 65 20  values) and the 
20ec0 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65 72  conflict handler
20ed0 20 0a 20 20 2a 2a 20 72 65 74 75 72 6e 65 64 20   .  ** returned 
20ee0 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54  SQLITE_CHANGESET
20ef0 5f 52 45 50 4c 41 43 45 2e 20 49 6e 20 74 68 69  _REPLACE. In thi
20f00 73 20 63 61 73 65 20 72 65 74 72 79 20 74 68 65  s case retry the
20f10 20 6f 70 65 72 61 74 69 6f 6e 2c 0a 20 20 2a 2a   operation,.  **
20f20 20 62 75 74 20 70 61 73 73 20 4e 55 4c 4c 20 61   but pass NULL a
20f30 73 20 74 68 65 20 66 69 6e 61 6c 20 61 72 67 75  s the final argu
20f40 6d 65 6e 74 20 73 6f 20 74 68 61 74 20 73 65 73  ment so that ses
20f50 73 69 6f 6e 41 70 70 6c 79 4f 6e 65 4f 70 28 29  sionApplyOneOp()
20f60 20 69 67 6e 6f 72 65 73 0a 20 20 2a 2a 20 74 68   ignores.  ** th
20f70 65 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53  e SQLITE_CHANGES
20f80 45 54 5f 44 41 54 41 20 70 72 6f 62 6c 65 6d 2e  ET_DATA problem.
20f90 20 20 2a 2f 0a 20 20 69 66 28 20 62 52 65 74 72    */.  if( bRetr
20fa0 79 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  y ){.    assert(
20fb0 20 70 49 74 65 72 2d 3e 6f 70 3d 3d 53 51 4c 49   pIter->op==SQLI
20fc0 54 45 5f 55 50 44 41 54 45 20 7c 7c 20 70 49 74  TE_UPDATE || pIt
20fd0 65 72 2d 3e 6f 70 3d 3d 53 51 4c 49 54 45 5f 44  er->op==SQLITE_D
20fe0 45 4c 45 54 45 20 29 3b 0a 20 20 20 20 72 63 20  ELETE );.    rc 
20ff0 3d 20 73 65 73 73 69 6f 6e 41 70 70 6c 79 4f 6e  = sessionApplyOn
21000 65 4f 70 28 70 49 74 65 72 2c 20 70 41 70 70 6c  eOp(pIter, pAppl
21010 79 2c 20 78 43 6f 6e 66 6c 69 63 74 2c 20 70 43  y, xConflict, pC
21020 74 78 2c 20 30 2c 20 30 29 3b 0a 20 20 7d 0a 0a  tx, 0, 0);.  }..
21030 20 20 2f 2a 20 49 66 20 74 68 65 20 62 52 65 70    /* If the bRep
21040 6c 61 63 65 20 66 6c 61 67 20 69 73 20 73 65 74  lace flag is set
21050 2c 20 74 68 65 20 63 68 61 6e 67 65 20 69 73 20  , the change is 
21060 61 6e 20 49 4e 53 45 52 54 20 74 68 61 74 20 68  an INSERT that h
21070 61 73 20 6e 6f 74 0a 20 20 2a 2a 20 62 65 65 6e  as not.  ** been
21080 20 70 65 72 66 6f 72 6d 65 64 20 62 65 63 61 75   performed becau
21090 73 65 20 74 68 65 20 64 61 74 61 62 61 73 65 20  se the database 
210a0 61 6c 72 65 61 64 79 20 63 6f 6e 74 61 69 6e 73  already contains
210b0 20 61 20 72 6f 77 20 77 69 74 68 20 74 68 65 0a   a row with the.
210c0 20 20 2a 2a 20 73 70 65 63 69 66 69 65 64 20 70    ** specified p
210d0 72 69 6d 61 72 79 20 6b 65 79 20 61 6e 64 20 74  rimary key and t
210e0 68 65 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64  he conflict hand
210f0 6c 65 72 20 72 65 74 75 72 6e 65 64 0a 20 20 2a  ler returned.  *
21100 2a 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53  * SQLITE_CHANGES
21110 45 54 5f 52 45 50 4c 41 43 45 2e 20 49 6e 20 74  ET_REPLACE. In t
21120 68 69 73 20 63 61 73 65 20 72 65 6d 6f 76 65 20  his case remove 
21130 74 68 65 20 63 6f 6e 66 6c 69 63 74 69 6e 67 20  the conflicting 
21140 72 6f 77 0a 20 20 2a 2a 20 62 65 66 6f 72 65 20  row.  ** before 
21150 72 65 61 74 74 65 6d 70 74 69 6e 67 20 74 68 65  reattempting the
21160 20 49 4e 53 45 52 54 2e 20 20 2a 2f 0a 20 20 65   INSERT.  */.  e
21170 6c 73 65 20 69 66 28 20 62 52 65 70 6c 61 63 65  lse if( bReplace
21180 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20   ){.    assert( 
21190 70 49 74 65 72 2d 3e 6f 70 3d 3d 53 51 4c 49 54  pIter->op==SQLIT
211a0 45 5f 49 4e 53 45 52 54 20 29 3b 0a 20 20 20 20  E_INSERT );.    
211b0 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65  rc = sqlite3_exe
211c0 63 28 64 62 2c 20 22 53 41 56 45 50 4f 49 4e 54  c(db, "SAVEPOINT
211d0 20 72 65 70 6c 61 63 65 5f 6f 70 22 2c 20 30 2c   replace_op", 0,
211e0 20 30 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20   0, 0);.    if( 
211f0 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
21200 0a 20 20 20 20 20 20 72 63 20 3d 20 73 65 73 73  .      rc = sess
21210 69 6f 6e 42 69 6e 64 52 6f 77 28 70 49 74 65 72  ionBindRow(pIter
21220 2c 20 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c  , .          sql
21230 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6e 65  ite3changeset_ne
21240 77 2c 20 70 41 70 70 6c 79 2d 3e 6e 43 6f 6c 2c  w, pApply->nCol,
21250 20 70 41 70 70 6c 79 2d 3e 61 62 50 4b 2c 20 70   pApply->abPK, p
21260 41 70 70 6c 79 2d 3e 70 44 65 6c 65 74 65 29 3b  Apply->pDelete);
21270 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 62  .      sqlite3_b
21280 69 6e 64 5f 69 6e 74 28 70 41 70 70 6c 79 2d 3e  ind_int(pApply->
21290 70 44 65 6c 65 74 65 2c 20 70 41 70 70 6c 79 2d  pDelete, pApply-
212a0 3e 6e 43 6f 6c 2b 31 2c 20 31 29 3b 0a 20 20 20  >nCol+1, 1);.   
212b0 20 7d 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53   }.    if( rc==S
212c0 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
212d0 20 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70    sqlite3_step(p
212e0 41 70 70 6c 79 2d 3e 70 44 65 6c 65 74 65 29 3b  Apply->pDelete);
212f0 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
21300 74 65 33 5f 72 65 73 65 74 28 70 41 70 70 6c 79  te3_reset(pApply
21310 2d 3e 70 44 65 6c 65 74 65 29 3b 0a 20 20 20 20  ->pDelete);.    
21320 7d 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  }.    if( rc==SQ
21330 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
21340 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 41 70 70   rc = sessionApp
21350 6c 79 4f 6e 65 4f 70 28 70 49 74 65 72 2c 20 70  lyOneOp(pIter, p
21360 41 70 70 6c 79 2c 20 78 43 6f 6e 66 6c 69 63 74  Apply, xConflict
21370 2c 20 70 43 74 78 2c 20 30 2c 20 30 29 3b 0a 20  , pCtx, 0, 0);. 
21380 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 3d     }.    if( rc=
21390 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
213a0 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
213b0 5f 65 78 65 63 28 64 62 2c 20 22 52 45 4c 45 41  _exec(db, "RELEA
213c0 53 45 20 72 65 70 6c 61 63 65 5f 6f 70 22 2c 20  SE replace_op", 
213d0 30 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 7d 0a  0, 0, 0);.    }.
213e0 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
213f0 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 72 79  ;.}../*.** Retry
21400 20 74 68 65 20 63 68 61 6e 67 65 73 20 61 63 63   the changes acc
21410 75 6d 75 6c 61 74 65 64 20 69 6e 20 74 68 65 20  umulated in the 
21420 70 41 70 70 6c 79 2d 3e 63 6f 6e 73 74 72 61 69  pApply->constrai
21430 6e 74 73 20 62 75 66 66 65 72 2e 0a 2a 2f 0a 73  nts buffer..*/.s
21440 74 61 74 69 63 20 69 6e 74 20 73 65 73 73 69 6f  tatic int sessio
21450 6e 52 65 74 72 79 43 6f 6e 73 74 72 61 69 6e 74  nRetryConstraint
21460 73 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  s(.  sqlite3 *db
21470 2c 20 0a 20 20 69 6e 74 20 62 50 61 74 63 68 73  , .  int bPatchs
21480 65 74 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  et,.  const char
21490 20 2a 7a 54 61 62 2c 0a 20 20 53 65 73 73 69 6f   *zTab,.  Sessio
214a0 6e 41 70 70 6c 79 43 74 78 20 2a 70 41 70 70 6c  nApplyCtx *pAppl
214b0 79 2c 0a 20 20 69 6e 74 28 2a 78 43 6f 6e 66 6c  y,.  int(*xConfl
214c0 69 63 74 29 28 76 6f 69 64 2a 2c 20 69 6e 74 2c  ict)(void*, int,
214d0 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73   sqlite3_changes
214e0 65 74 5f 69 74 65 72 2a 29 2c 0a 20 20 76 6f 69  et_iter*),.  voi
214f0 64 20 2a 70 43 74 78 20 20 20 20 20 20 20 20 20  d *pCtx         
21500 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
21510 46 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 70  First argument p
21520 61 73 73 65 64 20 74 6f 20 78 43 6f 6e 66 6c 69  assed to xConfli
21530 63 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  ct */.){.  int r
21540 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a  c = SQLITE_OK;..
21550 20 20 77 68 69 6c 65 28 20 70 41 70 70 6c 79 2d    while( pApply-
21560 3e 63 6f 6e 73 74 72 61 69 6e 74 73 2e 6e 42 75  >constraints.nBu
21570 66 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  f ){.    sqlite3
21580 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20  _changeset_iter 
21590 2a 70 49 74 65 72 32 20 3d 20 30 3b 0a 20 20 20  *pIter2 = 0;.   
215a0 20 53 65 73 73 69 6f 6e 42 75 66 66 65 72 20 63   SessionBuffer c
215b0 6f 6e 73 20 3d 20 70 41 70 70 6c 79 2d 3e 63 6f  ons = pApply->co
215c0 6e 73 74 72 61 69 6e 74 73 3b 0a 20 20 20 20 6d  nstraints;.    m
215d0 65 6d 73 65 74 28 26 70 41 70 70 6c 79 2d 3e 63  emset(&pApply->c
215e0 6f 6e 73 74 72 61 69 6e 74 73 2c 20 30 2c 20 73  onstraints, 0, s
215f0 69 7a 65 6f 66 28 53 65 73 73 69 6f 6e 42 75 66  izeof(SessionBuf
21600 66 65 72 29 29 3b 0a 0a 20 20 20 20 72 63 20 3d  fer));..    rc =
21610 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65   sessionChangese
21620 74 53 74 61 72 74 28 26 70 49 74 65 72 32 2c 20  tStart(&pIter2, 
21630 30 2c 20 30 2c 20 63 6f 6e 73 2e 6e 42 75 66 2c  0, 0, cons.nBuf,
21640 20 63 6f 6e 73 2e 61 42 75 66 29 3b 0a 20 20 20   cons.aBuf);.   
21650 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
21660 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  OK ){.      int 
21670 6e 42 79 74 65 20 3d 20 32 2a 70 41 70 70 6c 79  nByte = 2*pApply
21680 2d 3e 6e 43 6f 6c 2a 73 69 7a 65 6f 66 28 73 71  ->nCol*sizeof(sq
21690 6c 69 74 65 33 5f 76 61 6c 75 65 2a 29 3b 0a 20  lite3_value*);. 
216a0 20 20 20 20 20 69 6e 74 20 72 63 32 3b 0a 20 20       int rc2;.  
216b0 20 20 20 20 70 49 74 65 72 32 2d 3e 62 50 61 74      pIter2->bPat
216c0 63 68 73 65 74 20 3d 20 62 50 61 74 63 68 73 65  chset = bPatchse
216d0 74 3b 0a 20 20 20 20 20 20 70 49 74 65 72 32 2d  t;.      pIter2-
216e0 3e 7a 54 61 62 20 3d 20 28 63 68 61 72 2a 29 7a  >zTab = (char*)z
216f0 54 61 62 3b 0a 20 20 20 20 20 20 70 49 74 65 72  Tab;.      pIter
21700 32 2d 3e 6e 43 6f 6c 20 3d 20 70 41 70 70 6c 79  2->nCol = pApply
21710 2d 3e 6e 43 6f 6c 3b 0a 20 20 20 20 20 20 70 49  ->nCol;.      pI
21720 74 65 72 32 2d 3e 61 62 50 4b 20 3d 20 70 41 70  ter2->abPK = pAp
21730 70 6c 79 2d 3e 61 62 50 4b 3b 0a 20 20 20 20 20  ply->abPK;.     
21740 20 73 65 73 73 69 6f 6e 42 75 66 66 65 72 47 72   sessionBufferGr
21750 6f 77 28 26 70 49 74 65 72 32 2d 3e 74 62 6c 68  ow(&pIter2->tblh
21760 64 72 2c 20 6e 42 79 74 65 2c 20 26 72 63 29 3b  dr, nByte, &rc);
21770 0a 20 20 20 20 20 20 70 49 74 65 72 32 2d 3e 61  .      pIter2->a
21780 70 56 61 6c 75 65 20 3d 20 28 73 71 6c 69 74 65  pValue = (sqlite
21790 33 5f 76 61 6c 75 65 2a 2a 29 70 49 74 65 72 32  3_value**)pIter2
217a0 2d 3e 74 62 6c 68 64 72 2e 61 42 75 66 3b 0a 20  ->tblhdr.aBuf;. 
217b0 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
217c0 49 54 45 5f 4f 4b 20 29 20 6d 65 6d 73 65 74 28  ITE_OK ) memset(
217d0 70 49 74 65 72 32 2d 3e 61 70 56 61 6c 75 65 2c  pIter2->apValue,
217e0 20 30 2c 20 6e 42 79 74 65 29 3b 0a 0a 20 20 20   0, nByte);..   
217f0 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51     while( rc==SQ
21800 4c 49 54 45 5f 4f 4b 20 26 26 20 53 51 4c 49 54  LITE_OK && SQLIT
21810 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33 63 68  E_ROW==sqlite3ch
21820 61 6e 67 65 73 65 74 5f 6e 65 78 74 28 70 49 74  angeset_next(pIt
21830 65 72 32 29 20 29 7b 0a 20 20 20 20 20 20 20 20  er2) ){.        
21840 72 63 20 3d 20 73 65 73 73 69 6f 6e 41 70 70 6c  rc = sessionAppl
21850 79 4f 6e 65 57 69 74 68 52 65 74 72 79 28 64 62  yOneWithRetry(db
21860 2c 20 70 49 74 65 72 32 2c 20 70 41 70 70 6c 79  , pIter2, pApply
21870 2c 20 78 43 6f 6e 66 6c 69 63 74 2c 20 70 43 74  , xConflict, pCt
21880 78 29 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20  x);.      }..   
21890 20 20 20 72 63 32 20 3d 20 73 71 6c 69 74 65 33     rc2 = sqlite3
218a0 63 68 61 6e 67 65 73 65 74 5f 66 69 6e 61 6c 69  changeset_finali
218b0 7a 65 28 70 49 74 65 72 32 29 3b 0a 20 20 20 20  ze(pIter2);.    
218c0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
218d0 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63 32 3b 0a  _OK ) rc = rc2;.
218e0 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74      }.    assert
218f0 28 20 70 41 70 70 6c 79 2d 3e 62 44 65 66 65 72  ( pApply->bDefer
21900 43 6f 6e 73 74 72 61 69 6e 74 73 20 7c 7c 20 70  Constraints || p
21910 41 70 70 6c 79 2d 3e 63 6f 6e 73 74 72 61 69 6e  Apply->constrain
21920 74 73 2e 6e 42 75 66 3d 3d 30 20 29 3b 0a 0a 20  ts.nBuf==0 );.. 
21930 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
21940 63 6f 6e 73 2e 61 42 75 66 29 3b 0a 20 20 20 20  cons.aBuf);.    
21950 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
21960 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 69  K ) break;.    i
21970 66 28 20 70 41 70 70 6c 79 2d 3e 63 6f 6e 73 74  f( pApply->const
21980 72 61 69 6e 74 73 2e 6e 42 75 66 3e 3d 63 6f 6e  raints.nBuf>=con
21990 73 2e 6e 42 75 66 20 29 7b 0a 20 20 20 20 20 20  s.nBuf ){.      
219a0 2f 2a 20 4e 6f 20 70 72 6f 67 72 65 73 73 20 77  /* No progress w
219b0 61 73 20 6d 61 64 65 20 6f 6e 20 74 68 65 20 6c  as made on the l
219c0 61 73 74 20 72 6f 75 6e 64 2e 20 2a 2f 0a 20 20  ast round. */.  
219d0 20 20 20 20 70 41 70 70 6c 79 2d 3e 62 44 65 66      pApply->bDef
219e0 65 72 43 6f 6e 73 74 72 61 69 6e 74 73 20 3d 20  erConstraints = 
219f0 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  0;.    }.  }..  
21a00 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
21a10 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20 70 49 74  .** Argument pIt
21a20 65 72 20 69 73 20 61 20 63 68 61 6e 67 65 73 65  er is a changese
21a30 74 20 69 74 65 72 61 74 6f 72 20 74 68 61 74 20  t iterator that 
21a40 68 61 73 20 62 65 65 6e 20 69 6e 69 74 69 61 6c  has been initial
21a50 69 7a 65 64 2c 20 62 75 74 0a 2a 2a 20 6e 6f 74  ized, but.** not
21a60 20 79 65 74 20 70 61 73 73 65 64 20 74 6f 20 73   yet passed to s
21a70 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
21a80 6e 65 78 74 28 29 2e 20 54 68 69 73 20 66 75 6e  next(). This fun
21a90 63 74 69 6f 6e 20 61 70 70 6c 69 65 73 20 74 68  ction applies th
21aa0 65 20 0a 2a 2a 20 63 68 61 6e 67 65 73 65 74 20  e .** changeset 
21ab0 74 6f 20 74 68 65 20 6d 61 69 6e 20 64 61 74 61  to the main data
21ac0 62 61 73 65 20 61 74 74 61 63 68 65 64 20 74 6f  base attached to
21ad0 20 68 61 6e 64 6c 65 20 22 64 62 22 2e 20 54 68   handle "db". Th
21ae0 65 20 73 75 70 70 6c 69 65 64 0a 2a 2a 20 63 6f  e supplied.** co
21af0 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65 72 20 63  nflict handler c
21b00 61 6c 6c 62 61 63 6b 20 69 73 20 69 6e 76 6f 6b  allback is invok
21b10 65 64 20 74 6f 20 72 65 73 6f 6c 76 65 20 61 6e  ed to resolve an
21b20 79 20 63 6f 6e 66 6c 69 63 74 73 20 65 6e 63 6f  y conflicts enco
21b30 75 6e 74 65 72 65 64 0a 2a 2a 20 77 68 69 6c 65  untered.** while
21b40 20 61 70 70 6c 79 69 6e 67 20 74 68 65 20 63 68   applying the ch
21b50 61 6e 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ange..*/.static 
21b60 69 6e 74 20 73 65 73 73 69 6f 6e 43 68 61 6e 67  int sessionChang
21b70 65 73 65 74 41 70 70 6c 79 28 0a 20 20 73 71 6c  esetApply(.  sql
21b80 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20  ite3 *db,       
21b90 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
21ba0 41 70 70 6c 79 20 63 68 61 6e 67 65 20 74 6f 20  Apply change to 
21bb0 22 6d 61 69 6e 22 20 64 62 20 6f 66 20 74 68 69  "main" db of thi
21bc0 73 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 73 71  s handle */.  sq
21bd0 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f  lite3_changeset_
21be0 69 74 65 72 20 2a 70 49 74 65 72 2c 20 20 2f 2a  iter *pIter,  /*
21bf0 20 43 68 61 6e 67 65 73 65 74 20 74 6f 20 61 70   Changeset to ap
21c00 70 6c 79 20 2a 2f 0a 20 20 69 6e 74 28 2a 78 46  ply */.  int(*xF
21c10 69 6c 74 65 72 29 28 0a 20 20 20 20 76 6f 69 64  ilter)(.    void
21c20 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20   *pCtx,         
21c30 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 70            /* Cop
21c40 79 20 6f 66 20 73 69 78 74 68 20 61 72 67 20 74  y of sixth arg t
21c50 6f 20 5f 61 70 70 6c 79 28 29 20 2a 2f 0a 20 20  o _apply() */.  
21c60 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54    const char *zT
21c70 61 62 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ab              
21c80 2f 2a 20 54 61 62 6c 65 20 6e 61 6d 65 20 2a 2f  /* Table name */
21c90 0a 20 20 29 2c 0a 20 20 69 6e 74 28 2a 78 43 6f  .  ),.  int(*xCo
21ca0 6e 66 6c 69 63 74 29 28 0a 20 20 20 20 76 6f 69  nflict)(.    voi
21cb0 64 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20  d *pCtx,        
21cc0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
21cd0 70 79 20 6f 66 20 66 69 66 74 68 20 61 72 67 20  py of fifth arg 
21ce0 74 6f 20 5f 61 70 70 6c 79 28 29 20 2a 2f 0a 20  to _apply() */. 
21cf0 20 20 20 69 6e 74 20 65 43 6f 6e 66 6c 69 63 74     int eConflict
21d00 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
21d10 20 2f 2a 20 44 41 54 41 2c 20 4d 49 53 53 49 4e   /* DATA, MISSIN
21d20 47 2c 20 43 4f 4e 46 4c 49 43 54 2c 20 43 4f 4e  G, CONFLICT, CON
21d30 53 54 52 41 49 4e 54 20 2a 2f 0a 20 20 20 20 73  STRAINT */.    s
21d40 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74  qlite3_changeset
21d50 5f 69 74 65 72 20 2a 70 20 20 20 20 20 2f 2a 20  _iter *p     /* 
21d60 48 61 6e 64 6c 65 20 64 65 73 63 72 69 62 69 6e  Handle describin
21d70 67 20 63 68 61 6e 67 65 20 61 6e 64 20 63 6f 6e  g change and con
21d80 66 6c 69 63 74 20 2a 2f 0a 20 20 29 2c 0a 20 20  flict */.  ),.  
21d90 76 6f 69 64 20 2a 70 43 74 78 20 20 20 20 20 20  void *pCtx      
21da0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21db0 2f 2a 20 46 69 72 73 74 20 61 72 67 75 6d 65 6e  /* First argumen
21dc0 74 20 70 61 73 73 65 64 20 74 6f 20 78 43 6f 6e  t passed to xCon
21dd0 66 6c 69 63 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e  flict */.){.  in
21de0 74 20 73 63 68 65 6d 61 4d 69 73 6d 61 74 63 68  t schemaMismatch
21df0 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 3b 20   = 0;.  int rc; 
21e00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21e10 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
21e20 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 63 6f 6e 73  n code */.  cons
21e30 74 20 63 68 61 72 20 2a 7a 54 61 62 20 3d 20 30  t char *zTab = 0
21e40 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e  ;           /* N
21e50 61 6d 65 20 6f 66 20 63 75 72 72 65 6e 74 20 74  ame of current t
21e60 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 54  able */.  int nT
21e70 61 62 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  ab = 0;         
21e80 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 73            /* Res
21e90 75 6c 74 20 6f 66 20 73 71 6c 69 74 65 33 53 74  ult of sqlite3St
21ea0 72 6c 65 6e 33 30 28 7a 54 61 62 29 20 2a 2f 0a  rlen30(zTab) */.
21eb0 20 20 53 65 73 73 69 6f 6e 41 70 70 6c 79 43 74    SessionApplyCt
21ec0 78 20 73 41 70 70 6c 79 3b 20 20 20 20 20 20 20  x sApply;       
21ed0 20 20 2f 2a 20 63 68 61 6e 67 65 73 65 74 5f 61    /* changeset_a
21ee0 70 70 6c 79 28 29 20 63 6f 6e 74 65 78 74 20 6f  pply() context o
21ef0 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e 74 20 62  bject */.  int b
21f00 50 61 74 63 68 73 65 74 3b 0a 0a 20 20 61 73 73  Patchset;..  ass
21f10 65 72 74 28 20 78 43 6f 6e 66 6c 69 63 74 21 3d  ert( xConflict!=
21f20 30 20 29 3b 0a 0a 20 20 70 49 74 65 72 2d 3e 69  0 );..  pIter->i
21f30 6e 2e 62 4e 6f 44 69 73 63 61 72 64 20 3d 20 31  n.bNoDiscard = 1
21f40 3b 0a 20 20 6d 65 6d 73 65 74 28 26 73 41 70 70  ;.  memset(&sApp
21f50 6c 79 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73 41  ly, 0, sizeof(sA
21f60 70 70 6c 79 29 29 3b 0a 20 20 73 71 6c 69 74 65  pply));.  sqlite
21f70 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 73 71  3_mutex_enter(sq
21f80 6c 69 74 65 33 5f 64 62 5f 6d 75 74 65 78 28 64  lite3_db_mutex(d
21f90 62 29 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69  b));.  rc = sqli
21fa0 74 65 33 5f 65 78 65 63 28 64 62 2c 20 22 53 41  te3_exec(db, "SA
21fb0 56 45 50 4f 49 4e 54 20 63 68 61 6e 67 65 73 65  VEPOINT changese
21fc0 74 5f 61 70 70 6c 79 22 2c 20 30 2c 20 30 2c 20  t_apply", 0, 0, 
21fd0 30 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  0);.  if( rc==SQ
21fe0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
21ff0 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63  c = sqlite3_exec
22000 28 64 62 2c 20 22 50 52 41 47 4d 41 20 64 65 66  (db, "PRAGMA def
22010 65 72 5f 66 6f 72 65 69 67 6e 5f 6b 65 79 73 20  er_foreign_keys 
22020 3d 20 31 22 2c 20 30 2c 20 30 2c 20 30 29 3b 0a  = 1", 0, 0, 0);.
22030 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 72 63 3d    }.  while( rc=
22040 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 53 51  =SQLITE_OK && SQ
22050 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65  LITE_ROW==sqlite
22060 33 63 68 61 6e 67 65 73 65 74 5f 6e 65 78 74 28  3changeset_next(
22070 70 49 74 65 72 29 20 29 7b 0a 20 20 20 20 69 6e  pIter) ){.    in
22080 74 20 6e 43 6f 6c 3b 0a 20 20 20 20 69 6e 74 20  t nCol;.    int 
22090 6f 70 3b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68  op;.    const ch
220a0 61 72 20 2a 7a 4e 65 77 3b 0a 20 20 20 20 0a 20  ar *zNew;.    . 
220b0 20 20 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65     sqlite3change
220c0 73 65 74 5f 6f 70 28 70 49 74 65 72 2c 20 26 7a  set_op(pIter, &z
220d0 4e 65 77 2c 20 26 6e 43 6f 6c 2c 20 26 6f 70 2c  New, &nCol, &op,
220e0 20 30 29 3b 0a 0a 20 20 20 20 69 66 28 20 7a 54   0);..    if( zT
220f0 61 62 3d 3d 30 20 7c 7c 20 73 71 6c 69 74 65 33  ab==0 || sqlite3
22100 5f 73 74 72 6e 69 63 6d 70 28 7a 4e 65 77 2c 20  _strnicmp(zNew, 
22110 7a 54 61 62 2c 20 6e 54 61 62 2b 31 29 20 29 7b  zTab, nTab+1) ){
22120 0a 20 20 20 20 20 20 75 38 20 2a 61 62 50 4b 3b  .      u8 *abPK;
22130 0a 0a 20 20 20 20 20 20 72 63 20 3d 20 73 65 73  ..      rc = ses
22140 73 69 6f 6e 52 65 74 72 79 43 6f 6e 73 74 72 61  sionRetryConstra
22150 69 6e 74 73 28 0a 20 20 20 20 20 20 20 20 20 20  ints(.          
22160 64 62 2c 20 70 49 74 65 72 2d 3e 62 50 61 74 63  db, pIter->bPatc
22170 68 73 65 74 2c 20 7a 54 61 62 2c 20 26 73 41 70  hset, zTab, &sAp
22180 70 6c 79 2c 20 78 43 6f 6e 66 6c 69 63 74 2c 20  ply, xConflict, 
22190 70 43 74 78 0a 20 20 20 20 20 20 29 3b 0a 20 20  pCtx.      );.  
221a0 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
221b0 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 0a  TE_OK ) break;..
221c0 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
221d0 65 65 28 28 63 68 61 72 2a 29 73 41 70 70 6c 79  ee((char*)sApply
221e0 2e 61 7a 43 6f 6c 29 3b 20 20 2f 2a 20 63 61 73  .azCol);  /* cas
221f0 74 20 77 6f 72 6b 73 20 61 72 6f 75 6e 64 20 56  t works around V
22200 43 2b 2b 20 62 75 67 20 2a 2f 0a 20 20 20 20 20  C++ bug */.     
22210 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
22220 65 28 73 41 70 70 6c 79 2e 70 44 65 6c 65 74 65  e(sApply.pDelete
22230 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  );.      sqlite3
22240 5f 66 69 6e 61 6c 69 7a 65 28 73 41 70 70 6c 79  _finalize(sApply
22250 2e 70 55 70 64 61 74 65 29 3b 20 0a 20 20 20 20  .pUpdate); .    
22260 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
22270 7a 65 28 73 41 70 70 6c 79 2e 70 49 6e 73 65 72  ze(sApply.pInser
22280 74 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  t);.      sqlite
22290 33 5f 66 69 6e 61 6c 69 7a 65 28 73 41 70 70 6c  3_finalize(sAppl
222a0 79 2e 70 53 65 6c 65 63 74 29 3b 0a 20 20 20 20  y.pSelect);.    
222b0 20 20 6d 65 6d 73 65 74 28 26 73 41 70 70 6c 79    memset(&sApply
222c0 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73 41 70 70  , 0, sizeof(sApp
222d0 6c 79 29 29 3b 0a 20 20 20 20 20 20 73 41 70 70  ly));.      sApp
222e0 6c 79 2e 64 62 20 3d 20 64 62 3b 0a 20 20 20 20  ly.db = db;.    
222f0 20 20 73 41 70 70 6c 79 2e 62 44 65 66 65 72 43    sApply.bDeferC
22300 6f 6e 73 74 72 61 69 6e 74 73 20 3d 20 31 3b 0a  onstraints = 1;.
22310 0a 20 20 20 20 20 20 2f 2a 20 49 66 20 61 6e 20  .      /* If an 
22320 78 46 69 6c 74 65 72 28 29 20 63 61 6c 6c 62 61  xFilter() callba
22330 63 6b 20 77 61 73 20 73 70 65 63 69 66 69 65 64  ck was specified
22340 2c 20 69 6e 76 6f 6b 65 20 69 74 20 6e 6f 77 2e  , invoke it now.
22350 20 49 66 20 74 68 65 20 0a 20 20 20 20 20 20 2a   If the .      *
22360 2a 20 78 46 69 6c 74 65 72 20 63 61 6c 6c 62 61  * xFilter callba
22370 63 6b 20 72 65 74 75 72 6e 73 20 7a 65 72 6f 2c  ck returns zero,
22380 20 73 6b 69 70 20 74 68 69 73 20 74 61 62 6c 65   skip this table
22390 2e 20 49 66 20 69 74 20 72 65 74 75 72 6e 73 0a  . If it returns.
223a0 20 20 20 20 20 20 2a 2a 20 6e 6f 6e 2d 7a 65 72        ** non-zer
223b0 6f 2c 20 70 72 6f 63 65 65 64 2e 20 2a 2f 0a 20  o, proceed. */. 
223c0 20 20 20 20 20 73 63 68 65 6d 61 4d 69 73 6d 61       schemaMisma
223d0 74 63 68 20 3d 20 28 78 46 69 6c 74 65 72 20 26  tch = (xFilter &
223e0 26 20 28 30 3d 3d 78 46 69 6c 74 65 72 28 70 43  & (0==xFilter(pC
223f0 74 78 2c 20 7a 4e 65 77 29 29 29 3b 0a 20 20 20  tx, zNew)));.   
22400 20 20 20 69 66 28 20 73 63 68 65 6d 61 4d 69 73     if( schemaMis
22410 6d 61 74 63 68 20 29 7b 0a 20 20 20 20 20 20 20  match ){.       
22420 20 7a 54 61 62 20 3d 20 73 71 6c 69 74 65 33 5f   zTab = sqlite3_
22430 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 4e  mprintf("%s", zN
22440 65 77 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  ew);.        if(
22450 20 7a 54 61 62 3d 3d 30 20 29 7b 0a 20 20 20 20   zTab==0 ){.    
22460 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
22470 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 20  E_NOMEM;.       
22480 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
22490 20 20 7d 0a 20 20 20 20 20 20 20 20 6e 54 61 62    }.        nTab
224a0 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28 7a   = (int)strlen(z
224b0 54 61 62 29 3b 0a 20 20 20 20 20 20 20 20 73 41  Tab);.        sA
224c0 70 70 6c 79 2e 61 7a 43 6f 6c 20 3d 20 28 63 6f  pply.azCol = (co
224d0 6e 73 74 20 63 68 61 72 20 2a 2a 29 7a 54 61 62  nst char **)zTab
224e0 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
224f0 20 20 20 20 20 20 20 69 6e 74 20 6e 4d 69 6e 43         int nMinC
22500 6f 6c 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  ol = 0;.        
22510 69 6e 74 20 69 3b 0a 0a 20 20 20 20 20 20 20 20  int i;..        
22520 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
22530 5f 70 6b 28 70 49 74 65 72 2c 20 26 61 62 50 4b  _pk(pIter, &abPK
22540 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20 72 63  , 0);.        rc
22550 20 3d 20 73 65 73 73 69 6f 6e 54 61 62 6c 65 49   = sessionTableI
22560 6e 66 6f 28 0a 20 20 20 20 20 20 20 20 20 20 20  nfo(.           
22570 20 64 62 2c 20 22 6d 61 69 6e 22 2c 20 7a 4e 65   db, "main", zNe
22580 77 2c 20 26 73 41 70 70 6c 79 2e 6e 43 6f 6c 2c  w, &sApply.nCol,
22590 20 26 7a 54 61 62 2c 20 26 73 41 70 70 6c 79 2e   &zTab, &sApply.
225a0 61 7a 43 6f 6c 2c 20 26 73 41 70 70 6c 79 2e 61  azCol, &sApply.a
225b0 62 50 4b 0a 20 20 20 20 20 20 20 20 29 3b 0a 20  bPK.        );. 
225c0 20 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53         if( rc!=S
225d0 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b  QLITE_OK ) break
225e0 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69 3d  ;.        for(i=
225f0 30 3b 20 69 3c 73 41 70 70 6c 79 2e 6e 43 6f 6c  0; i<sApply.nCol
22600 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
22610 20 20 69 66 28 20 73 41 70 70 6c 79 2e 61 62 50    if( sApply.abP
22620 4b 5b 69 5d 20 29 20 6e 4d 69 6e 43 6f 6c 20 3d  K[i] ) nMinCol =
22630 20 69 2b 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a   i+1;.        }.
22640 20 20 0a 20 20 20 20 20 20 20 20 69 66 28 20 73    .        if( s
22650 41 70 70 6c 79 2e 6e 43 6f 6c 3d 3d 30 20 29 7b  Apply.nCol==0 ){
22660 0a 20 20 20 20 20 20 20 20 20 20 73 63 68 65 6d  .          schem
22670 61 4d 69 73 6d 61 74 63 68 20 3d 20 31 3b 0a 20  aMismatch = 1;. 
22680 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33           sqlite3
22690 5f 6c 6f 67 28 53 51 4c 49 54 45 5f 53 43 48 45  _log(SQLITE_SCHE
226a0 4d 41 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20  MA, .           
226b0 20 20 20 22 73 71 6c 69 74 65 33 63 68 61 6e 67     "sqlite3chang
226c0 65 73 65 74 5f 61 70 70 6c 79 28 29 3a 20 6e 6f  eset_apply(): no
226d0 20 73 75 63 68 20 74 61 62 6c 65 3a 20 25 73 22   such table: %s"
226e0 2c 20 7a 54 61 62 0a 20 20 20 20 20 20 20 20 20  , zTab.         
226f0 20 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20   );.        }.  
22700 20 20 20 20 20 20 65 6c 73 65 20 69 66 28 20 73        else if( s
22710 41 70 70 6c 79 2e 6e 43 6f 6c 3c 6e 43 6f 6c 20  Apply.nCol<nCol 
22720 29 7b 0a 20 20 20 20 20 20 20 20 20 20 73 63 68  ){.          sch
22730 65 6d 61 4d 69 73 6d 61 74 63 68 20 3d 20 31 3b  emaMismatch = 1;
22740 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74  .          sqlit
22750 65 33 5f 6c 6f 67 28 53 51 4c 49 54 45 5f 53 43  e3_log(SQLITE_SC
22760 48 45 4d 41 2c 20 0a 20 20 20 20 20 20 20 20 20  HEMA, .         
22770 20 20 20 20 20 22 73 71 6c 69 74 65 33 63 68 61       "sqlite3cha
22780 6e 67 65 73 65 74 5f 61 70 70 6c 79 28 29 3a 20  ngeset_apply(): 
22790 74 61 62 6c 65 20 25 73 20 68 61 73 20 25 64 20  table %s has %d 
227a0 63 6f 6c 75 6d 6e 73 2c 20 22 0a 20 20 20 20 20  columns, ".     
227b0 20 20 20 20 20 20 20 20 20 22 65 78 70 65 63 74           "expect
227c0 65 64 20 25 64 20 6f 72 20 6d 6f 72 65 22 2c 20  ed %d or more", 
227d0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7a  .              z
227e0 54 61 62 2c 20 73 41 70 70 6c 79 2e 6e 43 6f 6c  Tab, sApply.nCol
227f0 2c 20 6e 43 6f 6c 0a 20 20 20 20 20 20 20 20 20  , nCol.         
22800 20 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20   );.        }.  
22810 20 20 20 20 20 20 65 6c 73 65 20 69 66 28 20 6e        else if( n
22820 43 6f 6c 3c 6e 4d 69 6e 43 6f 6c 20 7c 7c 20 6d  Col<nMinCol || m
22830 65 6d 63 6d 70 28 73 41 70 70 6c 79 2e 61 62 50  emcmp(sApply.abP
22840 4b 2c 20 61 62 50 4b 2c 20 6e 43 6f 6c 29 21 3d  K, abPK, nCol)!=
22850 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 73  0 ){.          s
22860 63 68 65 6d 61 4d 69 73 6d 61 74 63 68 20 3d 20  chemaMismatch = 
22870 31 3b 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c  1;.          sql
22880 69 74 65 33 5f 6c 6f 67 28 53 51 4c 49 54 45 5f  ite3_log(SQLITE_
22890 53 43 48 45 4d 41 2c 20 22 73 71 6c 69 74 65 33  SCHEMA, "sqlite3
228a0 63 68 61 6e 67 65 73 65 74 5f 61 70 70 6c 79 28  changeset_apply(
228b0 29 3a 20 22 0a 20 20 20 20 20 20 20 20 20 20 20  ): ".           
228c0 20 20 20 22 70 72 69 6d 61 72 79 20 6b 65 79 20     "primary key 
228d0 6d 69 73 6d 61 74 63 68 20 66 6f 72 20 74 61 62  mismatch for tab
228e0 6c 65 20 25 73 22 2c 20 7a 54 61 62 0a 20 20 20  le %s", zTab.   
228f0 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20         );.      
22900 20 20 7d 0a 20 20 20 20 20 20 20 20 65 6c 73 65    }.        else
22910 7b 0a 20 20 20 20 20 20 20 20 20 20 73 41 70 70  {.          sApp
22920 6c 79 2e 6e 43 6f 6c 20 3d 20 6e 43 6f 6c 3b 0a  ly.nCol = nCol;.
22930 20 20 20 20 20 20 20 20 20 20 69 66 28 20 30 3d            if( 0=
22940 3d 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d 70  =sqlite3_stricmp
22950 28 7a 54 61 62 2c 20 22 73 71 6c 69 74 65 5f 73  (zTab, "sqlite_s
22960 74 61 74 31 22 29 20 29 7b 0a 20 20 20 20 20 20  tat1") ){.      
22970 20 20 20 20 20 20 69 66 28 20 28 72 63 20 3d 20        if( (rc = 
22980 73 65 73 73 69 6f 6e 53 74 61 74 31 53 71 6c 28  sessionStat1Sql(
22990 64 62 2c 20 26 73 41 70 70 6c 79 29 20 29 20 29  db, &sApply) ) )
229a0 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  {.              
229b0 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 20  break;.         
229c0 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20     }.           
229d0 20 73 41 70 70 6c 79 2e 62 53 74 61 74 31 20 3d   sApply.bStat1 =
229e0 20 31 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 65   1;.          }e
229f0 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 20  lse{.           
22a00 20 69 66 28 28 72 63 20 3d 20 73 65 73 73 69 6f   if((rc = sessio
22a10 6e 53 65 6c 65 63 74 52 6f 77 28 64 62 2c 20 7a  nSelectRow(db, z
22a20 54 61 62 2c 20 26 73 41 70 70 6c 79 29 29 0a 20  Tab, &sApply)). 
22a30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7c                 |
22a40 7c 20 28 72 63 20 3d 20 73 65 73 73 69 6f 6e 55  | (rc = sessionU
22a50 70 64 61 74 65 52 6f 77 28 64 62 2c 20 7a 54 61  pdateRow(db, zTa
22a60 62 2c 20 26 73 41 70 70 6c 79 29 29 0a 20 20 20  b, &sApply)).   
22a70 20 20 20 20 20 20 20 20 20 20 20 20 20 7c 7c 20               || 
22a80 28 72 63 20 3d 20 73 65 73 73 69 6f 6e 44 65 6c  (rc = sessionDel
22a90 65 74 65 52 6f 77 28 64 62 2c 20 7a 54 61 62 2c  eteRow(db, zTab,
22aa0 20 26 73 41 70 70 6c 79 29 29 0a 20 20 20 20 20   &sApply)).     
22ab0 20 20 20 20 20 20 20 20 20 20 20 7c 7c 20 28 72             || (r
22ac0 63 20 3d 20 73 65 73 73 69 6f 6e 49 6e 73 65 72  c = sessionInser
22ad0 74 52 6f 77 28 64 62 2c 20 7a 54 61 62 2c 20 26  tRow(db, zTab, &
22ae0 73 41 70 70 6c 79 29 29 0a 20 20 20 20 20 20 20  sApply)).       
22af0 20 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20         ){.      
22b00 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
22b10 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20             }.   
22b20 20 20 20 20 20 20 20 20 20 73 41 70 70 6c 79 2e           sApply.
22b30 62 53 74 61 74 31 20 3d 20 30 3b 0a 20 20 20 20  bStat1 = 0;.    
22b40 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
22b50 7d 0a 20 20 20 20 20 20 20 20 6e 54 61 62 20 3d  }.        nTab =
22b60 20 73 71 6c 69 74 65 33 53 74 72 6c 65 6e 33 30   sqlite3Strlen30
22b70 28 7a 54 61 62 29 3b 0a 20 20 20 20 20 20 7d 0a  (zTab);.      }.
22b80 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66      }..    /* If
22b90 20 74 68 65 72 65 20 69 73 20 61 20 73 63 68 65   there is a sche
22ba0 6d 61 20 6d 69 73 6d 61 74 63 68 20 6f 6e 20 74  ma mismatch on t
22bb0 68 65 20 63 75 72 72 65 6e 74 20 74 61 62 6c 65  he current table
22bc0 2c 20 70 72 6f 63 65 65 64 20 74 6f 20 74 68 65  , proceed to the
22bd0 0a 20 20 20 20 2a 2a 20 6e 65 78 74 20 63 68 61  .    ** next cha
22be0 6e 67 65 2e 20 41 20 6c 6f 67 20 6d 65 73 73 61  nge. A log messa
22bf0 67 65 20 68 61 73 20 61 6c 72 65 61 64 79 20 62  ge has already b
22c00 65 65 6e 20 69 73 73 75 65 64 2e 20 2a 2f 0a 20  een issued. */. 
22c10 20 20 20 69 66 28 20 73 63 68 65 6d 61 4d 69 73     if( schemaMis
22c20 6d 61 74 63 68 20 29 20 63 6f 6e 74 69 6e 75 65  match ) continue
22c30 3b 0a 0a 20 20 20 20 72 63 20 3d 20 73 65 73 73  ;..    rc = sess
22c40 69 6f 6e 41 70 70 6c 79 4f 6e 65 57 69 74 68 52  ionApplyOneWithR
22c50 65 74 72 79 28 64 62 2c 20 70 49 74 65 72 2c 20  etry(db, pIter, 
22c60 26 73 41 70 70 6c 79 2c 20 78 43 6f 6e 66 6c 69  &sApply, xConfli
22c70 63 74 2c 20 70 43 74 78 29 3b 0a 20 20 7d 0a 0a  ct, pCtx);.  }..
22c80 20 20 62 50 61 74 63 68 73 65 74 20 3d 20 70 49    bPatchset = pI
22c90 74 65 72 2d 3e 62 50 61 74 63 68 73 65 74 3b 0a  ter->bPatchset;.
22ca0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
22cb0 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
22cc0 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
22cd0 5f 66 69 6e 61 6c 69 7a 65 28 70 49 74 65 72 29  _finalize(pIter)
22ce0 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73  ;.  }else{.    s
22cf0 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
22d00 66 69 6e 61 6c 69 7a 65 28 70 49 74 65 72 29 3b  finalize(pIter);
22d10 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
22d20 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
22d30 20 72 63 20 3d 20 73 65 73 73 69 6f 6e 52 65 74   rc = sessionRet
22d40 72 79 43 6f 6e 73 74 72 61 69 6e 74 73 28 64 62  ryConstraints(db
22d50 2c 20 62 50 61 74 63 68 73 65 74 2c 20 7a 54 61  , bPatchset, zTa
22d60 62 2c 20 26 73 41 70 70 6c 79 2c 20 78 43 6f 6e  b, &sApply, xCon
22d70 66 6c 69 63 74 2c 20 70 43 74 78 29 3b 0a 20 20  flict, pCtx);.  
22d80 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
22d90 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e  ITE_OK ){.    in
22da0 74 20 6e 46 6b 2c 20 6e 6f 74 55 73 65 64 3b 0a  t nFk, notUsed;.
22db0 20 20 20 20 73 71 6c 69 74 65 33 5f 64 62 5f 73      sqlite3_db_s
22dc0 74 61 74 75 73 28 64 62 2c 20 53 51 4c 49 54 45  tatus(db, SQLITE
22dd0 5f 44 42 53 54 41 54 55 53 5f 44 45 46 45 52 52  _DBSTATUS_DEFERR
22de0 45 44 5f 46 4b 53 2c 20 26 6e 46 6b 2c 20 26 6e  ED_FKS, &nFk, &n
22df0 6f 74 55 73 65 64 2c 20 30 29 3b 0a 20 20 20 20  otUsed, 0);.    
22e00 69 66 28 20 6e 46 6b 21 3d 30 20 29 7b 0a 20 20  if( nFk!=0 ){.  
22e10 20 20 20 20 69 6e 74 20 72 65 73 20 3d 20 53 51      int res = SQ
22e20 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 41  LITE_CHANGESET_A
22e30 42 4f 52 54 3b 0a 20 20 20 20 20 20 73 71 6c 69  BORT;.      sqli
22e40 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74  te3_changeset_it
22e50 65 72 20 73 49 74 65 72 3b 0a 20 20 20 20 20 20  er sIter;.      
22e60 6d 65 6d 73 65 74 28 26 73 49 74 65 72 2c 20 30  memset(&sIter, 0
22e70 2c 20 73 69 7a 65 6f 66 28 73 49 74 65 72 29 29  , sizeof(sIter))
22e80 3b 0a 20 20 20 20 20 20 73 49 74 65 72 2e 6e 43  ;.      sIter.nC
22e90 6f 6c 20 3d 20 6e 46 6b 3b 0a 20 20 20 20 20 20  ol = nFk;.      
22ea0 72 65 73 20 3d 20 78 43 6f 6e 66 6c 69 63 74 28  res = xConflict(
22eb0 70 43 74 78 2c 20 53 51 4c 49 54 45 5f 43 48 41  pCtx, SQLITE_CHA
22ec0 4e 47 45 53 45 54 5f 46 4f 52 45 49 47 4e 5f 4b  NGESET_FOREIGN_K
22ed0 45 59 2c 20 26 73 49 74 65 72 29 3b 0a 20 20 20  EY, &sIter);.   
22ee0 20 20 20 69 66 28 20 72 65 73 21 3d 53 51 4c 49     if( res!=SQLI
22ef0 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 4f 4d 49  TE_CHANGESET_OMI
22f00 54 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  T ){.        rc 
22f10 3d 20 53 51 4c 49 54 45 5f 43 4f 4e 53 54 52 41  = SQLITE_CONSTRA
22f20 49 4e 54 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  INT;.      }.   
22f30 20 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33   }.  }.  sqlite3
22f40 5f 65 78 65 63 28 64 62 2c 20 22 50 52 41 47 4d  _exec(db, "PRAGM
22f50 41 20 64 65 66 65 72 5f 66 6f 72 65 69 67 6e 5f  A defer_foreign_
22f60 6b 65 79 73 20 3d 20 30 22 2c 20 30 2c 20 30 2c  keys = 0", 0, 0,
22f70 20 30 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d   0);..  if( rc==
22f80 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
22f90 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78   rc = sqlite3_ex
22fa0 65 63 28 64 62 2c 20 22 52 45 4c 45 41 53 45 20  ec(db, "RELEASE 
22fb0 63 68 61 6e 67 65 73 65 74 5f 61 70 70 6c 79 22  changeset_apply"
22fc0 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20 7d 65  , 0, 0, 0);.  }e
22fd0 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  lse{.    sqlite3
22fe0 5f 65 78 65 63 28 64 62 2c 20 22 52 4f 4c 4c 42  _exec(db, "ROLLB
22ff0 41 43 4b 20 54 4f 20 63 68 61 6e 67 65 73 65 74  ACK TO changeset
23000 5f 61 70 70 6c 79 22 2c 20 30 2c 20 30 2c 20 30  _apply", 0, 0, 0
23010 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 65  );.    sqlite3_e
23020 78 65 63 28 64 62 2c 20 22 52 45 4c 45 41 53 45  xec(db, "RELEASE
23030 20 63 68 61 6e 67 65 73 65 74 5f 61 70 70 6c 79   changeset_apply
23040 22 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20 7d  ", 0, 0, 0);.  }
23050 0a 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  ..  sqlite3_fina
23060 6c 69 7a 65 28 73 41 70 70 6c 79 2e 70 49 6e 73  lize(sApply.pIns
23070 65 72 74 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  ert);.  sqlite3_
23080 66 69 6e 61 6c 69 7a 65 28 73 41 70 70 6c 79 2e  finalize(sApply.
23090 70 44 65 6c 65 74 65 29 3b 0a 20 20 73 71 6c 69  pDelete);.  sqli
230a0 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 73 41 70  te3_finalize(sAp
230b0 70 6c 79 2e 70 55 70 64 61 74 65 29 3b 0a 20 20  ply.pUpdate);.  
230c0 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65  sqlite3_finalize
230d0 28 73 41 70 70 6c 79 2e 70 53 65 6c 65 63 74 29  (sApply.pSelect)
230e0 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
230f0 28 28 63 68 61 72 2a 29 73 41 70 70 6c 79 2e 61  ((char*)sApply.a
23100 7a 43 6f 6c 29 3b 20 20 2f 2a 20 63 61 73 74 20  zCol);  /* cast 
23110 77 6f 72 6b 73 20 61 72 6f 75 6e 64 20 56 43 2b  works around VC+
23120 2b 20 62 75 67 20 2a 2f 0a 20 20 73 71 6c 69 74  + bug */.  sqlit
23130 65 33 5f 66 72 65 65 28 28 63 68 61 72 2a 29 73  e3_free((char*)s
23140 41 70 70 6c 79 2e 63 6f 6e 73 74 72 61 69 6e 74  Apply.constraint
23150 73 2e 61 42 75 66 29 3b 0a 20 20 73 71 6c 69 74  s.aBuf);.  sqlit
23160 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 73  e3_mutex_leave(s
23170 71 6c 69 74 65 33 5f 64 62 5f 6d 75 74 65 78 28  qlite3_db_mutex(
23180 64 62 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  db));.  return r
23190 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 6c  c;.}../*.** Appl
231a0 79 20 74 68 65 20 63 68 61 6e 67 65 73 65 74 20  y the changeset 
231b0 70 61 73 73 65 64 20 76 69 61 20 70 43 68 61 6e  passed via pChan
231c0 67 65 73 65 74 2f 6e 43 68 61 6e 67 65 73 65 74  geset/nChangeset
231d0 20 74 6f 20 74 68 65 20 6d 61 69 6e 20 64 61 74   to the main dat
231e0 61 62 61 73 65 0a 2a 2a 20 61 74 74 61 63 68 65  abase.** attache
231f0 64 20 74 6f 20 68 61 6e 64 6c 65 20 22 64 62 22  d to handle "db"
23200 2e 20 49 6e 76 6f 6b 65 20 74 68 65 20 73 75 70  . Invoke the sup
23210 70 6c 69 65 64 20 63 6f 6e 66 6c 69 63 74 20 68  plied conflict h
23220 61 6e 64 6c 65 72 20 63 61 6c 6c 62 61 63 6b 0a  andler callback.
23230 2a 2a 20 74 6f 20 72 65 73 6f 6c 76 65 20 61 6e  ** to resolve an
23240 79 20 63 6f 6e 66 6c 69 63 74 73 20 65 6e 63 6f  y conflicts enco
23250 75 6e 74 65 72 65 64 20 77 68 69 6c 65 20 61 70  untered while ap
23260 70 6c 79 69 6e 67 20 74 68 65 20 63 68 61 6e 67  plying the chang
23270 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
23280 33 63 68 61 6e 67 65 73 65 74 5f 61 70 70 6c 79  3changeset_apply
23290 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
232a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
232b0 20 20 20 20 2f 2a 20 41 70 70 6c 79 20 63 68 61      /* Apply cha
232c0 6e 67 65 20 74 6f 20 22 6d 61 69 6e 22 20 64 62  nge to "main" db
232d0 20 6f 66 20 74 68 69 73 20 68 61 6e 64 6c 65 20   of this handle 
232e0 2a 2f 0a 20 20 69 6e 74 20 6e 43 68 61 6e 67 65  */.  int nChange
232f0 73 65 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  set,            
23300 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
23310 63 68 61 6e 67 65 73 65 74 20 69 6e 20 62 79 74  changeset in byt
23320 65 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 43  es */.  void *pC
23330 68 61 6e 67 65 73 65 74 2c 20 20 20 20 20 20 20  hangeset,       
23340 20 20 20 20 20 20 20 20 2f 2a 20 43 68 61 6e 67          /* Chang
23350 65 73 65 74 20 62 6c 6f 62 20 2a 2f 0a 20 20 69  eset blob */.  i
23360 6e 74 28 2a 78 46 69 6c 74 65 72 29 28 0a 20 20  nt(*xFilter)(.  
23370 20 20 76 6f 69 64 20 2a 70 43 74 78 2c 20 20 20    void *pCtx,   
23380 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
23390 2f 2a 20 43 6f 70 79 20 6f 66 20 73 69 78 74 68  /* Copy of sixth
233a0 20 61 72 67 20 74 6f 20 5f 61 70 70 6c 79 28 29   arg to _apply()
233b0 20 2a 2f 0a 20 20 20 20 63 6f 6e 73 74 20 63 68   */.    const ch
233c0 61 72 20 2a 7a 54 61 62 20 20 20 20 20 20 20 20  ar *zTab        
233d0 20 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20 6e        /* Table n
233e0 61 6d 65 20 2a 2f 0a 20 20 29 2c 0a 20 20 69 6e  ame */.  ),.  in
233f0 74 28 2a 78 43 6f 6e 66 6c 69 63 74 29 28 0a 20  t(*xConflict)(. 
23400 20 20 20 76 6f 69 64 20 2a 70 43 74 78 2c 20 20     void *pCtx,  
23410 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
23420 20 2f 2a 20 43 6f 70 79 20 6f 66 20 66 69 66 74   /* Copy of fift
23430 68 20 61 72 67 20 74 6f 20 5f 61 70 70 6c 79 28  h arg to _apply(
23440 29 20 2a 2f 0a 20 20 20 20 69 6e 74 20 65 43 6f  ) */.    int eCo
23450 6e 66 6c 69 63 74 2c 20 20 20 20 20 20 20 20 20  nflict,         
23460 20 20 20 20 20 20 20 2f 2a 20 44 41 54 41 2c 20         /* DATA, 
23470 4d 49 53 53 49 4e 47 2c 20 43 4f 4e 46 4c 49 43  MISSING, CONFLIC
23480 54 2c 20 43 4f 4e 53 54 52 41 49 4e 54 20 2a 2f  T, CONSTRAINT */
23490 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 63 68 61  .    sqlite3_cha
234a0 6e 67 65 73 65 74 5f 69 74 65 72 20 2a 70 20 20  ngeset_iter *p  
234b0 20 20 20 2f 2a 20 48 61 6e 64 6c 65 20 64 65 73     /* Handle des
234c0 63 72 69 62 69 6e 67 20 63 68 61 6e 67 65 20 61  cribing change a
234d0 6e 64 20 63 6f 6e 66 6c 69 63 74 20 2a 2f 0a 20  nd conflict */. 
234e0 20 29 2c 0a 20 20 76 6f 69 64 20 2a 70 43 74 78   ),.  void *pCtx
234f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
23500 20 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 61        /* First a
23510 72 67 75 6d 65 6e 74 20 70 61 73 73 65 64 20 74  rgument passed t
23520 6f 20 78 43 6f 6e 66 6c 69 63 74 20 2a 2f 0a 29  o xConflict */.)
23530 7b 0a 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e  {.  sqlite3_chan
23540 67 65 73 65 74 5f 69 74 65 72 20 2a 70 49 74 65  geset_iter *pIte
23550 72 3b 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20  r;  /* Iterator 
23560 74 6f 20 73 6b 69 70 20 74 68 72 6f 75 67 68 20  to skip through 
23570 63 68 61 6e 67 65 73 65 74 20 2a 2f 20 20 0a 20  changeset */  . 
23580 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 69 74 65   int rc = sqlite
23590 33 63 68 61 6e 67 65 73 65 74 5f 73 74 61 72 74  3changeset_start
235a0 28 26 70 49 74 65 72 2c 20 6e 43 68 61 6e 67 65  (&pIter, nChange
235b0 73 65 74 2c 20 70 43 68 61 6e 67 65 73 65 74 29  set, pChangeset)
235c0 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
235d0 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  TE_OK ){.    rc 
235e0 3d 20 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73  = sessionChanges
235f0 65 74 41 70 70 6c 79 28 64 62 2c 20 70 49 74 65  etApply(db, pIte
23600 72 2c 20 78 46 69 6c 74 65 72 2c 20 78 43 6f 6e  r, xFilter, xCon
23610 66 6c 69 63 74 2c 20 70 43 74 78 29 3b 0a 20 20  flict, pCtx);.  
23620 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
23630 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 6c 79 20 74 68  ../*.** Apply th
23640 65 20 63 68 61 6e 67 65 73 65 74 20 70 61 73 73  e changeset pass
23650 65 64 20 76 69 61 20 78 49 6e 70 75 74 2f 70 49  ed via xInput/pI
23660 6e 20 74 6f 20 74 68 65 20 6d 61 69 6e 20 64 61  n to the main da
23670 74 61 62 61 73 65 0a 2a 2a 20 61 74 74 61 63 68  tabase.** attach
23680 65 64 20 74 6f 20 68 61 6e 64 6c 65 20 22 64 62  ed to handle "db
23690 22 2e 20 49 6e 76 6f 6b 65 20 74 68 65 20 73 75  ". Invoke the su
236a0 70 70 6c 69 65 64 20 63 6f 6e 66 6c 69 63 74 20  pplied conflict 
236b0 68 61 6e 64 6c 65 72 20 63 61 6c 6c 62 61 63 6b  handler callback
236c0 0a 2a 2a 20 74 6f 20 72 65 73 6f 6c 76 65 20 61  .** to resolve a
236d0 6e 79 20 63 6f 6e 66 6c 69 63 74 73 20 65 6e 63  ny conflicts enc
236e0 6f 75 6e 74 65 72 65 64 20 77 68 69 6c 65 20 61  ountered while a
236f0 70 70 6c 79 69 6e 67 20 74 68 65 20 63 68 61 6e  pplying the chan
23700 67 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ge..*/.int sqlit
23710 65 33 63 68 61 6e 67 65 73 65 74 5f 61 70 70 6c  e3changeset_appl
23720 79 5f 73 74 72 6d 28 0a 20 20 73 71 6c 69 74 65  y_strm(.  sqlite
23730 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20  3 *db,          
23740 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 70 70            /* App
23750 6c 79 20 63 68 61 6e 67 65 20 74 6f 20 22 6d 61  ly change to "ma
23760 69 6e 22 20 64 62 20 6f 66 20 74 68 69 73 20 68  in" db of this h
23770 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 28  andle */.  int (
23780 2a 78 49 6e 70 75 74 29 28 76 6f 69 64 20 2a 70  *xInput)(void *p
23790 49 6e 2c 20 76 6f 69 64 20 2a 70 44 61 74 61 2c  In, void *pData,
237a0 20 69 6e 74 20 2a 70 6e 44 61 74 61 29 2c 20 2f   int *pnData), /
237b0 2a 20 49 6e 70 75 74 20 66 75 6e 63 74 69 6f 6e  * Input function
237c0 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 49 6e 2c   */.  void *pIn,
237d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
237e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
237f0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72            /* Fir
23800 73 74 20 61 72 67 20 66 6f 72 20 78 49 6e 70 75  st arg for xInpu
23810 74 20 2a 2f 0a 20 20 69 6e 74 28 2a 78 46 69 6c  t */.  int(*xFil
23820 74 65 72 29 28 0a 20 20 20 20 76 6f 69 64 20 2a  ter)(.    void *
23830 70 43 74 78 2c 20 20 20 20 20 20 20 20 20 20 20  pCtx,           
23840 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 70 79 20          /* Copy 
23850 6f 66 20 73 69 78 74 68 20 61 72 67 20 74 6f 20  of sixth arg to 
23860 5f 61 70 70 6c 79 28 29 20 2a 2f 0a 20 20 20 20  _apply() */.    
23870 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 62  const char *zTab
23880 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
23890 20 54 61 62 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20   Table name */. 
238a0 20 29 2c 0a 20 20 69 6e 74 28 2a 78 43 6f 6e 66   ),.  int(*xConf
238b0 6c 69 63 74 29 28 0a 20 20 20 20 76 6f 69 64 20  lict)(.    void 
238c0 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20 20  *pCtx,          
238d0 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 70 79           /* Copy
238e0 20 6f 66 20 73 69 78 74 68 20 61 72 67 20 74 6f   of sixth arg to
238f0 20 5f 61 70 70 6c 79 28 29 20 2a 2f 0a 20 20 20   _apply() */.   
23900 20 69 6e 74 20 65 43 6f 6e 66 6c 69 63 74 2c 20   int eConflict, 
23910 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
23920 2a 20 44 41 54 41 2c 20 4d 49 53 53 49 4e 47 2c  * DATA, MISSING,
23930 20 43 4f 4e 46 4c 49 43 54 2c 20 43 4f 4e 53 54   CONFLICT, CONST
23940 52 41 49 4e 54 20 2a 2f 0a 20 20 20 20 73 71 6c  RAINT */.    sql
23950 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69  ite3_changeset_i
23960 74 65 72 20 2a 70 20 20 20 20 20 2f 2a 20 48 61  ter *p     /* Ha
23970 6e 64 6c 65 20 64 65 73 63 72 69 62 69 6e 67 20  ndle describing 
23980 63 68 61 6e 67 65 20 61 6e 64 20 63 6f 6e 66 6c  change and confl
23990 69 63 74 20 2a 2f 0a 20 20 29 2c 0a 20 20 76 6f  ict */.  ),.  vo
239a0 69 64 20 2a 70 43 74 78 20 20 20 20 20 20 20 20  id *pCtx        
239b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
239c0 20 46 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20   First argument 
239d0 70 61 73 73 65 64 20 74 6f 20 78 43 6f 6e 66 6c  passed to xConfl
239e0 69 63 74 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69  ict */.){.  sqli
239f0 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74  te3_changeset_it
23a00 65 72 20 2a 70 49 74 65 72 3b 20 20 2f 2a 20 49  er *pIter;  /* I
23a10 74 65 72 61 74 6f 72 20 74 6f 20 73 6b 69 70 20  terator to skip 
23a20 74 68 72 6f 75 67 68 20 63 68 61 6e 67 65 73 65  through changese
23a30 74 20 2a 2f 20 20 0a 20 20 69 6e 74 20 72 63 20  t */  .  int rc 
23a40 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  = sqlite3changes
23a50 65 74 5f 73 74 61 72 74 5f 73 74 72 6d 28 26 70  et_start_strm(&p
23a60 49 74 65 72 2c 20 78 49 6e 70 75 74 2c 20 70 49  Iter, xInput, pI
23a70 6e 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  n);.  if( rc==SQ
23a80 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
23a90 63 20 3d 20 73 65 73 73 69 6f 6e 43 68 61 6e 67  c = sessionChang
23aa0 65 73 65 74 41 70 70 6c 79 28 64 62 2c 20 70 49  esetApply(db, pI
23ab0 74 65 72 2c 20 78 46 69 6c 74 65 72 2c 20 78 43  ter, xFilter, xC
23ac0 6f 6e 66 6c 69 63 74 2c 20 70 43 74 78 29 3b 0a  onflict, pCtx);.
23ad0 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
23ae0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 73 71 6c 69 74 65  .}../*.** sqlite
23af0 33 5f 63 68 61 6e 67 65 67 72 6f 75 70 20 68 61  3_changegroup ha
23b00 6e 64 6c 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  ndle..*/.struct 
23b10 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 67 72  sqlite3_changegr
23b20 6f 75 70 20 7b 0a 20 20 69 6e 74 20 72 63 3b 20  oup {.  int rc; 
23b30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
23b40 20 20 20 20 20 20 20 20 2f 2a 20 45 72 72 6f 72          /* Error
23b50 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 62   code */.  int b
23b60 50 61 74 63 68 3b 20 20 20 20 20 20 20 20 20 20  Patch;          
23b70 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
23b80 75 65 20 74 6f 20 61 63 63 75 6d 75 6c 61 74 65  ue to accumulate
23b90 20 70 61 74 63 68 73 65 74 73 20 2a 2f 0a 20 20   patchsets */.  
23ba0 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70 4c  SessionTable *pL
23bb0 69 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ist;            
23bc0 2f 2a 20 4c 69 73 74 20 6f 66 20 74 61 62 6c 65  /* List of table
23bd0 73 20 69 6e 20 63 75 72 72 65 6e 74 20 70 61 74  s in current pat
23be0 63 68 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  ch */.};../*.** 
23bf0 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
23c00 20 63 61 6c 6c 65 64 20 74 6f 20 6d 65 72 67 65   called to merge
23c10 20 74 77 6f 20 63 68 61 6e 67 65 73 20 74 6f 20   two changes to 
23c20 74 68 65 20 73 61 6d 65 20 72 6f 77 20 74 6f 67  the same row tog
23c30 65 74 68 65 72 20 61 73 0a 2a 2a 20 70 61 72 74  ether as.** part
23c40 20 6f 66 20 61 6e 20 73 71 6c 69 74 65 33 63 68   of an sqlite3ch
23c50 61 6e 67 65 73 65 74 5f 63 6f 6e 63 61 74 28 29  angeset_concat()
23c60 20 6f 70 65 72 61 74 69 6f 6e 2e 20 41 20 6e 65   operation. A ne
23c70 77 20 63 68 61 6e 67 65 20 6f 62 6a 65 63 74 20  w change object 
23c80 69 73 0a 2a 2a 20 61 6c 6c 6f 63 61 74 65 64 20  is.** allocated 
23c90 61 6e 64 20 61 20 70 6f 69 6e 74 65 72 20 74 6f  and a pointer to
23ca0 20 69 74 20 73 74 6f 72 65 64 20 69 6e 20 2a 70   it stored in *p
23cb0 70 4e 65 77 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  pNew..*/.static 
23cc0 69 6e 74 20 73 65 73 73 69 6f 6e 43 68 61 6e 67  int sessionChang
23cd0 65 4d 65 72 67 65 28 0a 20 20 53 65 73 73 69 6f  eMerge(.  Sessio
23ce0 6e 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 20 20  nTable *pTab,   
23cf0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 62            /* Tab
23d00 6c 65 20 73 74 72 75 63 74 75 72 65 20 2a 2f 0a  le structure */.
23d10 20 20 69 6e 74 20 62 50 61 74 63 68 73 65 74 2c    int bPatchset,
23d20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
23d30 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 70 61    /* True for pa
23d40 74 63 68 73 65 74 73 20 2a 2f 0a 20 20 53 65 73  tchsets */.  Ses
23d50 73 69 6f 6e 43 68 61 6e 67 65 20 2a 70 45 78 69  sionChange *pExi
23d60 73 74 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  st,          /* 
23d70 45 78 69 73 74 69 6e 67 20 63 68 61 6e 67 65 20  Existing change 
23d80 2a 2f 0a 20 20 69 6e 74 20 6f 70 32 2c 20 20 20  */.  int op2,   
23d90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
23da0 20 20 20 20 20 2f 2a 20 53 65 63 6f 6e 64 20 63       /* Second c
23db0 68 61 6e 67 65 20 6f 70 65 72 61 74 69 6f 6e 20  hange operation 
23dc0 2a 2f 0a 20 20 69 6e 74 20 62 49 6e 64 69 72 65  */.  int bIndire
23dd0 63 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ct,             
23de0 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
23df0 73 65 63 6f 6e 64 20 63 68 61 6e 67 65 20 69 73  second change is
23e00 20 69 6e 64 69 72 65 63 74 20 2a 2f 0a 20 20 75   indirect */.  u
23e10 38 20 2a 61 52 65 63 2c 20 20 20 20 20 20 20 20  8 *aRec,        
23e20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
23e30 2a 20 53 65 63 6f 6e 64 20 63 68 61 6e 67 65 20  * Second change 
23e40 72 65 63 6f 72 64 20 2a 2f 0a 20 20 69 6e 74 20  record */.  int 
23e50 6e 52 65 63 2c 20 20 20 20 20 20 20 20 20 20 20  nRec,           
23e60 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
23e70 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69  umber of bytes i
23e80 6e 20 61 52 65 63 20 2a 2f 0a 20 20 53 65 73 73  n aRec */.  Sess
23e90 69 6f 6e 43 68 61 6e 67 65 20 2a 2a 70 70 4e 65  ionChange **ppNe
23ea0 77 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f  w           /* O
23eb0 55 54 3a 20 4d 65 72 67 65 64 20 63 68 61 6e 67  UT: Merged chang
23ec0 65 20 2a 2f 0a 29 7b 0a 20 20 53 65 73 73 69 6f  e */.){.  Sessio
23ed0 6e 43 68 61 6e 67 65 20 2a 70 4e 65 77 20 3d 20  nChange *pNew = 
23ee0 30 3b 0a 0a 20 20 69 66 28 20 21 70 45 78 69 73  0;..  if( !pExis
23ef0 74 20 29 7b 0a 20 20 20 20 70 4e 65 77 20 3d 20  t ){.    pNew = 
23f00 28 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a  (SessionChange *
23f10 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28  )sqlite3_malloc(
23f20 73 69 7a 65 6f 66 28 53 65 73 73 69 6f 6e 43 68  sizeof(SessionCh
23f30 61 6e 67 65 29 20 2b 20 6e 52 65 63 29 3b 0a 20  ange) + nRec);. 
23f40 20 20 20 69 66 28 20 21 70 4e 65 77 20 29 7b 0a     if( !pNew ){.
23f50 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c        return SQL
23f60 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d  ITE_NOMEM;.    }
23f70 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 4e 65 77  .    memset(pNew
23f80 2c 20 30 2c 20 73 69 7a 65 6f 66 28 53 65 73 73  , 0, sizeof(Sess
23f90 69 6f 6e 43 68 61 6e 67 65 29 29 3b 0a 20 20 20  ionChange));.   
23fa0 20 70 4e 65 77 2d 3e 6f 70 20 3d 20 6f 70 32 3b   pNew->op = op2;
23fb0 0a 20 20 20 20 70 4e 65 77 2d 3e 62 49 6e 64 69  .    pNew->bIndi
23fc0 72 65 63 74 20 3d 20 62 49 6e 64 69 72 65 63 74  rect = bIndirect
23fd0 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 6e 52 65 63  ;.    pNew->nRec
23fe0 6f 72 64 20 3d 20 6e 52 65 63 3b 0a 20 20 20 20  ord = nRec;.    
23ff0 70 4e 65 77 2d 3e 61 52 65 63 6f 72 64 20 3d 20  pNew->aRecord = 
24000 28 75 38 2a 29 26 70 4e 65 77 5b 31 5d 3b 0a 20  (u8*)&pNew[1];. 
24010 20 20 20 6d 65 6d 63 70 79 28 70 4e 65 77 2d 3e     memcpy(pNew->
24020 61 52 65 63 6f 72 64 2c 20 61 52 65 63 2c 20 6e  aRecord, aRec, n
24030 52 65 63 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  Rec);.  }else{. 
24040 20 20 20 69 6e 74 20 6f 70 31 20 3d 20 70 45 78     int op1 = pEx
24050 69 73 74 2d 3e 6f 70 3b 0a 0a 20 20 20 20 2f 2a  ist->op;..    /*
24060 20 0a 20 20 20 20 2a 2a 20 20 20 6f 70 31 3d 49   .    **   op1=I
24070 4e 53 45 52 54 2c 20 6f 70 32 3d 49 4e 53 45 52  NSERT, op2=INSER
24080 54 20 20 20 20 20 20 2d 3e 20 20 20 20 20 20 55  T      ->      U
24090 6e 73 75 70 70 6f 72 74 65 64 2e 20 44 69 73 63  nsupported. Disc
240a0 61 72 64 20 6f 70 32 2e 0a 20 20 20 20 2a 2a 20  ard op2..    ** 
240b0 20 20 6f 70 31 3d 49 4e 53 45 52 54 2c 20 6f 70    op1=INSERT, op
240c0 32 3d 55 50 44 41 54 45 20 20 20 20 20 20 2d 3e  2=UPDATE      ->
240d0 20 20 20 20 20 20 49 4e 53 45 52 54 2e 0a 20 20        INSERT..  
240e0 20 20 2a 2a 20 20 20 6f 70 31 3d 49 4e 53 45 52    **   op1=INSER
240f0 54 2c 20 6f 70 32 3d 44 45 4c 45 54 45 20 20 20  T, op2=DELETE   
24100 20 20 20 2d 3e 20 20 20 20 20 20 28 6e 6f 6e 65     ->      (none
24110 29 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20  ).    **.    ** 
24120 20 20 6f 70 31 3d 55 50 44 41 54 45 2c 20 6f 70    op1=UPDATE, op
24130 32 3d 49 4e 53 45 52 54 20 20 20 20 20 20 2d 3e  2=INSERT      ->
24140 20 20 20 20 20 20 55 6e 73 75 70 70 6f 72 74 65        Unsupporte
24150 64 2e 20 44 69 73 63 61 72 64 20 6f 70 32 2e 0a  d. Discard op2..
24160 20 20 20 20 2a 2a 20 20 20 6f 70 31 3d 55 50 44      **   op1=UPD
24170 41 54 45 2c 20 6f 70 32 3d 55 50 44 41 54 45 20  ATE, op2=UPDATE 
24180 20 20 20 20 20 2d 3e 20 20 20 20 20 20 55 50 44       ->      UPD
24190 41 54 45 2e 0a 20 20 20 20 2a 2a 20 20 20 6f 70  ATE..    **   op
241a0 31 3d 55 50 44 41 54 45 2c 20 6f 70 32 3d 44 45  1=UPDATE, op2=DE
241b0 4c 45 54 45 20 20 20 20 20 20 2d 3e 20 20 20 20  LETE      ->    
241c0 20 20 44 45 4c 45 54 45 2e 0a 20 20 20 20 2a 2a    DELETE..    **
241d0 0a 20 20 20 20 2a 2a 20 20 20 6f 70 31 3d 44 45  .    **   op1=DE
241e0 4c 45 54 45 2c 20 6f 70 32 3d 49 4e 53 45 52 54  LETE, op2=INSERT
241f0 20 20 20 20 20 20 2d 3e 20 20 20 20 20 20 55 50        ->      UP
24200 44 41 54 45 2e 0a 20 20 20 20 2a 2a 20 20 20 6f  DATE..    **   o
24210 70 31 3d 44 45 4c 45 54 45 2c 20 6f 70 32 3d 55  p1=DELETE, op2=U
24220 50 44 41 54 45 20 20 20 20 20 20 2d 3e 20 20 20  PDATE      ->   
24230 20 20 20 55 6e 73 75 70 70 6f 72 74 65 64 2e 20     Unsupported. 
24240 44 69 73 63 61 72 64 20 6f 70 32 2e 0a 20 20 20  Discard op2..   
24250 20 2a 2a 20 20 20 6f 70 31 3d 44 45 4c 45 54 45   **   op1=DELETE
24260 2c 20 6f 70 32 3d 44 45 4c 45 54 45 20 20 20 20  , op2=DELETE    
24270 20 20 2d 3e 20 20 20 20 20 20 55 6e 73 75 70 70    ->      Unsupp
24280 6f 72 74 65 64 2e 20 44 69 73 63 61 72 64 20 6f  orted. Discard o
24290 70 32 2e 0a 20 20 20 20 2a 2f 20 20 20 0a 20 20  p2..    */   .  
242a0 20 20 69 66 28 20 28 6f 70 31 3d 3d 53 51 4c 49    if( (op1==SQLI
242b0 54 45 5f 49 4e 53 45 52 54 20 26 26 20 6f 70 32  TE_INSERT && op2
242c0 3d 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 29  ==SQLITE_INSERT)
242d0 0a 20 20 20 20 20 7c 7c 20 28 6f 70 31 3d 3d 53  .     || (op1==S
242e0 51 4c 49 54 45 5f 55 50 44 41 54 45 20 26 26 20  QLITE_UPDATE && 
242f0 6f 70 32 3d 3d 53 51 4c 49 54 45 5f 49 4e 53 45  op2==SQLITE_INSE
24300 52 54 29 0a 20 20 20 20 20 7c 7c 20 28 6f 70 31  RT).     || (op1
24310 3d 3d 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 20  ==SQLITE_DELETE 
24320 26 26 20 6f 70 32 3d 3d 53 51 4c 49 54 45 5f 55  && op2==SQLITE_U
24330 50 44 41 54 45 29 0a 20 20 20 20 20 7c 7c 20 28  PDATE).     || (
24340 6f 70 31 3d 3d 53 51 4c 49 54 45 5f 44 45 4c 45  op1==SQLITE_DELE
24350 54 45 20 26 26 20 6f 70 32 3d 3d 53 51 4c 49 54  TE && op2==SQLIT
24360 45 5f 44 45 4c 45 54 45 29 0a 20 20 20 20 29 7b  E_DELETE).    ){
24370 0a 20 20 20 20 20 20 70 4e 65 77 20 3d 20 70 45  .      pNew = pE
24380 78 69 73 74 3b 0a 20 20 20 20 7d 65 6c 73 65 20  xist;.    }else 
24390 69 66 28 20 6f 70 31 3d 3d 53 51 4c 49 54 45 5f  if( op1==SQLITE_
243a0 49 4e 53 45 52 54 20 26 26 20 6f 70 32 3d 3d 53  INSERT && op2==S
243b0 51 4c 49 54 45 5f 44 45 4c 45 54 45 20 29 7b 0a  QLITE_DELETE ){.
243c0 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
243d0 65 65 28 70 45 78 69 73 74 29 3b 0a 20 20 20 20  ee(pExist);.    
243e0 20 20 61 73 73 65 72 74 28 20 70 4e 65 77 3d 3d    assert( pNew==
243f0 30 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  0 );.    }else{.
24400 20 20 20 20 20 20 75 38 20 2a 61 45 78 69 73 74        u8 *aExist
24410 20 3d 20 70 45 78 69 73 74 2d 3e 61 52 65 63 6f   = pExist->aReco
24420 72 64 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 42  rd;.      int nB
24430 79 74 65 3b 0a 20 20 20 20 20 20 75 38 20 2a 61  yte;.      u8 *a
24440 43 73 72 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 41  Csr;..      /* A
24450 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 53 65  llocate a new Se
24460 73 73 69 6f 6e 43 68 61 6e 67 65 20 6f 62 6a 65  ssionChange obje
24470 63 74 2e 20 45 6e 73 75 72 65 20 74 68 61 74 20  ct. Ensure that 
24480 74 68 65 20 61 52 65 63 6f 72 64 5b 5d 0a 20 20  the aRecord[].  
24490 20 20 20 20 2a 2a 20 62 75 66 66 65 72 20 6f 66      ** buffer of
244a0 20 74 68 65 20 6e 65 77 20 6f 62 6a 65 63 74 20   the new object 
244b0 69 73 20 6c 61 72 67 65 20 65 6e 6f 75 67 68 20  is large enough 
244c0 74 6f 20 68 6f 6c 64 20 61 6e 79 20 72 65 63 6f  to hold any reco
244d0 72 64 20 74 68 61 74 0a 20 20 20 20 20 20 2a 2a  rd that.      **
244e0 20 6d 61 79 20 62 65 20 67 65 6e 65 72 61 74 65   may be generate
244f0 64 20 62 79 20 63 6f 6d 62 69 6e 69 6e 67 20 74  d by combining t
24500 68 65 20 69 6e 70 75 74 20 72 65 63 6f 72 64 73  he input records
24510 2e 20 20 2a 2f 0a 20 20 20 20 20 20 6e 42 79 74  .  */.      nByt
24520 65 20 3d 20 73 69 7a 65 6f 66 28 53 65 73 73 69  e = sizeof(Sessi
24530 6f 6e 43 68 61 6e 67 65 29 20 2b 20 70 45 78 69  onChange) + pExi
24540 73 74 2d 3e 6e 52 65 63 6f 72 64 20 2b 20 6e 52  st->nRecord + nR
24550 65 63 3b 0a 20 20 20 20 20 20 70 4e 65 77 20 3d  ec;.      pNew =
24560 20 28 53 65 73 73 69 6f 6e 43 68 61 6e 67 65 20   (SessionChange 
24570 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  *)sqlite3_malloc
24580 28 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20 69  (nByte);.      i
24590 66 28 20 21 70 4e 65 77 20 29 7b 0a 20 20 20 20  f( !pNew ){.    
245a0 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
245b0 28 70 45 78 69 73 74 29 3b 0a 20 20 20 20 20 20  (pExist);.      
245c0 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
245d0 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 7d 0a 20  NOMEM;.      }. 
245e0 20 20 20 20 20 6d 65 6d 73 65 74 28 70 4e 65 77       memset(pNew
245f0 2c 20 30 2c 20 73 69 7a 65 6f 66 28 53 65 73 73  , 0, sizeof(Sess
24600 69 6f 6e 43 68 61 6e 67 65 29 29 3b 0a 20 20 20  ionChange));.   
24610 20 20 20 70 4e 65 77 2d 3e 62 49 6e 64 69 72 65     pNew->bIndire
24620 63 74 20 3d 20 28 62 49 6e 64 69 72 65 63 74 20  ct = (bIndirect 
24630 26 26 20 70 45 78 69 73 74 2d 3e 62 49 6e 64 69  && pExist->bIndi
24640 72 65 63 74 29 3b 0a 20 20 20 20 20 20 61 43 73  rect);.      aCs
24650 72 20 3d 20 70 4e 65 77 2d 3e 61 52 65 63 6f 72  r = pNew->aRecor
24660 64 20 3d 20 28 75 38 20 2a 29 26 70 4e 65 77 5b  d = (u8 *)&pNew[
24670 31 5d 3b 0a 0a 20 20 20 20 20 20 69 66 28 20 6f  1];..      if( o
24680 70 31 3d 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52  p1==SQLITE_INSER
24690 54 20 29 7b 20 20 20 20 20 20 20 20 20 20 20 20  T ){            
246a0 20 2f 2a 20 49 4e 53 45 52 54 20 2b 20 55 50 44   /* INSERT + UPD
246b0 41 54 45 20 2a 2f 0a 20 20 20 20 20 20 20 20 75  ATE */.        u
246c0 38 20 2a 61 31 20 3d 20 61 52 65 63 3b 0a 20 20  8 *a1 = aRec;.  
246d0 20 20 20 20 20 20 61 73 73 65 72 74 28 20 6f 70        assert( op
246e0 32 3d 3d 53 51 4c 49 54 45 5f 55 50 44 41 54 45  2==SQLITE_UPDATE
246f0 20 29 3b 0a 20 20 20 20 20 20 20 20 70 4e 65 77   );.        pNew
24700 2d 3e 6f 70 20 3d 20 53 51 4c 49 54 45 5f 49 4e  ->op = SQLITE_IN
24710 53 45 52 54 3b 0a 20 20 20 20 20 20 20 20 69 66  SERT;.        if
24720 28 20 62 50 61 74 63 68 73 65 74 3d 3d 30 20 29  ( bPatchset==0 )
24730 20 73 65 73 73 69 6f 6e 53 6b 69 70 52 65 63 6f   sessionSkipReco
24740 72 64 28 26 61 31 2c 20 70 54 61 62 2d 3e 6e 43  rd(&a1, pTab->nC
24750 6f 6c 29 3b 0a 20 20 20 20 20 20 20 20 73 65 73  ol);.        ses
24760 73 69 6f 6e 4d 65 72 67 65 52 65 63 6f 72 64 28  sionMergeRecord(
24770 26 61 43 73 72 2c 20 70 54 61 62 2d 3e 6e 43 6f  &aCsr, pTab->nCo
24780 6c 2c 20 61 45 78 69 73 74 2c 20 61 31 29 3b 0a  l, aExist, a1);.
24790 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
247a0 6f 70 31 3d 3d 53 51 4c 49 54 45 5f 44 45 4c 45  op1==SQLITE_DELE
247b0 54 45 20 29 7b 20 20 20 20 20 20 20 2f 2a 20 44  TE ){       /* D
247c0 45 4c 45 54 45 20 2b 20 49 4e 53 45 52 54 20 2a  ELETE + INSERT *
247d0 2f 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  /.        assert
247e0 28 20 6f 70 32 3d 3d 53 51 4c 49 54 45 5f 49 4e  ( op2==SQLITE_IN
247f0 53 45 52 54 20 29 3b 0a 20 20 20 20 20 20 20 20  SERT );.        
24800 70 4e 65 77 2d 3e 6f 70 20 3d 20 53 51 4c 49 54  pNew->op = SQLIT
24810 45 5f 55 50 44 41 54 45 3b 0a 20 20 20 20 20 20  E_UPDATE;.      
24820 20 20 69 66 28 20 62 50 61 74 63 68 73 65 74 20    if( bPatchset 
24830 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d  ){.          mem
24840 63 70 79 28 61 43 73 72 2c 20 61 52 65 63 2c 20  cpy(aCsr, aRec, 
24850 6e 52 65 63 29 3b 0a 20 20 20 20 20 20 20 20 20  nRec);.         
24860 20 61 43 73 72 20 2b 3d 20 6e 52 65 63 3b 0a 20   aCsr += nRec;. 
24870 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20         }else{.  
24880 20 20 20 20 20 20 20 20 69 66 28 20 30 3d 3d 73          if( 0==s
24890 65 73 73 69 6f 6e 4d 65 72 67 65 55 70 64 61 74  essionMergeUpdat
248a0 65 28 26 61 43 73 72 2c 20 70 54 61 62 2c 20 62  e(&aCsr, pTab, b
248b0 50 61 74 63 68 73 65 74 2c 20 61 45 78 69 73 74  Patchset, aExist
248c0 2c 20 30 2c 61 52 65 63 2c 30 29 20 29 7b 0a 20  , 0,aRec,0) ){. 
248d0 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74             sqlit
248e0 65 33 5f 66 72 65 65 28 70 4e 65 77 29 3b 0a 20  e3_free(pNew);. 
248f0 20 20 20 20 20 20 20 20 20 20 20 70 4e 65 77 20             pNew 
24900 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  = 0;.          }
24910 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
24920 20 7d 65 6c 73 65 20 69 66 28 20 6f 70 32 3d 3d   }else if( op2==
24930 53 51 4c 49 54 45 5f 55 50 44 41 54 45 20 29 7b  SQLITE_UPDATE ){
24940 20 20 20 20 20 20 20 2f 2a 20 55 50 44 41 54 45         /* UPDATE
24950 20 2b 20 55 50 44 41 54 45 20 2a 2f 0a 20 20 20   + UPDATE */.   
24960 20 20 20 20 20 75 38 20 2a 61 31 20 3d 20 61 45       u8 *a1 = aE
24970 78 69 73 74 3b 0a 20 20 20 20 20 20 20 20 75 38  xist;.        u8
24980 20 2a 61 32 20 3d 20 61 52 65 63 3b 0a 20 20 20   *a2 = aRec;.   
24990 20 20 20 20 20 61 73 73 65 72 74 28 20 6f 70 31       assert( op1
249a0 3d 3d 53 51 4c 49 54 45 5f 55 50 44 41 54 45 20  ==SQLITE_UPDATE 
249b0 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 62  );.        if( b
249c0 50 61 74 63 68 73 65 74 3d 3d 30 20 29 7b 0a 20  Patchset==0 ){. 
249d0 20 20 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e           session
249e0 53 6b 69 70 52 65 63 6f 72 64 28 26 61 31 2c 20  SkipRecord(&a1, 
249f0 70 54 61 62 2d 3e 6e 43 6f 6c 29 3b 0a 20 20 20  pTab->nCol);.   
24a00 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e 53 6b         sessionSk
24a10 69 70 52 65 63 6f 72 64 28 26 61 32 2c 20 70 54  ipRecord(&a2, pT
24a20 61 62 2d 3e 6e 43 6f 6c 29 3b 0a 20 20 20 20 20  ab->nCol);.     
24a30 20 20 20 7d 0a 20 20 20 20 20 20 20 20 70 4e 65     }.        pNe
24a40 77 2d 3e 6f 70 20 3d 20 53 51 4c 49 54 45 5f 55  w->op = SQLITE_U
24a50 50 44 41 54 45 3b 0a 20 20 20 20 20 20 20 20 69  PDATE;.        i
24a60 66 28 20 30 3d 3d 73 65 73 73 69 6f 6e 4d 65 72  f( 0==sessionMer
24a70 67 65 55 70 64 61 74 65 28 26 61 43 73 72 2c 20  geUpdate(&aCsr, 
24a80 70 54 61 62 2c 20 62 50 61 74 63 68 73 65 74 2c  pTab, bPatchset,
24a90 20 61 52 65 63 2c 20 61 45 78 69 73 74 2c 61 31   aRec, aExist,a1
24aa0 2c 61 32 29 20 29 7b 0a 20 20 20 20 20 20 20 20  ,a2) ){.        
24ab0 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
24ac0 4e 65 77 29 3b 0a 20 20 20 20 20 20 20 20 20 20  New);.          
24ad0 70 4e 65 77 20 3d 20 30 3b 0a 20 20 20 20 20 20  pNew = 0;.      
24ae0 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b    }.      }else{
24af0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24b00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24b10 2f 2a 20 55 50 44 41 54 45 20 2b 20 44 45 4c 45  /* UPDATE + DELE
24b20 54 45 20 2a 2f 0a 20 20 20 20 20 20 20 20 61 73  TE */.        as
24b30 73 65 72 74 28 20 6f 70 31 3d 3d 53 51 4c 49 54  sert( op1==SQLIT
24b40 45 5f 55 50 44 41 54 45 20 26 26 20 6f 70 32 3d  E_UPDATE && op2=
24b50 3d 53 51 4c 49 54 45 5f 44 45 4c 45 54 45 20 29  =SQLITE_DELETE )
24b60 3b 0a 20 20 20 20 20 20 20 20 70 4e 65 77 2d 3e  ;.        pNew->
24b70 6f 70 20 3d 20 53 51 4c 49 54 45 5f 44 45 4c 45  op = SQLITE_DELE
24b80 54 45 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  TE;.        if( 
24b90 62 50 61 74 63 68 73 65 74 20 29 7b 0a 20 20 20  bPatchset ){.   
24ba0 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 61 43         memcpy(aC
24bb0 73 72 2c 20 61 52 65 63 2c 20 6e 52 65 63 29 3b  sr, aRec, nRec);
24bc0 0a 20 20 20 20 20 20 20 20 20 20 61 43 73 72 20  .          aCsr 
24bd0 2b 3d 20 6e 52 65 63 3b 0a 20 20 20 20 20 20 20  += nRec;.       
24be0 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
24bf0 20 20 73 65 73 73 69 6f 6e 4d 65 72 67 65 52 65    sessionMergeRe
24c00 63 6f 72 64 28 26 61 43 73 72 2c 20 70 54 61 62  cord(&aCsr, pTab
24c10 2d 3e 6e 43 6f 6c 2c 20 61 52 65 63 2c 20 61 45  ->nCol, aRec, aE
24c20 78 69 73 74 29 3b 0a 20 20 20 20 20 20 20 20 7d  xist);.        }
24c30 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
24c40 69 66 28 20 70 4e 65 77 20 29 7b 0a 20 20 20 20  if( pNew ){.    
24c50 20 20 20 20 70 4e 65 77 2d 3e 6e 52 65 63 6f 72      pNew->nRecor
24c60 64 20 3d 20 28 69 6e 74 29 28 61 43 73 72 20 2d  d = (int)(aCsr -
24c70 20 70 4e 65 77 2d 3e 61 52 65 63 6f 72 64 29 3b   pNew->aRecord);
24c80 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73  .      }.      s
24c90 71 6c 69 74 65 33 5f 66 72 65 65 28 70 45 78 69  qlite3_free(pExi
24ca0 73 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  st);.    }.  }..
24cb0 20 20 2a 70 70 4e 65 77 20 3d 20 70 4e 65 77 3b    *ppNew = pNew;
24cc0 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
24cd0 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64  _OK;.}../*.** Ad
24ce0 64 20 61 6c 6c 20 63 68 61 6e 67 65 73 20 69 6e  d all changes in
24cf0 20 74 68 65 20 63 68 61 6e 67 65 73 65 74 20 74   the changeset t
24d00 72 61 76 65 72 73 65 64 20 62 79 20 74 68 65 20  raversed by the 
24d10 69 74 65 72 61 74 6f 72 20 70 61 73 73 65 64 20  iterator passed 
24d20 61 73 0a 2a 2a 20 74 68 65 20 66 69 72 73 74 20  as.** the first 
24d30 61 72 67 75 6d 65 6e 74 20 74 6f 20 74 68 65 20  argument to the 
24d40 63 68 61 6e 67 65 67 72 6f 75 70 20 68 61 73 68  changegroup hash
24d50 20 74 61 62 6c 65 73 2e 0a 2a 2f 0a 73 74 61 74   tables..*/.stat
24d60 69 63 20 69 6e 74 20 73 65 73 73 69 6f 6e 43 68  ic int sessionCh
24d70 61 6e 67 65 73 65 74 54 6f 48 61 73 68 28 0a 20  angesetToHash(. 
24d80 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73   sqlite3_changes
24d90 65 74 5f 69 74 65 72 20 2a 70 49 74 65 72 2c 20  et_iter *pIter, 
24da0 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 74 6f    /* Iterator to
24db0 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20   read from */.  
24dc0 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 67 72  sqlite3_changegr
24dd0 6f 75 70 20 2a 70 47 72 70 20 20 20 20 20 20 20  oup *pGrp       
24de0 20 2f 2a 20 43 68 61 6e 67 65 67 72 6f 75 70 20   /* Changegroup 
24df0 6f 62 6a 65 63 74 20 74 6f 20 61 64 64 20 63 68  object to add ch
24e00 61 6e 67 65 73 65 74 20 74 6f 20 2a 2f 0a 29 7b  angeset to */.){
24e10 0a 20 20 75 38 20 2a 61 52 65 63 3b 0a 20 20 69  .  u8 *aRec;.  i
24e20 6e 74 20 6e 52 65 63 3b 0a 20 20 69 6e 74 20 72  nt nRec;.  int r
24e30 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
24e40 20 53 65 73 73 69 6f 6e 54 61 62 6c 65 20 2a 70   SessionTable *p
24e50 54 61 62 20 3d 20 30 3b 0a 0a 0a 20 20 77 68 69  Tab = 0;...  whi
24e60 6c 65 28 20 53 51 4c 49 54 45 5f 52 4f 57 3d 3d  le( SQLITE_ROW==
24e70 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65 74  sessionChangeset
24e80 4e 65 78 74 28 70 49 74 65 72 2c 20 26 61 52 65  Next(pIter, &aRe
24e90 63 2c 20 26 6e 52 65 63 29 20 29 7b 0a 20 20 20  c, &nRec) ){.   
24ea0 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 65   const char *zNe
24eb0 77 3b 0a 20 20 20 20 69 6e 74 20 6e 43 6f 6c 3b  w;.    int nCol;
24ec0 0a 20 20 20 20 69 6e 74 20 6f 70 3b 0a 20 20 20  .    int op;.   
24ed0 20 69 6e 74 20 69 48 61 73 68 3b 0a 20 20 20 20   int iHash;.    
24ee0 69 6e 74 20 62 49 6e 64 69 72 65 63 74 3b 0a 20  int bIndirect;. 
24ef0 20 20 20 53 65 73 73 69 6f 6e 43 68 61 6e 67 65     SessionChange
24f00 20 2a 70 43 68 61 6e 67 65 3b 0a 20 20 20 20 53   *pChange;.    S
24f10 65 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 70 45  essionChange *pE
24f20 78 69 73 74 20 3d 20 30 3b 0a 20 20 20 20 53 65  xist = 0;.    Se
24f30 73 73 69 6f 6e 43 68 61 6e 67 65 20 2a 2a 70 70  ssionChange **pp
24f40 3b 0a 0a 20 20 20 20 69 66 28 20 70 47 72 70 2d  ;..    if( pGrp-
24f50 3e 70 4c 69 73 74 3d 3d 30 20 29 7b 0a 20 20 20  >pList==0 ){.   
24f60 20 20 20 70 47 72 70 2d 3e 62 50 61 74 63 68 20     pGrp->bPatch 
24f70 3d 20 70 49 74 65 72 2d 3e 62 50 61 74 63 68 73  = pIter->bPatchs
24f80 65 74 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66  et;.    }else if
24f90 28 20 70 49 74 65 72 2d 3e 62 50 61 74 63 68 73  ( pIter->bPatchs
24fa0 65 74 21 3d 70 47 72 70 2d 3e 62 50 61 74 63 68  et!=pGrp->bPatch
24fb0 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53   ){.      rc = S
24fc0 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20  QLITE_ERROR;.   
24fd0 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
24fe0 0a 20 20 20 20 73 71 6c 69 74 65 33 63 68 61 6e  .    sqlite3chan
24ff0 67 65 73 65 74 5f 6f 70 28 70 49 74 65 72 2c 20  geset_op(pIter, 
25000 26 7a 4e 65 77 2c 20 26 6e 43 6f 6c 2c 20 26 6f  &zNew, &nCol, &o
25010 70 2c 20 26 62 49 6e 64 69 72 65 63 74 29 3b 0a  p, &bIndirect);.
25020 20 20 20 20 69 66 28 20 21 70 54 61 62 20 7c 7c      if( !pTab ||
25030 20 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d 70   sqlite3_stricmp
25040 28 7a 4e 65 77 2c 20 70 54 61 62 2d 3e 7a 4e 61  (zNew, pTab->zNa
25050 6d 65 29 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  me) ){.      /* 
25060 53 65 61 72 63 68 20 74 68 65 20 6c 69 73 74 20  Search the list 
25070 66 6f 72 20 61 20 6d 61 74 63 68 69 6e 67 20 74  for a matching t
25080 61 62 6c 65 20 2a 2f 0a 20 20 20 20 20 20 69 6e  able */.      in
25090 74 20 6e 4e 65 77 20 3d 20 28 69 6e 74 29 73 74  t nNew = (int)st
250a0 72 6c 65 6e 28 7a 4e 65 77 29 3b 0a 20 20 20 20  rlen(zNew);.    
250b0 20 20 75 38 20 2a 61 62 50 4b 3b 0a 0a 20 20 20    u8 *abPK;..   
250c0 20 20 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65     sqlite3change
250d0 73 65 74 5f 70 6b 28 70 49 74 65 72 2c 20 26 61  set_pk(pIter, &a
250e0 62 50 4b 2c 20 30 29 3b 0a 20 20 20 20 20 20 66  bPK, 0);.      f
250f0 6f 72 28 70 54 61 62 20 3d 20 70 47 72 70 2d 3e  or(pTab = pGrp->
25100 70 4c 69 73 74 3b 20 70 54 61 62 3b 20 70 54 61  pList; pTab; pTa
25110 62 3d 70 54 61 62 2d 3e 70 4e 65 78 74 29 7b 0a  b=pTab->pNext){.
25120 20 20 20 20 20 20 20 20 69 66 28 20 30 3d 3d 73          if( 0==s
25130 71 6c 69 74 65 33 5f 73 74 72 6e 69 63 6d 70 28  qlite3_strnicmp(
25140 70 54 61 62 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e 65  pTab->zName, zNe
25150 77 2c 20 6e 4e 65 77 2b 31 29 20 29 20 62 72 65  w, nNew+1) ) bre
25160 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
25170 20 20 69 66 28 20 21 70 54 61 62 20 29 7b 0a 20    if( !pTab ){. 
25180 20 20 20 20 20 20 20 53 65 73 73 69 6f 6e 54 61         SessionTa
25190 62 6c 65 20 2a 2a 70 70 54 61 62 3b 0a 0a 20 20  ble **ppTab;..  
251a0 20 20 20 20 20 20 70 54 61 62 20 3d 20 73 71 6c        pTab = sql
251b0 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65  ite3_malloc(size
251c0 6f 66 28 53 65 73 73 69 6f 6e 54 61 62 6c 65 29  of(SessionTable)
251d0 20 2b 20 6e 43 6f 6c 20 2b 20 6e 4e 65 77 2b 31   + nCol + nNew+1
251e0 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 21  );.        if( !
251f0 70 54 61 62 20 29 7b 0a 20 20 20 20 20 20 20 20  pTab ){.        
25200 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
25210 4d 45 4d 3b 0a 20 20 20 20 20 20 20 20 20 20 62  MEM;.          b
25220 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a  reak;.        }.
25230 20 20 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70          memset(p
25240 54 61 62 2c 20 30 2c 20 73 69 7a 65 6f 66 28 53  Tab, 0, sizeof(S
25250 65 73 73 69 6f 6e 54 61 62 6c 65 29 29 3b 0a 20  essionTable));. 
25260 20 20 20 20 20 20 20 70 54 61 62 2d 3e 6e 43 6f         pTab->nCo
25270 6c 20 3d 20 6e 43 6f 6c 3b 0a 20 20 20 20 20 20  l = nCol;.      
25280 20 20 70 54 61 62 2d 3e 61 62 50 4b 20 3d 20 28    pTab->abPK = (
25290 75 38 2a 29 26 70 54 61 62 5b 31 5d 3b 0a 20 20  u8*)&pTab[1];.  
252a0 20 20 20 20 20 20 6d 65 6d 63 70 79 28 70 54 61        memcpy(pTa
252b0 62 2d 3e 61 62 50 4b 2c 20 61 62 50 4b 2c 20 6e  b->abPK, abPK, n
252c0 43 6f 6c 29 3b 0a 20 20 20 20 20 20 20 20 70 54  Col);.        pT
252d0 61 62 2d 3e 7a 4e 61 6d 65 20 3d 20 28 63 68 61  ab->zName = (cha
252e0 72 2a 29 26 70 54 61 62 2d 3e 61 62 50 4b 5b 6e  r*)&pTab->abPK[n
252f0 43 6f 6c 5d 3b 0a 20 20 20 20 20 20 20 20 6d 65  Col];.        me
25300 6d 63 70 79 28 70 54 61 62 2d 3e 7a 4e 61 6d 65  mcpy(pTab->zName
25310 2c 20 7a 4e 65 77 2c 20 6e 4e 65 77 2b 31 29 3b  , zNew, nNew+1);
25320 0a 0a 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65  ..        /* The
25330 20 6e 65 77 20 6f 62 6a 65 63 74 20 6d 75 73 74   new object must
25340 20 62 65 20 6c 69 6e 6b 65 64 20 6f 6e 20 74 6f   be linked on to
25350 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20   the end of the 
25360 6c 69 73 74 2c 20 6e 6f 74 0a 20 20 20 20 20 20  list, not.      
25370 20 20 2a 2a 20 73 69 6d 70 6c 79 20 61 64 64 65    ** simply adde
25380 64 20 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f  d to the start o
25390 66 20 69 74 2e 20 54 68 69 73 20 69 73 20 74 6f  f it. This is to
253a0 20 65 6e 73 75 72 65 20 74 68 61 74 20 74 68 65   ensure that the
253b0 0a 20 20 20 20 20 20 20 20 2a 2a 20 74 61 62 6c  .        ** tabl
253c0 65 73 20 77 69 74 68 69 6e 20 74 68 65 20 6f 75  es within the ou
253d0 74 70 75 74 20 6f 66 20 73 71 6c 69 74 65 33 63  tput of sqlite3c
253e0 68 61 6e 67 65 67 72 6f 75 70 5f 6f 75 74 70 75  hangegroup_outpu
253f0 74 28 29 20 61 72 65 20 69 6e 20 0a 20 20 20 20  t() are in .    
25400 20 20 20 20 2a 2a 20 74 68 65 20 72 69 67 68 74      ** the right
25410 20 6f 72 64 65 72 2e 20 20 2a 2f 0a 20 20 20 20   order.  */.    
25420 20 20 20 20 66 6f 72 28 70 70 54 61 62 3d 26 70      for(ppTab=&p
25430 47 72 70 2d 3e 70 4c 69 73 74 3b 20 2a 70 70 54  Grp->pList; *ppT
25440 61 62 3b 20 70 70 54 61 62 3d 26 28 2a 70 70 54  ab; ppTab=&(*ppT
25450 61 62 29 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 20  ab)->pNext);.   
25460 20 20 20 20 20 2a 70 70 54 61 62 20 3d 20 70 54       *ppTab = pT
25470 61 62 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20  ab;.      }else 
25480 69 66 28 20 70 54 61 62 2d 3e 6e 43 6f 6c 21 3d  if( pTab->nCol!=
25490 6e 43 6f 6c 20 7c 7c 20 6d 65 6d 63 6d 70 28 70  nCol || memcmp(p
254a0 54 61 62 2d 3e 61 62 50 4b 2c 20 61 62 50 4b 2c  Tab->abPK, abPK,
254b0 20 6e 43 6f 6c 29 20 29 7b 0a 20 20 20 20 20 20   nCol) ){.      
254c0 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 53 43    rc = SQLITE_SC
254d0 48 45 4d 41 3b 0a 20 20 20 20 20 20 20 20 62 72  HEMA;.        br
254e0 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  eak;.      }.   
254f0 20 7d 0a 0a 20 20 20 20 69 66 28 20 73 65 73 73   }..    if( sess
25500 69 6f 6e 47 72 6f 77 48 61 73 68 28 70 49 74 65  ionGrowHash(pIte
25510 72 2d 3e 62 50 61 74 63 68 73 65 74 2c 20 70 54  r->bPatchset, pT
25520 61 62 29 20 29 7b 0a 20 20 20 20 20 20 72 63 20  ab) ){.      rc 
25530 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
25540 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
25550 20 7d 0a 20 20 20 20 69 48 61 73 68 20 3d 20 73   }.    iHash = s
25560 65 73 73 69 6f 6e 43 68 61 6e 67 65 48 61 73 68  essionChangeHash
25570 28 0a 20 20 20 20 20 20 20 20 70 54 61 62 2c 20  (.        pTab, 
25580 28 70 49 74 65 72 2d 3e 62 50 61 74 63 68 73 65  (pIter->bPatchse
25590 74 20 26 26 20 6f 70 3d 3d 53 51 4c 49 54 45 5f  t && op==SQLITE_
255a0 44 45 4c 45 54 45 29 2c 20 61 52 65 63 2c 20 70  DELETE), aRec, p
255b0 54 61 62 2d 3e 6e 43 68 61 6e 67 65 0a 20 20 20  Tab->nChange.   
255c0 20 29 3b 0a 0a 20 20 20 20 2f 2a 20 53 65 61 72   );..    /* Sear
255d0 63 68 20 66 6f 72 20 65 78 69 73 74 69 6e 67 20  ch for existing 
255e0 65 6e 74 72 79 2e 20 49 66 20 66 6f 75 6e 64 2c  entry. If found,
255f0 20 72 65 6d 6f 76 65 20 69 74 20 66 72 6f 6d 20   remove it from 
25600 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 2e 20  the hash table. 
25610 0a 20 20 20 20 2a 2a 20 43 6f 64 65 20 62 65 6c  .    ** Code bel
25620 6f 77 20 6d 61 79 20 6c 69 6e 6b 20 69 74 20 62  ow may link it b
25630 61 63 6b 20 69 6e 2e 0a 20 20 20 20 2a 2f 0a 20  ack in..    */. 
25640 20 20 20 66 6f 72 28 70 70 3d 26 70 54 61 62 2d     for(pp=&pTab-
25650 3e 61 70 43 68 61 6e 67 65 5b 69 48 61 73 68 5d  >apChange[iHash]
25660 3b 20 2a 70 70 3b 20 70 70 3d 26 28 2a 70 70 29  ; *pp; pp=&(*pp)
25670 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20  ->pNext){.      
25680 69 6e 74 20 62 50 6b 4f 6e 6c 79 31 20 3d 20 30  int bPkOnly1 = 0
25690 3b 0a 20 20 20 20 20 20 69 6e 74 20 62 50 6b 4f  ;.      int bPkO
256a0 6e 6c 79 32 20 3d 20 30 3b 0a 20 20 20 20 20 20  nly2 = 0;.      
256b0 69 66 28 20 70 49 74 65 72 2d 3e 62 50 61 74 63  if( pIter->bPatc
256c0 68 73 65 74 20 29 7b 0a 20 20 20 20 20 20 20 20  hset ){.        
256d0 62 50 6b 4f 6e 6c 79 31 20 3d 20 28 2a 70 70 29  bPkOnly1 = (*pp)
256e0 2d 3e 6f 70 3d 3d 53 51 4c 49 54 45 5f 44 45 4c  ->op==SQLITE_DEL
256f0 45 54 45 3b 0a 20 20 20 20 20 20 20 20 62 50 6b  ETE;.        bPk
25700 4f 6e 6c 79 32 20 3d 20 6f 70 3d 3d 53 51 4c 49  Only2 = op==SQLI
25710 54 45 5f 44 45 4c 45 54 45 3b 0a 20 20 20 20 20  TE_DELETE;.     
25720 20 7d 0a 20 20 20 20 20 20 69 66 28 20 73 65 73   }.      if( ses
25730 73 69 6f 6e 43 68 61 6e 67 65 45 71 75 61 6c 28  sionChangeEqual(
25740 70 54 61 62 2c 20 62 50 6b 4f 6e 6c 79 31 2c 20  pTab, bPkOnly1, 
25750 28 2a 70 70 29 2d 3e 61 52 65 63 6f 72 64 2c 20  (*pp)->aRecord, 
25760 62 50 6b 4f 6e 6c 79 32 2c 20 61 52 65 63 29 20  bPkOnly2, aRec) 
25770 29 7b 0a 20 20 20 20 20 20 20 20 70 45 78 69 73  ){.        pExis
25780 74 20 3d 20 2a 70 70 3b 0a 20 20 20 20 20 20 20  t = *pp;.       
25790 20 2a 70 70 20 3d 20 28 2a 70 70 29 2d 3e 70 4e   *pp = (*pp)->pN
257a0 65 78 74 3b 0a 20 20 20 20 20 20 20 20 70 54 61  ext;.        pTa
257b0 62 2d 3e 6e 45 6e 74 72 79 2d 2d 3b 0a 20 20 20  b->nEntry--;.   
257c0 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
257d0 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 72    }.    }..    r
257e0 63 20 3d 20 73 65 73 73 69 6f 6e 43 68 61 6e 67  c = sessionChang
257f0 65 4d 65 72 67 65 28 70 54 61 62 2c 20 0a 20 20  eMerge(pTab, .  
25800 20 20 20 20 20 20 70 49 74 65 72 2d 3e 62 50 61        pIter->bPa
25810 74 63 68 73 65 74 2c 20 70 45 78 69 73 74 2c 20  tchset, pExist, 
25820 6f 70 2c 20 62 49 6e 64 69 72 65 63 74 2c 20 61  op, bIndirect, a
25830 52 65 63 2c 20 6e 52 65 63 2c 20 26 70 43 68 61  Rec, nRec, &pCha
25840 6e 67 65 0a 20 20 20 20 29 3b 0a 20 20 20 20 69  nge.    );.    i
25850 66 28 20 72 63 20 29 20 62 72 65 61 6b 3b 0a 20  f( rc ) break;. 
25860 20 20 20 69 66 28 20 70 43 68 61 6e 67 65 20 29     if( pChange )
25870 7b 0a 20 20 20 20 20 20 70 43 68 61 6e 67 65 2d  {.      pChange-
25880 3e 70 4e 65 78 74 20 3d 20 70 54 61 62 2d 3e 61  >pNext = pTab->a
25890 70 43 68 61 6e 67 65 5b 69 48 61 73 68 5d 3b 0a  pChange[iHash];.
258a0 20 20 20 20 20 20 70 54 61 62 2d 3e 61 70 43 68        pTab->apCh
258b0 61 6e 67 65 5b 69 48 61 73 68 5d 20 3d 20 70 43  ange[iHash] = pC
258c0 68 61 6e 67 65 3b 0a 20 20 20 20 20 20 70 54 61  hange;.      pTa
258d0 62 2d 3e 6e 45 6e 74 72 79 2b 2b 3b 0a 20 20 20  b->nEntry++;.   
258e0 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63   }.  }..  if( rc
258f0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63  ==SQLITE_OK ) rc
25900 20 3d 20 70 49 74 65 72 2d 3e 72 63 3b 0a 20 20   = pIter->rc;.  
25910 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
25920 0a 2a 2a 20 53 65 72 69 61 6c 69 7a 65 20 61 20  .** Serialize a 
25930 63 68 61 6e 67 65 73 65 74 20 28 6f 72 20 70 61  changeset (or pa
25940 74 63 68 73 65 74 29 20 62 61 73 65 64 20 6f 6e  tchset) based on
25950 20 61 6c 6c 20 63 68 61 6e 67 65 73 65 74 73 20   all changesets 
25960 28 6f 72 20 70 61 74 63 68 73 65 74 73 29 0a 2a  (or patchsets).*
25970 2a 20 61 64 64 65 64 20 74 6f 20 74 68 65 20 63  * added to the c
25980 68 61 6e 67 65 67 72 6f 75 70 20 6f 62 6a 65 63  hangegroup objec
25990 74 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20  t passed as the 
259a0 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 0a  first argument..
259b0 2a 2a 0a 2a 2a 20 49 66 20 78 4f 75 74 70 75 74  **.** If xOutput
259c0 20 69 73 20 6e 6f 74 20 4e 55 4c 4c 2c 20 74 68   is not NULL, th
259d0 65 6e 20 74 68 65 20 63 68 61 6e 67 65 73 65 74  en the changeset
259e0 2f 70 61 74 63 68 73 65 74 20 69 73 20 72 65 74  /patchset is ret
259f0 75 72 6e 65 64 20 74 6f 20 74 68 65 0a 2a 2a 20  urned to the.** 
25a00 75 73 65 72 20 76 69 61 20 6f 6e 65 20 6f 72 20  user via one or 
25a10 6d 6f 72 65 20 63 61 6c 6c 73 20 74 6f 20 78 4f  more calls to xO
25a20 75 74 70 75 74 2c 20 61 73 20 77 69 74 68 20 74  utput, as with t
25a30 68 65 20 6f 74 68 65 72 20 73 74 72 65 61 6d 69  he other streami
25a40 6e 67 0a 2a 2a 20 69 6e 74 65 72 66 61 63 65 73  ng.** interfaces
25a50 2e 20 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 69 66 20  . .**.** Or, if 
25a60 78 4f 75 74 70 75 74 20 69 73 20 4e 55 4c 4c 2c  xOutput is NULL,
25a70 20 74 68 65 6e 20 28 2a 70 70 4f 75 74 29 20 69   then (*ppOut) i
25a80 73 20 70 6f 70 75 6c 61 74 65 64 20 77 69 74 68  s populated with
25a90 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 0a   a pointer to a.
25aa0 2a 2a 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69  ** buffer contai
25ab0 6e 69 6e 67 20 74 68 65 20 6f 75 74 70 75 74 20  ning the output 
25ac0 63 68 61 6e 67 65 73 65 74 20 62 65 66 6f 72 65  changeset before
25ad0 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72   this function r
25ae0 65 74 75 72 6e 73 2e 20 49 6e 0a 2a 2a 20 74 68  eturns. In.** th
25af0 69 73 20 63 61 73 65 20 28 2a 70 6e 4f 75 74 29  is case (*pnOut)
25b00 20 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 73   is set to the s
25b10 69 7a 65 20 6f 66 20 74 68 65 20 6f 75 74 70 75  ize of the outpu
25b20 74 20 62 75 66 66 65 72 20 69 6e 20 62 79 74 65  t buffer in byte
25b30 73 2e 20 49 74 0a 2a 2a 20 69 73 20 74 68 65 20  s. It.** is the 
25b40 72 65 73 70 6f 6e 73 69 62 69 6c 69 74 79 20 6f  responsibility o
25b50 66 20 74 68 65 20 63 61 6c 6c 65 72 20 74 6f 20  f the caller to 
25b60 66 72 65 65 20 74 68 65 20 6f 75 74 70 75 74 20  free the output 
25b70 62 75 66 66 65 72 20 75 73 69 6e 67 0a 2a 2a 20  buffer using.** 
25b80 73 71 6c 69 74 65 33 5f 66 72 65 65 28 29 20 77  sqlite3_free() w
25b90 68 65 6e 20 69 74 20 69 73 20 6e 6f 20 6c 6f 6e  hen it is no lon
25ba0 67 65 72 20 72 65 71 75 69 72 65 64 2e 0a 2a 2a  ger required..**
25bb0 0a 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75  .** If successfu
25bc0 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20  l, SQLITE_OK is 
25bd0 72 65 74 75 72 6e 65 64 2e 20 4f 72 2c 20 69 66  returned. Or, if
25be0 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
25bf0 2c 20 61 6e 20 53 51 4c 69 74 65 0a 2a 2a 20 65  , an SQLite.** e
25c00 72 72 6f 72 20 63 6f 64 65 2e 20 49 66 20 61 6e  rror code. If an
25c10 20 65 72 72 6f 72 20 6f 63 63 75 72 73 20 61 6e   error occurs an
25c20 64 20 78 4f 75 74 70 75 74 20 69 73 20 4e 55 4c  d xOutput is NUL
25c30 4c 2c 20 28 2a 70 70 4f 75 74 29 20 61 6e 64 20  L, (*ppOut) and 
25c40 28 2a 70 6e 4f 75 74 29 0a 2a 2a 20 61 72 65 20  (*pnOut).** are 
25c50 62 6f 74 68 20 73 65 74 20 74 6f 20 30 20 62 65  both set to 0 be
25c60 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a  fore returning..
25c70 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
25c80 73 73 69 6f 6e 43 68 61 6e 67 65 67 72 6f 75 70  ssionChangegroup
25c90 4f 75 74 70 75 74 28 0a 20 20 73 71 6c 69 74 65  Output(.  sqlite
25ca0 33 5f 63 68 61 6e 67 65 67 72 6f 75 70 20 2a 70  3_changegroup *p
25cb0 47 72 70 2c 0a 20 20 69 6e 74 20 28 2a 78 4f 75  Grp,.  int (*xOu
25cc0 74 70 75 74 29 28 76 6f 69 64 20 2a 70 4f 75 74  tput)(void *pOut
25cd0 2c 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 44  , const void *pD
25ce0 61 74 61 2c 20 69 6e 74 20 6e 44 61 74 61 29 2c  ata, int nData),
25cf0 0a 20 20 76 6f 69 64 20 2a 70 4f 75 74 2c 0a 20  .  void *pOut,. 
25d00 20 69 6e 74 20 2a 70 6e 4f 75 74 2c 0a 20 20 76   int *pnOut,.  v
25d10 6f 69 64 20 2a 2a 70 70 4f 75 74 0a 29 7b 0a 20  oid **ppOut.){. 
25d20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
25d30 5f 4f 4b 3b 0a 20 20 53 65 73 73 69 6f 6e 42 75  _OK;.  SessionBu
25d40 66 66 65 72 20 62 75 66 20 3d 20 7b 30 2c 20 30  ffer buf = {0, 0
25d50 2c 20 30 7d 3b 0a 20 20 53 65 73 73 69 6f 6e 54  , 0};.  SessionT
25d60 61 62 6c 65 20 2a 70 54 61 62 3b 0a 20 20 61 73  able *pTab;.  as
25d70 73 65 72 74 28 20 78 4f 75 74 70 75 74 3d 3d 30  sert( xOutput==0
25d80 20 7c 7c 20 28 70 70 4f 75 74 3d 3d 30 20 26 26   || (ppOut==0 &&
25d90 20 70 6e 4f 75 74 3d 3d 30 29 20 29 3b 0a 0a 20   pnOut==0) );.. 
25da0 20 2f 2a 20 43 72 65 61 74 65 20 74 68 65 20 73   /* Create the s
25db0 65 72 69 61 6c 69 7a 65 64 20 6f 75 74 70 75 74  erialized output
25dc0 20 63 68 61 6e 67 65 73 65 74 20 62 61 73 65 64   changeset based
25dd0 20 6f 6e 20 74 68 65 20 63 6f 6e 74 65 6e 74 73   on the contents
25de0 20 6f 66 20 74 68 65 0a 20 20 2a 2a 20 68 61 73   of the.  ** has
25df0 68 20 74 61 62 6c 65 73 20 61 74 74 61 63 68 65  h tables attache
25e00 64 20 74 6f 20 74 68 65 20 53 65 73 73 69 6f 6e  d to the Session
25e10 54 61 62 6c 65 20 6f 62 6a 65 63 74 73 20 69 6e  Table objects in
25e20 20 6c 69 73 74 20 70 2d 3e 70 4c 69 73 74 2e 20   list p->pList. 
25e30 0a 20 20 2a 2f 0a 20 20 66 6f 72 28 70 54 61 62  .  */.  for(pTab
25e40 3d 70 47 72 70 2d 3e 70 4c 69 73 74 3b 20 72 63  =pGrp->pList; rc
25e50 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70  ==SQLITE_OK && p
25e60 54 61 62 3b 20 70 54 61 62 3d 70 54 61 62 2d 3e  Tab; pTab=pTab->
25e70 70 4e 65 78 74 29 7b 0a 20 20 20 20 69 6e 74 20  pNext){.    int 
25e80 69 3b 0a 20 20 20 20 69 66 28 20 70 54 61 62 2d  i;.    if( pTab-
25e90 3e 6e 45 6e 74 72 79 3d 3d 30 20 29 20 63 6f 6e  >nEntry==0 ) con
25ea0 74 69 6e 75 65 3b 0a 0a 20 20 20 20 73 65 73 73  tinue;..    sess
25eb0 69 6f 6e 41 70 70 65 6e 64 54 61 62 6c 65 48 64  ionAppendTableHd
25ec0 72 28 26 62 75 66 2c 20 70 47 72 70 2d 3e 62 50  r(&buf, pGrp->bP
25ed0 61 74 63 68 2c 20 70 54 61 62 2c 20 26 72 63 29  atch, pTab, &rc)
25ee0 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69  ;.    for(i=0; i
25ef0 3c 70 54 61 62 2d 3e 6e 43 68 61 6e 67 65 3b 20  <pTab->nChange; 
25f00 69 2b 2b 29 7b 0a 20 20 20 20 20 20 53 65 73 73  i++){.      Sess
25f10 69 6f 6e 43 68 61 6e 67 65 20 2a 70 3b 0a 20 20  ionChange *p;.  
25f20 20 20 20 20 66 6f 72 28 70 3d 70 54 61 62 2d 3e      for(p=pTab->
25f30 61 70 43 68 61 6e 67 65 5b 69 5d 3b 20 70 3b 20  apChange[i]; p; 
25f40 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20  p=p->pNext){.   
25f50 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70 65       sessionAppe
25f60 6e 64 42 79 74 65 28 26 62 75 66 2c 20 70 2d 3e  ndByte(&buf, p->
25f70 6f 70 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20  op, &rc);.      
25f80 20 20 73 65 73 73 69 6f 6e 41 70 70 65 6e 64 42    sessionAppendB
25f90 79 74 65 28 26 62 75 66 2c 20 70 2d 3e 62 49 6e  yte(&buf, p->bIn
25fa0 64 69 72 65 63 74 2c 20 26 72 63 29 3b 0a 20 20  direct, &rc);.  
25fb0 20 20 20 20 20 20 73 65 73 73 69 6f 6e 41 70 70        sessionApp
25fc0 65 6e 64 42 6c 6f 62 28 26 62 75 66 2c 20 70 2d  endBlob(&buf, p-
25fd0 3e 61 52 65 63 6f 72 64 2c 20 70 2d 3e 6e 52 65  >aRecord, p->nRe
25fe0 63 6f 72 64 2c 20 26 72 63 29 3b 0a 20 20 20 20  cord, &rc);.    
25ff0 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69    }.    }..    i
26000 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
26010 20 26 26 20 78 4f 75 74 70 75 74 20 26 26 20 62   && xOutput && b
26020 75 66 2e 6e 42 75 66 3e 3d 53 45 53 53 49 4f 4e  uf.nBuf>=SESSION
26030 53 5f 53 54 52 4d 5f 43 48 55 4e 4b 5f 53 49 5a  S_STRM_CHUNK_SIZ
26040 45 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  E ){.      rc = 
26050 78 4f 75 74 70 75 74 28 70 4f 75 74 2c 20 62 75  xOutput(pOut, bu
26060 66 2e 61 42 75 66 2c 20 62 75 66 2e 6e 42 75 66  f.aBuf, buf.nBuf
26070 29 3b 0a 20 20 20 20 20 20 62 75 66 2e 6e 42 75  );.      buf.nBu
26080 66 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d  f = 0;.    }.  }
26090 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
260a0 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 66 28  TE_OK ){.    if(
260b0 20 78 4f 75 74 70 75 74 20 29 7b 0a 20 20 20 20   xOutput ){.    
260c0 20 20 69 66 28 20 62 75 66 2e 6e 42 75 66 3e 30    if( buf.nBuf>0
260d0 20 29 20 72 63 20 3d 20 78 4f 75 74 70 75 74 28   ) rc = xOutput(
260e0 70 4f 75 74 2c 20 62 75 66 2e 61 42 75 66 2c 20  pOut, buf.aBuf, 
260f0 62 75 66 2e 6e 42 75 66 29 3b 0a 20 20 20 20 7d  buf.nBuf);.    }
26100 65 6c 73 65 7b 0a 20 20 20 20 20 20 2a 70 70 4f  else{.      *ppO
26110 75 74 20 3d 20 62 75 66 2e 61 42 75 66 3b 0a 20  ut = buf.aBuf;. 
26120 20 20 20 20 20 2a 70 6e 4f 75 74 20 3d 20 62 75       *pnOut = bu
26130 66 2e 6e 42 75 66 3b 0a 20 20 20 20 20 20 62 75  f.nBuf;.      bu
26140 66 2e 61 42 75 66 20 3d 20 30 3b 0a 20 20 20 20  f.aBuf = 0;.    
26150 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  }.  }.  sqlite3_
26160 66 72 65 65 28 62 75 66 2e 61 42 75 66 29 3b 0a  free(buf.aBuf);.
26170 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
26180 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20  ./*.** Allocate 
26190 61 20 6e 65 77 2c 20 65 6d 70 74 79 2c 20 73 71  a new, empty, sq
261a0 6c 69 74 65 33 5f 63 68 61 6e 67 65 67 72 6f 75  lite3_changegrou
261b0 70 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  p..*/.int sqlite
261c0 33 63 68 61 6e 67 65 67 72 6f 75 70 5f 6e 65 77  3changegroup_new
261d0 28 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 67  (sqlite3_changeg
261e0 72 6f 75 70 20 2a 2a 70 70 29 7b 0a 20 20 69 6e  roup **pp){.  in
261f0 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
26200 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
26210 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a   Return code */.
26220 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65    sqlite3_change
26230 67 72 6f 75 70 20 2a 70 3b 20 20 20 20 20 20 20  group *p;       
26240 20 20 2f 2a 20 4e 65 77 20 6f 62 6a 65 63 74 20    /* New object 
26250 2a 2f 0a 20 20 70 20 3d 20 28 73 71 6c 69 74 65  */.  p = (sqlite
26260 33 5f 63 68 61 6e 67 65 67 72 6f 75 70 2a 29 73  3_changegroup*)s
26270 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69  qlite3_malloc(si
26280 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f 63 68 61  zeof(sqlite3_cha
26290 6e 67 65 67 72 6f 75 70 29 29 3b 0a 20 20 69 66  ngegroup));.  if
262a0 28 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63  ( p==0 ){.    rc
262b0 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
262c0 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 6d 65  .  }else{.    me
262d0 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f  mset(p, 0, sizeo
262e0 66 28 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65  f(sqlite3_change
262f0 67 72 6f 75 70 29 29 3b 0a 20 20 7d 0a 20 20 2a  group));.  }.  *
26300 70 70 20 3d 20 70 3b 0a 20 20 72 65 74 75 72 6e  pp = p;.  return
26310 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64   rc;.}../*.** Ad
26320 64 20 74 68 65 20 63 68 61 6e 67 65 73 65 74 20  d the changeset 
26330 63 75 72 72 65 6e 74 6c 79 20 73 74 6f 72 65 64  currently stored
26340 20 69 6e 20 62 75 66 66 65 72 20 70 44 61 74 61   in buffer pData
26350 2c 20 73 69 7a 65 20 6e 44 61 74 61 20 62 79 74  , size nData byt
26360 65 73 2c 0a 2a 2a 20 74 6f 20 63 68 61 6e 67 65  es,.** to change
26370 73 65 74 2d 67 72 6f 75 70 20 70 2e 0a 2a 2f 0a  set-group p..*/.
26380 69 6e 74 20 73 71 6c 69 74 65 33 63 68 61 6e 67  int sqlite3chang
26390 65 67 72 6f 75 70 5f 61 64 64 28 73 71 6c 69 74  egroup_add(sqlit
263a0 65 33 5f 63 68 61 6e 67 65 67 72 6f 75 70 20 2a  e3_changegroup *
263b0 70 47 72 70 2c 20 69 6e 74 20 6e 44 61 74 61 2c  pGrp, int nData,
263c0 20 76 6f 69 64 20 2a 70 44 61 74 61 29 7b 0a 20   void *pData){. 
263d0 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73   sqlite3_changes
263e0 65 74 5f 69 74 65 72 20 2a 70 49 74 65 72 3b 20  et_iter *pIter; 
263f0 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 6f 70 65   /* Iterator ope
26400 6e 65 64 20 6f 6e 20 70 44 61 74 61 2f 6e 44 61  ned on pData/nDa
26410 74 61 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20  ta */.  int rc; 
26420 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26430 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
26440 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 72 63 20  n code */..  rc 
26450 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  = sqlite3changes
26460 65 74 5f 73 74 61 72 74 28 26 70 49 74 65 72 2c  et_start(&pIter,
26470 20 6e 44 61 74 61 2c 20 70 44 61 74 61 29 3b 0a   nData, pData);.
26480 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
26490 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
264a0 73 65 73 73 69 6f 6e 43 68 61 6e 67 65 73 65 74  sessionChangeset
264b0 54 6f 48 61 73 68 28 70 49 74 65 72 2c 20 70 47  ToHash(pIter, pG
264c0 72 70 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74  rp);.  }.  sqlit
264d0 65 33 63 68 61 6e 67 65 73 65 74 5f 66 69 6e 61  e3changeset_fina
264e0 6c 69 7a 65 28 70 49 74 65 72 29 3b 0a 20 20 72  lize(pIter);.  r
264f0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
26500 2a 2a 20 4f 62 74 61 69 6e 20 61 20 62 75 66 66  ** Obtain a buff
26510 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 61 20  er containing a 
26520 63 68 61 6e 67 65 73 65 74 20 72 65 70 72 65 73  changeset repres
26530 65 6e 74 69 6e 67 20 74 68 65 20 63 6f 6e 63 61  enting the conca
26540 74 65 6e 61 74 69 6f 6e 0a 2a 2a 20 6f 66 20 61  tenation.** of a
26550 6c 6c 20 63 68 61 6e 67 65 73 65 74 73 20 61 64  ll changesets ad
26560 64 65 64 20 74 6f 20 74 68 65 20 67 72 6f 75 70  ded to the group
26570 20 73 6f 20 66 61 72 2e 0a 2a 2f 0a 69 6e 74 20   so far..*/.int 
26580 73 71 6c 69 74 65 33 63 68 61 6e 67 65 67 72 6f  sqlite3changegro
26590 75 70 5f 6f 75 74 70 75 74 28 0a 20 20 20 20 73  up_output(.    s
265a0 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 67 72 6f  qlite3_changegro
265b0 75 70 20 2a 70 47 72 70 2c 0a 20 20 20 20 69 6e  up *pGrp,.    in
265c0 74 20 2a 70 6e 44 61 74 61 2c 0a 20 20 20 20 76  t *pnData,.    v
265d0 6f 69 64 20 2a 2a 70 70 44 61 74 61 0a 29 7b 0a  oid **ppData.){.
265e0 20 20 72 65 74 75 72 6e 20 73 65 73 73 69 6f 6e    return session
265f0 43 68 61 6e 67 65 67 72 6f 75 70 4f 75 74 70 75  ChangegroupOutpu
26600 74 28 70 47 72 70 2c 20 30 2c 20 30 2c 20 70 6e  t(pGrp, 0, 0, pn
26610 44 61 74 61 2c 20 70 70 44 61 74 61 29 3b 0a 7d  Data, ppData);.}
26620 0a 0a 2f 2a 0a 2a 2a 20 53 74 72 65 61 6d 69 6e  ../*.** Streamin
26630 67 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 63 68  g versions of ch
26640 61 6e 67 65 67 72 6f 75 70 5f 61 64 64 28 29 2e  angegroup_add().
26650 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 63  .*/.int sqlite3c
26660 68 61 6e 67 65 67 72 6f 75 70 5f 61 64 64 5f 73  hangegroup_add_s
26670 74 72 6d 28 0a 20 20 73 71 6c 69 74 65 33 5f 63  trm(.  sqlite3_c
26680 68 61 6e 67 65 67 72 6f 75 70 20 2a 70 47 72 70  hangegroup *pGrp
26690 2c 0a 20 20 69 6e 74 20 28 2a 78 49 6e 70 75 74  ,.  int (*xInput
266a0 29 28 76 6f 69 64 20 2a 70 49 6e 2c 20 76 6f 69  )(void *pIn, voi
266b0 64 20 2a 70 44 61 74 61 2c 20 69 6e 74 20 2a 70  d *pData, int *p
266c0 6e 44 61 74 61 29 2c 0a 20 20 76 6f 69 64 20 2a  nData),.  void *
266d0 70 49 6e 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33  pIn.){.  sqlite3
266e0 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20  _changeset_iter 
266f0 2a 70 49 74 65 72 3b 20 20 2f 2a 20 49 74 65 72  *pIter;  /* Iter
26700 61 74 6f 72 20 6f 70 65 6e 65 64 20 6f 6e 20 70  ator opened on p
26710 44 61 74 61 2f 6e 44 61 74 61 20 2a 2f 0a 20 20  Data/nData */.  
26720 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
26730 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26740 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
26750 2f 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  /..  rc = sqlite
26760 33 63 68 61 6e 67 65 73 65 74 5f 73 74 61 72 74  3changeset_start
26770 5f 73 74 72 6d 28 26 70 49 74 65 72 2c 20 78 49  _strm(&pIter, xI
26780 6e 70 75 74 2c 20 70 49 6e 29 3b 0a 20 20 69 66  nput, pIn);.  if
26790 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
267a0 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 65 73 73  ){.    rc = sess
267b0 69 6f 6e 43 68 61 6e 67 65 73 65 74 54 6f 48 61  ionChangesetToHa
267c0 73 68 28 70 49 74 65 72 2c 20 70 47 72 70 29 3b  sh(pIter, pGrp);
267d0 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 63 68  .  }.  sqlite3ch
267e0 61 6e 67 65 73 65 74 5f 66 69 6e 61 6c 69 7a 65  angeset_finalize
267f0 28 70 49 74 65 72 29 3b 0a 20 20 72 65 74 75 72  (pIter);.  retur
26800 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  n rc;.}../*.** S
26810 74 72 65 61 6d 69 6e 67 20 76 65 72 73 69 6f 6e  treaming version
26820 73 20 6f 66 20 63 68 61 6e 67 65 67 72 6f 75 70  s of changegroup
26830 5f 6f 75 74 70 75 74 28 29 2e 0a 2a 2f 0a 69 6e  _output()..*/.in
26840 74 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 67  t sqlite3changeg
26850 72 6f 75 70 5f 6f 75 74 70 75 74 5f 73 74 72 6d  roup_output_strm
26860 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 68 61 6e  (.  sqlite3_chan
26870 67 65 67 72 6f 75 70 20 2a 70 47 72 70 2c 0a 20  gegroup *pGrp,. 
26880 20 69 6e 74 20 28 2a 78 4f 75 74 70 75 74 29 28   int (*xOutput)(
26890 76 6f 69 64 20 2a 70 4f 75 74 2c 20 63 6f 6e 73  void *pOut, cons
268a0 74 20 76 6f 69 64 20 2a 70 44 61 74 61 2c 20 69  t void *pData, i
268b0 6e 74 20 6e 44 61 74 61 29 2c 20 0a 20 20 76 6f  nt nData), .  vo
268c0 69 64 20 2a 70 4f 75 74 0a 29 7b 0a 20 20 72 65  id *pOut.){.  re
268d0 74 75 72 6e 20 73 65 73 73 69 6f 6e 43 68 61 6e  turn sessionChan
268e0 67 65 67 72 6f 75 70 4f 75 74 70 75 74 28 70 47  gegroupOutput(pG
268f0 72 70 2c 20 78 4f 75 74 70 75 74 2c 20 70 4f 75  rp, xOutput, pOu
26900 74 2c 20 30 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a  t, 0, 0);.}../*.
26910 2a 2a 20 44 65 6c 65 74 65 20 61 20 63 68 61 6e  ** Delete a chan
26920 67 65 67 72 6f 75 70 20 6f 62 6a 65 63 74 2e 0a  gegroup object..
26930 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 63  */.void sqlite3c
26940 68 61 6e 67 65 67 72 6f 75 70 5f 64 65 6c 65 74  hangegroup_delet
26950 65 28 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65  e(sqlite3_change
26960 67 72 6f 75 70 20 2a 70 47 72 70 29 7b 0a 20 20  group *pGrp){.  
26970 69 66 28 20 70 47 72 70 20 29 7b 0a 20 20 20 20  if( pGrp ){.    
26980 73 65 73 73 69 6f 6e 44 65 6c 65 74 65 54 61 62  sessionDeleteTab
26990 6c 65 28 70 47 72 70 2d 3e 70 4c 69 73 74 29 3b  le(pGrp->pList);
269a0 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
269b0 65 28 70 47 72 70 29 3b 0a 20 20 7d 0a 7d 0a 0a  e(pGrp);.  }.}..
269c0 2f 2a 20 0a 2a 2a 20 43 6f 6d 62 69 6e 65 20 74  /* .** Combine t
269d0 77 6f 20 63 68 61 6e 67 65 73 65 74 73 20 74 6f  wo changesets to
269e0 67 65 74 68 65 72 2e 0a 2a 2f 0a 69 6e 74 20 73  gether..*/.int s
269f0 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
26a00 63 6f 6e 63 61 74 28 0a 20 20 69 6e 74 20 6e 4c  concat(.  int nL
26a10 65 66 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  eft,            
26a20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
26a30 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
26a40 6c 68 73 20 69 6e 70 75 74 20 2a 2f 0a 20 20 76  lhs input */.  v
26a50 6f 69 64 20 2a 70 4c 65 66 74 2c 20 20 20 20 20  oid *pLeft,     
26a60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
26a70 2a 20 4c 68 73 20 69 6e 70 75 74 20 63 68 61 6e  * Lhs input chan
26a80 67 65 73 65 74 20 2a 2f 0a 20 20 69 6e 74 20 6e  geset */.  int n
26a90 52 69 67 68 74 20 20 20 20 20 20 20 20 20 20 20  Right           
26aa0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
26ab0 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e  mber of bytes in
26ac0 20 72 68 73 20 69 6e 70 75 74 20 2a 2f 2c 0a 20   rhs input */,. 
26ad0 20 76 6f 69 64 20 2a 70 52 69 67 68 74 2c 20 20   void *pRight,  
26ae0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26af0 20 2f 2a 20 52 68 73 20 69 6e 70 75 74 20 63 68   /* Rhs input ch
26b00 61 6e 67 65 73 65 74 20 2a 2f 0a 20 20 69 6e 74  angeset */.  int
26b10 20 2a 70 6e 4f 75 74 2c 20 20 20 20 20 20 20 20   *pnOut,        
26b20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
26b30 4f 55 54 3a 20 4e 75 6d 62 65 72 20 6f 66 20 62  OUT: Number of b
26b40 79 74 65 73 20 69 6e 20 6f 75 74 70 75 74 20 63  ytes in output c
26b50 68 61 6e 67 65 73 65 74 20 2a 2f 0a 20 20 76 6f  hangeset */.  vo
26b60 69 64 20 2a 2a 70 70 4f 75 74 20 20 20 20 20 20  id **ppOut      
26b70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
26b80 20 4f 55 54 3a 20 63 68 61 6e 67 65 73 65 74 20   OUT: changeset 
26b90 28 6c 65 66 74 20 3c 63 6f 6e 63 61 74 3e 20 72  (left <concat> r
26ba0 69 67 68 74 29 20 2a 2f 0a 29 7b 0a 20 20 73 71  ight) */.){.  sq
26bb0 6c 69 74 65 33 5f 63 68 61 6e 67 65 67 72 6f 75  lite3_changegrou
26bc0 70 20 2a 70 47 72 70 3b 0a 20 20 69 6e 74 20 72  p *pGrp;.  int r
26bd0 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  c;..  rc = sqlit
26be0 65 33 63 68 61 6e 67 65 67 72 6f 75 70 5f 6e 65  e3changegroup_ne
26bf0 77 28 26 70 47 72 70 29 3b 0a 20 20 69 66 28 20  w(&pGrp);.  if( 
26c00 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
26c10 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
26c20 33 63 68 61 6e 67 65 67 72 6f 75 70 5f 61 64 64  3changegroup_add
26c30 28 70 47 72 70 2c 20 6e 4c 65 66 74 2c 20 70 4c  (pGrp, nLeft, pL
26c40 65 66 74 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20  eft);.  }.  if( 
26c50 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
26c60 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
26c70 33 63 68 61 6e 67 65 67 72 6f 75 70 5f 61 64 64  3changegroup_add
26c80 28 70 47 72 70 2c 20 6e 52 69 67 68 74 2c 20 70  (pGrp, nRight, p
26c90 52 69 67 68 74 29 3b 0a 20 20 7d 0a 20 20 69 66  Right);.  }.  if
26ca0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
26cb0 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  ){.    rc = sqli
26cc0 74 65 33 63 68 61 6e 67 65 67 72 6f 75 70 5f 6f  te3changegroup_o
26cd0 75 74 70 75 74 28 70 47 72 70 2c 20 70 6e 4f 75  utput(pGrp, pnOu
26ce0 74 2c 20 70 70 4f 75 74 29 3b 0a 20 20 7d 0a 20  t, ppOut);.  }. 
26cf0 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 67 72   sqlite3changegr
26d00 6f 75 70 5f 64 65 6c 65 74 65 28 70 47 72 70 29  oup_delete(pGrp)
26d10 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  ;..  return rc;.
26d20 7d 0a 0a 2f 2a 0a 2a 2a 20 53 74 72 65 61 6d 69  }../*.** Streami
26d30 6e 67 20 76 65 72 73 69 6f 6e 20 6f 66 20 73 71  ng version of sq
26d40 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 63  lite3changeset_c
26d50 6f 6e 63 61 74 28 29 2e 0a 2a 2f 0a 69 6e 74 20  oncat()..*/.int 
26d60 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
26d70 5f 63 6f 6e 63 61 74 5f 73 74 72 6d 28 0a 20 20  _concat_strm(.  
26d80 69 6e 74 20 28 2a 78 49 6e 70 75 74 41 29 28 76  int (*xInputA)(v
26d90 6f 69 64 20 2a 70 49 6e 2c 20 76 6f 69 64 20 2a  oid *pIn, void *
26da0 70 44 61 74 61 2c 20 69 6e 74 20 2a 70 6e 44 61  pData, int *pnDa
26db0 74 61 29 2c 0a 20 20 76 6f 69 64 20 2a 70 49 6e  ta),.  void *pIn
26dc0 41 2c 0a 20 20 69 6e 74 20 28 2a 78 49 6e 70 75  A,.  int (*xInpu
26dd0 74 42 29 28 76 6f 69 64 20 2a 70 49 6e 2c 20 76  tB)(void *pIn, v
26de0 6f 69 64 20 2a 70 44 61 74 61 2c 20 69 6e 74 20  oid *pData, int 
26df0 2a 70 6e 44 61 74 61 29 2c 0a 20 20 76 6f 69 64  *pnData),.  void
26e00 20 2a 70 49 6e 42 2c 0a 20 20 69 6e 74 20 28 2a   *pInB,.  int (*
26e10 78 4f 75 74 70 75 74 29 28 76 6f 69 64 20 2a 70  xOutput)(void *p
26e20 4f 75 74 2c 20 63 6f 6e 73 74 20 76 6f 69 64 20  Out, const void 
26e30 2a 70 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74  *pData, int nDat
26e40 61 29 2c 0a 20 20 76 6f 69 64 20 2a 70 4f 75 74  a),.  void *pOut
26e50 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 63 68  .){.  sqlite3_ch
26e60 61 6e 67 65 67 72 6f 75 70 20 2a 70 47 72 70 3b  angegroup *pGrp;
26e70 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 72 63  .  int rc;..  rc
26e80 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65   = sqlite3change
26e90 67 72 6f 75 70 5f 6e 65 77 28 26 70 47 72 70 29  group_new(&pGrp)
26ea0 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
26eb0 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  TE_OK ){.    rc 
26ec0 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 67  = sqlite3changeg
26ed0 72 6f 75 70 5f 61 64 64 5f 73 74 72 6d 28 70 47  roup_add_strm(pG
26ee0 72 70 2c 20 78 49 6e 70 75 74 41 2c 20 70 49 6e  rp, xInputA, pIn
26ef0 41 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72 63  A);.  }.  if( rc
26f00 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
26f10 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 63     rc = sqlite3c
26f20 68 61 6e 67 65 67 72 6f 75 70 5f 61 64 64 5f 73  hangegroup_add_s
26f30 74 72 6d 28 70 47 72 70 2c 20 78 49 6e 70 75 74  trm(pGrp, xInput
26f40 42 2c 20 70 49 6e 42 29 3b 0a 20 20 7d 0a 20 20  B, pInB);.  }.  
26f50 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
26f60 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71  K ){.    rc = sq
26f70 6c 69 74 65 33 63 68 61 6e 67 65 67 72 6f 75 70  lite3changegroup
26f80 5f 6f 75 74 70 75 74 5f 73 74 72 6d 28 70 47 72  _output_strm(pGr
26f90 70 2c 20 78 4f 75 74 70 75 74 2c 20 70 4f 75 74  p, xOutput, pOut
26fa0 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33  );.  }.  sqlite3
26fb0 63 68 61 6e 67 65 67 72 6f 75 70 5f 64 65 6c 65  changegroup_dele
26fc0 74 65 28 70 47 72 70 29 3b 0a 0a 20 20 72 65 74  te(pGrp);..  ret
26fd0 75 72 6e 20 72 63 3b 0a 7d 0a 0a 23 65 6e 64 69  urn rc;.}..#endi
26fe0 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42  f /* SQLITE_ENAB
26ff0 4c 45 5f 53 45 53 53 49 4f 4e 20 26 26 20 53 51  LE_SESSION && SQ
27000 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 50 52 45 55  LITE_ENABLE_PREU
27010 50 44 41 54 45 5f 48 4f 4f 4b 20 2a 2f 0a        PDATE_HOOK */.