/ Hex Artifact Content
Login

Artifact ea4dc9b4a1895c8e6bddcbfe3838d7eb57df2d99:


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 54 45 53 54 29 20 26 26 20 64 65 66  ITE_TEST) && def
0020: 69 6e 65 64 28 53 51 4c 49 54 45 5f 45 4e 41 42  ined(SQLITE_ENAB
0030: 4c 45 5f 53 45 53 53 49 4f 4e 29 20 5c 0a 20 26  LE_SESSION) \. &
0040: 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  & defined(SQLITE
0050: 5f 45 4e 41 42 4c 45 5f 50 52 45 55 50 44 41 54  _ENABLE_PREUPDAT
0060: 45 5f 48 4f 4f 4b 29 0a 0a 23 69 6e 63 6c 75 64  E_HOOK)..#includ
0070: 65 20 22 73 71 6c 69 74 65 33 73 65 73 73 69 6f  e "sqlite3sessio
0080: 6e 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 3c 61  n.h".#include <a
0090: 73 73 65 72 74 2e 68 3e 0a 23 69 6e 63 6c 75 64  ssert.h>.#includ
00a0: 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e  e <string.h>.#in
00b0: 63 6c 75 64 65 20 3c 74 63 6c 2e 68 3e 0a 0a 73  clude <tcl.h>..s
00c0: 74 61 74 69 63 20 69 6e 74 20 74 65 73 74 5f 73  tatic int test_s
00d0: 65 73 73 69 6f 6e 5f 65 72 72 6f 72 28 54 63 6c  ession_error(Tcl
00e0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
00f0: 20 69 6e 74 20 72 63 29 7b 0a 20 20 65 78 74 65   int rc){.  exte
0100: 72 6e 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 73  rn const char *s
0110: 71 6c 69 74 65 33 54 65 73 74 45 72 72 6f 72 4e  qlite3TestErrorN
0120: 61 6d 65 28 69 6e 74 29 3b 0a 20 20 54 63 6c 5f  ame(int);.  Tcl_
0130: 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  SetObjResult(int
0140: 65 72 70 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69  erp, Tcl_NewStri
0150: 6e 67 4f 62 6a 28 73 71 6c 69 74 65 33 54 65 73  ngObj(sqlite3Tes
0160: 74 45 72 72 6f 72 4e 61 6d 65 28 72 63 29 2c 20  tErrorName(rc), 
0170: 2d 31 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 54  -1));.  return T
0180: 43 4c 5f 45 52 52 4f 52 3b 0a 7d 0a 0a 2f 2a 0a  CL_ERROR;.}../*.
0190: 2a 2a 20 54 63 6c 63 6d 64 3a 20 20 24 73 65 73  ** Tclcmd:  $ses
01a0: 73 69 6f 6e 20 61 74 74 61 63 68 20 54 41 42 4c  sion attach TABL
01b0: 45 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 24 73  E.**          $s
01c0: 65 73 73 69 6f 6e 20 63 68 61 6e 67 65 73 65 74  ession changeset
01d0: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 24 73 65  .**          $se
01e0: 73 73 69 6f 6e 20 64 65 6c 65 74 65 0a 2a 2a 20  ssion delete.** 
01f0: 20 20 20 20 20 20 20 20 20 24 73 65 73 73 69 6f           $sessio
0200: 6e 20 65 6e 61 62 6c 65 20 42 4f 4f 4c 0a 2a 2a  n enable BOOL.**
0210: 20 20 20 20 20 20 20 20 20 20 24 73 65 73 73 69            $sessi
0220: 6f 6e 20 69 6e 64 69 72 65 63 74 20 49 4e 54 45  on indirect INTE
0230: 47 45 52 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  GER.*/.static in
0240: 74 20 74 65 73 74 5f 73 65 73 73 69 6f 6e 5f 63  t test_session_c
0250: 6d 64 28 0a 20 20 76 6f 69 64 20 2a 63 6c 69 65  md(.  void *clie
0260: 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e  ntData,.  Tcl_In
0270: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20  terp *interp,.  
0280: 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f  int objc,.  Tcl_
0290: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
02a0: 5d 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73  ].){.  sqlite3_s
02b0: 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f 6e  ession *pSession
02c0: 20 3d 20 28 73 71 6c 69 74 65 33 5f 73 65 73 73   = (sqlite3_sess
02d0: 69 6f 6e 20 2a 29 63 6c 69 65 6e 74 44 61 74 61  ion *)clientData
02e0: 3b 0a 20 20 73 74 72 75 63 74 20 53 65 73 73 69  ;.  struct Sessi
02f0: 6f 6e 53 75 62 63 6d 64 20 7b 0a 20 20 20 20 63  onSubcmd {.    c
0300: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 75 62 3b  onst char *zSub;
0310: 0a 20 20 20 20 69 6e 74 20 6e 41 72 67 3b 0a 20  .    int nArg;. 
0320: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
0330: 4d 73 67 3b 0a 20 20 20 20 69 6e 74 20 69 53 75  Msg;.    int iSu
0340: 62 3b 0a 20 20 7d 20 61 53 75 62 5b 5d 20 3d 20  b;.  } aSub[] = 
0350: 7b 0a 20 20 20 20 7b 20 22 61 74 74 61 63 68 22  {.    { "attach"
0360: 2c 20 20 20 20 31 2c 20 22 54 41 42 4c 45 22 2c  ,    1, "TABLE",
0370: 20 7d 2c 20 2f 2a 20 30 20 2a 2f 0a 20 20 20 20   }, /* 0 */.    
0380: 7b 20 22 63 68 61 6e 67 65 73 65 74 22 2c 20 30  { "changeset", 0
0390: 2c 20 22 22 2c 20 20 20 20 20 20 7d 2c 20 2f 2a  , "",      }, /*
03a0: 20 31 20 2a 2f 0a 20 20 20 20 7b 20 22 64 65 6c   1 */.    { "del
03b0: 65 74 65 22 2c 20 20 20 20 30 2c 20 22 22 2c 20  ete",    0, "", 
03c0: 20 20 20 20 20 7d 2c 20 2f 2a 20 32 20 2a 2f 0a       }, /* 2 */.
03d0: 20 20 20 20 7b 20 22 65 6e 61 62 6c 65 22 2c 20      { "enable", 
03e0: 20 20 20 31 2c 20 22 42 4f 4f 4c 22 2c 20 20 7d     1, "BOOL",  }
03f0: 2c 20 2f 2a 20 33 20 2a 2f 0a 20 20 20 20 7b 20  , /* 3 */.    { 
0400: 22 69 6e 64 69 72 65 63 74 22 2c 20 20 31 2c 20  "indirect",  1, 
0410: 22 42 4f 4f 4c 22 2c 20 20 7d 2c 20 2f 2a 20 34  "BOOL",  }, /* 4
0420: 20 2a 2f 0a 20 20 20 20 7b 20 22 69 73 65 6d 70   */.    { "isemp
0430: 74 79 22 2c 20 20 20 30 2c 20 22 22 2c 20 20 20  ty",   0, "",   
0440: 20 20 20 7d 2c 20 2f 2a 20 35 20 2a 2f 0a 20 20     }, /* 5 */.  
0450: 20 20 7b 20 30 20 7d 0a 20 20 7d 3b 0a 20 20 69    { 0 }.  };.  i
0460: 6e 74 20 69 53 75 62 3b 0a 20 20 69 6e 74 20 72  nt iSub;.  int r
0470: 63 3b 0a 0a 20 20 69 66 28 20 6f 62 6a 63 3c 32  c;..  if( objc<2
0480: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e   ){.    Tcl_Wron
0490: 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c  gNumArgs(interp,
04a0: 20 31 2c 20 6f 62 6a 76 2c 20 22 53 55 42 43 4f   1, objv, "SUBCO
04b0: 4d 4d 41 4e 44 20 2e 2e 2e 22 29 3b 0a 20 20 20  MMAND ...");.   
04c0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
04d0: 52 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 54 63  R;.  }.  rc = Tc
04e0: 6c 5f 47 65 74 49 6e 64 65 78 46 72 6f 6d 4f 62  l_GetIndexFromOb
04f0: 6a 53 74 72 75 63 74 28 69 6e 74 65 72 70 2c 20  jStruct(interp, 
0500: 0a 20 20 20 20 20 20 6f 62 6a 76 5b 31 5d 2c 20  .      objv[1], 
0510: 61 53 75 62 2c 20 73 69 7a 65 6f 66 28 61 53 75  aSub, sizeof(aSu
0520: 62 5b 30 5d 29 2c 20 22 73 75 62 2d 63 6f 6d 6d  b[0]), "sub-comm
0530: 61 6e 64 22 2c 20 30 2c 20 26 69 53 75 62 0a 20  and", 0, &iSub. 
0540: 20 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 54 43   );.  if( rc!=TC
0550: 4c 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  L_OK ) return rc
0560: 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 32 2b  ;.  if( objc!=2+
0570: 61 53 75 62 5b 69 53 75 62 5d 2e 6e 41 72 67 20  aSub[iSub].nArg 
0580: 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67  ){.    Tcl_Wrong
0590: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
05a0: 32 2c 20 6f 62 6a 76 2c 20 61 53 75 62 5b 69 53  2, objv, aSub[iS
05b0: 75 62 5d 2e 7a 4d 73 67 29 3b 0a 20 20 20 20 72  ub].zMsg);.    r
05c0: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
05d0: 0a 20 20 7d 0a 0a 20 20 73 77 69 74 63 68 28 20  .  }..  switch( 
05e0: 69 53 75 62 20 29 7b 0a 20 20 20 20 63 61 73 65  iSub ){.    case
05f0: 20 30 3a 20 7b 20 20 20 20 20 20 2f 2a 20 61 74   0: {      /* at
0600: 74 61 63 68 20 2a 2f 0a 20 20 20 20 20 20 63 68  tach */.      ch
0610: 61 72 20 2a 7a 41 72 67 20 3d 20 54 63 6c 5f 47  ar *zArg = Tcl_G
0620: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d  etString(objv[2]
0630: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 41 72  );.      if( zAr
0640: 67 5b 30 5d 3d 3d 27 2a 27 20 26 26 20 7a 41 72  g[0]=='*' && zAr
0650: 67 5b 31 5d 3d 3d 27 5c 30 27 20 29 20 7a 41 72  g[1]=='\0' ) zAr
0660: 67 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 63 20  g = 0;.      rc 
0670: 3d 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e  = sqlite3session
0680: 5f 61 74 74 61 63 68 28 70 53 65 73 73 69 6f 6e  _attach(pSession
0690: 2c 20 7a 41 72 67 29 3b 0a 20 20 20 20 20 20 69  , zArg);.      i
06a0: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
06b0: 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75   ){.        retu
06c0: 72 6e 20 74 65 73 74 5f 73 65 73 73 69 6f 6e 5f  rn test_session_
06d0: 65 72 72 6f 72 28 69 6e 74 65 72 70 2c 20 72 63  error(interp, rc
06e0: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
06f0: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20  .      break;.. 
0700: 20 20 20 63 61 73 65 20 31 3a 20 7b 20 20 20 20     case 1: {    
0710: 20 20 2f 2a 20 63 68 61 6e 67 65 73 65 74 20 2a    /* changeset *
0720: 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e 43 68 61  /.      int nCha
0730: 6e 67 65 3b 0a 20 20 20 20 20 20 76 6f 69 64 20  nge;.      void 
0740: 2a 70 43 68 61 6e 67 65 3b 0a 20 20 20 20 20 20  *pChange;.      
0750: 72 63 20 3d 20 73 71 6c 69 74 65 33 73 65 73 73  rc = sqlite3sess
0760: 69 6f 6e 5f 63 68 61 6e 67 65 73 65 74 28 70 53  ion_changeset(pS
0770: 65 73 73 69 6f 6e 2c 20 26 6e 43 68 61 6e 67 65  ession, &nChange
0780: 2c 20 26 70 43 68 61 6e 67 65 29 3b 0a 20 20 20  , &pChange);.   
0790: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
07a0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
07b0: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
07c0: 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77  (interp, Tcl_New
07d0: 42 79 74 65 41 72 72 61 79 4f 62 6a 28 70 43 68  ByteArrayObj(pCh
07e0: 61 6e 67 65 2c 20 6e 43 68 61 6e 67 65 29 29 3b  ange, nChange));
07f0: 20 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65   .        sqlite
0800: 33 5f 66 72 65 65 28 70 43 68 61 6e 67 65 29 3b  3_free(pChange);
0810: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
0820: 20 20 20 20 20 20 72 65 74 75 72 6e 20 74 65 73        return tes
0830: 74 5f 73 65 73 73 69 6f 6e 5f 65 72 72 6f 72 28  t_session_error(
0840: 69 6e 74 65 72 70 2c 20 72 63 29 3b 0a 20 20 20  interp, rc);.   
0850: 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b     }.      break
0860: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73  ;.    }..    cas
0870: 65 20 32 3a 20 20 20 20 20 20 20 20 2f 2a 20 64  e 2:        /* d
0880: 65 6c 65 74 65 20 2a 2f 0a 20 20 20 20 20 20 54  elete */.      T
0890: 63 6c 5f 44 65 6c 65 74 65 43 6f 6d 6d 61 6e 64  cl_DeleteCommand
08a0: 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74  (interp, Tcl_Get
08b0: 53 74 72 69 6e 67 28 6f 62 6a 76 5b 30 5d 29 29  String(objv[0]))
08c0: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a  ;.      break;..
08d0: 20 20 20 20 63 61 73 65 20 33 3a 20 7b 20 20 20      case 3: {   
08e0: 20 20 20 2f 2a 20 65 6e 61 62 6c 65 20 2a 2f 0a     /* enable */.
08f0: 20 20 20 20 20 20 69 6e 74 20 76 61 6c 3b 0a 20        int val;. 
0900: 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74       if( Tcl_Get
0910: 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72  IntFromObj(inter
0920: 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 76 61 6c  p, objv[2], &val
0930: 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f 45  ) ) return TCL_E
0940: 52 52 4f 52 3b 0a 20 20 20 20 20 20 76 61 6c 20  RROR;.      val 
0950: 3d 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e  = sqlite3session
0960: 5f 65 6e 61 62 6c 65 28 70 53 65 73 73 69 6f 6e  _enable(pSession
0970: 2c 20 76 61 6c 29 3b 0a 20 20 20 20 20 20 54 63  , val);.      Tc
0980: 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69  l_SetObjResult(i
0990: 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 42 6f  nterp, Tcl_NewBo
09a0: 6f 6c 65 61 6e 4f 62 6a 28 76 61 6c 29 29 3b 0a  oleanObj(val));.
09b0: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
09c0: 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 34 3a 20   }..    case 4: 
09d0: 7b 20 20 20 20 20 20 2f 2a 20 69 6e 64 69 72 65  {      /* indire
09e0: 63 74 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20  ct */.      int 
09f0: 76 61 6c 3b 0a 20 20 20 20 20 20 69 66 28 20 54  val;.      if( T
0a00: 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a  cl_GetIntFromObj
0a10: 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d  (interp, objv[2]
0a20: 2c 20 26 76 61 6c 29 20 29 20 72 65 74 75 72 6e  , &val) ) return
0a30: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
0a40: 20 20 76 61 6c 20 3d 20 73 71 6c 69 74 65 33 73    val = sqlite3s
0a50: 65 73 73 69 6f 6e 5f 69 6e 64 69 72 65 63 74 28  ession_indirect(
0a60: 70 53 65 73 73 69 6f 6e 2c 20 76 61 6c 29 3b 0a  pSession, val);.
0a70: 20 20 20 20 20 20 54 63 6c 5f 53 65 74 4f 62 6a        Tcl_SetObj
0a80: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54  Result(interp, T
0a90: 63 6c 5f 4e 65 77 42 6f 6f 6c 65 61 6e 4f 62 6a  cl_NewBooleanObj
0aa0: 28 76 61 6c 29 29 3b 0a 20 20 20 20 20 20 62 72  (val));.      br
0ab0: 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  eak;.    }..    
0ac0: 63 61 73 65 20 35 3a 20 7b 20 20 20 20 20 20 2f  case 5: {      /
0ad0: 2a 20 69 73 65 6d 70 74 79 20 2a 2f 0a 20 20 20  * isempty */.   
0ae0: 20 20 20 69 6e 74 20 76 61 6c 3b 0a 20 20 20 20     int val;.    
0af0: 20 20 76 61 6c 20 3d 20 73 71 6c 69 74 65 33 73    val = sqlite3s
0b00: 65 73 73 69 6f 6e 5f 69 73 65 6d 70 74 79 28 70  ession_isempty(p
0b10: 53 65 73 73 69 6f 6e 29 3b 0a 20 20 20 20 20 20  Session);.      
0b20: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
0b30: 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77  (interp, Tcl_New
0b40: 42 6f 6f 6c 65 61 6e 4f 62 6a 28 76 61 6c 29 29  BooleanObj(val))
0b50: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
0b60: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
0b70: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 73 74  rn TCL_OK;.}..st
0b80: 61 74 69 63 20 76 6f 69 64 20 74 65 73 74 5f 73  atic void test_s
0b90: 65 73 73 69 6f 6e 5f 64 65 6c 28 76 6f 69 64 20  ession_del(void 
0ba0: 2a 63 6c 69 65 6e 74 44 61 74 61 29 7b 0a 20 20  *clientData){.  
0bb0: 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20  sqlite3_session 
0bc0: 2a 70 53 65 73 73 69 6f 6e 20 3d 20 28 73 71 6c  *pSession = (sql
0bd0: 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a 29 63  ite3_session *)c
0be0: 6c 69 65 6e 74 44 61 74 61 3b 0a 20 20 73 71 6c  lientData;.  sql
0bf0: 69 74 65 33 73 65 73 73 69 6f 6e 5f 64 65 6c 65  ite3session_dele
0c00: 74 65 28 70 53 65 73 73 69 6f 6e 29 3b 0a 7d 0a  te(pSession);.}.
0c10: 0a 2f 2a 0a 2a 2a 20 54 63 6c 63 6d 64 3a 20 20  ./*.** Tclcmd:  
0c20: 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 20 43  sqlite3session C
0c30: 4d 44 20 44 42 2d 48 41 4e 44 4c 45 20 44 42 2d  MD DB-HANDLE DB-
0c40: 4e 41 4d 45 0a 2a 2f 0a 73 74 61 74 69 63 20 69  NAME.*/.static i
0c50: 6e 74 20 74 65 73 74 5f 73 71 6c 69 74 65 33 73  nt test_sqlite3s
0c60: 65 73 73 69 6f 6e 28 0a 20 20 76 6f 69 64 20 2a  ession(.  void *
0c70: 20 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54   clientData,.  T
0c80: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
0c90: 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20  p,.  int objc,. 
0ca0: 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20   Tcl_Obj *CONST 
0cb0: 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 73 71 6c 69  objv[].){.  sqli
0cc0: 74 65 33 20 2a 64 62 3b 0a 20 20 54 63 6c 5f 43  te3 *db;.  Tcl_C
0cd0: 6d 64 49 6e 66 6f 20 69 6e 66 6f 3b 0a 20 20 69  mdInfo info;.  i
0ce0: 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
0cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0d00: 2a 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e  * sqlite3session
0d10: 5f 63 72 65 61 74 65 28 29 20 72 65 74 75 72 6e  _create() return
0d20: 20 63 6f 64 65 20 2a 2f 0a 20 20 73 71 6c 69 74   code */.  sqlit
0d30: 65 33 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73  e3_session *pSes
0d40: 73 69 6f 6e 3b 20 20 20 20 20 20 2f 2a 20 4e 65  sion;      /* Ne
0d50: 77 20 73 65 73 73 69 6f 6e 20 6f 62 6a 65 63 74  w session object
0d60: 20 2a 2f 0a 0a 20 20 69 66 28 20 6f 62 6a 63 21   */..  if( objc!
0d70: 3d 34 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72  =4 ){.    Tcl_Wr
0d80: 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72  ongNumArgs(inter
0d90: 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 43 4d 44  p, 1, objv, "CMD
0da0: 20 44 42 2d 48 41 4e 44 4c 45 20 44 42 2d 4e 41   DB-HANDLE DB-NA
0db0: 4d 45 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  ME");.    return
0dc0: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a   TCL_ERROR;.  }.
0dd0: 0a 20 20 69 66 28 20 30 3d 3d 54 63 6c 5f 47 65  .  if( 0==Tcl_Ge
0de0: 74 43 6f 6d 6d 61 6e 64 49 6e 66 6f 28 69 6e 74  tCommandInfo(int
0df0: 65 72 70 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  erp, Tcl_GetStri
0e00: 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c 20 26 69 6e  ng(objv[2]), &in
0e10: 66 6f 29 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41  fo) ){.    Tcl_A
0e20: 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65  ppendResult(inte
0e30: 72 70 2c 20 22 6e 6f 20 73 75 63 68 20 68 61 6e  rp, "no such han
0e40: 64 6c 65 3a 20 22 2c 20 54 63 6c 5f 47 65 74 53  dle: ", Tcl_GetS
0e50: 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c 20  tring(objv[2]), 
0e60: 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54  0);.    return T
0e70: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20  CL_ERROR;.  }.  
0e80: 64 62 20 3d 20 2a 28 73 71 6c 69 74 65 33 20 2a  db = *(sqlite3 *
0e90: 2a 29 69 6e 66 6f 2e 6f 62 6a 43 6c 69 65 6e 74  *)info.objClient
0ea0: 44 61 74 61 3b 0a 0a 20 20 72 63 20 3d 20 73 71  Data;..  rc = sq
0eb0: 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 63 72 65  lite3session_cre
0ec0: 61 74 65 28 64 62 2c 20 54 63 6c 5f 47 65 74 53  ate(db, Tcl_GetS
0ed0: 74 72 69 6e 67 28 6f 62 6a 76 5b 33 5d 29 2c 20  tring(objv[3]), 
0ee0: 26 70 53 65 73 73 69 6f 6e 29 3b 0a 20 20 69 66  &pSession);.  if
0ef0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
0f00: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 74 65  ){.    return te
0f10: 73 74 5f 73 65 73 73 69 6f 6e 5f 65 72 72 6f 72  st_session_error
0f20: 28 69 6e 74 65 72 70 2c 20 72 63 29 3b 0a 20 20  (interp, rc);.  
0f30: 7d 0a 0a 20 20 54 63 6c 5f 43 72 65 61 74 65 4f  }..  Tcl_CreateO
0f40: 62 6a 43 6f 6d 6d 61 6e 64 28 0a 20 20 20 20 20  bjCommand(.     
0f50: 20 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74   interp, Tcl_Get
0f60: 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c  String(objv[1]),
0f70: 20 74 65 73 74 5f 73 65 73 73 69 6f 6e 5f 63 6d   test_session_cm
0f80: 64 2c 20 28 43 6c 69 65 6e 74 44 61 74 61 29 70  d, (ClientData)p
0f90: 53 65 73 73 69 6f 6e 2c 0a 20 20 20 20 20 20 74  Session,.      t
0fa0: 65 73 74 5f 73 65 73 73 69 6f 6e 5f 64 65 6c 0a  est_session_del.
0fb0: 20 20 29 3b 0a 20 20 54 63 6c 5f 53 65 74 4f 62    );.  Tcl_SetOb
0fc0: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  jResult(interp, 
0fd0: 6f 62 6a 76 5b 31 5d 29 3b 0a 20 20 72 65 74 75  objv[1]);.  retu
0fe0: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 73 74  rn TCL_OK;.}..st
0ff0: 61 74 69 63 20 76 6f 69 64 20 74 65 73 74 5f 61  atic void test_a
1000: 70 70 65 6e 64 5f 76 61 6c 75 65 28 54 63 6c 5f  ppend_value(Tcl_
1010: 4f 62 6a 20 2a 70 4c 69 73 74 2c 20 73 71 6c 69  Obj *pList, sqli
1020: 74 65 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c 29  te3_value *pVal)
1030: 7b 0a 20 20 69 66 28 20 70 56 61 6c 3d 3d 30 20  {.  if( pVal==0 
1040: 29 7b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f  ){.    Tcl_ListO
1050: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
1060: 30 2c 20 70 4c 69 73 74 2c 20 54 63 6c 5f 4e 65  0, pList, Tcl_Ne
1070: 77 4f 62 6a 28 29 29 3b 0a 20 20 20 20 54 63 6c  wObj());.    Tcl
1080: 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c  _ListObjAppendEl
1090: 65 6d 65 6e 74 28 30 2c 20 70 4c 69 73 74 2c 20  ement(0, pList, 
10a0: 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 29 3b 0a 20  Tcl_NewObj());. 
10b0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 54 63 6c 5f   }else{.    Tcl_
10c0: 4f 62 6a 20 2a 70 4f 62 6a 3b 0a 20 20 20 20 73  Obj *pObj;.    s
10d0: 77 69 74 63 68 28 20 73 71 6c 69 74 65 33 5f 76  witch( sqlite3_v
10e0: 61 6c 75 65 5f 74 79 70 65 28 70 56 61 6c 29 20  alue_type(pVal) 
10f0: 29 7b 0a 20 20 20 20 20 20 63 61 73 65 20 53 51  ){.      case SQ
1100: 4c 49 54 45 5f 4e 55 4c 4c 3a 0a 20 20 20 20 20  LITE_NULL:.     
1110: 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70     Tcl_ListObjAp
1120: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70  pendElement(0, p
1130: 4c 69 73 74 2c 20 54 63 6c 5f 4e 65 77 53 74 72  List, Tcl_NewStr
1140: 69 6e 67 4f 62 6a 28 22 6e 22 2c 20 31 29 29 3b  ingObj("n", 1));
1150: 0a 20 20 20 20 20 20 20 20 70 4f 62 6a 20 3d 20  .        pObj = 
1160: 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20  Tcl_NewObj();.  
1170: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
1180: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49     case SQLITE_I
1190: 4e 54 45 47 45 52 3a 0a 20 20 20 20 20 20 20 20  NTEGER:.        
11a0: 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e  Tcl_ListObjAppen
11b0: 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 4c 69 73  dElement(0, pLis
11c0: 74 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67  t, Tcl_NewString
11d0: 4f 62 6a 28 22 69 22 2c 20 31 29 29 3b 0a 20 20  Obj("i", 1));.  
11e0: 20 20 20 20 20 20 70 4f 62 6a 20 3d 20 54 63 6c        pObj = Tcl
11f0: 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 73  _NewWideIntObj(s
1200: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74  qlite3_value_int
1210: 36 34 28 70 56 61 6c 29 29 3b 0a 20 20 20 20 20  64(pVal));.     
1220: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
1230: 63 61 73 65 20 53 51 4c 49 54 45 5f 46 4c 4f 41  case SQLITE_FLOA
1240: 54 3a 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4c  T:.        Tcl_L
1250: 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d  istObjAppendElem
1260: 65 6e 74 28 30 2c 20 70 4c 69 73 74 2c 20 54 63  ent(0, pList, Tc
1270: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
1280: 66 22 2c 20 31 29 29 3b 0a 20 20 20 20 20 20 20  f", 1));.       
1290: 20 70 4f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77 44   pObj = Tcl_NewD
12a0: 6f 75 62 6c 65 4f 62 6a 28 73 71 6c 69 74 65 33  oubleObj(sqlite3
12b0: 5f 76 61 6c 75 65 5f 64 6f 75 62 6c 65 28 70 56  _value_double(pV
12c0: 61 6c 29 29 3b 0a 20 20 20 20 20 20 20 20 62 72  al));.        br
12d0: 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20  eak;.      case 
12e0: 53 51 4c 49 54 45 5f 54 45 58 54 3a 0a 20 20 20  SQLITE_TEXT:.   
12f0: 20 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a       Tcl_ListObj
1300: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c  AppendElement(0,
1310: 20 70 4c 69 73 74 2c 20 54 63 6c 5f 4e 65 77 53   pList, Tcl_NewS
1320: 74 72 69 6e 67 4f 62 6a 28 22 74 22 2c 20 31 29  tringObj("t", 1)
1330: 29 3b 0a 20 20 20 20 20 20 20 20 70 4f 62 6a 20  );.        pObj 
1340: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
1350: 62 6a 28 28 63 68 61 72 20 2a 29 73 71 6c 69 74  bj((char *)sqlit
1360: 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 70 56  e3_value_text(pV
1370: 61 6c 29 2c 20 2d 31 29 3b 0a 20 20 20 20 20 20  al), -1);.      
1380: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63    break;.      c
1390: 61 73 65 20 53 51 4c 49 54 45 5f 42 4c 4f 42 3a  ase SQLITE_BLOB:
13a0: 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4c 69 73  .        Tcl_Lis
13b0: 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e  tObjAppendElemen
13c0: 74 28 30 2c 20 70 4c 69 73 74 2c 20 54 63 6c 5f  t(0, pList, Tcl_
13d0: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 62 22  NewStringObj("b"
13e0: 2c 20 31 29 29 3b 0a 20 20 20 20 20 20 20 20 70  , 1));.        p
13f0: 4f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77 42 79 74  Obj = Tcl_NewByt
1400: 65 41 72 72 61 79 4f 62 6a 28 0a 20 20 20 20 20  eArrayObj(.     
1410: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76         sqlite3_v
1420: 61 6c 75 65 5f 62 6c 6f 62 28 70 56 61 6c 29 2c  alue_blob(pVal),
1430: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c  .            sql
1440: 69 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73  ite3_value_bytes
1450: 28 70 56 61 6c 29 0a 20 20 20 20 20 20 20 20 29  (pVal).        )
1460: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
1470: 0a 20 20 20 20 7d 0a 20 20 20 20 54 63 6c 5f 4c  .    }.    Tcl_L
1480: 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d  istObjAppendElem
1490: 65 6e 74 28 30 2c 20 70 4c 69 73 74 2c 20 70 4f  ent(0, pList, pO
14a0: 62 6a 29 3b 0a 20 20 7d 0a 7d 0a 0a 74 79 70 65  bj);.  }.}..type
14b0: 64 65 66 20 73 74 72 75 63 74 20 54 65 73 74 43  def struct TestC
14c0: 6f 6e 66 6c 69 63 74 48 61 6e 64 6c 65 72 20 54  onflictHandler T
14d0: 65 73 74 43 6f 6e 66 6c 69 63 74 48 61 6e 64 6c  estConflictHandl
14e0: 65 72 3b 0a 73 74 72 75 63 74 20 54 65 73 74 43  er;.struct TestC
14f0: 6f 6e 66 6c 69 63 74 48 61 6e 64 6c 65 72 20 7b  onflictHandler {
1500: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
1510: 6e 74 65 72 70 3b 0a 20 20 54 63 6c 5f 4f 62 6a  nterp;.  Tcl_Obj
1520: 20 2a 70 43 6f 6e 66 6c 69 63 74 53 63 72 69 70   *pConflictScrip
1530: 74 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 46  t;.  Tcl_Obj *pF
1540: 69 6c 74 65 72 53 63 72 69 70 74 3b 0a 7d 3b 0a  ilterScript;.};.
1550: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 73 74  .static int test
1560: 5f 6f 62 6a 5f 65 71 5f 73 74 72 69 6e 67 28 54  _obj_eq_string(T
1570: 63 6c 5f 4f 62 6a 20 2a 70 2c 20 63 6f 6e 73 74  cl_Obj *p, const
1580: 20 63 68 61 72 20 2a 7a 29 7b 0a 20 20 69 6e 74   char *z){.  int
1590: 20 6e 3b 0a 20 20 69 6e 74 20 6e 4f 62 6a 3b 0a   n;.  int nObj;.
15a0: 20 20 63 68 61 72 20 2a 7a 4f 62 6a 3b 0a 0a 20    char *zObj;.. 
15b0: 20 6e 20 3d 20 73 74 72 6c 65 6e 28 7a 29 3b 0a   n = strlen(z);.
15c0: 20 20 7a 4f 62 6a 20 3d 20 54 63 6c 5f 47 65 74    zObj = Tcl_Get
15d0: 53 74 72 69 6e 67 46 72 6f 6d 4f 62 6a 28 70 2c  StringFromObj(p,
15e0: 20 26 6e 4f 62 6a 29 3b 0a 0a 20 20 72 65 74 75   &nObj);..  retu
15f0: 72 6e 20 28 6e 4f 62 6a 3d 3d 6e 20 26 26 20 28  rn (nObj==n && (
1600: 6e 3d 3d 30 20 7c 7c 20 30 3d 3d 6d 65 6d 63 6d  n==0 || 0==memcm
1610: 70 28 7a 4f 62 6a 2c 20 7a 2c 20 6e 29 29 29 3b  p(zObj, z, n)));
1620: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
1630: 65 73 74 5f 66 69 6c 74 65 72 5f 68 61 6e 64 6c  est_filter_handl
1640: 65 72 28 0a 20 20 76 6f 69 64 20 2a 70 43 74 78  er(.  void *pCtx
1650: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1660: 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
1670: 20 74 6f 20 54 65 73 74 43 6f 6e 66 6c 69 63 74   to TestConflict
1680: 48 61 6e 64 6c 65 72 20 73 74 72 75 63 74 75 72  Handler structur
1690: 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  e */.  const cha
16a0: 72 20 2a 7a 54 61 62 20 20 20 20 20 20 20 20 20  r *zTab         
16b0: 20 20 20 20 20 20 20 2f 2a 20 54 61 62 6c 65 20         /* Table 
16c0: 6e 61 6d 65 20 2a 2f 0a 29 7b 0a 20 20 54 65 73  name */.){.  Tes
16d0: 74 43 6f 6e 66 6c 69 63 74 48 61 6e 64 6c 65 72  tConflictHandler
16e0: 20 2a 70 20 3d 20 28 54 65 73 74 43 6f 6e 66 6c   *p = (TestConfl
16f0: 69 63 74 48 61 6e 64 6c 65 72 20 2a 29 70 43 74  ictHandler *)pCt
1700: 78 3b 0a 20 20 69 6e 74 20 72 65 73 20 3d 20 31  x;.  int res = 1
1710: 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 45 76  ;.  Tcl_Obj *pEv
1720: 61 6c 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70  al;.  Tcl_Interp
1730: 20 2a 69 6e 74 65 72 70 20 3d 20 70 2d 3e 69 6e   *interp = p->in
1740: 74 65 72 70 3b 0a 0a 20 20 70 45 76 61 6c 20 3d  terp;..  pEval =
1750: 20 54 63 6c 5f 44 75 70 6c 69 63 61 74 65 4f 62   Tcl_DuplicateOb
1760: 6a 28 70 2d 3e 70 46 69 6c 74 65 72 53 63 72 69  j(p->pFilterScri
1770: 70 74 29 3b 0a 20 20 54 63 6c 5f 49 6e 63 72 52  pt);.  Tcl_IncrR
1780: 65 66 43 6f 75 6e 74 28 70 45 76 61 6c 29 3b 0a  efCount(pEval);.
1790: 0a 20 20 69 66 28 20 54 43 4c 5f 4f 4b 21 3d 54  .  if( TCL_OK!=T
17a0: 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64  cl_ListObjAppend
17b0: 45 6c 65 6d 65 6e 74 28 30 2c 20 70 45 76 61 6c  Element(0, pEval
17c0: 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  , Tcl_NewStringO
17d0: 62 6a 28 7a 54 61 62 2c 20 2d 31 29 29 0a 20 20  bj(zTab, -1)).  
17e0: 20 7c 7c 20 54 43 4c 5f 4f 4b 21 3d 54 63 6c 5f   || TCL_OK!=Tcl_
17f0: 45 76 61 6c 4f 62 6a 45 78 28 69 6e 74 65 72 70  EvalObjEx(interp
1800: 2c 20 70 45 76 61 6c 2c 20 54 43 4c 5f 45 56 41  , pEval, TCL_EVA
1810: 4c 5f 47 4c 4f 42 41 4c 29 20 0a 20 20 20 7c 7c  L_GLOBAL) .   ||
1820: 20 54 43 4c 5f 4f 4b 21 3d 54 63 6c 5f 47 65 74   TCL_OK!=Tcl_Get
1830: 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72  IntFromObj(inter
1840: 70 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73  p, Tcl_GetObjRes
1850: 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 26 72 65  ult(interp), &re
1860: 73 29 0a 20 20 29 7b 0a 20 20 20 20 54 63 6c 5f  s).  ){.    Tcl_
1870: 42 61 63 6b 67 72 6f 75 6e 64 45 72 72 6f 72 28  BackgroundError(
1880: 69 6e 74 65 72 70 29 3b 0a 20 20 7d 0a 0a 20 20  interp);.  }..  
1890: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74  Tcl_DecrRefCount
18a0: 28 70 45 76 61 6c 29 3b 0a 20 20 72 65 74 75 72  (pEval);.  retur
18b0: 6e 20 72 65 73 3b 0a 7d 20 20 0a 0a 73 74 61 74  n res;.}  ..stat
18c0: 69 63 20 69 6e 74 20 74 65 73 74 5f 63 6f 6e 66  ic int test_conf
18d0: 6c 69 63 74 5f 68 61 6e 64 6c 65 72 28 0a 20 20  lict_handler(.  
18e0: 76 6f 69 64 20 2a 70 43 74 78 2c 20 20 20 20 20  void *pCtx,     
18f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1900: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 54 65  /* Pointer to Te
1910: 73 74 43 6f 6e 66 6c 69 63 74 48 61 6e 64 6c 65  stConflictHandle
1920: 72 20 73 74 72 75 63 74 75 72 65 20 2a 2f 0a 20  r structure */. 
1930: 20 69 6e 74 20 65 43 6f 6e 66 2c 20 20 20 20 20   int eConf,     
1940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1950: 20 2f 2a 20 44 41 54 41 2c 20 4d 49 53 53 49 4e   /* DATA, MISSIN
1960: 47 2c 20 43 4f 4e 46 4c 49 43 54 2c 20 43 4f 4e  G, CONFLICT, CON
1970: 53 54 52 41 49 4e 54 20 2a 2f 0a 20 20 73 71 6c  STRAINT */.  sql
1980: 69 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69  ite3_changeset_i
1990: 74 65 72 20 2a 70 49 74 65 72 20 20 20 2f 2a 20  ter *pIter   /* 
19a0: 48 61 6e 64 6c 65 20 64 65 73 63 72 69 62 69 6e  Handle describin
19b0: 67 20 63 68 61 6e 67 65 20 61 6e 64 20 63 6f 6e  g change and con
19c0: 66 6c 69 63 74 20 2a 2f 0a 29 7b 0a 20 20 54 65  flict */.){.  Te
19d0: 73 74 43 6f 6e 66 6c 69 63 74 48 61 6e 64 6c 65  stConflictHandle
19e0: 72 20 2a 70 20 3d 20 28 54 65 73 74 43 6f 6e 66  r *p = (TestConf
19f0: 6c 69 63 74 48 61 6e 64 6c 65 72 20 2a 29 70 43  lictHandler *)pC
1a00: 74 78 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70  tx;.  Tcl_Obj *p
1a10: 45 76 61 6c 3b 0a 20 20 54 63 6c 5f 49 6e 74 65  Eval;.  Tcl_Inte
1a20: 72 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 2d 3e  rp *interp = p->
1a30: 69 6e 74 65 72 70 3b 0a 20 20 69 6e 74 20 72 65  interp;.  int re
1a40: 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  t = 0;          
1a50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
1a60: 75 72 6e 20 76 61 6c 75 65 20 2a 2f 0a 0a 20 20  urn value */..  
1a70: 69 6e 74 20 6f 70 3b 20 20 20 20 20 20 20 20 20  int op;         
1a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a90: 2f 2a 20 53 51 4c 49 54 45 5f 55 50 44 41 54 45  /* SQLITE_UPDATE
1aa0: 2c 20 44 45 4c 45 54 45 20 6f 72 20 49 4e 53 45  , DELETE or INSE
1ab0: 52 54 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  RT */.  const ch
1ac0: 61 72 20 2a 7a 54 61 62 3b 20 20 20 20 20 20 20  ar *zTab;       
1ad0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20          /* Name 
1ae0: 6f 66 20 74 61 62 6c 65 20 63 6f 6e 66 6c 69 63  of table conflic
1af0: 74 20 69 73 20 6f 6e 20 2a 2f 0a 20 20 69 6e 74  t is on */.  int
1b00: 20 6e 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20   nCol;          
1b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1b20: 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e  Number of column
1b30: 73 20 69 6e 20 74 61 62 6c 65 20 7a 54 61 62 20  s in table zTab 
1b40: 2a 2f 0a 0a 20 20 70 45 76 61 6c 20 3d 20 54 63  */..  pEval = Tc
1b50: 6c 5f 44 75 70 6c 69 63 61 74 65 4f 62 6a 28 70  l_DuplicateObj(p
1b60: 2d 3e 70 43 6f 6e 66 6c 69 63 74 53 63 72 69 70  ->pConflictScrip
1b70: 74 29 3b 0a 20 20 54 63 6c 5f 49 6e 63 72 52 65  t);.  Tcl_IncrRe
1b80: 66 43 6f 75 6e 74 28 70 45 76 61 6c 29 3b 0a 0a  fCount(pEval);..
1b90: 20 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73    sqlite3changes
1ba0: 65 74 5f 6f 70 28 70 49 74 65 72 2c 20 26 7a 54  et_op(pIter, &zT
1bb0: 61 62 2c 20 26 6e 43 6f 6c 2c 20 26 6f 70 2c 20  ab, &nCol, &op, 
1bc0: 30 29 3b 0a 0a 20 20 2f 2a 20 41 70 70 65 6e 64  0);..  /* Append
1bd0: 20 74 68 65 20 6f 70 65 72 61 74 69 6f 6e 20 74   the operation t
1be0: 79 70 65 2e 20 2a 2f 0a 20 20 54 63 6c 5f 4c 69  ype. */.  Tcl_Li
1bf0: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
1c00: 6e 74 28 30 2c 20 70 45 76 61 6c 2c 20 54 63 6c  nt(0, pEval, Tcl
1c10: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 0a 20  _NewStringObj(. 
1c20: 20 20 20 20 20 6f 70 3d 3d 53 51 4c 49 54 45 5f       op==SQLITE_
1c30: 49 4e 53 45 52 54 20 3f 20 22 49 4e 53 45 52 54  INSERT ? "INSERT
1c40: 22 20 3a 0a 20 20 20 20 20 20 6f 70 3d 3d 53 51  " :.      op==SQ
1c50: 4c 49 54 45 5f 55 50 44 41 54 45 20 3f 20 22 55  LITE_UPDATE ? "U
1c60: 50 44 41 54 45 22 20 3a 20 0a 20 20 20 20 20 20  PDATE" : .      
1c70: 22 44 45 4c 45 54 45 22 2c 20 2d 31 0a 20 20 29  "DELETE", -1.  )
1c80: 29 3b 0a 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20  );..  /* Append 
1c90: 74 68 65 20 74 61 62 6c 65 20 6e 61 6d 65 2e 20  the table name. 
1ca0: 2a 2f 0a 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  */.  Tcl_ListObj
1cb0: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c  AppendElement(0,
1cc0: 20 70 45 76 61 6c 2c 20 54 63 6c 5f 4e 65 77 53   pEval, Tcl_NewS
1cd0: 74 72 69 6e 67 4f 62 6a 28 7a 54 61 62 2c 20 2d  tringObj(zTab, -
1ce0: 31 29 29 3b 0a 0a 20 20 2f 2a 20 41 70 70 65 6e  1));..  /* Appen
1cf0: 64 20 74 68 65 20 63 6f 6e 66 6c 69 63 74 20 74  d the conflict t
1d00: 79 70 65 2e 20 2a 2f 0a 20 20 73 77 69 74 63 68  ype. */.  switch
1d10: 28 20 65 43 6f 6e 66 20 29 7b 0a 20 20 20 20 63  ( eConf ){.    c
1d20: 61 73 65 20 53 51 4c 49 54 45 5f 43 48 41 4e 47  ase SQLITE_CHANG
1d30: 45 53 45 54 5f 44 41 54 41 3a 0a 20 20 20 20 20  ESET_DATA:.     
1d40: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
1d50: 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72 70  ndElement(interp
1d60: 2c 20 70 45 76 61 6c 2c 54 63 6c 5f 4e 65 77 53  , pEval,Tcl_NewS
1d70: 74 72 69 6e 67 4f 62 6a 28 22 44 41 54 41 22 2c  tringObj("DATA",
1d80: 2d 31 29 29 3b 0a 20 20 20 20 20 20 62 72 65 61  -1));.      brea
1d90: 6b 3b 0a 20 20 20 20 63 61 73 65 20 53 51 4c 49  k;.    case SQLI
1da0: 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 4e 4f 54  TE_CHANGESET_NOT
1db0: 46 4f 55 4e 44 3a 0a 20 20 20 20 20 20 54 63 6c  FOUND:.      Tcl
1dc0: 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c  _ListObjAppendEl
1dd0: 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 45  ement(interp, pE
1de0: 76 61 6c 2c 54 63 6c 5f 4e 65 77 53 74 72 69 6e  val,Tcl_NewStrin
1df0: 67 4f 62 6a 28 22 4e 4f 54 46 4f 55 4e 44 22 2c  gObj("NOTFOUND",
1e00: 2d 31 29 29 3b 0a 20 20 20 20 20 20 62 72 65 61  -1));.      brea
1e10: 6b 3b 0a 20 20 20 20 63 61 73 65 20 53 51 4c 49  k;.    case SQLI
1e20: 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e  TE_CHANGESET_CON
1e30: 46 4c 49 43 54 3a 0a 20 20 20 20 20 20 54 63 6c  FLICT:.      Tcl
1e40: 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c  _ListObjAppendEl
1e50: 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 45  ement(interp, pE
1e60: 76 61 6c 2c 54 63 6c 5f 4e 65 77 53 74 72 69 6e  val,Tcl_NewStrin
1e70: 67 4f 62 6a 28 22 43 4f 4e 46 4c 49 43 54 22 2c  gObj("CONFLICT",
1e80: 2d 31 29 29 3b 0a 20 20 20 20 20 20 62 72 65 61  -1));.      brea
1e90: 6b 3b 0a 20 20 20 20 63 61 73 65 20 53 51 4c 49  k;.    case SQLI
1ea0: 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e  TE_CHANGESET_CON
1eb0: 53 54 52 41 49 4e 54 3a 0a 20 20 20 20 20 20 54  STRAINT:.      T
1ec0: 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64  cl_ListObjAppend
1ed0: 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20  Element(interp, 
1ee0: 70 45 76 61 6c 2c 54 63 6c 5f 4e 65 77 53 74 72  pEval,Tcl_NewStr
1ef0: 69 6e 67 4f 62 6a 28 22 43 4f 4e 53 54 52 41 49  ingObj("CONSTRAI
1f00: 4e 54 22 2c 2d 31 29 29 3b 0a 20 20 20 20 20 20  NT",-1));.      
1f10: 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  break;.  }..  /*
1f20: 20 49 66 20 74 68 69 73 20 69 73 20 6e 6f 74 20   If this is not 
1f30: 61 6e 20 49 4e 53 45 52 54 2c 20 61 70 70 65 6e  an INSERT, appen
1f40: 64 20 74 68 65 20 6f 6c 64 20 72 6f 77 20 2a 2f  d the old row */
1f50: 0a 20 20 69 66 28 20 6f 70 21 3d 53 51 4c 49 54  .  if( op!=SQLIT
1f60: 45 5f 49 4e 53 45 52 54 20 29 7b 0a 20 20 20 20  E_INSERT ){.    
1f70: 69 6e 74 20 69 3b 0a 20 20 20 20 54 63 6c 5f 4f  int i;.    Tcl_O
1f80: 62 6a 20 2a 70 4f 6c 64 20 3d 20 54 63 6c 5f 4e  bj *pOld = Tcl_N
1f90: 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20 66 6f 72  ewObj();.    for
1fa0: 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b  (i=0; i<nCol; i+
1fb0: 2b 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  +){.      sqlite
1fc0: 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c 3b 0a 20  3_value *pVal;. 
1fd0: 20 20 20 20 20 73 71 6c 69 74 65 33 63 68 61 6e       sqlite3chan
1fe0: 67 65 73 65 74 5f 6f 6c 64 28 70 49 74 65 72 2c  geset_old(pIter,
1ff0: 20 69 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20 20   i, &pVal);.    
2000: 20 20 74 65 73 74 5f 61 70 70 65 6e 64 5f 76 61    test_append_va
2010: 6c 75 65 28 70 4f 6c 64 2c 20 70 56 61 6c 29 3b  lue(pOld, pVal);
2020: 0a 20 20 20 20 7d 0a 20 20 20 20 54 63 6c 5f 4c  .    }.    Tcl_L
2030: 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d  istObjAppendElem
2040: 65 6e 74 28 30 2c 20 70 45 76 61 6c 2c 20 70 4f  ent(0, pEval, pO
2050: 6c 64 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49  ld);.  }..  /* I
2060: 66 20 74 68 69 73 20 69 73 20 6e 6f 74 20 61 20  f this is not a 
2070: 44 45 4c 45 54 45 2c 20 61 70 70 65 6e 64 20 74  DELETE, append t
2080: 68 65 20 6e 65 77 20 72 6f 77 20 2a 2f 0a 20 20  he new row */.  
2090: 69 66 28 20 6f 70 21 3d 53 51 4c 49 54 45 5f 44  if( op!=SQLITE_D
20a0: 45 4c 45 54 45 20 29 7b 0a 20 20 20 20 69 6e 74  ELETE ){.    int
20b0: 20 69 3b 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20   i;.    Tcl_Obj 
20c0: 2a 70 4e 65 77 20 3d 20 54 63 6c 5f 4e 65 77 4f  *pNew = Tcl_NewO
20d0: 62 6a 28 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d  bj();.    for(i=
20e0: 30 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b  0; i<nCol; i++){
20f0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76  .      sqlite3_v
2100: 61 6c 75 65 20 2a 70 56 61 6c 3b 0a 20 20 20 20  alue *pVal;.    
2110: 20 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73    sqlite3changes
2120: 65 74 5f 6e 65 77 28 70 49 74 65 72 2c 20 69 2c  et_new(pIter, i,
2130: 20 26 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 74   &pVal);.      t
2140: 65 73 74 5f 61 70 70 65 6e 64 5f 76 61 6c 75 65  est_append_value
2150: 28 70 4e 65 77 2c 20 70 56 61 6c 29 3b 0a 20 20  (pNew, pVal);.  
2160: 20 20 7d 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74    }.    Tcl_List
2170: 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74  ObjAppendElement
2180: 28 30 2c 20 70 45 76 61 6c 2c 20 70 4e 65 77 29  (0, pEval, pNew)
2190: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74  ;.  }..  /* If t
21a0: 68 69 73 20 69 73 20 61 20 43 48 41 4e 47 45 53  his is a CHANGES
21b0: 45 54 5f 44 41 54 41 20 6f 72 20 43 48 41 4e 47  ET_DATA or CHANG
21c0: 45 53 45 54 5f 43 4f 4e 46 4c 49 43 54 20 63 6f  ESET_CONFLICT co
21d0: 6e 66 6c 69 63 74 2c 20 61 70 70 65 6e 64 0a 20  nflict, append. 
21e0: 20 2a 2a 20 74 68 65 20 63 6f 6e 66 6c 69 63 74   ** the conflict
21f0: 69 6e 67 20 72 6f 77 2e 20 20 2a 2f 0a 20 20 69  ing row.  */.  i
2200: 66 28 20 65 43 6f 6e 66 3d 3d 53 51 4c 49 54 45  f( eConf==SQLITE
2210: 5f 43 48 41 4e 47 45 53 45 54 5f 44 41 54 41 20  _CHANGESET_DATA 
2220: 7c 7c 20 65 43 6f 6e 66 3d 3d 53 51 4c 49 54 45  || eConf==SQLITE
2230: 5f 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c  _CHANGESET_CONFL
2240: 49 43 54 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  ICT ){.    int i
2250: 3b 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70  ;.    Tcl_Obj *p
2260: 43 6f 6e 66 6c 69 63 74 20 3d 20 54 63 6c 5f 4e  Conflict = Tcl_N
2270: 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20 66 6f 72  ewObj();.    for
2280: 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b  (i=0; i<nCol; i+
2290: 2b 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72 63  +){.      int rc
22a0: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
22b0: 76 61 6c 75 65 20 2a 70 56 61 6c 3b 0a 20 20 20  value *pVal;.   
22c0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 63     rc = sqlite3c
22d0: 68 61 6e 67 65 73 65 74 5f 63 6f 6e 66 6c 69 63  hangeset_conflic
22e0: 74 28 70 49 74 65 72 2c 20 69 2c 20 26 70 56 61  t(pIter, i, &pVa
22f0: 6c 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74  l);.      assert
2300: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
2310: 29 3b 0a 20 20 20 20 20 20 74 65 73 74 5f 61 70  );.      test_ap
2320: 70 65 6e 64 5f 76 61 6c 75 65 28 70 43 6f 6e 66  pend_value(pConf
2330: 6c 69 63 74 2c 20 70 56 61 6c 29 3b 0a 20 20 20  lict, pVal);.   
2340: 20 7d 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f   }.    Tcl_ListO
2350: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
2360: 30 2c 20 70 45 76 61 6c 2c 20 70 43 6f 6e 66 6c  0, pEval, pConfl
2370: 69 63 74 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 2a  ict);.  }..  /**
2380: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2390: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
23a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
23b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
23c0: 2a 2a 2a 2a 2a 0a 20 20 2a 2a 20 54 68 69 73 20  *****.  ** This 
23d0: 62 6c 6f 63 6b 20 69 73 20 70 75 72 65 6c 79 20  block is purely 
23e0: 66 6f 72 20 74 65 73 74 69 6e 67 20 73 6f 6d 65  for testing some
23f0: 20 65 72 72 6f 72 20 63 6f 6e 64 69 74 69 6f 6e   error condition
2400: 73 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 65 43  s..  */.  if( eC
2410: 6f 6e 66 3d 3d 53 51 4c 49 54 45 5f 43 48 41 4e  onf==SQLITE_CHAN
2420: 47 45 53 45 54 5f 43 4f 4e 53 54 52 41 49 4e 54  GESET_CONSTRAINT
2430: 20 7c 7c 20 65 43 6f 6e 66 3d 3d 53 51 4c 49 54   || eConf==SQLIT
2440: 45 5f 43 48 41 4e 47 45 53 45 54 5f 4e 4f 54 46  E_CHANGESET_NOTF
2450: 4f 55 4e 44 20 29 7b 0a 20 20 20 20 73 71 6c 69  OUND ){.    sqli
2460: 74 65 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c 3b  te3_value *pVal;
2470: 0a 20 20 20 20 69 6e 74 20 72 63 20 3d 20 73 71  .    int rc = sq
2480: 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 63  lite3changeset_c
2490: 6f 6e 66 6c 69 63 74 28 70 49 74 65 72 2c 20 30  onflict(pIter, 0
24a0: 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20 20 61 73  , &pVal);.    as
24b0: 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45  sert( rc==SQLITE
24c0: 5f 4d 49 53 55 53 45 20 29 3b 0a 20 20 7d 65 6c  _MISUSE );.  }el
24d0: 73 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  se{.    sqlite3_
24e0: 76 61 6c 75 65 20 2a 70 56 61 6c 3b 0a 20 20 20  value *pVal;.   
24f0: 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 69 74 65   int rc = sqlite
2500: 33 63 68 61 6e 67 65 73 65 74 5f 63 6f 6e 66 6c  3changeset_confl
2510: 69 63 74 28 70 49 74 65 72 2c 20 2d 31 2c 20 26  ict(pIter, -1, &
2520: 70 56 61 6c 29 3b 0a 20 20 20 20 61 73 73 65 72  pVal);.    asser
2530: 74 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52 41  t( rc==SQLITE_RA
2540: 4e 47 45 20 29 3b 0a 20 20 20 20 72 63 20 3d 20  NGE );.    rc = 
2550: 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
2560: 5f 63 6f 6e 66 6c 69 63 74 28 70 49 74 65 72 2c  _conflict(pIter,
2570: 20 6e 43 6f 6c 2c 20 26 70 56 61 6c 29 3b 0a 20   nCol, &pVal);. 
2580: 20 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53     assert( rc==S
2590: 51 4c 49 54 45 5f 52 41 4e 47 45 20 29 3b 0a 20  QLITE_RANGE );. 
25a0: 20 7d 0a 20 20 69 66 28 20 6f 70 3d 3d 53 51 4c   }.  if( op==SQL
25b0: 49 54 45 5f 44 45 4c 45 54 45 20 29 7b 0a 20 20  ITE_DELETE ){.  
25c0: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
25d0: 2a 70 56 61 6c 3b 0a 20 20 20 20 69 6e 74 20 72  *pVal;.    int r
25e0: 63 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67  c = sqlite3chang
25f0: 65 73 65 74 5f 6e 65 77 28 70 49 74 65 72 2c 20  eset_new(pIter, 
2600: 30 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20 20 61  0, &pVal);.    a
2610: 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54  ssert( rc==SQLIT
2620: 45 5f 4d 49 53 55 53 45 20 29 3b 0a 20 20 7d 65  E_MISUSE );.  }e
2630: 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  lse{.    sqlite3
2640: 5f 76 61 6c 75 65 20 2a 70 56 61 6c 3b 0a 20 20  _value *pVal;.  
2650: 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 69 74    int rc = sqlit
2660: 65 33 63 68 61 6e 67 65 73 65 74 5f 6e 65 77 28  e3changeset_new(
2670: 70 49 74 65 72 2c 20 2d 31 2c 20 26 70 56 61 6c  pIter, -1, &pVal
2680: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 72  );.    assert( r
2690: 63 3d 3d 53 51 4c 49 54 45 5f 52 41 4e 47 45 20  c==SQLITE_RANGE 
26a0: 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  );.    rc = sqli
26b0: 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6e 65 77  te3changeset_new
26c0: 28 70 49 74 65 72 2c 20 6e 43 6f 6c 2c 20 26 70  (pIter, nCol, &p
26d0: 56 61 6c 29 3b 0a 20 20 20 20 61 73 73 65 72 74  Val);.    assert
26e0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52 41 4e  ( rc==SQLITE_RAN
26f0: 47 45 20 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20  GE );.  }.  if( 
2700: 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52  op==SQLITE_INSER
2710: 54 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  T ){.    sqlite3
2720: 5f 76 61 6c 75 65 20 2a 70 56 61 6c 3b 0a 20 20  _value *pVal;.  
2730: 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 69 74    int rc = sqlit
2740: 65 33 63 68 61 6e 67 65 73 65 74 5f 6f 6c 64 28  e3changeset_old(
2750: 70 49 74 65 72 2c 20 30 2c 20 26 70 56 61 6c 29  pIter, 0, &pVal)
2760: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 72 63  ;.    assert( rc
2770: 3d 3d 53 51 4c 49 54 45 5f 4d 49 53 55 53 45 20  ==SQLITE_MISUSE 
2780: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
2790: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70  sqlite3_value *p
27a0: 56 61 6c 3b 0a 20 20 20 20 69 6e 74 20 72 63 20  Val;.    int rc 
27b0: 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  = sqlite3changes
27c0: 65 74 5f 6f 6c 64 28 70 49 74 65 72 2c 20 2d 31  et_old(pIter, -1
27d0: 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20 20 61 73  , &pVal);.    as
27e0: 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45  sert( rc==SQLITE
27f0: 5f 52 41 4e 47 45 20 29 3b 0a 20 20 20 20 72 63  _RANGE );.    rc
2800: 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65   = sqlite3change
2810: 73 65 74 5f 6f 6c 64 28 70 49 74 65 72 2c 20 6e  set_old(pIter, n
2820: 43 6f 6c 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20  Col, &pVal);.   
2830: 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c   assert( rc==SQL
2840: 49 54 45 5f 52 41 4e 47 45 20 29 3b 0a 20 20 7d  ITE_RANGE );.  }
2850: 0a 20 20 2f 2a 20 45 6e 64 20 6f 66 20 74 65 73  .  /* End of tes
2860: 74 69 6e 67 20 62 6c 6f 63 6b 0a 20 20 2a 2a 2a  ting block.  ***
2870: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2880: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2890: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
28a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
28b0: 2a 2a 2a 2a 2f 0a 0a 20 20 69 66 28 20 54 43 4c  ****/..  if( TCL
28c0: 5f 4f 4b 21 3d 54 63 6c 5f 45 76 61 6c 4f 62 6a  _OK!=Tcl_EvalObj
28d0: 45 78 28 69 6e 74 65 72 70 2c 20 70 45 76 61 6c  Ex(interp, pEval
28e0: 2c 20 54 43 4c 5f 45 56 41 4c 5f 47 4c 4f 42 41  , TCL_EVAL_GLOBA
28f0: 4c 29 20 29 7b 0a 20 20 20 20 54 63 6c 5f 42 61  L) ){.    Tcl_Ba
2900: 63 6b 67 72 6f 75 6e 64 45 72 72 6f 72 28 69 6e  ckgroundError(in
2910: 74 65 72 70 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  terp);.  }else{.
2920: 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 52 65      Tcl_Obj *pRe
2930: 73 20 3d 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65  s = Tcl_GetObjRe
2940: 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 20 20  sult(interp);.  
2950: 20 20 69 66 28 20 74 65 73 74 5f 6f 62 6a 5f 65    if( test_obj_e
2960: 71 5f 73 74 72 69 6e 67 28 70 52 65 73 2c 20 22  q_string(pRes, "
2970: 4f 4d 49 54 22 29 20 7c 7c 20 74 65 73 74 5f 6f  OMIT") || test_o
2980: 62 6a 5f 65 71 5f 73 74 72 69 6e 67 28 70 52 65  bj_eq_string(pRe
2990: 73 2c 20 22 22 29 20 29 7b 0a 20 20 20 20 20 20  s, "") ){.      
29a0: 72 65 74 20 3d 20 53 51 4c 49 54 45 5f 43 48 41  ret = SQLITE_CHA
29b0: 4e 47 45 53 45 54 5f 4f 4d 49 54 3b 0a 20 20 20  NGESET_OMIT;.   
29c0: 20 7d 65 6c 73 65 20 69 66 28 20 74 65 73 74 5f   }else if( test_
29d0: 6f 62 6a 5f 65 71 5f 73 74 72 69 6e 67 28 70 52  obj_eq_string(pR
29e0: 65 73 2c 20 22 52 45 50 4c 41 43 45 22 29 20 29  es, "REPLACE") )
29f0: 7b 0a 20 20 20 20 20 20 72 65 74 20 3d 20 53 51  {.      ret = SQ
2a00: 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 52  LITE_CHANGESET_R
2a10: 45 50 4c 41 43 45 3b 0a 20 20 20 20 7d 65 6c 73  EPLACE;.    }els
2a20: 65 20 69 66 28 20 74 65 73 74 5f 6f 62 6a 5f 65  e if( test_obj_e
2a30: 71 5f 73 74 72 69 6e 67 28 70 52 65 73 2c 20 22  q_string(pRes, "
2a40: 41 42 4f 52 54 22 29 20 29 7b 0a 20 20 20 20 20  ABORT") ){.     
2a50: 20 72 65 74 20 3d 20 53 51 4c 49 54 45 5f 43 48   ret = SQLITE_CH
2a60: 41 4e 47 45 53 45 54 5f 41 42 4f 52 54 3b 0a 20  ANGESET_ABORT;. 
2a70: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
2a80: 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62  Tcl_GetIntFromOb
2a90: 6a 28 30 2c 20 70 52 65 73 2c 20 26 72 65 74 29  j(0, pRes, &ret)
2aa0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 54  ;.    }.  }..  T
2ab0: 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28  cl_DecrRefCount(
2ac0: 70 45 76 61 6c 29 3b 0a 20 20 72 65 74 75 72 6e  pEval);.  return
2ad0: 20 72 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 73   ret;.}../*.** s
2ae0: 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
2af0: 61 70 70 6c 79 20 44 42 20 43 48 41 4e 47 45 53  apply DB CHANGES
2b00: 45 54 20 43 4f 4e 46 4c 49 43 54 2d 53 43 52 49  ET CONFLICT-SCRI
2b10: 50 54 20 3f 46 49 4c 54 45 52 2d 53 43 52 49 50  PT ?FILTER-SCRIP
2b20: 54 3f 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  T?.*/.static int
2b30: 20 74 65 73 74 5f 73 71 6c 69 74 65 33 63 68 61   test_sqlite3cha
2b40: 6e 67 65 73 65 74 5f 61 70 70 6c 79 28 0a 20 20  ngeset_apply(.  
2b50: 76 6f 69 64 20 2a 20 63 6c 69 65 6e 74 44 61 74  void * clientDat
2b60: 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  a,.  Tcl_Interp 
2b70: 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f  *interp,.  int o
2b80: 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a  bjc,.  Tcl_Obj *
2b90: 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a  CONST objv[].){.
2ba0: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b 20 20    sqlite3 *db;  
2bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2bc0: 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61    /* Database ha
2bd0: 6e 64 6c 65 20 2a 2f 0a 20 20 54 63 6c 5f 43 6d  ndle */.  Tcl_Cm
2be0: 64 49 6e 66 6f 20 69 6e 66 6f 3b 20 20 20 20 20  dInfo info;     
2bf0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
2c00: 61 62 61 73 65 20 54 63 6c 20 63 6f 6d 6d 61 6e  abase Tcl comman
2c10: 64 20 28 6f 62 6a 76 5b 31 5d 29 20 69 6e 66 6f  d (objv[1]) info
2c20: 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20 20 20   */.  int rc;   
2c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2c40: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
2c50: 63 6f 64 65 20 66 72 6f 6d 20 63 68 61 6e 67 65  code from change
2c60: 73 65 74 5f 69 6e 76 65 72 74 28 29 20 2a 2f 0a  set_invert() */.
2c70: 20 20 76 6f 69 64 20 2a 70 43 68 61 6e 67 65 73    void *pChanges
2c80: 65 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  et;             
2c90: 20 20 2f 2a 20 42 75 66 66 65 72 20 63 6f 6e 74    /* Buffer cont
2ca0: 61 69 6e 69 6e 67 20 63 68 61 6e 67 65 73 65 74  aining changeset
2cb0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 68 61 6e 67   */.  int nChang
2cc0: 65 73 65 74 3b 20 20 20 20 20 20 20 20 20 20 20  eset;           
2cd0: 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
2ce0: 20 62 75 66 66 65 72 20 61 43 68 61 6e 67 65 73   buffer aChanges
2cf0: 65 74 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20  et in bytes */. 
2d00: 20 54 65 73 74 43 6f 6e 66 6c 69 63 74 48 61 6e   TestConflictHan
2d10: 64 6c 65 72 20 63 74 78 3b 0a 0a 20 20 69 66 28  dler ctx;..  if(
2d20: 20 6f 62 6a 63 21 3d 34 20 26 26 20 6f 62 6a 63   objc!=4 && objc
2d30: 21 3d 35 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57  !=5 ){.    Tcl_W
2d40: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
2d50: 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 0a 20 20  rp, 1, objv, .  
2d60: 20 20 20 20 20 20 22 44 42 20 43 48 41 4e 47 45        "DB CHANGE
2d70: 53 45 54 20 43 4f 4e 46 4c 49 43 54 2d 53 43 52  SET CONFLICT-SCR
2d80: 49 50 54 20 3f 46 49 4c 54 45 52 2d 53 43 52 49  IPT ?FILTER-SCRI
2d90: 50 54 3f 22 0a 20 20 20 20 29 3b 0a 20 20 20 20  PT?".    );.    
2da0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
2db0: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 30 3d 3d 54  ;.  }.  if( 0==T
2dc0: 63 6c 5f 47 65 74 43 6f 6d 6d 61 6e 64 49 6e 66  cl_GetCommandInf
2dd0: 6f 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65  o(interp, Tcl_Ge
2de0: 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29  tString(objv[1])
2df0: 2c 20 26 69 6e 66 6f 29 20 29 7b 0a 20 20 20 20  , &info) ){.    
2e00: 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74  Tcl_AppendResult
2e10: 28 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75 63  (interp, "no suc
2e20: 68 20 68 61 6e 64 6c 65 3a 20 22 2c 20 54 63 6c  h handle: ", Tcl
2e30: 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b  _GetString(objv[
2e40: 32 5d 29 2c 20 30 29 3b 0a 20 20 20 20 72 65 74  2]), 0);.    ret
2e50: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
2e60: 20 7d 0a 20 20 64 62 20 3d 20 2a 28 73 71 6c 69   }.  db = *(sqli
2e70: 74 65 33 20 2a 2a 29 69 6e 66 6f 2e 6f 62 6a 43  te3 **)info.objC
2e80: 6c 69 65 6e 74 44 61 74 61 3b 0a 20 20 70 43 68  lientData;.  pCh
2e90: 61 6e 67 65 73 65 74 20 3d 20 28 76 6f 69 64 20  angeset = (void 
2ea0: 2a 29 54 63 6c 5f 47 65 74 42 79 74 65 41 72 72  *)Tcl_GetByteArr
2eb0: 61 79 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 32  ayFromObj(objv[2
2ec0: 5d 2c 20 26 6e 43 68 61 6e 67 65 73 65 74 29 3b  ], &nChangeset);
2ed0: 0a 20 20 63 74 78 2e 70 43 6f 6e 66 6c 69 63 74  .  ctx.pConflict
2ee0: 53 63 72 69 70 74 20 3d 20 6f 62 6a 76 5b 33 5d  Script = objv[3]
2ef0: 3b 0a 20 20 63 74 78 2e 70 46 69 6c 74 65 72 53  ;.  ctx.pFilterS
2f00: 63 72 69 70 74 20 3d 20 6f 62 6a 63 3d 3d 35 20  cript = objc==5 
2f10: 3f 20 6f 62 6a 76 5b 34 5d 20 3a 20 30 3b 0a 20  ? objv[4] : 0;. 
2f20: 20 63 74 78 2e 69 6e 74 65 72 70 20 3d 20 69 6e   ctx.interp = in
2f30: 74 65 72 70 3b 0a 0a 20 20 72 63 20 3d 20 73 71  terp;..  rc = sq
2f40: 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 61  lite3changeset_a
2f50: 70 70 6c 79 28 64 62 2c 20 6e 43 68 61 6e 67 65  pply(db, nChange
2f60: 73 65 74 2c 20 70 43 68 61 6e 67 65 73 65 74 2c  set, pChangeset,
2f70: 20 0a 20 20 20 20 20 20 28 6f 62 6a 63 3d 3d 35   .      (objc==5
2f80: 29 20 3f 20 74 65 73 74 5f 66 69 6c 74 65 72 5f  ) ? test_filter_
2f90: 68 61 6e 64 6c 65 72 20 3a 20 30 2c 20 74 65 73  handler : 0, tes
2fa0: 74 5f 63 6f 6e 66 6c 69 63 74 5f 68 61 6e 64 6c  t_conflict_handl
2fb0: 65 72 2c 20 28 76 6f 69 64 20 2a 29 26 63 74 78  er, (void *)&ctx
2fc0: 0a 20 20 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  .  );.  if( rc!=
2fd0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
2fe0: 20 72 65 74 75 72 6e 20 74 65 73 74 5f 73 65 73   return test_ses
2ff0: 73 69 6f 6e 5f 65 72 72 6f 72 28 69 6e 74 65 72  sion_error(inter
3000: 70 2c 20 72 63 29 3b 0a 20 20 7d 0a 20 20 54 63  p, rc);.  }.  Tc
3010: 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 69 6e  l_ResetResult(in
3020: 74 65 72 70 29 3b 0a 20 20 72 65 74 75 72 6e 20  terp);.  return 
3030: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  TCL_OK;.}../*.**
3040: 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
3050: 74 5f 69 6e 76 65 72 74 20 43 48 41 4e 47 45 53  t_invert CHANGES
3060: 45 54 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  ET.*/.static int
3070: 20 74 65 73 74 5f 73 71 6c 69 74 65 33 63 68 61   test_sqlite3cha
3080: 6e 67 65 73 65 74 5f 69 6e 76 65 72 74 28 0a 20  ngeset_invert(. 
3090: 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e 74 44 61   void * clientDa
30a0: 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70  ta,.  Tcl_Interp
30b0: 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20   *interp,.  int 
30c0: 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20  objc,.  Tcl_Obj 
30d0: 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b  *CONST objv[].){
30e0: 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
30f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3100: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
3110: 65 20 66 72 6f 6d 20 63 68 61 6e 67 65 73 65 74  e from changeset
3120: 5f 69 6e 76 65 72 74 28 29 20 2a 2f 0a 20 20 76  _invert() */.  v
3130: 6f 69 64 20 2a 61 43 68 61 6e 67 65 73 65 74 3b  oid *aChangeset;
3140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3150: 2a 20 49 6e 70 75 74 20 63 68 61 6e 67 65 73 65  * Input changese
3160: 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 68 61 6e  t */.  int nChan
3170: 67 65 53 65 74 3b 20 20 20 20 20 20 20 20 20 20  geSet;          
3180: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
3190: 66 20 62 75 66 66 65 72 20 61 43 68 61 6e 67 65  f buffer aChange
31a0: 73 65 74 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  set in bytes */.
31b0: 20 20 76 6f 69 64 20 2a 61 4f 75 74 3b 20 20 20    void *aOut;   
31c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
31d0: 20 20 2f 2a 20 4f 75 74 70 75 74 20 63 68 61 6e    /* Output chan
31e0: 67 65 73 65 74 20 2a 2f 0a 20 20 69 6e 74 20 6e  geset */.  int n
31f0: 4f 75 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  Out;            
3200: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
3210: 7a 65 20 6f 66 20 62 75 66 66 65 72 20 61 4f 75  ze of buffer aOu
3220: 74 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 0a 20  t in bytes */.. 
3230: 20 69 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a   if( objc!=2 ){.
3240: 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d      Tcl_WrongNum
3250: 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20  Args(interp, 1, 
3260: 6f 62 6a 76 2c 20 22 43 48 41 4e 47 45 53 45 54  objv, "CHANGESET
3270: 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54  ");.    return T
3280: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20  CL_ERROR;.  }.  
3290: 61 43 68 61 6e 67 65 73 65 74 20 3d 20 28 76 6f  aChangeset = (vo
32a0: 69 64 20 2a 29 54 63 6c 5f 47 65 74 42 79 74 65  id *)Tcl_GetByte
32b0: 41 72 72 61 79 46 72 6f 6d 4f 62 6a 28 6f 62 6a  ArrayFromObj(obj
32c0: 76 5b 31 5d 2c 20 26 6e 43 68 61 6e 67 65 53 65  v[1], &nChangeSe
32d0: 74 29 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69  t);..  rc = sqli
32e0: 74 65 33 63 68 61 6e 67 65 73 65 74 5f 69 6e 76  te3changeset_inv
32f0: 65 72 74 28 6e 43 68 61 6e 67 65 53 65 74 2c 20  ert(nChangeSet, 
3300: 61 43 68 61 6e 67 65 73 65 74 2c 20 26 6e 4f 75  aChangeset, &nOu
3310: 74 2c 20 26 61 4f 75 74 29 3b 0a 20 20 69 66 28  t, &aOut);.  if(
3320: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
3330: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 74 65 73  {.    return tes
3340: 74 5f 73 65 73 73 69 6f 6e 5f 65 72 72 6f 72 28  t_session_error(
3350: 69 6e 74 65 72 70 2c 20 72 63 29 3b 0a 20 20 7d  interp, rc);.  }
3360: 0a 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73  .  Tcl_SetObjRes
3370: 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  ult(interp, Tcl_
3380: 4e 65 77 42 79 74 65 41 72 72 61 79 4f 62 6a 28  NewByteArrayObj(
3390: 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a  (unsigned char *
33a0: 29 61 4f 75 74 2c 20 6e 4f 75 74 29 29 3b 0a 20  )aOut, nOut));. 
33b0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 4f   sqlite3_free(aO
33c0: 75 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43  ut);.  return TC
33d0: 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 73  L_OK;.}../*.** s
33e0: 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
33f0: 63 6f 6e 63 61 74 20 4c 45 46 54 20 52 49 47 48  concat LEFT RIGH
3400: 54 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  T.*/.static int 
3410: 74 65 73 74 5f 73 71 6c 69 74 65 33 63 68 61 6e  test_sqlite3chan
3420: 67 65 73 65 74 5f 63 6f 6e 63 61 74 28 0a 20 20  geset_concat(.  
3430: 76 6f 69 64 20 2a 20 63 6c 69 65 6e 74 44 61 74  void * clientDat
3440: 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  a,.  Tcl_Interp 
3450: 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f  *interp,.  int o
3460: 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a  bjc,.  Tcl_Obj *
3470: 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a  CONST objv[].){.
3480: 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
3490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
34a0: 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
34b0: 20 66 72 6f 6d 20 63 68 61 6e 67 65 73 65 74 5f   from changeset_
34c0: 69 6e 76 65 72 74 28 29 20 2a 2f 0a 20 20 76 6f  invert() */.  vo
34d0: 69 64 20 2a 61 4c 65 66 74 3b 20 20 20 20 20 20  id *aLeft;      
34e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
34f0: 20 49 6e 70 75 74 20 63 68 61 6e 67 65 73 65 74   Input changeset
3500: 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c 65 66 74 3b   */.  int nLeft;
3510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3520: 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
3530: 20 62 75 66 66 65 72 20 61 43 68 61 6e 67 65 73   buffer aChanges
3540: 65 74 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20  et in bytes */. 
3550: 20 76 6f 69 64 20 2a 61 52 69 67 68 74 3b 20 20   void *aRight;  
3560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3570: 20 2f 2a 20 49 6e 70 75 74 20 63 68 61 6e 67 65   /* Input change
3580: 73 65 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 69  set */.  int nRi
3590: 67 68 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ght;            
35a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
35b0: 20 6f 66 20 62 75 66 66 65 72 20 61 43 68 61 6e   of buffer aChan
35c0: 67 65 73 65 74 20 69 6e 20 62 79 74 65 73 20 2a  geset in bytes *
35d0: 2f 0a 20 20 76 6f 69 64 20 2a 61 4f 75 74 3b 20  /.  void *aOut; 
35e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
35f0: 20 20 20 20 2f 2a 20 4f 75 74 70 75 74 20 63 68      /* Output ch
3600: 61 6e 67 65 73 65 74 20 2a 2f 0a 20 20 69 6e 74  angeset */.  int
3610: 20 6e 4f 75 74 3b 20 20 20 20 20 20 20 20 20 20   nOut;          
3620: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3630: 53 69 7a 65 20 6f 66 20 62 75 66 66 65 72 20 61  Size of buffer a
3640: 4f 75 74 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  Out in bytes */.
3650: 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 33 20 29  .  if( objc!=3 )
3660: 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e  {.    Tcl_WrongN
3670: 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31  umArgs(interp, 1
3680: 2c 20 6f 62 6a 76 2c 20 22 4c 45 46 54 20 52 49  , objv, "LEFT RI
3690: 47 48 54 22 29 3b 0a 20 20 20 20 72 65 74 75 72  GHT");.    retur
36a0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
36b0: 0a 20 20 61 4c 65 66 74 20 3d 20 28 76 6f 69 64  .  aLeft = (void
36c0: 20 2a 29 54 63 6c 5f 47 65 74 42 79 74 65 41 72   *)Tcl_GetByteAr
36d0: 72 61 79 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b  rayFromObj(objv[
36e0: 31 5d 2c 20 26 6e 4c 65 66 74 29 3b 0a 20 20 61  1], &nLeft);.  a
36f0: 52 69 67 68 74 20 3d 20 28 76 6f 69 64 20 2a 29  Right = (void *)
3700: 54 63 6c 5f 47 65 74 42 79 74 65 41 72 72 61 79  Tcl_GetByteArray
3710: 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 32 5d 2c  FromObj(objv[2],
3720: 20 26 6e 52 69 67 68 74 29 3b 0a 0a 20 20 72 63   &nRight);..  rc
3730: 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65   = sqlite3change
3740: 73 65 74 5f 63 6f 6e 63 61 74 28 6e 4c 65 66 74  set_concat(nLeft
3750: 2c 20 61 4c 65 66 74 2c 20 6e 52 69 67 68 74 2c  , aLeft, nRight,
3760: 20 61 52 69 67 68 74 2c 20 26 6e 4f 75 74 2c 20   aRight, &nOut, 
3770: 26 61 4f 75 74 29 3b 0a 20 20 69 66 28 20 72 63  &aOut);.  if( rc
3780: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
3790: 20 20 20 72 65 74 75 72 6e 20 74 65 73 74 5f 73     return test_s
37a0: 65 73 73 69 6f 6e 5f 65 72 72 6f 72 28 69 6e 74  ession_error(int
37b0: 65 72 70 2c 20 72 63 29 3b 0a 20 20 7d 0a 20 20  erp, rc);.  }.  
37c0: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
37d0: 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77  (interp, Tcl_New
37e0: 42 79 74 65 41 72 72 61 79 4f 62 6a 28 28 75 6e  ByteArrayObj((un
37f0: 73 69 67 6e 65 64 20 63 68 61 72 20 2a 29 61 4f  signed char *)aO
3800: 75 74 2c 20 6e 4f 75 74 29 29 3b 0a 20 20 73 71  ut, nOut));.  sq
3810: 6c 69 74 65 33 5f 66 72 65 65 28 61 4f 75 74 29  lite3_free(aOut)
3820: 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f  ;.  return TCL_O
3830: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 73 71 6c 69  K;.}../*.** sqli
3840: 74 65 33 73 65 73 73 69 6f 6e 5f 66 6f 72 65 61  te3session_forea
3850: 63 68 20 56 41 52 4e 41 4d 45 20 43 48 41 4e 47  ch VARNAME CHANG
3860: 45 53 45 54 20 53 43 52 49 50 54 0a 2a 2f 0a 73  ESET SCRIPT.*/.s
3870: 74 61 74 69 63 20 69 6e 74 20 74 65 73 74 5f 73  tatic int test_s
3880: 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 66 6f  qlite3session_fo
3890: 72 65 61 63 68 28 0a 20 20 76 6f 69 64 20 2a 20  reach(.  void * 
38a0: 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63  clientData,.  Tc
38b0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
38c0: 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20  ,.  int objc,.  
38d0: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
38e0: 62 6a 76 5b 5d 0a 29 7b 0a 20 20 76 6f 69 64 20  bjv[].){.  void 
38f0: 2a 70 43 68 61 6e 67 65 53 65 74 3b 0a 20 20 69  *pChangeSet;.  i
3900: 6e 74 20 6e 43 68 61 6e 67 65 53 65 74 3b 0a 20  nt nChangeSet;. 
3910: 20 73 71 6c 69 74 65 33 5f 63 68 61 6e 67 65 73   sqlite3_changes
3920: 65 74 5f 69 74 65 72 20 2a 70 49 74 65 72 3b 0a  et_iter *pIter;.
3930: 20 20 69 6e 74 20 72 63 3b 0a 20 20 54 63 6c 5f    int rc;.  Tcl_
3940: 4f 62 6a 20 2a 70 56 61 72 6e 61 6d 65 3b 0a 20  Obj *pVarname;. 
3950: 20 54 63 6c 5f 4f 62 6a 20 2a 70 43 53 3b 0a 20   Tcl_Obj *pCS;. 
3960: 20 54 63 6c 5f 4f 62 6a 20 2a 70 53 63 72 69 70   Tcl_Obj *pScrip
3970: 74 3b 0a 20 20 69 6e 74 20 69 73 43 68 65 63 6b  t;.  int isCheck
3980: 4e 65 78 74 20 3d 20 30 3b 0a 0a 20 20 69 66 28  Next = 0;..  if(
3990: 20 6f 62 6a 63 3e 31 20 29 7b 0a 20 20 20 20 63   objc>1 ){.    c
39a0: 68 61 72 20 2a 7a 4f 70 74 20 3d 20 54 63 6c 5f  har *zOpt = Tcl_
39b0: 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31  GetString(objv[1
39c0: 5d 29 3b 0a 20 20 20 20 69 73 43 68 65 63 6b 4e  ]);.    isCheckN
39d0: 65 78 74 20 3d 20 28 73 74 72 63 6d 70 28 7a 4f  ext = (strcmp(zO
39e0: 70 74 2c 20 22 2d 6e 65 78 74 22 29 3d 3d 30 29  pt, "-next")==0)
39f0: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 6f 62 6a 63  ;.  }.  if( objc
3a00: 21 3d 34 2b 69 73 43 68 65 63 6b 4e 65 78 74 20  !=4+isCheckNext 
3a10: 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67  ){.    Tcl_Wrong
3a20: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
3a30: 31 2c 20 6f 62 6a 76 2c 20 22 3f 2d 6e 65 78 74  1, objv, "?-next
3a40: 3f 20 56 41 52 4e 41 4d 45 20 43 48 41 4e 47 45  ? VARNAME CHANGE
3a50: 53 45 54 20 53 43 52 49 50 54 22 29 3b 0a 20 20  SET SCRIPT");.  
3a60: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
3a70: 4f 52 3b 0a 20 20 7d 0a 0a 20 20 70 56 61 72 6e  OR;.  }..  pVarn
3a80: 61 6d 65 20 3d 20 6f 62 6a 76 5b 31 2b 69 73 43  ame = objv[1+isC
3a90: 68 65 63 6b 4e 65 78 74 5d 3b 0a 20 20 70 43 53  heckNext];.  pCS
3aa0: 20 3d 20 6f 62 6a 76 5b 32 2b 69 73 43 68 65 63   = objv[2+isChec
3ab0: 6b 4e 65 78 74 5d 3b 0a 20 20 70 53 63 72 69 70  kNext];.  pScrip
3ac0: 74 20 3d 20 6f 62 6a 76 5b 33 2b 69 73 43 68 65  t = objv[3+isChe
3ad0: 63 6b 4e 65 78 74 5d 3b 0a 0a 20 20 70 43 68 61  ckNext];..  pCha
3ae0: 6e 67 65 53 65 74 20 3d 20 28 76 6f 69 64 20 2a  ngeSet = (void *
3af0: 29 54 63 6c 5f 47 65 74 42 79 74 65 41 72 72 61  )Tcl_GetByteArra
3b00: 79 46 72 6f 6d 4f 62 6a 28 70 43 53 2c 20 26 6e  yFromObj(pCS, &n
3b10: 43 68 61 6e 67 65 53 65 74 29 3b 0a 20 20 72 63  ChangeSet);.  rc
3b20: 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65   = sqlite3change
3b30: 73 65 74 5f 73 74 61 72 74 28 26 70 49 74 65 72  set_start(&pIter
3b40: 2c 20 6e 43 68 61 6e 67 65 53 65 74 2c 20 70 43  , nChangeSet, pC
3b50: 68 61 6e 67 65 53 65 74 29 3b 0a 20 20 69 66 28  hangeSet);.  if(
3b60: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
3b70: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 74 65 73  {.    return tes
3b80: 74 5f 73 65 73 73 69 6f 6e 5f 65 72 72 6f 72 28  t_session_error(
3b90: 69 6e 74 65 72 70 2c 20 72 63 29 3b 0a 20 20 7d  interp, rc);.  }
3ba0: 0a 0a 20 20 77 68 69 6c 65 28 20 53 51 4c 49 54  ..  while( SQLIT
3bb0: 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33 63 68  E_ROW==sqlite3ch
3bc0: 61 6e 67 65 73 65 74 5f 6e 65 78 74 28 70 49 74  angeset_next(pIt
3bd0: 65 72 29 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e  er) ){.    int n
3be0: 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  Col;            
3bf0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
3c00: 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e  er of columns in
3c10: 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20 69 6e   table */.    in
3c20: 74 20 6e 43 6f 6c 32 3b 20 20 20 20 20 20 20 20  t nCol2;        
3c30: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
3c40: 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73  umber of columns
3c50: 20 69 6e 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20   in table */.   
3c60: 20 69 6e 74 20 6f 70 3b 20 20 20 20 20 20 20 20   int op;        
3c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3c80: 2a 20 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 2c  * SQLITE_INSERT,
3c90: 20 55 50 44 41 54 45 20 6f 72 20 44 45 4c 45 54   UPDATE or DELET
3ca0: 45 20 2a 2f 0a 20 20 20 20 63 6f 6e 73 74 20 63  E */.    const c
3cb0: 68 61 72 20 2a 7a 54 61 62 3b 20 20 20 20 20 20  har *zTab;      
3cc0: 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f         /* Name o
3cd0: 66 20 74 61 62 6c 65 20 63 68 61 6e 67 65 20 61  f table change a
3ce0: 70 70 6c 69 65 73 20 74 6f 20 2a 2f 0a 20 20 20  pplies to */.   
3cf0: 20 54 63 6c 5f 4f 62 6a 20 2a 70 56 61 72 3b 20   Tcl_Obj *pVar; 
3d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3d10: 2a 20 54 63 6c 20 76 61 6c 75 65 20 74 6f 20 73  * Tcl value to s
3d20: 65 74 20 24 56 41 52 4e 41 4d 45 20 74 6f 20 2a  et $VARNAME to *
3d30: 2f 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70  /.    Tcl_Obj *p
3d40: 4f 6c 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  Old;            
3d50: 20 20 20 20 2f 2a 20 56 65 63 74 6f 72 20 6f 66      /* Vector of
3d60: 20 6f 6c 64 2e 2a 20 76 61 6c 75 65 73 20 2a 2f   old.* values */
3d70: 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 4e  .    Tcl_Obj *pN
3d80: 65 77 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ew;             
3d90: 20 20 20 2f 2a 20 56 65 63 74 6f 72 20 6f 66 20     /* Vector of 
3da0: 6e 65 77 2e 2a 20 76 61 6c 75 65 73 20 2a 2f 0a  new.* values */.
3db0: 20 20 20 20 69 6e 74 20 62 49 6e 64 69 72 65 63      int bIndirec
3dc0: 74 3b 0a 0a 20 20 20 20 63 68 61 72 20 2a 7a 50  t;..    char *zP
3dd0: 4b 3b 0a 20 20 20 20 75 6e 73 69 67 6e 65 64 20  K;.    unsigned 
3de0: 63 68 61 72 20 2a 61 62 50 4b 3b 0a 20 20 20 20  char *abPK;.    
3df0: 69 6e 74 20 69 3b 0a 0a 20 20 20 20 73 71 6c 69  int i;..    sqli
3e00: 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f 70 28  te3changeset_op(
3e10: 70 49 74 65 72 2c 20 26 7a 54 61 62 2c 20 26 6e  pIter, &zTab, &n
3e20: 43 6f 6c 2c 20 26 6f 70 2c 20 26 62 49 6e 64 69  Col, &op, &bIndi
3e30: 72 65 63 74 29 3b 0a 20 20 20 20 70 56 61 72 20  rect);.    pVar 
3e40: 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a  = Tcl_NewObj();.
3e50: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
3e60: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20  ppendElement(0, 
3e70: 70 56 61 72 2c 20 54 63 6c 5f 4e 65 77 53 74 72  pVar, Tcl_NewStr
3e80: 69 6e 67 4f 62 6a 28 0a 20 20 20 20 20 20 20 20  ingObj(.        
3e90: 20 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 53    op==SQLITE_INS
3ea0: 45 52 54 20 3f 20 22 49 4e 53 45 52 54 22 20 3a  ERT ? "INSERT" :
3eb0: 0a 20 20 20 20 20 20 20 20 20 20 6f 70 3d 3d 53  .          op==S
3ec0: 51 4c 49 54 45 5f 55 50 44 41 54 45 20 3f 20 22  QLITE_UPDATE ? "
3ed0: 55 50 44 41 54 45 22 20 3a 20 0a 20 20 20 20 20  UPDATE" : .     
3ee0: 20 20 20 20 20 22 44 45 4c 45 54 45 22 2c 20 2d       "DELETE", -
3ef0: 31 0a 20 20 20 20 29 29 3b 0a 0a 20 20 20 20 54  1.    ));..    T
3f00: 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64  cl_ListObjAppend
3f10: 45 6c 65 6d 65 6e 74 28 30 2c 20 70 56 61 72 2c  Element(0, pVar,
3f20: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
3f30: 6a 28 7a 54 61 62 2c 20 2d 31 29 29 3b 0a 20 20  j(zTab, -1));.  
3f40: 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70    Tcl_ListObjApp
3f50: 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 56  endElement(0, pV
3f60: 61 72 2c 20 54 63 6c 5f 4e 65 77 42 6f 6f 6c 65  ar, Tcl_NewBoole
3f70: 61 6e 4f 62 6a 28 62 49 6e 64 69 72 65 63 74 29  anObj(bIndirect)
3f80: 29 3b 0a 0a 20 20 20 20 7a 50 4b 20 3d 20 63 6b  );..    zPK = ck
3f90: 61 6c 6c 6f 63 28 6e 43 6f 6c 2b 31 29 3b 0a 20  alloc(nCol+1);. 
3fa0: 20 20 20 6d 65 6d 73 65 74 28 7a 50 4b 2c 20 30     memset(zPK, 0
3fb0: 2c 20 6e 43 6f 6c 2b 31 29 3b 0a 20 20 20 20 73  , nCol+1);.    s
3fc0: 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
3fd0: 70 6b 28 70 49 74 65 72 2c 20 26 61 62 50 4b 2c  pk(pIter, &abPK,
3fe0: 20 26 6e 43 6f 6c 32 29 3b 0a 20 20 20 20 61 73   &nCol2);.    as
3ff0: 73 65 72 74 28 20 6e 43 6f 6c 3d 3d 6e 43 6f 6c  sert( nCol==nCol
4000: 32 20 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30  2 );.    for(i=0
4010: 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a  ; i<nCol; i++){.
4020: 20 20 20 20 20 20 7a 50 4b 5b 69 5d 20 3d 20 28        zPK[i] = (
4030: 61 62 50 4b 5b 69 5d 20 3f 20 27 58 27 20 3a 20  abPK[i] ? 'X' : 
4040: 27 2e 27 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  '.');.    }.    
4050: 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e  Tcl_ListObjAppen
4060: 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 56 61 72  dElement(0, pVar
4070: 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  , Tcl_NewStringO
4080: 62 6a 28 7a 50 4b 2c 20 2d 31 29 29 3b 0a 20 20  bj(zPK, -1));.  
4090: 20 20 63 6b 66 72 65 65 28 7a 50 4b 29 3b 0a 0a    ckfree(zPK);..
40a0: 20 20 20 20 70 4f 6c 64 20 3d 20 54 63 6c 5f 4e      pOld = Tcl_N
40b0: 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20 69 66 28  ewObj();.    if(
40c0: 20 6f 70 21 3d 53 51 4c 49 54 45 5f 49 4e 53 45   op!=SQLITE_INSE
40d0: 52 54 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  RT ){.      int 
40e0: 69 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30  i;.      for(i=0
40f0: 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a  ; i<nCol; i++){.
4100: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f          sqlite3_
4110: 76 61 6c 75 65 20 2a 70 56 61 6c 3b 0a 20 20 20  value *pVal;.   
4120: 20 20 20 20 20 73 71 6c 69 74 65 33 63 68 61 6e       sqlite3chan
4130: 67 65 73 65 74 5f 6f 6c 64 28 70 49 74 65 72 2c  geset_old(pIter,
4140: 20 69 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20 20   i, &pVal);.    
4150: 20 20 20 20 74 65 73 74 5f 61 70 70 65 6e 64 5f      test_append_
4160: 76 61 6c 75 65 28 70 4f 6c 64 2c 20 70 56 61 6c  value(pOld, pVal
4170: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
4180: 0a 20 20 20 20 70 4e 65 77 20 3d 20 54 63 6c 5f  .    pNew = Tcl_
4190: 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20 69 66  NewObj();.    if
41a0: 28 20 6f 70 21 3d 53 51 4c 49 54 45 5f 44 45 4c  ( op!=SQLITE_DEL
41b0: 45 54 45 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  ETE ){.      int
41c0: 20 69 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d   i;.      for(i=
41d0: 30 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b  0; i<nCol; i++){
41e0: 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
41f0: 5f 76 61 6c 75 65 20 2a 70 56 61 6c 3b 0a 20 20  _value *pVal;.  
4200: 20 20 20 20 20 20 73 71 6c 69 74 65 33 63 68 61        sqlite3cha
4210: 6e 67 65 73 65 74 5f 6e 65 77 28 70 49 74 65 72  ngeset_new(pIter
4220: 2c 20 69 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20  , i, &pVal);.   
4230: 20 20 20 20 20 74 65 73 74 5f 61 70 70 65 6e 64       test_append
4240: 5f 76 61 6c 75 65 28 70 4e 65 77 2c 20 70 56 61  _value(pNew, pVa
4250: 6c 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  l);.      }.    
4260: 7d 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62  }.    Tcl_ListOb
4270: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30  jAppendElement(0
4280: 2c 20 70 56 61 72 2c 20 70 4f 6c 64 29 3b 0a 20  , pVar, pOld);. 
4290: 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70     Tcl_ListObjAp
42a0: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70  pendElement(0, p
42b0: 56 61 72 2c 20 70 4e 65 77 29 3b 0a 0a 20 20 20  Var, pNew);..   
42c0: 20 54 63 6c 5f 4f 62 6a 53 65 74 56 61 72 32 28   Tcl_ObjSetVar2(
42d0: 69 6e 74 65 72 70 2c 20 70 56 61 72 6e 61 6d 65  interp, pVarname
42e0: 2c 20 30 2c 20 70 56 61 72 2c 20 30 29 3b 0a 20  , 0, pVar, 0);. 
42f0: 20 20 20 72 63 20 3d 20 54 63 6c 5f 45 76 61 6c     rc = Tcl_Eval
4300: 4f 62 6a 45 78 28 69 6e 74 65 72 70 2c 20 70 53  ObjEx(interp, pS
4310: 63 72 69 70 74 2c 20 30 29 3b 0a 20 20 20 20 69  cript, 0);.    i
4320: 66 28 20 72 63 21 3d 54 43 4c 5f 4f 4b 20 26 26  f( rc!=TCL_OK &&
4330: 20 72 63 21 3d 54 43 4c 5f 43 4f 4e 54 49 4e 55   rc!=TCL_CONTINU
4340: 45 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  E ){.      sqlit
4350: 65 33 63 68 61 6e 67 65 73 65 74 5f 66 69 6e 61  e3changeset_fina
4360: 6c 69 7a 65 28 70 49 74 65 72 29 3b 0a 20 20 20  lize(pIter);.   
4370: 20 20 20 72 65 74 75 72 6e 20 72 63 3d 3d 54 43     return rc==TC
4380: 4c 5f 42 52 45 41 4b 20 3f 20 54 43 4c 5f 4f 4b  L_BREAK ? TCL_OK
4390: 20 3a 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d   : rc;.    }.  }
43a0: 0a 0a 20 20 69 66 28 20 69 73 43 68 65 63 6b 4e  ..  if( isCheckN
43b0: 65 78 74 20 29 7b 0a 20 20 20 20 69 6e 74 20 72  ext ){.    int r
43c0: 63 32 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e  c2 = sqlite3chan
43d0: 67 65 73 65 74 5f 6e 65 78 74 28 70 49 74 65 72  geset_next(pIter
43e0: 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  );.    rc = sqli
43f0: 74 65 33 63 68 61 6e 67 65 73 65 74 5f 66 69 6e  te3changeset_fin
4400: 61 6c 69 7a 65 28 70 49 74 65 72 29 3b 0a 20 20  alize(pIter);.  
4410: 20 20 61 73 73 65 72 74 28 20 28 72 63 32 3d 3d    assert( (rc2==
4420: 53 51 4c 49 54 45 5f 44 4f 4e 45 20 26 26 20 72  SQLITE_DONE && r
4430: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 29 20 7c 7c  c==SQLITE_OK) ||
4440: 20 72 63 32 3d 3d 72 63 20 29 3b 0a 20 20 7d 65   rc2==rc );.  }e
4450: 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 73 71  lse{.    rc = sq
4460: 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 66  lite3changeset_f
4470: 69 6e 61 6c 69 7a 65 28 70 49 74 65 72 29 3b 0a  inalize(pIter);.
4480: 20 20 7d 0a 20 20 69 66 28 20 72 63 21 3d 53 51    }.  if( rc!=SQ
4490: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
44a0: 65 74 75 72 6e 20 74 65 73 74 5f 73 65 73 73 69  eturn test_sessi
44b0: 6f 6e 5f 65 72 72 6f 72 28 69 6e 74 65 72 70 2c  on_error(interp,
44c0: 20 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74   rc);.  }..  ret
44d0: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 69  urn TCL_OK;.}..i
44e0: 6e 74 20 54 65 73 74 53 65 73 73 69 6f 6e 5f 49  nt TestSession_I
44f0: 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a  nit(Tcl_Interp *
4500: 69 6e 74 65 72 70 29 7b 0a 20 20 54 63 6c 5f 43  interp){.  Tcl_C
4510: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
4520: 69 6e 74 65 72 70 2c 20 22 73 71 6c 69 74 65 33  interp, "sqlite3
4530: 73 65 73 73 69 6f 6e 22 2c 20 74 65 73 74 5f 73  session", test_s
4540: 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 2c 20 30  qlite3session, 0
4550: 2c 20 30 29 3b 0a 20 20 54 63 6c 5f 43 72 65 61  , 0);.  Tcl_Crea
4560: 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 0a 20 20  teObjCommand(.  
4570: 20 20 20 20 69 6e 74 65 72 70 2c 20 22 73 71 6c      interp, "sql
4580: 69 74 65 33 73 65 73 73 69 6f 6e 5f 66 6f 72 65  ite3session_fore
4590: 61 63 68 22 2c 20 74 65 73 74 5f 73 71 6c 69 74  ach", test_sqlit
45a0: 65 33 73 65 73 73 69 6f 6e 5f 66 6f 72 65 61 63  e3session_foreac
45b0: 68 2c 20 30 2c 20 30 0a 20 20 29 3b 0a 20 20 54  h, 0, 0.  );.  T
45c0: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
45d0: 61 6e 64 28 0a 20 20 20 20 20 20 69 6e 74 65 72  and(.      inter
45e0: 70 2c 20 22 73 71 6c 69 74 65 33 63 68 61 6e 67  p, "sqlite3chang
45f0: 65 73 65 74 5f 69 6e 76 65 72 74 22 2c 20 74 65  eset_invert", te
4600: 73 74 5f 73 71 6c 69 74 65 33 63 68 61 6e 67 65  st_sqlite3change
4610: 73 65 74 5f 69 6e 76 65 72 74 2c 20 30 2c 20 30  set_invert, 0, 0
4620: 0a 20 20 29 3b 0a 20 20 54 63 6c 5f 43 72 65 61  .  );.  Tcl_Crea
4630: 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 0a 20 20  teObjCommand(.  
4640: 20 20 20 20 69 6e 74 65 72 70 2c 20 22 73 71 6c      interp, "sql
4650: 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 63 6f  ite3changeset_co
4660: 6e 63 61 74 22 2c 20 74 65 73 74 5f 73 71 6c 69  ncat", test_sqli
4670: 74 65 33 63 68 61 6e 67 65 73 65 74 5f 63 6f 6e  te3changeset_con
4680: 63 61 74 2c 20 30 2c 20 30 0a 20 20 29 3b 0a 20  cat, 0, 0.  );. 
4690: 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f   Tcl_CreateObjCo
46a0: 6d 6d 61 6e 64 28 0a 20 20 20 20 20 20 69 6e 74  mmand(.      int
46b0: 65 72 70 2c 20 22 73 71 6c 69 74 65 33 63 68 61  erp, "sqlite3cha
46c0: 6e 67 65 73 65 74 5f 61 70 70 6c 79 22 2c 20 74  ngeset_apply", t
46d0: 65 73 74 5f 73 71 6c 69 74 65 33 63 68 61 6e 67  est_sqlite3chang
46e0: 65 73 65 74 5f 61 70 70 6c 79 2c 20 30 2c 20 30  eset_apply, 0, 0
46f0: 0a 20 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 54  .  );.  return T
4700: 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64 69 66  CL_OK;.}..#endif
4710: 20 2f 2a 20 53 51 4c 49 54 45 5f 54 45 53 54 20   /* SQLITE_TEST 
4720: 26 26 20 53 51 4c 49 54 45 5f 53 45 53 53 49 4f  && SQLITE_SESSIO
4730: 4e 20 26 26 20 53 51 4c 49 54 45 5f 50 52 45 55  N && SQLITE_PREU
4740: 50 44 41 54 45 5f 48 4f 4f 4b 20 2a 2f 0a        PDATE_HOOK */.