Fossil

Hex Artifact Content
Login

Artifact f16dc0d7df22821df3e1bd75f2de2e3654b828eb88e881f60e8b7f87616f3769:


0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20  /*.** Copyright 
0010: 28 63 29 20 32 30 30 37 20 44 2e 20 52 69 63 68  (c) 2007 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54  ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66  his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f  ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75  u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20  te it and/or.** 
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20  modify it under 
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65  the terms of the
0090: 20 53 69 6d 70 6c 69 66 69 65 64 20 42 53 44 20   Simplified BSD 
00a0: 4c 69 63 65 6e 73 65 20 28 61 6c 73 6f 0a 2a 2a  License (also.**
00b0: 20 6b 6e 6f 77 6e 20 61 73 20 74 68 65 20 22 32   known as the "2
00c0: 2d 43 6c 61 75 73 65 20 4c 69 63 65 6e 73 65 22  -Clause License"
00d0: 20 6f 72 20 22 46 72 65 65 42 53 44 20 4c 69 63   or "FreeBSD Lic
00e0: 65 6e 73 65 22 2e 29 0a 0a 2a 2a 20 54 68 69 73  ense".)..** This
00f0: 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 73 74   program is dist
0100: 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 20 68  ributed in the h
0110: 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 6c 6c  ope that it will
0120: 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a 20 62   be useful,.** b
0130: 75 74 20 77 69 74 68 6f 75 74 20 61 6e 79 20 77  ut without any w
0140: 61 72 72 61 6e 74 79 3b 20 77 69 74 68 6f 75 74  arranty; without
0150: 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69 65   even the implie
0160: 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 2a 2a  d warranty of.**
0170: 20 6d 65 72 63 68 61 6e 74 61 62 69 6c 69 74 79   merchantability
0180: 20 6f 72 20 66 69 74 6e 65 73 73 20 66 6f 72 20   or fitness for 
0190: 61 20 70 61 72 74 69 63 75 6c 61 72 20 70 75 72  a particular pur
01a0: 70 6f 73 65 2e 0a 2a 2a 0a 2a 2a 20 41 75 74 68  pose..**.** Auth
01b0: 6f 72 20 63 6f 6e 74 61 63 74 20 69 6e 66 6f 72  or contact infor
01c0: 6d 61 74 69 6f 6e 3a 0a 2a 2a 20 20 20 64 72 68  mation:.**   drh
01d0: 40 68 77 61 63 69 2e 63 6f 6d 0a 2a 2a 20 20 20  @hwaci.com.**   
01e0: 68 74 74 70 3a 2f 2f 77 77 77 2e 68 77 61 63 69  http://www.hwaci
01f0: 2e 63 6f 6d 2f 64 72 68 2f 0a 2a 2a 0a 2a 2a 2a  .com/drh/.**.***
0200: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0210: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0220: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0230: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0240: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 0a  ************.**.
0250: 2a 2a 20 54 68 69 73 20 66 69 6c 65 20 63 6f 6e  ** This file con
0260: 74 61 69 6e 73 20 63 6f 64 65 20 75 73 65 64 20  tains code used 
0270: 74 6f 20 66 69 6e 64 20 74 68 65 20 6d 6f 73 74  to find the most
0280: 20 72 65 63 65 6e 74 20 63 6f 6d 6d 6f 6e 0a 2a   recent common.*
0290: 2a 20 61 6e 63 65 73 74 6f 72 20 6f 66 20 74 69  * ancestor of ti
02a0: 6d 65 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 74  me versions of t
02b0: 68 65 20 73 61 6d 65 20 66 69 6c 65 2e 20 20 57  he same file.  W
02c0: 65 20 63 61 6c 6c 20 74 68 69 73 0a 2a 2a 20 63  e call this.** c
02d0: 6f 6d 6d 6f 6e 20 61 6e 63 65 73 74 6f 72 20 74  ommon ancestor t
02e0: 68 65 20 22 70 69 76 6f 74 22 20 69 6e 20 61 20  he "pivot" in a 
02f0: 33 2d 77 61 79 20 6d 65 72 67 65 2e 0a 2a 2f 0a  3-way merge..*/.
0300: 23 69 6e 63 6c 75 64 65 20 22 63 6f 6e 66 69 67  #include "config
0310: 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 70 69  .h".#include "pi
0320: 76 6f 74 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20  vot.h".#include 
0330: 3c 61 73 73 65 72 74 2e 68 3e 0a 0a 0a 2f 2a 0a  <assert.h>.../*.
0340: 2a 2a 20 53 65 74 20 74 68 65 20 70 72 69 6d 61  ** Set the prima
0350: 72 79 20 66 69 6c 65 2e 20 20 54 68 65 20 70 72  ry file.  The pr
0360: 69 6d 61 72 79 20 76 65 72 73 69 6f 6e 20 69 73  imary version is
0370: 20 6f 6e 65 20 6f 66 20 74 68 65 20 74 77 6f 0a   one of the two.
0380: 2a 2a 20 66 69 6c 65 73 20 74 68 61 74 20 68 61  ** files that ha
0390: 76 65 20 61 20 63 6f 6d 6d 6f 6e 20 61 6e 63 65  ve a common ance
03a0: 73 74 6f 72 2e 20 20 54 68 65 20 6f 74 68 65 72  stor.  The other
03b0: 20 66 69 6c 65 20 69 73 20 74 68 65 20 73 65 63   file is the sec
03c0: 6f 6e 64 61 72 79 2e 0a 2a 2a 20 54 68 65 72 65  ondary..** There
03d0: 20 63 61 6e 20 62 65 20 6d 75 6c 74 69 70 6c 65   can be multiple
03e0: 20 73 65 63 6f 6e 64 61 72 69 65 73 20 62 75 74   secondaries but
03f0: 20 6f 6e 6c 79 20 61 20 73 69 6e 67 6c 65 20 70   only a single p
0400: 72 69 6d 61 72 79 2e 0a 2a 2a 20 54 68 65 20 70  rimary..** The p
0410: 72 69 6d 61 72 79 20 6d 75 73 74 20 62 65 20 73  rimary must be s
0420: 65 74 20 66 69 72 73 74 2e 0a 2a 2a 0a 2a 2a 20  et first..**.** 
0430: 49 6e 20 74 68 65 20 6d 65 72 67 65 20 61 6c 67  In the merge alg
0440: 6f 72 69 74 68 6d 2c 20 74 68 65 20 66 69 6c 65  orithm, the file
0450: 20 62 65 69 6e 67 20 6d 65 72 67 65 64 20 69 6e   being merged in
0460: 20 69 73 20 74 68 65 20 70 72 69 6d 61 72 79 2e   is the primary.
0470: 0a 2a 2a 20 54 68 65 20 63 75 72 72 65 6e 74 20  .** The current 
0480: 63 68 65 63 6b 2d 6f 75 74 20 6f 72 20 6f 74 68  check-out or oth
0490: 65 72 20 66 69 6c 65 73 20 74 68 61 74 20 68 61  er files that ha
04a0: 76 65 20 62 65 65 6e 20 6d 65 72 67 65 64 20 69  ve been merged i
04b0: 6e 74 6f 0a 2a 2a 20 74 68 65 20 63 75 72 72 65  nto.** the curre
04c0: 6e 74 20 63 68 65 63 6b 6f 75 74 20 61 72 65 20  nt checkout are 
04d0: 74 68 65 20 73 65 63 6f 6e 64 61 72 69 65 73 2e  the secondaries.
04e0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 63 74 20 6f  .**.** The act o
04f0: 66 20 73 65 74 74 69 6e 67 20 74 68 65 20 70 72  f setting the pr
0500: 69 6d 61 72 79 20 72 65 73 65 74 73 20 74 68 65  imary resets the
0510: 20 70 69 76 6f 74 2d 66 69 6e 64 69 6e 67 20 61   pivot-finding a
0520: 6c 67 6f 72 69 74 68 6d 2e 0a 2a 2f 0a 76 6f 69  lgorithm..*/.voi
0530: 64 20 70 69 76 6f 74 5f 73 65 74 5f 70 72 69 6d  d pivot_set_prim
0540: 61 72 79 28 69 6e 74 20 72 69 64 29 7b 0a 20 20  ary(int rid){.  
0550: 2f 2a 20 53 65 74 20 75 70 20 74 61 62 6c 65 20  /* Set up table 
0560: 75 73 65 64 20 74 6f 20 64 6f 20 74 68 65 20 73  used to do the s
0570: 65 61 72 63 68 20 2a 2f 0a 20 20 64 62 5f 6d 75  earch */.  db_mu
0580: 6c 74 69 5f 65 78 65 63 28 0a 20 20 20 20 22 43  lti_exec(.    "C
0590: 52 45 41 54 45 20 54 45 4d 50 20 54 41 42 4c 45  REATE TEMP TABLE
05a0: 20 49 46 20 4e 4f 54 20 45 58 49 53 54 53 20 61   IF NOT EXISTS a
05b0: 71 75 65 75 65 28 22 0a 20 20 20 20 22 20 20 72  queue(".    "  r
05c0: 69 64 20 49 4e 54 45 47 45 52 2c 22 20 20 20 20  id INTEGER,"    
05d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
05e0: 20 72 65 63 6f 72 64 20 69 64 20 66 6f 72 20 74   record id for t
05f0: 68 69 73 20 76 65 72 73 69 6f 6e 20 2a 2f 0a 20  his version */. 
0600: 20 20 20 22 20 20 6d 74 69 6d 65 20 52 45 41 4c     "  mtime REAL
0610: 2c 22 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,"              
0620: 20 2f 2a 20 54 69 6d 65 20 77 68 65 6e 20 74 68   /* Time when th
0630: 69 73 20 76 65 72 73 69 6f 6e 20 77 61 73 20 63  is version was c
0640: 72 65 61 74 65 64 20 2a 2f 0a 20 20 20 20 22 20  reated */.    " 
0650: 20 70 65 6e 64 69 6e 67 20 42 4f 4f 4c 45 41 4e   pending BOOLEAN
0660: 2c 22 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54  ,"          /* T
0670: 72 75 65 20 69 66 20 77 65 20 68 61 76 65 20 6e  rue if we have n
0680: 6f 74 20 63 68 65 63 6b 20 74 68 69 73 20 6f 6e  ot check this on
0690: 65 20 79 65 74 20 2a 2f 0a 20 20 20 20 22 20 20  e yet */.    "  
06a0: 73 72 63 20 42 4f 4f 4c 45 41 4e 2c 22 20 20 20  src BOOLEAN,"   
06b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 31              /* 1
06c0: 20 66 6f 72 20 70 72 69 6d 61 72 79 2e 20 20 30   for primary.  0
06d0: 20 66 6f 72 20 6f 74 68 65 72 73 20 2a 2f 0a 20   for others */. 
06e0: 20 20 20 22 20 20 50 52 49 4d 41 52 59 20 4b 45     "  PRIMARY KE
06f0: 59 28 72 69 64 2c 73 72 63 29 22 0a 20 20 20 20  Y(rid,src)".    
0700: 22 29 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44  ") WITHOUT ROWID
0710: 3b 22 0a 20 20 20 20 22 44 45 4c 45 54 45 20 46  ;".    "DELETE F
0720: 52 4f 4d 20 61 71 75 65 75 65 3b 22 0a 20 20 20  ROM aqueue;".   
0730: 20 22 43 52 45 41 54 45 20 49 4e 44 45 58 20 49   "CREATE INDEX I
0740: 46 20 4e 4f 54 20 45 58 49 53 54 53 20 61 71 75  F NOT EXISTS aqu
0750: 65 75 65 5f 69 64 78 31 20 4f 4e 20 61 71 75 65  eue_idx1 ON aque
0760: 75 65 28 70 65 6e 64 69 6e 67 2c 20 6d 74 69 6d  ue(pending, mtim
0770: 65 29 3b 22 0a 20 20 29 3b 0a 0a 20 20 2f 2a 20  e);".  );..  /* 
0780: 49 6e 73 65 72 74 20 74 68 65 20 70 72 69 6d 61  Insert the prima
0790: 72 79 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20 64  ry record */.  d
07a0: 62 5f 6d 75 6c 74 69 5f 65 78 65 63 28 0a 20 20  b_multi_exec(.  
07b0: 20 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 61    "INSERT INTO a
07c0: 71 75 65 75 65 28 72 69 64 2c 20 6d 74 69 6d 65  queue(rid, mtime
07d0: 2c 20 70 65 6e 64 69 6e 67 2c 20 73 72 63 29 22  , pending, src)"
07e0: 0a 20 20 20 20 22 20 20 53 45 4c 45 43 54 20 25  .    "  SELECT %
07f0: 64 2c 20 6d 74 69 6d 65 2c 20 31 2c 20 31 20 46  d, mtime, 1, 1 F
0800: 52 4f 4d 20 65 76 65 6e 74 20 57 48 45 52 45 20  ROM event WHERE 
0810: 6f 62 6a 69 64 3d 25 64 20 41 4e 44 20 74 79 70  objid=%d AND typ
0820: 65 3d 27 63 69 27 20 4c 49 4d 49 54 20 31 22 2c  e='ci' LIMIT 1",
0830: 0a 20 20 20 20 72 69 64 2c 20 72 69 64 0a 20 20  .    rid, rid.  
0840: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20  );.}../*.** Set 
0850: 61 20 73 65 63 6f 6e 64 61 72 79 20 66 69 6c 65  a secondary file
0860: 2e 20 20 54 68 65 20 70 72 69 6d 61 72 79 20 66  .  The primary f
0870: 69 6c 65 20 6d 75 73 74 20 62 65 20 73 65 74 20  ile must be set 
0880: 66 69 72 73 74 2e 20 20 54 68 65 72 65 0a 2a 2a  first.  There.**
0890: 20 6d 75 73 74 20 62 65 20 61 74 20 6c 65 61 73   must be at leas
08a0: 74 20 6f 6e 65 20 73 65 63 6f 6e 64 61 72 79 20  t one secondary 
08b0: 62 75 74 20 74 68 65 72 65 20 63 61 6e 20 62 65  but there can be
08c0: 20 6d 6f 72 65 20 74 68 61 6e 20 6f 6e 65 20 69   more than one i
08d0: 66 0a 2a 2a 20 64 65 73 69 72 65 64 2e 0a 2a 2f  f.** desired..*/
08e0: 0a 76 6f 69 64 20 70 69 76 6f 74 5f 73 65 74 5f  .void pivot_set_
08f0: 73 65 63 6f 6e 64 61 72 79 28 69 6e 74 20 72 69  secondary(int ri
0900: 64 29 7b 0a 20 20 2f 2a 20 49 6e 73 65 72 74 20  d){.  /* Insert 
0910: 74 68 65 20 70 72 69 6d 61 72 79 20 72 65 63 6f  the primary reco
0920: 72 64 20 2a 2f 0a 20 20 64 62 5f 6d 75 6c 74 69  rd */.  db_multi
0930: 5f 65 78 65 63 28 0a 20 20 20 20 22 49 4e 53 45  _exec(.    "INSE
0940: 52 54 20 4f 52 20 49 47 4e 4f 52 45 20 49 4e 54  RT OR IGNORE INT
0950: 4f 20 61 71 75 65 75 65 28 72 69 64 2c 20 6d 74  O aqueue(rid, mt
0960: 69 6d 65 2c 20 70 65 6e 64 69 6e 67 2c 20 73 72  ime, pending, sr
0970: 63 29 22 0a 20 20 20 20 22 20 20 53 45 4c 45 43  c)".    "  SELEC
0980: 54 20 25 64 2c 20 6d 74 69 6d 65 2c 20 31 2c 20  T %d, mtime, 1, 
0990: 30 20 46 52 4f 4d 20 65 76 65 6e 74 20 57 48 45  0 FROM event WHE
09a0: 52 45 20 6f 62 6a 69 64 3d 25 64 20 41 4e 44 20  RE objid=%d AND 
09b0: 74 79 70 65 3d 27 63 69 27 22 2c 0a 20 20 20 20  type='ci'",.    
09c0: 72 69 64 2c 20 72 69 64 0a 20 20 29 3b 0a 7d 0a  rid, rid.  );.}.
09d0: 0a 2f 2a 0a 2a 2a 20 46 69 6e 64 20 74 68 65 20  ./*.** Find the 
09e0: 6d 6f 73 74 20 72 65 63 65 6e 74 20 63 6f 6d 6d  most recent comm
09f0: 6f 6e 20 61 6e 63 65 73 74 6f 72 20 6f 66 20 74  on ancestor of t
0a00: 68 65 20 70 72 69 6d 61 72 79 20 61 6e 64 20 6f  he primary and o
0a10: 6e 65 20 6f 66 0a 2a 2a 20 74 68 65 20 73 65 63  ne of.** the sec
0a20: 6f 6e 64 61 72 69 65 73 2e 20 20 52 65 74 75 72  ondaries.  Retur
0a30: 6e 20 69 74 73 20 72 69 64 2e 20 20 52 65 74 75  n its rid.  Retu
0a40: 72 6e 20 30 20 69 66 20 6e 6f 20 63 6f 6d 6d 6f  rn 0 if no commo
0a50: 6e 20 61 6e 63 65 73 74 6f 72 0a 2a 2a 20 63 61  n ancestor.** ca
0a60: 6e 20 62 65 20 66 6f 75 6e 64 2e 0a 2a 2a 0a 2a  n be found..**.*
0a70: 2a 20 49 66 20 69 67 6e 6f 72 65 4d 65 72 67 65  * If ignoreMerge
0a80: 73 20 69 73 20 74 72 75 65 2c 20 66 6f 6c 6c 6f  s is true, follo
0a90: 77 20 6f 6e 6c 79 20 22 70 72 69 6d 61 72 79 22  w only "primary"
0aa0: 20 70 61 72 65 6e 74 20 6c 69 6e 6b 73 2e 0a 2a   parent links..*
0ab0: 2f 0a 69 6e 74 20 70 69 76 6f 74 5f 66 69 6e 64  /.int pivot_find
0ac0: 28 69 6e 74 20 69 67 6e 6f 72 65 4d 65 72 67 65  (int ignoreMerge
0ad0: 73 29 7b 0a 20 20 53 74 6d 74 20 71 31 2c 20 71  s){.  Stmt q1, q
0ae0: 32 2c 20 75 31 2c 20 69 31 3b 0a 20 20 69 6e 74  2, u1, i1;.  int
0af0: 20 72 69 64 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20   rid = 0;..  /* 
0b00: 61 71 75 65 75 65 20 6d 75 73 74 20 63 6f 6e 74  aqueue must cont
0b10: 61 69 6e 20 61 74 20 6c 65 61 73 74 20 6f 6e 65  ain at least one
0b20: 20 70 72 69 6d 61 72 79 20 61 6e 64 20 6f 6e 65   primary and one
0b30: 20 6f 74 68 65 72 2e 20 20 4f 74 68 65 72 77 69   other.  Otherwi
0b40: 73 65 0a 20 20 2a 2a 20 77 65 20 61 62 6f 72 74  se.  ** we abort
0b50: 20 65 61 72 6c 79 0a 20 20 2a 2f 0a 20 20 69 66   early.  */.  if
0b60: 28 20 64 62 5f 69 6e 74 28 30 2c 20 22 53 45 4c  ( db_int(0, "SEL
0b70: 45 43 54 20 63 6f 75 6e 74 28 64 69 73 74 69 6e  ECT count(distin
0b80: 63 74 20 73 72 63 29 20 46 52 4f 4d 20 61 71 75  ct src) FROM aqu
0b90: 65 75 65 22 29 3c 32 20 29 7b 0a 20 20 20 20 66  eue")<2 ){.    f
0ba0: 6f 73 73 69 6c 5f 66 61 74 61 6c 28 22 6c 61 63  ossil_fatal("lac
0bb0: 6b 20 62 6f 74 68 20 70 72 69 6d 61 72 79 20 61  k both primary a
0bc0: 6e 64 20 73 65 63 6f 6e 64 61 72 79 20 66 69 6c  nd secondary fil
0bd0: 65 73 22 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  es");.  }..  /* 
0be0: 50 72 65 70 61 72 65 20 71 75 65 72 69 65 73 20  Prepare queries 
0bf0: 77 65 20 77 69 6c 6c 20 62 65 20 6e 65 65 64 69  we will be needi
0c00: 6e 67 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 65  ng.  **.  ** The
0c10: 20 66 69 72 73 74 20 71 75 65 72 79 20 66 69 6e   first query fin
0c20: 64 73 20 74 68 65 20 6f 6c 64 65 73 74 20 70 65  ds the oldest pe
0c30: 6e 64 69 6e 67 20 76 65 72 73 69 6f 6e 20 6f 6e  nding version on
0c40: 20 74 68 65 20 61 71 75 65 75 65 2e 20 20 54 68   the aqueue.  Th
0c50: 69 73 0a 20 20 2a 2a 20 77 69 6c 6c 20 62 65 20  is.  ** will be 
0c60: 6e 65 78 74 20 6f 6e 65 20 73 65 61 72 63 68 65  next one searche
0c70: 64 2e 0a 20 20 2a 2f 0a 20 20 64 62 5f 70 72 65  d..  */.  db_pre
0c80: 70 61 72 65 28 26 71 31 2c 20 22 53 45 4c 45 43  pare(&q1, "SELEC
0c90: 54 20 72 69 64 20 46 52 4f 4d 20 61 71 75 65 75  T rid FROM aqueu
0ca0: 65 20 57 48 45 52 45 20 70 65 6e 64 69 6e 67 22  e WHERE pending"
0cb0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0cc0: 20 20 20 22 20 4f 52 44 45 52 20 42 59 20 70 65     " ORDER BY pe
0cd0: 6e 64 69 6e 67 20 44 45 53 43 2c 20 6d 74 69 6d  nding DESC, mtim
0ce0: 65 20 44 45 53 43 22 29 3b 0a 0a 20 20 2f 2a 20  e DESC");..  /* 
0cf0: 43 68 65 63 6b 20 74 6f 20 73 65 65 20 69 66 20  Check to see if 
0d00: 74 68 65 20 72 65 63 6f 72 64 20 3a 72 69 64 20  the record :rid 
0d10: 69 73 20 61 20 63 6f 6d 6d 6f 6e 20 61 6e 63 65  is a common ance
0d20: 73 74 6f 72 2e 20 20 54 68 65 20 72 65 73 75 6c  stor.  The resul
0d30: 74 0a 20 20 2a 2a 20 73 65 74 20 63 6f 6e 74 61  t.  ** set conta
0d40: 69 6e 73 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20  ins one or more 
0d50: 72 6f 77 73 20 69 66 20 69 74 20 69 73 20 61 6e  rows if it is an
0d60: 64 20 69 73 20 74 68 65 20 65 6d 70 74 79 20 73  d is the empty s
0d70: 65 74 20 69 66 20 69 74 0a 20 20 2a 2a 20 69 73  et if it.  ** is
0d80: 20 6e 6f 74 2e 0a 20 20 2a 2f 0a 20 20 64 62 5f   not..  */.  db_
0d90: 70 72 65 70 61 72 65 28 26 71 32 2c 0a 20 20 20  prepare(&q2,.   
0da0: 20 22 53 45 4c 45 43 54 20 31 20 46 52 4f 4d 20   "SELECT 1 FROM 
0db0: 61 71 75 65 75 65 20 41 2c 20 70 6c 69 6e 6b 2c  aqueue A, plink,
0dc0: 20 61 71 75 65 75 65 20 42 22 0a 20 20 20 20 22   aqueue B".    "
0dd0: 20 57 48 45 52 45 20 70 6c 69 6e 6b 2e 70 69 64   WHERE plink.pid
0de0: 3d 3a 72 69 64 22 0a 20 20 20 20 22 20 20 20 41  =:rid".    "   A
0df0: 4e 44 20 70 6c 69 6e 6b 2e 63 69 64 3d 42 2e 72  ND plink.cid=B.r
0e00: 69 64 22 0a 20 20 20 20 22 20 20 20 41 4e 44 20  id".    "   AND 
0e10: 41 2e 72 69 64 3d 3a 72 69 64 22 0a 20 20 20 20  A.rid=:rid".    
0e20: 22 20 20 20 41 4e 44 20 41 2e 73 72 63 21 3d 42  "   AND A.src!=B
0e30: 2e 73 72 63 20 25 73 22 2c 0a 20 20 20 20 69 67  .src %s",.    ig
0e40: 6e 6f 72 65 4d 65 72 67 65 73 20 3f 20 22 41 4e  noreMerges ? "AN
0e50: 44 20 70 6c 69 6e 6b 2e 69 73 70 72 69 6d 22 20  D plink.isprim" 
0e60: 3a 20 22 22 0a 20 20 29 3b 0a 0a 20 20 2f 2a 20  : "".  );..  /* 
0e70: 4d 61 72 6b 20 74 68 65 20 3a 72 69 64 20 72 65  Mark the :rid re
0e80: 63 6f 72 64 20 68 61 73 20 68 61 76 69 6e 67 20  cord has having 
0e90: 62 65 65 6e 20 63 68 65 63 6b 65 64 2e 20 20 49  been checked.  I
0ea0: 74 20 69 73 20 6e 6f 74 20 74 68 65 0a 20 20 2a  t is not the.  *
0eb0: 2a 20 63 6f 6d 6d 6f 6e 20 61 6e 63 65 73 74 6f  * common ancesto
0ec0: 72 2e 0a 20 20 2a 2f 0a 20 20 64 62 5f 70 72 65  r..  */.  db_pre
0ed0: 70 61 72 65 28 26 75 31 2c 0a 20 20 20 20 22 55  pare(&u1,.    "U
0ee0: 50 44 41 54 45 20 61 71 75 65 75 65 20 53 45 54  PDATE aqueue SET
0ef0: 20 70 65 6e 64 69 6e 67 3d 30 20 57 48 45 52 45   pending=0 WHERE
0f00: 20 72 69 64 3d 3a 72 69 64 22 0a 20 20 29 3b 0a   rid=:rid".  );.
0f10: 0a 20 20 2f 2a 20 41 64 64 20 74 6f 20 74 68 65  .  /* Add to the
0f20: 20 71 75 65 75 65 20 61 6c 6c 20 61 6e 63 65 73   queue all ances
0f30: 74 6f 72 73 20 6f 66 20 3a 72 69 64 2e 0a 20 20  tors of :rid..  
0f40: 2a 2f 0a 20 20 64 62 5f 70 72 65 70 61 72 65 28  */.  db_prepare(
0f50: 26 69 31 2c 0a 20 20 20 20 22 52 45 50 4c 41 43  &i1,.    "REPLAC
0f60: 45 20 49 4e 54 4f 20 61 71 75 65 75 65 20 22 0a  E INTO aqueue ".
0f70: 20 20 20 20 22 53 45 4c 45 43 54 20 70 6c 69 6e      "SELECT plin
0f80: 6b 2e 70 69 64 2c 22 0a 20 20 20 20 22 20 20 20  k.pid,".    "   
0f90: 20 20 20 20 63 6f 61 6c 65 73 63 65 28 28 53 45      coalesce((SE
0fa0: 4c 45 43 54 20 6d 74 69 6d 65 20 46 52 4f 4d 20  LECT mtime FROM 
0fb0: 65 76 65 6e 74 20 58 20 57 48 45 52 45 20 58 2e  event X WHERE X.
0fc0: 6f 62 6a 69 64 3d 70 6c 69 6e 6b 2e 70 69 64 29  objid=plink.pid)
0fd0: 2c 20 30 2e 30 29 2c 22 0a 20 20 20 20 22 20 20  , 0.0),".    "  
0fe0: 20 20 20 20 20 31 2c 22 0a 20 20 20 20 22 20 20       1,".    "  
0ff0: 20 20 20 20 20 61 71 75 65 75 65 2e 73 72 63 20       aqueue.src 
1000: 22 0a 20 20 20 20 22 20 20 46 52 4f 4d 20 70 6c  ".    "  FROM pl
1010: 69 6e 6b 2c 20 61 71 75 65 75 65 22 0a 20 20 20  ink, aqueue".   
1020: 20 22 20 57 48 45 52 45 20 70 6c 69 6e 6b 2e 63   " WHERE plink.c
1030: 69 64 3d 3a 72 69 64 22 0a 20 20 20 20 22 20 20  id=:rid".    "  
1040: 20 41 4e 44 20 61 71 75 65 75 65 2e 72 69 64 3d   AND aqueue.rid=
1050: 3a 72 69 64 20 25 73 22 2c 0a 20 20 20 20 69 67  :rid %s",.    ig
1060: 6e 6f 72 65 4d 65 72 67 65 73 20 3f 20 22 41 4e  noreMerges ? "AN
1070: 44 20 70 6c 69 6e 6b 2e 69 73 70 72 69 6d 22 20  D plink.isprim" 
1080: 3a 20 22 22 0a 20 20 29 3b 0a 0a 20 20 77 68 69  : "".  );..  whi
1090: 6c 65 28 20 64 62 5f 73 74 65 70 28 26 71 31 29  le( db_step(&q1)
10a0: 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a  ==SQLITE_ROW ){.
10b0: 20 20 20 20 72 69 64 20 3d 20 64 62 5f 63 6f 6c      rid = db_col
10c0: 75 6d 6e 5f 69 6e 74 28 26 71 31 2c 20 30 29 3b  umn_int(&q1, 0);
10d0: 0a 20 20 20 20 64 62 5f 72 65 73 65 74 28 26 71  .    db_reset(&q
10e0: 31 29 3b 0a 20 20 20 20 64 62 5f 62 69 6e 64 5f  1);.    db_bind_
10f0: 69 6e 74 28 26 71 32 2c 20 22 3a 72 69 64 22 2c  int(&q2, ":rid",
1100: 20 72 69 64 29 3b 0a 20 20 20 20 69 66 28 20 64   rid);.    if( d
1110: 62 5f 73 74 65 70 28 26 71 32 29 3d 3d 53 51 4c  b_step(&q2)==SQL
1120: 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20  ITE_ROW ){.     
1130: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20    break;.    }. 
1140: 20 20 20 64 62 5f 72 65 73 65 74 28 26 71 32 29     db_reset(&q2)
1150: 3b 0a 20 20 20 20 64 62 5f 62 69 6e 64 5f 69 6e  ;.    db_bind_in
1160: 74 28 26 69 31 2c 20 22 3a 72 69 64 22 2c 20 72  t(&i1, ":rid", r
1170: 69 64 29 3b 0a 20 20 20 20 64 62 5f 65 78 65 63  id);.    db_exec
1180: 28 26 69 31 29 3b 0a 20 20 20 20 64 62 5f 62 69  (&i1);.    db_bi
1190: 6e 64 5f 69 6e 74 28 26 75 31 2c 20 22 3a 72 69  nd_int(&u1, ":ri
11a0: 64 22 2c 20 72 69 64 29 3b 0a 20 20 20 20 64 62  d", rid);.    db
11b0: 5f 65 78 65 63 28 26 75 31 29 3b 0a 20 20 20 20  _exec(&u1);.    
11c0: 72 69 64 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 64  rid = 0;.  }.  d
11d0: 62 5f 66 69 6e 61 6c 69 7a 65 28 26 71 31 29 3b  b_finalize(&q1);
11e0: 0a 20 20 64 62 5f 66 69 6e 61 6c 69 7a 65 28 26  .  db_finalize(&
11f0: 71 32 29 3b 0a 20 20 64 62 5f 66 69 6e 61 6c 69  q2);.  db_finali
1200: 7a 65 28 26 69 31 29 3b 0a 20 20 64 62 5f 66 69  ze(&i1);.  db_fi
1210: 6e 61 6c 69 7a 65 28 26 75 31 29 3b 0a 20 20 72  nalize(&u1);.  r
1220: 65 74 75 72 6e 20 72 69 64 3b 0a 7d 0a 0a 2f 2a  eturn rid;.}../*
1230: 0a 2a 2a 20 43 4f 4d 4d 41 4e 44 3a 20 74 65 73  .** COMMAND: tes
1240: 74 2d 66 69 6e 64 2d 70 69 76 6f 74 0a 2a 2a 0a  t-find-pivot.**.
1250: 2a 2a 20 55 73 61 67 65 3a 20 25 66 6f 73 73 69  ** Usage: %fossi
1260: 6c 20 74 65 73 74 2d 66 69 6e 64 2d 70 69 76 6f  l test-find-pivo
1270: 74 20 3f 6f 70 74 69 6f 6e 73 3f 20 50 52 49 4d  t ?options? PRIM
1280: 41 52 59 20 53 45 43 4f 4e 44 41 52 59 20 2e 2e  ARY SECONDARY ..
1290: 2e 0a 2a 2a 0a 2a 2a 20 54 65 73 74 20 74 68 65  ..**.** Test the
12a0: 20 70 69 76 6f 74 5f 66 69 6e 64 28 29 20 70 72   pivot_find() pr
12b0: 6f 63 65 64 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 4f  ocedure..**.** O
12c0: 70 74 69 6f 6e 73 3a 0a 2a 2a 20 20 20 20 2d 2d  ptions:.**    --
12d0: 69 67 6e 6f 72 65 2d 6d 65 72 67 65 73 20 20 20  ignore-merges   
12e0: 20 20 20 20 49 67 6e 6f 72 65 20 6d 65 72 67 65      Ignore merge
12f0: 73 20 66 6f 72 20 64 69 73 63 6f 76 65 72 69 6e  s for discoverin
1300: 67 20 6e 61 6d 65 20 70 69 76 6f 74 73 0a 2a 2f  g name pivots.*/
1310: 0a 76 6f 69 64 20 74 65 73 74 5f 66 69 6e 64 5f  .void test_find_
1320: 70 69 76 6f 74 28 76 6f 69 64 29 7b 0a 20 20 69  pivot(void){.  i
1330: 6e 74 20 69 2c 20 72 69 64 3b 0a 20 20 69 6e 74  nt i, rid;.  int
1340: 20 69 67 6e 6f 72 65 4d 65 72 67 65 73 20 3d 20   ignoreMerges = 
1350: 66 69 6e 64 5f 6f 70 74 69 6f 6e 28 22 69 67 6e  find_option("ign
1360: 6f 72 65 2d 6d 65 72 67 65 73 22 2c 30 2c 30 29  ore-merges",0,0)
1370: 21 3d 30 3b 0a 20 20 69 6e 74 20 73 68 6f 77 44  !=0;.  int showD
1380: 65 74 61 69 6c 73 20 3d 20 66 69 6e 64 5f 6f 70  etails = find_op
1390: 74 69 6f 6e 28 22 64 65 74 61 69 6c 73 22 2c 30  tion("details",0
13a0: 2c 30 29 21 3d 30 3b 0a 20 20 69 66 28 20 67 2e  ,0)!=0;.  if( g.
13b0: 61 72 67 63 3c 34 20 29 7b 0a 20 20 20 20 75 73  argc<4 ){.    us
13c0: 61 67 65 28 22 3f 6f 70 74 69 6f 6e 73 3f 20 50  age("?options? P
13d0: 52 49 4d 41 52 59 20 53 45 43 4f 4e 44 41 52 59  RIMARY SECONDARY
13e0: 20 2e 2e 2e 22 29 3b 0a 20 20 7d 0a 20 20 64 62   ...");.  }.  db
13f0: 5f 6d 75 73 74 5f 62 65 5f 77 69 74 68 69 6e 5f  _must_be_within_
1400: 74 72 65 65 28 29 3b 0a 20 20 70 69 76 6f 74 5f  tree();.  pivot_
1410: 73 65 74 5f 70 72 69 6d 61 72 79 28 6e 61 6d 65  set_primary(name
1420: 5f 74 6f 5f 72 69 64 28 67 2e 61 72 67 76 5b 32  _to_rid(g.argv[2
1430: 5d 29 29 3b 0a 20 20 66 6f 72 28 69 3d 33 3b 20  ]));.  for(i=3; 
1440: 69 3c 67 2e 61 72 67 63 3b 20 69 2b 2b 29 7b 0a  i<g.argc; i++){.
1450: 20 20 20 20 70 69 76 6f 74 5f 73 65 74 5f 73 65      pivot_set_se
1460: 63 6f 6e 64 61 72 79 28 6e 61 6d 65 5f 74 6f 5f  condary(name_to_
1470: 72 69 64 28 67 2e 61 72 67 76 5b 69 5d 29 29 3b  rid(g.argv[i]));
1480: 0a 20 20 7d 0a 20 20 72 69 64 20 3d 20 70 69 76  .  }.  rid = piv
1490: 6f 74 5f 66 69 6e 64 28 69 67 6e 6f 72 65 4d 65  ot_find(ignoreMe
14a0: 72 67 65 73 29 3b 0a 20 20 70 72 69 6e 74 66 28  rges);.  printf(
14b0: 22 70 69 76 6f 74 3d 25 73 5c 6e 22 2c 0a 20 20  "pivot=%s\n",.  
14c0: 20 20 20 20 20 20 20 64 62 5f 74 65 78 74 28 22         db_text("
14d0: 3f 22 2c 22 53 45 4c 45 43 54 20 75 75 69 64 20  ?","SELECT uuid 
14e0: 46 52 4f 4d 20 62 6c 6f 62 20 57 48 45 52 45 20  FROM blob WHERE 
14f0: 72 69 64 3d 25 64 22 2c 72 69 64 29 0a 20 20 29  rid=%d",rid).  )
1500: 3b 0a 20 20 69 66 28 20 73 68 6f 77 44 65 74 61  ;.  if( showDeta
1510: 69 6c 73 20 29 7b 0a 20 20 20 20 53 74 6d 74 20  ils ){.    Stmt 
1520: 71 3b 0a 20 20 20 20 64 62 5f 70 72 65 70 61 72  q;.    db_prepar
1530: 65 28 26 71 2c 0a 20 20 20 20 20 20 22 53 45 4c  e(&q,.      "SEL
1540: 45 43 54 20 73 75 62 73 74 72 28 75 75 69 64 2c  ECT substr(uuid,
1550: 31 2c 31 32 29 2c 20 61 71 75 65 75 65 2e 72 69  1,12), aqueue.ri
1560: 64 2c 20 64 61 74 65 74 69 6d 65 28 61 71 75 65  d, datetime(aque
1570: 75 65 2e 6d 74 69 6d 65 29 2c 22 0a 20 20 20 20  ue.mtime),".    
1580: 20 20 20 20 20 20 20 20 20 22 20 61 71 75 65 75           " aqueu
1590: 65 2e 70 65 6e 64 69 6e 67 2c 20 61 71 75 65 75  e.pending, aqueu
15a0: 65 2e 73 72 63 5c 6e 22 0a 20 20 20 20 20 20 22  e.src\n".      "
15b0: 20 20 46 52 4f 4d 20 61 71 75 65 75 65 20 4a 4f    FROM aqueue JO
15c0: 49 4e 20 62 6c 6f 62 20 4f 4e 20 61 71 75 65 75  IN blob ON aqueu
15d0: 65 2e 72 69 64 3d 62 6c 6f 62 2e 72 69 64 5c 6e  e.rid=blob.rid\n
15e0: 22 0a 20 20 20 20 20 20 22 20 4f 52 44 45 52 20  ".      " ORDER 
15f0: 42 59 20 61 71 75 65 75 65 2e 6d 74 69 6d 65 20  BY aqueue.mtime 
1600: 44 45 53 43 22 0a 20 20 20 20 29 3b 0a 20 20 20  DESC".    );.   
1610: 20 77 68 69 6c 65 28 20 64 62 5f 73 74 65 70 28   while( db_step(
1620: 26 71 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20  &q)==SQLITE_ROW 
1630: 29 7b 0a 20 20 20 20 20 20 70 72 69 6e 74 66 28  ){.      printf(
1640: 22 5c 22 25 73 5c 22 2c 25 64 2c 5c 22 25 73 5c  "\"%s\",%d,\"%s\
1650: 22 2c 25 64 2c 25 64 5c 6e 22 2c 0a 20 20 20 20  ",%d,%d\n",.    
1660: 20 20 20 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65      db_column_te
1670: 78 74 28 26 71 2c 20 30 29 2c 0a 20 20 20 20 20  xt(&q, 0),.     
1680: 20 20 20 64 62 5f 63 6f 6c 75 6d 6e 5f 69 6e 74     db_column_int
1690: 28 26 71 2c 20 31 29 2c 0a 20 20 20 20 20 20 20  (&q, 1),.       
16a0: 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28   db_column_text(
16b0: 26 71 2c 20 32 29 2c 0a 20 20 20 20 20 20 20 20  &q, 2),.        
16c0: 64 62 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 26 71  db_column_int(&q
16d0: 2c 20 33 29 2c 0a 20 20 20 20 20 20 20 20 64 62  , 3),.        db
16e0: 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 26 71 2c 20  _column_int(&q, 
16f0: 34 29 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 64  4));.    }.    d
1700: 62 5f 66 69 6e 61 6c 69 7a 65 28 26 71 29 3b 0a  b_finalize(&q);.
1710: 20 20 7d 0a 7d 0a                                  }.}.