/ Hex Artifact Content
Login

Artifact 56c663772aaa7cd790ba2eb8f3bd3b4a4ac1fa4d:


0000: 2f 2a 0a 2a 2a 20 32 30 31 31 2d 30 37 2d 30 39  /*.** 2011-07-09
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a  ***************.
0170: 2a 2a 20 54 68 69 73 20 66 69 6c 65 20 63 6f 6e  ** This file con
0180: 74 61 69 6e 73 20 63 6f 64 65 20 66 6f 72 20 74  tains code for t
0190: 68 65 20 56 64 62 65 53 6f 72 74 65 72 20 6f 62  he VdbeSorter ob
01a0: 6a 65 63 74 2c 20 75 73 65 64 20 69 6e 20 63 6f  ject, used in co
01b0: 6e 63 65 72 74 20 77 69 74 68 0a 2a 2a 20 61 20  ncert with.** a 
01c0: 56 64 62 65 43 75 72 73 6f 72 20 74 6f 20 73 6f  VdbeCursor to so
01d0: 72 74 20 6c 61 72 67 65 20 6e 75 6d 62 65 72 73  rt large numbers
01e0: 20 6f 66 20 6b 65 79 73 20 66 6f 72 20 43 52 45   of keys for CRE
01f0: 41 54 45 20 49 4e 44 45 58 20 73 74 61 74 65 6d  ATE INDEX statem
0200: 65 6e 74 73 0a 2a 2a 20 6f 72 20 62 79 20 53 45  ents.** or by SE
0210: 4c 45 43 54 20 73 74 61 74 65 6d 65 6e 74 73 20  LECT statements 
0220: 77 69 74 68 20 4f 52 44 45 52 20 42 59 20 63 6c  with ORDER BY cl
0230: 61 75 73 65 73 20 74 68 61 74 20 63 61 6e 6e 6f  auses that canno
0240: 74 20 62 65 20 73 61 74 69 73 66 69 65 64 0a 2a  t be satisfied.*
0250: 2a 20 75 73 69 6e 67 20 69 6e 64 65 78 65 73 20  * using indexes 
0260: 61 6e 64 20 77 69 74 68 6f 75 74 20 4c 49 4d 49  and without LIMI
0270: 54 20 63 6c 61 75 73 65 73 2e 0a 2a 2a 0a 2a 2a  T clauses..**.**
0280: 20 54 68 65 20 56 64 62 65 53 6f 72 74 65 72 20   The VdbeSorter 
0290: 6f 62 6a 65 63 74 20 69 6d 70 6c 65 6d 65 6e 74  object implement
02a0: 73 20 61 20 6d 75 6c 74 69 2d 74 68 72 65 61 64  s a multi-thread
02b0: 65 64 20 65 78 74 65 72 6e 61 6c 20 6d 65 72 67  ed external merg
02c0: 65 20 73 6f 72 74 0a 2a 2a 20 61 6c 67 6f 72 69  e sort.** algori
02d0: 74 68 6d 20 74 68 61 74 20 69 73 20 65 66 66 69  thm that is effi
02e0: 63 69 65 6e 74 20 65 76 65 6e 20 69 66 20 74 68  cient even if th
02f0: 65 20 6e 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d  e number of elem
0300: 65 6e 74 20 62 65 69 6e 67 20 73 6f 72 74 65 64  ent being sorted
0310: 0a 2a 2a 20 65 78 63 65 65 64 73 20 74 68 65 20  .** exceeds the 
0320: 61 76 61 69 6c 61 62 6c 65 20 6d 65 6d 6f 72 79  available memory
0330: 2e 0a 2a 2a 0a 2a 2a 20 48 65 72 65 20 69 73 20  ..**.** Here is 
0340: 74 68 65 20 28 69 6e 74 65 72 6e 61 6c 2c 20 6e  the (internal, n
0350: 6f 6e 2d 41 50 49 29 20 69 6e 74 65 72 66 61 63  on-API) interfac
0360: 65 20 62 65 74 77 65 65 6e 20 74 68 69 73 20 6d  e between this m
0370: 6f 64 75 6c 65 20 61 6e 64 20 74 68 65 0a 2a 2a  odule and the.**
0380: 20 72 65 73 74 20 6f 66 20 74 68 65 20 53 51 4c   rest of the SQL
0390: 69 74 65 20 73 79 73 74 65 6d 3a 0a 2a 2a 0a 2a  ite system:.**.*
03a0: 2a 20 20 20 20 73 71 6c 69 74 65 33 56 64 62 65  *    sqlite3Vdbe
03b0: 53 6f 72 74 65 72 49 6e 69 74 28 29 20 20 20 20  SorterInit()    
03c0: 20 20 20 43 72 65 61 74 65 20 61 20 6e 65 77 20     Create a new 
03d0: 56 64 62 65 53 6f 72 74 65 72 20 6f 62 6a 65 63  VdbeSorter objec
03e0: 74 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71 6c 69  t..**.**    sqli
03f0: 74 65 33 56 64 62 65 53 6f 72 74 65 72 57 72 69  te3VdbeSorterWri
0400: 74 65 28 29 20 20 20 20 20 20 41 64 64 20 61 20  te()      Add a 
0410: 73 69 6e 67 6c 65 20 6e 65 77 20 72 6f 77 20 74  single new row t
0420: 6f 20 74 68 65 20 56 64 62 65 53 6f 72 74 65 72  o the VdbeSorter
0430: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20  .**             
0440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0450: 20 20 20 20 20 6f 62 6a 65 63 74 2e 20 20 54 68       object.  Th
0460: 65 20 72 6f 77 20 69 73 20 61 20 62 69 6e 61 72  e row is a binar
0470: 79 20 62 6c 6f 62 20 69 6e 20 74 68 65 0a 2a 2a  y blob in the.**
0480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04a0: 20 20 4f 50 5f 4d 61 6b 65 52 65 63 6f 72 64 20    OP_MakeRecord 
04b0: 66 6f 72 6d 61 74 20 74 68 61 74 20 63 6f 6e 74  format that cont
04c0: 61 69 6e 73 20 62 6f 74 68 0a 2a 2a 20 20 20 20  ains both.**    
04d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 74 68                th
04f0: 65 20 4f 52 44 45 52 20 42 59 20 6b 65 79 20 63  e ORDER BY key c
0500: 6f 6c 75 6d 6e 73 20 61 6e 64 20 72 65 73 75 6c  olumns and resul
0510: 74 20 63 6f 6c 75 6d 6e 73 0a 2a 2a 20 20 20 20  t columns.**    
0520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e                in
0540: 20 74 68 65 20 63 61 73 65 20 6f 66 20 61 20 53   the case of a S
0550: 45 4c 45 43 54 20 77 2f 20 4f 52 44 45 52 20 42  ELECT w/ ORDER B
0560: 59 2c 20 6f 72 0a 2a 2a 20 20 20 20 20 20 20 20  Y, or.**        
0570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0580: 20 20 20 20 20 20 20 20 20 20 74 68 65 20 63 6f            the co
0590: 6d 70 6c 65 74 65 20 72 65 63 6f 72 64 20 66 6f  mplete record fo
05a0: 72 20 61 6e 20 69 6e 64 65 78 20 65 6e 74 72 79  r an index entry
05b0: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20  .**             
05c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05d0: 20 20 20 20 20 69 6e 20 74 68 65 20 63 61 73 65       in the case
05e0: 20 6f 66 20 61 20 43 52 45 41 54 45 20 49 4e 44   of a CREATE IND
05f0: 45 58 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71 6c  EX..**.**    sql
0600: 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 52 65  ite3VdbeSorterRe
0610: 77 69 6e 64 28 29 20 20 20 20 20 53 6f 72 74 20  wind()     Sort 
0620: 61 6c 6c 20 63 6f 6e 74 65 6e 74 20 70 72 65 76  all content prev
0630: 69 6f 75 73 6c 79 20 61 64 64 65 64 2e 0a 2a 2a  iously added..**
0640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0660: 20 20 50 6f 73 69 74 69 6f 6e 20 74 68 65 20 72    Position the r
0670: 65 61 64 20 63 75 72 73 6f 72 20 6f 6e 20 74 68  ead cursor on th
0680: 65 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20  e.**            
0690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06a0: 20 20 20 20 20 20 66 69 72 73 74 20 73 6f 72 74        first sort
06b0: 65 64 20 65 6c 65 6d 65 6e 74 2e 0a 2a 2a 0a 2a  ed element..**.*
06c0: 2a 20 20 20 20 73 71 6c 69 74 65 33 56 64 62 65  *    sqlite3Vdbe
06d0: 53 6f 72 74 65 72 4e 65 78 74 28 29 20 20 20 20  SorterNext()    
06e0: 20 20 20 41 64 76 61 6e 63 65 20 74 68 65 20 72     Advance the r
06f0: 65 61 64 20 63 75 72 73 6f 72 20 74 6f 20 74 68  ead cursor to th
0700: 65 20 6e 65 78 74 20 73 6f 72 74 65 64 0a 2a 2a  e next sorted.**
0710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0730: 20 20 65 6c 65 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a    element..**.**
0740: 20 20 20 20 73 71 6c 69 74 65 33 56 64 62 65 53      sqlite3VdbeS
0750: 6f 72 74 65 72 52 6f 77 6b 65 79 28 29 20 20 20  orterRowkey()   
0760: 20 20 52 65 74 75 72 6e 20 74 68 65 20 63 6f 6d    Return the com
0770: 70 6c 65 74 65 20 62 69 6e 61 72 79 20 62 6c 6f  plete binary blo
0780: 62 20 66 6f 72 20 74 68 65 0a 2a 2a 20 20 20 20  b for the.**    
0790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72 6f                ro
07b0: 77 20 63 75 72 72 65 6e 74 6c 79 20 75 6e 64 65  w currently unde
07c0: 72 20 74 68 65 20 72 65 61 64 20 63 75 72 73 6f  r the read curso
07d0: 72 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71 6c 69  r..**.**    sqli
07e0: 74 65 33 56 64 62 65 53 6f 72 74 65 72 43 6f 6d  te3VdbeSorterCom
07f0: 70 61 72 65 28 29 20 20 20 20 43 6f 6d 70 61 72  pare()    Compar
0800: 65 20 74 68 65 20 62 69 6e 61 72 79 20 62 6c 6f  e the binary blo
0810: 62 20 66 6f 72 20 74 68 65 20 72 6f 77 0a 2a 2a  b for the row.**
0820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0840: 20 20 63 75 72 72 65 6e 74 6c 79 20 75 6e 64 65    currently unde
0850: 72 20 74 68 65 20 72 65 61 64 20 63 75 72 73 6f  r the read curso
0860: 72 20 61 67 61 69 6e 73 74 0a 2a 2a 20 20 20 20  r against.**    
0870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 6e                an
0890: 6f 74 68 65 72 20 62 69 6e 61 72 79 20 62 6c 6f  other binary blo
08a0: 62 20 58 20 61 6e 64 20 72 65 70 6f 72 74 20 69  b X and report i
08b0: 66 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20  f.**            
08c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08d0: 20 20 20 20 20 20 58 20 69 73 20 73 74 72 69 63        X is stric
08e0: 74 6c 79 20 6c 65 73 73 20 74 68 61 6e 20 74 68  tly less than th
08f0: 65 20 72 65 61 64 20 63 75 72 73 6f 72 2e 0a 2a  e read cursor..*
0900: 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  *               
0910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0920: 20 20 20 55 73 65 64 20 74 6f 20 65 6e 66 6f 72     Used to enfor
0930: 63 65 20 75 6e 69 71 75 65 6e 65 73 73 20 69 6e  ce uniqueness in
0940: 20 61 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20   a.**           
0950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0960: 20 20 20 20 20 20 20 43 52 45 41 54 45 20 55 4e         CREATE UN
0970: 49 51 55 45 20 49 4e 44 45 58 20 73 74 61 74 65  IQUE INDEX state
0980: 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73  ment..**.**    s
0990: 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72  qlite3VdbeSorter
09a0: 43 6c 6f 73 65 28 29 20 20 20 20 20 20 43 6c 6f  Close()      Clo
09b0: 73 65 20 74 68 65 20 56 64 62 65 53 6f 72 74 65  se the VdbeSorte
09c0: 72 20 6f 62 6a 65 63 74 20 61 6e 64 20 72 65 63  r object and rec
09d0: 6c 61 69 6d 0a 2a 2a 20 20 20 20 20 20 20 20 20  laim.**         
09e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09f0: 20 20 20 20 20 20 20 20 20 61 6c 6c 20 72 65 73           all res
0a00: 6f 75 72 63 65 73 2e 0a 2a 2a 0a 2a 2a 20 20 20  ources..**.**   
0a10: 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74   sqlite3VdbeSort
0a20: 65 72 52 65 73 65 74 28 29 20 20 20 20 20 20 52  erReset()      R
0a30: 65 66 75 72 62 69 73 68 20 74 68 65 20 56 64 62  efurbish the Vdb
0a40: 65 53 6f 72 74 65 72 20 66 6f 72 20 72 65 75 73  eSorter for reus
0a50: 65 2e 20 20 54 68 69 73 0a 2a 2a 20 20 20 20 20  e.  This.**     
0a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 73 20               is 
0a80: 6c 69 6b 65 20 43 6c 6f 73 65 28 29 20 66 6f 6c  like Close() fol
0a90: 6c 6f 77 65 64 20 62 79 20 49 6e 69 74 28 29 20  lowed by Init() 
0aa0: 6f 6e 6c 79 0a 2a 2a 20 20 20 20 20 20 20 20 20  only.**         
0ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ac0: 20 20 20 20 20 20 20 20 20 6d 75 63 68 20 66 61           much fa
0ad0: 73 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ster..**.** The 
0ae0: 69 6e 74 65 72 66 61 63 65 73 20 61 62 6f 76 65  interfaces above
0af0: 20 6d 75 73 74 20 62 65 20 63 61 6c 6c 65 64 20   must be called 
0b00: 69 6e 20 61 20 70 61 72 74 69 63 75 6c 61 72 20  in a particular 
0b10: 6f 72 64 65 72 2e 20 20 57 72 69 74 65 28 29 20  order.  Write() 
0b20: 63 61 6e 20 0a 2a 2a 20 6f 6e 6c 79 20 6f 63 63  can .** only occ
0b30: 75 72 20 69 6e 20 62 65 74 77 65 65 6e 20 49 6e  ur in between In
0b40: 69 74 28 29 2f 52 65 73 65 74 28 29 20 61 6e 64  it()/Reset() and
0b50: 20 52 65 77 69 6e 64 28 29 2e 20 20 4e 65 78 74   Rewind().  Next
0b60: 28 29 2c 20 52 6f 77 6b 65 79 28 29 2c 20 61 6e  (), Rowkey(), an
0b70: 64 0a 2a 2a 20 43 6f 6d 70 61 72 65 28 29 20 63  d.** Compare() c
0b80: 61 6e 20 6f 6e 6c 79 20 6f 63 63 75 72 20 69 6e  an only occur in
0b90: 20 62 65 74 77 65 65 6e 20 52 65 77 69 6e 64 28   between Rewind(
0ba0: 29 20 61 6e 64 20 43 6c 6f 73 65 28 29 2f 52 65  ) and Close()/Re
0bb0: 73 65 74 28 29 2e 20 69 2e 65 2e 0a 2a 2a 0a 2a  set(). i.e..**.*
0bc0: 2a 20 20 20 49 6e 69 74 28 29 0a 2a 2a 20 20 20  *   Init().**   
0bd0: 66 6f 72 20 65 61 63 68 20 72 65 63 6f 72 64 3a  for each record:
0be0: 20 57 72 69 74 65 28 29 0a 2a 2a 20 20 20 52 65   Write().**   Re
0bf0: 77 69 6e 64 28 29 0a 2a 2a 20 20 20 20 20 52 6f  wind().**     Ro
0c00: 77 6b 65 79 28 29 2f 43 6f 6d 70 61 72 65 28 29  wkey()/Compare()
0c10: 0a 2a 2a 20 20 20 4e 65 78 74 28 29 20 0a 2a 2a  .**   Next() .**
0c20: 20 20 20 43 6c 6f 73 65 28 29 0a 2a 2a 0a 2a 2a     Close().**.**
0c30: 20 41 6c 67 6f 72 69 74 68 6d 3a 0a 2a 2a 0a 2a   Algorithm:.**.*
0c40: 2a 20 52 65 63 6f 72 64 73 20 70 61 73 73 65 64  * Records passed
0c50: 20 74 6f 20 74 68 65 20 73 6f 72 74 65 72 20 76   to the sorter v
0c60: 69 61 20 63 61 6c 6c 73 20 74 6f 20 57 72 69 74  ia calls to Writ
0c70: 65 28 29 20 61 72 65 20 69 6e 69 74 69 61 6c 6c  e() are initiall
0c80: 79 20 68 65 6c 64 20 0a 2a 2a 20 75 6e 73 6f 72  y held .** unsor
0c90: 74 65 64 20 69 6e 20 6d 61 69 6e 20 6d 65 6d 6f  ted in main memo
0ca0: 72 79 2e 20 41 73 73 75 6d 69 6e 67 20 74 68 65  ry. Assuming the
0cb0: 20 61 6d 6f 75 6e 74 20 6f 66 20 6d 65 6d 6f 72   amount of memor
0cc0: 79 20 75 73 65 64 20 6e 65 76 65 72 20 65 78 63  y used never exc
0cd0: 65 65 64 73 0a 2a 2a 20 61 20 74 68 72 65 73 68  eeds.** a thresh
0ce0: 6f 6c 64 2c 20 77 68 65 6e 20 52 65 77 69 6e 64  old, when Rewind
0cf0: 28 29 20 69 73 20 63 61 6c 6c 65 64 20 74 68 65  () is called the
0d00: 20 73 65 74 20 6f 66 20 72 65 63 6f 72 64 73 20   set of records 
0d10: 69 73 20 73 6f 72 74 65 64 20 75 73 69 6e 67 0a  is sorted using.
0d20: 2a 2a 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20  ** an in-memory 
0d30: 6d 65 72 67 65 20 73 6f 72 74 2e 20 49 6e 20 74  merge sort. In t
0d40: 68 69 73 20 63 61 73 65 2c 20 6e 6f 20 74 65 6d  his case, no tem
0d50: 70 6f 72 61 72 79 20 66 69 6c 65 73 20 61 72 65  porary files are
0d60: 20 72 65 71 75 69 72 65 64 0a 2a 2a 20 61 6e 64   required.** and
0d70: 20 73 75 62 73 65 71 75 65 6e 74 20 63 61 6c 6c   subsequent call
0d80: 73 20 74 6f 20 52 6f 77 6b 65 79 28 29 2c 20 4e  s to Rowkey(), N
0d90: 65 78 74 28 29 20 61 6e 64 20 43 6f 6d 70 61 72  ext() and Compar
0da0: 65 28 29 20 72 65 61 64 20 72 65 63 6f 72 64 73  e() read records
0db0: 20 0a 2a 2a 20 64 69 72 65 63 74 6c 79 20 66 72   .** directly fr
0dc0: 6f 6d 20 6d 61 69 6e 20 6d 65 6d 6f 72 79 2e 0a  om main memory..
0dd0: 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 61 6d 6f  **.** If the amo
0de0: 75 6e 74 20 6f 66 20 73 70 61 63 65 20 75 73 65  unt of space use
0df0: 64 20 74 6f 20 73 74 6f 72 65 20 72 65 63 6f 72  d to store recor
0e00: 64 73 20 69 6e 20 6d 61 69 6e 20 6d 65 6d 6f 72  ds in main memor
0e10: 79 20 65 78 63 65 65 64 73 20 74 68 65 0a 2a 2a  y exceeds the.**
0e20: 20 74 68 72 65 73 68 6f 6c 64 2c 20 74 68 65 6e   threshold, then
0e30: 20 74 68 65 20 73 65 74 20 6f 66 20 72 65 63 6f   the set of reco
0e40: 72 64 73 20 63 75 72 72 65 6e 74 6c 79 20 69 6e  rds currently in
0e50: 20 6d 65 6d 6f 72 79 20 61 72 65 20 73 6f 72 74   memory are sort
0e60: 65 64 20 61 6e 64 0a 2a 2a 20 77 72 69 74 74 65  ed and.** writte
0e70: 6e 20 74 6f 20 61 20 74 65 6d 70 6f 72 61 72 79  n to a temporary
0e80: 20 66 69 6c 65 20 69 6e 20 22 50 61 63 6b 65 64   file in "Packed
0e90: 20 4d 65 6d 6f 72 79 20 41 72 72 61 79 22 20 28   Memory Array" (
0ea0: 50 4d 41 29 20 66 6f 72 6d 61 74 2e 0a 2a 2a 20  PMA) format..** 
0eb0: 41 20 50 4d 41 20 63 72 65 61 74 65 64 20 61 74  A PMA created at
0ec0: 20 74 68 69 73 20 70 6f 69 6e 74 20 69 73 20 6b   this point is k
0ed0: 6e 6f 77 6e 20 61 73 20 61 20 22 6c 65 76 65 6c  nown as a "level
0ee0: 2d 30 20 50 4d 41 22 2e 20 48 69 67 68 65 72 20  -0 PMA". Higher 
0ef0: 6c 65 76 65 6c 73 0a 2a 2a 20 6f 66 20 50 4d 41  levels.** of PMA
0f00: 73 20 6d 61 79 20 62 65 20 63 72 65 61 74 65 64  s may be created
0f10: 20 62 79 20 6d 65 72 67 69 6e 67 20 65 78 69 73   by merging exis
0f20: 74 69 6e 67 20 50 4d 41 73 20 74 6f 67 65 74 68  ting PMAs togeth
0f30: 65 72 20 2d 20 66 6f 72 20 65 78 61 6d 70 6c 65  er - for example
0f40: 0a 2a 2a 20 6d 65 72 67 69 6e 67 20 74 77 6f 20  .** merging two 
0f50: 6f 72 20 6d 6f 72 65 20 6c 65 76 65 6c 2d 30 20  or more level-0 
0f60: 50 4d 41 73 20 74 6f 67 65 74 68 65 72 20 63 72  PMAs together cr
0f70: 65 61 74 65 73 20 61 20 6c 65 76 65 6c 2d 31 20  eates a level-1 
0f80: 50 4d 41 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 74  PMA..**.** The t
0f90: 68 72 65 73 68 6f 6c 64 20 66 6f 72 20 74 68 65  hreshold for the
0fa0: 20 61 6d 6f 75 6e 74 20 6f 66 20 6d 61 69 6e 20   amount of main 
0fb0: 6d 65 6d 6f 72 79 20 74 6f 20 75 73 65 20 62 65  memory to use be
0fc0: 66 6f 72 65 20 66 6c 75 73 68 69 6e 67 20 0a 2a  fore flushing .*
0fd0: 2a 20 72 65 63 6f 72 64 73 20 74 6f 20 61 20 50  * records to a P
0fe0: 4d 41 20 69 73 20 72 6f 75 67 68 6c 79 20 74 68  MA is roughly th
0ff0: 65 20 73 61 6d 65 20 61 73 20 74 68 65 20 6c 69  e same as the li
1000: 6d 69 74 20 63 6f 6e 66 69 67 75 72 65 64 20 66  mit configured f
1010: 6f 72 20 74 68 65 0a 2a 2a 20 70 61 67 65 2d 63  or the.** page-c
1020: 61 63 68 65 20 6f 66 20 74 68 65 20 6d 61 69 6e  ache of the main
1030: 20 64 61 74 61 62 61 73 65 2e 20 53 70 65 63 69   database. Speci
1040: 66 69 63 61 6c 6c 79 2c 20 74 68 65 20 74 68 72  fically, the thr
1050: 65 73 68 6f 6c 64 20 69 73 20 73 65 74 20 74 6f  eshold is set to
1060: 20 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 20 72   .** the value r
1070: 65 74 75 72 6e 65 64 20 6d 75 6c 74 69 70 6c 69  eturned multipli
1080: 65 64 20 62 79 20 22 50 52 41 47 4d 41 20 6d 61  ed by "PRAGMA ma
1090: 69 6e 2e 70 61 67 65 5f 73 69 7a 65 22 20 6d 75  in.page_size" mu
10a0: 6c 74 69 70 6c 65 64 20 62 79 20 0a 2a 2a 20 74  ltipled by .** t
10b0: 68 61 74 20 72 65 74 75 72 6e 65 64 20 62 79 20  hat returned by 
10c0: 22 50 52 41 47 4d 41 20 6d 61 69 6e 2e 63 61 63  "PRAGMA main.cac
10d0: 68 65 5f 73 69 7a 65 22 2c 20 69 6e 20 62 79 74  he_size", in byt
10e0: 65 73 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  es..**.** If the
10f0: 20 73 6f 72 74 65 72 20 69 73 20 72 75 6e 6e 69   sorter is runni
1100: 6e 67 20 69 6e 20 73 69 6e 67 6c 65 2d 74 68 72  ng in single-thr
1110: 65 61 64 65 64 20 6d 6f 64 65 2c 20 74 68 65 6e  eaded mode, then
1120: 20 61 6c 6c 20 50 4d 41 73 20 67 65 6e 65 72 61   all PMAs genera
1130: 74 65 64 0a 2a 2a 20 61 72 65 20 61 70 70 65 6e  ted.** are appen
1140: 64 65 64 20 74 6f 20 61 20 73 69 6e 67 6c 65 20  ded to a single 
1150: 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 2e 20  temporary file. 
1160: 4f 72 2c 20 69 66 20 74 68 65 20 73 6f 72 74 65  Or, if the sorte
1170: 72 20 69 73 20 72 75 6e 6e 69 6e 67 20 69 6e 0a  r is running in.
1180: 2a 2a 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65  ** multi-threade
1190: 64 20 6d 6f 64 65 20 74 68 65 6e 20 75 70 20 74  d mode then up t
11a0: 6f 20 28 4e 2b 31 29 20 74 65 6d 70 6f 72 61 72  o (N+1) temporar
11b0: 79 20 66 69 6c 65 73 20 6d 61 79 20 62 65 20 6f  y files may be o
11c0: 70 65 6e 65 64 2c 20 77 68 65 72 65 0a 2a 2a 20  pened, where.** 
11d0: 4e 20 69 73 20 74 68 65 20 63 6f 6e 66 69 67 75  N is the configu
11e0: 72 65 64 20 6e 75 6d 62 65 72 20 6f 66 20 77 6f  red number of wo
11f0: 72 6b 65 72 20 74 68 72 65 61 64 73 2e 20 49 6e  rker threads. In
1200: 20 74 68 69 73 20 63 61 73 65 2c 20 69 6e 73 74   this case, inst
1210: 65 61 64 20 6f 66 0a 2a 2a 20 73 6f 72 74 69 6e  ead of.** sortin
1220: 67 20 74 68 65 20 72 65 63 6f 72 64 73 20 61 6e  g the records an
1230: 64 20 77 72 69 74 69 6e 67 20 74 68 65 20 50 4d  d writing the PM
1240: 41 20 74 6f 20 61 20 74 65 6d 70 6f 72 61 72 79  A to a temporary
1250: 20 66 69 6c 65 20 69 74 73 65 6c 66 2c 20 74 68   file itself, th
1260: 65 0a 2a 2a 20 63 61 6c 6c 69 6e 67 20 74 68 72  e.** calling thr
1270: 65 61 64 20 75 73 75 61 6c 6c 79 20 6c 61 75 6e  ead usually laun
1280: 63 68 65 73 20 61 20 77 6f 72 6b 65 72 20 74 68  ches a worker th
1290: 72 65 61 64 20 74 6f 20 64 6f 20 73 6f 2e 20 45  read to do so. E
12a0: 78 63 65 70 74 2c 20 69 66 0a 2a 2a 20 74 68 65  xcept, if.** the
12b0: 72 65 20 61 72 65 20 61 6c 72 65 61 64 79 20 4e  re are already N
12c0: 20 77 6f 72 6b 65 72 20 74 68 72 65 61 64 73 20   worker threads 
12d0: 72 75 6e 6e 69 6e 67 2c 20 74 68 65 20 6d 61 69  running, the mai
12e0: 6e 20 74 68 72 65 61 64 20 64 6f 65 73 20 74 68  n thread does th
12f0: 65 20 77 6f 72 6b 0a 2a 2a 20 69 74 73 65 6c 66  e work.** itself
1300: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 6f 72 74  ..**.** The sort
1310: 65 72 20 69 73 20 72 75 6e 6e 69 6e 67 20 69 6e  er is running in
1320: 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20   multi-threaded 
1330: 6d 6f 64 65 20 69 66 20 28 61 29 20 74 68 65 20  mode if (a) the 
1340: 6c 69 62 72 61 72 79 20 77 61 73 20 62 75 69 6c  library was buil
1350: 74 0a 2a 2a 20 77 69 74 68 20 70 72 65 2d 70 72  t.** with pre-pr
1360: 6f 63 65 73 73 6f 72 20 73 79 6d 62 6f 6c 20 53  ocessor symbol S
1370: 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52  QLITE_MAX_WORKER
1380: 5f 54 48 52 45 41 44 53 20 73 65 74 20 74 6f 20  _THREADS set to 
1390: 61 20 76 61 6c 75 65 20 67 72 65 61 74 65 72 0a  a value greater.
13a0: 2a 2a 20 74 68 61 6e 20 7a 65 72 6f 2c 20 61 6e  ** than zero, an
13b0: 64 20 28 62 29 20 77 6f 72 6b 65 72 20 74 68 72  d (b) worker thr
13c0: 65 61 64 73 20 68 61 76 65 20 62 65 65 6e 20 65  eads have been e
13d0: 6e 61 62 6c 65 64 20 61 74 20 72 75 6e 74 69 6d  nabled at runtim
13e0: 65 20 62 79 20 63 61 6c 6c 69 6e 67 0a 2a 2a 20  e by calling.** 
13f0: 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53  sqlite3_config(S
1400: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 57 4f 52  QLITE_CONFIG_WOR
1410: 4b 45 52 5f 54 48 52 45 41 44 53 2c 20 2e 2e 2e  KER_THREADS, ...
1420: 29 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 52 65  )..**.** When Re
1430: 77 69 6e 64 28 29 20 69 73 20 63 61 6c 6c 65 64  wind() is called
1440: 2c 20 61 6e 79 20 64 61 74 61 20 72 65 6d 61 69  , any data remai
1450: 6e 69 6e 67 20 69 6e 20 6d 65 6d 6f 72 79 20 69  ning in memory i
1460: 73 20 66 6c 75 73 68 65 64 20 74 6f 20 61 20 0a  s flushed to a .
1470: 2a 2a 20 66 69 6e 61 6c 20 50 4d 41 2e 20 53 6f  ** final PMA. So
1480: 20 61 74 20 74 68 69 73 20 70 6f 69 6e 74 20 74   at this point t
1490: 68 65 20 64 61 74 61 20 69 73 20 73 74 6f 72 65  he data is store
14a0: 64 20 69 6e 20 73 6f 6d 65 20 6e 75 6d 62 65 72  d in some number
14b0: 20 6f 66 20 73 6f 72 74 65 64 0a 2a 2a 20 50 4d   of sorted.** PM
14c0: 41 73 20 77 69 74 68 69 6e 20 74 65 6d 70 6f 72  As within tempor
14d0: 61 72 79 20 66 69 6c 65 73 20 6f 6e 20 64 69 73  ary files on dis
14e0: 6b 2e 20 57 69 74 68 69 6e 20 61 20 73 69 6e 67  k. Within a sing
14f0: 6c 65 20 66 69 6c 65 20 73 6f 72 74 65 72 20 69  le file sorter i
1500: 73 20 0a 2a 2a 20 72 75 6e 6e 69 6e 67 20 69 6e  s .** running in
1510: 20 73 69 6e 67 6c 65 20 74 68 72 65 61 64 65 64   single threaded
1520: 20 6d 6f 64 65 2c 20 6f 72 20 64 69 73 74 72 69   mode, or distri
1530: 62 75 74 65 64 20 62 65 74 77 65 65 6e 20 6f 6e  buted between on
1540: 65 20 6f 72 20 6d 6f 72 65 20 66 69 6c 65 73 0a  e or more files.
1550: 2a 2a 20 66 6f 72 20 6d 75 6c 74 69 2d 74 68 72  ** for multi-thr
1560: 65 61 64 65 64 20 73 6f 72 74 65 72 73 2e 0a 2a  eaded sorters..*
1570: 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65 20 61 72  *.** If there ar
1580: 65 20 66 65 77 65 72 20 74 68 61 6e 20 53 4f 52  e fewer than SOR
1590: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
15a0: 55 4e 54 20 50 4d 41 73 20 69 6e 20 74 6f 74 61  UNT PMAs in tota
15b0: 6c 20 61 6e 64 20 74 68 65 0a 2a 2a 20 73 6f 72  l and the.** sor
15c0: 74 65 72 20 69 73 20 72 75 6e 6e 69 6e 67 20 69  ter is running i
15d0: 6e 20 73 69 6e 67 6c 65 2d 74 68 72 65 61 64 65  n single-threade
15e0: 64 20 6d 6f 64 65 2c 20 74 68 65 6e 20 74 68 65  d mode, then the
15f0: 73 65 20 50 4d 41 73 20 61 72 65 20 6d 65 72 67  se PMAs are merg
1600: 65 64 0a 2a 2a 20 69 6e 63 72 65 6d 65 6e 74 61  ed.** incrementa
1610: 6c 6c 79 20 61 73 20 6b 65 79 73 20 61 72 65 20  lly as keys are 
1620: 72 65 74 72 65 69 76 65 64 20 66 72 6f 6d 20 74  retreived from t
1630: 68 65 20 73 6f 72 74 65 72 20 62 79 20 74 68 65  he sorter by the
1640: 20 56 44 42 45 2e 20 53 65 65 0a 2a 2a 20 63 6f   VDBE. See.** co
1650: 6d 6d 65 6e 74 73 20 61 62 6f 76 65 20 6f 62 6a  mments above obj
1660: 65 63 74 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  ect MergeEngine 
1670: 62 65 6c 6f 77 20 66 6f 72 20 64 65 74 61 69 6c  below for detail
1680: 73 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 69 66 20  s..**.** Or, if 
1690: 72 75 6e 6e 69 6e 67 20 69 6e 20 6d 75 6c 74 69  running in multi
16a0: 2d 74 68 72 65 61 64 65 64 20 6d 6f 64 65 2c 20  -threaded mode, 
16b0: 74 68 65 6e 20 61 20 62 61 63 6b 67 72 6f 75 6e  then a backgroun
16c0: 64 20 74 68 72 65 61 64 20 69 73 0a 2a 2a 20 6c  d thread is.** l
16d0: 61 75 6e 63 68 65 64 20 74 6f 20 6d 65 72 67 65  aunched to merge
16e0: 20 74 68 65 20 65 78 69 73 74 69 6e 67 20 50 4d   the existing PM
16f0: 41 73 2e 20 4f 6e 63 65 20 74 68 65 20 62 61 63  As. Once the bac
1700: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 68  kground thread h
1710: 61 73 0a 2a 2a 20 6d 65 72 67 65 64 20 54 20 62  as.** merged T b
1720: 79 74 65 73 20 6f 66 20 64 61 74 61 20 69 6e 74  ytes of data int
1730: 6f 20 61 20 73 69 6e 67 6c 65 20 73 6f 72 74 65  o a single sorte
1740: 64 20 50 4d 41 2c 20 74 68 65 20 6d 61 69 6e 20  d PMA, the main 
1750: 74 68 72 65 61 64 20 0a 2a 2a 20 62 65 67 69 6e  thread .** begin
1760: 73 20 72 65 61 64 69 6e 67 20 6b 65 79 73 20 66  s reading keys f
1770: 72 6f 6d 20 74 68 61 74 20 50 4d 41 20 77 68 69  rom that PMA whi
1780: 6c 65 20 74 68 65 20 62 61 63 6b 67 72 6f 75 6e  le the backgroun
1790: 64 20 74 68 72 65 61 64 20 70 72 6f 63 65 65 64  d thread proceed
17a0: 73 0a 2a 2a 20 77 69 74 68 20 6d 65 72 67 69 6e  s.** with mergin
17b0: 67 20 74 68 65 20 6e 65 78 74 20 54 20 62 79 74  g the next T byt
17c0: 65 73 20 6f 66 20 64 61 74 61 2e 20 41 6e 64 20  es of data. And 
17d0: 73 6f 20 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 50 61 72  so on..**.** Par
17e0: 61 6d 65 74 65 72 20 54 20 69 73 20 73 65 74 20  ameter T is set 
17f0: 74 6f 20 68 61 6c 66 20 74 68 65 20 76 61 6c 75  to half the valu
1800: 65 20 6f 66 20 74 68 65 20 6d 65 6d 6f 72 79 20  e of the memory 
1810: 74 68 72 65 73 68 6f 6c 64 20 75 73 65 64 20 0a  threshold used .
1820: 2a 2a 20 62 79 20 57 72 69 74 65 28 29 20 61 62  ** by Write() ab
1830: 6f 76 65 20 74 6f 20 64 65 74 65 72 6d 69 6e 65  ove to determine
1840: 20 77 68 65 6e 20 74 6f 20 63 72 65 61 74 65 20   when to create 
1850: 61 20 6e 65 77 20 50 4d 41 2e 0a 2a 2a 0a 2a 2a  a new PMA..**.**
1860: 20 49 66 20 74 68 65 72 65 20 61 72 65 20 6d 6f   If there are mo
1870: 72 65 20 74 68 61 6e 20 53 4f 52 54 45 52 5f 4d  re than SORTER_M
1880: 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20 50  AX_MERGE_COUNT P
1890: 4d 41 73 20 69 6e 20 74 6f 74 61 6c 20 77 68 65  MAs in total whe
18a0: 6e 20 0a 2a 2a 20 52 65 77 69 6e 64 28 29 20 69  n .** Rewind() i
18b0: 73 20 63 61 6c 6c 65 64 2c 20 74 68 65 6e 20 61  s called, then a
18c0: 20 68 69 65 72 61 72 63 68 79 20 6f 66 20 69 6e   hierarchy of in
18d0: 63 72 65 6d 65 6e 74 61 6c 2d 6d 65 72 67 65 73  cremental-merges
18e0: 20 69 73 20 75 73 65 64 2e 20 0a 2a 2a 20 46 69   is used. .** Fi
18f0: 72 73 74 2c 20 54 20 62 79 74 65 73 20 6f 66 20  rst, T bytes of 
1900: 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 66 69  data from the fi
1910: 72 73 74 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  rst SORTER_MAX_M
1920: 45 52 47 45 5f 43 4f 55 4e 54 20 50 4d 41 73 20  ERGE_COUNT PMAs 
1930: 6f 6e 20 0a 2a 2a 20 64 69 73 6b 20 61 72 65 20  on .** disk are 
1940: 6d 65 72 67 65 64 20 74 6f 67 65 74 68 65 72 2e  merged together.
1950: 20 54 68 65 6e 20 54 20 62 79 74 65 73 20 6f 66   Then T bytes of
1960: 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 73   data from the s
1970: 65 63 6f 6e 64 20 73 65 74 2c 20 61 6e 64 0a 2a  econd set, and.*
1980: 2a 20 73 6f 20 6f 6e 2c 20 73 75 63 68 20 74 68  * so on, such th
1990: 61 74 20 6e 6f 20 6f 70 65 72 61 74 69 6f 6e 20  at no operation 
19a0: 65 76 65 72 20 6d 65 72 67 65 73 20 6d 6f 72 65  ever merges more
19b0: 20 74 68 61 6e 20 53 4f 52 54 45 52 5f 4d 41 58   than SORTER_MAX
19c0: 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 0a 2a 2a 20  _MERGE_COUNT.** 
19d0: 50 4d 41 73 20 61 74 20 61 20 74 69 6d 65 2e 20  PMAs at a time. 
19e0: 54 68 69 73 20 64 6f 6e 65 20 69 73 20 74 6f 20  This done is to 
19f0: 69 6d 70 72 6f 76 65 20 6c 6f 63 61 6c 69 74 79  improve locality
1a00: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 72 75 6e 6e 69  ..**.** If runni
1a10: 6e 67 20 69 6e 20 6d 75 6c 74 69 2d 74 68 72 65  ng in multi-thre
1a20: 61 64 65 64 20 6d 6f 64 65 20 61 6e 64 20 74 68  aded mode and th
1a30: 65 72 65 20 61 72 65 20 6d 6f 72 65 20 74 68 61  ere are more tha
1a40: 6e 0a 2a 2a 20 53 4f 52 54 45 52 5f 4d 41 58 5f  n.** SORTER_MAX_
1a50: 4d 45 52 47 45 5f 43 4f 55 4e 54 20 50 4d 41 73  MERGE_COUNT PMAs
1a60: 20 6f 6e 20 64 69 73 6b 20 77 68 65 6e 20 52 65   on disk when Re
1a70: 77 69 6e 64 28 29 20 69 73 20 63 61 6c 6c 65 64  wind() is called
1a80: 2c 20 74 68 65 6e 20 6d 6f 72 65 0a 2a 2a 20 74  , then more.** t
1a90: 68 61 6e 20 6f 6e 65 20 62 61 63 6b 67 72 6f 75  han one backgrou
1aa0: 6e 64 20 74 68 72 65 61 64 20 6d 61 79 20 62 65  nd thread may be
1ab0: 20 63 72 65 61 74 65 64 2e 20 53 70 65 63 69 66   created. Specif
1ac0: 69 63 61 6c 6c 79 2c 20 74 68 65 72 65 20 6d 61  ically, there ma
1ad0: 79 20 62 65 0a 2a 2a 20 6f 6e 65 20 62 61 63 6b  y be.** one back
1ae0: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 66 6f  ground thread fo
1af0: 72 20 65 61 63 68 20 74 65 6d 70 6f 72 61 72 79  r each temporary
1b00: 20 66 69 6c 65 20 6f 6e 20 64 69 73 6b 2c 20 61   file on disk, a
1b10: 6e 64 20 6f 6e 65 20 62 61 63 6b 67 72 6f 75 6e  nd one backgroun
1b20: 64 0a 2a 2a 20 74 68 72 65 61 64 20 74 6f 20 6d  d.** thread to m
1b30: 65 72 67 65 20 74 68 65 20 6f 75 74 70 75 74 20  erge the output 
1b40: 6f 66 20 65 61 63 68 20 6f 66 20 74 68 65 20 6f  of each of the o
1b50: 74 68 65 72 73 20 74 6f 20 61 20 73 69 6e 67 6c  thers to a singl
1b60: 65 20 50 4d 41 20 66 6f 72 0a 2a 2a 20 74 68 65  e PMA for.** the
1b70: 20 6d 61 69 6e 20 74 68 72 65 61 64 20 74 6f 20   main thread to 
1b80: 72 65 61 64 20 66 72 6f 6d 2e 0a 2a 2f 0a 23 69  read from..*/.#i
1b90: 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65 49 6e  nclude "sqliteIn
1ba0: 74 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 76  t.h".#include "v
1bb0: 64 62 65 49 6e 74 2e 68 22 0a 0a 2f 2a 20 0a 2a  dbeInt.h"../* .*
1bc0: 2a 20 49 66 20 53 51 4c 49 54 45 5f 44 45 42 55  * If SQLITE_DEBU
1bd0: 47 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44 53  G_SORTER_THREADS
1be0: 20 69 73 20 64 65 66 69 6e 65 64 2c 20 74 68 69   is defined, thi
1bf0: 73 20 6d 6f 64 75 6c 65 20 6f 75 74 70 75 74 73  s module outputs
1c00: 20 76 61 72 69 6f 75 73 0a 2a 2a 20 6d 65 73 73   various.** mess
1c10: 61 67 65 73 20 74 6f 20 73 74 64 65 72 72 20 74  ages to stderr t
1c20: 68 61 74 20 6d 61 79 20 62 65 20 68 65 6c 70 66  hat may be helpf
1c30: 75 6c 20 69 6e 20 75 6e 64 65 72 73 74 61 6e 64  ul in understand
1c40: 69 6e 67 20 74 68 65 20 70 65 72 66 6f 72 6d 61  ing the performa
1c50: 6e 63 65 0a 2a 2a 20 63 68 61 72 61 63 74 65 72  nce.** character
1c60: 69 73 74 69 63 73 20 6f 66 20 74 68 65 20 73 6f  istics of the so
1c70: 72 74 65 72 20 69 6e 20 6d 75 6c 74 69 2d 74 68  rter in multi-th
1c80: 72 65 61 64 65 64 20 6d 6f 64 65 2e 0a 2a 2f 0a  readed mode..*/.
1c90: 23 69 66 20 30 0a 23 20 64 65 66 69 6e 65 20 53  #if 0.# define S
1ca0: 51 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f 52 54  QLITE_DEBUG_SORT
1cb0: 45 52 5f 54 48 52 45 41 44 53 20 31 0a 23 65 6e  ER_THREADS 1.#en
1cc0: 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 76 61  dif../*.** Priva
1cd0: 74 65 20 6f 62 6a 65 63 74 73 20 75 73 65 64 20  te objects used 
1ce0: 62 79 20 74 68 65 20 73 6f 72 74 65 72 0a 2a 2f  by the sorter.*/
1cf0: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
1d00: 4d 65 72 67 65 45 6e 67 69 6e 65 20 4d 65 72 67  MergeEngine Merg
1d10: 65 45 6e 67 69 6e 65 3b 20 20 20 20 20 2f 2a 20  eEngine;     /* 
1d20: 4d 65 72 67 65 20 50 4d 41 73 20 74 6f 67 65 74  Merge PMAs toget
1d30: 68 65 72 20 2a 2f 0a 74 79 70 65 64 65 66 20 73  her */.typedef s
1d40: 74 72 75 63 74 20 50 6d 61 52 65 61 64 65 72 20  truct PmaReader 
1d50: 50 6d 61 52 65 61 64 65 72 3b 20 20 20 20 20 20  PmaReader;      
1d60: 20 20 20 2f 2a 20 49 6e 63 72 65 6d 65 6e 74 61     /* Incrementa
1d70: 6c 6c 79 20 72 65 61 64 20 6f 6e 65 20 50 4d 41  lly read one PMA
1d80: 20 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75   */.typedef stru
1d90: 63 74 20 50 6d 61 57 72 69 74 65 72 20 50 6d 61  ct PmaWriter Pma
1da0: 57 72 69 74 65 72 3b 20 20 20 20 20 20 20 20 20  Writer;         
1db0: 2f 2a 20 49 6e 63 72 65 6d 65 6e 74 61 6c 6c 79  /* Incrementally
1dc0: 20 77 72 69 74 65 20 6f 6e 65 20 50 4d 41 20 2a   write one PMA *
1dd0: 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  /.typedef struct
1de0: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 53 6f   SorterRecord So
1df0: 72 74 65 72 52 65 63 6f 72 64 3b 20 20 20 2f 2a  rterRecord;   /*
1e00: 20 41 20 72 65 63 6f 72 64 20 62 65 69 6e 67 20   A record being 
1e10: 73 6f 72 74 65 64 20 2a 2f 0a 74 79 70 65 64 65  sorted */.typede
1e20: 66 20 73 74 72 75 63 74 20 53 6f 72 74 53 75 62  f struct SortSub
1e30: 74 61 73 6b 20 53 6f 72 74 53 75 62 74 61 73 6b  task SortSubtask
1e40: 3b 20 20 20 20 20 2f 2a 20 41 20 73 75 62 2d 74  ;     /* A sub-t
1e50: 61 73 6b 20 69 6e 20 74 68 65 20 73 6f 72 74 20  ask in the sort 
1e60: 70 72 6f 63 65 73 73 20 2a 2f 0a 74 79 70 65 64  process */.typed
1e70: 65 66 20 73 74 72 75 63 74 20 53 6f 72 74 65 72  ef struct Sorter
1e80: 46 69 6c 65 20 53 6f 72 74 65 72 46 69 6c 65 3b  File SorterFile;
1e90: 20 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72         /* Tempor
1ea0: 61 72 79 20 66 69 6c 65 20 6f 62 6a 65 63 74 20  ary file object 
1eb0: 77 72 61 70 70 65 72 20 2a 2f 0a 74 79 70 65 64  wrapper */.typed
1ec0: 65 66 20 73 74 72 75 63 74 20 53 6f 72 74 65 72  ef struct Sorter
1ed0: 4c 69 73 74 20 53 6f 72 74 65 72 4c 69 73 74 3b  List SorterList;
1ee0: 20 20 20 20 20 20 20 2f 2a 20 49 6e 2d 6d 65 6d         /* In-mem
1ef0: 6f 72 79 20 6c 69 73 74 20 6f 66 20 72 65 63 6f  ory list of reco
1f00: 72 64 73 20 2a 2f 0a 74 79 70 65 64 65 66 20 73  rds */.typedef s
1f10: 74 72 75 63 74 20 49 6e 63 72 4d 65 72 67 65 72  truct IncrMerger
1f20: 20 49 6e 63 72 4d 65 72 67 65 72 3b 0a 0a 2f 2a   IncrMerger;../*
1f30: 0a 2a 2a 20 41 20 63 6f 6e 74 61 69 6e 65 72 20  .** A container 
1f40: 66 6f 72 20 61 20 74 65 6d 70 20 66 69 6c 65 20  for a temp file 
1f50: 68 61 6e 64 6c 65 20 61 6e 64 20 74 68 65 20 63  handle and the c
1f60: 75 72 72 65 6e 74 20 61 6d 6f 75 6e 74 20 6f 66  urrent amount of
1f70: 20 64 61 74 61 20 0a 2a 2a 20 73 74 6f 72 65 64   data .** stored
1f80: 20 69 6e 20 74 68 65 20 66 69 6c 65 2e 0a 2a 2f   in the file..*/
1f90: 0a 73 74 72 75 63 74 20 53 6f 72 74 65 72 46 69  .struct SorterFi
1fa0: 6c 65 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66  le {.  sqlite3_f
1fb0: 69 6c 65 20 2a 70 46 64 3b 20 20 20 20 20 20 20  ile *pFd;       
1fc0: 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 68         /* File h
1fd0: 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 36 34 20 69  andle */.  i64 i
1fe0: 45 6f 66 3b 20 20 20 20 20 20 20 20 20 20 20 20  Eof;            
1ff0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79             /* By
2000: 74 65 73 20 6f 66 20 64 61 74 61 20 73 74 6f 72  tes of data stor
2010: 65 64 20 69 6e 20 70 46 64 20 2a 2f 0a 7d 3b 0a  ed in pFd */.};.
2020: 0a 2f 2a 0a 2a 2a 20 49 6e 20 6d 65 6d 6f 72 79  ./*.** In memory
2030: 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20   linked list of 
2040: 72 65 63 6f 72 64 73 2e 0a 2a 2f 0a 73 74 72 75  records..*/.stru
2050: 63 74 20 53 6f 72 74 65 72 4c 69 73 74 20 7b 0a  ct SorterList {.
2060: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
2070: 70 4c 69 73 74 3b 20 20 20 20 20 20 20 20 20 20  pList;          
2080: 20 20 2f 2a 20 4c 69 6e 6b 65 64 20 6c 69 73 74    /* Linked list
2090: 20 6f 66 20 72 65 63 6f 72 64 73 20 2a 2f 0a 20   of records */. 
20a0: 20 75 38 20 2a 61 4d 65 6d 6f 72 79 3b 20 20 20   u8 *aMemory;   
20b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20c0: 20 2f 2a 20 49 66 20 6e 6f 6e 2d 4e 55 4c 4c 2c   /* If non-NULL,
20d0: 20 62 6c 6f 62 20 6f 66 20 6d 65 6d 6f 72 79 20   blob of memory 
20e0: 66 6f 72 20 70 4c 69 73 74 20 2a 2f 0a 20 20 69  for pList */.  i
20f0: 6e 74 20 73 7a 50 4d 41 3b 20 20 20 20 20 20 20  nt szPMA;       
2100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2110: 2a 20 53 69 7a 65 20 6f 66 20 70 4c 69 73 74 20  * Size of pList 
2120: 61 73 20 50 4d 41 20 69 6e 20 62 79 74 65 73 20  as PMA in bytes 
2130: 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65  */.};../*.** The
2140: 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 6f 62 6a   MergeEngine obj
2150: 65 63 74 20 69 73 20 75 73 65 64 20 74 6f 20 63  ect is used to c
2160: 6f 6d 62 69 6e 65 20 74 77 6f 20 6f 72 20 6d 6f  ombine two or mo
2170: 72 65 20 73 6d 61 6c 6c 65 72 20 50 4d 41 73 20  re smaller PMAs 
2180: 69 6e 74 6f 0a 2a 2a 20 6f 6e 65 20 62 69 67 20  into.** one big 
2190: 50 4d 41 20 75 73 69 6e 67 20 61 20 6d 65 72 67  PMA using a merg
21a0: 65 20 6f 70 65 72 61 74 69 6f 6e 2e 20 20 53 65  e operation.  Se
21b0: 70 61 72 61 74 65 20 50 4d 41 73 20 61 6c 6c 20  parate PMAs all 
21c0: 6e 65 65 64 20 74 6f 20 62 65 0a 2a 2a 20 63 6f  need to be.** co
21d0: 6d 62 69 6e 65 64 20 69 6e 74 6f 20 6f 6e 65 20  mbined into one 
21e0: 62 69 67 20 50 4d 41 20 69 6e 20 6f 72 64 65 72  big PMA in order
21f0: 20 74 6f 20 62 65 20 61 62 6c 65 20 74 6f 20 73   to be able to s
2200: 74 65 70 20 74 68 72 6f 75 67 68 20 74 68 65 20  tep through the 
2210: 73 6f 72 74 65 64 0a 2a 2a 20 72 65 63 6f 72 64  sorted.** record
2220: 73 20 69 6e 20 6f 72 64 65 72 2e 0a 2a 2a 0a 2a  s in order..**.*
2230: 2a 20 54 68 65 20 61 49 74 65 72 5b 5d 20 61 72  * The aIter[] ar
2240: 72 61 79 20 63 6f 6e 74 61 69 6e 73 20 61 20 50  ray contains a P
2250: 6d 61 52 65 61 64 65 72 20 6f 62 6a 65 63 74 20  maReader object 
2260: 66 6f 72 20 65 61 63 68 20 6f 66 20 74 68 65 20  for each of the 
2270: 50 4d 41 73 20 62 65 69 6e 67 0a 2a 2a 20 6d 65  PMAs being.** me
2280: 72 67 65 64 2e 20 20 41 6e 20 61 49 74 65 72 5b  rged.  An aIter[
2290: 5d 20 6f 62 6a 65 63 74 20 65 69 74 68 65 72 20  ] object either 
22a0: 70 6f 69 6e 74 73 20 74 6f 20 61 20 76 61 6c 69  points to a vali
22b0: 64 20 6b 65 79 20 6f 72 20 65 6c 73 65 20 69 73  d key or else is
22c0: 20 61 74 20 45 4f 46 2e 0a 2a 2a 20 46 6f 72 20   at EOF..** For 
22d0: 74 68 65 20 70 75 72 70 6f 73 65 73 20 6f 66 20  the purposes of 
22e0: 74 68 65 20 70 61 72 61 67 72 61 70 68 73 20 62  the paragraphs b
22f0: 65 6c 6f 77 2c 20 77 65 20 61 73 73 75 6d 65 20  elow, we assume 
2300: 74 68 61 74 20 74 68 65 20 61 72 72 61 79 20 69  that the array i
2310: 73 0a 2a 2a 20 61 63 74 75 61 6c 6c 79 20 4e 20  s.** actually N 
2320: 65 6c 65 6d 65 6e 74 73 20 69 6e 20 73 69 7a 65  elements in size
2330: 2c 20 77 68 65 72 65 20 4e 20 69 73 20 74 68 65  , where N is the
2340: 20 73 6d 61 6c 6c 65 73 74 20 70 6f 77 65 72 20   smallest power 
2350: 6f 66 20 32 20 67 72 65 61 74 65 72 0a 2a 2a 20  of 2 greater.** 
2360: 74 6f 20 6f 72 20 65 71 75 61 6c 20 74 6f 20 74  to or equal to t
2370: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 50 4d 41  he number of PMA
2380: 73 20 62 65 69 6e 67 20 6d 65 72 67 65 64 2e 20  s being merged. 
2390: 54 68 65 20 65 78 74 72 61 20 61 49 74 65 72 5b  The extra aIter[
23a0: 5d 20 65 6c 65 6d 65 6e 74 73 0a 2a 2a 20 61 72  ] elements.** ar
23b0: 65 20 74 72 65 61 74 65 64 20 61 73 20 69 66 20  e treated as if 
23c0: 74 68 65 79 20 61 72 65 20 65 6d 70 74 79 20 28  they are empty (
23d0: 61 6c 77 61 79 73 20 61 74 20 45 4f 46 29 2e 0a  always at EOF)..
23e0: 2a 2a 0a 2a 2a 20 54 68 65 20 61 54 72 65 65 5b  **.** The aTree[
23f0: 5d 20 61 72 72 61 79 20 69 73 20 61 6c 73 6f 20  ] array is also 
2400: 4e 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 73 69  N elements in si
2410: 7a 65 2e 20 54 68 65 20 76 61 6c 75 65 20 6f 66  ze. The value of
2420: 20 4e 20 69 73 20 73 74 6f 72 65 64 20 69 6e 0a   N is stored in.
2430: 2a 2a 20 74 68 65 20 4d 65 72 67 65 45 6e 67 69  ** the MergeEngi
2440: 6e 65 2e 6e 54 72 65 65 20 76 61 72 69 61 62 6c  ne.nTree variabl
2450: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66 69 6e  e..**.** The fin
2460: 61 6c 20 28 4e 2f 32 29 20 65 6c 65 6d 65 6e 74  al (N/2) element
2470: 73 20 6f 66 20 61 54 72 65 65 5b 5d 20 63 6f 6e  s of aTree[] con
2480: 74 61 69 6e 20 74 68 65 20 72 65 73 75 6c 74 73  tain the results
2490: 20 6f 66 20 63 6f 6d 70 61 72 69 6e 67 0a 2a 2a   of comparing.**
24a0: 20 70 61 69 72 73 20 6f 66 20 50 4d 41 20 6b 65   pairs of PMA ke
24b0: 79 73 20 74 6f 67 65 74 68 65 72 2e 20 45 6c 65  ys together. Ele
24c0: 6d 65 6e 74 20 69 20 63 6f 6e 74 61 69 6e 73 20  ment i contains 
24d0: 74 68 65 20 72 65 73 75 6c 74 20 6f 66 20 0a 2a  the result of .*
24e0: 2a 20 63 6f 6d 70 61 72 69 6e 67 20 61 49 74 65  * comparing aIte
24f0: 72 5b 32 2a 69 2d 4e 5d 20 61 6e 64 20 61 49 74  r[2*i-N] and aIt
2500: 65 72 5b 32 2a 69 2d 4e 2b 31 5d 2e 20 57 68 69  er[2*i-N+1]. Whi
2510: 63 68 65 76 65 72 20 6b 65 79 20 69 73 20 73 6d  chever key is sm
2520: 61 6c 6c 65 72 2c 20 74 68 65 0a 2a 2a 20 61 54  aller, the.** aT
2530: 72 65 65 20 65 6c 65 6d 65 6e 74 20 69 73 20 73  ree element is s
2540: 65 74 20 74 6f 20 74 68 65 20 69 6e 64 65 78 20  et to the index 
2550: 6f 66 20 69 74 2e 20 0a 2a 2a 0a 2a 2a 20 46 6f  of it. .**.** Fo
2560: 72 20 74 68 65 20 70 75 72 70 6f 73 65 73 20 6f  r the purposes o
2570: 66 20 74 68 69 73 20 63 6f 6d 70 61 72 69 73 6f  f this compariso
2580: 6e 2c 20 45 4f 46 20 69 73 20 63 6f 6e 73 69 64  n, EOF is consid
2590: 65 72 65 64 20 67 72 65 61 74 65 72 20 74 68 61  ered greater tha
25a0: 6e 20 61 6e 79 0a 2a 2a 20 6f 74 68 65 72 20 6b  n any.** other k
25b0: 65 79 20 76 61 6c 75 65 2e 20 49 66 20 74 68 65  ey value. If the
25c0: 20 6b 65 79 73 20 61 72 65 20 65 71 75 61 6c 20   keys are equal 
25d0: 28 6f 6e 6c 79 20 70 6f 73 73 69 62 6c 65 20 77  (only possible w
25e0: 69 74 68 20 74 77 6f 20 45 4f 46 0a 2a 2a 20 76  ith two EOF.** v
25f0: 61 6c 75 65 73 29 2c 20 69 74 20 64 6f 65 73 6e  alues), it doesn
2600: 27 74 20 6d 61 74 74 65 72 20 77 68 69 63 68 20  't matter which 
2610: 69 6e 64 65 78 20 69 73 20 73 74 6f 72 65 64 2e  index is stored.
2620: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 28 4e 2f 34 29  .**.** The (N/4)
2630: 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20 61 54 72   elements of aTr
2640: 65 65 5b 5d 20 74 68 61 74 20 70 72 65 63 65 64  ee[] that preced
2650: 65 20 74 68 65 20 66 69 6e 61 6c 20 28 4e 2f 32  e the final (N/2
2660: 29 20 64 65 73 63 72 69 62 65 64 20 0a 2a 2a 20  ) described .** 
2670: 61 62 6f 76 65 20 63 6f 6e 74 61 69 6e 73 20 74  above contains t
2680: 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20  he index of the 
2690: 73 6d 61 6c 6c 65 73 74 20 6f 66 20 65 61 63 68  smallest of each
26a0: 20 62 6c 6f 63 6b 20 6f 66 20 34 20 69 74 65 72   block of 4 iter
26b0: 61 74 6f 72 73 2e 0a 2a 2a 20 41 6e 64 20 73 6f  ators..** And so
26c0: 20 6f 6e 2e 20 53 6f 20 74 68 61 74 20 61 54 72   on. So that aTr
26d0: 65 65 5b 31 5d 20 63 6f 6e 74 61 69 6e 73 20 74  ee[1] contains t
26e0: 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20  he index of the 
26f0: 69 74 65 72 61 74 6f 72 20 74 68 61 74 20 0a 2a  iterator that .*
2700: 2a 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e  * currently poin
2710: 74 73 20 74 6f 20 74 68 65 20 73 6d 61 6c 6c 65  ts to the smalle
2720: 73 74 20 6b 65 79 20 76 61 6c 75 65 2e 20 61 54  st key value. aT
2730: 72 65 65 5b 30 5d 20 69 73 20 75 6e 75 73 65 64  ree[0] is unused
2740: 2e 0a 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65 3a  ..**.** Example:
2750: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 49 74 65 72  .**.**     aIter
2760: 5b 30 5d 20 2d 3e 20 42 61 6e 61 6e 61 0a 2a 2a  [0] -> Banana.**
2770: 20 20 20 20 20 61 49 74 65 72 5b 31 5d 20 2d 3e       aIter[1] ->
2780: 20 46 65 69 6a 6f 61 0a 2a 2a 20 20 20 20 20 61   Feijoa.**     a
2790: 49 74 65 72 5b 32 5d 20 2d 3e 20 45 6c 64 65 72  Iter[2] -> Elder
27a0: 62 65 72 72 79 0a 2a 2a 20 20 20 20 20 61 49 74  berry.**     aIt
27b0: 65 72 5b 33 5d 20 2d 3e 20 43 75 72 72 61 6e 74  er[3] -> Currant
27c0: 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 34 5d  .**     aIter[4]
27d0: 20 2d 3e 20 47 72 61 70 65 66 72 75 69 74 0a 2a   -> Grapefruit.*
27e0: 2a 20 20 20 20 20 61 49 74 65 72 5b 35 5d 20 2d  *     aIter[5] -
27f0: 3e 20 41 70 70 6c 65 0a 2a 2a 20 20 20 20 20 61  > Apple.**     a
2800: 49 74 65 72 5b 36 5d 20 2d 3e 20 44 75 72 69 61  Iter[6] -> Duria
2810: 6e 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 37  n.**     aIter[7
2820: 5d 20 2d 3e 20 45 4f 46 0a 2a 2a 0a 2a 2a 20 20  ] -> EOF.**.**  
2830: 20 20 20 61 54 72 65 65 5b 5d 20 3d 20 7b 20 58     aTree[] = { X
2840: 2c 20 35 20 20 20 30 2c 20 35 20 20 20 20 30 2c  , 5   0, 5    0,
2850: 20 33 2c 20 35 2c 20 36 20 7d 0a 2a 2a 0a 2a 2a   3, 5, 6 }.**.**
2860: 20 54 68 65 20 63 75 72 72 65 6e 74 20 65 6c 65   The current ele
2870: 6d 65 6e 74 20 69 73 20 22 41 70 70 6c 65 22 20  ment is "Apple" 
2880: 28 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68  (the value of th
2890: 65 20 6b 65 79 20 69 6e 64 69 63 61 74 65 64 20  e key indicated 
28a0: 62 79 20 0a 2a 2a 20 69 74 65 72 61 74 6f 72 20  by .** iterator 
28b0: 35 29 2e 20 57 68 65 6e 20 74 68 65 20 4e 65 78  5). When the Nex
28c0: 74 28 29 20 6f 70 65 72 61 74 69 6f 6e 20 69 73  t() operation is
28d0: 20 69 6e 76 6f 6b 65 64 2c 20 69 74 65 72 61 74   invoked, iterat
28e0: 6f 72 20 35 20 77 69 6c 6c 0a 2a 2a 20 62 65 20  or 5 will.** be 
28f0: 61 64 76 61 6e 63 65 64 20 74 6f 20 74 68 65 20  advanced to the 
2900: 6e 65 78 74 20 6b 65 79 20 69 6e 20 69 74 73 20  next key in its 
2910: 73 65 67 6d 65 6e 74 2e 20 53 61 79 20 74 68 65  segment. Say the
2920: 20 6e 65 78 74 20 6b 65 79 20 69 73 0a 2a 2a 20   next key is.** 
2930: 22 45 67 67 70 6c 61 6e 74 22 3a 0a 2a 2a 0a 2a  "Eggplant":.**.*
2940: 2a 20 20 20 20 20 61 49 74 65 72 5b 35 5d 20 2d  *     aIter[5] -
2950: 3e 20 45 67 67 70 6c 61 6e 74 0a 2a 2a 0a 2a 2a  > Eggplant.**.**
2960: 20 54 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   The contents of
2970: 20 61 54 72 65 65 5b 5d 20 61 72 65 20 75 70 64   aTree[] are upd
2980: 61 74 65 64 20 66 69 72 73 74 20 62 79 20 63 6f  ated first by co
2990: 6d 70 61 72 69 6e 67 20 74 68 65 20 6e 65 77 20  mparing the new 
29a0: 69 74 65 72 61 74 6f 72 0a 2a 2a 20 35 20 6b 65  iterator.** 5 ke
29b0: 79 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e 74  y to the current
29c0: 20 6b 65 79 20 6f 66 20 69 74 65 72 61 74 6f 72   key of iterator
29d0: 20 34 20 28 73 74 69 6c 6c 20 22 47 72 61 70 65   4 (still "Grape
29e0: 66 72 75 69 74 22 29 2e 20 54 68 65 20 69 74 65  fruit"). The ite
29f0: 72 61 74 6f 72 0a 2a 2a 20 35 20 76 61 6c 75 65  rator.** 5 value
2a00: 20 69 73 20 73 74 69 6c 6c 20 73 6d 61 6c 6c 65   is still smalle
2a10: 72 2c 20 73 6f 20 61 54 72 65 65 5b 36 5d 20 69  r, so aTree[6] i
2a20: 73 20 73 65 74 20 74 6f 20 35 2e 20 41 6e 64 20  s set to 5. And 
2a30: 73 6f 20 6f 6e 20 75 70 20 74 68 65 20 74 72 65  so on up the tre
2a40: 65 2e 0a 2a 2a 20 54 68 65 20 76 61 6c 75 65 20  e..** The value 
2a50: 6f 66 20 69 74 65 72 61 74 6f 72 20 36 20 2d 20  of iterator 6 - 
2a60: 22 44 75 72 69 61 6e 22 20 2d 20 69 73 20 6e 6f  "Durian" - is no
2a70: 77 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 74  w smaller than t
2a80: 68 61 74 20 6f 66 20 69 74 65 72 61 74 6f 72 0a  hat of iterator.
2a90: 2a 2a 20 35 2c 20 73 6f 20 61 54 72 65 65 5b 33  ** 5, so aTree[3
2aa0: 5d 20 69 73 20 73 65 74 20 74 6f 20 36 2e 20 4b  ] is set to 6. K
2ab0: 65 79 20 30 20 69 73 20 73 6d 61 6c 6c 65 72 20  ey 0 is smaller 
2ac0: 74 68 61 6e 20 6b 65 79 20 36 20 28 42 61 6e 61  than key 6 (Bana
2ad0: 6e 61 3c 44 75 72 69 61 6e 29 2c 0a 2a 2a 20 73  na<Durian),.** s
2ae0: 6f 20 74 68 65 20 76 61 6c 75 65 20 77 72 69 74  o the value writ
2af0: 74 65 6e 20 69 6e 74 6f 20 65 6c 65 6d 65 6e 74  ten into element
2b00: 20 31 20 6f 66 20 74 68 65 20 61 72 72 61 79 20   1 of the array 
2b10: 69 73 20 30 2e 20 41 73 20 66 6f 6c 6c 6f 77 73  is 0. As follows
2b20: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 54 72 65  :.**.**     aTre
2b30: 65 5b 5d 20 3d 20 7b 20 58 2c 20 30 20 20 20 30  e[] = { X, 0   0
2b40: 2c 20 36 20 20 20 20 30 2c 20 33 2c 20 35 2c 20  , 6    0, 3, 5, 
2b50: 36 20 7d 0a 2a 2a 0a 2a 2a 20 49 6e 20 6f 74 68  6 }.**.** In oth
2b60: 65 72 20 77 6f 72 64 73 2c 20 65 61 63 68 20 74  er words, each t
2b70: 69 6d 65 20 77 65 20 61 64 76 61 6e 63 65 20 74  ime we advance t
2b80: 6f 20 74 68 65 20 6e 65 78 74 20 73 6f 72 74 65  o the next sorte
2b90: 72 20 65 6c 65 6d 65 6e 74 2c 20 6c 6f 67 32 28  r element, log2(
2ba0: 4e 29 0a 2a 2a 20 6b 65 79 20 63 6f 6d 70 61 72  N).** key compar
2bb0: 69 73 6f 6e 20 6f 70 65 72 61 74 69 6f 6e 73 20  ison operations 
2bc0: 61 72 65 20 72 65 71 75 69 72 65 64 2c 20 77 68  are required, wh
2bd0: 65 72 65 20 4e 20 69 73 20 74 68 65 20 6e 75 6d  ere N is the num
2be0: 62 65 72 20 6f 66 20 73 65 67 6d 65 6e 74 73 0a  ber of segments.
2bf0: 2a 2a 20 62 65 69 6e 67 20 6d 65 72 67 65 64 20  ** being merged 
2c00: 28 72 6f 75 6e 64 65 64 20 75 70 20 74 6f 20 74  (rounded up to t
2c10: 68 65 20 6e 65 78 74 20 70 6f 77 65 72 20 6f 66  he next power of
2c20: 20 32 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 4d   2)..*/.struct M
2c30: 65 72 67 65 45 6e 67 69 6e 65 20 7b 0a 20 20 69  ergeEngine {.  i
2c40: 6e 74 20 6e 54 72 65 65 3b 20 20 20 20 20 20 20  nt nTree;       
2c50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65            /* Use
2c60: 64 20 73 69 7a 65 20 6f 66 20 61 54 72 65 65 2f  d size of aTree/
2c70: 61 49 74 65 72 20 28 70 6f 77 65 72 20 6f 66 20  aIter (power of 
2c80: 32 29 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 54 72  2) */.  int *aTr
2c90: 65 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ee;             
2ca0: 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 73 74     /* Current st
2cb0: 61 74 65 20 6f 66 20 69 6e 63 72 65 6d 65 6e 74  ate of increment
2cc0: 61 6c 20 6d 65 72 67 65 20 2a 2f 0a 20 20 50 6d  al merge */.  Pm
2cd0: 61 52 65 61 64 65 72 20 2a 61 49 74 65 72 3b 20  aReader *aIter; 
2ce0: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61           /* Arra
2cf0: 79 20 6f 66 20 69 74 65 72 61 74 6f 72 73 20 74  y of iterators t
2d00: 6f 20 6d 65 72 67 65 20 64 61 74 61 20 66 72 6f  o merge data fro
2d10: 6d 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 45  m */.};../*.** E
2d20: 78 61 63 74 6c 79 20 56 64 62 65 53 6f 72 74 65  xactly VdbeSorte
2d30: 72 2e 6e 54 61 73 6b 20 69 6e 73 74 61 6e 63 65  r.nTask instance
2d40: 73 20 6f 66 20 74 68 69 73 20 6f 62 6a 65 63 74  s of this object
2d50: 20 61 72 65 20 61 6c 6c 6f 63 61 74 65 64 0a 2a   are allocated.*
2d60: 2a 20 61 73 20 70 61 72 74 20 6f 66 20 65 61 63  * as part of eac
2d70: 68 20 56 64 62 65 53 6f 72 74 65 72 20 6f 62 6a  h VdbeSorter obj
2d80: 65 63 74 2e 20 49 6e 73 74 61 6e 63 65 73 20 61  ect. Instances a
2d90: 72 65 20 6e 65 76 65 72 20 61 6c 6c 6f 63 61 74  re never allocat
2da0: 65 64 20 61 6e 79 0a 2a 2a 20 6f 74 68 65 72 20  ed any.** other 
2db0: 77 61 79 2e 20 56 64 62 65 53 6f 72 74 65 72 2e  way. VdbeSorter.
2dc0: 6e 54 61 73 6b 20 69 73 20 73 65 74 20 74 6f 20  nTask is set to 
2dd0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 77 6f  the number of wo
2de0: 72 6b 65 72 20 74 68 72 65 61 64 73 20 61 6c 6c  rker threads all
2df0: 6f 77 65 64 0a 2a 2a 20 28 73 65 65 20 53 51 4c  owed.** (see SQL
2e00: 49 54 45 5f 43 4f 4e 46 49 47 5f 57 4f 52 4b 45  ITE_CONFIG_WORKE
2e10: 52 5f 54 48 52 45 41 44 53 29 20 70 6c 75 73 20  R_THREADS) plus 
2e20: 6f 6e 65 20 28 74 68 65 20 6d 61 69 6e 20 74 68  one (the main th
2e30: 72 65 61 64 29 2e 0a 2a 2a 0a 2a 2a 20 45 73 73  read)..**.** Ess
2e40: 65 6e 74 69 61 6c 6c 79 2c 20 74 68 69 73 20 73  entially, this s
2e50: 74 72 75 63 74 75 72 65 20 63 6f 6e 74 61 69 6e  tructure contain
2e60: 73 20 61 6c 6c 20 74 68 6f 73 65 20 66 69 65 6c  s all those fiel
2e70: 64 73 20 6f 66 20 74 68 65 20 56 64 62 65 53 6f  ds of the VdbeSo
2e80: 72 74 65 72 0a 2a 2a 20 73 74 72 75 63 74 75 72  rter.** structur
2e90: 65 20 66 6f 72 20 77 68 69 63 68 20 65 61 63 68  e for which each
2ea0: 20 74 68 72 65 61 64 20 72 65 71 75 69 72 65 73   thread requires
2eb0: 20 61 20 73 65 70 61 72 61 74 65 20 69 6e 73 74   a separate inst
2ec0: 61 6e 63 65 2e 20 46 6f 72 20 65 78 61 6d 70 6c  ance. For exampl
2ed0: 65 2c 0a 2a 2a 20 65 61 63 68 20 74 68 72 65 61  e,.** each threa
2ee0: 64 20 72 65 71 75 72 69 65 73 20 69 74 73 20 6f  d requries its o
2ef0: 77 6e 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72  wn UnpackedRecor
2f00: 64 20 6f 62 6a 65 63 74 20 74 6f 20 75 6e 70 61  d object to unpa
2f10: 63 6b 20 72 65 63 6f 72 64 73 20 69 6e 0a 2a 2a  ck records in.**
2f20: 20 61 73 20 70 61 72 74 20 6f 66 20 63 6f 6d 70   as part of comp
2f30: 61 72 69 73 6f 6e 20 6f 70 65 72 61 74 69 6f 6e  arison operation
2f40: 73 2e 0a 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65 20  s..**.** Before 
2f50: 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  a background thr
2f60: 65 61 64 20 69 73 20 6c 61 75 6e 63 68 65 64 2c  ead is launched,
2f70: 20 76 61 72 69 61 62 6c 65 20 62 44 6f 6e 65 20   variable bDone 
2f80: 69 73 20 73 65 74 20 74 6f 20 30 2e 20 54 68 65  is set to 0. The
2f90: 6e 2c 20 0a 2a 2a 20 72 69 67 68 74 20 62 65 66  n, .** right bef
2fa0: 6f 72 65 20 69 74 20 65 78 69 74 73 2c 20 74 68  ore it exits, th
2fb0: 65 20 74 68 72 65 61 64 20 69 74 73 65 6c 66 20  e thread itself 
2fc0: 73 65 74 73 20 62 44 6f 6e 65 20 74 6f 20 31 2e  sets bDone to 1.
2fd0: 20 54 68 69 73 20 69 73 20 75 73 65 64 20 66 6f   This is used fo
2fe0: 72 20 0a 2a 2a 20 74 77 6f 20 70 75 72 70 6f 73  r .** two purpos
2ff0: 65 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 57  es:.**.**   1. W
3000: 68 65 6e 20 66 6c 75 73 68 69 6e 67 20 74 68 65  hen flushing the
3010: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65 6d   contents of mem
3020: 6f 72 79 20 74 6f 20 61 20 6c 65 76 65 6c 2d 30  ory to a level-0
3030: 20 50 4d 41 20 6f 6e 20 64 69 73 6b 2c 20 74 6f   PMA on disk, to
3040: 0a 2a 2a 20 20 20 20 20 20 61 74 74 65 6d 70 74  .**      attempt
3050: 20 74 6f 20 73 65 6c 65 63 74 20 61 20 53 6f 72   to select a Sor
3060: 74 53 75 62 74 61 73 6b 20 66 6f 72 20 77 68 69  tSubtask for whi
3070: 63 68 20 74 68 65 72 65 20 69 73 20 6e 6f 74 20  ch there is not 
3080: 61 6c 72 65 61 64 79 20 61 6e 0a 2a 2a 20 20 20  already an.**   
3090: 20 20 20 61 63 74 69 76 65 20 62 61 63 6b 67 72     active backgr
30a0: 6f 75 6e 64 20 74 68 72 65 61 64 20 28 73 69 6e  ound thread (sin
30b0: 63 65 20 64 6f 69 6e 67 20 73 6f 20 63 61 75 73  ce doing so caus
30c0: 65 73 20 74 68 65 20 6d 61 69 6e 20 74 68 72 65  es the main thre
30d0: 61 64 0a 2a 2a 20 20 20 20 20 20 74 6f 20 62 6c  ad.**      to bl
30e0: 6f 63 6b 20 75 6e 74 69 6c 20 69 74 20 66 69 6e  ock until it fin
30f0: 69 73 68 65 73 29 2e 0a 2a 2a 0a 2a 2a 20 20 20  ishes)..**.**   
3100: 32 2e 20 49 66 20 53 51 4c 49 54 45 5f 44 45 42  2. If SQLITE_DEB
3110: 55 47 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44  UG_SORTER_THREAD
3120: 53 20 69 73 20 64 65 66 69 6e 65 64 2c 20 74 6f  S is defined, to
3130: 20 64 65 74 65 72 6d 69 6e 65 20 69 66 20 61 20   determine if a 
3140: 63 61 6c 6c 0a 2a 2a 20 20 20 20 20 20 74 6f 20  call.**      to 
3150: 73 71 6c 69 74 65 33 54 68 72 65 61 64 4a 6f 69  sqlite3ThreadJoi
3160: 6e 28 29 20 69 73 20 6c 69 6b 65 6c 79 20 74 6f  n() is likely to
3170: 20 62 6c 6f 63 6b 2e 20 43 61 73 65 73 20 74 68   block. Cases th
3180: 61 74 20 61 72 65 20 6c 69 6b 65 6c 79 20 74 6f  at are likely to
3190: 0a 2a 2a 20 20 20 20 20 20 62 6c 6f 63 6b 20 70  .**      block p
31a0: 72 6f 76 6f 6b 65 20 64 65 62 75 67 67 69 6e 67  rovoke debugging
31b0: 20 6f 75 74 70 75 74 2e 0a 2a 2a 0a 2a 2a 20 49   output..**.** I
31c0: 6e 20 62 6f 74 68 20 63 61 73 65 73 2c 20 74 68  n both cases, th
31d0: 65 20 65 66 66 65 63 74 73 20 6f 66 20 74 68 65  e effects of the
31e0: 20 6d 61 69 6e 20 74 68 72 65 61 64 20 73 65 65   main thread see
31f0: 69 6e 67 20 28 62 44 6f 6e 65 3d 3d 30 29 20 65  ing (bDone==0) e
3200: 76 65 6e 0a 2a 2a 20 61 66 74 65 72 20 74 68 65  ven.** after the
3210: 20 74 68 72 65 61 64 20 68 61 73 20 66 69 6e 69   thread has fini
3220: 73 68 65 64 20 61 72 65 20 6e 6f 74 20 64 69 72  shed are not dir
3230: 65 2e 20 53 6f 20 77 65 20 64 6f 6e 27 74 20 77  e. So we don't w
3240: 6f 72 72 79 20 61 62 6f 75 74 0a 2a 2a 20 6d 65  orry about.** me
3250: 6d 6f 72 79 20 62 61 72 72 69 65 72 73 20 61 6e  mory barriers an
3260: 64 20 73 75 63 68 20 68 65 72 65 2e 0a 2a 2f 0a  d such here..*/.
3270: 73 74 72 75 63 74 20 53 6f 72 74 53 75 62 74 61  struct SortSubta
3280: 73 6b 20 7b 0a 20 20 53 51 4c 69 74 65 54 68 72  sk {.  SQLiteThr
3290: 65 61 64 20 2a 70 54 68 72 65 61 64 3b 20 20 20  ead *pThread;   
32a0: 20 20 20 20 20 20 20 2f 2a 20 42 61 63 6b 67 72         /* Backgr
32b0: 6f 75 6e 64 20 74 68 72 65 61 64 2c 20 69 66 20  ound thread, if 
32c0: 61 6e 79 20 2a 2f 0a 20 20 69 6e 74 20 62 44 6f  any */.  int bDo
32d0: 6e 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ne;             
32e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74 20           /* Set 
32f0: 69 66 20 74 68 72 65 61 64 20 69 73 20 66 69 6e  if thread is fin
3300: 69 73 68 65 64 20 62 75 74 20 6e 6f 74 20 6a 6f  ished but not jo
3310: 69 6e 65 64 20 2a 2f 0a 20 20 56 64 62 65 53 6f  ined */.  VdbeSo
3320: 72 74 65 72 20 2a 70 53 6f 72 74 65 72 3b 20 20  rter *pSorter;  
3330: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72            /* Sor
3340: 74 65 72 20 74 68 61 74 20 6f 77 6e 73 20 74 68  ter that owns th
3350: 69 73 20 73 75 62 2d 74 61 73 6b 20 2a 2f 0a 20  is sub-task */. 
3360: 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20   UnpackedRecord 
3370: 2a 70 55 6e 70 61 63 6b 65 64 3b 20 20 20 20 20  *pUnpacked;     
3380: 20 2f 2a 20 53 70 61 63 65 20 74 6f 20 75 6e 70   /* Space to unp
3390: 61 63 6b 20 61 20 72 65 63 6f 72 64 20 2a 2f 0a  ack a record */.
33a0: 20 20 53 6f 72 74 65 72 4c 69 73 74 20 6c 69 73    SorterList lis
33b0: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
33c0: 20 20 2f 2a 20 4c 69 73 74 20 66 6f 72 20 74 68    /* List for th
33d0: 72 65 61 64 20 74 6f 20 77 72 69 74 65 20 74 6f  read to write to
33e0: 20 61 20 50 4d 41 20 2a 2f 0a 20 20 69 6e 74 20   a PMA */.  int 
33f0: 6e 50 4d 41 3b 20 20 20 20 20 20 20 20 20 20 20  nPMA;           
3400: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
3410: 75 6d 62 65 72 20 6f 66 20 50 4d 41 73 20 63 75  umber of PMAs cu
3420: 72 72 65 6e 74 6c 79 20 69 6e 20 66 69 6c 65 20  rrently in file 
3430: 2a 2f 0a 20 20 53 6f 72 74 65 72 46 69 6c 65 20  */.  SorterFile 
3440: 66 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20  file;           
3450: 20 20 20 20 20 2f 2a 20 54 65 6d 70 20 66 69 6c       /* Temp fil
3460: 65 20 66 6f 72 20 6c 65 76 65 6c 2d 30 20 50 4d  e for level-0 PM
3470: 41 73 20 2a 2f 0a 20 20 53 6f 72 74 65 72 46 69  As */.  SorterFi
3480: 6c 65 20 66 69 6c 65 32 3b 20 20 20 20 20 20 20  le file2;       
3490: 20 20 20 20 20 20 20 20 2f 2a 20 53 70 61 63 65          /* Space
34a0: 20 66 6f 72 20 6f 74 68 65 72 20 50 4d 41 73 20   for other PMAs 
34b0: 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 4d 61 69  */.};../*.** Mai
34c0: 6e 20 73 6f 72 74 65 72 20 73 74 72 75 63 74 75  n sorter structu
34d0: 72 65 2e 20 41 20 73 69 6e 67 6c 65 20 69 6e 73  re. A single ins
34e0: 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 69 73  tance of this is
34f0: 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 65   allocated for e
3500: 61 63 68 20 0a 2a 2a 20 73 6f 72 74 65 72 20 63  ach .** sorter c
3510: 75 72 73 6f 72 20 63 72 65 61 74 65 64 20 62 79  ursor created by
3520: 20 74 68 65 20 56 44 42 45 2e 0a 2a 2a 0a 2a 2a   the VDBE..**.**
3530: 20 6d 78 4b 65 79 73 69 7a 65 3a 0a 2a 2a 20 20   mxKeysize:.**  
3540: 20 41 73 20 72 65 63 6f 72 64 73 20 61 72 65 20   As records are 
3550: 61 64 64 65 64 20 74 6f 20 74 68 65 20 73 6f 72  added to the sor
3560: 74 65 72 20 62 79 20 63 61 6c 6c 73 20 74 6f 20  ter by calls to 
3570: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
3580: 72 57 72 69 74 65 28 29 2c 0a 2a 2a 20 20 20 74  rWrite(),.**   t
3590: 68 69 73 20 76 61 72 69 61 62 6c 65 20 69 73 20  his variable is 
35a0: 75 70 64 61 74 65 64 20 73 6f 20 61 73 20 74 6f  updated so as to
35b0: 20 62 65 20 73 65 74 20 74 6f 20 74 68 65 20 73   be set to the s
35c0: 69 7a 65 20 6f 6e 20 64 69 73 6b 20 6f 66 20 74  ize on disk of t
35d0: 68 65 0a 2a 2a 20 20 20 6c 61 72 67 65 73 74 20  he.**   largest 
35e0: 72 65 63 6f 72 64 20 69 6e 20 74 68 65 20 73 6f  record in the so
35f0: 72 74 65 72 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  rter..*/.struct 
3600: 56 64 62 65 53 6f 72 74 65 72 20 7b 0a 20 20 69  VdbeSorter {.  i
3610: 6e 74 20 6d 6e 50 6d 61 53 69 7a 65 3b 20 20 20  nt mnPmaSize;   
3620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3630: 2a 20 4d 69 6e 69 6d 75 6d 20 50 4d 41 20 73 69  * Minimum PMA si
3640: 7a 65 2c 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  ze, in bytes */.
3650: 20 20 69 6e 74 20 6d 78 50 6d 61 53 69 7a 65 3b    int mxPmaSize;
3660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3670: 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 50 4d 41    /* Maximum PMA
3680: 20 73 69 7a 65 2c 20 69 6e 20 62 79 74 65 73 2e   size, in bytes.
3690: 20 20 30 3d 3d 6e 6f 20 6c 69 6d 69 74 20 2a 2f    0==no limit */
36a0: 0a 20 20 69 6e 74 20 6d 78 4b 65 79 73 69 7a 65  .  int mxKeysize
36b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
36c0: 20 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 73 65     /* Largest se
36d0: 72 69 61 6c 69 7a 65 64 20 6b 65 79 20 73 65 65  rialized key see
36e0: 6e 20 73 6f 20 66 61 72 20 2a 2f 0a 20 20 69 6e  n so far */.  in
36f0: 74 20 70 67 73 7a 3b 20 20 20 20 20 20 20 20 20  t pgsz;         
3700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3710: 20 4d 61 69 6e 20 64 61 74 61 62 61 73 65 20 70   Main database p
3720: 61 67 65 20 73 69 7a 65 20 2a 2f 0a 20 20 50 6d  age size */.  Pm
3730: 61 52 65 61 64 65 72 20 2a 70 52 65 61 64 65 72  aReader *pReader
3740: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
3750: 20 52 65 61 64 20 64 61 74 61 20 66 72 6f 6d 20   Read data from 
3760: 68 65 72 65 20 61 66 74 65 72 20 52 65 77 69 6e  here after Rewin
3770: 64 28 29 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e  d() */.  MergeEn
3780: 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 3b 20 20  gine *pMerger;  
3790: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 72 20 68           /* Or h
37a0: 65 72 65 2c 20 69 66 20 62 55 73 65 54 68 72 65  ere, if bUseThre
37b0: 61 64 73 3d 3d 30 20 2a 2f 0a 20 20 73 71 6c 69  ads==0 */.  sqli
37c0: 74 65 33 20 2a 64 62 3b 20 20 20 20 20 20 20 20  te3 *db;        
37d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
37e0: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
37f0: 6f 6e 20 2a 2f 0a 20 20 4b 65 79 49 6e 66 6f 20  on */.  KeyInfo 
3800: 2a 70 4b 65 79 49 6e 66 6f 3b 20 20 20 20 20 20  *pKeyInfo;      
3810: 20 20 20 20 20 20 20 20 2f 2a 20 48 6f 77 20 74          /* How t
3820: 6f 20 63 6f 6d 70 61 72 65 20 72 65 63 6f 72 64  o compare record
3830: 73 20 2a 2f 0a 20 20 55 6e 70 61 63 6b 65 64 52  s */.  UnpackedR
3840: 65 63 6f 72 64 20 2a 70 55 6e 70 61 63 6b 65 64  ecord *pUnpacked
3850: 3b 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 62  ;      /* Used b
3860: 79 20 56 64 62 65 53 6f 72 74 65 72 43 6f 6d 70  y VdbeSorterComp
3870: 61 72 65 28 29 20 2a 2f 0a 20 20 53 6f 72 74 65  are() */.  Sorte
3880: 72 4c 69 73 74 20 6c 69 73 74 3b 20 20 20 20 20  rList list;     
3890: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69             /* Li
38a0: 73 74 20 6f 66 20 69 6e 2d 6d 65 6d 6f 72 79 20  st of in-memory 
38b0: 72 65 63 6f 72 64 73 20 2a 2f 0a 20 20 69 6e 74  records */.  int
38c0: 20 69 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20 20   iMemory;       
38d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
38e0: 4f 66 66 73 65 74 20 6f 66 20 66 72 65 65 20 73  Offset of free s
38f0: 70 61 63 65 20 69 6e 20 6c 69 73 74 2e 61 4d 65  pace in list.aMe
3900: 6d 6f 72 79 20 2a 2f 0a 20 20 69 6e 74 20 6e 4d  mory */.  int nM
3910: 65 6d 6f 72 79 3b 20 20 20 20 20 20 20 20 20 20  emory;          
3920: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
3930: 65 20 6f 66 20 6c 69 73 74 2e 61 4d 65 6d 6f 72  e of list.aMemor
3940: 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 6e 20  y allocation in 
3950: 62 79 74 65 73 20 2a 2f 0a 20 20 75 38 20 62 55  bytes */.  u8 bU
3960: 73 65 50 4d 41 3b 20 20 20 20 20 20 20 20 20 20  sePMA;          
3970: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
3980: 75 65 20 69 66 20 6f 6e 65 20 6f 72 20 6d 6f 72  ue if one or mor
3990: 65 20 50 4d 41 73 20 63 72 65 61 74 65 64 20 2a  e PMAs created *
39a0: 2f 0a 20 20 75 38 20 62 55 73 65 54 68 72 65 61  /.  u8 bUseThrea
39b0: 64 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ds;             
39c0: 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 75      /* True to u
39d0: 73 65 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68  se background th
39e0: 72 65 61 64 73 20 2a 2f 0a 20 20 75 38 20 69 50  reads */.  u8 iP
39f0: 72 65 76 3b 20 20 20 20 20 20 20 20 20 20 20 20  rev;            
3a00: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 72             /* Pr
3a10: 65 76 69 6f 75 73 20 74 68 72 65 61 64 20 75 73  evious thread us
3a20: 65 64 20 74 6f 20 66 6c 75 73 68 20 50 4d 41 20  ed to flush PMA 
3a30: 2a 2f 0a 20 20 75 38 20 6e 54 61 73 6b 3b 20 20  */.  u8 nTask;  
3a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a50: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
3a60: 61 54 61 73 6b 5b 5d 20 61 72 72 61 79 20 2a 2f  aTask[] array */
3a70: 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 61  .  SortSubtask a
3a80: 54 61 73 6b 5b 31 5d 3b 20 20 20 20 20 20 20 20  Task[1];        
3a90: 20 20 20 2f 2a 20 4f 6e 65 20 6f 72 20 6d 6f 72     /* One or mor
3aa0: 65 20 73 75 62 74 61 73 6b 73 20 2a 2f 0a 7d 3b  e subtasks */.};
3ab0: 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73 74 61  ../*.** An insta
3ac0: 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  nce of the follo
3ad0: 77 69 6e 67 20 6f 62 6a 65 63 74 20 69 73 20 75  wing object is u
3ae0: 73 65 64 20 74 6f 20 72 65 61 64 20 72 65 63 6f  sed to read reco
3af0: 72 64 73 20 6f 75 74 20 6f 66 20 61 0a 2a 2a 20  rds out of a.** 
3b00: 50 4d 41 2c 20 69 6e 20 73 6f 72 74 65 64 20 6f  PMA, in sorted o
3b10: 72 64 65 72 2e 20 20 54 68 65 20 6e 65 78 74 20  rder.  The next 
3b20: 6b 65 79 20 74 6f 20 62 65 20 72 65 61 64 20 69  key to be read i
3b30: 73 20 63 61 63 68 65 64 20 69 6e 20 6e 4b 65 79  s cached in nKey
3b40: 2f 61 4b 65 79 2e 0a 2a 2a 20 70 46 69 6c 65 3d  /aKey..** pFile=
3b50: 3d 30 20 61 74 20 45 4f 46 2e 0a 2a 2f 0a 73 74  =0 at EOF..*/.st
3b60: 72 75 63 74 20 50 6d 61 52 65 61 64 65 72 20 7b  ruct PmaReader {
3b70: 0a 20 20 69 36 34 20 69 52 65 61 64 4f 66 66 3b  .  i64 iReadOff;
3b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3b90: 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 72 65     /* Current re
3ba0: 61 64 20 6f 66 66 73 65 74 20 2a 2f 0a 20 20 69  ad offset */.  i
3bb0: 36 34 20 69 45 6f 66 3b 20 20 20 20 20 20 20 20  64 iEof;        
3bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3bd0: 2a 20 31 20 62 79 74 65 20 70 61 73 74 20 45 4f  * 1 byte past EO
3be0: 46 20 66 6f 72 20 74 68 69 73 20 69 74 65 72 61  F for this itera
3bf0: 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 6c  tor */.  int nAl
3c00: 6c 6f 63 3b 20 20 20 20 20 20 20 20 20 20 20 20  loc;            
3c10: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65           /* Byte
3c20: 73 20 6f 66 20 73 70 61 63 65 20 61 74 20 61 41  s of space at aA
3c30: 6c 6c 6f 63 20 2a 2f 0a 20 20 69 6e 74 20 6e 4b  lloc */.  int nK
3c40: 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ey;             
3c50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
3c60: 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
3c70: 6b 65 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  key */.  sqlite3
3c80: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20  _file *pFile;   
3c90: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65           /* File
3ca0: 20 69 74 65 72 61 74 6f 72 20 69 73 20 72 65 61   iterator is rea
3cb0: 64 69 6e 67 20 66 72 6f 6d 20 2a 2f 0a 20 20 75  ding from */.  u
3cc0: 38 20 2a 61 41 6c 6c 6f 63 3b 20 20 20 20 20 20  8 *aAlloc;      
3cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3ce0: 2a 20 41 6c 6c 6f 63 61 74 65 64 20 73 70 61 63  * Allocated spac
3cf0: 65 20 2a 2f 0a 20 20 75 38 20 2a 61 4b 65 79 3b  e */.  u8 *aKey;
3d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3d10: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
3d20: 72 20 74 6f 20 63 75 72 72 65 6e 74 20 6b 65 79  r to current key
3d30: 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75 66 66 65   */.  u8 *aBuffe
3d40: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
3d50: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
3d60: 20 72 65 61 64 20 62 75 66 66 65 72 20 2a 2f 0a   read buffer */.
3d70: 20 20 69 6e 74 20 6e 42 75 66 66 65 72 3b 20 20    int nBuffer;  
3d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3d90: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 72 65 61    /* Size of rea
3da0: 64 20 62 75 66 66 65 72 20 69 6e 20 62 79 74 65  d buffer in byte
3db0: 73 20 2a 2f 0a 20 20 75 38 20 2a 61 4d 61 70 3b  s */.  u8 *aMap;
3dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3dd0: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
3de0: 72 20 74 6f 20 6d 61 70 70 69 6e 67 20 6f 66 20  r to mapping of 
3df0: 65 6e 74 69 72 65 20 66 69 6c 65 20 2a 2f 0a 20  entire file */. 
3e00: 20 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e   IncrMerger *pIn
3e10: 63 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  cr;             
3e20: 20 2f 2a 20 49 6e 63 72 65 6d 65 6e 74 61 6c 20   /* Incremental 
3e30: 6d 65 72 67 65 72 20 2a 2f 0a 7d 3b 0a 0a 2f 2a  merger */.};../*
3e40: 0a 2a 2a 20 4e 6f 72 6d 61 6c 6c 79 2c 20 61 20  .** Normally, a 
3e50: 50 6d 61 52 65 61 64 65 72 20 6f 62 6a 65 63 74  PmaReader object
3e60: 20 69 74 65 72 61 74 65 73 20 74 68 72 6f 75 67   iterates throug
3e70: 68 20 61 6e 20 65 78 69 73 74 69 6e 67 20 50 4d  h an existing PM
3e80: 41 20 73 74 6f 72 65 64 20 0a 2a 2a 20 77 69 74  A stored .** wit
3e90: 68 69 6e 20 61 20 74 65 6d 70 20 66 69 6c 65 2e  hin a temp file.
3ea0: 20 48 6f 77 65 76 65 72 2c 20 69 66 20 74 68 65   However, if the
3eb0: 20 50 6d 61 52 65 61 64 65 72 2e 70 49 6e 63 72   PmaReader.pIncr
3ec0: 20 76 61 72 69 61 62 6c 65 20 70 6f 69 6e 74 73   variable points
3ed0: 20 74 6f 0a 2a 2a 20 61 6e 20 6f 62 6a 65 63 74   to.** an object
3ee0: 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e   of the followin
3ef0: 67 20 74 79 70 65 2c 20 69 74 20 6d 61 79 20 62  g type, it may b
3f00: 65 20 75 73 65 64 20 74 6f 20 69 74 65 72 61 74  e used to iterat
3f10: 65 2f 6d 65 72 67 65 20 74 68 72 6f 75 67 68 0a  e/merge through.
3f20: 2a 2a 20 6d 75 6c 74 69 70 6c 65 20 50 4d 41 73  ** multiple PMAs
3f30: 20 73 69 6d 75 6c 74 61 6e 65 6f 75 73 6c 79 2e   simultaneously.
3f40: 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 61 72 65  .**.** There are
3f50: 20 74 77 6f 20 74 79 70 65 73 20 6f 66 20 49 6e   two types of In
3f60: 63 72 4d 65 72 67 65 72 20 6f 62 6a 65 63 74 20  crMerger object 
3f70: 2d 20 73 69 6e 67 6c 65 20 28 62 55 73 65 54 68  - single (bUseTh
3f80: 72 65 61 64 3d 3d 30 29 20 61 6e 64 20 0a 2a 2a  read==0) and .**
3f90: 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20   multi-threaded 
3fa0: 28 62 55 73 65 54 68 72 65 61 64 3d 3d 31 29 2e  (bUseThread==1).
3fb0: 20 0a 2a 2a 0a 2a 2a 20 41 20 6d 75 6c 74 69 2d   .**.** A multi-
3fc0: 74 68 72 65 61 64 65 64 20 49 6e 63 72 4d 65 72  threaded IncrMer
3fd0: 67 65 72 20 6f 62 6a 65 63 74 20 75 73 65 73 20  ger object uses 
3fe0: 74 77 6f 20 74 65 6d 70 6f 72 61 72 79 20 66 69  two temporary fi
3ff0: 6c 65 73 20 2d 20 61 46 69 6c 65 5b 30 5d 20 0a  les - aFile[0] .
4000: 2a 2a 20 61 6e 64 20 61 46 69 6c 65 5b 31 5d 2e  ** and aFile[1].
4010: 20 4e 65 69 74 68 65 72 20 66 69 6c 65 20 69 73   Neither file is
4020: 20 61 6c 6c 6f 77 65 64 20 74 6f 20 67 72 6f 77   allowed to grow
4030: 20 74 6f 20 6d 6f 72 65 20 74 68 61 6e 20 6d 78   to more than mx
4040: 53 7a 20 62 79 74 65 73 20 69 6e 20 0a 2a 2a 20  Sz bytes in .** 
4050: 73 69 7a 65 2e 20 57 68 65 6e 20 74 68 65 20 49  size. When the I
4060: 6e 63 72 4d 65 72 67 65 72 20 69 73 20 69 6e 69  ncrMerger is ini
4070: 74 69 61 6c 69 7a 65 64 2c 20 69 74 20 72 65 61  tialized, it rea
4080: 64 73 20 65 6e 6f 75 67 68 20 64 61 74 61 20 66  ds enough data f
4090: 72 6f 6d 20 0a 2a 2a 20 70 4d 65 72 67 65 72 20  rom .** pMerger 
40a0: 74 6f 20 70 6f 70 75 6c 61 74 65 20 61 46 69 6c  to populate aFil
40b0: 65 5b 30 5d 2e 20 49 74 20 74 68 65 6e 20 73 65  e[0]. It then se
40c0: 74 73 20 76 61 72 69 61 62 6c 65 73 20 77 69 74  ts variables wit
40d0: 68 69 6e 20 74 68 65 20 0a 2a 2a 20 63 6f 72 72  hin the .** corr
40e0: 65 73 70 6f 6e 64 69 6e 67 20 50 6d 61 52 65 61  esponding PmaRea
40f0: 64 65 72 20 6f 62 6a 65 63 74 20 74 6f 20 72 65  der object to re
4100: 61 64 20 66 72 6f 6d 20 74 68 61 74 20 66 69 6c  ad from that fil
4110: 65 20 61 6e 64 20 6b 69 63 6b 73 20 6f 66 66 20  e and kicks off 
4120: 0a 2a 2a 20 61 20 62 61 63 6b 67 72 6f 75 6e 64  .** a background
4130: 20 74 68 72 65 61 64 20 74 6f 20 70 6f 70 75 6c   thread to popul
4140: 61 74 65 20 61 46 69 6c 65 5b 31 5d 20 77 69 74  ate aFile[1] wit
4150: 68 20 74 68 65 20 6e 65 78 74 20 6d 78 53 7a 20  h the next mxSz 
4160: 62 79 74 65 73 20 6f 66 20 0a 2a 2a 20 73 6f 72  bytes of .** sor
4170: 74 65 64 20 72 65 63 6f 72 64 20 64 61 74 61 20  ted record data 
4180: 66 72 6f 6d 20 70 4d 65 72 67 65 72 2e 20 0a 2a  from pMerger. .*
4190: 2a 0a 2a 2a 20 57 68 65 6e 20 74 68 65 20 50 6d  *.** When the Pm
41a0: 61 52 65 61 64 65 72 20 72 65 61 63 68 65 73 20  aReader reaches 
41b0: 74 68 65 20 65 6e 64 20 6f 66 20 61 46 69 6c 65  the end of aFile
41c0: 5b 30 5d 2c 20 69 74 20 62 6c 6f 63 6b 73 20 75  [0], it blocks u
41d0: 6e 74 69 6c 20 74 68 65 0a 2a 2a 20 62 61 63 6b  ntil the.** back
41e0: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 68 61  ground thread ha
41f0: 73 20 66 69 6e 69 73 68 65 64 20 70 6f 70 75 6c  s finished popul
4200: 61 74 69 6e 67 20 61 46 69 6c 65 5b 31 5d 2e 20  ating aFile[1]. 
4210: 49 74 20 74 68 65 6e 20 65 78 63 68 61 6e 67 65  It then exchange
4220: 73 0a 2a 2a 20 74 68 65 20 63 6f 6e 74 65 6e 74  s.** the content
4230: 73 20 6f 66 20 74 68 65 20 61 46 69 6c 65 5b 30  s of the aFile[0
4240: 5d 20 61 6e 64 20 61 46 69 6c 65 5b 31 5d 20 76  ] and aFile[1] v
4250: 61 72 69 61 62 6c 65 73 20 77 69 74 68 69 6e 20  ariables within 
4260: 74 68 69 73 20 73 74 72 75 63 74 75 72 65 2c 0a  this structure,.
4270: 2a 2a 20 73 65 74 73 20 74 68 65 20 50 6d 61 52  ** sets the PmaR
4280: 65 61 64 65 72 20 66 69 65 6c 64 73 20 74 6f 20  eader fields to 
4290: 72 65 61 64 20 66 72 6f 6d 20 74 68 65 20 6e 65  read from the ne
42a0: 77 20 61 46 69 6c 65 5b 30 5d 20 61 6e 64 20 6b  w aFile[0] and k
42b0: 69 63 6b 73 20 6f 66 66 0a 2a 2a 20 61 6e 6f 74  icks off.** anot
42c0: 68 65 72 20 62 61 63 6b 67 72 6f 75 6e 64 20 74  her background t
42d0: 68 72 65 61 64 20 74 6f 20 70 6f 70 75 6c 61 74  hread to populat
42e0: 65 20 74 68 65 20 6e 65 77 20 61 46 69 6c 65 5b  e the new aFile[
42f0: 31 5d 2e 20 41 6e 64 20 73 6f 20 6f 6e 2c 20 75  1]. And so on, u
4300: 6e 74 69 6c 0a 2a 2a 20 74 68 65 20 63 6f 6e 74  ntil.** the cont
4310: 65 6e 74 73 20 6f 66 20 70 4d 65 72 67 65 72 20  ents of pMerger 
4320: 61 72 65 20 65 78 68 61 75 73 74 65 64 2e 0a 2a  are exhausted..*
4330: 2a 0a 2a 2a 20 41 20 73 69 6e 67 6c 65 2d 74 68  *.** A single-th
4340: 72 65 61 64 65 64 20 49 6e 63 72 4d 65 72 67 65  readed IncrMerge
4350: 72 20 64 6f 65 73 20 6e 6f 74 20 6f 70 65 6e 20  r does not open 
4360: 61 6e 79 20 74 65 6d 70 6f 72 61 72 79 20 66 69  any temporary fi
4370: 6c 65 73 20 6f 66 20 69 74 73 0a 2a 2a 20 6f 77  les of its.** ow
4380: 6e 2e 20 49 6e 73 74 65 61 64 2c 20 69 74 20 68  n. Instead, it h
4390: 61 73 20 65 78 63 6c 75 73 69 76 65 20 61 63 63  as exclusive acc
43a0: 65 73 73 20 74 6f 20 6d 78 53 7a 20 62 79 74 65  ess to mxSz byte
43b0: 73 20 6f 66 20 73 70 61 63 65 20 62 65 67 69 6e  s of space begin
43c0: 6e 69 6e 67 0a 2a 2a 20 61 74 20 6f 66 66 73 65  ning.** at offse
43d0: 74 20 69 53 74 61 72 74 4f 66 66 20 6f 66 20 66  t iStartOff of f
43e0: 69 6c 65 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32  ile pTask->file2
43f0: 2e 20 41 6e 64 20 69 6e 73 74 65 61 64 20 6f 66  . And instead of
4400: 20 75 73 69 6e 67 20 61 20 0a 2a 2a 20 62 61 63   using a .** bac
4410: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 74  kground thread t
4420: 6f 20 70 72 65 70 61 72 65 20 64 61 74 61 20 66  o prepare data f
4430: 6f 72 20 74 68 65 20 50 6d 61 52 65 61 64 65 72  or the PmaReader
4440: 2c 20 77 69 74 68 20 61 20 73 69 6e 67 6c 65 0a  , with a single.
4450: 2a 2a 20 74 68 72 65 61 64 65 64 20 49 6e 63 72  ** threaded Incr
4460: 4d 65 72 67 65 72 20 74 68 65 20 61 6c 6c 6f 63  Merger the alloc
4470: 61 74 65 20 70 61 72 74 20 6f 66 20 70 54 61 73  ate part of pTas
4480: 6b 2d 3e 66 69 6c 65 32 20 69 73 20 22 72 65 66  k->file2 is "ref
4490: 69 6c 6c 65 64 22 20 77 69 74 68 0a 2a 2a 20 6b  illed" with.** k
44a0: 65 79 73 20 66 72 6f 6d 20 70 4d 65 72 67 65 72  eys from pMerger
44b0: 20 62 79 20 74 68 65 20 63 61 6c 6c 69 6e 67 20   by the calling 
44c0: 74 68 72 65 61 64 20 77 68 65 6e 65 76 65 72 20  thread whenever 
44d0: 74 68 65 20 50 6d 61 52 65 61 64 65 72 20 72 75  the PmaReader ru
44e0: 6e 73 20 6f 75 74 0a 2a 2a 20 6f 66 20 64 61 74  ns out.** of dat
44f0: 61 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 49 6e 63  a..*/.struct Inc
4500: 72 4d 65 72 67 65 72 20 7b 0a 20 20 53 6f 72 74  rMerger {.  Sort
4510: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 3b 20  Subtask *pTask; 
4520: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
4530: 61 73 6b 20 74 68 61 74 20 6f 77 6e 73 20 74 68  ask that owns th
4540: 69 73 20 6d 65 72 67 65 72 20 2a 2f 0a 20 20 4d  is merger */.  M
4550: 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72  ergeEngine *pMer
4560: 67 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 2f  ger;           /
4570: 2a 20 4d 65 72 67 65 20 65 6e 67 69 6e 65 20 74  * Merge engine t
4580: 68 72 65 61 64 20 72 65 61 64 73 20 64 61 74 61  hread reads data
4590: 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 36 34 20 69   from */.  i64 i
45a0: 53 74 61 72 74 4f 66 66 3b 20 20 20 20 20 20 20  StartOff;       
45b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66             /* Of
45c0: 66 73 65 74 20 74 6f 20 73 74 61 72 74 20 77 72  fset to start wr
45d0: 69 74 69 6e 67 20 66 69 6c 65 20 61 74 20 2a 2f  iting file at */
45e0: 0a 20 20 69 6e 74 20 6d 78 53 7a 3b 20 20 20 20  .  int mxSz;    
45f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4600: 20 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 62 79     /* Maximum by
4610: 74 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 73  tes of data to s
4620: 74 6f 72 65 20 2a 2f 0a 20 20 69 6e 74 20 62 45  tore */.  int bE
4630: 6f 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  of;             
4640: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74            /* Set
4650: 20 74 6f 20 74 72 75 65 20 77 68 65 6e 20 6d 65   to true when me
4660: 72 67 65 20 69 73 20 66 69 6e 69 73 68 65 64 20  rge is finished 
4670: 2a 2f 0a 20 20 69 6e 74 20 62 55 73 65 54 68 72  */.  int bUseThr
4680: 65 61 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  ead;            
4690: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20       /* True to 
46a0: 75 73 65 20 61 20 62 67 20 74 68 72 65 61 64 20  use a bg thread 
46b0: 66 6f 72 20 74 68 69 73 20 6f 62 6a 65 63 74 20  for this object 
46c0: 2a 2f 0a 20 20 53 6f 72 74 65 72 46 69 6c 65 20  */.  SorterFile 
46d0: 61 46 69 6c 65 5b 32 5d 3b 20 20 20 20 20 20 20  aFile[2];       
46e0: 20 20 20 20 20 2f 2a 20 61 46 69 6c 65 5b 30 5d       /* aFile[0]
46f0: 20 66 6f 72 20 72 65 61 64 69 6e 67 2c 20 5b 31   for reading, [1
4700: 5d 20 66 6f 72 20 77 72 69 74 69 6e 67 20 2a 2f  ] for writing */
4710: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e  .};../*.** An in
4720: 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 6f  stance of this o
4730: 62 6a 65 63 74 20 69 73 20 75 73 65 64 20 66 6f  bject is used fo
4740: 72 20 77 72 69 74 69 6e 67 20 61 20 50 4d 41 2e  r writing a PMA.
4750: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 4d 41 20 69  .**.** The PMA i
4760: 73 20 77 72 69 74 74 65 6e 20 6f 6e 65 20 72 65  s written one re
4770: 63 6f 72 64 20 61 74 20 61 20 74 69 6d 65 2e 20  cord at a time. 
4780: 20 45 61 63 68 20 72 65 63 6f 72 64 20 69 73 20   Each record is 
4790: 6f 66 20 61 6e 20 61 72 62 69 74 72 61 72 79 0a  of an arbitrary.
47a0: 2a 2a 20 73 69 7a 65 2e 20 20 42 75 74 20 49 2f  ** size.  But I/
47b0: 4f 20 69 73 20 6d 6f 72 65 20 65 66 66 69 63 69  O is more effici
47c0: 65 6e 74 20 69 66 20 69 74 20 6f 63 63 75 72 73  ent if it occurs
47d0: 20 69 6e 20 70 61 67 65 2d 73 69 7a 65 64 20 62   in page-sized b
47e0: 6c 6f 63 6b 73 20 77 68 65 72 65 0a 2a 2a 20 65  locks where.** e
47f0: 61 63 68 20 62 6c 6f 63 6b 20 69 73 20 61 6c 69  ach block is ali
4800: 67 6e 65 64 20 6f 6e 20 61 20 70 61 67 65 20 62  gned on a page b
4810: 6f 75 6e 64 61 72 79 2e 20 20 54 68 69 73 20 6f  oundary.  This o
4820: 62 6a 65 63 74 20 63 61 63 68 65 73 20 77 72 69  bject caches wri
4830: 74 65 73 20 74 6f 0a 2a 2a 20 74 68 65 20 50 4d  tes to.** the PM
4840: 41 20 73 6f 20 74 68 61 74 20 61 6c 69 67 6e 65  A so that aligne
4850: 64 2c 20 70 61 67 65 2d 73 69 7a 65 20 62 6c 6f  d, page-size blo
4860: 63 6b 73 20 61 72 65 20 77 72 69 74 74 65 6e 2e  cks are written.
4870: 0a 2a 2f 0a 73 74 72 75 63 74 20 50 6d 61 57 72  .*/.struct PmaWr
4880: 69 74 65 72 20 7b 0a 20 20 69 6e 74 20 65 46 57  iter {.  int eFW
4890: 45 72 72 3b 20 20 20 20 20 20 20 20 20 20 20 20  Err;            
48a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 6f 6e 2d           /* Non-
48b0: 7a 65 72 6f 20 69 66 20 69 6e 20 61 6e 20 65 72  zero if in an er
48c0: 72 6f 72 20 73 74 61 74 65 20 2a 2f 0a 20 20 75  ror state */.  u
48d0: 38 20 2a 61 42 75 66 66 65 72 3b 20 20 20 20 20  8 *aBuffer;     
48e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
48f0: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 77 72 69  * Pointer to wri
4900: 74 65 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 69  te buffer */.  i
4910: 6e 74 20 6e 42 75 66 66 65 72 3b 20 20 20 20 20  nt nBuffer;     
4920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4930: 2a 20 53 69 7a 65 20 6f 66 20 77 72 69 74 65 20  * Size of write 
4940: 62 75 66 66 65 72 20 69 6e 20 62 79 74 65 73 20  buffer in bytes 
4950: 2a 2f 0a 20 20 69 6e 74 20 69 42 75 66 53 74 61  */.  int iBufSta
4960: 72 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rt;             
4970: 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 62 79       /* First by
4980: 74 65 20 6f 66 20 62 75 66 66 65 72 20 74 6f 20  te of buffer to 
4990: 77 72 69 74 65 20 2a 2f 0a 20 20 69 6e 74 20 69  write */.  int i
49a0: 42 75 66 45 6e 64 3b 20 20 20 20 20 20 20 20 20  BufEnd;         
49b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61             /* La
49c0: 73 74 20 62 79 74 65 20 6f 66 20 62 75 66 66 65  st byte of buffe
49d0: 72 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20  r to write */.  
49e0: 69 36 34 20 69 57 72 69 74 65 4f 66 66 3b 20 20  i64 iWriteOff;  
49f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4a00: 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20 73 74 61  /* Offset of sta
4a10: 72 74 20 6f 66 20 62 75 66 66 65 72 20 69 6e 20  rt of buffer in 
4a20: 66 69 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65  file */.  sqlite
4a30: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20  3_file *pFile;  
4a40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c            /* Fil
4a50: 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f  e to write to */
4a60: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  .};../*.** This 
4a70: 6f 62 6a 65 63 74 20 69 73 20 74 68 65 20 68 65  object is the he
4a80: 61 64 65 72 20 6f 6e 20 61 20 73 69 6e 67 6c 65  ader on a single
4a90: 20 72 65 63 6f 72 64 20 77 68 69 6c 65 20 74 68   record while th
4aa0: 61 74 20 72 65 63 6f 72 64 20 69 73 20 62 65 69  at record is bei
4ab0: 6e 67 0a 2a 2a 20 68 65 6c 64 20 69 6e 20 6d 65  ng.** held in me
4ac0: 6d 6f 72 79 20 61 6e 64 20 70 72 69 6f 72 20 74  mory and prior t
4ad0: 6f 20 62 65 69 6e 67 20 77 72 69 74 74 65 6e 20  o being written 
4ae0: 6f 75 74 20 61 73 20 70 61 72 74 20 6f 66 20 61  out as part of a
4af0: 20 50 4d 41 2e 0a 2a 2a 0a 2a 2a 20 48 6f 77 20   PMA..**.** How 
4b00: 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20  the linked list 
4b10: 69 73 20 63 6f 6e 6e 65 63 74 65 64 20 64 65 70  is connected dep
4b20: 65 6e 64 73 20 6f 6e 20 68 6f 77 20 6d 65 6d 6f  ends on how memo
4b30: 72 79 20 69 73 20 62 65 69 6e 67 20 6d 61 6e 61  ry is being mana
4b40: 67 65 64 0a 2a 2a 20 62 79 20 74 68 69 73 20 6d  ged.** by this m
4b50: 6f 64 75 6c 65 2e 20 49 66 20 75 73 69 6e 67 20  odule. If using 
4b60: 61 20 73 65 70 61 72 61 74 65 20 61 6c 6c 6f 63  a separate alloc
4b70: 61 74 69 6f 6e 20 66 6f 72 20 65 61 63 68 20 69  ation for each i
4b80: 6e 2d 6d 65 6d 6f 72 79 20 72 65 63 6f 72 64 0a  n-memory record.
4b90: 2a 2a 20 28 56 64 62 65 53 6f 72 74 65 72 2e 6c  ** (VdbeSorter.l
4ba0: 69 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30 29 2c  ist.aMemory==0),
4bb0: 20 74 68 65 6e 20 74 68 65 20 6c 69 73 74 20 69   then the list i
4bc0: 73 20 61 6c 77 61 79 73 20 63 6f 6e 6e 65 63 74  s always connect
4bd0: 65 64 20 75 73 69 6e 67 20 74 68 65 0a 2a 2a 20  ed using the.** 
4be0: 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 75 2e 70  SorterRecord.u.p
4bf0: 4e 65 78 74 20 70 6f 69 6e 74 65 72 73 2e 0a 2a  Next pointers..*
4c00: 2a 0a 2a 2a 20 4f 72 2c 20 69 66 20 75 73 69 6e  *.** Or, if usin
4c10: 67 20 74 68 65 20 73 69 6e 67 6c 65 20 6c 61 72  g the single lar
4c20: 67 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6d 65  ge allocation me
4c30: 74 68 6f 64 20 28 56 64 62 65 53 6f 72 74 65 72  thod (VdbeSorter
4c40: 2e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 21 3d 30  .list.aMemory!=0
4c50: 29 2c 0a 2a 2a 20 74 68 65 6e 20 77 68 69 6c 65  ),.** then while
4c60: 20 72 65 63 6f 72 64 73 20 61 72 65 20 62 65 69   records are bei
4c70: 6e 67 20 61 63 63 75 6d 75 6c 61 74 65 64 20 74  ng accumulated t
4c80: 68 65 20 6c 69 73 74 20 69 73 20 6c 69 6e 6b 65  he list is linke
4c90: 64 20 75 73 69 6e 67 20 74 68 65 0a 2a 2a 20 53  d using the.** S
4ca0: 6f 72 74 65 72 52 65 63 6f 72 64 2e 75 2e 69 4e  orterRecord.u.iN
4cb0: 65 78 74 20 6f 66 66 73 65 74 2e 20 54 68 69 73  ext offset. This
4cc0: 20 69 73 20 62 65 63 61 75 73 65 20 74 68 65 20   is because the 
4cd0: 61 4d 65 6d 6f 72 79 5b 5d 20 61 72 72 61 79 20  aMemory[] array 
4ce0: 6d 61 79 0a 2a 2a 20 62 65 20 73 71 6c 69 74 65  may.** be sqlite
4cf0: 33 52 65 61 6c 6c 6f 63 28 29 65 64 20 77 68 69  3Realloc()ed whi
4d00: 6c 65 20 72 65 63 6f 72 64 73 20 61 72 65 20 62  le records are b
4d10: 65 69 6e 67 20 61 63 63 75 6d 75 6c 61 74 65 64  eing accumulated
4d20: 2e 20 4f 6e 63 65 20 74 68 65 20 56 4d 0a 2a 2a  . Once the VM.**
4d30: 20 68 61 73 20 66 69 6e 69 73 68 65 64 20 70 61   has finished pa
4d40: 73 73 69 6e 67 20 72 65 63 6f 72 64 73 20 74 6f  ssing records to
4d50: 20 74 68 65 20 73 6f 72 74 65 72 2c 20 6f 72 20   the sorter, or 
4d60: 77 68 65 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f  when the in-memo
4d70: 72 79 20 62 75 66 66 65 72 0a 2a 2a 20 69 73 20  ry buffer.** is 
4d80: 66 75 6c 6c 2c 20 74 68 65 20 6c 69 73 74 20 69  full, the list i
4d90: 73 20 73 6f 72 74 65 64 2e 20 41 73 20 70 61 72  s sorted. As par
4da0: 74 20 6f 66 20 74 68 65 20 73 6f 72 74 69 6e 67  t of the sorting
4db0: 20 70 72 6f 63 65 73 73 2c 20 69 74 20 69 73 0a   process, it is.
4dc0: 2a 2a 20 63 6f 6e 76 65 72 74 65 64 20 74 6f 20  ** converted to 
4dd0: 75 73 65 20 74 68 65 20 53 6f 72 74 65 72 52 65  use the SorterRe
4de0: 63 6f 72 64 2e 75 2e 70 4e 65 78 74 20 70 6f 69  cord.u.pNext poi
4df0: 6e 74 65 72 73 2e 20 53 65 65 20 66 75 6e 63 74  nters. See funct
4e00: 69 6f 6e 0a 2a 2a 20 76 64 62 65 53 6f 72 74 65  ion.** vdbeSorte
4e10: 72 53 6f 72 74 28 29 20 66 6f 72 20 64 65 74 61  rSort() for deta
4e20: 69 6c 73 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 53  ils..*/.struct S
4e30: 6f 72 74 65 72 52 65 63 6f 72 64 20 7b 0a 20 20  orterRecord {.  
4e40: 69 6e 74 20 6e 56 61 6c 3b 20 20 20 20 20 20 20  int nVal;       
4e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4e60: 2f 2a 20 53 69 7a 65 20 6f 66 20 74 68 65 20 72  /* Size of the r
4e70: 65 63 6f 72 64 20 69 6e 20 62 79 74 65 73 20 2a  ecord in bytes *
4e80: 2f 0a 20 20 75 6e 69 6f 6e 20 7b 0a 20 20 20 20  /.  union {.    
4e90: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e  SorterRecord *pN
4ea0: 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 2f 2a  ext;          /*
4eb0: 20 50 6f 69 6e 74 65 72 20 74 6f 20 6e 65 78 74   Pointer to next
4ec0: 20 72 65 63 6f 72 64 20 69 6e 20 6c 69 73 74 20   record in list 
4ed0: 2a 2f 0a 20 20 20 20 69 6e 74 20 69 4e 65 78 74  */.    int iNext
4ee0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4ef0: 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 77       /* Offset w
4f00: 69 74 68 69 6e 20 61 4d 65 6d 6f 72 79 20 6f 66  ithin aMemory of
4f10: 20 6e 65 78 74 20 72 65 63 6f 72 64 20 2a 2f 0a   next record */.
4f20: 20 20 7d 20 75 3b 0a 20 20 2f 2a 20 54 68 65 20    } u;.  /* The 
4f30: 64 61 74 61 20 66 6f 72 20 74 68 65 20 72 65 63  data for the rec
4f40: 6f 72 64 20 69 6d 6d 65 64 69 61 74 65 6c 79 20  ord immediately 
4f50: 66 6f 6c 6c 6f 77 73 20 74 68 69 73 20 68 65 61  follows this hea
4f60: 64 65 72 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 52 65  der */.};../* Re
4f70: 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74  turn a pointer t
4f80: 6f 20 74 68 65 20 62 75 66 66 65 72 20 63 6f 6e  o the buffer con
4f90: 74 61 69 6e 69 6e 67 20 74 68 65 20 72 65 63 6f  taining the reco
4fa0: 72 64 20 64 61 74 61 20 66 6f 72 20 53 6f 72 74  rd data for Sort
4fb0: 65 72 52 65 63 6f 72 64 0a 2a 2a 20 6f 62 6a 65  erRecord.** obje
4fc0: 63 74 20 70 2e 20 53 68 6f 75 6c 64 20 62 65 20  ct p. Should be 
4fd0: 75 73 65 64 20 61 73 20 69 66 3a 0a 2a 2a 0a 2a  used as if:.**.*
4fe0: 2a 20 20 20 76 6f 69 64 20 2a 53 52 56 41 4c 28  *   void *SRVAL(
4ff0: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 29  SorterRecord *p)
5000: 20 7b 20 72 65 74 75 72 6e 20 28 76 6f 69 64 2a   { return (void*
5010: 29 26 70 5b 31 5d 3b 20 7d 0a 2a 2f 0a 23 64 65  )&p[1]; }.*/.#de
5020: 66 69 6e 65 20 53 52 56 41 4c 28 70 29 20 28 28  fine SRVAL(p) ((
5030: 76 6f 69 64 2a 29 28 28 53 6f 72 74 65 72 52 65  void*)((SorterRe
5040: 63 6f 72 64 2a 29 28 70 29 20 2b 20 31 29 29 0a  cord*)(p) + 1)).
5050: 0a 2f 2a 20 54 68 65 20 6d 69 6e 69 6d 75 6d 20  ./* The minimum 
5060: 50 4d 41 20 73 69 7a 65 20 69 73 20 73 65 74 20  PMA size is set 
5070: 74 6f 20 74 68 69 73 20 76 61 6c 75 65 20 6d 75  to this value mu
5080: 6c 74 69 70 6c 69 65 64 20 62 79 20 74 68 65 20  ltiplied by the 
5090: 64 61 74 61 62 61 73 65 0a 2a 2a 20 70 61 67 65  database.** page
50a0: 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73 2e 20   size in bytes. 
50b0: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53 4f 52 54   */.#define SORT
50c0: 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20 31  ER_MIN_WORKING 1
50d0: 30 0a 0a 2f 2a 20 4d 61 78 69 6d 75 6d 20 6e 75  0../* Maximum nu
50e0: 6d 62 65 72 20 6f 66 20 50 4d 41 73 20 74 68 61  mber of PMAs tha
50f0: 74 20 61 20 73 69 6e 67 6c 65 20 4d 65 72 67 65  t a single Merge
5100: 45 6e 67 69 6e 65 20 63 61 6e 20 6d 65 72 67 65  Engine can merge
5110: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53 4f 52 54   */.#define SORT
5120: 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55  ER_MAX_MERGE_COU
5130: 4e 54 20 31 36 0a 0a 73 74 61 74 69 63 20 69 6e  NT 16..static in
5140: 74 20 76 64 62 65 49 6e 63 72 53 77 61 70 28 49  t vdbeIncrSwap(I
5150: 6e 63 72 4d 65 72 67 65 72 2a 29 3b 0a 73 74 61  ncrMerger*);.sta
5160: 74 69 63 20 76 6f 69 64 20 76 64 62 65 49 6e 63  tic void vdbeInc
5170: 72 46 72 65 65 28 49 6e 63 72 4d 65 72 67 65 72  rFree(IncrMerger
5180: 20 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65   *);../*.** Free
5190: 20 61 6c 6c 20 6d 65 6d 6f 72 79 20 62 65 6c 6f   all memory belo
51a0: 6e 67 69 6e 67 20 74 6f 20 74 68 65 20 50 6d 61  nging to the Pma
51b0: 52 65 61 64 65 72 20 6f 62 6a 65 63 74 20 70 61  Reader object pa
51c0: 73 73 65 64 20 61 73 20 74 68 65 20 73 65 63 6f  ssed as the seco
51d0: 6e 64 0a 2a 2a 20 61 72 67 75 6d 65 6e 74 2e 20  nd.** argument. 
51e0: 41 6c 6c 20 73 74 72 75 63 74 75 72 65 20 66 69  All structure fi
51f0: 65 6c 64 73 20 61 72 65 20 73 65 74 20 74 6f 20  elds are set to 
5200: 7a 65 72 6f 20 62 65 66 6f 72 65 20 72 65 74 75  zero before retu
5210: 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63  rning..*/.static
5220: 20 76 6f 69 64 20 76 64 62 65 50 6d 61 52 65 61   void vdbePmaRea
5230: 64 65 72 43 6c 65 61 72 28 50 6d 61 52 65 61 64  derClear(PmaRead
5240: 65 72 20 2a 70 49 74 65 72 29 7b 0a 20 20 73 71  er *pIter){.  sq
5250: 6c 69 74 65 33 5f 66 72 65 65 28 70 49 74 65 72  lite3_free(pIter
5260: 2d 3e 61 41 6c 6c 6f 63 29 3b 0a 20 20 73 71 6c  ->aAlloc);.  sql
5270: 69 74 65 33 5f 66 72 65 65 28 70 49 74 65 72 2d  ite3_free(pIter-
5280: 3e 61 42 75 66 66 65 72 29 3b 0a 20 20 69 66 28  >aBuffer);.  if(
5290: 20 70 49 74 65 72 2d 3e 61 4d 61 70 20 29 20 73   pIter->aMap ) s
52a0: 71 6c 69 74 65 33 4f 73 55 6e 66 65 74 63 68 28  qlite3OsUnfetch(
52b0: 70 49 74 65 72 2d 3e 70 46 69 6c 65 2c 20 30 2c  pIter->pFile, 0,
52c0: 20 70 49 74 65 72 2d 3e 61 4d 61 70 29 3b 0a 20   pIter->aMap);. 
52d0: 20 69 66 28 20 70 49 74 65 72 2d 3e 70 49 6e 63   if( pIter->pInc
52e0: 72 20 29 20 76 64 62 65 49 6e 63 72 46 72 65 65  r ) vdbeIncrFree
52f0: 28 70 49 74 65 72 2d 3e 70 49 6e 63 72 29 3b 0a  (pIter->pIncr);.
5300: 20 20 6d 65 6d 73 65 74 28 70 49 74 65 72 2c 20    memset(pIter, 
5310: 30 2c 20 73 69 7a 65 6f 66 28 50 6d 61 52 65 61  0, sizeof(PmaRea
5320: 64 65 72 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  der));.}../*.** 
5330: 52 65 61 64 20 6e 42 79 74 65 20 62 79 74 65 73  Read nByte bytes
5340: 20 6f 66 20 64 61 74 61 20 66 72 6f 6d 20 74 68   of data from th
5350: 65 20 73 74 72 65 61 6d 20 6f 66 20 64 61 74 61  e stream of data
5360: 20 69 74 65 72 61 74 65 64 20 62 79 20 6f 62 6a   iterated by obj
5370: 65 63 74 20 70 2e 0a 2a 2a 20 49 66 20 73 75 63  ect p..** If suc
5380: 63 65 73 73 66 75 6c 2c 20 73 65 74 20 2a 70 70  cessful, set *pp
5390: 4f 75 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  Out to point to 
53a0: 61 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69 6e  a buffer contain
53b0: 69 6e 67 20 74 68 65 20 64 61 74 61 0a 2a 2a 20  ing the data.** 
53c0: 61 6e 64 20 72 65 74 75 72 6e 20 53 51 4c 49 54  and return SQLIT
53d0: 45 5f 4f 4b 2e 20 4f 74 68 65 72 77 69 73 65 2c  E_OK. Otherwise,
53e0: 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   if an error occ
53f0: 75 72 73 2c 20 72 65 74 75 72 6e 20 61 6e 20 53  urs, return an S
5400: 51 4c 69 74 65 0a 2a 2a 20 65 72 72 6f 72 20 63  QLite.** error c
5410: 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 62  ode..**.** The b
5420: 75 66 66 65 72 20 69 6e 64 69 63 61 74 65 64 20  uffer indicated 
5430: 62 79 20 2a 70 70 4f 75 74 20 6d 61 79 20 6f 6e  by *ppOut may on
5440: 6c 79 20 62 65 20 63 6f 6e 73 69 64 65 72 65 64  ly be considered
5450: 20 76 61 6c 69 64 20 75 6e 74 69 6c 20 74 68 65   valid until the
5460: 0a 2a 2a 20 6e 65 78 74 20 63 61 6c 6c 20 74 6f  .** next call to
5470: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 2e 0a   this function..
5480: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
5490: 62 65 50 6d 61 52 65 61 64 42 6c 6f 62 28 0a 20  bePmaReadBlob(. 
54a0: 20 50 6d 61 52 65 61 64 65 72 20 2a 70 2c 20 20   PmaReader *p,  
54b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
54c0: 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 2a 2f 0a   /* Iterator */.
54d0: 20 20 69 6e 74 20 6e 42 79 74 65 2c 20 20 20 20    int nByte,    
54e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
54f0: 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 64 61    /* Bytes of da
5500: 74 61 20 74 6f 20 72 65 61 64 20 2a 2f 0a 20 20  ta to read */.  
5510: 75 38 20 2a 2a 70 70 4f 75 74 20 20 20 20 20 20  u8 **ppOut      
5520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5530: 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20  /* OUT: Pointer 
5540: 74 6f 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69  to buffer contai
5550: 6e 69 6e 67 20 64 61 74 61 20 2a 2f 0a 29 7b 0a  ning data */.){.
5560: 20 20 69 6e 74 20 69 42 75 66 3b 20 20 20 20 20    int iBuf;     
5570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5580: 20 20 2f 2a 20 4f 66 66 73 65 74 20 77 69 74 68    /* Offset with
5590: 69 6e 20 62 75 66 66 65 72 20 74 6f 20 72 65 61  in buffer to rea
55a0: 64 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 6e 74 20  d from */.  int 
55b0: 6e 41 76 61 69 6c 3b 20 20 20 20 20 20 20 20 20  nAvail;         
55c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
55d0: 79 74 65 73 20 6f 66 20 64 61 74 61 20 61 76 61  ytes of data ava
55e0: 69 6c 61 62 6c 65 20 69 6e 20 62 75 66 66 65 72  ilable in buffer
55f0: 20 2a 2f 0a 0a 20 20 69 66 28 20 70 2d 3e 61 4d   */..  if( p->aM
5600: 61 70 20 29 7b 0a 20 20 20 20 2a 70 70 4f 75 74  ap ){.    *ppOut
5610: 20 3d 20 26 70 2d 3e 61 4d 61 70 5b 70 2d 3e 69   = &p->aMap[p->i
5620: 52 65 61 64 4f 66 66 5d 3b 0a 20 20 20 20 70 2d  ReadOff];.    p-
5630: 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e 42 79  >iReadOff += nBy
5640: 74 65 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53  te;.    return S
5650: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20  QLITE_OK;.  }.. 
5660: 20 61 73 73 65 72 74 28 20 70 2d 3e 61 42 75 66   assert( p->aBuf
5670: 66 65 72 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20  fer );..  /* If 
5680: 74 68 65 72 65 20 69 73 20 6e 6f 20 6d 6f 72 65  there is no more
5690: 20 64 61 74 61 20 74 6f 20 62 65 20 72 65 61 64   data to be read
56a0: 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66 65 72   from the buffer
56b0: 2c 20 72 65 61 64 20 74 68 65 20 6e 65 78 74 20  , read the next 
56c0: 0a 20 20 2a 2a 20 70 2d 3e 6e 42 75 66 66 65 72  .  ** p->nBuffer
56d0: 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 66   bytes of data f
56e0: 72 6f 6d 20 74 68 65 20 66 69 6c 65 20 69 6e 74  rom the file int
56f0: 6f 20 69 74 2e 20 4f 72 2c 20 69 66 20 74 68 65  o it. Or, if the
5700: 72 65 20 61 72 65 20 6c 65 73 73 0a 20 20 2a 2a  re are less.  **
5710: 20 74 68 61 6e 20 70 2d 3e 6e 42 75 66 66 65 72   than p->nBuffer
5720: 20 62 79 74 65 73 20 72 65 6d 61 69 6e 69 6e 67   bytes remaining
5730: 20 69 6e 20 74 68 65 20 50 4d 41 2c 20 72 65 61   in the PMA, rea
5740: 64 20 61 6c 6c 20 72 65 6d 61 69 6e 69 6e 67 20  d all remaining 
5750: 64 61 74 61 2e 20 20 2a 2f 0a 20 20 69 42 75 66  data.  */.  iBuf
5760: 20 3d 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 25   = p->iReadOff %
5770: 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 69   p->nBuffer;.  i
5780: 66 28 20 69 42 75 66 3d 3d 30 20 29 7b 0a 20 20  f( iBuf==0 ){.  
5790: 20 20 69 6e 74 20 6e 52 65 61 64 3b 20 20 20 20    int nRead;    
57a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
57b0: 2f 2a 20 42 79 74 65 73 20 74 6f 20 72 65 61 64  /* Bytes to read
57c0: 20 66 72 6f 6d 20 64 69 73 6b 20 2a 2f 0a 20 20   from disk */.  
57d0: 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
57e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
57f0: 2f 2a 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64  /* sqlite3OsRead
5800: 28 29 20 72 65 74 75 72 6e 20 63 6f 64 65 20 2a  () return code *
5810: 2f 0a 0a 20 20 20 20 2f 2a 20 44 65 74 65 72 6d  /..    /* Determ
5820: 69 6e 65 20 68 6f 77 20 6d 61 6e 79 20 62 79 74  ine how many byt
5830: 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 72 65  es of data to re
5840: 61 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 28  ad. */.    if( (
5850: 70 2d 3e 69 45 6f 66 20 2d 20 70 2d 3e 69 52 65  p->iEof - p->iRe
5860: 61 64 4f 66 66 29 20 3e 20 28 69 36 34 29 70 2d  adOff) > (i64)p-
5870: 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20  >nBuffer ){.    
5880: 20 20 6e 52 65 61 64 20 3d 20 70 2d 3e 6e 42 75    nRead = p->nBu
5890: 66 66 65 72 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  ffer;.    }else{
58a0: 0a 20 20 20 20 20 20 6e 52 65 61 64 20 3d 20 28  .      nRead = (
58b0: 69 6e 74 29 28 70 2d 3e 69 45 6f 66 20 2d 20 70  int)(p->iEof - p
58c0: 2d 3e 69 52 65 61 64 4f 66 66 29 3b 0a 20 20 20  ->iReadOff);.   
58d0: 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 6e   }.    assert( n
58e0: 52 65 61 64 3e 30 20 29 3b 0a 0a 20 20 20 20 2f  Read>0 );..    /
58f0: 2a 20 52 65 61 64 20 64 61 74 61 20 66 72 6f 6d  * Read data from
5900: 20 74 68 65 20 66 69 6c 65 2e 20 52 65 74 75 72   the file. Retur
5910: 6e 20 65 61 72 6c 79 20 69 66 20 61 6e 20 65 72  n early if an er
5920: 72 6f 72 20 6f 63 63 75 72 73 2e 20 2a 2f 0a 20  ror occurs. */. 
5930: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
5940: 73 52 65 61 64 28 70 2d 3e 70 46 69 6c 65 2c 20  sRead(p->pFile, 
5950: 70 2d 3e 61 42 75 66 66 65 72 2c 20 6e 52 65 61  p->aBuffer, nRea
5960: 64 2c 20 70 2d 3e 69 52 65 61 64 4f 66 66 29 3b  d, p->iReadOff);
5970: 0a 20 20 20 20 61 73 73 65 72 74 28 20 72 63 21  .    assert( rc!
5980: 3d 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f 53 48  =SQLITE_IOERR_SH
5990: 4f 52 54 5f 52 45 41 44 20 29 3b 0a 20 20 20 20  ORT_READ );.    
59a0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
59b0: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  K ) return rc;. 
59c0: 20 7d 0a 20 20 6e 41 76 61 69 6c 20 3d 20 70 2d   }.  nAvail = p-
59d0: 3e 6e 42 75 66 66 65 72 20 2d 20 69 42 75 66 3b  >nBuffer - iBuf;
59e0: 20 0a 0a 20 20 69 66 28 20 6e 42 79 74 65 3c 3d   ..  if( nByte<=
59f0: 6e 41 76 61 69 6c 20 29 7b 0a 20 20 20 20 2f 2a  nAvail ){.    /*
5a00: 20 54 68 65 20 72 65 71 75 65 73 74 65 64 20 64   The requested d
5a10: 61 74 61 20 69 73 20 61 76 61 69 6c 61 62 6c 65  ata is available
5a20: 20 69 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72   in the in-memor
5a30: 79 20 62 75 66 66 65 72 2e 20 49 6e 20 74 68 69  y buffer. In thi
5a40: 73 0a 20 20 20 20 2a 2a 20 63 61 73 65 20 74 68  s.    ** case th
5a50: 65 72 65 20 69 73 20 6e 6f 20 6e 65 65 64 20 74  ere is no need t
5a60: 6f 20 6d 61 6b 65 20 61 20 63 6f 70 79 20 6f 66  o make a copy of
5a70: 20 74 68 65 20 64 61 74 61 2c 20 6a 75 73 74 20   the data, just 
5a80: 72 65 74 75 72 6e 20 61 20 0a 20 20 20 20 2a 2a  return a .    **
5a90: 20 70 6f 69 6e 74 65 72 20 69 6e 74 6f 20 74 68   pointer into th
5aa0: 65 20 62 75 66 66 65 72 20 74 6f 20 74 68 65 20  e buffer to the 
5ab0: 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a 20 20 20 20  caller.  */.    
5ac0: 2a 70 70 4f 75 74 20 3d 20 26 70 2d 3e 61 42 75  *ppOut = &p->aBu
5ad0: 66 66 65 72 5b 69 42 75 66 5d 3b 0a 20 20 20 20  ffer[iBuf];.    
5ae0: 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e  p->iReadOff += n
5af0: 42 79 74 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  Byte;.  }else{. 
5b00: 20 20 20 2f 2a 20 54 68 65 20 72 65 71 75 65 73     /* The reques
5b10: 74 65 64 20 64 61 74 61 20 69 73 20 6e 6f 74 20  ted data is not 
5b20: 61 6c 6c 20 61 76 61 69 6c 61 62 6c 65 20 69 6e  all available in
5b30: 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 62   the in-memory b
5b40: 75 66 66 65 72 2e 0a 20 20 20 20 2a 2a 20 49 6e  uffer..    ** In
5b50: 20 74 68 69 73 20 63 61 73 65 2c 20 61 6c 6c 6f   this case, allo
5b60: 63 61 74 65 20 73 70 61 63 65 20 61 74 20 70 2d  cate space at p-
5b70: 3e 61 41 6c 6c 6f 63 5b 5d 20 74 6f 20 63 6f 70  >aAlloc[] to cop
5b80: 79 20 74 68 65 20 72 65 71 75 65 73 74 65 64 0a  y the requested.
5b90: 20 20 20 20 2a 2a 20 72 61 6e 67 65 20 69 6e 74      ** range int
5ba0: 6f 2e 20 54 68 65 6e 20 72 65 74 75 72 6e 20 61  o. Then return a
5bb0: 20 63 6f 70 79 20 6f 66 20 70 6f 69 6e 74 65 72   copy of pointer
5bc0: 20 70 2d 3e 61 41 6c 6c 6f 63 20 74 6f 20 74 68   p->aAlloc to th
5bd0: 65 20 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a 20 20  e caller.  */.  
5be0: 20 20 69 6e 74 20 6e 52 65 6d 3b 20 20 20 20 20    int nRem;     
5bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5c00: 2f 2a 20 42 79 74 65 73 20 72 65 6d 61 69 6e 69  /* Bytes remaini
5c10: 6e 67 20 74 6f 20 63 6f 70 79 20 2a 2f 0a 0a 20  ng to copy */.. 
5c20: 20 20 20 2f 2a 20 45 78 74 65 6e 64 20 74 68 65     /* Extend the
5c30: 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 61 6c 6c   p->aAlloc[] all
5c40: 6f 63 61 74 69 6f 6e 20 69 66 20 72 65 71 75 69  ocation if requi
5c50: 72 65 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20  red. */.    if( 
5c60: 70 2d 3e 6e 41 6c 6c 6f 63 3c 6e 42 79 74 65 20  p->nAlloc<nByte 
5c70: 29 7b 0a 20 20 20 20 20 20 75 38 20 2a 61 4e 65  ){.      u8 *aNe
5c80: 77 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e 65  w;.      int nNe
5c90: 77 20 3d 20 4d 41 58 28 31 32 38 2c 20 70 2d 3e  w = MAX(128, p->
5ca0: 6e 41 6c 6c 6f 63 2a 32 29 3b 0a 20 20 20 20 20  nAlloc*2);.     
5cb0: 20 77 68 69 6c 65 28 20 6e 42 79 74 65 3e 6e 4e   while( nByte>nN
5cc0: 65 77 20 29 20 6e 4e 65 77 20 3d 20 6e 4e 65 77  ew ) nNew = nNew
5cd0: 2a 32 3b 0a 20 20 20 20 20 20 61 4e 65 77 20 3d  *2;.      aNew =
5ce0: 20 73 71 6c 69 74 65 33 52 65 61 6c 6c 6f 63 28   sqlite3Realloc(
5cf0: 70 2d 3e 61 41 6c 6c 6f 63 2c 20 6e 4e 65 77 29  p->aAlloc, nNew)
5d00: 3b 0a 20 20 20 20 20 20 69 66 28 20 21 61 4e 65  ;.      if( !aNe
5d10: 77 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  w ) return SQLIT
5d20: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 70  E_NOMEM;.      p
5d30: 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 6e 4e 65 77 3b  ->nAlloc = nNew;
5d40: 0a 20 20 20 20 20 20 70 2d 3e 61 41 6c 6c 6f 63  .      p->aAlloc
5d50: 20 3d 20 61 4e 65 77 3b 0a 20 20 20 20 7d 0a 0a   = aNew;.    }..
5d60: 20 20 20 20 2f 2a 20 43 6f 70 79 20 61 73 20 6d      /* Copy as m
5d70: 75 63 68 20 64 61 74 61 20 61 73 20 69 73 20 61  uch data as is a
5d80: 76 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65 20  vailable in the 
5d90: 62 75 66 66 65 72 20 69 6e 74 6f 20 74 68 65 20  buffer into the 
5da0: 73 74 61 72 74 20 6f 66 0a 20 20 20 20 2a 2a 20  start of.    ** 
5db0: 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 2e 20 20 2a 2f  p->aAlloc[].  */
5dc0: 0a 20 20 20 20 6d 65 6d 63 70 79 28 70 2d 3e 61  .    memcpy(p->a
5dd0: 41 6c 6c 6f 63 2c 20 26 70 2d 3e 61 42 75 66 66  Alloc, &p->aBuff
5de0: 65 72 5b 69 42 75 66 5d 2c 20 6e 41 76 61 69 6c  er[iBuf], nAvail
5df0: 29 3b 0a 20 20 20 20 70 2d 3e 69 52 65 61 64 4f  );.    p->iReadO
5e00: 66 66 20 2b 3d 20 6e 41 76 61 69 6c 3b 0a 20 20  ff += nAvail;.  
5e10: 20 20 6e 52 65 6d 20 3d 20 6e 42 79 74 65 20 2d    nRem = nByte -
5e20: 20 6e 41 76 61 69 6c 3b 0a 0a 20 20 20 20 2f 2a   nAvail;..    /*
5e30: 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6c   The following l
5e40: 6f 6f 70 20 63 6f 70 69 65 73 20 75 70 20 74 6f  oop copies up to
5e50: 20 70 2d 3e 6e 42 75 66 66 65 72 20 62 79 74 65   p->nBuffer byte
5e60: 73 20 70 65 72 20 69 74 65 72 61 74 69 6f 6e 20  s per iteration 
5e70: 69 6e 74 6f 0a 20 20 20 20 2a 2a 20 74 68 65 20  into.    ** the 
5e80: 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 62 75 66 66  p->aAlloc[] buff
5e90: 65 72 2e 20 20 2a 2f 0a 20 20 20 20 77 68 69 6c  er.  */.    whil
5ea0: 65 28 20 6e 52 65 6d 3e 30 20 29 7b 0a 20 20 20  e( nRem>0 ){.   
5eb0: 20 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20     int rc;      
5ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5ed0: 2a 20 76 64 62 65 50 6d 61 52 65 61 64 42 6c 6f  * vdbePmaReadBlo
5ee0: 62 28 29 20 72 65 74 75 72 6e 20 63 6f 64 65 20  b() return code 
5ef0: 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e 43 6f  */.      int nCo
5f00: 70 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  py;             
5f10: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
5f20: 66 20 62 79 74 65 73 20 74 6f 20 63 6f 70 79 20  f bytes to copy 
5f30: 2a 2f 0a 20 20 20 20 20 20 75 38 20 2a 61 4e 65  */.      u8 *aNe
5f40: 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  xt;             
5f50: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
5f60: 74 6f 20 62 75 66 66 65 72 20 74 6f 20 63 6f 70  to buffer to cop
5f70: 79 20 64 61 74 61 20 66 72 6f 6d 20 2a 2f 0a 0a  y data from */..
5f80: 20 20 20 20 20 20 6e 43 6f 70 79 20 3d 20 6e 52        nCopy = nR
5f90: 65 6d 3b 0a 20 20 20 20 20 20 69 66 28 20 6e 52  em;.      if( nR
5fa0: 65 6d 3e 70 2d 3e 6e 42 75 66 66 65 72 20 29 20  em>p->nBuffer ) 
5fb0: 6e 43 6f 70 79 20 3d 20 70 2d 3e 6e 42 75 66 66  nCopy = p->nBuff
5fc0: 65 72 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 76  er;.      rc = v
5fd0: 64 62 65 50 6d 61 52 65 61 64 42 6c 6f 62 28 70  dbePmaReadBlob(p
5fe0: 2c 20 6e 43 6f 70 79 2c 20 26 61 4e 65 78 74 29  , nCopy, &aNext)
5ff0: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  ;.      if( rc!=
6000: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
6010: 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 61 73 73  rn rc;.      ass
6020: 65 72 74 28 20 61 4e 65 78 74 21 3d 70 2d 3e 61  ert( aNext!=p->a
6030: 41 6c 6c 6f 63 20 29 3b 0a 20 20 20 20 20 20 6d  Alloc );.      m
6040: 65 6d 63 70 79 28 26 70 2d 3e 61 41 6c 6c 6f 63  emcpy(&p->aAlloc
6050: 5b 6e 42 79 74 65 20 2d 20 6e 52 65 6d 5d 2c 20  [nByte - nRem], 
6060: 61 4e 65 78 74 2c 20 6e 43 6f 70 79 29 3b 0a 20  aNext, nCopy);. 
6070: 20 20 20 20 20 6e 52 65 6d 20 2d 3d 20 6e 43 6f       nRem -= nCo
6080: 70 79 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2a  py;.    }..    *
6090: 70 70 4f 75 74 20 3d 20 70 2d 3e 61 41 6c 6c 6f  ppOut = p->aAllo
60a0: 63 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  c;.  }..  return
60b0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
60c0: 2a 0a 2a 2a 20 52 65 61 64 20 61 20 76 61 72 69  *.** Read a vari
60d0: 6e 74 20 66 72 6f 6d 20 74 68 65 20 73 74 72 65  nt from the stre
60e0: 61 6d 20 6f 66 20 64 61 74 61 20 61 63 63 65 73  am of data acces
60f0: 73 65 64 20 62 79 20 70 2e 20 53 65 74 20 2a 70  sed by p. Set *p
6100: 6e 4f 75 74 20 74 6f 0a 2a 2a 20 74 68 65 20 76  nOut to.** the v
6110: 61 6c 75 65 20 72 65 61 64 2e 0a 2a 2f 0a 73 74  alue read..*/.st
6120: 61 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d 61  atic int vdbePma
6130: 52 65 61 64 56 61 72 69 6e 74 28 50 6d 61 52 65  ReadVarint(PmaRe
6140: 61 64 65 72 20 2a 70 2c 20 75 36 34 20 2a 70 6e  ader *p, u64 *pn
6150: 4f 75 74 29 7b 0a 20 20 69 6e 74 20 69 42 75 66  Out){.  int iBuf
6160: 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 61 4d 61 70  ;..  if( p->aMap
6170: 20 29 7b 0a 20 20 20 20 70 2d 3e 69 52 65 61 64   ){.    p->iRead
6180: 4f 66 66 20 2b 3d 20 73 71 6c 69 74 65 33 47 65  Off += sqlite3Ge
6190: 74 56 61 72 69 6e 74 28 26 70 2d 3e 61 4d 61 70  tVarint(&p->aMap
61a0: 5b 70 2d 3e 69 52 65 61 64 4f 66 66 5d 2c 20 70  [p->iReadOff], p
61b0: 6e 4f 75 74 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  nOut);.  }else{.
61c0: 20 20 20 20 69 42 75 66 20 3d 20 70 2d 3e 69 52      iBuf = p->iR
61d0: 65 61 64 4f 66 66 20 25 20 70 2d 3e 6e 42 75 66  eadOff % p->nBuf
61e0: 66 65 72 3b 0a 20 20 20 20 69 66 28 20 69 42 75  fer;.    if( iBu
61f0: 66 20 26 26 20 28 70 2d 3e 6e 42 75 66 66 65 72  f && (p->nBuffer
6200: 2d 69 42 75 66 29 3e 3d 39 20 29 7b 0a 20 20 20  -iBuf)>=9 ){.   
6210: 20 20 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b     p->iReadOff +
6220: 3d 20 73 71 6c 69 74 65 33 47 65 74 56 61 72 69  = sqlite3GetVari
6230: 6e 74 28 26 70 2d 3e 61 42 75 66 66 65 72 5b 69  nt(&p->aBuffer[i
6240: 42 75 66 5d 2c 20 70 6e 4f 75 74 29 3b 0a 20 20  Buf], pnOut);.  
6250: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 75    }else{.      u
6260: 38 20 61 56 61 72 69 6e 74 5b 31 36 5d 2c 20 2a  8 aVarint[16], *
6270: 61 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 20 3d  a;.      int i =
6280: 20 30 2c 20 72 63 3b 0a 20 20 20 20 20 20 64 6f   0, rc;.      do
6290: 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 76  {.        rc = v
62a0: 64 62 65 50 6d 61 52 65 61 64 42 6c 6f 62 28 70  dbePmaReadBlob(p
62b0: 2c 20 31 2c 20 26 61 29 3b 0a 20 20 20 20 20 20  , 1, &a);.      
62c0: 20 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72    if( rc ) retur
62d0: 6e 20 72 63 3b 0a 20 20 20 20 20 20 20 20 61 56  n rc;.        aV
62e0: 61 72 69 6e 74 5b 28 69 2b 2b 29 26 30 78 66 5d  arint[(i++)&0xf]
62f0: 20 3d 20 61 5b 30 5d 3b 0a 20 20 20 20 20 20 7d   = a[0];.      }
6300: 77 68 69 6c 65 28 20 28 61 5b 30 5d 26 30 78 38  while( (a[0]&0x8
6310: 30 29 21 3d 30 20 29 3b 0a 20 20 20 20 20 20 73  0)!=0 );.      s
6320: 71 6c 69 74 65 33 47 65 74 56 61 72 69 6e 74 28  qlite3GetVarint(
6330: 61 56 61 72 69 6e 74 2c 20 70 6e 4f 75 74 29 3b  aVarint, pnOut);
6340: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
6350: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
6360: 7d 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74  }../*.** Attempt
6370: 20 74 6f 20 6d 65 6d 6f 72 79 20 6d 61 70 20 66   to memory map f
6380: 69 6c 65 20 70 46 69 6c 65 2e 20 49 66 20 73 75  ile pFile. If su
6390: 63 63 65 73 73 66 75 6c 2c 20 73 65 74 20 2a 70  ccessful, set *p
63a0: 70 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68  p to point to th
63b0: 65 0a 2a 2a 20 6e 65 77 20 6d 61 70 70 69 6e 67  e.** new mapping
63c0: 20 61 6e 64 20 72 65 74 75 72 6e 20 53 51 4c 49   and return SQLI
63d0: 54 45 5f 4f 4b 2e 20 49 66 20 74 68 65 20 6d 61  TE_OK. If the ma
63e0: 70 70 69 6e 67 20 69 73 20 6e 6f 74 20 61 74 74  pping is not att
63f0: 65 6d 70 74 65 64 20 0a 2a 2a 20 28 62 65 63 61  empted .** (beca
6400: 75 73 65 20 74 68 65 20 66 69 6c 65 20 69 73 20  use the file is 
6410: 74 6f 6f 20 6c 61 72 67 65 20 6f 72 20 74 68 65  too large or the
6420: 20 56 46 53 20 6c 61 79 65 72 20 69 73 20 63 6f   VFS layer is co
6430: 6e 66 69 67 75 72 65 64 20 6e 6f 74 20 74 6f 20  nfigured not to 
6440: 75 73 65 0a 2a 2a 20 6d 6d 61 70 29 2c 20 72 65  use.** mmap), re
6450: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 61  turn SQLITE_OK a
6460: 6e 64 20 73 65 74 20 2a 70 70 20 74 6f 20 4e 55  nd set *pp to NU
6470: 4c 4c 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 69 66  LL..**.** Or, if
6480: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
6490: 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69  , return an SQLi
64a0: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 20 54  te error code. T
64b0: 68 65 20 66 69 6e 61 6c 20 76 61 6c 75 65 20 6f  he final value o
64c0: 66 0a 2a 2a 20 2a 70 70 20 69 73 20 75 6e 64 65  f.** *pp is unde
64d0: 66 69 6e 65 64 20 69 6e 20 74 68 69 73 20 63 61  fined in this ca
64e0: 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  se..*/.static in
64f0: 74 20 76 64 62 65 53 6f 72 74 65 72 4d 61 70 46  t vdbeSorterMapF
6500: 69 6c 65 28 53 6f 72 74 53 75 62 74 61 73 6b 20  ile(SortSubtask 
6510: 2a 70 54 61 73 6b 2c 20 53 6f 72 74 65 72 46 69  *pTask, SorterFi
6520: 6c 65 20 2a 70 46 69 6c 65 2c 20 75 38 20 2a 2a  le *pFile, u8 **
6530: 70 70 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  pp){.  int rc = 
6540: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28  SQLITE_OK;.  if(
6550: 20 70 46 69 6c 65 2d 3e 69 45 6f 66 3c 3d 28 69   pFile->iEof<=(i
6560: 36 34 29 28 70 54 61 73 6b 2d 3e 70 53 6f 72 74  64)(pTask->pSort
6570: 65 72 2d 3e 64 62 2d 3e 6e 4d 61 78 53 6f 72 74  er->db->nMaxSort
6580: 65 72 4d 6d 61 70 29 20 29 7b 0a 20 20 20 20 72  erMmap) ){.    r
6590: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 46 65 74  c = sqlite3OsFet
65a0: 63 68 28 70 46 69 6c 65 2d 3e 70 46 64 2c 20 30  ch(pFile->pFd, 0
65b0: 2c 20 70 46 69 6c 65 2d 3e 69 45 6f 66 2c 20 28  , pFile->iEof, (
65c0: 76 6f 69 64 2a 2a 29 70 70 29 3b 0a 20 20 7d 0a  void**)pp);.  }.
65d0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
65e0: 2f 2a 0a 2a 2a 20 53 65 65 6b 20 69 74 65 72 61  /*.** Seek itera
65f0: 74 6f 72 20 70 49 74 65 72 20 74 6f 20 6f 66 66  tor pIter to off
6600: 73 65 74 20 69 4f 66 66 20 77 69 74 68 69 6e 20  set iOff within 
6610: 66 69 6c 65 20 70 46 69 6c 65 2e 20 52 65 74 75  file pFile. Retu
6620: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 0a 2a 2a  rn SQLITE_OK .**
6630: 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   if successful, 
6640: 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  or an SQLite err
6650: 6f 72 20 63 6f 64 65 20 69 66 20 61 6e 20 65 72  or code if an er
6660: 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73  ror occurs..*/.s
6670: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d  tatic int vdbePm
6680: 61 52 65 61 64 65 72 53 65 65 6b 28 0a 20 20 53  aReaderSeek(.  S
6690: 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
66a0: 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  k,             /
66b0: 2a 20 54 61 73 6b 20 63 6f 6e 74 65 78 74 20 2a  * Task context *
66c0: 2f 0a 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70  /.  PmaReader *p
66d0: 49 74 65 72 2c 20 20 20 20 20 20 20 20 20 20 20  Iter,           
66e0: 20 20 20 20 2f 2a 20 49 74 65 72 61 74 65 20 74      /* Iterate t
66f0: 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f 0a 20 20  o populate */.  
6700: 53 6f 72 74 65 72 46 69 6c 65 20 2a 70 46 69 6c  SorterFile *pFil
6710: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
6720: 2f 2a 20 53 6f 72 74 65 72 20 66 69 6c 65 20 74  /* Sorter file t
6730: 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20  o read from */. 
6740: 20 69 36 34 20 69 4f 66 66 20 20 20 20 20 20 20   i64 iOff       
6750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6760: 20 2f 2a 20 4f 66 66 73 65 74 20 69 6e 20 70 46   /* Offset in pF
6770: 69 6c 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  ile */.){.  int 
6780: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
6790: 0a 20 20 61 73 73 65 72 74 28 20 70 49 74 65 72  .  assert( pIter
67a0: 2d 3e 70 49 6e 63 72 3d 3d 30 20 7c 7c 20 70 49  ->pIncr==0 || pI
67b0: 74 65 72 2d 3e 70 49 6e 63 72 2d 3e 62 45 6f 66  ter->pIncr->bEof
67c0: 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 70 49  ==0 );..  if( pI
67d0: 74 65 72 2d 3e 61 4d 61 70 20 29 7b 0a 20 20 20  ter->aMap ){.   
67e0: 20 73 71 6c 69 74 65 33 4f 73 55 6e 66 65 74 63   sqlite3OsUnfetc
67f0: 68 28 70 49 74 65 72 2d 3e 70 46 69 6c 65 2c 20  h(pIter->pFile, 
6800: 30 2c 20 70 49 74 65 72 2d 3e 61 4d 61 70 29 3b  0, pIter->aMap);
6810: 0a 20 20 20 20 70 49 74 65 72 2d 3e 61 4d 61 70  .    pIter->aMap
6820: 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 70 49 74 65   = 0;.  }.  pIte
6830: 72 2d 3e 69 52 65 61 64 4f 66 66 20 3d 20 69 4f  r->iReadOff = iO
6840: 66 66 3b 0a 20 20 70 49 74 65 72 2d 3e 69 45 6f  ff;.  pIter->iEo
6850: 66 20 3d 20 70 46 69 6c 65 2d 3e 69 45 6f 66 3b  f = pFile->iEof;
6860: 0a 20 20 70 49 74 65 72 2d 3e 70 46 69 6c 65 20  .  pIter->pFile 
6870: 3d 20 70 46 69 6c 65 2d 3e 70 46 64 3b 0a 0a 20  = pFile->pFd;.. 
6880: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
6890: 4d 61 70 46 69 6c 65 28 70 54 61 73 6b 2c 20 70  MapFile(pTask, p
68a0: 46 69 6c 65 2c 20 26 70 49 74 65 72 2d 3e 61 4d  File, &pIter->aM
68b0: 61 70 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  ap);.  if( rc==S
68c0: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 49 74 65  QLITE_OK && pIte
68d0: 72 2d 3e 61 4d 61 70 3d 3d 30 20 29 7b 0a 20 20  r->aMap==0 ){.  
68e0: 20 20 69 6e 74 20 70 67 73 7a 20 3d 20 70 54 61    int pgsz = pTa
68f0: 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 67 73  sk->pSorter->pgs
6900: 7a 3b 0a 20 20 20 20 69 6e 74 20 69 42 75 66 20  z;.    int iBuf 
6910: 3d 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66  = pIter->iReadOf
6920: 66 20 25 20 70 67 73 7a 3b 0a 20 20 20 20 69 66  f % pgsz;.    if
6930: 28 20 70 49 74 65 72 2d 3e 61 42 75 66 66 65 72  ( pIter->aBuffer
6940: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 49 74  ==0 ){.      pIt
6950: 65 72 2d 3e 61 42 75 66 66 65 72 20 3d 20 28 75  er->aBuffer = (u
6960: 38 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  8*)sqlite3Malloc
6970: 28 70 67 73 7a 29 3b 0a 20 20 20 20 20 20 69 66  (pgsz);.      if
6980: 28 20 70 49 74 65 72 2d 3e 61 42 75 66 66 65 72  ( pIter->aBuffer
6990: 3d 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49 54  ==0 ) rc = SQLIT
69a0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 70  E_NOMEM;.      p
69b0: 49 74 65 72 2d 3e 6e 42 75 66 66 65 72 20 3d 20  Iter->nBuffer = 
69c0: 70 67 73 7a 3b 0a 20 20 20 20 7d 0a 20 20 20 20  pgsz;.    }.    
69d0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
69e0: 4b 20 26 26 20 69 42 75 66 20 29 7b 0a 20 20 20  K && iBuf ){.   
69f0: 20 20 20 69 6e 74 20 6e 52 65 61 64 20 3d 20 70     int nRead = p
6a00: 67 73 7a 20 2d 20 69 42 75 66 3b 0a 20 20 20 20  gsz - iBuf;.    
6a10: 20 20 69 66 28 20 28 70 49 74 65 72 2d 3e 69 52    if( (pIter->iR
6a20: 65 61 64 4f 66 66 20 2b 20 6e 52 65 61 64 29 20  eadOff + nRead) 
6a30: 3e 20 70 49 74 65 72 2d 3e 69 45 6f 66 20 29 7b  > pIter->iEof ){
6a40: 0a 20 20 20 20 20 20 20 20 6e 52 65 61 64 20 3d  .        nRead =
6a50: 20 28 69 6e 74 29 28 70 49 74 65 72 2d 3e 69 45   (int)(pIter->iE
6a60: 6f 66 20 2d 20 70 49 74 65 72 2d 3e 69 52 65 61  of - pIter->iRea
6a70: 64 4f 66 66 29 3b 0a 20 20 20 20 20 20 7d 0a 20  dOff);.      }. 
6a80: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
6a90: 33 4f 73 52 65 61 64 28 0a 20 20 20 20 20 20 20  3OsRead(.       
6aa0: 20 20 20 70 49 74 65 72 2d 3e 70 46 69 6c 65 2c     pIter->pFile,
6ab0: 20 26 70 49 74 65 72 2d 3e 61 42 75 66 66 65 72   &pIter->aBuffer
6ac0: 5b 69 42 75 66 5d 2c 20 6e 52 65 61 64 2c 20 70  [iBuf], nRead, p
6ad0: 49 74 65 72 2d 3e 69 52 65 61 64 4f 66 66 0a 20  Iter->iReadOff. 
6ae0: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 61 73       );.      as
6af0: 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45  sert( rc!=SQLITE
6b00: 5f 49 4f 45 52 52 5f 53 48 4f 52 54 5f 52 45 41  _IOERR_SHORT_REA
6b10: 44 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  D );.    }.  }..
6b20: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
6b30: 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 69 74  /*.** Advance it
6b40: 65 72 61 74 6f 72 20 70 49 74 65 72 20 74 6f 20  erator pIter to 
6b50: 74 68 65 20 6e 65 78 74 20 6b 65 79 20 69 6e 20  the next key in 
6b60: 69 74 73 20 50 4d 41 2e 20 52 65 74 75 72 6e 20  its PMA. Return 
6b70: 53 51 4c 49 54 45 5f 4f 4b 20 69 66 0a 2a 2a 20  SQLITE_OK if.** 
6b80: 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c  no error occurs,
6b90: 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72   or an SQLite er
6ba0: 72 6f 72 20 63 6f 64 65 20 69 66 20 6f 6e 65 20  ror code if one 
6bb0: 64 6f 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  does..*/.static 
6bc0: 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61 64 65  int vdbePmaReade
6bd0: 72 4e 65 78 74 28 50 6d 61 52 65 61 64 65 72 20  rNext(PmaReader 
6be0: 2a 70 49 74 65 72 29 7b 0a 20 20 69 6e 74 20 72  *pIter){.  int r
6bf0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20  c = SQLITE_OK;  
6c00: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
6c10: 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 75  turn Code */.  u
6c20: 36 34 20 6e 52 65 63 20 3d 20 30 3b 20 20 20 20  64 nRec = 0;    
6c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6c40: 2a 20 53 69 7a 65 20 6f 66 20 72 65 63 6f 72 64  * Size of record
6c50: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 0a 20 20   in bytes */..  
6c60: 69 66 28 20 70 49 74 65 72 2d 3e 69 52 65 61 64  if( pIter->iRead
6c70: 4f 66 66 3e 3d 70 49 74 65 72 2d 3e 69 45 6f 66  Off>=pIter->iEof
6c80: 20 29 7b 0a 20 20 20 20 49 6e 63 72 4d 65 72 67   ){.    IncrMerg
6c90: 65 72 20 2a 70 49 6e 63 72 20 3d 20 70 49 74 65  er *pIncr = pIte
6ca0: 72 2d 3e 70 49 6e 63 72 3b 0a 20 20 20 20 69 6e  r->pIncr;.    in
6cb0: 74 20 62 45 6f 66 20 3d 20 31 3b 0a 20 20 20 20  t bEof = 1;.    
6cc0: 69 66 28 20 70 49 6e 63 72 20 29 7b 0a 20 20 20  if( pIncr ){.   
6cd0: 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72     rc = vdbeIncr
6ce0: 53 77 61 70 28 70 49 6e 63 72 29 3b 0a 20 20 20  Swap(pIncr);.   
6cf0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
6d00: 45 5f 4f 4b 20 26 26 20 70 49 6e 63 72 2d 3e 62  E_OK && pIncr->b
6d10: 45 6f 66 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  Eof==0 ){.      
6d20: 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65    rc = vdbePmaRe
6d30: 61 64 65 72 53 65 65 6b 28 0a 20 20 20 20 20 20  aderSeek(.      
6d40: 20 20 20 20 20 20 70 49 6e 63 72 2d 3e 70 54 61        pIncr->pTa
6d50: 73 6b 2c 20 70 49 74 65 72 2c 20 26 70 49 6e 63  sk, pIter, &pInc
6d60: 72 2d 3e 61 46 69 6c 65 5b 30 5d 2c 20 70 49 6e  r->aFile[0], pIn
6d70: 63 72 2d 3e 69 53 74 61 72 74 4f 66 66 0a 20 20  cr->iStartOff.  
6d80: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20        );.       
6d90: 20 62 45 6f 66 20 3d 20 30 3b 0a 20 20 20 20 20   bEof = 0;.     
6da0: 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66   }.    }..    if
6db0: 28 20 62 45 6f 66 20 29 7b 0a 20 20 20 20 20 20  ( bEof ){.      
6dc0: 2f 2a 20 54 68 69 73 20 69 73 20 61 6e 20 45 4f  /* This is an EO
6dd0: 46 20 63 6f 6e 64 69 74 69 6f 6e 20 2a 2f 0a 20  F condition */. 
6de0: 20 20 20 20 20 76 64 62 65 50 6d 61 52 65 61 64       vdbePmaRead
6df0: 65 72 43 6c 65 61 72 28 70 49 74 65 72 29 3b 0a  erClear(pIter);.
6e00: 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
6e10: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
6e20: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
6e30: 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65  ){.    rc = vdbe
6e40: 50 6d 61 52 65 61 64 56 61 72 69 6e 74 28 70 49  PmaReadVarint(pI
6e50: 74 65 72 2c 20 26 6e 52 65 63 29 3b 0a 20 20 7d  ter, &nRec);.  }
6e60: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
6e70: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 49 74 65  E_OK ){.    pIte
6e80: 72 2d 3e 6e 4b 65 79 20 3d 20 28 69 6e 74 29 6e  r->nKey = (int)n
6e90: 52 65 63 3b 0a 20 20 20 20 72 63 20 3d 20 76 64  Rec;.    rc = vd
6ea0: 62 65 50 6d 61 52 65 61 64 42 6c 6f 62 28 70 49  bePmaReadBlob(pI
6eb0: 74 65 72 2c 20 28 69 6e 74 29 6e 52 65 63 2c 20  ter, (int)nRec, 
6ec0: 26 70 49 74 65 72 2d 3e 61 4b 65 79 29 3b 0a 20  &pIter->aKey);. 
6ed0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
6ee0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61  .}../*.** Initia
6ef0: 6c 69 7a 65 20 69 74 65 72 61 74 6f 72 20 70 49  lize iterator pI
6f00: 74 65 72 20 74 6f 20 73 63 61 6e 20 74 68 72 6f  ter to scan thro
6f10: 75 67 68 20 74 68 65 20 50 4d 41 20 73 74 6f 72  ugh the PMA stor
6f20: 65 64 20 69 6e 20 66 69 6c 65 20 70 46 69 6c 65  ed in file pFile
6f30: 0a 2a 2a 20 73 74 61 72 74 69 6e 67 20 61 74 20  .** starting at 
6f40: 6f 66 66 73 65 74 20 69 53 74 61 72 74 20 61 6e  offset iStart an
6f50: 64 20 65 6e 64 69 6e 67 20 61 74 20 6f 66 66 73  d ending at offs
6f60: 65 74 20 69 45 6f 66 2d 31 2e 20 54 68 69 73 20  et iEof-1. This 
6f70: 66 75 6e 63 74 69 6f 6e 20 0a 2a 2a 20 6c 65 61  function .** lea
6f80: 76 65 73 20 74 68 65 20 69 74 65 72 61 74 6f 72  ves the iterator
6f90: 20 70 6f 69 6e 74 69 6e 67 20 74 6f 20 74 68 65   pointing to the
6fa0: 20 66 69 72 73 74 20 6b 65 79 20 69 6e 20 74 68   first key in th
6fb0: 65 20 50 4d 41 20 28 6f 72 20 45 4f 46 20 69 66  e PMA (or EOF if
6fc0: 20 74 68 65 20 0a 2a 2a 20 50 4d 41 20 69 73 20   the .** PMA is 
6fd0: 65 6d 70 74 79 29 2e 0a 2a 2a 0a 2a 2a 20 49 66  empty)..**.** If
6fe0: 20 74 68 65 20 70 6e 42 79 74 65 20 70 61 72 61   the pnByte para
6ff0: 6d 65 74 65 72 20 69 73 20 4e 55 4c 4c 2c 20 74  meter is NULL, t
7000: 68 65 6e 20 69 74 20 69 73 20 61 73 73 75 6d 65  hen it is assume
7010: 64 20 74 68 61 74 20 74 68 65 20 66 69 6c 65 20  d that the file 
7020: 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 61 20 73  .** contains a s
7030: 69 6e 67 6c 65 20 50 4d 41 2c 20 61 6e 64 20 74  ingle PMA, and t
7040: 68 61 74 20 74 68 61 74 20 50 4d 41 20 6f 6d 69  hat that PMA omi
7050: 74 73 20 74 68 65 20 69 6e 69 74 69 61 6c 20 6c  ts the initial l
7060: 65 6e 67 74 68 20 76 61 72 69 6e 74 2e 0a 2a 2f  ength varint..*/
7070: 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65  .static int vdbe
7080: 50 6d 61 52 65 61 64 65 72 49 6e 69 74 28 0a 20  PmaReaderInit(. 
7090: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
70a0: 61 73 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20  ask,            
70b0: 20 2f 2a 20 54 61 73 6b 20 63 6f 6e 74 65 78 74   /* Task context
70c0: 20 2a 2f 0a 20 20 53 6f 72 74 65 72 46 69 6c 65   */.  SorterFile
70d0: 20 2a 70 46 69 6c 65 2c 20 20 20 20 20 20 20 20   *pFile,        
70e0: 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20        /* Sorter 
70f0: 66 69 6c 65 20 74 6f 20 72 65 61 64 20 66 72 6f  file to read fro
7100: 6d 20 2a 2f 0a 20 20 69 36 34 20 69 53 74 61 72  m */.  i64 iStar
7110: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
7120: 20 20 20 20 20 20 20 2f 2a 20 53 74 61 72 74 20         /* Start 
7130: 6f 66 66 73 65 74 20 69 6e 20 70 46 69 6c 65 20  offset in pFile 
7140: 2a 2f 0a 20 20 50 6d 61 52 65 61 64 65 72 20 2a  */.  PmaReader *
7150: 70 49 74 65 72 2c 20 20 20 20 20 20 20 20 20 20  pIter,          
7160: 20 20 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72       /* Iterator
7170: 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f 0a   to populate */.
7180: 20 20 69 36 34 20 2a 70 6e 42 79 74 65 20 20 20    i64 *pnByte   
7190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
71a0: 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 49 6e 63    /* IN/OUT: Inc
71b0: 72 65 6d 65 6e 74 20 74 68 69 73 20 76 61 6c 75  rement this valu
71c0: 65 20 62 79 20 50 4d 41 20 73 69 7a 65 20 2a 2f  e by PMA size */
71d0: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20  .){.  int rc;.. 
71e0: 20 61 73 73 65 72 74 28 20 70 46 69 6c 65 2d 3e   assert( pFile->
71f0: 69 45 6f 66 3e 69 53 74 61 72 74 20 29 3b 0a 20  iEof>iStart );. 
7200: 20 61 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e   assert( pIter->
7210: 61 41 6c 6c 6f 63 3d 3d 30 20 26 26 20 70 49 74  aAlloc==0 && pIt
7220: 65 72 2d 3e 6e 41 6c 6c 6f 63 3d 3d 30 20 29 3b  er->nAlloc==0 );
7230: 0a 20 20 61 73 73 65 72 74 28 20 70 49 74 65 72  .  assert( pIter
7240: 2d 3e 61 42 75 66 66 65 72 3d 3d 30 20 29 3b 0a  ->aBuffer==0 );.
7250: 20 20 61 73 73 65 72 74 28 20 70 49 74 65 72 2d    assert( pIter-
7260: 3e 61 4d 61 70 3d 3d 30 20 29 3b 0a 0a 20 20 72  >aMap==0 );..  r
7270: 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65  c = vdbePmaReade
7280: 72 53 65 65 6b 28 70 54 61 73 6b 2c 20 70 49 74  rSeek(pTask, pIt
7290: 65 72 2c 20 70 46 69 6c 65 2c 20 69 53 74 61 72  er, pFile, iStar
72a0: 74 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  t);.  if( rc==SQ
72b0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 75  LITE_OK ){.    u
72c0: 36 34 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20  64 nByte;       
72d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
72e0: 53 69 7a 65 20 6f 66 20 50 4d 41 20 69 6e 20 62  Size of PMA in b
72f0: 79 74 65 73 20 2a 2f 0a 20 20 20 20 72 63 20 3d  ytes */.    rc =
7300: 20 76 64 62 65 50 6d 61 52 65 61 64 56 61 72 69   vdbePmaReadVari
7310: 6e 74 28 70 49 74 65 72 2c 20 26 6e 42 79 74 65  nt(pIter, &nByte
7320: 29 3b 0a 20 20 20 20 70 49 74 65 72 2d 3e 69 45  );.    pIter->iE
7330: 6f 66 20 3d 20 70 49 74 65 72 2d 3e 69 52 65 61  of = pIter->iRea
7340: 64 4f 66 66 20 2b 20 6e 42 79 74 65 3b 0a 20 20  dOff + nByte;.  
7350: 20 20 2a 70 6e 42 79 74 65 20 2b 3d 20 6e 42 79    *pnByte += nBy
7360: 74 65 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72  te;.  }..  if( r
7370: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
7380: 20 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61      rc = vdbePma
7390: 52 65 61 64 65 72 4e 65 78 74 28 70 49 74 65 72  ReaderNext(pIter
73a0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
73b0: 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6f  rc;.}.../*.** Co
73c0: 6d 70 61 72 65 20 6b 65 79 31 20 28 62 75 66 66  mpare key1 (buff
73d0: 65 72 20 70 4b 65 79 31 2c 20 73 69 7a 65 20 6e  er pKey1, size n
73e0: 4b 65 79 31 20 62 79 74 65 73 29 20 77 69 74 68  Key1 bytes) with
73f0: 20 6b 65 79 32 20 28 62 75 66 66 65 72 20 70 4b   key2 (buffer pK
7400: 65 79 32 2c 20 0a 2a 2a 20 73 69 7a 65 20 6e 4b  ey2, .** size nK
7410: 65 79 32 20 62 79 74 65 73 29 2e 20 55 73 65 20  ey2 bytes). Use 
7420: 28 70 54 61 73 6b 2d 3e 70 4b 65 79 49 6e 66 6f  (pTask->pKeyInfo
7430: 29 20 66 6f 72 20 74 68 65 20 63 6f 6c 6c 61 74  ) for the collat
7440: 69 6f 6e 20 73 65 71 75 65 6e 63 65 73 0a 2a 2a  ion sequences.**
7450: 20 75 73 65 64 20 62 79 20 74 68 65 20 63 6f 6d   used by the com
7460: 70 61 72 69 73 6f 6e 2e 20 52 65 74 75 72 6e 20  parison. Return 
7470: 74 68 65 20 72 65 73 75 6c 74 20 6f 66 20 74 68  the result of th
7480: 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2e 0a 2a 2a  e comparison..**
7490: 0a 2a 2a 20 42 65 66 6f 72 65 20 72 65 74 75 72  .** Before retur
74a0: 6e 69 6e 67 2c 20 6f 62 6a 65 63 74 20 28 70 54  ning, object (pT
74b0: 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 29 20  ask->pUnpacked) 
74c0: 69 73 20 70 6f 70 75 6c 61 74 65 64 20 77 69 74  is populated wit
74d0: 68 20 74 68 65 0a 2a 2a 20 75 6e 70 61 63 6b 65  h the.** unpacke
74e0: 64 20 76 65 72 73 69 6f 6e 20 6f 66 20 6b 65 79  d version of key
74f0: 32 2e 20 4f 72 2c 20 69 66 20 70 4b 65 79 32 20  2. Or, if pKey2 
7500: 69 73 20 70 61 73 73 65 64 20 61 20 4e 55 4c 4c  is passed a NULL
7510: 20 70 6f 69 6e 74 65 72 2c 20 74 68 65 6e 20 69   pointer, then i
7520: 74 20 0a 2a 2a 20 69 73 20 61 73 73 75 6d 65 64  t .** is assumed
7530: 20 74 68 61 74 20 74 68 65 20 28 70 54 61 73 6b   that the (pTask
7540: 2d 3e 70 55 6e 70 61 63 6b 65 64 29 20 73 74 72  ->pUnpacked) str
7550: 75 63 74 75 72 65 20 61 6c 72 65 61 64 79 20 63  ucture already c
7560: 6f 6e 74 61 69 6e 73 20 74 68 65 20 0a 2a 2a 20  ontains the .** 
7570: 75 6e 70 61 63 6b 65 64 20 6b 65 79 20 74 6f 20  unpacked key to 
7580: 75 73 65 20 61 73 20 6b 65 79 32 2e 0a 2a 2a 0a  use as key2..**.
7590: 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 65 72 72  ** If an OOM err
75a0: 6f 72 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65  or is encountere
75b0: 64 2c 20 28 70 54 61 73 6b 2d 3e 70 55 6e 70 61  d, (pTask->pUnpa
75c0: 63 6b 65 64 2d 3e 65 72 72 6f 72 5f 72 63 29 20  cked->error_rc) 
75d0: 69 73 20 73 65 74 0a 2a 2a 20 74 6f 20 53 51 4c  is set.** to SQL
75e0: 49 54 45 5f 4e 4f 4d 45 4d 2e 0a 2a 2f 0a 73 74  ITE_NOMEM..*/.st
75f0: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
7600: 74 65 72 43 6f 6d 70 61 72 65 28 0a 20 20 53 6f  terCompare(.  So
7610: 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b  rtSubtask *pTask
7620: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
7630: 20 53 75 62 74 61 73 6b 20 63 6f 6e 74 65 78 74   Subtask context
7640: 20 28 66 6f 72 20 70 4b 65 79 49 6e 66 6f 29 20   (for pKeyInfo) 
7650: 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20  */.  const void 
7660: 2a 70 4b 65 79 31 2c 20 69 6e 74 20 6e 4b 65 79  *pKey1, int nKey
7670: 31 2c 20 20 20 2f 2a 20 4c 65 66 74 20 73 69 64  1,   /* Left sid
7680: 65 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20  e of comparison 
7690: 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20  */.  const void 
76a0: 2a 70 4b 65 79 32 2c 20 69 6e 74 20 6e 4b 65 79  *pKey2, int nKey
76b0: 32 20 20 20 20 2f 2a 20 52 69 67 68 74 20 73 69  2    /* Right si
76c0: 64 65 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e  de of comparison
76d0: 20 2a 2f 0a 29 7b 0a 20 20 55 6e 70 61 63 6b 65   */.){.  Unpacke
76e0: 64 52 65 63 6f 72 64 20 2a 72 32 20 3d 20 70 54  dRecord *r2 = pT
76f0: 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 3b 0a  ask->pUnpacked;.
7700: 20 20 69 66 28 20 70 4b 65 79 32 20 29 7b 0a 20    if( pKey2 ){. 
7710: 20 20 20 73 71 6c 69 74 65 33 56 64 62 65 52 65     sqlite3VdbeRe
7720: 63 6f 72 64 55 6e 70 61 63 6b 28 70 54 61 73 6b  cordUnpack(pTask
7730: 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49  ->pSorter->pKeyI
7740: 6e 66 6f 2c 20 6e 4b 65 79 32 2c 20 70 4b 65 79  nfo, nKey2, pKey
7750: 32 2c 20 72 32 29 3b 0a 20 20 7d 0a 20 20 72 65  2, r2);.  }.  re
7760: 74 75 72 6e 20 73 71 6c 69 74 65 33 56 64 62 65  turn sqlite3Vdbe
7770: 52 65 63 6f 72 64 43 6f 6d 70 61 72 65 28 6e 4b  RecordCompare(nK
7780: 65 79 31 2c 20 70 4b 65 79 31 2c 20 72 32 2c 20  ey1, pKey1, r2, 
7790: 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  0);.}../*.** Thi
77a0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
77b0: 6c 6c 65 64 20 74 6f 20 63 6f 6d 70 61 72 65 20  lled to compare 
77c0: 74 77 6f 20 69 74 65 72 61 74 6f 72 20 6b 65 79  two iterator key
77d0: 73 20 77 68 65 6e 20 6d 65 72 67 69 6e 67 20 0a  s when merging .
77e0: 2a 2a 20 6d 75 6c 74 69 70 6c 65 20 62 2d 74 72  ** multiple b-tr
77f0: 65 65 20 73 65 67 6d 65 6e 74 73 2e 20 50 61 72  ee segments. Par
7800: 61 6d 65 74 65 72 20 69 4f 75 74 20 69 73 20 74  ameter iOut is t
7810: 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20  he index of the 
7820: 61 54 72 65 65 5b 5d 20 0a 2a 2a 20 76 61 6c 75  aTree[] .** valu
7830: 65 20 74 6f 20 72 65 63 61 6c 63 75 6c 61 74 65  e to recalculate
7840: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
7850: 76 64 62 65 53 6f 72 74 65 72 44 6f 43 6f 6d 70  vdbeSorterDoComp
7860: 61 72 65 28 0a 20 20 53 6f 72 74 53 75 62 74 61  are(.  SortSubta
7870: 73 6b 20 2a 70 54 61 73 6b 2c 20 0a 20 20 4d 65  sk *pTask, .  Me
7880: 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67  rgeEngine *pMerg
7890: 65 72 2c 20 0a 20 20 69 6e 74 20 69 4f 75 74 0a  er, .  int iOut.
78a0: 29 7b 0a 20 20 69 6e 74 20 69 31 3b 0a 20 20 69  ){.  int i1;.  i
78b0: 6e 74 20 69 32 3b 0a 20 20 69 6e 74 20 69 52 65  nt i2;.  int iRe
78c0: 73 3b 0a 20 20 50 6d 61 52 65 61 64 65 72 20 2a  s;.  PmaReader *
78d0: 70 31 3b 0a 20 20 50 6d 61 52 65 61 64 65 72 20  p1;.  PmaReader 
78e0: 2a 70 32 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  *p2;..  assert( 
78f0: 69 4f 75 74 3c 70 4d 65 72 67 65 72 2d 3e 6e 54  iOut<pMerger->nT
7900: 72 65 65 20 26 26 20 69 4f 75 74 3e 30 20 29 3b  ree && iOut>0 );
7910: 0a 0a 20 20 69 66 28 20 69 4f 75 74 3e 3d 28 70  ..  if( iOut>=(p
7920: 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65 2f 32 29  Merger->nTree/2)
7930: 20 29 7b 0a 20 20 20 20 69 31 20 3d 20 28 69 4f   ){.    i1 = (iO
7940: 75 74 20 2d 20 70 4d 65 72 67 65 72 2d 3e 6e 54  ut - pMerger->nT
7950: 72 65 65 2f 32 29 20 2a 20 32 3b 0a 20 20 20 20  ree/2) * 2;.    
7960: 69 32 20 3d 20 69 31 20 2b 20 31 3b 0a 20 20 7d  i2 = i1 + 1;.  }
7970: 65 6c 73 65 7b 0a 20 20 20 20 69 31 20 3d 20 70  else{.    i1 = p
7980: 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 4f  Merger->aTree[iO
7990: 75 74 2a 32 5d 3b 0a 20 20 20 20 69 32 20 3d 20  ut*2];.    i2 = 
79a0: 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69  pMerger->aTree[i
79b0: 4f 75 74 2a 32 2b 31 5d 3b 0a 20 20 7d 0a 0a 20  Out*2+1];.  }.. 
79c0: 20 70 31 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e   p1 = &pMerger->
79d0: 61 49 74 65 72 5b 69 31 5d 3b 0a 20 20 70 32 20  aIter[i1];.  p2 
79e0: 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65  = &pMerger->aIte
79f0: 72 5b 69 32 5d 3b 0a 0a 20 20 69 66 28 20 70 31  r[i2];..  if( p1
7a00: 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20  ->pFile==0 ){.  
7a10: 20 20 69 52 65 73 20 3d 20 69 32 3b 0a 20 20 7d    iRes = i2;.  }
7a20: 65 6c 73 65 20 69 66 28 20 70 32 2d 3e 70 46 69  else if( p2->pFi
7a30: 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69 52 65  le==0 ){.    iRe
7a40: 73 20 3d 20 69 31 3b 0a 20 20 7d 65 6c 73 65 7b  s = i1;.  }else{
7a50: 0a 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 20 20  .    int res;.  
7a60: 20 20 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d    assert( pTask-
7a70: 3e 70 55 6e 70 61 63 6b 65 64 21 3d 30 20 29 3b  >pUnpacked!=0 );
7a80: 20 20 2f 2a 20 61 6c 6c 6f 63 61 74 65 64 20 69    /* allocated i
7a90: 6e 20 76 64 62 65 53 6f 72 74 53 75 62 74 61 73  n vdbeSortSubtas
7aa0: 6b 4d 61 69 6e 28 29 20 2a 2f 0a 20 20 20 20 72  kMain() */.    r
7ab0: 65 73 20 3d 20 76 64 62 65 53 6f 72 74 65 72 43  es = vdbeSorterC
7ac0: 6f 6d 70 61 72 65 28 0a 20 20 20 20 20 20 20 20  ompare(.        
7ad0: 70 54 61 73 6b 2c 20 70 31 2d 3e 61 4b 65 79 2c  pTask, p1->aKey,
7ae0: 20 70 31 2d 3e 6e 4b 65 79 2c 20 70 32 2d 3e 61   p1->nKey, p2->a
7af0: 4b 65 79 2c 20 70 32 2d 3e 6e 4b 65 79 0a 20 20  Key, p2->nKey.  
7b00: 20 20 29 3b 0a 20 20 20 20 69 66 28 20 72 65 73    );.    if( res
7b10: 3c 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 52 65  <=0 ){.      iRe
7b20: 73 20 3d 20 69 31 3b 0a 20 20 20 20 7d 65 6c 73  s = i1;.    }els
7b30: 65 7b 0a 20 20 20 20 20 20 69 52 65 73 20 3d 20  e{.      iRes = 
7b40: 69 32 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  i2;.    }.  }.. 
7b50: 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b   pMerger->aTree[
7b60: 69 4f 75 74 5d 20 3d 20 69 52 65 73 3b 0a 20 20  iOut] = iRes;.  
7b70: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
7b80: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69  ;.}../*.** Initi
7b90: 61 6c 69 7a 65 20 74 68 65 20 74 65 6d 70 6f 72  alize the tempor
7ba0: 61 72 79 20 69 6e 64 65 78 20 63 75 72 73 6f 72  ary index cursor
7bb0: 20 6a 75 73 74 20 6f 70 65 6e 65 64 20 61 73 20   just opened as 
7bc0: 61 20 73 6f 72 74 65 72 20 63 75 72 73 6f 72 2e  a sorter cursor.
7bd0: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56  .*/.int sqlite3V
7be0: 64 62 65 53 6f 72 74 65 72 49 6e 69 74 28 0a 20  dbeSorterInit(. 
7bf0: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20   sqlite3 *db,   
7c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7c10: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 63 6f 6e   /* Database con
7c20: 6e 65 63 74 69 6f 6e 20 28 66 6f 72 20 6d 61 6c  nection (for mal
7c30: 6c 6f 63 28 29 29 20 2a 2f 0a 20 20 69 6e 74 20  loc()) */.  int 
7c40: 6e 46 69 65 6c 64 2c 20 20 20 20 20 20 20 20 20  nField,         
7c50: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
7c60: 75 6d 62 65 72 20 6f 66 20 6b 65 79 20 66 69 65  umber of key fie
7c70: 6c 64 73 20 69 6e 20 65 61 63 68 20 72 65 63 6f  lds in each reco
7c80: 72 64 20 2a 2f 0a 20 20 56 64 62 65 43 75 72 73  rd */.  VdbeCurs
7c90: 6f 72 20 2a 70 43 73 72 20 20 20 20 20 20 20 20  or *pCsr        
7ca0: 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 73 6f          /* Curso
7cb0: 72 20 74 68 61 74 20 68 6f 6c 64 73 20 74 68 65  r that holds the
7cc0: 20 6e 65 77 20 73 6f 72 74 65 72 20 2a 2f 0a 29   new sorter */.)
7cd0: 7b 0a 20 20 69 6e 74 20 70 67 73 7a 3b 20 20 20  {.  int pgsz;   
7ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7cf0: 20 20 20 20 2f 2a 20 50 61 67 65 20 73 69 7a 65      /* Page size
7d00: 20 6f 66 20 6d 61 69 6e 20 64 61 74 61 62 61 73   of main databas
7d10: 65 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20  e */.  int i;   
7d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7d30: 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74         /* Used t
7d40: 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67  o iterate throug
7d50: 68 20 61 54 61 73 6b 5b 5d 20 2a 2f 0a 20 20 69  h aTask[] */.  i
7d60: 6e 74 20 6d 78 43 61 63 68 65 3b 20 20 20 20 20  nt mxCache;     
7d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7d80: 2a 20 43 61 63 68 65 20 73 69 7a 65 20 2a 2f 0a  * Cache size */.
7d90: 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
7da0: 6f 72 74 65 72 3b 20 20 20 20 20 20 20 20 20 20  orter;          
7db0: 20 20 2f 2a 20 54 68 65 20 6e 65 77 20 73 6f 72    /* The new sor
7dc0: 74 65 72 20 2a 2f 0a 20 20 4b 65 79 49 6e 66 6f  ter */.  KeyInfo
7dd0: 20 2a 70 4b 65 79 49 6e 66 6f 3b 20 20 20 20 20   *pKeyInfo;     
7de0: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 70 79           /* Copy
7df0: 20 6f 66 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e   of pCsr->pKeyIn
7e00: 66 6f 20 77 69 74 68 20 64 62 3d 3d 30 20 2a 2f  fo with db==0 */
7e10: 0a 20 20 69 6e 74 20 73 7a 4b 65 79 49 6e 66 6f  .  int szKeyInfo
7e20: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
7e30: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 70 43     /* Size of pC
7e40: 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 20 69 6e 20  sr->pKeyInfo in 
7e50: 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20 73  bytes */.  int s
7e60: 7a 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  z;              
7e70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
7e80: 7a 65 20 6f 66 20 70 53 6f 72 74 65 72 20 69 6e  ze of pSorter in
7e90: 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20   bytes */.  int 
7ea0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
7eb0: 20 20 69 6e 74 20 6e 57 6f 72 6b 65 72 20 3d 20    int nWorker = 
7ec0: 28 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f  (sqlite3GlobalCo
7ed0: 6e 66 69 67 2e 62 43 6f 72 65 4d 75 74 65 78 3f  nfig.bCoreMutex?
7ee0: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
7ef0: 66 69 67 2e 6e 57 6f 72 6b 65 72 3a 30 29 3b 0a  fig.nWorker:0);.
7f00: 0a 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d  .  assert( pCsr-
7f10: 3e 70 4b 65 79 49 6e 66 6f 20 26 26 20 70 43 73  >pKeyInfo && pCs
7f20: 72 2d 3e 70 42 74 3d 3d 30 20 29 3b 0a 20 20 73  r->pBt==0 );.  s
7f30: 7a 4b 65 79 49 6e 66 6f 20 3d 20 73 69 7a 65 6f  zKeyInfo = sizeo
7f40: 66 28 4b 65 79 49 6e 66 6f 29 20 2b 20 28 70 43  f(KeyInfo) + (pC
7f50: 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46  sr->pKeyInfo->nF
7f60: 69 65 6c 64 2d 31 29 2a 73 69 7a 65 6f 66 28 43  ield-1)*sizeof(C
7f70: 6f 6c 6c 53 65 71 2a 29 3b 0a 20 20 73 7a 20 3d  ollSeq*);.  sz =
7f80: 20 73 69 7a 65 6f 66 28 56 64 62 65 53 6f 72 74   sizeof(VdbeSort
7f90: 65 72 29 20 2b 20 6e 57 6f 72 6b 65 72 20 2a 20  er) + nWorker * 
7fa0: 73 69 7a 65 6f 66 28 53 6f 72 74 53 75 62 74 61  sizeof(SortSubta
7fb0: 73 6b 29 3b 0a 0a 20 20 70 53 6f 72 74 65 72 20  sk);..  pSorter 
7fc0: 3d 20 28 56 64 62 65 53 6f 72 74 65 72 2a 29 73  = (VdbeSorter*)s
7fd0: 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f 63 5a 65  qlite3DbMallocZe
7fe0: 72 6f 28 64 62 2c 20 73 7a 20 2b 20 73 7a 4b 65  ro(db, sz + szKe
7ff0: 79 49 6e 66 6f 29 3b 0a 20 20 70 43 73 72 2d 3e  yInfo);.  pCsr->
8000: 70 53 6f 72 74 65 72 20 3d 20 70 53 6f 72 74 65  pSorter = pSorte
8010: 72 3b 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72  r;.  if( pSorter
8020: 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  ==0 ){.    rc = 
8030: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
8040: 7d 65 6c 73 65 7b 0a 20 20 20 20 70 53 6f 72 74  }else{.    pSort
8050: 65 72 2d 3e 70 4b 65 79 49 6e 66 6f 20 3d 20 70  er->pKeyInfo = p
8060: 4b 65 79 49 6e 66 6f 20 3d 20 28 4b 65 79 49 6e  KeyInfo = (KeyIn
8070: 66 6f 2a 29 28 28 75 38 2a 29 70 53 6f 72 74 65  fo*)((u8*)pSorte
8080: 72 20 2b 20 73 7a 29 3b 0a 20 20 20 20 6d 65 6d  r + sz);.    mem
8090: 63 70 79 28 70 4b 65 79 49 6e 66 6f 2c 20 70 43  cpy(pKeyInfo, pC
80a0: 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20 73 7a  sr->pKeyInfo, sz
80b0: 4b 65 79 49 6e 66 6f 29 3b 0a 20 20 20 20 70 4b  KeyInfo);.    pK
80c0: 65 79 49 6e 66 6f 2d 3e 64 62 20 3d 20 30 3b 0a  eyInfo->db = 0;.
80d0: 20 20 20 20 69 66 28 20 6e 46 69 65 6c 64 20 26      if( nField &
80e0: 26 20 6e 57 6f 72 6b 65 72 3d 3d 30 20 29 20 70  & nWorker==0 ) p
80f0: 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64 20  KeyInfo->nField 
8100: 3d 20 6e 46 69 65 6c 64 3b 0a 20 20 20 20 70 53  = nField;.    pS
8110: 6f 72 74 65 72 2d 3e 70 67 73 7a 20 3d 20 70 67  orter->pgsz = pg
8120: 73 7a 20 3d 20 73 71 6c 69 74 65 33 42 74 72 65  sz = sqlite3Btre
8130: 65 47 65 74 50 61 67 65 53 69 7a 65 28 64 62 2d  eGetPageSize(db-
8140: 3e 61 44 62 5b 30 5d 2e 70 42 74 29 3b 0a 20 20  >aDb[0].pBt);.  
8150: 20 20 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b    pSorter->nTask
8160: 20 3d 20 6e 57 6f 72 6b 65 72 20 2b 20 31 3b 0a   = nWorker + 1;.
8170: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 62 55 73      pSorter->bUs
8180: 65 54 68 72 65 61 64 73 20 3d 20 28 70 53 6f 72  eThreads = (pSor
8190: 74 65 72 2d 3e 6e 54 61 73 6b 3e 31 29 3b 0a 20  ter->nTask>1);. 
81a0: 20 20 20 70 53 6f 72 74 65 72 2d 3e 64 62 20 3d     pSorter->db =
81b0: 20 64 62 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30   db;.    for(i=0
81c0: 3b 20 69 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 61  ; i<pSorter->nTa
81d0: 73 6b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  sk; i++){.      
81e0: 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61  SortSubtask *pTa
81f0: 73 6b 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61  sk = &pSorter->a
8200: 54 61 73 6b 5b 69 5d 3b 0a 20 20 20 20 20 20 70  Task[i];.      p
8210: 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 20 3d 20  Task->pSorter = 
8220: 70 53 6f 72 74 65 72 3b 0a 20 20 20 20 7d 0a 0a  pSorter;.    }..
8230: 20 20 20 20 69 66 28 20 21 73 71 6c 69 74 65 33      if( !sqlite3
8240: 54 65 6d 70 49 6e 4d 65 6d 6f 72 79 28 64 62 29  TempInMemory(db)
8250: 20 29 7b 0a 20 20 20 20 20 20 70 53 6f 72 74 65   ){.      pSorte
8260: 72 2d 3e 6d 6e 50 6d 61 53 69 7a 65 20 3d 20 53  r->mnPmaSize = S
8270: 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e  ORTER_MIN_WORKIN
8280: 47 20 2a 20 70 67 73 7a 3b 0a 20 20 20 20 20 20  G * pgsz;.      
8290: 6d 78 43 61 63 68 65 20 3d 20 64 62 2d 3e 61 44  mxCache = db->aD
82a0: 62 5b 30 5d 2e 70 53 63 68 65 6d 61 2d 3e 63 61  b[0].pSchema->ca
82b0: 63 68 65 5f 73 69 7a 65 3b 0a 20 20 20 20 20 20  che_size;.      
82c0: 69 66 28 20 6d 78 43 61 63 68 65 3c 53 4f 52 54  if( mxCache<SORT
82d0: 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20 29  ER_MIN_WORKING )
82e0: 20 6d 78 43 61 63 68 65 20 3d 20 53 4f 52 54 45   mxCache = SORTE
82f0: 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 3b 0a 20  R_MIN_WORKING;. 
8300: 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6d 78       pSorter->mx
8310: 50 6d 61 53 69 7a 65 20 3d 20 6d 78 43 61 63 68  PmaSize = mxCach
8320: 65 20 2a 20 70 67 73 7a 3b 0a 0a 20 20 20 20 20  e * pgsz;..     
8330: 20 2f 2a 20 49 66 20 74 68 65 20 61 70 70 6c 69   /* If the appli
8340: 63 61 74 69 6f 6e 20 69 73 20 75 73 69 6e 67 20  cation is using 
8350: 6d 65 6d 73 79 73 33 20 6f 72 20 6d 65 6d 73 79  memsys3 or memsy
8360: 73 35 2c 20 75 73 65 20 61 20 73 65 70 61 72 61  s5, use a separa
8370: 74 65 20 0a 20 20 20 20 20 20 2a 2a 20 61 6c 6c  te .      ** all
8380: 6f 63 61 74 69 6f 6e 20 66 6f 72 20 65 61 63 68  ocation for each
8390: 20 73 6f 72 74 2d 6b 65 79 20 69 6e 20 6d 65 6d   sort-key in mem
83a0: 6f 72 79 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  ory. Otherwise, 
83b0: 75 73 65 20 61 20 73 69 6e 67 6c 65 20 62 69 67  use a single big
83c0: 0a 20 20 20 20 20 20 2a 2a 20 61 6c 6c 6f 63 61  .      ** alloca
83d0: 74 69 6f 6e 20 61 74 20 70 53 6f 72 74 65 72 2d  tion at pSorter-
83e0: 3e 61 4d 65 6d 6f 72 79 20 66 6f 72 20 61 6c 6c  >aMemory for all
83f0: 20 73 6f 72 74 2d 6b 65 79 73 2e 20 20 2a 2f 0a   sort-keys.  */.
8400: 20 20 20 20 20 20 69 66 28 20 73 71 6c 69 74 65        if( sqlite
8410: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 48  3GlobalConfig.pH
8420: 65 61 70 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  eap==0 ){.      
8430: 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65    assert( pSorte
8440: 72 2d 3e 69 4d 65 6d 6f 72 79 3d 3d 30 20 29 3b  r->iMemory==0 );
8450: 0a 20 20 20 20 20 20 20 20 70 53 6f 72 74 65 72  .        pSorter
8460: 2d 3e 6e 4d 65 6d 6f 72 79 20 3d 20 70 67 73 7a  ->nMemory = pgsz
8470: 3b 0a 20 20 20 20 20 20 20 20 70 53 6f 72 74 65  ;.        pSorte
8480: 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20  r->list.aMemory 
8490: 3d 20 28 75 38 2a 29 73 71 6c 69 74 65 33 4d 61  = (u8*)sqlite3Ma
84a0: 6c 6c 6f 63 28 70 67 73 7a 29 3b 0a 20 20 20 20  lloc(pgsz);.    
84b0: 20 20 20 20 69 66 28 20 21 70 53 6f 72 74 65 72      if( !pSorter
84c0: 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 29  ->list.aMemory )
84d0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
84e0: 45 4d 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  EM;.      }.    
84f0: 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  }.  }..  return 
8500: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65  rc;.}../*.** Fre
8510: 65 20 74 68 65 20 6c 69 73 74 20 6f 66 20 73 6f  e the list of so
8520: 72 74 65 64 20 72 65 63 6f 72 64 73 20 73 74 61  rted records sta
8530: 72 74 69 6e 67 20 61 74 20 70 52 65 63 6f 72 64  rting at pRecord
8540: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
8550: 20 76 64 62 65 53 6f 72 74 65 72 52 65 63 6f 72   vdbeSorterRecor
8560: 64 46 72 65 65 28 73 71 6c 69 74 65 33 20 2a 64  dFree(sqlite3 *d
8570: 62 2c 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20  b, SorterRecord 
8580: 2a 70 52 65 63 6f 72 64 29 7b 0a 20 20 53 6f 72  *pRecord){.  Sor
8590: 74 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a 20 20  terRecord *p;.  
85a0: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e  SorterRecord *pN
85b0: 65 78 74 3b 0a 20 20 66 6f 72 28 70 3d 70 52 65  ext;.  for(p=pRe
85c0: 63 6f 72 64 3b 20 70 3b 20 70 3d 70 4e 65 78 74  cord; p; p=pNext
85d0: 29 7b 0a 20 20 20 20 70 4e 65 78 74 20 3d 20 70  ){.    pNext = p
85e0: 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20 20 20 20 73  ->u.pNext;.    s
85f0: 71 6c 69 74 65 33 44 62 46 72 65 65 28 64 62 2c  qlite3DbFree(db,
8600: 20 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a   p);.  }.}../*.*
8610: 2a 20 46 72 65 65 20 61 6c 6c 20 72 65 73 6f 75  * Free all resou
8620: 72 63 65 73 20 6f 77 6e 65 64 20 62 79 20 74 68  rces owned by th
8630: 65 20 6f 62 6a 65 63 74 20 69 6e 64 69 63 61 74  e object indicat
8640: 65 64 20 62 79 20 61 72 67 75 6d 65 6e 74 20 70  ed by argument p
8650: 54 61 73 6b 2e 20 41 6c 6c 20 0a 2a 2a 20 66 69  Task. All .** fi
8660: 65 6c 64 73 20 6f 66 20 2a 70 54 61 73 6b 20 61  elds of *pTask a
8670: 72 65 20 7a 65 72 6f 65 64 20 62 65 66 6f 72 65  re zeroed before
8680: 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73   returning..*/.s
8690: 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 53  tatic void vdbeS
86a0: 6f 72 74 53 75 62 74 61 73 6b 43 6c 65 61 6e 75  ortSubtaskCleanu
86b0: 70 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 53  p(sqlite3 *db, S
86c0: 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
86d0: 6b 29 7b 0a 20 20 73 71 6c 69 74 65 33 44 62 46  k){.  sqlite3DbF
86e0: 72 65 65 28 64 62 2c 20 70 54 61 73 6b 2d 3e 70  ree(db, pTask->p
86f0: 55 6e 70 61 63 6b 65 64 29 3b 0a 20 20 70 54 61  Unpacked);.  pTa
8700: 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 20 3d 20  sk->pUnpacked = 
8710: 30 3b 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e  0;.  if( pTask->
8720: 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30 20  list.aMemory==0 
8730: 29 7b 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65  ){.    vdbeSorte
8740: 72 52 65 63 6f 72 64 46 72 65 65 28 30 2c 20 70  rRecordFree(0, p
8750: 54 61 73 6b 2d 3e 6c 69 73 74 2e 70 4c 69 73 74  Task->list.pList
8760: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
8770: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 54 61  sqlite3_free(pTa
8780: 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  sk->list.aMemory
8790: 29 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 6c 69  );.    pTask->li
87a0: 73 74 2e 61 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a  st.aMemory = 0;.
87b0: 20 20 7d 0a 20 20 70 54 61 73 6b 2d 3e 6c 69 73    }.  pTask->lis
87c0: 74 2e 70 4c 69 73 74 20 3d 20 30 3b 0a 20 20 69  t.pList = 0;.  i
87d0: 66 28 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70  f( pTask->file.p
87e0: 46 64 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  Fd ){.    sqlite
87f0: 33 4f 73 43 6c 6f 73 65 46 72 65 65 28 70 54 61  3OsCloseFree(pTa
8800: 73 6b 2d 3e 66 69 6c 65 2e 70 46 64 29 3b 0a 20  sk->file.pFd);. 
8810: 20 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70     pTask->file.p
8820: 46 64 20 3d 20 30 3b 0a 20 20 20 20 70 54 61 73  Fd = 0;.    pTas
8830: 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 20 3d 20 30  k->file.iEof = 0
8840: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 54 61 73  ;.  }.  if( pTas
8850: 6b 2d 3e 66 69 6c 65 32 2e 70 46 64 20 29 7b 0a  k->file2.pFd ){.
8860: 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43 6c 6f      sqlite3OsClo
8870: 73 65 46 72 65 65 28 70 54 61 73 6b 2d 3e 66 69  seFree(pTask->fi
8880: 6c 65 32 2e 70 46 64 29 3b 0a 20 20 20 20 70 54  le2.pFd);.    pT
8890: 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64 20 3d  ask->file2.pFd =
88a0: 20 30 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 66   0;.    pTask->f
88b0: 69 6c 65 32 2e 69 45 6f 66 20 3d 20 30 3b 0a 20  ile2.iEof = 0;. 
88c0: 20 7d 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c   }.}..#ifdef SQL
88d0: 49 54 45 5f 44 45 42 55 47 5f 53 4f 52 54 45 52  ITE_DEBUG_SORTER
88e0: 5f 54 48 52 45 41 44 53 0a 73 74 61 74 69 63 20  _THREADS.static 
88f0: 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72 57  void vdbeSorterW
8900: 6f 72 6b 44 65 62 75 67 28 53 6f 72 74 53 75 62  orkDebug(SortSub
8910: 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 63 6f 6e  task *pTask, con
8920: 73 74 20 63 68 61 72 20 2a 7a 45 76 65 6e 74 29  st char *zEvent)
8930: 7b 0a 20 20 69 36 34 20 74 3b 0a 20 20 69 6e 74  {.  i64 t;.  int
8940: 20 69 54 61 73 6b 20 3d 20 28 70 54 61 73 6b 20   iTask = (pTask 
8950: 2d 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72  - pTask->pSorter
8960: 2d 3e 61 54 61 73 6b 29 3b 0a 20 20 73 71 6c 69  ->aTask);.  sqli
8970: 74 65 33 4f 73 43 75 72 72 65 6e 74 54 69 6d 65  te3OsCurrentTime
8980: 49 6e 74 36 34 28 70 54 61 73 6b 2d 3e 64 62 2d  Int64(pTask->db-
8990: 3e 70 56 66 73 2c 20 26 74 29 3b 0a 20 20 66 70  >pVfs, &t);.  fp
89a0: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25  rintf(stderr, "%
89b0: 6c 6c 64 3a 25 64 20 25 73 5c 6e 22 2c 20 74 2c  lld:%d %s\n", t,
89c0: 20 69 54 61 73 6b 2c 20 7a 45 76 65 6e 74 29 3b   iTask, zEvent);
89d0: 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76  .}.static void v
89e0: 64 62 65 53 6f 72 74 65 72 52 65 77 69 6e 64 44  dbeSorterRewindD
89f0: 65 62 75 67 28 73 71 6c 69 74 65 33 20 2a 64 62  ebug(sqlite3 *db
8a00: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45  , const char *zE
8a10: 76 65 6e 74 29 7b 0a 20 20 69 36 34 20 74 3b 0a  vent){.  i64 t;.
8a20: 20 20 73 71 6c 69 74 65 33 4f 73 43 75 72 72 65    sqlite3OsCurre
8a30: 6e 74 54 69 6d 65 49 6e 74 36 34 28 64 62 2d 3e  ntTimeInt64(db->
8a40: 70 56 66 73 2c 20 26 74 29 3b 0a 20 20 66 70 72  pVfs, &t);.  fpr
8a50: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25 6c  intf(stderr, "%l
8a60: 6c 64 3a 58 20 25 73 5c 6e 22 2c 20 74 2c 20 7a  ld:X %s\n", t, z
8a70: 45 76 65 6e 74 29 3b 0a 7d 0a 73 74 61 74 69 63  Event);.}.static
8a80: 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72   void vdbeSorter
8a90: 50 6f 70 75 6c 61 74 65 44 65 62 75 67 28 0a 20  PopulateDebug(. 
8aa0: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
8ab0: 61 73 6b 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61  ask,.  const cha
8ac0: 72 20 2a 7a 45 76 65 6e 74 0a 29 7b 0a 20 20 69  r *zEvent.){.  i
8ad0: 36 34 20 74 3b 0a 20 20 69 6e 74 20 69 54 61 73  64 t;.  int iTas
8ae0: 6b 20 3d 20 28 70 54 61 73 6b 20 2d 20 70 54 61  k = (pTask - pTa
8af0: 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 61 54 61  sk->pSorter->aTa
8b00: 73 6b 29 3b 0a 20 20 73 71 6c 69 74 65 33 4f 73  sk);.  sqlite3Os
8b10: 43 75 72 72 65 6e 74 54 69 6d 65 49 6e 74 36 34  CurrentTimeInt64
8b20: 28 70 54 61 73 6b 2d 3e 64 62 2d 3e 70 56 66 73  (pTask->db->pVfs
8b30: 2c 20 26 74 29 3b 0a 20 20 66 70 72 69 6e 74 66  , &t);.  fprintf
8b40: 28 73 74 64 65 72 72 2c 20 22 25 6c 6c 64 3a 62  (stderr, "%lld:b
8b50: 67 25 64 20 25 73 5c 6e 22 2c 20 74 2c 20 69 54  g%d %s\n", t, iT
8b60: 61 73 6b 2c 20 7a 45 76 65 6e 74 29 3b 0a 7d 0a  ask, zEvent);.}.
8b70: 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65  static void vdbe
8b80: 53 6f 72 74 65 72 42 6c 6f 63 6b 44 65 62 75 67  SorterBlockDebug
8b90: 28 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20  (.  SortSubtask 
8ba0: 2a 70 54 61 73 6b 2c 0a 20 20 69 6e 74 20 62 42  *pTask,.  int bB
8bb0: 6c 6f 63 6b 65 64 2c 0a 20 20 63 6f 6e 73 74 20  locked,.  const 
8bc0: 63 68 61 72 20 2a 7a 45 76 65 6e 74 0a 29 7b 0a  char *zEvent.){.
8bd0: 20 20 69 66 28 20 62 42 6c 6f 63 6b 65 64 20 29    if( bBlocked )
8be0: 7b 0a 20 20 20 20 69 36 34 20 74 3b 0a 20 20 20  {.    i64 t;.   
8bf0: 20 73 71 6c 69 74 65 33 4f 73 43 75 72 72 65 6e   sqlite3OsCurren
8c00: 74 54 69 6d 65 49 6e 74 36 34 28 70 54 61 73 6b  tTimeInt64(pTask
8c10: 2d 3e 64 62 2d 3e 70 56 66 73 2c 20 26 74 29 3b  ->db->pVfs, &t);
8c20: 0a 20 20 20 20 66 70 72 69 6e 74 66 28 73 74 64  .    fprintf(std
8c30: 65 72 72 2c 20 22 25 6c 6c 64 3a 6d 61 69 6e 20  err, "%lld:main 
8c40: 25 73 5c 6e 22 2c 20 74 2c 20 7a 45 76 65 6e 74  %s\n", t, zEvent
8c50: 29 3b 0a 20 20 7d 0a 7d 0a 23 65 6c 73 65 0a 23  );.  }.}.#else.#
8c60: 20 64 65 66 69 6e 65 20 76 64 62 65 53 6f 72 74   define vdbeSort
8c70: 65 72 57 6f 72 6b 44 65 62 75 67 28 78 2c 79 29  erWorkDebug(x,y)
8c80: 0a 23 20 64 65 66 69 6e 65 20 76 64 62 65 53 6f  .# define vdbeSo
8c90: 72 74 65 72 52 65 77 69 6e 64 44 65 62 75 67 28  rterRewindDebug(
8ca0: 78 2c 79 29 0a 23 20 64 65 66 69 6e 65 20 76 64  x,y).# define vd
8cb0: 62 65 53 6f 72 74 65 72 50 6f 70 75 6c 61 74 65  beSorterPopulate
8cc0: 44 65 62 75 67 28 78 2c 79 29 0a 23 20 64 65 66  Debug(x,y).# def
8cd0: 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72 42 6c  ine vdbeSorterBl
8ce0: 6f 63 6b 44 65 62 75 67 28 78 2c 79 2c 7a 29 0a  ockDebug(x,y,z).
8cf0: 23 65 6e 64 69 66 0a 0a 23 69 66 20 53 51 4c 49  #endif..#if SQLI
8d00: 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48  TE_MAX_WORKER_TH
8d10: 52 45 41 44 53 3e 30 0a 2f 2a 0a 2a 2a 20 4a 6f  READS>0./*.** Jo
8d20: 69 6e 20 74 68 72 65 61 64 20 70 54 61 73 6b 2d  in thread pTask-
8d30: 3e 74 68 72 65 61 64 2e 0a 2a 2f 0a 73 74 61 74  >thread..*/.stat
8d40: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
8d50: 72 4a 6f 69 6e 54 68 72 65 61 64 28 53 6f 72 74  rJoinThread(Sort
8d60: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 29 7b  Subtask *pTask){
8d70: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
8d80: 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70 54 61  TE_OK;.  if( pTa
8d90: 73 6b 2d 3e 70 54 68 72 65 61 64 20 29 7b 0a 23  sk->pThread ){.#
8da0: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 44 45 42  ifdef SQLITE_DEB
8db0: 55 47 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44  UG_SORTER_THREAD
8dc0: 53 0a 20 20 20 20 69 6e 74 20 62 44 6f 6e 65 20  S.    int bDone 
8dd0: 3d 20 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 3b 0a  = pTask->bDone;.
8de0: 23 65 6e 64 69 66 0a 20 20 20 20 76 6f 69 64 20  #endif.    void 
8df0: 2a 70 52 65 74 3b 0a 20 20 20 20 76 64 62 65 53  *pRet;.    vdbeS
8e00: 6f 72 74 65 72 42 6c 6f 63 6b 44 65 62 75 67 28  orterBlockDebug(
8e10: 70 54 61 73 6b 2c 20 21 62 44 6f 6e 65 2c 20 22  pTask, !bDone, "
8e20: 65 6e 74 65 72 22 29 3b 0a 20 20 20 20 72 63 20  enter");.    rc 
8e30: 3d 20 73 71 6c 69 74 65 33 54 68 72 65 61 64 4a  = sqlite3ThreadJ
8e40: 6f 69 6e 28 70 54 61 73 6b 2d 3e 70 54 68 72 65  oin(pTask->pThre
8e50: 61 64 2c 20 26 70 52 65 74 29 3b 0a 20 20 20 20  ad, &pRet);.    
8e60: 76 64 62 65 53 6f 72 74 65 72 42 6c 6f 63 6b 44  vdbeSorterBlockD
8e70: 65 62 75 67 28 70 54 61 73 6b 2c 20 21 62 44 6f  ebug(pTask, !bDo
8e80: 6e 65 2c 20 22 65 78 69 74 22 29 3b 0a 20 20 20  ne, "exit");.   
8e90: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
8ea0: 4f 4b 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45  OK ) rc = SQLITE
8eb0: 5f 50 54 52 5f 54 4f 5f 49 4e 54 28 70 52 65 74  _PTR_TO_INT(pRet
8ec0: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
8ed0: 54 61 73 6b 2d 3e 62 44 6f 6e 65 3d 3d 31 20 29  Task->bDone==1 )
8ee0: 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 62 44 6f  ;.    pTask->bDo
8ef0: 6e 65 20 3d 20 30 3b 0a 20 20 20 20 70 54 61 73  ne = 0;.    pTas
8f00: 6b 2d 3e 70 54 68 72 65 61 64 20 3d 20 30 3b 0a  k->pThread = 0;.
8f10: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
8f20: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 61 75 6e 63 68  .}../*.** Launch
8f30: 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68   a background th
8f40: 72 65 61 64 20 74 6f 20 72 75 6e 20 78 54 61 73  read to run xTas
8f50: 6b 28 70 49 6e 29 2e 0a 2a 2f 0a 73 74 61 74 69  k(pIn)..*/.stati
8f60: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72  c int vdbeSorter
8f70: 43 72 65 61 74 65 54 68 72 65 61 64 28 0a 20 20  CreateThread(.  
8f80: 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61  SortSubtask *pTa
8f90: 73 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  sk,             
8fa0: 2f 2a 20 54 68 72 65 61 64 20 77 69 6c 6c 20 75  /* Thread will u
8fb0: 73 65 20 74 68 69 73 20 74 61 73 6b 20 6f 62 6a  se this task obj
8fc0: 65 63 74 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 28  ect */.  void *(
8fd0: 2a 78 54 61 73 6b 29 28 76 6f 69 64 2a 29 2c 20  *xTask)(void*), 
8fe0: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 6f 75 74           /* Rout
8ff0: 69 6e 65 20 74 6f 20 72 75 6e 20 69 6e 20 61 20  ine to run in a 
9000: 73 65 70 61 72 61 74 65 20 74 68 72 65 61 64 20  separate thread 
9010: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 49 6e 20 20  */.  void *pIn  
9020: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9030: 20 20 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74       /* Argument
9040: 20 70 61 73 73 65 64 20 69 6e 74 6f 20 78 54 61   passed into xTa
9050: 73 6b 28 29 20 2a 2f 0a 29 7b 0a 20 20 61 73 73  sk() */.){.  ass
9060: 65 72 74 28 20 70 54 61 73 6b 2d 3e 70 54 68 72  ert( pTask->pThr
9070: 65 61 64 3d 3d 30 20 26 26 20 70 54 61 73 6b 2d  ead==0 && pTask-
9080: 3e 62 44 6f 6e 65 3d 3d 30 20 29 3b 0a 20 20 72  >bDone==0 );.  r
9090: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 54 68 72  eturn sqlite3Thr
90a0: 65 61 64 43 72 65 61 74 65 28 26 70 54 61 73 6b  eadCreate(&pTask
90b0: 2d 3e 70 54 68 72 65 61 64 2c 20 78 54 61 73 6b  ->pThread, xTask
90c0: 2c 20 70 49 6e 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  , pIn);.}../*.**
90d0: 20 4a 6f 69 6e 20 61 6c 6c 20 6f 75 74 73 74 61   Join all outsta
90e0: 6e 64 69 6e 67 20 74 68 72 65 61 64 73 20 6c 61  nding threads la
90f0: 75 6e 63 68 65 64 20 62 79 20 53 6f 72 74 65 72  unched by Sorter
9100: 57 72 69 74 65 28 29 20 74 6f 20 63 72 65 61 74  Write() to creat
9110: 65 20 0a 2a 2a 20 6c 65 76 65 6c 2d 30 20 50 4d  e .** level-0 PM
9120: 41 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  As..*/.static in
9130: 74 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e  t vdbeSorterJoin
9140: 41 6c 6c 28 56 64 62 65 53 6f 72 74 65 72 20 2a  All(VdbeSorter *
9150: 70 53 6f 72 74 65 72 2c 20 69 6e 74 20 72 63 69  pSorter, int rci
9160: 6e 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 72  n){.  int rc = r
9170: 63 69 6e 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  cin;.  int i;.  
9180: 66 6f 72 28 69 3d 30 3b 20 69 3c 70 53 6f 72 74  for(i=0; i<pSort
9190: 65 72 2d 3e 6e 54 61 73 6b 3b 20 69 2b 2b 29 7b  er->nTask; i++){
91a0: 0a 20 20 20 20 53 6f 72 74 53 75 62 74 61 73 6b  .    SortSubtask
91b0: 20 2a 70 54 61 73 6b 20 3d 20 26 70 53 6f 72 74   *pTask = &pSort
91c0: 65 72 2d 3e 61 54 61 73 6b 5b 69 5d 3b 0a 20 20  er->aTask[i];.  
91d0: 20 20 69 6e 74 20 72 63 32 20 3d 20 76 64 62 65    int rc2 = vdbe
91e0: 53 6f 72 74 65 72 4a 6f 69 6e 54 68 72 65 61 64  SorterJoinThread
91f0: 28 70 54 61 73 6b 29 3b 0a 20 20 20 20 69 66 28  (pTask);.    if(
9200: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
9210: 20 72 63 20 3d 20 72 63 32 3b 0a 20 20 7d 0a 20   rc = rc2;.  }. 
9220: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 23 65   return rc;.}.#e
9230: 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 76 64 62  lse.# define vdb
9240: 65 53 6f 72 74 65 72 4a 6f 69 6e 41 6c 6c 28 78  eSorterJoinAll(x
9250: 2c 72 63 69 6e 29 20 28 72 63 69 6e 29 0a 23 20  ,rcin) (rcin).# 
9260: 64 65 66 69 6e 65 20 76 64 62 65 53 6f 72 74 65  define vdbeSorte
9270: 72 4a 6f 69 6e 54 68 72 65 61 64 28 70 54 61 73  rJoinThread(pTas
9280: 6b 29 20 53 51 4c 49 54 45 5f 4f 4b 0a 23 65 6e  k) SQLITE_OK.#en
9290: 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63  dif../*.** Alloc
92a0: 61 74 65 20 61 20 6e 65 77 20 4d 65 72 67 65 45  ate a new MergeE
92b0: 6e 67 69 6e 65 20 6f 62 6a 65 63 74 20 77 69 74  ngine object wit
92c0: 68 20 73 70 61 63 65 20 66 6f 72 20 6e 49 74 65  h space for nIte
92d0: 72 20 69 74 65 72 61 74 6f 72 73 2e 0a 2a 2f 0a  r iterators..*/.
92e0: 73 74 61 74 69 63 20 4d 65 72 67 65 45 6e 67 69  static MergeEngi
92f0: 6e 65 20 2a 76 64 62 65 4d 65 72 67 65 45 6e 67  ne *vdbeMergeEng
9300: 69 6e 65 4e 65 77 28 69 6e 74 20 6e 49 74 65 72  ineNew(int nIter
9310: 29 7b 0a 20 20 69 6e 74 20 4e 20 3d 20 32 3b 20  ){.  int N = 2; 
9320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9330: 20 20 20 20 20 2f 2a 20 53 6d 61 6c 6c 65 73 74       /* Smallest
9340: 20 70 6f 77 65 72 20 6f 66 20 74 77 6f 20 3e 3d   power of two >=
9350: 20 6e 49 74 65 72 20 2a 2f 0a 20 20 69 6e 74 20   nIter */.  int 
9360: 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20 20 20  nByte;          
9370: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
9380: 6f 74 61 6c 20 62 79 74 65 73 20 6f 66 20 73 70  otal bytes of sp
9390: 61 63 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20  ace to allocate 
93a0: 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65  */.  MergeEngine
93b0: 20 2a 70 4e 65 77 3b 20 20 20 20 20 20 20 20 20   *pNew;         
93c0: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
93d0: 74 6f 20 61 6c 6c 6f 63 61 74 65 64 20 6f 62 6a  to allocated obj
93e0: 65 63 74 20 74 6f 20 72 65 74 75 72 6e 20 2a 2f  ect to return */
93f0: 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 49 74 65  ..  assert( nIte
9400: 72 3c 3d 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45  r<=SORTER_MAX_ME
9410: 52 47 45 5f 43 4f 55 4e 54 20 29 3b 0a 0a 20 20  RGE_COUNT );..  
9420: 77 68 69 6c 65 28 20 4e 3c 6e 49 74 65 72 20 29  while( N<nIter )
9430: 20 4e 20 2b 3d 20 4e 3b 0a 20 20 6e 42 79 74 65   N += N;.  nByte
9440: 20 3d 20 73 69 7a 65 6f 66 28 4d 65 72 67 65 45   = sizeof(MergeE
9450: 6e 67 69 6e 65 29 20 2b 20 4e 20 2a 20 28 73 69  ngine) + N * (si
9460: 7a 65 6f 66 28 69 6e 74 29 20 2b 20 73 69 7a 65  zeof(int) + size
9470: 6f 66 28 50 6d 61 52 65 61 64 65 72 29 29 3b 0a  of(PmaReader));.
9480: 0a 20 20 70 4e 65 77 20 3d 20 28 4d 65 72 67 65  .  pNew = (Merge
9490: 45 6e 67 69 6e 65 2a 29 73 71 6c 69 74 65 33 4d  Engine*)sqlite3M
94a0: 61 6c 6c 6f 63 5a 65 72 6f 28 6e 42 79 74 65 29  allocZero(nByte)
94b0: 3b 0a 20 20 69 66 28 20 70 4e 65 77 20 29 7b 0a  ;.  if( pNew ){.
94c0: 20 20 20 20 70 4e 65 77 2d 3e 6e 54 72 65 65 20      pNew->nTree 
94d0: 3d 20 4e 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 61  = N;.    pNew->a
94e0: 49 74 65 72 20 3d 20 28 50 6d 61 52 65 61 64 65  Iter = (PmaReade
94f0: 72 2a 29 26 70 4e 65 77 5b 31 5d 3b 0a 20 20 20  r*)&pNew[1];.   
9500: 20 70 4e 65 77 2d 3e 61 54 72 65 65 20 3d 20 28   pNew->aTree = (
9510: 69 6e 74 2a 29 26 70 4e 65 77 2d 3e 61 49 74 65  int*)&pNew->aIte
9520: 72 5b 4e 5d 3b 0a 20 20 7d 0a 20 20 72 65 74 75  r[N];.  }.  retu
9530: 72 6e 20 70 4e 65 77 3b 0a 7d 0a 0a 2f 2a 0a 2a  rn pNew;.}../*.*
9540: 2a 20 46 72 65 65 20 74 68 65 20 4d 65 72 67 65  * Free the Merge
9550: 45 6e 67 69 6e 65 20 6f 62 6a 65 63 74 20 70 61  Engine object pa
9560: 73 73 65 64 20 61 73 20 74 68 65 20 6f 6e 6c 79  ssed as the only
9570: 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74   argument..*/.st
9580: 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 4d 65  atic void vdbeMe
9590: 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28 4d 65  rgeEngineFree(Me
95a0: 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67  rgeEngine *pMerg
95b0: 65 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  er){.  int i;.  
95c0: 69 66 28 20 70 4d 65 72 67 65 72 20 29 7b 0a 20  if( pMerger ){. 
95d0: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 4d     for(i=0; i<pM
95e0: 65 72 67 65 72 2d 3e 6e 54 72 65 65 3b 20 69 2b  erger->nTree; i+
95f0: 2b 29 7b 0a 20 20 20 20 20 20 76 64 62 65 50 6d  +){.      vdbePm
9600: 61 52 65 61 64 65 72 43 6c 65 61 72 28 26 70 4d  aReaderClear(&pM
9610: 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 69 5d 29  erger->aIter[i])
9620: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73 71  ;.    }.  }.  sq
9630: 6c 69 74 65 33 5f 66 72 65 65 28 70 4d 65 72 67  lite3_free(pMerg
9640: 65 72 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72  er);.}../*.** Fr
9650: 65 65 20 61 6c 6c 20 72 65 73 6f 75 72 63 65 73  ee all resources
9660: 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68   associated with
9670: 20 74 68 65 20 49 6e 63 72 4d 65 72 67 65 72 20   the IncrMerger 
9680: 6f 62 6a 65 63 74 20 69 6e 64 69 63 61 74 65 64  object indicated
9690: 20 62 79 0a 2a 2a 20 74 68 65 20 66 69 72 73 74   by.** the first
96a0: 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74   argument..*/.st
96b0: 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 49 6e  atic void vdbeIn
96c0: 63 72 46 72 65 65 28 49 6e 63 72 4d 65 72 67 65  crFree(IncrMerge
96d0: 72 20 2a 70 49 6e 63 72 29 7b 0a 20 20 69 66 28  r *pIncr){.  if(
96e0: 20 70 49 6e 63 72 20 29 7b 0a 23 69 66 20 53 51   pIncr ){.#if SQ
96f0: 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f  LITE_MAX_WORKER_
9700: 54 48 52 45 41 44 53 3e 30 0a 20 20 20 20 69 66  THREADS>0.    if
9710: 28 20 70 49 6e 63 72 2d 3e 62 55 73 65 54 68 72  ( pIncr->bUseThr
9720: 65 61 64 20 29 7b 0a 20 20 20 20 20 20 76 64 62  ead ){.      vdb
9730: 65 53 6f 72 74 65 72 4a 6f 69 6e 54 68 72 65 61  eSorterJoinThrea
9740: 64 28 70 49 6e 63 72 2d 3e 70 54 61 73 6b 29 3b  d(pIncr->pTask);
9750: 0a 20 20 20 20 20 20 69 66 28 20 70 49 6e 63 72  .      if( pIncr
9760: 2d 3e 61 46 69 6c 65 5b 30 5d 2e 70 46 64 20 29  ->aFile[0].pFd )
9770: 20 73 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 46   sqlite3OsCloseF
9780: 72 65 65 28 70 49 6e 63 72 2d 3e 61 46 69 6c 65  ree(pIncr->aFile
9790: 5b 30 5d 2e 70 46 64 29 3b 0a 20 20 20 20 20 20  [0].pFd);.      
97a0: 69 66 28 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65  if( pIncr->aFile
97b0: 5b 31 5d 2e 70 46 64 20 29 20 73 71 6c 69 74 65  [1].pFd ) sqlite
97c0: 33 4f 73 43 6c 6f 73 65 46 72 65 65 28 70 49 6e  3OsCloseFree(pIn
97d0: 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 2e 70 46 64  cr->aFile[1].pFd
97e0: 29 3b 0a 20 20 20 20 7d 0a 23 65 6e 64 69 66 0a  );.    }.#endif.
97f0: 20 20 20 20 76 64 62 65 4d 65 72 67 65 45 6e 67      vdbeMergeEng
9800: 69 6e 65 46 72 65 65 28 70 49 6e 63 72 2d 3e 70  ineFree(pIncr->p
9810: 4d 65 72 67 65 72 29 3b 0a 20 20 20 20 73 71 6c  Merger);.    sql
9820: 69 74 65 33 5f 66 72 65 65 28 70 49 6e 63 72 29  ite3_free(pIncr)
9830: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  ;.  }.}../*.** R
9840: 65 73 65 74 20 61 20 73 6f 72 74 69 6e 67 20 63  eset a sorting c
9850: 75 72 73 6f 72 20 62 61 63 6b 20 74 6f 20 69 74  ursor back to it
9860: 73 20 6f 72 69 67 69 6e 61 6c 20 65 6d 70 74 79  s original empty
9870: 20 73 74 61 74 65 2e 0a 2a 2f 0a 76 6f 69 64 20   state..*/.void 
9880: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
9890: 72 52 65 73 65 74 28 73 71 6c 69 74 65 33 20 2a  rReset(sqlite3 *
98a0: 64 62 2c 20 56 64 62 65 53 6f 72 74 65 72 20 2a  db, VdbeSorter *
98b0: 70 53 6f 72 74 65 72 29 7b 0a 20 20 69 6e 74 20  pSorter){.  int 
98c0: 69 3b 0a 20 20 28 76 6f 69 64 29 76 64 62 65 53  i;.  (void)vdbeS
98d0: 6f 72 74 65 72 4a 6f 69 6e 41 6c 6c 28 70 53 6f  orterJoinAll(pSo
98e0: 72 74 65 72 2c 20 53 51 4c 49 54 45 5f 4f 4b 29  rter, SQLITE_OK)
98f0: 3b 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d  ;.  if( pSorter-
9900: 3e 70 52 65 61 64 65 72 20 29 7b 0a 20 20 20 20  >pReader ){.    
9910: 76 64 62 65 50 6d 61 52 65 61 64 65 72 43 6c 65  vdbePmaReaderCle
9920: 61 72 28 70 53 6f 72 74 65 72 2d 3e 70 52 65 61  ar(pSorter->pRea
9930: 64 65 72 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  der);.    sqlite
9940: 33 44 62 46 72 65 65 28 64 62 2c 20 70 53 6f 72  3DbFree(db, pSor
9950: 74 65 72 2d 3e 70 52 65 61 64 65 72 29 3b 0a 20  ter->pReader);. 
9960: 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 61     pSorter->pRea
9970: 64 65 72 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 76  der = 0;.  }.  v
9980: 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46 72  dbeMergeEngineFr
9990: 65 65 28 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72  ee(pSorter->pMer
99a0: 67 65 72 29 3b 0a 20 20 70 53 6f 72 74 65 72 2d  ger);.  pSorter-
99b0: 3e 70 4d 65 72 67 65 72 20 3d 20 30 3b 0a 20 20  >pMerger = 0;.  
99c0: 66 6f 72 28 69 3d 30 3b 20 69 3c 70 53 6f 72 74  for(i=0; i<pSort
99d0: 65 72 2d 3e 6e 54 61 73 6b 3b 20 69 2b 2b 29 7b  er->nTask; i++){
99e0: 0a 20 20 20 20 53 6f 72 74 53 75 62 74 61 73 6b  .    SortSubtask
99f0: 20 2a 70 54 61 73 6b 20 3d 20 26 70 53 6f 72 74   *pTask = &pSort
9a00: 65 72 2d 3e 61 54 61 73 6b 5b 69 5d 3b 0a 20 20  er->aTask[i];.  
9a10: 20 20 76 64 62 65 53 6f 72 74 53 75 62 74 61 73    vdbeSortSubtas
9a20: 6b 43 6c 65 61 6e 75 70 28 64 62 2c 20 70 54 61  kCleanup(db, pTa
9a30: 73 6b 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70  sk);.  }.  if( p
9a40: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65  Sorter->list.aMe
9a50: 6d 6f 72 79 3d 3d 30 20 29 7b 0a 20 20 20 20 76  mory==0 ){.    v
9a60: 64 62 65 53 6f 72 74 65 72 52 65 63 6f 72 64 46  dbeSorterRecordF
9a70: 72 65 65 28 30 2c 20 70 53 6f 72 74 65 72 2d 3e  ree(0, pSorter->
9a80: 6c 69 73 74 2e 70 4c 69 73 74 29 3b 0a 20 20 7d  list.pList);.  }
9a90: 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74  .  pSorter->list
9aa0: 2e 70 4c 69 73 74 20 3d 20 30 3b 0a 20 20 70 53  .pList = 0;.  pS
9ab0: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 73 7a 50 4d  orter->list.szPM
9ac0: 41 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74 65 72  A = 0;.  pSorter
9ad0: 2d 3e 62 55 73 65 50 4d 41 20 3d 20 30 3b 0a 20  ->bUsePMA = 0;. 
9ae0: 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72   pSorter->iMemor
9af0: 79 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74 65 72  y = 0;.  pSorter
9b00: 2d 3e 6d 78 4b 65 79 73 69 7a 65 20 3d 20 30 3b  ->mxKeysize = 0;
9b10: 0a 20 20 73 71 6c 69 74 65 33 44 62 46 72 65 65  .  sqlite3DbFree
9b20: 28 64 62 2c 20 70 53 6f 72 74 65 72 2d 3e 70 55  (db, pSorter->pU
9b30: 6e 70 61 63 6b 65 64 29 3b 0a 20 20 70 53 6f 72  npacked);.  pSor
9b40: 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64 20 3d  ter->pUnpacked =
9b50: 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65   0;.}../*.** Fre
9b60: 65 20 61 6e 79 20 63 75 72 73 6f 72 20 63 6f 6d  e any cursor com
9b70: 70 6f 6e 65 6e 74 73 20 61 6c 6c 6f 63 61 74 65  ponents allocate
9b80: 64 20 62 79 20 73 71 6c 69 74 65 33 56 64 62 65  d by sqlite3Vdbe
9b90: 53 6f 72 74 65 72 58 58 58 20 72 6f 75 74 69 6e  SorterXXX routin
9ba0: 65 73 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  es..*/.void sqli
9bb0: 74 65 33 56 64 62 65 53 6f 72 74 65 72 43 6c 6f  te3VdbeSorterClo
9bc0: 73 65 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  se(sqlite3 *db, 
9bd0: 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72  VdbeCursor *pCsr
9be0: 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20  ){.  VdbeSorter 
9bf0: 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d  *pSorter = pCsr-
9c00: 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69 66 28 20  >pSorter;.  if( 
9c10: 70 53 6f 72 74 65 72 20 29 7b 0a 20 20 20 20 73  pSorter ){.    s
9c20: 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72  qlite3VdbeSorter
9c30: 52 65 73 65 74 28 64 62 2c 20 70 53 6f 72 74 65  Reset(db, pSorte
9c40: 72 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  r);.    sqlite3_
9c50: 66 72 65 65 28 70 53 6f 72 74 65 72 2d 3e 6c 69  free(pSorter->li
9c60: 73 74 2e 61 4d 65 6d 6f 72 79 29 3b 0a 20 20 20  st.aMemory);.   
9c70: 20 73 71 6c 69 74 65 33 44 62 46 72 65 65 28 64   sqlite3DbFree(d
9c80: 62 2c 20 70 53 6f 72 74 65 72 29 3b 0a 20 20 20  b, pSorter);.   
9c90: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 20 3d   pCsr->pSorter =
9ca0: 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a   0;.  }.}../*.**
9cb0: 20 41 6c 6c 6f 63 61 74 65 20 73 70 61 63 65 20   Allocate space 
9cc0: 66 6f 72 20 61 20 66 69 6c 65 2d 68 61 6e 64 6c  for a file-handl
9cd0: 65 20 61 6e 64 20 6f 70 65 6e 20 61 20 74 65 6d  e and open a tem
9ce0: 70 6f 72 61 72 79 20 66 69 6c 65 2e 20 49 66 20  porary file. If 
9cf0: 73 75 63 63 65 73 73 66 75 6c 2c 0a 2a 2a 20 73  successful,.** s
9d00: 65 74 20 2a 70 70 46 69 6c 65 20 74 6f 20 70 6f  et *ppFile to po
9d10: 69 6e 74 20 74 6f 20 74 68 65 20 6d 61 6c 6c 6f  int to the mallo
9d20: 63 27 64 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20  c'd file-handle 
9d30: 61 6e 64 20 72 65 74 75 72 6e 20 53 51 4c 49 54  and return SQLIT
9d40: 45 5f 4f 4b 2e 0a 2a 2a 20 4f 74 68 65 72 77 69  E_OK..** Otherwi
9d50: 73 65 2c 20 73 65 74 20 2a 70 70 46 69 6c 65 20  se, set *ppFile 
9d60: 74 6f 20 30 20 61 6e 64 20 72 65 74 75 72 6e 20  to 0 and return 
9d70: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
9d80: 63 6f 64 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  code..*/.static 
9d90: 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72 4f 70  int vdbeSorterOp
9da0: 65 6e 54 65 6d 70 46 69 6c 65 28 73 71 6c 69 74  enTempFile(sqlit
9db0: 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 73 71  e3_vfs *pVfs, sq
9dc0: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 2a 70 70 46  lite3_file **ppF
9dd0: 69 6c 65 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  ile){.  int rc;.
9de0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
9df0: 4f 70 65 6e 4d 61 6c 6c 6f 63 28 70 56 66 73 2c  OpenMalloc(pVfs,
9e00: 20 30 2c 20 70 70 46 69 6c 65 2c 0a 20 20 20 20   0, ppFile,.    
9e10: 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 54 45    SQLITE_OPEN_TE
9e20: 4d 50 5f 4a 4f 55 52 4e 41 4c 20 7c 0a 20 20 20  MP_JOURNAL |.   
9e30: 20 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 52     SQLITE_OPEN_R
9e40: 45 41 44 57 52 49 54 45 20 20 20 20 7c 20 53 51  EADWRITE    | SQ
9e50: 4c 49 54 45 5f 4f 50 45 4e 5f 43 52 45 41 54 45  LITE_OPEN_CREATE
9e60: 20 7c 0a 20 20 20 20 20 20 53 51 4c 49 54 45 5f   |.      SQLITE_
9e70: 4f 50 45 4e 5f 45 58 43 4c 55 53 49 56 45 20 20  OPEN_EXCLUSIVE  
9e80: 20 20 7c 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f    | SQLITE_OPEN_
9e90: 44 45 4c 45 54 45 4f 4e 43 4c 4f 53 45 2c 20 26  DELETEONCLOSE, &
9ea0: 72 63 0a 20 20 29 3b 0a 20 20 69 66 28 20 72 63  rc.  );.  if( rc
9eb0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
9ec0: 20 20 20 69 36 34 20 6d 61 78 20 3d 20 53 51 4c     i64 max = SQL
9ed0: 49 54 45 5f 4d 41 58 5f 4d 4d 41 50 5f 53 49 5a  ITE_MAX_MMAP_SIZ
9ee0: 45 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73  E;.    sqlite3Os
9ef0: 46 69 6c 65 43 6f 6e 74 72 6f 6c 48 69 6e 74 28  FileControlHint(
9f00: 20 2a 70 70 46 69 6c 65 2c 20 53 51 4c 49 54 45   *ppFile, SQLITE
9f10: 5f 46 43 4e 54 4c 5f 4d 4d 41 50 5f 53 49 5a 45  _FCNTL_MMAP_SIZE
9f20: 2c 20 28 76 6f 69 64 2a 29 26 6d 61 78 29 3b 0a  , (void*)&max);.
9f30: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
9f40: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 69 74 20  .}../*.** If it 
9f50: 68 61 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20  has not already 
9f60: 62 65 65 6e 20 61 6c 6c 6f 63 61 74 65 64 2c 20  been allocated, 
9f70: 61 6c 6c 6f 63 61 74 65 20 74 68 65 20 55 6e 70  allocate the Unp
9f80: 61 63 6b 65 64 52 65 63 6f 72 64 20 0a 2a 2a 20  ackedRecord .** 
9f90: 73 74 72 75 63 74 75 72 65 20 61 74 20 70 54 61  structure at pTa
9fa0: 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 2e 20 52  sk->pUnpacked. R
9fb0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20  eturn SQLITE_OK 
9fc0: 69 66 20 73 75 63 63 65 73 73 66 75 6c 20 28 6f  if successful (o
9fd0: 72 20 0a 2a 2a 20 69 66 20 6e 6f 20 61 6c 6c 6f  r .** if no allo
9fe0: 63 61 74 69 6f 6e 20 77 61 73 20 72 65 71 75 69  cation was requi
9ff0: 72 65 64 29 2c 20 6f 72 20 53 51 4c 49 54 45 5f  red), or SQLITE_
a000: 4e 4f 4d 45 4d 20 6f 74 68 65 72 77 69 73 65 2e  NOMEM otherwise.
a010: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
a020: 64 62 65 53 6f 72 74 41 6c 6c 6f 63 55 6e 70 61  dbeSortAllocUnpa
a030: 63 6b 65 64 28 53 6f 72 74 53 75 62 74 61 73 6b  cked(SortSubtask
a040: 20 2a 70 54 61 73 6b 29 7b 0a 20 20 69 66 28 20   *pTask){.  if( 
a050: 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64  pTask->pUnpacked
a060: 3d 3d 30 20 29 7b 0a 20 20 20 20 63 68 61 72 20  ==0 ){.    char 
a070: 2a 70 46 72 65 65 3b 0a 20 20 20 20 70 54 61 73  *pFree;.    pTas
a080: 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 20 3d 20 73  k->pUnpacked = s
a090: 71 6c 69 74 65 33 56 64 62 65 41 6c 6c 6f 63 55  qlite3VdbeAllocU
a0a0: 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 28 0a 20  npackedRecord(. 
a0b0: 20 20 20 20 20 20 20 70 54 61 73 6b 2d 3e 70 53         pTask->pS
a0c0: 6f 72 74 65 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c  orter->pKeyInfo,
a0d0: 20 30 2c 20 30 2c 20 26 70 46 72 65 65 0a 20 20   0, 0, &pFree.  
a0e0: 20 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28    );.    assert(
a0f0: 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65   pTask->pUnpacke
a100: 64 3d 3d 28 55 6e 70 61 63 6b 65 64 52 65 63 6f  d==(UnpackedReco
a110: 72 64 2a 29 70 46 72 65 65 20 29 3b 0a 20 20 20  rd*)pFree );.   
a120: 20 69 66 28 20 70 46 72 65 65 3d 3d 30 20 29 20   if( pFree==0 ) 
a130: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
a140: 4d 45 4d 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e  MEM;.    pTask->
a150: 70 55 6e 70 61 63 6b 65 64 2d 3e 6e 46 69 65 6c  pUnpacked->nFiel
a160: 64 20 3d 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74  d = pTask->pSort
a170: 65 72 2d 3e 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46  er->pKeyInfo->nF
a180: 69 65 6c 64 3b 0a 20 20 20 20 70 54 61 73 6b 2d  ield;.    pTask-
a190: 3e 70 55 6e 70 61 63 6b 65 64 2d 3e 65 72 72 43  >pUnpacked->errC
a1a0: 6f 64 65 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 72  ode = 0;.  }.  r
a1b0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
a1c0: 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 4d 65 72 67 65  .}.../*.** Merge
a1d0: 20 74 68 65 20 74 77 6f 20 73 6f 72 74 65 64 20   the two sorted 
a1e0: 6c 69 73 74 73 20 70 31 20 61 6e 64 20 70 32 20  lists p1 and p2 
a1f0: 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65 20 6c 69  into a single li
a200: 73 74 2e 0a 2a 2a 20 53 65 74 20 2a 70 70 4f 75  st..** Set *ppOu
a210: 74 20 74 6f 20 74 68 65 20 68 65 61 64 20 6f 66  t to the head of
a220: 20 74 68 65 20 6e 65 77 20 6c 69 73 74 2e 0a 2a   the new list..*
a230: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64  /.static void vd
a240: 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28 0a 20  beSorterMerge(. 
a250: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
a260: 61 73 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20  ask,            
a270: 20 2f 2a 20 43 61 6c 6c 69 6e 67 20 74 68 72 65   /* Calling thre
a280: 61 64 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20  ad context */.  
a290: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 31  SorterRecord *p1
a2a0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
a2b0: 2f 2a 20 46 69 72 73 74 20 6c 69 73 74 20 74 6f  /* First list to
a2c0: 20 6d 65 72 67 65 20 2a 2f 0a 20 20 53 6f 72 74   merge */.  Sort
a2d0: 65 72 52 65 63 6f 72 64 20 2a 70 32 2c 20 20 20  erRecord *p2,   
a2e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
a2f0: 65 63 6f 6e 64 20 6c 69 73 74 20 74 6f 20 6d 65  econd list to me
a300: 72 67 65 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52  rge */.  SorterR
a310: 65 63 6f 72 64 20 2a 2a 70 70 4f 75 74 20 20 20  ecord **ppOut   
a320: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
a330: 20 48 65 61 64 20 6f 66 20 6d 65 72 67 65 64 20   Head of merged 
a340: 6c 69 73 74 20 2a 2f 0a 29 7b 0a 20 20 53 6f 72  list */.){.  Sor
a350: 74 65 72 52 65 63 6f 72 64 20 2a 70 46 69 6e 61  terRecord *pFina
a360: 6c 20 3d 20 30 3b 0a 20 20 53 6f 72 74 65 72 52  l = 0;.  SorterR
a370: 65 63 6f 72 64 20 2a 2a 70 70 20 3d 20 26 70 46  ecord **pp = &pF
a380: 69 6e 61 6c 3b 0a 20 20 76 6f 69 64 20 2a 70 56  inal;.  void *pV
a390: 61 6c 32 20 3d 20 70 32 20 3f 20 53 52 56 41 4c  al2 = p2 ? SRVAL
a3a0: 28 70 32 29 20 3a 20 30 3b 0a 0a 20 20 77 68 69  (p2) : 0;..  whi
a3b0: 6c 65 28 20 70 31 20 26 26 20 70 32 20 29 7b 0a  le( p1 && p2 ){.
a3c0: 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 20 20 20      int res;.   
a3d0: 20 72 65 73 20 3d 20 76 64 62 65 53 6f 72 74 65   res = vdbeSorte
a3e0: 72 43 6f 6d 70 61 72 65 28 70 54 61 73 6b 2c 20  rCompare(pTask, 
a3f0: 53 52 56 41 4c 28 70 31 29 2c 20 70 31 2d 3e 6e  SRVAL(p1), p1->n
a400: 56 61 6c 2c 20 70 56 61 6c 32 2c 20 70 32 2d 3e  Val, pVal2, p2->
a410: 6e 56 61 6c 29 3b 0a 20 20 20 20 69 66 28 20 72  nVal);.    if( r
a420: 65 73 3c 3d 30 20 29 7b 0a 20 20 20 20 20 20 2a  es<=0 ){.      *
a430: 70 70 20 3d 20 70 31 3b 0a 20 20 20 20 20 20 70  pp = p1;.      p
a440: 70 20 3d 20 26 70 31 2d 3e 75 2e 70 4e 65 78 74  p = &p1->u.pNext
a450: 3b 0a 20 20 20 20 20 20 70 31 20 3d 20 70 31 2d  ;.      p1 = p1-
a460: 3e 75 2e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  >u.pNext;.      
a470: 70 56 61 6c 32 20 3d 20 30 3b 0a 20 20 20 20 7d  pVal2 = 0;.    }
a480: 65 6c 73 65 7b 0a 20 20 20 20 20 20 2a 70 70 20  else{.      *pp 
a490: 3d 20 70 32 3b 0a 20 20 20 20 20 20 20 70 70 20  = p2;.       pp 
a4a0: 3d 20 26 70 32 2d 3e 75 2e 70 4e 65 78 74 3b 0a  = &p2->u.pNext;.
a4b0: 20 20 20 20 20 20 70 32 20 3d 20 70 32 2d 3e 75        p2 = p2->u
a4c0: 2e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 69 66  .pNext;.      if
a4d0: 28 20 70 32 3d 3d 30 20 29 20 62 72 65 61 6b 3b  ( p2==0 ) break;
a4e0: 0a 20 20 20 20 20 20 70 56 61 6c 32 20 3d 20 53  .      pVal2 = S
a4f0: 52 56 41 4c 28 70 32 29 3b 0a 20 20 20 20 7d 0a  RVAL(p2);.    }.
a500: 20 20 7d 0a 20 20 2a 70 70 20 3d 20 70 31 20 3f    }.  *pp = p1 ?
a510: 20 70 31 20 3a 20 70 32 3b 0a 20 20 2a 70 70 4f   p1 : p2;.  *ppO
a520: 75 74 20 3d 20 70 46 69 6e 61 6c 3b 0a 7d 0a 0a  ut = pFinal;.}..
a530: 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74 68 65 20 6c  /*.** Sort the l
a540: 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20 72 65  inked list of re
a550: 63 6f 72 64 73 20 68 65 61 64 65 64 20 61 74 20  cords headed at 
a560: 70 54 61 73 6b 2d 3e 70 4c 69 73 74 2e 20 52 65  pTask->pList. Re
a570: 74 75 72 6e 20 0a 2a 2a 20 53 51 4c 49 54 45 5f  turn .** SQLITE_
a580: 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  OK if successful
a590: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65  , or an SQLite e
a5a0: 72 72 6f 72 20 63 6f 64 65 20 28 69 2e 65 2e 20  rror code (i.e. 
a5b0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 20 69 66  SQLITE_NOMEM) if
a5c0: 20 0a 2a 2a 20 61 6e 20 65 72 72 6f 72 20 6f 63   .** an error oc
a5d0: 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  curs..*/.static 
a5e0: 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72 53 6f  int vdbeSorterSo
a5f0: 72 74 28 53 6f 72 74 53 75 62 74 61 73 6b 20 2a  rt(SortSubtask *
a600: 70 54 61 73 6b 2c 20 53 6f 72 74 65 72 4c 69 73  pTask, SorterLis
a610: 74 20 2a 70 4c 69 73 74 29 7b 0a 20 20 69 6e 74  t *pList){.  int
a620: 20 69 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f   i;.  SorterReco
a630: 72 64 20 2a 2a 61 53 6c 6f 74 3b 0a 20 20 53 6f  rd **aSlot;.  So
a640: 72 74 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a 20  rterRecord *p;. 
a650: 20 69 6e 74 20 72 63 3b 0a 0a 20 20 72 63 20 3d   int rc;..  rc =
a660: 20 76 64 62 65 53 6f 72 74 41 6c 6c 6f 63 55 6e   vdbeSortAllocUn
a670: 70 61 63 6b 65 64 28 70 54 61 73 6b 29 3b 0a 20  packed(pTask);. 
a680: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
a690: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
a6a0: 0a 20 20 61 53 6c 6f 74 20 3d 20 28 53 6f 72 74  .  aSlot = (Sort
a6b0: 65 72 52 65 63 6f 72 64 20 2a 2a 29 73 71 6c 69  erRecord **)sqli
a6c0: 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 36 34  te3MallocZero(64
a6d0: 20 2a 20 73 69 7a 65 6f 66 28 53 6f 72 74 65 72   * sizeof(Sorter
a6e0: 52 65 63 6f 72 64 20 2a 29 29 3b 0a 20 20 69 66  Record *));.  if
a6f0: 28 20 21 61 53 6c 6f 74 20 29 7b 0a 20 20 20 20  ( !aSlot ){.    
a700: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
a710: 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20 70 20 3d 20  MEM;.  }..  p = 
a720: 70 4c 69 73 74 2d 3e 70 4c 69 73 74 3b 0a 20 20  pList->pList;.  
a730: 77 68 69 6c 65 28 20 70 20 29 7b 0a 20 20 20 20  while( p ){.    
a740: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e  SorterRecord *pN
a750: 65 78 74 3b 0a 20 20 20 20 69 66 28 20 70 4c 69  ext;.    if( pLi
a760: 73 74 2d 3e 61 4d 65 6d 6f 72 79 20 29 7b 0a 20  st->aMemory ){. 
a770: 20 20 20 20 20 69 66 28 20 28 75 38 2a 29 70 3d       if( (u8*)p=
a780: 3d 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f 72 79 20  =pList->aMemory 
a790: 29 7b 0a 20 20 20 20 20 20 20 20 70 4e 65 78 74  ){.        pNext
a7a0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 65 6c 73   = 0;.      }els
a7b0: 65 7b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  e{.        asser
a7c0: 74 28 20 70 2d 3e 75 2e 69 4e 65 78 74 3c 73 71  t( p->u.iNext<sq
a7d0: 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28  lite3MallocSize(
a7e0: 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f 72 79 29 20  pList->aMemory) 
a7f0: 29 3b 0a 20 20 20 20 20 20 20 20 70 4e 65 78 74  );.        pNext
a800: 20 3d 20 28 53 6f 72 74 65 72 52 65 63 6f 72 64   = (SorterRecord
a810: 2a 29 26 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f 72  *)&pList->aMemor
a820: 79 5b 70 2d 3e 75 2e 69 4e 65 78 74 5d 3b 0a 20  y[p->u.iNext];. 
a830: 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65       }.    }else
a840: 7b 0a 20 20 20 20 20 20 70 4e 65 78 74 20 3d 20  {.      pNext = 
a850: 70 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20 20 20 20  p->u.pNext;.    
a860: 7d 0a 0a 20 20 20 20 70 2d 3e 75 2e 70 4e 65 78  }..    p->u.pNex
a870: 74 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28 69  t = 0;.    for(i
a880: 3d 30 3b 20 61 53 6c 6f 74 5b 69 5d 3b 20 69 2b  =0; aSlot[i]; i+
a890: 2b 29 7b 0a 20 20 20 20 20 20 76 64 62 65 53 6f  +){.      vdbeSo
a8a0: 72 74 65 72 4d 65 72 67 65 28 70 54 61 73 6b 2c  rterMerge(pTask,
a8b0: 20 70 2c 20 61 53 6c 6f 74 5b 69 5d 2c 20 26 70   p, aSlot[i], &p
a8c0: 29 3b 0a 20 20 20 20 20 20 61 53 6c 6f 74 5b 69  );.      aSlot[i
a8d0: 5d 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20  ] = 0;.    }.   
a8e0: 20 61 53 6c 6f 74 5b 69 5d 20 3d 20 70 3b 0a 20   aSlot[i] = p;. 
a8f0: 20 20 20 70 20 3d 20 70 4e 65 78 74 3b 0a 20 20     p = pNext;.  
a900: 7d 0a 0a 20 20 70 20 3d 20 30 3b 0a 20 20 66 6f  }..  p = 0;.  fo
a910: 72 28 69 3d 30 3b 20 69 3c 36 34 3b 20 69 2b 2b  r(i=0; i<64; i++
a920: 29 7b 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65  ){.    vdbeSorte
a930: 72 4d 65 72 67 65 28 70 54 61 73 6b 2c 20 70 2c  rMerge(pTask, p,
a940: 20 61 53 6c 6f 74 5b 69 5d 2c 20 26 70 29 3b 0a   aSlot[i], &p);.
a950: 20 20 7d 0a 20 20 70 4c 69 73 74 2d 3e 70 4c 69    }.  pList->pLi
a960: 73 74 20 3d 20 70 3b 0a 0a 20 20 73 71 6c 69 74  st = p;..  sqlit
a970: 65 33 5f 66 72 65 65 28 61 53 6c 6f 74 29 3b 0a  e3_free(aSlot);.
a980: 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 70 55 6e    if( pTask->pUn
a990: 70 61 63 6b 65 64 2d 3e 65 72 72 43 6f 64 65 20  packed->errCode 
a9a0: 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  ){.    assert( p
a9b0: 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 2d  Task->pUnpacked-
a9c0: 3e 65 72 72 43 6f 64 65 3d 3d 53 51 4c 49 54 45  >errCode==SQLITE
a9d0: 5f 4e 4f 4d 45 4d 20 29 3b 0a 20 20 20 20 72 65  _NOMEM );.    re
a9e0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
a9f0: 4d 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  M;.  }.  return 
aa00: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
aa10: 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61  .** Initialize a
aa20: 20 50 4d 41 2d 77 72 69 74 65 72 20 6f 62 6a 65   PMA-writer obje
aa30: 63 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ct..*/.static vo
aa40: 69 64 20 76 64 62 65 50 6d 61 57 72 69 74 65 72  id vdbePmaWriter
aa50: 49 6e 69 74 28 0a 20 20 73 71 6c 69 74 65 33 5f  Init(.  sqlite3_
aa60: 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 20 20 20  file *pFile,    
aa70: 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20          /* File 
aa80: 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a 20  to write to */. 
aa90: 20 50 6d 61 57 72 69 74 65 72 20 2a 70 2c 20 20   PmaWriter *p,  
aaa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
aab0: 20 2f 2a 20 4f 62 6a 65 63 74 20 74 6f 20 70 6f   /* Object to po
aac0: 70 75 6c 61 74 65 20 2a 2f 0a 20 20 69 6e 74 20  pulate */.  int 
aad0: 6e 42 75 66 2c 20 20 20 20 20 20 20 20 20 20 20  nBuf,           
aae0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
aaf0: 75 66 66 65 72 20 73 69 7a 65 20 2a 2f 0a 20 20  uffer size */.  
ab00: 69 36 34 20 69 53 74 61 72 74 20 20 20 20 20 20  i64 iStart      
ab10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ab20: 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20 70 46 69  /* Offset of pFi
ab30: 6c 65 20 74 6f 20 62 65 67 69 6e 20 77 72 69 74  le to begin writ
ab40: 69 6e 67 20 61 74 20 2a 2f 0a 29 7b 0a 20 20 6d  ing at */.){.  m
ab50: 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65  emset(p, 0, size
ab60: 6f 66 28 50 6d 61 57 72 69 74 65 72 29 29 3b 0a  of(PmaWriter));.
ab70: 20 20 70 2d 3e 61 42 75 66 66 65 72 20 3d 20 28    p->aBuffer = (
ab80: 75 38 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  u8*)sqlite3Mallo
ab90: 63 28 6e 42 75 66 29 3b 0a 20 20 69 66 28 20 21  c(nBuf);.  if( !
aba0: 70 2d 3e 61 42 75 66 66 65 72 20 29 7b 0a 20 20  p->aBuffer ){.  
abb0: 20 20 70 2d 3e 65 46 57 45 72 72 20 3d 20 53 51    p->eFWErr = SQ
abc0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65  LITE_NOMEM;.  }e
abd0: 6c 73 65 7b 0a 20 20 20 20 70 2d 3e 69 42 75 66  lse{.    p->iBuf
abe0: 45 6e 64 20 3d 20 70 2d 3e 69 42 75 66 53 74 61  End = p->iBufSta
abf0: 72 74 20 3d 20 28 69 53 74 61 72 74 20 25 20 6e  rt = (iStart % n
ac00: 42 75 66 29 3b 0a 20 20 20 20 70 2d 3e 69 57 72  Buf);.    p->iWr
ac10: 69 74 65 4f 66 66 20 3d 20 69 53 74 61 72 74 20  iteOff = iStart 
ac20: 2d 20 70 2d 3e 69 42 75 66 53 74 61 72 74 3b 0a  - p->iBufStart;.
ac30: 20 20 20 20 70 2d 3e 6e 42 75 66 66 65 72 20 3d      p->nBuffer =
ac40: 20 6e 42 75 66 3b 0a 20 20 20 20 70 2d 3e 70 46   nBuf;.    p->pF
ac50: 69 6c 65 20 3d 20 70 46 69 6c 65 3b 0a 20 20 7d  ile = pFile;.  }
ac60: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20  .}../*.** Write 
ac70: 6e 44 61 74 61 20 62 79 74 65 73 20 6f 66 20 64  nData bytes of d
ac80: 61 74 61 20 74 6f 20 74 68 65 20 50 4d 41 2e 20  ata to the PMA. 
ac90: 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  Return SQLITE_OK
aca0: 0a 2a 2a 20 69 66 20 73 75 63 63 65 73 73 66 75  .** if successfu
acb0: 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20  l, or an SQLite 
acc0: 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20 61 6e  error code if an
acd0: 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a   error occurs..*
ace0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64  /.static void vd
acf0: 62 65 50 6d 61 57 72 69 74 65 42 6c 6f 62 28 50  bePmaWriteBlob(P
ad00: 6d 61 57 72 69 74 65 72 20 2a 70 2c 20 75 38 20  maWriter *p, u8 
ad10: 2a 70 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74  *pData, int nDat
ad20: 61 29 7b 0a 20 20 69 6e 74 20 6e 52 65 6d 20 3d  a){.  int nRem =
ad30: 20 6e 44 61 74 61 3b 0a 20 20 77 68 69 6c 65 28   nData;.  while(
ad40: 20 6e 52 65 6d 3e 30 20 26 26 20 70 2d 3e 65 46   nRem>0 && p->eF
ad50: 57 45 72 72 3d 3d 30 20 29 7b 0a 20 20 20 20 69  WErr==0 ){.    i
ad60: 6e 74 20 6e 43 6f 70 79 20 3d 20 6e 52 65 6d 3b  nt nCopy = nRem;
ad70: 0a 20 20 20 20 69 66 28 20 6e 43 6f 70 79 3e 28  .    if( nCopy>(
ad80: 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 70 2d 3e  p->nBuffer - p->
ad90: 69 42 75 66 45 6e 64 29 20 29 7b 0a 20 20 20 20  iBufEnd) ){.    
ada0: 20 20 6e 43 6f 70 79 20 3d 20 70 2d 3e 6e 42 75    nCopy = p->nBu
adb0: 66 66 65 72 20 2d 20 70 2d 3e 69 42 75 66 45 6e  ffer - p->iBufEn
adc0: 64 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 6d 65  d;.    }..    me
add0: 6d 63 70 79 28 26 70 2d 3e 61 42 75 66 66 65 72  mcpy(&p->aBuffer
ade0: 5b 70 2d 3e 69 42 75 66 45 6e 64 5d 2c 20 26 70  [p->iBufEnd], &p
adf0: 44 61 74 61 5b 6e 44 61 74 61 2d 6e 52 65 6d 5d  Data[nData-nRem]
ae00: 2c 20 6e 43 6f 70 79 29 3b 0a 20 20 20 20 70 2d  , nCopy);.    p-
ae10: 3e 69 42 75 66 45 6e 64 20 2b 3d 20 6e 43 6f 70  >iBufEnd += nCop
ae20: 79 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 69 42  y;.    if( p->iB
ae30: 75 66 45 6e 64 3d 3d 70 2d 3e 6e 42 75 66 66 65  ufEnd==p->nBuffe
ae40: 72 20 29 7b 0a 20 20 20 20 20 20 70 2d 3e 65 46  r ){.      p->eF
ae50: 57 45 72 72 20 3d 20 73 71 6c 69 74 65 33 4f 73  WErr = sqlite3Os
ae60: 57 72 69 74 65 28 70 2d 3e 70 46 69 6c 65 2c 20  Write(p->pFile, 
ae70: 0a 20 20 20 20 20 20 20 20 20 20 26 70 2d 3e 61  .          &p->a
ae80: 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 53 74  Buffer[p->iBufSt
ae90: 61 72 74 5d 2c 20 70 2d 3e 69 42 75 66 45 6e 64  art], p->iBufEnd
aea0: 20 2d 20 70 2d 3e 69 42 75 66 53 74 61 72 74 2c   - p->iBufStart,
aeb0: 20 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e 69   .          p->i
aec0: 57 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42  WriteOff + p->iB
aed0: 75 66 53 74 61 72 74 0a 20 20 20 20 20 20 29 3b  ufStart.      );
aee0: 0a 20 20 20 20 20 20 70 2d 3e 69 42 75 66 53 74  .      p->iBufSt
aef0: 61 72 74 20 3d 20 70 2d 3e 69 42 75 66 45 6e 64  art = p->iBufEnd
af00: 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 2d 3e 69   = 0;.      p->i
af10: 57 72 69 74 65 4f 66 66 20 2b 3d 20 70 2d 3e 6e  WriteOff += p->n
af20: 42 75 66 66 65 72 3b 0a 20 20 20 20 7d 0a 20 20  Buffer;.    }.  
af30: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 69 42 75    assert( p->iBu
af40: 66 45 6e 64 3c 70 2d 3e 6e 42 75 66 66 65 72 20  fEnd<p->nBuffer 
af50: 29 3b 0a 0a 20 20 20 20 6e 52 65 6d 20 2d 3d 20  );..    nRem -= 
af60: 6e 43 6f 70 79 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  nCopy;.  }.}../*
af70: 0a 2a 2a 20 46 6c 75 73 68 20 61 6e 79 20 62 75  .** Flush any bu
af80: 66 66 65 72 65 64 20 64 61 74 61 20 74 6f 20 64  ffered data to d
af90: 69 73 6b 20 61 6e 64 20 63 6c 65 61 6e 20 75 70  isk and clean up
afa0: 20 74 68 65 20 50 4d 41 2d 77 72 69 74 65 72 20   the PMA-writer 
afb0: 6f 62 6a 65 63 74 2e 0a 2a 2a 20 54 68 65 20 72  object..** The r
afc0: 65 73 75 6c 74 73 20 6f 66 20 75 73 69 6e 67 20  esults of using 
afd0: 74 68 65 20 50 4d 41 2d 77 72 69 74 65 72 20 61  the PMA-writer a
afe0: 66 74 65 72 20 74 68 69 73 20 63 61 6c 6c 20 61  fter this call a
aff0: 72 65 20 75 6e 64 65 66 69 6e 65 64 2e 0a 2a 2a  re undefined..**
b000: 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   Return SQLITE_O
b010: 4b 20 69 66 20 66 6c 75 73 68 69 6e 67 20 74 68  K if flushing th
b020: 65 20 62 75 66 66 65 72 65 64 20 64 61 74 61 20  e buffered data 
b030: 73 75 63 63 65 65 64 73 20 6f 72 20 69 73 20 6e  succeeds or is n
b040: 6f 74 20 0a 2a 2a 20 72 65 71 75 69 72 65 64 2e  ot .** required.
b050: 20 4f 74 68 65 72 77 69 73 65 2c 20 72 65 74 75   Otherwise, retu
b060: 72 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  rn an SQLite err
b070: 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 42  or code..**.** B
b080: 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2c  efore returning,
b090: 20 73 65 74 20 2a 70 69 45 6f 66 20 74 6f 20 74   set *piEof to t
b0a0: 68 65 20 6f 66 66 73 65 74 20 69 6d 6d 65 64 69  he offset immedi
b0b0: 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 69 6e 67 20  ately following 
b0c0: 74 68 65 0a 2a 2a 20 6c 61 73 74 20 62 79 74 65  the.** last byte
b0d0: 20 77 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20   written to the 
b0e0: 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  file..*/.static 
b0f0: 69 6e 74 20 76 64 62 65 50 6d 61 57 72 69 74 65  int vdbePmaWrite
b100: 72 46 69 6e 69 73 68 28 50 6d 61 57 72 69 74 65  rFinish(PmaWrite
b110: 72 20 2a 70 2c 20 69 36 34 20 2a 70 69 45 6f 66  r *p, i64 *piEof
b120: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69  ){.  int rc;.  i
b130: 66 28 20 70 2d 3e 65 46 57 45 72 72 3d 3d 30 20  f( p->eFWErr==0 
b140: 26 26 20 41 4c 57 41 59 53 28 70 2d 3e 61 42 75  && ALWAYS(p->aBu
b150: 66 66 65 72 29 20 26 26 20 70 2d 3e 69 42 75 66  ffer) && p->iBuf
b160: 45 6e 64 3e 70 2d 3e 69 42 75 66 53 74 61 72 74  End>p->iBufStart
b170: 20 29 7b 0a 20 20 20 20 70 2d 3e 65 46 57 45 72   ){.    p->eFWEr
b180: 72 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69  r = sqlite3OsWri
b190: 74 65 28 70 2d 3e 70 46 69 6c 65 2c 20 0a 20 20  te(p->pFile, .  
b1a0: 20 20 20 20 20 20 26 70 2d 3e 61 42 75 66 66 65        &p->aBuffe
b1b0: 72 5b 70 2d 3e 69 42 75 66 53 74 61 72 74 5d 2c  r[p->iBufStart],
b1c0: 20 70 2d 3e 69 42 75 66 45 6e 64 20 2d 20 70 2d   p->iBufEnd - p-
b1d0: 3e 69 42 75 66 53 74 61 72 74 2c 20 0a 20 20 20  >iBufStart, .   
b1e0: 20 20 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66       p->iWriteOf
b1f0: 66 20 2b 20 70 2d 3e 69 42 75 66 53 74 61 72 74  f + p->iBufStart
b200: 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 20 20 2a 70  .    );.  }.  *p
b210: 69 45 6f 66 20 3d 20 28 70 2d 3e 69 57 72 69 74  iEof = (p->iWrit
b220: 65 4f 66 66 20 2b 20 70 2d 3e 69 42 75 66 45 6e  eOff + p->iBufEn
b230: 64 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  d);.  sqlite3_fr
b240: 65 65 28 70 2d 3e 61 42 75 66 66 65 72 29 3b 0a  ee(p->aBuffer);.
b250: 20 20 72 63 20 3d 20 70 2d 3e 65 46 57 45 72 72    rc = p->eFWErr
b260: 3b 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c  ;.  memset(p, 0,
b270: 20 73 69 7a 65 6f 66 28 50 6d 61 57 72 69 74 65   sizeof(PmaWrite
b280: 72 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  r));.  return rc
b290: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65  ;.}../*.** Write
b2a0: 20 76 61 6c 75 65 20 69 56 61 6c 20 65 6e 63 6f   value iVal enco
b2b0: 64 65 64 20 61 73 20 61 20 76 61 72 69 6e 74 20  ded as a varint 
b2c0: 74 6f 20 74 68 65 20 50 4d 41 2e 20 52 65 74 75  to the PMA. Retu
b2d0: 72 6e 20 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b  rn .** SQLITE_OK
b2e0: 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   if successful, 
b2f0: 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  or an SQLite err
b300: 6f 72 20 63 6f 64 65 20 69 66 20 61 6e 20 65 72  or code if an er
b310: 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73  ror occurs..*/.s
b320: 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 50  tatic void vdbeP
b330: 6d 61 57 72 69 74 65 56 61 72 69 6e 74 28 50 6d  maWriteVarint(Pm
b340: 61 57 72 69 74 65 72 20 2a 70 2c 20 75 36 34 20  aWriter *p, u64 
b350: 69 56 61 6c 29 7b 0a 20 20 69 6e 74 20 6e 42 79  iVal){.  int nBy
b360: 74 65 3b 20 0a 20 20 75 38 20 61 42 79 74 65 5b  te; .  u8 aByte[
b370: 31 30 5d 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73  10];.  nByte = s
b380: 71 6c 69 74 65 33 50 75 74 56 61 72 69 6e 74 28  qlite3PutVarint(
b390: 61 42 79 74 65 2c 20 69 56 61 6c 29 3b 0a 20 20  aByte, iVal);.  
b3a0: 76 64 62 65 50 6d 61 57 72 69 74 65 42 6c 6f 62  vdbePmaWriteBlob
b3b0: 28 70 2c 20 61 42 79 74 65 2c 20 6e 42 79 74 65  (p, aByte, nByte
b3c0: 29 3b 0a 7d 0a 0a 23 69 66 20 53 51 4c 49 54 45  );.}..#if SQLITE
b3d0: 5f 4d 41 58 5f 4d 4d 41 50 5f 53 49 5a 45 3e 30  _MAX_MMAP_SIZE>0
b3e0: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66 69 72 73 74  ./*.** The first
b3f0: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 61 20 66   argument is a f
b400: 69 6c 65 2d 68 61 6e 64 6c 65 20 6f 70 65 6e 20  ile-handle open 
b410: 6f 6e 20 61 20 74 65 6d 70 6f 72 61 72 79 20 66  on a temporary f
b420: 69 6c 65 2e 20 54 68 65 20 66 69 6c 65 0a 2a 2a  ile. The file.**
b430: 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 74   is guaranteed t
b440: 6f 20 62 65 20 6e 42 79 74 65 20 62 79 74 65 73  o be nByte bytes
b450: 20 6f 72 20 73 6d 61 6c 6c 65 72 20 69 6e 20 73   or smaller in s
b460: 69 7a 65 2e 20 54 68 69 73 20 66 75 6e 63 74 69  ize. This functi
b470: 6f 6e 0a 2a 2a 20 61 74 74 65 6d 70 74 73 20 74  on.** attempts t
b480: 6f 20 65 78 74 65 6e 64 20 74 68 65 20 66 69 6c  o extend the fil
b490: 65 20 74 6f 20 6e 42 79 74 65 20 62 79 74 65 73  e to nByte bytes
b4a0: 20 69 6e 20 73 69 7a 65 20 61 6e 64 20 74 6f 20   in size and to 
b4b0: 65 6e 73 75 72 65 20 74 68 61 74 0a 2a 2a 20 74  ensure that.** t
b4c0: 68 65 20 56 46 53 20 68 61 73 20 6d 65 6d 6f 72  he VFS has memor
b4d0: 79 20 6d 61 70 70 65 64 20 69 74 2e 0a 2a 2a 0a  y mapped it..**.
b4e0: 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e 6f  ** Whether or no
b4f0: 74 20 74 68 65 20 66 69 6c 65 20 64 6f 65 73 20  t the file does 
b500: 65 6e 64 20 75 70 20 6d 65 6d 6f 72 79 20 6d 61  end up memory ma
b510: 70 70 65 64 20 6f 66 20 63 6f 75 72 73 65 20 64  pped of course d
b520: 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20 74 68 65  epends on.** the
b530: 20 73 70 65 63 69 66 69 63 20 56 46 53 20 69 6d   specific VFS im
b540: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f  plementation..*/
b550: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62  .static void vdb
b560: 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46 69 6c  eSorterExtendFil
b570: 65 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 73  e(sqlite3 *db, s
b580: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
b590: 6c 65 2c 20 69 36 34 20 6e 42 79 74 65 29 7b 0a  le, i64 nByte){.
b5a0: 20 20 69 66 28 20 6e 42 79 74 65 3c 3d 28 69 36    if( nByte<=(i6
b5b0: 34 29 28 64 62 2d 3e 6e 4d 61 78 53 6f 72 74 65  4)(db->nMaxSorte
b5c0: 72 4d 6d 61 70 29 20 29 7b 0a 20 20 20 20 69 6e  rMmap) ){.    in
b5d0: 74 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73  t rc = sqlite3Os
b5e0: 54 72 75 6e 63 61 74 65 28 70 46 69 6c 65 2c 20  Truncate(pFile, 
b5f0: 6e 42 79 74 65 29 3b 0a 20 20 20 20 69 66 28 20  nByte);.    if( 
b600: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
b610: 0a 20 20 20 20 20 20 76 6f 69 64 20 2a 70 20 3d  .      void *p =
b620: 20 30 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   0;.      sqlite
b630: 33 4f 73 46 65 74 63 68 28 70 46 69 6c 65 2c 20  3OsFetch(pFile, 
b640: 30 2c 20 6e 42 79 74 65 2c 20 26 70 29 3b 0a 20  0, nByte, &p);. 
b650: 20 20 20 20 20 73 71 6c 69 74 65 33 4f 73 55 6e       sqlite3OsUn
b660: 66 65 74 63 68 28 70 46 69 6c 65 2c 20 30 2c 20  fetch(pFile, 0, 
b670: 70 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a  p);.    }.  }.}.
b680: 23 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 76  #else.# define v
b690: 64 62 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46  dbeSorterExtendF
b6a0: 69 6c 65 28 78 2c 79 2c 7a 29 20 53 51 4c 49 54  ile(x,y,z) SQLIT
b6b0: 45 5f 4f 4b 0a 23 65 6e 64 69 66 0a 0a 0a 2f 2a  E_OK.#endif.../*
b6c0: 0a 2a 2a 20 57 72 69 74 65 20 74 68 65 20 63 75  .** Write the cu
b6d0: 72 72 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f  rrent contents o
b6e0: 66 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 6e 6b  f in-memory link
b6f0: 65 64 2d 6c 69 73 74 20 70 4c 69 73 74 20 74 6f  ed-list pList to
b700: 20 61 20 6c 65 76 65 6c 2d 30 0a 2a 2a 20 50 4d   a level-0.** PM
b710: 41 20 69 6e 20 74 68 65 20 74 65 6d 70 20 66 69  A in the temp fi
b720: 6c 65 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20  le belonging to 
b730: 73 75 62 2d 74 61 73 6b 20 70 54 61 73 6b 2e 20  sub-task pTask. 
b740: 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  Return SQLITE_OK
b750: 20 69 66 20 0a 2a 2a 20 73 75 63 63 65 73 73 66   if .** successf
b760: 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65  ul, or an SQLite
b770: 20 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65   error code othe
b780: 72 77 69 73 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  rwise..**.** The
b790: 20 66 6f 72 6d 61 74 20 6f 66 20 61 20 50 4d 41   format of a PMA
b7a0: 20 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a   is:.**.**     *
b7b0: 20 41 20 76 61 72 69 6e 74 2e 20 54 68 69 73 20   A varint. This 
b7c0: 76 61 72 69 6e 74 20 63 6f 6e 74 61 69 6e 73 20  varint contains 
b7d0: 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72  the total number
b7e0: 20 6f 66 20 62 79 74 65 73 20 6f 66 20 63 6f 6e   of bytes of con
b7f0: 74 65 6e 74 0a 2a 2a 20 20 20 20 20 20 20 69 6e  tent.**       in
b800: 20 74 68 65 20 50 4d 41 20 28 6e 6f 74 20 69 6e   the PMA (not in
b810: 63 6c 75 64 69 6e 67 20 74 68 65 20 76 61 72 69  cluding the vari
b820: 6e 74 20 69 74 73 65 6c 66 29 2e 0a 2a 2a 0a 2a  nt itself)..**.*
b830: 2a 20 20 20 20 20 2a 20 4f 6e 65 20 6f 72 20 6d  *     * One or m
b840: 6f 72 65 20 72 65 63 6f 72 64 73 20 70 61 63 6b  ore records pack
b850: 65 64 20 65 6e 64 2d 74 6f 2d 65 6e 64 20 69 6e  ed end-to-end in
b860: 20 6f 72 64 65 72 20 6f 66 20 61 73 63 65 6e 64   order of ascend
b870: 69 6e 67 20 6b 65 79 73 2e 20 0a 2a 2a 20 20 20  ing keys. .**   
b880: 20 20 20 20 45 61 63 68 20 72 65 63 6f 72 64 20      Each record 
b890: 63 6f 6e 73 69 73 74 73 20 6f 66 20 61 20 76 61  consists of a va
b8a0: 72 69 6e 74 20 66 6f 6c 6c 6f 77 65 64 20 62 79  rint followed by
b8b0: 20 61 20 62 6c 6f 62 20 6f 66 20 64 61 74 61 20   a blob of data 
b8c0: 28 74 68 65 20 0a 2a 2a 20 20 20 20 20 20 20 6b  (the .**       k
b8d0: 65 79 29 2e 20 54 68 65 20 76 61 72 69 6e 74 20  ey). The varint 
b8e0: 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  is the number of
b8f0: 20 62 79 74 65 73 20 69 6e 20 74 68 65 20 62 6c   bytes in the bl
b900: 6f 62 20 6f 66 20 64 61 74 61 2e 0a 2a 2f 0a 73  ob of data..*/.s
b910: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
b920: 72 74 65 72 4c 69 73 74 54 6f 50 4d 41 28 53 6f  rterListToPMA(So
b930: 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b  rtSubtask *pTask
b940: 2c 20 53 6f 72 74 65 72 4c 69 73 74 20 2a 70 4c  , SorterList *pL
b950: 69 73 74 29 7b 0a 20 20 73 71 6c 69 74 65 33 20  ist){.  sqlite3 
b960: 2a 64 62 20 3d 20 70 54 61 73 6b 2d 3e 70 53 6f  *db = pTask->pSo
b970: 72 74 65 72 2d 3e 64 62 3b 0a 20 20 69 6e 74 20  rter->db;.  int 
b980: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20  rc = SQLITE_OK; 
b990: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
b9a0: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
b9b0: 50 6d 61 57 72 69 74 65 72 20 77 72 69 74 65 72  PmaWriter writer
b9c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
b9d0: 2f 2a 20 4f 62 6a 65 63 74 20 75 73 65 64 20 74  /* Object used t
b9e0: 6f 20 77 72 69 74 65 20 74 6f 20 74 68 65 20 66  o write to the f
b9f0: 69 6c 65 20 2a 2f 0a 0a 23 69 66 64 65 66 20 53  ile */..#ifdef S
ba00: 51 4c 49 54 45 5f 44 45 42 55 47 0a 20 20 2f 2a  QLITE_DEBUG.  /*
ba10: 20 53 65 74 20 69 53 7a 20 74 6f 20 74 68 65 20   Set iSz to the 
ba20: 65 78 70 65 63 74 65 64 20 73 69 7a 65 20 6f 66  expected size of
ba30: 20 66 69 6c 65 20 70 54 61 73 6b 2d 3e 66 69 6c   file pTask->fil
ba40: 65 20 61 66 74 65 72 20 77 72 69 74 69 6e 67 20  e after writing 
ba50: 74 68 65 20 50 4d 41 2e 20 0a 20 20 2a 2a 20 54  the PMA. .  ** T
ba60: 68 69 73 20 69 73 20 75 73 65 64 20 62 79 20 61  his is used by a
ba70: 6e 20 61 73 73 65 72 74 28 29 20 73 74 61 74 65  n assert() state
ba80: 6d 65 6e 74 20 61 74 20 74 68 65 20 65 6e 64 20  ment at the end 
ba90: 6f 66 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  of this function
baa0: 2e 20 20 2a 2f 0a 20 20 69 36 34 20 69 53 7a 20  .  */.  i64 iSz 
bab0: 3d 20 70 4c 69 73 74 2d 3e 73 7a 50 4d 41 20 2b  = pList->szPMA +
bac0: 20 73 71 6c 69 74 65 33 56 61 72 69 6e 74 4c 65   sqlite3VarintLe
bad0: 6e 28 70 4c 69 73 74 2d 3e 73 7a 50 4d 41 29 20  n(pList->szPMA) 
bae0: 2b 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45  + pTask->file.iE
baf0: 6f 66 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 76 64  of;.#endif..  vd
bb00: 62 65 53 6f 72 74 65 72 57 6f 72 6b 44 65 62 75  beSorterWorkDebu
bb10: 67 28 70 54 61 73 6b 2c 20 22 65 6e 74 65 72 22  g(pTask, "enter"
bb20: 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 77 72 69  );.  memset(&wri
bb30: 74 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50  ter, 0, sizeof(P
bb40: 6d 61 57 72 69 74 65 72 29 29 3b 0a 20 20 61 73  maWriter));.  as
bb50: 73 65 72 74 28 20 70 4c 69 73 74 2d 3e 73 7a 50  sert( pList->szP
bb60: 4d 41 3e 30 20 29 3b 0a 0a 20 20 2f 2a 20 49 66  MA>0 );..  /* If
bb70: 20 74 68 65 20 66 69 72 73 74 20 74 65 6d 70 6f   the first tempo
bb80: 72 61 72 79 20 50 4d 41 20 66 69 6c 65 20 68 61  rary PMA file ha
bb90: 73 20 6e 6f 74 20 62 65 65 6e 20 6f 70 65 6e 65  s not been opene
bba0: 64 2c 20 6f 70 65 6e 20 69 74 20 6e 6f 77 2e 20  d, open it now. 
bbb0: 2a 2f 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e  */.  if( pTask->
bbc0: 66 69 6c 65 2e 70 46 64 3d 3d 30 20 29 7b 0a 20  file.pFd==0 ){. 
bbd0: 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74     rc = vdbeSort
bbe0: 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 64  erOpenTempFile(d
bbf0: 62 2d 3e 70 56 66 73 2c 20 26 70 54 61 73 6b 2d  b->pVfs, &pTask-
bc00: 3e 66 69 6c 65 2e 70 46 64 29 3b 0a 20 20 20 20  >file.pFd);.    
bc10: 61 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49  assert( rc!=SQLI
bc20: 54 45 5f 4f 4b 20 7c 7c 20 70 54 61 73 6b 2d 3e  TE_OK || pTask->
bc30: 66 69 6c 65 2e 70 46 64 20 29 3b 0a 20 20 20 20  file.pFd );.    
bc40: 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 66  assert( pTask->f
bc50: 69 6c 65 2e 69 45 6f 66 3d 3d 30 20 29 3b 0a 20  ile.iEof==0 );. 
bc60: 20 20 20 61 73 73 65 72 74 28 20 70 54 61 73 6b     assert( pTask
bc70: 2d 3e 6e 50 4d 41 3d 3d 30 20 29 3b 0a 20 20 7d  ->nPMA==0 );.  }
bc80: 0a 0a 20 20 2f 2a 20 54 72 79 20 74 6f 20 67 65  ..  /* Try to ge
bc90: 74 20 74 68 65 20 66 69 6c 65 20 74 6f 20 6d 65  t the file to me
bca0: 6d 6f 72 79 20 6d 61 70 20 2a 2f 0a 20 20 69 66  mory map */.  if
bcb0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
bcc0: 29 7b 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65  ){.    vdbeSorte
bcd0: 72 45 78 74 65 6e 64 46 69 6c 65 28 64 62 2c 20  rExtendFile(db, 
bce0: 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64 2c  pTask->file.pFd,
bcf0: 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f   pTask->file.iEo
bd00: 66 2b 70 4c 69 73 74 2d 3e 73 7a 50 4d 41 2b 39  f+pList->szPMA+9
bd10: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 6f 72  );.  }..  /* Sor
bd20: 74 20 74 68 65 20 6c 69 73 74 20 2a 2f 0a 20 20  t the list */.  
bd30: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
bd40: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64  K ){.    rc = vd
bd50: 62 65 53 6f 72 74 65 72 53 6f 72 74 28 70 54 61  beSorterSort(pTa
bd60: 73 6b 2c 20 70 4c 69 73 74 29 3b 0a 20 20 7d 0a  sk, pList);.  }.
bd70: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
bd80: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 53 6f 72 74  E_OK ){.    Sort
bd90: 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a 20 20 20  erRecord *p;.   
bda0: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
bdb0: 4e 65 78 74 20 3d 20 30 3b 0a 0a 20 20 20 20 76  Next = 0;..    v
bdc0: 64 62 65 50 6d 61 57 72 69 74 65 72 49 6e 69 74  dbePmaWriterInit
bdd0: 28 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64  (pTask->file.pFd
bde0: 2c 20 26 77 72 69 74 65 72 2c 20 70 54 61 73 6b  , &writer, pTask
bdf0: 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 67 73 7a 2c  ->pSorter->pgsz,
be00: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
be10: 20 20 20 20 20 20 20 70 54 61 73 6b 2d 3e 66 69         pTask->fi
be20: 6c 65 2e 69 45 6f 66 29 3b 0a 20 20 20 20 70 54  le.iEof);.    pT
be30: 61 73 6b 2d 3e 6e 50 4d 41 2b 2b 3b 0a 20 20 20  ask->nPMA++;.   
be40: 20 76 64 62 65 50 6d 61 57 72 69 74 65 56 61 72   vdbePmaWriteVar
be50: 69 6e 74 28 26 77 72 69 74 65 72 2c 20 70 4c 69  int(&writer, pLi
be60: 73 74 2d 3e 73 7a 50 4d 41 29 3b 0a 20 20 20 20  st->szPMA);.    
be70: 66 6f 72 28 70 3d 70 4c 69 73 74 2d 3e 70 4c 69  for(p=pList->pLi
be80: 73 74 3b 20 70 3b 20 70 3d 70 4e 65 78 74 29 7b  st; p; p=pNext){
be90: 0a 20 20 20 20 20 20 70 4e 65 78 74 20 3d 20 70  .      pNext = p
bea0: 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20 20 20 20 20  ->u.pNext;.     
beb0: 20 76 64 62 65 50 6d 61 57 72 69 74 65 56 61 72   vdbePmaWriteVar
bec0: 69 6e 74 28 26 77 72 69 74 65 72 2c 20 70 2d 3e  int(&writer, p->
bed0: 6e 56 61 6c 29 3b 0a 20 20 20 20 20 20 76 64 62  nVal);.      vdb
bee0: 65 50 6d 61 57 72 69 74 65 42 6c 6f 62 28 26 77  ePmaWriteBlob(&w
bef0: 72 69 74 65 72 2c 20 53 52 56 41 4c 28 70 29 2c  riter, SRVAL(p),
bf00: 20 70 2d 3e 6e 56 61 6c 29 3b 0a 20 20 20 20 20   p->nVal);.     
bf10: 20 69 66 28 20 70 4c 69 73 74 2d 3e 61 4d 65 6d   if( pList->aMem
bf20: 6f 72 79 3d 3d 30 20 29 20 73 71 6c 69 74 65 33  ory==0 ) sqlite3
bf30: 5f 66 72 65 65 28 70 29 3b 0a 20 20 20 20 7d 0a  _free(p);.    }.
bf40: 20 20 20 20 70 4c 69 73 74 2d 3e 70 4c 69 73 74      pList->pList
bf50: 20 3d 20 70 3b 0a 20 20 20 20 72 63 20 3d 20 76   = p;.    rc = v
bf60: 64 62 65 50 6d 61 57 72 69 74 65 72 46 69 6e 69  dbePmaWriterFini
bf70: 73 68 28 26 77 72 69 74 65 72 2c 20 26 70 54 61  sh(&writer, &pTa
bf80: 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 29 3b 0a  sk->file.iEof);.
bf90: 20 20 7d 0a 0a 20 20 76 64 62 65 53 6f 72 74 65    }..  vdbeSorte
bfa0: 72 57 6f 72 6b 44 65 62 75 67 28 70 54 61 73 6b  rWorkDebug(pTask
bfb0: 2c 20 22 65 78 69 74 22 29 3b 0a 20 20 61 73 73  , "exit");.  ass
bfc0: 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f  ert( rc!=SQLITE_
bfd0: 4f 4b 20 7c 7c 20 70 4c 69 73 74 2d 3e 70 4c 69  OK || pList->pLi
bfe0: 73 74 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  st==0 );.  asser
bff0: 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  t( rc!=SQLITE_OK
c000: 20 7c 7c 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e   || pTask->file.
c010: 69 45 6f 66 3d 3d 69 53 7a 20 29 3b 0a 20 20 72  iEof==iSz );.  r
c020: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
c030: 2a 2a 20 41 64 76 61 6e 63 65 20 74 68 65 20 4d  ** Advance the M
c040: 65 72 67 65 45 6e 67 69 6e 65 20 69 74 65 72 61  ergeEngine itera
c050: 74 6f 72 20 70 61 73 73 65 64 20 61 73 20 74 68  tor passed as th
c060: 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e  e second argumen
c070: 74 20 74 6f 0a 2a 2a 20 74 68 65 20 6e 65 78 74  t to.** the next
c080: 20 65 6e 74 72 79 2e 20 53 65 74 20 2a 70 62 45   entry. Set *pbE
c090: 6f 66 20 74 6f 20 74 72 75 65 20 69 66 20 74 68  of to true if th
c0a0: 69 73 20 6d 65 61 6e 73 20 74 68 65 20 69 74 65  is means the ite
c0b0: 72 61 74 6f 72 20 68 61 73 20 0a 2a 2a 20 72 65  rator has .** re
c0c0: 61 63 68 65 64 20 45 4f 46 2e 0a 2a 2a 0a 2a 2a  ached EOF..**.**
c0d0: 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   Return SQLITE_O
c0e0: 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 20  K if successful 
c0f0: 6f 72 20 61 6e 20 65 72 72 6f 72 20 63 6f 64 65  or an error code
c100: 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   if an error occ
c110: 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  urs..*/.static i
c120: 6e 74 20 76 64 62 65 53 6f 72 74 65 72 4e 65 78  nt vdbeSorterNex
c130: 74 28 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b  t(.  SortSubtask
c140: 20 2a 70 54 61 73 6b 2c 20 0a 20 20 4d 65 72 67   *pTask, .  Merg
c150: 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67 65 72  eEngine *pMerger
c160: 2c 20 0a 20 20 69 6e 74 20 2a 70 62 45 6f 66 0a  , .  int *pbEof.
c170: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69  ){.  int rc;.  i
c180: 6e 74 20 69 50 72 65 76 20 3d 20 70 4d 65 72 67  nt iPrev = pMerg
c190: 65 72 2d 3e 61 54 72 65 65 5b 31 5d 3b 2f 2a 20  er->aTree[1];/* 
c1a0: 49 6e 64 65 78 20 6f 66 20 69 74 65 72 61 74 6f  Index of iterato
c1b0: 72 20 74 6f 20 61 64 76 61 6e 63 65 20 2a 2f 0a  r to advance */.
c1c0: 0a 20 20 2f 2a 20 41 64 76 61 6e 63 65 20 74 68  .  /* Advance th
c1d0: 65 20 63 75 72 72 65 6e 74 20 69 74 65 72 61 74  e current iterat
c1e0: 6f 72 20 2a 2f 0a 20 20 72 63 20 3d 20 76 64 62  or */.  rc = vdb
c1f0: 65 50 6d 61 52 65 61 64 65 72 4e 65 78 74 28 26  ePmaReaderNext(&
c200: 70 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 69  pMerger->aIter[i
c210: 50 72 65 76 5d 29 3b 0a 0a 20 20 2f 2a 20 55 70  Prev]);..  /* Up
c220: 64 61 74 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66  date contents of
c230: 20 61 54 72 65 65 5b 5d 20 2a 2f 0a 20 20 69 66   aTree[] */.  if
c240: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
c250: 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b 20 20 20  ){.    int i;   
c260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c270: 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 61     /* Index of a
c280: 54 72 65 65 5b 5d 20 74 6f 20 72 65 63 61 6c 63  Tree[] to recalc
c290: 75 6c 61 74 65 20 2a 2f 0a 20 20 20 20 50 6d 61  ulate */.    Pma
c2a0: 52 65 61 64 65 72 20 2a 70 49 74 65 72 31 3b 20  Reader *pIter1; 
c2b0: 20 20 20 20 2f 2a 20 46 69 72 73 74 20 69 74 65      /* First ite
c2c0: 72 61 74 6f 72 20 74 6f 20 63 6f 6d 70 61 72 65  rator to compare
c2d0: 20 2a 2f 0a 20 20 20 20 50 6d 61 52 65 61 64 65   */.    PmaReade
c2e0: 72 20 2a 70 49 74 65 72 32 3b 20 20 20 20 20 2f  r *pIter2;     /
c2f0: 2a 20 53 65 63 6f 6e 64 20 69 74 65 72 61 74 6f  * Second iterato
c300: 72 20 74 6f 20 63 6f 6d 70 61 72 65 20 2a 2f 0a  r to compare */.
c310: 20 20 20 20 75 38 20 2a 70 4b 65 79 32 3b 20 20      u8 *pKey2;  
c320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c330: 2f 2a 20 54 6f 20 70 49 74 65 72 32 2d 3e 61 4b  /* To pIter2->aK
c340: 65 79 2c 20 6f 72 20 30 20 69 66 20 72 65 63 6f  ey, or 0 if reco
c350: 72 64 20 63 61 63 68 65 64 20 2a 2f 0a 0a 20 20  rd cached */..  
c360: 20 20 2f 2a 20 46 69 6e 64 20 74 68 65 20 66 69    /* Find the fi
c370: 72 73 74 20 74 77 6f 20 69 74 65 72 61 74 6f 72  rst two iterator
c380: 73 20 74 6f 20 63 6f 6d 70 61 72 65 2e 20 54 68  s to compare. Th
c390: 65 20 6f 6e 65 20 74 68 61 74 20 77 61 73 20 6a  e one that was j
c3a0: 75 73 74 0a 20 20 20 20 2a 2a 20 61 64 76 61 6e  ust.    ** advan
c3b0: 63 65 64 20 28 69 50 72 65 76 29 20 61 6e 64 20  ced (iPrev) and 
c3c0: 74 68 65 20 6f 6e 65 20 6e 65 78 74 20 74 6f 20  the one next to 
c3d0: 69 74 20 69 6e 20 74 68 65 20 61 72 72 61 79 2e  it in the array.
c3e0: 20 20 2a 2f 0a 20 20 20 20 70 49 74 65 72 31 20    */.    pIter1 
c3f0: 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65  = &pMerger->aIte
c400: 72 5b 28 69 50 72 65 76 20 26 20 30 78 46 46 46  r[(iPrev & 0xFFF
c410: 45 29 5d 3b 0a 20 20 20 20 70 49 74 65 72 32 20  E)];.    pIter2 
c420: 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65  = &pMerger->aIte
c430: 72 5b 28 69 50 72 65 76 20 7c 20 30 78 30 30 30  r[(iPrev | 0x000
c440: 31 29 5d 3b 0a 20 20 20 20 70 4b 65 79 32 20 3d  1)];.    pKey2 =
c450: 20 70 49 74 65 72 32 2d 3e 61 4b 65 79 3b 0a 0a   pIter2->aKey;..
c460: 20 20 20 20 66 6f 72 28 69 3d 28 70 4d 65 72 67      for(i=(pMerg
c470: 65 72 2d 3e 6e 54 72 65 65 2b 69 50 72 65 76 29  er->nTree+iPrev)
c480: 2f 32 3b 20 69 3e 30 3b 20 69 3d 69 2f 32 29 7b  /2; i>0; i=i/2){
c490: 0a 20 20 20 20 20 20 2f 2a 20 43 6f 6d 70 61 72  .      /* Compar
c4a0: 65 20 70 49 74 65 72 31 20 61 6e 64 20 70 49 74  e pIter1 and pIt
c4b0: 65 72 32 2e 20 53 74 6f 72 65 20 74 68 65 20 72  er2. Store the r
c4c0: 65 73 75 6c 74 20 69 6e 20 76 61 72 69 61 62 6c  esult in variabl
c4d0: 65 20 69 52 65 73 2e 20 2a 2f 0a 20 20 20 20 20  e iRes. */.     
c4e0: 20 69 6e 74 20 69 52 65 73 3b 0a 20 20 20 20 20   int iRes;.     
c4f0: 20 69 66 28 20 70 49 74 65 72 31 2d 3e 70 46 69   if( pIter1->pFi
c500: 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  le==0 ){.       
c510: 20 69 52 65 73 20 3d 20 2b 31 3b 0a 20 20 20 20   iRes = +1;.    
c520: 20 20 7d 65 6c 73 65 20 69 66 28 20 70 49 74 65    }else if( pIte
c530: 72 32 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a  r2->pFile==0 ){.
c540: 20 20 20 20 20 20 20 20 69 52 65 73 20 3d 20 2d          iRes = -
c550: 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  1;.      }else{.
c560: 20 20 20 20 20 20 20 20 69 52 65 73 20 3d 20 76          iRes = v
c570: 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65  dbeSorterCompare
c580: 28 70 54 61 73 6b 2c 20 0a 20 20 20 20 20 20 20  (pTask, .       
c590: 20 20 20 20 20 70 49 74 65 72 31 2d 3e 61 4b 65       pIter1->aKe
c5a0: 79 2c 20 70 49 74 65 72 31 2d 3e 6e 4b 65 79 2c  y, pIter1->nKey,
c5b0: 20 70 4b 65 79 32 2c 20 70 49 74 65 72 32 2d 3e   pKey2, pIter2->
c5c0: 6e 4b 65 79 0a 20 20 20 20 20 20 20 20 29 3b 0a  nKey.        );.
c5d0: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f        }..      /
c5e0: 2a 20 49 66 20 70 49 74 65 72 31 20 63 6f 6e 74  * If pIter1 cont
c5f0: 61 69 6e 65 64 20 74 68 65 20 73 6d 61 6c 6c 65  ained the smalle
c600: 72 20 76 61 6c 75 65 2c 20 73 65 74 20 61 54 72  r value, set aTr
c610: 65 65 5b 69 5d 20 74 6f 20 69 74 73 20 69 6e 64  ee[i] to its ind
c620: 65 78 2e 0a 20 20 20 20 20 20 2a 2a 20 54 68 65  ex..      ** The
c630: 6e 20 73 65 74 20 70 49 74 65 72 32 20 74 6f 20  n set pIter2 to 
c640: 74 68 65 20 6e 65 78 74 20 69 74 65 72 61 74 6f  the next iterato
c650: 72 20 74 6f 20 63 6f 6d 70 61 72 65 20 74 6f 20  r to compare to 
c660: 70 49 74 65 72 31 2e 20 49 6e 20 74 68 69 73 0a  pIter1. In this.
c670: 20 20 20 20 20 20 2a 2a 20 63 61 73 65 20 74 68        ** case th
c680: 65 72 65 20 69 73 20 6e 6f 20 63 61 63 68 65 20  ere is no cache 
c690: 6f 66 20 70 49 74 65 72 32 20 69 6e 20 70 54 61  of pIter2 in pTa
c6a0: 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 2c 20 73  sk->pUnpacked, s
c6b0: 6f 20 73 65 74 0a 20 20 20 20 20 20 2a 2a 20 70  o set.      ** p
c6c0: 4b 65 79 32 20 74 6f 20 70 6f 69 6e 74 20 74 6f  Key2 to point to
c6d0: 20 74 68 65 20 72 65 63 6f 72 64 20 62 65 6c 6f   the record belo
c6e0: 6e 67 69 6e 67 20 74 6f 20 70 49 74 65 72 32 2e  nging to pIter2.
c6f0: 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20  .      **.      
c700: 2a 2a 20 41 6c 74 65 72 6e 61 74 69 76 65 6c 79  ** Alternatively
c710: 2c 20 69 66 20 70 49 74 65 72 32 20 63 6f 6e 74  , if pIter2 cont
c720: 61 69 6e 73 20 74 68 65 20 73 6d 61 6c 6c 65 72  ains the smaller
c730: 20 6f 66 20 74 68 65 20 74 77 6f 20 76 61 6c 75   of the two valu
c740: 65 73 2c 0a 20 20 20 20 20 20 2a 2a 20 73 65 74  es,.      ** set
c750: 20 61 54 72 65 65 5b 69 5d 20 74 6f 20 69 74 73   aTree[i] to its
c760: 20 69 6e 64 65 78 20 61 6e 64 20 75 70 64 61 74   index and updat
c770: 65 20 70 49 74 65 72 31 2e 20 49 66 20 76 64 62  e pIter1. If vdb
c780: 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 29  eSorterCompare()
c790: 0a 20 20 20 20 20 20 2a 2a 20 77 61 73 20 61 63  .      ** was ac
c7a0: 74 75 61 6c 6c 79 20 63 61 6c 6c 65 64 20 61 62  tually called ab
c7b0: 6f 76 65 2c 20 74 68 65 6e 20 70 54 61 73 6b 2d  ove, then pTask-
c7c0: 3e 70 55 6e 70 61 63 6b 65 64 20 6e 6f 77 20 63  >pUnpacked now c
c7d0: 6f 6e 74 61 69 6e 73 0a 20 20 20 20 20 20 2a 2a  ontains.      **
c7e0: 20 61 20 76 61 6c 75 65 20 65 71 75 69 76 61 6c   a value equival
c7f0: 65 6e 74 20 74 6f 20 70 49 74 65 72 32 2e 20 53  ent to pIter2. S
c800: 6f 20 73 65 74 20 70 4b 65 79 32 20 74 6f 20 4e  o set pKey2 to N
c810: 55 4c 4c 20 74 6f 20 70 72 65 76 65 6e 74 0a 20  ULL to prevent. 
c820: 20 20 20 20 20 2a 2a 20 76 64 62 65 53 6f 72 74       ** vdbeSort
c830: 65 72 43 6f 6d 70 61 72 65 28 29 20 66 72 6f 6d  erCompare() from
c840: 20 64 65 63 6f 64 69 6e 67 20 70 49 74 65 72 32   decoding pIter2
c850: 20 61 67 61 69 6e 2e 0a 20 20 20 20 20 20 2a 2a   again..      **
c860: 0a 20 20 20 20 20 20 2a 2a 20 49 66 20 74 68 65  .      ** If the
c870: 20 74 77 6f 20 76 61 6c 75 65 73 20 77 65 72 65   two values were
c880: 20 65 71 75 61 6c 2c 20 74 68 65 6e 20 74 68 65   equal, then the
c890: 20 76 61 6c 75 65 20 66 72 6f 6d 20 74 68 65 20   value from the 
c8a0: 6f 6c 64 65 73 74 0a 20 20 20 20 20 20 2a 2a 20  oldest.      ** 
c8b0: 50 4d 41 20 73 68 6f 75 6c 64 20 62 65 20 63 6f  PMA should be co
c8c0: 6e 73 69 64 65 72 65 64 20 73 6d 61 6c 6c 65 72  nsidered smaller
c8d0: 2e 20 54 68 65 20 56 64 62 65 53 6f 72 74 65 72  . The VdbeSorter
c8e0: 2e 61 49 74 65 72 5b 5d 20 61 72 72 61 79 0a 20  .aIter[] array. 
c8f0: 20 20 20 20 20 2a 2a 20 69 73 20 73 6f 72 74 65       ** is sorte
c900: 64 20 66 72 6f 6d 20 6f 6c 64 65 73 74 20 74 6f  d from oldest to
c910: 20 6e 65 77 65 73 74 2c 20 73 6f 20 70 49 74 65   newest, so pIte
c920: 72 31 20 63 6f 6e 74 61 69 6e 73 20 6f 6c 64 65  r1 contains olde
c930: 72 20 76 61 6c 75 65 73 0a 20 20 20 20 20 20 2a  r values.      *
c940: 2a 20 74 68 61 6e 20 70 49 74 65 72 32 20 69 66  * than pIter2 if
c950: 66 20 28 70 49 74 65 72 31 3c 70 49 74 65 72 32  f (pIter1<pIter2
c960: 29 2e 20 20 2a 2f 0a 20 20 20 20 20 20 69 66 28  ).  */.      if(
c970: 20 69 52 65 73 3c 30 20 7c 7c 20 28 69 52 65 73   iRes<0 || (iRes
c980: 3d 3d 30 20 26 26 20 70 49 74 65 72 31 3c 70 49  ==0 && pIter1<pI
c990: 74 65 72 32 29 20 29 7b 0a 20 20 20 20 20 20 20  ter2) ){.       
c9a0: 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b   pMerger->aTree[
c9b0: 69 5d 20 3d 20 28 69 6e 74 29 28 70 49 74 65 72  i] = (int)(pIter
c9c0: 31 20 2d 20 70 4d 65 72 67 65 72 2d 3e 61 49 74  1 - pMerger->aIt
c9d0: 65 72 29 3b 0a 20 20 20 20 20 20 20 20 70 49 74  er);.        pIt
c9e0: 65 72 32 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e  er2 = &pMerger->
c9f0: 61 49 74 65 72 5b 20 70 4d 65 72 67 65 72 2d 3e  aIter[ pMerger->
ca00: 61 54 72 65 65 5b 69 20 5e 20 30 78 30 30 30 31  aTree[i ^ 0x0001
ca10: 5d 20 5d 3b 0a 20 20 20 20 20 20 20 20 70 4b 65  ] ];.        pKe
ca20: 79 32 20 3d 20 70 49 74 65 72 32 2d 3e 61 4b 65  y2 = pIter2->aKe
ca30: 79 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  y;.      }else{.
ca40: 20 20 20 20 20 20 20 20 69 66 28 20 70 49 74 65          if( pIte
ca50: 72 31 2d 3e 70 46 69 6c 65 20 29 20 70 4b 65 79  r1->pFile ) pKey
ca60: 32 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 70  2 = 0;.        p
ca70: 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 5d  Merger->aTree[i]
ca80: 20 3d 20 28 69 6e 74 29 28 70 49 74 65 72 32 20   = (int)(pIter2 
ca90: 2d 20 70 4d 65 72 67 65 72 2d 3e 61 49 74 65 72  - pMerger->aIter
caa0: 29 3b 0a 20 20 20 20 20 20 20 20 70 49 74 65 72  );.        pIter
cab0: 31 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49  1 = &pMerger->aI
cac0: 74 65 72 5b 20 70 4d 65 72 67 65 72 2d 3e 61 54  ter[ pMerger->aT
cad0: 72 65 65 5b 69 20 5e 20 30 78 30 30 30 31 5d 20  ree[i ^ 0x0001] 
cae0: 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  ];.      }.    }
caf0: 0a 20 20 20 20 2a 70 62 45 6f 66 20 3d 20 28 70  .    *pbEof = (p
cb00: 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 70 4d  Merger->aIter[pM
cb10: 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 31 5d 5d  erger->aTree[1]]
cb20: 2e 70 46 69 6c 65 3d 3d 30 29 3b 0a 20 20 7d 0a  .pFile==0);.  }.
cb30: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
cb40: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d 61 69 6e 20  ./*.** The main 
cb50: 72 6f 75 74 69 6e 65 20 66 6f 72 20 62 61 63 6b  routine for back
cb60: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 73 20 74  ground threads t
cb70: 68 61 74 20 77 72 69 74 65 20 6c 65 76 65 6c 2d  hat write level-
cb80: 30 20 50 4d 41 73 2e 0a 2a 2f 0a 73 74 61 74 69  0 PMAs..*/.stati
cb90: 63 20 76 6f 69 64 20 2a 76 64 62 65 53 6f 72 74  c void *vdbeSort
cba0: 65 72 46 6c 75 73 68 54 68 72 65 61 64 28 76 6f  erFlushThread(vo
cbb0: 69 64 20 2a 70 43 74 78 29 7b 0a 20 20 53 6f 72  id *pCtx){.  Sor
cbc0: 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 20  tSubtask *pTask 
cbd0: 3d 20 28 53 6f 72 74 53 75 62 74 61 73 6b 2a 29  = (SortSubtask*)
cbe0: 70 43 74 78 3b 0a 20 20 69 6e 74 20 72 63 3b 20  pCtx;.  int rc; 
cbf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cc00: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
cc10: 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 61 73 73 65  n code */.  asse
cc20: 72 74 28 20 70 54 61 73 6b 2d 3e 62 44 6f 6e 65  rt( pTask->bDone
cc30: 3d 3d 30 20 29 3b 0a 20 20 72 63 20 3d 20 76 64  ==0 );.  rc = vd
cc40: 62 65 53 6f 72 74 65 72 4c 69 73 74 54 6f 50 4d  beSorterListToPM
cc50: 41 28 70 54 61 73 6b 2c 20 26 70 54 61 73 6b 2d  A(pTask, &pTask-
cc60: 3e 6c 69 73 74 29 3b 0a 20 20 70 54 61 73 6b 2d  >list);.  pTask-
cc70: 3e 62 44 6f 6e 65 20 3d 20 31 3b 0a 20 20 72 65  >bDone = 1;.  re
cc80: 74 75 72 6e 20 53 51 4c 49 54 45 5f 49 4e 54 5f  turn SQLITE_INT_
cc90: 54 4f 5f 50 54 52 28 72 63 29 3b 0a 7d 0a 0a 2f  TO_PTR(rc);.}../
cca0: 2a 0a 2a 2a 20 46 6c 75 73 68 20 74 68 65 20 63  *.** Flush the c
ccb0: 75 72 72 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20  urrent contents 
ccc0: 6f 66 20 56 64 62 65 53 6f 72 74 65 72 2e 6c 69  of VdbeSorter.li
ccd0: 73 74 20 74 6f 20 61 20 6e 65 77 20 50 4d 41 2c  st to a new PMA,
cce0: 20 70 6f 73 73 69 62 6c 79 0a 2a 2a 20 75 73 69   possibly.** usi
ccf0: 6e 67 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20  ng a background 
cd00: 74 68 72 65 61 64 2e 0a 2a 2f 0a 73 74 61 74 69  thread..*/.stati
cd10: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72  c int vdbeSorter
cd20: 46 6c 75 73 68 50 4d 41 28 56 64 62 65 53 6f 72  FlushPMA(VdbeSor
cd30: 74 65 72 20 2a 70 53 6f 72 74 65 72 29 7b 0a 23  ter *pSorter){.#
cd40: 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f  if SQLITE_MAX_WO
cd50: 52 4b 45 52 5f 54 48 52 45 41 44 53 3d 3d 30 0a  RKER_THREADS==0.
cd60: 20 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 50    pSorter->bUseP
cd70: 4d 41 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e  MA = 1;.  return
cd80: 20 76 64 62 65 53 6f 72 74 65 72 4c 69 73 74 54   vdbeSorterListT
cd90: 6f 50 4d 41 28 26 70 53 6f 72 74 65 72 2d 3e 61  oPMA(&pSorter->a
cda0: 54 61 73 6b 5b 30 5d 2c 20 26 70 53 6f 72 74 65  Task[0], &pSorte
cdb0: 72 2d 3e 6c 69 73 74 29 3b 0a 23 65 6c 73 65 0a  r->list);.#else.
cdc0: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
cdd0: 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 69 3b 0a 20  E_OK;.  int i;. 
cde0: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
cdf0: 61 73 6b 20 3d 20 30 3b 20 20 20 20 2f 2a 20 54  ask = 0;    /* T
ce00: 68 72 65 61 64 20 63 6f 6e 74 65 78 74 20 75 73  hread context us
ce10: 65 64 20 74 6f 20 63 72 65 61 74 65 20 6e 65 77  ed to create new
ce20: 20 50 4d 41 20 2a 2f 0a 20 20 69 6e 74 20 6e 57   PMA */.  int nW
ce30: 6f 72 6b 65 72 20 3d 20 28 70 53 6f 72 74 65 72  orker = (pSorter
ce40: 2d 3e 6e 54 61 73 6b 2d 31 29 3b 0a 0a 20 20 2f  ->nTask-1);..  /
ce50: 2a 20 53 65 74 20 74 68 65 20 66 6c 61 67 20 74  * Set the flag t
ce60: 6f 20 69 6e 64 69 63 61 74 65 20 74 68 61 74 20  o indicate that 
ce70: 61 74 20 6c 65 61 73 74 20 6f 6e 65 20 50 4d 41  at least one PMA
ce80: 20 68 61 73 20 62 65 65 6e 20 77 72 69 74 74 65   has been writte
ce90: 6e 2e 20 0a 20 20 2a 2a 20 4f 72 20 77 69 6c 6c  n. .  ** Or will
cea0: 20 62 65 2c 20 61 6e 79 68 6f 77 2e 20 20 2a 2f   be, anyhow.  */
ceb0: 0a 20 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65  .  pSorter->bUse
cec0: 50 4d 41 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20 53  PMA = 1;..  /* S
ced0: 65 6c 65 63 74 20 61 20 73 75 62 2d 74 61 73 6b  elect a sub-task
cee0: 20 74 6f 20 73 6f 72 74 20 61 6e 64 20 66 6c 75   to sort and flu
cef0: 73 68 20 74 68 65 20 63 75 72 72 65 6e 74 20 6c  sh the current l
cf00: 69 73 74 20 6f 66 20 69 6e 2d 6d 65 6d 6f 72 79  ist of in-memory
cf10: 0a 20 20 2a 2a 20 72 65 63 6f 72 64 73 20 74 6f  .  ** records to
cf20: 20 64 69 73 6b 2e 20 49 66 20 74 68 65 20 73 6f   disk. If the so
cf30: 72 74 65 72 20 69 73 20 72 75 6e 6e 69 6e 67 20  rter is running 
cf40: 69 6e 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65  in multi-threade
cf50: 64 20 6d 6f 64 65 2c 0a 20 20 2a 2a 20 72 6f 75  d mode,.  ** rou
cf60: 6e 64 2d 72 6f 62 69 6e 20 62 65 74 77 65 65 6e  nd-robin between
cf70: 20 74 68 65 20 66 69 72 73 74 20 28 70 53 6f 72   the first (pSor
cf80: 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 20 74 61  ter->nTask-1) ta
cf90: 73 6b 73 2e 20 45 78 63 65 70 74 2c 20 69 66 0a  sks. Except, if.
cfa0: 20 20 2a 2a 20 74 68 65 20 62 61 63 6b 67 72 6f    ** the backgro
cfb0: 75 6e 64 20 74 68 72 65 61 64 20 66 72 6f 6d 20  und thread from 
cfc0: 61 20 73 75 62 2d 74 61 73 6b 73 20 70 72 65 76  a sub-tasks prev
cfd0: 69 6f 75 73 20 74 75 72 6e 20 69 73 20 73 74 69  ious turn is sti
cfe0: 6c 6c 20 72 75 6e 6e 69 6e 67 2c 0a 20 20 2a 2a  ll running,.  **
cff0: 20 73 6b 69 70 20 69 74 2e 20 49 66 20 74 68 65   skip it. If the
d000: 20 66 69 72 73 74 20 28 70 53 6f 72 74 65 72 2d   first (pSorter-
d010: 3e 6e 54 61 73 6b 2d 31 29 20 73 75 62 2d 74 61  >nTask-1) sub-ta
d020: 73 6b 73 20 61 72 65 20 61 6c 6c 20 73 74 69 6c  sks are all stil
d030: 6c 20 62 75 73 79 2c 0a 20 20 2a 2a 20 66 61 6c  l busy,.  ** fal
d040: 6c 20 62 61 63 6b 20 74 6f 20 75 73 69 6e 67 20  l back to using 
d050: 74 68 65 20 66 69 6e 61 6c 20 73 75 62 2d 74 61  the final sub-ta
d060: 73 6b 2e 20 54 68 65 20 66 69 72 73 74 20 28 70  sk. The first (p
d070: 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29  Sorter->nTask-1)
d080: 0a 20 20 2a 2a 20 73 75 62 2d 74 61 73 6b 73 20  .  ** sub-tasks 
d090: 61 72 65 20 70 72 65 66 65 72 65 64 20 61 73 20  are prefered as 
d0a0: 74 68 65 79 20 75 73 65 20 62 61 63 6b 67 72 6f  they use backgro
d0b0: 75 6e 64 20 74 68 72 65 61 64 73 20 2d 20 74 68  und threads - th
d0c0: 65 20 66 69 6e 61 6c 20 0a 20 20 2a 2a 20 73 75  e final .  ** su
d0d0: 62 2d 74 61 73 6b 20 75 73 65 73 20 74 68 65 20  b-task uses the 
d0e0: 6d 61 69 6e 20 74 68 72 65 61 64 2e 20 2a 2f 0a  main thread. */.
d0f0: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 57 6f    for(i=0; i<nWo
d100: 72 6b 65 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  rker; i++){.    
d110: 69 6e 74 20 69 54 65 73 74 20 3d 20 28 70 53 6f  int iTest = (pSo
d120: 72 74 65 72 2d 3e 69 50 72 65 76 20 2b 20 69 20  rter->iPrev + i 
d130: 2b 20 31 29 20 25 20 6e 57 6f 72 6b 65 72 3b 0a  + 1) % nWorker;.
d140: 20 20 20 20 70 54 61 73 6b 20 3d 20 26 70 53 6f      pTask = &pSo
d150: 72 74 65 72 2d 3e 61 54 61 73 6b 5b 69 54 65 73  rter->aTask[iTes
d160: 74 5d 3b 0a 20 20 20 20 69 66 28 20 70 54 61 73  t];.    if( pTas
d170: 6b 2d 3e 62 44 6f 6e 65 20 29 7b 0a 20 20 20 20  k->bDone ){.    
d180: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
d190: 72 4a 6f 69 6e 54 68 72 65 61 64 28 70 54 61 73  rJoinThread(pTas
d1a0: 6b 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  k);.    }.    if
d1b0: 28 20 70 54 61 73 6b 2d 3e 70 54 68 72 65 61 64  ( pTask->pThread
d1c0: 3d 3d 30 20 7c 7c 20 72 63 21 3d 53 51 4c 49 54  ==0 || rc!=SQLIT
d1d0: 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20  E_OK ) break;.  
d1e0: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
d1f0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 66  ITE_OK ){.    if
d200: 28 20 69 3d 3d 6e 57 6f 72 6b 65 72 20 29 7b 0a  ( i==nWorker ){.
d210: 20 20 20 20 20 20 2f 2a 20 55 73 65 20 74 68 65        /* Use the
d220: 20 66 6f 72 65 67 72 6f 75 6e 64 20 74 68 72 65   foreground thre
d230: 61 64 20 66 6f 72 20 74 68 69 73 20 6f 70 65 72  ad for this oper
d240: 61 74 69 6f 6e 20 2a 2f 0a 20 20 20 20 20 20 72  ation */.      r
d250: 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4c 69  c = vdbeSorterLi
d260: 73 74 54 6f 50 4d 41 28 26 70 53 6f 72 74 65 72  stToPMA(&pSorter
d270: 2d 3e 61 54 61 73 6b 5b 6e 57 6f 72 6b 65 72 5d  ->aTask[nWorker]
d280: 2c 20 26 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74  , &pSorter->list
d290: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
d2a0: 20 20 20 20 2f 2a 20 4c 61 75 6e 63 68 20 61 20      /* Launch a 
d2b0: 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61  background threa
d2c0: 64 20 66 6f 72 20 74 68 69 73 20 6f 70 65 72 61  d for this opera
d2d0: 74 69 6f 6e 20 2a 2f 0a 20 20 20 20 20 20 75 38  tion */.      u8
d2e0: 20 2a 61 4d 65 6d 20 3d 20 70 54 61 73 6b 2d 3e   *aMem = pTask->
d2f0: 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 3b 0a 20 20  list.aMemory;.  
d300: 20 20 20 20 76 6f 69 64 20 2a 70 43 74 78 20 3d      void *pCtx =
d310: 20 28 76 6f 69 64 2a 29 70 54 61 73 6b 3b 0a 0a   (void*)pTask;..
d320: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 54        assert( pT
d330: 61 73 6b 2d 3e 70 54 68 72 65 61 64 3d 3d 30 20  ask->pThread==0 
d340: 26 26 20 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 3d  && pTask->bDone=
d350: 3d 30 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65  =0 );.      asse
d360: 72 74 28 20 70 54 61 73 6b 2d 3e 6c 69 73 74 2e  rt( pTask->list.
d370: 70 4c 69 73 74 3d 3d 30 20 29 3b 0a 20 20 20 20  pList==0 );.    
d380: 20 20 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d    assert( pTask-
d390: 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30  >list.aMemory==0
d3a0: 20 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73   || pSorter->lis
d3b0: 74 2e 61 4d 65 6d 6f 72 79 21 3d 30 20 29 3b 0a  t.aMemory!=0 );.
d3c0: 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  .      pSorter->
d3d0: 69 50 72 65 76 20 3d 20 28 70 54 61 73 6b 20 2d  iPrev = (pTask -
d3e0: 20 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 29   pSorter->aTask)
d3f0: 3b 0a 20 20 20 20 20 20 70 54 61 73 6b 2d 3e 6c  ;.      pTask->l
d400: 69 73 74 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6c  ist = pSorter->l
d410: 69 73 74 3b 0a 20 20 20 20 20 20 70 53 6f 72 74  ist;.      pSort
d420: 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d  er->list.pList =
d430: 20 30 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65   0;.      pSorte
d440: 72 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 3d 20  r->list.szPMA = 
d450: 30 3b 0a 20 20 20 20 20 20 69 66 28 20 61 4d 65  0;.      if( aMe
d460: 6d 20 29 7b 0a 20 20 20 20 20 20 20 20 70 53 6f  m ){.        pSo
d470: 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f  rter->list.aMemo
d480: 72 79 20 3d 20 61 4d 65 6d 3b 0a 20 20 20 20 20  ry = aMem;.     
d490: 20 20 20 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d     pSorter->nMem
d4a0: 6f 72 79 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c  ory = sqlite3Mal
d4b0: 6c 6f 63 53 69 7a 65 28 61 4d 65 6d 29 3b 0a 20  locSize(aMem);. 
d4c0: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
d4d0: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73      pSorter->lis
d4e0: 74 2e 61 4d 65 6d 6f 72 79 20 3d 20 73 71 6c 69  t.aMemory = sqli
d4f0: 74 65 33 4d 61 6c 6c 6f 63 28 70 53 6f 72 74 65  te3Malloc(pSorte
d500: 72 2d 3e 6e 4d 65 6d 6f 72 79 29 3b 0a 20 20 20  r->nMemory);.   
d510: 20 20 20 20 20 69 66 28 20 21 70 53 6f 72 74 65       if( !pSorte
d520: 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20  r->list.aMemory 
d530: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
d540: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 7d 0a 0a  NOMEM;.      }..
d550: 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53        rc = vdbeS
d560: 6f 72 74 65 72 43 72 65 61 74 65 54 68 72 65 61  orterCreateThrea
d570: 64 28 70 54 61 73 6b 2c 20 76 64 62 65 53 6f 72  d(pTask, vdbeSor
d580: 74 65 72 46 6c 75 73 68 54 68 72 65 61 64 2c 20  terFlushThread, 
d590: 70 43 74 78 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  pCtx);.    }.  }
d5a0: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 23  ..  return rc;.#
d5b0: 65 6e 64 69 66 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  endif.}../*.** A
d5c0: 64 64 20 61 20 72 65 63 6f 72 64 20 74 6f 20 74  dd a record to t
d5d0: 68 65 20 73 6f 72 74 65 72 2e 0a 2a 2f 0a 69 6e  he sorter..*/.in
d5e0: 74 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72  t sqlite3VdbeSor
d5f0: 74 65 72 57 72 69 74 65 28 0a 20 20 73 71 6c 69  terWrite(.  sqli
d600: 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20  te3 *db,        
d610: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
d620: 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a  atabase handle *
d630: 2f 0a 20 20 63 6f 6e 73 74 20 56 64 62 65 43 75  /.  const VdbeCu
d640: 72 73 6f 72 20 2a 70 43 73 72 2c 20 20 20 20 20  rsor *pCsr,     
d650: 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 63 75      /* Sorter cu
d660: 72 73 6f 72 20 2a 2f 0a 20 20 4d 65 6d 20 2a 70  rsor */.  Mem *p
d670: 56 61 6c 20 20 20 20 20 20 20 20 20 20 20 20 20  Val             
d680: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 65 6d            /* Mem
d690: 6f 72 79 20 63 65 6c 6c 20 63 6f 6e 74 61 69 6e  ory cell contain
d6a0: 69 6e 67 20 72 65 63 6f 72 64 20 2a 2f 0a 29 7b  ing record */.){
d6b0: 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70  .  VdbeSorter *p
d6c0: 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70  Sorter = pCsr->p
d6d0: 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 72 63  Sorter;.  int rc
d6e0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20   = SQLITE_OK;   
d6f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
d700: 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 53 6f  urn Code */.  So
d710: 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65 77  rterRecord *pNew
d720: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
d730: 20 4e 65 77 20 6c 69 73 74 20 65 6c 65 6d 65 6e   New list elemen
d740: 74 20 2a 2f 0a 0a 20 20 69 6e 74 20 62 46 6c 75  t */..  int bFlu
d750: 73 68 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  sh;             
d760: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
d770: 74 6f 20 66 6c 75 73 68 20 63 6f 6e 74 65 6e 74  to flush content
d780: 73 20 6f 66 20 6d 65 6d 6f 72 79 20 74 6f 20 50  s of memory to P
d790: 4d 41 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 71  MA */.  int nReq
d7a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
d7b0: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
d7c0: 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71 75 69   of memory requi
d7d0: 72 65 64 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 4d  red */.  int nPM
d7e0: 41 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  A;              
d7f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65           /* Byte
d800: 73 20 6f 66 20 50 4d 41 20 73 70 61 63 65 20 72  s of PMA space r
d810: 65 71 75 69 72 65 64 20 2a 2f 0a 0a 20 20 61 73  equired */..  as
d820: 73 65 72 74 28 20 70 53 6f 72 74 65 72 20 29 3b  sert( pSorter );
d830: 0a 0a 20 20 2f 2a 20 46 69 67 75 72 65 20 6f 75  ..  /* Figure ou
d840: 74 20 77 68 65 74 68 65 72 20 6f 72 20 6e 6f 74  t whether or not
d850: 20 74 68 65 20 63 75 72 72 65 6e 74 20 63 6f 6e   the current con
d860: 74 65 6e 74 73 20 6f 66 20 6d 65 6d 6f 72 79 20  tents of memory 
d870: 73 68 6f 75 6c 64 20 62 65 0a 20 20 2a 2a 20 66  should be.  ** f
d880: 6c 75 73 68 65 64 20 74 6f 20 61 20 50 4d 41 20  lushed to a PMA 
d890: 62 65 66 6f 72 65 20 63 6f 6e 74 69 6e 75 69 6e  before continuin
d8a0: 67 2e 20 49 66 20 73 6f 2c 20 64 6f 20 73 6f 2e  g. If so, do so.
d8b0: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49 66 20 75 73  .  **.  ** If us
d8c0: 69 6e 67 20 74 68 65 20 73 69 6e 67 6c 65 20 6c  ing the single l
d8d0: 61 72 67 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20  arge allocation 
d8e0: 6d 6f 64 65 20 28 70 53 6f 72 74 65 72 2d 3e 61  mode (pSorter->a
d8f0: 4d 65 6d 6f 72 79 21 3d 30 29 2c 20 74 68 65 6e  Memory!=0), then
d900: 0a 20 20 2a 2a 20 66 6c 75 73 68 20 74 68 65 20  .  ** flush the 
d910: 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65 6d 6f  contents of memo
d920: 72 79 20 74 6f 20 61 20 6e 65 77 20 50 4d 41 20  ry to a new PMA 
d930: 69 66 20 28 61 29 20 61 74 20 6c 65 61 73 74 20  if (a) at least 
d940: 6f 6e 65 20 76 61 6c 75 65 20 69 73 0a 20 20 2a  one value is.  *
d950: 2a 20 61 6c 72 65 61 64 79 20 69 6e 20 6d 65 6d  * already in mem
d960: 6f 72 79 20 61 6e 64 20 28 62 29 20 74 68 65 20  ory and (b) the 
d970: 6e 65 77 20 76 61 6c 75 65 20 77 69 6c 6c 20 6e  new value will n
d980: 6f 74 20 66 69 74 20 69 6e 20 6d 65 6d 6f 72 79  ot fit in memory
d990: 2e 0a 20 20 2a 2a 20 0a 20 20 2a 2a 20 4f 72 2c  ..  ** .  ** Or,
d9a0: 20 69 66 20 75 73 69 6e 67 20 73 65 70 61 72 61   if using separa
d9b0: 74 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 20 66  te allocations f
d9c0: 6f 72 20 65 61 63 68 20 72 65 63 6f 72 64 2c 20  or each record, 
d9d0: 66 6c 75 73 68 20 74 68 65 20 63 6f 6e 74 65 6e  flush the conten
d9e0: 74 73 0a 20 20 2a 2a 20 6f 66 20 6d 65 6d 6f 72  ts.  ** of memor
d9f0: 79 20 74 6f 20 61 20 50 4d 41 20 69 66 20 65 69  y to a PMA if ei
da00: 74 68 65 72 20 6f 66 20 74 68 65 20 66 6f 6c 6c  ther of the foll
da10: 6f 77 69 6e 67 20 61 72 65 20 74 72 75 65 3a 0a  owing are true:.
da20: 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 54 68    **.  **   * Th
da30: 65 20 74 6f 74 61 6c 20 6d 65 6d 6f 72 79 20 61  e total memory a
da40: 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 74 68 65  llocated for the
da50: 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20   in-memory list 
da60: 69 73 20 67 72 65 61 74 65 72 20 0a 20 20 2a 2a  is greater .  **
da70: 20 20 20 20 20 74 68 61 6e 20 28 70 61 67 65 2d       than (page-
da80: 73 69 7a 65 20 2a 20 63 61 63 68 65 2d 73 69 7a  size * cache-siz
da90: 65 29 2c 20 6f 72 0a 20 20 2a 2a 0a 20 20 2a 2a  e), or.  **.  **
daa0: 20 20 20 2a 20 54 68 65 20 74 6f 74 61 6c 20 6d     * The total m
dab0: 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 65 64 20  emory allocated 
dac0: 66 6f 72 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72  for the in-memor
dad0: 79 20 6c 69 73 74 20 69 73 20 67 72 65 61 74 65  y list is greate
dae0: 72 20 0a 20 20 2a 2a 20 20 20 20 20 74 68 61 6e  r .  **     than
daf0: 20 28 70 61 67 65 2d 73 69 7a 65 20 2a 20 31 30   (page-size * 10
db00: 29 20 61 6e 64 20 73 71 6c 69 74 65 33 48 65 61  ) and sqlite3Hea
db10: 70 4e 65 61 72 6c 79 46 75 6c 6c 28 29 20 72 65  pNearlyFull() re
db20: 74 75 72 6e 73 20 74 72 75 65 2e 0a 20 20 2a 2f  turns true..  */
db30: 0a 20 20 6e 52 65 71 20 3d 20 70 56 61 6c 2d 3e  .  nReq = pVal->
db40: 6e 20 2b 20 73 69 7a 65 6f 66 28 53 6f 72 74 65  n + sizeof(Sorte
db50: 72 52 65 63 6f 72 64 29 3b 0a 20 20 6e 50 4d 41  rRecord);.  nPMA
db60: 20 3d 20 70 56 61 6c 2d 3e 6e 20 2b 20 73 71 6c   = pVal->n + sql
db70: 69 74 65 33 56 61 72 69 6e 74 4c 65 6e 28 70 56  ite3VarintLen(pV
db80: 61 6c 2d 3e 6e 29 3b 0a 20 20 69 66 28 20 70 53  al->n);.  if( pS
db90: 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65  orter->mxPmaSize
dba0: 20 29 7b 0a 20 20 20 20 69 66 28 20 70 53 6f 72   ){.    if( pSor
dbb0: 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72  ter->list.aMemor
dbc0: 79 20 29 7b 0a 20 20 20 20 20 20 62 46 6c 75 73  y ){.      bFlus
dbd0: 68 20 3d 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65  h = pSorter->iMe
dbe0: 6d 6f 72 79 20 26 26 20 28 70 53 6f 72 74 65 72  mory && (pSorter
dbf0: 2d 3e 69 4d 65 6d 6f 72 79 2b 6e 52 65 71 29 20  ->iMemory+nReq) 
dc00: 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61  > pSorter->mxPma
dc10: 53 69 7a 65 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  Size;.    }else{
dc20: 0a 20 20 20 20 20 20 62 46 6c 75 73 68 20 3d 20  .      bFlush = 
dc30: 28 0a 20 20 20 20 20 20 20 20 20 20 28 70 53 6f  (.          (pSo
dc40: 72 74 65 72 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41  rter->list.szPMA
dc50: 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d   > pSorter->mxPm
dc60: 61 53 69 7a 65 29 0a 20 20 20 20 20 20 20 7c 7c  aSize).       ||
dc70: 20 28 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e   (pSorter->list.
dc80: 73 7a 50 4d 41 20 3e 20 70 53 6f 72 74 65 72 2d  szPMA > pSorter-
dc90: 3e 6d 6e 50 6d 61 53 69 7a 65 20 26 26 20 73 71  >mnPmaSize && sq
dca0: 6c 69 74 65 33 48 65 61 70 4e 65 61 72 6c 79 46  lite3HeapNearlyF
dcb0: 75 6c 6c 28 29 29 0a 20 20 20 20 20 20 29 3b 0a  ull()).      );.
dcc0: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 62 46      }.    if( bF
dcd0: 6c 75 73 68 20 29 7b 0a 20 20 20 20 20 20 72 63  lush ){.      rc
dce0: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 46 6c 75   = vdbeSorterFlu
dcf0: 73 68 50 4d 41 28 70 53 6f 72 74 65 72 29 3b 0a  shPMA(pSorter);.
dd00: 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6c        pSorter->l
dd10: 69 73 74 2e 73 7a 50 4d 41 20 3d 20 30 3b 0a 20  ist.szPMA = 0;. 
dd20: 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 69 4d       pSorter->iM
dd30: 65 6d 6f 72 79 20 3d 20 30 3b 0a 20 20 20 20 20  emory = 0;.     
dd40: 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c   assert( rc!=SQL
dd50: 49 54 45 5f 4f 4b 20 7c 7c 20 70 53 6f 72 74 65  ITE_OK || pSorte
dd60: 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 3d 3d 30  r->list.pList==0
dd70: 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20   );.    }.  }.. 
dd80: 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 73   pSorter->list.s
dd90: 7a 50 4d 41 20 2b 3d 20 6e 50 4d 41 3b 0a 20 20  zPMA += nPMA;.  
dda0: 69 66 28 20 6e 50 4d 41 3e 70 53 6f 72 74 65 72  if( nPMA>pSorter
ddb0: 2d 3e 6d 78 4b 65 79 73 69 7a 65 20 29 7b 0a 20  ->mxKeysize ){. 
ddc0: 20 20 20 70 53 6f 72 74 65 72 2d 3e 6d 78 4b 65     pSorter->mxKe
ddd0: 79 73 69 7a 65 20 3d 20 6e 50 4d 41 3b 0a 20 20  ysize = nPMA;.  
dde0: 7d 0a 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72  }..  if( pSorter
ddf0: 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 29  ->list.aMemory )
de00: 7b 0a 20 20 20 20 69 6e 74 20 6e 4d 69 6e 20 3d  {.    int nMin =
de10: 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72   pSorter->iMemor
de20: 79 20 2b 20 6e 52 65 71 3b 0a 0a 20 20 20 20 69  y + nReq;..    i
de30: 66 28 20 6e 4d 69 6e 3e 70 53 6f 72 74 65 72 2d  f( nMin>pSorter-
de40: 3e 6e 4d 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20  >nMemory ){.    
de50: 20 20 75 38 20 2a 61 4e 65 77 3b 0a 20 20 20 20    u8 *aNew;.    
de60: 20 20 69 6e 74 20 6e 4e 65 77 20 3d 20 70 53 6f    int nNew = pSo
de70: 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 2a 20  rter->nMemory * 
de80: 32 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20  2;.      while( 
de90: 6e 4e 65 77 20 3c 20 6e 4d 69 6e 20 29 20 6e 4e  nNew < nMin ) nN
dea0: 65 77 20 3d 20 6e 4e 65 77 2a 32 3b 0a 20 20 20  ew = nNew*2;.   
deb0: 20 20 20 69 66 28 20 6e 4e 65 77 20 3e 20 70 53     if( nNew > pS
dec0: 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65  orter->mxPmaSize
ded0: 20 29 20 6e 4e 65 77 20 3d 20 70 53 6f 72 74 65   ) nNew = pSorte
dee0: 72 2d 3e 6d 78 50 6d 61 53 69 7a 65 3b 0a 20 20  r->mxPmaSize;.  
def0: 20 20 20 20 69 66 28 20 6e 4e 65 77 20 3c 20 6e      if( nNew < n
df00: 4d 69 6e 20 29 20 6e 4e 65 77 20 3d 20 6e 4d 69  Min ) nNew = nMi
df10: 6e 3b 0a 0a 20 20 20 20 20 20 61 4e 65 77 20 3d  n;..      aNew =
df20: 20 73 71 6c 69 74 65 33 52 65 61 6c 6c 6f 63 28   sqlite3Realloc(
df30: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d  pSorter->list.aM
df40: 65 6d 6f 72 79 2c 20 6e 4e 65 77 29 3b 0a 20 20  emory, nNew);.  
df50: 20 20 20 20 69 66 28 20 21 61 4e 65 77 20 29 20      if( !aNew ) 
df60: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
df70: 4d 45 4d 3b 0a 20 20 20 20 20 20 70 53 6f 72 74  MEM;.      pSort
df80: 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d  er->list.pList =
df90: 20 28 53 6f 72 74 65 72 52 65 63 6f 72 64 2a 29   (SorterRecord*)
dfa0: 28 0a 20 20 20 20 20 20 20 20 20 20 61 4e 65 77  (.          aNew
dfb0: 20 2b 20 28 28 75 38 2a 29 70 53 6f 72 74 65 72   + ((u8*)pSorter
dfc0: 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 2d 20 70  ->list.pList - p
dfd0: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65  Sorter->list.aMe
dfe0: 6d 6f 72 79 29 0a 20 20 20 20 20 20 29 3b 0a 20  mory).      );. 
dff0: 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69       pSorter->li
e000: 73 74 2e 61 4d 65 6d 6f 72 79 20 3d 20 61 4e 65  st.aMemory = aNe
e010: 77 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72  w;.      pSorter
e020: 2d 3e 6e 4d 65 6d 6f 72 79 20 3d 20 6e 4e 65 77  ->nMemory = nNew
e030: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 4e 65  ;.    }..    pNe
e040: 77 20 3d 20 28 53 6f 72 74 65 72 52 65 63 6f 72  w = (SorterRecor
e050: 64 2a 29 26 70 53 6f 72 74 65 72 2d 3e 6c 69 73  d*)&pSorter->lis
e060: 74 2e 61 4d 65 6d 6f 72 79 5b 70 53 6f 72 74 65  t.aMemory[pSorte
e070: 72 2d 3e 69 4d 65 6d 6f 72 79 5d 3b 0a 20 20 20  r->iMemory];.   
e080: 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72   pSorter->iMemor
e090: 79 20 2b 3d 20 52 4f 55 4e 44 38 28 6e 52 65 71  y += ROUND8(nReq
e0a0: 29 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 75 2e 69  );.    pNew->u.i
e0b0: 4e 65 78 74 20 3d 20 28 75 38 2a 29 28 70 53 6f  Next = (u8*)(pSo
e0c0: 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74  rter->list.pList
e0d0: 29 20 2d 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73  ) - pSorter->lis
e0e0: 74 2e 61 4d 65 6d 6f 72 79 3b 0a 20 20 7d 65 6c  t.aMemory;.  }el
e0f0: 73 65 7b 0a 20 20 20 20 70 4e 65 77 20 3d 20 28  se{.    pNew = (
e100: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 29 73  SorterRecord *)s
e110: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 6e 52 65  qlite3Malloc(nRe
e120: 71 29 3b 0a 20 20 20 20 69 66 28 20 70 4e 65 77  q);.    if( pNew
e130: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 65 74  ==0 ){.      ret
e140: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
e150: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 4e 65 77  ;.    }.    pNew
e160: 2d 3e 75 2e 70 4e 65 78 74 20 3d 20 70 53 6f 72  ->u.pNext = pSor
e170: 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 3b  ter->list.pList;
e180: 0a 20 20 7d 0a 0a 20 20 6d 65 6d 63 70 79 28 53  .  }..  memcpy(S
e190: 52 56 41 4c 28 70 4e 65 77 29 2c 20 70 56 61 6c  RVAL(pNew), pVal
e1a0: 2d 3e 7a 2c 20 70 56 61 6c 2d 3e 6e 29 3b 0a 20  ->z, pVal->n);. 
e1b0: 20 70 4e 65 77 2d 3e 6e 56 61 6c 20 3d 20 70 56   pNew->nVal = pV
e1c0: 61 6c 2d 3e 6e 3b 0a 20 20 70 53 6f 72 74 65 72  al->n;.  pSorter
e1d0: 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d 20 70  ->list.pList = p
e1e0: 4e 65 77 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72  New;..  return r
e1f0: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64  c;.}../*.** Read
e200: 20 6b 65 79 73 20 66 72 6f 6d 20 70 49 6e 63 72   keys from pIncr
e210: 2d 3e 70 4d 65 72 67 65 72 20 61 6e 64 20 70 6f  ->pMerger and po
e220: 70 75 6c 61 74 65 20 70 49 6e 63 72 2d 3e 61 46  pulate pIncr->aF
e230: 69 6c 65 5b 31 5d 2e 20 54 68 65 20 66 6f 72 6d  ile[1]. The form
e240: 61 74 0a 2a 2a 20 6f 66 20 74 68 65 20 64 61 74  at.** of the dat
e250: 61 20 73 74 6f 72 65 64 20 69 6e 20 61 46 69 6c  a stored in aFil
e260: 65 5b 31 5d 20 69 73 20 74 68 65 20 73 61 6d 65  e[1] is the same
e270: 20 61 73 20 74 68 61 74 20 75 73 65 64 20 62 79   as that used by
e280: 20 72 65 67 75 6c 61 72 20 50 4d 41 73 2c 0a 2a   regular PMAs,.*
e290: 2a 20 65 78 63 65 70 74 20 74 68 61 74 20 74 68  * except that th
e2a0: 65 20 6e 75 6d 62 65 72 2d 6f 66 2d 62 79 74 65  e number-of-byte
e2b0: 73 20 76 61 72 69 6e 74 20 69 73 20 6f 6d 69 74  s varint is omit
e2c0: 74 65 64 20 66 72 6f 6d 20 74 68 65 20 73 74 61  ted from the sta
e2d0: 72 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  rt..*/.static in
e2e0: 74 20 76 64 62 65 49 6e 63 72 50 6f 70 75 6c 61  t vdbeIncrPopula
e2f0: 74 65 28 49 6e 63 72 4d 65 72 67 65 72 20 2a 70  te(IncrMerger *p
e300: 49 6e 63 72 29 7b 0a 20 20 69 6e 74 20 72 63 20  Incr){.  int rc 
e310: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
e320: 6e 74 20 72 63 32 3b 0a 20 20 69 36 34 20 69 53  nt rc2;.  i64 iS
e330: 74 61 72 74 20 3d 20 70 49 6e 63 72 2d 3e 69 53  tart = pIncr->iS
e340: 74 61 72 74 4f 66 66 3b 0a 20 20 53 6f 72 74 65  tartOff;.  Sorte
e350: 72 46 69 6c 65 20 2a 70 4f 75 74 20 3d 20 26 70  rFile *pOut = &p
e360: 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 3b 0a  Incr->aFile[1];.
e370: 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70    SortSubtask *p
e380: 54 61 73 6b 20 3d 20 70 49 6e 63 72 2d 3e 70 54  Task = pIncr->pT
e390: 61 73 6b 3b 0a 20 20 4d 65 72 67 65 45 6e 67 69  ask;.  MergeEngi
e3a0: 6e 65 20 2a 70 4d 65 72 67 65 72 20 3d 20 70 49  ne *pMerger = pI
e3b0: 6e 63 72 2d 3e 70 4d 65 72 67 65 72 3b 0a 20 20  ncr->pMerger;.  
e3c0: 50 6d 61 57 72 69 74 65 72 20 77 72 69 74 65 72  PmaWriter writer
e3d0: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 49 6e 63  ;.  assert( pInc
e3e0: 72 2d 3e 62 45 6f 66 3d 3d 30 20 29 3b 0a 0a 20  r->bEof==0 );.. 
e3f0: 20 76 64 62 65 53 6f 72 74 65 72 50 6f 70 75 6c   vdbeSorterPopul
e400: 61 74 65 44 65 62 75 67 28 70 54 61 73 6b 2c 20  ateDebug(pTask, 
e410: 22 65 6e 74 65 72 22 29 3b 0a 0a 20 20 76 64 62  "enter");..  vdb
e420: 65 50 6d 61 57 72 69 74 65 72 49 6e 69 74 28 70  ePmaWriterInit(p
e430: 4f 75 74 2d 3e 70 46 64 2c 20 26 77 72 69 74 65  Out->pFd, &write
e440: 72 2c 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65  r, pTask->pSorte
e450: 72 2d 3e 70 67 73 7a 2c 20 69 53 74 61 72 74 29  r->pgsz, iStart)
e460: 3b 0a 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 53  ;.  while( rc==S
e470: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
e480: 69 6e 74 20 64 75 6d 6d 79 3b 0a 20 20 20 20 50  int dummy;.    P
e490: 6d 61 52 65 61 64 65 72 20 2a 70 52 65 61 64 65  maReader *pReade
e4a0: 72 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49  r = &pMerger->aI
e4b0: 74 65 72 5b 20 70 4d 65 72 67 65 72 2d 3e 61 54  ter[ pMerger->aT
e4c0: 72 65 65 5b 31 5d 20 5d 3b 0a 20 20 20 20 69 6e  ree[1] ];.    in
e4d0: 74 20 6e 4b 65 79 20 3d 20 70 52 65 61 64 65 72  t nKey = pReader
e4e0: 2d 3e 6e 4b 65 79 3b 0a 20 20 20 20 69 36 34 20  ->nKey;.    i64 
e4f0: 69 45 6f 66 20 3d 20 77 72 69 74 65 72 2e 69 57  iEof = writer.iW
e500: 72 69 74 65 4f 66 66 20 2b 20 77 72 69 74 65 72  riteOff + writer
e510: 2e 69 42 75 66 45 6e 64 3b 0a 0a 20 20 20 20 2f  .iBufEnd;..    /
e520: 2a 20 43 68 65 63 6b 20 69 66 20 74 68 65 20 6f  * Check if the o
e530: 75 74 70 75 74 20 66 69 6c 65 20 69 73 20 66 75  utput file is fu
e540: 6c 6c 20 6f 72 20 69 66 20 74 68 65 20 69 6e 70  ll or if the inp
e550: 75 74 20 68 61 73 20 62 65 65 6e 20 65 78 68 61  ut has been exha
e560: 75 73 74 65 64 2e 0a 20 20 20 20 2a 2a 20 49 6e  usted..    ** In
e570: 20 65 69 74 68 65 72 20 63 61 73 65 20 65 78 69   either case exi
e580: 74 20 74 68 65 20 6c 6f 6f 70 2e 20 2a 2f 0a 20  t the loop. */. 
e590: 20 20 20 69 66 28 20 70 52 65 61 64 65 72 2d 3e     if( pReader->
e5a0: 70 46 69 6c 65 3d 3d 30 20 29 20 62 72 65 61 6b  pFile==0 ) break
e5b0: 3b 0a 20 20 20 20 69 66 28 20 28 69 45 6f 66 20  ;.    if( (iEof 
e5c0: 2b 20 6e 4b 65 79 20 2b 20 73 71 6c 69 74 65 33  + nKey + sqlite3
e5d0: 56 61 72 69 6e 74 4c 65 6e 28 6e 4b 65 79 29 29  VarintLen(nKey))
e5e0: 3e 28 69 53 74 61 72 74 20 2b 20 70 49 6e 63 72  >(iStart + pIncr
e5f0: 2d 3e 6d 78 53 7a 29 20 29 20 62 72 65 61 6b 3b  ->mxSz) ) break;
e600: 0a 0a 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74  ..    /* Write t
e610: 68 65 20 6e 65 78 74 20 6b 65 79 20 74 6f 20 74  he next key to t
e620: 68 65 20 6f 75 74 70 75 74 2e 20 2a 2f 0a 20 20  he output. */.  
e630: 20 20 76 64 62 65 50 6d 61 57 72 69 74 65 56 61    vdbePmaWriteVa
e640: 72 69 6e 74 28 26 77 72 69 74 65 72 2c 20 6e 4b  rint(&writer, nK
e650: 65 79 29 3b 0a 20 20 20 20 76 64 62 65 50 6d 61  ey);.    vdbePma
e660: 57 72 69 74 65 42 6c 6f 62 28 26 77 72 69 74 65  WriteBlob(&write
e670: 72 2c 20 70 52 65 61 64 65 72 2d 3e 61 4b 65 79  r, pReader->aKey
e680: 2c 20 6e 4b 65 79 29 3b 0a 20 20 20 20 72 63 20  , nKey);.    rc 
e690: 3d 20 76 64 62 65 53 6f 72 74 65 72 4e 65 78 74  = vdbeSorterNext
e6a0: 28 70 54 61 73 6b 2c 20 70 49 6e 63 72 2d 3e 70  (pTask, pIncr->p
e6b0: 4d 65 72 67 65 72 2c 20 26 64 75 6d 6d 79 29 3b  Merger, &dummy);
e6c0: 0a 20 20 7d 0a 0a 20 20 72 63 32 20 3d 20 76 64  .  }..  rc2 = vd
e6d0: 62 65 50 6d 61 57 72 69 74 65 72 46 69 6e 69 73  bePmaWriterFinis
e6e0: 68 28 26 77 72 69 74 65 72 2c 20 26 70 4f 75 74  h(&writer, &pOut
e6f0: 2d 3e 69 45 6f 66 29 3b 0a 20 20 69 66 28 20 72  ->iEof);.  if( r
e700: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c==SQLITE_OK ) r
e710: 63 20 3d 20 72 63 32 3b 0a 20 20 76 64 62 65 53  c = rc2;.  vdbeS
e720: 6f 72 74 65 72 50 6f 70 75 6c 61 74 65 44 65 62  orterPopulateDeb
e730: 75 67 28 70 54 61 73 6b 2c 20 22 65 78 69 74 22  ug(pTask, "exit"
e740: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
e750: 7d 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41  }..#if SQLITE_MA
e760: 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53  X_WORKER_THREADS
e770: 3e 30 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d 61 69  >0./*.** The mai
e780: 6e 20 72 6f 75 74 69 6e 65 20 66 6f 72 20 62 61  n routine for ba
e790: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 73  ckground threads
e7a0: 20 74 68 61 74 20 70 6f 70 75 6c 61 74 65 20 61   that populate a
e7b0: 46 69 6c 65 5b 31 5d 20 6f 66 0a 2a 2a 20 6d 75  File[1] of.** mu
e7c0: 6c 74 69 2d 74 68 72 65 61 64 65 64 20 49 6e 63  lti-threaded Inc
e7d0: 72 4d 65 72 67 65 72 20 6f 62 6a 65 63 74 73 2e  rMerger objects.
e7e0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
e7f0: 2a 76 64 62 65 49 6e 63 72 50 6f 70 75 6c 61 74  *vdbeIncrPopulat
e800: 65 54 68 72 65 61 64 28 76 6f 69 64 20 2a 70 43  eThread(void *pC
e810: 74 78 29 7b 0a 20 20 49 6e 63 72 4d 65 72 67 65  tx){.  IncrMerge
e820: 72 20 2a 70 49 6e 63 72 20 3d 20 28 49 6e 63 72  r *pIncr = (Incr
e830: 4d 65 72 67 65 72 2a 29 70 43 74 78 3b 0a 20 20  Merger*)pCtx;.  
e840: 76 6f 69 64 20 2a 70 52 65 74 20 3d 20 53 51 4c  void *pRet = SQL
e850: 49 54 45 5f 49 4e 54 5f 54 4f 5f 50 54 52 28 20  ITE_INT_TO_PTR( 
e860: 76 64 62 65 49 6e 63 72 50 6f 70 75 6c 61 74 65  vdbeIncrPopulate
e870: 28 70 49 6e 63 72 29 20 29 3b 0a 20 20 70 49 6e  (pIncr) );.  pIn
e880: 63 72 2d 3e 70 54 61 73 6b 2d 3e 62 44 6f 6e 65  cr->pTask->bDone
e890: 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 70   = 1;.  return p
e8a0: 52 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 61  Ret;.}../*.** La
e8b0: 75 6e 63 68 20 61 20 62 61 63 6b 67 72 6f 75 6e  unch a backgroun
e8c0: 64 20 74 68 72 65 61 64 20 74 6f 20 70 6f 70 75  d thread to popu
e8d0: 6c 61 74 65 20 61 46 69 6c 65 5b 31 5d 20 6f 66  late aFile[1] of
e8e0: 20 70 49 6e 63 72 2e 0a 2a 2f 0a 73 74 61 74 69   pIncr..*/.stati
e8f0: 63 20 69 6e 74 20 76 64 62 65 49 6e 63 72 42 67  c int vdbeIncrBg
e900: 50 6f 70 75 6c 61 74 65 28 49 6e 63 72 4d 65 72  Populate(IncrMer
e910: 67 65 72 20 2a 70 49 6e 63 72 29 7b 0a 20 20 76  ger *pIncr){.  v
e920: 6f 69 64 20 2a 70 20 3d 20 28 76 6f 69 64 2a 29  oid *p = (void*)
e930: 70 49 6e 63 72 3b 0a 20 20 61 73 73 65 72 74 28  pIncr;.  assert(
e940: 20 70 49 6e 63 72 2d 3e 62 55 73 65 54 68 72 65   pIncr->bUseThre
e950: 61 64 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 76  ad );.  return v
e960: 64 62 65 53 6f 72 74 65 72 43 72 65 61 74 65 54  dbeSorterCreateT
e970: 68 72 65 61 64 28 70 49 6e 63 72 2d 3e 70 54 61  hread(pIncr->pTa
e980: 73 6b 2c 20 76 64 62 65 49 6e 63 72 50 6f 70 75  sk, vdbeIncrPopu
e990: 6c 61 74 65 54 68 72 65 61 64 2c 20 70 29 3b 0a  lateThread, p);.
e9a0: 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20  }.#endif../*.** 
e9b0: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
e9c0: 20 63 61 6c 6c 65 64 20 77 68 65 6e 20 74 68 65   called when the
e9d0: 20 50 6d 61 52 65 61 64 65 72 20 63 6f 72 72 65   PmaReader corre
e9e0: 73 70 6f 6e 64 69 6e 67 20 74 6f 20 70 49 6e 63  sponding to pInc
e9f0: 72 20 68 61 73 0a 2a 2a 20 66 69 6e 69 73 68 65  r has.** finishe
ea00: 64 20 72 65 61 64 69 6e 67 20 74 68 65 20 63 6f  d reading the co
ea10: 6e 74 65 6e 74 73 20 6f 66 20 61 46 69 6c 65 5b  ntents of aFile[
ea20: 30 5d 2e 20 49 74 73 20 70 75 72 70 6f 73 65 20  0]. Its purpose 
ea30: 69 73 20 74 6f 20 22 72 65 66 69 6c 6c 22 0a 2a  is to "refill".*
ea40: 2a 20 61 46 69 6c 65 5b 30 5d 20 73 75 63 68 20  * aFile[0] such 
ea50: 74 68 61 74 20 74 68 65 20 69 74 65 72 61 74 6f  that the iterato
ea60: 72 20 73 68 6f 75 6c 64 20 73 74 61 72 74 20 72  r should start r
ea70: 65 72 65 61 64 69 6e 67 20 69 74 20 66 72 6f 6d  ereading it from
ea80: 20 74 68 65 0a 2a 2a 20 62 65 67 69 6e 6e 69 6e   the.** beginnin
ea90: 67 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 73 69 6e  g..**.** For sin
eaa0: 67 6c 65 2d 74 68 72 65 61 64 65 64 20 6f 62 6a  gle-threaded obj
eab0: 65 63 74 73 2c 20 74 68 69 73 20 69 73 20 61 63  ects, this is ac
eac0: 63 6f 6d 70 6c 69 73 68 65 64 20 62 79 20 6c 69  complished by li
ead0: 74 65 72 61 6c 6c 79 20 72 65 61 64 69 6e 67 20  terally reading 
eae0: 0a 2a 2a 20 6b 65 79 73 20 66 72 6f 6d 20 70 49  .** keys from pI
eaf0: 6e 63 72 2d 3e 70 4d 65 72 67 65 72 20 61 6e 64  ncr->pMerger and
eb00: 20 72 65 70 6f 70 75 6c 61 74 69 6e 67 20 61 46   repopulating aF
eb10: 69 6c 65 5b 30 5d 2e 20 0a 2a 2a 0a 2a 2a 20 46  ile[0]. .**.** F
eb20: 6f 72 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65  or multi-threade
eb30: 64 20 6f 62 6a 65 63 74 73 2c 20 61 6c 6c 20 74  d objects, all t
eb40: 68 61 74 20 69 73 20 72 65 71 75 69 72 65 64 20  hat is required 
eb50: 69 73 20 74 6f 20 77 61 69 74 20 75 6e 74 69 6c  is to wait until
eb60: 20 74 68 65 20 0a 2a 2a 20 62 61 63 6b 67 72 6f   the .** backgro
eb70: 75 6e 64 20 74 68 72 65 61 64 20 69 73 20 66 69  und thread is fi
eb80: 6e 69 73 68 65 64 20 28 69 66 20 69 74 20 69 73  nished (if it is
eb90: 20 6e 6f 74 20 61 6c 72 65 61 64 79 29 20 61 6e   not already) an
eba0: 64 20 74 68 65 6e 20 73 77 61 70 20 0a 2a 2a 20  d then swap .** 
ebb0: 61 46 69 6c 65 5b 30 5d 20 61 6e 64 20 61 46 69  aFile[0] and aFi
ebc0: 6c 65 5b 31 5d 20 69 6e 20 70 6c 61 63 65 2e 20  le[1] in place. 
ebd0: 49 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  If the contents 
ebe0: 6f 66 20 70 4d 65 72 67 65 72 20 68 61 76 65 20  of pMerger have 
ebf0: 6e 6f 74 0a 2a 2a 20 62 65 65 6e 20 65 78 68 61  not.** been exha
ec00: 75 73 74 65 64 2c 20 74 68 69 73 20 66 75 6e 63  usted, this func
ec10: 74 69 6f 6e 20 61 6c 73 6f 20 6c 61 75 6e 63 68  tion also launch
ec20: 65 73 20 61 20 6e 65 77 20 62 61 63 6b 67 72 6f  es a new backgro
ec30: 75 6e 64 20 74 68 72 65 61 64 0a 2a 2a 20 74 6f  und thread.** to
ec40: 20 70 6f 70 75 6c 61 74 65 20 74 68 65 20 6e 65   populate the ne
ec50: 77 20 61 46 69 6c 65 5b 31 5d 2e 0a 2a 2a 0a 2a  w aFile[1]..**.*
ec60: 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72  * SQLITE_OK is r
ec70: 65 74 75 72 6e 65 64 20 6f 6e 20 73 75 63 63 65  eturned on succe
ec80: 73 73 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65  ss, or an SQLite
ec90: 20 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65   error code othe
eca0: 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  rwise..*/.static
ecb0: 20 69 6e 74 20 76 64 62 65 49 6e 63 72 53 77 61   int vdbeIncrSwa
ecc0: 70 28 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49  p(IncrMerger *pI
ecd0: 6e 63 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  ncr){.  int rc =
ece0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 23 69 66   SQLITE_OK;..#if
ecf0: 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b   SQLITE_MAX_WORK
ed00: 45 52 5f 54 48 52 45 41 44 53 3e 30 0a 20 20 69  ER_THREADS>0.  i
ed10: 66 28 20 70 49 6e 63 72 2d 3e 62 55 73 65 54 68  f( pIncr->bUseTh
ed20: 72 65 61 64 20 29 7b 0a 20 20 20 20 72 63 20 3d  read ){.    rc =
ed30: 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e 54   vdbeSorterJoinT
ed40: 68 72 65 61 64 28 70 49 6e 63 72 2d 3e 70 54 61  hread(pIncr->pTa
ed50: 73 6b 29 3b 0a 0a 20 20 20 20 69 66 28 20 72 63  sk);..    if( rc
ed60: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
ed70: 20 20 20 20 20 53 6f 72 74 65 72 46 69 6c 65 20       SorterFile 
ed80: 66 30 20 3d 20 70 49 6e 63 72 2d 3e 61 46 69 6c  f0 = pIncr->aFil
ed90: 65 5b 30 5d 3b 0a 20 20 20 20 20 20 70 49 6e 63  e[0];.      pInc
eda0: 72 2d 3e 61 46 69 6c 65 5b 30 5d 20 3d 20 70 49  r->aFile[0] = pI
edb0: 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 3b 0a 20  ncr->aFile[1];. 
edc0: 20 20 20 20 20 70 49 6e 63 72 2d 3e 61 46 69 6c       pIncr->aFil
edd0: 65 5b 31 5d 20 3d 20 66 30 3b 0a 20 20 20 20 7d  e[1] = f0;.    }
ede0: 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ..    if( rc==SQ
edf0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
ee00: 20 69 66 28 20 70 49 6e 63 72 2d 3e 61 46 69 6c   if( pIncr->aFil
ee10: 65 5b 30 5d 2e 69 45 6f 66 3d 3d 70 49 6e 63 72  e[0].iEof==pIncr
ee20: 2d 3e 69 53 74 61 72 74 4f 66 66 20 29 7b 0a 20  ->iStartOff ){. 
ee30: 20 20 20 20 20 20 20 70 49 6e 63 72 2d 3e 62 45         pIncr->bE
ee40: 6f 66 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 65  of = 1;.      }e
ee50: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 72 63 20  lse{.        rc 
ee60: 3d 20 76 64 62 65 49 6e 63 72 42 67 50 6f 70 75  = vdbeIncrBgPopu
ee70: 6c 61 74 65 28 70 49 6e 63 72 29 3b 0a 20 20 20  late(pIncr);.   
ee80: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 65 6c     }.    }.  }el
ee90: 73 65 0a 23 65 6e 64 69 66 0a 20 20 7b 0a 20 20  se.#endif.  {.  
eea0: 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72 50    rc = vdbeIncrP
eeb0: 6f 70 75 6c 61 74 65 28 70 49 6e 63 72 29 3b 0a  opulate(pIncr);.
eec0: 20 20 20 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65      pIncr->aFile
eed0: 5b 30 5d 20 3d 20 70 49 6e 63 72 2d 3e 61 46 69  [0] = pIncr->aFi
eee0: 6c 65 5b 31 5d 3b 0a 20 20 20 20 69 66 28 20 70  le[1];.    if( p
eef0: 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e 69  Incr->aFile[0].i
ef00: 45 6f 66 3d 3d 70 49 6e 63 72 2d 3e 69 53 74 61  Eof==pIncr->iSta
ef10: 72 74 4f 66 66 20 29 7b 0a 20 20 20 20 20 20 70  rtOff ){.      p
ef20: 49 6e 63 72 2d 3e 62 45 6f 66 20 3d 20 31 3b 0a  Incr->bEof = 1;.
ef30: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
ef40: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
ef50: 20 41 6c 6c 6f 63 61 74 65 20 61 6e 64 20 72 65   Allocate and re
ef60: 74 75 72 6e 20 61 20 6e 65 77 20 49 6e 63 72 4d  turn a new IncrM
ef70: 65 72 67 65 72 20 6f 62 6a 65 63 74 20 74 6f 20  erger object to 
ef80: 72 65 61 64 20 64 61 74 61 20 66 72 6f 6d 20 70  read data from p
ef90: 4d 65 72 67 65 72 2e 0a 2a 2f 0a 73 74 61 74 69  Merger..*/.stati
efa0: 63 20 49 6e 63 72 4d 65 72 67 65 72 20 2a 76 64  c IncrMerger *vd
efb0: 62 65 49 6e 63 72 4e 65 77 28 53 6f 72 74 53 75  beIncrNew(SortSu
efc0: 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 4d 65  btask *pTask, Me
efd0: 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67  rgeEngine *pMerg
efe0: 65 72 29 7b 0a 20 20 49 6e 63 72 4d 65 72 67 65  er){.  IncrMerge
eff0: 72 20 2a 70 49 6e 63 72 20 3d 20 73 71 6c 69 74  r *pIncr = sqlit
f000: 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66  e3_malloc(sizeof
f010: 28 49 6e 63 72 4d 65 72 67 65 72 29 29 3b 0a 20  (IncrMerger));. 
f020: 20 69 66 28 20 70 49 6e 63 72 20 29 7b 0a 20 20   if( pIncr ){.  
f030: 20 20 6d 65 6d 73 65 74 28 70 49 6e 63 72 2c 20    memset(pIncr, 
f040: 30 2c 20 73 69 7a 65 6f 66 28 49 6e 63 72 4d 65  0, sizeof(IncrMe
f050: 72 67 65 72 29 29 3b 0a 20 20 20 20 70 49 6e 63  rger));.    pInc
f060: 72 2d 3e 70 4d 65 72 67 65 72 20 3d 20 70 4d 65  r->pMerger = pMe
f070: 72 67 65 72 3b 0a 20 20 20 20 70 49 6e 63 72 2d  rger;.    pIncr-
f080: 3e 70 54 61 73 6b 20 3d 20 70 54 61 73 6b 3b 0a  >pTask = pTask;.
f090: 20 20 20 20 70 49 6e 63 72 2d 3e 6d 78 53 7a 20      pIncr->mxSz 
f0a0: 3d 20 4d 41 58 28 70 54 61 73 6b 2d 3e 70 53 6f  = MAX(pTask->pSo
f0b0: 72 74 65 72 2d 3e 6d 78 4b 65 79 73 69 7a 65 2b  rter->mxKeysize+
f0c0: 39 2c 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72  9,pTask->pSorter
f0d0: 2d 3e 6d 78 50 6d 61 53 69 7a 65 2f 32 29 3b 0a  ->mxPmaSize/2);.
f0e0: 20 20 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32      pTask->file2
f0f0: 2e 69 45 6f 66 20 2b 3d 20 70 49 6e 63 72 2d 3e  .iEof += pIncr->
f100: 6d 78 53 7a 3b 0a 20 20 7d 0a 20 20 72 65 74 75  mxSz;.  }.  retu
f110: 72 6e 20 70 49 6e 63 72 3b 0a 7d 0a 0a 2f 2a 0a  rn pIncr;.}../*.
f120: 2a 2a 20 53 65 74 20 74 68 65 20 22 75 73 65 2d  ** Set the "use-
f130: 74 68 72 65 61 64 73 22 20 66 6c 61 67 20 6f 6e  threads" flag on
f140: 20 6f 62 6a 65 63 74 20 70 49 6e 63 72 2e 0a 2a   object pIncr..*
f150: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64  /.static void vd
f160: 62 65 49 6e 63 72 53 65 74 54 68 72 65 61 64 73  beIncrSetThreads
f170: 28 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e  (IncrMerger *pIn
f180: 63 72 2c 20 69 6e 74 20 62 55 73 65 54 68 72 65  cr, int bUseThre
f190: 61 64 29 7b 0a 20 20 69 66 28 20 62 55 73 65 54  ad){.  if( bUseT
f1a0: 68 72 65 61 64 20 29 7b 0a 20 20 20 20 70 49 6e  hread ){.    pIn
f1b0: 63 72 2d 3e 62 55 73 65 54 68 72 65 61 64 20 3d  cr->bUseThread =
f1c0: 20 31 3b 0a 20 20 20 20 70 49 6e 63 72 2d 3e 70   1;.    pIncr->p
f1d0: 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66  Task->file2.iEof
f1e0: 20 2d 3d 20 70 49 6e 63 72 2d 3e 6d 78 53 7a 3b   -= pIncr->mxSz;
f1f0: 0a 20 20 7d 0a 7d 0a 0a 23 64 65 66 69 6e 65 20  .  }.}..#define 
f200: 49 4e 43 52 49 4e 49 54 32 5f 4e 4f 52 4d 41 4c  INCRINIT2_NORMAL
f210: 20 30 0a 23 64 65 66 69 6e 65 20 49 4e 43 52 49   0.#define INCRI
f220: 4e 49 54 32 5f 54 41 53 4b 20 20 20 31 0a 23 64  NIT2_TASK   1.#d
f230: 65 66 69 6e 65 20 49 4e 43 52 49 4e 49 54 32 5f  efine INCRINIT2_
f240: 52 4f 4f 54 20 20 20 32 0a 0a 73 74 61 74 69 63  ROOT   2..static
f250: 20 69 6e 74 20 76 64 62 65 49 6e 63 72 49 6e 69   int vdbeIncrIni
f260: 74 32 28 50 6d 61 52 65 61 64 65 72 20 2a 70 49  t2(PmaReader *pI
f270: 74 65 72 2c 20 69 6e 74 20 65 4d 6f 64 65 29 3b  ter, int eMode);
f280: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  ..static int vdb
f290: 65 49 6e 63 72 49 6e 69 74 4d 65 72 67 65 72 28  eIncrInitMerger(
f2a0: 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a  .  SortSubtask *
f2b0: 70 54 61 73 6b 2c 20 0a 20 20 4d 65 72 67 65 45  pTask, .  MergeE
f2c0: 6e 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 2c 20  ngine *pMerger, 
f2d0: 0a 20 20 69 6e 74 20 65 4d 6f 64 65 0a 29 7b 0a  .  int eMode.){.
f2e0: 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72    int i;.  int r
f2f0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a  c = SQLITE_OK;..
f300: 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53    for(i=0; rc==S
f310: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 70 4d  QLITE_OK && i<pM
f320: 65 72 67 65 72 2d 3e 6e 54 72 65 65 3b 20 69 2b  erger->nTree; i+
f330: 2b 29 7b 0a 20 20 20 20 69 66 28 20 65 4d 6f 64  +){.    if( eMod
f340: 65 3d 3d 49 4e 43 52 49 4e 49 54 32 5f 52 4f 4f  e==INCRINIT2_ROO
f350: 54 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  T ){.      rc = 
f360: 76 64 62 65 50 6d 61 52 65 61 64 65 72 4e 65 78  vdbePmaReaderNex
f370: 74 28 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65  t(&pMerger->aIte
f380: 72 5b 69 5d 29 3b 0a 20 20 20 20 7d 65 6c 73 65  r[i]);.    }else
f390: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62  {.      rc = vdb
f3a0: 65 49 6e 63 72 49 6e 69 74 32 28 26 70 4d 65 72  eIncrInit2(&pMer
f3b0: 67 65 72 2d 3e 61 49 74 65 72 5b 69 5d 2c 20 49  ger->aIter[i], I
f3c0: 4e 43 52 49 4e 49 54 32 5f 4e 4f 52 4d 41 4c 29  NCRINIT2_NORMAL)
f3d0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 66  ;.    }.  }..  f
f3e0: 6f 72 28 69 3d 70 4d 65 72 67 65 72 2d 3e 6e 54  or(i=pMerger->nT
f3f0: 72 65 65 2d 31 3b 20 72 63 3d 3d 53 51 4c 49 54  ree-1; rc==SQLIT
f400: 45 5f 4f 4b 20 26 26 20 69 3e 30 3b 20 69 2d 2d  E_OK && i>0; i--
f410: 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65  ){.    rc = vdbe
f420: 53 6f 72 74 65 72 44 6f 43 6f 6d 70 61 72 65 28  SorterDoCompare(
f430: 70 54 61 73 6b 2c 20 70 4d 65 72 67 65 72 2c 20  pTask, pMerger, 
f440: 69 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  i);.  }..  retur
f450: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
f460: 69 6e 74 20 76 64 62 65 49 6e 63 72 49 6e 69 74  int vdbeIncrInit
f470: 32 28 50 6d 61 52 65 61 64 65 72 20 2a 70 49 74  2(PmaReader *pIt
f480: 65 72 2c 20 69 6e 74 20 65 4d 6f 64 65 29 7b 0a  er, int eMode){.
f490: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
f4a0: 45 5f 4f 4b 3b 0a 20 20 49 6e 63 72 4d 65 72 67  E_OK;.  IncrMerg
f4b0: 65 72 20 2a 70 49 6e 63 72 20 3d 20 70 49 74 65  er *pIncr = pIte
f4c0: 72 2d 3e 70 49 6e 63 72 3b 0a 20 20 69 66 28 20  r->pIncr;.  if( 
f4d0: 70 49 6e 63 72 20 29 7b 0a 20 20 20 20 53 6f 72  pIncr ){.    Sor
f4e0: 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 20  tSubtask *pTask 
f4f0: 3d 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b 3b 0a  = pIncr->pTask;.
f500: 20 20 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20      sqlite3 *db 
f510: 3d 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72  = pTask->pSorter
f520: 2d 3e 64 62 3b 0a 0a 20 20 20 20 72 63 20 3d 20  ->db;..    rc = 
f530: 76 64 62 65 49 6e 63 72 49 6e 69 74 4d 65 72 67  vdbeIncrInitMerg
f540: 65 72 28 70 54 61 73 6b 2c 20 70 49 6e 63 72 2d  er(pTask, pIncr-
f550: 3e 70 4d 65 72 67 65 72 2c 20 65 4d 6f 64 65 29  >pMerger, eMode)
f560: 3b 0a 0a 20 20 20 20 2f 2a 20 53 65 74 20 75 70  ;..    /* Set up
f570: 20 74 68 65 20 72 65 71 75 69 72 65 64 20 66 69   the required fi
f580: 6c 65 73 20 66 6f 72 20 70 49 6e 63 72 20 2a 2f  les for pIncr */
f590: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
f5a0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
f5b0: 69 66 28 20 70 49 6e 63 72 2d 3e 62 55 73 65 54  if( pIncr->bUseT
f5c0: 68 72 65 61 64 3d 3d 30 20 29 7b 0a 20 20 20 20  hread==0 ){.    
f5d0: 20 20 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 66      if( pTask->f
f5e0: 69 6c 65 32 2e 70 46 64 3d 3d 30 20 29 7b 0a 20  ile2.pFd==0 ){. 
f5f0: 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64           rc = vd
f600: 62 65 53 6f 72 74 65 72 4f 70 65 6e 54 65 6d 70  beSorterOpenTemp
f610: 46 69 6c 65 28 64 62 2d 3e 70 56 66 73 2c 20 26  File(db->pVfs, &
f620: 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64  pTask->file2.pFd
f630: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 61 73 73  );.          ass
f640: 65 72 74 28 20 70 54 61 73 6b 2d 3e 66 69 6c 65  ert( pTask->file
f650: 32 2e 69 45 6f 66 3e 30 20 29 3b 0a 20 20 20 20  2.iEof>0 );.    
f660: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
f670: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
f680: 20 20 20 20 20 20 20 76 64 62 65 53 6f 72 74 65         vdbeSorte
f690: 72 45 78 74 65 6e 64 46 69 6c 65 28 64 62 2c 20  rExtendFile(db, 
f6a0: 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64  pTask->file2.pFd
f6b0: 2c 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69  , pTask->file2.i
f6c0: 45 6f 66 29 3b 0a 20 20 20 20 20 20 20 20 20 20  Eof);.          
f6d0: 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69    pTask->file2.i
f6e0: 45 6f 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  Eof = 0;.       
f6f0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20     }.        }. 
f700: 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
f710: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
f720: 20 20 20 20 20 20 70 49 6e 63 72 2d 3e 61 46 69        pIncr->aFi
f730: 6c 65 5b 31 5d 2e 70 46 64 20 3d 20 70 54 61 73  le[1].pFd = pTas
f740: 6b 2d 3e 66 69 6c 65 32 2e 70 46 64 3b 0a 20 20  k->file2.pFd;.  
f750: 20 20 20 20 20 20 20 20 70 49 6e 63 72 2d 3e 69          pIncr->i
f760: 53 74 61 72 74 4f 66 66 20 3d 20 70 54 61 73 6b  StartOff = pTask
f770: 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 3b 0a 20 20  ->file2.iEof;.  
f780: 20 20 20 20 20 20 20 20 70 54 61 73 6b 2d 3e 66          pTask->f
f790: 69 6c 65 32 2e 69 45 6f 66 20 2b 3d 20 70 49 6e  ile2.iEof += pIn
f7a0: 63 72 2d 3e 6d 78 53 7a 3b 0a 20 20 20 20 20 20  cr->mxSz;.      
f7b0: 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b    }.      }else{
f7c0: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64  .        rc = vd
f7d0: 62 65 53 6f 72 74 65 72 4f 70 65 6e 54 65 6d 70  beSorterOpenTemp
f7e0: 46 69 6c 65 28 64 62 2d 3e 70 56 66 73 2c 20 26  File(db->pVfs, &
f7f0: 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e  pIncr->aFile[0].
f800: 70 46 64 29 3b 0a 20 20 20 20 20 20 20 20 69 66  pFd);.        if
f810: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
f820: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  ){.          rc 
f830: 3d 20 76 64 62 65 53 6f 72 74 65 72 4f 70 65 6e  = vdbeSorterOpen
f840: 54 65 6d 70 46 69 6c 65 28 64 62 2d 3e 70 56 66  TempFile(db->pVf
f850: 73 2c 20 26 70 49 6e 63 72 2d 3e 61 46 69 6c 65  s, &pIncr->aFile
f860: 5b 31 5d 2e 70 46 64 29 3b 0a 20 20 20 20 20 20  [1].pFd);.      
f870: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
f880: 7d 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  }..    if( rc==S
f890: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 49 6e 63  QLITE_OK && pInc
f8a0: 72 2d 3e 62 55 73 65 54 68 72 65 61 64 20 29 7b  r->bUseThread ){
f8b0: 0a 20 20 20 20 20 20 2f 2a 20 55 73 65 20 74 68  .      /* Use th
f8c0: 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64  e current thread
f8d0: 20 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72 74   */.      assert
f8e0: 28 20 65 4d 6f 64 65 3d 3d 49 4e 43 52 49 4e 49  ( eMode==INCRINI
f8f0: 54 32 5f 52 4f 4f 54 20 7c 7c 20 65 4d 6f 64 65  T2_ROOT || eMode
f900: 3d 3d 49 4e 43 52 49 4e 49 54 32 5f 54 41 53 4b  ==INCRINIT2_TASK
f910: 20 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 76   );.      rc = v
f920: 64 62 65 49 6e 63 72 50 6f 70 75 6c 61 74 65 28  dbeIncrPopulate(
f930: 70 49 6e 63 72 29 3b 0a 20 20 20 20 7d 0a 0a 20  pIncr);.    }.. 
f940: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
f950: 45 5f 4f 4b 20 26 26 20 65 4d 6f 64 65 21 3d 49  E_OK && eMode!=I
f960: 4e 43 52 49 4e 49 54 32 5f 54 41 53 4b 20 29 7b  NCRINIT2_TASK ){
f970: 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65  .      rc = vdbe
f980: 50 6d 61 52 65 61 64 65 72 4e 65 78 74 28 70 49  PmaReaderNext(pI
f990: 74 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  ter);.    }.  }.
f9a0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
f9b0: 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57  #if SQLITE_MAX_W
f9c0: 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 0a  ORKER_THREADS>0.
f9d0: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 76 64 62  static void *vdb
f9e0: 65 49 6e 63 72 49 6e 69 74 32 54 68 72 65 61 64  eIncrInit2Thread
f9f0: 28 76 6f 69 64 20 2a 70 43 74 78 29 7b 0a 20 20  (void *pCtx){.  
fa00: 50 6d 61 52 65 61 64 65 72 20 2a 70 52 65 61 64  PmaReader *pRead
fa10: 65 72 20 3d 20 28 50 6d 61 52 65 61 64 65 72 2a  er = (PmaReader*
fa20: 29 70 43 74 78 3b 0a 20 20 76 6f 69 64 20 2a 70  )pCtx;.  void *p
fa30: 52 65 74 20 3d 20 53 51 4c 49 54 45 5f 49 4e 54  Ret = SQLITE_INT
fa40: 5f 54 4f 5f 50 54 52 28 20 76 64 62 65 49 6e 63  _TO_PTR( vdbeInc
fa50: 72 49 6e 69 74 32 28 70 52 65 61 64 65 72 2c 20  rInit2(pReader, 
fa60: 49 4e 43 52 49 4e 49 54 32 5f 54 41 53 4b 29 20  INCRINIT2_TASK) 
fa70: 29 3b 0a 20 20 70 52 65 61 64 65 72 2d 3e 70 49  );.  pReader->pI
fa80: 6e 63 72 2d 3e 70 54 61 73 6b 2d 3e 62 44 6f 6e  ncr->pTask->bDon
fa90: 65 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20  e = 1;.  return 
faa0: 70 52 65 74 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  pRet;.}..static 
fab0: 69 6e 74 20 76 64 62 65 49 6e 63 72 42 67 49 6e  int vdbeIncrBgIn
fac0: 69 74 32 28 50 6d 61 52 65 61 64 65 72 20 2a 70  it2(PmaReader *p
fad0: 49 74 65 72 29 7b 0a 20 20 76 6f 69 64 20 2a 70  Iter){.  void *p
fae0: 43 74 78 20 3d 20 28 76 6f 69 64 2a 29 70 49 74  Ctx = (void*)pIt
faf0: 65 72 3b 0a 20 20 72 65 74 75 72 6e 20 76 64 62  er;.  return vdb
fb00: 65 53 6f 72 74 65 72 43 72 65 61 74 65 54 68 72  eSorterCreateThr
fb10: 65 61 64 28 70 49 74 65 72 2d 3e 70 49 6e 63 72  ead(pIter->pIncr
fb20: 2d 3e 70 54 61 73 6b 2c 20 76 64 62 65 49 6e 63  ->pTask, vdbeInc
fb30: 72 49 6e 69 74 32 54 68 72 65 61 64 2c 20 70 43  rInit2Thread, pC
fb40: 74 78 29 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f  tx);.}.#endif../
fb50: 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20  *.** Allocate a 
fb60: 6e 65 77 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  new MergeEngine 
fb70: 6f 62 6a 65 63 74 20 74 6f 20 6d 65 72 67 65 20  object to merge 
fb80: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
fb90: 6e 50 4d 41 20 6c 65 76 65 6c 2d 30 0a 2a 2a 20  nPMA level-0.** 
fba0: 50 4d 41 73 20 66 72 6f 6d 20 70 54 61 73 6b 2d  PMAs from pTask-
fbb0: 3e 66 69 6c 65 2e 20 49 66 20 6e 6f 20 65 72 72  >file. If no err
fbc0: 6f 72 20 6f 63 63 75 72 73 2c 20 73 65 74 20 2a  or occurs, set *
fbd0: 70 70 4f 75 74 20 74 6f 20 70 6f 69 6e 74 20 74  ppOut to point t
fbe0: 6f 0a 2a 2a 20 74 68 65 20 6e 65 77 20 6f 62 6a  o.** the new obj
fbf0: 65 63 74 20 61 6e 64 20 72 65 74 75 72 6e 20 53  ect and return S
fc00: 51 4c 49 54 45 5f 4f 4b 2e 20 4f 72 2c 20 69 66  QLITE_OK. Or, if
fc10: 20 61 6e 20 65 72 72 6f 72 20 64 6f 65 73 20 6f   an error does o
fc20: 63 63 75 72 2c 20 73 65 74 20 2a 70 70 4f 75 74  ccur, set *ppOut
fc30: 0a 2a 2a 20 74 6f 20 4e 55 4c 4c 20 61 6e 64 20  .** to NULL and 
fc40: 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74 65  return an SQLite
fc50: 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a   error code..**.
fc60: 2a 2a 20 57 68 65 6e 20 74 68 69 73 20 66 75 6e  ** When this fun
fc70: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2c  ction is called,
fc80: 20 2a 70 69 4f 66 66 73 65 74 20 69 73 20 73 65   *piOffset is se
fc90: 74 20 74 6f 20 74 68 65 20 6f 66 66 73 65 74 20  t to the offset 
fca0: 6f 66 20 74 68 65 0a 2a 2a 20 66 69 72 73 74 20  of the.** first 
fcb0: 50 4d 41 20 74 6f 20 72 65 61 64 20 66 72 6f 6d  PMA to read from
fcc0: 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 20 41 73   pTask->file. As
fcd0: 73 75 6d 69 6e 67 20 6e 6f 20 65 72 72 6f 72 20  suming no error 
fce0: 6f 63 63 75 72 73 2c 20 69 74 20 69 73 20 0a 2a  occurs, it is .*
fcf0: 2a 20 73 65 74 20 74 6f 20 74 68 65 20 6f 66 66  * set to the off
fd00: 73 65 74 20 69 6d 6d 65 64 69 61 74 65 6c 79 20  set immediately 
fd10: 66 6f 6c 6c 6f 77 69 6e 67 20 74 68 65 20 6c 61  following the la
fd20: 73 74 20 62 79 74 65 20 6f 66 20 74 68 65 20 6c  st byte of the l
fd30: 61 73 74 0a 2a 2a 20 50 4d 41 20 62 65 66 6f 72  ast.** PMA befor
fd40: 65 20 72 65 74 75 72 6e 69 6e 67 2e 20 49 66 20  e returning. If 
fd50: 61 6e 20 65 72 72 6f 72 20 64 6f 65 73 20 6f 63  an error does oc
fd60: 63 75 72 2c 20 74 68 65 6e 20 74 68 65 20 66 69  cur, then the fi
fd70: 6e 61 6c 20 76 61 6c 75 65 20 6f 66 0a 2a 2a 20  nal value of.** 
fd80: 2a 70 69 4f 66 66 73 65 74 20 69 73 20 75 6e 64  *piOffset is und
fd90: 65 66 69 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  efined..*/.stati
fda0: 63 20 69 6e 74 20 76 64 62 65 4d 65 72 67 65 45  c int vdbeMergeE
fdb0: 6e 67 69 6e 65 4c 65 76 65 6c 30 28 0a 20 20 53  ngineLevel0(.  S
fdc0: 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
fdd0: 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  k,             /
fde0: 2a 20 53 6f 72 74 65 72 20 74 61 73 6b 20 74 6f  * Sorter task to
fdf0: 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20   read from */.  
fe00: 69 6e 74 20 6e 50 4d 41 2c 20 20 20 20 20 20 20  int nPMA,       
fe10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fe20: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 50 4d 41  /* Number of PMA
fe30: 73 20 74 6f 20 72 65 61 64 20 2a 2f 0a 20 20 69  s to read */.  i
fe40: 36 34 20 2a 70 69 4f 66 66 73 65 74 2c 20 20 20  64 *piOffset,   
fe50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
fe60: 2a 20 49 4e 2f 4f 55 54 3a 20 52 65 61 64 20 6f  * IN/OUT: Read o
fe70: 66 66 73 65 74 20 69 6e 20 70 54 61 73 6b 2d 3e  ffset in pTask->
fe80: 66 69 6c 65 20 2a 2f 0a 20 20 4d 65 72 67 65 45  file */.  MergeE
fe90: 6e 67 69 6e 65 20 2a 2a 70 70 4f 75 74 20 20 20  ngine **ppOut   
fea0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
feb0: 3a 20 4e 65 77 20 6d 65 72 67 65 2d 65 6e 67 69  : New merge-engi
fec0: 6e 65 20 2a 2f 0a 29 7b 0a 20 20 4d 65 72 67 65  ne */.){.  Merge
fed0: 45 6e 67 69 6e 65 20 2a 70 4e 65 77 3b 20 20 20  Engine *pNew;   
fee0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 65             /* Me
fef0: 72 67 65 20 65 6e 67 69 6e 65 20 74 6f 20 72 65  rge engine to re
ff00: 74 75 72 6e 20 2a 2f 0a 20 20 69 36 34 20 69 4f  turn */.  i64 iO
ff10: 66 66 20 3d 20 2a 70 69 4f 66 66 73 65 74 3b 0a  ff = *piOffset;.
ff20: 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72    int i;.  int r
ff30: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a  c = SQLITE_OK;..
ff40: 20 20 2a 70 70 4f 75 74 20 3d 20 70 4e 65 77 20    *ppOut = pNew 
ff50: 3d 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e  = vdbeMergeEngin
ff60: 65 4e 65 77 28 6e 50 4d 41 29 3b 0a 20 20 69 66  eNew(nPMA);.  if
ff70: 28 20 70 4e 65 77 3d 3d 30 20 29 20 72 63 20 3d  ( pNew==0 ) rc =
ff80: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 0a   SQLITE_NOMEM;..
ff90: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 50 4d    for(i=0; i<nPM
ffa0: 41 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f  A && rc==SQLITE_
ffb0: 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 36  OK; i++){.    i6
ffc0: 34 20 6e 44 75 6d 6d 79 3b 0a 20 20 20 20 50 6d  4 nDummy;.    Pm
ffd0: 61 52 65 61 64 65 72 20 2a 70 49 74 65 72 20 3d  aReader *pIter =
ffe0: 20 26 70 4e 65 77 2d 3e 61 49 74 65 72 5b 69 5d   &pNew->aIter[i]
fff0: 3b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 50  ;.    rc = vdbeP
10000 6d 61 52 65 61 64 65 72 49 6e 69 74 28 70 54 61  maReaderInit(pTa
10010 73 6b 2c 20 26 70 54 61 73 6b 2d 3e 66 69 6c 65  sk, &pTask->file
10020 2c 20 69 4f 66 66 2c 20 70 49 74 65 72 2c 20 26  , iOff, pIter, &
10030 6e 44 75 6d 6d 79 29 3b 0a 20 20 20 20 69 4f 66  nDummy);.    iOf
10040 66 20 3d 20 70 49 74 65 72 2d 3e 69 45 6f 66 3b  f = pIter->iEof;
10050 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d  .  }..  if( rc!=
10060 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
10070 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65   vdbeMergeEngine
10080 46 72 65 65 28 70 4e 65 77 29 3b 0a 20 20 20 20  Free(pNew);.    
10090 2a 70 70 4f 75 74 20 3d 20 30 3b 0a 20 20 7d 0a  *ppOut = 0;.  }.
100a0 20 20 2a 70 69 4f 66 66 73 65 74 20 3d 20 69 4f    *piOffset = iO
100b0 66 66 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ff;.  return rc;
100c0 0a 7d 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75  .}..typedef stru
100d0 63 74 20 49 6e 63 72 42 75 69 6c 64 65 72 20 49  ct IncrBuilder I
100e0 6e 63 72 42 75 69 6c 64 65 72 3b 0a 73 74 72 75  ncrBuilder;.stru
100f0 63 74 20 49 6e 63 72 42 75 69 6c 64 65 72 20 7b  ct IncrBuilder {
10100 0a 20 20 69 6e 74 20 6e 50 4d 41 3b 20 20 20 20  .  int nPMA;    
10110 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10120 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 69 74   /* Number of it
10130 65 72 61 74 6f 72 73 20 75 73 65 64 20 73 6f 20  erators used so 
10140 66 61 72 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e  far */.  MergeEn
10150 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 3b 20 20  gine *pMerger;  
10160 20 20 20 20 20 20 20 2f 2a 20 4d 65 72 67 65 20         /* Merge 
10170 65 6e 67 69 6e 65 20 74 6f 20 70 6f 70 75 6c 61  engine to popula
10180 74 65 2e 20 2a 2f 0a 7d 3b 0a 0a 73 74 61 74 69  te. */.};..stati
10190 63 20 69 6e 74 20 76 64 62 65 41 64 64 54 6f 42  c int vdbeAddToB
101a0 75 69 6c 64 65 72 28 0a 20 20 53 6f 72 74 53 75  uilder(.  SortSu
101b0 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 0a 20 20  btask *pTask,.  
101c0 49 6e 63 72 42 75 69 6c 64 65 72 20 2a 70 42 75  IncrBuilder *pBu
101d0 69 6c 64 65 72 2c 20 0a 20 20 4d 65 72 67 65 45  ilder, .  MergeE
101e0 6e 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 0a 29  ngine *pMerger.)
101f0 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
10200 49 54 45 5f 4f 4b 3b 0a 20 20 49 6e 63 72 4d 65  ITE_OK;.  IncrMe
10210 72 67 65 72 20 2a 70 49 6e 63 72 3b 0a 0a 20 20  rger *pIncr;..  
10220 61 73 73 65 72 74 28 20 70 4d 65 72 67 65 72 20  assert( pMerger 
10230 29 3b 0a 20 20 69 66 28 20 70 42 75 69 6c 64 65  );.  if( pBuilde
10240 72 2d 3e 6e 50 4d 41 3d 3d 53 4f 52 54 45 52 5f  r->nPMA==SORTER_
10250 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20  MAX_MERGE_COUNT 
10260 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65  ){.    rc = vdbe
10270 41 64 64 54 6f 42 75 69 6c 64 65 72 28 70 54 61  AddToBuilder(pTa
10280 73 6b 2c 20 26 70 42 75 69 6c 64 65 72 5b 31 5d  sk, &pBuilder[1]
10290 2c 20 70 42 75 69 6c 64 65 72 2d 3e 70 4d 65 72  , pBuilder->pMer
102a0 67 65 72 29 3b 0a 20 20 20 20 70 42 75 69 6c 64  ger);.    pBuild
102b0 65 72 2d 3e 70 4d 65 72 67 65 72 20 3d 20 30 3b  er->pMerger = 0;
102c0 0a 20 20 20 20 70 42 75 69 6c 64 65 72 2d 3e 6e  .    pBuilder->n
102d0 50 4d 41 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20  PMA = 0;.  }..  
102e0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
102f0 4b 20 26 26 20 70 42 75 69 6c 64 65 72 2d 3e 70  K && pBuilder->p
10300 4d 65 72 67 65 72 3d 3d 30 20 29 7b 0a 20 20 20  Merger==0 ){.   
10310 20 70 42 75 69 6c 64 65 72 2d 3e 70 4d 65 72 67   pBuilder->pMerg
10320 65 72 20 3d 20 76 64 62 65 4d 65 72 67 65 45 6e  er = vdbeMergeEn
10330 67 69 6e 65 4e 65 77 28 53 4f 52 54 45 52 5f 4d  gineNew(SORTER_M
10340 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 29 3b  AX_MERGE_COUNT);
10350 0a 20 20 20 20 69 66 28 20 70 42 75 69 6c 64 65  .    if( pBuilde
10360 72 2d 3e 70 4d 65 72 67 65 72 3d 3d 30 20 29 20  r->pMerger==0 ) 
10370 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
10380 4d 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63  M;.  }..  if( rc
10390 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
103a0 20 20 20 70 49 6e 63 72 20 3d 20 76 64 62 65 49     pIncr = vdbeI
103b0 6e 63 72 4e 65 77 28 70 54 61 73 6b 2c 20 70 4d  ncrNew(pTask, pM
103c0 65 72 67 65 72 29 3b 0a 20 20 20 20 69 66 28 20  erger);.    if( 
103d0 70 49 6e 63 72 3d 3d 30 20 29 20 72 63 20 3d 20  pIncr==0 ) rc = 
103e0 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
103f0 20 20 70 42 75 69 6c 64 65 72 2d 3e 70 4d 65 72    pBuilder->pMer
10400 67 65 72 2d 3e 61 49 74 65 72 5b 70 42 75 69 6c  ger->aIter[pBuil
10410 64 65 72 2d 3e 6e 50 4d 41 2b 2b 5d 2e 70 49 6e  der->nPMA++].pIn
10420 63 72 20 3d 20 70 49 6e 63 72 3b 0a 20 20 7d 0a  cr = pIncr;.  }.
10430 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
10440 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 64 62 65  E_OK ){.    vdbe
10450 4d 65 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28  MergeEngineFree(
10460 70 4d 65 72 67 65 72 29 3b 0a 20 20 7d 0a 0a 20  pMerger);.  }.. 
10470 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
10480 2a 0a 2a 2a 20 50 6f 70 75 6c 61 74 65 20 69 74  *.** Populate it
10490 65 72 61 74 6f 72 20 2a 70 49 74 65 72 20 73 6f  erator *pIter so
104a0 20 74 68 61 74 20 69 74 20 6d 61 79 20 62 65 20   that it may be 
104b0 75 73 65 64 20 74 6f 20 69 74 65 72 61 74 65 20  used to iterate 
104c0 74 68 72 6f 75 67 68 20 61 6c 6c 20 0a 2a 2a 20  through all .** 
104d0 6b 65 79 73 20 73 74 6f 72 65 64 20 69 6e 20 61  keys stored in a
104e0 6c 6c 20 50 4d 41 73 20 63 72 65 61 74 65 64 20  ll PMAs created 
104f0 62 79 20 74 68 69 73 20 73 6f 72 74 65 72 2e 0a  by this sorter..
10500 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
10510 62 65 50 6d 61 52 65 61 64 65 72 49 6e 63 72 49  bePmaReaderIncrI
10520 6e 69 74 28 56 64 62 65 53 6f 72 74 65 72 20 2a  nit(VdbeSorter *
10530 70 53 6f 72 74 65 72 29 7b 0a 20 20 53 6f 72 74  pSorter){.  Sort
10540 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 30 20  Subtask *pTask0 
10550 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73  = &pSorter->aTas
10560 6b 5b 30 5d 3b 0a 20 20 4d 65 72 67 65 45 6e 67  k[0];.  MergeEng
10570 69 6e 65 20 2a 70 4d 61 69 6e 20 3d 20 30 3b 0a  ine *pMain = 0;.
10580 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20 3d 20    sqlite3 *db = 
10590 70 54 61 73 6b 30 2d 3e 70 53 6f 72 74 65 72 2d  pTask0->pSorter-
105a0 3e 64 62 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20  >db;.  int rc = 
105b0 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74  SQLITE_OK;.  int
105c0 20 69 54 61 73 6b 3b 0a 0a 20 20 49 6e 63 72 42   iTask;..  IncrB
105d0 75 69 6c 64 65 72 20 2a 61 4d 65 72 67 65 3b 0a  uilder *aMerge;.
105e0 20 20 63 6f 6e 73 74 20 69 6e 74 20 6e 4d 65 72    const int nMer
105f0 67 65 20 3d 20 33 32 3b 0a 20 20 61 4d 65 72 67  ge = 32;.  aMerg
10600 65 20 3d 20 73 71 6c 69 74 65 33 44 62 4d 61 6c  e = sqlite3DbMal
10610 6c 6f 63 5a 65 72 6f 28 64 62 2c 20 73 69 7a 65  locZero(db, size
10620 6f 66 28 61 4d 65 72 67 65 5b 30 5d 29 2a 6e 4d  of(aMerge[0])*nM
10630 65 72 67 65 29 3b 0a 20 20 69 66 28 20 61 4d 65  erge);.  if( aMe
10640 72 67 65 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  rge==0 ) return 
10650 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 0a 20  SQLITE_NOMEM;.. 
10660 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6e 54   if( pSorter->nT
10670 61 73 6b 3e 31 20 29 7b 0a 20 20 20 20 70 4d 61  ask>1 ){.    pMa
10680 69 6e 20 3d 20 76 64 62 65 4d 65 72 67 65 45 6e  in = vdbeMergeEn
10690 67 69 6e 65 4e 65 77 28 70 53 6f 72 74 65 72 2d  gineNew(pSorter-
106a0 3e 6e 54 61 73 6b 29 3b 0a 20 20 20 20 69 66 28  >nTask);.    if(
106b0 20 70 4d 61 69 6e 3d 3d 30 20 29 20 72 63 20 3d   pMain==0 ) rc =
106c0 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
106d0 20 7d 0a 0a 20 20 66 6f 72 28 69 54 61 73 6b 3d   }..  for(iTask=
106e0 30 3b 20 69 54 61 73 6b 3c 70 53 6f 72 74 65 72  0; iTask<pSorter
106f0 2d 3e 6e 54 61 73 6b 20 26 26 20 72 63 3d 3d 53  ->nTask && rc==S
10700 51 4c 49 54 45 5f 4f 4b 3b 20 69 54 61 73 6b 2b  QLITE_OK; iTask+
10710 2b 29 7b 0a 20 20 20 20 4d 65 72 67 65 45 6e 67  +){.    MergeEng
10720 69 6e 65 20 2a 70 52 6f 6f 74 20 3d 20 30 3b 0a  ine *pRoot = 0;.
10730 20 20 20 20 69 6e 74 20 69 50 4d 41 3b 0a 20 20      int iPMA;.  
10740 20 20 69 36 34 20 69 52 65 61 64 4f 66 66 20 3d    i64 iReadOff =
10750 20 30 3b 0a 20 20 20 20 53 6f 72 74 53 75 62 74   0;.    SortSubt
10760 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20 26 70 53  ask *pTask = &pS
10770 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 69 54 61  orter->aTask[iTa
10780 73 6b 5d 3b 0a 20 20 20 20 69 66 28 20 70 54 61  sk];.    if( pTa
10790 73 6b 2d 3e 6e 50 4d 41 3d 3d 30 20 29 20 63 6f  sk->nPMA==0 ) co
107a0 6e 74 69 6e 75 65 3b 0a 20 20 20 20 66 6f 72 28  ntinue;.    for(
107b0 69 50 4d 41 3d 30 3b 20 69 50 4d 41 3c 70 54 61  iPMA=0; iPMA<pTa
107c0 73 6b 2d 3e 6e 50 4d 41 3b 20 69 50 4d 41 20 2b  sk->nPMA; iPMA +
107d0 3d 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52  = SORTER_MAX_MER
107e0 47 45 5f 43 4f 55 4e 54 29 7b 0a 20 20 20 20 20  GE_COUNT){.     
107f0 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d   MergeEngine *pM
10800 65 72 67 65 72 20 3d 20 30 3b 0a 20 20 20 20 20  erger = 0;.     
10810 20 69 6e 74 20 6e 52 65 61 64 65 72 20 3d 20 4d   int nReader = M
10820 49 4e 28 70 54 61 73 6b 2d 3e 6e 50 4d 41 20 2d  IN(pTask->nPMA -
10830 20 69 50 4d 41 2c 20 53 4f 52 54 45 52 5f 4d 41   iPMA, SORTER_MA
10840 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 29 3b 0a  X_MERGE_COUNT);.
10850 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65  .      rc = vdbe
10860 4d 65 72 67 65 45 6e 67 69 6e 65 4c 65 76 65 6c  MergeEngineLevel
10870 30 28 70 54 61 73 6b 2c 20 6e 52 65 61 64 65 72  0(pTask, nReader
10880 2c 20 26 69 52 65 61 64 4f 66 66 2c 20 26 70 4d  , &iReadOff, &pM
10890 65 72 67 65 72 29 3b 0a 20 20 20 20 20 20 69 66  erger);.      if
108a0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
108b0 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20  ) break;..      
108c0 69 66 28 20 69 50 4d 41 3d 3d 30 20 29 7b 0a 20  if( iPMA==0 ){. 
108d0 20 20 20 20 20 20 20 70 52 6f 6f 74 20 3d 20 70         pRoot = p
108e0 4d 65 72 67 65 72 3b 0a 20 20 20 20 20 20 7d 65  Merger;.      }e
108f0 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69 66 28  lse{.        if(
10900 20 70 52 6f 6f 74 20 29 7b 0a 20 20 20 20 20 20   pRoot ){.      
10910 20 20 20 20 72 63 20 3d 20 76 64 62 65 41 64 64      rc = vdbeAdd
10920 54 6f 42 75 69 6c 64 65 72 28 70 54 61 73 6b 2c  ToBuilder(pTask,
10930 20 26 61 4d 65 72 67 65 5b 30 5d 2c 20 70 52 6f   &aMerge[0], pRo
10940 6f 74 29 3b 0a 20 20 20 20 20 20 20 20 20 20 70  ot);.          p
10950 52 6f 6f 74 20 3d 20 30 3b 0a 20 20 20 20 20 20  Root = 0;.      
10960 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
10970 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  TE_OK ){.       
10980 20 20 20 20 20 76 64 62 65 4d 65 72 67 65 45 6e       vdbeMergeEn
10990 67 69 6e 65 46 72 65 65 28 70 4d 65 72 67 65 72  gineFree(pMerger
109a0 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 62  );.            b
109b0 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 20 20  reak;.          
109c0 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  }.        }.    
109d0 20 20 20 20 72 63 20 3d 20 76 64 62 65 41 64 64      rc = vdbeAdd
109e0 54 6f 42 75 69 6c 64 65 72 28 70 54 61 73 6b 2c  ToBuilder(pTask,
109f0 20 26 61 4d 65 72 67 65 5b 30 5d 2c 20 70 4d 65   &aMerge[0], pMe
10a00 72 67 65 72 29 3b 0a 20 20 20 20 20 20 20 20 69  rger);.        i
10a10 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
10a20 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20   ) break;.      
10a30 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  }.    }..    if(
10a40 20 70 52 6f 6f 74 3d 3d 30 20 29 7b 0a 20 20 20   pRoot==0 ){.   
10a50 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20     int i;.      
10a60 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c  for(i=0; rc==SQL
10a70 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e 4d 65 72  ITE_OK && i<nMer
10a80 67 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  ge; i++){.      
10a90 20 20 69 66 28 20 61 4d 65 72 67 65 5b 69 5d 2e    if( aMerge[i].
10aa0 70 4d 65 72 67 65 72 20 29 7b 0a 20 20 20 20 20  pMerger ){.     
10ab0 20 20 20 20 20 69 66 28 20 70 52 6f 6f 74 20 29       if( pRoot )
10ac0 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 63  {.            rc
10ad0 20 3d 20 76 64 62 65 41 64 64 54 6f 42 75 69 6c   = vdbeAddToBuil
10ae0 64 65 72 28 70 54 61 73 6b 2c 20 26 61 4d 65 72  der(pTask, &aMer
10af0 67 65 5b 69 5d 2c 20 70 52 6f 6f 74 29 3b 0a 20  ge[i], pRoot);. 
10b00 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20 72             if( r
10b10 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62  c!=SQLITE_OK ) b
10b20 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 20 20  reak;.          
10b30 7d 0a 20 20 20 20 20 20 20 20 20 20 70 52 6f 6f  }.          pRoo
10b40 74 20 3d 20 61 4d 65 72 67 65 5b 69 5d 2e 70 4d  t = aMerge[i].pM
10b50 65 72 67 65 72 3b 0a 20 20 20 20 20 20 20 20 20  erger;.         
10b60 20 61 4d 65 72 67 65 5b 69 5d 2e 70 4d 65 72 67   aMerge[i].pMerg
10b70 65 72 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  er = 0;.        
10b80 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  }.      }.    }.
10b90 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
10ba0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
10bb0 69 66 28 20 70 4d 61 69 6e 3d 3d 30 20 29 7b 0a  if( pMain==0 ){.
10bc0 20 20 20 20 20 20 20 20 70 4d 61 69 6e 20 3d 20          pMain = 
10bd0 70 52 6f 6f 74 3b 0a 20 20 20 20 20 20 7d 65 6c  pRoot;.      }el
10be0 73 65 7b 0a 20 20 20 20 20 20 20 20 49 6e 63 72  se{.        Incr
10bf0 4d 65 72 67 65 72 20 2a 70 4e 65 77 20 3d 20 76  Merger *pNew = v
10c00 64 62 65 49 6e 63 72 4e 65 77 28 70 54 61 73 6b  dbeIncrNew(pTask
10c10 2c 20 70 52 6f 6f 74 29 3b 0a 20 20 20 20 20 20  , pRoot);.      
10c20 20 20 70 4d 61 69 6e 2d 3e 61 49 74 65 72 5b 69    pMain->aIter[i
10c30 54 61 73 6b 5d 2e 70 49 6e 63 72 20 3d 20 70 4e  Task].pIncr = pN
10c40 65 77 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  ew;.        if( 
10c50 70 4e 65 77 3d 3d 30 20 29 20 72 63 20 3d 20 53  pNew==0 ) rc = S
10c60 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
10c70 20 20 20 7d 0a 20 20 20 20 20 20 6d 65 6d 73 65     }.      memse
10c80 74 28 61 4d 65 72 67 65 2c 20 30 2c 20 6e 4d 65  t(aMerge, 0, nMe
10c90 72 67 65 2a 73 69 7a 65 6f 66 28 61 4d 65 72 67  rge*sizeof(aMerg
10ca0 65 5b 30 5d 29 29 3b 0a 20 20 20 20 7d 0a 0a 20  e[0]));.    }.. 
10cb0 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
10cc0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 76 64  E_OK ){.      vd
10cd0 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46 72 65  beMergeEngineFre
10ce0 65 28 70 52 6f 6f 74 29 3b 0a 20 20 20 20 7d 0a  e(pRoot);.    }.
10cf0 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53    }..  if( rc==S
10d00 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 23 69 66 20  QLITE_OK ){.#if 
10d10 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45  SQLITE_MAX_WORKE
10d20 52 5f 54 48 52 45 41 44 53 0a 20 20 20 20 69 66  R_THREADS.    if
10d30 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54  ( pSorter->bUseT
10d40 68 72 65 61 64 73 20 29 7b 0a 20 20 20 20 20 20  hreads ){.      
10d50 50 6d 61 52 65 61 64 65 72 20 2a 70 49 74 65 72  PmaReader *pIter
10d60 3b 0a 20 20 20 20 20 20 53 6f 72 74 53 75 62 74  ;.      SortSubt
10d70 61 73 6b 20 2a 70 4c 61 73 74 20 3d 20 26 70 53  ask *pLast = &pS
10d80 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 70 53 6f  orter->aTask[pSo
10d90 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 5d 3b 0a  rter->nTask-1];.
10da0 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53        rc = vdbeS
10db0 6f 72 74 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64  ortAllocUnpacked
10dc0 28 70 4c 61 73 74 29 3b 0a 20 20 20 20 20 20 69  (pLast);.      i
10dd0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
10de0 20 29 7b 0a 20 20 20 20 20 20 20 20 70 49 74 65   ){.        pIte
10df0 72 20 3d 20 28 50 6d 61 52 65 61 64 65 72 2a 29  r = (PmaReader*)
10e00 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f 63 5a  sqlite3DbMallocZ
10e10 65 72 6f 28 64 62 2c 20 73 69 7a 65 6f 66 28 50  ero(db, sizeof(P
10e20 6d 61 52 65 61 64 65 72 29 29 3b 0a 20 20 20 20  maReader));.    
10e30 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 52 65      pSorter->pRe
10e40 61 64 65 72 20 3d 20 70 49 74 65 72 3b 0a 20 20  ader = pIter;.  
10e50 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
10e60 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
10e70 0a 20 20 20 20 20 20 20 20 70 49 74 65 72 2d 3e  .        pIter->
10e80 70 49 6e 63 72 20 3d 20 76 64 62 65 49 6e 63 72  pIncr = vdbeIncr
10e90 4e 65 77 28 70 4c 61 73 74 2c 20 70 4d 61 69 6e  New(pLast, pMain
10ea0 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70  );.        if( p
10eb0 49 74 65 72 2d 3e 70 49 6e 63 72 3d 3d 30 20 29  Iter->pIncr==0 )
10ec0 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d  {.          rc =
10ed0 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
10ee0 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
10ef0 20 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20   else{.         
10f00 20 76 64 62 65 49 6e 63 72 53 65 74 54 68 72 65   vdbeIncrSetThre
10f10 61 64 73 28 70 49 74 65 72 2d 3e 70 49 6e 63 72  ads(pIter->pIncr
10f20 2c 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54  , pSorter->bUseT
10f30 68 72 65 61 64 73 29 3b 0a 20 20 20 20 20 20 20  hreads);.       
10f40 20 20 20 66 6f 72 28 69 54 61 73 6b 3d 30 3b 20     for(iTask=0; 
10f50 69 54 61 73 6b 3c 28 70 53 6f 72 74 65 72 2d 3e  iTask<(pSorter->
10f60 6e 54 61 73 6b 2d 31 29 3b 20 69 54 61 73 6b 2b  nTask-1); iTask+
10f70 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  +){.            
10f80 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63  IncrMerger *pInc
10f90 72 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  r;.            i
10fa0 66 28 20 28 70 49 6e 63 72 20 3d 20 70 4d 61 69  f( (pIncr = pMai
10fb0 6e 2d 3e 61 49 74 65 72 5b 69 54 61 73 6b 5d 2e  n->aIter[iTask].
10fc0 70 49 6e 63 72 29 20 29 7b 0a 20 20 20 20 20 20  pIncr) ){.      
10fd0 20 20 20 20 20 20 20 20 76 64 62 65 49 6e 63 72          vdbeIncr
10fe0 53 65 74 54 68 72 65 61 64 73 28 70 49 6e 63 72  SetThreads(pIncr
10ff0 2c 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54  , pSorter->bUseT
11000 68 72 65 61 64 73 29 3b 0a 20 20 20 20 20 20 20  hreads);.       
11010 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70         assert( p
11020 49 6e 63 72 2d 3e 70 54 61 73 6b 21 3d 70 4c 61  Incr->pTask!=pLa
11030 73 74 20 29 3b 0a 20 20 20 20 20 20 20 20 20 20  st );.          
11040 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 7d 0a    }.          }.
11050 20 20 20 20 20 20 20 20 20 20 69 66 28 20 70 53            if( pS
11060 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3e 31 20 29  orter->nTask>1 )
11070 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f  {.            fo
11080 72 28 69 54 61 73 6b 3d 30 3b 20 72 63 3d 3d 53  r(iTask=0; rc==S
11090 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 54 61 73  QLITE_OK && iTas
110a0 6b 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b  k<pSorter->nTask
110b0 3b 20 69 54 61 73 6b 2b 2b 29 7b 0a 20 20 20 20  ; iTask++){.    
110c0 20 20 20 20 20 20 20 20 20 20 50 6d 61 52 65 61            PmaRea
110d0 64 65 72 20 2a 70 20 3d 20 26 70 4d 61 69 6e 2d  der *p = &pMain-
110e0 3e 61 49 74 65 72 5b 69 54 61 73 6b 5d 3b 0a 20  >aIter[iTask];. 
110f0 20 20 20 20 20 20 20 20 20 20 20 20 20 61 73 73               ass
11100 65 72 74 28 20 70 2d 3e 70 49 6e 63 72 3d 3d 30  ert( p->pIncr==0
11110 20 7c 7c 20 70 2d 3e 70 49 6e 63 72 2d 3e 70 54   || p->pIncr->pT
11120 61 73 6b 3d 3d 26 70 53 6f 72 74 65 72 2d 3e 61  ask==&pSorter->a
11130 54 61 73 6b 5b 69 54 61 73 6b 5d 20 29 3b 0a 20  Task[iTask] );. 
11140 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28               if(
11150 20 70 2d 3e 70 49 6e 63 72 20 29 7b 20 72 63 20   p->pIncr ){ rc 
11160 3d 20 76 64 62 65 49 6e 63 72 42 67 49 6e 69 74  = vdbeIncrBgInit
11170 32 28 70 29 3b 20 7d 0a 20 20 20 20 20 20 20 20  2(p); }.        
11180 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20      }.          
11190 7d 0a 20 20 20 20 20 20 20 20 20 20 70 4d 61 69  }.          pMai
111a0 6e 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7d  n = 0;.        }
111b0 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69  .      }.      i
111c0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
111d0 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   ){.        int 
111e0 65 4d 6f 64 65 20 3d 20 28 70 53 6f 72 74 65 72  eMode = (pSorter
111f0 2d 3e 6e 54 61 73 6b 3e 31 20 3f 20 49 4e 43 52  ->nTask>1 ? INCR
11200 49 4e 49 54 32 5f 52 4f 4f 54 20 3a 20 49 4e 43  INIT2_ROOT : INC
11210 52 49 4e 49 54 32 5f 4e 4f 52 4d 41 4c 29 3b 0a  RINIT2_NORMAL);.
11220 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62          rc = vdb
11230 65 49 6e 63 72 49 6e 69 74 32 28 70 49 74 65 72  eIncrInit2(pIter
11240 2c 20 65 4d 6f 64 65 29 3b 0a 20 20 20 20 20 20  , eMode);.      
11250 7d 0a 20 20 20 20 7d 65 6c 73 65 0a 23 65 6e 64  }.    }else.#end
11260 69 66 0a 20 20 20 20 7b 0a 20 20 20 20 20 20 70  if.    {.      p
11270 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 20  Sorter->pMerger 
11280 3d 20 70 4d 61 69 6e 3b 0a 20 20 20 20 20 20 72  = pMain;.      r
11290 63 20 3d 20 76 64 62 65 49 6e 63 72 49 6e 69 74  c = vdbeIncrInit
112a0 4d 65 72 67 65 72 28 70 54 61 73 6b 30 2c 20 70  Merger(pTask0, p
112b0 4d 61 69 6e 2c 20 49 4e 43 52 49 4e 49 54 32 5f  Main, INCRINIT2_
112c0 4e 4f 52 4d 41 4c 29 3b 0a 20 20 20 20 20 20 70  NORMAL);.      p
112d0 4d 61 69 6e 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  Main = 0;.    }.
112e0 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53    }..  if( rc!=S
112f0 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
11300 69 6e 74 20 69 3b 0a 20 20 20 20 66 6f 72 28 69  int i;.    for(i
11310 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  =0; rc==SQLITE_O
11320 4b 20 26 26 20 69 3c 6e 4d 65 72 67 65 3b 20 69  K && i<nMerge; i
11330 2b 2b 29 7b 0a 20 20 20 20 20 20 76 64 62 65 4d  ++){.      vdbeM
11340 65 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28 61  ergeEngineFree(a
11350 4d 65 72 67 65 5b 69 5d 2e 70 4d 65 72 67 65 72  Merge[i].pMerger
11360 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 76 64 62  );.    }.    vdb
11370 65 4d 65 72 67 65 45 6e 67 69 6e 65 46 72 65 65  eMergeEngineFree
11380 28 70 4d 61 69 6e 29 3b 0a 20 20 7d 0a 20 20 73  (pMain);.  }.  s
11390 71 6c 69 74 65 33 5f 66 72 65 65 28 61 4d 65 72  qlite3_free(aMer
113a0 67 65 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  ge);.  return rc
113b0 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 4f 6e 63 65  ;.}.../*.** Once
113c0 20 74 68 65 20 73 6f 72 74 65 72 20 68 61 73 20   the sorter has 
113d0 62 65 65 6e 20 70 6f 70 75 6c 61 74 65 64 20 62  been populated b
113e0 79 20 63 61 6c 6c 73 20 74 6f 20 73 71 6c 69 74  y calls to sqlit
113f0 65 33 56 64 62 65 53 6f 72 74 65 72 57 72 69 74  e3VdbeSorterWrit
11400 65 2c 0a 2a 2a 20 74 68 69 73 20 66 75 6e 63 74  e,.** this funct
11410 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f  ion is called to
11420 20 70 72 65 70 61 72 65 20 66 6f 72 20 69 74 65   prepare for ite
11430 72 61 74 69 6e 67 20 74 68 72 6f 75 67 68 20 74  rating through t
11440 68 65 20 72 65 63 6f 72 64 73 0a 2a 2a 20 69 6e  he records.** in
11450 20 73 6f 72 74 65 64 20 6f 72 64 65 72 2e 0a 2a   sorted order..*
11460 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62  /.int sqlite3Vdb
11470 65 53 6f 72 74 65 72 52 65 77 69 6e 64 28 73 71  eSorterRewind(sq
11480 6c 69 74 65 33 20 2a 64 62 2c 20 63 6f 6e 73 74  lite3 *db, const
11490 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73   VdbeCursor *pCs
114a0 72 2c 20 69 6e 74 20 2a 70 62 45 6f 66 29 7b 0a  r, int *pbEof){.
114b0 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
114c0 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53  orter = pCsr->pS
114d0 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 72 63 20  orter;.  int rc 
114e0 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20  = SQLITE_OK;    
114f0 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
11500 72 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 61 73  rn code */..  as
11510 73 65 72 74 28 20 70 53 6f 72 74 65 72 20 29 3b  sert( pSorter );
11520 0a 0a 20 20 2f 2a 20 49 66 20 6e 6f 20 64 61 74  ..  /* If no dat
11530 61 20 68 61 73 20 62 65 65 6e 20 77 72 69 74 74  a has been writt
11540 65 6e 20 74 6f 20 64 69 73 6b 2c 20 74 68 65 6e  en to disk, then
11550 20 64 6f 20 6e 6f 74 20 64 6f 20 73 6f 20 6e 6f   do not do so no
11560 77 2e 20 49 6e 73 74 65 61 64 2c 0a 20 20 2a 2a  w. Instead,.  **
11570 20 73 6f 72 74 20 74 68 65 20 56 64 62 65 53 6f   sort the VdbeSo
11580 72 74 65 72 2e 70 52 65 63 6f 72 64 20 6c 69 73  rter.pRecord lis
11590 74 2e 20 54 68 65 20 76 64 62 65 20 6c 61 79 65  t. The vdbe laye
115a0 72 20 77 69 6c 6c 20 72 65 61 64 20 64 61 74 61  r will read data
115b0 20 64 69 72 65 63 74 6c 79 0a 20 20 2a 2a 20 66   directly.  ** f
115c0 72 6f 6d 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72  rom the in-memor
115d0 79 20 6c 69 73 74 2e 20 20 2a 2f 0a 20 20 69 66  y list.  */.  if
115e0 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 50  ( pSorter->bUseP
115f0 4d 41 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28  MA==0 ){.    if(
11600 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70   pSorter->list.p
11610 4c 69 73 74 20 29 7b 0a 20 20 20 20 20 20 2a 70  List ){.      *p
11620 62 45 6f 66 20 3d 20 30 3b 0a 20 20 20 20 20 20  bEof = 0;.      
11630 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 53  rc = vdbeSorterS
11640 6f 72 74 28 26 70 53 6f 72 74 65 72 2d 3e 61 54  ort(&pSorter->aT
11650 61 73 6b 5b 30 5d 2c 20 26 70 53 6f 72 74 65 72  ask[0], &pSorter
11660 2d 3e 6c 69 73 74 29 3b 0a 20 20 20 20 7d 65 6c  ->list);.    }el
11670 73 65 7b 0a 20 20 20 20 20 20 2a 70 62 45 6f 66  se{.      *pbEof
11680 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20   = 1;.    }.    
11690 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a  return rc;.  }..
116a0 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 63    /* Write the c
116b0 75 72 72 65 6e 74 20 69 6e 2d 6d 65 6d 6f 72 79  urrent in-memory
116c0 20 6c 69 73 74 20 74 6f 20 61 20 50 4d 41 2e 20   list to a PMA. 
116d0 2a 2f 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72  */.  if( pSorter
116e0 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 29 7b 0a  ->list.pList ){.
116f0 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
11700 74 65 72 46 6c 75 73 68 50 4d 41 28 70 53 6f 72  terFlushPMA(pSor
11710 74 65 72 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  ter);.  }..  /* 
11720 4a 6f 69 6e 20 61 6c 6c 20 74 68 72 65 61 64 73  Join all threads
11730 20 2a 2f 0a 20 20 72 63 20 3d 20 76 64 62 65 53   */.  rc = vdbeS
11740 6f 72 74 65 72 4a 6f 69 6e 41 6c 6c 28 70 53 6f  orterJoinAll(pSo
11750 72 74 65 72 2c 20 72 63 29 3b 0a 0a 20 20 76 64  rter, rc);..  vd
11760 62 65 53 6f 72 74 65 72 52 65 77 69 6e 64 44 65  beSorterRewindDe
11770 62 75 67 28 64 62 2c 20 22 72 65 77 69 6e 64 22  bug(db, "rewind"
11780 29 3b 0a 0a 20 20 2f 2a 20 41 73 73 75 6d 69 6e  );..  /* Assumin
11790 67 20 6e 6f 20 65 72 72 6f 72 73 20 68 61 76 65  g no errors have
117a0 20 6f 63 63 75 72 72 65 64 2c 20 73 65 74 20 75   occurred, set u
117b0 70 20 61 20 6d 65 72 67 65 72 20 73 74 72 75 63  p a merger struc
117c0 74 75 72 65 20 74 6f 20 0a 20 20 2a 2a 20 69 6e  ture to .  ** in
117d0 63 72 65 6d 65 6e 74 61 6c 6c 79 20 72 65 61 64  crementally read
117e0 20 61 6e 64 20 6d 65 72 67 65 20 61 6c 6c 20 72   and merge all r
117f0 65 6d 61 69 6e 69 6e 67 20 50 4d 41 73 2e 20 20  emaining PMAs.  
11800 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 53 6f  */.  assert( pSo
11810 72 74 65 72 2d 3e 70 52 65 61 64 65 72 3d 3d 30  rter->pReader==0
11820 20 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   );.  if( rc==SQ
11830 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
11840 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65  c = vdbePmaReade
11850 72 49 6e 63 72 49 6e 69 74 28 70 53 6f 72 74 65  rIncrInit(pSorte
11860 72 29 3b 0a 20 20 20 20 2a 70 62 45 6f 66 20 3d  r);.    *pbEof =
11870 20 30 3b 0a 20 20 7d 0a 0a 20 20 76 64 62 65 53   0;.  }..  vdbeS
11880 6f 72 74 65 72 52 65 77 69 6e 64 44 65 62 75 67  orterRewindDebug
11890 28 64 62 2c 20 22 72 65 77 69 6e 64 64 6f 6e 65  (db, "rewinddone
118a0 22 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ");.  return rc;
118b0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63  .}../*.** Advanc
118c0 65 20 74 6f 20 74 68 65 20 6e 65 78 74 20 65 6c  e to the next el
118d0 65 6d 65 6e 74 20 69 6e 20 74 68 65 20 73 6f 72  ement in the sor
118e0 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  ter..*/.int sqli
118f0 74 65 33 56 64 62 65 53 6f 72 74 65 72 4e 65 78  te3VdbeSorterNex
11900 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 63  t(sqlite3 *db, c
11910 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72 20  onst VdbeCursor 
11920 2a 70 43 73 72 2c 20 69 6e 74 20 2a 70 62 45 6f  *pCsr, int *pbEo
11930 66 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72  f){.  VdbeSorter
11940 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72   *pSorter = pCsr
11950 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74  ->pSorter;.  int
11960 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
11970 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
11980 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 0a  Return code */..
11990 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65    assert( pSorte
119a0 72 2d 3e 62 55 73 65 50 4d 41 20 7c 7c 20 28 70  r->bUsePMA || (p
119b0 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72 3d  Sorter->pReader=
119c0 3d 30 20 26 26 20 70 53 6f 72 74 65 72 2d 3e 70  =0 && pSorter->p
119d0 4d 65 72 67 65 72 3d 3d 30 29 20 29 3b 0a 20 20  Merger==0) );.  
119e0 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73  if( pSorter->bUs
119f0 65 50 4d 41 20 29 7b 0a 20 20 20 20 61 73 73 65  ePMA ){.    asse
11a00 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 70 52 65  rt( pSorter->pRe
11a10 61 64 65 72 3d 3d 30 20 7c 7c 20 70 53 6f 72 74  ader==0 || pSort
11a20 65 72 2d 3e 70 4d 65 72 67 65 72 3d 3d 30 20 29  er->pMerger==0 )
11a30 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 53  ;.    assert( pS
11a40 6f 72 74 65 72 2d 3e 62 55 73 65 54 68 72 65 61  orter->bUseThrea
11a50 64 73 3d 3d 30 20 7c 7c 20 70 53 6f 72 74 65 72  ds==0 || pSorter
11a60 2d 3e 70 52 65 61 64 65 72 20 29 3b 0a 20 20 20  ->pReader );.   
11a70 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72   assert( pSorter
11a80 2d 3e 62 55 73 65 54 68 72 65 61 64 73 3d 3d 31  ->bUseThreads==1
11a90 20 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65   || pSorter->pMe
11aa0 72 67 65 72 20 29 3b 0a 20 20 20 20 69 66 28 20  rger );.    if( 
11ab0 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68 72  pSorter->bUseThr
11ac0 65 61 64 73 20 29 7b 0a 20 20 20 20 20 20 72 63  eads ){.      rc
11ad0 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65 72   = vdbePmaReader
11ae0 4e 65 78 74 28 70 53 6f 72 74 65 72 2d 3e 70 52  Next(pSorter->pR
11af0 65 61 64 65 72 29 3b 0a 20 20 20 20 20 20 2a 70  eader);.      *p
11b00 62 45 6f 66 20 3d 20 28 70 53 6f 72 74 65 72 2d  bEof = (pSorter-
11b10 3e 70 52 65 61 64 65 72 2d 3e 70 46 69 6c 65 3d  >pReader->pFile=
11b20 3d 30 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  =0);.    }else{.
11b30 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53        rc = vdbeS
11b40 6f 72 74 65 72 4e 65 78 74 28 26 70 53 6f 72 74  orterNext(&pSort
11b50 65 72 2d 3e 61 54 61 73 6b 5b 30 5d 2c 20 70 53  er->aTask[0], pS
11b60 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 2c 20  orter->pMerger, 
11b70 70 62 45 6f 66 29 3b 0a 20 20 20 20 7d 0a 20 20  pbEof);.    }.  
11b80 7d 65 6c 73 65 7b 0a 20 20 20 20 53 6f 72 74 65  }else{.    Sorte
11b90 72 52 65 63 6f 72 64 20 2a 70 46 72 65 65 20 3d  rRecord *pFree =
11ba0 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70   pSorter->list.p
11bb0 4c 69 73 74 3b 0a 20 20 20 20 70 53 6f 72 74 65  List;.    pSorte
11bc0 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d 20  r->list.pList = 
11bd0 70 46 72 65 65 2d 3e 75 2e 70 4e 65 78 74 3b 0a  pFree->u.pNext;.
11be0 20 20 20 20 70 46 72 65 65 2d 3e 75 2e 70 4e 65      pFree->u.pNe
11bf0 78 74 20 3d 20 30 3b 0a 20 20 20 20 69 66 28 20  xt = 0;.    if( 
11c00 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d  pSorter->list.aM
11c10 65 6d 6f 72 79 3d 3d 30 20 29 20 76 64 62 65 53  emory==0 ) vdbeS
11c20 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65 65 28  orterRecordFree(
11c30 64 62 2c 20 70 46 72 65 65 29 3b 0a 20 20 20 20  db, pFree);.    
11c40 2a 70 62 45 6f 66 20 3d 20 21 70 53 6f 72 74 65  *pbEof = !pSorte
11c50 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 3b 0a 20  r->list.pList;. 
11c60 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f     rc = SQLITE_O
11c70 4b 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  K;.  }.  return 
11c80 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  rc;.}../*.** Ret
11c90 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f  urn a pointer to
11ca0 20 61 20 62 75 66 66 65 72 20 6f 77 6e 65 64 20   a buffer owned 
11cb0 62 79 20 74 68 65 20 73 6f 72 74 65 72 20 74 68  by the sorter th
11cc0 61 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  at contains the 
11cd0 0a 2a 2a 20 63 75 72 72 65 6e 74 20 6b 65 79 2e  .** current key.
11ce0 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
11cf0 2a 76 64 62 65 53 6f 72 74 65 72 52 6f 77 6b 65  *vdbeSorterRowke
11d00 79 28 0a 20 20 63 6f 6e 73 74 20 56 64 62 65 53  y(.  const VdbeS
11d10 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 2c 20  orter *pSorter, 
11d20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 6f       /* Sorter o
11d30 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e 74 20 2a  bject */.  int *
11d40 70 6e 4b 65 79 20 20 20 20 20 20 20 20 20 20 20  pnKey           
11d50 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
11d60 54 3a 20 53 69 7a 65 20 6f 66 20 63 75 72 72 65  T: Size of curre
11d70 6e 74 20 6b 65 79 20 69 6e 20 62 79 74 65 73 20  nt key in bytes 
11d80 2a 2f 0a 29 7b 0a 20 20 76 6f 69 64 20 2a 70 4b  */.){.  void *pK
11d90 65 79 3b 0a 20 20 69 66 28 20 70 53 6f 72 74 65  ey;.  if( pSorte
11da0 72 2d 3e 62 55 73 65 50 4d 41 20 29 7b 0a 20 20  r->bUsePMA ){.  
11db0 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70 52 65    PmaReader *pRe
11dc0 61 64 65 72 20 3d 20 28 70 53 6f 72 74 65 72 2d  ader = (pSorter-
11dd0 3e 62 55 73 65 54 68 72 65 61 64 73 20 3f 0a 20  >bUseThreads ?. 
11de0 20 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e         pSorter->
11df0 70 52 65 61 64 65 72 20 3a 20 26 70 53 6f 72 74  pReader : &pSort
11e00 65 72 2d 3e 70 4d 65 72 67 65 72 2d 3e 61 49 74  er->pMerger->aIt
11e10 65 72 5b 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72  er[pSorter->pMer
11e20 67 65 72 2d 3e 61 54 72 65 65 5b 31 5d 5d 0a 20  ger->aTree[1]]. 
11e30 20 20 20 29 3b 0a 20 20 20 20 2a 70 6e 4b 65 79     );.    *pnKey
11e40 20 3d 20 70 52 65 61 64 65 72 2d 3e 6e 4b 65 79   = pReader->nKey
11e50 3b 0a 20 20 20 20 70 4b 65 79 20 3d 20 70 52 65  ;.    pKey = pRe
11e60 61 64 65 72 2d 3e 61 4b 65 79 3b 0a 20 20 7d 65  ader->aKey;.  }e
11e70 6c 73 65 7b 0a 20 20 20 20 2a 70 6e 4b 65 79 20  lse{.    *pnKey 
11e80 3d 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e  = pSorter->list.
11e90 70 4c 69 73 74 2d 3e 6e 56 61 6c 3b 0a 20 20 20  pList->nVal;.   
11ea0 20 70 4b 65 79 20 3d 20 53 52 56 41 4c 28 70 53   pKey = SRVAL(pS
11eb0 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73  orter->list.pLis
11ec0 74 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  t);.  }.  return
11ed0 20 70 4b 65 79 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20   pKey;.}../*.** 
11ee0 43 6f 70 79 20 74 68 65 20 63 75 72 72 65 6e 74  Copy the current
11ef0 20 73 6f 72 74 65 72 20 6b 65 79 20 69 6e 74 6f   sorter key into
11f00 20 74 68 65 20 6d 65 6d 6f 72 79 20 63 65 6c 6c   the memory cell
11f10 20 70 4f 75 74 2e 0a 2a 2f 0a 69 6e 74 20 73 71   pOut..*/.int sq
11f20 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 52  lite3VdbeSorterR
11f30 6f 77 6b 65 79 28 63 6f 6e 73 74 20 56 64 62 65  owkey(const Vdbe
11f40 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 4d 65  Cursor *pCsr, Me
11f50 6d 20 2a 70 4f 75 74 29 7b 0a 20 20 56 64 62 65  m *pOut){.  Vdbe
11f60 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20  Sorter *pSorter 
11f70 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b  = pCsr->pSorter;
11f80 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 3b 20 69  .  void *pKey; i
11f90 6e 74 20 6e 4b 65 79 3b 20 20 20 20 20 20 20 20  nt nKey;        
11fa0 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 6b 65 79     /* Sorter key
11fb0 20 74 6f 20 63 6f 70 79 20 69 6e 74 6f 20 70 4f   to copy into pO
11fc0 75 74 20 2a 2f 0a 0a 20 20 70 4b 65 79 20 3d 20  ut */..  pKey = 
11fd0 76 64 62 65 53 6f 72 74 65 72 52 6f 77 6b 65 79  vdbeSorterRowkey
11fe0 28 70 53 6f 72 74 65 72 2c 20 26 6e 4b 65 79 29  (pSorter, &nKey)
11ff0 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33 56  ;.  if( sqlite3V
12000 64 62 65 4d 65 6d 47 72 6f 77 28 70 4f 75 74 2c  dbeMemGrow(pOut,
12010 20 6e 4b 65 79 2c 20 30 29 20 29 7b 0a 20 20 20   nKey, 0) ){.   
12020 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
12030 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 70 4f 75 74  OMEM;.  }.  pOut
12040 2d 3e 6e 20 3d 20 6e 4b 65 79 3b 0a 20 20 4d 65  ->n = nKey;.  Me
12050 6d 53 65 74 54 79 70 65 46 6c 61 67 28 70 4f 75  mSetTypeFlag(pOu
12060 74 2c 20 4d 45 4d 5f 42 6c 6f 62 29 3b 0a 20 20  t, MEM_Blob);.  
12070 6d 65 6d 63 70 79 28 70 4f 75 74 2d 3e 7a 2c 20  memcpy(pOut->z, 
12080 70 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 0a 20 20  pKey, nKey);..  
12090 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
120a0 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 61  ;.}../*.** Compa
120b0 72 65 20 74 68 65 20 6b 65 79 20 69 6e 20 6d 65  re the key in me
120c0 6d 6f 72 79 20 63 65 6c 6c 20 70 56 61 6c 20 77  mory cell pVal w
120d0 69 74 68 20 74 68 65 20 6b 65 79 20 74 68 61 74  ith the key that
120e0 20 74 68 65 20 73 6f 72 74 65 72 20 63 75 72 73   the sorter curs
120f0 6f 72 0a 2a 2a 20 70 61 73 73 65 64 20 61 73 20  or.** passed as 
12100 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65  the first argume
12110 6e 74 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69  nt currently poi
12120 6e 74 73 20 74 6f 2e 20 46 6f 72 20 74 68 65 20  nts to. For the 
12130 70 75 72 70 6f 73 65 73 20 6f 66 0a 2a 2a 20 74  purposes of.** t
12140 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2c 20 69  he comparison, i
12150 67 6e 6f 72 65 20 74 68 65 20 72 6f 77 69 64 20  gnore the rowid 
12160 66 69 65 6c 64 20 61 74 20 74 68 65 20 65 6e 64  field at the end
12170 20 6f 66 20 65 61 63 68 20 72 65 63 6f 72 64 2e   of each record.
12180 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 73 6f  .**.** If the so
12190 72 74 65 72 20 63 75 72 73 6f 72 20 6b 65 79 20  rter cursor key 
121a0 63 6f 6e 74 61 69 6e 73 20 61 6e 79 20 4e 55 4c  contains any NUL
121b0 4c 20 76 61 6c 75 65 73 2c 20 63 6f 6e 73 69 64  L values, consid
121c0 65 72 20 69 74 20 74 6f 20 62 65 0a 2a 2a 20 6c  er it to be.** l
121d0 65 73 73 20 74 68 61 6e 20 70 56 61 6c 2e 20 45  ess than pVal. E
121e0 76 65 6e 20 69 66 20 70 56 61 6c 20 61 6c 73 6f  ven if pVal also
121f0 20 63 6f 6e 74 61 69 6e 73 20 4e 55 4c 4c 20 76   contains NULL v
12200 61 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  alues..**.** If 
12210 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c  an error occurs,
12220 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74   return an SQLit
12230 65 20 65 72 72 6f 72 20 63 6f 64 65 20 28 69 2e  e error code (i.
12240 65 2e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29  e. SQLITE_NOMEM)
12250 2e 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20  ..** Otherwise, 
12260 73 65 74 20 2a 70 52 65 73 20 74 6f 20 61 20 6e  set *pRes to a n
12270 65 67 61 74 69 76 65 2c 20 7a 65 72 6f 20 6f 72  egative, zero or
12280 20 70 6f 73 69 74 69 76 65 20 76 61 6c 75 65 20   positive value 
12290 69 66 20 74 68 65 0a 2a 2a 20 6b 65 79 20 69 6e  if the.** key in
122a0 20 70 56 61 6c 20 69 73 20 73 6d 61 6c 6c 65 72   pVal is smaller
122b0 20 74 68 61 6e 2c 20 65 71 75 61 6c 20 74 6f 20   than, equal to 
122c0 6f 72 20 6c 61 72 67 65 72 20 74 68 61 6e 20 74  or larger than t
122d0 68 65 20 63 75 72 72 65 6e 74 20 73 6f 72 74 65  he current sorte
122e0 72 0a 2a 2a 20 6b 65 79 2e 0a 2a 2a 0a 2a 2a 20  r.** key..**.** 
122f0 54 68 69 73 20 72 6f 75 74 69 6e 65 20 66 6f 72  This routine for
12300 6d 73 20 74 68 65 20 63 6f 72 65 20 6f 66 20 74  ms the core of t
12310 68 65 20 4f 50 5f 53 6f 72 74 65 72 43 6f 6d 70  he OP_SorterComp
12320 61 72 65 20 6f 70 63 6f 64 65 2c 20 77 68 69 63  are opcode, whic
12330 68 20 69 6e 0a 2a 2a 20 74 75 72 6e 20 69 73 20  h in.** turn is 
12340 75 73 65 64 20 74 6f 20 76 65 72 69 66 79 20 75  used to verify u
12350 6e 69 71 75 65 6e 65 73 73 20 77 68 65 6e 20 63  niqueness when c
12360 6f 6e 73 74 72 75 63 74 69 6e 67 20 61 20 55 4e  onstructing a UN
12370 49 51 55 45 20 49 4e 44 45 58 2e 0a 2a 2f 0a 69  IQUE INDEX..*/.i
12380 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f  nt sqlite3VdbeSo
12390 72 74 65 72 43 6f 6d 70 61 72 65 28 0a 20 20 63  rterCompare(.  c
123a0 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72 20  onst VdbeCursor 
123b0 2a 70 43 73 72 2c 20 20 20 20 20 20 20 20 20 2f  *pCsr,         /
123c0 2a 20 53 6f 72 74 65 72 20 63 75 72 73 6f 72 20  * Sorter cursor 
123d0 2a 2f 0a 20 20 4d 65 6d 20 2a 70 56 61 6c 2c 20  */.  Mem *pVal, 
123e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
123f0 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 74 6f       /* Value to
12400 20 63 6f 6d 70 61 72 65 20 74 6f 20 63 75 72 72   compare to curr
12410 65 6e 74 20 73 6f 72 74 65 72 20 6b 65 79 20 2a  ent sorter key *
12420 2f 0a 20 20 69 6e 74 20 6e 49 67 6e 6f 72 65 2c  /.  int nIgnore,
12430 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12440 20 20 20 20 2f 2a 20 49 67 6e 6f 72 65 20 74 68      /* Ignore th
12450 69 73 20 6d 61 6e 79 20 66 69 65 6c 64 73 20 61  is many fields a
12460 74 20 74 68 65 20 65 6e 64 20 2a 2f 0a 20 20 69  t the end */.  i
12470 6e 74 20 2a 70 52 65 73 20 20 20 20 20 20 20 20  nt *pRes        
12480 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
12490 2a 20 4f 55 54 3a 20 52 65 73 75 6c 74 20 6f 66  * OUT: Result of
124a0 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f 0a 29   comparison */.)
124b0 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a  {.  VdbeSorter *
124c0 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e  pSorter = pCsr->
124d0 70 53 6f 72 74 65 72 3b 0a 20 20 55 6e 70 61 63  pSorter;.  Unpac
124e0 6b 65 64 52 65 63 6f 72 64 20 2a 72 32 20 3d 20  kedRecord *r2 = 
124f0 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b  pSorter->pUnpack
12500 65 64 3b 0a 20 20 4b 65 79 49 6e 66 6f 20 2a 70  ed;.  KeyInfo *p
12510 4b 65 79 49 6e 66 6f 20 3d 20 70 43 73 72 2d 3e  KeyInfo = pCsr->
12520 70 4b 65 79 49 6e 66 6f 3b 0a 20 20 69 6e 74 20  pKeyInfo;.  int 
12530 69 3b 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 3b  i;.  void *pKey;
12540 20 69 6e 74 20 6e 4b 65 79 3b 20 20 20 20 20 20   int nKey;      
12550 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 6b       /* Sorter k
12560 65 79 20 74 6f 20 63 6f 6d 70 61 72 65 20 70 56  ey to compare pV
12570 61 6c 20 77 69 74 68 20 2a 2f 0a 0a 20 20 69 66  al with */..  if
12580 28 20 72 32 3d 3d 30 20 29 7b 0a 20 20 20 20 63  ( r2==0 ){.    c
12590 68 61 72 20 2a 70 3b 0a 20 20 20 20 72 32 20 3d  har *p;.    r2 =
125a0 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63   pSorter->pUnpac
125b0 6b 65 64 20 3d 20 73 71 6c 69 74 65 33 56 64 62  ked = sqlite3Vdb
125c0 65 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64 52 65  eAllocUnpackedRe
125d0 63 6f 72 64 28 70 4b 65 79 49 6e 66 6f 2c 30 2c  cord(pKeyInfo,0,
125e0 30 2c 26 70 29 3b 0a 20 20 20 20 61 73 73 65 72  0,&p);.    asser
125f0 74 28 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70  t( pSorter->pUnp
12600 61 63 6b 65 64 3d 3d 28 55 6e 70 61 63 6b 65 64  acked==(Unpacked
12610 52 65 63 6f 72 64 2a 29 70 20 29 3b 0a 20 20 20  Record*)p );.   
12620 20 69 66 28 20 72 32 3d 3d 30 20 29 20 72 65 74   if( r2==0 ) ret
12630 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
12640 3b 0a 20 20 20 20 72 32 2d 3e 6e 46 69 65 6c 64  ;.    r2->nField
12650 20 3d 20 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69   = pKeyInfo->nFi
12660 65 6c 64 2d 6e 49 67 6e 6f 72 65 3b 0a 20 20 7d  eld-nIgnore;.  }
12670 0a 20 20 61 73 73 65 72 74 28 20 72 32 2d 3e 6e  .  assert( r2->n
12680 46 69 65 6c 64 3e 3d 70 4b 65 79 49 6e 66 6f 2d  Field>=pKeyInfo-
12690 3e 6e 46 69 65 6c 64 2d 6e 49 67 6e 6f 72 65 20  >nField-nIgnore 
126a0 29 3b 0a 0a 20 20 70 4b 65 79 20 3d 20 76 64 62  );..  pKey = vdb
126b0 65 53 6f 72 74 65 72 52 6f 77 6b 65 79 28 70 53  eSorterRowkey(pS
126c0 6f 72 74 65 72 2c 20 26 6e 4b 65 79 29 3b 0a 20  orter, &nKey);. 
126d0 20 73 71 6c 69 74 65 33 56 64 62 65 52 65 63 6f   sqlite3VdbeReco
126e0 72 64 55 6e 70 61 63 6b 28 70 4b 65 79 49 6e 66  rdUnpack(pKeyInf
126f0 6f 2c 20 6e 4b 65 79 2c 20 70 4b 65 79 2c 20 72  o, nKey, pKey, r
12700 32 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  2);.  for(i=0; i
12710 3c 72 32 2d 3e 6e 46 69 65 6c 64 3b 20 69 2b 2b  <r2->nField; i++
12720 29 7b 0a 20 20 20 20 69 66 28 20 72 32 2d 3e 61  ){.    if( r2->a
12730 4d 65 6d 5b 69 5d 2e 66 6c 61 67 73 20 26 20 4d  Mem[i].flags & M
12740 45 4d 5f 4e 75 6c 6c 20 29 7b 0a 20 20 20 20 20  EM_Null ){.     
12750 20 2a 70 52 65 73 20 3d 20 2d 31 3b 0a 20 20 20   *pRes = -1;.   
12760 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
12770 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  _OK;.    }.  }..
12780 20 20 2a 70 52 65 73 20 3d 20 73 71 6c 69 74 65    *pRes = sqlite
12790 33 56 64 62 65 52 65 63 6f 72 64 43 6f 6d 70 61  3VdbeRecordCompa
127a0 72 65 28 70 56 61 6c 2d 3e 6e 2c 20 70 56 61 6c  re(pVal->n, pVal
127b0 2d 3e 7a 2c 20 72 32 2c 20 30 29 3b 0a 20 20 72  ->z, r2, 0);.  r
127c0 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
127d0 0a 7d 0a                                         .}.