/ Hex Artifact Content
Login

Artifact fcd15eb438a3462f4dbeebf506ee9050947236bf:


0000: 2f 2a 0a 2a 2a 20 32 30 31 31 2d 30 37 2d 30 39  /*.** 2011-07-09
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a  ***************.
0170: 2a 2a 20 54 68 69 73 20 66 69 6c 65 20 63 6f 6e  ** This file con
0180: 74 61 69 6e 73 20 63 6f 64 65 20 66 6f 72 20 74  tains code for t
0190: 68 65 20 56 64 62 65 53 6f 72 74 65 72 20 6f 62  he VdbeSorter ob
01a0: 6a 65 63 74 2c 20 75 73 65 64 20 69 6e 20 63 6f  ject, used in co
01b0: 6e 63 65 72 74 20 77 69 74 68 0a 2a 2a 20 61 20  ncert with.** a 
01c0: 56 64 62 65 43 75 72 73 6f 72 20 74 6f 20 73 6f  VdbeCursor to so
01d0: 72 74 20 6c 61 72 67 65 20 6e 75 6d 62 65 72 73  rt large numbers
01e0: 20 6f 66 20 6b 65 79 73 20 66 6f 72 20 43 52 45   of keys for CRE
01f0: 41 54 45 20 49 4e 44 45 58 20 73 74 61 74 65 6d  ATE INDEX statem
0200: 65 6e 74 73 0a 2a 2a 20 6f 72 20 62 79 20 53 45  ents.** or by SE
0210: 4c 45 43 54 20 73 74 61 74 65 6d 65 6e 74 73 20  LECT statements 
0220: 77 69 74 68 20 4f 52 44 45 52 20 42 59 20 63 6c  with ORDER BY cl
0230: 61 75 73 65 73 20 74 68 61 74 20 63 61 6e 6e 6f  auses that canno
0240: 74 20 62 65 20 73 61 74 69 73 66 69 65 64 0a 2a  t be satisfied.*
0250: 2a 20 75 73 69 6e 67 20 69 6e 64 65 78 65 73 20  * using indexes 
0260: 61 6e 64 20 77 69 74 68 6f 75 74 20 4c 49 4d 49  and without LIMI
0270: 54 20 63 6c 61 75 73 65 73 2e 0a 2a 2a 0a 2a 2a  T clauses..**.**
0280: 20 54 68 65 20 56 64 62 65 53 6f 72 74 65 72 20   The VdbeSorter 
0290: 6f 62 6a 65 63 74 20 69 6d 70 6c 65 6d 65 6e 74  object implement
02a0: 73 20 61 20 6d 75 6c 74 69 2d 74 68 72 65 61 64  s a multi-thread
02b0: 65 64 20 65 78 74 65 72 6e 61 6c 20 6d 65 72 67  ed external merg
02c0: 65 20 73 6f 72 74 0a 2a 2a 20 61 6c 67 6f 72 69  e sort.** algori
02d0: 74 68 6d 20 74 68 61 74 20 69 73 20 65 66 66 69  thm that is effi
02e0: 63 69 65 6e 74 20 65 76 65 6e 20 69 66 20 74 68  cient even if th
02f0: 65 20 6e 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d  e number of elem
0300: 65 6e 74 20 62 65 69 6e 67 20 73 6f 72 74 65 64  ent being sorted
0310: 0a 2a 2a 20 65 78 63 65 65 64 73 20 74 68 65 20  .** exceeds the 
0320: 61 76 61 69 6c 61 62 6c 65 20 6d 65 6d 6f 72 79  available memory
0330: 2e 0a 2a 2a 0a 2a 2a 20 48 65 72 65 20 69 73 20  ..**.** Here is 
0340: 74 68 65 20 28 69 6e 74 65 72 6e 61 6c 2c 20 6e  the (internal, n
0350: 6f 6e 2d 41 50 49 29 20 69 6e 74 65 72 66 61 63  on-API) interfac
0360: 65 20 62 65 74 77 65 65 6e 20 74 68 69 73 20 6d  e between this m
0370: 6f 64 75 6c 65 20 61 6e 64 20 74 68 65 0a 2a 2a  odule and the.**
0380: 20 72 65 73 74 20 6f 66 20 74 68 65 20 53 51 4c   rest of the SQL
0390: 69 74 65 20 73 79 73 74 65 6d 3a 0a 2a 2a 0a 2a  ite system:.**.*
03a0: 2a 20 20 20 20 73 71 6c 69 74 65 33 56 64 62 65  *    sqlite3Vdbe
03b0: 53 6f 72 74 65 72 49 6e 69 74 28 29 20 20 20 20  SorterInit()    
03c0: 20 20 20 43 72 65 61 74 65 20 61 20 6e 65 77 20     Create a new 
03d0: 56 64 62 65 53 6f 72 74 65 72 20 6f 62 6a 65 63  VdbeSorter objec
03e0: 74 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71 6c 69  t..**.**    sqli
03f0: 74 65 33 56 64 62 65 53 6f 72 74 65 72 57 72 69  te3VdbeSorterWri
0400: 74 65 28 29 20 20 20 20 20 20 41 64 64 20 61 20  te()      Add a 
0410: 73 69 6e 67 6c 65 20 6e 65 77 20 72 6f 77 20 74  single new row t
0420: 6f 20 74 68 65 20 56 64 62 65 53 6f 72 74 65 72  o the VdbeSorter
0430: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20  .**             
0440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0450: 20 20 20 20 20 6f 62 6a 65 63 74 2e 20 20 54 68       object.  Th
0460: 65 20 72 6f 77 20 69 73 20 61 20 62 69 6e 61 72  e row is a binar
0470: 79 20 62 6c 6f 62 20 69 6e 20 74 68 65 0a 2a 2a  y blob in the.**
0480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04a0: 20 20 4f 50 5f 4d 61 6b 65 52 65 63 6f 72 64 20    OP_MakeRecord 
04b0: 66 6f 72 6d 61 74 20 74 68 61 74 20 63 6f 6e 74  format that cont
04c0: 61 69 6e 73 20 62 6f 74 68 0a 2a 2a 20 20 20 20  ains both.**    
04d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 74 68                th
04f0: 65 20 4f 52 44 45 52 20 42 59 20 6b 65 79 20 63  e ORDER BY key c
0500: 6f 6c 75 6d 6e 73 20 61 6e 64 20 72 65 73 75 6c  olumns and resul
0510: 74 20 63 6f 6c 75 6d 6e 73 0a 2a 2a 20 20 20 20  t columns.**    
0520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e                in
0540: 20 74 68 65 20 63 61 73 65 20 6f 66 20 61 20 53   the case of a S
0550: 45 4c 45 43 54 20 77 2f 20 4f 52 44 45 52 20 42  ELECT w/ ORDER B
0560: 59 2c 20 6f 72 0a 2a 2a 20 20 20 20 20 20 20 20  Y, or.**        
0570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0580: 20 20 20 20 20 20 20 20 20 20 74 68 65 20 63 6f            the co
0590: 6d 70 6c 65 74 65 20 72 65 63 6f 72 64 20 66 6f  mplete record fo
05a0: 72 20 61 6e 20 69 6e 64 65 78 20 65 6e 74 72 79  r an index entry
05b0: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20  .**             
05c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05d0: 20 20 20 20 20 69 6e 20 74 68 65 20 63 61 73 65       in the case
05e0: 20 6f 66 20 61 20 43 52 45 41 54 45 20 49 4e 44   of a CREATE IND
05f0: 45 58 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71 6c  EX..**.**    sql
0600: 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 52 65  ite3VdbeSorterRe
0610: 77 69 6e 64 28 29 20 20 20 20 20 53 6f 72 74 20  wind()     Sort 
0620: 61 6c 6c 20 63 6f 6e 74 65 6e 74 20 70 72 65 76  all content prev
0630: 69 6f 75 73 6c 79 20 61 64 64 65 64 2e 0a 2a 2a  iously added..**
0640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0660: 20 20 50 6f 73 69 74 69 6f 6e 20 74 68 65 20 72    Position the r
0670: 65 61 64 20 63 75 72 73 6f 72 20 6f 6e 20 74 68  ead cursor on th
0680: 65 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20  e.**            
0690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06a0: 20 20 20 20 20 20 66 69 72 73 74 20 73 6f 72 74        first sort
06b0: 65 64 20 65 6c 65 6d 65 6e 74 2e 0a 2a 2a 0a 2a  ed element..**.*
06c0: 2a 20 20 20 20 73 71 6c 69 74 65 33 56 64 62 65  *    sqlite3Vdbe
06d0: 53 6f 72 74 65 72 4e 65 78 74 28 29 20 20 20 20  SorterNext()    
06e0: 20 20 20 41 64 76 61 6e 63 65 20 74 68 65 20 72     Advance the r
06f0: 65 61 64 20 63 75 72 73 6f 72 20 74 6f 20 74 68  ead cursor to th
0700: 65 20 6e 65 78 74 20 73 6f 72 74 65 64 0a 2a 2a  e next sorted.**
0710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0730: 20 20 65 6c 65 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a    element..**.**
0740: 20 20 20 20 73 71 6c 69 74 65 33 56 64 62 65 53      sqlite3VdbeS
0750: 6f 72 74 65 72 52 6f 77 6b 65 79 28 29 20 20 20  orterRowkey()   
0760: 20 20 52 65 74 75 72 6e 20 74 68 65 20 63 6f 6d    Return the com
0770: 70 6c 65 74 65 20 62 69 6e 61 72 79 20 62 6c 6f  plete binary blo
0780: 62 20 66 6f 72 20 74 68 65 0a 2a 2a 20 20 20 20  b for the.**    
0790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72 6f                ro
07b0: 77 20 63 75 72 72 65 6e 74 6c 79 20 75 6e 64 65  w currently unde
07c0: 72 20 74 68 65 20 72 65 61 64 20 63 75 72 73 6f  r the read curso
07d0: 72 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71 6c 69  r..**.**    sqli
07e0: 74 65 33 56 64 62 65 53 6f 72 74 65 72 43 6f 6d  te3VdbeSorterCom
07f0: 70 61 72 65 28 29 20 20 20 20 43 6f 6d 70 61 72  pare()    Compar
0800: 65 20 74 68 65 20 62 69 6e 61 72 79 20 62 6c 6f  e the binary blo
0810: 62 20 66 6f 72 20 74 68 65 20 72 6f 77 0a 2a 2a  b for the row.**
0820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0840: 20 20 63 75 72 72 65 6e 74 6c 79 20 75 6e 64 65    currently unde
0850: 72 20 74 68 65 20 72 65 61 64 20 63 75 72 73 6f  r the read curso
0860: 72 20 61 67 61 69 6e 73 74 0a 2a 2a 20 20 20 20  r against.**    
0870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 6e                an
0890: 6f 74 68 65 72 20 62 69 6e 61 72 79 20 62 6c 6f  other binary blo
08a0: 62 20 58 20 61 6e 64 20 72 65 70 6f 72 74 20 69  b X and report i
08b0: 66 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20  f.**            
08c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08d0: 20 20 20 20 20 20 58 20 69 73 20 73 74 72 69 63        X is stric
08e0: 74 6c 79 20 6c 65 73 73 20 74 68 61 6e 20 74 68  tly less than th
08f0: 65 20 72 65 61 64 20 63 75 72 73 6f 72 2e 0a 2a  e read cursor..*
0900: 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  *               
0910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0920: 20 20 20 55 73 65 64 20 74 6f 20 65 6e 66 6f 72     Used to enfor
0930: 63 65 20 75 6e 69 71 75 65 6e 65 73 73 20 69 6e  ce uniqueness in
0940: 20 61 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20   a.**           
0950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0960: 20 20 20 20 20 20 20 43 52 45 41 54 45 20 55 4e         CREATE UN
0970: 49 51 55 45 20 49 4e 44 45 58 20 73 74 61 74 65  IQUE INDEX state
0980: 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73  ment..**.**    s
0990: 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72  qlite3VdbeSorter
09a0: 43 6c 6f 73 65 28 29 20 20 20 20 20 20 43 6c 6f  Close()      Clo
09b0: 73 65 20 74 68 65 20 56 64 62 65 53 6f 72 74 65  se the VdbeSorte
09c0: 72 20 6f 62 6a 65 63 74 20 61 6e 64 20 72 65 63  r object and rec
09d0: 6c 61 69 6d 0a 2a 2a 20 20 20 20 20 20 20 20 20  laim.**         
09e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09f0: 20 20 20 20 20 20 20 20 20 61 6c 6c 20 72 65 73           all res
0a00: 6f 75 72 63 65 73 2e 0a 2a 2a 0a 2a 2a 20 20 20  ources..**.**   
0a10: 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74   sqlite3VdbeSort
0a20: 65 72 52 65 73 65 74 28 29 20 20 20 20 20 20 52  erReset()      R
0a30: 65 66 75 72 62 69 73 68 20 74 68 65 20 56 64 62  efurbish the Vdb
0a40: 65 53 6f 72 74 65 72 20 66 6f 72 20 72 65 75 73  eSorter for reus
0a50: 65 2e 20 20 54 68 69 73 0a 2a 2a 20 20 20 20 20  e.  This.**     
0a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 73 20               is 
0a80: 6c 69 6b 65 20 43 6c 6f 73 65 28 29 20 66 6f 6c  like Close() fol
0a90: 6c 6f 77 65 64 20 62 79 20 49 6e 69 74 28 29 20  lowed by Init() 
0aa0: 6f 6e 6c 79 0a 2a 2a 20 20 20 20 20 20 20 20 20  only.**         
0ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ac0: 20 20 20 20 20 20 20 20 20 6d 75 63 68 20 66 61           much fa
0ad0: 73 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ster..**.** The 
0ae0: 69 6e 74 65 72 66 61 63 65 73 20 61 62 6f 76 65  interfaces above
0af0: 20 6d 75 73 74 20 62 65 20 63 61 6c 6c 65 64 20   must be called 
0b00: 69 6e 20 61 20 70 61 72 74 69 63 75 6c 61 72 20  in a particular 
0b10: 6f 72 64 65 72 2e 20 20 57 72 69 74 65 28 29 20  order.  Write() 
0b20: 63 61 6e 20 0a 2a 2a 20 6f 6e 6c 79 20 6f 63 63  can .** only occ
0b30: 75 72 20 69 6e 20 62 65 74 77 65 65 6e 20 49 6e  ur in between In
0b40: 69 74 28 29 2f 52 65 73 65 74 28 29 20 61 6e 64  it()/Reset() and
0b50: 20 52 65 77 69 6e 64 28 29 2e 20 20 4e 65 78 74   Rewind().  Next
0b60: 28 29 2c 20 52 6f 77 6b 65 79 28 29 2c 20 61 6e  (), Rowkey(), an
0b70: 64 0a 2a 2a 20 43 6f 6d 70 61 72 65 28 29 20 63  d.** Compare() c
0b80: 61 6e 20 6f 6e 6c 79 20 6f 63 63 75 72 20 69 6e  an only occur in
0b90: 20 62 65 74 77 65 65 6e 20 52 65 77 69 6e 64 28   between Rewind(
0ba0: 29 20 61 6e 64 20 43 6c 6f 73 65 28 29 2f 52 65  ) and Close()/Re
0bb0: 73 65 74 28 29 2e 20 69 2e 65 2e 0a 2a 2a 0a 2a  set(). i.e..**.*
0bc0: 2a 20 20 20 49 6e 69 74 28 29 0a 2a 2a 20 20 20  *   Init().**   
0bd0: 66 6f 72 20 65 61 63 68 20 72 65 63 6f 72 64 3a  for each record:
0be0: 20 57 72 69 74 65 28 29 0a 2a 2a 20 20 20 52 65   Write().**   Re
0bf0: 77 69 6e 64 28 29 0a 2a 2a 20 20 20 20 20 52 6f  wind().**     Ro
0c00: 77 6b 65 79 28 29 2f 43 6f 6d 70 61 72 65 28 29  wkey()/Compare()
0c10: 0a 2a 2a 20 20 20 4e 65 78 74 28 29 20 0a 2a 2a  .**   Next() .**
0c20: 20 20 20 43 6c 6f 73 65 28 29 0a 2a 2a 0a 2a 2a     Close().**.**
0c30: 20 41 6c 67 6f 72 69 74 68 6d 3a 0a 2a 2a 0a 2a   Algorithm:.**.*
0c40: 2a 20 52 65 63 6f 72 64 73 20 70 61 73 73 65 64  * Records passed
0c50: 20 74 6f 20 74 68 65 20 73 6f 72 74 65 72 20 76   to the sorter v
0c60: 69 61 20 63 61 6c 6c 73 20 74 6f 20 57 72 69 74  ia calls to Writ
0c70: 65 28 29 20 61 72 65 20 69 6e 69 74 69 61 6c 6c  e() are initiall
0c80: 79 20 68 65 6c 64 20 0a 2a 2a 20 75 6e 73 6f 72  y held .** unsor
0c90: 74 65 64 20 69 6e 20 6d 61 69 6e 20 6d 65 6d 6f  ted in main memo
0ca0: 72 79 2e 20 41 73 73 75 6d 69 6e 67 20 74 68 65  ry. Assuming the
0cb0: 20 61 6d 6f 75 6e 74 20 6f 66 20 6d 65 6d 6f 72   amount of memor
0cc0: 79 20 75 73 65 64 20 6e 65 76 65 72 20 65 78 63  y used never exc
0cd0: 65 65 64 73 0a 2a 2a 20 61 20 74 68 72 65 73 68  eeds.** a thresh
0ce0: 6f 6c 64 2c 20 77 68 65 6e 20 52 65 77 69 6e 64  old, when Rewind
0cf0: 28 29 20 69 73 20 63 61 6c 6c 65 64 20 74 68 65  () is called the
0d00: 20 73 65 74 20 6f 66 20 72 65 63 6f 72 64 73 20   set of records 
0d10: 69 73 20 73 6f 72 74 65 64 20 75 73 69 6e 67 0a  is sorted using.
0d20: 2a 2a 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20  ** an in-memory 
0d30: 6d 65 72 67 65 20 73 6f 72 74 2e 20 49 6e 20 74  merge sort. In t
0d40: 68 69 73 20 63 61 73 65 2c 20 6e 6f 20 74 65 6d  his case, no tem
0d50: 70 6f 72 61 72 79 20 66 69 6c 65 73 20 61 72 65  porary files are
0d60: 20 72 65 71 75 69 72 65 64 0a 2a 2a 20 61 6e 64   required.** and
0d70: 20 73 75 62 73 65 71 75 65 6e 74 20 63 61 6c 6c   subsequent call
0d80: 73 20 74 6f 20 52 6f 77 6b 65 79 28 29 2c 20 4e  s to Rowkey(), N
0d90: 65 78 74 28 29 20 61 6e 64 20 43 6f 6d 70 61 72  ext() and Compar
0da0: 65 28 29 20 72 65 61 64 20 72 65 63 6f 72 64 73  e() read records
0db0: 20 0a 2a 2a 20 64 69 72 65 63 74 6c 79 20 66 72   .** directly fr
0dc0: 6f 6d 20 6d 61 69 6e 20 6d 65 6d 6f 72 79 2e 0a  om main memory..
0dd0: 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 61 6d 6f  **.** If the amo
0de0: 75 6e 74 20 6f 66 20 73 70 61 63 65 20 75 73 65  unt of space use
0df0: 64 20 74 6f 20 73 74 6f 72 65 20 72 65 63 6f 72  d to store recor
0e00: 64 73 20 69 6e 20 6d 61 69 6e 20 6d 65 6d 6f 72  ds in main memor
0e10: 79 20 65 78 63 65 65 64 73 20 74 68 65 0a 2a 2a  y exceeds the.**
0e20: 20 74 68 72 65 73 68 6f 6c 64 2c 20 74 68 65 6e   threshold, then
0e30: 20 74 68 65 20 73 65 74 20 6f 66 20 72 65 63 6f   the set of reco
0e40: 72 64 73 20 63 75 72 72 65 6e 74 6c 79 20 69 6e  rds currently in
0e50: 20 6d 65 6d 6f 72 79 20 61 72 65 20 73 6f 72 74   memory are sort
0e60: 65 64 20 61 6e 64 0a 2a 2a 20 77 72 69 74 74 65  ed and.** writte
0e70: 6e 20 74 6f 20 61 20 74 65 6d 70 6f 72 61 72 79  n to a temporary
0e80: 20 66 69 6c 65 20 69 6e 20 22 50 61 63 6b 65 64   file in "Packed
0e90: 20 4d 65 6d 6f 72 79 20 41 72 72 61 79 22 20 28   Memory Array" (
0ea0: 50 4d 41 29 20 66 6f 72 6d 61 74 2e 0a 2a 2a 20  PMA) format..** 
0eb0: 41 20 50 4d 41 20 63 72 65 61 74 65 64 20 61 74  A PMA created at
0ec0: 20 74 68 69 73 20 70 6f 69 6e 74 20 69 73 20 6b   this point is k
0ed0: 6e 6f 77 6e 20 61 73 20 61 20 22 6c 65 76 65 6c  nown as a "level
0ee0: 2d 30 20 50 4d 41 22 2e 20 48 69 67 68 65 72 20  -0 PMA". Higher 
0ef0: 6c 65 76 65 6c 73 0a 2a 2a 20 6f 66 20 50 4d 41  levels.** of PMA
0f00: 73 20 6d 61 79 20 62 65 20 63 72 65 61 74 65 64  s may be created
0f10: 20 62 79 20 6d 65 72 67 69 6e 67 20 65 78 69 73   by merging exis
0f20: 74 69 6e 67 20 50 4d 41 73 20 74 6f 67 65 74 68  ting PMAs togeth
0f30: 65 72 20 2d 20 66 6f 72 20 65 78 61 6d 70 6c 65  er - for example
0f40: 0a 2a 2a 20 6d 65 72 67 69 6e 67 20 74 77 6f 20  .** merging two 
0f50: 6f 72 20 6d 6f 72 65 20 6c 65 76 65 6c 2d 30 20  or more level-0 
0f60: 50 4d 41 73 20 74 6f 67 65 74 68 65 72 20 63 72  PMAs together cr
0f70: 65 61 74 65 73 20 61 20 6c 65 76 65 6c 2d 31 20  eates a level-1 
0f80: 50 4d 41 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 74  PMA..**.** The t
0f90: 68 72 65 73 68 6f 6c 64 20 66 6f 72 20 74 68 65  hreshold for the
0fa0: 20 61 6d 6f 75 6e 74 20 6f 66 20 6d 61 69 6e 20   amount of main 
0fb0: 6d 65 6d 6f 72 79 20 74 6f 20 75 73 65 20 62 65  memory to use be
0fc0: 66 6f 72 65 20 66 6c 75 73 68 69 6e 67 20 0a 2a  fore flushing .*
0fd0: 2a 20 72 65 63 6f 72 64 73 20 74 6f 20 61 20 50  * records to a P
0fe0: 4d 41 20 69 73 20 72 6f 75 67 68 6c 79 20 74 68  MA is roughly th
0ff0: 65 20 73 61 6d 65 20 61 73 20 74 68 65 20 6c 69  e same as the li
1000: 6d 69 74 20 63 6f 6e 66 69 67 75 72 65 64 20 66  mit configured f
1010: 6f 72 20 74 68 65 0a 2a 2a 20 70 61 67 65 2d 63  or the.** page-c
1020: 61 63 68 65 20 6f 66 20 74 68 65 20 6d 61 69 6e  ache of the main
1030: 20 64 61 74 61 62 61 73 65 2e 20 53 70 65 63 69   database. Speci
1040: 66 69 63 61 6c 6c 79 2c 20 74 68 65 20 74 68 72  fically, the thr
1050: 65 73 68 6f 6c 64 20 69 73 20 73 65 74 20 74 6f  eshold is set to
1060: 20 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 20 72   .** the value r
1070: 65 74 75 72 6e 65 64 20 6d 75 6c 74 69 70 6c 69  eturned multipli
1080: 65 64 20 62 79 20 22 50 52 41 47 4d 41 20 6d 61  ed by "PRAGMA ma
1090: 69 6e 2e 70 61 67 65 5f 73 69 7a 65 22 20 6d 75  in.page_size" mu
10a0: 6c 74 69 70 6c 65 64 20 62 79 20 0a 2a 2a 20 74  ltipled by .** t
10b0: 68 61 74 20 72 65 74 75 72 6e 65 64 20 62 79 20  hat returned by 
10c0: 22 50 52 41 47 4d 41 20 6d 61 69 6e 2e 63 61 63  "PRAGMA main.cac
10d0: 68 65 5f 73 69 7a 65 22 2c 20 69 6e 20 62 79 74  he_size", in byt
10e0: 65 73 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  es..**.** If the
10f0: 20 73 6f 72 74 65 72 20 69 73 20 72 75 6e 6e 69   sorter is runni
1100: 6e 67 20 69 6e 20 73 69 6e 67 6c 65 2d 74 68 72  ng in single-thr
1110: 65 61 64 65 64 20 6d 6f 64 65 2c 20 74 68 65 6e  eaded mode, then
1120: 20 61 6c 6c 20 50 4d 41 73 20 67 65 6e 65 72 61   all PMAs genera
1130: 74 65 64 0a 2a 2a 20 61 72 65 20 61 70 70 65 6e  ted.** are appen
1140: 64 65 64 20 74 6f 20 61 20 73 69 6e 67 6c 65 20  ded to a single 
1150: 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 2e 20  temporary file. 
1160: 4f 72 2c 20 69 66 20 74 68 65 20 73 6f 72 74 65  Or, if the sorte
1170: 72 20 69 73 20 72 75 6e 6e 69 6e 67 20 69 6e 0a  r is running in.
1180: 2a 2a 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65  ** multi-threade
1190: 64 20 6d 6f 64 65 20 74 68 65 6e 20 75 70 20 74  d mode then up t
11a0: 6f 20 28 4e 2b 31 29 20 74 65 6d 70 6f 72 61 72  o (N+1) temporar
11b0: 79 20 66 69 6c 65 73 20 6d 61 79 20 62 65 20 6f  y files may be o
11c0: 70 65 6e 65 64 2c 20 77 68 65 72 65 0a 2a 2a 20  pened, where.** 
11d0: 4e 20 69 73 20 74 68 65 20 63 6f 6e 66 69 67 75  N is the configu
11e0: 72 65 64 20 6e 75 6d 62 65 72 20 6f 66 20 77 6f  red number of wo
11f0: 72 6b 65 72 20 74 68 72 65 61 64 73 2e 20 49 6e  rker threads. In
1200: 20 74 68 69 73 20 63 61 73 65 2c 20 69 6e 73 74   this case, inst
1210: 65 61 64 20 6f 66 0a 2a 2a 20 73 6f 72 74 69 6e  ead of.** sortin
1220: 67 20 74 68 65 20 72 65 63 6f 72 64 73 20 61 6e  g the records an
1230: 64 20 77 72 69 74 69 6e 67 20 74 68 65 20 50 4d  d writing the PM
1240: 41 20 74 6f 20 61 20 74 65 6d 70 6f 72 61 72 79  A to a temporary
1250: 20 66 69 6c 65 20 69 74 73 65 6c 66 2c 20 74 68   file itself, th
1260: 65 0a 2a 2a 20 63 61 6c 6c 69 6e 67 20 74 68 72  e.** calling thr
1270: 65 61 64 20 75 73 75 61 6c 6c 79 20 6c 61 75 6e  ead usually laun
1280: 63 68 65 73 20 61 20 77 6f 72 6b 65 72 20 74 68  ches a worker th
1290: 72 65 61 64 20 74 6f 20 64 6f 20 73 6f 2e 20 45  read to do so. E
12a0: 78 63 65 70 74 2c 20 69 66 0a 2a 2a 20 74 68 65  xcept, if.** the
12b0: 72 65 20 61 72 65 20 61 6c 72 65 61 64 79 20 4e  re are already N
12c0: 20 77 6f 72 6b 65 72 20 74 68 72 65 61 64 73 20   worker threads 
12d0: 72 75 6e 6e 69 6e 67 2c 20 74 68 65 20 6d 61 69  running, the mai
12e0: 6e 20 74 68 72 65 61 64 20 64 6f 65 73 20 74 68  n thread does th
12f0: 65 20 77 6f 72 6b 0a 2a 2a 20 69 74 73 65 6c 66  e work.** itself
1300: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 6f 72 74  ..**.** The sort
1310: 65 72 20 69 73 20 72 75 6e 6e 69 6e 67 20 69 6e  er is running in
1320: 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20   multi-threaded 
1330: 6d 6f 64 65 20 69 66 20 28 61 29 20 74 68 65 20  mode if (a) the 
1340: 6c 69 62 72 61 72 79 20 77 61 73 20 62 75 69 6c  library was buil
1350: 74 0a 2a 2a 20 77 69 74 68 20 70 72 65 2d 70 72  t.** with pre-pr
1360: 6f 63 65 73 73 6f 72 20 73 79 6d 62 6f 6c 20 53  ocessor symbol S
1370: 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52  QLITE_MAX_WORKER
1380: 5f 54 48 52 45 41 44 53 20 73 65 74 20 74 6f 20  _THREADS set to 
1390: 61 20 76 61 6c 75 65 20 67 72 65 61 74 65 72 0a  a value greater.
13a0: 2a 2a 20 74 68 61 6e 20 7a 65 72 6f 2c 20 61 6e  ** than zero, an
13b0: 64 20 28 62 29 20 77 6f 72 6b 65 72 20 74 68 72  d (b) worker thr
13c0: 65 61 64 73 20 68 61 76 65 20 62 65 65 6e 20 65  eads have been e
13d0: 6e 61 62 6c 65 64 20 61 74 20 72 75 6e 74 69 6d  nabled at runtim
13e0: 65 20 62 79 20 63 61 6c 6c 69 6e 67 0a 2a 2a 20  e by calling.** 
13f0: 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53  sqlite3_config(S
1400: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 57 4f 52  QLITE_CONFIG_WOR
1410: 4b 45 52 5f 54 48 52 45 41 44 53 2c 20 2e 2e 2e  KER_THREADS, ...
1420: 29 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 52 65  )..**.** When Re
1430: 77 69 6e 64 28 29 20 69 73 20 63 61 6c 6c 65 64  wind() is called
1440: 2c 20 61 6e 79 20 64 61 74 61 20 72 65 6d 61 69  , any data remai
1450: 6e 69 6e 67 20 69 6e 20 6d 65 6d 6f 72 79 20 69  ning in memory i
1460: 73 20 66 6c 75 73 68 65 64 20 74 6f 20 61 20 0a  s flushed to a .
1470: 2a 2a 20 66 69 6e 61 6c 20 50 4d 41 2e 20 53 6f  ** final PMA. So
1480: 20 61 74 20 74 68 69 73 20 70 6f 69 6e 74 20 74   at this point t
1490: 68 65 20 64 61 74 61 20 69 73 20 73 74 6f 72 65  he data is store
14a0: 64 20 69 6e 20 73 6f 6d 65 20 6e 75 6d 62 65 72  d in some number
14b0: 20 6f 66 20 73 6f 72 74 65 64 0a 2a 2a 20 50 4d   of sorted.** PM
14c0: 41 73 20 77 69 74 68 69 6e 20 74 65 6d 70 6f 72  As within tempor
14d0: 61 72 79 20 66 69 6c 65 73 20 6f 6e 20 64 69 73  ary files on dis
14e0: 6b 2e 20 57 69 74 68 69 6e 20 61 20 73 69 6e 67  k. Within a sing
14f0: 6c 65 20 66 69 6c 65 20 73 6f 72 74 65 72 20 69  le file sorter i
1500: 73 20 0a 2a 2a 20 72 75 6e 6e 69 6e 67 20 69 6e  s .** running in
1510: 20 73 69 6e 67 6c 65 20 74 68 72 65 61 64 65 64   single threaded
1520: 20 6d 6f 64 65 2c 20 6f 72 20 64 69 73 74 72 69   mode, or distri
1530: 62 75 74 65 64 20 62 65 74 77 65 65 6e 20 6f 6e  buted between on
1540: 65 20 6f 72 20 6d 6f 72 65 20 66 69 6c 65 73 0a  e or more files.
1550: 2a 2a 20 66 6f 72 20 6d 75 6c 74 69 2d 74 68 72  ** for multi-thr
1560: 65 61 64 65 64 20 73 6f 72 74 65 72 73 2e 0a 2a  eaded sorters..*
1570: 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65 20 61 72  *.** If there ar
1580: 65 20 66 65 77 65 72 20 74 68 61 6e 20 53 4f 52  e fewer than SOR
1590: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
15a0: 55 4e 54 20 50 4d 41 73 20 69 6e 20 74 6f 74 61  UNT PMAs in tota
15b0: 6c 20 61 6e 64 20 74 68 65 0a 2a 2a 20 73 6f 72  l and the.** sor
15c0: 74 65 72 20 69 73 20 72 75 6e 6e 69 6e 67 20 69  ter is running i
15d0: 6e 20 73 69 6e 67 6c 65 2d 74 68 72 65 61 64 65  n single-threade
15e0: 64 20 6d 6f 64 65 2c 20 74 68 65 6e 20 74 68 65  d mode, then the
15f0: 73 65 20 50 4d 41 73 20 61 72 65 20 6d 65 72 67  se PMAs are merg
1600: 65 64 0a 2a 2a 20 69 6e 63 72 65 6d 65 6e 74 61  ed.** incrementa
1610: 6c 6c 79 20 61 73 20 6b 65 79 73 20 61 72 65 20  lly as keys are 
1620: 72 65 74 72 65 69 76 65 64 20 66 72 6f 6d 20 74  retreived from t
1630: 68 65 20 73 6f 72 74 65 72 20 62 79 20 74 68 65  he sorter by the
1640: 20 56 44 42 45 2e 20 53 65 65 0a 2a 2a 20 63 6f   VDBE. See.** co
1650: 6d 6d 65 6e 74 73 20 61 62 6f 76 65 20 6f 62 6a  mments above obj
1660: 65 63 74 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  ect MergeEngine 
1670: 62 65 6c 6f 77 20 66 6f 72 20 64 65 74 61 69 6c  below for detail
1680: 73 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 69 66 20  s..**.** Or, if 
1690: 72 75 6e 6e 69 6e 67 20 69 6e 20 6d 75 6c 74 69  running in multi
16a0: 2d 74 68 72 65 61 64 65 64 20 6d 6f 64 65 2c 20  -threaded mode, 
16b0: 74 68 65 6e 20 61 20 62 61 63 6b 67 72 6f 75 6e  then a backgroun
16c0: 64 20 74 68 72 65 61 64 20 69 73 0a 2a 2a 20 6c  d thread is.** l
16d0: 61 75 6e 63 68 65 64 20 74 6f 20 6d 65 72 67 65  aunched to merge
16e0: 20 74 68 65 20 65 78 69 73 74 69 6e 67 20 50 4d   the existing PM
16f0: 41 73 2e 20 4f 6e 63 65 20 74 68 65 20 62 61 63  As. Once the bac
1700: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 68  kground thread h
1710: 61 73 0a 2a 2a 20 6d 65 72 67 65 64 20 54 20 62  as.** merged T b
1720: 79 74 65 73 20 6f 66 20 64 61 74 61 20 69 6e 74  ytes of data int
1730: 6f 20 61 20 73 69 6e 67 6c 65 20 73 6f 72 74 65  o a single sorte
1740: 64 20 50 4d 41 2c 20 74 68 65 20 6d 61 69 6e 20  d PMA, the main 
1750: 74 68 72 65 61 64 20 0a 2a 2a 20 62 65 67 69 6e  thread .** begin
1760: 73 20 72 65 61 64 69 6e 67 20 6b 65 79 73 20 66  s reading keys f
1770: 72 6f 6d 20 74 68 61 74 20 50 4d 41 20 77 68 69  rom that PMA whi
1780: 6c 65 20 74 68 65 20 62 61 63 6b 67 72 6f 75 6e  le the backgroun
1790: 64 20 74 68 72 65 61 64 20 70 72 6f 63 65 65 64  d thread proceed
17a0: 73 0a 2a 2a 20 77 69 74 68 20 6d 65 72 67 69 6e  s.** with mergin
17b0: 67 20 74 68 65 20 6e 65 78 74 20 54 20 62 79 74  g the next T byt
17c0: 65 73 20 6f 66 20 64 61 74 61 2e 20 41 6e 64 20  es of data. And 
17d0: 73 6f 20 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 50 61 72  so on..**.** Par
17e0: 61 6d 65 74 65 72 20 54 20 69 73 20 73 65 74 20  ameter T is set 
17f0: 74 6f 20 68 61 6c 66 20 74 68 65 20 76 61 6c 75  to half the valu
1800: 65 20 6f 66 20 74 68 65 20 6d 65 6d 6f 72 79 20  e of the memory 
1810: 74 68 72 65 73 68 6f 6c 64 20 75 73 65 64 20 0a  threshold used .
1820: 2a 2a 20 62 79 20 57 72 69 74 65 28 29 20 61 62  ** by Write() ab
1830: 6f 76 65 20 74 6f 20 64 65 74 65 72 6d 69 6e 65  ove to determine
1840: 20 77 68 65 6e 20 74 6f 20 63 72 65 61 74 65 20   when to create 
1850: 61 20 6e 65 77 20 50 4d 41 2e 0a 2a 2a 0a 2a 2a  a new PMA..**.**
1860: 20 49 66 20 74 68 65 72 65 20 61 72 65 20 6d 6f   If there are mo
1870: 72 65 20 74 68 61 6e 20 53 4f 52 54 45 52 5f 4d  re than SORTER_M
1880: 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20 50  AX_MERGE_COUNT P
1890: 4d 41 73 20 69 6e 20 74 6f 74 61 6c 20 77 68 65  MAs in total whe
18a0: 6e 20 0a 2a 2a 20 52 65 77 69 6e 64 28 29 20 69  n .** Rewind() i
18b0: 73 20 63 61 6c 6c 65 64 2c 20 74 68 65 6e 20 61  s called, then a
18c0: 20 68 69 65 72 61 72 63 68 79 20 6f 66 20 69 6e   hierarchy of in
18d0: 63 72 65 6d 65 6e 74 61 6c 2d 6d 65 72 67 65 73  cremental-merges
18e0: 20 69 73 20 75 73 65 64 2e 20 0a 2a 2a 20 46 69   is used. .** Fi
18f0: 72 73 74 2c 20 54 20 62 79 74 65 73 20 6f 66 20  rst, T bytes of 
1900: 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 66 69  data from the fi
1910: 72 73 74 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  rst SORTER_MAX_M
1920: 45 52 47 45 5f 43 4f 55 4e 54 20 50 4d 41 73 20  ERGE_COUNT PMAs 
1930: 6f 6e 20 0a 2a 2a 20 64 69 73 6b 20 61 72 65 20  on .** disk are 
1940: 6d 65 72 67 65 64 20 74 6f 67 65 74 68 65 72 2e  merged together.
1950: 20 54 68 65 6e 20 54 20 62 79 74 65 73 20 6f 66   Then T bytes of
1960: 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 73   data from the s
1970: 65 63 6f 6e 64 20 73 65 74 2c 20 61 6e 64 0a 2a  econd set, and.*
1980: 2a 20 73 6f 20 6f 6e 2c 20 73 75 63 68 20 74 68  * so on, such th
1990: 61 74 20 6e 6f 20 6f 70 65 72 61 74 69 6f 6e 20  at no operation 
19a0: 65 76 65 72 20 6d 65 72 67 65 73 20 6d 6f 72 65  ever merges more
19b0: 20 74 68 61 6e 20 53 4f 52 54 45 52 5f 4d 41 58   than SORTER_MAX
19c0: 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 0a 2a 2a 20  _MERGE_COUNT.** 
19d0: 50 4d 41 73 20 61 74 20 61 20 74 69 6d 65 2e 20  PMAs at a time. 
19e0: 54 68 69 73 20 64 6f 6e 65 20 69 73 20 74 6f 20  This done is to 
19f0: 69 6d 70 72 6f 76 65 20 6c 6f 63 61 6c 69 74 79  improve locality
1a00: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 72 75 6e 6e 69  ..**.** If runni
1a10: 6e 67 20 69 6e 20 6d 75 6c 74 69 2d 74 68 72 65  ng in multi-thre
1a20: 61 64 65 64 20 6d 6f 64 65 20 61 6e 64 20 74 68  aded mode and th
1a30: 65 72 65 20 61 72 65 20 6d 6f 72 65 20 74 68 61  ere are more tha
1a40: 6e 0a 2a 2a 20 53 4f 52 54 45 52 5f 4d 41 58 5f  n.** SORTER_MAX_
1a50: 4d 45 52 47 45 5f 43 4f 55 4e 54 20 50 4d 41 73  MERGE_COUNT PMAs
1a60: 20 6f 6e 20 64 69 73 6b 20 77 68 65 6e 20 52 65   on disk when Re
1a70: 77 69 6e 64 28 29 20 69 73 20 63 61 6c 6c 65 64  wind() is called
1a80: 2c 20 74 68 65 6e 20 6d 6f 72 65 0a 2a 2a 20 74  , then more.** t
1a90: 68 61 6e 20 6f 6e 65 20 62 61 63 6b 67 72 6f 75  han one backgrou
1aa0: 6e 64 20 74 68 72 65 61 64 20 6d 61 79 20 62 65  nd thread may be
1ab0: 20 63 72 65 61 74 65 64 2e 20 53 70 65 63 69 66   created. Specif
1ac0: 69 63 61 6c 6c 79 2c 20 74 68 65 72 65 20 6d 61  ically, there ma
1ad0: 79 20 62 65 0a 2a 2a 20 6f 6e 65 20 62 61 63 6b  y be.** one back
1ae0: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 66 6f  ground thread fo
1af0: 72 20 65 61 63 68 20 74 65 6d 70 6f 72 61 72 79  r each temporary
1b00: 20 66 69 6c 65 20 6f 6e 20 64 69 73 6b 2c 20 61   file on disk, a
1b10: 6e 64 20 6f 6e 65 20 62 61 63 6b 67 72 6f 75 6e  nd one backgroun
1b20: 64 0a 2a 2a 20 74 68 72 65 61 64 20 74 6f 20 6d  d.** thread to m
1b30: 65 72 67 65 20 74 68 65 20 6f 75 74 70 75 74 20  erge the output 
1b40: 6f 66 20 65 61 63 68 20 6f 66 20 74 68 65 20 6f  of each of the o
1b50: 74 68 65 72 73 20 74 6f 20 61 20 73 69 6e 67 6c  thers to a singl
1b60: 65 20 50 4d 41 20 66 6f 72 0a 2a 2a 20 74 68 65  e PMA for.** the
1b70: 20 6d 61 69 6e 20 74 68 72 65 61 64 20 74 6f 20   main thread to 
1b80: 72 65 61 64 20 66 72 6f 6d 2e 0a 2a 2f 0a 23 69  read from..*/.#i
1b90: 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65 49 6e  nclude "sqliteIn
1ba0: 74 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 76  t.h".#include "v
1bb0: 64 62 65 49 6e 74 2e 68 22 0a 0a 2f 2a 20 0a 2a  dbeInt.h"../* .*
1bc0: 2a 20 49 66 20 53 51 4c 49 54 45 5f 44 45 42 55  * If SQLITE_DEBU
1bd0: 47 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44 53  G_SORTER_THREADS
1be0: 20 69 73 20 64 65 66 69 6e 65 64 2c 20 74 68 69   is defined, thi
1bf0: 73 20 6d 6f 64 75 6c 65 20 6f 75 74 70 75 74 73  s module outputs
1c00: 20 76 61 72 69 6f 75 73 0a 2a 2a 20 6d 65 73 73   various.** mess
1c10: 61 67 65 73 20 74 6f 20 73 74 64 65 72 72 20 74  ages to stderr t
1c20: 68 61 74 20 6d 61 79 20 62 65 20 68 65 6c 70 66  hat may be helpf
1c30: 75 6c 20 69 6e 20 75 6e 64 65 72 73 74 61 6e 64  ul in understand
1c40: 69 6e 67 20 74 68 65 20 70 65 72 66 6f 72 6d 61  ing the performa
1c50: 6e 63 65 0a 2a 2a 20 63 68 61 72 61 63 74 65 72  nce.** character
1c60: 69 73 74 69 63 73 20 6f 66 20 74 68 65 20 73 6f  istics of the so
1c70: 72 74 65 72 20 69 6e 20 6d 75 6c 74 69 2d 74 68  rter in multi-th
1c80: 72 65 61 64 65 64 20 6d 6f 64 65 2e 0a 2a 2f 0a  readed mode..*/.
1c90: 23 69 66 20 30 0a 23 20 64 65 66 69 6e 65 20 53  #if 0.# define S
1ca0: 51 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f 52 54  QLITE_DEBUG_SORT
1cb0: 45 52 5f 54 48 52 45 41 44 53 20 31 0a 23 65 6e  ER_THREADS 1.#en
1cc0: 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 76 61  dif../*.** Priva
1cd0: 74 65 20 6f 62 6a 65 63 74 73 20 75 73 65 64 20  te objects used 
1ce0: 62 79 20 74 68 65 20 73 6f 72 74 65 72 0a 2a 2f  by the sorter.*/
1cf0: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
1d00: 4d 65 72 67 65 45 6e 67 69 6e 65 20 4d 65 72 67  MergeEngine Merg
1d10: 65 45 6e 67 69 6e 65 3b 20 20 20 20 20 2f 2a 20  eEngine;     /* 
1d20: 4d 65 72 67 65 20 50 4d 41 73 20 74 6f 67 65 74  Merge PMAs toget
1d30: 68 65 72 20 2a 2f 0a 74 79 70 65 64 65 66 20 73  her */.typedef s
1d40: 74 72 75 63 74 20 50 6d 61 52 65 61 64 65 72 20  truct PmaReader 
1d50: 50 6d 61 52 65 61 64 65 72 3b 20 20 20 20 20 20  PmaReader;      
1d60: 20 20 20 2f 2a 20 49 6e 63 72 65 6d 65 6e 74 61     /* Incrementa
1d70: 6c 6c 79 20 72 65 61 64 20 6f 6e 65 20 50 4d 41  lly read one PMA
1d80: 20 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75   */.typedef stru
1d90: 63 74 20 50 6d 61 57 72 69 74 65 72 20 50 6d 61  ct PmaWriter Pma
1da0: 57 72 69 74 65 72 3b 20 20 20 20 20 20 20 20 20  Writer;         
1db0: 2f 2a 20 49 6e 63 72 65 6d 65 6e 74 61 6c 6c 79  /* Incrementally
1dc0: 20 77 72 69 74 65 20 6f 6e 65 20 50 4d 41 20 2a   write one PMA *
1dd0: 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  /.typedef struct
1de0: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 53 6f   SorterRecord So
1df0: 72 74 65 72 52 65 63 6f 72 64 3b 20 20 20 2f 2a  rterRecord;   /*
1e00: 20 41 20 72 65 63 6f 72 64 20 62 65 69 6e 67 20   A record being 
1e10: 73 6f 72 74 65 64 20 2a 2f 0a 74 79 70 65 64 65  sorted */.typede
1e20: 66 20 73 74 72 75 63 74 20 53 6f 72 74 53 75 62  f struct SortSub
1e30: 74 61 73 6b 20 53 6f 72 74 53 75 62 74 61 73 6b  task SortSubtask
1e40: 3b 20 20 20 20 20 2f 2a 20 41 20 73 75 62 2d 74  ;     /* A sub-t
1e50: 61 73 6b 20 69 6e 20 74 68 65 20 73 6f 72 74 20  ask in the sort 
1e60: 70 72 6f 63 65 73 73 20 2a 2f 0a 74 79 70 65 64  process */.typed
1e70: 65 66 20 73 74 72 75 63 74 20 53 6f 72 74 65 72  ef struct Sorter
1e80: 46 69 6c 65 20 53 6f 72 74 65 72 46 69 6c 65 3b  File SorterFile;
1e90: 20 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72         /* Tempor
1ea0: 61 72 79 20 66 69 6c 65 20 6f 62 6a 65 63 74 20  ary file object 
1eb0: 77 72 61 70 70 65 72 20 2a 2f 0a 74 79 70 65 64  wrapper */.typed
1ec0: 65 66 20 73 74 72 75 63 74 20 53 6f 72 74 65 72  ef struct Sorter
1ed0: 4c 69 73 74 20 53 6f 72 74 65 72 4c 69 73 74 3b  List SorterList;
1ee0: 20 20 20 20 20 20 20 2f 2a 20 49 6e 2d 6d 65 6d         /* In-mem
1ef0: 6f 72 79 20 6c 69 73 74 20 6f 66 20 72 65 63 6f  ory list of reco
1f00: 72 64 73 20 2a 2f 0a 74 79 70 65 64 65 66 20 73  rds */.typedef s
1f10: 74 72 75 63 74 20 49 6e 63 72 4d 65 72 67 65 72  truct IncrMerger
1f20: 20 49 6e 63 72 4d 65 72 67 65 72 3b 0a 0a 2f 2a   IncrMerger;../*
1f30: 0a 2a 2a 20 41 20 63 6f 6e 74 61 69 6e 65 72 20  .** A container 
1f40: 66 6f 72 20 61 20 74 65 6d 70 20 66 69 6c 65 20  for a temp file 
1f50: 68 61 6e 64 6c 65 20 61 6e 64 20 74 68 65 20 63  handle and the c
1f60: 75 72 72 65 6e 74 20 61 6d 6f 75 6e 74 20 6f 66  urrent amount of
1f70: 20 64 61 74 61 20 0a 2a 2a 20 73 74 6f 72 65 64   data .** stored
1f80: 20 69 6e 20 74 68 65 20 66 69 6c 65 2e 0a 2a 2f   in the file..*/
1f90: 0a 73 74 72 75 63 74 20 53 6f 72 74 65 72 46 69  .struct SorterFi
1fa0: 6c 65 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66  le {.  sqlite3_f
1fb0: 69 6c 65 20 2a 70 46 64 3b 20 20 20 20 20 20 20  ile *pFd;       
1fc0: 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 68         /* File h
1fd0: 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 36 34 20 69  andle */.  i64 i
1fe0: 45 6f 66 3b 20 20 20 20 20 20 20 20 20 20 20 20  Eof;            
1ff0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79             /* By
2000: 74 65 73 20 6f 66 20 64 61 74 61 20 73 74 6f 72  tes of data stor
2010: 65 64 20 69 6e 20 70 46 64 20 2a 2f 0a 7d 3b 0a  ed in pFd */.};.
2020: 0a 2f 2a 0a 2a 2a 20 49 6e 20 6d 65 6d 6f 72 79  ./*.** In memory
2030: 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20   linked list of 
2040: 72 65 63 6f 72 64 73 2e 0a 2a 2f 0a 73 74 72 75  records..*/.stru
2050: 63 74 20 53 6f 72 74 65 72 4c 69 73 74 20 7b 0a  ct SorterList {.
2060: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
2070: 70 4c 69 73 74 3b 20 20 20 20 20 20 20 20 20 20  pList;          
2080: 20 20 2f 2a 20 4c 69 6e 6b 65 64 20 6c 69 73 74    /* Linked list
2090: 20 6f 66 20 72 65 63 6f 72 64 73 20 2a 2f 0a 20   of records */. 
20a0: 20 75 38 20 2a 61 4d 65 6d 6f 72 79 3b 20 20 20   u8 *aMemory;   
20b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20c0: 20 2f 2a 20 49 66 20 6e 6f 6e 2d 4e 55 4c 4c 2c   /* If non-NULL,
20d0: 20 62 6c 6f 62 20 6f 66 20 6d 65 6d 6f 72 79 20   blob of memory 
20e0: 66 6f 72 20 70 4c 69 73 74 20 2a 2f 0a 20 20 69  for pList */.  i
20f0: 6e 74 20 73 7a 50 4d 41 3b 20 20 20 20 20 20 20  nt szPMA;       
2100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2110: 2a 20 53 69 7a 65 20 6f 66 20 70 4c 69 73 74 20  * Size of pList 
2120: 61 73 20 50 4d 41 20 69 6e 20 62 79 74 65 73 20  as PMA in bytes 
2130: 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65  */.};../*.** The
2140: 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 6f 62 6a   MergeEngine obj
2150: 65 63 74 20 69 73 20 75 73 65 64 20 74 6f 20 63  ect is used to c
2160: 6f 6d 62 69 6e 65 20 74 77 6f 20 6f 72 20 6d 6f  ombine two or mo
2170: 72 65 20 73 6d 61 6c 6c 65 72 20 50 4d 41 73 20  re smaller PMAs 
2180: 69 6e 74 6f 0a 2a 2a 20 6f 6e 65 20 62 69 67 20  into.** one big 
2190: 50 4d 41 20 75 73 69 6e 67 20 61 20 6d 65 72 67  PMA using a merg
21a0: 65 20 6f 70 65 72 61 74 69 6f 6e 2e 20 20 53 65  e operation.  Se
21b0: 70 61 72 61 74 65 20 50 4d 41 73 20 61 6c 6c 20  parate PMAs all 
21c0: 6e 65 65 64 20 74 6f 20 62 65 0a 2a 2a 20 63 6f  need to be.** co
21d0: 6d 62 69 6e 65 64 20 69 6e 74 6f 20 6f 6e 65 20  mbined into one 
21e0: 62 69 67 20 50 4d 41 20 69 6e 20 6f 72 64 65 72  big PMA in order
21f0: 20 74 6f 20 62 65 20 61 62 6c 65 20 74 6f 20 73   to be able to s
2200: 74 65 70 20 74 68 72 6f 75 67 68 20 74 68 65 20  tep through the 
2210: 73 6f 72 74 65 64 0a 2a 2a 20 72 65 63 6f 72 64  sorted.** record
2220: 73 20 69 6e 20 6f 72 64 65 72 2e 0a 2a 2a 0a 2a  s in order..**.*
2230: 2a 20 54 68 65 20 61 49 74 65 72 5b 5d 20 61 72  * The aIter[] ar
2240: 72 61 79 20 63 6f 6e 74 61 69 6e 73 20 61 20 50  ray contains a P
2250: 6d 61 52 65 61 64 65 72 20 6f 62 6a 65 63 74 20  maReader object 
2260: 66 6f 72 20 65 61 63 68 20 6f 66 20 74 68 65 20  for each of the 
2270: 50 4d 41 73 20 62 65 69 6e 67 0a 2a 2a 20 6d 65  PMAs being.** me
2280: 72 67 65 64 2e 20 20 41 6e 20 61 49 74 65 72 5b  rged.  An aIter[
2290: 5d 20 6f 62 6a 65 63 74 20 65 69 74 68 65 72 20  ] object either 
22a0: 70 6f 69 6e 74 73 20 74 6f 20 61 20 76 61 6c 69  points to a vali
22b0: 64 20 6b 65 79 20 6f 72 20 65 6c 73 65 20 69 73  d key or else is
22c0: 20 61 74 20 45 4f 46 2e 0a 2a 2a 20 46 6f 72 20   at EOF..** For 
22d0: 74 68 65 20 70 75 72 70 6f 73 65 73 20 6f 66 20  the purposes of 
22e0: 74 68 65 20 70 61 72 61 67 72 61 70 68 73 20 62  the paragraphs b
22f0: 65 6c 6f 77 2c 20 77 65 20 61 73 73 75 6d 65 20  elow, we assume 
2300: 74 68 61 74 20 74 68 65 20 61 72 72 61 79 20 69  that the array i
2310: 73 0a 2a 2a 20 61 63 74 75 61 6c 6c 79 20 4e 20  s.** actually N 
2320: 65 6c 65 6d 65 6e 74 73 20 69 6e 20 73 69 7a 65  elements in size
2330: 2c 20 77 68 65 72 65 20 4e 20 69 73 20 74 68 65  , where N is the
2340: 20 73 6d 61 6c 6c 65 73 74 20 70 6f 77 65 72 20   smallest power 
2350: 6f 66 20 32 20 67 72 65 61 74 65 72 0a 2a 2a 20  of 2 greater.** 
2360: 74 6f 20 6f 72 20 65 71 75 61 6c 20 74 6f 20 74  to or equal to t
2370: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 50 4d 41  he number of PMA
2380: 73 20 62 65 69 6e 67 20 6d 65 72 67 65 64 2e 20  s being merged. 
2390: 54 68 65 20 65 78 74 72 61 20 61 49 74 65 72 5b  The extra aIter[
23a0: 5d 20 65 6c 65 6d 65 6e 74 73 0a 2a 2a 20 61 72  ] elements.** ar
23b0: 65 20 74 72 65 61 74 65 64 20 61 73 20 69 66 20  e treated as if 
23c0: 74 68 65 79 20 61 72 65 20 65 6d 70 74 79 20 28  they are empty (
23d0: 61 6c 77 61 79 73 20 61 74 20 45 4f 46 29 2e 0a  always at EOF)..
23e0: 2a 2a 0a 2a 2a 20 54 68 65 20 61 54 72 65 65 5b  **.** The aTree[
23f0: 5d 20 61 72 72 61 79 20 69 73 20 61 6c 73 6f 20  ] array is also 
2400: 4e 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 73 69  N elements in si
2410: 7a 65 2e 20 54 68 65 20 76 61 6c 75 65 20 6f 66  ze. The value of
2420: 20 4e 20 69 73 20 73 74 6f 72 65 64 20 69 6e 0a   N is stored in.
2430: 2a 2a 20 74 68 65 20 4d 65 72 67 65 45 6e 67 69  ** the MergeEngi
2440: 6e 65 2e 6e 54 72 65 65 20 76 61 72 69 61 62 6c  ne.nTree variabl
2450: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66 69 6e  e..**.** The fin
2460: 61 6c 20 28 4e 2f 32 29 20 65 6c 65 6d 65 6e 74  al (N/2) element
2470: 73 20 6f 66 20 61 54 72 65 65 5b 5d 20 63 6f 6e  s of aTree[] con
2480: 74 61 69 6e 20 74 68 65 20 72 65 73 75 6c 74 73  tain the results
2490: 20 6f 66 20 63 6f 6d 70 61 72 69 6e 67 0a 2a 2a   of comparing.**
24a0: 20 70 61 69 72 73 20 6f 66 20 50 4d 41 20 6b 65   pairs of PMA ke
24b0: 79 73 20 74 6f 67 65 74 68 65 72 2e 20 45 6c 65  ys together. Ele
24c0: 6d 65 6e 74 20 69 20 63 6f 6e 74 61 69 6e 73 20  ment i contains 
24d0: 74 68 65 20 72 65 73 75 6c 74 20 6f 66 20 0a 2a  the result of .*
24e0: 2a 20 63 6f 6d 70 61 72 69 6e 67 20 61 49 74 65  * comparing aIte
24f0: 72 5b 32 2a 69 2d 4e 5d 20 61 6e 64 20 61 49 74  r[2*i-N] and aIt
2500: 65 72 5b 32 2a 69 2d 4e 2b 31 5d 2e 20 57 68 69  er[2*i-N+1]. Whi
2510: 63 68 65 76 65 72 20 6b 65 79 20 69 73 20 73 6d  chever key is sm
2520: 61 6c 6c 65 72 2c 20 74 68 65 0a 2a 2a 20 61 54  aller, the.** aT
2530: 72 65 65 20 65 6c 65 6d 65 6e 74 20 69 73 20 73  ree element is s
2540: 65 74 20 74 6f 20 74 68 65 20 69 6e 64 65 78 20  et to the index 
2550: 6f 66 20 69 74 2e 20 0a 2a 2a 0a 2a 2a 20 46 6f  of it. .**.** Fo
2560: 72 20 74 68 65 20 70 75 72 70 6f 73 65 73 20 6f  r the purposes o
2570: 66 20 74 68 69 73 20 63 6f 6d 70 61 72 69 73 6f  f this compariso
2580: 6e 2c 20 45 4f 46 20 69 73 20 63 6f 6e 73 69 64  n, EOF is consid
2590: 65 72 65 64 20 67 72 65 61 74 65 72 20 74 68 61  ered greater tha
25a0: 6e 20 61 6e 79 0a 2a 2a 20 6f 74 68 65 72 20 6b  n any.** other k
25b0: 65 79 20 76 61 6c 75 65 2e 20 49 66 20 74 68 65  ey value. If the
25c0: 20 6b 65 79 73 20 61 72 65 20 65 71 75 61 6c 20   keys are equal 
25d0: 28 6f 6e 6c 79 20 70 6f 73 73 69 62 6c 65 20 77  (only possible w
25e0: 69 74 68 20 74 77 6f 20 45 4f 46 0a 2a 2a 20 76  ith two EOF.** v
25f0: 61 6c 75 65 73 29 2c 20 69 74 20 64 6f 65 73 6e  alues), it doesn
2600: 27 74 20 6d 61 74 74 65 72 20 77 68 69 63 68 20  't matter which 
2610: 69 6e 64 65 78 20 69 73 20 73 74 6f 72 65 64 2e  index is stored.
2620: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 28 4e 2f 34 29  .**.** The (N/4)
2630: 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20 61 54 72   elements of aTr
2640: 65 65 5b 5d 20 74 68 61 74 20 70 72 65 63 65 64  ee[] that preced
2650: 65 20 74 68 65 20 66 69 6e 61 6c 20 28 4e 2f 32  e the final (N/2
2660: 29 20 64 65 73 63 72 69 62 65 64 20 0a 2a 2a 20  ) described .** 
2670: 61 62 6f 76 65 20 63 6f 6e 74 61 69 6e 73 20 74  above contains t
2680: 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20  he index of the 
2690: 73 6d 61 6c 6c 65 73 74 20 6f 66 20 65 61 63 68  smallest of each
26a0: 20 62 6c 6f 63 6b 20 6f 66 20 34 20 69 74 65 72   block of 4 iter
26b0: 61 74 6f 72 73 2e 0a 2a 2a 20 41 6e 64 20 73 6f  ators..** And so
26c0: 20 6f 6e 2e 20 53 6f 20 74 68 61 74 20 61 54 72   on. So that aTr
26d0: 65 65 5b 31 5d 20 63 6f 6e 74 61 69 6e 73 20 74  ee[1] contains t
26e0: 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20  he index of the 
26f0: 69 74 65 72 61 74 6f 72 20 74 68 61 74 20 0a 2a  iterator that .*
2700: 2a 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e  * currently poin
2710: 74 73 20 74 6f 20 74 68 65 20 73 6d 61 6c 6c 65  ts to the smalle
2720: 73 74 20 6b 65 79 20 76 61 6c 75 65 2e 20 61 54  st key value. aT
2730: 72 65 65 5b 30 5d 20 69 73 20 75 6e 75 73 65 64  ree[0] is unused
2740: 2e 0a 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65 3a  ..**.** Example:
2750: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 49 74 65 72  .**.**     aIter
2760: 5b 30 5d 20 2d 3e 20 42 61 6e 61 6e 61 0a 2a 2a  [0] -> Banana.**
2770: 20 20 20 20 20 61 49 74 65 72 5b 31 5d 20 2d 3e       aIter[1] ->
2780: 20 46 65 69 6a 6f 61 0a 2a 2a 20 20 20 20 20 61   Feijoa.**     a
2790: 49 74 65 72 5b 32 5d 20 2d 3e 20 45 6c 64 65 72  Iter[2] -> Elder
27a0: 62 65 72 72 79 0a 2a 2a 20 20 20 20 20 61 49 74  berry.**     aIt
27b0: 65 72 5b 33 5d 20 2d 3e 20 43 75 72 72 61 6e 74  er[3] -> Currant
27c0: 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 34 5d  .**     aIter[4]
27d0: 20 2d 3e 20 47 72 61 70 65 66 72 75 69 74 0a 2a   -> Grapefruit.*
27e0: 2a 20 20 20 20 20 61 49 74 65 72 5b 35 5d 20 2d  *     aIter[5] -
27f0: 3e 20 41 70 70 6c 65 0a 2a 2a 20 20 20 20 20 61  > Apple.**     a
2800: 49 74 65 72 5b 36 5d 20 2d 3e 20 44 75 72 69 61  Iter[6] -> Duria
2810: 6e 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 37  n.**     aIter[7
2820: 5d 20 2d 3e 20 45 4f 46 0a 2a 2a 0a 2a 2a 20 20  ] -> EOF.**.**  
2830: 20 20 20 61 54 72 65 65 5b 5d 20 3d 20 7b 20 58     aTree[] = { X
2840: 2c 20 35 20 20 20 30 2c 20 35 20 20 20 20 30 2c  , 5   0, 5    0,
2850: 20 33 2c 20 35 2c 20 36 20 7d 0a 2a 2a 0a 2a 2a   3, 5, 6 }.**.**
2860: 20 54 68 65 20 63 75 72 72 65 6e 74 20 65 6c 65   The current ele
2870: 6d 65 6e 74 20 69 73 20 22 41 70 70 6c 65 22 20  ment is "Apple" 
2880: 28 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68  (the value of th
2890: 65 20 6b 65 79 20 69 6e 64 69 63 61 74 65 64 20  e key indicated 
28a0: 62 79 20 0a 2a 2a 20 69 74 65 72 61 74 6f 72 20  by .** iterator 
28b0: 35 29 2e 20 57 68 65 6e 20 74 68 65 20 4e 65 78  5). When the Nex
28c0: 74 28 29 20 6f 70 65 72 61 74 69 6f 6e 20 69 73  t() operation is
28d0: 20 69 6e 76 6f 6b 65 64 2c 20 69 74 65 72 61 74   invoked, iterat
28e0: 6f 72 20 35 20 77 69 6c 6c 0a 2a 2a 20 62 65 20  or 5 will.** be 
28f0: 61 64 76 61 6e 63 65 64 20 74 6f 20 74 68 65 20  advanced to the 
2900: 6e 65 78 74 20 6b 65 79 20 69 6e 20 69 74 73 20  next key in its 
2910: 73 65 67 6d 65 6e 74 2e 20 53 61 79 20 74 68 65  segment. Say the
2920: 20 6e 65 78 74 20 6b 65 79 20 69 73 0a 2a 2a 20   next key is.** 
2930: 22 45 67 67 70 6c 61 6e 74 22 3a 0a 2a 2a 0a 2a  "Eggplant":.**.*
2940: 2a 20 20 20 20 20 61 49 74 65 72 5b 35 5d 20 2d  *     aIter[5] -
2950: 3e 20 45 67 67 70 6c 61 6e 74 0a 2a 2a 0a 2a 2a  > Eggplant.**.**
2960: 20 54 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   The contents of
2970: 20 61 54 72 65 65 5b 5d 20 61 72 65 20 75 70 64   aTree[] are upd
2980: 61 74 65 64 20 66 69 72 73 74 20 62 79 20 63 6f  ated first by co
2990: 6d 70 61 72 69 6e 67 20 74 68 65 20 6e 65 77 20  mparing the new 
29a0: 69 74 65 72 61 74 6f 72 0a 2a 2a 20 35 20 6b 65  iterator.** 5 ke
29b0: 79 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e 74  y to the current
29c0: 20 6b 65 79 20 6f 66 20 69 74 65 72 61 74 6f 72   key of iterator
29d0: 20 34 20 28 73 74 69 6c 6c 20 22 47 72 61 70 65   4 (still "Grape
29e0: 66 72 75 69 74 22 29 2e 20 54 68 65 20 69 74 65  fruit"). The ite
29f0: 72 61 74 6f 72 0a 2a 2a 20 35 20 76 61 6c 75 65  rator.** 5 value
2a00: 20 69 73 20 73 74 69 6c 6c 20 73 6d 61 6c 6c 65   is still smalle
2a10: 72 2c 20 73 6f 20 61 54 72 65 65 5b 36 5d 20 69  r, so aTree[6] i
2a20: 73 20 73 65 74 20 74 6f 20 35 2e 20 41 6e 64 20  s set to 5. And 
2a30: 73 6f 20 6f 6e 20 75 70 20 74 68 65 20 74 72 65  so on up the tre
2a40: 65 2e 0a 2a 2a 20 54 68 65 20 76 61 6c 75 65 20  e..** The value 
2a50: 6f 66 20 69 74 65 72 61 74 6f 72 20 36 20 2d 20  of iterator 6 - 
2a60: 22 44 75 72 69 61 6e 22 20 2d 20 69 73 20 6e 6f  "Durian" - is no
2a70: 77 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 74  w smaller than t
2a80: 68 61 74 20 6f 66 20 69 74 65 72 61 74 6f 72 0a  hat of iterator.
2a90: 2a 2a 20 35 2c 20 73 6f 20 61 54 72 65 65 5b 33  ** 5, so aTree[3
2aa0: 5d 20 69 73 20 73 65 74 20 74 6f 20 36 2e 20 4b  ] is set to 6. K
2ab0: 65 79 20 30 20 69 73 20 73 6d 61 6c 6c 65 72 20  ey 0 is smaller 
2ac0: 74 68 61 6e 20 6b 65 79 20 36 20 28 42 61 6e 61  than key 6 (Bana
2ad0: 6e 61 3c 44 75 72 69 61 6e 29 2c 0a 2a 2a 20 73  na<Durian),.** s
2ae0: 6f 20 74 68 65 20 76 61 6c 75 65 20 77 72 69 74  o the value writ
2af0: 74 65 6e 20 69 6e 74 6f 20 65 6c 65 6d 65 6e 74  ten into element
2b00: 20 31 20 6f 66 20 74 68 65 20 61 72 72 61 79 20   1 of the array 
2b10: 69 73 20 30 2e 20 41 73 20 66 6f 6c 6c 6f 77 73  is 0. As follows
2b20: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 54 72 65  :.**.**     aTre
2b30: 65 5b 5d 20 3d 20 7b 20 58 2c 20 30 20 20 20 30  e[] = { X, 0   0
2b40: 2c 20 36 20 20 20 20 30 2c 20 33 2c 20 35 2c 20  , 6    0, 3, 5, 
2b50: 36 20 7d 0a 2a 2a 0a 2a 2a 20 49 6e 20 6f 74 68  6 }.**.** In oth
2b60: 65 72 20 77 6f 72 64 73 2c 20 65 61 63 68 20 74  er words, each t
2b70: 69 6d 65 20 77 65 20 61 64 76 61 6e 63 65 20 74  ime we advance t
2b80: 6f 20 74 68 65 20 6e 65 78 74 20 73 6f 72 74 65  o the next sorte
2b90: 72 20 65 6c 65 6d 65 6e 74 2c 20 6c 6f 67 32 28  r element, log2(
2ba0: 4e 29 0a 2a 2a 20 6b 65 79 20 63 6f 6d 70 61 72  N).** key compar
2bb0: 69 73 6f 6e 20 6f 70 65 72 61 74 69 6f 6e 73 20  ison operations 
2bc0: 61 72 65 20 72 65 71 75 69 72 65 64 2c 20 77 68  are required, wh
2bd0: 65 72 65 20 4e 20 69 73 20 74 68 65 20 6e 75 6d  ere N is the num
2be0: 62 65 72 20 6f 66 20 73 65 67 6d 65 6e 74 73 0a  ber of segments.
2bf0: 2a 2a 20 62 65 69 6e 67 20 6d 65 72 67 65 64 20  ** being merged 
2c00: 28 72 6f 75 6e 64 65 64 20 75 70 20 74 6f 20 74  (rounded up to t
2c10: 68 65 20 6e 65 78 74 20 70 6f 77 65 72 20 6f 66  he next power of
2c20: 20 32 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 4d   2)..*/.struct M
2c30: 65 72 67 65 45 6e 67 69 6e 65 20 7b 0a 20 20 69  ergeEngine {.  i
2c40: 6e 74 20 6e 54 72 65 65 3b 20 20 20 20 20 20 20  nt nTree;       
2c50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65            /* Use
2c60: 64 20 73 69 7a 65 20 6f 66 20 61 54 72 65 65 2f  d size of aTree/
2c70: 61 49 74 65 72 20 28 70 6f 77 65 72 20 6f 66 20  aIter (power of 
2c80: 32 29 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 54 72  2) */.  int *aTr
2c90: 65 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ee;             
2ca0: 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 73 74     /* Current st
2cb0: 61 74 65 20 6f 66 20 69 6e 63 72 65 6d 65 6e 74  ate of increment
2cc0: 61 6c 20 6d 65 72 67 65 20 2a 2f 0a 20 20 50 6d  al merge */.  Pm
2cd0: 61 52 65 61 64 65 72 20 2a 61 49 74 65 72 3b 20  aReader *aIter; 
2ce0: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61           /* Arra
2cf0: 79 20 6f 66 20 69 74 65 72 61 74 6f 72 73 20 74  y of iterators t
2d00: 6f 20 6d 65 72 67 65 20 64 61 74 61 20 66 72 6f  o merge data fro
2d10: 6d 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 45  m */.};../*.** E
2d20: 78 61 63 74 6c 79 20 56 64 62 65 53 6f 72 74 65  xactly VdbeSorte
2d30: 72 2e 6e 54 61 73 6b 20 69 6e 73 74 61 6e 63 65  r.nTask instance
2d40: 73 20 6f 66 20 74 68 69 73 20 6f 62 6a 65 63 74  s of this object
2d50: 20 61 72 65 20 61 6c 6c 6f 63 61 74 65 64 0a 2a   are allocated.*
2d60: 2a 20 61 73 20 70 61 72 74 20 6f 66 20 65 61 63  * as part of eac
2d70: 68 20 56 64 62 65 53 6f 72 74 65 72 20 6f 62 6a  h VdbeSorter obj
2d80: 65 63 74 2e 20 49 6e 73 74 61 6e 63 65 73 20 61  ect. Instances a
2d90: 72 65 20 6e 65 76 65 72 20 61 6c 6c 6f 63 61 74  re never allocat
2da0: 65 64 20 61 6e 79 0a 2a 2a 20 6f 74 68 65 72 20  ed any.** other 
2db0: 77 61 79 2e 20 56 64 62 65 53 6f 72 74 65 72 2e  way. VdbeSorter.
2dc0: 6e 54 61 73 6b 20 69 73 20 73 65 74 20 74 6f 20  nTask is set to 
2dd0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 77 6f  the number of wo
2de0: 72 6b 65 72 20 74 68 72 65 61 64 73 20 61 6c 6c  rker threads all
2df0: 6f 77 65 64 0a 2a 2a 20 28 73 65 65 20 53 51 4c  owed.** (see SQL
2e00: 49 54 45 5f 43 4f 4e 46 49 47 5f 57 4f 52 4b 45  ITE_CONFIG_WORKE
2e10: 52 5f 54 48 52 45 41 44 53 29 20 70 6c 75 73 20  R_THREADS) plus 
2e20: 6f 6e 65 20 28 74 68 65 20 6d 61 69 6e 20 74 68  one (the main th
2e30: 72 65 61 64 29 2e 0a 2a 2a 0a 2a 2a 20 45 73 73  read)..**.** Ess
2e40: 65 6e 74 69 61 6c 6c 79 2c 20 74 68 69 73 20 73  entially, this s
2e50: 74 72 75 63 74 75 72 65 20 63 6f 6e 74 61 69 6e  tructure contain
2e60: 73 20 61 6c 6c 20 74 68 6f 73 65 20 66 69 65 6c  s all those fiel
2e70: 64 73 20 6f 66 20 74 68 65 20 56 64 62 65 53 6f  ds of the VdbeSo
2e80: 72 74 65 72 0a 2a 2a 20 73 74 72 75 63 74 75 72  rter.** structur
2e90: 65 20 66 6f 72 20 77 68 69 63 68 20 65 61 63 68  e for which each
2ea0: 20 74 68 72 65 61 64 20 72 65 71 75 69 72 65 73   thread requires
2eb0: 20 61 20 73 65 70 61 72 61 74 65 20 69 6e 73 74   a separate inst
2ec0: 61 6e 63 65 2e 20 46 6f 72 20 65 78 61 6d 70 6c  ance. For exampl
2ed0: 65 2c 0a 2a 2a 20 65 61 63 68 20 74 68 72 65 61  e,.** each threa
2ee0: 64 20 72 65 71 75 72 69 65 73 20 69 74 73 20 6f  d requries its o
2ef0: 77 6e 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72  wn UnpackedRecor
2f00: 64 20 6f 62 6a 65 63 74 20 74 6f 20 75 6e 70 61  d object to unpa
2f10: 63 6b 20 72 65 63 6f 72 64 73 20 69 6e 0a 2a 2a  ck records in.**
2f20: 20 61 73 20 70 61 72 74 20 6f 66 20 63 6f 6d 70   as part of comp
2f30: 61 72 69 73 6f 6e 20 6f 70 65 72 61 74 69 6f 6e  arison operation
2f40: 73 2e 0a 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65 20  s..**.** Before 
2f50: 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  a background thr
2f60: 65 61 64 20 69 73 20 6c 61 75 6e 63 68 65 64 2c  ead is launched,
2f70: 20 76 61 72 69 61 62 6c 65 20 62 44 6f 6e 65 20   variable bDone 
2f80: 69 73 20 73 65 74 20 74 6f 20 30 2e 20 54 68 65  is set to 0. The
2f90: 6e 2c 20 0a 2a 2a 20 72 69 67 68 74 20 62 65 66  n, .** right bef
2fa0: 6f 72 65 20 69 74 20 65 78 69 74 73 2c 20 74 68  ore it exits, th
2fb0: 65 20 74 68 72 65 61 64 20 69 74 73 65 6c 66 20  e thread itself 
2fc0: 73 65 74 73 20 62 44 6f 6e 65 20 74 6f 20 31 2e  sets bDone to 1.
2fd0: 20 54 68 69 73 20 69 73 20 75 73 65 64 20 66 6f   This is used fo
2fe0: 72 20 0a 2a 2a 20 74 77 6f 20 70 75 72 70 6f 73  r .** two purpos
2ff0: 65 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 57  es:.**.**   1. W
3000: 68 65 6e 20 66 6c 75 73 68 69 6e 67 20 74 68 65  hen flushing the
3010: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65 6d   contents of mem
3020: 6f 72 79 20 74 6f 20 61 20 6c 65 76 65 6c 2d 30  ory to a level-0
3030: 20 50 4d 41 20 6f 6e 20 64 69 73 6b 2c 20 74 6f   PMA on disk, to
3040: 0a 2a 2a 20 20 20 20 20 20 61 74 74 65 6d 70 74  .**      attempt
3050: 20 74 6f 20 73 65 6c 65 63 74 20 61 20 53 6f 72   to select a Sor
3060: 74 53 75 62 74 61 73 6b 20 66 6f 72 20 77 68 69  tSubtask for whi
3070: 63 68 20 74 68 65 72 65 20 69 73 20 6e 6f 74 20  ch there is not 
3080: 61 6c 72 65 61 64 79 20 61 6e 0a 2a 2a 20 20 20  already an.**   
3090: 20 20 20 61 63 74 69 76 65 20 62 61 63 6b 67 72     active backgr
30a0: 6f 75 6e 64 20 74 68 72 65 61 64 20 28 73 69 6e  ound thread (sin
30b0: 63 65 20 64 6f 69 6e 67 20 73 6f 20 63 61 75 73  ce doing so caus
30c0: 65 73 20 74 68 65 20 6d 61 69 6e 20 74 68 72 65  es the main thre
30d0: 61 64 0a 2a 2a 20 20 20 20 20 20 74 6f 20 62 6c  ad.**      to bl
30e0: 6f 63 6b 20 75 6e 74 69 6c 20 69 74 20 66 69 6e  ock until it fin
30f0: 69 73 68 65 73 29 2e 0a 2a 2a 0a 2a 2a 20 20 20  ishes)..**.**   
3100: 32 2e 20 49 66 20 53 51 4c 49 54 45 5f 44 45 42  2. If SQLITE_DEB
3110: 55 47 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44  UG_SORTER_THREAD
3120: 53 20 69 73 20 64 65 66 69 6e 65 64 2c 20 74 6f  S is defined, to
3130: 20 64 65 74 65 72 6d 69 6e 65 20 69 66 20 61 20   determine if a 
3140: 63 61 6c 6c 0a 2a 2a 20 20 20 20 20 20 74 6f 20  call.**      to 
3150: 73 71 6c 69 74 65 33 54 68 72 65 61 64 4a 6f 69  sqlite3ThreadJoi
3160: 6e 28 29 20 69 73 20 6c 69 6b 65 6c 79 20 74 6f  n() is likely to
3170: 20 62 6c 6f 63 6b 2e 20 43 61 73 65 73 20 74 68   block. Cases th
3180: 61 74 20 61 72 65 20 6c 69 6b 65 6c 79 20 74 6f  at are likely to
3190: 0a 2a 2a 20 20 20 20 20 20 62 6c 6f 63 6b 20 70  .**      block p
31a0: 72 6f 76 6f 6b 65 20 64 65 62 75 67 67 69 6e 67  rovoke debugging
31b0: 20 6f 75 74 70 75 74 2e 0a 2a 2a 0a 2a 2a 20 49   output..**.** I
31c0: 6e 20 62 6f 74 68 20 63 61 73 65 73 2c 20 74 68  n both cases, th
31d0: 65 20 65 66 66 65 63 74 73 20 6f 66 20 74 68 65  e effects of the
31e0: 20 6d 61 69 6e 20 74 68 72 65 61 64 20 73 65 65   main thread see
31f0: 69 6e 67 20 28 62 44 6f 6e 65 3d 3d 30 29 20 65  ing (bDone==0) e
3200: 76 65 6e 0a 2a 2a 20 61 66 74 65 72 20 74 68 65  ven.** after the
3210: 20 74 68 72 65 61 64 20 68 61 73 20 66 69 6e 69   thread has fini
3220: 73 68 65 64 20 61 72 65 20 6e 6f 74 20 64 69 72  shed are not dir
3230: 65 2e 20 53 6f 20 77 65 20 64 6f 6e 27 74 20 77  e. So we don't w
3240: 6f 72 72 79 20 61 62 6f 75 74 0a 2a 2a 20 6d 65  orry about.** me
3250: 6d 6f 72 79 20 62 61 72 72 69 65 72 73 20 61 6e  mory barriers an
3260: 64 20 73 75 63 68 20 68 65 72 65 2e 0a 2a 2f 0a  d such here..*/.
3270: 73 74 72 75 63 74 20 53 6f 72 74 53 75 62 74 61  struct SortSubta
3280: 73 6b 20 7b 0a 20 20 53 51 4c 69 74 65 54 68 72  sk {.  SQLiteThr
3290: 65 61 64 20 2a 70 54 68 72 65 61 64 3b 20 20 20  ead *pThread;   
32a0: 20 20 20 20 20 20 20 2f 2a 20 42 61 63 6b 67 72         /* Backgr
32b0: 6f 75 6e 64 20 74 68 72 65 61 64 2c 20 69 66 20  ound thread, if 
32c0: 61 6e 79 20 2a 2f 0a 20 20 69 6e 74 20 62 44 6f  any */.  int bDo
32d0: 6e 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ne;             
32e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74 20           /* Set 
32f0: 69 66 20 74 68 72 65 61 64 20 69 73 20 66 69 6e  if thread is fin
3300: 69 73 68 65 64 20 62 75 74 20 6e 6f 74 20 6a 6f  ished but not jo
3310: 69 6e 65 64 20 2a 2f 0a 20 20 56 64 62 65 53 6f  ined */.  VdbeSo
3320: 72 74 65 72 20 2a 70 53 6f 72 74 65 72 3b 20 20  rter *pSorter;  
3330: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72            /* Sor
3340: 74 65 72 20 74 68 61 74 20 6f 77 6e 73 20 74 68  ter that owns th
3350: 69 73 20 73 75 62 2d 74 61 73 6b 20 2a 2f 0a 20  is sub-task */. 
3360: 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20   UnpackedRecord 
3370: 2a 70 55 6e 70 61 63 6b 65 64 3b 20 20 20 20 20  *pUnpacked;     
3380: 20 2f 2a 20 53 70 61 63 65 20 74 6f 20 75 6e 70   /* Space to unp
3390: 61 63 6b 20 61 20 72 65 63 6f 72 64 20 2a 2f 0a  ack a record */.
33a0: 20 20 53 6f 72 74 65 72 4c 69 73 74 20 6c 69 73    SorterList lis
33b0: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
33c0: 20 20 2f 2a 20 4c 69 73 74 20 66 6f 72 20 74 68    /* List for th
33d0: 72 65 61 64 20 74 6f 20 77 72 69 74 65 20 74 6f  read to write to
33e0: 20 61 20 50 4d 41 20 2a 2f 0a 20 20 69 6e 74 20   a PMA */.  int 
33f0: 6e 50 4d 41 3b 20 20 20 20 20 20 20 20 20 20 20  nPMA;           
3400: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
3410: 75 6d 62 65 72 20 6f 66 20 50 4d 41 73 20 63 75  umber of PMAs cu
3420: 72 72 65 6e 74 6c 79 20 69 6e 20 66 69 6c 65 20  rrently in file 
3430: 2a 2f 0a 20 20 53 6f 72 74 65 72 46 69 6c 65 20  */.  SorterFile 
3440: 66 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20  file;           
3450: 20 20 20 20 20 2f 2a 20 54 65 6d 70 20 66 69 6c       /* Temp fil
3460: 65 20 66 6f 72 20 6c 65 76 65 6c 2d 30 20 50 4d  e for level-0 PM
3470: 41 73 20 2a 2f 0a 20 20 53 6f 72 74 65 72 46 69  As */.  SorterFi
3480: 6c 65 20 66 69 6c 65 32 3b 20 20 20 20 20 20 20  le file2;       
3490: 20 20 20 20 20 20 20 20 2f 2a 20 53 70 61 63 65          /* Space
34a0: 20 66 6f 72 20 6f 74 68 65 72 20 50 4d 41 73 20   for other PMAs 
34b0: 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 4d 61 69  */.};../*.** Mai
34c0: 6e 20 73 6f 72 74 65 72 20 73 74 72 75 63 74 75  n sorter structu
34d0: 72 65 2e 20 41 20 73 69 6e 67 6c 65 20 69 6e 73  re. A single ins
34e0: 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 69 73  tance of this is
34f0: 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 65   allocated for e
3500: 61 63 68 20 0a 2a 2a 20 73 6f 72 74 65 72 20 63  ach .** sorter c
3510: 75 72 73 6f 72 20 63 72 65 61 74 65 64 20 62 79  ursor created by
3520: 20 74 68 65 20 56 44 42 45 2e 0a 2a 2a 0a 2a 2a   the VDBE..**.**
3530: 20 6d 78 4b 65 79 73 69 7a 65 3a 0a 2a 2a 20 20   mxKeysize:.**  
3540: 20 41 73 20 72 65 63 6f 72 64 73 20 61 72 65 20   As records are 
3550: 61 64 64 65 64 20 74 6f 20 74 68 65 20 73 6f 72  added to the sor
3560: 74 65 72 20 62 79 20 63 61 6c 6c 73 20 74 6f 20  ter by calls to 
3570: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
3580: 72 57 72 69 74 65 28 29 2c 0a 2a 2a 20 20 20 74  rWrite(),.**   t
3590: 68 69 73 20 76 61 72 69 61 62 6c 65 20 69 73 20  his variable is 
35a0: 75 70 64 61 74 65 64 20 73 6f 20 61 73 20 74 6f  updated so as to
35b0: 20 62 65 20 73 65 74 20 74 6f 20 74 68 65 20 73   be set to the s
35c0: 69 7a 65 20 6f 6e 20 64 69 73 6b 20 6f 66 20 74  ize on disk of t
35d0: 68 65 0a 2a 2a 20 20 20 6c 61 72 67 65 73 74 20  he.**   largest 
35e0: 72 65 63 6f 72 64 20 69 6e 20 74 68 65 20 73 6f  record in the so
35f0: 72 74 65 72 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  rter..*/.struct 
3600: 56 64 62 65 53 6f 72 74 65 72 20 7b 0a 20 20 69  VdbeSorter {.  i
3610: 6e 74 20 6d 6e 50 6d 61 53 69 7a 65 3b 20 20 20  nt mnPmaSize;   
3620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3630: 2a 20 4d 69 6e 69 6d 75 6d 20 50 4d 41 20 73 69  * Minimum PMA si
3640: 7a 65 2c 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  ze, in bytes */.
3650: 20 20 69 6e 74 20 6d 78 50 6d 61 53 69 7a 65 3b    int mxPmaSize;
3660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3670: 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 50 4d 41    /* Maximum PMA
3680: 20 73 69 7a 65 2c 20 69 6e 20 62 79 74 65 73 2e   size, in bytes.
3690: 20 20 30 3d 3d 6e 6f 20 6c 69 6d 69 74 20 2a 2f    0==no limit */
36a0: 0a 20 20 69 6e 74 20 6d 78 4b 65 79 73 69 7a 65  .  int mxKeysize
36b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
36c0: 20 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 73 65     /* Largest se
36d0: 72 69 61 6c 69 7a 65 64 20 6b 65 79 20 73 65 65  rialized key see
36e0: 6e 20 73 6f 20 66 61 72 20 2a 2f 0a 20 20 69 6e  n so far */.  in
36f0: 74 20 70 67 73 7a 3b 20 20 20 20 20 20 20 20 20  t pgsz;         
3700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3710: 20 4d 61 69 6e 20 64 61 74 61 62 61 73 65 20 70   Main database p
3720: 61 67 65 20 73 69 7a 65 20 2a 2f 0a 20 20 50 6d  age size */.  Pm
3730: 61 52 65 61 64 65 72 20 2a 70 52 65 61 64 65 72  aReader *pReader
3740: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
3750: 20 52 65 61 64 20 64 61 74 61 20 66 72 6f 6d 20   Read data from 
3760: 68 65 72 65 20 61 66 74 65 72 20 52 65 77 69 6e  here after Rewin
3770: 64 28 29 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e  d() */.  MergeEn
3780: 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 3b 20 20  gine *pMerger;  
3790: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 72 20 68           /* Or h
37a0: 65 72 65 2c 20 69 66 20 62 55 73 65 54 68 72 65  ere, if bUseThre
37b0: 61 64 73 3d 3d 30 20 2a 2f 0a 20 20 73 71 6c 69  ads==0 */.  sqli
37c0: 74 65 33 20 2a 64 62 3b 20 20 20 20 20 20 20 20  te3 *db;        
37d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
37e0: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
37f0: 6f 6e 20 2a 2f 0a 20 20 4b 65 79 49 6e 66 6f 20  on */.  KeyInfo 
3800: 2a 70 4b 65 79 49 6e 66 6f 3b 20 20 20 20 20 20  *pKeyInfo;      
3810: 20 20 20 20 20 20 20 20 2f 2a 20 48 6f 77 20 74          /* How t
3820: 6f 20 63 6f 6d 70 61 72 65 20 72 65 63 6f 72 64  o compare record
3830: 73 20 2a 2f 0a 20 20 55 6e 70 61 63 6b 65 64 52  s */.  UnpackedR
3840: 65 63 6f 72 64 20 2a 70 55 6e 70 61 63 6b 65 64  ecord *pUnpacked
3850: 3b 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 62  ;      /* Used b
3860: 79 20 56 64 62 65 53 6f 72 74 65 72 43 6f 6d 70  y VdbeSorterComp
3870: 61 72 65 28 29 20 2a 2f 0a 20 20 53 6f 72 74 65  are() */.  Sorte
3880: 72 4c 69 73 74 20 6c 69 73 74 3b 20 20 20 20 20  rList list;     
3890: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69             /* Li
38a0: 73 74 20 6f 66 20 69 6e 2d 6d 65 6d 6f 72 79 20  st of in-memory 
38b0: 72 65 63 6f 72 64 73 20 2a 2f 0a 20 20 69 6e 74  records */.  int
38c0: 20 69 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20 20   iMemory;       
38d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
38e0: 4f 66 66 73 65 74 20 6f 66 20 66 72 65 65 20 73  Offset of free s
38f0: 70 61 63 65 20 69 6e 20 6c 69 73 74 2e 61 4d 65  pace in list.aMe
3900: 6d 6f 72 79 20 2a 2f 0a 20 20 69 6e 74 20 6e 4d  mory */.  int nM
3910: 65 6d 6f 72 79 3b 20 20 20 20 20 20 20 20 20 20  emory;          
3920: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
3930: 65 20 6f 66 20 6c 69 73 74 2e 61 4d 65 6d 6f 72  e of list.aMemor
3940: 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 6e 20  y allocation in 
3950: 62 79 74 65 73 20 2a 2f 0a 20 20 75 38 20 62 55  bytes */.  u8 bU
3960: 73 65 50 4d 41 3b 20 20 20 20 20 20 20 20 20 20  sePMA;          
3970: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
3980: 75 65 20 69 66 20 6f 6e 65 20 6f 72 20 6d 6f 72  ue if one or mor
3990: 65 20 50 4d 41 73 20 63 72 65 61 74 65 64 20 2a  e PMAs created *
39a0: 2f 0a 20 20 75 38 20 62 55 73 65 54 68 72 65 61  /.  u8 bUseThrea
39b0: 64 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ds;             
39c0: 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 75      /* True to u
39d0: 73 65 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68  se background th
39e0: 72 65 61 64 73 20 2a 2f 0a 20 20 75 38 20 69 50  reads */.  u8 iP
39f0: 72 65 76 3b 20 20 20 20 20 20 20 20 20 20 20 20  rev;            
3a00: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 72             /* Pr
3a10: 65 76 69 6f 75 73 20 74 68 72 65 61 64 20 75 73  evious thread us
3a20: 65 64 20 74 6f 20 66 6c 75 73 68 20 50 4d 41 20  ed to flush PMA 
3a30: 2a 2f 0a 20 20 75 38 20 6e 54 61 73 6b 3b 20 20  */.  u8 nTask;  
3a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a50: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
3a60: 61 54 61 73 6b 5b 5d 20 61 72 72 61 79 20 2a 2f  aTask[] array */
3a70: 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 61  .  SortSubtask a
3a80: 54 61 73 6b 5b 31 5d 3b 20 20 20 20 20 20 20 20  Task[1];        
3a90: 20 20 20 2f 2a 20 4f 6e 65 20 6f 72 20 6d 6f 72     /* One or mor
3aa0: 65 20 73 75 62 74 61 73 6b 73 20 2a 2f 0a 7d 3b  e subtasks */.};
3ab0: 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73 74 61  ../*.** An insta
3ac0: 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  nce of the follo
3ad0: 77 69 6e 67 20 6f 62 6a 65 63 74 20 69 73 20 75  wing object is u
3ae0: 73 65 64 20 74 6f 20 72 65 61 64 20 72 65 63 6f  sed to read reco
3af0: 72 64 73 20 6f 75 74 20 6f 66 20 61 0a 2a 2a 20  rds out of a.** 
3b00: 50 4d 41 2c 20 69 6e 20 73 6f 72 74 65 64 20 6f  PMA, in sorted o
3b10: 72 64 65 72 2e 20 20 54 68 65 20 6e 65 78 74 20  rder.  The next 
3b20: 6b 65 79 20 74 6f 20 62 65 20 72 65 61 64 20 69  key to be read i
3b30: 73 20 63 61 63 68 65 64 20 69 6e 20 6e 4b 65 79  s cached in nKey
3b40: 2f 61 4b 65 79 2e 0a 2a 2a 20 70 46 69 6c 65 3d  /aKey..** pFile=
3b50: 3d 30 20 61 74 20 45 4f 46 2e 0a 2a 2f 0a 73 74  =0 at EOF..*/.st
3b60: 72 75 63 74 20 50 6d 61 52 65 61 64 65 72 20 7b  ruct PmaReader {
3b70: 0a 20 20 69 36 34 20 69 52 65 61 64 4f 66 66 3b  .  i64 iReadOff;
3b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3b90: 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 72 65     /* Current re
3ba0: 61 64 20 6f 66 66 73 65 74 20 2a 2f 0a 20 20 69  ad offset */.  i
3bb0: 36 34 20 69 45 6f 66 3b 20 20 20 20 20 20 20 20  64 iEof;        
3bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3bd0: 2a 20 31 20 62 79 74 65 20 70 61 73 74 20 45 4f  * 1 byte past EO
3be0: 46 20 66 6f 72 20 74 68 69 73 20 69 74 65 72 61  F for this itera
3bf0: 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 6c  tor */.  int nAl
3c00: 6c 6f 63 3b 20 20 20 20 20 20 20 20 20 20 20 20  loc;            
3c10: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65           /* Byte
3c20: 73 20 6f 66 20 73 70 61 63 65 20 61 74 20 61 41  s of space at aA
3c30: 6c 6c 6f 63 20 2a 2f 0a 20 20 69 6e 74 20 6e 4b  lloc */.  int nK
3c40: 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ey;             
3c50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
3c60: 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
3c70: 6b 65 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  key */.  sqlite3
3c80: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20  _file *pFile;   
3c90: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65           /* File
3ca0: 20 69 74 65 72 61 74 6f 72 20 69 73 20 72 65 61   iterator is rea
3cb0: 64 69 6e 67 20 66 72 6f 6d 20 2a 2f 0a 20 20 75  ding from */.  u
3cc0: 38 20 2a 61 41 6c 6c 6f 63 3b 20 20 20 20 20 20  8 *aAlloc;      
3cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3ce0: 2a 20 41 6c 6c 6f 63 61 74 65 64 20 73 70 61 63  * Allocated spac
3cf0: 65 20 2a 2f 0a 20 20 75 38 20 2a 61 4b 65 79 3b  e */.  u8 *aKey;
3d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3d10: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
3d20: 72 20 74 6f 20 63 75 72 72 65 6e 74 20 6b 65 79  r to current key
3d30: 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75 66 66 65   */.  u8 *aBuffe
3d40: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
3d50: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
3d60: 20 72 65 61 64 20 62 75 66 66 65 72 20 2a 2f 0a   read buffer */.
3d70: 20 20 69 6e 74 20 6e 42 75 66 66 65 72 3b 20 20    int nBuffer;  
3d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3d90: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 72 65 61    /* Size of rea
3da0: 64 20 62 75 66 66 65 72 20 69 6e 20 62 79 74 65  d buffer in byte
3db0: 73 20 2a 2f 0a 20 20 75 38 20 2a 61 4d 61 70 3b  s */.  u8 *aMap;
3dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3dd0: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
3de0: 72 20 74 6f 20 6d 61 70 70 69 6e 67 20 6f 66 20  r to mapping of 
3df0: 65 6e 74 69 72 65 20 66 69 6c 65 20 2a 2f 0a 20  entire file */. 
3e00: 20 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e   IncrMerger *pIn
3e10: 63 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  cr;             
3e20: 20 2f 2a 20 49 6e 63 72 65 6d 65 6e 74 61 6c 20   /* Incremental 
3e30: 6d 65 72 67 65 72 20 2a 2f 0a 7d 3b 0a 0a 2f 2a  merger */.};../*
3e40: 0a 2a 2a 20 4e 6f 72 6d 61 6c 6c 79 2c 20 61 20  .** Normally, a 
3e50: 50 6d 61 52 65 61 64 65 72 20 6f 62 6a 65 63 74  PmaReader object
3e60: 20 69 74 65 72 61 74 65 73 20 74 68 72 6f 75 67   iterates throug
3e70: 68 20 61 6e 20 65 78 69 73 74 69 6e 67 20 50 4d  h an existing PM
3e80: 41 20 73 74 6f 72 65 64 20 0a 2a 2a 20 77 69 74  A stored .** wit
3e90: 68 69 6e 20 61 20 74 65 6d 70 20 66 69 6c 65 2e  hin a temp file.
3ea0: 20 48 6f 77 65 76 65 72 2c 20 69 66 20 74 68 65   However, if the
3eb0: 20 50 6d 61 52 65 61 64 65 72 2e 70 49 6e 63 72   PmaReader.pIncr
3ec0: 20 76 61 72 69 61 62 6c 65 20 70 6f 69 6e 74 73   variable points
3ed0: 20 74 6f 0a 2a 2a 20 61 6e 20 6f 62 6a 65 63 74   to.** an object
3ee0: 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e   of the followin
3ef0: 67 20 74 79 70 65 2c 20 69 74 20 6d 61 79 20 62  g type, it may b
3f00: 65 20 75 73 65 64 20 74 6f 20 69 74 65 72 61 74  e used to iterat
3f10: 65 2f 6d 65 72 67 65 20 74 68 72 6f 75 67 68 0a  e/merge through.
3f20: 2a 2a 20 6d 75 6c 74 69 70 6c 65 20 50 4d 41 73  ** multiple PMAs
3f30: 20 73 69 6d 75 6c 74 61 6e 65 6f 75 73 6c 79 2e   simultaneously.
3f40: 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 61 72 65  .**.** There are
3f50: 20 74 77 6f 20 74 79 70 65 73 20 6f 66 20 49 6e   two types of In
3f60: 63 72 4d 65 72 67 65 72 20 6f 62 6a 65 63 74 20  crMerger object 
3f70: 2d 20 73 69 6e 67 6c 65 20 28 62 55 73 65 54 68  - single (bUseTh
3f80: 72 65 61 64 3d 3d 30 29 20 61 6e 64 20 0a 2a 2a  read==0) and .**
3f90: 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20   multi-threaded 
3fa0: 28 62 55 73 65 54 68 72 65 61 64 3d 3d 31 29 2e  (bUseThread==1).
3fb0: 20 0a 2a 2a 0a 2a 2a 20 41 20 6d 75 6c 74 69 2d   .**.** A multi-
3fc0: 74 68 72 65 61 64 65 64 20 49 6e 63 72 4d 65 72  threaded IncrMer
3fd0: 67 65 72 20 6f 62 6a 65 63 74 20 75 73 65 73 20  ger object uses 
3fe0: 74 77 6f 20 74 65 6d 70 6f 72 61 72 79 20 66 69  two temporary fi
3ff0: 6c 65 73 20 2d 20 61 46 69 6c 65 5b 30 5d 20 0a  les - aFile[0] .
4000: 2a 2a 20 61 6e 64 20 61 46 69 6c 65 5b 31 5d 2e  ** and aFile[1].
4010: 20 4e 65 69 74 68 65 72 20 66 69 6c 65 20 69 73   Neither file is
4020: 20 61 6c 6c 6f 77 65 64 20 74 6f 20 67 72 6f 77   allowed to grow
4030: 20 74 6f 20 6d 6f 72 65 20 74 68 61 6e 20 6d 78   to more than mx
4040: 53 7a 20 62 79 74 65 73 20 69 6e 20 0a 2a 2a 20  Sz bytes in .** 
4050: 73 69 7a 65 2e 20 57 68 65 6e 20 74 68 65 20 49  size. When the I
4060: 6e 63 72 4d 65 72 67 65 72 20 69 73 20 69 6e 69  ncrMerger is ini
4070: 74 69 61 6c 69 7a 65 64 2c 20 69 74 20 72 65 61  tialized, it rea
4080: 64 73 20 65 6e 6f 75 67 68 20 64 61 74 61 20 66  ds enough data f
4090: 72 6f 6d 20 0a 2a 2a 20 70 4d 65 72 67 65 72 20  rom .** pMerger 
40a0: 74 6f 20 70 6f 70 75 6c 61 74 65 20 61 46 69 6c  to populate aFil
40b0: 65 5b 30 5d 2e 20 49 74 20 74 68 65 6e 20 73 65  e[0]. It then se
40c0: 74 73 20 76 61 72 69 61 62 6c 65 73 20 77 69 74  ts variables wit
40d0: 68 69 6e 20 74 68 65 20 0a 2a 2a 20 63 6f 72 72  hin the .** corr
40e0: 65 73 70 6f 6e 64 69 6e 67 20 50 6d 61 52 65 61  esponding PmaRea
40f0: 64 65 72 20 6f 62 6a 65 63 74 20 74 6f 20 72 65  der object to re
4100: 61 64 20 66 72 6f 6d 20 74 68 61 74 20 66 69 6c  ad from that fil
4110: 65 20 61 6e 64 20 6b 69 63 6b 73 20 6f 66 66 20  e and kicks off 
4120: 0a 2a 2a 20 61 20 62 61 63 6b 67 72 6f 75 6e 64  .** a background
4130: 20 74 68 72 65 61 64 20 74 6f 20 70 6f 70 75 6c   thread to popul
4140: 61 74 65 20 61 46 69 6c 65 5b 31 5d 20 77 69 74  ate aFile[1] wit
4150: 68 20 74 68 65 20 6e 65 78 74 20 6d 78 53 7a 20  h the next mxSz 
4160: 62 79 74 65 73 20 6f 66 20 0a 2a 2a 20 73 6f 72  bytes of .** sor
4170: 74 65 64 20 72 65 63 6f 72 64 20 64 61 74 61 20  ted record data 
4180: 66 72 6f 6d 20 70 4d 65 72 67 65 72 2e 20 0a 2a  from pMerger. .*
4190: 2a 0a 2a 2a 20 57 68 65 6e 20 74 68 65 20 50 6d  *.** When the Pm
41a0: 61 52 65 61 64 65 72 20 72 65 61 63 68 65 73 20  aReader reaches 
41b0: 74 68 65 20 65 6e 64 20 6f 66 20 61 46 69 6c 65  the end of aFile
41c0: 5b 30 5d 2c 20 69 74 20 62 6c 6f 63 6b 73 20 75  [0], it blocks u
41d0: 6e 74 69 6c 20 74 68 65 0a 2a 2a 20 62 61 63 6b  ntil the.** back
41e0: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 68 61  ground thread ha
41f0: 73 20 66 69 6e 69 73 68 65 64 20 70 6f 70 75 6c  s finished popul
4200: 61 74 69 6e 67 20 61 46 69 6c 65 5b 31 5d 2e 20  ating aFile[1]. 
4210: 49 74 20 74 68 65 6e 20 65 78 63 68 61 6e 67 65  It then exchange
4220: 73 0a 2a 2a 20 74 68 65 20 63 6f 6e 74 65 6e 74  s.** the content
4230: 73 20 6f 66 20 74 68 65 20 61 46 69 6c 65 5b 30  s of the aFile[0
4240: 5d 20 61 6e 64 20 61 46 69 6c 65 5b 31 5d 20 76  ] and aFile[1] v
4250: 61 72 69 61 62 6c 65 73 20 77 69 74 68 69 6e 20  ariables within 
4260: 74 68 69 73 20 73 74 72 75 63 74 75 72 65 2c 0a  this structure,.
4270: 2a 2a 20 73 65 74 73 20 74 68 65 20 50 6d 61 52  ** sets the PmaR
4280: 65 61 64 65 72 20 66 69 65 6c 64 73 20 74 6f 20  eader fields to 
4290: 72 65 61 64 20 66 72 6f 6d 20 74 68 65 20 6e 65  read from the ne
42a0: 77 20 61 46 69 6c 65 5b 30 5d 20 61 6e 64 20 6b  w aFile[0] and k
42b0: 69 63 6b 73 20 6f 66 66 0a 2a 2a 20 61 6e 6f 74  icks off.** anot
42c0: 68 65 72 20 62 61 63 6b 67 72 6f 75 6e 64 20 74  her background t
42d0: 68 72 65 61 64 20 74 6f 20 70 6f 70 75 6c 61 74  hread to populat
42e0: 65 20 74 68 65 20 6e 65 77 20 61 46 69 6c 65 5b  e the new aFile[
42f0: 31 5d 2e 20 41 6e 64 20 73 6f 20 6f 6e 2c 20 75  1]. And so on, u
4300: 6e 74 69 6c 0a 2a 2a 20 74 68 65 20 63 6f 6e 74  ntil.** the cont
4310: 65 6e 74 73 20 6f 66 20 70 4d 65 72 67 65 72 20  ents of pMerger 
4320: 61 72 65 20 65 78 68 61 75 73 74 65 64 2e 0a 2a  are exhausted..*
4330: 2a 0a 2a 2a 20 41 20 73 69 6e 67 6c 65 2d 74 68  *.** A single-th
4340: 72 65 61 64 65 64 20 49 6e 63 72 4d 65 72 67 65  readed IncrMerge
4350: 72 20 64 6f 65 73 20 6e 6f 74 20 6f 70 65 6e 20  r does not open 
4360: 61 6e 79 20 74 65 6d 70 6f 72 61 72 79 20 66 69  any temporary fi
4370: 6c 65 73 20 6f 66 20 69 74 73 0a 2a 2a 20 6f 77  les of its.** ow
4380: 6e 2e 20 49 6e 73 74 65 61 64 2c 20 69 74 20 68  n. Instead, it h
4390: 61 73 20 65 78 63 6c 75 73 69 76 65 20 61 63 63  as exclusive acc
43a0: 65 73 73 20 74 6f 20 6d 78 53 7a 20 62 79 74 65  ess to mxSz byte
43b0: 73 20 6f 66 20 73 70 61 63 65 20 62 65 67 69 6e  s of space begin
43c0: 6e 69 6e 67 0a 2a 2a 20 61 74 20 6f 66 66 73 65  ning.** at offse
43d0: 74 20 69 53 74 61 72 74 4f 66 66 20 6f 66 20 66  t iStartOff of f
43e0: 69 6c 65 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32  ile pTask->file2
43f0: 2e 20 41 6e 64 20 69 6e 73 74 65 61 64 20 6f 66  . And instead of
4400: 20 75 73 69 6e 67 20 61 20 0a 2a 2a 20 62 61 63   using a .** bac
4410: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 74  kground thread t
4420: 6f 20 70 72 65 70 61 72 65 20 64 61 74 61 20 66  o prepare data f
4430: 6f 72 20 74 68 65 20 50 6d 61 52 65 61 64 65 72  or the PmaReader
4440: 2c 20 77 69 74 68 20 61 20 73 69 6e 67 6c 65 0a  , with a single.
4450: 2a 2a 20 74 68 72 65 61 64 65 64 20 49 6e 63 72  ** threaded Incr
4460: 4d 65 72 67 65 72 20 74 68 65 20 61 6c 6c 6f 63  Merger the alloc
4470: 61 74 65 20 70 61 72 74 20 6f 66 20 70 54 61 73  ate part of pTas
4480: 6b 2d 3e 66 69 6c 65 32 20 69 73 20 22 72 65 66  k->file2 is "ref
4490: 69 6c 6c 65 64 22 20 77 69 74 68 0a 2a 2a 20 6b  illed" with.** k
44a0: 65 79 73 20 66 72 6f 6d 20 70 4d 65 72 67 65 72  eys from pMerger
44b0: 20 62 79 20 74 68 65 20 63 61 6c 6c 69 6e 67 20   by the calling 
44c0: 74 68 72 65 61 64 20 77 68 65 6e 65 76 65 72 20  thread whenever 
44d0: 74 68 65 20 50 6d 61 52 65 61 64 65 72 20 72 75  the PmaReader ru
44e0: 6e 73 20 6f 75 74 0a 2a 2a 20 6f 66 20 64 61 74  ns out.** of dat
44f0: 61 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 49 6e 63  a..*/.struct Inc
4500: 72 4d 65 72 67 65 72 20 7b 0a 20 20 53 6f 72 74  rMerger {.  Sort
4510: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 3b 20  Subtask *pTask; 
4520: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
4530: 61 73 6b 20 74 68 61 74 20 6f 77 6e 73 20 74 68  ask that owns th
4540: 69 73 20 6d 65 72 67 65 72 20 2a 2f 0a 20 20 4d  is merger */.  M
4550: 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72  ergeEngine *pMer
4560: 67 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 2f  ger;           /
4570: 2a 20 4d 65 72 67 65 20 65 6e 67 69 6e 65 20 74  * Merge engine t
4580: 68 72 65 61 64 20 72 65 61 64 73 20 64 61 74 61  hread reads data
4590: 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 36 34 20 69   from */.  i64 i
45a0: 53 74 61 72 74 4f 66 66 3b 20 20 20 20 20 20 20  StartOff;       
45b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66             /* Of
45c0: 66 73 65 74 20 74 6f 20 73 74 61 72 74 20 77 72  fset to start wr
45d0: 69 74 69 6e 67 20 66 69 6c 65 20 61 74 20 2a 2f  iting file at */
45e0: 0a 20 20 69 6e 74 20 6d 78 53 7a 3b 20 20 20 20  .  int mxSz;    
45f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4600: 20 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 62 79     /* Maximum by
4610: 74 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 73  tes of data to s
4620: 74 6f 72 65 20 2a 2f 0a 20 20 69 6e 74 20 62 45  tore */.  int bE
4630: 6f 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  of;             
4640: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74            /* Set
4650: 20 74 6f 20 74 72 75 65 20 77 68 65 6e 20 6d 65   to true when me
4660: 72 67 65 20 69 73 20 66 69 6e 69 73 68 65 64 20  rge is finished 
4670: 2a 2f 0a 20 20 69 6e 74 20 62 55 73 65 54 68 72  */.  int bUseThr
4680: 65 61 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  ead;            
4690: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20       /* True to 
46a0: 75 73 65 20 61 20 62 67 20 74 68 72 65 61 64 20  use a bg thread 
46b0: 66 6f 72 20 74 68 69 73 20 6f 62 6a 65 63 74 20  for this object 
46c0: 2a 2f 0a 20 20 53 6f 72 74 65 72 46 69 6c 65 20  */.  SorterFile 
46d0: 61 46 69 6c 65 5b 32 5d 3b 20 20 20 20 20 20 20  aFile[2];       
46e0: 20 20 20 20 20 2f 2a 20 61 46 69 6c 65 5b 30 5d       /* aFile[0]
46f0: 20 66 6f 72 20 72 65 61 64 69 6e 67 2c 20 5b 31   for reading, [1
4700: 5d 20 66 6f 72 20 77 72 69 74 69 6e 67 20 2a 2f  ] for writing */
4710: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e  .};../*.** An in
4720: 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 6f  stance of this o
4730: 62 6a 65 63 74 20 69 73 20 75 73 65 64 20 66 6f  bject is used fo
4740: 72 20 77 72 69 74 69 6e 67 20 61 20 50 4d 41 2e  r writing a PMA.
4750: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 4d 41 20 69  .**.** The PMA i
4760: 73 20 77 72 69 74 74 65 6e 20 6f 6e 65 20 72 65  s written one re
4770: 63 6f 72 64 20 61 74 20 61 20 74 69 6d 65 2e 20  cord at a time. 
4780: 20 45 61 63 68 20 72 65 63 6f 72 64 20 69 73 20   Each record is 
4790: 6f 66 20 61 6e 20 61 72 62 69 74 72 61 72 79 0a  of an arbitrary.
47a0: 2a 2a 20 73 69 7a 65 2e 20 20 42 75 74 20 49 2f  ** size.  But I/
47b0: 4f 20 69 73 20 6d 6f 72 65 20 65 66 66 69 63 69  O is more effici
47c0: 65 6e 74 20 69 66 20 69 74 20 6f 63 63 75 72 73  ent if it occurs
47d0: 20 69 6e 20 70 61 67 65 2d 73 69 7a 65 64 20 62   in page-sized b
47e0: 6c 6f 63 6b 73 20 77 68 65 72 65 0a 2a 2a 20 65  locks where.** e
47f0: 61 63 68 20 62 6c 6f 63 6b 20 69 73 20 61 6c 69  ach block is ali
4800: 67 6e 65 64 20 6f 6e 20 61 20 70 61 67 65 20 62  gned on a page b
4810: 6f 75 6e 64 61 72 79 2e 20 20 54 68 69 73 20 6f  oundary.  This o
4820: 62 6a 65 63 74 20 63 61 63 68 65 73 20 77 72 69  bject caches wri
4830: 74 65 73 20 74 6f 0a 2a 2a 20 74 68 65 20 50 4d  tes to.** the PM
4840: 41 20 73 6f 20 74 68 61 74 20 61 6c 69 67 6e 65  A so that aligne
4850: 64 2c 20 70 61 67 65 2d 73 69 7a 65 20 62 6c 6f  d, page-size blo
4860: 63 6b 73 20 61 72 65 20 77 72 69 74 74 65 6e 2e  cks are written.
4870: 0a 2a 2f 0a 73 74 72 75 63 74 20 50 6d 61 57 72  .*/.struct PmaWr
4880: 69 74 65 72 20 7b 0a 20 20 69 6e 74 20 65 46 57  iter {.  int eFW
4890: 45 72 72 3b 20 20 20 20 20 20 20 20 20 20 20 20  Err;            
48a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 6f 6e 2d           /* Non-
48b0: 7a 65 72 6f 20 69 66 20 69 6e 20 61 6e 20 65 72  zero if in an er
48c0: 72 6f 72 20 73 74 61 74 65 20 2a 2f 0a 20 20 75  ror state */.  u
48d0: 38 20 2a 61 42 75 66 66 65 72 3b 20 20 20 20 20  8 *aBuffer;     
48e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
48f0: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 77 72 69  * Pointer to wri
4900: 74 65 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 69  te buffer */.  i
4910: 6e 74 20 6e 42 75 66 66 65 72 3b 20 20 20 20 20  nt nBuffer;     
4920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4930: 2a 20 53 69 7a 65 20 6f 66 20 77 72 69 74 65 20  * Size of write 
4940: 62 75 66 66 65 72 20 69 6e 20 62 79 74 65 73 20  buffer in bytes 
4950: 2a 2f 0a 20 20 69 6e 74 20 69 42 75 66 53 74 61  */.  int iBufSta
4960: 72 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rt;             
4970: 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 62 79       /* First by
4980: 74 65 20 6f 66 20 62 75 66 66 65 72 20 74 6f 20  te of buffer to 
4990: 77 72 69 74 65 20 2a 2f 0a 20 20 69 6e 74 20 69  write */.  int i
49a0: 42 75 66 45 6e 64 3b 20 20 20 20 20 20 20 20 20  BufEnd;         
49b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61             /* La
49c0: 73 74 20 62 79 74 65 20 6f 66 20 62 75 66 66 65  st byte of buffe
49d0: 72 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20  r to write */.  
49e0: 69 36 34 20 69 57 72 69 74 65 4f 66 66 3b 20 20  i64 iWriteOff;  
49f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4a00: 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20 73 74 61  /* Offset of sta
4a10: 72 74 20 6f 66 20 62 75 66 66 65 72 20 69 6e 20  rt of buffer in 
4a20: 66 69 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65  file */.  sqlite
4a30: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20  3_file *pFile;  
4a40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c            /* Fil
4a50: 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f  e to write to */
4a60: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  .};../*.** This 
4a70: 6f 62 6a 65 63 74 20 69 73 20 74 68 65 20 68 65  object is the he
4a80: 61 64 65 72 20 6f 6e 20 61 20 73 69 6e 67 6c 65  ader on a single
4a90: 20 72 65 63 6f 72 64 20 77 68 69 6c 65 20 74 68   record while th
4aa0: 61 74 20 72 65 63 6f 72 64 20 69 73 20 62 65 69  at record is bei
4ab0: 6e 67 0a 2a 2a 20 68 65 6c 64 20 69 6e 20 6d 65  ng.** held in me
4ac0: 6d 6f 72 79 20 61 6e 64 20 70 72 69 6f 72 20 74  mory and prior t
4ad0: 6f 20 62 65 69 6e 67 20 77 72 69 74 74 65 6e 20  o being written 
4ae0: 6f 75 74 20 61 73 20 70 61 72 74 20 6f 66 20 61  out as part of a
4af0: 20 50 4d 41 2e 0a 2a 2a 0a 2a 2a 20 48 6f 77 20   PMA..**.** How 
4b00: 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20  the linked list 
4b10: 69 73 20 63 6f 6e 6e 65 63 74 65 64 20 64 65 70  is connected dep
4b20: 65 6e 64 73 20 6f 6e 20 68 6f 77 20 6d 65 6d 6f  ends on how memo
4b30: 72 79 20 69 73 20 62 65 69 6e 67 20 6d 61 6e 61  ry is being mana
4b40: 67 65 64 0a 2a 2a 20 62 79 20 74 68 69 73 20 6d  ged.** by this m
4b50: 6f 64 75 6c 65 2e 20 49 66 20 75 73 69 6e 67 20  odule. If using 
4b60: 61 20 73 65 70 61 72 61 74 65 20 61 6c 6c 6f 63  a separate alloc
4b70: 61 74 69 6f 6e 20 66 6f 72 20 65 61 63 68 20 69  ation for each i
4b80: 6e 2d 6d 65 6d 6f 72 79 20 72 65 63 6f 72 64 0a  n-memory record.
4b90: 2a 2a 20 28 56 64 62 65 53 6f 72 74 65 72 2e 6c  ** (VdbeSorter.l
4ba0: 69 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30 29 2c  ist.aMemory==0),
4bb0: 20 74 68 65 6e 20 74 68 65 20 6c 69 73 74 20 69   then the list i
4bc0: 73 20 61 6c 77 61 79 73 20 63 6f 6e 6e 65 63 74  s always connect
4bd0: 65 64 20 75 73 69 6e 67 20 74 68 65 0a 2a 2a 20  ed using the.** 
4be0: 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 75 2e 70  SorterRecord.u.p
4bf0: 4e 65 78 74 20 70 6f 69 6e 74 65 72 73 2e 0a 2a  Next pointers..*
4c00: 2a 0a 2a 2a 20 4f 72 2c 20 69 66 20 75 73 69 6e  *.** Or, if usin
4c10: 67 20 74 68 65 20 73 69 6e 67 6c 65 20 6c 61 72  g the single lar
4c20: 67 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6d 65  ge allocation me
4c30: 74 68 6f 64 20 28 56 64 62 65 53 6f 72 74 65 72  thod (VdbeSorter
4c40: 2e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 21 3d 30  .list.aMemory!=0
4c50: 29 2c 0a 2a 2a 20 74 68 65 6e 20 77 68 69 6c 65  ),.** then while
4c60: 20 72 65 63 6f 72 64 73 20 61 72 65 20 62 65 69   records are bei
4c70: 6e 67 20 61 63 63 75 6d 75 6c 61 74 65 64 20 74  ng accumulated t
4c80: 68 65 20 6c 69 73 74 20 69 73 20 6c 69 6e 6b 65  he list is linke
4c90: 64 20 75 73 69 6e 67 20 74 68 65 0a 2a 2a 20 53  d using the.** S
4ca0: 6f 72 74 65 72 52 65 63 6f 72 64 2e 75 2e 69 4e  orterRecord.u.iN
4cb0: 65 78 74 20 6f 66 66 73 65 74 2e 20 54 68 69 73  ext offset. This
4cc0: 20 69 73 20 62 65 63 61 75 73 65 20 74 68 65 20   is because the 
4cd0: 61 4d 65 6d 6f 72 79 5b 5d 20 61 72 72 61 79 20  aMemory[] array 
4ce0: 6d 61 79 0a 2a 2a 20 62 65 20 73 71 6c 69 74 65  may.** be sqlite
4cf0: 33 52 65 61 6c 6c 6f 63 28 29 65 64 20 77 68 69  3Realloc()ed whi
4d00: 6c 65 20 72 65 63 6f 72 64 73 20 61 72 65 20 62  le records are b
4d10: 65 69 6e 67 20 61 63 63 75 6d 75 6c 61 74 65 64  eing accumulated
4d20: 2e 20 4f 6e 63 65 20 74 68 65 20 56 4d 0a 2a 2a  . Once the VM.**
4d30: 20 68 61 73 20 66 69 6e 69 73 68 65 64 20 70 61   has finished pa
4d40: 73 73 69 6e 67 20 72 65 63 6f 72 64 73 20 74 6f  ssing records to
4d50: 20 74 68 65 20 73 6f 72 74 65 72 2c 20 6f 72 20   the sorter, or 
4d60: 77 68 65 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f  when the in-memo
4d70: 72 79 20 62 75 66 66 65 72 0a 2a 2a 20 69 73 20  ry buffer.** is 
4d80: 66 75 6c 6c 2c 20 74 68 65 20 6c 69 73 74 20 69  full, the list i
4d90: 73 20 73 6f 72 74 65 64 2e 20 41 73 20 70 61 72  s sorted. As par
4da0: 74 20 6f 66 20 74 68 65 20 73 6f 72 74 69 6e 67  t of the sorting
4db0: 20 70 72 6f 63 65 73 73 2c 20 69 74 20 69 73 0a   process, it is.
4dc0: 2a 2a 20 63 6f 6e 76 65 72 74 65 64 20 74 6f 20  ** converted to 
4dd0: 75 73 65 20 74 68 65 20 53 6f 72 74 65 72 52 65  use the SorterRe
4de0: 63 6f 72 64 2e 75 2e 70 4e 65 78 74 20 70 6f 69  cord.u.pNext poi
4df0: 6e 74 65 72 73 2e 20 53 65 65 20 66 75 6e 63 74  nters. See funct
4e00: 69 6f 6e 0a 2a 2a 20 76 64 62 65 53 6f 72 74 65  ion.** vdbeSorte
4e10: 72 53 6f 72 74 28 29 20 66 6f 72 20 64 65 74 61  rSort() for deta
4e20: 69 6c 73 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 53  ils..*/.struct S
4e30: 6f 72 74 65 72 52 65 63 6f 72 64 20 7b 0a 20 20  orterRecord {.  
4e40: 69 6e 74 20 6e 56 61 6c 3b 20 20 20 20 20 20 20  int nVal;       
4e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4e60: 2f 2a 20 53 69 7a 65 20 6f 66 20 74 68 65 20 72  /* Size of the r
4e70: 65 63 6f 72 64 20 69 6e 20 62 79 74 65 73 20 2a  ecord in bytes *
4e80: 2f 0a 20 20 75 6e 69 6f 6e 20 7b 0a 20 20 20 20  /.  union {.    
4e90: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e  SorterRecord *pN
4ea0: 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 2f 2a  ext;          /*
4eb0: 20 50 6f 69 6e 74 65 72 20 74 6f 20 6e 65 78 74   Pointer to next
4ec0: 20 72 65 63 6f 72 64 20 69 6e 20 6c 69 73 74 20   record in list 
4ed0: 2a 2f 0a 20 20 20 20 69 6e 74 20 69 4e 65 78 74  */.    int iNext
4ee0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4ef0: 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 77       /* Offset w
4f00: 69 74 68 69 6e 20 61 4d 65 6d 6f 72 79 20 6f 66  ithin aMemory of
4f10: 20 6e 65 78 74 20 72 65 63 6f 72 64 20 2a 2f 0a   next record */.
4f20: 20 20 7d 20 75 3b 0a 20 20 2f 2a 20 54 68 65 20    } u;.  /* The 
4f30: 64 61 74 61 20 66 6f 72 20 74 68 65 20 72 65 63  data for the rec
4f40: 6f 72 64 20 69 6d 6d 65 64 69 61 74 65 6c 79 20  ord immediately 
4f50: 66 6f 6c 6c 6f 77 73 20 74 68 69 73 20 68 65 61  follows this hea
4f60: 64 65 72 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 52 65  der */.};../* Re
4f70: 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74  turn a pointer t
4f80: 6f 20 74 68 65 20 62 75 66 66 65 72 20 63 6f 6e  o the buffer con
4f90: 74 61 69 6e 69 6e 67 20 74 68 65 20 72 65 63 6f  taining the reco
4fa0: 72 64 20 64 61 74 61 20 66 6f 72 20 53 6f 72 74  rd data for Sort
4fb0: 65 72 52 65 63 6f 72 64 0a 2a 2a 20 6f 62 6a 65  erRecord.** obje
4fc0: 63 74 20 70 2e 20 53 68 6f 75 6c 64 20 62 65 20  ct p. Should be 
4fd0: 75 73 65 64 20 61 73 20 69 66 3a 0a 2a 2a 0a 2a  used as if:.**.*
4fe0: 2a 20 20 20 76 6f 69 64 20 2a 53 52 56 41 4c 28  *   void *SRVAL(
4ff0: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 29  SorterRecord *p)
5000: 20 7b 20 72 65 74 75 72 6e 20 28 76 6f 69 64 2a   { return (void*
5010: 29 26 70 5b 31 5d 3b 20 7d 0a 2a 2f 0a 23 64 65  )&p[1]; }.*/.#de
5020: 66 69 6e 65 20 53 52 56 41 4c 28 70 29 20 28 28  fine SRVAL(p) ((
5030: 76 6f 69 64 2a 29 28 28 53 6f 72 74 65 72 52 65  void*)((SorterRe
5040: 63 6f 72 64 2a 29 28 70 29 20 2b 20 31 29 29 0a  cord*)(p) + 1)).
5050: 0a 2f 2a 20 54 68 65 20 6d 69 6e 69 6d 75 6d 20  ./* The minimum 
5060: 50 4d 41 20 73 69 7a 65 20 69 73 20 73 65 74 20  PMA size is set 
5070: 74 6f 20 74 68 69 73 20 76 61 6c 75 65 20 6d 75  to this value mu
5080: 6c 74 69 70 6c 69 65 64 20 62 79 20 74 68 65 20  ltiplied by the 
5090: 64 61 74 61 62 61 73 65 0a 2a 2a 20 70 61 67 65  database.** page
50a0: 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73 2e 20   size in bytes. 
50b0: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53 4f 52 54   */.#define SORT
50c0: 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20 31  ER_MIN_WORKING 1
50d0: 30 0a 0a 2f 2a 20 4d 61 78 69 6d 75 6d 20 6e 75  0../* Maximum nu
50e0: 6d 62 65 72 20 6f 66 20 50 4d 41 73 20 74 68 61  mber of PMAs tha
50f0: 74 20 61 20 73 69 6e 67 6c 65 20 4d 65 72 67 65  t a single Merge
5100: 45 6e 67 69 6e 65 20 63 61 6e 20 6d 65 72 67 65  Engine can merge
5110: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53 4f 52 54   */.#define SORT
5120: 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55  ER_MAX_MERGE_COU
5130: 4e 54 20 31 36 0a 0a 73 74 61 74 69 63 20 69 6e  NT 16..static in
5140: 74 20 76 64 62 65 49 6e 63 72 53 77 61 70 28 49  t vdbeIncrSwap(I
5150: 6e 63 72 4d 65 72 67 65 72 2a 29 3b 0a 73 74 61  ncrMerger*);.sta
5160: 74 69 63 20 76 6f 69 64 20 76 64 62 65 49 6e 63  tic void vdbeInc
5170: 72 46 72 65 65 28 49 6e 63 72 4d 65 72 67 65 72  rFree(IncrMerger
5180: 20 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65   *);../*.** Free
5190: 20 61 6c 6c 20 6d 65 6d 6f 72 79 20 62 65 6c 6f   all memory belo
51a0: 6e 67 69 6e 67 20 74 6f 20 74 68 65 20 50 6d 61  nging to the Pma
51b0: 52 65 61 64 65 72 20 6f 62 6a 65 63 74 20 70 61  Reader object pa
51c0: 73 73 65 64 20 61 73 20 74 68 65 20 73 65 63 6f  ssed as the seco
51d0: 6e 64 0a 2a 2a 20 61 72 67 75 6d 65 6e 74 2e 20  nd.** argument. 
51e0: 41 6c 6c 20 73 74 72 75 63 74 75 72 65 20 66 69  All structure fi
51f0: 65 6c 64 73 20 61 72 65 20 73 65 74 20 74 6f 20  elds are set to 
5200: 7a 65 72 6f 20 62 65 66 6f 72 65 20 72 65 74 75  zero before retu
5210: 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63  rning..*/.static
5220: 20 76 6f 69 64 20 76 64 62 65 50 6d 61 52 65 61   void vdbePmaRea
5230: 64 65 72 43 6c 65 61 72 28 50 6d 61 52 65 61 64  derClear(PmaRead
5240: 65 72 20 2a 70 49 74 65 72 29 7b 0a 20 20 73 71  er *pIter){.  sq
5250: 6c 69 74 65 33 5f 66 72 65 65 28 70 49 74 65 72  lite3_free(pIter
5260: 2d 3e 61 41 6c 6c 6f 63 29 3b 0a 20 20 73 71 6c  ->aAlloc);.  sql
5270: 69 74 65 33 5f 66 72 65 65 28 70 49 74 65 72 2d  ite3_free(pIter-
5280: 3e 61 42 75 66 66 65 72 29 3b 0a 20 20 69 66 28  >aBuffer);.  if(
5290: 20 70 49 74 65 72 2d 3e 61 4d 61 70 20 29 20 73   pIter->aMap ) s
52a0: 71 6c 69 74 65 33 4f 73 55 6e 66 65 74 63 68 28  qlite3OsUnfetch(
52b0: 70 49 74 65 72 2d 3e 70 46 69 6c 65 2c 20 30 2c  pIter->pFile, 0,
52c0: 20 70 49 74 65 72 2d 3e 61 4d 61 70 29 3b 0a 20   pIter->aMap);. 
52d0: 20 69 66 28 20 70 49 74 65 72 2d 3e 70 49 6e 63   if( pIter->pInc
52e0: 72 20 29 20 76 64 62 65 49 6e 63 72 46 72 65 65  r ) vdbeIncrFree
52f0: 28 70 49 74 65 72 2d 3e 70 49 6e 63 72 29 3b 0a  (pIter->pIncr);.
5300: 20 20 6d 65 6d 73 65 74 28 70 49 74 65 72 2c 20    memset(pIter, 
5310: 30 2c 20 73 69 7a 65 6f 66 28 50 6d 61 52 65 61  0, sizeof(PmaRea
5320: 64 65 72 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  der));.}../*.** 
5330: 52 65 61 64 20 6e 42 79 74 65 20 62 79 74 65 73  Read nByte bytes
5340: 20 6f 66 20 64 61 74 61 20 66 72 6f 6d 20 74 68   of data from th
5350: 65 20 73 74 72 65 61 6d 20 6f 66 20 64 61 74 61  e stream of data
5360: 20 69 74 65 72 61 74 65 64 20 62 79 20 6f 62 6a   iterated by obj
5370: 65 63 74 20 70 2e 0a 2a 2a 20 49 66 20 73 75 63  ect p..** If suc
5380: 63 65 73 73 66 75 6c 2c 20 73 65 74 20 2a 70 70  cessful, set *pp
5390: 4f 75 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  Out to point to 
53a0: 61 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69 6e  a buffer contain
53b0: 69 6e 67 20 74 68 65 20 64 61 74 61 0a 2a 2a 20  ing the data.** 
53c0: 61 6e 64 20 72 65 74 75 72 6e 20 53 51 4c 49 54  and return SQLIT
53d0: 45 5f 4f 4b 2e 20 4f 74 68 65 72 77 69 73 65 2c  E_OK. Otherwise,
53e0: 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   if an error occ
53f0: 75 72 73 2c 20 72 65 74 75 72 6e 20 61 6e 20 53  urs, return an S
5400: 51 4c 69 74 65 0a 2a 2a 20 65 72 72 6f 72 20 63  QLite.** error c
5410: 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 62  ode..**.** The b
5420: 75 66 66 65 72 20 69 6e 64 69 63 61 74 65 64 20  uffer indicated 
5430: 62 79 20 2a 70 70 4f 75 74 20 6d 61 79 20 6f 6e  by *ppOut may on
5440: 6c 79 20 62 65 20 63 6f 6e 73 69 64 65 72 65 64  ly be considered
5450: 20 76 61 6c 69 64 20 75 6e 74 69 6c 20 74 68 65   valid until the
5460: 0a 2a 2a 20 6e 65 78 74 20 63 61 6c 6c 20 74 6f  .** next call to
5470: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 2e 0a   this function..
5480: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
5490: 62 65 50 6d 61 52 65 61 64 42 6c 6f 62 28 0a 20  bePmaReadBlob(. 
54a0: 20 50 6d 61 52 65 61 64 65 72 20 2a 70 2c 20 20   PmaReader *p,  
54b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
54c0: 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 2a 2f 0a   /* Iterator */.
54d0: 20 20 69 6e 74 20 6e 42 79 74 65 2c 20 20 20 20    int nByte,    
54e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
54f0: 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 64 61    /* Bytes of da
5500: 74 61 20 74 6f 20 72 65 61 64 20 2a 2f 0a 20 20  ta to read */.  
5510: 75 38 20 2a 2a 70 70 4f 75 74 20 20 20 20 20 20  u8 **ppOut      
5520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5530: 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20  /* OUT: Pointer 
5540: 74 6f 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69  to buffer contai
5550: 6e 69 6e 67 20 64 61 74 61 20 2a 2f 0a 29 7b 0a  ning data */.){.
5560: 20 20 69 6e 74 20 69 42 75 66 3b 20 20 20 20 20    int iBuf;     
5570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5580: 20 20 2f 2a 20 4f 66 66 73 65 74 20 77 69 74 68    /* Offset with
5590: 69 6e 20 62 75 66 66 65 72 20 74 6f 20 72 65 61  in buffer to rea
55a0: 64 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 6e 74 20  d from */.  int 
55b0: 6e 41 76 61 69 6c 3b 20 20 20 20 20 20 20 20 20  nAvail;         
55c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
55d0: 79 74 65 73 20 6f 66 20 64 61 74 61 20 61 76 61  ytes of data ava
55e0: 69 6c 61 62 6c 65 20 69 6e 20 62 75 66 66 65 72  ilable in buffer
55f0: 20 2a 2f 0a 0a 20 20 69 66 28 20 70 2d 3e 61 4d   */..  if( p->aM
5600: 61 70 20 29 7b 0a 20 20 20 20 2a 70 70 4f 75 74  ap ){.    *ppOut
5610: 20 3d 20 26 70 2d 3e 61 4d 61 70 5b 70 2d 3e 69   = &p->aMap[p->i
5620: 52 65 61 64 4f 66 66 5d 3b 0a 20 20 20 20 70 2d  ReadOff];.    p-
5630: 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e 42 79  >iReadOff += nBy
5640: 74 65 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53  te;.    return S
5650: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20  QLITE_OK;.  }.. 
5660: 20 61 73 73 65 72 74 28 20 70 2d 3e 61 42 75 66   assert( p->aBuf
5670: 66 65 72 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20  fer );..  /* If 
5680: 74 68 65 72 65 20 69 73 20 6e 6f 20 6d 6f 72 65  there is no more
5690: 20 64 61 74 61 20 74 6f 20 62 65 20 72 65 61 64   data to be read
56a0: 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66 65 72   from the buffer
56b0: 2c 20 72 65 61 64 20 74 68 65 20 6e 65 78 74 20  , read the next 
56c0: 0a 20 20 2a 2a 20 70 2d 3e 6e 42 75 66 66 65 72  .  ** p->nBuffer
56d0: 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 66   bytes of data f
56e0: 72 6f 6d 20 74 68 65 20 66 69 6c 65 20 69 6e 74  rom the file int
56f0: 6f 20 69 74 2e 20 4f 72 2c 20 69 66 20 74 68 65  o it. Or, if the
5700: 72 65 20 61 72 65 20 6c 65 73 73 0a 20 20 2a 2a  re are less.  **
5710: 20 74 68 61 6e 20 70 2d 3e 6e 42 75 66 66 65 72   than p->nBuffer
5720: 20 62 79 74 65 73 20 72 65 6d 61 69 6e 69 6e 67   bytes remaining
5730: 20 69 6e 20 74 68 65 20 50 4d 41 2c 20 72 65 61   in the PMA, rea
5740: 64 20 61 6c 6c 20 72 65 6d 61 69 6e 69 6e 67 20  d all remaining 
5750: 64 61 74 61 2e 20 20 2a 2f 0a 20 20 69 42 75 66  data.  */.  iBuf
5760: 20 3d 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 25   = p->iReadOff %
5770: 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 69   p->nBuffer;.  i
5780: 66 28 20 69 42 75 66 3d 3d 30 20 29 7b 0a 20 20  f( iBuf==0 ){.  
5790: 20 20 69 6e 74 20 6e 52 65 61 64 3b 20 20 20 20    int nRead;    
57a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
57b0: 2f 2a 20 42 79 74 65 73 20 74 6f 20 72 65 61 64  /* Bytes to read
57c0: 20 66 72 6f 6d 20 64 69 73 6b 20 2a 2f 0a 20 20   from disk */.  
57d0: 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
57e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
57f0: 2f 2a 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64  /* sqlite3OsRead
5800: 28 29 20 72 65 74 75 72 6e 20 63 6f 64 65 20 2a  () return code *
5810: 2f 0a 0a 20 20 20 20 2f 2a 20 44 65 74 65 72 6d  /..    /* Determ
5820: 69 6e 65 20 68 6f 77 20 6d 61 6e 79 20 62 79 74  ine how many byt
5830: 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 72 65  es of data to re
5840: 61 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 28  ad. */.    if( (
5850: 70 2d 3e 69 45 6f 66 20 2d 20 70 2d 3e 69 52 65  p->iEof - p->iRe
5860: 61 64 4f 66 66 29 20 3e 20 28 69 36 34 29 70 2d  adOff) > (i64)p-
5870: 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20  >nBuffer ){.    
5880: 20 20 6e 52 65 61 64 20 3d 20 70 2d 3e 6e 42 75    nRead = p->nBu
5890: 66 66 65 72 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  ffer;.    }else{
58a0: 0a 20 20 20 20 20 20 6e 52 65 61 64 20 3d 20 28  .      nRead = (
58b0: 69 6e 74 29 28 70 2d 3e 69 45 6f 66 20 2d 20 70  int)(p->iEof - p
58c0: 2d 3e 69 52 65 61 64 4f 66 66 29 3b 0a 20 20 20  ->iReadOff);.   
58d0: 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 6e   }.    assert( n
58e0: 52 65 61 64 3e 30 20 29 3b 0a 0a 20 20 20 20 2f  Read>0 );..    /
58f0: 2a 20 52 65 61 64 20 64 61 74 61 20 66 72 6f 6d  * Read data from
5900: 20 74 68 65 20 66 69 6c 65 2e 20 52 65 74 75 72   the file. Retur
5910: 6e 20 65 61 72 6c 79 20 69 66 20 61 6e 20 65 72  n early if an er
5920: 72 6f 72 20 6f 63 63 75 72 73 2e 20 2a 2f 0a 20  ror occurs. */. 
5930: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
5940: 73 52 65 61 64 28 70 2d 3e 70 46 69 6c 65 2c 20  sRead(p->pFile, 
5950: 70 2d 3e 61 42 75 66 66 65 72 2c 20 6e 52 65 61  p->aBuffer, nRea
5960: 64 2c 20 70 2d 3e 69 52 65 61 64 4f 66 66 29 3b  d, p->iReadOff);
5970: 0a 20 20 20 20 61 73 73 65 72 74 28 20 72 63 21  .    assert( rc!
5980: 3d 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f 53 48  =SQLITE_IOERR_SH
5990: 4f 52 54 5f 52 45 41 44 20 29 3b 0a 20 20 20 20  ORT_READ );.    
59a0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
59b0: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  K ) return rc;. 
59c0: 20 7d 0a 20 20 6e 41 76 61 69 6c 20 3d 20 70 2d   }.  nAvail = p-
59d0: 3e 6e 42 75 66 66 65 72 20 2d 20 69 42 75 66 3b  >nBuffer - iBuf;
59e0: 20 0a 0a 20 20 69 66 28 20 6e 42 79 74 65 3c 3d   ..  if( nByte<=
59f0: 6e 41 76 61 69 6c 20 29 7b 0a 20 20 20 20 2f 2a  nAvail ){.    /*
5a00: 20 54 68 65 20 72 65 71 75 65 73 74 65 64 20 64   The requested d
5a10: 61 74 61 20 69 73 20 61 76 61 69 6c 61 62 6c 65  ata is available
5a20: 20 69 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72   in the in-memor
5a30: 79 20 62 75 66 66 65 72 2e 20 49 6e 20 74 68 69  y buffer. In thi
5a40: 73 0a 20 20 20 20 2a 2a 20 63 61 73 65 20 74 68  s.    ** case th
5a50: 65 72 65 20 69 73 20 6e 6f 20 6e 65 65 64 20 74  ere is no need t
5a60: 6f 20 6d 61 6b 65 20 61 20 63 6f 70 79 20 6f 66  o make a copy of
5a70: 20 74 68 65 20 64 61 74 61 2c 20 6a 75 73 74 20   the data, just 
5a80: 72 65 74 75 72 6e 20 61 20 0a 20 20 20 20 2a 2a  return a .    **
5a90: 20 70 6f 69 6e 74 65 72 20 69 6e 74 6f 20 74 68   pointer into th
5aa0: 65 20 62 75 66 66 65 72 20 74 6f 20 74 68 65 20  e buffer to the 
5ab0: 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a 20 20 20 20  caller.  */.    
5ac0: 2a 70 70 4f 75 74 20 3d 20 26 70 2d 3e 61 42 75  *ppOut = &p->aBu
5ad0: 66 66 65 72 5b 69 42 75 66 5d 3b 0a 20 20 20 20  ffer[iBuf];.    
5ae0: 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e  p->iReadOff += n
5af0: 42 79 74 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  Byte;.  }else{. 
5b00: 20 20 20 2f 2a 20 54 68 65 20 72 65 71 75 65 73     /* The reques
5b10: 74 65 64 20 64 61 74 61 20 69 73 20 6e 6f 74 20  ted data is not 
5b20: 61 6c 6c 20 61 76 61 69 6c 61 62 6c 65 20 69 6e  all available in
5b30: 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 62   the in-memory b
5b40: 75 66 66 65 72 2e 0a 20 20 20 20 2a 2a 20 49 6e  uffer..    ** In
5b50: 20 74 68 69 73 20 63 61 73 65 2c 20 61 6c 6c 6f   this case, allo
5b60: 63 61 74 65 20 73 70 61 63 65 20 61 74 20 70 2d  cate space at p-
5b70: 3e 61 41 6c 6c 6f 63 5b 5d 20 74 6f 20 63 6f 70  >aAlloc[] to cop
5b80: 79 20 74 68 65 20 72 65 71 75 65 73 74 65 64 0a  y the requested.
5b90: 20 20 20 20 2a 2a 20 72 61 6e 67 65 20 69 6e 74      ** range int
5ba0: 6f 2e 20 54 68 65 6e 20 72 65 74 75 72 6e 20 61  o. Then return a
5bb0: 20 63 6f 70 79 20 6f 66 20 70 6f 69 6e 74 65 72   copy of pointer
5bc0: 20 70 2d 3e 61 41 6c 6c 6f 63 20 74 6f 20 74 68   p->aAlloc to th
5bd0: 65 20 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a 20 20  e caller.  */.  
5be0: 20 20 69 6e 74 20 6e 52 65 6d 3b 20 20 20 20 20    int nRem;     
5bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5c00: 2f 2a 20 42 79 74 65 73 20 72 65 6d 61 69 6e 69  /* Bytes remaini
5c10: 6e 67 20 74 6f 20 63 6f 70 79 20 2a 2f 0a 0a 20  ng to copy */.. 
5c20: 20 20 20 2f 2a 20 45 78 74 65 6e 64 20 74 68 65     /* Extend the
5c30: 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 61 6c 6c   p->aAlloc[] all
5c40: 6f 63 61 74 69 6f 6e 20 69 66 20 72 65 71 75 69  ocation if requi
5c50: 72 65 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20  red. */.    if( 
5c60: 70 2d 3e 6e 41 6c 6c 6f 63 3c 6e 42 79 74 65 20  p->nAlloc<nByte 
5c70: 29 7b 0a 20 20 20 20 20 20 75 38 20 2a 61 4e 65  ){.      u8 *aNe
5c80: 77 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e 65  w;.      int nNe
5c90: 77 20 3d 20 4d 41 58 28 31 32 38 2c 20 70 2d 3e  w = MAX(128, p->
5ca0: 6e 41 6c 6c 6f 63 2a 32 29 3b 0a 20 20 20 20 20  nAlloc*2);.     
5cb0: 20 77 68 69 6c 65 28 20 6e 42 79 74 65 3e 6e 4e   while( nByte>nN
5cc0: 65 77 20 29 20 6e 4e 65 77 20 3d 20 6e 4e 65 77  ew ) nNew = nNew
5cd0: 2a 32 3b 0a 20 20 20 20 20 20 61 4e 65 77 20 3d  *2;.      aNew =
5ce0: 20 73 71 6c 69 74 65 33 52 65 61 6c 6c 6f 63 28   sqlite3Realloc(
5cf0: 70 2d 3e 61 41 6c 6c 6f 63 2c 20 6e 4e 65 77 29  p->aAlloc, nNew)
5d00: 3b 0a 20 20 20 20 20 20 69 66 28 20 21 61 4e 65  ;.      if( !aNe
5d10: 77 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  w ) return SQLIT
5d20: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 70  E_NOMEM;.      p
5d30: 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 6e 4e 65 77 3b  ->nAlloc = nNew;
5d40: 0a 20 20 20 20 20 20 70 2d 3e 61 41 6c 6c 6f 63  .      p->aAlloc
5d50: 20 3d 20 61 4e 65 77 3b 0a 20 20 20 20 7d 0a 0a   = aNew;.    }..
5d60: 20 20 20 20 2f 2a 20 43 6f 70 79 20 61 73 20 6d      /* Copy as m
5d70: 75 63 68 20 64 61 74 61 20 61 73 20 69 73 20 61  uch data as is a
5d80: 76 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65 20  vailable in the 
5d90: 62 75 66 66 65 72 20 69 6e 74 6f 20 74 68 65 20  buffer into the 
5da0: 73 74 61 72 74 20 6f 66 0a 20 20 20 20 2a 2a 20  start of.    ** 
5db0: 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 2e 20 20 2a 2f  p->aAlloc[].  */
5dc0: 0a 20 20 20 20 6d 65 6d 63 70 79 28 70 2d 3e 61  .    memcpy(p->a
5dd0: 41 6c 6c 6f 63 2c 20 26 70 2d 3e 61 42 75 66 66  Alloc, &p->aBuff
5de0: 65 72 5b 69 42 75 66 5d 2c 20 6e 41 76 61 69 6c  er[iBuf], nAvail
5df0: 29 3b 0a 20 20 20 20 70 2d 3e 69 52 65 61 64 4f  );.    p->iReadO
5e00: 66 66 20 2b 3d 20 6e 41 76 61 69 6c 3b 0a 20 20  ff += nAvail;.  
5e10: 20 20 6e 52 65 6d 20 3d 20 6e 42 79 74 65 20 2d    nRem = nByte -
5e20: 20 6e 41 76 61 69 6c 3b 0a 0a 20 20 20 20 2f 2a   nAvail;..    /*
5e30: 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6c   The following l
5e40: 6f 6f 70 20 63 6f 70 69 65 73 20 75 70 20 74 6f  oop copies up to
5e50: 20 70 2d 3e 6e 42 75 66 66 65 72 20 62 79 74 65   p->nBuffer byte
5e60: 73 20 70 65 72 20 69 74 65 72 61 74 69 6f 6e 20  s per iteration 
5e70: 69 6e 74 6f 0a 20 20 20 20 2a 2a 20 74 68 65 20  into.    ** the 
5e80: 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 62 75 66 66  p->aAlloc[] buff
5e90: 65 72 2e 20 20 2a 2f 0a 20 20 20 20 77 68 69 6c  er.  */.    whil
5ea0: 65 28 20 6e 52 65 6d 3e 30 20 29 7b 0a 20 20 20  e( nRem>0 ){.   
5eb0: 20 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20     int rc;      
5ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5ed0: 2a 20 76 64 62 65 50 6d 61 52 65 61 64 42 6c 6f  * vdbePmaReadBlo
5ee0: 62 28 29 20 72 65 74 75 72 6e 20 63 6f 64 65 20  b() return code 
5ef0: 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e 43 6f  */.      int nCo
5f00: 70 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  py;             
5f10: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
5f20: 66 20 62 79 74 65 73 20 74 6f 20 63 6f 70 79 20  f bytes to copy 
5f30: 2a 2f 0a 20 20 20 20 20 20 75 38 20 2a 61 4e 65  */.      u8 *aNe
5f40: 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  xt;             
5f50: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
5f60: 74 6f 20 62 75 66 66 65 72 20 74 6f 20 63 6f 70  to buffer to cop
5f70: 79 20 64 61 74 61 20 66 72 6f 6d 20 2a 2f 0a 0a  y data from */..
5f80: 20 20 20 20 20 20 6e 43 6f 70 79 20 3d 20 6e 52        nCopy = nR
5f90: 65 6d 3b 0a 20 20 20 20 20 20 69 66 28 20 6e 52  em;.      if( nR
5fa0: 65 6d 3e 70 2d 3e 6e 42 75 66 66 65 72 20 29 20  em>p->nBuffer ) 
5fb0: 6e 43 6f 70 79 20 3d 20 70 2d 3e 6e 42 75 66 66  nCopy = p->nBuff
5fc0: 65 72 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 76  er;.      rc = v
5fd0: 64 62 65 50 6d 61 52 65 61 64 42 6c 6f 62 28 70  dbePmaReadBlob(p
5fe0: 2c 20 6e 43 6f 70 79 2c 20 26 61 4e 65 78 74 29  , nCopy, &aNext)
5ff0: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  ;.      if( rc!=
6000: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
6010: 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 61 73 73  rn rc;.      ass
6020: 65 72 74 28 20 61 4e 65 78 74 21 3d 70 2d 3e 61  ert( aNext!=p->a
6030: 41 6c 6c 6f 63 20 29 3b 0a 20 20 20 20 20 20 6d  Alloc );.      m
6040: 65 6d 63 70 79 28 26 70 2d 3e 61 41 6c 6c 6f 63  emcpy(&p->aAlloc
6050: 5b 6e 42 79 74 65 20 2d 20 6e 52 65 6d 5d 2c 20  [nByte - nRem], 
6060: 61 4e 65 78 74 2c 20 6e 43 6f 70 79 29 3b 0a 20  aNext, nCopy);. 
6070: 20 20 20 20 20 6e 52 65 6d 20 2d 3d 20 6e 43 6f       nRem -= nCo
6080: 70 79 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2a  py;.    }..    *
6090: 70 70 4f 75 74 20 3d 20 70 2d 3e 61 41 6c 6c 6f  ppOut = p->aAllo
60a0: 63 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  c;.  }..  return
60b0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
60c0: 2a 0a 2a 2a 20 52 65 61 64 20 61 20 76 61 72 69  *.** Read a vari
60d0: 6e 74 20 66 72 6f 6d 20 74 68 65 20 73 74 72 65  nt from the stre
60e0: 61 6d 20 6f 66 20 64 61 74 61 20 61 63 63 65 73  am of data acces
60f0: 73 65 64 20 62 79 20 70 2e 20 53 65 74 20 2a 70  sed by p. Set *p
6100: 6e 4f 75 74 20 74 6f 0a 2a 2a 20 74 68 65 20 76  nOut to.** the v
6110: 61 6c 75 65 20 72 65 61 64 2e 0a 2a 2f 0a 73 74  alue read..*/.st
6120: 61 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d 61  atic int vdbePma
6130: 52 65 61 64 56 61 72 69 6e 74 28 50 6d 61 52 65  ReadVarint(PmaRe
6140: 61 64 65 72 20 2a 70 2c 20 75 36 34 20 2a 70 6e  ader *p, u64 *pn
6150: 4f 75 74 29 7b 0a 20 20 69 6e 74 20 69 42 75 66  Out){.  int iBuf
6160: 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 61 4d 61 70  ;..  if( p->aMap
6170: 20 29 7b 0a 20 20 20 20 70 2d 3e 69 52 65 61 64   ){.    p->iRead
6180: 4f 66 66 20 2b 3d 20 73 71 6c 69 74 65 33 47 65  Off += sqlite3Ge
6190: 74 56 61 72 69 6e 74 28 26 70 2d 3e 61 4d 61 70  tVarint(&p->aMap
61a0: 5b 70 2d 3e 69 52 65 61 64 4f 66 66 5d 2c 20 70  [p->iReadOff], p
61b0: 6e 4f 75 74 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  nOut);.  }else{.
61c0: 20 20 20 20 69 42 75 66 20 3d 20 70 2d 3e 69 52      iBuf = p->iR
61d0: 65 61 64 4f 66 66 20 25 20 70 2d 3e 6e 42 75 66  eadOff % p->nBuf
61e0: 66 65 72 3b 0a 20 20 20 20 69 66 28 20 69 42 75  fer;.    if( iBu
61f0: 66 20 26 26 20 28 70 2d 3e 6e 42 75 66 66 65 72  f && (p->nBuffer
6200: 2d 69 42 75 66 29 3e 3d 39 20 29 7b 0a 20 20 20  -iBuf)>=9 ){.   
6210: 20 20 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b     p->iReadOff +
6220: 3d 20 73 71 6c 69 74 65 33 47 65 74 56 61 72 69  = sqlite3GetVari
6230: 6e 74 28 26 70 2d 3e 61 42 75 66 66 65 72 5b 69  nt(&p->aBuffer[i
6240: 42 75 66 5d 2c 20 70 6e 4f 75 74 29 3b 0a 20 20  Buf], pnOut);.  
6250: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 75    }else{.      u
6260: 38 20 61 56 61 72 69 6e 74 5b 31 36 5d 2c 20 2a  8 aVarint[16], *
6270: 61 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 20 3d  a;.      int i =
6280: 20 30 2c 20 72 63 3b 0a 20 20 20 20 20 20 64 6f   0, rc;.      do
6290: 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 76  {.        rc = v
62a0: 64 62 65 50 6d 61 52 65 61 64 42 6c 6f 62 28 70  dbePmaReadBlob(p
62b0: 2c 20 31 2c 20 26 61 29 3b 0a 20 20 20 20 20 20  , 1, &a);.      
62c0: 20 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72    if( rc ) retur
62d0: 6e 20 72 63 3b 0a 20 20 20 20 20 20 20 20 61 56  n rc;.        aV
62e0: 61 72 69 6e 74 5b 28 69 2b 2b 29 26 30 78 66 5d  arint[(i++)&0xf]
62f0: 20 3d 20 61 5b 30 5d 3b 0a 20 20 20 20 20 20 7d   = a[0];.      }
6300: 77 68 69 6c 65 28 20 28 61 5b 30 5d 26 30 78 38  while( (a[0]&0x8
6310: 30 29 21 3d 30 20 29 3b 0a 20 20 20 20 20 20 73  0)!=0 );.      s
6320: 71 6c 69 74 65 33 47 65 74 56 61 72 69 6e 74 28  qlite3GetVarint(
6330: 61 56 61 72 69 6e 74 2c 20 70 6e 4f 75 74 29 3b  aVarint, pnOut);
6340: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
6350: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
6360: 7d 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74  }../*.** Attempt
6370: 20 74 6f 20 6d 65 6d 6f 72 79 20 6d 61 70 20 66   to memory map f
6380: 69 6c 65 20 70 46 69 6c 65 2e 20 49 66 20 73 75  ile pFile. If su
6390: 63 63 65 73 73 66 75 6c 2c 20 73 65 74 20 2a 70  ccessful, set *p
63a0: 70 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68  p to point to th
63b0: 65 0a 2a 2a 20 6e 65 77 20 6d 61 70 70 69 6e 67  e.** new mapping
63c0: 20 61 6e 64 20 72 65 74 75 72 6e 20 53 51 4c 49   and return SQLI
63d0: 54 45 5f 4f 4b 2e 20 49 66 20 74 68 65 20 6d 61  TE_OK. If the ma
63e0: 70 70 69 6e 67 20 69 73 20 6e 6f 74 20 61 74 74  pping is not att
63f0: 65 6d 70 74 65 64 20 0a 2a 2a 20 28 62 65 63 61  empted .** (beca
6400: 75 73 65 20 74 68 65 20 66 69 6c 65 20 69 73 20  use the file is 
6410: 74 6f 6f 20 6c 61 72 67 65 20 6f 72 20 74 68 65  too large or the
6420: 20 56 46 53 20 6c 61 79 65 72 20 69 73 20 63 6f   VFS layer is co
6430: 6e 66 69 67 75 72 65 64 20 6e 6f 74 20 74 6f 20  nfigured not to 
6440: 75 73 65 0a 2a 2a 20 6d 6d 61 70 29 2c 20 72 65  use.** mmap), re
6450: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 61  turn SQLITE_OK a
6460: 6e 64 20 73 65 74 20 2a 70 70 20 74 6f 20 4e 55  nd set *pp to NU
6470: 4c 4c 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 69 66  LL..**.** Or, if
6480: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
6490: 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69  , return an SQLi
64a0: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 20 54  te error code. T
64b0: 68 65 20 66 69 6e 61 6c 20 76 61 6c 75 65 20 6f  he final value o
64c0: 66 0a 2a 2a 20 2a 70 70 20 69 73 20 75 6e 64 65  f.** *pp is unde
64d0: 66 69 6e 65 64 20 69 6e 20 74 68 69 73 20 63 61  fined in this ca
64e0: 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  se..*/.static in
64f0: 74 20 76 64 62 65 53 6f 72 74 65 72 4d 61 70 46  t vdbeSorterMapF
6500: 69 6c 65 28 53 6f 72 74 53 75 62 74 61 73 6b 20  ile(SortSubtask 
6510: 2a 70 54 61 73 6b 2c 20 53 6f 72 74 65 72 46 69  *pTask, SorterFi
6520: 6c 65 20 2a 70 46 69 6c 65 2c 20 75 38 20 2a 2a  le *pFile, u8 **
6530: 70 70 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  pp){.  int rc = 
6540: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28  SQLITE_OK;.  if(
6550: 20 70 46 69 6c 65 2d 3e 69 45 6f 66 3c 3d 28 69   pFile->iEof<=(i
6560: 36 34 29 28 70 54 61 73 6b 2d 3e 70 53 6f 72 74  64)(pTask->pSort
6570: 65 72 2d 3e 64 62 2d 3e 6e 4d 61 78 53 6f 72 74  er->db->nMaxSort
6580: 65 72 4d 6d 61 70 29 20 29 7b 0a 20 20 20 20 72  erMmap) ){.    r
6590: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 46 65 74  c = sqlite3OsFet
65a0: 63 68 28 70 46 69 6c 65 2d 3e 70 46 64 2c 20 30  ch(pFile->pFd, 0
65b0: 2c 20 70 46 69 6c 65 2d 3e 69 45 6f 66 2c 20 28  , pFile->iEof, (
65c0: 76 6f 69 64 2a 2a 29 70 70 29 3b 0a 20 20 7d 0a  void**)pp);.  }.
65d0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
65e0: 2f 2a 0a 2a 2a 20 53 65 65 6b 20 69 74 65 72 61  /*.** Seek itera
65f0: 74 6f 72 20 70 49 74 65 72 20 74 6f 20 6f 66 66  tor pIter to off
6600: 73 65 74 20 69 4f 66 66 20 77 69 74 68 69 6e 20  set iOff within 
6610: 66 69 6c 65 20 70 46 69 6c 65 2e 20 52 65 74 75  file pFile. Retu
6620: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 0a 2a 2a  rn SQLITE_OK .**
6630: 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   if successful, 
6640: 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  or an SQLite err
6650: 6f 72 20 63 6f 64 65 20 69 66 20 61 6e 20 65 72  or code if an er
6660: 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73  ror occurs..*/.s
6670: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d  tatic int vdbePm
6680: 61 52 65 61 64 65 72 53 65 65 6b 28 0a 20 20 53  aReaderSeek(.  S
6690: 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
66a0: 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  k,             /
66b0: 2a 20 54 61 73 6b 20 63 6f 6e 74 65 78 74 20 2a  * Task context *
66c0: 2f 0a 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70  /.  PmaReader *p
66d0: 49 74 65 72 2c 20 20 20 20 20 20 20 20 20 20 20  Iter,           
66e0: 20 20 20 20 2f 2a 20 49 74 65 72 61 74 65 20 74      /* Iterate t
66f0: 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f 0a 20 20  o populate */.  
6700: 53 6f 72 74 65 72 46 69 6c 65 20 2a 70 46 69 6c  SorterFile *pFil
6710: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
6720: 2f 2a 20 53 6f 72 74 65 72 20 66 69 6c 65 20 74  /* Sorter file t
6730: 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20  o read from */. 
6740: 20 69 36 34 20 69 4f 66 66 20 20 20 20 20 20 20   i64 iOff       
6750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6760: 20 2f 2a 20 4f 66 66 73 65 74 20 69 6e 20 70 46   /* Offset in pF
6770: 69 6c 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  ile */.){.  int 
6780: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
6790: 0a 20 20 61 73 73 65 72 74 28 20 70 49 74 65 72  .  assert( pIter
67a0: 2d 3e 70 49 6e 63 72 3d 3d 30 20 7c 7c 20 70 49  ->pIncr==0 || pI
67b0: 74 65 72 2d 3e 70 49 6e 63 72 2d 3e 62 45 6f 66  ter->pIncr->bEof
67c0: 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 70 49  ==0 );..  if( pI
67d0: 74 65 72 2d 3e 61 4d 61 70 20 29 7b 0a 20 20 20  ter->aMap ){.   
67e0: 20 73 71 6c 69 74 65 33 4f 73 55 6e 66 65 74 63   sqlite3OsUnfetc
67f0: 68 28 70 49 74 65 72 2d 3e 70 46 69 6c 65 2c 20  h(pIter->pFile, 
6800: 30 2c 20 70 49 74 65 72 2d 3e 61 4d 61 70 29 3b  0, pIter->aMap);
6810: 0a 20 20 20 20 70 49 74 65 72 2d 3e 61 4d 61 70  .    pIter->aMap
6820: 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 70 49 74 65   = 0;.  }.  pIte
6830: 72 2d 3e 69 52 65 61 64 4f 66 66 20 3d 20 69 4f  r->iReadOff = iO
6840: 66 66 3b 0a 20 20 70 49 74 65 72 2d 3e 69 45 6f  ff;.  pIter->iEo
6850: 66 20 3d 20 70 46 69 6c 65 2d 3e 69 45 6f 66 3b  f = pFile->iEof;
6860: 0a 20 20 70 49 74 65 72 2d 3e 70 46 69 6c 65 20  .  pIter->pFile 
6870: 3d 20 70 46 69 6c 65 2d 3e 70 46 64 3b 0a 0a 20  = pFile->pFd;.. 
6880: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
6890: 4d 61 70 46 69 6c 65 28 70 54 61 73 6b 2c 20 70  MapFile(pTask, p
68a0: 46 69 6c 65 2c 20 26 70 49 74 65 72 2d 3e 61 4d  File, &pIter->aM
68b0: 61 70 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  ap);.  if( rc==S
68c0: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 49 74 65  QLITE_OK && pIte
68d0: 72 2d 3e 61 4d 61 70 3d 3d 30 20 29 7b 0a 20 20  r->aMap==0 ){.  
68e0: 20 20 69 6e 74 20 70 67 73 7a 20 3d 20 70 54 61    int pgsz = pTa
68f0: 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 67 73  sk->pSorter->pgs
6900: 7a 3b 0a 20 20 20 20 69 6e 74 20 69 42 75 66 20  z;.    int iBuf 
6910: 3d 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66  = pIter->iReadOf
6920: 66 20 25 20 70 67 73 7a 3b 0a 20 20 20 20 69 66  f % pgsz;.    if
6930: 28 20 70 49 74 65 72 2d 3e 61 42 75 66 66 65 72  ( pIter->aBuffer
6940: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 49 74  ==0 ){.      pIt
6950: 65 72 2d 3e 61 42 75 66 66 65 72 20 3d 20 28 75  er->aBuffer = (u
6960: 38 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  8*)sqlite3Malloc
6970: 28 70 67 73 7a 29 3b 0a 20 20 20 20 20 20 69 66  (pgsz);.      if
6980: 28 20 70 49 74 65 72 2d 3e 61 42 75 66 66 65 72  ( pIter->aBuffer
6990: 3d 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49 54  ==0 ) rc = SQLIT
69a0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 70  E_NOMEM;.      p
69b0: 49 74 65 72 2d 3e 6e 42 75 66 66 65 72 20 3d 20  Iter->nBuffer = 
69c0: 70 67 73 7a 3b 0a 20 20 20 20 7d 0a 20 20 20 20  pgsz;.    }.    
69d0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
69e0: 4b 20 26 26 20 69 42 75 66 20 29 7b 0a 20 20 20  K && iBuf ){.   
69f0: 20 20 20 69 6e 74 20 6e 52 65 61 64 20 3d 20 70     int nRead = p
6a00: 67 73 7a 20 2d 20 69 42 75 66 3b 0a 20 20 20 20  gsz - iBuf;.    
6a10: 20 20 69 66 28 20 28 70 49 74 65 72 2d 3e 69 52    if( (pIter->iR
6a20: 65 61 64 4f 66 66 20 2b 20 6e 52 65 61 64 29 20  eadOff + nRead) 
6a30: 3e 20 70 49 74 65 72 2d 3e 69 45 6f 66 20 29 7b  > pIter->iEof ){
6a40: 0a 20 20 20 20 20 20 20 20 6e 52 65 61 64 20 3d  .        nRead =
6a50: 20 28 69 6e 74 29 28 70 49 74 65 72 2d 3e 69 45   (int)(pIter->iE
6a60: 6f 66 20 2d 20 70 49 74 65 72 2d 3e 69 52 65 61  of - pIter->iRea
6a70: 64 4f 66 66 29 3b 0a 20 20 20 20 20 20 7d 0a 20  dOff);.      }. 
6a80: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
6a90: 33 4f 73 52 65 61 64 28 0a 20 20 20 20 20 20 20  3OsRead(.       
6aa0: 20 20 20 70 49 74 65 72 2d 3e 70 46 69 6c 65 2c     pIter->pFile,
6ab0: 20 26 70 49 74 65 72 2d 3e 61 42 75 66 66 65 72   &pIter->aBuffer
6ac0: 5b 69 42 75 66 5d 2c 20 6e 52 65 61 64 2c 20 70  [iBuf], nRead, p
6ad0: 49 74 65 72 2d 3e 69 52 65 61 64 4f 66 66 0a 20  Iter->iReadOff. 
6ae0: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 61 73       );.      as
6af0: 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45  sert( rc!=SQLITE
6b00: 5f 49 4f 45 52 52 5f 53 48 4f 52 54 5f 52 45 41  _IOERR_SHORT_REA
6b10: 44 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  D );.    }.  }..
6b20: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
6b30: 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 69 74  /*.** Advance it
6b40: 65 72 61 74 6f 72 20 70 49 74 65 72 20 74 6f 20  erator pIter to 
6b50: 74 68 65 20 6e 65 78 74 20 6b 65 79 20 69 6e 20  the next key in 
6b60: 69 74 73 20 50 4d 41 2e 20 52 65 74 75 72 6e 20  its PMA. Return 
6b70: 53 51 4c 49 54 45 5f 4f 4b 20 69 66 0a 2a 2a 20  SQLITE_OK if.** 
6b80: 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c  no error occurs,
6b90: 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72   or an SQLite er
6ba0: 72 6f 72 20 63 6f 64 65 20 69 66 20 6f 6e 65 20  ror code if one 
6bb0: 64 6f 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  does..*/.static 
6bc0: 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61 64 65  int vdbePmaReade
6bd0: 72 4e 65 78 74 28 50 6d 61 52 65 61 64 65 72 20  rNext(PmaReader 
6be0: 2a 70 49 74 65 72 29 7b 0a 20 20 69 6e 74 20 72  *pIter){.  int r
6bf0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20  c = SQLITE_OK;  
6c00: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
6c10: 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 75  turn Code */.  u
6c20: 36 34 20 6e 52 65 63 20 3d 20 30 3b 20 20 20 20  64 nRec = 0;    
6c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6c40: 2a 20 53 69 7a 65 20 6f 66 20 72 65 63 6f 72 64  * Size of record
6c50: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 0a 20 20   in bytes */..  
6c60: 69 66 28 20 70 49 74 65 72 2d 3e 69 52 65 61 64  if( pIter->iRead
6c70: 4f 66 66 3e 3d 70 49 74 65 72 2d 3e 69 45 6f 66  Off>=pIter->iEof
6c80: 20 29 7b 0a 20 20 20 20 49 6e 63 72 4d 65 72 67   ){.    IncrMerg
6c90: 65 72 20 2a 70 49 6e 63 72 20 3d 20 70 49 74 65  er *pIncr = pIte
6ca0: 72 2d 3e 70 49 6e 63 72 3b 0a 20 20 20 20 69 6e  r->pIncr;.    in
6cb0: 74 20 62 45 6f 66 20 3d 20 31 3b 0a 20 20 20 20  t bEof = 1;.    
6cc0: 69 66 28 20 70 49 6e 63 72 20 29 7b 0a 20 20 20  if( pIncr ){.   
6cd0: 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72     rc = vdbeIncr
6ce0: 53 77 61 70 28 70 49 6e 63 72 29 3b 0a 20 20 20  Swap(pIncr);.   
6cf0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
6d00: 45 5f 4f 4b 20 26 26 20 70 49 6e 63 72 2d 3e 62  E_OK && pIncr->b
6d10: 45 6f 66 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  Eof==0 ){.      
6d20: 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65    rc = vdbePmaRe
6d30: 61 64 65 72 53 65 65 6b 28 0a 20 20 20 20 20 20  aderSeek(.      
6d40: 20 20 20 20 20 20 70 49 6e 63 72 2d 3e 70 54 61        pIncr->pTa
6d50: 73 6b 2c 20 70 49 74 65 72 2c 20 26 70 49 6e 63  sk, pIter, &pInc
6d60: 72 2d 3e 61 46 69 6c 65 5b 30 5d 2c 20 70 49 6e  r->aFile[0], pIn
6d70: 63 72 2d 3e 69 53 74 61 72 74 4f 66 66 0a 20 20  cr->iStartOff.  
6d80: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20        );.       
6d90: 20 62 45 6f 66 20 3d 20 30 3b 0a 20 20 20 20 20   bEof = 0;.     
6da0: 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66   }.    }..    if
6db0: 28 20 62 45 6f 66 20 29 7b 0a 20 20 20 20 20 20  ( bEof ){.      
6dc0: 2f 2a 20 54 68 69 73 20 69 73 20 61 6e 20 45 4f  /* This is an EO
6dd0: 46 20 63 6f 6e 64 69 74 69 6f 6e 20 2a 2f 0a 20  F condition */. 
6de0: 20 20 20 20 20 76 64 62 65 50 6d 61 52 65 61 64       vdbePmaRead
6df0: 65 72 43 6c 65 61 72 28 70 49 74 65 72 29 3b 0a  erClear(pIter);.
6e00: 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
6e10: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
6e20: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
6e30: 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65  ){.    rc = vdbe
6e40: 50 6d 61 52 65 61 64 56 61 72 69 6e 74 28 70 49  PmaReadVarint(pI
6e50: 74 65 72 2c 20 26 6e 52 65 63 29 3b 0a 20 20 7d  ter, &nRec);.  }
6e60: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
6e70: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 49 74 65  E_OK ){.    pIte
6e80: 72 2d 3e 6e 4b 65 79 20 3d 20 28 69 6e 74 29 6e  r->nKey = (int)n
6e90: 52 65 63 3b 0a 20 20 20 20 72 63 20 3d 20 76 64  Rec;.    rc = vd
6ea0: 62 65 50 6d 61 52 65 61 64 42 6c 6f 62 28 70 49  bePmaReadBlob(pI
6eb0: 74 65 72 2c 20 28 69 6e 74 29 6e 52 65 63 2c 20  ter, (int)nRec, 
6ec0: 26 70 49 74 65 72 2d 3e 61 4b 65 79 29 3b 0a 20  &pIter->aKey);. 
6ed0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
6ee0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61  .}../*.** Initia
6ef0: 6c 69 7a 65 20 69 74 65 72 61 74 6f 72 20 70 49  lize iterator pI
6f00: 74 65 72 20 74 6f 20 73 63 61 6e 20 74 68 72 6f  ter to scan thro
6f10: 75 67 68 20 74 68 65 20 50 4d 41 20 73 74 6f 72  ugh the PMA stor
6f20: 65 64 20 69 6e 20 66 69 6c 65 20 70 46 69 6c 65  ed in file pFile
6f30: 0a 2a 2a 20 73 74 61 72 74 69 6e 67 20 61 74 20  .** starting at 
6f40: 6f 66 66 73 65 74 20 69 53 74 61 72 74 20 61 6e  offset iStart an
6f50: 64 20 65 6e 64 69 6e 67 20 61 74 20 6f 66 66 73  d ending at offs
6f60: 65 74 20 69 45 6f 66 2d 31 2e 20 54 68 69 73 20  et iEof-1. This 
6f70: 66 75 6e 63 74 69 6f 6e 20 0a 2a 2a 20 6c 65 61  function .** lea
6f80: 76 65 73 20 74 68 65 20 69 74 65 72 61 74 6f 72  ves the iterator
6f90: 20 70 6f 69 6e 74 69 6e 67 20 74 6f 20 74 68 65   pointing to the
6fa0: 20 66 69 72 73 74 20 6b 65 79 20 69 6e 20 74 68   first key in th
6fb0: 65 20 50 4d 41 20 28 6f 72 20 45 4f 46 20 69 66  e PMA (or EOF if
6fc0: 20 74 68 65 20 0a 2a 2a 20 50 4d 41 20 69 73 20   the .** PMA is 
6fd0: 65 6d 70 74 79 29 2e 0a 2a 2a 0a 2a 2a 20 49 66  empty)..**.** If
6fe0: 20 74 68 65 20 70 6e 42 79 74 65 20 70 61 72 61   the pnByte para
6ff0: 6d 65 74 65 72 20 69 73 20 4e 55 4c 4c 2c 20 74  meter is NULL, t
7000: 68 65 6e 20 69 74 20 69 73 20 61 73 73 75 6d 65  hen it is assume
7010: 64 20 74 68 61 74 20 74 68 65 20 66 69 6c 65 20  d that the file 
7020: 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 61 20 73  .** contains a s
7030: 69 6e 67 6c 65 20 50 4d 41 2c 20 61 6e 64 20 74  ingle PMA, and t
7040: 68 61 74 20 74 68 61 74 20 50 4d 41 20 6f 6d 69  hat that PMA omi
7050: 74 73 20 74 68 65 20 69 6e 69 74 69 61 6c 20 6c  ts the initial l
7060: 65 6e 67 74 68 20 76 61 72 69 6e 74 2e 0a 2a 2f  ength varint..*/
7070: 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65  .static int vdbe
7080: 50 6d 61 52 65 61 64 65 72 49 6e 69 74 28 0a 20  PmaReaderInit(. 
7090: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
70a0: 61 73 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20  ask,            
70b0: 20 2f 2a 20 54 61 73 6b 20 63 6f 6e 74 65 78 74   /* Task context
70c0: 20 2a 2f 0a 20 20 53 6f 72 74 65 72 46 69 6c 65   */.  SorterFile
70d0: 20 2a 70 46 69 6c 65 2c 20 20 20 20 20 20 20 20   *pFile,        
70e0: 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20        /* Sorter 
70f0: 66 69 6c 65 20 74 6f 20 72 65 61 64 20 66 72 6f  file to read fro
7100: 6d 20 2a 2f 0a 20 20 69 36 34 20 69 53 74 61 72  m */.  i64 iStar
7110: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
7120: 20 20 20 20 20 20 20 2f 2a 20 53 74 61 72 74 20         /* Start 
7130: 6f 66 66 73 65 74 20 69 6e 20 70 46 69 6c 65 20  offset in pFile 
7140: 2a 2f 0a 20 20 50 6d 61 52 65 61 64 65 72 20 2a  */.  PmaReader *
7150: 70 49 74 65 72 2c 20 20 20 20 20 20 20 20 20 20  pIter,          
7160: 20 20 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72       /* Iterator
7170: 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f 0a   to populate */.
7180: 20 20 69 36 34 20 2a 70 6e 42 79 74 65 20 20 20    i64 *pnByte   
7190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
71a0: 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 49 6e 63    /* IN/OUT: Inc
71b0: 72 65 6d 65 6e 74 20 74 68 69 73 20 76 61 6c 75  rement this valu
71c0: 65 20 62 79 20 50 4d 41 20 73 69 7a 65 20 2a 2f  e by PMA size */
71d0: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20  .){.  int rc;.. 
71e0: 20 61 73 73 65 72 74 28 20 70 46 69 6c 65 2d 3e   assert( pFile->
71f0: 69 45 6f 66 3e 69 53 74 61 72 74 20 29 3b 0a 20  iEof>iStart );. 
7200: 20 61 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e   assert( pIter->
7210: 61 41 6c 6c 6f 63 3d 3d 30 20 26 26 20 70 49 74  aAlloc==0 && pIt
7220: 65 72 2d 3e 6e 41 6c 6c 6f 63 3d 3d 30 20 29 3b  er->nAlloc==0 );
7230: 0a 20 20 61 73 73 65 72 74 28 20 70 49 74 65 72  .  assert( pIter
7240: 2d 3e 61 42 75 66 66 65 72 3d 3d 30 20 29 3b 0a  ->aBuffer==0 );.
7250: 20 20 61 73 73 65 72 74 28 20 70 49 74 65 72 2d    assert( pIter-
7260: 3e 61 4d 61 70 3d 3d 30 20 29 3b 0a 0a 20 20 72  >aMap==0 );..  r
7270: 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65  c = vdbePmaReade
7280: 72 53 65 65 6b 28 70 54 61 73 6b 2c 20 70 49 74  rSeek(pTask, pIt
7290: 65 72 2c 20 70 46 69 6c 65 2c 20 69 53 74 61 72  er, pFile, iStar
72a0: 74 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  t);.  if( rc==SQ
72b0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 75  LITE_OK ){.    u
72c0: 36 34 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20  64 nByte;       
72d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
72e0: 53 69 7a 65 20 6f 66 20 50 4d 41 20 69 6e 20 62  Size of PMA in b
72f0: 79 74 65 73 20 2a 2f 0a 20 20 20 20 72 63 20 3d  ytes */.    rc =
7300: 20 76 64 62 65 50 6d 61 52 65 61 64 56 61 72 69   vdbePmaReadVari
7310: 6e 74 28 70 49 74 65 72 2c 20 26 6e 42 79 74 65  nt(pIter, &nByte
7320: 29 3b 0a 20 20 20 20 70 49 74 65 72 2d 3e 69 45  );.    pIter->iE
7330: 6f 66 20 3d 20 70 49 74 65 72 2d 3e 69 52 65 61  of = pIter->iRea
7340: 64 4f 66 66 20 2b 20 6e 42 79 74 65 3b 0a 20 20  dOff + nByte;.  
7350: 20 20 2a 70 6e 42 79 74 65 20 2b 3d 20 6e 42 79    *pnByte += nBy
7360: 74 65 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72  te;.  }..  if( r
7370: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
7380: 20 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61      rc = vdbePma
7390: 52 65 61 64 65 72 4e 65 78 74 28 70 49 74 65 72  ReaderNext(pIter
73a0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
73b0: 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6f  rc;.}.../*.** Co
73c0: 6d 70 61 72 65 20 6b 65 79 31 20 28 62 75 66 66  mpare key1 (buff
73d0: 65 72 20 70 4b 65 79 31 2c 20 73 69 7a 65 20 6e  er pKey1, size n
73e0: 4b 65 79 31 20 62 79 74 65 73 29 20 77 69 74 68  Key1 bytes) with
73f0: 20 6b 65 79 32 20 28 62 75 66 66 65 72 20 70 4b   key2 (buffer pK
7400: 65 79 32 2c 20 0a 2a 2a 20 73 69 7a 65 20 6e 4b  ey2, .** size nK
7410: 65 79 32 20 62 79 74 65 73 29 2e 20 55 73 65 20  ey2 bytes). Use 
7420: 28 70 54 61 73 6b 2d 3e 70 4b 65 79 49 6e 66 6f  (pTask->pKeyInfo
7430: 29 20 66 6f 72 20 74 68 65 20 63 6f 6c 6c 61 74  ) for the collat
7440: 69 6f 6e 20 73 65 71 75 65 6e 63 65 73 0a 2a 2a  ion sequences.**
7450: 20 75 73 65 64 20 62 79 20 74 68 65 20 63 6f 6d   used by the com
7460: 70 61 72 69 73 6f 6e 2e 20 52 65 74 75 72 6e 20  parison. Return 
7470: 74 68 65 20 72 65 73 75 6c 74 20 6f 66 20 74 68  the result of th
7480: 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2e 0a 2a 2a  e comparison..**
7490: 0a 2a 2a 20 42 65 66 6f 72 65 20 72 65 74 75 72  .** Before retur
74a0: 6e 69 6e 67 2c 20 6f 62 6a 65 63 74 20 28 70 54  ning, object (pT
74b0: 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 29 20  ask->pUnpacked) 
74c0: 69 73 20 70 6f 70 75 6c 61 74 65 64 20 77 69 74  is populated wit
74d0: 68 20 74 68 65 0a 2a 2a 20 75 6e 70 61 63 6b 65  h the.** unpacke
74e0: 64 20 76 65 72 73 69 6f 6e 20 6f 66 20 6b 65 79  d version of key
74f0: 32 2e 20 4f 72 2c 20 69 66 20 70 4b 65 79 32 20  2. Or, if pKey2 
7500: 69 73 20 70 61 73 73 65 64 20 61 20 4e 55 4c 4c  is passed a NULL
7510: 20 70 6f 69 6e 74 65 72 2c 20 74 68 65 6e 20 69   pointer, then i
7520: 74 20 0a 2a 2a 20 69 73 20 61 73 73 75 6d 65 64  t .** is assumed
7530: 20 74 68 61 74 20 74 68 65 20 28 70 54 61 73 6b   that the (pTask
7540: 2d 3e 70 55 6e 70 61 63 6b 65 64 29 20 73 74 72  ->pUnpacked) str
7550: 75 63 74 75 72 65 20 61 6c 72 65 61 64 79 20 63  ucture already c
7560: 6f 6e 74 61 69 6e 73 20 74 68 65 20 0a 2a 2a 20  ontains the .** 
7570: 75 6e 70 61 63 6b 65 64 20 6b 65 79 20 74 6f 20  unpacked key to 
7580: 75 73 65 20 61 73 20 6b 65 79 32 2e 0a 2a 2a 0a  use as key2..**.
7590: 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 65 72 72  ** If an OOM err
75a0: 6f 72 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65  or is encountere
75b0: 64 2c 20 28 70 54 61 73 6b 2d 3e 70 55 6e 70 61  d, (pTask->pUnpa
75c0: 63 6b 65 64 2d 3e 65 72 72 6f 72 5f 72 63 29 20  cked->error_rc) 
75d0: 69 73 20 73 65 74 0a 2a 2a 20 74 6f 20 53 51 4c  is set.** to SQL
75e0: 49 54 45 5f 4e 4f 4d 45 4d 2e 0a 2a 2f 0a 73 74  ITE_NOMEM..*/.st
75f0: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
7600: 74 65 72 43 6f 6d 70 61 72 65 28 0a 20 20 53 6f  terCompare(.  So
7610: 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b  rtSubtask *pTask
7620: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
7630: 20 53 75 62 74 61 73 6b 20 63 6f 6e 74 65 78 74   Subtask context
7640: 20 28 66 6f 72 20 70 4b 65 79 49 6e 66 6f 29 20   (for pKeyInfo) 
7650: 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20  */.  const void 
7660: 2a 70 4b 65 79 31 2c 20 69 6e 74 20 6e 4b 65 79  *pKey1, int nKey
7670: 31 2c 20 20 20 2f 2a 20 4c 65 66 74 20 73 69 64  1,   /* Left sid
7680: 65 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20  e of comparison 
7690: 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20  */.  const void 
76a0: 2a 70 4b 65 79 32 2c 20 69 6e 74 20 6e 4b 65 79  *pKey2, int nKey
76b0: 32 20 20 20 20 2f 2a 20 52 69 67 68 74 20 73 69  2    /* Right si
76c0: 64 65 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e  de of comparison
76d0: 20 2a 2f 0a 29 7b 0a 20 20 55 6e 70 61 63 6b 65   */.){.  Unpacke
76e0: 64 52 65 63 6f 72 64 20 2a 72 32 20 3d 20 70 54  dRecord *r2 = pT
76f0: 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 3b 0a  ask->pUnpacked;.
7700: 20 20 69 66 28 20 70 4b 65 79 32 20 29 7b 0a 20    if( pKey2 ){. 
7710: 20 20 20 73 71 6c 69 74 65 33 56 64 62 65 52 65     sqlite3VdbeRe
7720: 63 6f 72 64 55 6e 70 61 63 6b 28 70 54 61 73 6b  cordUnpack(pTask
7730: 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49  ->pSorter->pKeyI
7740: 6e 66 6f 2c 20 6e 4b 65 79 32 2c 20 70 4b 65 79  nfo, nKey2, pKey
7750: 32 2c 20 72 32 29 3b 0a 20 20 7d 0a 20 20 72 65  2, r2);.  }.  re
7760: 74 75 72 6e 20 73 71 6c 69 74 65 33 56 64 62 65  turn sqlite3Vdbe
7770: 52 65 63 6f 72 64 43 6f 6d 70 61 72 65 28 6e 4b  RecordCompare(nK
7780: 65 79 31 2c 20 70 4b 65 79 31 2c 20 72 32 2c 20  ey1, pKey1, r2, 
7790: 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  0);.}../*.** Thi
77a0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
77b0: 6c 6c 65 64 20 74 6f 20 63 6f 6d 70 61 72 65 20  lled to compare 
77c0: 74 77 6f 20 69 74 65 72 61 74 6f 72 20 6b 65 79  two iterator key
77d0: 73 20 77 68 65 6e 20 6d 65 72 67 69 6e 67 20 0a  s when merging .
77e0: 2a 2a 20 6d 75 6c 74 69 70 6c 65 20 62 2d 74 72  ** multiple b-tr
77f0: 65 65 20 73 65 67 6d 65 6e 74 73 2e 20 50 61 72  ee segments. Par
7800: 61 6d 65 74 65 72 20 69 4f 75 74 20 69 73 20 74  ameter iOut is t
7810: 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20  he index of the 
7820: 61 54 72 65 65 5b 5d 20 0a 2a 2a 20 76 61 6c 75  aTree[] .** valu
7830: 65 20 74 6f 20 72 65 63 61 6c 63 75 6c 61 74 65  e to recalculate
7840: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
7850: 76 64 62 65 53 6f 72 74 65 72 44 6f 43 6f 6d 70  vdbeSorterDoComp
7860: 61 72 65 28 0a 20 20 53 6f 72 74 53 75 62 74 61  are(.  SortSubta
7870: 73 6b 20 2a 70 54 61 73 6b 2c 20 0a 20 20 4d 65  sk *pTask, .  Me
7880: 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67  rgeEngine *pMerg
7890: 65 72 2c 20 0a 20 20 69 6e 74 20 69 4f 75 74 0a  er, .  int iOut.
78a0: 29 7b 0a 20 20 69 6e 74 20 69 31 3b 0a 20 20 69  ){.  int i1;.  i
78b0: 6e 74 20 69 32 3b 0a 20 20 69 6e 74 20 69 52 65  nt i2;.  int iRe
78c0: 73 3b 0a 20 20 50 6d 61 52 65 61 64 65 72 20 2a  s;.  PmaReader *
78d0: 70 31 3b 0a 20 20 50 6d 61 52 65 61 64 65 72 20  p1;.  PmaReader 
78e0: 2a 70 32 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  *p2;..  assert( 
78f0: 69 4f 75 74 3c 70 4d 65 72 67 65 72 2d 3e 6e 54  iOut<pMerger->nT
7900: 72 65 65 20 26 26 20 69 4f 75 74 3e 30 20 29 3b  ree && iOut>0 );
7910: 0a 0a 20 20 69 66 28 20 69 4f 75 74 3e 3d 28 70  ..  if( iOut>=(p
7920: 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65 2f 32 29  Merger->nTree/2)
7930: 20 29 7b 0a 20 20 20 20 69 31 20 3d 20 28 69 4f   ){.    i1 = (iO
7940: 75 74 20 2d 20 70 4d 65 72 67 65 72 2d 3e 6e 54  ut - pMerger->nT
7950: 72 65 65 2f 32 29 20 2a 20 32 3b 0a 20 20 20 20  ree/2) * 2;.    
7960: 69 32 20 3d 20 69 31 20 2b 20 31 3b 0a 20 20 7d  i2 = i1 + 1;.  }
7970: 65 6c 73 65 7b 0a 20 20 20 20 69 31 20 3d 20 70  else{.    i1 = p
7980: 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 4f  Merger->aTree[iO
7990: 75 74 2a 32 5d 3b 0a 20 20 20 20 69 32 20 3d 20  ut*2];.    i2 = 
79a0: 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69  pMerger->aTree[i
79b0: 4f 75 74 2a 32 2b 31 5d 3b 0a 20 20 7d 0a 0a 20  Out*2+1];.  }.. 
79c0: 20 70 31 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e   p1 = &pMerger->
79d0: 61 49 74 65 72 5b 69 31 5d 3b 0a 20 20 70 32 20  aIter[i1];.  p2 
79e0: 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65  = &pMerger->aIte
79f0: 72 5b 69 32 5d 3b 0a 0a 20 20 69 66 28 20 70 31  r[i2];..  if( p1
7a00: 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20  ->pFile==0 ){.  
7a10: 20 20 69 52 65 73 20 3d 20 69 32 3b 0a 20 20 7d    iRes = i2;.  }
7a20: 65 6c 73 65 20 69 66 28 20 70 32 2d 3e 70 46 69  else if( p2->pFi
7a30: 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69 52 65  le==0 ){.    iRe
7a40: 73 20 3d 20 69 31 3b 0a 20 20 7d 65 6c 73 65 7b  s = i1;.  }else{
7a50: 0a 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 20 20  .    int res;.  
7a60: 20 20 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d    assert( pTask-
7a70: 3e 70 55 6e 70 61 63 6b 65 64 21 3d 30 20 29 3b  >pUnpacked!=0 );
7a80: 20 20 2f 2a 20 61 6c 6c 6f 63 61 74 65 64 20 69    /* allocated i
7a90: 6e 20 76 64 62 65 53 6f 72 74 53 75 62 74 61 73  n vdbeSortSubtas
7aa0: 6b 4d 61 69 6e 28 29 20 2a 2f 0a 20 20 20 20 72  kMain() */.    r
7ab0: 65 73 20 3d 20 76 64 62 65 53 6f 72 74 65 72 43  es = vdbeSorterC
7ac0: 6f 6d 70 61 72 65 28 0a 20 20 20 20 20 20 20 20  ompare(.        
7ad0: 70 54 61 73 6b 2c 20 70 31 2d 3e 61 4b 65 79 2c  pTask, p1->aKey,
7ae0: 20 70 31 2d 3e 6e 4b 65 79 2c 20 70 32 2d 3e 61   p1->nKey, p2->a
7af0: 4b 65 79 2c 20 70 32 2d 3e 6e 4b 65 79 0a 20 20  Key, p2->nKey.  
7b00: 20 20 29 3b 0a 20 20 20 20 69 66 28 20 72 65 73    );.    if( res
7b10: 3c 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 52 65  <=0 ){.      iRe
7b20: 73 20 3d 20 69 31 3b 0a 20 20 20 20 7d 65 6c 73  s = i1;.    }els
7b30: 65 7b 0a 20 20 20 20 20 20 69 52 65 73 20 3d 20  e{.      iRes = 
7b40: 69 32 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  i2;.    }.  }.. 
7b50: 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b   pMerger->aTree[
7b60: 69 4f 75 74 5d 20 3d 20 69 52 65 73 3b 0a 20 20  iOut] = iRes;.  
7b70: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
7b80: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69  ;.}../*.** Initi
7b90: 61 6c 69 7a 65 20 74 68 65 20 74 65 6d 70 6f 72  alize the tempor
7ba0: 61 72 79 20 69 6e 64 65 78 20 63 75 72 73 6f 72  ary index cursor
7bb0: 20 6a 75 73 74 20 6f 70 65 6e 65 64 20 61 73 20   just opened as 
7bc0: 61 20 73 6f 72 74 65 72 20 63 75 72 73 6f 72 2e  a sorter cursor.
7bd0: 0a 2a 2a 0a 2a 2a 20 55 73 75 61 6c 6c 79 2c 20  .**.** Usually, 
7be0: 74 68 65 20 73 6f 72 74 65 72 20 6d 6f 64 75 6c  the sorter modul
7bf0: 65 20 75 73 65 73 20 74 68 65 20 76 61 6c 75 65  e uses the value
7c00: 20 6f 66 20 28 70 43 73 72 2d 3e 70 4b 65 79 49   of (pCsr->pKeyI
7c10: 6e 66 6f 2d 3e 6e 46 69 65 6c 64 29 0a 2a 2a 20  nfo->nField).** 
7c20: 74 6f 20 64 65 74 65 72 6d 69 6e 65 20 74 68 65  to determine the
7c30: 20 6e 75 6d 62 65 72 20 6f 66 20 66 69 65 6c 64   number of field
7c40: 73 20 74 68 61 74 20 73 68 6f 75 6c 64 20 62 65  s that should be
7c50: 20 63 6f 6d 70 61 72 65 64 20 66 72 6f 6d 20 74   compared from t
7c60: 68 65 0a 2a 2a 20 72 65 63 6f 72 64 73 20 62 65  he.** records be
7c70: 69 6e 67 20 73 6f 72 74 65 64 2e 20 48 6f 77 65  ing sorted. Howe
7c80: 76 65 72 2c 20 69 66 20 74 68 65 20 76 61 6c 75  ver, if the valu
7c90: 65 20 70 61 73 73 65 64 20 61 73 20 61 72 67 75  e passed as argu
7ca0: 6d 65 6e 74 20 6e 46 69 65 6c 64 0a 2a 2a 20 69  ment nField.** i
7cb0: 73 20 6e 6f 6e 2d 7a 65 72 6f 20 61 6e 64 20 74  s non-zero and t
7cc0: 68 65 20 73 6f 72 74 65 72 20 69 73 20 61 62 6c  he sorter is abl
7cd0: 65 20 74 6f 20 67 75 61 72 61 6e 74 65 65 20 61  e to guarantee a
7ce0: 20 73 74 61 62 6c 65 20 73 6f 72 74 2c 20 6e 46   stable sort, nF
7cf0: 69 65 6c 64 0a 2a 2a 20 69 73 20 75 73 65 64 20  ield.** is used 
7d00: 69 6e 73 74 65 61 64 2e 20 54 68 69 73 20 69 73  instead. This is
7d10: 20 75 73 65 64 20 77 68 65 6e 20 73 6f 72 74 69   used when sorti
7d20: 6e 67 20 72 65 63 6f 72 64 73 20 66 6f 72 20 61  ng records for a
7d30: 20 43 52 45 41 54 45 20 49 4e 44 45 58 0a 2a 2a   CREATE INDEX.**
7d40: 20 73 74 61 74 65 6d 65 6e 74 2e 20 49 6e 20 74   statement. In t
7d50: 68 69 73 20 63 61 73 65 2c 20 6b 65 79 73 20 61  his case, keys a
7d60: 72 65 20 61 6c 77 61 79 73 20 64 65 6c 69 76 65  re always delive
7d70: 72 65 64 20 74 6f 20 74 68 65 20 73 6f 72 74 65  red to the sorte
7d80: 72 20 69 6e 0a 2a 2a 20 6f 72 64 65 72 20 6f 66  r in.** order of
7d90: 20 74 68 65 20 70 72 69 6d 61 72 79 20 6b 65 79   the primary key
7da0: 2c 20 77 68 69 63 68 20 68 61 70 70 65 6e 73 20  , which happens 
7db0: 74 6f 20 62 65 20 6d 61 6b 65 20 75 70 20 74 68  to be make up th
7dc0: 65 20 66 69 6e 61 6c 20 70 61 72 74 20 0a 2a 2a  e final part .**
7dd0: 20 6f 66 20 74 68 65 20 72 65 63 6f 72 64 73 20   of the records 
7de0: 62 65 69 6e 67 20 73 6f 72 74 65 64 2e 20 53 6f  being sorted. So
7df0: 20 69 66 20 74 68 65 20 73 6f 72 74 20 69 73 20   if the sort is 
7e00: 73 74 61 62 6c 65 2c 20 74 68 65 72 65 20 69 73  stable, there is
7e10: 20 6e 65 76 65 72 0a 2a 2a 20 61 6e 79 20 72 65   never.** any re
7e20: 61 73 6f 6e 20 74 6f 20 63 6f 6d 70 61 72 65 20  ason to compare 
7e30: 50 4b 20 66 69 65 6c 64 73 20 61 6e 64 20 74 68  PK fields and th
7e40: 65 79 20 63 61 6e 20 62 65 20 69 67 6e 6f 72 65  ey can be ignore
7e50: 64 20 66 6f 72 20 61 20 73 6d 61 6c 6c 0a 2a 2a  d for a small.**
7e60: 20 70 65 72 66 6f 72 6d 61 6e 63 65 20 62 6f 6f   performance boo
7e70: 73 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 6f  st..**.** The so
7e80: 72 74 65 72 20 63 61 6e 20 67 75 61 72 61 6e 74  rter can guarant
7e90: 65 65 20 61 20 73 74 61 62 6c 65 20 73 6f 72 74  ee a stable sort
7ea0: 20 77 68 65 6e 20 72 75 6e 6e 69 6e 67 20 69 6e   when running in
7eb0: 20 73 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64   single-threaded
7ec0: 0a 2a 2a 20 6d 6f 64 65 2c 20 62 75 74 20 6e 6f  .** mode, but no
7ed0: 74 20 69 6e 20 6d 75 6c 74 69 2d 74 68 72 65 61  t in multi-threa
7ee0: 64 65 64 20 6d 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20  ded mode..**.** 
7ef0: 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74  SQLITE_OK is ret
7f00: 75 72 6e 65 64 20 69 66 20 73 75 63 63 65 73 73  urned if success
7f10: 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74  ful, or an SQLit
7f20: 65 20 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68  e error code oth
7f30: 65 72 77 69 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73  erwise..*/.int s
7f40: 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72  qlite3VdbeSorter
7f50: 49 6e 69 74 28 0a 20 20 73 71 6c 69 74 65 33 20  Init(.  sqlite3 
7f60: 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20  *db,            
7f70: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
7f80: 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 28  ase connection (
7f90: 66 6f 72 20 6d 61 6c 6c 6f 63 28 29 29 20 2a 2f  for malloc()) */
7fa0: 0a 20 20 69 6e 74 20 6e 46 69 65 6c 64 2c 20 20  .  int nField,  
7fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7fc0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
7fd0: 6b 65 79 20 66 69 65 6c 64 73 20 69 6e 20 65 61  key fields in ea
7fe0: 63 68 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20 56  ch record */.  V
7ff0: 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 20  dbeCursor *pCsr 
8000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8010: 2a 20 43 75 72 73 6f 72 20 74 68 61 74 20 68 6f  * Cursor that ho
8020: 6c 64 73 20 74 68 65 20 6e 65 77 20 73 6f 72 74  lds the new sort
8030: 65 72 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 70  er */.){.  int p
8040: 67 73 7a 3b 20 20 20 20 20 20 20 20 20 20 20 20  gsz;            
8050: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
8060: 67 65 20 73 69 7a 65 20 6f 66 20 6d 61 69 6e 20  ge size of main 
8070: 64 61 74 61 62 61 73 65 20 2a 2f 0a 20 20 69 6e  database */.  in
8080: 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20  t i;            
8090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
80a0: 20 55 73 65 64 20 74 6f 20 69 74 65 72 61 74 65   Used to iterate
80b0: 20 74 68 72 6f 75 67 68 20 61 54 61 73 6b 5b 5d   through aTask[]
80c0: 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 43 61 63 68   */.  int mxCach
80d0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
80e0: 20 20 20 20 20 20 2f 2a 20 43 61 63 68 65 20 73        /* Cache s
80f0: 69 7a 65 20 2a 2f 0a 20 20 56 64 62 65 53 6f 72  ize */.  VdbeSor
8100: 74 65 72 20 2a 70 53 6f 72 74 65 72 3b 20 20 20  ter *pSorter;   
8110: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
8120: 6e 65 77 20 73 6f 72 74 65 72 20 2a 2f 0a 20 20  new sorter */.  
8130: 4b 65 79 49 6e 66 6f 20 2a 70 4b 65 79 49 6e 66  KeyInfo *pKeyInf
8140: 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  o;              
8150: 2f 2a 20 43 6f 70 79 20 6f 66 20 70 43 73 72 2d  /* Copy of pCsr-
8160: 3e 70 4b 65 79 49 6e 66 6f 20 77 69 74 68 20 64  >pKeyInfo with d
8170: 62 3d 3d 30 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  b==0 */.  int sz
8180: 4b 65 79 49 6e 66 6f 3b 20 20 20 20 20 20 20 20  KeyInfo;        
8190: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
81a0: 65 20 6f 66 20 70 43 73 72 2d 3e 70 4b 65 79 49  e of pCsr->pKeyI
81b0: 6e 66 6f 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  nfo in bytes */.
81c0: 20 20 69 6e 74 20 73 7a 3b 20 20 20 20 20 20 20    int sz;       
81d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
81e0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 70 53 6f    /* Size of pSo
81f0: 72 74 65 72 20 69 6e 20 62 79 74 65 73 20 2a 2f  rter in bytes */
8200: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
8210: 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 57 6f  TE_OK;.  int nWo
8220: 72 6b 65 72 20 3d 20 28 73 71 6c 69 74 65 33 47  rker = (sqlite3G
8230: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62 43 6f 72  lobalConfig.bCor
8240: 65 4d 75 74 65 78 3f 73 71 6c 69 74 65 33 47 6c  eMutex?sqlite3Gl
8250: 6f 62 61 6c 43 6f 6e 66 69 67 2e 6e 57 6f 72 6b  obalConfig.nWork
8260: 65 72 3a 30 29 3b 0a 0a 20 20 61 73 73 65 72 74  er:0);..  assert
8270: 28 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f  ( pCsr->pKeyInfo
8280: 20 26 26 20 70 43 73 72 2d 3e 70 42 74 3d 3d 30   && pCsr->pBt==0
8290: 20 29 3b 0a 20 20 73 7a 4b 65 79 49 6e 66 6f 20   );.  szKeyInfo 
82a0: 3d 20 73 69 7a 65 6f 66 28 4b 65 79 49 6e 66 6f  = sizeof(KeyInfo
82b0: 29 20 2b 20 28 70 43 73 72 2d 3e 70 4b 65 79 49  ) + (pCsr->pKeyI
82c0: 6e 66 6f 2d 3e 6e 46 69 65 6c 64 2d 31 29 2a 73  nfo->nField-1)*s
82d0: 69 7a 65 6f 66 28 43 6f 6c 6c 53 65 71 2a 29 3b  izeof(CollSeq*);
82e0: 0a 20 20 73 7a 20 3d 20 73 69 7a 65 6f 66 28 56  .  sz = sizeof(V
82f0: 64 62 65 53 6f 72 74 65 72 29 20 2b 20 6e 57 6f  dbeSorter) + nWo
8300: 72 6b 65 72 20 2a 20 73 69 7a 65 6f 66 28 53 6f  rker * sizeof(So
8310: 72 74 53 75 62 74 61 73 6b 29 3b 0a 0a 20 20 70  rtSubtask);..  p
8320: 53 6f 72 74 65 72 20 3d 20 28 56 64 62 65 53 6f  Sorter = (VdbeSo
8330: 72 74 65 72 2a 29 73 71 6c 69 74 65 33 44 62 4d  rter*)sqlite3DbM
8340: 61 6c 6c 6f 63 5a 65 72 6f 28 64 62 2c 20 73 7a  allocZero(db, sz
8350: 20 2b 20 73 7a 4b 65 79 49 6e 66 6f 29 3b 0a 20   + szKeyInfo);. 
8360: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 20 3d   pCsr->pSorter =
8370: 20 70 53 6f 72 74 65 72 3b 0a 20 20 69 66 28 20   pSorter;.  if( 
8380: 70 53 6f 72 74 65 72 3d 3d 30 20 29 7b 0a 20 20  pSorter==0 ){.  
8390: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
83a0: 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  MEM;.  }else{.  
83b0: 20 20 70 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49    pSorter->pKeyI
83c0: 6e 66 6f 20 3d 20 70 4b 65 79 49 6e 66 6f 20 3d  nfo = pKeyInfo =
83d0: 20 28 4b 65 79 49 6e 66 6f 2a 29 28 28 75 38 2a   (KeyInfo*)((u8*
83e0: 29 70 53 6f 72 74 65 72 20 2b 20 73 7a 29 3b 0a  )pSorter + sz);.
83f0: 20 20 20 20 6d 65 6d 63 70 79 28 70 4b 65 79 49      memcpy(pKeyI
8400: 6e 66 6f 2c 20 70 43 73 72 2d 3e 70 4b 65 79 49  nfo, pCsr->pKeyI
8410: 6e 66 6f 2c 20 73 7a 4b 65 79 49 6e 66 6f 29 3b  nfo, szKeyInfo);
8420: 0a 20 20 20 20 70 4b 65 79 49 6e 66 6f 2d 3e 64  .    pKeyInfo->d
8430: 62 20 3d 20 30 3b 0a 20 20 20 20 69 66 28 20 6e  b = 0;.    if( n
8440: 46 69 65 6c 64 20 26 26 20 6e 57 6f 72 6b 65 72  Field && nWorker
8450: 3d 3d 30 20 29 20 70 4b 65 79 49 6e 66 6f 2d 3e  ==0 ) pKeyInfo->
8460: 6e 46 69 65 6c 64 20 3d 20 6e 46 69 65 6c 64 3b  nField = nField;
8470: 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 67  .    pSorter->pg
8480: 73 7a 20 3d 20 70 67 73 7a 20 3d 20 73 71 6c 69  sz = pgsz = sqli
8490: 74 65 33 42 74 72 65 65 47 65 74 50 61 67 65 53  te3BtreeGetPageS
84a0: 69 7a 65 28 64 62 2d 3e 61 44 62 5b 30 5d 2e 70  ize(db->aDb[0].p
84b0: 42 74 29 3b 0a 20 20 20 20 70 53 6f 72 74 65 72  Bt);.    pSorter
84c0: 2d 3e 6e 54 61 73 6b 20 3d 20 6e 57 6f 72 6b 65  ->nTask = nWorke
84d0: 72 20 2b 20 31 3b 0a 20 20 20 20 70 53 6f 72 74  r + 1;.    pSort
84e0: 65 72 2d 3e 62 55 73 65 54 68 72 65 61 64 73 20  er->bUseThreads 
84f0: 3d 20 28 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73  = (pSorter->nTas
8500: 6b 3e 31 29 3b 0a 20 20 20 20 70 53 6f 72 74 65  k>1);.    pSorte
8510: 72 2d 3e 64 62 20 3d 20 64 62 3b 0a 20 20 20 20  r->db = db;.    
8520: 66 6f 72 28 69 3d 30 3b 20 69 3c 70 53 6f 72 74  for(i=0; i<pSort
8530: 65 72 2d 3e 6e 54 61 73 6b 3b 20 69 2b 2b 29 7b  er->nTask; i++){
8540: 0a 20 20 20 20 20 20 53 6f 72 74 53 75 62 74 61  .      SortSubta
8550: 73 6b 20 2a 70 54 61 73 6b 20 3d 20 26 70 53 6f  sk *pTask = &pSo
8560: 72 74 65 72 2d 3e 61 54 61 73 6b 5b 69 5d 3b 0a  rter->aTask[i];.
8570: 20 20 20 20 20 20 70 54 61 73 6b 2d 3e 70 53 6f        pTask->pSo
8580: 72 74 65 72 20 3d 20 70 53 6f 72 74 65 72 3b 0a  rter = pSorter;.
8590: 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 21      }..    if( !
85a0: 73 71 6c 69 74 65 33 54 65 6d 70 49 6e 4d 65 6d  sqlite3TempInMem
85b0: 6f 72 79 28 64 62 29 20 29 7b 0a 20 20 20 20 20  ory(db) ){.     
85c0: 20 70 53 6f 72 74 65 72 2d 3e 6d 6e 50 6d 61 53   pSorter->mnPmaS
85d0: 69 7a 65 20 3d 20 53 4f 52 54 45 52 5f 4d 49 4e  ize = SORTER_MIN
85e0: 5f 57 4f 52 4b 49 4e 47 20 2a 20 70 67 73 7a 3b  _WORKING * pgsz;
85f0: 0a 20 20 20 20 20 20 6d 78 43 61 63 68 65 20 3d  .      mxCache =
8600: 20 64 62 2d 3e 61 44 62 5b 30 5d 2e 70 53 63 68   db->aDb[0].pSch
8610: 65 6d 61 2d 3e 63 61 63 68 65 5f 73 69 7a 65 3b  ema->cache_size;
8620: 0a 20 20 20 20 20 20 69 66 28 20 6d 78 43 61 63  .      if( mxCac
8630: 68 65 3c 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f  he<SORTER_MIN_WO
8640: 52 4b 49 4e 47 20 29 20 6d 78 43 61 63 68 65 20  RKING ) mxCache 
8650: 3d 20 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52  = SORTER_MIN_WOR
8660: 4b 49 4e 47 3b 0a 20 20 20 20 20 20 70 53 6f 72  KING;.      pSor
8670: 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65 20 3d  ter->mxPmaSize =
8680: 20 6d 78 43 61 63 68 65 20 2a 20 70 67 73 7a 3b   mxCache * pgsz;
8690: 0a 0a 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68  ..      /* If th
86a0: 65 20 61 70 70 6c 69 63 61 74 69 6f 6e 20 69 73  e application is
86b0: 20 75 73 69 6e 67 20 6d 65 6d 73 79 73 33 20 6f   using memsys3 o
86c0: 72 20 6d 65 6d 73 79 73 35 2c 20 75 73 65 20 61  r memsys5, use a
86d0: 20 73 65 70 61 72 61 74 65 20 0a 20 20 20 20 20   separate .     
86e0: 20 2a 2a 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66   ** allocation f
86f0: 6f 72 20 65 61 63 68 20 73 6f 72 74 2d 6b 65 79  or each sort-key
8700: 20 69 6e 20 6d 65 6d 6f 72 79 2e 20 4f 74 68 65   in memory. Othe
8710: 72 77 69 73 65 2c 20 75 73 65 20 61 20 73 69 6e  rwise, use a sin
8720: 67 6c 65 20 62 69 67 0a 20 20 20 20 20 20 2a 2a  gle big.      **
8730: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 61 74 20 70   allocation at p
8740: 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 20  Sorter->aMemory 
8750: 66 6f 72 20 61 6c 6c 20 73 6f 72 74 2d 6b 65 79  for all sort-key
8760: 73 2e 20 20 2a 2f 0a 20 20 20 20 20 20 69 66 28  s.  */.      if(
8770: 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f   sqlite3GlobalCo
8780: 6e 66 69 67 2e 70 48 65 61 70 3d 3d 30 20 29 7b  nfig.pHeap==0 ){
8790: 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28  .        assert(
87a0: 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72   pSorter->iMemor
87b0: 79 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 20 20  y==0 );.        
87c0: 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79  pSorter->nMemory
87d0: 20 3d 20 70 67 73 7a 3b 0a 20 20 20 20 20 20 20   = pgsz;.       
87e0: 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61   pSorter->list.a
87f0: 4d 65 6d 6f 72 79 20 3d 20 28 75 38 2a 29 73 71  Memory = (u8*)sq
8800: 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 70 67 73 7a  lite3Malloc(pgsz
8810: 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 21  );.        if( !
8820: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d  pSorter->list.aM
8830: 65 6d 6f 72 79 20 29 20 72 63 20 3d 20 53 51 4c  emory ) rc = SQL
8840: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
8850: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
8860: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
8870: 0a 2a 2a 20 46 72 65 65 20 74 68 65 20 6c 69 73  .** Free the lis
8880: 74 20 6f 66 20 73 6f 72 74 65 64 20 72 65 63 6f  t of sorted reco
8890: 72 64 73 20 73 74 61 72 74 69 6e 67 20 61 74 20  rds starting at 
88a0: 70 52 65 63 6f 72 64 2e 0a 2a 2f 0a 73 74 61 74  pRecord..*/.stat
88b0: 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74  ic void vdbeSort
88c0: 65 72 52 65 63 6f 72 64 46 72 65 65 28 73 71 6c  erRecordFree(sql
88d0: 69 74 65 33 20 2a 64 62 2c 20 53 6f 72 74 65 72  ite3 *db, Sorter
88e0: 52 65 63 6f 72 64 20 2a 70 52 65 63 6f 72 64 29  Record *pRecord)
88f0: 7b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  {.  SorterRecord
8900: 20 2a 70 3b 0a 20 20 53 6f 72 74 65 72 52 65 63   *p;.  SorterRec
8910: 6f 72 64 20 2a 70 4e 65 78 74 3b 0a 20 20 66 6f  ord *pNext;.  fo
8920: 72 28 70 3d 70 52 65 63 6f 72 64 3b 20 70 3b 20  r(p=pRecord; p; 
8930: 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 4e  p=pNext){.    pN
8940: 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74  ext = p->u.pNext
8950: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 44 62 46  ;.    sqlite3DbF
8960: 72 65 65 28 64 62 2c 20 70 29 3b 0a 20 20 7d 0a  ree(db, p);.  }.
8970: 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6c  }../*.** Free al
8980: 6c 20 72 65 73 6f 75 72 63 65 73 20 6f 77 6e 65  l resources owne
8990: 64 20 62 79 20 74 68 65 20 6f 62 6a 65 63 74 20  d by the object 
89a0: 69 6e 64 69 63 61 74 65 64 20 62 79 20 61 72 67  indicated by arg
89b0: 75 6d 65 6e 74 20 70 54 61 73 6b 2e 20 41 6c 6c  ument pTask. All
89c0: 20 0a 2a 2a 20 66 69 65 6c 64 73 20 6f 66 20 2a   .** fields of *
89d0: 70 54 61 73 6b 20 61 72 65 20 7a 65 72 6f 65 64  pTask are zeroed
89e0: 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e   before returnin
89f0: 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  g..*/.static voi
8a00: 64 20 76 64 62 65 53 6f 72 74 53 75 62 74 61 73  d vdbeSortSubtas
8a10: 6b 43 6c 65 61 6e 75 70 28 73 71 6c 69 74 65 33  kCleanup(sqlite3
8a20: 20 2a 64 62 2c 20 53 6f 72 74 53 75 62 74 61 73   *db, SortSubtas
8a30: 6b 20 2a 70 54 61 73 6b 29 7b 0a 20 20 73 71 6c  k *pTask){.  sql
8a40: 69 74 65 33 44 62 46 72 65 65 28 64 62 2c 20 70  ite3DbFree(db, p
8a50: 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 29  Task->pUnpacked)
8a60: 3b 0a 20 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61  ;.  pTask->pUnpa
8a70: 63 6b 65 64 20 3d 20 30 3b 0a 20 20 69 66 28 20  cked = 0;.  if( 
8a80: 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d  pTask->list.aMem
8a90: 6f 72 79 3d 3d 30 20 29 7b 0a 20 20 20 20 76 64  ory==0 ){.    vd
8aa0: 62 65 53 6f 72 74 65 72 52 65 63 6f 72 64 46 72  beSorterRecordFr
8ab0: 65 65 28 30 2c 20 70 54 61 73 6b 2d 3e 6c 69 73  ee(0, pTask->lis
8ac0: 74 2e 70 4c 69 73 74 29 3b 0a 20 20 7d 65 6c 73  t.pList);.  }els
8ad0: 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  e{.    sqlite3_f
8ae0: 72 65 65 28 70 54 61 73 6b 2d 3e 6c 69 73 74 2e  ree(pTask->list.
8af0: 61 4d 65 6d 6f 72 79 29 3b 0a 20 20 20 20 70 54  aMemory);.    pT
8b00: 61 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72  ask->list.aMemor
8b10: 79 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 70 54 61  y = 0;.  }.  pTa
8b20: 73 6b 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d  sk->list.pList =
8b30: 20 30 3b 0a 20 20 69 66 28 20 70 54 61 73 6b 2d   0;.  if( pTask-
8b40: 3e 66 69 6c 65 2e 70 46 64 20 29 7b 0a 20 20 20  >file.pFd ){.   
8b50: 20 73 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 46   sqlite3OsCloseF
8b60: 72 65 65 28 70 54 61 73 6b 2d 3e 66 69 6c 65 2e  ree(pTask->file.
8b70: 70 46 64 29 3b 0a 20 20 20 20 70 54 61 73 6b 2d  pFd);.    pTask-
8b80: 3e 66 69 6c 65 2e 70 46 64 20 3d 20 30 3b 0a 20  >file.pFd = 0;. 
8b90: 20 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69     pTask->file.i
8ba0: 45 6f 66 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 69  Eof = 0;.  }.  i
8bb0: 66 28 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e  f( pTask->file2.
8bc0: 70 46 64 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  pFd ){.    sqlit
8bd0: 65 33 4f 73 43 6c 6f 73 65 46 72 65 65 28 70 54  e3OsCloseFree(pT
8be0: 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64 29 3b  ask->file2.pFd);
8bf0: 0a 20 20 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65  .    pTask->file
8c00: 32 2e 70 46 64 20 3d 20 30 3b 0a 20 20 20 20 70  2.pFd = 0;.    p
8c10: 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66  Task->file2.iEof
8c20: 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 23 69 66   = 0;.  }.}..#if
8c30: 64 65 66 20 53 51 4c 49 54 45 5f 44 45 42 55 47  def SQLITE_DEBUG
8c40: 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44 53 0a  _SORTER_THREADS.
8c50: 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65  static void vdbe
8c60: 53 6f 72 74 65 72 57 6f 72 6b 44 65 62 75 67 28  SorterWorkDebug(
8c70: 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61  SortSubtask *pTa
8c80: 73 6b 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  sk, const char *
8c90: 7a 45 76 65 6e 74 29 7b 0a 20 20 69 36 34 20 74  zEvent){.  i64 t
8ca0: 3b 0a 20 20 69 6e 74 20 69 54 61 73 6b 20 3d 20  ;.  int iTask = 
8cb0: 28 70 54 61 73 6b 20 2d 20 70 54 61 73 6b 2d 3e  (pTask - pTask->
8cc0: 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 29 3b  pSorter->aTask);
8cd0: 0a 20 20 73 71 6c 69 74 65 33 4f 73 43 75 72 72  .  sqlite3OsCurr
8ce0: 65 6e 74 54 69 6d 65 49 6e 74 36 34 28 70 54 61  entTimeInt64(pTa
8cf0: 73 6b 2d 3e 64 62 2d 3e 70 56 66 73 2c 20 26 74  sk->db->pVfs, &t
8d00: 29 3b 0a 20 20 66 70 72 69 6e 74 66 28 73 74 64  );.  fprintf(std
8d10: 65 72 72 2c 20 22 25 6c 6c 64 3a 25 64 20 25 73  err, "%lld:%d %s
8d20: 5c 6e 22 2c 20 74 2c 20 69 54 61 73 6b 2c 20 7a  \n", t, iTask, z
8d30: 45 76 65 6e 74 29 3b 0a 7d 0a 73 74 61 74 69 63  Event);.}.static
8d40: 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72   void vdbeSorter
8d50: 52 65 77 69 6e 64 44 65 62 75 67 28 73 71 6c 69  RewindDebug(sqli
8d60: 74 65 33 20 2a 64 62 2c 20 63 6f 6e 73 74 20 63  te3 *db, const c
8d70: 68 61 72 20 2a 7a 45 76 65 6e 74 29 7b 0a 20 20  har *zEvent){.  
8d80: 69 36 34 20 74 3b 0a 20 20 73 71 6c 69 74 65 33  i64 t;.  sqlite3
8d90: 4f 73 43 75 72 72 65 6e 74 54 69 6d 65 49 6e 74  OsCurrentTimeInt
8da0: 36 34 28 64 62 2d 3e 70 56 66 73 2c 20 26 74 29  64(db->pVfs, &t)
8db0: 3b 0a 20 20 66 70 72 69 6e 74 66 28 73 74 64 65  ;.  fprintf(stde
8dc0: 72 72 2c 20 22 25 6c 6c 64 3a 58 20 25 73 5c 6e  rr, "%lld:X %s\n
8dd0: 22 2c 20 74 2c 20 7a 45 76 65 6e 74 29 3b 0a 7d  ", t, zEvent);.}
8de0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62  .static void vdb
8df0: 65 53 6f 72 74 65 72 50 6f 70 75 6c 61 74 65 44  eSorterPopulateD
8e00: 65 62 75 67 28 0a 20 20 53 6f 72 74 53 75 62 74  ebug(.  SortSubt
8e10: 61 73 6b 20 2a 70 54 61 73 6b 2c 0a 20 20 63 6f  ask *pTask,.  co
8e20: 6e 73 74 20 63 68 61 72 20 2a 7a 45 76 65 6e 74  nst char *zEvent
8e30: 0a 29 7b 0a 20 20 69 36 34 20 74 3b 0a 20 20 69  .){.  i64 t;.  i
8e40: 6e 74 20 69 54 61 73 6b 20 3d 20 28 70 54 61 73  nt iTask = (pTas
8e50: 6b 20 2d 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74  k - pTask->pSort
8e60: 65 72 2d 3e 61 54 61 73 6b 29 3b 0a 20 20 73 71  er->aTask);.  sq
8e70: 6c 69 74 65 33 4f 73 43 75 72 72 65 6e 74 54 69  lite3OsCurrentTi
8e80: 6d 65 49 6e 74 36 34 28 70 54 61 73 6b 2d 3e 64  meInt64(pTask->d
8e90: 62 2d 3e 70 56 66 73 2c 20 26 74 29 3b 0a 20 20  b->pVfs, &t);.  
8ea0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
8eb0: 22 25 6c 6c 64 3a 62 67 25 64 20 25 73 5c 6e 22  "%lld:bg%d %s\n"
8ec0: 2c 20 74 2c 20 69 54 61 73 6b 2c 20 7a 45 76 65  , t, iTask, zEve
8ed0: 6e 74 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f  nt);.}.static vo
8ee0: 69 64 20 76 64 62 65 53 6f 72 74 65 72 42 6c 6f  id vdbeSorterBlo
8ef0: 63 6b 44 65 62 75 67 28 0a 20 20 53 6f 72 74 53  ckDebug(.  SortS
8f00: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 0a 20  ubtask *pTask,. 
8f10: 20 69 6e 74 20 62 42 6c 6f 63 6b 65 64 2c 0a 20   int bBlocked,. 
8f20: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45 76   const char *zEv
8f30: 65 6e 74 0a 29 7b 0a 20 20 69 66 28 20 62 42 6c  ent.){.  if( bBl
8f40: 6f 63 6b 65 64 20 29 7b 0a 20 20 20 20 69 36 34  ocked ){.    i64
8f50: 20 74 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f   t;.    sqlite3O
8f60: 73 43 75 72 72 65 6e 74 54 69 6d 65 49 6e 74 36  sCurrentTimeInt6
8f70: 34 28 70 54 61 73 6b 2d 3e 64 62 2d 3e 70 56 66  4(pTask->db->pVf
8f80: 73 2c 20 26 74 29 3b 0a 20 20 20 20 66 70 72 69  s, &t);.    fpri
8f90: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25 6c 6c  ntf(stderr, "%ll
8fa0: 64 3a 6d 61 69 6e 20 25 73 5c 6e 22 2c 20 74 2c  d:main %s\n", t,
8fb0: 20 7a 45 76 65 6e 74 29 3b 0a 20 20 7d 0a 7d 0a   zEvent);.  }.}.
8fc0: 23 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 76  #else.# define v
8fd0: 64 62 65 53 6f 72 74 65 72 57 6f 72 6b 44 65 62  dbeSorterWorkDeb
8fe0: 75 67 28 78 2c 79 29 0a 23 20 64 65 66 69 6e 65  ug(x,y).# define
8ff0: 20 76 64 62 65 53 6f 72 74 65 72 52 65 77 69 6e   vdbeSorterRewin
9000: 64 44 65 62 75 67 28 78 2c 79 29 0a 23 20 64 65  dDebug(x,y).# de
9010: 66 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72 50  fine vdbeSorterP
9020: 6f 70 75 6c 61 74 65 44 65 62 75 67 28 78 2c 79  opulateDebug(x,y
9030: 29 0a 23 20 64 65 66 69 6e 65 20 76 64 62 65 53  ).# define vdbeS
9040: 6f 72 74 65 72 42 6c 6f 63 6b 44 65 62 75 67 28  orterBlockDebug(
9050: 78 2c 79 2c 7a 29 0a 23 65 6e 64 69 66 0a 0a 23  x,y,z).#endif..#
9060: 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f  if SQLITE_MAX_WO
9070: 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 0a 2f  RKER_THREADS>0./
9080: 2a 0a 2a 2a 20 4a 6f 69 6e 20 74 68 72 65 61 64  *.** Join thread
9090: 20 70 54 61 73 6b 2d 3e 74 68 72 65 61 64 2e 0a   pTask->thread..
90a0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
90b0: 62 65 53 6f 72 74 65 72 4a 6f 69 6e 54 68 72 65  beSorterJoinThre
90c0: 61 64 28 53 6f 72 74 53 75 62 74 61 73 6b 20 2a  ad(SortSubtask *
90d0: 70 54 61 73 6b 29 7b 0a 20 20 69 6e 74 20 72 63  pTask){.  int rc
90e0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
90f0: 69 66 28 20 70 54 61 73 6b 2d 3e 70 54 68 72 65  if( pTask->pThre
9100: 61 64 20 29 7b 0a 23 69 66 64 65 66 20 53 51 4c  ad ){.#ifdef SQL
9110: 49 54 45 5f 44 45 42 55 47 5f 53 4f 52 54 45 52  ITE_DEBUG_SORTER
9120: 5f 54 48 52 45 41 44 53 0a 20 20 20 20 69 6e 74  _THREADS.    int
9130: 20 62 44 6f 6e 65 20 3d 20 70 54 61 73 6b 2d 3e   bDone = pTask->
9140: 62 44 6f 6e 65 3b 0a 23 65 6e 64 69 66 0a 20 20  bDone;.#endif.  
9150: 20 20 76 6f 69 64 20 2a 70 52 65 74 3b 0a 20 20    void *pRet;.  
9160: 20 20 76 64 62 65 53 6f 72 74 65 72 42 6c 6f 63    vdbeSorterBloc
9170: 6b 44 65 62 75 67 28 70 54 61 73 6b 2c 20 21 62  kDebug(pTask, !b
9180: 44 6f 6e 65 2c 20 22 65 6e 74 65 72 22 29 3b 0a  Done, "enter");.
9190: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
91a0: 54 68 72 65 61 64 4a 6f 69 6e 28 70 54 61 73 6b  ThreadJoin(pTask
91b0: 2d 3e 70 54 68 72 65 61 64 2c 20 26 70 52 65 74  ->pThread, &pRet
91c0: 29 3b 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65  );.    vdbeSorte
91d0: 72 42 6c 6f 63 6b 44 65 62 75 67 28 70 54 61 73  rBlockDebug(pTas
91e0: 6b 2c 20 21 62 44 6f 6e 65 2c 20 22 65 78 69 74  k, !bDone, "exit
91f0: 22 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  ");.    if( rc==
9200: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d  SQLITE_OK ) rc =
9210: 20 53 51 4c 49 54 45 5f 50 54 52 5f 54 4f 5f 49   SQLITE_PTR_TO_I
9220: 4e 54 28 70 52 65 74 29 3b 0a 20 20 20 20 61 73  NT(pRet);.    as
9230: 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 62 44 6f  sert( pTask->bDo
9240: 6e 65 3d 3d 31 20 29 3b 0a 20 20 20 20 70 54 61  ne==1 );.    pTa
9250: 73 6b 2d 3e 62 44 6f 6e 65 20 3d 20 30 3b 0a 20  sk->bDone = 0;. 
9260: 20 20 20 70 54 61 73 6b 2d 3e 70 54 68 72 65 61     pTask->pThrea
9270: 64 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74  d = 0;.  }.  ret
9280: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
9290: 20 4c 61 75 6e 63 68 20 61 20 62 61 63 6b 67 72   Launch a backgr
92a0: 6f 75 6e 64 20 74 68 72 65 61 64 20 74 6f 20 72  ound thread to r
92b0: 75 6e 20 78 54 61 73 6b 28 70 49 6e 29 2e 0a 2a  un xTask(pIn)..*
92c0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
92d0: 65 53 6f 72 74 65 72 43 72 65 61 74 65 54 68 72  eSorterCreateThr
92e0: 65 61 64 28 0a 20 20 53 6f 72 74 53 75 62 74 61  ead(.  SortSubta
92f0: 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20 20 20 20  sk *pTask,      
9300: 20 20 20 20 20 20 20 2f 2a 20 54 68 72 65 61 64         /* Thread
9310: 20 77 69 6c 6c 20 75 73 65 20 74 68 69 73 20 74   will use this t
9320: 61 73 6b 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20  ask object */.  
9330: 76 6f 69 64 20 2a 28 2a 78 54 61 73 6b 29 28 76  void *(*xTask)(v
9340: 6f 69 64 2a 29 2c 20 20 20 20 20 20 20 20 20 20  oid*),          
9350: 2f 2a 20 52 6f 75 74 69 6e 65 20 74 6f 20 72 75  /* Routine to ru
9360: 6e 20 69 6e 20 61 20 73 65 70 61 72 61 74 65 20  n in a separate 
9370: 74 68 72 65 61 64 20 2a 2f 0a 20 20 76 6f 69 64  thread */.  void
9380: 20 2a 70 49 6e 20 20 20 20 20 20 20 20 20 20 20   *pIn           
9390: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41              /* A
93a0: 72 67 75 6d 65 6e 74 20 70 61 73 73 65 64 20 69  rgument passed i
93b0: 6e 74 6f 20 78 54 61 73 6b 28 29 20 2a 2f 0a 29  nto xTask() */.)
93c0: 7b 0a 20 20 61 73 73 65 72 74 28 20 70 54 61 73  {.  assert( pTas
93d0: 6b 2d 3e 70 54 68 72 65 61 64 3d 3d 30 20 26 26  k->pThread==0 &&
93e0: 20 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 3d 3d 30   pTask->bDone==0
93f0: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c   );.  return sql
9400: 69 74 65 33 54 68 72 65 61 64 43 72 65 61 74 65  ite3ThreadCreate
9410: 28 26 70 54 61 73 6b 2d 3e 70 54 68 72 65 61 64  (&pTask->pThread
9420: 2c 20 78 54 61 73 6b 2c 20 70 49 6e 29 3b 0a 7d  , xTask, pIn);.}
9430: 0a 0a 2f 2a 0a 2a 2a 20 4a 6f 69 6e 20 61 6c 6c  ../*.** Join all
9440: 20 6f 75 74 73 74 61 6e 64 69 6e 67 20 74 68 72   outstanding thr
9450: 65 61 64 73 20 6c 61 75 6e 63 68 65 64 20 62 79  eads launched by
9460: 20 53 6f 72 74 65 72 57 72 69 74 65 28 29 20 74   SorterWrite() t
9470: 6f 20 63 72 65 61 74 65 20 0a 2a 2a 20 6c 65 76  o create .** lev
9480: 65 6c 2d 30 20 50 4d 41 73 2e 0a 2a 2f 0a 73 74  el-0 PMAs..*/.st
9490: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
94a0: 74 65 72 4a 6f 69 6e 41 6c 6c 28 56 64 62 65 53  terJoinAll(VdbeS
94b0: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 2c 20  orter *pSorter, 
94c0: 69 6e 74 20 72 63 69 6e 29 7b 0a 20 20 69 6e 74  int rcin){.  int
94d0: 20 72 63 20 3d 20 72 63 69 6e 3b 0a 20 20 69 6e   rc = rcin;.  in
94e0: 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  t i;.  for(i=0; 
94f0: 69 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b  i<pSorter->nTask
9500: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 53 6f 72 74  ; i++){.    Sort
9510: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d  Subtask *pTask =
9520: 20 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b   &pSorter->aTask
9530: 5b 69 5d 3b 0a 20 20 20 20 69 6e 74 20 72 63 32  [i];.    int rc2
9540: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69   = vdbeSorterJoi
9550: 6e 54 68 72 65 61 64 28 70 54 61 73 6b 29 3b 0a  nThread(pTask);.
9560: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
9570: 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63 32  TE_OK ) rc = rc2
9580: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
9590: 63 3b 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65 66  c;.}.#else.# def
95a0: 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72 4a 6f  ine vdbeSorterJo
95b0: 69 6e 41 6c 6c 28 78 2c 72 63 69 6e 29 20 28 72  inAll(x,rcin) (r
95c0: 63 69 6e 29 0a 23 20 64 65 66 69 6e 65 20 76 64  cin).# define vd
95d0: 62 65 53 6f 72 74 65 72 4a 6f 69 6e 54 68 72 65  beSorterJoinThre
95e0: 61 64 28 70 54 61 73 6b 29 20 53 51 4c 49 54 45  ad(pTask) SQLITE
95f0: 5f 4f 4b 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a  _OK.#endif../*.*
9600: 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77  * Allocate a new
9610: 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 6f 62 6a   MergeEngine obj
9620: 65 63 74 20 77 69 74 68 20 73 70 61 63 65 20 66  ect with space f
9630: 6f 72 20 6e 49 74 65 72 20 69 74 65 72 61 74 6f  or nIter iterato
9640: 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 4d 65  rs..*/.static Me
9650: 72 67 65 45 6e 67 69 6e 65 20 2a 76 64 62 65 4d  rgeEngine *vdbeM
9660: 65 72 67 65 45 6e 67 69 6e 65 4e 65 77 28 69 6e  ergeEngineNew(in
9670: 74 20 6e 49 74 65 72 29 7b 0a 20 20 69 6e 74 20  t nIter){.  int 
9680: 4e 20 3d 20 32 3b 20 20 20 20 20 20 20 20 20 20  N = 2;          
9690: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
96a0: 6d 61 6c 6c 65 73 74 20 70 6f 77 65 72 20 6f 66  mallest power of
96b0: 20 74 77 6f 20 3e 3d 20 6e 49 74 65 72 20 2a 2f   two >= nIter */
96c0: 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20  .  int nByte;   
96d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
96e0: 20 20 20 2f 2a 20 54 6f 74 61 6c 20 62 79 74 65     /* Total byte
96f0: 73 20 6f 66 20 73 70 61 63 65 20 74 6f 20 61 6c  s of space to al
9700: 6c 6f 63 61 74 65 20 2a 2f 0a 20 20 4d 65 72 67  locate */.  Merg
9710: 65 45 6e 67 69 6e 65 20 2a 70 4e 65 77 3b 20 20  eEngine *pNew;  
9720: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
9730: 6f 69 6e 74 65 72 20 74 6f 20 61 6c 6c 6f 63 61  ointer to alloca
9740: 74 65 64 20 6f 62 6a 65 63 74 20 74 6f 20 72 65  ted object to re
9750: 74 75 72 6e 20 2a 2f 0a 0a 20 20 61 73 73 65 72  turn */..  asser
9760: 74 28 20 6e 49 74 65 72 3c 3d 53 4f 52 54 45 52  t( nIter<=SORTER
9770: 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
9780: 20 29 3b 0a 0a 20 20 77 68 69 6c 65 28 20 4e 3c   );..  while( N<
9790: 6e 49 74 65 72 20 29 20 4e 20 2b 3d 20 4e 3b 0a  nIter ) N += N;.
97a0: 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66    nByte = sizeof
97b0: 28 4d 65 72 67 65 45 6e 67 69 6e 65 29 20 2b 20  (MergeEngine) + 
97c0: 4e 20 2a 20 28 73 69 7a 65 6f 66 28 69 6e 74 29  N * (sizeof(int)
97d0: 20 2b 20 73 69 7a 65 6f 66 28 50 6d 61 52 65 61   + sizeof(PmaRea
97e0: 64 65 72 29 29 3b 0a 0a 20 20 70 4e 65 77 20 3d  der));..  pNew =
97f0: 20 28 4d 65 72 67 65 45 6e 67 69 6e 65 2a 29 73   (MergeEngine*)s
9800: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f  qlite3MallocZero
9810: 28 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20 70  (nByte);.  if( p
9820: 4e 65 77 20 29 7b 0a 20 20 20 20 70 4e 65 77 2d  New ){.    pNew-
9830: 3e 6e 54 72 65 65 20 3d 20 4e 3b 0a 20 20 20 20  >nTree = N;.    
9840: 70 4e 65 77 2d 3e 61 49 74 65 72 20 3d 20 28 50  pNew->aIter = (P
9850: 6d 61 52 65 61 64 65 72 2a 29 26 70 4e 65 77 5b  maReader*)&pNew[
9860: 31 5d 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 61 54  1];.    pNew->aT
9870: 72 65 65 20 3d 20 28 69 6e 74 2a 29 26 70 4e 65  ree = (int*)&pNe
9880: 77 2d 3e 61 49 74 65 72 5b 4e 5d 3b 0a 20 20 7d  w->aIter[N];.  }
9890: 0a 20 20 72 65 74 75 72 6e 20 70 4e 65 77 3b 0a  .  return pNew;.
98a0: 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 74 68  }../*.** Free th
98b0: 65 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 6f 62  e MergeEngine ob
98c0: 6a 65 63 74 20 70 61 73 73 65 64 20 61 73 20 74  ject passed as t
98d0: 68 65 20 6f 6e 6c 79 20 61 72 67 75 6d 65 6e 74  he only argument
98e0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
98f0: 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65   vdbeMergeEngine
9900: 46 72 65 65 28 4d 65 72 67 65 45 6e 67 69 6e 65  Free(MergeEngine
9910: 20 2a 70 4d 65 72 67 65 72 29 7b 0a 20 20 69 6e   *pMerger){.  in
9920: 74 20 69 3b 0a 20 20 69 66 28 20 70 4d 65 72 67  t i;.  if( pMerg
9930: 65 72 20 29 7b 0a 20 20 20 20 66 6f 72 28 69 3d  er ){.    for(i=
9940: 30 3b 20 69 3c 70 4d 65 72 67 65 72 2d 3e 6e 54  0; i<pMerger->nT
9950: 72 65 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  ree; i++){.     
9960: 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 43 6c   vdbePmaReaderCl
9970: 65 61 72 28 26 70 4d 65 72 67 65 72 2d 3e 61 49  ear(&pMerger->aI
9980: 74 65 72 5b 69 5d 29 3b 0a 20 20 20 20 7d 0a 20  ter[i]);.    }. 
9990: 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65   }.  sqlite3_fre
99a0: 65 28 70 4d 65 72 67 65 72 29 3b 0a 7d 0a 0a 2f  e(pMerger);.}../
99b0: 2a 0a 2a 2a 20 46 72 65 65 20 61 6c 6c 20 72 65  *.** Free all re
99c0: 73 6f 75 72 63 65 73 20 61 73 73 6f 63 69 61 74  sources associat
99d0: 65 64 20 77 69 74 68 20 74 68 65 20 49 6e 63 72  ed with the Incr
99e0: 4d 65 72 67 65 72 20 6f 62 6a 65 63 74 20 69 6e  Merger object in
99f0: 64 69 63 61 74 65 64 20 62 79 0a 2a 2a 20 74 68  dicated by.** th
9a00: 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
9a10: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
9a20: 20 76 64 62 65 49 6e 63 72 46 72 65 65 28 49 6e   vdbeIncrFree(In
9a30: 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 29  crMerger *pIncr)
9a40: 7b 0a 20 20 69 66 28 20 70 49 6e 63 72 20 29 7b  {.  if( pIncr ){
9a50: 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f  .#if SQLITE_MAX_
9a60: 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30  WORKER_THREADS>0
9a70: 0a 20 20 20 20 69 66 28 20 70 49 6e 63 72 2d 3e  .    if( pIncr->
9a80: 62 55 73 65 54 68 72 65 61 64 20 29 7b 0a 20 20  bUseThread ){.  
9a90: 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 4a 6f      vdbeSorterJo
9aa0: 69 6e 54 68 72 65 61 64 28 70 49 6e 63 72 2d 3e  inThread(pIncr->
9ab0: 70 54 61 73 6b 29 3b 0a 20 20 20 20 20 20 69 66  pTask);.      if
9ac0: 28 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30  ( pIncr->aFile[0
9ad0: 5d 2e 70 46 64 20 29 20 73 71 6c 69 74 65 33 4f  ].pFd ) sqlite3O
9ae0: 73 43 6c 6f 73 65 46 72 65 65 28 70 49 6e 63 72  sCloseFree(pIncr
9af0: 2d 3e 61 46 69 6c 65 5b 30 5d 2e 70 46 64 29 3b  ->aFile[0].pFd);
9b00: 0a 20 20 20 20 20 20 69 66 28 20 70 49 6e 63 72  .      if( pIncr
9b10: 2d 3e 61 46 69 6c 65 5b 31 5d 2e 70 46 64 20 29  ->aFile[1].pFd )
9b20: 20 73 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 46   sqlite3OsCloseF
9b30: 72 65 65 28 70 49 6e 63 72 2d 3e 61 46 69 6c 65  ree(pIncr->aFile
9b40: 5b 31 5d 2e 70 46 64 29 3b 0a 20 20 20 20 7d 0a  [1].pFd);.    }.
9b50: 23 65 6e 64 69 66 0a 20 20 20 20 76 64 62 65 4d  #endif.    vdbeM
9b60: 65 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28 70  ergeEngineFree(p
9b70: 49 6e 63 72 2d 3e 70 4d 65 72 67 65 72 29 3b 0a  Incr->pMerger);.
9b80: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
9b90: 28 70 49 6e 63 72 29 3b 0a 20 20 7d 0a 7d 0a 0a  (pIncr);.  }.}..
9ba0: 2f 2a 0a 2a 2a 20 52 65 73 65 74 20 61 20 73 6f  /*.** Reset a so
9bb0: 72 74 69 6e 67 20 63 75 72 73 6f 72 20 62 61 63  rting cursor bac
9bc0: 6b 20 74 6f 20 69 74 73 20 6f 72 69 67 69 6e 61  k to its origina
9bd0: 6c 20 65 6d 70 74 79 20 73 74 61 74 65 2e 0a 2a  l empty state..*
9be0: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 56 64  /.void sqlite3Vd
9bf0: 62 65 53 6f 72 74 65 72 52 65 73 65 74 28 73 71  beSorterReset(sq
9c00: 6c 69 74 65 33 20 2a 64 62 2c 20 56 64 62 65 53  lite3 *db, VdbeS
9c10: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 29 7b  orter *pSorter){
9c20: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 28 76 6f 69  .  int i;.  (voi
9c30: 64 29 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e  d)vdbeSorterJoin
9c40: 41 6c 6c 28 70 53 6f 72 74 65 72 2c 20 53 51 4c  All(pSorter, SQL
9c50: 49 54 45 5f 4f 4b 29 3b 0a 20 20 69 66 28 20 70  ITE_OK);.  if( p
9c60: 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72 20  Sorter->pReader 
9c70: 29 7b 0a 20 20 20 20 76 64 62 65 50 6d 61 52 65  ){.    vdbePmaRe
9c80: 61 64 65 72 43 6c 65 61 72 28 70 53 6f 72 74 65  aderClear(pSorte
9c90: 72 2d 3e 70 52 65 61 64 65 72 29 3b 0a 20 20 20  r->pReader);.   
9ca0: 20 73 71 6c 69 74 65 33 44 62 46 72 65 65 28 64   sqlite3DbFree(d
9cb0: 62 2c 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 61  b, pSorter->pRea
9cc0: 64 65 72 29 3b 0a 20 20 20 20 70 53 6f 72 74 65  der);.    pSorte
9cd0: 72 2d 3e 70 52 65 61 64 65 72 20 3d 20 30 3b 0a  r->pReader = 0;.
9ce0: 20 20 7d 0a 20 20 76 64 62 65 4d 65 72 67 65 45    }.  vdbeMergeE
9cf0: 6e 67 69 6e 65 46 72 65 65 28 70 53 6f 72 74 65  ngineFree(pSorte
9d00: 72 2d 3e 70 4d 65 72 67 65 72 29 3b 0a 20 20 70  r->pMerger);.  p
9d10: 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 20  Sorter->pMerger 
9d20: 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  = 0;.  for(i=0; 
9d30: 69 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b  i<pSorter->nTask
9d40: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 53 6f 72 74  ; i++){.    Sort
9d50: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d  Subtask *pTask =
9d60: 20 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b   &pSorter->aTask
9d70: 5b 69 5d 3b 0a 20 20 20 20 76 64 62 65 53 6f 72  [i];.    vdbeSor
9d80: 74 53 75 62 74 61 73 6b 43 6c 65 61 6e 75 70 28  tSubtaskCleanup(
9d90: 64 62 2c 20 70 54 61 73 6b 29 3b 0a 20 20 7d 0a  db, pTask);.  }.
9da0: 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6c    if( pSorter->l
9db0: 69 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30 20 29  ist.aMemory==0 )
9dc0: 7b 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65 72  {.    vdbeSorter
9dd0: 52 65 63 6f 72 64 46 72 65 65 28 30 2c 20 70 53  RecordFree(0, pS
9de0: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73  orter->list.pLis
9df0: 74 29 3b 0a 20 20 7d 0a 20 20 70 53 6f 72 74 65  t);.  }.  pSorte
9e00: 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d 20  r->list.pList = 
9e10: 30 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69  0;.  pSorter->li
9e20: 73 74 2e 73 7a 50 4d 41 20 3d 20 30 3b 0a 20 20  st.szPMA = 0;.  
9e30: 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41  pSorter->bUsePMA
9e40: 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74 65 72 2d   = 0;.  pSorter-
9e50: 3e 69 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a 20 20  >iMemory = 0;.  
9e60: 70 53 6f 72 74 65 72 2d 3e 6d 78 4b 65 79 73 69  pSorter->mxKeysi
9e70: 7a 65 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65  ze = 0;.  sqlite
9e80: 33 44 62 46 72 65 65 28 64 62 2c 20 70 53 6f 72  3DbFree(db, pSor
9e90: 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64 29 3b  ter->pUnpacked);
9ea0: 0a 20 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70  .  pSorter->pUnp
9eb0: 61 63 6b 65 64 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a  acked = 0;.}../*
9ec0: 0a 2a 2a 20 46 72 65 65 20 61 6e 79 20 63 75 72  .** Free any cur
9ed0: 73 6f 72 20 63 6f 6d 70 6f 6e 65 6e 74 73 20 61  sor components a
9ee0: 6c 6c 6f 63 61 74 65 64 20 62 79 20 73 71 6c 69  llocated by sqli
9ef0: 74 65 33 56 64 62 65 53 6f 72 74 65 72 58 58 58  te3VdbeSorterXXX
9f00: 20 72 6f 75 74 69 6e 65 73 2e 0a 2a 2f 0a 76 6f   routines..*/.vo
9f10: 69 64 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f  id sqlite3VdbeSo
9f20: 72 74 65 72 43 6c 6f 73 65 28 73 71 6c 69 74 65  rterClose(sqlite
9f30: 33 20 2a 64 62 2c 20 56 64 62 65 43 75 72 73 6f  3 *db, VdbeCurso
9f40: 72 20 2a 70 43 73 72 29 7b 0a 20 20 56 64 62 65  r *pCsr){.  Vdbe
9f50: 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20  Sorter *pSorter 
9f60: 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b  = pCsr->pSorter;
9f70: 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72 20 29  .  if( pSorter )
9f80: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 56 64 62  {.    sqlite3Vdb
9f90: 65 53 6f 72 74 65 72 52 65 73 65 74 28 64 62 2c  eSorterReset(db,
9fa0: 20 70 53 6f 72 74 65 72 29 3b 0a 20 20 20 20 73   pSorter);.    s
9fb0: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 53 6f 72  qlite3_free(pSor
9fc0: 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72  ter->list.aMemor
9fd0: 79 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 44  y);.    sqlite3D
9fe0: 62 46 72 65 65 28 64 62 2c 20 70 53 6f 72 74 65  bFree(db, pSorte
9ff0: 72 29 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70 53  r);.    pCsr->pS
a000: 6f 72 74 65 72 20 3d 20 30 3b 0a 20 20 7d 0a 7d  orter = 0;.  }.}
a010: 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65  ../*.** Allocate
a020: 20 73 70 61 63 65 20 66 6f 72 20 61 20 66 69 6c   space for a fil
a030: 65 2d 68 61 6e 64 6c 65 20 61 6e 64 20 6f 70 65  e-handle and ope
a040: 6e 20 61 20 74 65 6d 70 6f 72 61 72 79 20 66 69  n a temporary fi
a050: 6c 65 2e 20 49 66 20 73 75 63 63 65 73 73 66 75  le. If successfu
a060: 6c 2c 0a 2a 2a 20 73 65 74 20 2a 70 70 46 69 6c  l,.** set *ppFil
a070: 65 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68  e to point to th
a080: 65 20 6d 61 6c 6c 6f 63 27 64 20 66 69 6c 65 2d  e malloc'd file-
a090: 68 61 6e 64 6c 65 20 61 6e 64 20 72 65 74 75 72  handle and retur
a0a0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2a 20  n SQLITE_OK..** 
a0b0: 4f 74 68 65 72 77 69 73 65 2c 20 73 65 74 20 2a  Otherwise, set *
a0c0: 70 70 46 69 6c 65 20 74 6f 20 30 20 61 6e 64 20  ppFile to 0 and 
a0d0: 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74 65  return an SQLite
a0e0: 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2f 0a   error code..*/.
a0f0: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53  static int vdbeS
a100: 6f 72 74 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c  orterOpenTempFil
a110: 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70  e(sqlite3_vfs *p
a120: 56 66 73 2c 20 73 71 6c 69 74 65 33 5f 66 69 6c  Vfs, sqlite3_fil
a130: 65 20 2a 2a 70 70 46 69 6c 65 29 7b 0a 20 20 69  e **ppFile){.  i
a140: 6e 74 20 72 63 3b 0a 20 20 72 63 20 3d 20 73 71  nt rc;.  rc = sq
a150: 6c 69 74 65 33 4f 73 4f 70 65 6e 4d 61 6c 6c 6f  lite3OsOpenMallo
a160: 63 28 70 56 66 73 2c 20 30 2c 20 70 70 46 69 6c  c(pVfs, 0, ppFil
a170: 65 2c 0a 20 20 20 20 20 20 53 51 4c 49 54 45 5f  e,.      SQLITE_
a180: 4f 50 45 4e 5f 54 45 4d 50 5f 4a 4f 55 52 4e 41  OPEN_TEMP_JOURNA
a190: 4c 20 7c 0a 20 20 20 20 20 20 53 51 4c 49 54 45  L |.      SQLITE
a1a0: 5f 4f 50 45 4e 5f 52 45 41 44 57 52 49 54 45 20  _OPEN_READWRITE 
a1b0: 20 20 20 7c 20 53 51 4c 49 54 45 5f 4f 50 45 4e     | SQLITE_OPEN
a1c0: 5f 43 52 45 41 54 45 20 7c 0a 20 20 20 20 20 20  _CREATE |.      
a1d0: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 45 58 43 4c  SQLITE_OPEN_EXCL
a1e0: 55 53 49 56 45 20 20 20 20 7c 20 53 51 4c 49 54  USIVE    | SQLIT
a1f0: 45 5f 4f 50 45 4e 5f 44 45 4c 45 54 45 4f 4e 43  E_OPEN_DELETEONC
a200: 4c 4f 53 45 2c 20 26 72 63 0a 20 20 29 3b 0a 20  LOSE, &rc.  );. 
a210: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
a220: 4f 4b 20 29 7b 0a 20 20 20 20 69 36 34 20 6d 61  OK ){.    i64 ma
a230: 78 20 3d 20 53 51 4c 49 54 45 5f 4d 41 58 5f 4d  x = SQLITE_MAX_M
a240: 4d 41 50 5f 53 49 5a 45 3b 0a 20 20 20 20 73 71  MAP_SIZE;.    sq
a250: 6c 69 74 65 33 4f 73 46 69 6c 65 43 6f 6e 74 72  lite3OsFileContr
a260: 6f 6c 48 69 6e 74 28 20 2a 70 70 46 69 6c 65 2c  olHint( *ppFile,
a270: 20 53 51 4c 49 54 45 5f 46 43 4e 54 4c 5f 4d 4d   SQLITE_FCNTL_MM
a280: 41 50 5f 53 49 5a 45 2c 20 28 76 6f 69 64 2a 29  AP_SIZE, (void*)
a290: 26 6d 61 78 29 3b 0a 20 20 7d 0a 20 20 72 65 74  &max);.  }.  ret
a2a0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
a2b0: 20 49 66 20 69 74 20 68 61 73 20 6e 6f 74 20 61   If it has not a
a2c0: 6c 72 65 61 64 79 20 62 65 65 6e 20 61 6c 6c 6f  lready been allo
a2d0: 63 61 74 65 64 2c 20 61 6c 6c 6f 63 61 74 65 20  cated, allocate 
a2e0: 74 68 65 20 55 6e 70 61 63 6b 65 64 52 65 63 6f  the UnpackedReco
a2f0: 72 64 20 0a 2a 2a 20 73 74 72 75 63 74 75 72 65  rd .** structure
a300: 20 61 74 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61   at pTask->pUnpa
a310: 63 6b 65 64 2e 20 52 65 74 75 72 6e 20 53 51 4c  cked. Return SQL
a320: 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73  ITE_OK if succes
a330: 73 66 75 6c 20 28 6f 72 20 0a 2a 2a 20 69 66 20  sful (or .** if 
a340: 6e 6f 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 77 61  no allocation wa
a350: 73 20 72 65 71 75 69 72 65 64 29 2c 20 6f 72 20  s required), or 
a360: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 6f 74 68  SQLITE_NOMEM oth
a370: 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69  erwise..*/.stati
a380: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 41 6c  c int vdbeSortAl
a390: 6c 6f 63 55 6e 70 61 63 6b 65 64 28 53 6f 72 74  locUnpacked(Sort
a3a0: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 29 7b  Subtask *pTask){
a3b0: 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 70 55  .  if( pTask->pU
a3c0: 6e 70 61 63 6b 65 64 3d 3d 30 20 29 7b 0a 20 20  npacked==0 ){.  
a3d0: 20 20 63 68 61 72 20 2a 70 46 72 65 65 3b 0a 20    char *pFree;. 
a3e0: 20 20 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63     pTask->pUnpac
a3f0: 6b 65 64 20 3d 20 73 71 6c 69 74 65 33 56 64 62  ked = sqlite3Vdb
a400: 65 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64 52 65  eAllocUnpackedRe
a410: 63 6f 72 64 28 0a 20 20 20 20 20 20 20 20 70 54  cord(.        pT
a420: 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 4b  ask->pSorter->pK
a430: 65 79 49 6e 66 6f 2c 20 30 2c 20 30 2c 20 26 70  eyInfo, 0, 0, &p
a440: 46 72 65 65 0a 20 20 20 20 29 3b 0a 20 20 20 20  Free.    );.    
a450: 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 70  assert( pTask->p
a460: 55 6e 70 61 63 6b 65 64 3d 3d 28 55 6e 70 61 63  Unpacked==(Unpac
a470: 6b 65 64 52 65 63 6f 72 64 2a 29 70 46 72 65 65  kedRecord*)pFree
a480: 20 29 3b 0a 20 20 20 20 69 66 28 20 70 46 72 65   );.    if( pFre
a490: 65 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  e==0 ) return SQ
a4a0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
a4b0: 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64  pTask->pUnpacked
a4c0: 2d 3e 6e 46 69 65 6c 64 20 3d 20 70 54 61 73 6b  ->nField = pTask
a4d0: 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49  ->pSorter->pKeyI
a4e0: 6e 66 6f 2d 3e 6e 46 69 65 6c 64 3b 0a 20 20 20  nfo->nField;.   
a4f0: 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65   pTask->pUnpacke
a500: 64 2d 3e 65 72 72 43 6f 64 65 20 3d 20 30 3b 0a  d->errCode = 0;.
a510: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c    }.  return SQL
a520: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  ITE_OK;.}.../*.*
a530: 2a 20 4d 65 72 67 65 20 74 68 65 20 74 77 6f 20  * Merge the two 
a540: 73 6f 72 74 65 64 20 6c 69 73 74 73 20 70 31 20  sorted lists p1 
a550: 61 6e 64 20 70 32 20 69 6e 74 6f 20 61 20 73 69  and p2 into a si
a560: 6e 67 6c 65 20 6c 69 73 74 2e 0a 2a 2a 20 53 65  ngle list..** Se
a570: 74 20 2a 70 70 4f 75 74 20 74 6f 20 74 68 65 20  t *ppOut to the 
a580: 68 65 61 64 20 6f 66 20 74 68 65 20 6e 65 77 20  head of the new 
a590: 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  list..*/.static 
a5a0: 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72 4d  void vdbeSorterM
a5b0: 65 72 67 65 28 0a 20 20 53 6f 72 74 53 75 62 74  erge(.  SortSubt
a5c0: 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20 20 20  ask *pTask,     
a5d0: 20 20 20 20 20 20 20 20 2f 2a 20 43 61 6c 6c 69          /* Calli
a5e0: 6e 67 20 74 68 72 65 61 64 20 63 6f 6e 74 65 78  ng thread contex
a5f0: 74 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63  t */.  SorterRec
a600: 6f 72 64 20 2a 70 31 2c 20 20 20 20 20 20 20 20  ord *p1,        
a610: 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20         /* First 
a620: 6c 69 73 74 20 74 6f 20 6d 65 72 67 65 20 2a 2f  list to merge */
a630: 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20  .  SorterRecord 
a640: 2a 70 32 2c 20 20 20 20 20 20 20 20 20 20 20 20  *p2,            
a650: 20 20 20 2f 2a 20 53 65 63 6f 6e 64 20 6c 69 73     /* Second lis
a660: 74 20 74 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20  t to merge */.  
a670: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 2a 70  SorterRecord **p
a680: 70 4f 75 74 20 20 20 20 20 20 20 20 20 20 20 20  pOut            
a690: 2f 2a 20 4f 55 54 3a 20 48 65 61 64 20 6f 66 20  /* OUT: Head of 
a6a0: 6d 65 72 67 65 64 20 6c 69 73 74 20 2a 2f 0a 29  merged list */.)
a6b0: 7b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  {.  SorterRecord
a6c0: 20 2a 70 46 69 6e 61 6c 20 3d 20 30 3b 0a 20 20   *pFinal = 0;.  
a6d0: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 2a 70  SorterRecord **p
a6e0: 70 20 3d 20 26 70 46 69 6e 61 6c 3b 0a 20 20 76  p = &pFinal;.  v
a6f0: 6f 69 64 20 2a 70 56 61 6c 32 20 3d 20 70 32 20  oid *pVal2 = p2 
a700: 3f 20 53 52 56 41 4c 28 70 32 29 20 3a 20 30 3b  ? SRVAL(p2) : 0;
a710: 0a 0a 20 20 77 68 69 6c 65 28 20 70 31 20 26 26  ..  while( p1 &&
a720: 20 70 32 20 29 7b 0a 20 20 20 20 69 6e 74 20 72   p2 ){.    int r
a730: 65 73 3b 0a 20 20 20 20 72 65 73 20 3d 20 76 64  es;.    res = vd
a740: 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28  beSorterCompare(
a750: 70 54 61 73 6b 2c 20 53 52 56 41 4c 28 70 31 29  pTask, SRVAL(p1)
a760: 2c 20 70 31 2d 3e 6e 56 61 6c 2c 20 70 56 61 6c  , p1->nVal, pVal
a770: 32 2c 20 70 32 2d 3e 6e 56 61 6c 29 3b 0a 20 20  2, p2->nVal);.  
a780: 20 20 69 66 28 20 72 65 73 3c 3d 30 20 29 7b 0a    if( res<=0 ){.
a790: 20 20 20 20 20 20 2a 70 70 20 3d 20 70 31 3b 0a        *pp = p1;.
a7a0: 20 20 20 20 20 20 70 70 20 3d 20 26 70 31 2d 3e        pp = &p1->
a7b0: 75 2e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70  u.pNext;.      p
a7c0: 31 20 3d 20 70 31 2d 3e 75 2e 70 4e 65 78 74 3b  1 = p1->u.pNext;
a7d0: 0a 20 20 20 20 20 20 70 56 61 6c 32 20 3d 20 30  .      pVal2 = 0
a7e0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
a7f0: 20 20 20 2a 70 70 20 3d 20 70 32 3b 0a 20 20 20     *pp = p2;.   
a800: 20 20 20 20 70 70 20 3d 20 26 70 32 2d 3e 75 2e      pp = &p2->u.
a810: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 32 20  pNext;.      p2 
a820: 3d 20 70 32 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20  = p2->u.pNext;. 
a830: 20 20 20 20 20 69 66 28 20 70 32 3d 3d 30 20 29       if( p2==0 )
a840: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 70 56   break;.      pV
a850: 61 6c 32 20 3d 20 53 52 56 41 4c 28 70 32 29 3b  al2 = SRVAL(p2);
a860: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 70  .    }.  }.  *pp
a870: 20 3d 20 70 31 20 3f 20 70 31 20 3a 20 70 32 3b   = p1 ? p1 : p2;
a880: 0a 20 20 2a 70 70 4f 75 74 20 3d 20 70 46 69 6e  .  *ppOut = pFin
a890: 61 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72  al;.}../*.** Sor
a8a0: 74 20 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73  t the linked lis
a8b0: 74 20 6f 66 20 72 65 63 6f 72 64 73 20 68 65 61  t of records hea
a8c0: 64 65 64 20 61 74 20 70 54 61 73 6b 2d 3e 70 4c  ded at pTask->pL
a8d0: 69 73 74 2e 20 52 65 74 75 72 6e 20 0a 2a 2a 20  ist. Return .** 
a8e0: 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63  SQLITE_OK if suc
a8f0: 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53  cessful, or an S
a900: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
a910: 20 28 69 2e 65 2e 20 53 51 4c 49 54 45 5f 4e 4f   (i.e. SQLITE_NO
a920: 4d 45 4d 29 20 69 66 20 0a 2a 2a 20 61 6e 20 65  MEM) if .** an e
a930: 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a  rror occurs..*/.
a940: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53  static int vdbeS
a950: 6f 72 74 65 72 53 6f 72 74 28 53 6f 72 74 53 75  orterSort(SortSu
a960: 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 53 6f  btask *pTask, So
a970: 72 74 65 72 4c 69 73 74 20 2a 70 4c 69 73 74 29  rterList *pList)
a980: 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 53 6f 72  {.  int i;.  Sor
a990: 74 65 72 52 65 63 6f 72 64 20 2a 2a 61 53 6c 6f  terRecord **aSlo
a9a0: 74 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72  t;.  SorterRecor
a9b0: 64 20 2a 70 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  d *p;.  int rc;.
a9c0: 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74  .  rc = vdbeSort
a9d0: 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64 28 70 54  AllocUnpacked(pT
a9e0: 61 73 6b 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  ask);.  if( rc!=
a9f0: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
aa00: 72 6e 20 72 63 3b 0a 0a 20 20 61 53 6c 6f 74 20  rn rc;..  aSlot 
aa10: 3d 20 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20  = (SorterRecord 
aa20: 2a 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  **)sqlite3Malloc
aa30: 5a 65 72 6f 28 36 34 20 2a 20 73 69 7a 65 6f 66  Zero(64 * sizeof
aa40: 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 29  (SorterRecord *)
aa50: 29 3b 0a 20 20 69 66 28 20 21 61 53 6c 6f 74 20  );.  if( !aSlot 
aa60: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
aa70: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a  LITE_NOMEM;.  }.
aa80: 0a 20 20 70 20 3d 20 70 4c 69 73 74 2d 3e 70 4c  .  p = pList->pL
aa90: 69 73 74 3b 0a 20 20 77 68 69 6c 65 28 20 70 20  ist;.  while( p 
aaa0: 29 7b 0a 20 20 20 20 53 6f 72 74 65 72 52 65 63  ){.    SorterRec
aab0: 6f 72 64 20 2a 70 4e 65 78 74 3b 0a 20 20 20 20  ord *pNext;.    
aac0: 69 66 28 20 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f  if( pList->aMemo
aad0: 72 79 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  ry ){.      if( 
aae0: 28 75 38 2a 29 70 3d 3d 70 4c 69 73 74 2d 3e 61  (u8*)p==pList->a
aaf0: 4d 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20 20  Memory ){.      
ab00: 20 20 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20    pNext = 0;.   
ab10: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
ab20: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 75 2e 69    assert( p->u.i
ab30: 4e 65 78 74 3c 73 71 6c 69 74 65 33 4d 61 6c 6c  Next<sqlite3Mall
ab40: 6f 63 53 69 7a 65 28 70 4c 69 73 74 2d 3e 61 4d  ocSize(pList->aM
ab50: 65 6d 6f 72 79 29 20 29 3b 0a 20 20 20 20 20 20  emory) );.      
ab60: 20 20 70 4e 65 78 74 20 3d 20 28 53 6f 72 74 65    pNext = (Sorte
ab70: 72 52 65 63 6f 72 64 2a 29 26 70 4c 69 73 74 2d  rRecord*)&pList-
ab80: 3e 61 4d 65 6d 6f 72 79 5b 70 2d 3e 75 2e 69 4e  >aMemory[p->u.iN
ab90: 65 78 74 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20  ext];.      }.  
aba0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70    }else{.      p
abb0: 4e 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78  Next = p->u.pNex
abc0: 74 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 2d  t;.    }..    p-
abd0: 3e 75 2e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20  >u.pNext = 0;.  
abe0: 20 20 66 6f 72 28 69 3d 30 3b 20 61 53 6c 6f 74    for(i=0; aSlot
abf0: 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  [i]; i++){.     
ac00: 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65   vdbeSorterMerge
ac10: 28 70 54 61 73 6b 2c 20 70 2c 20 61 53 6c 6f 74  (pTask, p, aSlot
ac20: 5b 69 5d 2c 20 26 70 29 3b 0a 20 20 20 20 20 20  [i], &p);.      
ac30: 61 53 6c 6f 74 5b 69 5d 20 3d 20 30 3b 0a 20 20  aSlot[i] = 0;.  
ac40: 20 20 7d 0a 20 20 20 20 61 53 6c 6f 74 5b 69 5d    }.    aSlot[i]
ac50: 20 3d 20 70 3b 0a 20 20 20 20 70 20 3d 20 70 4e   = p;.    p = pN
ac60: 65 78 74 3b 0a 20 20 7d 0a 0a 20 20 70 20 3d 20  ext;.  }..  p = 
ac70: 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  0;.  for(i=0; i<
ac80: 36 34 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 76 64  64; i++){.    vd
ac90: 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28 70 54  beSorterMerge(pT
aca0: 61 73 6b 2c 20 70 2c 20 61 53 6c 6f 74 5b 69 5d  ask, p, aSlot[i]
acb0: 2c 20 26 70 29 3b 0a 20 20 7d 0a 20 20 70 4c 69  , &p);.  }.  pLi
acc0: 73 74 2d 3e 70 4c 69 73 74 20 3d 20 70 3b 0a 0a  st->pList = p;..
acd0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61    sqlite3_free(a
ace0: 53 6c 6f 74 29 3b 0a 20 20 69 66 28 20 70 54 61  Slot);.  if( pTa
acf0: 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 2d 3e 65  sk->pUnpacked->e
ad00: 72 72 43 6f 64 65 20 29 7b 0a 20 20 20 20 61 73  rrCode ){.    as
ad10: 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 70 55 6e  sert( pTask->pUn
ad20: 70 61 63 6b 65 64 2d 3e 65 72 72 43 6f 64 65 3d  packed->errCode=
ad30: 3d 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 29 3b  =SQLITE_NOMEM );
ad40: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
ad50: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20  TE_NOMEM;.  }.  
ad60: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
ad70: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69  ;.}../*.** Initi
ad80: 61 6c 69 7a 65 20 61 20 50 4d 41 2d 77 72 69 74  alize a PMA-writ
ad90: 65 72 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74  er object..*/.st
ada0: 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 50 6d  atic void vdbePm
adb0: 61 57 72 69 74 65 72 49 6e 69 74 28 0a 20 20 73  aWriterInit(.  s
adc0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
add0: 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  le,            /
ade0: 2a 20 46 69 6c 65 20 74 6f 20 77 72 69 74 65 20  * File to write 
adf0: 74 6f 20 2a 2f 0a 20 20 50 6d 61 57 72 69 74 65  to */.  PmaWrite
ae00: 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20  r *p,           
ae10: 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63          /* Objec
ae20: 74 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f  t to populate */
ae30: 0a 20 20 69 6e 74 20 6e 42 75 66 2c 20 20 20 20  .  int nBuf,    
ae40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ae50: 20 20 20 2f 2a 20 42 75 66 66 65 72 20 73 69 7a     /* Buffer siz
ae60: 65 20 2a 2f 0a 20 20 69 36 34 20 69 53 74 61 72  e */.  i64 iStar
ae70: 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t               
ae80: 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74         /* Offset
ae90: 20 6f 66 20 70 46 69 6c 65 20 74 6f 20 62 65 67   of pFile to beg
aea0: 69 6e 20 77 72 69 74 69 6e 67 20 61 74 20 2a 2f  in writing at */
aeb0: 0a 29 7b 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20  .){.  memset(p, 
aec0: 30 2c 20 73 69 7a 65 6f 66 28 50 6d 61 57 72 69  0, sizeof(PmaWri
aed0: 74 65 72 29 29 3b 0a 20 20 70 2d 3e 61 42 75 66  ter));.  p->aBuf
aee0: 66 65 72 20 3d 20 28 75 38 2a 29 73 71 6c 69 74  fer = (u8*)sqlit
aef0: 65 33 4d 61 6c 6c 6f 63 28 6e 42 75 66 29 3b 0a  e3Malloc(nBuf);.
af00: 20 20 69 66 28 20 21 70 2d 3e 61 42 75 66 66 65    if( !p->aBuffe
af10: 72 20 29 7b 0a 20 20 20 20 70 2d 3e 65 46 57 45  r ){.    p->eFWE
af20: 72 72 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rr = SQLITE_NOME
af30: 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  M;.  }else{.    
af40: 70 2d 3e 69 42 75 66 45 6e 64 20 3d 20 70 2d 3e  p->iBufEnd = p->
af50: 69 42 75 66 53 74 61 72 74 20 3d 20 28 69 53 74  iBufStart = (iSt
af60: 61 72 74 20 25 20 6e 42 75 66 29 3b 0a 20 20 20  art % nBuf);.   
af70: 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20 3d 20   p->iWriteOff = 
af80: 69 53 74 61 72 74 20 2d 20 70 2d 3e 69 42 75 66  iStart - p->iBuf
af90: 53 74 61 72 74 3b 0a 20 20 20 20 70 2d 3e 6e 42  Start;.    p->nB
afa0: 75 66 66 65 72 20 3d 20 6e 42 75 66 3b 0a 20 20  uffer = nBuf;.  
afb0: 20 20 70 2d 3e 70 46 69 6c 65 20 3d 20 70 46 69    p->pFile = pFi
afc0: 6c 65 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  le;.  }.}../*.**
afd0: 20 57 72 69 74 65 20 6e 44 61 74 61 20 62 79 74   Write nData byt
afe0: 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 74 68  es of data to th
aff0: 65 20 50 4d 41 2e 20 52 65 74 75 72 6e 20 53 51  e PMA. Return SQ
b000: 4c 49 54 45 5f 4f 4b 0a 2a 2a 20 69 66 20 73 75  LITE_OK.** if su
b010: 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20  ccessful, or an 
b020: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
b030: 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  e if an error oc
b040: 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  curs..*/.static 
b050: 76 6f 69 64 20 76 64 62 65 50 6d 61 57 72 69 74  void vdbePmaWrit
b060: 65 42 6c 6f 62 28 50 6d 61 57 72 69 74 65 72 20  eBlob(PmaWriter 
b070: 2a 70 2c 20 75 38 20 2a 70 44 61 74 61 2c 20 69  *p, u8 *pData, i
b080: 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20 69 6e 74  nt nData){.  int
b090: 20 6e 52 65 6d 20 3d 20 6e 44 61 74 61 3b 0a 20   nRem = nData;. 
b0a0: 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30 20 26   while( nRem>0 &
b0b0: 26 20 70 2d 3e 65 46 57 45 72 72 3d 3d 30 20 29  & p->eFWErr==0 )
b0c0: 7b 0a 20 20 20 20 69 6e 74 20 6e 43 6f 70 79 20  {.    int nCopy 
b0d0: 3d 20 6e 52 65 6d 3b 0a 20 20 20 20 69 66 28 20  = nRem;.    if( 
b0e0: 6e 43 6f 70 79 3e 28 70 2d 3e 6e 42 75 66 66 65  nCopy>(p->nBuffe
b0f0: 72 20 2d 20 70 2d 3e 69 42 75 66 45 6e 64 29 20  r - p->iBufEnd) 
b100: 29 7b 0a 20 20 20 20 20 20 6e 43 6f 70 79 20 3d  ){.      nCopy =
b110: 20 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 70 2d   p->nBuffer - p-
b120: 3e 69 42 75 66 45 6e 64 3b 0a 20 20 20 20 7d 0a  >iBufEnd;.    }.
b130: 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d 3e  .    memcpy(&p->
b140: 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 45  aBuffer[p->iBufE
b150: 6e 64 5d 2c 20 26 70 44 61 74 61 5b 6e 44 61 74  nd], &pData[nDat
b160: 61 2d 6e 52 65 6d 5d 2c 20 6e 43 6f 70 79 29 3b  a-nRem], nCopy);
b170: 0a 20 20 20 20 70 2d 3e 69 42 75 66 45 6e 64 20  .    p->iBufEnd 
b180: 2b 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 69 66  += nCopy;.    if
b190: 28 20 70 2d 3e 69 42 75 66 45 6e 64 3d 3d 70 2d  ( p->iBufEnd==p-
b1a0: 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20  >nBuffer ){.    
b1b0: 20 20 70 2d 3e 65 46 57 45 72 72 20 3d 20 73 71    p->eFWErr = sq
b1c0: 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d 3e  lite3OsWrite(p->
b1d0: 70 46 69 6c 65 2c 20 0a 20 20 20 20 20 20 20 20  pFile, .        
b1e0: 20 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 70 2d    &p->aBuffer[p-
b1f0: 3e 69 42 75 66 53 74 61 72 74 5d 2c 20 70 2d 3e  >iBufStart], p->
b200: 69 42 75 66 45 6e 64 20 2d 20 70 2d 3e 69 42 75  iBufEnd - p->iBu
b210: 66 53 74 61 72 74 2c 20 0a 20 20 20 20 20 20 20  fStart, .       
b220: 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20     p->iWriteOff 
b230: 2b 20 70 2d 3e 69 42 75 66 53 74 61 72 74 0a 20  + p->iBufStart. 
b240: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 70 2d       );.      p-
b250: 3e 69 42 75 66 53 74 61 72 74 20 3d 20 70 2d 3e  >iBufStart = p->
b260: 69 42 75 66 45 6e 64 20 3d 20 30 3b 0a 20 20 20  iBufEnd = 0;.   
b270: 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20     p->iWriteOff 
b280: 2b 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20  += p->nBuffer;. 
b290: 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28     }.    assert(
b2a0: 20 70 2d 3e 69 42 75 66 45 6e 64 3c 70 2d 3e 6e   p->iBufEnd<p->n
b2b0: 42 75 66 66 65 72 20 29 3b 0a 0a 20 20 20 20 6e  Buffer );..    n
b2c0: 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20  Rem -= nCopy;.  
b2d0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68  }.}../*.** Flush
b2e0: 20 61 6e 79 20 62 75 66 66 65 72 65 64 20 64 61   any buffered da
b2f0: 74 61 20 74 6f 20 64 69 73 6b 20 61 6e 64 20 63  ta to disk and c
b300: 6c 65 61 6e 20 75 70 20 74 68 65 20 50 4d 41 2d  lean up the PMA-
b310: 77 72 69 74 65 72 20 6f 62 6a 65 63 74 2e 0a 2a  writer object..*
b320: 2a 20 54 68 65 20 72 65 73 75 6c 74 73 20 6f 66  * The results of
b330: 20 75 73 69 6e 67 20 74 68 65 20 50 4d 41 2d 77   using the PMA-w
b340: 72 69 74 65 72 20 61 66 74 65 72 20 74 68 69 73  riter after this
b350: 20 63 61 6c 6c 20 61 72 65 20 75 6e 64 65 66 69   call are undefi
b360: 6e 65 64 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 53  ned..** Return S
b370: 51 4c 49 54 45 5f 4f 4b 20 69 66 20 66 6c 75 73  QLITE_OK if flus
b380: 68 69 6e 67 20 74 68 65 20 62 75 66 66 65 72 65  hing the buffere
b390: 64 20 64 61 74 61 20 73 75 63 63 65 65 64 73 20  d data succeeds 
b3a0: 6f 72 20 69 73 20 6e 6f 74 20 0a 2a 2a 20 72 65  or is not .** re
b3b0: 71 75 69 72 65 64 2e 20 4f 74 68 65 72 77 69 73  quired. Otherwis
b3c0: 65 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c  e, return an SQL
b3d0: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a  ite error code..
b3e0: 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65 20 72 65 74  **.** Before ret
b3f0: 75 72 6e 69 6e 67 2c 20 73 65 74 20 2a 70 69 45  urning, set *piE
b400: 6f 66 20 74 6f 20 74 68 65 20 6f 66 66 73 65 74  of to the offset
b410: 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c   immediately fol
b420: 6c 6f 77 69 6e 67 20 74 68 65 0a 2a 2a 20 6c 61  lowing the.** la
b430: 73 74 20 62 79 74 65 20 77 72 69 74 74 65 6e 20  st byte written 
b440: 74 6f 20 74 68 65 20 66 69 6c 65 2e 0a 2a 2f 0a  to the file..*/.
b450: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 50  static int vdbeP
b460: 6d 61 57 72 69 74 65 72 46 69 6e 69 73 68 28 50  maWriterFinish(P
b470: 6d 61 57 72 69 74 65 72 20 2a 70 2c 20 69 36 34  maWriter *p, i64
b480: 20 2a 70 69 45 6f 66 29 7b 0a 20 20 69 6e 74 20   *piEof){.  int 
b490: 72 63 3b 0a 20 20 69 66 28 20 70 2d 3e 65 46 57  rc;.  if( p->eFW
b4a0: 45 72 72 3d 3d 30 20 26 26 20 41 4c 57 41 59 53  Err==0 && ALWAYS
b4b0: 28 70 2d 3e 61 42 75 66 66 65 72 29 20 26 26 20  (p->aBuffer) && 
b4c0: 70 2d 3e 69 42 75 66 45 6e 64 3e 70 2d 3e 69 42  p->iBufEnd>p->iB
b4d0: 75 66 53 74 61 72 74 20 29 7b 0a 20 20 20 20 70  ufStart ){.    p
b4e0: 2d 3e 65 46 57 45 72 72 20 3d 20 73 71 6c 69 74  ->eFWErr = sqlit
b4f0: 65 33 4f 73 57 72 69 74 65 28 70 2d 3e 70 46 69  e3OsWrite(p->pFi
b500: 6c 65 2c 20 0a 20 20 20 20 20 20 20 20 26 70 2d  le, .        &p-
b510: 3e 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66  >aBuffer[p->iBuf
b520: 53 74 61 72 74 5d 2c 20 70 2d 3e 69 42 75 66 45  Start], p->iBufE
b530: 6e 64 20 2d 20 70 2d 3e 69 42 75 66 53 74 61 72  nd - p->iBufStar
b540: 74 2c 20 0a 20 20 20 20 20 20 20 20 70 2d 3e 69  t, .        p->i
b550: 57 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42  WriteOff + p->iB
b560: 75 66 53 74 61 72 74 0a 20 20 20 20 29 3b 0a 20  ufStart.    );. 
b570: 20 7d 0a 20 20 2a 70 69 45 6f 66 20 3d 20 28 70   }.  *piEof = (p
b580: 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b 20 70 2d  ->iWriteOff + p-
b590: 3e 69 42 75 66 45 6e 64 29 3b 0a 20 20 73 71 6c  >iBufEnd);.  sql
b5a0: 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 42 75  ite3_free(p->aBu
b5b0: 66 66 65 72 29 3b 0a 20 20 72 63 20 3d 20 70 2d  ffer);.  rc = p-
b5c0: 3e 65 46 57 45 72 72 3b 0a 20 20 6d 65 6d 73 65  >eFWErr;.  memse
b5d0: 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50  t(p, 0, sizeof(P
b5e0: 6d 61 57 72 69 74 65 72 29 29 3b 0a 20 20 72 65  maWriter));.  re
b5f0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
b600: 2a 20 57 72 69 74 65 20 76 61 6c 75 65 20 69 56  * Write value iV
b610: 61 6c 20 65 6e 63 6f 64 65 64 20 61 73 20 61 20  al encoded as a 
b620: 76 61 72 69 6e 74 20 74 6f 20 74 68 65 20 50 4d  varint to the PM
b630: 41 2e 20 52 65 74 75 72 6e 20 0a 2a 2a 20 53 51  A. Return .** SQ
b640: 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65  LITE_OK if succe
b650: 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c  ssful, or an SQL
b660: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69  ite error code i
b670: 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
b680: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  s..*/.static voi
b690: 64 20 76 64 62 65 50 6d 61 57 72 69 74 65 56 61  d vdbePmaWriteVa
b6a0: 72 69 6e 74 28 50 6d 61 57 72 69 74 65 72 20 2a  rint(PmaWriter *
b6b0: 70 2c 20 75 36 34 20 69 56 61 6c 29 7b 0a 20 20  p, u64 iVal){.  
b6c0: 69 6e 74 20 6e 42 79 74 65 3b 20 0a 20 20 75 38  int nByte; .  u8
b6d0: 20 61 42 79 74 65 5b 31 30 5d 3b 0a 20 20 6e 42   aByte[10];.  nB
b6e0: 79 74 65 20 3d 20 73 71 6c 69 74 65 33 50 75 74  yte = sqlite3Put
b6f0: 56 61 72 69 6e 74 28 61 42 79 74 65 2c 20 69 56  Varint(aByte, iV
b700: 61 6c 29 3b 0a 20 20 76 64 62 65 50 6d 61 57 72  al);.  vdbePmaWr
b710: 69 74 65 42 6c 6f 62 28 70 2c 20 61 42 79 74 65  iteBlob(p, aByte
b720: 2c 20 6e 42 79 74 65 29 3b 0a 7d 0a 0a 23 69 66  , nByte);.}..#if
b730: 20 53 51 4c 49 54 45 5f 4d 41 58 5f 4d 4d 41 50   SQLITE_MAX_MMAP
b740: 5f 53 49 5a 45 3e 30 0a 2f 2a 0a 2a 2a 20 54 68  _SIZE>0./*.** Th
b750: 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
b760: 20 69 73 20 61 20 66 69 6c 65 2d 68 61 6e 64 6c   is a file-handl
b770: 65 20 6f 70 65 6e 20 6f 6e 20 61 20 74 65 6d 70  e open on a temp
b780: 6f 72 61 72 79 20 66 69 6c 65 2e 20 54 68 65 20  orary file. The 
b790: 66 69 6c 65 0a 2a 2a 20 69 73 20 67 75 61 72 61  file.** is guara
b7a0: 6e 74 65 65 64 20 74 6f 20 62 65 20 6e 42 79 74  nteed to be nByt
b7b0: 65 20 62 79 74 65 73 20 6f 72 20 73 6d 61 6c 6c  e bytes or small
b7c0: 65 72 20 69 6e 20 73 69 7a 65 2e 20 54 68 69 73  er in size. This
b7d0: 20 66 75 6e 63 74 69 6f 6e 0a 2a 2a 20 61 74 74   function.** att
b7e0: 65 6d 70 74 73 20 74 6f 20 65 78 74 65 6e 64 20  empts to extend 
b7f0: 74 68 65 20 66 69 6c 65 20 74 6f 20 6e 42 79 74  the file to nByt
b800: 65 20 62 79 74 65 73 20 69 6e 20 73 69 7a 65 20  e bytes in size 
b810: 61 6e 64 20 74 6f 20 65 6e 73 75 72 65 20 74 68  and to ensure th
b820: 61 74 0a 2a 2a 20 74 68 65 20 56 46 53 20 68 61  at.** the VFS ha
b830: 73 20 6d 65 6d 6f 72 79 20 6d 61 70 70 65 64 20  s memory mapped 
b840: 69 74 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 74 68 65  it..**.** Whethe
b850: 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 66 69 6c  r or not the fil
b860: 65 20 64 6f 65 73 20 65 6e 64 20 75 70 20 6d 65  e does end up me
b870: 6d 6f 72 79 20 6d 61 70 70 65 64 20 6f 66 20 63  mory mapped of c
b880: 6f 75 72 73 65 20 64 65 70 65 6e 64 73 20 6f 6e  ourse depends on
b890: 0a 2a 2a 20 74 68 65 20 73 70 65 63 69 66 69 63  .** the specific
b8a0: 20 56 46 53 20 69 6d 70 6c 65 6d 65 6e 74 61 74   VFS implementat
b8b0: 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ion..*/.static v
b8c0: 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72 45 78  oid vdbeSorterEx
b8d0: 74 65 6e 64 46 69 6c 65 28 73 71 6c 69 74 65 33  tendFile(sqlite3
b8e0: 20 2a 64 62 2c 20 73 71 6c 69 74 65 33 5f 66 69   *db, sqlite3_fi
b8f0: 6c 65 20 2a 70 46 69 6c 65 2c 20 69 36 34 20 6e  le *pFile, i64 n
b900: 42 79 74 65 29 7b 0a 20 20 69 66 28 20 6e 42 79  Byte){.  if( nBy
b910: 74 65 3c 3d 28 69 36 34 29 28 64 62 2d 3e 6e 4d  te<=(i64)(db->nM
b920: 61 78 53 6f 72 74 65 72 4d 6d 61 70 29 20 29 7b  axSorterMmap) ){
b930: 0a 20 20 20 20 69 6e 74 20 72 63 20 3d 20 73 71  .    int rc = sq
b940: 6c 69 74 65 33 4f 73 54 72 75 6e 63 61 74 65 28  lite3OsTruncate(
b950: 70 46 69 6c 65 2c 20 6e 42 79 74 65 29 3b 0a 20  pFile, nByte);. 
b960: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
b970: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 76 6f  E_OK ){.      vo
b980: 69 64 20 2a 70 20 3d 20 30 3b 0a 20 20 20 20 20  id *p = 0;.     
b990: 20 73 71 6c 69 74 65 33 4f 73 46 65 74 63 68 28   sqlite3OsFetch(
b9a0: 70 46 69 6c 65 2c 20 30 2c 20 6e 42 79 74 65 2c  pFile, 0, nByte,
b9b0: 20 26 70 29 3b 0a 20 20 20 20 20 20 73 71 6c 69   &p);.      sqli
b9c0: 74 65 33 4f 73 55 6e 66 65 74 63 68 28 70 46 69  te3OsUnfetch(pFi
b9d0: 6c 65 2c 20 30 2c 20 70 29 3b 0a 20 20 20 20 7d  le, 0, p);.    }
b9e0: 0a 20 20 7d 0a 7d 0a 23 65 6c 73 65 0a 23 20 64  .  }.}.#else.# d
b9f0: 65 66 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72  efine vdbeSorter
ba00: 45 78 74 65 6e 64 46 69 6c 65 28 78 2c 79 2c 7a  ExtendFile(x,y,z
ba10: 29 20 53 51 4c 49 54 45 5f 4f 4b 0a 23 65 6e 64  ) SQLITE_OK.#end
ba20: 69 66 0a 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65  if.../*.** Write
ba30: 20 74 68 65 20 63 75 72 72 65 6e 74 20 63 6f 6e   the current con
ba40: 74 65 6e 74 73 20 6f 66 20 69 6e 2d 6d 65 6d 6f  tents of in-memo
ba50: 72 79 20 6c 69 6e 6b 65 64 2d 6c 69 73 74 20 70  ry linked-list p
ba60: 4c 69 73 74 20 74 6f 20 61 20 6c 65 76 65 6c 2d  List to a level-
ba70: 30 0a 2a 2a 20 50 4d 41 20 69 6e 20 74 68 65 20  0.** PMA in the 
ba80: 74 65 6d 70 20 66 69 6c 65 20 62 65 6c 6f 6e 67  temp file belong
ba90: 69 6e 67 20 74 6f 20 73 75 62 2d 74 61 73 6b 20  ing to sub-task 
baa0: 70 54 61 73 6b 2e 20 52 65 74 75 72 6e 20 53 51  pTask. Return SQ
bab0: 4c 49 54 45 5f 4f 4b 20 69 66 20 0a 2a 2a 20 73  LITE_OK if .** s
bac0: 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e  uccessful, or an
bad0: 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
bae0: 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2a  de otherwise..**
baf0: 0a 2a 2a 20 54 68 65 20 66 6f 72 6d 61 74 20 6f  .** The format o
bb00: 66 20 61 20 50 4d 41 20 69 73 3a 0a 2a 2a 0a 2a  f a PMA is:.**.*
bb10: 2a 20 20 20 20 20 2a 20 41 20 76 61 72 69 6e 74  *     * A varint
bb20: 2e 20 54 68 69 73 20 76 61 72 69 6e 74 20 63 6f  . This varint co
bb30: 6e 74 61 69 6e 73 20 74 68 65 20 74 6f 74 61 6c  ntains the total
bb40: 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   number of bytes
bb50: 20 6f 66 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20 20   of content.**  
bb60: 20 20 20 20 20 69 6e 20 74 68 65 20 50 4d 41 20       in the PMA 
bb70: 28 6e 6f 74 20 69 6e 63 6c 75 64 69 6e 67 20 74  (not including t
bb80: 68 65 20 76 61 72 69 6e 74 20 69 74 73 65 6c 66  he varint itself
bb90: 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 4f  )..**.**     * O
bba0: 6e 65 20 6f 72 20 6d 6f 72 65 20 72 65 63 6f 72  ne or more recor
bbb0: 64 73 20 70 61 63 6b 65 64 20 65 6e 64 2d 74 6f  ds packed end-to
bbc0: 2d 65 6e 64 20 69 6e 20 6f 72 64 65 72 20 6f 66  -end in order of
bbd0: 20 61 73 63 65 6e 64 69 6e 67 20 6b 65 79 73 2e   ascending keys.
bbe0: 20 0a 2a 2a 20 20 20 20 20 20 20 45 61 63 68 20   .**       Each 
bbf0: 72 65 63 6f 72 64 20 63 6f 6e 73 69 73 74 73 20  record consists 
bc00: 6f 66 20 61 20 76 61 72 69 6e 74 20 66 6f 6c 6c  of a varint foll
bc10: 6f 77 65 64 20 62 79 20 61 20 62 6c 6f 62 20 6f  owed by a blob o
bc20: 66 20 64 61 74 61 20 28 74 68 65 20 0a 2a 2a 20  f data (the .** 
bc30: 20 20 20 20 20 20 6b 65 79 29 2e 20 54 68 65 20        key). The 
bc40: 76 61 72 69 6e 74 20 69 73 20 74 68 65 20 6e 75  varint is the nu
bc50: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e  mber of bytes in
bc60: 20 74 68 65 20 62 6c 6f 62 20 6f 66 20 64 61 74   the blob of dat
bc70: 61 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  a..*/.static int
bc80: 20 76 64 62 65 53 6f 72 74 65 72 4c 69 73 74 54   vdbeSorterListT
bc90: 6f 50 4d 41 28 53 6f 72 74 53 75 62 74 61 73 6b  oPMA(SortSubtask
bca0: 20 2a 70 54 61 73 6b 2c 20 53 6f 72 74 65 72 4c   *pTask, SorterL
bcb0: 69 73 74 20 2a 70 4c 69 73 74 29 7b 0a 20 20 73  ist *pList){.  s
bcc0: 71 6c 69 74 65 33 20 2a 64 62 20 3d 20 70 54 61  qlite3 *db = pTa
bcd0: 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 64 62 3b  sk->pSorter->db;
bce0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
bcf0: 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
bd00: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
bd10: 65 20 2a 2f 0a 20 20 50 6d 61 57 72 69 74 65 72  e */.  PmaWriter
bd20: 20 77 72 69 74 65 72 3b 20 20 20 20 20 20 20 20   writer;        
bd30: 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63 74         /* Object
bd40: 20 75 73 65 64 20 74 6f 20 77 72 69 74 65 20 74   used to write t
bd50: 6f 20 74 68 65 20 66 69 6c 65 20 2a 2f 0a 0a 23  o the file */..#
bd60: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 44 45 42  ifdef SQLITE_DEB
bd70: 55 47 0a 20 20 2f 2a 20 53 65 74 20 69 53 7a 20  UG.  /* Set iSz 
bd80: 74 6f 20 74 68 65 20 65 78 70 65 63 74 65 64 20  to the expected 
bd90: 73 69 7a 65 20 6f 66 20 66 69 6c 65 20 70 54 61  size of file pTa
bda0: 73 6b 2d 3e 66 69 6c 65 20 61 66 74 65 72 20 77  sk->file after w
bdb0: 72 69 74 69 6e 67 20 74 68 65 20 50 4d 41 2e 20  riting the PMA. 
bdc0: 0a 20 20 2a 2a 20 54 68 69 73 20 69 73 20 75 73  .  ** This is us
bdd0: 65 64 20 62 79 20 61 6e 20 61 73 73 65 72 74 28  ed by an assert(
bde0: 29 20 73 74 61 74 65 6d 65 6e 74 20 61 74 20 74  ) statement at t
bdf0: 68 65 20 65 6e 64 20 6f 66 20 74 68 69 73 20 66  he end of this f
be00: 75 6e 63 74 69 6f 6e 2e 20 20 2a 2f 0a 20 20 69  unction.  */.  i
be10: 36 34 20 69 53 7a 20 3d 20 70 4c 69 73 74 2d 3e  64 iSz = pList->
be20: 73 7a 50 4d 41 20 2b 20 73 71 6c 69 74 65 33 56  szPMA + sqlite3V
be30: 61 72 69 6e 74 4c 65 6e 28 70 4c 69 73 74 2d 3e  arintLen(pList->
be40: 73 7a 50 4d 41 29 20 2b 20 70 54 61 73 6b 2d 3e  szPMA) + pTask->
be50: 66 69 6c 65 2e 69 45 6f 66 3b 0a 23 65 6e 64 69  file.iEof;.#endi
be60: 66 0a 0a 20 20 76 64 62 65 53 6f 72 74 65 72 57  f..  vdbeSorterW
be70: 6f 72 6b 44 65 62 75 67 28 70 54 61 73 6b 2c 20  orkDebug(pTask, 
be80: 22 65 6e 74 65 72 22 29 3b 0a 20 20 6d 65 6d 73  "enter");.  mems
be90: 65 74 28 26 77 72 69 74 65 72 2c 20 30 2c 20 73  et(&writer, 0, s
bea0: 69 7a 65 6f 66 28 50 6d 61 57 72 69 74 65 72 29  izeof(PmaWriter)
beb0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 4c 69  );.  assert( pLi
bec0: 73 74 2d 3e 73 7a 50 4d 41 3e 30 20 29 3b 0a 0a  st->szPMA>0 );..
bed0: 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69 72 73    /* If the firs
bee0: 74 20 74 65 6d 70 6f 72 61 72 79 20 50 4d 41 20  t temporary PMA 
bef0: 66 69 6c 65 20 68 61 73 20 6e 6f 74 20 62 65 65  file has not bee
bf00: 6e 20 6f 70 65 6e 65 64 2c 20 6f 70 65 6e 20 69  n opened, open i
bf10: 74 20 6e 6f 77 2e 20 2a 2f 0a 20 20 69 66 28 20  t now. */.  if( 
bf20: 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64 3d  pTask->file.pFd=
bf30: 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 76  =0 ){.    rc = v
bf40: 64 62 65 53 6f 72 74 65 72 4f 70 65 6e 54 65 6d  dbeSorterOpenTem
bf50: 70 46 69 6c 65 28 64 62 2d 3e 70 56 66 73 2c 20  pFile(db->pVfs, 
bf60: 26 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64  &pTask->file.pFd
bf70: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 72  );.    assert( r
bf80: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20  c!=SQLITE_OK || 
bf90: 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64 20  pTask->file.pFd 
bfa0: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
bfb0: 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 3d  Task->file.iEof=
bfc0: 3d 30 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  =0 );.    assert
bfd0: 28 20 70 54 61 73 6b 2d 3e 6e 50 4d 41 3d 3d 30  ( pTask->nPMA==0
bfe0: 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54 72   );.  }..  /* Tr
bff0: 79 20 74 6f 20 67 65 74 20 74 68 65 20 66 69 6c  y to get the fil
c000: 65 20 74 6f 20 6d 65 6d 6f 72 79 20 6d 61 70 20  e to memory map 
c010: 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  */.  if( rc==SQL
c020: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 64  ITE_OK ){.    vd
c030: 62 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46 69  beSorterExtendFi
c040: 6c 65 28 64 62 2c 20 70 54 61 73 6b 2d 3e 66 69  le(db, pTask->fi
c050: 6c 65 2e 70 46 64 2c 20 70 54 61 73 6b 2d 3e 66  le.pFd, pTask->f
c060: 69 6c 65 2e 69 45 6f 66 2b 70 4c 69 73 74 2d 3e  ile.iEof+pList->
c070: 73 7a 50 4d 41 2b 39 29 3b 0a 20 20 7d 0a 0a 20  szPMA+9);.  }.. 
c080: 20 2f 2a 20 53 6f 72 74 20 74 68 65 20 6c 69 73   /* Sort the lis
c090: 74 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53  t */.  if( rc==S
c0a0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
c0b0: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 53  rc = vdbeSorterS
c0c0: 6f 72 74 28 70 54 61 73 6b 2c 20 70 4c 69 73 74  ort(pTask, pList
c0d0: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63  );.  }..  if( rc
c0e0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
c0f0: 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20     SorterRecord 
c100: 2a 70 3b 0a 20 20 20 20 53 6f 72 74 65 72 52 65  *p;.    SorterRe
c110: 63 6f 72 64 20 2a 70 4e 65 78 74 20 3d 20 30 3b  cord *pNext = 0;
c120: 0a 0a 20 20 20 20 76 64 62 65 50 6d 61 57 72 69  ..    vdbePmaWri
c130: 74 65 72 49 6e 69 74 28 70 54 61 73 6b 2d 3e 66  terInit(pTask->f
c140: 69 6c 65 2e 70 46 64 2c 20 26 77 72 69 74 65 72  ile.pFd, &writer
c150: 2c 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72  , pTask->pSorter
c160: 2d 3e 70 67 73 7a 2c 0a 20 20 20 20 20 20 20 20  ->pgsz,.        
c170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 54                pT
c180: 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 29 3b  ask->file.iEof);
c190: 0a 20 20 20 20 70 54 61 73 6b 2d 3e 6e 50 4d 41  .    pTask->nPMA
c1a0: 2b 2b 3b 0a 20 20 20 20 76 64 62 65 50 6d 61 57  ++;.    vdbePmaW
c1b0: 72 69 74 65 56 61 72 69 6e 74 28 26 77 72 69 74  riteVarint(&writ
c1c0: 65 72 2c 20 70 4c 69 73 74 2d 3e 73 7a 50 4d 41  er, pList->szPMA
c1d0: 29 3b 0a 20 20 20 20 66 6f 72 28 70 3d 70 4c 69  );.    for(p=pLi
c1e0: 73 74 2d 3e 70 4c 69 73 74 3b 20 70 3b 20 70 3d  st->pList; p; p=
c1f0: 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 70 4e  pNext){.      pN
c200: 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74  ext = p->u.pNext
c210: 3b 0a 20 20 20 20 20 20 76 64 62 65 50 6d 61 57  ;.      vdbePmaW
c220: 72 69 74 65 56 61 72 69 6e 74 28 26 77 72 69 74  riteVarint(&writ
c230: 65 72 2c 20 70 2d 3e 6e 56 61 6c 29 3b 0a 20 20  er, p->nVal);.  
c240: 20 20 20 20 76 64 62 65 50 6d 61 57 72 69 74 65      vdbePmaWrite
c250: 42 6c 6f 62 28 26 77 72 69 74 65 72 2c 20 53 52  Blob(&writer, SR
c260: 56 41 4c 28 70 29 2c 20 70 2d 3e 6e 56 61 6c 29  VAL(p), p->nVal)
c270: 3b 0a 20 20 20 20 20 20 69 66 28 20 70 4c 69 73  ;.      if( pLis
c280: 74 2d 3e 61 4d 65 6d 6f 72 79 3d 3d 30 20 29 20  t->aMemory==0 ) 
c290: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b  sqlite3_free(p);
c2a0: 0a 20 20 20 20 7d 0a 20 20 20 20 70 4c 69 73 74  .    }.    pList
c2b0: 2d 3e 70 4c 69 73 74 20 3d 20 70 3b 0a 20 20 20  ->pList = p;.   
c2c0: 20 72 63 20 3d 20 76 64 62 65 50 6d 61 57 72 69   rc = vdbePmaWri
c2d0: 74 65 72 46 69 6e 69 73 68 28 26 77 72 69 74 65  terFinish(&write
c2e0: 72 2c 20 26 70 54 61 73 6b 2d 3e 66 69 6c 65 2e  r, &pTask->file.
c2f0: 69 45 6f 66 29 3b 0a 20 20 7d 0a 0a 20 20 76 64  iEof);.  }..  vd
c300: 62 65 53 6f 72 74 65 72 57 6f 72 6b 44 65 62 75  beSorterWorkDebu
c310: 67 28 70 54 61 73 6b 2c 20 22 65 78 69 74 22 29  g(pTask, "exit")
c320: 3b 0a 20 20 61 73 73 65 72 74 28 20 72 63 21 3d  ;.  assert( rc!=
c330: 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 4c 69  SQLITE_OK || pLi
c340: 73 74 2d 3e 70 4c 69 73 74 3d 3d 30 20 29 3b 0a  st->pList==0 );.
c350: 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51    assert( rc!=SQ
c360: 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 54 61 73 6b  LITE_OK || pTask
c370: 2d 3e 66 69 6c 65 2e 69 45 6f 66 3d 3d 69 53 7a  ->file.iEof==iSz
c380: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   );.  return rc;
c390: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63  .}../*.** Advanc
c3a0: 65 20 74 68 65 20 4d 65 72 67 65 45 6e 67 69 6e  e the MergeEngin
c3b0: 65 20 69 74 65 72 61 74 6f 72 20 70 61 73 73 65  e iterator passe
c3c0: 64 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64 20  d as the second 
c3d0: 61 72 67 75 6d 65 6e 74 20 74 6f 0a 2a 2a 20 74  argument to.** t
c3e0: 68 65 20 6e 65 78 74 20 65 6e 74 72 79 2e 20 53  he next entry. S
c3f0: 65 74 20 2a 70 62 45 6f 66 20 74 6f 20 74 72 75  et *pbEof to tru
c400: 65 20 69 66 20 74 68 69 73 20 6d 65 61 6e 73 20  e if this means 
c410: 74 68 65 20 69 74 65 72 61 74 6f 72 20 68 61 73  the iterator has
c420: 20 0a 2a 2a 20 72 65 61 63 68 65 64 20 45 4f 46   .** reached EOF
c430: 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 53  ..**.** Return S
c440: 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63  QLITE_OK if succ
c450: 65 73 73 66 75 6c 20 6f 72 20 61 6e 20 65 72 72  essful or an err
c460: 6f 72 20 63 6f 64 65 20 69 66 20 61 6e 20 65 72  or code if an er
c470: 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73  ror occurs..*/.s
c480: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
c490: 72 74 65 72 4e 65 78 74 28 0a 20 20 53 6f 72 74  rterNext(.  Sort
c4a0: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20  Subtask *pTask, 
c4b0: 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a  .  MergeEngine *
c4c0: 70 4d 65 72 67 65 72 2c 20 0a 20 20 69 6e 74 20  pMerger, .  int 
c4d0: 2a 70 62 45 6f 66 0a 29 7b 0a 20 20 69 6e 74 20  *pbEof.){.  int 
c4e0: 72 63 3b 0a 20 20 69 6e 74 20 69 50 72 65 76 20  rc;.  int iPrev 
c4f0: 3d 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65  = pMerger->aTree
c500: 5b 31 5d 3b 2f 2a 20 49 6e 64 65 78 20 6f 66 20  [1];/* Index of 
c510: 69 74 65 72 61 74 6f 72 20 74 6f 20 61 64 76 61  iterator to adva
c520: 6e 63 65 20 2a 2f 0a 0a 20 20 2f 2a 20 41 64 76  nce */..  /* Adv
c530: 61 6e 63 65 20 74 68 65 20 63 75 72 72 65 6e 74  ance the current
c540: 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 72   iterator */.  r
c550: 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65  c = vdbePmaReade
c560: 72 4e 65 78 74 28 26 70 4d 65 72 67 65 72 2d 3e  rNext(&pMerger->
c570: 61 49 74 65 72 5b 69 50 72 65 76 5d 29 3b 0a 0a  aIter[iPrev]);..
c580: 20 20 2f 2a 20 55 70 64 61 74 65 20 63 6f 6e 74    /* Update cont
c590: 65 6e 74 73 20 6f 66 20 61 54 72 65 65 5b 5d 20  ents of aTree[] 
c5a0: 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  */.  if( rc==SQL
c5b0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e  ITE_OK ){.    in
c5c0: 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20  t i;            
c5d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64            /* Ind
c5e0: 65 78 20 6f 66 20 61 54 72 65 65 5b 5d 20 74 6f  ex of aTree[] to
c5f0: 20 72 65 63 61 6c 63 75 6c 61 74 65 20 2a 2f 0a   recalculate */.
c600: 20 20 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70      PmaReader *p
c610: 49 74 65 72 31 3b 20 20 20 20 20 2f 2a 20 46 69  Iter1;     /* Fi
c620: 72 73 74 20 69 74 65 72 61 74 6f 72 20 74 6f 20  rst iterator to 
c630: 63 6f 6d 70 61 72 65 20 2a 2f 0a 20 20 20 20 50  compare */.    P
c640: 6d 61 52 65 61 64 65 72 20 2a 70 49 74 65 72 32  maReader *pIter2
c650: 3b 20 20 20 20 20 2f 2a 20 53 65 63 6f 6e 64 20  ;     /* Second 
c660: 69 74 65 72 61 74 6f 72 20 74 6f 20 63 6f 6d 70  iterator to comp
c670: 61 72 65 20 2a 2f 0a 20 20 20 20 75 38 20 2a 70  are */.    u8 *p
c680: 4b 65 79 32 3b 20 20 20 20 20 20 20 20 20 20 20  Key2;           
c690: 20 20 20 20 20 20 20 2f 2a 20 54 6f 20 70 49 74         /* To pIt
c6a0: 65 72 32 2d 3e 61 4b 65 79 2c 20 6f 72 20 30 20  er2->aKey, or 0 
c6b0: 69 66 20 72 65 63 6f 72 64 20 63 61 63 68 65 64  if record cached
c6c0: 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 46 69 6e 64   */..    /* Find
c6d0: 20 74 68 65 20 66 69 72 73 74 20 74 77 6f 20 69   the first two i
c6e0: 74 65 72 61 74 6f 72 73 20 74 6f 20 63 6f 6d 70  terators to comp
c6f0: 61 72 65 2e 20 54 68 65 20 6f 6e 65 20 74 68 61  are. The one tha
c700: 74 20 77 61 73 20 6a 75 73 74 0a 20 20 20 20 2a  t was just.    *
c710: 2a 20 61 64 76 61 6e 63 65 64 20 28 69 50 72 65  * advanced (iPre
c720: 76 29 20 61 6e 64 20 74 68 65 20 6f 6e 65 20 6e  v) and the one n
c730: 65 78 74 20 74 6f 20 69 74 20 69 6e 20 74 68 65  ext to it in the
c740: 20 61 72 72 61 79 2e 20 20 2a 2f 0a 20 20 20 20   array.  */.    
c750: 70 49 74 65 72 31 20 3d 20 26 70 4d 65 72 67 65  pIter1 = &pMerge
c760: 72 2d 3e 61 49 74 65 72 5b 28 69 50 72 65 76 20  r->aIter[(iPrev 
c770: 26 20 30 78 46 46 46 45 29 5d 3b 0a 20 20 20 20  & 0xFFFE)];.    
c780: 70 49 74 65 72 32 20 3d 20 26 70 4d 65 72 67 65  pIter2 = &pMerge
c790: 72 2d 3e 61 49 74 65 72 5b 28 69 50 72 65 76 20  r->aIter[(iPrev 
c7a0: 7c 20 30 78 30 30 30 31 29 5d 3b 0a 20 20 20 20  | 0x0001)];.    
c7b0: 70 4b 65 79 32 20 3d 20 70 49 74 65 72 32 2d 3e  pKey2 = pIter2->
c7c0: 61 4b 65 79 3b 0a 0a 20 20 20 20 66 6f 72 28 69  aKey;..    for(i
c7d0: 3d 28 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65  =(pMerger->nTree
c7e0: 2b 69 50 72 65 76 29 2f 32 3b 20 69 3e 30 3b 20  +iPrev)/2; i>0; 
c7f0: 69 3d 69 2f 32 29 7b 0a 20 20 20 20 20 20 2f 2a  i=i/2){.      /*
c800: 20 43 6f 6d 70 61 72 65 20 70 49 74 65 72 31 20   Compare pIter1 
c810: 61 6e 64 20 70 49 74 65 72 32 2e 20 53 74 6f 72  and pIter2. Stor
c820: 65 20 74 68 65 20 72 65 73 75 6c 74 20 69 6e 20  e the result in 
c830: 76 61 72 69 61 62 6c 65 20 69 52 65 73 2e 20 2a  variable iRes. *
c840: 2f 0a 20 20 20 20 20 20 69 6e 74 20 69 52 65 73  /.      int iRes
c850: 3b 0a 20 20 20 20 20 20 69 66 28 20 70 49 74 65  ;.      if( pIte
c860: 72 31 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a  r1->pFile==0 ){.
c870: 20 20 20 20 20 20 20 20 69 52 65 73 20 3d 20 2b          iRes = +
c880: 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69  1;.      }else i
c890: 66 28 20 70 49 74 65 72 32 2d 3e 70 46 69 6c 65  f( pIter2->pFile
c8a0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 69  ==0 ){.        i
c8b0: 52 65 73 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20  Res = -1;.      
c8c0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69  }else{.        i
c8d0: 52 65 73 20 3d 20 76 64 62 65 53 6f 72 74 65 72  Res = vdbeSorter
c8e0: 43 6f 6d 70 61 72 65 28 70 54 61 73 6b 2c 20 0a  Compare(pTask, .
c8f0: 20 20 20 20 20 20 20 20 20 20 20 20 70 49 74 65              pIte
c900: 72 31 2d 3e 61 4b 65 79 2c 20 70 49 74 65 72 31  r1->aKey, pIter1
c910: 2d 3e 6e 4b 65 79 2c 20 70 4b 65 79 32 2c 20 70  ->nKey, pKey2, p
c920: 49 74 65 72 32 2d 3e 6e 4b 65 79 0a 20 20 20 20  Iter2->nKey.    
c930: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 7d 0a 0a      );.      }..
c940: 20 20 20 20 20 20 2f 2a 20 49 66 20 70 49 74 65        /* If pIte
c950: 72 31 20 63 6f 6e 74 61 69 6e 65 64 20 74 68 65  r1 contained the
c960: 20 73 6d 61 6c 6c 65 72 20 76 61 6c 75 65 2c 20   smaller value, 
c970: 73 65 74 20 61 54 72 65 65 5b 69 5d 20 74 6f 20  set aTree[i] to 
c980: 69 74 73 20 69 6e 64 65 78 2e 0a 20 20 20 20 20  its index..     
c990: 20 2a 2a 20 54 68 65 6e 20 73 65 74 20 70 49 74   ** Then set pIt
c9a0: 65 72 32 20 74 6f 20 74 68 65 20 6e 65 78 74 20  er2 to the next 
c9b0: 69 74 65 72 61 74 6f 72 20 74 6f 20 63 6f 6d 70  iterator to comp
c9c0: 61 72 65 20 74 6f 20 70 49 74 65 72 31 2e 20 49  are to pIter1. I
c9d0: 6e 20 74 68 69 73 0a 20 20 20 20 20 20 2a 2a 20  n this.      ** 
c9e0: 63 61 73 65 20 74 68 65 72 65 20 69 73 20 6e 6f  case there is no
c9f0: 20 63 61 63 68 65 20 6f 66 20 70 49 74 65 72 32   cache of pIter2
ca00: 20 69 6e 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61   in pTask->pUnpa
ca10: 63 6b 65 64 2c 20 73 6f 20 73 65 74 0a 20 20 20  cked, so set.   
ca20: 20 20 20 2a 2a 20 70 4b 65 79 32 20 74 6f 20 70     ** pKey2 to p
ca30: 6f 69 6e 74 20 74 6f 20 74 68 65 20 72 65 63 6f  oint to the reco
ca40: 72 64 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20  rd belonging to 
ca50: 70 49 74 65 72 32 2e 0a 20 20 20 20 20 20 2a 2a  pIter2..      **
ca60: 0a 20 20 20 20 20 20 2a 2a 20 41 6c 74 65 72 6e  .      ** Altern
ca70: 61 74 69 76 65 6c 79 2c 20 69 66 20 70 49 74 65  atively, if pIte
ca80: 72 32 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  r2 contains the 
ca90: 73 6d 61 6c 6c 65 72 20 6f 66 20 74 68 65 20 74  smaller of the t
caa0: 77 6f 20 76 61 6c 75 65 73 2c 0a 20 20 20 20 20  wo values,.     
cab0: 20 2a 2a 20 73 65 74 20 61 54 72 65 65 5b 69 5d   ** set aTree[i]
cac0: 20 74 6f 20 69 74 73 20 69 6e 64 65 78 20 61 6e   to its index an
cad0: 64 20 75 70 64 61 74 65 20 70 49 74 65 72 31 2e  d update pIter1.
cae0: 20 49 66 20 76 64 62 65 53 6f 72 74 65 72 43 6f   If vdbeSorterCo
caf0: 6d 70 61 72 65 28 29 0a 20 20 20 20 20 20 2a 2a  mpare().      **
cb00: 20 77 61 73 20 61 63 74 75 61 6c 6c 79 20 63 61   was actually ca
cb10: 6c 6c 65 64 20 61 62 6f 76 65 2c 20 74 68 65 6e  lled above, then
cb20: 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65   pTask->pUnpacke
cb30: 64 20 6e 6f 77 20 63 6f 6e 74 61 69 6e 73 0a 20  d now contains. 
cb40: 20 20 20 20 20 2a 2a 20 61 20 76 61 6c 75 65 20       ** a value 
cb50: 65 71 75 69 76 61 6c 65 6e 74 20 74 6f 20 70 49  equivalent to pI
cb60: 74 65 72 32 2e 20 53 6f 20 73 65 74 20 70 4b 65  ter2. So set pKe
cb70: 79 32 20 74 6f 20 4e 55 4c 4c 20 74 6f 20 70 72  y2 to NULL to pr
cb80: 65 76 65 6e 74 0a 20 20 20 20 20 20 2a 2a 20 76  event.      ** v
cb90: 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65  dbeSorterCompare
cba0: 28 29 20 66 72 6f 6d 20 64 65 63 6f 64 69 6e 67  () from decoding
cbb0: 20 70 49 74 65 72 32 20 61 67 61 69 6e 2e 0a 20   pIter2 again.. 
cbc0: 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a       **.      **
cbd0: 20 49 66 20 74 68 65 20 74 77 6f 20 76 61 6c 75   If the two valu
cbe0: 65 73 20 77 65 72 65 20 65 71 75 61 6c 2c 20 74  es were equal, t
cbf0: 68 65 6e 20 74 68 65 20 76 61 6c 75 65 20 66 72  hen the value fr
cc00: 6f 6d 20 74 68 65 20 6f 6c 64 65 73 74 0a 20 20  om the oldest.  
cc10: 20 20 20 20 2a 2a 20 50 4d 41 20 73 68 6f 75 6c      ** PMA shoul
cc20: 64 20 62 65 20 63 6f 6e 73 69 64 65 72 65 64 20  d be considered 
cc30: 73 6d 61 6c 6c 65 72 2e 20 54 68 65 20 56 64 62  smaller. The Vdb
cc40: 65 53 6f 72 74 65 72 2e 61 49 74 65 72 5b 5d 20  eSorter.aIter[] 
cc50: 61 72 72 61 79 0a 20 20 20 20 20 20 2a 2a 20 69  array.      ** i
cc60: 73 20 73 6f 72 74 65 64 20 66 72 6f 6d 20 6f 6c  s sorted from ol
cc70: 64 65 73 74 20 74 6f 20 6e 65 77 65 73 74 2c 20  dest to newest, 
cc80: 73 6f 20 70 49 74 65 72 31 20 63 6f 6e 74 61 69  so pIter1 contai
cc90: 6e 73 20 6f 6c 64 65 72 20 76 61 6c 75 65 73 0a  ns older values.
cca0: 20 20 20 20 20 20 2a 2a 20 74 68 61 6e 20 70 49        ** than pI
ccb0: 74 65 72 32 20 69 66 66 20 28 70 49 74 65 72 31  ter2 iff (pIter1
ccc0: 3c 70 49 74 65 72 32 29 2e 20 20 2a 2f 0a 20 20  <pIter2).  */.  
ccd0: 20 20 20 20 69 66 28 20 69 52 65 73 3c 30 20 7c      if( iRes<0 |
cce0: 7c 20 28 69 52 65 73 3d 3d 30 20 26 26 20 70 49  | (iRes==0 && pI
ccf0: 74 65 72 31 3c 70 49 74 65 72 32 29 20 29 7b 0a  ter1<pIter2) ){.
cd00: 20 20 20 20 20 20 20 20 70 4d 65 72 67 65 72 2d          pMerger-
cd10: 3e 61 54 72 65 65 5b 69 5d 20 3d 20 28 69 6e 74  >aTree[i] = (int
cd20: 29 28 70 49 74 65 72 31 20 2d 20 70 4d 65 72 67  )(pIter1 - pMerg
cd30: 65 72 2d 3e 61 49 74 65 72 29 3b 0a 20 20 20 20  er->aIter);.    
cd40: 20 20 20 20 70 49 74 65 72 32 20 3d 20 26 70 4d      pIter2 = &pM
cd50: 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 20 70 4d  erger->aIter[ pM
cd60: 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 20 5e  erger->aTree[i ^
cd70: 20 30 78 30 30 30 31 5d 20 5d 3b 0a 20 20 20 20   0x0001] ];.    
cd80: 20 20 20 20 70 4b 65 79 32 20 3d 20 70 49 74 65      pKey2 = pIte
cd90: 72 32 2d 3e 61 4b 65 79 3b 0a 20 20 20 20 20 20  r2->aKey;.      
cda0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69  }else{.        i
cdb0: 66 28 20 70 49 74 65 72 31 2d 3e 70 46 69 6c 65  f( pIter1->pFile
cdc0: 20 29 20 70 4b 65 79 32 20 3d 20 30 3b 0a 20 20   ) pKey2 = 0;.  
cdd0: 20 20 20 20 20 20 70 4d 65 72 67 65 72 2d 3e 61        pMerger->a
cde0: 54 72 65 65 5b 69 5d 20 3d 20 28 69 6e 74 29 28  Tree[i] = (int)(
cdf0: 70 49 74 65 72 32 20 2d 20 70 4d 65 72 67 65 72  pIter2 - pMerger
ce00: 2d 3e 61 49 74 65 72 29 3b 0a 20 20 20 20 20 20  ->aIter);.      
ce10: 20 20 70 49 74 65 72 31 20 3d 20 26 70 4d 65 72    pIter1 = &pMer
ce20: 67 65 72 2d 3e 61 49 74 65 72 5b 20 70 4d 65 72  ger->aIter[ pMer
ce30: 67 65 72 2d 3e 61 54 72 65 65 5b 69 20 5e 20 30  ger->aTree[i ^ 0
ce40: 78 30 30 30 31 5d 20 5d 3b 0a 20 20 20 20 20 20  x0001] ];.      
ce50: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 2a 70 62 45  }.    }.    *pbE
ce60: 6f 66 20 3d 20 28 70 4d 65 72 67 65 72 2d 3e 61  of = (pMerger->a
ce70: 49 74 65 72 5b 70 4d 65 72 67 65 72 2d 3e 61 54  Iter[pMerger->aT
ce80: 72 65 65 5b 31 5d 5d 2e 70 46 69 6c 65 3d 3d 30  ree[1]].pFile==0
ce90: 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  );.  }..  return
cea0: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
ceb0: 65 20 6d 61 69 6e 20 72 6f 75 74 69 6e 65 20 66  e main routine f
cec0: 6f 72 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68  or background th
ced0: 72 65 61 64 73 20 74 68 61 74 20 77 72 69 74 65  reads that write
cee0: 20 6c 65 76 65 6c 2d 30 20 50 4d 41 73 2e 0a 2a   level-0 PMAs..*
cef0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a 76  /.static void *v
cf00: 64 62 65 53 6f 72 74 65 72 46 6c 75 73 68 54 68  dbeSorterFlushTh
cf10: 72 65 61 64 28 76 6f 69 64 20 2a 70 43 74 78 29  read(void *pCtx)
cf20: 7b 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20  {.  SortSubtask 
cf30: 2a 70 54 61 73 6b 20 3d 20 28 53 6f 72 74 53 75  *pTask = (SortSu
cf40: 62 74 61 73 6b 2a 29 70 43 74 78 3b 0a 20 20 69  btask*)pCtx;.  i
cf50: 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
cf60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
cf70: 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
cf80: 0a 20 20 61 73 73 65 72 74 28 20 70 54 61 73 6b  .  assert( pTask
cf90: 2d 3e 62 44 6f 6e 65 3d 3d 30 20 29 3b 0a 20 20  ->bDone==0 );.  
cfa0: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4c  rc = vdbeSorterL
cfb0: 69 73 74 54 6f 50 4d 41 28 70 54 61 73 6b 2c 20  istToPMA(pTask, 
cfc0: 26 70 54 61 73 6b 2d 3e 6c 69 73 74 29 3b 0a 20  &pTask->list);. 
cfd0: 20 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 20 3d 20   pTask->bDone = 
cfe0: 31 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  1;.  return SQLI
cff0: 54 45 5f 49 4e 54 5f 54 4f 5f 50 54 52 28 72 63  TE_INT_TO_PTR(rc
d000: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73  );.}../*.** Flus
d010: 68 20 74 68 65 20 63 75 72 72 65 6e 74 20 63 6f  h the current co
d020: 6e 74 65 6e 74 73 20 6f 66 20 56 64 62 65 53 6f  ntents of VdbeSo
d030: 72 74 65 72 2e 6c 69 73 74 20 74 6f 20 61 20 6e  rter.list to a n
d040: 65 77 20 50 4d 41 2c 20 70 6f 73 73 69 62 6c 79  ew PMA, possibly
d050: 0a 2a 2a 20 75 73 69 6e 67 20 61 20 62 61 63 6b  .** using a back
d060: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 2e 0a 2a  ground thread..*
d070: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
d080: 65 53 6f 72 74 65 72 46 6c 75 73 68 50 4d 41 28  eSorterFlushPMA(
d090: 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72  VdbeSorter *pSor
d0a0: 74 65 72 29 7b 0a 23 69 66 20 53 51 4c 49 54 45  ter){.#if SQLITE
d0b0: 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45  _MAX_WORKER_THRE
d0c0: 41 44 53 3d 3d 30 0a 20 20 70 53 6f 72 74 65 72  ADS==0.  pSorter
d0d0: 2d 3e 62 55 73 65 50 4d 41 20 3d 20 31 3b 0a 20  ->bUsePMA = 1;. 
d0e0: 20 72 65 74 75 72 6e 20 76 64 62 65 53 6f 72 74   return vdbeSort
d0f0: 65 72 4c 69 73 74 54 6f 50 4d 41 28 26 70 53 6f  erListToPMA(&pSo
d100: 72 74 65 72 2d 3e 61 54 61 73 6b 5b 30 5d 2c 20  rter->aTask[0], 
d110: 26 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 29 3b  &pSorter->list);
d120: 0a 23 65 6c 73 65 0a 20 20 69 6e 74 20 72 63 20  .#else.  int rc 
d130: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
d140: 6e 74 20 69 3b 0a 20 20 53 6f 72 74 53 75 62 74  nt i;.  SortSubt
d150: 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20 30 3b 20  ask *pTask = 0; 
d160: 20 20 20 2f 2a 20 54 68 72 65 61 64 20 63 6f 6e     /* Thread con
d170: 74 65 78 74 20 75 73 65 64 20 74 6f 20 63 72 65  text used to cre
d180: 61 74 65 20 6e 65 77 20 50 4d 41 20 2a 2f 0a 20  ate new PMA */. 
d190: 20 69 6e 74 20 6e 57 6f 72 6b 65 72 20 3d 20 28   int nWorker = (
d1a0: 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31  pSorter->nTask-1
d1b0: 29 3b 0a 0a 20 20 2f 2a 20 53 65 74 20 74 68 65  );..  /* Set the
d1c0: 20 66 6c 61 67 20 74 6f 20 69 6e 64 69 63 61 74   flag to indicat
d1d0: 65 20 74 68 61 74 20 61 74 20 6c 65 61 73 74 20  e that at least 
d1e0: 6f 6e 65 20 50 4d 41 20 68 61 73 20 62 65 65 6e  one PMA has been
d1f0: 20 77 72 69 74 74 65 6e 2e 20 0a 20 20 2a 2a 20   written. .  ** 
d200: 4f 72 20 77 69 6c 6c 20 62 65 2c 20 61 6e 79 68  Or will be, anyh
d210: 6f 77 2e 20 20 2a 2f 0a 20 20 70 53 6f 72 74 65  ow.  */.  pSorte
d220: 72 2d 3e 62 55 73 65 50 4d 41 20 3d 20 31 3b 0a  r->bUsePMA = 1;.
d230: 0a 20 20 2f 2a 20 53 65 6c 65 63 74 20 61 20 73  .  /* Select a s
d240: 75 62 2d 74 61 73 6b 20 74 6f 20 73 6f 72 74 20  ub-task to sort 
d250: 61 6e 64 20 66 6c 75 73 68 20 74 68 65 20 63 75  and flush the cu
d260: 72 72 65 6e 74 20 6c 69 73 74 20 6f 66 20 69 6e  rrent list of in
d270: 2d 6d 65 6d 6f 72 79 0a 20 20 2a 2a 20 72 65 63  -memory.  ** rec
d280: 6f 72 64 73 20 74 6f 20 64 69 73 6b 2e 20 49 66  ords to disk. If
d290: 20 74 68 65 20 73 6f 72 74 65 72 20 69 73 20 72   the sorter is r
d2a0: 75 6e 6e 69 6e 67 20 69 6e 20 6d 75 6c 74 69 2d  unning in multi-
d2b0: 74 68 72 65 61 64 65 64 20 6d 6f 64 65 2c 0a 20  threaded mode,. 
d2c0: 20 2a 2a 20 72 6f 75 6e 64 2d 72 6f 62 69 6e 20   ** round-robin 
d2d0: 62 65 74 77 65 65 6e 20 74 68 65 20 66 69 72 73  between the firs
d2e0: 74 20 28 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73  t (pSorter->nTas
d2f0: 6b 2d 31 29 20 74 61 73 6b 73 2e 20 45 78 63 65  k-1) tasks. Exce
d300: 70 74 2c 20 69 66 0a 20 20 2a 2a 20 74 68 65 20  pt, if.  ** the 
d310: 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61  background threa
d320: 64 20 66 72 6f 6d 20 61 20 73 75 62 2d 74 61 73  d from a sub-tas
d330: 6b 73 20 70 72 65 76 69 6f 75 73 20 74 75 72 6e  ks previous turn
d340: 20 69 73 20 73 74 69 6c 6c 20 72 75 6e 6e 69 6e   is still runnin
d350: 67 2c 0a 20 20 2a 2a 20 73 6b 69 70 20 69 74 2e  g,.  ** skip it.
d360: 20 49 66 20 74 68 65 20 66 69 72 73 74 20 28 70   If the first (p
d370: 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29  Sorter->nTask-1)
d380: 20 73 75 62 2d 74 61 73 6b 73 20 61 72 65 20 61   sub-tasks are a
d390: 6c 6c 20 73 74 69 6c 6c 20 62 75 73 79 2c 0a 20  ll still busy,. 
d3a0: 20 2a 2a 20 66 61 6c 6c 20 62 61 63 6b 20 74 6f   ** fall back to
d3b0: 20 75 73 69 6e 67 20 74 68 65 20 66 69 6e 61 6c   using the final
d3c0: 20 73 75 62 2d 74 61 73 6b 2e 20 54 68 65 20 66   sub-task. The f
d3d0: 69 72 73 74 20 28 70 53 6f 72 74 65 72 2d 3e 6e  irst (pSorter->n
d3e0: 54 61 73 6b 2d 31 29 0a 20 20 2a 2a 20 73 75 62  Task-1).  ** sub
d3f0: 2d 74 61 73 6b 73 20 61 72 65 20 70 72 65 66 65  -tasks are prefe
d400: 72 65 64 20 61 73 20 74 68 65 79 20 75 73 65 20  red as they use 
d410: 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61  background threa
d420: 64 73 20 2d 20 74 68 65 20 66 69 6e 61 6c 20 0a  ds - the final .
d430: 20 20 2a 2a 20 73 75 62 2d 74 61 73 6b 20 75 73    ** sub-task us
d440: 65 73 20 74 68 65 20 6d 61 69 6e 20 74 68 72 65  es the main thre
d450: 61 64 2e 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30  ad. */.  for(i=0
d460: 3b 20 69 3c 6e 57 6f 72 6b 65 72 3b 20 69 2b 2b  ; i<nWorker; i++
d470: 29 7b 0a 20 20 20 20 69 6e 74 20 69 54 65 73 74  ){.    int iTest
d480: 20 3d 20 28 70 53 6f 72 74 65 72 2d 3e 69 50 72   = (pSorter->iPr
d490: 65 76 20 2b 20 69 20 2b 20 31 29 20 25 20 6e 57  ev + i + 1) % nW
d4a0: 6f 72 6b 65 72 3b 0a 20 20 20 20 70 54 61 73 6b  orker;.    pTask
d4b0: 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 54 61   = &pSorter->aTa
d4c0: 73 6b 5b 69 54 65 73 74 5d 3b 0a 20 20 20 20 69  sk[iTest];.    i
d4d0: 66 28 20 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 20  f( pTask->bDone 
d4e0: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64  ){.      rc = vd
d4f0: 62 65 53 6f 72 74 65 72 4a 6f 69 6e 54 68 72 65  beSorterJoinThre
d500: 61 64 28 70 54 61 73 6b 29 3b 0a 20 20 20 20 7d  ad(pTask);.    }
d510: 0a 20 20 20 20 69 66 28 20 70 54 61 73 6b 2d 3e  .    if( pTask->
d520: 70 54 68 72 65 61 64 3d 3d 30 20 7c 7c 20 72 63  pThread==0 || rc
d530: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72  !=SQLITE_OK ) br
d540: 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  eak;.  }..  if( 
d550: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
d560: 0a 20 20 20 20 69 66 28 20 69 3d 3d 6e 57 6f 72  .    if( i==nWor
d570: 6b 65 72 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  ker ){.      /* 
d580: 55 73 65 20 74 68 65 20 66 6f 72 65 67 72 6f 75  Use the foregrou
d590: 6e 64 20 74 68 72 65 61 64 20 66 6f 72 20 74 68  nd thread for th
d5a0: 69 73 20 6f 70 65 72 61 74 69 6f 6e 20 2a 2f 0a  is operation */.
d5b0: 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53        rc = vdbeS
d5c0: 6f 72 74 65 72 4c 69 73 74 54 6f 50 4d 41 28 26  orterListToPMA(&
d5d0: 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 6e  pSorter->aTask[n
d5e0: 57 6f 72 6b 65 72 5d 2c 20 26 70 53 6f 72 74 65  Worker], &pSorte
d5f0: 72 2d 3e 6c 69 73 74 29 3b 0a 20 20 20 20 7d 65  r->list);.    }e
d600: 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a 20 4c 61  lse{.      /* La
d610: 75 6e 63 68 20 61 20 62 61 63 6b 67 72 6f 75 6e  unch a backgroun
d620: 64 20 74 68 72 65 61 64 20 66 6f 72 20 74 68 69  d thread for thi
d630: 73 20 6f 70 65 72 61 74 69 6f 6e 20 2a 2f 0a 20  s operation */. 
d640: 20 20 20 20 20 75 38 20 2a 61 4d 65 6d 20 3d 20       u8 *aMem = 
d650: 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d  pTask->list.aMem
d660: 6f 72 79 3b 0a 20 20 20 20 20 20 76 6f 69 64 20  ory;.      void 
d670: 2a 70 43 74 78 20 3d 20 28 76 6f 69 64 2a 29 70  *pCtx = (void*)p
d680: 54 61 73 6b 3b 0a 0a 20 20 20 20 20 20 61 73 73  Task;..      ass
d690: 65 72 74 28 20 70 54 61 73 6b 2d 3e 70 54 68 72  ert( pTask->pThr
d6a0: 65 61 64 3d 3d 30 20 26 26 20 70 54 61 73 6b 2d  ead==0 && pTask-
d6b0: 3e 62 44 6f 6e 65 3d 3d 30 20 29 3b 0a 20 20 20  >bDone==0 );.   
d6c0: 20 20 20 61 73 73 65 72 74 28 20 70 54 61 73 6b     assert( pTask
d6d0: 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 3d 3d 30 20  ->list.pList==0 
d6e0: 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  );.      assert(
d6f0: 20 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65   pTask->list.aMe
d700: 6d 6f 72 79 3d 3d 30 20 7c 7c 20 70 53 6f 72 74  mory==0 || pSort
d710: 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  er->list.aMemory
d720: 21 3d 30 20 29 3b 0a 0a 20 20 20 20 20 20 70 53  !=0 );..      pS
d730: 6f 72 74 65 72 2d 3e 69 50 72 65 76 20 3d 20 28  orter->iPrev = (
d740: 70 54 61 73 6b 20 2d 20 70 53 6f 72 74 65 72 2d  pTask - pSorter-
d750: 3e 61 54 61 73 6b 29 3b 0a 20 20 20 20 20 20 70  >aTask);.      p
d760: 54 61 73 6b 2d 3e 6c 69 73 74 20 3d 20 70 53 6f  Task->list = pSo
d770: 72 74 65 72 2d 3e 6c 69 73 74 3b 0a 20 20 20 20  rter->list;.    
d780: 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e    pSorter->list.
d790: 70 4c 69 73 74 20 3d 20 30 3b 0a 20 20 20 20 20  pList = 0;.     
d7a0: 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 73   pSorter->list.s
d7b0: 7a 50 4d 41 20 3d 20 30 3b 0a 20 20 20 20 20 20  zPMA = 0;.      
d7c0: 69 66 28 20 61 4d 65 6d 20 29 7b 0a 20 20 20 20  if( aMem ){.    
d7d0: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73      pSorter->lis
d7e0: 74 2e 61 4d 65 6d 6f 72 79 20 3d 20 61 4d 65 6d  t.aMemory = aMem
d7f0: 3b 0a 20 20 20 20 20 20 20 20 70 53 6f 72 74 65  ;.        pSorte
d800: 72 2d 3e 6e 4d 65 6d 6f 72 79 20 3d 20 73 71 6c  r->nMemory = sql
d810: 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 61  ite3MallocSize(a
d820: 4d 65 6d 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73  Mem);.      }els
d830: 65 7b 0a 20 20 20 20 20 20 20 20 70 53 6f 72 74  e{.        pSort
d840: 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  er->list.aMemory
d850: 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63   = sqlite3Malloc
d860: 28 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72  (pSorter->nMemor
d870: 79 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  y);.        if( 
d880: 21 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61  !pSorter->list.a
d890: 4d 65 6d 6f 72 79 20 29 20 72 65 74 75 72 6e 20  Memory ) return 
d8a0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
d8b0: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 72 63 20      }..      rc 
d8c0: 3d 20 76 64 62 65 53 6f 72 74 65 72 43 72 65 61  = vdbeSorterCrea
d8d0: 74 65 54 68 72 65 61 64 28 70 54 61 73 6b 2c 20  teThread(pTask, 
d8e0: 76 64 62 65 53 6f 72 74 65 72 46 6c 75 73 68 54  vdbeSorterFlushT
d8f0: 68 72 65 61 64 2c 20 70 43 74 78 29 3b 0a 20 20  hread, pCtx);.  
d900: 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
d910: 6e 20 72 63 3b 0a 23 65 6e 64 69 66 0a 7d 0a 0a  n rc;.#endif.}..
d920: 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 72 65 63 6f  /*.** Add a reco
d930: 72 64 20 74 6f 20 74 68 65 20 73 6f 72 74 65 72  rd to the sorter
d940: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
d950: 56 64 62 65 53 6f 72 74 65 72 57 72 69 74 65 28  VdbeSorterWrite(
d960: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  .  sqlite3 *db, 
d970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d980: 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68     /* Database h
d990: 61 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74  andle */.  const
d9a0: 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73   VdbeCursor *pCs
d9b0: 72 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f  r,         /* So
d9c0: 72 74 65 72 20 63 75 72 73 6f 72 20 2a 2f 0a 20  rter cursor */. 
d9d0: 20 4d 65 6d 20 2a 70 56 61 6c 20 20 20 20 20 20   Mem *pVal      
d9e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d9f0: 20 2f 2a 20 4d 65 6d 6f 72 79 20 63 65 6c 6c 20   /* Memory cell 
da00: 63 6f 6e 74 61 69 6e 69 6e 67 20 72 65 63 6f 72  containing recor
da10: 64 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65 53 6f  d */.){.  VdbeSo
da20: 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20  rter *pSorter = 
da30: 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20  pCsr->pSorter;. 
da40: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
da50: 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20  _OK;            
da60: 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20   /* Return Code 
da70: 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72  */.  SorterRecor
da80: 64 20 2a 70 4e 65 77 3b 20 20 20 20 20 20 20 20  d *pNew;        
da90: 20 20 20 20 20 2f 2a 20 4e 65 77 20 6c 69 73 74       /* New list
daa0: 20 65 6c 65 6d 65 6e 74 20 2a 2f 0a 0a 20 20 69   element */..  i
dab0: 6e 74 20 62 46 6c 75 73 68 3b 20 20 20 20 20 20  nt bFlush;      
dac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
dad0: 2a 20 54 72 75 65 20 74 6f 20 66 6c 75 73 68 20  * True to flush 
dae0: 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65 6d 6f  contents of memo
daf0: 72 79 20 74 6f 20 50 4d 41 20 2a 2f 0a 20 20 69  ry to PMA */.  i
db00: 6e 74 20 6e 52 65 71 3b 20 20 20 20 20 20 20 20  nt nReq;        
db10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
db20: 2a 20 42 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72  * Bytes of memor
db30: 79 20 72 65 71 75 69 72 65 64 20 2a 2f 0a 20 20  y required */.  
db40: 69 6e 74 20 6e 50 4d 41 3b 20 20 20 20 20 20 20  int nPMA;       
db50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
db60: 2f 2a 20 42 79 74 65 73 20 6f 66 20 50 4d 41 20  /* Bytes of PMA 
db70: 73 70 61 63 65 20 72 65 71 75 69 72 65 64 20 2a  space required *
db80: 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 53 6f  /..  assert( pSo
db90: 72 74 65 72 20 29 3b 0a 0a 20 20 2f 2a 20 46 69  rter );..  /* Fi
dba0: 67 75 72 65 20 6f 75 74 20 77 68 65 74 68 65 72  gure out whether
dbb0: 20 6f 72 20 6e 6f 74 20 74 68 65 20 63 75 72 72   or not the curr
dbc0: 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  ent contents of 
dbd0: 6d 65 6d 6f 72 79 20 73 68 6f 75 6c 64 20 62 65  memory should be
dbe0: 0a 20 20 2a 2a 20 66 6c 75 73 68 65 64 20 74 6f  .  ** flushed to
dbf0: 20 61 20 50 4d 41 20 62 65 66 6f 72 65 20 63 6f   a PMA before co
dc00: 6e 74 69 6e 75 69 6e 67 2e 20 49 66 20 73 6f 2c  ntinuing. If so,
dc10: 20 64 6f 20 73 6f 2e 0a 20 20 2a 2a 0a 20 20 2a   do so..  **.  *
dc20: 2a 20 49 66 20 75 73 69 6e 67 20 74 68 65 20 73  * If using the s
dc30: 69 6e 67 6c 65 20 6c 61 72 67 65 20 61 6c 6c 6f  ingle large allo
dc40: 63 61 74 69 6f 6e 20 6d 6f 64 65 20 28 70 53 6f  cation mode (pSo
dc50: 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 21 3d 30  rter->aMemory!=0
dc60: 29 2c 20 74 68 65 6e 0a 20 20 2a 2a 20 66 6c 75  ), then.  ** flu
dc70: 73 68 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  sh the contents 
dc80: 6f 66 20 6d 65 6d 6f 72 79 20 74 6f 20 61 20 6e  of memory to a n
dc90: 65 77 20 50 4d 41 20 69 66 20 28 61 29 20 61 74  ew PMA if (a) at
dca0: 20 6c 65 61 73 74 20 6f 6e 65 20 76 61 6c 75 65   least one value
dcb0: 20 69 73 0a 20 20 2a 2a 20 61 6c 72 65 61 64 79   is.  ** already
dcc0: 20 69 6e 20 6d 65 6d 6f 72 79 20 61 6e 64 20 28   in memory and (
dcd0: 62 29 20 74 68 65 20 6e 65 77 20 76 61 6c 75 65  b) the new value
dce0: 20 77 69 6c 6c 20 6e 6f 74 20 66 69 74 20 69 6e   will not fit in
dcf0: 20 6d 65 6d 6f 72 79 2e 0a 20 20 2a 2a 20 0a 20   memory..  ** . 
dd00: 20 2a 2a 20 4f 72 2c 20 69 66 20 75 73 69 6e 67   ** Or, if using
dd10: 20 73 65 70 61 72 61 74 65 20 61 6c 6c 6f 63 61   separate alloca
dd20: 74 69 6f 6e 73 20 66 6f 72 20 65 61 63 68 20 72  tions for each r
dd30: 65 63 6f 72 64 2c 20 66 6c 75 73 68 20 74 68 65  ecord, flush the
dd40: 20 63 6f 6e 74 65 6e 74 73 0a 20 20 2a 2a 20 6f   contents.  ** o
dd50: 66 20 6d 65 6d 6f 72 79 20 74 6f 20 61 20 50 4d  f memory to a PM
dd60: 41 20 69 66 20 65 69 74 68 65 72 20 6f 66 20 74  A if either of t
dd70: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 72 65  he following are
dd80: 20 74 72 75 65 3a 0a 20 20 2a 2a 0a 20 20 2a 2a   true:.  **.  **
dd90: 20 20 20 2a 20 54 68 65 20 74 6f 74 61 6c 20 6d     * The total m
dda0: 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 65 64 20  emory allocated 
ddb0: 66 6f 72 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72  for the in-memor
ddc0: 79 20 6c 69 73 74 20 69 73 20 67 72 65 61 74 65  y list is greate
ddd0: 72 20 0a 20 20 2a 2a 20 20 20 20 20 74 68 61 6e  r .  **     than
dde0: 20 28 70 61 67 65 2d 73 69 7a 65 20 2a 20 63 61   (page-size * ca
ddf0: 63 68 65 2d 73 69 7a 65 29 2c 20 6f 72 0a 20 20  che-size), or.  
de00: 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 54 68 65 20  **.  **   * The 
de10: 74 6f 74 61 6c 20 6d 65 6d 6f 72 79 20 61 6c 6c  total memory all
de20: 6f 63 61 74 65 64 20 66 6f 72 20 74 68 65 20 69  ocated for the i
de30: 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20 69 73  n-memory list is
de40: 20 67 72 65 61 74 65 72 20 0a 20 20 2a 2a 20 20   greater .  **  
de50: 20 20 20 74 68 61 6e 20 28 70 61 67 65 2d 73 69     than (page-si
de60: 7a 65 20 2a 20 31 30 29 20 61 6e 64 20 73 71 6c  ze * 10) and sql
de70: 69 74 65 33 48 65 61 70 4e 65 61 72 6c 79 46 75  ite3HeapNearlyFu
de80: 6c 6c 28 29 20 72 65 74 75 72 6e 73 20 74 72 75  ll() returns tru
de90: 65 2e 0a 20 20 2a 2f 0a 20 20 6e 52 65 71 20 3d  e..  */.  nReq =
dea0: 20 70 56 61 6c 2d 3e 6e 20 2b 20 73 69 7a 65 6f   pVal->n + sizeo
deb0: 66 28 53 6f 72 74 65 72 52 65 63 6f 72 64 29 3b  f(SorterRecord);
dec0: 0a 20 20 6e 50 4d 41 20 3d 20 70 56 61 6c 2d 3e  .  nPMA = pVal->
ded0: 6e 20 2b 20 73 71 6c 69 74 65 33 56 61 72 69 6e  n + sqlite3Varin
dee0: 74 4c 65 6e 28 70 56 61 6c 2d 3e 6e 29 3b 0a 20  tLen(pVal->n);. 
def0: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6d 78   if( pSorter->mx
df00: 50 6d 61 53 69 7a 65 20 29 7b 0a 20 20 20 20 69  PmaSize ){.    i
df10: 66 28 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74  f( pSorter->list
df20: 2e 61 4d 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20  .aMemory ){.    
df30: 20 20 62 46 6c 75 73 68 20 3d 20 70 53 6f 72 74    bFlush = pSort
df40: 65 72 2d 3e 69 4d 65 6d 6f 72 79 20 26 26 20 28  er->iMemory && (
df50: 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79  pSorter->iMemory
df60: 2b 6e 52 65 71 29 20 3e 20 70 53 6f 72 74 65 72  +nReq) > pSorter
df70: 2d 3e 6d 78 50 6d 61 53 69 7a 65 3b 0a 20 20 20  ->mxPmaSize;.   
df80: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 62 46   }else{.      bF
df90: 6c 75 73 68 20 3d 20 28 0a 20 20 20 20 20 20 20  lush = (.       
dfa0: 20 20 20 28 70 53 6f 72 74 65 72 2d 3e 6c 69 73     (pSorter->lis
dfb0: 74 2e 73 7a 50 4d 41 20 3e 20 70 53 6f 72 74 65  t.szPMA > pSorte
dfc0: 72 2d 3e 6d 78 50 6d 61 53 69 7a 65 29 0a 20 20  r->mxPmaSize).  
dfd0: 20 20 20 20 20 7c 7c 20 28 70 53 6f 72 74 65 72       || (pSorter
dfe0: 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 3e 20 70  ->list.szPMA > p
dff0: 53 6f 72 74 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a  Sorter->mnPmaSiz
e000: 65 20 26 26 20 73 71 6c 69 74 65 33 48 65 61 70  e && sqlite3Heap
e010: 4e 65 61 72 6c 79 46 75 6c 6c 28 29 29 0a 20 20  NearlyFull()).  
e020: 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 20      );.    }.   
e030: 20 69 66 28 20 62 46 6c 75 73 68 20 29 7b 0a 20   if( bFlush ){. 
e040: 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f       rc = vdbeSo
e050: 72 74 65 72 46 6c 75 73 68 50 4d 41 28 70 53 6f  rterFlushPMA(pSo
e060: 72 74 65 72 29 3b 0a 20 20 20 20 20 20 70 53 6f  rter);.      pSo
e070: 72 74 65 72 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41  rter->list.szPMA
e080: 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 53 6f 72   = 0;.      pSor
e090: 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 20 3d 20 30  ter->iMemory = 0
e0a0: 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  ;.      assert( 
e0b0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c  rc!=SQLITE_OK ||
e0c0: 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70   pSorter->list.p
e0d0: 4c 69 73 74 3d 3d 30 20 29 3b 0a 20 20 20 20 7d  List==0 );.    }
e0e0: 0a 20 20 7d 0a 0a 20 20 70 53 6f 72 74 65 72 2d  .  }..  pSorter-
e0f0: 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 2b 3d 20 6e  >list.szPMA += n
e100: 50 4d 41 3b 0a 20 20 69 66 28 20 6e 50 4d 41 3e  PMA;.  if( nPMA>
e110: 70 53 6f 72 74 65 72 2d 3e 6d 78 4b 65 79 73 69  pSorter->mxKeysi
e120: 7a 65 20 29 7b 0a 20 20 20 20 70 53 6f 72 74 65  ze ){.    pSorte
e130: 72 2d 3e 6d 78 4b 65 79 73 69 7a 65 20 3d 20 6e  r->mxKeysize = n
e140: 50 4d 41 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  PMA;.  }..  if( 
e150: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d  pSorter->list.aM
e160: 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 69 6e 74  emory ){.    int
e170: 20 6e 4d 69 6e 20 3d 20 70 53 6f 72 74 65 72 2d   nMin = pSorter-
e180: 3e 69 4d 65 6d 6f 72 79 20 2b 20 6e 52 65 71 3b  >iMemory + nReq;
e190: 0a 0a 20 20 20 20 69 66 28 20 6e 4d 69 6e 3e 70  ..    if( nMin>p
e1a0: 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20  Sorter->nMemory 
e1b0: 29 7b 0a 20 20 20 20 20 20 75 38 20 2a 61 4e 65  ){.      u8 *aNe
e1c0: 77 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e 65  w;.      int nNe
e1d0: 77 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6e 4d 65  w = pSorter->nMe
e1e0: 6d 6f 72 79 20 2a 20 32 3b 0a 20 20 20 20 20 20  mory * 2;.      
e1f0: 77 68 69 6c 65 28 20 6e 4e 65 77 20 3c 20 6e 4d  while( nNew < nM
e200: 69 6e 20 29 20 6e 4e 65 77 20 3d 20 6e 4e 65 77  in ) nNew = nNew
e210: 2a 32 3b 0a 20 20 20 20 20 20 69 66 28 20 6e 4e  *2;.      if( nN
e220: 65 77 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 78  ew > pSorter->mx
e230: 50 6d 61 53 69 7a 65 20 29 20 6e 4e 65 77 20 3d  PmaSize ) nNew =
e240: 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53   pSorter->mxPmaS
e250: 69 7a 65 3b 0a 20 20 20 20 20 20 69 66 28 20 6e  ize;.      if( n
e260: 4e 65 77 20 3c 20 6e 4d 69 6e 20 29 20 6e 4e 65  New < nMin ) nNe
e270: 77 20 3d 20 6e 4d 69 6e 3b 0a 0a 20 20 20 20 20  w = nMin;..     
e280: 20 61 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 52   aNew = sqlite3R
e290: 65 61 6c 6c 6f 63 28 70 53 6f 72 74 65 72 2d 3e  ealloc(pSorter->
e2a0: 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 2c 20 6e 4e  list.aMemory, nN
e2b0: 65 77 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21  ew);.      if( !
e2c0: 61 4e 65 77 20 29 20 72 65 74 75 72 6e 20 53 51  aNew ) return SQ
e2d0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
e2e0: 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e    pSorter->list.
e2f0: 70 4c 69 73 74 20 3d 20 28 53 6f 72 74 65 72 52  pList = (SorterR
e300: 65 63 6f 72 64 2a 29 28 0a 20 20 20 20 20 20 20  ecord*)(.       
e310: 20 20 20 61 4e 65 77 20 2b 20 28 28 75 38 2a 29     aNew + ((u8*)
e320: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c  pSorter->list.pL
e330: 69 73 74 20 2d 20 70 53 6f 72 74 65 72 2d 3e 6c  ist - pSorter->l
e340: 69 73 74 2e 61 4d 65 6d 6f 72 79 29 0a 20 20 20  ist.aMemory).   
e350: 20 20 20 29 3b 0a 20 20 20 20 20 20 70 53 6f 72     );.      pSor
e360: 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72  ter->list.aMemor
e370: 79 20 3d 20 61 4e 65 77 3b 0a 20 20 20 20 20 20  y = aNew;.      
e380: 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79  pSorter->nMemory
e390: 20 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 7d 0a 0a   = nNew;.    }..
e3a0: 20 20 20 20 70 4e 65 77 20 3d 20 28 53 6f 72 74      pNew = (Sort
e3b0: 65 72 52 65 63 6f 72 64 2a 29 26 70 53 6f 72 74  erRecord*)&pSort
e3c0: 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  er->list.aMemory
e3d0: 5b 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72  [pSorter->iMemor
e3e0: 79 5d 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d  y];.    pSorter-
e3f0: 3e 69 4d 65 6d 6f 72 79 20 2b 3d 20 52 4f 55 4e  >iMemory += ROUN
e400: 44 38 28 6e 52 65 71 29 3b 0a 20 20 20 20 70 4e  D8(nReq);.    pN
e410: 65 77 2d 3e 75 2e 69 4e 65 78 74 20 3d 20 28 75  ew->u.iNext = (u
e420: 38 2a 29 28 70 53 6f 72 74 65 72 2d 3e 6c 69 73  8*)(pSorter->lis
e430: 74 2e 70 4c 69 73 74 29 20 2d 20 70 53 6f 72 74  t.pList) - pSort
e440: 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  er->list.aMemory
e450: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70  ;.  }else{.    p
e460: 4e 65 77 20 3d 20 28 53 6f 72 74 65 72 52 65 63  New = (SorterRec
e470: 6f 72 64 20 2a 29 73 71 6c 69 74 65 33 4d 61 6c  ord *)sqlite3Mal
e480: 6c 6f 63 28 6e 52 65 71 29 3b 0a 20 20 20 20 69  loc(nReq);.    i
e490: 66 28 20 70 4e 65 77 3d 3d 30 20 29 7b 0a 20 20  f( pNew==0 ){.  
e4a0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
e4b0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20  E_NOMEM;.    }. 
e4c0: 20 20 20 70 4e 65 77 2d 3e 75 2e 70 4e 65 78 74     pNew->u.pNext
e4d0: 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74   = pSorter->list
e4e0: 2e 70 4c 69 73 74 3b 0a 20 20 7d 0a 0a 20 20 6d  .pList;.  }..  m
e4f0: 65 6d 63 70 79 28 53 52 56 41 4c 28 70 4e 65 77  emcpy(SRVAL(pNew
e500: 29 2c 20 70 56 61 6c 2d 3e 7a 2c 20 70 56 61 6c  ), pVal->z, pVal
e510: 2d 3e 6e 29 3b 0a 20 20 70 4e 65 77 2d 3e 6e 56  ->n);.  pNew->nV
e520: 61 6c 20 3d 20 70 56 61 6c 2d 3e 6e 3b 0a 20 20  al = pVal->n;.  
e530: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c  pSorter->list.pL
e540: 69 73 74 20 3d 20 70 4e 65 77 3b 0a 0a 20 20 72  ist = pNew;..  r
e550: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
e560: 2a 2a 20 52 65 61 64 20 6b 65 79 73 20 66 72 6f  ** Read keys fro
e570: 6d 20 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65 72  m pIncr->pMerger
e580: 20 61 6e 64 20 70 6f 70 75 6c 61 74 65 20 70 49   and populate pI
e590: 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 2e 20 54  ncr->aFile[1]. T
e5a0: 68 65 20 66 6f 72 6d 61 74 0a 2a 2a 20 6f 66 20  he format.** of 
e5b0: 74 68 65 20 64 61 74 61 20 73 74 6f 72 65 64 20  the data stored 
e5c0: 69 6e 20 61 46 69 6c 65 5b 31 5d 20 69 73 20 74  in aFile[1] is t
e5d0: 68 65 20 73 61 6d 65 20 61 73 20 74 68 61 74 20  he same as that 
e5e0: 75 73 65 64 20 62 79 20 72 65 67 75 6c 61 72 20  used by regular 
e5f0: 50 4d 41 73 2c 0a 2a 2a 20 65 78 63 65 70 74 20  PMAs,.** except 
e600: 74 68 61 74 20 74 68 65 20 6e 75 6d 62 65 72 2d  that the number-
e610: 6f 66 2d 62 79 74 65 73 20 76 61 72 69 6e 74 20  of-bytes varint 
e620: 69 73 20 6f 6d 69 74 74 65 64 20 66 72 6f 6d 20  is omitted from 
e630: 74 68 65 20 73 74 61 72 74 2e 0a 2a 2f 0a 73 74  the start..*/.st
e640: 61 74 69 63 20 69 6e 74 20 76 64 62 65 49 6e 63  atic int vdbeInc
e650: 72 50 6f 70 75 6c 61 74 65 28 49 6e 63 72 4d 65  rPopulate(IncrMe
e660: 72 67 65 72 20 2a 70 49 6e 63 72 29 7b 0a 20 20  rger *pIncr){.  
e670: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
e680: 4f 4b 3b 0a 20 20 69 6e 74 20 72 63 32 3b 0a 20  OK;.  int rc2;. 
e690: 20 69 36 34 20 69 53 74 61 72 74 20 3d 20 70 49   i64 iStart = pI
e6a0: 6e 63 72 2d 3e 69 53 74 61 72 74 4f 66 66 3b 0a  ncr->iStartOff;.
e6b0: 20 20 53 6f 72 74 65 72 46 69 6c 65 20 2a 70 4f    SorterFile *pO
e6c0: 75 74 20 3d 20 26 70 49 6e 63 72 2d 3e 61 46 69  ut = &pIncr->aFi
e6d0: 6c 65 5b 31 5d 3b 0a 20 20 53 6f 72 74 53 75 62  le[1];.  SortSub
e6e0: 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20 70 49  task *pTask = pI
e6f0: 6e 63 72 2d 3e 70 54 61 73 6b 3b 0a 20 20 4d 65  ncr->pTask;.  Me
e700: 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67  rgeEngine *pMerg
e710: 65 72 20 3d 20 70 49 6e 63 72 2d 3e 70 4d 65 72  er = pIncr->pMer
e720: 67 65 72 3b 0a 20 20 50 6d 61 57 72 69 74 65 72  ger;.  PmaWriter
e730: 20 77 72 69 74 65 72 3b 0a 20 20 61 73 73 65 72   writer;.  asser
e740: 74 28 20 70 49 6e 63 72 2d 3e 62 45 6f 66 3d 3d  t( pIncr->bEof==
e750: 30 20 29 3b 0a 0a 20 20 76 64 62 65 53 6f 72 74  0 );..  vdbeSort
e760: 65 72 50 6f 70 75 6c 61 74 65 44 65 62 75 67 28  erPopulateDebug(
e770: 70 54 61 73 6b 2c 20 22 65 6e 74 65 72 22 29 3b  pTask, "enter");
e780: 0a 0a 20 20 76 64 62 65 50 6d 61 57 72 69 74 65  ..  vdbePmaWrite
e790: 72 49 6e 69 74 28 70 4f 75 74 2d 3e 70 46 64 2c  rInit(pOut->pFd,
e7a0: 20 26 77 72 69 74 65 72 2c 20 70 54 61 73 6b 2d   &writer, pTask-
e7b0: 3e 70 53 6f 72 74 65 72 2d 3e 70 67 73 7a 2c 20  >pSorter->pgsz, 
e7c0: 69 53 74 61 72 74 29 3b 0a 20 20 77 68 69 6c 65  iStart);.  while
e7d0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
e7e0: 29 7b 0a 20 20 20 20 69 6e 74 20 64 75 6d 6d 79  ){.    int dummy
e7f0: 3b 0a 20 20 20 20 50 6d 61 52 65 61 64 65 72 20  ;.    PmaReader 
e800: 2a 70 52 65 61 64 65 72 20 3d 20 26 70 4d 65 72  *pReader = &pMer
e810: 67 65 72 2d 3e 61 49 74 65 72 5b 20 70 4d 65 72  ger->aIter[ pMer
e820: 67 65 72 2d 3e 61 54 72 65 65 5b 31 5d 20 5d 3b  ger->aTree[1] ];
e830: 0a 20 20 20 20 69 6e 74 20 6e 4b 65 79 20 3d 20  .    int nKey = 
e840: 70 52 65 61 64 65 72 2d 3e 6e 4b 65 79 3b 0a 20  pReader->nKey;. 
e850: 20 20 20 69 36 34 20 69 45 6f 66 20 3d 20 77 72     i64 iEof = wr
e860: 69 74 65 72 2e 69 57 72 69 74 65 4f 66 66 20 2b  iter.iWriteOff +
e870: 20 77 72 69 74 65 72 2e 69 42 75 66 45 6e 64 3b   writer.iBufEnd;
e880: 0a 0a 20 20 20 20 2f 2a 20 43 68 65 63 6b 20 69  ..    /* Check i
e890: 66 20 74 68 65 20 6f 75 74 70 75 74 20 66 69 6c  f the output fil
e8a0: 65 20 69 73 20 66 75 6c 6c 20 6f 72 20 69 66 20  e is full or if 
e8b0: 74 68 65 20 69 6e 70 75 74 20 68 61 73 20 62 65  the input has be
e8c0: 65 6e 20 65 78 68 61 75 73 74 65 64 2e 0a 20 20  en exhausted..  
e8d0: 20 20 2a 2a 20 49 6e 20 65 69 74 68 65 72 20 63    ** In either c
e8e0: 61 73 65 20 65 78 69 74 20 74 68 65 20 6c 6f 6f  ase exit the loo
e8f0: 70 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 52  p. */.    if( pR
e900: 65 61 64 65 72 2d 3e 70 46 69 6c 65 3d 3d 30 20  eader->pFile==0 
e910: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 69 66 28  ) break;.    if(
e920: 20 28 69 45 6f 66 20 2b 20 6e 4b 65 79 20 2b 20   (iEof + nKey + 
e930: 73 71 6c 69 74 65 33 56 61 72 69 6e 74 4c 65 6e  sqlite3VarintLen
e940: 28 6e 4b 65 79 29 29 3e 28 69 53 74 61 72 74 20  (nKey))>(iStart 
e950: 2b 20 70 49 6e 63 72 2d 3e 6d 78 53 7a 29 20 29  + pIncr->mxSz) )
e960: 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 2f 2a 20   break;..    /* 
e970: 57 72 69 74 65 20 74 68 65 20 6e 65 78 74 20 6b  Write the next k
e980: 65 79 20 74 6f 20 74 68 65 20 6f 75 74 70 75 74  ey to the output
e990: 2e 20 2a 2f 0a 20 20 20 20 76 64 62 65 50 6d 61  . */.    vdbePma
e9a0: 57 72 69 74 65 56 61 72 69 6e 74 28 26 77 72 69  WriteVarint(&wri
e9b0: 74 65 72 2c 20 6e 4b 65 79 29 3b 0a 20 20 20 20  ter, nKey);.    
e9c0: 76 64 62 65 50 6d 61 57 72 69 74 65 42 6c 6f 62  vdbePmaWriteBlob
e9d0: 28 26 77 72 69 74 65 72 2c 20 70 52 65 61 64 65  (&writer, pReade
e9e0: 72 2d 3e 61 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a  r->aKey, nKey);.
e9f0: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
ea00: 74 65 72 4e 65 78 74 28 70 54 61 73 6b 2c 20 70  terNext(pTask, p
ea10: 49 6e 63 72 2d 3e 70 4d 65 72 67 65 72 2c 20 26  Incr->pMerger, &
ea20: 64 75 6d 6d 79 29 3b 0a 20 20 7d 0a 0a 20 20 72  dummy);.  }..  r
ea30: 63 32 20 3d 20 76 64 62 65 50 6d 61 57 72 69 74  c2 = vdbePmaWrit
ea40: 65 72 46 69 6e 69 73 68 28 26 77 72 69 74 65 72  erFinish(&writer
ea50: 2c 20 26 70 4f 75 74 2d 3e 69 45 6f 66 29 3b 0a  , &pOut->iEof);.
ea60: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
ea70: 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63 32 3b 0a  _OK ) rc = rc2;.
ea80: 20 20 76 64 62 65 53 6f 72 74 65 72 50 6f 70 75    vdbeSorterPopu
ea90: 6c 61 74 65 44 65 62 75 67 28 70 54 61 73 6b 2c  lateDebug(pTask,
eaa0: 20 22 65 78 69 74 22 29 3b 0a 20 20 72 65 74 75   "exit");.  retu
eab0: 72 6e 20 72 63 3b 0a 7d 0a 0a 23 69 66 20 53 51  rn rc;.}..#if SQ
eac0: 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f  LITE_MAX_WORKER_
ead0: 54 48 52 45 41 44 53 3e 30 0a 2f 2a 0a 2a 2a 20  THREADS>0./*.** 
eae0: 54 68 65 20 6d 61 69 6e 20 72 6f 75 74 69 6e 65  The main routine
eaf0: 20 66 6f 72 20 62 61 63 6b 67 72 6f 75 6e 64 20   for background 
eb00: 74 68 72 65 61 64 73 20 74 68 61 74 20 70 6f 70  threads that pop
eb10: 75 6c 61 74 65 20 61 46 69 6c 65 5b 31 5d 20 6f  ulate aFile[1] o
eb20: 66 0a 2a 2a 20 6d 75 6c 74 69 2d 74 68 72 65 61  f.** multi-threa
eb30: 64 65 64 20 49 6e 63 72 4d 65 72 67 65 72 20 6f  ded IncrMerger o
eb40: 62 6a 65 63 74 73 2e 0a 2a 2f 0a 73 74 61 74 69  bjects..*/.stati
eb50: 63 20 76 6f 69 64 20 2a 76 64 62 65 49 6e 63 72  c void *vdbeIncr
eb60: 50 6f 70 75 6c 61 74 65 54 68 72 65 61 64 28 76  PopulateThread(v
eb70: 6f 69 64 20 2a 70 43 74 78 29 7b 0a 20 20 49 6e  oid *pCtx){.  In
eb80: 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 20  crMerger *pIncr 
eb90: 3d 20 28 49 6e 63 72 4d 65 72 67 65 72 2a 29 70  = (IncrMerger*)p
eba0: 43 74 78 3b 0a 20 20 76 6f 69 64 20 2a 70 52 65  Ctx;.  void *pRe
ebb0: 74 20 3d 20 53 51 4c 49 54 45 5f 49 4e 54 5f 54  t = SQLITE_INT_T
ebc0: 4f 5f 50 54 52 28 20 76 64 62 65 49 6e 63 72 50  O_PTR( vdbeIncrP
ebd0: 6f 70 75 6c 61 74 65 28 70 49 6e 63 72 29 20 29  opulate(pIncr) )
ebe0: 3b 0a 20 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b  ;.  pIncr->pTask
ebf0: 2d 3e 62 44 6f 6e 65 20 3d 20 31 3b 0a 20 20 72  ->bDone = 1;.  r
ec00: 65 74 75 72 6e 20 70 52 65 74 3b 0a 7d 0a 0a 2f  eturn pRet;.}../
ec10: 2a 0a 2a 2a 20 4c 61 75 6e 63 68 20 61 20 62 61  *.** Launch a ba
ec20: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
ec30: 74 6f 20 70 6f 70 75 6c 61 74 65 20 61 46 69 6c  to populate aFil
ec40: 65 5b 31 5d 20 6f 66 20 70 49 6e 63 72 2e 0a 2a  e[1] of pIncr..*
ec50: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
ec60: 65 49 6e 63 72 42 67 50 6f 70 75 6c 61 74 65 28  eIncrBgPopulate(
ec70: 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63  IncrMerger *pInc
ec80: 72 29 7b 0a 20 20 76 6f 69 64 20 2a 70 20 3d 20  r){.  void *p = 
ec90: 28 76 6f 69 64 2a 29 70 49 6e 63 72 3b 0a 20 20  (void*)pIncr;.  
eca0: 61 73 73 65 72 74 28 20 70 49 6e 63 72 2d 3e 62  assert( pIncr->b
ecb0: 55 73 65 54 68 72 65 61 64 20 29 3b 0a 20 20 72  UseThread );.  r
ecc0: 65 74 75 72 6e 20 76 64 62 65 53 6f 72 74 65 72  eturn vdbeSorter
ecd0: 43 72 65 61 74 65 54 68 72 65 61 64 28 70 49 6e  CreateThread(pIn
ece0: 63 72 2d 3e 70 54 61 73 6b 2c 20 76 64 62 65 49  cr->pTask, vdbeI
ecf0: 6e 63 72 50 6f 70 75 6c 61 74 65 54 68 72 65 61  ncrPopulateThrea
ed00: 64 2c 20 70 29 3b 0a 7d 0a 23 65 6e 64 69 66 0a  d, p);.}.#endif.
ed10: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
ed20: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 77  tion is called w
ed30: 68 65 6e 20 74 68 65 20 50 6d 61 52 65 61 64 65  hen the PmaReade
ed40: 72 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20  r corresponding 
ed50: 74 6f 20 70 49 6e 63 72 20 68 61 73 0a 2a 2a 20  to pIncr has.** 
ed60: 66 69 6e 69 73 68 65 64 20 72 65 61 64 69 6e 67  finished reading
ed70: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
ed80: 20 61 46 69 6c 65 5b 30 5d 2e 20 49 74 73 20 70   aFile[0]. Its p
ed90: 75 72 70 6f 73 65 20 69 73 20 74 6f 20 22 72 65  urpose is to "re
eda0: 66 69 6c 6c 22 0a 2a 2a 20 61 46 69 6c 65 5b 30  fill".** aFile[0
edb0: 5d 20 73 75 63 68 20 74 68 61 74 20 74 68 65 20  ] such that the 
edc0: 69 74 65 72 61 74 6f 72 20 73 68 6f 75 6c 64 20  iterator should 
edd0: 73 74 61 72 74 20 72 65 72 65 61 64 69 6e 67 20  start rereading 
ede0: 69 74 20 66 72 6f 6d 20 74 68 65 0a 2a 2a 20 62  it from the.** b
edf0: 65 67 69 6e 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20  eginning..**.** 
ee00: 46 6f 72 20 73 69 6e 67 6c 65 2d 74 68 72 65 61  For single-threa
ee10: 64 65 64 20 6f 62 6a 65 63 74 73 2c 20 74 68 69  ded objects, thi
ee20: 73 20 69 73 20 61 63 63 6f 6d 70 6c 69 73 68 65  s is accomplishe
ee30: 64 20 62 79 20 6c 69 74 65 72 61 6c 6c 79 20 72  d by literally r
ee40: 65 61 64 69 6e 67 20 0a 2a 2a 20 6b 65 79 73 20  eading .** keys 
ee50: 66 72 6f 6d 20 70 49 6e 63 72 2d 3e 70 4d 65 72  from pIncr->pMer
ee60: 67 65 72 20 61 6e 64 20 72 65 70 6f 70 75 6c 61  ger and repopula
ee70: 74 69 6e 67 20 61 46 69 6c 65 5b 30 5d 2e 20 0a  ting aFile[0]. .
ee80: 2a 2a 0a 2a 2a 20 46 6f 72 20 6d 75 6c 74 69 2d  **.** For multi-
ee90: 74 68 72 65 61 64 65 64 20 6f 62 6a 65 63 74 73  threaded objects
eea0: 2c 20 61 6c 6c 20 74 68 61 74 20 69 73 20 72 65  , all that is re
eeb0: 71 75 69 72 65 64 20 69 73 20 74 6f 20 77 61 69  quired is to wai
eec0: 74 20 75 6e 74 69 6c 20 74 68 65 20 0a 2a 2a 20  t until the .** 
eed0: 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61  background threa
eee0: 64 20 69 73 20 66 69 6e 69 73 68 65 64 20 28 69  d is finished (i
eef0: 66 20 69 74 20 69 73 20 6e 6f 74 20 61 6c 72 65  f it is not alre
ef00: 61 64 79 29 20 61 6e 64 20 74 68 65 6e 20 73 77  ady) and then sw
ef10: 61 70 20 0a 2a 2a 20 61 46 69 6c 65 5b 30 5d 20  ap .** aFile[0] 
ef20: 61 6e 64 20 61 46 69 6c 65 5b 31 5d 20 69 6e 20  and aFile[1] in 
ef30: 70 6c 61 63 65 2e 20 49 66 20 74 68 65 20 63 6f  place. If the co
ef40: 6e 74 65 6e 74 73 20 6f 66 20 70 4d 65 72 67 65  ntents of pMerge
ef50: 72 20 68 61 76 65 20 6e 6f 74 0a 2a 2a 20 62 65  r have not.** be
ef60: 65 6e 20 65 78 68 61 75 73 74 65 64 2c 20 74 68  en exhausted, th
ef70: 69 73 20 66 75 6e 63 74 69 6f 6e 20 61 6c 73 6f  is function also
ef80: 20 6c 61 75 6e 63 68 65 73 20 61 20 6e 65 77 20   launches a new 
ef90: 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61  background threa
efa0: 64 0a 2a 2a 20 74 6f 20 70 6f 70 75 6c 61 74 65  d.** to populate
efb0: 20 74 68 65 20 6e 65 77 20 61 46 69 6c 65 5b 31   the new aFile[1
efc0: 5d 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f  ]..**.** SQLITE_
efd0: 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 6f  OK is returned o
efe0: 6e 20 73 75 63 63 65 73 73 2c 20 6f 72 20 61 6e  n success, or an
eff0: 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
f000: 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f  de otherwise..*/
f010: 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65  .static int vdbe
f020: 49 6e 63 72 53 77 61 70 28 49 6e 63 72 4d 65 72  IncrSwap(IncrMer
f030: 67 65 72 20 2a 70 49 6e 63 72 29 7b 0a 20 20 69  ger *pIncr){.  i
f040: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
f050: 4b 3b 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d  K;..#if SQLITE_M
f060: 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44  AX_WORKER_THREAD
f070: 53 3e 30 0a 20 20 69 66 28 20 70 49 6e 63 72 2d  S>0.  if( pIncr-
f080: 3e 62 55 73 65 54 68 72 65 61 64 20 29 7b 0a 20  >bUseThread ){. 
f090: 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74     rc = vdbeSort
f0a0: 65 72 4a 6f 69 6e 54 68 72 65 61 64 28 70 49 6e  erJoinThread(pIn
f0b0: 63 72 2d 3e 70 54 61 73 6b 29 3b 0a 0a 20 20 20  cr->pTask);..   
f0c0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
f0d0: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 53 6f 72 74  OK ){.      Sort
f0e0: 65 72 46 69 6c 65 20 66 30 20 3d 20 70 49 6e 63  erFile f0 = pInc
f0f0: 72 2d 3e 61 46 69 6c 65 5b 30 5d 3b 0a 20 20 20  r->aFile[0];.   
f100: 20 20 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b     pIncr->aFile[
f110: 30 5d 20 3d 20 70 49 6e 63 72 2d 3e 61 46 69 6c  0] = pIncr->aFil
f120: 65 5b 31 5d 3b 0a 20 20 20 20 20 20 70 49 6e 63  e[1];.      pInc
f130: 72 2d 3e 61 46 69 6c 65 5b 31 5d 20 3d 20 66 30  r->aFile[1] = f0
f140: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  ;.    }..    if(
f150: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
f160: 7b 0a 20 20 20 20 20 20 69 66 28 20 70 49 6e 63  {.      if( pInc
f170: 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e 69 45 6f 66  r->aFile[0].iEof
f180: 3d 3d 70 49 6e 63 72 2d 3e 69 53 74 61 72 74 4f  ==pIncr->iStartO
f190: 66 66 20 29 7b 0a 20 20 20 20 20 20 20 20 70 49  ff ){.        pI
f1a0: 6e 63 72 2d 3e 62 45 6f 66 20 3d 20 31 3b 0a 20  ncr->bEof = 1;. 
f1b0: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
f1c0: 20 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63      rc = vdbeInc
f1d0: 72 42 67 50 6f 70 75 6c 61 74 65 28 70 49 6e 63  rBgPopulate(pInc
f1e0: 72 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  r);.      }.    
f1f0: 7d 0a 20 20 7d 65 6c 73 65 0a 23 65 6e 64 69 66  }.  }else.#endif
f200: 0a 20 20 7b 0a 20 20 20 20 72 63 20 3d 20 76 64  .  {.    rc = vd
f210: 62 65 49 6e 63 72 50 6f 70 75 6c 61 74 65 28 70  beIncrPopulate(p
f220: 49 6e 63 72 29 3b 0a 20 20 20 20 70 49 6e 63 72  Incr);.    pIncr
f230: 2d 3e 61 46 69 6c 65 5b 30 5d 20 3d 20 70 49 6e  ->aFile[0] = pIn
f240: 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 3b 0a 20 20  cr->aFile[1];.  
f250: 20 20 69 66 28 20 70 49 6e 63 72 2d 3e 61 46 69    if( pIncr->aFi
f260: 6c 65 5b 30 5d 2e 69 45 6f 66 3d 3d 70 49 6e 63  le[0].iEof==pInc
f270: 72 2d 3e 69 53 74 61 72 74 4f 66 66 20 29 7b 0a  r->iStartOff ){.
f280: 20 20 20 20 20 20 70 49 6e 63 72 2d 3e 62 45 6f        pIncr->bEo
f290: 66 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d  f = 1;.    }.  }
f2a0: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
f2b0: 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65  ../*.** Allocate
f2c0: 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20 6e 65   and return a ne
f2d0: 77 20 49 6e 63 72 4d 65 72 67 65 72 20 6f 62 6a  w IncrMerger obj
f2e0: 65 63 74 20 74 6f 20 72 65 61 64 20 64 61 74 61  ect to read data
f2f0: 20 66 72 6f 6d 20 70 4d 65 72 67 65 72 2e 0a 2a   from pMerger..*
f300: 2a 0a 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 63  *.** If an OOM c
f310: 6f 6e 64 69 74 69 6f 6e 20 69 73 20 65 6e 63 6f  ondition is enco
f320: 75 6e 74 65 72 65 64 2c 20 72 65 74 75 72 6e 20  untered, return 
f330: 4e 55 4c 4c 2e 20 49 6e 20 74 68 69 73 20 63 61  NULL. In this ca
f340: 73 65 20 66 72 65 65 20 74 68 65 0a 2a 2a 20 70  se free the.** p
f350: 4d 65 72 67 65 72 20 61 72 67 75 6d 65 6e 74 20  Merger argument 
f360: 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  before returning
f370: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
f380: 76 64 62 65 49 6e 63 72 4e 65 77 28 0a 20 20 53  vdbeIncrNew(.  S
f390: 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
f3a0: 6b 2c 20 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e  k, .  MergeEngin
f3b0: 65 20 2a 70 4d 65 72 67 65 72 2c 0a 20 20 49 6e  e *pMerger,.  In
f3c0: 63 72 4d 65 72 67 65 72 20 2a 2a 70 70 4f 75 74  crMerger **ppOut
f3d0: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
f3e0: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 49 6e 63 72  QLITE_OK;.  Incr
f3f0: 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 20 3d 20  Merger *pIncr = 
f400: 2a 70 70 4f 75 74 20 3d 20 28 49 6e 63 72 4d 65  *ppOut = (IncrMe
f410: 72 67 65 72 2a 29 73 71 6c 69 74 65 33 5f 6d 61  rger*)sqlite3_ma
f420: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 49 6e 63 72  lloc(sizeof(Incr
f430: 4d 65 72 67 65 72 29 29 3b 0a 20 20 69 66 28 20  Merger));.  if( 
f440: 70 49 6e 63 72 20 29 7b 0a 20 20 20 20 6d 65 6d  pIncr ){.    mem
f450: 73 65 74 28 70 49 6e 63 72 2c 20 30 2c 20 73 69  set(pIncr, 0, si
f460: 7a 65 6f 66 28 49 6e 63 72 4d 65 72 67 65 72 29  zeof(IncrMerger)
f470: 29 3b 0a 20 20 20 20 70 49 6e 63 72 2d 3e 70 4d  );.    pIncr->pM
f480: 65 72 67 65 72 20 3d 20 70 4d 65 72 67 65 72 3b  erger = pMerger;
f490: 0a 20 20 20 20 70 49 6e 63 72 2d 3e 70 54 61 73  .    pIncr->pTas
f4a0: 6b 20 3d 20 70 54 61 73 6b 3b 0a 20 20 20 20 70  k = pTask;.    p
f4b0: 49 6e 63 72 2d 3e 6d 78 53 7a 20 3d 20 4d 41 58  Incr->mxSz = MAX
f4c0: 28 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d  (pTask->pSorter-
f4d0: 3e 6d 78 4b 65 79 73 69 7a 65 2b 39 2c 70 54 61  >mxKeysize+9,pTa
f4e0: 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 6d 78 50  sk->pSorter->mxP
f4f0: 6d 61 53 69 7a 65 2f 32 29 3b 0a 20 20 20 20 70  maSize/2);.    p
f500: 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66  Task->file2.iEof
f510: 20 2b 3d 20 70 49 6e 63 72 2d 3e 6d 78 53 7a 3b   += pIncr->mxSz;
f520: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 76 64  .  }else{.    vd
f530: 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46 72 65  beMergeEngineFre
f540: 65 28 70 4d 65 72 67 65 72 29 3b 0a 20 20 20 20  e(pMerger);.    
f550: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
f560: 4d 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  M;.  }.  return 
f570: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74  rc;.}../*.** Set
f580: 20 74 68 65 20 22 75 73 65 2d 74 68 72 65 61 64   the "use-thread
f590: 73 22 20 66 6c 61 67 20 6f 6e 20 6f 62 6a 65 63  s" flag on objec
f5a0: 74 20 70 49 6e 63 72 2e 0a 2a 2f 0a 73 74 61 74  t pIncr..*/.stat
f5b0: 69 63 20 76 6f 69 64 20 76 64 62 65 49 6e 63 72  ic void vdbeIncr
f5c0: 53 65 74 54 68 72 65 61 64 73 28 49 6e 63 72 4d  SetThreads(IncrM
f5d0: 65 72 67 65 72 20 2a 70 49 6e 63 72 2c 20 69 6e  erger *pIncr, in
f5e0: 74 20 62 55 73 65 54 68 72 65 61 64 29 7b 0a 20  t bUseThread){. 
f5f0: 20 69 66 28 20 62 55 73 65 54 68 72 65 61 64 20   if( bUseThread 
f600: 29 7b 0a 20 20 20 20 70 49 6e 63 72 2d 3e 62 55  ){.    pIncr->bU
f610: 73 65 54 68 72 65 61 64 20 3d 20 31 3b 0a 20 20  seThread = 1;.  
f620: 20 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b 2d 3e    pIncr->pTask->
f630: 66 69 6c 65 32 2e 69 45 6f 66 20 2d 3d 20 70 49  file2.iEof -= pI
f640: 6e 63 72 2d 3e 6d 78 53 7a 3b 0a 20 20 7d 0a 7d  ncr->mxSz;.  }.}
f650: 0a 0a 23 64 65 66 69 6e 65 20 49 4e 43 52 49 4e  ..#define INCRIN
f660: 49 54 32 5f 4e 4f 52 4d 41 4c 20 30 0a 23 64 65  IT2_NORMAL 0.#de
f670: 66 69 6e 65 20 49 4e 43 52 49 4e 49 54 32 5f 54  fine INCRINIT2_T
f680: 41 53 4b 20 20 20 31 0a 23 64 65 66 69 6e 65 20  ASK   1.#define 
f690: 49 4e 43 52 49 4e 49 54 32 5f 52 4f 4f 54 20 20  INCRINIT2_ROOT  
f6a0: 20 32 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64   2.static int vd
f6b0: 62 65 50 6d 61 52 65 61 64 65 72 49 6e 63 72 49  bePmaReaderIncrI
f6c0: 6e 69 74 28 50 6d 61 52 65 61 64 65 72 20 2a 70  nit(PmaReader *p
f6d0: 49 74 65 72 2c 20 69 6e 74 20 65 4d 6f 64 65 29  Iter, int eMode)
f6e0: 3b 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c  ;../*.** Initial
f6f0: 69 7a 65 20 74 68 65 20 6d 65 72 67 65 72 20 61  ize the merger a
f700: 72 67 75 6d 65 6e 74 20 70 61 73 73 65 64 20 61  rgument passed a
f710: 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67  s the second arg
f720: 75 6d 65 6e 74 2e 20 4f 6e 63 65 20 74 68 69 73  ument. Once this
f730: 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 72 65 74  .** function ret
f740: 75 72 6e 73 2c 20 74 68 65 20 66 69 72 73 74 20  urns, the first 
f750: 6b 65 79 20 6f 66 20 6d 65 72 67 65 64 20 64 61  key of merged da
f760: 74 61 20 6d 61 79 20 62 65 20 72 65 61 64 20 66  ta may be read f
f770: 72 6f 6d 20 74 68 65 20 6d 65 72 67 65 72 0a 2a  rom the merger.*
f780: 2a 20 6f 62 6a 65 63 74 20 69 6e 20 74 68 65 20  * object in the 
f790: 75 73 75 61 6c 20 66 61 73 68 69 6f 6e 2e 0a 2a  usual fashion..*
f7a0: 2a 0a 2a 2a 20 49 66 20 61 72 67 75 6d 65 6e 74  *.** If argument
f7b0: 20 65 4d 6f 64 65 20 69 73 20 49 4e 43 52 49 4e   eMode is INCRIN
f7c0: 49 54 32 5f 52 4f 4f 54 2c 20 74 68 65 6e 20 69  IT2_ROOT, then i
f7d0: 74 20 69 73 20 61 73 73 75 6d 65 64 20 74 68 61  t is assumed tha
f7e0: 74 20 61 6e 79 20 49 6e 63 72 4d 65 72 67 65 0a  t any IncrMerge.
f7f0: 2a 2a 20 6f 62 6a 65 63 74 73 20 61 74 74 61 63  ** objects attac
f800: 68 65 64 20 74 6f 20 74 68 65 20 50 6d 61 52 65  hed to the PmaRe
f810: 61 64 65 72 20 6f 62 6a 65 63 74 73 20 74 68 61  ader objects tha
f820: 74 20 74 68 65 20 6d 65 72 67 65 72 20 72 65 61  t the merger rea
f830: 64 73 20 66 72 6f 6d 20 68 61 76 65 0a 2a 2a 20  ds from have.** 
f840: 61 6c 72 65 61 64 79 20 62 65 65 6e 20 70 6f 70  already been pop
f850: 75 6c 61 74 65 64 2c 20 62 75 74 20 74 68 61 74  ulated, but that
f860: 20 74 68 65 79 20 68 61 76 65 20 6e 6f 74 20 79   they have not y
f870: 65 74 20 70 6f 70 75 6c 61 74 65 64 20 61 46 69  et populated aFi
f880: 6c 65 5b 30 5d 20 61 6e 64 0a 2a 2a 20 73 65 74  le[0] and.** set
f890: 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 20 6f   the PmaReader o
f8a0: 62 6a 65 63 74 73 20 75 70 20 74 6f 20 72 65 61  bjects up to rea
f8b0: 64 20 66 72 6f 6d 20 69 74 2e 20 49 6e 20 74 68  d from it. In th
f8c0: 69 73 20 63 61 73 65 20 61 6c 6c 20 74 68 61 74  is case all that
f8d0: 20 69 73 0a 2a 2a 20 72 65 71 75 69 72 65 64 20   is.** required 
f8e0: 69 73 20 74 6f 20 63 61 6c 6c 20 76 64 62 65 50  is to call vdbeP
f8f0: 6d 61 52 65 61 64 65 72 4e 65 78 74 28 29 20 6f  maReaderNext() o
f900: 6e 20 65 61 63 68 20 69 74 65 72 61 74 6f 72 20  n each iterator 
f910: 74 6f 20 70 6f 69 6e 74 20 69 74 20 61 74 0a 2a  to point it at.*
f920: 2a 20 69 74 73 20 66 69 72 73 74 20 6b 65 79 2e  * its first key.
f930: 0a 2a 2a 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65  .**.** Otherwise
f940: 2c 20 69 66 20 65 4d 6f 64 65 20 69 73 20 61 6e  , if eMode is an
f950: 79 20 76 61 6c 75 65 20 6f 74 68 65 72 20 74 68  y value other th
f960: 61 6e 20 49 4e 43 52 49 4e 49 54 32 5f 52 4f 4f  an INCRINIT2_ROO
f970: 54 2c 20 74 68 65 6e 20 75 73 65 20 0a 2a 2a 20  T, then use .** 
f980: 76 64 62 65 50 6d 61 52 65 61 64 65 72 49 6e 63  vdbePmaReaderInc
f990: 72 49 6e 69 74 28 29 20 74 6f 20 69 6e 69 74 69  rInit() to initi
f9a0: 61 6c 69 7a 65 20 65 61 63 68 20 50 6d 61 52 65  alize each PmaRe
f9b0: 61 64 65 72 20 74 68 61 74 20 66 65 65 64 73 20  ader that feeds 
f9c0: 64 61 74 61 20 0a 2a 2a 20 74 6f 20 70 4d 65 72  data .** to pMer
f9d0: 67 65 72 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54  ger..**.** SQLIT
f9e0: 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64  E_OK is returned
f9f0: 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   if successful, 
fa00: 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  or an SQLite err
fa10: 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77 69 73  or code otherwis
fa20: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
fa30: 20 76 64 62 65 49 6e 63 72 49 6e 69 74 4d 65 72   vdbeIncrInitMer
fa40: 67 65 72 28 0a 20 20 53 6f 72 74 53 75 62 74 61  ger(.  SortSubta
fa50: 73 6b 20 2a 70 54 61 73 6b 2c 20 0a 20 20 4d 65  sk *pTask, .  Me
fa60: 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67  rgeEngine *pMerg
fa70: 65 72 2c 20 0a 20 20 69 6e 74 20 65 4d 6f 64 65  er, .  int eMode
fa80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fa90: 20 20 20 20 20 20 20 2f 2a 20 4f 6e 65 20 6f 66         /* One of
faa0: 20 74 68 65 20 49 4e 43 52 49 4e 49 54 32 5f 58   the INCRINIT2_X
fab0: 58 58 20 63 6f 6e 73 74 61 6e 74 73 20 2a 2f 0a  XX constants */.
fac0: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
fad0: 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20  LITE_OK;        
fae0: 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
faf0: 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20  ode */.  int i; 
fb00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fb10: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6f 72 20           /* For 
fb20: 69 74 65 72 61 74 69 6e 67 20 74 68 72 6f 75 67  iterating throug
fb30: 68 20 50 6d 61 52 65 61 64 65 72 20 6f 62 6a 65  h PmaReader obje
fb40: 63 74 73 20 2a 2f 0a 0a 20 20 66 6f 72 28 69 3d  cts */..  for(i=
fb50: 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  0; rc==SQLITE_OK
fb60: 20 26 26 20 69 3c 70 4d 65 72 67 65 72 2d 3e 6e   && i<pMerger->n
fb70: 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  Tree; i++){.    
fb80: 69 66 28 20 65 4d 6f 64 65 3d 3d 49 4e 43 52 49  if( eMode==INCRI
fb90: 4e 49 54 32 5f 52 4f 4f 54 20 29 7b 0a 20 20 20  NIT2_ROOT ){.   
fba0: 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52     rc = vdbePmaR
fbb0: 65 61 64 65 72 4e 65 78 74 28 26 70 4d 65 72 67  eaderNext(&pMerg
fbc0: 65 72 2d 3e 61 49 74 65 72 5b 69 5d 29 3b 0a 20  er->aIter[i]);. 
fbd0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
fbe0: 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64  rc = vdbePmaRead
fbf0: 65 72 49 6e 63 72 49 6e 69 74 28 26 70 4d 65 72  erIncrInit(&pMer
fc00: 67 65 72 2d 3e 61 49 74 65 72 5b 69 5d 2c 20 49  ger->aIter[i], I
fc10: 4e 43 52 49 4e 49 54 32 5f 4e 4f 52 4d 41 4c 29  NCRINIT2_NORMAL)
fc20: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 66  ;.    }.  }..  f
fc30: 6f 72 28 69 3d 70 4d 65 72 67 65 72 2d 3e 6e 54  or(i=pMerger->nT
fc40: 72 65 65 2d 31 3b 20 72 63 3d 3d 53 51 4c 49 54  ree-1; rc==SQLIT
fc50: 45 5f 4f 4b 20 26 26 20 69 3e 30 3b 20 69 2d 2d  E_OK && i>0; i--
fc60: 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65  ){.    rc = vdbe
fc70: 53 6f 72 74 65 72 44 6f 43 6f 6d 70 61 72 65 28  SorterDoCompare(
fc80: 70 54 61 73 6b 2c 20 70 4d 65 72 67 65 72 2c 20  pTask, pMerger, 
fc90: 69 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  i);.  }..  retur
fca0: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
fcb0: 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61 64 65  int vdbePmaReade
fcc0: 72 49 6e 63 72 49 6e 69 74 28 50 6d 61 52 65 61  rIncrInit(PmaRea
fcd0: 64 65 72 20 2a 70 49 74 65 72 2c 20 69 6e 74 20  der *pIter, int 
fce0: 65 4d 6f 64 65 29 7b 0a 20 20 69 6e 74 20 72 63  eMode){.  int rc
fcf0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
fd00: 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63  IncrMerger *pInc
fd10: 72 20 3d 20 70 49 74 65 72 2d 3e 70 49 6e 63 72  r = pIter->pIncr
fd20: 3b 0a 20 20 69 66 28 20 70 49 6e 63 72 20 29 7b  ;.  if( pIncr ){
fd30: 0a 20 20 20 20 53 6f 72 74 53 75 62 74 61 73 6b  .    SortSubtask
fd40: 20 2a 70 54 61 73 6b 20 3d 20 70 49 6e 63 72 2d   *pTask = pIncr-
fd50: 3e 70 54 61 73 6b 3b 0a 20 20 20 20 73 71 6c 69  >pTask;.    sqli
fd60: 74 65 33 20 2a 64 62 20 3d 20 70 54 61 73 6b 2d  te3 *db = pTask-
fd70: 3e 70 53 6f 72 74 65 72 2d 3e 64 62 3b 0a 0a 20  >pSorter->db;.. 
fd80: 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72     rc = vdbeIncr
fd90: 49 6e 69 74 4d 65 72 67 65 72 28 70 54 61 73 6b  InitMerger(pTask
fda0: 2c 20 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65 72  , pIncr->pMerger
fdb0: 2c 20 65 4d 6f 64 65 29 3b 0a 0a 20 20 20 20 2f  , eMode);..    /
fdc0: 2a 20 53 65 74 20 75 70 20 74 68 65 20 72 65 71  * Set up the req
fdd0: 75 69 72 65 64 20 66 69 6c 65 73 20 66 6f 72 20  uired files for 
fde0: 70 49 6e 63 72 20 2a 2f 0a 20 20 20 20 69 66 28  pIncr */.    if(
fdf0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
fe00: 7b 0a 20 20 20 20 20 20 69 66 28 20 70 49 6e 63  {.      if( pInc
fe10: 72 2d 3e 62 55 73 65 54 68 72 65 61 64 3d 3d 30  r->bUseThread==0
fe20: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20   ){.        if( 
fe30: 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64  pTask->file2.pFd
fe40: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ==0 ){.         
fe50: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
fe60: 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 64 62 2d  OpenTempFile(db-
fe70: 3e 70 56 66 73 2c 20 26 70 54 61 73 6b 2d 3e 66  >pVfs, &pTask->f
fe80: 69 6c 65 32 2e 70 46 64 29 3b 0a 20 20 20 20 20  ile2.pFd);.     
fe90: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 54 61       assert( pTa
fea0: 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 3e 30  sk->file2.iEof>0
feb0: 20 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66   );.          if
fec0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
fed0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 76  ){.            v
fee0: 64 62 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46  dbeSorterExtendF
fef0: 69 6c 65 28 64 62 2c 20 70 54 61 73 6b 2d 3e 66  ile(db, pTask->f
ff00: 69 6c 65 32 2e 70 46 64 2c 20 70 54 61 73 6b 2d  ile2.pFd, pTask-
ff10: 3e 66 69 6c 65 32 2e 69 45 6f 66 29 3b 0a 20 20  >file2.iEof);.  
ff20: 20 20 20 20 20 20 20 20 20 20 70 54 61 73 6b 2d            pTask-
ff30: 3e 66 69 6c 65 32 2e 69 45 6f 66 20 3d 20 30 3b  >file2.iEof = 0;
ff40: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
ff50: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69       }.        i
ff60: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
ff70: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70 49   ){.          pI
ff80: 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 2e 70 46  ncr->aFile[1].pF
ff90: 64 20 3d 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32  d = pTask->file2
ffa0: 2e 70 46 64 3b 0a 20 20 20 20 20 20 20 20 20 20  .pFd;.          
ffb0: 70 49 6e 63 72 2d 3e 69 53 74 61 72 74 4f 66 66  pIncr->iStartOff
ffc0: 20 3d 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e   = pTask->file2.
ffd0: 69 45 6f 66 3b 0a 20 20 20 20 20 20 20 20 20 20  iEof;.          
ffe0: 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f  pTask->file2.iEo
fff0: 66 20 2b 3d 20 70 49 6e 63 72 2d 3e 6d 78 53 7a  f += pIncr->mxSz
10000 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
10010 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
10020 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
10030 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 64 62 2d  OpenTempFile(db-
10040 3e 70 56 66 73 2c 20 26 70 49 6e 63 72 2d 3e 61  >pVfs, &pIncr->a
10050 46 69 6c 65 5b 30 5d 2e 70 46 64 29 3b 0a 20 20  File[0].pFd);.  
10060 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
10070 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
10080 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f       rc = vdbeSo
10090 72 74 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65  rterOpenTempFile
100a0 28 64 62 2d 3e 70 56 66 73 2c 20 26 70 49 6e 63  (db->pVfs, &pInc
100b0 72 2d 3e 61 46 69 6c 65 5b 31 5d 2e 70 46 64 29  r->aFile[1].pFd)
100c0 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
100d0 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69    }.    }..    i
100e0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
100f0 20 26 26 20 70 49 6e 63 72 2d 3e 62 55 73 65 54   && pIncr->bUseT
10100 68 72 65 61 64 20 29 7b 0a 20 20 20 20 20 20 2f  hread ){.      /
10110 2a 20 55 73 65 20 74 68 65 20 63 75 72 72 65 6e  * Use the curren
10120 74 20 74 68 72 65 61 64 20 2a 2f 0a 20 20 20 20  t thread */.    
10130 20 20 61 73 73 65 72 74 28 20 65 4d 6f 64 65 3d    assert( eMode=
10140 3d 49 4e 43 52 49 4e 49 54 32 5f 52 4f 4f 54 20  =INCRINIT2_ROOT 
10150 7c 7c 20 65 4d 6f 64 65 3d 3d 49 4e 43 52 49 4e  || eMode==INCRIN
10160 49 54 32 5f 54 41 53 4b 20 29 3b 0a 20 20 20 20  IT2_TASK );.    
10170 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72 50    rc = vdbeIncrP
10180 6f 70 75 6c 61 74 65 28 70 49 6e 63 72 29 3b 0a  opulate(pIncr);.
10190 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72      }..    if( r
101a0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
101b0 65 4d 6f 64 65 21 3d 49 4e 43 52 49 4e 49 54 32  eMode!=INCRINIT2
101c0 5f 54 41 53 4b 20 29 7b 0a 20 20 20 20 20 20 72  _TASK ){.      r
101d0 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65  c = vdbePmaReade
101e0 72 4e 65 78 74 28 70 49 74 65 72 29 3b 0a 20 20  rNext(pIter);.  
101f0 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
10200 20 72 63 3b 0a 7d 0a 0a 23 69 66 20 53 51 4c 49   rc;.}..#if SQLI
10210 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48  TE_MAX_WORKER_TH
10220 52 45 41 44 53 3e 30 0a 2f 2a 0a 2a 2a 20 54 68  READS>0./*.** Th
10230 65 20 6d 61 69 6e 20 72 6f 75 74 69 6e 65 20 66  e main routine f
10240 6f 72 20 76 64 62 65 50 6d 61 52 65 61 64 65 72  or vdbePmaReader
10250 49 6e 63 72 49 6e 69 74 28 29 20 6f 70 65 72 61  IncrInit() opera
10260 74 69 6f 6e 73 20 72 75 6e 20 69 6e 20 0a 2a 2a  tions run in .**
10270 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65   background thre
10280 61 64 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ads..*/.static v
10290 6f 69 64 20 2a 76 64 62 65 50 6d 61 52 65 61 64  oid *vdbePmaRead
102a0 65 72 42 67 49 6e 69 74 28 76 6f 69 64 20 2a 70  erBgInit(void *p
102b0 43 74 78 29 7b 0a 20 20 50 6d 61 52 65 61 64 65  Ctx){.  PmaReade
102c0 72 20 2a 70 52 65 61 64 65 72 20 3d 20 28 50 6d  r *pReader = (Pm
102d0 61 52 65 61 64 65 72 2a 29 70 43 74 78 3b 0a 20  aReader*)pCtx;. 
102e0 20 76 6f 69 64 20 2a 70 52 65 74 20 3d 20 53 51   void *pRet = SQ
102f0 4c 49 54 45 5f 49 4e 54 5f 54 4f 5f 50 54 52 28  LITE_INT_TO_PTR(
10300 76 64 62 65 50 6d 61 52 65 61 64 65 72 49 6e 63  vdbePmaReaderInc
10310 72 49 6e 69 74 28 70 52 65 61 64 65 72 2c 49 4e  rInit(pReader,IN
10320 43 52 49 4e 49 54 32 5f 54 41 53 4b 29 29 3b 0a  CRINIT2_TASK));.
10330 20 20 70 52 65 61 64 65 72 2d 3e 70 49 6e 63 72    pReader->pIncr
10340 2d 3e 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 20 3d  ->pTask->bDone =
10350 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 70 52 65   1;.  return pRe
10360 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73 65 20  t;.}../*.** Use 
10370 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  a background thr
10380 65 61 64 20 74 6f 20 69 6e 76 6f 6b 65 20 76 64  ead to invoke vd
10390 62 65 50 6d 61 52 65 61 64 65 72 49 6e 63 72 49  bePmaReaderIncrI
103a0 6e 69 74 28 49 4e 43 52 49 4e 49 54 32 5f 54 41  nit(INCRINIT2_TA
103b0 53 4b 29 20 0a 2a 2a 20 6f 6e 20 74 68 65 20 74  SK) .** on the t
103c0 68 65 20 50 6d 61 52 65 61 64 65 72 20 6f 62 6a  he PmaReader obj
103d0 65 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68  ect passed as th
103e0 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
103f0 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 63 61 6c  ..**.** This cal
10400 6c 20 77 69 6c 6c 20 69 6e 69 74 69 61 6c 69 7a  l will initializ
10410 65 20 74 68 65 20 76 61 72 69 6f 75 73 20 66 69  e the various fi
10420 65 6c 64 73 20 6f 66 20 74 68 65 20 70 49 74 65  elds of the pIte
10430 72 2d 3e 70 49 6e 63 72 20 0a 2a 2a 20 73 74 72  r->pIncr .** str
10440 75 63 74 75 72 65 20 61 6e 64 2c 20 69 66 20 69  ucture and, if i
10450 74 20 69 73 20 61 20 6d 75 6c 74 69 2d 74 68 72  t is a multi-thr
10460 65 61 64 65 64 20 49 6e 63 72 4d 65 72 67 65 72  eaded IncrMerger
10470 2c 20 6c 61 75 6e 63 68 20 61 20 0a 2a 2a 20 62  , launch a .** b
10480 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64  ackground thread
10490 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 61 46 69   to populate aFi
104a0 6c 65 5b 31 5d 2e 0a 2a 2f 0a 73 74 61 74 69 63  le[1]..*/.static
104b0 20 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61 64   int vdbePmaRead
104c0 65 72 42 67 49 6e 63 72 49 6e 69 74 28 50 6d 61  erBgIncrInit(Pma
104d0 52 65 61 64 65 72 20 2a 70 49 74 65 72 29 7b 0a  Reader *pIter){.
104e0 20 20 76 6f 69 64 20 2a 70 43 74 78 20 3d 20 28    void *pCtx = (
104f0 76 6f 69 64 2a 29 70 49 74 65 72 3b 0a 20 20 72  void*)pIter;.  r
10500 65 74 75 72 6e 20 76 64 62 65 53 6f 72 74 65 72  eturn vdbeSorter
10510 43 72 65 61 74 65 54 68 72 65 61 64 28 70 49 74  CreateThread(pIt
10520 65 72 2d 3e 70 49 6e 63 72 2d 3e 70 54 61 73 6b  er->pIncr->pTask
10530 2c 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 42  , vdbePmaReaderB
10540 67 49 6e 69 74 2c 20 70 43 74 78 29 3b 0a 7d 0a  gInit, pCtx);.}.
10550 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 41 6c  #endif../*.** Al
10560 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 4d 65 72  locate a new Mer
10570 67 65 45 6e 67 69 6e 65 20 6f 62 6a 65 63 74 20  geEngine object 
10580 74 6f 20 6d 65 72 67 65 20 74 68 65 20 63 6f 6e  to merge the con
10590 74 65 6e 74 73 20 6f 66 20 6e 50 4d 41 20 6c 65  tents of nPMA le
105a0 76 65 6c 2d 30 0a 2a 2a 20 50 4d 41 73 20 66 72  vel-0.** PMAs fr
105b0 6f 6d 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 20  om pTask->file. 
105c0 49 66 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75  If no error occu
105d0 72 73 2c 20 73 65 74 20 2a 70 70 4f 75 74 20 74  rs, set *ppOut t
105e0 6f 20 70 6f 69 6e 74 20 74 6f 0a 2a 2a 20 74 68  o point to.** th
105f0 65 20 6e 65 77 20 6f 62 6a 65 63 74 20 61 6e 64  e new object and
10600 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
10610 4b 2e 20 4f 72 2c 20 69 66 20 61 6e 20 65 72 72  K. Or, if an err
10620 6f 72 20 64 6f 65 73 20 6f 63 63 75 72 2c 20 73  or does occur, s
10630 65 74 20 2a 70 70 4f 75 74 0a 2a 2a 20 74 6f 20  et *ppOut.** to 
10640 4e 55 4c 4c 20 61 6e 64 20 72 65 74 75 72 6e 20  NULL and return 
10650 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
10660 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 6e  code..**.** When
10670 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
10680 73 20 63 61 6c 6c 65 64 2c 20 2a 70 69 4f 66 66  s called, *piOff
10690 73 65 74 20 69 73 20 73 65 74 20 74 6f 20 74 68  set is set to th
106a0 65 20 6f 66 66 73 65 74 20 6f 66 20 74 68 65 0a  e offset of the.
106b0 2a 2a 20 66 69 72 73 74 20 50 4d 41 20 74 6f 20  ** first PMA to 
106c0 72 65 61 64 20 66 72 6f 6d 20 70 54 61 73 6b 2d  read from pTask-
106d0 3e 66 69 6c 65 2e 20 41 73 73 75 6d 69 6e 67 20  >file. Assuming 
106e0 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c  no error occurs,
106f0 20 69 74 20 69 73 20 0a 2a 2a 20 73 65 74 20 74   it is .** set t
10700 6f 20 74 68 65 20 6f 66 66 73 65 74 20 69 6d 6d  o the offset imm
10710 65 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 69  ediately followi
10720 6e 67 20 74 68 65 20 6c 61 73 74 20 62 79 74 65  ng the last byte
10730 20 6f 66 20 74 68 65 20 6c 61 73 74 0a 2a 2a 20   of the last.** 
10740 50 4d 41 20 62 65 66 6f 72 65 20 72 65 74 75 72  PMA before retur
10750 6e 69 6e 67 2e 20 49 66 20 61 6e 20 65 72 72 6f  ning. If an erro
10760 72 20 64 6f 65 73 20 6f 63 63 75 72 2c 20 74 68  r does occur, th
10770 65 6e 20 74 68 65 20 66 69 6e 61 6c 20 76 61 6c  en the final val
10780 75 65 20 6f 66 0a 2a 2a 20 2a 70 69 4f 66 66 73  ue of.** *piOffs
10790 65 74 20 69 73 20 75 6e 64 65 66 69 6e 65 64 2e  et is undefined.
107a0 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
107b0 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4c 65  dbeMergeEngineLe
107c0 76 65 6c 30 28 0a 20 20 53 6f 72 74 53 75 62 74  vel0(.  SortSubt
107d0 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20 20 20  ask *pTask,     
107e0 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65          /* Sorte
107f0 72 20 74 61 73 6b 20 74 6f 20 72 65 61 64 20 66  r task to read f
10800 72 6f 6d 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 4d  rom */.  int nPM
10810 41 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  A,              
10820 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
10830 65 72 20 6f 66 20 50 4d 41 73 20 74 6f 20 72 65  er of PMAs to re
10840 61 64 20 2a 2f 0a 20 20 69 36 34 20 2a 70 69 4f  ad */.  i64 *piO
10850 66 66 73 65 74 2c 20 20 20 20 20 20 20 20 20 20  ffset,          
10860 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55          /* IN/OU
10870 54 3a 20 52 65 61 64 20 6f 66 66 73 65 74 20 69  T: Read offset i
10880 6e 20 70 54 61 73 6b 2d 3e 66 69 6c 65 20 2a 2f  n pTask->file */
10890 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a  .  MergeEngine *
108a0 2a 70 70 4f 75 74 20 20 20 20 20 20 20 20 20 20  *ppOut          
108b0 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 65 77 20 6d     /* OUT: New m
108c0 65 72 67 65 2d 65 6e 67 69 6e 65 20 2a 2f 0a 29  erge-engine */.)
108d0 7b 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  {.  MergeEngine 
108e0 2a 70 4e 65 77 3b 20 20 20 20 20 20 20 20 20 20  *pNew;          
108f0 20 20 20 20 2f 2a 20 4d 65 72 67 65 20 65 6e 67      /* Merge eng
10900 69 6e 65 20 74 6f 20 72 65 74 75 72 6e 20 2a 2f  ine to return */
10910 0a 20 20 69 36 34 20 69 4f 66 66 20 3d 20 2a 70  .  i64 iOff = *p
10920 69 4f 66 66 73 65 74 3b 0a 20 20 69 6e 74 20 69  iOffset;.  int i
10930 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  ;.  int rc = SQL
10940 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2a 70 70 4f 75  ITE_OK;..  *ppOu
10950 74 20 3d 20 70 4e 65 77 20 3d 20 76 64 62 65 4d  t = pNew = vdbeM
10960 65 72 67 65 45 6e 67 69 6e 65 4e 65 77 28 6e 50  ergeEngineNew(nP
10970 4d 41 29 3b 0a 20 20 69 66 28 20 70 4e 65 77 3d  MA);.  if( pNew=
10980 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45  =0 ) rc = SQLITE
10990 5f 4e 4f 4d 45 4d 3b 0a 0a 20 20 66 6f 72 28 69  _NOMEM;..  for(i
109a0 3d 30 3b 20 69 3c 6e 50 4d 41 20 26 26 20 72 63  =0; i<nPMA && rc
109b0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 2b 2b  ==SQLITE_OK; i++
109c0 29 7b 0a 20 20 20 20 69 36 34 20 6e 44 75 6d 6d  ){.    i64 nDumm
109d0 79 3b 0a 20 20 20 20 50 6d 61 52 65 61 64 65 72  y;.    PmaReader
109e0 20 2a 70 49 74 65 72 20 3d 20 26 70 4e 65 77 2d   *pIter = &pNew-
109f0 3e 61 49 74 65 72 5b 69 5d 3b 0a 20 20 20 20 72  >aIter[i];.    r
10a00 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65  c = vdbePmaReade
10a10 72 49 6e 69 74 28 70 54 61 73 6b 2c 20 26 70 54  rInit(pTask, &pT
10a20 61 73 6b 2d 3e 66 69 6c 65 2c 20 69 4f 66 66 2c  ask->file, iOff,
10a30 20 70 49 74 65 72 2c 20 26 6e 44 75 6d 6d 79 29   pIter, &nDummy)
10a40 3b 0a 20 20 20 20 69 4f 66 66 20 3d 20 70 49 74  ;.    iOff = pIt
10a50 65 72 2d 3e 69 45 6f 66 3b 0a 20 20 7d 0a 0a 20  er->iEof;.  }.. 
10a60 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
10a70 4f 4b 20 29 7b 0a 20 20 20 20 76 64 62 65 4d 65  OK ){.    vdbeMe
10a80 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28 70 4e  rgeEngineFree(pN
10a90 65 77 29 3b 0a 20 20 20 20 2a 70 70 4f 75 74 20  ew);.    *ppOut 
10aa0 3d 20 30 3b 0a 20 20 7d 0a 20 20 2a 70 69 4f 66  = 0;.  }.  *piOf
10ab0 66 73 65 74 20 3d 20 69 4f 66 66 3b 0a 20 20 72  fset = iOff;.  r
10ac0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
10ad0 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 64 65  ** Return the de
10ae0 70 74 68 20 6f 66 20 61 20 74 72 65 65 20 63 6f  pth of a tree co
10af0 6d 70 72 69 73 69 6e 67 20 6e 50 4d 41 20 50 4d  mprising nPMA PM
10b00 41 73 2c 20 61 73 73 75 6d 69 6e 67 20 61 20 66  As, assuming a f
10b10 61 6e 6f 75 74 20 6f 66 0a 2a 2a 20 53 4f 52 54  anout of.** SORT
10b20 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55  ER_MAX_MERGE_COU
10b30 4e 54 2e 20 54 68 65 20 72 65 74 75 72 6e 65 64  NT. The returned
10b40 20 76 61 6c 75 65 20 64 6f 65 73 20 6e 6f 74 20   value does not 
10b50 69 6e 63 6c 75 64 65 20 6c 65 61 66 20 6e 6f 64  include leaf nod
10b60 65 73 2e 0a 2a 2a 0a 2a 2a 20 69 2e 65 2e 0a 2a  es..**.** i.e..*
10b70 2a 0a 2a 2a 20 20 20 6e 50 4d 41 3c 3d 31 36 20  *.**   nPMA<=16 
10b80 20 20 20 2d 3e 20 54 72 65 65 44 65 70 74 68 28     -> TreeDepth(
10b90 29 20 3d 3d 20 30 0a 2a 2a 20 20 20 6e 50 4d 41  ) == 0.**   nPMA
10ba0 3c 3d 32 35 36 20 20 20 2d 3e 20 54 72 65 65 44  <=256   -> TreeD
10bb0 65 70 74 68 28 29 20 3d 3d 20 31 0a 2a 2a 20 20  epth() == 1.**  
10bc0 20 6e 50 4d 41 3c 3d 36 35 35 33 36 20 2d 3e 20   nPMA<=65536 -> 
10bd0 54 72 65 65 44 65 70 74 68 28 29 20 3d 3d 20 32  TreeDepth() == 2
10be0 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
10bf0 64 62 65 53 6f 72 74 65 72 54 72 65 65 44 65 70  dbeSorterTreeDep
10c00 74 68 28 69 6e 74 20 6e 50 4d 41 29 7b 0a 20 20  th(int nPMA){.  
10c10 69 6e 74 20 6e 44 65 70 74 68 20 3d 20 30 3b 0a  int nDepth = 0;.
10c20 20 20 69 36 34 20 6e 44 69 76 20 3d 20 53 4f 52    i64 nDiv = SOR
10c30 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
10c40 55 4e 54 3b 0a 20 20 77 68 69 6c 65 28 20 6e 44  UNT;.  while( nD
10c50 69 76 20 3c 20 28 69 36 34 29 6e 50 4d 41 20 29  iv < (i64)nPMA )
10c60 7b 0a 20 20 20 20 6e 44 69 76 20 3d 20 6e 44 69  {.    nDiv = nDi
10c70 76 20 2a 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  v * SORTER_MAX_M
10c80 45 52 47 45 5f 43 4f 55 4e 54 3b 0a 20 20 20 20  ERGE_COUNT;.    
10c90 6e 44 65 70 74 68 2b 2b 3b 0a 20 20 7d 0a 20 20  nDepth++;.  }.  
10ca0 72 65 74 75 72 6e 20 6e 44 65 70 74 68 3b 0a 7d  return nDepth;.}
10cb0 0a 0a 2f 2a 0a 2a 2a 20 70 52 6f 6f 74 20 69 73  ../*.** pRoot is
10cc0 20 74 68 65 20 72 6f 6f 74 20 6f 66 20 61 6e 20   the root of an 
10cd0 69 6e 63 72 65 6d 65 6e 74 61 6c 20 6d 65 72 67  incremental merg
10ce0 65 2d 74 72 65 65 20 77 69 74 68 20 64 65 70 74  e-tree with dept
10cf0 68 20 6e 44 65 70 74 68 20 28 61 63 63 6f 72 64  h nDepth (accord
10d00 69 6e 67 0a 2a 2a 20 74 6f 20 76 64 62 65 53 6f  ing.** to vdbeSo
10d10 72 74 65 72 54 72 65 65 44 65 70 74 68 28 29 29  rterTreeDepth())
10d20 2e 20 70 4c 65 61 66 20 69 73 20 74 68 65 20 69  . pLeaf is the i
10d30 53 65 71 27 74 68 20 6c 65 61 66 20 74 6f 20 62  Seq'th leaf to b
10d40 65 20 61 64 64 65 64 20 74 6f 20 74 68 65 0a 2a  e added to the.*
10d50 2a 20 74 72 65 65 2c 20 63 6f 75 6e 74 69 6e 67  * tree, counting
10d60 20 66 72 6f 6d 20 7a 65 72 6f 2e 20 54 68 69 73   from zero. This
10d70 20 66 75 6e 63 74 69 6f 6e 20 61 64 64 73 20 70   function adds p
10d80 4c 65 61 66 20 74 6f 20 74 68 65 20 74 72 65 65  Leaf to the tree
10d90 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65  ..**.** If succe
10da0 73 73 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b  ssful, SQLITE_OK
10db0 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 49 66   is returned. If
10dc0 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
10dd0 2c 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  , an SQLite erro
10de0 72 0a 2a 2a 20 63 6f 64 65 20 69 73 20 72 65 74  r.** code is ret
10df0 75 72 6e 65 64 20 61 6e 64 20 70 4c 65 61 66 20  urned and pLeaf 
10e00 69 73 20 66 72 65 65 64 2e 0a 2a 2f 0a 73 74 61  is freed..*/.sta
10e10 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74  tic int vdbeSort
10e20 65 72 41 64 64 54 6f 54 72 65 65 28 0a 20 20 53  erAddToTree(.  S
10e30 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
10e40 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  k,             /
10e50 2a 20 54 61 73 6b 20 63 6f 6e 74 65 78 74 20 2a  * Task context *
10e60 2f 0a 20 20 69 6e 74 20 6e 44 65 70 74 68 2c 20  /.  int nDepth, 
10e70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10e80 20 20 20 20 2f 2a 20 44 65 70 74 68 20 6f 66 20      /* Depth of 
10e90 74 72 65 65 20 61 63 63 6f 72 64 69 6e 67 20 74  tree according t
10ea0 6f 20 54 72 65 65 44 65 70 74 68 28 29 20 2a 2f  o TreeDepth() */
10eb0 0a 20 20 69 6e 74 20 69 53 65 71 2c 20 20 20 20  .  int iSeq,    
10ec0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10ed0 20 20 20 2f 2a 20 53 65 71 75 65 6e 63 65 20 6e     /* Sequence n
10ee0 75 6d 62 65 72 20 6f 66 20 6c 65 61 66 20 77 69  umber of leaf wi
10ef0 74 68 69 6e 20 74 72 65 65 20 2a 2f 0a 20 20 4d  thin tree */.  M
10f00 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 52 6f 6f  ergeEngine *pRoo
10f10 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  t,             /
10f20 2a 20 52 6f 6f 74 20 6f 66 20 74 72 65 65 20 2a  * Root of tree *
10f30 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  /.  MergeEngine 
10f40 2a 70 4c 65 61 66 20 20 20 20 20 20 20 20 20 20  *pLeaf          
10f50 20 20 20 20 2f 2a 20 4c 65 61 66 20 74 6f 20 61      /* Leaf to a
10f60 64 64 20 74 6f 20 74 72 65 65 20 2a 2f 0a 29 7b  dd to tree */.){
10f70 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
10f80 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 44 69  TE_OK;.  int nDi
10f90 76 20 3d 20 31 3b 0a 20 20 69 6e 74 20 69 3b 0a  v = 1;.  int i;.
10fa0 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70    MergeEngine *p
10fb0 20 3d 20 70 52 6f 6f 74 3b 0a 20 20 49 6e 63 72   = pRoot;.  Incr
10fc0 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 3b 0a 0a  Merger *pIncr;..
10fd0 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72 4e    rc = vdbeIncrN
10fe0 65 77 28 70 54 61 73 6b 2c 20 70 4c 65 61 66 2c  ew(pTask, pLeaf,
10ff0 20 26 70 49 6e 63 72 29 3b 0a 0a 20 20 66 6f 72   &pIncr);..  for
11000 28 69 3d 31 3b 20 69 3c 6e 44 65 70 74 68 3b 20  (i=1; i<nDepth; 
11010 69 2b 2b 29 7b 0a 20 20 20 20 6e 44 69 76 20 3d  i++){.    nDiv =
11020 20 6e 44 69 76 20 2a 20 53 4f 52 54 45 52 5f 4d   nDiv * SORTER_M
11030 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3b 0a  AX_MERGE_COUNT;.
11040 20 20 7d 0a 0a 20 20 66 6f 72 28 69 3d 31 3b 20    }..  for(i=1; 
11050 69 3c 6e 44 65 70 74 68 20 26 26 20 72 63 3d 3d  i<nDepth && rc==
11060 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b  SQLITE_OK; i++){
11070 0a 20 20 20 20 69 6e 74 20 69 49 74 65 72 20 3d  .    int iIter =
11080 20 28 69 53 65 71 20 2f 20 6e 44 69 76 29 20 25   (iSeq / nDiv) %
11090 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47   SORTER_MAX_MERG
110a0 45 5f 43 4f 55 4e 54 3b 0a 20 20 20 20 50 6d 61  E_COUNT;.    Pma
110b0 52 65 61 64 65 72 20 2a 70 49 74 65 72 20 3d 20  Reader *pIter = 
110c0 26 70 2d 3e 61 49 74 65 72 5b 69 49 74 65 72 5d  &p->aIter[iIter]
110d0 3b 0a 0a 20 20 20 20 69 66 28 20 70 49 74 65 72  ;..    if( pIter
110e0 2d 3e 70 49 6e 63 72 3d 3d 30 20 29 7b 0a 20 20  ->pIncr==0 ){.  
110f0 20 20 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20      MergeEngine 
11100 2a 70 4e 65 77 20 3d 20 76 64 62 65 4d 65 72 67  *pNew = vdbeMerg
11110 65 45 6e 67 69 6e 65 4e 65 77 28 53 4f 52 54 45  eEngineNew(SORTE
11120 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
11130 54 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 4e  T);.      if( pN
11140 65 77 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  ew==0 ){.       
11150 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
11160 45 4d 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  EM;.      }else{
11170 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64  .        rc = vd
11180 62 65 49 6e 63 72 4e 65 77 28 70 54 61 73 6b 2c  beIncrNew(pTask,
11190 20 70 4e 65 77 2c 20 26 70 49 74 65 72 2d 3e 70   pNew, &pIter->p
111a0 49 6e 63 72 29 3b 0a 20 20 20 20 20 20 7d 0a 20  Incr);.      }. 
111b0 20 20 20 7d 0a 0a 20 20 20 20 70 20 3d 20 70 49     }..    p = pI
111c0 74 65 72 2d 3e 70 49 6e 63 72 2d 3e 70 4d 65 72  ter->pIncr->pMer
111d0 67 65 72 3b 0a 20 20 20 20 6e 44 69 76 20 3d 20  ger;.    nDiv = 
111e0 6e 44 69 76 20 2f 20 53 4f 52 54 45 52 5f 4d 41  nDiv / SORTER_MA
111f0 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3b 0a 20  X_MERGE_COUNT;. 
11200 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
11210 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70  LITE_OK ){.    p
11220 2d 3e 61 49 74 65 72 5b 69 53 65 71 20 25 20 53  ->aIter[iSeq % S
11230 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f  ORTER_MAX_MERGE_
11240 43 4f 55 4e 54 5d 2e 70 49 6e 63 72 20 3d 20 70  COUNT].pIncr = p
11250 49 6e 63 72 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  Incr;.  }else{. 
11260 20 20 20 76 64 62 65 49 6e 63 72 46 72 65 65 28     vdbeIncrFree(
11270 70 49 6e 63 72 29 3b 0a 20 20 7d 0a 20 20 72 65  pIncr);.  }.  re
11280 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
11290 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
112a0 69 73 20 63 61 6c 6c 65 64 20 61 73 20 70 61 72  is called as par
112b0 74 20 6f 66 20 61 20 53 6f 72 74 65 72 52 65 77  t of a SorterRew
112c0 69 6e 64 28 29 20 6f 70 65 72 61 74 69 6f 6e 20  ind() operation 
112d0 6f 6e 20 61 20 73 6f 72 74 65 72 0a 2a 2a 20 74  on a sorter.** t
112e0 68 61 74 20 68 61 73 20 61 6c 72 65 61 64 79 20  hat has already 
112f0 77 72 69 74 74 65 6e 20 74 77 6f 20 6f 72 20 6d  written two or m
11300 6f 72 65 20 6c 65 76 65 6c 2d 30 20 50 4d 41 73  ore level-0 PMAs
11310 20 74 6f 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20   to one or more 
11320 74 65 6d 70 0a 2a 2a 20 66 69 6c 65 73 2e 20 49  temp.** files. I
11330 74 20 62 75 69 6c 64 73 20 61 20 74 72 65 65 20  t builds a tree 
11340 6f 66 20 4d 65 72 67 65 45 6e 67 69 6e 65 2f 49  of MergeEngine/I
11350 6e 63 72 4d 65 72 67 65 72 2f 50 6d 61 52 65 61  ncrMerger/PmaRea
11360 64 65 72 20 6f 62 6a 65 63 74 73 20 74 68 61 74  der objects that
11370 20 0a 2a 2a 20 63 61 6e 20 62 65 20 75 73 65 64   .** can be used
11380 20 74 6f 20 69 6e 63 72 65 6d 65 6e 74 61 6c 6c   to incrementall
11390 79 20 6d 65 72 67 65 20 61 6c 6c 20 50 4d 41 73  y merge all PMAs
113a0 20 6f 6e 20 64 69 73 6b 2e 0a 2a 2a 0a 2a 2a 20   on disk..**.** 
113b0 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 53  If successful, S
113c0 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75  QLITE_OK is retu
113d0 72 6e 65 64 20 61 6e 64 20 2a 70 70 4f 75 74 20  rned and *ppOut 
113e0 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  set to point to 
113f0 74 68 65 0a 2a 2a 20 4d 65 72 67 65 45 6e 67 69  the.** MergeEngi
11400 6e 65 20 6f 62 6a 65 63 74 20 61 74 20 74 68 65  ne object at the
11410 20 72 6f 6f 74 20 6f 66 20 74 68 65 20 74 72 65   root of the tre
11420 65 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69  e before returni
11430 6e 67 2e 20 4f 72 2c 20 69 66 20 61 6e 0a 2a 2a  ng. Or, if an.**
11440 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 61   error occurs, a
11450 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  n SQLite error c
11460 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65 64 20  ode is returned 
11470 61 6e 64 20 74 68 65 20 66 69 6e 61 6c 20 76 61  and the final va
11480 6c 75 65 20 0a 2a 2a 20 6f 66 20 2a 70 70 4f 75  lue .** of *ppOu
11490 74 20 69 73 20 75 6e 64 65 66 69 6e 65 64 2e 0a  t is undefined..
114a0 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
114b0 62 65 53 6f 72 74 65 72 4d 65 72 67 65 54 72 65  beSorterMergeTre
114c0 65 42 75 69 6c 64 28 56 64 62 65 53 6f 72 74 65  eBuild(VdbeSorte
114d0 72 20 2a 70 53 6f 72 74 65 72 2c 20 4d 65 72 67  r *pSorter, Merg
114e0 65 45 6e 67 69 6e 65 20 2a 2a 70 70 4f 75 74 29  eEngine **ppOut)
114f0 7b 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  {.  MergeEngine 
11500 2a 70 4d 61 69 6e 20 3d 20 30 3b 0a 20 20 69 6e  *pMain = 0;.  in
11510 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
11520 3b 0a 20 20 69 6e 74 20 69 54 61 73 6b 3b 0a 0a  ;.  int iTask;..
11530 20 20 2f 2a 20 49 66 20 74 68 65 20 73 6f 72 74    /* If the sort
11540 65 72 20 75 73 65 73 20 6d 6f 72 65 20 74 68 61  er uses more tha
11550 6e 20 6f 6e 65 20 74 61 73 6b 2c 20 74 68 65 6e  n one task, then
11560 20 63 72 65 61 74 65 20 74 68 65 20 74 6f 70 2d   create the top-
11570 6c 65 76 65 6c 20 0a 20 20 2a 2a 20 4d 65 72 67  level .  ** Merg
11580 65 45 6e 67 69 6e 65 20 68 65 72 65 2e 20 54 68  eEngine here. Th
11590 69 73 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 77  is MergeEngine w
115a0 69 6c 6c 20 72 65 61 64 20 64 61 74 61 20 66 72  ill read data fr
115b0 6f 6d 20 65 78 61 63 74 6c 79 20 0a 20 20 2a 2a  om exactly .  **
115c0 20 6f 6e 65 20 50 6d 61 52 65 61 64 65 72 20 70   one PmaReader p
115d0 65 72 20 73 75 62 2d 74 61 73 6b 2e 20 20 2a 2f  er sub-task.  */
115e0 0a 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74  .  assert( pSort
115f0 65 72 2d 3e 62 55 73 65 54 68 72 65 61 64 73 20  er->bUseThreads 
11600 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73  || pSorter->nTas
11610 6b 3d 3d 31 20 29 3b 0a 20 20 69 66 28 20 70 53  k==1 );.  if( pS
11620 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3e 31 20 29  orter->nTask>1 )
11630 7b 0a 20 20 20 20 70 4d 61 69 6e 20 3d 20 76 64  {.    pMain = vd
11640 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4e 65 77  beMergeEngineNew
11650 28 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 29  (pSorter->nTask)
11660 3b 0a 20 20 20 20 69 66 28 20 70 4d 61 69 6e 3d  ;.    if( pMain=
11670 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45  =0 ) rc = SQLITE
11680 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20 66  _NOMEM;.  }..  f
11690 6f 72 28 69 54 61 73 6b 3d 30 3b 20 69 54 61 73  or(iTask=0; iTas
116a0 6b 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b  k<pSorter->nTask
116b0 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f   && rc==SQLITE_O
116c0 4b 3b 20 69 54 61 73 6b 2b 2b 29 7b 0a 20 20 20  K; iTask++){.   
116d0 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
116e0 61 73 6b 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e  ask = &pSorter->
116f0 61 54 61 73 6b 5b 69 54 61 73 6b 5d 3b 0a 20 20  aTask[iTask];.  
11700 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 6e 50 4d    if( pTask->nPM
11710 41 20 29 7b 0a 20 20 20 20 20 20 4d 65 72 67 65  A ){.      Merge
11720 45 6e 67 69 6e 65 20 2a 70 52 6f 6f 74 20 3d 20  Engine *pRoot = 
11730 30 3b 20 20 20 20 20 2f 2a 20 52 6f 6f 74 20 6e  0;     /* Root n
11740 6f 64 65 20 6f 66 20 74 72 65 65 20 66 6f 72 20  ode of tree for 
11750 74 68 69 73 20 74 61 73 6b 20 2a 2f 0a 20 20 20  this task */.   
11760 20 20 20 69 6e 74 20 6e 44 65 70 74 68 20 3d 20     int nDepth = 
11770 76 64 62 65 53 6f 72 74 65 72 54 72 65 65 44 65  vdbeSorterTreeDe
11780 70 74 68 28 70 54 61 73 6b 2d 3e 6e 50 4d 41 29  pth(pTask->nPMA)
11790 3b 0a 20 20 20 20 20 20 69 36 34 20 69 52 65 61  ;.      i64 iRea
117a0 64 4f 66 66 20 3d 20 30 3b 0a 0a 20 20 20 20 20  dOff = 0;..     
117b0 20 69 66 28 20 70 54 61 73 6b 2d 3e 6e 50 4d 41   if( pTask->nPMA
117c0 3c 3d 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52  <=SORTER_MAX_MER
117d0 47 45 5f 43 4f 55 4e 54 20 29 7b 0a 20 20 20 20  GE_COUNT ){.    
117e0 20 20 20 20 72 63 20 3d 20 76 64 62 65 4d 65 72      rc = vdbeMer
117f0 67 65 45 6e 67 69 6e 65 4c 65 76 65 6c 30 28 70  geEngineLevel0(p
11800 54 61 73 6b 2c 20 70 54 61 73 6b 2d 3e 6e 50 4d  Task, pTask->nPM
11810 41 2c 20 26 69 52 65 61 64 4f 66 66 2c 20 26 70  A, &iReadOff, &p
11820 52 6f 6f 74 29 3b 0a 20 20 20 20 20 20 7d 65 6c  Root);.      }el
11830 73 65 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20  se{.        int 
11840 69 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69  i;.        int i
11850 53 65 71 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  Seq = 0;.       
11860 20 70 52 6f 6f 74 20 3d 20 76 64 62 65 4d 65 72   pRoot = vdbeMer
11870 67 65 45 6e 67 69 6e 65 4e 65 77 28 53 4f 52 54  geEngineNew(SORT
11880 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55  ER_MAX_MERGE_COU
11890 4e 54 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  NT);.        if(
118a0 20 70 52 6f 6f 74 3d 3d 30 20 29 20 72 63 20 3d   pRoot==0 ) rc =
118b0 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
118c0 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20         for(i=0; 
118d0 69 3c 70 54 61 73 6b 2d 3e 6e 50 4d 41 20 26 26  i<pTask->nPMA &&
118e0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20   rc==SQLITE_OK; 
118f0 69 20 2b 3d 20 53 4f 52 54 45 52 5f 4d 41 58 5f  i += SORTER_MAX_
11900 4d 45 52 47 45 5f 43 4f 55 4e 54 29 7b 0a 20 20  MERGE_COUNT){.  
11910 20 20 20 20 20 20 20 20 4d 65 72 67 65 45 6e 67          MergeEng
11920 69 6e 65 20 2a 70 4d 65 72 67 65 72 20 3d 20 30  ine *pMerger = 0
11930 3b 20 2f 2a 20 4e 65 77 20 6c 65 76 65 6c 2d 30  ; /* New level-0
11940 20 50 4d 41 20 6d 65 72 67 65 72 20 2a 2f 0a 20   PMA merger */. 
11950 20 20 20 20 20 20 20 20 20 69 6e 74 20 6e 52 65           int nRe
11960 61 64 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  ader;           
11970 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
11980 6c 65 76 65 6c 2d 30 20 50 4d 41 73 20 74 6f 20  level-0 PMAs to 
11990 6d 65 72 67 65 20 2a 2f 0a 0a 20 20 20 20 20 20  merge */..      
119a0 20 20 20 20 6e 52 65 61 64 65 72 20 3d 20 4d 49      nReader = MI
119b0 4e 28 70 54 61 73 6b 2d 3e 6e 50 4d 41 20 2d 20  N(pTask->nPMA - 
119c0 69 2c 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45  i, SORTER_MAX_ME
119d0 52 47 45 5f 43 4f 55 4e 54 29 3b 0a 20 20 20 20  RGE_COUNT);.    
119e0 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 4d        rc = vdbeM
119f0 65 72 67 65 45 6e 67 69 6e 65 4c 65 76 65 6c 30  ergeEngineLevel0
11a00 28 70 54 61 73 6b 2c 20 6e 52 65 61 64 65 72 2c  (pTask, nReader,
11a10 20 26 69 52 65 61 64 4f 66 66 2c 20 26 70 4d 65   &iReadOff, &pMe
11a20 72 67 65 72 29 3b 0a 20 20 20 20 20 20 20 20 20  rger);.         
11a30 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
11a40 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  OK ){.          
11a50 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
11a60 72 41 64 64 54 6f 54 72 65 65 28 70 54 61 73 6b  rAddToTree(pTask
11a70 2c 20 6e 44 65 70 74 68 2c 20 69 53 65 71 2b 2b  , nDepth, iSeq++
11a80 2c 20 70 52 6f 6f 74 2c 20 70 4d 65 72 67 65 72  , pRoot, pMerger
11a90 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20  );.          }. 
11aa0 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
11ab0 0a 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ..      if( rc==
11ac0 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
11ad0 20 20 20 20 20 69 66 28 20 70 4d 61 69 6e 3d 3d       if( pMain==
11ae0 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70  0 ){.          p
11af0 4d 61 69 6e 20 3d 20 70 52 6f 6f 74 3b 0a 20 20  Main = pRoot;.  
11b00 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
11b10 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65         rc = vdbe
11b20 49 6e 63 72 4e 65 77 28 70 54 61 73 6b 2c 20 70  IncrNew(pTask, p
11b30 52 6f 6f 74 2c 20 26 70 4d 61 69 6e 2d 3e 61 49  Root, &pMain->aI
11b40 74 65 72 5b 69 54 61 73 6b 5d 2e 70 49 6e 63 72  ter[iTask].pIncr
11b50 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  );.        }.   
11b60 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
11b70 20 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e    vdbeMergeEngin
11b80 65 46 72 65 65 28 70 52 6f 6f 74 29 3b 0a 20 20  eFree(pRoot);.  
11b90 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
11ba0 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
11bb0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 64 62 65  E_OK ){.    vdbe
11bc0 4d 65 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28  MergeEngineFree(
11bd0 70 4d 61 69 6e 29 3b 0a 20 20 20 20 70 4d 61 69  pMain);.    pMai
11be0 6e 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 2a 70 70  n = 0;.  }.  *pp
11bf0 4f 75 74 20 3d 20 70 4d 61 69 6e 3b 0a 20 20 72  Out = pMain;.  r
11c00 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
11c10 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
11c20 20 69 73 20 63 61 6c 6c 65 64 20 61 73 20 70 61   is called as pa
11c30 72 74 20 6f 66 20 61 6e 20 73 71 6c 69 74 65 33  rt of an sqlite3
11c40 56 64 62 65 53 6f 72 74 65 72 52 65 77 69 6e 64  VdbeSorterRewind
11c50 28 29 20 6f 70 65 72 61 74 69 6f 6e 0a 2a 2a 20  () operation.** 
11c60 6f 6e 20 61 20 73 6f 72 74 65 72 20 74 68 61 74  on a sorter that
11c70 20 68 61 73 20 77 72 69 74 74 65 6e 20 74 77 6f   has written two
11c80 20 6f 72 20 6d 6f 72 65 20 50 4d 41 73 20 74 6f   or more PMAs to
11c90 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 73   temporary files
11ca0 2e 20 49 74 20 73 65 74 73 0a 2a 2a 20 75 70 20  . It sets.** up 
11cb0 65 69 74 68 65 72 20 56 64 62 65 53 6f 72 74 65  either VdbeSorte
11cc0 72 2e 70 4d 65 72 67 65 72 20 28 66 6f 72 20 73  r.pMerger (for s
11cd0 69 6e 67 6c 65 20 74 68 72 65 61 64 65 64 20 73  ingle threaded s
11ce0 6f 72 74 65 72 73 29 20 6f 72 20 70 52 65 61 64  orters) or pRead
11cf0 65 72 0a 2a 2a 20 28 66 6f 72 20 6d 75 6c 74 69  er.** (for multi
11d00 2d 74 68 72 65 61 64 65 64 20 73 6f 72 74 65 72  -threaded sorter
11d10 73 29 20 73 6f 20 74 68 61 74 20 69 74 20 63 61  s) so that it ca
11d20 6e 20 62 65 20 75 73 65 64 20 74 6f 20 69 74 65  n be used to ite
11d30 72 61 74 65 20 74 68 72 6f 75 67 68 0a 2a 2a 20  rate through.** 
11d40 61 6c 6c 20 72 65 63 6f 72 64 73 20 73 74 6f 72  all records stor
11d50 65 64 20 69 6e 20 74 68 65 20 73 6f 72 74 65 72  ed in the sorter
11d60 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f  ..**.** SQLITE_O
11d70 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 69 66  K is returned if
11d80 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20   successful, or 
11d90 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
11da0 63 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a  code otherwise..
11db0 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
11dc0 62 65 53 6f 72 74 65 72 53 65 74 75 70 4d 65 72  beSorterSetupMer
11dd0 67 65 28 56 64 62 65 53 6f 72 74 65 72 20 2a 70  ge(VdbeSorter *p
11de0 53 6f 72 74 65 72 29 7b 0a 20 20 69 6e 74 20 72  Sorter){.  int r
11df0 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
11e00 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
11e10 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 53  turn code */.  S
11e20 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
11e30 6b 30 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61  k0 = &pSorter->a
11e40 54 61 73 6b 5b 30 5d 3b 0a 20 20 4d 65 72 67 65  Task[0];.  Merge
11e50 45 6e 67 69 6e 65 20 2a 70 4d 61 69 6e 20 3d 20  Engine *pMain = 
11e60 30 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  0;.  sqlite3 *db
11e70 20 3d 20 70 54 61 73 6b 30 2d 3e 70 53 6f 72 74   = pTask0->pSort
11e80 65 72 2d 3e 64 62 3b 0a 20 20 69 6e 74 20 69 54  er->db;.  int iT
11e90 61 73 6b 3b 0a 0a 20 20 72 63 20 3d 20 76 64 62  ask;..  rc = vdb
11ea0 65 53 6f 72 74 65 72 4d 65 72 67 65 54 72 65 65  eSorterMergeTree
11eb0 42 75 69 6c 64 28 70 53 6f 72 74 65 72 2c 20 26  Build(pSorter, &
11ec0 70 4d 61 69 6e 29 3b 0a 20 20 69 66 28 20 72 63  pMain);.  if( rc
11ed0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 23  ==SQLITE_OK ){.#
11ee0 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f  if SQLITE_MAX_WO
11ef0 52 4b 45 52 5f 54 48 52 45 41 44 53 0a 20 20 20  RKER_THREADS.   
11f00 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 62 55   if( pSorter->bU
11f10 73 65 54 68 72 65 61 64 73 20 29 7b 0a 20 20 20  seThreads ){.   
11f20 20 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70 49     PmaReader *pI
11f30 74 65 72 3b 0a 20 20 20 20 20 20 53 6f 72 74 53  ter;.      SortS
11f40 75 62 74 61 73 6b 20 2a 70 4c 61 73 74 20 3d 20  ubtask *pLast = 
11f50 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b  &pSorter->aTask[
11f60 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31  pSorter->nTask-1
11f70 5d 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64  ];.      rc = vd
11f80 62 65 53 6f 72 74 41 6c 6c 6f 63 55 6e 70 61 63  beSortAllocUnpac
11f90 6b 65 64 28 70 4c 61 73 74 29 3b 0a 20 20 20 20  ked(pLast);.    
11fa0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
11fb0 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 70  _OK ){.        p
11fc0 49 74 65 72 20 3d 20 28 50 6d 61 52 65 61 64 65  Iter = (PmaReade
11fd0 72 2a 29 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c  r*)sqlite3DbMall
11fe0 6f 63 5a 65 72 6f 28 64 62 2c 20 73 69 7a 65 6f  ocZero(db, sizeo
11ff0 66 28 50 6d 61 52 65 61 64 65 72 29 29 3b 0a 20  f(PmaReader));. 
12000 20 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e         pSorter->
12010 70 52 65 61 64 65 72 20 3d 20 70 49 74 65 72 3b  pReader = pIter;
12020 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69  .      }.      i
12030 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
12040 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d   ){.        rc =
12050 20 76 64 62 65 49 6e 63 72 4e 65 77 28 70 4c 61   vdbeIncrNew(pLa
12060 73 74 2c 20 70 4d 61 69 6e 2c 20 26 70 49 74 65  st, pMain, &pIte
12070 72 2d 3e 70 49 6e 63 72 29 3b 0a 20 20 20 20 20  r->pIncr);.     
12080 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
12090 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
120a0 20 20 76 64 62 65 49 6e 63 72 53 65 74 54 68 72    vdbeIncrSetThr
120b0 65 61 64 73 28 70 49 74 65 72 2d 3e 70 49 6e 63  eads(pIter->pInc
120c0 72 2c 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65  r, pSorter->bUse
120d0 54 68 72 65 61 64 73 29 3b 0a 20 20 20 20 20 20  Threads);.      
120e0 20 20 20 20 66 6f 72 28 69 54 61 73 6b 3d 30 3b      for(iTask=0;
120f0 20 69 54 61 73 6b 3c 28 70 53 6f 72 74 65 72 2d   iTask<(pSorter-
12100 3e 6e 54 61 73 6b 2d 31 29 3b 20 69 54 61 73 6b  >nTask-1); iTask
12110 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  ++){.           
12120 20 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e   IncrMerger *pIn
12130 63 72 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  cr;.            
12140 69 66 28 20 28 70 49 6e 63 72 20 3d 20 70 4d 61  if( (pIncr = pMa
12150 69 6e 2d 3e 61 49 74 65 72 5b 69 54 61 73 6b 5d  in->aIter[iTask]
12160 2e 70 49 6e 63 72 29 20 29 7b 0a 20 20 20 20 20  .pIncr) ){.     
12170 20 20 20 20 20 20 20 20 20 76 64 62 65 49 6e 63           vdbeInc
12180 72 53 65 74 54 68 72 65 61 64 73 28 70 49 6e 63  rSetThreads(pInc
12190 72 2c 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65  r, pSorter->bUse
121a0 54 68 72 65 61 64 73 29 3b 0a 20 20 20 20 20 20  Threads);.      
121b0 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
121c0 70 49 6e 63 72 2d 3e 70 54 61 73 6b 21 3d 70 4c  pIncr->pTask!=pL
121d0 61 73 74 20 29 3b 0a 20 20 20 20 20 20 20 20 20  ast );.         
121e0 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 7d     }.          }
121f0 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 70  .          if( p
12200 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3e 31 20  Sorter->nTask>1 
12210 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 66  ){.            f
12220 6f 72 28 69 54 61 73 6b 3d 30 3b 20 72 63 3d 3d  or(iTask=0; rc==
12230 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 54 61  SQLITE_OK && iTa
12240 73 6b 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73  sk<pSorter->nTas
12250 6b 3b 20 69 54 61 73 6b 2b 2b 29 7b 0a 20 20 20  k; iTask++){.   
12260 20 20 20 20 20 20 20 20 20 20 20 50 6d 61 52 65             PmaRe
12270 61 64 65 72 20 2a 70 20 3d 20 26 70 4d 61 69 6e  ader *p = &pMain
12280 2d 3e 61 49 74 65 72 5b 69 54 61 73 6b 5d 3b 0a  ->aIter[iTask];.
12290 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 73                as
122a0 73 65 72 74 28 20 70 2d 3e 70 49 6e 63 72 3d 3d  sert( p->pIncr==
122b0 30 20 7c 7c 20 70 2d 3e 70 49 6e 63 72 2d 3e 70  0 || p->pIncr->p
122c0 54 61 73 6b 3d 3d 26 70 53 6f 72 74 65 72 2d 3e  Task==&pSorter->
122d0 61 54 61 73 6b 5b 69 54 61 73 6b 5d 20 29 3b 0a  aTask[iTask] );.
122e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
122f0 28 20 70 2d 3e 70 49 6e 63 72 20 29 7b 20 72 63  ( p->pIncr ){ rc
12300 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65 72   = vdbePmaReader
12310 42 67 49 6e 63 72 49 6e 69 74 28 70 29 3b 20 7d  BgIncrInit(p); }
12320 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20  .            }. 
12330 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
12340 20 20 20 7d 0a 20 20 20 20 20 20 20 20 70 4d 61     }.        pMa
12350 69 6e 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a  in = 0;.      }.
12360 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
12370 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
12380 20 20 20 69 6e 74 20 65 4d 6f 64 65 20 3d 20 28     int eMode = (
12390 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3e 31  pSorter->nTask>1
123a0 20 3f 20 49 4e 43 52 49 4e 49 54 32 5f 52 4f 4f   ? INCRINIT2_ROO
123b0 54 20 3a 20 49 4e 43 52 49 4e 49 54 32 5f 4e 4f  T : INCRINIT2_NO
123c0 52 4d 41 4c 29 3b 0a 20 20 20 20 20 20 20 20 72  RMAL);.        r
123d0 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65  c = vdbePmaReade
123e0 72 49 6e 63 72 49 6e 69 74 28 70 49 74 65 72 2c  rIncrInit(pIter,
123f0 20 65 4d 6f 64 65 29 3b 0a 20 20 20 20 20 20 7d   eMode);.      }
12400 0a 20 20 20 20 7d 65 6c 73 65 0a 23 65 6e 64 69  .    }else.#endi
12410 66 0a 20 20 20 20 7b 0a 20 20 20 20 20 20 72 63  f.    {.      rc
12420 20 3d 20 76 64 62 65 49 6e 63 72 49 6e 69 74 4d   = vdbeIncrInitM
12430 65 72 67 65 72 28 70 54 61 73 6b 30 2c 20 70 4d  erger(pTask0, pM
12440 61 69 6e 2c 20 49 4e 43 52 49 4e 49 54 32 5f 4e  ain, INCRINIT2_N
12450 4f 52 4d 41 4c 29 3b 0a 20 20 20 20 20 20 70 53  ORMAL);.      pS
12460 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 20 3d  orter->pMerger =
12470 20 70 4d 61 69 6e 3b 0a 20 20 20 20 20 20 70 4d   pMain;.      pM
12480 61 69 6e 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20  ain = 0;.    }. 
12490 20 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53 51   }..  if( rc!=SQ
124a0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76  LITE_OK ){.    v
124b0 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46 72  dbeMergeEngineFr
124c0 65 65 28 70 4d 61 69 6e 29 3b 0a 20 20 7d 0a 20  ee(pMain);.  }. 
124d0 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a   return rc;.}...
124e0 2f 2a 0a 2a 2a 20 4f 6e 63 65 20 74 68 65 20 73  /*.** Once the s
124f0 6f 72 74 65 72 20 68 61 73 20 62 65 65 6e 20 70  orter has been p
12500 6f 70 75 6c 61 74 65 64 20 62 79 20 63 61 6c 6c  opulated by call
12510 73 20 74 6f 20 73 71 6c 69 74 65 33 56 64 62 65  s to sqlite3Vdbe
12520 53 6f 72 74 65 72 57 72 69 74 65 2c 0a 2a 2a 20  SorterWrite,.** 
12530 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  this function is
12540 20 63 61 6c 6c 65 64 20 74 6f 20 70 72 65 70 61   called to prepa
12550 72 65 20 66 6f 72 20 69 74 65 72 61 74 69 6e 67  re for iterating
12560 20 74 68 72 6f 75 67 68 20 74 68 65 20 72 65 63   through the rec
12570 6f 72 64 73 0a 2a 2a 20 69 6e 20 73 6f 72 74 65  ords.** in sorte
12580 64 20 6f 72 64 65 72 2e 0a 2a 2f 0a 69 6e 74 20  d order..*/.int 
12590 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
125a0 72 52 65 77 69 6e 64 28 73 71 6c 69 74 65 33 20  rRewind(sqlite3 
125b0 2a 64 62 2c 20 63 6f 6e 73 74 20 56 64 62 65 43  *db, const VdbeC
125c0 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74  ursor *pCsr, int
125d0 20 2a 70 62 45 6f 66 29 7b 0a 20 20 56 64 62 65   *pbEof){.  Vdbe
125e0 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20  Sorter *pSorter 
125f0 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b  = pCsr->pSorter;
12600 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
12610 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
12620 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
12630 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20  e */..  assert( 
12640 70 53 6f 72 74 65 72 20 29 3b 0a 0a 20 20 2f 2a  pSorter );..  /*
12650 20 49 66 20 6e 6f 20 64 61 74 61 20 68 61 73 20   If no data has 
12660 62 65 65 6e 20 77 72 69 74 74 65 6e 20 74 6f 20  been written to 
12670 64 69 73 6b 2c 20 74 68 65 6e 20 64 6f 20 6e 6f  disk, then do no
12680 74 20 64 6f 20 73 6f 20 6e 6f 77 2e 20 49 6e 73  t do so now. Ins
12690 74 65 61 64 2c 0a 20 20 2a 2a 20 73 6f 72 74 20  tead,.  ** sort 
126a0 74 68 65 20 56 64 62 65 53 6f 72 74 65 72 2e 70  the VdbeSorter.p
126b0 52 65 63 6f 72 64 20 6c 69 73 74 2e 20 54 68 65  Record list. The
126c0 20 76 64 62 65 20 6c 61 79 65 72 20 77 69 6c 6c   vdbe layer will
126d0 20 72 65 61 64 20 64 61 74 61 20 64 69 72 65 63   read data direc
126e0 74 6c 79 0a 20 20 2a 2a 20 66 72 6f 6d 20 74 68  tly.  ** from th
126f0 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74  e in-memory list
12700 2e 20 20 2a 2f 0a 20 20 69 66 28 20 70 53 6f 72  .  */.  if( pSor
12710 74 65 72 2d 3e 62 55 73 65 50 4d 41 3d 3d 30 20  ter->bUsePMA==0 
12720 29 7b 0a 20 20 20 20 69 66 28 20 70 53 6f 72 74  ){.    if( pSort
12730 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 29  er->list.pList )
12740 7b 0a 20 20 20 20 20 20 2a 70 62 45 6f 66 20 3d  {.      *pbEof =
12750 20 30 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 76   0;.      rc = v
12760 64 62 65 53 6f 72 74 65 72 53 6f 72 74 28 26 70  dbeSorterSort(&p
12770 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 30 5d  Sorter->aTask[0]
12780 2c 20 26 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74  , &pSorter->list
12790 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
127a0 20 20 20 20 2a 70 62 45 6f 66 20 3d 20 31 3b 0a      *pbEof = 1;.
127b0 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75 72 6e      }.    return
127c0 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 57   rc;.  }..  /* W
127d0 72 69 74 65 20 74 68 65 20 63 75 72 72 65 6e 74  rite the current
127e0 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20   in-memory list 
127f0 74 6f 20 61 20 50 4d 41 2e 20 2a 2f 0a 20 20 69  to a PMA. */.  i
12800 66 28 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74  f( pSorter->list
12810 2e 70 4c 69 73 74 20 29 7b 0a 20 20 20 20 72 63  .pList ){.    rc
12820 20 3d 20 76 64 62 65 53 6f 72 74 65 72 46 6c 75   = vdbeSorterFlu
12830 73 68 50 4d 41 28 70 53 6f 72 74 65 72 29 3b 0a  shPMA(pSorter);.
12840 20 20 7d 0a 0a 20 20 2f 2a 20 4a 6f 69 6e 20 61    }..  /* Join a
12850 6c 6c 20 74 68 72 65 61 64 73 20 2a 2f 0a 20 20  ll threads */.  
12860 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4a  rc = vdbeSorterJ
12870 6f 69 6e 41 6c 6c 28 70 53 6f 72 74 65 72 2c 20  oinAll(pSorter, 
12880 72 63 29 3b 0a 0a 20 20 76 64 62 65 53 6f 72 74  rc);..  vdbeSort
12890 65 72 52 65 77 69 6e 64 44 65 62 75 67 28 64 62  erRewindDebug(db
128a0 2c 20 22 72 65 77 69 6e 64 22 29 3b 0a 0a 20 20  , "rewind");..  
128b0 2f 2a 20 41 73 73 75 6d 69 6e 67 20 6e 6f 20 65  /* Assuming no e
128c0 72 72 6f 72 73 20 68 61 76 65 20 6f 63 63 75 72  rrors have occur
128d0 72 65 64 2c 20 73 65 74 20 75 70 20 61 20 6d 65  red, set up a me
128e0 72 67 65 72 20 73 74 72 75 63 74 75 72 65 20 74  rger structure t
128f0 6f 20 0a 20 20 2a 2a 20 69 6e 63 72 65 6d 65 6e  o .  ** incremen
12900 74 61 6c 6c 79 20 72 65 61 64 20 61 6e 64 20 6d  tally read and m
12910 65 72 67 65 20 61 6c 6c 20 72 65 6d 61 69 6e 69  erge all remaini
12920 6e 67 20 50 4d 41 73 2e 20 20 2a 2f 0a 20 20 61  ng PMAs.  */.  a
12930 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e  ssert( pSorter->
12940 70 52 65 61 64 65 72 3d 3d 30 20 29 3b 0a 20 20  pReader==0 );.  
12950 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
12960 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64  K ){.    rc = vd
12970 62 65 53 6f 72 74 65 72 53 65 74 75 70 4d 65 72  beSorterSetupMer
12980 67 65 28 70 53 6f 72 74 65 72 29 3b 0a 20 20 20  ge(pSorter);.   
12990 20 2a 70 62 45 6f 66 20 3d 20 30 3b 0a 20 20 7d   *pbEof = 0;.  }
129a0 0a 0a 20 20 76 64 62 65 53 6f 72 74 65 72 52 65  ..  vdbeSorterRe
129b0 77 69 6e 64 44 65 62 75 67 28 64 62 2c 20 22 72  windDebug(db, "r
129c0 65 77 69 6e 64 64 6f 6e 65 22 29 3b 0a 20 20 72  ewinddone");.  r
129d0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
129e0 2a 2a 20 41 64 76 61 6e 63 65 20 74 6f 20 74 68  ** Advance to th
129f0 65 20 6e 65 78 74 20 65 6c 65 6d 65 6e 74 20 69  e next element i
12a00 6e 20 74 68 65 20 73 6f 72 74 65 72 2e 0a 2a 2f  n the sorter..*/
12a10 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65  .int sqlite3Vdbe
12a20 53 6f 72 74 65 72 4e 65 78 74 28 73 71 6c 69 74  SorterNext(sqlit
12a30 65 33 20 2a 64 62 2c 20 63 6f 6e 73 74 20 56 64  e3 *db, const Vd
12a40 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  beCursor *pCsr, 
12a50 69 6e 74 20 2a 70 62 45 6f 66 29 7b 0a 20 20 56  int *pbEof){.  V
12a60 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
12a70 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74  er = pCsr->pSort
12a80 65 72 3b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20  er;.  int rc;   
12a90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12aa0 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
12ab0 63 6f 64 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72  code */..  asser
12ac0 74 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65  t( pSorter->bUse
12ad0 50 4d 41 20 7c 7c 20 28 70 53 6f 72 74 65 72 2d  PMA || (pSorter-
12ae0 3e 70 52 65 61 64 65 72 3d 3d 30 20 26 26 20 70  >pReader==0 && p
12af0 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 3d  Sorter->pMerger=
12b00 3d 30 29 20 29 3b 0a 20 20 69 66 28 20 70 53 6f  =0) );.  if( pSo
12b10 72 74 65 72 2d 3e 62 55 73 65 50 4d 41 20 29 7b  rter->bUsePMA ){
12b20 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 53 6f  .    assert( pSo
12b30 72 74 65 72 2d 3e 70 52 65 61 64 65 72 3d 3d 30  rter->pReader==0
12b40 20 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65   || pSorter->pMe
12b50 72 67 65 72 3d 3d 30 20 29 3b 0a 20 20 20 20 61  rger==0 );.    a
12b60 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e  ssert( pSorter->
12b70 62 55 73 65 54 68 72 65 61 64 73 3d 3d 30 20 7c  bUseThreads==0 |
12b80 7c 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 61 64  | pSorter->pRead
12b90 65 72 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  er );.    assert
12ba0 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54  ( pSorter->bUseT
12bb0 68 72 65 61 64 73 3d 3d 31 20 7c 7c 20 70 53 6f  hreads==1 || pSo
12bc0 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 20 29 3b  rter->pMerger );
12bd0 0a 20 20 20 20 69 66 28 20 70 53 6f 72 74 65 72  .    if( pSorter
12be0 2d 3e 62 55 73 65 54 68 72 65 61 64 73 20 29 7b  ->bUseThreads ){
12bf0 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65  .      rc = vdbe
12c00 50 6d 61 52 65 61 64 65 72 4e 65 78 74 28 70 53  PmaReaderNext(pS
12c10 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72 29 3b  orter->pReader);
12c20 0a 20 20 20 20 20 20 2a 70 62 45 6f 66 20 3d 20  .      *pbEof = 
12c30 28 70 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65  (pSorter->pReade
12c40 72 2d 3e 70 46 69 6c 65 3d 3d 30 29 3b 0a 20 20  r->pFile==0);.  
12c50 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72    }else{.      r
12c60 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4e 65  c = vdbeSorterNe
12c70 78 74 28 26 70 53 6f 72 74 65 72 2d 3e 61 54 61  xt(&pSorter->aTa
12c80 73 6b 5b 30 5d 2c 20 70 53 6f 72 74 65 72 2d 3e  sk[0], pSorter->
12c90 70 4d 65 72 67 65 72 2c 20 70 62 45 6f 66 29 3b  pMerger, pbEof);
12ca0 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a  .    }.  }else{.
12cb0 20 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64      SorterRecord
12cc0 20 2a 70 46 72 65 65 20 3d 20 70 53 6f 72 74 65   *pFree = pSorte
12cd0 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 3b 0a 20  r->list.pList;. 
12ce0 20 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74     pSorter->list
12cf0 2e 70 4c 69 73 74 20 3d 20 70 46 72 65 65 2d 3e  .pList = pFree->
12d00 75 2e 70 4e 65 78 74 3b 0a 20 20 20 20 70 46 72  u.pNext;.    pFr
12d10 65 65 2d 3e 75 2e 70 4e 65 78 74 20 3d 20 30 3b  ee->u.pNext = 0;
12d20 0a 20 20 20 20 69 66 28 20 70 53 6f 72 74 65 72  .    if( pSorter
12d30 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d  ->list.aMemory==
12d40 30 20 29 20 76 64 62 65 53 6f 72 74 65 72 52 65  0 ) vdbeSorterRe
12d50 63 6f 72 64 46 72 65 65 28 64 62 2c 20 70 46 72  cordFree(db, pFr
12d60 65 65 29 3b 0a 20 20 20 20 2a 70 62 45 6f 66 20  ee);.    *pbEof 
12d70 3d 20 21 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74  = !pSorter->list
12d80 2e 70 4c 69 73 74 3b 0a 20 20 20 20 72 63 20 3d  .pList;.    rc =
12d90 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a   SQLITE_OK;.  }.
12da0 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
12db0 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70  /*.** Return a p
12dc0 6f 69 6e 74 65 72 20 74 6f 20 61 20 62 75 66 66  ointer to a buff
12dd0 65 72 20 6f 77 6e 65 64 20 62 79 20 74 68 65 20  er owned by the 
12de0 73 6f 72 74 65 72 20 74 68 61 74 20 63 6f 6e 74  sorter that cont
12df0 61 69 6e 73 20 74 68 65 20 0a 2a 2a 20 63 75 72  ains the .** cur
12e00 72 65 6e 74 20 6b 65 79 2e 0a 2a 2f 0a 73 74 61  rent key..*/.sta
12e10 74 69 63 20 76 6f 69 64 20 2a 76 64 62 65 53 6f  tic void *vdbeSo
12e20 72 74 65 72 52 6f 77 6b 65 79 28 0a 20 20 63 6f  rterRowkey(.  co
12e30 6e 73 74 20 56 64 62 65 53 6f 72 74 65 72 20 2a  nst VdbeSorter *
12e40 70 53 6f 72 74 65 72 2c 20 20 20 20 20 20 2f 2a  pSorter,      /*
12e50 20 53 6f 72 74 65 72 20 6f 62 6a 65 63 74 20 2a   Sorter object *
12e60 2f 0a 20 20 69 6e 74 20 2a 70 6e 4b 65 79 20 20  /.  int *pnKey  
12e70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12e80 20 20 20 20 2f 2a 20 4f 55 54 3a 20 53 69 7a 65      /* OUT: Size
12e90 20 6f 66 20 63 75 72 72 65 6e 74 20 6b 65 79 20   of current key 
12ea0 69 6e 20 62 79 74 65 73 20 2a 2f 0a 29 7b 0a 20  in bytes */.){. 
12eb0 20 76 6f 69 64 20 2a 70 4b 65 79 3b 0a 20 20 69   void *pKey;.  i
12ec0 66 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65  f( pSorter->bUse
12ed0 50 4d 41 20 29 7b 0a 20 20 20 20 50 6d 61 52 65  PMA ){.    PmaRe
12ee0 61 64 65 72 20 2a 70 52 65 61 64 65 72 20 3d 20  ader *pReader = 
12ef0 28 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68  (pSorter->bUseTh
12f00 72 65 61 64 73 20 3f 0a 20 20 20 20 20 20 20 20  reads ?.        
12f10 70 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72  pSorter->pReader
12f20 20 3a 20 26 70 53 6f 72 74 65 72 2d 3e 70 4d 65   : &pSorter->pMe
12f30 72 67 65 72 2d 3e 61 49 74 65 72 5b 70 53 6f 72  rger->aIter[pSor
12f40 74 65 72 2d 3e 70 4d 65 72 67 65 72 2d 3e 61 54  ter->pMerger->aT
12f50 72 65 65 5b 31 5d 5d 0a 20 20 20 20 29 3b 0a 20  ree[1]].    );. 
12f60 20 20 20 2a 70 6e 4b 65 79 20 3d 20 70 52 65 61     *pnKey = pRea
12f70 64 65 72 2d 3e 6e 4b 65 79 3b 0a 20 20 20 20 70  der->nKey;.    p
12f80 4b 65 79 20 3d 20 70 52 65 61 64 65 72 2d 3e 61  Key = pReader->a
12f90 4b 65 79 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  Key;.  }else{.  
12fa0 20 20 2a 70 6e 4b 65 79 20 3d 20 70 53 6f 72 74    *pnKey = pSort
12fb0 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 2d 3e  er->list.pList->
12fc0 6e 56 61 6c 3b 0a 20 20 20 20 70 4b 65 79 20 3d  nVal;.    pKey =
12fd0 20 53 52 56 41 4c 28 70 53 6f 72 74 65 72 2d 3e   SRVAL(pSorter->
12fe0 6c 69 73 74 2e 70 4c 69 73 74 29 3b 0a 20 20 7d  list.pList);.  }
12ff0 0a 20 20 72 65 74 75 72 6e 20 70 4b 65 79 3b 0a  .  return pKey;.
13000 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20 74 68  }../*.** Copy th
13010 65 20 63 75 72 72 65 6e 74 20 73 6f 72 74 65 72  e current sorter
13020 20 6b 65 79 20 69 6e 74 6f 20 74 68 65 20 6d 65   key into the me
13030 6d 6f 72 79 20 63 65 6c 6c 20 70 4f 75 74 2e 0a  mory cell pOut..
13040 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64  */.int sqlite3Vd
13050 62 65 53 6f 72 74 65 72 52 6f 77 6b 65 79 28 63  beSorterRowkey(c
13060 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72 20  onst VdbeCursor 
13070 2a 70 43 73 72 2c 20 4d 65 6d 20 2a 70 4f 75 74  *pCsr, Mem *pOut
13080 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20  ){.  VdbeSorter 
13090 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d  *pSorter = pCsr-
130a0 3e 70 53 6f 72 74 65 72 3b 0a 20 20 76 6f 69 64  >pSorter;.  void
130b0 20 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b 65 79   *pKey; int nKey
130c0 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53  ;           /* S
130d0 6f 72 74 65 72 20 6b 65 79 20 74 6f 20 63 6f 70  orter key to cop
130e0 79 20 69 6e 74 6f 20 70 4f 75 74 20 2a 2f 0a 0a  y into pOut */..
130f0 20 20 70 4b 65 79 20 3d 20 76 64 62 65 53 6f 72    pKey = vdbeSor
13100 74 65 72 52 6f 77 6b 65 79 28 70 53 6f 72 74 65  terRowkey(pSorte
13110 72 2c 20 26 6e 4b 65 79 29 3b 0a 20 20 69 66 28  r, &nKey);.  if(
13120 20 73 71 6c 69 74 65 33 56 64 62 65 4d 65 6d 47   sqlite3VdbeMemG
13130 72 6f 77 28 70 4f 75 74 2c 20 6e 4b 65 79 2c 20  row(pOut, nKey, 
13140 30 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  0) ){.    return
13150 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
13160 20 7d 0a 20 20 70 4f 75 74 2d 3e 6e 20 3d 20 6e   }.  pOut->n = n
13170 4b 65 79 3b 0a 20 20 4d 65 6d 53 65 74 54 79 70  Key;.  MemSetTyp
13180 65 46 6c 61 67 28 70 4f 75 74 2c 20 4d 45 4d 5f  eFlag(pOut, MEM_
13190 42 6c 6f 62 29 3b 0a 20 20 6d 65 6d 63 70 79 28  Blob);.  memcpy(
131a0 70 4f 75 74 2d 3e 7a 2c 20 70 4b 65 79 2c 20 6e  pOut->z, pKey, n
131b0 4b 65 79 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20  Key);..  return 
131c0 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
131d0 0a 2a 2a 20 43 6f 6d 70 61 72 65 20 74 68 65 20  .** Compare the 
131e0 6b 65 79 20 69 6e 20 6d 65 6d 6f 72 79 20 63 65  key in memory ce
131f0 6c 6c 20 70 56 61 6c 20 77 69 74 68 20 74 68 65  ll pVal with the
13200 20 6b 65 79 20 74 68 61 74 20 74 68 65 20 73 6f   key that the so
13210 72 74 65 72 20 63 75 72 73 6f 72 0a 2a 2a 20 70  rter cursor.** p
13220 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69 72  assed as the fir
13230 73 74 20 61 72 67 75 6d 65 6e 74 20 63 75 72 72  st argument curr
13240 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f 2e  ently points to.
13250 20 46 6f 72 20 74 68 65 20 70 75 72 70 6f 73 65   For the purpose
13260 73 20 6f 66 0a 2a 2a 20 74 68 65 20 63 6f 6d 70  s of.** the comp
13270 61 72 69 73 6f 6e 2c 20 69 67 6e 6f 72 65 20 74  arison, ignore t
13280 68 65 20 72 6f 77 69 64 20 66 69 65 6c 64 20 61  he rowid field a
13290 74 20 74 68 65 20 65 6e 64 20 6f 66 20 65 61 63  t the end of eac
132a0 68 20 72 65 63 6f 72 64 2e 0a 2a 2a 0a 2a 2a 20  h record..**.** 
132b0 49 66 20 74 68 65 20 73 6f 72 74 65 72 20 63 75  If the sorter cu
132c0 72 73 6f 72 20 6b 65 79 20 63 6f 6e 74 61 69 6e  rsor key contain
132d0 73 20 61 6e 79 20 4e 55 4c 4c 20 76 61 6c 75 65  s any NULL value
132e0 73 2c 20 63 6f 6e 73 69 64 65 72 20 69 74 20 74  s, consider it t
132f0 6f 20 62 65 0a 2a 2a 20 6c 65 73 73 20 74 68 61  o be.** less tha
13300 6e 20 70 56 61 6c 2e 20 45 76 65 6e 20 69 66 20  n pVal. Even if 
13310 70 56 61 6c 20 61 6c 73 6f 20 63 6f 6e 74 61 69  pVal also contai
13320 6e 73 20 4e 55 4c 4c 20 76 61 6c 75 65 73 2e 0a  ns NULL values..
13330 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 65 72 72 6f  **.** If an erro
13340 72 20 6f 63 63 75 72 73 2c 20 72 65 74 75 72 6e  r occurs, return
13350 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
13360 20 63 6f 64 65 20 28 69 2e 65 2e 20 53 51 4c 49   code (i.e. SQLI
13370 54 45 5f 4e 4f 4d 45 4d 29 2e 0a 2a 2a 20 4f 74  TE_NOMEM)..** Ot
13380 68 65 72 77 69 73 65 2c 20 73 65 74 20 2a 70 52  herwise, set *pR
13390 65 73 20 74 6f 20 61 20 6e 65 67 61 74 69 76 65  es to a negative
133a0 2c 20 7a 65 72 6f 20 6f 72 20 70 6f 73 69 74 69  , zero or positi
133b0 76 65 20 76 61 6c 75 65 20 69 66 20 74 68 65 0a  ve value if the.
133c0 2a 2a 20 6b 65 79 20 69 6e 20 70 56 61 6c 20 69  ** key in pVal i
133d0 73 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 2c 20  s smaller than, 
133e0 65 71 75 61 6c 20 74 6f 20 6f 72 20 6c 61 72 67  equal to or larg
133f0 65 72 20 74 68 61 6e 20 74 68 65 20 63 75 72 72  er than the curr
13400 65 6e 74 20 73 6f 72 74 65 72 0a 2a 2a 20 6b 65  ent sorter.** ke
13410 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f  y..**.** This ro
13420 75 74 69 6e 65 20 66 6f 72 6d 73 20 74 68 65 20  utine forms the 
13430 63 6f 72 65 20 6f 66 20 74 68 65 20 4f 50 5f 53  core of the OP_S
13440 6f 72 74 65 72 43 6f 6d 70 61 72 65 20 6f 70 63  orterCompare opc
13450 6f 64 65 2c 20 77 68 69 63 68 20 69 6e 0a 2a 2a  ode, which in.**
13460 20 74 75 72 6e 20 69 73 20 75 73 65 64 20 74 6f   turn is used to
13470 20 76 65 72 69 66 79 20 75 6e 69 71 75 65 6e 65   verify uniquene
13480 73 73 20 77 68 65 6e 20 63 6f 6e 73 74 72 75 63  ss when construc
13490 74 69 6e 67 20 61 20 55 4e 49 51 55 45 20 49 4e  ting a UNIQUE IN
134a0 44 45 58 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  DEX..*/.int sqli
134b0 74 65 33 56 64 62 65 53 6f 72 74 65 72 43 6f 6d  te3VdbeSorterCom
134c0 70 61 72 65 28 0a 20 20 63 6f 6e 73 74 20 56 64  pare(.  const Vd
134d0 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  beCursor *pCsr, 
134e0 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65          /* Sorte
134f0 72 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 4d 65  r cursor */.  Me
13500 6d 20 2a 70 56 61 6c 2c 20 20 20 20 20 20 20 20  m *pVal,        
13510 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
13520 20 56 61 6c 75 65 20 74 6f 20 63 6f 6d 70 61 72   Value to compar
13530 65 20 74 6f 20 63 75 72 72 65 6e 74 20 73 6f 72  e to current sor
13540 74 65 72 20 6b 65 79 20 2a 2f 0a 20 20 69 6e 74  ter key */.  int
13550 20 6e 49 67 6e 6f 72 65 2c 20 20 20 20 20 20 20   nIgnore,       
13560 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
13570 49 67 6e 6f 72 65 20 74 68 69 73 20 6d 61 6e 79  Ignore this many
13580 20 66 69 65 6c 64 73 20 61 74 20 74 68 65 20 65   fields at the e
13590 6e 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 52 65  nd */.  int *pRe
135a0 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s               
135b0 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
135c0 52 65 73 75 6c 74 20 6f 66 20 63 6f 6d 70 61 72  Result of compar
135d0 69 73 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 56 64 62  ison */.){.  Vdb
135e0 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72  eSorter *pSorter
135f0 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72   = pCsr->pSorter
13600 3b 0a 20 20 55 6e 70 61 63 6b 65 64 52 65 63 6f  ;.  UnpackedReco
13610 72 64 20 2a 72 32 20 3d 20 70 53 6f 72 74 65 72  rd *r2 = pSorter
13620 2d 3e 70 55 6e 70 61 63 6b 65 64 3b 0a 20 20 4b  ->pUnpacked;.  K
13630 65 79 49 6e 66 6f 20 2a 70 4b 65 79 49 6e 66 6f  eyInfo *pKeyInfo
13640 20 3d 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66   = pCsr->pKeyInf
13650 6f 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 76 6f  o;.  int i;.  vo
13660 69 64 20 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b  id *pKey; int nK
13670 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ey;           /*
13680 20 53 6f 72 74 65 72 20 6b 65 79 20 74 6f 20 63   Sorter key to c
13690 6f 6d 70 61 72 65 20 70 56 61 6c 20 77 69 74 68  ompare pVal with
136a0 20 2a 2f 0a 0a 20 20 69 66 28 20 72 32 3d 3d 30   */..  if( r2==0
136b0 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 70 3b   ){.    char *p;
136c0 0a 20 20 20 20 72 32 20 3d 20 70 53 6f 72 74 65  .    r2 = pSorte
136d0 72 2d 3e 70 55 6e 70 61 63 6b 65 64 20 3d 20 73  r->pUnpacked = s
136e0 71 6c 69 74 65 33 56 64 62 65 41 6c 6c 6f 63 55  qlite3VdbeAllocU
136f0 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 28 70 4b  npackedRecord(pK
13700 65 79 49 6e 66 6f 2c 30 2c 30 2c 26 70 29 3b 0a  eyInfo,0,0,&p);.
13710 20 20 20 20 61 73 73 65 72 74 28 20 70 53 6f 72      assert( pSor
13720 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64 3d 3d  ter->pUnpacked==
13730 28 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 2a  (UnpackedRecord*
13740 29 70 20 29 3b 0a 20 20 20 20 69 66 28 20 72 32  )p );.    if( r2
13750 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
13760 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 72  ITE_NOMEM;.    r
13770 32 2d 3e 6e 46 69 65 6c 64 20 3d 20 70 4b 65 79  2->nField = pKey
13780 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64 2d 6e 49 67  Info->nField-nIg
13790 6e 6f 72 65 3b 0a 20 20 7d 0a 20 20 61 73 73 65  nore;.  }.  asse
137a0 72 74 28 20 72 32 2d 3e 6e 46 69 65 6c 64 3e 3d  rt( r2->nField>=
137b0 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64  pKeyInfo->nField
137c0 2d 6e 49 67 6e 6f 72 65 20 29 3b 0a 0a 20 20 70  -nIgnore );..  p
137d0 4b 65 79 20 3d 20 76 64 62 65 53 6f 72 74 65 72  Key = vdbeSorter
137e0 52 6f 77 6b 65 79 28 70 53 6f 72 74 65 72 2c 20  Rowkey(pSorter, 
137f0 26 6e 4b 65 79 29 3b 0a 20 20 73 71 6c 69 74 65  &nKey);.  sqlite
13800 33 56 64 62 65 52 65 63 6f 72 64 55 6e 70 61 63  3VdbeRecordUnpac
13810 6b 28 70 4b 65 79 49 6e 66 6f 2c 20 6e 4b 65 79  k(pKeyInfo, nKey
13820 2c 20 70 4b 65 79 2c 20 72 32 29 3b 0a 20 20 66  , pKey, r2);.  f
13830 6f 72 28 69 3d 30 3b 20 69 3c 72 32 2d 3e 6e 46  or(i=0; i<r2->nF
13840 69 65 6c 64 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  ield; i++){.    
13850 69 66 28 20 72 32 2d 3e 61 4d 65 6d 5b 69 5d 2e  if( r2->aMem[i].
13860 66 6c 61 67 73 20 26 20 4d 45 4d 5f 4e 75 6c 6c  flags & MEM_Null
13870 20 29 7b 0a 20 20 20 20 20 20 2a 70 52 65 73 20   ){.      *pRes 
13880 3d 20 2d 31 3b 0a 20 20 20 20 20 20 72 65 74 75  = -1;.      retu
13890 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20  rn SQLITE_OK;.  
138a0 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 52 65 73    }.  }..  *pRes
138b0 20 3d 20 73 71 6c 69 74 65 33 56 64 62 65 52 65   = sqlite3VdbeRe
138c0 63 6f 72 64 43 6f 6d 70 61 72 65 28 70 56 61 6c  cordCompare(pVal
138d0 2d 3e 6e 2c 20 70 56 61 6c 2d 3e 7a 2c 20 72 32  ->n, pVal->z, r2
138e0 2c 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  , 0);.  return S
138f0 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a              QLITE_OK;.}.