/ Hex Artifact Content
Login

Artifact eb0bd6c1ea791c1d66ee4ef94c16500dad936386:


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 66  e <string.h>.#if
00b0: 20 64 65 66 69 6e 65 64 28 49 4e 43 4c 55 44 45   defined(INCLUDE
00c0: 5f 53 51 4c 49 54 45 5f 54 43 4c 5f 48 29 0a 23  _SQLITE_TCL_H).#
00d0: 20 20 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74    include "sqlit
00e0: 65 5f 74 63 6c 2e 68 22 0a 23 65 6c 73 65 0a 23  e_tcl.h".#else.#
00f0: 20 20 69 6e 63 6c 75 64 65 20 22 74 63 6c 2e 68    include "tcl.h
0100: 22 0a 23 20 20 69 66 6e 64 65 66 20 53 51 4c 49  ".#  ifndef SQLI
0110: 54 45 5f 54 43 4c 41 50 49 0a 23 20 20 20 20 64  TE_TCLAPI.#    d
0120: 65 66 69 6e 65 20 53 51 4c 49 54 45 5f 54 43 4c  efine SQLITE_TCL
0130: 41 50 49 0a 23 20 20 65 6e 64 69 66 0a 23 65 6e  API.#  endif.#en
0140: 64 69 66 0a 0a 74 79 70 65 64 65 66 20 73 74 72  dif..typedef str
0150: 75 63 74 20 54 65 73 74 53 65 73 73 69 6f 6e 20  uct TestSession 
0160: 54 65 73 74 53 65 73 73 69 6f 6e 3b 0a 73 74 72  TestSession;.str
0170: 75 63 74 20 54 65 73 74 53 65 73 73 69 6f 6e 20  uct TestSession 
0180: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 65 73 73  {.  sqlite3_sess
0190: 69 6f 6e 20 2a 70 53 65 73 73 69 6f 6e 3b 0a 20  ion *pSession;. 
01a0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
01b0: 65 72 70 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a  erp;.  Tcl_Obj *
01c0: 70 46 69 6c 74 65 72 53 63 72 69 70 74 3b 0a 7d  pFilterScript;.}
01d0: 3b 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  ;..typedef struc
01e0: 74 20 54 65 73 74 53 74 72 65 61 6d 49 6e 70 75  t TestStreamInpu
01f0: 74 20 54 65 73 74 53 74 72 65 61 6d 49 6e 70 75  t TestStreamInpu
0200: 74 3b 0a 73 74 72 75 63 74 20 54 65 73 74 53 74  t;.struct TestSt
0210: 72 65 61 6d 49 6e 70 75 74 20 7b 0a 20 20 69 6e  reamInput {.  in
0220: 74 20 6e 53 74 72 65 61 6d 3b 20 20 20 20 20 20  t nStream;      
0230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0240: 20 4d 61 78 69 6d 75 6d 20 63 68 75 6e 6b 20 73   Maximum chunk s
0250: 69 7a 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ize */.  unsigne
0260: 64 20 63 68 61 72 20 2a 61 44 61 74 61 3b 20 20  d char *aData;  
0270: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
0280: 74 65 72 20 74 6f 20 62 75 66 66 65 72 20 63 6f  ter to buffer co
0290: 6e 74 61 69 6e 69 6e 67 20 64 61 74 61 20 2a 2f  ntaining data */
02a0: 0a 20 20 69 6e 74 20 6e 44 61 74 61 3b 20 20 20  .  int nData;   
02b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
02c0: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 62 75     /* Size of bu
02d0: 66 66 65 72 20 61 44 61 74 61 20 69 6e 20 62 79  ffer aData in by
02e0: 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20 69 44 61  tes */.  int iDa
02f0: 74 61 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ta;             
0300: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65           /* Byte
0310: 73 20 6f 66 20 64 61 74 61 20 61 6c 72 65 61 64  s of data alread
0320: 79 20 72 65 61 64 20 62 79 20 73 65 73 73 69 6f  y read by sessio
0330: 6e 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  ns */.};../*.** 
0340: 45 78 74 72 61 63 74 20 61 6e 20 73 71 6c 69 74  Extract an sqlit
0350: 65 33 2a 20 64 62 20 68 61 6e 64 6c 65 20 66 72  e3* db handle fr
0360: 6f 6d 20 74 68 65 20 6f 62 6a 65 63 74 20 70 61  om the object pa
0370: 73 73 65 64 20 61 73 20 74 68 65 20 73 65 63 6f  ssed as the seco
0380: 6e 64 0a 2a 2a 20 61 72 67 75 6d 65 6e 74 2e 20  nd.** argument. 
0390: 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 73  If successful, s
03a0: 65 74 20 2a 70 44 62 20 74 6f 20 70 6f 69 6e 74  et *pDb to point
03b0: 20 74 6f 20 74 68 65 20 64 62 20 68 61 6e 64 6c   to the db handl
03c0: 65 20 61 6e 64 20 72 65 74 75 72 6e 0a 2a 2a 20  e and return.** 
03d0: 54 43 4c 5f 4f 4b 2e 20 4f 74 68 65 72 77 69 73  TCL_OK. Otherwis
03e0: 65 2c 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52  e, return TCL_ER
03f0: 52 4f 52 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ROR..*/.static i
0400: 6e 74 20 64 62 48 61 6e 64 6c 65 46 72 6f 6d 4f  nt dbHandleFromO
0410: 62 6a 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  bj(Tcl_Interp *i
0420: 6e 74 65 72 70 2c 20 54 63 6c 5f 4f 62 6a 20 2a  nterp, Tcl_Obj *
0430: 70 4f 62 6a 2c 20 73 71 6c 69 74 65 33 20 2a 2a  pObj, sqlite3 **
0440: 70 44 62 29 7b 0a 20 20 54 63 6c 5f 43 6d 64 49  pDb){.  Tcl_CmdI
0450: 6e 66 6f 20 69 6e 66 6f 3b 0a 20 20 69 66 28 20  nfo info;.  if( 
0460: 30 3d 3d 54 63 6c 5f 47 65 74 43 6f 6d 6d 61 6e  0==Tcl_GetComman
0470: 64 49 6e 66 6f 28 69 6e 74 65 72 70 2c 20 54 63  dInfo(interp, Tc
0480: 6c 5f 47 65 74 53 74 72 69 6e 67 28 70 4f 62 6a  l_GetString(pObj
0490: 29 2c 20 26 69 6e 66 6f 29 20 29 7b 0a 20 20 20  ), &info) ){.   
04a0: 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c   Tcl_AppendResul
04b0: 74 28 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75  t(interp, "no su
04c0: 63 68 20 68 61 6e 64 6c 65 3a 20 22 2c 20 54 63  ch handle: ", Tc
04d0: 6c 5f 47 65 74 53 74 72 69 6e 67 28 70 4f 62 6a  l_GetString(pObj
04e0: 29 2c 20 30 29 3b 0a 20 20 20 20 72 65 74 75 72  ), 0);.    retur
04f0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
0500: 0a 0a 20 20 2a 70 44 62 20 3d 20 2a 28 73 71 6c  ..  *pDb = *(sql
0510: 69 74 65 33 20 2a 2a 29 69 6e 66 6f 2e 6f 62 6a  ite3 **)info.obj
0520: 43 6c 69 65 6e 74 44 61 74 61 3b 0a 20 20 72 65  ClientData;.  re
0530: 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a  turn TCL_OK;.}..
0540: 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
0550: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0560: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0570: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0580: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 54 68  **********.** Th
0590: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 6f 64 65  e following code
05a0: 20 69 73 20 63 6f 70 69 65 64 20 62 79 74 65 2d   is copied byte-
05b0: 66 6f 72 2d 62 79 74 65 20 66 72 6f 6d 20 74 68  for-byte from th
05c0: 65 20 73 65 73 73 69 6f 6e 73 20 6d 6f 64 75 6c  e sessions modul
05d0: 65 0a 2a 2a 20 64 6f 63 75 6d 65 6e 74 61 74 69  e.** documentati
05e0: 6f 6e 2e 20 20 49 74 20 69 73 20 75 73 65 64 20  on.  It is used 
05f0: 62 79 20 73 6f 6d 65 20 6f 66 20 74 68 65 20 73  by some of the s
0600: 65 73 73 69 6f 6e 73 20 6d 6f 64 75 6c 65 73 20  essions modules 
0610: 74 65 73 74 73 20 74 6f 0a 2a 2a 20 65 6e 73 75  tests to.** ensu
0620: 72 65 20 74 68 61 74 20 74 68 65 20 65 78 61 6d  re that the exam
0630: 70 6c 65 20 69 6e 20 74 68 65 20 64 6f 63 75 6d  ple in the docum
0640: 65 6e 74 61 74 69 6f 6e 20 64 6f 65 73 20 61 63  entation does ac
0650: 74 75 61 6c 6c 79 20 77 6f 72 6b 2e 0a 2a 2f 20  tually work..*/ 
0660: 0a 2f 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20  ./*.** Argument 
0670: 7a 53 71 6c 20 70 6f 69 6e 74 73 20 74 6f 20 61  zSql points to a
0680: 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69   buffer containi
0690: 6e 67 20 61 6e 20 53 51 4c 20 73 63 72 69 70 74  ng an SQL script
06a0: 20 74 6f 20 65 78 65 63 75 74 65 20 0a 2a 2a 20   to execute .** 
06b0: 61 67 61 69 6e 73 74 20 74 68 65 20 64 61 74 61  against the data
06c0: 62 61 73 65 20 68 61 6e 64 6c 65 20 70 61 73 73  base handle pass
06d0: 65 64 20 61 73 20 74 68 65 20 66 69 72 73 74 20  ed as the first 
06e0: 61 72 67 75 6d 65 6e 74 2e 20 41 73 20 77 65 6c  argument. As wel
06f0: 6c 20 61 73 0a 2a 2a 20 65 78 65 63 75 74 69 6e  l as.** executin
0700: 67 20 74 68 65 20 53 51 4c 20 73 63 72 69 70 74  g the SQL script
0710: 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  , this function 
0720: 63 6f 6c 6c 65 63 74 73 20 61 20 63 68 61 6e 67  collects a chang
0730: 65 73 65 74 20 72 65 63 6f 72 64 69 6e 67 0a 2a  eset recording.*
0740: 2a 20 61 6c 6c 20 63 68 61 6e 67 65 73 20 6d 61  * all changes ma
0750: 64 65 20 74 6f 20 74 68 65 20 22 6d 61 69 6e 22  de to the "main"
0760: 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e 20   database file. 
0770: 41 73 73 75 6d 69 6e 67 20 6e 6f 20 65 72 72 6f  Assuming no erro
0780: 72 20 6f 63 63 75 72 73 2c 0a 2a 2a 20 6f 75 74  r occurs,.** out
0790: 70 75 74 20 76 61 72 69 61 62 6c 65 73 20 28 2a  put variables (*
07a0: 70 70 43 68 61 6e 67 65 73 65 74 29 20 61 6e 64  ppChangeset) and
07b0: 20 28 2a 70 6e 43 68 61 6e 67 65 73 65 74 29 20   (*pnChangeset) 
07c0: 61 72 65 20 73 65 74 20 74 6f 20 70 6f 69 6e 74  are set to point
07d0: 0a 2a 2a 20 74 6f 20 61 20 62 75 66 66 65 72 20  .** to a buffer 
07e0: 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 63  containing the c
07f0: 68 61 6e 67 65 73 65 74 20 61 6e 64 20 74 68 65  hangeset and the
0800: 20 73 69 7a 65 20 6f 66 20 74 68 65 20 63 68 61   size of the cha
0810: 6e 67 65 73 65 74 20 69 6e 0a 2a 2a 20 62 79 74  ngeset in.** byt
0820: 65 73 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e  es before return
0830: 69 6e 67 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 49  ing SQLITE_OK. I
0840: 6e 20 74 68 69 73 20 63 61 73 65 20 69 74 20 69  n this case it i
0850: 73 20 74 68 65 20 72 65 73 70 6f 6e 73 69 62 69  s the responsibi
0860: 6c 69 74 79 0a 2a 2a 20 6f 66 20 74 68 65 20 63  lity.** of the c
0870: 61 6c 6c 65 72 20 74 6f 20 65 76 65 6e 74 75 61  aller to eventua
0880: 6c 6c 79 20 66 72 65 65 20 74 68 65 20 63 68 61  lly free the cha
0890: 6e 67 65 73 65 74 20 62 6c 6f 62 20 62 79 20 70  ngeset blob by p
08a0: 61 73 73 69 6e 67 20 69 74 20 74 6f 0a 2a 2a 20  assing it to.** 
08b0: 74 68 65 20 73 71 6c 69 74 65 33 5f 66 72 65 65  the sqlite3_free
08c0: 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a   function..**.**
08d0: 20 4f 72 2c 20 69 66 20 61 6e 20 65 72 72 6f 72   Or, if an error
08e0: 20 64 6f 65 73 20 6f 63 63 75 72 2c 20 72 65 74   does occur, ret
08f0: 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72  urn an SQLite er
0900: 72 6f 72 20 63 6f 64 65 2e 20 54 68 65 20 66 69  ror code. The fi
0910: 6e 61 6c 0a 2a 2a 20 76 61 6c 75 65 20 6f 66 20  nal.** value of 
0920: 28 2a 70 43 68 61 6e 67 65 73 65 74 29 20 61 6e  (*pChangeset) an
0930: 64 20 28 2a 70 6e 43 68 61 6e 67 65 73 65 74 29  d (*pnChangeset)
0940: 20 61 72 65 20 75 6e 64 65 66 69 6e 65 64 20 69   are undefined i
0950: 6e 20 74 68 69 73 20 63 61 73 65 2e 0a 2a 2f 0a  n this case..*/.
0960: 69 6e 74 20 73 71 6c 5f 65 78 65 63 5f 63 68 61  int sql_exec_cha
0970: 6e 67 65 73 65 74 28 0a 20 20 73 71 6c 69 74 65  ngeset(.  sqlite
0980: 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20  3 *db,          
0990: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
09a0: 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20  ase handle */.  
09b0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 71 6c  const char *zSql
09c0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
09d0: 20 53 51 4c 20 73 63 72 69 70 74 20 74 6f 20 65   SQL script to e
09e0: 78 65 63 75 74 65 20 2a 2f 0a 20 20 69 6e 74 20  xecute */.  int 
09f0: 2a 70 6e 43 68 61 6e 67 65 73 65 74 2c 20 20 20  *pnChangeset,   
0a00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
0a10: 3a 20 53 69 7a 65 20 6f 66 20 63 68 61 6e 67 65  : Size of change
0a20: 73 65 74 20 62 6c 6f 62 20 69 6e 20 62 79 74 65  set blob in byte
0a30: 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 2a 70 70  s */.  void **pp
0a40: 43 68 61 6e 67 65 73 65 74 20 20 20 20 20 20 20  Changeset       
0a50: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 50 6f 69       /* OUT: Poi
0a60: 6e 74 65 72 20 74 6f 20 63 68 61 6e 67 65 73 65  nter to changese
0a70: 74 20 62 6c 6f 62 20 2a 2f 0a 29 7b 0a 20 20 73  t blob */.){.  s
0a80: 71 6c 69 74 65 33 5f 73 65 73 73 69 6f 6e 20 2a  qlite3_session *
0a90: 70 53 65 73 73 69 6f 6e 20 3d 20 30 3b 0a 20 20  pSession = 0;.  
0aa0: 69 6e 74 20 72 63 3b 0a 0a 20 20 2f 2a 20 43 72  int rc;..  /* Cr
0ab0: 65 61 74 65 20 61 20 6e 65 77 20 73 65 73 73 69  eate a new sessi
0ac0: 6f 6e 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 72  on object */.  r
0ad0: 63 20 3d 20 73 71 6c 69 74 65 33 73 65 73 73 69  c = sqlite3sessi
0ae0: 6f 6e 5f 63 72 65 61 74 65 28 64 62 2c 20 22 6d  on_create(db, "m
0af0: 61 69 6e 22 2c 20 26 70 53 65 73 73 69 6f 6e 29  ain", &pSession)
0b00: 3b 0a 0a 20 20 2f 2a 20 43 6f 6e 66 69 67 75 72  ;..  /* Configur
0b10: 65 20 74 68 65 20 73 65 73 73 69 6f 6e 20 6f 62  e the session ob
0b20: 6a 65 63 74 20 74 6f 20 72 65 63 6f 72 64 20 63  ject to record c
0b30: 68 61 6e 67 65 73 20 74 6f 20 61 6c 6c 20 74 61  hanges to all ta
0b40: 62 6c 65 73 20 2a 2f 0a 20 20 69 66 28 20 72 63  bles */.  if( rc
0b50: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63  ==SQLITE_OK ) rc
0b60: 20 3d 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f   = sqlite3sessio
0b70: 6e 5f 61 74 74 61 63 68 28 70 53 65 73 73 69 6f  n_attach(pSessio
0b80: 6e 2c 20 4e 55 4c 4c 29 3b 0a 0a 20 20 2f 2a 20  n, NULL);..  /* 
0b90: 45 78 65 63 75 74 65 20 74 68 65 20 53 51 4c 20  Execute the SQL 
0ba0: 73 63 72 69 70 74 20 2a 2f 0a 20 20 69 66 28 20  script */.  if( 
0bb0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc==SQLITE_OK ) 
0bc0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65  rc = sqlite3_exe
0bd0: 63 28 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30  c(db, zSql, 0, 0
0be0: 2c 20 30 29 3b 0a 0a 20 20 2f 2a 20 43 6f 6c 6c  , 0);..  /* Coll
0bf0: 65 63 74 20 74 68 65 20 63 68 61 6e 67 65 73 65  ect the changese
0c00: 74 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53  t */.  if( rc==S
0c10: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
0c20: 72 63 20 3d 20 73 71 6c 69 74 65 33 73 65 73 73  rc = sqlite3sess
0c30: 69 6f 6e 5f 63 68 61 6e 67 65 73 65 74 28 70 53  ion_changeset(pS
0c40: 65 73 73 69 6f 6e 2c 20 70 6e 43 68 61 6e 67 65  ession, pnChange
0c50: 73 65 74 2c 20 70 70 43 68 61 6e 67 65 73 65 74  set, ppChangeset
0c60: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 65 6c  );.  }..  /* Del
0c70: 65 74 65 20 74 68 65 20 73 65 73 73 69 6f 6e 20  ete the session 
0c80: 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 73 71 6c 69  object */.  sqli
0c90: 74 65 33 73 65 73 73 69 6f 6e 5f 64 65 6c 65 74  te3session_delet
0ca0: 65 28 70 53 65 73 73 69 6f 6e 29 3b 0a 0a 20 20  e(pSession);..  
0cb0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 2f 2a 2a  return rc;.}./**
0cc0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0cd0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0ce0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0cf0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0d00: 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54  ******/../*.** T
0d10: 63 6c 63 6d 64 3a 20 73 71 6c 5f 65 78 65 63 5f  clcmd: sql_exec_
0d20: 63 68 61 6e 67 65 73 65 74 20 44 42 20 53 51 4c  changeset DB SQL
0d30: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 53  .*/.static int S
0d40: 51 4c 49 54 45 5f 54 43 4c 41 50 49 20 74 65 73  QLITE_TCLAPI tes
0d50: 74 5f 73 71 6c 5f 65 78 65 63 5f 63 68 61 6e 67  t_sql_exec_chang
0d60: 65 73 65 74 28 0a 20 20 76 6f 69 64 20 2a 20 63  eset(.  void * c
0d70: 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c  lientData,.  Tcl
0d80: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
0d90: 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54  .  int objc,.  T
0da0: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
0db0: 6a 76 5b 5d 0a 29 7b 0a 20 20 63 6f 6e 73 74 20  jv[].){.  const 
0dc0: 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 73 71  char *zSql;.  sq
0dd0: 6c 69 74 65 33 20 2a 64 62 3b 0a 20 20 76 6f 69  lite3 *db;.  voi
0de0: 64 20 2a 70 43 68 61 6e 67 65 73 65 74 3b 0a 20  d *pChangeset;. 
0df0: 20 69 6e 74 20 6e 43 68 61 6e 67 65 73 65 74 3b   int nChangeset;
0e00: 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 69 66  .  int rc;..  if
0e10: 28 20 6f 62 6a 63 21 3d 33 20 29 7b 0a 20 20 20  ( objc!=3 ){.   
0e20: 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67   Tcl_WrongNumArg
0e30: 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a  s(interp, 1, obj
0e40: 76 2c 20 22 44 42 20 53 51 4c 22 29 3b 0a 20 20  v, "DB SQL");.  
0e50: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
0e60: 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28 20 64 62  OR;.  }.  if( db
0e70: 48 61 6e 64 6c 65 46 72 6f 6d 4f 62 6a 28 69 6e  HandleFromObj(in
0e80: 74 65 72 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26  terp, objv[1], &
0e90: 64 62 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c  db) ) return TCL
0ea0: 5f 45 52 52 4f 52 3b 0a 20 20 7a 53 71 6c 20 3d  _ERROR;.  zSql =
0eb0: 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 54 63   (const char*)Tc
0ec0: 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76  l_GetString(objv
0ed0: 5b 32 5d 29 3b 0a 0a 20 20 72 63 20 3d 20 73 71  [2]);..  rc = sq
0ee0: 6c 5f 65 78 65 63 5f 63 68 61 6e 67 65 73 65 74  l_exec_changeset
0ef0: 28 64 62 2c 20 7a 53 71 6c 2c 20 26 6e 43 68 61  (db, zSql, &nCha
0f00: 6e 67 65 73 65 74 2c 20 26 70 43 68 61 6e 67 65  ngeset, &pChange
0f10: 73 65 74 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  set);.  if( rc!=
0f20: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
0f30: 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74   Tcl_ResetResult
0f40: 28 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 54 63  (interp);.    Tc
0f50: 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69  l_AppendResult(i
0f60: 6e 74 65 72 70 2c 20 22 65 72 72 6f 72 20 69 6e  nterp, "error in
0f70: 20 73 71 6c 5f 65 78 65 63 5f 63 68 61 6e 67 65   sql_exec_change
0f80: 73 65 74 28 29 22 2c 20 30 29 3b 0a 20 20 20 20  set()", 0);.    
0f90: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
0fa0: 3b 0a 20 20 7d 0a 0a 20 20 54 63 6c 5f 53 65 74  ;.  }..  Tcl_Set
0fb0: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
0fc0: 2c 20 54 63 6c 5f 4e 65 77 42 79 74 65 41 72 72  , Tcl_NewByteArr
0fd0: 61 79 4f 62 6a 28 70 43 68 61 6e 67 65 73 65 74  ayObj(pChangeset
0fe0: 2c 20 6e 43 68 61 6e 67 65 73 65 74 29 29 3b 0a  , nChangeset));.
0ff0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
1000: 43 68 61 6e 67 65 73 65 74 29 3b 0a 20 20 72 65  Changeset);.  re
1010: 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a  turn TCL_OK;.}..
1020: 0a 0a 23 64 65 66 69 6e 65 20 53 45 53 53 49 4f  ..#define SESSIO
1030: 4e 5f 53 54 52 45 41 4d 5f 54 43 4c 5f 56 41 52  N_STREAM_TCL_VAR
1040: 20 22 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e   "sqlite3session
1050: 5f 73 74 72 65 61 6d 73 22 0a 0a 2f 2a 0a 2a 2a  _streams"../*.**
1060: 20 41 74 74 65 6d 70 74 20 74 6f 20 66 69 6e 64   Attempt to find
1070: 20 74 68 65 20 67 6c 6f 62 61 6c 20 76 61 72 69   the global vari
1080: 61 62 6c 65 20 7a 56 61 72 20 77 69 74 68 69 6e  able zVar within
1090: 20 69 6e 74 65 72 70 72 65 74 65 72 20 69 6e 74   interpreter int
10a0: 65 72 70 0a 2a 2a 20 61 6e 64 20 65 78 74 72 61  erp.** and extra
10b0: 63 74 20 61 6e 20 69 6e 74 65 67 65 72 20 76 61  ct an integer va
10c0: 6c 75 65 20 66 72 6f 6d 20 69 74 2e 20 52 65 74  lue from it. Ret
10d0: 75 72 6e 20 74 68 69 73 20 76 61 6c 75 65 2e 0a  urn this value..
10e0: 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 6e 61 6d  **.** If the nam
10f0: 65 64 20 76 61 72 69 61 62 6c 65 20 63 61 6e 6e  ed variable cann
1100: 6f 74 20 62 65 20 66 6f 75 6e 64 2c 20 6f 72 20  ot be found, or 
1110: 69 66 20 69 74 20 63 61 6e 6e 6f 74 20 62 65 20  if it cannot be 
1120: 69 6e 74 65 72 70 72 65 74 65 64 0a 2a 2a 20 61  interpreted.** a
1130: 73 20 61 20 69 6e 74 65 67 65 72 2c 20 72 65 74  s a integer, ret
1140: 75 72 6e 20 30 2e 0a 2a 2f 0a 73 74 61 74 69 63  urn 0..*/.static
1150: 20 69 6e 74 20 74 65 73 74 5f 74 63 6c 5f 69 6e   int test_tcl_in
1160: 74 65 67 65 72 28 54 63 6c 5f 49 6e 74 65 72 70  teger(Tcl_Interp
1170: 20 2a 69 6e 74 65 72 70 2c 20 63 6f 6e 73 74 20   *interp, const 
1180: 63 68 61 72 20 2a 7a 56 61 72 29 7b 0a 20 20 54  char *zVar){.  T
1190: 63 6c 5f 4f 62 6a 20 2a 70 4f 62 6a 3b 0a 20 20  cl_Obj *pObj;.  
11a0: 69 6e 74 20 69 56 61 6c 20 3d 20 30 3b 0a 20 20  int iVal = 0;.  
11b0: 70 4f 62 6a 20 3d 20 54 63 6c 5f 4f 62 6a 47 65  pObj = Tcl_ObjGe
11c0: 74 56 61 72 32 28 69 6e 74 65 72 70 2c 20 54 63  tVar2(interp, Tc
11d0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a  l_NewStringObj(z
11e0: 56 61 72 2c 20 2d 31 29 2c 20 30 2c 20 54 43 4c  Var, -1), 0, TCL
11f0: 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a 20  _GLOBAL_ONLY);. 
1200: 20 69 66 28 20 70 4f 62 6a 20 29 20 54 63 6c 5f   if( pObj ) Tcl_
1210: 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 30 2c  GetIntFromObj(0,
1220: 20 70 4f 62 6a 2c 20 26 69 56 61 6c 29 3b 0a 20   pObj, &iVal);. 
1230: 20 72 65 74 75 72 6e 20 69 56 61 6c 3b 0a 7d 0a   return iVal;.}.
1240: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 73 74  .static int test
1250: 5f 73 65 73 73 69 6f 6e 5f 65 72 72 6f 72 28 54  _session_error(T
1260: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
1270: 70 2c 20 69 6e 74 20 72 63 2c 20 63 68 61 72 20  p, int rc, char 
1280: 2a 7a 45 72 72 29 7b 0a 20 20 65 78 74 65 72 6e  *zErr){.  extern
1290: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c   const char *sql
12a0: 69 74 65 33 45 72 72 4e 61 6d 65 28 69 6e 74 29  ite3ErrName(int)
12b0: 3b 0a 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65  ;.  Tcl_SetObjRe
12c0: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c  sult(interp, Tcl
12d0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 73 71  _NewStringObj(sq
12e0: 6c 69 74 65 33 45 72 72 4e 61 6d 65 28 72 63 29  lite3ErrName(rc)
12f0: 2c 20 2d 31 29 29 3b 0a 20 20 69 66 28 20 7a 45  , -1));.  if( zE
1300: 72 72 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70  rr ){.    Tcl_Ap
1310: 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72  pendResult(inter
1320: 70 2c 20 22 20 2d 20 22 2c 20 7a 45 72 72 2c 20  p, " - ", zErr, 
1330: 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  0);.    sqlite3_
1340: 66 72 65 65 28 7a 45 72 72 29 3b 0a 20 20 7d 0a  free(zErr);.  }.
1350: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
1360: 4f 52 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  OR;.}..static in
1370: 74 20 74 65 73 74 5f 74 61 62 6c 65 5f 66 69 6c  t test_table_fil
1380: 74 65 72 28 76 6f 69 64 20 2a 70 43 74 78 2c 20  ter(void *pCtx, 
1390: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 62 6c  const char *zTbl
13a0: 29 7b 0a 20 20 54 65 73 74 53 65 73 73 69 6f 6e  ){.  TestSession
13b0: 20 2a 70 20 3d 20 28 54 65 73 74 53 65 73 73 69   *p = (TestSessi
13c0: 6f 6e 2a 29 70 43 74 78 3b 0a 20 20 54 63 6c 5f  on*)pCtx;.  Tcl_
13d0: 4f 62 6a 20 2a 70 45 76 61 6c 3b 0a 20 20 69 6e  Obj *pEval;.  in
13e0: 74 20 72 63 3b 0a 20 20 69 6e 74 20 62 52 65 73  t rc;.  int bRes
13f0: 20 3d 20 30 3b 0a 0a 20 20 70 45 76 61 6c 20 3d   = 0;..  pEval =
1400: 20 54 63 6c 5f 44 75 70 6c 69 63 61 74 65 4f 62   Tcl_DuplicateOb
1410: 6a 28 70 2d 3e 70 46 69 6c 74 65 72 53 63 72 69  j(p->pFilterScri
1420: 70 74 29 3b 0a 20 20 54 63 6c 5f 49 6e 63 72 52  pt);.  Tcl_IncrR
1430: 65 66 43 6f 75 6e 74 28 70 45 76 61 6c 29 3b 0a  efCount(pEval);.
1440: 20 20 72 63 20 3d 20 54 63 6c 5f 4c 69 73 74 4f    rc = Tcl_ListO
1450: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
1460: 70 2d 3e 69 6e 74 65 72 70 2c 20 70 45 76 61 6c  p->interp, pEval
1470: 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  , Tcl_NewStringO
1480: 62 6a 28 7a 54 62 6c 2c 20 2d 31 29 29 3b 0a 20  bj(zTbl, -1));. 
1490: 20 69 66 28 20 72 63 3d 3d 54 43 4c 5f 4f 4b 20   if( rc==TCL_OK 
14a0: 29 7b 0a 20 20 20 20 72 63 20 3d 20 54 63 6c 5f  ){.    rc = Tcl_
14b0: 45 76 61 6c 4f 62 6a 45 78 28 70 2d 3e 69 6e 74  EvalObjEx(p->int
14c0: 65 72 70 2c 20 70 45 76 61 6c 2c 20 54 43 4c 5f  erp, pEval, TCL_
14d0: 45 56 41 4c 5f 47 4c 4f 42 41 4c 29 3b 0a 20 20  EVAL_GLOBAL);.  
14e0: 7d 0a 20 20 69 66 28 20 72 63 3d 3d 54 43 4c 5f  }.  if( rc==TCL_
14f0: 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 54  OK ){.    rc = T
1500: 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46 72 6f  cl_GetBooleanFro
1510: 6d 4f 62 6a 28 70 2d 3e 69 6e 74 65 72 70 2c 20  mObj(p->interp, 
1520: 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_GetObjResult
1530: 28 70 2d 3e 69 6e 74 65 72 70 29 2c 20 26 62 52  (p->interp), &bR
1540: 65 73 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72  es);.  }.  if( r
1550: 63 21 3d 54 43 4c 5f 4f 4b 20 29 7b 0a 20 20 20  c!=TCL_OK ){.   
1560: 20 2f 2a 20 70 72 69 6e 74 66 28 22 65 72 72 6f   /* printf("erro
1570: 72 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65  r: %s\n", Tcl_Ge
1580: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 70 2d  tStringResult(p-
1590: 3e 69 6e 74 65 72 70 29 29 3b 20 2a 2f 0a 20 20  >interp)); */.  
15a0: 20 20 54 63 6c 5f 42 61 63 6b 67 72 6f 75 6e 64    Tcl_Background
15b0: 45 72 72 6f 72 28 70 2d 3e 69 6e 74 65 72 70 29  Error(p->interp)
15c0: 3b 0a 20 20 7d 0a 20 20 54 63 6c 5f 44 65 63 72  ;.  }.  Tcl_Decr
15d0: 52 65 66 43 6f 75 6e 74 28 70 45 76 61 6c 29 3b  RefCount(pEval);
15e0: 0a 0a 20 20 72 65 74 75 72 6e 20 62 52 65 73 3b  ..  return bRes;
15f0: 0a 7d 0a 0a 73 74 72 75 63 74 20 54 65 73 74 53  .}..struct TestS
1600: 65 73 73 69 6f 6e 73 42 6c 6f 62 20 7b 0a 20 20  essionsBlob {.  
1610: 76 6f 69 64 20 2a 70 3b 0a 20 20 69 6e 74 20 6e  void *p;.  int n
1620: 3b 0a 7d 3b 0a 74 79 70 65 64 65 66 20 73 74 72  ;.};.typedef str
1630: 75 63 74 20 54 65 73 74 53 65 73 73 69 6f 6e 73  uct TestSessions
1640: 42 6c 6f 62 20 54 65 73 74 53 65 73 73 69 6f 6e  Blob TestSession
1650: 73 42 6c 6f 62 3b 0a 0a 73 74 61 74 69 63 20 69  sBlob;..static i
1660: 6e 74 20 74 65 73 74 53 74 72 65 61 6d 4f 75 74  nt testStreamOut
1670: 70 75 74 28 0a 20 20 76 6f 69 64 20 2a 70 43 74  put(.  void *pCt
1680: 78 2c 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20  x,.  const void 
1690: 2a 70 44 61 74 61 2c 0a 20 20 69 6e 74 20 6e 44  *pData,.  int nD
16a0: 61 74 61 0a 29 7b 0a 20 20 54 65 73 74 53 65 73  ata.){.  TestSes
16b0: 73 69 6f 6e 73 42 6c 6f 62 20 2a 70 42 6c 6f 62  sionsBlob *pBlob
16c0: 20 3d 20 28 54 65 73 74 53 65 73 73 69 6f 6e 73   = (TestSessions
16d0: 42 6c 6f 62 2a 29 70 43 74 78 3b 0a 20 20 63 68  Blob*)pCtx;.  ch
16e0: 61 72 20 2a 70 4e 65 77 3b 0a 0a 20 20 61 73 73  ar *pNew;..  ass
16f0: 65 72 74 28 20 6e 44 61 74 61 3e 30 20 29 3b 0a  ert( nData>0 );.
1700: 20 20 70 4e 65 77 20 3d 20 28 63 68 61 72 2a 29    pNew = (char*)
1710: 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63 28  sqlite3_realloc(
1720: 70 42 6c 6f 62 2d 3e 70 2c 20 70 42 6c 6f 62 2d  pBlob->p, pBlob-
1730: 3e 6e 20 2b 20 6e 44 61 74 61 29 3b 0a 20 20 69  >n + nData);.  i
1740: 66 28 20 70 4e 65 77 3d 3d 30 20 29 7b 0a 20 20  f( pNew==0 ){.  
1750: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
1760: 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 70 42 6c  NOMEM;.  }.  pBl
1770: 6f 62 2d 3e 70 20 3d 20 28 76 6f 69 64 2a 29 70  ob->p = (void*)p
1780: 4e 65 77 3b 0a 20 20 6d 65 6d 63 70 79 28 26 70  New;.  memcpy(&p
1790: 4e 65 77 5b 70 42 6c 6f 62 2d 3e 6e 5d 2c 20 70  New[pBlob->n], p
17a0: 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20  Data, nData);.  
17b0: 70 42 6c 6f 62 2d 3e 6e 20 2b 3d 20 6e 44 61 74  pBlob->n += nDat
17c0: 61 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  a;.  return SQLI
17d0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
17e0: 54 63 6c 63 6d 64 3a 20 20 24 73 65 73 73 69 6f  Tclcmd:  $sessio
17f0: 6e 20 61 74 74 61 63 68 20 54 41 42 4c 45 0a 2a  n attach TABLE.*
1800: 2a 20 20 20 20 20 20 20 20 20 20 24 73 65 73 73  *          $sess
1810: 69 6f 6e 20 63 68 61 6e 67 65 73 65 74 0a 2a 2a  ion changeset.**
1820: 20 20 20 20 20 20 20 20 20 20 24 73 65 73 73 69            $sessi
1830: 6f 6e 20 64 65 6c 65 74 65 0a 2a 2a 20 20 20 20  on delete.**    
1840: 20 20 20 20 20 20 24 73 65 73 73 69 6f 6e 20 65        $session e
1850: 6e 61 62 6c 65 20 42 4f 4f 4c 0a 2a 2a 20 20 20  nable BOOL.**   
1860: 20 20 20 20 20 20 20 24 73 65 73 73 69 6f 6e 20         $session 
1870: 69 6e 64 69 72 65 63 74 20 49 4e 54 45 47 45 52  indirect INTEGER
1880: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 24 73 65  .**          $se
1890: 73 73 69 6f 6e 20 70 61 74 63 68 73 65 74 0a 2a  ssion patchset.*
18a0: 2a 20 20 20 20 20 20 20 20 20 20 24 73 65 73 73  *          $sess
18b0: 69 6f 6e 20 74 61 62 6c 65 5f 66 69 6c 74 65 72  ion table_filter
18c0: 20 53 43 52 49 50 54 0a 2a 2f 0a 73 74 61 74 69   SCRIPT.*/.stati
18d0: 63 20 69 6e 74 20 53 51 4c 49 54 45 5f 54 43 4c  c int SQLITE_TCL
18e0: 41 50 49 20 74 65 73 74 5f 73 65 73 73 69 6f 6e  API test_session
18f0: 5f 63 6d 64 28 0a 20 20 76 6f 69 64 20 2a 63 6c  _cmd(.  void *cl
1900: 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f  ientData,.  Tcl_
1910: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a  Interp *interp,.
1920: 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63    int objc,.  Tc
1930: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
1940: 76 5b 5d 0a 29 7b 0a 20 20 54 65 73 74 53 65 73  v[].){.  TestSes
1950: 73 69 6f 6e 20 2a 70 20 3d 20 28 54 65 73 74 53  sion *p = (TestS
1960: 65 73 73 69 6f 6e 2a 29 63 6c 69 65 6e 74 44 61  ession*)clientDa
1970: 74 61 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 65  ta;.  sqlite3_se
1980: 73 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f 6e 20  ssion *pSession 
1990: 3d 20 70 2d 3e 70 53 65 73 73 69 6f 6e 3b 0a 20  = p->pSession;. 
19a0: 20 73 74 72 75 63 74 20 53 65 73 73 69 6f 6e 53   struct SessionS
19b0: 75 62 63 6d 64 20 7b 0a 20 20 20 20 63 6f 6e 73  ubcmd {.    cons
19c0: 74 20 63 68 61 72 20 2a 7a 53 75 62 3b 0a 20 20  t char *zSub;.  
19d0: 20 20 69 6e 74 20 6e 41 72 67 3b 0a 20 20 20 20    int nArg;.    
19e0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4d 73 67  const char *zMsg
19f0: 3b 0a 20 20 20 20 69 6e 74 20 69 53 75 62 3b 0a  ;.    int iSub;.
1a00: 20 20 7d 20 61 53 75 62 5b 5d 20 3d 20 7b 0a 20    } aSub[] = {. 
1a10: 20 20 20 7b 20 22 61 74 74 61 63 68 22 2c 20 20     { "attach",  
1a20: 20 20 20 20 20 31 2c 20 22 54 41 42 4c 45 22 2c       1, "TABLE",
1a30: 20 20 20 20 20 20 7d 2c 20 2f 2a 20 30 20 2a 2f        }, /* 0 */
1a40: 0a 20 20 20 20 7b 20 22 63 68 61 6e 67 65 73 65  .    { "changese
1a50: 74 22 2c 20 20 20 20 30 2c 20 22 22 2c 20 20 20  t",    0, "",   
1a60: 20 20 20 20 20 20 20 20 7d 2c 20 2f 2a 20 31 20          }, /* 1 
1a70: 2a 2f 0a 20 20 20 20 7b 20 22 64 65 6c 65 74 65  */.    { "delete
1a80: 22 2c 20 20 20 20 20 20 20 30 2c 20 22 22 2c 20  ",       0, "", 
1a90: 20 20 20 20 20 20 20 20 20 20 7d 2c 20 2f 2a 20            }, /* 
1aa0: 32 20 2a 2f 0a 20 20 20 20 7b 20 22 65 6e 61 62  2 */.    { "enab
1ab0: 6c 65 22 2c 20 20 20 20 20 20 20 31 2c 20 22 42  le",       1, "B
1ac0: 4f 4f 4c 22 2c 20 20 20 20 20 20 20 7d 2c 20 2f  OOL",       }, /
1ad0: 2a 20 33 20 2a 2f 0a 20 20 20 20 7b 20 22 69 6e  * 3 */.    { "in
1ae0: 64 69 72 65 63 74 22 2c 20 20 20 20 20 31 2c 20  direct",     1, 
1af0: 22 42 4f 4f 4c 22 2c 20 20 20 20 20 20 20 7d 2c  "BOOL",       },
1b00: 20 2f 2a 20 34 20 2a 2f 0a 20 20 20 20 7b 20 22   /* 4 */.    { "
1b10: 69 73 65 6d 70 74 79 22 2c 20 20 20 20 20 20 30  isempty",      0
1b20: 2c 20 22 22 2c 20 20 20 20 20 20 20 20 20 20 20  , "",           
1b30: 7d 2c 20 2f 2a 20 35 20 2a 2f 0a 20 20 20 20 7b  }, /* 5 */.    {
1b40: 20 22 74 61 62 6c 65 5f 66 69 6c 74 65 72 22 2c   "table_filter",
1b50: 20 31 2c 20 22 53 43 52 49 50 54 22 2c 20 20 20   1, "SCRIPT",   
1b60: 20 20 7d 2c 20 2f 2a 20 36 20 2a 2f 0a 20 20 20    }, /* 6 */.   
1b70: 20 7b 20 22 70 61 74 63 68 73 65 74 22 2c 20 20   { "patchset",  
1b80: 20 20 20 30 2c 20 22 22 2c 20 20 20 20 20 20 20     0, "",       
1b90: 20 20 20 20 7d 2c 20 2f 2a 20 37 20 2a 2f 0a 20      }, /* 7 */. 
1ba0: 20 20 20 7b 20 22 64 69 66 66 22 2c 20 20 20 20     { "diff",    
1bb0: 20 20 20 20 20 32 2c 20 22 46 52 4f 4d 44 42 20       2, "FROMDB 
1bc0: 54 42 4c 22 2c 20 7d 2c 20 2f 2a 20 38 20 2a 2f  TBL", }, /* 8 */
1bd0: 0a 20 20 20 20 7b 20 30 20 7d 0a 20 20 7d 3b 0a  .    { 0 }.  };.
1be0: 20 20 69 6e 74 20 69 53 75 62 3b 0a 20 20 69 6e    int iSub;.  in
1bf0: 74 20 72 63 3b 0a 0a 20 20 69 66 28 20 6f 62 6a  t rc;..  if( obj
1c00: 63 3c 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57  c<2 ){.    Tcl_W
1c10: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
1c20: 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 53 55  rp, 1, objv, "SU
1c30: 42 43 4f 4d 4d 41 4e 44 20 2e 2e 2e 22 29 3b 0a  BCOMMAND ...");.
1c40: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
1c50: 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 72 63 20 3d  RROR;.  }.  rc =
1c60: 20 54 63 6c 5f 47 65 74 49 6e 64 65 78 46 72 6f   Tcl_GetIndexFro
1c70: 6d 4f 62 6a 53 74 72 75 63 74 28 69 6e 74 65 72  mObjStruct(inter
1c80: 70 2c 20 0a 20 20 20 20 20 20 6f 62 6a 76 5b 31  p, .      objv[1
1c90: 5d 2c 20 61 53 75 62 2c 20 73 69 7a 65 6f 66 28  ], aSub, sizeof(
1ca0: 61 53 75 62 5b 30 5d 29 2c 20 22 73 75 62 2d 63  aSub[0]), "sub-c
1cb0: 6f 6d 6d 61 6e 64 22 2c 20 30 2c 20 26 69 53 75  ommand", 0, &iSu
1cc0: 62 0a 20 20 29 3b 0a 20 20 69 66 28 20 72 63 21  b.  );.  if( rc!
1cd0: 3d 54 43 4c 5f 4f 4b 20 29 20 72 65 74 75 72 6e  =TCL_OK ) return
1ce0: 20 72 63 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21   rc;.  if( objc!
1cf0: 3d 32 2b 61 53 75 62 5b 69 53 75 62 5d 2e 6e 41  =2+aSub[iSub].nA
1d00: 72 67 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72  rg ){.    Tcl_Wr
1d10: 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72  ongNumArgs(inter
1d20: 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 61 53 75 62  p, 2, objv, aSub
1d30: 5b 69 53 75 62 5d 2e 7a 4d 73 67 29 3b 0a 20 20  [iSub].zMsg);.  
1d40: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
1d50: 4f 52 3b 0a 20 20 7d 0a 0a 20 20 73 77 69 74 63  OR;.  }..  switc
1d60: 68 28 20 69 53 75 62 20 29 7b 0a 20 20 20 20 63  h( iSub ){.    c
1d70: 61 73 65 20 30 3a 20 7b 20 20 20 20 20 20 2f 2a  ase 0: {      /*
1d80: 20 61 74 74 61 63 68 20 2a 2f 0a 20 20 20 20 20   attach */.     
1d90: 20 63 68 61 72 20 2a 7a 41 72 67 20 3d 20 54 63   char *zArg = Tc
1da0: 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76  l_GetString(objv
1db0: 5b 32 5d 29 3b 0a 20 20 20 20 20 20 69 66 28 20  [2]);.      if( 
1dc0: 7a 41 72 67 5b 30 5d 3d 3d 27 2a 27 20 26 26 20  zArg[0]=='*' && 
1dd0: 7a 41 72 67 5b 31 5d 3d 3d 27 5c 30 27 20 29 20  zArg[1]=='\0' ) 
1de0: 7a 41 72 67 20 3d 20 30 3b 0a 20 20 20 20 20 20  zArg = 0;.      
1df0: 72 63 20 3d 20 73 71 6c 69 74 65 33 73 65 73 73  rc = sqlite3sess
1e00: 69 6f 6e 5f 61 74 74 61 63 68 28 70 53 65 73 73  ion_attach(pSess
1e10: 69 6f 6e 2c 20 7a 41 72 67 29 3b 0a 20 20 20 20  ion, zArg);.    
1e20: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
1e30: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72  _OK ){.        r
1e40: 65 74 75 72 6e 20 74 65 73 74 5f 73 65 73 73 69  eturn test_sessi
1e50: 6f 6e 5f 65 72 72 6f 72 28 69 6e 74 65 72 70 2c  on_error(interp,
1e60: 20 72 63 2c 20 30 29 3b 0a 20 20 20 20 20 20 7d   rc, 0);.      }
1e70: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
1e80: 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 37 3a    }..    case 7:
1e90: 20 20 20 20 20 20 20 20 2f 2a 20 70 61 74 63 68          /* patch
1ea0: 73 65 74 20 2a 2f 0a 20 20 20 20 63 61 73 65 20  set */.    case 
1eb0: 31 3a 20 7b 20 20 20 20 20 20 2f 2a 20 63 68 61  1: {      /* cha
1ec0: 6e 67 65 73 65 74 20 2a 2f 0a 20 20 20 20 20 20  ngeset */.      
1ed0: 54 65 73 74 53 65 73 73 69 6f 6e 73 42 6c 6f 62  TestSessionsBlob
1ee0: 20 6f 20 3d 20 7b 30 2c 20 30 7d 3b 0a 20 20 20   o = {0, 0};.   
1ef0: 20 20 20 69 66 28 20 74 65 73 74 5f 74 63 6c 5f     if( test_tcl_
1f00: 69 6e 74 65 67 65 72 28 69 6e 74 65 72 70 2c 20  integer(interp, 
1f10: 53 45 53 53 49 4f 4e 5f 53 54 52 45 41 4d 5f 54  SESSION_STREAM_T
1f20: 43 4c 5f 56 41 52 29 20 29 7b 0a 20 20 20 20 20  CL_VAR) ){.     
1f30: 20 20 20 76 6f 69 64 20 2a 70 43 74 78 20 3d 20     void *pCtx = 
1f40: 28 76 6f 69 64 2a 29 26 6f 3b 0a 20 20 20 20 20  (void*)&o;.     
1f50: 20 20 20 69 66 28 20 69 53 75 62 3d 3d 37 20 29     if( iSub==7 )
1f60: 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d  {.          rc =
1f70: 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f   sqlite3session_
1f80: 70 61 74 63 68 73 65 74 5f 73 74 72 6d 28 70 53  patchset_strm(pS
1f90: 65 73 73 69 6f 6e 2c 20 74 65 73 74 53 74 72 65  ession, testStre
1fa0: 61 6d 4f 75 74 70 75 74 2c 20 70 43 74 78 29 3b  amOutput, pCtx);
1fb0: 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  .        }else{.
1fc0: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 73            rc = s
1fd0: 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 63 68  qlite3session_ch
1fe0: 61 6e 67 65 73 65 74 5f 73 74 72 6d 28 70 53 65  angeset_strm(pSe
1ff0: 73 73 69 6f 6e 2c 20 74 65 73 74 53 74 72 65 61  ssion, testStrea
2000: 6d 4f 75 74 70 75 74 2c 20 70 43 74 78 29 3b 0a  mOutput, pCtx);.
2010: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
2020: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69  }else{.        i
2030: 66 28 20 69 53 75 62 3d 3d 37 20 29 7b 0a 20 20  f( iSub==7 ){.  
2040: 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c          rc = sql
2050: 69 74 65 33 73 65 73 73 69 6f 6e 5f 70 61 74 63  ite3session_patc
2060: 68 73 65 74 28 70 53 65 73 73 69 6f 6e 2c 20 26  hset(pSession, &
2070: 6f 2e 6e 2c 20 26 6f 2e 70 29 3b 0a 20 20 20 20  o.n, &o.p);.    
2080: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
2090: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
20a0: 33 73 65 73 73 69 6f 6e 5f 63 68 61 6e 67 65 73  3session_changes
20b0: 65 74 28 70 53 65 73 73 69 6f 6e 2c 20 26 6f 2e  et(pSession, &o.
20c0: 6e 2c 20 26 6f 2e 70 29 3b 0a 20 20 20 20 20 20  n, &o.p);.      
20d0: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
20e0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
20f0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 54  _OK ){.        T
2100: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
2110: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 42  interp, Tcl_NewB
2120: 79 74 65 41 72 72 61 79 4f 62 6a 28 6f 2e 70 2c  yteArrayObj(o.p,
2130: 20 6f 2e 6e 29 29 3b 20 0a 20 20 20 20 20 20 7d   o.n)); .      }
2140: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66  .      sqlite3_f
2150: 72 65 65 28 6f 2e 70 29 3b 0a 20 20 20 20 20 20  ree(o.p);.      
2160: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
2170: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74  K ){.        ret
2180: 75 72 6e 20 74 65 73 74 5f 73 65 73 73 69 6f 6e  urn test_session
2190: 5f 65 72 72 6f 72 28 69 6e 74 65 72 70 2c 20 72  _error(interp, r
21a0: 63 2c 20 30 29 3b 0a 20 20 20 20 20 20 7d 0a 20  c, 0);.      }. 
21b0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
21c0: 7d 0a 0a 20 20 20 20 63 61 73 65 20 32 3a 20 20  }..    case 2:  
21d0: 20 20 20 20 20 20 2f 2a 20 64 65 6c 65 74 65 20        /* delete 
21e0: 2a 2f 0a 20 20 20 20 20 20 54 63 6c 5f 44 65 6c  */.      Tcl_Del
21f0: 65 74 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  eteCommand(inter
2200: 70 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  p, Tcl_GetString
2210: 28 6f 62 6a 76 5b 30 5d 29 29 3b 0a 20 20 20 20  (objv[0]));.    
2220: 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61    break;..    ca
2230: 73 65 20 33 3a 20 7b 20 20 20 20 20 20 2f 2a 20  se 3: {      /* 
2240: 65 6e 61 62 6c 65 20 2a 2f 0a 20 20 20 20 20 20  enable */.      
2250: 69 6e 74 20 76 61 6c 3b 0a 20 20 20 20 20 20 69  int val;.      i
2260: 66 28 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f  f( Tcl_GetIntFro
2270: 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a  mObj(interp, obj
2280: 76 5b 32 5d 2c 20 26 76 61 6c 29 20 29 20 72 65  v[2], &val) ) re
2290: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
22a0: 20 20 20 20 20 20 76 61 6c 20 3d 20 73 71 6c 69        val = sqli
22b0: 74 65 33 73 65 73 73 69 6f 6e 5f 65 6e 61 62 6c  te3session_enabl
22c0: 65 28 70 53 65 73 73 69 6f 6e 2c 20 76 61 6c 29  e(pSession, val)
22d0: 3b 0a 20 20 20 20 20 20 54 63 6c 5f 53 65 74 4f  ;.      Tcl_SetO
22e0: 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  bjResult(interp,
22f0: 20 54 63 6c 5f 4e 65 77 42 6f 6f 6c 65 61 6e 4f   Tcl_NewBooleanO
2300: 62 6a 28 76 61 6c 29 29 3b 0a 20 20 20 20 20 20  bj(val));.      
2310: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
2320: 20 20 63 61 73 65 20 34 3a 20 7b 20 20 20 20 20    case 4: {     
2330: 20 2f 2a 20 69 6e 64 69 72 65 63 74 20 2a 2f 0a   /* indirect */.
2340: 20 20 20 20 20 20 69 6e 74 20 76 61 6c 3b 0a 20        int val;. 
2350: 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74       if( Tcl_Get
2360: 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72  IntFromObj(inter
2370: 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 76 61 6c  p, objv[2], &val
2380: 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f 45  ) ) return TCL_E
2390: 52 52 4f 52 3b 0a 20 20 20 20 20 20 76 61 6c 20  RROR;.      val 
23a0: 3d 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e  = sqlite3session
23b0: 5f 69 6e 64 69 72 65 63 74 28 70 53 65 73 73 69  _indirect(pSessi
23c0: 6f 6e 2c 20 76 61 6c 29 3b 0a 20 20 20 20 20 20  on, val);.      
23d0: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
23e0: 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77  (interp, Tcl_New
23f0: 42 6f 6f 6c 65 61 6e 4f 62 6a 28 76 61 6c 29 29  BooleanObj(val))
2400: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
2410: 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 35     }..    case 5
2420: 3a 20 7b 20 20 20 20 20 20 2f 2a 20 69 73 65 6d  : {      /* isem
2430: 70 74 79 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74  pty */.      int
2440: 20 76 61 6c 3b 0a 20 20 20 20 20 20 76 61 6c 20   val;.      val 
2450: 3d 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e  = sqlite3session
2460: 5f 69 73 65 6d 70 74 79 28 70 53 65 73 73 69 6f  _isempty(pSessio
2470: 6e 29 3b 0a 20 20 20 20 20 20 54 63 6c 5f 53 65  n);.      Tcl_Se
2480: 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72  tObjResult(inter
2490: 70 2c 20 54 63 6c 5f 4e 65 77 42 6f 6f 6c 65 61  p, Tcl_NewBoolea
24a0: 6e 4f 62 6a 28 76 61 6c 29 29 3b 0a 20 20 20 20  nObj(val));.    
24b0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20    break;.    }. 
24c0: 20 20 20 20 20 20 20 20 20 20 20 0a 20 20 20 20             .    
24d0: 63 61 73 65 20 36 3a 20 7b 20 20 20 20 20 20 2f  case 6: {      /
24e0: 2a 20 74 61 62 6c 65 5f 66 69 6c 74 65 72 20 2a  * table_filter *
24f0: 2f 0a 20 20 20 20 20 20 69 66 28 20 70 2d 3e 70  /.      if( p->p
2500: 46 69 6c 74 65 72 53 63 72 69 70 74 20 29 20 54  FilterScript ) T
2510: 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28  cl_DecrRefCount(
2520: 70 2d 3e 70 46 69 6c 74 65 72 53 63 72 69 70 74  p->pFilterScript
2530: 29 3b 0a 20 20 20 20 20 20 70 2d 3e 69 6e 74 65  );.      p->inte
2540: 72 70 20 3d 20 69 6e 74 65 72 70 3b 0a 20 20 20  rp = interp;.   
2550: 20 20 20 70 2d 3e 70 46 69 6c 74 65 72 53 63 72     p->pFilterScr
2560: 69 70 74 20 3d 20 54 63 6c 5f 44 75 70 6c 69 63  ipt = Tcl_Duplic
2570: 61 74 65 4f 62 6a 28 6f 62 6a 76 5b 32 5d 29 3b  ateObj(objv[2]);
2580: 0a 20 20 20 20 20 20 54 63 6c 5f 49 6e 63 72 52  .      Tcl_IncrR
2590: 65 66 43 6f 75 6e 74 28 70 2d 3e 70 46 69 6c 74  efCount(p->pFilt
25a0: 65 72 53 63 72 69 70 74 29 3b 0a 20 20 20 20 20  erScript);.     
25b0: 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f   sqlite3session_
25c0: 74 61 62 6c 65 5f 66 69 6c 74 65 72 28 70 53 65  table_filter(pSe
25d0: 73 73 69 6f 6e 2c 20 74 65 73 74 5f 74 61 62 6c  ssion, test_tabl
25e0: 65 5f 66 69 6c 74 65 72 2c 20 63 6c 69 65 6e 74  e_filter, client
25f0: 44 61 74 61 29 3b 0a 20 20 20 20 20 20 62 72 65  Data);.      bre
2600: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
2610: 61 73 65 20 38 3a 20 7b 20 20 20 20 20 20 2f 2a  ase 8: {      /*
2620: 20 64 69 66 66 20 2a 2f 0a 20 20 20 20 20 20 63   diff */.      c
2630: 68 61 72 20 2a 7a 45 72 72 20 3d 20 30 3b 0a 20  har *zErr = 0;. 
2640: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
2650: 33 73 65 73 73 69 6f 6e 5f 64 69 66 66 28 70 53  3session_diff(pS
2660: 65 73 73 69 6f 6e 2c 20 0a 20 20 20 20 20 20 20  ession, .       
2670: 20 20 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67     Tcl_GetString
2680: 28 6f 62 6a 76 5b 32 5d 29 2c 0a 20 20 20 20 20  (objv[2]),.     
2690: 20 20 20 20 20 54 63 6c 5f 47 65 74 53 74 72 69       Tcl_GetStri
26a0: 6e 67 28 6f 62 6a 76 5b 33 5d 29 2c 0a 20 20 20  ng(objv[3]),.   
26b0: 20 20 20 20 20 20 20 26 7a 45 72 72 0a 20 20 20         &zErr.   
26c0: 20 20 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65     );.      asse
26d0: 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  rt( rc!=SQLITE_O
26e0: 4b 20 7c 7c 20 7a 45 72 72 3d 3d 30 20 29 3b 0a  K || zErr==0 );.
26f0: 20 20 20 20 20 20 69 66 28 20 72 63 20 29 7b 0a        if( rc ){.
2700: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 74          return t
2710: 65 73 74 5f 73 65 73 73 69 6f 6e 5f 65 72 72 6f  est_session_erro
2720: 72 28 69 6e 74 65 72 70 2c 20 72 63 2c 20 7a 45  r(interp, rc, zE
2730: 72 72 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  rr);.      }.   
2740: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
2750: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 54 43    }..  return TC
2760: 4c 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  L_OK;.}..static 
2770: 76 6f 69 64 20 53 51 4c 49 54 45 5f 54 43 4c 41  void SQLITE_TCLA
2780: 50 49 20 74 65 73 74 5f 73 65 73 73 69 6f 6e 5f  PI test_session_
2790: 64 65 6c 28 76 6f 69 64 20 2a 63 6c 69 65 6e 74  del(void *client
27a0: 44 61 74 61 29 7b 0a 20 20 54 65 73 74 53 65 73  Data){.  TestSes
27b0: 73 69 6f 6e 20 2a 70 20 3d 20 28 54 65 73 74 53  sion *p = (TestS
27c0: 65 73 73 69 6f 6e 2a 29 63 6c 69 65 6e 74 44 61  ession*)clientDa
27d0: 74 61 3b 0a 20 20 69 66 28 20 70 2d 3e 70 46 69  ta;.  if( p->pFi
27e0: 6c 74 65 72 53 63 72 69 70 74 20 29 20 54 63 6c  lterScript ) Tcl
27f0: 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 70 2d  _DecrRefCount(p-
2800: 3e 70 46 69 6c 74 65 72 53 63 72 69 70 74 29 3b  >pFilterScript);
2810: 0a 20 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f  .  sqlite3sessio
2820: 6e 5f 64 65 6c 65 74 65 28 70 2d 3e 70 53 65 73  n_delete(p->pSes
2830: 73 69 6f 6e 29 3b 0a 20 20 63 6b 66 72 65 65 28  sion);.  ckfree(
2840: 28 63 68 61 72 2a 29 70 29 3b 0a 7d 0a 0a 2f 2a  (char*)p);.}../*
2850: 0a 2a 2a 20 54 63 6c 63 6d 64 3a 20 20 73 71 6c  .** Tclcmd:  sql
2860: 69 74 65 33 73 65 73 73 69 6f 6e 20 43 4d 44 20  ite3session CMD 
2870: 44 42 2d 48 41 4e 44 4c 45 20 44 42 2d 4e 41 4d  DB-HANDLE DB-NAM
2880: 45 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  E.*/.static int 
2890: 53 51 4c 49 54 45 5f 54 43 4c 41 50 49 20 74 65  SQLITE_TCLAPI te
28a0: 73 74 5f 73 71 6c 69 74 65 33 73 65 73 73 69 6f  st_sqlite3sessio
28b0: 6e 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65  n(.  void * clie
28c0: 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e  ntData,.  Tcl_In
28d0: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20  terp *interp,.  
28e0: 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f  int objc,.  Tcl_
28f0: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
2900: 5d 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a  ].){.  sqlite3 *
2910: 64 62 3b 0a 20 20 54 63 6c 5f 43 6d 64 49 6e 66  db;.  Tcl_CmdInf
2920: 6f 20 69 6e 66 6f 3b 0a 20 20 69 6e 74 20 72 63  o info;.  int rc
2930: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
2940: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73 71 6c            /* sql
2950: 69 74 65 33 73 65 73 73 69 6f 6e 5f 63 72 65 61  ite3session_crea
2960: 74 65 28 29 20 72 65 74 75 72 6e 20 63 6f 64 65  te() return code
2970: 20 2a 2f 0a 20 20 54 65 73 74 53 65 73 73 69 6f   */.  TestSessio
2980: 6e 20 2a 70 3b 20 20 20 20 20 20 20 20 20 20 20  n *p;           
2990: 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 77 72 61        /* New wra
29a0: 70 70 65 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 0a  pper object */..
29b0: 20 20 69 66 28 20 6f 62 6a 63 21 3d 34 20 29 7b    if( objc!=4 ){
29c0: 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75  .    Tcl_WrongNu
29d0: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
29e0: 20 6f 62 6a 76 2c 20 22 43 4d 44 20 44 42 2d 48   objv, "CMD DB-H
29f0: 41 4e 44 4c 45 20 44 42 2d 4e 41 4d 45 22 29 3b  ANDLE DB-NAME");
2a00: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
2a10: 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69 66  ERROR;.  }..  if
2a20: 28 20 30 3d 3d 54 63 6c 5f 47 65 74 43 6f 6d 6d  ( 0==Tcl_GetComm
2a30: 61 6e 64 49 6e 66 6f 28 69 6e 74 65 72 70 2c 20  andInfo(interp, 
2a40: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62  Tcl_GetString(ob
2a50: 6a 76 5b 32 5d 29 2c 20 26 69 6e 66 6f 29 20 29  jv[2]), &info) )
2a60: 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64  {.    Tcl_Append
2a70: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22  Result(interp, "
2a80: 6e 6f 20 73 75 63 68 20 68 61 6e 64 6c 65 3a 20  no such handle: 
2a90: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
2aa0: 28 6f 62 6a 76 5b 32 5d 29 2c 20 30 29 3b 0a 20  (objv[2]), 0);. 
2ab0: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
2ac0: 52 4f 52 3b 0a 20 20 7d 0a 20 20 64 62 20 3d 20  ROR;.  }.  db = 
2ad0: 2a 28 73 71 6c 69 74 65 33 20 2a 2a 29 69 6e 66  *(sqlite3 **)inf
2ae0: 6f 2e 6f 62 6a 43 6c 69 65 6e 74 44 61 74 61 3b  o.objClientData;
2af0: 0a 0a 20 20 70 20 3d 20 28 54 65 73 74 53 65 73  ..  p = (TestSes
2b00: 73 69 6f 6e 2a 29 63 6b 61 6c 6c 6f 63 28 73 69  sion*)ckalloc(si
2b10: 7a 65 6f 66 28 54 65 73 74 53 65 73 73 69 6f 6e  zeof(TestSession
2b20: 29 29 3b 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20  ));.  memset(p, 
2b30: 30 2c 20 73 69 7a 65 6f 66 28 54 65 73 74 53 65  0, sizeof(TestSe
2b40: 73 73 69 6f 6e 29 29 3b 0a 20 20 72 63 20 3d 20  ssion));.  rc = 
2b50: 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 63  sqlite3session_c
2b60: 72 65 61 74 65 28 64 62 2c 20 54 63 6c 5f 47 65  reate(db, Tcl_Ge
2b70: 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 33 5d 29  tString(objv[3])
2b80: 2c 20 26 70 2d 3e 70 53 65 73 73 69 6f 6e 29 3b  , &p->pSession);
2b90: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
2ba0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 63 6b 66 72  E_OK ){.    ckfr
2bb0: 65 65 28 28 63 68 61 72 2a 29 70 29 3b 0a 20 20  ee((char*)p);.  
2bc0: 20 20 72 65 74 75 72 6e 20 74 65 73 74 5f 73 65    return test_se
2bd0: 73 73 69 6f 6e 5f 65 72 72 6f 72 28 69 6e 74 65  ssion_error(inte
2be0: 72 70 2c 20 72 63 2c 20 30 29 3b 0a 20 20 7d 0a  rp, rc, 0);.  }.
2bf0: 0a 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a  .  Tcl_CreateObj
2c00: 43 6f 6d 6d 61 6e 64 28 0a 20 20 20 20 20 20 69  Command(.      i
2c10: 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 53 74  nterp, Tcl_GetSt
2c20: 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c 20 74  ring(objv[1]), t
2c30: 65 73 74 5f 73 65 73 73 69 6f 6e 5f 63 6d 64 2c  est_session_cmd,
2c40: 20 28 43 6c 69 65 6e 74 44 61 74 61 29 70 2c 0a   (ClientData)p,.
2c50: 20 20 20 20 20 20 74 65 73 74 5f 73 65 73 73 69        test_sessi
2c60: 6f 6e 5f 64 65 6c 0a 20 20 29 3b 0a 20 20 54 63  on_del.  );.  Tc
2c70: 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69  l_SetObjResult(i
2c80: 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 31 5d 29 3b  nterp, objv[1]);
2c90: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
2ca0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
2cb0: 20 74 65 73 74 5f 61 70 70 65 6e 64 5f 76 61 6c   test_append_val
2cc0: 75 65 28 54 63 6c 5f 4f 62 6a 20 2a 70 4c 69 73  ue(Tcl_Obj *pLis
2cd0: 74 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  t, sqlite3_value
2ce0: 20 2a 70 56 61 6c 29 7b 0a 20 20 69 66 28 20 70   *pVal){.  if( p
2cf0: 56 61 6c 3d 3d 30 20 29 7b 0a 20 20 20 20 54 63  Val==0 ){.    Tc
2d00: 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45  l_ListObjAppendE
2d10: 6c 65 6d 65 6e 74 28 30 2c 20 70 4c 69 73 74 2c  lement(0, pList,
2d20: 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 29 3b 0a   Tcl_NewObj());.
2d30: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
2d40: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20  ppendElement(0, 
2d50: 70 4c 69 73 74 2c 20 54 63 6c 5f 4e 65 77 4f 62  pList, Tcl_NewOb
2d60: 6a 28 29 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  j());.  }else{. 
2d70: 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 4f 62 6a     Tcl_Obj *pObj
2d80: 3b 0a 20 20 20 20 73 77 69 74 63 68 28 20 73 71  ;.    switch( sq
2d90: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65  lite3_value_type
2da0: 28 70 56 61 6c 29 20 29 7b 0a 20 20 20 20 20 20  (pVal) ){.      
2db0: 63 61 73 65 20 53 51 4c 49 54 45 5f 4e 55 4c 4c  case SQLITE_NULL
2dc0: 3a 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4c 69  :.        Tcl_Li
2dd0: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
2de0: 6e 74 28 30 2c 20 70 4c 69 73 74 2c 20 54 63 6c  nt(0, pList, Tcl
2df0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 6e  _NewStringObj("n
2e00: 22 2c 20 31 29 29 3b 0a 20 20 20 20 20 20 20 20  ", 1));.        
2e10: 70 4f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77 4f 62  pObj = Tcl_NewOb
2e20: 6a 28 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65  j();.        bre
2e30: 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 53  ak;.      case S
2e40: 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 3a 0a 20  QLITE_INTEGER:. 
2e50: 20 20 20 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f         Tcl_ListO
2e60: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
2e70: 30 2c 20 70 4c 69 73 74 2c 20 54 63 6c 5f 4e 65  0, pList, Tcl_Ne
2e80: 77 53 74 72 69 6e 67 4f 62 6a 28 22 69 22 2c 20  wStringObj("i", 
2e90: 31 29 29 3b 0a 20 20 20 20 20 20 20 20 70 4f 62  1));.        pOb
2ea0: 6a 20 3d 20 54 63 6c 5f 4e 65 77 57 69 64 65 49  j = Tcl_NewWideI
2eb0: 6e 74 4f 62 6a 28 73 71 6c 69 74 65 33 5f 76 61  ntObj(sqlite3_va
2ec0: 6c 75 65 5f 69 6e 74 36 34 28 70 56 61 6c 29 29  lue_int64(pVal))
2ed0: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
2ee0: 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
2ef0: 54 45 5f 46 4c 4f 41 54 3a 0a 20 20 20 20 20 20  TE_FLOAT:.      
2f00: 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70    Tcl_ListObjApp
2f10: 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 4c  endElement(0, pL
2f20: 69 73 74 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69  ist, Tcl_NewStri
2f30: 6e 67 4f 62 6a 28 22 66 22 2c 20 31 29 29 3b 0a  ngObj("f", 1));.
2f40: 20 20 20 20 20 20 20 20 70 4f 62 6a 20 3d 20 54          pObj = T
2f50: 63 6c 5f 4e 65 77 44 6f 75 62 6c 65 4f 62 6a 28  cl_NewDoubleObj(
2f60: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 64 6f  sqlite3_value_do
2f70: 75 62 6c 65 28 70 56 61 6c 29 29 3b 0a 20 20 20  uble(pVal));.   
2f80: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
2f90: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 54 45    case SQLITE_TE
2fa0: 58 54 3a 20 7b 0a 20 20 20 20 20 20 20 20 63 6f  XT: {.        co
2fb0: 6e 73 74 20 63 68 61 72 20 2a 7a 20 3d 20 28 63  nst char *z = (c
2fc0: 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c  har*)sqlite3_val
2fd0: 75 65 5f 62 6c 6f 62 28 70 56 61 6c 29 3b 0a 20  ue_blob(pVal);. 
2fe0: 20 20 20 20 20 20 20 69 6e 74 20 6e 20 3d 20 73         int n = s
2ff0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 79 74  qlite3_value_byt
3000: 65 73 28 70 56 61 6c 29 3b 0a 20 20 20 20 20 20  es(pVal);.      
3010: 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70    Tcl_ListObjApp
3020: 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 4c  endElement(0, pL
3030: 69 73 74 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69  ist, Tcl_NewStri
3040: 6e 67 4f 62 6a 28 22 74 22 2c 20 31 29 29 3b 0a  ngObj("t", 1));.
3050: 20 20 20 20 20 20 20 20 70 4f 62 6a 20 3d 20 54          pObj = T
3060: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
3070: 7a 2c 20 6e 29 3b 0a 20 20 20 20 20 20 20 20 62  z, n);.        b
3080: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  reak;.      }.  
3090: 20 20 20 20 64 65 66 61 75 6c 74 3a 0a 20 20 20      default:.   
30a0: 20 20 20 20 20 61 73 73 65 72 74 28 20 73 71 6c       assert( sql
30b0: 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
30c0: 70 56 61 6c 29 3d 3d 53 51 4c 49 54 45 5f 42 4c  pVal)==SQLITE_BL
30d0: 4f 42 20 29 3b 0a 20 20 20 20 20 20 20 20 54 63  OB );.        Tc
30e0: 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45  l_ListObjAppendE
30f0: 6c 65 6d 65 6e 74 28 30 2c 20 70 4c 69 73 74 2c  lement(0, pList,
3100: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
3110: 6a 28 22 62 22 2c 20 31 29 29 3b 0a 20 20 20 20  j("b", 1));.    
3120: 20 20 20 20 70 4f 62 6a 20 3d 20 54 63 6c 5f 4e      pObj = Tcl_N
3130: 65 77 42 79 74 65 41 72 72 61 79 4f 62 6a 28 0a  ewByteArrayObj(.
3140: 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69              sqli
3150: 74 65 33 5f 76 61 6c 75 65 5f 62 6c 6f 62 28 70  te3_value_blob(p
3160: 56 61 6c 29 2c 0a 20 20 20 20 20 20 20 20 20 20  Val),.          
3170: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f    sqlite3_value_
3180: 62 79 74 65 73 28 70 56 61 6c 29 0a 20 20 20 20  bytes(pVal).    
3190: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 62      );.        b
31a0: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20  reak;.    }.    
31b0: 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e  Tcl_ListObjAppen
31c0: 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 4c 69 73  dElement(0, pLis
31d0: 74 2c 20 70 4f 62 6a 29 3b 0a 20 20 7d 0a 7d 0a  t, pObj);.  }.}.
31e0: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
31f0: 54 65 73 74 43 6f 6e 66 6c 69 63 74 48 61 6e 64  TestConflictHand
3200: 6c 65 72 20 54 65 73 74 43 6f 6e 66 6c 69 63 74  ler TestConflict
3210: 48 61 6e 64 6c 65 72 3b 0a 73 74 72 75 63 74 20  Handler;.struct 
3220: 54 65 73 74 43 6f 6e 66 6c 69 63 74 48 61 6e 64  TestConflictHand
3230: 6c 65 72 20 7b 0a 20 20 54 63 6c 5f 49 6e 74 65  ler {.  Tcl_Inte
3240: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 20 20 54 63  rp *interp;.  Tc
3250: 6c 5f 4f 62 6a 20 2a 70 43 6f 6e 66 6c 69 63 74  l_Obj *pConflict
3260: 53 63 72 69 70 74 3b 0a 20 20 54 63 6c 5f 4f 62  Script;.  Tcl_Ob
3270: 6a 20 2a 70 46 69 6c 74 65 72 53 63 72 69 70 74  j *pFilterScript
3280: 3b 0a 7d 3b 0a 0a 73 74 61 74 69 63 20 69 6e 74  ;.};..static int
3290: 20 74 65 73 74 5f 6f 62 6a 5f 65 71 5f 73 74 72   test_obj_eq_str
32a0: 69 6e 67 28 54 63 6c 5f 4f 62 6a 20 2a 70 2c 20  ing(Tcl_Obj *p, 
32b0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 29 7b 0a  const char *z){.
32c0: 20 20 69 6e 74 20 6e 3b 0a 20 20 69 6e 74 20 6e    int n;.  int n
32d0: 4f 62 6a 3b 0a 20 20 63 68 61 72 20 2a 7a 4f 62  Obj;.  char *zOb
32e0: 6a 3b 0a 0a 20 20 6e 20 3d 20 28 69 6e 74 29 73  j;..  n = (int)s
32f0: 74 72 6c 65 6e 28 7a 29 3b 0a 20 20 7a 4f 62 6a  trlen(z);.  zObj
3300: 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67   = Tcl_GetString
3310: 46 72 6f 6d 4f 62 6a 28 70 2c 20 26 6e 4f 62 6a  FromObj(p, &nObj
3320: 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 28 6e 4f  );..  return (nO
3330: 62 6a 3d 3d 6e 20 26 26 20 28 6e 3d 3d 30 20 7c  bj==n && (n==0 |
3340: 7c 20 30 3d 3d 6d 65 6d 63 6d 70 28 7a 4f 62 6a  | 0==memcmp(zObj
3350: 2c 20 7a 2c 20 6e 29 29 29 3b 0a 7d 0a 0a 73 74  , z, n)));.}..st
3360: 61 74 69 63 20 69 6e 74 20 74 65 73 74 5f 66 69  atic int test_fi
3370: 6c 74 65 72 5f 68 61 6e 64 6c 65 72 28 0a 20 20  lter_handler(.  
3380: 76 6f 69 64 20 2a 70 43 74 78 2c 20 20 20 20 20  void *pCtx,     
3390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
33a0: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 54 65  /* Pointer to Te
33b0: 73 74 43 6f 6e 66 6c 69 63 74 48 61 6e 64 6c 65  stConflictHandle
33c0: 72 20 73 74 72 75 63 74 75 72 65 20 2a 2f 0a 20  r structure */. 
33d0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61   const char *zTa
33e0: 62 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b               
33f0: 20 2f 2a 20 54 61 62 6c 65 20 6e 61 6d 65 20 2a   /* Table name *
3400: 2f 0a 29 7b 0a 20 20 54 65 73 74 43 6f 6e 66 6c  /.){.  TestConfl
3410: 69 63 74 48 61 6e 64 6c 65 72 20 2a 70 20 3d 20  ictHandler *p = 
3420: 28 54 65 73 74 43 6f 6e 66 6c 69 63 74 48 61 6e  (TestConflictHan
3430: 64 6c 65 72 20 2a 29 70 43 74 78 3b 0a 20 20 69  dler *)pCtx;.  i
3440: 6e 74 20 72 65 73 20 3d 20 31 3b 0a 20 20 54 63  nt res = 1;.  Tc
3450: 6c 5f 4f 62 6a 20 2a 70 45 76 61 6c 3b 0a 20 20  l_Obj *pEval;.  
3460: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
3470: 72 70 20 3d 20 70 2d 3e 69 6e 74 65 72 70 3b 0a  rp = p->interp;.
3480: 0a 20 20 70 45 76 61 6c 20 3d 20 54 63 6c 5f 44  .  pEval = Tcl_D
3490: 75 70 6c 69 63 61 74 65 4f 62 6a 28 70 2d 3e 70  uplicateObj(p->p
34a0: 46 69 6c 74 65 72 53 63 72 69 70 74 29 3b 0a 20  FilterScript);. 
34b0: 20 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e   Tcl_IncrRefCoun
34c0: 74 28 70 45 76 61 6c 29 3b 0a 0a 20 20 69 66 28  t(pEval);..  if(
34d0: 20 54 43 4c 5f 4f 4b 21 3d 54 63 6c 5f 4c 69 73   TCL_OK!=Tcl_Lis
34e0: 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e  tObjAppendElemen
34f0: 74 28 30 2c 20 70 45 76 61 6c 2c 20 54 63 6c 5f  t(0, pEval, Tcl_
3500: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 54 61  NewStringObj(zTa
3510: 62 2c 20 2d 31 29 29 0a 20 20 20 7c 7c 20 54 43  b, -1)).   || TC
3520: 4c 5f 4f 4b 21 3d 54 63 6c 5f 45 76 61 6c 4f 62  L_OK!=Tcl_EvalOb
3530: 6a 45 78 28 69 6e 74 65 72 70 2c 20 70 45 76 61  jEx(interp, pEva
3540: 6c 2c 20 54 43 4c 5f 45 56 41 4c 5f 47 4c 4f 42  l, TCL_EVAL_GLOB
3550: 41 4c 29 20 0a 20 20 20 7c 7c 20 54 43 4c 5f 4f  AL) .   || TCL_O
3560: 4b 21 3d 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f  K!=Tcl_GetIntFro
3570: 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 54 63 6c  mObj(interp, Tcl
3580: 5f 47 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e  _GetObjResult(in
3590: 74 65 72 70 29 2c 20 26 72 65 73 29 0a 20 20 29  terp), &res).  )
35a0: 7b 0a 20 20 20 20 54 63 6c 5f 42 61 63 6b 67 72  {.    Tcl_Backgr
35b0: 6f 75 6e 64 45 72 72 6f 72 28 69 6e 74 65 72 70  oundError(interp
35c0: 29 3b 0a 20 20 7d 0a 0a 20 20 54 63 6c 5f 44 65  );.  }..  Tcl_De
35d0: 63 72 52 65 66 43 6f 75 6e 74 28 70 45 76 61 6c  crRefCount(pEval
35e0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 65 73 3b  );.  return res;
35f0: 0a 7d 20 20 0a 0a 73 74 61 74 69 63 20 69 6e 74  .}  ..static int
3600: 20 74 65 73 74 5f 63 6f 6e 66 6c 69 63 74 5f 68   test_conflict_h
3610: 61 6e 64 6c 65 72 28 0a 20 20 76 6f 69 64 20 2a  andler(.  void *
3620: 70 43 74 78 2c 20 20 20 20 20 20 20 20 20 20 20  pCtx,           
3630: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
3640: 6e 74 65 72 20 74 6f 20 54 65 73 74 43 6f 6e 66  nter to TestConf
3650: 6c 69 63 74 48 61 6e 64 6c 65 72 20 73 74 72 75  lictHandler stru
3660: 63 74 75 72 65 20 2a 2f 0a 20 20 69 6e 74 20 65  cture */.  int e
3670: 43 6f 6e 66 2c 20 20 20 20 20 20 20 20 20 20 20  Conf,           
3680: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 41             /* DA
3690: 54 41 2c 20 4d 49 53 53 49 4e 47 2c 20 43 4f 4e  TA, MISSING, CON
36a0: 46 4c 49 43 54 2c 20 43 4f 4e 53 54 52 41 49 4e  FLICT, CONSTRAIN
36b0: 54 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 63  T */.  sqlite3_c
36c0: 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a 70  hangeset_iter *p
36d0: 49 74 65 72 20 20 20 2f 2a 20 48 61 6e 64 6c 65  Iter   /* Handle
36e0: 20 64 65 73 63 72 69 62 69 6e 67 20 63 68 61 6e   describing chan
36f0: 67 65 20 61 6e 64 20 63 6f 6e 66 6c 69 63 74 20  ge and conflict 
3700: 2a 2f 0a 29 7b 0a 20 20 54 65 73 74 43 6f 6e 66  */.){.  TestConf
3710: 6c 69 63 74 48 61 6e 64 6c 65 72 20 2a 70 20 3d  lictHandler *p =
3720: 20 28 54 65 73 74 43 6f 6e 66 6c 69 63 74 48 61   (TestConflictHa
3730: 6e 64 6c 65 72 20 2a 29 70 43 74 78 3b 0a 20 20  ndler *)pCtx;.  
3740: 54 63 6c 5f 4f 62 6a 20 2a 70 45 76 61 6c 3b 0a  Tcl_Obj *pEval;.
3750: 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e    Tcl_Interp *in
3760: 74 65 72 70 20 3d 20 70 2d 3e 69 6e 74 65 72 70  terp = p->interp
3770: 3b 0a 20 20 69 6e 74 20 72 65 74 20 3d 20 30 3b  ;.  int ret = 0;
3780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3790: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 76 61      /* Return va
37a0: 6c 75 65 20 2a 2f 0a 0a 20 20 69 6e 74 20 6f 70  lue */..  int op
37b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
37c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 51 4c            /* SQL
37d0: 49 54 45 5f 55 50 44 41 54 45 2c 20 44 45 4c 45  ITE_UPDATE, DELE
37e0: 54 45 20 6f 72 20 49 4e 53 45 52 54 20 2a 2f 0a  TE or INSERT */.
37f0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54    const char *zT
3800: 61 62 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ab;             
3810: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 61 62    /* Name of tab
3820: 6c 65 20 63 6f 6e 66 6c 69 63 74 20 69 73 20 6f  le conflict is o
3830: 6e 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 3b  n */.  int nCol;
3840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3850: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
3860: 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74   of columns in t
3870: 61 62 6c 65 20 7a 54 61 62 20 2a 2f 0a 0a 20 20  able zTab */..  
3880: 70 45 76 61 6c 20 3d 20 54 63 6c 5f 44 75 70 6c  pEval = Tcl_Dupl
3890: 69 63 61 74 65 4f 62 6a 28 70 2d 3e 70 43 6f 6e  icateObj(p->pCon
38a0: 66 6c 69 63 74 53 63 72 69 70 74 29 3b 0a 20 20  flictScript);.  
38b0: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74  Tcl_IncrRefCount
38c0: 28 70 45 76 61 6c 29 3b 0a 0a 20 20 73 71 6c 69  (pEval);..  sqli
38d0: 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f 70 28  te3changeset_op(
38e0: 70 49 74 65 72 2c 20 26 7a 54 61 62 2c 20 26 6e  pIter, &zTab, &n
38f0: 43 6f 6c 2c 20 26 6f 70 2c 20 30 29 3b 0a 0a 20  Col, &op, 0);.. 
3900: 20 69 66 28 20 65 43 6f 6e 66 3d 3d 53 51 4c 49   if( eConf==SQLI
3910: 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 46 4f 52  TE_CHANGESET_FOR
3920: 45 49 47 4e 5f 4b 45 59 20 29 7b 0a 20 20 20 20  EIGN_KEY ){.    
3930: 69 6e 74 20 6e 46 6b 3b 0a 20 20 20 20 73 71 6c  int nFk;.    sql
3940: 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 66 6b  ite3changeset_fk
3950: 5f 63 6f 6e 66 6c 69 63 74 73 28 70 49 74 65 72  _conflicts(pIter
3960: 2c 20 26 6e 46 6b 29 3b 0a 20 20 20 20 54 63 6c  , &nFk);.    Tcl
3970: 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c  _ListObjAppendEl
3980: 65 6d 65 6e 74 28 30 2c 20 70 45 76 61 6c 2c 20  ement(0, pEval, 
3990: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
39a0: 28 22 46 4f 52 45 49 47 4e 5f 4b 45 59 22 2c 20  ("FOREIGN_KEY", 
39b0: 2d 31 29 29 3b 0a 20 20 20 20 54 63 6c 5f 4c 69  -1));.    Tcl_Li
39c0: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
39d0: 6e 74 28 30 2c 20 70 45 76 61 6c 2c 20 54 63 6c  nt(0, pEval, Tcl
39e0: 5f 4e 65 77 49 6e 74 4f 62 6a 28 6e 46 6b 29 29  _NewIntObj(nFk))
39f0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 0a 20 20 20 20  ;.  }else{..    
3a00: 2f 2a 20 41 70 70 65 6e 64 20 74 68 65 20 6f 70  /* Append the op
3a10: 65 72 61 74 69 6f 6e 20 74 79 70 65 2e 20 2a 2f  eration type. */
3a20: 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  .    Tcl_ListObj
3a30: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c  AppendElement(0,
3a40: 20 70 45 76 61 6c 2c 20 54 63 6c 5f 4e 65 77 53   pEval, Tcl_NewS
3a50: 74 72 69 6e 67 4f 62 6a 28 0a 20 20 20 20 20 20  tringObj(.      
3a60: 20 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 53    op==SQLITE_INS
3a70: 45 52 54 20 3f 20 22 49 4e 53 45 52 54 22 20 3a  ERT ? "INSERT" :
3a80: 0a 20 20 20 20 20 20 20 20 6f 70 3d 3d 53 51 4c  .        op==SQL
3a90: 49 54 45 5f 55 50 44 41 54 45 20 3f 20 22 55 50  ITE_UPDATE ? "UP
3aa0: 44 41 54 45 22 20 3a 20 0a 20 20 20 20 20 20 20  DATE" : .       
3ab0: 20 22 44 45 4c 45 54 45 22 2c 20 2d 31 0a 20 20   "DELETE", -1.  
3ac0: 20 20 29 29 3b 0a 20 20 0a 20 20 20 20 2f 2a 20    ));.  .    /* 
3ad0: 41 70 70 65 6e 64 20 74 68 65 20 74 61 62 6c 65  Append the table
3ae0: 20 6e 61 6d 65 2e 20 2a 2f 0a 20 20 20 20 54 63   name. */.    Tc
3af0: 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45  l_ListObjAppendE
3b00: 6c 65 6d 65 6e 74 28 30 2c 20 70 45 76 61 6c 2c  lement(0, pEval,
3b10: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
3b20: 6a 28 7a 54 61 62 2c 20 2d 31 29 29 3b 0a 20 20  j(zTab, -1));.  
3b30: 0a 20 20 20 20 2f 2a 20 41 70 70 65 6e 64 20 74  .    /* Append t
3b40: 68 65 20 63 6f 6e 66 6c 69 63 74 20 74 79 70 65  he conflict type
3b50: 2e 20 2a 2f 0a 20 20 20 20 73 77 69 74 63 68 28  . */.    switch(
3b60: 20 65 43 6f 6e 66 20 29 7b 0a 20 20 20 20 20 20   eConf ){.      
3b70: 63 61 73 65 20 53 51 4c 49 54 45 5f 43 48 41 4e  case SQLITE_CHAN
3b80: 47 45 53 45 54 5f 44 41 54 41 3a 0a 20 20 20 20  GESET_DATA:.    
3b90: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
3ba0: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74  ppendElement(int
3bb0: 65 72 70 2c 20 70 45 76 61 6c 2c 54 63 6c 5f 4e  erp, pEval,Tcl_N
3bc0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 44 41 54  ewStringObj("DAT
3bd0: 41 22 2c 2d 31 29 29 3b 0a 20 20 20 20 20 20 20  A",-1));.       
3be0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61   break;.      ca
3bf0: 73 65 20 53 51 4c 49 54 45 5f 43 48 41 4e 47 45  se SQLITE_CHANGE
3c00: 53 45 54 5f 4e 4f 54 46 4f 55 4e 44 3a 0a 20 20  SET_NOTFOUND:.  
3c10: 20 20 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62        Tcl_ListOb
3c20: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69  jAppendElement(i
3c30: 6e 74 65 72 70 2c 20 70 45 76 61 6c 2c 54 63 6c  nterp, pEval,Tcl
3c40: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 4e  _NewStringObj("N
3c50: 4f 54 46 4f 55 4e 44 22 2c 2d 31 29 29 3b 0a 20  OTFOUND",-1));. 
3c60: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
3c70: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
3c80: 43 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49  CHANGESET_CONFLI
3c90: 43 54 3a 0a 20 20 20 20 20 20 20 20 54 63 6c 5f  CT:.        Tcl_
3ca0: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
3cb0: 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 45 76  ment(interp, pEv
3cc0: 61 6c 2c 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67  al,Tcl_NewString
3cd0: 4f 62 6a 28 22 43 4f 4e 46 4c 49 43 54 22 2c 2d  Obj("CONFLICT",-
3ce0: 31 29 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65  1));.        bre
3cf0: 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 53  ak;.      case S
3d00: 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f  QLITE_CHANGESET_
3d10: 43 4f 4e 53 54 52 41 49 4e 54 3a 0a 20 20 20 20  CONSTRAINT:.    
3d20: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
3d30: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74  ppendElement(int
3d40: 65 72 70 2c 20 70 45 76 61 6c 2c 54 63 6c 5f 4e  erp, pEval,Tcl_N
3d50: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 43 4f 4e  ewStringObj("CON
3d60: 53 54 52 41 49 4e 54 22 2c 2d 31 29 29 3b 0a 20  STRAINT",-1));. 
3d70: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
3d80: 20 20 7d 0a 20 20 0a 20 20 20 20 2f 2a 20 49 66    }.  .    /* If
3d90: 20 74 68 69 73 20 69 73 20 6e 6f 74 20 61 6e 20   this is not an 
3da0: 49 4e 53 45 52 54 2c 20 61 70 70 65 6e 64 20 74  INSERT, append t
3db0: 68 65 20 6f 6c 64 20 72 6f 77 20 2a 2f 0a 20 20  he old row */.  
3dc0: 20 20 69 66 28 20 6f 70 21 3d 53 51 4c 49 54 45    if( op!=SQLITE
3dd0: 5f 49 4e 53 45 52 54 20 29 7b 0a 20 20 20 20 20  _INSERT ){.     
3de0: 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 54 63   int i;.      Tc
3df0: 6c 5f 4f 62 6a 20 2a 70 4f 6c 64 20 3d 20 54 63  l_Obj *pOld = Tc
3e00: 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20  l_NewObj();.    
3e10: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43 6f    for(i=0; i<nCo
3e20: 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20  l; i++){.       
3e30: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
3e40: 70 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 73 71  pVal;.        sq
3e50: 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f  lite3changeset_o
3e60: 6c 64 28 70 49 74 65 72 2c 20 69 2c 20 26 70 56  ld(pIter, i, &pV
3e70: 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 74 65 73  al);.        tes
3e80: 74 5f 61 70 70 65 6e 64 5f 76 61 6c 75 65 28 70  t_append_value(p
3e90: 4f 6c 64 2c 20 70 56 61 6c 29 3b 0a 20 20 20 20  Old, pVal);.    
3ea0: 20 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f 4c 69    }.      Tcl_Li
3eb0: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
3ec0: 6e 74 28 30 2c 20 70 45 76 61 6c 2c 20 70 4f 6c  nt(0, pEval, pOl
3ed0: 64 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  d);.    }..    /
3ee0: 2a 20 49 66 20 74 68 69 73 20 69 73 20 6e 6f 74  * If this is not
3ef0: 20 61 20 44 45 4c 45 54 45 2c 20 61 70 70 65 6e   a DELETE, appen
3f00: 64 20 74 68 65 20 6e 65 77 20 72 6f 77 20 2a 2f  d the new row */
3f10: 0a 20 20 20 20 69 66 28 20 6f 70 21 3d 53 51 4c  .    if( op!=SQL
3f20: 49 54 45 5f 44 45 4c 45 54 45 20 29 7b 0a 20 20  ITE_DELETE ){.  
3f30: 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20      int i;.     
3f40: 20 54 63 6c 5f 4f 62 6a 20 2a 70 4e 65 77 20 3d   Tcl_Obj *pNew =
3f50: 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20   Tcl_NewObj();. 
3f60: 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c       for(i=0; i<
3f70: 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  nCol; i++){.    
3f80: 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75      sqlite3_valu
3f90: 65 20 2a 70 56 61 6c 3b 0a 20 20 20 20 20 20 20  e *pVal;.       
3fa0: 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
3fb0: 74 5f 6e 65 77 28 70 49 74 65 72 2c 20 69 2c 20  t_new(pIter, i, 
3fc0: 26 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 20 20  &pVal);.        
3fd0: 74 65 73 74 5f 61 70 70 65 6e 64 5f 76 61 6c 75  test_append_valu
3fe0: 65 28 70 4e 65 77 2c 20 70 56 61 6c 29 3b 0a 20  e(pNew, pVal);. 
3ff0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 54 63 6c       }.      Tcl
4000: 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c  _ListObjAppendEl
4010: 65 6d 65 6e 74 28 30 2c 20 70 45 76 61 6c 2c 20  ement(0, pEval, 
4020: 70 4e 65 77 29 3b 0a 20 20 20 20 7d 0a 0a 20 20  pNew);.    }..  
4030: 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69 73 20    /* If this is 
4040: 61 20 43 48 41 4e 47 45 53 45 54 5f 44 41 54 41  a CHANGESET_DATA
4050: 20 6f 72 20 43 48 41 4e 47 45 53 45 54 5f 43 4f   or CHANGESET_CO
4060: 4e 46 4c 49 43 54 20 63 6f 6e 66 6c 69 63 74 2c  NFLICT conflict,
4070: 20 61 70 70 65 6e 64 0a 20 20 20 20 20 2a 2a 20   append.     ** 
4080: 74 68 65 20 63 6f 6e 66 6c 69 63 74 69 6e 67 20  the conflicting 
4090: 72 6f 77 2e 20 20 2a 2f 0a 20 20 20 20 69 66 28  row.  */.    if(
40a0: 20 65 43 6f 6e 66 3d 3d 53 51 4c 49 54 45 5f 43   eConf==SQLITE_C
40b0: 48 41 4e 47 45 53 45 54 5f 44 41 54 41 20 7c 7c  HANGESET_DATA ||
40c0: 20 65 43 6f 6e 66 3d 3d 53 51 4c 49 54 45 5f 43   eConf==SQLITE_C
40d0: 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49 43  HANGESET_CONFLIC
40e0: 54 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69  T ){.      int i
40f0: 3b 0a 20 20 20 20 20 20 54 63 6c 5f 4f 62 6a 20  ;.      Tcl_Obj 
4100: 2a 70 43 6f 6e 66 6c 69 63 74 20 3d 20 54 63 6c  *pConflict = Tcl
4110: 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20 20  _NewObj();.     
4120: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c   for(i=0; i<nCol
4130: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
4140: 69 6e 74 20 72 63 3b 0a 20 20 20 20 20 20 20 20  int rc;.        
4150: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70  sqlite3_value *p
4160: 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 72 63 20  Val;.        rc 
4170: 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  = sqlite3changes
4180: 65 74 5f 63 6f 6e 66 6c 69 63 74 28 70 49 74 65  et_conflict(pIte
4190: 72 2c 20 69 2c 20 26 70 56 61 6c 29 3b 0a 20 20  r, i, &pVal);.  
41a0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 72 63        assert( rc
41b0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20  ==SQLITE_OK );. 
41c0: 20 20 20 20 20 20 20 74 65 73 74 5f 61 70 70 65         test_appe
41d0: 6e 64 5f 76 61 6c 75 65 28 70 43 6f 6e 66 6c 69  nd_value(pConfli
41e0: 63 74 2c 20 70 56 61 6c 29 3b 0a 20 20 20 20 20  ct, pVal);.     
41f0: 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f 4c 69 73   }.      Tcl_Lis
4200: 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e  tObjAppendElemen
4210: 74 28 30 2c 20 70 45 76 61 6c 2c 20 70 43 6f 6e  t(0, pEval, pCon
4220: 66 6c 69 63 74 29 3b 0a 20 20 20 20 7d 0a 0a 20  flict);.    }.. 
4230: 20 20 20 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a     /************
4240: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4250: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4260: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4270: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 20 20 20 20  ***********.    
4280: 20 2a 2a 20 54 68 69 73 20 62 6c 6f 63 6b 20 69   ** This block i
4290: 73 20 70 75 72 65 6c 79 20 66 6f 72 20 74 65 73  s purely for tes
42a0: 74 69 6e 67 20 73 6f 6d 65 20 65 72 72 6f 72 20  ting some error 
42b0: 63 6f 6e 64 69 74 69 6f 6e 73 2e 0a 20 20 20 20  conditions..    
42c0: 20 2a 2f 0a 20 20 20 20 69 66 28 20 65 43 6f 6e   */.    if( eCon
42d0: 66 3d 3d 53 51 4c 49 54 45 5f 43 48 41 4e 47 45  f==SQLITE_CHANGE
42e0: 53 45 54 5f 43 4f 4e 53 54 52 41 49 4e 54 20 0a  SET_CONSTRAINT .
42f0: 20 20 20 20 20 7c 7c 20 65 43 6f 6e 66 3d 3d 53       || eConf==S
4300: 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f  QLITE_CHANGESET_
4310: 4e 4f 54 46 4f 55 4e 44 20 0a 20 20 20 20 29 7b  NOTFOUND .    ){
4320: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76  .      sqlite3_v
4330: 61 6c 75 65 20 2a 70 56 61 6c 3b 0a 20 20 20 20  alue *pVal;.    
4340: 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 69 74    int rc = sqlit
4350: 65 33 63 68 61 6e 67 65 73 65 74 5f 63 6f 6e 66  e3changeset_conf
4360: 6c 69 63 74 28 70 49 74 65 72 2c 20 30 2c 20 26  lict(pIter, 0, &
4370: 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 61 73 73  pVal);.      ass
4380: 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ert( rc==SQLITE_
4390: 4d 49 53 55 53 45 20 29 3b 0a 20 20 20 20 7d 65  MISUSE );.    }e
43a0: 6c 73 65 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  lse{.      sqlit
43b0: 65 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c 3b 0a  e3_value *pVal;.
43c0: 20 20 20 20 20 20 69 6e 74 20 72 63 20 3d 20 73        int rc = s
43d0: 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
43e0: 63 6f 6e 66 6c 69 63 74 28 70 49 74 65 72 2c 20  conflict(pIter, 
43f0: 2d 31 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20 20  -1, &pVal);.    
4400: 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51    assert( rc==SQ
4410: 4c 49 54 45 5f 52 41 4e 47 45 20 29 3b 0a 20 20  LITE_RANGE );.  
4420: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
4430: 63 68 61 6e 67 65 73 65 74 5f 63 6f 6e 66 6c 69  changeset_confli
4440: 63 74 28 70 49 74 65 72 2c 20 6e 43 6f 6c 2c 20  ct(pIter, nCol, 
4450: 26 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 61 73  &pVal);.      as
4460: 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45  sert( rc==SQLITE
4470: 5f 52 41 4e 47 45 20 29 3b 0a 20 20 20 20 7d 0a  _RANGE );.    }.
4480: 20 20 20 20 69 66 28 20 6f 70 3d 3d 53 51 4c 49      if( op==SQLI
4490: 54 45 5f 44 45 4c 45 54 45 20 29 7b 0a 20 20 20  TE_DELETE ){.   
44a0: 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65     sqlite3_value
44b0: 20 2a 70 56 61 6c 3b 0a 20 20 20 20 20 20 69 6e   *pVal;.      in
44c0: 74 20 72 63 20 3d 20 73 71 6c 69 74 65 33 63 68  t rc = sqlite3ch
44d0: 61 6e 67 65 73 65 74 5f 6e 65 77 28 70 49 74 65  angeset_new(pIte
44e0: 72 2c 20 30 2c 20 26 70 56 61 6c 29 3b 0a 20 20  r, 0, &pVal);.  
44f0: 20 20 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d      assert( rc==
4500: 53 51 4c 49 54 45 5f 4d 49 53 55 53 45 20 29 3b  SQLITE_MISUSE );
4510: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
4520: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
4530: 2a 70 56 61 6c 3b 0a 20 20 20 20 20 20 69 6e 74  *pVal;.      int
4540: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 63 68 61   rc = sqlite3cha
4550: 6e 67 65 73 65 74 5f 6e 65 77 28 70 49 74 65 72  ngeset_new(pIter
4560: 2c 20 2d 31 2c 20 26 70 56 61 6c 29 3b 0a 20 20  , -1, &pVal);.  
4570: 20 20 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d      assert( rc==
4580: 53 51 4c 49 54 45 5f 52 41 4e 47 45 20 29 3b 0a  SQLITE_RANGE );.
4590: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
45a0: 65 33 63 68 61 6e 67 65 73 65 74 5f 6e 65 77 28  e3changeset_new(
45b0: 70 49 74 65 72 2c 20 6e 43 6f 6c 2c 20 26 70 56  pIter, nCol, &pV
45c0: 61 6c 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72  al);.      asser
45d0: 74 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52 41  t( rc==SQLITE_RA
45e0: 4e 47 45 20 29 3b 0a 20 20 20 20 7d 0a 20 20 20  NGE );.    }.   
45f0: 20 69 66 28 20 6f 70 3d 3d 53 51 4c 49 54 45 5f   if( op==SQLITE_
4600: 49 4e 53 45 52 54 20 29 7b 0a 20 20 20 20 20 20  INSERT ){.      
4610: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70  sqlite3_value *p
4620: 56 61 6c 3b 0a 20 20 20 20 20 20 69 6e 74 20 72  Val;.      int r
4630: 63 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67  c = sqlite3chang
4640: 65 73 65 74 5f 6f 6c 64 28 70 49 74 65 72 2c 20  eset_old(pIter, 
4650: 30 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20 20 20  0, &pVal);.     
4660: 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c   assert( rc==SQL
4670: 49 54 45 5f 4d 49 53 55 53 45 20 29 3b 0a 20 20  ITE_MISUSE );.  
4680: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 73    }else{.      s
4690: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56  qlite3_value *pV
46a0: 61 6c 3b 0a 20 20 20 20 20 20 69 6e 74 20 72 63  al;.      int rc
46b0: 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65   = sqlite3change
46c0: 73 65 74 5f 6f 6c 64 28 70 49 74 65 72 2c 20 2d  set_old(pIter, -
46d0: 31 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20 20 20  1, &pVal);.     
46e0: 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c   assert( rc==SQL
46f0: 49 54 45 5f 52 41 4e 47 45 20 29 3b 0a 20 20 20  ITE_RANGE );.   
4700: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 63     rc = sqlite3c
4710: 68 61 6e 67 65 73 65 74 5f 6f 6c 64 28 70 49 74  hangeset_old(pIt
4720: 65 72 2c 20 6e 43 6f 6c 2c 20 26 70 56 61 6c 29  er, nCol, &pVal)
4730: 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  ;.      assert( 
4740: 72 63 3d 3d 53 51 4c 49 54 45 5f 52 41 4e 47 45  rc==SQLITE_RANGE
4750: 20 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66   );.    }.    if
4760: 28 20 65 43 6f 6e 66 21 3d 53 51 4c 49 54 45 5f  ( eConf!=SQLITE_
4770: 43 48 41 4e 47 45 53 45 54 5f 46 4f 52 45 49 47  CHANGESET_FOREIG
4780: 4e 5f 4b 45 59 20 29 7b 0a 20 20 20 20 20 20 2f  N_KEY ){.      /
4790: 2a 20 65 43 6f 6e 66 21 3d 46 4f 52 45 49 47 4e  * eConf!=FOREIGN
47a0: 5f 4b 45 59 20 69 73 20 61 6c 77 61 79 73 20 74  _KEY is always t
47b0: 72 75 65 20 61 74 20 74 68 69 73 20 70 6f 69 6e  rue at this poin
47c0: 74 2e 20 54 68 65 20 63 6f 6e 64 69 74 69 6f 6e  t. The condition
47d0: 20 69 73 20 0a 20 20 20 20 20 20 2a 2a 20 6a 75   is .      ** ju
47e0: 73 74 20 74 68 65 72 65 20 74 6f 20 6d 61 6b 65  st there to make
47f0: 20 69 74 20 63 6c 65 61 72 65 72 20 77 68 61 74   it clearer what
4800: 20 69 73 20 62 65 69 6e 67 20 74 65 73 74 65 64   is being tested
4810: 2e 20 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20  .  */.      int 
4820: 6e 44 75 6d 6d 79 3b 0a 20 20 20 20 20 20 69 6e  nDummy;.      in
4830: 74 20 72 63 20 3d 20 73 71 6c 69 74 65 33 63 68  t rc = sqlite3ch
4840: 61 6e 67 65 73 65 74 5f 66 6b 5f 63 6f 6e 66 6c  angeset_fk_confl
4850: 69 63 74 73 28 70 49 74 65 72 2c 20 26 6e 44 75  icts(pIter, &nDu
4860: 6d 6d 79 29 3b 0a 20 20 20 20 20 20 61 73 73 65  mmy);.      asse
4870: 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4d  rt( rc==SQLITE_M
4880: 49 53 55 53 45 20 29 3b 0a 20 20 20 20 7d 0a 20  ISUSE );.    }. 
4890: 20 20 20 2f 2a 20 45 6e 64 20 6f 66 20 74 65 73     /* End of tes
48a0: 74 69 6e 67 20 62 6c 6f 63 6b 0a 20 20 20 20 2a  ting block.    *
48b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
48c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
48d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
48e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
48f0: 2a 2a 2a 2a 2a 2a 2f 0a 20 20 7d 0a 0a 20 20 69  ******/.  }..  i
4900: 66 28 20 54 43 4c 5f 4f 4b 21 3d 54 63 6c 5f 45  f( TCL_OK!=Tcl_E
4910: 76 61 6c 4f 62 6a 45 78 28 69 6e 74 65 72 70 2c  valObjEx(interp,
4920: 20 70 45 76 61 6c 2c 20 54 43 4c 5f 45 56 41 4c   pEval, TCL_EVAL
4930: 5f 47 4c 4f 42 41 4c 29 20 29 7b 0a 20 20 20 20  _GLOBAL) ){.    
4940: 54 63 6c 5f 42 61 63 6b 67 72 6f 75 6e 64 45 72  Tcl_BackgroundEr
4950: 72 6f 72 28 69 6e 74 65 72 70 29 3b 0a 20 20 7d  ror(interp);.  }
4960: 65 6c 73 65 7b 0a 20 20 20 20 54 63 6c 5f 4f 62  else{.    Tcl_Ob
4970: 6a 20 2a 70 52 65 73 20 3d 20 54 63 6c 5f 47 65  j *pRes = Tcl_Ge
4980: 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72  tObjResult(inter
4990: 70 29 3b 0a 20 20 20 20 69 66 28 20 74 65 73 74  p);.    if( test
49a0: 5f 6f 62 6a 5f 65 71 5f 73 74 72 69 6e 67 28 70  _obj_eq_string(p
49b0: 52 65 73 2c 20 22 4f 4d 49 54 22 29 20 7c 7c 20  Res, "OMIT") || 
49c0: 74 65 73 74 5f 6f 62 6a 5f 65 71 5f 73 74 72 69  test_obj_eq_stri
49d0: 6e 67 28 70 52 65 73 2c 20 22 22 29 20 29 7b 0a  ng(pRes, "") ){.
49e0: 20 20 20 20 20 20 72 65 74 20 3d 20 53 51 4c 49        ret = SQLI
49f0: 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 4f 4d 49  TE_CHANGESET_OMI
4a00: 54 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  T;.    }else if(
4a10: 20 74 65 73 74 5f 6f 62 6a 5f 65 71 5f 73 74 72   test_obj_eq_str
4a20: 69 6e 67 28 70 52 65 73 2c 20 22 52 45 50 4c 41  ing(pRes, "REPLA
4a30: 43 45 22 29 20 29 7b 0a 20 20 20 20 20 20 72 65  CE") ){.      re
4a40: 74 20 3d 20 53 51 4c 49 54 45 5f 43 48 41 4e 47  t = SQLITE_CHANG
4a50: 45 53 45 54 5f 52 45 50 4c 41 43 45 3b 0a 20 20  ESET_REPLACE;.  
4a60: 20 20 7d 65 6c 73 65 20 69 66 28 20 74 65 73 74    }else if( test
4a70: 5f 6f 62 6a 5f 65 71 5f 73 74 72 69 6e 67 28 70  _obj_eq_string(p
4a80: 52 65 73 2c 20 22 41 42 4f 52 54 22 29 20 29 7b  Res, "ABORT") ){
4a90: 0a 20 20 20 20 20 20 72 65 74 20 3d 20 53 51 4c  .      ret = SQL
4aa0: 49 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 41 42  ITE_CHANGESET_AB
4ab0: 4f 52 54 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  ORT;.    }else{.
4ac0: 20 20 20 20 20 20 54 63 6c 5f 47 65 74 49 6e 74        Tcl_GetInt
4ad0: 46 72 6f 6d 4f 62 6a 28 30 2c 20 70 52 65 73 2c  FromObj(0, pRes,
4ae0: 20 26 72 65 74 29 3b 0a 20 20 20 20 7d 0a 20 20   &ret);.    }.  
4af0: 7d 0a 0a 20 20 54 63 6c 5f 44 65 63 72 52 65 66  }..  Tcl_DecrRef
4b00: 43 6f 75 6e 74 28 70 45 76 61 6c 29 3b 0a 20 20  Count(pEval);.  
4b10: 72 65 74 75 72 6e 20 72 65 74 3b 0a 7d 0a 0a 2f  return ret;.}../
4b20: 2a 0a 2a 2a 20 54 68 65 20 63 6f 6e 66 6c 69 63  *.** The conflic
4b30: 74 20 68 61 6e 64 6c 65 72 20 75 73 65 64 20 62  t handler used b
4b40: 79 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  y sqlite3changes
4b50: 65 74 5f 61 70 70 6c 79 5f 72 65 70 6c 61 63 65  et_apply_replace
4b60: 5f 61 6c 6c 28 29 2e 20 0a 2a 2a 20 54 68 69 73  _all(). .** This
4b70: 20 63 6f 6e 66 6c 69 63 74 20 68 61 6e 64 6c 65   conflict handle
4b80: 72 20 63 61 6c 6c 73 20 73 71 6c 69 74 65 33 5f  r calls sqlite3_
4b90: 76 61 6c 75 65 5f 74 65 78 74 31 36 28 29 20 6f  value_text16() o
4ba0: 6e 20 61 6c 6c 20 61 76 61 69 6c 61 62 6c 65 0a  n all available.
4bb0: 2a 2a 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  ** sqlite3_value
4bc0: 20 6f 62 6a 65 63 74 73 20 61 6e 64 20 74 68 65   objects and the
4bd0: 6e 20 72 65 74 75 72 6e 73 20 43 48 41 4e 47 45  n returns CHANGE
4be0: 53 45 54 5f 52 45 50 4c 41 43 45 2c 20 6f 72 20  SET_REPLACE, or 
4bf0: 0a 2a 2a 20 43 48 41 4e 47 45 53 45 54 5f 4f 4d  .** CHANGESET_OM
4c00: 49 54 20 69 66 20 52 45 50 4c 41 43 45 20 69 73  IT if REPLACE is
4c10: 20 6e 6f 74 20 61 70 70 6c 69 63 61 62 6c 65 2e   not applicable.
4c20: 20 54 68 69 73 20 69 73 20 75 73 65 64 20 74 6f   This is used to
4c30: 20 74 65 73 74 20 74 68 65 0a 2a 2a 20 65 66 66   test the.** eff
4c40: 65 63 74 20 6f 66 20 61 20 6d 61 6c 6c 6f 63 20  ect of a malloc 
4c50: 66 61 69 6c 75 72 65 20 77 69 74 68 69 6e 20 61  failure within a
4c60: 6e 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  n sqlite3_value_
4c70: 78 78 78 28 29 20 66 75 6e 63 74 69 6f 6e 0a 2a  xxx() function.*
4c80: 2a 20 69 6e 76 6f 6b 65 64 20 62 79 20 61 20 63  * invoked by a c
4c90: 6f 6e 66 6c 69 63 74 2d 68 61 6e 64 6c 65 72 20  onflict-handler 
4ca0: 63 61 6c 6c 62 61 63 6b 2e 0a 2a 2f 0a 73 74 61  callback..*/.sta
4cb0: 74 69 63 20 69 6e 74 20 72 65 70 6c 61 63 65 5f  tic int replace_
4cc0: 68 61 6e 64 6c 65 72 28 0a 20 20 76 6f 69 64 20  handler(.  void 
4cd0: 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20 20  *pCtx,          
4ce0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f             /* Po
4cf0: 69 6e 74 65 72 20 74 6f 20 54 65 73 74 43 6f 6e  inter to TestCon
4d00: 66 6c 69 63 74 48 61 6e 64 6c 65 72 20 73 74 72  flictHandler str
4d10: 75 63 74 75 72 65 20 2a 2f 0a 20 20 69 6e 74 20  ucture */.  int 
4d20: 65 43 6f 6e 66 2c 20 20 20 20 20 20 20 20 20 20  eConf,          
4d30: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
4d40: 41 54 41 2c 20 4d 49 53 53 49 4e 47 2c 20 43 4f  ATA, MISSING, CO
4d50: 4e 46 4c 49 43 54 2c 20 43 4f 4e 53 54 52 41 49  NFLICT, CONSTRAI
4d60: 4e 54 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  NT */.  sqlite3_
4d70: 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20 2a  changeset_iter *
4d80: 70 49 74 65 72 20 20 20 2f 2a 20 48 61 6e 64 6c  pIter   /* Handl
4d90: 65 20 64 65 73 63 72 69 62 69 6e 67 20 63 68 61  e describing cha
4da0: 6e 67 65 20 61 6e 64 20 63 6f 6e 66 6c 69 63 74  nge and conflict
4db0: 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 6f 70 3b   */.){.  int op;
4dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4dd0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 51 4c 49           /* SQLI
4de0: 54 45 5f 55 50 44 41 54 45 2c 20 44 45 4c 45 54  TE_UPDATE, DELET
4df0: 45 20 6f 72 20 49 4e 53 45 52 54 20 2a 2f 0a 20  E or INSERT */. 
4e00: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61   const char *zTa
4e10: 62 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b;              
4e20: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 61 62 6c   /* Name of tabl
4e30: 65 20 63 6f 6e 66 6c 69 63 74 20 69 73 20 6f 6e  e conflict is on
4e40: 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 3b 20   */.  int nCol; 
4e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4e60: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
4e70: 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 61  of columns in ta
4e80: 62 6c 65 20 7a 54 61 62 20 2a 2f 0a 20 20 69 6e  ble zTab */.  in
4e90: 74 20 69 3b 0a 20 20 69 6e 74 20 78 20 3d 20 30  t i;.  int x = 0
4ea0: 3b 0a 0a 20 20 73 71 6c 69 74 65 33 63 68 61 6e  ;..  sqlite3chan
4eb0: 67 65 73 65 74 5f 6f 70 28 70 49 74 65 72 2c 20  geset_op(pIter, 
4ec0: 26 7a 54 61 62 2c 20 26 6e 43 6f 6c 2c 20 26 6f  &zTab, &nCol, &o
4ed0: 70 2c 20 30 29 3b 0a 0a 20 20 69 66 28 20 6f 70  p, 0);..  if( op
4ee0: 21 3d 53 51 4c 49 54 45 5f 49 4e 53 45 52 54 20  !=SQLITE_INSERT 
4ef0: 29 7b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  ){.    for(i=0; 
4f00: 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20  i<nCol; i++){.  
4f10: 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75      sqlite3_valu
4f20: 65 20 2a 70 56 61 6c 3b 0a 20 20 20 20 20 20 73  e *pVal;.      s
4f30: 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
4f40: 6f 6c 64 28 70 49 74 65 72 2c 20 69 2c 20 26 70  old(pIter, i, &p
4f50: 56 61 6c 29 3b 0a 20 20 20 20 20 20 73 71 6c 69  Val);.      sqli
4f60: 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 31 36  te3_value_text16
4f70: 28 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 78 2b  (pVal);.      x+
4f80: 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  +;.    }.  }..  
4f90: 69 66 28 20 6f 70 21 3d 53 51 4c 49 54 45 5f 44  if( op!=SQLITE_D
4fa0: 45 4c 45 54 45 20 29 7b 0a 20 20 20 20 66 6f 72  ELETE ){.    for
4fb0: 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b  (i=0; i<nCol; i+
4fc0: 2b 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  +){.      sqlite
4fd0: 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c 3b 0a 20  3_value *pVal;. 
4fe0: 20 20 20 20 20 73 71 6c 69 74 65 33 63 68 61 6e       sqlite3chan
4ff0: 67 65 73 65 74 5f 6e 65 77 28 70 49 74 65 72 2c  geset_new(pIter,
5000: 20 69 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20 20   i, &pVal);.    
5010: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f    sqlite3_value_
5020: 74 65 78 74 31 36 28 70 56 61 6c 29 3b 0a 20 20  text16(pVal);.  
5030: 20 20 20 20 78 2b 2b 3b 0a 20 20 20 20 7d 0a 20      x++;.    }. 
5040: 20 7d 0a 0a 20 20 69 66 28 20 65 43 6f 6e 66 3d   }..  if( eConf=
5050: 3d 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45  =SQLITE_CHANGESE
5060: 54 5f 44 41 54 41 20 29 7b 0a 20 20 20 20 72 65  T_DATA ){.    re
5070: 74 75 72 6e 20 53 51 4c 49 54 45 5f 43 48 41 4e  turn SQLITE_CHAN
5080: 47 45 53 45 54 5f 52 45 50 4c 41 43 45 3b 0a 20  GESET_REPLACE;. 
5090: 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49   }.  return SQLI
50a0: 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 4f 4d 49  TE_CHANGESET_OMI
50b0: 54 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  T;.}..static int
50c0: 20 74 65 73 74 53 74 72 65 61 6d 49 6e 70 75 74   testStreamInput
50d0: 28 0a 20 20 76 6f 69 64 20 2a 70 43 74 78 2c 20  (.  void *pCtx, 
50e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
50f0: 20 20 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20 70      /* Context p
5100: 6f 69 6e 74 65 72 20 2a 2f 0a 20 20 76 6f 69 64  ointer */.  void
5110: 20 2a 70 44 61 74 61 2c 20 20 20 20 20 20 20 20   *pData,        
5120: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
5130: 75 66 66 65 72 20 74 6f 20 70 6f 70 75 6c 61 74  uffer to populat
5140: 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 44 61  e */.  int *pnDa
5150: 74 61 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ta              
5160: 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54         /* IN/OUT
5170: 3a 20 42 79 74 65 73 20 72 65 71 75 65 73 74 65  : Bytes requeste
5180: 64 2f 73 75 70 70 6c 69 65 64 20 2a 2f 0a 29 7b  d/supplied */.){
5190: 0a 20 20 54 65 73 74 53 74 72 65 61 6d 49 6e 70  .  TestStreamInp
51a0: 75 74 20 2a 70 20 3d 20 28 54 65 73 74 53 74 72  ut *p = (TestStr
51b0: 65 61 6d 49 6e 70 75 74 2a 29 70 43 74 78 3b 0a  eamInput*)pCtx;.
51c0: 20 20 69 6e 74 20 6e 52 65 71 20 3d 20 2a 70 6e    int nReq = *pn
51d0: 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20  Data;           
51e0: 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 64 61    /* Bytes of da
51f0: 74 61 20 72 65 71 75 65 73 74 65 64 20 2a 2f 0a  ta requested */.
5200: 20 20 69 6e 74 20 6e 52 65 6d 20 3d 20 70 2d 3e    int nRem = p->
5210: 6e 44 61 74 61 20 2d 20 70 2d 3e 69 44 61 74 61  nData - p->iData
5220: 3b 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 64 61  ; /* Bytes of da
5230: 74 61 20 61 76 61 69 6c 61 62 6c 65 20 2a 2f 0a  ta available */.
5240: 20 20 69 6e 74 20 6e 52 65 74 20 3d 20 70 2d 3e    int nRet = p->
5250: 6e 53 74 72 65 61 6d 3b 20 20 20 20 20 20 20 20  nStream;        
5260: 20 20 2f 2a 20 42 79 74 65 73 20 61 63 74 75 61    /* Bytes actua
5270: 6c 6c 79 20 72 65 74 75 72 6e 65 64 20 2a 2f 0a  lly returned */.
5280: 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 61  .  /* Allocate a
5290: 6e 64 20 66 72 65 65 20 73 6f 6d 65 20 73 70 61  nd free some spa
52a0: 63 65 2e 20 54 68 65 72 65 20 69 73 20 6e 6f 20  ce. There is no 
52b0: 70 6f 69 6e 74 20 74 6f 20 74 68 69 73 2c 20 6f  point to this, o
52c0: 74 68 65 72 20 74 68 61 6e 0a 20 20 2a 2a 20 74  ther than.  ** t
52d0: 68 61 74 20 69 74 20 61 6c 6c 6f 77 73 20 74 68  hat it allows th
52e0: 65 20 72 65 67 75 6c 61 72 20 4f 4f 4d 20 66 61  e regular OOM fa
52f0: 75 6c 74 2d 69 6e 6a 65 63 74 69 6f 6e 20 74 65  ult-injection te
5300: 73 74 73 20 74 6f 20 63 61 75 73 65 20 61 6e 20  sts to cause an 
5310: 65 72 72 6f 72 0a 20 20 2a 2a 20 69 6e 20 74 68  error.  ** in th
5320: 69 73 20 66 75 6e 63 74 69 6f 6e 2e 20 20 2a 2f  is function.  */
5330: 0a 20 20 76 6f 69 64 20 2a 70 41 6c 6c 6f 63 20  .  void *pAlloc 
5340: 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  = sqlite3_malloc
5350: 28 31 30 29 3b 0a 20 20 69 66 28 20 70 41 6c 6c  (10);.  if( pAll
5360: 6f 63 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53  oc==0 ) return S
5370: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 73  QLITE_NOMEM;.  s
5380: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 41 6c 6c  qlite3_free(pAll
5390: 6f 63 29 3b 0a 0a 20 20 69 66 28 20 6e 52 65 74  oc);..  if( nRet
53a0: 3e 6e 52 65 71 20 29 20 6e 52 65 74 20 3d 20 6e  >nReq ) nRet = n
53b0: 52 65 71 3b 0a 20 20 69 66 28 20 6e 52 65 74 3e  Req;.  if( nRet>
53c0: 6e 52 65 6d 20 29 20 6e 52 65 74 20 3d 20 6e 52  nRem ) nRet = nR
53d0: 65 6d 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 6e  em;..  assert( n
53e0: 52 65 74 3e 3d 30 20 29 3b 0a 20 20 69 66 28 20  Ret>=0 );.  if( 
53f0: 6e 52 65 74 3e 30 20 29 7b 0a 20 20 20 20 6d 65  nRet>0 ){.    me
5400: 6d 63 70 79 28 70 44 61 74 61 2c 20 26 70 2d 3e  mcpy(pData, &p->
5410: 61 44 61 74 61 5b 70 2d 3e 69 44 61 74 61 5d 2c  aData[p->iData],
5420: 20 6e 52 65 74 29 3b 0a 20 20 20 20 70 2d 3e 69   nRet);.    p->i
5430: 44 61 74 61 20 2b 3d 20 6e 52 65 74 3b 0a 20 20  Data += nRet;.  
5440: 7d 0a 0a 20 20 2a 70 6e 44 61 74 61 20 3d 20 6e  }..  *pnData = n
5450: 52 65 74 3b 0a 20 20 72 65 74 75 72 6e 20 53 51  Ret;.  return SQ
5460: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a  LITE_OK;.}.../*.
5470: 2a 2a 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65  ** sqlite3change
5480: 73 65 74 5f 61 70 70 6c 79 20 44 42 20 43 48 41  set_apply DB CHA
5490: 4e 47 45 53 45 54 20 43 4f 4e 46 4c 49 43 54 2d  NGESET CONFLICT-
54a0: 53 43 52 49 50 54 20 3f 46 49 4c 54 45 52 2d 53  SCRIPT ?FILTER-S
54b0: 43 52 49 50 54 3f 0a 2a 2f 0a 73 74 61 74 69 63  CRIPT?.*/.static
54c0: 20 69 6e 74 20 53 51 4c 49 54 45 5f 54 43 4c 41   int SQLITE_TCLA
54d0: 50 49 20 74 65 73 74 5f 73 71 6c 69 74 65 33 63  PI test_sqlite3c
54e0: 68 61 6e 67 65 73 65 74 5f 61 70 70 6c 79 28 0a  hangeset_apply(.
54f0: 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e 74 44    void * clientD
5500: 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72  ata,.  Tcl_Inter
5510: 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74  p *interp,.  int
5520: 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a   objc,.  Tcl_Obj
5530: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29   *CONST objv[].)
5540: 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b  {.  sqlite3 *db;
5550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5560: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
5570: 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 54 63 6c 5f  handle */.  Tcl_
5580: 43 6d 64 49 6e 66 6f 20 69 6e 66 6f 3b 20 20 20  CmdInfo info;   
5590: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
55a0: 61 74 61 62 61 73 65 20 54 63 6c 20 63 6f 6d 6d  atabase Tcl comm
55b0: 61 6e 64 20 28 6f 62 6a 76 5b 31 5d 29 20 69 6e  and (objv[1]) in
55c0: 66 6f 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20  fo */.  int rc; 
55d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
55e0: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
55f0: 6e 20 63 6f 64 65 20 66 72 6f 6d 20 63 68 61 6e  n code from chan
5600: 67 65 73 65 74 5f 69 6e 76 65 72 74 28 29 20 2a  geset_invert() *
5610: 2f 0a 20 20 76 6f 69 64 20 2a 70 43 68 61 6e 67  /.  void *pChang
5620: 65 73 65 74 3b 20 20 20 20 20 20 20 20 20 20 20  eset;           
5630: 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 63 6f      /* Buffer co
5640: 6e 74 61 69 6e 69 6e 67 20 63 68 61 6e 67 65 73  ntaining changes
5650: 65 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 68 61  et */.  int nCha
5660: 6e 67 65 73 65 74 3b 20 20 20 20 20 20 20 20 20  ngeset;         
5670: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
5680: 6f 66 20 62 75 66 66 65 72 20 61 43 68 61 6e 67  of buffer aChang
5690: 65 73 65 74 20 69 6e 20 62 79 74 65 73 20 2a 2f  eset in bytes */
56a0: 0a 20 20 54 65 73 74 43 6f 6e 66 6c 69 63 74 48  .  TestConflictH
56b0: 61 6e 64 6c 65 72 20 63 74 78 3b 0a 20 20 54 65  andler ctx;.  Te
56c0: 73 74 53 74 72 65 61 6d 49 6e 70 75 74 20 73 53  stStreamInput sS
56d0: 74 72 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 73  tr;..  memset(&s
56e0: 53 74 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73  Str, 0, sizeof(s
56f0: 53 74 72 29 29 3b 0a 20 20 73 53 74 72 2e 6e 53  Str));.  sStr.nS
5700: 74 72 65 61 6d 20 3d 20 74 65 73 74 5f 74 63 6c  tream = test_tcl
5710: 5f 69 6e 74 65 67 65 72 28 69 6e 74 65 72 70 2c  _integer(interp,
5720: 20 53 45 53 53 49 4f 4e 5f 53 54 52 45 41 4d 5f   SESSION_STREAM_
5730: 54 43 4c 5f 56 41 52 29 3b 0a 0a 20 20 69 66 28  TCL_VAR);..  if(
5740: 20 6f 62 6a 63 21 3d 34 20 26 26 20 6f 62 6a 63   objc!=4 && objc
5750: 21 3d 35 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57  !=5 ){.    Tcl_W
5760: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
5770: 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 0a 20 20  rp, 1, objv, .  
5780: 20 20 20 20 20 20 22 44 42 20 43 48 41 4e 47 45        "DB CHANGE
5790: 53 45 54 20 43 4f 4e 46 4c 49 43 54 2d 53 43 52  SET CONFLICT-SCR
57a0: 49 50 54 20 3f 46 49 4c 54 45 52 2d 53 43 52 49  IPT ?FILTER-SCRI
57b0: 50 54 3f 22 0a 20 20 20 20 29 3b 0a 20 20 20 20  PT?".    );.    
57c0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
57d0: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 30 3d 3d 54  ;.  }.  if( 0==T
57e0: 63 6c 5f 47 65 74 43 6f 6d 6d 61 6e 64 49 6e 66  cl_GetCommandInf
57f0: 6f 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65  o(interp, Tcl_Ge
5800: 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29  tString(objv[1])
5810: 2c 20 26 69 6e 66 6f 29 20 29 7b 0a 20 20 20 20  , &info) ){.    
5820: 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74  Tcl_AppendResult
5830: 28 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75 63  (interp, "no suc
5840: 68 20 68 61 6e 64 6c 65 3a 20 22 2c 20 54 63 6c  h handle: ", Tcl
5850: 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b  _GetString(objv[
5860: 32 5d 29 2c 20 30 29 3b 0a 20 20 20 20 72 65 74  2]), 0);.    ret
5870: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
5880: 20 7d 0a 20 20 64 62 20 3d 20 2a 28 73 71 6c 69   }.  db = *(sqli
5890: 74 65 33 20 2a 2a 29 69 6e 66 6f 2e 6f 62 6a 43  te3 **)info.objC
58a0: 6c 69 65 6e 74 44 61 74 61 3b 0a 20 20 70 43 68  lientData;.  pCh
58b0: 61 6e 67 65 73 65 74 20 3d 20 28 76 6f 69 64 20  angeset = (void 
58c0: 2a 29 54 63 6c 5f 47 65 74 42 79 74 65 41 72 72  *)Tcl_GetByteArr
58d0: 61 79 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 32  ayFromObj(objv[2
58e0: 5d 2c 20 26 6e 43 68 61 6e 67 65 73 65 74 29 3b  ], &nChangeset);
58f0: 0a 20 20 63 74 78 2e 70 43 6f 6e 66 6c 69 63 74  .  ctx.pConflict
5900: 53 63 72 69 70 74 20 3d 20 6f 62 6a 76 5b 33 5d  Script = objv[3]
5910: 3b 0a 20 20 63 74 78 2e 70 46 69 6c 74 65 72 53  ;.  ctx.pFilterS
5920: 63 72 69 70 74 20 3d 20 6f 62 6a 63 3d 3d 35 20  cript = objc==5 
5930: 3f 20 6f 62 6a 76 5b 34 5d 20 3a 20 30 3b 0a 20  ? objv[4] : 0;. 
5940: 20 63 74 78 2e 69 6e 74 65 72 70 20 3d 20 69 6e   ctx.interp = in
5950: 74 65 72 70 3b 0a 0a 20 20 69 66 28 20 73 53 74  terp;..  if( sSt
5960: 72 2e 6e 53 74 72 65 61 6d 3d 3d 30 20 29 7b 0a  r.nStream==0 ){.
5970: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
5980: 63 68 61 6e 67 65 73 65 74 5f 61 70 70 6c 79 28  changeset_apply(
5990: 64 62 2c 20 6e 43 68 61 6e 67 65 73 65 74 2c 20  db, nChangeset, 
59a0: 70 43 68 61 6e 67 65 73 65 74 2c 20 0a 20 20 20  pChangeset, .   
59b0: 20 20 20 20 20 28 6f 62 6a 63 3d 3d 35 29 20 3f       (objc==5) ?
59c0: 20 74 65 73 74 5f 66 69 6c 74 65 72 5f 68 61 6e   test_filter_han
59d0: 64 6c 65 72 20 3a 20 30 2c 20 74 65 73 74 5f 63  dler : 0, test_c
59e0: 6f 6e 66 6c 69 63 74 5f 68 61 6e 64 6c 65 72 2c  onflict_handler,
59f0: 20 28 76 6f 69 64 20 2a 29 26 63 74 78 0a 20 20   (void *)&ctx.  
5a00: 20 20 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20    );.  }else{.  
5a10: 20 20 73 53 74 72 2e 61 44 61 74 61 20 3d 20 28    sStr.aData = (
5a20: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 2a 29 70  unsigned char*)p
5a30: 43 68 61 6e 67 65 73 65 74 3b 0a 20 20 20 20 73  Changeset;.    s
5a40: 53 74 72 2e 6e 44 61 74 61 20 3d 20 6e 43 68 61  Str.nData = nCha
5a50: 6e 67 65 73 65 74 3b 0a 20 20 20 20 72 63 20 3d  ngeset;.    rc =
5a60: 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
5a70: 74 5f 61 70 70 6c 79 5f 73 74 72 6d 28 64 62 2c  t_apply_strm(db,
5a80: 20 74 65 73 74 53 74 72 65 61 6d 49 6e 70 75 74   testStreamInput
5a90: 2c 20 28 76 6f 69 64 2a 29 26 73 53 74 72 2c 0a  , (void*)&sStr,.
5aa0: 20 20 20 20 20 20 20 20 28 6f 62 6a 63 3d 3d 35          (objc==5
5ab0: 29 20 3f 20 74 65 73 74 5f 66 69 6c 74 65 72 5f  ) ? test_filter_
5ac0: 68 61 6e 64 6c 65 72 20 3a 20 30 2c 20 74 65 73  handler : 0, tes
5ad0: 74 5f 63 6f 6e 66 6c 69 63 74 5f 68 61 6e 64 6c  t_conflict_handl
5ae0: 65 72 2c 20 28 76 6f 69 64 20 2a 29 26 63 74 78  er, (void *)&ctx
5af0: 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a 20 20 69  .    );.  }..  i
5b00: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
5b10: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 74   ){.    return t
5b20: 65 73 74 5f 73 65 73 73 69 6f 6e 5f 65 72 72 6f  est_session_erro
5b30: 72 28 69 6e 74 65 72 70 2c 20 72 63 2c 20 30 29  r(interp, rc, 0)
5b40: 3b 0a 20 20 7d 0a 20 20 54 63 6c 5f 52 65 73 65  ;.  }.  Tcl_Rese
5b50: 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  tResult(interp);
5b60: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
5b70: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 73 71 6c 69 74  ;.}../*.** sqlit
5b80: 65 33 63 68 61 6e 67 65 73 65 74 5f 61 70 70 6c  e3changeset_appl
5b90: 79 5f 72 65 70 6c 61 63 65 5f 61 6c 6c 20 44 42  y_replace_all DB
5ba0: 20 43 48 41 4e 47 45 53 45 54 20 0a 2a 2f 0a 73   CHANGESET .*/.s
5bb0: 74 61 74 69 63 20 69 6e 74 20 53 51 4c 49 54 45  tatic int SQLITE
5bc0: 5f 54 43 4c 41 50 49 20 74 65 73 74 5f 73 71 6c  _TCLAPI test_sql
5bd0: 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 61 70  ite3changeset_ap
5be0: 70 6c 79 5f 72 65 70 6c 61 63 65 5f 61 6c 6c 28  ply_replace_all(
5bf0: 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e 74  .  void * client
5c00: 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65  Data,.  Tcl_Inte
5c10: 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e  rp *interp,.  in
5c20: 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62  t objc,.  Tcl_Ob
5c30: 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a  j *CONST objv[].
5c40: 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  ){.  sqlite3 *db
5c50: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
5c60: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
5c70: 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 54 63 6c   handle */.  Tcl
5c80: 5f 43 6d 64 49 6e 66 6f 20 69 6e 66 6f 3b 20 20  _CmdInfo info;  
5c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5ca0: 44 61 74 61 62 61 73 65 20 54 63 6c 20 63 6f 6d  Database Tcl com
5cb0: 6d 61 6e 64 20 28 6f 62 6a 76 5b 31 5d 29 20 69  mand (objv[1]) i
5cc0: 6e 66 6f 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b  nfo */.  int rc;
5cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ce0: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
5cf0: 72 6e 20 63 6f 64 65 20 66 72 6f 6d 20 63 68 61  rn code from cha
5d00: 6e 67 65 73 65 74 5f 69 6e 76 65 72 74 28 29 20  ngeset_invert() 
5d10: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 43 68 61 6e  */.  void *pChan
5d20: 67 65 73 65 74 3b 20 20 20 20 20 20 20 20 20 20  geset;          
5d30: 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 63       /* Buffer c
5d40: 6f 6e 74 61 69 6e 69 6e 67 20 63 68 61 6e 67 65  ontaining change
5d50: 73 65 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 68  set */.  int nCh
5d60: 61 6e 67 65 73 65 74 3b 20 20 20 20 20 20 20 20  angeset;        
5d70: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
5d80: 20 6f 66 20 62 75 66 66 65 72 20 61 43 68 61 6e   of buffer aChan
5d90: 67 65 73 65 74 20 69 6e 20 62 79 74 65 73 20 2a  geset in bytes *
5da0: 2f 0a 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 33  /..  if( objc!=3
5db0: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e   ){.    Tcl_Wron
5dc0: 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c  gNumArgs(interp,
5dd0: 20 31 2c 20 6f 62 6a 76 2c 20 22 44 42 20 43 48   1, objv, "DB CH
5de0: 41 4e 47 45 53 45 54 22 29 3b 0a 20 20 20 20 72  ANGESET");.    r
5df0: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
5e00: 0a 20 20 7d 0a 20 20 69 66 28 20 30 3d 3d 54 63  .  }.  if( 0==Tc
5e10: 6c 5f 47 65 74 43 6f 6d 6d 61 6e 64 49 6e 66 6f  l_GetCommandInfo
5e20: 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74  (interp, Tcl_Get
5e30: 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c  String(objv[1]),
5e40: 20 26 69 6e 66 6f 29 20 29 7b 0a 20 20 20 20 54   &info) ){.    T
5e50: 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28  cl_AppendResult(
5e60: 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75 63 68  interp, "no such
5e70: 20 68 61 6e 64 6c 65 3a 20 22 2c 20 54 63 6c 5f   handle: ", Tcl_
5e80: 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32  GetString(objv[2
5e90: 5d 29 2c 20 30 29 3b 0a 20 20 20 20 72 65 74 75  ]), 0);.    retu
5ea0: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
5eb0: 7d 0a 20 20 64 62 20 3d 20 2a 28 73 71 6c 69 74  }.  db = *(sqlit
5ec0: 65 33 20 2a 2a 29 69 6e 66 6f 2e 6f 62 6a 43 6c  e3 **)info.objCl
5ed0: 69 65 6e 74 44 61 74 61 3b 0a 20 20 70 43 68 61  ientData;.  pCha
5ee0: 6e 67 65 73 65 74 20 3d 20 28 76 6f 69 64 20 2a  ngeset = (void *
5ef0: 29 54 63 6c 5f 47 65 74 42 79 74 65 41 72 72 61  )Tcl_GetByteArra
5f00: 79 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 32 5d  yFromObj(objv[2]
5f10: 2c 20 26 6e 43 68 61 6e 67 65 73 65 74 29 3b 0a  , &nChangeset);.
5f20: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 63  .  rc = sqlite3c
5f30: 68 61 6e 67 65 73 65 74 5f 61 70 70 6c 79 28 64  hangeset_apply(d
5f40: 62 2c 20 6e 43 68 61 6e 67 65 73 65 74 2c 20 70  b, nChangeset, p
5f50: 43 68 61 6e 67 65 73 65 74 2c 20 30 2c 20 72 65  Changeset, 0, re
5f60: 70 6c 61 63 65 5f 68 61 6e 64 6c 65 72 2c 30 29  place_handler,0)
5f70: 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
5f80: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 65 74  TE_OK ){.    ret
5f90: 75 72 6e 20 74 65 73 74 5f 73 65 73 73 69 6f 6e  urn test_session
5fa0: 5f 65 72 72 6f 72 28 69 6e 74 65 72 70 2c 20 72  _error(interp, r
5fb0: 63 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 54 63 6c  c, 0);.  }.  Tcl
5fc0: 5f 52 65 73 65 74 52 65 73 75 6c 74 28 69 6e 74  _ResetResult(int
5fd0: 65 72 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 54  erp);.  return T
5fe0: 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a  CL_OK;.}.../*.**
5ff0: 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
6000: 74 5f 69 6e 76 65 72 74 20 43 48 41 4e 47 45 53  t_invert CHANGES
6010: 45 54 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  ET.*/.static int
6020: 20 53 51 4c 49 54 45 5f 54 43 4c 41 50 49 20 74   SQLITE_TCLAPI t
6030: 65 73 74 5f 73 71 6c 69 74 65 33 63 68 61 6e 67  est_sqlite3chang
6040: 65 73 65 74 5f 69 6e 76 65 72 74 28 0a 20 20 76  eset_invert(.  v
6050: 6f 69 64 20 2a 20 63 6c 69 65 6e 74 44 61 74 61  oid * clientData
6060: 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  ,.  Tcl_Interp *
6070: 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62  interp,.  int ob
6080: 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43  jc,.  Tcl_Obj *C
6090: 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20  ONST objv[].){. 
60a0: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
60b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60c0: 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
60d0: 66 72 6f 6d 20 63 68 61 6e 67 65 73 65 74 5f 69  from changeset_i
60e0: 6e 76 65 72 74 28 29 20 2a 2f 0a 20 20 54 65 73  nvert() */.  Tes
60f0: 74 53 74 72 65 61 6d 49 6e 70 75 74 20 73 49 6e  tStreamInput sIn
6100: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
6110: 49 6e 70 75 74 20 73 74 72 65 61 6d 20 2a 2f 0a  Input stream */.
6120: 20 20 54 65 73 74 53 65 73 73 69 6f 6e 73 42 6c    TestSessionsBl
6130: 6f 62 20 73 4f 75 74 3b 20 20 20 20 20 20 20 20  ob sOut;        
6140: 20 20 2f 2a 20 4f 75 74 70 75 74 20 62 6c 6f 62    /* Output blob
6150: 20 2a 2f 0a 0a 20 20 69 66 28 20 6f 62 6a 63 21   */..  if( objc!
6160: 3d 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72  =2 ){.    Tcl_Wr
6170: 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72  ongNumArgs(inter
6180: 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 43 48 41  p, 1, objv, "CHA
6190: 4e 47 45 53 45 54 22 29 3b 0a 20 20 20 20 72 65  NGESET");.    re
61a0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
61b0: 20 20 7d 0a 0a 20 20 6d 65 6d 73 65 74 28 26 73    }..  memset(&s
61c0: 49 6e 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73 49  In, 0, sizeof(sI
61d0: 6e 29 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 73  n));.  memset(&s
61e0: 4f 75 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73  Out, 0, sizeof(s
61f0: 4f 75 74 29 29 3b 0a 20 20 73 49 6e 2e 6e 53 74  Out));.  sIn.nSt
6200: 72 65 61 6d 20 3d 20 74 65 73 74 5f 74 63 6c 5f  ream = test_tcl_
6210: 69 6e 74 65 67 65 72 28 69 6e 74 65 72 70 2c 20  integer(interp, 
6220: 53 45 53 53 49 4f 4e 5f 53 54 52 45 41 4d 5f 54  SESSION_STREAM_T
6230: 43 4c 5f 56 41 52 29 3b 0a 20 20 73 49 6e 2e 61  CL_VAR);.  sIn.a
6240: 44 61 74 61 20 3d 20 54 63 6c 5f 47 65 74 42 79  Data = Tcl_GetBy
6250: 74 65 41 72 72 61 79 46 72 6f 6d 4f 62 6a 28 6f  teArrayFromObj(o
6260: 62 6a 76 5b 31 5d 2c 20 26 73 49 6e 2e 6e 44 61  bjv[1], &sIn.nDa
6270: 74 61 29 3b 0a 0a 20 20 69 66 28 20 73 49 6e 2e  ta);..  if( sIn.
6280: 6e 53 74 72 65 61 6d 20 29 7b 0a 20 20 20 20 72  nStream ){.    r
6290: 63 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67  c = sqlite3chang
62a0: 65 73 65 74 5f 69 6e 76 65 72 74 5f 73 74 72 6d  eset_invert_strm
62b0: 28 0a 20 20 20 20 20 20 20 20 74 65 73 74 53 74  (.        testSt
62c0: 72 65 61 6d 49 6e 70 75 74 2c 20 28 76 6f 69 64  reamInput, (void
62d0: 2a 29 26 73 49 6e 2c 20 74 65 73 74 53 74 72 65  *)&sIn, testStre
62e0: 61 6d 4f 75 74 70 75 74 2c 20 28 76 6f 69 64 2a  amOutput, (void*
62f0: 29 26 73 4f 75 74 0a 20 20 20 20 29 3b 0a 20 20  )&sOut.    );.  
6300: 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d 20  }else{.    rc = 
6310: 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
6320: 5f 69 6e 76 65 72 74 28 73 49 6e 2e 6e 44 61 74  _invert(sIn.nDat
6330: 61 2c 20 73 49 6e 2e 61 44 61 74 61 2c 20 26 73  a, sIn.aData, &s
6340: 4f 75 74 2e 6e 2c 20 26 73 4f 75 74 2e 70 29 3b  Out.n, &sOut.p);
6350: 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 21 3d 53  .  }.  if( rc!=S
6360: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
6370: 72 63 20 3d 20 74 65 73 74 5f 73 65 73 73 69 6f  rc = test_sessio
6380: 6e 5f 65 72 72 6f 72 28 69 6e 74 65 72 70 2c 20  n_error(interp, 
6390: 72 63 2c 20 30 29 3b 0a 20 20 7d 65 6c 73 65 7b  rc, 0);.  }else{
63a0: 0a 20 20 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52  .    Tcl_SetObjR
63b0: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 54 63 6c  esult(interp,Tcl
63c0: 5f 4e 65 77 42 79 74 65 41 72 72 61 79 4f 62 6a  _NewByteArrayObj
63d0: 28 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 2a  ((unsigned char*
63e0: 29 73 4f 75 74 2e 70 2c 73 4f 75 74 2e 6e 29 29  )sOut.p,sOut.n))
63f0: 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  ;.  }.  sqlite3_
6400: 66 72 65 65 28 73 4f 75 74 2e 70 29 3b 0a 20 20  free(sOut.p);.  
6410: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
6420: 0a 2a 2a 20 73 71 6c 69 74 65 33 63 68 61 6e 67  .** sqlite3chang
6430: 65 73 65 74 5f 63 6f 6e 63 61 74 20 4c 45 46 54  eset_concat LEFT
6440: 20 52 49 47 48 54 0a 2a 2f 0a 73 74 61 74 69 63   RIGHT.*/.static
6450: 20 69 6e 74 20 53 51 4c 49 54 45 5f 54 43 4c 41   int SQLITE_TCLA
6460: 50 49 20 74 65 73 74 5f 73 71 6c 69 74 65 33 63  PI test_sqlite3c
6470: 68 61 6e 67 65 73 65 74 5f 63 6f 6e 63 61 74 28  hangeset_concat(
6480: 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e 74  .  void * client
6490: 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65  Data,.  Tcl_Inte
64a0: 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e  rp *interp,.  in
64b0: 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62  t objc,.  Tcl_Ob
64c0: 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a  j *CONST objv[].
64d0: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20  ){.  int rc;    
64e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
64f0: 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
6500: 6f 64 65 20 66 72 6f 6d 20 63 68 61 6e 67 65 73  ode from changes
6510: 65 74 5f 69 6e 76 65 72 74 28 29 20 2a 2f 0a 0a  et_invert() */..
6520: 20 20 54 65 73 74 53 74 72 65 61 6d 49 6e 70 75    TestStreamInpu
6530: 74 20 73 4c 65 66 74 3b 20 20 20 20 20 20 20 20  t sLeft;        
6540: 20 20 2f 2a 20 49 6e 70 75 74 20 73 74 72 65 61    /* Input strea
6550: 6d 20 2a 2f 0a 20 20 54 65 73 74 53 74 72 65 61  m */.  TestStrea
6560: 6d 49 6e 70 75 74 20 73 52 69 67 68 74 3b 20 20  mInput sRight;  
6570: 20 20 20 20 20 20 20 2f 2a 20 49 6e 70 75 74 20         /* Input 
6580: 73 74 72 65 61 6d 20 2a 2f 0a 20 20 54 65 73 74  stream */.  Test
6590: 53 65 73 73 69 6f 6e 73 42 6c 6f 62 20 73 4f 75  SessionsBlob sOu
65a0: 74 20 3d 20 7b 30 2c 30 7d 3b 20 20 2f 2a 20 4f  t = {0,0};  /* O
65b0: 75 74 70 75 74 20 62 6c 6f 62 20 2a 2f 0a 0a 20  utput blob */.. 
65c0: 20 69 66 28 20 6f 62 6a 63 21 3d 33 20 29 7b 0a   if( objc!=3 ){.
65d0: 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d      Tcl_WrongNum
65e0: 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20  Args(interp, 1, 
65f0: 6f 62 6a 76 2c 20 22 4c 45 46 54 20 52 49 47 48  objv, "LEFT RIGH
6600: 54 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  T");.    return 
6610: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a  TCL_ERROR;.  }..
6620: 20 20 6d 65 6d 73 65 74 28 26 73 4c 65 66 74 2c    memset(&sLeft,
6630: 20 30 2c 20 73 69 7a 65 6f 66 28 73 4c 65 66 74   0, sizeof(sLeft
6640: 29 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 73 52  ));.  memset(&sR
6650: 69 67 68 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28  ight, 0, sizeof(
6660: 73 52 69 67 68 74 29 29 3b 0a 20 20 73 4c 65 66  sRight));.  sLef
6670: 74 2e 61 44 61 74 61 20 3d 20 54 63 6c 5f 47 65  t.aData = Tcl_Ge
6680: 74 42 79 74 65 41 72 72 61 79 46 72 6f 6d 4f 62  tByteArrayFromOb
6690: 6a 28 6f 62 6a 76 5b 31 5d 2c 20 26 73 4c 65 66  j(objv[1], &sLef
66a0: 74 2e 6e 44 61 74 61 29 3b 0a 20 20 73 52 69 67  t.nData);.  sRig
66b0: 68 74 2e 61 44 61 74 61 20 3d 20 54 63 6c 5f 47  ht.aData = Tcl_G
66c0: 65 74 42 79 74 65 41 72 72 61 79 46 72 6f 6d 4f  etByteArrayFromO
66d0: 62 6a 28 6f 62 6a 76 5b 32 5d 2c 20 26 73 52 69  bj(objv[2], &sRi
66e0: 67 68 74 2e 6e 44 61 74 61 29 3b 0a 20 20 73 4c  ght.nData);.  sL
66f0: 65 66 74 2e 6e 53 74 72 65 61 6d 20 3d 20 74 65  eft.nStream = te
6700: 73 74 5f 74 63 6c 5f 69 6e 74 65 67 65 72 28 69  st_tcl_integer(i
6710: 6e 74 65 72 70 2c 20 53 45 53 53 49 4f 4e 5f 53  nterp, SESSION_S
6720: 54 52 45 41 4d 5f 54 43 4c 5f 56 41 52 29 3b 0a  TREAM_TCL_VAR);.
6730: 20 20 73 52 69 67 68 74 2e 6e 53 74 72 65 61 6d    sRight.nStream
6740: 20 3d 20 73 4c 65 66 74 2e 6e 53 74 72 65 61 6d   = sLeft.nStream
6750: 3b 0a 0a 20 20 69 66 28 20 73 4c 65 66 74 2e 6e  ;..  if( sLeft.n
6760: 53 74 72 65 61 6d 3e 30 20 29 7b 0a 20 20 20 20  Stream>0 ){.    
6770: 72 63 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e  rc = sqlite3chan
6780: 67 65 73 65 74 5f 63 6f 6e 63 61 74 5f 73 74 72  geset_concat_str
6790: 6d 28 0a 20 20 20 20 20 20 20 20 74 65 73 74 53  m(.        testS
67a0: 74 72 65 61 6d 49 6e 70 75 74 2c 20 28 76 6f 69  treamInput, (voi
67b0: 64 2a 29 26 73 4c 65 66 74 2c 0a 20 20 20 20 20  d*)&sLeft,.     
67c0: 20 20 20 74 65 73 74 53 74 72 65 61 6d 49 6e 70     testStreamInp
67d0: 75 74 2c 20 28 76 6f 69 64 2a 29 26 73 52 69 67  ut, (void*)&sRig
67e0: 68 74 2c 0a 20 20 20 20 20 20 20 20 74 65 73 74  ht,.        test
67f0: 53 74 72 65 61 6d 4f 75 74 70 75 74 2c 20 28 76  StreamOutput, (v
6800: 6f 69 64 2a 29 26 73 4f 75 74 0a 20 20 20 20 29  oid*)&sOut.    )
6810: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72  ;.  }else{.    r
6820: 63 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67  c = sqlite3chang
6830: 65 73 65 74 5f 63 6f 6e 63 61 74 28 0a 20 20 20  eset_concat(.   
6840: 20 20 20 20 20 73 4c 65 66 74 2e 6e 44 61 74 61       sLeft.nData
6850: 2c 20 73 4c 65 66 74 2e 61 44 61 74 61 2c 20 73  , sLeft.aData, s
6860: 52 69 67 68 74 2e 6e 44 61 74 61 2c 20 73 52 69  Right.nData, sRi
6870: 67 68 74 2e 61 44 61 74 61 2c 20 26 73 4f 75 74  ght.aData, &sOut
6880: 2e 6e 2c 20 26 73 4f 75 74 2e 70 0a 20 20 20 20  .n, &sOut.p.    
6890: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63  );.  }..  if( rc
68a0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
68b0: 20 20 20 72 63 20 3d 20 74 65 73 74 5f 73 65 73     rc = test_ses
68c0: 73 69 6f 6e 5f 65 72 72 6f 72 28 69 6e 74 65 72  sion_error(inter
68d0: 70 2c 20 72 63 2c 20 30 29 3b 0a 20 20 7d 65 6c  p, rc, 0);.  }el
68e0: 73 65 7b 0a 20 20 20 20 54 63 6c 5f 53 65 74 4f  se{.    Tcl_SetO
68f0: 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  bjResult(interp,
6900: 54 63 6c 5f 4e 65 77 42 79 74 65 41 72 72 61 79  Tcl_NewByteArray
6910: 4f 62 6a 28 28 75 6e 73 69 67 6e 65 64 20 63 68  Obj((unsigned ch
6920: 61 72 2a 29 73 4f 75 74 2e 70 2c 73 4f 75 74 2e  ar*)sOut.p,sOut.
6930: 6e 29 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74  n));.  }.  sqlit
6940: 65 33 5f 66 72 65 65 28 73 4f 75 74 2e 70 29 3b  e3_free(sOut.p);
6950: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
6960: 0a 2f 2a 0a 2a 2a 20 73 71 6c 69 74 65 33 73 65  ./*.** sqlite3se
6970: 73 73 69 6f 6e 5f 66 6f 72 65 61 63 68 20 56 41  ssion_foreach VA
6980: 52 4e 41 4d 45 20 43 48 41 4e 47 45 53 45 54 20  RNAME CHANGESET 
6990: 53 43 52 49 50 54 0a 2a 2f 0a 73 74 61 74 69 63  SCRIPT.*/.static
69a0: 20 69 6e 74 20 53 51 4c 49 54 45 5f 54 43 4c 41   int SQLITE_TCLA
69b0: 50 49 20 74 65 73 74 5f 73 71 6c 69 74 65 33 73  PI test_sqlite3s
69c0: 65 73 73 69 6f 6e 5f 66 6f 72 65 61 63 68 28 0a  ession_foreach(.
69d0: 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e 74 44    void * clientD
69e0: 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72  ata,.  Tcl_Inter
69f0: 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74  p *interp,.  int
6a00: 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a   objc,.  Tcl_Obj
6a10: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29   *CONST objv[].)
6a20: 7b 0a 20 20 76 6f 69 64 20 2a 70 43 68 61 6e 67  {.  void *pChang
6a30: 65 73 65 74 3b 0a 20 20 69 6e 74 20 6e 43 68 61  eset;.  int nCha
6a40: 6e 67 65 73 65 74 3b 0a 20 20 73 71 6c 69 74 65  ngeset;.  sqlite
6a50: 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72  3_changeset_iter
6a60: 20 2a 70 49 74 65 72 3b 0a 20 20 69 6e 74 20 72   *pIter;.  int r
6a70: 63 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 56  c;.  Tcl_Obj *pV
6a80: 61 72 6e 61 6d 65 3b 0a 20 20 54 63 6c 5f 4f 62  arname;.  Tcl_Ob
6a90: 6a 20 2a 70 43 53 3b 0a 20 20 54 63 6c 5f 4f 62  j *pCS;.  Tcl_Ob
6aa0: 6a 20 2a 70 53 63 72 69 70 74 3b 0a 20 20 69 6e  j *pScript;.  in
6ab0: 74 20 69 73 43 68 65 63 6b 4e 65 78 74 20 3d 20  t isCheckNext = 
6ac0: 30 3b 0a 0a 20 20 54 65 73 74 53 74 72 65 61 6d  0;..  TestStream
6ad0: 49 6e 70 75 74 20 73 53 74 72 3b 0a 20 20 6d 65  Input sStr;.  me
6ae0: 6d 73 65 74 28 26 73 53 74 72 2c 20 30 2c 20 73  mset(&sStr, 0, s
6af0: 69 7a 65 6f 66 28 73 53 74 72 29 29 3b 0a 0a 20  izeof(sStr));.. 
6b00: 20 69 66 28 20 6f 62 6a 63 3e 31 20 29 7b 0a 20   if( objc>1 ){. 
6b10: 20 20 20 63 68 61 72 20 2a 7a 4f 70 74 20 3d 20     char *zOpt = 
6b20: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62  Tcl_GetString(ob
6b30: 6a 76 5b 31 5d 29 3b 0a 20 20 20 20 69 73 43 68  jv[1]);.    isCh
6b40: 65 63 6b 4e 65 78 74 20 3d 20 28 73 74 72 63 6d  eckNext = (strcm
6b50: 70 28 7a 4f 70 74 2c 20 22 2d 6e 65 78 74 22 29  p(zOpt, "-next")
6b60: 3d 3d 30 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20  ==0);.  }.  if( 
6b70: 6f 62 6a 63 21 3d 34 2b 69 73 43 68 65 63 6b 4e  objc!=4+isCheckN
6b80: 65 78 74 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57  ext ){.    Tcl_W
6b90: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
6ba0: 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 3f 2d  rp, 1, objv, "?-
6bb0: 6e 65 78 74 3f 20 56 41 52 4e 41 4d 45 20 43 48  next? VARNAME CH
6bc0: 41 4e 47 45 53 45 54 20 53 43 52 49 50 54 22 29  ANGESET SCRIPT")
6bd0: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c  ;.    return TCL
6be0: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 70  _ERROR;.  }..  p
6bf0: 56 61 72 6e 61 6d 65 20 3d 20 6f 62 6a 76 5b 31  Varname = objv[1
6c00: 2b 69 73 43 68 65 63 6b 4e 65 78 74 5d 3b 0a 20  +isCheckNext];. 
6c10: 20 70 43 53 20 3d 20 6f 62 6a 76 5b 32 2b 69 73   pCS = objv[2+is
6c20: 43 68 65 63 6b 4e 65 78 74 5d 3b 0a 20 20 70 53  CheckNext];.  pS
6c30: 63 72 69 70 74 20 3d 20 6f 62 6a 76 5b 33 2b 69  cript = objv[3+i
6c40: 73 43 68 65 63 6b 4e 65 78 74 5d 3b 0a 0a 20 20  sCheckNext];..  
6c50: 70 43 68 61 6e 67 65 73 65 74 20 3d 20 28 76 6f  pChangeset = (vo
6c60: 69 64 20 2a 29 54 63 6c 5f 47 65 74 42 79 74 65  id *)Tcl_GetByte
6c70: 41 72 72 61 79 46 72 6f 6d 4f 62 6a 28 70 43 53  ArrayFromObj(pCS
6c80: 2c 20 26 6e 43 68 61 6e 67 65 73 65 74 29 3b 0a  , &nChangeset);.
6c90: 20 20 73 53 74 72 2e 6e 53 74 72 65 61 6d 20 3d    sStr.nStream =
6ca0: 20 74 65 73 74 5f 74 63 6c 5f 69 6e 74 65 67 65   test_tcl_intege
6cb0: 72 28 69 6e 74 65 72 70 2c 20 53 45 53 53 49 4f  r(interp, SESSIO
6cc0: 4e 5f 53 54 52 45 41 4d 5f 54 43 4c 5f 56 41 52  N_STREAM_TCL_VAR
6cd0: 29 3b 0a 20 20 69 66 28 20 73 53 74 72 2e 6e 53  );.  if( sStr.nS
6ce0: 74 72 65 61 6d 3d 3d 30 20 29 7b 0a 20 20 20 20  tream==0 ){.    
6cf0: 72 63 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e  rc = sqlite3chan
6d00: 67 65 73 65 74 5f 73 74 61 72 74 28 26 70 49 74  geset_start(&pIt
6d10: 65 72 2c 20 6e 43 68 61 6e 67 65 73 65 74 2c 20  er, nChangeset, 
6d20: 70 43 68 61 6e 67 65 73 65 74 29 3b 0a 20 20 7d  pChangeset);.  }
6d30: 65 6c 73 65 7b 0a 20 20 20 20 73 53 74 72 2e 61  else{.    sStr.a
6d40: 44 61 74 61 20 3d 20 28 75 6e 73 69 67 6e 65 64  Data = (unsigned
6d50: 20 63 68 61 72 2a 29 70 43 68 61 6e 67 65 73 65   char*)pChangese
6d60: 74 3b 0a 20 20 20 20 73 53 74 72 2e 6e 44 61 74  t;.    sStr.nDat
6d70: 61 20 3d 20 6e 43 68 61 6e 67 65 73 65 74 3b 0a  a = nChangeset;.
6d80: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
6d90: 63 68 61 6e 67 65 73 65 74 5f 73 74 61 72 74 5f  changeset_start_
6da0: 73 74 72 6d 28 26 70 49 74 65 72 2c 20 74 65 73  strm(&pIter, tes
6db0: 74 53 74 72 65 61 6d 49 6e 70 75 74 2c 20 28 76  tStreamInput, (v
6dc0: 6f 69 64 2a 29 26 73 53 74 72 29 3b 0a 20 20 7d  oid*)&sStr);.  }
6dd0: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
6de0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 65 74 75  E_OK ){.    retu
6df0: 72 6e 20 74 65 73 74 5f 73 65 73 73 69 6f 6e 5f  rn test_session_
6e00: 65 72 72 6f 72 28 69 6e 74 65 72 70 2c 20 72 63  error(interp, rc
6e10: 2c 20 30 29 3b 0a 20 20 7d 0a 0a 20 20 77 68 69  , 0);.  }..  whi
6e20: 6c 65 28 20 53 51 4c 49 54 45 5f 52 4f 57 3d 3d  le( SQLITE_ROW==
6e30: 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
6e40: 5f 6e 65 78 74 28 70 49 74 65 72 29 20 29 7b 0a  _next(pIter) ){.
6e50: 20 20 20 20 69 6e 74 20 6e 43 6f 6c 3b 20 20 20      int nCol;   
6e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6e70: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63    /* Number of c
6e80: 6f 6c 75 6d 6e 73 20 69 6e 20 74 61 62 6c 65 20  olumns in table 
6e90: 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 43 6f 6c 32  */.    int nCol2
6ea0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
6eb0: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
6ec0: 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 61 62  f columns in tab
6ed0: 6c 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6f 70  le */.    int op
6ee0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
6ef0: 20 20 20 20 20 20 20 20 2f 2a 20 53 51 4c 49 54          /* SQLIT
6f00: 45 5f 49 4e 53 45 52 54 2c 20 55 50 44 41 54 45  E_INSERT, UPDATE
6f10: 20 6f 72 20 44 45 4c 45 54 45 20 2a 2f 0a 20 20   or DELETE */.  
6f20: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54    const char *zT
6f30: 61 62 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ab;             
6f40: 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 61 62 6c 65  /* Name of table
6f50: 20 63 68 61 6e 67 65 20 61 70 70 6c 69 65 73 20   change applies 
6f60: 74 6f 20 2a 2f 0a 20 20 20 20 54 63 6c 5f 4f 62  to */.    Tcl_Ob
6f70: 6a 20 2a 70 56 61 72 3b 20 20 20 20 20 20 20 20  j *pVar;        
6f80: 20 20 20 20 20 20 20 20 2f 2a 20 54 63 6c 20 76          /* Tcl v
6f90: 61 6c 75 65 20 74 6f 20 73 65 74 20 24 56 41 52  alue to set $VAR
6fa0: 4e 41 4d 45 20 74 6f 20 2a 2f 0a 20 20 20 20 54  NAME to */.    T
6fb0: 63 6c 5f 4f 62 6a 20 2a 70 4f 6c 64 3b 20 20 20  cl_Obj *pOld;   
6fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6fd0: 56 65 63 74 6f 72 20 6f 66 20 6f 6c 64 2e 2a 20  Vector of old.* 
6fe0: 76 61 6c 75 65 73 20 2a 2f 0a 20 20 20 20 54 63  values */.    Tc
6ff0: 6c 5f 4f 62 6a 20 2a 70 4e 65 77 3b 20 20 20 20  l_Obj *pNew;    
7000: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56              /* V
7010: 65 63 74 6f 72 20 6f 66 20 6e 65 77 2e 2a 20 76  ector of new.* v
7020: 61 6c 75 65 73 20 2a 2f 0a 20 20 20 20 69 6e 74  alues */.    int
7030: 20 62 49 6e 64 69 72 65 63 74 3b 0a 0a 20 20 20   bIndirect;..   
7040: 20 63 68 61 72 20 2a 7a 50 4b 3b 0a 20 20 20 20   char *zPK;.    
7050: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 61  unsigned char *a
7060: 62 50 4b 3b 0a 20 20 20 20 69 6e 74 20 69 3b 0a  bPK;.    int i;.
7070: 0a 20 20 20 20 2f 2a 20 54 65 73 74 20 74 68 61  .    /* Test tha
7080: 74 20 5f 66 6b 5f 63 6f 6e 66 6c 69 63 74 73 28  t _fk_conflicts(
7090: 29 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45  ) returns SQLITE
70a0: 5f 4d 49 53 55 53 45 20 69 66 20 63 61 6c 6c 65  _MISUSE if calle
70b0: 64 20 6f 6e 20 74 68 69 73 0a 20 20 20 20 2a 2a  d on this.    **
70c0: 20 69 74 65 72 61 74 6f 72 2e 20 2a 2f 0a 20 20   iterator. */.  
70d0: 20 20 69 6e 74 20 6e 44 75 6d 6d 79 3b 0a 20 20    int nDummy;.  
70e0: 20 20 69 66 28 20 53 51 4c 49 54 45 5f 4d 49 53    if( SQLITE_MIS
70f0: 55 53 45 21 3d 73 71 6c 69 74 65 33 63 68 61 6e  USE!=sqlite3chan
7100: 67 65 73 65 74 5f 66 6b 5f 63 6f 6e 66 6c 69 63  geset_fk_conflic
7110: 74 73 28 70 49 74 65 72 2c 20 26 6e 44 75 6d 6d  ts(pIter, &nDumm
7120: 79 29 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69  y) ){.      sqli
7130: 74 65 33 63 68 61 6e 67 65 73 65 74 5f 66 69 6e  te3changeset_fin
7140: 61 6c 69 7a 65 28 70 49 74 65 72 29 3b 0a 20 20  alize(pIter);.  
7150: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
7160: 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  RROR;.    }..   
7170: 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
7180: 74 5f 6f 70 28 70 49 74 65 72 2c 20 26 7a 54 61  t_op(pIter, &zTa
7190: 62 2c 20 26 6e 43 6f 6c 2c 20 26 6f 70 2c 20 26  b, &nCol, &op, &
71a0: 62 49 6e 64 69 72 65 63 74 29 3b 0a 20 20 20 20  bIndirect);.    
71b0: 70 56 61 72 20 3d 20 54 63 6c 5f 4e 65 77 4f 62  pVar = Tcl_NewOb
71c0: 6a 28 29 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73  j();.    Tcl_Lis
71d0: 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e  tObjAppendElemen
71e0: 74 28 30 2c 20 70 56 61 72 2c 20 54 63 6c 5f 4e  t(0, pVar, Tcl_N
71f0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 0a 20 20 20  ewStringObj(.   
7200: 20 20 20 20 20 20 20 6f 70 3d 3d 53 51 4c 49 54         op==SQLIT
7210: 45 5f 49 4e 53 45 52 54 20 3f 20 22 49 4e 53 45  E_INSERT ? "INSE
7220: 52 54 22 20 3a 0a 20 20 20 20 20 20 20 20 20 20  RT" :.          
7230: 6f 70 3d 3d 53 51 4c 49 54 45 5f 55 50 44 41 54  op==SQLITE_UPDAT
7240: 45 20 3f 20 22 55 50 44 41 54 45 22 20 3a 20 0a  E ? "UPDATE" : .
7250: 20 20 20 20 20 20 20 20 20 20 22 44 45 4c 45 54            "DELET
7260: 45 22 2c 20 2d 31 0a 20 20 20 20 29 29 3b 0a 0a  E", -1.    ));..
7270: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
7280: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20  ppendElement(0, 
7290: 70 56 61 72 2c 20 54 63 6c 5f 4e 65 77 53 74 72  pVar, Tcl_NewStr
72a0: 69 6e 67 4f 62 6a 28 7a 54 61 62 2c 20 2d 31 29  ingObj(zTab, -1)
72b0: 29 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f  );.    Tcl_ListO
72c0: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
72d0: 30 2c 20 70 56 61 72 2c 20 54 63 6c 5f 4e 65 77  0, pVar, Tcl_New
72e0: 42 6f 6f 6c 65 61 6e 4f 62 6a 28 62 49 6e 64 69  BooleanObj(bIndi
72f0: 72 65 63 74 29 29 3b 0a 0a 20 20 20 20 7a 50 4b  rect));..    zPK
7300: 20 3d 20 63 6b 61 6c 6c 6f 63 28 6e 43 6f 6c 2b   = ckalloc(nCol+
7310: 31 29 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28 7a  1);.    memset(z
7320: 50 4b 2c 20 30 2c 20 6e 43 6f 6c 2b 31 29 3b 0a  PK, 0, nCol+1);.
7330: 20 20 20 20 73 71 6c 69 74 65 33 63 68 61 6e 67      sqlite3chang
7340: 65 73 65 74 5f 70 6b 28 70 49 74 65 72 2c 20 26  eset_pk(pIter, &
7350: 61 62 50 4b 2c 20 26 6e 43 6f 6c 32 29 3b 0a 20  abPK, &nCol2);. 
7360: 20 20 20 61 73 73 65 72 74 28 20 6e 43 6f 6c 3d     assert( nCol=
7370: 3d 6e 43 6f 6c 32 20 29 3b 0a 20 20 20 20 66 6f  =nCol2 );.    fo
7380: 72 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c 3b 20 69  r(i=0; i<nCol; i
7390: 2b 2b 29 7b 0a 20 20 20 20 20 20 7a 50 4b 5b 69  ++){.      zPK[i
73a0: 5d 20 3d 20 28 61 62 50 4b 5b 69 5d 20 3f 20 27  ] = (abPK[i] ? '
73b0: 58 27 20 3a 20 27 2e 27 29 3b 0a 20 20 20 20 7d  X' : '.');.    }
73c0: 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  .    Tcl_ListObj
73d0: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c  AppendElement(0,
73e0: 20 70 56 61 72 2c 20 54 63 6c 5f 4e 65 77 53 74   pVar, Tcl_NewSt
73f0: 72 69 6e 67 4f 62 6a 28 7a 50 4b 2c 20 2d 31 29  ringObj(zPK, -1)
7400: 29 3b 0a 20 20 20 20 63 6b 66 72 65 65 28 7a 50  );.    ckfree(zP
7410: 4b 29 3b 0a 0a 20 20 20 20 70 4f 6c 64 20 3d 20  K);..    pOld = 
7420: 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20  Tcl_NewObj();.  
7430: 20 20 69 66 28 20 6f 70 21 3d 53 51 4c 49 54 45    if( op!=SQLITE
7440: 5f 49 4e 53 45 52 54 20 29 7b 0a 20 20 20 20 20  _INSERT ){.     
7450: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c   for(i=0; i<nCol
7460: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
7470: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70  sqlite3_value *p
7480: 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 73 71 6c  Val;.        sql
7490: 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f 6c  ite3changeset_ol
74a0: 64 28 70 49 74 65 72 2c 20 69 2c 20 26 70 56 61  d(pIter, i, &pVa
74b0: 6c 29 3b 0a 20 20 20 20 20 20 20 20 74 65 73 74  l);.        test
74c0: 5f 61 70 70 65 6e 64 5f 76 61 6c 75 65 28 70 4f  _append_value(pO
74d0: 6c 64 2c 20 70 56 61 6c 29 3b 0a 20 20 20 20 20  ld, pVal);.     
74e0: 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 70 4e 65   }.    }.    pNe
74f0: 77 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29  w = Tcl_NewObj()
7500: 3b 0a 20 20 20 20 69 66 28 20 6f 70 21 3d 53 51  ;.    if( op!=SQ
7510: 4c 49 54 45 5f 44 45 4c 45 54 45 20 29 7b 0a 20  LITE_DELETE ){. 
7520: 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c       for(i=0; i<
7530: 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  nCol; i++){.    
7540: 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75      sqlite3_valu
7550: 65 20 2a 70 56 61 6c 3b 0a 20 20 20 20 20 20 20  e *pVal;.       
7560: 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
7570: 74 5f 6e 65 77 28 70 49 74 65 72 2c 20 69 2c 20  t_new(pIter, i, 
7580: 26 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 20 20  &pVal);.        
7590: 74 65 73 74 5f 61 70 70 65 6e 64 5f 76 61 6c 75  test_append_valu
75a0: 65 28 70 4e 65 77 2c 20 70 56 61 6c 29 3b 0a 20  e(pNew, pVal);. 
75b0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
75c0: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
75d0: 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 56 61  ndElement(0, pVa
75e0: 72 2c 20 70 4f 6c 64 29 3b 0a 20 20 20 20 54 63  r, pOld);.    Tc
75f0: 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45  l_ListObjAppendE
7600: 6c 65 6d 65 6e 74 28 30 2c 20 70 56 61 72 2c 20  lement(0, pVar, 
7610: 70 4e 65 77 29 3b 0a 0a 20 20 20 20 54 63 6c 5f  pNew);..    Tcl_
7620: 4f 62 6a 53 65 74 56 61 72 32 28 69 6e 74 65 72  ObjSetVar2(inter
7630: 70 2c 20 70 56 61 72 6e 61 6d 65 2c 20 30 2c 20  p, pVarname, 0, 
7640: 70 56 61 72 2c 20 30 29 3b 0a 20 20 20 20 72 63  pVar, 0);.    rc
7650: 20 3d 20 54 63 6c 5f 45 76 61 6c 4f 62 6a 45 78   = Tcl_EvalObjEx
7660: 28 69 6e 74 65 72 70 2c 20 70 53 63 72 69 70 74  (interp, pScript
7670: 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 72 63  , 0);.    if( rc
7680: 21 3d 54 43 4c 5f 4f 4b 20 26 26 20 72 63 21 3d  !=TCL_OK && rc!=
7690: 54 43 4c 5f 43 4f 4e 54 49 4e 55 45 20 29 7b 0a  TCL_CONTINUE ){.
76a0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 63 68 61        sqlite3cha
76b0: 6e 67 65 73 65 74 5f 66 69 6e 61 6c 69 7a 65 28  ngeset_finalize(
76c0: 70 49 74 65 72 29 3b 0a 20 20 20 20 20 20 72 65  pIter);.      re
76d0: 74 75 72 6e 20 72 63 3d 3d 54 43 4c 5f 42 52 45  turn rc==TCL_BRE
76e0: 41 4b 20 3f 20 54 43 4c 5f 4f 4b 20 3a 20 72 63  AK ? TCL_OK : rc
76f0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  ;.    }.  }..  i
7700: 66 28 20 69 73 43 68 65 63 6b 4e 65 78 74 20 29  f( isCheckNext )
7710: 7b 0a 20 20 20 20 69 6e 74 20 72 63 32 20 3d 20  {.    int rc2 = 
7720: 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
7730: 5f 6e 65 78 74 28 70 49 74 65 72 29 3b 0a 20 20  _next(pIter);.  
7740: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 63 68    rc = sqlite3ch
7750: 61 6e 67 65 73 65 74 5f 66 69 6e 61 6c 69 7a 65  angeset_finalize
7760: 28 70 49 74 65 72 29 3b 0a 20 20 20 20 61 73 73  (pIter);.    ass
7770: 65 72 74 28 20 28 72 63 32 3d 3d 53 51 4c 49 54  ert( (rc2==SQLIT
7780: 45 5f 44 4f 4e 45 20 26 26 20 72 63 3d 3d 53 51  E_DONE && rc==SQ
7790: 4c 49 54 45 5f 4f 4b 29 20 7c 7c 20 72 63 32 3d  LITE_OK) || rc2=
77a0: 3d 72 63 20 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  =rc );.  }else{.
77b0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
77c0: 63 68 61 6e 67 65 73 65 74 5f 66 69 6e 61 6c 69  changeset_finali
77d0: 7a 65 28 70 49 74 65 72 29 3b 0a 20 20 7d 0a 20  ze(pIter);.  }. 
77e0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
77f0: 4f 4b 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  OK ){.    return
7800: 20 74 65 73 74 5f 73 65 73 73 69 6f 6e 5f 65 72   test_session_er
7810: 72 6f 72 28 69 6e 74 65 72 70 2c 20 72 63 2c 20  ror(interp, rc, 
7820: 30 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  0);.  }..  retur
7830: 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 69 6e 74  n TCL_OK;.}..int
7840: 20 54 65 73 74 53 65 73 73 69 6f 6e 5f 49 6e 69   TestSession_Ini
7850: 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  t(Tcl_Interp *in
7860: 74 65 72 70 29 7b 0a 20 20 73 74 72 75 63 74 20  terp){.  struct 
7870: 43 6d 64 20 7b 0a 20 20 20 20 63 6f 6e 73 74 20  Cmd {.    const 
7880: 63 68 61 72 20 2a 7a 43 6d 64 3b 0a 20 20 20 20  char *zCmd;.    
7890: 54 63 6c 5f 4f 62 6a 43 6d 64 50 72 6f 63 20 2a  Tcl_ObjCmdProc *
78a0: 78 50 72 6f 63 3b 0a 20 20 7d 20 61 43 6d 64 5b  xProc;.  } aCmd[
78b0: 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 22 73 71 6c  ] = {.    { "sql
78c0: 69 74 65 33 73 65 73 73 69 6f 6e 22 2c 20 74 65  ite3session", te
78d0: 73 74 5f 73 71 6c 69 74 65 33 73 65 73 73 69 6f  st_sqlite3sessio
78e0: 6e 20 7d 2c 0a 20 20 20 20 7b 20 22 73 71 6c 69  n },.    { "sqli
78f0: 74 65 33 73 65 73 73 69 6f 6e 5f 66 6f 72 65 61  te3session_forea
7900: 63 68 22 2c 20 74 65 73 74 5f 73 71 6c 69 74 65  ch", test_sqlite
7910: 33 73 65 73 73 69 6f 6e 5f 66 6f 72 65 61 63 68  3session_foreach
7920: 20 7d 2c 0a 20 20 20 20 7b 20 22 73 71 6c 69 74   },.    { "sqlit
7930: 65 33 63 68 61 6e 67 65 73 65 74 5f 69 6e 76 65  e3changeset_inve
7940: 72 74 22 2c 20 74 65 73 74 5f 73 71 6c 69 74 65  rt", test_sqlite
7950: 33 63 68 61 6e 67 65 73 65 74 5f 69 6e 76 65 72  3changeset_inver
7960: 74 20 7d 2c 0a 20 20 20 20 7b 20 22 73 71 6c 69  t },.    { "sqli
7970: 74 65 33 63 68 61 6e 67 65 73 65 74 5f 63 6f 6e  te3changeset_con
7980: 63 61 74 22 2c 20 74 65 73 74 5f 73 71 6c 69 74  cat", test_sqlit
7990: 65 33 63 68 61 6e 67 65 73 65 74 5f 63 6f 6e 63  e3changeset_conc
79a0: 61 74 20 7d 2c 0a 20 20 20 20 7b 20 22 73 71 6c  at },.    { "sql
79b0: 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 61 70  ite3changeset_ap
79c0: 70 6c 79 22 2c 20 74 65 73 74 5f 73 71 6c 69 74  ply", test_sqlit
79d0: 65 33 63 68 61 6e 67 65 73 65 74 5f 61 70 70 6c  e3changeset_appl
79e0: 79 20 7d 2c 0a 20 20 20 20 7b 20 22 73 71 6c 69  y },.    { "sqli
79f0: 74 65 33 63 68 61 6e 67 65 73 65 74 5f 61 70 70  te3changeset_app
7a00: 6c 79 5f 72 65 70 6c 61 63 65 5f 61 6c 6c 22 2c  ly_replace_all",
7a10: 20 0a 20 20 20 20 20 20 74 65 73 74 5f 73 71 6c   .      test_sql
7a20: 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 61 70  ite3changeset_ap
7a30: 70 6c 79 5f 72 65 70 6c 61 63 65 5f 61 6c 6c 20  ply_replace_all 
7a40: 7d 2c 0a 20 20 20 20 7b 20 22 73 71 6c 5f 65 78  },.    { "sql_ex
7a50: 65 63 5f 63 68 61 6e 67 65 73 65 74 22 2c 20 74  ec_changeset", t
7a60: 65 73 74 5f 73 71 6c 5f 65 78 65 63 5f 63 68 61  est_sql_exec_cha
7a70: 6e 67 65 73 65 74 20 7d 2c 0a 20 20 7d 3b 0a 20  ngeset },.  };. 
7a80: 20 69 6e 74 20 69 3b 0a 0a 20 20 66 6f 72 28 69   int i;..  for(i
7a90: 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61 43 6d  =0; i<sizeof(aCm
7aa0: 64 29 2f 73 69 7a 65 6f 66 28 73 74 72 75 63 74  d)/sizeof(struct
7ab0: 20 43 6d 64 29 3b 20 69 2b 2b 29 7b 0a 20 20 20   Cmd); i++){.   
7ac0: 20 73 74 72 75 63 74 20 43 6d 64 20 2a 70 20 3d   struct Cmd *p =
7ad0: 20 26 61 43 6d 64 5b 69 5d 3b 0a 20 20 20 20 54   &aCmd[i];.    T
7ae0: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
7af0: 61 6e 64 28 69 6e 74 65 72 70 2c 20 70 2d 3e 7a  and(interp, p->z
7b00: 43 6d 64 2c 20 70 2d 3e 78 50 72 6f 63 2c 20 30  Cmd, p->xProc, 0
7b10: 2c 20 30 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  , 0);.  }..  ret
7b20: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 23  urn TCL_OK;.}..#
7b30: 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f  endif /* SQLITE_
7b40: 54 45 53 54 20 26 26 20 53 51 4c 49 54 45 5f 53  TEST && SQLITE_S
7b50: 45 53 53 49 4f 4e 20 26 26 20 53 51 4c 49 54 45  ESSION && SQLITE
7b60: 5f 50 52 45 55 50 44 41 54 45 5f 48 4f 4f 4b 20  _PREUPDATE_HOOK 
7b70: 2a 2f 0a                                         */.