/ Hex Artifact Content
Login

Artifact bc0d90e00abcc88997f463d4d41b7ba4a10cfd88:


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 54 41 42 4c 45 20 73 74 61 74 65 6d  ATE TABLE 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 0a 2a 2a 0a 2a 2a 20 41 6c 67  set()..**.** Alg
0bc0: 6f 72 69 74 68 6d 3a 0a 2a 2a 0a 2a 2a 20 52 65  orithm:.**.** Re
0bd0: 63 6f 72 64 73 20 74 6f 20 62 65 20 73 6f 72 74  cords to be sort
0be0: 65 64 20 61 72 65 20 69 6e 69 74 69 61 6c 6c 79  ed are initially
0bf0: 20 68 65 6c 64 20 69 6e 20 6d 65 6d 6f 72 79 2c   held in memory,
0c00: 20 69 6e 20 74 68 65 20 6f 72 64 65 72 20 69 6e   in the order in
0c10: 0a 2a 2a 20 77 68 69 63 68 20 74 68 65 79 20 61  .** which they a
0c20: 72 72 69 76 65 20 66 72 6f 6d 20 57 72 69 74 65  rrive from Write
0c30: 28 29 2e 20 20 57 68 65 6e 20 74 68 65 20 61 6d  ().  When the am
0c40: 6f 75 6e 74 20 6f 66 20 6d 65 6d 6f 72 79 20 6e  ount of memory n
0c50: 65 65 64 65 64 20 65 78 63 65 65 64 73 0a 2a 2a  eeded exceeds.**
0c60: 20 61 20 74 68 72 65 73 68 6f 6c 64 2c 20 61 6c   a threshold, al
0c70: 6c 20 69 6e 2d 6d 65 6d 6f 72 79 20 72 65 63 6f  l in-memory reco
0c80: 72 64 73 20 61 72 65 20 73 6f 72 74 65 64 20 61  rds are sorted a
0c90: 6e 64 20 74 68 65 6e 20 61 70 70 65 6e 64 65 64  nd then appended
0ca0: 20 74 6f 0a 2a 2a 20 61 20 74 65 6d 70 6f 72 61   to.** a tempora
0cb0: 72 79 20 66 69 6c 65 20 61 73 20 61 20 22 50 61  ry file as a "Pa
0cc0: 63 6b 65 64 2d 4d 65 6d 6f 72 79 2d 41 72 72 61  cked-Memory-Arra
0cd0: 79 22 20 6f 72 20 22 50 4d 41 22 20 61 6e 64 20  y" or "PMA" and 
0ce0: 74 68 65 20 6d 65 6d 6f 72 79 20 69 73 0a 2a 2a  the memory is.**
0cf0: 20 72 65 73 65 74 2e 20 20 54 68 65 72 65 20 69   reset.  There i
0d00: 73 20 61 20 73 69 6e 67 6c 65 20 74 65 6d 70 6f  s a single tempo
0d10: 72 61 72 79 20 66 69 6c 65 20 75 73 65 64 20 66  rary file used f
0d20: 6f 72 20 61 6c 6c 20 50 4d 41 73 2e 20 20 54 68  or all PMAs.  Th
0d30: 65 20 50 4d 41 73 0a 2a 2a 20 61 72 65 20 70 61  e PMAs.** are pa
0d40: 63 6b 65 64 20 6f 6e 65 20 61 66 74 65 72 20 61  cked one after a
0d50: 6e 6f 74 68 65 72 20 69 6e 20 74 68 65 20 66 69  nother in the fi
0d60: 6c 65 2e 20 20 54 68 65 20 56 64 62 65 53 6f 72  le.  The VdbeSor
0d70: 74 65 72 20 6f 62 6a 65 63 74 20 6b 65 65 70 73  ter object keeps
0d80: 0a 2a 2a 20 74 72 61 63 6b 20 6f 66 20 74 68 65  .** track of the
0d90: 20 6e 75 6d 62 65 72 20 6f 66 20 50 4d 41 73 20   number of PMAs 
0da0: 77 72 69 74 74 65 6e 2e 0a 2a 2a 0a 2a 2a 20 57  written..**.** W
0db0: 68 65 6e 20 74 68 65 20 52 65 77 69 6e 64 28 29  hen the Rewind()
0dc0: 20 69 73 20 73 65 65 6e 2c 20 61 6e 79 20 72 65   is seen, any re
0dd0: 63 6f 72 64 73 20 73 74 69 6c 6c 20 68 65 6c 64  cords still held
0de0: 20 69 6e 20 6d 65 6d 6f 72 79 20 61 72 65 20 73   in memory are s
0df0: 6f 72 74 65 64 2e 0a 2a 2a 20 49 66 20 6e 6f 20  orted..** If no 
0e00: 50 4d 41 73 20 68 61 76 65 20 62 65 65 6e 20 77  PMAs have been w
0e10: 72 69 74 74 65 6e 20 28 69 66 20 61 6c 6c 20 72  ritten (if all r
0e20: 65 63 6f 72 64 73 20 61 72 65 20 73 74 69 6c 6c  ecords are still
0e30: 20 68 65 6c 64 20 69 6e 20 6d 65 6d 6f 72 79 29   held in memory)
0e40: 0a 2a 2a 20 74 68 65 6e 20 73 75 62 73 65 71 75  .** then subsequ
0e50: 65 6e 74 20 52 6f 77 6b 65 79 28 29 2c 20 4e 65  ent Rowkey(), Ne
0e60: 78 74 28 29 2c 20 61 6e 64 20 43 6f 6d 70 61 72  xt(), and Compar
0e70: 65 28 29 20 6f 70 65 72 61 74 69 6f 6e 73 20 77  e() operations w
0e80: 6f 72 6b 20 64 69 72 65 63 74 6c 79 0a 2a 2a 20  ork directly.** 
0e90: 66 72 6f 6d 20 6d 65 6d 6f 72 79 2e 20 20 42 75  from memory.  Bu
0ea0: 74 20 69 66 20 50 4d 41 73 20 68 61 76 65 20 62  t if PMAs have b
0eb0: 65 65 6e 20 77 72 69 74 74 65 6e 20 74 68 69 6e  een written thin
0ec0: 67 73 20 67 65 74 20 61 20 6c 69 74 74 6c 65 20  gs get a little 
0ed0: 6d 6f 72 65 0a 2a 2a 20 63 6f 6d 70 6c 69 63 61  more.** complica
0ee0: 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20  ted..**.** When 
0ef0: 52 65 77 69 6e 64 28 29 20 69 73 20 73 65 65 6e  Rewind() is seen
0f00: 20 61 66 74 65 72 20 50 4d 41 73 20 68 61 76 65   after PMAs have
0f10: 20 62 65 65 6e 20 77 72 69 74 74 65 6e 2c 20 61   been written, a
0f20: 6e 79 20 72 65 63 6f 72 64 73 20 73 74 69 6c 6c  ny records still
0f30: 0a 2a 2a 20 69 6e 20 6d 65 6d 6f 72 79 20 61 72  .** in memory ar
0f40: 65 20 73 6f 72 74 65 64 20 61 6e 64 20 77 72 69  e sorted and wri
0f50: 74 74 65 6e 20 61 73 20 61 20 66 69 6e 61 6c 20  tten as a final 
0f60: 50 4d 41 2e 20 20 54 68 65 6e 20 61 6c 6c 20 74  PMA.  Then all t
0f70: 68 65 20 50 4d 41 73 0a 2a 2a 20 61 72 65 20 6d  he PMAs.** are m
0f80: 65 72 67 65 64 20 74 6f 67 65 74 68 65 72 20 69  erged together i
0f90: 6e 74 6f 20 61 20 73 69 6e 67 6c 65 20 6d 61 73  nto a single mas
0fa0: 73 69 76 65 20 50 4d 41 20 74 68 61 74 20 4e 65  sive PMA that Ne
0fb0: 78 74 28 29 2c 20 52 6f 77 6b 65 79 28 29 2c 0a  xt(), Rowkey(),.
0fc0: 2a 2a 20 61 6e 64 20 43 6f 6d 70 61 72 65 28 29  ** and Compare()
0fd0: 20 77 61 6c 6b 20 74 6f 20 65 78 74 72 61 63 74   walk to extract
0fe0: 20 74 68 65 20 72 65 63 6f 72 64 73 20 69 6e 20   the records in 
0ff0: 73 6f 72 74 65 64 20 6f 72 64 65 72 2e 0a 2a 2a  sorted order..**
1000: 0a 2a 2a 20 49 66 20 53 51 4c 49 54 45 5f 4d 41  .** If SQLITE_MA
1010: 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53  X_WORKER_THREADS
1020: 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 76 61   is non-zero, va
1030: 72 69 6f 75 73 20 73 74 65 70 73 20 6f 66 20 74  rious steps of t
1040: 68 65 20 61 62 6f 76 65 0a 2a 2a 20 61 6c 67 6f  he above.** algo
1050: 72 69 74 68 6d 20 6d 69 67 68 74 20 62 65 20 70  rithm might be p
1060: 65 72 66 6f 72 6d 65 64 20 69 6e 20 70 61 72 61  erformed in para
1070: 6c 6c 65 6c 20 62 79 20 73 65 70 61 72 61 74 65  llel by separate
1080: 20 74 68 72 65 61 64 73 2e 20 20 54 68 72 65 61   threads.  Threa
1090: 64 73 0a 2a 2a 20 61 72 65 20 6f 6e 6c 79 20 75  ds.** are only u
10a0: 73 65 64 20 77 68 65 6e 20 6f 6e 65 20 6f 72 20  sed when one or 
10b0: 6d 6f 72 65 20 50 4d 41 20 73 70 69 6c 6c 20 74  more PMA spill t
10c0: 6f 20 64 69 73 6b 2e 20 20 49 66 20 74 68 65 20  o disk.  If the 
10d0: 73 6f 72 74 20 69 73 20 73 6d 61 6c 6c 0a 2a 2a  sort is small.**
10e0: 20 65 6e 6f 75 67 68 20 74 6f 20 66 69 74 20 65   enough to fit e
10f0: 6e 74 69 72 65 6c 79 20 69 6e 20 6d 65 6d 6f 72  ntirely in memor
1100: 79 2c 20 65 76 65 72 79 74 68 69 6e 67 20 68 61  y, everything ha
1110: 70 70 65 6e 73 20 6f 6e 20 74 68 65 20 6d 61 69  ppens on the mai
1120: 6e 20 74 68 72 65 61 64 2e 0a 2a 2f 0a 23 69 6e  n thread..*/.#in
1130: 63 6c 75 64 65 20 22 73 71 6c 69 74 65 49 6e 74  clude "sqliteInt
1140: 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 76 64  .h".#include "vd
1150: 62 65 49 6e 74 2e 68 22 0a 0a 2f 2a 20 0a 2a 2a  beInt.h"../* .**
1160: 20 49 66 20 53 51 4c 49 54 45 5f 44 45 42 55 47   If SQLITE_DEBUG
1170: 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44 53 20  _SORTER_THREADS 
1180: 69 73 20 64 65 66 69 6e 65 64 2c 20 74 68 69 73  is defined, this
1190: 20 6d 6f 64 75 6c 65 20 6f 75 74 70 75 74 73 20   module outputs 
11a0: 76 61 72 69 6f 75 73 0a 2a 2a 20 6d 65 73 73 61  various.** messa
11b0: 67 65 73 20 74 6f 20 73 74 64 65 72 72 20 74 68  ges to stderr th
11c0: 61 74 20 6d 61 79 20 62 65 20 68 65 6c 70 66 75  at may be helpfu
11d0: 6c 20 69 6e 20 75 6e 64 65 72 73 74 61 6e 64 69  l in understandi
11e0: 6e 67 20 74 68 65 20 70 65 72 66 6f 72 6d 61 6e  ng the performan
11f0: 63 65 0a 2a 2a 20 63 68 61 72 61 63 74 65 72 69  ce.** characteri
1200: 73 74 69 63 73 20 6f 66 20 74 68 65 20 73 6f 72  stics of the sor
1210: 74 65 72 20 69 6e 20 6d 75 6c 74 69 2d 74 68 72  ter in multi-thr
1220: 65 61 64 65 64 20 6d 6f 64 65 2e 0a 2a 2f 0a 23  eaded mode..*/.#
1230: 69 66 20 30 0a 23 20 64 65 66 69 6e 65 20 53 51  if 0.# define SQ
1240: 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f 52 54 45  LITE_DEBUG_SORTE
1250: 52 5f 54 48 52 45 41 44 53 20 31 0a 23 65 6e 64  R_THREADS 1.#end
1260: 69 66 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 76 61 74  if../*.** Privat
1270: 65 20 6f 62 6a 65 63 74 73 20 75 73 65 64 20 62  e objects used b
1280: 79 20 74 68 65 20 73 6f 72 74 65 72 0a 2a 2f 0a  y the sorter.*/.
1290: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 4d  typedef struct M
12a0: 65 72 67 65 45 6e 67 69 6e 65 20 4d 65 72 67 65  ergeEngine Merge
12b0: 45 6e 67 69 6e 65 3b 20 20 20 20 20 2f 2a 20 4d  Engine;     /* M
12c0: 65 72 67 65 20 50 4d 41 73 20 74 6f 67 65 74 68  erge PMAs togeth
12d0: 65 72 20 2a 2f 0a 74 79 70 65 64 65 66 20 73 74  er */.typedef st
12e0: 72 75 63 74 20 50 6d 61 52 65 61 64 65 72 20 50  ruct PmaReader P
12f0: 6d 61 52 65 61 64 65 72 3b 20 20 20 20 20 20 20  maReader;       
1300: 20 20 2f 2a 20 49 6e 63 72 65 6d 65 6e 74 61 6c    /* Incremental
1310: 6c 79 20 72 65 61 64 20 6f 6e 65 20 50 4d 41 20  ly read one PMA 
1320: 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  */.typedef struc
1330: 74 20 50 6d 61 57 72 69 74 65 72 20 50 6d 61 57  t PmaWriter PmaW
1340: 72 69 74 65 72 3b 20 20 20 20 20 20 20 20 20 2f  riter;         /
1350: 2a 20 49 6e 63 72 65 6d 65 6e 74 61 6c 6c 79 20  * Incrementally 
1360: 77 72 69 74 65 20 6f 6e 20 50 4d 41 20 2a 2f 0a  write on PMA */.
1370: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53  typedef struct S
1380: 6f 72 74 65 72 52 65 63 6f 72 64 20 53 6f 72 74  orterRecord Sort
1390: 65 72 52 65 63 6f 72 64 3b 20 20 20 2f 2a 20 41  erRecord;   /* A
13a0: 20 72 65 63 6f 72 64 20 62 65 69 6e 67 20 73 6f   record being so
13b0: 72 74 65 64 20 2a 2f 0a 74 79 70 65 64 65 66 20  rted */.typedef 
13c0: 73 74 72 75 63 74 20 53 6f 72 74 53 75 62 74 61  struct SortSubta
13d0: 73 6b 20 53 6f 72 74 53 75 62 74 61 73 6b 3b 20  sk SortSubtask; 
13e0: 20 20 20 20 2f 2a 20 41 20 73 75 62 2d 74 61 73      /* A sub-tas
13f0: 6b 20 69 6e 20 74 68 65 20 73 6f 72 74 20 70 72  k in the sort pr
1400: 6f 63 65 73 73 20 2a 2f 0a 74 79 70 65 64 65 66  ocess */.typedef
1410: 20 73 74 72 75 63 74 20 53 6f 72 74 65 72 46 69   struct SorterFi
1420: 6c 65 20 53 6f 72 74 65 72 46 69 6c 65 3b 0a 74  le SorterFile;.t
1430: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53 6f  ypedef struct So
1440: 72 74 65 72 54 68 72 65 61 64 20 53 6f 72 74 65  rterThread Sorte
1450: 72 54 68 72 65 61 64 3b 0a 74 79 70 65 64 65 66  rThread;.typedef
1460: 20 73 74 72 75 63 74 20 53 6f 72 74 65 72 4c 69   struct SorterLi
1470: 73 74 20 53 6f 72 74 65 72 4c 69 73 74 3b 0a 74  st SorterList;.t
1480: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 49 6e  ypedef struct In
1490: 63 72 4d 65 72 67 65 72 20 49 6e 63 72 4d 65 72  crMerger IncrMer
14a0: 67 65 72 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 63 6f  ger;../*.** A co
14b0: 6e 74 61 69 6e 65 72 20 66 6f 72 20 61 20 74 65  ntainer for a te
14c0: 6d 70 20 66 69 6c 65 20 68 61 6e 64 6c 65 20 61  mp file handle a
14d0: 6e 64 20 74 68 65 20 63 75 72 72 65 6e 74 20 61  nd the current a
14e0: 6d 6f 75 6e 74 20 6f 66 20 64 61 74 61 20 0a 2a  mount of data .*
14f0: 2a 20 73 74 6f 72 65 64 20 69 6e 20 74 68 65 20  * stored in the 
1500: 66 69 6c 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  file..*/.struct 
1510: 53 6f 72 74 65 72 46 69 6c 65 20 7b 0a 20 20 73  SorterFile {.  s
1520: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 64  qlite3_file *pFd
1530: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
1540: 2a 20 46 69 6c 65 20 68 61 6e 64 6c 65 20 2a 2f  * File handle */
1550: 0a 20 20 69 36 34 20 69 45 6f 66 3b 20 20 20 20  .  i64 iEof;    
1560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1570: 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 64     /* Bytes of d
1580: 61 74 61 20 73 74 6f 72 65 64 20 69 6e 20 70 46  ata stored in pF
1590: 64 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41  d */.};../*.** A
15a0: 6e 20 6f 62 6a 65 63 74 20 6f 66 20 74 68 69 73  n object of this
15b0: 20 74 79 70 65 20 69 73 20 75 73 65 64 20 74 6f   type is used to
15c0: 20 73 74 6f 72 65 20 74 68 65 20 74 68 72 65 61   store the threa
15d0: 64 20 68 61 6e 64 6c 65 20 66 6f 72 20 65 61 63  d handle for eac
15e0: 68 20 0a 2a 2a 20 62 61 63 6b 67 72 6f 75 6e 64  h .** background
15f0: 20 74 68 72 65 61 64 20 6c 61 75 6e 63 68 65 64   thread launched
1600: 20 62 79 20 74 68 65 20 73 6f 72 74 65 72 2e 20   by the sorter. 
1610: 42 65 66 6f 72 65 20 74 68 65 20 74 68 72 65 61  Before the threa
1620: 64 20 69 73 20 6c 61 75 6e 63 68 65 64 2c 0a 2a  d is launched,.*
1630: 2a 20 76 61 72 69 61 62 6c 65 20 62 44 6f 6e 65  * variable bDone
1640: 20 69 73 20 73 65 74 20 74 6f 20 30 2e 20 54 68   is set to 0. Th
1650: 65 6e 2c 20 72 69 67 68 74 20 62 65 66 6f 72 65  en, right before
1660: 20 69 74 20 65 78 69 74 73 2c 20 74 68 65 20 74   it exits, the t
1670: 68 72 65 61 64 20 0a 2a 2a 20 69 74 73 65 6c 66  hread .** itself
1680: 20 73 65 74 73 20 62 44 6f 6e 65 20 74 6f 20 31   sets bDone to 1
1690: 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20  ..**.** This is 
16a0: 74 68 65 6e 20 75 73 65 64 20 66 6f 72 20 74 77  then used for tw
16b0: 6f 20 70 75 72 70 6f 73 65 73 3a 0a 2a 2a 0a 2a  o purposes:.**.*
16c0: 2a 20 20 20 31 2e 20 57 68 65 6e 20 66 6c 75 73  *   1. When flus
16d0: 68 69 6e 67 20 74 68 65 20 63 6f 6e 74 65 6e 74  hing the content
16e0: 73 20 6f 66 20 6d 65 6d 6f 72 79 20 74 6f 20 61  s of memory to a
16f0: 20 6c 65 76 65 6c 2d 30 20 50 4d 41 20 6f 6e 20   level-0 PMA on 
1700: 64 69 73 6b 2c 20 74 6f 0a 2a 2a 20 20 20 20 20  disk, to.**     
1710: 20 61 74 74 65 6d 70 74 20 74 6f 20 73 65 6c 65   attempt to sele
1720: 63 74 20 61 20 53 6f 72 74 53 75 62 74 61 73 6b  ct a SortSubtask
1730: 20 66 6f 72 20 77 68 69 63 68 20 74 68 65 72 65   for which there
1740: 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20   is not already 
1750: 61 6e 0a 2a 2a 20 20 20 20 20 20 61 63 74 69 76  an.**      activ
1760: 65 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  e background thr
1770: 65 61 64 20 28 73 69 6e 63 65 20 64 6f 69 6e 67  ead (since doing
1780: 20 73 6f 20 63 61 75 73 65 73 20 74 68 65 20 6d   so causes the m
1790: 61 69 6e 20 74 68 72 65 61 64 0a 2a 2a 20 20 20  ain thread.**   
17a0: 20 20 20 74 6f 20 62 6c 6f 63 6b 20 75 6e 74 69     to block unti
17b0: 6c 20 69 74 20 66 69 6e 69 73 68 65 73 29 2e 0a  l it finishes)..
17c0: 2a 2a 0a 2a 2a 20 20 20 32 2e 20 49 66 20 53 51  **.**   2. If SQ
17d0: 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f 52 54 45  LITE_DEBUG_SORTE
17e0: 52 5f 54 48 52 45 41 44 53 20 69 73 20 64 65 66  R_THREADS is def
17f0: 69 6e 65 64 2c 20 74 6f 20 64 65 74 65 72 6d 69  ined, to determi
1800: 6e 65 20 69 66 20 61 20 63 61 6c 6c 0a 2a 2a 20  ne if a call.** 
1810: 20 20 20 20 20 74 6f 20 73 71 6c 69 74 65 33 54       to sqlite3T
1820: 68 72 65 61 64 4a 6f 69 6e 28 29 20 69 73 20 6c  hreadJoin() is l
1830: 69 6b 65 6c 79 20 74 6f 20 62 6c 6f 63 6b 2e 0a  ikely to block..
1840: 2a 2a 0a 2a 2a 20 49 6e 20 62 6f 74 68 20 63 61  **.** In both ca
1850: 73 65 73 2c 20 74 68 65 20 65 66 66 65 63 74 73  ses, the effects
1860: 20 6f 66 20 74 68 65 20 6d 61 69 6e 20 74 68 72   of the main thr
1870: 65 61 64 20 73 65 65 69 6e 67 20 28 62 44 6f 6e  ead seeing (bDon
1880: 65 3d 3d 30 29 20 65 76 65 6e 0a 2a 2a 20 61 66  e==0) even.** af
1890: 74 65 72 20 74 68 65 20 74 68 72 65 61 64 20 68  ter the thread h
18a0: 61 73 20 66 69 6e 69 73 68 65 64 20 61 72 65 20  as finished are 
18b0: 6e 6f 74 20 64 69 72 65 2e 20 53 6f 20 77 65 20  not dire. So we 
18c0: 64 6f 6e 27 74 20 77 6f 72 72 79 20 61 62 6f 75  don't worry abou
18d0: 74 0a 2a 2a 20 6d 65 6d 6f 72 79 20 62 61 72 72  t.** memory barr
18e0: 69 65 72 73 20 61 6e 64 20 73 75 63 68 20 68 65  iers and such he
18f0: 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 53 6f  re..*/.struct So
1900: 72 74 65 72 54 68 72 65 61 64 20 7b 0a 20 20 53  rterThread {.  S
1910: 51 4c 69 74 65 54 68 72 65 61 64 20 2a 70 54 68  QLiteThread *pTh
1920: 72 65 61 64 3b 0a 20 20 69 6e 74 20 62 44 6f 6e  read;.  int bDon
1930: 65 3b 0a 7d 3b 0a 0a 73 74 72 75 63 74 20 53 6f  e;.};..struct So
1940: 72 74 65 72 4c 69 73 74 20 7b 0a 20 20 53 6f 72  rterList {.  Sor
1950: 74 65 72 52 65 63 6f 72 64 20 2a 70 4c 69 73 74  terRecord *pList
1960: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
1970: 4c 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20 72  Linked list of r
1980: 65 63 6f 72 64 73 20 2a 2f 0a 20 20 75 38 20 2a  ecords */.  u8 *
1990: 61 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20 20 20  aMemory;        
19a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
19b0: 66 20 6e 6f 6e 2d 4e 55 4c 4c 2c 20 62 6c 6f 62  f non-NULL, blob
19c0: 20 6f 66 20 6d 65 6d 6f 72 79 20 66 6f 72 20 70   of memory for p
19d0: 4c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  List */.  int sz
19e0: 50 4d 41 3b 20 20 20 20 20 20 20 20 20 20 20 20  PMA;            
19f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
1a00: 65 20 6f 66 20 70 4c 69 73 74 20 61 73 20 50 4d  e of pList as PM
1a10: 41 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 7d 3b  A in bytes */.};
1a20: 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 69 6e 67 20  ../*.** Sorting 
1a30: 69 73 20 64 69 76 69 64 65 64 20 75 70 20 69 6e  is divided up in
1a40: 74 6f 20 73 6d 61 6c 6c 65 72 20 73 75 62 74 61  to smaller subta
1a50: 73 6b 73 2e 20 20 45 61 63 68 20 73 75 62 74 61  sks.  Each subta
1a60: 73 6b 20 69 73 20 63 6f 6e 74 72 6f 6c 6c 65 64  sk is controlled
1a70: 0a 2a 2a 20 62 79 20 61 6e 20 69 6e 73 74 61 6e  .** by an instan
1a80: 63 65 20 6f 66 20 74 68 69 73 20 6f 62 6a 65 63  ce of this objec
1a90: 74 2e 20 41 20 53 75 62 74 61 73 6b 20 6d 69 67  t. A Subtask mig
1aa0: 68 74 20 72 75 6e 20 69 6e 20 65 69 74 68 65 72  ht run in either
1ab0: 20 74 68 65 20 6d 61 69 6e 20 74 68 72 65 61 64   the main thread
1ac0: 0a 2a 2a 20 6f 72 20 69 6e 20 61 20 62 61 63 6b  .** or in a back
1ad0: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 2e 0a 2a  ground thread..*
1ae0: 2a 0a 2a 2a 20 45 78 61 63 74 6c 79 20 56 64 62  *.** Exactly Vdb
1af0: 65 53 6f 72 74 65 72 2e 6e 54 61 73 6b 20 69 6e  eSorter.nTask in
1b00: 73 74 61 6e 63 65 73 20 6f 66 20 74 68 69 73 20  stances of this 
1b10: 6f 62 6a 65 63 74 20 61 72 65 20 61 6c 6c 6f 63  object are alloc
1b20: 61 74 65 64 0a 2a 2a 20 61 73 20 70 61 72 74 20  ated.** as part 
1b30: 6f 66 20 65 61 63 68 20 56 64 62 65 53 6f 72 74  of each VdbeSort
1b40: 65 72 20 6f 62 6a 65 63 74 2e 20 49 6e 73 74 61  er object. Insta
1b50: 6e 63 65 73 20 61 72 65 20 6e 65 76 65 72 20 61  nces are never a
1b60: 6c 6c 6f 63 61 74 65 64 20 61 6e 79 20 6f 74 68  llocated any oth
1b70: 65 72 0a 2a 2a 20 77 61 79 2e 20 56 64 62 65 53  er.** way. VdbeS
1b80: 6f 72 74 65 72 2e 6e 54 61 73 6b 20 69 73 20 73  orter.nTask is s
1b90: 65 74 20 74 6f 20 74 68 65 20 6e 75 6d 62 65 72  et to the number
1ba0: 20 6f 66 20 77 6f 72 6b 65 72 20 74 68 72 65 61   of worker threa
1bb0: 64 73 20 61 6c 6c 6f 77 65 64 0a 2a 2a 20 28 73  ds allowed.** (s
1bc0: 65 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  ee SQLITE_CONFIG
1bd0: 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 29  _WORKER_THREADS)
1be0: 20 70 6c 75 73 20 6f 6e 65 20 28 74 68 65 20 6d   plus one (the m
1bf0: 61 69 6e 20 74 68 72 65 61 64 29 2e 0a 2a 2a 0a  ain thread)..**.
1c00: 2a 2a 20 57 68 65 6e 20 61 20 62 61 63 6b 67 72  ** When a backgr
1c10: 6f 75 6e 64 20 74 68 72 65 61 64 20 69 73 20 6c  ound thread is l
1c20: 61 75 6e 63 68 65 64 20 74 6f 20 70 65 72 66 6f  aunched to perfo
1c30: 72 6d 20 77 6f 72 6b 2c 20 53 6f 72 74 53 75 62  rm work, SortSub
1c40: 74 61 73 6b 2e 62 44 6f 6e 65 0a 2a 2a 20 69 73  task.bDone.** is
1c50: 20 73 65 74 20 74 6f 20 30 20 61 6e 64 20 74 68   set to 0 and th
1c60: 65 20 53 6f 72 74 53 75 62 74 61 73 6b 2e 70 54  e SortSubtask.pT
1c70: 61 73 6b 20 76 61 72 69 61 62 6c 65 20 73 65 74  ask variable set
1c80: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65   to point to the
1c90: 0a 2a 2a 20 74 68 72 65 61 64 20 68 61 6e 64 6c  .** thread handl
1ca0: 65 2e 20 53 6f 72 74 53 75 62 74 61 73 6b 2e 62  e. SortSubtask.b
1cb0: 44 6f 6e 65 20 69 73 20 73 65 74 20 74 6f 20 31  Done is set to 1
1cc0: 20 28 74 6f 20 69 6e 64 69 63 61 74 65 20 74 6f   (to indicate to
1cd0: 20 74 68 65 20 6d 61 69 6e 0a 2a 2a 20 74 68 72   the main.** thr
1ce0: 65 61 64 20 74 68 61 74 20 6a 6f 69 6e 69 6e 67  ead that joining
1cf0: 20 53 6f 72 74 53 75 62 74 61 73 6b 2e 70 54 61   SortSubtask.pTa
1d00: 73 6b 20 77 69 6c 6c 20 6e 6f 74 20 62 6c 6f 63  sk will not bloc
1d10: 6b 29 20 62 65 66 6f 72 65 20 74 68 65 20 74 68  k) before the th
1d20: 72 65 61 64 0a 2a 2a 20 65 78 69 74 73 2e 20 53  read.** exits. S
1d30: 6f 72 74 53 75 62 74 61 73 6b 2e 70 54 61 73 6b  ortSubtask.pTask
1d40: 20 61 6e 64 20 62 44 6f 6e 65 20 61 72 65 20 61   and bDone are a
1d50: 6c 77 61 79 73 20 63 6c 65 61 72 65 64 20 61 66  lways cleared af
1d60: 74 65 72 20 74 68 65 20 0a 2a 2a 20 62 61 63 6b  ter the .** back
1d70: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 68 61  ground thread ha
1d80: 73 20 62 65 65 6e 20 6a 6f 69 6e 65 64 2e 0a 2a  s been joined..*
1d90: 2a 0a 2a 2a 20 4f 6e 65 20 6f 62 6a 65 63 74 20  *.** One object 
1da0: 28 73 70 65 63 69 66 69 63 61 6c 6c 79 2c 20 56  (specifically, V
1db0: 64 62 65 53 6f 72 74 65 72 2e 61 54 61 73 6b 5b  dbeSorter.aTask[
1dc0: 56 64 62 65 53 6f 72 74 65 72 2e 6e 54 61 73 6b  VdbeSorter.nTask
1dd0: 2d 31 5d 29 0a 2a 2a 20 69 73 20 72 65 73 65 72  -1]).** is reser
1de0: 76 65 64 20 66 6f 72 20 74 68 65 20 66 6f 72 65  ved for the fore
1df0: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 2e 0a 2a  ground thread..*
1e00: 2a 0a 2a 2a 20 54 68 65 20 6e 61 74 75 72 65 20  *.** The nature 
1e10: 6f 66 20 74 68 65 20 77 6f 72 6b 20 70 65 72 66  of the work perf
1e20: 6f 72 6d 65 64 20 69 73 20 64 65 74 65 72 6d 69  ormed is determi
1e30: 6e 65 64 20 62 79 20 53 6f 72 74 53 75 62 74 61  ned by SortSubta
1e40: 73 6b 2e 65 57 6f 72 6b 2c 0a 2a 2a 20 61 73 20  sk.eWork,.** as 
1e50: 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20  follows:.**.**  
1e60: 20 53 4f 52 54 5f 53 55 42 54 41 53 4b 5f 53 4f   SORT_SUBTASK_SO
1e70: 52 54 3a 0a 2a 2a 20 20 20 20 20 53 6f 72 74 20  RT:.**     Sort 
1e80: 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20  the linked list 
1e90: 6f 66 20 72 65 63 6f 72 64 73 20 61 74 20 53 6f  of records at So
1ea0: 72 74 53 75 62 74 61 73 6b 2e 70 4c 69 73 74 2e  rtSubtask.pList.
1eb0: 0a 2a 2a 0a 2a 2a 20 20 20 53 4f 52 54 5f 53 55  .**.**   SORT_SU
1ec0: 42 54 41 53 4b 5f 54 4f 5f 50 4d 41 3a 0a 2a 2a  BTASK_TO_PMA:.**
1ed0: 20 20 20 20 20 53 6f 72 74 20 74 68 65 20 6c 69       Sort the li
1ee0: 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20 72 65 63  nked list of rec
1ef0: 6f 72 64 73 20 61 74 20 53 6f 72 74 53 75 62 74  ords at SortSubt
1f00: 61 73 6b 2e 70 4c 69 73 74 2c 20 61 6e 64 20 77  ask.pList, and w
1f10: 72 69 74 65 0a 2a 2a 20 20 20 20 20 74 68 65 20  rite.**     the 
1f20: 72 65 73 75 6c 74 73 20 74 6f 20 61 20 6e 65 77  results to a new
1f30: 20 50 4d 41 20 69 6e 20 74 65 6d 70 20 66 69 6c   PMA in temp fil
1f40: 65 20 53 6f 72 74 53 75 62 74 61 73 6b 2e 70 54  e SortSubtask.pT
1f50: 65 6d 70 31 2e 20 4f 70 65 6e 0a 2a 2a 20 20 20  emp1. Open.**   
1f60: 20 20 74 68 65 20 74 65 6d 70 20 66 69 6c 65 20    the temp file 
1f70: 69 66 20 69 74 20 69 73 20 6e 6f 74 20 61 6c 72  if it is not alr
1f80: 65 61 64 79 20 6f 70 65 6e 2e 0a 2a 2a 0a 2a 2a  eady open..**.**
1f90: 20 20 20 53 4f 52 54 5f 53 55 42 54 41 53 4b 5f     SORT_SUBTASK_
1fa0: 43 4f 4e 53 3a 0a 2a 2a 20 20 20 20 20 4d 65 72  CONS:.**     Mer
1fb0: 67 65 20 65 78 69 73 74 69 6e 67 20 50 4d 41 73  ge existing PMAs
1fc0: 20 75 6e 74 69 6c 20 53 6f 72 74 53 75 62 74 61   until SortSubta
1fd0: 73 6b 2e 6e 43 6f 6e 73 6f 6c 69 64 61 74 65 20  sk.nConsolidate 
1fe0: 6f 72 20 66 65 77 65 72 0a 2a 2a 20 20 20 20 20  or fewer.**     
1ff0: 72 65 6d 61 69 6e 20 69 6e 20 74 65 6d 70 20 66  remain in temp f
2000: 69 6c 65 20 53 6f 72 74 53 75 62 74 61 73 6b 2e  ile SortSubtask.
2010: 70 54 65 6d 70 31 2e 0a 2a 2f 0a 73 74 72 75 63  pTemp1..*/.struc
2020: 74 20 53 6f 72 74 53 75 62 74 61 73 6b 20 7b 0a  t SortSubtask {.
2030: 20 20 53 6f 72 74 65 72 54 68 72 65 61 64 20 74    SorterThread t
2040: 68 72 65 61 64 3b 0a 20 20 73 71 6c 69 74 65 33  hread;.  sqlite3
2050: 20 2a 64 62 3b 20 20 20 20 20 20 20 20 20 20 20   *db;           
2060: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
2070: 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  base connection 
2080: 2a 2f 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20  */.  VdbeSorter 
2090: 2a 70 53 6f 72 74 65 72 3b 20 20 20 20 20 20 20  *pSorter;       
20a0: 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 2a       /* Sorter *
20b0: 2f 0a 20 20 4b 65 79 49 6e 66 6f 20 2a 70 4b 65  /.  KeyInfo *pKe
20c0: 79 49 6e 66 6f 3b 20 20 20 20 20 20 20 20 20 20  yInfo;          
20d0: 20 20 20 20 2f 2a 20 48 6f 77 20 74 6f 20 63 6f      /* How to co
20e0: 6d 70 61 72 65 20 72 65 63 6f 72 64 73 20 2a 2f  mpare records */
20f0: 0a 20 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72  .  UnpackedRecor
2100: 64 20 2a 70 55 6e 70 61 63 6b 65 64 3b 20 20 20  d *pUnpacked;   
2110: 20 20 20 2f 2a 20 53 70 61 63 65 20 74 6f 20 75     /* Space to u
2120: 6e 70 61 63 6b 20 61 20 72 65 63 6f 72 64 20 2a  npack a record *
2130: 2f 0a 20 20 69 6e 74 20 70 67 73 7a 3b 20 20 20  /.  int pgsz;   
2140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2150: 20 20 20 20 2f 2a 20 4d 61 69 6e 20 64 61 74 61      /* Main data
2160: 62 61 73 65 20 70 61 67 65 20 73 69 7a 65 20 2a  base page size *
2170: 2f 0a 20 20 53 6f 72 74 65 72 4c 69 73 74 20 6c  /.  SorterList l
2180: 69 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ist;            
2190: 20 20 20 20 2f 2a 20 4c 69 73 74 20 66 6f 72 20      /* List for 
21a0: 74 68 72 65 61 64 20 74 6f 20 77 72 69 74 65 20  thread to write 
21b0: 74 6f 20 61 20 50 4d 41 20 2a 2f 0a 20 20 69 6e  to a PMA */.  in
21c0: 74 20 6e 50 4d 41 3b 20 20 20 20 20 20 20 20 20  t nPMA;         
21d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
21e0: 20 4e 75 6d 62 65 72 20 6f 66 20 50 4d 41 73 20   Number of PMAs 
21f0: 63 75 72 72 65 6e 74 6c 79 20 69 6e 20 66 69 6c  currently in fil
2200: 65 20 2a 2f 0a 20 20 53 6f 72 74 65 72 46 69 6c  e */.  SorterFil
2210: 65 20 66 69 6c 65 3b 20 20 20 20 20 20 20 20 20  e file;         
2220: 20 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 20 66         /* Temp f
2230: 69 6c 65 20 66 6f 72 20 6c 65 76 65 6c 2d 30 20  ile for level-0 
2240: 50 4d 41 73 20 2a 2f 0a 20 20 53 6f 72 74 65 72  PMAs */.  Sorter
2250: 46 69 6c 65 20 66 69 6c 65 32 3b 20 20 20 20 20  File file2;     
2260: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 70 61            /* Spa
2270: 63 65 20 66 6f 72 20 6f 74 68 65 72 20 50 4d 41  ce for other PMA
2280: 73 20 2a 2f 0a 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20  s */.};.../*.** 
2290: 54 68 65 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  The MergeEngine 
22a0: 6f 62 6a 65 63 74 20 69 73 20 75 73 65 64 20 74  object is used t
22b0: 6f 20 63 6f 6d 62 69 6e 65 20 74 77 6f 20 6f 72  o combine two or
22c0: 20 6d 6f 72 65 20 73 6d 61 6c 6c 65 72 20 50 4d   more smaller PM
22d0: 41 73 20 69 6e 74 6f 0a 2a 2a 20 6f 6e 65 20 62  As into.** one b
22e0: 69 67 20 50 4d 41 20 75 73 69 6e 67 20 61 20 6d  ig PMA using a m
22f0: 65 72 67 65 20 6f 70 65 72 61 74 69 6f 6e 2e 20  erge operation. 
2300: 20 53 65 70 61 72 61 74 65 20 50 4d 41 73 20 61   Separate PMAs a
2310: 6c 6c 20 6e 65 65 64 20 74 6f 20 62 65 0a 2a 2a  ll need to be.**
2320: 20 63 6f 6d 62 69 6e 65 64 20 69 6e 74 6f 20 6f   combined into o
2330: 6e 65 20 62 69 67 20 50 4d 41 20 69 6e 20 6f 72  ne big PMA in or
2340: 64 65 72 20 74 6f 20 62 65 20 61 62 6c 65 20 74  der to be able t
2350: 6f 20 73 74 65 70 20 74 68 72 6f 75 67 68 20 74  o step through t
2360: 68 65 20 73 6f 72 74 65 64 0a 2a 2a 20 72 65 63  he sorted.** rec
2370: 6f 72 64 73 20 69 6e 20 6f 72 64 65 72 2e 0a 2a  ords in order..*
2380: 2a 0a 2a 2a 20 54 68 65 20 61 49 74 65 72 5b 5d  *.** The aIter[]
2390: 20 61 72 72 61 79 20 63 6f 6e 74 61 69 6e 73 20   array contains 
23a0: 61 20 50 6d 61 52 65 61 64 65 72 20 6f 62 6a 65  a PmaReader obje
23b0: 63 74 20 66 6f 72 20 65 61 63 68 20 6f 66 20 74  ct for each of t
23c0: 68 65 20 50 4d 41 73 20 62 65 69 6e 67 0a 2a 2a  he PMAs being.**
23d0: 20 6d 65 72 67 65 64 2e 20 20 41 6e 20 61 49 74   merged.  An aIt
23e0: 65 72 5b 5d 20 6f 62 6a 65 63 74 20 65 69 74 68  er[] object eith
23f0: 65 72 20 70 6f 69 6e 74 73 20 74 6f 20 61 20 76  er points to a v
2400: 61 6c 69 64 20 6b 65 79 20 6f 72 20 65 6c 73 65  alid key or else
2410: 20 69 73 20 61 74 20 45 4f 46 2e 0a 2a 2a 20 46   is at EOF..** F
2420: 6f 72 20 74 68 65 20 70 75 72 70 6f 73 65 73 20  or the purposes 
2430: 6f 66 20 74 68 65 20 70 61 72 61 67 72 61 70 68  of the paragraph
2440: 73 20 62 65 6c 6f 77 2c 20 77 65 20 61 73 73 75  s below, we assu
2450: 6d 65 20 74 68 61 74 20 74 68 65 20 61 72 72 61  me that the arra
2460: 79 20 69 73 0a 2a 2a 20 61 63 74 75 61 6c 6c 79  y is.** actually
2470: 20 4e 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 73   N elements in s
2480: 69 7a 65 2c 20 77 68 65 72 65 20 4e 20 69 73 20  ize, where N is 
2490: 74 68 65 20 73 6d 61 6c 6c 65 73 74 20 70 6f 77  the smallest pow
24a0: 65 72 20 6f 66 20 32 20 67 72 65 61 74 65 72 0a  er of 2 greater.
24b0: 2a 2a 20 74 6f 20 6f 72 20 65 71 75 61 6c 20 74  ** to or equal t
24c0: 6f 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  o the number of 
24d0: 50 4d 41 73 20 62 65 69 6e 67 20 6d 65 72 67 65  PMAs being merge
24e0: 64 2e 20 54 68 65 20 65 78 74 72 61 20 61 49 74  d. The extra aIt
24f0: 65 72 5b 5d 20 65 6c 65 6d 65 6e 74 73 0a 2a 2a  er[] elements.**
2500: 20 61 72 65 20 74 72 65 61 74 65 64 20 61 73 20   are treated as 
2510: 69 66 20 74 68 65 79 20 61 72 65 20 65 6d 70 74  if they are empt
2520: 79 20 28 61 6c 77 61 79 73 20 61 74 20 45 4f 46  y (always at EOF
2530: 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 54 72  )..**.** The aTr
2540: 65 65 5b 5d 20 61 72 72 61 79 20 69 73 20 61 6c  ee[] array is al
2550: 73 6f 20 4e 20 65 6c 65 6d 65 6e 74 73 20 69 6e  so N elements in
2560: 20 73 69 7a 65 2e 20 54 68 65 20 76 61 6c 75 65   size. The value
2570: 20 6f 66 20 4e 20 69 73 20 73 74 6f 72 65 64 20   of N is stored 
2580: 69 6e 0a 2a 2a 20 74 68 65 20 4d 65 72 67 65 45  in.** the MergeE
2590: 6e 67 69 6e 65 2e 6e 54 72 65 65 20 76 61 72 69  ngine.nTree vari
25a0: 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  able..**.** The 
25b0: 66 69 6e 61 6c 20 28 4e 2f 32 29 20 65 6c 65 6d  final (N/2) elem
25c0: 65 6e 74 73 20 6f 66 20 61 54 72 65 65 5b 5d 20  ents of aTree[] 
25d0: 63 6f 6e 74 61 69 6e 20 74 68 65 20 72 65 73 75  contain the resu
25e0: 6c 74 73 20 6f 66 20 63 6f 6d 70 61 72 69 6e 67  lts of comparing
25f0: 0a 2a 2a 20 70 61 69 72 73 20 6f 66 20 50 4d 41  .** pairs of PMA
2600: 20 6b 65 79 73 20 74 6f 67 65 74 68 65 72 2e 20   keys together. 
2610: 45 6c 65 6d 65 6e 74 20 69 20 63 6f 6e 74 61 69  Element i contai
2620: 6e 73 20 74 68 65 20 72 65 73 75 6c 74 20 6f 66  ns the result of
2630: 20 0a 2a 2a 20 63 6f 6d 70 61 72 69 6e 67 20 61   .** comparing a
2640: 49 74 65 72 5b 32 2a 69 2d 4e 5d 20 61 6e 64 20  Iter[2*i-N] and 
2650: 61 49 74 65 72 5b 32 2a 69 2d 4e 2b 31 5d 2e 20  aIter[2*i-N+1]. 
2660: 57 68 69 63 68 65 76 65 72 20 6b 65 79 20 69 73  Whichever key is
2670: 20 73 6d 61 6c 6c 65 72 2c 20 74 68 65 0a 2a 2a   smaller, the.**
2680: 20 61 54 72 65 65 20 65 6c 65 6d 65 6e 74 20 69   aTree element i
2690: 73 20 73 65 74 20 74 6f 20 74 68 65 20 69 6e 64  s set to the ind
26a0: 65 78 20 6f 66 20 69 74 2e 20 0a 2a 2a 0a 2a 2a  ex of it. .**.**
26b0: 20 46 6f 72 20 74 68 65 20 70 75 72 70 6f 73 65   For the purpose
26c0: 73 20 6f 66 20 74 68 69 73 20 63 6f 6d 70 61 72  s of this compar
26d0: 69 73 6f 6e 2c 20 45 4f 46 20 69 73 20 63 6f 6e  ison, EOF is con
26e0: 73 69 64 65 72 65 64 20 67 72 65 61 74 65 72 20  sidered greater 
26f0: 74 68 61 6e 20 61 6e 79 0a 2a 2a 20 6f 74 68 65  than any.** othe
2700: 72 20 6b 65 79 20 76 61 6c 75 65 2e 20 49 66 20  r key value. If 
2710: 74 68 65 20 6b 65 79 73 20 61 72 65 20 65 71 75  the keys are equ
2720: 61 6c 20 28 6f 6e 6c 79 20 70 6f 73 73 69 62 6c  al (only possibl
2730: 65 20 77 69 74 68 20 74 77 6f 20 45 4f 46 0a 2a  e with two EOF.*
2740: 2a 20 76 61 6c 75 65 73 29 2c 20 69 74 20 64 6f  * values), it do
2750: 65 73 6e 27 74 20 6d 61 74 74 65 72 20 77 68 69  esn't matter whi
2760: 63 68 20 69 6e 64 65 78 20 69 73 20 73 74 6f 72  ch index is stor
2770: 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 28 4e  ed..**.** The (N
2780: 2f 34 29 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20  /4) elements of 
2790: 61 54 72 65 65 5b 5d 20 74 68 61 74 20 70 72 65  aTree[] that pre
27a0: 63 65 64 65 20 74 68 65 20 66 69 6e 61 6c 20 28  cede the final (
27b0: 4e 2f 32 29 20 64 65 73 63 72 69 62 65 64 20 0a  N/2) described .
27c0: 2a 2a 20 61 62 6f 76 65 20 63 6f 6e 74 61 69 6e  ** above contain
27d0: 73 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20 74  s the index of t
27e0: 68 65 20 73 6d 61 6c 6c 65 73 74 20 6f 66 20 65  he smallest of e
27f0: 61 63 68 20 62 6c 6f 63 6b 20 6f 66 20 34 20 69  ach block of 4 i
2800: 74 65 72 61 74 6f 72 73 2e 0a 2a 2a 20 41 6e 64  terators..** And
2810: 20 73 6f 20 6f 6e 2e 20 53 6f 20 74 68 61 74 20   so on. So that 
2820: 61 54 72 65 65 5b 31 5d 20 63 6f 6e 74 61 69 6e  aTree[1] contain
2830: 73 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20 74  s the index of t
2840: 68 65 20 69 74 65 72 61 74 6f 72 20 74 68 61 74  he iterator that
2850: 20 0a 2a 2a 20 63 75 72 72 65 6e 74 6c 79 20 70   .** currently p
2860: 6f 69 6e 74 73 20 74 6f 20 74 68 65 20 73 6d 61  oints to the sma
2870: 6c 6c 65 73 74 20 6b 65 79 20 76 61 6c 75 65 2e  llest key value.
2880: 20 61 54 72 65 65 5b 30 5d 20 69 73 20 75 6e 75   aTree[0] is unu
2890: 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 45 78 61 6d 70  sed..**.** Examp
28a0: 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 49  le:.**.**     aI
28b0: 74 65 72 5b 30 5d 20 2d 3e 20 42 61 6e 61 6e 61  ter[0] -> Banana
28c0: 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 31 5d  .**     aIter[1]
28d0: 20 2d 3e 20 46 65 69 6a 6f 61 0a 2a 2a 20 20 20   -> Feijoa.**   
28e0: 20 20 61 49 74 65 72 5b 32 5d 20 2d 3e 20 45 6c    aIter[2] -> El
28f0: 64 65 72 62 65 72 72 79 0a 2a 2a 20 20 20 20 20  derberry.**     
2900: 61 49 74 65 72 5b 33 5d 20 2d 3e 20 43 75 72 72  aIter[3] -> Curr
2910: 61 6e 74 0a 2a 2a 20 20 20 20 20 61 49 74 65 72  ant.**     aIter
2920: 5b 34 5d 20 2d 3e 20 47 72 61 70 65 66 72 75 69  [4] -> Grapefrui
2930: 74 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 35  t.**     aIter[5
2940: 5d 20 2d 3e 20 41 70 70 6c 65 0a 2a 2a 20 20 20  ] -> Apple.**   
2950: 20 20 61 49 74 65 72 5b 36 5d 20 2d 3e 20 44 75    aIter[6] -> Du
2960: 72 69 61 6e 0a 2a 2a 20 20 20 20 20 61 49 74 65  rian.**     aIte
2970: 72 5b 37 5d 20 2d 3e 20 45 4f 46 0a 2a 2a 0a 2a  r[7] -> EOF.**.*
2980: 2a 20 20 20 20 20 61 54 72 65 65 5b 5d 20 3d 20  *     aTree[] = 
2990: 7b 20 58 2c 20 35 20 20 20 30 2c 20 35 20 20 20  { X, 5   0, 5   
29a0: 20 30 2c 20 33 2c 20 35 2c 20 36 20 7d 0a 2a 2a   0, 3, 5, 6 }.**
29b0: 0a 2a 2a 20 54 68 65 20 63 75 72 72 65 6e 74 20  .** The current 
29c0: 65 6c 65 6d 65 6e 74 20 69 73 20 22 41 70 70 6c  element is "Appl
29d0: 65 22 20 28 74 68 65 20 76 61 6c 75 65 20 6f 66  e" (the value of
29e0: 20 74 68 65 20 6b 65 79 20 69 6e 64 69 63 61 74   the key indicat
29f0: 65 64 20 62 79 20 0a 2a 2a 20 69 74 65 72 61 74  ed by .** iterat
2a00: 6f 72 20 35 29 2e 20 57 68 65 6e 20 74 68 65 20  or 5). When the 
2a10: 4e 65 78 74 28 29 20 6f 70 65 72 61 74 69 6f 6e  Next() operation
2a20: 20 69 73 20 69 6e 76 6f 6b 65 64 2c 20 69 74 65   is invoked, ite
2a30: 72 61 74 6f 72 20 35 20 77 69 6c 6c 0a 2a 2a 20  rator 5 will.** 
2a40: 62 65 20 61 64 76 61 6e 63 65 64 20 74 6f 20 74  be advanced to t
2a50: 68 65 20 6e 65 78 74 20 6b 65 79 20 69 6e 20 69  he next key in i
2a60: 74 73 20 73 65 67 6d 65 6e 74 2e 20 53 61 79 20  ts segment. Say 
2a70: 74 68 65 20 6e 65 78 74 20 6b 65 79 20 69 73 0a  the next key is.
2a80: 2a 2a 20 22 45 67 67 70 6c 61 6e 74 22 3a 0a 2a  ** "Eggplant":.*
2a90: 2a 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 35  *.**     aIter[5
2aa0: 5d 20 2d 3e 20 45 67 67 70 6c 61 6e 74 0a 2a 2a  ] -> Eggplant.**
2ab0: 0a 2a 2a 20 54 68 65 20 63 6f 6e 74 65 6e 74 73  .** The contents
2ac0: 20 6f 66 20 61 54 72 65 65 5b 5d 20 61 72 65 20   of aTree[] are 
2ad0: 75 70 64 61 74 65 64 20 66 69 72 73 74 20 62 79  updated first by
2ae0: 20 63 6f 6d 70 61 72 69 6e 67 20 74 68 65 20 6e   comparing the n
2af0: 65 77 20 69 74 65 72 61 74 6f 72 0a 2a 2a 20 35  ew iterator.** 5
2b00: 20 6b 65 79 20 74 6f 20 74 68 65 20 63 75 72 72   key to the curr
2b10: 65 6e 74 20 6b 65 79 20 6f 66 20 69 74 65 72 61  ent key of itera
2b20: 74 6f 72 20 34 20 28 73 74 69 6c 6c 20 22 47 72  tor 4 (still "Gr
2b30: 61 70 65 66 72 75 69 74 22 29 2e 20 54 68 65 20  apefruit"). The 
2b40: 69 74 65 72 61 74 6f 72 0a 2a 2a 20 35 20 76 61  iterator.** 5 va
2b50: 6c 75 65 20 69 73 20 73 74 69 6c 6c 20 73 6d 61  lue is still sma
2b60: 6c 6c 65 72 2c 20 73 6f 20 61 54 72 65 65 5b 36  ller, so aTree[6
2b70: 5d 20 69 73 20 73 65 74 20 74 6f 20 35 2e 20 41  ] is set to 5. A
2b80: 6e 64 20 73 6f 20 6f 6e 20 75 70 20 74 68 65 20  nd so on up the 
2b90: 74 72 65 65 2e 0a 2a 2a 20 54 68 65 20 76 61 6c  tree..** The val
2ba0: 75 65 20 6f 66 20 69 74 65 72 61 74 6f 72 20 36  ue of iterator 6
2bb0: 20 2d 20 22 44 75 72 69 61 6e 22 20 2d 20 69 73   - "Durian" - is
2bc0: 20 6e 6f 77 20 73 6d 61 6c 6c 65 72 20 74 68 61   now smaller tha
2bd0: 6e 20 74 68 61 74 20 6f 66 20 69 74 65 72 61 74  n that of iterat
2be0: 6f 72 0a 2a 2a 20 35 2c 20 73 6f 20 61 54 72 65  or.** 5, so aTre
2bf0: 65 5b 33 5d 20 69 73 20 73 65 74 20 74 6f 20 36  e[3] is set to 6
2c00: 2e 20 4b 65 79 20 30 20 69 73 20 73 6d 61 6c 6c  . Key 0 is small
2c10: 65 72 20 74 68 61 6e 20 6b 65 79 20 36 20 28 42  er than key 6 (B
2c20: 61 6e 61 6e 61 3c 44 75 72 69 61 6e 29 2c 0a 2a  anana<Durian),.*
2c30: 2a 20 73 6f 20 74 68 65 20 76 61 6c 75 65 20 77  * so the value w
2c40: 72 69 74 74 65 6e 20 69 6e 74 6f 20 65 6c 65 6d  ritten into elem
2c50: 65 6e 74 20 31 20 6f 66 20 74 68 65 20 61 72 72  ent 1 of the arr
2c60: 61 79 20 69 73 20 30 2e 20 41 73 20 66 6f 6c 6c  ay is 0. As foll
2c70: 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61  ows:.**.**     a
2c80: 54 72 65 65 5b 5d 20 3d 20 7b 20 58 2c 20 30 20  Tree[] = { X, 0 
2c90: 20 20 30 2c 20 36 20 20 20 20 30 2c 20 33 2c 20    0, 6    0, 3, 
2ca0: 35 2c 20 36 20 7d 0a 2a 2a 0a 2a 2a 20 49 6e 20  5, 6 }.**.** In 
2cb0: 6f 74 68 65 72 20 77 6f 72 64 73 2c 20 65 61 63  other words, eac
2cc0: 68 20 74 69 6d 65 20 77 65 20 61 64 76 61 6e 63  h time we advanc
2cd0: 65 20 74 6f 20 74 68 65 20 6e 65 78 74 20 73 6f  e to the next so
2ce0: 72 74 65 72 20 65 6c 65 6d 65 6e 74 2c 20 6c 6f  rter element, lo
2cf0: 67 32 28 4e 29 0a 2a 2a 20 6b 65 79 20 63 6f 6d  g2(N).** key com
2d00: 70 61 72 69 73 6f 6e 20 6f 70 65 72 61 74 69 6f  parison operatio
2d10: 6e 73 20 61 72 65 20 72 65 71 75 69 72 65 64 2c  ns are required,
2d20: 20 77 68 65 72 65 20 4e 20 69 73 20 74 68 65 20   where N is the 
2d30: 6e 75 6d 62 65 72 20 6f 66 20 73 65 67 6d 65 6e  number of segmen
2d40: 74 73 0a 2a 2a 20 62 65 69 6e 67 20 6d 65 72 67  ts.** being merg
2d50: 65 64 20 28 72 6f 75 6e 64 65 64 20 75 70 20 74  ed (rounded up t
2d60: 6f 20 74 68 65 20 6e 65 78 74 20 70 6f 77 65 72  o the next power
2d70: 20 6f 66 20 32 29 2e 0a 2a 2f 0a 73 74 72 75 63   of 2)..*/.struc
2d80: 74 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 7b 0a  t MergeEngine {.
2d90: 20 20 69 6e 74 20 6e 54 72 65 65 3b 20 20 20 20    int nTree;    
2da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2db0: 55 73 65 64 20 73 69 7a 65 20 6f 66 20 61 54 72  Used size of aTr
2dc0: 65 65 2f 61 49 74 65 72 20 28 70 6f 77 65 72 20  ee/aIter (power 
2dd0: 6f 66 20 32 29 20 2a 2f 0a 20 20 69 6e 74 20 2a  of 2) */.  int *
2de0: 61 54 72 65 65 3b 20 20 20 20 20 20 20 20 20 20  aTree;          
2df0: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
2e00: 20 73 74 61 74 65 20 6f 66 20 69 6e 63 72 65 6d   state of increm
2e10: 65 6e 74 61 6c 20 6d 65 72 67 65 20 2a 2f 0a 20  ental merge */. 
2e20: 20 50 6d 61 52 65 61 64 65 72 20 2a 61 49 74 65   PmaReader *aIte
2e30: 72 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41  r;          /* A
2e40: 72 72 61 79 20 6f 66 20 69 74 65 72 61 74 6f 72  rray of iterator
2e50: 73 20 74 6f 20 6d 65 72 67 65 20 64 61 74 61 20  s to merge data 
2e60: 66 72 6f 6d 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  from */.};../*.*
2e70: 2a 20 4d 61 69 6e 20 73 6f 72 74 65 72 20 73 74  * Main sorter st
2e80: 72 75 63 74 75 72 65 2e 20 41 20 73 69 6e 67 6c  ructure. A singl
2e90: 65 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68  e instance of th
2ea0: 69 73 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 20  is is allocated 
2eb0: 66 6f 72 20 65 61 63 68 20 0a 2a 2a 20 73 6f 72  for each .** sor
2ec0: 74 65 72 20 63 75 72 73 6f 72 20 63 72 65 61 74  ter cursor creat
2ed0: 65 64 20 62 79 20 74 68 65 20 56 44 42 45 2e 0a  ed by the VDBE..
2ee0: 2a 2a 0a 2a 2a 20 6d 78 4b 65 79 73 69 7a 65 3a  **.** mxKeysize:
2ef0: 0a 2a 2a 20 20 20 41 73 20 72 65 63 6f 72 64 73  .**   As records
2f00: 20 61 72 65 20 61 64 64 65 64 20 74 6f 20 74 68   are added to th
2f10: 65 20 73 6f 72 74 65 72 20 62 79 20 63 61 6c 6c  e sorter by call
2f20: 73 20 74 6f 20 73 71 6c 69 74 65 33 56 64 62 65  s to sqlite3Vdbe
2f30: 53 6f 72 74 65 72 57 72 69 74 65 28 29 2c 0a 2a  SorterWrite(),.*
2f40: 2a 20 20 20 74 68 69 73 20 76 61 72 69 61 62 6c  *   this variabl
2f50: 65 20 69 73 20 75 70 64 61 74 65 64 20 73 6f 20  e is updated so 
2f60: 61 73 20 74 6f 20 62 65 20 73 65 74 20 74 6f 20  as to be set to 
2f70: 74 68 65 20 73 69 7a 65 20 6f 6e 20 64 69 73 6b  the size on disk
2f80: 20 6f 66 20 74 68 65 0a 2a 2a 20 20 20 6c 61 72   of the.**   lar
2f90: 67 65 73 74 20 72 65 63 6f 72 64 20 69 6e 20 74  gest record in t
2fa0: 68 65 20 73 6f 72 74 65 72 2e 0a 2a 2f 0a 73 74  he sorter..*/.st
2fb0: 72 75 63 74 20 56 64 62 65 53 6f 72 74 65 72 20  ruct VdbeSorter 
2fc0: 7b 0a 20 20 69 6e 74 20 6d 6e 50 6d 61 53 69 7a  {.  int mnPmaSiz
2fd0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
2fe0: 20 20 20 20 2f 2a 20 4d 69 6e 69 6d 75 6d 20 50      /* Minimum P
2ff0: 4d 41 20 73 69 7a 65 2c 20 69 6e 20 62 79 74 65  MA size, in byte
3000: 73 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 50 6d 61  s */.  int mxPma
3010: 53 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20  Size;           
3020: 20 20 20 20 20 20 20 2f 2a 20 4d 61 78 69 6d 75         /* Maximu
3030: 6d 20 50 4d 41 20 73 69 7a 65 2c 20 69 6e 20 62  m PMA size, in b
3040: 79 74 65 73 2e 20 20 30 3d 3d 6e 6f 20 6c 69 6d  ytes.  0==no lim
3050: 69 74 20 2a 2f 0a 20 20 69 6e 74 20 62 55 73 65  it */.  int bUse
3060: 50 4d 41 3b 20 20 20 20 20 20 20 20 20 20 20 20  PMA;            
3070: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
3080: 69 66 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 50  if one or more P
3090: 4d 41 73 20 63 72 65 61 74 65 64 20 2a 2f 0a 20  MAs created */. 
30a0: 20 69 6e 74 20 62 55 73 65 54 68 72 65 61 64 73   int bUseThreads
30b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
30c0: 20 2f 2a 20 54 72 75 65 20 69 66 20 6f 6e 65 20   /* True if one 
30d0: 6f 72 20 6d 6f 72 65 20 50 4d 41 73 20 63 72 65  or more PMAs cre
30e0: 61 74 65 64 20 2a 2f 0a 20 20 50 6d 61 52 65 61  ated */.  PmaRea
30f0: 64 65 72 20 2a 70 52 65 61 64 65 72 3b 20 20 20  der *pReader;   
3100: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 61            /* Rea
3110: 64 20 64 61 74 61 20 66 72 6f 6d 20 68 65 72 65  d data from here
3120: 20 61 66 74 65 72 20 52 65 77 69 6e 64 28 29 20   after Rewind() 
3130: 2a 2f 0a 20 20 69 6e 74 20 6d 78 4b 65 79 73 69  */.  int mxKeysi
3140: 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ze;             
3150: 20 20 20 20 20 2f 2a 20 4c 61 72 67 65 73 74 20       /* Largest 
3160: 73 65 72 69 61 6c 69 7a 65 64 20 6b 65 79 20 73  serialized key s
3170: 65 65 6e 20 73 6f 20 66 61 72 20 2a 2f 0a 20 20  een so far */.  
3180: 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20 2a  UnpackedRecord *
3190: 70 55 6e 70 61 63 6b 65 64 3b 20 20 20 20 20 20  pUnpacked;      
31a0: 2f 2a 20 55 73 65 64 20 62 79 20 56 64 62 65 53  /* Used by VdbeS
31b0: 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 29 20 2a  orterCompare() *
31c0: 2f 0a 23 69 66 20 30 0a 20 20 69 6e 74 20 6e 49  /.#if 0.  int nI
31d0: 6e 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20 20 20  nMemory;        
31e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72            /* Cur
31f0: 72 65 6e 74 20 73 69 7a 65 20 6f 66 20 70 52 65  rent size of pRe
3200: 63 6f 72 64 20 6c 69 73 74 20 61 73 20 50 4d 41  cord list as PMA
3210: 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f   */.  SorterReco
3220: 72 64 20 2a 70 52 65 63 6f 72 64 3b 20 20 20 20  rd *pRecord;    
3230: 20 20 20 20 20 20 2f 2a 20 48 65 61 64 20 6f 66        /* Head of
3240: 20 69 6e 2d 6d 65 6d 6f 72 79 20 72 65 63 6f 72   in-memory recor
3250: 64 20 6c 69 73 74 20 2a 2f 0a 20 20 75 38 20 2a  d list */.  u8 *
3260: 61 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20 20 20  aMemory;        
3270: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
3280: 6c 6f 63 6b 20 6f 66 20 6d 65 6d 6f 72 79 20 74  lock of memory t
3290: 6f 20 61 6c 6c 6f 63 20 72 65 63 6f 72 64 73 20  o alloc records 
32a0: 66 72 6f 6d 20 2a 2f 0a 23 65 6e 64 69 66 0a 20  from */.#endif. 
32b0: 20 53 6f 72 74 65 72 4c 69 73 74 20 6c 69 73 74   SorterList list
32c0: 3b 0a 20 20 69 6e 74 20 69 4d 65 6d 6f 72 79 3b  ;.  int iMemory;
32d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
32e0: 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 6f 66      /* Offset of
32f0: 20 66 69 72 73 74 20 66 72 65 65 20 62 79 74 65   first free byte
3300: 20 69 6e 20 61 4d 65 6d 6f 72 79 20 2a 2f 0a 20   in aMemory */. 
3310: 20 69 6e 74 20 6e 4d 65 6d 6f 72 79 3b 20 20 20   int nMemory;   
3320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3330: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61 4d 65 6d   /* Size of aMem
3340: 6f 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69  ory allocation i
3350: 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74  n bytes */.  int
3360: 20 69 50 72 65 76 3b 20 20 20 20 20 20 20 20 20   iPrev;         
3370: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3380: 50 72 65 76 69 6f 75 73 20 74 68 72 65 61 64 20  Previous thread 
3390: 75 73 65 64 20 74 6f 20 66 6c 75 73 68 20 50 4d  used to flush PM
33a0: 41 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 61 73 6b  A */.  int nTask
33b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
33c0: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
33d0: 66 20 61 54 61 73 6b 5b 5d 20 61 72 72 61 79 20  f aTask[] array 
33e0: 2a 2f 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b  */.  SortSubtask
33f0: 20 61 54 61 73 6b 5b 31 5d 3b 20 20 20 20 20 20   aTask[1];      
3400: 20 20 20 20 20 2f 2a 20 4f 6e 65 20 6f 72 20 6d       /* One or m
3410: 6f 72 65 20 73 75 62 74 61 73 6b 73 20 2a 2f 0a  ore subtasks */.
3420: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73  };../*.** An ins
3430: 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c  tance of the fol
3440: 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20 69 73  lowing object is
3450: 20 75 73 65 64 20 74 6f 20 72 65 61 64 20 72 65   used to read re
3460: 63 6f 72 64 73 20 6f 75 74 20 6f 66 20 61 0a 2a  cords out of a.*
3470: 2a 20 50 4d 41 2c 20 69 6e 20 73 6f 72 74 65 64  * PMA, in sorted
3480: 20 6f 72 64 65 72 2e 20 20 54 68 65 20 6e 65 78   order.  The nex
3490: 74 20 6b 65 79 20 74 6f 20 62 65 20 72 65 61 64  t key to be read
34a0: 20 69 73 20 63 61 63 68 65 64 20 69 6e 20 6e 4b   is cached in nK
34b0: 65 79 2f 61 4b 65 79 2e 0a 2a 2a 20 70 46 69 6c  ey/aKey..** pFil
34c0: 65 3d 3d 30 20 61 74 20 45 4f 46 2e 0a 2a 2f 0a  e==0 at EOF..*/.
34d0: 73 74 72 75 63 74 20 50 6d 61 52 65 61 64 65 72  struct PmaReader
34e0: 20 7b 0a 20 20 69 36 34 20 69 52 65 61 64 4f 66   {.  i64 iReadOf
34f0: 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f;              
3500: 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20       /* Current 
3510: 72 65 61 64 20 6f 66 66 73 65 74 20 2a 2f 0a 20  read offset */. 
3520: 20 69 36 34 20 69 45 6f 66 3b 20 20 20 20 20 20   i64 iEof;      
3530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3540: 20 2f 2a 20 31 20 62 79 74 65 20 70 61 73 74 20   /* 1 byte past 
3550: 45 4f 46 20 66 6f 72 20 74 68 69 73 20 69 74 65  EOF for this ite
3560: 72 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 6e  rator */.  int n
3570: 41 6c 6c 6f 63 3b 20 20 20 20 20 20 20 20 20 20  Alloc;          
3580: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79             /* By
3590: 74 65 73 20 6f 66 20 73 70 61 63 65 20 61 74 20  tes of space at 
35a0: 61 41 6c 6c 6f 63 20 2a 2f 0a 20 20 69 6e 74 20  aAlloc */.  int 
35b0: 6e 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20  nKey;           
35c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
35d0: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69  umber of bytes i
35e0: 6e 20 6b 65 79 20 2a 2f 0a 20 20 73 71 6c 69 74  n key */.  sqlit
35f0: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 3b 20  e3_file *pFile; 
3600: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69             /* Fi
3610: 6c 65 20 69 74 65 72 61 74 6f 72 20 69 73 20 72  le iterator is r
3620: 65 61 64 69 6e 67 20 66 72 6f 6d 20 2a 2f 0a 20  eading from */. 
3630: 20 75 38 20 2a 61 41 6c 6c 6f 63 3b 20 20 20 20   u8 *aAlloc;    
3640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3650: 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 64 20 73 70   /* Allocated sp
3660: 61 63 65 20 2a 2f 0a 20 20 75 38 20 2a 61 4b 65  ace */.  u8 *aKe
3670: 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  y;              
3680: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
3690: 74 65 72 20 74 6f 20 63 75 72 72 65 6e 74 20 6b  ter to current k
36a0: 65 79 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75 66  ey */.  u8 *aBuf
36b0: 66 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20  fer;            
36c0: 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65          /* Curre
36d0: 6e 74 20 72 65 61 64 20 62 75 66 66 65 72 20 2a  nt read buffer *
36e0: 2f 0a 20 20 69 6e 74 20 6e 42 75 66 66 65 72 3b  /.  int nBuffer;
36f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3700: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 72      /* Size of r
3710: 65 61 64 20 62 75 66 66 65 72 20 69 6e 20 62 79  ead buffer in by
3720: 74 65 73 20 2a 2f 0a 20 20 75 38 20 2a 61 4d 61  tes */.  u8 *aMa
3730: 70 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p;              
3740: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
3750: 74 65 72 20 74 6f 20 6d 61 70 70 69 6e 67 20 6f  ter to mapping o
3760: 66 20 65 6e 74 69 72 65 20 66 69 6c 65 20 2a 2f  f entire file */
3770: 0a 20 20 49 6e 63 72 4d 65 72 67 65 72 20 2a 70  .  IncrMerger *p
3780: 49 6e 63 72 3b 20 20 20 20 20 20 20 20 20 20 20  Incr;           
3790: 20 20 20 2f 2a 20 49 6e 63 72 65 6d 65 6e 74 61     /* Incrementa
37a0: 6c 20 6d 65 72 67 65 72 20 2a 2f 0a 7d 3b 0a 0a  l merger */.};..
37b0: 2f 2a 0a 2a 2a 20 4e 6f 72 6d 61 6c 6c 79 2c 20  /*.** Normally, 
37c0: 61 20 50 6d 61 52 65 61 64 65 72 20 6f 62 6a 65  a PmaReader obje
37d0: 63 74 20 69 74 65 72 61 74 65 73 20 74 68 72 6f  ct iterates thro
37e0: 75 67 68 20 61 6e 20 65 78 69 73 74 69 6e 67 20  ugh an existing 
37f0: 50 4d 41 20 73 74 6f 72 65 64 20 0a 2a 2a 20 77  PMA stored .** w
3800: 69 74 68 69 6e 20 61 20 74 65 6d 70 20 66 69 6c  ithin a temp fil
3810: 65 2e 20 48 6f 77 65 76 65 72 2c 20 69 66 20 74  e. However, if t
3820: 68 65 20 50 6d 61 52 65 61 64 65 72 2e 70 49 6e  he PmaReader.pIn
3830: 63 72 20 76 61 72 69 61 62 6c 65 20 70 6f 69 6e  cr variable poin
3840: 74 73 20 74 6f 0a 2a 2a 20 61 6e 20 6f 62 6a 65  ts to.** an obje
3850: 63 74 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77  ct of the follow
3860: 69 6e 67 20 74 79 70 65 2c 20 69 74 20 6d 61 79  ing type, it may
3870: 20 62 65 20 75 73 65 64 20 74 6f 20 69 74 65 72   be used to iter
3880: 61 74 65 2f 6d 65 72 67 65 20 74 68 72 6f 75 67  ate/merge throug
3890: 68 0a 2a 2a 20 6d 75 6c 74 69 70 6c 65 20 50 4d  h.** multiple PM
38a0: 41 73 20 73 69 6d 75 6c 74 61 6e 65 6f 75 73 6c  As simultaneousl
38b0: 79 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 49 6e 63  y..*/.struct Inc
38c0: 72 4d 65 72 67 65 72 20 7b 0a 20 20 53 6f 72 74  rMerger {.  Sort
38d0: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 3b 20  Subtask *pTask; 
38e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
38f0: 61 73 6b 20 74 68 61 74 20 6f 77 6e 73 20 74 68  ask that owns th
3900: 69 73 20 6d 65 72 67 65 72 20 2a 2f 0a 20 20 53  is merger */.  S
3910: 6f 72 74 65 72 54 68 72 65 61 64 20 74 68 72 65  orterThread thre
3920: 61 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  ad;            /
3930: 2a 20 54 68 72 65 61 64 20 66 6f 72 20 70 6f 70  * Thread for pop
3940: 75 6c 61 74 69 6e 67 20 61 46 69 6c 65 5b 31 5d  ulating aFile[1]
3950: 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e   */.  MergeEngin
3960: 65 20 2a 70 4d 65 72 67 65 72 3b 20 20 20 20 20  e *pMerger;     
3970: 20 20 20 20 20 20 2f 2a 20 4d 65 72 67 65 20 65        /* Merge e
3980: 6e 67 69 6e 65 20 74 68 72 65 61 64 20 72 65 61  ngine thread rea
3990: 64 73 20 64 61 74 61 20 66 72 6f 6d 20 2a 2f 0a  ds data from */.
39a0: 20 20 69 36 34 20 69 53 74 61 72 74 4f 66 66 3b    i64 iStartOff;
39b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
39c0: 20 20 2f 2a 20 4f 66 66 73 65 74 20 74 6f 20 73    /* Offset to s
39d0: 74 61 72 74 20 77 72 69 74 69 6e 67 20 66 69 6c  tart writing fil
39e0: 65 20 61 74 20 2a 2f 0a 20 20 69 6e 74 20 6d 78  e at */.  int mx
39f0: 53 7a 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  Sz;             
3a00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 78            /* Max
3a10: 69 6d 75 6d 20 62 79 74 65 73 20 6f 66 20 64 61  imum bytes of da
3a20: 74 61 20 74 6f 20 73 74 6f 72 65 20 2a 2f 0a 20  ta to store */. 
3a30: 20 69 6e 74 20 62 45 6f 66 3b 20 20 20 20 20 20   int bEof;      
3a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a50: 20 2f 2a 20 53 65 74 20 74 6f 20 74 72 75 65 20   /* Set to true 
3a60: 77 68 65 6e 20 6d 65 72 67 65 20 69 73 20 66 69  when merge is fi
3a70: 6e 69 73 68 65 64 20 2a 2f 0a 20 20 69 6e 74 20  nished */.  int 
3a80: 62 55 73 65 54 68 72 65 61 64 3b 20 20 20 20 20  bUseThread;     
3a90: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
3aa0: 72 75 65 20 74 6f 20 75 73 65 20 61 20 62 67 20  rue to use a bg 
3ab0: 74 68 72 65 61 64 20 66 6f 72 20 74 68 69 73 20  thread for this 
3ac0: 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 53 6f 72 74  object */.  Sort
3ad0: 65 72 46 69 6c 65 20 61 46 69 6c 65 5b 32 5d 3b  erFile aFile[2];
3ae0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 61              /* a
3af0: 46 69 6c 65 5b 30 5d 20 66 6f 72 20 72 65 61 64  File[0] for read
3b00: 69 6e 67 2c 20 5b 31 5d 20 66 6f 72 20 77 72 69  ing, [1] for wri
3b10: 74 69 6e 67 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  ting */.};../*.*
3b20: 2a 20 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66  * An instance of
3b30: 20 74 68 69 73 20 6f 62 6a 65 63 74 20 69 73 20   this object is 
3b40: 75 73 65 64 20 66 6f 72 20 77 72 69 74 69 6e 67  used for writing
3b50: 20 61 20 50 4d 41 2e 0a 2a 2a 0a 2a 2a 20 54 68   a PMA..**.** Th
3b60: 65 20 50 4d 41 20 69 73 20 77 72 69 74 74 65 6e  e PMA is written
3b70: 20 6f 6e 65 20 72 65 63 6f 72 64 20 61 74 20 61   one record at a
3b80: 20 74 69 6d 65 2e 20 20 45 61 63 68 20 72 65 63   time.  Each rec
3b90: 6f 72 64 20 69 73 20 6f 66 20 61 6e 20 61 72 62  ord is of an arb
3ba0: 69 74 72 61 72 79 0a 2a 2a 20 73 69 7a 65 2e 20  itrary.** size. 
3bb0: 20 42 75 74 20 49 2f 4f 20 69 73 20 6d 6f 72 65   But I/O is more
3bc0: 20 65 66 66 69 63 69 65 6e 74 20 69 66 20 69 74   efficient if it
3bd0: 20 6f 63 63 75 72 73 20 69 6e 20 70 61 67 65 2d   occurs in page-
3be0: 73 69 7a 65 64 20 62 6c 6f 63 6b 73 20 77 68 65  sized blocks whe
3bf0: 72 65 0a 2a 2a 20 65 61 63 68 20 62 6c 6f 63 6b  re.** each block
3c00: 20 69 73 20 61 6c 69 67 6e 65 64 20 6f 6e 20 61   is aligned on a
3c10: 20 70 61 67 65 20 62 6f 75 6e 64 61 72 79 2e 20   page boundary. 
3c20: 20 54 68 69 73 20 6f 62 6a 65 63 74 20 63 61 63   This object cac
3c30: 68 65 73 20 77 72 69 74 65 73 20 74 6f 0a 2a 2a  hes writes to.**
3c40: 20 74 68 65 20 50 4d 41 20 73 6f 20 74 68 61 74   the PMA so that
3c50: 20 61 6c 69 67 6e 65 64 2c 20 70 61 67 65 2d 73   aligned, page-s
3c60: 69 7a 65 20 62 6c 6f 63 6b 73 20 61 72 65 20 77  ize blocks are w
3c70: 72 69 74 74 65 6e 2e 0a 2a 2f 0a 73 74 72 75 63  ritten..*/.struc
3c80: 74 20 50 6d 61 57 72 69 74 65 72 20 7b 0a 20 20  t PmaWriter {.  
3c90: 69 6e 74 20 65 46 57 45 72 72 3b 20 20 20 20 20  int eFWErr;     
3ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3cb0: 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20 69 66 20 69  /* Non-zero if i
3cc0: 6e 20 61 6e 20 65 72 72 6f 72 20 73 74 61 74 65  n an error state
3cd0: 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75 66 66 65   */.  u8 *aBuffe
3ce0: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
3cf0: 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
3d00: 20 74 6f 20 77 72 69 74 65 20 62 75 66 66 65 72   to write buffer
3d10: 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66 66 65   */.  int nBuffe
3d20: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
3d30: 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
3d40: 20 77 72 69 74 65 20 62 75 66 66 65 72 20 69 6e   write buffer in
3d50: 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20   bytes */.  int 
3d60: 69 42 75 66 53 74 61 72 74 3b 20 20 20 20 20 20  iBufStart;      
3d70: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
3d80: 69 72 73 74 20 62 79 74 65 20 6f 66 20 62 75 66  irst byte of buf
3d90: 66 65 72 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a  fer to write */.
3da0: 20 20 69 6e 74 20 69 42 75 66 45 6e 64 3b 20 20    int iBufEnd;  
3db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3dc0: 20 20 2f 2a 20 4c 61 73 74 20 62 79 74 65 20 6f    /* Last byte o
3dd0: 66 20 62 75 66 66 65 72 20 74 6f 20 77 72 69 74  f buffer to writ
3de0: 65 20 2a 2f 0a 20 20 69 36 34 20 69 57 72 69 74  e */.  i64 iWrit
3df0: 65 4f 66 66 3b 20 20 20 20 20 20 20 20 20 20 20  eOff;           
3e00: 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74         /* Offset
3e10: 20 6f 66 20 73 74 61 72 74 20 6f 66 20 62 75 66   of start of buf
3e20: 66 65 72 20 69 6e 20 66 69 6c 65 20 2a 2f 0a 20  fer in file */. 
3e30: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
3e40: 46 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20  File;           
3e50: 20 2f 2a 20 46 69 6c 65 20 74 6f 20 77 72 69 74   /* File to writ
3e60: 65 20 74 6f 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  e to */.};../*.*
3e70: 2a 20 54 68 69 73 20 6f 62 6a 65 63 74 20 69 73  * This object is
3e80: 20 74 68 65 20 68 65 61 64 65 72 20 6f 6e 20 61   the header on a
3e90: 20 73 69 6e 67 6c 65 20 72 65 63 6f 72 64 20 77   single record w
3ea0: 68 69 6c 65 20 74 68 61 74 20 72 65 63 6f 72 64  hile that record
3eb0: 20 69 73 20 62 65 69 6e 67 0a 2a 2a 20 68 65 6c   is being.** hel
3ec0: 64 20 69 6e 20 6d 65 6d 6f 72 79 20 61 6e 64 20  d in memory and 
3ed0: 70 72 69 6f 72 20 74 6f 20 62 65 69 6e 67 20 77  prior to being w
3ee0: 72 69 74 74 65 6e 20 6f 75 74 20 61 73 20 70 61  ritten out as pa
3ef0: 72 74 20 6f 66 20 61 20 50 4d 41 2e 0a 2a 2a 0a  rt of a PMA..**.
3f00: 2a 2a 20 48 6f 77 20 74 68 65 20 6c 69 6e 6b 65  ** How the linke
3f10: 64 20 6c 69 73 74 20 69 73 20 63 6f 6e 6e 65 63  d list is connec
3f20: 74 65 64 20 64 65 70 65 6e 64 73 20 6f 6e 20 68  ted depends on h
3f30: 6f 77 20 6d 65 6d 6f 72 79 20 69 73 20 62 65 69  ow memory is bei
3f40: 6e 67 20 6d 61 6e 61 67 65 64 0a 2a 2a 20 62 79  ng managed.** by
3f50: 20 74 68 69 73 20 6d 6f 64 75 6c 65 2e 20 49 66   this module. If
3f60: 20 75 73 69 6e 67 20 61 20 73 65 70 61 72 61 74   using a separat
3f70: 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 6f 72  e allocation for
3f80: 20 65 61 63 68 20 69 6e 2d 6d 65 6d 6f 72 79 20   each in-memory 
3f90: 72 65 63 6f 72 64 0a 2a 2a 20 28 56 64 62 65 53  record.** (VdbeS
3fa0: 6f 72 74 65 72 2e 61 4d 65 6d 6f 72 79 3d 3d 30  orter.aMemory==0
3fb0: 29 2c 20 74 68 65 6e 20 74 68 65 20 6c 69 73 74  ), then the list
3fc0: 20 69 73 20 61 6c 77 61 79 73 20 63 6f 6e 6e 65   is always conne
3fd0: 63 74 65 64 20 75 73 69 6e 67 20 74 68 65 0a 2a  cted using the.*
3fe0: 2a 20 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 75  * SorterRecord.u
3ff0: 2e 70 4e 65 78 74 20 70 6f 69 6e 74 65 72 73 2e  .pNext pointers.
4000: 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 69 66 20 75 73  .**.** Or, if us
4010: 69 6e 67 20 74 68 65 20 73 69 6e 67 6c 65 20 6c  ing the single l
4020: 61 72 67 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20  arge allocation 
4030: 6d 65 74 68 6f 64 20 28 56 64 62 65 53 6f 72 74  method (VdbeSort
4040: 65 72 2e 61 4d 65 6d 6f 72 79 21 3d 30 29 2c 0a  er.aMemory!=0),.
4050: 2a 2a 20 74 68 65 6e 20 77 68 69 6c 65 20 72 65  ** then while re
4060: 63 6f 72 64 73 20 61 72 65 20 62 65 69 6e 67 20  cords are being 
4070: 61 63 63 75 6d 75 6c 61 74 65 64 20 74 68 65 20  accumulated the 
4080: 6c 69 73 74 20 69 73 20 6c 69 6e 6b 65 64 20 75  list is linked u
4090: 73 69 6e 67 20 74 68 65 0a 2a 2a 20 53 6f 72 74  sing the.** Sort
40a0: 65 72 52 65 63 6f 72 64 2e 75 2e 69 4e 65 78 74  erRecord.u.iNext
40b0: 20 6f 66 66 73 65 74 2e 20 54 68 69 73 20 69 73   offset. This is
40c0: 20 62 65 63 61 75 73 65 20 74 68 65 20 61 4d 65   because the aMe
40d0: 6d 6f 72 79 5b 5d 20 61 72 72 61 79 20 6d 61 79  mory[] array may
40e0: 0a 2a 2a 20 62 65 20 73 71 6c 69 74 65 33 52 65  .** be sqlite3Re
40f0: 61 6c 6c 6f 63 28 29 65 64 20 77 68 69 6c 65 20  alloc()ed while 
4100: 72 65 63 6f 72 64 73 20 61 72 65 20 62 65 69 6e  records are bein
4110: 67 20 61 63 63 75 6d 75 6c 61 74 65 64 2e 20 4f  g accumulated. O
4120: 6e 63 65 20 74 68 65 20 56 4d 0a 2a 2a 20 68 61  nce the VM.** ha
4130: 73 20 66 69 6e 69 73 68 65 64 20 70 61 73 73 69  s finished passi
4140: 6e 67 20 72 65 63 6f 72 64 73 20 74 6f 20 74 68  ng records to th
4150: 65 20 73 6f 72 74 65 72 2c 20 6f 72 20 77 68 65  e sorter, or whe
4160: 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20  n the in-memory 
4170: 62 75 66 66 65 72 0a 2a 2a 20 69 73 20 66 75 6c  buffer.** is ful
4180: 6c 2c 20 74 68 65 20 6c 69 73 74 20 69 73 20 73  l, the list is s
4190: 6f 72 74 65 64 2e 20 41 73 20 70 61 72 74 20 6f  orted. As part o
41a0: 66 20 74 68 65 20 73 6f 72 74 69 6e 67 20 70 72  f the sorting pr
41b0: 6f 63 65 73 73 2c 20 69 74 20 69 73 0a 2a 2a 20  ocess, it is.** 
41c0: 63 6f 6e 76 65 72 74 65 64 20 74 6f 20 75 73 65  converted to use
41d0: 20 74 68 65 20 53 6f 72 74 65 72 52 65 63 6f 72   the SorterRecor
41e0: 64 2e 75 2e 70 4e 65 78 74 20 70 6f 69 6e 74 65  d.u.pNext pointe
41f0: 72 73 2e 20 53 65 65 20 66 75 6e 63 74 69 6f 6e  rs. See function
4200: 0a 2a 2a 20 76 64 62 65 53 6f 72 74 65 72 53 6f  .** vdbeSorterSo
4210: 72 74 28 29 20 66 6f 72 20 64 65 74 61 69 6c 73  rt() for details
4220: 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 53 6f 72 74  ..*/.struct Sort
4230: 65 72 52 65 63 6f 72 64 20 7b 0a 20 20 69 6e 74  erRecord {.  int
4240: 20 6e 56 61 6c 3b 20 20 20 20 20 20 20 20 20 20   nVal;          
4250: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4260: 53 69 7a 65 20 6f 66 20 74 68 65 20 72 65 63 6f  Size of the reco
4270: 72 64 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20  rd in bytes */. 
4280: 20 75 6e 69 6f 6e 20 7b 0a 20 20 20 20 53 6f 72   union {.    Sor
4290: 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65 78 74  terRecord *pNext
42a0: 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f  ;          /* Po
42b0: 69 6e 74 65 72 20 74 6f 20 6e 65 78 74 20 72 65  inter to next re
42c0: 63 6f 72 64 20 69 6e 20 6c 69 73 74 20 2a 2f 0a  cord in list */.
42d0: 20 20 20 20 69 6e 74 20 69 4e 65 78 74 3b 20 20      int iNext;  
42e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
42f0: 20 20 2f 2a 20 4f 66 66 73 65 74 20 77 69 74 68    /* Offset with
4300: 69 6e 20 61 4d 65 6d 6f 72 79 20 6f 66 20 6e 65  in aMemory of ne
4310: 78 74 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20 7d  xt record */.  }
4320: 20 75 3b 0a 20 20 2f 2a 20 54 68 65 20 64 61 74   u;.  /* The dat
4330: 61 20 66 6f 72 20 74 68 65 20 72 65 63 6f 72 64  a for the record
4340: 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c   immediately fol
4350: 6c 6f 77 73 20 74 68 69 73 20 68 65 61 64 65 72  lows this header
4360: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 52 65 74 75 72   */.};../* Retur
4370: 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74  n a pointer to t
4380: 68 65 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69  he buffer contai
4390: 6e 69 6e 67 20 74 68 65 20 72 65 63 6f 72 64 20  ning the record 
43a0: 64 61 74 61 20 66 6f 72 20 53 6f 72 74 65 72 52  data for SorterR
43b0: 65 63 6f 72 64 0a 2a 2a 20 6f 62 6a 65 63 74 20  ecord.** object 
43c0: 70 2e 20 53 68 6f 75 6c 64 20 62 65 20 75 73 65  p. Should be use
43d0: 64 20 61 73 20 69 66 3a 0a 2a 2a 0a 2a 2a 20 20  d as if:.**.**  
43e0: 20 76 6f 69 64 20 2a 53 52 56 41 4c 28 53 6f 72   void *SRVAL(Sor
43f0: 74 65 72 52 65 63 6f 72 64 20 2a 70 29 20 7b 20  terRecord *p) { 
4400: 72 65 74 75 72 6e 20 28 76 6f 69 64 2a 29 26 70  return (void*)&p
4410: 5b 31 5d 3b 20 7d 0a 2a 2f 0a 23 64 65 66 69 6e  [1]; }.*/.#defin
4420: 65 20 53 52 56 41 4c 28 70 29 20 28 28 76 6f 69  e SRVAL(p) ((voi
4430: 64 2a 29 28 28 53 6f 72 74 65 72 52 65 63 6f 72  d*)((SorterRecor
4440: 64 2a 29 28 70 29 20 2b 20 31 29 29 0a 0a 2f 2a  d*)(p) + 1))../*
4450: 20 54 68 65 20 6d 69 6e 69 6d 75 6d 20 50 4d 41   The minimum PMA
4460: 20 73 69 7a 65 20 69 73 20 73 65 74 20 74 6f 20   size is set to 
4470: 74 68 69 73 20 76 61 6c 75 65 20 6d 75 6c 74 69  this value multi
4480: 70 6c 69 65 64 20 62 79 20 74 68 65 20 64 61 74  plied by the dat
4490: 61 62 61 73 65 0a 2a 2a 20 70 61 67 65 20 73 69  abase.** page si
44a0: 7a 65 20 69 6e 20 62 79 74 65 73 2e 20 20 2a 2f  ze in bytes.  */
44b0: 0a 23 64 65 66 69 6e 65 20 53 4f 52 54 45 52 5f  .#define SORTER_
44c0: 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20 31 30 0a 0a  MIN_WORKING 10..
44d0: 2f 2a 20 4d 61 78 69 6d 75 6d 20 6e 75 6d 62 65  /* Maximum numbe
44e0: 72 20 6f 66 20 50 4d 41 73 20 74 68 61 74 20 61  r of PMAs that a
44f0: 20 73 69 6e 67 6c 65 20 4d 65 72 67 65 45 6e 67   single MergeEng
4500: 69 6e 65 20 63 61 6e 20 6d 65 72 67 65 20 2a 2f  ine can merge */
4510: 0a 23 64 65 66 69 6e 65 20 53 4f 52 54 45 52 5f  .#define SORTER_
4520: 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20  MAX_MERGE_COUNT 
4530: 31 36 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 76  16..static int v
4540: 64 62 65 49 6e 63 72 53 77 61 70 28 49 6e 63 72  dbeIncrSwap(Incr
4550: 4d 65 72 67 65 72 2a 29 3b 0a 73 74 61 74 69 63  Merger*);.static
4560: 20 76 6f 69 64 20 76 64 62 65 49 6e 63 72 46 72   void vdbeIncrFr
4570: 65 65 28 49 6e 63 72 4d 65 72 67 65 72 2a 29 3b  ee(IncrMerger*);
4580: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6c 6c  ../*.** Free all
4590: 20 6d 65 6d 6f 72 79 20 62 65 6c 6f 6e 67 69 6e   memory belongin
45a0: 67 20 74 6f 20 74 68 65 20 50 6d 61 52 65 61 64  g to the PmaRead
45b0: 65 72 20 6f 62 6a 65 63 74 20 70 61 73 73 65 64  er object passed
45c0: 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64 0a 2a   as the second.*
45d0: 2a 20 61 72 67 75 6d 65 6e 74 2e 20 41 6c 6c 20  * argument. All 
45e0: 73 74 72 75 63 74 75 72 65 20 66 69 65 6c 64 73  structure fields
45f0: 20 61 72 65 20 73 65 74 20 74 6f 20 7a 65 72 6f   are set to zero
4600: 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e   before returnin
4610: 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  g..*/.static voi
4620: 64 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 43  d vdbePmaReaderC
4630: 6c 65 61 72 28 50 6d 61 52 65 61 64 65 72 20 2a  lear(PmaReader *
4640: 70 49 74 65 72 29 7b 0a 20 20 73 71 6c 69 74 65  pIter){.  sqlite
4650: 33 5f 66 72 65 65 28 70 49 74 65 72 2d 3e 61 41  3_free(pIter->aA
4660: 6c 6c 6f 63 29 3b 0a 20 20 73 71 6c 69 74 65 33  lloc);.  sqlite3
4670: 5f 66 72 65 65 28 70 49 74 65 72 2d 3e 61 42 75  _free(pIter->aBu
4680: 66 66 65 72 29 3b 0a 20 20 69 66 28 20 70 49 74  ffer);.  if( pIt
4690: 65 72 2d 3e 61 4d 61 70 20 29 20 73 71 6c 69 74  er->aMap ) sqlit
46a0: 65 33 4f 73 55 6e 66 65 74 63 68 28 70 49 74 65  e3OsUnfetch(pIte
46b0: 72 2d 3e 70 46 69 6c 65 2c 20 30 2c 20 70 49 74  r->pFile, 0, pIt
46c0: 65 72 2d 3e 61 4d 61 70 29 3b 0a 20 20 69 66 28  er->aMap);.  if(
46d0: 20 70 49 74 65 72 2d 3e 70 49 6e 63 72 20 29 20   pIter->pIncr ) 
46e0: 76 64 62 65 49 6e 63 72 46 72 65 65 28 70 49 74  vdbeIncrFree(pIt
46f0: 65 72 2d 3e 70 49 6e 63 72 29 3b 0a 20 20 6d 65  er->pIncr);.  me
4700: 6d 73 65 74 28 70 49 74 65 72 2c 20 30 2c 20 73  mset(pIter, 0, s
4710: 69 7a 65 6f 66 28 50 6d 61 52 65 61 64 65 72 29  izeof(PmaReader)
4720: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64  );.}../*.** Read
4730: 20 6e 42 79 74 65 20 62 79 74 65 73 20 6f 66 20   nByte bytes of 
4740: 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 73 74  data from the st
4750: 72 65 61 6d 20 6f 66 20 64 61 74 61 20 69 74 65  ream of data ite
4760: 72 61 74 65 64 20 62 79 20 6f 62 6a 65 63 74 20  rated by object 
4770: 70 2e 0a 2a 2a 20 49 66 20 73 75 63 63 65 73 73  p..** If success
4780: 66 75 6c 2c 20 73 65 74 20 2a 70 70 4f 75 74 20  ful, set *ppOut 
4790: 74 6f 20 70 6f 69 6e 74 20 74 6f 20 61 20 62 75  to point to a bu
47a0: 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ffer containing 
47b0: 74 68 65 20 64 61 74 61 0a 2a 2a 20 61 6e 64 20  the data.** and 
47c0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
47d0: 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20  . Otherwise, if 
47e0: 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c  an error occurs,
47f0: 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74   return an SQLit
4800: 65 0a 2a 2a 20 65 72 72 6f 72 20 63 6f 64 65 2e  e.** error code.
4810: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 62 75 66 66 65  .**.** The buffe
4820: 72 20 69 6e 64 69 63 61 74 65 64 20 62 79 20 2a  r indicated by *
4830: 70 70 4f 75 74 20 6d 61 79 20 6f 6e 6c 79 20 62  ppOut may only b
4840: 65 20 63 6f 6e 73 69 64 65 72 65 64 20 76 61 6c  e considered val
4850: 69 64 20 75 6e 74 69 6c 20 74 68 65 0a 2a 2a 20  id until the.** 
4860: 6e 65 78 74 20 63 61 6c 6c 20 74 6f 20 74 68 69  next call to thi
4870: 73 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73  s function..*/.s
4880: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d  tatic int vdbePm
4890: 61 52 65 61 64 42 6c 6f 62 28 0a 20 20 50 6d 61  aReadBlob(.  Pma
48a0: 52 65 61 64 65 72 20 2a 70 2c 20 20 20 20 20 20  Reader *p,      
48b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
48c0: 49 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69 6e  Iterator */.  in
48d0: 74 20 6e 42 79 74 65 2c 20 20 20 20 20 20 20 20  t nByte,        
48e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
48f0: 20 42 79 74 65 73 20 6f 66 20 64 61 74 61 20 74   Bytes of data t
4900: 6f 20 72 65 61 64 20 2a 2f 0a 20 20 75 38 20 2a  o read */.  u8 *
4910: 2a 70 70 4f 75 74 20 20 20 20 20 20 20 20 20 20  *ppOut          
4920: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
4930: 55 54 3a 20 50 6f 69 6e 74 65 72 20 74 6f 20 62  UT: Pointer to b
4940: 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67  uffer containing
4950: 20 64 61 74 61 20 2a 2f 0a 29 7b 0a 20 20 69 6e   data */.){.  in
4960: 74 20 69 42 75 66 3b 20 20 20 20 20 20 20 20 20  t iBuf;         
4970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4980: 20 4f 66 66 73 65 74 20 77 69 74 68 69 6e 20 62   Offset within b
4990: 75 66 66 65 72 20 74 6f 20 72 65 61 64 20 66 72  uffer to read fr
49a0: 6f 6d 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 76 61  om */.  int nAva
49b0: 69 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  il;             
49c0: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
49d0: 20 6f 66 20 64 61 74 61 20 61 76 61 69 6c 61 62   of data availab
49e0: 6c 65 20 69 6e 20 62 75 66 66 65 72 20 2a 2f 0a  le in buffer */.
49f0: 0a 20 20 69 66 28 20 70 2d 3e 61 4d 61 70 20 29  .  if( p->aMap )
4a00: 7b 0a 20 20 20 20 2a 70 70 4f 75 74 20 3d 20 26  {.    *ppOut = &
4a10: 70 2d 3e 61 4d 61 70 5b 70 2d 3e 69 52 65 61 64  p->aMap[p->iRead
4a20: 4f 66 66 5d 3b 0a 20 20 20 20 70 2d 3e 69 52 65  Off];.    p->iRe
4a30: 61 64 4f 66 66 20 2b 3d 20 6e 42 79 74 65 3b 0a  adOff += nByte;.
4a40: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
4a50: 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 61 73 73  E_OK;.  }..  ass
4a60: 65 72 74 28 20 70 2d 3e 61 42 75 66 66 65 72 20  ert( p->aBuffer 
4a70: 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 72  );..  /* If ther
4a80: 65 20 69 73 20 6e 6f 20 6d 6f 72 65 20 64 61 74  e is no more dat
4a90: 61 20 74 6f 20 62 65 20 72 65 61 64 20 66 72 6f  a to be read fro
4aa0: 6d 20 74 68 65 20 62 75 66 66 65 72 2c 20 72 65  m the buffer, re
4ab0: 61 64 20 74 68 65 20 6e 65 78 74 20 0a 20 20 2a  ad the next .  *
4ac0: 2a 20 70 2d 3e 6e 42 75 66 66 65 72 20 62 79 74  * p->nBuffer byt
4ad0: 65 73 20 6f 66 20 64 61 74 61 20 66 72 6f 6d 20  es of data from 
4ae0: 74 68 65 20 66 69 6c 65 20 69 6e 74 6f 20 69 74  the file into it
4af0: 2e 20 4f 72 2c 20 69 66 20 74 68 65 72 65 20 61  . Or, if there a
4b00: 72 65 20 6c 65 73 73 0a 20 20 2a 2a 20 74 68 61  re less.  ** tha
4b10: 6e 20 70 2d 3e 6e 42 75 66 66 65 72 20 62 79 74  n p->nBuffer byt
4b20: 65 73 20 72 65 6d 61 69 6e 69 6e 67 20 69 6e 20  es remaining in 
4b30: 74 68 65 20 50 4d 41 2c 20 72 65 61 64 20 61 6c  the PMA, read al
4b40: 6c 20 72 65 6d 61 69 6e 69 6e 67 20 64 61 74 61  l remaining data
4b50: 2e 20 20 2a 2f 0a 20 20 69 42 75 66 20 3d 20 70  .  */.  iBuf = p
4b60: 2d 3e 69 52 65 61 64 4f 66 66 20 25 20 70 2d 3e  ->iReadOff % p->
4b70: 6e 42 75 66 66 65 72 3b 0a 20 20 69 66 28 20 69  nBuffer;.  if( i
4b80: 42 75 66 3d 3d 30 20 29 7b 0a 20 20 20 20 69 6e  Buf==0 ){.    in
4b90: 74 20 6e 52 65 61 64 3b 20 20 20 20 20 20 20 20  t nRead;        
4ba0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
4bb0: 79 74 65 73 20 74 6f 20 72 65 61 64 20 66 72 6f  ytes to read fro
4bc0: 6d 20 64 69 73 6b 20 2a 2f 0a 20 20 20 20 69 6e  m disk */.    in
4bd0: 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
4be0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73              /* s
4bf0: 71 6c 69 74 65 33 4f 73 52 65 61 64 28 29 20 72  qlite3OsRead() r
4c00: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20  eturn code */.. 
4c10: 20 20 20 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20     /* Determine 
4c20: 68 6f 77 20 6d 61 6e 79 20 62 79 74 65 73 20 6f  how many bytes o
4c30: 66 20 64 61 74 61 20 74 6f 20 72 65 61 64 2e 20  f data to read. 
4c40: 2a 2f 0a 20 20 20 20 69 66 28 20 28 70 2d 3e 69  */.    if( (p->i
4c50: 45 6f 66 20 2d 20 70 2d 3e 69 52 65 61 64 4f 66  Eof - p->iReadOf
4c60: 66 29 20 3e 20 28 69 36 34 29 70 2d 3e 6e 42 75  f) > (i64)p->nBu
4c70: 66 66 65 72 20 29 7b 0a 20 20 20 20 20 20 6e 52  ffer ){.      nR
4c80: 65 61 64 20 3d 20 70 2d 3e 6e 42 75 66 66 65 72  ead = p->nBuffer
4c90: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
4ca0: 20 20 20 6e 52 65 61 64 20 3d 20 28 69 6e 74 29     nRead = (int)
4cb0: 28 70 2d 3e 69 45 6f 66 20 2d 20 70 2d 3e 69 52  (p->iEof - p->iR
4cc0: 65 61 64 4f 66 66 29 3b 0a 20 20 20 20 7d 0a 20  eadOff);.    }. 
4cd0: 20 20 20 61 73 73 65 72 74 28 20 6e 52 65 61 64     assert( nRead
4ce0: 3e 30 20 29 3b 0a 0a 20 20 20 20 2f 2a 20 52 65  >0 );..    /* Re
4cf0: 61 64 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65  ad data from the
4d00: 20 66 69 6c 65 2e 20 52 65 74 75 72 6e 20 65 61   file. Return ea
4d10: 72 6c 79 20 69 66 20 61 6e 20 65 72 72 6f 72 20  rly if an error 
4d20: 6f 63 63 75 72 73 2e 20 2a 2f 0a 20 20 20 20 72  occurs. */.    r
4d30: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61  c = sqlite3OsRea
4d40: 64 28 70 2d 3e 70 46 69 6c 65 2c 20 70 2d 3e 61  d(p->pFile, p->a
4d50: 42 75 66 66 65 72 2c 20 6e 52 65 61 64 2c 20 70  Buffer, nRead, p
4d60: 2d 3e 69 52 65 61 64 4f 66 66 29 3b 0a 20 20 20  ->iReadOff);.   
4d70: 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c   assert( rc!=SQL
4d80: 49 54 45 5f 49 4f 45 52 52 5f 53 48 4f 52 54 5f  ITE_IOERR_SHORT_
4d90: 52 45 41 44 20 29 3b 0a 20 20 20 20 69 66 28 20  READ );.    if( 
4da0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
4db0: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20  return rc;.  }. 
4dc0: 20 6e 41 76 61 69 6c 20 3d 20 70 2d 3e 6e 42 75   nAvail = p->nBu
4dd0: 66 66 65 72 20 2d 20 69 42 75 66 3b 20 0a 0a 20  ffer - iBuf; .. 
4de0: 20 69 66 28 20 6e 42 79 74 65 3c 3d 6e 41 76 61   if( nByte<=nAva
4df0: 69 6c 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 65  il ){.    /* The
4e00: 20 72 65 71 75 65 73 74 65 64 20 64 61 74 61 20   requested data 
4e10: 69 73 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20  is available in 
4e20: 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 62 75  the in-memory bu
4e30: 66 66 65 72 2e 20 49 6e 20 74 68 69 73 0a 20 20  ffer. In this.  
4e40: 20 20 2a 2a 20 63 61 73 65 20 74 68 65 72 65 20    ** case there 
4e50: 69 73 20 6e 6f 20 6e 65 65 64 20 74 6f 20 6d 61  is no need to ma
4e60: 6b 65 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65  ke a copy of the
4e70: 20 64 61 74 61 2c 20 6a 75 73 74 20 72 65 74 75   data, just retu
4e80: 72 6e 20 61 20 0a 20 20 20 20 2a 2a 20 70 6f 69  rn a .    ** poi
4e90: 6e 74 65 72 20 69 6e 74 6f 20 74 68 65 20 62 75  nter into the bu
4ea0: 66 66 65 72 20 74 6f 20 74 68 65 20 63 61 6c 6c  ffer to the call
4eb0: 65 72 2e 20 20 2a 2f 0a 20 20 20 20 2a 70 70 4f  er.  */.    *ppO
4ec0: 75 74 20 3d 20 26 70 2d 3e 61 42 75 66 66 65 72  ut = &p->aBuffer
4ed0: 5b 69 42 75 66 5d 3b 0a 20 20 20 20 70 2d 3e 69  [iBuf];.    p->i
4ee0: 52 65 61 64 4f 66 66 20 2b 3d 20 6e 42 79 74 65  ReadOff += nByte
4ef0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f  ;.  }else{.    /
4f00: 2a 20 54 68 65 20 72 65 71 75 65 73 74 65 64 20  * The requested 
4f10: 64 61 74 61 20 69 73 20 6e 6f 74 20 61 6c 6c 20  data is not all 
4f20: 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65  available in the
4f30: 20 69 6e 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65   in-memory buffe
4f40: 72 2e 0a 20 20 20 20 2a 2a 20 49 6e 20 74 68 69  r..    ** In thi
4f50: 73 20 63 61 73 65 2c 20 61 6c 6c 6f 63 61 74 65  s case, allocate
4f60: 20 73 70 61 63 65 20 61 74 20 70 2d 3e 61 41 6c   space at p->aAl
4f70: 6c 6f 63 5b 5d 20 74 6f 20 63 6f 70 79 20 74 68  loc[] to copy th
4f80: 65 20 72 65 71 75 65 73 74 65 64 0a 20 20 20 20  e requested.    
4f90: 2a 2a 20 72 61 6e 67 65 20 69 6e 74 6f 2e 20 54  ** range into. T
4fa0: 68 65 6e 20 72 65 74 75 72 6e 20 61 20 63 6f 70  hen return a cop
4fb0: 79 20 6f 66 20 70 6f 69 6e 74 65 72 20 70 2d 3e  y of pointer p->
4fc0: 61 41 6c 6c 6f 63 20 74 6f 20 74 68 65 20 63 61  aAlloc to the ca
4fd0: 6c 6c 65 72 2e 20 20 2a 2f 0a 20 20 20 20 69 6e  ller.  */.    in
4fe0: 74 20 6e 52 65 6d 3b 20 20 20 20 20 20 20 20 20  t nRem;         
4ff0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
5000: 79 74 65 73 20 72 65 6d 61 69 6e 69 6e 67 20 74  ytes remaining t
5010: 6f 20 63 6f 70 79 20 2a 2f 0a 0a 20 20 20 20 2f  o copy */..    /
5020: 2a 20 45 78 74 65 6e 64 20 74 68 65 20 70 2d 3e  * Extend the p->
5030: 61 41 6c 6c 6f 63 5b 5d 20 61 6c 6c 6f 63 61 74  aAlloc[] allocat
5040: 69 6f 6e 20 69 66 20 72 65 71 75 69 72 65 64 2e  ion if required.
5050: 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 2d 3e 6e   */.    if( p->n
5060: 41 6c 6c 6f 63 3c 6e 42 79 74 65 20 29 7b 0a 20  Alloc<nByte ){. 
5070: 20 20 20 20 20 75 38 20 2a 61 4e 65 77 3b 0a 20       u8 *aNew;. 
5080: 20 20 20 20 20 69 6e 74 20 6e 4e 65 77 20 3d 20       int nNew = 
5090: 4d 41 58 28 31 32 38 2c 20 70 2d 3e 6e 41 6c 6c  MAX(128, p->nAll
50a0: 6f 63 2a 32 29 3b 0a 20 20 20 20 20 20 77 68 69  oc*2);.      whi
50b0: 6c 65 28 20 6e 42 79 74 65 3e 6e 4e 65 77 20 29  le( nByte>nNew )
50c0: 20 6e 4e 65 77 20 3d 20 6e 4e 65 77 2a 32 3b 0a   nNew = nNew*2;.
50d0: 20 20 20 20 20 20 61 4e 65 77 20 3d 20 73 71 6c        aNew = sql
50e0: 69 74 65 33 52 65 61 6c 6c 6f 63 28 70 2d 3e 61  ite3Realloc(p->a
50f0: 41 6c 6c 6f 63 2c 20 6e 4e 65 77 29 3b 0a 20 20  Alloc, nNew);.  
5100: 20 20 20 20 69 66 28 20 21 61 4e 65 77 20 29 20      if( !aNew ) 
5110: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
5120: 4d 45 4d 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 41  MEM;.      p->nA
5130: 6c 6c 6f 63 20 3d 20 6e 4e 65 77 3b 0a 20 20 20  lloc = nNew;.   
5140: 20 20 20 70 2d 3e 61 41 6c 6c 6f 63 20 3d 20 61     p->aAlloc = a
5150: 4e 65 77 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  New;.    }..    
5160: 2f 2a 20 43 6f 70 79 20 61 73 20 6d 75 63 68 20  /* Copy as much 
5170: 64 61 74 61 20 61 73 20 69 73 20 61 76 61 69 6c  data as is avail
5180: 61 62 6c 65 20 69 6e 20 74 68 65 20 62 75 66 66  able in the buff
5190: 65 72 20 69 6e 74 6f 20 74 68 65 20 73 74 61 72  er into the star
51a0: 74 20 6f 66 0a 20 20 20 20 2a 2a 20 70 2d 3e 61  t of.    ** p->a
51b0: 41 6c 6c 6f 63 5b 5d 2e 20 20 2a 2f 0a 20 20 20  Alloc[].  */.   
51c0: 20 6d 65 6d 63 70 79 28 70 2d 3e 61 41 6c 6c 6f   memcpy(p->aAllo
51d0: 63 2c 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 69  c, &p->aBuffer[i
51e0: 42 75 66 5d 2c 20 6e 41 76 61 69 6c 29 3b 0a 20  Buf], nAvail);. 
51f0: 20 20 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b     p->iReadOff +
5200: 3d 20 6e 41 76 61 69 6c 3b 0a 20 20 20 20 6e 52  = nAvail;.    nR
5210: 65 6d 20 3d 20 6e 42 79 74 65 20 2d 20 6e 41 76  em = nByte - nAv
5220: 61 69 6c 3b 0a 0a 20 20 20 20 2f 2a 20 54 68 65  ail;..    /* The
5230: 20 66 6f 6c 6c 6f 77 69 6e 67 20 6c 6f 6f 70 20   following loop 
5240: 63 6f 70 69 65 73 20 75 70 20 74 6f 20 70 2d 3e  copies up to p->
5250: 6e 42 75 66 66 65 72 20 62 79 74 65 73 20 70 65  nBuffer bytes pe
5260: 72 20 69 74 65 72 61 74 69 6f 6e 20 69 6e 74 6f  r iteration into
5270: 0a 20 20 20 20 2a 2a 20 74 68 65 20 70 2d 3e 61  .    ** the p->a
5280: 41 6c 6c 6f 63 5b 5d 20 62 75 66 66 65 72 2e 20  Alloc[] buffer. 
5290: 20 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 6e   */.    while( n
52a0: 52 65 6d 3e 30 20 29 7b 0a 20 20 20 20 20 20 69  Rem>0 ){.      i
52b0: 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
52c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 76 64             /* vd
52d0: 62 65 50 6d 61 52 65 61 64 42 6c 6f 62 28 29 20  bePmaReadBlob() 
52e0: 72 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  return code */. 
52f0: 20 20 20 20 20 69 6e 74 20 6e 43 6f 70 79 3b 20       int nCopy; 
5300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5310: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79   /* Number of by
5320: 74 65 73 20 74 6f 20 63 6f 70 79 20 2a 2f 0a 20  tes to copy */. 
5330: 20 20 20 20 20 75 38 20 2a 61 4e 65 78 74 3b 20       u8 *aNext; 
5340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5350: 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 62   /* Pointer to b
5360: 75 66 66 65 72 20 74 6f 20 63 6f 70 79 20 64 61  uffer to copy da
5370: 74 61 20 66 72 6f 6d 20 2a 2f 0a 0a 20 20 20 20  ta from */..    
5380: 20 20 6e 43 6f 70 79 20 3d 20 6e 52 65 6d 3b 0a    nCopy = nRem;.
5390: 20 20 20 20 20 20 69 66 28 20 6e 52 65 6d 3e 70        if( nRem>p
53a0: 2d 3e 6e 42 75 66 66 65 72 20 29 20 6e 43 6f 70  ->nBuffer ) nCop
53b0: 79 20 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a  y = p->nBuffer;.
53c0: 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 50        rc = vdbeP
53d0: 6d 61 52 65 61 64 42 6c 6f 62 28 70 2c 20 6e 43  maReadBlob(p, nC
53e0: 6f 70 79 2c 20 26 61 4e 65 78 74 29 3b 0a 20 20  opy, &aNext);.  
53f0: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
5400: 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
5410: 63 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  c;.      assert(
5420: 20 61 4e 65 78 74 21 3d 70 2d 3e 61 41 6c 6c 6f   aNext!=p->aAllo
5430: 63 20 29 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70  c );.      memcp
5440: 79 28 26 70 2d 3e 61 41 6c 6c 6f 63 5b 6e 42 79  y(&p->aAlloc[nBy
5450: 74 65 20 2d 20 6e 52 65 6d 5d 2c 20 61 4e 65 78  te - nRem], aNex
5460: 74 2c 20 6e 43 6f 70 79 29 3b 0a 20 20 20 20 20  t, nCopy);.     
5470: 20 6e 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a   nRem -= nCopy;.
5480: 20 20 20 20 7d 0a 0a 20 20 20 20 2a 70 70 4f 75      }..    *ppOu
5490: 74 20 3d 20 70 2d 3e 61 41 6c 6c 6f 63 3b 0a 20  t = p->aAlloc;. 
54a0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c   }..  return SQL
54b0: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
54c0: 20 52 65 61 64 20 61 20 76 61 72 69 6e 74 20 66   Read a varint f
54d0: 72 6f 6d 20 74 68 65 20 73 74 72 65 61 6d 20 6f  rom the stream o
54e0: 66 20 64 61 74 61 20 61 63 63 65 73 73 65 64 20  f data accessed 
54f0: 62 79 20 70 2e 20 53 65 74 20 2a 70 6e 4f 75 74  by p. Set *pnOut
5500: 20 74 6f 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65   to.** the value
5510: 20 72 65 61 64 2e 0a 2a 2f 0a 73 74 61 74 69 63   read..*/.static
5520: 20 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61 64   int vdbePmaRead
5530: 56 61 72 69 6e 74 28 50 6d 61 52 65 61 64 65 72  Varint(PmaReader
5540: 20 2a 70 2c 20 75 36 34 20 2a 70 6e 4f 75 74 29   *p, u64 *pnOut)
5550: 7b 0a 20 20 69 6e 74 20 69 42 75 66 3b 0a 0a 20  {.  int iBuf;.. 
5560: 20 69 66 28 20 70 2d 3e 61 4d 61 70 20 29 7b 0a   if( p->aMap ){.
5570: 20 20 20 20 70 2d 3e 69 52 65 61 64 4f 66 66 20      p->iReadOff 
5580: 2b 3d 20 73 71 6c 69 74 65 33 47 65 74 56 61 72  += sqlite3GetVar
5590: 69 6e 74 28 26 70 2d 3e 61 4d 61 70 5b 70 2d 3e  int(&p->aMap[p->
55a0: 69 52 65 61 64 4f 66 66 5d 2c 20 70 6e 4f 75 74  iReadOff], pnOut
55b0: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
55c0: 69 42 75 66 20 3d 20 70 2d 3e 69 52 65 61 64 4f  iBuf = p->iReadO
55d0: 66 66 20 25 20 70 2d 3e 6e 42 75 66 66 65 72 3b  ff % p->nBuffer;
55e0: 0a 20 20 20 20 69 66 28 20 69 42 75 66 20 26 26  .    if( iBuf &&
55f0: 20 28 70 2d 3e 6e 42 75 66 66 65 72 2d 69 42 75   (p->nBuffer-iBu
5600: 66 29 3e 3d 39 20 29 7b 0a 20 20 20 20 20 20 70  f)>=9 ){.      p
5610: 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 73 71  ->iReadOff += sq
5620: 6c 69 74 65 33 47 65 74 56 61 72 69 6e 74 28 26  lite3GetVarint(&
5630: 70 2d 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d  p->aBuffer[iBuf]
5640: 2c 20 70 6e 4f 75 74 29 3b 0a 20 20 20 20 7d 65  , pnOut);.    }e
5650: 6c 73 65 7b 0a 20 20 20 20 20 20 75 38 20 61 56  lse{.      u8 aV
5660: 61 72 69 6e 74 5b 31 36 5d 2c 20 2a 61 3b 0a 20  arint[16], *a;. 
5670: 20 20 20 20 20 69 6e 74 20 69 20 3d 20 30 2c 20       int i = 0, 
5680: 72 63 3b 0a 20 20 20 20 20 20 64 6f 7b 0a 20 20  rc;.      do{.  
5690: 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 50        rc = vdbeP
56a0: 6d 61 52 65 61 64 42 6c 6f 62 28 70 2c 20 31 2c  maReadBlob(p, 1,
56b0: 20 26 61 29 3b 0a 20 20 20 20 20 20 20 20 69 66   &a);.        if
56c0: 28 20 72 63 20 29 20 72 65 74 75 72 6e 20 72 63  ( rc ) return rc
56d0: 3b 0a 20 20 20 20 20 20 20 20 61 56 61 72 69 6e  ;.        aVarin
56e0: 74 5b 28 69 2b 2b 29 26 30 78 66 5d 20 3d 20 61  t[(i++)&0xf] = a
56f0: 5b 30 5d 3b 0a 20 20 20 20 20 20 7d 77 68 69 6c  [0];.      }whil
5700: 65 28 20 28 61 5b 30 5d 26 30 78 38 30 29 21 3d  e( (a[0]&0x80)!=
5710: 30 20 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  0 );.      sqlit
5720: 65 33 47 65 74 56 61 72 69 6e 74 28 61 56 61 72  e3GetVarint(aVar
5730: 69 6e 74 2c 20 70 6e 4f 75 74 29 3b 0a 20 20 20  int, pnOut);.   
5740: 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
5750: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73   SQLITE_OK;.}..s
5760: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
5770: 72 74 65 72 4d 61 70 46 69 6c 65 28 53 6f 72 74  rterMapFile(Sort
5780: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20  Subtask *pTask, 
5790: 53 6f 72 74 65 72 46 69 6c 65 20 2a 70 46 69 6c  SorterFile *pFil
57a0: 65 2c 20 75 38 20 2a 2a 70 70 29 7b 0a 20 20 69  e, u8 **pp){.  i
57b0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
57c0: 4b 3b 0a 20 20 69 66 28 20 70 46 69 6c 65 2d 3e  K;.  if( pFile->
57d0: 69 45 6f 66 3c 3d 28 69 36 34 29 28 70 54 61 73  iEof<=(i64)(pTas
57e0: 6b 2d 3e 64 62 2d 3e 6e 4d 61 78 53 6f 72 74 65  k->db->nMaxSorte
57f0: 72 4d 6d 61 70 29 20 29 7b 0a 20 20 20 20 72 63  rMmap) ){.    rc
5800: 20 3d 20 73 71 6c 69 74 65 33 4f 73 46 65 74 63   = sqlite3OsFetc
5810: 68 28 70 46 69 6c 65 2d 3e 70 46 64 2c 20 30 2c  h(pFile->pFd, 0,
5820: 20 70 46 69 6c 65 2d 3e 69 45 6f 66 2c 20 28 76   pFile->iEof, (v
5830: 6f 69 64 2a 2a 29 70 70 29 3b 0a 20 20 7d 0a 20  oid**)pp);.  }. 
5840: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
5850: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d  tatic int vdbePm
5860: 61 52 65 61 64 65 72 52 65 69 6e 69 74 28 50 6d  aReaderReinit(Pm
5870: 61 52 65 61 64 65 72 20 2a 70 49 74 65 72 29 7b  aReader *pIter){
5880: 0a 20 20 49 6e 63 72 4d 65 72 67 65 72 20 2a 70  .  IncrMerger *p
5890: 49 6e 63 72 20 3d 20 70 49 74 65 72 2d 3e 70 49  Incr = pIter->pI
58a0: 6e 63 72 3b 0a 20 20 53 6f 72 74 53 75 62 74 61  ncr;.  SortSubta
58b0: 73 6b 20 2a 70 54 61 73 6b 20 3d 20 70 49 6e 63  sk *pTask = pInc
58c0: 72 2d 3e 70 54 61 73 6b 3b 0a 20 20 69 6e 74 20  r->pTask;.  int 
58d0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
58e0: 0a 20 20 61 73 73 65 72 74 28 20 70 49 6e 63 72  .  assert( pIncr
58f0: 2d 3e 62 45 6f 66 3d 3d 30 20 29 3b 0a 0a 20 20  ->bEof==0 );..  
5900: 69 66 28 20 70 49 74 65 72 2d 3e 61 4d 61 70 20  if( pIter->aMap 
5910: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73  ){.    sqlite3Os
5920: 55 6e 66 65 74 63 68 28 70 49 74 65 72 2d 3e 70  Unfetch(pIter->p
5930: 46 69 6c 65 2c 20 30 2c 20 70 49 74 65 72 2d 3e  File, 0, pIter->
5940: 61 4d 61 70 29 3b 0a 20 20 20 20 70 49 74 65 72  aMap);.    pIter
5950: 2d 3e 61 4d 61 70 20 3d 20 30 3b 0a 20 20 7d 0a  ->aMap = 0;.  }.
5960: 20 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66    pIter->iReadOf
5970: 66 20 3d 20 70 49 6e 63 72 2d 3e 69 53 74 61 72  f = pIncr->iStar
5980: 74 4f 66 66 3b 0a 20 20 70 49 74 65 72 2d 3e 69  tOff;.  pIter->i
5990: 45 6f 66 20 3d 20 70 49 6e 63 72 2d 3e 61 46 69  Eof = pIncr->aFi
59a0: 6c 65 5b 30 5d 2e 69 45 6f 66 3b 0a 20 20 70 49  le[0].iEof;.  pI
59b0: 74 65 72 2d 3e 70 46 69 6c 65 20 3d 20 70 49 6e  ter->pFile = pIn
59c0: 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e 70 46 64  cr->aFile[0].pFd
59d0: 3b 0a 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f  ;..  rc = vdbeSo
59e0: 72 74 65 72 4d 61 70 46 69 6c 65 28 70 54 61 73  rterMapFile(pTas
59f0: 6b 2c 20 26 70 49 6e 63 72 2d 3e 61 46 69 6c 65  k, &pIncr->aFile
5a00: 5b 30 5d 2c 20 26 70 49 74 65 72 2d 3e 61 4d 61  [0], &pIter->aMa
5a10: 70 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  p);.  if( rc==SQ
5a20: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69  LITE_OK ){.    i
5a30: 66 28 20 70 49 74 65 72 2d 3e 61 4d 61 70 3d 3d  f( pIter->aMap==
5a40: 30 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 54 4f  0 ){.      /* TO
5a50: 44 4f 3a 20 43 6f 6d 62 69 6e 65 20 74 68 69 73  DO: Combine this
5a60: 20 63 6f 64 65 20 77 69 74 68 20 73 69 6d 69 6c   code with simil
5a70: 61 72 20 63 6f 64 65 20 69 6e 20 76 64 62 65 50  ar code in vdbeP
5a80: 6d 61 52 65 61 64 65 72 49 6e 69 74 28 29 20 2a  maReaderInit() *
5a90: 2f 0a 20 20 20 20 20 20 69 6e 74 20 69 42 75 66  /.      int iBuf
5aa0: 20 3d 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f   = pIter->iReadO
5ab0: 66 66 20 25 20 70 54 61 73 6b 2d 3e 70 67 73 7a  ff % pTask->pgsz
5ac0: 3b 0a 20 20 20 20 20 20 69 66 28 20 70 49 74 65  ;.      if( pIte
5ad0: 72 2d 3e 61 42 75 66 66 65 72 3d 3d 30 20 29 7b  r->aBuffer==0 ){
5ae0: 0a 20 20 20 20 20 20 20 20 70 49 74 65 72 2d 3e  .        pIter->
5af0: 61 42 75 66 66 65 72 20 3d 20 28 75 38 2a 29 73  aBuffer = (u8*)s
5b00: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 70 54 61  qlite3Malloc(pTa
5b10: 73 6b 2d 3e 70 67 73 7a 29 3b 0a 20 20 20 20 20  sk->pgsz);.     
5b20: 20 20 20 69 66 28 20 70 49 74 65 72 2d 3e 61 42     if( pIter->aB
5b30: 75 66 66 65 72 3d 3d 30 20 29 20 72 63 20 3d 20  uffer==0 ) rc = 
5b40: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
5b50: 20 20 20 20 20 20 70 49 74 65 72 2d 3e 6e 42 75        pIter->nBu
5b60: 66 66 65 72 20 3d 20 70 54 61 73 6b 2d 3e 70 67  ffer = pTask->pg
5b70: 73 7a 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  sz;.      }.    
5b80: 20 20 69 66 28 20 69 42 75 66 20 29 7b 0a 20 20    if( iBuf ){.  
5b90: 20 20 20 20 20 20 69 6e 74 20 6e 52 65 61 64 20        int nRead 
5ba0: 3d 20 70 54 61 73 6b 2d 3e 70 67 73 7a 20 2d 20  = pTask->pgsz - 
5bb0: 69 42 75 66 3b 0a 20 20 20 20 20 20 20 20 69 66  iBuf;.        if
5bc0: 28 20 28 70 49 74 65 72 2d 3e 69 52 65 61 64 4f  ( (pIter->iReadO
5bd0: 66 66 20 2b 20 6e 52 65 61 64 29 20 3e 20 70 49  ff + nRead) > pI
5be0: 74 65 72 2d 3e 69 45 6f 66 20 29 7b 0a 20 20 20  ter->iEof ){.   
5bf0: 20 20 20 20 20 20 20 6e 52 65 61 64 20 3d 20 28         nRead = (
5c00: 69 6e 74 29 28 70 49 74 65 72 2d 3e 69 45 6f 66  int)(pIter->iEof
5c10: 20 2d 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f   - pIter->iReadO
5c20: 66 66 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  ff);.        }. 
5c30: 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69         rc = sqli
5c40: 74 65 33 4f 73 52 65 61 64 28 0a 20 20 20 20 20  te3OsRead(.     
5c50: 20 20 20 20 20 20 20 70 49 74 65 72 2d 3e 70 46         pIter->pF
5c60: 69 6c 65 2c 20 26 70 49 74 65 72 2d 3e 61 42 75  ile, &pIter->aBu
5c70: 66 66 65 72 5b 69 42 75 66 5d 2c 20 6e 52 65 61  ffer[iBuf], nRea
5c80: 64 2c 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f  d, pIter->iReadO
5c90: 66 66 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 20  ff.        );.  
5ca0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 72 63        assert( rc
5cb0: 21 3d 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f 53  !=SQLITE_IOERR_S
5cc0: 48 4f 52 54 5f 52 45 41 44 20 29 3b 0a 20 20 20  HORT_READ );.   
5cd0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a     }.    }.  }..
5ce0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
5cf0: 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 69  ./*.** Advance i
5d00: 74 65 72 61 74 6f 72 20 70 49 74 65 72 20 74 6f  terator pIter to
5d10: 20 74 68 65 20 6e 65 78 74 20 6b 65 79 20 69 6e   the next key in
5d20: 20 69 74 73 20 50 4d 41 2e 20 52 65 74 75 72 6e   its PMA. Return
5d30: 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 0a 2a 2a   SQLITE_OK if.**
5d40: 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73   no error occurs
5d50: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65  , or an SQLite e
5d60: 72 72 6f 72 20 63 6f 64 65 20 69 66 20 6f 6e 65  rror code if one
5d70: 20 64 6f 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63   does..*/.static
5d80: 20 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61 64   int vdbePmaRead
5d90: 65 72 4e 65 78 74 28 50 6d 61 52 65 61 64 65 72  erNext(PmaReader
5da0: 20 2a 70 49 74 65 72 29 7b 0a 20 20 69 6e 74 20   *pIter){.  int 
5db0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20  rc = SQLITE_OK; 
5dc0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
5dd0: 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20  eturn Code */.  
5de0: 75 36 34 20 6e 52 65 63 20 3d 20 30 3b 20 20 20  u64 nRec = 0;   
5df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e00: 2f 2a 20 53 69 7a 65 20 6f 66 20 72 65 63 6f 72  /* Size of recor
5e10: 64 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 0a 20  d in bytes */.. 
5e20: 20 69 66 28 20 70 49 74 65 72 2d 3e 69 52 65 61   if( pIter->iRea
5e30: 64 4f 66 66 3e 3d 70 49 74 65 72 2d 3e 69 45 6f  dOff>=pIter->iEo
5e40: 66 20 29 7b 0a 20 20 20 20 69 6e 74 20 62 45 6f  f ){.    int bEo
5e50: 66 20 3d 20 31 3b 0a 20 20 20 20 69 66 28 20 70  f = 1;.    if( p
5e60: 49 74 65 72 2d 3e 70 49 6e 63 72 20 29 7b 0a 20  Iter->pIncr ){. 
5e70: 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e       rc = vdbeIn
5e80: 63 72 53 77 61 70 28 70 49 74 65 72 2d 3e 70 49  crSwap(pIter->pI
5e90: 6e 63 72 29 3b 0a 20 20 20 20 20 20 69 66 28 20  ncr);.      if( 
5ea0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
5eb0: 20 70 49 74 65 72 2d 3e 70 49 6e 63 72 2d 3e 62   pIter->pIncr->b
5ec0: 45 6f 66 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  Eof==0 ){.      
5ed0: 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65    rc = vdbePmaRe
5ee0: 61 64 65 72 52 65 69 6e 69 74 28 70 49 74 65 72  aderReinit(pIter
5ef0: 29 3b 0a 20 20 20 20 20 20 20 20 62 45 6f 66 20  );.        bEof 
5f00: 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  = 0;.      }.   
5f10: 20 7d 0a 0a 20 20 20 20 69 66 28 20 62 45 6f 66   }..    if( bEof
5f20: 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 54 68 69   ){.      /* Thi
5f30: 73 20 69 73 20 61 6e 20 45 4f 46 20 63 6f 6e 64  s is an EOF cond
5f40: 69 74 69 6f 6e 20 2a 2f 0a 20 20 20 20 20 20 76  ition */.      v
5f50: 64 62 65 50 6d 61 52 65 61 64 65 72 43 6c 65 61  dbePmaReaderClea
5f60: 72 28 70 49 74 65 72 29 3b 0a 20 20 20 20 20 20  r(pIter);.      
5f70: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d  return rc;.    }
5f80: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
5f90: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
5fa0: 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61   rc = vdbePmaRea
5fb0: 64 56 61 72 69 6e 74 28 70 49 74 65 72 2c 20 26  dVarint(pIter, &
5fc0: 6e 52 65 63 29 3b 0a 20 20 7d 0a 20 20 69 66 28  nRec);.  }.  if(
5fd0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
5fe0: 7b 0a 20 20 20 20 70 49 74 65 72 2d 3e 6e 4b 65  {.    pIter->nKe
5ff0: 79 20 3d 20 28 69 6e 74 29 6e 52 65 63 3b 0a 20  y = (int)nRec;. 
6000: 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52     rc = vdbePmaR
6010: 65 61 64 42 6c 6f 62 28 70 49 74 65 72 2c 20 28  eadBlob(pIter, (
6020: 69 6e 74 29 6e 52 65 63 2c 20 26 70 49 74 65 72  int)nRec, &pIter
6030: 2d 3e 61 4b 65 79 29 3b 0a 20 20 7d 0a 0a 20 20  ->aKey);.  }..  
6040: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
6050: 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 69  .** Initialize i
6060: 74 65 72 61 74 6f 72 20 70 49 74 65 72 20 74 6f  terator pIter to
6070: 20 73 63 61 6e 20 74 68 72 6f 75 67 68 20 74 68   scan through th
6080: 65 20 50 4d 41 20 73 74 6f 72 65 64 20 69 6e 20  e PMA stored in 
6090: 66 69 6c 65 20 70 46 69 6c 65 0a 2a 2a 20 73 74  file pFile.** st
60a0: 61 72 74 69 6e 67 20 61 74 20 6f 66 66 73 65 74  arting at offset
60b0: 20 69 53 74 61 72 74 20 61 6e 64 20 65 6e 64 69   iStart and endi
60c0: 6e 67 20 61 74 20 6f 66 66 73 65 74 20 69 45 6f  ng at offset iEo
60d0: 66 2d 31 2e 20 54 68 69 73 20 66 75 6e 63 74 69  f-1. This functi
60e0: 6f 6e 20 0a 2a 2a 20 6c 65 61 76 65 73 20 74 68  on .** leaves th
60f0: 65 20 69 74 65 72 61 74 6f 72 20 70 6f 69 6e 74  e iterator point
6100: 69 6e 67 20 74 6f 20 74 68 65 20 66 69 72 73 74  ing to the first
6110: 20 6b 65 79 20 69 6e 20 74 68 65 20 50 4d 41 20   key in the PMA 
6120: 28 6f 72 20 45 4f 46 20 69 66 20 74 68 65 20 0a  (or EOF if the .
6130: 2a 2a 20 50 4d 41 20 69 73 20 65 6d 70 74 79 29  ** PMA is empty)
6140: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 70  ..**.** If the p
6150: 6e 42 79 74 65 20 70 61 72 61 6d 65 74 65 72 20  nByte parameter 
6160: 69 73 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 69 74  is NULL, then it
6170: 20 69 73 20 61 73 73 75 6d 65 64 20 74 68 61 74   is assumed that
6180: 20 74 68 65 20 66 69 6c 65 20 0a 2a 2a 20 63 6f   the file .** co
6190: 6e 74 61 69 6e 73 20 61 20 73 69 6e 67 6c 65 20  ntains a single 
61a0: 50 4d 41 2c 20 61 6e 64 20 74 68 61 74 20 74 68  PMA, and that th
61b0: 61 74 20 50 4d 41 20 6f 6d 69 74 73 20 74 68 65  at PMA omits the
61c0: 20 69 6e 69 74 69 61 6c 20 6c 65 6e 67 74 68 20   initial length 
61d0: 76 61 72 69 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69  varint..*/.stati
61e0: 63 20 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61  c int vdbePmaRea
61f0: 64 65 72 49 6e 69 74 28 0a 20 20 53 6f 72 74 53  derInit(.  SortS
6200: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20  ubtask *pTask,  
6210: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61             /* Ta
6220: 73 6b 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20  sk context */.  
6230: 53 6f 72 74 65 72 46 69 6c 65 20 2a 70 46 69 6c  SorterFile *pFil
6240: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
6250: 2f 2a 20 53 6f 72 74 65 72 20 66 69 6c 65 20 74  /* Sorter file t
6260: 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20  o read from */. 
6270: 20 69 36 34 20 69 53 74 61 72 74 2c 20 20 20 20   i64 iStart,    
6280: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6290: 20 2f 2a 20 53 74 61 72 74 20 6f 66 66 73 65 74   /* Start offset
62a0: 20 69 6e 20 70 46 69 6c 65 20 2a 2f 0a 20 20 50   in pFile */.  P
62b0: 6d 61 52 65 61 64 65 72 20 2a 70 49 74 65 72 2c  maReader *pIter,
62c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
62d0: 2a 20 49 74 65 72 61 74 6f 72 20 74 6f 20 70 6f  * Iterator to po
62e0: 70 75 6c 61 74 65 20 2a 2f 0a 20 20 69 36 34 20  pulate */.  i64 
62f0: 2a 70 6e 42 79 74 65 20 20 20 20 20 20 20 20 20  *pnByte         
6300: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
6310: 4e 2f 4f 55 54 3a 20 49 6e 63 72 65 6d 65 6e 74  N/OUT: Increment
6320: 20 74 68 69 73 20 76 61 6c 75 65 20 62 79 20 50   this value by P
6330: 4d 41 20 73 69 7a 65 20 2a 2f 0a 29 7b 0a 20 20  MA size */.){.  
6340: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
6350: 4f 4b 3b 0a 20 20 69 6e 74 20 6e 42 75 66 20 3d  OK;.  int nBuf =
6360: 20 70 54 61 73 6b 2d 3e 70 67 73 7a 3b 0a 0a 20   pTask->pgsz;.. 
6370: 20 61 73 73 65 72 74 28 20 70 46 69 6c 65 2d 3e   assert( pFile->
6380: 69 45 6f 66 3e 69 53 74 61 72 74 20 29 3b 0a 20  iEof>iStart );. 
6390: 20 61 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e   assert( pIter->
63a0: 61 41 6c 6c 6f 63 3d 3d 30 20 29 3b 0a 20 20 61  aAlloc==0 );.  a
63b0: 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e 61 42  ssert( pIter->aB
63c0: 75 66 66 65 72 3d 3d 30 20 29 3b 0a 20 20 70 49  uffer==0 );.  pI
63d0: 74 65 72 2d 3e 70 46 69 6c 65 20 3d 20 70 46 69  ter->pFile = pFi
63e0: 6c 65 2d 3e 70 46 64 3b 0a 20 20 70 49 74 65 72  le->pFd;.  pIter
63f0: 2d 3e 69 52 65 61 64 4f 66 66 20 3d 20 69 53 74  ->iReadOff = iSt
6400: 61 72 74 3b 0a 20 20 70 49 74 65 72 2d 3e 6e 41  art;.  pIter->nA
6410: 6c 6c 6f 63 20 3d 20 31 32 38 3b 0a 20 20 70 49  lloc = 128;.  pI
6420: 74 65 72 2d 3e 61 41 6c 6c 6f 63 20 3d 20 28 75  ter->aAlloc = (u
6430: 38 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  8*)sqlite3Malloc
6440: 28 70 49 74 65 72 2d 3e 6e 41 6c 6c 6f 63 29 3b  (pIter->nAlloc);
6450: 0a 20 20 69 66 28 20 70 49 74 65 72 2d 3e 61 41  .  if( pIter->aA
6460: 6c 6c 6f 63 20 29 7b 0a 20 20 20 20 2f 2a 20 54  lloc ){.    /* T
6470: 72 79 20 74 6f 20 78 46 65 74 63 68 28 29 20 61  ry to xFetch() a
6480: 20 6d 61 70 70 69 6e 67 20 6f 66 20 74 68 65 20   mapping of the 
6490: 65 6e 74 69 72 65 20 74 65 6d 70 20 66 69 6c 65  entire temp file
64a0: 2e 20 49 66 20 74 68 69 73 20 69 73 20 70 6f 73  . If this is pos
64b0: 73 69 62 6c 65 2c 0a 20 20 20 20 2a 2a 20 74 68  sible,.    ** th
64c0: 65 20 50 4d 41 20 77 69 6c 6c 20 62 65 20 72 65  e PMA will be re
64d0: 61 64 20 76 69 61 20 74 68 65 20 6d 61 70 70 69  ad via the mappi
64e0: 6e 67 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 75  ng. Otherwise, u
64f0: 73 65 20 78 52 65 61 64 28 29 2e 20 20 2a 2f 0a  se xRead().  */.
6500: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
6510: 74 65 72 4d 61 70 46 69 6c 65 28 70 54 61 73 6b  terMapFile(pTask
6520: 2c 20 70 46 69 6c 65 2c 20 26 70 49 74 65 72 2d  , pFile, &pIter-
6530: 3e 61 4d 61 70 29 3b 0a 20 20 7d 65 6c 73 65 7b  >aMap);.  }else{
6540: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
6550: 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20 69  _NOMEM;.  }..  i
6560: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
6570: 20 26 26 20 70 49 74 65 72 2d 3e 61 4d 61 70 3d   && pIter->aMap=
6580: 3d 30 20 29 7b 0a 20 20 20 20 70 49 74 65 72 2d  =0 ){.    pIter-
6590: 3e 6e 42 75 66 66 65 72 20 3d 20 6e 42 75 66 3b  >nBuffer = nBuf;
65a0: 0a 20 20 20 20 70 49 74 65 72 2d 3e 61 42 75 66  .    pIter->aBuf
65b0: 66 65 72 20 3d 20 28 75 38 2a 29 73 71 6c 69 74  fer = (u8*)sqlit
65c0: 65 33 4d 61 6c 6c 6f 63 28 6e 42 75 66 29 3b 0a  e3Malloc(nBuf);.
65d0: 20 20 20 20 69 66 28 20 21 70 49 74 65 72 2d 3e      if( !pIter->
65e0: 61 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20 20  aBuffer ){.     
65f0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
6600: 45 4d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  EM;.    }else{. 
6610: 20 20 20 20 20 69 6e 74 20 69 42 75 66 20 3d 20       int iBuf = 
6620: 69 53 74 61 72 74 20 25 20 6e 42 75 66 3b 0a 20  iStart % nBuf;. 
6630: 20 20 20 20 20 69 66 28 20 69 42 75 66 20 29 7b       if( iBuf ){
6640: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 52 65  .        int nRe
6650: 61 64 20 3d 20 6e 42 75 66 20 2d 20 69 42 75 66  ad = nBuf - iBuf
6660: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 28 69  ;.        if( (i
6670: 53 74 61 72 74 20 2b 20 6e 52 65 61 64 29 20 3e  Start + nRead) >
6680: 20 70 46 69 6c 65 2d 3e 69 45 6f 66 20 29 7b 0a   pFile->iEof ){.
6690: 20 20 20 20 20 20 20 20 20 20 6e 52 65 61 64 20            nRead 
66a0: 3d 20 28 69 6e 74 29 28 70 46 69 6c 65 2d 3e 69  = (int)(pFile->i
66b0: 45 6f 66 20 2d 20 69 53 74 61 72 74 29 3b 0a 20  Eof - iStart);. 
66c0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
66d0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52   rc = sqlite3OsR
66e0: 65 61 64 28 0a 20 20 20 20 20 20 20 20 20 20 20  ead(.           
66f0: 20 70 49 74 65 72 2d 3e 70 46 69 6c 65 2c 20 26   pIter->pFile, &
6700: 70 49 74 65 72 2d 3e 61 42 75 66 66 65 72 5b 69  pIter->aBuffer[i
6710: 42 75 66 5d 2c 20 6e 52 65 61 64 2c 20 69 53 74  Buf], nRead, iSt
6720: 61 72 74 0a 20 20 20 20 20 20 20 20 29 3b 0a 20  art.        );. 
6730: 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20 72         assert( r
6740: 63 21 3d 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f  c!=SQLITE_IOERR_
6750: 53 48 4f 52 54 5f 52 45 41 44 20 29 3b 0a 20 20  SHORT_READ );.  
6760: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
6770: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
6780: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 75 36 34 20  E_OK ){.    u64 
6790: 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20 20 20  nByte;          
67a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
67b0: 65 20 6f 66 20 50 4d 41 20 69 6e 20 62 79 74 65  e of PMA in byte
67c0: 73 20 2a 2f 0a 20 20 20 20 70 49 74 65 72 2d 3e  s */.    pIter->
67d0: 69 45 6f 66 20 3d 20 70 46 69 6c 65 2d 3e 69 45  iEof = pFile->iE
67e0: 6f 66 3b 0a 20 20 20 20 72 63 20 3d 20 76 64 62  of;.    rc = vdb
67f0: 65 50 6d 61 52 65 61 64 56 61 72 69 6e 74 28 70  ePmaReadVarint(p
6800: 49 74 65 72 2c 20 26 6e 42 79 74 65 29 3b 0a 20  Iter, &nByte);. 
6810: 20 20 20 70 49 74 65 72 2d 3e 69 45 6f 66 20 3d     pIter->iEof =
6820: 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66 66   pIter->iReadOff
6830: 20 2b 20 6e 42 79 74 65 3b 0a 20 20 20 20 2a 70   + nByte;.    *p
6840: 6e 42 79 74 65 20 2b 3d 20 6e 42 79 74 65 3b 0a  nByte += nByte;.
6850: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53    }..  if( rc==S
6860: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
6870: 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64  rc = vdbePmaRead
6880: 65 72 4e 65 78 74 28 70 49 74 65 72 29 3b 0a 20  erNext(pIter);. 
6890: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
68a0: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 61 72  }.../*.** Compar
68b0: 65 20 6b 65 79 31 20 28 62 75 66 66 65 72 20 70  e key1 (buffer p
68c0: 4b 65 79 31 2c 20 73 69 7a 65 20 6e 4b 65 79 31  Key1, size nKey1
68d0: 20 62 79 74 65 73 29 20 77 69 74 68 20 6b 65 79   bytes) with key
68e0: 32 20 28 62 75 66 66 65 72 20 70 4b 65 79 32 2c  2 (buffer pKey2,
68f0: 20 0a 2a 2a 20 73 69 7a 65 20 6e 4b 65 79 32 20   .** size nKey2 
6900: 62 79 74 65 73 29 2e 20 55 73 65 20 28 70 54 61  bytes). Use (pTa
6910: 73 6b 2d 3e 70 4b 65 79 49 6e 66 6f 29 20 66 6f  sk->pKeyInfo) fo
6920: 72 20 74 68 65 20 63 6f 6c 6c 61 74 69 6f 6e 20  r the collation 
6930: 73 65 71 75 65 6e 63 65 73 0a 2a 2a 20 75 73 65  sequences.** use
6940: 64 20 62 79 20 74 68 65 20 63 6f 6d 70 61 72 69  d by the compari
6950: 73 6f 6e 2e 20 52 65 74 75 72 6e 20 74 68 65 20  son. Return the 
6960: 72 65 73 75 6c 74 20 6f 66 20 74 68 65 20 63 6f  result of the co
6970: 6d 70 61 72 69 73 6f 6e 2e 0a 2a 2a 0a 2a 2a 20  mparison..**.** 
6980: 42 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  Before returning
6990: 2c 20 6f 62 6a 65 63 74 20 28 70 54 61 73 6b 2d  , object (pTask-
69a0: 3e 70 55 6e 70 61 63 6b 65 64 29 20 69 73 20 70  >pUnpacked) is p
69b0: 6f 70 75 6c 61 74 65 64 20 77 69 74 68 20 74 68  opulated with th
69c0: 65 0a 2a 2a 20 75 6e 70 61 63 6b 65 64 20 76 65  e.** unpacked ve
69d0: 72 73 69 6f 6e 20 6f 66 20 6b 65 79 32 2e 20 4f  rsion of key2. O
69e0: 72 2c 20 69 66 20 70 4b 65 79 32 20 69 73 20 70  r, if pKey2 is p
69f0: 61 73 73 65 64 20 61 20 4e 55 4c 4c 20 70 6f 69  assed a NULL poi
6a00: 6e 74 65 72 2c 20 74 68 65 6e 20 69 74 20 0a 2a  nter, then it .*
6a10: 2a 20 69 73 20 61 73 73 75 6d 65 64 20 74 68 61  * is assumed tha
6a20: 74 20 74 68 65 20 28 70 54 61 73 6b 2d 3e 70 55  t the (pTask->pU
6a30: 6e 70 61 63 6b 65 64 29 20 73 74 72 75 63 74 75  npacked) structu
6a40: 72 65 20 61 6c 72 65 61 64 79 20 63 6f 6e 74 61  re already conta
6a50: 69 6e 73 20 74 68 65 20 0a 2a 2a 20 75 6e 70 61  ins the .** unpa
6a60: 63 6b 65 64 20 6b 65 79 20 74 6f 20 75 73 65 20  cked key to use 
6a70: 61 73 20 6b 65 79 32 2e 0a 2a 2a 0a 2a 2a 20 49  as key2..**.** I
6a80: 66 20 61 6e 20 4f 4f 4d 20 65 72 72 6f 72 20 69  f an OOM error i
6a90: 73 20 65 6e 63 6f 75 6e 74 65 72 65 64 2c 20 28  s encountered, (
6aa0: 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64  pTask->pUnpacked
6ab0: 2d 3e 65 72 72 6f 72 5f 72 63 29 20 69 73 20 73  ->error_rc) is s
6ac0: 65 74 0a 2a 2a 20 74 6f 20 53 51 4c 49 54 45 5f  et.** to SQLITE_
6ad0: 4e 4f 4d 45 4d 2e 0a 2a 2f 0a 73 74 61 74 69 63  NOMEM..*/.static
6ae0: 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72 43   int vdbeSorterC
6af0: 6f 6d 70 61 72 65 28 0a 20 20 53 6f 72 74 53 75  ompare(.  SortSu
6b00: 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20  btask *pTask,   
6b10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 75 62            /* Sub
6b20: 74 61 73 6b 20 63 6f 6e 74 65 78 74 20 28 66 6f  task context (fo
6b30: 72 20 70 4b 65 79 49 6e 66 6f 29 20 2a 2f 0a 20  r pKeyInfo) */. 
6b40: 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 4b 65   const void *pKe
6b50: 79 31 2c 20 69 6e 74 20 6e 4b 65 79 31 2c 20 20  y1, int nKey1,  
6b60: 20 2f 2a 20 4c 65 66 74 20 73 69 64 65 20 6f 66   /* Left side of
6b70: 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f 0a 20   comparison */. 
6b80: 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 4b 65   const void *pKe
6b90: 79 32 2c 20 69 6e 74 20 6e 4b 65 79 32 20 20 20  y2, int nKey2   
6ba0: 20 2f 2a 20 52 69 67 68 74 20 73 69 64 65 20 6f   /* Right side o
6bb0: 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f 0a  f comparison */.
6bc0: 29 7b 0a 20 20 55 6e 70 61 63 6b 65 64 52 65 63  ){.  UnpackedRec
6bd0: 6f 72 64 20 2a 72 32 20 3d 20 70 54 61 73 6b 2d  ord *r2 = pTask-
6be0: 3e 70 55 6e 70 61 63 6b 65 64 3b 0a 20 20 69 66  >pUnpacked;.  if
6bf0: 28 20 70 4b 65 79 32 20 29 7b 0a 20 20 20 20 73  ( pKey2 ){.    s
6c00: 71 6c 69 74 65 33 56 64 62 65 52 65 63 6f 72 64  qlite3VdbeRecord
6c10: 55 6e 70 61 63 6b 28 70 54 61 73 6b 2d 3e 70 4b  Unpack(pTask->pK
6c20: 65 79 49 6e 66 6f 2c 20 6e 4b 65 79 32 2c 20 70  eyInfo, nKey2, p
6c30: 4b 65 79 32 2c 20 72 32 29 3b 0a 20 20 7d 0a 20  Key2, r2);.  }. 
6c40: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 56   return sqlite3V
6c50: 64 62 65 52 65 63 6f 72 64 43 6f 6d 70 61 72 65  dbeRecordCompare
6c60: 28 6e 4b 65 79 31 2c 20 70 4b 65 79 31 2c 20 72  (nKey1, pKey1, r
6c70: 32 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  2, 0);.}../*.** 
6c80: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
6c90: 20 63 61 6c 6c 65 64 20 74 6f 20 63 6f 6d 70 61   called to compa
6ca0: 72 65 20 74 77 6f 20 69 74 65 72 61 74 6f 72 20  re two iterator 
6cb0: 6b 65 79 73 20 77 68 65 6e 20 6d 65 72 67 69 6e  keys when mergin
6cc0: 67 20 0a 2a 2a 20 6d 75 6c 74 69 70 6c 65 20 62  g .** multiple b
6cd0: 2d 74 72 65 65 20 73 65 67 6d 65 6e 74 73 2e 20  -tree segments. 
6ce0: 50 61 72 61 6d 65 74 65 72 20 69 4f 75 74 20 69  Parameter iOut i
6cf0: 73 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20 74  s the index of t
6d00: 68 65 20 61 54 72 65 65 5b 5d 20 0a 2a 2a 20 76  he aTree[] .** v
6d10: 61 6c 75 65 20 74 6f 20 72 65 63 61 6c 63 75 6c  alue to recalcul
6d20: 61 74 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ate..*/.static i
6d30: 6e 74 20 76 64 62 65 53 6f 72 74 65 72 44 6f 43  nt vdbeSorterDoC
6d40: 6f 6d 70 61 72 65 28 0a 20 20 53 6f 72 74 53 75  ompare(.  SortSu
6d50: 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 0a 20  btask *pTask, . 
6d60: 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d   MergeEngine *pM
6d70: 65 72 67 65 72 2c 20 0a 20 20 69 6e 74 20 69 4f  erger, .  int iO
6d80: 75 74 0a 29 7b 0a 20 20 69 6e 74 20 69 31 3b 0a  ut.){.  int i1;.
6d90: 20 20 69 6e 74 20 69 32 3b 0a 20 20 69 6e 74 20    int i2;.  int 
6da0: 69 52 65 73 3b 0a 20 20 50 6d 61 52 65 61 64 65  iRes;.  PmaReade
6db0: 72 20 2a 70 31 3b 0a 20 20 50 6d 61 52 65 61 64  r *p1;.  PmaRead
6dc0: 65 72 20 2a 70 32 3b 0a 0a 20 20 61 73 73 65 72  er *p2;..  asser
6dd0: 74 28 20 69 4f 75 74 3c 70 4d 65 72 67 65 72 2d  t( iOut<pMerger-
6de0: 3e 6e 54 72 65 65 20 26 26 20 69 4f 75 74 3e 30  >nTree && iOut>0
6df0: 20 29 3b 0a 0a 20 20 69 66 28 20 69 4f 75 74 3e   );..  if( iOut>
6e00: 3d 28 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65  =(pMerger->nTree
6e10: 2f 32 29 20 29 7b 0a 20 20 20 20 69 31 20 3d 20  /2) ){.    i1 = 
6e20: 28 69 4f 75 74 20 2d 20 70 4d 65 72 67 65 72 2d  (iOut - pMerger-
6e30: 3e 6e 54 72 65 65 2f 32 29 20 2a 20 32 3b 0a 20  >nTree/2) * 2;. 
6e40: 20 20 20 69 32 20 3d 20 69 31 20 2b 20 31 3b 0a     i2 = i1 + 1;.
6e50: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 31 20    }else{.    i1 
6e60: 3d 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65  = pMerger->aTree
6e70: 5b 69 4f 75 74 2a 32 5d 3b 0a 20 20 20 20 69 32  [iOut*2];.    i2
6e80: 20 3d 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65   = pMerger->aTre
6e90: 65 5b 69 4f 75 74 2a 32 2b 31 5d 3b 0a 20 20 7d  e[iOut*2+1];.  }
6ea0: 0a 0a 20 20 70 31 20 3d 20 26 70 4d 65 72 67 65  ..  p1 = &pMerge
6eb0: 72 2d 3e 61 49 74 65 72 5b 69 31 5d 3b 0a 20 20  r->aIter[i1];.  
6ec0: 70 32 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61  p2 = &pMerger->a
6ed0: 49 74 65 72 5b 69 32 5d 3b 0a 0a 20 20 69 66 28  Iter[i2];..  if(
6ee0: 20 70 31 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b   p1->pFile==0 ){
6ef0: 0a 20 20 20 20 69 52 65 73 20 3d 20 69 32 3b 0a  .    iRes = i2;.
6f00: 20 20 7d 65 6c 73 65 20 69 66 28 20 70 32 2d 3e    }else if( p2->
6f10: 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20  pFile==0 ){.    
6f20: 69 52 65 73 20 3d 20 69 31 3b 0a 20 20 7d 65 6c  iRes = i1;.  }el
6f30: 73 65 7b 0a 20 20 20 20 69 6e 74 20 72 65 73 3b  se{.    int res;
6f40: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 54 61  .    assert( pTa
6f50: 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 21 3d 30  sk->pUnpacked!=0
6f60: 20 29 3b 20 20 2f 2a 20 61 6c 6c 6f 63 61 74 65   );  /* allocate
6f70: 64 20 69 6e 20 76 64 62 65 53 6f 72 74 53 75 62  d in vdbeSortSub
6f80: 74 61 73 6b 4d 61 69 6e 28 29 20 2a 2f 0a 20 20  taskMain() */.  
6f90: 20 20 72 65 73 20 3d 20 76 64 62 65 53 6f 72 74    res = vdbeSort
6fa0: 65 72 43 6f 6d 70 61 72 65 28 0a 20 20 20 20 20  erCompare(.     
6fb0: 20 20 20 70 54 61 73 6b 2c 20 70 31 2d 3e 61 4b     pTask, p1->aK
6fc0: 65 79 2c 20 70 31 2d 3e 6e 4b 65 79 2c 20 70 32  ey, p1->nKey, p2
6fd0: 2d 3e 61 4b 65 79 2c 20 70 32 2d 3e 6e 4b 65 79  ->aKey, p2->nKey
6fe0: 0a 20 20 20 20 29 3b 0a 20 20 20 20 69 66 28 20  .    );.    if( 
6ff0: 72 65 73 3c 3d 30 20 29 7b 0a 20 20 20 20 20 20  res<=0 ){.      
7000: 69 52 65 73 20 3d 20 69 31 3b 0a 20 20 20 20 7d  iRes = i1;.    }
7010: 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 52 65 73  else{.      iRes
7020: 20 3d 20 69 32 3b 0a 20 20 20 20 7d 0a 20 20 7d   = i2;.    }.  }
7030: 0a 0a 20 20 70 4d 65 72 67 65 72 2d 3e 61 54 72  ..  pMerger->aTr
7040: 65 65 5b 69 4f 75 74 5d 20 3d 20 69 52 65 73 3b  ee[iOut] = iRes;
7050: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
7060: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e  _OK;.}../*.** In
7070: 69 74 69 61 6c 69 7a 65 20 74 68 65 20 74 65 6d  itialize the tem
7080: 70 6f 72 61 72 79 20 69 6e 64 65 78 20 63 75 72  porary index cur
7090: 73 6f 72 20 6a 75 73 74 20 6f 70 65 6e 65 64 20  sor just opened 
70a0: 61 73 20 61 20 73 6f 72 74 65 72 20 63 75 72 73  as a sorter curs
70b0: 6f 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  or..*/.int sqlit
70c0: 65 33 56 64 62 65 53 6f 72 74 65 72 49 6e 69 74  e3VdbeSorterInit
70d0: 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
70e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
70f0: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
7100: 63 6f 6e 6e 65 63 74 69 6f 6e 20 28 66 6f 72 20  connection (for 
7110: 6d 61 6c 6c 6f 63 28 29 29 20 2a 2f 0a 20 20 69  malloc()) */.  i
7120: 6e 74 20 6e 46 69 65 6c 64 2c 20 20 20 20 20 20  nt nField,      
7130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7140: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 6b 65 79 20  * Number of key 
7150: 66 69 65 6c 64 73 20 69 6e 20 65 61 63 68 20 72  fields in each r
7160: 65 63 6f 72 64 20 2a 2f 0a 20 20 56 64 62 65 43  ecord */.  VdbeC
7170: 75 72 73 6f 72 20 2a 70 43 73 72 20 20 20 20 20  ursor *pCsr     
7180: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
7190: 72 73 6f 72 20 74 68 61 74 20 68 6f 6c 64 73 20  rsor that holds 
71a0: 74 68 65 20 6e 65 77 20 73 6f 72 74 65 72 20 2a  the new sorter *
71b0: 2f 0a 29 7b 0a 20 20 69 6e 74 20 70 67 73 7a 3b  /.){.  int pgsz;
71c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
71d0: 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 73         /* Page s
71e0: 69 7a 65 20 6f 66 20 6d 61 69 6e 20 64 61 74 61  ize of main data
71f0: 62 61 73 65 20 2a 2f 0a 20 20 69 6e 74 20 69 3b  base */.  int i;
7200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7210: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65            /* Use
7220: 64 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72  d to iterate thr
7230: 6f 75 67 68 20 61 54 61 73 6b 5b 5d 20 2a 2f 0a  ough aTask[] */.
7240: 20 20 69 6e 74 20 6d 78 43 61 63 68 65 3b 20 20    int mxCache;  
7250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7260: 20 20 2f 2a 20 43 61 63 68 65 20 73 69 7a 65 20    /* Cache size 
7270: 2a 2f 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20  */.  VdbeSorter 
7280: 2a 70 53 6f 72 74 65 72 3b 20 20 20 20 20 20 20  *pSorter;       
7290: 20 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77 20       /* The new 
72a0: 73 6f 72 74 65 72 20 2a 2f 0a 20 20 4b 65 79 49  sorter */.  KeyI
72b0: 6e 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 3b 20 20  nfo *pKeyInfo;  
72c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
72d0: 6f 70 79 20 6f 66 20 70 43 73 72 2d 3e 70 4b 65  opy of pCsr->pKe
72e0: 79 49 6e 66 6f 20 77 69 74 68 20 64 62 3d 3d 30  yInfo with db==0
72f0: 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 4b 65 79 49   */.  int szKeyI
7300: 6e 66 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20  nfo;            
7310: 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
7320: 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 20   pCsr->pKeyInfo 
7330: 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e  in bytes */.  in
7340: 74 20 73 7a 3b 20 20 20 20 20 20 20 20 20 20 20  t sz;           
7350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7360: 20 53 69 7a 65 20 6f 66 20 70 53 6f 72 74 65 72   Size of pSorter
7370: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69   in bytes */.  i
7380: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
7390: 4b 3b 0a 20 20 69 6e 74 20 6e 57 6f 72 6b 65 72  K;.  int nWorker
73a0: 20 3d 20 28 73 71 6c 69 74 65 33 47 6c 6f 62 61   = (sqlite3Globa
73b0: 6c 43 6f 6e 66 69 67 2e 62 43 6f 72 65 4d 75 74  lConfig.bCoreMut
73c0: 65 78 3f 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c  ex?sqlite3Global
73d0: 43 6f 6e 66 69 67 2e 6e 57 6f 72 6b 65 72 3a 30  Config.nWorker:0
73e0: 29 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 43  );..  assert( pC
73f0: 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 20 26 26 20  sr->pKeyInfo && 
7400: 70 43 73 72 2d 3e 70 42 74 3d 3d 30 20 29 3b 0a  pCsr->pBt==0 );.
7410: 20 20 73 7a 4b 65 79 49 6e 66 6f 20 3d 20 73 69    szKeyInfo = si
7420: 7a 65 6f 66 28 4b 65 79 49 6e 66 6f 29 20 2b 20  zeof(KeyInfo) + 
7430: 28 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2d  (pCsr->pKeyInfo-
7440: 3e 6e 46 69 65 6c 64 2d 31 29 2a 73 69 7a 65 6f  >nField-1)*sizeo
7450: 66 28 43 6f 6c 6c 53 65 71 2a 29 3b 0a 20 20 73  f(CollSeq*);.  s
7460: 7a 20 3d 20 73 69 7a 65 6f 66 28 56 64 62 65 53  z = sizeof(VdbeS
7470: 6f 72 74 65 72 29 20 2b 20 6e 57 6f 72 6b 65 72  orter) + nWorker
7480: 20 2a 20 73 69 7a 65 6f 66 28 53 6f 72 74 53 75   * sizeof(SortSu
7490: 62 74 61 73 6b 29 3b 0a 0a 20 20 70 53 6f 72 74  btask);..  pSort
74a0: 65 72 20 3d 20 28 56 64 62 65 53 6f 72 74 65 72  er = (VdbeSorter
74b0: 2a 29 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f  *)sqlite3DbMallo
74c0: 63 5a 65 72 6f 28 64 62 2c 20 73 7a 20 2b 20 73  cZero(db, sz + s
74d0: 7a 4b 65 79 49 6e 66 6f 29 3b 0a 20 20 70 43 73  zKeyInfo);.  pCs
74e0: 72 2d 3e 70 53 6f 72 74 65 72 20 3d 20 70 53 6f  r->pSorter = pSo
74f0: 72 74 65 72 3b 0a 20 20 69 66 28 20 70 53 6f 72  rter;.  if( pSor
7500: 74 65 72 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63  ter==0 ){.    rc
7510: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
7520: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 4b  .  }else{.    pK
7530: 65 79 49 6e 66 6f 20 3d 20 28 4b 65 79 49 6e 66  eyInfo = (KeyInf
7540: 6f 2a 29 28 28 75 38 2a 29 70 53 6f 72 74 65 72  o*)((u8*)pSorter
7550: 20 2b 20 73 7a 29 3b 0a 20 20 20 20 6d 65 6d 63   + sz);.    memc
7560: 70 79 28 70 4b 65 79 49 6e 66 6f 2c 20 70 43 73  py(pKeyInfo, pCs
7570: 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20 73 7a 4b  r->pKeyInfo, szK
7580: 65 79 49 6e 66 6f 29 3b 0a 20 20 20 20 70 4b 65  eyInfo);.    pKe
7590: 79 49 6e 66 6f 2d 3e 64 62 20 3d 20 30 3b 0a 20  yInfo->db = 0;. 
75a0: 20 20 20 69 66 28 20 6e 46 69 65 6c 64 20 26 26     if( nField &&
75b0: 20 6e 57 6f 72 6b 65 72 3d 3d 30 20 29 20 70 4b   nWorker==0 ) pK
75c0: 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64 20 3d  eyInfo->nField =
75d0: 20 6e 46 69 65 6c 64 3b 0a 20 20 20 20 70 67 73   nField;.    pgs
75e0: 7a 20 3d 20 73 71 6c 69 74 65 33 42 74 72 65 65  z = sqlite3Btree
75f0: 47 65 74 50 61 67 65 53 69 7a 65 28 64 62 2d 3e  GetPageSize(db->
7600: 61 44 62 5b 30 5d 2e 70 42 74 29 3b 0a 0a 20 20  aDb[0].pBt);..  
7610: 20 20 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b    pSorter->nTask
7620: 20 3d 20 6e 57 6f 72 6b 65 72 20 2b 20 31 3b 0a   = nWorker + 1;.
7630: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 62 55 73      pSorter->bUs
7640: 65 54 68 72 65 61 64 73 20 3d 20 28 70 53 6f 72  eThreads = (pSor
7650: 74 65 72 2d 3e 6e 54 61 73 6b 3e 31 29 3b 0a 20  ter->nTask>1);. 
7660: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 53     for(i=0; i<pS
7670: 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3b 20 69 2b  orter->nTask; i+
7680: 2b 29 7b 0a 20 20 20 20 20 20 53 6f 72 74 53 75  +){.      SortSu
7690: 62 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20 26  btask *pTask = &
76a0: 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 69  pSorter->aTask[i
76b0: 5d 3b 0a 20 20 20 20 20 20 70 54 61 73 6b 2d 3e  ];.      pTask->
76c0: 70 4b 65 79 49 6e 66 6f 20 3d 20 70 4b 65 79 49  pKeyInfo = pKeyI
76d0: 6e 66 6f 3b 0a 20 20 20 20 20 20 70 54 61 73 6b  nfo;.      pTask
76e0: 2d 3e 70 67 73 7a 20 3d 20 70 67 73 7a 3b 0a 20  ->pgsz = pgsz;. 
76f0: 20 20 20 20 20 70 54 61 73 6b 2d 3e 64 62 20 3d       pTask->db =
7700: 20 64 62 3b 0a 20 20 20 20 20 20 70 54 61 73 6b   db;.      pTask
7710: 2d 3e 70 53 6f 72 74 65 72 20 3d 20 70 53 6f 72  ->pSorter = pSor
7720: 74 65 72 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  ter;.    }..    
7730: 69 66 28 20 21 73 71 6c 69 74 65 33 54 65 6d 70  if( !sqlite3Temp
7740: 49 6e 4d 65 6d 6f 72 79 28 64 62 29 20 29 7b 0a  InMemory(db) ){.
7750: 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6d        pSorter->m
7760: 6e 50 6d 61 53 69 7a 65 20 3d 20 53 4f 52 54 45  nPmaSize = SORTE
7770: 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20 2a 20  R_MIN_WORKING * 
7780: 70 67 73 7a 3b 0a 20 20 20 20 20 20 6d 78 43 61  pgsz;.      mxCa
7790: 63 68 65 20 3d 20 64 62 2d 3e 61 44 62 5b 30 5d  che = db->aDb[0]
77a0: 2e 70 53 63 68 65 6d 61 2d 3e 63 61 63 68 65 5f  .pSchema->cache_
77b0: 73 69 7a 65 3b 0a 20 20 20 20 20 20 69 66 28 20  size;.      if( 
77c0: 6d 78 43 61 63 68 65 3c 53 4f 52 54 45 52 5f 4d  mxCache<SORTER_M
77d0: 49 4e 5f 57 4f 52 4b 49 4e 47 20 29 20 6d 78 43  IN_WORKING ) mxC
77e0: 61 63 68 65 20 3d 20 53 4f 52 54 45 52 5f 4d 49  ache = SORTER_MI
77f0: 4e 5f 57 4f 52 4b 49 4e 47 3b 0a 20 20 20 20 20  N_WORKING;.     
7800: 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53   pSorter->mxPmaS
7810: 69 7a 65 20 3d 20 6d 78 43 61 63 68 65 20 2a 20  ize = mxCache * 
7820: 70 67 73 7a 3b 0a 0a 20 20 20 20 20 20 2f 2a 20  pgsz;..      /* 
7830: 49 66 20 74 68 65 20 61 70 70 6c 69 63 61 74 69  If the applicati
7840: 6f 6e 20 69 73 20 75 73 69 6e 67 20 6d 65 6d 73  on is using mems
7850: 79 73 33 20 6f 72 20 6d 65 6d 73 79 73 35 2c 20  ys3 or memsys5, 
7860: 75 73 65 20 61 20 73 65 70 61 72 61 74 65 20 0a  use a separate .
7870: 20 20 20 20 20 20 2a 2a 20 61 6c 6c 6f 63 61 74        ** allocat
7880: 69 6f 6e 20 66 6f 72 20 65 61 63 68 20 73 6f 72  ion for each sor
7890: 74 2d 6b 65 79 20 69 6e 20 6d 65 6d 6f 72 79 2e  t-key in memory.
78a0: 20 4f 74 68 65 72 77 69 73 65 2c 20 75 73 65 20   Otherwise, use 
78b0: 61 20 73 69 6e 67 6c 65 20 62 69 67 0a 20 20 20  a single big.   
78c0: 20 20 20 2a 2a 20 61 6c 6c 6f 63 61 74 69 6f 6e     ** allocation
78d0: 20 61 74 20 70 53 6f 72 74 65 72 2d 3e 61 4d 65   at pSorter->aMe
78e0: 6d 6f 72 79 20 66 6f 72 20 61 6c 6c 20 73 6f 72  mory for all sor
78f0: 74 2d 6b 65 79 73 2e 20 20 2a 2f 0a 20 20 20 20  t-keys.  */.    
7900: 20 20 69 66 28 20 73 71 6c 69 74 65 33 47 6c 6f    if( sqlite3Glo
7910: 62 61 6c 43 6f 6e 66 69 67 2e 70 48 65 61 70 3d  balConfig.pHeap=
7920: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 61 73  =0 ){.        as
7930: 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 69  sert( pSorter->i
7940: 4d 65 6d 6f 72 79 3d 3d 30 20 29 3b 0a 20 20 20  Memory==0 );.   
7950: 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6e 4d       pSorter->nM
7960: 65 6d 6f 72 79 20 3d 20 70 67 73 7a 3b 0a 20 20  emory = pgsz;.  
7970: 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6c        pSorter->l
7980: 69 73 74 2e 61 4d 65 6d 6f 72 79 20 3d 20 28 75  ist.aMemory = (u
7990: 38 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  8*)sqlite3Malloc
79a0: 28 70 67 73 7a 29 3b 0a 20 20 20 20 20 20 20 20  (pgsz);.        
79b0: 69 66 28 20 21 70 53 6f 72 74 65 72 2d 3e 6c 69  if( !pSorter->li
79c0: 73 74 2e 61 4d 65 6d 6f 72 79 20 29 20 72 63 20  st.aMemory ) rc 
79d0: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
79e0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
79f0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
7a00: 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 74 68  }../*.** Free th
7a10: 65 20 6c 69 73 74 20 6f 66 20 73 6f 72 74 65 64  e list of sorted
7a20: 20 72 65 63 6f 72 64 73 20 73 74 61 72 74 69 6e   records startin
7a30: 67 20 61 74 20 70 52 65 63 6f 72 64 2e 0a 2a 2f  g at pRecord..*/
7a40: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62  .static void vdb
7a50: 65 53 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65  eSorterRecordFre
7a60: 65 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 53  e(sqlite3 *db, S
7a70: 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 52 65  orterRecord *pRe
7a80: 63 6f 72 64 29 7b 0a 20 20 53 6f 72 74 65 72 52  cord){.  SorterR
7a90: 65 63 6f 72 64 20 2a 70 3b 0a 20 20 53 6f 72 74  ecord *p;.  Sort
7aa0: 65 72 52 65 63 6f 72 64 20 2a 70 4e 65 78 74 3b  erRecord *pNext;
7ab0: 0a 20 20 66 6f 72 28 70 3d 70 52 65 63 6f 72 64  .  for(p=pRecord
7ac0: 3b 20 70 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20  ; p; p=pNext){. 
7ad0: 20 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e 75 2e     pNext = p->u.
7ae0: 70 4e 65 78 74 3b 0a 20 20 20 20 73 71 6c 69 74  pNext;.    sqlit
7af0: 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 29 3b  e3DbFree(db, p);
7b00: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72  .  }.}../*.** Fr
7b10: 65 65 20 61 6c 6c 20 72 65 73 6f 75 72 63 65 73  ee all resources
7b20: 20 6f 77 6e 65 64 20 62 79 20 74 68 65 20 6f 62   owned by the ob
7b30: 6a 65 63 74 20 69 6e 64 69 63 61 74 65 64 20 62  ject indicated b
7b40: 79 20 61 72 67 75 6d 65 6e 74 20 70 54 61 73 6b  y argument pTask
7b50: 2e 20 41 6c 6c 20 0a 2a 2a 20 66 69 65 6c 64 73  . All .** fields
7b60: 20 6f 66 20 2a 70 54 61 73 6b 20 61 72 65 20 7a   of *pTask are z
7b70: 65 72 6f 65 64 20 62 65 66 6f 72 65 20 72 65 74  eroed before ret
7b80: 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69  urning..*/.stati
7b90: 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74 53  c void vdbeSortS
7ba0: 75 62 74 61 73 6b 43 6c 65 61 6e 75 70 28 73 71  ubtaskCleanup(sq
7bb0: 6c 69 74 65 33 20 2a 64 62 2c 20 53 6f 72 74 53  lite3 *db, SortS
7bc0: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 29 7b 0a  ubtask *pTask){.
7bd0: 20 20 73 71 6c 69 74 65 33 44 62 46 72 65 65 28    sqlite3DbFree(
7be0: 64 62 2c 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61  db, pTask->pUnpa
7bf0: 63 6b 65 64 29 3b 0a 20 20 70 54 61 73 6b 2d 3e  cked);.  pTask->
7c00: 70 55 6e 70 61 63 6b 65 64 20 3d 20 30 3b 0a 20  pUnpacked = 0;. 
7c10: 20 69 66 28 20 70 54 61 73 6b 2d 3e 6c 69 73 74   if( pTask->list
7c20: 2e 61 4d 65 6d 6f 72 79 3d 3d 30 20 29 7b 0a 20  .aMemory==0 ){. 
7c30: 20 20 20 76 64 62 65 53 6f 72 74 65 72 52 65 63     vdbeSorterRec
7c40: 6f 72 64 46 72 65 65 28 30 2c 20 70 54 61 73 6b  ordFree(0, pTask
7c50: 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 29 3b 0a 20  ->list.pList);. 
7c60: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69   }else{.    sqli
7c70: 74 65 33 5f 66 72 65 65 28 70 54 61 73 6b 2d 3e  te3_free(pTask->
7c80: 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 29 3b 0a 20  list.aMemory);. 
7c90: 20 20 20 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 61     pTask->list.a
7ca0: 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a 20 20 7d 0a  Memory = 0;.  }.
7cb0: 20 20 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 70 4c    pTask->list.pL
7cc0: 69 73 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 70  ist = 0;.  if( p
7cd0: 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64 20 29  Task->file.pFd )
7ce0: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43  {.    sqlite3OsC
7cf0: 6c 6f 73 65 46 72 65 65 28 70 54 61 73 6b 2d 3e  loseFree(pTask->
7d00: 66 69 6c 65 2e 70 46 64 29 3b 0a 20 20 20 20 70  file.pFd);.    p
7d10: 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64 20 3d  Task->file.pFd =
7d20: 20 30 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 66   0;.    pTask->f
7d30: 69 6c 65 2e 69 45 6f 66 20 3d 20 30 3b 0a 20 20  ile.iEof = 0;.  
7d40: 7d 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 66  }.  if( pTask->f
7d50: 69 6c 65 32 2e 70 46 64 20 29 7b 0a 20 20 20 20  ile2.pFd ){.    
7d60: 73 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 46 72  sqlite3OsCloseFr
7d70: 65 65 28 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e  ee(pTask->file2.
7d80: 70 46 64 29 3b 0a 20 20 20 20 70 54 61 73 6b 2d  pFd);.    pTask-
7d90: 3e 66 69 6c 65 32 2e 70 46 64 20 3d 20 30 3b 0a  >file2.pFd = 0;.
7da0: 20 20 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32      pTask->file2
7db0: 2e 69 45 6f 66 20 3d 20 30 3b 0a 20 20 7d 0a 7d  .iEof = 0;.  }.}
7dc0: 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
7dd0: 44 45 42 55 47 5f 53 4f 52 54 45 52 5f 54 48 52  DEBUG_SORTER_THR
7de0: 45 41 44 53 0a 73 74 61 74 69 63 20 76 6f 69 64  EADS.static void
7df0: 20 76 64 62 65 53 6f 72 74 65 72 57 6f 72 6b 44   vdbeSorterWorkD
7e00: 65 62 75 67 28 53 6f 72 74 53 75 62 74 61 73 6b  ebug(SortSubtask
7e10: 20 2a 70 54 61 73 6b 2c 20 63 6f 6e 73 74 20 63   *pTask, const c
7e20: 68 61 72 20 2a 7a 45 76 65 6e 74 29 7b 0a 20 20  har *zEvent){.  
7e30: 69 36 34 20 74 3b 0a 20 20 69 6e 74 20 69 54 61  i64 t;.  int iTa
7e40: 73 6b 20 3d 20 28 70 54 61 73 6b 20 2d 20 70 54  sk = (pTask - pT
7e50: 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 61 54  ask->pSorter->aT
7e60: 61 73 6b 29 3b 0a 20 20 73 71 6c 69 74 65 33 4f  ask);.  sqlite3O
7e70: 73 43 75 72 72 65 6e 74 54 69 6d 65 49 6e 74 36  sCurrentTimeInt6
7e80: 34 28 70 54 61 73 6b 2d 3e 64 62 2d 3e 70 56 66  4(pTask->db->pVf
7e90: 73 2c 20 26 74 29 3b 0a 20 20 66 70 72 69 6e 74  s, &t);.  fprint
7ea0: 66 28 73 74 64 65 72 72 2c 20 22 25 6c 6c 64 3a  f(stderr, "%lld:
7eb0: 25 64 20 25 73 5c 6e 22 2c 20 74 2c 20 69 54 61  %d %s\n", t, iTa
7ec0: 73 6b 2c 20 7a 45 76 65 6e 74 29 3b 0a 7d 0a 73  sk, zEvent);.}.s
7ed0: 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 53  tatic void vdbeS
7ee0: 6f 72 74 65 72 52 65 77 69 6e 64 44 65 62 75 67  orterRewindDebug
7ef0: 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 63 6f  (sqlite3 *db, co
7f00: 6e 73 74 20 63 68 61 72 20 2a 7a 45 76 65 6e 74  nst char *zEvent
7f10: 29 7b 0a 20 20 69 36 34 20 74 3b 0a 20 20 73 71  ){.  i64 t;.  sq
7f20: 6c 69 74 65 33 4f 73 43 75 72 72 65 6e 74 54 69  lite3OsCurrentTi
7f30: 6d 65 49 6e 74 36 34 28 64 62 2d 3e 70 56 66 73  meInt64(db->pVfs
7f40: 2c 20 26 74 29 3b 0a 20 20 66 70 72 69 6e 74 66  , &t);.  fprintf
7f50: 28 73 74 64 65 72 72 2c 20 22 25 6c 6c 64 3a 58  (stderr, "%lld:X
7f60: 20 25 73 5c 6e 22 2c 20 74 2c 20 7a 45 76 65 6e   %s\n", t, zEven
7f70: 74 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69  t);.}.static voi
7f80: 64 20 76 64 62 65 53 6f 72 74 65 72 50 6f 70 75  d vdbeSorterPopu
7f90: 6c 61 74 65 44 65 62 75 67 28 0a 20 20 53 6f 72  lateDebug(.  Sor
7fa0: 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c  tSubtask *pTask,
7fb0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
7fc0: 45 76 65 6e 74 0a 29 7b 0a 20 20 69 36 34 20 74  Event.){.  i64 t
7fd0: 3b 0a 20 20 69 6e 74 20 69 54 61 73 6b 20 3d 20  ;.  int iTask = 
7fe0: 28 70 54 61 73 6b 20 2d 20 70 54 61 73 6b 2d 3e  (pTask - pTask->
7ff0: 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 29 3b  pSorter->aTask);
8000: 0a 20 20 73 71 6c 69 74 65 33 4f 73 43 75 72 72  .  sqlite3OsCurr
8010: 65 6e 74 54 69 6d 65 49 6e 74 36 34 28 70 54 61  entTimeInt64(pTa
8020: 73 6b 2d 3e 64 62 2d 3e 70 56 66 73 2c 20 26 74  sk->db->pVfs, &t
8030: 29 3b 0a 20 20 66 70 72 69 6e 74 66 28 73 74 64  );.  fprintf(std
8040: 65 72 72 2c 20 22 25 6c 6c 64 3a 62 67 25 64 20  err, "%lld:bg%d 
8050: 25 73 5c 6e 22 2c 20 74 2c 20 69 54 61 73 6b 2c  %s\n", t, iTask,
8060: 20 7a 45 76 65 6e 74 29 3b 0a 7d 0a 73 74 61 74   zEvent);.}.stat
8070: 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74  ic void vdbeSort
8080: 65 72 42 6c 6f 63 6b 44 65 62 75 67 28 0a 20 20  erBlockDebug(.  
8090: 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61  SortSubtask *pTa
80a0: 73 6b 2c 0a 20 20 69 6e 74 20 62 42 6c 6f 63 6b  sk,.  int bBlock
80b0: 65 64 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  ed,.  const char
80c0: 20 2a 7a 45 76 65 6e 74 0a 29 7b 0a 20 20 69 66   *zEvent.){.  if
80d0: 28 20 62 42 6c 6f 63 6b 65 64 20 29 7b 0a 20 20  ( bBlocked ){.  
80e0: 20 20 69 36 34 20 74 3b 0a 20 20 20 20 73 71 6c    i64 t;.    sql
80f0: 69 74 65 33 4f 73 43 75 72 72 65 6e 74 54 69 6d  ite3OsCurrentTim
8100: 65 49 6e 74 36 34 28 70 54 61 73 6b 2d 3e 64 62  eInt64(pTask->db
8110: 2d 3e 70 56 66 73 2c 20 26 74 29 3b 0a 20 20 20  ->pVfs, &t);.   
8120: 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c   fprintf(stderr,
8130: 20 22 25 6c 6c 64 3a 6d 61 69 6e 20 25 73 5c 6e   "%lld:main %s\n
8140: 22 2c 20 74 2c 20 7a 45 76 65 6e 74 29 3b 0a 20  ", t, zEvent);. 
8150: 20 7d 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65 66   }.}.#else.# def
8160: 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72 57 6f  ine vdbeSorterWo
8170: 72 6b 44 65 62 75 67 28 78 2c 79 29 0a 23 20 64  rkDebug(x,y).# d
8180: 65 66 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72  efine vdbeSorter
8190: 52 65 77 69 6e 64 44 65 62 75 67 28 78 2c 79 29  RewindDebug(x,y)
81a0: 0a 23 20 64 65 66 69 6e 65 20 76 64 62 65 53 6f  .# define vdbeSo
81b0: 72 74 65 72 50 6f 70 75 6c 61 74 65 44 65 62 75  rterPopulateDebu
81c0: 67 28 78 2c 79 29 0a 23 20 64 65 66 69 6e 65 20  g(x,y).# define 
81d0: 76 64 62 65 53 6f 72 74 65 72 42 6c 6f 63 6b 44  vdbeSorterBlockD
81e0: 65 62 75 67 28 78 2c 79 2c 7a 29 0a 23 65 6e 64  ebug(x,y,z).#end
81f0: 69 66 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d  if..#if SQLITE_M
8200: 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44  AX_WORKER_THREAD
8210: 53 3e 30 0a 2f 2a 0a 2a 2a 20 4a 6f 69 6e 20 74  S>0./*.** Join t
8220: 68 72 65 61 64 20 70 2e 0a 2a 2f 0a 73 74 61 74  hread p..*/.stat
8230: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
8240: 72 4a 6f 69 6e 54 68 72 65 61 64 28 53 6f 72 74  rJoinThread(Sort
8250: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20  Subtask *pTask, 
8260: 53 6f 72 74 65 72 54 68 72 65 61 64 20 2a 70 29  SorterThread *p)
8270: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
8280: 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70 2d  ITE_OK;.  if( p-
8290: 3e 70 54 68 72 65 61 64 20 29 7b 0a 23 69 66 64  >pThread ){.#ifd
82a0: 65 66 20 53 51 4c 49 54 45 5f 44 45 42 55 47 5f  ef SQLITE_DEBUG_
82b0: 53 4f 52 54 45 52 5f 54 48 52 45 41 44 53 0a 20  SORTER_THREADS. 
82c0: 20 20 20 69 6e 74 20 62 44 6f 6e 65 20 3d 20 70     int bDone = p
82d0: 2d 3e 62 44 6f 6e 65 3b 0a 23 65 6e 64 69 66 0a  ->bDone;.#endif.
82e0: 20 20 20 20 76 6f 69 64 20 2a 70 52 65 74 3b 0a      void *pRet;.
82f0: 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 42 6c      vdbeSorterBl
8300: 6f 63 6b 44 65 62 75 67 28 70 54 61 73 6b 2c 20  ockDebug(pTask, 
8310: 21 62 44 6f 6e 65 2c 20 22 65 6e 74 65 72 22 29  !bDone, "enter")
8320: 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ;.    rc = sqlit
8330: 65 33 54 68 72 65 61 64 4a 6f 69 6e 28 70 2d 3e  e3ThreadJoin(p->
8340: 70 54 68 72 65 61 64 2c 20 26 70 52 65 74 29 3b  pThread, &pRet);
8350: 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 42  .    vdbeSorterB
8360: 6c 6f 63 6b 44 65 62 75 67 28 70 54 61 73 6b 2c  lockDebug(pTask,
8370: 20 21 62 44 6f 6e 65 2c 20 22 65 78 69 74 22 29   !bDone, "exit")
8380: 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
8390: 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 53  LITE_OK ) rc = S
83a0: 51 4c 49 54 45 5f 50 54 52 5f 54 4f 5f 49 4e 54  QLITE_PTR_TO_INT
83b0: 28 70 52 65 74 29 3b 0a 20 20 20 20 61 73 73 65  (pRet);.    asse
83c0: 72 74 28 20 70 2d 3e 62 44 6f 6e 65 3d 3d 31 20  rt( p->bDone==1 
83d0: 29 3b 0a 20 20 20 20 70 2d 3e 62 44 6f 6e 65 20  );.    p->bDone 
83e0: 3d 20 30 3b 0a 20 20 20 20 70 2d 3e 70 54 68 72  = 0;.    p->pThr
83f0: 65 61 64 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 72  ead = 0;.  }.  r
8400: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
8410: 2a 2a 20 4c 61 75 6e 63 68 20 61 20 62 61 63 6b  ** Launch a back
8420: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 74 6f  ground thread to
8430: 20 72 75 6e 20 78 54 61 73 6b 28 70 49 6e 29 2e   run xTask(pIn).
8440: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
8450: 64 62 65 53 6f 72 74 65 72 43 72 65 61 74 65 54  dbeSorterCreateT
8460: 68 72 65 61 64 28 0a 20 20 53 6f 72 74 65 72 54  hread(.  SorterT
8470: 68 72 65 61 64 20 2a 70 2c 20 20 20 20 20 20 20  hread *p,       
8480: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 72 65           /* Thre
8490: 61 64 20 6f 62 6a 65 63 74 20 74 6f 20 70 6f 70  ad object to pop
84a0: 75 6c 61 74 65 20 2a 2f 0a 20 20 76 6f 69 64 20  ulate */.  void 
84b0: 2a 28 2a 78 54 61 73 6b 29 28 76 6f 69 64 2a 29  *(*xTask)(void*)
84c0: 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 6f  ,          /* Ro
84d0: 75 74 69 6e 65 20 74 6f 20 72 75 6e 20 69 6e 20  utine to run in 
84e0: 61 20 73 65 70 61 72 61 74 65 20 74 68 72 65 61  a separate threa
84f0: 64 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 49 6e  d */.  void *pIn
8500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8510: 20 20 20 20 20 20 20 2f 2a 20 41 72 67 75 6d 65         /* Argume
8520: 6e 74 20 70 61 73 73 65 64 20 69 6e 74 6f 20 78  nt passed into x
8530: 54 61 73 6b 28 29 20 2a 2f 0a 29 7b 0a 20 20 61  Task() */.){.  a
8540: 73 73 65 72 74 28 20 70 2d 3e 70 54 68 72 65 61  ssert( p->pThrea
8550: 64 3d 3d 30 20 26 26 20 70 2d 3e 62 44 6f 6e 65  d==0 && p->bDone
8560: 3d 3d 30 20 29 3b 0a 20 20 72 65 74 75 72 6e 20  ==0 );.  return 
8570: 73 71 6c 69 74 65 33 54 68 72 65 61 64 43 72 65  sqlite3ThreadCre
8580: 61 74 65 28 26 70 2d 3e 70 54 68 72 65 61 64 2c  ate(&p->pThread,
8590: 20 78 54 61 73 6b 2c 20 70 49 6e 29 3b 0a 7d 0a   xTask, pIn);.}.
85a0: 0a 2f 2a 0a 2a 2a 20 4a 6f 69 6e 20 61 6c 6c 20  ./*.** Join all 
85b0: 6f 75 74 73 74 61 6e 64 69 6e 67 20 74 68 72 65  outstanding thre
85c0: 61 64 73 20 6c 61 75 6e 63 68 65 64 20 62 79 20  ads launched by 
85d0: 53 6f 72 74 65 72 57 72 69 74 65 28 29 20 74 6f  SorterWrite() to
85e0: 20 63 72 65 61 74 65 20 0a 2a 2a 20 6c 65 76 65   create .** leve
85f0: 6c 2d 30 20 50 4d 41 73 2e 0a 2a 2f 0a 73 74 61  l-0 PMAs..*/.sta
8600: 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74  tic int vdbeSort
8610: 65 72 4a 6f 69 6e 41 6c 6c 28 56 64 62 65 53 6f  erJoinAll(VdbeSo
8620: 72 74 65 72 20 2a 70 53 6f 72 74 65 72 2c 20 69  rter *pSorter, i
8630: 6e 74 20 72 63 69 6e 29 7b 0a 20 20 69 6e 74 20  nt rcin){.  int 
8640: 72 63 20 3d 20 72 63 69 6e 3b 0a 20 20 69 6e 74  rc = rcin;.  int
8650: 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69   i;.  for(i=0; i
8660: 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3b  <pSorter->nTask;
8670: 20 69 2b 2b 29 7b 0a 20 20 20 20 53 6f 72 74 53   i++){.    SortS
8680: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20  ubtask *pTask = 
8690: 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b  &pSorter->aTask[
86a0: 69 5d 3b 0a 20 20 20 20 69 6e 74 20 72 63 32 20  i];.    int rc2 
86b0: 3d 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e  = vdbeSorterJoin
86c0: 54 68 72 65 61 64 28 70 54 61 73 6b 2c 20 26 70  Thread(pTask, &p
86d0: 54 61 73 6b 2d 3e 74 68 72 65 61 64 29 3b 0a 20  Task->thread);. 
86e0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
86f0: 45 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63 32 3b  E_OK ) rc = rc2;
8700: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
8710: 3b 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65 66 69  ;.}.#else.# defi
8720: 6e 65 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69  ne vdbeSorterJoi
8730: 6e 41 6c 6c 28 78 2c 72 63 69 6e 29 20 28 72 63  nAll(x,rcin) (rc
8740: 69 6e 29 0a 23 20 64 65 66 69 6e 65 20 76 64 62  in).# define vdb
8750: 65 53 6f 72 74 65 72 4a 6f 69 6e 54 68 72 65 61  eSorterJoinThrea
8760: 64 28 70 54 61 73 6b 2c 70 29 20 53 51 4c 49 54  d(pTask,p) SQLIT
8770: 45 5f 4f 4b 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a  E_OK.#endif../*.
8780: 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65  ** Allocate a ne
8790: 77 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 6f 62  w MergeEngine ob
87a0: 6a 65 63 74 20 77 69 74 68 20 73 70 61 63 65 20  ject with space 
87b0: 66 6f 72 20 6e 49 74 65 72 20 69 74 65 72 61 74  for nIter iterat
87c0: 6f 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 4d  ors..*/.static M
87d0: 65 72 67 65 45 6e 67 69 6e 65 20 2a 76 64 62 65  ergeEngine *vdbe
87e0: 4d 65 72 67 65 45 6e 67 69 6e 65 4e 65 77 28 69  MergeEngineNew(i
87f0: 6e 74 20 6e 49 74 65 72 29 7b 0a 20 20 69 6e 74  nt nIter){.  int
8800: 20 4e 20 3d 20 32 3b 20 20 20 20 20 20 20 20 20   N = 2;         
8810: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8820: 53 6d 61 6c 6c 65 73 74 20 70 6f 77 65 72 20 6f  Smallest power o
8830: 66 20 74 77 6f 20 3e 3d 20 6e 49 74 65 72 20 2a  f two >= nIter *
8840: 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b 20 20  /.  int nByte;  
8850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8860: 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 62 79 74      /* Total byt
8870: 65 73 20 6f 66 20 73 70 61 63 65 20 74 6f 20 61  es of space to a
8880: 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20 20 4d 65 72  llocate */.  Mer
8890: 67 65 45 6e 67 69 6e 65 20 2a 70 4e 65 77 3b 20  geEngine *pNew; 
88a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
88b0: 50 6f 69 6e 74 65 72 20 74 6f 20 61 6c 6c 6f 63  Pointer to alloc
88c0: 61 74 65 64 20 6f 62 6a 65 63 74 20 74 6f 20 72  ated object to r
88d0: 65 74 75 72 6e 20 2a 2f 0a 0a 20 20 61 73 73 65  eturn */..  asse
88e0: 72 74 28 20 6e 49 74 65 72 3c 3d 53 4f 52 54 45  rt( nIter<=SORTE
88f0: 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
8900: 54 20 29 3b 0a 0a 20 20 77 68 69 6c 65 28 20 4e  T );..  while( N
8910: 3c 6e 49 74 65 72 20 29 20 4e 20 2b 3d 20 4e 3b  <nIter ) N += N;
8920: 0a 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f  .  nByte = sizeo
8930: 66 28 4d 65 72 67 65 45 6e 67 69 6e 65 29 20 2b  f(MergeEngine) +
8940: 20 4e 20 2a 20 28 73 69 7a 65 6f 66 28 69 6e 74   N * (sizeof(int
8950: 29 20 2b 20 73 69 7a 65 6f 66 28 50 6d 61 52 65  ) + sizeof(PmaRe
8960: 61 64 65 72 29 29 3b 0a 0a 20 20 70 4e 65 77 20  ader));..  pNew 
8970: 3d 20 28 4d 65 72 67 65 45 6e 67 69 6e 65 2a 29  = (MergeEngine*)
8980: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72  sqlite3MallocZer
8990: 6f 28 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20  o(nByte);.  if( 
89a0: 70 4e 65 77 20 29 7b 0a 20 20 20 20 70 4e 65 77  pNew ){.    pNew
89b0: 2d 3e 6e 54 72 65 65 20 3d 20 4e 3b 0a 20 20 20  ->nTree = N;.   
89c0: 20 70 4e 65 77 2d 3e 61 49 74 65 72 20 3d 20 28   pNew->aIter = (
89d0: 50 6d 61 52 65 61 64 65 72 2a 29 26 70 4e 65 77  PmaReader*)&pNew
89e0: 5b 31 5d 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 61  [1];.    pNew->a
89f0: 54 72 65 65 20 3d 20 28 69 6e 74 2a 29 26 70 4e  Tree = (int*)&pN
8a00: 65 77 2d 3e 61 49 74 65 72 5b 4e 5d 3b 0a 20 20  ew->aIter[N];.  
8a10: 7d 0a 20 20 72 65 74 75 72 6e 20 70 4e 65 77 3b  }.  return pNew;
8a20: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 74  .}../*.** Free t
8a30: 68 65 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 6f  he MergeEngine o
8a40: 62 6a 65 63 74 20 70 61 73 73 65 64 20 61 73 20  bject passed as 
8a50: 74 68 65 20 6f 6e 6c 79 20 61 72 67 75 6d 65 6e  the only argumen
8a60: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  t..*/.static voi
8a70: 64 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e  d vdbeMergeEngin
8a80: 65 46 72 65 65 28 4d 65 72 67 65 45 6e 67 69 6e  eFree(MergeEngin
8a90: 65 20 2a 70 4d 65 72 67 65 72 29 7b 0a 20 20 69  e *pMerger){.  i
8aa0: 6e 74 20 69 3b 0a 20 20 69 66 28 20 70 4d 65 72  nt i;.  if( pMer
8ab0: 67 65 72 20 29 7b 0a 20 20 20 20 66 6f 72 28 69  ger ){.    for(i
8ac0: 3d 30 3b 20 69 3c 70 4d 65 72 67 65 72 2d 3e 6e  =0; i<pMerger->n
8ad0: 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  Tree; i++){.    
8ae0: 20 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 43    vdbePmaReaderC
8af0: 6c 65 61 72 28 26 70 4d 65 72 67 65 72 2d 3e 61  lear(&pMerger->a
8b00: 49 74 65 72 5b 69 5d 29 3b 0a 20 20 20 20 7d 0a  Iter[i]);.    }.
8b10: 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72    }.  sqlite3_fr
8b20: 65 65 28 70 4d 65 72 67 65 72 29 3b 0a 7d 0a 0a  ee(pMerger);.}..
8b30: 2f 2a 0a 2a 2a 20 52 65 73 65 74 20 61 20 73 6f  /*.** Reset a so
8b40: 72 74 69 6e 67 20 63 75 72 73 6f 72 20 62 61 63  rting cursor bac
8b50: 6b 20 74 6f 20 69 74 73 20 6f 72 69 67 69 6e 61  k to its origina
8b60: 6c 20 65 6d 70 74 79 20 73 74 61 74 65 2e 0a 2a  l empty state..*
8b70: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 56 64  /.void sqlite3Vd
8b80: 62 65 53 6f 72 74 65 72 52 65 73 65 74 28 73 71  beSorterReset(sq
8b90: 6c 69 74 65 33 20 2a 64 62 2c 20 56 64 62 65 53  lite3 *db, VdbeS
8ba0: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 29 7b  orter *pSorter){
8bb0: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 28 76 6f 69  .  int i;.  (voi
8bc0: 64 29 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e  d)vdbeSorterJoin
8bd0: 41 6c 6c 28 70 53 6f 72 74 65 72 2c 20 53 51 4c  All(pSorter, SQL
8be0: 49 54 45 5f 4f 4b 29 3b 0a 20 20 69 66 28 20 70  ITE_OK);.  if( p
8bf0: 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72 20  Sorter->pReader 
8c00: 29 7b 0a 20 20 20 20 76 64 62 65 50 6d 61 52 65  ){.    vdbePmaRe
8c10: 61 64 65 72 43 6c 65 61 72 28 70 53 6f 72 74 65  aderClear(pSorte
8c20: 72 2d 3e 70 52 65 61 64 65 72 29 3b 0a 20 20 20  r->pReader);.   
8c30: 20 73 71 6c 69 74 65 33 44 62 46 72 65 65 28 64   sqlite3DbFree(d
8c40: 62 2c 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 61  b, pSorter->pRea
8c50: 64 65 72 29 3b 0a 20 20 20 20 70 53 6f 72 74 65  der);.    pSorte
8c60: 72 2d 3e 70 52 65 61 64 65 72 20 3d 20 30 3b 0a  r->pReader = 0;.
8c70: 20 20 7d 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69    }.  for(i=0; i
8c80: 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3b  <pSorter->nTask;
8c90: 20 69 2b 2b 29 7b 0a 20 20 20 20 53 6f 72 74 53   i++){.    SortS
8ca0: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20  ubtask *pTask = 
8cb0: 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b  &pSorter->aTask[
8cc0: 69 5d 3b 0a 20 20 20 20 76 64 62 65 53 6f 72 74  i];.    vdbeSort
8cd0: 53 75 62 74 61 73 6b 43 6c 65 61 6e 75 70 28 64  SubtaskCleanup(d
8ce0: 62 2c 20 70 54 61 73 6b 29 3b 0a 20 20 7d 0a 20  b, pTask);.  }. 
8cf0: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6c 69   if( pSorter->li
8d00: 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30 20 29 7b  st.aMemory==0 ){
8d10: 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 52  .    vdbeSorterR
8d20: 65 63 6f 72 64 46 72 65 65 28 30 2c 20 70 53 6f  ecordFree(0, pSo
8d30: 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74  rter->list.pList
8d40: 29 3b 0a 20 20 7d 0a 20 20 70 53 6f 72 74 65 72  );.  }.  pSorter
8d50: 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d 20 30  ->list.pList = 0
8d60: 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73  ;.  pSorter->lis
8d70: 74 2e 73 7a 50 4d 41 20 3d 20 30 3b 0a 20 20 70  t.szPMA = 0;.  p
8d80: 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41 20  Sorter->bUsePMA 
8d90: 3d 20 30 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e  = 0;.  pSorter->
8da0: 69 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a 20 20 70  iMemory = 0;.  p
8db0: 53 6f 72 74 65 72 2d 3e 6d 78 4b 65 79 73 69 7a  Sorter->mxKeysiz
8dc0: 65 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65 33  e = 0;.  sqlite3
8dd0: 44 62 46 72 65 65 28 64 62 2c 20 70 53 6f 72 74  DbFree(db, pSort
8de0: 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64 29 3b 0a  er->pUnpacked);.
8df0: 20 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61    pSorter->pUnpa
8e00: 63 6b 65 64 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a  cked = 0;.}../*.
8e10: 2a 2a 20 46 72 65 65 20 61 6e 79 20 63 75 72 73  ** Free any curs
8e20: 6f 72 20 63 6f 6d 70 6f 6e 65 6e 74 73 20 61 6c  or components al
8e30: 6c 6f 63 61 74 65 64 20 62 79 20 73 71 6c 69 74  located by sqlit
8e40: 65 33 56 64 62 65 53 6f 72 74 65 72 58 58 58 20  e3VdbeSorterXXX 
8e50: 72 6f 75 74 69 6e 65 73 2e 0a 2a 2f 0a 76 6f 69  routines..*/.voi
8e60: 64 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72  d sqlite3VdbeSor
8e70: 74 65 72 43 6c 6f 73 65 28 73 71 6c 69 74 65 33  terClose(sqlite3
8e80: 20 2a 64 62 2c 20 56 64 62 65 43 75 72 73 6f 72   *db, VdbeCursor
8e90: 20 2a 70 43 73 72 29 7b 0a 20 20 56 64 62 65 53   *pCsr){.  VdbeS
8ea0: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d  orter *pSorter =
8eb0: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a   pCsr->pSorter;.
8ec0: 20 20 69 66 28 20 70 53 6f 72 74 65 72 20 29 7b    if( pSorter ){
8ed0: 0a 20 20 20 20 73 71 6c 69 74 65 33 56 64 62 65  .    sqlite3Vdbe
8ee0: 53 6f 72 74 65 72 52 65 73 65 74 28 64 62 2c 20  SorterReset(db, 
8ef0: 70 53 6f 72 74 65 72 29 3b 0a 20 20 20 20 73 71  pSorter);.    sq
8f00: 6c 69 74 65 33 5f 66 72 65 65 28 70 53 6f 72 74  lite3_free(pSort
8f10: 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  er->list.aMemory
8f20: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 44 62  );.    sqlite3Db
8f30: 46 72 65 65 28 64 62 2c 20 70 53 6f 72 74 65 72  Free(db, pSorter
8f40: 29 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70 53 6f  );.    pCsr->pSo
8f50: 72 74 65 72 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a  rter = 0;.  }.}.
8f60: 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20  ./*.** Allocate 
8f70: 73 70 61 63 65 20 66 6f 72 20 61 20 66 69 6c 65  space for a file
8f80: 2d 68 61 6e 64 6c 65 20 61 6e 64 20 6f 70 65 6e  -handle and open
8f90: 20 61 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c   a temporary fil
8fa0: 65 2e 20 49 66 20 73 75 63 63 65 73 73 66 75 6c  e. If successful
8fb0: 2c 0a 2a 2a 20 73 65 74 20 2a 70 70 46 69 6c 65  ,.** set *ppFile
8fc0: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65   to point to the
8fd0: 20 6d 61 6c 6c 6f 63 27 64 20 66 69 6c 65 2d 68   malloc'd file-h
8fe0: 61 6e 64 6c 65 20 61 6e 64 20 72 65 74 75 72 6e  andle and return
8ff0: 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2a 20 4f   SQLITE_OK..** O
9000: 74 68 65 72 77 69 73 65 2c 20 73 65 74 20 2a 70  therwise, set *p
9010: 70 46 69 6c 65 20 74 6f 20 30 20 61 6e 64 20 72  pFile to 0 and r
9020: 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 20  eturn an SQLite 
9030: 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2f 0a 73  error code..*/.s
9040: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
9050: 72 74 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65  rterOpenTempFile
9060: 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56  (sqlite3_vfs *pV
9070: 66 73 2c 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  fs, sqlite3_file
9080: 20 2a 2a 70 70 46 69 6c 65 29 7b 0a 20 20 69 6e   **ppFile){.  in
9090: 74 20 72 63 3b 0a 20 20 72 63 20 3d 20 73 71 6c  t rc;.  rc = sql
90a0: 69 74 65 33 4f 73 4f 70 65 6e 4d 61 6c 6c 6f 63  ite3OsOpenMalloc
90b0: 28 70 56 66 73 2c 20 30 2c 20 70 70 46 69 6c 65  (pVfs, 0, ppFile
90c0: 2c 0a 20 20 20 20 20 20 53 51 4c 49 54 45 5f 4f  ,.      SQLITE_O
90d0: 50 45 4e 5f 54 45 4d 50 5f 4a 4f 55 52 4e 41 4c  PEN_TEMP_JOURNAL
90e0: 20 7c 0a 20 20 20 20 20 20 53 51 4c 49 54 45 5f   |.      SQLITE_
90f0: 4f 50 45 4e 5f 52 45 41 44 57 52 49 54 45 20 20  OPEN_READWRITE  
9100: 20 20 7c 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f    | SQLITE_OPEN_
9110: 43 52 45 41 54 45 20 7c 0a 20 20 20 20 20 20 53  CREATE |.      S
9120: 51 4c 49 54 45 5f 4f 50 45 4e 5f 45 58 43 4c 55  QLITE_OPEN_EXCLU
9130: 53 49 56 45 20 20 20 20 7c 20 53 51 4c 49 54 45  SIVE    | SQLITE
9140: 5f 4f 50 45 4e 5f 44 45 4c 45 54 45 4f 4e 43 4c  _OPEN_DELETEONCL
9150: 4f 53 45 2c 20 26 72 63 0a 20 20 29 3b 0a 20 20  OSE, &rc.  );.  
9160: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
9170: 4b 20 29 7b 0a 20 20 20 20 69 36 34 20 6d 61 78  K ){.    i64 max
9180: 20 3d 20 53 51 4c 49 54 45 5f 4d 41 58 5f 4d 4d   = SQLITE_MAX_MM
9190: 41 50 5f 53 49 5a 45 3b 0a 20 20 20 20 73 71 6c  AP_SIZE;.    sql
91a0: 69 74 65 33 4f 73 46 69 6c 65 43 6f 6e 74 72 6f  ite3OsFileContro
91b0: 6c 48 69 6e 74 28 20 2a 70 70 46 69 6c 65 2c 20  lHint( *ppFile, 
91c0: 53 51 4c 49 54 45 5f 46 43 4e 54 4c 5f 4d 4d 41  SQLITE_FCNTL_MMA
91d0: 50 5f 53 49 5a 45 2c 20 28 76 6f 69 64 2a 29 26  P_SIZE, (void*)&
91e0: 6d 61 78 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  max);.  }.  retu
91f0: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
9200: 20 69 6e 74 20 76 64 62 65 53 6f 72 74 41 6c 6c   int vdbeSortAll
9210: 6f 63 55 6e 70 61 63 6b 65 64 28 53 6f 72 74 53  ocUnpacked(SortS
9220: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 29 7b 0a  ubtask *pTask){.
9230: 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 70 55 6e    if( pTask->pUn
9240: 70 61 63 6b 65 64 3d 3d 30 20 29 7b 0a 20 20 20  packed==0 ){.   
9250: 20 63 68 61 72 20 2a 70 46 72 65 65 3b 0a 20 20   char *pFree;.  
9260: 20 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b    pTask->pUnpack
9270: 65 64 20 3d 20 73 71 6c 69 74 65 33 56 64 62 65  ed = sqlite3Vdbe
9280: 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64 52 65 63  AllocUnpackedRec
9290: 6f 72 64 28 0a 20 20 20 20 20 20 20 20 70 54 61  ord(.        pTa
92a0: 73 6b 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20 30 2c  sk->pKeyInfo, 0,
92b0: 20 30 2c 20 26 70 46 72 65 65 0a 20 20 20 20 29   0, &pFree.    )
92c0: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 54  ;.    assert( pT
92d0: 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 3d 3d  ask->pUnpacked==
92e0: 28 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 2a  (UnpackedRecord*
92f0: 29 70 46 72 65 65 20 29 3b 0a 20 20 20 20 69 66  )pFree );.    if
9300: 28 20 70 46 72 65 65 3d 3d 30 20 29 20 72 65 74  ( pFree==0 ) ret
9310: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
9320: 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 70 55 6e  ;.    pTask->pUn
9330: 70 61 63 6b 65 64 2d 3e 6e 46 69 65 6c 64 20 3d  packed->nField =
9340: 20 70 54 61 73 6b 2d 3e 70 4b 65 79 49 6e 66 6f   pTask->pKeyInfo
9350: 2d 3e 6e 46 69 65 6c 64 3b 0a 20 20 20 20 70 54  ->nField;.    pT
9360: 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 2d 3e  ask->pUnpacked->
9370: 65 72 72 43 6f 64 65 20 3d 20 30 3b 0a 20 20 7d  errCode = 0;.  }
9380: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
9390: 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 4d  _OK;.}.../*.** M
93a0: 65 72 67 65 20 74 68 65 20 74 77 6f 20 73 6f 72  erge the two sor
93b0: 74 65 64 20 6c 69 73 74 73 20 70 31 20 61 6e 64  ted lists p1 and
93c0: 20 70 32 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c   p2 into a singl
93d0: 65 20 6c 69 73 74 2e 0a 2a 2a 20 53 65 74 20 2a  e list..** Set *
93e0: 70 70 4f 75 74 20 74 6f 20 74 68 65 20 68 65 61  ppOut to the hea
93f0: 64 20 6f 66 20 74 68 65 20 6e 65 77 20 6c 69 73  d of the new lis
9400: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  t..*/.static voi
9410: 64 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67  d vdbeSorterMerg
9420: 65 28 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b  e(.  SortSubtask
9430: 20 2a 70 54 61 73 6b 2c 20 20 20 20 20 20 20 20   *pTask,        
9440: 20 20 20 20 20 2f 2a 20 43 61 6c 6c 69 6e 67 20       /* Calling 
9450: 74 68 72 65 61 64 20 63 6f 6e 74 65 78 74 20 2a  thread context *
9460: 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  /.  SorterRecord
9470: 20 2a 70 31 2c 20 20 20 20 20 20 20 20 20 20 20   *p1,           
9480: 20 20 20 20 2f 2a 20 46 69 72 73 74 20 6c 69 73      /* First lis
9490: 74 20 74 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20  t to merge */.  
94a0: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 32  SorterRecord *p2
94b0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
94c0: 2f 2a 20 53 65 63 6f 6e 64 20 6c 69 73 74 20 74  /* Second list t
94d0: 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20 53 6f 72  o merge */.  Sor
94e0: 74 65 72 52 65 63 6f 72 64 20 2a 2a 70 70 4f 75  terRecord **ppOu
94f0: 74 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  t            /* 
9500: 4f 55 54 3a 20 48 65 61 64 20 6f 66 20 6d 65 72  OUT: Head of mer
9510: 67 65 64 20 6c 69 73 74 20 2a 2f 0a 29 7b 0a 20  ged list */.){. 
9520: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
9530: 46 69 6e 61 6c 20 3d 20 30 3b 0a 20 20 53 6f 72  Final = 0;.  Sor
9540: 74 65 72 52 65 63 6f 72 64 20 2a 2a 70 70 20 3d  terRecord **pp =
9550: 20 26 70 46 69 6e 61 6c 3b 0a 20 20 76 6f 69 64   &pFinal;.  void
9560: 20 2a 70 56 61 6c 32 20 3d 20 70 32 20 3f 20 53   *pVal2 = p2 ? S
9570: 52 56 41 4c 28 70 32 29 20 3a 20 30 3b 0a 0a 20  RVAL(p2) : 0;.. 
9580: 20 77 68 69 6c 65 28 20 70 31 20 26 26 20 70 32   while( p1 && p2
9590: 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 65 73 3b   ){.    int res;
95a0: 0a 20 20 20 20 72 65 73 20 3d 20 76 64 62 65 53  .    res = vdbeS
95b0: 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 70 54 61  orterCompare(pTa
95c0: 73 6b 2c 20 53 52 56 41 4c 28 70 31 29 2c 20 70  sk, SRVAL(p1), p
95d0: 31 2d 3e 6e 56 61 6c 2c 20 70 56 61 6c 32 2c 20  1->nVal, pVal2, 
95e0: 70 32 2d 3e 6e 56 61 6c 29 3b 0a 20 20 20 20 69  p2->nVal);.    i
95f0: 66 28 20 72 65 73 3c 3d 30 20 29 7b 0a 20 20 20  f( res<=0 ){.   
9600: 20 20 20 2a 70 70 20 3d 20 70 31 3b 0a 20 20 20     *pp = p1;.   
9610: 20 20 20 70 70 20 3d 20 26 70 31 2d 3e 75 2e 70     pp = &p1->u.p
9620: 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 31 20 3d  Next;.      p1 =
9630: 20 70 31 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20 20   p1->u.pNext;.  
9640: 20 20 20 20 70 56 61 6c 32 20 3d 20 30 3b 0a 20      pVal2 = 0;. 
9650: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
9660: 2a 70 70 20 3d 20 70 32 3b 0a 20 20 20 20 20 20  *pp = p2;.      
9670: 20 70 70 20 3d 20 26 70 32 2d 3e 75 2e 70 4e 65   pp = &p2->u.pNe
9680: 78 74 3b 0a 20 20 20 20 20 20 70 32 20 3d 20 70  xt;.      p2 = p
9690: 32 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20 20 20 20  2->u.pNext;.    
96a0: 20 20 69 66 28 20 70 32 3d 3d 30 20 29 20 62 72    if( p2==0 ) br
96b0: 65 61 6b 3b 0a 20 20 20 20 20 20 70 56 61 6c 32  eak;.      pVal2
96c0: 20 3d 20 53 52 56 41 4c 28 70 32 29 3b 0a 20 20   = SRVAL(p2);.  
96d0: 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 70 20 3d 20    }.  }.  *pp = 
96e0: 70 31 20 3f 20 70 31 20 3a 20 70 32 3b 0a 20 20  p1 ? p1 : p2;.  
96f0: 2a 70 70 4f 75 74 20 3d 20 70 46 69 6e 61 6c 3b  *ppOut = pFinal;
9700: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74  .}../*.** Sort t
9710: 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f  he linked list o
9720: 66 20 72 65 63 6f 72 64 73 20 68 65 61 64 65 64  f records headed
9730: 20 61 74 20 70 54 61 73 6b 2d 3e 70 4c 69 73 74   at pTask->pList
9740: 2e 20 52 65 74 75 72 6e 20 0a 2a 2a 20 53 51 4c  . Return .** SQL
9750: 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73  ITE_OK if succes
9760: 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69  sful, or an SQLi
9770: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 28 69  te error code (i
9780: 2e 65 2e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  .e. SQLITE_NOMEM
9790: 29 20 69 66 20 0a 2a 2a 20 61 6e 20 65 72 72 6f  ) if .** an erro
97a0: 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61  r occurs..*/.sta
97b0: 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74  tic int vdbeSort
97c0: 65 72 53 6f 72 74 28 53 6f 72 74 53 75 62 74 61  erSort(SortSubta
97d0: 73 6b 20 2a 70 54 61 73 6b 2c 20 53 6f 72 74 65  sk *pTask, Sorte
97e0: 72 4c 69 73 74 20 2a 70 4c 69 73 74 29 7b 0a 20  rList *pList){. 
97f0: 20 69 6e 74 20 69 3b 0a 20 20 53 6f 72 74 65 72   int i;.  Sorter
9800: 52 65 63 6f 72 64 20 2a 2a 61 53 6c 6f 74 3b 0a  Record **aSlot;.
9810: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
9820: 70 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20  p;.  int rc;..  
9830: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 41 6c 6c  rc = vdbeSortAll
9840: 6f 63 55 6e 70 61 63 6b 65 64 28 70 54 61 73 6b  ocUnpacked(pTask
9850: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
9860: 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
9870: 72 63 3b 0a 0a 20 20 61 53 6c 6f 74 20 3d 20 28  rc;..  aSlot = (
9880: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 2a 29  SorterRecord **)
9890: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72  sqlite3MallocZer
98a0: 6f 28 36 34 20 2a 20 73 69 7a 65 6f 66 28 53 6f  o(64 * sizeof(So
98b0: 72 74 65 72 52 65 63 6f 72 64 20 2a 29 29 3b 0a  rterRecord *));.
98c0: 20 20 69 66 28 20 21 61 53 6c 6f 74 20 29 7b 0a    if( !aSlot ){.
98d0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
98e0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20  E_NOMEM;.  }..  
98f0: 70 20 3d 20 70 4c 69 73 74 2d 3e 70 4c 69 73 74  p = pList->pList
9900: 3b 0a 20 20 77 68 69 6c 65 28 20 70 20 29 7b 0a  ;.  while( p ){.
9910: 20 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64      SorterRecord
9920: 20 2a 70 4e 65 78 74 3b 0a 20 20 20 20 69 66 28   *pNext;.    if(
9930: 20 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f 72 79 20   pList->aMemory 
9940: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 28 75 38  ){.      if( (u8
9950: 2a 29 70 3d 3d 70 4c 69 73 74 2d 3e 61 4d 65 6d  *)p==pList->aMem
9960: 6f 72 79 20 29 7b 0a 20 20 20 20 20 20 20 20 70  ory ){.        p
9970: 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 20 20  Next = 0;.      
9980: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 61  }else{.        a
9990: 73 73 65 72 74 28 20 70 2d 3e 75 2e 69 4e 65 78  ssert( p->u.iNex
99a0: 74 3c 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53  t<sqlite3MallocS
99b0: 69 7a 65 28 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f  ize(pList->aMemo
99c0: 72 79 29 20 29 3b 0a 20 20 20 20 20 20 20 20 70  ry) );.        p
99d0: 4e 65 78 74 20 3d 20 28 53 6f 72 74 65 72 52 65  Next = (SorterRe
99e0: 63 6f 72 64 2a 29 26 70 4c 69 73 74 2d 3e 61 4d  cord*)&pList->aM
99f0: 65 6d 6f 72 79 5b 70 2d 3e 75 2e 69 4e 65 78 74  emory[p->u.iNext
9a00: 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  ];.      }.    }
9a10: 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 4e 65 78  else{.      pNex
9a20: 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74 3b 0a  t = p->u.pNext;.
9a30: 20 20 20 20 7d 0a 0a 20 20 20 20 70 2d 3e 75 2e      }..    p->u.
9a40: 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 66  pNext = 0;.    f
9a50: 6f 72 28 69 3d 30 3b 20 61 53 6c 6f 74 5b 69 5d  or(i=0; aSlot[i]
9a60: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 76 64  ; i++){.      vd
9a70: 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28 70 54  beSorterMerge(pT
9a80: 61 73 6b 2c 20 70 2c 20 61 53 6c 6f 74 5b 69 5d  ask, p, aSlot[i]
9a90: 2c 20 26 70 29 3b 0a 20 20 20 20 20 20 61 53 6c  , &p);.      aSl
9aa0: 6f 74 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 7d  ot[i] = 0;.    }
9ab0: 0a 20 20 20 20 61 53 6c 6f 74 5b 69 5d 20 3d 20  .    aSlot[i] = 
9ac0: 70 3b 0a 20 20 20 20 70 20 3d 20 70 4e 65 78 74  p;.    p = pNext
9ad0: 3b 0a 20 20 7d 0a 0a 20 20 70 20 3d 20 30 3b 0a  ;.  }..  p = 0;.
9ae0: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 36 34 3b    for(i=0; i<64;
9af0: 20 69 2b 2b 29 7b 0a 20 20 20 20 76 64 62 65 53   i++){.    vdbeS
9b00: 6f 72 74 65 72 4d 65 72 67 65 28 70 54 61 73 6b  orterMerge(pTask
9b10: 2c 20 70 2c 20 61 53 6c 6f 74 5b 69 5d 2c 20 26  , p, aSlot[i], &
9b20: 70 29 3b 0a 20 20 7d 0a 20 20 70 4c 69 73 74 2d  p);.  }.  pList-
9b30: 3e 70 4c 69 73 74 20 3d 20 70 3b 0a 0a 20 20 73  >pList = p;..  s
9b40: 71 6c 69 74 65 33 5f 66 72 65 65 28 61 53 6c 6f  qlite3_free(aSlo
9b50: 74 29 3b 0a 20 20 69 66 28 20 70 54 61 73 6b 2d  t);.  if( pTask-
9b60: 3e 70 55 6e 70 61 63 6b 65 64 2d 3e 65 72 72 43  >pUnpacked->errC
9b70: 6f 64 65 20 29 7b 0a 20 20 20 20 61 73 73 65 72  ode ){.    asser
9b80: 74 28 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63  t( pTask->pUnpac
9b90: 6b 65 64 2d 3e 65 72 72 43 6f 64 65 3d 3d 53 51  ked->errCode==SQ
9ba0: 4c 49 54 45 5f 4e 4f 4d 45 4d 20 29 3b 0a 20 20  LITE_NOMEM );.  
9bb0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
9bc0: 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 72 65 74  NOMEM;.  }.  ret
9bd0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
9be0: 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69  ../*.** Initiali
9bf0: 7a 65 20 61 20 50 4d 41 2d 77 72 69 74 65 72 20  ze a PMA-writer 
9c00: 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74 61 74 69  object..*/.stati
9c10: 63 20 76 6f 69 64 20 76 64 62 65 50 6d 61 57 72  c void vdbePmaWr
9c20: 69 74 65 72 49 6e 69 74 28 0a 20 20 73 71 6c 69  iterInit(.  sqli
9c30: 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c  te3_file *pFile,
9c40: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
9c50: 69 6c 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20  ile to write to 
9c60: 2a 2f 0a 20 20 50 6d 61 57 72 69 74 65 72 20 2a  */.  PmaWriter *
9c70: 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p,              
9c80: 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63 74 20 74       /* Object t
9c90: 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f 0a 20 20  o populate */.  
9ca0: 69 6e 74 20 6e 42 75 66 2c 20 20 20 20 20 20 20  int nBuf,       
9cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9cc0: 2f 2a 20 42 75 66 66 65 72 20 73 69 7a 65 20 2a  /* Buffer size *
9cd0: 2f 0a 20 20 69 36 34 20 69 53 74 61 72 74 20 20  /.  i64 iStart  
9ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9cf0: 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 6f 66      /* Offset of
9d00: 20 70 46 69 6c 65 20 74 6f 20 62 65 67 69 6e 20   pFile to begin 
9d10: 77 72 69 74 69 6e 67 20 61 74 20 2a 2f 0a 29 7b  writing at */.){
9d20: 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20  .  memset(p, 0, 
9d30: 73 69 7a 65 6f 66 28 50 6d 61 57 72 69 74 65 72  sizeof(PmaWriter
9d40: 29 29 3b 0a 20 20 70 2d 3e 61 42 75 66 66 65 72  ));.  p->aBuffer
9d50: 20 3d 20 28 75 38 2a 29 73 71 6c 69 74 65 33 4d   = (u8*)sqlite3M
9d60: 61 6c 6c 6f 63 28 6e 42 75 66 29 3b 0a 20 20 69  alloc(nBuf);.  i
9d70: 66 28 20 21 70 2d 3e 61 42 75 66 66 65 72 20 29  f( !p->aBuffer )
9d80: 7b 0a 20 20 20 20 70 2d 3e 65 46 57 45 72 72 20  {.    p->eFWErr 
9d90: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
9da0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 2d 3e    }else{.    p->
9db0: 69 42 75 66 45 6e 64 20 3d 20 70 2d 3e 69 42 75  iBufEnd = p->iBu
9dc0: 66 53 74 61 72 74 20 3d 20 28 69 53 74 61 72 74  fStart = (iStart
9dd0: 20 25 20 6e 42 75 66 29 3b 0a 20 20 20 20 70 2d   % nBuf);.    p-
9de0: 3e 69 57 72 69 74 65 4f 66 66 20 3d 20 69 53 74  >iWriteOff = iSt
9df0: 61 72 74 20 2d 20 70 2d 3e 69 42 75 66 53 74 61  art - p->iBufSta
9e00: 72 74 3b 0a 20 20 20 20 70 2d 3e 6e 42 75 66 66  rt;.    p->nBuff
9e10: 65 72 20 3d 20 6e 42 75 66 3b 0a 20 20 20 20 70  er = nBuf;.    p
9e20: 2d 3e 70 46 69 6c 65 20 3d 20 70 46 69 6c 65 3b  ->pFile = pFile;
9e30: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72  .  }.}../*.** Wr
9e40: 69 74 65 20 6e 44 61 74 61 20 62 79 74 65 73 20  ite nData bytes 
9e50: 6f 66 20 64 61 74 61 20 74 6f 20 74 68 65 20 50  of data to the P
9e60: 4d 41 2e 20 52 65 74 75 72 6e 20 53 51 4c 49 54  MA. Return SQLIT
9e70: 45 5f 4f 4b 0a 2a 2a 20 69 66 20 73 75 63 63 65  E_OK.** if succe
9e80: 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c  ssful, or an SQL
9e90: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69  ite error code i
9ea0: 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
9eb0: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  s..*/.static voi
9ec0: 64 20 76 64 62 65 50 6d 61 57 72 69 74 65 42 6c  d vdbePmaWriteBl
9ed0: 6f 62 28 50 6d 61 57 72 69 74 65 72 20 2a 70 2c  ob(PmaWriter *p,
9ee0: 20 75 38 20 2a 70 44 61 74 61 2c 20 69 6e 74 20   u8 *pData, int 
9ef0: 6e 44 61 74 61 29 7b 0a 20 20 69 6e 74 20 6e 52  nData){.  int nR
9f00: 65 6d 20 3d 20 6e 44 61 74 61 3b 0a 20 20 77 68  em = nData;.  wh
9f10: 69 6c 65 28 20 6e 52 65 6d 3e 30 20 26 26 20 70  ile( nRem>0 && p
9f20: 2d 3e 65 46 57 45 72 72 3d 3d 30 20 29 7b 0a 20  ->eFWErr==0 ){. 
9f30: 20 20 20 69 6e 74 20 6e 43 6f 70 79 20 3d 20 6e     int nCopy = n
9f40: 52 65 6d 3b 0a 20 20 20 20 69 66 28 20 6e 43 6f  Rem;.    if( nCo
9f50: 70 79 3e 28 70 2d 3e 6e 42 75 66 66 65 72 20 2d  py>(p->nBuffer -
9f60: 20 70 2d 3e 69 42 75 66 45 6e 64 29 20 29 7b 0a   p->iBufEnd) ){.
9f70: 20 20 20 20 20 20 6e 43 6f 70 79 20 3d 20 70 2d        nCopy = p-
9f80: 3e 6e 42 75 66 66 65 72 20 2d 20 70 2d 3e 69 42  >nBuffer - p->iB
9f90: 75 66 45 6e 64 3b 0a 20 20 20 20 7d 0a 0a 20 20  ufEnd;.    }..  
9fa0: 20 20 6d 65 6d 63 70 79 28 26 70 2d 3e 61 42 75    memcpy(&p->aBu
9fb0: 66 66 65 72 5b 70 2d 3e 69 42 75 66 45 6e 64 5d  ffer[p->iBufEnd]
9fc0: 2c 20 26 70 44 61 74 61 5b 6e 44 61 74 61 2d 6e  , &pData[nData-n
9fd0: 52 65 6d 5d 2c 20 6e 43 6f 70 79 29 3b 0a 20 20  Rem], nCopy);.  
9fe0: 20 20 70 2d 3e 69 42 75 66 45 6e 64 20 2b 3d 20    p->iBufEnd += 
9ff0: 6e 43 6f 70 79 3b 0a 20 20 20 20 69 66 28 20 70  nCopy;.    if( p
a000: 2d 3e 69 42 75 66 45 6e 64 3d 3d 70 2d 3e 6e 42  ->iBufEnd==p->nB
a010: 75 66 66 65 72 20 29 7b 0a 20 20 20 20 20 20 70  uffer ){.      p
a020: 2d 3e 65 46 57 45 72 72 20 3d 20 73 71 6c 69 74  ->eFWErr = sqlit
a030: 65 33 4f 73 57 72 69 74 65 28 70 2d 3e 70 46 69  e3OsWrite(p->pFi
a040: 6c 65 2c 20 0a 20 20 20 20 20 20 20 20 20 20 26  le, .          &
a050: 70 2d 3e 61 42 75 66 66 65 72 5b 70 2d 3e 69 42  p->aBuffer[p->iB
a060: 75 66 53 74 61 72 74 5d 2c 20 70 2d 3e 69 42 75  ufStart], p->iBu
a070: 66 45 6e 64 20 2d 20 70 2d 3e 69 42 75 66 53 74  fEnd - p->iBufSt
a080: 61 72 74 2c 20 0a 20 20 20 20 20 20 20 20 20 20  art, .          
a090: 70 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b 20 70  p->iWriteOff + p
a0a0: 2d 3e 69 42 75 66 53 74 61 72 74 0a 20 20 20 20  ->iBufStart.    
a0b0: 20 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e 69 42    );.      p->iB
a0c0: 75 66 53 74 61 72 74 20 3d 20 70 2d 3e 69 42 75  ufStart = p->iBu
a0d0: 66 45 6e 64 20 3d 20 30 3b 0a 20 20 20 20 20 20  fEnd = 0;.      
a0e0: 70 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b 3d 20  p->iWriteOff += 
a0f0: 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20 20  p->nBuffer;.    
a100: 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 2d  }.    assert( p-
a110: 3e 69 42 75 66 45 6e 64 3c 70 2d 3e 6e 42 75 66  >iBufEnd<p->nBuf
a120: 66 65 72 20 29 3b 0a 0a 20 20 20 20 6e 52 65 6d  fer );..    nRem
a130: 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20 7d 0a 7d   -= nCopy;.  }.}
a140: 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68 20 61 6e  ../*.** Flush an
a150: 79 20 62 75 66 66 65 72 65 64 20 64 61 74 61 20  y buffered data 
a160: 74 6f 20 64 69 73 6b 20 61 6e 64 20 63 6c 65 61  to disk and clea
a170: 6e 20 75 70 20 74 68 65 20 50 4d 41 2d 77 72 69  n up the PMA-wri
a180: 74 65 72 20 6f 62 6a 65 63 74 2e 0a 2a 2a 20 54  ter object..** T
a190: 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20 75 73  he results of us
a1a0: 69 6e 67 20 74 68 65 20 50 4d 41 2d 77 72 69 74  ing the PMA-writ
a1b0: 65 72 20 61 66 74 65 72 20 74 68 69 73 20 63 61  er after this ca
a1c0: 6c 6c 20 61 72 65 20 75 6e 64 65 66 69 6e 65 64  ll are undefined
a1d0: 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 53 51 4c 49  ..** Return SQLI
a1e0: 54 45 5f 4f 4b 20 69 66 20 66 6c 75 73 68 69 6e  TE_OK if flushin
a1f0: 67 20 74 68 65 20 62 75 66 66 65 72 65 64 20 64  g the buffered d
a200: 61 74 61 20 73 75 63 63 65 65 64 73 20 6f 72 20  ata succeeds or 
a210: 69 73 20 6e 6f 74 20 0a 2a 2a 20 72 65 71 75 69  is not .** requi
a220: 72 65 64 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  red. Otherwise, 
a230: 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74 65  return an SQLite
a240: 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a   error code..**.
a250: 2a 2a 20 42 65 66 6f 72 65 20 72 65 74 75 72 6e  ** Before return
a260: 69 6e 67 2c 20 73 65 74 20 2a 70 69 45 6f 66 20  ing, set *piEof 
a270: 74 6f 20 74 68 65 20 6f 66 66 73 65 74 20 69 6d  to the offset im
a280: 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77  mediately follow
a290: 69 6e 67 20 74 68 65 0a 2a 2a 20 6c 61 73 74 20  ing the.** last 
a2a0: 62 79 74 65 20 77 72 69 74 74 65 6e 20 74 6f 20  byte written to 
a2b0: 74 68 65 20 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61  the file..*/.sta
a2c0: 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d 61 57  tic int vdbePmaW
a2d0: 72 69 74 65 72 46 69 6e 69 73 68 28 50 6d 61 57  riterFinish(PmaW
a2e0: 72 69 74 65 72 20 2a 70 2c 20 69 36 34 20 2a 70  riter *p, i64 *p
a2f0: 69 45 6f 66 29 7b 0a 20 20 69 6e 74 20 72 63 3b  iEof){.  int rc;
a300: 0a 20 20 69 66 28 20 70 2d 3e 65 46 57 45 72 72  .  if( p->eFWErr
a310: 3d 3d 30 20 26 26 20 41 4c 57 41 59 53 28 70 2d  ==0 && ALWAYS(p-
a320: 3e 61 42 75 66 66 65 72 29 20 26 26 20 70 2d 3e  >aBuffer) && p->
a330: 69 42 75 66 45 6e 64 3e 70 2d 3e 69 42 75 66 53  iBufEnd>p->iBufS
a340: 74 61 72 74 20 29 7b 0a 20 20 20 20 70 2d 3e 65  tart ){.    p->e
a350: 46 57 45 72 72 20 3d 20 73 71 6c 69 74 65 33 4f  FWErr = sqlite3O
a360: 73 57 72 69 74 65 28 70 2d 3e 70 46 69 6c 65 2c  sWrite(p->pFile,
a370: 20 0a 20 20 20 20 20 20 20 20 26 70 2d 3e 61 42   .        &p->aB
a380: 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 53 74 61  uffer[p->iBufSta
a390: 72 74 5d 2c 20 70 2d 3e 69 42 75 66 45 6e 64 20  rt], p->iBufEnd 
a3a0: 2d 20 70 2d 3e 69 42 75 66 53 74 61 72 74 2c 20  - p->iBufStart, 
a3b0: 0a 20 20 20 20 20 20 20 20 70 2d 3e 69 57 72 69  .        p->iWri
a3c0: 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42 75 66 53  teOff + p->iBufS
a3d0: 74 61 72 74 0a 20 20 20 20 29 3b 0a 20 20 7d 0a  tart.    );.  }.
a3e0: 20 20 2a 70 69 45 6f 66 20 3d 20 28 70 2d 3e 69    *piEof = (p->i
a3f0: 57 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42  WriteOff + p->iB
a400: 75 66 45 6e 64 29 3b 0a 20 20 73 71 6c 69 74 65  ufEnd);.  sqlite
a410: 33 5f 66 72 65 65 28 70 2d 3e 61 42 75 66 66 65  3_free(p->aBuffe
a420: 72 29 3b 0a 20 20 72 63 20 3d 20 70 2d 3e 65 46  r);.  rc = p->eF
a430: 57 45 72 72 3b 0a 20 20 6d 65 6d 73 65 74 28 70  WErr;.  memset(p
a440: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50 6d 61 57  , 0, sizeof(PmaW
a450: 72 69 74 65 72 29 29 3b 0a 20 20 72 65 74 75 72  riter));.  retur
a460: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57  n rc;.}../*.** W
a470: 72 69 74 65 20 76 61 6c 75 65 20 69 56 61 6c 20  rite value iVal 
a480: 65 6e 63 6f 64 65 64 20 61 73 20 61 20 76 61 72  encoded as a var
a490: 69 6e 74 20 74 6f 20 74 68 65 20 50 4d 41 2e 20  int to the PMA. 
a4a0: 52 65 74 75 72 6e 20 0a 2a 2a 20 53 51 4c 49 54  Return .** SQLIT
a4b0: 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66  E_OK if successf
a4c0: 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65  ul, or an SQLite
a4d0: 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20 61   error code if a
a4e0: 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a  n error occurs..
a4f0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76  */.static void v
a500: 64 62 65 50 6d 61 57 72 69 74 65 56 61 72 69 6e  dbePmaWriteVarin
a510: 74 28 50 6d 61 57 72 69 74 65 72 20 2a 70 2c 20  t(PmaWriter *p, 
a520: 75 36 34 20 69 56 61 6c 29 7b 0a 20 20 69 6e 74  u64 iVal){.  int
a530: 20 6e 42 79 74 65 3b 20 0a 20 20 75 38 20 61 42   nByte; .  u8 aB
a540: 79 74 65 5b 31 30 5d 3b 0a 20 20 6e 42 79 74 65  yte[10];.  nByte
a550: 20 3d 20 73 71 6c 69 74 65 33 50 75 74 56 61 72   = sqlite3PutVar
a560: 69 6e 74 28 61 42 79 74 65 2c 20 69 56 61 6c 29  int(aByte, iVal)
a570: 3b 0a 20 20 76 64 62 65 50 6d 61 57 72 69 74 65  ;.  vdbePmaWrite
a580: 42 6c 6f 62 28 70 2c 20 61 42 79 74 65 2c 20 6e  Blob(p, aByte, n
a590: 42 79 74 65 29 3b 0a 7d 0a 0a 23 69 66 20 53 51  Byte);.}..#if SQ
a5a0: 4c 49 54 45 5f 4d 41 58 5f 4d 4d 41 50 5f 53 49  LITE_MAX_MMAP_SI
a5b0: 5a 45 3e 30 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66  ZE>0./*.** The f
a5c0: 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 69 73  irst argument is
a5d0: 20 61 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20 6f   a file-handle o
a5e0: 70 65 6e 20 6f 6e 20 61 20 74 65 6d 70 6f 72 61  pen on a tempora
a5f0: 72 79 20 66 69 6c 65 2e 20 54 68 65 20 66 69 6c  ry file. The fil
a600: 65 0a 2a 2a 20 69 73 20 67 75 61 72 61 6e 74 65  e.** is guarante
a610: 65 64 20 74 6f 20 62 65 20 6e 42 79 74 65 20 62  ed to be nByte b
a620: 79 74 65 73 20 6f 72 20 73 6d 61 6c 6c 65 72 20  ytes or smaller 
a630: 69 6e 20 73 69 7a 65 2e 20 54 68 69 73 20 66 75  in size. This fu
a640: 6e 63 74 69 6f 6e 0a 2a 2a 20 61 74 74 65 6d 70  nction.** attemp
a650: 74 73 20 74 6f 20 65 78 74 65 6e 64 20 74 68 65  ts to extend the
a660: 20 66 69 6c 65 20 74 6f 20 6e 42 79 74 65 20 62   file to nByte b
a670: 79 74 65 73 20 69 6e 20 73 69 7a 65 20 61 6e 64  ytes in size and
a680: 20 74 6f 20 65 6e 73 75 72 65 20 74 68 61 74 0a   to ensure that.
a690: 2a 2a 20 74 68 65 20 56 46 53 20 68 61 73 20 6d  ** the VFS has m
a6a0: 65 6d 6f 72 79 20 6d 61 70 70 65 64 20 69 74 2e  emory mapped it.
a6b0: 0a 2a 2a 0a 2a 2a 20 57 68 65 74 68 65 72 20 6f  .**.** Whether o
a6c0: 72 20 6e 6f 74 20 74 68 65 20 66 69 6c 65 20 64  r not the file d
a6d0: 6f 65 73 20 65 6e 64 20 75 70 20 6d 65 6d 6f 72  oes end up memor
a6e0: 79 20 6d 61 70 70 65 64 20 6f 66 20 63 6f 75 72  y mapped of cour
a6f0: 73 65 20 64 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a  se depends on.**
a700: 20 74 68 65 20 73 70 65 63 69 66 69 63 20 56 46   the specific VF
a710: 53 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  S implementation
a720: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
a730: 20 76 64 62 65 53 6f 72 74 65 72 45 78 74 65 6e   vdbeSorterExten
a740: 64 46 69 6c 65 28 73 71 6c 69 74 65 33 20 2a 64  dFile(sqlite3 *d
a750: 62 2c 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  b, sqlite3_file 
a760: 2a 70 46 69 6c 65 2c 20 69 36 34 20 6e 42 79 74  *pFile, i64 nByt
a770: 65 29 7b 0a 20 20 69 66 28 20 6e 42 79 74 65 3c  e){.  if( nByte<
a780: 3d 28 69 36 34 29 28 64 62 2d 3e 6e 4d 61 78 53  =(i64)(db->nMaxS
a790: 6f 72 74 65 72 4d 6d 61 70 29 20 29 7b 0a 20 20  orterMmap) ){.  
a7a0: 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 69 74    int rc = sqlit
a7b0: 65 33 4f 73 54 72 75 6e 63 61 74 65 28 70 46 69  e3OsTruncate(pFi
a7c0: 6c 65 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20  le, nByte);.    
a7d0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
a7e0: 4b 20 29 7b 0a 20 20 20 20 20 20 76 6f 69 64 20  K ){.      void 
a7f0: 2a 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 73 71  *p = 0;.      sq
a800: 6c 69 74 65 33 4f 73 46 65 74 63 68 28 70 46 69  lite3OsFetch(pFi
a810: 6c 65 2c 20 30 2c 20 6e 42 79 74 65 2c 20 26 70  le, 0, nByte, &p
a820: 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  );.      sqlite3
a830: 4f 73 55 6e 66 65 74 63 68 28 70 46 69 6c 65 2c  OsUnfetch(pFile,
a840: 20 30 2c 20 70 29 3b 0a 20 20 20 20 7d 0a 20 20   0, p);.    }.  
a850: 7d 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65 66 69  }.}.#else.# defi
a860: 6e 65 20 76 64 62 65 53 6f 72 74 65 72 45 78 74  ne vdbeSorterExt
a870: 65 6e 64 46 69 6c 65 28 78 2c 79 2c 7a 29 20 53  endFile(x,y,z) S
a880: 51 4c 49 54 45 5f 4f 4b 0a 23 65 6e 64 69 66 0a  QLITE_OK.#endif.
a890: 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 74 68  ../*.** Write th
a8a0: 65 20 63 75 72 72 65 6e 74 20 63 6f 6e 74 65 6e  e current conten
a8b0: 74 73 20 6f 66 20 69 6e 2d 6d 65 6d 6f 72 79 20  ts of in-memory 
a8c0: 6c 69 6e 6b 65 64 2d 6c 69 73 74 20 70 4c 69 73  linked-list pLis
a8d0: 74 20 74 6f 20 61 20 6c 65 76 65 6c 2d 30 0a 2a  t to a level-0.*
a8e0: 2a 20 50 4d 41 20 69 6e 20 74 68 65 20 74 65 6d  * PMA in the tem
a8f0: 70 20 66 69 6c 65 20 62 65 6c 6f 6e 67 69 6e 67  p file belonging
a900: 20 74 6f 20 73 75 62 2d 74 61 73 6b 20 70 54 61   to sub-task pTa
a910: 73 6b 2e 20 52 65 74 75 72 6e 20 53 51 4c 49 54  sk. Return SQLIT
a920: 45 5f 4f 4b 20 69 66 20 0a 2a 2a 20 73 75 63 63  E_OK if .** succ
a930: 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51  essful, or an SQ
a940: 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20  Lite error code 
a950: 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2a 0a 2a 2a  otherwise..**.**
a960: 20 54 68 65 20 66 6f 72 6d 61 74 20 6f 66 20 61   The format of a
a970: 20 50 4d 41 20 69 73 3a 0a 2a 2a 0a 2a 2a 20 20   PMA is:.**.**  
a980: 20 20 20 2a 20 41 20 76 61 72 69 6e 74 2e 20 54     * A varint. T
a990: 68 69 73 20 76 61 72 69 6e 74 20 63 6f 6e 74 61  his varint conta
a9a0: 69 6e 73 20 74 68 65 20 74 6f 74 61 6c 20 6e 75  ins the total nu
a9b0: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66  mber of bytes of
a9c0: 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20 20 20 20 20   content.**     
a9d0: 20 20 69 6e 20 74 68 65 20 50 4d 41 20 28 6e 6f    in the PMA (no
a9e0: 74 20 69 6e 63 6c 75 64 69 6e 67 20 74 68 65 20  t including the 
a9f0: 76 61 72 69 6e 74 20 69 74 73 65 6c 66 29 2e 0a  varint itself)..
aa00: 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 4f 6e 65 20  **.**     * One 
aa10: 6f 72 20 6d 6f 72 65 20 72 65 63 6f 72 64 73 20  or more records 
aa20: 70 61 63 6b 65 64 20 65 6e 64 2d 74 6f 2d 65 6e  packed end-to-en
aa30: 64 20 69 6e 20 6f 72 64 65 72 20 6f 66 20 61 73  d in order of as
aa40: 63 65 6e 64 69 6e 67 20 6b 65 79 73 2e 20 0a 2a  cending keys. .*
aa50: 2a 20 20 20 20 20 20 20 45 61 63 68 20 72 65 63  *       Each rec
aa60: 6f 72 64 20 63 6f 6e 73 69 73 74 73 20 6f 66 20  ord consists of 
aa70: 61 20 76 61 72 69 6e 74 20 66 6f 6c 6c 6f 77 65  a varint followe
aa80: 64 20 62 79 20 61 20 62 6c 6f 62 20 6f 66 20 64  d by a blob of d
aa90: 61 74 61 20 28 74 68 65 20 0a 2a 2a 20 20 20 20  ata (the .**    
aaa0: 20 20 20 6b 65 79 29 2e 20 54 68 65 20 76 61 72     key). The var
aab0: 69 6e 74 20 69 73 20 74 68 65 20 6e 75 6d 62 65  int is the numbe
aac0: 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 74 68  r of bytes in th
aad0: 65 20 62 6c 6f 62 20 6f 66 20 64 61 74 61 2e 0a  e blob of data..
aae0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
aaf0: 62 65 53 6f 72 74 65 72 4c 69 73 74 54 6f 50 4d  beSorterListToPM
ab00: 41 28 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70  A(SortSubtask *p
ab10: 54 61 73 6b 2c 20 53 6f 72 74 65 72 4c 69 73 74  Task, SorterList
ab20: 20 2a 70 4c 69 73 74 29 7b 0a 20 20 69 6e 74 20   *pList){.  int 
ab30: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20  rc = SQLITE_OK; 
ab40: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
ab50: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
ab60: 50 6d 61 57 72 69 74 65 72 20 77 72 69 74 65 72  PmaWriter writer
ab70: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
ab80: 2f 2a 20 4f 62 6a 65 63 74 20 75 73 65 64 20 74  /* Object used t
ab90: 6f 20 77 72 69 74 65 20 74 6f 20 74 68 65 20 66  o write to the f
aba0: 69 6c 65 20 2a 2f 0a 0a 23 69 66 64 65 66 20 53  ile */..#ifdef S
abb0: 51 4c 49 54 45 5f 44 45 42 55 47 0a 20 20 2f 2a  QLITE_DEBUG.  /*
abc0: 20 53 65 74 20 69 53 7a 20 74 6f 20 74 68 65 20   Set iSz to the 
abd0: 65 78 70 65 63 74 65 64 20 73 69 7a 65 20 6f 66  expected size of
abe0: 20 66 69 6c 65 20 70 54 61 73 6b 2d 3e 66 69 6c   file pTask->fil
abf0: 65 20 61 66 74 65 72 20 77 72 69 74 69 6e 67 20  e after writing 
ac00: 74 68 65 20 50 4d 41 2e 20 0a 20 20 2a 2a 20 54  the PMA. .  ** T
ac10: 68 69 73 20 69 73 20 75 73 65 64 20 62 79 20 61  his is used by a
ac20: 6e 20 61 73 73 65 72 74 28 29 20 73 74 61 74 65  n assert() state
ac30: 6d 65 6e 74 20 61 74 20 74 68 65 20 65 6e 64 20  ment at the end 
ac40: 6f 66 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  of this function
ac50: 2e 20 20 2a 2f 0a 20 20 69 36 34 20 69 53 7a 20  .  */.  i64 iSz 
ac60: 3d 20 70 4c 69 73 74 2d 3e 73 7a 50 4d 41 20 2b  = pList->szPMA +
ac70: 20 73 71 6c 69 74 65 33 56 61 72 69 6e 74 4c 65   sqlite3VarintLe
ac80: 6e 28 70 4c 69 73 74 2d 3e 73 7a 50 4d 41 29 20  n(pList->szPMA) 
ac90: 2b 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45  + pTask->file.iE
aca0: 6f 66 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 76 64  of;.#endif..  vd
acb0: 62 65 53 6f 72 74 65 72 57 6f 72 6b 44 65 62 75  beSorterWorkDebu
acc0: 67 28 70 54 61 73 6b 2c 20 22 65 6e 74 65 72 22  g(pTask, "enter"
acd0: 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 77 72 69  );.  memset(&wri
ace0: 74 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50  ter, 0, sizeof(P
acf0: 6d 61 57 72 69 74 65 72 29 29 3b 0a 20 20 61 73  maWriter));.  as
ad00: 73 65 72 74 28 20 70 4c 69 73 74 2d 3e 73 7a 50  sert( pList->szP
ad10: 4d 41 3e 30 20 29 3b 0a 0a 20 20 2f 2a 20 49 66  MA>0 );..  /* If
ad20: 20 74 68 65 20 66 69 72 73 74 20 74 65 6d 70 6f   the first tempo
ad30: 72 61 72 79 20 50 4d 41 20 66 69 6c 65 20 68 61  rary PMA file ha
ad40: 73 20 6e 6f 74 20 62 65 65 6e 20 6f 70 65 6e 65  s not been opene
ad50: 64 2c 20 6f 70 65 6e 20 69 74 20 6e 6f 77 2e 20  d, open it now. 
ad60: 2a 2f 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e  */.  if( pTask->
ad70: 66 69 6c 65 2e 70 46 64 3d 3d 30 20 29 7b 0a 20  file.pFd==0 ){. 
ad80: 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74     rc = vdbeSort
ad90: 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 70  erOpenTempFile(p
ada0: 54 61 73 6b 2d 3e 64 62 2d 3e 70 56 66 73 2c 20  Task->db->pVfs, 
adb0: 26 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64  &pTask->file.pFd
adc0: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 72  );.    assert( r
add0: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20  c!=SQLITE_OK || 
ade0: 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64 20  pTask->file.pFd 
adf0: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
ae00: 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 3d  Task->file.iEof=
ae10: 3d 30 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  =0 );.    assert
ae20: 28 20 70 54 61 73 6b 2d 3e 6e 50 4d 41 3d 3d 30  ( pTask->nPMA==0
ae30: 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54 72   );.  }..  /* Tr
ae40: 79 20 74 6f 20 67 65 74 20 74 68 65 20 66 69 6c  y to get the fil
ae50: 65 20 74 6f 20 6d 65 6d 6f 72 79 20 6d 61 70 20  e to memory map 
ae60: 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  */.  if( rc==SQL
ae70: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 64  ITE_OK ){.    vd
ae80: 62 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46 69  beSorterExtendFi
ae90: 6c 65 28 70 54 61 73 6b 2d 3e 64 62 2c 20 0a 20  le(pTask->db, . 
aea0: 20 20 20 20 20 20 20 70 54 61 73 6b 2d 3e 66 69         pTask->fi
aeb0: 6c 65 2e 70 46 64 2c 20 70 54 61 73 6b 2d 3e 66  le.pFd, pTask->f
aec0: 69 6c 65 2e 69 45 6f 66 20 2b 20 70 4c 69 73 74  ile.iEof + pList
aed0: 2d 3e 73 7a 50 4d 41 20 2b 20 39 0a 20 20 20 20  ->szPMA + 9.    
aee0: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 6f 72  );.  }..  /* Sor
aef0: 74 20 74 68 65 20 6c 69 73 74 20 2a 2f 0a 20 20  t the list */.  
af00: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
af10: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64  K ){.    rc = vd
af20: 62 65 53 6f 72 74 65 72 53 6f 72 74 28 70 54 61  beSorterSort(pTa
af30: 73 6b 2c 20 70 4c 69 73 74 29 3b 0a 20 20 7d 0a  sk, pList);.  }.
af40: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
af50: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 53 6f 72 74  E_OK ){.    Sort
af60: 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a 20 20 20  erRecord *p;.   
af70: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
af80: 4e 65 78 74 20 3d 20 30 3b 0a 0a 20 20 20 20 76  Next = 0;..    v
af90: 64 62 65 50 6d 61 57 72 69 74 65 72 49 6e 69 74  dbePmaWriterInit
afa0: 28 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64  (pTask->file.pFd
afb0: 2c 20 26 77 72 69 74 65 72 2c 20 70 54 61 73 6b  , &writer, pTask
afc0: 2d 3e 70 67 73 7a 2c 0a 20 20 20 20 20 20 20 20  ->pgsz,.        
afd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 54                pT
afe0: 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 29 3b  ask->file.iEof);
aff0: 0a 20 20 20 20 70 54 61 73 6b 2d 3e 6e 50 4d 41  .    pTask->nPMA
b000: 2b 2b 3b 0a 20 20 20 20 76 64 62 65 50 6d 61 57  ++;.    vdbePmaW
b010: 72 69 74 65 56 61 72 69 6e 74 28 26 77 72 69 74  riteVarint(&writ
b020: 65 72 2c 20 70 4c 69 73 74 2d 3e 73 7a 50 4d 41  er, pList->szPMA
b030: 29 3b 0a 20 20 20 20 66 6f 72 28 70 3d 70 4c 69  );.    for(p=pLi
b040: 73 74 2d 3e 70 4c 69 73 74 3b 20 70 3b 20 70 3d  st->pList; p; p=
b050: 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 70 4e  pNext){.      pN
b060: 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74  ext = p->u.pNext
b070: 3b 0a 20 20 20 20 20 20 76 64 62 65 50 6d 61 57  ;.      vdbePmaW
b080: 72 69 74 65 56 61 72 69 6e 74 28 26 77 72 69 74  riteVarint(&writ
b090: 65 72 2c 20 70 2d 3e 6e 56 61 6c 29 3b 0a 20 20  er, p->nVal);.  
b0a0: 20 20 20 20 76 64 62 65 50 6d 61 57 72 69 74 65      vdbePmaWrite
b0b0: 42 6c 6f 62 28 26 77 72 69 74 65 72 2c 20 53 52  Blob(&writer, SR
b0c0: 56 41 4c 28 70 29 2c 20 70 2d 3e 6e 56 61 6c 29  VAL(p), p->nVal)
b0d0: 3b 0a 20 20 20 20 20 20 69 66 28 20 70 4c 69 73  ;.      if( pLis
b0e0: 74 2d 3e 61 4d 65 6d 6f 72 79 3d 3d 30 20 29 20  t->aMemory==0 ) 
b0f0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b  sqlite3_free(p);
b100: 0a 20 20 20 20 7d 0a 20 20 20 20 70 4c 69 73 74  .    }.    pList
b110: 2d 3e 70 4c 69 73 74 20 3d 20 70 3b 0a 20 20 20  ->pList = p;.   
b120: 20 72 63 20 3d 20 76 64 62 65 50 6d 61 57 72 69   rc = vdbePmaWri
b130: 74 65 72 46 69 6e 69 73 68 28 26 77 72 69 74 65  terFinish(&write
b140: 72 2c 20 26 70 54 61 73 6b 2d 3e 66 69 6c 65 2e  r, &pTask->file.
b150: 69 45 6f 66 29 3b 0a 20 20 7d 0a 0a 20 20 76 64  iEof);.  }..  vd
b160: 62 65 53 6f 72 74 65 72 57 6f 72 6b 44 65 62 75  beSorterWorkDebu
b170: 67 28 70 54 61 73 6b 2c 20 22 65 78 69 74 22 29  g(pTask, "exit")
b180: 3b 0a 20 20 61 73 73 65 72 74 28 20 72 63 21 3d  ;.  assert( rc!=
b190: 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 4c 69  SQLITE_OK || pLi
b1a0: 73 74 2d 3e 70 4c 69 73 74 3d 3d 30 20 29 3b 0a  st->pList==0 );.
b1b0: 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51    assert( rc!=SQ
b1c0: 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 54 61 73 6b  LITE_OK || pTask
b1d0: 2d 3e 66 69 6c 65 2e 69 45 6f 66 3d 3d 69 53 7a  ->file.iEof==iSz
b1e0: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   );.  return rc;
b1f0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63  .}../*.** Advanc
b200: 65 20 74 68 65 20 4d 65 72 67 65 45 6e 67 69 6e  e the MergeEngin
b210: 65 20 69 74 65 72 61 74 6f 72 20 70 61 73 73 65  e iterator passe
b220: 64 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64 20  d as the second 
b230: 61 72 67 75 6d 65 6e 74 20 74 6f 0a 2a 2a 20 74  argument to.** t
b240: 68 65 20 6e 65 78 74 20 65 6e 74 72 79 2e 20 53  he next entry. S
b250: 65 74 20 2a 70 62 45 6f 66 20 74 6f 20 74 72 75  et *pbEof to tru
b260: 65 20 69 66 20 74 68 69 73 20 6d 65 61 6e 73 20  e if this means 
b270: 74 68 65 20 69 74 65 72 61 74 6f 72 20 68 61 73  the iterator has
b280: 20 0a 2a 2a 20 72 65 61 63 68 65 64 20 45 4f 46   .** reached EOF
b290: 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 53  ..**.** Return S
b2a0: 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63  QLITE_OK if succ
b2b0: 65 73 73 66 75 6c 20 6f 72 20 61 6e 20 65 72 72  essful or an err
b2c0: 6f 72 20 63 6f 64 65 20 69 66 20 61 6e 20 65 72  or code if an er
b2d0: 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73  ror occurs..*/.s
b2e0: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
b2f0: 72 74 65 72 4e 65 78 74 28 0a 20 20 53 6f 72 74  rterNext(.  Sort
b300: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20  Subtask *pTask, 
b310: 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a  .  MergeEngine *
b320: 70 4d 65 72 67 65 72 2c 20 0a 20 20 69 6e 74 20  pMerger, .  int 
b330: 2a 70 62 45 6f 66 0a 29 7b 0a 20 20 69 6e 74 20  *pbEof.){.  int 
b340: 72 63 3b 0a 20 20 69 6e 74 20 69 50 72 65 76 20  rc;.  int iPrev 
b350: 3d 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65  = pMerger->aTree
b360: 5b 31 5d 3b 2f 2a 20 49 6e 64 65 78 20 6f 66 20  [1];/* Index of 
b370: 69 74 65 72 61 74 6f 72 20 74 6f 20 61 64 76 61  iterator to adva
b380: 6e 63 65 20 2a 2f 0a 0a 20 20 2f 2a 20 41 64 76  nce */..  /* Adv
b390: 61 6e 63 65 20 74 68 65 20 63 75 72 72 65 6e 74  ance the current
b3a0: 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 72   iterator */.  r
b3b0: 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65  c = vdbePmaReade
b3c0: 72 4e 65 78 74 28 26 70 4d 65 72 67 65 72 2d 3e  rNext(&pMerger->
b3d0: 61 49 74 65 72 5b 69 50 72 65 76 5d 29 3b 0a 0a  aIter[iPrev]);..
b3e0: 20 20 2f 2a 20 55 70 64 61 74 65 20 63 6f 6e 74    /* Update cont
b3f0: 65 6e 74 73 20 6f 66 20 61 54 72 65 65 5b 5d 20  ents of aTree[] 
b400: 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  */.  if( rc==SQL
b410: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e  ITE_OK ){.    in
b420: 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20  t i;            
b430: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64            /* Ind
b440: 65 78 20 6f 66 20 61 54 72 65 65 5b 5d 20 74 6f  ex of aTree[] to
b450: 20 72 65 63 61 6c 63 75 6c 61 74 65 20 2a 2f 0a   recalculate */.
b460: 20 20 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70      PmaReader *p
b470: 49 74 65 72 31 3b 20 20 20 20 20 2f 2a 20 46 69  Iter1;     /* Fi
b480: 72 73 74 20 69 74 65 72 61 74 6f 72 20 74 6f 20  rst iterator to 
b490: 63 6f 6d 70 61 72 65 20 2a 2f 0a 20 20 20 20 50  compare */.    P
b4a0: 6d 61 52 65 61 64 65 72 20 2a 70 49 74 65 72 32  maReader *pIter2
b4b0: 3b 20 20 20 20 20 2f 2a 20 53 65 63 6f 6e 64 20  ;     /* Second 
b4c0: 69 74 65 72 61 74 6f 72 20 74 6f 20 63 6f 6d 70  iterator to comp
b4d0: 61 72 65 20 2a 2f 0a 20 20 20 20 75 38 20 2a 70  are */.    u8 *p
b4e0: 4b 65 79 32 3b 20 20 20 20 20 20 20 20 20 20 20  Key2;           
b4f0: 20 20 20 20 20 20 20 2f 2a 20 54 6f 20 70 49 74         /* To pIt
b500: 65 72 32 2d 3e 61 4b 65 79 2c 20 6f 72 20 30 20  er2->aKey, or 0 
b510: 69 66 20 72 65 63 6f 72 64 20 63 61 63 68 65 64  if record cached
b520: 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 46 69 6e 64   */..    /* Find
b530: 20 74 68 65 20 66 69 72 73 74 20 74 77 6f 20 69   the first two i
b540: 74 65 72 61 74 6f 72 73 20 74 6f 20 63 6f 6d 70  terators to comp
b550: 61 72 65 2e 20 54 68 65 20 6f 6e 65 20 74 68 61  are. The one tha
b560: 74 20 77 61 73 20 6a 75 73 74 0a 20 20 20 20 2a  t was just.    *
b570: 2a 20 61 64 76 61 6e 63 65 64 20 28 69 50 72 65  * advanced (iPre
b580: 76 29 20 61 6e 64 20 74 68 65 20 6f 6e 65 20 6e  v) and the one n
b590: 65 78 74 20 74 6f 20 69 74 20 69 6e 20 74 68 65  ext to it in the
b5a0: 20 61 72 72 61 79 2e 20 20 2a 2f 0a 20 20 20 20   array.  */.    
b5b0: 70 49 74 65 72 31 20 3d 20 26 70 4d 65 72 67 65  pIter1 = &pMerge
b5c0: 72 2d 3e 61 49 74 65 72 5b 28 69 50 72 65 76 20  r->aIter[(iPrev 
b5d0: 26 20 30 78 46 46 46 45 29 5d 3b 0a 20 20 20 20  & 0xFFFE)];.    
b5e0: 70 49 74 65 72 32 20 3d 20 26 70 4d 65 72 67 65  pIter2 = &pMerge
b5f0: 72 2d 3e 61 49 74 65 72 5b 28 69 50 72 65 76 20  r->aIter[(iPrev 
b600: 7c 20 30 78 30 30 30 31 29 5d 3b 0a 20 20 20 20  | 0x0001)];.    
b610: 70 4b 65 79 32 20 3d 20 70 49 74 65 72 32 2d 3e  pKey2 = pIter2->
b620: 61 4b 65 79 3b 0a 0a 20 20 20 20 66 6f 72 28 69  aKey;..    for(i
b630: 3d 28 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65  =(pMerger->nTree
b640: 2b 69 50 72 65 76 29 2f 32 3b 20 69 3e 30 3b 20  +iPrev)/2; i>0; 
b650: 69 3d 69 2f 32 29 7b 0a 20 20 20 20 20 20 2f 2a  i=i/2){.      /*
b660: 20 43 6f 6d 70 61 72 65 20 70 49 74 65 72 31 20   Compare pIter1 
b670: 61 6e 64 20 70 49 74 65 72 32 2e 20 53 74 6f 72  and pIter2. Stor
b680: 65 20 74 68 65 20 72 65 73 75 6c 74 20 69 6e 20  e the result in 
b690: 76 61 72 69 61 62 6c 65 20 69 52 65 73 2e 20 2a  variable iRes. *
b6a0: 2f 0a 20 20 20 20 20 20 69 6e 74 20 69 52 65 73  /.      int iRes
b6b0: 3b 0a 20 20 20 20 20 20 69 66 28 20 70 49 74 65  ;.      if( pIte
b6c0: 72 31 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a  r1->pFile==0 ){.
b6d0: 20 20 20 20 20 20 20 20 69 52 65 73 20 3d 20 2b          iRes = +
b6e0: 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69  1;.      }else i
b6f0: 66 28 20 70 49 74 65 72 32 2d 3e 70 46 69 6c 65  f( pIter2->pFile
b700: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 69  ==0 ){.        i
b710: 52 65 73 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20  Res = -1;.      
b720: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69  }else{.        i
b730: 52 65 73 20 3d 20 76 64 62 65 53 6f 72 74 65 72  Res = vdbeSorter
b740: 43 6f 6d 70 61 72 65 28 70 54 61 73 6b 2c 20 0a  Compare(pTask, .
b750: 20 20 20 20 20 20 20 20 20 20 20 20 70 49 74 65              pIte
b760: 72 31 2d 3e 61 4b 65 79 2c 20 70 49 74 65 72 31  r1->aKey, pIter1
b770: 2d 3e 6e 4b 65 79 2c 20 70 4b 65 79 32 2c 20 70  ->nKey, pKey2, p
b780: 49 74 65 72 32 2d 3e 6e 4b 65 79 0a 20 20 20 20  Iter2->nKey.    
b790: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 7d 0a 0a      );.      }..
b7a0: 20 20 20 20 20 20 2f 2a 20 49 66 20 70 49 74 65        /* If pIte
b7b0: 72 31 20 63 6f 6e 74 61 69 6e 65 64 20 74 68 65  r1 contained the
b7c0: 20 73 6d 61 6c 6c 65 72 20 76 61 6c 75 65 2c 20   smaller value, 
b7d0: 73 65 74 20 61 54 72 65 65 5b 69 5d 20 74 6f 20  set aTree[i] to 
b7e0: 69 74 73 20 69 6e 64 65 78 2e 0a 20 20 20 20 20  its index..     
b7f0: 20 2a 2a 20 54 68 65 6e 20 73 65 74 20 70 49 74   ** Then set pIt
b800: 65 72 32 20 74 6f 20 74 68 65 20 6e 65 78 74 20  er2 to the next 
b810: 69 74 65 72 61 74 6f 72 20 74 6f 20 63 6f 6d 70  iterator to comp
b820: 61 72 65 20 74 6f 20 70 49 74 65 72 31 2e 20 49  are to pIter1. I
b830: 6e 20 74 68 69 73 0a 20 20 20 20 20 20 2a 2a 20  n this.      ** 
b840: 63 61 73 65 20 74 68 65 72 65 20 69 73 20 6e 6f  case there is no
b850: 20 63 61 63 68 65 20 6f 66 20 70 49 74 65 72 32   cache of pIter2
b860: 20 69 6e 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61   in pTask->pUnpa
b870: 63 6b 65 64 2c 20 73 6f 20 73 65 74 0a 20 20 20  cked, so set.   
b880: 20 20 20 2a 2a 20 70 4b 65 79 32 20 74 6f 20 70     ** pKey2 to p
b890: 6f 69 6e 74 20 74 6f 20 74 68 65 20 72 65 63 6f  oint to the reco
b8a0: 72 64 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20  rd belonging to 
b8b0: 70 49 74 65 72 32 2e 0a 20 20 20 20 20 20 2a 2a  pIter2..      **
b8c0: 0a 20 20 20 20 20 20 2a 2a 20 41 6c 74 65 72 6e  .      ** Altern
b8d0: 61 74 69 76 65 6c 79 2c 20 69 66 20 70 49 74 65  atively, if pIte
b8e0: 72 32 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  r2 contains the 
b8f0: 73 6d 61 6c 6c 65 72 20 6f 66 20 74 68 65 20 74  smaller of the t
b900: 77 6f 20 76 61 6c 75 65 73 2c 0a 20 20 20 20 20  wo values,.     
b910: 20 2a 2a 20 73 65 74 20 61 54 72 65 65 5b 69 5d   ** set aTree[i]
b920: 20 74 6f 20 69 74 73 20 69 6e 64 65 78 20 61 6e   to its index an
b930: 64 20 75 70 64 61 74 65 20 70 49 74 65 72 31 2e  d update pIter1.
b940: 20 49 66 20 76 64 62 65 53 6f 72 74 65 72 43 6f   If vdbeSorterCo
b950: 6d 70 61 72 65 28 29 0a 20 20 20 20 20 20 2a 2a  mpare().      **
b960: 20 77 61 73 20 61 63 74 75 61 6c 6c 79 20 63 61   was actually ca
b970: 6c 6c 65 64 20 61 62 6f 76 65 2c 20 74 68 65 6e  lled above, then
b980: 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65   pTask->pUnpacke
b990: 64 20 6e 6f 77 20 63 6f 6e 74 61 69 6e 73 0a 20  d now contains. 
b9a0: 20 20 20 20 20 2a 2a 20 61 20 76 61 6c 75 65 20       ** a value 
b9b0: 65 71 75 69 76 61 6c 65 6e 74 20 74 6f 20 70 49  equivalent to pI
b9c0: 74 65 72 32 2e 20 53 6f 20 73 65 74 20 70 4b 65  ter2. So set pKe
b9d0: 79 32 20 74 6f 20 4e 55 4c 4c 20 74 6f 20 70 72  y2 to NULL to pr
b9e0: 65 76 65 6e 74 0a 20 20 20 20 20 20 2a 2a 20 76  event.      ** v
b9f0: 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65  dbeSorterCompare
ba00: 28 29 20 66 72 6f 6d 20 64 65 63 6f 64 69 6e 67  () from decoding
ba10: 20 70 49 74 65 72 32 20 61 67 61 69 6e 2e 0a 20   pIter2 again.. 
ba20: 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a       **.      **
ba30: 20 49 66 20 74 68 65 20 74 77 6f 20 76 61 6c 75   If the two valu
ba40: 65 73 20 77 65 72 65 20 65 71 75 61 6c 2c 20 74  es were equal, t
ba50: 68 65 6e 20 74 68 65 20 76 61 6c 75 65 20 66 72  hen the value fr
ba60: 6f 6d 20 74 68 65 20 6f 6c 64 65 73 74 0a 20 20  om the oldest.  
ba70: 20 20 20 20 2a 2a 20 50 4d 41 20 73 68 6f 75 6c      ** PMA shoul
ba80: 64 20 62 65 20 63 6f 6e 73 69 64 65 72 65 64 20  d be considered 
ba90: 73 6d 61 6c 6c 65 72 2e 20 54 68 65 20 56 64 62  smaller. The Vdb
baa0: 65 53 6f 72 74 65 72 2e 61 49 74 65 72 5b 5d 20  eSorter.aIter[] 
bab0: 61 72 72 61 79 0a 20 20 20 20 20 20 2a 2a 20 69  array.      ** i
bac0: 73 20 73 6f 72 74 65 64 20 66 72 6f 6d 20 6f 6c  s sorted from ol
bad0: 64 65 73 74 20 74 6f 20 6e 65 77 65 73 74 2c 20  dest to newest, 
bae0: 73 6f 20 70 49 74 65 72 31 20 63 6f 6e 74 61 69  so pIter1 contai
baf0: 6e 73 20 6f 6c 64 65 72 20 76 61 6c 75 65 73 0a  ns older values.
bb00: 20 20 20 20 20 20 2a 2a 20 74 68 61 6e 20 70 49        ** than pI
bb10: 74 65 72 32 20 69 66 66 20 28 70 49 74 65 72 31  ter2 iff (pIter1
bb20: 3c 70 49 74 65 72 32 29 2e 20 20 2a 2f 0a 20 20  <pIter2).  */.  
bb30: 20 20 20 20 69 66 28 20 69 52 65 73 3c 30 20 7c      if( iRes<0 |
bb40: 7c 20 28 69 52 65 73 3d 3d 30 20 26 26 20 70 49  | (iRes==0 && pI
bb50: 74 65 72 31 3c 70 49 74 65 72 32 29 20 29 7b 0a  ter1<pIter2) ){.
bb60: 20 20 20 20 20 20 20 20 70 4d 65 72 67 65 72 2d          pMerger-
bb70: 3e 61 54 72 65 65 5b 69 5d 20 3d 20 28 69 6e 74  >aTree[i] = (int
bb80: 29 28 70 49 74 65 72 31 20 2d 20 70 4d 65 72 67  )(pIter1 - pMerg
bb90: 65 72 2d 3e 61 49 74 65 72 29 3b 0a 20 20 20 20  er->aIter);.    
bba0: 20 20 20 20 70 49 74 65 72 32 20 3d 20 26 70 4d      pIter2 = &pM
bbb0: 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 20 70 4d  erger->aIter[ pM
bbc0: 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 20 5e  erger->aTree[i ^
bbd0: 20 30 78 30 30 30 31 5d 20 5d 3b 0a 20 20 20 20   0x0001] ];.    
bbe0: 20 20 20 20 70 4b 65 79 32 20 3d 20 70 49 74 65      pKey2 = pIte
bbf0: 72 32 2d 3e 61 4b 65 79 3b 0a 20 20 20 20 20 20  r2->aKey;.      
bc00: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69  }else{.        i
bc10: 66 28 20 70 49 74 65 72 31 2d 3e 70 46 69 6c 65  f( pIter1->pFile
bc20: 20 29 20 70 4b 65 79 32 20 3d 20 30 3b 0a 20 20   ) pKey2 = 0;.  
bc30: 20 20 20 20 20 20 70 4d 65 72 67 65 72 2d 3e 61        pMerger->a
bc40: 54 72 65 65 5b 69 5d 20 3d 20 28 69 6e 74 29 28  Tree[i] = (int)(
bc50: 70 49 74 65 72 32 20 2d 20 70 4d 65 72 67 65 72  pIter2 - pMerger
bc60: 2d 3e 61 49 74 65 72 29 3b 0a 20 20 20 20 20 20  ->aIter);.      
bc70: 20 20 70 49 74 65 72 31 20 3d 20 26 70 4d 65 72    pIter1 = &pMer
bc80: 67 65 72 2d 3e 61 49 74 65 72 5b 20 70 4d 65 72  ger->aIter[ pMer
bc90: 67 65 72 2d 3e 61 54 72 65 65 5b 69 20 5e 20 30  ger->aTree[i ^ 0
bca0: 78 30 30 30 31 5d 20 5d 3b 0a 20 20 20 20 20 20  x0001] ];.      
bcb0: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 2a 70 62 45  }.    }.    *pbE
bcc0: 6f 66 20 3d 20 28 70 4d 65 72 67 65 72 2d 3e 61  of = (pMerger->a
bcd0: 49 74 65 72 5b 70 4d 65 72 67 65 72 2d 3e 61 54  Iter[pMerger->aT
bce0: 72 65 65 5b 31 5d 5d 2e 70 46 69 6c 65 3d 3d 30  ree[1]].pFile==0
bcf0: 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  );.  }..  return
bd00: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
bd10: 65 20 6d 61 69 6e 20 72 6f 75 74 69 6e 65 20 66  e main routine f
bd20: 6f 72 20 73 6f 72 74 65 72 2d 74 68 72 65 61 64  or sorter-thread
bd30: 20 6f 70 65 72 61 74 69 6f 6e 73 2e 0a 2a 2f 0a   operations..*/.
bd40: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 76 64 62  static void *vdb
bd50: 65 53 6f 72 74 65 72 46 6c 75 73 68 54 68 72 65  eSorterFlushThre
bd60: 61 64 28 76 6f 69 64 20 2a 70 43 74 78 29 7b 0a  ad(void *pCtx){.
bd70: 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70    SortSubtask *p
bd80: 54 61 73 6b 20 3d 20 28 53 6f 72 74 53 75 62 74  Task = (SortSubt
bd90: 61 73 6b 2a 29 70 43 74 78 3b 0a 20 20 69 6e 74  ask*)pCtx;.  int
bda0: 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
bdb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
bdc0: 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
bdd0: 20 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e   assert( pTask->
bde0: 74 68 72 65 61 64 2e 62 44 6f 6e 65 3d 3d 30 20  thread.bDone==0 
bdf0: 29 3b 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f  );.  rc = vdbeSo
be00: 72 74 65 72 4c 69 73 74 54 6f 50 4d 41 28 70 54  rterListToPMA(pT
be10: 61 73 6b 2c 20 26 70 54 61 73 6b 2d 3e 6c 69 73  ask, &pTask->lis
be20: 74 29 3b 0a 20 20 70 54 61 73 6b 2d 3e 74 68 72  t);.  pTask->thr
be30: 65 61 64 2e 62 44 6f 6e 65 20 3d 20 31 3b 0a 20  ead.bDone = 1;. 
be40: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 49   return SQLITE_I
be50: 4e 54 5f 54 4f 5f 50 54 52 28 72 63 29 3b 0a 7d  NT_TO_PTR(rc);.}
be60: 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68 20 74 68  ../*.** Flush th
be70: 65 20 63 75 72 72 65 6e 74 20 63 6f 6e 74 65 6e  e current conten
be80: 74 73 20 6f 66 20 56 64 62 65 53 6f 72 74 65 72  ts of VdbeSorter
be90: 2e 6c 69 73 74 20 74 6f 20 61 20 6e 65 77 20 50  .list to a new P
bea0: 4d 41 2c 20 70 6f 73 73 69 62 6c 79 0a 2a 2a 20  MA, possibly.** 
beb0: 75 73 69 6e 67 20 61 20 62 61 63 6b 67 72 6f 75  using a backgrou
bec0: 6e 64 20 74 68 72 65 61 64 2e 0a 2a 2f 0a 73 74  nd thread..*/.st
bed0: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
bee0: 74 65 72 46 6c 75 73 68 50 4d 41 28 56 64 62 65  terFlushPMA(Vdbe
bef0: 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 29  Sorter *pSorter)
bf00: 7b 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58  {.#if SQLITE_MAX
bf10: 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3d  _WORKER_THREADS=
bf20: 3d 30 0a 20 20 70 53 6f 72 74 65 72 2d 3e 62 55  =0.  pSorter->bU
bf30: 73 65 50 4d 41 20 3d 20 31 3b 0a 20 20 72 65 74  sePMA = 1;.  ret
bf40: 75 72 6e 20 76 64 62 65 53 6f 72 74 65 72 4c 69  urn vdbeSorterLi
bf50: 73 74 54 6f 50 4d 41 28 26 70 53 6f 72 74 65 72  stToPMA(&pSorter
bf60: 2d 3e 61 54 61 73 6b 5b 30 5d 2c 20 26 70 53 6f  ->aTask[0], &pSo
bf70: 72 74 65 72 2d 3e 6c 69 73 74 29 3b 0a 23 65 6c  rter->list);.#el
bf80: 73 65 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  se.  int rc = SQ
bf90: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 69  LITE_OK;.  int i
bfa0: 3b 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20  ;.  SortSubtask 
bfb0: 2a 70 54 61 73 6b 20 3d 20 30 3b 20 20 20 20 2f  *pTask = 0;    /
bfc0: 2a 20 54 68 72 65 61 64 20 63 6f 6e 74 65 78 74  * Thread context
bfd0: 20 75 73 65 64 20 74 6f 20 63 72 65 61 74 65 20   used to create 
bfe0: 6e 65 77 20 50 4d 41 20 2a 2f 0a 20 20 69 6e 74  new PMA */.  int
bff0: 20 6e 57 6f 72 6b 65 72 20 3d 20 28 70 53 6f 72   nWorker = (pSor
c000: 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 3b 0a 0a  ter->nTask-1);..
c010: 20 20 2f 2a 20 53 65 74 20 74 68 65 20 66 6c 61    /* Set the fla
c020: 67 20 74 6f 20 69 6e 64 69 63 61 74 65 20 74 68  g to indicate th
c030: 61 74 20 61 74 20 6c 65 61 73 74 20 6f 6e 65 20  at at least one 
c040: 50 4d 41 20 68 61 73 20 62 65 65 6e 20 77 72 69  PMA has been wri
c050: 74 74 65 6e 2e 20 0a 20 20 2a 2a 20 4f 72 20 77  tten. .  ** Or w
c060: 69 6c 6c 20 62 65 2c 20 61 6e 79 68 6f 77 2e 20  ill be, anyhow. 
c070: 20 2a 2f 0a 20 20 70 53 6f 72 74 65 72 2d 3e 62   */.  pSorter->b
c080: 55 73 65 50 4d 41 20 3d 20 31 3b 0a 0a 20 20 2f  UsePMA = 1;..  /
c090: 2a 20 53 65 6c 65 63 74 20 61 20 73 75 62 2d 74  * Select a sub-t
c0a0: 61 73 6b 20 74 6f 20 73 6f 72 74 20 61 6e 64 20  ask to sort and 
c0b0: 66 6c 75 73 68 20 74 68 65 20 63 75 72 72 65 6e  flush the curren
c0c0: 74 20 6c 69 73 74 20 6f 66 20 69 6e 2d 6d 65 6d  t list of in-mem
c0d0: 6f 72 79 0a 20 20 2a 2a 20 72 65 63 6f 72 64 73  ory.  ** records
c0e0: 20 74 6f 20 64 69 73 6b 2e 20 49 66 20 74 68 65   to disk. If the
c0f0: 20 73 6f 72 74 65 72 20 69 73 20 72 75 6e 6e 69   sorter is runni
c100: 6e 67 20 69 6e 20 6d 75 6c 74 69 2d 74 68 72 65  ng in multi-thre
c110: 61 64 65 64 20 6d 6f 64 65 2c 0a 20 20 2a 2a 20  aded mode,.  ** 
c120: 72 6f 75 6e 64 2d 72 6f 62 69 6e 20 62 65 74 77  round-robin betw
c130: 65 65 6e 20 74 68 65 20 66 69 72 73 74 20 28 70  een the first (p
c140: 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29  Sorter->nTask-1)
c150: 20 74 61 73 6b 73 2e 20 45 78 63 65 70 74 2c 20   tasks. Except, 
c160: 69 66 0a 20 20 2a 2a 20 74 68 65 20 62 61 63 6b  if.  ** the back
c170: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 66 72  ground thread fr
c180: 6f 6d 20 61 20 73 75 62 2d 74 61 73 6b 73 20 70  om a sub-tasks p
c190: 72 65 76 69 6f 75 73 20 74 75 72 6e 20 69 73 20  revious turn is 
c1a0: 73 74 69 6c 6c 20 72 75 6e 6e 69 6e 67 2c 0a 20  still running,. 
c1b0: 20 2a 2a 20 73 6b 69 70 20 69 74 2e 20 49 66 20   ** skip it. If 
c1c0: 74 68 65 20 66 69 72 73 74 20 28 70 53 6f 72 74  the first (pSort
c1d0: 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 20 73 75 62  er->nTask-1) sub
c1e0: 2d 74 61 73 6b 73 20 61 72 65 20 61 6c 6c 20 73  -tasks are all s
c1f0: 74 69 6c 6c 20 62 75 73 79 2c 0a 20 20 2a 2a 20  till busy,.  ** 
c200: 66 61 6c 6c 20 62 61 63 6b 20 74 6f 20 75 73 69  fall back to usi
c210: 6e 67 20 74 68 65 20 66 69 6e 61 6c 20 73 75 62  ng the final sub
c220: 2d 74 61 73 6b 2e 20 54 68 65 20 66 69 72 73 74  -task. The first
c230: 20 28 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b   (pSorter->nTask
c240: 2d 31 29 0a 20 20 2a 2a 20 73 75 62 2d 74 61 73  -1).  ** sub-tas
c250: 6b 73 20 61 72 65 20 70 72 65 66 65 72 65 64 20  ks are prefered 
c260: 61 73 20 74 68 65 79 20 75 73 65 20 62 61 63 6b  as they use back
c270: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 73 20 2d  ground threads -
c280: 20 74 68 65 20 66 69 6e 61 6c 20 0a 20 20 2a 2a   the final .  **
c290: 20 73 75 62 2d 74 61 73 6b 20 75 73 65 73 20 74   sub-task uses t
c2a0: 68 65 20 6d 61 69 6e 20 74 68 72 65 61 64 2e 20  he main thread. 
c2b0: 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  */.  for(i=0; i<
c2c0: 6e 57 6f 72 6b 65 72 3b 20 69 2b 2b 29 7b 0a 20  nWorker; i++){. 
c2d0: 20 20 20 69 6e 74 20 69 54 65 73 74 20 3d 20 28     int iTest = (
c2e0: 70 53 6f 72 74 65 72 2d 3e 69 50 72 65 76 20 2b  pSorter->iPrev +
c2f0: 20 69 20 2b 20 31 29 20 25 20 6e 57 6f 72 6b 65   i + 1) % nWorke
c300: 72 3b 0a 20 20 20 20 70 54 61 73 6b 20 3d 20 26  r;.    pTask = &
c310: 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 69  pSorter->aTask[i
c320: 54 65 73 74 5d 3b 0a 20 20 20 20 69 66 28 20 70  Test];.    if( p
c330: 54 61 73 6b 2d 3e 74 68 72 65 61 64 2e 62 44 6f  Task->thread.bDo
c340: 6e 65 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  ne ){.      rc =
c350: 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e 54   vdbeSorterJoinT
c360: 68 72 65 61 64 28 70 54 61 73 6b 2c 20 26 70 54  hread(pTask, &pT
c370: 61 73 6b 2d 3e 74 68 72 65 61 64 29 3b 0a 20 20  ask->thread);.  
c380: 20 20 7d 0a 20 20 20 20 69 66 28 20 70 54 61 73    }.    if( pTas
c390: 6b 2d 3e 74 68 72 65 61 64 2e 70 54 68 72 65 61  k->thread.pThrea
c3a0: 64 3d 3d 30 20 7c 7c 20 72 63 21 3d 53 51 4c 49  d==0 || rc!=SQLI
c3b0: 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20  TE_OK ) break;. 
c3c0: 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
c3d0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69  LITE_OK ){.    i
c3e0: 66 28 20 69 3d 3d 6e 57 6f 72 6b 65 72 20 29 7b  f( i==nWorker ){
c3f0: 0a 20 20 20 20 20 20 2f 2a 20 55 73 65 20 74 68  .      /* Use th
c400: 65 20 66 6f 72 65 67 72 6f 75 6e 64 20 74 68 72  e foreground thr
c410: 65 61 64 20 66 6f 72 20 74 68 69 73 20 6f 70 65  ead for this ope
c420: 72 61 74 69 6f 6e 20 2a 2f 0a 20 20 20 20 20 20  ration */.      
c430: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4c  rc = vdbeSorterL
c440: 69 73 74 54 6f 50 4d 41 28 26 70 53 6f 72 74 65  istToPMA(&pSorte
c450: 72 2d 3e 61 54 61 73 6b 5b 6e 57 6f 72 6b 65 72  r->aTask[nWorker
c460: 5d 2c 20 26 70 53 6f 72 74 65 72 2d 3e 6c 69 73  ], &pSorter->lis
c470: 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  t);.    }else{. 
c480: 20 20 20 20 20 2f 2a 20 4c 61 75 6e 63 68 20 61       /* Launch a
c490: 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65   background thre
c4a0: 61 64 20 66 6f 72 20 74 68 69 73 20 6f 70 65 72  ad for this oper
c4b0: 61 74 69 6f 6e 20 2a 2f 0a 20 20 20 20 20 20 75  ation */.      u
c4c0: 38 20 2a 61 4d 65 6d 20 3d 20 70 54 61 73 6b 2d  8 *aMem = pTask-
c4d0: 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 3b 0a 20  >list.aMemory;. 
c4e0: 20 20 20 20 20 76 6f 69 64 20 2a 70 43 74 78 20       void *pCtx 
c4f0: 3d 20 28 76 6f 69 64 2a 29 70 54 61 73 6b 3b 0a  = (void*)pTask;.
c500: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70  .      assert( p
c510: 54 61 73 6b 2d 3e 74 68 72 65 61 64 2e 70 54 68  Task->thread.pTh
c520: 72 65 61 64 3d 3d 30 20 26 26 20 70 54 61 73 6b  read==0 && pTask
c530: 2d 3e 74 68 72 65 61 64 2e 62 44 6f 6e 65 3d 3d  ->thread.bDone==
c540: 30 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72  0 );.      asser
c550: 74 28 20 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 70  t( pTask->list.p
c560: 4c 69 73 74 3d 3d 30 20 29 3b 0a 20 20 20 20 20  List==0 );.     
c570: 20 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e   assert( pTask->
c580: 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30 20  list.aMemory==0 
c590: 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74  || pSorter->list
c5a0: 2e 61 4d 65 6d 6f 72 79 21 3d 30 20 29 3b 0a 0a  .aMemory!=0 );..
c5b0: 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 69        pSorter->i
c5c0: 50 72 65 76 20 3d 20 28 70 54 61 73 6b 20 2d 20  Prev = (pTask - 
c5d0: 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 29 3b  pSorter->aTask);
c5e0: 0a 20 20 20 20 20 20 70 54 61 73 6b 2d 3e 6c 69  .      pTask->li
c5f0: 73 74 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6c 69  st = pSorter->li
c600: 73 74 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65  st;.      pSorte
c610: 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d 20  r->list.pList = 
c620: 30 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72  0;.      pSorter
c630: 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 3d 20 30  ->list.szPMA = 0
c640: 3b 0a 20 20 20 20 20 20 69 66 28 20 61 4d 65 6d  ;.      if( aMem
c650: 20 29 7b 0a 20 20 20 20 20 20 20 20 70 53 6f 72   ){.        pSor
c660: 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72  ter->list.aMemor
c670: 79 20 3d 20 61 4d 65 6d 3b 0a 20 20 20 20 20 20  y = aMem;.      
c680: 20 20 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f    pSorter->nMemo
c690: 72 79 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c  ry = sqlite3Mall
c6a0: 6f 63 53 69 7a 65 28 61 4d 65 6d 29 3b 0a 20 20  ocSize(aMem);.  
c6b0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
c6c0: 20 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74     pSorter->list
c6d0: 2e 61 4d 65 6d 6f 72 79 20 3d 20 73 71 6c 69 74  .aMemory = sqlit
c6e0: 65 33 4d 61 6c 6c 6f 63 28 70 53 6f 72 74 65 72  e3Malloc(pSorter
c6f0: 2d 3e 6e 4d 65 6d 6f 72 79 29 3b 0a 20 20 20 20  ->nMemory);.    
c700: 20 20 20 20 69 66 28 20 21 70 53 6f 72 74 65 72      if( !pSorter
c710: 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 29  ->list.aMemory )
c720: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
c730: 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 7d 0a 0a 20  OMEM;.      }.. 
c740: 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f       rc = vdbeSo
c750: 72 74 65 72 43 72 65 61 74 65 54 68 72 65 61 64  rterCreateThread
c760: 28 26 70 54 61 73 6b 2d 3e 74 68 72 65 61 64 2c  (&pTask->thread,
c770: 20 76 64 62 65 53 6f 72 74 65 72 46 6c 75 73 68   vdbeSorterFlush
c780: 54 68 72 65 61 64 2c 20 70 43 74 78 29 3b 0a 20  Thread, pCtx);. 
c790: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
c7a0: 72 6e 20 72 63 3b 0a 23 65 6e 64 69 66 0a 7d 0a  rn rc;.#endif.}.
c7b0: 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 72 65 63  ./*.** Add a rec
c7c0: 6f 72 64 20 74 6f 20 74 68 65 20 73 6f 72 74 65  ord to the sorte
c7d0: 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  r..*/.int sqlite
c7e0: 33 56 64 62 65 53 6f 72 74 65 72 57 72 69 74 65  3VdbeSorterWrite
c7f0: 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
c800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c810: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
c820: 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73  handle */.  cons
c830: 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43  t VdbeCursor *pC
c840: 73 72 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 53  sr,         /* S
c850: 6f 72 74 65 72 20 63 75 72 73 6f 72 20 2a 2f 0a  orter cursor */.
c860: 20 20 4d 65 6d 20 2a 70 56 61 6c 20 20 20 20 20    Mem *pVal     
c870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c880: 20 20 2f 2a 20 4d 65 6d 6f 72 79 20 63 65 6c 6c    /* Memory cell
c890: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 72 65 63 6f   containing reco
c8a0: 72 64 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65 53  rd */.){.  VdbeS
c8b0: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d  orter *pSorter =
c8c0: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a   pCsr->pSorter;.
c8d0: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
c8e0: 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20  E_OK;           
c8f0: 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65    /* Return Code
c900: 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f   */.  SorterReco
c910: 72 64 20 2a 70 4e 65 77 3b 20 20 20 20 20 20 20  rd *pNew;       
c920: 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 6c 69 73        /* New lis
c930: 74 20 65 6c 65 6d 65 6e 74 20 2a 2f 0a 0a 20 20  t element */..  
c940: 69 6e 74 20 62 46 6c 75 73 68 3b 20 20 20 20 20  int bFlush;     
c950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c960: 2f 2a 20 54 72 75 65 20 74 6f 20 66 6c 75 73 68  /* True to flush
c970: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65 6d   contents of mem
c980: 6f 72 79 20 74 6f 20 50 4d 41 20 2a 2f 0a 20 20  ory to PMA */.  
c990: 69 6e 74 20 6e 52 65 71 3b 20 20 20 20 20 20 20  int nReq;       
c9a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c9b0: 2f 2a 20 42 79 74 65 73 20 6f 66 20 6d 65 6d 6f  /* Bytes of memo
c9c0: 72 79 20 72 65 71 75 69 72 65 64 20 2a 2f 0a 20  ry required */. 
c9d0: 20 69 6e 74 20 6e 50 4d 41 3b 20 20 20 20 20 20   int nPMA;      
c9e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c9f0: 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 50 4d 41   /* Bytes of PMA
ca00: 20 73 70 61 63 65 20 72 65 71 75 69 72 65 64 20   space required 
ca10: 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 53  */..  assert( pS
ca20: 6f 72 74 65 72 20 29 3b 0a 0a 20 20 2f 2a 20 46  orter );..  /* F
ca30: 69 67 75 72 65 20 6f 75 74 20 77 68 65 74 68 65  igure out whethe
ca40: 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 63 75 72  r or not the cur
ca50: 72 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f 66  rent contents of
ca60: 20 6d 65 6d 6f 72 79 20 73 68 6f 75 6c 64 20 62   memory should b
ca70: 65 0a 20 20 2a 2a 20 66 6c 75 73 68 65 64 20 74  e.  ** flushed t
ca80: 6f 20 61 20 50 4d 41 20 62 65 66 6f 72 65 20 63  o a PMA before c
ca90: 6f 6e 74 69 6e 75 69 6e 67 2e 20 49 66 20 73 6f  ontinuing. If so
caa0: 2c 20 64 6f 20 73 6f 2e 0a 20 20 2a 2a 0a 20 20  , do so..  **.  
cab0: 2a 2a 20 49 66 20 75 73 69 6e 67 20 74 68 65 20  ** If using the 
cac0: 73 69 6e 67 6c 65 20 6c 61 72 67 65 20 61 6c 6c  single large all
cad0: 6f 63 61 74 69 6f 6e 20 6d 6f 64 65 20 28 70 53  ocation mode (pS
cae0: 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 21 3d  orter->aMemory!=
caf0: 30 29 2c 20 74 68 65 6e 0a 20 20 2a 2a 20 66 6c  0), then.  ** fl
cb00: 75 73 68 20 74 68 65 20 63 6f 6e 74 65 6e 74 73  ush the contents
cb10: 20 6f 66 20 6d 65 6d 6f 72 79 20 74 6f 20 61 20   of memory to a 
cb20: 6e 65 77 20 50 4d 41 20 69 66 20 28 61 29 20 61  new PMA if (a) a
cb30: 74 20 6c 65 61 73 74 20 6f 6e 65 20 76 61 6c 75  t least one valu
cb40: 65 20 69 73 0a 20 20 2a 2a 20 61 6c 72 65 61 64  e is.  ** alread
cb50: 79 20 69 6e 20 6d 65 6d 6f 72 79 20 61 6e 64 20  y in memory and 
cb60: 28 62 29 20 74 68 65 20 6e 65 77 20 76 61 6c 75  (b) the new valu
cb70: 65 20 77 69 6c 6c 20 6e 6f 74 20 66 69 74 20 69  e will not fit i
cb80: 6e 20 6d 65 6d 6f 72 79 2e 0a 20 20 2a 2a 20 0a  n memory..  ** .
cb90: 20 20 2a 2a 20 4f 72 2c 20 69 66 20 75 73 69 6e    ** Or, if usin
cba0: 67 20 73 65 70 61 72 61 74 65 20 61 6c 6c 6f 63  g separate alloc
cbb0: 61 74 69 6f 6e 73 20 66 6f 72 20 65 61 63 68 20  ations for each 
cbc0: 72 65 63 6f 72 64 2c 20 66 6c 75 73 68 20 74 68  record, flush th
cbd0: 65 20 63 6f 6e 74 65 6e 74 73 0a 20 20 2a 2a 20  e contents.  ** 
cbe0: 6f 66 20 6d 65 6d 6f 72 79 20 74 6f 20 61 20 50  of memory to a P
cbf0: 4d 41 20 69 66 20 65 69 74 68 65 72 20 6f 66 20  MA if either of 
cc00: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 72  the following ar
cc10: 65 20 74 72 75 65 3a 0a 20 20 2a 2a 0a 20 20 2a  e true:.  **.  *
cc20: 2a 20 20 20 2a 20 54 68 65 20 74 6f 74 61 6c 20  *   * The total 
cc30: 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 65 64  memory allocated
cc40: 20 66 6f 72 20 74 68 65 20 69 6e 2d 6d 65 6d 6f   for the in-memo
cc50: 72 79 20 6c 69 73 74 20 69 73 20 67 72 65 61 74  ry list is great
cc60: 65 72 20 0a 20 20 2a 2a 20 20 20 20 20 74 68 61  er .  **     tha
cc70: 6e 20 28 70 61 67 65 2d 73 69 7a 65 20 2a 20 63  n (page-size * c
cc80: 61 63 68 65 2d 73 69 7a 65 29 2c 20 6f 72 0a 20  ache-size), or. 
cc90: 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 54 68 65   **.  **   * The
cca0: 20 74 6f 74 61 6c 20 6d 65 6d 6f 72 79 20 61 6c   total memory al
ccb0: 6c 6f 63 61 74 65 64 20 66 6f 72 20 74 68 65 20  located for the 
ccc0: 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20 69  in-memory list i
ccd0: 73 20 67 72 65 61 74 65 72 20 0a 20 20 2a 2a 20  s greater .  ** 
cce0: 20 20 20 20 74 68 61 6e 20 28 70 61 67 65 2d 73      than (page-s
ccf0: 69 7a 65 20 2a 20 31 30 29 20 61 6e 64 20 73 71  ize * 10) and sq
cd00: 6c 69 74 65 33 48 65 61 70 4e 65 61 72 6c 79 46  lite3HeapNearlyF
cd10: 75 6c 6c 28 29 20 72 65 74 75 72 6e 73 20 74 72  ull() returns tr
cd20: 75 65 2e 0a 20 20 2a 2f 0a 20 20 6e 52 65 71 20  ue..  */.  nReq 
cd30: 3d 20 70 56 61 6c 2d 3e 6e 20 2b 20 73 69 7a 65  = pVal->n + size
cd40: 6f 66 28 53 6f 72 74 65 72 52 65 63 6f 72 64 29  of(SorterRecord)
cd50: 3b 0a 20 20 6e 50 4d 41 20 3d 20 70 56 61 6c 2d  ;.  nPMA = pVal-
cd60: 3e 6e 20 2b 20 73 71 6c 69 74 65 33 56 61 72 69  >n + sqlite3Vari
cd70: 6e 74 4c 65 6e 28 70 56 61 6c 2d 3e 6e 29 3b 0a  ntLen(pVal->n);.
cd80: 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6d    if( pSorter->m
cd90: 78 50 6d 61 53 69 7a 65 20 29 7b 0a 20 20 20 20  xPmaSize ){.    
cda0: 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73  if( pSorter->lis
cdb0: 74 2e 61 4d 65 6d 6f 72 79 20 29 7b 0a 20 20 20  t.aMemory ){.   
cdc0: 20 20 20 62 46 6c 75 73 68 20 3d 20 70 53 6f 72     bFlush = pSor
cdd0: 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 20 26 26 20  ter->iMemory && 
cde0: 28 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72  (pSorter->iMemor
cdf0: 79 2b 6e 52 65 71 29 20 3e 20 70 53 6f 72 74 65  y+nReq) > pSorte
ce00: 72 2d 3e 6d 78 50 6d 61 53 69 7a 65 3b 0a 20 20  r->mxPmaSize;.  
ce10: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 62    }else{.      b
ce20: 46 6c 75 73 68 20 3d 20 28 0a 20 20 20 20 20 20  Flush = (.      
ce30: 20 20 20 20 28 70 53 6f 72 74 65 72 2d 3e 6c 69      (pSorter->li
ce40: 73 74 2e 73 7a 50 4d 41 20 3e 20 70 53 6f 72 74  st.szPMA > pSort
ce50: 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65 29 0a 20  er->mxPmaSize). 
ce60: 20 20 20 20 20 20 7c 7c 20 28 70 53 6f 72 74 65        || (pSorte
ce70: 72 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 3e 20  r->list.szPMA > 
ce80: 70 53 6f 72 74 65 72 2d 3e 6d 6e 50 6d 61 53 69  pSorter->mnPmaSi
ce90: 7a 65 20 26 26 20 73 71 6c 69 74 65 33 48 65 61  ze && sqlite3Hea
cea0: 70 4e 65 61 72 6c 79 46 75 6c 6c 28 29 29 0a 20  pNearlyFull()). 
ceb0: 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20       );.    }.  
cec0: 20 20 69 66 28 20 62 46 6c 75 73 68 20 29 7b 0a    if( bFlush ){.
ced0: 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53        rc = vdbeS
cee0: 6f 72 74 65 72 46 6c 75 73 68 50 4d 41 28 70 53  orterFlushPMA(pS
cef0: 6f 72 74 65 72 29 3b 0a 20 20 20 20 20 20 70 53  orter);.      pS
cf00: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 73 7a 50 4d  orter->list.szPM
cf10: 41 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 53 6f  A = 0;.      pSo
cf20: 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 20 3d 20  rter->iMemory = 
cf30: 30 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  0;.      assert(
cf40: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c   rc!=SQLITE_OK |
cf50: 7c 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e  | pSorter->list.
cf60: 70 4c 69 73 74 3d 3d 30 20 29 3b 0a 20 20 20 20  pList==0 );.    
cf70: 7d 0a 20 20 7d 0a 0a 20 20 70 53 6f 72 74 65 72  }.  }..  pSorter
cf80: 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 2b 3d 20  ->list.szPMA += 
cf90: 6e 50 4d 41 3b 0a 20 20 69 66 28 20 6e 50 4d 41  nPMA;.  if( nPMA
cfa0: 3e 70 53 6f 72 74 65 72 2d 3e 6d 78 4b 65 79 73  >pSorter->mxKeys
cfb0: 69 7a 65 20 29 7b 0a 20 20 20 20 70 53 6f 72 74  ize ){.    pSort
cfc0: 65 72 2d 3e 6d 78 4b 65 79 73 69 7a 65 20 3d 20  er->mxKeysize = 
cfd0: 6e 50 4d 41 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  nPMA;.  }..  if(
cfe0: 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61   pSorter->list.a
cff0: 4d 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 69 6e  Memory ){.    in
d000: 74 20 6e 4d 69 6e 20 3d 20 70 53 6f 72 74 65 72  t nMin = pSorter
d010: 2d 3e 69 4d 65 6d 6f 72 79 20 2b 20 6e 52 65 71  ->iMemory + nReq
d020: 3b 0a 0a 20 20 20 20 69 66 28 20 6e 4d 69 6e 3e  ;..    if( nMin>
d030: 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79  pSorter->nMemory
d040: 20 29 7b 0a 20 20 20 20 20 20 75 38 20 2a 61 4e   ){.      u8 *aN
d050: 65 77 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e  ew;.      int nN
d060: 65 77 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6e 4d  ew = pSorter->nM
d070: 65 6d 6f 72 79 20 2a 20 32 3b 0a 20 20 20 20 20  emory * 2;.     
d080: 20 77 68 69 6c 65 28 20 6e 4e 65 77 20 3c 20 6e   while( nNew < n
d090: 4d 69 6e 20 29 20 6e 4e 65 77 20 3d 20 6e 4e 65  Min ) nNew = nNe
d0a0: 77 2a 32 3b 0a 20 20 20 20 20 20 69 66 28 20 6e  w*2;.      if( n
d0b0: 4e 65 77 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d  New > pSorter->m
d0c0: 78 50 6d 61 53 69 7a 65 20 29 20 6e 4e 65 77 20  xPmaSize ) nNew 
d0d0: 3d 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61  = pSorter->mxPma
d0e0: 53 69 7a 65 3b 0a 20 20 20 20 20 20 69 66 28 20  Size;.      if( 
d0f0: 6e 4e 65 77 20 3c 20 6e 4d 69 6e 20 29 20 6e 4e  nNew < nMin ) nN
d100: 65 77 20 3d 20 6e 4d 69 6e 3b 0a 0a 20 20 20 20  ew = nMin;..    
d110: 20 20 61 4e 65 77 20 3d 20 73 71 6c 69 74 65 33    aNew = sqlite3
d120: 52 65 61 6c 6c 6f 63 28 70 53 6f 72 74 65 72 2d  Realloc(pSorter-
d130: 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 2c 20 6e  >list.aMemory, n
d140: 4e 65 77 29 3b 0a 20 20 20 20 20 20 69 66 28 20  New);.      if( 
d150: 21 61 4e 65 77 20 29 20 72 65 74 75 72 6e 20 53  !aNew ) return S
d160: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
d170: 20 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74     pSorter->list
d180: 2e 70 4c 69 73 74 20 3d 20 28 53 6f 72 74 65 72  .pList = (Sorter
d190: 52 65 63 6f 72 64 2a 29 28 0a 20 20 20 20 20 20  Record*)(.      
d1a0: 20 20 20 20 61 4e 65 77 20 2b 20 28 28 75 38 2a      aNew + ((u8*
d1b0: 29 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70  )pSorter->list.p
d1c0: 4c 69 73 74 20 2d 20 70 53 6f 72 74 65 72 2d 3e  List - pSorter->
d1d0: 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 29 0a 20 20  list.aMemory).  
d1e0: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 70 53 6f      );.      pSo
d1f0: 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f  rter->list.aMemo
d200: 72 79 20 3d 20 61 4e 65 77 3b 0a 20 20 20 20 20  ry = aNew;.     
d210: 20 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72   pSorter->nMemor
d220: 79 20 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 7d 0a  y = nNew;.    }.
d230: 0a 20 20 20 20 70 4e 65 77 20 3d 20 28 53 6f 72  .    pNew = (Sor
d240: 74 65 72 52 65 63 6f 72 64 2a 29 26 70 53 6f 72  terRecord*)&pSor
d250: 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72  ter->list.aMemor
d260: 79 5b 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f  y[pSorter->iMemo
d270: 72 79 5d 3b 0a 20 20 20 20 70 53 6f 72 74 65 72  ry];.    pSorter
d280: 2d 3e 69 4d 65 6d 6f 72 79 20 2b 3d 20 52 4f 55  ->iMemory += ROU
d290: 4e 44 38 28 6e 52 65 71 29 3b 0a 20 20 20 20 70  ND8(nReq);.    p
d2a0: 4e 65 77 2d 3e 75 2e 69 4e 65 78 74 20 3d 20 28  New->u.iNext = (
d2b0: 75 38 2a 29 28 70 53 6f 72 74 65 72 2d 3e 6c 69  u8*)(pSorter->li
d2c0: 73 74 2e 70 4c 69 73 74 29 20 2d 20 70 53 6f 72  st.pList) - pSor
d2d0: 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72  ter->list.aMemor
d2e0: 79 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  y;.  }else{.    
d2f0: 70 4e 65 77 20 3d 20 28 53 6f 72 74 65 72 52 65  pNew = (SorterRe
d300: 63 6f 72 64 20 2a 29 73 71 6c 69 74 65 33 4d 61  cord *)sqlite3Ma
d310: 6c 6c 6f 63 28 6e 52 65 71 29 3b 0a 20 20 20 20  lloc(nReq);.    
d320: 69 66 28 20 70 4e 65 77 3d 3d 30 20 29 7b 0a 20  if( pNew==0 ){. 
d330: 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
d340: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a  TE_NOMEM;.    }.
d350: 20 20 20 20 70 4e 65 77 2d 3e 75 2e 70 4e 65 78      pNew->u.pNex
d360: 74 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73  t = pSorter->lis
d370: 74 2e 70 4c 69 73 74 3b 0a 20 20 7d 0a 0a 20 20  t.pList;.  }..  
d380: 6d 65 6d 63 70 79 28 53 52 56 41 4c 28 70 4e 65  memcpy(SRVAL(pNe
d390: 77 29 2c 20 70 56 61 6c 2d 3e 7a 2c 20 70 56 61  w), pVal->z, pVa
d3a0: 6c 2d 3e 6e 29 3b 0a 20 20 70 4e 65 77 2d 3e 6e  l->n);.  pNew->n
d3b0: 56 61 6c 20 3d 20 70 56 61 6c 2d 3e 6e 3b 0a 20  Val = pVal->n;. 
d3c0: 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70   pSorter->list.p
d3d0: 4c 69 73 74 20 3d 20 70 4e 65 77 3b 0a 0a 20 20  List = pNew;..  
d3e0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
d3f0: 0a 2a 2a 20 52 65 61 64 20 6b 65 79 73 20 66 72  .** Read keys fr
d400: 6f 6d 20 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65  om pIncr->pMerge
d410: 72 20 61 6e 64 20 70 6f 70 75 6c 61 74 65 20 70  r and populate p
d420: 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 2e 20  Incr->aFile[1]. 
d430: 54 68 65 20 66 6f 72 6d 61 74 0a 2a 2a 20 6f 66  The format.** of
d440: 20 74 68 65 20 64 61 74 61 20 73 74 6f 72 65 64   the data stored
d450: 20 69 6e 20 61 46 69 6c 65 5b 31 5d 20 69 73 20   in aFile[1] is 
d460: 74 68 65 20 73 61 6d 65 20 61 73 20 74 68 61 74  the same as that
d470: 20 75 73 65 64 20 62 79 20 72 65 67 75 6c 61 72   used by regular
d480: 20 50 4d 41 73 2c 0a 2a 2a 20 65 78 63 65 70 74   PMAs,.** except
d490: 20 74 68 61 74 20 74 68 65 20 6e 75 6d 62 65 72   that the number
d4a0: 2d 6f 66 2d 62 79 74 65 73 20 76 61 72 69 6e 74  -of-bytes varint
d4b0: 20 69 73 20 6f 6d 69 74 74 65 64 20 66 72 6f 6d   is omitted from
d4c0: 20 74 68 65 20 73 74 61 72 74 2e 0a 2a 2f 0a 73   the start..*/.s
d4d0: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 49 6e  tatic int vdbeIn
d4e0: 63 72 50 6f 70 75 6c 61 74 65 28 49 6e 63 72 4d  crPopulate(IncrM
d4f0: 65 72 67 65 72 20 2a 70 49 6e 63 72 29 7b 0a 20  erger *pIncr){. 
d500: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
d510: 5f 4f 4b 3b 0a 20 20 69 6e 74 20 72 63 32 3b 0a  _OK;.  int rc2;.
d520: 20 20 69 36 34 20 69 53 74 61 72 74 20 3d 20 70    i64 iStart = p
d530: 49 6e 63 72 2d 3e 69 53 74 61 72 74 4f 66 66 3b  Incr->iStartOff;
d540: 0a 20 20 53 6f 72 74 65 72 46 69 6c 65 20 2a 70  .  SorterFile *p
d550: 4f 75 74 20 3d 20 26 70 49 6e 63 72 2d 3e 61 46  Out = &pIncr->aF
d560: 69 6c 65 5b 31 5d 3b 0a 20 20 4d 65 72 67 65 45  ile[1];.  MergeE
d570: 6e 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 20 3d  ngine *pMerger =
d580: 20 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65 72 3b   pIncr->pMerger;
d590: 0a 20 20 50 6d 61 57 72 69 74 65 72 20 77 72 69  .  PmaWriter wri
d5a0: 74 65 72 3b 0a 20 20 61 73 73 65 72 74 28 20 70  ter;.  assert( p
d5b0: 49 6e 63 72 2d 3e 62 45 6f 66 3d 3d 30 20 29 3b  Incr->bEof==0 );
d5c0: 0a 0a 20 20 76 64 62 65 53 6f 72 74 65 72 50 6f  ..  vdbeSorterPo
d5d0: 70 75 6c 61 74 65 44 65 62 75 67 28 70 49 6e 63  pulateDebug(pInc
d5e0: 72 2d 3e 70 54 61 73 6b 2c 20 22 65 6e 74 65 72  r->pTask, "enter
d5f0: 22 29 3b 0a 0a 20 20 76 64 62 65 50 6d 61 57 72  ");..  vdbePmaWr
d600: 69 74 65 72 49 6e 69 74 28 70 4f 75 74 2d 3e 70  iterInit(pOut->p
d610: 46 64 2c 20 26 77 72 69 74 65 72 2c 20 70 49 6e  Fd, &writer, pIn
d620: 63 72 2d 3e 70 54 61 73 6b 2d 3e 70 67 73 7a 2c  cr->pTask->pgsz,
d630: 20 69 53 74 61 72 74 29 3b 0a 20 20 77 68 69 6c   iStart);.  whil
d640: 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  e( rc==SQLITE_OK
d650: 20 29 7b 0a 20 20 20 20 69 6e 74 20 64 75 6d 6d   ){.    int dumm
d660: 79 3b 0a 20 20 20 20 50 6d 61 52 65 61 64 65 72  y;.    PmaReader
d670: 20 2a 70 52 65 61 64 65 72 20 3d 20 26 70 4d 65   *pReader = &pMe
d680: 72 67 65 72 2d 3e 61 49 74 65 72 5b 20 70 4d 65  rger->aIter[ pMe
d690: 72 67 65 72 2d 3e 61 54 72 65 65 5b 31 5d 20 5d  rger->aTree[1] ]
d6a0: 3b 0a 20 20 20 20 69 6e 74 20 6e 4b 65 79 20 3d  ;.    int nKey =
d6b0: 20 70 52 65 61 64 65 72 2d 3e 6e 4b 65 79 3b 0a   pReader->nKey;.
d6c0: 20 20 20 20 69 36 34 20 69 45 6f 66 20 3d 20 77      i64 iEof = w
d6d0: 72 69 74 65 72 2e 69 57 72 69 74 65 4f 66 66 20  riter.iWriteOff 
d6e0: 2b 20 77 72 69 74 65 72 2e 69 42 75 66 45 6e 64  + writer.iBufEnd
d6f0: 3b 0a 0a 20 20 20 20 2f 2a 20 43 68 65 63 6b 20  ;..    /* Check 
d700: 69 66 20 74 68 65 20 6f 75 74 70 75 74 20 66 69  if the output fi
d710: 6c 65 20 69 73 20 66 75 6c 6c 20 6f 72 20 69 66  le is full or if
d720: 20 74 68 65 20 69 6e 70 75 74 20 68 61 73 20 62   the input has b
d730: 65 65 6e 20 65 78 68 61 75 73 74 65 64 2e 0a 20  een exhausted.. 
d740: 20 20 20 2a 2a 20 49 6e 20 65 69 74 68 65 72 20     ** In either 
d750: 63 61 73 65 20 65 78 69 74 20 74 68 65 20 6c 6f  case exit the lo
d760: 6f 70 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 70  op. */.    if( p
d770: 52 65 61 64 65 72 2d 3e 70 46 69 6c 65 3d 3d 30  Reader->pFile==0
d780: 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 69 66   ) break;.    if
d790: 28 20 28 69 45 6f 66 20 2b 20 6e 4b 65 79 20 2b  ( (iEof + nKey +
d7a0: 20 73 71 6c 69 74 65 33 56 61 72 69 6e 74 4c 65   sqlite3VarintLe
d7b0: 6e 28 6e 4b 65 79 29 29 3e 28 69 53 74 61 72 74  n(nKey))>(iStart
d7c0: 20 2b 20 70 49 6e 63 72 2d 3e 6d 78 53 7a 29 20   + pIncr->mxSz) 
d7d0: 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 2f 2a  ) break;..    /*
d7e0: 20 57 72 69 74 65 20 74 68 65 20 6e 65 78 74 20   Write the next 
d7f0: 6b 65 79 20 74 6f 20 74 68 65 20 6f 75 74 70 75  key to the outpu
d800: 74 2e 20 2a 2f 0a 20 20 20 20 76 64 62 65 50 6d  t. */.    vdbePm
d810: 61 57 72 69 74 65 56 61 72 69 6e 74 28 26 77 72  aWriteVarint(&wr
d820: 69 74 65 72 2c 20 6e 4b 65 79 29 3b 0a 20 20 20  iter, nKey);.   
d830: 20 76 64 62 65 50 6d 61 57 72 69 74 65 42 6c 6f   vdbePmaWriteBlo
d840: 62 28 26 77 72 69 74 65 72 2c 20 70 52 65 61 64  b(&writer, pRead
d850: 65 72 2d 3e 61 4b 65 79 2c 20 6e 4b 65 79 29 3b  er->aKey, nKey);
d860: 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f  .    rc = vdbeSo
d870: 72 74 65 72 4e 65 78 74 28 70 49 6e 63 72 2d 3e  rterNext(pIncr->
d880: 70 54 61 73 6b 2c 20 70 49 6e 63 72 2d 3e 70 4d  pTask, pIncr->pM
d890: 65 72 67 65 72 2c 20 26 64 75 6d 6d 79 29 3b 0a  erger, &dummy);.
d8a0: 20 20 7d 0a 0a 20 20 72 63 32 20 3d 20 76 64 62    }..  rc2 = vdb
d8b0: 65 50 6d 61 57 72 69 74 65 72 46 69 6e 69 73 68  ePmaWriterFinish
d8c0: 28 26 77 72 69 74 65 72 2c 20 26 70 4f 75 74 2d  (&writer, &pOut-
d8d0: 3e 69 45 6f 66 29 3b 0a 20 20 69 66 28 20 72 63  >iEof);.  if( rc
d8e0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63  ==SQLITE_OK ) rc
d8f0: 20 3d 20 72 63 32 3b 0a 20 20 76 64 62 65 53 6f   = rc2;.  vdbeSo
d900: 72 74 65 72 50 6f 70 75 6c 61 74 65 44 65 62 75  rterPopulateDebu
d910: 67 28 70 49 6e 63 72 2d 3e 70 54 61 73 6b 2c 20  g(pIncr->pTask, 
d920: 22 65 78 69 74 22 29 3b 0a 20 20 72 65 74 75 72  "exit");.  retur
d930: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
d940: 76 6f 69 64 20 2a 76 64 62 65 49 6e 63 72 50 6f  void *vdbeIncrPo
d950: 70 75 6c 61 74 65 54 68 72 65 61 64 28 76 6f 69  pulateThread(voi
d960: 64 20 2a 70 43 74 78 29 7b 0a 20 20 49 6e 63 72  d *pCtx){.  Incr
d970: 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 20 3d 20  Merger *pIncr = 
d980: 28 49 6e 63 72 4d 65 72 67 65 72 2a 29 70 43 74  (IncrMerger*)pCt
d990: 78 3b 0a 20 20 76 6f 69 64 20 2a 70 52 65 74 20  x;.  void *pRet 
d9a0: 3d 20 53 51 4c 49 54 45 5f 49 4e 54 5f 54 4f 5f  = SQLITE_INT_TO_
d9b0: 50 54 52 28 20 76 64 62 65 49 6e 63 72 50 6f 70  PTR( vdbeIncrPop
d9c0: 75 6c 61 74 65 28 70 49 6e 63 72 29 20 29 3b 0a  ulate(pIncr) );.
d9d0: 20 20 70 49 6e 63 72 2d 3e 74 68 72 65 61 64 2e    pIncr->thread.
d9e0: 62 44 6f 6e 65 20 3d 20 31 3b 0a 20 20 72 65 74  bDone = 1;.  ret
d9f0: 75 72 6e 20 70 52 65 74 3b 0a 7d 0a 0a 23 69 66  urn pRet;.}..#if
da00: 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b   SQLITE_MAX_WORK
da10: 45 52 5f 54 48 52 45 41 44 53 3e 30 0a 73 74 61  ER_THREADS>0.sta
da20: 74 69 63 20 69 6e 74 20 76 64 62 65 49 6e 63 72  tic int vdbeIncr
da30: 42 67 50 6f 70 75 6c 61 74 65 28 49 6e 63 72 4d  BgPopulate(IncrM
da40: 65 72 67 65 72 20 2a 70 49 6e 63 72 29 7b 0a 20  erger *pIncr){. 
da50: 20 76 6f 69 64 20 2a 70 43 74 78 20 3d 20 28 76   void *pCtx = (v
da60: 6f 69 64 2a 29 70 49 6e 63 72 3b 0a 20 20 61 73  oid*)pIncr;.  as
da70: 73 65 72 74 28 20 70 49 6e 63 72 2d 3e 62 55 73  sert( pIncr->bUs
da80: 65 54 68 72 65 61 64 20 29 3b 0a 20 20 72 65 74  eThread );.  ret
da90: 75 72 6e 20 76 64 62 65 53 6f 72 74 65 72 43 72  urn vdbeSorterCr
daa0: 65 61 74 65 54 68 72 65 61 64 28 26 70 49 6e 63  eateThread(&pInc
dab0: 72 2d 3e 74 68 72 65 61 64 2c 20 76 64 62 65 49  r->thread, vdbeI
dac0: 6e 63 72 50 6f 70 75 6c 61 74 65 54 68 72 65 61  ncrPopulateThrea
dad0: 64 2c 20 70 43 74 78 29 3b 0a 7d 0a 23 65 6e 64  d, pCtx);.}.#end
dae0: 69 66 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 76  if..static int v
daf0: 64 62 65 49 6e 63 72 53 77 61 70 28 49 6e 63 72  dbeIncrSwap(Incr
db00: 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 29 7b 0a  Merger *pIncr){.
db10: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
db20: 45 5f 4f 4b 3b 0a 0a 23 69 66 20 53 51 4c 49 54  E_OK;..#if SQLIT
db30: 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52  E_MAX_WORKER_THR
db40: 45 41 44 53 3e 30 0a 20 20 69 66 28 20 70 49 6e  EADS>0.  if( pIn
db50: 63 72 2d 3e 62 55 73 65 54 68 72 65 61 64 20 29  cr->bUseThread )
db60: 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53  {.    rc = vdbeS
db70: 6f 72 74 65 72 4a 6f 69 6e 54 68 72 65 61 64 28  orterJoinThread(
db80: 70 49 6e 63 72 2d 3e 70 54 61 73 6b 2c 20 26 70  pIncr->pTask, &p
db90: 49 6e 63 72 2d 3e 74 68 72 65 61 64 29 3b 0a 0a  Incr->thread);..
dba0: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
dbb0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 53  TE_OK ){.      S
dbc0: 6f 72 74 65 72 46 69 6c 65 20 66 30 20 3d 20 70  orterFile f0 = p
dbd0: 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 3b 0a  Incr->aFile[0];.
dbe0: 20 20 20 20 20 20 70 49 6e 63 72 2d 3e 61 46 69        pIncr->aFi
dbf0: 6c 65 5b 30 5d 20 3d 20 70 49 6e 63 72 2d 3e 61  le[0] = pIncr->a
dc00: 46 69 6c 65 5b 31 5d 3b 0a 20 20 20 20 20 20 70  File[1];.      p
dc10: 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 20 3d  Incr->aFile[1] =
dc20: 20 66 30 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20   f0;.    }..    
dc30: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
dc40: 4b 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70  K ){.      if( p
dc50: 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e 69  Incr->aFile[0].i
dc60: 45 6f 66 3d 3d 70 49 6e 63 72 2d 3e 69 53 74 61  Eof==pIncr->iSta
dc70: 72 74 4f 66 66 20 29 7b 0a 20 20 20 20 20 20 20  rtOff ){.       
dc80: 20 70 49 6e 63 72 2d 3e 62 45 6f 66 20 3d 20 31   pIncr->bEof = 1
dc90: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
dca0: 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65         rc = vdbe
dcb0: 49 6e 63 72 42 67 50 6f 70 75 6c 61 74 65 28 70  IncrBgPopulate(p
dcc0: 49 6e 63 72 29 3b 0a 20 20 20 20 20 20 7d 0a 20  Incr);.      }. 
dcd0: 20 20 20 7d 0a 20 20 7d 65 6c 73 65 0a 23 65 6e     }.  }else.#en
dce0: 64 69 66 0a 20 20 7b 0a 20 20 20 20 72 63 20 3d  dif.  {.    rc =
dcf0: 20 76 64 62 65 49 6e 63 72 50 6f 70 75 6c 61 74   vdbeIncrPopulat
dd00: 65 28 70 49 6e 63 72 29 3b 0a 20 20 20 20 70 49  e(pIncr);.    pI
dd10: 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 20 3d 20  ncr->aFile[0] = 
dd20: 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 3b  pIncr->aFile[1];
dd30: 0a 20 20 20 20 69 66 28 20 70 49 6e 63 72 2d 3e  .    if( pIncr->
dd40: 61 46 69 6c 65 5b 30 5d 2e 69 45 6f 66 3d 3d 70  aFile[0].iEof==p
dd50: 49 6e 63 72 2d 3e 69 53 74 61 72 74 4f 66 66 20  Incr->iStartOff 
dd60: 29 7b 0a 20 20 20 20 20 20 70 49 6e 63 72 2d 3e  ){.      pIncr->
dd70: 62 45 6f 66 20 3d 20 31 3b 0a 20 20 20 20 7d 0a  bEof = 1;.    }.
dd80: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
dd90: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
dda0: 20 76 64 62 65 49 6e 63 72 46 72 65 65 28 49 6e   vdbeIncrFree(In
ddb0: 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 29  crMerger *pIncr)
ddc0: 7b 0a 20 20 69 66 28 20 70 49 6e 63 72 20 29 7b  {.  if( pIncr ){
ddd0: 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f  .#if SQLITE_MAX_
dde0: 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30  WORKER_THREADS>0
ddf0: 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 4a  .    vdbeSorterJ
de00: 6f 69 6e 54 68 72 65 61 64 28 70 49 6e 63 72 2d  oinThread(pIncr-
de10: 3e 70 54 61 73 6b 2c 20 26 70 49 6e 63 72 2d 3e  >pTask, &pIncr->
de20: 74 68 72 65 61 64 29 3b 0a 20 20 20 20 69 66 28  thread);.    if(
de30: 20 70 49 6e 63 72 2d 3e 62 55 73 65 54 68 72 65   pIncr->bUseThre
de40: 61 64 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  ad ){.      if( 
de50: 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e  pIncr->aFile[0].
de60: 70 46 64 20 29 20 73 71 6c 69 74 65 33 4f 73 43  pFd ) sqlite3OsC
de70: 6c 6f 73 65 46 72 65 65 28 70 49 6e 63 72 2d 3e  loseFree(pIncr->
de80: 61 46 69 6c 65 5b 30 5d 2e 70 46 64 29 3b 0a 20  aFile[0].pFd);. 
de90: 20 20 20 20 20 69 66 28 20 70 49 6e 63 72 2d 3e       if( pIncr->
dea0: 61 46 69 6c 65 5b 31 5d 2e 70 46 64 20 29 20 73  aFile[1].pFd ) s
deb0: 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 46 72 65  qlite3OsCloseFre
dec0: 65 28 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31  e(pIncr->aFile[1
ded0: 5d 2e 70 46 64 29 3b 0a 20 20 20 20 7d 0a 23 65  ].pFd);.    }.#e
dee0: 6e 64 69 66 0a 20 20 20 20 76 64 62 65 4d 65 72  ndif.    vdbeMer
def0: 67 65 45 6e 67 69 6e 65 46 72 65 65 28 70 49 6e  geEngineFree(pIn
df00: 63 72 2d 3e 70 4d 65 72 67 65 72 29 3b 0a 20 20  cr->pMerger);.  
df10: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
df20: 49 6e 63 72 29 3b 0a 20 20 7d 0a 7d 0a 0a 73 74  Incr);.  }.}..st
df30: 61 74 69 63 20 49 6e 63 72 4d 65 72 67 65 72 20  atic IncrMerger 
df40: 2a 76 64 62 65 49 6e 63 72 4e 65 77 28 53 6f 72  *vdbeIncrNew(Sor
df50: 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c  tSubtask *pTask,
df60: 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d   MergeEngine *pM
df70: 65 72 67 65 72 29 7b 0a 20 20 49 6e 63 72 4d 65  erger){.  IncrMe
df80: 72 67 65 72 20 2a 70 49 6e 63 72 20 3d 20 73 71  rger *pIncr = sq
df90: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a  lite3_malloc(siz
dfa0: 65 6f 66 28 49 6e 63 72 4d 65 72 67 65 72 29 29  eof(IncrMerger))
dfb0: 3b 0a 20 20 69 66 28 20 70 49 6e 63 72 20 29 7b  ;.  if( pIncr ){
dfc0: 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 49 6e 63  .    memset(pInc
dfd0: 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 49 6e 63  r, 0, sizeof(Inc
dfe0: 72 4d 65 72 67 65 72 29 29 3b 0a 20 20 20 20 70  rMerger));.    p
dff0: 49 6e 63 72 2d 3e 70 4d 65 72 67 65 72 20 3d 20  Incr->pMerger = 
e000: 70 4d 65 72 67 65 72 3b 0a 20 20 20 20 70 49 6e  pMerger;.    pIn
e010: 63 72 2d 3e 70 54 61 73 6b 20 3d 20 70 54 61 73  cr->pTask = pTas
e020: 6b 3b 0a 20 20 20 20 70 49 6e 63 72 2d 3e 6d 78  k;.    pIncr->mx
e030: 53 7a 20 3d 20 4d 41 58 28 70 54 61 73 6b 2d 3e  Sz = MAX(pTask->
e040: 70 53 6f 72 74 65 72 2d 3e 6d 78 4b 65 79 73 69  pSorter->mxKeysi
e050: 7a 65 2b 39 2c 70 54 61 73 6b 2d 3e 70 53 6f 72  ze+9,pTask->pSor
e060: 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65 2f 32  ter->mxPmaSize/2
e070: 29 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 66 69  );.    pTask->fi
e080: 6c 65 32 2e 69 45 6f 66 20 2b 3d 20 70 49 6e 63  le2.iEof += pInc
e090: 72 2d 3e 6d 78 53 7a 3b 0a 20 20 7d 0a 20 20 72  r->mxSz;.  }.  r
e0a0: 65 74 75 72 6e 20 70 49 6e 63 72 3b 0a 7d 0a 0a  eturn pIncr;.}..
e0b0: 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65  static void vdbe
e0c0: 49 6e 63 72 53 65 74 54 68 72 65 61 64 73 28 49  IncrSetThreads(I
e0d0: 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63 72  ncrMerger *pIncr
e0e0: 2c 20 69 6e 74 20 62 55 73 65 54 68 72 65 61 64  , int bUseThread
e0f0: 29 7b 0a 20 20 69 66 28 20 62 55 73 65 54 68 72  ){.  if( bUseThr
e100: 65 61 64 20 29 7b 0a 20 20 20 20 70 49 6e 63 72  ead ){.    pIncr
e110: 2d 3e 62 55 73 65 54 68 72 65 61 64 20 3d 20 31  ->bUseThread = 1
e120: 3b 0a 20 20 20 20 70 49 6e 63 72 2d 3e 70 54 61  ;.    pIncr->pTa
e130: 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 20 2d  sk->file2.iEof -
e140: 3d 20 70 49 6e 63 72 2d 3e 6d 78 53 7a 3b 0a 20  = pIncr->mxSz;. 
e150: 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74   }.}..static int
e160: 20 76 64 62 65 49 6e 63 72 49 6e 69 74 32 28 50   vdbeIncrInit2(P
e170: 6d 61 52 65 61 64 65 72 20 2a 70 49 74 65 72 29  maReader *pIter)
e180: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
e190: 49 54 45 5f 4f 4b 3b 0a 20 20 49 6e 63 72 4d 65  ITE_OK;.  IncrMe
e1a0: 72 67 65 72 20 2a 70 49 6e 63 72 20 3d 20 70 49  rger *pIncr = pI
e1b0: 74 65 72 2d 3e 70 49 6e 63 72 3b 0a 20 20 69 66  ter->pIncr;.  if
e1c0: 28 20 70 49 6e 63 72 20 29 7b 0a 20 20 20 20 53  ( pIncr ){.    S
e1d0: 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
e1e0: 6b 20 3d 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b  k = pIncr->pTask
e1f0: 3b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20  ;.    int i;.   
e200: 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d   MergeEngine *pM
e210: 65 72 67 65 72 20 3d 20 70 49 6e 63 72 2d 3e 70  erger = pIncr->p
e220: 4d 65 72 67 65 72 3b 0a 0a 20 20 20 20 66 6f 72  Merger;..    for
e230: 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45  (i=0; rc==SQLITE
e240: 5f 4f 4b 20 26 26 20 69 3c 70 4d 65 72 67 65 72  _OK && i<pMerger
e250: 2d 3e 6e 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20  ->nTree; i++){. 
e260: 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e       rc = vdbeIn
e270: 63 72 49 6e 69 74 32 28 26 70 4d 65 72 67 65 72  crInit2(&pMerger
e280: 2d 3e 61 49 74 65 72 5b 69 5d 29 3b 0a 20 20 20  ->aIter[i]);.   
e290: 20 7d 0a 0a 20 20 20 20 2f 2a 20 53 65 74 20 75   }..    /* Set u
e2a0: 70 20 74 68 65 20 72 65 71 75 69 72 65 64 20 66  p the required f
e2b0: 69 6c 65 73 20 66 6f 72 20 70 49 6e 63 72 20 2a  iles for pIncr *
e2c0: 2f 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  /.    if( rc==SQ
e2d0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
e2e0: 20 69 66 28 20 70 49 6e 63 72 2d 3e 62 55 73 65   if( pIncr->bUse
e2f0: 54 68 72 65 61 64 3d 3d 30 20 29 7b 0a 20 20 20  Thread==0 ){.   
e300: 20 20 20 20 20 69 66 28 20 70 54 61 73 6b 2d 3e       if( pTask->
e310: 66 69 6c 65 32 2e 70 46 64 3d 3d 30 20 29 7b 0a  file2.pFd==0 ){.
e320: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 76            rc = v
e330: 64 62 65 53 6f 72 74 65 72 4f 70 65 6e 54 65 6d  dbeSorterOpenTem
e340: 70 46 69 6c 65 28 70 54 61 73 6b 2d 3e 64 62 2d  pFile(pTask->db-
e350: 3e 70 56 66 73 2c 20 26 70 54 61 73 6b 2d 3e 66  >pVfs, &pTask->f
e360: 69 6c 65 32 2e 70 46 64 29 3b 0a 20 20 20 20 20  ile2.pFd);.     
e370: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 54 61       assert( pTa
e380: 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 3e 30  sk->file2.iEof>0
e390: 20 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66   );.          if
e3a0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
e3b0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 76  ){.            v
e3c0: 64 62 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46  dbeSorterExtendF
e3d0: 69 6c 65 28 70 54 61 73 6b 2d 3e 64 62 2c 70 54  ile(pTask->db,pT
e3e0: 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64 2c 70  ask->file2.pFd,p
e3f0: 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66  Task->file2.iEof
e400: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  );.            p
e410: 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66  Task->file2.iEof
e420: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20   = 0;.          
e430: 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  }.        }.    
e440: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
e450: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  TE_OK ){.       
e460: 20 20 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b     pIncr->aFile[
e470: 31 5d 2e 70 46 64 20 3d 20 70 54 61 73 6b 2d 3e  1].pFd = pTask->
e480: 66 69 6c 65 32 2e 70 46 64 3b 0a 20 20 20 20 20  file2.pFd;.     
e490: 20 20 20 20 20 70 49 6e 63 72 2d 3e 69 53 74 61       pIncr->iSta
e4a0: 72 74 4f 66 66 20 3d 20 70 54 61 73 6b 2d 3e 66  rtOff = pTask->f
e4b0: 69 6c 65 32 2e 69 45 6f 66 3b 0a 20 20 20 20 20  ile2.iEof;.     
e4c0: 20 20 20 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65       pTask->file
e4d0: 32 2e 69 45 6f 66 20 2b 3d 20 70 49 6e 63 72 2d  2.iEof += pIncr-
e4e0: 3e 6d 78 53 7a 3b 0a 20 20 20 20 20 20 20 20 7d  >mxSz;.        }
e4f0: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
e500: 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53        rc = vdbeS
e510: 6f 72 74 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c  orterOpenTempFil
e520: 65 28 70 54 61 73 6b 2d 3e 64 62 2d 3e 70 56 66  e(pTask->db->pVf
e530: 73 2c 20 26 70 49 6e 63 72 2d 3e 61 46 69 6c 65  s, &pIncr->aFile
e540: 5b 30 5d 2e 70 46 64 29 3b 0a 20 20 20 20 20 20  [0].pFd);.      
e550: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
e560: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20  _OK ){.         
e570: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
e580: 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 70 54 61  OpenTempFile(pTa
e590: 73 6b 2d 3e 64 62 2d 3e 70 56 66 73 2c 20 26 70  sk->db->pVfs, &p
e5a0: 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 2e 70  Incr->aFile[1].p
e5b0: 46 64 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  Fd);.        }. 
e5c0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
e5d0: 20 20 66 6f 72 28 69 3d 70 4d 65 72 67 65 72 2d    for(i=pMerger-
e5e0: 3e 6e 54 72 65 65 2d 31 3b 20 72 63 3d 3d 53 51  >nTree-1; rc==SQ
e5f0: 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3e 30 3b 20  LITE_OK && i>0; 
e600: 69 2d 2d 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  i--){.      rc =
e610: 20 76 64 62 65 53 6f 72 74 65 72 44 6f 43 6f 6d   vdbeSorterDoCom
e620: 70 61 72 65 28 70 49 6e 63 72 2d 3e 70 54 61 73  pare(pIncr->pTas
e630: 6b 2c 20 70 4d 65 72 67 65 72 2c 20 69 29 3b 0a  k, pMerger, i);.
e640: 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72      }..    if( r
e650: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
e660: 70 49 6e 63 72 2d 3e 62 55 73 65 54 68 72 65 61  pIncr->bUseThrea
e670: 64 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  d ){.      rc = 
e680: 76 64 62 65 49 6e 63 72 42 67 50 6f 70 75 6c 61  vdbeIncrBgPopula
e690: 74 65 28 70 49 6e 63 72 29 3b 0a 20 20 20 20 7d  te(pIncr);.    }
e6a0: 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ..    if( rc==SQ
e6b0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
e6c0: 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61   rc = vdbePmaRea
e6d0: 64 65 72 4e 65 78 74 28 70 49 74 65 72 29 3b 0a  derNext(pIter);.
e6e0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
e6f0: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
e700: 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 4d  Allocate a new M
e710: 65 72 67 65 45 6e 67 69 6e 65 20 6f 62 6a 65 63  ergeEngine objec
e720: 74 20 74 6f 20 6d 65 72 67 65 20 74 68 65 20 63  t to merge the c
e730: 6f 6e 74 65 6e 74 73 20 6f 66 20 6e 50 4d 41 20  ontents of nPMA 
e740: 6c 65 76 65 6c 2d 30 0a 2a 2a 20 50 4d 41 73 20  level-0.** PMAs 
e750: 66 72 6f 6d 20 70 54 61 73 6b 2d 3e 66 69 6c 65  from pTask->file
e760: 2e 20 49 66 20 6e 6f 20 65 72 72 6f 72 20 6f 63  . If no error oc
e770: 63 75 72 73 2c 20 73 65 74 20 2a 70 70 4f 75 74  curs, set *ppOut
e780: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 0a 2a 2a 20   to point to.** 
e790: 74 68 65 20 6e 65 77 20 6f 62 6a 65 63 74 20 61  the new object a
e7a0: 6e 64 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  nd return SQLITE
e7b0: 5f 4f 4b 2e 20 4f 72 2c 20 69 66 20 61 6e 20 65  _OK. Or, if an e
e7c0: 72 72 6f 72 20 64 6f 65 73 20 6f 63 63 75 72 2c  rror does occur,
e7d0: 20 73 65 74 20 2a 70 70 4f 75 74 0a 2a 2a 20 74   set *ppOut.** t
e7e0: 6f 20 4e 55 4c 4c 20 61 6e 64 20 72 65 74 75 72  o NULL and retur
e7f0: 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  n an SQLite erro
e800: 72 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 57 68  r code..**.** Wh
e810: 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  en this function
e820: 20 69 73 20 63 61 6c 6c 65 64 2c 20 2a 70 69 4f   is called, *piO
e830: 66 66 73 65 74 20 69 73 20 73 65 74 20 74 6f 20  ffset is set to 
e840: 74 68 65 20 6f 66 66 73 65 74 20 6f 66 20 74 68  the offset of th
e850: 65 0a 2a 2a 20 66 69 72 73 74 20 50 4d 41 20 74  e.** first PMA t
e860: 6f 20 72 65 61 64 20 66 72 6f 6d 20 70 54 61 73  o read from pTas
e870: 6b 2d 3e 66 69 6c 65 2e 20 41 73 73 75 6d 69 6e  k->file. Assumin
e880: 67 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72  g no error occur
e890: 73 2c 20 69 74 20 69 73 20 0a 2a 2a 20 73 65 74  s, it is .** set
e8a0: 20 74 6f 20 74 68 65 20 6f 66 66 73 65 74 20 69   to the offset i
e8b0: 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f  mmediately follo
e8c0: 77 69 6e 67 20 74 68 65 20 6c 61 73 74 20 62 79  wing the last by
e8d0: 74 65 20 6f 66 20 74 68 65 20 6c 61 73 74 0a 2a  te of the last.*
e8e0: 2a 20 50 4d 41 20 62 65 66 6f 72 65 20 72 65 74  * PMA before ret
e8f0: 75 72 6e 69 6e 67 2e 20 49 66 20 61 6e 20 65 72  urning. If an er
e900: 72 6f 72 20 64 6f 65 73 20 6f 63 63 75 72 2c 20  ror does occur, 
e910: 74 68 65 6e 20 74 68 65 20 66 69 6e 61 6c 20 76  then the final v
e920: 61 6c 75 65 20 6f 66 0a 2a 2a 20 2a 70 69 4f 66  alue of.** *piOf
e930: 66 73 65 74 20 69 73 20 75 6e 64 65 66 69 6e 65  fset is undefine
e940: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
e950: 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65   vdbeMergeEngine
e960: 4c 65 76 65 6c 30 28 0a 20 20 53 6f 72 74 53 75  Level0(.  SortSu
e970: 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20  btask *pTask,   
e980: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72            /* Sor
e990: 74 65 72 20 74 61 73 6b 20 74 6f 20 72 65 61 64  ter task to read
e9a0: 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 6e 74 20 6e   from */.  int n
e9b0: 50 4d 41 2c 20 20 20 20 20 20 20 20 20 20 20 20  PMA,            
e9c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
e9d0: 6d 62 65 72 20 6f 66 20 50 4d 41 73 20 74 6f 20  mber of PMAs to 
e9e0: 72 65 61 64 20 2a 2f 0a 20 20 69 36 34 20 2a 70  read */.  i64 *p
e9f0: 69 4f 66 66 73 65 74 2c 20 20 20 20 20 20 20 20  iOffset,        
ea00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f            /* IN/
ea10: 4f 55 54 3a 20 52 65 61 64 20 6f 66 66 73 65 74  OUT: Read offset
ea20: 20 69 6e 20 70 54 61 73 6b 2d 3e 66 69 6c 65 20   in pTask->file 
ea30: 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65  */.  MergeEngine
ea40: 20 2a 2a 70 70 4f 75 74 20 20 20 20 20 20 20 20   **ppOut        
ea50: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 65 77       /* OUT: New
ea60: 20 6d 65 72 67 65 2d 65 6e 67 69 6e 65 20 2a 2f   merge-engine */
ea70: 0a 29 7b 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e  .){.  MergeEngin
ea80: 65 20 2a 70 4e 65 77 3b 20 20 20 20 20 20 20 20  e *pNew;        
ea90: 20 20 20 20 20 20 2f 2a 20 4d 65 72 67 65 20 65        /* Merge e
eaa0: 6e 67 69 6e 65 20 74 6f 20 72 65 74 75 72 6e 20  ngine to return 
eab0: 2a 2f 0a 20 20 69 36 34 20 69 4f 66 66 20 3d 20  */.  i64 iOff = 
eac0: 2a 70 69 4f 66 66 73 65 74 3b 0a 20 20 69 6e 74  *piOffset;.  int
ead0: 20 69 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53   i;.  int rc = S
eae0: 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2a 70 70  QLITE_OK;..  *pp
eaf0: 4f 75 74 20 3d 20 70 4e 65 77 20 3d 20 76 64 62  Out = pNew = vdb
eb00: 65 4d 65 72 67 65 45 6e 67 69 6e 65 4e 65 77 28  eMergeEngineNew(
eb10: 6e 50 4d 41 29 3b 0a 20 20 69 66 28 20 70 4e 65  nPMA);.  if( pNe
eb20: 77 3d 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49  w==0 ) rc = SQLI
eb30: 54 45 5f 4e 4f 4d 45 4d 3b 0a 0a 20 20 66 6f 72  TE_NOMEM;..  for
eb40: 28 69 3d 30 3b 20 69 3c 6e 50 4d 41 20 26 26 20  (i=0; i<nPMA && 
eb50: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69  rc==SQLITE_OK; i
eb60: 2b 2b 29 7b 0a 20 20 20 20 69 36 34 20 6e 44 75  ++){.    i64 nDu
eb70: 6d 6d 79 3b 0a 20 20 20 20 50 6d 61 52 65 61 64  mmy;.    PmaRead
eb80: 65 72 20 2a 70 49 74 65 72 20 3d 20 26 70 4e 65  er *pIter = &pNe
eb90: 77 2d 3e 61 49 74 65 72 5b 69 5d 3b 0a 20 20 20  w->aIter[i];.   
eba0: 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61   rc = vdbePmaRea
ebb0: 64 65 72 49 6e 69 74 28 70 54 61 73 6b 2c 20 26  derInit(pTask, &
ebc0: 70 54 61 73 6b 2d 3e 66 69 6c 65 2c 20 69 4f 66  pTask->file, iOf
ebd0: 66 2c 20 70 49 74 65 72 2c 20 26 6e 44 75 6d 6d  f, pIter, &nDumm
ebe0: 79 29 3b 0a 20 20 20 20 69 4f 66 66 20 3d 20 70  y);.    iOff = p
ebf0: 49 74 65 72 2d 3e 69 45 6f 66 3b 0a 20 20 7d 0a  Iter->iEof;.  }.
ec00: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
ec10: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 64 62 65  E_OK ){.    vdbe
ec20: 4d 65 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28  MergeEngineFree(
ec30: 70 4e 65 77 29 3b 0a 20 20 20 20 2a 70 70 4f 75  pNew);.    *ppOu
ec40: 74 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 2a 70 69  t = 0;.  }.  *pi
ec50: 4f 66 66 73 65 74 20 3d 20 69 4f 66 66 3b 0a 20  Offset = iOff;. 
ec60: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 74   return rc;.}..t
ec70: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 49 6e  ypedef struct In
ec80: 63 72 42 75 69 6c 64 65 72 20 49 6e 63 72 42 75  crBuilder IncrBu
ec90: 69 6c 64 65 72 3b 0a 73 74 72 75 63 74 20 49 6e  ilder;.struct In
eca0: 63 72 42 75 69 6c 64 65 72 20 7b 0a 20 20 69 6e  crBuilder {.  in
ecb0: 74 20 6e 50 4d 41 3b 20 20 20 20 20 20 20 20 20  t nPMA;         
ecc0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
ecd0: 75 6d 62 65 72 20 6f 66 20 69 74 65 72 61 74 6f  umber of iterato
ece0: 72 73 20 75 73 65 64 20 73 6f 20 66 61 72 20 2a  rs used so far *
ecf0: 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  /.  MergeEngine 
ed00: 2a 70 4d 65 72 67 65 72 3b 20 20 20 20 20 20 20  *pMerger;       
ed10: 20 20 2f 2a 20 4d 65 72 67 65 20 65 6e 67 69 6e    /* Merge engin
ed20: 65 20 74 6f 20 70 6f 70 75 6c 61 74 65 2e 20 2a  e to populate. *
ed30: 2f 0a 7d 3b 0a 0a 73 74 61 74 69 63 20 69 6e 74  /.};..static int
ed40: 20 76 64 62 65 41 64 64 54 6f 42 75 69 6c 64 65   vdbeAddToBuilde
ed50: 72 28 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b  r(.  SortSubtask
ed60: 20 2a 70 54 61 73 6b 2c 0a 20 20 49 6e 63 72 42   *pTask,.  IncrB
ed70: 75 69 6c 64 65 72 20 2a 70 42 75 69 6c 64 65 72  uilder *pBuilder
ed80: 2c 20 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65  , .  MergeEngine
ed90: 20 2a 70 4d 65 72 67 65 72 0a 29 7b 0a 20 20 69   *pMerger.){.  i
eda0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
edb0: 4b 3b 0a 20 20 49 6e 63 72 4d 65 72 67 65 72 20  K;.  IncrMerger 
edc0: 2a 70 49 6e 63 72 3b 0a 0a 20 20 61 73 73 65 72  *pIncr;..  asser
edd0: 74 28 20 70 4d 65 72 67 65 72 20 29 3b 0a 20 20  t( pMerger );.  
ede0: 69 66 28 20 70 42 75 69 6c 64 65 72 2d 3e 6e 50  if( pBuilder->nP
edf0: 4d 41 3d 3d 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  MA==SORTER_MAX_M
ee00: 45 52 47 45 5f 43 4f 55 4e 54 20 29 7b 0a 20 20  ERGE_COUNT ){.  
ee10: 20 20 72 63 20 3d 20 76 64 62 65 41 64 64 54 6f    rc = vdbeAddTo
ee20: 42 75 69 6c 64 65 72 28 70 54 61 73 6b 2c 20 26  Builder(pTask, &
ee30: 70 42 75 69 6c 64 65 72 5b 31 5d 2c 20 70 42 75  pBuilder[1], pBu
ee40: 69 6c 64 65 72 2d 3e 70 4d 65 72 67 65 72 29 3b  ilder->pMerger);
ee50: 0a 20 20 20 20 70 42 75 69 6c 64 65 72 2d 3e 70  .    pBuilder->p
ee60: 4d 65 72 67 65 72 20 3d 20 30 3b 0a 20 20 20 20  Merger = 0;.    
ee70: 70 42 75 69 6c 64 65 72 2d 3e 6e 50 4d 41 20 3d  pBuilder->nPMA =
ee80: 20 30 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72   0;.  }..  if( r
ee90: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
eea0: 70 42 75 69 6c 64 65 72 2d 3e 70 4d 65 72 67 65  pBuilder->pMerge
eeb0: 72 3d 3d 30 20 29 7b 0a 20 20 20 20 70 42 75 69  r==0 ){.    pBui
eec0: 6c 64 65 72 2d 3e 70 4d 65 72 67 65 72 20 3d 20  lder->pMerger = 
eed0: 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4e  vdbeMergeEngineN
eee0: 65 77 28 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45  ew(SORTER_MAX_ME
eef0: 52 47 45 5f 43 4f 55 4e 54 29 3b 0a 20 20 20 20  RGE_COUNT);.    
ef00: 69 66 28 20 70 42 75 69 6c 64 65 72 2d 3e 70 4d  if( pBuilder->pM
ef10: 65 72 67 65 72 3d 3d 30 20 29 20 72 63 20 3d 20  erger==0 ) rc = 
ef20: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
ef30: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
ef40: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 49  ITE_OK ){.    pI
ef50: 6e 63 72 20 3d 20 76 64 62 65 49 6e 63 72 4e 65  ncr = vdbeIncrNe
ef60: 77 28 70 54 61 73 6b 2c 20 70 4d 65 72 67 65 72  w(pTask, pMerger
ef70: 29 3b 0a 20 20 20 20 69 66 28 20 70 49 6e 63 72  );.    if( pIncr
ef80: 3d 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49 54  ==0 ) rc = SQLIT
ef90: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 70 42 75  E_NOMEM;.    pBu
efa0: 69 6c 64 65 72 2d 3e 70 4d 65 72 67 65 72 2d 3e  ilder->pMerger->
efb0: 61 49 74 65 72 5b 70 42 75 69 6c 64 65 72 2d 3e  aIter[pBuilder->
efc0: 6e 50 4d 41 2b 2b 5d 2e 70 49 6e 63 72 20 3d 20  nPMA++].pIncr = 
efd0: 70 49 6e 63 72 3b 0a 20 20 7d 0a 0a 20 20 69 66  pIncr;.  }..  if
efe0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
eff0: 29 7b 0a 20 20 20 20 76 64 62 65 4d 65 72 67 65  ){.    vdbeMerge
f000: 45 6e 67 69 6e 65 46 72 65 65 28 70 4d 65 72 67  EngineFree(pMerg
f010: 65 72 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  er);.  }..  retu
f020: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
f030: 50 6f 70 75 6c 61 74 65 20 69 74 65 72 61 74 6f  Populate iterato
f040: 72 20 2a 70 49 74 65 72 20 73 6f 20 74 68 61 74  r *pIter so that
f050: 20 69 74 20 6d 61 79 20 62 65 20 75 73 65 64 20   it may be used 
f060: 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75  to iterate throu
f070: 67 68 20 61 6c 6c 20 0a 2a 2a 20 6b 65 79 73 20  gh all .** keys 
f080: 73 74 6f 72 65 64 20 69 6e 20 61 6c 6c 20 50 4d  stored in all PM
f090: 41 73 20 63 72 65 61 74 65 64 20 62 79 20 74 68  As created by th
f0a0: 69 73 20 73 6f 72 74 65 72 2e 0a 2a 2f 0a 73 74  is sorter..*/.st
f0b0: 61 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d 61  atic int vdbePma
f0c0: 52 65 61 64 65 72 49 6e 63 72 49 6e 69 74 28 56  ReaderIncrInit(V
f0d0: 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
f0e0: 65 72 2c 20 50 6d 61 52 65 61 64 65 72 20 2a 70  er, PmaReader *p
f0f0: 49 74 65 72 29 7b 0a 20 20 53 6f 72 74 53 75 62  Iter){.  SortSub
f100: 74 61 73 6b 20 2a 70 54 61 73 6b 30 20 3d 20 26  task *pTask0 = &
f110: 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 30  pSorter->aTask[0
f120: 5d 3b 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65  ];.  MergeEngine
f130: 20 2a 70 4d 61 69 6e 20 3d 20 30 3b 0a 20 20 73   *pMain = 0;.  s
f140: 71 6c 69 74 65 33 20 2a 64 62 20 3d 20 70 54 61  qlite3 *db = pTa
f150: 73 6b 30 2d 3e 64 62 3b 0a 20 20 69 6e 74 20 72  sk0->db;.  int r
f160: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
f170: 20 69 6e 74 20 69 54 61 73 6b 3b 0a 0a 20 20 49   int iTask;..  I
f180: 6e 63 72 42 75 69 6c 64 65 72 20 2a 61 4d 65 72  ncrBuilder *aMer
f190: 67 65 3b 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20  ge;.  const int 
f1a0: 6e 4d 65 72 67 65 20 3d 20 33 32 3b 0a 20 20 61  nMerge = 32;.  a
f1b0: 4d 65 72 67 65 20 3d 20 73 71 6c 69 74 65 33 44  Merge = sqlite3D
f1c0: 62 4d 61 6c 6c 6f 63 5a 65 72 6f 28 64 62 2c 20  bMallocZero(db, 
f1d0: 73 69 7a 65 6f 66 28 61 4d 65 72 67 65 5b 30 5d  sizeof(aMerge[0]
f1e0: 29 2a 6e 4d 65 72 67 65 29 3b 0a 20 20 69 66 28  )*nMerge);.  if(
f1f0: 20 61 4d 65 72 67 65 3d 3d 30 20 29 20 72 65 74   aMerge==0 ) ret
f200: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
f210: 3b 0a 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72  ;..  if( pSorter
f220: 2d 3e 6e 54 61 73 6b 3e 31 20 29 7b 0a 20 20 20  ->nTask>1 ){.   
f230: 20 70 4d 61 69 6e 20 3d 20 76 64 62 65 4d 65 72   pMain = vdbeMer
f240: 67 65 45 6e 67 69 6e 65 4e 65 77 28 70 53 6f 72  geEngineNew(pSor
f250: 74 65 72 2d 3e 6e 54 61 73 6b 29 3b 0a 20 20 20  ter->nTask);.   
f260: 20 69 66 28 20 70 4d 61 69 6e 3d 3d 30 20 29 20   if( pMain==0 ) 
f270: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
f280: 4d 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 69 54  M;.  }..  for(iT
f290: 61 73 6b 3d 30 3b 20 69 54 61 73 6b 3c 70 53 6f  ask=0; iTask<pSo
f2a0: 72 74 65 72 2d 3e 6e 54 61 73 6b 20 26 26 20 72  rter->nTask && r
f2b0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 54  c==SQLITE_OK; iT
f2c0: 61 73 6b 2b 2b 29 7b 0a 20 20 20 20 4d 65 72 67  ask++){.    Merg
f2d0: 65 45 6e 67 69 6e 65 20 2a 70 52 6f 6f 74 20 3d  eEngine *pRoot =
f2e0: 20 30 3b 0a 20 20 20 20 69 6e 74 20 69 50 4d 41   0;.    int iPMA
f2f0: 3b 0a 20 20 20 20 69 36 34 20 69 52 65 61 64 4f  ;.    i64 iReadO
f300: 66 66 20 3d 20 30 3b 0a 20 20 20 20 53 6f 72 74  ff = 0;.    Sort
f310: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d  Subtask *pTask =
f320: 20 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b   &pSorter->aTask
f330: 5b 69 54 61 73 6b 5d 3b 0a 20 20 20 20 69 66 28  [iTask];.    if(
f340: 20 70 54 61 73 6b 2d 3e 6e 50 4d 41 3d 3d 30 20   pTask->nPMA==0 
f350: 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20  ) continue;.    
f360: 66 6f 72 28 69 50 4d 41 3d 30 3b 20 69 50 4d 41  for(iPMA=0; iPMA
f370: 3c 70 54 61 73 6b 2d 3e 6e 50 4d 41 3b 20 69 50  <pTask->nPMA; iP
f380: 4d 41 20 2b 3d 20 53 4f 52 54 45 52 5f 4d 41 58  MA += SORTER_MAX
f390: 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 29 7b 0a 20  _MERGE_COUNT){. 
f3a0: 20 20 20 20 20 4d 65 72 67 65 45 6e 67 69 6e 65       MergeEngine
f3b0: 20 2a 70 4d 65 72 67 65 72 20 3d 20 30 3b 0a 20   *pMerger = 0;. 
f3c0: 20 20 20 20 20 69 6e 74 20 6e 52 65 61 64 65 72       int nReader
f3d0: 20 3d 20 4d 49 4e 28 70 54 61 73 6b 2d 3e 6e 50   = MIN(pTask->nP
f3e0: 4d 41 20 2d 20 69 50 4d 41 2c 20 53 4f 52 54 45  MA - iPMA, SORTE
f3f0: 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
f400: 54 29 3b 0a 0a 20 20 20 20 20 20 72 63 20 3d 20  T);..      rc = 
f410: 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4c  vdbeMergeEngineL
f420: 65 76 65 6c 30 28 70 54 61 73 6b 2c 20 6e 52 65  evel0(pTask, nRe
f430: 61 64 65 72 2c 20 26 69 52 65 61 64 4f 66 66 2c  ader, &iReadOff,
f440: 20 26 70 4d 65 72 67 65 72 29 3b 0a 20 20 20 20   &pMerger);.    
f450: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
f460: 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 0a 20 20  _OK ) break;..  
f470: 20 20 20 20 69 66 28 20 69 50 4d 41 3d 3d 30 20      if( iPMA==0 
f480: 29 7b 0a 20 20 20 20 20 20 20 20 70 52 6f 6f 74  ){.        pRoot
f490: 20 3d 20 70 4d 65 72 67 65 72 3b 0a 20 20 20 20   = pMerger;.    
f4a0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
f4b0: 20 69 66 28 20 70 52 6f 6f 74 20 29 7b 0a 20 20   if( pRoot ){.  
f4c0: 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62          rc = vdb
f4d0: 65 41 64 64 54 6f 42 75 69 6c 64 65 72 28 70 54  eAddToBuilder(pT
f4e0: 61 73 6b 2c 20 26 61 4d 65 72 67 65 5b 30 5d 2c  ask, &aMerge[0],
f4f0: 20 70 52 6f 6f 74 29 3b 0a 20 20 20 20 20 20 20   pRoot);.       
f500: 20 20 20 70 52 6f 6f 74 20 3d 20 30 3b 0a 20 20     pRoot = 0;.  
f510: 20 20 20 20 20 20 20 20 69 66 28 20 72 63 21 3d          if( rc!=
f520: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
f530: 20 20 20 20 20 20 20 20 20 76 64 62 65 4d 65 72           vdbeMer
f540: 67 65 45 6e 67 69 6e 65 46 72 65 65 28 70 4d 65  geEngineFree(pMe
f550: 72 67 65 72 29 3b 0a 20 20 20 20 20 20 20 20 20  rger);.         
f560: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
f570: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a      }.        }.
f580: 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62          rc = vdb
f590: 65 41 64 64 54 6f 42 75 69 6c 64 65 72 28 70 54  eAddToBuilder(pT
f5a0: 61 73 6b 2c 20 26 61 4d 65 72 67 65 5b 30 5d 2c  ask, &aMerge[0],
f5b0: 20 70 4d 65 72 67 65 72 29 3b 0a 20 20 20 20 20   pMerger);.     
f5c0: 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66   }.    }..    if
f5d0: 28 20 70 52 6f 6f 74 3d 3d 30 20 29 7b 0a 20 20  ( pRoot==0 ){.  
f5e0: 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20      int i;.     
f5f0: 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51   for(i=0; rc==SQ
f600: 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e 4d 65  LITE_OK && i<nMe
f610: 72 67 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  rge; i++){.     
f620: 20 20 20 69 66 28 20 61 4d 65 72 67 65 5b 69 5d     if( aMerge[i]
f630: 2e 70 4d 65 72 67 65 72 20 29 7b 0a 20 20 20 20  .pMerger ){.    
f640: 20 20 20 20 20 20 69 66 28 20 70 52 6f 6f 74 20        if( pRoot 
f650: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72  ){.            r
f660: 63 20 3d 20 76 64 62 65 41 64 64 54 6f 42 75 69  c = vdbeAddToBui
f670: 6c 64 65 72 28 70 54 61 73 6b 2c 20 26 61 4d 65  lder(pTask, &aMe
f680: 72 67 65 5b 69 5d 2c 20 70 52 6f 6f 74 29 3b 0a  rge[i], pRoot);.
f690: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20              if( 
f6a0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
f6b0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 20  break;.         
f6c0: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 70 52 6f   }.          pRo
f6d0: 6f 74 20 3d 20 61 4d 65 72 67 65 5b 69 5d 2e 70  ot = aMerge[i].p
f6e0: 4d 65 72 67 65 72 3b 0a 20 20 20 20 20 20 20 20  Merger;.        
f6f0: 20 20 61 4d 65 72 67 65 5b 69 5d 2e 70 4d 65 72    aMerge[i].pMer
f700: 67 65 72 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ger = 0;.       
f710: 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d   }.      }.    }
f720: 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ..    if( rc==SQ
f730: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
f740: 20 69 66 28 20 70 4d 61 69 6e 3d 3d 30 20 29 7b   if( pMain==0 ){
f750: 0a 20 20 20 20 20 20 20 20 70 4d 61 69 6e 20 3d  .        pMain =
f760: 20 70 52 6f 6f 74 3b 0a 20 20 20 20 20 20 7d 65   pRoot;.      }e
f770: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 49 6e 63  lse{.        Inc
f780: 72 4d 65 72 67 65 72 20 2a 70 4e 65 77 20 3d 20  rMerger *pNew = 
f790: 76 64 62 65 49 6e 63 72 4e 65 77 28 70 54 61 73  vdbeIncrNew(pTas
f7a0: 6b 2c 20 70 52 6f 6f 74 29 3b 0a 20 20 20 20 20  k, pRoot);.     
f7b0: 20 20 20 70 4d 61 69 6e 2d 3e 61 49 74 65 72 5b     pMain->aIter[
f7c0: 69 54 61 73 6b 5d 2e 70 49 6e 63 72 20 3d 20 70  iTask].pIncr = p
f7d0: 4e 65 77 3b 0a 20 20 20 20 20 20 20 20 69 66 28  New;.        if(
f7e0: 20 70 4e 65 77 3d 3d 30 20 29 20 72 63 20 3d 20   pNew==0 ) rc = 
f7f0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
f800: 20 20 20 20 7d 0a 20 20 20 20 20 20 6d 65 6d 73      }.      mems
f810: 65 74 28 61 4d 65 72 67 65 2c 20 30 2c 20 6e 4d  et(aMerge, 0, nM
f820: 65 72 67 65 2a 73 69 7a 65 6f 66 28 61 4d 65 72  erge*sizeof(aMer
f830: 67 65 5b 30 5d 29 29 3b 0a 20 20 20 20 7d 0a 20  ge[0]));.    }. 
f840: 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
f850: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 53  LITE_OK ){.    S
f860: 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 4c 61 73  ortSubtask *pLas
f870: 74 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 54  t = &pSorter->aT
f880: 61 73 6b 5b 70 53 6f 72 74 65 72 2d 3e 6e 54 61  ask[pSorter->nTa
f890: 73 6b 2d 31 5d 3b 0a 0a 20 20 20 20 72 63 20 3d  sk-1];..    rc =
f8a0: 20 76 64 62 65 53 6f 72 74 41 6c 6c 6f 63 55 6e   vdbeSortAllocUn
f8b0: 70 61 63 6b 65 64 28 70 4c 61 73 74 29 3b 0a 20  packed(pLast);. 
f8c0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
f8d0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 70 49  E_OK ){.      pI
f8e0: 74 65 72 2d 3e 70 49 6e 63 72 20 3d 20 76 64 62  ter->pIncr = vdb
f8f0: 65 49 6e 63 72 4e 65 77 28 70 4c 61 73 74 2c 20  eIncrNew(pLast, 
f900: 70 4d 61 69 6e 29 3b 0a 20 20 20 20 20 20 69 66  pMain);.      if
f910: 28 20 70 49 74 65 72 2d 3e 70 49 6e 63 72 3d 3d  ( pIter->pIncr==
f920: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  0 ){.        rc 
f930: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
f940: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
f950: 20 20 20 20 20 76 64 62 65 49 6e 63 72 53 65 74       vdbeIncrSet
f960: 54 68 72 65 61 64 73 28 70 49 74 65 72 2d 3e 70  Threads(pIter->p
f970: 49 6e 63 72 2c 20 70 53 6f 72 74 65 72 2d 3e 62  Incr, pSorter->b
f980: 55 73 65 54 68 72 65 61 64 73 29 3b 0a 20 20 20  UseThreads);.   
f990: 20 20 20 20 20 66 6f 72 28 69 54 61 73 6b 3d 30       for(iTask=0
f9a0: 3b 20 69 54 61 73 6b 3c 28 70 53 6f 72 74 65 72  ; iTask<(pSorter
f9b0: 2d 3e 6e 54 61 73 6b 2d 31 29 3b 20 69 54 61 73  ->nTask-1); iTas
f9c0: 6b 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20  k++){.          
f9d0: 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63  IncrMerger *pInc
f9e0: 72 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  r;.          if(
f9f0: 20 28 70 49 6e 63 72 20 3d 20 70 4d 61 69 6e 2d   (pIncr = pMain-
fa00: 3e 61 49 74 65 72 5b 69 54 61 73 6b 5d 2e 70 49  >aIter[iTask].pI
fa10: 6e 63 72 29 20 29 7b 0a 20 20 20 20 20 20 20 20  ncr) ){.        
fa20: 20 20 20 20 76 64 62 65 49 6e 63 72 53 65 74 54      vdbeIncrSetT
fa30: 68 72 65 61 64 73 28 70 49 6e 63 72 2c 20 70 53  hreads(pIncr, pS
fa40: 6f 72 74 65 72 2d 3e 62 55 73 65 54 68 72 65 61  orter->bUseThrea
fa50: 64 73 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  ds);.           
fa60: 20 61 73 73 65 72 74 28 20 70 49 6e 63 72 2d 3e   assert( pIncr->
fa70: 70 54 61 73 6b 21 3d 70 4c 61 73 74 20 29 3b 0a  pTask!=pLast );.
fa80: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
fa90: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20      }.      }.  
faa0: 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 72 63    }.  }.  if( rc
fab0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63  ==SQLITE_OK ) rc
fac0: 20 3d 20 76 64 62 65 49 6e 63 72 49 6e 69 74 32   = vdbeIncrInit2
fad0: 28 70 49 74 65 72 29 3b 0a 0a 20 20 73 71 6c 69  (pIter);..  sqli
fae0: 74 65 33 5f 66 72 65 65 28 61 4d 65 72 67 65 29  te3_free(aMerge)
faf0: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
fb00: 0a 0a 0a 2f 2a 0a 2a 2a 20 4f 6e 63 65 20 74 68  .../*.** Once th
fb10: 65 20 73 6f 72 74 65 72 20 68 61 73 20 62 65 65  e sorter has bee
fb20: 6e 20 70 6f 70 75 6c 61 74 65 64 20 62 79 20 63  n populated by c
fb30: 61 6c 6c 73 20 74 6f 20 73 71 6c 69 74 65 33 56  alls to sqlite3V
fb40: 64 62 65 53 6f 72 74 65 72 57 72 69 74 65 2c 0a  dbeSorterWrite,.
fb50: 2a 2a 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** this function
fb60: 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 70 72   is called to pr
fb70: 65 70 61 72 65 20 66 6f 72 20 69 74 65 72 61 74  epare for iterat
fb80: 69 6e 67 20 74 68 72 6f 75 67 68 20 74 68 65 20  ing through the 
fb90: 72 65 63 6f 72 64 73 0a 2a 2a 20 69 6e 20 73 6f  records.** in so
fba0: 72 74 65 64 20 6f 72 64 65 72 2e 0a 2a 2f 0a 69  rted order..*/.i
fbb0: 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f  nt sqlite3VdbeSo
fbc0: 72 74 65 72 52 65 77 69 6e 64 28 73 71 6c 69 74  rterRewind(sqlit
fbd0: 65 33 20 2a 64 62 2c 20 63 6f 6e 73 74 20 56 64  e3 *db, const Vd
fbe0: 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  beCursor *pCsr, 
fbf0: 69 6e 74 20 2a 70 62 45 6f 66 29 7b 0a 20 20 56  int *pbEof){.  V
fc00: 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
fc10: 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74  er = pCsr->pSort
fc20: 65 72 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  er;.  int rc = S
fc30: 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
fc40: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
fc50: 63 6f 64 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72  code */..  asser
fc60: 74 28 20 70 53 6f 72 74 65 72 20 29 3b 0a 0a 20  t( pSorter );.. 
fc70: 20 2f 2a 20 49 66 20 6e 6f 20 64 61 74 61 20 68   /* If no data h
fc80: 61 73 20 62 65 65 6e 20 77 72 69 74 74 65 6e 20  as been written 
fc90: 74 6f 20 64 69 73 6b 2c 20 74 68 65 6e 20 64 6f  to disk, then do
fca0: 20 6e 6f 74 20 64 6f 20 73 6f 20 6e 6f 77 2e 20   not do so now. 
fcb0: 49 6e 73 74 65 61 64 2c 0a 20 20 2a 2a 20 73 6f  Instead,.  ** so
fcc0: 72 74 20 74 68 65 20 56 64 62 65 53 6f 72 74 65  rt the VdbeSorte
fcd0: 72 2e 70 52 65 63 6f 72 64 20 6c 69 73 74 2e 20  r.pRecord list. 
fce0: 54 68 65 20 76 64 62 65 20 6c 61 79 65 72 20 77  The vdbe layer w
fcf0: 69 6c 6c 20 72 65 61 64 20 64 61 74 61 20 64 69  ill read data di
fd00: 72 65 63 74 6c 79 0a 20 20 2a 2a 20 66 72 6f 6d  rectly.  ** from
fd10: 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c   the in-memory l
fd20: 69 73 74 2e 20 20 2a 2f 0a 20 20 69 66 28 20 70  ist.  */.  if( p
fd30: 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41 3d  Sorter->bUsePMA=
fd40: 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 70 53  =0 ){.    if( pS
fd50: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73  orter->list.pLis
fd60: 74 20 29 7b 0a 20 20 20 20 20 20 2a 70 62 45 6f  t ){.      *pbEo
fd70: 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 63 20  f = 0;.      rc 
fd80: 3d 20 76 64 62 65 53 6f 72 74 65 72 53 6f 72 74  = vdbeSorterSort
fd90: 28 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b  (&pSorter->aTask
fda0: 5b 30 5d 2c 20 26 70 53 6f 72 74 65 72 2d 3e 6c  [0], &pSorter->l
fdb0: 69 73 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  ist);.    }else{
fdc0: 0a 20 20 20 20 20 20 2a 70 62 45 6f 66 20 3d 20  .      *pbEof = 
fdd0: 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74  1;.    }.    ret
fde0: 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f  urn rc;.  }..  /
fdf0: 2a 20 57 72 69 74 65 20 74 68 65 20 63 75 72 72  * Write the curr
fe00: 65 6e 74 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69  ent in-memory li
fe10: 73 74 20 74 6f 20 61 20 50 4d 41 2e 20 2a 2f 0a  st to a PMA. */.
fe20: 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6c    if( pSorter->l
fe30: 69 73 74 2e 70 4c 69 73 74 20 29 7b 0a 20 20 20  ist.pList ){.   
fe40: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
fe50: 46 6c 75 73 68 50 4d 41 28 70 53 6f 72 74 65 72  FlushPMA(pSorter
fe60: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4a 6f 69  );.  }..  /* Joi
fe70: 6e 20 61 6c 6c 20 74 68 72 65 61 64 73 20 2a 2f  n all threads */
fe80: 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74  .  rc = vdbeSort
fe90: 65 72 4a 6f 69 6e 41 6c 6c 28 70 53 6f 72 74 65  erJoinAll(pSorte
fea0: 72 2c 20 72 63 29 3b 0a 0a 20 20 76 64 62 65 53  r, rc);..  vdbeS
feb0: 6f 72 74 65 72 52 65 77 69 6e 64 44 65 62 75 67  orterRewindDebug
fec0: 28 64 62 2c 20 22 72 65 77 69 6e 64 22 29 3b 0a  (db, "rewind");.
fed0: 0a 20 20 2f 2a 20 41 73 73 75 6d 69 6e 67 20 6e  .  /* Assuming n
fee0: 6f 20 65 72 72 6f 72 73 20 68 61 76 65 20 6f 63  o errors have oc
fef0: 63 75 72 72 65 64 2c 20 73 65 74 20 75 70 20 61  curred, set up a
ff00: 20 6d 65 72 67 65 72 20 73 74 72 75 63 74 75 72   merger structur
ff10: 65 20 74 6f 20 0a 20 20 2a 2a 20 69 6e 63 72 65  e to .  ** incre
ff20: 6d 65 6e 74 61 6c 6c 79 20 72 65 61 64 20 61 6e  mentally read an
ff30: 64 20 6d 65 72 67 65 20 61 6c 6c 20 72 65 6d 61  d merge all rema
ff40: 69 6e 69 6e 67 20 50 4d 41 73 2e 20 20 2a 2f 0a  ining PMAs.  */.
ff50: 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65    assert( pSorte
ff60: 72 2d 3e 70 52 65 61 64 65 72 3d 3d 30 20 29 3b  r->pReader==0 );
ff70: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
ff80: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 50 6d 61 52  E_OK ){.    PmaR
ff90: 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 3b 0a  eader *pReader;.
ffa0: 20 20 20 20 70 52 65 61 64 65 72 20 3d 20 28 50      pReader = (P
ffb0: 6d 61 52 65 61 64 65 72 2a 29 73 71 6c 69 74 65  maReader*)sqlite
ffc0: 33 44 62 4d 61 6c 6c 6f 63 5a 65 72 6f 28 64 62  3DbMallocZero(db
ffd0: 2c 20 73 69 7a 65 6f 66 28 50 6d 61 52 65 61 64  , sizeof(PmaRead
ffe0: 65 72 29 29 3b 0a 20 20 20 20 70 53 6f 72 74 65  er));.    pSorte
fff0: 72 2d 3e 70 52 65 61 64 65 72 20 3d 20 70 52 65  r->pReader = pRe
10000 61 64 65 72 3b 0a 20 20 20 20 72 63 20 3d 20 76  ader;.    rc = v
10010 64 62 65 50 6d 61 52 65 61 64 65 72 49 6e 63 72  dbePmaReaderIncr
10020 49 6e 69 74 28 70 53 6f 72 74 65 72 2c 20 70 52  Init(pSorter, pR
10030 65 61 64 65 72 29 3b 0a 20 20 20 20 61 73 73 65  eader);.    asse
10040 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  rt( rc!=SQLITE_O
10050 4b 20 7c 7c 20 70 52 65 61 64 65 72 2d 3e 70 46  K || pReader->pF
10060 69 6c 65 20 29 3b 0a 20 20 20 20 2a 70 62 45 6f  ile );.    *pbEo
10070 66 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 76 64  f = 0;.  }..  vd
10080 62 65 53 6f 72 74 65 72 52 65 77 69 6e 64 44 65  beSorterRewindDe
10090 62 75 67 28 64 62 2c 20 22 72 65 77 69 6e 64 64  bug(db, "rewindd
100a0 6f 6e 65 22 29 3b 0a 20 20 72 65 74 75 72 6e 20  one");.  return 
100b0 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76  rc;.}../*.** Adv
100c0 61 6e 63 65 20 74 6f 20 74 68 65 20 6e 65 78 74  ance to the next
100d0 20 65 6c 65 6d 65 6e 74 20 69 6e 20 74 68 65 20   element in the 
100e0 73 6f 72 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20 73  sorter..*/.int s
100f0 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72  qlite3VdbeSorter
10100 4e 65 78 74 28 73 71 6c 69 74 65 33 20 2a 64 62  Next(sqlite3 *db
10110 2c 20 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73  , const VdbeCurs
10120 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74 20 2a 70  or *pCsr, int *p
10130 62 45 6f 66 29 7b 0a 20 20 56 64 62 65 53 6f 72  bEof){.  VdbeSor
10140 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70  ter *pSorter = p
10150 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20  Csr->pSorter;.  
10160 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
10170 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10180 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
10190 2f 0a 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72  /..  if( pSorter
101a0 2d 3e 70 52 65 61 64 65 72 20 29 7b 0a 20 20 20  ->pReader ){.   
101b0 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61   rc = vdbePmaRea
101c0 64 65 72 4e 65 78 74 28 70 53 6f 72 74 65 72 2d  derNext(pSorter-
101d0 3e 70 52 65 61 64 65 72 29 3b 0a 20 20 20 20 2a  >pReader);.    *
101e0 70 62 45 6f 66 20 3d 20 28 70 53 6f 72 74 65 72  pbEof = (pSorter
101f0 2d 3e 70 52 65 61 64 65 72 2d 3e 70 46 69 6c 65  ->pReader->pFile
10200 3d 3d 30 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  ==0);.  }else{. 
10210 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20     SorterRecord 
10220 2a 70 46 72 65 65 20 3d 20 70 53 6f 72 74 65 72  *pFree = pSorter
10230 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 3b 0a 20 20  ->list.pList;.  
10240 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e    pSorter->list.
10250 70 4c 69 73 74 20 3d 20 70 46 72 65 65 2d 3e 75  pList = pFree->u
10260 2e 70 4e 65 78 74 3b 0a 20 20 20 20 70 46 72 65  .pNext;.    pFre
10270 65 2d 3e 75 2e 70 4e 65 78 74 20 3d 20 30 3b 0a  e->u.pNext = 0;.
10280 20 20 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d      if( pSorter-
10290 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30  >list.aMemory==0
102a0 20 29 20 76 64 62 65 53 6f 72 74 65 72 52 65 63   ) vdbeSorterRec
102b0 6f 72 64 46 72 65 65 28 64 62 2c 20 70 46 72 65  ordFree(db, pFre
102c0 65 29 3b 0a 20 20 20 20 2a 70 62 45 6f 66 20 3d  e);.    *pbEof =
102d0 20 21 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e   !pSorter->list.
102e0 70 4c 69 73 74 3b 0a 20 20 20 20 72 63 20 3d 20  pList;.    rc = 
102f0 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 20  SQLITE_OK;.  }. 
10300 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
10310 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f  *.** Return a po
10320 69 6e 74 65 72 20 74 6f 20 61 20 62 75 66 66 65  inter to a buffe
10330 72 20 6f 77 6e 65 64 20 62 79 20 74 68 65 20 73  r owned by the s
10340 6f 72 74 65 72 20 74 68 61 74 20 63 6f 6e 74 61  orter that conta
10350 69 6e 73 20 74 68 65 20 0a 2a 2a 20 63 75 72 72  ins the .** curr
10360 65 6e 74 20 6b 65 79 2e 0a 2a 2f 0a 73 74 61 74  ent key..*/.stat
10370 69 63 20 76 6f 69 64 20 2a 76 64 62 65 53 6f 72  ic void *vdbeSor
10380 74 65 72 52 6f 77 6b 65 79 28 0a 20 20 63 6f 6e  terRowkey(.  con
10390 73 74 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70  st VdbeSorter *p
103a0 53 6f 72 74 65 72 2c 20 20 20 20 20 20 2f 2a 20  Sorter,      /* 
103b0 53 6f 72 74 65 72 20 6f 62 6a 65 63 74 20 2a 2f  Sorter object */
103c0 0a 20 20 69 6e 74 20 2a 70 6e 4b 65 79 20 20 20  .  int *pnKey   
103d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
103e0 20 20 20 2f 2a 20 4f 55 54 3a 20 53 69 7a 65 20     /* OUT: Size 
103f0 6f 66 20 63 75 72 72 65 6e 74 20 6b 65 79 20 69  of current key i
10400 6e 20 62 79 74 65 73 20 2a 2f 0a 29 7b 0a 20 20  n bytes */.){.  
10410 76 6f 69 64 20 2a 70 4b 65 79 3b 0a 20 20 69 66  void *pKey;.  if
10420 28 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 61 64  ( pSorter->pRead
10430 65 72 20 29 7b 0a 20 20 20 20 2a 70 6e 4b 65 79  er ){.    *pnKey
10440 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 61   = pSorter->pRea
10450 64 65 72 2d 3e 6e 4b 65 79 3b 0a 20 20 20 20 70  der->nKey;.    p
10460 4b 65 79 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70  Key = pSorter->p
10470 52 65 61 64 65 72 2d 3e 61 4b 65 79 3b 0a 20 20  Reader->aKey;.  
10480 7d 65 6c 73 65 7b 0a 20 20 20 20 2a 70 6e 4b 65  }else{.    *pnKe
10490 79 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73  y = pSorter->lis
104a0 74 2e 70 4c 69 73 74 2d 3e 6e 56 61 6c 3b 0a 20  t.pList->nVal;. 
104b0 20 20 20 70 4b 65 79 20 3d 20 53 52 56 41 4c 28     pKey = SRVAL(
104c0 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c  pSorter->list.pL
104d0 69 73 74 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  ist);.  }.  retu
104e0 72 6e 20 70 4b 65 79 3b 0a 7d 0a 0a 2f 2a 0a 2a  rn pKey;.}../*.*
104f0 2a 20 43 6f 70 79 20 74 68 65 20 63 75 72 72 65  * Copy the curre
10500 6e 74 20 73 6f 72 74 65 72 20 6b 65 79 20 69 6e  nt sorter key in
10510 74 6f 20 74 68 65 20 6d 65 6d 6f 72 79 20 63 65  to the memory ce
10520 6c 6c 20 70 4f 75 74 2e 0a 2a 2f 0a 69 6e 74 20  ll pOut..*/.int 
10530 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
10540 72 52 6f 77 6b 65 79 28 63 6f 6e 73 74 20 56 64  rRowkey(const Vd
10550 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  beCursor *pCsr, 
10560 4d 65 6d 20 2a 70 4f 75 74 29 7b 0a 20 20 56 64  Mem *pOut){.  Vd
10570 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
10580 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65  r = pCsr->pSorte
10590 72 3b 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 3b  r;.  void *pKey;
105a0 20 69 6e 74 20 6e 4b 65 79 3b 20 20 20 20 20 20   int nKey;      
105b0 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 6b       /* Sorter k
105c0 65 79 20 74 6f 20 63 6f 70 79 20 69 6e 74 6f 20  ey to copy into 
105d0 70 4f 75 74 20 2a 2f 0a 0a 20 20 70 4b 65 79 20  pOut */..  pKey 
105e0 3d 20 76 64 62 65 53 6f 72 74 65 72 52 6f 77 6b  = vdbeSorterRowk
105f0 65 79 28 70 53 6f 72 74 65 72 2c 20 26 6e 4b 65  ey(pSorter, &nKe
10600 79 29 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65  y);.  if( sqlite
10610 33 56 64 62 65 4d 65 6d 47 72 6f 77 28 70 4f 75  3VdbeMemGrow(pOu
10620 74 2c 20 6e 4b 65 79 2c 20 30 29 20 29 7b 0a 20  t, nKey, 0) ){. 
10630 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
10640 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 70 4f  _NOMEM;.  }.  pO
10650 75 74 2d 3e 6e 20 3d 20 6e 4b 65 79 3b 0a 20 20  ut->n = nKey;.  
10660 4d 65 6d 53 65 74 54 79 70 65 46 6c 61 67 28 70  MemSetTypeFlag(p
10670 4f 75 74 2c 20 4d 45 4d 5f 42 6c 6f 62 29 3b 0a  Out, MEM_Blob);.
10680 20 20 6d 65 6d 63 70 79 28 70 4f 75 74 2d 3e 7a    memcpy(pOut->z
10690 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 0a  , pKey, nKey);..
106a0 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
106b0 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d  OK;.}../*.** Com
106c0 70 61 72 65 20 74 68 65 20 6b 65 79 20 69 6e 20  pare the key in 
106d0 6d 65 6d 6f 72 79 20 63 65 6c 6c 20 70 56 61 6c  memory cell pVal
106e0 20 77 69 74 68 20 74 68 65 20 6b 65 79 20 74 68   with the key th
106f0 61 74 20 74 68 65 20 73 6f 72 74 65 72 20 63 75  at the sorter cu
10700 72 73 6f 72 0a 2a 2a 20 70 61 73 73 65 64 20 61  rsor.** passed a
10710 73 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75  s the first argu
10720 6d 65 6e 74 20 63 75 72 72 65 6e 74 6c 79 20 70  ment currently p
10730 6f 69 6e 74 73 20 74 6f 2e 20 46 6f 72 20 74 68  oints to. For th
10740 65 20 70 75 72 70 6f 73 65 73 20 6f 66 0a 2a 2a  e purposes of.**
10750 20 74 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2c   the comparison,
10760 20 69 67 6e 6f 72 65 20 74 68 65 20 72 6f 77 69   ignore the rowi
10770 64 20 66 69 65 6c 64 20 61 74 20 74 68 65 20 65  d field at the e
10780 6e 64 20 6f 66 20 65 61 63 68 20 72 65 63 6f 72  nd of each recor
10790 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20  d..**.** If the 
107a0 73 6f 72 74 65 72 20 63 75 72 73 6f 72 20 6b 65  sorter cursor ke
107b0 79 20 63 6f 6e 74 61 69 6e 73 20 61 6e 79 20 4e  y contains any N
107c0 55 4c 4c 20 76 61 6c 75 65 73 2c 20 63 6f 6e 73  ULL values, cons
107d0 69 64 65 72 20 69 74 20 74 6f 20 62 65 0a 2a 2a  ider it to be.**
107e0 20 6c 65 73 73 20 74 68 61 6e 20 70 56 61 6c 2e   less than pVal.
107f0 20 45 76 65 6e 20 69 66 20 70 56 61 6c 20 61 6c   Even if pVal al
10800 73 6f 20 63 6f 6e 74 61 69 6e 73 20 4e 55 4c 4c  so contains NULL
10810 20 76 61 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 49   values..**.** I
10820 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
10830 73 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c  s, return an SQL
10840 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 28  ite error code (
10850 69 2e 65 2e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  i.e. SQLITE_NOME
10860 4d 29 2e 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65  M)..** Otherwise
10870 2c 20 73 65 74 20 2a 70 52 65 73 20 74 6f 20 61  , set *pRes to a
10880 20 6e 65 67 61 74 69 76 65 2c 20 7a 65 72 6f 20   negative, zero 
10890 6f 72 20 70 6f 73 69 74 69 76 65 20 76 61 6c 75  or positive valu
108a0 65 20 69 66 20 74 68 65 0a 2a 2a 20 6b 65 79 20  e if the.** key 
108b0 69 6e 20 70 56 61 6c 20 69 73 20 73 6d 61 6c 6c  in pVal is small
108c0 65 72 20 74 68 61 6e 2c 20 65 71 75 61 6c 20 74  er than, equal t
108d0 6f 20 6f 72 20 6c 61 72 67 65 72 20 74 68 61 6e  o or larger than
108e0 20 74 68 65 20 63 75 72 72 65 6e 74 20 73 6f 72   the current sor
108f0 74 65 72 0a 2a 2a 20 6b 65 79 2e 0a 2a 2a 0a 2a  ter.** key..**.*
10900 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 66  * This routine f
10910 6f 72 6d 73 20 74 68 65 20 63 6f 72 65 20 6f 66  orms the core of
10920 20 74 68 65 20 4f 50 5f 53 6f 72 74 65 72 43 6f   the OP_SorterCo
10930 6d 70 61 72 65 20 6f 70 63 6f 64 65 2c 20 77 68  mpare opcode, wh
10940 69 63 68 20 69 6e 0a 2a 2a 20 74 75 72 6e 20 69  ich in.** turn i
10950 73 20 75 73 65 64 20 74 6f 20 76 65 72 69 66 79  s used to verify
10960 20 75 6e 69 71 75 65 6e 65 73 73 20 77 68 65 6e   uniqueness when
10970 20 63 6f 6e 73 74 72 75 63 74 69 6e 67 20 61 20   constructing a 
10980 55 4e 49 51 55 45 20 49 4e 44 45 58 2e 0a 2a 2f  UNIQUE INDEX..*/
10990 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65  .int sqlite3Vdbe
109a0 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 0a 20  SorterCompare(. 
109b0 20 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f   const VdbeCurso
109c0 72 20 2a 70 43 73 72 2c 20 20 20 20 20 20 20 20  r *pCsr,        
109d0 20 2f 2a 20 53 6f 72 74 65 72 20 63 75 72 73 6f   /* Sorter curso
109e0 72 20 2a 2f 0a 20 20 4d 65 6d 20 2a 70 56 61 6c  r */.  Mem *pVal
109f0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
10a00 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20         /* Value 
10a10 74 6f 20 63 6f 6d 70 61 72 65 20 74 6f 20 63 75  to compare to cu
10a20 72 72 65 6e 74 20 73 6f 72 74 65 72 20 6b 65 79  rrent sorter key
10a30 20 2a 2f 0a 20 20 69 6e 74 20 6e 49 67 6e 6f 72   */.  int nIgnor
10a40 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
10a50 20 20 20 20 20 20 2f 2a 20 49 67 6e 6f 72 65 20        /* Ignore 
10a60 74 68 69 73 20 6d 61 6e 79 20 66 69 65 6c 64 73  this many fields
10a70 20 61 74 20 74 68 65 20 65 6e 64 20 2a 2f 0a 20   at the end */. 
10a80 20 69 6e 74 20 2a 70 52 65 73 20 20 20 20 20 20   int *pRes      
10a90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10aa0 20 2f 2a 20 4f 55 54 3a 20 52 65 73 75 6c 74 20   /* OUT: Result 
10ab0 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f  of comparison */
10ac0 0a 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72  .){.  VdbeSorter
10ad0 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72   *pSorter = pCsr
10ae0 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 55 6e 70  ->pSorter;.  Unp
10af0 61 63 6b 65 64 52 65 63 6f 72 64 20 2a 72 32 20  ackedRecord *r2 
10b00 3d 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61  = pSorter->pUnpa
10b10 63 6b 65 64 3b 0a 20 20 4b 65 79 49 6e 66 6f 20  cked;.  KeyInfo 
10b20 2a 70 4b 65 79 49 6e 66 6f 20 3d 20 70 43 73 72  *pKeyInfo = pCsr
10b30 2d 3e 70 4b 65 79 49 6e 66 6f 3b 0a 20 20 69 6e  ->pKeyInfo;.  in
10b40 74 20 69 3b 0a 20 20 76 6f 69 64 20 2a 70 4b 65  t i;.  void *pKe
10b50 79 3b 20 69 6e 74 20 6e 4b 65 79 3b 20 20 20 20  y; int nKey;    
10b60 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72         /* Sorter
10b70 20 6b 65 79 20 74 6f 20 63 6f 6d 70 61 72 65 20   key to compare 
10b80 70 56 61 6c 20 77 69 74 68 20 2a 2f 0a 0a 20 20  pVal with */..  
10b90 69 66 28 20 72 32 3d 3d 30 20 29 7b 0a 20 20 20  if( r2==0 ){.   
10ba0 20 63 68 61 72 20 2a 70 3b 0a 20 20 20 20 72 32   char *p;.    r2
10bb0 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70   = pSorter->pUnp
10bc0 61 63 6b 65 64 20 3d 20 73 71 6c 69 74 65 33 56  acked = sqlite3V
10bd0 64 62 65 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64  dbeAllocUnpacked
10be0 52 65 63 6f 72 64 28 70 4b 65 79 49 6e 66 6f 2c  Record(pKeyInfo,
10bf0 30 2c 30 2c 26 70 29 3b 0a 20 20 20 20 61 73 73  0,0,&p);.    ass
10c00 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 70 55  ert( pSorter->pU
10c10 6e 70 61 63 6b 65 64 3d 3d 28 55 6e 70 61 63 6b  npacked==(Unpack
10c20 65 64 52 65 63 6f 72 64 2a 29 70 20 29 3b 0a 20  edRecord*)p );. 
10c30 20 20 20 69 66 28 20 72 32 3d 3d 30 20 29 20 72     if( r2==0 ) r
10c40 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
10c50 45 4d 3b 0a 20 20 20 20 72 32 2d 3e 6e 46 69 65  EM;.    r2->nFie
10c60 6c 64 20 3d 20 70 4b 65 79 49 6e 66 6f 2d 3e 6e  ld = pKeyInfo->n
10c70 46 69 65 6c 64 2d 6e 49 67 6e 6f 72 65 3b 0a 20  Field-nIgnore;. 
10c80 20 7d 0a 20 20 61 73 73 65 72 74 28 20 72 32 2d   }.  assert( r2-
10c90 3e 6e 46 69 65 6c 64 3e 3d 70 4b 65 79 49 6e 66  >nField>=pKeyInf
10ca0 6f 2d 3e 6e 46 69 65 6c 64 2d 6e 49 67 6e 6f 72  o->nField-nIgnor
10cb0 65 20 29 3b 0a 0a 20 20 70 4b 65 79 20 3d 20 76  e );..  pKey = v
10cc0 64 62 65 53 6f 72 74 65 72 52 6f 77 6b 65 79 28  dbeSorterRowkey(
10cd0 70 53 6f 72 74 65 72 2c 20 26 6e 4b 65 79 29 3b  pSorter, &nKey);
10ce0 0a 20 20 73 71 6c 69 74 65 33 56 64 62 65 52 65  .  sqlite3VdbeRe
10cf0 63 6f 72 64 55 6e 70 61 63 6b 28 70 4b 65 79 49  cordUnpack(pKeyI
10d00 6e 66 6f 2c 20 6e 4b 65 79 2c 20 70 4b 65 79 2c  nfo, nKey, pKey,
10d10 20 72 32 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b   r2);.  for(i=0;
10d20 20 69 3c 72 32 2d 3e 6e 46 69 65 6c 64 3b 20 69   i<r2->nField; i
10d30 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 72 32 2d  ++){.    if( r2-
10d40 3e 61 4d 65 6d 5b 69 5d 2e 66 6c 61 67 73 20 26  >aMem[i].flags &
10d50 20 4d 45 4d 5f 4e 75 6c 6c 20 29 7b 0a 20 20 20   MEM_Null ){.   
10d60 20 20 20 2a 70 52 65 73 20 3d 20 2d 31 3b 0a 20     *pRes = -1;. 
10d70 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
10d80 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 7d  TE_OK;.    }.  }
10d90 0a 0a 20 20 2a 70 52 65 73 20 3d 20 73 71 6c 69  ..  *pRes = sqli
10da0 74 65 33 56 64 62 65 52 65 63 6f 72 64 43 6f 6d  te3VdbeRecordCom
10db0 70 61 72 65 28 70 56 61 6c 2d 3e 6e 2c 20 70 56  pare(pVal->n, pV
10dc0 61 6c 2d 3e 7a 2c 20 72 32 2c 20 30 29 3b 0a 20  al->z, r2, 0);. 
10dd0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
10de0 4b 3b 0a 7d 0a                                   K;.}.