/ Hex Artifact Content
Login

Artifact d205b56d0a1c2cbd8f6c8c4f513337ab0096d0b3:


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 53 65 65 0a  y the VDBE. See.
15c0: 2a 2a 20 63 6f 6d 6d 65 6e 74 73 20 61 62 6f 76  ** comments abov
15d0: 65 20 6f 62 6a 65 63 74 20 4d 65 72 67 65 45 6e  e object MergeEn
15e0: 67 69 6e 65 20 62 65 6c 6f 77 20 66 6f 72 20 64  gine below for d
15f0: 65 74 61 69 6c 73 2e 0a 2a 2a 0a 2a 2a 20 4f 72  etails..**.** Or
1600: 2c 20 69 66 20 72 75 6e 6e 69 6e 67 20 69 6e 20  , if running in 
1610: 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20 6d  multi-threaded m
1620: 6f 64 65 2c 20 74 68 65 6e 20 61 20 62 61 63 6b  ode, then a back
1630: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 69 73  ground thread is
1640: 0a 2a 2a 20 6c 61 75 6e 63 68 65 64 20 74 6f 20  .** launched to 
1650: 6d 65 72 67 65 20 74 68 65 20 65 78 69 73 74 69  merge the existi
1660: 6e 67 20 50 4d 41 73 2e 20 4f 6e 63 65 20 74 68  ng PMAs. Once th
1670: 65 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  e background thr
1680: 65 61 64 20 68 61 73 0a 2a 2a 20 6d 65 72 67 65  ead has.** merge
1690: 64 20 54 20 62 79 74 65 73 20 6f 66 20 64 61 74  d T bytes of dat
16a0: 61 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65 20  a into a single 
16b0: 73 6f 72 74 65 64 20 50 4d 41 2c 20 74 68 65 20  sorted PMA, the 
16c0: 6d 61 69 6e 20 74 68 72 65 61 64 20 0a 2a 2a 20  main thread .** 
16d0: 62 65 67 69 6e 73 20 72 65 61 64 69 6e 67 20 6b  begins reading k
16e0: 65 79 73 20 66 72 6f 6d 20 74 68 61 74 20 50 4d  eys from that PM
16f0: 41 20 77 68 69 6c 65 20 74 68 65 20 62 61 63 6b  A while the back
1700: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 70 72  ground thread pr
1710: 6f 63 65 65 64 73 0a 2a 2a 20 77 69 74 68 20 6d  oceeds.** with m
1720: 65 72 67 69 6e 67 20 74 68 65 20 6e 65 78 74 20  erging the next 
1730: 54 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 2e  T bytes of data.
1740: 20 41 6e 64 20 73 6f 20 6f 6e 2e 0a 2a 2a 0a 2a   And so on..**.*
1750: 2a 20 50 61 72 61 6d 65 74 65 72 20 54 20 69 73  * Parameter T is
1760: 20 73 65 74 20 74 6f 20 68 61 6c 66 20 74 68 65   set to half the
1770: 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 6d 65   value of the me
1780: 6d 6f 72 79 20 74 68 72 65 73 68 6f 6c 64 20 75  mory threshold u
1790: 73 65 64 20 0a 2a 2a 20 62 79 20 57 72 69 74 65  sed .** by Write
17a0: 28 29 20 61 62 6f 76 65 20 74 6f 20 64 65 74 65  () above to dete
17b0: 72 6d 69 6e 65 20 77 68 65 6e 20 74 6f 20 63 72  rmine when to cr
17c0: 65 61 74 65 20 61 20 6e 65 77 20 50 4d 41 2e 0a  eate a new PMA..
17d0: 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65 20 61  **.** If there a
17e0: 72 65 20 6d 6f 72 65 20 74 68 61 6e 20 53 4f 52  re more than SOR
17f0: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
1800: 55 4e 54 20 50 4d 41 73 20 69 6e 20 74 6f 74 61  UNT PMAs in tota
1810: 6c 20 77 68 65 6e 20 0a 2a 2a 20 52 65 77 69 6e  l when .** Rewin
1820: 64 28 29 20 69 73 20 63 61 6c 6c 65 64 2c 20 74  d() is called, t
1830: 68 65 6e 20 61 20 68 69 65 72 61 72 63 68 79 20  hen a hierarchy 
1840: 6f 66 20 69 6e 63 72 65 6d 65 6e 74 61 6c 2d 6d  of incremental-m
1850: 65 72 67 65 73 20 69 73 20 75 73 65 64 2e 20 0a  erges is used. .
1860: 2a 2a 20 46 69 72 73 74 2c 20 54 20 62 79 74 65  ** First, T byte
1870: 73 20 6f 66 20 64 61 74 61 20 66 72 6f 6d 20 74  s of data from t
1880: 68 65 20 66 69 72 73 74 20 53 4f 52 54 45 52 5f  he first SORTER_
1890: 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20  MAX_MERGE_COUNT 
18a0: 50 4d 41 73 20 6f 6e 20 0a 2a 2a 20 64 69 73 6b  PMAs on .** disk
18b0: 20 61 72 65 20 6d 65 72 67 65 64 20 74 6f 67 65   are merged toge
18c0: 74 68 65 72 2e 20 54 68 65 6e 20 54 20 62 79 74  ther. Then T byt
18d0: 65 73 20 6f 66 20 64 61 74 61 20 66 72 6f 6d 20  es of data from 
18e0: 74 68 65 20 73 65 63 6f 6e 64 20 73 65 74 2c 20  the second set, 
18f0: 61 6e 64 0a 2a 2a 20 73 6f 20 6f 6e 2c 20 73 75  and.** so on, su
1900: 63 68 20 74 68 61 74 20 6e 6f 20 6f 70 65 72 61  ch that no opera
1910: 74 69 6f 6e 20 65 76 65 72 20 6d 65 72 67 65 73  tion ever merges
1920: 20 6d 6f 72 65 20 74 68 61 6e 20 53 4f 52 54 45   more than SORTE
1930: 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
1940: 54 0a 2a 2a 20 50 4d 41 73 20 61 74 20 61 20 74  T.** PMAs at a t
1950: 69 6d 65 2e 20 54 68 69 73 20 64 6f 6e 65 20 69  ime. This done i
1960: 73 20 74 6f 20 69 6d 70 72 6f 76 65 20 6c 6f 63  s to improve loc
1970: 61 6c 69 74 79 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  ality..**.** If 
1980: 72 75 6e 6e 69 6e 67 20 69 6e 20 6d 75 6c 74 69  running in multi
1990: 2d 74 68 72 65 61 64 65 64 20 6d 6f 64 65 20 61  -threaded mode a
19a0: 6e 64 20 74 68 65 72 65 20 61 72 65 20 6d 6f 72  nd there are mor
19b0: 65 20 74 68 61 6e 0a 2a 2a 20 53 4f 52 54 45 52  e than.** SORTER
19c0: 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
19d0: 20 50 4d 41 73 20 6f 6e 20 64 69 73 6b 20 77 68   PMAs on disk wh
19e0: 65 6e 20 52 65 77 69 6e 64 28 29 20 69 73 20 63  en Rewind() is c
19f0: 61 6c 6c 65 64 2c 20 74 68 65 6e 20 6d 6f 72 65  alled, then more
1a00: 0a 2a 2a 20 74 68 61 6e 20 6f 6e 65 20 62 61 63  .** than one bac
1a10: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 6d  kground thread m
1a20: 61 79 20 62 65 20 63 72 65 61 74 65 64 2e 20 53  ay be created. S
1a30: 70 65 63 69 66 69 63 61 6c 6c 79 2c 20 74 68 65  pecifically, the
1a40: 72 65 20 6d 61 79 20 62 65 0a 2a 2a 20 6f 6e 65  re may be.** one
1a50: 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65   background thre
1a60: 61 64 20 66 6f 72 20 65 61 63 68 20 74 65 6d 70  ad for each temp
1a70: 6f 72 61 72 79 20 66 69 6c 65 20 6f 6e 20 64 69  orary file on di
1a80: 73 6b 2c 20 61 6e 64 20 6f 6e 65 20 62 61 63 6b  sk, and one back
1a90: 67 72 6f 75 6e 64 0a 2a 2a 20 74 68 72 65 61 64  ground.** thread
1aa0: 20 74 6f 20 6d 65 72 67 65 20 74 68 65 20 6f 75   to merge the ou
1ab0: 74 70 75 74 20 6f 66 20 65 61 63 68 20 6f 66 20  tput of each of 
1ac0: 74 68 65 20 6f 74 68 65 72 73 20 74 6f 20 61 20  the others to a 
1ad0: 73 69 6e 67 6c 65 20 50 4d 41 20 66 6f 72 0a 2a  single PMA for.*
1ae0: 2a 20 74 68 65 20 6d 61 69 6e 20 74 68 72 65 61  * the main threa
1af0: 64 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 2e 0a  d to read from..
1b00: 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c  */.#include "sql
1b10: 69 74 65 49 6e 74 2e 68 22 0a 23 69 6e 63 6c 75  iteInt.h".#inclu
1b20: 64 65 20 22 76 64 62 65 49 6e 74 2e 68 22 0a 0a  de "vdbeInt.h"..
1b30: 2f 2a 20 0a 2a 2a 20 49 66 20 53 51 4c 49 54 45  /* .** If SQLITE
1b40: 5f 44 45 42 55 47 5f 53 4f 52 54 45 52 5f 54 48  _DEBUG_SORTER_TH
1b50: 52 45 41 44 53 20 69 73 20 64 65 66 69 6e 65 64  READS is defined
1b60: 2c 20 74 68 69 73 20 6d 6f 64 75 6c 65 20 6f 75  , this module ou
1b70: 74 70 75 74 73 20 76 61 72 69 6f 75 73 0a 2a 2a  tputs various.**
1b80: 20 6d 65 73 73 61 67 65 73 20 74 6f 20 73 74 64   messages to std
1b90: 65 72 72 20 74 68 61 74 20 6d 61 79 20 62 65 20  err that may be 
1ba0: 68 65 6c 70 66 75 6c 20 69 6e 20 75 6e 64 65 72  helpful in under
1bb0: 73 74 61 6e 64 69 6e 67 20 74 68 65 20 70 65 72  standing the per
1bc0: 66 6f 72 6d 61 6e 63 65 0a 2a 2a 20 63 68 61 72  formance.** char
1bd0: 61 63 74 65 72 69 73 74 69 63 73 20 6f 66 20 74  acteristics of t
1be0: 68 65 20 73 6f 72 74 65 72 20 69 6e 20 6d 75 6c  he sorter in mul
1bf0: 74 69 2d 74 68 72 65 61 64 65 64 20 6d 6f 64 65  ti-threaded mode
1c00: 2e 0a 2a 2f 0a 23 69 66 20 30 0a 23 20 64 65 66  ..*/.#if 0.# def
1c10: 69 6e 65 20 53 51 4c 49 54 45 5f 44 45 42 55 47  ine SQLITE_DEBUG
1c20: 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44 53 20  _SORTER_THREADS 
1c30: 31 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20  1.#endif../*.** 
1c40: 50 72 69 76 61 74 65 20 6f 62 6a 65 63 74 73 20  Private objects 
1c50: 75 73 65 64 20 62 79 20 74 68 65 20 73 6f 72 74  used by the sort
1c60: 65 72 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74  er.*/.typedef st
1c70: 72 75 63 74 20 4d 65 72 67 65 45 6e 67 69 6e 65  ruct MergeEngine
1c80: 20 4d 65 72 67 65 45 6e 67 69 6e 65 3b 20 20 20   MergeEngine;   
1c90: 20 20 2f 2a 20 4d 65 72 67 65 20 50 4d 41 73 20    /* Merge PMAs 
1ca0: 74 6f 67 65 74 68 65 72 20 2a 2f 0a 74 79 70 65  together */.type
1cb0: 64 65 66 20 73 74 72 75 63 74 20 50 6d 61 52 65  def struct PmaRe
1cc0: 61 64 65 72 20 50 6d 61 52 65 61 64 65 72 3b 20  ader PmaReader; 
1cd0: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 63 72 65          /* Incre
1ce0: 6d 65 6e 74 61 6c 6c 79 20 72 65 61 64 20 6f 6e  mentally read on
1cf0: 65 20 50 4d 41 20 2a 2f 0a 74 79 70 65 64 65 66  e PMA */.typedef
1d00: 20 73 74 72 75 63 74 20 50 6d 61 57 72 69 74 65   struct PmaWrite
1d10: 72 20 50 6d 61 57 72 69 74 65 72 3b 20 20 20 20  r PmaWriter;    
1d20: 20 20 20 20 20 2f 2a 20 49 6e 63 72 65 6d 65 6e       /* Incremen
1d30: 74 61 6c 6c 79 20 77 72 69 74 65 20 6f 6e 65 20  tally write one 
1d40: 50 4d 41 20 2a 2f 0a 74 79 70 65 64 65 66 20 73  PMA */.typedef s
1d50: 74 72 75 63 74 20 53 6f 72 74 65 72 52 65 63 6f  truct SorterReco
1d60: 72 64 20 53 6f 72 74 65 72 52 65 63 6f 72 64 3b  rd SorterRecord;
1d70: 20 20 20 2f 2a 20 41 20 72 65 63 6f 72 64 20 62     /* A record b
1d80: 65 69 6e 67 20 73 6f 72 74 65 64 20 2a 2f 0a 74  eing sorted */.t
1d90: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53 6f  ypedef struct So
1da0: 72 74 53 75 62 74 61 73 6b 20 53 6f 72 74 53 75  rtSubtask SortSu
1db0: 62 74 61 73 6b 3b 20 20 20 20 20 2f 2a 20 41 20  btask;     /* A 
1dc0: 73 75 62 2d 74 61 73 6b 20 69 6e 20 74 68 65 20  sub-task in the 
1dd0: 73 6f 72 74 20 70 72 6f 63 65 73 73 20 2a 2f 0a  sort process */.
1de0: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53  typedef struct S
1df0: 6f 72 74 65 72 46 69 6c 65 20 53 6f 72 74 65 72  orterFile Sorter
1e00: 46 69 6c 65 3b 20 20 20 20 20 20 20 2f 2a 20 54  File;       /* T
1e10: 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 20 6f 62  emporary file ob
1e20: 6a 65 63 74 20 77 72 61 70 70 65 72 20 2a 2f 0a  ject wrapper */.
1e30: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53  typedef struct S
1e40: 6f 72 74 65 72 4c 69 73 74 20 53 6f 72 74 65 72  orterList Sorter
1e50: 4c 69 73 74 3b 20 20 20 20 20 20 20 2f 2a 20 49  List;       /* I
1e60: 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20 6f 66  n-memory list of
1e70: 20 72 65 63 6f 72 64 73 20 2a 2f 0a 74 79 70 65   records */.type
1e80: 64 65 66 20 73 74 72 75 63 74 20 49 6e 63 72 4d  def struct IncrM
1e90: 65 72 67 65 72 20 49 6e 63 72 4d 65 72 67 65 72  erger IncrMerger
1ea0: 3b 20 20 20 20 20 20 20 2f 2a 20 52 65 61 64 20  ;       /* Read 
1eb0: 26 20 6d 65 72 67 65 20 6d 75 6c 74 69 70 6c 65  & merge multiple
1ec0: 20 50 4d 41 73 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20   PMAs */../*.** 
1ed0: 41 20 63 6f 6e 74 61 69 6e 65 72 20 66 6f 72 20  A container for 
1ee0: 61 20 74 65 6d 70 20 66 69 6c 65 20 68 61 6e 64  a temp file hand
1ef0: 6c 65 20 61 6e 64 20 74 68 65 20 63 75 72 72 65  le and the curre
1f00: 6e 74 20 61 6d 6f 75 6e 74 20 6f 66 20 64 61 74  nt amount of dat
1f10: 61 20 0a 2a 2a 20 73 74 6f 72 65 64 20 69 6e 20  a .** stored in 
1f20: 74 68 65 20 66 69 6c 65 2e 0a 2a 2f 0a 73 74 72  the file..*/.str
1f30: 75 63 74 20 53 6f 72 74 65 72 46 69 6c 65 20 7b  uct SorterFile {
1f40: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
1f50: 2a 70 46 64 3b 20 20 20 20 20 20 20 20 20 20 20  *pFd;           
1f60: 20 20 20 2f 2a 20 46 69 6c 65 20 68 61 6e 64 6c     /* File handl
1f70: 65 20 2a 2f 0a 20 20 69 36 34 20 69 45 6f 66 3b  e */.  i64 iEof;
1f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f90: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
1fa0: 6f 66 20 64 61 74 61 20 73 74 6f 72 65 64 20 69  of data stored i
1fb0: 6e 20 70 46 64 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  n pFd */.};../*.
1fc0: 2a 2a 20 41 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20  ** An in-memory 
1fd0: 6c 69 73 74 20 6f 66 20 6f 62 6a 65 63 74 73 20  list of objects 
1fe0: 74 6f 20 62 65 20 73 6f 72 74 65 64 2e 0a 2a 2a  to be sorted..**
1ff0: 0a 2a 2a 20 49 66 20 61 4d 65 6d 6f 72 79 3d 3d  .** If aMemory==
2000: 30 20 74 68 65 6e 20 65 61 63 68 20 6f 62 6a 65  0 then each obje
2010: 63 74 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 20  ct is allocated 
2020: 73 65 70 61 72 61 74 65 6c 79 20 61 6e 64 20 74  separately and t
2030: 68 65 20 6f 62 6a 65 63 74 73 0a 2a 2a 20 61 72  he objects.** ar
2040: 65 20 63 6f 6e 6e 65 63 74 65 64 20 75 73 69 6e  e connected usin
2050: 67 20 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 75  g SorterRecord.u
2060: 2e 70 4e 65 78 74 2e 20 20 49 66 20 61 4d 65 6d  .pNext.  If aMem
2070: 6f 72 79 21 3d 30 20 74 68 65 6e 20 61 6c 6c 20  ory!=0 then all 
2080: 6f 62 6a 65 63 74 73 0a 2a 2a 20 61 72 65 20 73  objects.** are s
2090: 74 6f 72 65 64 20 69 6e 20 74 68 65 20 61 4d 65  tored in the aMe
20a0: 6d 6f 72 79 5b 5d 20 62 75 6c 6b 20 6d 65 6d 6f  mory[] bulk memo
20b0: 72 79 2c 20 6f 6e 65 20 72 69 67 68 74 20 61 66  ry, one right af
20c0: 74 65 72 20 74 68 65 20 6f 74 68 65 72 2c 20 61  ter the other, a
20d0: 6e 64 0a 2a 2a 20 61 72 65 20 63 6f 6e 6e 65 63  nd.** are connec
20e0: 74 65 64 20 75 73 69 6e 67 20 53 6f 72 74 65 72  ted using Sorter
20f0: 52 65 63 6f 72 64 2e 75 2e 69 4e 65 78 74 2e 0a  Record.u.iNext..
2100: 2a 2f 0a 73 74 72 75 63 74 20 53 6f 72 74 65 72  */.struct Sorter
2110: 4c 69 73 74 20 7b 0a 20 20 53 6f 72 74 65 72 52  List {.  SorterR
2120: 65 63 6f 72 64 20 2a 70 4c 69 73 74 3b 20 20 20  ecord *pList;   
2130: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 6e 6b           /* Link
2140: 65 64 20 6c 69 73 74 20 6f 66 20 72 65 63 6f 72  ed list of recor
2150: 64 73 20 2a 2f 0a 20 20 75 38 20 2a 61 4d 65 6d  ds */.  u8 *aMem
2160: 6f 72 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  ory;            
2170: 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 6e 6f          /* If no
2180: 6e 2d 4e 55 4c 4c 2c 20 62 75 6c 6b 20 6d 65 6d  n-NULL, bulk mem
2190: 6f 72 79 20 74 6f 20 68 6f 6c 64 20 70 4c 69 73  ory to hold pLis
21a0: 74 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 4d 41  t */.  int szPMA
21b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
21c0: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
21d0: 66 20 70 4c 69 73 74 20 61 73 20 50 4d 41 20 69  f pList as PMA i
21e0: 6e 20 62 79 74 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f  n bytes */.};../
21f0: 2a 0a 2a 2a 20 54 68 65 20 4d 65 72 67 65 45 6e  *.** The MergeEn
2200: 67 69 6e 65 20 6f 62 6a 65 63 74 20 69 73 20 75  gine object is u
2210: 73 65 64 20 74 6f 20 63 6f 6d 62 69 6e 65 20 74  sed to combine t
2220: 77 6f 20 6f 72 20 6d 6f 72 65 20 73 6d 61 6c 6c  wo or more small
2230: 65 72 20 50 4d 41 73 20 69 6e 74 6f 0a 2a 2a 20  er PMAs into.** 
2240: 6f 6e 65 20 62 69 67 20 50 4d 41 20 75 73 69 6e  one big PMA usin
2250: 67 20 61 20 6d 65 72 67 65 20 6f 70 65 72 61 74  g a merge operat
2260: 69 6f 6e 2e 20 20 53 65 70 61 72 61 74 65 20 50  ion.  Separate P
2270: 4d 41 73 20 61 6c 6c 20 6e 65 65 64 20 74 6f 20  MAs all need to 
2280: 62 65 0a 2a 2a 20 63 6f 6d 62 69 6e 65 64 20 69  be.** combined i
2290: 6e 74 6f 20 6f 6e 65 20 62 69 67 20 50 4d 41 20  nto one big PMA 
22a0: 69 6e 20 6f 72 64 65 72 20 74 6f 20 62 65 20 61  in order to be a
22b0: 62 6c 65 20 74 6f 20 73 74 65 70 20 74 68 72 6f  ble to step thro
22c0: 75 67 68 20 74 68 65 20 73 6f 72 74 65 64 0a 2a  ugh the sorted.*
22d0: 2a 20 72 65 63 6f 72 64 73 20 69 6e 20 6f 72 64  * records in ord
22e0: 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 49  er..**.** The aI
22f0: 74 65 72 5b 5d 20 61 72 72 61 79 20 63 6f 6e 74  ter[] array cont
2300: 61 69 6e 73 20 61 20 50 6d 61 52 65 61 64 65 72  ains a PmaReader
2310: 20 6f 62 6a 65 63 74 20 66 6f 72 20 65 61 63 68   object for each
2320: 20 6f 66 20 74 68 65 20 50 4d 41 73 20 62 65 69   of the PMAs bei
2330: 6e 67 0a 2a 2a 20 6d 65 72 67 65 64 2e 20 20 41  ng.** merged.  A
2340: 6e 20 61 49 74 65 72 5b 5d 20 6f 62 6a 65 63 74  n aIter[] object
2350: 20 65 69 74 68 65 72 20 70 6f 69 6e 74 73 20 74   either points t
2360: 6f 20 61 20 76 61 6c 69 64 20 6b 65 79 20 6f 72  o a valid key or
2370: 20 65 6c 73 65 20 69 73 20 61 74 20 45 4f 46 2e   else is at EOF.
2380: 0a 2a 2a 20 46 6f 72 20 74 68 65 20 70 75 72 70  .** For the purp
2390: 6f 73 65 73 20 6f 66 20 74 68 65 20 70 61 72 61  oses of the para
23a0: 67 72 61 70 68 73 20 62 65 6c 6f 77 2c 20 77 65  graphs below, we
23b0: 20 61 73 73 75 6d 65 20 74 68 61 74 20 74 68 65   assume that the
23c0: 20 61 72 72 61 79 20 69 73 0a 2a 2a 20 61 63 74   array is.** act
23d0: 75 61 6c 6c 79 20 4e 20 65 6c 65 6d 65 6e 74 73  ually N elements
23e0: 20 69 6e 20 73 69 7a 65 2c 20 77 68 65 72 65 20   in size, where 
23f0: 4e 20 69 73 20 74 68 65 20 73 6d 61 6c 6c 65 73  N is the smalles
2400: 74 20 70 6f 77 65 72 20 6f 66 20 32 20 67 72 65  t power of 2 gre
2410: 61 74 65 72 0a 2a 2a 20 74 6f 20 6f 72 20 65 71  ater.** to or eq
2420: 75 61 6c 20 74 6f 20 74 68 65 20 6e 75 6d 62 65  ual to the numbe
2430: 72 20 6f 66 20 50 4d 41 73 20 62 65 69 6e 67 20  r of PMAs being 
2440: 6d 65 72 67 65 64 2e 20 54 68 65 20 65 78 74 72  merged. The extr
2450: 61 20 61 49 74 65 72 5b 5d 20 65 6c 65 6d 65 6e  a aIter[] elemen
2460: 74 73 0a 2a 2a 20 61 72 65 20 74 72 65 61 74 65  ts.** are treate
2470: 64 20 61 73 20 69 66 20 74 68 65 79 20 61 72 65  d as if they are
2480: 20 65 6d 70 74 79 20 28 61 6c 77 61 79 73 20 61   empty (always a
2490: 74 20 45 4f 46 29 2e 0a 2a 2a 0a 2a 2a 20 54 68  t EOF)..**.** Th
24a0: 65 20 61 54 72 65 65 5b 5d 20 61 72 72 61 79 20  e aTree[] array 
24b0: 69 73 20 61 6c 73 6f 20 4e 20 65 6c 65 6d 65 6e  is also N elemen
24c0: 74 73 20 69 6e 20 73 69 7a 65 2e 20 54 68 65 20  ts in size. The 
24d0: 76 61 6c 75 65 20 6f 66 20 4e 20 69 73 20 73 74  value of N is st
24e0: 6f 72 65 64 20 69 6e 0a 2a 2a 20 74 68 65 20 4d  ored in.** the M
24f0: 65 72 67 65 45 6e 67 69 6e 65 2e 6e 54 72 65 65  ergeEngine.nTree
2500: 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a   variable..**.**
2510: 20 54 68 65 20 66 69 6e 61 6c 20 28 4e 2f 32 29   The final (N/2)
2520: 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20 61 54 72   elements of aTr
2530: 65 65 5b 5d 20 63 6f 6e 74 61 69 6e 20 74 68 65  ee[] contain the
2540: 20 72 65 73 75 6c 74 73 20 6f 66 20 63 6f 6d 70   results of comp
2550: 61 72 69 6e 67 0a 2a 2a 20 70 61 69 72 73 20 6f  aring.** pairs o
2560: 66 20 50 4d 41 20 6b 65 79 73 20 74 6f 67 65 74  f PMA keys toget
2570: 68 65 72 2e 20 45 6c 65 6d 65 6e 74 20 69 20 63  her. Element i c
2580: 6f 6e 74 61 69 6e 73 20 74 68 65 20 72 65 73 75  ontains the resu
2590: 6c 74 20 6f 66 20 0a 2a 2a 20 63 6f 6d 70 61 72  lt of .** compar
25a0: 69 6e 67 20 61 49 74 65 72 5b 32 2a 69 2d 4e 5d  ing aIter[2*i-N]
25b0: 20 61 6e 64 20 61 49 74 65 72 5b 32 2a 69 2d 4e   and aIter[2*i-N
25c0: 2b 31 5d 2e 20 57 68 69 63 68 65 76 65 72 20 6b  +1]. Whichever k
25d0: 65 79 20 69 73 20 73 6d 61 6c 6c 65 72 2c 20 74  ey is smaller, t
25e0: 68 65 0a 2a 2a 20 61 54 72 65 65 20 65 6c 65 6d  he.** aTree elem
25f0: 65 6e 74 20 69 73 20 73 65 74 20 74 6f 20 74 68  ent is set to th
2600: 65 20 69 6e 64 65 78 20 6f 66 20 69 74 2e 20 0a  e index of it. .
2610: 2a 2a 0a 2a 2a 20 46 6f 72 20 74 68 65 20 70 75  **.** For the pu
2620: 72 70 6f 73 65 73 20 6f 66 20 74 68 69 73 20 63  rposes of this c
2630: 6f 6d 70 61 72 69 73 6f 6e 2c 20 45 4f 46 20 69  omparison, EOF i
2640: 73 20 63 6f 6e 73 69 64 65 72 65 64 20 67 72 65  s considered gre
2650: 61 74 65 72 20 74 68 61 6e 20 61 6e 79 0a 2a 2a  ater than any.**
2660: 20 6f 74 68 65 72 20 6b 65 79 20 76 61 6c 75 65   other key value
2670: 2e 20 49 66 20 74 68 65 20 6b 65 79 73 20 61 72  . If the keys ar
2680: 65 20 65 71 75 61 6c 20 28 6f 6e 6c 79 20 70 6f  e equal (only po
2690: 73 73 69 62 6c 65 20 77 69 74 68 20 74 77 6f 20  ssible with two 
26a0: 45 4f 46 0a 2a 2a 20 76 61 6c 75 65 73 29 2c 20  EOF.** values), 
26b0: 69 74 20 64 6f 65 73 6e 27 74 20 6d 61 74 74 65  it doesn't matte
26c0: 72 20 77 68 69 63 68 20 69 6e 64 65 78 20 69 73  r which index is
26d0: 20 73 74 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 54   stored..**.** T
26e0: 68 65 20 28 4e 2f 34 29 20 65 6c 65 6d 65 6e 74  he (N/4) element
26f0: 73 20 6f 66 20 61 54 72 65 65 5b 5d 20 74 68 61  s of aTree[] tha
2700: 74 20 70 72 65 63 65 64 65 20 74 68 65 20 66 69  t precede the fi
2710: 6e 61 6c 20 28 4e 2f 32 29 20 64 65 73 63 72 69  nal (N/2) descri
2720: 62 65 64 20 0a 2a 2a 20 61 62 6f 76 65 20 63 6f  bed .** above co
2730: 6e 74 61 69 6e 73 20 74 68 65 20 69 6e 64 65 78  ntains the index
2740: 20 6f 66 20 74 68 65 20 73 6d 61 6c 6c 65 73 74   of the smallest
2750: 20 6f 66 20 65 61 63 68 20 62 6c 6f 63 6b 20 6f   of each block o
2760: 66 20 34 20 69 74 65 72 61 74 6f 72 73 2e 0a 2a  f 4 iterators..*
2770: 2a 20 41 6e 64 20 73 6f 20 6f 6e 2e 20 53 6f 20  * And so on. So 
2780: 74 68 61 74 20 61 54 72 65 65 5b 31 5d 20 63 6f  that aTree[1] co
2790: 6e 74 61 69 6e 73 20 74 68 65 20 69 6e 64 65 78  ntains the index
27a0: 20 6f 66 20 74 68 65 20 69 74 65 72 61 74 6f 72   of the iterator
27b0: 20 74 68 61 74 20 0a 2a 2a 20 63 75 72 72 65 6e   that .** curren
27c0: 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f 20 74 68  tly points to th
27d0: 65 20 73 6d 61 6c 6c 65 73 74 20 6b 65 79 20 76  e smallest key v
27e0: 61 6c 75 65 2e 20 61 54 72 65 65 5b 30 5d 20 69  alue. aTree[0] i
27f0: 73 20 75 6e 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20  s unused..**.** 
2800: 45 78 61 6d 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20  Example:.**.**  
2810: 20 20 20 61 49 74 65 72 5b 30 5d 20 2d 3e 20 42     aIter[0] -> B
2820: 61 6e 61 6e 61 0a 2a 2a 20 20 20 20 20 61 49 74  anana.**     aIt
2830: 65 72 5b 31 5d 20 2d 3e 20 46 65 69 6a 6f 61 0a  er[1] -> Feijoa.
2840: 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 32 5d 20  **     aIter[2] 
2850: 2d 3e 20 45 6c 64 65 72 62 65 72 72 79 0a 2a 2a  -> Elderberry.**
2860: 20 20 20 20 20 61 49 74 65 72 5b 33 5d 20 2d 3e       aIter[3] ->
2870: 20 43 75 72 72 61 6e 74 0a 2a 2a 20 20 20 20 20   Currant.**     
2880: 61 49 74 65 72 5b 34 5d 20 2d 3e 20 47 72 61 70  aIter[4] -> Grap
2890: 65 66 72 75 69 74 0a 2a 2a 20 20 20 20 20 61 49  efruit.**     aI
28a0: 74 65 72 5b 35 5d 20 2d 3e 20 41 70 70 6c 65 0a  ter[5] -> Apple.
28b0: 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 36 5d 20  **     aIter[6] 
28c0: 2d 3e 20 44 75 72 69 61 6e 0a 2a 2a 20 20 20 20  -> Durian.**    
28d0: 20 61 49 74 65 72 5b 37 5d 20 2d 3e 20 45 4f 46   aIter[7] -> EOF
28e0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 54 72 65 65  .**.**     aTree
28f0: 5b 5d 20 3d 20 7b 20 58 2c 20 35 20 20 20 30 2c  [] = { X, 5   0,
2900: 20 35 20 20 20 20 30 2c 20 33 2c 20 35 2c 20 36   5    0, 3, 5, 6
2910: 20 7d 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 75 72   }.**.** The cur
2920: 72 65 6e 74 20 65 6c 65 6d 65 6e 74 20 69 73 20  rent element is 
2930: 22 41 70 70 6c 65 22 20 28 74 68 65 20 76 61 6c  "Apple" (the val
2940: 75 65 20 6f 66 20 74 68 65 20 6b 65 79 20 69 6e  ue of the key in
2950: 64 69 63 61 74 65 64 20 62 79 20 0a 2a 2a 20 69  dicated by .** i
2960: 74 65 72 61 74 6f 72 20 35 29 2e 20 57 68 65 6e  terator 5). When
2970: 20 74 68 65 20 4e 65 78 74 28 29 20 6f 70 65 72   the Next() oper
2980: 61 74 69 6f 6e 20 69 73 20 69 6e 76 6f 6b 65 64  ation is invoked
2990: 2c 20 69 74 65 72 61 74 6f 72 20 35 20 77 69 6c  , iterator 5 wil
29a0: 6c 0a 2a 2a 20 62 65 20 61 64 76 61 6e 63 65 64  l.** be advanced
29b0: 20 74 6f 20 74 68 65 20 6e 65 78 74 20 6b 65 79   to the next key
29c0: 20 69 6e 20 69 74 73 20 73 65 67 6d 65 6e 74 2e   in its segment.
29d0: 20 53 61 79 20 74 68 65 20 6e 65 78 74 20 6b 65   Say the next ke
29e0: 79 20 69 73 0a 2a 2a 20 22 45 67 67 70 6c 61 6e  y is.** "Eggplan
29f0: 74 22 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 49  t":.**.**     aI
2a00: 74 65 72 5b 35 5d 20 2d 3e 20 45 67 67 70 6c 61  ter[5] -> Eggpla
2a10: 6e 74 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f 6e  nt.**.** The con
2a20: 74 65 6e 74 73 20 6f 66 20 61 54 72 65 65 5b 5d  tents of aTree[]
2a30: 20 61 72 65 20 75 70 64 61 74 65 64 20 66 69 72   are updated fir
2a40: 73 74 20 62 79 20 63 6f 6d 70 61 72 69 6e 67 20  st by comparing 
2a50: 74 68 65 20 6e 65 77 20 69 74 65 72 61 74 6f 72  the new iterator
2a60: 0a 2a 2a 20 35 20 6b 65 79 20 74 6f 20 74 68 65  .** 5 key to the
2a70: 20 63 75 72 72 65 6e 74 20 6b 65 79 20 6f 66 20   current key of 
2a80: 69 74 65 72 61 74 6f 72 20 34 20 28 73 74 69 6c  iterator 4 (stil
2a90: 6c 20 22 47 72 61 70 65 66 72 75 69 74 22 29 2e  l "Grapefruit").
2aa0: 20 54 68 65 20 69 74 65 72 61 74 6f 72 0a 2a 2a   The iterator.**
2ab0: 20 35 20 76 61 6c 75 65 20 69 73 20 73 74 69 6c   5 value is stil
2ac0: 6c 20 73 6d 61 6c 6c 65 72 2c 20 73 6f 20 61 54  l smaller, so aT
2ad0: 72 65 65 5b 36 5d 20 69 73 20 73 65 74 20 74 6f  ree[6] is set to
2ae0: 20 35 2e 20 41 6e 64 20 73 6f 20 6f 6e 20 75 70   5. And so on up
2af0: 20 74 68 65 20 74 72 65 65 2e 0a 2a 2a 20 54 68   the tree..** Th
2b00: 65 20 76 61 6c 75 65 20 6f 66 20 69 74 65 72 61  e value of itera
2b10: 74 6f 72 20 36 20 2d 20 22 44 75 72 69 61 6e 22  tor 6 - "Durian"
2b20: 20 2d 20 69 73 20 6e 6f 77 20 73 6d 61 6c 6c 65   - is now smalle
2b30: 72 20 74 68 61 6e 20 74 68 61 74 20 6f 66 20 69  r than that of i
2b40: 74 65 72 61 74 6f 72 0a 2a 2a 20 35 2c 20 73 6f  terator.** 5, so
2b50: 20 61 54 72 65 65 5b 33 5d 20 69 73 20 73 65 74   aTree[3] is set
2b60: 20 74 6f 20 36 2e 20 4b 65 79 20 30 20 69 73 20   to 6. Key 0 is 
2b70: 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 6b 65 79  smaller than key
2b80: 20 36 20 28 42 61 6e 61 6e 61 3c 44 75 72 69 61   6 (Banana<Duria
2b90: 6e 29 2c 0a 2a 2a 20 73 6f 20 74 68 65 20 76 61  n),.** so the va
2ba0: 6c 75 65 20 77 72 69 74 74 65 6e 20 69 6e 74 6f  lue written into
2bb0: 20 65 6c 65 6d 65 6e 74 20 31 20 6f 66 20 74 68   element 1 of th
2bc0: 65 20 61 72 72 61 79 20 69 73 20 30 2e 20 41 73  e array is 0. As
2bd0: 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20   follows:.**.** 
2be0: 20 20 20 20 61 54 72 65 65 5b 5d 20 3d 20 7b 20      aTree[] = { 
2bf0: 58 2c 20 30 20 20 20 30 2c 20 36 20 20 20 20 30  X, 0   0, 6    0
2c00: 2c 20 33 2c 20 35 2c 20 36 20 7d 0a 2a 2a 0a 2a  , 3, 5, 6 }.**.*
2c10: 2a 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64 73  * In other words
2c20: 2c 20 65 61 63 68 20 74 69 6d 65 20 77 65 20 61  , each time we a
2c30: 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20 6e 65  dvance to the ne
2c40: 78 74 20 73 6f 72 74 65 72 20 65 6c 65 6d 65 6e  xt sorter elemen
2c50: 74 2c 20 6c 6f 67 32 28 4e 29 0a 2a 2a 20 6b 65  t, log2(N).** ke
2c60: 79 20 63 6f 6d 70 61 72 69 73 6f 6e 20 6f 70 65  y comparison ope
2c70: 72 61 74 69 6f 6e 73 20 61 72 65 20 72 65 71 75  rations are requ
2c80: 69 72 65 64 2c 20 77 68 65 72 65 20 4e 20 69 73  ired, where N is
2c90: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 73   the number of s
2ca0: 65 67 6d 65 6e 74 73 0a 2a 2a 20 62 65 69 6e 67  egments.** being
2cb0: 20 6d 65 72 67 65 64 20 28 72 6f 75 6e 64 65 64   merged (rounded
2cc0: 20 75 70 20 74 6f 20 74 68 65 20 6e 65 78 74 20   up to the next 
2cd0: 70 6f 77 65 72 20 6f 66 20 32 29 2e 0a 2a 2f 0a  power of 2)..*/.
2ce0: 73 74 72 75 63 74 20 4d 65 72 67 65 45 6e 67 69  struct MergeEngi
2cf0: 6e 65 20 7b 0a 20 20 69 6e 74 20 6e 54 72 65 65  ne {.  int nTree
2d00: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
2d10: 20 20 2f 2a 20 55 73 65 64 20 73 69 7a 65 20 6f    /* Used size o
2d20: 66 20 61 54 72 65 65 2f 61 49 74 65 72 20 28 70  f aTree/aIter (p
2d30: 6f 77 65 72 20 6f 66 20 32 29 20 2a 2f 0a 20 20  ower of 2) */.  
2d40: 69 6e 74 20 2a 61 54 72 65 65 3b 20 20 20 20 20  int *aTree;     
2d50: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
2d60: 72 72 65 6e 74 20 73 74 61 74 65 20 6f 66 20 69  rrent state of i
2d70: 6e 63 72 65 6d 65 6e 74 61 6c 20 6d 65 72 67 65  ncremental merge
2d80: 20 2a 2f 0a 20 20 50 6d 61 52 65 61 64 65 72 20   */.  PmaReader 
2d90: 2a 61 49 74 65 72 3b 20 20 20 20 20 20 20 20 20  *aIter;         
2da0: 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 69 74 65   /* Array of ite
2db0: 72 61 74 6f 72 73 20 74 6f 20 6d 65 72 67 65 20  rators to merge 
2dc0: 64 61 74 61 20 66 72 6f 6d 20 2a 2f 0a 7d 3b 0a  data from */.};.
2dd0: 0a 2f 2a 0a 2a 2a 20 45 78 61 63 74 6c 79 20 56  ./*.** Exactly V
2de0: 64 62 65 53 6f 72 74 65 72 2e 6e 54 61 73 6b 20  dbeSorter.nTask 
2df0: 69 6e 73 74 61 6e 63 65 73 20 6f 66 20 74 68 69  instances of thi
2e00: 73 20 6f 62 6a 65 63 74 20 61 72 65 20 61 6c 6c  s object are all
2e10: 6f 63 61 74 65 64 0a 2a 2a 20 61 73 20 70 61 72  ocated.** as par
2e20: 74 20 6f 66 20 65 61 63 68 20 56 64 62 65 53 6f  t of each VdbeSo
2e30: 72 74 65 72 20 6f 62 6a 65 63 74 2e 20 49 6e 73  rter object. Ins
2e40: 74 61 6e 63 65 73 20 61 72 65 20 6e 65 76 65 72  tances are never
2e50: 20 61 6c 6c 6f 63 61 74 65 64 20 61 6e 79 0a 2a   allocated any.*
2e60: 2a 20 6f 74 68 65 72 20 77 61 79 2e 20 56 64 62  * other way. Vdb
2e70: 65 53 6f 72 74 65 72 2e 6e 54 61 73 6b 20 69 73  eSorter.nTask is
2e80: 20 73 65 74 20 74 6f 20 74 68 65 20 6e 75 6d 62   set to the numb
2e90: 65 72 20 6f 66 20 77 6f 72 6b 65 72 20 74 68 72  er of worker thr
2ea0: 65 61 64 73 20 61 6c 6c 6f 77 65 64 0a 2a 2a 20  eads allowed.** 
2eb0: 28 73 65 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46  (see SQLITE_CONF
2ec0: 49 47 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44  IG_WORKER_THREAD
2ed0: 53 29 20 70 6c 75 73 20 6f 6e 65 20 28 74 68 65  S) plus one (the
2ee0: 20 6d 61 69 6e 20 74 68 72 65 61 64 29 2e 0a 2a   main thread)..*
2ef0: 2a 0a 2a 2a 20 45 73 73 65 6e 74 69 61 6c 6c 79  *.** Essentially
2f00: 2c 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65  , this structure
2f10: 20 63 6f 6e 74 61 69 6e 73 20 61 6c 6c 20 74 68   contains all th
2f20: 6f 73 65 20 66 69 65 6c 64 73 20 6f 66 20 74 68  ose fields of th
2f30: 65 20 56 64 62 65 53 6f 72 74 65 72 0a 2a 2a 20  e VdbeSorter.** 
2f40: 73 74 72 75 63 74 75 72 65 20 66 6f 72 20 77 68  structure for wh
2f50: 69 63 68 20 65 61 63 68 20 74 68 72 65 61 64 20  ich each thread 
2f60: 72 65 71 75 69 72 65 73 20 61 20 73 65 70 61 72  requires a separ
2f70: 61 74 65 20 69 6e 73 74 61 6e 63 65 2e 20 46 6f  ate instance. Fo
2f80: 72 20 65 78 61 6d 70 6c 65 2c 0a 2a 2a 20 65 61  r example,.** ea
2f90: 63 68 20 74 68 72 65 61 64 20 72 65 71 75 72 69  ch thread requri
2fa0: 65 73 20 69 74 73 20 6f 77 6e 20 55 6e 70 61 63  es its own Unpac
2fb0: 6b 65 64 52 65 63 6f 72 64 20 6f 62 6a 65 63 74  kedRecord object
2fc0: 20 74 6f 20 75 6e 70 61 63 6b 20 72 65 63 6f 72   to unpack recor
2fd0: 64 73 20 69 6e 0a 2a 2a 20 61 73 20 70 61 72 74  ds in.** as part
2fe0: 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 6f   of comparison o
2ff0: 70 65 72 61 74 69 6f 6e 73 2e 0a 2a 2a 0a 2a 2a  perations..**.**
3000: 20 42 65 66 6f 72 65 20 61 20 62 61 63 6b 67 72   Before a backgr
3010: 6f 75 6e 64 20 74 68 72 65 61 64 20 69 73 20 6c  ound thread is l
3020: 61 75 6e 63 68 65 64 2c 20 76 61 72 69 61 62 6c  aunched, variabl
3030: 65 20 62 44 6f 6e 65 20 69 73 20 73 65 74 20 74  e bDone is set t
3040: 6f 20 30 2e 20 54 68 65 6e 2c 20 0a 2a 2a 20 72  o 0. Then, .** r
3050: 69 67 68 74 20 62 65 66 6f 72 65 20 69 74 20 65  ight before it e
3060: 78 69 74 73 2c 20 74 68 65 20 74 68 72 65 61 64  xits, the thread
3070: 20 69 74 73 65 6c 66 20 73 65 74 73 20 62 44 6f   itself sets bDo
3080: 6e 65 20 74 6f 20 31 2e 20 54 68 69 73 20 69 73  ne to 1. This is
3090: 20 75 73 65 64 20 66 6f 72 20 0a 2a 2a 20 74 77   used for .** tw
30a0: 6f 20 70 75 72 70 6f 73 65 73 3a 0a 2a 2a 0a 2a  o purposes:.**.*
30b0: 2a 20 20 20 31 2e 20 57 68 65 6e 20 66 6c 75 73  *   1. When flus
30c0: 68 69 6e 67 20 74 68 65 20 63 6f 6e 74 65 6e 74  hing the content
30d0: 73 20 6f 66 20 6d 65 6d 6f 72 79 20 74 6f 20 61  s of memory to a
30e0: 20 6c 65 76 65 6c 2d 30 20 50 4d 41 20 6f 6e 20   level-0 PMA on 
30f0: 64 69 73 6b 2c 20 74 6f 0a 2a 2a 20 20 20 20 20  disk, to.**     
3100: 20 61 74 74 65 6d 70 74 20 74 6f 20 73 65 6c 65   attempt to sele
3110: 63 74 20 61 20 53 6f 72 74 53 75 62 74 61 73 6b  ct a SortSubtask
3120: 20 66 6f 72 20 77 68 69 63 68 20 74 68 65 72 65   for which there
3130: 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20   is not already 
3140: 61 6e 0a 2a 2a 20 20 20 20 20 20 61 63 74 69 76  an.**      activ
3150: 65 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  e background thr
3160: 65 61 64 20 28 73 69 6e 63 65 20 64 6f 69 6e 67  ead (since doing
3170: 20 73 6f 20 63 61 75 73 65 73 20 74 68 65 20 6d   so causes the m
3180: 61 69 6e 20 74 68 72 65 61 64 0a 2a 2a 20 20 20  ain thread.**   
3190: 20 20 20 74 6f 20 62 6c 6f 63 6b 20 75 6e 74 69     to block unti
31a0: 6c 20 69 74 20 66 69 6e 69 73 68 65 73 29 2e 0a  l it finishes)..
31b0: 2a 2a 0a 2a 2a 20 20 20 32 2e 20 49 66 20 53 51  **.**   2. If SQ
31c0: 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f 52 54 45  LITE_DEBUG_SORTE
31d0: 52 5f 54 48 52 45 41 44 53 20 69 73 20 64 65 66  R_THREADS is def
31e0: 69 6e 65 64 2c 20 74 6f 20 64 65 74 65 72 6d 69  ined, to determi
31f0: 6e 65 20 69 66 20 61 20 63 61 6c 6c 0a 2a 2a 20  ne if a call.** 
3200: 20 20 20 20 20 74 6f 20 73 71 6c 69 74 65 33 54       to sqlite3T
3210: 68 72 65 61 64 4a 6f 69 6e 28 29 20 69 73 20 6c  hreadJoin() is l
3220: 69 6b 65 6c 79 20 74 6f 20 62 6c 6f 63 6b 2e 20  ikely to block. 
3230: 43 61 73 65 73 20 74 68 61 74 20 61 72 65 20 6c  Cases that are l
3240: 69 6b 65 6c 79 20 74 6f 0a 2a 2a 20 20 20 20 20  ikely to.**     
3250: 20 62 6c 6f 63 6b 20 70 72 6f 76 6f 6b 65 20 64   block provoke d
3260: 65 62 75 67 67 69 6e 67 20 6f 75 74 70 75 74 2e  ebugging output.
3270: 0a 2a 2a 0a 2a 2a 20 49 6e 20 62 6f 74 68 20 63  .**.** In both c
3280: 61 73 65 73 2c 20 74 68 65 20 65 66 66 65 63 74  ases, the effect
3290: 73 20 6f 66 20 74 68 65 20 6d 61 69 6e 20 74 68  s of the main th
32a0: 72 65 61 64 20 73 65 65 69 6e 67 20 28 62 44 6f  read seeing (bDo
32b0: 6e 65 3d 3d 30 29 20 65 76 65 6e 0a 2a 2a 20 61  ne==0) even.** a
32c0: 66 74 65 72 20 74 68 65 20 74 68 72 65 61 64 20  fter the thread 
32d0: 68 61 73 20 66 69 6e 69 73 68 65 64 20 61 72 65  has finished are
32e0: 20 6e 6f 74 20 64 69 72 65 2e 20 53 6f 20 77 65   not dire. So we
32f0: 20 64 6f 6e 27 74 20 77 6f 72 72 79 20 61 62 6f   don't worry abo
3300: 75 74 0a 2a 2a 20 6d 65 6d 6f 72 79 20 62 61 72  ut.** memory bar
3310: 72 69 65 72 73 20 61 6e 64 20 73 75 63 68 20 68  riers and such h
3320: 65 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 53  ere..*/.struct S
3330: 6f 72 74 53 75 62 74 61 73 6b 20 7b 0a 20 20 53  ortSubtask {.  S
3340: 51 4c 69 74 65 54 68 72 65 61 64 20 2a 70 54 68  QLiteThread *pTh
3350: 72 65 61 64 3b 20 20 20 20 20 20 20 20 20 20 2f  read;          /
3360: 2a 20 42 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  * Background thr
3370: 65 61 64 2c 20 69 66 20 61 6e 79 20 2a 2f 0a 20  ead, if any */. 
3380: 20 69 6e 74 20 62 44 6f 6e 65 3b 20 20 20 20 20   int bDone;     
3390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
33a0: 20 2f 2a 20 53 65 74 20 69 66 20 74 68 72 65 61   /* Set if threa
33b0: 64 20 69 73 20 66 69 6e 69 73 68 65 64 20 62 75  d is finished bu
33c0: 74 20 6e 6f 74 20 6a 6f 69 6e 65 64 20 2a 2f 0a  t not joined */.
33d0: 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
33e0: 6f 72 74 65 72 3b 20 20 20 20 20 20 20 20 20 20  orter;          
33f0: 20 20 2f 2a 20 53 6f 72 74 65 72 20 74 68 61 74    /* Sorter that
3400: 20 6f 77 6e 73 20 74 68 69 73 20 73 75 62 2d 74   owns this sub-t
3410: 61 73 6b 20 2a 2f 0a 20 20 55 6e 70 61 63 6b 65  ask */.  Unpacke
3420: 64 52 65 63 6f 72 64 20 2a 70 55 6e 70 61 63 6b  dRecord *pUnpack
3430: 65 64 3b 20 20 20 20 20 20 2f 2a 20 53 70 61 63  ed;      /* Spac
3440: 65 20 74 6f 20 75 6e 70 61 63 6b 20 61 20 72 65  e to unpack a re
3450: 63 6f 72 64 20 2a 2f 0a 20 20 53 6f 72 74 65 72  cord */.  Sorter
3460: 4c 69 73 74 20 6c 69 73 74 3b 20 20 20 20 20 20  List list;      
3470: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 73            /* Lis
3480: 74 20 66 6f 72 20 74 68 72 65 61 64 20 74 6f 20  t for thread to 
3490: 77 72 69 74 65 20 74 6f 20 61 20 50 4d 41 20 2a  write to a PMA *
34a0: 2f 0a 20 20 69 6e 74 20 6e 50 4d 41 3b 20 20 20  /.  int nPMA;   
34b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
34c0: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
34d0: 20 50 4d 41 73 20 63 75 72 72 65 6e 74 6c 79 20   PMAs currently 
34e0: 69 6e 20 66 69 6c 65 20 2a 2f 0a 20 20 53 6f 72  in file */.  Sor
34f0: 74 65 72 46 69 6c 65 20 66 69 6c 65 3b 20 20 20  terFile file;   
3500: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3510: 54 65 6d 70 20 66 69 6c 65 20 66 6f 72 20 6c 65  Temp file for le
3520: 76 65 6c 2d 30 20 50 4d 41 73 20 2a 2f 0a 20 20  vel-0 PMAs */.  
3530: 53 6f 72 74 65 72 46 69 6c 65 20 66 69 6c 65 32  SorterFile file2
3540: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
3550: 2f 2a 20 53 70 61 63 65 20 66 6f 72 20 6f 74 68  /* Space for oth
3560: 65 72 20 50 4d 41 73 20 2a 2f 0a 7d 3b 0a 0a 2f  er PMAs */.};../
3570: 2a 0a 2a 2a 20 4d 61 69 6e 20 73 6f 72 74 65 72  *.** Main sorter
3580: 20 73 74 72 75 63 74 75 72 65 2e 20 41 20 73 69   structure. A si
3590: 6e 67 6c 65 20 69 6e 73 74 61 6e 63 65 20 6f 66  ngle instance of
35a0: 20 74 68 69 73 20 69 73 20 61 6c 6c 6f 63 61 74   this is allocat
35b0: 65 64 20 66 6f 72 20 65 61 63 68 20 0a 2a 2a 20  ed for each .** 
35c0: 73 6f 72 74 65 72 20 63 75 72 73 6f 72 20 63 72  sorter cursor cr
35d0: 65 61 74 65 64 20 62 79 20 74 68 65 20 56 44 42  eated by the VDB
35e0: 45 2e 0a 2a 2a 0a 2a 2a 20 6d 78 4b 65 79 73 69  E..**.** mxKeysi
35f0: 7a 65 3a 0a 2a 2a 20 20 20 41 73 20 72 65 63 6f  ze:.**   As reco
3600: 72 64 73 20 61 72 65 20 61 64 64 65 64 20 74 6f  rds are added to
3610: 20 74 68 65 20 73 6f 72 74 65 72 20 62 79 20 63   the sorter by c
3620: 61 6c 6c 73 20 74 6f 20 73 71 6c 69 74 65 33 56  alls to sqlite3V
3630: 64 62 65 53 6f 72 74 65 72 57 72 69 74 65 28 29  dbeSorterWrite()
3640: 2c 0a 2a 2a 20 20 20 74 68 69 73 20 76 61 72 69  ,.**   this vari
3650: 61 62 6c 65 20 69 73 20 75 70 64 61 74 65 64 20  able is updated 
3660: 73 6f 20 61 73 20 74 6f 20 62 65 20 73 65 74 20  so as to be set 
3670: 74 6f 20 74 68 65 20 73 69 7a 65 20 6f 6e 20 64  to the size on d
3680: 69 73 6b 20 6f 66 20 74 68 65 0a 2a 2a 20 20 20  isk of the.**   
3690: 6c 61 72 67 65 73 74 20 72 65 63 6f 72 64 20 69  largest record i
36a0: 6e 20 74 68 65 20 73 6f 72 74 65 72 2e 0a 2a 2f  n the sorter..*/
36b0: 0a 73 74 72 75 63 74 20 56 64 62 65 53 6f 72 74  .struct VdbeSort
36c0: 65 72 20 7b 0a 20 20 69 6e 74 20 6d 6e 50 6d 61  er {.  int mnPma
36d0: 53 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20  Size;           
36e0: 20 20 20 20 20 20 20 2f 2a 20 4d 69 6e 69 6d 75         /* Minimu
36f0: 6d 20 50 4d 41 20 73 69 7a 65 2c 20 69 6e 20 62  m PMA size, in b
3700: 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6d 78  ytes */.  int mx
3710: 50 6d 61 53 69 7a 65 3b 20 20 20 20 20 20 20 20  PmaSize;        
3720: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 78            /* Max
3730: 69 6d 75 6d 20 50 4d 41 20 73 69 7a 65 2c 20 69  imum PMA size, i
3740: 6e 20 62 79 74 65 73 2e 20 20 30 3d 3d 6e 6f 20  n bytes.  0==no 
3750: 6c 69 6d 69 74 20 2a 2f 0a 20 20 69 6e 74 20 6d  limit */.  int m
3760: 78 4b 65 79 73 69 7a 65 3b 20 20 20 20 20 20 20  xKeysize;       
3770: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61             /* La
3780: 72 67 65 73 74 20 73 65 72 69 61 6c 69 7a 65 64  rgest serialized
3790: 20 6b 65 79 20 73 65 65 6e 20 73 6f 20 66 61 72   key seen so far
37a0: 20 2a 2f 0a 20 20 69 6e 74 20 70 67 73 7a 3b 20   */.  int pgsz; 
37b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
37c0: 20 20 20 20 20 20 2f 2a 20 4d 61 69 6e 20 64 61        /* Main da
37d0: 74 61 62 61 73 65 20 70 61 67 65 20 73 69 7a 65  tabase page size
37e0: 20 2a 2f 0a 20 20 50 6d 61 52 65 61 64 65 72 20   */.  PmaReader 
37f0: 2a 70 52 65 61 64 65 72 3b 20 20 20 20 20 20 20  *pReader;       
3800: 20 20 20 20 20 20 2f 2a 20 52 65 61 64 20 64 61        /* Read da
3810: 74 61 20 66 72 6f 6d 20 68 65 72 65 20 61 66 74  ta from here aft
3820: 65 72 20 52 65 77 69 6e 64 28 29 20 2a 2f 0a 20  er Rewind() */. 
3830: 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d   MergeEngine *pM
3840: 65 72 67 65 72 3b 20 20 20 20 20 20 20 20 20 20  erger;          
3850: 20 2f 2a 20 4f 72 20 68 65 72 65 2c 20 69 66 20   /* Or here, if 
3860: 62 55 73 65 54 68 72 65 61 64 73 3d 3d 30 20 2a  bUseThreads==0 *
3870: 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b  /.  sqlite3 *db;
3880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3890: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
38a0: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20  connection */.  
38b0: 4b 65 79 49 6e 66 6f 20 2a 70 4b 65 79 49 6e 66  KeyInfo *pKeyInf
38c0: 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  o;              
38d0: 2f 2a 20 48 6f 77 20 74 6f 20 63 6f 6d 70 61 72  /* How to compar
38e0: 65 20 72 65 63 6f 72 64 73 20 2a 2f 0a 20 20 55  e records */.  U
38f0: 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20 2a 70  npackedRecord *p
3900: 55 6e 70 61 63 6b 65 64 3b 20 20 20 20 20 20 2f  Unpacked;      /
3910: 2a 20 55 73 65 64 20 62 79 20 56 64 62 65 53 6f  * Used by VdbeSo
3920: 72 74 65 72 43 6f 6d 70 61 72 65 28 29 20 2a 2f  rterCompare() */
3930: 0a 20 20 53 6f 72 74 65 72 4c 69 73 74 20 6c 69  .  SorterList li
3940: 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  st;             
3950: 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20 69 6e     /* List of in
3960: 2d 6d 65 6d 6f 72 79 20 72 65 63 6f 72 64 73 20  -memory records 
3970: 2a 2f 0a 20 20 69 6e 74 20 69 4d 65 6d 6f 72 79  */.  int iMemory
3980: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
3990: 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 6f       /* Offset o
39a0: 66 20 66 72 65 65 20 73 70 61 63 65 20 69 6e 20  f free space in 
39b0: 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 2a 2f 0a  list.aMemory */.
39c0: 20 20 69 6e 74 20 6e 4d 65 6d 6f 72 79 3b 20 20    int nMemory;  
39d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
39e0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 6c 69 73    /* Size of lis
39f0: 74 2e 61 4d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61  t.aMemory alloca
3a00: 74 69 6f 6e 20 69 6e 20 62 79 74 65 73 20 2a 2f  tion in bytes */
3a10: 0a 20 20 75 38 20 62 55 73 65 50 4d 41 3b 20 20  .  u8 bUsePMA;  
3a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a30: 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 6f 6e     /* True if on
3a40: 65 20 6f 72 20 6d 6f 72 65 20 50 4d 41 73 20 63  e or more PMAs c
3a50: 72 65 61 74 65 64 20 2a 2f 0a 20 20 75 38 20 62  reated */.  u8 b
3a60: 55 73 65 54 68 72 65 61 64 73 3b 20 20 20 20 20  UseThreads;     
3a70: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
3a80: 72 75 65 20 74 6f 20 75 73 65 20 62 61 63 6b 67  rue to use backg
3a90: 72 6f 75 6e 64 20 74 68 72 65 61 64 73 20 2a 2f  round threads */
3aa0: 0a 20 20 75 38 20 69 50 72 65 76 3b 20 20 20 20  .  u8 iPrev;    
3ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3ac0: 20 20 20 2f 2a 20 50 72 65 76 69 6f 75 73 20 74     /* Previous t
3ad0: 68 72 65 61 64 20 75 73 65 64 20 74 6f 20 66 6c  hread used to fl
3ae0: 75 73 68 20 50 4d 41 20 2a 2f 0a 20 20 75 38 20  ush PMA */.  u8 
3af0: 6e 54 61 73 6b 3b 20 20 20 20 20 20 20 20 20 20  nTask;          
3b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3b10: 53 69 7a 65 20 6f 66 20 61 54 61 73 6b 5b 5d 20  Size of aTask[] 
3b20: 61 72 72 61 79 20 2a 2f 0a 20 20 53 6f 72 74 53  array */.  SortS
3b30: 75 62 74 61 73 6b 20 61 54 61 73 6b 5b 31 5d 3b  ubtask aTask[1];
3b40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e             /* On
3b50: 65 20 6f 72 20 6d 6f 72 65 20 73 75 62 74 61 73  e or more subtas
3b60: 6b 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  ks */.};../*.** 
3b70: 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74  An instance of t
3b80: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a  he following obj
3b90: 65 63 74 20 69 73 20 75 73 65 64 20 74 6f 20 72  ect is used to r
3ba0: 65 61 64 20 72 65 63 6f 72 64 73 20 6f 75 74 20  ead records out 
3bb0: 6f 66 20 61 0a 2a 2a 20 50 4d 41 2c 20 69 6e 20  of a.** PMA, in 
3bc0: 73 6f 72 74 65 64 20 6f 72 64 65 72 2e 20 20 54  sorted order.  T
3bd0: 68 65 20 6e 65 78 74 20 6b 65 79 20 74 6f 20 62  he next key to b
3be0: 65 20 72 65 61 64 20 69 73 20 63 61 63 68 65 64  e read is cached
3bf0: 20 69 6e 20 6e 4b 65 79 2f 61 4b 65 79 2e 0a 2a   in nKey/aKey..*
3c00: 2a 20 70 46 69 6c 65 3d 3d 30 20 61 74 20 45 4f  * pFile==0 at EO
3c10: 46 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 6d 61  F..*/.struct Pma
3c20: 52 65 61 64 65 72 20 7b 0a 20 20 69 36 34 20 69  Reader {.  i64 i
3c30: 52 65 61 64 4f 66 66 3b 20 20 20 20 20 20 20 20  ReadOff;        
3c40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
3c50: 72 72 65 6e 74 20 72 65 61 64 20 6f 66 66 73 65  rrent read offse
3c60: 74 20 2a 2f 0a 20 20 69 36 34 20 69 45 6f 66 3b  t */.  i64 iEof;
3c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3c80: 20 20 20 20 20 20 20 2f 2a 20 31 20 62 79 74 65         /* 1 byte
3c90: 20 70 61 73 74 20 45 4f 46 20 66 6f 72 20 74 68   past EOF for th
3ca0: 69 73 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20  is iterator */. 
3cb0: 20 69 6e 74 20 6e 41 6c 6c 6f 63 3b 20 20 20 20   int nAlloc;    
3cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3cd0: 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 73 70 61   /* Bytes of spa
3ce0: 63 65 20 61 74 20 61 41 6c 6c 6f 63 20 2a 2f 0a  ce at aAlloc */.
3cf0: 20 20 69 6e 74 20 6e 4b 65 79 3b 20 20 20 20 20    int nKey;     
3d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3d10: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62    /* Number of b
3d20: 79 74 65 73 20 69 6e 20 6b 65 79 20 2a 2f 0a 20  ytes in key */. 
3d30: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
3d40: 46 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20  File;           
3d50: 20 2f 2a 20 46 69 6c 65 20 69 74 65 72 61 74 6f   /* File iterato
3d60: 72 20 69 73 20 72 65 61 64 69 6e 67 20 66 72 6f  r is reading fro
3d70: 6d 20 2a 2f 0a 20 20 75 38 20 2a 61 41 6c 6c 6f  m */.  u8 *aAllo
3d80: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
3d90: 20 20 20 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61         /* Alloca
3da0: 74 65 64 20 73 70 61 63 65 20 2a 2f 0a 20 20 75  ted space */.  u
3db0: 38 20 2a 61 4b 65 79 3b 20 20 20 20 20 20 20 20  8 *aKey;        
3dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3dd0: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 63 75 72  * Pointer to cur
3de0: 72 65 6e 74 20 6b 65 79 20 2a 2f 0a 20 20 75 38  rent key */.  u8
3df0: 20 2a 61 42 75 66 66 65 72 3b 20 20 20 20 20 20   *aBuffer;      
3e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3e10: 20 43 75 72 72 65 6e 74 20 72 65 61 64 20 62 75   Current read bu
3e20: 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  ffer */.  int nB
3e30: 75 66 66 65 72 3b 20 20 20 20 20 20 20 20 20 20  uffer;          
3e40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
3e50: 65 20 6f 66 20 72 65 61 64 20 62 75 66 66 65 72  e of read buffer
3e60: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 75   in bytes */.  u
3e70: 38 20 2a 61 4d 61 70 3b 20 20 20 20 20 20 20 20  8 *aMap;        
3e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3e90: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 6d 61 70  * Pointer to map
3ea0: 70 69 6e 67 20 6f 66 20 65 6e 74 69 72 65 20 66  ping of entire f
3eb0: 69 6c 65 20 2a 2f 0a 20 20 49 6e 63 72 4d 65 72  ile */.  IncrMer
3ec0: 67 65 72 20 2a 70 49 6e 63 72 3b 20 20 20 20 20  ger *pIncr;     
3ed0: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 63 72           /* Incr
3ee0: 65 6d 65 6e 74 61 6c 20 6d 65 72 67 65 72 20 2a  emental merger *
3ef0: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 4e 6f 72 6d  /.};../*.** Norm
3f00: 61 6c 6c 79 2c 20 61 20 50 6d 61 52 65 61 64 65  ally, a PmaReade
3f10: 72 20 6f 62 6a 65 63 74 20 69 74 65 72 61 74 65  r object iterate
3f20: 73 20 74 68 72 6f 75 67 68 20 61 6e 20 65 78 69  s through an exi
3f30: 73 74 69 6e 67 20 50 4d 41 20 73 74 6f 72 65 64  sting PMA stored
3f40: 20 0a 2a 2a 20 77 69 74 68 69 6e 20 61 20 74 65   .** within a te
3f50: 6d 70 20 66 69 6c 65 2e 20 48 6f 77 65 76 65 72  mp file. However
3f60: 2c 20 69 66 20 74 68 65 20 50 6d 61 52 65 61 64  , if the PmaRead
3f70: 65 72 2e 70 49 6e 63 72 20 76 61 72 69 61 62 6c  er.pIncr variabl
3f80: 65 20 70 6f 69 6e 74 73 20 74 6f 0a 2a 2a 20 61  e points to.** a
3f90: 6e 20 6f 62 6a 65 63 74 20 6f 66 20 74 68 65 20  n object of the 
3fa0: 66 6f 6c 6c 6f 77 69 6e 67 20 74 79 70 65 2c 20  following type, 
3fb0: 69 74 20 6d 61 79 20 62 65 20 75 73 65 64 20 74  it may be used t
3fc0: 6f 20 69 74 65 72 61 74 65 2f 6d 65 72 67 65 20  o iterate/merge 
3fd0: 74 68 72 6f 75 67 68 0a 2a 2a 20 6d 75 6c 74 69  through.** multi
3fe0: 70 6c 65 20 50 4d 41 73 20 73 69 6d 75 6c 74 61  ple PMAs simulta
3ff0: 6e 65 6f 75 73 6c 79 2e 0a 2a 2a 0a 2a 2a 20 54  neously..**.** T
4000: 68 65 72 65 20 61 72 65 20 74 77 6f 20 74 79 70  here are two typ
4010: 65 73 20 6f 66 20 49 6e 63 72 4d 65 72 67 65 72  es of IncrMerger
4020: 20 6f 62 6a 65 63 74 20 2d 20 73 69 6e 67 6c 65   object - single
4030: 20 28 62 55 73 65 54 68 72 65 61 64 3d 3d 30 29   (bUseThread==0)
4040: 20 61 6e 64 20 0a 2a 2a 20 6d 75 6c 74 69 2d 74   and .** multi-t
4050: 68 72 65 61 64 65 64 20 28 62 55 73 65 54 68 72  hreaded (bUseThr
4060: 65 61 64 3d 3d 31 29 2e 20 0a 2a 2a 0a 2a 2a 20  ead==1). .**.** 
4070: 41 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64  A multi-threaded
4080: 20 49 6e 63 72 4d 65 72 67 65 72 20 6f 62 6a 65   IncrMerger obje
4090: 63 74 20 75 73 65 73 20 74 77 6f 20 74 65 6d 70  ct uses two temp
40a0: 6f 72 61 72 79 20 66 69 6c 65 73 20 2d 20 61 46  orary files - aF
40b0: 69 6c 65 5b 30 5d 20 0a 2a 2a 20 61 6e 64 20 61  ile[0] .** and a
40c0: 46 69 6c 65 5b 31 5d 2e 20 4e 65 69 74 68 65 72  File[1]. Neither
40d0: 20 66 69 6c 65 20 69 73 20 61 6c 6c 6f 77 65 64   file is allowed
40e0: 20 74 6f 20 67 72 6f 77 20 74 6f 20 6d 6f 72 65   to grow to more
40f0: 20 74 68 61 6e 20 6d 78 53 7a 20 62 79 74 65 73   than mxSz bytes
4100: 20 69 6e 20 0a 2a 2a 20 73 69 7a 65 2e 20 57 68   in .** size. Wh
4110: 65 6e 20 74 68 65 20 49 6e 63 72 4d 65 72 67 65  en the IncrMerge
4120: 72 20 69 73 20 69 6e 69 74 69 61 6c 69 7a 65 64  r is initialized
4130: 2c 20 69 74 20 72 65 61 64 73 20 65 6e 6f 75 67  , it reads enoug
4140: 68 20 64 61 74 61 20 66 72 6f 6d 20 0a 2a 2a 20  h data from .** 
4150: 70 4d 65 72 67 65 72 20 74 6f 20 70 6f 70 75 6c  pMerger to popul
4160: 61 74 65 20 61 46 69 6c 65 5b 30 5d 2e 20 49 74  ate aFile[0]. It
4170: 20 74 68 65 6e 20 73 65 74 73 20 76 61 72 69 61   then sets varia
4180: 62 6c 65 73 20 77 69 74 68 69 6e 20 74 68 65 20  bles within the 
4190: 0a 2a 2a 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e  .** correspondin
41a0: 67 20 50 6d 61 52 65 61 64 65 72 20 6f 62 6a 65  g PmaReader obje
41b0: 63 74 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20  ct to read from 
41c0: 74 68 61 74 20 66 69 6c 65 20 61 6e 64 20 6b 69  that file and ki
41d0: 63 6b 73 20 6f 66 66 20 0a 2a 2a 20 61 20 62 61  cks off .** a ba
41e0: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
41f0: 74 6f 20 70 6f 70 75 6c 61 74 65 20 61 46 69 6c  to populate aFil
4200: 65 5b 31 5d 20 77 69 74 68 20 74 68 65 20 6e 65  e[1] with the ne
4210: 78 74 20 6d 78 53 7a 20 62 79 74 65 73 20 6f 66  xt mxSz bytes of
4220: 20 0a 2a 2a 20 73 6f 72 74 65 64 20 72 65 63 6f   .** sorted reco
4230: 72 64 20 64 61 74 61 20 66 72 6f 6d 20 70 4d 65  rd data from pMe
4240: 72 67 65 72 2e 20 0a 2a 2a 0a 2a 2a 20 57 68 65  rger. .**.** Whe
4250: 6e 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 20  n the PmaReader 
4260: 72 65 61 63 68 65 73 20 74 68 65 20 65 6e 64 20  reaches the end 
4270: 6f 66 20 61 46 69 6c 65 5b 30 5d 2c 20 69 74 20  of aFile[0], it 
4280: 62 6c 6f 63 6b 73 20 75 6e 74 69 6c 20 74 68 65  blocks until the
4290: 0a 2a 2a 20 62 61 63 6b 67 72 6f 75 6e 64 20 74  .** background t
42a0: 68 72 65 61 64 20 68 61 73 20 66 69 6e 69 73 68  hread has finish
42b0: 65 64 20 70 6f 70 75 6c 61 74 69 6e 67 20 61 46  ed populating aF
42c0: 69 6c 65 5b 31 5d 2e 20 49 74 20 74 68 65 6e 20  ile[1]. It then 
42d0: 65 78 63 68 61 6e 67 65 73 0a 2a 2a 20 74 68 65  exchanges.** the
42e0: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
42f0: 20 61 46 69 6c 65 5b 30 5d 20 61 6e 64 20 61 46   aFile[0] and aF
4300: 69 6c 65 5b 31 5d 20 76 61 72 69 61 62 6c 65 73  ile[1] variables
4310: 20 77 69 74 68 69 6e 20 74 68 69 73 20 73 74 72   within this str
4320: 75 63 74 75 72 65 2c 0a 2a 2a 20 73 65 74 73 20  ucture,.** sets 
4330: 74 68 65 20 50 6d 61 52 65 61 64 65 72 20 66 69  the PmaReader fi
4340: 65 6c 64 73 20 74 6f 20 72 65 61 64 20 66 72 6f  elds to read fro
4350: 6d 20 74 68 65 20 6e 65 77 20 61 46 69 6c 65 5b  m the new aFile[
4360: 30 5d 20 61 6e 64 20 6b 69 63 6b 73 20 6f 66 66  0] and kicks off
4370: 0a 2a 2a 20 61 6e 6f 74 68 65 72 20 62 61 63 6b  .** another back
4380: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 74 6f  ground thread to
4390: 20 70 6f 70 75 6c 61 74 65 20 74 68 65 20 6e 65   populate the ne
43a0: 77 20 61 46 69 6c 65 5b 31 5d 2e 20 41 6e 64 20  w aFile[1]. And 
43b0: 73 6f 20 6f 6e 2c 20 75 6e 74 69 6c 0a 2a 2a 20  so on, until.** 
43c0: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
43d0: 70 4d 65 72 67 65 72 20 61 72 65 20 65 78 68 61  pMerger are exha
43e0: 75 73 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 41 20 73  usted..**.** A s
43f0: 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64 20 49  ingle-threaded I
4400: 6e 63 72 4d 65 72 67 65 72 20 64 6f 65 73 20 6e  ncrMerger does n
4410: 6f 74 20 6f 70 65 6e 20 61 6e 79 20 74 65 6d 70  ot open any temp
4420: 6f 72 61 72 79 20 66 69 6c 65 73 20 6f 66 20 69  orary files of i
4430: 74 73 0a 2a 2a 20 6f 77 6e 2e 20 49 6e 73 74 65  ts.** own. Inste
4440: 61 64 2c 20 69 74 20 68 61 73 20 65 78 63 6c 75  ad, it has exclu
4450: 73 69 76 65 20 61 63 63 65 73 73 20 74 6f 20 6d  sive access to m
4460: 78 53 7a 20 62 79 74 65 73 20 6f 66 20 73 70 61  xSz bytes of spa
4470: 63 65 20 62 65 67 69 6e 6e 69 6e 67 0a 2a 2a 20  ce beginning.** 
4480: 61 74 20 6f 66 66 73 65 74 20 69 53 74 61 72 74  at offset iStart
4490: 4f 66 66 20 6f 66 20 66 69 6c 65 20 70 54 61 73  Off of file pTas
44a0: 6b 2d 3e 66 69 6c 65 32 2e 20 41 6e 64 20 69 6e  k->file2. And in
44b0: 73 74 65 61 64 20 6f 66 20 75 73 69 6e 67 20 61  stead of using a
44c0: 20 0a 2a 2a 20 62 61 63 6b 67 72 6f 75 6e 64 20   .** background 
44d0: 74 68 72 65 61 64 20 74 6f 20 70 72 65 70 61 72  thread to prepar
44e0: 65 20 64 61 74 61 20 66 6f 72 20 74 68 65 20 50  e data for the P
44f0: 6d 61 52 65 61 64 65 72 2c 20 77 69 74 68 20 61  maReader, with a
4500: 20 73 69 6e 67 6c 65 0a 2a 2a 20 74 68 72 65 61   single.** threa
4510: 64 65 64 20 49 6e 63 72 4d 65 72 67 65 72 20 74  ded IncrMerger t
4520: 68 65 20 61 6c 6c 6f 63 61 74 65 20 70 61 72 74  he allocate part
4530: 20 6f 66 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32   of pTask->file2
4540: 20 69 73 20 22 72 65 66 69 6c 6c 65 64 22 20 77   is "refilled" w
4550: 69 74 68 0a 2a 2a 20 6b 65 79 73 20 66 72 6f 6d  ith.** keys from
4560: 20 70 4d 65 72 67 65 72 20 62 79 20 74 68 65 20   pMerger by the 
4570: 63 61 6c 6c 69 6e 67 20 74 68 72 65 61 64 20 77  calling thread w
4580: 68 65 6e 65 76 65 72 20 74 68 65 20 50 6d 61 52  henever the PmaR
4590: 65 61 64 65 72 20 72 75 6e 73 20 6f 75 74 0a 2a  eader runs out.*
45a0: 2a 20 6f 66 20 64 61 74 61 2e 0a 2a 2f 0a 73 74  * of data..*/.st
45b0: 72 75 63 74 20 49 6e 63 72 4d 65 72 67 65 72 20  ruct IncrMerger 
45c0: 7b 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20  {.  SortSubtask 
45d0: 2a 70 54 61 73 6b 3b 20 20 20 20 20 20 20 20 20  *pTask;         
45e0: 20 20 20 20 2f 2a 20 54 61 73 6b 20 74 68 61 74      /* Task that
45f0: 20 6f 77 6e 73 20 74 68 69 73 20 6d 65 72 67 65   owns this merge
4600: 72 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69  r */.  MergeEngi
4610: 6e 65 20 2a 70 4d 65 72 67 65 72 3b 20 20 20 20  ne *pMerger;    
4620: 20 20 20 20 20 20 20 2f 2a 20 4d 65 72 67 65 20         /* Merge 
4630: 65 6e 67 69 6e 65 20 74 68 72 65 61 64 20 72 65  engine thread re
4640: 61 64 73 20 64 61 74 61 20 66 72 6f 6d 20 2a 2f  ads data from */
4650: 0a 20 20 69 36 34 20 69 53 74 61 72 74 4f 66 66  .  i64 iStartOff
4660: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4670: 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 74 6f 20     /* Offset to 
4680: 73 74 61 72 74 20 77 72 69 74 69 6e 67 20 66 69  start writing fi
4690: 6c 65 20 61 74 20 2a 2f 0a 20 20 69 6e 74 20 6d  le at */.  int m
46a0: 78 53 7a 3b 20 20 20 20 20 20 20 20 20 20 20 20  xSz;            
46b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61             /* Ma
46c0: 78 69 6d 75 6d 20 62 79 74 65 73 20 6f 66 20 64  ximum bytes of d
46d0: 61 74 61 20 74 6f 20 73 74 6f 72 65 20 2a 2f 0a  ata to store */.
46e0: 20 20 69 6e 74 20 62 45 6f 66 3b 20 20 20 20 20    int bEof;     
46f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4700: 20 20 2f 2a 20 53 65 74 20 74 6f 20 74 72 75 65    /* Set to true
4710: 20 77 68 65 6e 20 6d 65 72 67 65 20 69 73 20 66   when merge is f
4720: 69 6e 69 73 68 65 64 20 2a 2f 0a 20 20 69 6e 74  inished */.  int
4730: 20 62 55 73 65 54 68 72 65 61 64 3b 20 20 20 20   bUseThread;    
4740: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4750: 54 72 75 65 20 74 6f 20 75 73 65 20 61 20 62 67  True to use a bg
4760: 20 74 68 72 65 61 64 20 66 6f 72 20 74 68 69 73   thread for this
4770: 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 53 6f 72   object */.  Sor
4780: 74 65 72 46 69 6c 65 20 61 46 69 6c 65 5b 32 5d  terFile aFile[2]
4790: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
47a0: 61 46 69 6c 65 5b 30 5d 20 66 6f 72 20 72 65 61  aFile[0] for rea
47b0: 64 69 6e 67 2c 20 5b 31 5d 20 66 6f 72 20 77 72  ding, [1] for wr
47c0: 69 74 69 6e 67 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  iting */.};../*.
47d0: 2a 2a 20 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f  ** An instance o
47e0: 66 20 74 68 69 73 20 6f 62 6a 65 63 74 20 69 73  f this object is
47f0: 20 75 73 65 64 20 66 6f 72 20 77 72 69 74 69 6e   used for writin
4800: 67 20 61 20 50 4d 41 2e 0a 2a 2a 0a 2a 2a 20 54  g a PMA..**.** T
4810: 68 65 20 50 4d 41 20 69 73 20 77 72 69 74 74 65  he PMA is writte
4820: 6e 20 6f 6e 65 20 72 65 63 6f 72 64 20 61 74 20  n one record at 
4830: 61 20 74 69 6d 65 2e 20 20 45 61 63 68 20 72 65  a time.  Each re
4840: 63 6f 72 64 20 69 73 20 6f 66 20 61 6e 20 61 72  cord is of an ar
4850: 62 69 74 72 61 72 79 0a 2a 2a 20 73 69 7a 65 2e  bitrary.** size.
4860: 20 20 42 75 74 20 49 2f 4f 20 69 73 20 6d 6f 72    But I/O is mor
4870: 65 20 65 66 66 69 63 69 65 6e 74 20 69 66 20 69  e efficient if i
4880: 74 20 6f 63 63 75 72 73 20 69 6e 20 70 61 67 65  t occurs in page
4890: 2d 73 69 7a 65 64 20 62 6c 6f 63 6b 73 20 77 68  -sized blocks wh
48a0: 65 72 65 0a 2a 2a 20 65 61 63 68 20 62 6c 6f 63  ere.** each bloc
48b0: 6b 20 69 73 20 61 6c 69 67 6e 65 64 20 6f 6e 20  k is aligned on 
48c0: 61 20 70 61 67 65 20 62 6f 75 6e 64 61 72 79 2e  a page boundary.
48d0: 20 20 54 68 69 73 20 6f 62 6a 65 63 74 20 63 61    This object ca
48e0: 63 68 65 73 20 77 72 69 74 65 73 20 74 6f 0a 2a  ches writes to.*
48f0: 2a 20 74 68 65 20 50 4d 41 20 73 6f 20 74 68 61  * the PMA so tha
4900: 74 20 61 6c 69 67 6e 65 64 2c 20 70 61 67 65 2d  t aligned, page-
4910: 73 69 7a 65 20 62 6c 6f 63 6b 73 20 61 72 65 20  size blocks are 
4920: 77 72 69 74 74 65 6e 2e 0a 2a 2f 0a 73 74 72 75  written..*/.stru
4930: 63 74 20 50 6d 61 57 72 69 74 65 72 20 7b 0a 20  ct PmaWriter {. 
4940: 20 69 6e 74 20 65 46 57 45 72 72 3b 20 20 20 20   int eFWErr;    
4950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4960: 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20 69 66 20   /* Non-zero if 
4970: 69 6e 20 61 6e 20 65 72 72 6f 72 20 73 74 61 74  in an error stat
4980: 65 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75 66 66  e */.  u8 *aBuff
4990: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  er;             
49a0: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
49b0: 72 20 74 6f 20 77 72 69 74 65 20 62 75 66 66 65  r to write buffe
49c0: 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66 66  r */.  int nBuff
49d0: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  er;             
49e0: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
49f0: 66 20 77 72 69 74 65 20 62 75 66 66 65 72 20 69  f write buffer i
4a00: 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74  n bytes */.  int
4a10: 20 69 42 75 66 53 74 61 72 74 3b 20 20 20 20 20   iBufStart;     
4a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4a30: 46 69 72 73 74 20 62 79 74 65 20 6f 66 20 62 75  First byte of bu
4a40: 66 66 65 72 20 74 6f 20 77 72 69 74 65 20 2a 2f  ffer to write */
4a50: 0a 20 20 69 6e 74 20 69 42 75 66 45 6e 64 3b 20  .  int iBufEnd; 
4a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4a70: 20 20 20 2f 2a 20 4c 61 73 74 20 62 79 74 65 20     /* Last byte 
4a80: 6f 66 20 62 75 66 66 65 72 20 74 6f 20 77 72 69  of buffer to wri
4a90: 74 65 20 2a 2f 0a 20 20 69 36 34 20 69 57 72 69  te */.  i64 iWri
4aa0: 74 65 4f 66 66 3b 20 20 20 20 20 20 20 20 20 20  teOff;          
4ab0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65          /* Offse
4ac0: 74 20 6f 66 20 73 74 61 72 74 20 6f 66 20 62 75  t of start of bu
4ad0: 66 66 65 72 20 69 6e 20 66 69 6c 65 20 2a 2f 0a  ffer in file */.
4ae0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
4af0: 70 46 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20  pFile;          
4b00: 20 20 2f 2a 20 46 69 6c 65 20 74 6f 20 77 72 69    /* File to wri
4b10: 74 65 20 74 6f 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  te to */.};../*.
4b20: 2a 2a 20 54 68 69 73 20 6f 62 6a 65 63 74 20 69  ** This object i
4b30: 73 20 74 68 65 20 68 65 61 64 65 72 20 6f 6e 20  s the header on 
4b40: 61 20 73 69 6e 67 6c 65 20 72 65 63 6f 72 64 20  a single record 
4b50: 77 68 69 6c 65 20 74 68 61 74 20 72 65 63 6f 72  while that recor
4b60: 64 20 69 73 20 62 65 69 6e 67 0a 2a 2a 20 68 65  d is being.** he
4b70: 6c 64 20 69 6e 20 6d 65 6d 6f 72 79 20 61 6e 64  ld in memory and
4b80: 20 70 72 69 6f 72 20 74 6f 20 62 65 69 6e 67 20   prior to being 
4b90: 77 72 69 74 74 65 6e 20 6f 75 74 20 61 73 20 70  written out as p
4ba0: 61 72 74 20 6f 66 20 61 20 50 4d 41 2e 0a 2a 2a  art of a PMA..**
4bb0: 0a 2a 2a 20 48 6f 77 20 74 68 65 20 6c 69 6e 6b  .** How the link
4bc0: 65 64 20 6c 69 73 74 20 69 73 20 63 6f 6e 6e 65  ed list is conne
4bd0: 63 74 65 64 20 64 65 70 65 6e 64 73 20 6f 6e 20  cted depends on 
4be0: 68 6f 77 20 6d 65 6d 6f 72 79 20 69 73 20 62 65  how memory is be
4bf0: 69 6e 67 20 6d 61 6e 61 67 65 64 0a 2a 2a 20 62  ing managed.** b
4c00: 79 20 74 68 69 73 20 6d 6f 64 75 6c 65 2e 20 49  y this module. I
4c10: 66 20 75 73 69 6e 67 20 61 20 73 65 70 61 72 61  f using a separa
4c20: 74 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 6f  te allocation fo
4c30: 72 20 65 61 63 68 20 69 6e 2d 6d 65 6d 6f 72 79  r each in-memory
4c40: 20 72 65 63 6f 72 64 0a 2a 2a 20 28 56 64 62 65   record.** (Vdbe
4c50: 53 6f 72 74 65 72 2e 6c 69 73 74 2e 61 4d 65 6d  Sorter.list.aMem
4c60: 6f 72 79 3d 3d 30 29 2c 20 74 68 65 6e 20 74 68  ory==0), then th
4c70: 65 20 6c 69 73 74 20 69 73 20 61 6c 77 61 79 73  e list is always
4c80: 20 63 6f 6e 6e 65 63 74 65 64 20 75 73 69 6e 67   connected using
4c90: 20 74 68 65 0a 2a 2a 20 53 6f 72 74 65 72 52 65   the.** SorterRe
4ca0: 63 6f 72 64 2e 75 2e 70 4e 65 78 74 20 70 6f 69  cord.u.pNext poi
4cb0: 6e 74 65 72 73 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c  nters..**.** Or,
4cc0: 20 69 66 20 75 73 69 6e 67 20 74 68 65 20 73 69   if using the si
4cd0: 6e 67 6c 65 20 6c 61 72 67 65 20 61 6c 6c 6f 63  ngle large alloc
4ce0: 61 74 69 6f 6e 20 6d 65 74 68 6f 64 20 28 56 64  ation method (Vd
4cf0: 62 65 53 6f 72 74 65 72 2e 6c 69 73 74 2e 61 4d  beSorter.list.aM
4d00: 65 6d 6f 72 79 21 3d 30 29 2c 0a 2a 2a 20 74 68  emory!=0),.** th
4d10: 65 6e 20 77 68 69 6c 65 20 72 65 63 6f 72 64 73  en while records
4d20: 20 61 72 65 20 62 65 69 6e 67 20 61 63 63 75 6d   are being accum
4d30: 75 6c 61 74 65 64 20 74 68 65 20 6c 69 73 74 20  ulated the list 
4d40: 69 73 20 6c 69 6e 6b 65 64 20 75 73 69 6e 67 20  is linked using 
4d50: 74 68 65 0a 2a 2a 20 53 6f 72 74 65 72 52 65 63  the.** SorterRec
4d60: 6f 72 64 2e 75 2e 69 4e 65 78 74 20 6f 66 66 73  ord.u.iNext offs
4d70: 65 74 2e 20 54 68 69 73 20 69 73 20 62 65 63 61  et. This is beca
4d80: 75 73 65 20 74 68 65 20 61 4d 65 6d 6f 72 79 5b  use the aMemory[
4d90: 5d 20 61 72 72 61 79 20 6d 61 79 0a 2a 2a 20 62  ] array may.** b
4da0: 65 20 73 71 6c 69 74 65 33 52 65 61 6c 6c 6f 63  e sqlite3Realloc
4db0: 28 29 65 64 20 77 68 69 6c 65 20 72 65 63 6f 72  ()ed while recor
4dc0: 64 73 20 61 72 65 20 62 65 69 6e 67 20 61 63 63  ds are being acc
4dd0: 75 6d 75 6c 61 74 65 64 2e 20 4f 6e 63 65 20 74  umulated. Once t
4de0: 68 65 20 56 4d 0a 2a 2a 20 68 61 73 20 66 69 6e  he VM.** has fin
4df0: 69 73 68 65 64 20 70 61 73 73 69 6e 67 20 72 65  ished passing re
4e00: 63 6f 72 64 73 20 74 6f 20 74 68 65 20 73 6f 72  cords to the sor
4e10: 74 65 72 2c 20 6f 72 20 77 68 65 6e 20 74 68 65  ter, or when the
4e20: 20 69 6e 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65   in-memory buffe
4e30: 72 0a 2a 2a 20 69 73 20 66 75 6c 6c 2c 20 74 68  r.** is full, th
4e40: 65 20 6c 69 73 74 20 69 73 20 73 6f 72 74 65 64  e list is sorted
4e50: 2e 20 41 73 20 70 61 72 74 20 6f 66 20 74 68 65  . As part of the
4e60: 20 73 6f 72 74 69 6e 67 20 70 72 6f 63 65 73 73   sorting process
4e70: 2c 20 69 74 20 69 73 0a 2a 2a 20 63 6f 6e 76 65  , it is.** conve
4e80: 72 74 65 64 20 74 6f 20 75 73 65 20 74 68 65 20  rted to use the 
4e90: 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 75 2e 70  SorterRecord.u.p
4ea0: 4e 65 78 74 20 70 6f 69 6e 74 65 72 73 2e 20 53  Next pointers. S
4eb0: 65 65 20 66 75 6e 63 74 69 6f 6e 0a 2a 2a 20 76  ee function.** v
4ec0: 64 62 65 53 6f 72 74 65 72 53 6f 72 74 28 29 20  dbeSorterSort() 
4ed0: 66 6f 72 20 64 65 74 61 69 6c 73 2e 0a 2a 2f 0a  for details..*/.
4ee0: 73 74 72 75 63 74 20 53 6f 72 74 65 72 52 65 63  struct SorterRec
4ef0: 6f 72 64 20 7b 0a 20 20 69 6e 74 20 6e 56 61 6c  ord {.  int nVal
4f00: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4f10: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
4f20: 6f 66 20 74 68 65 20 72 65 63 6f 72 64 20 69 6e  of the record in
4f30: 20 62 79 74 65 73 20 2a 2f 0a 20 20 75 6e 69 6f   bytes */.  unio
4f40: 6e 20 7b 0a 20 20 20 20 53 6f 72 74 65 72 52 65  n {.    SorterRe
4f50: 63 6f 72 64 20 2a 70 4e 65 78 74 3b 20 20 20 20  cord *pNext;    
4f60: 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
4f70: 20 74 6f 20 6e 65 78 74 20 72 65 63 6f 72 64 20   to next record 
4f80: 69 6e 20 6c 69 73 74 20 2a 2f 0a 20 20 20 20 69  in list */.    i
4f90: 6e 74 20 69 4e 65 78 74 3b 20 20 20 20 20 20 20  nt iNext;       
4fa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4fb0: 4f 66 66 73 65 74 20 77 69 74 68 69 6e 20 61 4d  Offset within aM
4fc0: 65 6d 6f 72 79 20 6f 66 20 6e 65 78 74 20 72 65  emory of next re
4fd0: 63 6f 72 64 20 2a 2f 0a 20 20 7d 20 75 3b 0a 20  cord */.  } u;. 
4fe0: 20 2f 2a 20 54 68 65 20 64 61 74 61 20 66 6f 72   /* The data for
4ff0: 20 74 68 65 20 72 65 63 6f 72 64 20 69 6d 6d 65   the record imme
5000: 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 73 20  diately follows 
5010: 74 68 69 73 20 68 65 61 64 65 72 20 2a 2f 0a 7d  this header */.}
5020: 3b 0a 0a 2f 2a 20 52 65 74 75 72 6e 20 61 20 70  ;../* Return a p
5030: 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 62 75  ointer to the bu
5040: 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ffer containing 
5050: 74 68 65 20 72 65 63 6f 72 64 20 64 61 74 61 20  the record data 
5060: 66 6f 72 20 53 6f 72 74 65 72 52 65 63 6f 72 64  for SorterRecord
5070: 0a 2a 2a 20 6f 62 6a 65 63 74 20 70 2e 20 53 68  .** object p. Sh
5080: 6f 75 6c 64 20 62 65 20 75 73 65 64 20 61 73 20  ould be used as 
5090: 69 66 3a 0a 2a 2a 0a 2a 2a 20 20 20 76 6f 69 64  if:.**.**   void
50a0: 20 2a 53 52 56 41 4c 28 53 6f 72 74 65 72 52 65   *SRVAL(SorterRe
50b0: 63 6f 72 64 20 2a 70 29 20 7b 20 72 65 74 75 72  cord *p) { retur
50c0: 6e 20 28 76 6f 69 64 2a 29 26 70 5b 31 5d 3b 20  n (void*)&p[1]; 
50d0: 7d 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 53 52 56  }.*/.#define SRV
50e0: 41 4c 28 70 29 20 28 28 76 6f 69 64 2a 29 28 28  AL(p) ((void*)((
50f0: 53 6f 72 74 65 72 52 65 63 6f 72 64 2a 29 28 70  SorterRecord*)(p
5100: 29 20 2b 20 31 29 29 0a 0a 2f 2a 20 54 68 65 20  ) + 1))../* The 
5110: 6d 69 6e 69 6d 75 6d 20 50 4d 41 20 73 69 7a 65  minimum PMA size
5120: 20 69 73 20 73 65 74 20 74 6f 20 74 68 69 73 20   is set to this 
5130: 76 61 6c 75 65 20 6d 75 6c 74 69 70 6c 69 65 64  value multiplied
5140: 20 62 79 20 74 68 65 20 64 61 74 61 62 61 73 65   by the database
5150: 0a 2a 2a 20 70 61 67 65 20 73 69 7a 65 20 69 6e  .** page size in
5160: 20 62 79 74 65 73 2e 20 20 2a 2f 0a 23 64 65 66   bytes.  */.#def
5170: 69 6e 65 20 53 4f 52 54 45 52 5f 4d 49 4e 5f 57  ine SORTER_MIN_W
5180: 4f 52 4b 49 4e 47 20 31 30 0a 0a 2f 2a 20 4d 61  ORKING 10../* Ma
5190: 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20  ximum number of 
51a0: 50 4d 41 73 20 74 68 61 74 20 61 20 73 69 6e 67  PMAs that a sing
51b0: 6c 65 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 63  le MergeEngine c
51c0: 61 6e 20 6d 65 72 67 65 20 2a 2f 0a 23 64 65 66  an merge */.#def
51d0: 69 6e 65 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  ine SORTER_MAX_M
51e0: 45 52 47 45 5f 43 4f 55 4e 54 20 31 36 0a 0a 73  ERGE_COUNT 16..s
51f0: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 49 6e  tatic int vdbeIn
5200: 63 72 53 77 61 70 28 49 6e 63 72 4d 65 72 67 65  crSwap(IncrMerge
5210: 72 2a 29 3b 0a 73 74 61 74 69 63 20 76 6f 69 64  r*);.static void
5220: 20 76 64 62 65 49 6e 63 72 46 72 65 65 28 49 6e   vdbeIncrFree(In
5230: 63 72 4d 65 72 67 65 72 20 2a 29 3b 0a 0a 2f 2a  crMerger *);../*
5240: 0a 2a 2a 20 46 72 65 65 20 61 6c 6c 20 6d 65 6d  .** Free all mem
5250: 6f 72 79 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f  ory belonging to
5260: 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 20 6f   the PmaReader o
5270: 62 6a 65 63 74 20 70 61 73 73 65 64 20 61 73 20  bject passed as 
5280: 74 68 65 20 73 65 63 6f 6e 64 0a 2a 2a 20 61 72  the second.** ar
5290: 67 75 6d 65 6e 74 2e 20 41 6c 6c 20 73 74 72 75  gument. All stru
52a0: 63 74 75 72 65 20 66 69 65 6c 64 73 20 61 72 65  cture fields are
52b0: 20 73 65 74 20 74 6f 20 7a 65 72 6f 20 62 65 66   set to zero bef
52c0: 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a  ore returning..*
52d0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64  /.static void vd
52e0: 62 65 50 6d 61 52 65 61 64 65 72 43 6c 65 61 72  bePmaReaderClear
52f0: 28 50 6d 61 52 65 61 64 65 72 20 2a 70 49 74 65  (PmaReader *pIte
5300: 72 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  r){.  sqlite3_fr
5310: 65 65 28 70 49 74 65 72 2d 3e 61 41 6c 6c 6f 63  ee(pIter->aAlloc
5320: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
5330: 65 28 70 49 74 65 72 2d 3e 61 42 75 66 66 65 72  e(pIter->aBuffer
5340: 29 3b 0a 20 20 69 66 28 20 70 49 74 65 72 2d 3e  );.  if( pIter->
5350: 61 4d 61 70 20 29 20 73 71 6c 69 74 65 33 4f 73  aMap ) sqlite3Os
5360: 55 6e 66 65 74 63 68 28 70 49 74 65 72 2d 3e 70  Unfetch(pIter->p
5370: 46 69 6c 65 2c 20 30 2c 20 70 49 74 65 72 2d 3e  File, 0, pIter->
5380: 61 4d 61 70 29 3b 0a 20 20 69 66 28 20 70 49 74  aMap);.  if( pIt
5390: 65 72 2d 3e 70 49 6e 63 72 20 29 20 76 64 62 65  er->pIncr ) vdbe
53a0: 49 6e 63 72 46 72 65 65 28 70 49 74 65 72 2d 3e  IncrFree(pIter->
53b0: 70 49 6e 63 72 29 3b 0a 20 20 6d 65 6d 73 65 74  pIncr);.  memset
53c0: 28 70 49 74 65 72 2c 20 30 2c 20 73 69 7a 65 6f  (pIter, 0, sizeo
53d0: 66 28 50 6d 61 52 65 61 64 65 72 29 29 3b 0a 7d  f(PmaReader));.}
53e0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 6e 42 79  ../*.** Read nBy
53f0: 74 65 20 62 79 74 65 73 20 6f 66 20 64 61 74 61  te bytes of data
5400: 20 66 72 6f 6d 20 74 68 65 20 73 74 72 65 61 6d   from the stream
5410: 20 6f 66 20 64 61 74 61 20 69 74 65 72 61 74 65   of data iterate
5420: 64 20 62 79 20 6f 62 6a 65 63 74 20 70 2e 0a 2a  d by object p..*
5430: 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c  * If successful,
5440: 20 73 65 74 20 2a 70 70 4f 75 74 20 74 6f 20 70   set *ppOut to p
5450: 6f 69 6e 74 20 74 6f 20 61 20 62 75 66 66 65 72  oint to a buffer
5460: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20   containing the 
5470: 64 61 74 61 0a 2a 2a 20 61 6e 64 20 72 65 74 75  data.** and retu
5480: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 4f 74  rn SQLITE_OK. Ot
5490: 68 65 72 77 69 73 65 2c 20 69 66 20 61 6e 20 65  herwise, if an e
54a0: 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 72 65 74  rror occurs, ret
54b0: 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 0a 2a 2a  urn an SQLite.**
54c0: 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a   error code..**.
54d0: 2a 2a 20 54 68 65 20 62 75 66 66 65 72 20 69 6e  ** The buffer in
54e0: 64 69 63 61 74 65 64 20 62 79 20 2a 70 70 4f 75  dicated by *ppOu
54f0: 74 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 63 6f  t may only be co
5500: 6e 73 69 64 65 72 65 64 20 76 61 6c 69 64 20 75  nsidered valid u
5510: 6e 74 69 6c 20 74 68 65 0a 2a 2a 20 6e 65 78 74  ntil the.** next
5520: 20 63 61 6c 6c 20 74 6f 20 74 68 69 73 20 66 75   call to this fu
5530: 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69  nction..*/.stati
5540: 63 20 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61  c int vdbePmaRea
5550: 64 42 6c 6f 62 28 0a 20 20 50 6d 61 52 65 61 64  dBlob(.  PmaRead
5560: 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20  er *p,          
5570: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72           /* Iter
5580: 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  ator */.  int nB
5590: 79 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  yte,            
55a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74            /* Byt
55b0: 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 72 65  es of data to re
55c0: 61 64 20 2a 2f 0a 20 20 75 38 20 2a 2a 70 70 4f  ad */.  u8 **ppO
55d0: 75 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ut              
55e0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
55f0: 50 6f 69 6e 74 65 72 20 74 6f 20 62 75 66 66 65  Pointer to buffe
5600: 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64 61 74  r containing dat
5610: 61 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 42  a */.){.  int iB
5620: 75 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  uf;             
5630: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66            /* Off
5640: 73 65 74 20 77 69 74 68 69 6e 20 62 75 66 66 65  set within buffe
5650: 72 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a  r to read from *
5660: 2f 0a 20 20 69 6e 74 20 6e 41 76 61 69 6c 3b 20  /.  int nAvail; 
5670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5680: 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20      /* Bytes of 
5690: 64 61 74 61 20 61 76 61 69 6c 61 62 6c 65 20 69  data available i
56a0: 6e 20 62 75 66 66 65 72 20 2a 2f 0a 0a 20 20 69  n buffer */..  i
56b0: 66 28 20 70 2d 3e 61 4d 61 70 20 29 7b 0a 20 20  f( p->aMap ){.  
56c0: 20 20 2a 70 70 4f 75 74 20 3d 20 26 70 2d 3e 61    *ppOut = &p->a
56d0: 4d 61 70 5b 70 2d 3e 69 52 65 61 64 4f 66 66 5d  Map[p->iReadOff]
56e0: 3b 0a 20 20 20 20 70 2d 3e 69 52 65 61 64 4f 66  ;.    p->iReadOf
56f0: 66 20 2b 3d 20 6e 42 79 74 65 3b 0a 20 20 20 20  f += nByte;.    
5700: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
5710: 3b 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 28  ;.  }..  assert(
5720: 20 70 2d 3e 61 42 75 66 66 65 72 20 29 3b 0a 0a   p->aBuffer );..
5730: 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20 69 73    /* If there is
5740: 20 6e 6f 20 6d 6f 72 65 20 64 61 74 61 20 74 6f   no more data to
5750: 20 62 65 20 72 65 61 64 20 66 72 6f 6d 20 74 68   be read from th
5760: 65 20 62 75 66 66 65 72 2c 20 72 65 61 64 20 74  e buffer, read t
5770: 68 65 20 6e 65 78 74 20 0a 20 20 2a 2a 20 70 2d  he next .  ** p-
5780: 3e 6e 42 75 66 66 65 72 20 62 79 74 65 73 20 6f  >nBuffer bytes o
5790: 66 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20  f data from the 
57a0: 66 69 6c 65 20 69 6e 74 6f 20 69 74 2e 20 4f 72  file into it. Or
57b0: 2c 20 69 66 20 74 68 65 72 65 20 61 72 65 20 6c  , if there are l
57c0: 65 73 73 0a 20 20 2a 2a 20 74 68 61 6e 20 70 2d  ess.  ** than p-
57d0: 3e 6e 42 75 66 66 65 72 20 62 79 74 65 73 20 72  >nBuffer bytes r
57e0: 65 6d 61 69 6e 69 6e 67 20 69 6e 20 74 68 65 20  emaining in the 
57f0: 50 4d 41 2c 20 72 65 61 64 20 61 6c 6c 20 72 65  PMA, read all re
5800: 6d 61 69 6e 69 6e 67 20 64 61 74 61 2e 20 20 2a  maining data.  *
5810: 2f 0a 20 20 69 42 75 66 20 3d 20 70 2d 3e 69 52  /.  iBuf = p->iR
5820: 65 61 64 4f 66 66 20 25 20 70 2d 3e 6e 42 75 66  eadOff % p->nBuf
5830: 66 65 72 3b 0a 20 20 69 66 28 20 69 42 75 66 3d  fer;.  if( iBuf=
5840: 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 52  =0 ){.    int nR
5850: 65 61 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  ead;            
5860: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
5870: 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 64 69   to read from di
5880: 73 6b 20 2a 2f 0a 20 20 20 20 69 6e 74 20 72 63  sk */.    int rc
5890: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
58a0: 20 20 20 20 20 20 20 20 2f 2a 20 73 71 6c 69 74          /* sqlit
58b0: 65 33 4f 73 52 65 61 64 28 29 20 72 65 74 75 72  e3OsRead() retur
58c0: 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 20 20 2f  n code */..    /
58d0: 2a 20 44 65 74 65 72 6d 69 6e 65 20 68 6f 77 20  * Determine how 
58e0: 6d 61 6e 79 20 62 79 74 65 73 20 6f 66 20 64 61  many bytes of da
58f0: 74 61 20 74 6f 20 72 65 61 64 2e 20 2a 2f 0a 20  ta to read. */. 
5900: 20 20 20 69 66 28 20 28 70 2d 3e 69 45 6f 66 20     if( (p->iEof 
5910: 2d 20 70 2d 3e 69 52 65 61 64 4f 66 66 29 20 3e  - p->iReadOff) >
5920: 20 28 69 36 34 29 70 2d 3e 6e 42 75 66 66 65 72   (i64)p->nBuffer
5930: 20 29 7b 0a 20 20 20 20 20 20 6e 52 65 61 64 20   ){.      nRead 
5940: 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20  = p->nBuffer;.  
5950: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6e    }else{.      n
5960: 52 65 61 64 20 3d 20 28 69 6e 74 29 28 70 2d 3e  Read = (int)(p->
5970: 69 45 6f 66 20 2d 20 70 2d 3e 69 52 65 61 64 4f  iEof - p->iReadO
5980: 66 66 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61  ff);.    }.    a
5990: 73 73 65 72 74 28 20 6e 52 65 61 64 3e 30 20 29  ssert( nRead>0 )
59a0: 3b 0a 0a 20 20 20 20 2f 2a 20 52 65 61 64 20 64  ;..    /* Read d
59b0: 61 74 61 20 66 72 6f 6d 20 74 68 65 20 66 69 6c  ata from the fil
59c0: 65 2e 20 52 65 74 75 72 6e 20 65 61 72 6c 79 20  e. Return early 
59d0: 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  if an error occu
59e0: 72 73 2e 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20  rs. */.    rc = 
59f0: 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70 2d  sqlite3OsRead(p-
5a00: 3e 70 46 69 6c 65 2c 20 70 2d 3e 61 42 75 66 66  >pFile, p->aBuff
5a10: 65 72 2c 20 6e 52 65 61 64 2c 20 70 2d 3e 69 52  er, nRead, p->iR
5a20: 65 61 64 4f 66 66 29 3b 0a 20 20 20 20 61 73 73  eadOff);.    ass
5a30: 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f  ert( rc!=SQLITE_
5a40: 49 4f 45 52 52 5f 53 48 4f 52 54 5f 52 45 41 44  IOERR_SHORT_READ
5a50: 20 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d   );.    if( rc!=
5a60: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
5a70: 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 6e 41 76  rn rc;.  }.  nAv
5a80: 61 69 6c 20 3d 20 70 2d 3e 6e 42 75 66 66 65 72  ail = p->nBuffer
5a90: 20 2d 20 69 42 75 66 3b 20 0a 0a 20 20 69 66 28   - iBuf; ..  if(
5aa0: 20 6e 42 79 74 65 3c 3d 6e 41 76 61 69 6c 20 29   nByte<=nAvail )
5ab0: 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20 72 65 71  {.    /* The req
5ac0: 75 65 73 74 65 64 20 64 61 74 61 20 69 73 20 61  uested data is a
5ad0: 76 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65 20  vailable in the 
5ae0: 69 6e 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65 72  in-memory buffer
5af0: 2e 20 49 6e 20 74 68 69 73 0a 20 20 20 20 2a 2a  . In this.    **
5b00: 20 63 61 73 65 20 74 68 65 72 65 20 69 73 20 6e   case there is n
5b10: 6f 20 6e 65 65 64 20 74 6f 20 6d 61 6b 65 20 61  o need to make a
5b20: 20 63 6f 70 79 20 6f 66 20 74 68 65 20 64 61 74   copy of the dat
5b30: 61 2c 20 6a 75 73 74 20 72 65 74 75 72 6e 20 61  a, just return a
5b40: 20 0a 20 20 20 20 2a 2a 20 70 6f 69 6e 74 65 72   .    ** pointer
5b50: 20 69 6e 74 6f 20 74 68 65 20 62 75 66 66 65 72   into the buffer
5b60: 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e 20   to the caller. 
5b70: 20 2a 2f 0a 20 20 20 20 2a 70 70 4f 75 74 20 3d   */.    *ppOut =
5b80: 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 69 42 75   &p->aBuffer[iBu
5b90: 66 5d 3b 0a 20 20 20 20 70 2d 3e 69 52 65 61 64  f];.    p->iRead
5ba0: 4f 66 66 20 2b 3d 20 6e 42 79 74 65 3b 0a 20 20  Off += nByte;.  
5bb0: 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 54 68  }else{.    /* Th
5bc0: 65 20 72 65 71 75 65 73 74 65 64 20 64 61 74 61  e requested data
5bd0: 20 69 73 20 6e 6f 74 20 61 6c 6c 20 61 76 61 69   is not all avai
5be0: 6c 61 62 6c 65 20 69 6e 20 74 68 65 20 69 6e 2d  lable in the in-
5bf0: 6d 65 6d 6f 72 79 20 62 75 66 66 65 72 2e 0a 20  memory buffer.. 
5c00: 20 20 20 2a 2a 20 49 6e 20 74 68 69 73 20 63 61     ** In this ca
5c10: 73 65 2c 20 61 6c 6c 6f 63 61 74 65 20 73 70 61  se, allocate spa
5c20: 63 65 20 61 74 20 70 2d 3e 61 41 6c 6c 6f 63 5b  ce at p->aAlloc[
5c30: 5d 20 74 6f 20 63 6f 70 79 20 74 68 65 20 72 65  ] to copy the re
5c40: 71 75 65 73 74 65 64 0a 20 20 20 20 2a 2a 20 72  quested.    ** r
5c50: 61 6e 67 65 20 69 6e 74 6f 2e 20 54 68 65 6e 20  ange into. Then 
5c60: 72 65 74 75 72 6e 20 61 20 63 6f 70 79 20 6f 66  return a copy of
5c70: 20 70 6f 69 6e 74 65 72 20 70 2d 3e 61 41 6c 6c   pointer p->aAll
5c80: 6f 63 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72  oc to the caller
5c90: 2e 20 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 52  .  */.    int nR
5ca0: 65 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  em;             
5cb0: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
5cc0: 20 72 65 6d 61 69 6e 69 6e 67 20 74 6f 20 63 6f   remaining to co
5cd0: 70 79 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 45 78  py */..    /* Ex
5ce0: 74 65 6e 64 20 74 68 65 20 70 2d 3e 61 41 6c 6c  tend the p->aAll
5cf0: 6f 63 5b 5d 20 61 6c 6c 6f 63 61 74 69 6f 6e 20  oc[] allocation 
5d00: 69 66 20 72 65 71 75 69 72 65 64 2e 20 2a 2f 0a  if required. */.
5d10: 20 20 20 20 69 66 28 20 70 2d 3e 6e 41 6c 6c 6f      if( p->nAllo
5d20: 63 3c 6e 42 79 74 65 20 29 7b 0a 20 20 20 20 20  c<nByte ){.     
5d30: 20 75 38 20 2a 61 4e 65 77 3b 0a 20 20 20 20 20   u8 *aNew;.     
5d40: 20 69 6e 74 20 6e 4e 65 77 20 3d 20 4d 41 58 28   int nNew = MAX(
5d50: 31 32 38 2c 20 70 2d 3e 6e 41 6c 6c 6f 63 2a 32  128, p->nAlloc*2
5d60: 29 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20  );.      while( 
5d70: 6e 42 79 74 65 3e 6e 4e 65 77 20 29 20 6e 4e 65  nByte>nNew ) nNe
5d80: 77 20 3d 20 6e 4e 65 77 2a 32 3b 0a 20 20 20 20  w = nNew*2;.    
5d90: 20 20 61 4e 65 77 20 3d 20 73 71 6c 69 74 65 33    aNew = sqlite3
5da0: 52 65 61 6c 6c 6f 63 28 70 2d 3e 61 41 6c 6c 6f  Realloc(p->aAllo
5db0: 63 2c 20 6e 4e 65 77 29 3b 0a 20 20 20 20 20 20  c, nNew);.      
5dc0: 69 66 28 20 21 61 4e 65 77 20 29 20 72 65 74 75  if( !aNew ) retu
5dd0: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
5de0: 0a 20 20 20 20 20 20 70 2d 3e 6e 41 6c 6c 6f 63  .      p->nAlloc
5df0: 20 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 70   = nNew;.      p
5e00: 2d 3e 61 41 6c 6c 6f 63 20 3d 20 61 4e 65 77 3b  ->aAlloc = aNew;
5e10: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 43  .    }..    /* C
5e20: 6f 70 79 20 61 73 20 6d 75 63 68 20 64 61 74 61  opy as much data
5e30: 20 61 73 20 69 73 20 61 76 61 69 6c 61 62 6c 65   as is available
5e40: 20 69 6e 20 74 68 65 20 62 75 66 66 65 72 20 69   in the buffer i
5e50: 6e 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66  nto the start of
5e60: 0a 20 20 20 20 2a 2a 20 70 2d 3e 61 41 6c 6c 6f  .    ** p->aAllo
5e70: 63 5b 5d 2e 20 20 2a 2f 0a 20 20 20 20 6d 65 6d  c[].  */.    mem
5e80: 63 70 79 28 70 2d 3e 61 41 6c 6c 6f 63 2c 20 26  cpy(p->aAlloc, &
5e90: 70 2d 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d  p->aBuffer[iBuf]
5ea0: 2c 20 6e 41 76 61 69 6c 29 3b 0a 20 20 20 20 70  , nAvail);.    p
5eb0: 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e 41  ->iReadOff += nA
5ec0: 76 61 69 6c 3b 0a 20 20 20 20 6e 52 65 6d 20 3d  vail;.    nRem =
5ed0: 20 6e 42 79 74 65 20 2d 20 6e 41 76 61 69 6c 3b   nByte - nAvail;
5ee0: 0a 0a 20 20 20 20 2f 2a 20 54 68 65 20 66 6f 6c  ..    /* The fol
5ef0: 6c 6f 77 69 6e 67 20 6c 6f 6f 70 20 63 6f 70 69  lowing loop copi
5f00: 65 73 20 75 70 20 74 6f 20 70 2d 3e 6e 42 75 66  es up to p->nBuf
5f10: 66 65 72 20 62 79 74 65 73 20 70 65 72 20 69 74  fer bytes per it
5f20: 65 72 61 74 69 6f 6e 20 69 6e 74 6f 0a 20 20 20  eration into.   
5f30: 20 2a 2a 20 74 68 65 20 70 2d 3e 61 41 6c 6c 6f   ** the p->aAllo
5f40: 63 5b 5d 20 62 75 66 66 65 72 2e 20 20 2a 2f 0a  c[] buffer.  */.
5f50: 20 20 20 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e      while( nRem>
5f60: 30 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72  0 ){.      int r
5f70: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
5f80: 20 20 20 20 20 20 20 2f 2a 20 76 64 62 65 50 6d         /* vdbePm
5f90: 61 52 65 61 64 42 6c 6f 62 28 29 20 72 65 74 75  aReadBlob() retu
5fa0: 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 20 20 20  rn code */.     
5fb0: 20 69 6e 74 20 6e 43 6f 70 79 3b 20 20 20 20 20   int nCopy;     
5fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5fd0: 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  Number of bytes 
5fe0: 74 6f 20 63 6f 70 79 20 2a 2f 0a 20 20 20 20 20  to copy */.     
5ff0: 20 75 38 20 2a 61 4e 65 78 74 3b 20 20 20 20 20   u8 *aNext;     
6000: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6010: 50 6f 69 6e 74 65 72 20 74 6f 20 62 75 66 66 65  Pointer to buffe
6020: 72 20 74 6f 20 63 6f 70 79 20 64 61 74 61 20 66  r to copy data f
6030: 72 6f 6d 20 2a 2f 0a 0a 20 20 20 20 20 20 6e 43  rom */..      nC
6040: 6f 70 79 20 3d 20 6e 52 65 6d 3b 0a 20 20 20 20  opy = nRem;.    
6050: 20 20 69 66 28 20 6e 52 65 6d 3e 70 2d 3e 6e 42    if( nRem>p->nB
6060: 75 66 66 65 72 20 29 20 6e 43 6f 70 79 20 3d 20  uffer ) nCopy = 
6070: 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20 20  p->nBuffer;.    
6080: 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65    rc = vdbePmaRe
6090: 61 64 42 6c 6f 62 28 70 2c 20 6e 43 6f 70 79 2c  adBlob(p, nCopy,
60a0: 20 26 61 4e 65 78 74 29 3b 0a 20 20 20 20 20 20   &aNext);.      
60b0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
60c0: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  K ) return rc;. 
60d0: 20 20 20 20 20 61 73 73 65 72 74 28 20 61 4e 65       assert( aNe
60e0: 78 74 21 3d 70 2d 3e 61 41 6c 6c 6f 63 20 29 3b  xt!=p->aAlloc );
60f0: 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 70  .      memcpy(&p
6100: 2d 3e 61 41 6c 6c 6f 63 5b 6e 42 79 74 65 20 2d  ->aAlloc[nByte -
6110: 20 6e 52 65 6d 5d 2c 20 61 4e 65 78 74 2c 20 6e   nRem], aNext, n
6120: 43 6f 70 79 29 3b 0a 20 20 20 20 20 20 6e 52 65  Copy);.      nRe
6130: 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20  m -= nCopy;.    
6140: 7d 0a 0a 20 20 20 20 2a 70 70 4f 75 74 20 3d 20  }..    *ppOut = 
6150: 70 2d 3e 61 41 6c 6c 6f 63 3b 0a 20 20 7d 0a 0a  p->aAlloc;.  }..
6160: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
6170: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61  OK;.}../*.** Rea
6180: 64 20 61 20 76 61 72 69 6e 74 20 66 72 6f 6d 20  d a varint from 
6190: 74 68 65 20 73 74 72 65 61 6d 20 6f 66 20 64 61  the stream of da
61a0: 74 61 20 61 63 63 65 73 73 65 64 20 62 79 20 70  ta accessed by p
61b0: 2e 20 53 65 74 20 2a 70 6e 4f 75 74 20 74 6f 0a  . Set *pnOut to.
61c0: 2a 2a 20 74 68 65 20 76 61 6c 75 65 20 72 65 61  ** the value rea
61d0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
61e0: 20 76 64 62 65 50 6d 61 52 65 61 64 56 61 72 69   vdbePmaReadVari
61f0: 6e 74 28 50 6d 61 52 65 61 64 65 72 20 2a 70 2c  nt(PmaReader *p,
6200: 20 75 36 34 20 2a 70 6e 4f 75 74 29 7b 0a 20 20   u64 *pnOut){.  
6210: 69 6e 74 20 69 42 75 66 3b 0a 0a 20 20 69 66 28  int iBuf;..  if(
6220: 20 70 2d 3e 61 4d 61 70 20 29 7b 0a 20 20 20 20   p->aMap ){.    
6230: 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 73  p->iReadOff += s
6240: 71 6c 69 74 65 33 47 65 74 56 61 72 69 6e 74 28  qlite3GetVarint(
6250: 26 70 2d 3e 61 4d 61 70 5b 70 2d 3e 69 52 65 61  &p->aMap[p->iRea
6260: 64 4f 66 66 5d 2c 20 70 6e 4f 75 74 29 3b 0a 20  dOff], pnOut);. 
6270: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 42 75 66   }else{.    iBuf
6280: 20 3d 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 25   = p->iReadOff %
6290: 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20   p->nBuffer;.   
62a0: 20 69 66 28 20 69 42 75 66 20 26 26 20 28 70 2d   if( iBuf && (p-
62b0: 3e 6e 42 75 66 66 65 72 2d 69 42 75 66 29 3e 3d  >nBuffer-iBuf)>=
62c0: 39 20 29 7b 0a 20 20 20 20 20 20 70 2d 3e 69 52  9 ){.      p->iR
62d0: 65 61 64 4f 66 66 20 2b 3d 20 73 71 6c 69 74 65  eadOff += sqlite
62e0: 33 47 65 74 56 61 72 69 6e 74 28 26 70 2d 3e 61  3GetVarint(&p->a
62f0: 42 75 66 66 65 72 5b 69 42 75 66 5d 2c 20 70 6e  Buffer[iBuf], pn
6300: 4f 75 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  Out);.    }else{
6310: 0a 20 20 20 20 20 20 75 38 20 61 56 61 72 69 6e  .      u8 aVarin
6320: 74 5b 31 36 5d 2c 20 2a 61 3b 0a 20 20 20 20 20  t[16], *a;.     
6330: 20 69 6e 74 20 69 20 3d 20 30 2c 20 72 63 3b 0a   int i = 0, rc;.
6340: 20 20 20 20 20 20 64 6f 7b 0a 20 20 20 20 20 20        do{.      
6350: 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65    rc = vdbePmaRe
6360: 61 64 42 6c 6f 62 28 70 2c 20 31 2c 20 26 61 29  adBlob(p, 1, &a)
6370: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
6380: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
6390: 20 20 20 20 20 20 61 56 61 72 69 6e 74 5b 28 69        aVarint[(i
63a0: 2b 2b 29 26 30 78 66 5d 20 3d 20 61 5b 30 5d 3b  ++)&0xf] = a[0];
63b0: 0a 20 20 20 20 20 20 7d 77 68 69 6c 65 28 20 28  .      }while( (
63c0: 61 5b 30 5d 26 30 78 38 30 29 21 3d 30 20 29 3b  a[0]&0x80)!=0 );
63d0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 47 65  .      sqlite3Ge
63e0: 74 56 61 72 69 6e 74 28 61 56 61 72 69 6e 74 2c  tVarint(aVarint,
63f0: 20 70 6e 4f 75 74 29 3b 0a 20 20 20 20 7d 0a 20   pnOut);.    }. 
6400: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c   }..  return SQL
6410: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
6420: 20 41 74 74 65 6d 70 74 20 74 6f 20 6d 65 6d 6f   Attempt to memo
6430: 72 79 20 6d 61 70 20 66 69 6c 65 20 70 46 69 6c  ry map file pFil
6440: 65 2e 20 49 66 20 73 75 63 63 65 73 73 66 75 6c  e. If successful
6450: 2c 20 73 65 74 20 2a 70 70 20 74 6f 20 70 6f 69  , set *pp to poi
6460: 6e 74 20 74 6f 20 74 68 65 0a 2a 2a 20 6e 65 77  nt to the.** new
6470: 20 6d 61 70 70 69 6e 67 20 61 6e 64 20 72 65 74   mapping and ret
6480: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 49  urn SQLITE_OK. I
6490: 66 20 74 68 65 20 6d 61 70 70 69 6e 67 20 69 73  f the mapping is
64a0: 20 6e 6f 74 20 61 74 74 65 6d 70 74 65 64 20 0a   not attempted .
64b0: 2a 2a 20 28 62 65 63 61 75 73 65 20 74 68 65 20  ** (because the 
64c0: 66 69 6c 65 20 69 73 20 74 6f 6f 20 6c 61 72 67  file is too larg
64d0: 65 20 6f 72 20 74 68 65 20 56 46 53 20 6c 61 79  e or the VFS lay
64e0: 65 72 20 69 73 20 63 6f 6e 66 69 67 75 72 65 64  er is configured
64f0: 20 6e 6f 74 20 74 6f 20 75 73 65 0a 2a 2a 20 6d   not to use.** m
6500: 6d 61 70 29 2c 20 72 65 74 75 72 6e 20 53 51 4c  map), return SQL
6510: 49 54 45 5f 4f 4b 20 61 6e 64 20 73 65 74 20 2a  ITE_OK and set *
6520: 70 70 20 74 6f 20 4e 55 4c 4c 2e 0a 2a 2a 0a 2a  pp to NULL..**.*
6530: 2a 20 4f 72 2c 20 69 66 20 61 6e 20 65 72 72 6f  * Or, if an erro
6540: 72 20 6f 63 63 75 72 73 2c 20 72 65 74 75 72 6e  r occurs, return
6550: 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
6560: 20 63 6f 64 65 2e 20 54 68 65 20 66 69 6e 61 6c   code. The final
6570: 20 76 61 6c 75 65 20 6f 66 0a 2a 2a 20 2a 70 70   value of.** *pp
6580: 20 69 73 20 75 6e 64 65 66 69 6e 65 64 20 69 6e   is undefined in
6590: 20 74 68 69 73 20 63 61 73 65 2e 0a 2a 2f 0a 73   this case..*/.s
65a0: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
65b0: 72 74 65 72 4d 61 70 46 69 6c 65 28 53 6f 72 74  rterMapFile(Sort
65c0: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20  Subtask *pTask, 
65d0: 53 6f 72 74 65 72 46 69 6c 65 20 2a 70 46 69 6c  SorterFile *pFil
65e0: 65 2c 20 75 38 20 2a 2a 70 70 29 7b 0a 20 20 69  e, u8 **pp){.  i
65f0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
6600: 4b 3b 0a 20 20 69 66 28 20 70 46 69 6c 65 2d 3e  K;.  if( pFile->
6610: 69 45 6f 66 3c 3d 28 69 36 34 29 28 70 54 61 73  iEof<=(i64)(pTas
6620: 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 64 62 2d 3e  k->pSorter->db->
6630: 6e 4d 61 78 53 6f 72 74 65 72 4d 6d 61 70 29 20  nMaxSorterMmap) 
6640: 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  ){.    rc = sqli
6650: 74 65 33 4f 73 46 65 74 63 68 28 70 46 69 6c 65  te3OsFetch(pFile
6660: 2d 3e 70 46 64 2c 20 30 2c 20 28 69 6e 74 29 70  ->pFd, 0, (int)p
6670: 46 69 6c 65 2d 3e 69 45 6f 66 2c 20 28 76 6f 69  File->iEof, (voi
6680: 64 2a 2a 29 70 70 29 3b 0a 20 20 7d 0a 20 20 72  d**)pp);.  }.  r
6690: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
66a0: 2a 2a 20 53 65 65 6b 20 69 74 65 72 61 74 6f 72  ** Seek iterator
66b0: 20 70 49 74 65 72 20 74 6f 20 6f 66 66 73 65 74   pIter to offset
66c0: 20 69 4f 66 66 20 77 69 74 68 69 6e 20 66 69 6c   iOff within fil
66d0: 65 20 70 46 69 6c 65 2e 20 52 65 74 75 72 6e 20  e pFile. Return 
66e0: 53 51 4c 49 54 45 5f 4f 4b 20 0a 2a 2a 20 69 66  SQLITE_OK .** if
66f0: 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20   successful, or 
6700: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
6710: 63 6f 64 65 20 69 66 20 61 6e 20 65 72 72 6f 72  code if an error
6720: 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74   occurs..*/.stat
6730: 69 63 20 69 6e 74 20 76 64 62 65 50 6d 61 52 65  ic int vdbePmaRe
6740: 61 64 65 72 53 65 65 6b 28 0a 20 20 53 6f 72 74  aderSeek(.  Sort
6750: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20  Subtask *pTask, 
6760: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
6770: 61 73 6b 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20  ask context */. 
6780: 20 50 6d 61 52 65 61 64 65 72 20 2a 70 49 74 65   PmaReader *pIte
6790: 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r,              
67a0: 20 2f 2a 20 49 74 65 72 61 74 65 20 74 6f 20 70   /* Iterate to p
67b0: 6f 70 75 6c 61 74 65 20 2a 2f 0a 20 20 53 6f 72  opulate */.  Sor
67c0: 74 65 72 46 69 6c 65 20 2a 70 46 69 6c 65 2c 20  terFile *pFile, 
67d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
67e0: 53 6f 72 74 65 72 20 66 69 6c 65 20 74 6f 20 72  Sorter file to r
67f0: 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 36  ead from */.  i6
6800: 34 20 69 4f 66 66 20 20 20 20 20 20 20 20 20 20  4 iOff          
6810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6820: 20 4f 66 66 73 65 74 20 69 6e 20 70 46 69 6c 65   Offset in pFile
6830: 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20   */.){.  int rc 
6840: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20  = SQLITE_OK;..  
6850: 61 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e 70  assert( pIter->p
6860: 49 6e 63 72 3d 3d 30 20 7c 7c 20 70 49 74 65 72  Incr==0 || pIter
6870: 2d 3e 70 49 6e 63 72 2d 3e 62 45 6f 66 3d 3d 30  ->pIncr->bEof==0
6880: 20 29 3b 0a 0a 20 20 69 66 28 20 70 49 74 65 72   );..  if( pIter
6890: 2d 3e 61 4d 61 70 20 29 7b 0a 20 20 20 20 73 71  ->aMap ){.    sq
68a0: 6c 69 74 65 33 4f 73 55 6e 66 65 74 63 68 28 70  lite3OsUnfetch(p
68b0: 49 74 65 72 2d 3e 70 46 69 6c 65 2c 20 30 2c 20  Iter->pFile, 0, 
68c0: 70 49 74 65 72 2d 3e 61 4d 61 70 29 3b 0a 20 20  pIter->aMap);.  
68d0: 20 20 70 49 74 65 72 2d 3e 61 4d 61 70 20 3d 20    pIter->aMap = 
68e0: 30 3b 0a 20 20 7d 0a 20 20 70 49 74 65 72 2d 3e  0;.  }.  pIter->
68f0: 69 52 65 61 64 4f 66 66 20 3d 20 69 4f 66 66 3b  iReadOff = iOff;
6900: 0a 20 20 70 49 74 65 72 2d 3e 69 45 6f 66 20 3d  .  pIter->iEof =
6910: 20 70 46 69 6c 65 2d 3e 69 45 6f 66 3b 0a 20 20   pFile->iEof;.  
6920: 70 49 74 65 72 2d 3e 70 46 69 6c 65 20 3d 20 70  pIter->pFile = p
6930: 46 69 6c 65 2d 3e 70 46 64 3b 0a 0a 20 20 72 63  File->pFd;..  rc
6940: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4d 61 70   = vdbeSorterMap
6950: 46 69 6c 65 28 70 54 61 73 6b 2c 20 70 46 69 6c  File(pTask, pFil
6960: 65 2c 20 26 70 49 74 65 72 2d 3e 61 4d 61 70 29  e, &pIter->aMap)
6970: 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
6980: 54 45 5f 4f 4b 20 26 26 20 70 49 74 65 72 2d 3e  TE_OK && pIter->
6990: 61 4d 61 70 3d 3d 30 20 29 7b 0a 20 20 20 20 69  aMap==0 ){.    i
69a0: 6e 74 20 70 67 73 7a 20 3d 20 70 54 61 73 6b 2d  nt pgsz = pTask-
69b0: 3e 70 53 6f 72 74 65 72 2d 3e 70 67 73 7a 3b 0a  >pSorter->pgsz;.
69c0: 20 20 20 20 69 6e 74 20 69 42 75 66 20 3d 20 70      int iBuf = p
69d0: 49 74 65 72 2d 3e 69 52 65 61 64 4f 66 66 20 25  Iter->iReadOff %
69e0: 20 70 67 73 7a 3b 0a 20 20 20 20 69 66 28 20 70   pgsz;.    if( p
69f0: 49 74 65 72 2d 3e 61 42 75 66 66 65 72 3d 3d 30  Iter->aBuffer==0
6a00: 20 29 7b 0a 20 20 20 20 20 20 70 49 74 65 72 2d   ){.      pIter-
6a10: 3e 61 42 75 66 66 65 72 20 3d 20 28 75 38 2a 29  >aBuffer = (u8*)
6a20: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 70 67  sqlite3Malloc(pg
6a30: 73 7a 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70  sz);.      if( p
6a40: 49 74 65 72 2d 3e 61 42 75 66 66 65 72 3d 3d 30  Iter->aBuffer==0
6a50: 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e   ) rc = SQLITE_N
6a60: 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 70 49 74 65  OMEM;.      pIte
6a70: 72 2d 3e 6e 42 75 66 66 65 72 20 3d 20 70 67 73  r->nBuffer = pgs
6a80: 7a 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  z;.    }.    if(
6a90: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
6aa0: 26 20 69 42 75 66 20 29 7b 0a 20 20 20 20 20 20  & iBuf ){.      
6ab0: 69 6e 74 20 6e 52 65 61 64 20 3d 20 70 67 73 7a  int nRead = pgsz
6ac0: 20 2d 20 69 42 75 66 3b 0a 20 20 20 20 20 20 69   - iBuf;.      i
6ad0: 66 28 20 28 70 49 74 65 72 2d 3e 69 52 65 61 64  f( (pIter->iRead
6ae0: 4f 66 66 20 2b 20 6e 52 65 61 64 29 20 3e 20 70  Off + nRead) > p
6af0: 49 74 65 72 2d 3e 69 45 6f 66 20 29 7b 0a 20 20  Iter->iEof ){.  
6b00: 20 20 20 20 20 20 6e 52 65 61 64 20 3d 20 28 69        nRead = (i
6b10: 6e 74 29 28 70 49 74 65 72 2d 3e 69 45 6f 66 20  nt)(pIter->iEof 
6b20: 2d 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66  - pIter->iReadOf
6b30: 66 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  f);.      }.    
6b40: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
6b50: 52 65 61 64 28 0a 20 20 20 20 20 20 20 20 20 20  Read(.          
6b60: 70 49 74 65 72 2d 3e 70 46 69 6c 65 2c 20 26 70  pIter->pFile, &p
6b70: 49 74 65 72 2d 3e 61 42 75 66 66 65 72 5b 69 42  Iter->aBuffer[iB
6b80: 75 66 5d 2c 20 6e 52 65 61 64 2c 20 70 49 74 65  uf], nRead, pIte
6b90: 72 2d 3e 69 52 65 61 64 4f 66 66 0a 20 20 20 20  r->iReadOff.    
6ba0: 20 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72    );.      asser
6bb0: 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 49 4f  t( rc!=SQLITE_IO
6bc0: 45 52 52 5f 53 48 4f 52 54 5f 52 45 41 44 20 29  ERR_SHORT_READ )
6bd0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  ;.    }.  }..  r
6be0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
6bf0: 2a 2a 20 41 64 76 61 6e 63 65 20 69 74 65 72 61  ** Advance itera
6c00: 74 6f 72 20 70 49 74 65 72 20 74 6f 20 74 68 65  tor pIter to the
6c10: 20 6e 65 78 74 20 6b 65 79 20 69 6e 20 69 74 73   next key in its
6c20: 20 50 4d 41 2e 20 52 65 74 75 72 6e 20 53 51 4c   PMA. Return SQL
6c30: 49 54 45 5f 4f 4b 20 69 66 0a 2a 2a 20 6e 6f 20  ITE_OK if.** no 
6c40: 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 6f 72  error occurs, or
6c50: 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
6c60: 20 63 6f 64 65 20 69 66 20 6f 6e 65 20 64 6f 65   code if one doe
6c70: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  s..*/.static int
6c80: 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 4e 65   vdbePmaReaderNe
6c90: 78 74 28 50 6d 61 52 65 61 64 65 72 20 2a 70 49  xt(PmaReader *pI
6ca0: 74 65 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  ter){.  int rc =
6cb0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20   SQLITE_OK;     
6cc0: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
6cd0: 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 75 36 34 20  n Code */.  u64 
6ce0: 6e 52 65 63 20 3d 20 30 3b 20 20 20 20 20 20 20  nRec = 0;       
6cf0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
6d00: 69 7a 65 20 6f 66 20 72 65 63 6f 72 64 20 69 6e  ize of record in
6d10: 20 62 79 74 65 73 20 2a 2f 0a 0a 20 20 69 66 28   bytes */..  if(
6d20: 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66 66   pIter->iReadOff
6d30: 3e 3d 70 49 74 65 72 2d 3e 69 45 6f 66 20 29 7b  >=pIter->iEof ){
6d40: 0a 20 20 20 20 49 6e 63 72 4d 65 72 67 65 72 20  .    IncrMerger 
6d50: 2a 70 49 6e 63 72 20 3d 20 70 49 74 65 72 2d 3e  *pIncr = pIter->
6d60: 70 49 6e 63 72 3b 0a 20 20 20 20 69 6e 74 20 62  pIncr;.    int b
6d70: 45 6f 66 20 3d 20 31 3b 0a 20 20 20 20 69 66 28  Eof = 1;.    if(
6d80: 20 70 49 6e 63 72 20 29 7b 0a 20 20 20 20 20 20   pIncr ){.      
6d90: 72 63 20 3d 20 76 64 62 65 49 6e 63 72 53 77 61  rc = vdbeIncrSwa
6da0: 70 28 70 49 6e 63 72 29 3b 0a 20 20 20 20 20 20  p(pIncr);.      
6db0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
6dc0: 4b 20 26 26 20 70 49 6e 63 72 2d 3e 62 45 6f 66  K && pIncr->bEof
6dd0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72  ==0 ){.        r
6de0: 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65  c = vdbePmaReade
6df0: 72 53 65 65 6b 28 0a 20 20 20 20 20 20 20 20 20  rSeek(.         
6e00: 20 20 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b 2c     pIncr->pTask,
6e10: 20 70 49 74 65 72 2c 20 26 70 49 6e 63 72 2d 3e   pIter, &pIncr->
6e20: 61 46 69 6c 65 5b 30 5d 2c 20 70 49 6e 63 72 2d  aFile[0], pIncr-
6e30: 3e 69 53 74 61 72 74 4f 66 66 0a 20 20 20 20 20  >iStartOff.     
6e40: 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 62 45     );.        bE
6e50: 6f 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a  of = 0;.      }.
6e60: 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 62      }..    if( b
6e70: 45 6f 66 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  Eof ){.      /* 
6e80: 54 68 69 73 20 69 73 20 61 6e 20 45 4f 46 20 63  This is an EOF c
6e90: 6f 6e 64 69 74 69 6f 6e 20 2a 2f 0a 20 20 20 20  ondition */.    
6ea0: 20 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 43    vdbePmaReaderC
6eb0: 6c 65 61 72 28 70 49 74 65 72 29 3b 0a 20 20 20  lear(pIter);.   
6ec0: 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
6ed0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72    }.  }..  if( r
6ee0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
6ef0: 20 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61      rc = vdbePma
6f00: 52 65 61 64 56 61 72 69 6e 74 28 70 49 74 65 72  ReadVarint(pIter
6f10: 2c 20 26 6e 52 65 63 29 3b 0a 20 20 7d 0a 20 20  , &nRec);.  }.  
6f20: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
6f30: 4b 20 29 7b 0a 20 20 20 20 70 49 74 65 72 2d 3e  K ){.    pIter->
6f40: 6e 4b 65 79 20 3d 20 28 69 6e 74 29 6e 52 65 63  nKey = (int)nRec
6f50: 3b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 50  ;.    rc = vdbeP
6f60: 6d 61 52 65 61 64 42 6c 6f 62 28 70 49 74 65 72  maReadBlob(pIter
6f70: 2c 20 28 69 6e 74 29 6e 52 65 63 2c 20 26 70 49  , (int)nRec, &pI
6f80: 74 65 72 2d 3e 61 4b 65 79 29 3b 0a 20 20 7d 0a  ter->aKey);.  }.
6f90: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
6fa0: 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a  ./*.** Initializ
6fb0: 65 20 69 74 65 72 61 74 6f 72 20 70 49 74 65 72  e iterator pIter
6fc0: 20 74 6f 20 73 63 61 6e 20 74 68 72 6f 75 67 68   to scan through
6fd0: 20 74 68 65 20 50 4d 41 20 73 74 6f 72 65 64 20   the PMA stored 
6fe0: 69 6e 20 66 69 6c 65 20 70 46 69 6c 65 0a 2a 2a  in file pFile.**
6ff0: 20 73 74 61 72 74 69 6e 67 20 61 74 20 6f 66 66   starting at off
7000: 73 65 74 20 69 53 74 61 72 74 20 61 6e 64 20 65  set iStart and e
7010: 6e 64 69 6e 67 20 61 74 20 6f 66 66 73 65 74 20  nding at offset 
7020: 69 45 6f 66 2d 31 2e 20 54 68 69 73 20 66 75 6e  iEof-1. This fun
7030: 63 74 69 6f 6e 20 0a 2a 2a 20 6c 65 61 76 65 73  ction .** leaves
7040: 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 70 6f   the iterator po
7050: 69 6e 74 69 6e 67 20 74 6f 20 74 68 65 20 66 69  inting to the fi
7060: 72 73 74 20 6b 65 79 20 69 6e 20 74 68 65 20 50  rst key in the P
7070: 4d 41 20 28 6f 72 20 45 4f 46 20 69 66 20 74 68  MA (or EOF if th
7080: 65 20 0a 2a 2a 20 50 4d 41 20 69 73 20 65 6d 70  e .** PMA is emp
7090: 74 79 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  ty)..**.** If th
70a0: 65 20 70 6e 42 79 74 65 20 70 61 72 61 6d 65 74  e pnByte paramet
70b0: 65 72 20 69 73 20 4e 55 4c 4c 2c 20 74 68 65 6e  er is NULL, then
70c0: 20 69 74 20 69 73 20 61 73 73 75 6d 65 64 20 74   it is assumed t
70d0: 68 61 74 20 74 68 65 20 66 69 6c 65 20 0a 2a 2a  hat the file .**
70e0: 20 63 6f 6e 74 61 69 6e 73 20 61 20 73 69 6e 67   contains a sing
70f0: 6c 65 20 50 4d 41 2c 20 61 6e 64 20 74 68 61 74  le PMA, and that
7100: 20 74 68 61 74 20 50 4d 41 20 6f 6d 69 74 73 20   that PMA omits 
7110: 74 68 65 20 69 6e 69 74 69 61 6c 20 6c 65 6e 67  the initial leng
7120: 74 68 20 76 61 72 69 6e 74 2e 0a 2a 2f 0a 73 74  th varint..*/.st
7130: 61 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d 61  atic int vdbePma
7140: 52 65 61 64 65 72 49 6e 69 74 28 0a 20 20 53 6f  ReaderInit(.  So
7150: 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b  rtSubtask *pTask
7160: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
7170: 20 54 61 73 6b 20 63 6f 6e 74 65 78 74 20 2a 2f   Task context */
7180: 0a 20 20 53 6f 72 74 65 72 46 69 6c 65 20 2a 70  .  SorterFile *p
7190: 46 69 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20  File,           
71a0: 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 66 69 6c     /* Sorter fil
71b0: 65 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a  e to read from *
71c0: 2f 0a 20 20 69 36 34 20 69 53 74 61 72 74 2c 20  /.  i64 iStart, 
71d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
71e0: 20 20 20 20 2f 2a 20 53 74 61 72 74 20 6f 66 66      /* Start off
71f0: 73 65 74 20 69 6e 20 70 46 69 6c 65 20 2a 2f 0a  set in pFile */.
7200: 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70 49 74    PmaReader *pIt
7210: 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  er,             
7220: 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 74 6f    /* Iterator to
7230: 20 70 6f 70 75 6c 61 74 65 20 2a 2f 0a 20 20 69   populate */.  i
7240: 36 34 20 2a 70 6e 42 79 74 65 20 20 20 20 20 20  64 *pnByte      
7250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7260: 2a 20 49 4e 2f 4f 55 54 3a 20 49 6e 63 72 65 6d  * IN/OUT: Increm
7270: 65 6e 74 20 74 68 69 73 20 76 61 6c 75 65 20 62  ent this value b
7280: 79 20 50 4d 41 20 73 69 7a 65 20 2a 2f 0a 29 7b  y PMA size */.){
7290: 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 61 73  .  int rc;..  as
72a0: 73 65 72 74 28 20 70 46 69 6c 65 2d 3e 69 45 6f  sert( pFile->iEo
72b0: 66 3e 69 53 74 61 72 74 20 29 3b 0a 20 20 61 73  f>iStart );.  as
72c0: 73 65 72 74 28 20 70 49 74 65 72 2d 3e 61 41 6c  sert( pIter->aAl
72d0: 6c 6f 63 3d 3d 30 20 26 26 20 70 49 74 65 72 2d  loc==0 && pIter-
72e0: 3e 6e 41 6c 6c 6f 63 3d 3d 30 20 29 3b 0a 20 20  >nAlloc==0 );.  
72f0: 61 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e 61  assert( pIter->a
7300: 42 75 66 66 65 72 3d 3d 30 20 29 3b 0a 20 20 61  Buffer==0 );.  a
7310: 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e 61 4d  ssert( pIter->aM
7320: 61 70 3d 3d 30 20 29 3b 0a 0a 20 20 72 63 20 3d  ap==0 );..  rc =
7330: 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 53 65   vdbePmaReaderSe
7340: 65 6b 28 70 54 61 73 6b 2c 20 70 49 74 65 72 2c  ek(pTask, pIter,
7350: 20 70 46 69 6c 65 2c 20 69 53 74 61 72 74 29 3b   pFile, iStart);
7360: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
7370: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 75 36 34 20  E_OK ){.    u64 
7380: 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20 20 20  nByte;          
7390: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
73a0: 65 20 6f 66 20 50 4d 41 20 69 6e 20 62 79 74 65  e of PMA in byte
73b0: 73 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 76 64  s */.    rc = vd
73c0: 62 65 50 6d 61 52 65 61 64 56 61 72 69 6e 74 28  bePmaReadVarint(
73d0: 70 49 74 65 72 2c 20 26 6e 42 79 74 65 29 3b 0a  pIter, &nByte);.
73e0: 20 20 20 20 70 49 74 65 72 2d 3e 69 45 6f 66 20      pIter->iEof 
73f0: 3d 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66  = pIter->iReadOf
7400: 66 20 2b 20 6e 42 79 74 65 3b 0a 20 20 20 20 2a  f + nByte;.    *
7410: 70 6e 42 79 74 65 20 2b 3d 20 6e 42 79 74 65 3b  pnByte += nByte;
7420: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
7430: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
7440: 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61   rc = vdbePmaRea
7450: 64 65 72 4e 65 78 74 28 70 49 74 65 72 29 3b 0a  derNext(pIter);.
7460: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
7470: 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 61  .}.../*.** Compa
7480: 72 65 20 6b 65 79 31 20 28 62 75 66 66 65 72 20  re key1 (buffer 
7490: 70 4b 65 79 31 2c 20 73 69 7a 65 20 6e 4b 65 79  pKey1, size nKey
74a0: 31 20 62 79 74 65 73 29 20 77 69 74 68 20 6b 65  1 bytes) with ke
74b0: 79 32 20 28 62 75 66 66 65 72 20 70 4b 65 79 32  y2 (buffer pKey2
74c0: 2c 20 0a 2a 2a 20 73 69 7a 65 20 6e 4b 65 79 32  , .** size nKey2
74d0: 20 62 79 74 65 73 29 2e 20 55 73 65 20 28 70 54   bytes). Use (pT
74e0: 61 73 6b 2d 3e 70 4b 65 79 49 6e 66 6f 29 20 66  ask->pKeyInfo) f
74f0: 6f 72 20 74 68 65 20 63 6f 6c 6c 61 74 69 6f 6e  or the collation
7500: 20 73 65 71 75 65 6e 63 65 73 0a 2a 2a 20 75 73   sequences.** us
7510: 65 64 20 62 79 20 74 68 65 20 63 6f 6d 70 61 72  ed by the compar
7520: 69 73 6f 6e 2e 20 52 65 74 75 72 6e 20 74 68 65  ison. Return the
7530: 20 72 65 73 75 6c 74 20 6f 66 20 74 68 65 20 63   result of the c
7540: 6f 6d 70 61 72 69 73 6f 6e 2e 0a 2a 2a 0a 2a 2a  omparison..**.**
7550: 20 42 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e   Before returnin
7560: 67 2c 20 6f 62 6a 65 63 74 20 28 70 54 61 73 6b  g, object (pTask
7570: 2d 3e 70 55 6e 70 61 63 6b 65 64 29 20 69 73 20  ->pUnpacked) is 
7580: 70 6f 70 75 6c 61 74 65 64 20 77 69 74 68 20 74  populated with t
7590: 68 65 0a 2a 2a 20 75 6e 70 61 63 6b 65 64 20 76  he.** unpacked v
75a0: 65 72 73 69 6f 6e 20 6f 66 20 6b 65 79 32 2e 20  ersion of key2. 
75b0: 4f 72 2c 20 69 66 20 70 4b 65 79 32 20 69 73 20  Or, if pKey2 is 
75c0: 70 61 73 73 65 64 20 61 20 4e 55 4c 4c 20 70 6f  passed a NULL po
75d0: 69 6e 74 65 72 2c 20 74 68 65 6e 20 69 74 20 0a  inter, then it .
75e0: 2a 2a 20 69 73 20 61 73 73 75 6d 65 64 20 74 68  ** is assumed th
75f0: 61 74 20 74 68 65 20 28 70 54 61 73 6b 2d 3e 70  at the (pTask->p
7600: 55 6e 70 61 63 6b 65 64 29 20 73 74 72 75 63 74  Unpacked) struct
7610: 75 72 65 20 61 6c 72 65 61 64 79 20 63 6f 6e 74  ure already cont
7620: 61 69 6e 73 20 74 68 65 20 0a 2a 2a 20 75 6e 70  ains the .** unp
7630: 61 63 6b 65 64 20 6b 65 79 20 74 6f 20 75 73 65  acked key to use
7640: 20 61 73 20 6b 65 79 32 2e 0a 2a 2a 0a 2a 2a 20   as key2..**.** 
7650: 49 66 20 61 6e 20 4f 4f 4d 20 65 72 72 6f 72 20  If an OOM error 
7660: 69 73 20 65 6e 63 6f 75 6e 74 65 72 65 64 2c 20  is encountered, 
7670: 28 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65  (pTask->pUnpacke
7680: 64 2d 3e 65 72 72 6f 72 5f 72 63 29 20 69 73 20  d->error_rc) is 
7690: 73 65 74 0a 2a 2a 20 74 6f 20 53 51 4c 49 54 45  set.** to SQLITE
76a0: 5f 4e 4f 4d 45 4d 2e 0a 2a 2f 0a 73 74 61 74 69  _NOMEM..*/.stati
76b0: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72  c int vdbeSorter
76c0: 43 6f 6d 70 61 72 65 28 0a 20 20 53 6f 72 74 53  Compare(.  SortS
76d0: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20  ubtask *pTask,  
76e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 75             /* Su
76f0: 62 74 61 73 6b 20 63 6f 6e 74 65 78 74 20 28 66  btask context (f
7700: 6f 72 20 70 4b 65 79 49 6e 66 6f 29 20 2a 2f 0a  or pKeyInfo) */.
7710: 20 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 4b    const void *pK
7720: 65 79 31 2c 20 69 6e 74 20 6e 4b 65 79 31 2c 20  ey1, int nKey1, 
7730: 20 20 2f 2a 20 4c 65 66 74 20 73 69 64 65 20 6f    /* Left side o
7740: 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f 0a  f comparison */.
7750: 20 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 4b    const void *pK
7760: 65 79 32 2c 20 69 6e 74 20 6e 4b 65 79 32 20 20  ey2, int nKey2  
7770: 20 20 2f 2a 20 52 69 67 68 74 20 73 69 64 65 20    /* Right side 
7780: 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f  of comparison */
7790: 0a 29 7b 0a 20 20 55 6e 70 61 63 6b 65 64 52 65  .){.  UnpackedRe
77a0: 63 6f 72 64 20 2a 72 32 20 3d 20 70 54 61 73 6b  cord *r2 = pTask
77b0: 2d 3e 70 55 6e 70 61 63 6b 65 64 3b 0a 20 20 69  ->pUnpacked;.  i
77c0: 66 28 20 70 4b 65 79 32 20 29 7b 0a 20 20 20 20  f( pKey2 ){.    
77d0: 73 71 6c 69 74 65 33 56 64 62 65 52 65 63 6f 72  sqlite3VdbeRecor
77e0: 64 55 6e 70 61 63 6b 28 70 54 61 73 6b 2d 3e 70  dUnpack(pTask->p
77f0: 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49 6e 66 6f  Sorter->pKeyInfo
7800: 2c 20 6e 4b 65 79 32 2c 20 70 4b 65 79 32 2c 20  , nKey2, pKey2, 
7810: 72 32 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  r2);.  }.  retur
7820: 6e 20 73 71 6c 69 74 65 33 56 64 62 65 52 65 63  n sqlite3VdbeRec
7830: 6f 72 64 43 6f 6d 70 61 72 65 28 6e 4b 65 79 31  ordCompare(nKey1
7840: 2c 20 70 4b 65 79 31 2c 20 72 32 2c 20 30 29 3b  , pKey1, r2, 0);
7850: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
7860: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
7870: 64 20 74 6f 20 63 6f 6d 70 61 72 65 20 74 77 6f  d to compare two
7880: 20 69 74 65 72 61 74 6f 72 20 6b 65 79 73 20 77   iterator keys w
7890: 68 65 6e 20 6d 65 72 67 69 6e 67 20 0a 2a 2a 20  hen merging .** 
78a0: 6d 75 6c 74 69 70 6c 65 20 62 2d 74 72 65 65 20  multiple b-tree 
78b0: 73 65 67 6d 65 6e 74 73 2e 20 50 61 72 61 6d 65  segments. Parame
78c0: 74 65 72 20 69 4f 75 74 20 69 73 20 74 68 65 20  ter iOut is the 
78d0: 69 6e 64 65 78 20 6f 66 20 74 68 65 20 61 54 72  index of the aTr
78e0: 65 65 5b 5d 20 0a 2a 2a 20 76 61 6c 75 65 20 74  ee[] .** value t
78f0: 6f 20 72 65 63 61 6c 63 75 6c 61 74 65 2e 0a 2a  o recalculate..*
7900: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
7910: 65 53 6f 72 74 65 72 44 6f 43 6f 6d 70 61 72 65  eSorterDoCompare
7920: 28 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20  (.  SortSubtask 
7930: 2a 70 54 61 73 6b 2c 20 0a 20 20 4d 65 72 67 65  *pTask, .  Merge
7940: 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 2c  Engine *pMerger,
7950: 20 0a 20 20 69 6e 74 20 69 4f 75 74 0a 29 7b 0a   .  int iOut.){.
7960: 20 20 69 6e 74 20 69 31 3b 0a 20 20 69 6e 74 20    int i1;.  int 
7970: 69 32 3b 0a 20 20 69 6e 74 20 69 52 65 73 3b 0a  i2;.  int iRes;.
7980: 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70 31 3b    PmaReader *p1;
7990: 0a 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70 32  .  PmaReader *p2
79a0: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 69 4f 75  ;..  assert( iOu
79b0: 74 3c 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65  t<pMerger->nTree
79c0: 20 26 26 20 69 4f 75 74 3e 30 20 29 3b 0a 0a 20   && iOut>0 );.. 
79d0: 20 69 66 28 20 69 4f 75 74 3e 3d 28 70 4d 65 72   if( iOut>=(pMer
79e0: 67 65 72 2d 3e 6e 54 72 65 65 2f 32 29 20 29 7b  ger->nTree/2) ){
79f0: 0a 20 20 20 20 69 31 20 3d 20 28 69 4f 75 74 20  .    i1 = (iOut 
7a00: 2d 20 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65  - pMerger->nTree
7a10: 2f 32 29 20 2a 20 32 3b 0a 20 20 20 20 69 32 20  /2) * 2;.    i2 
7a20: 3d 20 69 31 20 2b 20 31 3b 0a 20 20 7d 65 6c 73  = i1 + 1;.  }els
7a30: 65 7b 0a 20 20 20 20 69 31 20 3d 20 70 4d 65 72  e{.    i1 = pMer
7a40: 67 65 72 2d 3e 61 54 72 65 65 5b 69 4f 75 74 2a  ger->aTree[iOut*
7a50: 32 5d 3b 0a 20 20 20 20 69 32 20 3d 20 70 4d 65  2];.    i2 = pMe
7a60: 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 4f 75 74  rger->aTree[iOut
7a70: 2a 32 2b 31 5d 3b 0a 20 20 7d 0a 0a 20 20 70 31  *2+1];.  }..  p1
7a80: 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49 74   = &pMerger->aIt
7a90: 65 72 5b 69 31 5d 3b 0a 20 20 70 32 20 3d 20 26  er[i1];.  p2 = &
7aa0: 70 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 69  pMerger->aIter[i
7ab0: 32 5d 3b 0a 0a 20 20 69 66 28 20 70 31 2d 3e 70  2];..  if( p1->p
7ac0: 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69  File==0 ){.    i
7ad0: 52 65 73 20 3d 20 69 32 3b 0a 20 20 7d 65 6c 73  Res = i2;.  }els
7ae0: 65 20 69 66 28 20 70 32 2d 3e 70 46 69 6c 65 3d  e if( p2->pFile=
7af0: 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 73 20 3d  =0 ){.    iRes =
7b00: 20 69 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20   i1;.  }else{.  
7b10: 20 20 69 6e 74 20 72 65 73 3b 0a 20 20 20 20 61    int res;.    a
7b20: 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 70 55  ssert( pTask->pU
7b30: 6e 70 61 63 6b 65 64 21 3d 30 20 29 3b 20 20 2f  npacked!=0 );  /
7b40: 2a 20 61 6c 6c 6f 63 61 74 65 64 20 69 6e 20 76  * allocated in v
7b50: 64 62 65 53 6f 72 74 53 75 62 74 61 73 6b 4d 61  dbeSortSubtaskMa
7b60: 69 6e 28 29 20 2a 2f 0a 20 20 20 20 72 65 73 20  in() */.    res 
7b70: 3d 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70  = vdbeSorterComp
7b80: 61 72 65 28 0a 20 20 20 20 20 20 20 20 70 54 61  are(.        pTa
7b90: 73 6b 2c 20 70 31 2d 3e 61 4b 65 79 2c 20 70 31  sk, p1->aKey, p1
7ba0: 2d 3e 6e 4b 65 79 2c 20 70 32 2d 3e 61 4b 65 79  ->nKey, p2->aKey
7bb0: 2c 20 70 32 2d 3e 6e 4b 65 79 0a 20 20 20 20 29  , p2->nKey.    )
7bc0: 3b 0a 20 20 20 20 69 66 28 20 72 65 73 3c 3d 30  ;.    if( res<=0
7bd0: 20 29 7b 0a 20 20 20 20 20 20 69 52 65 73 20 3d   ){.      iRes =
7be0: 20 69 31 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a   i1;.    }else{.
7bf0: 20 20 20 20 20 20 69 52 65 73 20 3d 20 69 32 3b        iRes = i2;
7c00: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 70 4d  .    }.  }..  pM
7c10: 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 4f 75  erger->aTree[iOu
7c20: 74 5d 20 3d 20 69 52 65 73 3b 0a 20 20 72 65 74  t] = iRes;.  ret
7c30: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
7c40: 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69  ../*.** Initiali
7c50: 7a 65 20 74 68 65 20 74 65 6d 70 6f 72 61 72 79  ze the temporary
7c60: 20 69 6e 64 65 78 20 63 75 72 73 6f 72 20 6a 75   index cursor ju
7c70: 73 74 20 6f 70 65 6e 65 64 20 61 73 20 61 20 73  st opened as a s
7c80: 6f 72 74 65 72 20 63 75 72 73 6f 72 2e 0a 2a 2a  orter cursor..**
7c90: 0a 2a 2a 20 55 73 75 61 6c 6c 79 2c 20 74 68 65  .** Usually, the
7ca0: 20 73 6f 72 74 65 72 20 6d 6f 64 75 6c 65 20 75   sorter module u
7cb0: 73 65 73 20 74 68 65 20 76 61 6c 75 65 20 6f 66  ses the value of
7cc0: 20 28 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f   (pCsr->pKeyInfo
7cd0: 2d 3e 6e 46 69 65 6c 64 29 0a 2a 2a 20 74 6f 20  ->nField).** to 
7ce0: 64 65 74 65 72 6d 69 6e 65 20 74 68 65 20 6e 75  determine the nu
7cf0: 6d 62 65 72 20 6f 66 20 66 69 65 6c 64 73 20 74  mber of fields t
7d00: 68 61 74 20 73 68 6f 75 6c 64 20 62 65 20 63 6f  hat should be co
7d10: 6d 70 61 72 65 64 20 66 72 6f 6d 20 74 68 65 0a  mpared from the.
7d20: 2a 2a 20 72 65 63 6f 72 64 73 20 62 65 69 6e 67  ** records being
7d30: 20 73 6f 72 74 65 64 2e 20 48 6f 77 65 76 65 72   sorted. However
7d40: 2c 20 69 66 20 74 68 65 20 76 61 6c 75 65 20 70  , if the value p
7d50: 61 73 73 65 64 20 61 73 20 61 72 67 75 6d 65 6e  assed as argumen
7d60: 74 20 6e 46 69 65 6c 64 0a 2a 2a 20 69 73 20 6e  t nField.** is n
7d70: 6f 6e 2d 7a 65 72 6f 20 61 6e 64 20 74 68 65 20  on-zero and the 
7d80: 73 6f 72 74 65 72 20 69 73 20 61 62 6c 65 20 74  sorter is able t
7d90: 6f 20 67 75 61 72 61 6e 74 65 65 20 61 20 73 74  o guarantee a st
7da0: 61 62 6c 65 20 73 6f 72 74 2c 20 6e 46 69 65 6c  able sort, nFiel
7db0: 64 0a 2a 2a 20 69 73 20 75 73 65 64 20 69 6e 73  d.** is used ins
7dc0: 74 65 61 64 2e 20 54 68 69 73 20 69 73 20 75 73  tead. This is us
7dd0: 65 64 20 77 68 65 6e 20 73 6f 72 74 69 6e 67 20  ed when sorting 
7de0: 72 65 63 6f 72 64 73 20 66 6f 72 20 61 20 43 52  records for a CR
7df0: 45 41 54 45 20 49 4e 44 45 58 0a 2a 2a 20 73 74  EATE INDEX.** st
7e00: 61 74 65 6d 65 6e 74 2e 20 49 6e 20 74 68 69 73  atement. In this
7e10: 20 63 61 73 65 2c 20 6b 65 79 73 20 61 72 65 20   case, keys are 
7e20: 61 6c 77 61 79 73 20 64 65 6c 69 76 65 72 65 64  always delivered
7e30: 20 74 6f 20 74 68 65 20 73 6f 72 74 65 72 20 69   to the sorter i
7e40: 6e 0a 2a 2a 20 6f 72 64 65 72 20 6f 66 20 74 68  n.** order of th
7e50: 65 20 70 72 69 6d 61 72 79 20 6b 65 79 2c 20 77  e primary key, w
7e60: 68 69 63 68 20 68 61 70 70 65 6e 73 20 74 6f 20  hich happens to 
7e70: 62 65 20 6d 61 6b 65 20 75 70 20 74 68 65 20 66  be make up the f
7e80: 69 6e 61 6c 20 70 61 72 74 20 0a 2a 2a 20 6f 66  inal part .** of
7e90: 20 74 68 65 20 72 65 63 6f 72 64 73 20 62 65 69   the records bei
7ea0: 6e 67 20 73 6f 72 74 65 64 2e 20 53 6f 20 69 66  ng sorted. So if
7eb0: 20 74 68 65 20 73 6f 72 74 20 69 73 20 73 74 61   the sort is sta
7ec0: 62 6c 65 2c 20 74 68 65 72 65 20 69 73 20 6e 65  ble, there is ne
7ed0: 76 65 72 0a 2a 2a 20 61 6e 79 20 72 65 61 73 6f  ver.** any reaso
7ee0: 6e 20 74 6f 20 63 6f 6d 70 61 72 65 20 50 4b 20  n to compare PK 
7ef0: 66 69 65 6c 64 73 20 61 6e 64 20 74 68 65 79 20  fields and they 
7f00: 63 61 6e 20 62 65 20 69 67 6e 6f 72 65 64 20 66  can be ignored f
7f10: 6f 72 20 61 20 73 6d 61 6c 6c 0a 2a 2a 20 70 65  or a small.** pe
7f20: 72 66 6f 72 6d 61 6e 63 65 20 62 6f 6f 73 74 2e  rformance boost.
7f30: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 6f 72 74 65  .**.** The sorte
7f40: 72 20 63 61 6e 20 67 75 61 72 61 6e 74 65 65 20  r can guarantee 
7f50: 61 20 73 74 61 62 6c 65 20 73 6f 72 74 20 77 68  a stable sort wh
7f60: 65 6e 20 72 75 6e 6e 69 6e 67 20 69 6e 20 73 69  en running in si
7f70: 6e 67 6c 65 2d 74 68 72 65 61 64 65 64 0a 2a 2a  ngle-threaded.**
7f80: 20 6d 6f 64 65 2c 20 62 75 74 20 6e 6f 74 20 69   mode, but not i
7f90: 6e 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64  n multi-threaded
7fa0: 20 6d 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c   mode..**.** SQL
7fb0: 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e  ITE_OK is return
7fc0: 65 64 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  ed if successful
7fd0: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65  , or an SQLite e
7fe0: 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77  rror code otherw
7ff0: 69 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  ise..*/.int sqli
8000: 74 65 33 56 64 62 65 53 6f 72 74 65 72 49 6e 69  te3VdbeSorterIni
8010: 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  t(.  sqlite3 *db
8020: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8030: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
8040: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 28 66 6f 72   connection (for
8050: 20 6d 61 6c 6c 6f 63 28 29 29 20 2a 2f 0a 20 20   malloc()) */.  
8060: 69 6e 74 20 6e 46 69 65 6c 64 2c 20 20 20 20 20  int nField,     
8070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8080: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 6b 65 79  /* Number of key
8090: 20 66 69 65 6c 64 73 20 69 6e 20 65 61 63 68 20   fields in each 
80a0: 72 65 63 6f 72 64 20 2a 2f 0a 20 20 56 64 62 65  record */.  Vdbe
80b0: 43 75 72 73 6f 72 20 2a 70 43 73 72 20 20 20 20  Cursor *pCsr    
80c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
80d0: 75 72 73 6f 72 20 74 68 61 74 20 68 6f 6c 64 73  ursor that holds
80e0: 20 74 68 65 20 6e 65 77 20 73 6f 72 74 65 72 20   the new sorter 
80f0: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 70 67 73 7a  */.){.  int pgsz
8100: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
8110: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20          /* Page 
8120: 73 69 7a 65 20 6f 66 20 6d 61 69 6e 20 64 61 74  size of main dat
8130: 61 62 61 73 65 20 2a 2f 0a 20 20 69 6e 74 20 69  abase */.  int i
8140: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
8150: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73             /* Us
8160: 65 64 20 74 6f 20 69 74 65 72 61 74 65 20 74 68  ed to iterate th
8170: 72 6f 75 67 68 20 61 54 61 73 6b 5b 5d 20 2a 2f  rough aTask[] */
8180: 0a 20 20 69 6e 74 20 6d 78 43 61 63 68 65 3b 20  .  int mxCache; 
8190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
81a0: 20 20 20 2f 2a 20 43 61 63 68 65 20 73 69 7a 65     /* Cache size
81b0: 20 2a 2f 0a 20 20 56 64 62 65 53 6f 72 74 65 72   */.  VdbeSorter
81c0: 20 2a 70 53 6f 72 74 65 72 3b 20 20 20 20 20 20   *pSorter;      
81d0: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77        /* The new
81e0: 20 73 6f 72 74 65 72 20 2a 2f 0a 20 20 4b 65 79   sorter */.  Key
81f0: 49 6e 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 3b 20  Info *pKeyInfo; 
8200: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8210: 43 6f 70 79 20 6f 66 20 70 43 73 72 2d 3e 70 4b  Copy of pCsr->pK
8220: 65 79 49 6e 66 6f 20 77 69 74 68 20 64 62 3d 3d  eyInfo with db==
8230: 30 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 4b 65 79  0 */.  int szKey
8240: 49 6e 66 6f 3b 20 20 20 20 20 20 20 20 20 20 20  Info;           
8250: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
8260: 66 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f  f pCsr->pKeyInfo
8270: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69   in bytes */.  i
8280: 6e 74 20 73 7a 3b 20 20 20 20 20 20 20 20 20 20  nt sz;          
8290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
82a0: 2a 20 53 69 7a 65 20 6f 66 20 70 53 6f 72 74 65  * Size of pSorte
82b0: 72 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  r in bytes */.  
82c0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
82d0: 4f 4b 3b 0a 20 20 69 6e 74 20 6e 57 6f 72 6b 65  OK;.  int nWorke
82e0: 72 20 3d 20 28 73 71 6c 69 74 65 33 47 6c 6f 62  r = (sqlite3Glob
82f0: 61 6c 43 6f 6e 66 69 67 2e 62 43 6f 72 65 4d 75  alConfig.bCoreMu
8300: 74 65 78 3f 73 71 6c 69 74 65 33 47 6c 6f 62 61  tex?sqlite3Globa
8310: 6c 43 6f 6e 66 69 67 2e 6e 57 6f 72 6b 65 72 3a  lConfig.nWorker:
8320: 30 29 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  0);..  assert( p
8330: 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 20 26 26  Csr->pKeyInfo &&
8340: 20 70 43 73 72 2d 3e 70 42 74 3d 3d 30 20 29 3b   pCsr->pBt==0 );
8350: 0a 20 20 73 7a 4b 65 79 49 6e 66 6f 20 3d 20 73  .  szKeyInfo = s
8360: 69 7a 65 6f 66 28 4b 65 79 49 6e 66 6f 29 20 2b  izeof(KeyInfo) +
8370: 20 28 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f   (pCsr->pKeyInfo
8380: 2d 3e 6e 46 69 65 6c 64 2d 31 29 2a 73 69 7a 65  ->nField-1)*size
8390: 6f 66 28 43 6f 6c 6c 53 65 71 2a 29 3b 0a 20 20  of(CollSeq*);.  
83a0: 73 7a 20 3d 20 73 69 7a 65 6f 66 28 56 64 62 65  sz = sizeof(Vdbe
83b0: 53 6f 72 74 65 72 29 20 2b 20 6e 57 6f 72 6b 65  Sorter) + nWorke
83c0: 72 20 2a 20 73 69 7a 65 6f 66 28 53 6f 72 74 53  r * sizeof(SortS
83d0: 75 62 74 61 73 6b 29 3b 0a 0a 20 20 70 53 6f 72  ubtask);..  pSor
83e0: 74 65 72 20 3d 20 28 56 64 62 65 53 6f 72 74 65  ter = (VdbeSorte
83f0: 72 2a 29 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c  r*)sqlite3DbMall
8400: 6f 63 5a 65 72 6f 28 64 62 2c 20 73 7a 20 2b 20  ocZero(db, sz + 
8410: 73 7a 4b 65 79 49 6e 66 6f 29 3b 0a 20 20 70 43  szKeyInfo);.  pC
8420: 73 72 2d 3e 70 53 6f 72 74 65 72 20 3d 20 70 53  sr->pSorter = pS
8430: 6f 72 74 65 72 3b 0a 20 20 69 66 28 20 70 53 6f  orter;.  if( pSo
8440: 72 74 65 72 3d 3d 30 20 29 7b 0a 20 20 20 20 72  rter==0 ){.    r
8450: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
8460: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70  ;.  }else{.    p
8470: 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49 6e 66 6f  Sorter->pKeyInfo
8480: 20 3d 20 70 4b 65 79 49 6e 66 6f 20 3d 20 28 4b   = pKeyInfo = (K
8490: 65 79 49 6e 66 6f 2a 29 28 28 75 38 2a 29 70 53  eyInfo*)((u8*)pS
84a0: 6f 72 74 65 72 20 2b 20 73 7a 29 3b 0a 20 20 20  orter + sz);.   
84b0: 20 6d 65 6d 63 70 79 28 70 4b 65 79 49 6e 66 6f   memcpy(pKeyInfo
84c0: 2c 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f  , pCsr->pKeyInfo
84d0: 2c 20 73 7a 4b 65 79 49 6e 66 6f 29 3b 0a 20 20  , szKeyInfo);.  
84e0: 20 20 70 4b 65 79 49 6e 66 6f 2d 3e 64 62 20 3d    pKeyInfo->db =
84f0: 20 30 3b 0a 20 20 20 20 69 66 28 20 6e 46 69 65   0;.    if( nFie
8500: 6c 64 20 26 26 20 6e 57 6f 72 6b 65 72 3d 3d 30  ld && nWorker==0
8510: 20 29 20 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69   ) pKeyInfo->nFi
8520: 65 6c 64 20 3d 20 6e 46 69 65 6c 64 3b 0a 20 20  eld = nField;.  
8530: 20 20 70 53 6f 72 74 65 72 2d 3e 70 67 73 7a 20    pSorter->pgsz 
8540: 3d 20 70 67 73 7a 20 3d 20 73 71 6c 69 74 65 33  = pgsz = sqlite3
8550: 42 74 72 65 65 47 65 74 50 61 67 65 53 69 7a 65  BtreeGetPageSize
8560: 28 64 62 2d 3e 61 44 62 5b 30 5d 2e 70 42 74 29  (db->aDb[0].pBt)
8570: 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6e  ;.    pSorter->n
8580: 54 61 73 6b 20 3d 20 6e 57 6f 72 6b 65 72 20 2b  Task = nWorker +
8590: 20 31 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d   1;.    pSorter-
85a0: 3e 62 55 73 65 54 68 72 65 61 64 73 20 3d 20 28  >bUseThreads = (
85b0: 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3e 31  pSorter->nTask>1
85c0: 29 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  );.    pSorter->
85d0: 64 62 20 3d 20 64 62 3b 0a 20 20 20 20 66 6f 72  db = db;.    for
85e0: 28 69 3d 30 3b 20 69 3c 70 53 6f 72 74 65 72 2d  (i=0; i<pSorter-
85f0: 3e 6e 54 61 73 6b 3b 20 69 2b 2b 29 7b 0a 20 20  >nTask; i++){.  
8600: 20 20 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20      SortSubtask 
8610: 2a 70 54 61 73 6b 20 3d 20 26 70 53 6f 72 74 65  *pTask = &pSorte
8620: 72 2d 3e 61 54 61 73 6b 5b 69 5d 3b 0a 20 20 20  r->aTask[i];.   
8630: 20 20 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65     pTask->pSorte
8640: 72 20 3d 20 70 53 6f 72 74 65 72 3b 0a 20 20 20  r = pSorter;.   
8650: 20 7d 0a 0a 20 20 20 20 69 66 28 20 21 73 71 6c   }..    if( !sql
8660: 69 74 65 33 54 65 6d 70 49 6e 4d 65 6d 6f 72 79  ite3TempInMemory
8670: 28 64 62 29 20 29 7b 0a 20 20 20 20 20 20 70 53  (db) ){.      pS
8680: 6f 72 74 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a 65  orter->mnPmaSize
8690: 20 3d 20 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f   = SORTER_MIN_WO
86a0: 52 4b 49 4e 47 20 2a 20 70 67 73 7a 3b 0a 20 20  RKING * pgsz;.  
86b0: 20 20 20 20 6d 78 43 61 63 68 65 20 3d 20 64 62      mxCache = db
86c0: 2d 3e 61 44 62 5b 30 5d 2e 70 53 63 68 65 6d 61  ->aDb[0].pSchema
86d0: 2d 3e 63 61 63 68 65 5f 73 69 7a 65 3b 0a 20 20  ->cache_size;.  
86e0: 20 20 20 20 69 66 28 20 6d 78 43 61 63 68 65 3c      if( mxCache<
86f0: 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49  SORTER_MIN_WORKI
8700: 4e 47 20 29 20 6d 78 43 61 63 68 65 20 3d 20 53  NG ) mxCache = S
8710: 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e  ORTER_MIN_WORKIN
8720: 47 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72  G;.      pSorter
8730: 2d 3e 6d 78 50 6d 61 53 69 7a 65 20 3d 20 6d 78  ->mxPmaSize = mx
8740: 43 61 63 68 65 20 2a 20 70 67 73 7a 3b 0a 0a 20  Cache * pgsz;.. 
8750: 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 61       /* If the a
8760: 70 70 6c 69 63 61 74 69 6f 6e 20 69 73 20 75 73  pplication is us
8770: 69 6e 67 20 6d 65 6d 73 79 73 33 20 6f 72 20 6d  ing memsys3 or m
8780: 65 6d 73 79 73 35 2c 20 75 73 65 20 61 20 73 65  emsys5, use a se
8790: 70 61 72 61 74 65 20 0a 20 20 20 20 20 20 2a 2a  parate .      **
87a0: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 6f 72 20   allocation for 
87b0: 65 61 63 68 20 73 6f 72 74 2d 6b 65 79 20 69 6e  each sort-key in
87c0: 20 6d 65 6d 6f 72 79 2e 20 4f 74 68 65 72 77 69   memory. Otherwi
87d0: 73 65 2c 20 75 73 65 20 61 20 73 69 6e 67 6c 65  se, use a single
87e0: 20 62 69 67 0a 20 20 20 20 20 20 2a 2a 20 61 6c   big.      ** al
87f0: 6c 6f 63 61 74 69 6f 6e 20 61 74 20 70 53 6f 72  location at pSor
8800: 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 20 66 6f 72  ter->aMemory for
8810: 20 61 6c 6c 20 73 6f 72 74 2d 6b 65 79 73 2e 20   all sort-keys. 
8820: 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 73 71   */.      if( sq
8830: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
8840: 67 2e 70 48 65 61 70 3d 3d 30 20 29 7b 0a 20 20  g.pHeap==0 ){.  
8850: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 53        assert( pS
8860: 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 3d 3d  orter->iMemory==
8870: 30 20 29 3b 0a 20 20 20 20 20 20 20 20 70 53 6f  0 );.        pSo
8880: 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 3d 20  rter->nMemory = 
8890: 70 67 73 7a 3b 0a 20 20 20 20 20 20 20 20 70 53  pgsz;.        pS
88a0: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d  orter->list.aMem
88b0: 6f 72 79 20 3d 20 28 75 38 2a 29 73 71 6c 69 74  ory = (u8*)sqlit
88c0: 65 33 4d 61 6c 6c 6f 63 28 70 67 73 7a 29 3b 0a  e3Malloc(pgsz);.
88d0: 20 20 20 20 20 20 20 20 69 66 28 20 21 70 53 6f          if( !pSo
88e0: 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f  rter->list.aMemo
88f0: 72 79 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45  ry ) rc = SQLITE
8900: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 7d 0a  _NOMEM;.      }.
8910: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
8920: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
8930: 20 46 72 65 65 20 74 68 65 20 6c 69 73 74 20 6f   Free the list o
8940: 66 20 73 6f 72 74 65 64 20 72 65 63 6f 72 64 73  f sorted records
8950: 20 73 74 61 72 74 69 6e 67 20 61 74 20 70 52 65   starting at pRe
8960: 63 6f 72 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  cord..*/.static 
8970: 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72 52  void vdbeSorterR
8980: 65 63 6f 72 64 46 72 65 65 28 73 71 6c 69 74 65  ecordFree(sqlite
8990: 33 20 2a 64 62 2c 20 53 6f 72 74 65 72 52 65 63  3 *db, SorterRec
89a0: 6f 72 64 20 2a 70 52 65 63 6f 72 64 29 7b 0a 20  ord *pRecord){. 
89b0: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
89c0: 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  ;.  SorterRecord
89d0: 20 2a 70 4e 65 78 74 3b 0a 20 20 66 6f 72 28 70   *pNext;.  for(p
89e0: 3d 70 52 65 63 6f 72 64 3b 20 70 3b 20 70 3d 70  =pRecord; p; p=p
89f0: 4e 65 78 74 29 7b 0a 20 20 20 20 70 4e 65 78 74  Next){.    pNext
8a00: 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20   = p->u.pNext;. 
8a10: 20 20 20 73 71 6c 69 74 65 33 44 62 46 72 65 65     sqlite3DbFree
8a20: 28 64 62 2c 20 70 29 3b 0a 20 20 7d 0a 7d 0a 0a  (db, p);.  }.}..
8a30: 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6c 6c 20 72  /*.** Free all r
8a40: 65 73 6f 75 72 63 65 73 20 6f 77 6e 65 64 20 62  esources owned b
8a50: 79 20 74 68 65 20 6f 62 6a 65 63 74 20 69 6e 64  y the object ind
8a60: 69 63 61 74 65 64 20 62 79 20 61 72 67 75 6d 65  icated by argume
8a70: 6e 74 20 70 54 61 73 6b 2e 20 41 6c 6c 20 0a 2a  nt pTask. All .*
8a80: 2a 20 66 69 65 6c 64 73 20 6f 66 20 2a 70 54 61  * fields of *pTa
8a90: 73 6b 20 61 72 65 20 7a 65 72 6f 65 64 20 62 65  sk are zeroed be
8aa0: 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a  fore returning..
8ab0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76  */.static void v
8ac0: 64 62 65 53 6f 72 74 53 75 62 74 61 73 6b 43 6c  dbeSortSubtaskCl
8ad0: 65 61 6e 75 70 28 73 71 6c 69 74 65 33 20 2a 64  eanup(sqlite3 *d
8ae0: 62 2c 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a  b, SortSubtask *
8af0: 70 54 61 73 6b 29 7b 0a 20 20 73 71 6c 69 74 65  pTask){.  sqlite
8b00: 33 44 62 46 72 65 65 28 64 62 2c 20 70 54 61 73  3DbFree(db, pTas
8b10: 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 29 3b 0a 20  k->pUnpacked);. 
8b20: 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65   pTask->pUnpacke
8b30: 64 20 3d 20 30 3b 0a 20 20 69 66 28 20 70 54 61  d = 0;.  if( pTa
8b40: 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  sk->list.aMemory
8b50: 3d 3d 30 20 29 7b 0a 20 20 20 20 76 64 62 65 53  ==0 ){.    vdbeS
8b60: 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65 65 28  orterRecordFree(
8b70: 30 2c 20 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 70  0, pTask->list.p
8b80: 4c 69 73 74 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  List);.  }else{.
8b90: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
8ba0: 28 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65  (pTask->list.aMe
8bb0: 6d 6f 72 79 29 3b 0a 20 20 20 20 70 54 61 73 6b  mory);.    pTask
8bc0: 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 3d  ->list.aMemory =
8bd0: 20 30 3b 0a 20 20 7d 0a 20 20 70 54 61 73 6b 2d   0;.  }.  pTask-
8be0: 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d 20 30 3b  >list.pList = 0;
8bf0: 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 66 69  .  if( pTask->fi
8c00: 6c 65 2e 70 46 64 20 29 7b 0a 20 20 20 20 73 71  le.pFd ){.    sq
8c10: 6c 69 74 65 33 4f 73 43 6c 6f 73 65 46 72 65 65  lite3OsCloseFree
8c20: 28 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64  (pTask->file.pFd
8c30: 29 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 66 69  );.    pTask->fi
8c40: 6c 65 2e 70 46 64 20 3d 20 30 3b 0a 20 20 20 20  le.pFd = 0;.    
8c50: 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66  pTask->file.iEof
8c60: 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20   = 0;.  }.  if( 
8c70: 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64  pTask->file2.pFd
8c80: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f   ){.    sqlite3O
8c90: 73 43 6c 6f 73 65 46 72 65 65 28 70 54 61 73 6b  sCloseFree(pTask
8ca0: 2d 3e 66 69 6c 65 32 2e 70 46 64 29 3b 0a 20 20  ->file2.pFd);.  
8cb0: 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70    pTask->file2.p
8cc0: 46 64 20 3d 20 30 3b 0a 20 20 20 20 70 54 61 73  Fd = 0;.    pTas
8cd0: 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 20 3d 20  k->file2.iEof = 
8ce0: 30 3b 0a 20 20 7d 0a 7d 0a 0a 23 69 66 64 65 66  0;.  }.}..#ifdef
8cf0: 20 53 51 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f   SQLITE_DEBUG_SO
8d00: 52 54 45 52 5f 54 48 52 45 41 44 53 0a 73 74 61  RTER_THREADS.sta
8d10: 74 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72  tic void vdbeSor
8d20: 74 65 72 57 6f 72 6b 44 65 62 75 67 28 53 6f 72  terWorkDebug(Sor
8d30: 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c  tSubtask *pTask,
8d40: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45 76   const char *zEv
8d50: 65 6e 74 29 7b 0a 20 20 69 36 34 20 74 3b 0a 20  ent){.  i64 t;. 
8d60: 20 69 6e 74 20 69 54 61 73 6b 20 3d 20 28 70 54   int iTask = (pT
8d70: 61 73 6b 20 2d 20 70 54 61 73 6b 2d 3e 70 53 6f  ask - pTask->pSo
8d80: 72 74 65 72 2d 3e 61 54 61 73 6b 29 3b 0a 20 20  rter->aTask);.  
8d90: 73 71 6c 69 74 65 33 4f 73 43 75 72 72 65 6e 74  sqlite3OsCurrent
8da0: 54 69 6d 65 49 6e 74 36 34 28 70 54 61 73 6b 2d  TimeInt64(pTask-
8db0: 3e 70 53 6f 72 74 65 72 2d 3e 64 62 2d 3e 70 56  >pSorter->db->pV
8dc0: 66 73 2c 20 26 74 29 3b 0a 20 20 66 70 72 69 6e  fs, &t);.  fprin
8dd0: 74 66 28 73 74 64 65 72 72 2c 20 22 25 6c 6c 64  tf(stderr, "%lld
8de0: 3a 25 64 20 25 73 5c 6e 22 2c 20 74 2c 20 69 54  :%d %s\n", t, iT
8df0: 61 73 6b 2c 20 7a 45 76 65 6e 74 29 3b 0a 7d 0a  ask, zEvent);.}.
8e00: 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65  static void vdbe
8e10: 53 6f 72 74 65 72 52 65 77 69 6e 64 44 65 62 75  SorterRewindDebu
8e20: 67 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45  g(const char *zE
8e30: 76 65 6e 74 29 7b 0a 20 20 69 36 34 20 74 3b 0a  vent){.  i64 t;.
8e40: 20 20 73 71 6c 69 74 65 33 4f 73 43 75 72 72 65    sqlite3OsCurre
8e50: 6e 74 54 69 6d 65 49 6e 74 36 34 28 73 71 6c 69  ntTimeInt64(sqli
8e60: 74 65 33 5f 76 66 73 5f 66 69 6e 64 28 30 29 2c  te3_vfs_find(0),
8e70: 20 26 74 29 3b 0a 20 20 66 70 72 69 6e 74 66 28   &t);.  fprintf(
8e80: 73 74 64 65 72 72 2c 20 22 25 6c 6c 64 3a 58 20  stderr, "%lld:X 
8e90: 25 73 5c 6e 22 2c 20 74 2c 20 7a 45 76 65 6e 74  %s\n", t, zEvent
8ea0: 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64  );.}.static void
8eb0: 20 76 64 62 65 53 6f 72 74 65 72 50 6f 70 75 6c   vdbeSorterPopul
8ec0: 61 74 65 44 65 62 75 67 28 0a 20 20 53 6f 72 74  ateDebug(.  Sort
8ed0: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 0a  Subtask *pTask,.
8ee0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45    const char *zE
8ef0: 76 65 6e 74 0a 29 7b 0a 20 20 69 36 34 20 74 3b  vent.){.  i64 t;
8f00: 0a 20 20 69 6e 74 20 69 54 61 73 6b 20 3d 20 28  .  int iTask = (
8f10: 70 54 61 73 6b 20 2d 20 70 54 61 73 6b 2d 3e 70  pTask - pTask->p
8f20: 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 29 3b 0a  Sorter->aTask);.
8f30: 20 20 73 71 6c 69 74 65 33 4f 73 43 75 72 72 65    sqlite3OsCurre
8f40: 6e 74 54 69 6d 65 49 6e 74 36 34 28 70 54 61 73  ntTimeInt64(pTas
8f50: 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 64 62 2d 3e  k->pSorter->db->
8f60: 70 56 66 73 2c 20 26 74 29 3b 0a 20 20 66 70 72  pVfs, &t);.  fpr
8f70: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25 6c  intf(stderr, "%l
8f80: 6c 64 3a 62 67 25 64 20 25 73 5c 6e 22 2c 20 74  ld:bg%d %s\n", t
8f90: 2c 20 69 54 61 73 6b 2c 20 7a 45 76 65 6e 74 29  , iTask, zEvent)
8fa0: 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20  ;.}.static void 
8fb0: 76 64 62 65 53 6f 72 74 65 72 42 6c 6f 63 6b 44  vdbeSorterBlockD
8fc0: 65 62 75 67 28 0a 20 20 53 6f 72 74 53 75 62 74  ebug(.  SortSubt
8fd0: 61 73 6b 20 2a 70 54 61 73 6b 2c 0a 20 20 69 6e  ask *pTask,.  in
8fe0: 74 20 62 42 6c 6f 63 6b 65 64 2c 0a 20 20 63 6f  t bBlocked,.  co
8ff0: 6e 73 74 20 63 68 61 72 20 2a 7a 45 76 65 6e 74  nst char *zEvent
9000: 0a 29 7b 0a 20 20 69 66 28 20 62 42 6c 6f 63 6b  .){.  if( bBlock
9010: 65 64 20 29 7b 0a 20 20 20 20 69 36 34 20 74 3b  ed ){.    i64 t;
9020: 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43 75  .    sqlite3OsCu
9030: 72 72 65 6e 74 54 69 6d 65 49 6e 74 36 34 28 70  rrentTimeInt64(p
9040: 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 64  Task->pSorter->d
9050: 62 2d 3e 70 56 66 73 2c 20 26 74 29 3b 0a 20 20  b->pVfs, &t);.  
9060: 20 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72    fprintf(stderr
9070: 2c 20 22 25 6c 6c 64 3a 6d 61 69 6e 20 25 73 5c  , "%lld:main %s\
9080: 6e 22 2c 20 74 2c 20 7a 45 76 65 6e 74 29 3b 0a  n", t, zEvent);.
9090: 20 20 7d 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65    }.}.#else.# de
90a0: 66 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72 57  fine vdbeSorterW
90b0: 6f 72 6b 44 65 62 75 67 28 78 2c 79 29 0a 23 20  orkDebug(x,y).# 
90c0: 64 65 66 69 6e 65 20 76 64 62 65 53 6f 72 74 65  define vdbeSorte
90d0: 72 52 65 77 69 6e 64 44 65 62 75 67 28 79 29 0a  rRewindDebug(y).
90e0: 23 20 64 65 66 69 6e 65 20 76 64 62 65 53 6f 72  # define vdbeSor
90f0: 74 65 72 50 6f 70 75 6c 61 74 65 44 65 62 75 67  terPopulateDebug
9100: 28 78 2c 79 29 0a 23 20 64 65 66 69 6e 65 20 76  (x,y).# define v
9110: 64 62 65 53 6f 72 74 65 72 42 6c 6f 63 6b 44 65  dbeSorterBlockDe
9120: 62 75 67 28 78 2c 79 2c 7a 29 0a 23 65 6e 64 69  bug(x,y,z).#endi
9130: 66 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41  f..#if SQLITE_MA
9140: 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53  X_WORKER_THREADS
9150: 3e 30 0a 2f 2a 0a 2a 2a 20 4a 6f 69 6e 20 74 68  >0./*.** Join th
9160: 72 65 61 64 20 70 54 61 73 6b 2d 3e 74 68 72 65  read pTask->thre
9170: 61 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ad..*/.static in
9180: 74 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e  t vdbeSorterJoin
9190: 54 68 72 65 61 64 28 53 6f 72 74 53 75 62 74 61  Thread(SortSubta
91a0: 73 6b 20 2a 70 54 61 73 6b 29 7b 0a 20 20 69 6e  sk *pTask){.  in
91b0: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
91c0: 3b 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 70  ;.  if( pTask->p
91d0: 54 68 72 65 61 64 20 29 7b 0a 23 69 66 64 65 66  Thread ){.#ifdef
91e0: 20 53 51 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f   SQLITE_DEBUG_SO
91f0: 52 54 45 52 5f 54 48 52 45 41 44 53 0a 20 20 20  RTER_THREADS.   
9200: 20 69 6e 74 20 62 44 6f 6e 65 20 3d 20 70 54 61   int bDone = pTa
9210: 73 6b 2d 3e 62 44 6f 6e 65 3b 0a 23 65 6e 64 69  sk->bDone;.#endi
9220: 66 0a 20 20 20 20 76 6f 69 64 20 2a 70 52 65 74  f.    void *pRet
9230: 3b 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65 72  ;.    vdbeSorter
9240: 42 6c 6f 63 6b 44 65 62 75 67 28 70 54 61 73 6b  BlockDebug(pTask
9250: 2c 20 21 62 44 6f 6e 65 2c 20 22 65 6e 74 65 72  , !bDone, "enter
9260: 22 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c  ");.    rc = sql
9270: 69 74 65 33 54 68 72 65 61 64 4a 6f 69 6e 28 70  ite3ThreadJoin(p
9280: 54 61 73 6b 2d 3e 70 54 68 72 65 61 64 2c 20 26  Task->pThread, &
9290: 70 52 65 74 29 3b 0a 20 20 20 20 76 64 62 65 53  pRet);.    vdbeS
92a0: 6f 72 74 65 72 42 6c 6f 63 6b 44 65 62 75 67 28  orterBlockDebug(
92b0: 70 54 61 73 6b 2c 20 21 62 44 6f 6e 65 2c 20 22  pTask, !bDone, "
92c0: 65 78 69 74 22 29 3b 0a 20 20 20 20 69 66 28 20  exit");.    if( 
92d0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc==SQLITE_OK ) 
92e0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 50 54 52 5f  rc = SQLITE_PTR_
92f0: 54 4f 5f 49 4e 54 28 70 52 65 74 29 3b 0a 20 20  TO_INT(pRet);.  
9300: 20 20 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d    assert( pTask-
9310: 3e 62 44 6f 6e 65 3d 3d 31 20 29 3b 0a 20 20 20  >bDone==1 );.   
9320: 20 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 20 3d 20   pTask->bDone = 
9330: 30 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 70 54  0;.    pTask->pT
9340: 68 72 65 61 64 20 3d 20 30 3b 0a 20 20 7d 0a 20  hread = 0;.  }. 
9350: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
9360: 2a 0a 2a 2a 20 4c 61 75 6e 63 68 20 61 20 62 61  *.** Launch a ba
9370: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
9380: 74 6f 20 72 75 6e 20 78 54 61 73 6b 28 70 49 6e  to run xTask(pIn
9390: 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  )..*/.static int
93a0: 20 76 64 62 65 53 6f 72 74 65 72 43 72 65 61 74   vdbeSorterCreat
93b0: 65 54 68 72 65 61 64 28 0a 20 20 53 6f 72 74 53  eThread(.  SortS
93c0: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20  ubtask *pTask,  
93d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
93e0: 72 65 61 64 20 77 69 6c 6c 20 75 73 65 20 74 68  read will use th
93f0: 69 73 20 74 61 73 6b 20 6f 62 6a 65 63 74 20 2a  is task object *
9400: 2f 0a 20 20 76 6f 69 64 20 2a 28 2a 78 54 61 73  /.  void *(*xTas
9410: 6b 29 28 76 6f 69 64 2a 29 2c 20 20 20 20 20 20  k)(void*),      
9420: 20 20 20 20 2f 2a 20 52 6f 75 74 69 6e 65 20 74      /* Routine t
9430: 6f 20 72 75 6e 20 69 6e 20 61 20 73 65 70 61 72  o run in a separ
9440: 61 74 65 20 74 68 72 65 61 64 20 2a 2f 0a 20 20  ate thread */.  
9450: 76 6f 69 64 20 2a 70 49 6e 20 20 20 20 20 20 20  void *pIn       
9460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9470: 2f 2a 20 41 72 67 75 6d 65 6e 74 20 70 61 73 73  /* Argument pass
9480: 65 64 20 69 6e 74 6f 20 78 54 61 73 6b 28 29 20  ed into xTask() 
9490: 2a 2f 0a 29 7b 0a 20 20 61 73 73 65 72 74 28 20  */.){.  assert( 
94a0: 70 54 61 73 6b 2d 3e 70 54 68 72 65 61 64 3d 3d  pTask->pThread==
94b0: 30 20 26 26 20 70 54 61 73 6b 2d 3e 62 44 6f 6e  0 && pTask->bDon
94c0: 65 3d 3d 30 20 29 3b 0a 20 20 72 65 74 75 72 6e  e==0 );.  return
94d0: 20 73 71 6c 69 74 65 33 54 68 72 65 61 64 43 72   sqlite3ThreadCr
94e0: 65 61 74 65 28 26 70 54 61 73 6b 2d 3e 70 54 68  eate(&pTask->pTh
94f0: 72 65 61 64 2c 20 78 54 61 73 6b 2c 20 70 49 6e  read, xTask, pIn
9500: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4a 6f 69 6e  );.}../*.** Join
9510: 20 61 6c 6c 20 6f 75 74 73 74 61 6e 64 69 6e 67   all outstanding
9520: 20 74 68 72 65 61 64 73 20 6c 61 75 6e 63 68 65   threads launche
9530: 64 20 62 79 20 53 6f 72 74 65 72 57 72 69 74 65  d by SorterWrite
9540: 28 29 20 74 6f 20 63 72 65 61 74 65 20 0a 2a 2a  () to create .**
9550: 20 6c 65 76 65 6c 2d 30 20 50 4d 41 73 2e 0a 2a   level-0 PMAs..*
9560: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
9570: 65 53 6f 72 74 65 72 4a 6f 69 6e 41 6c 6c 28 56  eSorterJoinAll(V
9580: 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
9590: 65 72 2c 20 69 6e 74 20 72 63 69 6e 29 7b 0a 20  er, int rcin){. 
95a0: 20 69 6e 74 20 72 63 20 3d 20 72 63 69 6e 3b 0a   int rc = rcin;.
95b0: 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69    int i;.  for(i
95c0: 3d 30 3b 20 69 3c 70 53 6f 72 74 65 72 2d 3e 6e  =0; i<pSorter->n
95d0: 54 61 73 6b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  Task; i++){.    
95e0: 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61  SortSubtask *pTa
95f0: 73 6b 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61  sk = &pSorter->a
9600: 54 61 73 6b 5b 69 5d 3b 0a 20 20 20 20 69 6e 74  Task[i];.    int
9610: 20 72 63 32 20 3d 20 76 64 62 65 53 6f 72 74 65   rc2 = vdbeSorte
9620: 72 4a 6f 69 6e 54 68 72 65 61 64 28 70 54 61 73  rJoinThread(pTas
9630: 6b 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  k);.    if( rc==
9640: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d  SQLITE_OK ) rc =
9650: 20 72 63 32 3b 0a 20 20 7d 0a 20 20 72 65 74 75   rc2;.  }.  retu
9660: 72 6e 20 72 63 3b 0a 7d 0a 23 65 6c 73 65 0a 23  rn rc;.}.#else.#
9670: 20 64 65 66 69 6e 65 20 76 64 62 65 53 6f 72 74   define vdbeSort
9680: 65 72 4a 6f 69 6e 41 6c 6c 28 78 2c 72 63 69 6e  erJoinAll(x,rcin
9690: 29 20 28 72 63 69 6e 29 0a 23 20 64 65 66 69 6e  ) (rcin).# defin
96a0: 65 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e  e vdbeSorterJoin
96b0: 54 68 72 65 61 64 28 70 54 61 73 6b 29 20 53 51  Thread(pTask) SQ
96c0: 4c 49 54 45 5f 4f 4b 0a 23 65 6e 64 69 66 0a 0a  LITE_OK.#endif..
96d0: 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61  /*.** Allocate a
96e0: 20 6e 65 77 20 4d 65 72 67 65 45 6e 67 69 6e 65   new MergeEngine
96f0: 20 6f 62 6a 65 63 74 20 77 69 74 68 20 73 70 61   object with spa
9700: 63 65 20 66 6f 72 20 6e 49 74 65 72 20 69 74 65  ce for nIter ite
9710: 72 61 74 6f 72 73 2e 0a 2a 2f 0a 73 74 61 74 69  rators..*/.stati
9720: 63 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 76  c MergeEngine *v
9730: 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4e 65  dbeMergeEngineNe
9740: 77 28 69 6e 74 20 6e 49 74 65 72 29 7b 0a 20 20  w(int nIter){.  
9750: 69 6e 74 20 4e 20 3d 20 32 3b 20 20 20 20 20 20  int N = 2;      
9760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9770: 2f 2a 20 53 6d 61 6c 6c 65 73 74 20 70 6f 77 65  /* Smallest powe
9780: 72 20 6f 66 20 74 77 6f 20 3e 3d 20 6e 49 74 65  r of two >= nIte
9790: 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65  r */.  int nByte
97a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
97b0: 20 20 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20         /* Total 
97c0: 62 79 74 65 73 20 6f 66 20 73 70 61 63 65 20 74  bytes of space t
97d0: 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20 20  o allocate */.  
97e0: 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4e 65  MergeEngine *pNe
97f0: 77 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  w;              
9800: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 61 6c  /* Pointer to al
9810: 6c 6f 63 61 74 65 64 20 6f 62 6a 65 63 74 20 74  located object t
9820: 6f 20 72 65 74 75 72 6e 20 2a 2f 0a 0a 20 20 61  o return */..  a
9830: 73 73 65 72 74 28 20 6e 49 74 65 72 3c 3d 53 4f  ssert( nIter<=SO
9840: 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
9850: 4f 55 4e 54 20 29 3b 0a 0a 20 20 77 68 69 6c 65  OUNT );..  while
9860: 28 20 4e 3c 6e 49 74 65 72 20 29 20 4e 20 2b 3d  ( N<nIter ) N +=
9870: 20 4e 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 69   N;.  nByte = si
9880: 7a 65 6f 66 28 4d 65 72 67 65 45 6e 67 69 6e 65  zeof(MergeEngine
9890: 29 20 2b 20 4e 20 2a 20 28 73 69 7a 65 6f 66 28  ) + N * (sizeof(
98a0: 69 6e 74 29 20 2b 20 73 69 7a 65 6f 66 28 50 6d  int) + sizeof(Pm
98b0: 61 52 65 61 64 65 72 29 29 3b 0a 0a 20 20 70 4e  aReader));..  pN
98c0: 65 77 20 3d 20 28 4d 65 72 67 65 45 6e 67 69 6e  ew = (MergeEngin
98d0: 65 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  e*)sqlite3Malloc
98e0: 5a 65 72 6f 28 6e 42 79 74 65 29 3b 0a 20 20 69  Zero(nByte);.  i
98f0: 66 28 20 70 4e 65 77 20 29 7b 0a 20 20 20 20 70  f( pNew ){.    p
9900: 4e 65 77 2d 3e 6e 54 72 65 65 20 3d 20 4e 3b 0a  New->nTree = N;.
9910: 20 20 20 20 70 4e 65 77 2d 3e 61 49 74 65 72 20      pNew->aIter 
9920: 3d 20 28 50 6d 61 52 65 61 64 65 72 2a 29 26 70  = (PmaReader*)&p
9930: 4e 65 77 5b 31 5d 3b 0a 20 20 20 20 70 4e 65 77  New[1];.    pNew
9940: 2d 3e 61 54 72 65 65 20 3d 20 28 69 6e 74 2a 29  ->aTree = (int*)
9950: 26 70 4e 65 77 2d 3e 61 49 74 65 72 5b 4e 5d 3b  &pNew->aIter[N];
9960: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 4e  .  }.  return pN
9970: 65 77 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65  ew;.}../*.** Fre
9980: 65 20 74 68 65 20 4d 65 72 67 65 45 6e 67 69 6e  e the MergeEngin
9990: 65 20 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20  e object passed 
99a0: 61 73 20 74 68 65 20 6f 6e 6c 79 20 61 72 67 75  as the only argu
99b0: 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ment..*/.static 
99c0: 76 6f 69 64 20 76 64 62 65 4d 65 72 67 65 45 6e  void vdbeMergeEn
99d0: 67 69 6e 65 46 72 65 65 28 4d 65 72 67 65 45 6e  gineFree(MergeEn
99e0: 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 29 7b 0a  gine *pMerger){.
99f0: 20 20 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 70    int i;.  if( p
9a00: 4d 65 72 67 65 72 20 29 7b 0a 20 20 20 20 66 6f  Merger ){.    fo
9a10: 72 28 69 3d 30 3b 20 69 3c 70 4d 65 72 67 65 72  r(i=0; i<pMerger
9a20: 2d 3e 6e 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20  ->nTree; i++){. 
9a30: 20 20 20 20 20 76 64 62 65 50 6d 61 52 65 61 64       vdbePmaRead
9a40: 65 72 43 6c 65 61 72 28 26 70 4d 65 72 67 65 72  erClear(&pMerger
9a50: 2d 3e 61 49 74 65 72 5b 69 5d 29 3b 0a 20 20 20  ->aIter[i]);.   
9a60: 20 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33   }.  }.  sqlite3
9a70: 5f 66 72 65 65 28 70 4d 65 72 67 65 72 29 3b 0a  _free(pMerger);.
9a80: 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6c  }../*.** Free al
9a90: 6c 20 72 65 73 6f 75 72 63 65 73 20 61 73 73 6f  l resources asso
9aa0: 63 69 61 74 65 64 20 77 69 74 68 20 74 68 65 20  ciated with the 
9ab0: 49 6e 63 72 4d 65 72 67 65 72 20 6f 62 6a 65 63  IncrMerger objec
9ac0: 74 20 69 6e 64 69 63 61 74 65 64 20 62 79 0a 2a  t indicated by.*
9ad0: 2a 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75  * the first argu
9ae0: 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ment..*/.static 
9af0: 76 6f 69 64 20 76 64 62 65 49 6e 63 72 46 72 65  void vdbeIncrFre
9b00: 65 28 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49  e(IncrMerger *pI
9b10: 6e 63 72 29 7b 0a 20 20 69 66 28 20 70 49 6e 63  ncr){.  if( pInc
9b20: 72 20 29 7b 0a 23 69 66 20 53 51 4c 49 54 45 5f  r ){.#if SQLITE_
9b30: 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41  MAX_WORKER_THREA
9b40: 44 53 3e 30 0a 20 20 20 20 69 66 28 20 70 49 6e  DS>0.    if( pIn
9b50: 63 72 2d 3e 62 55 73 65 54 68 72 65 61 64 20 29  cr->bUseThread )
9b60: 7b 0a 20 20 20 20 20 20 76 64 62 65 53 6f 72 74  {.      vdbeSort
9b70: 65 72 4a 6f 69 6e 54 68 72 65 61 64 28 70 49 6e  erJoinThread(pIn
9b80: 63 72 2d 3e 70 54 61 73 6b 29 3b 0a 20 20 20 20  cr->pTask);.    
9b90: 20 20 69 66 28 20 70 49 6e 63 72 2d 3e 61 46 69    if( pIncr->aFi
9ba0: 6c 65 5b 30 5d 2e 70 46 64 20 29 20 73 71 6c 69  le[0].pFd ) sqli
9bb0: 74 65 33 4f 73 43 6c 6f 73 65 46 72 65 65 28 70  te3OsCloseFree(p
9bc0: 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e 70  Incr->aFile[0].p
9bd0: 46 64 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70  Fd);.      if( p
9be0: 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 2e 70  Incr->aFile[1].p
9bf0: 46 64 20 29 20 73 71 6c 69 74 65 33 4f 73 43 6c  Fd ) sqlite3OsCl
9c00: 6f 73 65 46 72 65 65 28 70 49 6e 63 72 2d 3e 61  oseFree(pIncr->a
9c10: 46 69 6c 65 5b 31 5d 2e 70 46 64 29 3b 0a 20 20  File[1].pFd);.  
9c20: 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 20 20 76    }.#endif.    v
9c30: 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46 72  dbeMergeEngineFr
9c40: 65 65 28 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65  ee(pIncr->pMerge
9c50: 72 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  r);.    sqlite3_
9c60: 66 72 65 65 28 70 49 6e 63 72 29 3b 0a 20 20 7d  free(pIncr);.  }
9c70: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65 74 20  .}../*.** Reset 
9c80: 61 20 73 6f 72 74 69 6e 67 20 63 75 72 73 6f 72  a sorting cursor
9c90: 20 62 61 63 6b 20 74 6f 20 69 74 73 20 6f 72 69   back to its ori
9ca0: 67 69 6e 61 6c 20 65 6d 70 74 79 20 73 74 61 74  ginal empty stat
9cb0: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  e..*/.void sqlit
9cc0: 65 33 56 64 62 65 53 6f 72 74 65 72 52 65 73 65  e3VdbeSorterRese
9cd0: 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 56  t(sqlite3 *db, V
9ce0: 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
9cf0: 65 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  er){.  int i;.  
9d00: 28 76 6f 69 64 29 76 64 62 65 53 6f 72 74 65 72  (void)vdbeSorter
9d10: 4a 6f 69 6e 41 6c 6c 28 70 53 6f 72 74 65 72 2c  JoinAll(pSorter,
9d20: 20 53 51 4c 49 54 45 5f 4f 4b 29 3b 0a 20 20 69   SQLITE_OK);.  i
9d30: 66 28 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 61  f( pSorter->pRea
9d40: 64 65 72 20 29 7b 0a 20 20 20 20 76 64 62 65 50  der ){.    vdbeP
9d50: 6d 61 52 65 61 64 65 72 43 6c 65 61 72 28 70 53  maReaderClear(pS
9d60: 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72 29 3b  orter->pReader);
9d70: 0a 20 20 20 20 73 71 6c 69 74 65 33 44 62 46 72  .    sqlite3DbFr
9d80: 65 65 28 64 62 2c 20 70 53 6f 72 74 65 72 2d 3e  ee(db, pSorter->
9d90: 70 52 65 61 64 65 72 29 3b 0a 20 20 20 20 70 53  pReader);.    pS
9da0: 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72 20 3d  orter->pReader =
9db0: 20 30 3b 0a 20 20 7d 0a 20 20 76 64 62 65 4d 65   0;.  }.  vdbeMe
9dc0: 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28 70 53  rgeEngineFree(pS
9dd0: 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 29 3b  orter->pMerger);
9de0: 0a 20 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72  .  pSorter->pMer
9df0: 67 65 72 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69  ger = 0;.  for(i
9e00: 3d 30 3b 20 69 3c 70 53 6f 72 74 65 72 2d 3e 6e  =0; i<pSorter->n
9e10: 54 61 73 6b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  Task; i++){.    
9e20: 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61  SortSubtask *pTa
9e30: 73 6b 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61  sk = &pSorter->a
9e40: 54 61 73 6b 5b 69 5d 3b 0a 20 20 20 20 76 64 62  Task[i];.    vdb
9e50: 65 53 6f 72 74 53 75 62 74 61 73 6b 43 6c 65 61  eSortSubtaskClea
9e60: 6e 75 70 28 64 62 2c 20 70 54 61 73 6b 29 3b 0a  nup(db, pTask);.
9e70: 20 20 7d 0a 20 20 69 66 28 20 70 53 6f 72 74 65    }.  if( pSorte
9e80: 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 3d  r->list.aMemory=
9e90: 3d 30 20 29 7b 0a 20 20 20 20 76 64 62 65 53 6f  =0 ){.    vdbeSo
9ea0: 72 74 65 72 52 65 63 6f 72 64 46 72 65 65 28 30  rterRecordFree(0
9eb0: 2c 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e  , pSorter->list.
9ec0: 70 4c 69 73 74 29 3b 0a 20 20 7d 0a 20 20 70 53  pList);.  }.  pS
9ed0: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73  orter->list.pLis
9ee0: 74 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74 65 72  t = 0;.  pSorter
9ef0: 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 3d 20 30  ->list.szPMA = 0
9f00: 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 62 55 73  ;.  pSorter->bUs
9f10: 65 50 4d 41 20 3d 20 30 3b 0a 20 20 70 53 6f 72  ePMA = 0;.  pSor
9f20: 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 20 3d 20 30  ter->iMemory = 0
9f30: 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6d 78 4b  ;.  pSorter->mxK
9f40: 65 79 73 69 7a 65 20 3d 20 30 3b 0a 20 20 73 71  eysize = 0;.  sq
9f50: 6c 69 74 65 33 44 62 46 72 65 65 28 64 62 2c 20  lite3DbFree(db, 
9f60: 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b  pSorter->pUnpack
9f70: 65 64 29 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e  ed);.  pSorter->
9f80: 70 55 6e 70 61 63 6b 65 64 20 3d 20 30 3b 0a 7d  pUnpacked = 0;.}
9f90: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 79  ../*.** Free any
9fa0: 20 63 75 72 73 6f 72 20 63 6f 6d 70 6f 6e 65 6e   cursor componen
9fb0: 74 73 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20  ts allocated by 
9fc0: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
9fd0: 72 58 58 58 20 72 6f 75 74 69 6e 65 73 2e 0a 2a  rXXX routines..*
9fe0: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 56 64  /.void sqlite3Vd
9ff0: 62 65 53 6f 72 74 65 72 43 6c 6f 73 65 28 73 71  beSorterClose(sq
a000: 6c 69 74 65 33 20 2a 64 62 2c 20 56 64 62 65 43  lite3 *db, VdbeC
a010: 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20  ursor *pCsr){.  
a020: 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72  VdbeSorter *pSor
a030: 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72  ter = pCsr->pSor
a040: 74 65 72 3b 0a 20 20 69 66 28 20 70 53 6f 72 74  ter;.  if( pSort
a050: 65 72 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  er ){.    sqlite
a060: 33 56 64 62 65 53 6f 72 74 65 72 52 65 73 65 74  3VdbeSorterReset
a070: 28 64 62 2c 20 70 53 6f 72 74 65 72 29 3b 0a 20  (db, pSorter);. 
a080: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
a090: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d  pSorter->list.aM
a0a0: 65 6d 6f 72 79 29 3b 0a 20 20 20 20 73 71 6c 69  emory);.    sqli
a0b0: 74 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 53  te3DbFree(db, pS
a0c0: 6f 72 74 65 72 29 3b 0a 20 20 20 20 70 43 73 72  orter);.    pCsr
a0d0: 2d 3e 70 53 6f 72 74 65 72 20 3d 20 30 3b 0a 20  ->pSorter = 0;. 
a0e0: 20 7d 0a 7d 0a 0a 23 69 66 20 53 51 4c 49 54 45   }.}..#if SQLITE
a0f0: 5f 4d 41 58 5f 4d 4d 41 50 5f 53 49 5a 45 3e 30  _MAX_MMAP_SIZE>0
a100: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66 69 72 73 74  ./*.** The first
a110: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 61 20 66   argument is a f
a120: 69 6c 65 2d 68 61 6e 64 6c 65 20 6f 70 65 6e 20  ile-handle open 
a130: 6f 6e 20 61 20 74 65 6d 70 6f 72 61 72 79 20 66  on a temporary f
a140: 69 6c 65 2e 20 54 68 65 20 66 69 6c 65 0a 2a 2a  ile. The file.**
a150: 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 74   is guaranteed t
a160: 6f 20 62 65 20 6e 42 79 74 65 20 62 79 74 65 73  o be nByte bytes
a170: 20 6f 72 20 73 6d 61 6c 6c 65 72 20 69 6e 20 73   or smaller in s
a180: 69 7a 65 2e 20 54 68 69 73 20 66 75 6e 63 74 69  ize. This functi
a190: 6f 6e 0a 2a 2a 20 61 74 74 65 6d 70 74 73 20 74  on.** attempts t
a1a0: 6f 20 65 78 74 65 6e 64 20 74 68 65 20 66 69 6c  o extend the fil
a1b0: 65 20 74 6f 20 6e 42 79 74 65 20 62 79 74 65 73  e to nByte bytes
a1c0: 20 69 6e 20 73 69 7a 65 20 61 6e 64 20 74 6f 20   in size and to 
a1d0: 65 6e 73 75 72 65 20 74 68 61 74 0a 2a 2a 20 74  ensure that.** t
a1e0: 68 65 20 56 46 53 20 68 61 73 20 6d 65 6d 6f 72  he VFS has memor
a1f0: 79 20 6d 61 70 70 65 64 20 69 74 2e 0a 2a 2a 0a  y mapped it..**.
a200: 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e 6f  ** Whether or no
a210: 74 20 74 68 65 20 66 69 6c 65 20 64 6f 65 73 20  t the file does 
a220: 65 6e 64 20 75 70 20 6d 65 6d 6f 72 79 20 6d 61  end up memory ma
a230: 70 70 65 64 20 6f 66 20 63 6f 75 72 73 65 20 64  pped of course d
a240: 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20 74 68 65  epends on.** the
a250: 20 73 70 65 63 69 66 69 63 20 56 46 53 20 69 6d   specific VFS im
a260: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f  plementation..*/
a270: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62  .static void vdb
a280: 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46 69 6c  eSorterExtendFil
a290: 65 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 73  e(sqlite3 *db, s
a2a0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
a2b0: 6c 65 2c 20 69 36 34 20 6e 42 79 74 65 29 7b 0a  le, i64 nByte){.
a2c0: 20 20 69 66 28 20 6e 42 79 74 65 3c 3d 28 69 36    if( nByte<=(i6
a2d0: 34 29 28 64 62 2d 3e 6e 4d 61 78 53 6f 72 74 65  4)(db->nMaxSorte
a2e0: 72 4d 6d 61 70 29 20 29 7b 0a 20 20 20 20 69 6e  rMmap) ){.    in
a2f0: 74 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73  t rc = sqlite3Os
a300: 54 72 75 6e 63 61 74 65 28 70 46 69 6c 65 2c 20  Truncate(pFile, 
a310: 6e 42 79 74 65 29 3b 0a 20 20 20 20 69 66 28 20  nByte);.    if( 
a320: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
a330: 0a 20 20 20 20 20 20 76 6f 69 64 20 2a 70 20 3d  .      void *p =
a340: 20 30 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   0;.      sqlite
a350: 33 4f 73 46 65 74 63 68 28 70 46 69 6c 65 2c 20  3OsFetch(pFile, 
a360: 30 2c 20 28 69 6e 74 29 6e 42 79 74 65 2c 20 26  0, (int)nByte, &
a370: 70 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  p);.      sqlite
a380: 33 4f 73 55 6e 66 65 74 63 68 28 70 46 69 6c 65  3OsUnfetch(pFile
a390: 2c 20 30 2c 20 70 29 3b 0a 20 20 20 20 7d 0a 20  , 0, p);.    }. 
a3a0: 20 7d 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65 66   }.}.#else.# def
a3b0: 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72 45 78  ine vdbeSorterEx
a3c0: 74 65 6e 64 46 69 6c 65 28 78 2c 79 2c 7a 29 20  tendFile(x,y,z) 
a3d0: 53 51 4c 49 54 45 5f 4f 4b 0a 23 65 6e 64 69 66  SQLITE_OK.#endif
a3e0: 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65  ../*.** Allocate
a3f0: 20 73 70 61 63 65 20 66 6f 72 20 61 20 66 69 6c   space for a fil
a400: 65 2d 68 61 6e 64 6c 65 20 61 6e 64 20 6f 70 65  e-handle and ope
a410: 6e 20 61 20 74 65 6d 70 6f 72 61 72 79 20 66 69  n a temporary fi
a420: 6c 65 2e 20 49 66 20 73 75 63 63 65 73 73 66 75  le. If successfu
a430: 6c 2c 0a 2a 2a 20 73 65 74 20 2a 70 70 46 69 6c  l,.** set *ppFil
a440: 65 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68  e to point to th
a450: 65 20 6d 61 6c 6c 6f 63 27 64 20 66 69 6c 65 2d  e malloc'd file-
a460: 68 61 6e 64 6c 65 20 61 6e 64 20 72 65 74 75 72  handle and retur
a470: 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2a 20  n SQLITE_OK..** 
a480: 4f 74 68 65 72 77 69 73 65 2c 20 73 65 74 20 2a  Otherwise, set *
a490: 70 70 46 69 6c 65 20 74 6f 20 30 20 61 6e 64 20  ppFile to 0 and 
a4a0: 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74 65  return an SQLite
a4b0: 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2f 0a   error code..*/.
a4c0: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53  static int vdbeS
a4d0: 6f 72 74 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c  orterOpenTempFil
a4e0: 65 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  e(.  sqlite3 *db
a4f0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
a500: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
a510: 20 68 61 6e 64 6c 65 20 64 6f 69 6e 67 20 73 6f   handle doing so
a520: 72 74 20 2a 2f 0a 20 20 69 36 34 20 6e 45 78 74  rt */.  i64 nExt
a530: 65 6e 64 2c 20 20 20 20 20 20 20 20 20 20 20 20  end,            
a540: 20 20 20 20 20 20 20 20 2f 2a 20 41 74 74 65 6d          /* Attem
a550: 70 74 20 74 6f 20 65 78 74 65 6e 64 20 66 69 6c  pt to extend fil
a560: 65 20 74 6f 20 74 68 69 73 20 73 69 7a 65 20 2a  e to this size *
a570: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  /.  sqlite3_file
a580: 20 2a 2a 70 70 46 69 6c 65 0a 29 7b 0a 20 20 69   **ppFile.){.  i
a590: 6e 74 20 72 63 3b 0a 20 20 72 63 20 3d 20 73 71  nt rc;.  rc = sq
a5a0: 6c 69 74 65 33 4f 73 4f 70 65 6e 4d 61 6c 6c 6f  lite3OsOpenMallo
a5b0: 63 28 64 62 2d 3e 70 56 66 73 2c 20 30 2c 20 70  c(db->pVfs, 0, p
a5c0: 70 46 69 6c 65 2c 0a 20 20 20 20 20 20 53 51 4c  pFile,.      SQL
a5d0: 49 54 45 5f 4f 50 45 4e 5f 54 45 4d 50 5f 4a 4f  ITE_OPEN_TEMP_JO
a5e0: 55 52 4e 41 4c 20 7c 0a 20 20 20 20 20 20 53 51  URNAL |.      SQ
a5f0: 4c 49 54 45 5f 4f 50 45 4e 5f 52 45 41 44 57 52  LITE_OPEN_READWR
a600: 49 54 45 20 20 20 20 7c 20 53 51 4c 49 54 45 5f  ITE    | SQLITE_
a610: 4f 50 45 4e 5f 43 52 45 41 54 45 20 7c 0a 20 20  OPEN_CREATE |.  
a620: 20 20 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f      SQLITE_OPEN_
a630: 45 58 43 4c 55 53 49 56 45 20 20 20 20 7c 20 53  EXCLUSIVE    | S
a640: 51 4c 49 54 45 5f 4f 50 45 4e 5f 44 45 4c 45 54  QLITE_OPEN_DELET
a650: 45 4f 4e 43 4c 4f 53 45 2c 20 26 72 63 0a 20 20  EONCLOSE, &rc.  
a660: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  );.  if( rc==SQL
a670: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 36  ITE_OK ){.    i6
a680: 34 20 6d 61 78 20 3d 20 53 51 4c 49 54 45 5f 4d  4 max = SQLITE_M
a690: 41 58 5f 4d 4d 41 50 5f 53 49 5a 45 3b 0a 20 20  AX_MMAP_SIZE;.  
a6a0: 20 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 43    sqlite3OsFileC
a6b0: 6f 6e 74 72 6f 6c 48 69 6e 74 28 2a 70 70 46 69  ontrolHint(*ppFi
a6c0: 6c 65 2c 20 53 51 4c 49 54 45 5f 46 43 4e 54 4c  le, SQLITE_FCNTL
a6d0: 5f 4d 4d 41 50 5f 53 49 5a 45 2c 20 28 76 6f 69  _MMAP_SIZE, (voi
a6e0: 64 2a 29 26 6d 61 78 29 3b 0a 20 20 20 20 69 66  d*)&max);.    if
a6f0: 28 20 6e 45 78 74 65 6e 64 3e 30 20 29 7b 0a 20  ( nExtend>0 ){. 
a700: 20 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 45       vdbeSorterE
a710: 78 74 65 6e 64 46 69 6c 65 28 64 62 2c 20 2a 70  xtendFile(db, *p
a720: 70 46 69 6c 65 2c 20 6e 45 78 74 65 6e 64 29 3b  pFile, nExtend);
a730: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
a740: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
a750: 20 49 66 20 69 74 20 68 61 73 20 6e 6f 74 20 61   If it has not a
a760: 6c 72 65 61 64 79 20 62 65 65 6e 20 61 6c 6c 6f  lready been allo
a770: 63 61 74 65 64 2c 20 61 6c 6c 6f 63 61 74 65 20  cated, allocate 
a780: 74 68 65 20 55 6e 70 61 63 6b 65 64 52 65 63 6f  the UnpackedReco
a790: 72 64 20 0a 2a 2a 20 73 74 72 75 63 74 75 72 65  rd .** structure
a7a0: 20 61 74 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61   at pTask->pUnpa
a7b0: 63 6b 65 64 2e 20 52 65 74 75 72 6e 20 53 51 4c  cked. Return SQL
a7c0: 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73  ITE_OK if succes
a7d0: 73 66 75 6c 20 28 6f 72 20 0a 2a 2a 20 69 66 20  sful (or .** if 
a7e0: 6e 6f 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 77 61  no allocation wa
a7f0: 73 20 72 65 71 75 69 72 65 64 29 2c 20 6f 72 20  s required), or 
a800: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 6f 74 68  SQLITE_NOMEM oth
a810: 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69  erwise..*/.stati
a820: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 41 6c  c int vdbeSortAl
a830: 6c 6f 63 55 6e 70 61 63 6b 65 64 28 53 6f 72 74  locUnpacked(Sort
a840: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 29 7b  Subtask *pTask){
a850: 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 70 55  .  if( pTask->pU
a860: 6e 70 61 63 6b 65 64 3d 3d 30 20 29 7b 0a 20 20  npacked==0 ){.  
a870: 20 20 63 68 61 72 20 2a 70 46 72 65 65 3b 0a 20    char *pFree;. 
a880: 20 20 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63     pTask->pUnpac
a890: 6b 65 64 20 3d 20 73 71 6c 69 74 65 33 56 64 62  ked = sqlite3Vdb
a8a0: 65 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64 52 65  eAllocUnpackedRe
a8b0: 63 6f 72 64 28 0a 20 20 20 20 20 20 20 20 70 54  cord(.        pT
a8c0: 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 4b  ask->pSorter->pK
a8d0: 65 79 49 6e 66 6f 2c 20 30 2c 20 30 2c 20 26 70  eyInfo, 0, 0, &p
a8e0: 46 72 65 65 0a 20 20 20 20 29 3b 0a 20 20 20 20  Free.    );.    
a8f0: 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 70  assert( pTask->p
a900: 55 6e 70 61 63 6b 65 64 3d 3d 28 55 6e 70 61 63  Unpacked==(Unpac
a910: 6b 65 64 52 65 63 6f 72 64 2a 29 70 46 72 65 65  kedRecord*)pFree
a920: 20 29 3b 0a 20 20 20 20 69 66 28 20 70 46 72 65   );.    if( pFre
a930: 65 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  e==0 ) return SQ
a940: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
a950: 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64  pTask->pUnpacked
a960: 2d 3e 6e 46 69 65 6c 64 20 3d 20 70 54 61 73 6b  ->nField = pTask
a970: 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49  ->pSorter->pKeyI
a980: 6e 66 6f 2d 3e 6e 46 69 65 6c 64 3b 0a 20 20 20  nfo->nField;.   
a990: 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65   pTask->pUnpacke
a9a0: 64 2d 3e 65 72 72 43 6f 64 65 20 3d 20 30 3b 0a  d->errCode = 0;.
a9b0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c    }.  return SQL
a9c0: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  ITE_OK;.}.../*.*
a9d0: 2a 20 4d 65 72 67 65 20 74 68 65 20 74 77 6f 20  * Merge the two 
a9e0: 73 6f 72 74 65 64 20 6c 69 73 74 73 20 70 31 20  sorted lists p1 
a9f0: 61 6e 64 20 70 32 20 69 6e 74 6f 20 61 20 73 69  and p2 into a si
aa00: 6e 67 6c 65 20 6c 69 73 74 2e 0a 2a 2a 20 53 65  ngle list..** Se
aa10: 74 20 2a 70 70 4f 75 74 20 74 6f 20 74 68 65 20  t *ppOut to the 
aa20: 68 65 61 64 20 6f 66 20 74 68 65 20 6e 65 77 20  head of the new 
aa30: 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  list..*/.static 
aa40: 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72 4d  void vdbeSorterM
aa50: 65 72 67 65 28 0a 20 20 53 6f 72 74 53 75 62 74  erge(.  SortSubt
aa60: 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20 20 20  ask *pTask,     
aa70: 20 20 20 20 20 20 20 20 2f 2a 20 43 61 6c 6c 69          /* Calli
aa80: 6e 67 20 74 68 72 65 61 64 20 63 6f 6e 74 65 78  ng thread contex
aa90: 74 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63  t */.  SorterRec
aaa0: 6f 72 64 20 2a 70 31 2c 20 20 20 20 20 20 20 20  ord *p1,        
aab0: 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20         /* First 
aac0: 6c 69 73 74 20 74 6f 20 6d 65 72 67 65 20 2a 2f  list to merge */
aad0: 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20  .  SorterRecord 
aae0: 2a 70 32 2c 20 20 20 20 20 20 20 20 20 20 20 20  *p2,            
aaf0: 20 20 20 2f 2a 20 53 65 63 6f 6e 64 20 6c 69 73     /* Second lis
ab00: 74 20 74 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20  t to merge */.  
ab10: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 2a 70  SorterRecord **p
ab20: 70 4f 75 74 20 20 20 20 20 20 20 20 20 20 20 20  pOut            
ab30: 2f 2a 20 4f 55 54 3a 20 48 65 61 64 20 6f 66 20  /* OUT: Head of 
ab40: 6d 65 72 67 65 64 20 6c 69 73 74 20 2a 2f 0a 29  merged list */.)
ab50: 7b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  {.  SorterRecord
ab60: 20 2a 70 46 69 6e 61 6c 20 3d 20 30 3b 0a 20 20   *pFinal = 0;.  
ab70: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 2a 70  SorterRecord **p
ab80: 70 20 3d 20 26 70 46 69 6e 61 6c 3b 0a 20 20 76  p = &pFinal;.  v
ab90: 6f 69 64 20 2a 70 56 61 6c 32 20 3d 20 70 32 20  oid *pVal2 = p2 
aba0: 3f 20 53 52 56 41 4c 28 70 32 29 20 3a 20 30 3b  ? SRVAL(p2) : 0;
abb0: 0a 0a 20 20 77 68 69 6c 65 28 20 70 31 20 26 26  ..  while( p1 &&
abc0: 20 70 32 20 29 7b 0a 20 20 20 20 69 6e 74 20 72   p2 ){.    int r
abd0: 65 73 3b 0a 20 20 20 20 72 65 73 20 3d 20 76 64  es;.    res = vd
abe0: 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28  beSorterCompare(
abf0: 70 54 61 73 6b 2c 20 53 52 56 41 4c 28 70 31 29  pTask, SRVAL(p1)
ac00: 2c 20 70 31 2d 3e 6e 56 61 6c 2c 20 70 56 61 6c  , p1->nVal, pVal
ac10: 32 2c 20 70 32 2d 3e 6e 56 61 6c 29 3b 0a 20 20  2, p2->nVal);.  
ac20: 20 20 69 66 28 20 72 65 73 3c 3d 30 20 29 7b 0a    if( res<=0 ){.
ac30: 20 20 20 20 20 20 2a 70 70 20 3d 20 70 31 3b 0a        *pp = p1;.
ac40: 20 20 20 20 20 20 70 70 20 3d 20 26 70 31 2d 3e        pp = &p1->
ac50: 75 2e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70  u.pNext;.      p
ac60: 31 20 3d 20 70 31 2d 3e 75 2e 70 4e 65 78 74 3b  1 = p1->u.pNext;
ac70: 0a 20 20 20 20 20 20 70 56 61 6c 32 20 3d 20 30  .      pVal2 = 0
ac80: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
ac90: 20 20 20 2a 70 70 20 3d 20 70 32 3b 0a 20 20 20     *pp = p2;.   
aca0: 20 20 20 20 70 70 20 3d 20 26 70 32 2d 3e 75 2e      pp = &p2->u.
acb0: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 32 20  pNext;.      p2 
acc0: 3d 20 70 32 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20  = p2->u.pNext;. 
acd0: 20 20 20 20 20 69 66 28 20 70 32 3d 3d 30 20 29       if( p2==0 )
ace0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 70 56   break;.      pV
acf0: 61 6c 32 20 3d 20 53 52 56 41 4c 28 70 32 29 3b  al2 = SRVAL(p2);
ad00: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 70  .    }.  }.  *pp
ad10: 20 3d 20 70 31 20 3f 20 70 31 20 3a 20 70 32 3b   = p1 ? p1 : p2;
ad20: 0a 20 20 2a 70 70 4f 75 74 20 3d 20 70 46 69 6e  .  *ppOut = pFin
ad30: 61 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72  al;.}../*.** Sor
ad40: 74 20 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73  t the linked lis
ad50: 74 20 6f 66 20 72 65 63 6f 72 64 73 20 68 65 61  t of records hea
ad60: 64 65 64 20 61 74 20 70 54 61 73 6b 2d 3e 70 4c  ded at pTask->pL
ad70: 69 73 74 2e 20 52 65 74 75 72 6e 20 0a 2a 2a 20  ist. Return .** 
ad80: 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63  SQLITE_OK if suc
ad90: 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53  cessful, or an S
ada0: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
adb0: 20 28 69 2e 65 2e 20 53 51 4c 49 54 45 5f 4e 4f   (i.e. SQLITE_NO
adc0: 4d 45 4d 29 20 69 66 20 0a 2a 2a 20 61 6e 20 65  MEM) if .** an e
add0: 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a  rror occurs..*/.
ade0: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53  static int vdbeS
adf0: 6f 72 74 65 72 53 6f 72 74 28 53 6f 72 74 53 75  orterSort(SortSu
ae00: 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 53 6f  btask *pTask, So
ae10: 72 74 65 72 4c 69 73 74 20 2a 70 4c 69 73 74 29  rterList *pList)
ae20: 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 53 6f 72  {.  int i;.  Sor
ae30: 74 65 72 52 65 63 6f 72 64 20 2a 2a 61 53 6c 6f  terRecord **aSlo
ae40: 74 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72  t;.  SorterRecor
ae50: 64 20 2a 70 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  d *p;.  int rc;.
ae60: 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74  .  rc = vdbeSort
ae70: 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64 28 70 54  AllocUnpacked(pT
ae80: 61 73 6b 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  ask);.  if( rc!=
ae90: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
aea0: 72 6e 20 72 63 3b 0a 0a 20 20 61 53 6c 6f 74 20  rn rc;..  aSlot 
aeb0: 3d 20 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20  = (SorterRecord 
aec0: 2a 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  **)sqlite3Malloc
aed0: 5a 65 72 6f 28 36 34 20 2a 20 73 69 7a 65 6f 66  Zero(64 * sizeof
aee0: 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 29  (SorterRecord *)
aef0: 29 3b 0a 20 20 69 66 28 20 21 61 53 6c 6f 74 20  );.  if( !aSlot 
af00: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
af10: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a  LITE_NOMEM;.  }.
af20: 0a 20 20 70 20 3d 20 70 4c 69 73 74 2d 3e 70 4c  .  p = pList->pL
af30: 69 73 74 3b 0a 20 20 77 68 69 6c 65 28 20 70 20  ist;.  while( p 
af40: 29 7b 0a 20 20 20 20 53 6f 72 74 65 72 52 65 63  ){.    SorterRec
af50: 6f 72 64 20 2a 70 4e 65 78 74 3b 0a 20 20 20 20  ord *pNext;.    
af60: 69 66 28 20 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f  if( pList->aMemo
af70: 72 79 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  ry ){.      if( 
af80: 28 75 38 2a 29 70 3d 3d 70 4c 69 73 74 2d 3e 61  (u8*)p==pList->a
af90: 4d 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20 20  Memory ){.      
afa0: 20 20 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20    pNext = 0;.   
afb0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
afc0: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 75 2e 69    assert( p->u.i
afd0: 4e 65 78 74 3c 73 71 6c 69 74 65 33 4d 61 6c 6c  Next<sqlite3Mall
afe0: 6f 63 53 69 7a 65 28 70 4c 69 73 74 2d 3e 61 4d  ocSize(pList->aM
aff0: 65 6d 6f 72 79 29 20 29 3b 0a 20 20 20 20 20 20  emory) );.      
b000: 20 20 70 4e 65 78 74 20 3d 20 28 53 6f 72 74 65    pNext = (Sorte
b010: 72 52 65 63 6f 72 64 2a 29 26 70 4c 69 73 74 2d  rRecord*)&pList-
b020: 3e 61 4d 65 6d 6f 72 79 5b 70 2d 3e 75 2e 69 4e  >aMemory[p->u.iN
b030: 65 78 74 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20  ext];.      }.  
b040: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70    }else{.      p
b050: 4e 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78  Next = p->u.pNex
b060: 74 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 2d  t;.    }..    p-
b070: 3e 75 2e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20  >u.pNext = 0;.  
b080: 20 20 66 6f 72 28 69 3d 30 3b 20 61 53 6c 6f 74    for(i=0; aSlot
b090: 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  [i]; i++){.     
b0a0: 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65   vdbeSorterMerge
b0b0: 28 70 54 61 73 6b 2c 20 70 2c 20 61 53 6c 6f 74  (pTask, p, aSlot
b0c0: 5b 69 5d 2c 20 26 70 29 3b 0a 20 20 20 20 20 20  [i], &p);.      
b0d0: 61 53 6c 6f 74 5b 69 5d 20 3d 20 30 3b 0a 20 20  aSlot[i] = 0;.  
b0e0: 20 20 7d 0a 20 20 20 20 61 53 6c 6f 74 5b 69 5d    }.    aSlot[i]
b0f0: 20 3d 20 70 3b 0a 20 20 20 20 70 20 3d 20 70 4e   = p;.    p = pN
b100: 65 78 74 3b 0a 20 20 7d 0a 0a 20 20 70 20 3d 20  ext;.  }..  p = 
b110: 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  0;.  for(i=0; i<
b120: 36 34 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 76 64  64; i++){.    vd
b130: 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28 70 54  beSorterMerge(pT
b140: 61 73 6b 2c 20 70 2c 20 61 53 6c 6f 74 5b 69 5d  ask, p, aSlot[i]
b150: 2c 20 26 70 29 3b 0a 20 20 7d 0a 20 20 70 4c 69  , &p);.  }.  pLi
b160: 73 74 2d 3e 70 4c 69 73 74 20 3d 20 70 3b 0a 0a  st->pList = p;..
b170: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61    sqlite3_free(a
b180: 53 6c 6f 74 29 3b 0a 20 20 69 66 28 20 70 54 61  Slot);.  if( pTa
b190: 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 2d 3e 65  sk->pUnpacked->e
b1a0: 72 72 43 6f 64 65 20 29 7b 0a 20 20 20 20 61 73  rrCode ){.    as
b1b0: 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 70 55 6e  sert( pTask->pUn
b1c0: 70 61 63 6b 65 64 2d 3e 65 72 72 43 6f 64 65 3d  packed->errCode=
b1d0: 3d 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 29 3b  =SQLITE_NOMEM );
b1e0: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
b1f0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20  TE_NOMEM;.  }.  
b200: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
b210: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69  ;.}../*.** Initi
b220: 61 6c 69 7a 65 20 61 20 50 4d 41 2d 77 72 69 74  alize a PMA-writ
b230: 65 72 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74  er object..*/.st
b240: 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 50 6d  atic void vdbePm
b250: 61 57 72 69 74 65 72 49 6e 69 74 28 0a 20 20 73  aWriterInit(.  s
b260: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
b270: 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  le,            /
b280: 2a 20 46 69 6c 65 20 74 6f 20 77 72 69 74 65 20  * File to write 
b290: 74 6f 20 2a 2f 0a 20 20 50 6d 61 57 72 69 74 65  to */.  PmaWrite
b2a0: 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20  r *p,           
b2b0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63          /* Objec
b2c0: 74 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f  t to populate */
b2d0: 0a 20 20 69 6e 74 20 6e 42 75 66 2c 20 20 20 20  .  int nBuf,    
b2e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b2f0: 20 20 20 2f 2a 20 42 75 66 66 65 72 20 73 69 7a     /* Buffer siz
b300: 65 20 2a 2f 0a 20 20 69 36 34 20 69 53 74 61 72  e */.  i64 iStar
b310: 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t               
b320: 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74         /* Offset
b330: 20 6f 66 20 70 46 69 6c 65 20 74 6f 20 62 65 67   of pFile to beg
b340: 69 6e 20 77 72 69 74 69 6e 67 20 61 74 20 2a 2f  in writing at */
b350: 0a 29 7b 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20  .){.  memset(p, 
b360: 30 2c 20 73 69 7a 65 6f 66 28 50 6d 61 57 72 69  0, sizeof(PmaWri
b370: 74 65 72 29 29 3b 0a 20 20 70 2d 3e 61 42 75 66  ter));.  p->aBuf
b380: 66 65 72 20 3d 20 28 75 38 2a 29 73 71 6c 69 74  fer = (u8*)sqlit
b390: 65 33 4d 61 6c 6c 6f 63 28 6e 42 75 66 29 3b 0a  e3Malloc(nBuf);.
b3a0: 20 20 69 66 28 20 21 70 2d 3e 61 42 75 66 66 65    if( !p->aBuffe
b3b0: 72 20 29 7b 0a 20 20 20 20 70 2d 3e 65 46 57 45  r ){.    p->eFWE
b3c0: 72 72 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rr = SQLITE_NOME
b3d0: 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  M;.  }else{.    
b3e0: 70 2d 3e 69 42 75 66 45 6e 64 20 3d 20 70 2d 3e  p->iBufEnd = p->
b3f0: 69 42 75 66 53 74 61 72 74 20 3d 20 28 69 53 74  iBufStart = (iSt
b400: 61 72 74 20 25 20 6e 42 75 66 29 3b 0a 20 20 20  art % nBuf);.   
b410: 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20 3d 20   p->iWriteOff = 
b420: 69 53 74 61 72 74 20 2d 20 70 2d 3e 69 42 75 66  iStart - p->iBuf
b430: 53 74 61 72 74 3b 0a 20 20 20 20 70 2d 3e 6e 42  Start;.    p->nB
b440: 75 66 66 65 72 20 3d 20 6e 42 75 66 3b 0a 20 20  uffer = nBuf;.  
b450: 20 20 70 2d 3e 70 46 69 6c 65 20 3d 20 70 46 69    p->pFile = pFi
b460: 6c 65 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  le;.  }.}../*.**
b470: 20 57 72 69 74 65 20 6e 44 61 74 61 20 62 79 74   Write nData byt
b480: 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 74 68  es of data to th
b490: 65 20 50 4d 41 2e 20 52 65 74 75 72 6e 20 53 51  e PMA. Return SQ
b4a0: 4c 49 54 45 5f 4f 4b 0a 2a 2a 20 69 66 20 73 75  LITE_OK.** if su
b4b0: 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20  ccessful, or an 
b4c0: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
b4d0: 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  e if an error oc
b4e0: 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  curs..*/.static 
b4f0: 76 6f 69 64 20 76 64 62 65 50 6d 61 57 72 69 74  void vdbePmaWrit
b500: 65 42 6c 6f 62 28 50 6d 61 57 72 69 74 65 72 20  eBlob(PmaWriter 
b510: 2a 70 2c 20 75 38 20 2a 70 44 61 74 61 2c 20 69  *p, u8 *pData, i
b520: 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20 69 6e 74  nt nData){.  int
b530: 20 6e 52 65 6d 20 3d 20 6e 44 61 74 61 3b 0a 20   nRem = nData;. 
b540: 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30 20 26   while( nRem>0 &
b550: 26 20 70 2d 3e 65 46 57 45 72 72 3d 3d 30 20 29  & p->eFWErr==0 )
b560: 7b 0a 20 20 20 20 69 6e 74 20 6e 43 6f 70 79 20  {.    int nCopy 
b570: 3d 20 6e 52 65 6d 3b 0a 20 20 20 20 69 66 28 20  = nRem;.    if( 
b580: 6e 43 6f 70 79 3e 28 70 2d 3e 6e 42 75 66 66 65  nCopy>(p->nBuffe
b590: 72 20 2d 20 70 2d 3e 69 42 75 66 45 6e 64 29 20  r - p->iBufEnd) 
b5a0: 29 7b 0a 20 20 20 20 20 20 6e 43 6f 70 79 20 3d  ){.      nCopy =
b5b0: 20 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 70 2d   p->nBuffer - p-
b5c0: 3e 69 42 75 66 45 6e 64 3b 0a 20 20 20 20 7d 0a  >iBufEnd;.    }.
b5d0: 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d 3e  .    memcpy(&p->
b5e0: 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 45  aBuffer[p->iBufE
b5f0: 6e 64 5d 2c 20 26 70 44 61 74 61 5b 6e 44 61 74  nd], &pData[nDat
b600: 61 2d 6e 52 65 6d 5d 2c 20 6e 43 6f 70 79 29 3b  a-nRem], nCopy);
b610: 0a 20 20 20 20 70 2d 3e 69 42 75 66 45 6e 64 20  .    p->iBufEnd 
b620: 2b 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 69 66  += nCopy;.    if
b630: 28 20 70 2d 3e 69 42 75 66 45 6e 64 3d 3d 70 2d  ( p->iBufEnd==p-
b640: 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20  >nBuffer ){.    
b650: 20 20 70 2d 3e 65 46 57 45 72 72 20 3d 20 73 71    p->eFWErr = sq
b660: 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d 3e  lite3OsWrite(p->
b670: 70 46 69 6c 65 2c 20 0a 20 20 20 20 20 20 20 20  pFile, .        
b680: 20 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 70 2d    &p->aBuffer[p-
b690: 3e 69 42 75 66 53 74 61 72 74 5d 2c 20 70 2d 3e  >iBufStart], p->
b6a0: 69 42 75 66 45 6e 64 20 2d 20 70 2d 3e 69 42 75  iBufEnd - p->iBu
b6b0: 66 53 74 61 72 74 2c 20 0a 20 20 20 20 20 20 20  fStart, .       
b6c0: 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20     p->iWriteOff 
b6d0: 2b 20 70 2d 3e 69 42 75 66 53 74 61 72 74 0a 20  + p->iBufStart. 
b6e0: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 70 2d       );.      p-
b6f0: 3e 69 42 75 66 53 74 61 72 74 20 3d 20 70 2d 3e  >iBufStart = p->
b700: 69 42 75 66 45 6e 64 20 3d 20 30 3b 0a 20 20 20  iBufEnd = 0;.   
b710: 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20     p->iWriteOff 
b720: 2b 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20  += p->nBuffer;. 
b730: 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28     }.    assert(
b740: 20 70 2d 3e 69 42 75 66 45 6e 64 3c 70 2d 3e 6e   p->iBufEnd<p->n
b750: 42 75 66 66 65 72 20 29 3b 0a 0a 20 20 20 20 6e  Buffer );..    n
b760: 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20  Rem -= nCopy;.  
b770: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68  }.}../*.** Flush
b780: 20 61 6e 79 20 62 75 66 66 65 72 65 64 20 64 61   any buffered da
b790: 74 61 20 74 6f 20 64 69 73 6b 20 61 6e 64 20 63  ta to disk and c
b7a0: 6c 65 61 6e 20 75 70 20 74 68 65 20 50 4d 41 2d  lean up the PMA-
b7b0: 77 72 69 74 65 72 20 6f 62 6a 65 63 74 2e 0a 2a  writer object..*
b7c0: 2a 20 54 68 65 20 72 65 73 75 6c 74 73 20 6f 66  * The results of
b7d0: 20 75 73 69 6e 67 20 74 68 65 20 50 4d 41 2d 77   using the PMA-w
b7e0: 72 69 74 65 72 20 61 66 74 65 72 20 74 68 69 73  riter after this
b7f0: 20 63 61 6c 6c 20 61 72 65 20 75 6e 64 65 66 69   call are undefi
b800: 6e 65 64 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 53  ned..** Return S
b810: 51 4c 49 54 45 5f 4f 4b 20 69 66 20 66 6c 75 73  QLITE_OK if flus
b820: 68 69 6e 67 20 74 68 65 20 62 75 66 66 65 72 65  hing the buffere
b830: 64 20 64 61 74 61 20 73 75 63 63 65 65 64 73 20  d data succeeds 
b840: 6f 72 20 69 73 20 6e 6f 74 20 0a 2a 2a 20 72 65  or is not .** re
b850: 71 75 69 72 65 64 2e 20 4f 74 68 65 72 77 69 73  quired. Otherwis
b860: 65 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c  e, return an SQL
b870: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a  ite error code..
b880: 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65 20 72 65 74  **.** Before ret
b890: 75 72 6e 69 6e 67 2c 20 73 65 74 20 2a 70 69 45  urning, set *piE
b8a0: 6f 66 20 74 6f 20 74 68 65 20 6f 66 66 73 65 74  of to the offset
b8b0: 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c   immediately fol
b8c0: 6c 6f 77 69 6e 67 20 74 68 65 0a 2a 2a 20 6c 61  lowing the.** la
b8d0: 73 74 20 62 79 74 65 20 77 72 69 74 74 65 6e 20  st byte written 
b8e0: 74 6f 20 74 68 65 20 66 69 6c 65 2e 0a 2a 2f 0a  to the file..*/.
b8f0: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 50  static int vdbeP
b900: 6d 61 57 72 69 74 65 72 46 69 6e 69 73 68 28 50  maWriterFinish(P
b910: 6d 61 57 72 69 74 65 72 20 2a 70 2c 20 69 36 34  maWriter *p, i64
b920: 20 2a 70 69 45 6f 66 29 7b 0a 20 20 69 6e 74 20   *piEof){.  int 
b930: 72 63 3b 0a 20 20 69 66 28 20 70 2d 3e 65 46 57  rc;.  if( p->eFW
b940: 45 72 72 3d 3d 30 20 26 26 20 41 4c 57 41 59 53  Err==0 && ALWAYS
b950: 28 70 2d 3e 61 42 75 66 66 65 72 29 20 26 26 20  (p->aBuffer) && 
b960: 70 2d 3e 69 42 75 66 45 6e 64 3e 70 2d 3e 69 42  p->iBufEnd>p->iB
b970: 75 66 53 74 61 72 74 20 29 7b 0a 20 20 20 20 70  ufStart ){.    p
b980: 2d 3e 65 46 57 45 72 72 20 3d 20 73 71 6c 69 74  ->eFWErr = sqlit
b990: 65 33 4f 73 57 72 69 74 65 28 70 2d 3e 70 46 69  e3OsWrite(p->pFi
b9a0: 6c 65 2c 20 0a 20 20 20 20 20 20 20 20 26 70 2d  le, .        &p-
b9b0: 3e 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66  >aBuffer[p->iBuf
b9c0: 53 74 61 72 74 5d 2c 20 70 2d 3e 69 42 75 66 45  Start], p->iBufE
b9d0: 6e 64 20 2d 20 70 2d 3e 69 42 75 66 53 74 61 72  nd - p->iBufStar
b9e0: 74 2c 20 0a 20 20 20 20 20 20 20 20 70 2d 3e 69  t, .        p->i
b9f0: 57 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42  WriteOff + p->iB
ba00: 75 66 53 74 61 72 74 0a 20 20 20 20 29 3b 0a 20  ufStart.    );. 
ba10: 20 7d 0a 20 20 2a 70 69 45 6f 66 20 3d 20 28 70   }.  *piEof = (p
ba20: 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b 20 70 2d  ->iWriteOff + p-
ba30: 3e 69 42 75 66 45 6e 64 29 3b 0a 20 20 73 71 6c  >iBufEnd);.  sql
ba40: 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 42 75  ite3_free(p->aBu
ba50: 66 66 65 72 29 3b 0a 20 20 72 63 20 3d 20 70 2d  ffer);.  rc = p-
ba60: 3e 65 46 57 45 72 72 3b 0a 20 20 6d 65 6d 73 65  >eFWErr;.  memse
ba70: 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50  t(p, 0, sizeof(P
ba80: 6d 61 57 72 69 74 65 72 29 29 3b 0a 20 20 72 65  maWriter));.  re
ba90: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
baa0: 2a 20 57 72 69 74 65 20 76 61 6c 75 65 20 69 56  * Write value iV
bab0: 61 6c 20 65 6e 63 6f 64 65 64 20 61 73 20 61 20  al encoded as a 
bac0: 76 61 72 69 6e 74 20 74 6f 20 74 68 65 20 50 4d  varint to the PM
bad0: 41 2e 20 52 65 74 75 72 6e 20 0a 2a 2a 20 53 51  A. Return .** SQ
bae0: 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65  LITE_OK if succe
baf0: 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c  ssful, or an SQL
bb00: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69  ite error code i
bb10: 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
bb20: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  s..*/.static voi
bb30: 64 20 76 64 62 65 50 6d 61 57 72 69 74 65 56 61  d vdbePmaWriteVa
bb40: 72 69 6e 74 28 50 6d 61 57 72 69 74 65 72 20 2a  rint(PmaWriter *
bb50: 70 2c 20 75 36 34 20 69 56 61 6c 29 7b 0a 20 20  p, u64 iVal){.  
bb60: 69 6e 74 20 6e 42 79 74 65 3b 20 0a 20 20 75 38  int nByte; .  u8
bb70: 20 61 42 79 74 65 5b 31 30 5d 3b 0a 20 20 6e 42   aByte[10];.  nB
bb80: 79 74 65 20 3d 20 73 71 6c 69 74 65 33 50 75 74  yte = sqlite3Put
bb90: 56 61 72 69 6e 74 28 61 42 79 74 65 2c 20 69 56  Varint(aByte, iV
bba0: 61 6c 29 3b 0a 20 20 76 64 62 65 50 6d 61 57 72  al);.  vdbePmaWr
bbb0: 69 74 65 42 6c 6f 62 28 70 2c 20 61 42 79 74 65  iteBlob(p, aByte
bbc0: 2c 20 6e 42 79 74 65 29 3b 0a 7d 0a 0a 2f 2a 0a  , nByte);.}../*.
bbd0: 2a 2a 20 57 72 69 74 65 20 74 68 65 20 63 75 72  ** Write the cur
bbe0: 72 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f 66  rent contents of
bbf0: 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 6e 6b 65   in-memory linke
bc00: 64 2d 6c 69 73 74 20 70 4c 69 73 74 20 74 6f 20  d-list pList to 
bc10: 61 20 6c 65 76 65 6c 2d 30 0a 2a 2a 20 50 4d 41  a level-0.** PMA
bc20: 20 69 6e 20 74 68 65 20 74 65 6d 70 20 66 69 6c   in the temp fil
bc30: 65 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 73  e belonging to s
bc40: 75 62 2d 74 61 73 6b 20 70 54 61 73 6b 2e 20 52  ub-task pTask. R
bc50: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20  eturn SQLITE_OK 
bc60: 69 66 20 0a 2a 2a 20 73 75 63 63 65 73 73 66 75  if .** successfu
bc70: 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20  l, or an SQLite 
bc80: 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72  error code other
bc90: 77 69 73 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  wise..**.** The 
bca0: 66 6f 72 6d 61 74 20 6f 66 20 61 20 50 4d 41 20  format of a PMA 
bcb0: 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20  is:.**.**     * 
bcc0: 41 20 76 61 72 69 6e 74 2e 20 54 68 69 73 20 76  A varint. This v
bcd0: 61 72 69 6e 74 20 63 6f 6e 74 61 69 6e 73 20 74  arint contains t
bce0: 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20  he total number 
bcf0: 6f 66 20 62 79 74 65 73 20 6f 66 20 63 6f 6e 74  of bytes of cont
bd00: 65 6e 74 0a 2a 2a 20 20 20 20 20 20 20 69 6e 20  ent.**       in 
bd10: 74 68 65 20 50 4d 41 20 28 6e 6f 74 20 69 6e 63  the PMA (not inc
bd20: 6c 75 64 69 6e 67 20 74 68 65 20 76 61 72 69 6e  luding the varin
bd30: 74 20 69 74 73 65 6c 66 29 2e 0a 2a 2a 0a 2a 2a  t itself)..**.**
bd40: 20 20 20 20 20 2a 20 4f 6e 65 20 6f 72 20 6d 6f       * One or mo
bd50: 72 65 20 72 65 63 6f 72 64 73 20 70 61 63 6b 65  re records packe
bd60: 64 20 65 6e 64 2d 74 6f 2d 65 6e 64 20 69 6e 20  d end-to-end in 
bd70: 6f 72 64 65 72 20 6f 66 20 61 73 63 65 6e 64 69  order of ascendi
bd80: 6e 67 20 6b 65 79 73 2e 20 0a 2a 2a 20 20 20 20  ng keys. .**    
bd90: 20 20 20 45 61 63 68 20 72 65 63 6f 72 64 20 63     Each record c
bda0: 6f 6e 73 69 73 74 73 20 6f 66 20 61 20 76 61 72  onsists of a var
bdb0: 69 6e 74 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20  int followed by 
bdc0: 61 20 62 6c 6f 62 20 6f 66 20 64 61 74 61 20 28  a blob of data (
bdd0: 74 68 65 20 0a 2a 2a 20 20 20 20 20 20 20 6b 65  the .**       ke
bde0: 79 29 2e 20 54 68 65 20 76 61 72 69 6e 74 20 69  y). The varint i
bdf0: 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  s the number of 
be00: 62 79 74 65 73 20 69 6e 20 74 68 65 20 62 6c 6f  bytes in the blo
be10: 62 20 6f 66 20 64 61 74 61 2e 0a 2a 2f 0a 73 74  b of data..*/.st
be20: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
be30: 74 65 72 4c 69 73 74 54 6f 50 4d 41 28 53 6f 72  terListToPMA(Sor
be40: 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c  tSubtask *pTask,
be50: 20 53 6f 72 74 65 72 4c 69 73 74 20 2a 70 4c 69   SorterList *pLi
be60: 73 74 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a  st){.  sqlite3 *
be70: 64 62 20 3d 20 70 54 61 73 6b 2d 3e 70 53 6f 72  db = pTask->pSor
be80: 74 65 72 2d 3e 64 62 3b 0a 20 20 69 6e 74 20 72  ter->db;.  int r
be90: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20  c = SQLITE_OK;  
bea0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
beb0: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 50  turn code */.  P
bec0: 6d 61 57 72 69 74 65 72 20 77 72 69 74 65 72 3b  maWriter writer;
bed0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
bee0: 2a 20 4f 62 6a 65 63 74 20 75 73 65 64 20 74 6f  * Object used to
bef0: 20 77 72 69 74 65 20 74 6f 20 74 68 65 20 66 69   write to the fi
bf00: 6c 65 20 2a 2f 0a 0a 23 69 66 64 65 66 20 53 51  le */..#ifdef SQ
bf10: 4c 49 54 45 5f 44 45 42 55 47 0a 20 20 2f 2a 20  LITE_DEBUG.  /* 
bf20: 53 65 74 20 69 53 7a 20 74 6f 20 74 68 65 20 65  Set iSz to the e
bf30: 78 70 65 63 74 65 64 20 73 69 7a 65 20 6f 66 20  xpected size of 
bf40: 66 69 6c 65 20 70 54 61 73 6b 2d 3e 66 69 6c 65  file pTask->file
bf50: 20 61 66 74 65 72 20 77 72 69 74 69 6e 67 20 74   after writing t
bf60: 68 65 20 50 4d 41 2e 20 0a 20 20 2a 2a 20 54 68  he PMA. .  ** Th
bf70: 69 73 20 69 73 20 75 73 65 64 20 62 79 20 61 6e  is is used by an
bf80: 20 61 73 73 65 72 74 28 29 20 73 74 61 74 65 6d   assert() statem
bf90: 65 6e 74 20 61 74 20 74 68 65 20 65 6e 64 20 6f  ent at the end o
bfa0: 66 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 2e  f this function.
bfb0: 20 20 2a 2f 0a 20 20 69 36 34 20 69 53 7a 20 3d    */.  i64 iSz =
bfc0: 20 70 4c 69 73 74 2d 3e 73 7a 50 4d 41 20 2b 20   pList->szPMA + 
bfd0: 73 71 6c 69 74 65 33 56 61 72 69 6e 74 4c 65 6e  sqlite3VarintLen
bfe0: 28 70 4c 69 73 74 2d 3e 73 7a 50 4d 41 29 20 2b  (pList->szPMA) +
bff0: 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f   pTask->file.iEo
c000: 66 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 76 64 62  f;.#endif..  vdb
c010: 65 53 6f 72 74 65 72 57 6f 72 6b 44 65 62 75 67  eSorterWorkDebug
c020: 28 70 54 61 73 6b 2c 20 22 65 6e 74 65 72 22 29  (pTask, "enter")
c030: 3b 0a 20 20 6d 65 6d 73 65 74 28 26 77 72 69 74  ;.  memset(&writ
c040: 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50 6d  er, 0, sizeof(Pm
c050: 61 57 72 69 74 65 72 29 29 3b 0a 20 20 61 73 73  aWriter));.  ass
c060: 65 72 74 28 20 70 4c 69 73 74 2d 3e 73 7a 50 4d  ert( pList->szPM
c070: 41 3e 30 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20  A>0 );..  /* If 
c080: 74 68 65 20 66 69 72 73 74 20 74 65 6d 70 6f 72  the first tempor
c090: 61 72 79 20 50 4d 41 20 66 69 6c 65 20 68 61 73  ary PMA file has
c0a0: 20 6e 6f 74 20 62 65 65 6e 20 6f 70 65 6e 65 64   not been opened
c0b0: 2c 20 6f 70 65 6e 20 69 74 20 6e 6f 77 2e 20 2a  , open it now. *
c0c0: 2f 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 66  /.  if( pTask->f
c0d0: 69 6c 65 2e 70 46 64 3d 3d 30 20 29 7b 0a 20 20  ile.pFd==0 ){.  
c0e0: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
c0f0: 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 64 62  rOpenTempFile(db
c100: 2c 20 30 2c 20 26 70 54 61 73 6b 2d 3e 66 69 6c  , 0, &pTask->fil
c110: 65 2e 70 46 64 29 3b 0a 20 20 20 20 61 73 73 65  e.pFd);.    asse
c120: 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  rt( rc!=SQLITE_O
c130: 4b 20 7c 7c 20 70 54 61 73 6b 2d 3e 66 69 6c 65  K || pTask->file
c140: 2e 70 46 64 20 29 3b 0a 20 20 20 20 61 73 73 65  .pFd );.    asse
c150: 72 74 28 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e  rt( pTask->file.
c160: 69 45 6f 66 3d 3d 30 20 29 3b 0a 20 20 20 20 61  iEof==0 );.    a
c170: 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 6e 50  ssert( pTask->nP
c180: 4d 41 3d 3d 30 20 29 3b 0a 20 20 7d 0a 0a 20 20  MA==0 );.  }..  
c190: 2f 2a 20 54 72 79 20 74 6f 20 67 65 74 20 74 68  /* Try to get th
c1a0: 65 20 66 69 6c 65 20 74 6f 20 6d 65 6d 6f 72 79  e file to memory
c1b0: 20 6d 61 70 20 2a 2f 0a 20 20 69 66 28 20 72 63   map */.  if( rc
c1c0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
c1d0: 20 20 20 76 64 62 65 53 6f 72 74 65 72 45 78 74     vdbeSorterExt
c1e0: 65 6e 64 46 69 6c 65 28 64 62 2c 20 70 54 61 73  endFile(db, pTas
c1f0: 6b 2d 3e 66 69 6c 65 2e 70 46 64 2c 20 70 54 61  k->file.pFd, pTa
c200: 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 2b 70 4c  sk->file.iEof+pL
c210: 69 73 74 2d 3e 73 7a 50 4d 41 2b 39 29 3b 0a 20  ist->szPMA+9);. 
c220: 20 7d 0a 0a 20 20 2f 2a 20 53 6f 72 74 20 74 68   }..  /* Sort th
c230: 65 20 6c 69 73 74 20 2a 2f 0a 20 20 69 66 28 20  e list */.  if( 
c240: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
c250: 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f  .    rc = vdbeSo
c260: 72 74 65 72 53 6f 72 74 28 70 54 61 73 6b 2c 20  rterSort(pTask, 
c270: 70 4c 69 73 74 29 3b 0a 20 20 7d 0a 0a 20 20 69  pList);.  }..  i
c280: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
c290: 20 29 7b 0a 20 20 20 20 53 6f 72 74 65 72 52 65   ){.    SorterRe
c2a0: 63 6f 72 64 20 2a 70 3b 0a 20 20 20 20 53 6f 72  cord *p;.    Sor
c2b0: 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65 78 74  terRecord *pNext
c2c0: 20 3d 20 30 3b 0a 0a 20 20 20 20 76 64 62 65 50   = 0;..    vdbeP
c2d0: 6d 61 57 72 69 74 65 72 49 6e 69 74 28 70 54 61  maWriterInit(pTa
c2e0: 73 6b 2d 3e 66 69 6c 65 2e 70 46 64 2c 20 26 77  sk->file.pFd, &w
c2f0: 72 69 74 65 72 2c 20 70 54 61 73 6b 2d 3e 70 53  riter, pTask->pS
c300: 6f 72 74 65 72 2d 3e 70 67 73 7a 2c 0a 20 20 20  orter->pgsz,.   
c310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c320: 20 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69     pTask->file.i
c330: 45 6f 66 29 3b 0a 20 20 20 20 70 54 61 73 6b 2d  Eof);.    pTask-
c340: 3e 6e 50 4d 41 2b 2b 3b 0a 20 20 20 20 76 64 62  >nPMA++;.    vdb
c350: 65 50 6d 61 57 72 69 74 65 56 61 72 69 6e 74 28  ePmaWriteVarint(
c360: 26 77 72 69 74 65 72 2c 20 70 4c 69 73 74 2d 3e  &writer, pList->
c370: 73 7a 50 4d 41 29 3b 0a 20 20 20 20 66 6f 72 28  szPMA);.    for(
c380: 70 3d 70 4c 69 73 74 2d 3e 70 4c 69 73 74 3b 20  p=pList->pList; 
c390: 70 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20  p; p=pNext){.   
c3a0: 20 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e 75 2e     pNext = p->u.
c3b0: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 76 64 62  pNext;.      vdb
c3c0: 65 50 6d 61 57 72 69 74 65 56 61 72 69 6e 74 28  ePmaWriteVarint(
c3d0: 26 77 72 69 74 65 72 2c 20 70 2d 3e 6e 56 61 6c  &writer, p->nVal
c3e0: 29 3b 0a 20 20 20 20 20 20 76 64 62 65 50 6d 61  );.      vdbePma
c3f0: 57 72 69 74 65 42 6c 6f 62 28 26 77 72 69 74 65  WriteBlob(&write
c400: 72 2c 20 53 52 56 41 4c 28 70 29 2c 20 70 2d 3e  r, SRVAL(p), p->
c410: 6e 56 61 6c 29 3b 0a 20 20 20 20 20 20 69 66 28  nVal);.      if(
c420: 20 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f 72 79 3d   pList->aMemory=
c430: 3d 30 20 29 20 73 71 6c 69 74 65 33 5f 66 72 65  =0 ) sqlite3_fre
c440: 65 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  e(p);.    }.    
c450: 70 4c 69 73 74 2d 3e 70 4c 69 73 74 20 3d 20 70  pList->pList = p
c460: 3b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 50  ;.    rc = vdbeP
c470: 6d 61 57 72 69 74 65 72 46 69 6e 69 73 68 28 26  maWriterFinish(&
c480: 77 72 69 74 65 72 2c 20 26 70 54 61 73 6b 2d 3e  writer, &pTask->
c490: 66 69 6c 65 2e 69 45 6f 66 29 3b 0a 20 20 7d 0a  file.iEof);.  }.
c4a0: 0a 20 20 76 64 62 65 53 6f 72 74 65 72 57 6f 72  .  vdbeSorterWor
c4b0: 6b 44 65 62 75 67 28 70 54 61 73 6b 2c 20 22 65  kDebug(pTask, "e
c4c0: 78 69 74 22 29 3b 0a 20 20 61 73 73 65 72 74 28  xit");.  assert(
c4d0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c   rc!=SQLITE_OK |
c4e0: 7c 20 70 4c 69 73 74 2d 3e 70 4c 69 73 74 3d 3d  | pList->pList==
c4f0: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 72  0 );.  assert( r
c500: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20  c!=SQLITE_OK || 
c510: 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66  pTask->file.iEof
c520: 3d 3d 69 53 7a 20 29 3b 0a 20 20 72 65 74 75 72  ==iSz );.  retur
c530: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  n rc;.}../*.** A
c540: 64 76 61 6e 63 65 20 74 68 65 20 4d 65 72 67 65  dvance the Merge
c550: 45 6e 67 69 6e 65 20 69 74 65 72 61 74 6f 72 20  Engine iterator 
c560: 70 61 73 73 65 64 20 61 73 20 74 68 65 20 73 65  passed as the se
c570: 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 74 6f  cond argument to
c580: 0a 2a 2a 20 74 68 65 20 6e 65 78 74 20 65 6e 74  .** the next ent
c590: 72 79 2e 20 53 65 74 20 2a 70 62 45 6f 66 20 74  ry. Set *pbEof t
c5a0: 6f 20 74 72 75 65 20 69 66 20 74 68 69 73 20 6d  o true if this m
c5b0: 65 61 6e 73 20 74 68 65 20 69 74 65 72 61 74 6f  eans the iterato
c5c0: 72 20 68 61 73 20 0a 2a 2a 20 72 65 61 63 68 65  r has .** reache
c5d0: 64 20 45 4f 46 2e 0a 2a 2a 0a 2a 2a 20 52 65 74  d EOF..**.** Ret
c5e0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66  urn SQLITE_OK if
c5f0: 20 73 75 63 63 65 73 73 66 75 6c 20 6f 72 20 61   successful or a
c600: 6e 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20  n error code if 
c610: 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e  an error occurs.
c620: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
c630: 64 62 65 53 6f 72 74 65 72 4e 65 78 74 28 0a 20  dbeSorterNext(. 
c640: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
c650: 61 73 6b 2c 20 0a 20 20 4d 65 72 67 65 45 6e 67  ask, .  MergeEng
c660: 69 6e 65 20 2a 70 4d 65 72 67 65 72 2c 20 0a 20  ine *pMerger, . 
c670: 20 69 6e 74 20 2a 70 62 45 6f 66 0a 29 7b 0a 20   int *pbEof.){. 
c680: 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69   int rc;.  int i
c690: 50 72 65 76 20 3d 20 70 4d 65 72 67 65 72 2d 3e  Prev = pMerger->
c6a0: 61 54 72 65 65 5b 31 5d 3b 2f 2a 20 49 6e 64 65  aTree[1];/* Inde
c6b0: 78 20 6f 66 20 69 74 65 72 61 74 6f 72 20 74 6f  x of iterator to
c6c0: 20 61 64 76 61 6e 63 65 20 2a 2f 0a 0a 20 20 2f   advance */..  /
c6d0: 2a 20 41 64 76 61 6e 63 65 20 74 68 65 20 63 75  * Advance the cu
c6e0: 72 72 65 6e 74 20 69 74 65 72 61 74 6f 72 20 2a  rrent iterator *
c6f0: 2f 0a 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61  /.  rc = vdbePma
c700: 52 65 61 64 65 72 4e 65 78 74 28 26 70 4d 65 72  ReaderNext(&pMer
c710: 67 65 72 2d 3e 61 49 74 65 72 5b 69 50 72 65 76  ger->aIter[iPrev
c720: 5d 29 3b 0a 0a 20 20 2f 2a 20 55 70 64 61 74 65  ]);..  /* Update
c730: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61 54 72   contents of aTr
c740: 65 65 5b 5d 20 2a 2f 0a 20 20 69 66 28 20 72 63  ee[] */.  if( rc
c750: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
c760: 20 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20     int i;       
c770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c780: 2a 20 49 6e 64 65 78 20 6f 66 20 61 54 72 65 65  * Index of aTree
c790: 5b 5d 20 74 6f 20 72 65 63 61 6c 63 75 6c 61 74  [] to recalculat
c7a0: 65 20 2a 2f 0a 20 20 20 20 50 6d 61 52 65 61 64  e */.    PmaRead
c7b0: 65 72 20 2a 70 49 74 65 72 31 3b 20 20 20 20 20  er *pIter1;     
c7c0: 2f 2a 20 46 69 72 73 74 20 69 74 65 72 61 74 6f  /* First iterato
c7d0: 72 20 74 6f 20 63 6f 6d 70 61 72 65 20 2a 2f 0a  r to compare */.
c7e0: 20 20 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70      PmaReader *p
c7f0: 49 74 65 72 32 3b 20 20 20 20 20 2f 2a 20 53 65  Iter2;     /* Se
c800: 63 6f 6e 64 20 69 74 65 72 61 74 6f 72 20 74 6f  cond iterator to
c810: 20 63 6f 6d 70 61 72 65 20 2a 2f 0a 20 20 20 20   compare */.    
c820: 75 38 20 2a 70 4b 65 79 32 3b 20 20 20 20 20 20  u8 *pKey2;      
c830: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
c840: 6f 20 70 49 74 65 72 32 2d 3e 61 4b 65 79 2c 20  o pIter2->aKey, 
c850: 6f 72 20 30 20 69 66 20 72 65 63 6f 72 64 20 63  or 0 if record c
c860: 61 63 68 65 64 20 2a 2f 0a 0a 20 20 20 20 2f 2a  ached */..    /*
c870: 20 46 69 6e 64 20 74 68 65 20 66 69 72 73 74 20   Find the first 
c880: 74 77 6f 20 69 74 65 72 61 74 6f 72 73 20 74 6f  two iterators to
c890: 20 63 6f 6d 70 61 72 65 2e 20 54 68 65 20 6f 6e   compare. The on
c8a0: 65 20 74 68 61 74 20 77 61 73 20 6a 75 73 74 0a  e that was just.
c8b0: 20 20 20 20 2a 2a 20 61 64 76 61 6e 63 65 64 20      ** advanced 
c8c0: 28 69 50 72 65 76 29 20 61 6e 64 20 74 68 65 20  (iPrev) and the 
c8d0: 6f 6e 65 20 6e 65 78 74 20 74 6f 20 69 74 20 69  one next to it i
c8e0: 6e 20 74 68 65 20 61 72 72 61 79 2e 20 20 2a 2f  n the array.  */
c8f0: 0a 20 20 20 20 70 49 74 65 72 31 20 3d 20 26 70  .    pIter1 = &p
c900: 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 28 69  Merger->aIter[(i
c910: 50 72 65 76 20 26 20 30 78 46 46 46 45 29 5d 3b  Prev & 0xFFFE)];
c920: 0a 20 20 20 20 70 49 74 65 72 32 20 3d 20 26 70  .    pIter2 = &p
c930: 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 28 69  Merger->aIter[(i
c940: 50 72 65 76 20 7c 20 30 78 30 30 30 31 29 5d 3b  Prev | 0x0001)];
c950: 0a 20 20 20 20 70 4b 65 79 32 20 3d 20 70 49 74  .    pKey2 = pIt
c960: 65 72 32 2d 3e 61 4b 65 79 3b 0a 0a 20 20 20 20  er2->aKey;..    
c970: 66 6f 72 28 69 3d 28 70 4d 65 72 67 65 72 2d 3e  for(i=(pMerger->
c980: 6e 54 72 65 65 2b 69 50 72 65 76 29 2f 32 3b 20  nTree+iPrev)/2; 
c990: 69 3e 30 3b 20 69 3d 69 2f 32 29 7b 0a 20 20 20  i>0; i=i/2){.   
c9a0: 20 20 20 2f 2a 20 43 6f 6d 70 61 72 65 20 70 49     /* Compare pI
c9b0: 74 65 72 31 20 61 6e 64 20 70 49 74 65 72 32 2e  ter1 and pIter2.
c9c0: 20 53 74 6f 72 65 20 74 68 65 20 72 65 73 75 6c   Store the resul
c9d0: 74 20 69 6e 20 76 61 72 69 61 62 6c 65 20 69 52  t in variable iR
c9e0: 65 73 2e 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74  es. */.      int
c9f0: 20 69 52 65 73 3b 0a 20 20 20 20 20 20 69 66 28   iRes;.      if(
ca00: 20 70 49 74 65 72 31 2d 3e 70 46 69 6c 65 3d 3d   pIter1->pFile==
ca10: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 69 52 65  0 ){.        iRe
ca20: 73 20 3d 20 2b 31 3b 0a 20 20 20 20 20 20 7d 65  s = +1;.      }e
ca30: 6c 73 65 20 69 66 28 20 70 49 74 65 72 32 2d 3e  lse if( pIter2->
ca40: 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20  pFile==0 ){.    
ca50: 20 20 20 20 69 52 65 73 20 3d 20 2d 31 3b 0a 20      iRes = -1;. 
ca60: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
ca70: 20 20 20 20 69 52 65 73 20 3d 20 76 64 62 65 53      iRes = vdbeS
ca80: 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 70 54 61  orterCompare(pTa
ca90: 73 6b 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20  sk, .           
caa0: 20 70 49 74 65 72 31 2d 3e 61 4b 65 79 2c 20 70   pIter1->aKey, p
cab0: 49 74 65 72 31 2d 3e 6e 4b 65 79 2c 20 70 4b 65  Iter1->nKey, pKe
cac0: 79 32 2c 20 70 49 74 65 72 32 2d 3e 6e 4b 65 79  y2, pIter2->nKey
cad0: 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20  .        );.    
cae0: 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 49 66    }..      /* If
caf0: 20 70 49 74 65 72 31 20 63 6f 6e 74 61 69 6e 65   pIter1 containe
cb00: 64 20 74 68 65 20 73 6d 61 6c 6c 65 72 20 76 61  d the smaller va
cb10: 6c 75 65 2c 20 73 65 74 20 61 54 72 65 65 5b 69  lue, set aTree[i
cb20: 5d 20 74 6f 20 69 74 73 20 69 6e 64 65 78 2e 0a  ] to its index..
cb30: 20 20 20 20 20 20 2a 2a 20 54 68 65 6e 20 73 65        ** Then se
cb40: 74 20 70 49 74 65 72 32 20 74 6f 20 74 68 65 20  t pIter2 to the 
cb50: 6e 65 78 74 20 69 74 65 72 61 74 6f 72 20 74 6f  next iterator to
cb60: 20 63 6f 6d 70 61 72 65 20 74 6f 20 70 49 74 65   compare to pIte
cb70: 72 31 2e 20 49 6e 20 74 68 69 73 0a 20 20 20 20  r1. In this.    
cb80: 20 20 2a 2a 20 63 61 73 65 20 74 68 65 72 65 20    ** case there 
cb90: 69 73 20 6e 6f 20 63 61 63 68 65 20 6f 66 20 70  is no cache of p
cba0: 49 74 65 72 32 20 69 6e 20 70 54 61 73 6b 2d 3e  Iter2 in pTask->
cbb0: 70 55 6e 70 61 63 6b 65 64 2c 20 73 6f 20 73 65  pUnpacked, so se
cbc0: 74 0a 20 20 20 20 20 20 2a 2a 20 70 4b 65 79 32  t.      ** pKey2
cbd0: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65   to point to the
cbe0: 20 72 65 63 6f 72 64 20 62 65 6c 6f 6e 67 69 6e   record belongin
cbf0: 67 20 74 6f 20 70 49 74 65 72 32 2e 0a 20 20 20  g to pIter2..   
cc00: 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 41     **.      ** A
cc10: 6c 74 65 72 6e 61 74 69 76 65 6c 79 2c 20 69 66  lternatively, if
cc20: 20 70 49 74 65 72 32 20 63 6f 6e 74 61 69 6e 73   pIter2 contains
cc30: 20 74 68 65 20 73 6d 61 6c 6c 65 72 20 6f 66 20   the smaller of 
cc40: 74 68 65 20 74 77 6f 20 76 61 6c 75 65 73 2c 0a  the two values,.
cc50: 20 20 20 20 20 20 2a 2a 20 73 65 74 20 61 54 72        ** set aTr
cc60: 65 65 5b 69 5d 20 74 6f 20 69 74 73 20 69 6e 64  ee[i] to its ind
cc70: 65 78 20 61 6e 64 20 75 70 64 61 74 65 20 70 49  ex and update pI
cc80: 74 65 72 31 2e 20 49 66 20 76 64 62 65 53 6f 72  ter1. If vdbeSor
cc90: 74 65 72 43 6f 6d 70 61 72 65 28 29 0a 20 20 20  terCompare().   
cca0: 20 20 20 2a 2a 20 77 61 73 20 61 63 74 75 61 6c     ** was actual
ccb0: 6c 79 20 63 61 6c 6c 65 64 20 61 62 6f 76 65 2c  ly called above,
ccc0: 20 74 68 65 6e 20 70 54 61 73 6b 2d 3e 70 55 6e   then pTask->pUn
ccd0: 70 61 63 6b 65 64 20 6e 6f 77 20 63 6f 6e 74 61  packed now conta
cce0: 69 6e 73 0a 20 20 20 20 20 20 2a 2a 20 61 20 76  ins.      ** a v
ccf0: 61 6c 75 65 20 65 71 75 69 76 61 6c 65 6e 74 20  alue equivalent 
cd00: 74 6f 20 70 49 74 65 72 32 2e 20 53 6f 20 73 65  to pIter2. So se
cd10: 74 20 70 4b 65 79 32 20 74 6f 20 4e 55 4c 4c 20  t pKey2 to NULL 
cd20: 74 6f 20 70 72 65 76 65 6e 74 0a 20 20 20 20 20  to prevent.     
cd30: 20 2a 2a 20 76 64 62 65 53 6f 72 74 65 72 43 6f   ** vdbeSorterCo
cd40: 6d 70 61 72 65 28 29 20 66 72 6f 6d 20 64 65 63  mpare() from dec
cd50: 6f 64 69 6e 67 20 70 49 74 65 72 32 20 61 67 61  oding pIter2 aga
cd60: 69 6e 2e 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20  in..      **.   
cd70: 20 20 20 2a 2a 20 49 66 20 74 68 65 20 74 77 6f     ** If the two
cd80: 20 76 61 6c 75 65 73 20 77 65 72 65 20 65 71 75   values were equ
cd90: 61 6c 2c 20 74 68 65 6e 20 74 68 65 20 76 61 6c  al, then the val
cda0: 75 65 20 66 72 6f 6d 20 74 68 65 20 6f 6c 64 65  ue from the olde
cdb0: 73 74 0a 20 20 20 20 20 20 2a 2a 20 50 4d 41 20  st.      ** PMA 
cdc0: 73 68 6f 75 6c 64 20 62 65 20 63 6f 6e 73 69 64  should be consid
cdd0: 65 72 65 64 20 73 6d 61 6c 6c 65 72 2e 20 54 68  ered smaller. Th
cde0: 65 20 56 64 62 65 53 6f 72 74 65 72 2e 61 49 74  e VdbeSorter.aIt
cdf0: 65 72 5b 5d 20 61 72 72 61 79 0a 20 20 20 20 20  er[] array.     
ce00: 20 2a 2a 20 69 73 20 73 6f 72 74 65 64 20 66 72   ** is sorted fr
ce10: 6f 6d 20 6f 6c 64 65 73 74 20 74 6f 20 6e 65 77  om oldest to new
ce20: 65 73 74 2c 20 73 6f 20 70 49 74 65 72 31 20 63  est, so pIter1 c
ce30: 6f 6e 74 61 69 6e 73 20 6f 6c 64 65 72 20 76 61  ontains older va
ce40: 6c 75 65 73 0a 20 20 20 20 20 20 2a 2a 20 74 68  lues.      ** th
ce50: 61 6e 20 70 49 74 65 72 32 20 69 66 66 20 28 70  an pIter2 iff (p
ce60: 49 74 65 72 31 3c 70 49 74 65 72 32 29 2e 20 20  Iter1<pIter2).  
ce70: 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 69 52 65  */.      if( iRe
ce80: 73 3c 30 20 7c 7c 20 28 69 52 65 73 3d 3d 30 20  s<0 || (iRes==0 
ce90: 26 26 20 70 49 74 65 72 31 3c 70 49 74 65 72 32  && pIter1<pIter2
cea0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 70 4d 65  ) ){.        pMe
ceb0: 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 5d 20 3d  rger->aTree[i] =
cec0: 20 28 69 6e 74 29 28 70 49 74 65 72 31 20 2d 20   (int)(pIter1 - 
ced0: 70 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 29 3b  pMerger->aIter);
cee0: 0a 20 20 20 20 20 20 20 20 70 49 74 65 72 32 20  .        pIter2 
cef0: 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65  = &pMerger->aIte
cf00: 72 5b 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65  r[ pMerger->aTre
cf10: 65 5b 69 20 5e 20 30 78 30 30 30 31 5d 20 5d 3b  e[i ^ 0x0001] ];
cf20: 0a 20 20 20 20 20 20 20 20 70 4b 65 79 32 20 3d  .        pKey2 =
cf30: 20 70 49 74 65 72 32 2d 3e 61 4b 65 79 3b 0a 20   pIter2->aKey;. 
cf40: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
cf50: 20 20 20 20 69 66 28 20 70 49 74 65 72 31 2d 3e      if( pIter1->
cf60: 70 46 69 6c 65 20 29 20 70 4b 65 79 32 20 3d 20  pFile ) pKey2 = 
cf70: 30 3b 0a 20 20 20 20 20 20 20 20 70 4d 65 72 67  0;.        pMerg
cf80: 65 72 2d 3e 61 54 72 65 65 5b 69 5d 20 3d 20 28  er->aTree[i] = (
cf90: 69 6e 74 29 28 70 49 74 65 72 32 20 2d 20 70 4d  int)(pIter2 - pM
cfa0: 65 72 67 65 72 2d 3e 61 49 74 65 72 29 3b 0a 20  erger->aIter);. 
cfb0: 20 20 20 20 20 20 20 70 49 74 65 72 31 20 3d 20         pIter1 = 
cfc0: 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b  &pMerger->aIter[
cfd0: 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b   pMerger->aTree[
cfe0: 69 20 5e 20 30 78 30 30 30 31 5d 20 5d 3b 0a 20  i ^ 0x0001] ];. 
cff0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
d000: 20 2a 70 62 45 6f 66 20 3d 20 28 70 4d 65 72 67   *pbEof = (pMerg
d010: 65 72 2d 3e 61 49 74 65 72 5b 70 4d 65 72 67 65  er->aIter[pMerge
d020: 72 2d 3e 61 54 72 65 65 5b 31 5d 5d 2e 70 46 69  r->aTree[1]].pFi
d030: 6c 65 3d 3d 30 29 3b 0a 20 20 7d 0a 0a 20 20 72  le==0);.  }..  r
d040: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 23 69 66  eturn rc;.}..#if
d050: 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b   SQLITE_MAX_WORK
d060: 45 52 5f 54 48 52 45 41 44 53 3e 30 0a 2f 2a 0a  ER_THREADS>0./*.
d070: 2a 2a 20 54 68 65 20 6d 61 69 6e 20 72 6f 75 74  ** The main rout
d080: 69 6e 65 20 66 6f 72 20 62 61 63 6b 67 72 6f 75  ine for backgrou
d090: 6e 64 20 74 68 72 65 61 64 73 20 74 68 61 74 20  nd threads that 
d0a0: 77 72 69 74 65 20 6c 65 76 65 6c 2d 30 20 50 4d  write level-0 PM
d0b0: 41 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  As..*/.static vo
d0c0: 69 64 20 2a 76 64 62 65 53 6f 72 74 65 72 46 6c  id *vdbeSorterFl
d0d0: 75 73 68 54 68 72 65 61 64 28 76 6f 69 64 20 2a  ushThread(void *
d0e0: 70 43 74 78 29 7b 0a 20 20 53 6f 72 74 53 75 62  pCtx){.  SortSub
d0f0: 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20 28 53  task *pTask = (S
d100: 6f 72 74 53 75 62 74 61 73 6b 2a 29 70 43 74 78  ortSubtask*)pCtx
d110: 3b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  ;.  int rc;     
d120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d130: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f      /* Return co
d140: 64 65 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20  de */.  assert( 
d150: 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 3d 3d 30 20  pTask->bDone==0 
d160: 29 3b 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f  );.  rc = vdbeSo
d170: 72 74 65 72 4c 69 73 74 54 6f 50 4d 41 28 70 54  rterListToPMA(pT
d180: 61 73 6b 2c 20 26 70 54 61 73 6b 2d 3e 6c 69 73  ask, &pTask->lis
d190: 74 29 3b 0a 20 20 70 54 61 73 6b 2d 3e 62 44 6f  t);.  pTask->bDo
d1a0: 6e 65 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e  ne = 1;.  return
d1b0: 20 53 51 4c 49 54 45 5f 49 4e 54 5f 54 4f 5f 50   SQLITE_INT_TO_P
d1c0: 54 52 28 72 63 29 3b 0a 7d 0a 23 65 6e 64 69 66  TR(rc);.}.#endif
d1d0: 20 2f 2a 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57   /* SQLITE_MAX_W
d1e0: 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 20  ORKER_THREADS>0 
d1f0: 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68 20  */../*.** Flush 
d200: 74 68 65 20 63 75 72 72 65 6e 74 20 63 6f 6e 74  the current cont
d210: 65 6e 74 73 20 6f 66 20 56 64 62 65 53 6f 72 74  ents of VdbeSort
d220: 65 72 2e 6c 69 73 74 20 74 6f 20 61 20 6e 65 77  er.list to a new
d230: 20 50 4d 41 2c 20 70 6f 73 73 69 62 6c 79 0a 2a   PMA, possibly.*
d240: 2a 20 75 73 69 6e 67 20 61 20 62 61 63 6b 67 72  * using a backgr
d250: 6f 75 6e 64 20 74 68 72 65 61 64 2e 0a 2a 2f 0a  ound thread..*/.
d260: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53  static int vdbeS
d270: 6f 72 74 65 72 46 6c 75 73 68 50 4d 41 28 56 64  orterFlushPMA(Vd
d280: 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
d290: 72 29 7b 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d  r){.#if SQLITE_M
d2a0: 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44  AX_WORKER_THREAD
d2b0: 53 3d 3d 30 0a 20 20 70 53 6f 72 74 65 72 2d 3e  S==0.  pSorter->
d2c0: 62 55 73 65 50 4d 41 20 3d 20 31 3b 0a 20 20 72  bUsePMA = 1;.  r
d2d0: 65 74 75 72 6e 20 76 64 62 65 53 6f 72 74 65 72  eturn vdbeSorter
d2e0: 4c 69 73 74 54 6f 50 4d 41 28 26 70 53 6f 72 74  ListToPMA(&pSort
d2f0: 65 72 2d 3e 61 54 61 73 6b 5b 30 5d 2c 20 26 70  er->aTask[0], &p
d300: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 29 3b 0a 23  Sorter->list);.#
d310: 65 6c 73 65 0a 20 20 69 6e 74 20 72 63 20 3d 20  else.  int rc = 
d320: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74  SQLITE_OK;.  int
d330: 20 69 3b 0a 20 20 53 6f 72 74 53 75 62 74 61 73   i;.  SortSubtas
d340: 6b 20 2a 70 54 61 73 6b 20 3d 20 30 3b 20 20 20  k *pTask = 0;   
d350: 20 2f 2a 20 54 68 72 65 61 64 20 63 6f 6e 74 65   /* Thread conte
d360: 78 74 20 75 73 65 64 20 74 6f 20 63 72 65 61 74  xt used to creat
d370: 65 20 6e 65 77 20 50 4d 41 20 2a 2f 0a 20 20 69  e new PMA */.  i
d380: 6e 74 20 6e 57 6f 72 6b 65 72 20 3d 20 28 70 53  nt nWorker = (pS
d390: 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 3b  orter->nTask-1);
d3a0: 0a 0a 20 20 2f 2a 20 53 65 74 20 74 68 65 20 66  ..  /* Set the f
d3b0: 6c 61 67 20 74 6f 20 69 6e 64 69 63 61 74 65 20  lag to indicate 
d3c0: 74 68 61 74 20 61 74 20 6c 65 61 73 74 20 6f 6e  that at least on
d3d0: 65 20 50 4d 41 20 68 61 73 20 62 65 65 6e 20 77  e PMA has been w
d3e0: 72 69 74 74 65 6e 2e 20 0a 20 20 2a 2a 20 4f 72  ritten. .  ** Or
d3f0: 20 77 69 6c 6c 20 62 65 2c 20 61 6e 79 68 6f 77   will be, anyhow
d400: 2e 20 20 2a 2f 0a 20 20 70 53 6f 72 74 65 72 2d  .  */.  pSorter-
d410: 3e 62 55 73 65 50 4d 41 20 3d 20 31 3b 0a 0a 20  >bUsePMA = 1;.. 
d420: 20 2f 2a 20 53 65 6c 65 63 74 20 61 20 73 75 62   /* Select a sub
d430: 2d 74 61 73 6b 20 74 6f 20 73 6f 72 74 20 61 6e  -task to sort an
d440: 64 20 66 6c 75 73 68 20 74 68 65 20 63 75 72 72  d flush the curr
d450: 65 6e 74 20 6c 69 73 74 20 6f 66 20 69 6e 2d 6d  ent list of in-m
d460: 65 6d 6f 72 79 0a 20 20 2a 2a 20 72 65 63 6f 72  emory.  ** recor
d470: 64 73 20 74 6f 20 64 69 73 6b 2e 20 49 66 20 74  ds to disk. If t
d480: 68 65 20 73 6f 72 74 65 72 20 69 73 20 72 75 6e  he sorter is run
d490: 6e 69 6e 67 20 69 6e 20 6d 75 6c 74 69 2d 74 68  ning in multi-th
d4a0: 72 65 61 64 65 64 20 6d 6f 64 65 2c 0a 20 20 2a  readed mode,.  *
d4b0: 2a 20 72 6f 75 6e 64 2d 72 6f 62 69 6e 20 62 65  * round-robin be
d4c0: 74 77 65 65 6e 20 74 68 65 20 66 69 72 73 74 20  tween the first 
d4d0: 28 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d  (pSorter->nTask-
d4e0: 31 29 20 74 61 73 6b 73 2e 20 45 78 63 65 70 74  1) tasks. Except
d4f0: 2c 20 69 66 0a 20 20 2a 2a 20 74 68 65 20 62 61  , if.  ** the ba
d500: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
d510: 66 72 6f 6d 20 61 20 73 75 62 2d 74 61 73 6b 73  from a sub-tasks
d520: 20 70 72 65 76 69 6f 75 73 20 74 75 72 6e 20 69   previous turn i
d530: 73 20 73 74 69 6c 6c 20 72 75 6e 6e 69 6e 67 2c  s still running,
d540: 0a 20 20 2a 2a 20 73 6b 69 70 20 69 74 2e 20 49  .  ** skip it. I
d550: 66 20 74 68 65 20 66 69 72 73 74 20 28 70 53 6f  f the first (pSo
d560: 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 20 73  rter->nTask-1) s
d570: 75 62 2d 74 61 73 6b 73 20 61 72 65 20 61 6c 6c  ub-tasks are all
d580: 20 73 74 69 6c 6c 20 62 75 73 79 2c 0a 20 20 2a   still busy,.  *
d590: 2a 20 66 61 6c 6c 20 62 61 63 6b 20 74 6f 20 75  * fall back to u
d5a0: 73 69 6e 67 20 74 68 65 20 66 69 6e 61 6c 20 73  sing the final s
d5b0: 75 62 2d 74 61 73 6b 2e 20 54 68 65 20 66 69 72  ub-task. The fir
d5c0: 73 74 20 28 70 53 6f 72 74 65 72 2d 3e 6e 54 61  st (pSorter->nTa
d5d0: 73 6b 2d 31 29 0a 20 20 2a 2a 20 73 75 62 2d 74  sk-1).  ** sub-t
d5e0: 61 73 6b 73 20 61 72 65 20 70 72 65 66 65 72 65  asks are prefere
d5f0: 64 20 61 73 20 74 68 65 79 20 75 73 65 20 62 61  d as they use ba
d600: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 73  ckground threads
d610: 20 2d 20 74 68 65 20 66 69 6e 61 6c 20 0a 20 20   - the final .  
d620: 2a 2a 20 73 75 62 2d 74 61 73 6b 20 75 73 65 73  ** sub-task uses
d630: 20 74 68 65 20 6d 61 69 6e 20 74 68 72 65 61 64   the main thread
d640: 2e 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20  . */.  for(i=0; 
d650: 69 3c 6e 57 6f 72 6b 65 72 3b 20 69 2b 2b 29 7b  i<nWorker; i++){
d660: 0a 20 20 20 20 69 6e 74 20 69 54 65 73 74 20 3d  .    int iTest =
d670: 20 28 70 53 6f 72 74 65 72 2d 3e 69 50 72 65 76   (pSorter->iPrev
d680: 20 2b 20 69 20 2b 20 31 29 20 25 20 6e 57 6f 72   + i + 1) % nWor
d690: 6b 65 72 3b 0a 20 20 20 20 70 54 61 73 6b 20 3d  ker;.    pTask =
d6a0: 20 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b   &pSorter->aTask
d6b0: 5b 69 54 65 73 74 5d 3b 0a 20 20 20 20 69 66 28  [iTest];.    if(
d6c0: 20 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 20 29 7b   pTask->bDone ){
d6d0: 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65  .      rc = vdbe
d6e0: 53 6f 72 74 65 72 4a 6f 69 6e 54 68 72 65 61 64  SorterJoinThread
d6f0: 28 70 54 61 73 6b 29 3b 0a 20 20 20 20 7d 0a 20  (pTask);.    }. 
d700: 20 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 70 54     if( pTask->pT
d710: 68 72 65 61 64 3d 3d 30 20 7c 7c 20 72 63 21 3d  hread==0 || rc!=
d720: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61  SQLITE_OK ) brea
d730: 6b 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63  k;.  }..  if( rc
d740: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
d750: 20 20 20 69 66 28 20 69 3d 3d 6e 57 6f 72 6b 65     if( i==nWorke
d760: 72 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 55 73  r ){.      /* Us
d770: 65 20 74 68 65 20 66 6f 72 65 67 72 6f 75 6e 64  e the foreground
d780: 20 74 68 72 65 61 64 20 66 6f 72 20 74 68 69 73   thread for this
d790: 20 6f 70 65 72 61 74 69 6f 6e 20 2a 2f 0a 20 20   operation */.  
d7a0: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
d7b0: 74 65 72 4c 69 73 74 54 6f 50 4d 41 28 26 70 53  terListToPMA(&pS
d7c0: 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 6e 57 6f  orter->aTask[nWo
d7d0: 72 6b 65 72 5d 2c 20 26 70 53 6f 72 74 65 72 2d  rker], &pSorter-
d7e0: 3e 6c 69 73 74 29 3b 0a 20 20 20 20 7d 65 6c 73  >list);.    }els
d7f0: 65 7b 0a 20 20 20 20 20 20 2f 2a 20 4c 61 75 6e  e{.      /* Laun
d800: 63 68 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20  ch a background 
d810: 74 68 72 65 61 64 20 66 6f 72 20 74 68 69 73 20  thread for this 
d820: 6f 70 65 72 61 74 69 6f 6e 20 2a 2f 0a 20 20 20  operation */.   
d830: 20 20 20 75 38 20 2a 61 4d 65 6d 20 3d 20 70 54     u8 *aMem = pT
d840: 61 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72  ask->list.aMemor
d850: 79 3b 0a 20 20 20 20 20 20 76 6f 69 64 20 2a 70  y;.      void *p
d860: 43 74 78 20 3d 20 28 76 6f 69 64 2a 29 70 54 61  Ctx = (void*)pTa
d870: 73 6b 3b 0a 0a 20 20 20 20 20 20 61 73 73 65 72  sk;..      asser
d880: 74 28 20 70 54 61 73 6b 2d 3e 70 54 68 72 65 61  t( pTask->pThrea
d890: 64 3d 3d 30 20 26 26 20 70 54 61 73 6b 2d 3e 62  d==0 && pTask->b
d8a0: 44 6f 6e 65 3d 3d 30 20 29 3b 0a 20 20 20 20 20  Done==0 );.     
d8b0: 20 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e   assert( pTask->
d8c0: 6c 69 73 74 2e 70 4c 69 73 74 3d 3d 30 20 29 3b  list.pList==0 );
d8d0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70  .      assert( p
d8e0: 54 61 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f  Task->list.aMemo
d8f0: 72 79 3d 3d 30 20 7c 7c 20 70 53 6f 72 74 65 72  ry==0 || pSorter
d900: 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 21 3d  ->list.aMemory!=
d910: 30 20 29 3b 0a 0a 20 20 20 20 20 20 70 53 6f 72  0 );..      pSor
d920: 74 65 72 2d 3e 69 50 72 65 76 20 3d 20 28 70 54  ter->iPrev = (pT
d930: 61 73 6b 20 2d 20 70 53 6f 72 74 65 72 2d 3e 61  ask - pSorter->a
d940: 54 61 73 6b 29 3b 0a 20 20 20 20 20 20 70 54 61  Task);.      pTa
d950: 73 6b 2d 3e 6c 69 73 74 20 3d 20 70 53 6f 72 74  sk->list = pSort
d960: 65 72 2d 3e 6c 69 73 74 3b 0a 20 20 20 20 20 20  er->list;.      
d970: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c  pSorter->list.pL
d980: 69 73 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 70  ist = 0;.      p
d990: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 73 7a 50  Sorter->list.szP
d9a0: 4d 41 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 66  MA = 0;.      if
d9b0: 28 20 61 4d 65 6d 20 29 7b 0a 20 20 20 20 20 20  ( aMem ){.      
d9c0: 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e    pSorter->list.
d9d0: 61 4d 65 6d 6f 72 79 20 3d 20 61 4d 65 6d 3b 0a  aMemory = aMem;.
d9e0: 20 20 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d          pSorter-
d9f0: 3e 6e 4d 65 6d 6f 72 79 20 3d 20 73 71 6c 69 74  >nMemory = sqlit
da00: 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 61 4d 65  e3MallocSize(aMe
da10: 6d 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  m);.      }else{
da20: 0a 20 20 20 20 20 20 20 20 70 53 6f 72 74 65 72  .        pSorter
da30: 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 3d  ->list.aMemory =
da40: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 70   sqlite3Malloc(p
da50: 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 29  Sorter->nMemory)
da60: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 21 70  ;.        if( !p
da70: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65  Sorter->list.aMe
da80: 6d 6f 72 79 20 29 20 72 65 74 75 72 6e 20 53 51  mory ) return SQ
da90: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
daa0: 20 20 7d 0a 0a 20 20 20 20 20 20 72 63 20 3d 20    }..      rc = 
dab0: 76 64 62 65 53 6f 72 74 65 72 43 72 65 61 74 65  vdbeSorterCreate
dac0: 54 68 72 65 61 64 28 70 54 61 73 6b 2c 20 76 64  Thread(pTask, vd
dad0: 62 65 53 6f 72 74 65 72 46 6c 75 73 68 54 68 72  beSorterFlushThr
dae0: 65 61 64 2c 20 70 43 74 78 29 3b 0a 20 20 20 20  ead, pCtx);.    
daf0: 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  }.  }..  return 
db00: 72 63 3b 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51  rc;.#endif /* SQ
db10: 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f  LITE_MAX_WORKER_
db20: 54 48 52 45 41 44 53 21 3d 30 20 2a 2f 0a 7d 0a  THREADS!=0 */.}.
db30: 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 72 65 63  ./*.** Add a rec
db40: 6f 72 64 20 74 6f 20 74 68 65 20 73 6f 72 74 65  ord to the sorte
db50: 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  r..*/.int sqlite
db60: 33 56 64 62 65 53 6f 72 74 65 72 57 72 69 74 65  3VdbeSorterWrite
db70: 28 0a 20 20 63 6f 6e 73 74 20 56 64 62 65 43 75  (.  const VdbeCu
db80: 72 73 6f 72 20 2a 70 43 73 72 2c 20 20 20 20 20  rsor *pCsr,     
db90: 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 63 75      /* Sorter cu
dba0: 72 73 6f 72 20 2a 2f 0a 20 20 4d 65 6d 20 2a 70  rsor */.  Mem *p
dbb0: 56 61 6c 20 20 20 20 20 20 20 20 20 20 20 20 20  Val             
dbc0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 65 6d            /* Mem
dbd0: 6f 72 79 20 63 65 6c 6c 20 63 6f 6e 74 61 69 6e  ory cell contain
dbe0: 69 6e 67 20 72 65 63 6f 72 64 20 2a 2f 0a 29 7b  ing record */.){
dbf0: 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70  .  VdbeSorter *p
dc00: 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70  Sorter = pCsr->p
dc10: 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 72 63  Sorter;.  int rc
dc20: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20   = SQLITE_OK;   
dc30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
dc40: 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 53 6f  urn Code */.  So
dc50: 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65 77  rterRecord *pNew
dc60: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
dc70: 20 4e 65 77 20 6c 69 73 74 20 65 6c 65 6d 65 6e   New list elemen
dc80: 74 20 2a 2f 0a 0a 20 20 69 6e 74 20 62 46 6c 75  t */..  int bFlu
dc90: 73 68 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  sh;             
dca0: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
dcb0: 74 6f 20 66 6c 75 73 68 20 63 6f 6e 74 65 6e 74  to flush content
dcc0: 73 20 6f 66 20 6d 65 6d 6f 72 79 20 74 6f 20 50  s of memory to P
dcd0: 4d 41 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 71  MA */.  int nReq
dce0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
dcf0: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
dd00: 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71 75 69   of memory requi
dd10: 72 65 64 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 4d  red */.  int nPM
dd20: 41 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  A;              
dd30: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65           /* Byte
dd40: 73 20 6f 66 20 50 4d 41 20 73 70 61 63 65 20 72  s of PMA space r
dd50: 65 71 75 69 72 65 64 20 2a 2f 0a 0a 20 20 61 73  equired */..  as
dd60: 73 65 72 74 28 20 70 53 6f 72 74 65 72 20 29 3b  sert( pSorter );
dd70: 0a 0a 20 20 2f 2a 20 46 69 67 75 72 65 20 6f 75  ..  /* Figure ou
dd80: 74 20 77 68 65 74 68 65 72 20 6f 72 20 6e 6f 74  t whether or not
dd90: 20 74 68 65 20 63 75 72 72 65 6e 74 20 63 6f 6e   the current con
dda0: 74 65 6e 74 73 20 6f 66 20 6d 65 6d 6f 72 79 20  tents of memory 
ddb0: 73 68 6f 75 6c 64 20 62 65 0a 20 20 2a 2a 20 66  should be.  ** f
ddc0: 6c 75 73 68 65 64 20 74 6f 20 61 20 50 4d 41 20  lushed to a PMA 
ddd0: 62 65 66 6f 72 65 20 63 6f 6e 74 69 6e 75 69 6e  before continuin
dde0: 67 2e 20 49 66 20 73 6f 2c 20 64 6f 20 73 6f 2e  g. If so, do so.
ddf0: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49 66 20 75 73  .  **.  ** If us
de00: 69 6e 67 20 74 68 65 20 73 69 6e 67 6c 65 20 6c  ing the single l
de10: 61 72 67 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20  arge allocation 
de20: 6d 6f 64 65 20 28 70 53 6f 72 74 65 72 2d 3e 61  mode (pSorter->a
de30: 4d 65 6d 6f 72 79 21 3d 30 29 2c 20 74 68 65 6e  Memory!=0), then
de40: 0a 20 20 2a 2a 20 66 6c 75 73 68 20 74 68 65 20  .  ** flush the 
de50: 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65 6d 6f  contents of memo
de60: 72 79 20 74 6f 20 61 20 6e 65 77 20 50 4d 41 20  ry to a new PMA 
de70: 69 66 20 28 61 29 20 61 74 20 6c 65 61 73 74 20  if (a) at least 
de80: 6f 6e 65 20 76 61 6c 75 65 20 69 73 0a 20 20 2a  one value is.  *
de90: 2a 20 61 6c 72 65 61 64 79 20 69 6e 20 6d 65 6d  * already in mem
dea0: 6f 72 79 20 61 6e 64 20 28 62 29 20 74 68 65 20  ory and (b) the 
deb0: 6e 65 77 20 76 61 6c 75 65 20 77 69 6c 6c 20 6e  new value will n
dec0: 6f 74 20 66 69 74 20 69 6e 20 6d 65 6d 6f 72 79  ot fit in memory
ded0: 2e 0a 20 20 2a 2a 20 0a 20 20 2a 2a 20 4f 72 2c  ..  ** .  ** Or,
dee0: 20 69 66 20 75 73 69 6e 67 20 73 65 70 61 72 61   if using separa
def0: 74 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 20 66  te allocations f
df00: 6f 72 20 65 61 63 68 20 72 65 63 6f 72 64 2c 20  or each record, 
df10: 66 6c 75 73 68 20 74 68 65 20 63 6f 6e 74 65 6e  flush the conten
df20: 74 73 0a 20 20 2a 2a 20 6f 66 20 6d 65 6d 6f 72  ts.  ** of memor
df30: 79 20 74 6f 20 61 20 50 4d 41 20 69 66 20 65 69  y to a PMA if ei
df40: 74 68 65 72 20 6f 66 20 74 68 65 20 66 6f 6c 6c  ther of the foll
df50: 6f 77 69 6e 67 20 61 72 65 20 74 72 75 65 3a 0a  owing are true:.
df60: 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 54 68    **.  **   * Th
df70: 65 20 74 6f 74 61 6c 20 6d 65 6d 6f 72 79 20 61  e total memory a
df80: 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 74 68 65  llocated for the
df90: 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20   in-memory list 
dfa0: 69 73 20 67 72 65 61 74 65 72 20 0a 20 20 2a 2a  is greater .  **
dfb0: 20 20 20 20 20 74 68 61 6e 20 28 70 61 67 65 2d       than (page-
dfc0: 73 69 7a 65 20 2a 20 63 61 63 68 65 2d 73 69 7a  size * cache-siz
dfd0: 65 29 2c 20 6f 72 0a 20 20 2a 2a 0a 20 20 2a 2a  e), or.  **.  **
dfe0: 20 20 20 2a 20 54 68 65 20 74 6f 74 61 6c 20 6d     * The total m
dff0: 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 65 64 20  emory allocated 
e000: 66 6f 72 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72  for the in-memor
e010: 79 20 6c 69 73 74 20 69 73 20 67 72 65 61 74 65  y list is greate
e020: 72 20 0a 20 20 2a 2a 20 20 20 20 20 74 68 61 6e  r .  **     than
e030: 20 28 70 61 67 65 2d 73 69 7a 65 20 2a 20 31 30   (page-size * 10
e040: 29 20 61 6e 64 20 73 71 6c 69 74 65 33 48 65 61  ) and sqlite3Hea
e050: 70 4e 65 61 72 6c 79 46 75 6c 6c 28 29 20 72 65  pNearlyFull() re
e060: 74 75 72 6e 73 20 74 72 75 65 2e 0a 20 20 2a 2f  turns true..  */
e070: 0a 20 20 6e 52 65 71 20 3d 20 70 56 61 6c 2d 3e  .  nReq = pVal->
e080: 6e 20 2b 20 73 69 7a 65 6f 66 28 53 6f 72 74 65  n + sizeof(Sorte
e090: 72 52 65 63 6f 72 64 29 3b 0a 20 20 6e 50 4d 41  rRecord);.  nPMA
e0a0: 20 3d 20 70 56 61 6c 2d 3e 6e 20 2b 20 73 71 6c   = pVal->n + sql
e0b0: 69 74 65 33 56 61 72 69 6e 74 4c 65 6e 28 70 56  ite3VarintLen(pV
e0c0: 61 6c 2d 3e 6e 29 3b 0a 20 20 69 66 28 20 70 53  al->n);.  if( pS
e0d0: 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65  orter->mxPmaSize
e0e0: 20 29 7b 0a 20 20 20 20 69 66 28 20 70 53 6f 72   ){.    if( pSor
e0f0: 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72  ter->list.aMemor
e100: 79 20 29 7b 0a 20 20 20 20 20 20 62 46 6c 75 73  y ){.      bFlus
e110: 68 20 3d 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65  h = pSorter->iMe
e120: 6d 6f 72 79 20 26 26 20 28 70 53 6f 72 74 65 72  mory && (pSorter
e130: 2d 3e 69 4d 65 6d 6f 72 79 2b 6e 52 65 71 29 20  ->iMemory+nReq) 
e140: 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61  > pSorter->mxPma
e150: 53 69 7a 65 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  Size;.    }else{
e160: 0a 20 20 20 20 20 20 62 46 6c 75 73 68 20 3d 20  .      bFlush = 
e170: 28 0a 20 20 20 20 20 20 20 20 20 20 28 70 53 6f  (.          (pSo
e180: 72 74 65 72 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41  rter->list.szPMA
e190: 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d   > pSorter->mxPm
e1a0: 61 53 69 7a 65 29 0a 20 20 20 20 20 20 20 7c 7c  aSize).       ||
e1b0: 20 28 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e   (pSorter->list.
e1c0: 73 7a 50 4d 41 20 3e 20 70 53 6f 72 74 65 72 2d  szPMA > pSorter-
e1d0: 3e 6d 6e 50 6d 61 53 69 7a 65 20 26 26 20 73 71  >mnPmaSize && sq
e1e0: 6c 69 74 65 33 48 65 61 70 4e 65 61 72 6c 79 46  lite3HeapNearlyF
e1f0: 75 6c 6c 28 29 29 0a 20 20 20 20 20 20 29 3b 0a  ull()).      );.
e200: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 62 46      }.    if( bF
e210: 6c 75 73 68 20 29 7b 0a 20 20 20 20 20 20 72 63  lush ){.      rc
e220: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 46 6c 75   = vdbeSorterFlu
e230: 73 68 50 4d 41 28 70 53 6f 72 74 65 72 29 3b 0a  shPMA(pSorter);.
e240: 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6c        pSorter->l
e250: 69 73 74 2e 73 7a 50 4d 41 20 3d 20 30 3b 0a 20  ist.szPMA = 0;. 
e260: 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 69 4d       pSorter->iM
e270: 65 6d 6f 72 79 20 3d 20 30 3b 0a 20 20 20 20 20  emory = 0;.     
e280: 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c   assert( rc!=SQL
e290: 49 54 45 5f 4f 4b 20 7c 7c 20 70 53 6f 72 74 65  ITE_OK || pSorte
e2a0: 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 3d 3d 30  r->list.pList==0
e2b0: 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20   );.    }.  }.. 
e2c0: 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 73   pSorter->list.s
e2d0: 7a 50 4d 41 20 2b 3d 20 6e 50 4d 41 3b 0a 20 20  zPMA += nPMA;.  
e2e0: 69 66 28 20 6e 50 4d 41 3e 70 53 6f 72 74 65 72  if( nPMA>pSorter
e2f0: 2d 3e 6d 78 4b 65 79 73 69 7a 65 20 29 7b 0a 20  ->mxKeysize ){. 
e300: 20 20 20 70 53 6f 72 74 65 72 2d 3e 6d 78 4b 65     pSorter->mxKe
e310: 79 73 69 7a 65 20 3d 20 6e 50 4d 41 3b 0a 20 20  ysize = nPMA;.  
e320: 7d 0a 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72  }..  if( pSorter
e330: 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 29  ->list.aMemory )
e340: 7b 0a 20 20 20 20 69 6e 74 20 6e 4d 69 6e 20 3d  {.    int nMin =
e350: 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72   pSorter->iMemor
e360: 79 20 2b 20 6e 52 65 71 3b 0a 0a 20 20 20 20 69  y + nReq;..    i
e370: 66 28 20 6e 4d 69 6e 3e 70 53 6f 72 74 65 72 2d  f( nMin>pSorter-
e380: 3e 6e 4d 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20  >nMemory ){.    
e390: 20 20 75 38 20 2a 61 4e 65 77 3b 0a 20 20 20 20    u8 *aNew;.    
e3a0: 20 20 69 6e 74 20 6e 4e 65 77 20 3d 20 70 53 6f    int nNew = pSo
e3b0: 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 2a 20  rter->nMemory * 
e3c0: 32 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20  2;.      while( 
e3d0: 6e 4e 65 77 20 3c 20 6e 4d 69 6e 20 29 20 6e 4e  nNew < nMin ) nN
e3e0: 65 77 20 3d 20 6e 4e 65 77 2a 32 3b 0a 20 20 20  ew = nNew*2;.   
e3f0: 20 20 20 69 66 28 20 6e 4e 65 77 20 3e 20 70 53     if( nNew > pS
e400: 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65  orter->mxPmaSize
e410: 20 29 20 6e 4e 65 77 20 3d 20 70 53 6f 72 74 65   ) nNew = pSorte
e420: 72 2d 3e 6d 78 50 6d 61 53 69 7a 65 3b 0a 20 20  r->mxPmaSize;.  
e430: 20 20 20 20 69 66 28 20 6e 4e 65 77 20 3c 20 6e      if( nNew < n
e440: 4d 69 6e 20 29 20 6e 4e 65 77 20 3d 20 6e 4d 69  Min ) nNew = nMi
e450: 6e 3b 0a 0a 20 20 20 20 20 20 61 4e 65 77 20 3d  n;..      aNew =
e460: 20 73 71 6c 69 74 65 33 52 65 61 6c 6c 6f 63 28   sqlite3Realloc(
e470: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d  pSorter->list.aM
e480: 65 6d 6f 72 79 2c 20 6e 4e 65 77 29 3b 0a 20 20  emory, nNew);.  
e490: 20 20 20 20 69 66 28 20 21 61 4e 65 77 20 29 20      if( !aNew ) 
e4a0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
e4b0: 4d 45 4d 3b 0a 20 20 20 20 20 20 70 53 6f 72 74  MEM;.      pSort
e4c0: 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d  er->list.pList =
e4d0: 20 28 53 6f 72 74 65 72 52 65 63 6f 72 64 2a 29   (SorterRecord*)
e4e0: 28 0a 20 20 20 20 20 20 20 20 20 20 61 4e 65 77  (.          aNew
e4f0: 20 2b 20 28 28 75 38 2a 29 70 53 6f 72 74 65 72   + ((u8*)pSorter
e500: 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 2d 20 70  ->list.pList - p
e510: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65  Sorter->list.aMe
e520: 6d 6f 72 79 29 0a 20 20 20 20 20 20 29 3b 0a 20  mory).      );. 
e530: 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69       pSorter->li
e540: 73 74 2e 61 4d 65 6d 6f 72 79 20 3d 20 61 4e 65  st.aMemory = aNe
e550: 77 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72  w;.      pSorter
e560: 2d 3e 6e 4d 65 6d 6f 72 79 20 3d 20 6e 4e 65 77  ->nMemory = nNew
e570: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 4e 65  ;.    }..    pNe
e580: 77 20 3d 20 28 53 6f 72 74 65 72 52 65 63 6f 72  w = (SorterRecor
e590: 64 2a 29 26 70 53 6f 72 74 65 72 2d 3e 6c 69 73  d*)&pSorter->lis
e5a0: 74 2e 61 4d 65 6d 6f 72 79 5b 70 53 6f 72 74 65  t.aMemory[pSorte
e5b0: 72 2d 3e 69 4d 65 6d 6f 72 79 5d 3b 0a 20 20 20  r->iMemory];.   
e5c0: 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72   pSorter->iMemor
e5d0: 79 20 2b 3d 20 52 4f 55 4e 44 38 28 6e 52 65 71  y += ROUND8(nReq
e5e0: 29 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 75 2e 69  );.    pNew->u.i
e5f0: 4e 65 78 74 20 3d 20 28 69 6e 74 29 28 28 75 38  Next = (int)((u8
e600: 2a 29 28 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74  *)(pSorter->list
e610: 2e 70 4c 69 73 74 29 20 2d 20 70 53 6f 72 74 65  .pList) - pSorte
e620: 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 29  r->list.aMemory)
e630: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70  ;.  }else{.    p
e640: 4e 65 77 20 3d 20 28 53 6f 72 74 65 72 52 65 63  New = (SorterRec
e650: 6f 72 64 20 2a 29 73 71 6c 69 74 65 33 4d 61 6c  ord *)sqlite3Mal
e660: 6c 6f 63 28 6e 52 65 71 29 3b 0a 20 20 20 20 69  loc(nReq);.    i
e670: 66 28 20 70 4e 65 77 3d 3d 30 20 29 7b 0a 20 20  f( pNew==0 ){.  
e680: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
e690: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20  E_NOMEM;.    }. 
e6a0: 20 20 20 70 4e 65 77 2d 3e 75 2e 70 4e 65 78 74     pNew->u.pNext
e6b0: 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74   = pSorter->list
e6c0: 2e 70 4c 69 73 74 3b 0a 20 20 7d 0a 0a 20 20 6d  .pList;.  }..  m
e6d0: 65 6d 63 70 79 28 53 52 56 41 4c 28 70 4e 65 77  emcpy(SRVAL(pNew
e6e0: 29 2c 20 70 56 61 6c 2d 3e 7a 2c 20 70 56 61 6c  ), pVal->z, pVal
e6f0: 2d 3e 6e 29 3b 0a 20 20 70 4e 65 77 2d 3e 6e 56  ->n);.  pNew->nV
e700: 61 6c 20 3d 20 70 56 61 6c 2d 3e 6e 3b 0a 20 20  al = pVal->n;.  
e710: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c  pSorter->list.pL
e720: 69 73 74 20 3d 20 70 4e 65 77 3b 0a 0a 20 20 72  ist = pNew;..  r
e730: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
e740: 2a 2a 20 52 65 61 64 20 6b 65 79 73 20 66 72 6f  ** Read keys fro
e750: 6d 20 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65 72  m pIncr->pMerger
e760: 20 61 6e 64 20 70 6f 70 75 6c 61 74 65 20 70 49   and populate pI
e770: 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 2e 20 54  ncr->aFile[1]. T
e780: 68 65 20 66 6f 72 6d 61 74 0a 2a 2a 20 6f 66 20  he format.** of 
e790: 74 68 65 20 64 61 74 61 20 73 74 6f 72 65 64 20  the data stored 
e7a0: 69 6e 20 61 46 69 6c 65 5b 31 5d 20 69 73 20 74  in aFile[1] is t
e7b0: 68 65 20 73 61 6d 65 20 61 73 20 74 68 61 74 20  he same as that 
e7c0: 75 73 65 64 20 62 79 20 72 65 67 75 6c 61 72 20  used by regular 
e7d0: 50 4d 41 73 2c 0a 2a 2a 20 65 78 63 65 70 74 20  PMAs,.** except 
e7e0: 74 68 61 74 20 74 68 65 20 6e 75 6d 62 65 72 2d  that the number-
e7f0: 6f 66 2d 62 79 74 65 73 20 76 61 72 69 6e 74 20  of-bytes varint 
e800: 69 73 20 6f 6d 69 74 74 65 64 20 66 72 6f 6d 20  is omitted from 
e810: 74 68 65 20 73 74 61 72 74 2e 0a 2a 2f 0a 73 74  the start..*/.st
e820: 61 74 69 63 20 69 6e 74 20 76 64 62 65 49 6e 63  atic int vdbeInc
e830: 72 50 6f 70 75 6c 61 74 65 28 49 6e 63 72 4d 65  rPopulate(IncrMe
e840: 72 67 65 72 20 2a 70 49 6e 63 72 29 7b 0a 20 20  rger *pIncr){.  
e850: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
e860: 4f 4b 3b 0a 20 20 69 6e 74 20 72 63 32 3b 0a 20  OK;.  int rc2;. 
e870: 20 69 36 34 20 69 53 74 61 72 74 20 3d 20 70 49   i64 iStart = pI
e880: 6e 63 72 2d 3e 69 53 74 61 72 74 4f 66 66 3b 0a  ncr->iStartOff;.
e890: 20 20 53 6f 72 74 65 72 46 69 6c 65 20 2a 70 4f    SorterFile *pO
e8a0: 75 74 20 3d 20 26 70 49 6e 63 72 2d 3e 61 46 69  ut = &pIncr->aFi
e8b0: 6c 65 5b 31 5d 3b 0a 20 20 53 6f 72 74 53 75 62  le[1];.  SortSub
e8c0: 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20 70 49  task *pTask = pI
e8d0: 6e 63 72 2d 3e 70 54 61 73 6b 3b 0a 20 20 4d 65  ncr->pTask;.  Me
e8e0: 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67  rgeEngine *pMerg
e8f0: 65 72 20 3d 20 70 49 6e 63 72 2d 3e 70 4d 65 72  er = pIncr->pMer
e900: 67 65 72 3b 0a 20 20 50 6d 61 57 72 69 74 65 72  ger;.  PmaWriter
e910: 20 77 72 69 74 65 72 3b 0a 20 20 61 73 73 65 72   writer;.  asser
e920: 74 28 20 70 49 6e 63 72 2d 3e 62 45 6f 66 3d 3d  t( pIncr->bEof==
e930: 30 20 29 3b 0a 0a 20 20 76 64 62 65 53 6f 72 74  0 );..  vdbeSort
e940: 65 72 50 6f 70 75 6c 61 74 65 44 65 62 75 67 28  erPopulateDebug(
e950: 70 54 61 73 6b 2c 20 22 65 6e 74 65 72 22 29 3b  pTask, "enter");
e960: 0a 0a 20 20 76 64 62 65 50 6d 61 57 72 69 74 65  ..  vdbePmaWrite
e970: 72 49 6e 69 74 28 70 4f 75 74 2d 3e 70 46 64 2c  rInit(pOut->pFd,
e980: 20 26 77 72 69 74 65 72 2c 20 70 54 61 73 6b 2d   &writer, pTask-
e990: 3e 70 53 6f 72 74 65 72 2d 3e 70 67 73 7a 2c 20  >pSorter->pgsz, 
e9a0: 69 53 74 61 72 74 29 3b 0a 20 20 77 68 69 6c 65  iStart);.  while
e9b0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
e9c0: 29 7b 0a 20 20 20 20 69 6e 74 20 64 75 6d 6d 79  ){.    int dummy
e9d0: 3b 0a 20 20 20 20 50 6d 61 52 65 61 64 65 72 20  ;.    PmaReader 
e9e0: 2a 70 52 65 61 64 65 72 20 3d 20 26 70 4d 65 72  *pReader = &pMer
e9f0: 67 65 72 2d 3e 61 49 74 65 72 5b 20 70 4d 65 72  ger->aIter[ pMer
ea00: 67 65 72 2d 3e 61 54 72 65 65 5b 31 5d 20 5d 3b  ger->aTree[1] ];
ea10: 0a 20 20 20 20 69 6e 74 20 6e 4b 65 79 20 3d 20  .    int nKey = 
ea20: 70 52 65 61 64 65 72 2d 3e 6e 4b 65 79 3b 0a 20  pReader->nKey;. 
ea30: 20 20 20 69 36 34 20 69 45 6f 66 20 3d 20 77 72     i64 iEof = wr
ea40: 69 74 65 72 2e 69 57 72 69 74 65 4f 66 66 20 2b  iter.iWriteOff +
ea50: 20 77 72 69 74 65 72 2e 69 42 75 66 45 6e 64 3b   writer.iBufEnd;
ea60: 0a 0a 20 20 20 20 2f 2a 20 43 68 65 63 6b 20 69  ..    /* Check i
ea70: 66 20 74 68 65 20 6f 75 74 70 75 74 20 66 69 6c  f the output fil
ea80: 65 20 69 73 20 66 75 6c 6c 20 6f 72 20 69 66 20  e is full or if 
ea90: 74 68 65 20 69 6e 70 75 74 20 68 61 73 20 62 65  the input has be
eaa0: 65 6e 20 65 78 68 61 75 73 74 65 64 2e 0a 20 20  en exhausted..  
eab0: 20 20 2a 2a 20 49 6e 20 65 69 74 68 65 72 20 63    ** In either c
eac0: 61 73 65 20 65 78 69 74 20 74 68 65 20 6c 6f 6f  ase exit the loo
ead0: 70 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 52  p. */.    if( pR
eae0: 65 61 64 65 72 2d 3e 70 46 69 6c 65 3d 3d 30 20  eader->pFile==0 
eaf0: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 69 66 28  ) break;.    if(
eb00: 20 28 69 45 6f 66 20 2b 20 6e 4b 65 79 20 2b 20   (iEof + nKey + 
eb10: 73 71 6c 69 74 65 33 56 61 72 69 6e 74 4c 65 6e  sqlite3VarintLen
eb20: 28 6e 4b 65 79 29 29 3e 28 69 53 74 61 72 74 20  (nKey))>(iStart 
eb30: 2b 20 70 49 6e 63 72 2d 3e 6d 78 53 7a 29 20 29  + pIncr->mxSz) )
eb40: 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 2f 2a 20   break;..    /* 
eb50: 57 72 69 74 65 20 74 68 65 20 6e 65 78 74 20 6b  Write the next k
eb60: 65 79 20 74 6f 20 74 68 65 20 6f 75 74 70 75 74  ey to the output
eb70: 2e 20 2a 2f 0a 20 20 20 20 76 64 62 65 50 6d 61  . */.    vdbePma
eb80: 57 72 69 74 65 56 61 72 69 6e 74 28 26 77 72 69  WriteVarint(&wri
eb90: 74 65 72 2c 20 6e 4b 65 79 29 3b 0a 20 20 20 20  ter, nKey);.    
eba0: 76 64 62 65 50 6d 61 57 72 69 74 65 42 6c 6f 62  vdbePmaWriteBlob
ebb0: 28 26 77 72 69 74 65 72 2c 20 70 52 65 61 64 65  (&writer, pReade
ebc0: 72 2d 3e 61 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a  r->aKey, nKey);.
ebd0: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
ebe0: 74 65 72 4e 65 78 74 28 70 54 61 73 6b 2c 20 70  terNext(pTask, p
ebf0: 49 6e 63 72 2d 3e 70 4d 65 72 67 65 72 2c 20 26  Incr->pMerger, &
ec00: 64 75 6d 6d 79 29 3b 0a 20 20 7d 0a 0a 20 20 72  dummy);.  }..  r
ec10: 63 32 20 3d 20 76 64 62 65 50 6d 61 57 72 69 74  c2 = vdbePmaWrit
ec20: 65 72 46 69 6e 69 73 68 28 26 77 72 69 74 65 72  erFinish(&writer
ec30: 2c 20 26 70 4f 75 74 2d 3e 69 45 6f 66 29 3b 0a  , &pOut->iEof);.
ec40: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
ec50: 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63 32 3b 0a  _OK ) rc = rc2;.
ec60: 20 20 76 64 62 65 53 6f 72 74 65 72 50 6f 70 75    vdbeSorterPopu
ec70: 6c 61 74 65 44 65 62 75 67 28 70 54 61 73 6b 2c  lateDebug(pTask,
ec80: 20 22 65 78 69 74 22 29 3b 0a 20 20 72 65 74 75   "exit");.  retu
ec90: 72 6e 20 72 63 3b 0a 7d 0a 0a 23 69 66 20 53 51  rn rc;.}..#if SQ
eca0: 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f  LITE_MAX_WORKER_
ecb0: 54 48 52 45 41 44 53 3e 30 0a 2f 2a 0a 2a 2a 20  THREADS>0./*.** 
ecc0: 54 68 65 20 6d 61 69 6e 20 72 6f 75 74 69 6e 65  The main routine
ecd0: 20 66 6f 72 20 62 61 63 6b 67 72 6f 75 6e 64 20   for background 
ece0: 74 68 72 65 61 64 73 20 74 68 61 74 20 70 6f 70  threads that pop
ecf0: 75 6c 61 74 65 20 61 46 69 6c 65 5b 31 5d 20 6f  ulate aFile[1] o
ed00: 66 0a 2a 2a 20 6d 75 6c 74 69 2d 74 68 72 65 61  f.** multi-threa
ed10: 64 65 64 20 49 6e 63 72 4d 65 72 67 65 72 20 6f  ded IncrMerger o
ed20: 62 6a 65 63 74 73 2e 0a 2a 2f 0a 73 74 61 74 69  bjects..*/.stati
ed30: 63 20 76 6f 69 64 20 2a 76 64 62 65 49 6e 63 72  c void *vdbeIncr
ed40: 50 6f 70 75 6c 61 74 65 54 68 72 65 61 64 28 76  PopulateThread(v
ed50: 6f 69 64 20 2a 70 43 74 78 29 7b 0a 20 20 49 6e  oid *pCtx){.  In
ed60: 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 20  crMerger *pIncr 
ed70: 3d 20 28 49 6e 63 72 4d 65 72 67 65 72 2a 29 70  = (IncrMerger*)p
ed80: 43 74 78 3b 0a 20 20 76 6f 69 64 20 2a 70 52 65  Ctx;.  void *pRe
ed90: 74 20 3d 20 53 51 4c 49 54 45 5f 49 4e 54 5f 54  t = SQLITE_INT_T
eda0: 4f 5f 50 54 52 28 20 76 64 62 65 49 6e 63 72 50  O_PTR( vdbeIncrP
edb0: 6f 70 75 6c 61 74 65 28 70 49 6e 63 72 29 20 29  opulate(pIncr) )
edc0: 3b 0a 20 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b  ;.  pIncr->pTask
edd0: 2d 3e 62 44 6f 6e 65 20 3d 20 31 3b 0a 20 20 72  ->bDone = 1;.  r
ede0: 65 74 75 72 6e 20 70 52 65 74 3b 0a 7d 0a 0a 2f  eturn pRet;.}../
edf0: 2a 0a 2a 2a 20 4c 61 75 6e 63 68 20 61 20 62 61  *.** Launch a ba
ee00: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
ee10: 74 6f 20 70 6f 70 75 6c 61 74 65 20 61 46 69 6c  to populate aFil
ee20: 65 5b 31 5d 20 6f 66 20 70 49 6e 63 72 2e 0a 2a  e[1] of pIncr..*
ee30: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
ee40: 65 49 6e 63 72 42 67 50 6f 70 75 6c 61 74 65 28  eIncrBgPopulate(
ee50: 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63  IncrMerger *pInc
ee60: 72 29 7b 0a 20 20 76 6f 69 64 20 2a 70 20 3d 20  r){.  void *p = 
ee70: 28 76 6f 69 64 2a 29 70 49 6e 63 72 3b 0a 20 20  (void*)pIncr;.  
ee80: 61 73 73 65 72 74 28 20 70 49 6e 63 72 2d 3e 62  assert( pIncr->b
ee90: 55 73 65 54 68 72 65 61 64 20 29 3b 0a 20 20 72  UseThread );.  r
eea0: 65 74 75 72 6e 20 76 64 62 65 53 6f 72 74 65 72  eturn vdbeSorter
eeb0: 43 72 65 61 74 65 54 68 72 65 61 64 28 70 49 6e  CreateThread(pIn
eec0: 63 72 2d 3e 70 54 61 73 6b 2c 20 76 64 62 65 49  cr->pTask, vdbeI
eed0: 6e 63 72 50 6f 70 75 6c 61 74 65 54 68 72 65 61  ncrPopulateThrea
eee0: 64 2c 20 70 29 3b 0a 7d 0a 23 65 6e 64 69 66 0a  d, p);.}.#endif.
eef0: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
ef00: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 77  tion is called w
ef10: 68 65 6e 20 74 68 65 20 50 6d 61 52 65 61 64 65  hen the PmaReade
ef20: 72 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20  r corresponding 
ef30: 74 6f 20 70 49 6e 63 72 20 68 61 73 0a 2a 2a 20  to pIncr has.** 
ef40: 66 69 6e 69 73 68 65 64 20 72 65 61 64 69 6e 67  finished reading
ef50: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
ef60: 20 61 46 69 6c 65 5b 30 5d 2e 20 49 74 73 20 70   aFile[0]. Its p
ef70: 75 72 70 6f 73 65 20 69 73 20 74 6f 20 22 72 65  urpose is to "re
ef80: 66 69 6c 6c 22 0a 2a 2a 20 61 46 69 6c 65 5b 30  fill".** aFile[0
ef90: 5d 20 73 75 63 68 20 74 68 61 74 20 74 68 65 20  ] such that the 
efa0: 69 74 65 72 61 74 6f 72 20 73 68 6f 75 6c 64 20  iterator should 
efb0: 73 74 61 72 74 20 72 65 72 65 61 64 69 6e 67 20  start rereading 
efc0: 69 74 20 66 72 6f 6d 20 74 68 65 0a 2a 2a 20 62  it from the.** b
efd0: 65 67 69 6e 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20  eginning..**.** 
efe0: 46 6f 72 20 73 69 6e 67 6c 65 2d 74 68 72 65 61  For single-threa
eff0: 64 65 64 20 6f 62 6a 65 63 74 73 2c 20 74 68 69  ded objects, thi
f000: 73 20 69 73 20 61 63 63 6f 6d 70 6c 69 73 68 65  s is accomplishe
f010: 64 20 62 79 20 6c 69 74 65 72 61 6c 6c 79 20 72  d by literally r
f020: 65 61 64 69 6e 67 20 0a 2a 2a 20 6b 65 79 73 20  eading .** keys 
f030: 66 72 6f 6d 20 70 49 6e 63 72 2d 3e 70 4d 65 72  from pIncr->pMer
f040: 67 65 72 20 61 6e 64 20 72 65 70 6f 70 75 6c 61  ger and repopula
f050: 74 69 6e 67 20 61 46 69 6c 65 5b 30 5d 2e 20 0a  ting aFile[0]. .
f060: 2a 2a 0a 2a 2a 20 46 6f 72 20 6d 75 6c 74 69 2d  **.** For multi-
f070: 74 68 72 65 61 64 65 64 20 6f 62 6a 65 63 74 73  threaded objects
f080: 2c 20 61 6c 6c 20 74 68 61 74 20 69 73 20 72 65  , all that is re
f090: 71 75 69 72 65 64 20 69 73 20 74 6f 20 77 61 69  quired is to wai
f0a0: 74 20 75 6e 74 69 6c 20 74 68 65 20 0a 2a 2a 20  t until the .** 
f0b0: 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61  background threa
f0c0: 64 20 69 73 20 66 69 6e 69 73 68 65 64 20 28 69  d is finished (i
f0d0: 66 20 69 74 20 69 73 20 6e 6f 74 20 61 6c 72 65  f it is not alre
f0e0: 61 64 79 29 20 61 6e 64 20 74 68 65 6e 20 73 77  ady) and then sw
f0f0: 61 70 20 0a 2a 2a 20 61 46 69 6c 65 5b 30 5d 20  ap .** aFile[0] 
f100: 61 6e 64 20 61 46 69 6c 65 5b 31 5d 20 69 6e 20  and aFile[1] in 
f110: 70 6c 61 63 65 2e 20 49 66 20 74 68 65 20 63 6f  place. If the co
f120: 6e 74 65 6e 74 73 20 6f 66 20 70 4d 65 72 67 65  ntents of pMerge
f130: 72 20 68 61 76 65 20 6e 6f 74 0a 2a 2a 20 62 65  r have not.** be
f140: 65 6e 20 65 78 68 61 75 73 74 65 64 2c 20 74 68  en exhausted, th
f150: 69 73 20 66 75 6e 63 74 69 6f 6e 20 61 6c 73 6f  is function also
f160: 20 6c 61 75 6e 63 68 65 73 20 61 20 6e 65 77 20   launches a new 
f170: 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61  background threa
f180: 64 0a 2a 2a 20 74 6f 20 70 6f 70 75 6c 61 74 65  d.** to populate
f190: 20 74 68 65 20 6e 65 77 20 61 46 69 6c 65 5b 31   the new aFile[1
f1a0: 5d 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f  ]..**.** SQLITE_
f1b0: 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 6f  OK is returned o
f1c0: 6e 20 73 75 63 63 65 73 73 2c 20 6f 72 20 61 6e  n success, or an
f1d0: 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
f1e0: 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f  de otherwise..*/
f1f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65  .static int vdbe
f200: 49 6e 63 72 53 77 61 70 28 49 6e 63 72 4d 65 72  IncrSwap(IncrMer
f210: 67 65 72 20 2a 70 49 6e 63 72 29 7b 0a 20 20 69  ger *pIncr){.  i
f220: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
f230: 4b 3b 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d  K;..#if SQLITE_M
f240: 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44  AX_WORKER_THREAD
f250: 53 3e 30 0a 20 20 69 66 28 20 70 49 6e 63 72 2d  S>0.  if( pIncr-
f260: 3e 62 55 73 65 54 68 72 65 61 64 20 29 7b 0a 20  >bUseThread ){. 
f270: 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74     rc = vdbeSort
f280: 65 72 4a 6f 69 6e 54 68 72 65 61 64 28 70 49 6e  erJoinThread(pIn
f290: 63 72 2d 3e 70 54 61 73 6b 29 3b 0a 0a 20 20 20  cr->pTask);..   
f2a0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
f2b0: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 53 6f 72 74  OK ){.      Sort
f2c0: 65 72 46 69 6c 65 20 66 30 20 3d 20 70 49 6e 63  erFile f0 = pInc
f2d0: 72 2d 3e 61 46 69 6c 65 5b 30 5d 3b 0a 20 20 20  r->aFile[0];.   
f2e0: 20 20 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b     pIncr->aFile[
f2f0: 30 5d 20 3d 20 70 49 6e 63 72 2d 3e 61 46 69 6c  0] = pIncr->aFil
f300: 65 5b 31 5d 3b 0a 20 20 20 20 20 20 70 49 6e 63  e[1];.      pInc
f310: 72 2d 3e 61 46 69 6c 65 5b 31 5d 20 3d 20 66 30  r->aFile[1] = f0
f320: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  ;.    }..    if(
f330: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
f340: 7b 0a 20 20 20 20 20 20 69 66 28 20 70 49 6e 63  {.      if( pInc
f350: 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e 69 45 6f 66  r->aFile[0].iEof
f360: 3d 3d 70 49 6e 63 72 2d 3e 69 53 74 61 72 74 4f  ==pIncr->iStartO
f370: 66 66 20 29 7b 0a 20 20 20 20 20 20 20 20 70 49  ff ){.        pI
f380: 6e 63 72 2d 3e 62 45 6f 66 20 3d 20 31 3b 0a 20  ncr->bEof = 1;. 
f390: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
f3a0: 20 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63      rc = vdbeInc
f3b0: 72 42 67 50 6f 70 75 6c 61 74 65 28 70 49 6e 63  rBgPopulate(pInc
f3c0: 72 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  r);.      }.    
f3d0: 7d 0a 20 20 7d 65 6c 73 65 0a 23 65 6e 64 69 66  }.  }else.#endif
f3e0: 0a 20 20 7b 0a 20 20 20 20 72 63 20 3d 20 76 64  .  {.    rc = vd
f3f0: 62 65 49 6e 63 72 50 6f 70 75 6c 61 74 65 28 70  beIncrPopulate(p
f400: 49 6e 63 72 29 3b 0a 20 20 20 20 70 49 6e 63 72  Incr);.    pIncr
f410: 2d 3e 61 46 69 6c 65 5b 30 5d 20 3d 20 70 49 6e  ->aFile[0] = pIn
f420: 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 3b 0a 20 20  cr->aFile[1];.  
f430: 20 20 69 66 28 20 70 49 6e 63 72 2d 3e 61 46 69    if( pIncr->aFi
f440: 6c 65 5b 30 5d 2e 69 45 6f 66 3d 3d 70 49 6e 63  le[0].iEof==pInc
f450: 72 2d 3e 69 53 74 61 72 74 4f 66 66 20 29 7b 0a  r->iStartOff ){.
f460: 20 20 20 20 20 20 70 49 6e 63 72 2d 3e 62 45 6f        pIncr->bEo
f470: 66 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d  f = 1;.    }.  }
f480: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
f490: 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65  ../*.** Allocate
f4a0: 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20 6e 65   and return a ne
f4b0: 77 20 49 6e 63 72 4d 65 72 67 65 72 20 6f 62 6a  w IncrMerger obj
f4c0: 65 63 74 20 74 6f 20 72 65 61 64 20 64 61 74 61  ect to read data
f4d0: 20 66 72 6f 6d 20 70 4d 65 72 67 65 72 2e 0a 2a   from pMerger..*
f4e0: 2a 0a 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 63  *.** If an OOM c
f4f0: 6f 6e 64 69 74 69 6f 6e 20 69 73 20 65 6e 63 6f  ondition is enco
f500: 75 6e 74 65 72 65 64 2c 20 72 65 74 75 72 6e 20  untered, return 
f510: 4e 55 4c 4c 2e 20 49 6e 20 74 68 69 73 20 63 61  NULL. In this ca
f520: 73 65 20 66 72 65 65 20 74 68 65 0a 2a 2a 20 70  se free the.** p
f530: 4d 65 72 67 65 72 20 61 72 67 75 6d 65 6e 74 20  Merger argument 
f540: 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  before returning
f550: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
f560: 76 64 62 65 49 6e 63 72 4e 65 77 28 0a 20 20 53  vdbeIncrNew(.  S
f570: 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
f580: 6b 2c 20 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e  k, .  MergeEngin
f590: 65 20 2a 70 4d 65 72 67 65 72 2c 0a 20 20 49 6e  e *pMerger,.  In
f5a0: 63 72 4d 65 72 67 65 72 20 2a 2a 70 70 4f 75 74  crMerger **ppOut
f5b0: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
f5c0: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 49 6e 63 72  QLITE_OK;.  Incr
f5d0: 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 20 3d 20  Merger *pIncr = 
f5e0: 2a 70 70 4f 75 74 20 3d 20 28 49 6e 63 72 4d 65  *ppOut = (IncrMe
f5f0: 72 67 65 72 2a 29 73 71 6c 69 74 65 33 5f 6d 61  rger*)sqlite3_ma
f600: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 49 6e 63 72  lloc(sizeof(Incr
f610: 4d 65 72 67 65 72 29 29 3b 0a 20 20 69 66 28 20  Merger));.  if( 
f620: 70 49 6e 63 72 20 29 7b 0a 20 20 20 20 6d 65 6d  pIncr ){.    mem
f630: 73 65 74 28 70 49 6e 63 72 2c 20 30 2c 20 73 69  set(pIncr, 0, si
f640: 7a 65 6f 66 28 49 6e 63 72 4d 65 72 67 65 72 29  zeof(IncrMerger)
f650: 29 3b 0a 20 20 20 20 70 49 6e 63 72 2d 3e 70 4d  );.    pIncr->pM
f660: 65 72 67 65 72 20 3d 20 70 4d 65 72 67 65 72 3b  erger = pMerger;
f670: 0a 20 20 20 20 70 49 6e 63 72 2d 3e 70 54 61 73  .    pIncr->pTas
f680: 6b 20 3d 20 70 54 61 73 6b 3b 0a 20 20 20 20 70  k = pTask;.    p
f690: 49 6e 63 72 2d 3e 6d 78 53 7a 20 3d 20 4d 41 58  Incr->mxSz = MAX
f6a0: 28 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d  (pTask->pSorter-
f6b0: 3e 6d 78 4b 65 79 73 69 7a 65 2b 39 2c 70 54 61  >mxKeysize+9,pTa
f6c0: 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 6d 78 50  sk->pSorter->mxP
f6d0: 6d 61 53 69 7a 65 2f 32 29 3b 0a 20 20 20 20 70  maSize/2);.    p
f6e0: 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66  Task->file2.iEof
f6f0: 20 2b 3d 20 70 49 6e 63 72 2d 3e 6d 78 53 7a 3b   += pIncr->mxSz;
f700: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 76 64  .  }else{.    vd
f710: 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46 72 65  beMergeEngineFre
f720: 65 28 70 4d 65 72 67 65 72 29 3b 0a 20 20 20 20  e(pMerger);.    
f730: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
f740: 4d 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  M;.  }.  return 
f750: 72 63 3b 0a 7d 0a 0a 23 69 66 20 53 51 4c 49 54  rc;.}..#if SQLIT
f760: 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52  E_MAX_WORKER_THR
f770: 45 41 44 53 3e 30 0a 2f 2a 0a 2a 2a 20 53 65 74  EADS>0./*.** Set
f780: 20 74 68 65 20 22 75 73 65 2d 74 68 72 65 61 64   the "use-thread
f790: 73 22 20 66 6c 61 67 20 6f 6e 20 6f 62 6a 65 63  s" flag on objec
f7a0: 74 20 70 49 6e 63 72 2e 0a 2a 2f 0a 73 74 61 74  t pIncr..*/.stat
f7b0: 69 63 20 76 6f 69 64 20 76 64 62 65 49 6e 63 72  ic void vdbeIncr
f7c0: 53 65 74 54 68 72 65 61 64 73 28 49 6e 63 72 4d  SetThreads(IncrM
f7d0: 65 72 67 65 72 20 2a 70 49 6e 63 72 2c 20 69 6e  erger *pIncr, in
f7e0: 74 20 62 55 73 65 54 68 72 65 61 64 29 7b 0a 20  t bUseThread){. 
f7f0: 20 69 66 28 20 62 55 73 65 54 68 72 65 61 64 20   if( bUseThread 
f800: 29 7b 0a 20 20 20 20 70 49 6e 63 72 2d 3e 62 55  ){.    pIncr->bU
f810: 73 65 54 68 72 65 61 64 20 3d 20 31 3b 0a 20 20  seThread = 1;.  
f820: 20 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b 2d 3e    pIncr->pTask->
f830: 66 69 6c 65 32 2e 69 45 6f 66 20 2d 3d 20 70 49  file2.iEof -= pI
f840: 6e 63 72 2d 3e 6d 78 53 7a 3b 0a 20 20 7d 0a 7d  ncr->mxSz;.  }.}
f850: 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54  .#endif /* SQLIT
f860: 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52  E_MAX_WORKER_THR
f870: 45 41 44 53 3e 30 20 2a 2f 0a 0a 23 64 65 66 69  EADS>0 */..#defi
f880: 6e 65 20 49 4e 43 52 49 4e 49 54 5f 4e 4f 52 4d  ne INCRINIT_NORM
f890: 41 4c 20 30 0a 23 64 65 66 69 6e 65 20 49 4e 43  AL 0.#define INC
f8a0: 52 49 4e 49 54 5f 54 41 53 4b 20 20 20 31 0a 23  RINIT_TASK   1.#
f8b0: 64 65 66 69 6e 65 20 49 4e 43 52 49 4e 49 54 5f  define INCRINIT_
f8c0: 52 4f 4f 54 20 20 20 32 0a 73 74 61 74 69 63 20  ROOT   2.static 
f8d0: 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61 64 65  int vdbePmaReade
f8e0: 72 49 6e 63 72 49 6e 69 74 28 50 6d 61 52 65 61  rIncrInit(PmaRea
f8f0: 64 65 72 20 2a 70 49 74 65 72 2c 20 69 6e 74 20  der *pIter, int 
f900: 65 4d 6f 64 65 29 3b 0a 0a 2f 2a 0a 2a 2a 20 49  eMode);../*.** I
f910: 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 6d 65  nitialize the me
f920: 72 67 65 72 20 61 72 67 75 6d 65 6e 74 20 70 61  rger argument pa
f930: 73 73 65 64 20 61 73 20 74 68 65 20 73 65 63 6f  ssed as the seco
f940: 6e 64 20 61 72 67 75 6d 65 6e 74 2e 20 4f 6e 63  nd argument. Onc
f950: 65 20 74 68 69 73 0a 2a 2a 20 66 75 6e 63 74 69  e this.** functi
f960: 6f 6e 20 72 65 74 75 72 6e 73 2c 20 74 68 65 20  on returns, the 
f970: 66 69 72 73 74 20 6b 65 79 20 6f 66 20 6d 65 72  first key of mer
f980: 67 65 64 20 64 61 74 61 20 6d 61 79 20 62 65 20  ged data may be 
f990: 72 65 61 64 20 66 72 6f 6d 20 74 68 65 20 6d 65  read from the me
f9a0: 72 67 65 72 0a 2a 2a 20 6f 62 6a 65 63 74 20 69  rger.** object i
f9b0: 6e 20 74 68 65 20 75 73 75 61 6c 20 66 61 73 68  n the usual fash
f9c0: 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 72  ion..**.** If ar
f9d0: 67 75 6d 65 6e 74 20 65 4d 6f 64 65 20 69 73 20  gument eMode is 
f9e0: 49 4e 43 52 49 4e 49 54 5f 52 4f 4f 54 2c 20 74  INCRINIT_ROOT, t
f9f0: 68 65 6e 20 69 74 20 69 73 20 61 73 73 75 6d 65  hen it is assume
fa00: 64 20 74 68 61 74 20 61 6e 79 20 49 6e 63 72 4d  d that any IncrM
fa10: 65 72 67 65 0a 2a 2a 20 6f 62 6a 65 63 74 73 20  erge.** objects 
fa20: 61 74 74 61 63 68 65 64 20 74 6f 20 74 68 65 20  attached to the 
fa30: 50 6d 61 52 65 61 64 65 72 20 6f 62 6a 65 63 74  PmaReader object
fa40: 73 20 74 68 61 74 20 74 68 65 20 6d 65 72 67 65  s that the merge
fa50: 72 20 72 65 61 64 73 20 66 72 6f 6d 20 68 61 76  r reads from hav
fa60: 65 0a 2a 2a 20 61 6c 72 65 61 64 79 20 62 65 65  e.** already bee
fa70: 6e 20 70 6f 70 75 6c 61 74 65 64 2c 20 62 75 74  n populated, but
fa80: 20 74 68 61 74 20 74 68 65 79 20 68 61 76 65 20   that they have 
fa90: 6e 6f 74 20 79 65 74 20 70 6f 70 75 6c 61 74 65  not yet populate
faa0: 64 20 61 46 69 6c 65 5b 30 5d 20 61 6e 64 0a 2a  d aFile[0] and.*
fab0: 2a 20 73 65 74 20 74 68 65 20 50 6d 61 52 65 61  * set the PmaRea
fac0: 64 65 72 20 6f 62 6a 65 63 74 73 20 75 70 20 74  der objects up t
fad0: 6f 20 72 65 61 64 20 66 72 6f 6d 20 69 74 2e 20  o read from it. 
fae0: 49 6e 20 74 68 69 73 20 63 61 73 65 20 61 6c 6c  In this case all
faf0: 20 74 68 61 74 20 69 73 0a 2a 2a 20 72 65 71 75   that is.** requ
fb00: 69 72 65 64 20 69 73 20 74 6f 20 63 61 6c 6c 20  ired is to call 
fb10: 76 64 62 65 50 6d 61 52 65 61 64 65 72 4e 65 78  vdbePmaReaderNex
fb20: 74 28 29 20 6f 6e 20 65 61 63 68 20 69 74 65 72  t() on each iter
fb30: 61 74 6f 72 20 74 6f 20 70 6f 69 6e 74 20 69 74  ator to point it
fb40: 20 61 74 0a 2a 2a 20 69 74 73 20 66 69 72 73 74   at.** its first
fb50: 20 6b 65 79 2e 0a 2a 2a 0a 2a 2a 20 4f 74 68 65   key..**.** Othe
fb60: 72 77 69 73 65 2c 20 69 66 20 65 4d 6f 64 65 20  rwise, if eMode 
fb70: 69 73 20 61 6e 79 20 76 61 6c 75 65 20 6f 74 68  is any value oth
fb80: 65 72 20 74 68 61 6e 20 49 4e 43 52 49 4e 49 54  er than INCRINIT
fb90: 5f 52 4f 4f 54 2c 20 74 68 65 6e 20 75 73 65 20  _ROOT, then use 
fba0: 0a 2a 2a 20 76 64 62 65 50 6d 61 52 65 61 64 65  .** vdbePmaReade
fbb0: 72 49 6e 63 72 49 6e 69 74 28 29 20 74 6f 20 69  rIncrInit() to i
fbc0: 6e 69 74 69 61 6c 69 7a 65 20 65 61 63 68 20 50  nitialize each P
fbd0: 6d 61 52 65 61 64 65 72 20 74 68 61 74 20 66 65  maReader that fe
fbe0: 65 64 73 20 64 61 74 61 20 0a 2a 2a 20 74 6f 20  eds data .** to 
fbf0: 70 4d 65 72 67 65 72 2e 0a 2a 2a 0a 2a 2a 20 53  pMerger..**.** S
fc00: 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75  QLITE_OK is retu
fc10: 72 6e 65 64 20 69 66 20 73 75 63 63 65 73 73 66  rned if successf
fc20: 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65  ul, or an SQLite
fc30: 20 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65   error code othe
fc40: 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  rwise..*/.static
fc50: 20 69 6e 74 20 76 64 62 65 49 6e 63 72 49 6e 69   int vdbeIncrIni
fc60: 74 4d 65 72 67 65 72 28 0a 20 20 53 6f 72 74 53  tMerger(.  SortS
fc70: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 0a  ubtask *pTask, .
fc80: 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70    MergeEngine *p
fc90: 4d 65 72 67 65 72 2c 20 0a 20 20 69 6e 74 20 65  Merger, .  int e
fca0: 4d 6f 64 65 20 20 20 20 20 20 20 20 20 20 20 20  Mode            
fcb0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e             /* On
fcc0: 65 20 6f 66 20 74 68 65 20 49 4e 43 52 49 4e 49  e of the INCRINI
fcd0: 54 5f 58 58 58 20 63 6f 6e 73 74 61 6e 74 73 20  T_XXX constants 
fce0: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  */.){.  int rc =
fcf0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20   SQLITE_OK;     
fd00: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
fd10: 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20  n code */.  int 
fd20: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
fd30: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
fd40: 6f 72 20 69 74 65 72 61 74 69 6e 67 20 74 68 72  or iterating thr
fd50: 6f 75 67 68 20 50 6d 61 52 65 61 64 65 72 20 6f  ough PmaReader o
fd60: 62 6a 65 63 74 73 20 2a 2f 0a 0a 20 20 66 6f 72  bjects */..  for
fd70: 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45  (i=0; rc==SQLITE
fd80: 5f 4f 4b 20 26 26 20 69 3c 70 4d 65 72 67 65 72  _OK && i<pMerger
fd90: 2d 3e 6e 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20  ->nTree; i++){. 
fda0: 20 20 20 69 66 28 20 65 4d 6f 64 65 3d 3d 49 4e     if( eMode==IN
fdb0: 43 52 49 4e 49 54 5f 52 4f 4f 54 20 29 7b 0a 20  CRINIT_ROOT ){. 
fdc0: 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d       rc = vdbePm
fdd0: 61 52 65 61 64 65 72 4e 65 78 74 28 26 70 4d 65  aReaderNext(&pMe
fde0: 72 67 65 72 2d 3e 61 49 74 65 72 5b 69 5d 29 3b  rger->aIter[i]);
fdf0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
fe00: 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65    rc = vdbePmaRe
fe10: 61 64 65 72 49 6e 63 72 49 6e 69 74 28 26 70 4d  aderIncrInit(&pM
fe20: 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 69 5d 2c  erger->aIter[i],
fe30: 20 49 4e 43 52 49 4e 49 54 5f 4e 4f 52 4d 41 4c   INCRINIT_NORMAL
fe40: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
fe50: 66 6f 72 28 69 3d 70 4d 65 72 67 65 72 2d 3e 6e  for(i=pMerger->n
fe60: 54 72 65 65 2d 31 3b 20 72 63 3d 3d 53 51 4c 49  Tree-1; rc==SQLI
fe70: 54 45 5f 4f 4b 20 26 26 20 69 3e 30 3b 20 69 2d  TE_OK && i>0; i-
fe80: 2d 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62  -){.    rc = vdb
fe90: 65 53 6f 72 74 65 72 44 6f 43 6f 6d 70 61 72 65  eSorterDoCompare
fea0: 28 70 54 61 73 6b 2c 20 70 4d 65 72 67 65 72 2c  (pTask, pMerger,
feb0: 20 69 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75   i);.  }..  retu
fec0: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
fed0: 49 66 20 74 68 65 20 50 6d 61 52 65 61 64 65 72  If the PmaReader
fee0: 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66   passed as the f
fef0: 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 69 73  irst argument is
ff00: 20 6e 6f 74 20 61 6e 20 69 6e 63 72 65 6d 65 6e   not an incremen
ff10: 74 61 6c 2d 72 65 61 64 65 72 0a 2a 2a 20 28 69  tal-reader.** (i
ff20: 66 20 70 49 74 65 72 2d 3e 70 49 6e 63 72 3d 3d  f pIter->pIncr==
ff30: 30 29 2c 20 74 68 65 6e 20 74 68 69 73 20 66 75  0), then this fu
ff40: 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f  nction is a no-o
ff50: 70 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69 74  p. Otherwise, it
ff60: 20 73 65 72 76 65 73 0a 2a 2a 20 74 6f 20 6f 70   serves.** to op
ff70: 65 6e 20 61 6e 64 2f 6f 72 20 69 6e 69 74 69 61  en and/or initia
ff80: 6c 69 7a 65 20 74 68 65 20 74 65 6d 70 20 66 69  lize the temp fi
ff90: 6c 65 20 72 65 6c 61 74 65 64 20 66 69 65 6c 64  le related field
ffa0: 73 20 6f 66 20 74 68 65 20 49 6e 63 72 4d 65 72  s of the IncrMer
ffb0: 67 65 0a 2a 2a 20 6f 62 6a 65 63 74 20 61 74 20  ge.** object at 
ffc0: 28 70 49 74 65 72 2d 3e 70 49 6e 63 72 29 2e 0a  (pIter->pIncr)..
ffd0: 2a 2a 0a 2a 2a 20 49 66 20 61 72 67 75 6d 65 6e  **.** If argumen
ffe0: 74 20 65 4d 6f 64 65 20 69 73 20 73 65 74 20 74  t eMode is set t
fff0: 6f 20 49 4e 43 52 49 4e 49 54 5f 4e 4f 52 4d 41  o INCRINIT_NORMA
10000 4c 2c 20 74 68 65 6e 20 50 6d 61 52 65 61 64 65  L, then PmaReade
10010 72 20 69 74 65 72 61 74 6f 72 73 0a 2a 2a 20 69  r iterators.** i
10020 6e 20 74 68 65 20 73 75 62 2d 74 72 65 65 20 68  n the sub-tree h
10030 65 61 64 65 64 20 62 79 20 70 49 74 65 72 20 61  eaded by pIter a
10040 72 65 20 61 6c 73 6f 20 69 6e 69 74 69 61 6c 69  re also initiali
10050 7a 65 64 2e 20 44 61 74 61 20 69 73 20 74 68 65  zed. Data is the
10060 6e 20 6c 6f 61 64 65 64 0a 2a 2a 20 69 6e 74 6f  n loaded.** into
10070 20 74 68 65 20 62 75 66 66 65 72 73 20 62 65 6c   the buffers bel
10080 6f 6e 67 69 6e 67 20 74 6f 20 74 68 69 73 20 69  onging to this i
10090 74 65 72 61 74 6f 72 2c 20 70 49 74 65 72 2c 20  terator, pIter, 
100a0 61 6e 64 20 69 74 20 69 73 20 73 65 74 20 74 6f  and it is set to
100b0 0a 2a 2a 20 70 6f 69 6e 74 20 74 6f 20 74 68 65  .** point to the
100c0 20 66 69 72 73 74 20 6b 65 79 20 69 6e 20 69 74   first key in it
100d0 73 20 72 61 6e 67 65 2e 0a 2a 2a 0a 2a 2a 20 49  s range..**.** I
100e0 66 20 61 72 67 75 6d 65 6e 74 20 65 4d 6f 64 65  f argument eMode
100f0 20 69 73 20 73 65 74 20 74 6f 20 49 4e 43 52 49   is set to INCRI
10100 4e 49 54 5f 54 41 53 4b 2c 20 74 68 65 6e 20 50  NIT_TASK, then P
10110 6d 61 52 65 61 64 65 72 20 69 73 20 67 75 61 72  maReader is guar
10120 61 6e 74 65 65 64 0a 2a 2a 20 74 6f 20 62 65 20  anteed.** to be 
10130 61 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64  a multi-threaded
10140 20 69 74 65 72 61 74 6f 72 20 61 6e 64 20 74 68   iterator and th
10150 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 62  is function is b
10160 65 69 6e 67 20 63 61 6c 6c 65 64 20 69 6e 20 61  eing called in a
10170 0a 2a 2a 20 62 61 63 6b 67 72 6f 75 6e 64 20 74  .** background t
10180 68 72 65 61 64 2e 20 49 6e 20 74 68 69 73 20 63  hread. In this c
10190 61 73 65 20 61 6c 6c 20 69 74 65 72 61 74 6f 72  ase all iterator
101a0 73 20 69 6e 20 74 68 65 20 73 75 62 2d 74 72 65  s in the sub-tre
101b0 65 20 61 72 65 20 0a 2a 2a 20 69 6e 69 74 69 61  e are .** initia
101c0 6c 69 7a 65 64 20 61 73 20 66 6f 72 20 49 4e 43  lized as for INC
101d0 52 49 4e 49 54 5f 4e 4f 52 4d 41 4c 20 61 6e 64  RINIT_NORMAL and
101e0 20 74 68 65 20 61 46 69 6c 65 5b 31 5d 20 62 75   the aFile[1] bu
101f0 66 66 65 72 20 62 65 6c 6f 6e 67 69 6e 67 20 74  ffer belonging t
10200 6f 0a 2a 2a 20 70 49 74 65 72 20 69 73 20 70 6f  o.** pIter is po
10210 70 75 6c 61 74 65 64 2e 20 48 6f 77 65 76 65 72  pulated. However
10220 2c 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 69  , the iterator i
10230 74 73 65 6c 66 20 69 73 20 6e 6f 74 20 73 65 74  tself is not set
10240 20 75 70 20 74 6f 20 70 6f 69 6e 74 0a 2a 2a 20   up to point.** 
10250 74 6f 20 69 74 73 20 66 69 72 73 74 20 6b 65 79  to its first key
10260 2e 20 41 20 63 61 6c 6c 20 74 6f 20 76 64 62 65  . A call to vdbe
10270 50 6d 61 52 65 61 64 65 72 4e 65 78 74 28 29 20  PmaReaderNext() 
10280 69 73 20 73 74 69 6c 6c 20 72 65 71 75 69 72 65  is still require
10290 64 20 74 6f 20 64 6f 0a 2a 2a 20 74 68 61 74 2e  d to do.** that.
102a0 20 0a 2a 2a 0a 2a 2a 20 54 68 65 20 72 65 61 73   .**.** The reas
102b0 6f 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  on this function
102c0 20 64 6f 65 73 20 6e 6f 74 20 63 61 6c 6c 20 76   does not call v
102d0 64 62 65 50 6d 61 52 65 61 64 65 72 4e 65 78 74  dbePmaReaderNext
102e0 28 29 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 0a  () immediately .
102f0 2a 2a 20 69 6e 20 74 68 65 20 49 4e 43 52 49 4e  ** in the INCRIN
10300 49 54 5f 54 41 53 4b 20 63 61 73 65 20 69 73 20  IT_TASK case is 
10310 74 68 61 74 20 76 64 62 65 50 6d 61 52 65 61 64  that vdbePmaRead
10320 65 72 4e 65 78 74 28 29 20 61 73 73 75 6d 65 73  erNext() assumes
10330 20 74 68 61 74 20 68 61 73 0a 2a 2a 20 74 6f 20   that has.** to 
10340 62 6c 6f 63 6b 20 6f 6e 20 74 68 72 65 61 64 20  block on thread 
10350 28 70 54 61 73 6b 2d 3e 74 68 72 65 61 64 29 20  (pTask->thread) 
10360 62 65 66 6f 72 65 20 61 63 63 65 73 73 69 6e 67  before accessing
10370 20 61 46 69 6c 65 5b 31 5d 2e 20 42 75 74 2c 20   aFile[1]. But, 
10380 73 69 6e 63 65 0a 2a 2a 20 74 68 69 73 20 65 6e  since.** this en
10390 74 69 72 65 20 66 75 6e 63 74 69 6f 6e 20 69 73  tire function is
103a0 20 62 65 69 6e 67 20 72 75 6e 20 62 79 20 74 68   being run by th
103b0 72 65 61 64 20 28 70 54 61 73 6b 2d 3e 74 68 72  read (pTask->thr
103c0 65 61 64 29 2c 20 74 68 61 74 20 77 69 6c 6c 0a  ead), that will.
103d0 2a 2a 20 6c 65 61 64 20 74 6f 20 74 68 65 20 63  ** lead to the c
103e0 75 72 72 65 6e 74 20 62 61 63 6b 67 72 6f 75 6e  urrent backgroun
103f0 64 20 74 68 72 65 61 64 20 61 74 74 65 6d 70 74  d thread attempt
10400 69 6e 67 20 74 6f 20 6a 6f 69 6e 20 69 74 73 65  ing to join itse
10410 6c 66 2e 0a 2a 2a 0a 2a 2a 20 46 69 6e 61 6c 6c  lf..**.** Finall
10420 79 2c 20 69 66 20 61 72 67 75 6d 65 6e 74 20 65  y, if argument e
10430 4d 6f 64 65 20 69 73 20 73 65 74 20 74 6f 20 49  Mode is set to I
10440 4e 43 52 49 4e 49 54 5f 52 4f 4f 54 2c 20 69 74  NCRINIT_ROOT, it
10450 20 6d 61 79 20 62 65 20 61 73 73 75 6d 65 64 0a   may be assumed.
10460 2a 2a 20 74 68 61 74 20 70 49 74 65 72 2d 3e 70  ** that pIter->p
10470 49 6e 63 72 20 69 73 20 61 20 6d 75 6c 74 69 2d  Incr is a multi-
10480 74 68 72 65 61 64 65 64 20 49 6e 63 72 4d 65 72  threaded IncrMer
10490 67 65 20 6f 62 6a 65 63 74 73 2c 20 61 6e 64 20  ge objects, and 
104a0 74 68 61 74 20 61 6c 6c 0a 2a 2a 20 63 68 69 6c  that all.** chil
104b0 64 2d 74 72 65 65 73 20 68 61 76 65 20 61 6c 72  d-trees have alr
104c0 65 61 64 79 20 62 65 65 6e 20 69 6e 69 74 69 61  eady been initia
104d0 6c 69 7a 65 64 20 75 73 69 6e 67 20 49 6e 63 72  lized using Incr
104e0 49 6e 69 74 28 49 4e 43 52 49 4e 49 54 5f 54 41  Init(INCRINIT_TA
104f0 53 4b 29 2e 0a 2a 2a 20 49 6e 20 74 68 69 73 20  SK)..** In this 
10500 63 61 73 65 20 76 64 62 65 50 6d 61 52 65 61 64  case vdbePmaRead
10510 65 72 4e 65 78 74 28 29 20 69 73 20 63 61 6c 6c  erNext() is call
10520 65 64 20 6f 6e 20 61 6c 6c 20 63 68 69 6c 64 20  ed on all child 
10530 69 74 65 72 61 74 6f 72 73 20 61 6e 64 0a 2a 2a  iterators and.**
10540 20 74 68 65 20 63 75 72 72 65 6e 74 20 69 74 65   the current ite
10550 72 61 74 6f 72 20 73 65 74 20 74 6f 20 70 6f 69  rator set to poi
10560 6e 74 20 74 6f 20 74 68 65 20 66 69 72 73 74 20  nt to the first 
10570 6b 65 79 20 69 6e 20 69 74 73 20 72 61 6e 67 65  key in its range
10580 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f  ..**.** SQLITE_O
10590 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 69 66  K is returned if
105a0 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20   successful, or 
105b0 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
105c0 63 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a  code otherwise..
105d0 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
105e0 62 65 50 6d 61 52 65 61 64 65 72 49 6e 63 72 49  bePmaReaderIncrI
105f0 6e 69 74 28 50 6d 61 52 65 61 64 65 72 20 2a 70  nit(PmaReader *p
10600 49 74 65 72 2c 20 69 6e 74 20 65 4d 6f 64 65 29  Iter, int eMode)
10610 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
10620 49 54 45 5f 4f 4b 3b 0a 20 20 49 6e 63 72 4d 65  ITE_OK;.  IncrMe
10630 72 67 65 72 20 2a 70 49 6e 63 72 20 3d 20 70 49  rger *pIncr = pI
10640 74 65 72 2d 3e 70 49 6e 63 72 3b 0a 20 20 69 66  ter->pIncr;.  if
10650 28 20 70 49 6e 63 72 20 29 7b 0a 20 20 20 20 53  ( pIncr ){.    S
10660 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
10670 6b 20 3d 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b  k = pIncr->pTask
10680 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 20 2a 64  ;.    sqlite3 *d
10690 62 20 3d 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74  b = pTask->pSort
106a0 65 72 2d 3e 64 62 3b 0a 0a 20 20 20 20 72 63 20  er->db;..    rc 
106b0 3d 20 76 64 62 65 49 6e 63 72 49 6e 69 74 4d 65  = vdbeIncrInitMe
106c0 72 67 65 72 28 70 54 61 73 6b 2c 20 70 49 6e 63  rger(pTask, pInc
106d0 72 2d 3e 70 4d 65 72 67 65 72 2c 20 65 4d 6f 64  r->pMerger, eMod
106e0 65 29 3b 0a 0a 20 20 20 20 2f 2a 20 53 65 74 20  e);..    /* Set 
106f0 75 70 20 74 68 65 20 72 65 71 75 69 72 65 64 20  up the required 
10700 66 69 6c 65 73 20 66 6f 72 20 70 49 6e 63 72 2e  files for pIncr.
10710 20 41 20 6d 75 6c 74 69 2d 74 68 65 61 64 65 64   A multi-theaded
10720 20 49 6e 63 72 4d 65 72 67 65 20 6f 62 6a 65 63   IncrMerge objec
10730 74 0a 20 20 20 20 2a 2a 20 72 65 71 75 69 72 65  t.    ** require
10740 73 20 74 77 6f 20 74 65 6d 70 20 66 69 6c 65 73  s two temp files
10750 20 74 6f 20 69 74 73 65 6c 66 2c 20 77 68 65 72   to itself, wher
10760 65 61 73 20 61 20 73 69 6e 67 6c 65 2d 74 68 72  eas a single-thr
10770 65 61 64 65 64 20 6f 62 6a 65 63 74 0a 20 20 20  eaded object.   
10780 20 2a 2a 20 6f 6e 6c 79 20 72 65 71 75 69 72 65   ** only require
10790 73 20 61 20 72 65 67 69 6f 6e 20 6f 66 20 70 54  s a region of pT
107a0 61 73 6b 2d 3e 66 69 6c 65 32 2e 20 2a 2f 0a 20  ask->file2. */. 
107b0 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
107c0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 6e  E_OK ){.      in
107d0 74 20 6d 78 53 7a 20 3d 20 70 49 6e 63 72 2d 3e  t mxSz = pIncr->
107e0 6d 78 53 7a 3b 0a 20 20 20 20 20 20 69 66 28 20  mxSz;.      if( 
107f0 70 49 6e 63 72 2d 3e 62 55 73 65 54 68 72 65 61  pIncr->bUseThrea
10800 64 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  d==0 ){.        
10810 69 66 28 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32  if( pTask->file2
10820 2e 70 46 64 3d 3d 30 20 29 7b 0a 20 20 20 20 20  .pFd==0 ){.     
10830 20 20 20 20 20 61 73 73 65 72 74 28 20 70 54 61       assert( pTa
10840 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 3e 30  sk->file2.iEof>0
10850 20 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63   );.          rc
10860 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4f 70 65   = vdbeSorterOpe
10870 6e 54 65 6d 70 46 69 6c 65 28 64 62 2c 20 70 54  nTempFile(db, pT
10880 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 2c  ask->file2.iEof,
10890 20 26 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70   &pTask->file2.p
108a0 46 64 29 3b 0a 20 20 20 20 20 20 20 20 20 20 70  Fd);.          p
108b0 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66  Task->file2.iEof
108c0 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7d 0a   = 0;.        }.
108d0 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d          if( rc==
108e0 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
108f0 20 20 20 20 20 20 20 70 49 6e 63 72 2d 3e 61 46         pIncr->aF
10900 69 6c 65 5b 31 5d 2e 70 46 64 20 3d 20 70 54 61  ile[1].pFd = pTa
10910 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64 3b 0a 20  sk->file2.pFd;. 
10920 20 20 20 20 20 20 20 20 20 70 49 6e 63 72 2d 3e           pIncr->
10930 69 53 74 61 72 74 4f 66 66 20 3d 20 70 54 61 73  iStartOff = pTas
10940 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 3b 0a 20  k->file2.iEof;. 
10950 20 20 20 20 20 20 20 20 20 70 54 61 73 6b 2d 3e           pTask->
10960 66 69 6c 65 32 2e 69 45 6f 66 20 2b 3d 20 6d 78  file2.iEof += mx
10970 53 7a 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  Sz;.        }.  
10980 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
10990 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74     rc = vdbeSort
109a0 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 64  erOpenTempFile(d
109b0 62 2c 20 6d 78 53 7a 2c 20 26 70 49 6e 63 72 2d  b, mxSz, &pIncr-
109c0 3e 61 46 69 6c 65 5b 30 5d 2e 70 46 64 29 3b 0a  >aFile[0].pFd);.
109d0 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d          if( rc==
109e0 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
109f0 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65         rc = vdbe
10a00 53 6f 72 74 65 72 4f 70 65 6e 54 65 6d 70 46 69  SorterOpenTempFi
10a10 6c 65 28 64 62 2c 20 6d 78 53 7a 2c 20 26 70 49  le(db, mxSz, &pI
10a20 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 2e 70 46  ncr->aFile[1].pF
10a30 64 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  d);.        }.  
10a40 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20      }.    }..   
10a50 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
10a60 4f 4b 20 26 26 20 70 49 6e 63 72 2d 3e 62 55 73  OK && pIncr->bUs
10a70 65 54 68 72 65 61 64 20 29 7b 0a 20 20 20 20 20  eThread ){.     
10a80 20 2f 2a 20 55 73 65 20 74 68 65 20 63 75 72 72   /* Use the curr
10a90 65 6e 74 20 74 68 72 65 61 64 20 74 6f 20 70 6f  ent thread to po
10aa0 70 75 6c 61 74 65 20 61 46 69 6c 65 5b 31 5d 2c  pulate aFile[1],
10ab0 20 65 76 65 6e 20 74 68 6f 75 67 68 20 74 68 69   even though thi
10ac0 73 0a 20 20 20 20 20 20 2a 2a 20 69 74 65 72 61  s.      ** itera
10ad0 74 6f 72 20 69 73 20 6d 75 6c 74 69 2d 74 68 72  tor is multi-thr
10ae0 65 61 64 65 64 2e 20 54 68 65 20 72 65 61 73 6f  eaded. The reaso
10af0 6e 20 62 65 69 6e 67 20 74 68 61 74 20 74 68 69  n being that thi
10b00 73 20 66 75 6e 63 74 69 6f 6e 0a 20 20 20 20 20  s function.     
10b10 20 2a 2a 20 69 73 20 61 6c 72 65 61 64 79 20 72   ** is already r
10b20 75 6e 6e 69 6e 67 20 69 6e 20 62 61 63 6b 67 72  unning in backgr
10b30 6f 75 6e 64 20 74 68 72 65 61 64 20 70 49 6e 63  ound thread pInc
10b40 72 2d 3e 70 54 61 73 6b 2d 3e 74 68 72 65 61 64  r->pTask->thread
10b50 2e 20 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72  . */.      asser
10b60 74 28 20 65 4d 6f 64 65 3d 3d 49 4e 43 52 49 4e  t( eMode==INCRIN
10b70 49 54 5f 52 4f 4f 54 20 7c 7c 20 65 4d 6f 64 65  IT_ROOT || eMode
10b80 3d 3d 49 4e 43 52 49 4e 49 54 5f 54 41 53 4b 20  ==INCRINIT_TASK 
10b90 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64  );.      rc = vd
10ba0 62 65 49 6e 63 72 50 6f 70 75 6c 61 74 65 28 70  beIncrPopulate(p
10bb0 49 6e 63 72 29 3b 0a 20 20 20 20 7d 0a 0a 20 20  Incr);.    }..  
10bc0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
10bd0 5f 4f 4b 20 26 26 20 65 4d 6f 64 65 21 3d 49 4e  _OK && eMode!=IN
10be0 43 52 49 4e 49 54 5f 54 41 53 4b 20 29 7b 0a 20  CRINIT_TASK ){. 
10bf0 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d       rc = vdbePm
10c00 61 52 65 61 64 65 72 4e 65 78 74 28 70 49 74 65  aReaderNext(pIte
10c10 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  r);.    }.  }.  
10c20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 23 69  return rc;.}..#i
10c30 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52  f SQLITE_MAX_WOR
10c40 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 0a 2f 2a  KER_THREADS>0./*
10c50 0a 2a 2a 20 54 68 65 20 6d 61 69 6e 20 72 6f 75  .** The main rou
10c60 74 69 6e 65 20 66 6f 72 20 76 64 62 65 50 6d 61  tine for vdbePma
10c70 52 65 61 64 65 72 49 6e 63 72 49 6e 69 74 28 29  ReaderIncrInit()
10c80 20 6f 70 65 72 61 74 69 6f 6e 73 20 72 75 6e 20   operations run 
10c90 69 6e 20 0a 2a 2a 20 62 61 63 6b 67 72 6f 75 6e  in .** backgroun
10ca0 64 20 74 68 72 65 61 64 73 2e 0a 2a 2f 0a 73 74  d threads..*/.st
10cb0 61 74 69 63 20 76 6f 69 64 20 2a 76 64 62 65 50  atic void *vdbeP
10cc0 6d 61 52 65 61 64 65 72 42 67 49 6e 69 74 28 76  maReaderBgInit(v
10cd0 6f 69 64 20 2a 70 43 74 78 29 7b 0a 20 20 50 6d  oid *pCtx){.  Pm
10ce0 61 52 65 61 64 65 72 20 2a 70 52 65 61 64 65 72  aReader *pReader
10cf0 20 3d 20 28 50 6d 61 52 65 61 64 65 72 2a 29 70   = (PmaReader*)p
10d00 43 74 78 3b 0a 20 20 76 6f 69 64 20 2a 70 52 65  Ctx;.  void *pRe
10d10 74 20 3d 20 53 51 4c 49 54 45 5f 49 4e 54 5f 54  t = SQLITE_INT_T
10d20 4f 5f 50 54 52 28 76 64 62 65 50 6d 61 52 65 61  O_PTR(vdbePmaRea
10d30 64 65 72 49 6e 63 72 49 6e 69 74 28 70 52 65 61  derIncrInit(pRea
10d40 64 65 72 2c 49 4e 43 52 49 4e 49 54 5f 54 41 53  der,INCRINIT_TAS
10d50 4b 29 29 3b 0a 20 20 70 52 65 61 64 65 72 2d 3e  K));.  pReader->
10d60 70 49 6e 63 72 2d 3e 70 54 61 73 6b 2d 3e 62 44  pIncr->pTask->bD
10d70 6f 6e 65 20 3d 20 31 3b 0a 20 20 72 65 74 75 72  one = 1;.  retur
10d80 6e 20 70 52 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  n pRet;.}../*.**
10d90 20 55 73 65 20 61 20 62 61 63 6b 67 72 6f 75 6e   Use a backgroun
10da0 64 20 74 68 72 65 61 64 20 74 6f 20 69 6e 76 6f  d thread to invo
10db0 6b 65 20 76 64 62 65 50 6d 61 52 65 61 64 65 72  ke vdbePmaReader
10dc0 49 6e 63 72 49 6e 69 74 28 49 4e 43 52 49 4e 49  IncrInit(INCRINI
10dd0 54 5f 54 41 53 4b 29 20 0a 2a 2a 20 6f 6e 20 74  T_TASK) .** on t
10de0 68 65 20 74 68 65 20 50 6d 61 52 65 61 64 65 72  he the PmaReader
10df0 20 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20 61   object passed a
10e00 73 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75  s the first argu
10e10 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  ment..**.** This
10e20 20 63 61 6c 6c 20 77 69 6c 6c 20 69 6e 69 74 69   call will initi
10e30 61 6c 69 7a 65 20 74 68 65 20 76 61 72 69 6f 75  alize the variou
10e40 73 20 66 69 65 6c 64 73 20 6f 66 20 74 68 65 20  s fields of the 
10e50 70 49 74 65 72 2d 3e 70 49 6e 63 72 20 0a 2a 2a  pIter->pIncr .**
10e60 20 73 74 72 75 63 74 75 72 65 20 61 6e 64 2c 20   structure and, 
10e70 69 66 20 69 74 20 69 73 20 61 20 6d 75 6c 74 69  if it is a multi
10e80 2d 74 68 72 65 61 64 65 64 20 49 6e 63 72 4d 65  -threaded IncrMe
10e90 72 67 65 72 2c 20 6c 61 75 6e 63 68 20 61 20 0a  rger, launch a .
10ea0 2a 2a 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68  ** background th
10eb0 72 65 61 64 20 74 6f 20 70 6f 70 75 6c 61 74 65  read to populate
10ec0 20 61 46 69 6c 65 5b 31 5d 2e 0a 2a 2f 0a 73 74   aFile[1]..*/.st
10ed0 61 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d 61  atic int vdbePma
10ee0 52 65 61 64 65 72 42 67 49 6e 63 72 49 6e 69 74  ReaderBgIncrInit
10ef0 28 50 6d 61 52 65 61 64 65 72 20 2a 70 49 74 65  (PmaReader *pIte
10f00 72 29 7b 0a 20 20 76 6f 69 64 20 2a 70 43 74 78  r){.  void *pCtx
10f10 20 3d 20 28 76 6f 69 64 2a 29 70 49 74 65 72 3b   = (void*)pIter;
10f20 0a 20 20 72 65 74 75 72 6e 20 76 64 62 65 53 6f  .  return vdbeSo
10f30 72 74 65 72 43 72 65 61 74 65 54 68 72 65 61 64  rterCreateThread
10f40 28 70 49 74 65 72 2d 3e 70 49 6e 63 72 2d 3e 70  (pIter->pIncr->p
10f50 54 61 73 6b 2c 20 76 64 62 65 50 6d 61 52 65 61  Task, vdbePmaRea
10f60 64 65 72 42 67 49 6e 69 74 2c 20 70 43 74 78 29  derBgInit, pCtx)
10f70 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a  ;.}.#endif../*.*
10f80 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77  * Allocate a new
10f90 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 6f 62 6a   MergeEngine obj
10fa0 65 63 74 20 74 6f 20 6d 65 72 67 65 20 74 68 65  ect to merge the
10fb0 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6e 50 4d   contents of nPM
10fc0 41 20 6c 65 76 65 6c 2d 30 0a 2a 2a 20 50 4d 41  A level-0.** PMA
10fd0 73 20 66 72 6f 6d 20 70 54 61 73 6b 2d 3e 66 69  s from pTask->fi
10fe0 6c 65 2e 20 49 66 20 6e 6f 20 65 72 72 6f 72 20  le. If no error 
10ff0 6f 63 63 75 72 73 2c 20 73 65 74 20 2a 70 70 4f  occurs, set *ppO
11000 75 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 0a 2a  ut to point to.*
11010 2a 20 74 68 65 20 6e 65 77 20 6f 62 6a 65 63 74  * the new object
11020 20 61 6e 64 20 72 65 74 75 72 6e 20 53 51 4c 49   and return SQLI
11030 54 45 5f 4f 4b 2e 20 4f 72 2c 20 69 66 20 61 6e  TE_OK. Or, if an
11040 20 65 72 72 6f 72 20 64 6f 65 73 20 6f 63 63 75   error does occu
11050 72 2c 20 73 65 74 20 2a 70 70 4f 75 74 0a 2a 2a  r, set *ppOut.**
11060 20 74 6f 20 4e 55 4c 4c 20 61 6e 64 20 72 65 74   to NULL and ret
11070 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72  urn an SQLite er
11080 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20  ror code..**.** 
11090 57 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69  When this functi
110a0 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2c 20 2a 70  on is called, *p
110b0 69 4f 66 66 73 65 74 20 69 73 20 73 65 74 20 74  iOffset is set t
110c0 6f 20 74 68 65 20 6f 66 66 73 65 74 20 6f 66 20  o the offset of 
110d0 74 68 65 0a 2a 2a 20 66 69 72 73 74 20 50 4d 41  the.** first PMA
110e0 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 70 54   to read from pT
110f0 61 73 6b 2d 3e 66 69 6c 65 2e 20 41 73 73 75 6d  ask->file. Assum
11100 69 6e 67 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63  ing no error occ
11110 75 72 73 2c 20 69 74 20 69 73 20 0a 2a 2a 20 73  urs, it is .** s
11120 65 74 20 74 6f 20 74 68 65 20 6f 66 66 73 65 74  et to the offset
11130 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c   immediately fol
11140 6c 6f 77 69 6e 67 20 74 68 65 20 6c 61 73 74 20  lowing the last 
11150 62 79 74 65 20 6f 66 20 74 68 65 20 6c 61 73 74  byte of the last
11160 0a 2a 2a 20 50 4d 41 20 62 65 66 6f 72 65 20 72  .** PMA before r
11170 65 74 75 72 6e 69 6e 67 2e 20 49 66 20 61 6e 20  eturning. If an 
11180 65 72 72 6f 72 20 64 6f 65 73 20 6f 63 63 75 72  error does occur
11190 2c 20 74 68 65 6e 20 74 68 65 20 66 69 6e 61 6c  , then the final
111a0 20 76 61 6c 75 65 20 6f 66 0a 2a 2a 20 2a 70 69   value of.** *pi
111b0 4f 66 66 73 65 74 20 69 73 20 75 6e 64 65 66 69  Offset is undefi
111c0 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ned..*/.static i
111d0 6e 74 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69  nt vdbeMergeEngi
111e0 6e 65 4c 65 76 65 6c 30 28 0a 20 20 53 6f 72 74  neLevel0(.  Sort
111f0 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20  Subtask *pTask, 
11200 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
11210 6f 72 74 65 72 20 74 61 73 6b 20 74 6f 20 72 65  orter task to re
11220 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 6e 74  ad from */.  int
11230 20 6e 50 4d 41 2c 20 20 20 20 20 20 20 20 20 20   nPMA,          
11240 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
11250 4e 75 6d 62 65 72 20 6f 66 20 50 4d 41 73 20 74  Number of PMAs t
11260 6f 20 72 65 61 64 20 2a 2f 0a 20 20 69 36 34 20  o read */.  i64 
11270 2a 70 69 4f 66 66 73 65 74 2c 20 20 20 20 20 20  *piOffset,      
11280 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
11290 4e 2f 4f 55 54 3a 20 52 65 61 64 20 6f 66 66 73  N/OUT: Read offs
112a0 65 74 20 69 6e 20 70 54 61 73 6b 2d 3e 66 69 6c  et in pTask->fil
112b0 65 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69  e */.  MergeEngi
112c0 6e 65 20 2a 2a 70 70 4f 75 74 20 20 20 20 20 20  ne **ppOut      
112d0 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e         /* OUT: N
112e0 65 77 20 6d 65 72 67 65 2d 65 6e 67 69 6e 65 20  ew merge-engine 
112f0 2a 2f 0a 29 7b 0a 20 20 4d 65 72 67 65 45 6e 67  */.){.  MergeEng
11300 69 6e 65 20 2a 70 4e 65 77 3b 20 20 20 20 20 20  ine *pNew;      
11310 20 20 20 20 20 20 20 20 2f 2a 20 4d 65 72 67 65          /* Merge
11320 20 65 6e 67 69 6e 65 20 74 6f 20 72 65 74 75 72   engine to retur
11330 6e 20 2a 2f 0a 20 20 69 36 34 20 69 4f 66 66 20  n */.  i64 iOff 
11340 3d 20 2a 70 69 4f 66 66 73 65 74 3b 0a 20 20 69  = *piOffset;.  i
11350 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72 63 20 3d  nt i;.  int rc =
11360 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2a   SQLITE_OK;..  *
11370 70 70 4f 75 74 20 3d 20 70 4e 65 77 20 3d 20 76  ppOut = pNew = v
11380 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4e 65  dbeMergeEngineNe
11390 77 28 6e 50 4d 41 29 3b 0a 20 20 69 66 28 20 70  w(nPMA);.  if( p
113a0 4e 65 77 3d 3d 30 20 29 20 72 63 20 3d 20 53 51  New==0 ) rc = SQ
113b0 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 0a 20 20 66  LITE_NOMEM;..  f
113c0 6f 72 28 69 3d 30 3b 20 69 3c 6e 50 4d 41 20 26  or(i=0; i<nPMA &
113d0 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b  & rc==SQLITE_OK;
113e0 20 69 2b 2b 29 7b 0a 20 20 20 20 69 36 34 20 6e   i++){.    i64 n
113f0 44 75 6d 6d 79 3b 0a 20 20 20 20 50 6d 61 52 65  Dummy;.    PmaRe
11400 61 64 65 72 20 2a 70 49 74 65 72 20 3d 20 26 70  ader *pIter = &p
11410 4e 65 77 2d 3e 61 49 74 65 72 5b 69 5d 3b 0a 20  New->aIter[i];. 
11420 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52     rc = vdbePmaR
11430 65 61 64 65 72 49 6e 69 74 28 70 54 61 73 6b 2c  eaderInit(pTask,
11440 20 26 70 54 61 73 6b 2d 3e 66 69 6c 65 2c 20 69   &pTask->file, i
11450 4f 66 66 2c 20 70 49 74 65 72 2c 20 26 6e 44 75  Off, pIter, &nDu
11460 6d 6d 79 29 3b 0a 20 20 20 20 69 4f 66 66 20 3d  mmy);.    iOff =
11470 20 70 49 74 65 72 2d 3e 69 45 6f 66 3b 0a 20 20   pIter->iEof;.  
11480 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  }..  if( rc!=SQL
11490 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 64  ITE_OK ){.    vd
114a0 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46 72 65  beMergeEngineFre
114b0 65 28 70 4e 65 77 29 3b 0a 20 20 20 20 2a 70 70  e(pNew);.    *pp
114c0 4f 75 74 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 2a  Out = 0;.  }.  *
114d0 70 69 4f 66 66 73 65 74 20 3d 20 69 4f 66 66 3b  piOffset = iOff;
114e0 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
114f0 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  ./*.** Return th
11500 65 20 64 65 70 74 68 20 6f 66 20 61 20 74 72 65  e depth of a tre
11510 65 20 63 6f 6d 70 72 69 73 69 6e 67 20 6e 50 4d  e comprising nPM
11520 41 20 50 4d 41 73 2c 20 61 73 73 75 6d 69 6e 67  A PMAs, assuming
11530 20 61 20 66 61 6e 6f 75 74 20 6f 66 0a 2a 2a 20   a fanout of.** 
11540 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45  SORTER_MAX_MERGE
11550 5f 43 4f 55 4e 54 2e 20 54 68 65 20 72 65 74 75  _COUNT. The retu
11560 72 6e 65 64 20 76 61 6c 75 65 20 64 6f 65 73 20  rned value does 
11570 6e 6f 74 20 69 6e 63 6c 75 64 65 20 6c 65 61 66  not include leaf
11580 20 6e 6f 64 65 73 2e 0a 2a 2a 0a 2a 2a 20 69 2e   nodes..**.** i.
11590 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 6e 50 4d 41 3c  e..**.**   nPMA<
115a0 3d 31 36 20 20 20 20 2d 3e 20 54 72 65 65 44 65  =16    -> TreeDe
115b0 70 74 68 28 29 20 3d 3d 20 30 0a 2a 2a 20 20 20  pth() == 0.**   
115c0 6e 50 4d 41 3c 3d 32 35 36 20 20 20 2d 3e 20 54  nPMA<=256   -> T
115d0 72 65 65 44 65 70 74 68 28 29 20 3d 3d 20 31 0a  reeDepth() == 1.
115e0 2a 2a 20 20 20 6e 50 4d 41 3c 3d 36 35 35 33 36  **   nPMA<=65536
115f0 20 2d 3e 20 54 72 65 65 44 65 70 74 68 28 29 20   -> TreeDepth() 
11600 3d 3d 20 32 0a 2a 2f 0a 73 74 61 74 69 63 20 69  == 2.*/.static i
11610 6e 74 20 76 64 62 65 53 6f 72 74 65 72 54 72 65  nt vdbeSorterTre
11620 65 44 65 70 74 68 28 69 6e 74 20 6e 50 4d 41 29  eDepth(int nPMA)
11630 7b 0a 20 20 69 6e 74 20 6e 44 65 70 74 68 20 3d  {.  int nDepth =
11640 20 30 3b 0a 20 20 69 36 34 20 6e 44 69 76 20 3d   0;.  i64 nDiv =
11650 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47   SORTER_MAX_MERG
11660 45 5f 43 4f 55 4e 54 3b 0a 20 20 77 68 69 6c 65  E_COUNT;.  while
11670 28 20 6e 44 69 76 20 3c 20 28 69 36 34 29 6e 50  ( nDiv < (i64)nP
11680 4d 41 20 29 7b 0a 20 20 20 20 6e 44 69 76 20 3d  MA ){.    nDiv =
11690 20 6e 44 69 76 20 2a 20 53 4f 52 54 45 52 5f 4d   nDiv * SORTER_M
116a0 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3b 0a  AX_MERGE_COUNT;.
116b0 20 20 20 20 6e 44 65 70 74 68 2b 2b 3b 0a 20 20      nDepth++;.  
116c0 7d 0a 20 20 72 65 74 75 72 6e 20 6e 44 65 70 74  }.  return nDept
116d0 68 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 70 52 6f 6f  h;.}../*.** pRoo
116e0 74 20 69 73 20 74 68 65 20 72 6f 6f 74 20 6f 66  t is the root of
116f0 20 61 6e 20 69 6e 63 72 65 6d 65 6e 74 61 6c 20   an incremental 
11700 6d 65 72 67 65 2d 74 72 65 65 20 77 69 74 68 20  merge-tree with 
11710 64 65 70 74 68 20 6e 44 65 70 74 68 20 28 61 63  depth nDepth (ac
11720 63 6f 72 64 69 6e 67 0a 2a 2a 20 74 6f 20 76 64  cording.** to vd
11730 62 65 53 6f 72 74 65 72 54 72 65 65 44 65 70 74  beSorterTreeDept
11740 68 28 29 29 2e 20 70 4c 65 61 66 20 69 73 20 74  h()). pLeaf is t
11750 68 65 20 69 53 65 71 27 74 68 20 6c 65 61 66 20  he iSeq'th leaf 
11760 74 6f 20 62 65 20 61 64 64 65 64 20 74 6f 20 74  to be added to t
11770 68 65 0a 2a 2a 20 74 72 65 65 2c 20 63 6f 75 6e  he.** tree, coun
11780 74 69 6e 67 20 66 72 6f 6d 20 7a 65 72 6f 2e 20  ting from zero. 
11790 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 61 64  This function ad
117a0 64 73 20 70 4c 65 61 66 20 74 6f 20 74 68 65 20  ds pLeaf to the 
117b0 74 72 65 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73  tree..**.** If s
117c0 75 63 63 65 73 73 66 75 6c 2c 20 53 51 4c 49 54  uccessful, SQLIT
117d0 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64  E_OK is returned
117e0 2e 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  . If an error oc
117f0 63 75 72 73 2c 20 61 6e 20 53 51 4c 69 74 65 20  curs, an SQLite 
11800 65 72 72 6f 72 0a 2a 2a 20 63 6f 64 65 20 69 73  error.** code is
11810 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 70 4c   returned and pL
11820 65 61 66 20 69 73 20 66 72 65 65 64 2e 0a 2a 2f  eaf is freed..*/
11830 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65  .static int vdbe
11840 53 6f 72 74 65 72 41 64 64 54 6f 54 72 65 65 28  SorterAddToTree(
11850 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a  .  SortSubtask *
11860 70 54 61 73 6b 2c 20 20 20 20 20 20 20 20 20 20  pTask,          
11870 20 20 20 2f 2a 20 54 61 73 6b 20 63 6f 6e 74 65     /* Task conte
11880 78 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 44 65 70  xt */.  int nDep
11890 74 68 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  th,             
118a0 20 20 20 20 20 20 20 20 2f 2a 20 44 65 70 74 68          /* Depth
118b0 20 6f 66 20 74 72 65 65 20 61 63 63 6f 72 64 69   of tree accordi
118c0 6e 67 20 74 6f 20 54 72 65 65 44 65 70 74 68 28  ng to TreeDepth(
118d0 29 20 2a 2f 0a 20 20 69 6e 74 20 69 53 65 71 2c  ) */.  int iSeq,
118e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
118f0 20 20 20 20 20 20 20 2f 2a 20 53 65 71 75 65 6e         /* Sequen
11900 63 65 20 6e 75 6d 62 65 72 20 6f 66 20 6c 65 61  ce number of lea
11910 66 20 77 69 74 68 69 6e 20 74 72 65 65 20 2a 2f  f within tree */
11920 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a  .  MergeEngine *
11930 70 52 6f 6f 74 2c 20 20 20 20 20 20 20 20 20 20  pRoot,          
11940 20 20 20 2f 2a 20 52 6f 6f 74 20 6f 66 20 74 72     /* Root of tr
11950 65 65 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67  ee */.  MergeEng
11960 69 6e 65 20 2a 70 4c 65 61 66 20 20 20 20 20 20  ine *pLeaf      
11970 20 20 20 20 20 20 20 20 2f 2a 20 4c 65 61 66 20          /* Leaf 
11980 74 6f 20 61 64 64 20 74 6f 20 74 72 65 65 20 2a  to add to tree *
11990 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  /.){.  int rc = 
119a0 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74  SQLITE_OK;.  int
119b0 20 6e 44 69 76 20 3d 20 31 3b 0a 20 20 69 6e 74   nDiv = 1;.  int
119c0 20 69 3b 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e   i;.  MergeEngin
119d0 65 20 2a 70 20 3d 20 70 52 6f 6f 74 3b 0a 20 20  e *p = pRoot;.  
119e0 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63  IncrMerger *pInc
119f0 72 3b 0a 0a 20 20 72 63 20 3d 20 76 64 62 65 49  r;..  rc = vdbeI
11a00 6e 63 72 4e 65 77 28 70 54 61 73 6b 2c 20 70 4c  ncrNew(pTask, pL
11a10 65 61 66 2c 20 26 70 49 6e 63 72 29 3b 0a 0a 20  eaf, &pIncr);.. 
11a20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 6e 44 65 70   for(i=1; i<nDep
11a30 74 68 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 6e 44  th; i++){.    nD
11a40 69 76 20 3d 20 6e 44 69 76 20 2a 20 53 4f 52 54  iv = nDiv * SORT
11a50 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55  ER_MAX_MERGE_COU
11a60 4e 54 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 69  NT;.  }..  for(i
11a70 3d 31 3b 20 69 3c 6e 44 65 70 74 68 20 26 26 20  =1; i<nDepth && 
11a80 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69  rc==SQLITE_OK; i
11a90 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 20 69 49 74  ++){.    int iIt
11aa0 65 72 20 3d 20 28 69 53 65 71 20 2f 20 6e 44 69  er = (iSeq / nDi
11ab0 76 29 20 25 20 53 4f 52 54 45 52 5f 4d 41 58 5f  v) % SORTER_MAX_
11ac0 4d 45 52 47 45 5f 43 4f 55 4e 54 3b 0a 20 20 20  MERGE_COUNT;.   
11ad0 20 50 6d 61 52 65 61 64 65 72 20 2a 70 49 74 65   PmaReader *pIte
11ae0 72 20 3d 20 26 70 2d 3e 61 49 74 65 72 5b 69 49  r = &p->aIter[iI
11af0 74 65 72 5d 3b 0a 0a 20 20 20 20 69 66 28 20 70  ter];..    if( p
11b00 49 74 65 72 2d 3e 70 49 6e 63 72 3d 3d 30 20 29  Iter->pIncr==0 )
11b10 7b 0a 20 20 20 20 20 20 4d 65 72 67 65 45 6e 67  {.      MergeEng
11b20 69 6e 65 20 2a 70 4e 65 77 20 3d 20 76 64 62 65  ine *pNew = vdbe
11b30 4d 65 72 67 65 45 6e 67 69 6e 65 4e 65 77 28 53  MergeEngineNew(S
11b40 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f  ORTER_MAX_MERGE_
11b50 43 4f 55 4e 54 29 3b 0a 20 20 20 20 20 20 69 66  COUNT);.      if
11b60 28 20 70 4e 65 77 3d 3d 30 20 29 7b 0a 20 20 20  ( pNew==0 ){.   
11b70 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
11b80 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 7d 65  _NOMEM;.      }e
11b90 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 72 63 20  lse{.        rc 
11ba0 3d 20 76 64 62 65 49 6e 63 72 4e 65 77 28 70 54  = vdbeIncrNew(pT
11bb0 61 73 6b 2c 20 70 4e 65 77 2c 20 26 70 49 74 65  ask, pNew, &pIte
11bc0 72 2d 3e 70 49 6e 63 72 29 3b 0a 20 20 20 20 20  r->pIncr);.     
11bd0 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 20   }.    }..    p 
11be0 3d 20 70 49 74 65 72 2d 3e 70 49 6e 63 72 2d 3e  = pIter->pIncr->
11bf0 70 4d 65 72 67 65 72 3b 0a 20 20 20 20 6e 44 69  pMerger;.    nDi
11c00 76 20 3d 20 6e 44 69 76 20 2f 20 53 4f 52 54 45  v = nDiv / SORTE
11c10 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
11c20 54 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63  T;.  }..  if( rc
11c30 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
11c40 20 20 20 70 2d 3e 61 49 74 65 72 5b 69 53 65 71     p->aIter[iSeq
11c50 20 25 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45   % SORTER_MAX_ME
11c60 52 47 45 5f 43 4f 55 4e 54 5d 2e 70 49 6e 63 72  RGE_COUNT].pIncr
11c70 20 3d 20 70 49 6e 63 72 3b 0a 20 20 7d 65 6c 73   = pIncr;.  }els
11c80 65 7b 0a 20 20 20 20 76 64 62 65 49 6e 63 72 46  e{.    vdbeIncrF
11c90 72 65 65 28 70 49 6e 63 72 29 3b 0a 20 20 7d 0a  ree(pIncr);.  }.
11ca0 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
11cb0 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
11cc0 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 61 73  ion is called as
11cd0 20 70 61 72 74 20 6f 66 20 61 20 53 6f 72 74 65   part of a Sorte
11ce0 72 52 65 77 69 6e 64 28 29 20 6f 70 65 72 61 74  rRewind() operat
11cf0 69 6f 6e 20 6f 6e 20 61 20 73 6f 72 74 65 72 0a  ion on a sorter.
11d00 2a 2a 20 74 68 61 74 20 68 61 73 20 61 6c 72 65  ** that has alre
11d10 61 64 79 20 77 72 69 74 74 65 6e 20 74 77 6f 20  ady written two 
11d20 6f 72 20 6d 6f 72 65 20 6c 65 76 65 6c 2d 30 20  or more level-0 
11d30 50 4d 41 73 20 74 6f 20 6f 6e 65 20 6f 72 20 6d  PMAs to one or m
11d40 6f 72 65 20 74 65 6d 70 0a 2a 2a 20 66 69 6c 65  ore temp.** file
11d50 73 2e 20 49 74 20 62 75 69 6c 64 73 20 61 20 74  s. It builds a t
11d60 72 65 65 20 6f 66 20 4d 65 72 67 65 45 6e 67 69  ree of MergeEngi
11d70 6e 65 2f 49 6e 63 72 4d 65 72 67 65 72 2f 50 6d  ne/IncrMerger/Pm
11d80 61 52 65 61 64 65 72 20 6f 62 6a 65 63 74 73 20  aReader objects 
11d90 74 68 61 74 20 0a 2a 2a 20 63 61 6e 20 62 65 20  that .** can be 
11da0 75 73 65 64 20 74 6f 20 69 6e 63 72 65 6d 65 6e  used to incremen
11db0 74 61 6c 6c 79 20 6d 65 72 67 65 20 61 6c 6c 20  tally merge all 
11dc0 50 4d 41 73 20 6f 6e 20 64 69 73 6b 2e 0a 2a 2a  PMAs on disk..**
11dd0 0a 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75  .** If successfu
11de0 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20  l, SQLITE_OK is 
11df0 72 65 74 75 72 6e 65 64 20 61 6e 64 20 2a 70 70  returned and *pp
11e00 4f 75 74 20 73 65 74 20 74 6f 20 70 6f 69 6e 74  Out set to point
11e10 20 74 6f 20 74 68 65 0a 2a 2a 20 4d 65 72 67 65   to the.** Merge
11e20 45 6e 67 69 6e 65 20 6f 62 6a 65 63 74 20 61 74  Engine object at
11e30 20 74 68 65 20 72 6f 6f 74 20 6f 66 20 74 68 65   the root of the
11e40 20 74 72 65 65 20 62 65 66 6f 72 65 20 72 65 74   tree before ret
11e50 75 72 6e 69 6e 67 2e 20 4f 72 2c 20 69 66 20 61  urning. Or, if a
11e60 6e 0a 2a 2a 20 65 72 72 6f 72 20 6f 63 63 75 72  n.** error occur
11e70 73 2c 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  s, an SQLite err
11e80 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74 75 72  or code is retur
11e90 6e 65 64 20 61 6e 64 20 74 68 65 20 66 69 6e 61  ned and the fina
11ea0 6c 20 76 61 6c 75 65 20 0a 2a 2a 20 6f 66 20 2a  l value .** of *
11eb0 70 70 4f 75 74 20 69 73 20 75 6e 64 65 66 69 6e  ppOut is undefin
11ec0 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ed..*/.static in
11ed0 74 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67  t vdbeSorterMerg
11ee0 65 54 72 65 65 42 75 69 6c 64 28 56 64 62 65 53  eTreeBuild(VdbeS
11ef0 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 2c 20  orter *pSorter, 
11f00 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 2a 70 70  MergeEngine **pp
11f10 4f 75 74 29 7b 0a 20 20 4d 65 72 67 65 45 6e 67  Out){.  MergeEng
11f20 69 6e 65 20 2a 70 4d 61 69 6e 20 3d 20 30 3b 0a  ine *pMain = 0;.
11f30 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
11f40 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 69 54 61 73  E_OK;.  int iTas
11f50 6b 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20  k;..  /* If the 
11f60 73 6f 72 74 65 72 20 75 73 65 73 20 6d 6f 72 65  sorter uses more
11f70 20 74 68 61 6e 20 6f 6e 65 20 74 61 73 6b 2c 20   than one task, 
11f80 74 68 65 6e 20 63 72 65 61 74 65 20 74 68 65 20  then create the 
11f90 74 6f 70 2d 6c 65 76 65 6c 20 0a 20 20 2a 2a 20  top-level .  ** 
11fa0 4d 65 72 67 65 45 6e 67 69 6e 65 20 68 65 72 65  MergeEngine here
11fb0 2e 20 54 68 69 73 20 4d 65 72 67 65 45 6e 67 69  . This MergeEngi
11fc0 6e 65 20 77 69 6c 6c 20 72 65 61 64 20 64 61 74  ne will read dat
11fd0 61 20 66 72 6f 6d 20 65 78 61 63 74 6c 79 20 0a  a from exactly .
11fe0 20 20 2a 2a 20 6f 6e 65 20 50 6d 61 52 65 61 64    ** one PmaRead
11ff0 65 72 20 70 65 72 20 73 75 62 2d 74 61 73 6b 2e  er per sub-task.
12000 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70    */.  assert( p
12010 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68 72 65  Sorter->bUseThre
12020 61 64 73 20 7c 7c 20 70 53 6f 72 74 65 72 2d 3e  ads || pSorter->
12030 6e 54 61 73 6b 3d 3d 31 20 29 3b 0a 20 20 69 66  nTask==1 );.  if
12040 28 20 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b  ( pSorter->nTask
12050 3e 31 20 29 7b 0a 20 20 20 20 70 4d 61 69 6e 20  >1 ){.    pMain 
12060 3d 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e  = vdbeMergeEngin
12070 65 4e 65 77 28 70 53 6f 72 74 65 72 2d 3e 6e 54  eNew(pSorter->nT
12080 61 73 6b 29 3b 0a 20 20 20 20 69 66 28 20 70 4d  ask);.    if( pM
12090 61 69 6e 3d 3d 30 20 29 20 72 63 20 3d 20 53 51  ain==0 ) rc = SQ
120a0 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a  LITE_NOMEM;.  }.
120b0 0a 20 20 66 6f 72 28 69 54 61 73 6b 3d 30 3b 20  .  for(iTask=0; 
120c0 69 54 61 73 6b 3c 70 53 6f 72 74 65 72 2d 3e 6e  iTask<pSorter->n
120d0 54 61 73 6b 20 26 26 20 72 63 3d 3d 53 51 4c 49  Task && rc==SQLI
120e0 54 45 5f 4f 4b 3b 20 69 54 61 73 6b 2b 2b 29 7b  TE_OK; iTask++){
120f0 0a 20 20 20 20 53 6f 72 74 53 75 62 74 61 73 6b  .    SortSubtask
12100 20 2a 70 54 61 73 6b 20 3d 20 26 70 53 6f 72 74   *pTask = &pSort
12110 65 72 2d 3e 61 54 61 73 6b 5b 69 54 61 73 6b 5d  er->aTask[iTask]
12120 3b 0a 20 20 20 20 69 66 28 20 70 54 61 73 6b 2d  ;.    if( pTask-
12130 3e 6e 50 4d 41 20 29 7b 0a 20 20 20 20 20 20 4d  >nPMA ){.      M
12140 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 52 6f 6f  ergeEngine *pRoo
12150 74 20 3d 20 30 3b 20 20 20 20 20 2f 2a 20 52 6f  t = 0;     /* Ro
12160 6f 74 20 6e 6f 64 65 20 6f 66 20 74 72 65 65 20  ot node of tree 
12170 66 6f 72 20 74 68 69 73 20 74 61 73 6b 20 2a 2f  for this task */
12180 0a 20 20 20 20 20 20 69 6e 74 20 6e 44 65 70 74  .      int nDept
12190 68 20 3d 20 76 64 62 65 53 6f 72 74 65 72 54 72  h = vdbeSorterTr
121a0 65 65 44 65 70 74 68 28 70 54 61 73 6b 2d 3e 6e  eeDepth(pTask->n
121b0 50 4d 41 29 3b 0a 20 20 20 20 20 20 69 36 34 20  PMA);.      i64 
121c0 69 52 65 61 64 4f 66 66 20 3d 20 30 3b 0a 0a 20  iReadOff = 0;.. 
121d0 20 20 20 20 20 69 66 28 20 70 54 61 73 6b 2d 3e       if( pTask->
121e0 6e 50 4d 41 3c 3d 53 4f 52 54 45 52 5f 4d 41 58  nPMA<=SORTER_MAX
121f0 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20 29 7b 0a  _MERGE_COUNT ){.
12200 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62          rc = vdb
12210 65 4d 65 72 67 65 45 6e 67 69 6e 65 4c 65 76 65  eMergeEngineLeve
12220 6c 30 28 70 54 61 73 6b 2c 20 70 54 61 73 6b 2d  l0(pTask, pTask-
12230 3e 6e 50 4d 41 2c 20 26 69 52 65 61 64 4f 66 66  >nPMA, &iReadOff
12240 2c 20 26 70 52 6f 6f 74 29 3b 0a 20 20 20 20 20  , &pRoot);.     
12250 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
12260 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 20 20 69  int i;.        i
12270 6e 74 20 69 53 65 71 20 3d 20 30 3b 0a 20 20 20  nt iSeq = 0;.   
12280 20 20 20 20 20 70 52 6f 6f 74 20 3d 20 76 64 62       pRoot = vdb
12290 65 4d 65 72 67 65 45 6e 67 69 6e 65 4e 65 77 28  eMergeEngineNew(
122a0 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45  SORTER_MAX_MERGE
122b0 5f 43 4f 55 4e 54 29 3b 0a 20 20 20 20 20 20 20  _COUNT);.       
122c0 20 69 66 28 20 70 52 6f 6f 74 3d 3d 30 20 29 20   if( pRoot==0 ) 
122d0 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
122e0 4d 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69  M;.        for(i
122f0 3d 30 3b 20 69 3c 70 54 61 73 6b 2d 3e 6e 50 4d  =0; i<pTask->nPM
12300 41 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f  A && rc==SQLITE_
12310 4f 4b 3b 20 69 20 2b 3d 20 53 4f 52 54 45 52 5f  OK; i += SORTER_
12320 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 29  MAX_MERGE_COUNT)
12330 7b 0a 20 20 20 20 20 20 20 20 20 20 4d 65 72 67  {.          Merg
12340 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67 65 72  eEngine *pMerger
12350 20 3d 20 30 3b 20 2f 2a 20 4e 65 77 20 6c 65 76   = 0; /* New lev
12360 65 6c 2d 30 20 50 4d 41 20 6d 65 72 67 65 72 20  el-0 PMA merger 
12370 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 69 6e 74  */.          int
12380 20 6e 52 65 61 64 65 72 3b 20 20 20 20 20 20 20   nReader;       
12390 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
123a0 20 6f 66 20 6c 65 76 65 6c 2d 30 20 50 4d 41 73   of level-0 PMAs
123b0 20 74 6f 20 6d 65 72 67 65 20 2a 2f 0a 0a 20 20   to merge */..  
123c0 20 20 20 20 20 20 20 20 6e 52 65 61 64 65 72 20          nReader 
123d0 3d 20 4d 49 4e 28 70 54 61 73 6b 2d 3e 6e 50 4d  = MIN(pTask->nPM
123e0 41 20 2d 20 69 2c 20 53 4f 52 54 45 52 5f 4d 41  A - i, SORTER_MA
123f0 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 29 3b 0a  X_MERGE_COUNT);.
12400 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 76            rc = v
12410 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4c 65  dbeMergeEngineLe
12420 76 65 6c 30 28 70 54 61 73 6b 2c 20 6e 52 65 61  vel0(pTask, nRea
12430 64 65 72 2c 20 26 69 52 65 61 64 4f 66 66 2c 20  der, &iReadOff, 
12440 26 70 4d 65 72 67 65 72 29 3b 0a 20 20 20 20 20  &pMerger);.     
12450 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
12460 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
12470 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53        rc = vdbeS
12480 6f 72 74 65 72 41 64 64 54 6f 54 72 65 65 28 70  orterAddToTree(p
12490 54 61 73 6b 2c 20 6e 44 65 70 74 68 2c 20 69 53  Task, nDepth, iS
124a0 65 71 2b 2b 2c 20 70 52 6f 6f 74 2c 20 70 4d 65  eq++, pRoot, pMe
124b0 72 67 65 72 29 3b 0a 20 20 20 20 20 20 20 20 20  rger);.         
124c0 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20   }.        }.   
124d0 20 20 20 7d 0a 0a 20 20 20 20 20 20 69 66 28 20     }..      if( 
124e0 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
124f0 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 4d 61  .        if( pMa
12500 69 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  in==0 ){.       
12510 20 20 20 70 4d 61 69 6e 20 3d 20 70 52 6f 6f 74     pMain = pRoot
12520 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b  ;.        }else{
12530 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
12540 76 64 62 65 49 6e 63 72 4e 65 77 28 70 54 61 73  vdbeIncrNew(pTas
12550 6b 2c 20 70 52 6f 6f 74 2c 20 26 70 4d 61 69 6e  k, pRoot, &pMain
12560 2d 3e 61 49 74 65 72 5b 69 54 61 73 6b 5d 2e 70  ->aIter[iTask].p
12570 49 6e 63 72 29 3b 0a 20 20 20 20 20 20 20 20 7d  Incr);.        }
12580 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
12590 20 20 20 20 20 20 76 64 62 65 4d 65 72 67 65 45        vdbeMergeE
125a0 6e 67 69 6e 65 46 72 65 65 28 70 52 6f 6f 74 29  ngineFree(pRoot)
125b0 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
125c0 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53    }..  if( rc!=S
125d0 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
125e0 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46  vdbeMergeEngineF
125f0 72 65 65 28 70 4d 61 69 6e 29 3b 0a 20 20 20 20  ree(pMain);.    
12600 70 4d 61 69 6e 20 3d 20 30 3b 0a 20 20 7d 0a 20  pMain = 0;.  }. 
12610 20 2a 70 70 4f 75 74 20 3d 20 70 4d 61 69 6e 3b   *ppOut = pMain;
12620 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
12630 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
12640 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 61  tion is called a
12650 73 20 70 61 72 74 20 6f 66 20 61 6e 20 73 71 6c  s part of an sql
12660 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 52 65  ite3VdbeSorterRe
12670 77 69 6e 64 28 29 20 6f 70 65 72 61 74 69 6f 6e  wind() operation
12680 0a 2a 2a 20 6f 6e 20 61 20 73 6f 72 74 65 72 20  .** on a sorter 
12690 74 68 61 74 20 68 61 73 20 77 72 69 74 74 65 6e  that has written
126a0 20 74 77 6f 20 6f 72 20 6d 6f 72 65 20 50 4d 41   two or more PMA
126b0 73 20 74 6f 20 74 65 6d 70 6f 72 61 72 79 20 66  s to temporary f
126c0 69 6c 65 73 2e 20 49 74 20 73 65 74 73 0a 2a 2a  iles. It sets.**
126d0 20 75 70 20 65 69 74 68 65 72 20 56 64 62 65 53   up either VdbeS
126e0 6f 72 74 65 72 2e 70 4d 65 72 67 65 72 20 28 66  orter.pMerger (f
126f0 6f 72 20 73 69 6e 67 6c 65 20 74 68 72 65 61 64  or single thread
12700 65 64 20 73 6f 72 74 65 72 73 29 20 6f 72 20 70  ed sorters) or p
12710 52 65 61 64 65 72 0a 2a 2a 20 28 66 6f 72 20 6d  Reader.** (for m
12720 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20 73 6f  ulti-threaded so
12730 72 74 65 72 73 29 20 73 6f 20 74 68 61 74 20 69  rters) so that i
12740 74 20 63 61 6e 20 62 65 20 75 73 65 64 20 74 6f  t can be used to
12750 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67 68   iterate through
12760 0a 2a 2a 20 61 6c 6c 20 72 65 63 6f 72 64 73 20  .** all records 
12770 73 74 6f 72 65 64 20 69 6e 20 74 68 65 20 73 6f  stored in the so
12780 72 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49  rter..**.** SQLI
12790 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65  TE_OK is returne
127a0 64 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c  d if successful,
127b0 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72   or an SQLite er
127c0 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77 69  ror code otherwi
127d0 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  se..*/.static in
127e0 74 20 76 64 62 65 53 6f 72 74 65 72 53 65 74 75  t vdbeSorterSetu
127f0 70 4d 65 72 67 65 28 56 64 62 65 53 6f 72 74 65  pMerge(VdbeSorte
12800 72 20 2a 70 53 6f 72 74 65 72 29 7b 0a 20 20 69  r *pSorter){.  i
12810 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
12820 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
12830 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
12840 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a  .  SortSubtask *
12850 70 54 61 73 6b 30 20 3d 20 26 70 53 6f 72 74 65  pTask0 = &pSorte
12860 72 2d 3e 61 54 61 73 6b 5b 30 5d 3b 0a 20 20 4d  r->aTask[0];.  M
12870 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 61 69  ergeEngine *pMai
12880 6e 20 3d 20 30 3b 0a 23 69 66 20 53 51 4c 49 54  n = 0;.#if SQLIT
12890 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52  E_MAX_WORKER_THR
128a0 45 41 44 53 0a 20 20 73 71 6c 69 74 65 33 20 2a  EADS.  sqlite3 *
128b0 64 62 20 3d 20 70 54 61 73 6b 30 2d 3e 70 53 6f  db = pTask0->pSo
128c0 72 74 65 72 2d 3e 64 62 3b 0a 23 65 6e 64 69 66  rter->db;.#endif
128d0 0a 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72  ..  rc = vdbeSor
128e0 74 65 72 4d 65 72 67 65 54 72 65 65 42 75 69 6c  terMergeTreeBuil
128f0 64 28 70 53 6f 72 74 65 72 2c 20 26 70 4d 61 69  d(pSorter, &pMai
12900 6e 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  n);.  if( rc==SQ
12910 4c 49 54 45 5f 4f 4b 20 29 7b 0a 23 69 66 20 53  LITE_OK ){.#if S
12920 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52  QLITE_MAX_WORKER
12930 5f 54 48 52 45 41 44 53 0a 20 20 20 20 69 66 28  _THREADS.    if(
12940 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68   pSorter->bUseTh
12950 72 65 61 64 73 20 29 7b 0a 20 20 20 20 20 20 69  reads ){.      i
12960 6e 74 20 69 54 61 73 6b 3b 0a 20 20 20 20 20 20  nt iTask;.      
12970 50 6d 61 52 65 61 64 65 72 20 2a 70 49 74 65 72  PmaReader *pIter
12980 3b 0a 20 20 20 20 20 20 53 6f 72 74 53 75 62 74  ;.      SortSubt
12990 61 73 6b 20 2a 70 4c 61 73 74 20 3d 20 26 70 53  ask *pLast = &pS
129a0 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 70 53 6f  orter->aTask[pSo
129b0 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 5d 3b 0a  rter->nTask-1];.
129c0 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53        rc = vdbeS
129d0 6f 72 74 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64  ortAllocUnpacked
129e0 28 70 4c 61 73 74 29 3b 0a 20 20 20 20 20 20 69  (pLast);.      i
129f0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
12a00 20 29 7b 0a 20 20 20 20 20 20 20 20 70 49 74 65   ){.        pIte
12a10 72 20 3d 20 28 50 6d 61 52 65 61 64 65 72 2a 29  r = (PmaReader*)
12a20 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f 63 5a  sqlite3DbMallocZ
12a30 65 72 6f 28 64 62 2c 20 73 69 7a 65 6f 66 28 50  ero(db, sizeof(P
12a40 6d 61 52 65 61 64 65 72 29 29 3b 0a 20 20 20 20  maReader));.    
12a50 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 52 65      pSorter->pRe
12a60 61 64 65 72 20 3d 20 70 49 74 65 72 3b 0a 20 20  ader = pIter;.  
12a70 20 20 20 20 20 20 69 66 28 20 70 49 74 65 72 3d        if( pIter=
12a80 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45  =0 ) rc = SQLITE
12a90 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 7d 0a  _NOMEM;.      }.
12aa0 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
12ab0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
12ac0 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72     rc = vdbeIncr
12ad0 4e 65 77 28 70 4c 61 73 74 2c 20 70 4d 61 69 6e  New(pLast, pMain
12ae0 2c 20 26 70 49 74 65 72 2d 3e 70 49 6e 63 72 29  , &pIter->pIncr)
12af0 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
12b00 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
12b10 20 20 20 20 20 20 20 20 20 76 64 62 65 49 6e 63           vdbeInc
12b20 72 53 65 74 54 68 72 65 61 64 73 28 70 49 74 65  rSetThreads(pIte
12b30 72 2d 3e 70 49 6e 63 72 2c 20 70 53 6f 72 74 65  r->pIncr, pSorte
12b40 72 2d 3e 62 55 73 65 54 68 72 65 61 64 73 29 3b  r->bUseThreads);
12b50 0a 20 20 20 20 20 20 20 20 20 20 66 6f 72 28 69  .          for(i
12b60 54 61 73 6b 3d 30 3b 20 69 54 61 73 6b 3c 28 70  Task=0; iTask<(p
12b70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29  Sorter->nTask-1)
12b80 3b 20 69 54 61 73 6b 2b 2b 29 7b 0a 20 20 20 20  ; iTask++){.    
12b90 20 20 20 20 20 20 20 20 49 6e 63 72 4d 65 72 67          IncrMerg
12ba0 65 72 20 2a 70 49 6e 63 72 3b 0a 20 20 20 20 20  er *pIncr;.     
12bb0 20 20 20 20 20 20 20 69 66 28 20 28 70 49 6e 63         if( (pInc
12bc0 72 20 3d 20 70 4d 61 69 6e 2d 3e 61 49 74 65 72  r = pMain->aIter
12bd0 5b 69 54 61 73 6b 5d 2e 70 49 6e 63 72 29 20 29  [iTask].pIncr) )
12be0 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  {.              
12bf0 76 64 62 65 49 6e 63 72 53 65 74 54 68 72 65 61  vdbeIncrSetThrea
12c00 64 73 28 70 49 6e 63 72 2c 20 70 53 6f 72 74 65  ds(pIncr, pSorte
12c10 72 2d 3e 62 55 73 65 54 68 72 65 61 64 73 29 3b  r->bUseThreads);
12c20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61  .              a
12c30 73 73 65 72 74 28 20 70 49 6e 63 72 2d 3e 70 54  ssert( pIncr->pT
12c40 61 73 6b 21 3d 70 4c 61 73 74 20 29 3b 0a 20 20  ask!=pLast );.  
12c50 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
12c60 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
12c70 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6e    if( pSorter->n
12c80 54 61 73 6b 3e 31 20 29 7b 0a 20 20 20 20 20 20  Task>1 ){.      
12c90 20 20 20 20 20 20 66 6f 72 28 69 54 61 73 6b 3d        for(iTask=
12ca0 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  0; rc==SQLITE_OK
12cb0 20 26 26 20 69 54 61 73 6b 3c 70 53 6f 72 74 65   && iTask<pSorte
12cc0 72 2d 3e 6e 54 61 73 6b 3b 20 69 54 61 73 6b 2b  r->nTask; iTask+
12cd0 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  +){.            
12ce0 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70 20 3d    PmaReader *p =
12cf0 20 26 70 4d 61 69 6e 2d 3e 61 49 74 65 72 5b 69   &pMain->aIter[i
12d00 54 61 73 6b 5d 3b 0a 20 20 20 20 20 20 20 20 20  Task];.         
12d10 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e       assert( p->
12d20 70 49 6e 63 72 3d 3d 30 20 7c 7c 20 70 2d 3e 70  pIncr==0 || p->p
12d30 49 6e 63 72 2d 3e 70 54 61 73 6b 3d 3d 26 70 53  Incr->pTask==&pS
12d40 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 69 54 61  orter->aTask[iTa
12d50 73 6b 5d 20 29 3b 0a 20 20 20 20 20 20 20 20 20  sk] );.         
12d60 20 20 20 20 20 69 66 28 20 70 2d 3e 70 49 6e 63       if( p->pInc
12d70 72 20 29 7b 20 72 63 20 3d 20 76 64 62 65 50 6d  r ){ rc = vdbePm
12d80 61 52 65 61 64 65 72 42 67 49 6e 63 72 49 6e 69  aReaderBgIncrIni
12d90 74 28 70 29 3b 20 7d 0a 20 20 20 20 20 20 20 20  t(p); }.        
12da0 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20      }.          
12db0 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  }.        }.    
12dc0 20 20 20 20 70 4d 61 69 6e 20 3d 20 30 3b 0a 20      pMain = 0;. 
12dd0 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
12de0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
12df0 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 65 4d  {.        int eM
12e00 6f 64 65 20 3d 20 28 70 53 6f 72 74 65 72 2d 3e  ode = (pSorter->
12e10 6e 54 61 73 6b 3e 31 20 3f 20 49 4e 43 52 49 4e  nTask>1 ? INCRIN
12e20 49 54 5f 52 4f 4f 54 20 3a 20 49 4e 43 52 49 4e  IT_ROOT : INCRIN
12e30 49 54 5f 4e 4f 52 4d 41 4c 29 3b 0a 20 20 20 20  IT_NORMAL);.    
12e40 20 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61      rc = vdbePma
12e50 52 65 61 64 65 72 49 6e 63 72 49 6e 69 74 28 70  ReaderIncrInit(p
12e60 49 74 65 72 2c 20 65 4d 6f 64 65 29 3b 0a 20 20  Iter, eMode);.  
12e70 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 0a      }.    }else.
12e80 23 65 6e 64 69 66 0a 20 20 20 20 7b 0a 20 20 20  #endif.    {.   
12e90 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72     rc = vdbeIncr
12ea0 49 6e 69 74 4d 65 72 67 65 72 28 70 54 61 73 6b  InitMerger(pTask
12eb0 30 2c 20 70 4d 61 69 6e 2c 20 49 4e 43 52 49 4e  0, pMain, INCRIN
12ec0 49 54 5f 4e 4f 52 4d 41 4c 29 3b 0a 20 20 20 20  IT_NORMAL);.    
12ed0 20 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67    pSorter->pMerg
12ee0 65 72 20 3d 20 70 4d 61 69 6e 3b 0a 20 20 20 20  er = pMain;.    
12ef0 20 20 70 4d 61 69 6e 20 3d 20 30 3b 0a 20 20 20    pMain = 0;.   
12f00 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63   }.  }..  if( rc
12f10 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
12f20 20 20 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69     vdbeMergeEngi
12f30 6e 65 46 72 65 65 28 70 4d 61 69 6e 29 3b 0a 20  neFree(pMain);. 
12f40 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
12f50 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 4f 6e 63 65 20 74  }.../*.** Once t
12f60 68 65 20 73 6f 72 74 65 72 20 68 61 73 20 62 65  he sorter has be
12f70 65 6e 20 70 6f 70 75 6c 61 74 65 64 20 62 79 20  en populated by 
12f80 63 61 6c 6c 73 20 74 6f 20 73 71 6c 69 74 65 33  calls to sqlite3
12f90 56 64 62 65 53 6f 72 74 65 72 57 72 69 74 65 2c  VdbeSorterWrite,
12fa0 0a 2a 2a 20 74 68 69 73 20 66 75 6e 63 74 69 6f  .** this functio
12fb0 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 70  n is called to p
12fc0 72 65 70 61 72 65 20 66 6f 72 20 69 74 65 72 61  repare for itera
12fd0 74 69 6e 67 20 74 68 72 6f 75 67 68 20 74 68 65  ting through the
12fe0 20 72 65 63 6f 72 64 73 0a 2a 2a 20 69 6e 20 73   records.** in s
12ff0 6f 72 74 65 64 20 6f 72 64 65 72 2e 0a 2a 2f 0a  orted order..*/.
13000 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65 53  int sqlite3VdbeS
13010 6f 72 74 65 72 52 65 77 69 6e 64 28 63 6f 6e 73  orterRewind(cons
13020 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43  t VdbeCursor *pC
13030 73 72 2c 20 69 6e 74 20 2a 70 62 45 6f 66 29 7b  sr, int *pbEof){
13040 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70  .  VdbeSorter *p
13050 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70  Sorter = pCsr->p
13060 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 72 63  Sorter;.  int rc
13070 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20   = SQLITE_OK;   
13080 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
13090 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 61  urn code */..  a
130a0 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 20 29  ssert( pSorter )
130b0 3b 0a 0a 20 20 2f 2a 20 49 66 20 6e 6f 20 64 61  ;..  /* If no da
130c0 74 61 20 68 61 73 20 62 65 65 6e 20 77 72 69 74  ta has been writ
130d0 74 65 6e 20 74 6f 20 64 69 73 6b 2c 20 74 68 65  ten to disk, the
130e0 6e 20 64 6f 20 6e 6f 74 20 64 6f 20 73 6f 20 6e  n do not do so n
130f0 6f 77 2e 20 49 6e 73 74 65 61 64 2c 0a 20 20 2a  ow. Instead,.  *
13100 2a 20 73 6f 72 74 20 74 68 65 20 56 64 62 65 53  * sort the VdbeS
13110 6f 72 74 65 72 2e 70 52 65 63 6f 72 64 20 6c 69  orter.pRecord li
13120 73 74 2e 20 54 68 65 20 76 64 62 65 20 6c 61 79  st. The vdbe lay
13130 65 72 20 77 69 6c 6c 20 72 65 61 64 20 64 61 74  er will read dat
13140 61 20 64 69 72 65 63 74 6c 79 0a 20 20 2a 2a 20  a directly.  ** 
13150 66 72 6f 6d 20 74 68 65 20 69 6e 2d 6d 65 6d 6f  from the in-memo
13160 72 79 20 6c 69 73 74 2e 20 20 2a 2f 0a 20 20 69  ry list.  */.  i
13170 66 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65  f( pSorter->bUse
13180 50 4d 41 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66  PMA==0 ){.    if
13190 28 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e  ( pSorter->list.
131a0 70 4c 69 73 74 20 29 7b 0a 20 20 20 20 20 20 2a  pList ){.      *
131b0 70 62 45 6f 66 20 3d 20 30 3b 0a 20 20 20 20 20  pbEof = 0;.     
131c0 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
131d0 53 6f 72 74 28 26 70 53 6f 72 74 65 72 2d 3e 61  Sort(&pSorter->a
131e0 54 61 73 6b 5b 30 5d 2c 20 26 70 53 6f 72 74 65  Task[0], &pSorte
131f0 72 2d 3e 6c 69 73 74 29 3b 0a 20 20 20 20 7d 65  r->list);.    }e
13200 6c 73 65 7b 0a 20 20 20 20 20 20 2a 70 62 45 6f  lse{.      *pbEo
13210 66 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20  f = 1;.    }.   
13220 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a   return rc;.  }.
13230 0a 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20  .  /* Write the 
13240 63 75 72 72 65 6e 74 20 69 6e 2d 6d 65 6d 6f 72  current in-memor
13250 79 20 6c 69 73 74 20 74 6f 20 61 20 50 4d 41 2e  y list to a PMA.
13260 20 2a 2f 0a 20 20 69 66 28 20 70 53 6f 72 74 65   */.  if( pSorte
13270 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 29 7b  r->list.pList ){
13280 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f  .    rc = vdbeSo
13290 72 74 65 72 46 6c 75 73 68 50 4d 41 28 70 53 6f  rterFlushPMA(pSo
132a0 72 74 65 72 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  rter);.  }..  /*
132b0 20 4a 6f 69 6e 20 61 6c 6c 20 74 68 72 65 61 64   Join all thread
132c0 73 20 2a 2f 0a 20 20 72 63 20 3d 20 76 64 62 65  s */.  rc = vdbe
132d0 53 6f 72 74 65 72 4a 6f 69 6e 41 6c 6c 28 70 53  SorterJoinAll(pS
132e0 6f 72 74 65 72 2c 20 72 63 29 3b 0a 0a 20 20 76  orter, rc);..  v
132f0 64 62 65 53 6f 72 74 65 72 52 65 77 69 6e 64 44  dbeSorterRewindD
13300 65 62 75 67 28 22 72 65 77 69 6e 64 22 29 3b 0a  ebug("rewind");.
13310 0a 20 20 2f 2a 20 41 73 73 75 6d 69 6e 67 20 6e  .  /* Assuming n
13320 6f 20 65 72 72 6f 72 73 20 68 61 76 65 20 6f 63  o errors have oc
13330 63 75 72 72 65 64 2c 20 73 65 74 20 75 70 20 61  curred, set up a
13340 20 6d 65 72 67 65 72 20 73 74 72 75 63 74 75 72   merger structur
13350 65 20 74 6f 20 0a 20 20 2a 2a 20 69 6e 63 72 65  e to .  ** incre
13360 6d 65 6e 74 61 6c 6c 79 20 72 65 61 64 20 61 6e  mentally read an
13370 64 20 6d 65 72 67 65 20 61 6c 6c 20 72 65 6d 61  d merge all rema
13380 69 6e 69 6e 67 20 50 4d 41 73 2e 20 20 2a 2f 0a  ining PMAs.  */.
13390 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65    assert( pSorte
133a0 72 2d 3e 70 52 65 61 64 65 72 3d 3d 30 20 29 3b  r->pReader==0 );
133b0 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
133c0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
133d0 20 76 64 62 65 53 6f 72 74 65 72 53 65 74 75 70   vdbeSorterSetup
133e0 4d 65 72 67 65 28 70 53 6f 72 74 65 72 29 3b 0a  Merge(pSorter);.
133f0 20 20 20 20 2a 70 62 45 6f 66 20 3d 20 30 3b 0a      *pbEof = 0;.
13400 20 20 7d 0a 0a 20 20 76 64 62 65 53 6f 72 74 65    }..  vdbeSorte
13410 72 52 65 77 69 6e 64 44 65 62 75 67 28 22 72 65  rRewindDebug("re
13420 77 69 6e 64 64 6f 6e 65 22 29 3b 0a 20 20 72 65  winddone");.  re
13430 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
13440 2a 20 41 64 76 61 6e 63 65 20 74 6f 20 74 68 65  * Advance to the
13450 20 6e 65 78 74 20 65 6c 65 6d 65 6e 74 20 69 6e   next element in
13460 20 74 68 65 20 73 6f 72 74 65 72 2e 0a 2a 2f 0a   the sorter..*/.
13470 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65 53  int sqlite3VdbeS
13480 6f 72 74 65 72 4e 65 78 74 28 73 71 6c 69 74 65  orterNext(sqlite
13490 33 20 2a 64 62 2c 20 63 6f 6e 73 74 20 56 64 62  3 *db, const Vdb
134a0 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69  eCursor *pCsr, i
134b0 6e 74 20 2a 70 62 45 6f 66 29 7b 0a 20 20 56 64  nt *pbEof){.  Vd
134c0 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
134d0 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65  r = pCsr->pSorte
134e0 72 3b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20  r;.  int rc;    
134f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13500 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
13510 6f 64 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74  ode */..  assert
13520 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 50  ( pSorter->bUseP
13530 4d 41 20 7c 7c 20 28 70 53 6f 72 74 65 72 2d 3e  MA || (pSorter->
13540 70 52 65 61 64 65 72 3d 3d 30 20 26 26 20 70 53  pReader==0 && pS
13550 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 3d 3d  orter->pMerger==
13560 30 29 20 29 3b 0a 20 20 69 66 28 20 70 53 6f 72  0) );.  if( pSor
13570 74 65 72 2d 3e 62 55 73 65 50 4d 41 20 29 7b 0a  ter->bUsePMA ){.
13580 20 20 20 20 61 73 73 65 72 74 28 20 70 53 6f 72      assert( pSor
13590 74 65 72 2d 3e 70 52 65 61 64 65 72 3d 3d 30 20  ter->pReader==0 
135a0 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72  || pSorter->pMer
135b0 67 65 72 3d 3d 30 20 29 3b 0a 20 20 20 20 61 73  ger==0 );.    as
135c0 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 62  sert( pSorter->b
135d0 55 73 65 54 68 72 65 61 64 73 3d 3d 30 20 7c 7c  UseThreads==0 ||
135e0 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65   pSorter->pReade
135f0 72 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  r );.    assert(
13600 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68   pSorter->bUseTh
13610 72 65 61 64 73 3d 3d 31 20 7c 7c 20 70 53 6f 72  reads==1 || pSor
13620 74 65 72 2d 3e 70 4d 65 72 67 65 72 20 29 3b 0a  ter->pMerger );.
13630 20 20 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d      if( pSorter-
13640 3e 62 55 73 65 54 68 72 65 61 64 73 20 29 7b 0a  >bUseThreads ){.
13650 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 50        rc = vdbeP
13660 6d 61 52 65 61 64 65 72 4e 65 78 74 28 70 53 6f  maReaderNext(pSo
13670 72 74 65 72 2d 3e 70 52 65 61 64 65 72 29 3b 0a  rter->pReader);.
13680 20 20 20 20 20 20 2a 70 62 45 6f 66 20 3d 20 28        *pbEof = (
13690 70 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72  pSorter->pReader
136a0 2d 3e 70 46 69 6c 65 3d 3d 30 29 3b 0a 20 20 20  ->pFile==0);.   
136b0 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63   }else{.      rc
136c0 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4e 65 78   = vdbeSorterNex
136d0 74 28 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73  t(&pSorter->aTas
136e0 6b 5b 30 5d 2c 20 70 53 6f 72 74 65 72 2d 3e 70  k[0], pSorter->p
136f0 4d 65 72 67 65 72 2c 20 70 62 45 6f 66 29 3b 0a  Merger, pbEof);.
13700 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20      }.  }else{. 
13710 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20     SorterRecord 
13720 2a 70 46 72 65 65 20 3d 20 70 53 6f 72 74 65 72  *pFree = pSorter
13730 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 3b 0a 20 20  ->list.pList;.  
13740 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e    pSorter->list.
13750 70 4c 69 73 74 20 3d 20 70 46 72 65 65 2d 3e 75  pList = pFree->u
13760 2e 70 4e 65 78 74 3b 0a 20 20 20 20 70 46 72 65  .pNext;.    pFre
13770 65 2d 3e 75 2e 70 4e 65 78 74 20 3d 20 30 3b 0a  e->u.pNext = 0;.
13780 20 20 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d      if( pSorter-
13790 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30  >list.aMemory==0
137a0 20 29 20 76 64 62 65 53 6f 72 74 65 72 52 65 63   ) vdbeSorterRec
137b0 6f 72 64 46 72 65 65 28 64 62 2c 20 70 46 72 65  ordFree(db, pFre
137c0 65 29 3b 0a 20 20 20 20 2a 70 62 45 6f 66 20 3d  e);.    *pbEof =
137d0 20 21 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e   !pSorter->list.
137e0 70 4c 69 73 74 3b 0a 20 20 20 20 72 63 20 3d 20  pList;.    rc = 
137f0 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 20  SQLITE_OK;.  }. 
13800 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
13810 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f  *.** Return a po
13820 69 6e 74 65 72 20 74 6f 20 61 20 62 75 66 66 65  inter to a buffe
13830 72 20 6f 77 6e 65 64 20 62 79 20 74 68 65 20 73  r owned by the s
13840 6f 72 74 65 72 20 74 68 61 74 20 63 6f 6e 74 61  orter that conta
13850 69 6e 73 20 74 68 65 20 0a 2a 2a 20 63 75 72 72  ins the .** curr
13860 65 6e 74 20 6b 65 79 2e 0a 2a 2f 0a 73 74 61 74  ent key..*/.stat
13870 69 63 20 76 6f 69 64 20 2a 76 64 62 65 53 6f 72  ic void *vdbeSor
13880 74 65 72 52 6f 77 6b 65 79 28 0a 20 20 63 6f 6e  terRowkey(.  con
13890 73 74 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70  st VdbeSorter *p
138a0 53 6f 72 74 65 72 2c 20 20 20 20 20 20 2f 2a 20  Sorter,      /* 
138b0 53 6f 72 74 65 72 20 6f 62 6a 65 63 74 20 2a 2f  Sorter object */
138c0 0a 20 20 69 6e 74 20 2a 70 6e 4b 65 79 20 20 20  .  int *pnKey   
138d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
138e0 20 20 20 2f 2a 20 4f 55 54 3a 20 53 69 7a 65 20     /* OUT: Size 
138f0 6f 66 20 63 75 72 72 65 6e 74 20 6b 65 79 20 69  of current key i
13900 6e 20 62 79 74 65 73 20 2a 2f 0a 29 7b 0a 20 20  n bytes */.){.  
13910 76 6f 69 64 20 2a 70 4b 65 79 3b 0a 20 20 69 66  void *pKey;.  if
13920 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 50  ( pSorter->bUseP
13930 4d 41 20 29 7b 0a 20 20 20 20 50 6d 61 52 65 61  MA ){.    PmaRea
13940 64 65 72 20 2a 70 52 65 61 64 65 72 20 3d 20 28  der *pReader = (
13950 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68 72  pSorter->bUseThr
13960 65 61 64 73 20 3f 0a 20 20 20 20 20 20 20 20 70  eads ?.        p
13970 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72 20  Sorter->pReader 
13980 3a 20 26 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72  : &pSorter->pMer
13990 67 65 72 2d 3e 61 49 74 65 72 5b 70 53 6f 72 74  ger->aIter[pSort
139a0 65 72 2d 3e 70 4d 65 72 67 65 72 2d 3e 61 54 72  er->pMerger->aTr
139b0 65 65 5b 31 5d 5d 0a 20 20 20 20 29 3b 0a 20 20  ee[1]].    );.  
139c0 20 20 2a 70 6e 4b 65 79 20 3d 20 70 52 65 61 64    *pnKey = pRead
139d0 65 72 2d 3e 6e 4b 65 79 3b 0a 20 20 20 20 70 4b  er->nKey;.    pK
139e0 65 79 20 3d 20 70 52 65 61 64 65 72 2d 3e 61 4b  ey = pReader->aK
139f0 65 79 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ey;.  }else{.   
13a00 20 2a 70 6e 4b 65 79 20 3d 20 70 53 6f 72 74 65   *pnKey = pSorte
13a10 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 2d 3e 6e  r->list.pList->n
13a20 56 61 6c 3b 0a 20 20 20 20 70 4b 65 79 20 3d 20  Val;.    pKey = 
13a30 53 52 56 41 4c 28 70 53 6f 72 74 65 72 2d 3e 6c  SRVAL(pSorter->l
13a40 69 73 74 2e 70 4c 69 73 74 29 3b 0a 20 20 7d 0a  ist.pList);.  }.
13a50 20 20 72 65 74 75 72 6e 20 70 4b 65 79 3b 0a 7d    return pKey;.}
13a60 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20 74 68 65  ../*.** Copy the
13a70 20 63 75 72 72 65 6e 74 20 73 6f 72 74 65 72 20   current sorter 
13a80 6b 65 79 20 69 6e 74 6f 20 74 68 65 20 6d 65 6d  key into the mem
13a90 6f 72 79 20 63 65 6c 6c 20 70 4f 75 74 2e 0a 2a  ory cell pOut..*
13aa0 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62  /.int sqlite3Vdb
13ab0 65 53 6f 72 74 65 72 52 6f 77 6b 65 79 28 63 6f  eSorterRowkey(co
13ac0 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a  nst VdbeCursor *
13ad0 70 43 73 72 2c 20 4d 65 6d 20 2a 70 4f 75 74 29  pCsr, Mem *pOut)
13ae0 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a  {.  VdbeSorter *
13af0 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e  pSorter = pCsr->
13b00 70 53 6f 72 74 65 72 3b 0a 20 20 76 6f 69 64 20  pSorter;.  void 
13b10 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b 65 79 3b  *pKey; int nKey;
13b20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f             /* So
13b30 72 74 65 72 20 6b 65 79 20 74 6f 20 63 6f 70 79  rter key to copy
13b40 20 69 6e 74 6f 20 70 4f 75 74 20 2a 2f 0a 0a 20   into pOut */.. 
13b50 20 70 4b 65 79 20 3d 20 76 64 62 65 53 6f 72 74   pKey = vdbeSort
13b60 65 72 52 6f 77 6b 65 79 28 70 53 6f 72 74 65 72  erRowkey(pSorter
13b70 2c 20 26 6e 4b 65 79 29 3b 0a 20 20 69 66 28 20  , &nKey);.  if( 
13b80 73 71 6c 69 74 65 33 56 64 62 65 4d 65 6d 47 72  sqlite3VdbeMemGr
13b90 6f 77 28 70 4f 75 74 2c 20 6e 4b 65 79 2c 20 30  ow(pOut, nKey, 0
13ba0 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
13bb0 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
13bc0 7d 0a 20 20 70 4f 75 74 2d 3e 6e 20 3d 20 6e 4b  }.  pOut->n = nK
13bd0 65 79 3b 0a 20 20 4d 65 6d 53 65 74 54 79 70 65  ey;.  MemSetType
13be0 46 6c 61 67 28 70 4f 75 74 2c 20 4d 45 4d 5f 42  Flag(pOut, MEM_B
13bf0 6c 6f 62 29 3b 0a 20 20 6d 65 6d 63 70 79 28 70  lob);.  memcpy(p
13c00 4f 75 74 2d 3e 7a 2c 20 70 4b 65 79 2c 20 6e 4b  Out->z, pKey, nK
13c10 65 79 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 53  ey);..  return S
13c20 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
13c30 2a 2a 20 43 6f 6d 70 61 72 65 20 74 68 65 20 6b  ** Compare the k
13c40 65 79 20 69 6e 20 6d 65 6d 6f 72 79 20 63 65 6c  ey in memory cel
13c50 6c 20 70 56 61 6c 20 77 69 74 68 20 74 68 65 20  l pVal with the 
13c60 6b 65 79 20 74 68 61 74 20 74 68 65 20 73 6f 72  key that the sor
13c70 74 65 72 20 63 75 72 73 6f 72 0a 2a 2a 20 70 61  ter cursor.** pa
13c80 73 73 65 64 20 61 73 20 74 68 65 20 66 69 72 73  ssed as the firs
13c90 74 20 61 72 67 75 6d 65 6e 74 20 63 75 72 72 65  t argument curre
13ca0 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f 2e 20  ntly points to. 
13cb0 46 6f 72 20 74 68 65 20 70 75 72 70 6f 73 65 73  For the purposes
13cc0 20 6f 66 0a 2a 2a 20 74 68 65 20 63 6f 6d 70 61   of.** the compa
13cd0 72 69 73 6f 6e 2c 20 69 67 6e 6f 72 65 20 74 68  rison, ignore th
13ce0 65 20 72 6f 77 69 64 20 66 69 65 6c 64 20 61 74  e rowid field at
13cf0 20 74 68 65 20 65 6e 64 20 6f 66 20 65 61 63 68   the end of each
13d00 20 72 65 63 6f 72 64 2e 0a 2a 2a 0a 2a 2a 20 49   record..**.** I
13d10 66 20 74 68 65 20 73 6f 72 74 65 72 20 63 75 72  f the sorter cur
13d20 73 6f 72 20 6b 65 79 20 63 6f 6e 74 61 69 6e 73  sor key contains
13d30 20 61 6e 79 20 4e 55 4c 4c 20 76 61 6c 75 65 73   any NULL values
13d40 2c 20 63 6f 6e 73 69 64 65 72 20 69 74 20 74 6f  , consider it to
13d50 20 62 65 0a 2a 2a 20 6c 65 73 73 20 74 68 61 6e   be.** less than
13d60 20 70 56 61 6c 2e 20 45 76 65 6e 20 69 66 20 70   pVal. Even if p
13d70 56 61 6c 20 61 6c 73 6f 20 63 6f 6e 74 61 69 6e  Val also contain
13d80 73 20 4e 55 4c 4c 20 76 61 6c 75 65 73 2e 0a 2a  s NULL values..*
13d90 2a 0a 2a 2a 20 49 66 20 61 6e 20 65 72 72 6f 72  *.** If an error
13da0 20 6f 63 63 75 72 73 2c 20 72 65 74 75 72 6e 20   occurs, return 
13db0 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
13dc0 63 6f 64 65 20 28 69 2e 65 2e 20 53 51 4c 49 54  code (i.e. SQLIT
13dd0 45 5f 4e 4f 4d 45 4d 29 2e 0a 2a 2a 20 4f 74 68  E_NOMEM)..** Oth
13de0 65 72 77 69 73 65 2c 20 73 65 74 20 2a 70 52 65  erwise, set *pRe
13df0 73 20 74 6f 20 61 20 6e 65 67 61 74 69 76 65 2c  s to a negative,
13e00 20 7a 65 72 6f 20 6f 72 20 70 6f 73 69 74 69 76   zero or positiv
13e10 65 20 76 61 6c 75 65 20 69 66 20 74 68 65 0a 2a  e value if the.*
13e20 2a 20 6b 65 79 20 69 6e 20 70 56 61 6c 20 69 73  * key in pVal is
13e30 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 2c 20 65   smaller than, e
13e40 71 75 61 6c 20 74 6f 20 6f 72 20 6c 61 72 67 65  qual to or large
13e50 72 20 74 68 61 6e 20 74 68 65 20 63 75 72 72 65  r than the curre
13e60 6e 74 20 73 6f 72 74 65 72 0a 2a 2a 20 6b 65 79  nt sorter.** key
13e70 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ..**.** This rou
13e80 74 69 6e 65 20 66 6f 72 6d 73 20 74 68 65 20 63  tine forms the c
13e90 6f 72 65 20 6f 66 20 74 68 65 20 4f 50 5f 53 6f  ore of the OP_So
13ea0 72 74 65 72 43 6f 6d 70 61 72 65 20 6f 70 63 6f  rterCompare opco
13eb0 64 65 2c 20 77 68 69 63 68 20 69 6e 0a 2a 2a 20  de, which in.** 
13ec0 74 75 72 6e 20 69 73 20 75 73 65 64 20 74 6f 20  turn is used to 
13ed0 76 65 72 69 66 79 20 75 6e 69 71 75 65 6e 65 73  verify uniquenes
13ee0 73 20 77 68 65 6e 20 63 6f 6e 73 74 72 75 63 74  s when construct
13ef0 69 6e 67 20 61 20 55 4e 49 51 55 45 20 49 4e 44  ing a UNIQUE IND
13f00 45 58 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  EX..*/.int sqlit
13f10 65 33 56 64 62 65 53 6f 72 74 65 72 43 6f 6d 70  e3VdbeSorterComp
13f20 61 72 65 28 0a 20 20 63 6f 6e 73 74 20 56 64 62  are(.  const Vdb
13f30 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 20  eCursor *pCsr,  
13f40 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72         /* Sorter
13f50 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 4d 65 6d   cursor */.  Mem
13f60 20 2a 70 56 61 6c 2c 20 20 20 20 20 20 20 20 20   *pVal,         
13f70 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
13f80 56 61 6c 75 65 20 74 6f 20 63 6f 6d 70 61 72 65  Value to compare
13f90 20 74 6f 20 63 75 72 72 65 6e 74 20 73 6f 72 74   to current sort
13fa0 65 72 20 6b 65 79 20 2a 2f 0a 20 20 69 6e 74 20  er key */.  int 
13fb0 6e 49 67 6e 6f 72 65 2c 20 20 20 20 20 20 20 20  nIgnore,        
13fc0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
13fd0 67 6e 6f 72 65 20 74 68 69 73 20 6d 61 6e 79 20  gnore this many 
13fe0 66 69 65 6c 64 73 20 61 74 20 74 68 65 20 65 6e  fields at the en
13ff0 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 52 65 73  d */.  int *pRes
14000 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14010 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 52         /* OUT: R
14020 65 73 75 6c 74 20 6f 66 20 63 6f 6d 70 61 72 69  esult of compari
14030 73 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65  son */.){.  Vdbe
14040 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20  Sorter *pSorter 
14050 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b  = pCsr->pSorter;
14060 0a 20 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72  .  UnpackedRecor
14070 64 20 2a 72 32 20 3d 20 70 53 6f 72 74 65 72 2d  d *r2 = pSorter-
14080 3e 70 55 6e 70 61 63 6b 65 64 3b 0a 20 20 4b 65  >pUnpacked;.  Ke
14090 79 49 6e 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 20  yInfo *pKeyInfo 
140a0 3d 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f  = pCsr->pKeyInfo
140b0 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 76 6f 69  ;.  int i;.  voi
140c0 64 20 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b 65  d *pKey; int nKe
140d0 79 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  y;           /* 
140e0 53 6f 72 74 65 72 20 6b 65 79 20 74 6f 20 63 6f  Sorter key to co
140f0 6d 70 61 72 65 20 70 56 61 6c 20 77 69 74 68 20  mpare pVal with 
14100 2a 2f 0a 0a 20 20 69 66 28 20 72 32 3d 3d 30 20  */..  if( r2==0 
14110 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 70 3b 0a  ){.    char *p;.
14120 20 20 20 20 72 32 20 3d 20 70 53 6f 72 74 65 72      r2 = pSorter
14130 2d 3e 70 55 6e 70 61 63 6b 65 64 20 3d 20 73 71  ->pUnpacked = sq
14140 6c 69 74 65 33 56 64 62 65 41 6c 6c 6f 63 55 6e  lite3VdbeAllocUn
14150 70 61 63 6b 65 64 52 65 63 6f 72 64 28 70 4b 65  packedRecord(pKe
14160 79 49 6e 66 6f 2c 30 2c 30 2c 26 70 29 3b 0a 20  yInfo,0,0,&p);. 
14170 20 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74     assert( pSort
14180 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64 3d 3d 28  er->pUnpacked==(
14190 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 2a 29  UnpackedRecord*)
141a0 70 20 29 3b 0a 20 20 20 20 69 66 28 20 72 32 3d  p );.    if( r2=
141b0 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  =0 ) return SQLI
141c0 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 72 32  TE_NOMEM;.    r2
141d0 2d 3e 6e 46 69 65 6c 64 20 3d 20 70 4b 65 79 49  ->nField = pKeyI
141e0 6e 66 6f 2d 3e 6e 46 69 65 6c 64 2d 6e 49 67 6e  nfo->nField-nIgn
141f0 6f 72 65 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72  ore;.  }.  asser
14200 74 28 20 72 32 2d 3e 6e 46 69 65 6c 64 3e 3d 70  t( r2->nField>=p
14210 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64 2d  KeyInfo->nField-
14220 6e 49 67 6e 6f 72 65 20 29 3b 0a 0a 20 20 70 4b  nIgnore );..  pK
14230 65 79 20 3d 20 76 64 62 65 53 6f 72 74 65 72 52  ey = vdbeSorterR
14240 6f 77 6b 65 79 28 70 53 6f 72 74 65 72 2c 20 26  owkey(pSorter, &
14250 6e 4b 65 79 29 3b 0a 20 20 73 71 6c 69 74 65 33  nKey);.  sqlite3
14260 56 64 62 65 52 65 63 6f 72 64 55 6e 70 61 63 6b  VdbeRecordUnpack
14270 28 70 4b 65 79 49 6e 66 6f 2c 20 6e 4b 65 79 2c  (pKeyInfo, nKey,
14280 20 70 4b 65 79 2c 20 72 32 29 3b 0a 20 20 66 6f   pKey, r2);.  fo
14290 72 28 69 3d 30 3b 20 69 3c 72 32 2d 3e 6e 46 69  r(i=0; i<r2->nFi
142a0 65 6c 64 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69  eld; i++){.    i
142b0 66 28 20 72 32 2d 3e 61 4d 65 6d 5b 69 5d 2e 66  f( r2->aMem[i].f
142c0 6c 61 67 73 20 26 20 4d 45 4d 5f 4e 75 6c 6c 20  lags & MEM_Null 
142d0 29 7b 0a 20 20 20 20 20 20 2a 70 52 65 73 20 3d  ){.      *pRes =
142e0 20 2d 31 3b 0a 20 20 20 20 20 20 72 65 74 75 72   -1;.      retur
142f0 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20  n SQLITE_OK;.   
14300 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 52 65 73 20   }.  }..  *pRes 
14310 3d 20 73 71 6c 69 74 65 33 56 64 62 65 52 65 63  = sqlite3VdbeRec
14320 6f 72 64 43 6f 6d 70 61 72 65 28 70 56 61 6c 2d  ordCompare(pVal-
14330 3e 6e 2c 20 70 56 61 6c 2d 3e 7a 2c 20 72 32 2c  >n, pVal->z, r2,
14340 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51   0);.  return SQ
14350 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a                 LITE_OK;.}.