/ Hex Artifact Content
Login

Artifact e2784e2e1f1819a55ce6f22c6ab22eca576ae6d8:


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 73 20 62 65 69 6e 67 20 73 6f 72 74 65  ents being sorte
0310: 64 0a 2a 2a 20 65 78 63 65 65 64 73 20 74 68 65  d.** exceeds the
0320: 20 61 76 61 69 6c 61 62 6c 65 20 6d 65 6d 6f 72   available memor
0330: 79 2e 0a 2a 2a 0a 2a 2a 20 48 65 72 65 20 69 73  y..**.** Here is
0340: 20 74 68 65 20 28 69 6e 74 65 72 6e 61 6c 2c 20   the (internal, 
0350: 6e 6f 6e 2d 41 50 49 29 20 69 6e 74 65 72 66 61  non-API) interfa
0360: 63 65 20 62 65 74 77 65 65 6e 20 74 68 69 73 20  ce between this 
0370: 6d 6f 64 75 6c 65 20 61 6e 64 20 74 68 65 0a 2a  module and the.*
0380: 2a 20 72 65 73 74 20 6f 66 20 74 68 65 20 53 51  * rest of the SQ
0390: 4c 69 74 65 20 73 79 73 74 65 6d 3a 0a 2a 2a 0a  Lite system:.**.
03a0: 2a 2a 20 20 20 20 73 71 6c 69 74 65 33 56 64 62  **    sqlite3Vdb
03b0: 65 53 6f 72 74 65 72 49 6e 69 74 28 29 20 20 20  eSorterInit()   
03c0: 20 20 20 20 43 72 65 61 74 65 20 61 20 6e 65 77      Create a new
03d0: 20 56 64 62 65 53 6f 72 74 65 72 20 6f 62 6a 65   VdbeSorter obje
03e0: 63 74 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71 6c  ct..**.**    sql
03f0: 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 57 72  ite3VdbeSorterWr
0400: 69 74 65 28 29 20 20 20 20 20 20 41 64 64 20 61  ite()      Add a
0410: 20 73 69 6e 67 6c 65 20 6e 65 77 20 72 6f 77 20   single new row 
0420: 74 6f 20 74 68 65 20 56 64 62 65 53 6f 72 74 65  to the VdbeSorte
0430: 72 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20  r.**            
0440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0450: 20 20 20 20 20 20 6f 62 6a 65 63 74 2e 20 20 54        object.  T
0460: 68 65 20 72 6f 77 20 69 73 20 61 20 62 69 6e 61  he row is a bina
0470: 72 79 20 62 6c 6f 62 20 69 6e 20 74 68 65 0a 2a  ry blob in the.*
0480: 2a 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 20 4f 50 5f 4d 61 6b 65 52 65 63 6f 72 64     OP_MakeRecord
04b0: 20 66 6f 72 6d 61 74 20 74 68 61 74 20 63 6f 6e   format that con
04c0: 74 61 69 6e 73 20 62 6f 74 68 0a 2a 2a 20 20 20  tains 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 20 74                 t
04f0: 68 65 20 4f 52 44 45 52 20 42 59 20 6b 65 79 20  he ORDER BY key 
0500: 63 6f 6c 75 6d 6e 73 20 61 6e 64 20 72 65 73 75  columns and resu
0510: 6c 74 20 63 6f 6c 75 6d 6e 73 0a 2a 2a 20 20 20  lt 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 20 69                 i
0540: 6e 20 74 68 65 20 63 61 73 65 20 6f 66 20 61 20  n the case of a 
0550: 53 45 4c 45 43 54 20 77 2f 20 4f 52 44 45 52 20  SELECT w/ ORDER 
0560: 42 59 2c 20 6f 72 0a 2a 2a 20 20 20 20 20 20 20  BY, 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 20 74 68 65 20 63             the c
0590: 6f 6d 70 6c 65 74 65 20 72 65 63 6f 72 64 20 66  omplete record f
05a0: 6f 72 20 61 6e 20 69 6e 64 65 78 20 65 6e 74 72  or an index entr
05b0: 79 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20  y.**            
05c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05d0: 20 20 20 20 20 20 69 6e 20 74 68 65 20 63 61 73        in the cas
05e0: 65 20 6f 66 20 61 20 43 52 45 41 54 45 20 49 4e  e of a CREATE IN
05f0: 44 45 58 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71  DEX..**.**    sq
0600: 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 52  lite3VdbeSorterR
0610: 65 77 69 6e 64 28 29 20 20 20 20 20 53 6f 72 74  ewind()     Sort
0620: 20 61 6c 6c 20 63 6f 6e 74 65 6e 74 20 70 72 65   all content pre
0630: 76 69 6f 75 73 6c 79 20 61 64 64 65 64 2e 0a 2a  viously added..*
0640: 2a 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 20 50 6f 73 69 74 69 6f 6e 20 74 68 65 20     Position the 
0670: 72 65 61 64 20 63 75 72 73 6f 72 20 6f 6e 20 74  read cursor on t
0680: 68 65 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20  he.**           
0690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06a0: 20 20 20 20 20 20 20 66 69 72 73 74 20 73 6f 72         first sor
06b0: 74 65 64 20 65 6c 65 6d 65 6e 74 2e 0a 2a 2a 0a  ted element..**.
06c0: 2a 2a 20 20 20 20 73 71 6c 69 74 65 33 56 64 62  **    sqlite3Vdb
06d0: 65 53 6f 72 74 65 72 4e 65 78 74 28 29 20 20 20  eSorterNext()   
06e0: 20 20 20 20 41 64 76 61 6e 63 65 20 74 68 65 20      Advance the 
06f0: 72 65 61 64 20 63 75 72 73 6f 72 20 74 6f 20 74  read cursor to t
0700: 68 65 20 6e 65 78 74 20 73 6f 72 74 65 64 0a 2a  he next sorted.*
0710: 2a 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 20 65 6c 65 6d 65 6e 74 2e 0a 2a 2a 0a 2a     element..**.*
0740: 2a 20 20 20 20 73 71 6c 69 74 65 33 56 64 62 65  *    sqlite3Vdbe
0750: 53 6f 72 74 65 72 52 6f 77 6b 65 79 28 29 20 20  SorterRowkey()  
0760: 20 20 20 52 65 74 75 72 6e 20 74 68 65 20 63 6f     Return the co
0770: 6d 70 6c 65 74 65 20 62 69 6e 61 72 79 20 62 6c  mplete binary bl
0780: 6f 62 20 66 6f 72 20 74 68 65 0a 2a 2a 20 20 20  ob 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 20 72                 r
07b0: 6f 77 20 63 75 72 72 65 6e 74 6c 79 20 75 6e 64  ow currently und
07c0: 65 72 20 74 68 65 20 72 65 61 64 20 63 75 72 73  er the read curs
07d0: 6f 72 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71 6c  or..**.**    sql
07e0: 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 43 6f  ite3VdbeSorterCo
07f0: 6d 70 61 72 65 28 29 20 20 20 20 43 6f 6d 70 61  mpare()    Compa
0800: 72 65 20 74 68 65 20 62 69 6e 61 72 79 20 62 6c  re the binary bl
0810: 6f 62 20 66 6f 72 20 74 68 65 20 72 6f 77 0a 2a  ob for the row.*
0820: 2a 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 20 63 75 72 72 65 6e 74 6c 79 20 75 6e 64     currently und
0850: 65 72 20 74 68 65 20 72 65 61 64 20 63 75 72 73  er the read curs
0860: 6f 72 20 61 67 61 69 6e 73 74 0a 2a 2a 20 20 20  or 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 20 61                 a
0890: 6e 6f 74 68 65 72 20 62 69 6e 61 72 79 20 62 6c  nother binary bl
08a0: 6f 62 20 58 20 61 6e 64 20 72 65 70 6f 72 74 20  ob X and report 
08b0: 69 66 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20  if.**           
08c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08d0: 20 20 20 20 20 20 20 58 20 69 73 20 73 74 72 69         X is stri
08e0: 63 74 6c 79 20 6c 65 73 73 20 74 68 61 6e 20 74  ctly less than t
08f0: 68 65 20 72 65 61 64 20 63 75 72 73 6f 72 2e 0a  he read cursor..
0900: 2a 2a 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 20 55 73 65 64 20 74 6f 20 65 6e 66 6f      Used to enfo
0930: 72 63 65 20 75 6e 69 71 75 65 6e 65 73 73 20 69  rce uniqueness i
0940: 6e 20 61 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  n 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 20 43 52 45 41 54 45 20 55          CREATE U
0970: 4e 49 51 55 45 20 49 4e 44 45 58 20 73 74 61 74  NIQUE INDEX stat
0980: 65 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 20 20 20  ement..**.**    
0990: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
09a0: 72 43 6c 6f 73 65 28 29 20 20 20 20 20 20 43 6c  rClose()      Cl
09b0: 6f 73 65 20 74 68 65 20 56 64 62 65 53 6f 72 74  ose the VdbeSort
09c0: 65 72 20 6f 62 6a 65 63 74 20 61 6e 64 20 72 65  er object and re
09d0: 63 6c 61 69 6d 0a 2a 2a 20 20 20 20 20 20 20 20  claim.**        
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 20 61 6c 6c 20 72 65            all re
0a00: 73 6f 75 72 63 65 73 2e 0a 2a 2a 0a 2a 2a 20 20  sources..**.**  
0a10: 20 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72    sqlite3VdbeSor
0a20: 74 65 72 52 65 73 65 74 28 29 20 20 20 20 20 20  terReset()      
0a30: 52 65 66 75 72 62 69 73 68 20 74 68 65 20 56 64  Refurbish the Vd
0a40: 62 65 53 6f 72 74 65 72 20 66 6f 72 20 72 65 75  beSorter for reu
0a50: 73 65 2e 20 20 54 68 69 73 0a 2a 2a 20 20 20 20  se.  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 20 69 73                is
0a80: 20 6c 69 6b 65 20 43 6c 6f 73 65 28 29 20 66 6f   like Close() fo
0a90: 6c 6c 6f 77 65 64 20 62 79 20 49 6e 69 74 28 29  llowed by Init()
0aa0: 20 6f 6e 6c 79 0a 2a 2a 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 20 6d 75 63 68 20 66            much f
0ad0: 61 73 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  aster..**.** The
0ae0: 20 69 6e 74 65 72 66 61 63 65 73 20 61 62 6f 76   interfaces abov
0af0: 65 20 6d 75 73 74 20 62 65 20 63 61 6c 6c 65 64  e must be called
0b00: 20 69 6e 20 61 20 70 61 72 74 69 63 75 6c 61 72   in a particular
0b10: 20 6f 72 64 65 72 2e 20 20 57 72 69 74 65 28 29   order.  Write()
0b20: 20 63 61 6e 20 0a 2a 2a 20 6f 6e 6c 79 20 6f 63   can .** only oc
0b30: 63 75 72 20 69 6e 20 62 65 74 77 65 65 6e 20 49  cur in between I
0b40: 6e 69 74 28 29 2f 52 65 73 65 74 28 29 20 61 6e  nit()/Reset() an
0b50: 64 20 52 65 77 69 6e 64 28 29 2e 20 20 4e 65 78  d Rewind().  Nex
0b60: 74 28 29 2c 20 52 6f 77 6b 65 79 28 29 2c 20 61  t(), Rowkey(), a
0b70: 6e 64 0a 2a 2a 20 43 6f 6d 70 61 72 65 28 29 20  nd.** Compare() 
0b80: 63 61 6e 20 6f 6e 6c 79 20 6f 63 63 75 72 20 69  can only occur i
0b90: 6e 20 62 65 74 77 65 65 6e 20 52 65 77 69 6e 64  n between Rewind
0ba0: 28 29 20 61 6e 64 20 43 6c 6f 73 65 28 29 2f 52  () and Close()/R
0bb0: 65 73 65 74 28 29 2e 20 69 2e 65 2e 0a 2a 2a 0a  eset(). i.e..**.
0bc0: 2a 2a 20 20 20 49 6e 69 74 28 29 0a 2a 2a 20 20  **   Init().**  
0bd0: 20 66 6f 72 20 65 61 63 68 20 72 65 63 6f 72 64   for each record
0be0: 3a 20 57 72 69 74 65 28 29 0a 2a 2a 20 20 20 52  : Write().**   R
0bf0: 65 77 69 6e 64 28 29 0a 2a 2a 20 20 20 20 20 52  ewind().**     R
0c00: 6f 77 6b 65 79 28 29 2f 43 6f 6d 70 61 72 65 28  owkey()/Compare(
0c10: 29 0a 2a 2a 20 20 20 4e 65 78 74 28 29 20 0a 2a  ).**   Next() .*
0c20: 2a 20 20 20 43 6c 6f 73 65 28 29 0a 2a 2a 0a 2a  *   Close().**.*
0c30: 2a 20 41 6c 67 6f 72 69 74 68 6d 3a 0a 2a 2a 0a  * Algorithm:.**.
0c40: 2a 2a 20 52 65 63 6f 72 64 73 20 70 61 73 73 65  ** Records passe
0c50: 64 20 74 6f 20 74 68 65 20 73 6f 72 74 65 72 20  d to the sorter 
0c60: 76 69 61 20 63 61 6c 6c 73 20 74 6f 20 57 72 69  via calls to Wri
0c70: 74 65 28 29 20 61 72 65 20 69 6e 69 74 69 61 6c  te() are initial
0c80: 6c 79 20 68 65 6c 64 20 0a 2a 2a 20 75 6e 73 6f  ly held .** unso
0c90: 72 74 65 64 20 69 6e 20 6d 61 69 6e 20 6d 65 6d  rted in main mem
0ca0: 6f 72 79 2e 20 41 73 73 75 6d 69 6e 67 20 74 68  ory. Assuming th
0cb0: 65 20 61 6d 6f 75 6e 74 20 6f 66 20 6d 65 6d 6f  e amount of memo
0cc0: 72 79 20 75 73 65 64 20 6e 65 76 65 72 20 65 78  ry used never ex
0cd0: 63 65 65 64 73 0a 2a 2a 20 61 20 74 68 72 65 73  ceeds.** a thres
0ce0: 68 6f 6c 64 2c 20 77 68 65 6e 20 52 65 77 69 6e  hold, when Rewin
0cf0: 64 28 29 20 69 73 20 63 61 6c 6c 65 64 20 74 68  d() is called th
0d00: 65 20 73 65 74 20 6f 66 20 72 65 63 6f 72 64 73  e set of records
0d10: 20 69 73 20 73 6f 72 74 65 64 20 75 73 69 6e 67   is sorted using
0d20: 0a 2a 2a 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79  .** an in-memory
0d30: 20 6d 65 72 67 65 20 73 6f 72 74 2e 20 49 6e 20   merge sort. In 
0d40: 74 68 69 73 20 63 61 73 65 2c 20 6e 6f 20 74 65  this case, no te
0d50: 6d 70 6f 72 61 72 79 20 66 69 6c 65 73 20 61 72  mporary files ar
0d60: 65 20 72 65 71 75 69 72 65 64 0a 2a 2a 20 61 6e  e required.** an
0d70: 64 20 73 75 62 73 65 71 75 65 6e 74 20 63 61 6c  d subsequent cal
0d80: 6c 73 20 74 6f 20 52 6f 77 6b 65 79 28 29 2c 20  ls to Rowkey(), 
0d90: 4e 65 78 74 28 29 20 61 6e 64 20 43 6f 6d 70 61  Next() and Compa
0da0: 72 65 28 29 20 72 65 61 64 20 72 65 63 6f 72 64  re() read record
0db0: 73 20 0a 2a 2a 20 64 69 72 65 63 74 6c 79 20 66  s .** directly f
0dc0: 72 6f 6d 20 6d 61 69 6e 20 6d 65 6d 6f 72 79 2e  rom main memory.
0dd0: 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 61 6d  .**.** If the am
0de0: 6f 75 6e 74 20 6f 66 20 73 70 61 63 65 20 75 73  ount of space us
0df0: 65 64 20 74 6f 20 73 74 6f 72 65 20 72 65 63 6f  ed to store reco
0e00: 72 64 73 20 69 6e 20 6d 61 69 6e 20 6d 65 6d 6f  rds in main memo
0e10: 72 79 20 65 78 63 65 65 64 73 20 74 68 65 0a 2a  ry exceeds the.*
0e20: 2a 20 74 68 72 65 73 68 6f 6c 64 2c 20 74 68 65  * threshold, the
0e30: 6e 20 74 68 65 20 73 65 74 20 6f 66 20 72 65 63  n the set of rec
0e40: 6f 72 64 73 20 63 75 72 72 65 6e 74 6c 79 20 69  ords currently i
0e50: 6e 20 6d 65 6d 6f 72 79 20 61 72 65 20 73 6f 72  n memory are sor
0e60: 74 65 64 20 61 6e 64 0a 2a 2a 20 77 72 69 74 74  ted and.** writt
0e70: 65 6e 20 74 6f 20 61 20 74 65 6d 70 6f 72 61 72  en to a temporar
0e80: 79 20 66 69 6c 65 20 69 6e 20 22 50 61 63 6b 65  y file in "Packe
0e90: 64 20 4d 65 6d 6f 72 79 20 41 72 72 61 79 22 20  d Memory Array" 
0ea0: 28 50 4d 41 29 20 66 6f 72 6d 61 74 2e 0a 2a 2a  (PMA) format..**
0eb0: 20 41 20 50 4d 41 20 63 72 65 61 74 65 64 20 61   A PMA created a
0ec0: 74 20 74 68 69 73 20 70 6f 69 6e 74 20 69 73 20  t this point is 
0ed0: 6b 6e 6f 77 6e 20 61 73 20 61 20 22 6c 65 76 65  known as a "leve
0ee0: 6c 2d 30 20 50 4d 41 22 2e 20 48 69 67 68 65 72  l-0 PMA". Higher
0ef0: 20 6c 65 76 65 6c 73 0a 2a 2a 20 6f 66 20 50 4d   levels.** of PM
0f00: 41 73 20 6d 61 79 20 62 65 20 63 72 65 61 74 65  As may be create
0f10: 64 20 62 79 20 6d 65 72 67 69 6e 67 20 65 78 69  d by merging exi
0f20: 73 74 69 6e 67 20 50 4d 41 73 20 74 6f 67 65 74  sting PMAs toget
0f30: 68 65 72 20 2d 20 66 6f 72 20 65 78 61 6d 70 6c  her - for exampl
0f40: 65 0a 2a 2a 20 6d 65 72 67 69 6e 67 20 74 77 6f  e.** merging two
0f50: 20 6f 72 20 6d 6f 72 65 20 6c 65 76 65 6c 2d 30   or more level-0
0f60: 20 50 4d 41 73 20 74 6f 67 65 74 68 65 72 20 63   PMAs together c
0f70: 72 65 61 74 65 73 20 61 20 6c 65 76 65 6c 2d 31  reates a level-1
0f80: 20 50 4d 41 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20   PMA..**.** The 
0f90: 74 68 72 65 73 68 6f 6c 64 20 66 6f 72 20 74 68  threshold for th
0fa0: 65 20 61 6d 6f 75 6e 74 20 6f 66 20 6d 61 69 6e  e amount of main
0fb0: 20 6d 65 6d 6f 72 79 20 74 6f 20 75 73 65 20 62   memory to use b
0fc0: 65 66 6f 72 65 20 66 6c 75 73 68 69 6e 67 20 0a  efore flushing .
0fd0: 2a 2a 20 72 65 63 6f 72 64 73 20 74 6f 20 61 20  ** records to a 
0fe0: 50 4d 41 20 69 73 20 72 6f 75 67 68 6c 79 20 74  PMA is roughly t
0ff0: 68 65 20 73 61 6d 65 20 61 73 20 74 68 65 20 6c  he same as the l
1000: 69 6d 69 74 20 63 6f 6e 66 69 67 75 72 65 64 20  imit configured 
1010: 66 6f 72 20 74 68 65 0a 2a 2a 20 70 61 67 65 2d  for the.** page-
1020: 63 61 63 68 65 20 6f 66 20 74 68 65 20 6d 61 69  cache of the mai
1030: 6e 20 64 61 74 61 62 61 73 65 2e 20 53 70 65 63  n database. Spec
1040: 69 66 69 63 61 6c 6c 79 2c 20 74 68 65 20 74 68  ifically, the th
1050: 72 65 73 68 6f 6c 64 20 69 73 20 73 65 74 20 74  reshold is set t
1060: 6f 20 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 20  o .** the value 
1070: 72 65 74 75 72 6e 65 64 20 6d 75 6c 74 69 70 6c  returned multipl
1080: 69 65 64 20 62 79 20 22 50 52 41 47 4d 41 20 6d  ied by "PRAGMA m
1090: 61 69 6e 2e 70 61 67 65 5f 73 69 7a 65 22 20 6d  ain.page_size" m
10a0: 75 6c 74 69 70 6c 65 64 20 62 79 20 0a 2a 2a 20  ultipled by .** 
10b0: 74 68 61 74 20 72 65 74 75 72 6e 65 64 20 62 79  that returned by
10c0: 20 22 50 52 41 47 4d 41 20 6d 61 69 6e 2e 63 61   "PRAGMA main.ca
10d0: 63 68 65 5f 73 69 7a 65 22 2c 20 69 6e 20 62 79  che_size", in by
10e0: 74 65 73 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  tes..**.** If th
10f0: 65 20 73 6f 72 74 65 72 20 69 73 20 72 75 6e 6e  e sorter is runn
1100: 69 6e 67 20 69 6e 20 73 69 6e 67 6c 65 2d 74 68  ing in single-th
1110: 72 65 61 64 65 64 20 6d 6f 64 65 2c 20 74 68 65  readed mode, the
1120: 6e 20 61 6c 6c 20 50 4d 41 73 20 67 65 6e 65 72  n all PMAs gener
1130: 61 74 65 64 0a 2a 2a 20 61 72 65 20 61 70 70 65  ated.** are appe
1140: 6e 64 65 64 20 74 6f 20 61 20 73 69 6e 67 6c 65  nded to a single
1150: 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 2e   temporary file.
1160: 20 4f 72 2c 20 69 66 20 74 68 65 20 73 6f 72 74   Or, if the sort
1170: 65 72 20 69 73 20 72 75 6e 6e 69 6e 67 20 69 6e  er is running in
1180: 0a 2a 2a 20 6d 75 6c 74 69 2d 74 68 72 65 61 64  .** multi-thread
1190: 65 64 20 6d 6f 64 65 20 74 68 65 6e 20 75 70 20  ed mode then up 
11a0: 74 6f 20 28 4e 2b 31 29 20 74 65 6d 70 6f 72 61  to (N+1) tempora
11b0: 72 79 20 66 69 6c 65 73 20 6d 61 79 20 62 65 20  ry files may be 
11c0: 6f 70 65 6e 65 64 2c 20 77 68 65 72 65 0a 2a 2a  opened, where.**
11d0: 20 4e 20 69 73 20 74 68 65 20 63 6f 6e 66 69 67   N is the config
11e0: 75 72 65 64 20 6e 75 6d 62 65 72 20 6f 66 20 77  ured number of w
11f0: 6f 72 6b 65 72 20 74 68 72 65 61 64 73 2e 20 49  orker threads. I
1200: 6e 20 74 68 69 73 20 63 61 73 65 2c 20 69 6e 73  n this case, ins
1210: 74 65 61 64 20 6f 66 0a 2a 2a 20 73 6f 72 74 69  tead of.** sorti
1220: 6e 67 20 74 68 65 20 72 65 63 6f 72 64 73 20 61  ng the records a
1230: 6e 64 20 77 72 69 74 69 6e 67 20 74 68 65 20 50  nd writing the P
1240: 4d 41 20 74 6f 20 61 20 74 65 6d 70 6f 72 61 72  MA to a temporar
1250: 79 20 66 69 6c 65 20 69 74 73 65 6c 66 2c 20 74  y file itself, t
1260: 68 65 0a 2a 2a 20 63 61 6c 6c 69 6e 67 20 74 68  he.** calling th
1270: 72 65 61 64 20 75 73 75 61 6c 6c 79 20 6c 61 75  read usually lau
1280: 6e 63 68 65 73 20 61 20 77 6f 72 6b 65 72 20 74  nches a worker t
1290: 68 72 65 61 64 20 74 6f 20 64 6f 20 73 6f 2e 20  hread to do so. 
12a0: 45 78 63 65 70 74 2c 20 69 66 0a 2a 2a 20 74 68  Except, if.** th
12b0: 65 72 65 20 61 72 65 20 61 6c 72 65 61 64 79 20  ere are already 
12c0: 4e 20 77 6f 72 6b 65 72 20 74 68 72 65 61 64 73  N worker threads
12d0: 20 72 75 6e 6e 69 6e 67 2c 20 74 68 65 20 6d 61   running, the ma
12e0: 69 6e 20 74 68 72 65 61 64 20 64 6f 65 73 20 74  in thread does t
12f0: 68 65 20 77 6f 72 6b 0a 2a 2a 20 69 74 73 65 6c  he work.** itsel
1300: 66 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 6f 72  f..**.** The sor
1310: 74 65 72 20 69 73 20 72 75 6e 6e 69 6e 67 20 69  ter is running i
1320: 6e 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64  n multi-threaded
1330: 20 6d 6f 64 65 20 69 66 20 28 61 29 20 74 68 65   mode if (a) the
1340: 20 6c 69 62 72 61 72 79 20 77 61 73 20 62 75 69   library was bui
1350: 6c 74 0a 2a 2a 20 77 69 74 68 20 70 72 65 2d 70  lt.** with pre-p
1360: 72 6f 63 65 73 73 6f 72 20 73 79 6d 62 6f 6c 20  rocessor symbol 
1370: 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45  SQLITE_MAX_WORKE
1380: 52 5f 54 48 52 45 41 44 53 20 73 65 74 20 74 6f  R_THREADS set to
1390: 20 61 20 76 61 6c 75 65 20 67 72 65 61 74 65 72   a value greater
13a0: 0a 2a 2a 20 74 68 61 6e 20 7a 65 72 6f 2c 20 61  .** than zero, a
13b0: 6e 64 20 28 62 29 20 77 6f 72 6b 65 72 20 74 68  nd (b) worker th
13c0: 72 65 61 64 73 20 68 61 76 65 20 62 65 65 6e 20  reads have been 
13d0: 65 6e 61 62 6c 65 64 20 61 74 20 72 75 6e 74 69  enabled at runti
13e0: 6d 65 20 62 79 20 63 61 6c 6c 69 6e 67 0a 2a 2a  me by calling.**
13f0: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28   sqlite3_config(
1400: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 57 4f  SQLITE_CONFIG_WO
1410: 52 4b 45 52 5f 54 48 52 45 41 44 53 2c 20 2e 2e  RKER_THREADS, ..
1420: 2e 29 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 52  .)..**.** When R
1430: 65 77 69 6e 64 28 29 20 69 73 20 63 61 6c 6c 65  ewind() is calle
1440: 64 2c 20 61 6e 79 20 64 61 74 61 20 72 65 6d 61  d, any data rema
1450: 69 6e 69 6e 67 20 69 6e 20 6d 65 6d 6f 72 79 20  ining in memory 
1460: 69 73 20 66 6c 75 73 68 65 64 20 74 6f 20 61 20  is flushed to a 
1470: 0a 2a 2a 20 66 69 6e 61 6c 20 50 4d 41 2e 20 53  .** final PMA. S
1480: 6f 20 61 74 20 74 68 69 73 20 70 6f 69 6e 74 20  o at this point 
1490: 74 68 65 20 64 61 74 61 20 69 73 20 73 74 6f 72  the data is stor
14a0: 65 64 20 69 6e 20 73 6f 6d 65 20 6e 75 6d 62 65  ed in some numbe
14b0: 72 20 6f 66 20 73 6f 72 74 65 64 0a 2a 2a 20 50  r of sorted.** P
14c0: 4d 41 73 20 77 69 74 68 69 6e 20 74 65 6d 70 6f  MAs within tempo
14d0: 72 61 72 79 20 66 69 6c 65 73 20 6f 6e 20 64 69  rary files on di
14e0: 73 6b 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  sk..**.** If the
14f0: 72 65 20 61 72 65 20 66 65 77 65 72 20 74 68 61  re are fewer tha
1500: 6e 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52  n SORTER_MAX_MER
1510: 47 45 5f 43 4f 55 4e 54 20 50 4d 41 73 20 69 6e  GE_COUNT PMAs in
1520: 20 74 6f 74 61 6c 20 61 6e 64 20 74 68 65 0a 2a   total and the.*
1530: 2a 20 73 6f 72 74 65 72 20 69 73 20 72 75 6e 6e  * sorter is runn
1540: 69 6e 67 20 69 6e 20 73 69 6e 67 6c 65 2d 74 68  ing in single-th
1550: 72 65 61 64 65 64 20 6d 6f 64 65 2c 20 74 68 65  readed mode, the
1560: 6e 20 74 68 65 73 65 20 50 4d 41 73 20 61 72 65  n these PMAs are
1570: 20 6d 65 72 67 65 64 0a 2a 2a 20 69 6e 63 72 65   merged.** incre
1580: 6d 65 6e 74 61 6c 6c 79 20 61 73 20 6b 65 79 73  mentally as keys
1590: 20 61 72 65 20 72 65 74 72 65 69 76 65 64 20 66   are retreived f
15a0: 72 6f 6d 20 74 68 65 20 73 6f 72 74 65 72 20 62  rom the sorter b
15b0: 79 20 74 68 65 20 56 44 42 45 2e 20 20 54 68 65  y the VDBE.  The
15c0: 0a 2a 2a 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  .** MergeEngine 
15d0: 6f 62 6a 65 63 74 2c 20 64 65 73 63 72 69 62 65  object, describe
15e0: 64 20 69 6e 20 66 75 72 74 68 65 72 20 64 65 74  d in further det
15f0: 61 69 6c 20 62 65 6c 6f 77 2c 20 70 65 72 66 6f  ail below, perfo
1600: 72 6d 73 20 74 68 69 73 0a 2a 2a 20 6d 65 72 67  rms this.** merg
1610: 65 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 69 66 20  e..**.** Or, if 
1620: 72 75 6e 6e 69 6e 67 20 69 6e 20 6d 75 6c 74 69  running in multi
1630: 2d 74 68 72 65 61 64 65 64 20 6d 6f 64 65 2c 20  -threaded mode, 
1640: 74 68 65 6e 20 61 20 62 61 63 6b 67 72 6f 75 6e  then a backgroun
1650: 64 20 74 68 72 65 61 64 20 69 73 0a 2a 2a 20 6c  d thread is.** l
1660: 61 75 6e 63 68 65 64 20 74 6f 20 6d 65 72 67 65  aunched to merge
1670: 20 74 68 65 20 65 78 69 73 74 69 6e 67 20 50 4d   the existing PM
1680: 41 73 2e 20 4f 6e 63 65 20 74 68 65 20 62 61 63  As. Once the bac
1690: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 68  kground thread h
16a0: 61 73 0a 2a 2a 20 6d 65 72 67 65 64 20 54 20 62  as.** merged T b
16b0: 79 74 65 73 20 6f 66 20 64 61 74 61 20 69 6e 74  ytes of data int
16c0: 6f 20 61 20 73 69 6e 67 6c 65 20 73 6f 72 74 65  o a single sorte
16d0: 64 20 50 4d 41 2c 20 74 68 65 20 6d 61 69 6e 20  d PMA, the main 
16e0: 74 68 72 65 61 64 20 0a 2a 2a 20 62 65 67 69 6e  thread .** begin
16f0: 73 20 72 65 61 64 69 6e 67 20 6b 65 79 73 20 66  s reading keys f
1700: 72 6f 6d 20 74 68 61 74 20 50 4d 41 20 77 68 69  rom that PMA whi
1710: 6c 65 20 74 68 65 20 62 61 63 6b 67 72 6f 75 6e  le the backgroun
1720: 64 20 74 68 72 65 61 64 20 70 72 6f 63 65 65 64  d thread proceed
1730: 73 0a 2a 2a 20 77 69 74 68 20 6d 65 72 67 69 6e  s.** with mergin
1740: 67 20 74 68 65 20 6e 65 78 74 20 54 20 62 79 74  g the next T byt
1750: 65 73 20 6f 66 20 64 61 74 61 2e 20 41 6e 64 20  es of data. And 
1760: 73 6f 20 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 50 61 72  so on..**.** Par
1770: 61 6d 65 74 65 72 20 54 20 69 73 20 73 65 74 20  ameter T is set 
1780: 74 6f 20 68 61 6c 66 20 74 68 65 20 76 61 6c 75  to half the valu
1790: 65 20 6f 66 20 74 68 65 20 6d 65 6d 6f 72 79 20  e of the memory 
17a0: 74 68 72 65 73 68 6f 6c 64 20 75 73 65 64 20 0a  threshold used .
17b0: 2a 2a 20 62 79 20 57 72 69 74 65 28 29 20 61 62  ** by Write() ab
17c0: 6f 76 65 20 74 6f 20 64 65 74 65 72 6d 69 6e 65  ove to determine
17d0: 20 77 68 65 6e 20 74 6f 20 63 72 65 61 74 65 20   when to create 
17e0: 61 20 6e 65 77 20 50 4d 41 2e 0a 2a 2a 0a 2a 2a  a new PMA..**.**
17f0: 20 49 66 20 74 68 65 72 65 20 61 72 65 20 6d 6f   If there are mo
1800: 72 65 20 74 68 61 6e 20 53 4f 52 54 45 52 5f 4d  re than SORTER_M
1810: 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20 50  AX_MERGE_COUNT P
1820: 4d 41 73 20 69 6e 20 74 6f 74 61 6c 20 77 68 65  MAs in total whe
1830: 6e 20 0a 2a 2a 20 52 65 77 69 6e 64 28 29 20 69  n .** Rewind() i
1840: 73 20 63 61 6c 6c 65 64 2c 20 74 68 65 6e 20 61  s called, then a
1850: 20 68 69 65 72 61 72 63 68 79 20 6f 66 20 69 6e   hierarchy of in
1860: 63 72 65 6d 65 6e 74 61 6c 2d 6d 65 72 67 65 73  cremental-merges
1870: 20 69 73 20 75 73 65 64 2e 20 0a 2a 2a 20 46 69   is used. .** Fi
1880: 72 73 74 2c 20 54 20 62 79 74 65 73 20 6f 66 20  rst, T bytes of 
1890: 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 66 69  data from the fi
18a0: 72 73 74 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  rst SORTER_MAX_M
18b0: 45 52 47 45 5f 43 4f 55 4e 54 20 50 4d 41 73 20  ERGE_COUNT PMAs 
18c0: 6f 6e 20 0a 2a 2a 20 64 69 73 6b 20 61 72 65 20  on .** disk are 
18d0: 6d 65 72 67 65 64 20 74 6f 67 65 74 68 65 72 2e  merged together.
18e0: 20 54 68 65 6e 20 54 20 62 79 74 65 73 20 6f 66   Then T bytes of
18f0: 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 73   data from the s
1900: 65 63 6f 6e 64 20 73 65 74 2c 20 61 6e 64 0a 2a  econd set, and.*
1910: 2a 20 73 6f 20 6f 6e 2c 20 73 75 63 68 20 74 68  * so on, such th
1920: 61 74 20 6e 6f 20 6f 70 65 72 61 74 69 6f 6e 20  at no operation 
1930: 65 76 65 72 20 6d 65 72 67 65 73 20 6d 6f 72 65  ever merges more
1940: 20 74 68 61 6e 20 53 4f 52 54 45 52 5f 4d 41 58   than SORTER_MAX
1950: 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 0a 2a 2a 20  _MERGE_COUNT.** 
1960: 50 4d 41 73 20 61 74 20 61 20 74 69 6d 65 2e 20  PMAs at a time. 
1970: 54 68 69 73 20 64 6f 6e 65 20 69 73 20 74 6f 20  This done is to 
1980: 69 6d 70 72 6f 76 65 20 6c 6f 63 61 6c 69 74 79  improve locality
1990: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 72 75 6e 6e 69  ..**.** If runni
19a0: 6e 67 20 69 6e 20 6d 75 6c 74 69 2d 74 68 72 65  ng in multi-thre
19b0: 61 64 65 64 20 6d 6f 64 65 20 61 6e 64 20 74 68  aded mode and th
19c0: 65 72 65 20 61 72 65 20 6d 6f 72 65 20 74 68 61  ere are more tha
19d0: 6e 0a 2a 2a 20 53 4f 52 54 45 52 5f 4d 41 58 5f  n.** SORTER_MAX_
19e0: 4d 45 52 47 45 5f 43 4f 55 4e 54 20 50 4d 41 73  MERGE_COUNT PMAs
19f0: 20 6f 6e 20 64 69 73 6b 20 77 68 65 6e 20 52 65   on disk when Re
1a00: 77 69 6e 64 28 29 20 69 73 20 63 61 6c 6c 65 64  wind() is called
1a10: 2c 20 74 68 65 6e 20 6d 6f 72 65 0a 2a 2a 20 74  , then more.** t
1a20: 68 61 6e 20 6f 6e 65 20 62 61 63 6b 67 72 6f 75  han one backgrou
1a30: 6e 64 20 74 68 72 65 61 64 20 6d 61 79 20 62 65  nd thread may be
1a40: 20 63 72 65 61 74 65 64 2e 20 53 70 65 63 69 66   created. Specif
1a50: 69 63 61 6c 6c 79 2c 20 74 68 65 72 65 20 6d 61  ically, there ma
1a60: 79 20 62 65 0a 2a 2a 20 6f 6e 65 20 62 61 63 6b  y be.** one back
1a70: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 66 6f  ground thread fo
1a80: 72 20 65 61 63 68 20 74 65 6d 70 6f 72 61 72 79  r each temporary
1a90: 20 66 69 6c 65 20 6f 6e 20 64 69 73 6b 2c 20 61   file on disk, a
1aa0: 6e 64 20 6f 6e 65 20 62 61 63 6b 67 72 6f 75 6e  nd one backgroun
1ab0: 64 0a 2a 2a 20 74 68 72 65 61 64 20 74 6f 20 6d  d.** thread to m
1ac0: 65 72 67 65 20 74 68 65 20 6f 75 74 70 75 74 20  erge the output 
1ad0: 6f 66 20 65 61 63 68 20 6f 66 20 74 68 65 20 6f  of each of the o
1ae0: 74 68 65 72 73 20 74 6f 20 61 20 73 69 6e 67 6c  thers to a singl
1af0: 65 20 50 4d 41 20 66 6f 72 0a 2a 2a 20 74 68 65  e PMA for.** the
1b00: 20 6d 61 69 6e 20 74 68 72 65 61 64 20 74 6f 20   main thread to 
1b10: 72 65 61 64 20 66 72 6f 6d 2e 0a 2a 2f 0a 23 69  read from..*/.#i
1b20: 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65 49 6e  nclude "sqliteIn
1b30: 74 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 76  t.h".#include "v
1b40: 64 62 65 49 6e 74 2e 68 22 0a 0a 2f 2a 20 0a 2a  dbeInt.h"../* .*
1b50: 2a 20 49 66 20 53 51 4c 49 54 45 5f 44 45 42 55  * If SQLITE_DEBU
1b60: 47 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44 53  G_SORTER_THREADS
1b70: 20 69 73 20 64 65 66 69 6e 65 64 2c 20 74 68 69   is defined, thi
1b80: 73 20 6d 6f 64 75 6c 65 20 6f 75 74 70 75 74 73  s module outputs
1b90: 20 76 61 72 69 6f 75 73 0a 2a 2a 20 6d 65 73 73   various.** mess
1ba0: 61 67 65 73 20 74 6f 20 73 74 64 65 72 72 20 74  ages to stderr t
1bb0: 68 61 74 20 6d 61 79 20 62 65 20 68 65 6c 70 66  hat may be helpf
1bc0: 75 6c 20 69 6e 20 75 6e 64 65 72 73 74 61 6e 64  ul in understand
1bd0: 69 6e 67 20 74 68 65 20 70 65 72 66 6f 72 6d 61  ing the performa
1be0: 6e 63 65 0a 2a 2a 20 63 68 61 72 61 63 74 65 72  nce.** character
1bf0: 69 73 74 69 63 73 20 6f 66 20 74 68 65 20 73 6f  istics of the so
1c00: 72 74 65 72 20 69 6e 20 6d 75 6c 74 69 2d 74 68  rter in multi-th
1c10: 72 65 61 64 65 64 20 6d 6f 64 65 2e 0a 2a 2f 0a  readed mode..*/.
1c20: 23 69 66 20 30 0a 23 20 64 65 66 69 6e 65 20 53  #if 0.# define S
1c30: 51 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f 52 54  QLITE_DEBUG_SORT
1c40: 45 52 5f 54 48 52 45 41 44 53 20 31 0a 23 65 6e  ER_THREADS 1.#en
1c50: 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 76 61  dif../*.** Priva
1c60: 74 65 20 6f 62 6a 65 63 74 73 20 75 73 65 64 20  te objects used 
1c70: 62 79 20 74 68 65 20 73 6f 72 74 65 72 0a 2a 2f  by the sorter.*/
1c80: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
1c90: 4d 65 72 67 65 45 6e 67 69 6e 65 20 4d 65 72 67  MergeEngine Merg
1ca0: 65 45 6e 67 69 6e 65 3b 20 20 20 20 20 2f 2a 20  eEngine;     /* 
1cb0: 4d 65 72 67 65 20 50 4d 41 73 20 74 6f 67 65 74  Merge PMAs toget
1cc0: 68 65 72 20 2a 2f 0a 74 79 70 65 64 65 66 20 73  her */.typedef s
1cd0: 74 72 75 63 74 20 50 6d 61 52 65 61 64 65 72 20  truct PmaReader 
1ce0: 50 6d 61 52 65 61 64 65 72 3b 20 20 20 20 20 20  PmaReader;      
1cf0: 20 20 20 2f 2a 20 49 6e 63 72 65 6d 65 6e 74 61     /* Incrementa
1d00: 6c 6c 79 20 72 65 61 64 20 6f 6e 65 20 50 4d 41  lly read one PMA
1d10: 20 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75   */.typedef stru
1d20: 63 74 20 50 6d 61 57 72 69 74 65 72 20 50 6d 61  ct PmaWriter Pma
1d30: 57 72 69 74 65 72 3b 20 20 20 20 20 20 20 20 20  Writer;         
1d40: 2f 2a 20 49 6e 63 72 65 6d 65 6e 74 61 6c 6c 79  /* Incrementally
1d50: 20 77 72 69 74 65 20 6f 6e 65 20 50 4d 41 20 2a   write one PMA *
1d60: 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  /.typedef struct
1d70: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 53 6f   SorterRecord So
1d80: 72 74 65 72 52 65 63 6f 72 64 3b 20 20 20 2f 2a  rterRecord;   /*
1d90: 20 41 20 72 65 63 6f 72 64 20 62 65 69 6e 67 20   A record being 
1da0: 73 6f 72 74 65 64 20 2a 2f 0a 74 79 70 65 64 65  sorted */.typede
1db0: 66 20 73 74 72 75 63 74 20 53 6f 72 74 53 75 62  f struct SortSub
1dc0: 74 61 73 6b 20 53 6f 72 74 53 75 62 74 61 73 6b  task SortSubtask
1dd0: 3b 20 20 20 20 20 2f 2a 20 41 20 73 75 62 2d 74  ;     /* A sub-t
1de0: 61 73 6b 20 69 6e 20 74 68 65 20 73 6f 72 74 20  ask in the sort 
1df0: 70 72 6f 63 65 73 73 20 2a 2f 0a 74 79 70 65 64  process */.typed
1e00: 65 66 20 73 74 72 75 63 74 20 53 6f 72 74 65 72  ef struct Sorter
1e10: 46 69 6c 65 20 53 6f 72 74 65 72 46 69 6c 65 3b  File SorterFile;
1e20: 20 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72         /* Tempor
1e30: 61 72 79 20 66 69 6c 65 20 6f 62 6a 65 63 74 20  ary file object 
1e40: 77 72 61 70 70 65 72 20 2a 2f 0a 74 79 70 65 64  wrapper */.typed
1e50: 65 66 20 73 74 72 75 63 74 20 53 6f 72 74 65 72  ef struct Sorter
1e60: 4c 69 73 74 20 53 6f 72 74 65 72 4c 69 73 74 3b  List SorterList;
1e70: 20 20 20 20 20 20 20 2f 2a 20 49 6e 2d 6d 65 6d         /* In-mem
1e80: 6f 72 79 20 6c 69 73 74 20 6f 66 20 72 65 63 6f  ory list of reco
1e90: 72 64 73 20 2a 2f 0a 74 79 70 65 64 65 66 20 73  rds */.typedef s
1ea0: 74 72 75 63 74 20 49 6e 63 72 4d 65 72 67 65 72  truct IncrMerger
1eb0: 20 49 6e 63 72 4d 65 72 67 65 72 3b 20 20 20 20   IncrMerger;    
1ec0: 20 20 20 2f 2a 20 52 65 61 64 20 26 20 6d 65 72     /* Read & mer
1ed0: 67 65 20 6d 75 6c 74 69 70 6c 65 20 50 4d 41 73  ge multiple PMAs
1ee0: 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 41 20 63 6f 6e   */../*.** A con
1ef0: 74 61 69 6e 65 72 20 66 6f 72 20 61 20 74 65 6d  tainer for a tem
1f00: 70 20 66 69 6c 65 20 68 61 6e 64 6c 65 20 61 6e  p file handle an
1f10: 64 20 74 68 65 20 63 75 72 72 65 6e 74 20 61 6d  d the current am
1f20: 6f 75 6e 74 20 6f 66 20 64 61 74 61 20 0a 2a 2a  ount of data .**
1f30: 20 73 74 6f 72 65 64 20 69 6e 20 74 68 65 20 66   stored in the f
1f40: 69 6c 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 53  ile..*/.struct S
1f50: 6f 72 74 65 72 46 69 6c 65 20 7b 0a 20 20 73 71  orterFile {.  sq
1f60: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 64 3b  lite3_file *pFd;
1f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1f80: 20 46 69 6c 65 20 68 61 6e 64 6c 65 20 2a 2f 0a   File handle */.
1f90: 20 20 69 36 34 20 69 45 6f 66 3b 20 20 20 20 20    i64 iEof;     
1fa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fb0: 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 64 61    /* Bytes of da
1fc0: 74 61 20 73 74 6f 72 65 64 20 69 6e 20 70 46 64  ta stored in pFd
1fd0: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e   */.};../*.** An
1fe0: 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20   in-memory list 
1ff0: 6f 66 20 6f 62 6a 65 63 74 73 20 74 6f 20 62 65  of objects to be
2000: 20 73 6f 72 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 49   sorted..**.** I
2010: 66 20 61 4d 65 6d 6f 72 79 3d 3d 30 20 74 68 65  f aMemory==0 the
2020: 6e 20 65 61 63 68 20 6f 62 6a 65 63 74 20 69 73  n each object is
2030: 20 61 6c 6c 6f 63 61 74 65 64 20 73 65 70 61 72   allocated separ
2040: 61 74 65 6c 79 20 61 6e 64 20 74 68 65 20 6f 62  ately and the ob
2050: 6a 65 63 74 73 0a 2a 2a 20 61 72 65 20 63 6f 6e  jects.** are con
2060: 6e 65 63 74 65 64 20 75 73 69 6e 67 20 53 6f 72  nected using Sor
2070: 74 65 72 52 65 63 6f 72 64 2e 75 2e 70 4e 65 78  terRecord.u.pNex
2080: 74 2e 20 20 49 66 20 61 4d 65 6d 6f 72 79 21 3d  t.  If aMemory!=
2090: 30 20 74 68 65 6e 20 61 6c 6c 20 6f 62 6a 65 63  0 then all objec
20a0: 74 73 0a 2a 2a 20 61 72 65 20 73 74 6f 72 65 64  ts.** are stored
20b0: 20 69 6e 20 74 68 65 20 61 4d 65 6d 6f 72 79 5b   in the aMemory[
20c0: 5d 20 62 75 6c 6b 20 6d 65 6d 6f 72 79 2c 20 6f  ] bulk memory, o
20d0: 6e 65 20 72 69 67 68 74 20 61 66 74 65 72 20 74  ne right after t
20e0: 68 65 20 6f 74 68 65 72 2c 20 61 6e 64 0a 2a 2a  he other, and.**
20f0: 20 61 72 65 20 63 6f 6e 6e 65 63 74 65 64 20 75   are connected u
2100: 73 69 6e 67 20 53 6f 72 74 65 72 52 65 63 6f 72  sing SorterRecor
2110: 64 2e 75 2e 69 4e 65 78 74 2e 0a 2a 2f 0a 73 74  d.u.iNext..*/.st
2120: 72 75 63 74 20 53 6f 72 74 65 72 4c 69 73 74 20  ruct SorterList 
2130: 7b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  {.  SorterRecord
2140: 20 2a 70 4c 69 73 74 3b 20 20 20 20 20 20 20 20   *pList;        
2150: 20 20 20 20 2f 2a 20 4c 69 6e 6b 65 64 20 6c 69      /* Linked li
2160: 73 74 20 6f 66 20 72 65 63 6f 72 64 73 20 2a 2f  st of records */
2170: 0a 20 20 75 38 20 2a 61 4d 65 6d 6f 72 79 3b 20  .  u8 *aMemory; 
2180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2190: 20 20 20 2f 2a 20 49 66 20 6e 6f 6e 2d 4e 55 4c     /* If non-NUL
21a0: 4c 2c 20 62 75 6c 6b 20 6d 65 6d 6f 72 79 20 74  L, bulk memory t
21b0: 6f 20 68 6f 6c 64 20 70 4c 69 73 74 20 2a 2f 0a  o hold pList */.
21c0: 20 20 69 6e 74 20 73 7a 50 4d 41 3b 20 20 20 20    int szPMA;    
21d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21e0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 70 4c 69    /* Size of pLi
21f0: 73 74 20 61 73 20 50 4d 41 20 69 6e 20 62 79 74  st as PMA in byt
2200: 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  es */.};../*.** 
2210: 54 68 65 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  The MergeEngine 
2220: 6f 62 6a 65 63 74 20 69 73 20 75 73 65 64 20 74  object is used t
2230: 6f 20 63 6f 6d 62 69 6e 65 20 74 77 6f 20 6f 72  o combine two or
2240: 20 6d 6f 72 65 20 73 6d 61 6c 6c 65 72 20 50 4d   more smaller PM
2250: 41 73 20 69 6e 74 6f 0a 2a 2a 20 6f 6e 65 20 62  As into.** one b
2260: 69 67 20 50 4d 41 20 75 73 69 6e 67 20 61 20 6d  ig PMA using a m
2270: 65 72 67 65 20 6f 70 65 72 61 74 69 6f 6e 2e 20  erge operation. 
2280: 20 53 65 70 61 72 61 74 65 20 50 4d 41 73 20 61   Separate PMAs a
2290: 6c 6c 20 6e 65 65 64 20 74 6f 20 62 65 0a 2a 2a  ll need to be.**
22a0: 20 63 6f 6d 62 69 6e 65 64 20 69 6e 74 6f 20 6f   combined into o
22b0: 6e 65 20 62 69 67 20 50 4d 41 20 69 6e 20 6f 72  ne big PMA in or
22c0: 64 65 72 20 74 6f 20 62 65 20 61 62 6c 65 20 74  der to be able t
22d0: 6f 20 73 74 65 70 20 74 68 72 6f 75 67 68 20 74  o step through t
22e0: 68 65 20 73 6f 72 74 65 64 0a 2a 2a 20 72 65 63  he sorted.** rec
22f0: 6f 72 64 73 20 69 6e 20 6f 72 64 65 72 2e 0a 2a  ords in order..*
2300: 2a 0a 2a 2a 20 54 68 65 20 61 52 65 61 64 72 5b  *.** The aReadr[
2310: 5d 20 61 72 72 61 79 20 63 6f 6e 74 61 69 6e 73  ] array contains
2320: 20 61 20 50 6d 61 52 65 61 64 65 72 20 6f 62 6a   a PmaReader obj
2330: 65 63 74 20 66 6f 72 20 65 61 63 68 20 6f 66 20  ect for each of 
2340: 74 68 65 20 50 4d 41 73 20 62 65 69 6e 67 0a 2a  the PMAs being.*
2350: 2a 20 6d 65 72 67 65 64 2e 20 20 41 6e 20 61 52  * merged.  An aR
2360: 65 61 64 72 5b 5d 20 6f 62 6a 65 63 74 20 65 69  eadr[] object ei
2370: 74 68 65 72 20 70 6f 69 6e 74 73 20 74 6f 20 61  ther points to a
2380: 20 76 61 6c 69 64 20 6b 65 79 20 6f 72 20 65 6c   valid key or el
2390: 73 65 20 69 73 20 61 74 20 45 4f 46 2e 0a 2a 2a  se is at EOF..**
23a0: 20 46 6f 72 20 74 68 65 20 70 75 72 70 6f 73 65   For the purpose
23b0: 73 20 6f 66 20 74 68 65 20 70 61 72 61 67 72 61  s of the paragra
23c0: 70 68 73 20 62 65 6c 6f 77 2c 20 77 65 20 61 73  phs below, we as
23d0: 73 75 6d 65 20 74 68 61 74 20 74 68 65 20 61 72  sume that the ar
23e0: 72 61 79 20 69 73 0a 2a 2a 20 61 63 74 75 61 6c  ray is.** actual
23f0: 6c 79 20 4e 20 65 6c 65 6d 65 6e 74 73 20 69 6e  ly N elements in
2400: 20 73 69 7a 65 2c 20 77 68 65 72 65 20 4e 20 69   size, where N i
2410: 73 20 74 68 65 20 73 6d 61 6c 6c 65 73 74 20 70  s the smallest p
2420: 6f 77 65 72 20 6f 66 20 32 20 67 72 65 61 74 65  ower of 2 greate
2430: 72 0a 2a 2a 20 74 6f 20 6f 72 20 65 71 75 61 6c  r.** to or equal
2440: 20 74 6f 20 74 68 65 20 6e 75 6d 62 65 72 20 6f   to the number o
2450: 66 20 50 4d 41 73 20 62 65 69 6e 67 20 6d 65 72  f PMAs being mer
2460: 67 65 64 2e 20 54 68 65 20 65 78 74 72 61 20 61  ged. The extra a
2470: 52 65 61 64 72 5b 5d 20 65 6c 65 6d 65 6e 74 73  Readr[] elements
2480: 0a 2a 2a 20 61 72 65 20 74 72 65 61 74 65 64 20  .** are treated 
2490: 61 73 20 69 66 20 74 68 65 79 20 61 72 65 20 65  as if they are e
24a0: 6d 70 74 79 20 28 61 6c 77 61 79 73 20 61 74 20  mpty (always at 
24b0: 45 4f 46 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  EOF)..**.** The 
24c0: 61 54 72 65 65 5b 5d 20 61 72 72 61 79 20 69 73  aTree[] array is
24d0: 20 61 6c 73 6f 20 4e 20 65 6c 65 6d 65 6e 74 73   also N elements
24e0: 20 69 6e 20 73 69 7a 65 2e 20 54 68 65 20 76 61   in size. The va
24f0: 6c 75 65 20 6f 66 20 4e 20 69 73 20 73 74 6f 72  lue of N is stor
2500: 65 64 20 69 6e 0a 2a 2a 20 74 68 65 20 4d 65 72  ed in.** the Mer
2510: 67 65 45 6e 67 69 6e 65 2e 6e 54 72 65 65 20 76  geEngine.nTree v
2520: 61 72 69 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54  ariable..**.** T
2530: 68 65 20 66 69 6e 61 6c 20 28 4e 2f 32 29 20 65  he final (N/2) e
2540: 6c 65 6d 65 6e 74 73 20 6f 66 20 61 54 72 65 65  lements of aTree
2550: 5b 5d 20 63 6f 6e 74 61 69 6e 20 74 68 65 20 72  [] contain the r
2560: 65 73 75 6c 74 73 20 6f 66 20 63 6f 6d 70 61 72  esults of compar
2570: 69 6e 67 0a 2a 2a 20 70 61 69 72 73 20 6f 66 20  ing.** pairs of 
2580: 50 4d 41 20 6b 65 79 73 20 74 6f 67 65 74 68 65  PMA keys togethe
2590: 72 2e 20 45 6c 65 6d 65 6e 74 20 69 20 63 6f 6e  r. Element i con
25a0: 74 61 69 6e 73 20 74 68 65 20 72 65 73 75 6c 74  tains the result
25b0: 20 6f 66 20 0a 2a 2a 20 63 6f 6d 70 61 72 69 6e   of .** comparin
25c0: 67 20 61 52 65 61 64 72 5b 32 2a 69 2d 4e 5d 20  g aReadr[2*i-N] 
25d0: 61 6e 64 20 61 52 65 61 64 72 5b 32 2a 69 2d 4e  and aReadr[2*i-N
25e0: 2b 31 5d 2e 20 57 68 69 63 68 65 76 65 72 20 6b  +1]. Whichever k
25f0: 65 79 20 69 73 20 73 6d 61 6c 6c 65 72 2c 20 74  ey is smaller, t
2600: 68 65 0a 2a 2a 20 61 54 72 65 65 20 65 6c 65 6d  he.** aTree elem
2610: 65 6e 74 20 69 73 20 73 65 74 20 74 6f 20 74 68  ent is set to th
2620: 65 20 69 6e 64 65 78 20 6f 66 20 69 74 2e 20 0a  e index of it. .
2630: 2a 2a 0a 2a 2a 20 46 6f 72 20 74 68 65 20 70 75  **.** For the pu
2640: 72 70 6f 73 65 73 20 6f 66 20 74 68 69 73 20 63  rposes of this c
2650: 6f 6d 70 61 72 69 73 6f 6e 2c 20 45 4f 46 20 69  omparison, EOF i
2660: 73 20 63 6f 6e 73 69 64 65 72 65 64 20 67 72 65  s considered gre
2670: 61 74 65 72 20 74 68 61 6e 20 61 6e 79 0a 2a 2a  ater than any.**
2680: 20 6f 74 68 65 72 20 6b 65 79 20 76 61 6c 75 65   other key value
2690: 2e 20 49 66 20 74 68 65 20 6b 65 79 73 20 61 72  . If the keys ar
26a0: 65 20 65 71 75 61 6c 20 28 6f 6e 6c 79 20 70 6f  e equal (only po
26b0: 73 73 69 62 6c 65 20 77 69 74 68 20 74 77 6f 20  ssible with two 
26c0: 45 4f 46 0a 2a 2a 20 76 61 6c 75 65 73 29 2c 20  EOF.** values), 
26d0: 69 74 20 64 6f 65 73 6e 27 74 20 6d 61 74 74 65  it doesn't matte
26e0: 72 20 77 68 69 63 68 20 69 6e 64 65 78 20 69 73  r which index is
26f0: 20 73 74 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 54   stored..**.** T
2700: 68 65 20 28 4e 2f 34 29 20 65 6c 65 6d 65 6e 74  he (N/4) element
2710: 73 20 6f 66 20 61 54 72 65 65 5b 5d 20 74 68 61  s of aTree[] tha
2720: 74 20 70 72 65 63 65 64 65 20 74 68 65 20 66 69  t precede the fi
2730: 6e 61 6c 20 28 4e 2f 32 29 20 64 65 73 63 72 69  nal (N/2) descri
2740: 62 65 64 20 0a 2a 2a 20 61 62 6f 76 65 20 63 6f  bed .** above co
2750: 6e 74 61 69 6e 73 20 74 68 65 20 69 6e 64 65 78  ntains the index
2760: 20 6f 66 20 74 68 65 20 73 6d 61 6c 6c 65 73 74   of the smallest
2770: 20 6f 66 20 65 61 63 68 20 62 6c 6f 63 6b 20 6f   of each block o
2780: 66 20 34 20 50 6d 61 52 65 61 64 65 72 73 0a 2a  f 4 PmaReaders.*
2790: 2a 20 41 6e 64 20 73 6f 20 6f 6e 2e 20 53 6f 20  * And so on. So 
27a0: 74 68 61 74 20 61 54 72 65 65 5b 31 5d 20 63 6f  that aTree[1] co
27b0: 6e 74 61 69 6e 73 20 74 68 65 20 69 6e 64 65 78  ntains the index
27c0: 20 6f 66 20 74 68 65 20 50 6d 61 52 65 61 64 65   of the PmaReade
27d0: 72 20 74 68 61 74 20 0a 2a 2a 20 63 75 72 72 65  r that .** curre
27e0: 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f 20 74  ntly points to t
27f0: 68 65 20 73 6d 61 6c 6c 65 73 74 20 6b 65 79 20  he smallest key 
2800: 76 61 6c 75 65 2e 20 61 54 72 65 65 5b 30 5d 20  value. aTree[0] 
2810: 69 73 20 75 6e 75 73 65 64 2e 0a 2a 2a 0a 2a 2a  is unused..**.**
2820: 20 45 78 61 6d 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20   Example:.**.** 
2830: 20 20 20 20 61 52 65 61 64 72 5b 30 5d 20 2d 3e      aReadr[0] ->
2840: 20 42 61 6e 61 6e 61 0a 2a 2a 20 20 20 20 20 61   Banana.**     a
2850: 52 65 61 64 72 5b 31 5d 20 2d 3e 20 46 65 69 6a  Readr[1] -> Feij
2860: 6f 61 0a 2a 2a 20 20 20 20 20 61 52 65 61 64 72  oa.**     aReadr
2870: 5b 32 5d 20 2d 3e 20 45 6c 64 65 72 62 65 72 72  [2] -> Elderberr
2880: 79 0a 2a 2a 20 20 20 20 20 61 52 65 61 64 72 5b  y.**     aReadr[
2890: 33 5d 20 2d 3e 20 43 75 72 72 61 6e 74 0a 2a 2a  3] -> Currant.**
28a0: 20 20 20 20 20 61 52 65 61 64 72 5b 34 5d 20 2d       aReadr[4] -
28b0: 3e 20 47 72 61 70 65 66 72 75 69 74 0a 2a 2a 20  > Grapefruit.** 
28c0: 20 20 20 20 61 52 65 61 64 72 5b 35 5d 20 2d 3e      aReadr[5] ->
28d0: 20 41 70 70 6c 65 0a 2a 2a 20 20 20 20 20 61 52   Apple.**     aR
28e0: 65 61 64 72 5b 36 5d 20 2d 3e 20 44 75 72 69 61  eadr[6] -> Duria
28f0: 6e 0a 2a 2a 20 20 20 20 20 61 52 65 61 64 72 5b  n.**     aReadr[
2900: 37 5d 20 2d 3e 20 45 4f 46 0a 2a 2a 0a 2a 2a 20  7] -> EOF.**.** 
2910: 20 20 20 20 61 54 72 65 65 5b 5d 20 3d 20 7b 20      aTree[] = { 
2920: 58 2c 20 35 20 20 20 30 2c 20 35 20 20 20 20 30  X, 5   0, 5    0
2930: 2c 20 33 2c 20 35 2c 20 36 20 7d 0a 2a 2a 0a 2a  , 3, 5, 6 }.**.*
2940: 2a 20 54 68 65 20 63 75 72 72 65 6e 74 20 65 6c  * The current el
2950: 65 6d 65 6e 74 20 69 73 20 22 41 70 70 6c 65 22  ement is "Apple"
2960: 20 28 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74   (the value of t
2970: 68 65 20 6b 65 79 20 69 6e 64 69 63 61 74 65 64  he key indicated
2980: 20 62 79 20 0a 2a 2a 20 50 6d 61 52 65 61 64 65   by .** PmaReade
2990: 72 20 35 29 2e 20 57 68 65 6e 20 74 68 65 20 4e  r 5). When the N
29a0: 65 78 74 28 29 20 6f 70 65 72 61 74 69 6f 6e 20  ext() operation 
29b0: 69 73 20 69 6e 76 6f 6b 65 64 2c 20 50 6d 61 52  is invoked, PmaR
29c0: 65 61 64 65 72 20 35 20 77 69 6c 6c 0a 2a 2a 20  eader 5 will.** 
29d0: 62 65 20 61 64 76 61 6e 63 65 64 20 74 6f 20 74  be advanced to t
29e0: 68 65 20 6e 65 78 74 20 6b 65 79 20 69 6e 20 69  he next key in i
29f0: 74 73 20 73 65 67 6d 65 6e 74 2e 20 53 61 79 20  ts segment. Say 
2a00: 74 68 65 20 6e 65 78 74 20 6b 65 79 20 69 73 0a  the next key is.
2a10: 2a 2a 20 22 45 67 67 70 6c 61 6e 74 22 3a 0a 2a  ** "Eggplant":.*
2a20: 2a 0a 2a 2a 20 20 20 20 20 61 52 65 61 64 72 5b  *.**     aReadr[
2a30: 35 5d 20 2d 3e 20 45 67 67 70 6c 61 6e 74 0a 2a  5] -> Eggplant.*
2a40: 2a 0a 2a 2a 20 54 68 65 20 63 6f 6e 74 65 6e 74  *.** The content
2a50: 73 20 6f 66 20 61 54 72 65 65 5b 5d 20 61 72 65  s of aTree[] are
2a60: 20 75 70 64 61 74 65 64 20 66 69 72 73 74 20 62   updated first b
2a70: 79 20 63 6f 6d 70 61 72 69 6e 67 20 74 68 65 20  y comparing the 
2a80: 6e 65 77 20 50 6d 61 52 65 61 64 65 72 0a 2a 2a  new PmaReader.**
2a90: 20 35 20 6b 65 79 20 74 6f 20 74 68 65 20 63 75   5 key to the cu
2aa0: 72 72 65 6e 74 20 6b 65 79 20 6f 66 20 50 6d 61  rrent key of Pma
2ab0: 52 65 61 64 65 72 20 34 20 28 73 74 69 6c 6c 20  Reader 4 (still 
2ac0: 22 47 72 61 70 65 66 72 75 69 74 22 29 2e 20 54  "Grapefruit"). T
2ad0: 68 65 20 50 6d 61 52 65 61 64 65 72 0a 2a 2a 20  he PmaReader.** 
2ae0: 35 20 76 61 6c 75 65 20 69 73 20 73 74 69 6c 6c  5 value is still
2af0: 20 73 6d 61 6c 6c 65 72 2c 20 73 6f 20 61 54 72   smaller, so aTr
2b00: 65 65 5b 36 5d 20 69 73 20 73 65 74 20 74 6f 20  ee[6] is set to 
2b10: 35 2e 20 41 6e 64 20 73 6f 20 6f 6e 20 75 70 20  5. And so on up 
2b20: 74 68 65 20 74 72 65 65 2e 0a 2a 2a 20 54 68 65  the tree..** The
2b30: 20 76 61 6c 75 65 20 6f 66 20 50 6d 61 52 65 61   value of PmaRea
2b40: 64 65 72 20 36 20 2d 20 22 44 75 72 69 61 6e 22  der 6 - "Durian"
2b50: 20 2d 20 69 73 20 6e 6f 77 20 73 6d 61 6c 6c 65   - is now smalle
2b60: 72 20 74 68 61 6e 20 74 68 61 74 20 6f 66 20 50  r than that of P
2b70: 6d 61 52 65 61 64 65 72 0a 2a 2a 20 35 2c 20 73  maReader.** 5, s
2b80: 6f 20 61 54 72 65 65 5b 33 5d 20 69 73 20 73 65  o aTree[3] is se
2b90: 74 20 74 6f 20 36 2e 20 4b 65 79 20 30 20 69 73  t to 6. Key 0 is
2ba0: 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 6b 65   smaller than ke
2bb0: 79 20 36 20 28 42 61 6e 61 6e 61 3c 44 75 72 69  y 6 (Banana<Duri
2bc0: 61 6e 29 2c 0a 2a 2a 20 73 6f 20 74 68 65 20 76  an),.** so the v
2bd0: 61 6c 75 65 20 77 72 69 74 74 65 6e 20 69 6e 74  alue written int
2be0: 6f 20 65 6c 65 6d 65 6e 74 20 31 20 6f 66 20 74  o element 1 of t
2bf0: 68 65 20 61 72 72 61 79 20 69 73 20 30 2e 20 41  he array is 0. A
2c00: 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a  s follows:.**.**
2c10: 20 20 20 20 20 61 54 72 65 65 5b 5d 20 3d 20 7b       aTree[] = {
2c20: 20 58 2c 20 30 20 20 20 30 2c 20 36 20 20 20 20   X, 0   0, 6    
2c30: 30 2c 20 33 2c 20 35 2c 20 36 20 7d 0a 2a 2a 0a  0, 3, 5, 6 }.**.
2c40: 2a 2a 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64  ** In other word
2c50: 73 2c 20 65 61 63 68 20 74 69 6d 65 20 77 65 20  s, each time we 
2c60: 61 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20 6e  advance to the n
2c70: 65 78 74 20 73 6f 72 74 65 72 20 65 6c 65 6d 65  ext sorter eleme
2c80: 6e 74 2c 20 6c 6f 67 32 28 4e 29 0a 2a 2a 20 6b  nt, log2(N).** k
2c90: 65 79 20 63 6f 6d 70 61 72 69 73 6f 6e 20 6f 70  ey comparison op
2ca0: 65 72 61 74 69 6f 6e 73 20 61 72 65 20 72 65 71  erations are req
2cb0: 75 69 72 65 64 2c 20 77 68 65 72 65 20 4e 20 69  uired, where N i
2cc0: 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  s the number of 
2cd0: 73 65 67 6d 65 6e 74 73 0a 2a 2a 20 62 65 69 6e  segments.** bein
2ce0: 67 20 6d 65 72 67 65 64 20 28 72 6f 75 6e 64 65  g merged (rounde
2cf0: 64 20 75 70 20 74 6f 20 74 68 65 20 6e 65 78 74  d up to the next
2d00: 20 70 6f 77 65 72 20 6f 66 20 32 29 2e 0a 2a 2f   power of 2)..*/
2d10: 0a 73 74 72 75 63 74 20 4d 65 72 67 65 45 6e 67  .struct MergeEng
2d20: 69 6e 65 20 7b 0a 20 20 69 6e 74 20 6e 54 72 65  ine {.  int nTre
2d30: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
2d40: 20 20 20 2f 2a 20 55 73 65 64 20 73 69 7a 65 20     /* Used size 
2d50: 6f 66 20 61 54 72 65 65 2f 61 52 65 61 64 72 20  of aTree/aReadr 
2d60: 28 70 6f 77 65 72 20 6f 66 20 32 29 20 2a 2f 0a  (power of 2) */.
2d70: 20 20 69 6e 74 20 2a 61 54 72 65 65 3b 20 20 20    int *aTree;   
2d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2d90: 43 75 72 72 65 6e 74 20 73 74 61 74 65 20 6f 66  Current state of
2da0: 20 69 6e 63 72 65 6d 65 6e 74 61 6c 20 6d 65 72   incremental mer
2db0: 67 65 20 2a 2f 0a 20 20 50 6d 61 52 65 61 64 65  ge */.  PmaReade
2dc0: 72 20 2a 61 52 65 61 64 72 3b 20 20 20 20 20 20  r *aReadr;      
2dd0: 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 50     /* Array of P
2de0: 6d 61 52 65 61 64 65 72 73 20 74 6f 20 6d 65 72  maReaders to mer
2df0: 67 65 20 64 61 74 61 20 66 72 6f 6d 20 2a 2f 0a  ge data from */.
2e00: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 45 78 61 63 74 6c  };../*.** Exactl
2e10: 79 20 56 64 62 65 53 6f 72 74 65 72 2e 6e 54 61  y VdbeSorter.nTa
2e20: 73 6b 20 69 6e 73 74 61 6e 63 65 73 20 6f 66 20  sk instances of 
2e30: 74 68 69 73 20 6f 62 6a 65 63 74 20 61 72 65 20  this object are 
2e40: 61 6c 6c 6f 63 61 74 65 64 0a 2a 2a 20 61 73 20  allocated.** as 
2e50: 70 61 72 74 20 6f 66 20 65 61 63 68 20 56 64 62  part of each Vdb
2e60: 65 53 6f 72 74 65 72 20 6f 62 6a 65 63 74 2e 20  eSorter object. 
2e70: 49 6e 73 74 61 6e 63 65 73 20 61 72 65 20 6e 65  Instances are ne
2e80: 76 65 72 20 61 6c 6c 6f 63 61 74 65 64 20 61 6e  ver allocated an
2e90: 79 0a 2a 2a 20 6f 74 68 65 72 20 77 61 79 2e 20  y.** other way. 
2ea0: 56 64 62 65 53 6f 72 74 65 72 2e 6e 54 61 73 6b  VdbeSorter.nTask
2eb0: 20 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e   is set to the n
2ec0: 75 6d 62 65 72 20 6f 66 20 77 6f 72 6b 65 72 20  umber of worker 
2ed0: 74 68 72 65 61 64 73 20 61 6c 6c 6f 77 65 64 0a  threads allowed.
2ee0: 2a 2a 20 28 73 65 65 20 53 51 4c 49 54 45 5f 43  ** (see SQLITE_C
2ef0: 4f 4e 46 49 47 5f 57 4f 52 4b 45 52 5f 54 48 52  ONFIG_WORKER_THR
2f00: 45 41 44 53 29 20 70 6c 75 73 20 6f 6e 65 20 28  EADS) plus one (
2f10: 74 68 65 20 6d 61 69 6e 20 74 68 72 65 61 64 29  the main thread)
2f20: 2e 0a 2a 2a 0a 2a 2a 20 45 73 73 65 6e 74 69 61  ..**.** Essentia
2f30: 6c 6c 79 2c 20 74 68 69 73 20 73 74 72 75 63 74  lly, this struct
2f40: 75 72 65 20 63 6f 6e 74 61 69 6e 73 20 61 6c 6c  ure contains all
2f50: 20 74 68 6f 73 65 20 66 69 65 6c 64 73 20 6f 66   those fields of
2f60: 20 74 68 65 20 56 64 62 65 53 6f 72 74 65 72 0a   the VdbeSorter.
2f70: 2a 2a 20 73 74 72 75 63 74 75 72 65 20 66 6f 72  ** structure for
2f80: 20 77 68 69 63 68 20 65 61 63 68 20 74 68 72 65   which each thre
2f90: 61 64 20 72 65 71 75 69 72 65 73 20 61 20 73 65  ad requires a se
2fa0: 70 61 72 61 74 65 20 69 6e 73 74 61 6e 63 65 2e  parate instance.
2fb0: 20 46 6f 72 20 65 78 61 6d 70 6c 65 2c 0a 2a 2a   For example,.**
2fc0: 20 65 61 63 68 20 74 68 72 65 61 64 20 72 65 71   each thread req
2fd0: 75 72 69 65 73 20 69 74 73 20 6f 77 6e 20 55 6e  uries its own Un
2fe0: 70 61 63 6b 65 64 52 65 63 6f 72 64 20 6f 62 6a  packedRecord obj
2ff0: 65 63 74 20 74 6f 20 75 6e 70 61 63 6b 20 72 65  ect to unpack re
3000: 63 6f 72 64 73 20 69 6e 0a 2a 2a 20 61 73 20 70  cords in.** as p
3010: 61 72 74 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f  art of compariso
3020: 6e 20 6f 70 65 72 61 74 69 6f 6e 73 2e 0a 2a 2a  n operations..**
3030: 0a 2a 2a 20 42 65 66 6f 72 65 20 61 20 62 61 63  .** Before a bac
3040: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 69  kground thread i
3050: 73 20 6c 61 75 6e 63 68 65 64 2c 20 76 61 72 69  s launched, vari
3060: 61 62 6c 65 20 62 44 6f 6e 65 20 69 73 20 73 65  able bDone is se
3070: 74 20 74 6f 20 30 2e 20 54 68 65 6e 2c 20 0a 2a  t to 0. Then, .*
3080: 2a 20 72 69 67 68 74 20 62 65 66 6f 72 65 20 69  * right before i
3090: 74 20 65 78 69 74 73 2c 20 74 68 65 20 74 68 72  t exits, the thr
30a0: 65 61 64 20 69 74 73 65 6c 66 20 73 65 74 73 20  ead itself sets 
30b0: 62 44 6f 6e 65 20 74 6f 20 31 2e 20 54 68 69 73  bDone to 1. This
30c0: 20 69 73 20 75 73 65 64 20 66 6f 72 20 0a 2a 2a   is used for .**
30d0: 20 74 77 6f 20 70 75 72 70 6f 73 65 73 3a 0a 2a   two purposes:.*
30e0: 2a 0a 2a 2a 20 20 20 31 2e 20 57 68 65 6e 20 66  *.**   1. When f
30f0: 6c 75 73 68 69 6e 67 20 74 68 65 20 63 6f 6e 74  lushing the cont
3100: 65 6e 74 73 20 6f 66 20 6d 65 6d 6f 72 79 20 74  ents of memory t
3110: 6f 20 61 20 6c 65 76 65 6c 2d 30 20 50 4d 41 20  o a level-0 PMA 
3120: 6f 6e 20 64 69 73 6b 2c 20 74 6f 0a 2a 2a 20 20  on disk, to.**  
3130: 20 20 20 20 61 74 74 65 6d 70 74 20 74 6f 20 73      attempt to s
3140: 65 6c 65 63 74 20 61 20 53 6f 72 74 53 75 62 74  elect a SortSubt
3150: 61 73 6b 20 66 6f 72 20 77 68 69 63 68 20 74 68  ask for which th
3160: 65 72 65 20 69 73 20 6e 6f 74 20 61 6c 72 65 61  ere is not alrea
3170: 64 79 20 61 6e 0a 2a 2a 20 20 20 20 20 20 61 63  dy an.**      ac
3180: 74 69 76 65 20 62 61 63 6b 67 72 6f 75 6e 64 20  tive background 
3190: 74 68 72 65 61 64 20 28 73 69 6e 63 65 20 64 6f  thread (since do
31a0: 69 6e 67 20 73 6f 20 63 61 75 73 65 73 20 74 68  ing so causes th
31b0: 65 20 6d 61 69 6e 20 74 68 72 65 61 64 0a 2a 2a  e main thread.**
31c0: 20 20 20 20 20 20 74 6f 20 62 6c 6f 63 6b 20 75        to block u
31d0: 6e 74 69 6c 20 69 74 20 66 69 6e 69 73 68 65 73  ntil it finishes
31e0: 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 32 2e 20 49 66  )..**.**   2. If
31f0: 20 53 51 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f   SQLITE_DEBUG_SO
3200: 52 54 45 52 5f 54 48 52 45 41 44 53 20 69 73 20  RTER_THREADS is 
3210: 64 65 66 69 6e 65 64 2c 20 74 6f 20 64 65 74 65  defined, to dete
3220: 72 6d 69 6e 65 20 69 66 20 61 20 63 61 6c 6c 0a  rmine if a call.
3230: 2a 2a 20 20 20 20 20 20 74 6f 20 73 71 6c 69 74  **      to sqlit
3240: 65 33 54 68 72 65 61 64 4a 6f 69 6e 28 29 20 69  e3ThreadJoin() i
3250: 73 20 6c 69 6b 65 6c 79 20 74 6f 20 62 6c 6f 63  s likely to bloc
3260: 6b 2e 20 43 61 73 65 73 20 74 68 61 74 20 61 72  k. Cases that ar
3270: 65 20 6c 69 6b 65 6c 79 20 74 6f 0a 2a 2a 20 20  e likely to.**  
3280: 20 20 20 20 62 6c 6f 63 6b 20 70 72 6f 76 6f 6b      block provok
3290: 65 20 64 65 62 75 67 67 69 6e 67 20 6f 75 74 70  e debugging outp
32a0: 75 74 2e 0a 2a 2a 0a 2a 2a 20 49 6e 20 62 6f 74  ut..**.** In bot
32b0: 68 20 63 61 73 65 73 2c 20 74 68 65 20 65 66 66  h cases, the eff
32c0: 65 63 74 73 20 6f 66 20 74 68 65 20 6d 61 69 6e  ects of the main
32d0: 20 74 68 72 65 61 64 20 73 65 65 69 6e 67 20 28   thread seeing (
32e0: 62 44 6f 6e 65 3d 3d 30 29 20 65 76 65 6e 0a 2a  bDone==0) even.*
32f0: 2a 20 61 66 74 65 72 20 74 68 65 20 74 68 72 65  * after the thre
3300: 61 64 20 68 61 73 20 66 69 6e 69 73 68 65 64 20  ad has finished 
3310: 61 72 65 20 6e 6f 74 20 64 69 72 65 2e 20 53 6f  are not dire. So
3320: 20 77 65 20 64 6f 6e 27 74 20 77 6f 72 72 79 20   we don't worry 
3330: 61 62 6f 75 74 0a 2a 2a 20 6d 65 6d 6f 72 79 20  about.** memory 
3340: 62 61 72 72 69 65 72 73 20 61 6e 64 20 73 75 63  barriers and suc
3350: 68 20 68 65 72 65 2e 0a 2a 2f 0a 73 74 72 75 63  h here..*/.struc
3360: 74 20 53 6f 72 74 53 75 62 74 61 73 6b 20 7b 0a  t SortSubtask {.
3370: 20 20 53 51 4c 69 74 65 54 68 72 65 61 64 20 2a    SQLiteThread *
3380: 70 54 68 72 65 61 64 3b 20 20 20 20 20 20 20 20  pThread;        
3390: 20 20 2f 2a 20 42 61 63 6b 67 72 6f 75 6e 64 20    /* Background 
33a0: 74 68 72 65 61 64 2c 20 69 66 20 61 6e 79 20 2a  thread, if any *
33b0: 2f 0a 20 20 69 6e 74 20 62 44 6f 6e 65 3b 20 20  /.  int bDone;  
33c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
33d0: 20 20 20 20 2f 2a 20 53 65 74 20 69 66 20 74 68      /* Set if th
33e0: 72 65 61 64 20 69 73 20 66 69 6e 69 73 68 65 64  read is finished
33f0: 20 62 75 74 20 6e 6f 74 20 6a 6f 69 6e 65 64 20   but not joined 
3400: 2a 2f 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20  */.  VdbeSorter 
3410: 2a 70 53 6f 72 74 65 72 3b 20 20 20 20 20 20 20  *pSorter;       
3420: 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 74       /* Sorter t
3430: 68 61 74 20 6f 77 6e 73 20 74 68 69 73 20 73 75  hat owns this su
3440: 62 2d 74 61 73 6b 20 2a 2f 0a 20 20 55 6e 70 61  b-task */.  Unpa
3450: 63 6b 65 64 52 65 63 6f 72 64 20 2a 70 55 6e 70  ckedRecord *pUnp
3460: 61 63 6b 65 64 3b 20 20 20 20 20 20 2f 2a 20 53  acked;      /* S
3470: 70 61 63 65 20 74 6f 20 75 6e 70 61 63 6b 20 61  pace to unpack a
3480: 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20 53 6f 72   record */.  Sor
3490: 74 65 72 4c 69 73 74 20 6c 69 73 74 3b 20 20 20  terList list;   
34a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
34b0: 4c 69 73 74 20 66 6f 72 20 74 68 72 65 61 64 20  List for thread 
34c0: 74 6f 20 77 72 69 74 65 20 74 6f 20 61 20 50 4d  to write to a PM
34d0: 41 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 4d 41 3b  A */.  int nPMA;
34e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
34f0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
3500: 20 6f 66 20 50 4d 41 73 20 63 75 72 72 65 6e 74   of PMAs current
3510: 6c 79 20 69 6e 20 66 69 6c 65 20 2a 2f 0a 20 20  ly in file */.  
3520: 53 6f 72 74 65 72 46 69 6c 65 20 66 69 6c 65 3b  SorterFile file;
3530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3540: 2f 2a 20 54 65 6d 70 20 66 69 6c 65 20 66 6f 72  /* Temp file for
3550: 20 6c 65 76 65 6c 2d 30 20 50 4d 41 73 20 2a 2f   level-0 PMAs */
3560: 0a 20 20 53 6f 72 74 65 72 46 69 6c 65 20 66 69  .  SorterFile fi
3570: 6c 65 32 3b 20 20 20 20 20 20 20 20 20 20 20 20  le2;            
3580: 20 20 20 2f 2a 20 53 70 61 63 65 20 66 6f 72 20     /* Space for 
3590: 6f 74 68 65 72 20 50 4d 41 73 20 2a 2f 0a 7d 3b  other PMAs */.};
35a0: 0a 0a 2f 2a 0a 2a 2a 20 4d 61 69 6e 20 73 6f 72  ../*.** Main sor
35b0: 74 65 72 20 73 74 72 75 63 74 75 72 65 2e 20 41  ter structure. A
35c0: 20 73 69 6e 67 6c 65 20 69 6e 73 74 61 6e 63 65   single instance
35d0: 20 6f 66 20 74 68 69 73 20 69 73 20 61 6c 6c 6f   of this is allo
35e0: 63 61 74 65 64 20 66 6f 72 20 65 61 63 68 20 0a  cated for each .
35f0: 2a 2a 20 73 6f 72 74 65 72 20 63 75 72 73 6f 72  ** sorter cursor
3600: 20 63 72 65 61 74 65 64 20 62 79 20 74 68 65 20   created by the 
3610: 56 44 42 45 2e 0a 2a 2a 0a 2a 2a 20 6d 78 4b 65  VDBE..**.** mxKe
3620: 79 73 69 7a 65 3a 0a 2a 2a 20 20 20 41 73 20 72  ysize:.**   As r
3630: 65 63 6f 72 64 73 20 61 72 65 20 61 64 64 65 64  ecords are added
3640: 20 74 6f 20 74 68 65 20 73 6f 72 74 65 72 20 62   to the sorter b
3650: 79 20 63 61 6c 6c 73 20 74 6f 20 73 71 6c 69 74  y calls to sqlit
3660: 65 33 56 64 62 65 53 6f 72 74 65 72 57 72 69 74  e3VdbeSorterWrit
3670: 65 28 29 2c 0a 2a 2a 20 20 20 74 68 69 73 20 76  e(),.**   this v
3680: 61 72 69 61 62 6c 65 20 69 73 20 75 70 64 61 74  ariable is updat
3690: 65 64 20 73 6f 20 61 73 20 74 6f 20 62 65 20 73  ed so as to be s
36a0: 65 74 20 74 6f 20 74 68 65 20 73 69 7a 65 20 6f  et to the size o
36b0: 6e 20 64 69 73 6b 20 6f 66 20 74 68 65 0a 2a 2a  n disk of the.**
36c0: 20 20 20 6c 61 72 67 65 73 74 20 72 65 63 6f 72     largest recor
36d0: 64 20 69 6e 20 74 68 65 20 73 6f 72 74 65 72 2e  d in the sorter.
36e0: 0a 2a 2f 0a 73 74 72 75 63 74 20 56 64 62 65 53  .*/.struct VdbeS
36f0: 6f 72 74 65 72 20 7b 0a 20 20 69 6e 74 20 6d 6e  orter {.  int mn
3700: 50 6d 61 53 69 7a 65 3b 20 20 20 20 20 20 20 20  PmaSize;        
3710: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 69 6e            /* Min
3720: 69 6d 75 6d 20 50 4d 41 20 73 69 7a 65 2c 20 69  imum PMA size, i
3730: 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74  n bytes */.  int
3740: 20 6d 78 50 6d 61 53 69 7a 65 3b 20 20 20 20 20   mxPmaSize;     
3750: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3760: 4d 61 78 69 6d 75 6d 20 50 4d 41 20 73 69 7a 65  Maximum PMA size
3770: 2c 20 69 6e 20 62 79 74 65 73 2e 20 20 30 3d 3d  , in bytes.  0==
3780: 6e 6f 20 6c 69 6d 69 74 20 2a 2f 0a 20 20 69 6e  no limit */.  in
3790: 74 20 6d 78 4b 65 79 73 69 7a 65 3b 20 20 20 20  t mxKeysize;    
37a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
37b0: 20 4c 61 72 67 65 73 74 20 73 65 72 69 61 6c 69   Largest seriali
37c0: 7a 65 64 20 6b 65 79 20 73 65 65 6e 20 73 6f 20  zed key seen so 
37d0: 66 61 72 20 2a 2f 0a 20 20 69 6e 74 20 70 67 73  far */.  int pgs
37e0: 7a 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  z;              
37f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 69 6e           /* Main
3800: 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20 73   database page s
3810: 69 7a 65 20 2a 2f 0a 20 20 50 6d 61 52 65 61 64  ize */.  PmaRead
3820: 65 72 20 2a 70 52 65 61 64 65 72 3b 20 20 20 20  er *pReader;    
3830: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 61 64           /* Read
3840: 72 20 64 61 74 61 20 66 72 6f 6d 20 68 65 72 65  r data from here
3850: 20 61 66 74 65 72 20 52 65 77 69 6e 64 28 29 20   after Rewind() 
3860: 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65  */.  MergeEngine
3870: 20 2a 70 4d 65 72 67 65 72 3b 20 20 20 20 20 20   *pMerger;      
3880: 20 20 20 20 20 2f 2a 20 4f 72 20 68 65 72 65 2c       /* Or here,
3890: 20 69 66 20 62 55 73 65 54 68 72 65 61 64 73 3d   if bUseThreads=
38a0: 3d 30 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20  =0 */.  sqlite3 
38b0: 2a 64 62 3b 20 20 20 20 20 20 20 20 20 20 20 20  *db;            
38c0: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
38d0: 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a  ase connection *
38e0: 2f 0a 20 20 4b 65 79 49 6e 66 6f 20 2a 70 4b 65  /.  KeyInfo *pKe
38f0: 79 49 6e 66 6f 3b 20 20 20 20 20 20 20 20 20 20  yInfo;          
3900: 20 20 20 20 2f 2a 20 48 6f 77 20 74 6f 20 63 6f      /* How to co
3910: 6d 70 61 72 65 20 72 65 63 6f 72 64 73 20 2a 2f  mpare records */
3920: 0a 20 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72  .  UnpackedRecor
3930: 64 20 2a 70 55 6e 70 61 63 6b 65 64 3b 20 20 20  d *pUnpacked;   
3940: 20 20 20 2f 2a 20 55 73 65 64 20 62 79 20 56 64     /* Used by Vd
3950: 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28  beSorterCompare(
3960: 29 20 2a 2f 0a 20 20 53 6f 72 74 65 72 4c 69 73  ) */.  SorterLis
3970: 74 20 6c 69 73 74 3b 20 20 20 20 20 20 20 20 20  t list;         
3980: 20 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f         /* List o
3990: 66 20 69 6e 2d 6d 65 6d 6f 72 79 20 72 65 63 6f  f in-memory reco
39a0: 72 64 73 20 2a 2f 0a 20 20 69 6e 74 20 69 4d 65  rds */.  int iMe
39b0: 6d 6f 72 79 3b 20 20 20 20 20 20 20 20 20 20 20  mory;           
39c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73           /* Offs
39d0: 65 74 20 6f 66 20 66 72 65 65 20 73 70 61 63 65  et of free space
39e0: 20 69 6e 20 6c 69 73 74 2e 61 4d 65 6d 6f 72 79   in list.aMemory
39f0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 4d 65 6d 6f 72   */.  int nMemor
3a00: 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  y;              
3a10: 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
3a20: 20 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 61 6c   list.aMemory al
3a30: 6c 6f 63 61 74 69 6f 6e 20 69 6e 20 62 79 74 65  location in byte
3a40: 73 20 2a 2f 0a 20 20 75 38 20 62 55 73 65 50 4d  s */.  u8 bUsePM
3a50: 41 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  A;              
3a60: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69         /* True i
3a70: 66 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 50 4d  f one or more PM
3a80: 41 73 20 63 72 65 61 74 65 64 20 2a 2f 0a 20 20  As created */.  
3a90: 75 38 20 62 55 73 65 54 68 72 65 61 64 73 3b 20  u8 bUseThreads; 
3aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3ab0: 2f 2a 20 54 72 75 65 20 74 6f 20 75 73 65 20 62  /* True to use b
3ac0: 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64  ackground thread
3ad0: 73 20 2a 2f 0a 20 20 75 38 20 69 50 72 65 76 3b  s */.  u8 iPrev;
3ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3af0: 20 20 20 20 20 20 20 2f 2a 20 50 72 65 76 69 6f         /* Previo
3b00: 75 73 20 74 68 72 65 61 64 20 75 73 65 64 20 74  us thread used t
3b10: 6f 20 66 6c 75 73 68 20 50 4d 41 20 2a 2f 0a 20  o flush PMA */. 
3b20: 20 75 38 20 6e 54 61 73 6b 3b 20 20 20 20 20 20   u8 nTask;      
3b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3b40: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61 54 61 73   /* Size of aTas
3b50: 6b 5b 5d 20 61 72 72 61 79 20 2a 2f 0a 20 20 53  k[] array */.  S
3b60: 6f 72 74 53 75 62 74 61 73 6b 20 61 54 61 73 6b  ortSubtask aTask
3b70: 5b 31 5d 3b 20 20 20 20 20 20 20 20 20 20 20 2f  [1];           /
3b80: 2a 20 4f 6e 65 20 6f 72 20 6d 6f 72 65 20 73 75  * One or more su
3b90: 62 74 61 73 6b 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a  btasks */.};../*
3ba0: 0a 2a 2a 20 41 6e 20 69 6e 73 74 61 6e 63 65 20  .** An instance 
3bb0: 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  of the following
3bc0: 20 6f 62 6a 65 63 74 20 69 73 20 75 73 65 64 20   object is used 
3bd0: 74 6f 20 72 65 61 64 20 72 65 63 6f 72 64 73 20  to read records 
3be0: 6f 75 74 20 6f 66 20 61 0a 2a 2a 20 50 4d 41 2c  out of a.** PMA,
3bf0: 20 69 6e 20 73 6f 72 74 65 64 20 6f 72 64 65 72   in sorted order
3c00: 2e 20 20 54 68 65 20 6e 65 78 74 20 6b 65 79 20  .  The next key 
3c10: 74 6f 20 62 65 20 72 65 61 64 20 69 73 20 63 61  to be read is ca
3c20: 63 68 65 64 20 69 6e 20 6e 4b 65 79 2f 61 4b 65  ched in nKey/aKe
3c30: 79 2e 0a 2a 2a 20 70 46 69 6c 65 3d 3d 30 20 61  y..** pFile==0 a
3c40: 74 20 45 4f 46 2e 0a 2a 2f 0a 73 74 72 75 63 74  t EOF..*/.struct
3c50: 20 50 6d 61 52 65 61 64 65 72 20 7b 0a 20 20 69   PmaReader {.  i
3c60: 36 34 20 69 52 65 61 64 4f 66 66 3b 20 20 20 20  64 iReadOff;    
3c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3c80: 2a 20 43 75 72 72 65 6e 74 20 72 65 61 64 20 6f  * Current read o
3c90: 66 66 73 65 74 20 2a 2f 0a 20 20 69 36 34 20 69  ffset */.  i64 i
3ca0: 45 6f 66 3b 20 20 20 20 20 20 20 20 20 20 20 20  Eof;            
3cb0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 31 20             /* 1 
3cc0: 62 79 74 65 20 70 61 73 74 20 45 4f 46 20 66 6f  byte past EOF fo
3cd0: 72 20 74 68 69 73 20 50 6d 61 52 65 61 64 65 72  r this PmaReader
3ce0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 6c 6c 6f 63   */.  int nAlloc
3cf0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
3d00: 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f        /* Bytes o
3d10: 66 20 73 70 61 63 65 20 61 74 20 61 41 6c 6c 6f  f space at aAllo
3d20: 63 20 2a 2f 0a 20 20 69 6e 74 20 6e 4b 65 79 3b  c */.  int nKey;
3d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3d40: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
3d50: 20 6f 66 20 62 79 74 65 73 20 69 6e 20 6b 65 79   of bytes in key
3d60: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69   */.  sqlite3_fi
3d70: 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20 20 20 20  le *pFile;      
3d80: 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 77 65        /* File we
3d90: 20 61 72 65 20 72 65 61 64 69 6e 67 20 66 72 6f   are reading fro
3da0: 6d 20 2a 2f 0a 20 20 75 38 20 2a 61 41 6c 6c 6f  m */.  u8 *aAllo
3db0: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
3dc0: 20 20 20 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61         /* Alloca
3dd0: 74 65 64 20 73 70 61 63 65 20 2a 2f 0a 20 20 75  ted space */.  u
3de0: 38 20 2a 61 4b 65 79 3b 20 20 20 20 20 20 20 20  8 *aKey;        
3df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3e00: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 63 75 72  * Pointer to cur
3e10: 72 65 6e 74 20 6b 65 79 20 2a 2f 0a 20 20 75 38  rent key */.  u8
3e20: 20 2a 61 42 75 66 66 65 72 3b 20 20 20 20 20 20   *aBuffer;      
3e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3e40: 20 43 75 72 72 65 6e 74 20 72 65 61 64 20 62 75   Current read bu
3e50: 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  ffer */.  int nB
3e60: 75 66 66 65 72 3b 20 20 20 20 20 20 20 20 20 20  uffer;          
3e70: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
3e80: 65 20 6f 66 20 72 65 61 64 20 62 75 66 66 65 72  e of read buffer
3e90: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 75   in bytes */.  u
3ea0: 38 20 2a 61 4d 61 70 3b 20 20 20 20 20 20 20 20  8 *aMap;        
3eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3ec0: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 6d 61 70  * Pointer to map
3ed0: 70 69 6e 67 20 6f 66 20 65 6e 74 69 72 65 20 66  ping of entire f
3ee0: 69 6c 65 20 2a 2f 0a 20 20 49 6e 63 72 4d 65 72  ile */.  IncrMer
3ef0: 67 65 72 20 2a 70 49 6e 63 72 3b 20 20 20 20 20  ger *pIncr;     
3f00: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 63 72           /* Incr
3f10: 65 6d 65 6e 74 61 6c 20 6d 65 72 67 65 72 20 2a  emental merger *
3f20: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 4e 6f 72 6d  /.};../*.** Norm
3f30: 61 6c 6c 79 2c 20 61 20 50 6d 61 52 65 61 64 65  ally, a PmaReade
3f40: 72 20 6f 62 6a 65 63 74 20 69 74 65 72 61 74 65  r object iterate
3f50: 73 20 74 68 72 6f 75 67 68 20 61 6e 20 65 78 69  s through an exi
3f60: 73 74 69 6e 67 20 50 4d 41 20 73 74 6f 72 65 64  sting PMA stored
3f70: 20 0a 2a 2a 20 77 69 74 68 69 6e 20 61 20 74 65   .** within a te
3f80: 6d 70 20 66 69 6c 65 2e 20 48 6f 77 65 76 65 72  mp file. However
3f90: 2c 20 69 66 20 74 68 65 20 50 6d 61 52 65 61 64  , if the PmaRead
3fa0: 65 72 2e 70 49 6e 63 72 20 76 61 72 69 61 62 6c  er.pIncr variabl
3fb0: 65 20 70 6f 69 6e 74 73 20 74 6f 0a 2a 2a 20 61  e points to.** a
3fc0: 6e 20 6f 62 6a 65 63 74 20 6f 66 20 74 68 65 20  n object of the 
3fd0: 66 6f 6c 6c 6f 77 69 6e 67 20 74 79 70 65 2c 20  following type, 
3fe0: 69 74 20 6d 61 79 20 62 65 20 75 73 65 64 20 74  it may be used t
3ff0: 6f 20 69 74 65 72 61 74 65 2f 6d 65 72 67 65 20  o iterate/merge 
4000: 74 68 72 6f 75 67 68 0a 2a 2a 20 6d 75 6c 74 69  through.** multi
4010: 70 6c 65 20 50 4d 41 73 20 73 69 6d 75 6c 74 61  ple PMAs simulta
4020: 6e 65 6f 75 73 6c 79 2e 0a 2a 2a 0a 2a 2a 20 54  neously..**.** T
4030: 68 65 72 65 20 61 72 65 20 74 77 6f 20 74 79 70  here are two typ
4040: 65 73 20 6f 66 20 49 6e 63 72 4d 65 72 67 65 72  es of IncrMerger
4050: 20 6f 62 6a 65 63 74 20 2d 20 73 69 6e 67 6c 65   object - single
4060: 20 28 62 55 73 65 54 68 72 65 61 64 3d 3d 30 29   (bUseThread==0)
4070: 20 61 6e 64 20 0a 2a 2a 20 6d 75 6c 74 69 2d 74   and .** multi-t
4080: 68 72 65 61 64 65 64 20 28 62 55 73 65 54 68 72  hreaded (bUseThr
4090: 65 61 64 3d 3d 31 29 2e 20 0a 2a 2a 0a 2a 2a 20  ead==1). .**.** 
40a0: 41 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64  A multi-threaded
40b0: 20 49 6e 63 72 4d 65 72 67 65 72 20 6f 62 6a 65   IncrMerger obje
40c0: 63 74 20 75 73 65 73 20 74 77 6f 20 74 65 6d 70  ct uses two temp
40d0: 6f 72 61 72 79 20 66 69 6c 65 73 20 2d 20 61 46  orary files - aF
40e0: 69 6c 65 5b 30 5d 20 0a 2a 2a 20 61 6e 64 20 61  ile[0] .** and a
40f0: 46 69 6c 65 5b 31 5d 2e 20 4e 65 69 74 68 65 72  File[1]. Neither
4100: 20 66 69 6c 65 20 69 73 20 61 6c 6c 6f 77 65 64   file is allowed
4110: 20 74 6f 20 67 72 6f 77 20 74 6f 20 6d 6f 72 65   to grow to more
4120: 20 74 68 61 6e 20 6d 78 53 7a 20 62 79 74 65 73   than mxSz bytes
4130: 20 69 6e 20 0a 2a 2a 20 73 69 7a 65 2e 20 57 68   in .** size. Wh
4140: 65 6e 20 74 68 65 20 49 6e 63 72 4d 65 72 67 65  en the IncrMerge
4150: 72 20 69 73 20 69 6e 69 74 69 61 6c 69 7a 65 64  r is initialized
4160: 2c 20 69 74 20 72 65 61 64 73 20 65 6e 6f 75 67  , it reads enoug
4170: 68 20 64 61 74 61 20 66 72 6f 6d 20 0a 2a 2a 20  h data from .** 
4180: 70 4d 65 72 67 65 72 20 74 6f 20 70 6f 70 75 6c  pMerger to popul
4190: 61 74 65 20 61 46 69 6c 65 5b 30 5d 2e 20 49 74  ate aFile[0]. It
41a0: 20 74 68 65 6e 20 73 65 74 73 20 76 61 72 69 61   then sets varia
41b0: 62 6c 65 73 20 77 69 74 68 69 6e 20 74 68 65 20  bles within the 
41c0: 0a 2a 2a 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e  .** correspondin
41d0: 67 20 50 6d 61 52 65 61 64 65 72 20 6f 62 6a 65  g PmaReader obje
41e0: 63 74 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20  ct to read from 
41f0: 74 68 61 74 20 66 69 6c 65 20 61 6e 64 20 6b 69  that file and ki
4200: 63 6b 73 20 6f 66 66 20 0a 2a 2a 20 61 20 62 61  cks off .** a ba
4210: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
4220: 74 6f 20 70 6f 70 75 6c 61 74 65 20 61 46 69 6c  to populate aFil
4230: 65 5b 31 5d 20 77 69 74 68 20 74 68 65 20 6e 65  e[1] with the ne
4240: 78 74 20 6d 78 53 7a 20 62 79 74 65 73 20 6f 66  xt mxSz bytes of
4250: 20 0a 2a 2a 20 73 6f 72 74 65 64 20 72 65 63 6f   .** sorted reco
4260: 72 64 20 64 61 74 61 20 66 72 6f 6d 20 70 4d 65  rd data from pMe
4270: 72 67 65 72 2e 20 0a 2a 2a 0a 2a 2a 20 57 68 65  rger. .**.** Whe
4280: 6e 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 20  n the PmaReader 
4290: 72 65 61 63 68 65 73 20 74 68 65 20 65 6e 64 20  reaches the end 
42a0: 6f 66 20 61 46 69 6c 65 5b 30 5d 2c 20 69 74 20  of aFile[0], it 
42b0: 62 6c 6f 63 6b 73 20 75 6e 74 69 6c 20 74 68 65  blocks until the
42c0: 0a 2a 2a 20 62 61 63 6b 67 72 6f 75 6e 64 20 74  .** background t
42d0: 68 72 65 61 64 20 68 61 73 20 66 69 6e 69 73 68  hread has finish
42e0: 65 64 20 70 6f 70 75 6c 61 74 69 6e 67 20 61 46  ed populating aF
42f0: 69 6c 65 5b 31 5d 2e 20 49 74 20 74 68 65 6e 20  ile[1]. It then 
4300: 65 78 63 68 61 6e 67 65 73 0a 2a 2a 20 74 68 65  exchanges.** the
4310: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
4320: 20 61 46 69 6c 65 5b 30 5d 20 61 6e 64 20 61 46   aFile[0] and aF
4330: 69 6c 65 5b 31 5d 20 76 61 72 69 61 62 6c 65 73  ile[1] variables
4340: 20 77 69 74 68 69 6e 20 74 68 69 73 20 73 74 72   within this str
4350: 75 63 74 75 72 65 2c 0a 2a 2a 20 73 65 74 73 20  ucture,.** sets 
4360: 74 68 65 20 50 6d 61 52 65 61 64 65 72 20 66 69  the PmaReader fi
4370: 65 6c 64 73 20 74 6f 20 72 65 61 64 20 66 72 6f  elds to read fro
4380: 6d 20 74 68 65 20 6e 65 77 20 61 46 69 6c 65 5b  m the new aFile[
4390: 30 5d 20 61 6e 64 20 6b 69 63 6b 73 20 6f 66 66  0] and kicks off
43a0: 0a 2a 2a 20 61 6e 6f 74 68 65 72 20 62 61 63 6b  .** another back
43b0: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 74 6f  ground thread to
43c0: 20 70 6f 70 75 6c 61 74 65 20 74 68 65 20 6e 65   populate the ne
43d0: 77 20 61 46 69 6c 65 5b 31 5d 2e 20 41 6e 64 20  w aFile[1]. And 
43e0: 73 6f 20 6f 6e 2c 20 75 6e 74 69 6c 0a 2a 2a 20  so on, until.** 
43f0: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
4400: 70 4d 65 72 67 65 72 20 61 72 65 20 65 78 68 61  pMerger are exha
4410: 75 73 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 41 20 73  usted..**.** A s
4420: 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64 20 49  ingle-threaded I
4430: 6e 63 72 4d 65 72 67 65 72 20 64 6f 65 73 20 6e  ncrMerger does n
4440: 6f 74 20 6f 70 65 6e 20 61 6e 79 20 74 65 6d 70  ot open any temp
4450: 6f 72 61 72 79 20 66 69 6c 65 73 20 6f 66 20 69  orary files of i
4460: 74 73 0a 2a 2a 20 6f 77 6e 2e 20 49 6e 73 74 65  ts.** own. Inste
4470: 61 64 2c 20 69 74 20 68 61 73 20 65 78 63 6c 75  ad, it has exclu
4480: 73 69 76 65 20 61 63 63 65 73 73 20 74 6f 20 6d  sive access to m
4490: 78 53 7a 20 62 79 74 65 73 20 6f 66 20 73 70 61  xSz bytes of spa
44a0: 63 65 20 62 65 67 69 6e 6e 69 6e 67 0a 2a 2a 20  ce beginning.** 
44b0: 61 74 20 6f 66 66 73 65 74 20 69 53 74 61 72 74  at offset iStart
44c0: 4f 66 66 20 6f 66 20 66 69 6c 65 20 70 54 61 73  Off of file pTas
44d0: 6b 2d 3e 66 69 6c 65 32 2e 20 41 6e 64 20 69 6e  k->file2. And in
44e0: 73 74 65 61 64 20 6f 66 20 75 73 69 6e 67 20 61  stead of using a
44f0: 20 0a 2a 2a 20 62 61 63 6b 67 72 6f 75 6e 64 20   .** background 
4500: 74 68 72 65 61 64 20 74 6f 20 70 72 65 70 61 72  thread to prepar
4510: 65 20 64 61 74 61 20 66 6f 72 20 74 68 65 20 50  e data for the P
4520: 6d 61 52 65 61 64 65 72 2c 20 77 69 74 68 20 61  maReader, with a
4530: 20 73 69 6e 67 6c 65 0a 2a 2a 20 74 68 72 65 61   single.** threa
4540: 64 65 64 20 49 6e 63 72 4d 65 72 67 65 72 20 74  ded IncrMerger t
4550: 68 65 20 61 6c 6c 6f 63 61 74 65 20 70 61 72 74  he allocate part
4560: 20 6f 66 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32   of pTask->file2
4570: 20 69 73 20 22 72 65 66 69 6c 6c 65 64 22 20 77   is "refilled" w
4580: 69 74 68 0a 2a 2a 20 6b 65 79 73 20 66 72 6f 6d  ith.** keys from
4590: 20 70 4d 65 72 67 65 72 20 62 79 20 74 68 65 20   pMerger by the 
45a0: 63 61 6c 6c 69 6e 67 20 74 68 72 65 61 64 20 77  calling thread w
45b0: 68 65 6e 65 76 65 72 20 74 68 65 20 50 6d 61 52  henever the PmaR
45c0: 65 61 64 65 72 20 72 75 6e 73 20 6f 75 74 0a 2a  eader runs out.*
45d0: 2a 20 6f 66 20 64 61 74 61 2e 0a 2a 2f 0a 73 74  * of data..*/.st
45e0: 72 75 63 74 20 49 6e 63 72 4d 65 72 67 65 72 20  ruct IncrMerger 
45f0: 7b 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20  {.  SortSubtask 
4600: 2a 70 54 61 73 6b 3b 20 20 20 20 20 20 20 20 20  *pTask;         
4610: 20 20 20 20 2f 2a 20 54 61 73 6b 20 74 68 61 74      /* Task that
4620: 20 6f 77 6e 73 20 74 68 69 73 20 6d 65 72 67 65   owns this merge
4630: 72 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69  r */.  MergeEngi
4640: 6e 65 20 2a 70 4d 65 72 67 65 72 3b 20 20 20 20  ne *pMerger;    
4650: 20 20 20 20 20 20 20 2f 2a 20 4d 65 72 67 65 20         /* Merge 
4660: 65 6e 67 69 6e 65 20 74 68 72 65 61 64 20 72 65  engine thread re
4670: 61 64 73 20 64 61 74 61 20 66 72 6f 6d 20 2a 2f  ads data from */
4680: 0a 20 20 69 36 34 20 69 53 74 61 72 74 4f 66 66  .  i64 iStartOff
4690: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
46a0: 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 74 6f 20     /* Offset to 
46b0: 73 74 61 72 74 20 77 72 69 74 69 6e 67 20 66 69  start writing fi
46c0: 6c 65 20 61 74 20 2a 2f 0a 20 20 69 6e 74 20 6d  le at */.  int m
46d0: 78 53 7a 3b 20 20 20 20 20 20 20 20 20 20 20 20  xSz;            
46e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61             /* Ma
46f0: 78 69 6d 75 6d 20 62 79 74 65 73 20 6f 66 20 64  ximum bytes of d
4700: 61 74 61 20 74 6f 20 73 74 6f 72 65 20 2a 2f 0a  ata to store */.
4710: 20 20 69 6e 74 20 62 45 6f 66 3b 20 20 20 20 20    int bEof;     
4720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4730: 20 20 2f 2a 20 53 65 74 20 74 6f 20 74 72 75 65    /* Set to true
4740: 20 77 68 65 6e 20 6d 65 72 67 65 20 69 73 20 66   when merge is f
4750: 69 6e 69 73 68 65 64 20 2a 2f 0a 20 20 69 6e 74  inished */.  int
4760: 20 62 55 73 65 54 68 72 65 61 64 3b 20 20 20 20   bUseThread;    
4770: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4780: 54 72 75 65 20 74 6f 20 75 73 65 20 61 20 62 67  True to use a bg
4790: 20 74 68 72 65 61 64 20 66 6f 72 20 74 68 69 73   thread for this
47a0: 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 53 6f 72   object */.  Sor
47b0: 74 65 72 46 69 6c 65 20 61 46 69 6c 65 5b 32 5d  terFile aFile[2]
47c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
47d0: 61 46 69 6c 65 5b 30 5d 20 66 6f 72 20 72 65 61  aFile[0] for rea
47e0: 64 69 6e 67 2c 20 5b 31 5d 20 66 6f 72 20 77 72  ding, [1] for wr
47f0: 69 74 69 6e 67 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  iting */.};../*.
4800: 2a 2a 20 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f  ** An instance o
4810: 66 20 74 68 69 73 20 6f 62 6a 65 63 74 20 69 73  f this object is
4820: 20 75 73 65 64 20 66 6f 72 20 77 72 69 74 69 6e   used for writin
4830: 67 20 61 20 50 4d 41 2e 0a 2a 2a 0a 2a 2a 20 54  g a PMA..**.** T
4840: 68 65 20 50 4d 41 20 69 73 20 77 72 69 74 74 65  he PMA is writte
4850: 6e 20 6f 6e 65 20 72 65 63 6f 72 64 20 61 74 20  n one record at 
4860: 61 20 74 69 6d 65 2e 20 20 45 61 63 68 20 72 65  a time.  Each re
4870: 63 6f 72 64 20 69 73 20 6f 66 20 61 6e 20 61 72  cord is of an ar
4880: 62 69 74 72 61 72 79 0a 2a 2a 20 73 69 7a 65 2e  bitrary.** size.
4890: 20 20 42 75 74 20 49 2f 4f 20 69 73 20 6d 6f 72    But I/O is mor
48a0: 65 20 65 66 66 69 63 69 65 6e 74 20 69 66 20 69  e efficient if i
48b0: 74 20 6f 63 63 75 72 73 20 69 6e 20 70 61 67 65  t occurs in page
48c0: 2d 73 69 7a 65 64 20 62 6c 6f 63 6b 73 20 77 68  -sized blocks wh
48d0: 65 72 65 0a 2a 2a 20 65 61 63 68 20 62 6c 6f 63  ere.** each bloc
48e0: 6b 20 69 73 20 61 6c 69 67 6e 65 64 20 6f 6e 20  k is aligned on 
48f0: 61 20 70 61 67 65 20 62 6f 75 6e 64 61 72 79 2e  a page boundary.
4900: 20 20 54 68 69 73 20 6f 62 6a 65 63 74 20 63 61    This object ca
4910: 63 68 65 73 20 77 72 69 74 65 73 20 74 6f 0a 2a  ches writes to.*
4920: 2a 20 74 68 65 20 50 4d 41 20 73 6f 20 74 68 61  * the PMA so tha
4930: 74 20 61 6c 69 67 6e 65 64 2c 20 70 61 67 65 2d  t aligned, page-
4940: 73 69 7a 65 20 62 6c 6f 63 6b 73 20 61 72 65 20  size blocks are 
4950: 77 72 69 74 74 65 6e 2e 0a 2a 2f 0a 73 74 72 75  written..*/.stru
4960: 63 74 20 50 6d 61 57 72 69 74 65 72 20 7b 0a 20  ct PmaWriter {. 
4970: 20 69 6e 74 20 65 46 57 45 72 72 3b 20 20 20 20   int eFWErr;    
4980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4990: 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20 69 66 20   /* Non-zero if 
49a0: 69 6e 20 61 6e 20 65 72 72 6f 72 20 73 74 61 74  in an error stat
49b0: 65 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75 66 66  e */.  u8 *aBuff
49c0: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  er;             
49d0: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
49e0: 72 20 74 6f 20 77 72 69 74 65 20 62 75 66 66 65  r to write buffe
49f0: 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66 66  r */.  int nBuff
4a00: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  er;             
4a10: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
4a20: 66 20 77 72 69 74 65 20 62 75 66 66 65 72 20 69  f write buffer i
4a30: 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74  n bytes */.  int
4a40: 20 69 42 75 66 53 74 61 72 74 3b 20 20 20 20 20   iBufStart;     
4a50: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4a60: 46 69 72 73 74 20 62 79 74 65 20 6f 66 20 62 75  First byte of bu
4a70: 66 66 65 72 20 74 6f 20 77 72 69 74 65 20 2a 2f  ffer to write */
4a80: 0a 20 20 69 6e 74 20 69 42 75 66 45 6e 64 3b 20  .  int iBufEnd; 
4a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4aa0: 20 20 20 2f 2a 20 4c 61 73 74 20 62 79 74 65 20     /* Last byte 
4ab0: 6f 66 20 62 75 66 66 65 72 20 74 6f 20 77 72 69  of buffer to wri
4ac0: 74 65 20 2a 2f 0a 20 20 69 36 34 20 69 57 72 69  te */.  i64 iWri
4ad0: 74 65 4f 66 66 3b 20 20 20 20 20 20 20 20 20 20  teOff;          
4ae0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65          /* Offse
4af0: 74 20 6f 66 20 73 74 61 72 74 20 6f 66 20 62 75  t of start of bu
4b00: 66 66 65 72 20 69 6e 20 66 69 6c 65 20 2a 2f 0a  ffer in file */.
4b10: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
4b20: 70 46 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20  pFile;          
4b30: 20 20 2f 2a 20 46 69 6c 65 20 74 6f 20 77 72 69    /* File to wri
4b40: 74 65 20 74 6f 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  te to */.};../*.
4b50: 2a 2a 20 54 68 69 73 20 6f 62 6a 65 63 74 20 69  ** This object i
4b60: 73 20 74 68 65 20 68 65 61 64 65 72 20 6f 6e 20  s the header on 
4b70: 61 20 73 69 6e 67 6c 65 20 72 65 63 6f 72 64 20  a single record 
4b80: 77 68 69 6c 65 20 74 68 61 74 20 72 65 63 6f 72  while that recor
4b90: 64 20 69 73 20 62 65 69 6e 67 0a 2a 2a 20 68 65  d is being.** he
4ba0: 6c 64 20 69 6e 20 6d 65 6d 6f 72 79 20 61 6e 64  ld in memory and
4bb0: 20 70 72 69 6f 72 20 74 6f 20 62 65 69 6e 67 20   prior to being 
4bc0: 77 72 69 74 74 65 6e 20 6f 75 74 20 61 73 20 70  written out as p
4bd0: 61 72 74 20 6f 66 20 61 20 50 4d 41 2e 0a 2a 2a  art of a PMA..**
4be0: 0a 2a 2a 20 48 6f 77 20 74 68 65 20 6c 69 6e 6b  .** How the link
4bf0: 65 64 20 6c 69 73 74 20 69 73 20 63 6f 6e 6e 65  ed list is conne
4c00: 63 74 65 64 20 64 65 70 65 6e 64 73 20 6f 6e 20  cted depends on 
4c10: 68 6f 77 20 6d 65 6d 6f 72 79 20 69 73 20 62 65  how memory is be
4c20: 69 6e 67 20 6d 61 6e 61 67 65 64 0a 2a 2a 20 62  ing managed.** b
4c30: 79 20 74 68 69 73 20 6d 6f 64 75 6c 65 2e 20 49  y this module. I
4c40: 66 20 75 73 69 6e 67 20 61 20 73 65 70 61 72 61  f using a separa
4c50: 74 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 6f  te allocation fo
4c60: 72 20 65 61 63 68 20 69 6e 2d 6d 65 6d 6f 72 79  r each in-memory
4c70: 20 72 65 63 6f 72 64 0a 2a 2a 20 28 56 64 62 65   record.** (Vdbe
4c80: 53 6f 72 74 65 72 2e 6c 69 73 74 2e 61 4d 65 6d  Sorter.list.aMem
4c90: 6f 72 79 3d 3d 30 29 2c 20 74 68 65 6e 20 74 68  ory==0), then th
4ca0: 65 20 6c 69 73 74 20 69 73 20 61 6c 77 61 79 73  e list is always
4cb0: 20 63 6f 6e 6e 65 63 74 65 64 20 75 73 69 6e 67   connected using
4cc0: 20 74 68 65 0a 2a 2a 20 53 6f 72 74 65 72 52 65   the.** SorterRe
4cd0: 63 6f 72 64 2e 75 2e 70 4e 65 78 74 20 70 6f 69  cord.u.pNext poi
4ce0: 6e 74 65 72 73 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c  nters..**.** Or,
4cf0: 20 69 66 20 75 73 69 6e 67 20 74 68 65 20 73 69   if using the si
4d00: 6e 67 6c 65 20 6c 61 72 67 65 20 61 6c 6c 6f 63  ngle large alloc
4d10: 61 74 69 6f 6e 20 6d 65 74 68 6f 64 20 28 56 64  ation method (Vd
4d20: 62 65 53 6f 72 74 65 72 2e 6c 69 73 74 2e 61 4d  beSorter.list.aM
4d30: 65 6d 6f 72 79 21 3d 30 29 2c 0a 2a 2a 20 74 68  emory!=0),.** th
4d40: 65 6e 20 77 68 69 6c 65 20 72 65 63 6f 72 64 73  en while records
4d50: 20 61 72 65 20 62 65 69 6e 67 20 61 63 63 75 6d   are being accum
4d60: 75 6c 61 74 65 64 20 74 68 65 20 6c 69 73 74 20  ulated the list 
4d70: 69 73 20 6c 69 6e 6b 65 64 20 75 73 69 6e 67 20  is linked using 
4d80: 74 68 65 0a 2a 2a 20 53 6f 72 74 65 72 52 65 63  the.** SorterRec
4d90: 6f 72 64 2e 75 2e 69 4e 65 78 74 20 6f 66 66 73  ord.u.iNext offs
4da0: 65 74 2e 20 54 68 69 73 20 69 73 20 62 65 63 61  et. This is beca
4db0: 75 73 65 20 74 68 65 20 61 4d 65 6d 6f 72 79 5b  use the aMemory[
4dc0: 5d 20 61 72 72 61 79 20 6d 61 79 0a 2a 2a 20 62  ] array may.** b
4dd0: 65 20 73 71 6c 69 74 65 33 52 65 61 6c 6c 6f 63  e sqlite3Realloc
4de0: 28 29 65 64 20 77 68 69 6c 65 20 72 65 63 6f 72  ()ed while recor
4df0: 64 73 20 61 72 65 20 62 65 69 6e 67 20 61 63 63  ds are being acc
4e00: 75 6d 75 6c 61 74 65 64 2e 20 4f 6e 63 65 20 74  umulated. Once t
4e10: 68 65 20 56 4d 0a 2a 2a 20 68 61 73 20 66 69 6e  he VM.** has fin
4e20: 69 73 68 65 64 20 70 61 73 73 69 6e 67 20 72 65  ished passing re
4e30: 63 6f 72 64 73 20 74 6f 20 74 68 65 20 73 6f 72  cords to the sor
4e40: 74 65 72 2c 20 6f 72 20 77 68 65 6e 20 74 68 65  ter, or when the
4e50: 20 69 6e 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65   in-memory buffe
4e60: 72 0a 2a 2a 20 69 73 20 66 75 6c 6c 2c 20 74 68  r.** is full, th
4e70: 65 20 6c 69 73 74 20 69 73 20 73 6f 72 74 65 64  e list is sorted
4e80: 2e 20 41 73 20 70 61 72 74 20 6f 66 20 74 68 65  . As part of the
4e90: 20 73 6f 72 74 69 6e 67 20 70 72 6f 63 65 73 73   sorting process
4ea0: 2c 20 69 74 20 69 73 0a 2a 2a 20 63 6f 6e 76 65  , it is.** conve
4eb0: 72 74 65 64 20 74 6f 20 75 73 65 20 74 68 65 20  rted to use the 
4ec0: 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 75 2e 70  SorterRecord.u.p
4ed0: 4e 65 78 74 20 70 6f 69 6e 74 65 72 73 2e 20 53  Next pointers. S
4ee0: 65 65 20 66 75 6e 63 74 69 6f 6e 0a 2a 2a 20 76  ee function.** v
4ef0: 64 62 65 53 6f 72 74 65 72 53 6f 72 74 28 29 20  dbeSorterSort() 
4f00: 66 6f 72 20 64 65 74 61 69 6c 73 2e 0a 2a 2f 0a  for details..*/.
4f10: 73 74 72 75 63 74 20 53 6f 72 74 65 72 52 65 63  struct SorterRec
4f20: 6f 72 64 20 7b 0a 20 20 69 6e 74 20 6e 56 61 6c  ord {.  int nVal
4f30: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4f40: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
4f50: 6f 66 20 74 68 65 20 72 65 63 6f 72 64 20 69 6e  of the record in
4f60: 20 62 79 74 65 73 20 2a 2f 0a 20 20 75 6e 69 6f   bytes */.  unio
4f70: 6e 20 7b 0a 20 20 20 20 53 6f 72 74 65 72 52 65  n {.    SorterRe
4f80: 63 6f 72 64 20 2a 70 4e 65 78 74 3b 20 20 20 20  cord *pNext;    
4f90: 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
4fa0: 20 74 6f 20 6e 65 78 74 20 72 65 63 6f 72 64 20   to next record 
4fb0: 69 6e 20 6c 69 73 74 20 2a 2f 0a 20 20 20 20 69  in list */.    i
4fc0: 6e 74 20 69 4e 65 78 74 3b 20 20 20 20 20 20 20  nt iNext;       
4fd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4fe0: 4f 66 66 73 65 74 20 77 69 74 68 69 6e 20 61 4d  Offset within aM
4ff0: 65 6d 6f 72 79 20 6f 66 20 6e 65 78 74 20 72 65  emory of next re
5000: 63 6f 72 64 20 2a 2f 0a 20 20 7d 20 75 3b 0a 20  cord */.  } u;. 
5010: 20 2f 2a 20 54 68 65 20 64 61 74 61 20 66 6f 72   /* The data for
5020: 20 74 68 65 20 72 65 63 6f 72 64 20 69 6d 6d 65   the record imme
5030: 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 73 20  diately follows 
5040: 74 68 69 73 20 68 65 61 64 65 72 20 2a 2f 0a 7d  this header */.}
5050: 3b 0a 0a 2f 2a 20 52 65 74 75 72 6e 20 61 20 70  ;../* Return a p
5060: 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 62 75  ointer to the bu
5070: 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ffer containing 
5080: 74 68 65 20 72 65 63 6f 72 64 20 64 61 74 61 20  the record data 
5090: 66 6f 72 20 53 6f 72 74 65 72 52 65 63 6f 72 64  for SorterRecord
50a0: 0a 2a 2a 20 6f 62 6a 65 63 74 20 70 2e 20 53 68  .** object p. Sh
50b0: 6f 75 6c 64 20 62 65 20 75 73 65 64 20 61 73 20  ould be used as 
50c0: 69 66 3a 0a 2a 2a 0a 2a 2a 20 20 20 76 6f 69 64  if:.**.**   void
50d0: 20 2a 53 52 56 41 4c 28 53 6f 72 74 65 72 52 65   *SRVAL(SorterRe
50e0: 63 6f 72 64 20 2a 70 29 20 7b 20 72 65 74 75 72  cord *p) { retur
50f0: 6e 20 28 76 6f 69 64 2a 29 26 70 5b 31 5d 3b 20  n (void*)&p[1]; 
5100: 7d 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 53 52 56  }.*/.#define SRV
5110: 41 4c 28 70 29 20 28 28 76 6f 69 64 2a 29 28 28  AL(p) ((void*)((
5120: 53 6f 72 74 65 72 52 65 63 6f 72 64 2a 29 28 70  SorterRecord*)(p
5130: 29 20 2b 20 31 29 29 0a 0a 2f 2a 20 54 68 65 20  ) + 1))../* The 
5140: 6d 69 6e 69 6d 75 6d 20 50 4d 41 20 73 69 7a 65  minimum PMA size
5150: 20 69 73 20 73 65 74 20 74 6f 20 74 68 69 73 20   is set to this 
5160: 76 61 6c 75 65 20 6d 75 6c 74 69 70 6c 69 65 64  value multiplied
5170: 20 62 79 20 74 68 65 20 64 61 74 61 62 61 73 65   by the database
5180: 0a 2a 2a 20 70 61 67 65 20 73 69 7a 65 20 69 6e  .** page size in
5190: 20 62 79 74 65 73 2e 20 20 2a 2f 0a 23 64 65 66   bytes.  */.#def
51a0: 69 6e 65 20 53 4f 52 54 45 52 5f 4d 49 4e 5f 57  ine SORTER_MIN_W
51b0: 4f 52 4b 49 4e 47 20 31 30 0a 0a 2f 2a 20 4d 61  ORKING 10../* Ma
51c0: 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20  ximum number of 
51d0: 50 4d 41 73 20 74 68 61 74 20 61 20 73 69 6e 67  PMAs that a sing
51e0: 6c 65 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 63  le MergeEngine c
51f0: 61 6e 20 6d 65 72 67 65 20 2a 2f 0a 23 64 65 66  an merge */.#def
5200: 69 6e 65 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  ine SORTER_MAX_M
5210: 45 52 47 45 5f 43 4f 55 4e 54 20 31 36 0a 0a 73  ERGE_COUNT 16..s
5220: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 49 6e  tatic int vdbeIn
5230: 63 72 53 77 61 70 28 49 6e 63 72 4d 65 72 67 65  crSwap(IncrMerge
5240: 72 2a 29 3b 0a 73 74 61 74 69 63 20 76 6f 69 64  r*);.static void
5250: 20 76 64 62 65 49 6e 63 72 46 72 65 65 28 49 6e   vdbeIncrFree(In
5260: 63 72 4d 65 72 67 65 72 20 2a 29 3b 0a 0a 2f 2a  crMerger *);../*
5270: 0a 2a 2a 20 46 72 65 65 20 61 6c 6c 20 6d 65 6d  .** Free all mem
5280: 6f 72 79 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f  ory belonging to
5290: 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 20 6f   the PmaReader o
52a0: 62 6a 65 63 74 20 70 61 73 73 65 64 20 61 73 20  bject passed as 
52b0: 74 68 65 20 73 65 63 6f 6e 64 0a 2a 2a 20 61 72  the second.** ar
52c0: 67 75 6d 65 6e 74 2e 20 41 6c 6c 20 73 74 72 75  gument. All stru
52d0: 63 74 75 72 65 20 66 69 65 6c 64 73 20 61 72 65  cture fields are
52e0: 20 73 65 74 20 74 6f 20 7a 65 72 6f 20 62 65 66   set to zero bef
52f0: 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a  ore returning..*
5300: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64  /.static void vd
5310: 62 65 50 6d 61 52 65 61 64 65 72 43 6c 65 61 72  bePmaReaderClear
5320: 28 50 6d 61 52 65 61 64 65 72 20 2a 70 52 65 61  (PmaReader *pRea
5330: 64 72 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66  dr){.  sqlite3_f
5340: 72 65 65 28 70 52 65 61 64 72 2d 3e 61 41 6c 6c  ree(pReadr->aAll
5350: 6f 63 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  oc);.  sqlite3_f
5360: 72 65 65 28 70 52 65 61 64 72 2d 3e 61 42 75 66  ree(pReadr->aBuf
5370: 66 65 72 29 3b 0a 20 20 69 66 28 20 70 52 65 61  fer);.  if( pRea
5380: 64 72 2d 3e 61 4d 61 70 20 29 20 73 71 6c 69 74  dr->aMap ) sqlit
5390: 65 33 4f 73 55 6e 66 65 74 63 68 28 70 52 65 61  e3OsUnfetch(pRea
53a0: 64 72 2d 3e 70 46 69 6c 65 2c 20 30 2c 20 70 52  dr->pFile, 0, pR
53b0: 65 61 64 72 2d 3e 61 4d 61 70 29 3b 0a 20 20 76  eadr->aMap);.  v
53c0: 64 62 65 49 6e 63 72 46 72 65 65 28 70 52 65 61  dbeIncrFree(pRea
53d0: 64 72 2d 3e 70 49 6e 63 72 29 3b 0a 20 20 6d 65  dr->pIncr);.  me
53e0: 6d 73 65 74 28 70 52 65 61 64 72 2c 20 30 2c 20  mset(pReadr, 0, 
53f0: 73 69 7a 65 6f 66 28 50 6d 61 52 65 61 64 65 72  sizeof(PmaReader
5400: 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61  ));.}../*.** Rea
5410: 64 20 6e 42 79 74 65 20 62 79 74 65 73 20 6f 66  d nByte bytes of
5420: 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 73   data from the s
5430: 74 72 65 61 6d 20 6f 66 20 64 61 74 61 20 69 74  tream of data it
5440: 65 72 61 74 65 64 20 62 79 20 6f 62 6a 65 63 74  erated by object
5450: 20 70 2e 0a 2a 2a 20 49 66 20 73 75 63 63 65 73   p..** If succes
5460: 73 66 75 6c 2c 20 73 65 74 20 2a 70 70 4f 75 74  sful, set *ppOut
5470: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 61 20 62   to point to a b
5480: 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67  uffer containing
5490: 20 74 68 65 20 64 61 74 61 0a 2a 2a 20 61 6e 64   the data.** and
54a0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
54b0: 4b 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66  K. Otherwise, if
54c0: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
54d0: 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69  , return an SQLi
54e0: 74 65 0a 2a 2a 20 65 72 72 6f 72 20 63 6f 64 65  te.** error code
54f0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 62 75 66 66  ..**.** The buff
5500: 65 72 20 69 6e 64 69 63 61 74 65 64 20 62 79 20  er indicated by 
5510: 2a 70 70 4f 75 74 20 6d 61 79 20 6f 6e 6c 79 20  *ppOut may only 
5520: 62 65 20 63 6f 6e 73 69 64 65 72 65 64 20 76 61  be considered va
5530: 6c 69 64 20 75 6e 74 69 6c 20 74 68 65 0a 2a 2a  lid until the.**
5540: 20 6e 65 78 74 20 63 61 6c 6c 20 74 6f 20 74 68   next call to th
5550: 69 73 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a  is function..*/.
5560: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 50  static int vdbeP
5570: 6d 61 52 65 61 64 42 6c 6f 62 28 0a 20 20 50 6d  maReadBlob(.  Pm
5580: 61 52 65 61 64 65 72 20 2a 70 2c 20 20 20 20 20  aReader *p,     
5590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
55a0: 20 50 6d 61 52 65 61 64 65 72 20 66 72 6f 6d 20   PmaReader from 
55b0: 77 68 69 63 68 20 74 6f 20 74 61 6b 65 20 74 68  which to take th
55c0: 65 20 62 6c 6f 62 20 2a 2f 0a 20 20 69 6e 74 20  e blob */.  int 
55d0: 6e 42 79 74 65 2c 20 20 20 20 20 20 20 20 20 20  nByte,          
55e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
55f0: 79 74 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20  ytes of data to 
5600: 72 65 61 64 20 2a 2f 0a 20 20 75 38 20 2a 2a 70  read */.  u8 **p
5610: 70 4f 75 74 20 20 20 20 20 20 20 20 20 20 20 20  pOut            
5620: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
5630: 3a 20 50 6f 69 6e 74 65 72 20 74 6f 20 62 75 66  : Pointer to buf
5640: 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64  fer containing d
5650: 61 74 61 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  ata */.){.  int 
5660: 69 42 75 66 3b 20 20 20 20 20 20 20 20 20 20 20  iBuf;           
5670: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
5680: 66 66 73 65 74 20 77 69 74 68 69 6e 20 62 75 66  ffset within buf
5690: 66 65 72 20 74 6f 20 72 65 61 64 20 66 72 6f 6d  fer to read from
56a0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 76 61 69 6c   */.  int nAvail
56b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
56c0: 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f        /* Bytes o
56d0: 66 20 64 61 74 61 20 61 76 61 69 6c 61 62 6c 65  f data available
56e0: 20 69 6e 20 62 75 66 66 65 72 20 2a 2f 0a 0a 20   in buffer */.. 
56f0: 20 69 66 28 20 70 2d 3e 61 4d 61 70 20 29 7b 0a   if( p->aMap ){.
5700: 20 20 20 20 2a 70 70 4f 75 74 20 3d 20 26 70 2d      *ppOut = &p-
5710: 3e 61 4d 61 70 5b 70 2d 3e 69 52 65 61 64 4f 66  >aMap[p->iReadOf
5720: 66 5d 3b 0a 20 20 20 20 70 2d 3e 69 52 65 61 64  f];.    p->iRead
5730: 4f 66 66 20 2b 3d 20 6e 42 79 74 65 3b 0a 20 20  Off += nByte;.  
5740: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
5750: 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72  OK;.  }..  asser
5760: 74 28 20 70 2d 3e 61 42 75 66 66 65 72 20 29 3b  t( p->aBuffer );
5770: 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20  ..  /* If there 
5780: 69 73 20 6e 6f 20 6d 6f 72 65 20 64 61 74 61 20  is no more data 
5790: 74 6f 20 62 65 20 72 65 61 64 20 66 72 6f 6d 20  to be read from 
57a0: 74 68 65 20 62 75 66 66 65 72 2c 20 72 65 61 64  the buffer, read
57b0: 20 74 68 65 20 6e 65 78 74 20 0a 20 20 2a 2a 20   the next .  ** 
57c0: 70 2d 3e 6e 42 75 66 66 65 72 20 62 79 74 65 73  p->nBuffer bytes
57d0: 20 6f 66 20 64 61 74 61 20 66 72 6f 6d 20 74 68   of data from th
57e0: 65 20 66 69 6c 65 20 69 6e 74 6f 20 69 74 2e 20  e file into it. 
57f0: 4f 72 2c 20 69 66 20 74 68 65 72 65 20 61 72 65  Or, if there are
5800: 20 6c 65 73 73 0a 20 20 2a 2a 20 74 68 61 6e 20   less.  ** than 
5810: 70 2d 3e 6e 42 75 66 66 65 72 20 62 79 74 65 73  p->nBuffer bytes
5820: 20 72 65 6d 61 69 6e 69 6e 67 20 69 6e 20 74 68   remaining in th
5830: 65 20 50 4d 41 2c 20 72 65 61 64 20 61 6c 6c 20  e PMA, read all 
5840: 72 65 6d 61 69 6e 69 6e 67 20 64 61 74 61 2e 20  remaining data. 
5850: 20 2a 2f 0a 20 20 69 42 75 66 20 3d 20 70 2d 3e   */.  iBuf = p->
5860: 69 52 65 61 64 4f 66 66 20 25 20 70 2d 3e 6e 42  iReadOff % p->nB
5870: 75 66 66 65 72 3b 0a 20 20 69 66 28 20 69 42 75  uffer;.  if( iBu
5880: 66 3d 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74 20  f==0 ){.    int 
5890: 6e 52 65 61 64 3b 20 20 20 20 20 20 20 20 20 20  nRead;          
58a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74            /* Byt
58b0: 65 73 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20  es to read from 
58c0: 64 69 73 6b 20 2a 2f 0a 20 20 20 20 69 6e 74 20  disk */.    int 
58d0: 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rc;             
58e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73 71 6c            /* sql
58f0: 69 74 65 33 4f 73 52 65 61 64 28 29 20 72 65 74  ite3OsRead() ret
5900: 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 20  urn code */..   
5910: 20 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20 68 6f   /* Determine ho
5920: 77 20 6d 61 6e 79 20 62 79 74 65 73 20 6f 66 20  w many bytes of 
5930: 64 61 74 61 20 74 6f 20 72 65 61 64 2e 20 2a 2f  data to read. */
5940: 0a 20 20 20 20 69 66 28 20 28 70 2d 3e 69 45 6f  .    if( (p->iEo
5950: 66 20 2d 20 70 2d 3e 69 52 65 61 64 4f 66 66 29  f - p->iReadOff)
5960: 20 3e 20 28 69 36 34 29 70 2d 3e 6e 42 75 66 66   > (i64)p->nBuff
5970: 65 72 20 29 7b 0a 20 20 20 20 20 20 6e 52 65 61  er ){.      nRea
5980: 64 20 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a  d = p->nBuffer;.
5990: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
59a0: 20 6e 52 65 61 64 20 3d 20 28 69 6e 74 29 28 70   nRead = (int)(p
59b0: 2d 3e 69 45 6f 66 20 2d 20 70 2d 3e 69 52 65 61  ->iEof - p->iRea
59c0: 64 4f 66 66 29 3b 0a 20 20 20 20 7d 0a 20 20 20  dOff);.    }.   
59d0: 20 61 73 73 65 72 74 28 20 6e 52 65 61 64 3e 30   assert( nRead>0
59e0: 20 29 3b 0a 0a 20 20 20 20 2f 2a 20 52 65 61 64   );..    /* Read
59f0: 72 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20  r data from the 
5a00: 66 69 6c 65 2e 20 52 65 74 75 72 6e 20 65 61 72  file. Return ear
5a10: 6c 79 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f  ly if an error o
5a20: 63 63 75 72 73 2e 20 2a 2f 0a 20 20 20 20 72 63  ccurs. */.    rc
5a30: 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64   = sqlite3OsRead
5a40: 28 70 2d 3e 70 46 69 6c 65 2c 20 70 2d 3e 61 42  (p->pFile, p->aB
5a50: 75 66 66 65 72 2c 20 6e 52 65 61 64 2c 20 70 2d  uffer, nRead, p-
5a60: 3e 69 52 65 61 64 4f 66 66 29 3b 0a 20 20 20 20  >iReadOff);.    
5a70: 61 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49  assert( rc!=SQLI
5a80: 54 45 5f 49 4f 45 52 52 5f 53 48 4f 52 54 5f 52  TE_IOERR_SHORT_R
5a90: 45 41 44 20 29 3b 0a 20 20 20 20 69 66 28 20 72  EAD );.    if( r
5aa0: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
5ab0: 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20  eturn rc;.  }.  
5ac0: 6e 41 76 61 69 6c 20 3d 20 70 2d 3e 6e 42 75 66  nAvail = p->nBuf
5ad0: 66 65 72 20 2d 20 69 42 75 66 3b 20 0a 0a 20 20  fer - iBuf; ..  
5ae0: 69 66 28 20 6e 42 79 74 65 3c 3d 6e 41 76 61 69  if( nByte<=nAvai
5af0: 6c 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20  l ){.    /* The 
5b00: 72 65 71 75 65 73 74 65 64 20 64 61 74 61 20 69  requested data i
5b10: 73 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 74  s available in t
5b20: 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 62 75 66  he in-memory buf
5b30: 66 65 72 2e 20 49 6e 20 74 68 69 73 0a 20 20 20  fer. In this.   
5b40: 20 2a 2a 20 63 61 73 65 20 74 68 65 72 65 20 69   ** case there i
5b50: 73 20 6e 6f 20 6e 65 65 64 20 74 6f 20 6d 61 6b  s no need to mak
5b60: 65 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20  e a copy of the 
5b70: 64 61 74 61 2c 20 6a 75 73 74 20 72 65 74 75 72  data, just retur
5b80: 6e 20 61 20 0a 20 20 20 20 2a 2a 20 70 6f 69 6e  n a .    ** poin
5b90: 74 65 72 20 69 6e 74 6f 20 74 68 65 20 62 75 66  ter into the buf
5ba0: 66 65 72 20 74 6f 20 74 68 65 20 63 61 6c 6c 65  fer to the calle
5bb0: 72 2e 20 20 2a 2f 0a 20 20 20 20 2a 70 70 4f 75  r.  */.    *ppOu
5bc0: 74 20 3d 20 26 70 2d 3e 61 42 75 66 66 65 72 5b  t = &p->aBuffer[
5bd0: 69 42 75 66 5d 3b 0a 20 20 20 20 70 2d 3e 69 52  iBuf];.    p->iR
5be0: 65 61 64 4f 66 66 20 2b 3d 20 6e 42 79 74 65 3b  eadOff += nByte;
5bf0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a  .  }else{.    /*
5c00: 20 54 68 65 20 72 65 71 75 65 73 74 65 64 20 64   The requested d
5c10: 61 74 61 20 69 73 20 6e 6f 74 20 61 6c 6c 20 61  ata is not all a
5c20: 76 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65 20  vailable in the 
5c30: 69 6e 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65 72  in-memory buffer
5c40: 2e 0a 20 20 20 20 2a 2a 20 49 6e 20 74 68 69 73  ..    ** In this
5c50: 20 63 61 73 65 2c 20 61 6c 6c 6f 63 61 74 65 20   case, allocate 
5c60: 73 70 61 63 65 20 61 74 20 70 2d 3e 61 41 6c 6c  space at p->aAll
5c70: 6f 63 5b 5d 20 74 6f 20 63 6f 70 79 20 74 68 65  oc[] to copy the
5c80: 20 72 65 71 75 65 73 74 65 64 0a 20 20 20 20 2a   requested.    *
5c90: 2a 20 72 61 6e 67 65 20 69 6e 74 6f 2e 20 54 68  * range into. Th
5ca0: 65 6e 20 72 65 74 75 72 6e 20 61 20 63 6f 70 79  en return a copy
5cb0: 20 6f 66 20 70 6f 69 6e 74 65 72 20 70 2d 3e 61   of pointer p->a
5cc0: 41 6c 6c 6f 63 20 74 6f 20 74 68 65 20 63 61 6c  Alloc to the cal
5cd0: 6c 65 72 2e 20 20 2a 2f 0a 20 20 20 20 69 6e 74  ler.  */.    int
5ce0: 20 6e 52 65 6d 3b 20 20 20 20 20 20 20 20 20 20   nRem;          
5cf0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79             /* By
5d00: 74 65 73 20 72 65 6d 61 69 6e 69 6e 67 20 74 6f  tes remaining to
5d10: 20 63 6f 70 79 20 2a 2f 0a 0a 20 20 20 20 2f 2a   copy */..    /*
5d20: 20 45 78 74 65 6e 64 20 74 68 65 20 70 2d 3e 61   Extend the p->a
5d30: 41 6c 6c 6f 63 5b 5d 20 61 6c 6c 6f 63 61 74 69  Alloc[] allocati
5d40: 6f 6e 20 69 66 20 72 65 71 75 69 72 65 64 2e 20  on if required. 
5d50: 2a 2f 0a 20 20 20 20 69 66 28 20 70 2d 3e 6e 41  */.    if( p->nA
5d60: 6c 6c 6f 63 3c 6e 42 79 74 65 20 29 7b 0a 20 20  lloc<nByte ){.  
5d70: 20 20 20 20 75 38 20 2a 61 4e 65 77 3b 0a 20 20      u8 *aNew;.  
5d80: 20 20 20 20 69 6e 74 20 6e 4e 65 77 20 3d 20 4d      int nNew = M
5d90: 41 58 28 31 32 38 2c 20 70 2d 3e 6e 41 6c 6c 6f  AX(128, p->nAllo
5da0: 63 2a 32 29 3b 0a 20 20 20 20 20 20 77 68 69 6c  c*2);.      whil
5db0: 65 28 20 6e 42 79 74 65 3e 6e 4e 65 77 20 29 20  e( nByte>nNew ) 
5dc0: 6e 4e 65 77 20 3d 20 6e 4e 65 77 2a 32 3b 0a 20  nNew = nNew*2;. 
5dd0: 20 20 20 20 20 61 4e 65 77 20 3d 20 73 71 6c 69       aNew = sqli
5de0: 74 65 33 52 65 61 6c 6c 6f 63 28 70 2d 3e 61 41  te3Realloc(p->aA
5df0: 6c 6c 6f 63 2c 20 6e 4e 65 77 29 3b 0a 20 20 20  lloc, nNew);.   
5e00: 20 20 20 69 66 28 20 21 61 4e 65 77 20 29 20 72     if( !aNew ) r
5e10: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
5e20: 45 4d 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 41 6c  EM;.      p->nAl
5e30: 6c 6f 63 20 3d 20 6e 4e 65 77 3b 0a 20 20 20 20  loc = nNew;.    
5e40: 20 20 70 2d 3e 61 41 6c 6c 6f 63 20 3d 20 61 4e    p->aAlloc = aN
5e50: 65 77 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  ew;.    }..    /
5e60: 2a 20 43 6f 70 79 20 61 73 20 6d 75 63 68 20 64  * Copy as much d
5e70: 61 74 61 20 61 73 20 69 73 20 61 76 61 69 6c 61  ata as is availa
5e80: 62 6c 65 20 69 6e 20 74 68 65 20 62 75 66 66 65  ble in the buffe
5e90: 72 20 69 6e 74 6f 20 74 68 65 20 73 74 61 72 74  r into the start
5ea0: 20 6f 66 0a 20 20 20 20 2a 2a 20 70 2d 3e 61 41   of.    ** p->aA
5eb0: 6c 6c 6f 63 5b 5d 2e 20 20 2a 2f 0a 20 20 20 20  lloc[].  */.    
5ec0: 6d 65 6d 63 70 79 28 70 2d 3e 61 41 6c 6c 6f 63  memcpy(p->aAlloc
5ed0: 2c 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 69 42  , &p->aBuffer[iB
5ee0: 75 66 5d 2c 20 6e 41 76 61 69 6c 29 3b 0a 20 20  uf], nAvail);.  
5ef0: 20 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d    p->iReadOff +=
5f00: 20 6e 41 76 61 69 6c 3b 0a 20 20 20 20 6e 52 65   nAvail;.    nRe
5f10: 6d 20 3d 20 6e 42 79 74 65 20 2d 20 6e 41 76 61  m = nByte - nAva
5f20: 69 6c 3b 0a 0a 20 20 20 20 2f 2a 20 54 68 65 20  il;..    /* The 
5f30: 66 6f 6c 6c 6f 77 69 6e 67 20 6c 6f 6f 70 20 63  following loop c
5f40: 6f 70 69 65 73 20 75 70 20 74 6f 20 70 2d 3e 6e  opies up to p->n
5f50: 42 75 66 66 65 72 20 62 79 74 65 73 20 70 65 72  Buffer bytes per
5f60: 20 69 74 65 72 61 74 69 6f 6e 20 69 6e 74 6f 0a   iteration into.
5f70: 20 20 20 20 2a 2a 20 74 68 65 20 70 2d 3e 61 41      ** the p->aA
5f80: 6c 6c 6f 63 5b 5d 20 62 75 66 66 65 72 2e 20 20  lloc[] buffer.  
5f90: 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 6e 52  */.    while( nR
5fa0: 65 6d 3e 30 20 29 7b 0a 20 20 20 20 20 20 69 6e  em>0 ){.      in
5fb0: 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
5fc0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 76 64 62            /* vdb
5fd0: 65 50 6d 61 52 65 61 64 42 6c 6f 62 28 29 20 72  ePmaReadBlob() r
5fe0: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
5ff0: 20 20 20 20 69 6e 74 20 6e 43 6f 70 79 3b 20 20      int nCopy;  
6000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6010: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74  /* Number of byt
6020: 65 73 20 74 6f 20 63 6f 70 79 20 2a 2f 0a 20 20  es to copy */.  
6030: 20 20 20 20 75 38 20 2a 61 4e 65 78 74 3b 20 20      u8 *aNext;  
6040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6050: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 62 75  /* Pointer to bu
6060: 66 66 65 72 20 74 6f 20 63 6f 70 79 20 64 61 74  ffer to copy dat
6070: 61 20 66 72 6f 6d 20 2a 2f 0a 0a 20 20 20 20 20  a from */..     
6080: 20 6e 43 6f 70 79 20 3d 20 6e 52 65 6d 3b 0a 20   nCopy = nRem;. 
6090: 20 20 20 20 20 69 66 28 20 6e 52 65 6d 3e 70 2d       if( nRem>p-
60a0: 3e 6e 42 75 66 66 65 72 20 29 20 6e 43 6f 70 79  >nBuffer ) nCopy
60b0: 20 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20   = p->nBuffer;. 
60c0: 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d       rc = vdbePm
60d0: 61 52 65 61 64 42 6c 6f 62 28 70 2c 20 6e 43 6f  aReadBlob(p, nCo
60e0: 70 79 2c 20 26 61 4e 65 78 74 29 3b 0a 20 20 20  py, &aNext);.   
60f0: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
6100: 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  E_OK ) return rc
6110: 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  ;.      assert( 
6120: 61 4e 65 78 74 21 3d 70 2d 3e 61 41 6c 6c 6f 63  aNext!=p->aAlloc
6130: 20 29 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79   );.      memcpy
6140: 28 26 70 2d 3e 61 41 6c 6c 6f 63 5b 6e 42 79 74  (&p->aAlloc[nByt
6150: 65 20 2d 20 6e 52 65 6d 5d 2c 20 61 4e 65 78 74  e - nRem], aNext
6160: 2c 20 6e 43 6f 70 79 29 3b 0a 20 20 20 20 20 20  , nCopy);.      
6170: 6e 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20  nRem -= nCopy;. 
6180: 20 20 20 7d 0a 0a 20 20 20 20 2a 70 70 4f 75 74     }..    *ppOut
6190: 20 3d 20 70 2d 3e 61 41 6c 6c 6f 63 3b 0a 20 20   = p->aAlloc;.  
61a0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  }..  return SQLI
61b0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
61c0: 52 65 61 64 20 61 20 76 61 72 69 6e 74 20 66 72  Read a varint fr
61d0: 6f 6d 20 74 68 65 20 73 74 72 65 61 6d 20 6f 66  om the stream of
61e0: 20 64 61 74 61 20 61 63 63 65 73 73 65 64 20 62   data accessed b
61f0: 79 20 70 2e 20 53 65 74 20 2a 70 6e 4f 75 74 20  y p. Set *pnOut 
6200: 74 6f 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 20  to.** the value 
6210: 72 65 61 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  read..*/.static 
6220: 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61 64 56  int vdbePmaReadV
6230: 61 72 69 6e 74 28 50 6d 61 52 65 61 64 65 72 20  arint(PmaReader 
6240: 2a 70 2c 20 75 36 34 20 2a 70 6e 4f 75 74 29 7b  *p, u64 *pnOut){
6250: 0a 20 20 69 6e 74 20 69 42 75 66 3b 0a 0a 20 20  .  int iBuf;..  
6260: 69 66 28 20 70 2d 3e 61 4d 61 70 20 29 7b 0a 20  if( p->aMap ){. 
6270: 20 20 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b     p->iReadOff +
6280: 3d 20 73 71 6c 69 74 65 33 47 65 74 56 61 72 69  = sqlite3GetVari
6290: 6e 74 28 26 70 2d 3e 61 4d 61 70 5b 70 2d 3e 69  nt(&p->aMap[p->i
62a0: 52 65 61 64 4f 66 66 5d 2c 20 70 6e 4f 75 74 29  ReadOff], pnOut)
62b0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69  ;.  }else{.    i
62c0: 42 75 66 20 3d 20 70 2d 3e 69 52 65 61 64 4f 66  Buf = p->iReadOf
62d0: 66 20 25 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a  f % p->nBuffer;.
62e0: 20 20 20 20 69 66 28 20 69 42 75 66 20 26 26 20      if( iBuf && 
62f0: 28 70 2d 3e 6e 42 75 66 66 65 72 2d 69 42 75 66  (p->nBuffer-iBuf
6300: 29 3e 3d 39 20 29 7b 0a 20 20 20 20 20 20 70 2d  )>=9 ){.      p-
6310: 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 73 71 6c  >iReadOff += sql
6320: 69 74 65 33 47 65 74 56 61 72 69 6e 74 28 26 70  ite3GetVarint(&p
6330: 2d 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d 2c  ->aBuffer[iBuf],
6340: 20 70 6e 4f 75 74 29 3b 0a 20 20 20 20 7d 65 6c   pnOut);.    }el
6350: 73 65 7b 0a 20 20 20 20 20 20 75 38 20 61 56 61  se{.      u8 aVa
6360: 72 69 6e 74 5b 31 36 5d 2c 20 2a 61 3b 0a 20 20  rint[16], *a;.  
6370: 20 20 20 20 69 6e 74 20 69 20 3d 20 30 2c 20 72      int i = 0, r
6380: 63 3b 0a 20 20 20 20 20 20 64 6f 7b 0a 20 20 20  c;.      do{.   
6390: 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d       rc = vdbePm
63a0: 61 52 65 61 64 42 6c 6f 62 28 70 2c 20 31 2c 20  aReadBlob(p, 1, 
63b0: 26 61 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  &a);.        if(
63c0: 20 72 63 20 29 20 72 65 74 75 72 6e 20 72 63 3b   rc ) return rc;
63d0: 0a 20 20 20 20 20 20 20 20 61 56 61 72 69 6e 74  .        aVarint
63e0: 5b 28 69 2b 2b 29 26 30 78 66 5d 20 3d 20 61 5b  [(i++)&0xf] = a[
63f0: 30 5d 3b 0a 20 20 20 20 20 20 7d 77 68 69 6c 65  0];.      }while
6400: 28 20 28 61 5b 30 5d 26 30 78 38 30 29 21 3d 30  ( (a[0]&0x80)!=0
6410: 20 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   );.      sqlite
6420: 33 47 65 74 56 61 72 69 6e 74 28 61 56 61 72 69  3GetVarint(aVari
6430: 6e 74 2c 20 70 6e 4f 75 74 29 3b 0a 20 20 20 20  nt, pnOut);.    
6440: 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  }.  }..  return 
6450: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
6460: 0a 2a 2a 20 41 74 74 65 6d 70 74 20 74 6f 20 6d  .** Attempt to m
6470: 65 6d 6f 72 79 20 6d 61 70 20 66 69 6c 65 20 70  emory map file p
6480: 46 69 6c 65 2e 20 49 66 20 73 75 63 63 65 73 73  File. If success
6490: 66 75 6c 2c 20 73 65 74 20 2a 70 70 20 74 6f 20  ful, set *pp to 
64a0: 70 6f 69 6e 74 20 74 6f 20 74 68 65 0a 2a 2a 20  point to the.** 
64b0: 6e 65 77 20 6d 61 70 70 69 6e 67 20 61 6e 64 20  new mapping and 
64c0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
64d0: 2e 20 49 66 20 74 68 65 20 6d 61 70 70 69 6e 67  . If the mapping
64e0: 20 69 73 20 6e 6f 74 20 61 74 74 65 6d 70 74 65   is not attempte
64f0: 64 20 0a 2a 2a 20 28 62 65 63 61 75 73 65 20 74  d .** (because t
6500: 68 65 20 66 69 6c 65 20 69 73 20 74 6f 6f 20 6c  he file is too l
6510: 61 72 67 65 20 6f 72 20 74 68 65 20 56 46 53 20  arge or the VFS 
6520: 6c 61 79 65 72 20 69 73 20 63 6f 6e 66 69 67 75  layer is configu
6530: 72 65 64 20 6e 6f 74 20 74 6f 20 75 73 65 0a 2a  red not to use.*
6540: 2a 20 6d 6d 61 70 29 2c 20 72 65 74 75 72 6e 20  * mmap), return 
6550: 53 51 4c 49 54 45 5f 4f 4b 20 61 6e 64 20 73 65  SQLITE_OK and se
6560: 74 20 2a 70 70 20 74 6f 20 4e 55 4c 4c 2e 0a 2a  t *pp to NULL..*
6570: 2a 0a 2a 2a 20 4f 72 2c 20 69 66 20 61 6e 20 65  *.** Or, if an e
6580: 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 72 65 74  rror occurs, ret
6590: 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72  urn an SQLite er
65a0: 72 6f 72 20 63 6f 64 65 2e 20 54 68 65 20 66 69  ror code. The fi
65b0: 6e 61 6c 20 76 61 6c 75 65 20 6f 66 0a 2a 2a 20  nal value of.** 
65c0: 2a 70 70 20 69 73 20 75 6e 64 65 66 69 6e 65 64  *pp is undefined
65d0: 20 69 6e 20 74 68 69 73 20 63 61 73 65 2e 0a 2a   in this case..*
65e0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
65f0: 65 53 6f 72 74 65 72 4d 61 70 46 69 6c 65 28 53  eSorterMapFile(S
6600: 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
6610: 6b 2c 20 53 6f 72 74 65 72 46 69 6c 65 20 2a 70  k, SorterFile *p
6620: 46 69 6c 65 2c 20 75 38 20 2a 2a 70 70 29 7b 0a  File, u8 **pp){.
6630: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
6640: 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70 46 69 6c  E_OK;.  if( pFil
6650: 65 2d 3e 69 45 6f 66 3c 3d 28 69 36 34 29 28 70  e->iEof<=(i64)(p
6660: 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 64  Task->pSorter->d
6670: 62 2d 3e 6e 4d 61 78 53 6f 72 74 65 72 4d 6d 61  b->nMaxSorterMma
6680: 70 29 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73  p) ){.    rc = s
6690: 71 6c 69 74 65 33 4f 73 46 65 74 63 68 28 70 46  qlite3OsFetch(pF
66a0: 69 6c 65 2d 3e 70 46 64 2c 20 30 2c 20 28 69 6e  ile->pFd, 0, (in
66b0: 74 29 70 46 69 6c 65 2d 3e 69 45 6f 66 2c 20 28  t)pFile->iEof, (
66c0: 76 6f 69 64 2a 2a 29 70 70 29 3b 0a 20 20 7d 0a  void**)pp);.  }.
66d0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
66e0: 2f 2a 0a 2a 2a 20 53 65 65 6b 20 50 6d 61 52 65  /*.** Seek PmaRe
66f0: 61 64 65 72 20 70 52 65 61 64 72 20 74 6f 20 6f  ader pReadr to o
6700: 66 66 73 65 74 20 69 4f 66 66 20 77 69 74 68 69  ffset iOff withi
6710: 6e 20 66 69 6c 65 20 70 46 69 6c 65 2e 20 52 65  n file pFile. Re
6720: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 0a  turn SQLITE_OK .
6730: 2a 2a 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  ** if successful
6740: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65  , or an SQLite e
6750: 72 72 6f 72 20 63 6f 64 65 20 69 66 20 61 6e 20  rror code if an 
6760: 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f  error occurs..*/
6770: 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65  .static int vdbe
6780: 50 6d 61 52 65 61 64 65 72 53 65 65 6b 28 0a 20  PmaReaderSeek(. 
6790: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
67a0: 61 73 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20  ask,            
67b0: 20 2f 2a 20 54 61 73 6b 20 63 6f 6e 74 65 78 74   /* Task context
67c0: 20 2a 2f 0a 20 20 50 6d 61 52 65 61 64 65 72 20   */.  PmaReader 
67d0: 2a 70 52 65 61 64 72 2c 20 20 20 20 20 20 20 20  *pReadr,        
67e0: 20 20 20 20 20 20 2f 2a 20 49 74 65 72 61 74 65        /* Iterate
67f0: 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f 0a   to populate */.
6800: 20 20 53 6f 72 74 65 72 46 69 6c 65 20 2a 70 46    SorterFile *pF
6810: 69 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ile,            
6820: 20 20 2f 2a 20 53 6f 72 74 65 72 20 66 69 6c 65    /* Sorter file
6830: 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f   to read from */
6840: 0a 20 20 69 36 34 20 69 4f 66 66 20 20 20 20 20  .  i64 iOff     
6850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6860: 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 69 6e 20     /* Offset in 
6870: 70 46 69 6c 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e  pFile */.){.  in
6880: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
6890: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 52 65  ;..  assert( pRe
68a0: 61 64 72 2d 3e 70 49 6e 63 72 3d 3d 30 20 7c 7c  adr->pIncr==0 ||
68b0: 20 70 52 65 61 64 72 2d 3e 70 49 6e 63 72 2d 3e   pReadr->pIncr->
68c0: 62 45 6f 66 3d 3d 30 20 29 3b 0a 0a 20 20 69 66  bEof==0 );..  if
68d0: 28 20 70 52 65 61 64 72 2d 3e 61 4d 61 70 20 29  ( pReadr->aMap )
68e0: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 55  {.    sqlite3OsU
68f0: 6e 66 65 74 63 68 28 70 52 65 61 64 72 2d 3e 70  nfetch(pReadr->p
6900: 46 69 6c 65 2c 20 30 2c 20 70 52 65 61 64 72 2d  File, 0, pReadr-
6910: 3e 61 4d 61 70 29 3b 0a 20 20 20 20 70 52 65 61  >aMap);.    pRea
6920: 64 72 2d 3e 61 4d 61 70 20 3d 20 30 3b 0a 20 20  dr->aMap = 0;.  
6930: 7d 0a 20 20 70 52 65 61 64 72 2d 3e 69 52 65 61  }.  pReadr->iRea
6940: 64 4f 66 66 20 3d 20 69 4f 66 66 3b 0a 20 20 70  dOff = iOff;.  p
6950: 52 65 61 64 72 2d 3e 69 45 6f 66 20 3d 20 70 46  Readr->iEof = pF
6960: 69 6c 65 2d 3e 69 45 6f 66 3b 0a 20 20 70 52 65  ile->iEof;.  pRe
6970: 61 64 72 2d 3e 70 46 69 6c 65 20 3d 20 70 46 69  adr->pFile = pFi
6980: 6c 65 2d 3e 70 46 64 3b 0a 0a 20 20 72 63 20 3d  le->pFd;..  rc =
6990: 20 76 64 62 65 53 6f 72 74 65 72 4d 61 70 46 69   vdbeSorterMapFi
69a0: 6c 65 28 70 54 61 73 6b 2c 20 70 46 69 6c 65 2c  le(pTask, pFile,
69b0: 20 26 70 52 65 61 64 72 2d 3e 61 4d 61 70 29 3b   &pReadr->aMap);
69c0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
69d0: 45 5f 4f 4b 20 26 26 20 70 52 65 61 64 72 2d 3e  E_OK && pReadr->
69e0: 61 4d 61 70 3d 3d 30 20 29 7b 0a 20 20 20 20 69  aMap==0 ){.    i
69f0: 6e 74 20 70 67 73 7a 20 3d 20 70 54 61 73 6b 2d  nt pgsz = pTask-
6a00: 3e 70 53 6f 72 74 65 72 2d 3e 70 67 73 7a 3b 0a  >pSorter->pgsz;.
6a10: 20 20 20 20 69 6e 74 20 69 42 75 66 20 3d 20 70      int iBuf = p
6a20: 52 65 61 64 72 2d 3e 69 52 65 61 64 4f 66 66 20  Readr->iReadOff 
6a30: 25 20 70 67 73 7a 3b 0a 20 20 20 20 69 66 28 20  % pgsz;.    if( 
6a40: 70 52 65 61 64 72 2d 3e 61 42 75 66 66 65 72 3d  pReadr->aBuffer=
6a50: 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 52 65 61  =0 ){.      pRea
6a60: 64 72 2d 3e 61 42 75 66 66 65 72 20 3d 20 28 75  dr->aBuffer = (u
6a70: 38 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  8*)sqlite3Malloc
6a80: 28 70 67 73 7a 29 3b 0a 20 20 20 20 20 20 69 66  (pgsz);.      if
6a90: 28 20 70 52 65 61 64 72 2d 3e 61 42 75 66 66 65  ( pReadr->aBuffe
6aa0: 72 3d 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49  r==0 ) rc = SQLI
6ab0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20  TE_NOMEM;.      
6ac0: 70 52 65 61 64 72 2d 3e 6e 42 75 66 66 65 72 20  pReadr->nBuffer 
6ad0: 3d 20 70 67 73 7a 3b 0a 20 20 20 20 7d 0a 20 20  = pgsz;.    }.  
6ae0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
6af0: 5f 4f 4b 20 26 26 20 69 42 75 66 20 29 7b 0a 20  _OK && iBuf ){. 
6b00: 20 20 20 20 20 69 6e 74 20 6e 52 65 61 64 20 3d       int nRead =
6b10: 20 70 67 73 7a 20 2d 20 69 42 75 66 3b 0a 20 20   pgsz - iBuf;.  
6b20: 20 20 20 20 69 66 28 20 28 70 52 65 61 64 72 2d      if( (pReadr-
6b30: 3e 69 52 65 61 64 4f 66 66 20 2b 20 6e 52 65 61  >iReadOff + nRea
6b40: 64 29 20 3e 20 70 52 65 61 64 72 2d 3e 69 45 6f  d) > pReadr->iEo
6b50: 66 20 29 7b 0a 20 20 20 20 20 20 20 20 6e 52 65  f ){.        nRe
6b60: 61 64 20 3d 20 28 69 6e 74 29 28 70 52 65 61 64  ad = (int)(pRead
6b70: 72 2d 3e 69 45 6f 66 20 2d 20 70 52 65 61 64 72  r->iEof - pReadr
6b80: 2d 3e 69 52 65 61 64 4f 66 66 29 3b 0a 20 20 20  ->iReadOff);.   
6b90: 20 20 20 7d 0a 20 20 20 20 20 20 72 63 20 3d 20     }.      rc = 
6ba0: 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28 0a 20  sqlite3OsRead(. 
6bb0: 20 20 20 20 20 20 20 20 20 70 52 65 61 64 72 2d           pReadr-
6bc0: 3e 70 46 69 6c 65 2c 20 26 70 52 65 61 64 72 2d  >pFile, &pReadr-
6bd0: 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d 2c 20  >aBuffer[iBuf], 
6be0: 6e 52 65 61 64 2c 20 70 52 65 61 64 72 2d 3e 69  nRead, pReadr->i
6bf0: 52 65 61 64 4f 66 66 0a 20 20 20 20 20 20 29 3b  ReadOff.      );
6c00: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
6c10: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
6c20: 2a 20 41 64 76 61 6e 63 65 20 50 6d 61 52 65 61  * Advance PmaRea
6c30: 64 65 72 20 70 52 65 61 64 72 20 74 6f 20 74 68  der pReadr to th
6c40: 65 20 6e 65 78 74 20 6b 65 79 20 69 6e 20 69 74  e next key in it
6c50: 73 20 50 4d 41 2e 20 52 65 74 75 72 6e 20 53 51  s PMA. Return SQ
6c60: 4c 49 54 45 5f 4f 4b 20 69 66 0a 2a 2a 20 6e 6f  LITE_OK if.** no
6c70: 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 6f   error occurs, o
6c80: 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  r an SQLite erro
6c90: 72 20 63 6f 64 65 20 69 66 20 6f 6e 65 20 64 6f  r code if one do
6ca0: 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  es..*/.static in
6cb0: 74 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 4e  t vdbePmaReaderN
6cc0: 65 78 74 28 50 6d 61 52 65 61 64 65 72 20 2a 70  ext(PmaReader *p
6cd0: 52 65 61 64 72 29 7b 0a 20 20 69 6e 74 20 72 63  Readr){.  int rc
6ce0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20   = SQLITE_OK;   
6cf0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
6d00: 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 75 36  urn Code */.  u6
6d10: 34 20 6e 52 65 63 20 3d 20 30 3b 20 20 20 20 20  4 nRec = 0;     
6d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6d30: 20 53 69 7a 65 20 6f 66 20 72 65 63 6f 72 64 20   Size of record 
6d40: 69 6e 20 62 79 74 65 73 20 2a 2f 0a 0a 0a 20 20  in bytes */...  
6d50: 69 66 28 20 70 52 65 61 64 72 2d 3e 69 52 65 61  if( pReadr->iRea
6d60: 64 4f 66 66 3e 3d 70 52 65 61 64 72 2d 3e 69 45  dOff>=pReadr->iE
6d70: 6f 66 20 29 7b 0a 20 20 20 20 49 6e 63 72 4d 65  of ){.    IncrMe
6d80: 72 67 65 72 20 2a 70 49 6e 63 72 20 3d 20 70 52  rger *pIncr = pR
6d90: 65 61 64 72 2d 3e 70 49 6e 63 72 3b 0a 20 20 20  eadr->pIncr;.   
6da0: 20 69 6e 74 20 62 45 6f 66 20 3d 20 31 3b 0a 20   int bEof = 1;. 
6db0: 20 20 20 69 66 28 20 70 49 6e 63 72 20 29 7b 0a     if( pIncr ){.
6dc0: 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 49        rc = vdbeI
6dd0: 6e 63 72 53 77 61 70 28 70 49 6e 63 72 29 3b 0a  ncrSwap(pIncr);.
6de0: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
6df0: 4c 49 54 45 5f 4f 4b 20 26 26 20 70 49 6e 63 72  LITE_OK && pIncr
6e00: 2d 3e 62 45 6f 66 3d 3d 30 20 29 7b 0a 20 20 20  ->bEof==0 ){.   
6e10: 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d       rc = vdbePm
6e20: 61 52 65 61 64 65 72 53 65 65 6b 28 0a 20 20 20  aReaderSeek(.   
6e30: 20 20 20 20 20 20 20 20 20 70 49 6e 63 72 2d 3e           pIncr->
6e40: 70 54 61 73 6b 2c 20 70 52 65 61 64 72 2c 20 26  pTask, pReadr, &
6e50: 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2c  pIncr->aFile[0],
6e60: 20 70 49 6e 63 72 2d 3e 69 53 74 61 72 74 4f 66   pIncr->iStartOf
6e70: 66 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20  f.        );.   
6e80: 20 20 20 20 20 62 45 6f 66 20 3d 20 30 3b 0a 20       bEof = 0;. 
6e90: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
6ea0: 20 20 69 66 28 20 62 45 6f 66 20 29 7b 0a 20 20    if( bEof ){.  
6eb0: 20 20 20 20 2f 2a 20 54 68 69 73 20 69 73 20 61      /* This is a
6ec0: 6e 20 45 4f 46 20 63 6f 6e 64 69 74 69 6f 6e 20  n EOF condition 
6ed0: 2a 2f 0a 20 20 20 20 20 20 76 64 62 65 50 6d 61  */.      vdbePma
6ee0: 52 65 61 64 65 72 43 6c 65 61 72 28 70 52 65 61  ReaderClear(pRea
6ef0: 64 72 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72  dr);.      retur
6f00: 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  n rc;.    }.  }.
6f10: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
6f20: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
6f30: 20 76 64 62 65 50 6d 61 52 65 61 64 56 61 72 69   vdbePmaReadVari
6f40: 6e 74 28 70 52 65 61 64 72 2c 20 26 6e 52 65 63  nt(pReadr, &nRec
6f50: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d  );.  }.  if( rc=
6f60: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
6f70: 20 20 70 52 65 61 64 72 2d 3e 6e 4b 65 79 20 3d    pReadr->nKey =
6f80: 20 28 69 6e 74 29 6e 52 65 63 3b 0a 20 20 20 20   (int)nRec;.    
6f90: 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64  rc = vdbePmaRead
6fa0: 42 6c 6f 62 28 70 52 65 61 64 72 2c 20 28 69 6e  Blob(pReadr, (in
6fb0: 74 29 6e 52 65 63 2c 20 26 70 52 65 61 64 72 2d  t)nRec, &pReadr-
6fc0: 3e 61 4b 65 79 29 3b 0a 20 20 7d 0a 0a 20 20 72  >aKey);.  }..  r
6fd0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
6fe0: 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 50 6d  ** Initialize Pm
6ff0: 61 52 65 61 64 65 72 20 70 52 65 61 64 72 20 74  aReader pReadr t
7000: 6f 20 73 63 61 6e 20 74 68 72 6f 75 67 68 20 74  o scan through t
7010: 68 65 20 50 4d 41 20 73 74 6f 72 65 64 20 69 6e  he PMA stored in
7020: 20 66 69 6c 65 20 70 46 69 6c 65 0a 2a 2a 20 73   file pFile.** s
7030: 74 61 72 74 69 6e 67 20 61 74 20 6f 66 66 73 65  tarting at offse
7040: 74 20 69 53 74 61 72 74 20 61 6e 64 20 65 6e 64  t iStart and end
7050: 69 6e 67 20 61 74 20 6f 66 66 73 65 74 20 69 45  ing at offset iE
7060: 6f 66 2d 31 2e 20 54 68 69 73 20 66 75 6e 63 74  of-1. This funct
7070: 69 6f 6e 20 0a 2a 2a 20 6c 65 61 76 65 73 20 74  ion .** leaves t
7080: 68 65 20 50 6d 61 52 65 61 64 65 72 20 70 6f 69  he PmaReader poi
7090: 6e 74 69 6e 67 20 74 6f 20 74 68 65 20 66 69 72  nting to the fir
70a0: 73 74 20 6b 65 79 20 69 6e 20 74 68 65 20 50 4d  st key in the PM
70b0: 41 20 28 6f 72 20 45 4f 46 20 69 66 20 74 68 65  A (or EOF if the
70c0: 20 0a 2a 2a 20 50 4d 41 20 69 73 20 65 6d 70 74   .** PMA is empt
70d0: 79 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  y)..**.** If the
70e0: 20 70 6e 42 79 74 65 20 70 61 72 61 6d 65 74 65   pnByte paramete
70f0: 72 20 69 73 20 4e 55 4c 4c 2c 20 74 68 65 6e 20  r is NULL, then 
7100: 69 74 20 69 73 20 61 73 73 75 6d 65 64 20 74 68  it is assumed th
7110: 61 74 20 74 68 65 20 66 69 6c 65 20 0a 2a 2a 20  at the file .** 
7120: 63 6f 6e 74 61 69 6e 73 20 61 20 73 69 6e 67 6c  contains a singl
7130: 65 20 50 4d 41 2c 20 61 6e 64 20 74 68 61 74 20  e PMA, and that 
7140: 74 68 61 74 20 50 4d 41 20 6f 6d 69 74 73 20 74  that PMA omits t
7150: 68 65 20 69 6e 69 74 69 61 6c 20 6c 65 6e 67 74  he initial lengt
7160: 68 20 76 61 72 69 6e 74 2e 0a 2a 2f 0a 73 74 61  h varint..*/.sta
7170: 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d 61 52  tic int vdbePmaR
7180: 65 61 64 65 72 49 6e 69 74 28 0a 20 20 53 6f 72  eaderInit(.  Sor
7190: 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c  tSubtask *pTask,
71a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
71b0: 54 61 73 6b 20 63 6f 6e 74 65 78 74 20 2a 2f 0a  Task context */.
71c0: 20 20 53 6f 72 74 65 72 46 69 6c 65 20 2a 70 46    SorterFile *pF
71d0: 69 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ile,            
71e0: 20 20 2f 2a 20 53 6f 72 74 65 72 20 66 69 6c 65    /* Sorter file
71f0: 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f   to read from */
7200: 0a 20 20 69 36 34 20 69 53 74 61 72 74 2c 20 20  .  i64 iStart,  
7210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7220: 20 20 20 2f 2a 20 53 74 61 72 74 20 6f 66 66 73     /* Start offs
7230: 65 74 20 69 6e 20 70 46 69 6c 65 20 2a 2f 0a 20  et in pFile */. 
7240: 20 50 6d 61 52 65 61 64 65 72 20 2a 70 52 65 61   PmaReader *pRea
7250: 64 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  dr,             
7260: 20 2f 2a 20 50 6d 61 52 65 61 64 65 72 20 74 6f   /* PmaReader to
7270: 20 70 6f 70 75 6c 61 74 65 20 2a 2f 0a 20 20 69   populate */.  i
7280: 36 34 20 2a 70 6e 42 79 74 65 20 20 20 20 20 20  64 *pnByte      
7290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
72a0: 2a 20 49 4e 2f 4f 55 54 3a 20 49 6e 63 72 65 6d  * IN/OUT: Increm
72b0: 65 6e 74 20 74 68 69 73 20 76 61 6c 75 65 20 62  ent this value b
72c0: 79 20 50 4d 41 20 73 69 7a 65 20 2a 2f 0a 29 7b  y PMA size */.){
72d0: 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 61 73  .  int rc;..  as
72e0: 73 65 72 74 28 20 70 46 69 6c 65 2d 3e 69 45 6f  sert( pFile->iEo
72f0: 66 3e 69 53 74 61 72 74 20 29 3b 0a 20 20 61 73  f>iStart );.  as
7300: 73 65 72 74 28 20 70 52 65 61 64 72 2d 3e 61 41  sert( pReadr->aA
7310: 6c 6c 6f 63 3d 3d 30 20 26 26 20 70 52 65 61 64  lloc==0 && pRead
7320: 72 2d 3e 6e 41 6c 6c 6f 63 3d 3d 30 20 29 3b 0a  r->nAlloc==0 );.
7330: 20 20 61 73 73 65 72 74 28 20 70 52 65 61 64 72    assert( pReadr
7340: 2d 3e 61 42 75 66 66 65 72 3d 3d 30 20 29 3b 0a  ->aBuffer==0 );.
7350: 20 20 61 73 73 65 72 74 28 20 70 52 65 61 64 72    assert( pReadr
7360: 2d 3e 61 4d 61 70 3d 3d 30 20 29 3b 0a 0a 20 20  ->aMap==0 );..  
7370: 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64  rc = vdbePmaRead
7380: 65 72 53 65 65 6b 28 70 54 61 73 6b 2c 20 70 52  erSeek(pTask, pR
7390: 65 61 64 72 2c 20 70 46 69 6c 65 2c 20 69 53 74  eadr, pFile, iSt
73a0: 61 72 74 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d  art);.  if( rc==
73b0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
73c0: 20 75 36 34 20 6e 42 79 74 65 3b 20 20 20 20 20   u64 nByte;     
73d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
73e0: 2a 20 53 69 7a 65 20 6f 66 20 50 4d 41 20 69 6e  * Size of PMA in
73f0: 20 62 79 74 65 73 20 2a 2f 0a 20 20 20 20 72 63   bytes */.    rc
7400: 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 56 61   = vdbePmaReadVa
7410: 72 69 6e 74 28 70 52 65 61 64 72 2c 20 26 6e 42  rint(pReadr, &nB
7420: 79 74 65 29 3b 0a 20 20 20 20 70 52 65 61 64 72  yte);.    pReadr
7430: 2d 3e 69 45 6f 66 20 3d 20 70 52 65 61 64 72 2d  ->iEof = pReadr-
7440: 3e 69 52 65 61 64 4f 66 66 20 2b 20 6e 42 79 74  >iReadOff + nByt
7450: 65 3b 0a 20 20 20 20 2a 70 6e 42 79 74 65 20 2b  e;.    *pnByte +
7460: 3d 20 6e 42 79 74 65 3b 0a 20 20 7d 0a 0a 20 20  = nByte;.  }..  
7470: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
7480: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64  K ){.    rc = vd
7490: 62 65 50 6d 61 52 65 61 64 65 72 4e 65 78 74 28  bePmaReaderNext(
74a0: 70 52 65 61 64 72 29 3b 0a 20 20 7d 0a 20 20 72  pReadr);.  }.  r
74b0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a  eturn rc;.}.../*
74c0: 0a 2a 2a 20 43 6f 6d 70 61 72 65 20 6b 65 79 31  .** Compare key1
74d0: 20 28 62 75 66 66 65 72 20 70 4b 65 79 31 2c 20   (buffer pKey1, 
74e0: 73 69 7a 65 20 6e 4b 65 79 31 20 62 79 74 65 73  size nKey1 bytes
74f0: 29 20 77 69 74 68 20 6b 65 79 32 20 28 62 75 66  ) with key2 (buf
7500: 66 65 72 20 70 4b 65 79 32 2c 20 0a 2a 2a 20 73  fer pKey2, .** s
7510: 69 7a 65 20 6e 4b 65 79 32 20 62 79 74 65 73 29  ize nKey2 bytes)
7520: 2e 20 55 73 65 20 28 70 54 61 73 6b 2d 3e 70 4b  . Use (pTask->pK
7530: 65 79 49 6e 66 6f 29 20 66 6f 72 20 74 68 65 20  eyInfo) for the 
7540: 63 6f 6c 6c 61 74 69 6f 6e 20 73 65 71 75 65 6e  collation sequen
7550: 63 65 73 0a 2a 2a 20 75 73 65 64 20 62 79 20 74  ces.** used by t
7560: 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2e 20 52  he comparison. R
7570: 65 74 75 72 6e 20 74 68 65 20 72 65 73 75 6c 74  eturn the result
7580: 20 6f 66 20 74 68 65 20 63 6f 6d 70 61 72 69 73   of the comparis
7590: 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65  on..**.** Before
75a0: 20 72 65 74 75 72 6e 69 6e 67 2c 20 6f 62 6a 65   returning, obje
75b0: 63 74 20 28 70 54 61 73 6b 2d 3e 70 55 6e 70 61  ct (pTask->pUnpa
75c0: 63 6b 65 64 29 20 69 73 20 70 6f 70 75 6c 61 74  cked) is populat
75d0: 65 64 20 77 69 74 68 20 74 68 65 0a 2a 2a 20 75  ed with the.** u
75e0: 6e 70 61 63 6b 65 64 20 76 65 72 73 69 6f 6e 20  npacked version 
75f0: 6f 66 20 6b 65 79 32 2e 20 4f 72 2c 20 69 66 20  of key2. Or, if 
7600: 70 4b 65 79 32 20 69 73 20 70 61 73 73 65 64 20  pKey2 is passed 
7610: 61 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2c 20  a NULL pointer, 
7620: 74 68 65 6e 20 69 74 20 0a 2a 2a 20 69 73 20 61  then it .** is a
7630: 73 73 75 6d 65 64 20 74 68 61 74 20 74 68 65 20  ssumed that the 
7640: 28 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65  (pTask->pUnpacke
7650: 64 29 20 73 74 72 75 63 74 75 72 65 20 61 6c 72  d) structure alr
7660: 65 61 64 79 20 63 6f 6e 74 61 69 6e 73 20 74 68  eady contains th
7670: 65 20 0a 2a 2a 20 75 6e 70 61 63 6b 65 64 20 6b  e .** unpacked k
7680: 65 79 20 74 6f 20 75 73 65 20 61 73 20 6b 65 79  ey to use as key
7690: 32 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 4f  2..**.** If an O
76a0: 4f 4d 20 65 72 72 6f 72 20 69 73 20 65 6e 63 6f  OM error is enco
76b0: 75 6e 74 65 72 65 64 2c 20 28 70 54 61 73 6b 2d  untered, (pTask-
76c0: 3e 70 55 6e 70 61 63 6b 65 64 2d 3e 65 72 72 6f  >pUnpacked->erro
76d0: 72 5f 72 63 29 20 69 73 20 73 65 74 0a 2a 2a 20  r_rc) is set.** 
76e0: 74 6f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 2e  to SQLITE_NOMEM.
76f0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
7700: 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65  dbeSorterCompare
7710: 28 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20  (.  SortSubtask 
7720: 2a 70 54 61 73 6b 2c 20 20 20 20 20 20 20 20 20  *pTask,         
7730: 20 20 20 20 2f 2a 20 53 75 62 74 61 73 6b 20 63      /* Subtask c
7740: 6f 6e 74 65 78 74 20 28 66 6f 72 20 70 4b 65 79  ontext (for pKey
7750: 49 6e 66 6f 29 20 2a 2f 0a 20 20 63 6f 6e 73 74  Info) */.  const
7760: 20 76 6f 69 64 20 2a 70 4b 65 79 31 2c 20 69 6e   void *pKey1, in
7770: 74 20 6e 4b 65 79 31 2c 20 20 20 2f 2a 20 4c 65  t nKey1,   /* Le
7780: 66 74 20 73 69 64 65 20 6f 66 20 63 6f 6d 70 61  ft side of compa
7790: 72 69 73 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74  rison */.  const
77a0: 20 76 6f 69 64 20 2a 70 4b 65 79 32 2c 20 69 6e   void *pKey2, in
77b0: 74 20 6e 4b 65 79 32 20 20 20 20 2f 2a 20 52 69  t nKey2    /* Ri
77c0: 67 68 74 20 73 69 64 65 20 6f 66 20 63 6f 6d 70  ght side of comp
77d0: 61 72 69 73 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 55  arison */.){.  U
77e0: 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20 2a 72  npackedRecord *r
77f0: 32 20 3d 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61  2 = pTask->pUnpa
7800: 63 6b 65 64 3b 0a 20 20 69 66 28 20 70 4b 65 79  cked;.  if( pKey
7810: 32 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  2 ){.    sqlite3
7820: 56 64 62 65 52 65 63 6f 72 64 55 6e 70 61 63 6b  VdbeRecordUnpack
7830: 28 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d  (pTask->pSorter-
7840: 3e 70 4b 65 79 49 6e 66 6f 2c 20 6e 4b 65 79 32  >pKeyInfo, nKey2
7850: 2c 20 70 4b 65 79 32 2c 20 72 32 29 3b 0a 20 20  , pKey2, r2);.  
7860: 7d 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  }.  return sqlit
7870: 65 33 56 64 62 65 52 65 63 6f 72 64 43 6f 6d 70  e3VdbeRecordComp
7880: 61 72 65 28 6e 4b 65 79 31 2c 20 70 4b 65 79 31  are(nKey1, pKey1
7890: 2c 20 72 32 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a  , r2, 0);.}../*.
78a0: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
78b0: 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 63 6f   is called to co
78c0: 6d 70 61 72 65 20 74 77 6f 20 50 6d 61 52 65 61  mpare two PmaRea
78d0: 64 65 72 20 6b 65 79 73 20 77 68 65 6e 20 6d 65  der keys when me
78e0: 72 67 69 6e 67 20 0a 2a 2a 20 6d 75 6c 74 69 70  rging .** multip
78f0: 6c 65 20 62 2d 74 72 65 65 20 73 65 67 6d 65 6e  le b-tree segmen
7900: 74 73 2e 20 50 61 72 61 6d 65 74 65 72 20 69 4f  ts. Parameter iO
7910: 75 74 20 69 73 20 74 68 65 20 69 6e 64 65 78 20  ut is the index 
7920: 6f 66 20 74 68 65 20 61 54 72 65 65 5b 5d 20 0a  of the aTree[] .
7930: 2a 2a 20 76 61 6c 75 65 20 74 6f 20 72 65 63 61  ** value to reca
7940: 6c 63 75 6c 61 74 65 2e 0a 2a 2f 0a 73 74 61 74  lculate..*/.stat
7950: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
7960: 72 44 6f 43 6f 6d 70 61 72 65 28 0a 20 20 53 6f  rDoCompare(.  So
7970: 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b  rtSubtask *pTask
7980: 2c 20 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65  , .  MergeEngine
7990: 20 2a 70 4d 65 72 67 65 72 2c 20 0a 20 20 69 6e   *pMerger, .  in
79a0: 74 20 69 4f 75 74 0a 29 7b 0a 20 20 69 6e 74 20  t iOut.){.  int 
79b0: 69 31 3b 0a 20 20 69 6e 74 20 69 32 3b 0a 20 20  i1;.  int i2;.  
79c0: 69 6e 74 20 69 52 65 73 3b 0a 20 20 50 6d 61 52  int iRes;.  PmaR
79d0: 65 61 64 65 72 20 2a 70 31 3b 0a 20 20 50 6d 61  eader *p1;.  Pma
79e0: 52 65 61 64 65 72 20 2a 70 32 3b 0a 0a 20 20 61  Reader *p2;..  a
79f0: 73 73 65 72 74 28 20 69 4f 75 74 3c 70 4d 65 72  ssert( iOut<pMer
7a00: 67 65 72 2d 3e 6e 54 72 65 65 20 26 26 20 69 4f  ger->nTree && iO
7a10: 75 74 3e 30 20 29 3b 0a 0a 20 20 69 66 28 20 69  ut>0 );..  if( i
7a20: 4f 75 74 3e 3d 28 70 4d 65 72 67 65 72 2d 3e 6e  Out>=(pMerger->n
7a30: 54 72 65 65 2f 32 29 20 29 7b 0a 20 20 20 20 69  Tree/2) ){.    i
7a40: 31 20 3d 20 28 69 4f 75 74 20 2d 20 70 4d 65 72  1 = (iOut - pMer
7a50: 67 65 72 2d 3e 6e 54 72 65 65 2f 32 29 20 2a 20  ger->nTree/2) * 
7a60: 32 3b 0a 20 20 20 20 69 32 20 3d 20 69 31 20 2b  2;.    i2 = i1 +
7a70: 20 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20   1;.  }else{.   
7a80: 20 69 31 20 3d 20 70 4d 65 72 67 65 72 2d 3e 61   i1 = pMerger->a
7a90: 54 72 65 65 5b 69 4f 75 74 2a 32 5d 3b 0a 20 20  Tree[iOut*2];.  
7aa0: 20 20 69 32 20 3d 20 70 4d 65 72 67 65 72 2d 3e    i2 = pMerger->
7ab0: 61 54 72 65 65 5b 69 4f 75 74 2a 32 2b 31 5d 3b  aTree[iOut*2+1];
7ac0: 0a 20 20 7d 0a 0a 20 20 70 31 20 3d 20 26 70 4d  .  }..  p1 = &pM
7ad0: 65 72 67 65 72 2d 3e 61 52 65 61 64 72 5b 69 31  erger->aReadr[i1
7ae0: 5d 3b 0a 20 20 70 32 20 3d 20 26 70 4d 65 72 67  ];.  p2 = &pMerg
7af0: 65 72 2d 3e 61 52 65 61 64 72 5b 69 32 5d 3b 0a  er->aReadr[i2];.
7b00: 0a 20 20 69 66 28 20 70 31 2d 3e 70 46 69 6c 65  .  if( p1->pFile
7b10: 3d 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 73 20  ==0 ){.    iRes 
7b20: 3d 20 69 32 3b 0a 20 20 7d 65 6c 73 65 20 69 66  = i2;.  }else if
7b30: 28 20 70 32 2d 3e 70 46 69 6c 65 3d 3d 30 20 29  ( p2->pFile==0 )
7b40: 7b 0a 20 20 20 20 69 52 65 73 20 3d 20 69 31 3b  {.    iRes = i1;
7b50: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e  .  }else{.    in
7b60: 74 20 72 65 73 3b 0a 20 20 20 20 61 73 73 65 72  t res;.    asser
7b70: 74 28 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63  t( pTask->pUnpac
7b80: 6b 65 64 21 3d 30 20 29 3b 20 20 2f 2a 20 61 6c  ked!=0 );  /* al
7b90: 6c 6f 63 61 74 65 64 20 69 6e 20 76 64 62 65 53  located in vdbeS
7ba0: 6f 72 74 53 75 62 74 61 73 6b 4d 61 69 6e 28 29  ortSubtaskMain()
7bb0: 20 2a 2f 0a 20 20 20 20 72 65 73 20 3d 20 76 64   */.    res = vd
7bc0: 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28  beSorterCompare(
7bd0: 0a 20 20 20 20 20 20 20 20 70 54 61 73 6b 2c 20  .        pTask, 
7be0: 70 31 2d 3e 61 4b 65 79 2c 20 70 31 2d 3e 6e 4b  p1->aKey, p1->nK
7bf0: 65 79 2c 20 70 32 2d 3e 61 4b 65 79 2c 20 70 32  ey, p2->aKey, p2
7c00: 2d 3e 6e 4b 65 79 0a 20 20 20 20 29 3b 0a 20 20  ->nKey.    );.  
7c10: 20 20 69 66 28 20 72 65 73 3c 3d 30 20 29 7b 0a    if( res<=0 ){.
7c20: 20 20 20 20 20 20 69 52 65 73 20 3d 20 69 31 3b        iRes = i1;
7c30: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
7c40: 20 20 69 52 65 73 20 3d 20 69 32 3b 0a 20 20 20    iRes = i2;.   
7c50: 20 7d 0a 20 20 7d 0a 0a 20 20 70 4d 65 72 67 65   }.  }..  pMerge
7c60: 72 2d 3e 61 54 72 65 65 5b 69 4f 75 74 5d 20 3d  r->aTree[iOut] =
7c70: 20 69 52 65 73 3b 0a 20 20 72 65 74 75 72 6e 20   iRes;.  return 
7c80: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
7c90: 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 74  .** Initialize t
7ca0: 68 65 20 74 65 6d 70 6f 72 61 72 79 20 69 6e 64  he temporary ind
7cb0: 65 78 20 63 75 72 73 6f 72 20 6a 75 73 74 20 6f  ex cursor just o
7cc0: 70 65 6e 65 64 20 61 73 20 61 20 73 6f 72 74 65  pened as a sorte
7cd0: 72 20 63 75 72 73 6f 72 2e 0a 2a 2a 0a 2a 2a 20  r cursor..**.** 
7ce0: 55 73 75 61 6c 6c 79 2c 20 74 68 65 20 73 6f 72  Usually, the sor
7cf0: 74 65 72 20 6d 6f 64 75 6c 65 20 75 73 65 73 20  ter module uses 
7d00: 74 68 65 20 76 61 6c 75 65 20 6f 66 20 28 70 43  the value of (pC
7d10: 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46  sr->pKeyInfo->nF
7d20: 69 65 6c 64 29 0a 2a 2a 20 74 6f 20 64 65 74 65  ield).** to dete
7d30: 72 6d 69 6e 65 20 74 68 65 20 6e 75 6d 62 65 72  rmine the number
7d40: 20 6f 66 20 66 69 65 6c 64 73 20 74 68 61 74 20   of fields that 
7d50: 73 68 6f 75 6c 64 20 62 65 20 63 6f 6d 70 61 72  should be compar
7d60: 65 64 20 66 72 6f 6d 20 74 68 65 0a 2a 2a 20 72  ed from the.** r
7d70: 65 63 6f 72 64 73 20 62 65 69 6e 67 20 73 6f 72  ecords being sor
7d80: 74 65 64 2e 20 48 6f 77 65 76 65 72 2c 20 69 66  ted. However, if
7d90: 20 74 68 65 20 76 61 6c 75 65 20 70 61 73 73 65   the value passe
7da0: 64 20 61 73 20 61 72 67 75 6d 65 6e 74 20 6e 46  d as argument nF
7db0: 69 65 6c 64 0a 2a 2a 20 69 73 20 6e 6f 6e 2d 7a  ield.** is non-z
7dc0: 65 72 6f 20 61 6e 64 20 74 68 65 20 73 6f 72 74  ero and the sort
7dd0: 65 72 20 69 73 20 61 62 6c 65 20 74 6f 20 67 75  er is able to gu
7de0: 61 72 61 6e 74 65 65 20 61 20 73 74 61 62 6c 65  arantee a stable
7df0: 20 73 6f 72 74 2c 20 6e 46 69 65 6c 64 0a 2a 2a   sort, nField.**
7e00: 20 69 73 20 75 73 65 64 20 69 6e 73 74 65 61 64   is used instead
7e10: 2e 20 54 68 69 73 20 69 73 20 75 73 65 64 20 77  . This is used w
7e20: 68 65 6e 20 73 6f 72 74 69 6e 67 20 72 65 63 6f  hen sorting reco
7e30: 72 64 73 20 66 6f 72 20 61 20 43 52 45 41 54 45  rds for a CREATE
7e40: 20 49 4e 44 45 58 0a 2a 2a 20 73 74 61 74 65 6d   INDEX.** statem
7e50: 65 6e 74 2e 20 49 6e 20 74 68 69 73 20 63 61 73  ent. In this cas
7e60: 65 2c 20 6b 65 79 73 20 61 72 65 20 61 6c 77 61  e, keys are alwa
7e70: 79 73 20 64 65 6c 69 76 65 72 65 64 20 74 6f 20  ys delivered to 
7e80: 74 68 65 20 73 6f 72 74 65 72 20 69 6e 0a 2a 2a  the sorter in.**
7e90: 20 6f 72 64 65 72 20 6f 66 20 74 68 65 20 70 72   order of the pr
7ea0: 69 6d 61 72 79 20 6b 65 79 2c 20 77 68 69 63 68  imary key, which
7eb0: 20 68 61 70 70 65 6e 73 20 74 6f 20 62 65 20 6d   happens to be m
7ec0: 61 6b 65 20 75 70 20 74 68 65 20 66 69 6e 61 6c  ake up the final
7ed0: 20 70 61 72 74 20 0a 2a 2a 20 6f 66 20 74 68 65   part .** of the
7ee0: 20 72 65 63 6f 72 64 73 20 62 65 69 6e 67 20 73   records being s
7ef0: 6f 72 74 65 64 2e 20 53 6f 20 69 66 20 74 68 65  orted. So if the
7f00: 20 73 6f 72 74 20 69 73 20 73 74 61 62 6c 65 2c   sort is stable,
7f10: 20 74 68 65 72 65 20 69 73 20 6e 65 76 65 72 0a   there is never.
7f20: 2a 2a 20 61 6e 79 20 72 65 61 73 6f 6e 20 74 6f  ** any reason to
7f30: 20 63 6f 6d 70 61 72 65 20 50 4b 20 66 69 65 6c   compare PK fiel
7f40: 64 73 20 61 6e 64 20 74 68 65 79 20 63 61 6e 20  ds and they can 
7f50: 62 65 20 69 67 6e 6f 72 65 64 20 66 6f 72 20 61  be ignored for a
7f60: 20 73 6d 61 6c 6c 0a 2a 2a 20 70 65 72 66 6f 72   small.** perfor
7f70: 6d 61 6e 63 65 20 62 6f 6f 73 74 2e 0a 2a 2a 0a  mance boost..**.
7f80: 2a 2a 20 54 68 65 20 73 6f 72 74 65 72 20 63 61  ** The sorter ca
7f90: 6e 20 67 75 61 72 61 6e 74 65 65 20 61 20 73 74  n guarantee a st
7fa0: 61 62 6c 65 20 73 6f 72 74 20 77 68 65 6e 20 72  able sort when r
7fb0: 75 6e 6e 69 6e 67 20 69 6e 20 73 69 6e 67 6c 65  unning in single
7fc0: 2d 74 68 72 65 61 64 65 64 0a 2a 2a 20 6d 6f 64  -threaded.** mod
7fd0: 65 2c 20 62 75 74 20 6e 6f 74 20 69 6e 20 6d 75  e, but not in mu
7fe0: 6c 74 69 2d 74 68 72 65 61 64 65 64 20 6d 6f 64  lti-threaded mod
7ff0: 65 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f  e..**.** SQLITE_
8000: 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 69  OK is returned i
8010: 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72  f successful, or
8020: 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
8030: 20 63 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e   code otherwise.
8040: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56  .*/.int sqlite3V
8050: 64 62 65 53 6f 72 74 65 72 49 6e 69 74 28 0a 20  dbeSorterInit(. 
8060: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20   sqlite3 *db,   
8070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8080: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 63 6f 6e   /* Database con
8090: 6e 65 63 74 69 6f 6e 20 28 66 6f 72 20 6d 61 6c  nection (for mal
80a0: 6c 6f 63 28 29 29 20 2a 2f 0a 20 20 69 6e 74 20  loc()) */.  int 
80b0: 6e 46 69 65 6c 64 2c 20 20 20 20 20 20 20 20 20  nField,         
80c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
80d0: 75 6d 62 65 72 20 6f 66 20 6b 65 79 20 66 69 65  umber of key fie
80e0: 6c 64 73 20 69 6e 20 65 61 63 68 20 72 65 63 6f  lds in each reco
80f0: 72 64 20 2a 2f 0a 20 20 56 64 62 65 43 75 72 73  rd */.  VdbeCurs
8100: 6f 72 20 2a 70 43 73 72 20 20 20 20 20 20 20 20  or *pCsr        
8110: 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 73 6f          /* Curso
8120: 72 20 74 68 61 74 20 68 6f 6c 64 73 20 74 68 65  r that holds the
8130: 20 6e 65 77 20 73 6f 72 74 65 72 20 2a 2f 0a 29   new sorter */.)
8140: 7b 0a 20 20 69 6e 74 20 70 67 73 7a 3b 20 20 20  {.  int pgsz;   
8150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8160: 20 20 20 20 2f 2a 20 50 61 67 65 20 73 69 7a 65      /* Page size
8170: 20 6f 66 20 6d 61 69 6e 20 64 61 74 61 62 61 73   of main databas
8180: 65 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20  e */.  int i;   
8190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
81a0: 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74         /* Used t
81b0: 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67  o iterate throug
81c0: 68 20 61 54 61 73 6b 5b 5d 20 2a 2f 0a 20 20 69  h aTask[] */.  i
81d0: 6e 74 20 6d 78 43 61 63 68 65 3b 20 20 20 20 20  nt mxCache;     
81e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
81f0: 2a 20 43 61 63 68 65 20 73 69 7a 65 20 2a 2f 0a  * Cache size */.
8200: 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
8210: 6f 72 74 65 72 3b 20 20 20 20 20 20 20 20 20 20  orter;          
8220: 20 20 2f 2a 20 54 68 65 20 6e 65 77 20 73 6f 72    /* The new sor
8230: 74 65 72 20 2a 2f 0a 20 20 4b 65 79 49 6e 66 6f  ter */.  KeyInfo
8240: 20 2a 70 4b 65 79 49 6e 66 6f 3b 20 20 20 20 20   *pKeyInfo;     
8250: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 70 79           /* Copy
8260: 20 6f 66 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e   of pCsr->pKeyIn
8270: 66 6f 20 77 69 74 68 20 64 62 3d 3d 30 20 2a 2f  fo with db==0 */
8280: 0a 20 20 69 6e 74 20 73 7a 4b 65 79 49 6e 66 6f  .  int szKeyInfo
8290: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
82a0: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 70 43     /* Size of pC
82b0: 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 20 69 6e 20  sr->pKeyInfo in 
82c0: 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20 73  bytes */.  int s
82d0: 7a 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  z;              
82e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
82f0: 7a 65 20 6f 66 20 70 53 6f 72 74 65 72 20 69 6e  ze of pSorter in
8300: 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20   bytes */.  int 
8310: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
8320: 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57  #if SQLITE_MAX_W
8330: 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3d 3d 30  ORKER_THREADS==0
8340: 0a 23 20 64 65 66 69 6e 65 20 6e 57 6f 72 6b 65  .# define nWorke
8350: 72 20 30 0a 23 65 6c 73 65 0a 20 20 69 6e 74 20  r 0.#else.  int 
8360: 6e 57 6f 72 6b 65 72 20 3d 20 28 73 71 6c 69 74  nWorker = (sqlit
8370: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62  e3GlobalConfig.b
8380: 43 6f 72 65 4d 75 74 65 78 3f 73 71 6c 69 74 65  CoreMutex?sqlite
8390: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 6e 57  3GlobalConfig.nW
83a0: 6f 72 6b 65 72 3a 30 29 3b 0a 23 65 6e 64 69 66  orker:0);.#endif
83b0: 0a 0a 20 20 61 73 73 65 72 74 28 20 70 43 73 72  ..  assert( pCsr
83c0: 2d 3e 70 4b 65 79 49 6e 66 6f 20 26 26 20 70 43  ->pKeyInfo && pC
83d0: 73 72 2d 3e 70 42 74 3d 3d 30 20 29 3b 0a 20 20  sr->pBt==0 );.  
83e0: 73 7a 4b 65 79 49 6e 66 6f 20 3d 20 73 69 7a 65  szKeyInfo = size
83f0: 6f 66 28 4b 65 79 49 6e 66 6f 29 20 2b 20 28 70  of(KeyInfo) + (p
8400: 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2d 3e 6e  Csr->pKeyInfo->n
8410: 46 69 65 6c 64 2d 31 29 2a 73 69 7a 65 6f 66 28  Field-1)*sizeof(
8420: 43 6f 6c 6c 53 65 71 2a 29 3b 0a 20 20 73 7a 20  CollSeq*);.  sz 
8430: 3d 20 73 69 7a 65 6f 66 28 56 64 62 65 53 6f 72  = sizeof(VdbeSor
8440: 74 65 72 29 20 2b 20 6e 57 6f 72 6b 65 72 20 2a  ter) + nWorker *
8450: 20 73 69 7a 65 6f 66 28 53 6f 72 74 53 75 62 74   sizeof(SortSubt
8460: 61 73 6b 29 3b 0a 0a 20 20 70 53 6f 72 74 65 72  ask);..  pSorter
8470: 20 3d 20 28 56 64 62 65 53 6f 72 74 65 72 2a 29   = (VdbeSorter*)
8480: 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f 63 5a  sqlite3DbMallocZ
8490: 65 72 6f 28 64 62 2c 20 73 7a 20 2b 20 73 7a 4b  ero(db, sz + szK
84a0: 65 79 49 6e 66 6f 29 3b 0a 20 20 70 43 73 72 2d  eyInfo);.  pCsr-
84b0: 3e 70 53 6f 72 74 65 72 20 3d 20 70 53 6f 72 74  >pSorter = pSort
84c0: 65 72 3b 0a 20 20 69 66 28 20 70 53 6f 72 74 65  er;.  if( pSorte
84d0: 72 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d  r==0 ){.    rc =
84e0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
84f0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 53 6f 72   }else{.    pSor
8500: 74 65 72 2d 3e 70 4b 65 79 49 6e 66 6f 20 3d 20  ter->pKeyInfo = 
8510: 70 4b 65 79 49 6e 66 6f 20 3d 20 28 4b 65 79 49  pKeyInfo = (KeyI
8520: 6e 66 6f 2a 29 28 28 75 38 2a 29 70 53 6f 72 74  nfo*)((u8*)pSort
8530: 65 72 20 2b 20 73 7a 29 3b 0a 20 20 20 20 6d 65  er + sz);.    me
8540: 6d 63 70 79 28 70 4b 65 79 49 6e 66 6f 2c 20 70  mcpy(pKeyInfo, p
8550: 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20 73  Csr->pKeyInfo, s
8560: 7a 4b 65 79 49 6e 66 6f 29 3b 0a 20 20 20 20 70  zKeyInfo);.    p
8570: 4b 65 79 49 6e 66 6f 2d 3e 64 62 20 3d 20 30 3b  KeyInfo->db = 0;
8580: 0a 20 20 20 20 69 66 28 20 6e 46 69 65 6c 64 20  .    if( nField 
8590: 26 26 20 6e 57 6f 72 6b 65 72 3d 3d 30 20 29 20  && nWorker==0 ) 
85a0: 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64  pKeyInfo->nField
85b0: 20 3d 20 6e 46 69 65 6c 64 3b 0a 20 20 20 20 70   = nField;.    p
85c0: 53 6f 72 74 65 72 2d 3e 70 67 73 7a 20 3d 20 70  Sorter->pgsz = p
85d0: 67 73 7a 20 3d 20 73 71 6c 69 74 65 33 42 74 72  gsz = sqlite3Btr
85e0: 65 65 47 65 74 50 61 67 65 53 69 7a 65 28 64 62  eeGetPageSize(db
85f0: 2d 3e 61 44 62 5b 30 5d 2e 70 42 74 29 3b 0a 20  ->aDb[0].pBt);. 
8600: 20 20 20 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73     pSorter->nTas
8610: 6b 20 3d 20 6e 57 6f 72 6b 65 72 20 2b 20 31 3b  k = nWorker + 1;
8620: 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 62 55  .    pSorter->bU
8630: 73 65 54 68 72 65 61 64 73 20 3d 20 28 70 53 6f  seThreads = (pSo
8640: 72 74 65 72 2d 3e 6e 54 61 73 6b 3e 31 29 3b 0a  rter->nTask>1);.
8650: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 64 62 20      pSorter->db 
8660: 3d 20 64 62 3b 0a 20 20 20 20 66 6f 72 28 69 3d  = db;.    for(i=
8670: 30 3b 20 69 3c 70 53 6f 72 74 65 72 2d 3e 6e 54  0; i<pSorter->nT
8680: 61 73 6b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  ask; i++){.     
8690: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
86a0: 61 73 6b 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e  ask = &pSorter->
86b0: 61 54 61 73 6b 5b 69 5d 3b 0a 20 20 20 20 20 20  aTask[i];.      
86c0: 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 20 3d  pTask->pSorter =
86d0: 20 70 53 6f 72 74 65 72 3b 0a 20 20 20 20 7d 0a   pSorter;.    }.
86e0: 0a 20 20 20 20 69 66 28 20 21 73 71 6c 69 74 65  .    if( !sqlite
86f0: 33 54 65 6d 70 49 6e 4d 65 6d 6f 72 79 28 64 62  3TempInMemory(db
8700: 29 20 29 7b 0a 20 20 20 20 20 20 70 53 6f 72 74  ) ){.      pSort
8710: 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a 65 20 3d 20  er->mnPmaSize = 
8720: 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49  SORTER_MIN_WORKI
8730: 4e 47 20 2a 20 70 67 73 7a 3b 0a 20 20 20 20 20  NG * pgsz;.     
8740: 20 6d 78 43 61 63 68 65 20 3d 20 64 62 2d 3e 61   mxCache = db->a
8750: 44 62 5b 30 5d 2e 70 53 63 68 65 6d 61 2d 3e 63  Db[0].pSchema->c
8760: 61 63 68 65 5f 73 69 7a 65 3b 0a 20 20 20 20 20  ache_size;.     
8770: 20 69 66 28 20 6d 78 43 61 63 68 65 3c 53 4f 52   if( mxCache<SOR
8780: 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20  TER_MIN_WORKING 
8790: 29 20 6d 78 43 61 63 68 65 20 3d 20 53 4f 52 54  ) mxCache = SORT
87a0: 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 3b 0a  ER_MIN_WORKING;.
87b0: 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6d        pSorter->m
87c0: 78 50 6d 61 53 69 7a 65 20 3d 20 6d 78 43 61 63  xPmaSize = mxCac
87d0: 68 65 20 2a 20 70 67 73 7a 3b 0a 0a 20 20 20 20  he * pgsz;..    
87e0: 20 20 2f 2a 20 49 66 20 74 68 65 20 61 70 70 6c    /* If the appl
87f0: 69 63 61 74 69 6f 6e 20 68 61 73 20 6e 6f 74 20  ication has not 
8800: 63 6f 6e 66 69 67 75 72 65 20 73 63 72 61 74 63  configure scratc
8810: 68 20 6d 65 6d 6f 72 79 20 75 73 69 6e 67 0a 20  h memory using. 
8820: 20 20 20 20 20 2a 2a 20 53 51 4c 49 54 45 5f 43       ** SQLITE_C
8830: 4f 4e 46 49 47 5f 53 43 52 41 54 43 48 20 74 68  ONFIG_SCRATCH th
8840: 65 6e 20 77 65 20 61 73 73 75 6d 65 20 69 74 20  en we assume it 
8850: 69 73 20 4f 4b 20 74 6f 20 64 6f 20 6c 61 72 67  is OK to do larg
8860: 65 20 6d 65 6d 6f 72 79 0a 20 20 20 20 20 20 2a  e memory.      *
8870: 2a 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 2e 20 20  * allocations.  
8880: 49 66 20 73 63 72 61 74 63 68 20 6d 65 6d 6f 72  If scratch memor
8890: 79 20 68 61 73 20 62 65 65 6e 20 63 6f 6e 66 69  y has been confi
88a0: 67 75 72 65 64 2c 20 74 68 65 6e 20 61 73 73 75  gured, then assu
88b0: 6d 65 0a 20 20 20 20 20 20 2a 2a 20 6c 61 72 67  me.      ** larg
88c0: 65 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74  e memory allocat
88d0: 69 6f 6e 73 20 73 68 6f 75 6c 64 20 62 65 20 61  ions should be a
88e0: 76 6f 69 64 65 64 20 74 6f 20 70 72 65 76 65 6e  voided to preven
88f0: 74 20 68 65 61 70 0a 20 20 20 20 20 20 2a 2a 20  t heap.      ** 
8900: 66 72 61 67 6d 65 6e 74 61 74 69 6f 6e 2e 0a 20  fragmentation.. 
8910: 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 69 66       */.      if
8920: 28 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43  ( sqlite3GlobalC
8930: 6f 6e 66 69 67 2e 70 53 63 72 61 74 63 68 3d 3d  onfig.pScratch==
8940: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 61 73 73  0 ){.        ass
8950: 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 69 4d  ert( pSorter->iM
8960: 65 6d 6f 72 79 3d 3d 30 20 29 3b 0a 20 20 20 20  emory==0 );.    
8970: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6e 4d 65      pSorter->nMe
8980: 6d 6f 72 79 20 3d 20 70 67 73 7a 3b 0a 20 20 20  mory = pgsz;.   
8990: 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69       pSorter->li
89a0: 73 74 2e 61 4d 65 6d 6f 72 79 20 3d 20 28 75 38  st.aMemory = (u8
89b0: 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28  *)sqlite3Malloc(
89c0: 70 67 73 7a 29 3b 0a 20 20 20 20 20 20 20 20 69  pgsz);.        i
89d0: 66 28 20 21 70 53 6f 72 74 65 72 2d 3e 6c 69 73  f( !pSorter->lis
89e0: 74 2e 61 4d 65 6d 6f 72 79 20 29 20 72 63 20 3d  t.aMemory ) rc =
89f0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
8a00: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
8a10: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
8a20: 0a 23 75 6e 64 65 66 20 6e 57 6f 72 6b 65 72 20  .#undef nWorker 
8a30: 20 20 2f 2a 20 44 65 66 69 6e 65 64 20 61 74 20    /* Defined at 
8a40: 74 68 65 20 74 6f 70 20 6f 66 20 74 68 69 73 20  the top of this 
8a50: 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 0a 2f 2a 0a  function */../*.
8a60: 2a 2a 20 46 72 65 65 20 74 68 65 20 6c 69 73 74  ** Free the list
8a70: 20 6f 66 20 73 6f 72 74 65 64 20 72 65 63 6f 72   of sorted recor
8a80: 64 73 20 73 74 61 72 74 69 6e 67 20 61 74 20 70  ds starting at p
8a90: 52 65 63 6f 72 64 2e 0a 2a 2f 0a 73 74 61 74 69  Record..*/.stati
8aa0: 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65  c void vdbeSorte
8ab0: 72 52 65 63 6f 72 64 46 72 65 65 28 73 71 6c 69  rRecordFree(sqli
8ac0: 74 65 33 20 2a 64 62 2c 20 53 6f 72 74 65 72 52  te3 *db, SorterR
8ad0: 65 63 6f 72 64 20 2a 70 52 65 63 6f 72 64 29 7b  ecord *pRecord){
8ae0: 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20  .  SorterRecord 
8af0: 2a 70 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f  *p;.  SorterReco
8b00: 72 64 20 2a 70 4e 65 78 74 3b 0a 20 20 66 6f 72  rd *pNext;.  for
8b10: 28 70 3d 70 52 65 63 6f 72 64 3b 20 70 3b 20 70  (p=pRecord; p; p
8b20: 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 4e 65  =pNext){.    pNe
8b30: 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74 3b  xt = p->u.pNext;
8b40: 0a 20 20 20 20 73 71 6c 69 74 65 33 44 62 46 72  .    sqlite3DbFr
8b50: 65 65 28 64 62 2c 20 70 29 3b 0a 20 20 7d 0a 7d  ee(db, p);.  }.}
8b60: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6c 6c  ../*.** Free all
8b70: 20 72 65 73 6f 75 72 63 65 73 20 6f 77 6e 65 64   resources owned
8b80: 20 62 79 20 74 68 65 20 6f 62 6a 65 63 74 20 69   by the object i
8b90: 6e 64 69 63 61 74 65 64 20 62 79 20 61 72 67 75  ndicated by argu
8ba0: 6d 65 6e 74 20 70 54 61 73 6b 2e 20 41 6c 6c 20  ment pTask. All 
8bb0: 0a 2a 2a 20 66 69 65 6c 64 73 20 6f 66 20 2a 70  .** fields of *p
8bc0: 54 61 73 6b 20 61 72 65 20 7a 65 72 6f 65 64 20  Task are zeroed 
8bd0: 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  before returning
8be0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
8bf0: 20 76 64 62 65 53 6f 72 74 53 75 62 74 61 73 6b   vdbeSortSubtask
8c00: 43 6c 65 61 6e 75 70 28 73 71 6c 69 74 65 33 20  Cleanup(sqlite3 
8c10: 2a 64 62 2c 20 53 6f 72 74 53 75 62 74 61 73 6b  *db, SortSubtask
8c20: 20 2a 70 54 61 73 6b 29 7b 0a 20 20 73 71 6c 69   *pTask){.  sqli
8c30: 74 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 54  te3DbFree(db, pT
8c40: 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 29 3b  ask->pUnpacked);
8c50: 0a 20 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63  .  pTask->pUnpac
8c60: 6b 65 64 20 3d 20 30 3b 0a 23 69 66 20 53 51 4c  ked = 0;.#if SQL
8c70: 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54  ITE_MAX_WORKER_T
8c80: 48 52 45 41 44 53 3e 30 0a 20 20 2f 2a 20 70 54  HREADS>0.  /* pT
8c90: 61 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72  ask->list.aMemor
8ca0: 79 20 63 61 6e 20 6f 6e 6c 79 20 62 65 20 6e 6f  y can only be no
8cb0: 6e 2d 7a 65 72 6f 20 69 66 20 69 74 20 77 61 73  n-zero if it was
8cc0: 20 68 61 6e 64 65 64 20 6d 65 6d 6f 72 79 0a 20   handed memory. 
8cd0: 20 2a 2a 20 66 72 6f 6d 20 74 68 65 20 6d 61 69   ** from the mai
8ce0: 6e 20 74 68 72 65 61 64 2e 20 20 54 68 61 74 20  n thread.  That 
8cf0: 6f 6e 6c 79 20 6f 63 63 75 72 73 20 53 51 4c 49  only occurs 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 20 2a 2f 0a 20 20 69 66 28  READS>0 */.  if(
8d20: 20 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65   pTask->list.aMe
8d30: 6d 6f 72 79 20 29 7b 0a 20 20 20 20 73 71 6c 69  mory ){.    sqli
8d40: 74 65 33 5f 66 72 65 65 28 70 54 61 73 6b 2d 3e  te3_free(pTask->
8d50: 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 29 3b 0a 20  list.aMemory);. 
8d60: 20 20 20 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 61     pTask->list.a
8d70: 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a 20 20 7d 65  Memory = 0;.  }e
8d80: 6c 73 65 0a 23 65 6e 64 69 66 0a 20 20 7b 0a 20  lse.#endif.  {. 
8d90: 20 20 20 61 73 73 65 72 74 28 20 70 54 61 73 6b     assert( pTask
8da0: 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d  ->list.aMemory==
8db0: 30 20 29 3b 0a 20 20 20 20 76 64 62 65 53 6f 72  0 );.    vdbeSor
8dc0: 74 65 72 52 65 63 6f 72 64 46 72 65 65 28 30 2c  terRecordFree(0,
8dd0: 20 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 70 4c 69   pTask->list.pLi
8de0: 73 74 29 3b 0a 20 20 7d 0a 20 20 70 54 61 73 6b  st);.  }.  pTask
8df0: 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d 20 30  ->list.pList = 0
8e00: 3b 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 66  ;.  if( pTask->f
8e10: 69 6c 65 2e 70 46 64 20 29 7b 0a 20 20 20 20 73  ile.pFd ){.    s
8e20: 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 46 72 65  qlite3OsCloseFre
8e30: 65 28 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46  e(pTask->file.pF
8e40: 64 29 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 66  d);.    pTask->f
8e50: 69 6c 65 2e 70 46 64 20 3d 20 30 3b 0a 20 20 20  ile.pFd = 0;.   
8e60: 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f   pTask->file.iEo
8e70: 66 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 69 66 28  f = 0;.  }.  if(
8e80: 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46   pTask->file2.pF
8e90: 64 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  d ){.    sqlite3
8ea0: 4f 73 43 6c 6f 73 65 46 72 65 65 28 70 54 61 73  OsCloseFree(pTas
8eb0: 6b 2d 3e 66 69 6c 65 32 2e 70 46 64 29 3b 0a 20  k->file2.pFd);. 
8ec0: 20 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e     pTask->file2.
8ed0: 70 46 64 20 3d 20 30 3b 0a 20 20 20 20 70 54 61  pFd = 0;.    pTa
8ee0: 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 20 3d  sk->file2.iEof =
8ef0: 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 23 69 66 64 65   0;.  }.}..#ifde
8f00: 66 20 53 51 4c 49 54 45 5f 44 45 42 55 47 5f 53  f SQLITE_DEBUG_S
8f10: 4f 52 54 45 52 5f 54 48 52 45 41 44 53 0a 73 74  ORTER_THREADS.st
8f20: 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f  atic void vdbeSo
8f30: 72 74 65 72 57 6f 72 6b 44 65 62 75 67 28 53 6f  rterWorkDebug(So
8f40: 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b  rtSubtask *pTask
8f50: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45  , const char *zE
8f60: 76 65 6e 74 29 7b 0a 20 20 69 36 34 20 74 3b 0a  vent){.  i64 t;.
8f70: 20 20 69 6e 74 20 69 54 61 73 6b 20 3d 20 28 70    int iTask = (p
8f80: 54 61 73 6b 20 2d 20 70 54 61 73 6b 2d 3e 70 53  Task - pTask->pS
8f90: 6f 72 74 65 72 2d 3e 61 54 61 73 6b 29 3b 0a 20  orter->aTask);. 
8fa0: 20 73 71 6c 69 74 65 33 4f 73 43 75 72 72 65 6e   sqlite3OsCurren
8fb0: 74 54 69 6d 65 49 6e 74 36 34 28 70 54 61 73 6b  tTimeInt64(pTask
8fc0: 2d 3e 70 53 6f 72 74 65 72 2d 3e 64 62 2d 3e 70  ->pSorter->db->p
8fd0: 56 66 73 2c 20 26 74 29 3b 0a 20 20 66 70 72 69  Vfs, &t);.  fpri
8fe0: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25 6c 6c  ntf(stderr, "%ll
8ff0: 64 3a 25 64 20 25 73 5c 6e 22 2c 20 74 2c 20 69  d:%d %s\n", t, i
9000: 54 61 73 6b 2c 20 7a 45 76 65 6e 74 29 3b 0a 7d  Task, zEvent);.}
9010: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62  .static void vdb
9020: 65 53 6f 72 74 65 72 52 65 77 69 6e 64 44 65 62  eSorterRewindDeb
9030: 75 67 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  ug(const char *z
9040: 45 76 65 6e 74 29 7b 0a 20 20 69 36 34 20 74 3b  Event){.  i64 t;
9050: 0a 20 20 73 71 6c 69 74 65 33 4f 73 43 75 72 72  .  sqlite3OsCurr
9060: 65 6e 74 54 69 6d 65 49 6e 74 36 34 28 73 71 6c  entTimeInt64(sql
9070: 69 74 65 33 5f 76 66 73 5f 66 69 6e 64 28 30 29  ite3_vfs_find(0)
9080: 2c 20 26 74 29 3b 0a 20 20 66 70 72 69 6e 74 66  , &t);.  fprintf
9090: 28 73 74 64 65 72 72 2c 20 22 25 6c 6c 64 3a 58  (stderr, "%lld:X
90a0: 20 25 73 5c 6e 22 2c 20 74 2c 20 7a 45 76 65 6e   %s\n", t, zEven
90b0: 74 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69  t);.}.static voi
90c0: 64 20 76 64 62 65 53 6f 72 74 65 72 50 6f 70 75  d vdbeSorterPopu
90d0: 6c 61 74 65 44 65 62 75 67 28 0a 20 20 53 6f 72  lateDebug(.  Sor
90e0: 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c  tSubtask *pTask,
90f0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
9100: 45 76 65 6e 74 0a 29 7b 0a 20 20 69 36 34 20 74  Event.){.  i64 t
9110: 3b 0a 20 20 69 6e 74 20 69 54 61 73 6b 20 3d 20  ;.  int iTask = 
9120: 28 70 54 61 73 6b 20 2d 20 70 54 61 73 6b 2d 3e  (pTask - pTask->
9130: 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 29 3b  pSorter->aTask);
9140: 0a 20 20 73 71 6c 69 74 65 33 4f 73 43 75 72 72  .  sqlite3OsCurr
9150: 65 6e 74 54 69 6d 65 49 6e 74 36 34 28 70 54 61  entTimeInt64(pTa
9160: 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 64 62 2d  sk->pSorter->db-
9170: 3e 70 56 66 73 2c 20 26 74 29 3b 0a 20 20 66 70  >pVfs, &t);.  fp
9180: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25  rintf(stderr, "%
9190: 6c 6c 64 3a 62 67 25 64 20 25 73 5c 6e 22 2c 20  lld:bg%d %s\n", 
91a0: 74 2c 20 69 54 61 73 6b 2c 20 7a 45 76 65 6e 74  t, iTask, zEvent
91b0: 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64  );.}.static void
91c0: 20 76 64 62 65 53 6f 72 74 65 72 42 6c 6f 63 6b   vdbeSorterBlock
91d0: 44 65 62 75 67 28 0a 20 20 53 6f 72 74 53 75 62  Debug(.  SortSub
91e0: 74 61 73 6b 20 2a 70 54 61 73 6b 2c 0a 20 20 69  task *pTask,.  i
91f0: 6e 74 20 62 42 6c 6f 63 6b 65 64 2c 0a 20 20 63  nt bBlocked,.  c
9200: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45 76 65 6e  onst char *zEven
9210: 74 0a 29 7b 0a 20 20 69 66 28 20 62 42 6c 6f 63  t.){.  if( bBloc
9220: 6b 65 64 20 29 7b 0a 20 20 20 20 69 36 34 20 74  ked ){.    i64 t
9230: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43  ;.    sqlite3OsC
9240: 75 72 72 65 6e 74 54 69 6d 65 49 6e 74 36 34 28  urrentTimeInt64(
9250: 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e  pTask->pSorter->
9260: 64 62 2d 3e 70 56 66 73 2c 20 26 74 29 3b 0a 20  db->pVfs, &t);. 
9270: 20 20 20 66 70 72 69 6e 74 66 28 73 74 64 65 72     fprintf(stder
9280: 72 2c 20 22 25 6c 6c 64 3a 6d 61 69 6e 20 25 73  r, "%lld:main %s
9290: 5c 6e 22 2c 20 74 2c 20 7a 45 76 65 6e 74 29 3b  \n", t, zEvent);
92a0: 0a 20 20 7d 0a 7d 0a 23 65 6c 73 65 0a 23 20 64  .  }.}.#else.# d
92b0: 65 66 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72  efine vdbeSorter
92c0: 57 6f 72 6b 44 65 62 75 67 28 78 2c 79 29 0a 23  WorkDebug(x,y).#
92d0: 20 64 65 66 69 6e 65 20 76 64 62 65 53 6f 72 74   define vdbeSort
92e0: 65 72 52 65 77 69 6e 64 44 65 62 75 67 28 79 29  erRewindDebug(y)
92f0: 0a 23 20 64 65 66 69 6e 65 20 76 64 62 65 53 6f  .# define vdbeSo
9300: 72 74 65 72 50 6f 70 75 6c 61 74 65 44 65 62 75  rterPopulateDebu
9310: 67 28 78 2c 79 29 0a 23 20 64 65 66 69 6e 65 20  g(x,y).# define 
9320: 76 64 62 65 53 6f 72 74 65 72 42 6c 6f 63 6b 44  vdbeSorterBlockD
9330: 65 62 75 67 28 78 2c 79 2c 7a 29 0a 23 65 6e 64  ebug(x,y,z).#end
9340: 69 66 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d  if..#if SQLITE_M
9350: 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44  AX_WORKER_THREAD
9360: 53 3e 30 0a 2f 2a 0a 2a 2a 20 4a 6f 69 6e 20 74  S>0./*.** Join t
9370: 68 72 65 61 64 20 70 54 61 73 6b 2d 3e 74 68 72  hread pTask->thr
9380: 65 61 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ead..*/.static i
9390: 6e 74 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69  nt vdbeSorterJoi
93a0: 6e 54 68 72 65 61 64 28 53 6f 72 74 53 75 62 74  nThread(SortSubt
93b0: 61 73 6b 20 2a 70 54 61 73 6b 29 7b 0a 20 20 69  ask *pTask){.  i
93c0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
93d0: 4b 3b 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e  K;.  if( pTask->
93e0: 70 54 68 72 65 61 64 20 29 7b 0a 23 69 66 64 65  pThread ){.#ifde
93f0: 66 20 53 51 4c 49 54 45 5f 44 45 42 55 47 5f 53  f SQLITE_DEBUG_S
9400: 4f 52 54 45 52 5f 54 48 52 45 41 44 53 0a 20 20  ORTER_THREADS.  
9410: 20 20 69 6e 74 20 62 44 6f 6e 65 20 3d 20 70 54    int bDone = pT
9420: 61 73 6b 2d 3e 62 44 6f 6e 65 3b 0a 23 65 6e 64  ask->bDone;.#end
9430: 69 66 0a 20 20 20 20 76 6f 69 64 20 2a 70 52 65  if.    void *pRe
9440: 74 3b 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65  t;.    vdbeSorte
9450: 72 42 6c 6f 63 6b 44 65 62 75 67 28 70 54 61 73  rBlockDebug(pTas
9460: 6b 2c 20 21 62 44 6f 6e 65 2c 20 22 65 6e 74 65  k, !bDone, "ente
9470: 72 22 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71  r");.    rc = sq
9480: 6c 69 74 65 33 54 68 72 65 61 64 4a 6f 69 6e 28  lite3ThreadJoin(
9490: 70 54 61 73 6b 2d 3e 70 54 68 72 65 61 64 2c 20  pTask->pThread, 
94a0: 26 70 52 65 74 29 3b 0a 20 20 20 20 76 64 62 65  &pRet);.    vdbe
94b0: 53 6f 72 74 65 72 42 6c 6f 63 6b 44 65 62 75 67  SorterBlockDebug
94c0: 28 70 54 61 73 6b 2c 20 21 62 44 6f 6e 65 2c 20  (pTask, !bDone, 
94d0: 22 65 78 69 74 22 29 3b 0a 20 20 20 20 69 66 28  "exit");.    if(
94e0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
94f0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 50 54 52   rc = SQLITE_PTR
9500: 5f 54 4f 5f 49 4e 54 28 70 52 65 74 29 3b 0a 20  _TO_INT(pRet);. 
9510: 20 20 20 61 73 73 65 72 74 28 20 70 54 61 73 6b     assert( pTask
9520: 2d 3e 62 44 6f 6e 65 3d 3d 31 20 29 3b 0a 20 20  ->bDone==1 );.  
9530: 20 20 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 20 3d    pTask->bDone =
9540: 20 30 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 70   0;.    pTask->p
9550: 54 68 72 65 61 64 20 3d 20 30 3b 0a 20 20 7d 0a  Thread = 0;.  }.
9560: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
9570: 2f 2a 0a 2a 2a 20 4c 61 75 6e 63 68 20 61 20 62  /*.** Launch a b
9580: 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64  ackground thread
9590: 20 74 6f 20 72 75 6e 20 78 54 61 73 6b 28 70 49   to run xTask(pI
95a0: 6e 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  n)..*/.static in
95b0: 74 20 76 64 62 65 53 6f 72 74 65 72 43 72 65 61  t vdbeSorterCrea
95c0: 74 65 54 68 72 65 61 64 28 0a 20 20 53 6f 72 74  teThread(.  Sort
95d0: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20  Subtask *pTask, 
95e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
95f0: 68 72 65 61 64 20 77 69 6c 6c 20 75 73 65 20 74  hread will use t
9600: 68 69 73 20 74 61 73 6b 20 6f 62 6a 65 63 74 20  his task object 
9610: 2a 2f 0a 20 20 76 6f 69 64 20 2a 28 2a 78 54 61  */.  void *(*xTa
9620: 73 6b 29 28 76 6f 69 64 2a 29 2c 20 20 20 20 20  sk)(void*),     
9630: 20 20 20 20 20 2f 2a 20 52 6f 75 74 69 6e 65 20       /* Routine 
9640: 74 6f 20 72 75 6e 20 69 6e 20 61 20 73 65 70 61  to run in a sepa
9650: 72 61 74 65 20 74 68 72 65 61 64 20 2a 2f 0a 20  rate thread */. 
9660: 20 76 6f 69 64 20 2a 70 49 6e 20 20 20 20 20 20   void *pIn      
9670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9680: 20 2f 2a 20 41 72 67 75 6d 65 6e 74 20 70 61 73   /* Argument pas
9690: 73 65 64 20 69 6e 74 6f 20 78 54 61 73 6b 28 29  sed into xTask()
96a0: 20 2a 2f 0a 29 7b 0a 20 20 61 73 73 65 72 74 28   */.){.  assert(
96b0: 20 70 54 61 73 6b 2d 3e 70 54 68 72 65 61 64 3d   pTask->pThread=
96c0: 3d 30 20 26 26 20 70 54 61 73 6b 2d 3e 62 44 6f  =0 && pTask->bDo
96d0: 6e 65 3d 3d 30 20 29 3b 0a 20 20 72 65 74 75 72  ne==0 );.  retur
96e0: 6e 20 73 71 6c 69 74 65 33 54 68 72 65 61 64 43  n sqlite3ThreadC
96f0: 72 65 61 74 65 28 26 70 54 61 73 6b 2d 3e 70 54  reate(&pTask->pT
9700: 68 72 65 61 64 2c 20 78 54 61 73 6b 2c 20 70 49  hread, xTask, pI
9710: 6e 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4a 6f 69  n);.}../*.** Joi
9720: 6e 20 61 6c 6c 20 6f 75 74 73 74 61 6e 64 69 6e  n all outstandin
9730: 67 20 74 68 72 65 61 64 73 20 6c 61 75 6e 63 68  g threads launch
9740: 65 64 20 62 79 20 53 6f 72 74 65 72 57 72 69 74  ed by SorterWrit
9750: 65 28 29 20 74 6f 20 63 72 65 61 74 65 20 0a 2a  e() to create .*
9760: 2a 20 6c 65 76 65 6c 2d 30 20 50 4d 41 73 2e 0a  * level-0 PMAs..
9770: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
9780: 62 65 53 6f 72 74 65 72 4a 6f 69 6e 41 6c 6c 28  beSorterJoinAll(
9790: 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72  VdbeSorter *pSor
97a0: 74 65 72 2c 20 69 6e 74 20 72 63 69 6e 29 7b 0a  ter, int rcin){.
97b0: 20 20 69 6e 74 20 72 63 20 3d 20 72 63 69 6e 3b    int rc = rcin;
97c0: 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 2f 2a 20  .  int i;..  /* 
97d0: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
97e0: 20 61 6c 77 61 79 73 20 63 61 6c 6c 65 64 20 62   always called b
97f0: 79 20 74 68 65 20 6d 61 69 6e 20 75 73 65 72 20  y the main user 
9800: 74 68 72 65 61 64 2e 0a 20 20 2a 2a 0a 20 20 2a  thread..  **.  *
9810: 2a 20 49 66 20 74 68 69 73 20 66 75 6e 63 74 69  * If this functi
9820: 6f 6e 20 69 73 20 62 65 69 6e 67 20 63 61 6c 6c  on is being call
9830: 65 64 20 61 66 74 65 72 20 53 6f 72 74 65 72 52  ed after SorterR
9840: 65 77 69 6e 64 28 29 20 68 61 73 20 62 65 65 6e  ewind() has been
9850: 20 63 61 6c 6c 65 64 2c 20 0a 20 20 2a 2a 20 69   called, .  ** i
9860: 74 20 69 73 20 70 6f 73 73 69 62 6c 65 20 74 68  t is possible th
9870: 61 74 20 74 68 72 65 61 64 20 70 53 6f 72 74 65  at thread pSorte
9880: 72 2d 3e 61 54 61 73 6b 5b 70 53 6f 72 74 65 72  r->aTask[pSorter
9890: 2d 3e 6e 54 61 73 6b 2d 31 5d 2e 70 54 68 72 65  ->nTask-1].pThre
98a0: 61 64 0a 20 20 2a 2a 20 69 73 20 63 75 72 72 65  ad.  ** is curre
98b0: 6e 74 6c 79 20 61 74 74 65 6d 70 74 20 74 6f 20  ntly attempt to 
98c0: 6a 6f 69 6e 20 6f 6e 65 20 6f 66 20 74 68 65 20  join one of the 
98d0: 6f 74 68 65 72 20 74 68 72 65 61 64 73 2e 20 54  other threads. T
98e0: 6f 20 61 76 6f 69 64 20 61 20 72 61 63 65 0a 20  o avoid a race. 
98f0: 20 2a 2a 20 63 6f 6e 64 69 74 69 6f 6e 20 77 68   ** condition wh
9900: 65 72 65 20 74 68 69 73 20 74 68 72 65 61 64 20  ere this thread 
9910: 61 6c 73 6f 20 61 74 74 65 6d 70 74 73 20 74 6f  also attempts to
9920: 20 6a 6f 69 6e 20 74 68 65 20 73 61 6d 65 20 6f   join the same o
9930: 62 6a 65 63 74 2c 20 6a 6f 69 6e 20 0a 20 20 2a  bject, join .  *
9940: 2a 20 74 68 72 65 61 64 20 70 53 6f 72 74 65 72  * thread pSorter
9950: 2d 3e 61 54 61 73 6b 5b 70 53 6f 72 74 65 72 2d  ->aTask[pSorter-
9960: 3e 6e 54 61 73 6b 2d 31 5d 2e 70 54 68 72 65 61  >nTask-1].pThrea
9970: 64 20 66 69 72 73 74 2e 20 2a 2f 0a 20 20 66 6f  d first. */.  fo
9980: 72 28 69 3d 70 53 6f 72 74 65 72 2d 3e 6e 54 61  r(i=pSorter->nTa
9990: 73 6b 2d 31 3b 20 69 3e 3d 30 3b 20 69 2d 2d 29  sk-1; i>=0; i--)
99a0: 7b 0a 20 20 20 20 53 6f 72 74 53 75 62 74 61 73  {.    SortSubtas
99b0: 6b 20 2a 70 54 61 73 6b 20 3d 20 26 70 53 6f 72  k *pTask = &pSor
99c0: 74 65 72 2d 3e 61 54 61 73 6b 5b 69 5d 3b 0a 20  ter->aTask[i];. 
99d0: 20 20 20 69 6e 74 20 72 63 32 20 3d 20 76 64 62     int rc2 = vdb
99e0: 65 53 6f 72 74 65 72 4a 6f 69 6e 54 68 72 65 61  eSorterJoinThrea
99f0: 64 28 70 54 61 73 6b 29 3b 0a 20 20 20 20 69 66  d(pTask);.    if
9a00: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
9a10: 29 20 72 63 20 3d 20 72 63 32 3b 0a 20 20 7d 0a  ) rc = rc2;.  }.
9a20: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 23    return rc;.}.#
9a30: 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 76 64  else.# define vd
9a40: 62 65 53 6f 72 74 65 72 4a 6f 69 6e 41 6c 6c 28  beSorterJoinAll(
9a50: 78 2c 72 63 69 6e 29 20 28 72 63 69 6e 29 0a 23  x,rcin) (rcin).#
9a60: 20 64 65 66 69 6e 65 20 76 64 62 65 53 6f 72 74   define vdbeSort
9a70: 65 72 4a 6f 69 6e 54 68 72 65 61 64 28 70 54 61  erJoinThread(pTa
9a80: 73 6b 29 20 53 51 4c 49 54 45 5f 4f 4b 0a 23 65  sk) SQLITE_OK.#e
9a90: 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f  ndif../*.** Allo
9aa0: 63 61 74 65 20 61 20 6e 65 77 20 4d 65 72 67 65  cate a new Merge
9ab0: 45 6e 67 69 6e 65 20 6f 62 6a 65 63 74 20 77 69  Engine object wi
9ac0: 74 68 20 73 70 61 63 65 20 66 6f 72 20 6e 52 65  th space for nRe
9ad0: 61 64 65 72 20 50 6d 61 52 65 61 64 65 72 73 2e  ader PmaReaders.
9ae0: 0a 2a 2f 0a 73 74 61 74 69 63 20 4d 65 72 67 65  .*/.static Merge
9af0: 45 6e 67 69 6e 65 20 2a 76 64 62 65 4d 65 72 67  Engine *vdbeMerg
9b00: 65 45 6e 67 69 6e 65 4e 65 77 28 69 6e 74 20 6e  eEngineNew(int n
9b10: 52 65 61 64 65 72 29 7b 0a 20 20 69 6e 74 20 4e  Reader){.  int N
9b20: 20 3d 20 32 3b 20 20 20 20 20 20 20 20 20 20 20   = 2;           
9b30: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6d             /* Sm
9b40: 61 6c 6c 65 73 74 20 70 6f 77 65 72 20 6f 66 20  allest power of 
9b50: 74 77 6f 20 3e 3d 20 6e 52 65 61 64 65 72 20 2a  two >= nReader *
9b60: 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b 20 20  /.  int nByte;  
9b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9b80: 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 62 79 74      /* Total byt
9b90: 65 73 20 6f 66 20 73 70 61 63 65 20 74 6f 20 61  es of space to a
9ba0: 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20 20 4d 65 72  llocate */.  Mer
9bb0: 67 65 45 6e 67 69 6e 65 20 2a 70 4e 65 77 3b 20  geEngine *pNew; 
9bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9bd0: 50 6f 69 6e 74 65 72 20 74 6f 20 61 6c 6c 6f 63  Pointer to alloc
9be0: 61 74 65 64 20 6f 62 6a 65 63 74 20 74 6f 20 72  ated object to r
9bf0: 65 74 75 72 6e 20 2a 2f 0a 0a 20 20 61 73 73 65  eturn */..  asse
9c00: 72 74 28 20 6e 52 65 61 64 65 72 3c 3d 53 4f 52  rt( nReader<=SOR
9c10: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
9c20: 55 4e 54 20 29 3b 0a 0a 20 20 77 68 69 6c 65 28  UNT );..  while(
9c30: 20 4e 3c 6e 52 65 61 64 65 72 20 29 20 4e 20 2b   N<nReader ) N +
9c40: 3d 20 4e 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73  = N;.  nByte = s
9c50: 69 7a 65 6f 66 28 4d 65 72 67 65 45 6e 67 69 6e  izeof(MergeEngin
9c60: 65 29 20 2b 20 4e 20 2a 20 28 73 69 7a 65 6f 66  e) + N * (sizeof
9c70: 28 69 6e 74 29 20 2b 20 73 69 7a 65 6f 66 28 50  (int) + sizeof(P
9c80: 6d 61 52 65 61 64 65 72 29 29 3b 0a 0a 20 20 70  maReader));..  p
9c90: 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 46 61 75  New = sqlite3Fau
9ca0: 6c 74 53 69 6d 28 31 30 30 29 20 3f 20 30 20 3a  ltSim(100) ? 0 :
9cb0: 20 28 4d 65 72 67 65 45 6e 67 69 6e 65 2a 29 73   (MergeEngine*)s
9cc0: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f  qlite3MallocZero
9cd0: 28 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20 70  (nByte);.  if( p
9ce0: 4e 65 77 20 29 7b 0a 20 20 20 20 70 4e 65 77 2d  New ){.    pNew-
9cf0: 3e 6e 54 72 65 65 20 3d 20 4e 3b 0a 20 20 20 20  >nTree = N;.    
9d00: 70 4e 65 77 2d 3e 61 52 65 61 64 72 20 3d 20 28  pNew->aReadr = (
9d10: 50 6d 61 52 65 61 64 65 72 2a 29 26 70 4e 65 77  PmaReader*)&pNew
9d20: 5b 31 5d 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 61  [1];.    pNew->a
9d30: 54 72 65 65 20 3d 20 28 69 6e 74 2a 29 26 70 4e  Tree = (int*)&pN
9d40: 65 77 2d 3e 61 52 65 61 64 72 5b 4e 5d 3b 0a 20  ew->aReadr[N];. 
9d50: 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 4e 65 77   }.  return pNew
9d60: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20  ;.}../*.** Free 
9d70: 74 68 65 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  the MergeEngine 
9d80: 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20 61 73  object passed as
9d90: 20 74 68 65 20 6f 6e 6c 79 20 61 72 67 75 6d 65   the only argume
9da0: 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  nt..*/.static vo
9db0: 69 64 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69  id vdbeMergeEngi
9dc0: 6e 65 46 72 65 65 28 4d 65 72 67 65 45 6e 67 69  neFree(MergeEngi
9dd0: 6e 65 20 2a 70 4d 65 72 67 65 72 29 7b 0a 20 20  ne *pMerger){.  
9de0: 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 70 4d 65  int i;.  if( pMe
9df0: 72 67 65 72 20 29 7b 0a 20 20 20 20 66 6f 72 28  rger ){.    for(
9e00: 69 3d 30 3b 20 69 3c 70 4d 65 72 67 65 72 2d 3e  i=0; i<pMerger->
9e10: 6e 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20 20 20  nTree; i++){.   
9e20: 20 20 20 76 64 62 65 50 6d 61 52 65 61 64 65 72     vdbePmaReader
9e30: 43 6c 65 61 72 28 26 70 4d 65 72 67 65 72 2d 3e  Clear(&pMerger->
9e40: 61 52 65 61 64 72 5b 69 5d 29 3b 0a 20 20 20 20  aReadr[i]);.    
9e50: 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  }.  }.  sqlite3_
9e60: 66 72 65 65 28 70 4d 65 72 67 65 72 29 3b 0a 7d  free(pMerger);.}
9e70: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6c 6c  ../*.** Free all
9e80: 20 72 65 73 6f 75 72 63 65 73 20 61 73 73 6f 63   resources assoc
9e90: 69 61 74 65 64 20 77 69 74 68 20 74 68 65 20 49  iated with the I
9ea0: 6e 63 72 4d 65 72 67 65 72 20 6f 62 6a 65 63 74  ncrMerger object
9eb0: 20 69 6e 64 69 63 61 74 65 64 20 62 79 0a 2a 2a   indicated by.**
9ec0: 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d   the first argum
9ed0: 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ent..*/.static v
9ee0: 6f 69 64 20 76 64 62 65 49 6e 63 72 46 72 65 65  oid vdbeIncrFree
9ef0: 28 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e  (IncrMerger *pIn
9f00: 63 72 29 7b 0a 20 20 69 66 28 20 70 49 6e 63 72  cr){.  if( pIncr
9f10: 20 29 7b 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d   ){.#if SQLITE_M
9f20: 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44  AX_WORKER_THREAD
9f30: 53 3e 30 0a 20 20 20 20 69 66 28 20 70 49 6e 63  S>0.    if( pInc
9f40: 72 2d 3e 62 55 73 65 54 68 72 65 61 64 20 29 7b  r->bUseThread ){
9f50: 0a 20 20 20 20 20 20 76 64 62 65 53 6f 72 74 65  .      vdbeSorte
9f60: 72 4a 6f 69 6e 54 68 72 65 61 64 28 70 49 6e 63  rJoinThread(pInc
9f70: 72 2d 3e 70 54 61 73 6b 29 3b 0a 20 20 20 20 20  r->pTask);.     
9f80: 20 69 66 28 20 70 49 6e 63 72 2d 3e 61 46 69 6c   if( pIncr->aFil
9f90: 65 5b 30 5d 2e 70 46 64 20 29 20 73 71 6c 69 74  e[0].pFd ) sqlit
9fa0: 65 33 4f 73 43 6c 6f 73 65 46 72 65 65 28 70 49  e3OsCloseFree(pI
9fb0: 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e 70 46  ncr->aFile[0].pF
9fc0: 64 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 49  d);.      if( pI
9fd0: 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 2e 70 46  ncr->aFile[1].pF
9fe0: 64 20 29 20 73 71 6c 69 74 65 33 4f 73 43 6c 6f  d ) sqlite3OsClo
9ff0: 73 65 46 72 65 65 28 70 49 6e 63 72 2d 3e 61 46  seFree(pIncr->aF
a000: 69 6c 65 5b 31 5d 2e 70 46 64 29 3b 0a 20 20 20  ile[1].pFd);.   
a010: 20 7d 0a 23 65 6e 64 69 66 0a 20 20 20 20 76 64   }.#endif.    vd
a020: 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46 72 65  beMergeEngineFre
a030: 65 28 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65 72  e(pIncr->pMerger
a040: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
a050: 72 65 65 28 70 49 6e 63 72 29 3b 0a 20 20 7d 0a  ree(pIncr);.  }.
a060: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65 74 20 61  }../*.** Reset a
a070: 20 73 6f 72 74 69 6e 67 20 63 75 72 73 6f 72 20   sorting cursor 
a080: 62 61 63 6b 20 74 6f 20 69 74 73 20 6f 72 69 67  back to its orig
a090: 69 6e 61 6c 20 65 6d 70 74 79 20 73 74 61 74 65  inal empty state
a0a0: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
a0b0: 33 56 64 62 65 53 6f 72 74 65 72 52 65 73 65 74  3VdbeSorterReset
a0c0: 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 56 64  (sqlite3 *db, Vd
a0d0: 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
a0e0: 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 28  r){.  int i;.  (
a0f0: 76 6f 69 64 29 76 64 62 65 53 6f 72 74 65 72 4a  void)vdbeSorterJ
a100: 6f 69 6e 41 6c 6c 28 70 53 6f 72 74 65 72 2c 20  oinAll(pSorter, 
a110: 53 51 4c 49 54 45 5f 4f 4b 29 3b 0a 20 20 61 73  SQLITE_OK);.  as
a120: 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 62  sert( pSorter->b
a130: 55 73 65 54 68 72 65 61 64 73 20 7c 7c 20 70 53  UseThreads || pS
a140: 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72 3d 3d  orter->pReader==
a150: 30 20 29 3b 0a 23 69 66 20 53 51 4c 49 54 45 5f  0 );.#if SQLITE_
a160: 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41  MAX_WORKER_THREA
a170: 44 53 3e 30 0a 20 20 69 66 28 20 70 53 6f 72 74  DS>0.  if( pSort
a180: 65 72 2d 3e 70 52 65 61 64 65 72 20 29 7b 0a 20  er->pReader ){. 
a190: 20 20 20 76 64 62 65 50 6d 61 52 65 61 64 65 72     vdbePmaReader
a1a0: 43 6c 65 61 72 28 70 53 6f 72 74 65 72 2d 3e 70  Clear(pSorter->p
a1b0: 52 65 61 64 65 72 29 3b 0a 20 20 20 20 73 71 6c  Reader);.    sql
a1c0: 69 74 65 33 44 62 46 72 65 65 28 64 62 2c 20 70  ite3DbFree(db, p
a1d0: 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72 29  Sorter->pReader)
a1e0: 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70  ;.    pSorter->p
a1f0: 52 65 61 64 65 72 20 3d 20 30 3b 0a 20 20 7d 0a  Reader = 0;.  }.
a200: 23 65 6e 64 69 66 0a 20 20 76 64 62 65 4d 65 72  #endif.  vdbeMer
a210: 67 65 45 6e 67 69 6e 65 46 72 65 65 28 70 53 6f  geEngineFree(pSo
a220: 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 29 3b 0a  rter->pMerger);.
a230: 20 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67    pSorter->pMerg
a240: 65 72 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d  er = 0;.  for(i=
a250: 30 3b 20 69 3c 70 53 6f 72 74 65 72 2d 3e 6e 54  0; i<pSorter->nT
a260: 61 73 6b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 53  ask; i++){.    S
a270: 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
a280: 6b 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 54  k = &pSorter->aT
a290: 61 73 6b 5b 69 5d 3b 0a 20 20 20 20 76 64 62 65  ask[i];.    vdbe
a2a0: 53 6f 72 74 53 75 62 74 61 73 6b 43 6c 65 61 6e  SortSubtaskClean
a2b0: 75 70 28 64 62 2c 20 70 54 61 73 6b 29 3b 0a 20  up(db, pTask);. 
a2c0: 20 7d 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72   }.  if( pSorter
a2d0: 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d  ->list.aMemory==
a2e0: 30 20 29 7b 0a 20 20 20 20 76 64 62 65 53 6f 72  0 ){.    vdbeSor
a2f0: 74 65 72 52 65 63 6f 72 64 46 72 65 65 28 30 2c  terRecordFree(0,
a300: 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70   pSorter->list.p
a310: 4c 69 73 74 29 3b 0a 20 20 7d 0a 20 20 70 53 6f  List);.  }.  pSo
a320: 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74  rter->list.pList
a330: 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74 65 72 2d   = 0;.  pSorter-
a340: 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 3d 20 30 3b  >list.szPMA = 0;
a350: 0a 20 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65  .  pSorter->bUse
a360: 50 4d 41 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74  PMA = 0;.  pSort
a370: 65 72 2d 3e 69 4d 65 6d 6f 72 79 20 3d 20 30 3b  er->iMemory = 0;
a380: 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6d 78 4b 65  .  pSorter->mxKe
a390: 79 73 69 7a 65 20 3d 20 30 3b 0a 20 20 73 71 6c  ysize = 0;.  sql
a3a0: 69 74 65 33 44 62 46 72 65 65 28 64 62 2c 20 70  ite3DbFree(db, p
a3b0: 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65  Sorter->pUnpacke
a3c0: 64 29 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 70  d);.  pSorter->p
a3d0: 55 6e 70 61 63 6b 65 64 20 3d 20 30 3b 0a 7d 0a  Unpacked = 0;.}.
a3e0: 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 79 20  ./*.** Free any 
a3f0: 63 75 72 73 6f 72 20 63 6f 6d 70 6f 6e 65 6e 74  cursor component
a400: 73 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20 73  s allocated by s
a410: 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72  qlite3VdbeSorter
a420: 58 58 58 20 72 6f 75 74 69 6e 65 73 2e 0a 2a 2f  XXX routines..*/
a430: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 56 64 62  .void sqlite3Vdb
a440: 65 53 6f 72 74 65 72 43 6c 6f 73 65 28 73 71 6c  eSorterClose(sql
a450: 69 74 65 33 20 2a 64 62 2c 20 56 64 62 65 43 75  ite3 *db, VdbeCu
a460: 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 56  rsor *pCsr){.  V
a470: 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
a480: 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74  er = pCsr->pSort
a490: 65 72 3b 0a 20 20 69 66 28 20 70 53 6f 72 74 65  er;.  if( pSorte
a4a0: 72 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  r ){.    sqlite3
a4b0: 56 64 62 65 53 6f 72 74 65 72 52 65 73 65 74 28  VdbeSorterReset(
a4c0: 64 62 2c 20 70 53 6f 72 74 65 72 29 3b 0a 20 20  db, pSorter);.  
a4d0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
a4e0: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65  Sorter->list.aMe
a4f0: 6d 6f 72 79 29 3b 0a 20 20 20 20 73 71 6c 69 74  mory);.    sqlit
a500: 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 53 6f  e3DbFree(db, pSo
a510: 72 74 65 72 29 3b 0a 20 20 20 20 70 43 73 72 2d  rter);.    pCsr-
a520: 3e 70 53 6f 72 74 65 72 20 3d 20 30 3b 0a 20 20  >pSorter = 0;.  
a530: 7d 0a 7d 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f  }.}..#if SQLITE_
a540: 4d 41 58 5f 4d 4d 41 50 5f 53 49 5a 45 3e 30 0a  MAX_MMAP_SIZE>0.
a550: 2f 2a 0a 2a 2a 20 54 68 65 20 66 69 72 73 74 20  /*.** The first 
a560: 61 72 67 75 6d 65 6e 74 20 69 73 20 61 20 66 69  argument is a fi
a570: 6c 65 2d 68 61 6e 64 6c 65 20 6f 70 65 6e 20 6f  le-handle open o
a580: 6e 20 61 20 74 65 6d 70 6f 72 61 72 79 20 66 69  n a temporary fi
a590: 6c 65 2e 20 54 68 65 20 66 69 6c 65 0a 2a 2a 20  le. The file.** 
a5a0: 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 74 6f  is guaranteed to
a5b0: 20 62 65 20 6e 42 79 74 65 20 62 79 74 65 73 20   be nByte bytes 
a5c0: 6f 72 20 73 6d 61 6c 6c 65 72 20 69 6e 20 73 69  or smaller in si
a5d0: 7a 65 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f  ze. This functio
a5e0: 6e 0a 2a 2a 20 61 74 74 65 6d 70 74 73 20 74 6f  n.** attempts to
a5f0: 20 65 78 74 65 6e 64 20 74 68 65 20 66 69 6c 65   extend the file
a600: 20 74 6f 20 6e 42 79 74 65 20 62 79 74 65 73 20   to nByte bytes 
a610: 69 6e 20 73 69 7a 65 20 61 6e 64 20 74 6f 20 65  in size and to e
a620: 6e 73 75 72 65 20 74 68 61 74 0a 2a 2a 20 74 68  nsure that.** th
a630: 65 20 56 46 53 20 68 61 73 20 6d 65 6d 6f 72 79  e VFS has memory
a640: 20 6d 61 70 70 65 64 20 69 74 2e 0a 2a 2a 0a 2a   mapped it..**.*
a650: 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e 6f 74  * Whether or not
a660: 20 74 68 65 20 66 69 6c 65 20 64 6f 65 73 20 65   the file does e
a670: 6e 64 20 75 70 20 6d 65 6d 6f 72 79 20 6d 61 70  nd up memory map
a680: 70 65 64 20 6f 66 20 63 6f 75 72 73 65 20 64 65  ped of course de
a690: 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20 74 68 65 20  pends on.** the 
a6a0: 73 70 65 63 69 66 69 63 20 56 46 53 20 69 6d 70  specific VFS imp
a6b0: 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a  lementation..*/.
a6c0: 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65  static void vdbe
a6d0: 53 6f 72 74 65 72 45 78 74 65 6e 64 46 69 6c 65  SorterExtendFile
a6e0: 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 73 71  (sqlite3 *db, sq
a6f0: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
a700: 65 2c 20 69 36 34 20 6e 42 79 74 65 29 7b 0a 20  e, i64 nByte){. 
a710: 20 69 66 28 20 6e 42 79 74 65 3c 3d 28 69 36 34   if( nByte<=(i64
a720: 29 28 64 62 2d 3e 6e 4d 61 78 53 6f 72 74 65 72  )(db->nMaxSorter
a730: 4d 6d 61 70 29 20 29 7b 0a 20 20 20 20 69 6e 74  Mmap) ){.    int
a740: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 54   rc = sqlite3OsT
a750: 72 75 6e 63 61 74 65 28 70 46 69 6c 65 2c 20 6e  runcate(pFile, n
a760: 42 79 74 65 29 3b 0a 20 20 20 20 69 66 28 20 72  Byte);.    if( r
a770: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
a780: 20 20 20 20 20 20 76 6f 69 64 20 2a 70 20 3d 20        void *p = 
a790: 30 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  0;.      sqlite3
a7a0: 4f 73 46 65 74 63 68 28 70 46 69 6c 65 2c 20 30  OsFetch(pFile, 0
a7b0: 2c 20 28 69 6e 74 29 6e 42 79 74 65 2c 20 26 70  , (int)nByte, &p
a7c0: 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  );.      sqlite3
a7d0: 4f 73 55 6e 66 65 74 63 68 28 70 46 69 6c 65 2c  OsUnfetch(pFile,
a7e0: 20 30 2c 20 70 29 3b 0a 20 20 20 20 7d 0a 20 20   0, p);.    }.  
a7f0: 7d 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65 66 69  }.}.#else.# defi
a800: 6e 65 20 76 64 62 65 53 6f 72 74 65 72 45 78 74  ne vdbeSorterExt
a810: 65 6e 64 46 69 6c 65 28 78 2c 79 2c 7a 29 20 53  endFile(x,y,z) S
a820: 51 4c 49 54 45 5f 4f 4b 0a 23 65 6e 64 69 66 0a  QLITE_OK.#endif.
a830: 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20  ./*.** Allocate 
a840: 73 70 61 63 65 20 66 6f 72 20 61 20 66 69 6c 65  space for a file
a850: 2d 68 61 6e 64 6c 65 20 61 6e 64 20 6f 70 65 6e  -handle and open
a860: 20 61 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c   a temporary fil
a870: 65 2e 20 49 66 20 73 75 63 63 65 73 73 66 75 6c  e. If successful
a880: 2c 0a 2a 2a 20 73 65 74 20 2a 70 70 46 69 6c 65  ,.** set *ppFile
a890: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65   to point to the
a8a0: 20 6d 61 6c 6c 6f 63 27 64 20 66 69 6c 65 2d 68   malloc'd file-h
a8b0: 61 6e 64 6c 65 20 61 6e 64 20 72 65 74 75 72 6e  andle and return
a8c0: 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2a 20 4f   SQLITE_OK..** O
a8d0: 74 68 65 72 77 69 73 65 2c 20 73 65 74 20 2a 70  therwise, set *p
a8e0: 70 46 69 6c 65 20 74 6f 20 30 20 61 6e 64 20 72  pFile to 0 and r
a8f0: 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 20  eturn an SQLite 
a900: 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2f 0a 73  error code..*/.s
a910: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
a920: 72 74 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65  rterOpenTempFile
a930: 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
a940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a950: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
a960: 68 61 6e 64 6c 65 20 64 6f 69 6e 67 20 73 6f 72  handle doing sor
a970: 74 20 2a 2f 0a 20 20 69 36 34 20 6e 45 78 74 65  t */.  i64 nExte
a980: 6e 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  nd,             
a990: 20 20 20 20 20 20 20 2f 2a 20 41 74 74 65 6d 70         /* Attemp
a9a0: 74 20 74 6f 20 65 78 74 65 6e 64 20 66 69 6c 65  t to extend file
a9b0: 20 74 6f 20 74 68 69 73 20 73 69 7a 65 20 2a 2f   to this size */
a9c0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
a9d0: 2a 2a 70 70 46 69 6c 65 0a 29 7b 0a 20 20 69 6e  **ppFile.){.  in
a9e0: 74 20 72 63 3b 0a 20 20 72 63 20 3d 20 73 71 6c  t rc;.  rc = sql
a9f0: 69 74 65 33 4f 73 4f 70 65 6e 4d 61 6c 6c 6f 63  ite3OsOpenMalloc
aa00: 28 64 62 2d 3e 70 56 66 73 2c 20 30 2c 20 70 70  (db->pVfs, 0, pp
aa10: 46 69 6c 65 2c 0a 20 20 20 20 20 20 53 51 4c 49  File,.      SQLI
aa20: 54 45 5f 4f 50 45 4e 5f 54 45 4d 50 5f 4a 4f 55  TE_OPEN_TEMP_JOU
aa30: 52 4e 41 4c 20 7c 0a 20 20 20 20 20 20 53 51 4c  RNAL |.      SQL
aa40: 49 54 45 5f 4f 50 45 4e 5f 52 45 41 44 57 52 49  ITE_OPEN_READWRI
aa50: 54 45 20 20 20 20 7c 20 53 51 4c 49 54 45 5f 4f  TE    | SQLITE_O
aa60: 50 45 4e 5f 43 52 45 41 54 45 20 7c 0a 20 20 20  PEN_CREATE |.   
aa70: 20 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 45     SQLITE_OPEN_E
aa80: 58 43 4c 55 53 49 56 45 20 20 20 20 7c 20 53 51  XCLUSIVE    | SQ
aa90: 4c 49 54 45 5f 4f 50 45 4e 5f 44 45 4c 45 54 45  LITE_OPEN_DELETE
aaa0: 4f 4e 43 4c 4f 53 45 2c 20 26 72 63 0a 20 20 29  ONCLOSE, &rc.  )
aab0: 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
aac0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 36 34  TE_OK ){.    i64
aad0: 20 6d 61 78 20 3d 20 53 51 4c 49 54 45 5f 4d 41   max = SQLITE_MA
aae0: 58 5f 4d 4d 41 50 5f 53 49 5a 45 3b 0a 20 20 20  X_MMAP_SIZE;.   
aaf0: 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 43 6f   sqlite3OsFileCo
ab00: 6e 74 72 6f 6c 48 69 6e 74 28 2a 70 70 46 69 6c  ntrolHint(*ppFil
ab10: 65 2c 20 53 51 4c 49 54 45 5f 46 43 4e 54 4c 5f  e, SQLITE_FCNTL_
ab20: 4d 4d 41 50 5f 53 49 5a 45 2c 20 28 76 6f 69 64  MMAP_SIZE, (void
ab30: 2a 29 26 6d 61 78 29 3b 0a 20 20 20 20 69 66 28  *)&max);.    if(
ab40: 20 6e 45 78 74 65 6e 64 3e 30 20 29 7b 0a 20 20   nExtend>0 ){.  
ab50: 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 45 78      vdbeSorterEx
ab60: 74 65 6e 64 46 69 6c 65 28 64 62 2c 20 2a 70 70  tendFile(db, *pp
ab70: 46 69 6c 65 2c 20 6e 45 78 74 65 6e 64 29 3b 0a  File, nExtend);.
ab80: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
ab90: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
aba0: 49 66 20 69 74 20 68 61 73 20 6e 6f 74 20 61 6c  If it has not al
abb0: 72 65 61 64 79 20 62 65 65 6e 20 61 6c 6c 6f 63  ready been alloc
abc0: 61 74 65 64 2c 20 61 6c 6c 6f 63 61 74 65 20 74  ated, allocate t
abd0: 68 65 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72  he UnpackedRecor
abe0: 64 20 0a 2a 2a 20 73 74 72 75 63 74 75 72 65 20  d .** structure 
abf0: 61 74 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63  at pTask->pUnpac
ac00: 6b 65 64 2e 20 52 65 74 75 72 6e 20 53 51 4c 49  ked. Return SQLI
ac10: 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73  TE_OK if success
ac20: 66 75 6c 20 28 6f 72 20 0a 2a 2a 20 69 66 20 6e  ful (or .** if n
ac30: 6f 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 77 61 73  o allocation was
ac40: 20 72 65 71 75 69 72 65 64 29 2c 20 6f 72 20 53   required), or S
ac50: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 6f 74 68 65  QLITE_NOMEM othe
ac60: 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  rwise..*/.static
ac70: 20 69 6e 74 20 76 64 62 65 53 6f 72 74 41 6c 6c   int vdbeSortAll
ac80: 6f 63 55 6e 70 61 63 6b 65 64 28 53 6f 72 74 53  ocUnpacked(SortS
ac90: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 29 7b 0a  ubtask *pTask){.
aca0: 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 70 55 6e    if( pTask->pUn
acb0: 70 61 63 6b 65 64 3d 3d 30 20 29 7b 0a 20 20 20  packed==0 ){.   
acc0: 20 63 68 61 72 20 2a 70 46 72 65 65 3b 0a 20 20   char *pFree;.  
acd0: 20 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b    pTask->pUnpack
ace0: 65 64 20 3d 20 73 71 6c 69 74 65 33 56 64 62 65  ed = sqlite3Vdbe
acf0: 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64 52 65 63  AllocUnpackedRec
ad00: 6f 72 64 28 0a 20 20 20 20 20 20 20 20 70 54 61  ord(.        pTa
ad10: 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 4b 65  sk->pSorter->pKe
ad20: 79 49 6e 66 6f 2c 20 30 2c 20 30 2c 20 26 70 46  yInfo, 0, 0, &pF
ad30: 72 65 65 0a 20 20 20 20 29 3b 0a 20 20 20 20 61  ree.    );.    a
ad40: 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 70 55  ssert( pTask->pU
ad50: 6e 70 61 63 6b 65 64 3d 3d 28 55 6e 70 61 63 6b  npacked==(Unpack
ad60: 65 64 52 65 63 6f 72 64 2a 29 70 46 72 65 65 20  edRecord*)pFree 
ad70: 29 3b 0a 20 20 20 20 69 66 28 20 70 46 72 65 65  );.    if( pFree
ad80: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
ad90: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 70  ITE_NOMEM;.    p
ada0: 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 2d  Task->pUnpacked-
adb0: 3e 6e 46 69 65 6c 64 20 3d 20 70 54 61 73 6b 2d  >nField = pTask-
adc0: 3e 70 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49 6e  >pSorter->pKeyIn
add0: 66 6f 2d 3e 6e 46 69 65 6c 64 3b 0a 20 20 20 20  fo->nField;.    
ade0: 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64  pTask->pUnpacked
adf0: 2d 3e 65 72 72 43 6f 64 65 20 3d 20 30 3b 0a 20  ->errCode = 0;. 
ae00: 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49   }.  return SQLI
ae10: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a  TE_OK;.}.../*.**
ae20: 20 4d 65 72 67 65 20 74 68 65 20 74 77 6f 20 73   Merge the two s
ae30: 6f 72 74 65 64 20 6c 69 73 74 73 20 70 31 20 61  orted lists p1 a
ae40: 6e 64 20 70 32 20 69 6e 74 6f 20 61 20 73 69 6e  nd p2 into a sin
ae50: 67 6c 65 20 6c 69 73 74 2e 0a 2a 2a 20 53 65 74  gle list..** Set
ae60: 20 2a 70 70 4f 75 74 20 74 6f 20 74 68 65 20 68   *ppOut to the h
ae70: 65 61 64 20 6f 66 20 74 68 65 20 6e 65 77 20 6c  ead of the new l
ae80: 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ist..*/.static v
ae90: 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72 4d 65  oid vdbeSorterMe
aea0: 72 67 65 28 0a 20 20 53 6f 72 74 53 75 62 74 61  rge(.  SortSubta
aeb0: 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20 20 20 20  sk *pTask,      
aec0: 20 20 20 20 20 20 20 2f 2a 20 43 61 6c 6c 69 6e         /* Callin
aed0: 67 20 74 68 72 65 61 64 20 63 6f 6e 74 65 78 74  g thread context
aee0: 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f   */.  SorterReco
aef0: 72 64 20 2a 70 31 2c 20 20 20 20 20 20 20 20 20  rd *p1,         
af00: 20 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 6c        /* First l
af10: 69 73 74 20 74 6f 20 6d 65 72 67 65 20 2a 2f 0a  ist to merge */.
af20: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
af30: 70 32 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  p2,             
af40: 20 20 2f 2a 20 53 65 63 6f 6e 64 20 6c 69 73 74    /* Second list
af50: 20 74 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20 53   to merge */.  S
af60: 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 2a 70 70  orterRecord **pp
af70: 4f 75 74 20 20 20 20 20 20 20 20 20 20 20 20 2f  Out            /
af80: 2a 20 4f 55 54 3a 20 48 65 61 64 20 6f 66 20 6d  * OUT: Head of m
af90: 65 72 67 65 64 20 6c 69 73 74 20 2a 2f 0a 29 7b  erged list */.){
afa0: 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20  .  SorterRecord 
afb0: 2a 70 46 69 6e 61 6c 20 3d 20 30 3b 0a 20 20 53  *pFinal = 0;.  S
afc0: 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 2a 70 70  orterRecord **pp
afd0: 20 3d 20 26 70 46 69 6e 61 6c 3b 0a 20 20 76 6f   = &pFinal;.  vo
afe0: 69 64 20 2a 70 56 61 6c 32 20 3d 20 70 32 20 3f  id *pVal2 = p2 ?
aff0: 20 53 52 56 41 4c 28 70 32 29 20 3a 20 30 3b 0a   SRVAL(p2) : 0;.
b000: 0a 20 20 77 68 69 6c 65 28 20 70 31 20 26 26 20  .  while( p1 && 
b010: 70 32 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 65  p2 ){.    int re
b020: 73 3b 0a 20 20 20 20 72 65 73 20 3d 20 76 64 62  s;.    res = vdb
b030: 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 70  eSorterCompare(p
b040: 54 61 73 6b 2c 20 53 52 56 41 4c 28 70 31 29 2c  Task, SRVAL(p1),
b050: 20 70 31 2d 3e 6e 56 61 6c 2c 20 70 56 61 6c 32   p1->nVal, pVal2
b060: 2c 20 70 32 2d 3e 6e 56 61 6c 29 3b 0a 20 20 20  , p2->nVal);.   
b070: 20 69 66 28 20 72 65 73 3c 3d 30 20 29 7b 0a 20   if( res<=0 ){. 
b080: 20 20 20 20 20 2a 70 70 20 3d 20 70 31 3b 0a 20       *pp = p1;. 
b090: 20 20 20 20 20 70 70 20 3d 20 26 70 31 2d 3e 75       pp = &p1->u
b0a0: 2e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 31  .pNext;.      p1
b0b0: 20 3d 20 70 31 2d 3e 75 2e 70 4e 65 78 74 3b 0a   = p1->u.pNext;.
b0c0: 20 20 20 20 20 20 70 56 61 6c 32 20 3d 20 30 3b        pVal2 = 0;
b0d0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
b0e0: 20 20 2a 70 70 20 3d 20 70 32 3b 0a 20 20 20 20    *pp = p2;.    
b0f0: 20 20 20 70 70 20 3d 20 26 70 32 2d 3e 75 2e 70     pp = &p2->u.p
b100: 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 32 20 3d  Next;.      p2 =
b110: 20 70 32 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20 20   p2->u.pNext;.  
b120: 20 20 20 20 69 66 28 20 70 32 3d 3d 30 20 29 20      if( p2==0 ) 
b130: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 70 56 61  break;.      pVa
b140: 6c 32 20 3d 20 53 52 56 41 4c 28 70 32 29 3b 0a  l2 = SRVAL(p2);.
b150: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 70 20      }.  }.  *pp 
b160: 3d 20 70 31 20 3f 20 70 31 20 3a 20 70 32 3b 0a  = p1 ? p1 : p2;.
b170: 20 20 2a 70 70 4f 75 74 20 3d 20 70 46 69 6e 61    *ppOut = pFina
b180: 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74  l;.}../*.** Sort
b190: 20 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74   the linked list
b1a0: 20 6f 66 20 72 65 63 6f 72 64 73 20 68 65 61 64   of records head
b1b0: 65 64 20 61 74 20 70 54 61 73 6b 2d 3e 70 4c 69  ed at pTask->pLi
b1c0: 73 74 2e 20 52 65 74 75 72 6e 20 0a 2a 2a 20 53  st. Return .** S
b1d0: 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63  QLITE_OK if succ
b1e0: 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51  essful, or an SQ
b1f0: 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20  Lite error code 
b200: 28 69 2e 65 2e 20 53 51 4c 49 54 45 5f 4e 4f 4d  (i.e. SQLITE_NOM
b210: 45 4d 29 20 69 66 20 0a 2a 2a 20 61 6e 20 65 72  EM) if .** an er
b220: 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73  ror occurs..*/.s
b230: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
b240: 72 74 65 72 53 6f 72 74 28 53 6f 72 74 53 75 62  rterSort(SortSub
b250: 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 53 6f 72  task *pTask, Sor
b260: 74 65 72 4c 69 73 74 20 2a 70 4c 69 73 74 29 7b  terList *pList){
b270: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 53 6f 72 74  .  int i;.  Sort
b280: 65 72 52 65 63 6f 72 64 20 2a 2a 61 53 6c 6f 74  erRecord **aSlot
b290: 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  ;.  SorterRecord
b2a0: 20 2a 70 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a   *p;.  int rc;..
b2b0: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 41    rc = vdbeSortA
b2c0: 6c 6c 6f 63 55 6e 70 61 63 6b 65 64 28 70 54 61  llocUnpacked(pTa
b2d0: 73 6b 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  sk);.  if( rc!=S
b2e0: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
b2f0: 6e 20 72 63 3b 0a 0a 20 20 61 53 6c 6f 74 20 3d  n rc;..  aSlot =
b300: 20 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a   (SorterRecord *
b310: 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a  *)sqlite3MallocZ
b320: 65 72 6f 28 36 34 20 2a 20 73 69 7a 65 6f 66 28  ero(64 * sizeof(
b330: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 29 29  SorterRecord *))
b340: 3b 0a 20 20 69 66 28 20 21 61 53 6c 6f 74 20 29  ;.  if( !aSlot )
b350: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  {.    return SQL
b360: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a  ITE_NOMEM;.  }..
b370: 20 20 70 20 3d 20 70 4c 69 73 74 2d 3e 70 4c 69    p = pList->pLi
b380: 73 74 3b 0a 20 20 77 68 69 6c 65 28 20 70 20 29  st;.  while( p )
b390: 7b 0a 20 20 20 20 53 6f 72 74 65 72 52 65 63 6f  {.    SorterReco
b3a0: 72 64 20 2a 70 4e 65 78 74 3b 0a 20 20 20 20 69  rd *pNext;.    i
b3b0: 66 28 20 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f 72  f( pList->aMemor
b3c0: 79 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 28  y ){.      if( (
b3d0: 75 38 2a 29 70 3d 3d 70 4c 69 73 74 2d 3e 61 4d  u8*)p==pList->aM
b3e0: 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20 20 20  emory ){.       
b3f0: 20 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20   pNext = 0;.    
b400: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
b410: 20 61 73 73 65 72 74 28 20 70 2d 3e 75 2e 69 4e   assert( p->u.iN
b420: 65 78 74 3c 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  ext<sqlite3Mallo
b430: 63 53 69 7a 65 28 70 4c 69 73 74 2d 3e 61 4d 65  cSize(pList->aMe
b440: 6d 6f 72 79 29 20 29 3b 0a 20 20 20 20 20 20 20  mory) );.       
b450: 20 70 4e 65 78 74 20 3d 20 28 53 6f 72 74 65 72   pNext = (Sorter
b460: 52 65 63 6f 72 64 2a 29 26 70 4c 69 73 74 2d 3e  Record*)&pList->
b470: 61 4d 65 6d 6f 72 79 5b 70 2d 3e 75 2e 69 4e 65  aMemory[p->u.iNe
b480: 78 74 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  xt];.      }.   
b490: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 4e   }else{.      pN
b4a0: 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74  ext = p->u.pNext
b4b0: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 2d 3e  ;.    }..    p->
b4c0: 75 2e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20  u.pNext = 0;.   
b4d0: 20 66 6f 72 28 69 3d 30 3b 20 61 53 6c 6f 74 5b   for(i=0; aSlot[
b4e0: 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  i]; i++){.      
b4f0: 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28  vdbeSorterMerge(
b500: 70 54 61 73 6b 2c 20 70 2c 20 61 53 6c 6f 74 5b  pTask, p, aSlot[
b510: 69 5d 2c 20 26 70 29 3b 0a 20 20 20 20 20 20 61  i], &p);.      a
b520: 53 6c 6f 74 5b 69 5d 20 3d 20 30 3b 0a 20 20 20  Slot[i] = 0;.   
b530: 20 7d 0a 20 20 20 20 61 53 6c 6f 74 5b 69 5d 20   }.    aSlot[i] 
b540: 3d 20 70 3b 0a 20 20 20 20 70 20 3d 20 70 4e 65  = p;.    p = pNe
b550: 78 74 3b 0a 20 20 7d 0a 0a 20 20 70 20 3d 20 30  xt;.  }..  p = 0
b560: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 36  ;.  for(i=0; i<6
b570: 34 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 76 64 62  4; i++){.    vdb
b580: 65 53 6f 72 74 65 72 4d 65 72 67 65 28 70 54 61  eSorterMerge(pTa
b590: 73 6b 2c 20 70 2c 20 61 53 6c 6f 74 5b 69 5d 2c  sk, p, aSlot[i],
b5a0: 20 26 70 29 3b 0a 20 20 7d 0a 20 20 70 4c 69 73   &p);.  }.  pLis
b5b0: 74 2d 3e 70 4c 69 73 74 20 3d 20 70 3b 0a 0a 20  t->pList = p;.. 
b5c0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 53   sqlite3_free(aS
b5d0: 6c 6f 74 29 3b 0a 20 20 61 73 73 65 72 74 28 20  lot);.  assert( 
b5e0: 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64  pTask->pUnpacked
b5f0: 2d 3e 65 72 72 43 6f 64 65 3d 3d 53 51 4c 49 54  ->errCode==SQLIT
b600: 45 5f 4f 4b 20 0a 20 20 20 20 20 20 20 7c 7c 20  E_OK .       || 
b610: 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64  pTask->pUnpacked
b620: 2d 3e 65 72 72 43 6f 64 65 3d 3d 53 51 4c 49 54  ->errCode==SQLIT
b630: 45 5f 4e 4f 4d 45 4d 20 0a 20 20 29 3b 0a 20 20  E_NOMEM .  );.  
b640: 72 65 74 75 72 6e 20 70 54 61 73 6b 2d 3e 70 55  return pTask->pU
b650: 6e 70 61 63 6b 65 64 2d 3e 65 72 72 43 6f 64 65  npacked->errCode
b660: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69  ;.}../*.** Initi
b670: 61 6c 69 7a 65 20 61 20 50 4d 41 2d 77 72 69 74  alize a PMA-writ
b680: 65 72 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74  er object..*/.st
b690: 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 50 6d  atic void vdbePm
b6a0: 61 57 72 69 74 65 72 49 6e 69 74 28 0a 20 20 73  aWriterInit(.  s
b6b0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
b6c0: 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  le,            /
b6d0: 2a 20 46 69 6c 65 20 74 6f 20 77 72 69 74 65 20  * File to write 
b6e0: 74 6f 20 2a 2f 0a 20 20 50 6d 61 57 72 69 74 65  to */.  PmaWrite
b6f0: 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20  r *p,           
b700: 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63          /* Objec
b710: 74 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f  t to populate */
b720: 0a 20 20 69 6e 74 20 6e 42 75 66 2c 20 20 20 20  .  int nBuf,    
b730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b740: 20 20 20 2f 2a 20 42 75 66 66 65 72 20 73 69 7a     /* Buffer siz
b750: 65 20 2a 2f 0a 20 20 69 36 34 20 69 53 74 61 72  e */.  i64 iStar
b760: 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t               
b770: 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74         /* Offset
b780: 20 6f 66 20 70 46 69 6c 65 20 74 6f 20 62 65 67   of pFile to beg
b790: 69 6e 20 77 72 69 74 69 6e 67 20 61 74 20 2a 2f  in writing at */
b7a0: 0a 29 7b 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20  .){.  memset(p, 
b7b0: 30 2c 20 73 69 7a 65 6f 66 28 50 6d 61 57 72 69  0, sizeof(PmaWri
b7c0: 74 65 72 29 29 3b 0a 20 20 70 2d 3e 61 42 75 66  ter));.  p->aBuf
b7d0: 66 65 72 20 3d 20 28 75 38 2a 29 73 71 6c 69 74  fer = (u8*)sqlit
b7e0: 65 33 4d 61 6c 6c 6f 63 28 6e 42 75 66 29 3b 0a  e3Malloc(nBuf);.
b7f0: 20 20 69 66 28 20 21 70 2d 3e 61 42 75 66 66 65    if( !p->aBuffe
b800: 72 20 29 7b 0a 20 20 20 20 70 2d 3e 65 46 57 45  r ){.    p->eFWE
b810: 72 72 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rr = SQLITE_NOME
b820: 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  M;.  }else{.    
b830: 70 2d 3e 69 42 75 66 45 6e 64 20 3d 20 70 2d 3e  p->iBufEnd = p->
b840: 69 42 75 66 53 74 61 72 74 20 3d 20 28 69 53 74  iBufStart = (iSt
b850: 61 72 74 20 25 20 6e 42 75 66 29 3b 0a 20 20 20  art % nBuf);.   
b860: 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20 3d 20   p->iWriteOff = 
b870: 69 53 74 61 72 74 20 2d 20 70 2d 3e 69 42 75 66  iStart - p->iBuf
b880: 53 74 61 72 74 3b 0a 20 20 20 20 70 2d 3e 6e 42  Start;.    p->nB
b890: 75 66 66 65 72 20 3d 20 6e 42 75 66 3b 0a 20 20  uffer = nBuf;.  
b8a0: 20 20 70 2d 3e 70 46 69 6c 65 20 3d 20 70 46 69    p->pFile = pFi
b8b0: 6c 65 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  le;.  }.}../*.**
b8c0: 20 57 72 69 74 65 20 6e 44 61 74 61 20 62 79 74   Write nData byt
b8d0: 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 74 68  es of data to th
b8e0: 65 20 50 4d 41 2e 20 52 65 74 75 72 6e 20 53 51  e PMA. Return SQ
b8f0: 4c 49 54 45 5f 4f 4b 0a 2a 2a 20 69 66 20 73 75  LITE_OK.** if su
b900: 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20  ccessful, or an 
b910: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
b920: 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  e if an error oc
b930: 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  curs..*/.static 
b940: 76 6f 69 64 20 76 64 62 65 50 6d 61 57 72 69 74  void vdbePmaWrit
b950: 65 42 6c 6f 62 28 50 6d 61 57 72 69 74 65 72 20  eBlob(PmaWriter 
b960: 2a 70 2c 20 75 38 20 2a 70 44 61 74 61 2c 20 69  *p, u8 *pData, i
b970: 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20 69 6e 74  nt nData){.  int
b980: 20 6e 52 65 6d 20 3d 20 6e 44 61 74 61 3b 0a 20   nRem = nData;. 
b990: 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30 20 26   while( nRem>0 &
b9a0: 26 20 70 2d 3e 65 46 57 45 72 72 3d 3d 30 20 29  & p->eFWErr==0 )
b9b0: 7b 0a 20 20 20 20 69 6e 74 20 6e 43 6f 70 79 20  {.    int nCopy 
b9c0: 3d 20 6e 52 65 6d 3b 0a 20 20 20 20 69 66 28 20  = nRem;.    if( 
b9d0: 6e 43 6f 70 79 3e 28 70 2d 3e 6e 42 75 66 66 65  nCopy>(p->nBuffe
b9e0: 72 20 2d 20 70 2d 3e 69 42 75 66 45 6e 64 29 20  r - p->iBufEnd) 
b9f0: 29 7b 0a 20 20 20 20 20 20 6e 43 6f 70 79 20 3d  ){.      nCopy =
ba00: 20 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 70 2d   p->nBuffer - p-
ba10: 3e 69 42 75 66 45 6e 64 3b 0a 20 20 20 20 7d 0a  >iBufEnd;.    }.
ba20: 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d 3e  .    memcpy(&p->
ba30: 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 45  aBuffer[p->iBufE
ba40: 6e 64 5d 2c 20 26 70 44 61 74 61 5b 6e 44 61 74  nd], &pData[nDat
ba50: 61 2d 6e 52 65 6d 5d 2c 20 6e 43 6f 70 79 29 3b  a-nRem], nCopy);
ba60: 0a 20 20 20 20 70 2d 3e 69 42 75 66 45 6e 64 20  .    p->iBufEnd 
ba70: 2b 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 69 66  += nCopy;.    if
ba80: 28 20 70 2d 3e 69 42 75 66 45 6e 64 3d 3d 70 2d  ( p->iBufEnd==p-
ba90: 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20  >nBuffer ){.    
baa0: 20 20 70 2d 3e 65 46 57 45 72 72 20 3d 20 73 71    p->eFWErr = sq
bab0: 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d 3e  lite3OsWrite(p->
bac0: 70 46 69 6c 65 2c 20 0a 20 20 20 20 20 20 20 20  pFile, .        
bad0: 20 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 70 2d    &p->aBuffer[p-
bae0: 3e 69 42 75 66 53 74 61 72 74 5d 2c 20 70 2d 3e  >iBufStart], p->
baf0: 69 42 75 66 45 6e 64 20 2d 20 70 2d 3e 69 42 75  iBufEnd - p->iBu
bb00: 66 53 74 61 72 74 2c 20 0a 20 20 20 20 20 20 20  fStart, .       
bb10: 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20     p->iWriteOff 
bb20: 2b 20 70 2d 3e 69 42 75 66 53 74 61 72 74 0a 20  + p->iBufStart. 
bb30: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 70 2d       );.      p-
bb40: 3e 69 42 75 66 53 74 61 72 74 20 3d 20 70 2d 3e  >iBufStart = p->
bb50: 69 42 75 66 45 6e 64 20 3d 20 30 3b 0a 20 20 20  iBufEnd = 0;.   
bb60: 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20     p->iWriteOff 
bb70: 2b 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20  += p->nBuffer;. 
bb80: 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28     }.    assert(
bb90: 20 70 2d 3e 69 42 75 66 45 6e 64 3c 70 2d 3e 6e   p->iBufEnd<p->n
bba0: 42 75 66 66 65 72 20 29 3b 0a 0a 20 20 20 20 6e  Buffer );..    n
bbb0: 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20  Rem -= nCopy;.  
bbc0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68  }.}../*.** Flush
bbd0: 20 61 6e 79 20 62 75 66 66 65 72 65 64 20 64 61   any buffered da
bbe0: 74 61 20 74 6f 20 64 69 73 6b 20 61 6e 64 20 63  ta to disk and c
bbf0: 6c 65 61 6e 20 75 70 20 74 68 65 20 50 4d 41 2d  lean up the PMA-
bc00: 77 72 69 74 65 72 20 6f 62 6a 65 63 74 2e 0a 2a  writer object..*
bc10: 2a 20 54 68 65 20 72 65 73 75 6c 74 73 20 6f 66  * The results of
bc20: 20 75 73 69 6e 67 20 74 68 65 20 50 4d 41 2d 77   using the PMA-w
bc30: 72 69 74 65 72 20 61 66 74 65 72 20 74 68 69 73  riter after this
bc40: 20 63 61 6c 6c 20 61 72 65 20 75 6e 64 65 66 69   call are undefi
bc50: 6e 65 64 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 53  ned..** Return S
bc60: 51 4c 49 54 45 5f 4f 4b 20 69 66 20 66 6c 75 73  QLITE_OK if flus
bc70: 68 69 6e 67 20 74 68 65 20 62 75 66 66 65 72 65  hing the buffere
bc80: 64 20 64 61 74 61 20 73 75 63 63 65 65 64 73 20  d data succeeds 
bc90: 6f 72 20 69 73 20 6e 6f 74 20 0a 2a 2a 20 72 65  or is not .** re
bca0: 71 75 69 72 65 64 2e 20 4f 74 68 65 72 77 69 73  quired. Otherwis
bcb0: 65 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c  e, return an SQL
bcc0: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a  ite error code..
bcd0: 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65 20 72 65 74  **.** Before ret
bce0: 75 72 6e 69 6e 67 2c 20 73 65 74 20 2a 70 69 45  urning, set *piE
bcf0: 6f 66 20 74 6f 20 74 68 65 20 6f 66 66 73 65 74  of to the offset
bd00: 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c   immediately fol
bd10: 6c 6f 77 69 6e 67 20 74 68 65 0a 2a 2a 20 6c 61  lowing the.** la
bd20: 73 74 20 62 79 74 65 20 77 72 69 74 74 65 6e 20  st byte written 
bd30: 74 6f 20 74 68 65 20 66 69 6c 65 2e 0a 2a 2f 0a  to the file..*/.
bd40: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 50  static int vdbeP
bd50: 6d 61 57 72 69 74 65 72 46 69 6e 69 73 68 28 50  maWriterFinish(P
bd60: 6d 61 57 72 69 74 65 72 20 2a 70 2c 20 69 36 34  maWriter *p, i64
bd70: 20 2a 70 69 45 6f 66 29 7b 0a 20 20 69 6e 74 20   *piEof){.  int 
bd80: 72 63 3b 0a 20 20 69 66 28 20 70 2d 3e 65 46 57  rc;.  if( p->eFW
bd90: 45 72 72 3d 3d 30 20 26 26 20 41 4c 57 41 59 53  Err==0 && ALWAYS
bda0: 28 70 2d 3e 61 42 75 66 66 65 72 29 20 26 26 20  (p->aBuffer) && 
bdb0: 70 2d 3e 69 42 75 66 45 6e 64 3e 70 2d 3e 69 42  p->iBufEnd>p->iB
bdc0: 75 66 53 74 61 72 74 20 29 7b 0a 20 20 20 20 70  ufStart ){.    p
bdd0: 2d 3e 65 46 57 45 72 72 20 3d 20 73 71 6c 69 74  ->eFWErr = sqlit
bde0: 65 33 4f 73 57 72 69 74 65 28 70 2d 3e 70 46 69  e3OsWrite(p->pFi
bdf0: 6c 65 2c 20 0a 20 20 20 20 20 20 20 20 26 70 2d  le, .        &p-
be00: 3e 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66  >aBuffer[p->iBuf
be10: 53 74 61 72 74 5d 2c 20 70 2d 3e 69 42 75 66 45  Start], p->iBufE
be20: 6e 64 20 2d 20 70 2d 3e 69 42 75 66 53 74 61 72  nd - p->iBufStar
be30: 74 2c 20 0a 20 20 20 20 20 20 20 20 70 2d 3e 69  t, .        p->i
be40: 57 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42  WriteOff + p->iB
be50: 75 66 53 74 61 72 74 0a 20 20 20 20 29 3b 0a 20  ufStart.    );. 
be60: 20 7d 0a 20 20 2a 70 69 45 6f 66 20 3d 20 28 70   }.  *piEof = (p
be70: 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b 20 70 2d  ->iWriteOff + p-
be80: 3e 69 42 75 66 45 6e 64 29 3b 0a 20 20 73 71 6c  >iBufEnd);.  sql
be90: 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 42 75  ite3_free(p->aBu
bea0: 66 66 65 72 29 3b 0a 20 20 72 63 20 3d 20 70 2d  ffer);.  rc = p-
beb0: 3e 65 46 57 45 72 72 3b 0a 20 20 6d 65 6d 73 65  >eFWErr;.  memse
bec0: 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50  t(p, 0, sizeof(P
bed0: 6d 61 57 72 69 74 65 72 29 29 3b 0a 20 20 72 65  maWriter));.  re
bee0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
bef0: 2a 20 57 72 69 74 65 20 76 61 6c 75 65 20 69 56  * Write value iV
bf00: 61 6c 20 65 6e 63 6f 64 65 64 20 61 73 20 61 20  al encoded as a 
bf10: 76 61 72 69 6e 74 20 74 6f 20 74 68 65 20 50 4d  varint to the PM
bf20: 41 2e 20 52 65 74 75 72 6e 20 0a 2a 2a 20 53 51  A. Return .** SQ
bf30: 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65  LITE_OK if succe
bf40: 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c  ssful, or an SQL
bf50: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69  ite error code i
bf60: 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
bf70: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  s..*/.static voi
bf80: 64 20 76 64 62 65 50 6d 61 57 72 69 74 65 56 61  d vdbePmaWriteVa
bf90: 72 69 6e 74 28 50 6d 61 57 72 69 74 65 72 20 2a  rint(PmaWriter *
bfa0: 70 2c 20 75 36 34 20 69 56 61 6c 29 7b 0a 20 20  p, u64 iVal){.  
bfb0: 69 6e 74 20 6e 42 79 74 65 3b 20 0a 20 20 75 38  int nByte; .  u8
bfc0: 20 61 42 79 74 65 5b 31 30 5d 3b 0a 20 20 6e 42   aByte[10];.  nB
bfd0: 79 74 65 20 3d 20 73 71 6c 69 74 65 33 50 75 74  yte = sqlite3Put
bfe0: 56 61 72 69 6e 74 28 61 42 79 74 65 2c 20 69 56  Varint(aByte, iV
bff0: 61 6c 29 3b 0a 20 20 76 64 62 65 50 6d 61 57 72  al);.  vdbePmaWr
c000: 69 74 65 42 6c 6f 62 28 70 2c 20 61 42 79 74 65  iteBlob(p, aByte
c010: 2c 20 6e 42 79 74 65 29 3b 0a 7d 0a 0a 2f 2a 0a  , nByte);.}../*.
c020: 2a 2a 20 57 72 69 74 65 20 74 68 65 20 63 75 72  ** Write the cur
c030: 72 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f 66  rent contents of
c040: 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 6e 6b 65   in-memory linke
c050: 64 2d 6c 69 73 74 20 70 4c 69 73 74 20 74 6f 20  d-list pList to 
c060: 61 20 6c 65 76 65 6c 2d 30 0a 2a 2a 20 50 4d 41  a level-0.** PMA
c070: 20 69 6e 20 74 68 65 20 74 65 6d 70 20 66 69 6c   in the temp fil
c080: 65 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 73  e belonging to s
c090: 75 62 2d 74 61 73 6b 20 70 54 61 73 6b 2e 20 52  ub-task pTask. R
c0a0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20  eturn SQLITE_OK 
c0b0: 69 66 20 0a 2a 2a 20 73 75 63 63 65 73 73 66 75  if .** successfu
c0c0: 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20  l, or an SQLite 
c0d0: 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72  error code other
c0e0: 77 69 73 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  wise..**.** The 
c0f0: 66 6f 72 6d 61 74 20 6f 66 20 61 20 50 4d 41 20  format of a PMA 
c100: 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20  is:.**.**     * 
c110: 41 20 76 61 72 69 6e 74 2e 20 54 68 69 73 20 76  A varint. This v
c120: 61 72 69 6e 74 20 63 6f 6e 74 61 69 6e 73 20 74  arint contains t
c130: 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20  he total number 
c140: 6f 66 20 62 79 74 65 73 20 6f 66 20 63 6f 6e 74  of bytes of cont
c150: 65 6e 74 0a 2a 2a 20 20 20 20 20 20 20 69 6e 20  ent.**       in 
c160: 74 68 65 20 50 4d 41 20 28 6e 6f 74 20 69 6e 63  the PMA (not inc
c170: 6c 75 64 69 6e 67 20 74 68 65 20 76 61 72 69 6e  luding the varin
c180: 74 20 69 74 73 65 6c 66 29 2e 0a 2a 2a 0a 2a 2a  t itself)..**.**
c190: 20 20 20 20 20 2a 20 4f 6e 65 20 6f 72 20 6d 6f       * One or mo
c1a0: 72 65 20 72 65 63 6f 72 64 73 20 70 61 63 6b 65  re records packe
c1b0: 64 20 65 6e 64 2d 74 6f 2d 65 6e 64 20 69 6e 20  d end-to-end in 
c1c0: 6f 72 64 65 72 20 6f 66 20 61 73 63 65 6e 64 69  order of ascendi
c1d0: 6e 67 20 6b 65 79 73 2e 20 0a 2a 2a 20 20 20 20  ng keys. .**    
c1e0: 20 20 20 45 61 63 68 20 72 65 63 6f 72 64 20 63     Each record c
c1f0: 6f 6e 73 69 73 74 73 20 6f 66 20 61 20 76 61 72  onsists of a var
c200: 69 6e 74 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20  int followed by 
c210: 61 20 62 6c 6f 62 20 6f 66 20 64 61 74 61 20 28  a blob of data (
c220: 74 68 65 20 0a 2a 2a 20 20 20 20 20 20 20 6b 65  the .**       ke
c230: 79 29 2e 20 54 68 65 20 76 61 72 69 6e 74 20 69  y). The varint i
c240: 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  s the number of 
c250: 62 79 74 65 73 20 69 6e 20 74 68 65 20 62 6c 6f  bytes in the blo
c260: 62 20 6f 66 20 64 61 74 61 2e 0a 2a 2f 0a 73 74  b of data..*/.st
c270: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
c280: 74 65 72 4c 69 73 74 54 6f 50 4d 41 28 53 6f 72  terListToPMA(Sor
c290: 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c  tSubtask *pTask,
c2a0: 20 53 6f 72 74 65 72 4c 69 73 74 20 2a 70 4c 69   SorterList *pLi
c2b0: 73 74 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a  st){.  sqlite3 *
c2c0: 64 62 20 3d 20 70 54 61 73 6b 2d 3e 70 53 6f 72  db = pTask->pSor
c2d0: 74 65 72 2d 3e 64 62 3b 0a 20 20 69 6e 74 20 72  ter->db;.  int r
c2e0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20  c = SQLITE_OK;  
c2f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
c300: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 50  turn code */.  P
c310: 6d 61 57 72 69 74 65 72 20 77 72 69 74 65 72 3b  maWriter writer;
c320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c330: 2a 20 4f 62 6a 65 63 74 20 75 73 65 64 20 74 6f  * Object used to
c340: 20 77 72 69 74 65 20 74 6f 20 74 68 65 20 66 69   write to the fi
c350: 6c 65 20 2a 2f 0a 0a 23 69 66 64 65 66 20 53 51  le */..#ifdef SQ
c360: 4c 49 54 45 5f 44 45 42 55 47 0a 20 20 2f 2a 20  LITE_DEBUG.  /* 
c370: 53 65 74 20 69 53 7a 20 74 6f 20 74 68 65 20 65  Set iSz to the e
c380: 78 70 65 63 74 65 64 20 73 69 7a 65 20 6f 66 20  xpected size of 
c390: 66 69 6c 65 20 70 54 61 73 6b 2d 3e 66 69 6c 65  file pTask->file
c3a0: 20 61 66 74 65 72 20 77 72 69 74 69 6e 67 20 74   after writing t
c3b0: 68 65 20 50 4d 41 2e 20 0a 20 20 2a 2a 20 54 68  he PMA. .  ** Th
c3c0: 69 73 20 69 73 20 75 73 65 64 20 62 79 20 61 6e  is is used by an
c3d0: 20 61 73 73 65 72 74 28 29 20 73 74 61 74 65 6d   assert() statem
c3e0: 65 6e 74 20 61 74 20 74 68 65 20 65 6e 64 20 6f  ent at the end o
c3f0: 66 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 2e  f this function.
c400: 20 20 2a 2f 0a 20 20 69 36 34 20 69 53 7a 20 3d    */.  i64 iSz =
c410: 20 70 4c 69 73 74 2d 3e 73 7a 50 4d 41 20 2b 20   pList->szPMA + 
c420: 73 71 6c 69 74 65 33 56 61 72 69 6e 74 4c 65 6e  sqlite3VarintLen
c430: 28 70 4c 69 73 74 2d 3e 73 7a 50 4d 41 29 20 2b  (pList->szPMA) +
c440: 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f   pTask->file.iEo
c450: 66 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 76 64 62  f;.#endif..  vdb
c460: 65 53 6f 72 74 65 72 57 6f 72 6b 44 65 62 75 67  eSorterWorkDebug
c470: 28 70 54 61 73 6b 2c 20 22 65 6e 74 65 72 22 29  (pTask, "enter")
c480: 3b 0a 20 20 6d 65 6d 73 65 74 28 26 77 72 69 74  ;.  memset(&writ
c490: 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50 6d  er, 0, sizeof(Pm
c4a0: 61 57 72 69 74 65 72 29 29 3b 0a 20 20 61 73 73  aWriter));.  ass
c4b0: 65 72 74 28 20 70 4c 69 73 74 2d 3e 73 7a 50 4d  ert( pList->szPM
c4c0: 41 3e 30 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20  A>0 );..  /* If 
c4d0: 74 68 65 20 66 69 72 73 74 20 74 65 6d 70 6f 72  the first tempor
c4e0: 61 72 79 20 50 4d 41 20 66 69 6c 65 20 68 61 73  ary PMA file has
c4f0: 20 6e 6f 74 20 62 65 65 6e 20 6f 70 65 6e 65 64   not been opened
c500: 2c 20 6f 70 65 6e 20 69 74 20 6e 6f 77 2e 20 2a  , open it now. *
c510: 2f 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 66  /.  if( pTask->f
c520: 69 6c 65 2e 70 46 64 3d 3d 30 20 29 7b 0a 20 20  ile.pFd==0 ){.  
c530: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
c540: 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 64 62  rOpenTempFile(db
c550: 2c 20 30 2c 20 26 70 54 61 73 6b 2d 3e 66 69 6c  , 0, &pTask->fil
c560: 65 2e 70 46 64 29 3b 0a 20 20 20 20 61 73 73 65  e.pFd);.    asse
c570: 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  rt( rc!=SQLITE_O
c580: 4b 20 7c 7c 20 70 54 61 73 6b 2d 3e 66 69 6c 65  K || pTask->file
c590: 2e 70 46 64 20 29 3b 0a 20 20 20 20 61 73 73 65  .pFd );.    asse
c5a0: 72 74 28 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e  rt( pTask->file.
c5b0: 69 45 6f 66 3d 3d 30 20 29 3b 0a 20 20 20 20 61  iEof==0 );.    a
c5c0: 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 6e 50  ssert( pTask->nP
c5d0: 4d 41 3d 3d 30 20 29 3b 0a 20 20 7d 0a 0a 20 20  MA==0 );.  }..  
c5e0: 2f 2a 20 54 72 79 20 74 6f 20 67 65 74 20 74 68  /* Try to get th
c5f0: 65 20 66 69 6c 65 20 74 6f 20 6d 65 6d 6f 72 79  e file to memory
c600: 20 6d 61 70 20 2a 2f 0a 20 20 69 66 28 20 72 63   map */.  if( rc
c610: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
c620: 20 20 20 76 64 62 65 53 6f 72 74 65 72 45 78 74     vdbeSorterExt
c630: 65 6e 64 46 69 6c 65 28 64 62 2c 20 70 54 61 73  endFile(db, pTas
c640: 6b 2d 3e 66 69 6c 65 2e 70 46 64 2c 20 70 54 61  k->file.pFd, pTa
c650: 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 2b 70 4c  sk->file.iEof+pL
c660: 69 73 74 2d 3e 73 7a 50 4d 41 2b 39 29 3b 0a 20  ist->szPMA+9);. 
c670: 20 7d 0a 0a 20 20 2f 2a 20 53 6f 72 74 20 74 68   }..  /* Sort th
c680: 65 20 6c 69 73 74 20 2a 2f 0a 20 20 69 66 28 20  e list */.  if( 
c690: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
c6a0: 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f  .    rc = vdbeSo
c6b0: 72 74 65 72 53 6f 72 74 28 70 54 61 73 6b 2c 20  rterSort(pTask, 
c6c0: 70 4c 69 73 74 29 3b 0a 20 20 7d 0a 0a 20 20 69  pList);.  }..  i
c6d0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
c6e0: 20 29 7b 0a 20 20 20 20 53 6f 72 74 65 72 52 65   ){.    SorterRe
c6f0: 63 6f 72 64 20 2a 70 3b 0a 20 20 20 20 53 6f 72  cord *p;.    Sor
c700: 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65 78 74  terRecord *pNext
c710: 20 3d 20 30 3b 0a 0a 20 20 20 20 76 64 62 65 50   = 0;..    vdbeP
c720: 6d 61 57 72 69 74 65 72 49 6e 69 74 28 70 54 61  maWriterInit(pTa
c730: 73 6b 2d 3e 66 69 6c 65 2e 70 46 64 2c 20 26 77  sk->file.pFd, &w
c740: 72 69 74 65 72 2c 20 70 54 61 73 6b 2d 3e 70 53  riter, pTask->pS
c750: 6f 72 74 65 72 2d 3e 70 67 73 7a 2c 0a 20 20 20  orter->pgsz,.   
c760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c770: 20 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69     pTask->file.i
c780: 45 6f 66 29 3b 0a 20 20 20 20 70 54 61 73 6b 2d  Eof);.    pTask-
c790: 3e 6e 50 4d 41 2b 2b 3b 0a 20 20 20 20 76 64 62  >nPMA++;.    vdb
c7a0: 65 50 6d 61 57 72 69 74 65 56 61 72 69 6e 74 28  ePmaWriteVarint(
c7b0: 26 77 72 69 74 65 72 2c 20 70 4c 69 73 74 2d 3e  &writer, pList->
c7c0: 73 7a 50 4d 41 29 3b 0a 20 20 20 20 66 6f 72 28  szPMA);.    for(
c7d0: 70 3d 70 4c 69 73 74 2d 3e 70 4c 69 73 74 3b 20  p=pList->pList; 
c7e0: 70 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20  p; p=pNext){.   
c7f0: 20 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e 75 2e     pNext = p->u.
c800: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 76 64 62  pNext;.      vdb
c810: 65 50 6d 61 57 72 69 74 65 56 61 72 69 6e 74 28  ePmaWriteVarint(
c820: 26 77 72 69 74 65 72 2c 20 70 2d 3e 6e 56 61 6c  &writer, p->nVal
c830: 29 3b 0a 20 20 20 20 20 20 76 64 62 65 50 6d 61  );.      vdbePma
c840: 57 72 69 74 65 42 6c 6f 62 28 26 77 72 69 74 65  WriteBlob(&write
c850: 72 2c 20 53 52 56 41 4c 28 70 29 2c 20 70 2d 3e  r, SRVAL(p), p->
c860: 6e 56 61 6c 29 3b 0a 20 20 20 20 20 20 69 66 28  nVal);.      if(
c870: 20 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f 72 79 3d   pList->aMemory=
c880: 3d 30 20 29 20 73 71 6c 69 74 65 33 5f 66 72 65  =0 ) sqlite3_fre
c890: 65 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  e(p);.    }.    
c8a0: 70 4c 69 73 74 2d 3e 70 4c 69 73 74 20 3d 20 70  pList->pList = p
c8b0: 3b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 50  ;.    rc = vdbeP
c8c0: 6d 61 57 72 69 74 65 72 46 69 6e 69 73 68 28 26  maWriterFinish(&
c8d0: 77 72 69 74 65 72 2c 20 26 70 54 61 73 6b 2d 3e  writer, &pTask->
c8e0: 66 69 6c 65 2e 69 45 6f 66 29 3b 0a 20 20 7d 0a  file.iEof);.  }.
c8f0: 0a 20 20 76 64 62 65 53 6f 72 74 65 72 57 6f 72  .  vdbeSorterWor
c900: 6b 44 65 62 75 67 28 70 54 61 73 6b 2c 20 22 65  kDebug(pTask, "e
c910: 78 69 74 22 29 3b 0a 20 20 61 73 73 65 72 74 28  xit");.  assert(
c920: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c   rc!=SQLITE_OK |
c930: 7c 20 70 4c 69 73 74 2d 3e 70 4c 69 73 74 3d 3d  | pList->pList==
c940: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 72  0 );.  assert( r
c950: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20  c!=SQLITE_OK || 
c960: 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66  pTask->file.iEof
c970: 3d 3d 69 53 7a 20 29 3b 0a 20 20 72 65 74 75 72  ==iSz );.  retur
c980: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  n rc;.}../*.** A
c990: 64 76 61 6e 63 65 20 74 68 65 20 4d 65 72 67 65  dvance the Merge
c9a0: 45 6e 67 69 6e 65 20 50 6d 61 52 65 61 64 65 72  Engine PmaReader
c9b0: 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 73   passed as the s
c9c0: 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 74  econd argument t
c9d0: 6f 0a 2a 2a 20 74 68 65 20 6e 65 78 74 20 65 6e  o.** the next en
c9e0: 74 72 79 2e 20 53 65 74 20 2a 70 62 45 6f 66 20  try. Set *pbEof 
c9f0: 74 6f 20 74 72 75 65 20 69 66 20 74 68 69 73 20  to true if this 
ca00: 6d 65 61 6e 73 20 74 68 65 20 50 6d 61 52 65 61  means the PmaRea
ca10: 64 65 72 20 68 61 73 20 0a 2a 2a 20 72 65 61 63  der has .** reac
ca20: 68 65 64 20 45 4f 46 2e 0a 2a 2a 0a 2a 2a 20 52  hed EOF..**.** R
ca30: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20  eturn SQLITE_OK 
ca40: 69 66 20 73 75 63 63 65 73 73 66 75 6c 20 6f 72  if successful or
ca50: 20 61 6e 20 65 72 72 6f 72 20 63 6f 64 65 20 69   an error code i
ca60: 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
ca70: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  s..*/.static int
ca80: 20 76 64 62 65 53 6f 72 74 65 72 4e 65 78 74 28   vdbeSorterNext(
ca90: 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a  .  SortSubtask *
caa0: 70 54 61 73 6b 2c 20 0a 20 20 4d 65 72 67 65 45  pTask, .  MergeE
cab0: 6e 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 2c 20  ngine *pMerger, 
cac0: 0a 20 20 69 6e 74 20 2a 70 62 45 6f 66 0a 29 7b  .  int *pbEof.){
cad0: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74  .  int rc;.  int
cae0: 20 69 50 72 65 76 20 3d 20 70 4d 65 72 67 65 72   iPrev = pMerger
caf0: 2d 3e 61 54 72 65 65 5b 31 5d 3b 2f 2a 20 49 6e  ->aTree[1];/* In
cb00: 64 65 78 20 6f 66 20 50 6d 61 52 65 61 64 65 72  dex of PmaReader
cb10: 20 74 6f 20 61 64 76 61 6e 63 65 20 2a 2f 0a 0a   to advance */..
cb20: 20 20 2f 2a 20 41 64 76 61 6e 63 65 20 74 68 65    /* Advance the
cb30: 20 63 75 72 72 65 6e 74 20 50 6d 61 52 65 61 64   current PmaRead
cb40: 65 72 20 2a 2f 0a 20 20 72 63 20 3d 20 76 64 62  er */.  rc = vdb
cb50: 65 50 6d 61 52 65 61 64 65 72 4e 65 78 74 28 26  ePmaReaderNext(&
cb60: 70 4d 65 72 67 65 72 2d 3e 61 52 65 61 64 72 5b  pMerger->aReadr[
cb70: 69 50 72 65 76 5d 29 3b 0a 0a 20 20 2f 2a 20 55  iPrev]);..  /* U
cb80: 70 64 61 74 65 20 63 6f 6e 74 65 6e 74 73 20 6f  pdate contents o
cb90: 66 20 61 54 72 65 65 5b 5d 20 2a 2f 0a 20 20 69  f aTree[] */.  i
cba0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
cbb0: 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b 20 20   ){.    int i;  
cbc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cbd0: 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20      /* Index of 
cbe0: 61 54 72 65 65 5b 5d 20 74 6f 20 72 65 63 61 6c  aTree[] to recal
cbf0: 63 75 6c 61 74 65 20 2a 2f 0a 20 20 20 20 50 6d  culate */.    Pm
cc00: 61 52 65 61 64 65 72 20 2a 70 52 65 61 64 72 31  aReader *pReadr1
cc10: 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72  ;         /* Fir
cc20: 73 74 20 50 6d 61 52 65 61 64 65 72 20 74 6f 20  st PmaReader to 
cc30: 63 6f 6d 70 61 72 65 20 2a 2f 0a 20 20 20 20 50  compare */.    P
cc40: 6d 61 52 65 61 64 65 72 20 2a 70 52 65 61 64 72  maReader *pReadr
cc50: 32 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65  2;         /* Se
cc60: 63 6f 6e 64 20 50 6d 61 52 65 61 64 65 72 20 74  cond PmaReader t
cc70: 6f 20 63 6f 6d 70 61 72 65 20 2a 2f 0a 20 20 20  o compare */.   
cc80: 20 75 38 20 2a 70 4b 65 79 32 3b 20 20 20 20 20   u8 *pKey2;     
cc90: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
cca0: 54 6f 20 70 52 65 61 64 72 32 2d 3e 61 4b 65 79  To pReadr2->aKey
ccb0: 2c 20 6f 72 20 30 20 69 66 20 72 65 63 6f 72 64  , or 0 if record
ccc0: 20 63 61 63 68 65 64 20 2a 2f 0a 0a 20 20 20 20   cached */..    
ccd0: 2f 2a 20 46 69 6e 64 20 74 68 65 20 66 69 72 73  /* Find the firs
cce0: 74 20 74 77 6f 20 50 6d 61 52 65 61 64 65 72 73  t two PmaReaders
ccf0: 20 74 6f 20 63 6f 6d 70 61 72 65 2e 20 54 68 65   to compare. The
cd00: 20 6f 6e 65 20 74 68 61 74 20 77 61 73 20 6a 75   one that was ju
cd10: 73 74 0a 20 20 20 20 2a 2a 20 61 64 76 61 6e 63  st.    ** advanc
cd20: 65 64 20 28 69 50 72 65 76 29 20 61 6e 64 20 74  ed (iPrev) and t
cd30: 68 65 20 6f 6e 65 20 6e 65 78 74 20 74 6f 20 69  he one next to i
cd40: 74 20 69 6e 20 74 68 65 20 61 72 72 61 79 2e 20  t in the array. 
cd50: 20 2a 2f 0a 20 20 20 20 70 52 65 61 64 72 31 20   */.    pReadr1 
cd60: 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 52 65 61  = &pMerger->aRea
cd70: 64 72 5b 28 69 50 72 65 76 20 26 20 30 78 46 46  dr[(iPrev & 0xFF
cd80: 46 45 29 5d 3b 0a 20 20 20 20 70 52 65 61 64 72  FE)];.    pReadr
cd90: 32 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 52  2 = &pMerger->aR
cda0: 65 61 64 72 5b 28 69 50 72 65 76 20 7c 20 30 78  eadr[(iPrev | 0x
cdb0: 30 30 30 31 29 5d 3b 0a 20 20 20 20 70 4b 65 79  0001)];.    pKey
cdc0: 32 20 3d 20 70 52 65 61 64 72 32 2d 3e 61 4b 65  2 = pReadr2->aKe
cdd0: 79 3b 0a 0a 20 20 20 20 66 6f 72 28 69 3d 28 70  y;..    for(i=(p
cde0: 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65 2b 69 50  Merger->nTree+iP
cdf0: 72 65 76 29 2f 32 3b 20 69 3e 30 3b 20 69 3d 69  rev)/2; i>0; i=i
ce00: 2f 32 29 7b 0a 20 20 20 20 20 20 2f 2a 20 43 6f  /2){.      /* Co
ce10: 6d 70 61 72 65 20 70 52 65 61 64 72 31 20 61 6e  mpare pReadr1 an
ce20: 64 20 70 52 65 61 64 72 32 2e 20 53 74 6f 72 65  d pReadr2. Store
ce30: 20 74 68 65 20 72 65 73 75 6c 74 20 69 6e 20 76   the result in v
ce40: 61 72 69 61 62 6c 65 20 69 52 65 73 2e 20 2a 2f  ariable iRes. */
ce50: 0a 20 20 20 20 20 20 69 6e 74 20 69 52 65 73 3b  .      int iRes;
ce60: 0a 20 20 20 20 20 20 69 66 28 20 70 52 65 61 64  .      if( pRead
ce70: 72 31 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a  r1->pFile==0 ){.
ce80: 20 20 20 20 20 20 20 20 69 52 65 73 20 3d 20 2b          iRes = +
ce90: 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69  1;.      }else i
cea0: 66 28 20 70 52 65 61 64 72 32 2d 3e 70 46 69 6c  f( pReadr2->pFil
ceb0: 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  e==0 ){.        
cec0: 69 52 65 73 20 3d 20 2d 31 3b 0a 20 20 20 20 20  iRes = -1;.     
ced0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
cee0: 69 52 65 73 20 3d 20 76 64 62 65 53 6f 72 74 65  iRes = vdbeSorte
cef0: 72 43 6f 6d 70 61 72 65 28 70 54 61 73 6b 2c 20  rCompare(pTask, 
cf00: 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 52 65  .            pRe
cf10: 61 64 72 31 2d 3e 61 4b 65 79 2c 20 70 52 65 61  adr1->aKey, pRea
cf20: 64 72 31 2d 3e 6e 4b 65 79 2c 20 70 4b 65 79 32  dr1->nKey, pKey2
cf30: 2c 20 70 52 65 61 64 72 32 2d 3e 6e 4b 65 79 0a  , pReadr2->nKey.
cf40: 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20          );.     
cf50: 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 49 66 20   }..      /* If 
cf60: 70 52 65 61 64 72 31 20 63 6f 6e 74 61 69 6e 65  pReadr1 containe
cf70: 64 20 74 68 65 20 73 6d 61 6c 6c 65 72 20 76 61  d the smaller va
cf80: 6c 75 65 2c 20 73 65 74 20 61 54 72 65 65 5b 69  lue, set aTree[i
cf90: 5d 20 74 6f 20 69 74 73 20 69 6e 64 65 78 2e 0a  ] to its index..
cfa0: 20 20 20 20 20 20 2a 2a 20 54 68 65 6e 20 73 65        ** Then se
cfb0: 74 20 70 52 65 61 64 72 32 20 74 6f 20 74 68 65  t pReadr2 to the
cfc0: 20 6e 65 78 74 20 50 6d 61 52 65 61 64 65 72 20   next PmaReader 
cfd0: 74 6f 20 63 6f 6d 70 61 72 65 20 74 6f 20 70 52  to compare to pR
cfe0: 65 61 64 72 31 2e 20 49 6e 20 74 68 69 73 0a 20  eadr1. In this. 
cff0: 20 20 20 20 20 2a 2a 20 63 61 73 65 20 74 68 65       ** case the
d000: 72 65 20 69 73 20 6e 6f 20 63 61 63 68 65 20 6f  re is no cache o
d010: 66 20 70 52 65 61 64 72 32 20 69 6e 20 70 54 61  f pReadr2 in pTa
d020: 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 2c 20 73  sk->pUnpacked, s
d030: 6f 20 73 65 74 0a 20 20 20 20 20 20 2a 2a 20 70  o set.      ** p
d040: 4b 65 79 32 20 74 6f 20 70 6f 69 6e 74 20 74 6f  Key2 to point to
d050: 20 74 68 65 20 72 65 63 6f 72 64 20 62 65 6c 6f   the record belo
d060: 6e 67 69 6e 67 20 74 6f 20 70 52 65 61 64 72 32  nging to pReadr2
d070: 2e 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20  ..      **.     
d080: 20 2a 2a 20 41 6c 74 65 72 6e 61 74 69 76 65 6c   ** Alternativel
d090: 79 2c 20 69 66 20 70 52 65 61 64 72 32 20 63 6f  y, if pReadr2 co
d0a0: 6e 74 61 69 6e 73 20 74 68 65 20 73 6d 61 6c 6c  ntains the small
d0b0: 65 72 20 6f 66 20 74 68 65 20 74 77 6f 20 76 61  er of the two va
d0c0: 6c 75 65 73 2c 0a 20 20 20 20 20 20 2a 2a 20 73  lues,.      ** s
d0d0: 65 74 20 61 54 72 65 65 5b 69 5d 20 74 6f 20 69  et aTree[i] to i
d0e0: 74 73 20 69 6e 64 65 78 20 61 6e 64 20 75 70 64  ts index and upd
d0f0: 61 74 65 20 70 52 65 61 64 72 31 2e 20 49 66 20  ate pReadr1. If 
d100: 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72  vdbeSorterCompar
d110: 65 28 29 0a 20 20 20 20 20 20 2a 2a 20 77 61 73  e().      ** was
d120: 20 61 63 74 75 61 6c 6c 79 20 63 61 6c 6c 65 64   actually called
d130: 20 61 62 6f 76 65 2c 20 74 68 65 6e 20 70 54 61   above, then pTa
d140: 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 20 6e 6f  sk->pUnpacked no
d150: 77 20 63 6f 6e 74 61 69 6e 73 0a 20 20 20 20 20  w contains.     
d160: 20 2a 2a 20 61 20 76 61 6c 75 65 20 65 71 75 69   ** a value equi
d170: 76 61 6c 65 6e 74 20 74 6f 20 70 52 65 61 64 72  valent to pReadr
d180: 32 2e 20 53 6f 20 73 65 74 20 70 4b 65 79 32 20  2. So set pKey2 
d190: 74 6f 20 4e 55 4c 4c 20 74 6f 20 70 72 65 76 65  to NULL to preve
d1a0: 6e 74 0a 20 20 20 20 20 20 2a 2a 20 76 64 62 65  nt.      ** vdbe
d1b0: 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 29 20  SorterCompare() 
d1c0: 66 72 6f 6d 20 64 65 63 6f 64 69 6e 67 20 70 52  from decoding pR
d1d0: 65 61 64 72 32 20 61 67 61 69 6e 2e 0a 20 20 20  eadr2 again..   
d1e0: 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 49     **.      ** I
d1f0: 66 20 74 68 65 20 74 77 6f 20 76 61 6c 75 65 73  f the two values
d200: 20 77 65 72 65 20 65 71 75 61 6c 2c 20 74 68 65   were equal, the
d210: 6e 20 74 68 65 20 76 61 6c 75 65 20 66 72 6f 6d  n the value from
d220: 20 74 68 65 20 6f 6c 64 65 73 74 0a 20 20 20 20   the oldest.    
d230: 20 20 2a 2a 20 50 4d 41 20 73 68 6f 75 6c 64 20    ** PMA should 
d240: 62 65 20 63 6f 6e 73 69 64 65 72 65 64 20 73 6d  be considered sm
d250: 61 6c 6c 65 72 2e 20 54 68 65 20 56 64 62 65 53  aller. The VdbeS
d260: 6f 72 74 65 72 2e 61 52 65 61 64 72 5b 5d 20 61  orter.aReadr[] a
d270: 72 72 61 79 0a 20 20 20 20 20 20 2a 2a 20 69 73  rray.      ** is
d280: 20 73 6f 72 74 65 64 20 66 72 6f 6d 20 6f 6c 64   sorted from old
d290: 65 73 74 20 74 6f 20 6e 65 77 65 73 74 2c 20 73  est to newest, s
d2a0: 6f 20 70 52 65 61 64 72 31 20 63 6f 6e 74 61 69  o pReadr1 contai
d2b0: 6e 73 20 6f 6c 64 65 72 20 76 61 6c 75 65 73 0a  ns older values.
d2c0: 20 20 20 20 20 20 2a 2a 20 74 68 61 6e 20 70 52        ** than pR
d2d0: 65 61 64 72 32 20 69 66 66 20 28 70 52 65 61 64  eadr2 iff (pRead
d2e0: 72 31 3c 70 52 65 61 64 72 32 29 2e 20 20 2a 2f  r1<pReadr2).  */
d2f0: 0a 20 20 20 20 20 20 69 66 28 20 69 52 65 73 3c  .      if( iRes<
d300: 30 20 7c 7c 20 28 69 52 65 73 3d 3d 30 20 26 26  0 || (iRes==0 &&
d310: 20 70 52 65 61 64 72 31 3c 70 52 65 61 64 72 32   pReadr1<pReadr2
d320: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 70 4d 65  ) ){.        pMe
d330: 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 5d 20 3d  rger->aTree[i] =
d340: 20 28 69 6e 74 29 28 70 52 65 61 64 72 31 20 2d   (int)(pReadr1 -
d350: 20 70 4d 65 72 67 65 72 2d 3e 61 52 65 61 64 72   pMerger->aReadr
d360: 29 3b 0a 20 20 20 20 20 20 20 20 70 52 65 61 64  );.        pRead
d370: 72 32 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61  r2 = &pMerger->a
d380: 52 65 61 64 72 5b 20 70 4d 65 72 67 65 72 2d 3e  Readr[ pMerger->
d390: 61 54 72 65 65 5b 69 20 5e 20 30 78 30 30 30 31  aTree[i ^ 0x0001
d3a0: 5d 20 5d 3b 0a 20 20 20 20 20 20 20 20 70 4b 65  ] ];.        pKe
d3b0: 79 32 20 3d 20 70 52 65 61 64 72 32 2d 3e 61 4b  y2 = pReadr2->aK
d3c0: 65 79 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  ey;.      }else{
d3d0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 52 65  .        if( pRe
d3e0: 61 64 72 31 2d 3e 70 46 69 6c 65 20 29 20 70 4b  adr1->pFile ) pK
d3f0: 65 79 32 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ey2 = 0;.       
d400: 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b   pMerger->aTree[
d410: 69 5d 20 3d 20 28 69 6e 74 29 28 70 52 65 61 64  i] = (int)(pRead
d420: 72 32 20 2d 20 70 4d 65 72 67 65 72 2d 3e 61 52  r2 - pMerger->aR
d430: 65 61 64 72 29 3b 0a 20 20 20 20 20 20 20 20 70  eadr);.        p
d440: 52 65 61 64 72 31 20 3d 20 26 70 4d 65 72 67 65  Readr1 = &pMerge
d450: 72 2d 3e 61 52 65 61 64 72 5b 20 70 4d 65 72 67  r->aReadr[ pMerg
d460: 65 72 2d 3e 61 54 72 65 65 5b 69 20 5e 20 30 78  er->aTree[i ^ 0x
d470: 30 30 30 31 5d 20 5d 3b 0a 20 20 20 20 20 20 7d  0001] ];.      }
d480: 0a 20 20 20 20 7d 0a 20 20 20 20 2a 70 62 45 6f  .    }.    *pbEo
d490: 66 20 3d 20 28 70 4d 65 72 67 65 72 2d 3e 61 52  f = (pMerger->aR
d4a0: 65 61 64 72 5b 70 4d 65 72 67 65 72 2d 3e 61 54  eadr[pMerger->aT
d4b0: 72 65 65 5b 31 5d 5d 2e 70 46 69 6c 65 3d 3d 30  ree[1]].pFile==0
d4c0: 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  );.  }..  return
d4d0: 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20   (rc==SQLITE_OK 
d4e0: 3f 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b  ? pTask->pUnpack
d4f0: 65 64 2d 3e 65 72 72 43 6f 64 65 20 3a 20 72 63  ed->errCode : rc
d500: 29 3b 0a 7d 0a 0a 23 69 66 20 53 51 4c 49 54 45  );.}..#if SQLITE
d510: 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45  _MAX_WORKER_THRE
d520: 41 44 53 3e 30 0a 2f 2a 0a 2a 2a 20 54 68 65 20  ADS>0./*.** The 
d530: 6d 61 69 6e 20 72 6f 75 74 69 6e 65 20 66 6f 72  main routine for
d540: 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65   background thre
d550: 61 64 73 20 74 68 61 74 20 77 72 69 74 65 20 6c  ads that write l
d560: 65 76 65 6c 2d 30 20 50 4d 41 73 2e 0a 2a 2f 0a  evel-0 PMAs..*/.
d570: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 76 64 62  static void *vdb
d580: 65 53 6f 72 74 65 72 46 6c 75 73 68 54 68 72 65  eSorterFlushThre
d590: 61 64 28 76 6f 69 64 20 2a 70 43 74 78 29 7b 0a  ad(void *pCtx){.
d5a0: 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70    SortSubtask *p
d5b0: 54 61 73 6b 20 3d 20 28 53 6f 72 74 53 75 62 74  Task = (SortSubt
d5c0: 61 73 6b 2a 29 70 43 74 78 3b 0a 20 20 69 6e 74  ask*)pCtx;.  int
d5d0: 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
d5e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
d5f0: 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
d600: 20 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e   assert( pTask->
d610: 62 44 6f 6e 65 3d 3d 30 20 29 3b 0a 20 20 72 63  bDone==0 );.  rc
d620: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4c 69 73   = vdbeSorterLis
d630: 74 54 6f 50 4d 41 28 70 54 61 73 6b 2c 20 26 70  tToPMA(pTask, &p
d640: 54 61 73 6b 2d 3e 6c 69 73 74 29 3b 0a 20 20 70  Task->list);.  p
d650: 54 61 73 6b 2d 3e 62 44 6f 6e 65 20 3d 20 31 3b  Task->bDone = 1;
d660: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
d670: 5f 49 4e 54 5f 54 4f 5f 50 54 52 28 72 63 29 3b  _INT_TO_PTR(rc);
d680: 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c  .}.#endif /* SQL
d690: 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54  ITE_MAX_WORKER_T
d6a0: 48 52 45 41 44 53 3e 30 20 2a 2f 0a 0a 2f 2a 0a  HREADS>0 */../*.
d6b0: 2a 2a 20 46 6c 75 73 68 20 74 68 65 20 63 75 72  ** Flush the cur
d6c0: 72 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f 66  rent contents of
d6d0: 20 56 64 62 65 53 6f 72 74 65 72 2e 6c 69 73 74   VdbeSorter.list
d6e0: 20 74 6f 20 61 20 6e 65 77 20 50 4d 41 2c 20 70   to a new PMA, p
d6f0: 6f 73 73 69 62 6c 79 0a 2a 2a 20 75 73 69 6e 67  ossibly.** using
d700: 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68   a background th
d710: 72 65 61 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  read..*/.static 
d720: 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72 46 6c  int vdbeSorterFl
d730: 75 73 68 50 4d 41 28 56 64 62 65 53 6f 72 74 65  ushPMA(VdbeSorte
d740: 72 20 2a 70 53 6f 72 74 65 72 29 7b 0a 23 69 66  r *pSorter){.#if
d750: 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b   SQLITE_MAX_WORK
d760: 45 52 5f 54 48 52 45 41 44 53 3d 3d 30 0a 20 20  ER_THREADS==0.  
d770: 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41  pSorter->bUsePMA
d780: 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 76   = 1;.  return v
d790: 64 62 65 53 6f 72 74 65 72 4c 69 73 74 54 6f 50  dbeSorterListToP
d7a0: 4d 41 28 26 70 53 6f 72 74 65 72 2d 3e 61 54 61  MA(&pSorter->aTa
d7b0: 73 6b 5b 30 5d 2c 20 26 70 53 6f 72 74 65 72 2d  sk[0], &pSorter-
d7c0: 3e 6c 69 73 74 29 3b 0a 23 65 6c 73 65 0a 20 20  >list);.#else.  
d7d0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
d7e0: 4f 4b 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 53  OK;.  int i;.  S
d7f0: 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
d800: 6b 20 3d 20 30 3b 20 20 20 20 2f 2a 20 54 68 72  k = 0;    /* Thr
d810: 65 61 64 20 63 6f 6e 74 65 78 74 20 75 73 65 64  ead context used
d820: 20 74 6f 20 63 72 65 61 74 65 20 6e 65 77 20 50   to create new P
d830: 4d 41 20 2a 2f 0a 20 20 69 6e 74 20 6e 57 6f 72  MA */.  int nWor
d840: 6b 65 72 20 3d 20 28 70 53 6f 72 74 65 72 2d 3e  ker = (pSorter->
d850: 6e 54 61 73 6b 2d 31 29 3b 0a 0a 20 20 2f 2a 20  nTask-1);..  /* 
d860: 53 65 74 20 74 68 65 20 66 6c 61 67 20 74 6f 20  Set the flag to 
d870: 69 6e 64 69 63 61 74 65 20 74 68 61 74 20 61 74  indicate that at
d880: 20 6c 65 61 73 74 20 6f 6e 65 20 50 4d 41 20 68   least one PMA h
d890: 61 73 20 62 65 65 6e 20 77 72 69 74 74 65 6e 2e  as been written.
d8a0: 20 0a 20 20 2a 2a 20 4f 72 20 77 69 6c 6c 20 62   .  ** Or will b
d8b0: 65 2c 20 61 6e 79 68 6f 77 2e 20 20 2a 2f 0a 20  e, anyhow.  */. 
d8c0: 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d   pSorter->bUsePM
d8d0: 41 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20 53 65 6c  A = 1;..  /* Sel
d8e0: 65 63 74 20 61 20 73 75 62 2d 74 61 73 6b 20 74  ect a sub-task t
d8f0: 6f 20 73 6f 72 74 20 61 6e 64 20 66 6c 75 73 68  o sort and flush
d900: 20 74 68 65 20 63 75 72 72 65 6e 74 20 6c 69 73   the current lis
d910: 74 20 6f 66 20 69 6e 2d 6d 65 6d 6f 72 79 0a 20  t of in-memory. 
d920: 20 2a 2a 20 72 65 63 6f 72 64 73 20 74 6f 20 64   ** records to d
d930: 69 73 6b 2e 20 49 66 20 74 68 65 20 73 6f 72 74  isk. If the sort
d940: 65 72 20 69 73 20 72 75 6e 6e 69 6e 67 20 69 6e  er is running in
d950: 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20   multi-threaded 
d960: 6d 6f 64 65 2c 0a 20 20 2a 2a 20 72 6f 75 6e 64  mode,.  ** round
d970: 2d 72 6f 62 69 6e 20 62 65 74 77 65 65 6e 20 74  -robin between t
d980: 68 65 20 66 69 72 73 74 20 28 70 53 6f 72 74 65  he first (pSorte
d990: 72 2d 3e 6e 54 61 73 6b 2d 31 29 20 74 61 73 6b  r->nTask-1) task
d9a0: 73 2e 20 45 78 63 65 70 74 2c 20 69 66 0a 20 20  s. Except, if.  
d9b0: 2a 2a 20 74 68 65 20 62 61 63 6b 67 72 6f 75 6e  ** the backgroun
d9c0: 64 20 74 68 72 65 61 64 20 66 72 6f 6d 20 61 20  d thread from a 
d9d0: 73 75 62 2d 74 61 73 6b 73 20 70 72 65 76 69 6f  sub-tasks previo
d9e0: 75 73 20 74 75 72 6e 20 69 73 20 73 74 69 6c 6c  us turn is still
d9f0: 20 72 75 6e 6e 69 6e 67 2c 0a 20 20 2a 2a 20 73   running,.  ** s
da00: 6b 69 70 20 69 74 2e 20 49 66 20 74 68 65 20 66  kip it. If the f
da10: 69 72 73 74 20 28 70 53 6f 72 74 65 72 2d 3e 6e  irst (pSorter->n
da20: 54 61 73 6b 2d 31 29 20 73 75 62 2d 74 61 73 6b  Task-1) sub-task
da30: 73 20 61 72 65 20 61 6c 6c 20 73 74 69 6c 6c 20  s are all still 
da40: 62 75 73 79 2c 0a 20 20 2a 2a 20 66 61 6c 6c 20  busy,.  ** fall 
da50: 62 61 63 6b 20 74 6f 20 75 73 69 6e 67 20 74 68  back to using th
da60: 65 20 66 69 6e 61 6c 20 73 75 62 2d 74 61 73 6b  e final sub-task
da70: 2e 20 54 68 65 20 66 69 72 73 74 20 28 70 53 6f  . The first (pSo
da80: 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 0a 20  rter->nTask-1). 
da90: 20 2a 2a 20 73 75 62 2d 74 61 73 6b 73 20 61 72   ** sub-tasks ar
daa0: 65 20 70 72 65 66 65 72 65 64 20 61 73 20 74 68  e prefered as th
dab0: 65 79 20 75 73 65 20 62 61 63 6b 67 72 6f 75 6e  ey use backgroun
dac0: 64 20 74 68 72 65 61 64 73 20 2d 20 74 68 65 20  d threads - the 
dad0: 66 69 6e 61 6c 20 0a 20 20 2a 2a 20 73 75 62 2d  final .  ** sub-
dae0: 74 61 73 6b 20 75 73 65 73 20 74 68 65 20 6d 61  task uses the ma
daf0: 69 6e 20 74 68 72 65 61 64 2e 20 2a 2f 0a 20 20  in thread. */.  
db00: 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 57 6f 72 6b  for(i=0; i<nWork
db10: 65 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e  er; i++){.    in
db20: 74 20 69 54 65 73 74 20 3d 20 28 70 53 6f 72 74  t iTest = (pSort
db30: 65 72 2d 3e 69 50 72 65 76 20 2b 20 69 20 2b 20  er->iPrev + i + 
db40: 31 29 20 25 20 6e 57 6f 72 6b 65 72 3b 0a 20 20  1) % nWorker;.  
db50: 20 20 70 54 61 73 6b 20 3d 20 26 70 53 6f 72 74    pTask = &pSort
db60: 65 72 2d 3e 61 54 61 73 6b 5b 69 54 65 73 74 5d  er->aTask[iTest]
db70: 3b 0a 20 20 20 20 69 66 28 20 70 54 61 73 6b 2d  ;.    if( pTask-
db80: 3e 62 44 6f 6e 65 20 29 7b 0a 20 20 20 20 20 20  >bDone ){.      
db90: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4a  rc = vdbeSorterJ
dba0: 6f 69 6e 54 68 72 65 61 64 28 70 54 61 73 6b 29  oinThread(pTask)
dbb0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
dbc0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c  rc!=SQLITE_OK ||
dbd0: 20 70 54 61 73 6b 2d 3e 70 54 68 72 65 61 64 3d   pTask->pThread=
dbe0: 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a  =0 ) break;.  }.
dbf0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
dc00: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 66 28 20  E_OK ){.    if( 
dc10: 69 3d 3d 6e 57 6f 72 6b 65 72 20 29 7b 0a 20 20  i==nWorker ){.  
dc20: 20 20 20 20 2f 2a 20 55 73 65 20 74 68 65 20 66      /* Use the f
dc30: 6f 72 65 67 72 6f 75 6e 64 20 74 68 72 65 61 64  oreground thread
dc40: 20 66 6f 72 20 74 68 69 73 20 6f 70 65 72 61 74   for this operat
dc50: 69 6f 6e 20 2a 2f 0a 20 20 20 20 20 20 72 63 20  ion */.      rc 
dc60: 3d 20 76 64 62 65 53 6f 72 74 65 72 4c 69 73 74  = vdbeSorterList
dc70: 54 6f 50 4d 41 28 26 70 53 6f 72 74 65 72 2d 3e  ToPMA(&pSorter->
dc80: 61 54 61 73 6b 5b 6e 57 6f 72 6b 65 72 5d 2c 20  aTask[nWorker], 
dc90: 26 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 29 3b  &pSorter->list);
dca0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
dcb0: 20 20 2f 2a 20 4c 61 75 6e 63 68 20 61 20 62 61    /* Launch a ba
dcc0: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
dcd0: 66 6f 72 20 74 68 69 73 20 6f 70 65 72 61 74 69  for this operati
dce0: 6f 6e 20 2a 2f 0a 20 20 20 20 20 20 75 38 20 2a  on */.      u8 *
dcf0: 61 4d 65 6d 20 3d 20 70 54 61 73 6b 2d 3e 6c 69  aMem = pTask->li
dd00: 73 74 2e 61 4d 65 6d 6f 72 79 3b 0a 20 20 20 20  st.aMemory;.    
dd10: 20 20 76 6f 69 64 20 2a 70 43 74 78 20 3d 20 28    void *pCtx = (
dd20: 76 6f 69 64 2a 29 70 54 61 73 6b 3b 0a 0a 20 20  void*)pTask;..  
dd30: 20 20 20 20 61 73 73 65 72 74 28 20 70 54 61 73      assert( pTas
dd40: 6b 2d 3e 70 54 68 72 65 61 64 3d 3d 30 20 26 26  k->pThread==0 &&
dd50: 20 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 3d 3d 30   pTask->bDone==0
dd60: 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74   );.      assert
dd70: 28 20 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 70 4c  ( pTask->list.pL
dd80: 69 73 74 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20  ist==0 );.      
dd90: 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 6c  assert( pTask->l
dda0: 69 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30 20 7c  ist.aMemory==0 |
ddb0: 7c 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e  | pSorter->list.
ddc0: 61 4d 65 6d 6f 72 79 21 3d 30 20 29 3b 0a 0a 20  aMemory!=0 );.. 
ddd0: 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 69 50       pSorter->iP
dde0: 72 65 76 20 3d 20 28 70 54 61 73 6b 20 2d 20 70  rev = (pTask - p
ddf0: 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 29 3b 0a  Sorter->aTask);.
de00: 20 20 20 20 20 20 70 54 61 73 6b 2d 3e 6c 69 73        pTask->lis
de10: 74 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73  t = pSorter->lis
de20: 74 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72  t;.      pSorter
de30: 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d 20 30  ->list.pList = 0
de40: 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d  ;.      pSorter-
de50: 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 3d 20 30 3b  >list.szPMA = 0;
de60: 0a 20 20 20 20 20 20 69 66 28 20 61 4d 65 6d 20  .      if( aMem 
de70: 29 7b 0a 20 20 20 20 20 20 20 20 70 53 6f 72 74  ){.        pSort
de80: 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  er->list.aMemory
de90: 20 3d 20 61 4d 65 6d 3b 0a 20 20 20 20 20 20 20   = aMem;.       
dea0: 20 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72   pSorter->nMemor
deb0: 79 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  y = sqlite3Mallo
dec0: 63 53 69 7a 65 28 61 4d 65 6d 29 3b 0a 20 20 20  cSize(aMem);.   
ded0: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70 53 6f     }else if( pSo
dee0: 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f  rter->list.aMemo
def0: 72 79 20 29 7b 0a 20 20 20 20 20 20 20 20 70 53  ry ){.        pS
df00: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d  orter->list.aMem
df10: 6f 72 79 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c  ory = sqlite3Mal
df20: 6c 6f 63 28 70 53 6f 72 74 65 72 2d 3e 6e 4d 65  loc(pSorter->nMe
df30: 6d 6f 72 79 29 3b 0a 20 20 20 20 20 20 20 20 69  mory);.        i
df40: 66 28 20 21 70 53 6f 72 74 65 72 2d 3e 6c 69 73  f( !pSorter->lis
df50: 74 2e 61 4d 65 6d 6f 72 79 20 29 20 72 65 74 75  t.aMemory ) retu
df60: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
df70: 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
df80: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 43  rc = vdbeSorterC
df90: 72 65 61 74 65 54 68 72 65 61 64 28 70 54 61 73  reateThread(pTas
dfa0: 6b 2c 20 76 64 62 65 53 6f 72 74 65 72 46 6c 75  k, vdbeSorterFlu
dfb0: 73 68 54 68 72 65 61 64 2c 20 70 43 74 78 29 3b  shThread, pCtx);
dfc0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
dfd0: 74 75 72 6e 20 72 63 3b 0a 23 65 6e 64 69 66 20  turn rc;.#endif 
dfe0: 2f 2a 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f  /* SQLITE_MAX_WO
dff0: 52 4b 45 52 5f 54 48 52 45 41 44 53 21 3d 30 20  RKER_THREADS!=0 
e000: 2a 2f 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20  */.}../*.** Add 
e010: 61 20 72 65 63 6f 72 64 20 74 6f 20 74 68 65 20  a record to the 
e020: 73 6f 72 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20 73  sorter..*/.int s
e030: 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72  qlite3VdbeSorter
e040: 57 72 69 74 65 28 0a 20 20 63 6f 6e 73 74 20 56  Write(.  const V
e050: 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c  dbeCursor *pCsr,
e060: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74           /* Sort
e070: 65 72 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 4d  er cursor */.  M
e080: 65 6d 20 2a 70 56 61 6c 20 20 20 20 20 20 20 20  em *pVal        
e090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
e0a0: 2a 20 4d 65 6d 6f 72 79 20 63 65 6c 6c 20 63 6f  * Memory cell co
e0b0: 6e 74 61 69 6e 69 6e 67 20 72 65 63 6f 72 64 20  ntaining record 
e0c0: 2a 2f 0a 29 7b 0a 20 20 56 64 62 65 53 6f 72 74  */.){.  VdbeSort
e0d0: 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43  er *pSorter = pC
e0e0: 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69  sr->pSorter;.  i
e0f0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
e100: 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  K;             /
e110: 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f  * Return Code */
e120: 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20  .  SorterRecord 
e130: 2a 70 4e 65 77 3b 20 20 20 20 20 20 20 20 20 20  *pNew;          
e140: 20 20 20 2f 2a 20 4e 65 77 20 6c 69 73 74 20 65     /* New list e
e150: 6c 65 6d 65 6e 74 20 2a 2f 0a 0a 20 20 69 6e 74  lement */..  int
e160: 20 62 46 6c 75 73 68 3b 20 20 20 20 20 20 20 20   bFlush;        
e170: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
e180: 54 72 75 65 20 74 6f 20 66 6c 75 73 68 20 63 6f  True to flush co
e190: 6e 74 65 6e 74 73 20 6f 66 20 6d 65 6d 6f 72 79  ntents of memory
e1a0: 20 74 6f 20 50 4d 41 20 2a 2f 0a 20 20 69 6e 74   to PMA */.  int
e1b0: 20 6e 52 65 71 3b 20 20 20 20 20 20 20 20 20 20   nReq;          
e1c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
e1d0: 42 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20  Bytes of memory 
e1e0: 72 65 71 75 69 72 65 64 20 2a 2f 0a 20 20 69 6e  required */.  in
e1f0: 74 20 6e 50 4d 41 3b 20 20 20 20 20 20 20 20 20  t nPMA;         
e200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
e210: 20 42 79 74 65 73 20 6f 66 20 50 4d 41 20 73 70   Bytes of PMA sp
e220: 61 63 65 20 72 65 71 75 69 72 65 64 20 2a 2f 0a  ace required */.
e230: 0a 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74  .  assert( pSort
e240: 65 72 20 29 3b 0a 0a 20 20 2f 2a 20 46 69 67 75  er );..  /* Figu
e250: 72 65 20 6f 75 74 20 77 68 65 74 68 65 72 20 6f  re out whether o
e260: 72 20 6e 6f 74 20 74 68 65 20 63 75 72 72 65 6e  r not the curren
e270: 74 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65  t contents of me
e280: 6d 6f 72 79 20 73 68 6f 75 6c 64 20 62 65 0a 20  mory should be. 
e290: 20 2a 2a 20 66 6c 75 73 68 65 64 20 74 6f 20 61   ** flushed to a
e2a0: 20 50 4d 41 20 62 65 66 6f 72 65 20 63 6f 6e 74   PMA before cont
e2b0: 69 6e 75 69 6e 67 2e 20 49 66 20 73 6f 2c 20 64  inuing. If so, d
e2c0: 6f 20 73 6f 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20  o so..  **.  ** 
e2d0: 49 66 20 75 73 69 6e 67 20 74 68 65 20 73 69 6e  If using the sin
e2e0: 67 6c 65 20 6c 61 72 67 65 20 61 6c 6c 6f 63 61  gle large alloca
e2f0: 74 69 6f 6e 20 6d 6f 64 65 20 28 70 53 6f 72 74  tion mode (pSort
e300: 65 72 2d 3e 61 4d 65 6d 6f 72 79 21 3d 30 29 2c  er->aMemory!=0),
e310: 20 74 68 65 6e 0a 20 20 2a 2a 20 66 6c 75 73 68   then.  ** flush
e320: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
e330: 20 6d 65 6d 6f 72 79 20 74 6f 20 61 20 6e 65 77   memory to a new
e340: 20 50 4d 41 20 69 66 20 28 61 29 20 61 74 20 6c   PMA if (a) at l
e350: 65 61 73 74 20 6f 6e 65 20 76 61 6c 75 65 20 69  east one value i
e360: 73 0a 20 20 2a 2a 20 61 6c 72 65 61 64 79 20 69  s.  ** already i
e370: 6e 20 6d 65 6d 6f 72 79 20 61 6e 64 20 28 62 29  n memory and (b)
e380: 20 74 68 65 20 6e 65 77 20 76 61 6c 75 65 20 77   the new value w
e390: 69 6c 6c 20 6e 6f 74 20 66 69 74 20 69 6e 20 6d  ill not fit in m
e3a0: 65 6d 6f 72 79 2e 0a 20 20 2a 2a 20 0a 20 20 2a  emory..  ** .  *
e3b0: 2a 20 4f 72 2c 20 69 66 20 75 73 69 6e 67 20 73  * Or, if using s
e3c0: 65 70 61 72 61 74 65 20 61 6c 6c 6f 63 61 74 69  eparate allocati
e3d0: 6f 6e 73 20 66 6f 72 20 65 61 63 68 20 72 65 63  ons for each rec
e3e0: 6f 72 64 2c 20 66 6c 75 73 68 20 74 68 65 20 63  ord, flush the c
e3f0: 6f 6e 74 65 6e 74 73 0a 20 20 2a 2a 20 6f 66 20  ontents.  ** of 
e400: 6d 65 6d 6f 72 79 20 74 6f 20 61 20 50 4d 41 20  memory to a PMA 
e410: 69 66 20 65 69 74 68 65 72 20 6f 66 20 74 68 65  if either of the
e420: 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 72 65 20 74   following are t
e430: 72 75 65 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20  rue:.  **.  **  
e440: 20 2a 20 54 68 65 20 74 6f 74 61 6c 20 6d 65 6d   * The total mem
e450: 6f 72 79 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f  ory allocated fo
e460: 72 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20  r the in-memory 
e470: 6c 69 73 74 20 69 73 20 67 72 65 61 74 65 72 20  list is greater 
e480: 0a 20 20 2a 2a 20 20 20 20 20 74 68 61 6e 20 28  .  **     than (
e490: 70 61 67 65 2d 73 69 7a 65 20 2a 20 63 61 63 68  page-size * cach
e4a0: 65 2d 73 69 7a 65 29 2c 20 6f 72 0a 20 20 2a 2a  e-size), or.  **
e4b0: 0a 20 20 2a 2a 20 20 20 2a 20 54 68 65 20 74 6f  .  **   * The to
e4c0: 74 61 6c 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63  tal memory alloc
e4d0: 61 74 65 64 20 66 6f 72 20 74 68 65 20 69 6e 2d  ated for the in-
e4e0: 6d 65 6d 6f 72 79 20 6c 69 73 74 20 69 73 20 67  memory list is g
e4f0: 72 65 61 74 65 72 20 0a 20 20 2a 2a 20 20 20 20  reater .  **    
e500: 20 74 68 61 6e 20 28 70 61 67 65 2d 73 69 7a 65   than (page-size
e510: 20 2a 20 31 30 29 20 61 6e 64 20 73 71 6c 69 74   * 10) and sqlit
e520: 65 33 48 65 61 70 4e 65 61 72 6c 79 46 75 6c 6c  e3HeapNearlyFull
e530: 28 29 20 72 65 74 75 72 6e 73 20 74 72 75 65 2e  () returns true.
e540: 0a 20 20 2a 2f 0a 20 20 6e 52 65 71 20 3d 20 70  .  */.  nReq = p
e550: 56 61 6c 2d 3e 6e 20 2b 20 73 69 7a 65 6f 66 28  Val->n + sizeof(
e560: 53 6f 72 74 65 72 52 65 63 6f 72 64 29 3b 0a 20  SorterRecord);. 
e570: 20 6e 50 4d 41 20 3d 20 70 56 61 6c 2d 3e 6e 20   nPMA = pVal->n 
e580: 2b 20 73 71 6c 69 74 65 33 56 61 72 69 6e 74 4c  + sqlite3VarintL
e590: 65 6e 28 70 56 61 6c 2d 3e 6e 29 3b 0a 20 20 69  en(pVal->n);.  i
e5a0: 66 28 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d  f( pSorter->mxPm
e5b0: 61 53 69 7a 65 20 29 7b 0a 20 20 20 20 69 66 28  aSize ){.    if(
e5c0: 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61   pSorter->list.a
e5d0: 4d 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20 20  Memory ){.      
e5e0: 62 46 6c 75 73 68 20 3d 20 70 53 6f 72 74 65 72  bFlush = pSorter
e5f0: 2d 3e 69 4d 65 6d 6f 72 79 20 26 26 20 28 70 53  ->iMemory && (pS
e600: 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 2b 6e  orter->iMemory+n
e610: 52 65 71 29 20 3e 20 70 53 6f 72 74 65 72 2d 3e  Req) > pSorter->
e620: 6d 78 50 6d 61 53 69 7a 65 3b 0a 20 20 20 20 7d  mxPmaSize;.    }
e630: 65 6c 73 65 7b 0a 20 20 20 20 20 20 62 46 6c 75  else{.      bFlu
e640: 73 68 20 3d 20 28 0a 20 20 20 20 20 20 20 20 20  sh = (.         
e650: 20 28 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e   (pSorter->list.
e660: 73 7a 50 4d 41 20 3e 20 70 53 6f 72 74 65 72 2d  szPMA > pSorter-
e670: 3e 6d 78 50 6d 61 53 69 7a 65 29 0a 20 20 20 20  >mxPmaSize).    
e680: 20 20 20 7c 7c 20 28 70 53 6f 72 74 65 72 2d 3e     || (pSorter->
e690: 6c 69 73 74 2e 73 7a 50 4d 41 20 3e 20 70 53 6f  list.szPMA > pSo
e6a0: 72 74 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a 65 20  rter->mnPmaSize 
e6b0: 26 26 20 73 71 6c 69 74 65 33 48 65 61 70 4e 65  && sqlite3HeapNe
e6c0: 61 72 6c 79 46 75 6c 6c 28 29 29 0a 20 20 20 20  arlyFull()).    
e6d0: 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69    );.    }.    i
e6e0: 66 28 20 62 46 6c 75 73 68 20 29 7b 0a 20 20 20  f( bFlush ){.   
e6f0: 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74     rc = vdbeSort
e700: 65 72 46 6c 75 73 68 50 4d 41 28 70 53 6f 72 74  erFlushPMA(pSort
e710: 65 72 29 3b 0a 20 20 20 20 20 20 70 53 6f 72 74  er);.      pSort
e720: 65 72 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 3d  er->list.szPMA =
e730: 20 30 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65   0;.      pSorte
e740: 72 2d 3e 69 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a  r->iMemory = 0;.
e750: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 72 63        assert( rc
e760: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70  !=SQLITE_OK || p
e770: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69  Sorter->list.pLi
e780: 73 74 3d 3d 30 20 29 3b 0a 20 20 20 20 7d 0a 20  st==0 );.    }. 
e790: 20 7d 0a 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6c   }..  pSorter->l
e7a0: 69 73 74 2e 73 7a 50 4d 41 20 2b 3d 20 6e 50 4d  ist.szPMA += nPM
e7b0: 41 3b 0a 20 20 69 66 28 20 6e 50 4d 41 3e 70 53  A;.  if( nPMA>pS
e7c0: 6f 72 74 65 72 2d 3e 6d 78 4b 65 79 73 69 7a 65  orter->mxKeysize
e7d0: 20 29 7b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d   ){.    pSorter-
e7e0: 3e 6d 78 4b 65 79 73 69 7a 65 20 3d 20 6e 50 4d  >mxKeysize = nPM
e7f0: 41 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 53  A;.  }..  if( pS
e800: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d  orter->list.aMem
e810: 6f 72 79 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e  ory ){.    int n
e820: 4d 69 6e 20 3d 20 70 53 6f 72 74 65 72 2d 3e 69  Min = pSorter->i
e830: 4d 65 6d 6f 72 79 20 2b 20 6e 52 65 71 3b 0a 0a  Memory + nReq;..
e840: 20 20 20 20 69 66 28 20 6e 4d 69 6e 3e 70 53 6f      if( nMin>pSo
e850: 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 29 7b  rter->nMemory ){
e860: 0a 20 20 20 20 20 20 75 38 20 2a 61 4e 65 77 3b  .      u8 *aNew;
e870: 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e 65 77 20  .      int nNew 
e880: 3d 20 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f  = pSorter->nMemo
e890: 72 79 20 2a 20 32 3b 0a 20 20 20 20 20 20 77 68  ry * 2;.      wh
e8a0: 69 6c 65 28 20 6e 4e 65 77 20 3c 20 6e 4d 69 6e  ile( nNew < nMin
e8b0: 20 29 20 6e 4e 65 77 20 3d 20 6e 4e 65 77 2a 32   ) nNew = nNew*2
e8c0: 3b 0a 20 20 20 20 20 20 69 66 28 20 6e 4e 65 77  ;.      if( nNew
e8d0: 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d   > pSorter->mxPm
e8e0: 61 53 69 7a 65 20 29 20 6e 4e 65 77 20 3d 20 70  aSize ) nNew = p
e8f0: 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a  Sorter->mxPmaSiz
e900: 65 3b 0a 20 20 20 20 20 20 69 66 28 20 6e 4e 65  e;.      if( nNe
e910: 77 20 3c 20 6e 4d 69 6e 20 29 20 6e 4e 65 77 20  w < nMin ) nNew 
e920: 3d 20 6e 4d 69 6e 3b 0a 0a 20 20 20 20 20 20 61  = nMin;..      a
e930: 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 52 65 61  New = sqlite3Rea
e940: 6c 6c 6f 63 28 70 53 6f 72 74 65 72 2d 3e 6c 69  lloc(pSorter->li
e950: 73 74 2e 61 4d 65 6d 6f 72 79 2c 20 6e 4e 65 77  st.aMemory, nNew
e960: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21 61 4e  );.      if( !aN
e970: 65 77 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  ew ) return SQLI
e980: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20  TE_NOMEM;.      
e990: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c  pSorter->list.pL
e9a0: 69 73 74 20 3d 20 28 53 6f 72 74 65 72 52 65 63  ist = (SorterRec
e9b0: 6f 72 64 2a 29 28 0a 20 20 20 20 20 20 20 20 20  ord*)(.         
e9c0: 20 61 4e 65 77 20 2b 20 28 28 75 38 2a 29 70 53   aNew + ((u8*)pS
e9d0: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73  orter->list.pLis
e9e0: 74 20 2d 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73  t - pSorter->lis
e9f0: 74 2e 61 4d 65 6d 6f 72 79 29 0a 20 20 20 20 20  t.aMemory).     
ea00: 20 29 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65   );.      pSorte
ea10: 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20  r->list.aMemory 
ea20: 3d 20 61 4e 65 77 3b 0a 20 20 20 20 20 20 70 53  = aNew;.      pS
ea30: 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 3d  orter->nMemory =
ea40: 20 6e 4e 65 77 3b 0a 20 20 20 20 7d 0a 0a 20 20   nNew;.    }..  
ea50: 20 20 70 4e 65 77 20 3d 20 28 53 6f 72 74 65 72    pNew = (Sorter
ea60: 52 65 63 6f 72 64 2a 29 26 70 53 6f 72 74 65 72  Record*)&pSorter
ea70: 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 5b 70  ->list.aMemory[p
ea80: 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 5d  Sorter->iMemory]
ea90: 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 69  ;.    pSorter->i
eaa0: 4d 65 6d 6f 72 79 20 2b 3d 20 52 4f 55 4e 44 38  Memory += ROUND8
eab0: 28 6e 52 65 71 29 3b 0a 20 20 20 20 70 4e 65 77  (nReq);.    pNew
eac0: 2d 3e 75 2e 69 4e 65 78 74 20 3d 20 28 69 6e 74  ->u.iNext = (int
ead0: 29 28 28 75 38 2a 29 28 70 53 6f 72 74 65 72 2d  )((u8*)(pSorter-
eae0: 3e 6c 69 73 74 2e 70 4c 69 73 74 29 20 2d 20 70  >list.pList) - p
eaf0: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65  Sorter->list.aMe
eb00: 6d 6f 72 79 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  mory);.  }else{.
eb10: 20 20 20 20 70 4e 65 77 20 3d 20 28 53 6f 72 74      pNew = (Sort
eb20: 65 72 52 65 63 6f 72 64 20 2a 29 73 71 6c 69 74  erRecord *)sqlit
eb30: 65 33 4d 61 6c 6c 6f 63 28 6e 52 65 71 29 3b 0a  e3Malloc(nReq);.
eb40: 20 20 20 20 69 66 28 20 70 4e 65 77 3d 3d 30 20      if( pNew==0 
eb50: 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
eb60: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
eb70: 20 20 7d 0a 20 20 20 20 70 4e 65 77 2d 3e 75 2e    }.    pNew->u.
eb80: 70 4e 65 78 74 20 3d 20 70 53 6f 72 74 65 72 2d  pNext = pSorter-
eb90: 3e 6c 69 73 74 2e 70 4c 69 73 74 3b 0a 20 20 7d  >list.pList;.  }
eba0: 0a 0a 20 20 6d 65 6d 63 70 79 28 53 52 56 41 4c  ..  memcpy(SRVAL
ebb0: 28 70 4e 65 77 29 2c 20 70 56 61 6c 2d 3e 7a 2c  (pNew), pVal->z,
ebc0: 20 70 56 61 6c 2d 3e 6e 29 3b 0a 20 20 70 4e 65   pVal->n);.  pNe
ebd0: 77 2d 3e 6e 56 61 6c 20 3d 20 70 56 61 6c 2d 3e  w->nVal = pVal->
ebe0: 6e 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69  n;.  pSorter->li
ebf0: 73 74 2e 70 4c 69 73 74 20 3d 20 70 4e 65 77 3b  st.pList = pNew;
ec00: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
ec10: 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 6b 65 79  ../*.** Read key
ec20: 73 20 66 72 6f 6d 20 70 49 6e 63 72 2d 3e 70 4d  s from pIncr->pM
ec30: 65 72 67 65 72 20 61 6e 64 20 70 6f 70 75 6c 61  erger and popula
ec40: 74 65 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b  te pIncr->aFile[
ec50: 31 5d 2e 20 54 68 65 20 66 6f 72 6d 61 74 0a 2a  1]. The format.*
ec60: 2a 20 6f 66 20 74 68 65 20 64 61 74 61 20 73 74  * of the data st
ec70: 6f 72 65 64 20 69 6e 20 61 46 69 6c 65 5b 31 5d  ored in aFile[1]
ec80: 20 69 73 20 74 68 65 20 73 61 6d 65 20 61 73 20   is the same as 
ec90: 74 68 61 74 20 75 73 65 64 20 62 79 20 72 65 67  that used by reg
eca0: 75 6c 61 72 20 50 4d 41 73 2c 0a 2a 2a 20 65 78  ular PMAs,.** ex
ecb0: 63 65 70 74 20 74 68 61 74 20 74 68 65 20 6e 75  cept that the nu
ecc0: 6d 62 65 72 2d 6f 66 2d 62 79 74 65 73 20 76 61  mber-of-bytes va
ecd0: 72 69 6e 74 20 69 73 20 6f 6d 69 74 74 65 64 20  rint is omitted 
ece0: 66 72 6f 6d 20 74 68 65 20 73 74 61 72 74 2e 0a  from the start..
ecf0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
ed00: 62 65 49 6e 63 72 50 6f 70 75 6c 61 74 65 28 49  beIncrPopulate(I
ed10: 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63 72  ncrMerger *pIncr
ed20: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
ed30: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 72  LITE_OK;.  int r
ed40: 63 32 3b 0a 20 20 69 36 34 20 69 53 74 61 72 74  c2;.  i64 iStart
ed50: 20 3d 20 70 49 6e 63 72 2d 3e 69 53 74 61 72 74   = pIncr->iStart
ed60: 4f 66 66 3b 0a 20 20 53 6f 72 74 65 72 46 69 6c  Off;.  SorterFil
ed70: 65 20 2a 70 4f 75 74 20 3d 20 26 70 49 6e 63 72  e *pOut = &pIncr
ed80: 2d 3e 61 46 69 6c 65 5b 31 5d 3b 0a 20 20 53 6f  ->aFile[1];.  So
ed90: 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b  rtSubtask *pTask
eda0: 20 3d 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b 3b   = pIncr->pTask;
edb0: 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a  .  MergeEngine *
edc0: 70 4d 65 72 67 65 72 20 3d 20 70 49 6e 63 72 2d  pMerger = pIncr-
edd0: 3e 70 4d 65 72 67 65 72 3b 0a 20 20 50 6d 61 57  >pMerger;.  PmaW
ede0: 72 69 74 65 72 20 77 72 69 74 65 72 3b 0a 20 20  riter writer;.  
edf0: 61 73 73 65 72 74 28 20 70 49 6e 63 72 2d 3e 62  assert( pIncr->b
ee00: 45 6f 66 3d 3d 30 20 29 3b 0a 0a 20 20 76 64 62  Eof==0 );..  vdb
ee10: 65 53 6f 72 74 65 72 50 6f 70 75 6c 61 74 65 44  eSorterPopulateD
ee20: 65 62 75 67 28 70 54 61 73 6b 2c 20 22 65 6e 74  ebug(pTask, "ent
ee30: 65 72 22 29 3b 0a 0a 20 20 76 64 62 65 50 6d 61  er");..  vdbePma
ee40: 57 72 69 74 65 72 49 6e 69 74 28 70 4f 75 74 2d  WriterInit(pOut-
ee50: 3e 70 46 64 2c 20 26 77 72 69 74 65 72 2c 20 70  >pFd, &writer, p
ee60: 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 70  Task->pSorter->p
ee70: 67 73 7a 2c 20 69 53 74 61 72 74 29 3b 0a 20 20  gsz, iStart);.  
ee80: 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54  while( rc==SQLIT
ee90: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20  E_OK ){.    int 
eea0: 64 75 6d 6d 79 3b 0a 20 20 20 20 50 6d 61 52 65  dummy;.    PmaRe
eeb0: 61 64 65 72 20 2a 70 52 65 61 64 65 72 20 3d 20  ader *pReader = 
eec0: 26 70 4d 65 72 67 65 72 2d 3e 61 52 65 61 64 72  &pMerger->aReadr
eed0: 5b 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65  [ pMerger->aTree
eee0: 5b 31 5d 20 5d 3b 0a 20 20 20 20 69 6e 74 20 6e  [1] ];.    int n
eef0: 4b 65 79 20 3d 20 70 52 65 61 64 65 72 2d 3e 6e  Key = pReader->n
ef00: 4b 65 79 3b 0a 20 20 20 20 69 36 34 20 69 45 6f  Key;.    i64 iEo
ef10: 66 20 3d 20 77 72 69 74 65 72 2e 69 57 72 69 74  f = writer.iWrit
ef20: 65 4f 66 66 20 2b 20 77 72 69 74 65 72 2e 69 42  eOff + writer.iB
ef30: 75 66 45 6e 64 3b 0a 0a 20 20 20 20 2f 2a 20 43  ufEnd;..    /* C
ef40: 68 65 63 6b 20 69 66 20 74 68 65 20 6f 75 74 70  heck if the outp
ef50: 75 74 20 66 69 6c 65 20 69 73 20 66 75 6c 6c 20  ut file is full 
ef60: 6f 72 20 69 66 20 74 68 65 20 69 6e 70 75 74 20  or if the input 
ef70: 68 61 73 20 62 65 65 6e 20 65 78 68 61 75 73 74  has been exhaust
ef80: 65 64 2e 0a 20 20 20 20 2a 2a 20 49 6e 20 65 69  ed..    ** In ei
ef90: 74 68 65 72 20 63 61 73 65 20 65 78 69 74 20 74  ther case exit t
efa0: 68 65 20 6c 6f 6f 70 2e 20 2a 2f 0a 20 20 20 20  he loop. */.    
efb0: 69 66 28 20 70 52 65 61 64 65 72 2d 3e 70 46 69  if( pReader->pFi
efc0: 6c 65 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20  le==0 ) break;. 
efd0: 20 20 20 69 66 28 20 28 69 45 6f 66 20 2b 20 6e     if( (iEof + n
efe0: 4b 65 79 20 2b 20 73 71 6c 69 74 65 33 56 61 72  Key + sqlite3Var
eff0: 69 6e 74 4c 65 6e 28 6e 4b 65 79 29 29 3e 28 69  intLen(nKey))>(i
f000: 53 74 61 72 74 20 2b 20 70 49 6e 63 72 2d 3e 6d  Start + pIncr->m
f010: 78 53 7a 29 20 29 20 62 72 65 61 6b 3b 0a 0a 20  xSz) ) break;.. 
f020: 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20     /* Write the 
f030: 6e 65 78 74 20 6b 65 79 20 74 6f 20 74 68 65 20  next key to the 
f040: 6f 75 74 70 75 74 2e 20 2a 2f 0a 20 20 20 20 76  output. */.    v
f050: 64 62 65 50 6d 61 57 72 69 74 65 56 61 72 69 6e  dbePmaWriteVarin
f060: 74 28 26 77 72 69 74 65 72 2c 20 6e 4b 65 79 29  t(&writer, nKey)
f070: 3b 0a 20 20 20 20 76 64 62 65 50 6d 61 57 72 69  ;.    vdbePmaWri
f080: 74 65 42 6c 6f 62 28 26 77 72 69 74 65 72 2c 20  teBlob(&writer, 
f090: 70 52 65 61 64 65 72 2d 3e 61 4b 65 79 2c 20 6e  pReader->aKey, n
f0a0: 4b 65 79 29 3b 0a 20 20 20 20 72 63 20 3d 20 76  Key);.    rc = v
f0b0: 64 62 65 53 6f 72 74 65 72 4e 65 78 74 28 70 54  dbeSorterNext(pT
f0c0: 61 73 6b 2c 20 70 49 6e 63 72 2d 3e 70 4d 65 72  ask, pIncr->pMer
f0d0: 67 65 72 2c 20 26 64 75 6d 6d 79 29 3b 0a 20 20  ger, &dummy);.  
f0e0: 7d 0a 0a 20 20 72 63 32 20 3d 20 76 64 62 65 50  }..  rc2 = vdbeP
f0f0: 6d 61 57 72 69 74 65 72 46 69 6e 69 73 68 28 26  maWriterFinish(&
f100: 77 72 69 74 65 72 2c 20 26 70 4f 75 74 2d 3e 69  writer, &pOut->i
f110: 45 6f 66 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d  Eof);.  if( rc==
f120: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d  SQLITE_OK ) rc =
f130: 20 72 63 32 3b 0a 20 20 76 64 62 65 53 6f 72 74   rc2;.  vdbeSort
f140: 65 72 50 6f 70 75 6c 61 74 65 44 65 62 75 67 28  erPopulateDebug(
f150: 70 54 61 73 6b 2c 20 22 65 78 69 74 22 29 3b 0a  pTask, "exit");.
f160: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
f170: 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57  #if SQLITE_MAX_W
f180: 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 0a  ORKER_THREADS>0.
f190: 2f 2a 0a 2a 2a 20 54 68 65 20 6d 61 69 6e 20 72  /*.** The main r
f1a0: 6f 75 74 69 6e 65 20 66 6f 72 20 62 61 63 6b 67  outine for backg
f1b0: 72 6f 75 6e 64 20 74 68 72 65 61 64 73 20 74 68  round threads th
f1c0: 61 74 20 70 6f 70 75 6c 61 74 65 20 61 46 69 6c  at populate aFil
f1d0: 65 5b 31 5d 20 6f 66 0a 2a 2a 20 6d 75 6c 74 69  e[1] of.** multi
f1e0: 2d 74 68 72 65 61 64 65 64 20 49 6e 63 72 4d 65  -threaded IncrMe
f1f0: 72 67 65 72 20 6f 62 6a 65 63 74 73 2e 0a 2a 2f  rger objects..*/
f200: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a 76 64  .static void *vd
f210: 62 65 49 6e 63 72 50 6f 70 75 6c 61 74 65 54 68  beIncrPopulateTh
f220: 72 65 61 64 28 76 6f 69 64 20 2a 70 43 74 78 29  read(void *pCtx)
f230: 7b 0a 20 20 49 6e 63 72 4d 65 72 67 65 72 20 2a  {.  IncrMerger *
f240: 70 49 6e 63 72 20 3d 20 28 49 6e 63 72 4d 65 72  pIncr = (IncrMer
f250: 67 65 72 2a 29 70 43 74 78 3b 0a 20 20 76 6f 69  ger*)pCtx;.  voi
f260: 64 20 2a 70 52 65 74 20 3d 20 53 51 4c 49 54 45  d *pRet = SQLITE
f270: 5f 49 4e 54 5f 54 4f 5f 50 54 52 28 20 76 64 62  _INT_TO_PTR( vdb
f280: 65 49 6e 63 72 50 6f 70 75 6c 61 74 65 28 70 49  eIncrPopulate(pI
f290: 6e 63 72 29 20 29 3b 0a 20 20 70 49 6e 63 72 2d  ncr) );.  pIncr-
f2a0: 3e 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 20 3d 20  >pTask->bDone = 
f2b0: 31 3b 0a 20 20 72 65 74 75 72 6e 20 70 52 65 74  1;.  return pRet
f2c0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 61 75 6e 63  ;.}../*.** Launc
f2d0: 68 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74  h a background t
f2e0: 68 72 65 61 64 20 74 6f 20 70 6f 70 75 6c 61 74  hread to populat
f2f0: 65 20 61 46 69 6c 65 5b 31 5d 20 6f 66 20 70 49  e aFile[1] of pI
f300: 6e 63 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ncr..*/.static i
f310: 6e 74 20 76 64 62 65 49 6e 63 72 42 67 50 6f 70  nt vdbeIncrBgPop
f320: 75 6c 61 74 65 28 49 6e 63 72 4d 65 72 67 65 72  ulate(IncrMerger
f330: 20 2a 70 49 6e 63 72 29 7b 0a 20 20 76 6f 69 64   *pIncr){.  void
f340: 20 2a 70 20 3d 20 28 76 6f 69 64 2a 29 70 49 6e   *p = (void*)pIn
f350: 63 72 3b 0a 20 20 61 73 73 65 72 74 28 20 70 49  cr;.  assert( pI
f360: 6e 63 72 2d 3e 62 55 73 65 54 68 72 65 61 64 20  ncr->bUseThread 
f370: 29 3b 0a 20 20 72 65 74 75 72 6e 20 76 64 62 65  );.  return vdbe
f380: 53 6f 72 74 65 72 43 72 65 61 74 65 54 68 72 65  SorterCreateThre
f390: 61 64 28 70 49 6e 63 72 2d 3e 70 54 61 73 6b 2c  ad(pIncr->pTask,
f3a0: 20 76 64 62 65 49 6e 63 72 50 6f 70 75 6c 61 74   vdbeIncrPopulat
f3b0: 65 54 68 72 65 61 64 2c 20 70 29 3b 0a 7d 0a 23  eThread, p);.}.#
f3c0: 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  endif../*.** Thi
f3d0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
f3e0: 6c 6c 65 64 20 77 68 65 6e 20 74 68 65 20 50 6d  lled when the Pm
f3f0: 61 52 65 61 64 65 72 20 63 6f 72 72 65 73 70 6f  aReader correspo
f400: 6e 64 69 6e 67 20 74 6f 20 70 49 6e 63 72 20 68  nding to pIncr h
f410: 61 73 0a 2a 2a 20 66 69 6e 69 73 68 65 64 20 72  as.** finished r
f420: 65 61 64 69 6e 67 20 74 68 65 20 63 6f 6e 74 65  eading the conte
f430: 6e 74 73 20 6f 66 20 61 46 69 6c 65 5b 30 5d 2e  nts of aFile[0].
f440: 20 49 74 73 20 70 75 72 70 6f 73 65 20 69 73 20   Its purpose is 
f450: 74 6f 20 22 72 65 66 69 6c 6c 22 0a 2a 2a 20 61  to "refill".** a
f460: 46 69 6c 65 5b 30 5d 20 73 75 63 68 20 74 68 61  File[0] such tha
f470: 74 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 20  t the PmaReader 
f480: 73 68 6f 75 6c 64 20 73 74 61 72 74 20 72 65 72  should start rer
f490: 65 61 64 69 6e 67 20 69 74 20 66 72 6f 6d 20 74  eading it from t
f4a0: 68 65 0a 2a 2a 20 62 65 67 69 6e 6e 69 6e 67 2e  he.** beginning.
f4b0: 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 73 69 6e 67 6c  .**.** For singl
f4c0: 65 2d 74 68 72 65 61 64 65 64 20 6f 62 6a 65 63  e-threaded objec
f4d0: 74 73 2c 20 74 68 69 73 20 69 73 20 61 63 63 6f  ts, this is acco
f4e0: 6d 70 6c 69 73 68 65 64 20 62 79 20 6c 69 74 65  mplished by lite
f4f0: 72 61 6c 6c 79 20 72 65 61 64 69 6e 67 20 0a 2a  rally reading .*
f500: 2a 20 6b 65 79 73 20 66 72 6f 6d 20 70 49 6e 63  * keys from pInc
f510: 72 2d 3e 70 4d 65 72 67 65 72 20 61 6e 64 20 72  r->pMerger and r
f520: 65 70 6f 70 75 6c 61 74 69 6e 67 20 61 46 69 6c  epopulating aFil
f530: 65 5b 30 5d 2e 20 0a 2a 2a 0a 2a 2a 20 46 6f 72  e[0]. .**.** For
f540: 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20   multi-threaded 
f550: 6f 62 6a 65 63 74 73 2c 20 61 6c 6c 20 74 68 61  objects, all tha
f560: 74 20 69 73 20 72 65 71 75 69 72 65 64 20 69 73  t is required is
f570: 20 74 6f 20 77 61 69 74 20 75 6e 74 69 6c 20 74   to wait until t
f580: 68 65 20 0a 2a 2a 20 62 61 63 6b 67 72 6f 75 6e  he .** backgroun
f590: 64 20 74 68 72 65 61 64 20 69 73 20 66 69 6e 69  d thread is fini
f5a0: 73 68 65 64 20 28 69 66 20 69 74 20 69 73 20 6e  shed (if it is n
f5b0: 6f 74 20 61 6c 72 65 61 64 79 29 20 61 6e 64 20  ot already) and 
f5c0: 74 68 65 6e 20 73 77 61 70 20 0a 2a 2a 20 61 46  then swap .** aF
f5d0: 69 6c 65 5b 30 5d 20 61 6e 64 20 61 46 69 6c 65  ile[0] and aFile
f5e0: 5b 31 5d 20 69 6e 20 70 6c 61 63 65 2e 20 49 66  [1] in place. If
f5f0: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
f600: 20 70 4d 65 72 67 65 72 20 68 61 76 65 20 6e 6f   pMerger have no
f610: 74 0a 2a 2a 20 62 65 65 6e 20 65 78 68 61 75 73  t.** been exhaus
f620: 74 65 64 2c 20 74 68 69 73 20 66 75 6e 63 74 69  ted, this functi
f630: 6f 6e 20 61 6c 73 6f 20 6c 61 75 6e 63 68 65 73  on also launches
f640: 20 61 20 6e 65 77 20 62 61 63 6b 67 72 6f 75 6e   a new backgroun
f650: 64 20 74 68 72 65 61 64 0a 2a 2a 20 74 6f 20 70  d thread.** to p
f660: 6f 70 75 6c 61 74 65 20 74 68 65 20 6e 65 77 20  opulate the new 
f670: 61 46 69 6c 65 5b 31 5d 2e 0a 2a 2a 0a 2a 2a 20  aFile[1]..**.** 
f680: 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74  SQLITE_OK is ret
f690: 75 72 6e 65 64 20 6f 6e 20 73 75 63 63 65 73 73  urned on success
f6a0: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65  , or an SQLite e
f6b0: 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77  rror code otherw
f6c0: 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ise..*/.static i
f6d0: 6e 74 20 76 64 62 65 49 6e 63 72 53 77 61 70 28  nt vdbeIncrSwap(
f6e0: 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63  IncrMerger *pInc
f6f0: 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  r){.  int rc = S
f700: 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 23 69 66 20 53  QLITE_OK;..#if S
f710: 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52  QLITE_MAX_WORKER
f720: 5f 54 48 52 45 41 44 53 3e 30 0a 20 20 69 66 28  _THREADS>0.  if(
f730: 20 70 49 6e 63 72 2d 3e 62 55 73 65 54 68 72 65   pIncr->bUseThre
f740: 61 64 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 76  ad ){.    rc = v
f750: 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e 54 68 72  dbeSorterJoinThr
f760: 65 61 64 28 70 49 6e 63 72 2d 3e 70 54 61 73 6b  ead(pIncr->pTask
f770: 29 3b 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  );..    if( rc==
f780: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
f790: 20 20 20 53 6f 72 74 65 72 46 69 6c 65 20 66 30     SorterFile f0
f7a0: 20 3d 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b   = pIncr->aFile[
f7b0: 30 5d 3b 0a 20 20 20 20 20 20 70 49 6e 63 72 2d  0];.      pIncr-
f7c0: 3e 61 46 69 6c 65 5b 30 5d 20 3d 20 70 49 6e 63  >aFile[0] = pInc
f7d0: 72 2d 3e 61 46 69 6c 65 5b 31 5d 3b 0a 20 20 20  r->aFile[1];.   
f7e0: 20 20 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b     pIncr->aFile[
f7f0: 31 5d 20 3d 20 66 30 3b 0a 20 20 20 20 7d 0a 0a  1] = f0;.    }..
f800: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
f810: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69  TE_OK ){.      i
f820: 66 28 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b  f( pIncr->aFile[
f830: 30 5d 2e 69 45 6f 66 3d 3d 70 49 6e 63 72 2d 3e  0].iEof==pIncr->
f840: 69 53 74 61 72 74 4f 66 66 20 29 7b 0a 20 20 20  iStartOff ){.   
f850: 20 20 20 20 20 70 49 6e 63 72 2d 3e 62 45 6f 66       pIncr->bEof
f860: 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73   = 1;.      }els
f870: 65 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  e{.        rc = 
f880: 76 64 62 65 49 6e 63 72 42 67 50 6f 70 75 6c 61  vdbeIncrBgPopula
f890: 74 65 28 70 49 6e 63 72 29 3b 0a 20 20 20 20 20  te(pIncr);.     
f8a0: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65   }.    }.  }else
f8b0: 0a 23 65 6e 64 69 66 0a 20 20 7b 0a 20 20 20 20  .#endif.  {.    
f8c0: 72 63 20 3d 20 76 64 62 65 49 6e 63 72 50 6f 70  rc = vdbeIncrPop
f8d0: 75 6c 61 74 65 28 70 49 6e 63 72 29 3b 0a 20 20  ulate(pIncr);.  
f8e0: 20 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30    pIncr->aFile[0
f8f0: 5d 20 3d 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65  ] = pIncr->aFile
f900: 5b 31 5d 3b 0a 20 20 20 20 69 66 28 20 70 49 6e  [1];.    if( pIn
f910: 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e 69 45 6f  cr->aFile[0].iEo
f920: 66 3d 3d 70 49 6e 63 72 2d 3e 69 53 74 61 72 74  f==pIncr->iStart
f930: 4f 66 66 20 29 7b 0a 20 20 20 20 20 20 70 49 6e  Off ){.      pIn
f940: 63 72 2d 3e 62 45 6f 66 20 3d 20 31 3b 0a 20 20  cr->bEof = 1;.  
f950: 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
f960: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  n rc;.}../*.** A
f970: 6c 6c 6f 63 61 74 65 20 61 6e 64 20 72 65 74 75  llocate and retu
f980: 72 6e 20 61 20 6e 65 77 20 49 6e 63 72 4d 65 72  rn a new IncrMer
f990: 67 65 72 20 6f 62 6a 65 63 74 20 74 6f 20 72 65  ger object to re
f9a0: 61 64 20 64 61 74 61 20 66 72 6f 6d 20 70 4d 65  ad data from pMe
f9b0: 72 67 65 72 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61  rger..**.** If a
f9c0: 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74 69 6f 6e 20  n OOM condition 
f9d0: 69 73 20 65 6e 63 6f 75 6e 74 65 72 65 64 2c 20  is encountered, 
f9e0: 72 65 74 75 72 6e 20 4e 55 4c 4c 2e 20 49 6e 20  return NULL. In 
f9f0: 74 68 69 73 20 63 61 73 65 20 66 72 65 65 20 74  this case free t
fa00: 68 65 0a 2a 2a 20 70 4d 65 72 67 65 72 20 61 72  he.** pMerger ar
fa10: 67 75 6d 65 6e 74 20 62 65 66 6f 72 65 20 72 65  gument before re
fa20: 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74  turning..*/.stat
fa30: 69 63 20 69 6e 74 20 76 64 62 65 49 6e 63 72 4e  ic int vdbeIncrN
fa40: 65 77 28 0a 20 20 53 6f 72 74 53 75 62 74 61 73  ew(.  SortSubtas
fa50: 6b 20 2a 70 54 61 73 6b 2c 20 0a 20 20 4d 65 72  k *pTask, .  Mer
fa60: 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67 65  geEngine *pMerge
fa70: 72 2c 0a 20 20 49 6e 63 72 4d 65 72 67 65 72 20  r,.  IncrMerger 
fa80: 2a 2a 70 70 4f 75 74 0a 29 7b 0a 20 20 69 6e 74  **ppOut.){.  int
fa90: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
faa0: 0a 20 20 49 6e 63 72 4d 65 72 67 65 72 20 2a 70  .  IncrMerger *p
fab0: 49 6e 63 72 20 3d 20 2a 70 70 4f 75 74 20 3d 20  Incr = *ppOut = 
fac0: 28 49 6e 63 72 4d 65 72 67 65 72 2a 29 0a 20 20  (IncrMerger*).  
fad0: 20 20 20 20 20 28 73 71 6c 69 74 65 33 46 61 75       (sqlite3Fau
fae0: 6c 74 53 69 6d 28 31 30 30 29 20 3f 20 30 20 3a  ltSim(100) ? 0 :
faf0: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65   sqlite3MallocZe
fb00: 72 6f 28 73 69 7a 65 6f 66 28 2a 70 49 6e 63 72  ro(sizeof(*pIncr
fb10: 29 29 29 3b 0a 20 20 69 66 28 20 70 49 6e 63 72  )));.  if( pIncr
fb20: 20 29 7b 0a 20 20 20 20 70 49 6e 63 72 2d 3e 70   ){.    pIncr->p
fb30: 4d 65 72 67 65 72 20 3d 20 70 4d 65 72 67 65 72  Merger = pMerger
fb40: 3b 0a 20 20 20 20 70 49 6e 63 72 2d 3e 70 54 61  ;.    pIncr->pTa
fb50: 73 6b 20 3d 20 70 54 61 73 6b 3b 0a 20 20 20 20  sk = pTask;.    
fb60: 70 49 6e 63 72 2d 3e 6d 78 53 7a 20 3d 20 4d 41  pIncr->mxSz = MA
fb70: 58 28 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72  X(pTask->pSorter
fb80: 2d 3e 6d 78 4b 65 79 73 69 7a 65 2b 39 2c 70 54  ->mxKeysize+9,pT
fb90: 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 6d 78  ask->pSorter->mx
fba0: 50 6d 61 53 69 7a 65 2f 32 29 3b 0a 20 20 20 20  PmaSize/2);.    
fbb0: 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f  pTask->file2.iEo
fbc0: 66 20 2b 3d 20 70 49 6e 63 72 2d 3e 6d 78 53 7a  f += pIncr->mxSz
fbd0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 76  ;.  }else{.    v
fbe0: 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46 72  dbeMergeEngineFr
fbf0: 65 65 28 70 4d 65 72 67 65 72 29 3b 0a 20 20 20  ee(pMerger);.   
fc00: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
fc10: 45 4d 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  EM;.  }.  return
fc20: 20 72 63 3b 0a 7d 0a 0a 23 69 66 20 53 51 4c 49   rc;.}..#if SQLI
fc30: 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48  TE_MAX_WORKER_TH
fc40: 52 45 41 44 53 3e 30 0a 2f 2a 0a 2a 2a 20 53 65  READS>0./*.** Se
fc50: 74 20 74 68 65 20 22 75 73 65 2d 74 68 72 65 61  t the "use-threa
fc60: 64 73 22 20 66 6c 61 67 20 6f 6e 20 6f 62 6a 65  ds" flag on obje
fc70: 63 74 20 70 49 6e 63 72 2e 0a 2a 2f 0a 73 74 61  ct pIncr..*/.sta
fc80: 74 69 63 20 76 6f 69 64 20 76 64 62 65 49 6e 63  tic void vdbeInc
fc90: 72 53 65 74 54 68 72 65 61 64 73 28 49 6e 63 72  rSetThreads(Incr
fca0: 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 29 7b 0a  Merger *pIncr){.
fcb0: 20 20 70 49 6e 63 72 2d 3e 62 55 73 65 54 68 72    pIncr->bUseThr
fcc0: 65 61 64 20 3d 20 31 3b 0a 20 20 70 49 6e 63 72  ead = 1;.  pIncr
fcd0: 2d 3e 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69  ->pTask->file2.i
fce0: 45 6f 66 20 2d 3d 20 70 49 6e 63 72 2d 3e 6d 78  Eof -= pIncr->mx
fcf0: 53 7a 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20  Sz;.}.#endif /* 
fd00: 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45  SQLITE_MAX_WORKE
fd10: 52 5f 54 48 52 45 41 44 53 3e 30 20 2a 2f 0a 0a  R_THREADS>0 */..
fd20: 23 64 65 66 69 6e 65 20 49 4e 43 52 49 4e 49 54  #define INCRINIT
fd30: 5f 4e 4f 52 4d 41 4c 20 30 0a 23 64 65 66 69 6e  _NORMAL 0.#defin
fd40: 65 20 49 4e 43 52 49 4e 49 54 5f 54 41 53 4b 20  e INCRINIT_TASK 
fd50: 20 20 31 0a 23 64 65 66 69 6e 65 20 49 4e 43 52    1.#define INCR
fd60: 49 4e 49 54 5f 52 4f 4f 54 20 20 20 32 0a 73 74  INIT_ROOT   2.st
fd70: 61 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d 61  atic int vdbePma
fd80: 52 65 61 64 65 72 49 6e 63 72 49 6e 69 74 28 50  ReaderIncrInit(P
fd90: 6d 61 52 65 61 64 65 72 20 2a 70 52 65 61 64 72  maReader *pReadr
fda0: 2c 20 69 6e 74 20 65 4d 6f 64 65 29 3b 0a 0a 2f  , int eMode);../
fdb0: 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20  *.** Initialize 
fdc0: 74 68 65 20 6d 65 72 67 65 72 20 61 72 67 75 6d  the merger argum
fdd0: 65 6e 74 20 70 61 73 73 65 64 20 61 73 20 74 68  ent passed as th
fde0: 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e  e second argumen
fdf0: 74 2e 20 4f 6e 63 65 20 74 68 69 73 0a 2a 2a 20  t. Once this.** 
fe00: 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73  function returns
fe10: 2c 20 74 68 65 20 66 69 72 73 74 20 6b 65 79 20  , the first key 
fe20: 6f 66 20 6d 65 72 67 65 64 20 64 61 74 61 20 6d  of merged data m
fe30: 61 79 20 62 65 20 72 65 61 64 20 66 72 6f 6d 20  ay be read from 
fe40: 74 68 65 20 6d 65 72 67 65 72 0a 2a 2a 20 6f 62  the merger.** ob
fe50: 6a 65 63 74 20 69 6e 20 74 68 65 20 75 73 75 61  ject in the usua
fe60: 6c 20 66 61 73 68 69 6f 6e 2e 0a 2a 2a 0a 2a 2a  l fashion..**.**
fe70: 20 49 66 20 61 72 67 75 6d 65 6e 74 20 65 4d 6f   If argument eMo
fe80: 64 65 20 69 73 20 49 4e 43 52 49 4e 49 54 5f 52  de is INCRINIT_R
fe90: 4f 4f 54 2c 20 74 68 65 6e 20 69 74 20 69 73 20  OOT, then it is 
fea0: 61 73 73 75 6d 65 64 20 74 68 61 74 20 61 6e 79  assumed that any
feb0: 20 49 6e 63 72 4d 65 72 67 65 0a 2a 2a 20 6f 62   IncrMerge.** ob
fec0: 6a 65 63 74 73 20 61 74 74 61 63 68 65 64 20 74  jects attached t
fed0: 6f 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 20  o the PmaReader 
fee0: 6f 62 6a 65 63 74 73 20 74 68 61 74 20 74 68 65  objects that the
fef0: 20 6d 65 72 67 65 72 20 72 65 61 64 73 20 66 72   merger reads fr
ff00: 6f 6d 20 68 61 76 65 0a 2a 2a 20 61 6c 72 65 61  om have.** alrea
ff10: 64 79 20 62 65 65 6e 20 70 6f 70 75 6c 61 74 65  dy been populate
ff20: 64 2c 20 62 75 74 20 74 68 61 74 20 74 68 65 79  d, but that they
ff30: 20 68 61 76 65 20 6e 6f 74 20 79 65 74 20 70 6f   have not yet po
ff40: 70 75 6c 61 74 65 64 20 61 46 69 6c 65 5b 30 5d  pulated aFile[0]
ff50: 20 61 6e 64 0a 2a 2a 20 73 65 74 20 74 68 65 20   and.** set the 
ff60: 50 6d 61 52 65 61 64 65 72 20 6f 62 6a 65 63 74  PmaReader object
ff70: 73 20 75 70 20 74 6f 20 72 65 61 64 20 66 72 6f  s up to read fro
ff80: 6d 20 69 74 2e 20 49 6e 20 74 68 69 73 20 63 61  m it. In this ca
ff90: 73 65 20 61 6c 6c 20 74 68 61 74 20 69 73 0a 2a  se all that is.*
ffa0: 2a 20 72 65 71 75 69 72 65 64 20 69 73 20 74 6f  * required is to
ffb0: 20 63 61 6c 6c 20 76 64 62 65 50 6d 61 52 65 61   call vdbePmaRea
ffc0: 64 65 72 4e 65 78 74 28 29 20 6f 6e 20 65 61 63  derNext() on eac
ffd0: 68 20 50 6d 61 52 65 61 64 65 72 20 74 6f 20 70  h PmaReader to p
ffe0: 6f 69 6e 74 20 69 74 20 61 74 0a 2a 2a 20 69 74  oint it at.** it
fff0: 73 20 66 69 72 73 74 20 6b 65 79 2e 0a 2a 2a 0a  s first key..**.
10000 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66  ** Otherwise, if
10010 20 65 4d 6f 64 65 20 69 73 20 61 6e 79 20 76 61   eMode is any va
10020 6c 75 65 20 6f 74 68 65 72 20 74 68 61 6e 20 49  lue other than I
10030 4e 43 52 49 4e 49 54 5f 52 4f 4f 54 2c 20 74 68  NCRINIT_ROOT, th
10040 65 6e 20 75 73 65 20 0a 2a 2a 20 76 64 62 65 50  en use .** vdbeP
10050 6d 61 52 65 61 64 65 72 49 6e 63 72 49 6e 69 74  maReaderIncrInit
10060 28 29 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65  () to initialize
10070 20 65 61 63 68 20 50 6d 61 52 65 61 64 65 72 20   each PmaReader 
10080 74 68 61 74 20 66 65 65 64 73 20 64 61 74 61 20  that feeds data 
10090 0a 2a 2a 20 74 6f 20 70 4d 65 72 67 65 72 2e 0a  .** to pMerger..
100a0 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20  **.** SQLITE_OK 
100b0 69 73 20 72 65 74 75 72 6e 65 64 20 69 66 20 73  is returned if s
100c0 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e  uccessful, or an
100d0 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
100e0 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f  de otherwise..*/
100f0 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65  .static int vdbe
10100 49 6e 63 72 49 6e 69 74 4d 65 72 67 65 72 28 0a  IncrInitMerger(.
10110 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70    SortSubtask *p
10120 54 61 73 6b 2c 20 0a 20 20 4d 65 72 67 65 45 6e  Task, .  MergeEn
10130 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 2c 20 0a  gine *pMerger, .
10140 20 20 69 6e 74 20 65 4d 6f 64 65 20 20 20 20 20    int eMode     
10150 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10160 20 20 2f 2a 20 4f 6e 65 20 6f 66 20 74 68 65 20    /* One of the 
10170 49 4e 43 52 49 4e 49 54 5f 58 58 58 20 63 6f 6e  INCRINIT_XXX con
10180 73 74 61 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 69  stants */.){.  i
10190 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
101a0 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  K;             /
101b0 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
101c0 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20  .  int i;       
101d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
101e0 20 20 20 2f 2a 20 46 6f 72 20 6c 6f 6f 70 69 6e     /* For loopin
101f0 67 20 6f 76 65 72 20 50 6d 61 52 65 61 64 65 72  g over PmaReader
10200 20 6f 62 6a 65 63 74 73 20 2a 2f 0a 20 20 69 6e   objects */.  in
10210 74 20 6e 54 72 65 65 20 3d 20 70 4d 65 72 67 65  t nTree = pMerge
10220 72 2d 3e 6e 54 72 65 65 3b 0a 0a 20 20 66 6f 72  r->nTree;..  for
10230 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45  (i=0; rc==SQLITE
10240 5f 4f 4b 20 26 26 20 69 3c 6e 54 72 65 65 3b 20  _OK && i<nTree; 
10250 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 65 4d  i++){.    if( eM
10260 6f 64 65 3d 3d 49 4e 43 52 49 4e 49 54 5f 52 4f  ode==INCRINIT_RO
10270 4f 54 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 50  OT ){.      /* P
10280 6d 61 52 65 61 64 65 72 73 20 73 68 6f 75 6c 64  maReaders should
10290 20 62 65 20 6e 6f 72 6d 61 6c 6c 79 20 69 6e 69   be normally ini
102a0 74 69 61 6c 69 7a 65 64 20 69 6e 20 6f 72 64 65  tialized in orde
102b0 72 2c 20 61 73 20 69 66 20 74 68 65 79 20 61 72  r, as if they ar
102c0 65 0a 20 20 20 20 20 20 2a 2a 20 72 65 61 64 69  e.      ** readi
102d0 6e 67 20 66 72 6f 6d 20 74 68 65 20 73 61 6d 65  ng from the same
102e0 20 74 65 6d 70 20 66 69 6c 65 20 74 68 69 73 20   temp file this 
102f0 6d 61 6b 65 73 20 66 6f 72 20 6d 6f 72 65 20 6c  makes for more l
10300 69 6e 65 61 72 20 66 69 6c 65 20 49 4f 2e 0a 20  inear file IO.. 
10310 20 20 20 20 20 2a 2a 20 48 6f 77 65 76 65 72 2c       ** However,
10320 20 69 6e 20 74 68 65 20 49 4e 43 52 49 4e 49 54   in the INCRINIT
10330 5f 52 4f 4f 54 20 63 61 73 65 2c 20 69 66 20 50  _ROOT case, if P
10340 6d 61 52 65 61 64 65 72 20 61 52 65 61 64 72 5b  maReader aReadr[
10350 6e 54 61 73 6b 2d 31 5d 20 69 73 0a 20 20 20 20  nTask-1] is.    
10360 20 20 2a 2a 20 69 6e 20 75 73 65 20 69 74 20 77    ** in use it w
10370 69 6c 6c 20 62 6c 6f 63 6b 20 74 68 65 20 76 64  ill block the vd
10380 62 65 50 6d 61 52 65 61 64 65 72 4e 65 78 74 28  bePmaReaderNext(
10390 29 20 63 61 6c 6c 20 77 68 69 6c 65 20 69 74 20  ) call while it 
103a0 75 73 65 73 0a 20 20 20 20 20 20 2a 2a 20 74 68  uses.      ** th
103b0 65 20 6d 61 69 6e 20 74 68 72 65 61 64 20 74 6f  e main thread to
103c0 20 66 69 6c 6c 20 69 74 73 20 62 75 66 66 65 72   fill its buffer
103d0 2e 20 53 6f 20 63 61 6c 6c 69 6e 67 20 50 6d 61  . So calling Pma
103e0 52 65 61 64 65 72 4e 65 78 74 28 29 0a 20 20 20  ReaderNext().   
103f0 20 20 20 2a 2a 20 6f 6e 20 74 68 69 73 20 50 6d     ** on this Pm
10400 61 52 65 61 64 65 72 20 62 65 66 6f 72 65 20 61  aReader before a
10410 6e 79 20 6f 66 20 74 68 65 20 6d 75 6c 74 69 2d  ny of the multi-
10420 74 68 72 65 61 64 65 64 20 50 6d 61 52 65 61 64  threaded PmaRead
10430 65 72 73 20 74 61 6b 65 73 0a 20 20 20 20 20 20  ers takes.      
10440 2a 2a 20 62 65 74 74 65 72 20 61 64 76 61 6e 74  ** better advant
10450 61 67 65 20 6f 66 20 6d 75 6c 74 69 2d 70 72 6f  age of multi-pro
10460 63 65 73 73 6f 72 20 68 61 72 64 77 61 72 65 2e  cessor hardware.
10470 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 76   */.      rc = v
10480 64 62 65 50 6d 61 52 65 61 64 65 72 4e 65 78 74  dbePmaReaderNext
10490 28 26 70 4d 65 72 67 65 72 2d 3e 61 52 65 61 64  (&pMerger->aRead
104a0 72 5b 6e 54 72 65 65 2d 69 2d 31 5d 29 3b 0a 20  r[nTree-i-1]);. 
104b0 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
104c0 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64  rc = vdbePmaRead
104d0 65 72 49 6e 63 72 49 6e 69 74 28 26 70 4d 65 72  erIncrInit(&pMer
104e0 67 65 72 2d 3e 61 52 65 61 64 72 5b 69 5d 2c 20  ger->aReadr[i], 
104f0 49 4e 43 52 49 4e 49 54 5f 4e 4f 52 4d 41 4c 29  INCRINIT_NORMAL)
10500 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 66  ;.    }.  }..  f
10510 6f 72 28 69 3d 70 4d 65 72 67 65 72 2d 3e 6e 54  or(i=pMerger->nT
10520 72 65 65 2d 31 3b 20 72 63 3d 3d 53 51 4c 49 54  ree-1; rc==SQLIT
10530 45 5f 4f 4b 20 26 26 20 69 3e 30 3b 20 69 2d 2d  E_OK && i>0; i--
10540 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65  ){.    rc = vdbe
10550 53 6f 72 74 65 72 44 6f 43 6f 6d 70 61 72 65 28  SorterDoCompare(
10560 70 54 61 73 6b 2c 20 70 4d 65 72 67 65 72 2c 20  pTask, pMerger, 
10570 69 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  i);.  }..  retur
10580 6e 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  n (rc==SQLITE_OK
10590 20 3f 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63   ? pTask->pUnpac
105a0 6b 65 64 2d 3e 65 72 72 43 6f 64 65 20 3a 20 72  ked->errCode : r
105b0 63 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20  c);.}../*.** If 
105c0 74 68 65 20 50 6d 61 52 65 61 64 65 72 20 70 61  the PmaReader pa
105d0 73 73 65 64 20 61 73 20 74 68 65 20 66 69 72 73  ssed as the firs
105e0 74 20 61 72 67 75 6d 65 6e 74 20 69 73 20 6e 6f  t argument is no
105f0 74 20 61 6e 20 69 6e 63 72 65 6d 65 6e 74 61 6c  t an incremental
10600 2d 72 65 61 64 65 72 0a 2a 2a 20 28 69 66 20 70  -reader.** (if p
10610 52 65 61 64 72 2d 3e 70 49 6e 63 72 3d 3d 30 29  Readr->pIncr==0)
10620 2c 20 74 68 65 6e 20 74 68 69 73 20 66 75 6e 63  , then this func
10630 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 2e  tion is a no-op.
10640 20 4f 74 68 65 72 77 69 73 65 2c 20 69 74 20 73   Otherwise, it s
10650 65 72 76 65 73 0a 2a 2a 20 74 6f 20 6f 70 65 6e  erves.** to open
10660 20 61 6e 64 2f 6f 72 20 69 6e 69 74 69 61 6c 69   and/or initiali
10670 7a 65 20 74 68 65 20 74 65 6d 70 20 66 69 6c 65  ze the temp file
10680 20 72 65 6c 61 74 65 64 20 66 69 65 6c 64 73 20   related fields 
10690 6f 66 20 74 68 65 20 49 6e 63 72 4d 65 72 67 65  of the IncrMerge
106a0 0a 2a 2a 20 6f 62 6a 65 63 74 20 61 74 20 28 70  .** object at (p
106b0 52 65 61 64 72 2d 3e 70 49 6e 63 72 29 2e 0a 2a  Readr->pIncr)..*
106c0 2a 0a 2a 2a 20 49 66 20 61 72 67 75 6d 65 6e 74  *.** If argument
106d0 20 65 4d 6f 64 65 20 69 73 20 73 65 74 20 74 6f   eMode is set to
106e0 20 49 4e 43 52 49 4e 49 54 5f 4e 4f 52 4d 41 4c   INCRINIT_NORMAL
106f0 2c 20 74 68 65 6e 20 50 6d 61 52 65 61 64 65 72  , then PmaReader
10700 20 50 6d 61 52 65 61 64 65 72 73 0a 2a 2a 20 69   PmaReaders.** i
10710 6e 20 74 68 65 20 73 75 62 2d 74 72 65 65 20 68  n the sub-tree h
10720 65 61 64 65 64 20 62 79 20 70 52 65 61 64 72 20  eaded by pReadr 
10730 61 72 65 20 61 6c 73 6f 20 69 6e 69 74 69 61 6c  are also initial
10740 69 7a 65 64 2e 20 44 61 74 61 20 69 73 20 74 68  ized. Data is th
10750 65 6e 20 6c 6f 61 64 65 64 0a 2a 2a 20 69 6e 74  en loaded.** int
10760 6f 20 74 68 65 20 62 75 66 66 65 72 73 20 62 65  o the buffers be
10770 6c 6f 6e 67 69 6e 67 20 74 6f 20 74 68 69 73 20  longing to this 
10780 50 6d 61 52 65 61 64 65 72 2c 20 70 52 65 61 64  PmaReader, pRead
10790 72 2c 20 61 6e 64 20 69 74 20 69 73 20 73 65 74  r, and it is set
107a0 20 74 6f 0a 2a 2a 20 70 6f 69 6e 74 20 74 6f 20   to.** point to 
107b0 74 68 65 20 66 69 72 73 74 20 6b 65 79 20 69 6e  the first key in
107c0 20 69 74 73 20 72 61 6e 67 65 2e 0a 2a 2a 0a 2a   its range..**.*
107d0 2a 20 49 66 20 61 72 67 75 6d 65 6e 74 20 65 4d  * If argument eM
107e0 6f 64 65 20 69 73 20 73 65 74 20 74 6f 20 49 4e  ode is set to IN
107f0 43 52 49 4e 49 54 5f 54 41 53 4b 2c 20 74 68 65  CRINIT_TASK, the
10800 6e 20 50 6d 61 52 65 61 64 65 72 20 69 73 20 67  n PmaReader is g
10810 75 61 72 61 6e 74 65 65 64 0a 2a 2a 20 74 6f 20  uaranteed.** to 
10820 62 65 20 61 20 6d 75 6c 74 69 2d 74 68 72 65 61  be a multi-threa
10830 64 65 64 20 50 6d 61 52 65 61 64 65 72 20 61 6e  ded PmaReader an
10840 64 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  d this function 
10850 69 73 20 62 65 69 6e 67 20 63 61 6c 6c 65 64 20  is being called 
10860 69 6e 20 61 0a 2a 2a 20 62 61 63 6b 67 72 6f 75  in a.** backgrou
10870 6e 64 20 74 68 72 65 61 64 2e 20 49 6e 20 74 68  nd thread. In th
10880 69 73 20 63 61 73 65 20 61 6c 6c 20 50 6d 61 52  is case all PmaR
10890 65 61 64 65 72 73 20 69 6e 20 74 68 65 20 73 75  eaders in the su
108a0 62 2d 74 72 65 65 20 61 72 65 20 0a 2a 2a 20 69  b-tree are .** i
108b0 6e 69 74 69 61 6c 69 7a 65 64 20 61 73 20 66 6f  nitialized as fo
108c0 72 20 49 4e 43 52 49 4e 49 54 5f 4e 4f 52 4d 41  r INCRINIT_NORMA
108d0 4c 20 61 6e 64 20 74 68 65 20 61 46 69 6c 65 5b  L and the aFile[
108e0 31 5d 20 62 75 66 66 65 72 20 62 65 6c 6f 6e 67  1] buffer belong
108f0 69 6e 67 20 74 6f 0a 2a 2a 20 70 52 65 61 64 72  ing to.** pReadr
10900 20 69 73 20 70 6f 70 75 6c 61 74 65 64 2e 20 48   is populated. H
10910 6f 77 65 76 65 72 2c 20 74 68 65 20 50 6d 61 52  owever, the PmaR
10920 65 61 64 65 72 20 69 74 73 65 6c 66 20 69 73 20  eader itself is 
10930 6e 6f 74 20 73 65 74 20 75 70 20 74 6f 20 70 6f  not set up to po
10940 69 6e 74 0a 2a 2a 20 74 6f 20 69 74 73 20 66 69  int.** to its fi
10950 72 73 74 20 6b 65 79 2e 20 41 20 63 61 6c 6c 20  rst key. A call 
10960 74 6f 20 76 64 62 65 50 6d 61 52 65 61 64 65 72  to vdbePmaReader
10970 4e 65 78 74 28 29 20 69 73 20 73 74 69 6c 6c 20  Next() is still 
10980 72 65 71 75 69 72 65 64 20 74 6f 20 64 6f 0a 2a  required to do.*
10990 2a 20 74 68 61 74 2e 20 0a 2a 2a 0a 2a 2a 20 54  * that. .**.** T
109a0 68 65 20 72 65 61 73 6f 6e 20 74 68 69 73 20 66  he reason this f
109b0 75 6e 63 74 69 6f 6e 20 64 6f 65 73 20 6e 6f 74  unction does not
109c0 20 63 61 6c 6c 20 76 64 62 65 50 6d 61 52 65 61   call vdbePmaRea
109d0 64 65 72 4e 65 78 74 28 29 20 69 6d 6d 65 64 69  derNext() immedi
109e0 61 74 65 6c 79 20 0a 2a 2a 20 69 6e 20 74 68 65  ately .** in the
109f0 20 49 4e 43 52 49 4e 49 54 5f 54 41 53 4b 20 63   INCRINIT_TASK c
10a00 61 73 65 20 69 73 20 74 68 61 74 20 76 64 62 65  ase is that vdbe
10a10 50 6d 61 52 65 61 64 65 72 4e 65 78 74 28 29 20  PmaReaderNext() 
10a20 61 73 73 75 6d 65 73 20 74 68 61 74 20 68 61 73  assumes that has
10a30 0a 2a 2a 20 74 6f 20 62 6c 6f 63 6b 20 6f 6e 20  .** to block on 
10a40 74 68 72 65 61 64 20 28 70 54 61 73 6b 2d 3e 74  thread (pTask->t
10a50 68 72 65 61 64 29 20 62 65 66 6f 72 65 20 61 63  hread) before ac
10a60 63 65 73 73 69 6e 67 20 61 46 69 6c 65 5b 31 5d  cessing aFile[1]
10a70 2e 20 42 75 74 2c 20 73 69 6e 63 65 0a 2a 2a 20  . But, since.** 
10a80 74 68 69 73 20 65 6e 74 69 72 65 20 66 75 6e 63  this entire func
10a90 74 69 6f 6e 20 69 73 20 62 65 69 6e 67 20 72 75  tion is being ru
10aa0 6e 20 62 79 20 74 68 72 65 61 64 20 28 70 54 61  n by thread (pTa
10ab0 73 6b 2d 3e 74 68 72 65 61 64 29 2c 20 74 68 61  sk->thread), tha
10ac0 74 20 77 69 6c 6c 0a 2a 2a 20 6c 65 61 64 20 74  t will.** lead t
10ad0 6f 20 74 68 65 20 63 75 72 72 65 6e 74 20 62 61  o the current ba
10ae0 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
10af0 61 74 74 65 6d 70 74 69 6e 67 20 74 6f 20 6a 6f  attempting to jo
10b00 69 6e 20 69 74 73 65 6c 66 2e 0a 2a 2a 0a 2a 2a  in itself..**.**
10b10 20 46 69 6e 61 6c 6c 79 2c 20 69 66 20 61 72 67   Finally, if arg
10b20 75 6d 65 6e 74 20 65 4d 6f 64 65 20 69 73 20 73  ument eMode is s
10b30 65 74 20 74 6f 20 49 4e 43 52 49 4e 49 54 5f 52  et to INCRINIT_R
10b40 4f 4f 54 2c 20 69 74 20 6d 61 79 20 62 65 20 61  OOT, it may be a
10b50 73 73 75 6d 65 64 0a 2a 2a 20 74 68 61 74 20 70  ssumed.** that p
10b60 52 65 61 64 72 2d 3e 70 49 6e 63 72 20 69 73 20  Readr->pIncr is 
10b70 61 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64  a multi-threaded
10b80 20 49 6e 63 72 4d 65 72 67 65 20 6f 62 6a 65 63   IncrMerge objec
10b90 74 73 2c 20 61 6e 64 20 74 68 61 74 20 61 6c 6c  ts, and that all
10ba0 0a 2a 2a 20 63 68 69 6c 64 2d 74 72 65 65 73 20  .** child-trees 
10bb0 68 61 76 65 20 61 6c 72 65 61 64 79 20 62 65 65  have already bee
10bc0 6e 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 75 73  n initialized us
10bd0 69 6e 67 20 49 6e 63 72 49 6e 69 74 28 49 4e 43  ing IncrInit(INC
10be0 52 49 4e 49 54 5f 54 41 53 4b 29 2e 0a 2a 2a 20  RINIT_TASK)..** 
10bf0 49 6e 20 74 68 69 73 20 63 61 73 65 20 76 64 62  In this case vdb
10c00 65 50 6d 61 52 65 61 64 65 72 4e 65 78 74 28 29  ePmaReaderNext()
10c10 20 69 73 20 63 61 6c 6c 65 64 20 6f 6e 20 61 6c   is called on al
10c20 6c 20 63 68 69 6c 64 20 50 6d 61 52 65 61 64 65  l child PmaReade
10c30 72 73 20 61 6e 64 0a 2a 2a 20 74 68 65 20 63 75  rs and.** the cu
10c40 72 72 65 6e 74 20 50 6d 61 52 65 61 64 65 72 20  rrent PmaReader 
10c50 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  set to point to 
10c60 74 68 65 20 66 69 72 73 74 20 6b 65 79 20 69 6e  the first key in
10c70 20 69 74 73 20 72 61 6e 67 65 2e 0a 2a 2a 0a 2a   its range..**.*
10c80 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72  * SQLITE_OK is r
10c90 65 74 75 72 6e 65 64 20 69 66 20 73 75 63 63 65  eturned if succe
10ca0 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c  ssful, or an SQL
10cb0 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 6f  ite error code o
10cc0 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61  therwise..*/.sta
10cd0 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d 61 52  tic int vdbePmaR
10ce0 65 61 64 65 72 49 6e 63 72 49 6e 69 74 28 50 6d  eaderIncrInit(Pm
10cf0 61 52 65 61 64 65 72 20 2a 70 52 65 61 64 72 2c  aReader *pReadr,
10d00 20 69 6e 74 20 65 4d 6f 64 65 29 7b 0a 20 20 69   int eMode){.  i
10d10 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
10d20 4b 3b 0a 20 20 49 6e 63 72 4d 65 72 67 65 72 20  K;.  IncrMerger 
10d30 2a 70 49 6e 63 72 20 3d 20 70 52 65 61 64 72 2d  *pIncr = pReadr-
10d40 3e 70 49 6e 63 72 3b 0a 20 20 69 66 28 20 70 49  >pIncr;.  if( pI
10d50 6e 63 72 20 29 7b 0a 20 20 20 20 53 6f 72 74 53  ncr ){.    SortS
10d60 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20  ubtask *pTask = 
10d70 70 49 6e 63 72 2d 3e 70 54 61 73 6b 3b 0a 20 20  pIncr->pTask;.  
10d80 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20 3d 20    sqlite3 *db = 
10d90 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e  pTask->pSorter->
10da0 64 62 3b 0a 0a 20 20 20 20 72 63 20 3d 20 76 64  db;..    rc = vd
10db0 62 65 49 6e 63 72 49 6e 69 74 4d 65 72 67 65 72  beIncrInitMerger
10dc0 28 70 54 61 73 6b 2c 20 70 49 6e 63 72 2d 3e 70  (pTask, pIncr->p
10dd0 4d 65 72 67 65 72 2c 20 65 4d 6f 64 65 29 3b 0a  Merger, eMode);.
10de0 0a 20 20 20 20 2f 2a 20 53 65 74 20 75 70 20 74  .    /* Set up t
10df0 68 65 20 72 65 71 75 69 72 65 64 20 66 69 6c 65  he required file
10e00 73 20 66 6f 72 20 70 49 6e 63 72 2e 20 41 20 6d  s for pIncr. A m
10e10 75 6c 74 69 2d 74 68 65 61 64 65 64 20 49 6e 63  ulti-theaded Inc
10e20 72 4d 65 72 67 65 20 6f 62 6a 65 63 74 0a 20 20  rMerge object.  
10e30 20 20 2a 2a 20 72 65 71 75 69 72 65 73 20 74 77    ** requires tw
10e40 6f 20 74 65 6d 70 20 66 69 6c 65 73 20 74 6f 20  o temp files to 
10e50 69 74 73 65 6c 66 2c 20 77 68 65 72 65 61 73 20  itself, whereas 
10e60 61 20 73 69 6e 67 6c 65 2d 74 68 72 65 61 64 65  a single-threade
10e70 64 20 6f 62 6a 65 63 74 0a 20 20 20 20 2a 2a 20  d object.    ** 
10e80 6f 6e 6c 79 20 72 65 71 75 69 72 65 73 20 61 20  only requires a 
10e90 72 65 67 69 6f 6e 20 6f 66 20 70 54 61 73 6b 2d  region of pTask-
10ea0 3e 66 69 6c 65 32 2e 20 2a 2f 0a 20 20 20 20 69  >file2. */.    i
10eb0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
10ec0 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6d 78   ){.      int mx
10ed0 53 7a 20 3d 20 70 49 6e 63 72 2d 3e 6d 78 53 7a  Sz = pIncr->mxSz
10ee0 3b 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58  ;.#if SQLITE_MAX
10ef0 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e  _WORKER_THREADS>
10f00 30 0a 20 20 20 20 20 20 69 66 28 20 70 49 6e 63  0.      if( pInc
10f10 72 2d 3e 62 55 73 65 54 68 72 65 61 64 20 29 7b  r->bUseThread ){
10f20 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64  .        rc = vd
10f30 62 65 53 6f 72 74 65 72 4f 70 65 6e 54 65 6d 70  beSorterOpenTemp
10f40 46 69 6c 65 28 64 62 2c 20 6d 78 53 7a 2c 20 26  File(db, mxSz, &
10f50 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e  pIncr->aFile[0].
10f60 70 46 64 29 3b 0a 20 20 20 20 20 20 20 20 69 66  pFd);.        if
10f70 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
10f80 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  ){.          rc 
10f90 3d 20 76 64 62 65 53 6f 72 74 65 72 4f 70 65 6e  = vdbeSorterOpen
10fa0 54 65 6d 70 46 69 6c 65 28 64 62 2c 20 6d 78 53  TempFile(db, mxS
10fb0 7a 2c 20 26 70 49 6e 63 72 2d 3e 61 46 69 6c 65  z, &pIncr->aFile
10fc0 5b 31 5d 2e 70 46 64 29 3b 0a 20 20 20 20 20 20  [1].pFd);.      
10fd0 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 0a    }.      }else.
10fe0 23 65 6e 64 69 66 0a 20 20 20 20 20 20 2f 2a 69  #endif.      /*i
10ff0 66 28 20 21 70 49 6e 63 72 2d 3e 62 55 73 65 54  f( !pIncr->bUseT
11000 68 72 65 61 64 20 29 2a 2f 7b 0a 20 20 20 20 20  hread )*/{.     
11010 20 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 66 69     if( pTask->fi
11020 6c 65 32 2e 70 46 64 3d 3d 30 20 29 7b 0a 20 20  le2.pFd==0 ){.  
11030 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
11040 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f  pTask->file2.iEo
11050 66 3e 30 20 29 3b 0a 20 20 20 20 20 20 20 20 20  f>0 );.         
11060 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
11070 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 64 62 2c  OpenTempFile(db,
11080 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45   pTask->file2.iE
11090 6f 66 2c 20 26 70 54 61 73 6b 2d 3e 66 69 6c 65  of, &pTask->file
110a0 32 2e 70 46 64 29 3b 0a 20 20 20 20 20 20 20 20  2.pFd);.        
110b0 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69    pTask->file2.i
110c0 45 6f 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  Eof = 0;.       
110d0 20 7d 0a 20 20 20 20 20 20 20 20 69 66 28 20 72   }.        if( r
110e0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
110f0 20 20 20 20 20 20 20 20 20 20 70 49 6e 63 72 2d            pIncr-
11100 3e 61 46 69 6c 65 5b 31 5d 2e 70 46 64 20 3d 20  >aFile[1].pFd = 
11110 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64  pTask->file2.pFd
11120 3b 0a 20 20 20 20 20 20 20 20 20 20 70 49 6e 63  ;.          pInc
11130 72 2d 3e 69 53 74 61 72 74 4f 66 66 20 3d 20 70  r->iStartOff = p
11140 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66  Task->file2.iEof
11150 3b 0a 20 20 20 20 20 20 20 20 20 20 70 54 61 73  ;.          pTas
11160 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 20 2b 3d  k->file2.iEof +=
11170 20 6d 78 53 7a 3b 0a 20 20 20 20 20 20 20 20 7d   mxSz;.        }
11180 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
11190 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57  #if SQLITE_MAX_W
111a0 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 0a  ORKER_THREADS>0.
111b0 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
111c0 54 45 5f 4f 4b 20 26 26 20 70 49 6e 63 72 2d 3e  TE_OK && pIncr->
111d0 62 55 73 65 54 68 72 65 61 64 20 29 7b 0a 20 20  bUseThread ){.  
111e0 20 20 20 20 2f 2a 20 55 73 65 20 74 68 65 20 63      /* Use the c
111f0 75 72 72 65 6e 74 20 74 68 72 65 61 64 20 74 6f  urrent thread to
11200 20 70 6f 70 75 6c 61 74 65 20 61 46 69 6c 65 5b   populate aFile[
11210 31 5d 2c 20 65 76 65 6e 20 74 68 6f 75 67 68 20  1], even though 
11220 74 68 69 73 0a 20 20 20 20 20 20 2a 2a 20 50 6d  this.      ** Pm
11230 61 52 65 61 64 65 72 20 69 73 20 6d 75 6c 74 69  aReader is multi
11240 2d 74 68 72 65 61 64 65 64 2e 20 54 68 65 20 72  -threaded. The r
11250 65 61 73 6f 6e 20 62 65 69 6e 67 20 74 68 61 74  eason being that
11260 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 0a 20   this function. 
11270 20 20 20 20 20 2a 2a 20 69 73 20 61 6c 72 65 61       ** is alrea
11280 64 79 20 72 75 6e 6e 69 6e 67 20 69 6e 20 62 61  dy running in ba
11290 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
112a0 70 49 6e 63 72 2d 3e 70 54 61 73 6b 2d 3e 74 68  pIncr->pTask->th
112b0 72 65 61 64 2e 20 2a 2f 0a 20 20 20 20 20 20 61  read. */.      a
112c0 73 73 65 72 74 28 20 65 4d 6f 64 65 3d 3d 49 4e  ssert( eMode==IN
112d0 43 52 49 4e 49 54 5f 52 4f 4f 54 20 7c 7c 20 65  CRINIT_ROOT || e
112e0 4d 6f 64 65 3d 3d 49 4e 43 52 49 4e 49 54 5f 54  Mode==INCRINIT_T
112f0 41 53 4b 20 29 3b 0a 20 20 20 20 20 20 72 63 20  ASK );.      rc 
11300 3d 20 76 64 62 65 49 6e 63 72 50 6f 70 75 6c 61  = vdbeIncrPopula
11310 74 65 28 70 49 6e 63 72 29 3b 0a 20 20 20 20 7d  te(pIncr);.    }
11320 0a 23 65 6e 64 69 66 0a 0a 20 20 20 20 69 66 28  .#endif..    if(
11330 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
11340 26 20 65 4d 6f 64 65 21 3d 49 4e 43 52 49 4e 49  & eMode!=INCRINI
11350 54 5f 54 41 53 4b 20 29 7b 0a 20 20 20 20 20 20  T_TASK ){.      
11360 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64  rc = vdbePmaRead
11370 65 72 4e 65 78 74 28 70 52 65 61 64 72 29 3b 0a  erNext(pReadr);.
11380 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
11390 72 6e 20 72 63 3b 0a 7d 0a 0a 23 69 66 20 53 51  rn rc;.}..#if SQ
113a0 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f  LITE_MAX_WORKER_
113b0 54 48 52 45 41 44 53 3e 30 0a 2f 2a 0a 2a 2a 20  THREADS>0./*.** 
113c0 54 68 65 20 6d 61 69 6e 20 72 6f 75 74 69 6e 65  The main routine
113d0 20 66 6f 72 20 76 64 62 65 50 6d 61 52 65 61 64   for vdbePmaRead
113e0 65 72 49 6e 63 72 49 6e 69 74 28 29 20 6f 70 65  erIncrInit() ope
113f0 72 61 74 69 6f 6e 73 20 72 75 6e 20 69 6e 20 0a  rations run in .
11400 2a 2a 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68  ** background th
11410 72 65 61 64 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  reads..*/.static
11420 20 76 6f 69 64 20 2a 76 64 62 65 50 6d 61 52 65   void *vdbePmaRe
11430 61 64 65 72 42 67 49 6e 69 74 28 76 6f 69 64 20  aderBgInit(void 
11440 2a 70 43 74 78 29 7b 0a 20 20 50 6d 61 52 65 61  *pCtx){.  PmaRea
11450 64 65 72 20 2a 70 52 65 61 64 65 72 20 3d 20 28  der *pReader = (
11460 50 6d 61 52 65 61 64 65 72 2a 29 70 43 74 78 3b  PmaReader*)pCtx;
11470 0a 20 20 76 6f 69 64 20 2a 70 52 65 74 20 3d 20  .  void *pRet = 
11480 53 51 4c 49 54 45 5f 49 4e 54 5f 54 4f 5f 50 54  SQLITE_INT_TO_PT
11490 52 28 76 64 62 65 50 6d 61 52 65 61 64 65 72 49  R(vdbePmaReaderI
114a0 6e 63 72 49 6e 69 74 28 70 52 65 61 64 65 72 2c  ncrInit(pReader,
114b0 49 4e 43 52 49 4e 49 54 5f 54 41 53 4b 29 29 3b  INCRINIT_TASK));
114c0 0a 20 20 70 52 65 61 64 65 72 2d 3e 70 49 6e 63  .  pReader->pInc
114d0 72 2d 3e 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 20  r->pTask->bDone 
114e0 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 70 52  = 1;.  return pR
114f0 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73 65  et;.}../*.** Use
11500 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68   a background th
11510 72 65 61 64 20 74 6f 20 69 6e 76 6f 6b 65 20 76  read to invoke v
11520 64 62 65 50 6d 61 52 65 61 64 65 72 49 6e 63 72  dbePmaReaderIncr
11530 49 6e 69 74 28 49 4e 43 52 49 4e 49 54 5f 54 41  Init(INCRINIT_TA
11540 53 4b 29 20 0a 2a 2a 20 6f 6e 20 74 68 65 20 74  SK) .** on the t
11550 68 65 20 50 6d 61 52 65 61 64 65 72 20 6f 62 6a  he PmaReader obj
11560 65 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68  ect passed as th
11570 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
11580 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 63 61 6c  ..**.** This cal
11590 6c 20 77 69 6c 6c 20 69 6e 69 74 69 61 6c 69 7a  l will initializ
115a0 65 20 74 68 65 20 76 61 72 69 6f 75 73 20 66 69  e the various fi
115b0 65 6c 64 73 20 6f 66 20 74 68 65 20 70 52 65 61  elds of the pRea
115c0 64 72 2d 3e 70 49 6e 63 72 20 0a 2a 2a 20 73 74  dr->pIncr .** st
115d0 72 75 63 74 75 72 65 20 61 6e 64 2c 20 69 66 20  ructure and, if 
115e0 69 74 20 69 73 20 61 20 6d 75 6c 74 69 2d 74 68  it is a multi-th
115f0 72 65 61 64 65 64 20 49 6e 63 72 4d 65 72 67 65  readed IncrMerge
11600 72 2c 20 6c 61 75 6e 63 68 20 61 20 0a 2a 2a 20  r, launch a .** 
11610 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61  background threa
11620 64 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 61 46  d to populate aF
11630 69 6c 65 5b 31 5d 2e 0a 2a 2f 0a 73 74 61 74 69  ile[1]..*/.stati
11640 63 20 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61  c int vdbePmaRea
11650 64 65 72 42 67 49 6e 63 72 49 6e 69 74 28 50 6d  derBgIncrInit(Pm
11660 61 52 65 61 64 65 72 20 2a 70 52 65 61 64 72 29  aReader *pReadr)
11670 7b 0a 20 20 76 6f 69 64 20 2a 70 43 74 78 20 3d  {.  void *pCtx =
11680 20 28 76 6f 69 64 2a 29 70 52 65 61 64 72 3b 0a   (void*)pReadr;.
11690 20 20 72 65 74 75 72 6e 20 76 64 62 65 53 6f 72    return vdbeSor
116a0 74 65 72 43 72 65 61 74 65 54 68 72 65 61 64 28  terCreateThread(
116b0 70 52 65 61 64 72 2d 3e 70 49 6e 63 72 2d 3e 70  pReadr->pIncr->p
116c0 54 61 73 6b 2c 20 76 64 62 65 50 6d 61 52 65 61  Task, vdbePmaRea
116d0 64 65 72 42 67 49 6e 69 74 2c 20 70 43 74 78 29  derBgInit, pCtx)
116e0 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a  ;.}.#endif../*.*
116f0 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77  * Allocate a new
11700 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 6f 62 6a   MergeEngine obj
11710 65 63 74 20 74 6f 20 6d 65 72 67 65 20 74 68 65  ect to merge the
11720 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6e 50 4d   contents of nPM
11730 41 20 6c 65 76 65 6c 2d 30 0a 2a 2a 20 50 4d 41  A level-0.** PMA
11740 73 20 66 72 6f 6d 20 70 54 61 73 6b 2d 3e 66 69  s from pTask->fi
11750 6c 65 2e 20 49 66 20 6e 6f 20 65 72 72 6f 72 20  le. If no error 
11760 6f 63 63 75 72 73 2c 20 73 65 74 20 2a 70 70 4f  occurs, set *ppO
11770 75 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 0a 2a  ut to point to.*
11780 2a 20 74 68 65 20 6e 65 77 20 6f 62 6a 65 63 74  * the new object
11790 20 61 6e 64 20 72 65 74 75 72 6e 20 53 51 4c 49   and return SQLI
117a0 54 45 5f 4f 4b 2e 20 4f 72 2c 20 69 66 20 61 6e  TE_OK. Or, if an
117b0 20 65 72 72 6f 72 20 64 6f 65 73 20 6f 63 63 75   error does occu
117c0 72 2c 20 73 65 74 20 2a 70 70 4f 75 74 0a 2a 2a  r, set *ppOut.**
117d0 20 74 6f 20 4e 55 4c 4c 20 61 6e 64 20 72 65 74   to NULL and ret
117e0 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72  urn an SQLite er
117f0 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20  ror code..**.** 
11800 57 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69  When this functi
11810 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2c 20 2a 70  on is called, *p
11820 69 4f 66 66 73 65 74 20 69 73 20 73 65 74 20 74  iOffset is set t
11830 6f 20 74 68 65 20 6f 66 66 73 65 74 20 6f 66 20  o the offset of 
11840 74 68 65 0a 2a 2a 20 66 69 72 73 74 20 50 4d 41  the.** first PMA
11850 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 70 54   to read from pT
11860 61 73 6b 2d 3e 66 69 6c 65 2e 20 41 73 73 75 6d  ask->file. Assum
11870 69 6e 67 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63  ing no error occ
11880 75 72 73 2c 20 69 74 20 69 73 20 0a 2a 2a 20 73  urs, it is .** s
11890 65 74 20 74 6f 20 74 68 65 20 6f 66 66 73 65 74  et to the offset
118a0 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c   immediately fol
118b0 6c 6f 77 69 6e 67 20 74 68 65 20 6c 61 73 74 20  lowing the last 
118c0 62 79 74 65 20 6f 66 20 74 68 65 20 6c 61 73 74  byte of the last
118d0 0a 2a 2a 20 50 4d 41 20 62 65 66 6f 72 65 20 72  .** PMA before r
118e0 65 74 75 72 6e 69 6e 67 2e 20 49 66 20 61 6e 20  eturning. If an 
118f0 65 72 72 6f 72 20 64 6f 65 73 20 6f 63 63 75 72  error does occur
11900 2c 20 74 68 65 6e 20 74 68 65 20 66 69 6e 61 6c  , then the final
11910 20 76 61 6c 75 65 20 6f 66 0a 2a 2a 20 2a 70 69   value of.** *pi
11920 4f 66 66 73 65 74 20 69 73 20 75 6e 64 65 66 69  Offset is undefi
11930 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ned..*/.static i
11940 6e 74 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69  nt vdbeMergeEngi
11950 6e 65 4c 65 76 65 6c 30 28 0a 20 20 53 6f 72 74  neLevel0(.  Sort
11960 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20  Subtask *pTask, 
11970 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
11980 6f 72 74 65 72 20 74 61 73 6b 20 74 6f 20 72 65  orter task to re
11990 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 6e 74  ad from */.  int
119a0 20 6e 50 4d 41 2c 20 20 20 20 20 20 20 20 20 20   nPMA,          
119b0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
119c0 4e 75 6d 62 65 72 20 6f 66 20 50 4d 41 73 20 74  Number of PMAs t
119d0 6f 20 72 65 61 64 20 2a 2f 0a 20 20 69 36 34 20  o read */.  i64 
119e0 2a 70 69 4f 66 66 73 65 74 2c 20 20 20 20 20 20  *piOffset,      
119f0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
11a00 4e 2f 4f 55 54 3a 20 52 65 61 64 72 20 6f 66 66  N/OUT: Readr off
11a10 73 65 74 20 69 6e 20 70 54 61 73 6b 2d 3e 66 69  set in pTask->fi
11a20 6c 65 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67  le */.  MergeEng
11a30 69 6e 65 20 2a 2a 70 70 4f 75 74 20 20 20 20 20  ine **ppOut     
11a40 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
11a50 4e 65 77 20 6d 65 72 67 65 2d 65 6e 67 69 6e 65  New merge-engine
11a60 20 2a 2f 0a 29 7b 0a 20 20 4d 65 72 67 65 45 6e   */.){.  MergeEn
11a70 67 69 6e 65 20 2a 70 4e 65 77 3b 20 20 20 20 20  gine *pNew;     
11a80 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 65 72 67           /* Merg
11a90 65 20 65 6e 67 69 6e 65 20 74 6f 20 72 65 74 75  e engine to retu
11aa0 72 6e 20 2a 2f 0a 20 20 69 36 34 20 69 4f 66 66  rn */.  i64 iOff
11ab0 20 3d 20 2a 70 69 4f 66 66 73 65 74 3b 0a 20 20   = *piOffset;.  
11ac0 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72 63 20  int i;.  int rc 
11ad0 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20  = SQLITE_OK;..  
11ae0 2a 70 70 4f 75 74 20 3d 20 70 4e 65 77 20 3d 20  *ppOut = pNew = 
11af0 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4e  vdbeMergeEngineN
11b00 65 77 28 6e 50 4d 41 29 3b 0a 20 20 69 66 28 20  ew(nPMA);.  if( 
11b10 70 4e 65 77 3d 3d 30 20 29 20 72 63 20 3d 20 53  pNew==0 ) rc = S
11b20 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 0a 20 20  QLITE_NOMEM;..  
11b30 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 50 4d 41 20  for(i=0; i<nPMA 
11b40 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  && rc==SQLITE_OK
11b50 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 36 34 20  ; i++){.    i64 
11b60 6e 44 75 6d 6d 79 3b 0a 20 20 20 20 50 6d 61 52  nDummy;.    PmaR
11b70 65 61 64 65 72 20 2a 70 52 65 61 64 72 20 3d 20  eader *pReadr = 
11b80 26 70 4e 65 77 2d 3e 61 52 65 61 64 72 5b 69 5d  &pNew->aReadr[i]
11b90 3b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 50  ;.    rc = vdbeP
11ba0 6d 61 52 65 61 64 65 72 49 6e 69 74 28 70 54 61  maReaderInit(pTa
11bb0 73 6b 2c 20 26 70 54 61 73 6b 2d 3e 66 69 6c 65  sk, &pTask->file
11bc0 2c 20 69 4f 66 66 2c 20 70 52 65 61 64 72 2c 20  , iOff, pReadr, 
11bd0 26 6e 44 75 6d 6d 79 29 3b 0a 20 20 20 20 69 4f  &nDummy);.    iO
11be0 66 66 20 3d 20 70 52 65 61 64 72 2d 3e 69 45 6f  ff = pReadr->iEo
11bf0 66 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63  f;.  }..  if( rc
11c00 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
11c10 20 20 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69     vdbeMergeEngi
11c20 6e 65 46 72 65 65 28 70 4e 65 77 29 3b 0a 20 20  neFree(pNew);.  
11c30 20 20 2a 70 70 4f 75 74 20 3d 20 30 3b 0a 20 20    *ppOut = 0;.  
11c40 7d 0a 20 20 2a 70 69 4f 66 66 73 65 74 20 3d 20  }.  *piOffset = 
11c50 69 4f 66 66 3b 0a 20 20 72 65 74 75 72 6e 20 72  iOff;.  return r
11c60 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  c;.}../*.** Retu
11c70 72 6e 20 74 68 65 20 64 65 70 74 68 20 6f 66 20  rn the depth of 
11c80 61 20 74 72 65 65 20 63 6f 6d 70 72 69 73 69 6e  a tree comprisin
11c90 67 20 6e 50 4d 41 20 50 4d 41 73 2c 20 61 73 73  g nPMA PMAs, ass
11ca0 75 6d 69 6e 67 20 61 20 66 61 6e 6f 75 74 20 6f  uming a fanout o
11cb0 66 0a 2a 2a 20 53 4f 52 54 45 52 5f 4d 41 58 5f  f.** SORTER_MAX_
11cc0 4d 45 52 47 45 5f 43 4f 55 4e 54 2e 20 54 68 65  MERGE_COUNT. The
11cd0 20 72 65 74 75 72 6e 65 64 20 76 61 6c 75 65 20   returned value 
11ce0 64 6f 65 73 20 6e 6f 74 20 69 6e 63 6c 75 64 65  does not include
11cf0 20 6c 65 61 66 20 6e 6f 64 65 73 2e 0a 2a 2a 0a   leaf nodes..**.
11d00 2a 2a 20 69 2e 65 2e 0a 2a 2a 0a 2a 2a 20 20 20  ** i.e..**.**   
11d10 6e 50 4d 41 3c 3d 31 36 20 20 20 20 2d 3e 20 54  nPMA<=16    -> T
11d20 72 65 65 44 65 70 74 68 28 29 20 3d 3d 20 30 0a  reeDepth() == 0.
11d30 2a 2a 20 20 20 6e 50 4d 41 3c 3d 32 35 36 20 20  **   nPMA<=256  
11d40 20 2d 3e 20 54 72 65 65 44 65 70 74 68 28 29 20   -> TreeDepth() 
11d50 3d 3d 20 31 0a 2a 2a 20 20 20 6e 50 4d 41 3c 3d  == 1.**   nPMA<=
11d60 36 35 35 33 36 20 2d 3e 20 54 72 65 65 44 65 70  65536 -> TreeDep
11d70 74 68 28 29 20 3d 3d 20 32 0a 2a 2f 0a 73 74 61  th() == 2.*/.sta
11d80 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74  tic int vdbeSort
11d90 65 72 54 72 65 65 44 65 70 74 68 28 69 6e 74 20  erTreeDepth(int 
11da0 6e 50 4d 41 29 7b 0a 20 20 69 6e 74 20 6e 44 65  nPMA){.  int nDe
11db0 70 74 68 20 3d 20 30 3b 0a 20 20 69 36 34 20 6e  pth = 0;.  i64 n
11dc0 44 69 76 20 3d 20 53 4f 52 54 45 52 5f 4d 41 58  Div = SORTER_MAX
11dd0 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3b 0a 20 20  _MERGE_COUNT;.  
11de0 77 68 69 6c 65 28 20 6e 44 69 76 20 3c 20 28 69  while( nDiv < (i
11df0 36 34 29 6e 50 4d 41 20 29 7b 0a 20 20 20 20 6e  64)nPMA ){.    n
11e00 44 69 76 20 3d 20 6e 44 69 76 20 2a 20 53 4f 52  Div = nDiv * SOR
11e10 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
11e20 55 4e 54 3b 0a 20 20 20 20 6e 44 65 70 74 68 2b  UNT;.    nDepth+
11e30 2b 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  +;.  }.  return 
11e40 6e 44 65 70 74 68 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  nDepth;.}../*.**
11e50 20 70 52 6f 6f 74 20 69 73 20 74 68 65 20 72 6f   pRoot is the ro
11e60 6f 74 20 6f 66 20 61 6e 20 69 6e 63 72 65 6d 65  ot of an increme
11e70 6e 74 61 6c 20 6d 65 72 67 65 2d 74 72 65 65 20  ntal merge-tree 
11e80 77 69 74 68 20 64 65 70 74 68 20 6e 44 65 70 74  with depth nDept
11e90 68 20 28 61 63 63 6f 72 64 69 6e 67 0a 2a 2a 20  h (according.** 
11ea0 74 6f 20 76 64 62 65 53 6f 72 74 65 72 54 72 65  to vdbeSorterTre
11eb0 65 44 65 70 74 68 28 29 29 2e 20 70 4c 65 61 66  eDepth()). pLeaf
11ec0 20 69 73 20 74 68 65 20 69 53 65 71 27 74 68 20   is the iSeq'th 
11ed0 6c 65 61 66 20 74 6f 20 62 65 20 61 64 64 65 64  leaf to be added
11ee0 20 74 6f 20 74 68 65 0a 2a 2a 20 74 72 65 65 2c   to the.** tree,
11ef0 20 63 6f 75 6e 74 69 6e 67 20 66 72 6f 6d 20 7a   counting from z
11f00 65 72 6f 2e 20 54 68 69 73 20 66 75 6e 63 74 69  ero. This functi
11f10 6f 6e 20 61 64 64 73 20 70 4c 65 61 66 20 74 6f  on adds pLeaf to
11f20 20 74 68 65 20 74 72 65 65 2e 0a 2a 2a 0a 2a 2a   the tree..**.**
11f30 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   If successful, 
11f40 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74  SQLITE_OK is ret
11f50 75 72 6e 65 64 2e 20 49 66 20 61 6e 20 65 72 72  urned. If an err
11f60 6f 72 20 6f 63 63 75 72 73 2c 20 61 6e 20 53 51  or occurs, an SQ
11f70 4c 69 74 65 20 65 72 72 6f 72 0a 2a 2a 20 63 6f  Lite error.** co
11f80 64 65 20 69 73 20 72 65 74 75 72 6e 65 64 20 61  de is returned a
11f90 6e 64 20 70 4c 65 61 66 20 69 73 20 66 72 65 65  nd pLeaf is free
11fa0 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
11fb0 20 76 64 62 65 53 6f 72 74 65 72 41 64 64 54 6f   vdbeSorterAddTo
11fc0 54 72 65 65 28 0a 20 20 53 6f 72 74 53 75 62 74  Tree(.  SortSubt
11fd0 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20 20 20  ask *pTask,     
11fe0 20 20 20 20 20 20 20 20 2f 2a 20 54 61 73 6b 20          /* Task 
11ff0 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74  context */.  int
12000 20 6e 44 65 70 74 68 2c 20 20 20 20 20 20 20 20   nDepth,        
12010 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
12020 44 65 70 74 68 20 6f 66 20 74 72 65 65 20 61 63  Depth of tree ac
12030 63 6f 72 64 69 6e 67 20 74 6f 20 54 72 65 65 44  cording to TreeD
12040 65 70 74 68 28 29 20 2a 2f 0a 20 20 69 6e 74 20  epth() */.  int 
12050 69 53 65 71 2c 20 20 20 20 20 20 20 20 20 20 20  iSeq,           
12060 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
12070 65 71 75 65 6e 63 65 20 6e 75 6d 62 65 72 20 6f  equence number o
12080 66 20 6c 65 61 66 20 77 69 74 68 69 6e 20 74 72  f leaf within tr
12090 65 65 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67  ee */.  MergeEng
120a0 69 6e 65 20 2a 70 52 6f 6f 74 2c 20 20 20 20 20  ine *pRoot,     
120b0 20 20 20 20 20 20 20 20 2f 2a 20 52 6f 6f 74 20          /* Root 
120c0 6f 66 20 74 72 65 65 20 2a 2f 0a 20 20 4d 65 72  of tree */.  Mer
120d0 67 65 45 6e 67 69 6e 65 20 2a 70 4c 65 61 66 20  geEngine *pLeaf 
120e0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
120f0 4c 65 61 66 20 74 6f 20 61 64 64 20 74 6f 20 74  Leaf to add to t
12100 72 65 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  ree */.){.  int 
12110 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
12120 20 20 69 6e 74 20 6e 44 69 76 20 3d 20 31 3b 0a    int nDiv = 1;.
12130 20 20 69 6e 74 20 69 3b 0a 20 20 4d 65 72 67 65    int i;.  Merge
12140 45 6e 67 69 6e 65 20 2a 70 20 3d 20 70 52 6f 6f  Engine *p = pRoo
12150 74 3b 0a 20 20 49 6e 63 72 4d 65 72 67 65 72 20  t;.  IncrMerger 
12160 2a 70 49 6e 63 72 3b 0a 0a 20 20 72 63 20 3d 20  *pIncr;..  rc = 
12170 76 64 62 65 49 6e 63 72 4e 65 77 28 70 54 61 73  vdbeIncrNew(pTas
12180 6b 2c 20 70 4c 65 61 66 2c 20 26 70 49 6e 63 72  k, pLeaf, &pIncr
12190 29 3b 0a 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69  );..  for(i=1; i
121a0 3c 6e 44 65 70 74 68 3b 20 69 2b 2b 29 7b 0a 20  <nDepth; i++){. 
121b0 20 20 20 6e 44 69 76 20 3d 20 6e 44 69 76 20 2a     nDiv = nDiv *
121c0 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47   SORTER_MAX_MERG
121d0 45 5f 43 4f 55 4e 54 3b 0a 20 20 7d 0a 0a 20 20  E_COUNT;.  }..  
121e0 66 6f 72 28 69 3d 31 3b 20 69 3c 6e 44 65 70 74  for(i=1; i<nDept
121f0 68 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f  h && rc==SQLITE_
12200 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e  OK; i++){.    in
12210 74 20 69 49 74 65 72 20 3d 20 28 69 53 65 71 20  t iIter = (iSeq 
12220 2f 20 6e 44 69 76 29 20 25 20 53 4f 52 54 45 52  / nDiv) % SORTER
12230 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
12240 3b 0a 20 20 20 20 50 6d 61 52 65 61 64 65 72 20  ;.    PmaReader 
12250 2a 70 52 65 61 64 72 20 3d 20 26 70 2d 3e 61 52  *pReadr = &p->aR
12260 65 61 64 72 5b 69 49 74 65 72 5d 3b 0a 0a 20 20  eadr[iIter];..  
12270 20 20 69 66 28 20 70 52 65 61 64 72 2d 3e 70 49    if( pReadr->pI
12280 6e 63 72 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  ncr==0 ){.      
12290 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4e 65  MergeEngine *pNe
122a0 77 20 3d 20 76 64 62 65 4d 65 72 67 65 45 6e 67  w = vdbeMergeEng
122b0 69 6e 65 4e 65 77 28 53 4f 52 54 45 52 5f 4d 41  ineNew(SORTER_MA
122c0 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 29 3b 0a  X_MERGE_COUNT);.
122d0 20 20 20 20 20 20 69 66 28 20 70 4e 65 77 3d 3d        if( pNew==
122e0 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  0 ){.        rc 
122f0 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
12300 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
12310 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e       rc = vdbeIn
12320 63 72 4e 65 77 28 70 54 61 73 6b 2c 20 70 4e 65  crNew(pTask, pNe
12330 77 2c 20 26 70 52 65 61 64 72 2d 3e 70 49 6e 63  w, &pReadr->pInc
12340 72 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  r);.      }.    
12350 7d 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  }.    if( rc==SQ
12360 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
12370 20 70 20 3d 20 70 52 65 61 64 72 2d 3e 70 49 6e   p = pReadr->pIn
12380 63 72 2d 3e 70 4d 65 72 67 65 72 3b 0a 20 20 20  cr->pMerger;.   
12390 20 20 20 6e 44 69 76 20 3d 20 6e 44 69 76 20 2f     nDiv = nDiv /
123a0 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47   SORTER_MAX_MERG
123b0 45 5f 43 4f 55 4e 54 3b 0a 20 20 20 20 7d 0a 20  E_COUNT;.    }. 
123c0 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
123d0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70  LITE_OK ){.    p
123e0 2d 3e 61 52 65 61 64 72 5b 69 53 65 71 20 25 20  ->aReadr[iSeq % 
123f0 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45  SORTER_MAX_MERGE
12400 5f 43 4f 55 4e 54 5d 2e 70 49 6e 63 72 20 3d 20  _COUNT].pIncr = 
12410 70 49 6e 63 72 3b 0a 20 20 7d 65 6c 73 65 7b 0a  pIncr;.  }else{.
12420 20 20 20 20 76 64 62 65 49 6e 63 72 46 72 65 65      vdbeIncrFree
12430 28 70 49 6e 63 72 29 3b 0a 20 20 7d 0a 20 20 72  (pIncr);.  }.  r
12440 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
12450 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
12460 20 69 73 20 63 61 6c 6c 65 64 20 61 73 20 70 61   is called as pa
12470 72 74 20 6f 66 20 61 20 53 6f 72 74 65 72 52 65  rt of a SorterRe
12480 77 69 6e 64 28 29 20 6f 70 65 72 61 74 69 6f 6e  wind() operation
12490 20 6f 6e 20 61 20 73 6f 72 74 65 72 0a 2a 2a 20   on a sorter.** 
124a0 74 68 61 74 20 68 61 73 20 61 6c 72 65 61 64 79  that has already
124b0 20 77 72 69 74 74 65 6e 20 74 77 6f 20 6f 72 20   written two or 
124c0 6d 6f 72 65 20 6c 65 76 65 6c 2d 30 20 50 4d 41  more level-0 PMA
124d0 73 20 74 6f 20 6f 6e 65 20 6f 72 20 6d 6f 72 65  s to one or more
124e0 20 74 65 6d 70 0a 2a 2a 20 66 69 6c 65 73 2e 20   temp.** files. 
124f0 49 74 20 62 75 69 6c 64 73 20 61 20 74 72 65 65  It builds a tree
12500 20 6f 66 20 4d 65 72 67 65 45 6e 67 69 6e 65 2f   of MergeEngine/
12510 49 6e 63 72 4d 65 72 67 65 72 2f 50 6d 61 52 65  IncrMerger/PmaRe
12520 61 64 65 72 20 6f 62 6a 65 63 74 73 20 74 68 61  ader objects tha
12530 74 20 0a 2a 2a 20 63 61 6e 20 62 65 20 75 73 65  t .** can be use
12540 64 20 74 6f 20 69 6e 63 72 65 6d 65 6e 74 61 6c  d to incremental
12550 6c 79 20 6d 65 72 67 65 20 61 6c 6c 20 50 4d 41  ly merge all PMA
12560 73 20 6f 6e 20 64 69 73 6b 2e 0a 2a 2a 0a 2a 2a  s on disk..**.**
12570 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   If successful, 
12580 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74  SQLITE_OK is ret
12590 75 72 6e 65 64 20 61 6e 64 20 2a 70 70 4f 75 74  urned and *ppOut
125a0 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f   set to point to
125b0 20 74 68 65 0a 2a 2a 20 4d 65 72 67 65 45 6e 67   the.** MergeEng
125c0 69 6e 65 20 6f 62 6a 65 63 74 20 61 74 20 74 68  ine object at th
125d0 65 20 72 6f 6f 74 20 6f 66 20 74 68 65 20 74 72  e root of the tr
125e0 65 65 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e  ee before return
125f0 69 6e 67 2e 20 4f 72 2c 20 69 66 20 61 6e 0a 2a  ing. Or, if an.*
12600 2a 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20  * error occurs, 
12610 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
12620 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65 64  code is returned
12630 20 61 6e 64 20 74 68 65 20 66 69 6e 61 6c 20 76   and the final v
12640 61 6c 75 65 20 0a 2a 2a 20 6f 66 20 2a 70 70 4f  alue .** of *ppO
12650 75 74 20 69 73 20 75 6e 64 65 66 69 6e 65 64 2e  ut is undefined.
12660 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
12670 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65 54 72  dbeSorterMergeTr
12680 65 65 42 75 69 6c 64 28 56 64 62 65 53 6f 72 74  eeBuild(VdbeSort
12690 65 72 20 2a 70 53 6f 72 74 65 72 2c 20 4d 65 72  er *pSorter, Mer
126a0 67 65 45 6e 67 69 6e 65 20 2a 2a 70 70 4f 75 74  geEngine **ppOut
126b0 29 7b 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65  ){.  MergeEngine
126c0 20 2a 70 4d 61 69 6e 20 3d 20 30 3b 0a 20 20 69   *pMain = 0;.  i
126d0 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
126e0 4b 3b 0a 20 20 69 6e 74 20 69 54 61 73 6b 3b 0a  K;.  int iTask;.
126f0 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f  .#if SQLITE_MAX_
12700 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30  WORKER_THREADS>0
12710 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 73 6f 72  .  /* If the sor
12720 74 65 72 20 75 73 65 73 20 6d 6f 72 65 20 74 68  ter uses more th
12730 61 6e 20 6f 6e 65 20 74 61 73 6b 2c 20 74 68 65  an one task, the
12740 6e 20 63 72 65 61 74 65 20 74 68 65 20 74 6f 70  n create the top
12750 2d 6c 65 76 65 6c 20 0a 20 20 2a 2a 20 4d 65 72  -level .  ** Mer
12760 67 65 45 6e 67 69 6e 65 20 68 65 72 65 2e 20 54  geEngine here. T
12770 68 69 73 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  his MergeEngine 
12780 77 69 6c 6c 20 72 65 61 64 20 64 61 74 61 20 66  will read data f
12790 72 6f 6d 20 65 78 61 63 74 6c 79 20 0a 20 20 2a  rom exactly .  *
127a0 2a 20 6f 6e 65 20 50 6d 61 52 65 61 64 65 72 20  * one PmaReader 
127b0 70 65 72 20 73 75 62 2d 74 61 73 6b 2e 20 20 2a  per sub-task.  *
127c0 2f 0a 20 20 61 73 73 65 72 74 28 20 70 53 6f 72  /.  assert( pSor
127d0 74 65 72 2d 3e 62 55 73 65 54 68 72 65 61 64 73  ter->bUseThreads
127e0 20 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 6e 54 61   || pSorter->nTa
127f0 73 6b 3d 3d 31 20 29 3b 0a 20 20 69 66 28 20 70  sk==1 );.  if( p
12800 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3e 31 20  Sorter->nTask>1 
12810 29 7b 0a 20 20 20 20 70 4d 61 69 6e 20 3d 20 76  ){.    pMain = v
12820 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4e 65  dbeMergeEngineNe
12830 77 28 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b  w(pSorter->nTask
12840 29 3b 0a 20 20 20 20 69 66 28 20 70 4d 61 69 6e  );.    if( pMain
12850 3d 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49 54  ==0 ) rc = SQLIT
12860 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 23 65 6e  E_NOMEM;.  }.#en
12870 64 69 66 0a 0a 20 20 66 6f 72 28 69 54 61 73 6b  dif..  for(iTask
12880 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  =0; rc==SQLITE_O
12890 4b 20 26 26 20 69 54 61 73 6b 3c 70 53 6f 72 74  K && iTask<pSort
128a0 65 72 2d 3e 6e 54 61 73 6b 3b 20 69 54 61 73 6b  er->nTask; iTask
128b0 2b 2b 29 7b 0a 20 20 20 20 53 6f 72 74 53 75 62  ++){.    SortSub
128c0 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20 26 70  task *pTask = &p
128d0 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 69 54  Sorter->aTask[iT
128e0 61 73 6b 5d 3b 0a 20 20 20 20 69 66 28 20 70 54  ask];.    if( pT
128f0 61 73 6b 2d 3e 6e 50 4d 41 20 29 7b 0a 20 20 20  ask->nPMA ){.   
12900 20 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a     MergeEngine *
12910 70 52 6f 6f 74 20 3d 20 30 3b 20 20 20 20 20 2f  pRoot = 0;     /
12920 2a 20 52 6f 6f 74 20 6e 6f 64 65 20 6f 66 20 74  * Root node of t
12930 72 65 65 20 66 6f 72 20 74 68 69 73 20 74 61 73  ree for this tas
12940 6b 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e  k */.      int n
12950 44 65 70 74 68 20 3d 20 76 64 62 65 53 6f 72 74  Depth = vdbeSort
12960 65 72 54 72 65 65 44 65 70 74 68 28 70 54 61 73  erTreeDepth(pTas
12970 6b 2d 3e 6e 50 4d 41 29 3b 0a 20 20 20 20 20 20  k->nPMA);.      
12980 69 36 34 20 69 52 65 61 64 4f 66 66 20 3d 20 30  i64 iReadOff = 0
12990 3b 0a 0a 20 20 20 20 20 20 69 66 28 20 70 54 61  ;..      if( pTa
129a0 73 6b 2d 3e 6e 50 4d 41 3c 3d 53 4f 52 54 45 52  sk->nPMA<=SORTER
129b0 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
129c0 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d   ){.        rc =
129d0 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65   vdbeMergeEngine
129e0 4c 65 76 65 6c 30 28 70 54 61 73 6b 2c 20 70 54  Level0(pTask, pT
129f0 61 73 6b 2d 3e 6e 50 4d 41 2c 20 26 69 52 65 61  ask->nPMA, &iRea
12a00 64 4f 66 66 2c 20 26 70 52 6f 6f 74 29 3b 0a 20  dOff, &pRoot);. 
12a10 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
12a20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20      int i;.     
12a30 20 20 20 69 6e 74 20 69 53 65 71 20 3d 20 30 3b     int iSeq = 0;
12a40 0a 20 20 20 20 20 20 20 20 70 52 6f 6f 74 20 3d  .        pRoot =
12a50 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65   vdbeMergeEngine
12a60 4e 65 77 28 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  New(SORTER_MAX_M
12a70 45 52 47 45 5f 43 4f 55 4e 54 29 3b 0a 20 20 20  ERGE_COUNT);.   
12a80 20 20 20 20 20 69 66 28 20 70 52 6f 6f 74 3d 3d       if( pRoot==
12a90 30 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  0 ) rc = SQLITE_
12aa0 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 20 20 66  NOMEM;.        f
12ab0 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61 73 6b 2d  or(i=0; i<pTask-
12ac0 3e 6e 50 4d 41 20 26 26 20 72 63 3d 3d 53 51 4c  >nPMA && rc==SQL
12ad0 49 54 45 5f 4f 4b 3b 20 69 20 2b 3d 20 53 4f 52  ITE_OK; i += SOR
12ae0 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
12af0 55 4e 54 29 7b 0a 20 20 20 20 20 20 20 20 20 20  UNT){.          
12b00 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65  MergeEngine *pMe
12b10 72 67 65 72 20 3d 20 30 3b 20 2f 2a 20 4e 65 77  rger = 0; /* New
12b20 20 6c 65 76 65 6c 2d 30 20 50 4d 41 20 6d 65 72   level-0 PMA mer
12b30 67 65 72 20 2a 2f 0a 20 20 20 20 20 20 20 20 20  ger */.         
12b40 20 69 6e 74 20 6e 52 65 61 64 65 72 3b 20 20 20   int nReader;   
12b50 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
12b60 6d 62 65 72 20 6f 66 20 6c 65 76 65 6c 2d 30 20  mber of level-0 
12b70 50 4d 41 73 20 74 6f 20 6d 65 72 67 65 20 2a 2f  PMAs to merge */
12b80 0a 0a 20 20 20 20 20 20 20 20 20 20 6e 52 65 61  ..          nRea
12b90 64 65 72 20 3d 20 4d 49 4e 28 70 54 61 73 6b 2d  der = MIN(pTask-
12ba0 3e 6e 50 4d 41 20 2d 20 69 2c 20 53 4f 52 54 45  >nPMA - i, SORTE
12bb0 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
12bc0 54 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63  T);.          rc
12bd0 20 3d 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69   = vdbeMergeEngi
12be0 6e 65 4c 65 76 65 6c 30 28 70 54 61 73 6b 2c 20  neLevel0(pTask, 
12bf0 6e 52 65 61 64 65 72 2c 20 26 69 52 65 61 64 4f  nReader, &iReadO
12c00 66 66 2c 20 26 70 4d 65 72 67 65 72 29 3b 0a 20  ff, &pMerger);. 
12c10 20 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d           if( rc=
12c20 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
12c30 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 76            rc = v
12c40 64 62 65 53 6f 72 74 65 72 41 64 64 54 6f 54 72  dbeSorterAddToTr
12c50 65 65 28 70 54 61 73 6b 2c 20 6e 44 65 70 74 68  ee(pTask, nDepth
12c60 2c 20 69 53 65 71 2b 2b 2c 20 70 52 6f 6f 74 2c  , iSeq++, pRoot,
12c70 20 70 4d 65 72 67 65 72 29 3b 0a 20 20 20 20 20   pMerger);.     
12c80 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d       }.        }
12c90 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
12ca0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
12cb0 4b 20 29 7b 0a 23 69 66 20 53 51 4c 49 54 45 5f  K ){.#if SQLITE_
12cc0 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41  MAX_WORKER_THREA
12cd0 44 53 3e 30 0a 20 20 20 20 20 20 20 20 69 66 28  DS>0.        if(
12ce0 20 70 4d 61 69 6e 21 3d 30 20 29 7b 0a 20 20 20   pMain!=0 ){.   
12cf0 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65         rc = vdbe
12d00 49 6e 63 72 4e 65 77 28 70 54 61 73 6b 2c 20 70  IncrNew(pTask, p
12d10 52 6f 6f 74 2c 20 26 70 4d 61 69 6e 2d 3e 61 52  Root, &pMain->aR
12d20 65 61 64 72 5b 69 54 61 73 6b 5d 2e 70 49 6e 63  eadr[iTask].pInc
12d30 72 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73  r);.        }els
12d40 65 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20 20  e.#endif.       
12d50 20 7b 0a 20 20 20 20 20 20 20 20 20 20 61 73 73   {.          ass
12d60 65 72 74 28 20 70 4d 61 69 6e 3d 3d 30 20 29 3b  ert( pMain==0 );
12d70 0a 20 20 20 20 20 20 20 20 20 20 70 4d 61 69 6e  .          pMain
12d80 20 3d 20 70 52 6f 6f 74 3b 0a 20 20 20 20 20 20   = pRoot;.      
12d90 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b    }.      }else{
12da0 0a 20 20 20 20 20 20 20 20 76 64 62 65 4d 65 72  .        vdbeMer
12db0 67 65 45 6e 67 69 6e 65 46 72 65 65 28 70 52 6f  geEngineFree(pRo
12dc0 6f 74 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ot);.      }.   
12dd0 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63   }.  }..  if( rc
12de0 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
12df0 20 20 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69     vdbeMergeEngi
12e00 6e 65 46 72 65 65 28 70 4d 61 69 6e 29 3b 0a 20  neFree(pMain);. 
12e10 20 20 20 70 4d 61 69 6e 20 3d 20 30 3b 0a 20 20     pMain = 0;.  
12e20 7d 0a 20 20 2a 70 70 4f 75 74 20 3d 20 70 4d 61  }.  *ppOut = pMa
12e30 69 6e 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  in;.  return rc;
12e40 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
12e50 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
12e60 64 20 61 73 20 70 61 72 74 20 6f 66 20 61 6e 20  d as part of an 
12e70 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
12e80 72 52 65 77 69 6e 64 28 29 20 6f 70 65 72 61 74  rRewind() operat
12e90 69 6f 6e 0a 2a 2a 20 6f 6e 20 61 20 73 6f 72 74  ion.** on a sort
12ea0 65 72 20 74 68 61 74 20 68 61 73 20 77 72 69 74  er that has writ
12eb0 74 65 6e 20 74 77 6f 20 6f 72 20 6d 6f 72 65 20  ten two or more 
12ec0 50 4d 41 73 20 74 6f 20 74 65 6d 70 6f 72 61 72  PMAs to temporar
12ed0 79 20 66 69 6c 65 73 2e 20 49 74 20 73 65 74 73  y files. It sets
12ee0 0a 2a 2a 20 75 70 20 65 69 74 68 65 72 20 56 64  .** up either Vd
12ef0 62 65 53 6f 72 74 65 72 2e 70 4d 65 72 67 65 72  beSorter.pMerger
12f00 20 28 66 6f 72 20 73 69 6e 67 6c 65 20 74 68 72   (for single thr
12f10 65 61 64 65 64 20 73 6f 72 74 65 72 73 29 20 6f  eaded sorters) o
12f20 72 20 70 52 65 61 64 65 72 0a 2a 2a 20 28 66 6f  r pReader.** (fo
12f30 72 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64  r multi-threaded
12f40 20 73 6f 72 74 65 72 73 29 20 73 6f 20 74 68 61   sorters) so tha
12f50 74 20 69 74 20 63 61 6e 20 62 65 20 75 73 65 64  t it can be used
12f60 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f   to iterate thro
12f70 75 67 68 0a 2a 2a 20 61 6c 6c 20 72 65 63 6f 72  ugh.** all recor
12f80 64 73 20 73 74 6f 72 65 64 20 69 6e 20 74 68 65  ds stored in the
12f90 20 73 6f 72 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 53   sorter..**.** S
12fa0 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75  QLITE_OK is retu
12fb0 72 6e 65 64 20 69 66 20 73 75 63 63 65 73 73 66  rned if successf
12fc0 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65  ul, or an SQLite
12fd0 20 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65   error code othe
12fe0 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  rwise..*/.static
12ff0 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72 53   int vdbeSorterS
13000 65 74 75 70 4d 65 72 67 65 28 56 64 62 65 53 6f  etupMerge(VdbeSo
13010 72 74 65 72 20 2a 70 53 6f 72 74 65 72 29 7b 0a  rter *pSorter){.
13020 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
13030 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13040 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
13050 20 2a 2f 0a 20 20 53 6f 72 74 53 75 62 74 61 73   */.  SortSubtas
13060 6b 20 2a 70 54 61 73 6b 30 20 3d 20 26 70 53 6f  k *pTask0 = &pSo
13070 72 74 65 72 2d 3e 61 54 61 73 6b 5b 30 5d 3b 0a  rter->aTask[0];.
13080 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70    MergeEngine *p
13090 4d 61 69 6e 20 3d 20 30 3b 0a 23 69 66 20 53 51  Main = 0;.#if SQ
130a0 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f  LITE_MAX_WORKER_
130b0 54 48 52 45 41 44 53 0a 20 20 73 71 6c 69 74 65  THREADS.  sqlite
130c0 33 20 2a 64 62 20 3d 20 70 54 61 73 6b 30 2d 3e  3 *db = pTask0->
130d0 70 53 6f 72 74 65 72 2d 3e 64 62 3b 0a 23 65 6e  pSorter->db;.#en
130e0 64 69 66 0a 0a 20 20 72 63 20 3d 20 76 64 62 65  dif..  rc = vdbe
130f0 53 6f 72 74 65 72 4d 65 72 67 65 54 72 65 65 42  SorterMergeTreeB
13100 75 69 6c 64 28 70 53 6f 72 74 65 72 2c 20 26 70  uild(pSorter, &p
13110 4d 61 69 6e 29 3b 0a 20 20 69 66 28 20 72 63 3d  Main);.  if( rc=
13120 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 23 69  =SQLITE_OK ){.#i
13130 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52  f SQLITE_MAX_WOR
13140 4b 45 52 5f 54 48 52 45 41 44 53 0a 20 20 20 20  KER_THREADS.    
13150 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d  assert( pSorter-
13160 3e 62 55 73 65 54 68 72 65 61 64 73 3d 3d 30 20  >bUseThreads==0 
13170 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73  || pSorter->nTas
13180 6b 3e 31 20 29 3b 0a 20 20 20 20 69 66 28 20 70  k>1 );.    if( p
13190 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68 72 65  Sorter->bUseThre
131a0 61 64 73 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  ads ){.      int
131b0 20 69 54 61 73 6b 3b 0a 20 20 20 20 20 20 50 6d   iTask;.      Pm
131c0 61 52 65 61 64 65 72 20 2a 70 52 65 61 64 72 3b  aReader *pReadr;
131d0 0a 20 20 20 20 20 20 53 6f 72 74 53 75 62 74 61  .      SortSubta
131e0 73 6b 20 2a 70 4c 61 73 74 20 3d 20 26 70 53 6f  sk *pLast = &pSo
131f0 72 74 65 72 2d 3e 61 54 61 73 6b 5b 70 53 6f 72  rter->aTask[pSor
13200 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 5d 3b 0a 20  ter->nTask-1];. 
13210 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f       rc = vdbeSo
13220 72 74 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64 28  rtAllocUnpacked(
13230 70 4c 61 73 74 29 3b 0a 20 20 20 20 20 20 69 66  pLast);.      if
13240 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
13250 29 7b 0a 20 20 20 20 20 20 20 20 70 52 65 61 64  ){.        pRead
13260 72 20 3d 20 28 50 6d 61 52 65 61 64 65 72 2a 29  r = (PmaReader*)
13270 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f 63 5a  sqlite3DbMallocZ
13280 65 72 6f 28 64 62 2c 20 73 69 7a 65 6f 66 28 50  ero(db, sizeof(P
13290 6d 61 52 65 61 64 65 72 29 29 3b 0a 20 20 20 20  maReader));.    
132a0 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 52 65      pSorter->pRe
132b0 61 64 65 72 20 3d 20 70 52 65 61 64 72 3b 0a 20  ader = pReadr;. 
132c0 20 20 20 20 20 20 20 69 66 28 20 70 52 65 61 64         if( pRead
132d0 72 3d 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49  r==0 ) rc = SQLI
132e0 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20  TE_NOMEM;.      
132f0 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  }.      if( rc==
13300 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
13310 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e       rc = vdbeIn
13320 63 72 4e 65 77 28 70 4c 61 73 74 2c 20 70 4d 61  crNew(pLast, pMa
13330 69 6e 2c 20 26 70 52 65 61 64 72 2d 3e 70 49 6e  in, &pReadr->pIn
13340 63 72 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  cr);.        if(
13350 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
13360 7b 0a 20 20 20 20 20 20 20 20 20 20 76 64 62 65  {.          vdbe
13370 49 6e 63 72 53 65 74 54 68 72 65 61 64 73 28 70  IncrSetThreads(p
13380 52 65 61 64 72 2d 3e 70 49 6e 63 72 29 3b 0a 20  Readr->pIncr);. 
13390 20 20 20 20 20 20 20 20 20 66 6f 72 28 69 54 61           for(iTa
133a0 73 6b 3d 30 3b 20 69 54 61 73 6b 3c 28 70 53 6f  sk=0; iTask<(pSo
133b0 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 3b 20  rter->nTask-1); 
133c0 69 54 61 73 6b 2b 2b 29 7b 0a 20 20 20 20 20 20  iTask++){.      
133d0 20 20 20 20 20 20 49 6e 63 72 4d 65 72 67 65 72        IncrMerger
133e0 20 2a 70 49 6e 63 72 3b 0a 20 20 20 20 20 20 20   *pIncr;.       
133f0 20 20 20 20 20 69 66 28 20 28 70 49 6e 63 72 20       if( (pIncr 
13400 3d 20 70 4d 61 69 6e 2d 3e 61 52 65 61 64 72 5b  = pMain->aReadr[
13410 69 54 61 73 6b 5d 2e 70 49 6e 63 72 29 20 29 7b  iTask].pIncr) ){
13420 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 76  .              v
13430 64 62 65 49 6e 63 72 53 65 74 54 68 72 65 61 64  dbeIncrSetThread
13440 73 28 70 49 6e 63 72 29 3b 0a 20 20 20 20 20 20  s(pIncr);.      
13450 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
13460 70 49 6e 63 72 2d 3e 70 54 61 73 6b 21 3d 70 4c  pIncr->pTask!=pL
13470 61 73 74 20 29 3b 0a 20 20 20 20 20 20 20 20 20  ast );.         
13480 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 7d     }.          }
13490 0a 20 20 20 20 20 20 20 20 20 20 66 6f 72 28 69  .          for(i
134a0 54 61 73 6b 3d 30 3b 20 72 63 3d 3d 53 51 4c 49  Task=0; rc==SQLI
134b0 54 45 5f 4f 4b 20 26 26 20 69 54 61 73 6b 3c 70  TE_OK && iTask<p
134c0 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3b 20 69  Sorter->nTask; i
134d0 54 61 73 6b 2b 2b 29 7b 0a 20 20 20 20 20 20 20  Task++){.       
134e0 20 20 20 20 20 50 6d 61 52 65 61 64 65 72 20 2a       PmaReader *
134f0 70 20 3d 20 26 70 4d 61 69 6e 2d 3e 61 52 65 61  p = &pMain->aRea
13500 64 72 5b 69 54 61 73 6b 5d 3b 0a 20 20 20 20 20  dr[iTask];.     
13510 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70         assert( p
13520 2d 3e 70 49 6e 63 72 3d 3d 30 20 7c 7c 20 70 2d  ->pIncr==0 || p-
13530 3e 70 49 6e 63 72 2d 3e 70 54 61 73 6b 3d 3d 26  >pIncr->pTask==&
13540 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 69  pSorter->aTask[i
13550 54 61 73 6b 5d 20 29 3b 0a 20 20 20 20 20 20 20  Task] );.       
13560 20 20 20 20 20 69 66 28 20 70 2d 3e 70 49 6e 63       if( p->pInc
13570 72 20 29 7b 20 0a 20 20 20 20 20 20 20 20 20 20  r ){ .          
13580 20 20 20 20 69 66 28 20 69 54 61 73 6b 3d 3d 70      if( iTask==p
13590 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 20  Sorter->nTask-1 
135a0 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ){.             
135b0 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52     rc = vdbePmaR
135c0 65 61 64 65 72 49 6e 63 72 49 6e 69 74 28 70 2c  eaderIncrInit(p,
135d0 20 49 4e 43 52 49 4e 49 54 5f 54 41 53 4b 29 3b   INCRINIT_TASK);
135e0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7d  .              }
135f0 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20  else{.          
13600 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 50        rc = vdbeP
13610 6d 61 52 65 61 64 65 72 42 67 49 6e 63 72 49 6e  maReaderBgIncrIn
13620 69 74 28 70 29 3b 0a 20 20 20 20 20 20 20 20 20  it(p);.         
13630 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
13640 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 7d     }.          }
13650 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
13660 20 20 20 70 4d 61 69 6e 20 3d 20 30 3b 0a 20 20     pMain = 0;.  
13670 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
13680 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
13690 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64  .        rc = vd
136a0 62 65 50 6d 61 52 65 61 64 65 72 49 6e 63 72 49  bePmaReaderIncrI
136b0 6e 69 74 28 70 52 65 61 64 72 2c 20 49 4e 43 52  nit(pReadr, INCR
136c0 49 4e 49 54 5f 52 4f 4f 54 29 3b 0a 20 20 20 20  INIT_ROOT);.    
136d0 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 0a 23 65    }.    }else.#e
136e0 6e 64 69 66 0a 20 20 20 20 7b 0a 20 20 20 20 20  ndif.    {.     
136f0 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72 49 6e   rc = vdbeIncrIn
13700 69 74 4d 65 72 67 65 72 28 70 54 61 73 6b 30 2c  itMerger(pTask0,
13710 20 70 4d 61 69 6e 2c 20 49 4e 43 52 49 4e 49 54   pMain, INCRINIT
13720 5f 4e 4f 52 4d 41 4c 29 3b 0a 20 20 20 20 20 20  _NORMAL);.      
13730 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72  pSorter->pMerger
13740 20 3d 20 70 4d 61 69 6e 3b 0a 20 20 20 20 20 20   = pMain;.      
13750 70 4d 61 69 6e 20 3d 20 30 3b 0a 20 20 20 20 7d  pMain = 0;.    }
13760 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d  .  }..  if( rc!=
13770 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
13780 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65   vdbeMergeEngine
13790 46 72 65 65 28 70 4d 61 69 6e 29 3b 0a 20 20 7d  Free(pMain);.  }
137a0 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
137b0 0a 0a 2f 2a 0a 2a 2a 20 4f 6e 63 65 20 74 68 65  ../*.** Once the
137c0 20 73 6f 72 74 65 72 20 68 61 73 20 62 65 65 6e   sorter has been
137d0 20 70 6f 70 75 6c 61 74 65 64 20 62 79 20 63 61   populated by ca
137e0 6c 6c 73 20 74 6f 20 73 71 6c 69 74 65 33 56 64  lls to sqlite3Vd
137f0 62 65 53 6f 72 74 65 72 57 72 69 74 65 2c 0a 2a  beSorterWrite,.*
13800 2a 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * this function 
13810 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 70 72 65  is called to pre
13820 70 61 72 65 20 66 6f 72 20 69 74 65 72 61 74 69  pare for iterati
13830 6e 67 20 74 68 72 6f 75 67 68 20 74 68 65 20 72  ng through the r
13840 65 63 6f 72 64 73 0a 2a 2a 20 69 6e 20 73 6f 72  ecords.** in sor
13850 74 65 64 20 6f 72 64 65 72 2e 0a 2a 2f 0a 69 6e  ted order..*/.in
13860 74 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72  t sqlite3VdbeSor
13870 74 65 72 52 65 77 69 6e 64 28 63 6f 6e 73 74 20  terRewind(const 
13880 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72  VdbeCursor *pCsr
13890 2c 20 69 6e 74 20 2a 70 62 45 6f 66 29 7b 0a 20  , int *pbEof){. 
138a0 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f   VdbeSorter *pSo
138b0 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f  rter = pCsr->pSo
138c0 72 74 65 72 3b 0a 20 20 69 6e 74 20 72 63 20 3d  rter;.  int rc =
138d0 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20   SQLITE_OK;     
138e0 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
138f0 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 61 73 73  n code */..  ass
13900 65 72 74 28 20 70 53 6f 72 74 65 72 20 29 3b 0a  ert( pSorter );.
13910 0a 20 20 2f 2a 20 49 66 20 6e 6f 20 64 61 74 61  .  /* If no data
13920 20 68 61 73 20 62 65 65 6e 20 77 72 69 74 74 65   has been writte
13930 6e 20 74 6f 20 64 69 73 6b 2c 20 74 68 65 6e 20  n to disk, then 
13940 64 6f 20 6e 6f 74 20 64 6f 20 73 6f 20 6e 6f 77  do not do so now
13950 2e 20 49 6e 73 74 65 61 64 2c 0a 20 20 2a 2a 20  . Instead,.  ** 
13960 73 6f 72 74 20 74 68 65 20 56 64 62 65 53 6f 72  sort the VdbeSor
13970 74 65 72 2e 70 52 65 63 6f 72 64 20 6c 69 73 74  ter.pRecord list
13980 2e 20 54 68 65 20 76 64 62 65 20 6c 61 79 65 72  . The vdbe layer
13990 20 77 69 6c 6c 20 72 65 61 64 20 64 61 74 61 20   will read data 
139a0 64 69 72 65 63 74 6c 79 0a 20 20 2a 2a 20 66 72  directly.  ** fr
139b0 6f 6d 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79  om the in-memory
139c0 20 6c 69 73 74 2e 20 20 2a 2f 0a 20 20 69 66 28   list.  */.  if(
139d0 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d   pSorter->bUsePM
139e0 41 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20  A==0 ){.    if( 
139f0 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c  pSorter->list.pL
13a00 69 73 74 20 29 7b 0a 20 20 20 20 20 20 2a 70 62  ist ){.      *pb
13a10 45 6f 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 72  Eof = 0;.      r
13a20 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 53 6f  c = vdbeSorterSo
13a30 72 74 28 26 70 53 6f 72 74 65 72 2d 3e 61 54 61  rt(&pSorter->aTa
13a40 73 6b 5b 30 5d 2c 20 26 70 53 6f 72 74 65 72 2d  sk[0], &pSorter-
13a50 3e 6c 69 73 74 29 3b 0a 20 20 20 20 7d 65 6c 73  >list);.    }els
13a60 65 7b 0a 20 20 20 20 20 20 2a 70 62 45 6f 66 20  e{.      *pbEof 
13a70 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72  = 1;.    }.    r
13a80 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20  eturn rc;.  }.. 
13a90 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 63 75   /* Write the cu
13aa0 72 72 65 6e 74 20 69 6e 2d 6d 65 6d 6f 72 79 20  rrent in-memory 
13ab0 6c 69 73 74 20 74 6f 20 61 20 50 4d 41 2e 20 57  list to a PMA. W
13ac0 68 65 6e 20 74 68 65 20 56 64 62 65 53 6f 72 74  hen the VdbeSort
13ad0 65 72 57 72 69 74 65 28 29 20 0a 20 20 2a 2a 20  erWrite() .  ** 
13ae0 66 75 6e 63 74 69 6f 6e 20 66 6c 75 73 68 65 73  function flushes
13af0 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
13b00 20 6d 65 6d 6f 72 79 20 74 6f 20 64 69 73 6b 2c   memory to disk,
13b10 20 69 74 20 69 6d 6d 65 64 69 61 74 65 6c 79 20   it immediately 
13b20 61 6c 77 61 79 73 0a 20 20 2a 2a 20 63 72 65 61  always.  ** crea
13b30 74 65 73 20 61 20 6e 65 77 20 6c 69 73 74 20 63  tes a new list c
13b40 6f 6e 73 69 73 74 69 6e 67 20 6f 66 20 61 20 73  onsisting of a s
13b50 69 6e 67 6c 65 20 6b 65 79 20 69 6d 6d 65 64 69  ingle key immedi
13b60 61 74 65 6c 79 20 61 66 74 65 72 77 61 72 64 73  ately afterwards
13b70 2e 0a 20 20 2a 2a 20 53 6f 20 74 68 65 20 6c 69  ..  ** So the li
13b80 73 74 20 69 73 20 6e 65 76 65 72 20 65 6d 70 74  st is never empt
13b90 79 20 61 74 20 74 68 69 73 20 70 6f 69 6e 74 2e  y at this point.
13ba0 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70    */.  assert( p
13bb0 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69  Sorter->list.pLi
13bc0 73 74 20 29 3b 0a 20 20 72 63 20 3d 20 76 64 62  st );.  rc = vdb
13bd0 65 53 6f 72 74 65 72 46 6c 75 73 68 50 4d 41 28  eSorterFlushPMA(
13be0 70 53 6f 72 74 65 72 29 3b 0a 0a 20 20 2f 2a 20  pSorter);..  /* 
13bf0 4a 6f 69 6e 20 61 6c 6c 20 74 68 72 65 61 64 73  Join all threads
13c00 20 2a 2f 0a 20 20 72 63 20 3d 20 76 64 62 65 53   */.  rc = vdbeS
13c10 6f 72 74 65 72 4a 6f 69 6e 41 6c 6c 28 70 53 6f  orterJoinAll(pSo
13c20 72 74 65 72 2c 20 72 63 29 3b 0a 0a 20 20 76 64  rter, rc);..  vd
13c30 62 65 53 6f 72 74 65 72 52 65 77 69 6e 64 44 65  beSorterRewindDe
13c40 62 75 67 28 22 72 65 77 69 6e 64 22 29 3b 0a 0a  bug("rewind");..
13c50 20 20 2f 2a 20 41 73 73 75 6d 69 6e 67 20 6e 6f    /* Assuming no
13c60 20 65 72 72 6f 72 73 20 68 61 76 65 20 6f 63 63   errors have occ
13c70 75 72 72 65 64 2c 20 73 65 74 20 75 70 20 61 20  urred, set up a 
13c80 6d 65 72 67 65 72 20 73 74 72 75 63 74 75 72 65  merger structure
13c90 20 74 6f 20 0a 20 20 2a 2a 20 69 6e 63 72 65 6d   to .  ** increm
13ca0 65 6e 74 61 6c 6c 79 20 72 65 61 64 20 61 6e 64  entally read and
13cb0 20 6d 65 72 67 65 20 61 6c 6c 20 72 65 6d 61 69   merge all remai
13cc0 6e 69 6e 67 20 50 4d 41 73 2e 20 20 2a 2f 0a 20  ning PMAs.  */. 
13cd0 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72   assert( pSorter
13ce0 2d 3e 70 52 65 61 64 65 72 3d 3d 30 20 29 3b 0a  ->pReader==0 );.
13cf0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
13d00 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
13d10 76 64 62 65 53 6f 72 74 65 72 53 65 74 75 70 4d  vdbeSorterSetupM
13d20 65 72 67 65 28 70 53 6f 72 74 65 72 29 3b 0a 20  erge(pSorter);. 
13d30 20 20 20 2a 70 62 45 6f 66 20 3d 20 30 3b 0a 20     *pbEof = 0;. 
13d40 20 7d 0a 0a 20 20 76 64 62 65 53 6f 72 74 65 72   }..  vdbeSorter
13d50 52 65 77 69 6e 64 44 65 62 75 67 28 22 72 65 77  RewindDebug("rew
13d60 69 6e 64 64 6f 6e 65 22 29 3b 0a 20 20 72 65 74  inddone");.  ret
13d70 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
13d80 20 41 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20   Advance to the 
13d90 6e 65 78 74 20 65 6c 65 6d 65 6e 74 20 69 6e 20  next element in 
13da0 74 68 65 20 73 6f 72 74 65 72 2e 0a 2a 2f 0a 69  the sorter..*/.i
13db0 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f  nt sqlite3VdbeSo
13dc0 72 74 65 72 4e 65 78 74 28 73 71 6c 69 74 65 33  rterNext(sqlite3
13dd0 20 2a 64 62 2c 20 63 6f 6e 73 74 20 56 64 62 65   *db, const Vdbe
13de0 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e  Cursor *pCsr, in
13df0 74 20 2a 70 62 45 6f 66 29 7b 0a 20 20 56 64 62  t *pbEof){.  Vdb
13e00 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72  eSorter *pSorter
13e10 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72   = pCsr->pSorter
13e20 3b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  ;.  int rc;     
13e30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13e40 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f      /* Return co
13e50 64 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28  de */..  assert(
13e60 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d   pSorter->bUsePM
13e70 41 20 7c 7c 20 28 70 53 6f 72 74 65 72 2d 3e 70  A || (pSorter->p
13e80 52 65 61 64 65 72 3d 3d 30 20 26 26 20 70 53 6f  Reader==0 && pSo
13e90 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 3d 3d 30  rter->pMerger==0
13ea0 29 20 29 3b 0a 20 20 69 66 28 20 70 53 6f 72 74  ) );.  if( pSort
13eb0 65 72 2d 3e 62 55 73 65 50 4d 41 20 29 7b 0a 20  er->bUsePMA ){. 
13ec0 20 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74     assert( pSort
13ed0 65 72 2d 3e 70 52 65 61 64 65 72 3d 3d 30 20 7c  er->pReader==0 |
13ee0 7c 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67  | pSorter->pMerg
13ef0 65 72 3d 3d 30 20 29 3b 0a 20 20 20 20 61 73 73  er==0 );.    ass
13f00 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 62 55  ert( pSorter->bU
13f10 73 65 54 68 72 65 61 64 73 3d 3d 30 20 7c 7c 20  seThreads==0 || 
13f20 70 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72  pSorter->pReader
13f30 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20   );.    assert( 
13f40 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68 72  pSorter->bUseThr
13f50 65 61 64 73 3d 3d 31 20 7c 7c 20 70 53 6f 72 74  eads==1 || pSort
13f60 65 72 2d 3e 70 4d 65 72 67 65 72 20 29 3b 0a 23  er->pMerger );.#
13f70 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f  if SQLITE_MAX_WO
13f80 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 0a 20  RKER_THREADS>0. 
13f90 20 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e     if( pSorter->
13fa0 62 55 73 65 54 68 72 65 61 64 73 20 29 7b 0a 20  bUseThreads ){. 
13fb0 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d       rc = vdbePm
13fc0 61 52 65 61 64 65 72 4e 65 78 74 28 70 53 6f 72  aReaderNext(pSor
13fd0 74 65 72 2d 3e 70 52 65 61 64 65 72 29 3b 0a 20  ter->pReader);. 
13fe0 20 20 20 20 20 2a 70 62 45 6f 66 20 3d 20 28 70       *pbEof = (p
13ff0 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72 2d  Sorter->pReader-
14000 3e 70 46 69 6c 65 3d 3d 30 29 3b 0a 20 20 20 20  >pFile==0);.    
14010 7d 65 6c 73 65 0a 23 65 6e 64 69 66 0a 20 20 20  }else.#endif.   
14020 20 2f 2a 69 66 28 20 21 70 53 6f 72 74 65 72 2d   /*if( !pSorter-
14030 3e 62 55 73 65 54 68 72 65 61 64 73 20 29 2a 2f  >bUseThreads )*/
14040 20 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64   {.      rc = vd
14050 62 65 53 6f 72 74 65 72 4e 65 78 74 28 26 70 53  beSorterNext(&pS
14060 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 30 5d 2c  orter->aTask[0],
14070 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65   pSorter->pMerge
14080 72 2c 20 70 62 45 6f 66 29 3b 0a 20 20 20 20 7d  r, pbEof);.    }
14090 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 53 6f  .  }else{.    So
140a0 72 74 65 72 52 65 63 6f 72 64 20 2a 70 46 72 65  rterRecord *pFre
140b0 65 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73  e = pSorter->lis
140c0 74 2e 70 4c 69 73 74 3b 0a 20 20 20 20 70 53 6f  t.pList;.    pSo
140d0 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74  rter->list.pList
140e0 20 3d 20 70 46 72 65 65 2d 3e 75 2e 70 4e 65 78   = pFree->u.pNex
140f0 74 3b 0a 20 20 20 20 70 46 72 65 65 2d 3e 75 2e  t;.    pFree->u.
14100 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 69  pNext = 0;.    i
14110 66 28 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74  f( pSorter->list
14120 2e 61 4d 65 6d 6f 72 79 3d 3d 30 20 29 20 76 64  .aMemory==0 ) vd
14130 62 65 53 6f 72 74 65 72 52 65 63 6f 72 64 46 72  beSorterRecordFr
14140 65 65 28 64 62 2c 20 70 46 72 65 65 29 3b 0a 20  ee(db, pFree);. 
14150 20 20 20 2a 70 62 45 6f 66 20 3d 20 21 70 53 6f     *pbEof = !pSo
14160 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74  rter->list.pList
14170 3b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54  ;.    rc = SQLIT
14180 45 5f 4f 4b 3b 0a 20 20 7d 0a 20 20 72 65 74 75  E_OK;.  }.  retu
14190 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
141a0 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72  Return a pointer
141b0 20 74 6f 20 61 20 62 75 66 66 65 72 20 6f 77 6e   to a buffer own
141c0 65 64 20 62 79 20 74 68 65 20 73 6f 72 74 65 72  ed by the sorter
141d0 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 74   that contains t
141e0 68 65 20 0a 2a 2a 20 63 75 72 72 65 6e 74 20 6b  he .** current k
141f0 65 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ey..*/.static vo
14200 69 64 20 2a 76 64 62 65 53 6f 72 74 65 72 52 6f  id *vdbeSorterRo
14210 77 6b 65 79 28 0a 20 20 63 6f 6e 73 74 20 56 64  wkey(.  const Vd
14220 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
14230 72 2c 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65  r,      /* Sorte
14240 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e  r object */.  in
14250 74 20 2a 70 6e 4b 65 79 20 20 20 20 20 20 20 20  t *pnKey        
14260 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
14270 20 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20 63 75   OUT: Size of cu
14280 72 72 65 6e 74 20 6b 65 79 20 69 6e 20 62 79 74  rrent key in byt
14290 65 73 20 2a 2f 0a 29 7b 0a 20 20 76 6f 69 64 20  es */.){.  void 
142a0 2a 70 4b 65 79 3b 0a 20 20 69 66 28 20 70 53 6f  *pKey;.  if( pSo
142b0 72 74 65 72 2d 3e 62 55 73 65 50 4d 41 20 29 7b  rter->bUsePMA ){
142c0 0a 20 20 20 20 50 6d 61 52 65 61 64 65 72 20 2a  .    PmaReader *
142d0 70 52 65 61 64 65 72 3b 0a 23 69 66 20 53 51 4c  pReader;.#if SQL
142e0 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54  ITE_MAX_WORKER_T
142f0 48 52 45 41 44 53 3e 30 0a 20 20 20 20 69 66 28  HREADS>0.    if(
14300 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68   pSorter->bUseTh
14310 72 65 61 64 73 20 29 7b 0a 20 20 20 20 20 20 70  reads ){.      p
14320 52 65 61 64 65 72 20 3d 20 70 53 6f 72 74 65 72  Reader = pSorter
14330 2d 3e 70 52 65 61 64 65 72 3b 0a 20 20 20 20 7d  ->pReader;.    }
14340 65 6c 73 65 0a 23 65 6e 64 69 66 0a 20 20 20 20  else.#endif.    
14350 2f 2a 69 66 28 20 21 70 53 6f 72 74 65 72 2d 3e  /*if( !pSorter->
14360 62 55 73 65 54 68 72 65 61 64 73 20 29 2a 2f 7b  bUseThreads )*/{
14370 0a 20 20 20 20 20 20 70 52 65 61 64 65 72 20 3d  .      pReader =
14380 20 26 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67   &pSorter->pMerg
14390 65 72 2d 3e 61 52 65 61 64 72 5b 70 53 6f 72 74  er->aReadr[pSort
143a0 65 72 2d 3e 70 4d 65 72 67 65 72 2d 3e 61 54 72  er->pMerger->aTr
143b0 65 65 5b 31 5d 5d 3b 0a 20 20 20 20 7d 0a 20 20  ee[1]];.    }.  
143c0 20 20 2a 70 6e 4b 65 79 20 3d 20 70 52 65 61 64    *pnKey = pRead
143d0 65 72 2d 3e 6e 4b 65 79 3b 0a 20 20 20 20 70 4b  er->nKey;.    pK
143e0 65 79 20 3d 20 70 52 65 61 64 65 72 2d 3e 61 4b  ey = pReader->aK
143f0 65 79 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ey;.  }else{.   
14400 20 2a 70 6e 4b 65 79 20 3d 20 70 53 6f 72 74 65   *pnKey = pSorte
14410 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 2d 3e 6e  r->list.pList->n
14420 56 61 6c 3b 0a 20 20 20 20 70 4b 65 79 20 3d 20  Val;.    pKey = 
14430 53 52 56 41 4c 28 70 53 6f 72 74 65 72 2d 3e 6c  SRVAL(pSorter->l
14440 69 73 74 2e 70 4c 69 73 74 29 3b 0a 20 20 7d 0a  ist.pList);.  }.
14450 20 20 72 65 74 75 72 6e 20 70 4b 65 79 3b 0a 7d    return pKey;.}
14460 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20 74 68 65  ../*.** Copy the
14470 20 63 75 72 72 65 6e 74 20 73 6f 72 74 65 72 20   current sorter 
14480 6b 65 79 20 69 6e 74 6f 20 74 68 65 20 6d 65 6d  key into the mem
14490 6f 72 79 20 63 65 6c 6c 20 70 4f 75 74 2e 0a 2a  ory cell pOut..*
144a0 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62  /.int sqlite3Vdb
144b0 65 53 6f 72 74 65 72 52 6f 77 6b 65 79 28 63 6f  eSorterRowkey(co
144c0 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a  nst VdbeCursor *
144d0 70 43 73 72 2c 20 4d 65 6d 20 2a 70 4f 75 74 29  pCsr, Mem *pOut)
144e0 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a  {.  VdbeSorter *
144f0 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e  pSorter = pCsr->
14500 70 53 6f 72 74 65 72 3b 0a 20 20 76 6f 69 64 20  pSorter;.  void 
14510 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b 65 79 3b  *pKey; int nKey;
14520 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f             /* So
14530 72 74 65 72 20 6b 65 79 20 74 6f 20 63 6f 70 79  rter key to copy
14540 20 69 6e 74 6f 20 70 4f 75 74 20 2a 2f 0a 0a 20   into pOut */.. 
14550 20 70 4b 65 79 20 3d 20 76 64 62 65 53 6f 72 74   pKey = vdbeSort
14560 65 72 52 6f 77 6b 65 79 28 70 53 6f 72 74 65 72  erRowkey(pSorter
14570 2c 20 26 6e 4b 65 79 29 3b 0a 20 20 69 66 28 20  , &nKey);.  if( 
14580 73 71 6c 69 74 65 33 56 64 62 65 4d 65 6d 47 72  sqlite3VdbeMemGr
14590 6f 77 28 70 4f 75 74 2c 20 6e 4b 65 79 2c 20 30  ow(pOut, nKey, 0
145a0 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
145b0 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
145c0 7d 0a 20 20 70 4f 75 74 2d 3e 6e 20 3d 20 6e 4b  }.  pOut->n = nK
145d0 65 79 3b 0a 20 20 4d 65 6d 53 65 74 54 79 70 65  ey;.  MemSetType
145e0 46 6c 61 67 28 70 4f 75 74 2c 20 4d 45 4d 5f 42  Flag(pOut, MEM_B
145f0 6c 6f 62 29 3b 0a 20 20 6d 65 6d 63 70 79 28 70  lob);.  memcpy(p
14600 4f 75 74 2d 3e 7a 2c 20 70 4b 65 79 2c 20 6e 4b  Out->z, pKey, nK
14610 65 79 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 53  ey);..  return S
14620 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
14630 2a 2a 20 43 6f 6d 70 61 72 65 20 74 68 65 20 6b  ** Compare the k
14640 65 79 20 69 6e 20 6d 65 6d 6f 72 79 20 63 65 6c  ey in memory cel
14650 6c 20 70 56 61 6c 20 77 69 74 68 20 74 68 65 20  l pVal with the 
14660 6b 65 79 20 74 68 61 74 20 74 68 65 20 73 6f 72  key that the sor
14670 74 65 72 20 63 75 72 73 6f 72 0a 2a 2a 20 70 61  ter cursor.** pa
14680 73 73 65 64 20 61 73 20 74 68 65 20 66 69 72 73  ssed as the firs
14690 74 20 61 72 67 75 6d 65 6e 74 20 63 75 72 72 65  t argument curre
146a0 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f 2e 20  ntly points to. 
146b0 46 6f 72 20 74 68 65 20 70 75 72 70 6f 73 65 73  For the purposes
146c0 20 6f 66 0a 2a 2a 20 74 68 65 20 63 6f 6d 70 61   of.** the compa
146d0 72 69 73 6f 6e 2c 20 69 67 6e 6f 72 65 20 74 68  rison, ignore th
146e0 65 20 72 6f 77 69 64 20 66 69 65 6c 64 20 61 74  e rowid field at
146f0 20 74 68 65 20 65 6e 64 20 6f 66 20 65 61 63 68   the end of each
14700 20 72 65 63 6f 72 64 2e 0a 2a 2a 0a 2a 2a 20 49   record..**.** I
14710 66 20 74 68 65 20 73 6f 72 74 65 72 20 63 75 72  f the sorter cur
14720 73 6f 72 20 6b 65 79 20 63 6f 6e 74 61 69 6e 73  sor key contains
14730 20 61 6e 79 20 4e 55 4c 4c 20 76 61 6c 75 65 73   any NULL values
14740 2c 20 63 6f 6e 73 69 64 65 72 20 69 74 20 74 6f  , consider it to
14750 20 62 65 0a 2a 2a 20 6c 65 73 73 20 74 68 61 6e   be.** less than
14760 20 70 56 61 6c 2e 20 45 76 65 6e 20 69 66 20 70   pVal. Even if p
14770 56 61 6c 20 61 6c 73 6f 20 63 6f 6e 74 61 69 6e  Val also contain
14780 73 20 4e 55 4c 4c 20 76 61 6c 75 65 73 2e 0a 2a  s NULL values..*
14790 2a 0a 2a 2a 20 49 66 20 61 6e 20 65 72 72 6f 72  *.** If an error
147a0 20 6f 63 63 75 72 73 2c 20 72 65 74 75 72 6e 20   occurs, return 
147b0 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
147c0 63 6f 64 65 20 28 69 2e 65 2e 20 53 51 4c 49 54  code (i.e. SQLIT
147d0 45 5f 4e 4f 4d 45 4d 29 2e 0a 2a 2a 20 4f 74 68  E_NOMEM)..** Oth
147e0 65 72 77 69 73 65 2c 20 73 65 74 20 2a 70 52 65  erwise, set *pRe
147f0 73 20 74 6f 20 61 20 6e 65 67 61 74 69 76 65 2c  s to a negative,
14800 20 7a 65 72 6f 20 6f 72 20 70 6f 73 69 74 69 76   zero or positiv
14810 65 20 76 61 6c 75 65 20 69 66 20 74 68 65 0a 2a  e value if the.*
14820 2a 20 6b 65 79 20 69 6e 20 70 56 61 6c 20 69 73  * key in pVal is
14830 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 2c 20 65   smaller than, e
14840 71 75 61 6c 20 74 6f 20 6f 72 20 6c 61 72 67 65  qual to or large
14850 72 20 74 68 61 6e 20 74 68 65 20 63 75 72 72 65  r than the curre
14860 6e 74 20 73 6f 72 74 65 72 0a 2a 2a 20 6b 65 79  nt sorter.** key
14870 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ..**.** This rou
14880 74 69 6e 65 20 66 6f 72 6d 73 20 74 68 65 20 63  tine forms the c
14890 6f 72 65 20 6f 66 20 74 68 65 20 4f 50 5f 53 6f  ore of the OP_So
148a0 72 74 65 72 43 6f 6d 70 61 72 65 20 6f 70 63 6f  rterCompare opco
148b0 64 65 2c 20 77 68 69 63 68 20 69 6e 0a 2a 2a 20  de, which in.** 
148c0 74 75 72 6e 20 69 73 20 75 73 65 64 20 74 6f 20  turn is used to 
148d0 76 65 72 69 66 79 20 75 6e 69 71 75 65 6e 65 73  verify uniquenes
148e0 73 20 77 68 65 6e 20 63 6f 6e 73 74 72 75 63 74  s when construct
148f0 69 6e 67 20 61 20 55 4e 49 51 55 45 20 49 4e 44  ing a UNIQUE IND
14900 45 58 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  EX..*/.int sqlit
14910 65 33 56 64 62 65 53 6f 72 74 65 72 43 6f 6d 70  e3VdbeSorterComp
14920 61 72 65 28 0a 20 20 63 6f 6e 73 74 20 56 64 62  are(.  const Vdb
14930 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 20  eCursor *pCsr,  
14940 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72         /* Sorter
14950 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 4d 65 6d   cursor */.  Mem
14960 20 2a 70 56 61 6c 2c 20 20 20 20 20 20 20 20 20   *pVal,         
14970 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
14980 56 61 6c 75 65 20 74 6f 20 63 6f 6d 70 61 72 65  Value to compare
14990 20 74 6f 20 63 75 72 72 65 6e 74 20 73 6f 72 74   to current sort
149a0 65 72 20 6b 65 79 20 2a 2f 0a 20 20 69 6e 74 20  er key */.  int 
149b0 6e 49 67 6e 6f 72 65 2c 20 20 20 20 20 20 20 20  nIgnore,        
149c0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
149d0 67 6e 6f 72 65 20 74 68 69 73 20 6d 61 6e 79 20  gnore this many 
149e0 66 69 65 6c 64 73 20 61 74 20 74 68 65 20 65 6e  fields at the en
149f0 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 52 65 73  d */.  int *pRes
14a00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14a10 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 52         /* OUT: R
14a20 65 73 75 6c 74 20 6f 66 20 63 6f 6d 70 61 72 69  esult of compari
14a30 73 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65  son */.){.  Vdbe
14a40 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20  Sorter *pSorter 
14a50 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b  = pCsr->pSorter;
14a60 0a 20 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72  .  UnpackedRecor
14a70 64 20 2a 72 32 20 3d 20 70 53 6f 72 74 65 72 2d  d *r2 = pSorter-
14a80 3e 70 55 6e 70 61 63 6b 65 64 3b 0a 20 20 4b 65  >pUnpacked;.  Ke
14a90 79 49 6e 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 20  yInfo *pKeyInfo 
14aa0 3d 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f  = pCsr->pKeyInfo
14ab0 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 76 6f 69  ;.  int i;.  voi
14ac0 64 20 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b 65  d *pKey; int nKe
14ad0 79 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  y;           /* 
14ae0 53 6f 72 74 65 72 20 6b 65 79 20 74 6f 20 63 6f  Sorter key to co
14af0 6d 70 61 72 65 20 70 56 61 6c 20 77 69 74 68 20  mpare pVal with 
14b00 2a 2f 0a 0a 20 20 69 66 28 20 72 32 3d 3d 30 20  */..  if( r2==0 
14b10 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 70 3b 0a  ){.    char *p;.
14b20 20 20 20 20 72 32 20 3d 20 70 53 6f 72 74 65 72      r2 = pSorter
14b30 2d 3e 70 55 6e 70 61 63 6b 65 64 20 3d 20 73 71  ->pUnpacked = sq
14b40 6c 69 74 65 33 56 64 62 65 41 6c 6c 6f 63 55 6e  lite3VdbeAllocUn
14b50 70 61 63 6b 65 64 52 65 63 6f 72 64 28 70 4b 65  packedRecord(pKe
14b60 79 49 6e 66 6f 2c 30 2c 30 2c 26 70 29 3b 0a 20  yInfo,0,0,&p);. 
14b70 20 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74     assert( pSort
14b80 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64 3d 3d 28  er->pUnpacked==(
14b90 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 2a 29  UnpackedRecord*)
14ba0 70 20 29 3b 0a 20 20 20 20 69 66 28 20 72 32 3d  p );.    if( r2=
14bb0 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  =0 ) return SQLI
14bc0 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 72 32  TE_NOMEM;.    r2
14bd0 2d 3e 6e 46 69 65 6c 64 20 3d 20 70 4b 65 79 49  ->nField = pKeyI
14be0 6e 66 6f 2d 3e 6e 46 69 65 6c 64 2d 6e 49 67 6e  nfo->nField-nIgn
14bf0 6f 72 65 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72  ore;.  }.  asser
14c00 74 28 20 72 32 2d 3e 6e 46 69 65 6c 64 3e 3d 70  t( r2->nField>=p
14c10 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64 2d  KeyInfo->nField-
14c20 6e 49 67 6e 6f 72 65 20 29 3b 0a 0a 20 20 70 4b  nIgnore );..  pK
14c30 65 79 20 3d 20 76 64 62 65 53 6f 72 74 65 72 52  ey = vdbeSorterR
14c40 6f 77 6b 65 79 28 70 53 6f 72 74 65 72 2c 20 26  owkey(pSorter, &
14c50 6e 4b 65 79 29 3b 0a 20 20 73 71 6c 69 74 65 33  nKey);.  sqlite3
14c60 56 64 62 65 52 65 63 6f 72 64 55 6e 70 61 63 6b  VdbeRecordUnpack
14c70 28 70 4b 65 79 49 6e 66 6f 2c 20 6e 4b 65 79 2c  (pKeyInfo, nKey,
14c80 20 70 4b 65 79 2c 20 72 32 29 3b 0a 20 20 66 6f   pKey, r2);.  fo
14c90 72 28 69 3d 30 3b 20 69 3c 72 32 2d 3e 6e 46 69  r(i=0; i<r2->nFi
14ca0 65 6c 64 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69  eld; i++){.    i
14cb0 66 28 20 72 32 2d 3e 61 4d 65 6d 5b 69 5d 2e 66  f( r2->aMem[i].f
14cc0 6c 61 67 73 20 26 20 4d 45 4d 5f 4e 75 6c 6c 20  lags & MEM_Null 
14cd0 29 7b 0a 20 20 20 20 20 20 2a 70 52 65 73 20 3d  ){.      *pRes =
14ce0 20 2d 31 3b 0a 20 20 20 20 20 20 72 65 74 75 72   -1;.      retur
14cf0 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20  n SQLITE_OK;.   
14d00 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 52 65 73 20   }.  }..  *pRes 
14d10 3d 20 73 71 6c 69 74 65 33 56 64 62 65 52 65 63  = sqlite3VdbeRec
14d20 6f 72 64 43 6f 6d 70 61 72 65 28 70 56 61 6c 2d  ordCompare(pVal-
14d30 3e 6e 2c 20 70 56 61 6c 2d 3e 7a 2c 20 72 32 2c  >n, pVal->z, r2,
14d40 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51   0);.  return SQ
14d50 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a                 LITE_OK;.}.