/ Hex Artifact Content
Login

Artifact 143de4b9da4e42a4270cb615dddfc9e8d5224373:


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 62 79 20 22 50 52 41  returned by "PRA
1080: 47 4d 41 20 6d 61 69 6e 2e 70 61 67 65 5f 73 69  GMA main.page_si
1090: 7a 65 22 20 6d 75 6c 74 69 70 6c 65 64 20 62 79  ze" multipled by
10a0: 20 0a 2a 2a 20 74 68 61 74 20 72 65 74 75 72 6e   .** that return
10b0: 65 64 20 62 79 20 22 50 52 41 47 4d 41 20 6d 61  ed by "PRAGMA ma
10c0: 69 6e 2e 63 61 63 68 65 5f 73 69 7a 65 22 2c 20  in.cache_size", 
10d0: 69 6e 20 62 79 74 65 73 2e 0a 2a 2a 0a 2a 2a 20  in bytes..**.** 
10e0: 49 66 20 74 68 65 20 73 6f 72 74 65 72 20 69 73  If the sorter is
10f0: 20 72 75 6e 6e 69 6e 67 20 69 6e 20 73 69 6e 67   running in sing
1100: 6c 65 2d 74 68 72 65 61 64 65 64 20 6d 6f 64 65  le-threaded mode
1110: 2c 20 74 68 65 6e 20 61 6c 6c 20 50 4d 41 73 20  , then all PMAs 
1120: 67 65 6e 65 72 61 74 65 64 0a 2a 2a 20 61 72 65  generated.** are
1130: 20 61 70 70 65 6e 64 65 64 20 74 6f 20 61 20 73   appended to a s
1140: 69 6e 67 6c 65 20 74 65 6d 70 6f 72 61 72 79 20  ingle temporary 
1150: 66 69 6c 65 2e 20 4f 72 2c 20 69 66 20 74 68 65  file. Or, if the
1160: 20 73 6f 72 74 65 72 20 69 73 20 72 75 6e 6e 69   sorter is runni
1170: 6e 67 20 69 6e 0a 2a 2a 20 6d 75 6c 74 69 2d 74  ng in.** multi-t
1180: 68 72 65 61 64 65 64 20 6d 6f 64 65 20 74 68 65  hreaded mode the
1190: 6e 20 75 70 20 74 6f 20 28 4e 2b 31 29 20 74 65  n up to (N+1) te
11a0: 6d 70 6f 72 61 72 79 20 66 69 6c 65 73 20 6d 61  mporary files ma
11b0: 79 20 62 65 20 6f 70 65 6e 65 64 2c 20 77 68 65  y be opened, whe
11c0: 72 65 0a 2a 2a 20 4e 20 69 73 20 74 68 65 20 63  re.** N is the c
11d0: 6f 6e 66 69 67 75 72 65 64 20 6e 75 6d 62 65 72  onfigured number
11e0: 20 6f 66 20 77 6f 72 6b 65 72 20 74 68 72 65 61   of worker threa
11f0: 64 73 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65  ds. In this case
1200: 2c 20 69 6e 73 74 65 61 64 20 6f 66 0a 2a 2a 20  , instead of.** 
1210: 73 6f 72 74 69 6e 67 20 74 68 65 20 72 65 63 6f  sorting the reco
1220: 72 64 73 20 61 6e 64 20 77 72 69 74 69 6e 67 20  rds and writing 
1230: 74 68 65 20 50 4d 41 20 74 6f 20 61 20 74 65 6d  the PMA to a tem
1240: 70 6f 72 61 72 79 20 66 69 6c 65 20 69 74 73 65  porary file itse
1250: 6c 66 2c 20 74 68 65 0a 2a 2a 20 63 61 6c 6c 69  lf, the.** calli
1260: 6e 67 20 74 68 72 65 61 64 20 75 73 75 61 6c 6c  ng thread usuall
1270: 79 20 6c 61 75 6e 63 68 65 73 20 61 20 77 6f 72  y launches a wor
1280: 6b 65 72 20 74 68 72 65 61 64 20 74 6f 20 64 6f  ker thread to do
1290: 20 73 6f 2e 20 45 78 63 65 70 74 2c 20 69 66 0a   so. Except, if.
12a0: 2a 2a 20 74 68 65 72 65 20 61 72 65 20 61 6c 72  ** there are alr
12b0: 65 61 64 79 20 4e 20 77 6f 72 6b 65 72 20 74 68  eady N worker th
12c0: 72 65 61 64 73 20 72 75 6e 6e 69 6e 67 2c 20 74  reads running, t
12d0: 68 65 20 6d 61 69 6e 20 74 68 72 65 61 64 20 64  he main thread d
12e0: 6f 65 73 20 74 68 65 20 77 6f 72 6b 0a 2a 2a 20  oes the work.** 
12f0: 69 74 73 65 6c 66 2e 0a 2a 2a 0a 2a 2a 20 54 68  itself..**.** Th
1300: 65 20 73 6f 72 74 65 72 20 69 73 20 72 75 6e 6e  e sorter is runn
1310: 69 6e 67 20 69 6e 20 6d 75 6c 74 69 2d 74 68 72  ing in multi-thr
1320: 65 61 64 65 64 20 6d 6f 64 65 20 69 66 20 28 61  eaded mode if (a
1330: 29 20 74 68 65 20 6c 69 62 72 61 72 79 20 77 61  ) the library wa
1340: 73 20 62 75 69 6c 74 0a 2a 2a 20 77 69 74 68 20  s built.** with 
1350: 70 72 65 2d 70 72 6f 63 65 73 73 6f 72 20 73 79  pre-processor sy
1360: 6d 62 6f 6c 20 53 51 4c 49 54 45 5f 4d 41 58 5f  mbol SQLITE_MAX_
1370: 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 20 73  WORKER_THREADS s
1380: 65 74 20 74 6f 20 61 20 76 61 6c 75 65 20 67 72  et to a value gr
1390: 65 61 74 65 72 0a 2a 2a 20 74 68 61 6e 20 7a 65  eater.** than ze
13a0: 72 6f 2c 20 61 6e 64 20 28 62 29 20 77 6f 72 6b  ro, and (b) work
13b0: 65 72 20 74 68 72 65 61 64 73 20 68 61 76 65 20  er threads have 
13c0: 62 65 65 6e 20 65 6e 61 62 6c 65 64 20 61 74 20  been enabled at 
13d0: 72 75 6e 74 69 6d 65 20 62 79 20 63 61 6c 6c 69  runtime by calli
13e0: 6e 67 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 63 6f  ng.** sqlite3_co
13f0: 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46  nfig(SQLITE_CONF
1400: 49 47 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44  IG_WORKER_THREAD
1410: 53 2c 20 2e 2e 2e 29 2e 0a 2a 2a 0a 2a 2a 20 57  S, ...)..**.** W
1420: 68 65 6e 20 52 65 77 69 6e 64 28 29 20 69 73 20  hen Rewind() is 
1430: 63 61 6c 6c 65 64 2c 20 61 6e 79 20 64 61 74 61  called, any data
1440: 20 72 65 6d 61 69 6e 69 6e 67 20 69 6e 20 6d 65   remaining in me
1450: 6d 6f 72 79 20 69 73 20 66 6c 75 73 68 65 64 20  mory is flushed 
1460: 74 6f 20 61 20 0a 2a 2a 20 66 69 6e 61 6c 20 50  to a .** final P
1470: 4d 41 2e 20 53 6f 20 61 74 20 74 68 69 73 20 70  MA. So at this p
1480: 6f 69 6e 74 20 74 68 65 20 64 61 74 61 20 69 73  oint the data is
1490: 20 73 74 6f 72 65 64 20 69 6e 20 73 6f 6d 65 20   stored in some 
14a0: 6e 75 6d 62 65 72 20 6f 66 20 73 6f 72 74 65 64  number of sorted
14b0: 0a 2a 2a 20 50 4d 41 73 20 77 69 74 68 69 6e 20  .** PMAs within 
14c0: 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 73 20  temporary files 
14d0: 6f 6e 20 64 69 73 6b 2e 0a 2a 2a 0a 2a 2a 20 49  on disk..**.** I
14e0: 66 20 74 68 65 72 65 20 61 72 65 20 66 65 77 65  f there are fewe
14f0: 72 20 74 68 61 6e 20 53 4f 52 54 45 52 5f 4d 41  r than SORTER_MA
1500: 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20 50 4d  X_MERGE_COUNT PM
1510: 41 73 20 69 6e 20 74 6f 74 61 6c 20 61 6e 64 20  As in total and 
1520: 74 68 65 0a 2a 2a 20 73 6f 72 74 65 72 20 69 73  the.** sorter is
1530: 20 72 75 6e 6e 69 6e 67 20 69 6e 20 73 69 6e 67   running in sing
1540: 6c 65 2d 74 68 72 65 61 64 65 64 20 6d 6f 64 65  le-threaded mode
1550: 2c 20 74 68 65 6e 20 74 68 65 73 65 20 50 4d 41  , then these PMA
1560: 73 20 61 72 65 20 6d 65 72 67 65 64 0a 2a 2a 20  s are merged.** 
1570: 69 6e 63 72 65 6d 65 6e 74 61 6c 6c 79 20 61 73  incrementally as
1580: 20 6b 65 79 73 20 61 72 65 20 72 65 74 72 65 69   keys are retrei
1590: 76 65 64 20 66 72 6f 6d 20 74 68 65 20 73 6f 72  ved from the sor
15a0: 74 65 72 20 62 79 20 74 68 65 20 56 44 42 45 2e  ter by the VDBE.
15b0: 20 20 54 68 65 0a 2a 2a 20 4d 65 72 67 65 45 6e    The.** MergeEn
15c0: 67 69 6e 65 20 6f 62 6a 65 63 74 2c 20 64 65 73  gine object, des
15d0: 63 72 69 62 65 64 20 69 6e 20 66 75 72 74 68 65  cribed in furthe
15e0: 72 20 64 65 74 61 69 6c 20 62 65 6c 6f 77 2c 20  r detail below, 
15f0: 70 65 72 66 6f 72 6d 73 20 74 68 69 73 0a 2a 2a  performs this.**
1600: 20 6d 65 72 67 65 2e 0a 2a 2a 0a 2a 2a 20 4f 72   merge..**.** Or
1610: 2c 20 69 66 20 72 75 6e 6e 69 6e 67 20 69 6e 20  , if running in 
1620: 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20 6d  multi-threaded m
1630: 6f 64 65 2c 20 74 68 65 6e 20 61 20 62 61 63 6b  ode, then a back
1640: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 69 73  ground thread is
1650: 0a 2a 2a 20 6c 61 75 6e 63 68 65 64 20 74 6f 20  .** launched to 
1660: 6d 65 72 67 65 20 74 68 65 20 65 78 69 73 74 69  merge the existi
1670: 6e 67 20 50 4d 41 73 2e 20 4f 6e 63 65 20 74 68  ng PMAs. Once th
1680: 65 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  e background thr
1690: 65 61 64 20 68 61 73 0a 2a 2a 20 6d 65 72 67 65  ead has.** merge
16a0: 64 20 54 20 62 79 74 65 73 20 6f 66 20 64 61 74  d T bytes of dat
16b0: 61 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65 20  a into a single 
16c0: 73 6f 72 74 65 64 20 50 4d 41 2c 20 74 68 65 20  sorted PMA, the 
16d0: 6d 61 69 6e 20 74 68 72 65 61 64 20 0a 2a 2a 20  main thread .** 
16e0: 62 65 67 69 6e 73 20 72 65 61 64 69 6e 67 20 6b  begins reading k
16f0: 65 79 73 20 66 72 6f 6d 20 74 68 61 74 20 50 4d  eys from that PM
1700: 41 20 77 68 69 6c 65 20 74 68 65 20 62 61 63 6b  A while the back
1710: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 70 72  ground thread pr
1720: 6f 63 65 65 64 73 0a 2a 2a 20 77 69 74 68 20 6d  oceeds.** with m
1730: 65 72 67 69 6e 67 20 74 68 65 20 6e 65 78 74 20  erging the next 
1740: 54 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 2e  T bytes of data.
1750: 20 41 6e 64 20 73 6f 20 6f 6e 2e 0a 2a 2a 0a 2a   And so on..**.*
1760: 2a 20 50 61 72 61 6d 65 74 65 72 20 54 20 69 73  * Parameter T is
1770: 20 73 65 74 20 74 6f 20 68 61 6c 66 20 74 68 65   set to half the
1780: 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 6d 65   value of the me
1790: 6d 6f 72 79 20 74 68 72 65 73 68 6f 6c 64 20 75  mory threshold u
17a0: 73 65 64 20 0a 2a 2a 20 62 79 20 57 72 69 74 65  sed .** by Write
17b0: 28 29 20 61 62 6f 76 65 20 74 6f 20 64 65 74 65  () above to dete
17c0: 72 6d 69 6e 65 20 77 68 65 6e 20 74 6f 20 63 72  rmine when to cr
17d0: 65 61 74 65 20 61 20 6e 65 77 20 50 4d 41 2e 0a  eate a new PMA..
17e0: 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65 20 61  **.** If there a
17f0: 72 65 20 6d 6f 72 65 20 74 68 61 6e 20 53 4f 52  re more than SOR
1800: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
1810: 55 4e 54 20 50 4d 41 73 20 69 6e 20 74 6f 74 61  UNT PMAs in tota
1820: 6c 20 77 68 65 6e 20 0a 2a 2a 20 52 65 77 69 6e  l when .** Rewin
1830: 64 28 29 20 69 73 20 63 61 6c 6c 65 64 2c 20 74  d() is called, t
1840: 68 65 6e 20 61 20 68 69 65 72 61 72 63 68 79 20  hen a hierarchy 
1850: 6f 66 20 69 6e 63 72 65 6d 65 6e 74 61 6c 2d 6d  of incremental-m
1860: 65 72 67 65 73 20 69 73 20 75 73 65 64 2e 20 0a  erges is used. .
1870: 2a 2a 20 46 69 72 73 74 2c 20 54 20 62 79 74 65  ** First, T byte
1880: 73 20 6f 66 20 64 61 74 61 20 66 72 6f 6d 20 74  s of data from t
1890: 68 65 20 66 69 72 73 74 20 53 4f 52 54 45 52 5f  he first SORTER_
18a0: 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20  MAX_MERGE_COUNT 
18b0: 50 4d 41 73 20 6f 6e 20 0a 2a 2a 20 64 69 73 6b  PMAs on .** disk
18c0: 20 61 72 65 20 6d 65 72 67 65 64 20 74 6f 67 65   are merged toge
18d0: 74 68 65 72 2e 20 54 68 65 6e 20 54 20 62 79 74  ther. Then T byt
18e0: 65 73 20 6f 66 20 64 61 74 61 20 66 72 6f 6d 20  es of data from 
18f0: 74 68 65 20 73 65 63 6f 6e 64 20 73 65 74 2c 20  the second set, 
1900: 61 6e 64 0a 2a 2a 20 73 6f 20 6f 6e 2c 20 73 75  and.** so on, su
1910: 63 68 20 74 68 61 74 20 6e 6f 20 6f 70 65 72 61  ch that no opera
1920: 74 69 6f 6e 20 65 76 65 72 20 6d 65 72 67 65 73  tion ever merges
1930: 20 6d 6f 72 65 20 74 68 61 6e 20 53 4f 52 54 45   more than SORTE
1940: 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
1950: 54 0a 2a 2a 20 50 4d 41 73 20 61 74 20 61 20 74  T.** PMAs at a t
1960: 69 6d 65 2e 20 54 68 69 73 20 64 6f 6e 65 20 69  ime. This done i
1970: 73 20 74 6f 20 69 6d 70 72 6f 76 65 20 6c 6f 63  s to improve loc
1980: 61 6c 69 74 79 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  ality..**.** If 
1990: 72 75 6e 6e 69 6e 67 20 69 6e 20 6d 75 6c 74 69  running in multi
19a0: 2d 74 68 72 65 61 64 65 64 20 6d 6f 64 65 20 61  -threaded mode a
19b0: 6e 64 20 74 68 65 72 65 20 61 72 65 20 6d 6f 72  nd there are mor
19c0: 65 20 74 68 61 6e 0a 2a 2a 20 53 4f 52 54 45 52  e than.** SORTER
19d0: 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
19e0: 20 50 4d 41 73 20 6f 6e 20 64 69 73 6b 20 77 68   PMAs on disk wh
19f0: 65 6e 20 52 65 77 69 6e 64 28 29 20 69 73 20 63  en Rewind() is c
1a00: 61 6c 6c 65 64 2c 20 74 68 65 6e 20 6d 6f 72 65  alled, then more
1a10: 0a 2a 2a 20 74 68 61 6e 20 6f 6e 65 20 62 61 63  .** than one bac
1a20: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 6d  kground thread m
1a30: 61 79 20 62 65 20 63 72 65 61 74 65 64 2e 20 53  ay be created. S
1a40: 70 65 63 69 66 69 63 61 6c 6c 79 2c 20 74 68 65  pecifically, the
1a50: 72 65 20 6d 61 79 20 62 65 0a 2a 2a 20 6f 6e 65  re may be.** one
1a60: 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65   background thre
1a70: 61 64 20 66 6f 72 20 65 61 63 68 20 74 65 6d 70  ad for each temp
1a80: 6f 72 61 72 79 20 66 69 6c 65 20 6f 6e 20 64 69  orary file on di
1a90: 73 6b 2c 20 61 6e 64 20 6f 6e 65 20 62 61 63 6b  sk, and one back
1aa0: 67 72 6f 75 6e 64 0a 2a 2a 20 74 68 72 65 61 64  ground.** thread
1ab0: 20 74 6f 20 6d 65 72 67 65 20 74 68 65 20 6f 75   to merge the ou
1ac0: 74 70 75 74 20 6f 66 20 65 61 63 68 20 6f 66 20  tput of each of 
1ad0: 74 68 65 20 6f 74 68 65 72 73 20 74 6f 20 61 20  the others to a 
1ae0: 73 69 6e 67 6c 65 20 50 4d 41 20 66 6f 72 0a 2a  single PMA for.*
1af0: 2a 20 74 68 65 20 6d 61 69 6e 20 74 68 72 65 61  * the main threa
1b00: 64 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 2e 0a  d to read from..
1b10: 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c  */.#include "sql
1b20: 69 74 65 49 6e 74 2e 68 22 0a 23 69 6e 63 6c 75  iteInt.h".#inclu
1b30: 64 65 20 22 76 64 62 65 49 6e 74 2e 68 22 0a 0a  de "vdbeInt.h"..
1b40: 2f 2a 20 0a 2a 2a 20 49 66 20 53 51 4c 49 54 45  /* .** If SQLITE
1b50: 5f 44 45 42 55 47 5f 53 4f 52 54 45 52 5f 54 48  _DEBUG_SORTER_TH
1b60: 52 45 41 44 53 20 69 73 20 64 65 66 69 6e 65 64  READS is defined
1b70: 2c 20 74 68 69 73 20 6d 6f 64 75 6c 65 20 6f 75  , this module ou
1b80: 74 70 75 74 73 20 76 61 72 69 6f 75 73 0a 2a 2a  tputs various.**
1b90: 20 6d 65 73 73 61 67 65 73 20 74 6f 20 73 74 64   messages to std
1ba0: 65 72 72 20 74 68 61 74 20 6d 61 79 20 62 65 20  err that may be 
1bb0: 68 65 6c 70 66 75 6c 20 69 6e 20 75 6e 64 65 72  helpful in under
1bc0: 73 74 61 6e 64 69 6e 67 20 74 68 65 20 70 65 72  standing the per
1bd0: 66 6f 72 6d 61 6e 63 65 0a 2a 2a 20 63 68 61 72  formance.** char
1be0: 61 63 74 65 72 69 73 74 69 63 73 20 6f 66 20 74  acteristics of t
1bf0: 68 65 20 73 6f 72 74 65 72 20 69 6e 20 6d 75 6c  he sorter in mul
1c00: 74 69 2d 74 68 72 65 61 64 65 64 20 6d 6f 64 65  ti-threaded mode
1c10: 2e 0a 2a 2f 0a 23 69 66 20 30 0a 23 20 64 65 66  ..*/.#if 0.# def
1c20: 69 6e 65 20 53 51 4c 49 54 45 5f 44 45 42 55 47  ine SQLITE_DEBUG
1c30: 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44 53 20  _SORTER_THREADS 
1c40: 31 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20  1.#endif../*.** 
1c50: 50 72 69 76 61 74 65 20 6f 62 6a 65 63 74 73 20  Private objects 
1c60: 75 73 65 64 20 62 79 20 74 68 65 20 73 6f 72 74  used by the sort
1c70: 65 72 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74  er.*/.typedef st
1c80: 72 75 63 74 20 4d 65 72 67 65 45 6e 67 69 6e 65  ruct MergeEngine
1c90: 20 4d 65 72 67 65 45 6e 67 69 6e 65 3b 20 20 20   MergeEngine;   
1ca0: 20 20 2f 2a 20 4d 65 72 67 65 20 50 4d 41 73 20    /* Merge PMAs 
1cb0: 74 6f 67 65 74 68 65 72 20 2a 2f 0a 74 79 70 65  together */.type
1cc0: 64 65 66 20 73 74 72 75 63 74 20 50 6d 61 52 65  def struct PmaRe
1cd0: 61 64 65 72 20 50 6d 61 52 65 61 64 65 72 3b 20  ader PmaReader; 
1ce0: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 63 72 65          /* Incre
1cf0: 6d 65 6e 74 61 6c 6c 79 20 72 65 61 64 20 6f 6e  mentally read on
1d00: 65 20 50 4d 41 20 2a 2f 0a 74 79 70 65 64 65 66  e PMA */.typedef
1d10: 20 73 74 72 75 63 74 20 50 6d 61 57 72 69 74 65   struct PmaWrite
1d20: 72 20 50 6d 61 57 72 69 74 65 72 3b 20 20 20 20  r PmaWriter;    
1d30: 20 20 20 20 20 2f 2a 20 49 6e 63 72 65 6d 65 6e       /* Incremen
1d40: 74 61 6c 6c 79 20 77 72 69 74 65 20 6f 6e 65 20  tally write one 
1d50: 50 4d 41 20 2a 2f 0a 74 79 70 65 64 65 66 20 73  PMA */.typedef s
1d60: 74 72 75 63 74 20 53 6f 72 74 65 72 52 65 63 6f  truct SorterReco
1d70: 72 64 20 53 6f 72 74 65 72 52 65 63 6f 72 64 3b  rd SorterRecord;
1d80: 20 20 20 2f 2a 20 41 20 72 65 63 6f 72 64 20 62     /* A record b
1d90: 65 69 6e 67 20 73 6f 72 74 65 64 20 2a 2f 0a 74  eing sorted */.t
1da0: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53 6f  ypedef struct So
1db0: 72 74 53 75 62 74 61 73 6b 20 53 6f 72 74 53 75  rtSubtask SortSu
1dc0: 62 74 61 73 6b 3b 20 20 20 20 20 2f 2a 20 41 20  btask;     /* A 
1dd0: 73 75 62 2d 74 61 73 6b 20 69 6e 20 74 68 65 20  sub-task in the 
1de0: 73 6f 72 74 20 70 72 6f 63 65 73 73 20 2a 2f 0a  sort process */.
1df0: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53  typedef struct S
1e00: 6f 72 74 65 72 46 69 6c 65 20 53 6f 72 74 65 72  orterFile Sorter
1e10: 46 69 6c 65 3b 20 20 20 20 20 20 20 2f 2a 20 54  File;       /* T
1e20: 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 20 6f 62  emporary file ob
1e30: 6a 65 63 74 20 77 72 61 70 70 65 72 20 2a 2f 0a  ject wrapper */.
1e40: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53  typedef struct S
1e50: 6f 72 74 65 72 4c 69 73 74 20 53 6f 72 74 65 72  orterList Sorter
1e60: 4c 69 73 74 3b 20 20 20 20 20 20 20 2f 2a 20 49  List;       /* I
1e70: 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20 6f 66  n-memory list of
1e80: 20 72 65 63 6f 72 64 73 20 2a 2f 0a 74 79 70 65   records */.type
1e90: 64 65 66 20 73 74 72 75 63 74 20 49 6e 63 72 4d  def struct IncrM
1ea0: 65 72 67 65 72 20 49 6e 63 72 4d 65 72 67 65 72  erger IncrMerger
1eb0: 3b 20 20 20 20 20 20 20 2f 2a 20 52 65 61 64 20  ;       /* Read 
1ec0: 26 20 6d 65 72 67 65 20 6d 75 6c 74 69 70 6c 65  & merge multiple
1ed0: 20 50 4d 41 73 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20   PMAs */../*.** 
1ee0: 41 20 63 6f 6e 74 61 69 6e 65 72 20 66 6f 72 20  A container for 
1ef0: 61 20 74 65 6d 70 20 66 69 6c 65 20 68 61 6e 64  a temp file hand
1f00: 6c 65 20 61 6e 64 20 74 68 65 20 63 75 72 72 65  le and the curre
1f10: 6e 74 20 61 6d 6f 75 6e 74 20 6f 66 20 64 61 74  nt amount of dat
1f20: 61 20 0a 2a 2a 20 73 74 6f 72 65 64 20 69 6e 20  a .** stored in 
1f30: 74 68 65 20 66 69 6c 65 2e 0a 2a 2f 0a 73 74 72  the file..*/.str
1f40: 75 63 74 20 53 6f 72 74 65 72 46 69 6c 65 20 7b  uct SorterFile {
1f50: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
1f60: 2a 70 46 64 3b 20 20 20 20 20 20 20 20 20 20 20  *pFd;           
1f70: 20 20 20 2f 2a 20 46 69 6c 65 20 68 61 6e 64 6c     /* File handl
1f80: 65 20 2a 2f 0a 20 20 69 36 34 20 69 45 6f 66 3b  e */.  i64 iEof;
1f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fa0: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
1fb0: 6f 66 20 64 61 74 61 20 73 74 6f 72 65 64 20 69  of data stored i
1fc0: 6e 20 70 46 64 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  n pFd */.};../*.
1fd0: 2a 2a 20 41 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20  ** An in-memory 
1fe0: 6c 69 73 74 20 6f 66 20 6f 62 6a 65 63 74 73 20  list of objects 
1ff0: 74 6f 20 62 65 20 73 6f 72 74 65 64 2e 0a 2a 2a  to be sorted..**
2000: 0a 2a 2a 20 49 66 20 61 4d 65 6d 6f 72 79 3d 3d  .** If aMemory==
2010: 30 20 74 68 65 6e 20 65 61 63 68 20 6f 62 6a 65  0 then each obje
2020: 63 74 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 20  ct is allocated 
2030: 73 65 70 61 72 61 74 65 6c 79 20 61 6e 64 20 74  separately and t
2040: 68 65 20 6f 62 6a 65 63 74 73 0a 2a 2a 20 61 72  he objects.** ar
2050: 65 20 63 6f 6e 6e 65 63 74 65 64 20 75 73 69 6e  e connected usin
2060: 67 20 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 75  g SorterRecord.u
2070: 2e 70 4e 65 78 74 2e 20 20 49 66 20 61 4d 65 6d  .pNext.  If aMem
2080: 6f 72 79 21 3d 30 20 74 68 65 6e 20 61 6c 6c 20  ory!=0 then all 
2090: 6f 62 6a 65 63 74 73 0a 2a 2a 20 61 72 65 20 73  objects.** are s
20a0: 74 6f 72 65 64 20 69 6e 20 74 68 65 20 61 4d 65  tored in the aMe
20b0: 6d 6f 72 79 5b 5d 20 62 75 6c 6b 20 6d 65 6d 6f  mory[] bulk memo
20c0: 72 79 2c 20 6f 6e 65 20 72 69 67 68 74 20 61 66  ry, one right af
20d0: 74 65 72 20 74 68 65 20 6f 74 68 65 72 2c 20 61  ter the other, a
20e0: 6e 64 0a 2a 2a 20 61 72 65 20 63 6f 6e 6e 65 63  nd.** are connec
20f0: 74 65 64 20 75 73 69 6e 67 20 53 6f 72 74 65 72  ted using Sorter
2100: 52 65 63 6f 72 64 2e 75 2e 69 4e 65 78 74 2e 0a  Record.u.iNext..
2110: 2a 2f 0a 73 74 72 75 63 74 20 53 6f 72 74 65 72  */.struct Sorter
2120: 4c 69 73 74 20 7b 0a 20 20 53 6f 72 74 65 72 52  List {.  SorterR
2130: 65 63 6f 72 64 20 2a 70 4c 69 73 74 3b 20 20 20  ecord *pList;   
2140: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 6e 6b           /* Link
2150: 65 64 20 6c 69 73 74 20 6f 66 20 72 65 63 6f 72  ed list of recor
2160: 64 73 20 2a 2f 0a 20 20 75 38 20 2a 61 4d 65 6d  ds */.  u8 *aMem
2170: 6f 72 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  ory;            
2180: 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 6e 6f          /* If no
2190: 6e 2d 4e 55 4c 4c 2c 20 62 75 6c 6b 20 6d 65 6d  n-NULL, bulk mem
21a0: 6f 72 79 20 74 6f 20 68 6f 6c 64 20 70 4c 69 73  ory to hold pLis
21b0: 74 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 4d 41  t */.  int szPMA
21c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
21d0: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
21e0: 66 20 70 4c 69 73 74 20 61 73 20 50 4d 41 20 69  f pList as PMA i
21f0: 6e 20 62 79 74 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f  n bytes */.};../
2200: 2a 0a 2a 2a 20 54 68 65 20 4d 65 72 67 65 45 6e  *.** The MergeEn
2210: 67 69 6e 65 20 6f 62 6a 65 63 74 20 69 73 20 75  gine object is u
2220: 73 65 64 20 74 6f 20 63 6f 6d 62 69 6e 65 20 74  sed to combine t
2230: 77 6f 20 6f 72 20 6d 6f 72 65 20 73 6d 61 6c 6c  wo or more small
2240: 65 72 20 50 4d 41 73 20 69 6e 74 6f 0a 2a 2a 20  er PMAs into.** 
2250: 6f 6e 65 20 62 69 67 20 50 4d 41 20 75 73 69 6e  one big PMA usin
2260: 67 20 61 20 6d 65 72 67 65 20 6f 70 65 72 61 74  g a merge operat
2270: 69 6f 6e 2e 20 20 53 65 70 61 72 61 74 65 20 50  ion.  Separate P
2280: 4d 41 73 20 61 6c 6c 20 6e 65 65 64 20 74 6f 20  MAs all need to 
2290: 62 65 0a 2a 2a 20 63 6f 6d 62 69 6e 65 64 20 69  be.** combined i
22a0: 6e 74 6f 20 6f 6e 65 20 62 69 67 20 50 4d 41 20  nto one big PMA 
22b0: 69 6e 20 6f 72 64 65 72 20 74 6f 20 62 65 20 61  in order to be a
22c0: 62 6c 65 20 74 6f 20 73 74 65 70 20 74 68 72 6f  ble to step thro
22d0: 75 67 68 20 74 68 65 20 73 6f 72 74 65 64 0a 2a  ugh the sorted.*
22e0: 2a 20 72 65 63 6f 72 64 73 20 69 6e 20 6f 72 64  * records in ord
22f0: 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 52  er..**.** The aR
2300: 65 61 64 72 5b 5d 20 61 72 72 61 79 20 63 6f 6e  eadr[] array con
2310: 74 61 69 6e 73 20 61 20 50 6d 61 52 65 61 64 65  tains a PmaReade
2320: 72 20 6f 62 6a 65 63 74 20 66 6f 72 20 65 61 63  r object for eac
2330: 68 20 6f 66 20 74 68 65 20 50 4d 41 73 20 62 65  h of the PMAs be
2340: 69 6e 67 0a 2a 2a 20 6d 65 72 67 65 64 2e 20 20  ing.** merged.  
2350: 41 6e 20 61 52 65 61 64 72 5b 5d 20 6f 62 6a 65  An aReadr[] obje
2360: 63 74 20 65 69 74 68 65 72 20 70 6f 69 6e 74 73  ct either points
2370: 20 74 6f 20 61 20 76 61 6c 69 64 20 6b 65 79 20   to a valid key 
2380: 6f 72 20 65 6c 73 65 20 69 73 20 61 74 20 45 4f  or else is at EO
2390: 46 2e 0a 2a 2a 20 28 22 45 4f 46 22 20 6d 65 61  F..** ("EOF" mea
23a0: 6e 73 20 22 45 6e 64 20 4f 66 20 46 69 6c 65 22  ns "End Of File"
23b0: 2e 20 20 57 68 65 6e 20 61 52 65 61 64 72 5b 5d  .  When aReadr[]
23c0: 20 69 73 20 61 74 20 45 4f 46 20 74 68 65 72 65   is at EOF there
23d0: 20 69 73 20 6e 6f 20 6d 6f 72 65 20 64 61 74 61   is no more data
23e0: 2e 29 0a 2a 2a 20 46 6f 72 20 74 68 65 20 70 75  .).** For the pu
23f0: 72 70 6f 73 65 73 20 6f 66 20 74 68 65 20 70 61  rposes of the pa
2400: 72 61 67 72 61 70 68 73 20 62 65 6c 6f 77 2c 20  ragraphs below, 
2410: 77 65 20 61 73 73 75 6d 65 20 74 68 61 74 20 74  we assume that t
2420: 68 65 20 61 72 72 61 79 20 69 73 0a 2a 2a 20 61  he array is.** a
2430: 63 74 75 61 6c 6c 79 20 4e 20 65 6c 65 6d 65 6e  ctually N elemen
2440: 74 73 20 69 6e 20 73 69 7a 65 2c 20 77 68 65 72  ts in size, wher
2450: 65 20 4e 20 69 73 20 74 68 65 20 73 6d 61 6c 6c  e N is the small
2460: 65 73 74 20 70 6f 77 65 72 20 6f 66 20 32 20 67  est power of 2 g
2470: 72 65 61 74 65 72 0a 2a 2a 20 74 6f 20 6f 72 20  reater.** to or 
2480: 65 71 75 61 6c 20 74 6f 20 74 68 65 20 6e 75 6d  equal to the num
2490: 62 65 72 20 6f 66 20 50 4d 41 73 20 62 65 69 6e  ber of PMAs bein
24a0: 67 20 6d 65 72 67 65 64 2e 20 54 68 65 20 65 78  g merged. The ex
24b0: 74 72 61 20 61 52 65 61 64 72 5b 5d 20 65 6c 65  tra aReadr[] ele
24c0: 6d 65 6e 74 73 0a 2a 2a 20 61 72 65 20 74 72 65  ments.** are tre
24d0: 61 74 65 64 20 61 73 20 69 66 20 74 68 65 79 20  ated as if they 
24e0: 61 72 65 20 65 6d 70 74 79 20 28 61 6c 77 61 79  are empty (alway
24f0: 73 20 61 74 20 45 4f 46 29 2e 0a 2a 2a 0a 2a 2a  s at EOF)..**.**
2500: 20 54 68 65 20 61 54 72 65 65 5b 5d 20 61 72 72   The aTree[] arr
2510: 61 79 20 69 73 20 61 6c 73 6f 20 4e 20 65 6c 65  ay is also N ele
2520: 6d 65 6e 74 73 20 69 6e 20 73 69 7a 65 2e 20 54  ments in size. T
2530: 68 65 20 76 61 6c 75 65 20 6f 66 20 4e 20 69 73  he value of N is
2540: 20 73 74 6f 72 65 64 20 69 6e 0a 2a 2a 20 74 68   stored in.** th
2550: 65 20 4d 65 72 67 65 45 6e 67 69 6e 65 2e 6e 54  e MergeEngine.nT
2560: 72 65 65 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2a  ree variable..**
2570: 0a 2a 2a 20 54 68 65 20 66 69 6e 61 6c 20 28 4e  .** The final (N
2580: 2f 32 29 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20  /2) elements of 
2590: 61 54 72 65 65 5b 5d 20 63 6f 6e 74 61 69 6e 20  aTree[] contain 
25a0: 74 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20 63  the results of c
25b0: 6f 6d 70 61 72 69 6e 67 0a 2a 2a 20 70 61 69 72  omparing.** pair
25c0: 73 20 6f 66 20 50 4d 41 20 6b 65 79 73 20 74 6f  s of PMA keys to
25d0: 67 65 74 68 65 72 2e 20 45 6c 65 6d 65 6e 74 20  gether. Element 
25e0: 69 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 72  i contains the r
25f0: 65 73 75 6c 74 20 6f 66 20 0a 2a 2a 20 63 6f 6d  esult of .** com
2600: 70 61 72 69 6e 67 20 61 52 65 61 64 72 5b 32 2a  paring aReadr[2*
2610: 69 2d 4e 5d 20 61 6e 64 20 61 52 65 61 64 72 5b  i-N] and aReadr[
2620: 32 2a 69 2d 4e 2b 31 5d 2e 20 57 68 69 63 68 65  2*i-N+1]. Whiche
2630: 76 65 72 20 6b 65 79 20 69 73 20 73 6d 61 6c 6c  ver key is small
2640: 65 72 2c 20 74 68 65 0a 2a 2a 20 61 54 72 65 65  er, the.** aTree
2650: 20 65 6c 65 6d 65 6e 74 20 69 73 20 73 65 74 20   element is set 
2660: 74 6f 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20  to the index of 
2670: 69 74 2e 20 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 74  it. .**.** For t
2680: 68 65 20 70 75 72 70 6f 73 65 73 20 6f 66 20 74  he purposes of t
2690: 68 69 73 20 63 6f 6d 70 61 72 69 73 6f 6e 2c 20  his comparison, 
26a0: 45 4f 46 20 69 73 20 63 6f 6e 73 69 64 65 72 65  EOF is considere
26b0: 64 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 61  d greater than a
26c0: 6e 79 0a 2a 2a 20 6f 74 68 65 72 20 6b 65 79 20  ny.** other key 
26d0: 76 61 6c 75 65 2e 20 49 66 20 74 68 65 20 6b 65  value. If the ke
26e0: 79 73 20 61 72 65 20 65 71 75 61 6c 20 28 6f 6e  ys are equal (on
26f0: 6c 79 20 70 6f 73 73 69 62 6c 65 20 77 69 74 68  ly possible with
2700: 20 74 77 6f 20 45 4f 46 0a 2a 2a 20 76 61 6c 75   two EOF.** valu
2710: 65 73 29 2c 20 69 74 20 64 6f 65 73 6e 27 74 20  es), it doesn't 
2720: 6d 61 74 74 65 72 20 77 68 69 63 68 20 69 6e 64  matter which ind
2730: 65 78 20 69 73 20 73 74 6f 72 65 64 2e 0a 2a 2a  ex is stored..**
2740: 0a 2a 2a 20 54 68 65 20 28 4e 2f 34 29 20 65 6c  .** The (N/4) el
2750: 65 6d 65 6e 74 73 20 6f 66 20 61 54 72 65 65 5b  ements of aTree[
2760: 5d 20 74 68 61 74 20 70 72 65 63 65 64 65 20 74  ] that precede t
2770: 68 65 20 66 69 6e 61 6c 20 28 4e 2f 32 29 20 64  he final (N/2) d
2780: 65 73 63 72 69 62 65 64 20 0a 2a 2a 20 61 62 6f  escribed .** abo
2790: 76 65 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  ve contains the 
27a0: 69 6e 64 65 78 20 6f 66 20 74 68 65 20 73 6d 61  index of the sma
27b0: 6c 6c 65 73 74 20 6f 66 20 65 61 63 68 20 62 6c  llest of each bl
27c0: 6f 63 6b 20 6f 66 20 34 20 50 6d 61 52 65 61 64  ock of 4 PmaRead
27d0: 65 72 73 0a 2a 2a 20 41 6e 64 20 73 6f 20 6f 6e  ers.** And so on
27e0: 2e 20 53 6f 20 74 68 61 74 20 61 54 72 65 65 5b  . So that aTree[
27f0: 31 5d 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  1] contains the 
2800: 69 6e 64 65 78 20 6f 66 20 74 68 65 20 50 6d 61  index of the Pma
2810: 52 65 61 64 65 72 20 74 68 61 74 20 0a 2a 2a 20  Reader that .** 
2820: 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73  currently points
2830: 20 74 6f 20 74 68 65 20 73 6d 61 6c 6c 65 73 74   to the smallest
2840: 20 6b 65 79 20 76 61 6c 75 65 2e 20 61 54 72 65   key value. aTre
2850: 65 5b 30 5d 20 69 73 20 75 6e 75 73 65 64 2e 0a  e[0] is unused..
2860: 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65 3a 0a 2a  **.** Example:.*
2870: 2a 0a 2a 2a 20 20 20 20 20 61 52 65 61 64 72 5b  *.**     aReadr[
2880: 30 5d 20 2d 3e 20 42 61 6e 61 6e 61 0a 2a 2a 20  0] -> Banana.** 
2890: 20 20 20 20 61 52 65 61 64 72 5b 31 5d 20 2d 3e      aReadr[1] ->
28a0: 20 46 65 69 6a 6f 61 0a 2a 2a 20 20 20 20 20 61   Feijoa.**     a
28b0: 52 65 61 64 72 5b 32 5d 20 2d 3e 20 45 6c 64 65  Readr[2] -> Elde
28c0: 72 62 65 72 72 79 0a 2a 2a 20 20 20 20 20 61 52  rberry.**     aR
28d0: 65 61 64 72 5b 33 5d 20 2d 3e 20 43 75 72 72 61  eadr[3] -> Curra
28e0: 6e 74 0a 2a 2a 20 20 20 20 20 61 52 65 61 64 72  nt.**     aReadr
28f0: 5b 34 5d 20 2d 3e 20 47 72 61 70 65 66 72 75 69  [4] -> Grapefrui
2900: 74 0a 2a 2a 20 20 20 20 20 61 52 65 61 64 72 5b  t.**     aReadr[
2910: 35 5d 20 2d 3e 20 41 70 70 6c 65 0a 2a 2a 20 20  5] -> Apple.**  
2920: 20 20 20 61 52 65 61 64 72 5b 36 5d 20 2d 3e 20     aReadr[6] -> 
2930: 44 75 72 69 61 6e 0a 2a 2a 20 20 20 20 20 61 52  Durian.**     aR
2940: 65 61 64 72 5b 37 5d 20 2d 3e 20 45 4f 46 0a 2a  eadr[7] -> EOF.*
2950: 2a 0a 2a 2a 20 20 20 20 20 61 54 72 65 65 5b 5d  *.**     aTree[]
2960: 20 3d 20 7b 20 58 2c 20 35 20 20 20 30 2c 20 35   = { X, 5   0, 5
2970: 20 20 20 20 30 2c 20 33 2c 20 35 2c 20 36 20 7d      0, 3, 5, 6 }
2980: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 75 72 72 65  .**.** The curre
2990: 6e 74 20 65 6c 65 6d 65 6e 74 20 69 73 20 22 41  nt element is "A
29a0: 70 70 6c 65 22 20 28 74 68 65 20 76 61 6c 75 65  pple" (the value
29b0: 20 6f 66 20 74 68 65 20 6b 65 79 20 69 6e 64 69   of the key indi
29c0: 63 61 74 65 64 20 62 79 20 0a 2a 2a 20 50 6d 61  cated by .** Pma
29d0: 52 65 61 64 65 72 20 35 29 2e 20 57 68 65 6e 20  Reader 5). When 
29e0: 74 68 65 20 4e 65 78 74 28 29 20 6f 70 65 72 61  the Next() opera
29f0: 74 69 6f 6e 20 69 73 20 69 6e 76 6f 6b 65 64 2c  tion is invoked,
2a00: 20 50 6d 61 52 65 61 64 65 72 20 35 20 77 69 6c   PmaReader 5 wil
2a10: 6c 0a 2a 2a 20 62 65 20 61 64 76 61 6e 63 65 64  l.** be advanced
2a20: 20 74 6f 20 74 68 65 20 6e 65 78 74 20 6b 65 79   to the next key
2a30: 20 69 6e 20 69 74 73 20 73 65 67 6d 65 6e 74 2e   in its segment.
2a40: 20 53 61 79 20 74 68 65 20 6e 65 78 74 20 6b 65   Say the next ke
2a50: 79 20 69 73 0a 2a 2a 20 22 45 67 67 70 6c 61 6e  y is.** "Eggplan
2a60: 74 22 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 52  t":.**.**     aR
2a70: 65 61 64 72 5b 35 5d 20 2d 3e 20 45 67 67 70 6c  eadr[5] -> Eggpl
2a80: 61 6e 74 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f  ant.**.** The co
2a90: 6e 74 65 6e 74 73 20 6f 66 20 61 54 72 65 65 5b  ntents of aTree[
2aa0: 5d 20 61 72 65 20 75 70 64 61 74 65 64 20 66 69  ] are updated fi
2ab0: 72 73 74 20 62 79 20 63 6f 6d 70 61 72 69 6e 67  rst by comparing
2ac0: 20 74 68 65 20 6e 65 77 20 50 6d 61 52 65 61 64   the new PmaRead
2ad0: 65 72 0a 2a 2a 20 35 20 6b 65 79 20 74 6f 20 74  er.** 5 key to t
2ae0: 68 65 20 63 75 72 72 65 6e 74 20 6b 65 79 20 6f  he current key o
2af0: 66 20 50 6d 61 52 65 61 64 65 72 20 34 20 28 73  f PmaReader 4 (s
2b00: 74 69 6c 6c 20 22 47 72 61 70 65 66 72 75 69 74  till "Grapefruit
2b10: 22 29 2e 20 54 68 65 20 50 6d 61 52 65 61 64 65  "). The PmaReade
2b20: 72 0a 2a 2a 20 35 20 76 61 6c 75 65 20 69 73 20  r.** 5 value is 
2b30: 73 74 69 6c 6c 20 73 6d 61 6c 6c 65 72 2c 20 73  still smaller, s
2b40: 6f 20 61 54 72 65 65 5b 36 5d 20 69 73 20 73 65  o aTree[6] is se
2b50: 74 20 74 6f 20 35 2e 20 41 6e 64 20 73 6f 20 6f  t to 5. And so o
2b60: 6e 20 75 70 20 74 68 65 20 74 72 65 65 2e 0a 2a  n up the tree..*
2b70: 2a 20 54 68 65 20 76 61 6c 75 65 20 6f 66 20 50  * The value of P
2b80: 6d 61 52 65 61 64 65 72 20 36 20 2d 20 22 44 75  maReader 6 - "Du
2b90: 72 69 61 6e 22 20 2d 20 69 73 20 6e 6f 77 20 73  rian" - is now s
2ba0: 6d 61 6c 6c 65 72 20 74 68 61 6e 20 74 68 61 74  maller than that
2bb0: 20 6f 66 20 50 6d 61 52 65 61 64 65 72 0a 2a 2a   of PmaReader.**
2bc0: 20 35 2c 20 73 6f 20 61 54 72 65 65 5b 33 5d 20   5, so aTree[3] 
2bd0: 69 73 20 73 65 74 20 74 6f 20 36 2e 20 4b 65 79  is set to 6. Key
2be0: 20 30 20 69 73 20 73 6d 61 6c 6c 65 72 20 74 68   0 is smaller th
2bf0: 61 6e 20 6b 65 79 20 36 20 28 42 61 6e 61 6e 61  an key 6 (Banana
2c00: 3c 44 75 72 69 61 6e 29 2c 0a 2a 2a 20 73 6f 20  <Durian),.** so 
2c10: 74 68 65 20 76 61 6c 75 65 20 77 72 69 74 74 65  the value writte
2c20: 6e 20 69 6e 74 6f 20 65 6c 65 6d 65 6e 74 20 31  n into element 1
2c30: 20 6f 66 20 74 68 65 20 61 72 72 61 79 20 69 73   of the array is
2c40: 20 30 2e 20 41 73 20 66 6f 6c 6c 6f 77 73 3a 0a   0. As follows:.
2c50: 2a 2a 0a 2a 2a 20 20 20 20 20 61 54 72 65 65 5b  **.**     aTree[
2c60: 5d 20 3d 20 7b 20 58 2c 20 30 20 20 20 30 2c 20  ] = { X, 0   0, 
2c70: 36 20 20 20 20 30 2c 20 33 2c 20 35 2c 20 36 20  6    0, 3, 5, 6 
2c80: 7d 0a 2a 2a 0a 2a 2a 20 49 6e 20 6f 74 68 65 72  }.**.** In other
2c90: 20 77 6f 72 64 73 2c 20 65 61 63 68 20 74 69 6d   words, each tim
2ca0: 65 20 77 65 20 61 64 76 61 6e 63 65 20 74 6f 20  e we advance to 
2cb0: 74 68 65 20 6e 65 78 74 20 73 6f 72 74 65 72 20  the next sorter 
2cc0: 65 6c 65 6d 65 6e 74 2c 20 6c 6f 67 32 28 4e 29  element, log2(N)
2cd0: 0a 2a 2a 20 6b 65 79 20 63 6f 6d 70 61 72 69 73  .** key comparis
2ce0: 6f 6e 20 6f 70 65 72 61 74 69 6f 6e 73 20 61 72  on operations ar
2cf0: 65 20 72 65 71 75 69 72 65 64 2c 20 77 68 65 72  e required, wher
2d00: 65 20 4e 20 69 73 20 74 68 65 20 6e 75 6d 62 65  e N is the numbe
2d10: 72 20 6f 66 20 73 65 67 6d 65 6e 74 73 0a 2a 2a  r of segments.**
2d20: 20 62 65 69 6e 67 20 6d 65 72 67 65 64 20 28 72   being merged (r
2d30: 6f 75 6e 64 65 64 20 75 70 20 74 6f 20 74 68 65  ounded up to the
2d40: 20 6e 65 78 74 20 70 6f 77 65 72 20 6f 66 20 32   next power of 2
2d50: 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 4d 65 72  )..*/.struct Mer
2d60: 67 65 45 6e 67 69 6e 65 20 7b 0a 20 20 69 6e 74  geEngine {.  int
2d70: 20 6e 54 72 65 65 3b 20 20 20 20 20 20 20 20 20   nTree;         
2d80: 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20          /* Used 
2d90: 73 69 7a 65 20 6f 66 20 61 54 72 65 65 2f 61 52  size of aTree/aR
2da0: 65 61 64 72 20 28 70 6f 77 65 72 20 6f 66 20 32  eadr (power of 2
2db0: 29 20 2a 2f 0a 20 20 53 6f 72 74 53 75 62 74 61  ) */.  SortSubta
2dc0: 73 6b 20 2a 70 54 61 73 6b 3b 20 20 20 20 20 20  sk *pTask;      
2dd0: 20 20 2f 2a 20 55 73 65 64 20 62 79 20 74 68 69    /* Used by thi
2de0: 73 20 74 68 72 65 61 64 20 6f 6e 6c 79 20 2a 2f  s thread only */
2df0: 0a 20 20 69 6e 74 20 2a 61 54 72 65 65 3b 20 20  .  int *aTree;  
2e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2e10: 20 43 75 72 72 65 6e 74 20 73 74 61 74 65 20 6f   Current state o
2e20: 66 20 69 6e 63 72 65 6d 65 6e 74 61 6c 20 6d 65  f incremental me
2e30: 72 67 65 20 2a 2f 0a 20 20 50 6d 61 52 65 61 64  rge */.  PmaRead
2e40: 65 72 20 2a 61 52 65 61 64 72 3b 20 20 20 20 20  er *aReadr;     
2e50: 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20      /* Array of 
2e60: 50 6d 61 52 65 61 64 65 72 73 20 74 6f 20 6d 65  PmaReaders to me
2e70: 72 67 65 20 64 61 74 61 20 66 72 6f 6d 20 2a 2f  rge data from */
2e80: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  .};../*.** This 
2e90: 6f 62 6a 65 63 74 20 72 65 70 72 65 73 65 6e 74  object represent
2ea0: 73 20 61 20 73 69 6e 67 6c 65 20 74 68 72 65 61  s a single threa
2eb0: 64 20 6f 66 20 63 6f 6e 74 72 6f 6c 20 69 6e 20  d of control in 
2ec0: 61 20 73 6f 72 74 20 6f 70 65 72 61 74 69 6f 6e  a sort operation
2ed0: 2e 0a 2a 2a 20 45 78 61 63 74 6c 79 20 56 64 62  ..** Exactly Vdb
2ee0: 65 53 6f 72 74 65 72 2e 6e 54 61 73 6b 20 69 6e  eSorter.nTask in
2ef0: 73 74 61 6e 63 65 73 20 6f 66 20 74 68 69 73 20  stances of this 
2f00: 6f 62 6a 65 63 74 20 61 72 65 20 61 6c 6c 6f 63  object are alloc
2f10: 61 74 65 64 0a 2a 2a 20 61 73 20 70 61 72 74 20  ated.** as part 
2f20: 6f 66 20 65 61 63 68 20 56 64 62 65 53 6f 72 74  of each VdbeSort
2f30: 65 72 20 6f 62 6a 65 63 74 2e 20 49 6e 73 74 61  er object. Insta
2f40: 6e 63 65 73 20 61 72 65 20 6e 65 76 65 72 20 61  nces are never a
2f50: 6c 6c 6f 63 61 74 65 64 20 61 6e 79 0a 2a 2a 20  llocated any.** 
2f60: 6f 74 68 65 72 20 77 61 79 2e 20 56 64 62 65 53  other way. VdbeS
2f70: 6f 72 74 65 72 2e 6e 54 61 73 6b 20 69 73 20 73  orter.nTask is s
2f80: 65 74 20 74 6f 20 74 68 65 20 6e 75 6d 62 65 72  et to the number
2f90: 20 6f 66 20 77 6f 72 6b 65 72 20 74 68 72 65 61   of worker threa
2fa0: 64 73 20 61 6c 6c 6f 77 65 64 0a 2a 2a 20 28 73  ds allowed.** (s
2fb0: 65 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  ee SQLITE_CONFIG
2fc0: 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 29  _WORKER_THREADS)
2fd0: 20 70 6c 75 73 20 6f 6e 65 20 28 74 68 65 20 6d   plus one (the m
2fe0: 61 69 6e 20 74 68 72 65 61 64 29 2e 20 20 54 68  ain thread).  Th
2ff0: 75 73 20 66 6f 72 0a 2a 2a 20 73 69 6e 67 6c 65  us for.** single
3000: 2d 74 68 72 65 61 64 65 64 20 6f 70 65 72 61 74  -threaded operat
3010: 69 6f 6e 2c 20 74 68 65 72 65 20 69 73 20 65 78  ion, there is ex
3020: 61 63 74 6c 79 20 6f 6e 65 20 69 6e 73 74 61 6e  actly one instan
3030: 63 65 20 6f 66 20 74 68 69 73 20 6f 62 6a 65 63  ce of this objec
3040: 74 0a 2a 2a 20 61 6e 64 20 66 6f 72 20 6d 75 6c  t.** and for mul
3050: 74 69 2d 74 68 72 65 61 64 65 64 20 6f 70 65 72  ti-threaded oper
3060: 61 74 69 6f 6e 20 74 68 65 72 65 20 61 72 65 20  ation there are 
3070: 74 77 6f 20 6f 72 20 6d 6f 72 65 20 69 6e 73 74  two or more inst
3080: 61 6e 63 65 73 2e 0a 2a 2a 0a 2a 2a 20 45 73 73  ances..**.** Ess
3090: 65 6e 74 69 61 6c 6c 79 2c 20 74 68 69 73 20 73  entially, this s
30a0: 74 72 75 63 74 75 72 65 20 63 6f 6e 74 61 69 6e  tructure contain
30b0: 73 20 61 6c 6c 20 74 68 6f 73 65 20 66 69 65 6c  s all those fiel
30c0: 64 73 20 6f 66 20 74 68 65 20 56 64 62 65 53 6f  ds of the VdbeSo
30d0: 72 74 65 72 0a 2a 2a 20 73 74 72 75 63 74 75 72  rter.** structur
30e0: 65 20 66 6f 72 20 77 68 69 63 68 20 65 61 63 68  e for which each
30f0: 20 74 68 72 65 61 64 20 72 65 71 75 69 72 65 73   thread requires
3100: 20 61 20 73 65 70 61 72 61 74 65 20 69 6e 73 74   a separate inst
3110: 61 6e 63 65 2e 20 46 6f 72 20 65 78 61 6d 70 6c  ance. For exampl
3120: 65 2c 0a 2a 2a 20 65 61 63 68 20 74 68 72 65 61  e,.** each threa
3130: 64 20 72 65 71 75 72 69 65 73 20 69 74 73 20 6f  d requries its o
3140: 77 6e 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72  wn UnpackedRecor
3150: 64 20 6f 62 6a 65 63 74 20 74 6f 20 75 6e 70 61  d object to unpa
3160: 63 6b 20 72 65 63 6f 72 64 73 20 69 6e 0a 2a 2a  ck records in.**
3170: 20 61 73 20 70 61 72 74 20 6f 66 20 63 6f 6d 70   as part of comp
3180: 61 72 69 73 6f 6e 20 6f 70 65 72 61 74 69 6f 6e  arison operation
3190: 73 2e 0a 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65 20  s..**.** Before 
31a0: 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  a background thr
31b0: 65 61 64 20 69 73 20 6c 61 75 6e 63 68 65 64 2c  ead is launched,
31c0: 20 76 61 72 69 61 62 6c 65 20 62 44 6f 6e 65 20   variable bDone 
31d0: 69 73 20 73 65 74 20 74 6f 20 30 2e 20 54 68 65  is set to 0. The
31e0: 6e 2c 20 0a 2a 2a 20 72 69 67 68 74 20 62 65 66  n, .** right bef
31f0: 6f 72 65 20 69 74 20 65 78 69 74 73 2c 20 74 68  ore it exits, th
3200: 65 20 74 68 72 65 61 64 20 69 74 73 65 6c 66 20  e thread itself 
3210: 73 65 74 73 20 62 44 6f 6e 65 20 74 6f 20 31 2e  sets bDone to 1.
3220: 20 54 68 69 73 20 69 73 20 75 73 65 64 20 66 6f   This is used fo
3230: 72 20 0a 2a 2a 20 74 77 6f 20 70 75 72 70 6f 73  r .** two purpos
3240: 65 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 57  es:.**.**   1. W
3250: 68 65 6e 20 66 6c 75 73 68 69 6e 67 20 74 68 65  hen flushing the
3260: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65 6d   contents of mem
3270: 6f 72 79 20 74 6f 20 61 20 6c 65 76 65 6c 2d 30  ory to a level-0
3280: 20 50 4d 41 20 6f 6e 20 64 69 73 6b 2c 20 74 6f   PMA on disk, to
3290: 0a 2a 2a 20 20 20 20 20 20 61 74 74 65 6d 70 74  .**      attempt
32a0: 20 74 6f 20 73 65 6c 65 63 74 20 61 20 53 6f 72   to select a Sor
32b0: 74 53 75 62 74 61 73 6b 20 66 6f 72 20 77 68 69  tSubtask for whi
32c0: 63 68 20 74 68 65 72 65 20 69 73 20 6e 6f 74 20  ch there is not 
32d0: 61 6c 72 65 61 64 79 20 61 6e 0a 2a 2a 20 20 20  already an.**   
32e0: 20 20 20 61 63 74 69 76 65 20 62 61 63 6b 67 72     active backgr
32f0: 6f 75 6e 64 20 74 68 72 65 61 64 20 28 73 69 6e  ound thread (sin
3300: 63 65 20 64 6f 69 6e 67 20 73 6f 20 63 61 75 73  ce doing so caus
3310: 65 73 20 74 68 65 20 6d 61 69 6e 20 74 68 72 65  es the main thre
3320: 61 64 0a 2a 2a 20 20 20 20 20 20 74 6f 20 62 6c  ad.**      to bl
3330: 6f 63 6b 20 75 6e 74 69 6c 20 69 74 20 66 69 6e  ock until it fin
3340: 69 73 68 65 73 29 2e 0a 2a 2a 0a 2a 2a 20 20 20  ishes)..**.**   
3350: 32 2e 20 49 66 20 53 51 4c 49 54 45 5f 44 45 42  2. If SQLITE_DEB
3360: 55 47 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44  UG_SORTER_THREAD
3370: 53 20 69 73 20 64 65 66 69 6e 65 64 2c 20 74 6f  S is defined, to
3380: 20 64 65 74 65 72 6d 69 6e 65 20 69 66 20 61 20   determine if a 
3390: 63 61 6c 6c 0a 2a 2a 20 20 20 20 20 20 74 6f 20  call.**      to 
33a0: 73 71 6c 69 74 65 33 54 68 72 65 61 64 4a 6f 69  sqlite3ThreadJoi
33b0: 6e 28 29 20 69 73 20 6c 69 6b 65 6c 79 20 74 6f  n() is likely to
33c0: 20 62 6c 6f 63 6b 2e 20 43 61 73 65 73 20 74 68   block. Cases th
33d0: 61 74 20 61 72 65 20 6c 69 6b 65 6c 79 20 74 6f  at are likely to
33e0: 0a 2a 2a 20 20 20 20 20 20 62 6c 6f 63 6b 20 70  .**      block p
33f0: 72 6f 76 6f 6b 65 20 64 65 62 75 67 67 69 6e 67  rovoke debugging
3400: 20 6f 75 74 70 75 74 2e 0a 2a 2a 0a 2a 2a 20 49   output..**.** I
3410: 6e 20 62 6f 74 68 20 63 61 73 65 73 2c 20 74 68  n both cases, th
3420: 65 20 65 66 66 65 63 74 73 20 6f 66 20 74 68 65  e effects of the
3430: 20 6d 61 69 6e 20 74 68 72 65 61 64 20 73 65 65   main thread see
3440: 69 6e 67 20 28 62 44 6f 6e 65 3d 3d 30 29 20 65  ing (bDone==0) e
3450: 76 65 6e 0a 2a 2a 20 61 66 74 65 72 20 74 68 65  ven.** after the
3460: 20 74 68 72 65 61 64 20 68 61 73 20 66 69 6e 69   thread has fini
3470: 73 68 65 64 20 61 72 65 20 6e 6f 74 20 64 69 72  shed are not dir
3480: 65 2e 20 53 6f 20 77 65 20 64 6f 6e 27 74 20 77  e. So we don't w
3490: 6f 72 72 79 20 61 62 6f 75 74 0a 2a 2a 20 6d 65  orry about.** me
34a0: 6d 6f 72 79 20 62 61 72 72 69 65 72 73 20 61 6e  mory barriers an
34b0: 64 20 73 75 63 68 20 68 65 72 65 2e 0a 2a 2f 0a  d such here..*/.
34c0: 73 74 72 75 63 74 20 53 6f 72 74 53 75 62 74 61  struct SortSubta
34d0: 73 6b 20 7b 0a 20 20 53 51 4c 69 74 65 54 68 72  sk {.  SQLiteThr
34e0: 65 61 64 20 2a 70 54 68 72 65 61 64 3b 20 20 20  ead *pThread;   
34f0: 20 20 20 20 20 20 20 2f 2a 20 42 61 63 6b 67 72         /* Backgr
3500: 6f 75 6e 64 20 74 68 72 65 61 64 2c 20 69 66 20  ound thread, if 
3510: 61 6e 79 20 2a 2f 0a 20 20 69 6e 74 20 62 44 6f  any */.  int bDo
3520: 6e 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ne;             
3530: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74 20           /* Set 
3540: 69 66 20 74 68 72 65 61 64 20 69 73 20 66 69 6e  if thread is fin
3550: 69 73 68 65 64 20 62 75 74 20 6e 6f 74 20 6a 6f  ished but not jo
3560: 69 6e 65 64 20 2a 2f 0a 20 20 56 64 62 65 53 6f  ined */.  VdbeSo
3570: 72 74 65 72 20 2a 70 53 6f 72 74 65 72 3b 20 20  rter *pSorter;  
3580: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72            /* Sor
3590: 74 65 72 20 74 68 61 74 20 6f 77 6e 73 20 74 68  ter that owns th
35a0: 69 73 20 73 75 62 2d 74 61 73 6b 20 2a 2f 0a 20  is sub-task */. 
35b0: 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20   UnpackedRecord 
35c0: 2a 70 55 6e 70 61 63 6b 65 64 3b 20 20 20 20 20  *pUnpacked;     
35d0: 20 2f 2a 20 53 70 61 63 65 20 74 6f 20 75 6e 70   /* Space to unp
35e0: 61 63 6b 20 61 20 72 65 63 6f 72 64 20 2a 2f 0a  ack a record */.
35f0: 20 20 53 6f 72 74 65 72 4c 69 73 74 20 6c 69 73    SorterList lis
3600: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
3610: 20 20 2f 2a 20 4c 69 73 74 20 66 6f 72 20 74 68    /* List for th
3620: 72 65 61 64 20 74 6f 20 77 72 69 74 65 20 74 6f  read to write to
3630: 20 61 20 50 4d 41 20 2a 2f 0a 20 20 69 6e 74 20   a PMA */.  int 
3640: 6e 50 4d 41 3b 20 20 20 20 20 20 20 20 20 20 20  nPMA;           
3650: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
3660: 75 6d 62 65 72 20 6f 66 20 50 4d 41 73 20 63 75  umber of PMAs cu
3670: 72 72 65 6e 74 6c 79 20 69 6e 20 66 69 6c 65 20  rrently in file 
3680: 2a 2f 0a 20 20 53 6f 72 74 65 72 46 69 6c 65 20  */.  SorterFile 
3690: 66 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20  file;           
36a0: 20 20 20 20 20 2f 2a 20 54 65 6d 70 20 66 69 6c       /* Temp fil
36b0: 65 20 66 6f 72 20 6c 65 76 65 6c 2d 30 20 50 4d  e for level-0 PM
36c0: 41 73 20 2a 2f 0a 20 20 53 6f 72 74 65 72 46 69  As */.  SorterFi
36d0: 6c 65 20 66 69 6c 65 32 3b 20 20 20 20 20 20 20  le file2;       
36e0: 20 20 20 20 20 20 20 20 2f 2a 20 53 70 61 63 65          /* Space
36f0: 20 66 6f 72 20 6f 74 68 65 72 20 50 4d 41 73 20   for other PMAs 
3700: 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 4d 61 69  */.};../*.** Mai
3710: 6e 20 73 6f 72 74 65 72 20 73 74 72 75 63 74 75  n sorter structu
3720: 72 65 2e 20 41 20 73 69 6e 67 6c 65 20 69 6e 73  re. A single ins
3730: 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 69 73  tance of this is
3740: 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 65   allocated for e
3750: 61 63 68 20 0a 2a 2a 20 73 6f 72 74 65 72 20 63  ach .** sorter c
3760: 75 72 73 6f 72 20 63 72 65 61 74 65 64 20 62 79  ursor created by
3770: 20 74 68 65 20 56 44 42 45 2e 0a 2a 2a 0a 2a 2a   the VDBE..**.**
3780: 20 6d 78 4b 65 79 73 69 7a 65 3a 0a 2a 2a 20 20   mxKeysize:.**  
3790: 20 41 73 20 72 65 63 6f 72 64 73 20 61 72 65 20   As records are 
37a0: 61 64 64 65 64 20 74 6f 20 74 68 65 20 73 6f 72  added to the sor
37b0: 74 65 72 20 62 79 20 63 61 6c 6c 73 20 74 6f 20  ter by calls to 
37c0: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
37d0: 72 57 72 69 74 65 28 29 2c 0a 2a 2a 20 20 20 74  rWrite(),.**   t
37e0: 68 69 73 20 76 61 72 69 61 62 6c 65 20 69 73 20  his variable is 
37f0: 75 70 64 61 74 65 64 20 73 6f 20 61 73 20 74 6f  updated so as to
3800: 20 62 65 20 73 65 74 20 74 6f 20 74 68 65 20 73   be set to the s
3810: 69 7a 65 20 6f 6e 20 64 69 73 6b 20 6f 66 20 74  ize on disk of t
3820: 68 65 0a 2a 2a 20 20 20 6c 61 72 67 65 73 74 20  he.**   largest 
3830: 72 65 63 6f 72 64 20 69 6e 20 74 68 65 20 73 6f  record in the so
3840: 72 74 65 72 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  rter..*/.struct 
3850: 56 64 62 65 53 6f 72 74 65 72 20 7b 0a 20 20 69  VdbeSorter {.  i
3860: 6e 74 20 6d 6e 50 6d 61 53 69 7a 65 3b 20 20 20  nt mnPmaSize;   
3870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3880: 2a 20 4d 69 6e 69 6d 75 6d 20 50 4d 41 20 73 69  * Minimum PMA si
3890: 7a 65 2c 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  ze, in bytes */.
38a0: 20 20 69 6e 74 20 6d 78 50 6d 61 53 69 7a 65 3b    int mxPmaSize;
38b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38c0: 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 50 4d 41    /* Maximum PMA
38d0: 20 73 69 7a 65 2c 20 69 6e 20 62 79 74 65 73 2e   size, in bytes.
38e0: 20 20 30 3d 3d 6e 6f 20 6c 69 6d 69 74 20 2a 2f    0==no limit */
38f0: 0a 20 20 69 6e 74 20 6d 78 4b 65 79 73 69 7a 65  .  int mxKeysize
3900: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
3910: 20 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 73 65     /* Largest se
3920: 72 69 61 6c 69 7a 65 64 20 6b 65 79 20 73 65 65  rialized key see
3930: 6e 20 73 6f 20 66 61 72 20 2a 2f 0a 20 20 69 6e  n so far */.  in
3940: 74 20 70 67 73 7a 3b 20 20 20 20 20 20 20 20 20  t pgsz;         
3950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3960: 20 4d 61 69 6e 20 64 61 74 61 62 61 73 65 20 70   Main database p
3970: 61 67 65 20 73 69 7a 65 20 2a 2f 0a 20 20 50 6d  age size */.  Pm
3980: 61 52 65 61 64 65 72 20 2a 70 52 65 61 64 65 72  aReader *pReader
3990: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
39a0: 20 52 65 61 64 72 20 64 61 74 61 20 66 72 6f 6d   Readr data from
39b0: 20 68 65 72 65 20 61 66 74 65 72 20 52 65 77 69   here after Rewi
39c0: 6e 64 28 29 20 2a 2f 0a 20 20 4d 65 72 67 65 45  nd() */.  MergeE
39d0: 6e 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 3b 20  ngine *pMerger; 
39e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 72 20            /* Or 
39f0: 68 65 72 65 2c 20 69 66 20 62 55 73 65 54 68 72  here, if bUseThr
3a00: 65 61 64 73 3d 3d 30 20 2a 2f 0a 20 20 73 71 6c  eads==0 */.  sql
3a10: 69 74 65 33 20 2a 64 62 3b 20 20 20 20 20 20 20  ite3 *db;       
3a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3a30: 44 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74  Database connect
3a40: 69 6f 6e 20 2a 2f 0a 20 20 4b 65 79 49 6e 66 6f  ion */.  KeyInfo
3a50: 20 2a 70 4b 65 79 49 6e 66 6f 3b 20 20 20 20 20   *pKeyInfo;     
3a60: 20 20 20 20 20 20 20 20 20 2f 2a 20 48 6f 77 20           /* How 
3a70: 74 6f 20 63 6f 6d 70 61 72 65 20 72 65 63 6f 72  to compare recor
3a80: 64 73 20 2a 2f 0a 20 20 55 6e 70 61 63 6b 65 64  ds */.  Unpacked
3a90: 52 65 63 6f 72 64 20 2a 70 55 6e 70 61 63 6b 65  Record *pUnpacke
3aa0: 64 3b 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20  d;      /* Used 
3ab0: 62 79 20 56 64 62 65 53 6f 72 74 65 72 43 6f 6d  by VdbeSorterCom
3ac0: 70 61 72 65 28 29 20 2a 2f 0a 20 20 53 6f 72 74  pare() */.  Sort
3ad0: 65 72 4c 69 73 74 20 6c 69 73 74 3b 20 20 20 20  erList list;    
3ae0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
3af0: 69 73 74 20 6f 66 20 69 6e 2d 6d 65 6d 6f 72 79  ist of in-memory
3b00: 20 72 65 63 6f 72 64 73 20 2a 2f 0a 20 20 69 6e   records */.  in
3b10: 74 20 69 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20  t iMemory;      
3b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3b30: 20 4f 66 66 73 65 74 20 6f 66 20 66 72 65 65 20   Offset of free 
3b40: 73 70 61 63 65 20 69 6e 20 6c 69 73 74 2e 61 4d  space in list.aM
3b50: 65 6d 6f 72 79 20 2a 2f 0a 20 20 69 6e 74 20 6e  emory */.  int n
3b60: 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20 20 20 20  Memory;         
3b70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
3b80: 7a 65 20 6f 66 20 6c 69 73 74 2e 61 4d 65 6d 6f  ze of list.aMemo
3b90: 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 6e  ry allocation in
3ba0: 20 62 79 74 65 73 20 2a 2f 0a 20 20 75 38 20 62   bytes */.  u8 b
3bb0: 55 73 65 50 4d 41 3b 20 20 20 20 20 20 20 20 20  UsePMA;         
3bc0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
3bd0: 72 75 65 20 69 66 20 6f 6e 65 20 6f 72 20 6d 6f  rue if one or mo
3be0: 72 65 20 50 4d 41 73 20 63 72 65 61 74 65 64 20  re PMAs created 
3bf0: 2a 2f 0a 20 20 75 38 20 62 55 73 65 54 68 72 65  */.  u8 bUseThre
3c00: 61 64 73 3b 20 20 20 20 20 20 20 20 20 20 20 20  ads;            
3c10: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20       /* True to 
3c20: 75 73 65 20 62 61 63 6b 67 72 6f 75 6e 64 20 74  use background t
3c30: 68 72 65 61 64 73 20 2a 2f 0a 20 20 75 38 20 69  hreads */.  u8 i
3c40: 50 72 65 76 3b 20 20 20 20 20 20 20 20 20 20 20  Prev;           
3c50: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
3c60: 72 65 76 69 6f 75 73 20 74 68 72 65 61 64 20 75  revious thread u
3c70: 73 65 64 20 74 6f 20 66 6c 75 73 68 20 50 4d 41  sed to flush PMA
3c80: 20 2a 2f 0a 20 20 75 38 20 6e 54 61 73 6b 3b 20   */.  u8 nTask; 
3c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3ca0: 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
3cb0: 20 61 54 61 73 6b 5b 5d 20 61 72 72 61 79 20 2a   aTask[] array *
3cc0: 2f 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20  /.  SortSubtask 
3cd0: 61 54 61 73 6b 5b 31 5d 3b 20 20 20 20 20 20 20  aTask[1];       
3ce0: 20 20 20 20 2f 2a 20 4f 6e 65 20 6f 72 20 6d 6f      /* One or mo
3cf0: 72 65 20 73 75 62 74 61 73 6b 73 20 2a 2f 0a 7d  re subtasks */.}
3d00: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73 74  ;../*.** An inst
3d10: 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c  ance of the foll
3d20: 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20 69 73 20  owing object is 
3d30: 75 73 65 64 20 74 6f 20 72 65 61 64 20 72 65 63  used to read rec
3d40: 6f 72 64 73 20 6f 75 74 20 6f 66 20 61 0a 2a 2a  ords out of a.**
3d50: 20 50 4d 41 2c 20 69 6e 20 73 6f 72 74 65 64 20   PMA, in sorted 
3d60: 6f 72 64 65 72 2e 20 20 54 68 65 20 6e 65 78 74  order.  The next
3d70: 20 6b 65 79 20 74 6f 20 62 65 20 72 65 61 64 20   key to be read 
3d80: 69 73 20 63 61 63 68 65 64 20 69 6e 20 6e 4b 65  is cached in nKe
3d90: 79 2f 61 4b 65 79 2e 0a 2a 2a 20 61 4b 65 79 20  y/aKey..** aKey 
3da0: 6d 69 67 68 74 20 70 6f 69 6e 74 20 69 6e 74 6f  might point into
3db0: 20 61 4d 61 70 20 6f 72 20 69 6e 74 6f 20 61 42   aMap or into aB
3dc0: 75 66 66 65 72 2e 20 20 49 66 20 6e 65 69 74 68  uffer.  If neith
3dd0: 65 72 20 6f 66 20 74 68 6f 73 65 20 6c 6f 63 61  er of those loca
3de0: 74 69 6f 6e 73 0a 2a 2a 20 63 6f 6e 74 61 69 6e  tions.** contain
3df0: 20 61 20 63 6f 6e 74 69 67 75 6f 75 73 20 72 65   a contiguous re
3e00: 70 72 65 73 65 6e 74 61 74 69 6f 6e 20 6f 66 20  presentation of 
3e10: 74 68 65 20 6b 65 79 2c 20 74 68 65 6e 20 61 41  the key, then aA
3e20: 6c 6c 6f 63 20 69 73 20 61 6c 6c 6f 63 61 74 65  lloc is allocate
3e30: 64 0a 2a 2a 20 61 6e 64 20 74 68 65 20 6b 65 79  d.** and the key
3e40: 20 69 73 20 63 6f 70 69 65 64 20 69 6e 74 6f 20   is copied into 
3e50: 61 41 6c 6c 6f 63 20 61 6e 64 20 61 4b 65 79 20  aAlloc and aKey 
3e60: 69 73 20 6d 61 64 65 20 74 6f 20 70 6f 69 74 6e  is made to poitn
3e70: 20 74 6f 20 61 41 6c 6c 6f 63 2e 0a 2a 2a 0a 2a   to aAlloc..**.*
3e80: 2a 20 70 46 64 3d 3d 30 20 61 74 20 45 4f 46 2e  * pFd==0 at EOF.
3e90: 0a 2a 2f 0a 73 74 72 75 63 74 20 50 6d 61 52 65  .*/.struct PmaRe
3ea0: 61 64 65 72 20 7b 0a 20 20 69 36 34 20 69 52 65  ader {.  i64 iRe
3eb0: 61 64 4f 66 66 3b 20 20 20 20 20 20 20 20 20 20  adOff;          
3ec0: 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20       /* Current 
3ed0: 72 65 61 64 20 6f 66 66 73 65 74 20 2a 2f 0a 20  read offset */. 
3ee0: 20 69 36 34 20 69 45 6f 66 3b 20 20 20 20 20 20   i64 iEof;      
3ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3f00: 31 20 62 79 74 65 20 70 61 73 74 20 45 4f 46 20  1 byte past EOF 
3f10: 66 6f 72 20 74 68 69 73 20 50 6d 61 52 65 61 64  for this PmaRead
3f20: 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 6c 6c  er */.  int nAll
3f30: 6f 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  oc;             
3f40: 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20      /* Bytes of 
3f50: 73 70 61 63 65 20 61 74 20 61 41 6c 6c 6f 63 20  space at aAlloc 
3f60: 2a 2f 0a 20 20 69 6e 74 20 6e 4b 65 79 3b 20 20  */.  int nKey;  
3f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3f80: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79   /* Number of by
3f90: 74 65 73 20 69 6e 20 6b 65 79 20 2a 2f 0a 20 20  tes in key */.  
3fa0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
3fb0: 64 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46  d;          /* F
3fc0: 69 6c 65 20 68 61 6e 64 6c 65 20 77 65 20 61 72  ile handle we ar
3fd0: 65 20 72 65 61 64 69 6e 67 20 66 72 6f 6d 20 2a  e reading from *
3fe0: 2f 0a 20 20 75 38 20 2a 61 41 6c 6c 6f 63 3b 20  /.  u8 *aAlloc; 
3ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4000: 2f 2a 20 53 70 61 63 65 20 66 6f 72 20 61 4b 65  /* Space for aKe
4010: 79 20 69 66 20 61 42 75 66 66 65 72 20 61 6e 64  y if aBuffer and
4020: 20 70 4d 61 70 20 77 6f 6e 74 20 77 6f 72 6b 20   pMap wont work 
4030: 2a 2f 0a 20 20 75 38 20 2a 61 4b 65 79 3b 20 20  */.  u8 *aKey;  
4040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4050: 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 63   /* Pointer to c
4060: 75 72 72 65 6e 74 20 6b 65 79 20 2a 2f 0a 20 20  urrent key */.  
4070: 75 38 20 2a 61 42 75 66 66 65 72 3b 20 20 20 20  u8 *aBuffer;    
4080: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
4090: 75 72 72 65 6e 74 20 72 65 61 64 20 62 75 66 66  urrent read buff
40a0: 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66  er */.  int nBuf
40b0: 66 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20  fer;            
40c0: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 72      /* Size of r
40d0: 65 61 64 20 62 75 66 66 65 72 20 69 6e 20 62 79  ead buffer in by
40e0: 74 65 73 20 2a 2f 0a 20 20 75 38 20 2a 61 4d 61  tes */.  u8 *aMa
40f0: 70 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p;              
4100: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
4110: 74 6f 20 6d 61 70 70 69 6e 67 20 6f 66 20 65 6e  to mapping of en
4120: 74 69 72 65 20 66 69 6c 65 20 2a 2f 0a 20 20 49  tire file */.  I
4130: 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63 72  ncrMerger *pIncr
4140: 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e  ;          /* In
4150: 63 72 65 6d 65 6e 74 61 6c 20 6d 65 72 67 65 72  cremental merger
4160: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 4e 6f   */.};../*.** No
4170: 72 6d 61 6c 6c 79 2c 20 61 20 50 6d 61 52 65 61  rmally, a PmaRea
4180: 64 65 72 20 6f 62 6a 65 63 74 20 69 74 65 72 61  der object itera
4190: 74 65 73 20 74 68 72 6f 75 67 68 20 61 6e 20 65  tes through an e
41a0: 78 69 73 74 69 6e 67 20 50 4d 41 20 73 74 6f 72  xisting PMA stor
41b0: 65 64 20 0a 2a 2a 20 77 69 74 68 69 6e 20 61 20  ed .** within a 
41c0: 74 65 6d 70 20 66 69 6c 65 2e 20 48 6f 77 65 76  temp file. Howev
41d0: 65 72 2c 20 69 66 20 74 68 65 20 50 6d 61 52 65  er, if the PmaRe
41e0: 61 64 65 72 2e 70 49 6e 63 72 20 76 61 72 69 61  ader.pIncr varia
41f0: 62 6c 65 20 70 6f 69 6e 74 73 20 74 6f 0a 2a 2a  ble points to.**
4200: 20 61 6e 20 6f 62 6a 65 63 74 20 6f 66 20 74 68   an object of th
4210: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 79 70 65  e following type
4220: 2c 20 69 74 20 6d 61 79 20 62 65 20 75 73 65 64  , it may be used
4230: 20 74 6f 20 69 74 65 72 61 74 65 2f 6d 65 72 67   to iterate/merg
4240: 65 20 74 68 72 6f 75 67 68 0a 2a 2a 20 6d 75 6c  e through.** mul
4250: 74 69 70 6c 65 20 50 4d 41 73 20 73 69 6d 75 6c  tiple PMAs simul
4260: 74 61 6e 65 6f 75 73 6c 79 2e 0a 2a 2a 0a 2a 2a  taneously..**.**
4270: 20 54 68 65 72 65 20 61 72 65 20 74 77 6f 20 74   There are two t
4280: 79 70 65 73 20 6f 66 20 49 6e 63 72 4d 65 72 67  ypes of IncrMerg
4290: 65 72 20 6f 62 6a 65 63 74 20 2d 20 73 69 6e 67  er object - sing
42a0: 6c 65 20 28 62 55 73 65 54 68 72 65 61 64 3d 3d  le (bUseThread==
42b0: 30 29 20 61 6e 64 20 0a 2a 2a 20 6d 75 6c 74 69  0) and .** multi
42c0: 2d 74 68 72 65 61 64 65 64 20 28 62 55 73 65 54  -threaded (bUseT
42d0: 68 72 65 61 64 3d 3d 31 29 2e 20 0a 2a 2a 0a 2a  hread==1). .**.*
42e0: 2a 20 41 20 6d 75 6c 74 69 2d 74 68 72 65 61 64  * A multi-thread
42f0: 65 64 20 49 6e 63 72 4d 65 72 67 65 72 20 6f 62  ed IncrMerger ob
4300: 6a 65 63 74 20 75 73 65 73 20 74 77 6f 20 74 65  ject uses two te
4310: 6d 70 6f 72 61 72 79 20 66 69 6c 65 73 20 2d 20  mporary files - 
4320: 61 46 69 6c 65 5b 30 5d 20 0a 2a 2a 20 61 6e 64  aFile[0] .** and
4330: 20 61 46 69 6c 65 5b 31 5d 2e 20 4e 65 69 74 68   aFile[1]. Neith
4340: 65 72 20 66 69 6c 65 20 69 73 20 61 6c 6c 6f 77  er file is allow
4350: 65 64 20 74 6f 20 67 72 6f 77 20 74 6f 20 6d 6f  ed to grow to mo
4360: 72 65 20 74 68 61 6e 20 6d 78 53 7a 20 62 79 74  re than mxSz byt
4370: 65 73 20 69 6e 20 0a 2a 2a 20 73 69 7a 65 2e 20  es in .** size. 
4380: 57 68 65 6e 20 74 68 65 20 49 6e 63 72 4d 65 72  When the IncrMer
4390: 67 65 72 20 69 73 20 69 6e 69 74 69 61 6c 69 7a  ger is initializ
43a0: 65 64 2c 20 69 74 20 72 65 61 64 73 20 65 6e 6f  ed, it reads eno
43b0: 75 67 68 20 64 61 74 61 20 66 72 6f 6d 20 0a 2a  ugh data from .*
43c0: 2a 20 70 4d 65 72 67 65 72 20 74 6f 20 70 6f 70  * pMerger to pop
43d0: 75 6c 61 74 65 20 61 46 69 6c 65 5b 30 5d 2e 20  ulate aFile[0]. 
43e0: 49 74 20 74 68 65 6e 20 73 65 74 73 20 76 61 72  It then sets var
43f0: 69 61 62 6c 65 73 20 77 69 74 68 69 6e 20 74 68  iables within th
4400: 65 20 0a 2a 2a 20 63 6f 72 72 65 73 70 6f 6e 64  e .** correspond
4410: 69 6e 67 20 50 6d 61 52 65 61 64 65 72 20 6f 62  ing PmaReader ob
4420: 6a 65 63 74 20 74 6f 20 72 65 61 64 20 66 72 6f  ject to read fro
4430: 6d 20 74 68 61 74 20 66 69 6c 65 20 61 6e 64 20  m that file and 
4440: 6b 69 63 6b 73 20 6f 66 66 20 0a 2a 2a 20 61 20  kicks off .** a 
4450: 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61  background threa
4460: 64 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 61 46  d to populate aF
4470: 69 6c 65 5b 31 5d 20 77 69 74 68 20 74 68 65 20  ile[1] with the 
4480: 6e 65 78 74 20 6d 78 53 7a 20 62 79 74 65 73 20  next mxSz bytes 
4490: 6f 66 20 0a 2a 2a 20 73 6f 72 74 65 64 20 72 65  of .** sorted re
44a0: 63 6f 72 64 20 64 61 74 61 20 66 72 6f 6d 20 70  cord data from p
44b0: 4d 65 72 67 65 72 2e 20 0a 2a 2a 0a 2a 2a 20 57  Merger. .**.** W
44c0: 68 65 6e 20 74 68 65 20 50 6d 61 52 65 61 64 65  hen the PmaReade
44d0: 72 20 72 65 61 63 68 65 73 20 74 68 65 20 65 6e  r reaches the en
44e0: 64 20 6f 66 20 61 46 69 6c 65 5b 30 5d 2c 20 69  d of aFile[0], i
44f0: 74 20 62 6c 6f 63 6b 73 20 75 6e 74 69 6c 20 74  t blocks until t
4500: 68 65 0a 2a 2a 20 62 61 63 6b 67 72 6f 75 6e 64  he.** background
4510: 20 74 68 72 65 61 64 20 68 61 73 20 66 69 6e 69   thread has fini
4520: 73 68 65 64 20 70 6f 70 75 6c 61 74 69 6e 67 20  shed populating 
4530: 61 46 69 6c 65 5b 31 5d 2e 20 49 74 20 74 68 65  aFile[1]. It the
4540: 6e 20 65 78 63 68 61 6e 67 65 73 0a 2a 2a 20 74  n exchanges.** t
4550: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
4560: 68 65 20 61 46 69 6c 65 5b 30 5d 20 61 6e 64 20  he aFile[0] and 
4570: 61 46 69 6c 65 5b 31 5d 20 76 61 72 69 61 62 6c  aFile[1] variabl
4580: 65 73 20 77 69 74 68 69 6e 20 74 68 69 73 20 73  es within this s
4590: 74 72 75 63 74 75 72 65 2c 0a 2a 2a 20 73 65 74  tructure,.** set
45a0: 73 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 20  s the PmaReader 
45b0: 66 69 65 6c 64 73 20 74 6f 20 72 65 61 64 20 66  fields to read f
45c0: 72 6f 6d 20 74 68 65 20 6e 65 77 20 61 46 69 6c  rom the new aFil
45d0: 65 5b 30 5d 20 61 6e 64 20 6b 69 63 6b 73 20 6f  e[0] and kicks o
45e0: 66 66 0a 2a 2a 20 61 6e 6f 74 68 65 72 20 62 61  ff.** another ba
45f0: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
4600: 74 6f 20 70 6f 70 75 6c 61 74 65 20 74 68 65 20  to populate the 
4610: 6e 65 77 20 61 46 69 6c 65 5b 31 5d 2e 20 41 6e  new aFile[1]. An
4620: 64 20 73 6f 20 6f 6e 2c 20 75 6e 74 69 6c 0a 2a  d so on, until.*
4630: 2a 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  * the contents o
4640: 66 20 70 4d 65 72 67 65 72 20 61 72 65 20 65 78  f pMerger are ex
4650: 68 61 75 73 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 41  hausted..**.** A
4660: 20 73 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64   single-threaded
4670: 20 49 6e 63 72 4d 65 72 67 65 72 20 64 6f 65 73   IncrMerger does
4680: 20 6e 6f 74 20 6f 70 65 6e 20 61 6e 79 20 74 65   not open any te
4690: 6d 70 6f 72 61 72 79 20 66 69 6c 65 73 20 6f 66  mporary files of
46a0: 20 69 74 73 0a 2a 2a 20 6f 77 6e 2e 20 49 6e 73   its.** own. Ins
46b0: 74 65 61 64 2c 20 69 74 20 68 61 73 20 65 78 63  tead, it has exc
46c0: 6c 75 73 69 76 65 20 61 63 63 65 73 73 20 74 6f  lusive access to
46d0: 20 6d 78 53 7a 20 62 79 74 65 73 20 6f 66 20 73   mxSz bytes of s
46e0: 70 61 63 65 20 62 65 67 69 6e 6e 69 6e 67 0a 2a  pace beginning.*
46f0: 2a 20 61 74 20 6f 66 66 73 65 74 20 69 53 74 61  * at offset iSta
4700: 72 74 4f 66 66 20 6f 66 20 66 69 6c 65 20 70 54  rtOff of file pT
4710: 61 73 6b 2d 3e 66 69 6c 65 32 2e 20 41 6e 64 20  ask->file2. And 
4720: 69 6e 73 74 65 61 64 20 6f 66 20 75 73 69 6e 67  instead of using
4730: 20 61 20 0a 2a 2a 20 62 61 63 6b 67 72 6f 75 6e   a .** backgroun
4740: 64 20 74 68 72 65 61 64 20 74 6f 20 70 72 65 70  d thread to prep
4750: 61 72 65 20 64 61 74 61 20 66 6f 72 20 74 68 65  are data for the
4760: 20 50 6d 61 52 65 61 64 65 72 2c 20 77 69 74 68   PmaReader, with
4770: 20 61 20 73 69 6e 67 6c 65 0a 2a 2a 20 74 68 72   a single.** thr
4780: 65 61 64 65 64 20 49 6e 63 72 4d 65 72 67 65 72  eaded IncrMerger
4790: 20 74 68 65 20 61 6c 6c 6f 63 61 74 65 20 70 61   the allocate pa
47a0: 72 74 20 6f 66 20 70 54 61 73 6b 2d 3e 66 69 6c  rt of pTask->fil
47b0: 65 32 20 69 73 20 22 72 65 66 69 6c 6c 65 64 22  e2 is "refilled"
47c0: 20 77 69 74 68 0a 2a 2a 20 6b 65 79 73 20 66 72   with.** keys fr
47d0: 6f 6d 20 70 4d 65 72 67 65 72 20 62 79 20 74 68  om pMerger by th
47e0: 65 20 63 61 6c 6c 69 6e 67 20 74 68 72 65 61 64  e calling thread
47f0: 20 77 68 65 6e 65 76 65 72 20 74 68 65 20 50 6d   whenever the Pm
4800: 61 52 65 61 64 65 72 20 72 75 6e 73 20 6f 75 74  aReader runs out
4810: 0a 2a 2a 20 6f 66 20 64 61 74 61 2e 0a 2a 2f 0a  .** of data..*/.
4820: 73 74 72 75 63 74 20 49 6e 63 72 4d 65 72 67 65  struct IncrMerge
4830: 72 20 7b 0a 20 20 53 6f 72 74 53 75 62 74 61 73  r {.  SortSubtas
4840: 6b 20 2a 70 54 61 73 6b 3b 20 20 20 20 20 20 20  k *pTask;       
4850: 20 20 20 20 20 20 2f 2a 20 54 61 73 6b 20 74 68        /* Task th
4860: 61 74 20 6f 77 6e 73 20 74 68 69 73 20 6d 65 72  at owns this mer
4870: 67 65 72 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e  ger */.  MergeEn
4880: 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 3b 20 20  gine *pMerger;  
4890: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 65 72 67           /* Merg
48a0: 65 20 65 6e 67 69 6e 65 20 74 68 72 65 61 64 20  e engine thread 
48b0: 72 65 61 64 73 20 64 61 74 61 20 66 72 6f 6d 20  reads data from 
48c0: 2a 2f 0a 20 20 69 36 34 20 69 53 74 61 72 74 4f  */.  i64 iStartO
48d0: 66 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ff;             
48e0: 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 74       /* Offset t
48f0: 6f 20 73 74 61 72 74 20 77 72 69 74 69 6e 67 20  o start writing 
4900: 66 69 6c 65 20 61 74 20 2a 2f 0a 20 20 69 6e 74  file at */.  int
4910: 20 6d 78 53 7a 3b 20 20 20 20 20 20 20 20 20 20   mxSz;          
4920: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4930: 4d 61 78 69 6d 75 6d 20 62 79 74 65 73 20 6f 66  Maximum bytes of
4940: 20 64 61 74 61 20 74 6f 20 73 74 6f 72 65 20 2a   data to store *
4950: 2f 0a 20 20 69 6e 74 20 62 45 6f 66 3b 20 20 20  /.  int bEof;   
4960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4970: 20 20 20 20 2f 2a 20 53 65 74 20 74 6f 20 74 72      /* Set to tr
4980: 75 65 20 77 68 65 6e 20 6d 65 72 67 65 20 69 73  ue when merge is
4990: 20 66 69 6e 69 73 68 65 64 20 2a 2f 0a 20 20 69   finished */.  i
49a0: 6e 74 20 62 55 73 65 54 68 72 65 61 64 3b 20 20  nt bUseThread;  
49b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
49c0: 2a 20 54 72 75 65 20 74 6f 20 75 73 65 20 61 20  * True to use a 
49d0: 62 67 20 74 68 72 65 61 64 20 66 6f 72 20 74 68  bg thread for th
49e0: 69 73 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 53  is object */.  S
49f0: 6f 72 74 65 72 46 69 6c 65 20 61 46 69 6c 65 5b  orterFile aFile[
4a00: 32 5d 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  2];            /
4a10: 2a 20 61 46 69 6c 65 5b 30 5d 20 66 6f 72 20 72  * aFile[0] for r
4a20: 65 61 64 69 6e 67 2c 20 5b 31 5d 20 66 6f 72 20  eading, [1] for 
4a30: 77 72 69 74 69 6e 67 20 2a 2f 0a 7d 3b 0a 0a 2f  writing */.};../
4a40: 2a 0a 2a 2a 20 41 6e 20 69 6e 73 74 61 6e 63 65  *.** An instance
4a50: 20 6f 66 20 74 68 69 73 20 6f 62 6a 65 63 74 20   of this object 
4a60: 69 73 20 75 73 65 64 20 66 6f 72 20 77 72 69 74  is used for writ
4a70: 69 6e 67 20 61 20 50 4d 41 2e 0a 2a 2a 0a 2a 2a  ing a PMA..**.**
4a80: 20 54 68 65 20 50 4d 41 20 69 73 20 77 72 69 74   The PMA is writ
4a90: 74 65 6e 20 6f 6e 65 20 72 65 63 6f 72 64 20 61  ten one record a
4aa0: 74 20 61 20 74 69 6d 65 2e 20 20 45 61 63 68 20  t a time.  Each 
4ab0: 72 65 63 6f 72 64 20 69 73 20 6f 66 20 61 6e 20  record is of an 
4ac0: 61 72 62 69 74 72 61 72 79 0a 2a 2a 20 73 69 7a  arbitrary.** siz
4ad0: 65 2e 20 20 42 75 74 20 49 2f 4f 20 69 73 20 6d  e.  But I/O is m
4ae0: 6f 72 65 20 65 66 66 69 63 69 65 6e 74 20 69 66  ore efficient if
4af0: 20 69 74 20 6f 63 63 75 72 73 20 69 6e 20 70 61   it occurs in pa
4b00: 67 65 2d 73 69 7a 65 64 20 62 6c 6f 63 6b 73 20  ge-sized blocks 
4b10: 77 68 65 72 65 0a 2a 2a 20 65 61 63 68 20 62 6c  where.** each bl
4b20: 6f 63 6b 20 69 73 20 61 6c 69 67 6e 65 64 20 6f  ock is aligned o
4b30: 6e 20 61 20 70 61 67 65 20 62 6f 75 6e 64 61 72  n a page boundar
4b40: 79 2e 20 20 54 68 69 73 20 6f 62 6a 65 63 74 20  y.  This object 
4b50: 63 61 63 68 65 73 20 77 72 69 74 65 73 20 74 6f  caches writes to
4b60: 0a 2a 2a 20 74 68 65 20 50 4d 41 20 73 6f 20 74  .** the PMA so t
4b70: 68 61 74 20 61 6c 69 67 6e 65 64 2c 20 70 61 67  hat aligned, pag
4b80: 65 2d 73 69 7a 65 20 62 6c 6f 63 6b 73 20 61 72  e-size blocks ar
4b90: 65 20 77 72 69 74 74 65 6e 2e 0a 2a 2f 0a 73 74  e written..*/.st
4ba0: 72 75 63 74 20 50 6d 61 57 72 69 74 65 72 20 7b  ruct PmaWriter {
4bb0: 0a 20 20 69 6e 74 20 65 46 57 45 72 72 3b 20 20  .  int eFWErr;  
4bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4bd0: 20 20 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20 69     /* Non-zero i
4be0: 66 20 69 6e 20 61 6e 20 65 72 72 6f 72 20 73 74  f in an error st
4bf0: 61 74 65 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75  ate */.  u8 *aBu
4c00: 66 66 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  ffer;           
4c10: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
4c20: 74 65 72 20 74 6f 20 77 72 69 74 65 20 62 75 66  ter to write buf
4c30: 66 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 75  fer */.  int nBu
4c40: 66 66 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  ffer;           
4c50: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
4c60: 20 6f 66 20 77 72 69 74 65 20 62 75 66 66 65 72   of write buffer
4c70: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69   in bytes */.  i
4c80: 6e 74 20 69 42 75 66 53 74 61 72 74 3b 20 20 20  nt iBufStart;   
4c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4ca0: 2a 20 46 69 72 73 74 20 62 79 74 65 20 6f 66 20  * First byte of 
4cb0: 62 75 66 66 65 72 20 74 6f 20 77 72 69 74 65 20  buffer to write 
4cc0: 2a 2f 0a 20 20 69 6e 74 20 69 42 75 66 45 6e 64  */.  int iBufEnd
4cd0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4ce0: 20 20 20 20 20 2f 2a 20 4c 61 73 74 20 62 79 74       /* Last byt
4cf0: 65 20 6f 66 20 62 75 66 66 65 72 20 74 6f 20 77  e of buffer to w
4d00: 72 69 74 65 20 2a 2f 0a 20 20 69 36 34 20 69 57  rite */.  i64 iW
4d10: 72 69 74 65 4f 66 66 3b 20 20 20 20 20 20 20 20  riteOff;        
4d20: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66            /* Off
4d30: 73 65 74 20 6f 66 20 73 74 61 72 74 20 6f 66 20  set of start of 
4d40: 62 75 66 66 65 72 20 69 6e 20 66 69 6c 65 20 2a  buffer in file *
4d50: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  /.  sqlite3_file
4d60: 20 2a 70 46 64 3b 20 20 20 20 20 20 20 20 20 20   *pFd;          
4d70: 20 20 20 20 2f 2a 20 46 69 6c 65 20 68 61 6e 64      /* File hand
4d80: 6c 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20 2a  le to write to *
4d90: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  /.};../*.** This
4da0: 20 6f 62 6a 65 63 74 20 69 73 20 74 68 65 20 68   object is the h
4db0: 65 61 64 65 72 20 6f 6e 20 61 20 73 69 6e 67 6c  eader on a singl
4dc0: 65 20 72 65 63 6f 72 64 20 77 68 69 6c 65 20 74  e record while t
4dd0: 68 61 74 20 72 65 63 6f 72 64 20 69 73 20 62 65  hat record is be
4de0: 69 6e 67 0a 2a 2a 20 68 65 6c 64 20 69 6e 20 6d  ing.** held in m
4df0: 65 6d 6f 72 79 20 61 6e 64 20 70 72 69 6f 72 20  emory and prior 
4e00: 74 6f 20 62 65 69 6e 67 20 77 72 69 74 74 65 6e  to being written
4e10: 20 6f 75 74 20 61 73 20 70 61 72 74 20 6f 66 20   out as part of 
4e20: 61 20 50 4d 41 2e 0a 2a 2a 0a 2a 2a 20 48 6f 77  a PMA..**.** How
4e30: 20 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74   the linked list
4e40: 20 69 73 20 63 6f 6e 6e 65 63 74 65 64 20 64 65   is connected de
4e50: 70 65 6e 64 73 20 6f 6e 20 68 6f 77 20 6d 65 6d  pends on how mem
4e60: 6f 72 79 20 69 73 20 62 65 69 6e 67 20 6d 61 6e  ory is being man
4e70: 61 67 65 64 0a 2a 2a 20 62 79 20 74 68 69 73 20  aged.** by this 
4e80: 6d 6f 64 75 6c 65 2e 20 49 66 20 75 73 69 6e 67  module. If using
4e90: 20 61 20 73 65 70 61 72 61 74 65 20 61 6c 6c 6f   a separate allo
4ea0: 63 61 74 69 6f 6e 20 66 6f 72 20 65 61 63 68 20  cation for each 
4eb0: 69 6e 2d 6d 65 6d 6f 72 79 20 72 65 63 6f 72 64  in-memory record
4ec0: 0a 2a 2a 20 28 56 64 62 65 53 6f 72 74 65 72 2e  .** (VdbeSorter.
4ed0: 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30 29  list.aMemory==0)
4ee0: 2c 20 74 68 65 6e 20 74 68 65 20 6c 69 73 74 20  , then the list 
4ef0: 69 73 20 61 6c 77 61 79 73 20 63 6f 6e 6e 65 63  is always connec
4f00: 74 65 64 20 75 73 69 6e 67 20 74 68 65 0a 2a 2a  ted using the.**
4f10: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 75 2e   SorterRecord.u.
4f20: 70 4e 65 78 74 20 70 6f 69 6e 74 65 72 73 2e 0a  pNext pointers..
4f30: 2a 2a 0a 2a 2a 20 4f 72 2c 20 69 66 20 75 73 69  **.** Or, if usi
4f40: 6e 67 20 74 68 65 20 73 69 6e 67 6c 65 20 6c 61  ng the single la
4f50: 72 67 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6d  rge allocation m
4f60: 65 74 68 6f 64 20 28 56 64 62 65 53 6f 72 74 65  ethod (VdbeSorte
4f70: 72 2e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 21 3d  r.list.aMemory!=
4f80: 30 29 2c 0a 2a 2a 20 74 68 65 6e 20 77 68 69 6c  0),.** then whil
4f90: 65 20 72 65 63 6f 72 64 73 20 61 72 65 20 62 65  e records are be
4fa0: 69 6e 67 20 61 63 63 75 6d 75 6c 61 74 65 64 20  ing accumulated 
4fb0: 74 68 65 20 6c 69 73 74 20 69 73 20 6c 69 6e 6b  the list is link
4fc0: 65 64 20 75 73 69 6e 67 20 74 68 65 0a 2a 2a 20  ed using the.** 
4fd0: 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 75 2e 69  SorterRecord.u.i
4fe0: 4e 65 78 74 20 6f 66 66 73 65 74 2e 20 54 68 69  Next offset. Thi
4ff0: 73 20 69 73 20 62 65 63 61 75 73 65 20 74 68 65  s is because the
5000: 20 61 4d 65 6d 6f 72 79 5b 5d 20 61 72 72 61 79   aMemory[] array
5010: 20 6d 61 79 0a 2a 2a 20 62 65 20 73 71 6c 69 74   may.** be sqlit
5020: 65 33 52 65 61 6c 6c 6f 63 28 29 65 64 20 77 68  e3Realloc()ed wh
5030: 69 6c 65 20 72 65 63 6f 72 64 73 20 61 72 65 20  ile records are 
5040: 62 65 69 6e 67 20 61 63 63 75 6d 75 6c 61 74 65  being accumulate
5050: 64 2e 20 4f 6e 63 65 20 74 68 65 20 56 4d 0a 2a  d. Once the VM.*
5060: 2a 20 68 61 73 20 66 69 6e 69 73 68 65 64 20 70  * has finished p
5070: 61 73 73 69 6e 67 20 72 65 63 6f 72 64 73 20 74  assing records t
5080: 6f 20 74 68 65 20 73 6f 72 74 65 72 2c 20 6f 72  o the sorter, or
5090: 20 77 68 65 6e 20 74 68 65 20 69 6e 2d 6d 65 6d   when the in-mem
50a0: 6f 72 79 20 62 75 66 66 65 72 0a 2a 2a 20 69 73  ory buffer.** is
50b0: 20 66 75 6c 6c 2c 20 74 68 65 20 6c 69 73 74 20   full, the list 
50c0: 69 73 20 73 6f 72 74 65 64 2e 20 41 73 20 70 61  is sorted. As pa
50d0: 72 74 20 6f 66 20 74 68 65 20 73 6f 72 74 69 6e  rt of the sortin
50e0: 67 20 70 72 6f 63 65 73 73 2c 20 69 74 20 69 73  g process, it is
50f0: 0a 2a 2a 20 63 6f 6e 76 65 72 74 65 64 20 74 6f  .** converted to
5100: 20 75 73 65 20 74 68 65 20 53 6f 72 74 65 72 52   use the SorterR
5110: 65 63 6f 72 64 2e 75 2e 70 4e 65 78 74 20 70 6f  ecord.u.pNext po
5120: 69 6e 74 65 72 73 2e 20 53 65 65 20 66 75 6e 63  inters. See func
5130: 74 69 6f 6e 0a 2a 2a 20 76 64 62 65 53 6f 72 74  tion.** vdbeSort
5140: 65 72 53 6f 72 74 28 29 20 66 6f 72 20 64 65 74  erSort() for det
5150: 61 69 6c 73 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  ails..*/.struct 
5160: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 7b 0a 20  SorterRecord {. 
5170: 20 69 6e 74 20 6e 56 61 6c 3b 20 20 20 20 20 20   int nVal;      
5180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5190: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 74 68 65 20   /* Size of the 
51a0: 72 65 63 6f 72 64 20 69 6e 20 62 79 74 65 73 20  record in bytes 
51b0: 2a 2f 0a 20 20 75 6e 69 6f 6e 20 7b 0a 20 20 20  */.  union {.   
51c0: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
51d0: 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 2f  Next;          /
51e0: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 6e 65 78  * Pointer to nex
51f0: 74 20 72 65 63 6f 72 64 20 69 6e 20 6c 69 73 74  t record in list
5200: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 4e 65 78   */.    int iNex
5210: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
5220: 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20        /* Offset 
5230: 77 69 74 68 69 6e 20 61 4d 65 6d 6f 72 79 20 6f  within aMemory o
5240: 66 20 6e 65 78 74 20 72 65 63 6f 72 64 20 2a 2f  f next record */
5250: 0a 20 20 7d 20 75 3b 0a 20 20 2f 2a 20 54 68 65  .  } u;.  /* The
5260: 20 64 61 74 61 20 66 6f 72 20 74 68 65 20 72 65   data for the re
5270: 63 6f 72 64 20 69 6d 6d 65 64 69 61 74 65 6c 79  cord immediately
5280: 20 66 6f 6c 6c 6f 77 73 20 74 68 69 73 20 68 65   follows this he
5290: 61 64 65 72 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 52  ader */.};../* R
52a0: 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20  eturn a pointer 
52b0: 74 6f 20 74 68 65 20 62 75 66 66 65 72 20 63 6f  to the buffer co
52c0: 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 72 65 63  ntaining the rec
52d0: 6f 72 64 20 64 61 74 61 20 66 6f 72 20 53 6f 72  ord data for Sor
52e0: 74 65 72 52 65 63 6f 72 64 0a 2a 2a 20 6f 62 6a  terRecord.** obj
52f0: 65 63 74 20 70 2e 20 53 68 6f 75 6c 64 20 62 65  ect p. Should be
5300: 20 75 73 65 64 20 61 73 20 69 66 3a 0a 2a 2a 0a   used as if:.**.
5310: 2a 2a 20 20 20 76 6f 69 64 20 2a 53 52 56 41 4c  **   void *SRVAL
5320: 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70  (SorterRecord *p
5330: 29 20 7b 20 72 65 74 75 72 6e 20 28 76 6f 69 64  ) { return (void
5340: 2a 29 26 70 5b 31 5d 3b 20 7d 0a 2a 2f 0a 23 64  *)&p[1]; }.*/.#d
5350: 65 66 69 6e 65 20 53 52 56 41 4c 28 70 29 20 28  efine SRVAL(p) (
5360: 28 76 6f 69 64 2a 29 28 28 53 6f 72 74 65 72 52  (void*)((SorterR
5370: 65 63 6f 72 64 2a 29 28 70 29 20 2b 20 31 29 29  ecord*)(p) + 1))
5380: 0a 0a 2f 2a 20 54 68 65 20 6d 69 6e 69 6d 75 6d  ../* The minimum
5390: 20 50 4d 41 20 73 69 7a 65 20 69 73 20 73 65 74   PMA size is set
53a0: 20 74 6f 20 74 68 69 73 20 76 61 6c 75 65 20 6d   to this value m
53b0: 75 6c 74 69 70 6c 69 65 64 20 62 79 20 74 68 65  ultiplied by the
53c0: 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 70 61 67   database.** pag
53d0: 65 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73 2e  e size in bytes.
53e0: 20 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53 4f 52    */.#define SOR
53f0: 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20  TER_MIN_WORKING 
5400: 31 30 0a 0a 2f 2a 20 4d 61 78 69 6d 75 6d 20 6e  10../* Maximum n
5410: 75 6d 62 65 72 20 6f 66 20 50 4d 41 73 20 74 68  umber of PMAs th
5420: 61 74 20 61 20 73 69 6e 67 6c 65 20 4d 65 72 67  at a single Merg
5430: 65 45 6e 67 69 6e 65 20 63 61 6e 20 6d 65 72 67  eEngine can merg
5440: 65 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53 4f 52  e */.#define SOR
5450: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
5460: 55 4e 54 20 31 36 0a 0a 73 74 61 74 69 63 20 69  UNT 16..static i
5470: 6e 74 20 76 64 62 65 49 6e 63 72 53 77 61 70 28  nt vdbeIncrSwap(
5480: 49 6e 63 72 4d 65 72 67 65 72 2a 29 3b 0a 73 74  IncrMerger*);.st
5490: 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 49 6e  atic void vdbeIn
54a0: 63 72 46 72 65 65 28 49 6e 63 72 4d 65 72 67 65  crFree(IncrMerge
54b0: 72 20 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 46 72 65  r *);../*.** Fre
54c0: 65 20 61 6c 6c 20 6d 65 6d 6f 72 79 20 62 65 6c  e all memory bel
54d0: 6f 6e 67 69 6e 67 20 74 6f 20 74 68 65 20 50 6d  onging to the Pm
54e0: 61 52 65 61 64 65 72 20 6f 62 6a 65 63 74 20 70  aReader object p
54f0: 61 73 73 65 64 20 61 73 20 74 68 65 0a 2a 2a 20  assed as the.** 
5500: 61 72 67 75 6d 65 6e 74 2e 20 41 6c 6c 20 73 74  argument. All st
5510: 72 75 63 74 75 72 65 20 66 69 65 6c 64 73 20 61  ructure fields a
5520: 72 65 20 73 65 74 20 74 6f 20 7a 65 72 6f 20 62  re set to zero b
5530: 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
5540: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
5550: 76 64 62 65 50 6d 61 52 65 61 64 65 72 43 6c 65  vdbePmaReaderCle
5560: 61 72 28 50 6d 61 52 65 61 64 65 72 20 2a 70 52  ar(PmaReader *pR
5570: 65 61 64 72 29 7b 0a 20 20 73 71 6c 69 74 65 33  eadr){.  sqlite3
5580: 5f 66 72 65 65 28 70 52 65 61 64 72 2d 3e 61 41  _free(pReadr->aA
5590: 6c 6c 6f 63 29 3b 0a 20 20 73 71 6c 69 74 65 33  lloc);.  sqlite3
55a0: 5f 66 72 65 65 28 70 52 65 61 64 72 2d 3e 61 42  _free(pReadr->aB
55b0: 75 66 66 65 72 29 3b 0a 20 20 69 66 28 20 70 52  uffer);.  if( pR
55c0: 65 61 64 72 2d 3e 61 4d 61 70 20 29 20 73 71 6c  eadr->aMap ) sql
55d0: 69 74 65 33 4f 73 55 6e 66 65 74 63 68 28 70 52  ite3OsUnfetch(pR
55e0: 65 61 64 72 2d 3e 70 46 64 2c 20 30 2c 20 70 52  eadr->pFd, 0, pR
55f0: 65 61 64 72 2d 3e 61 4d 61 70 29 3b 0a 20 20 76  eadr->aMap);.  v
5600: 64 62 65 49 6e 63 72 46 72 65 65 28 70 52 65 61  dbeIncrFree(pRea
5610: 64 72 2d 3e 70 49 6e 63 72 29 3b 0a 20 20 6d 65  dr->pIncr);.  me
5620: 6d 73 65 74 28 70 52 65 61 64 72 2c 20 30 2c 20  mset(pReadr, 0, 
5630: 73 69 7a 65 6f 66 28 50 6d 61 52 65 61 64 65 72  sizeof(PmaReader
5640: 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61  ));.}../*.** Rea
5650: 64 20 74 68 65 20 6e 65 78 74 20 6e 42 79 74 65  d the next nByte
5660: 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 66   bytes of data f
5670: 72 6f 6d 20 74 68 65 20 50 4d 41 20 70 2e 0a 2a  rom the PMA p..*
5680: 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c  * If successful,
5690: 20 73 65 74 20 2a 70 70 4f 75 74 20 74 6f 20 70   set *ppOut to p
56a0: 6f 69 6e 74 20 74 6f 20 61 20 62 75 66 66 65 72  oint to a buffer
56b0: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20   containing the 
56c0: 64 61 74 61 0a 2a 2a 20 61 6e 64 20 72 65 74 75  data.** and retu
56d0: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 4f 74  rn SQLITE_OK. Ot
56e0: 68 65 72 77 69 73 65 2c 20 69 66 20 61 6e 20 65  herwise, if an e
56f0: 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 72 65 74  rror occurs, ret
5700: 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 0a 2a 2a  urn an SQLite.**
5710: 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a   error code..**.
5720: 2a 2a 20 54 68 65 20 62 75 66 66 65 72 20 72 65  ** The buffer re
5730: 74 75 72 6e 65 64 20 69 6e 20 2a 70 70 4f 75 74  turned in *ppOut
5740: 20 69 73 20 6f 6e 6c 79 20 76 61 6c 69 64 20 75   is only valid u
5750: 6e 74 69 6c 20 74 68 65 0a 2a 2a 20 6e 65 78 74  ntil the.** next
5760: 20 63 61 6c 6c 20 74 6f 20 74 68 69 73 20 66 75   call to this fu
5770: 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69  nction..*/.stati
5780: 63 20 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61  c int vdbePmaRea
5790: 64 42 6c 6f 62 28 0a 20 20 50 6d 61 52 65 61 64  dBlob(.  PmaRead
57a0: 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20  er *p,          
57b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6d 61 52           /* PmaR
57c0: 65 61 64 65 72 20 66 72 6f 6d 20 77 68 69 63 68  eader from which
57d0: 20 74 6f 20 74 61 6b 65 20 74 68 65 20 62 6c 6f   to take the blo
57e0: 62 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65  b */.  int nByte
57f0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
5800: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
5810: 6f 66 20 64 61 74 61 20 74 6f 20 72 65 61 64 20  of data to read 
5820: 2a 2f 0a 20 20 75 38 20 2a 2a 70 70 4f 75 74 20  */.  u8 **ppOut 
5830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5840: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 50 6f 69       /* OUT: Poi
5850: 6e 74 65 72 20 74 6f 20 62 75 66 66 65 72 20 63  nter to buffer c
5860: 6f 6e 74 61 69 6e 69 6e 67 20 64 61 74 61 20 2a  ontaining data *
5870: 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 42 75 66 3b  /.){.  int iBuf;
5880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5890: 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74         /* Offset
58a0: 20 77 69 74 68 69 6e 20 62 75 66 66 65 72 20 74   within buffer t
58b0: 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20  o read from */. 
58c0: 20 69 6e 74 20 6e 41 76 61 69 6c 3b 20 20 20 20   int nAvail;    
58d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
58e0: 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 64 61 74   /* Bytes of dat
58f0: 61 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 62  a available in b
5900: 75 66 66 65 72 20 2a 2f 0a 0a 20 20 69 66 28 20  uffer */..  if( 
5910: 70 2d 3e 61 4d 61 70 20 29 7b 0a 20 20 20 20 2a  p->aMap ){.    *
5920: 70 70 4f 75 74 20 3d 20 26 70 2d 3e 61 4d 61 70  ppOut = &p->aMap
5930: 5b 70 2d 3e 69 52 65 61 64 4f 66 66 5d 3b 0a 20  [p->iReadOff];. 
5940: 20 20 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b     p->iReadOff +
5950: 3d 20 6e 42 79 74 65 3b 0a 20 20 20 20 72 65 74  = nByte;.    ret
5960: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  urn SQLITE_OK;. 
5970: 20 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 70 2d   }..  assert( p-
5980: 3e 61 42 75 66 66 65 72 20 29 3b 0a 0a 20 20 2f  >aBuffer );..  /
5990: 2a 20 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f  * If there is no
59a0: 20 6d 6f 72 65 20 64 61 74 61 20 74 6f 20 62 65   more data to be
59b0: 20 72 65 61 64 20 66 72 6f 6d 20 74 68 65 20 62   read from the b
59c0: 75 66 66 65 72 2c 20 72 65 61 64 20 74 68 65 20  uffer, read the 
59d0: 6e 65 78 74 20 0a 20 20 2a 2a 20 70 2d 3e 6e 42  next .  ** p->nB
59e0: 75 66 66 65 72 20 62 79 74 65 73 20 6f 66 20 64  uffer bytes of d
59f0: 61 74 61 20 66 72 6f 6d 20 74 68 65 20 66 69 6c  ata from the fil
5a00: 65 20 69 6e 74 6f 20 69 74 2e 20 4f 72 2c 20 69  e into it. Or, i
5a10: 66 20 74 68 65 72 65 20 61 72 65 20 6c 65 73 73  f there are less
5a20: 0a 20 20 2a 2a 20 74 68 61 6e 20 70 2d 3e 6e 42  .  ** than p->nB
5a30: 75 66 66 65 72 20 62 79 74 65 73 20 72 65 6d 61  uffer bytes rema
5a40: 69 6e 69 6e 67 20 69 6e 20 74 68 65 20 50 4d 41  ining in the PMA
5a50: 2c 20 72 65 61 64 20 61 6c 6c 20 72 65 6d 61 69  , read all remai
5a60: 6e 69 6e 67 20 64 61 74 61 2e 20 20 2a 2f 0a 20  ning data.  */. 
5a70: 20 69 42 75 66 20 3d 20 70 2d 3e 69 52 65 61 64   iBuf = p->iRead
5a80: 4f 66 66 20 25 20 70 2d 3e 6e 42 75 66 66 65 72  Off % p->nBuffer
5a90: 3b 0a 20 20 69 66 28 20 69 42 75 66 3d 3d 30 20  ;.  if( iBuf==0 
5aa0: 29 7b 0a 20 20 20 20 69 6e 74 20 6e 52 65 61 64  ){.    int nRead
5ab0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
5ac0: 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 74 6f       /* Bytes to
5ad0: 20 72 65 61 64 20 66 72 6f 6d 20 64 69 73 6b 20   read from disk 
5ae0: 2a 2f 0a 20 20 20 20 69 6e 74 20 72 63 3b 20 20  */.    int rc;  
5af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5b00: 20 20 20 20 20 2f 2a 20 73 71 6c 69 74 65 33 4f       /* sqlite3O
5b10: 73 52 65 61 64 28 29 20 72 65 74 75 72 6e 20 63  sRead() return c
5b20: 6f 64 65 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 44  ode */..    /* D
5b30: 65 74 65 72 6d 69 6e 65 20 68 6f 77 20 6d 61 6e  etermine how man
5b40: 79 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20  y bytes of data 
5b50: 74 6f 20 72 65 61 64 2e 20 2a 2f 0a 20 20 20 20  to read. */.    
5b60: 69 66 28 20 28 70 2d 3e 69 45 6f 66 20 2d 20 70  if( (p->iEof - p
5b70: 2d 3e 69 52 65 61 64 4f 66 66 29 20 3e 20 28 69  ->iReadOff) > (i
5b80: 36 34 29 70 2d 3e 6e 42 75 66 66 65 72 20 29 7b  64)p->nBuffer ){
5b90: 0a 20 20 20 20 20 20 6e 52 65 61 64 20 3d 20 70  .      nRead = p
5ba0: 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20 20 7d  ->nBuffer;.    }
5bb0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 6e 52 65 61  else{.      nRea
5bc0: 64 20 3d 20 28 69 6e 74 29 28 70 2d 3e 69 45 6f  d = (int)(p->iEo
5bd0: 66 20 2d 20 70 2d 3e 69 52 65 61 64 4f 66 66 29  f - p->iReadOff)
5be0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65  ;.    }.    asse
5bf0: 72 74 28 20 6e 52 65 61 64 3e 30 20 29 3b 0a 0a  rt( nRead>0 );..
5c00: 20 20 20 20 2f 2a 20 52 65 61 64 72 20 64 61 74      /* Readr dat
5c10: 61 20 66 72 6f 6d 20 74 68 65 20 66 69 6c 65 2e  a from the file.
5c20: 20 52 65 74 75 72 6e 20 65 61 72 6c 79 20 69 66   Return early if
5c30: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
5c40: 2e 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 73 71  . */.    rc = sq
5c50: 6c 69 74 65 33 4f 73 52 65 61 64 28 70 2d 3e 70  lite3OsRead(p->p
5c60: 46 64 2c 20 70 2d 3e 61 42 75 66 66 65 72 2c 20  Fd, p->aBuffer, 
5c70: 6e 52 65 61 64 2c 20 70 2d 3e 69 52 65 61 64 4f  nRead, p->iReadO
5c80: 66 66 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  ff);.    assert(
5c90: 20 72 63 21 3d 53 51 4c 49 54 45 5f 49 4f 45 52   rc!=SQLITE_IOER
5ca0: 52 5f 53 48 4f 52 54 5f 52 45 41 44 20 29 3b 0a  R_SHORT_READ );.
5cb0: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
5cc0: 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
5cd0: 63 3b 0a 20 20 7d 0a 20 20 6e 41 76 61 69 6c 20  c;.  }.  nAvail 
5ce0: 3d 20 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 69  = p->nBuffer - i
5cf0: 42 75 66 3b 20 0a 0a 20 20 69 66 28 20 6e 42 79  Buf; ..  if( nBy
5d00: 74 65 3c 3d 6e 41 76 61 69 6c 20 29 7b 0a 20 20  te<=nAvail ){.  
5d10: 20 20 2f 2a 20 54 68 65 20 72 65 71 75 65 73 74    /* The request
5d20: 65 64 20 64 61 74 61 20 69 73 20 61 76 61 69 6c  ed data is avail
5d30: 61 62 6c 65 20 69 6e 20 74 68 65 20 69 6e 2d 6d  able in the in-m
5d40: 65 6d 6f 72 79 20 62 75 66 66 65 72 2e 20 49 6e  emory buffer. In
5d50: 20 74 68 69 73 0a 20 20 20 20 2a 2a 20 63 61 73   this.    ** cas
5d60: 65 20 74 68 65 72 65 20 69 73 20 6e 6f 20 6e 65  e there is no ne
5d70: 65 64 20 74 6f 20 6d 61 6b 65 20 61 20 63 6f 70  ed to make a cop
5d80: 79 20 6f 66 20 74 68 65 20 64 61 74 61 2c 20 6a  y of the data, j
5d90: 75 73 74 20 72 65 74 75 72 6e 20 61 20 0a 20 20  ust return a .  
5da0: 20 20 2a 2a 20 70 6f 69 6e 74 65 72 20 69 6e 74    ** pointer int
5db0: 6f 20 74 68 65 20 62 75 66 66 65 72 20 74 6f 20  o the buffer to 
5dc0: 74 68 65 20 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a  the caller.  */.
5dd0: 20 20 20 20 2a 70 70 4f 75 74 20 3d 20 26 70 2d      *ppOut = &p-
5de0: 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d 3b 0a  >aBuffer[iBuf];.
5df0: 20 20 20 20 70 2d 3e 69 52 65 61 64 4f 66 66 20      p->iReadOff 
5e00: 2b 3d 20 6e 42 79 74 65 3b 0a 20 20 7d 65 6c 73  += nByte;.  }els
5e10: 65 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20 72 65  e{.    /* The re
5e20: 71 75 65 73 74 65 64 20 64 61 74 61 20 69 73 20  quested data is 
5e30: 6e 6f 74 20 61 6c 6c 20 61 76 61 69 6c 61 62 6c  not all availabl
5e40: 65 20 69 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f  e in the in-memo
5e50: 72 79 20 62 75 66 66 65 72 2e 0a 20 20 20 20 2a  ry buffer..    *
5e60: 2a 20 49 6e 20 74 68 69 73 20 63 61 73 65 2c 20  * In this case, 
5e70: 61 6c 6c 6f 63 61 74 65 20 73 70 61 63 65 20 61  allocate space a
5e80: 74 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 74 6f  t p->aAlloc[] to
5e90: 20 63 6f 70 79 20 74 68 65 20 72 65 71 75 65 73   copy the reques
5ea0: 74 65 64 0a 20 20 20 20 2a 2a 20 72 61 6e 67 65  ted.    ** range
5eb0: 20 69 6e 74 6f 2e 20 54 68 65 6e 20 72 65 74 75   into. Then retu
5ec0: 72 6e 20 61 20 63 6f 70 79 20 6f 66 20 70 6f 69  rn a copy of poi
5ed0: 6e 74 65 72 20 70 2d 3e 61 41 6c 6c 6f 63 20 74  nter p->aAlloc t
5ee0: 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 20 2a  o the caller.  *
5ef0: 2f 0a 20 20 20 20 69 6e 74 20 6e 52 65 6d 3b 20  /.    int nRem; 
5f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5f10: 20 20 20 20 2f 2a 20 42 79 74 65 73 20 72 65 6d      /* Bytes rem
5f20: 61 69 6e 69 6e 67 20 74 6f 20 63 6f 70 79 20 2a  aining to copy *
5f30: 2f 0a 0a 20 20 20 20 2f 2a 20 45 78 74 65 6e 64  /..    /* Extend
5f40: 20 74 68 65 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d   the p->aAlloc[]
5f50: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 66 20 72   allocation if r
5f60: 65 71 75 69 72 65 64 2e 20 2a 2f 0a 20 20 20 20  equired. */.    
5f70: 69 66 28 20 70 2d 3e 6e 41 6c 6c 6f 63 3c 6e 42  if( p->nAlloc<nB
5f80: 79 74 65 20 29 7b 0a 20 20 20 20 20 20 75 38 20  yte ){.      u8 
5f90: 2a 61 4e 65 77 3b 0a 20 20 20 20 20 20 69 6e 74  *aNew;.      int
5fa0: 20 6e 4e 65 77 20 3d 20 4d 41 58 28 31 32 38 2c   nNew = MAX(128,
5fb0: 20 70 2d 3e 6e 41 6c 6c 6f 63 2a 32 29 3b 0a 20   p->nAlloc*2);. 
5fc0: 20 20 20 20 20 77 68 69 6c 65 28 20 6e 42 79 74       while( nByt
5fd0: 65 3e 6e 4e 65 77 20 29 20 6e 4e 65 77 20 3d 20  e>nNew ) nNew = 
5fe0: 6e 4e 65 77 2a 32 3b 0a 20 20 20 20 20 20 61 4e  nNew*2;.      aN
5ff0: 65 77 20 3d 20 73 71 6c 69 74 65 33 52 65 61 6c  ew = sqlite3Real
6000: 6c 6f 63 28 70 2d 3e 61 41 6c 6c 6f 63 2c 20 6e  loc(p->aAlloc, n
6010: 4e 65 77 29 3b 0a 20 20 20 20 20 20 69 66 28 20  New);.      if( 
6020: 21 61 4e 65 77 20 29 20 72 65 74 75 72 6e 20 53  !aNew ) return S
6030: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
6040: 20 20 20 70 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 6e     p->nAlloc = n
6050: 4e 65 77 3b 0a 20 20 20 20 20 20 70 2d 3e 61 41  New;.      p->aA
6060: 6c 6c 6f 63 20 3d 20 61 4e 65 77 3b 0a 20 20 20  lloc = aNew;.   
6070: 20 7d 0a 0a 20 20 20 20 2f 2a 20 43 6f 70 79 20   }..    /* Copy 
6080: 61 73 20 6d 75 63 68 20 64 61 74 61 20 61 73 20  as much data as 
6090: 69 73 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20  is available in 
60a0: 74 68 65 20 62 75 66 66 65 72 20 69 6e 74 6f 20  the buffer into 
60b0: 74 68 65 20 73 74 61 72 74 20 6f 66 0a 20 20 20  the start of.   
60c0: 20 2a 2a 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 2e   ** p->aAlloc[].
60d0: 20 20 2a 2f 0a 20 20 20 20 6d 65 6d 63 70 79 28    */.    memcpy(
60e0: 70 2d 3e 61 41 6c 6c 6f 63 2c 20 26 70 2d 3e 61  p->aAlloc, &p->a
60f0: 42 75 66 66 65 72 5b 69 42 75 66 5d 2c 20 6e 41  Buffer[iBuf], nA
6100: 76 61 69 6c 29 3b 0a 20 20 20 20 70 2d 3e 69 52  vail);.    p->iR
6110: 65 61 64 4f 66 66 20 2b 3d 20 6e 41 76 61 69 6c  eadOff += nAvail
6120: 3b 0a 20 20 20 20 6e 52 65 6d 20 3d 20 6e 42 79  ;.    nRem = nBy
6130: 74 65 20 2d 20 6e 41 76 61 69 6c 3b 0a 0a 20 20  te - nAvail;..  
6140: 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69    /* The followi
6150: 6e 67 20 6c 6f 6f 70 20 63 6f 70 69 65 73 20 75  ng loop copies u
6160: 70 20 74 6f 20 70 2d 3e 6e 42 75 66 66 65 72 20  p to p->nBuffer 
6170: 62 79 74 65 73 20 70 65 72 20 69 74 65 72 61 74  bytes per iterat
6180: 69 6f 6e 20 69 6e 74 6f 0a 20 20 20 20 2a 2a 20  ion into.    ** 
6190: 74 68 65 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20  the p->aAlloc[] 
61a0: 62 75 66 66 65 72 2e 20 20 2a 2f 0a 20 20 20 20  buffer.  */.    
61b0: 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30 20 29 7b  while( nRem>0 ){
61c0: 0a 20 20 20 20 20 20 69 6e 74 20 72 63 3b 20 20  .      int rc;  
61d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
61e0: 20 20 20 2f 2a 20 76 64 62 65 50 6d 61 52 65 61     /* vdbePmaRea
61f0: 64 42 6c 6f 62 28 29 20 72 65 74 75 72 6e 20 63  dBlob() return c
6200: 6f 64 65 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74  ode */.      int
6210: 20 6e 43 6f 70 79 3b 20 20 20 20 20 20 20 20 20   nCopy;         
6220: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
6230: 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f 20 63  er of bytes to c
6240: 6f 70 79 20 2a 2f 0a 20 20 20 20 20 20 75 38 20  opy */.      u8 
6250: 2a 61 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20  *aNext;         
6260: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
6270: 74 65 72 20 74 6f 20 62 75 66 66 65 72 20 74 6f  ter to buffer to
6280: 20 63 6f 70 79 20 64 61 74 61 20 66 72 6f 6d 20   copy data from 
6290: 2a 2f 0a 0a 20 20 20 20 20 20 6e 43 6f 70 79 20  */..      nCopy 
62a0: 3d 20 6e 52 65 6d 3b 0a 20 20 20 20 20 20 69 66  = nRem;.      if
62b0: 28 20 6e 52 65 6d 3e 70 2d 3e 6e 42 75 66 66 65  ( nRem>p->nBuffe
62c0: 72 20 29 20 6e 43 6f 70 79 20 3d 20 70 2d 3e 6e  r ) nCopy = p->n
62d0: 42 75 66 66 65 72 3b 0a 20 20 20 20 20 20 72 63  Buffer;.      rc
62e0: 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 42 6c   = vdbePmaReadBl
62f0: 6f 62 28 70 2c 20 6e 43 6f 70 79 2c 20 26 61 4e  ob(p, nCopy, &aN
6300: 65 78 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20  ext);.      if( 
6310: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
6320: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20  return rc;.     
6330: 20 61 73 73 65 72 74 28 20 61 4e 65 78 74 21 3d   assert( aNext!=
6340: 70 2d 3e 61 41 6c 6c 6f 63 20 29 3b 0a 20 20 20  p->aAlloc );.   
6350: 20 20 20 6d 65 6d 63 70 79 28 26 70 2d 3e 61 41     memcpy(&p->aA
6360: 6c 6c 6f 63 5b 6e 42 79 74 65 20 2d 20 6e 52 65  lloc[nByte - nRe
6370: 6d 5d 2c 20 61 4e 65 78 74 2c 20 6e 43 6f 70 79  m], aNext, nCopy
6380: 29 3b 0a 20 20 20 20 20 20 6e 52 65 6d 20 2d 3d  );.      nRem -=
6390: 20 6e 43 6f 70 79 3b 0a 20 20 20 20 7d 0a 0a 20   nCopy;.    }.. 
63a0: 20 20 20 2a 70 70 4f 75 74 20 3d 20 70 2d 3e 61     *ppOut = p->a
63b0: 41 6c 6c 6f 63 3b 0a 20 20 7d 0a 0a 20 20 72 65  Alloc;.  }..  re
63c0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
63d0: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 61 20  }../*.** Read a 
63e0: 76 61 72 69 6e 74 20 66 72 6f 6d 20 74 68 65 20  varint from the 
63f0: 73 74 72 65 61 6d 20 6f 66 20 64 61 74 61 20 61  stream of data a
6400: 63 63 65 73 73 65 64 20 62 79 20 70 2e 20 53 65  ccessed by p. Se
6410: 74 20 2a 70 6e 4f 75 74 20 74 6f 0a 2a 2a 20 74  t *pnOut to.** t
6420: 68 65 20 76 61 6c 75 65 20 72 65 61 64 2e 0a 2a  he value read..*
6430: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
6440: 65 50 6d 61 52 65 61 64 56 61 72 69 6e 74 28 50  ePmaReadVarint(P
6450: 6d 61 52 65 61 64 65 72 20 2a 70 2c 20 75 36 34  maReader *p, u64
6460: 20 2a 70 6e 4f 75 74 29 7b 0a 20 20 69 6e 74 20   *pnOut){.  int 
6470: 69 42 75 66 3b 0a 0a 20 20 69 66 28 20 70 2d 3e  iBuf;..  if( p->
6480: 61 4d 61 70 20 29 7b 0a 20 20 20 20 70 2d 3e 69  aMap ){.    p->i
6490: 52 65 61 64 4f 66 66 20 2b 3d 20 73 71 6c 69 74  ReadOff += sqlit
64a0: 65 33 47 65 74 56 61 72 69 6e 74 28 26 70 2d 3e  e3GetVarint(&p->
64b0: 61 4d 61 70 5b 70 2d 3e 69 52 65 61 64 4f 66 66  aMap[p->iReadOff
64c0: 5d 2c 20 70 6e 4f 75 74 29 3b 0a 20 20 7d 65 6c  ], pnOut);.  }el
64d0: 73 65 7b 0a 20 20 20 20 69 42 75 66 20 3d 20 70  se{.    iBuf = p
64e0: 2d 3e 69 52 65 61 64 4f 66 66 20 25 20 70 2d 3e  ->iReadOff % p->
64f0: 6e 42 75 66 66 65 72 3b 0a 20 20 20 20 69 66 28  nBuffer;.    if(
6500: 20 69 42 75 66 20 26 26 20 28 70 2d 3e 6e 42 75   iBuf && (p->nBu
6510: 66 66 65 72 2d 69 42 75 66 29 3e 3d 39 20 29 7b  ffer-iBuf)>=9 ){
6520: 0a 20 20 20 20 20 20 70 2d 3e 69 52 65 61 64 4f  .      p->iReadO
6530: 66 66 20 2b 3d 20 73 71 6c 69 74 65 33 47 65 74  ff += sqlite3Get
6540: 56 61 72 69 6e 74 28 26 70 2d 3e 61 42 75 66 66  Varint(&p->aBuff
6550: 65 72 5b 69 42 75 66 5d 2c 20 70 6e 4f 75 74 29  er[iBuf], pnOut)
6560: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
6570: 20 20 20 75 38 20 61 56 61 72 69 6e 74 5b 31 36     u8 aVarint[16
6580: 5d 2c 20 2a 61 3b 0a 20 20 20 20 20 20 69 6e 74  ], *a;.      int
6590: 20 69 20 3d 20 30 2c 20 72 63 3b 0a 20 20 20 20   i = 0, rc;.    
65a0: 20 20 64 6f 7b 0a 20 20 20 20 20 20 20 20 72 63    do{.        rc
65b0: 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 42 6c   = vdbePmaReadBl
65c0: 6f 62 28 70 2c 20 31 2c 20 26 61 29 3b 0a 20 20  ob(p, 1, &a);.  
65d0: 20 20 20 20 20 20 69 66 28 20 72 63 20 29 20 72        if( rc ) r
65e0: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20  eturn rc;.      
65f0: 20 20 61 56 61 72 69 6e 74 5b 28 69 2b 2b 29 26    aVarint[(i++)&
6600: 30 78 66 5d 20 3d 20 61 5b 30 5d 3b 0a 20 20 20  0xf] = a[0];.   
6610: 20 20 20 7d 77 68 69 6c 65 28 20 28 61 5b 30 5d     }while( (a[0]
6620: 26 30 78 38 30 29 21 3d 30 20 29 3b 0a 20 20 20  &0x80)!=0 );.   
6630: 20 20 20 73 71 6c 69 74 65 33 47 65 74 56 61 72     sqlite3GetVar
6640: 69 6e 74 28 61 56 61 72 69 6e 74 2c 20 70 6e 4f  int(aVarint, pnO
6650: 75 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  ut);.    }.  }..
6660: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
6670: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 74 74  OK;.}../*.** Att
6680: 65 6d 70 74 20 74 6f 20 6d 65 6d 6f 72 79 20 6d  empt to memory m
6690: 61 70 20 66 69 6c 65 20 70 46 69 6c 65 2e 20 49  ap file pFile. I
66a0: 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 73 65  f successful, se
66b0: 74 20 2a 70 70 20 74 6f 20 70 6f 69 6e 74 20 74  t *pp to point t
66c0: 6f 20 74 68 65 0a 2a 2a 20 6e 65 77 20 6d 61 70  o the.** new map
66d0: 70 69 6e 67 20 61 6e 64 20 72 65 74 75 72 6e 20  ping and return 
66e0: 53 51 4c 49 54 45 5f 4f 4b 2e 20 49 66 20 74 68  SQLITE_OK. If th
66f0: 65 20 6d 61 70 70 69 6e 67 20 69 73 20 6e 6f 74  e mapping is not
6700: 20 61 74 74 65 6d 70 74 65 64 20 0a 2a 2a 20 28   attempted .** (
6710: 62 65 63 61 75 73 65 20 74 68 65 20 66 69 6c 65  because the file
6720: 20 69 73 20 74 6f 6f 20 6c 61 72 67 65 20 6f 72   is too large or
6730: 20 74 68 65 20 56 46 53 20 6c 61 79 65 72 20 69   the VFS layer i
6740: 73 20 63 6f 6e 66 69 67 75 72 65 64 20 6e 6f 74  s configured not
6750: 20 74 6f 20 75 73 65 0a 2a 2a 20 6d 6d 61 70 29   to use.** mmap)
6760: 2c 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  , return SQLITE_
6770: 4f 4b 20 61 6e 64 20 73 65 74 20 2a 70 70 20 74  OK and set *pp t
6780: 6f 20 4e 55 4c 4c 2e 0a 2a 2a 0a 2a 2a 20 4f 72  o NULL..**.** Or
6790: 2c 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  , if an error oc
67a0: 63 75 72 73 2c 20 72 65 74 75 72 6e 20 61 6e 20  curs, return an 
67b0: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
67c0: 65 2e 20 54 68 65 20 66 69 6e 61 6c 20 76 61 6c  e. The final val
67d0: 75 65 20 6f 66 0a 2a 2a 20 2a 70 70 20 69 73 20  ue of.** *pp is 
67e0: 75 6e 64 65 66 69 6e 65 64 20 69 6e 20 74 68 69  undefined in thi
67f0: 73 20 63 61 73 65 2e 0a 2a 2f 0a 73 74 61 74 69  s case..*/.stati
6800: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72  c int vdbeSorter
6810: 4d 61 70 46 69 6c 65 28 53 6f 72 74 53 75 62 74  MapFile(SortSubt
6820: 61 73 6b 20 2a 70 54 61 73 6b 2c 20 53 6f 72 74  ask *pTask, Sort
6830: 65 72 46 69 6c 65 20 2a 70 46 69 6c 65 2c 20 75  erFile *pFile, u
6840: 38 20 2a 2a 70 70 29 7b 0a 20 20 69 6e 74 20 72  8 **pp){.  int r
6850: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
6860: 20 69 66 28 20 70 46 69 6c 65 2d 3e 69 45 6f 66   if( pFile->iEof
6870: 3c 3d 28 69 36 34 29 28 70 54 61 73 6b 2d 3e 70  <=(i64)(pTask->p
6880: 53 6f 72 74 65 72 2d 3e 64 62 2d 3e 6e 4d 61 78  Sorter->db->nMax
6890: 53 6f 72 74 65 72 4d 6d 61 70 29 20 29 7b 0a 20  SorterMmap) ){. 
68a0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
68b0: 73 46 65 74 63 68 28 70 46 69 6c 65 2d 3e 70 46  sFetch(pFile->pF
68c0: 64 2c 20 30 2c 20 28 69 6e 74 29 70 46 69 6c 65  d, 0, (int)pFile
68d0: 2d 3e 69 45 6f 66 2c 20 28 76 6f 69 64 2a 2a 29  ->iEof, (void**)
68e0: 70 70 29 3b 0a 20 20 20 20 74 65 73 74 63 61 73  pp);.    testcas
68f0: 65 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  e( rc!=SQLITE_OK
6900: 20 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e   );.  }.  return
6910: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 74   rc;.}../*.** At
6920: 74 61 63 68 20 50 6d 61 52 65 61 64 65 72 20 70  tach PmaReader p
6930: 52 65 61 64 72 20 74 6f 20 66 69 6c 65 20 70 46  Readr to file pF
6940: 69 6c 65 20 28 69 66 20 69 74 20 69 73 20 6e 6f  ile (if it is no
6950: 74 20 61 6c 72 65 61 64 79 20 61 74 74 61 63 68  t already attach
6960: 65 64 20 74 6f 0a 2a 2a 20 74 68 61 74 20 66 69  ed to.** that fi
6970: 6c 65 29 20 61 6e 64 20 73 65 65 6b 20 69 74 20  le) and seek it 
6980: 74 6f 20 6f 66 66 73 65 74 20 69 4f 66 66 20 77  to offset iOff w
6990: 69 74 68 69 6e 20 74 68 65 20 66 69 6c 65 2e 20  ithin the file. 
69a0: 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   Return SQLITE_O
69b0: 4b 20 0a 2a 2a 20 69 66 20 73 75 63 63 65 73 73  K .** if success
69c0: 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74  ful, or an SQLit
69d0: 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20  e error code if 
69e0: 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e  an error occurs.
69f0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
6a00: 64 62 65 50 6d 61 52 65 61 64 65 72 53 65 65 6b  dbePmaReaderSeek
6a10: 28 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20  (.  SortSubtask 
6a20: 2a 70 54 61 73 6b 2c 20 20 20 20 20 20 20 20 20  *pTask,         
6a30: 20 20 20 20 2f 2a 20 54 61 73 6b 20 63 6f 6e 74      /* Task cont
6a40: 65 78 74 20 2a 2f 0a 20 20 50 6d 61 52 65 61 64  ext */.  PmaRead
6a50: 65 72 20 2a 70 52 65 61 64 72 2c 20 20 20 20 20  er *pReadr,     
6a60: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 61 64           /* Read
6a70: 65 72 20 77 68 6f 73 65 20 63 75 72 73 6f 72 20  er whose cursor 
6a80: 69 73 20 74 6f 20 62 65 20 6d 6f 76 65 64 20 2a  is to be moved *
6a90: 2f 0a 20 20 53 6f 72 74 65 72 46 69 6c 65 20 2a  /.  SorterFile *
6aa0: 70 46 69 6c 65 2c 20 20 20 20 20 20 20 20 20 20  pFile,          
6ab0: 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 66 69      /* Sorter fi
6ac0: 6c 65 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20  le to read from 
6ad0: 2a 2f 0a 20 20 69 36 34 20 69 4f 66 66 20 20 20  */.  i64 iOff   
6ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6af0: 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 69       /* Offset i
6b00: 6e 20 70 46 69 6c 65 20 2a 2f 0a 29 7b 0a 20 20  n pFile */.){.  
6b10: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
6b20: 4f 4b 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  OK;..  assert( p
6b30: 52 65 61 64 72 2d 3e 70 49 6e 63 72 3d 3d 30 20  Readr->pIncr==0 
6b40: 7c 7c 20 70 52 65 61 64 72 2d 3e 70 49 6e 63 72  || pReadr->pIncr
6b50: 2d 3e 62 45 6f 66 3d 3d 30 20 29 3b 0a 0a 20 20  ->bEof==0 );..  
6b60: 69 66 28 20 70 52 65 61 64 72 2d 3e 61 4d 61 70  if( pReadr->aMap
6b70: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f   ){.    sqlite3O
6b80: 73 55 6e 66 65 74 63 68 28 70 52 65 61 64 72 2d  sUnfetch(pReadr-
6b90: 3e 70 46 64 2c 20 30 2c 20 70 52 65 61 64 72 2d  >pFd, 0, pReadr-
6ba0: 3e 61 4d 61 70 29 3b 0a 20 20 20 20 70 52 65 61  >aMap);.    pRea
6bb0: 64 72 2d 3e 61 4d 61 70 20 3d 20 30 3b 0a 20 20  dr->aMap = 0;.  
6bc0: 7d 0a 20 20 70 52 65 61 64 72 2d 3e 69 52 65 61  }.  pReadr->iRea
6bd0: 64 4f 66 66 20 3d 20 69 4f 66 66 3b 0a 20 20 70  dOff = iOff;.  p
6be0: 52 65 61 64 72 2d 3e 69 45 6f 66 20 3d 20 70 46  Readr->iEof = pF
6bf0: 69 6c 65 2d 3e 69 45 6f 66 3b 0a 20 20 70 52 65  ile->iEof;.  pRe
6c00: 61 64 72 2d 3e 70 46 64 20 3d 20 70 46 69 6c 65  adr->pFd = pFile
6c10: 2d 3e 70 46 64 3b 0a 0a 20 20 72 63 20 3d 20 76  ->pFd;..  rc = v
6c20: 64 62 65 53 6f 72 74 65 72 4d 61 70 46 69 6c 65  dbeSorterMapFile
6c30: 28 70 54 61 73 6b 2c 20 70 46 69 6c 65 2c 20 26  (pTask, pFile, &
6c40: 70 52 65 61 64 72 2d 3e 61 4d 61 70 29 3b 0a 20  pReadr->aMap);. 
6c50: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
6c60: 4f 4b 20 26 26 20 70 52 65 61 64 72 2d 3e 61 4d  OK && pReadr->aM
6c70: 61 70 3d 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74  ap==0 ){.    int
6c80: 20 70 67 73 7a 20 3d 20 70 54 61 73 6b 2d 3e 70   pgsz = pTask->p
6c90: 53 6f 72 74 65 72 2d 3e 70 67 73 7a 3b 0a 20 20  Sorter->pgsz;.  
6ca0: 20 20 69 6e 74 20 69 42 75 66 20 3d 20 70 52 65    int iBuf = pRe
6cb0: 61 64 72 2d 3e 69 52 65 61 64 4f 66 66 20 25 20  adr->iReadOff % 
6cc0: 70 67 73 7a 3b 0a 20 20 20 20 69 66 28 20 70 52  pgsz;.    if( pR
6cd0: 65 61 64 72 2d 3e 61 42 75 66 66 65 72 3d 3d 30  eadr->aBuffer==0
6ce0: 20 29 7b 0a 20 20 20 20 20 20 70 52 65 61 64 72   ){.      pReadr
6cf0: 2d 3e 61 42 75 66 66 65 72 20 3d 20 28 75 38 2a  ->aBuffer = (u8*
6d00: 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 70  )sqlite3Malloc(p
6d10: 67 73 7a 29 3b 0a 20 20 20 20 20 20 69 66 28 20  gsz);.      if( 
6d20: 70 52 65 61 64 72 2d 3e 61 42 75 66 66 65 72 3d  pReadr->aBuffer=
6d30: 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45  =0 ) rc = SQLITE
6d40: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 70 52  _NOMEM;.      pR
6d50: 65 61 64 72 2d 3e 6e 42 75 66 66 65 72 20 3d 20  eadr->nBuffer = 
6d60: 70 67 73 7a 3b 0a 20 20 20 20 7d 0a 20 20 20 20  pgsz;.    }.    
6d70: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
6d80: 4b 20 26 26 20 69 42 75 66 20 29 7b 0a 20 20 20  K && iBuf ){.   
6d90: 20 20 20 69 6e 74 20 6e 52 65 61 64 20 3d 20 70     int nRead = p
6da0: 67 73 7a 20 2d 20 69 42 75 66 3b 0a 20 20 20 20  gsz - iBuf;.    
6db0: 20 20 69 66 28 20 28 70 52 65 61 64 72 2d 3e 69    if( (pReadr->i
6dc0: 52 65 61 64 4f 66 66 20 2b 20 6e 52 65 61 64 29  ReadOff + nRead)
6dd0: 20 3e 20 70 52 65 61 64 72 2d 3e 69 45 6f 66 20   > pReadr->iEof 
6de0: 29 7b 0a 20 20 20 20 20 20 20 20 6e 52 65 61 64  ){.        nRead
6df0: 20 3d 20 28 69 6e 74 29 28 70 52 65 61 64 72 2d   = (int)(pReadr-
6e00: 3e 69 45 6f 66 20 2d 20 70 52 65 61 64 72 2d 3e  >iEof - pReadr->
6e10: 69 52 65 61 64 4f 66 66 29 3b 0a 20 20 20 20 20  iReadOff);.     
6e20: 20 7d 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71   }.      rc = sq
6e30: 6c 69 74 65 33 4f 73 52 65 61 64 28 0a 20 20 20  lite3OsRead(.   
6e40: 20 20 20 20 20 20 20 70 52 65 61 64 72 2d 3e 70         pReadr->p
6e50: 46 64 2c 20 26 70 52 65 61 64 72 2d 3e 61 42 75  Fd, &pReadr->aBu
6e60: 66 66 65 72 5b 69 42 75 66 5d 2c 20 6e 52 65 61  ffer[iBuf], nRea
6e70: 64 2c 20 70 52 65 61 64 72 2d 3e 69 52 65 61 64  d, pReadr->iRead
6e80: 4f 66 66 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  Off.      );.   
6e90: 20 20 20 74 65 73 74 63 61 73 65 28 20 72 63 21     testcase( rc!
6ea0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20  =SQLITE_OK );.  
6eb0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
6ec0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  n rc;.}../*.** A
6ed0: 64 76 61 6e 63 65 20 50 6d 61 52 65 61 64 65 72  dvance PmaReader
6ee0: 20 70 52 65 61 64 72 20 74 6f 20 74 68 65 20 6e   pReadr to the n
6ef0: 65 78 74 20 6b 65 79 20 69 6e 20 69 74 73 20 50  ext key in its P
6f00: 4d 41 2e 20 52 65 74 75 72 6e 20 53 51 4c 49 54  MA. Return SQLIT
6f10: 45 5f 4f 4b 20 69 66 0a 2a 2a 20 6e 6f 20 65 72  E_OK if.** no er
6f20: 72 6f 72 20 6f 63 63 75 72 73 2c 20 6f 72 20 61  ror occurs, or a
6f30: 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  n SQLite error c
6f40: 6f 64 65 20 69 66 20 6f 6e 65 20 64 6f 65 73 2e  ode if one does.
6f50: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
6f60: 64 62 65 50 6d 61 52 65 61 64 65 72 4e 65 78 74  dbePmaReaderNext
6f70: 28 50 6d 61 52 65 61 64 65 72 20 2a 70 52 65 61  (PmaReader *pRea
6f80: 64 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  dr){.  int rc = 
6f90: 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20  SQLITE_OK;      
6fa0: 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
6fb0: 20 43 6f 64 65 20 2a 2f 0a 20 20 75 36 34 20 6e   Code */.  u64 n
6fc0: 52 65 63 20 3d 20 30 3b 20 20 20 20 20 20 20 20  Rec = 0;        
6fd0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
6fe0: 7a 65 20 6f 66 20 72 65 63 6f 72 64 20 69 6e 20  ze of record in 
6ff0: 62 79 74 65 73 20 2a 2f 0a 0a 0a 20 20 69 66 28  bytes */...  if(
7000: 20 70 52 65 61 64 72 2d 3e 69 52 65 61 64 4f 66   pReadr->iReadOf
7010: 66 3e 3d 70 52 65 61 64 72 2d 3e 69 45 6f 66 20  f>=pReadr->iEof 
7020: 29 7b 0a 20 20 20 20 49 6e 63 72 4d 65 72 67 65  ){.    IncrMerge
7030: 72 20 2a 70 49 6e 63 72 20 3d 20 70 52 65 61 64  r *pIncr = pRead
7040: 72 2d 3e 70 49 6e 63 72 3b 0a 20 20 20 20 69 6e  r->pIncr;.    in
7050: 74 20 62 45 6f 66 20 3d 20 31 3b 0a 20 20 20 20  t bEof = 1;.    
7060: 69 66 28 20 70 49 6e 63 72 20 29 7b 0a 20 20 20  if( pIncr ){.   
7070: 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72     rc = vdbeIncr
7080: 53 77 61 70 28 70 49 6e 63 72 29 3b 0a 20 20 20  Swap(pIncr);.   
7090: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
70a0: 45 5f 4f 4b 20 26 26 20 70 49 6e 63 72 2d 3e 62  E_OK && pIncr->b
70b0: 45 6f 66 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  Eof==0 ){.      
70c0: 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65    rc = vdbePmaRe
70d0: 61 64 65 72 53 65 65 6b 28 0a 20 20 20 20 20 20  aderSeek(.      
70e0: 20 20 20 20 20 20 70 49 6e 63 72 2d 3e 70 54 61        pIncr->pTa
70f0: 73 6b 2c 20 70 52 65 61 64 72 2c 20 26 70 49 6e  sk, pReadr, &pIn
7100: 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2c 20 70 49  cr->aFile[0], pI
7110: 6e 63 72 2d 3e 69 53 74 61 72 74 4f 66 66 0a 20  ncr->iStartOff. 
7120: 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20         );.      
7130: 20 20 62 45 6f 66 20 3d 20 30 3b 0a 20 20 20 20    bEof = 0;.    
7140: 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69    }.    }..    i
7150: 66 28 20 62 45 6f 66 20 29 7b 0a 20 20 20 20 20  f( bEof ){.     
7160: 20 2f 2a 20 54 68 69 73 20 69 73 20 61 6e 20 45   /* This is an E
7170: 4f 46 20 63 6f 6e 64 69 74 69 6f 6e 20 2a 2f 0a  OF condition */.
7180: 20 20 20 20 20 20 76 64 62 65 50 6d 61 52 65 61        vdbePmaRea
7190: 64 65 72 43 6c 65 61 72 28 70 52 65 61 64 72 29  derClear(pReadr)
71a0: 3b 0a 20 20 20 20 20 20 74 65 73 74 63 61 73 65  ;.      testcase
71b0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
71c0: 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  );.      return 
71d0: 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  rc;.    }.  }.. 
71e0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
71f0: 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 76  OK ){.    rc = v
7200: 64 62 65 50 6d 61 52 65 61 64 56 61 72 69 6e 74  dbePmaReadVarint
7210: 28 70 52 65 61 64 72 2c 20 26 6e 52 65 63 29 3b  (pReadr, &nRec);
7220: 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53  .  }.  if( rc==S
7230: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
7240: 70 52 65 61 64 72 2d 3e 6e 4b 65 79 20 3d 20 28  pReadr->nKey = (
7250: 69 6e 74 29 6e 52 65 63 3b 0a 20 20 20 20 72 63  int)nRec;.    rc
7260: 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 42 6c   = vdbePmaReadBl
7270: 6f 62 28 70 52 65 61 64 72 2c 20 28 69 6e 74 29  ob(pReadr, (int)
7280: 6e 52 65 63 2c 20 26 70 52 65 61 64 72 2d 3e 61  nRec, &pReadr->a
7290: 4b 65 79 29 3b 0a 20 20 20 20 74 65 73 74 63 61  Key);.    testca
72a0: 73 65 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  se( rc!=SQLITE_O
72b0: 4b 20 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  K );.  }..  retu
72c0: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
72d0: 49 6e 69 74 69 61 6c 69 7a 65 20 50 6d 61 52 65  Initialize PmaRe
72e0: 61 64 65 72 20 70 52 65 61 64 72 20 74 6f 20 73  ader pReadr to s
72f0: 63 61 6e 20 74 68 72 6f 75 67 68 20 74 68 65 20  can through the 
7300: 50 4d 41 20 73 74 6f 72 65 64 20 69 6e 20 66 69  PMA stored in fi
7310: 6c 65 20 70 46 69 6c 65 0a 2a 2a 20 73 74 61 72  le pFile.** star
7320: 74 69 6e 67 20 61 74 20 6f 66 66 73 65 74 20 69  ting at offset i
7330: 53 74 61 72 74 20 61 6e 64 20 65 6e 64 69 6e 67  Start and ending
7340: 20 61 74 20 6f 66 66 73 65 74 20 69 45 6f 66 2d   at offset iEof-
7350: 31 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  1. This function
7360: 20 0a 2a 2a 20 6c 65 61 76 65 73 20 74 68 65 20   .** leaves the 
7370: 50 6d 61 52 65 61 64 65 72 20 70 6f 69 6e 74 69  PmaReader pointi
7380: 6e 67 20 74 6f 20 74 68 65 20 66 69 72 73 74 20  ng to the first 
7390: 6b 65 79 20 69 6e 20 74 68 65 20 50 4d 41 20 28  key in the PMA (
73a0: 6f 72 20 45 4f 46 20 69 66 20 74 68 65 20 0a 2a  or EOF if the .*
73b0: 2a 20 50 4d 41 20 69 73 20 65 6d 70 74 79 29 2e  * PMA is empty).
73c0: 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 70 6e  .**.** If the pn
73d0: 42 79 74 65 20 70 61 72 61 6d 65 74 65 72 20 69  Byte parameter i
73e0: 73 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 69 74 20  s NULL, then it 
73f0: 69 73 20 61 73 73 75 6d 65 64 20 74 68 61 74 20  is assumed that 
7400: 74 68 65 20 66 69 6c 65 20 0a 2a 2a 20 63 6f 6e  the file .** con
7410: 74 61 69 6e 73 20 61 20 73 69 6e 67 6c 65 20 50  tains a single P
7420: 4d 41 2c 20 61 6e 64 20 74 68 61 74 20 74 68 61  MA, and that tha
7430: 74 20 50 4d 41 20 6f 6d 69 74 73 20 74 68 65 20  t PMA omits the 
7440: 69 6e 69 74 69 61 6c 20 6c 65 6e 67 74 68 20 76  initial length v
7450: 61 72 69 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  arint..*/.static
7460: 20 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61 64   int vdbePmaRead
7470: 65 72 49 6e 69 74 28 0a 20 20 53 6f 72 74 53 75  erInit(.  SortSu
7480: 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20  btask *pTask,   
7490: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 73            /* Tas
74a0: 6b 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 53  k context */.  S
74b0: 6f 72 74 65 72 46 69 6c 65 20 2a 70 46 69 6c 65  orterFile *pFile
74c0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
74d0: 2a 20 53 6f 72 74 65 72 20 66 69 6c 65 20 74 6f  * Sorter file to
74e0: 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20   read from */.  
74f0: 69 36 34 20 69 53 74 61 72 74 2c 20 20 20 20 20  i64 iStart,     
7500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7510: 2f 2a 20 53 74 61 72 74 20 6f 66 66 73 65 74 20  /* Start offset 
7520: 69 6e 20 70 46 69 6c 65 20 2a 2f 0a 20 20 50 6d  in pFile */.  Pm
7530: 61 52 65 61 64 65 72 20 2a 70 52 65 61 64 72 2c  aReader *pReadr,
7540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7550: 20 50 6d 61 52 65 61 64 65 72 20 74 6f 20 70 6f   PmaReader to po
7560: 70 75 6c 61 74 65 20 2a 2f 0a 20 20 69 36 34 20  pulate */.  i64 
7570: 2a 70 6e 42 79 74 65 20 20 20 20 20 20 20 20 20  *pnByte         
7580: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
7590: 4e 2f 4f 55 54 3a 20 49 6e 63 72 65 6d 65 6e 74  N/OUT: Increment
75a0: 20 74 68 69 73 20 76 61 6c 75 65 20 62 79 20 50   this value by P
75b0: 4d 41 20 73 69 7a 65 20 2a 2f 0a 29 7b 0a 20 20  MA size */.){.  
75c0: 69 6e 74 20 72 63 3b 0a 0a 20 20 61 73 73 65 72  int rc;..  asser
75d0: 74 28 20 70 46 69 6c 65 2d 3e 69 45 6f 66 3e 69  t( pFile->iEof>i
75e0: 53 74 61 72 74 20 29 3b 0a 20 20 61 73 73 65 72  Start );.  asser
75f0: 74 28 20 70 52 65 61 64 72 2d 3e 61 41 6c 6c 6f  t( pReadr->aAllo
7600: 63 3d 3d 30 20 26 26 20 70 52 65 61 64 72 2d 3e  c==0 && pReadr->
7610: 6e 41 6c 6c 6f 63 3d 3d 30 20 29 3b 0a 20 20 61  nAlloc==0 );.  a
7620: 73 73 65 72 74 28 20 70 52 65 61 64 72 2d 3e 61  ssert( pReadr->a
7630: 42 75 66 66 65 72 3d 3d 30 20 29 3b 0a 20 20 61  Buffer==0 );.  a
7640: 73 73 65 72 74 28 20 70 52 65 61 64 72 2d 3e 61  ssert( pReadr->a
7650: 4d 61 70 3d 3d 30 20 29 3b 0a 0a 20 20 72 63 20  Map==0 );..  rc 
7660: 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 53  = vdbePmaReaderS
7670: 65 65 6b 28 70 54 61 73 6b 2c 20 70 52 65 61 64  eek(pTask, pRead
7680: 72 2c 20 70 46 69 6c 65 2c 20 69 53 74 61 72 74  r, pFile, iStart
7690: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  );.  if( rc==SQL
76a0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 75 36  ITE_OK ){.    u6
76b0: 34 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20  4 nByte;        
76c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
76d0: 69 7a 65 20 6f 66 20 50 4d 41 20 69 6e 20 62 79  ize of PMA in by
76e0: 74 65 73 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20  tes */.    rc = 
76f0: 76 64 62 65 50 6d 61 52 65 61 64 56 61 72 69 6e  vdbePmaReadVarin
7700: 74 28 70 52 65 61 64 72 2c 20 26 6e 42 79 74 65  t(pReadr, &nByte
7710: 29 3b 0a 20 20 20 20 70 52 65 61 64 72 2d 3e 69  );.    pReadr->i
7720: 45 6f 66 20 3d 20 70 52 65 61 64 72 2d 3e 69 52  Eof = pReadr->iR
7730: 65 61 64 4f 66 66 20 2b 20 6e 42 79 74 65 3b 0a  eadOff + nByte;.
7740: 20 20 20 20 2a 70 6e 42 79 74 65 20 2b 3d 20 6e      *pnByte += n
7750: 42 79 74 65 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  Byte;.  }..  if(
7760: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
7770: 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 50  {.    rc = vdbeP
7780: 6d 61 52 65 61 64 65 72 4e 65 78 74 28 70 52 65  maReaderNext(pRe
7790: 61 64 72 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  adr);.  }.  retu
77a0: 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a  rn rc;.}.../*.**
77b0: 20 43 6f 6d 70 61 72 65 20 6b 65 79 31 20 28 62   Compare key1 (b
77c0: 75 66 66 65 72 20 70 4b 65 79 31 2c 20 73 69 7a  uffer pKey1, siz
77d0: 65 20 6e 4b 65 79 31 20 62 79 74 65 73 29 20 77  e nKey1 bytes) w
77e0: 69 74 68 20 6b 65 79 32 20 28 62 75 66 66 65 72  ith key2 (buffer
77f0: 20 70 4b 65 79 32 2c 20 0a 2a 2a 20 73 69 7a 65   pKey2, .** size
7800: 20 6e 4b 65 79 32 20 62 79 74 65 73 29 2e 20 55   nKey2 bytes). U
7810: 73 65 20 28 70 54 61 73 6b 2d 3e 70 4b 65 79 49  se (pTask->pKeyI
7820: 6e 66 6f 29 20 66 6f 72 20 74 68 65 20 63 6f 6c  nfo) for the col
7830: 6c 61 74 69 6f 6e 20 73 65 71 75 65 6e 63 65 73  lation sequences
7840: 0a 2a 2a 20 75 73 65 64 20 62 79 20 74 68 65 20  .** used by the 
7850: 63 6f 6d 70 61 72 69 73 6f 6e 2e 20 52 65 74 75  comparison. Retu
7860: 72 6e 20 74 68 65 20 72 65 73 75 6c 74 20 6f 66  rn the result of
7870: 20 74 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2e   the comparison.
7880: 0a 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65 20 72 65  .**.** Before re
7890: 74 75 72 6e 69 6e 67 2c 20 6f 62 6a 65 63 74 20  turning, object 
78a0: 28 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65  (pTask->pUnpacke
78b0: 64 29 20 69 73 20 70 6f 70 75 6c 61 74 65 64 20  d) is populated 
78c0: 77 69 74 68 20 74 68 65 0a 2a 2a 20 75 6e 70 61  with the.** unpa
78d0: 63 6b 65 64 20 76 65 72 73 69 6f 6e 20 6f 66 20  cked version of 
78e0: 6b 65 79 32 2e 20 4f 72 2c 20 69 66 20 70 4b 65  key2. Or, if pKe
78f0: 79 32 20 69 73 20 70 61 73 73 65 64 20 61 20 4e  y2 is passed a N
7900: 55 4c 4c 20 70 6f 69 6e 74 65 72 2c 20 74 68 65  ULL pointer, the
7910: 6e 20 69 74 20 0a 2a 2a 20 69 73 20 61 73 73 75  n it .** is assu
7920: 6d 65 64 20 74 68 61 74 20 74 68 65 20 28 70 54  med that the (pT
7930: 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 29 20  ask->pUnpacked) 
7940: 73 74 72 75 63 74 75 72 65 20 61 6c 72 65 61 64  structure alread
7950: 79 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 0a  y contains the .
7960: 2a 2a 20 75 6e 70 61 63 6b 65 64 20 6b 65 79 20  ** unpacked key 
7970: 74 6f 20 75 73 65 20 61 73 20 6b 65 79 32 2e 0a  to use as key2..
7980: 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20  **.** If an OOM 
7990: 65 72 72 6f 72 20 69 73 20 65 6e 63 6f 75 6e 74  error is encount
79a0: 65 72 65 64 2c 20 28 70 54 61 73 6b 2d 3e 70 55  ered, (pTask->pU
79b0: 6e 70 61 63 6b 65 64 2d 3e 65 72 72 6f 72 5f 72  npacked->error_r
79c0: 63 29 20 69 73 20 73 65 74 0a 2a 2a 20 74 6f 20  c) is set.** to 
79d0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 2e 0a 2a 2f  SQLITE_NOMEM..*/
79e0: 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65  .static int vdbe
79f0: 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 0a 20  SorterCompare(. 
7a00: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
7a10: 61 73 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20  ask,            
7a20: 20 2f 2a 20 53 75 62 74 61 73 6b 20 63 6f 6e 74   /* Subtask cont
7a30: 65 78 74 20 28 66 6f 72 20 70 4b 65 79 49 6e 66  ext (for pKeyInf
7a40: 6f 29 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f  o) */.  const vo
7a50: 69 64 20 2a 70 4b 65 79 31 2c 20 69 6e 74 20 6e  id *pKey1, int n
7a60: 4b 65 79 31 2c 20 20 20 2f 2a 20 4c 65 66 74 20  Key1,   /* Left 
7a70: 73 69 64 65 20 6f 66 20 63 6f 6d 70 61 72 69 73  side of comparis
7a80: 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f  on */.  const vo
7a90: 69 64 20 2a 70 4b 65 79 32 2c 20 69 6e 74 20 6e  id *pKey2, int n
7aa0: 4b 65 79 32 20 20 20 20 2f 2a 20 52 69 67 68 74  Key2    /* Right
7ab0: 20 73 69 64 65 20 6f 66 20 63 6f 6d 70 61 72 69   side of compari
7ac0: 73 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 55 6e 70 61  son */.){.  Unpa
7ad0: 63 6b 65 64 52 65 63 6f 72 64 20 2a 72 32 20 3d  ckedRecord *r2 =
7ae0: 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65   pTask->pUnpacke
7af0: 64 3b 0a 20 20 69 66 28 20 70 4b 65 79 32 20 29  d;.  if( pKey2 )
7b00: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 56 64 62  {.    sqlite3Vdb
7b10: 65 52 65 63 6f 72 64 55 6e 70 61 63 6b 28 70 54  eRecordUnpack(pT
7b20: 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 4b  ask->pSorter->pK
7b30: 65 79 49 6e 66 6f 2c 20 6e 4b 65 79 32 2c 20 70  eyInfo, nKey2, p
7b40: 4b 65 79 32 2c 20 72 32 29 3b 0a 20 20 7d 0a 20  Key2, r2);.  }. 
7b50: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 56   return sqlite3V
7b60: 64 62 65 52 65 63 6f 72 64 43 6f 6d 70 61 72 65  dbeRecordCompare
7b70: 28 6e 4b 65 79 31 2c 20 70 4b 65 79 31 2c 20 72  (nKey1, pKey1, r
7b80: 32 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  2, 0);.}../*.** 
7b90: 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 74  Initialize the t
7ba0: 65 6d 70 6f 72 61 72 79 20 69 6e 64 65 78 20 63  emporary index c
7bb0: 75 72 73 6f 72 20 6a 75 73 74 20 6f 70 65 6e 65  ursor just opene
7bc0: 64 20 61 73 20 61 20 73 6f 72 74 65 72 20 63 75  d as a sorter cu
7bd0: 72 73 6f 72 2e 0a 2a 2a 0a 2a 2a 20 55 73 75 61  rsor..**.** Usua
7be0: 6c 6c 79 2c 20 74 68 65 20 73 6f 72 74 65 72 20  lly, the sorter 
7bf0: 6d 6f 64 75 6c 65 20 75 73 65 73 20 74 68 65 20  module uses the 
7c00: 76 61 6c 75 65 20 6f 66 20 28 70 43 73 72 2d 3e  value of (pCsr->
7c10: 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64  pKeyInfo->nField
7c20: 29 0a 2a 2a 20 74 6f 20 64 65 74 65 72 6d 69 6e  ).** to determin
7c30: 65 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  e the number of 
7c40: 66 69 65 6c 64 73 20 74 68 61 74 20 73 68 6f 75  fields that shou
7c50: 6c 64 20 62 65 20 63 6f 6d 70 61 72 65 64 20 66  ld be compared f
7c60: 72 6f 6d 20 74 68 65 0a 2a 2a 20 72 65 63 6f 72  rom the.** recor
7c70: 64 73 20 62 65 69 6e 67 20 73 6f 72 74 65 64 2e  ds being sorted.
7c80: 20 48 6f 77 65 76 65 72 2c 20 69 66 20 74 68 65   However, if the
7c90: 20 76 61 6c 75 65 20 70 61 73 73 65 64 20 61 73   value passed as
7ca0: 20 61 72 67 75 6d 65 6e 74 20 6e 46 69 65 6c 64   argument nField
7cb0: 0a 2a 2a 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 20  .** is non-zero 
7cc0: 61 6e 64 20 74 68 65 20 73 6f 72 74 65 72 20 69  and the sorter i
7cd0: 73 20 61 62 6c 65 20 74 6f 20 67 75 61 72 61 6e  s able to guaran
7ce0: 74 65 65 20 61 20 73 74 61 62 6c 65 20 73 6f 72  tee a stable sor
7cf0: 74 2c 20 6e 46 69 65 6c 64 0a 2a 2a 20 69 73 20  t, nField.** is 
7d00: 75 73 65 64 20 69 6e 73 74 65 61 64 2e 20 54 68  used instead. Th
7d10: 69 73 20 69 73 20 75 73 65 64 20 77 68 65 6e 20  is is used when 
7d20: 73 6f 72 74 69 6e 67 20 72 65 63 6f 72 64 73 20  sorting records 
7d30: 66 6f 72 20 61 20 43 52 45 41 54 45 20 49 4e 44  for a CREATE IND
7d40: 45 58 0a 2a 2a 20 73 74 61 74 65 6d 65 6e 74 2e  EX.** statement.
7d50: 20 49 6e 20 74 68 69 73 20 63 61 73 65 2c 20 6b   In this case, k
7d60: 65 79 73 20 61 72 65 20 61 6c 77 61 79 73 20 64  eys are always d
7d70: 65 6c 69 76 65 72 65 64 20 74 6f 20 74 68 65 20  elivered to the 
7d80: 73 6f 72 74 65 72 20 69 6e 0a 2a 2a 20 6f 72 64  sorter in.** ord
7d90: 65 72 20 6f 66 20 74 68 65 20 70 72 69 6d 61 72  er of the primar
7da0: 79 20 6b 65 79 2c 20 77 68 69 63 68 20 68 61 70  y key, which hap
7db0: 70 65 6e 73 20 74 6f 20 62 65 20 6d 61 6b 65 20  pens to be make 
7dc0: 75 70 20 74 68 65 20 66 69 6e 61 6c 20 70 61 72  up the final par
7dd0: 74 20 0a 2a 2a 20 6f 66 20 74 68 65 20 72 65 63  t .** of the rec
7de0: 6f 72 64 73 20 62 65 69 6e 67 20 73 6f 72 74 65  ords being sorte
7df0: 64 2e 20 53 6f 20 69 66 20 74 68 65 20 73 6f 72  d. So if the sor
7e00: 74 20 69 73 20 73 74 61 62 6c 65 2c 20 74 68 65  t is stable, the
7e10: 72 65 20 69 73 20 6e 65 76 65 72 0a 2a 2a 20 61  re is never.** a
7e20: 6e 79 20 72 65 61 73 6f 6e 20 74 6f 20 63 6f 6d  ny reason to com
7e30: 70 61 72 65 20 50 4b 20 66 69 65 6c 64 73 20 61  pare PK fields a
7e40: 6e 64 20 74 68 65 79 20 63 61 6e 20 62 65 20 69  nd they can be i
7e50: 67 6e 6f 72 65 64 20 66 6f 72 20 61 20 73 6d 61  gnored for a sma
7e60: 6c 6c 0a 2a 2a 20 70 65 72 66 6f 72 6d 61 6e 63  ll.** performanc
7e70: 65 20 62 6f 6f 73 74 2e 0a 2a 2a 0a 2a 2a 20 54  e boost..**.** T
7e80: 68 65 20 73 6f 72 74 65 72 20 63 61 6e 20 67 75  he sorter can gu
7e90: 61 72 61 6e 74 65 65 20 61 20 73 74 61 62 6c 65  arantee a stable
7ea0: 20 73 6f 72 74 20 77 68 65 6e 20 72 75 6e 6e 69   sort when runni
7eb0: 6e 67 20 69 6e 20 73 69 6e 67 6c 65 2d 74 68 72  ng in single-thr
7ec0: 65 61 64 65 64 0a 2a 2a 20 6d 6f 64 65 2c 20 62  eaded.** mode, b
7ed0: 75 74 20 6e 6f 74 20 69 6e 20 6d 75 6c 74 69 2d  ut not in multi-
7ee0: 74 68 72 65 61 64 65 64 20 6d 6f 64 65 2e 0a 2a  threaded mode..*
7ef0: 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69  *.** SQLITE_OK i
7f00: 73 20 72 65 74 75 72 6e 65 64 20 69 66 20 73 75  s returned if su
7f10: 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20  ccessful, or an 
7f20: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
7f30: 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a  e otherwise..*/.
7f40: 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65 53  int sqlite3VdbeS
7f50: 6f 72 74 65 72 49 6e 69 74 28 0a 20 20 73 71 6c  orterInit(.  sql
7f60: 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20  ite3 *db,       
7f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7f80: 44 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74  Database connect
7f90: 69 6f 6e 20 28 66 6f 72 20 6d 61 6c 6c 6f 63 28  ion (for malloc(
7fa0: 29 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 46 69 65  )) */.  int nFie
7fb0: 6c 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ld,             
7fc0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
7fd0: 72 20 6f 66 20 6b 65 79 20 66 69 65 6c 64 73 20  r of key fields 
7fe0: 69 6e 20 65 61 63 68 20 72 65 63 6f 72 64 20 2a  in each record *
7ff0: 2f 0a 20 20 56 64 62 65 43 75 72 73 6f 72 20 2a  /.  VdbeCursor *
8000: 70 43 73 72 20 20 20 20 20 20 20 20 20 20 20 20  pCsr            
8010: 20 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 74 68      /* Cursor th
8020: 61 74 20 68 6f 6c 64 73 20 74 68 65 20 6e 65 77  at holds the new
8030: 20 73 6f 72 74 65 72 20 2a 2f 0a 29 7b 0a 20 20   sorter */.){.  
8040: 69 6e 74 20 70 67 73 7a 3b 20 20 20 20 20 20 20  int pgsz;       
8050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8060: 2f 2a 20 50 61 67 65 20 73 69 7a 65 20 6f 66 20  /* Page size of 
8070: 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20 2a 2f  main database */
8080: 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20  .  int i;       
8090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
80a0: 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69 74     /* Used to it
80b0: 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 61 54  erate through aT
80c0: 61 73 6b 5b 5d 20 2a 2f 0a 20 20 69 6e 74 20 6d  ask[] */.  int m
80d0: 78 43 61 63 68 65 3b 20 20 20 20 20 20 20 20 20  xCache;         
80e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61             /* Ca
80f0: 63 68 65 20 73 69 7a 65 20 2a 2f 0a 20 20 56 64  che size */.  Vd
8100: 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
8110: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  r;            /*
8120: 20 54 68 65 20 6e 65 77 20 73 6f 72 74 65 72 20   The new sorter 
8130: 2a 2f 0a 20 20 4b 65 79 49 6e 66 6f 20 2a 70 4b  */.  KeyInfo *pK
8140: 65 79 49 6e 66 6f 3b 20 20 20 20 20 20 20 20 20  eyInfo;         
8150: 20 20 20 20 20 2f 2a 20 43 6f 70 79 20 6f 66 20       /* Copy of 
8160: 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 20 77  pCsr->pKeyInfo w
8170: 69 74 68 20 64 62 3d 3d 30 20 2a 2f 0a 20 20 69  ith db==0 */.  i
8180: 6e 74 20 73 7a 4b 65 79 49 6e 66 6f 3b 20 20 20  nt szKeyInfo;   
8190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
81a0: 2a 20 53 69 7a 65 20 6f 66 20 70 43 73 72 2d 3e  * Size of pCsr->
81b0: 70 4b 65 79 49 6e 66 6f 20 69 6e 20 62 79 74 65  pKeyInfo in byte
81c0: 73 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 3b 20 20  s */.  int sz;  
81d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
81e0: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
81f0: 66 20 70 53 6f 72 74 65 72 20 69 6e 20 62 79 74  f pSorter in byt
8200: 65 73 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d  es */.  int rc =
8210: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 23 69 66 20   SQLITE_OK;.#if 
8220: 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45  SQLITE_MAX_WORKE
8230: 52 5f 54 48 52 45 41 44 53 3d 3d 30 0a 23 20 64  R_THREADS==0.# d
8240: 65 66 69 6e 65 20 6e 57 6f 72 6b 65 72 20 30 0a  efine nWorker 0.
8250: 23 65 6c 73 65 0a 20 20 69 6e 74 20 6e 57 6f 72  #else.  int nWor
8260: 6b 65 72 20 3d 20 28 73 71 6c 69 74 65 33 47 6c  ker = (sqlite3Gl
8270: 6f 62 61 6c 43 6f 6e 66 69 67 2e 62 43 6f 72 65  obalConfig.bCore
8280: 4d 75 74 65 78 3f 73 71 6c 69 74 65 33 47 6c 6f  Mutex?sqlite3Glo
8290: 62 61 6c 43 6f 6e 66 69 67 2e 6e 57 6f 72 6b 65  balConfig.nWorke
82a0: 72 3a 30 29 3b 0a 23 65 6e 64 69 66 0a 0a 20 20  r:0);.#endif..  
82b0: 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e 70 4b  assert( pCsr->pK
82c0: 65 79 49 6e 66 6f 20 26 26 20 70 43 73 72 2d 3e  eyInfo && pCsr->
82d0: 70 42 74 3d 3d 30 20 29 3b 0a 20 20 73 7a 4b 65  pBt==0 );.  szKe
82e0: 79 49 6e 66 6f 20 3d 20 73 69 7a 65 6f 66 28 4b  yInfo = sizeof(K
82f0: 65 79 49 6e 66 6f 29 20 2b 20 28 70 43 73 72 2d  eyInfo) + (pCsr-
8300: 3e 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c  >pKeyInfo->nFiel
8310: 64 2d 31 29 2a 73 69 7a 65 6f 66 28 43 6f 6c 6c  d-1)*sizeof(Coll
8320: 53 65 71 2a 29 3b 0a 20 20 73 7a 20 3d 20 73 69  Seq*);.  sz = si
8330: 7a 65 6f 66 28 56 64 62 65 53 6f 72 74 65 72 29  zeof(VdbeSorter)
8340: 20 2b 20 6e 57 6f 72 6b 65 72 20 2a 20 73 69 7a   + nWorker * siz
8350: 65 6f 66 28 53 6f 72 74 53 75 62 74 61 73 6b 29  eof(SortSubtask)
8360: 3b 0a 0a 20 20 70 53 6f 72 74 65 72 20 3d 20 28  ;..  pSorter = (
8370: 56 64 62 65 53 6f 72 74 65 72 2a 29 73 71 6c 69  VdbeSorter*)sqli
8380: 74 65 33 44 62 4d 61 6c 6c 6f 63 5a 65 72 6f 28  te3DbMallocZero(
8390: 64 62 2c 20 73 7a 20 2b 20 73 7a 4b 65 79 49 6e  db, sz + szKeyIn
83a0: 66 6f 29 3b 0a 20 20 70 43 73 72 2d 3e 70 53 6f  fo);.  pCsr->pSo
83b0: 72 74 65 72 20 3d 20 70 53 6f 72 74 65 72 3b 0a  rter = pSorter;.
83c0: 20 20 69 66 28 20 70 53 6f 72 74 65 72 3d 3d 30    if( pSorter==0
83d0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   ){.    rc = SQL
83e0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c  ITE_NOMEM;.  }el
83f0: 73 65 7b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d  se{.    pSorter-
8400: 3e 70 4b 65 79 49 6e 66 6f 20 3d 20 70 4b 65 79  >pKeyInfo = pKey
8410: 49 6e 66 6f 20 3d 20 28 4b 65 79 49 6e 66 6f 2a  Info = (KeyInfo*
8420: 29 28 28 75 38 2a 29 70 53 6f 72 74 65 72 20 2b  )((u8*)pSorter +
8430: 20 73 7a 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79   sz);.    memcpy
8440: 28 70 4b 65 79 49 6e 66 6f 2c 20 70 43 73 72 2d  (pKeyInfo, pCsr-
8450: 3e 70 4b 65 79 49 6e 66 6f 2c 20 73 7a 4b 65 79  >pKeyInfo, szKey
8460: 49 6e 66 6f 29 3b 0a 20 20 20 20 70 4b 65 79 49  Info);.    pKeyI
8470: 6e 66 6f 2d 3e 64 62 20 3d 20 30 3b 0a 20 20 20  nfo->db = 0;.   
8480: 20 69 66 28 20 6e 46 69 65 6c 64 20 26 26 20 6e   if( nField && n
8490: 57 6f 72 6b 65 72 3d 3d 30 20 29 20 70 4b 65 79  Worker==0 ) pKey
84a0: 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64 20 3d 20 6e  Info->nField = n
84b0: 46 69 65 6c 64 3b 0a 20 20 20 20 70 53 6f 72 74  Field;.    pSort
84c0: 65 72 2d 3e 70 67 73 7a 20 3d 20 70 67 73 7a 20  er->pgsz = pgsz 
84d0: 3d 20 73 71 6c 69 74 65 33 42 74 72 65 65 47 65  = sqlite3BtreeGe
84e0: 74 50 61 67 65 53 69 7a 65 28 64 62 2d 3e 61 44  tPageSize(db->aD
84f0: 62 5b 30 5d 2e 70 42 74 29 3b 0a 20 20 20 20 70  b[0].pBt);.    p
8500: 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 20 3d 20  Sorter->nTask = 
8510: 6e 57 6f 72 6b 65 72 20 2b 20 31 3b 0a 20 20 20  nWorker + 1;.   
8520: 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68   pSorter->bUseTh
8530: 72 65 61 64 73 20 3d 20 28 70 53 6f 72 74 65 72  reads = (pSorter
8540: 2d 3e 6e 54 61 73 6b 3e 31 29 3b 0a 20 20 20 20  ->nTask>1);.    
8550: 70 53 6f 72 74 65 72 2d 3e 64 62 20 3d 20 64 62  pSorter->db = db
8560: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69  ;.    for(i=0; i
8570: 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3b  <pSorter->nTask;
8580: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 53 6f 72   i++){.      Sor
8590: 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 20  tSubtask *pTask 
85a0: 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73  = &pSorter->aTas
85b0: 6b 5b 69 5d 3b 0a 20 20 20 20 20 20 70 54 61 73  k[i];.      pTas
85c0: 6b 2d 3e 70 53 6f 72 74 65 72 20 3d 20 70 53 6f  k->pSorter = pSo
85d0: 72 74 65 72 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  rter;.    }..   
85e0: 20 69 66 28 20 21 73 71 6c 69 74 65 33 54 65 6d   if( !sqlite3Tem
85f0: 70 49 6e 4d 65 6d 6f 72 79 28 64 62 29 20 29 7b  pInMemory(db) ){
8600: 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  .      pSorter->
8610: 6d 6e 50 6d 61 53 69 7a 65 20 3d 20 53 4f 52 54  mnPmaSize = SORT
8620: 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20 2a  ER_MIN_WORKING *
8630: 20 70 67 73 7a 3b 0a 20 20 20 20 20 20 6d 78 43   pgsz;.      mxC
8640: 61 63 68 65 20 3d 20 64 62 2d 3e 61 44 62 5b 30  ache = db->aDb[0
8650: 5d 2e 70 53 63 68 65 6d 61 2d 3e 63 61 63 68 65  ].pSchema->cache
8660: 5f 73 69 7a 65 3b 0a 20 20 20 20 20 20 69 66 28  _size;.      if(
8670: 20 6d 78 43 61 63 68 65 3c 53 4f 52 54 45 52 5f   mxCache<SORTER_
8680: 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20 29 20 6d 78  MIN_WORKING ) mx
8690: 43 61 63 68 65 20 3d 20 53 4f 52 54 45 52 5f 4d  Cache = SORTER_M
86a0: 49 4e 5f 57 4f 52 4b 49 4e 47 3b 0a 20 20 20 20  IN_WORKING;.    
86b0: 20 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61    pSorter->mxPma
86c0: 53 69 7a 65 20 3d 20 6d 78 43 61 63 68 65 20 2a  Size = mxCache *
86d0: 20 70 67 73 7a 3b 0a 0a 20 20 20 20 20 20 2f 2a   pgsz;..      /*
86e0: 20 49 66 20 74 68 65 20 61 70 70 6c 69 63 61 74   If the applicat
86f0: 69 6f 6e 20 68 61 73 20 6e 6f 74 20 63 6f 6e 66  ion has not conf
8700: 69 67 75 72 65 20 73 63 72 61 74 63 68 20 6d 65  igure scratch me
8710: 6d 6f 72 79 20 75 73 69 6e 67 0a 20 20 20 20 20  mory using.     
8720: 20 2a 2a 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49   ** SQLITE_CONFI
8730: 47 5f 53 43 52 41 54 43 48 20 74 68 65 6e 20 77  G_SCRATCH then w
8740: 65 20 61 73 73 75 6d 65 20 69 74 20 69 73 20 4f  e assume it is O
8750: 4b 20 74 6f 20 64 6f 20 6c 61 72 67 65 20 6d 65  K to do large me
8760: 6d 6f 72 79 0a 20 20 20 20 20 20 2a 2a 20 61 6c  mory.      ** al
8770: 6c 6f 63 61 74 69 6f 6e 73 2e 20 20 49 66 20 73  locations.  If s
8780: 63 72 61 74 63 68 20 6d 65 6d 6f 72 79 20 68 61  cratch memory ha
8790: 73 20 62 65 65 6e 20 63 6f 6e 66 69 67 75 72 65  s been configure
87a0: 64 2c 20 74 68 65 6e 20 61 73 73 75 6d 65 0a 20  d, then assume. 
87b0: 20 20 20 20 20 2a 2a 20 6c 61 72 67 65 20 6d 65       ** large me
87c0: 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 73  mory allocations
87d0: 20 73 68 6f 75 6c 64 20 62 65 20 61 76 6f 69 64   should be avoid
87e0: 65 64 20 74 6f 20 70 72 65 76 65 6e 74 20 68 65  ed to prevent he
87f0: 61 70 0a 20 20 20 20 20 20 2a 2a 20 66 72 61 67  ap.      ** frag
8800: 6d 65 6e 74 61 74 69 6f 6e 2e 0a 20 20 20 20 20  mentation..     
8810: 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 73 71   */.      if( sq
8820: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
8830: 67 2e 70 53 63 72 61 74 63 68 3d 3d 30 20 29 7b  g.pScratch==0 ){
8840: 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28  .        assert(
8850: 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72   pSorter->iMemor
8860: 79 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 20 20  y==0 );.        
8870: 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79  pSorter->nMemory
8880: 20 3d 20 70 67 73 7a 3b 0a 20 20 20 20 20 20 20   = pgsz;.       
8890: 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61   pSorter->list.a
88a0: 4d 65 6d 6f 72 79 20 3d 20 28 75 38 2a 29 73 71  Memory = (u8*)sq
88b0: 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 70 67 73 7a  lite3Malloc(pgsz
88c0: 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 21  );.        if( !
88d0: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d  pSorter->list.aM
88e0: 65 6d 6f 72 79 20 29 20 72 63 20 3d 20 53 51 4c  emory ) rc = SQL
88f0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
8900: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
8910: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 23 75 6e  return rc;.}.#un
8920: 64 65 66 20 6e 57 6f 72 6b 65 72 20 20 20 2f 2a  def nWorker   /*
8930: 20 44 65 66 69 6e 65 64 20 61 74 20 74 68 65 20   Defined at the 
8940: 74 6f 70 20 6f 66 20 74 68 69 73 20 66 75 6e 63  top of this func
8950: 74 69 6f 6e 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 46  tion */../*.** F
8960: 72 65 65 20 74 68 65 20 6c 69 73 74 20 6f 66 20  ree the list of 
8970: 73 6f 72 74 65 64 20 72 65 63 6f 72 64 73 20 73  sorted records s
8980: 74 61 72 74 69 6e 67 20 61 74 20 70 52 65 63 6f  tarting at pReco
8990: 72 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  rd..*/.static vo
89a0: 69 64 20 76 64 62 65 53 6f 72 74 65 72 52 65 63  id vdbeSorterRec
89b0: 6f 72 64 46 72 65 65 28 73 71 6c 69 74 65 33 20  ordFree(sqlite3 
89c0: 2a 64 62 2c 20 53 6f 72 74 65 72 52 65 63 6f 72  *db, SorterRecor
89d0: 64 20 2a 70 52 65 63 6f 72 64 29 7b 0a 20 20 53  d *pRecord){.  S
89e0: 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a  orterRecord *p;.
89f0: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
8a00: 70 4e 65 78 74 3b 0a 20 20 66 6f 72 28 70 3d 70  pNext;.  for(p=p
8a10: 52 65 63 6f 72 64 3b 20 70 3b 20 70 3d 70 4e 65  Record; p; p=pNe
8a20: 78 74 29 7b 0a 20 20 20 20 70 4e 65 78 74 20 3d  xt){.    pNext =
8a30: 20 70 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20 20 20   p->u.pNext;.   
8a40: 20 73 71 6c 69 74 65 33 44 62 46 72 65 65 28 64   sqlite3DbFree(d
8a50: 62 2c 20 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  b, p);.  }.}../*
8a60: 0a 2a 2a 20 46 72 65 65 20 61 6c 6c 20 72 65 73  .** Free all res
8a70: 6f 75 72 63 65 73 20 6f 77 6e 65 64 20 62 79 20  ources owned by 
8a80: 74 68 65 20 6f 62 6a 65 63 74 20 69 6e 64 69 63  the object indic
8a90: 61 74 65 64 20 62 79 20 61 72 67 75 6d 65 6e 74  ated by argument
8aa0: 20 70 54 61 73 6b 2e 20 41 6c 6c 20 0a 2a 2a 20   pTask. All .** 
8ab0: 66 69 65 6c 64 73 20 6f 66 20 2a 70 54 61 73 6b  fields of *pTask
8ac0: 20 61 72 65 20 7a 65 72 6f 65 64 20 62 65 66 6f   are zeroed befo
8ad0: 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2f  re returning..*/
8ae0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62  .static void vdb
8af0: 65 53 6f 72 74 53 75 62 74 61 73 6b 43 6c 65 61  eSortSubtaskClea
8b00: 6e 75 70 28 73 71 6c 69 74 65 33 20 2a 64 62 2c  nup(sqlite3 *db,
8b10: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
8b20: 61 73 6b 29 7b 0a 20 20 73 71 6c 69 74 65 33 44  ask){.  sqlite3D
8b30: 62 46 72 65 65 28 64 62 2c 20 70 54 61 73 6b 2d  bFree(db, pTask-
8b40: 3e 70 55 6e 70 61 63 6b 65 64 29 3b 0a 20 20 70  >pUnpacked);.  p
8b50: 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 20  Task->pUnpacked 
8b60: 3d 20 30 3b 0a 23 69 66 20 53 51 4c 49 54 45 5f  = 0;.#if SQLITE_
8b70: 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41  MAX_WORKER_THREA
8b80: 44 53 3e 30 0a 20 20 2f 2a 20 70 54 61 73 6b 2d  DS>0.  /* pTask-
8b90: 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 63 61  >list.aMemory ca
8ba0: 6e 20 6f 6e 6c 79 20 62 65 20 6e 6f 6e 2d 7a 65  n only be non-ze
8bb0: 72 6f 20 69 66 20 69 74 20 77 61 73 20 68 61 6e  ro if it was han
8bc0: 64 65 64 20 6d 65 6d 6f 72 79 0a 20 20 2a 2a 20  ded memory.  ** 
8bd0: 66 72 6f 6d 20 74 68 65 20 6d 61 69 6e 20 74 68  from the main th
8be0: 72 65 61 64 2e 20 20 54 68 61 74 20 6f 6e 6c 79  read.  That only
8bf0: 20 6f 63 63 75 72 73 20 53 51 4c 49 54 45 5f 4d   occurs SQLITE_M
8c00: 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44  AX_WORKER_THREAD
8c10: 53 3e 30 20 2a 2f 0a 20 20 69 66 28 20 70 54 61  S>0 */.  if( pTa
8c20: 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  sk->list.aMemory
8c30: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
8c40: 66 72 65 65 28 70 54 61 73 6b 2d 3e 6c 69 73 74  free(pTask->list
8c50: 2e 61 4d 65 6d 6f 72 79 29 3b 0a 20 20 20 20 70  .aMemory);.    p
8c60: 54 61 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f  Task->list.aMemo
8c70: 72 79 20 3d 20 30 3b 0a 20 20 7d 65 6c 73 65 0a  ry = 0;.  }else.
8c80: 23 65 6e 64 69 66 0a 20 20 7b 0a 20 20 20 20 61  #endif.  {.    a
8c90: 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 6c 69  ssert( pTask->li
8ca0: 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30 20 29 3b  st.aMemory==0 );
8cb0: 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 52  .    vdbeSorterR
8cc0: 65 63 6f 72 64 46 72 65 65 28 30 2c 20 70 54 61  ecordFree(0, pTa
8cd0: 73 6b 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 29 3b  sk->list.pList);
8ce0: 0a 20 20 7d 0a 20 20 70 54 61 73 6b 2d 3e 6c 69  .  }.  pTask->li
8cf0: 73 74 2e 70 4c 69 73 74 20 3d 20 30 3b 0a 20 20  st.pList = 0;.  
8d00: 69 66 28 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e  if( pTask->file.
8d10: 70 46 64 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  pFd ){.    sqlit
8d20: 65 33 4f 73 43 6c 6f 73 65 46 72 65 65 28 70 54  e3OsCloseFree(pT
8d30: 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64 29 3b 0a  ask->file.pFd);.
8d40: 20 20 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e      pTask->file.
8d50: 70 46 64 20 3d 20 30 3b 0a 20 20 20 20 70 54 61  pFd = 0;.    pTa
8d60: 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 20 3d 20  sk->file.iEof = 
8d70: 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 54 61  0;.  }.  if( pTa
8d80: 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64 20 29 7b  sk->file2.pFd ){
8d90: 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43 6c  .    sqlite3OsCl
8da0: 6f 73 65 46 72 65 65 28 70 54 61 73 6b 2d 3e 66  oseFree(pTask->f
8db0: 69 6c 65 32 2e 70 46 64 29 3b 0a 20 20 20 20 70  ile2.pFd);.    p
8dc0: 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64 20  Task->file2.pFd 
8dd0: 3d 20 30 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e  = 0;.    pTask->
8de0: 66 69 6c 65 32 2e 69 45 6f 66 20 3d 20 30 3b 0a  file2.iEof = 0;.
8df0: 20 20 7d 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51    }.}..#ifdef SQ
8e00: 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f 52 54 45  LITE_DEBUG_SORTE
8e10: 52 5f 54 48 52 45 41 44 53 0a 73 74 61 74 69 63  R_THREADS.static
8e20: 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72   void vdbeSorter
8e30: 57 6f 72 6b 44 65 62 75 67 28 53 6f 72 74 53 75  WorkDebug(SortSu
8e40: 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 63 6f  btask *pTask, co
8e50: 6e 73 74 20 63 68 61 72 20 2a 7a 45 76 65 6e 74  nst char *zEvent
8e60: 29 7b 0a 20 20 69 36 34 20 74 3b 0a 20 20 69 6e  ){.  i64 t;.  in
8e70: 74 20 69 54 61 73 6b 20 3d 20 28 70 54 61 73 6b  t iTask = (pTask
8e80: 20 2d 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65   - pTask->pSorte
8e90: 72 2d 3e 61 54 61 73 6b 29 3b 0a 20 20 73 71 6c  r->aTask);.  sql
8ea0: 69 74 65 33 4f 73 43 75 72 72 65 6e 74 54 69 6d  ite3OsCurrentTim
8eb0: 65 49 6e 74 36 34 28 70 54 61 73 6b 2d 3e 70 53  eInt64(pTask->pS
8ec0: 6f 72 74 65 72 2d 3e 64 62 2d 3e 70 56 66 73 2c  orter->db->pVfs,
8ed0: 20 26 74 29 3b 0a 20 20 66 70 72 69 6e 74 66 28   &t);.  fprintf(
8ee0: 73 74 64 65 72 72 2c 20 22 25 6c 6c 64 3a 25 64  stderr, "%lld:%d
8ef0: 20 25 73 5c 6e 22 2c 20 74 2c 20 69 54 61 73 6b   %s\n", t, iTask
8f00: 2c 20 7a 45 76 65 6e 74 29 3b 0a 7d 0a 73 74 61  , zEvent);.}.sta
8f10: 74 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72  tic void vdbeSor
8f20: 74 65 72 52 65 77 69 6e 64 44 65 62 75 67 28 63  terRewindDebug(c
8f30: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45 76 65 6e  onst char *zEven
8f40: 74 29 7b 0a 20 20 69 36 34 20 74 3b 0a 20 20 73  t){.  i64 t;.  s
8f50: 71 6c 69 74 65 33 4f 73 43 75 72 72 65 6e 74 54  qlite3OsCurrentT
8f60: 69 6d 65 49 6e 74 36 34 28 73 71 6c 69 74 65 33  imeInt64(sqlite3
8f70: 5f 76 66 73 5f 66 69 6e 64 28 30 29 2c 20 26 74  _vfs_find(0), &t
8f80: 29 3b 0a 20 20 66 70 72 69 6e 74 66 28 73 74 64  );.  fprintf(std
8f90: 65 72 72 2c 20 22 25 6c 6c 64 3a 58 20 25 73 5c  err, "%lld:X %s\
8fa0: 6e 22 2c 20 74 2c 20 7a 45 76 65 6e 74 29 3b 0a  n", t, zEvent);.
8fb0: 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64  }.static void vd
8fc0: 62 65 53 6f 72 74 65 72 50 6f 70 75 6c 61 74 65  beSorterPopulate
8fd0: 44 65 62 75 67 28 0a 20 20 53 6f 72 74 53 75 62  Debug(.  SortSub
8fe0: 74 61 73 6b 20 2a 70 54 61 73 6b 2c 0a 20 20 63  task *pTask,.  c
8ff0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45 76 65 6e  onst char *zEven
9000: 74 0a 29 7b 0a 20 20 69 36 34 20 74 3b 0a 20 20  t.){.  i64 t;.  
9010: 69 6e 74 20 69 54 61 73 6b 20 3d 20 28 70 54 61  int iTask = (pTa
9020: 73 6b 20 2d 20 70 54 61 73 6b 2d 3e 70 53 6f 72  sk - pTask->pSor
9030: 74 65 72 2d 3e 61 54 61 73 6b 29 3b 0a 20 20 73  ter->aTask);.  s
9040: 71 6c 69 74 65 33 4f 73 43 75 72 72 65 6e 74 54  qlite3OsCurrentT
9050: 69 6d 65 49 6e 74 36 34 28 70 54 61 73 6b 2d 3e  imeInt64(pTask->
9060: 70 53 6f 72 74 65 72 2d 3e 64 62 2d 3e 70 56 66  pSorter->db->pVf
9070: 73 2c 20 26 74 29 3b 0a 20 20 66 70 72 69 6e 74  s, &t);.  fprint
9080: 66 28 73 74 64 65 72 72 2c 20 22 25 6c 6c 64 3a  f(stderr, "%lld:
9090: 62 67 25 64 20 25 73 5c 6e 22 2c 20 74 2c 20 69  bg%d %s\n", t, i
90a0: 54 61 73 6b 2c 20 7a 45 76 65 6e 74 29 3b 0a 7d  Task, zEvent);.}
90b0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62  .static void vdb
90c0: 65 53 6f 72 74 65 72 42 6c 6f 63 6b 44 65 62 75  eSorterBlockDebu
90d0: 67 28 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b  g(.  SortSubtask
90e0: 20 2a 70 54 61 73 6b 2c 0a 20 20 69 6e 74 20 62   *pTask,.  int b
90f0: 42 6c 6f 63 6b 65 64 2c 0a 20 20 63 6f 6e 73 74  Blocked,.  const
9100: 20 63 68 61 72 20 2a 7a 45 76 65 6e 74 0a 29 7b   char *zEvent.){
9110: 0a 20 20 69 66 28 20 62 42 6c 6f 63 6b 65 64 20  .  if( bBlocked 
9120: 29 7b 0a 20 20 20 20 69 36 34 20 74 3b 0a 20 20  ){.    i64 t;.  
9130: 20 20 73 71 6c 69 74 65 33 4f 73 43 75 72 72 65    sqlite3OsCurre
9140: 6e 74 54 69 6d 65 49 6e 74 36 34 28 70 54 61 73  ntTimeInt64(pTas
9150: 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 64 62 2d 3e  k->pSorter->db->
9160: 70 56 66 73 2c 20 26 74 29 3b 0a 20 20 20 20 66  pVfs, &t);.    f
9170: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
9180: 25 6c 6c 64 3a 6d 61 69 6e 20 25 73 5c 6e 22 2c  %lld:main %s\n",
9190: 20 74 2c 20 7a 45 76 65 6e 74 29 3b 0a 20 20 7d   t, zEvent);.  }
91a0: 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65 66 69 6e  .}.#else.# defin
91b0: 65 20 76 64 62 65 53 6f 72 74 65 72 57 6f 72 6b  e vdbeSorterWork
91c0: 44 65 62 75 67 28 78 2c 79 29 0a 23 20 64 65 66  Debug(x,y).# def
91d0: 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72 52 65  ine vdbeSorterRe
91e0: 77 69 6e 64 44 65 62 75 67 28 79 29 0a 23 20 64  windDebug(y).# d
91f0: 65 66 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72  efine vdbeSorter
9200: 50 6f 70 75 6c 61 74 65 44 65 62 75 67 28 78 2c  PopulateDebug(x,
9210: 79 29 0a 23 20 64 65 66 69 6e 65 20 76 64 62 65  y).# define vdbe
9220: 53 6f 72 74 65 72 42 6c 6f 63 6b 44 65 62 75 67  SorterBlockDebug
9230: 28 78 2c 79 2c 7a 29 0a 23 65 6e 64 69 66 0a 0a  (x,y,z).#endif..
9240: 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57  #if SQLITE_MAX_W
9250: 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 0a  ORKER_THREADS>0.
9260: 2f 2a 0a 2a 2a 20 4a 6f 69 6e 20 74 68 72 65 61  /*.** Join threa
9270: 64 20 70 54 61 73 6b 2d 3e 74 68 72 65 61 64 2e  d pTask->thread.
9280: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
9290: 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e 54 68 72  dbeSorterJoinThr
92a0: 65 61 64 28 53 6f 72 74 53 75 62 74 61 73 6b 20  ead(SortSubtask 
92b0: 2a 70 54 61 73 6b 29 7b 0a 20 20 69 6e 74 20 72  *pTask){.  int r
92c0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
92d0: 20 69 66 28 20 70 54 61 73 6b 2d 3e 70 54 68 72   if( pTask->pThr
92e0: 65 61 64 20 29 7b 0a 23 69 66 64 65 66 20 53 51  ead ){.#ifdef SQ
92f0: 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f 52 54 45  LITE_DEBUG_SORTE
9300: 52 5f 54 48 52 45 41 44 53 0a 20 20 20 20 69 6e  R_THREADS.    in
9310: 74 20 62 44 6f 6e 65 20 3d 20 70 54 61 73 6b 2d  t bDone = pTask-
9320: 3e 62 44 6f 6e 65 3b 0a 23 65 6e 64 69 66 0a 20  >bDone;.#endif. 
9330: 20 20 20 76 6f 69 64 20 2a 70 52 65 74 3b 0a 20     void *pRet;. 
9340: 20 20 20 76 64 62 65 53 6f 72 74 65 72 42 6c 6f     vdbeSorterBlo
9350: 63 6b 44 65 62 75 67 28 70 54 61 73 6b 2c 20 21  ckDebug(pTask, !
9360: 62 44 6f 6e 65 2c 20 22 65 6e 74 65 72 22 29 3b  bDone, "enter");
9370: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
9380: 33 54 68 72 65 61 64 4a 6f 69 6e 28 70 54 61 73  3ThreadJoin(pTas
9390: 6b 2d 3e 70 54 68 72 65 61 64 2c 20 26 70 52 65  k->pThread, &pRe
93a0: 74 29 3b 0a 20 20 20 20 76 64 62 65 53 6f 72 74  t);.    vdbeSort
93b0: 65 72 42 6c 6f 63 6b 44 65 62 75 67 28 70 54 61  erBlockDebug(pTa
93c0: 73 6b 2c 20 21 62 44 6f 6e 65 2c 20 22 65 78 69  sk, !bDone, "exi
93d0: 74 22 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d  t");.    if( rc=
93e0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20  =SQLITE_OK ) rc 
93f0: 3d 20 53 51 4c 49 54 45 5f 50 54 52 5f 54 4f 5f  = SQLITE_PTR_TO_
9400: 49 4e 54 28 70 52 65 74 29 3b 0a 20 20 20 20 61  INT(pRet);.    a
9410: 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 62 44  ssert( pTask->bD
9420: 6f 6e 65 3d 3d 31 20 29 3b 0a 20 20 20 20 70 54  one==1 );.    pT
9430: 61 73 6b 2d 3e 62 44 6f 6e 65 20 3d 20 30 3b 0a  ask->bDone = 0;.
9440: 20 20 20 20 70 54 61 73 6b 2d 3e 70 54 68 72 65      pTask->pThre
9450: 61 64 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 72 65  ad = 0;.  }.  re
9460: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
9470: 2a 20 4c 61 75 6e 63 68 20 61 20 62 61 63 6b 67  * Launch a backg
9480: 72 6f 75 6e 64 20 74 68 72 65 61 64 20 74 6f 20  round thread to 
9490: 72 75 6e 20 78 54 61 73 6b 28 70 49 6e 29 2e 0a  run xTask(pIn)..
94a0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
94b0: 62 65 53 6f 72 74 65 72 43 72 65 61 74 65 54 68  beSorterCreateTh
94c0: 72 65 61 64 28 0a 20 20 53 6f 72 74 53 75 62 74  read(.  SortSubt
94d0: 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20 20 20  ask *pTask,     
94e0: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 72 65 61          /* Threa
94f0: 64 20 77 69 6c 6c 20 75 73 65 20 74 68 69 73 20  d will use this 
9500: 74 61 73 6b 20 6f 62 6a 65 63 74 20 2a 2f 0a 20  task object */. 
9510: 20 76 6f 69 64 20 2a 28 2a 78 54 61 73 6b 29 28   void *(*xTask)(
9520: 76 6f 69 64 2a 29 2c 20 20 20 20 20 20 20 20 20  void*),         
9530: 20 2f 2a 20 52 6f 75 74 69 6e 65 20 74 6f 20 72   /* Routine to r
9540: 75 6e 20 69 6e 20 61 20 73 65 70 61 72 61 74 65  un in a separate
9550: 20 74 68 72 65 61 64 20 2a 2f 0a 20 20 76 6f 69   thread */.  voi
9560: 64 20 2a 70 49 6e 20 20 20 20 20 20 20 20 20 20  d *pIn          
9570: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9580: 41 72 67 75 6d 65 6e 74 20 70 61 73 73 65 64 20  Argument passed 
9590: 69 6e 74 6f 20 78 54 61 73 6b 28 29 20 2a 2f 0a  into xTask() */.
95a0: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 54 61  ){.  assert( pTa
95b0: 73 6b 2d 3e 70 54 68 72 65 61 64 3d 3d 30 20 26  sk->pThread==0 &
95c0: 26 20 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 3d 3d  & pTask->bDone==
95d0: 30 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71  0 );.  return sq
95e0: 6c 69 74 65 33 54 68 72 65 61 64 43 72 65 61 74  lite3ThreadCreat
95f0: 65 28 26 70 54 61 73 6b 2d 3e 70 54 68 72 65 61  e(&pTask->pThrea
9600: 64 2c 20 78 54 61 73 6b 2c 20 70 49 6e 29 3b 0a  d, xTask, pIn);.
9610: 7d 0a 0a 2f 2a 0a 2a 2a 20 4a 6f 69 6e 20 61 6c  }../*.** Join al
9620: 6c 20 6f 75 74 73 74 61 6e 64 69 6e 67 20 74 68  l outstanding th
9630: 72 65 61 64 73 20 6c 61 75 6e 63 68 65 64 20 62  reads launched b
9640: 79 20 53 6f 72 74 65 72 57 72 69 74 65 28 29 20  y SorterWrite() 
9650: 74 6f 20 63 72 65 61 74 65 20 0a 2a 2a 20 6c 65  to create .** le
9660: 76 65 6c 2d 30 20 50 4d 41 73 2e 0a 2a 2f 0a 73  vel-0 PMAs..*/.s
9670: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
9680: 72 74 65 72 4a 6f 69 6e 41 6c 6c 28 56 64 62 65  rterJoinAll(Vdbe
9690: 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 2c  Sorter *pSorter,
96a0: 20 69 6e 74 20 72 63 69 6e 29 7b 0a 20 20 69 6e   int rcin){.  in
96b0: 74 20 72 63 20 3d 20 72 63 69 6e 3b 0a 20 20 69  t rc = rcin;.  i
96c0: 6e 74 20 69 3b 0a 0a 20 20 2f 2a 20 54 68 69 73  nt i;..  /* This
96d0: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 6c 77   function is alw
96e0: 61 79 73 20 63 61 6c 6c 65 64 20 62 79 20 74 68  ays called by th
96f0: 65 20 6d 61 69 6e 20 75 73 65 72 20 74 68 72 65  e main user thre
9700: 61 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49 66  ad..  **.  ** If
9710: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
9720: 73 20 62 65 69 6e 67 20 63 61 6c 6c 65 64 20 61  s being called a
9730: 66 74 65 72 20 53 6f 72 74 65 72 52 65 77 69 6e  fter SorterRewin
9740: 64 28 29 20 68 61 73 20 62 65 65 6e 20 63 61 6c  d() has been cal
9750: 6c 65 64 2c 20 0a 20 20 2a 2a 20 69 74 20 69 73  led, .  ** it is
9760: 20 70 6f 73 73 69 62 6c 65 20 74 68 61 74 20 74   possible that t
9770: 68 72 65 61 64 20 70 53 6f 72 74 65 72 2d 3e 61  hread pSorter->a
9780: 54 61 73 6b 5b 70 53 6f 72 74 65 72 2d 3e 6e 54  Task[pSorter->nT
9790: 61 73 6b 2d 31 5d 2e 70 54 68 72 65 61 64 0a 20  ask-1].pThread. 
97a0: 20 2a 2a 20 69 73 20 63 75 72 72 65 6e 74 6c 79   ** is currently
97b0: 20 61 74 74 65 6d 70 74 20 74 6f 20 6a 6f 69 6e   attempt to join
97c0: 20 6f 6e 65 20 6f 66 20 74 68 65 20 6f 74 68 65   one of the othe
97d0: 72 20 74 68 72 65 61 64 73 2e 20 54 6f 20 61 76  r threads. To av
97e0: 6f 69 64 20 61 20 72 61 63 65 0a 20 20 2a 2a 20  oid a race.  ** 
97f0: 63 6f 6e 64 69 74 69 6f 6e 20 77 68 65 72 65 20  condition where 
9800: 74 68 69 73 20 74 68 72 65 61 64 20 61 6c 73 6f  this thread also
9810: 20 61 74 74 65 6d 70 74 73 20 74 6f 20 6a 6f 69   attempts to joi
9820: 6e 20 74 68 65 20 73 61 6d 65 20 6f 62 6a 65 63  n the same objec
9830: 74 2c 20 6a 6f 69 6e 20 0a 20 20 2a 2a 20 74 68  t, join .  ** th
9840: 72 65 61 64 20 70 53 6f 72 74 65 72 2d 3e 61 54  read pSorter->aT
9850: 61 73 6b 5b 70 53 6f 72 74 65 72 2d 3e 6e 54 61  ask[pSorter->nTa
9860: 73 6b 2d 31 5d 2e 70 54 68 72 65 61 64 20 66 69  sk-1].pThread fi
9870: 72 73 74 2e 20 2a 2f 0a 20 20 66 6f 72 28 69 3d  rst. */.  for(i=
9880: 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31  pSorter->nTask-1
9890: 3b 20 69 3e 3d 30 3b 20 69 2d 2d 29 7b 0a 20 20  ; i>=0; i--){.  
98a0: 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70    SortSubtask *p
98b0: 54 61 73 6b 20 3d 20 26 70 53 6f 72 74 65 72 2d  Task = &pSorter-
98c0: 3e 61 54 61 73 6b 5b 69 5d 3b 0a 20 20 20 20 69  >aTask[i];.    i
98d0: 6e 74 20 72 63 32 20 3d 20 76 64 62 65 53 6f 72  nt rc2 = vdbeSor
98e0: 74 65 72 4a 6f 69 6e 54 68 72 65 61 64 28 70 54  terJoinThread(pT
98f0: 61 73 6b 29 3b 0a 20 20 20 20 69 66 28 20 72 63  ask);.    if( rc
9900: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63  ==SQLITE_OK ) rc
9910: 20 3d 20 72 63 32 3b 0a 20 20 7d 0a 20 20 72 65   = rc2;.  }.  re
9920: 74 75 72 6e 20 72 63 3b 0a 7d 0a 23 65 6c 73 65  turn rc;.}.#else
9930: 0a 23 20 64 65 66 69 6e 65 20 76 64 62 65 53 6f  .# define vdbeSo
9940: 72 74 65 72 4a 6f 69 6e 41 6c 6c 28 78 2c 72 63  rterJoinAll(x,rc
9950: 69 6e 29 20 28 72 63 69 6e 29 0a 23 20 64 65 66  in) (rcin).# def
9960: 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72 4a 6f  ine vdbeSorterJo
9970: 69 6e 54 68 72 65 61 64 28 70 54 61 73 6b 29 20  inThread(pTask) 
9980: 53 51 4c 49 54 45 5f 4f 4b 0a 23 65 6e 64 69 66  SQLITE_OK.#endif
9990: 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65  ../*.** Allocate
99a0: 20 61 20 6e 65 77 20 4d 65 72 67 65 45 6e 67 69   a new MergeEngi
99b0: 6e 65 20 6f 62 6a 65 63 74 20 63 61 70 61 62 6c  ne object capabl
99c0: 65 20 6f 66 20 68 61 6e 64 6c 69 6e 67 20 75 70  e of handling up
99d0: 20 74 6f 0a 2a 2a 20 6e 52 65 61 64 65 72 20 50   to.** nReader P
99e0: 6d 61 52 65 61 64 65 72 20 69 6e 70 75 74 73 2e  maReader inputs.
99f0: 0a 2a 2a 0a 2a 2a 20 6e 52 65 61 64 65 72 20 69  .**.** nReader i
9a00: 73 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20  s automatically 
9a10: 72 6f 75 6e 64 65 64 20 75 70 20 74 6f 20 74 68  rounded up to th
9a20: 65 20 6e 65 78 74 20 70 6f 77 65 72 20 6f 66 20  e next power of 
9a30: 74 77 6f 2e 0a 2a 2a 20 6e 52 65 61 64 65 72 20  two..** nReader 
9a40: 6d 61 79 20 6e 6f 74 20 65 78 63 65 65 64 20 53  may not exceed S
9a50: 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f  ORTER_MAX_MERGE_
9a60: 43 4f 55 4e 54 20 65 76 65 6e 20 61 66 74 65 72  COUNT even after
9a70: 20 72 6f 75 6e 64 69 6e 67 20 75 70 2e 0a 2a 2f   rounding up..*/
9a80: 0a 73 74 61 74 69 63 20 4d 65 72 67 65 45 6e 67  .static MergeEng
9a90: 69 6e 65 20 2a 76 64 62 65 4d 65 72 67 65 45 6e  ine *vdbeMergeEn
9aa0: 67 69 6e 65 4e 65 77 28 69 6e 74 20 6e 52 65 61  gineNew(int nRea
9ab0: 64 65 72 29 7b 0a 20 20 69 6e 74 20 4e 20 3d 20  der){.  int N = 
9ac0: 32 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  2;              
9ad0: 20 20 20 20 20 20 20 20 2f 2a 20 53 6d 61 6c 6c          /* Small
9ae0: 65 73 74 20 70 6f 77 65 72 20 6f 66 20 74 77 6f  est power of two
9af0: 20 3e 3d 20 6e 52 65 61 64 65 72 20 2a 2f 0a 20   >= nReader */. 
9b00: 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20   int nByte;     
9b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9b20: 20 2f 2a 20 54 6f 74 61 6c 20 62 79 74 65 73 20   /* Total bytes 
9b30: 6f 66 20 73 70 61 63 65 20 74 6f 20 61 6c 6c 6f  of space to allo
9b40: 63 61 74 65 20 2a 2f 0a 20 20 4d 65 72 67 65 45  cate */.  MergeE
9b50: 6e 67 69 6e 65 20 2a 70 4e 65 77 3b 20 20 20 20  ngine *pNew;    
9b60: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
9b70: 6e 74 65 72 20 74 6f 20 61 6c 6c 6f 63 61 74 65  nter to allocate
9b80: 64 20 6f 62 6a 65 63 74 20 74 6f 20 72 65 74 75  d object to retu
9b90: 72 6e 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28  rn */..  assert(
9ba0: 20 6e 52 65 61 64 65 72 3c 3d 53 4f 52 54 45 52   nReader<=SORTER
9bb0: 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
9bc0: 20 29 3b 0a 0a 20 20 77 68 69 6c 65 28 20 4e 3c   );..  while( N<
9bd0: 6e 52 65 61 64 65 72 20 29 20 4e 20 2b 3d 20 4e  nReader ) N += N
9be0: 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65  ;.  nByte = size
9bf0: 6f 66 28 4d 65 72 67 65 45 6e 67 69 6e 65 29 20  of(MergeEngine) 
9c00: 2b 20 4e 20 2a 20 28 73 69 7a 65 6f 66 28 69 6e  + N * (sizeof(in
9c10: 74 29 20 2b 20 73 69 7a 65 6f 66 28 50 6d 61 52  t) + sizeof(PmaR
9c20: 65 61 64 65 72 29 29 3b 0a 0a 20 20 70 4e 65 77  eader));..  pNew
9c30: 20 3d 20 73 71 6c 69 74 65 33 46 61 75 6c 74 53   = sqlite3FaultS
9c40: 69 6d 28 31 30 30 29 20 3f 20 30 20 3a 20 28 4d  im(100) ? 0 : (M
9c50: 65 72 67 65 45 6e 67 69 6e 65 2a 29 73 71 6c 69  ergeEngine*)sqli
9c60: 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 6e 42  te3MallocZero(nB
9c70: 79 74 65 29 3b 0a 20 20 69 66 28 20 70 4e 65 77  yte);.  if( pNew
9c80: 20 29 7b 0a 20 20 20 20 70 4e 65 77 2d 3e 6e 54   ){.    pNew->nT
9c90: 72 65 65 20 3d 20 4e 3b 0a 20 20 20 20 70 4e 65  ree = N;.    pNe
9ca0: 77 2d 3e 70 54 61 73 6b 20 3d 20 30 3b 0a 20 20  w->pTask = 0;.  
9cb0: 20 20 70 4e 65 77 2d 3e 61 52 65 61 64 72 20 3d    pNew->aReadr =
9cc0: 20 28 50 6d 61 52 65 61 64 65 72 2a 29 26 70 4e   (PmaReader*)&pN
9cd0: 65 77 5b 31 5d 3b 0a 20 20 20 20 70 4e 65 77 2d  ew[1];.    pNew-
9ce0: 3e 61 54 72 65 65 20 3d 20 28 69 6e 74 2a 29 26  >aTree = (int*)&
9cf0: 70 4e 65 77 2d 3e 61 52 65 61 64 72 5b 4e 5d 3b  pNew->aReadr[N];
9d00: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 4e  .  }.  return pN
9d10: 65 77 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65  ew;.}../*.** Fre
9d20: 65 20 74 68 65 20 4d 65 72 67 65 45 6e 67 69 6e  e the MergeEngin
9d30: 65 20 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20  e object passed 
9d40: 61 73 20 74 68 65 20 6f 6e 6c 79 20 61 72 67 75  as the only argu
9d50: 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ment..*/.static 
9d60: 76 6f 69 64 20 76 64 62 65 4d 65 72 67 65 45 6e  void vdbeMergeEn
9d70: 67 69 6e 65 46 72 65 65 28 4d 65 72 67 65 45 6e  gineFree(MergeEn
9d80: 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 29 7b 0a  gine *pMerger){.
9d90: 20 20 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 70    int i;.  if( p
9da0: 4d 65 72 67 65 72 20 29 7b 0a 20 20 20 20 66 6f  Merger ){.    fo
9db0: 72 28 69 3d 30 3b 20 69 3c 70 4d 65 72 67 65 72  r(i=0; i<pMerger
9dc0: 2d 3e 6e 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20  ->nTree; i++){. 
9dd0: 20 20 20 20 20 76 64 62 65 50 6d 61 52 65 61 64       vdbePmaRead
9de0: 65 72 43 6c 65 61 72 28 26 70 4d 65 72 67 65 72  erClear(&pMerger
9df0: 2d 3e 61 52 65 61 64 72 5b 69 5d 29 3b 0a 20 20  ->aReadr[i]);.  
9e00: 20 20 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65    }.  }.  sqlite
9e10: 33 5f 66 72 65 65 28 70 4d 65 72 67 65 72 29 3b  3_free(pMerger);
9e20: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61  .}../*.** Free a
9e30: 6c 6c 20 72 65 73 6f 75 72 63 65 73 20 61 73 73  ll resources ass
9e40: 6f 63 69 61 74 65 64 20 77 69 74 68 20 74 68 65  ociated with the
9e50: 20 49 6e 63 72 4d 65 72 67 65 72 20 6f 62 6a 65   IncrMerger obje
9e60: 63 74 20 69 6e 64 69 63 61 74 65 64 20 62 79 0a  ct indicated by.
9e70: 2a 2a 20 74 68 65 20 66 69 72 73 74 20 61 72 67  ** the first arg
9e80: 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  ument..*/.static
9e90: 20 76 6f 69 64 20 76 64 62 65 49 6e 63 72 46 72   void vdbeIncrFr
9ea0: 65 65 28 49 6e 63 72 4d 65 72 67 65 72 20 2a 70  ee(IncrMerger *p
9eb0: 49 6e 63 72 29 7b 0a 20 20 69 66 28 20 70 49 6e  Incr){.  if( pIn
9ec0: 63 72 20 29 7b 0a 23 69 66 20 53 51 4c 49 54 45  cr ){.#if SQLITE
9ed0: 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45  _MAX_WORKER_THRE
9ee0: 41 44 53 3e 30 0a 20 20 20 20 69 66 28 20 70 49  ADS>0.    if( pI
9ef0: 6e 63 72 2d 3e 62 55 73 65 54 68 72 65 61 64 20  ncr->bUseThread 
9f00: 29 7b 0a 20 20 20 20 20 20 76 64 62 65 53 6f 72  ){.      vdbeSor
9f10: 74 65 72 4a 6f 69 6e 54 68 72 65 61 64 28 70 49  terJoinThread(pI
9f20: 6e 63 72 2d 3e 70 54 61 73 6b 29 3b 0a 20 20 20  ncr->pTask);.   
9f30: 20 20 20 69 66 28 20 70 49 6e 63 72 2d 3e 61 46     if( pIncr->aF
9f40: 69 6c 65 5b 30 5d 2e 70 46 64 20 29 20 73 71 6c  ile[0].pFd ) sql
9f50: 69 74 65 33 4f 73 43 6c 6f 73 65 46 72 65 65 28  ite3OsCloseFree(
9f60: 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e  pIncr->aFile[0].
9f70: 70 46 64 29 3b 0a 20 20 20 20 20 20 69 66 28 20  pFd);.      if( 
9f80: 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 2e  pIncr->aFile[1].
9f90: 70 46 64 20 29 20 73 71 6c 69 74 65 33 4f 73 43  pFd ) sqlite3OsC
9fa0: 6c 6f 73 65 46 72 65 65 28 70 49 6e 63 72 2d 3e  loseFree(pIncr->
9fb0: 61 46 69 6c 65 5b 31 5d 2e 70 46 64 29 3b 0a 20  aFile[1].pFd);. 
9fc0: 20 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 20 20     }.#endif.    
9fd0: 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46  vdbeMergeEngineF
9fe0: 72 65 65 28 70 49 6e 63 72 2d 3e 70 4d 65 72 67  ree(pIncr->pMerg
9ff0: 65 72 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  er);.    sqlite3
a000: 5f 66 72 65 65 28 70 49 6e 63 72 29 3b 0a 20 20  _free(pIncr);.  
a010: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65 74  }.}../*.** Reset
a020: 20 61 20 73 6f 72 74 69 6e 67 20 63 75 72 73 6f   a sorting curso
a030: 72 20 62 61 63 6b 20 74 6f 20 69 74 73 20 6f 72  r back to its or
a040: 69 67 69 6e 61 6c 20 65 6d 70 74 79 20 73 74 61  iginal empty sta
a050: 74 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  te..*/.void sqli
a060: 74 65 33 56 64 62 65 53 6f 72 74 65 72 52 65 73  te3VdbeSorterRes
a070: 65 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  et(sqlite3 *db, 
a080: 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72  VdbeSorter *pSor
a090: 74 65 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  ter){.  int i;. 
a0a0: 20 28 76 6f 69 64 29 76 64 62 65 53 6f 72 74 65   (void)vdbeSorte
a0b0: 72 4a 6f 69 6e 41 6c 6c 28 70 53 6f 72 74 65 72  rJoinAll(pSorter
a0c0: 2c 20 53 51 4c 49 54 45 5f 4f 4b 29 3b 0a 20 20  , SQLITE_OK);.  
a0d0: 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d  assert( pSorter-
a0e0: 3e 62 55 73 65 54 68 72 65 61 64 73 20 7c 7c 20  >bUseThreads || 
a0f0: 70 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72  pSorter->pReader
a100: 3d 3d 30 20 29 3b 0a 23 69 66 20 53 51 4c 49 54  ==0 );.#if SQLIT
a110: 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52  E_MAX_WORKER_THR
a120: 45 41 44 53 3e 30 0a 20 20 69 66 28 20 70 53 6f  EADS>0.  if( pSo
a130: 72 74 65 72 2d 3e 70 52 65 61 64 65 72 20 29 7b  rter->pReader ){
a140: 0a 20 20 20 20 76 64 62 65 50 6d 61 52 65 61 64  .    vdbePmaRead
a150: 65 72 43 6c 65 61 72 28 70 53 6f 72 74 65 72 2d  erClear(pSorter-
a160: 3e 70 52 65 61 64 65 72 29 3b 0a 20 20 20 20 73  >pReader);.    s
a170: 71 6c 69 74 65 33 44 62 46 72 65 65 28 64 62 2c  qlite3DbFree(db,
a180: 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65   pSorter->pReade
a190: 72 29 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d  r);.    pSorter-
a1a0: 3e 70 52 65 61 64 65 72 20 3d 20 30 3b 0a 20 20  >pReader = 0;.  
a1b0: 7d 0a 23 65 6e 64 69 66 0a 20 20 76 64 62 65 4d  }.#endif.  vdbeM
a1c0: 65 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28 70  ergeEngineFree(p
a1d0: 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 29  Sorter->pMerger)
a1e0: 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65  ;.  pSorter->pMe
a1f0: 72 67 65 72 20 3d 20 30 3b 0a 20 20 66 6f 72 28  rger = 0;.  for(
a200: 69 3d 30 3b 20 69 3c 70 53 6f 72 74 65 72 2d 3e  i=0; i<pSorter->
a210: 6e 54 61 73 6b 3b 20 69 2b 2b 29 7b 0a 20 20 20  nTask; i++){.   
a220: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
a230: 61 73 6b 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e  ask = &pSorter->
a240: 61 54 61 73 6b 5b 69 5d 3b 0a 20 20 20 20 76 64  aTask[i];.    vd
a250: 62 65 53 6f 72 74 53 75 62 74 61 73 6b 43 6c 65  beSortSubtaskCle
a260: 61 6e 75 70 28 64 62 2c 20 70 54 61 73 6b 29 3b  anup(db, pTask);
a270: 0a 20 20 7d 0a 20 20 69 66 28 20 70 53 6f 72 74  .  }.  if( pSort
a280: 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  er->list.aMemory
a290: 3d 3d 30 20 29 7b 0a 20 20 20 20 76 64 62 65 53  ==0 ){.    vdbeS
a2a0: 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65 65 28  orterRecordFree(
a2b0: 30 2c 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74  0, pSorter->list
a2c0: 2e 70 4c 69 73 74 29 3b 0a 20 20 7d 0a 20 20 70  .pList);.  }.  p
a2d0: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69  Sorter->list.pLi
a2e0: 73 74 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74 65  st = 0;.  pSorte
a2f0: 72 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 3d 20  r->list.szPMA = 
a300: 30 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 62 55  0;.  pSorter->bU
a310: 73 65 50 4d 41 20 3d 20 30 3b 0a 20 20 70 53 6f  sePMA = 0;.  pSo
a320: 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 20 3d 20  rter->iMemory = 
a330: 30 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6d 78  0;.  pSorter->mx
a340: 4b 65 79 73 69 7a 65 20 3d 20 30 3b 0a 20 20 73  Keysize = 0;.  s
a350: 71 6c 69 74 65 33 44 62 46 72 65 65 28 64 62 2c  qlite3DbFree(db,
a360: 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63   pSorter->pUnpac
a370: 6b 65 64 29 3b 0a 20 20 70 53 6f 72 74 65 72 2d  ked);.  pSorter-
a380: 3e 70 55 6e 70 61 63 6b 65 64 20 3d 20 30 3b 0a  >pUnpacked = 0;.
a390: 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6e  }../*.** Free an
a3a0: 79 20 63 75 72 73 6f 72 20 63 6f 6d 70 6f 6e 65  y cursor compone
a3b0: 6e 74 73 20 61 6c 6c 6f 63 61 74 65 64 20 62 79  nts allocated by
a3c0: 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74   sqlite3VdbeSort
a3d0: 65 72 58 58 58 20 72 6f 75 74 69 6e 65 73 2e 0a  erXXX routines..
a3e0: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 56  */.void sqlite3V
a3f0: 64 62 65 53 6f 72 74 65 72 43 6c 6f 73 65 28 73  dbeSorterClose(s
a400: 71 6c 69 74 65 33 20 2a 64 62 2c 20 56 64 62 65  qlite3 *db, Vdbe
a410: 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20  Cursor *pCsr){. 
a420: 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f   VdbeSorter *pSo
a430: 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f  rter = pCsr->pSo
a440: 72 74 65 72 3b 0a 20 20 69 66 28 20 70 53 6f 72  rter;.  if( pSor
a450: 74 65 72 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  ter ){.    sqlit
a460: 65 33 56 64 62 65 53 6f 72 74 65 72 52 65 73 65  e3VdbeSorterRese
a470: 74 28 64 62 2c 20 70 53 6f 72 74 65 72 29 3b 0a  t(db, pSorter);.
a480: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
a490: 28 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61  (pSorter->list.a
a4a0: 4d 65 6d 6f 72 79 29 3b 0a 20 20 20 20 73 71 6c  Memory);.    sql
a4b0: 69 74 65 33 44 62 46 72 65 65 28 64 62 2c 20 70  ite3DbFree(db, p
a4c0: 53 6f 72 74 65 72 29 3b 0a 20 20 20 20 70 43 73  Sorter);.    pCs
a4d0: 72 2d 3e 70 53 6f 72 74 65 72 20 3d 20 30 3b 0a  r->pSorter = 0;.
a4e0: 20 20 7d 0a 7d 0a 0a 23 69 66 20 53 51 4c 49 54    }.}..#if SQLIT
a4f0: 45 5f 4d 41 58 5f 4d 4d 41 50 5f 53 49 5a 45 3e  E_MAX_MMAP_SIZE>
a500: 30 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66 69 72 73  0./*.** The firs
a510: 74 20 61 72 67 75 6d 65 6e 74 20 69 73 20 61 20  t argument is a 
a520: 66 69 6c 65 2d 68 61 6e 64 6c 65 20 6f 70 65 6e  file-handle open
a530: 20 6f 6e 20 61 20 74 65 6d 70 6f 72 61 72 79 20   on a temporary 
a540: 66 69 6c 65 2e 20 54 68 65 20 66 69 6c 65 0a 2a  file. The file.*
a550: 2a 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 20  * is guaranteed 
a560: 74 6f 20 62 65 20 6e 42 79 74 65 20 62 79 74 65  to be nByte byte
a570: 73 20 6f 72 20 73 6d 61 6c 6c 65 72 20 69 6e 20  s or smaller in 
a580: 73 69 7a 65 2e 20 54 68 69 73 20 66 75 6e 63 74  size. This funct
a590: 69 6f 6e 0a 2a 2a 20 61 74 74 65 6d 70 74 73 20  ion.** attempts 
a5a0: 74 6f 20 65 78 74 65 6e 64 20 74 68 65 20 66 69  to extend the fi
a5b0: 6c 65 20 74 6f 20 6e 42 79 74 65 20 62 79 74 65  le to nByte byte
a5c0: 73 20 69 6e 20 73 69 7a 65 20 61 6e 64 20 74 6f  s in size and to
a5d0: 20 65 6e 73 75 72 65 20 74 68 61 74 0a 2a 2a 20   ensure that.** 
a5e0: 74 68 65 20 56 46 53 20 68 61 73 20 6d 65 6d 6f  the VFS has memo
a5f0: 72 79 20 6d 61 70 70 65 64 20 69 74 2e 0a 2a 2a  ry mapped it..**
a600: 0a 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e  .** Whether or n
a610: 6f 74 20 74 68 65 20 66 69 6c 65 20 64 6f 65 73  ot the file does
a620: 20 65 6e 64 20 75 70 20 6d 65 6d 6f 72 79 20 6d   end up memory m
a630: 61 70 70 65 64 20 6f 66 20 63 6f 75 72 73 65 20  apped of course 
a640: 64 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20 74 68  depends on.** th
a650: 65 20 73 70 65 63 69 66 69 63 20 56 46 53 20 69  e specific VFS i
a660: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a  mplementation..*
a670: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64  /.static void vd
a680: 62 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46 69  beSorterExtendFi
a690: 6c 65 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  le(sqlite3 *db, 
a6a0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
a6b0: 64 2c 20 69 36 34 20 6e 42 79 74 65 29 7b 0a 20  d, i64 nByte){. 
a6c0: 20 69 66 28 20 6e 42 79 74 65 3c 3d 28 69 36 34   if( nByte<=(i64
a6d0: 29 28 64 62 2d 3e 6e 4d 61 78 53 6f 72 74 65 72  )(db->nMaxSorter
a6e0: 4d 6d 61 70 29 20 29 7b 0a 20 20 20 20 69 6e 74  Mmap) ){.    int
a6f0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 54   rc = sqlite3OsT
a700: 72 75 6e 63 61 74 65 28 70 46 64 2c 20 6e 42 79  runcate(pFd, nBy
a710: 74 65 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d  te);.    if( rc=
a720: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
a730: 20 20 20 20 76 6f 69 64 20 2a 70 20 3d 20 30 3b      void *p = 0;
a740: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 4f 73  .      sqlite3Os
a750: 46 65 74 63 68 28 70 46 64 2c 20 30 2c 20 28 69  Fetch(pFd, 0, (i
a760: 6e 74 29 6e 42 79 74 65 2c 20 26 70 29 3b 0a 20  nt)nByte, &p);. 
a770: 20 20 20 20 20 73 71 6c 69 74 65 33 4f 73 55 6e       sqlite3OsUn
a780: 66 65 74 63 68 28 70 46 64 2c 20 30 2c 20 70 29  fetch(pFd, 0, p)
a790: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 23 65  ;.    }.  }.}.#e
a7a0: 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 76 64 62  lse.# define vdb
a7b0: 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46 69 6c  eSorterExtendFil
a7c0: 65 28 78 2c 79 2c 7a 29 20 53 51 4c 49 54 45 5f  e(x,y,z) SQLITE_
a7d0: 4f 4b 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a  OK.#endif../*.**
a7e0: 20 41 6c 6c 6f 63 61 74 65 20 73 70 61 63 65 20   Allocate space 
a7f0: 66 6f 72 20 61 20 66 69 6c 65 2d 68 61 6e 64 6c  for a file-handl
a800: 65 20 61 6e 64 20 6f 70 65 6e 20 61 20 74 65 6d  e and open a tem
a810: 70 6f 72 61 72 79 20 66 69 6c 65 2e 20 49 66 20  porary file. If 
a820: 73 75 63 63 65 73 73 66 75 6c 2c 0a 2a 2a 20 73  successful,.** s
a830: 65 74 20 2a 70 70 46 64 20 74 6f 20 70 6f 69 6e  et *ppFd to poin
a840: 74 20 74 6f 20 74 68 65 20 6d 61 6c 6c 6f 63 27  t to the malloc'
a850: 64 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20 61 6e  d file-handle an
a860: 64 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  d return SQLITE_
a870: 4f 4b 2e 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65  OK..** Otherwise
a880: 2c 20 73 65 74 20 2a 70 70 46 64 20 74 6f 20 30  , set *ppFd to 0
a890: 20 61 6e 64 20 72 65 74 75 72 6e 20 61 6e 20 53   and return an S
a8a0: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
a8b0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
a8c0: 76 64 62 65 53 6f 72 74 65 72 4f 70 65 6e 54 65  vdbeSorterOpenTe
a8d0: 6d 70 46 69 6c 65 28 0a 20 20 73 71 6c 69 74 65  mpFile(.  sqlite
a8e0: 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20  3 *db,          
a8f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
a900: 61 62 61 73 65 20 68 61 6e 64 6c 65 20 64 6f 69  abase handle doi
a910: 6e 67 20 73 6f 72 74 20 2a 2f 0a 20 20 69 36 34  ng sort */.  i64
a920: 20 6e 45 78 74 65 6e 64 2c 20 20 20 20 20 20 20   nExtend,       
a930: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
a940: 41 74 74 65 6d 70 74 20 74 6f 20 65 78 74 65 6e  Attempt to exten
a950: 64 20 66 69 6c 65 20 74 6f 20 74 68 69 73 20 73  d file to this s
a960: 69 7a 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ize */.  sqlite3
a970: 5f 66 69 6c 65 20 2a 2a 70 70 46 64 0a 29 7b 0a  _file **ppFd.){.
a980: 20 20 69 6e 74 20 72 63 3b 0a 20 20 72 63 20 3d    int rc;.  rc =
a990: 20 73 71 6c 69 74 65 33 4f 73 4f 70 65 6e 4d 61   sqlite3OsOpenMa
a9a0: 6c 6c 6f 63 28 64 62 2d 3e 70 56 66 73 2c 20 30  lloc(db->pVfs, 0
a9b0: 2c 20 70 70 46 64 2c 0a 20 20 20 20 20 20 53 51  , ppFd,.      SQ
a9c0: 4c 49 54 45 5f 4f 50 45 4e 5f 54 45 4d 50 5f 4a  LITE_OPEN_TEMP_J
a9d0: 4f 55 52 4e 41 4c 20 7c 0a 20 20 20 20 20 20 53  OURNAL |.      S
a9e0: 51 4c 49 54 45 5f 4f 50 45 4e 5f 52 45 41 44 57  QLITE_OPEN_READW
a9f0: 52 49 54 45 20 20 20 20 7c 20 53 51 4c 49 54 45  RITE    | SQLITE
aa00: 5f 4f 50 45 4e 5f 43 52 45 41 54 45 20 7c 0a 20  _OPEN_CREATE |. 
aa10: 20 20 20 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e       SQLITE_OPEN
aa20: 5f 45 58 43 4c 55 53 49 56 45 20 20 20 20 7c 20  _EXCLUSIVE    | 
aa30: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 44 45 4c 45  SQLITE_OPEN_DELE
aa40: 54 45 4f 4e 43 4c 4f 53 45 2c 20 26 72 63 0a 20  TEONCLOSE, &rc. 
aa50: 20 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   );.  if( rc==SQ
aa60: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69  LITE_OK ){.    i
aa70: 36 34 20 6d 61 78 20 3d 20 53 51 4c 49 54 45 5f  64 max = SQLITE_
aa80: 4d 41 58 5f 4d 4d 41 50 5f 53 49 5a 45 3b 0a 20  MAX_MMAP_SIZE;. 
aa90: 20 20 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65     sqlite3OsFile
aaa0: 43 6f 6e 74 72 6f 6c 48 69 6e 74 28 2a 70 70 46  ControlHint(*ppF
aab0: 64 2c 20 53 51 4c 49 54 45 5f 46 43 4e 54 4c 5f  d, SQLITE_FCNTL_
aac0: 4d 4d 41 50 5f 53 49 5a 45 2c 20 28 76 6f 69 64  MMAP_SIZE, (void
aad0: 2a 29 26 6d 61 78 29 3b 0a 20 20 20 20 69 66 28  *)&max);.    if(
aae0: 20 6e 45 78 74 65 6e 64 3e 30 20 29 7b 0a 20 20   nExtend>0 ){.  
aaf0: 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 45 78      vdbeSorterEx
ab00: 74 65 6e 64 46 69 6c 65 28 64 62 2c 20 2a 70 70  tendFile(db, *pp
ab10: 46 64 2c 20 6e 45 78 74 65 6e 64 29 3b 0a 20 20  Fd, nExtend);.  
ab20: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
ab30: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66   rc;.}../*.** If
ab40: 20 69 74 20 68 61 73 20 6e 6f 74 20 61 6c 72 65   it has not alre
ab50: 61 64 79 20 62 65 65 6e 20 61 6c 6c 6f 63 61 74  ady been allocat
ab60: 65 64 2c 20 61 6c 6c 6f 63 61 74 65 20 74 68 65  ed, allocate the
ab70: 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20   UnpackedRecord 
ab80: 0a 2a 2a 20 73 74 72 75 63 74 75 72 65 20 61 74  .** structure at
ab90: 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65   pTask->pUnpacke
aba0: 64 2e 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45  d. Return SQLITE
abb0: 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75  _OK if successfu
abc0: 6c 20 28 6f 72 20 0a 2a 2a 20 69 66 20 6e 6f 20  l (or .** if no 
abd0: 61 6c 6c 6f 63 61 74 69 6f 6e 20 77 61 73 20 72  allocation was r
abe0: 65 71 75 69 72 65 64 29 2c 20 6f 72 20 53 51 4c  equired), or SQL
abf0: 49 54 45 5f 4e 4f 4d 45 4d 20 6f 74 68 65 72 77  ITE_NOMEM otherw
ac00: 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ise..*/.static i
ac10: 6e 74 20 76 64 62 65 53 6f 72 74 41 6c 6c 6f 63  nt vdbeSortAlloc
ac20: 55 6e 70 61 63 6b 65 64 28 53 6f 72 74 53 75 62  Unpacked(SortSub
ac30: 74 61 73 6b 20 2a 70 54 61 73 6b 29 7b 0a 20 20  task *pTask){.  
ac40: 69 66 28 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61  if( pTask->pUnpa
ac50: 63 6b 65 64 3d 3d 30 20 29 7b 0a 20 20 20 20 63  cked==0 ){.    c
ac60: 68 61 72 20 2a 70 46 72 65 65 3b 0a 20 20 20 20  har *pFree;.    
ac70: 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64  pTask->pUnpacked
ac80: 20 3d 20 73 71 6c 69 74 65 33 56 64 62 65 41 6c   = sqlite3VdbeAl
ac90: 6c 6f 63 55 6e 70 61 63 6b 65 64 52 65 63 6f 72  locUnpackedRecor
aca0: 64 28 0a 20 20 20 20 20 20 20 20 70 54 61 73 6b  d(.        pTask
acb0: 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49  ->pSorter->pKeyI
acc0: 6e 66 6f 2c 20 30 2c 20 30 2c 20 26 70 46 72 65  nfo, 0, 0, &pFre
acd0: 65 0a 20 20 20 20 29 3b 0a 20 20 20 20 61 73 73  e.    );.    ass
ace0: 65 72 74 28 20 70 54 61 73 6b 2d 3e 70 55 6e 70  ert( pTask->pUnp
acf0: 61 63 6b 65 64 3d 3d 28 55 6e 70 61 63 6b 65 64  acked==(Unpacked
ad00: 52 65 63 6f 72 64 2a 29 70 46 72 65 65 20 29 3b  Record*)pFree );
ad10: 0a 20 20 20 20 69 66 28 20 70 46 72 65 65 3d 3d  .    if( pFree==
ad20: 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  0 ) return SQLIT
ad30: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 70 54 61  E_NOMEM;.    pTa
ad40: 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 2d 3e 6e  sk->pUnpacked->n
ad50: 46 69 65 6c 64 20 3d 20 70 54 61 73 6b 2d 3e 70  Field = pTask->p
ad60: 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49 6e 66 6f  Sorter->pKeyInfo
ad70: 2d 3e 6e 46 69 65 6c 64 3b 0a 20 20 20 20 70 54  ->nField;.    pT
ad80: 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 2d 3e  ask->pUnpacked->
ad90: 65 72 72 43 6f 64 65 20 3d 20 30 3b 0a 20 20 7d  errCode = 0;.  }
ada0: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
adb0: 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 4d  _OK;.}.../*.** M
adc0: 65 72 67 65 20 74 68 65 20 74 77 6f 20 73 6f 72  erge the two sor
add0: 74 65 64 20 6c 69 73 74 73 20 70 31 20 61 6e 64  ted lists p1 and
ade0: 20 70 32 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c   p2 into a singl
adf0: 65 20 6c 69 73 74 2e 0a 2a 2a 20 53 65 74 20 2a  e list..** Set *
ae00: 70 70 4f 75 74 20 74 6f 20 74 68 65 20 68 65 61  ppOut to the hea
ae10: 64 20 6f 66 20 74 68 65 20 6e 65 77 20 6c 69 73  d of the new lis
ae20: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  t..*/.static voi
ae30: 64 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67  d vdbeSorterMerg
ae40: 65 28 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b  e(.  SortSubtask
ae50: 20 2a 70 54 61 73 6b 2c 20 20 20 20 20 20 20 20   *pTask,        
ae60: 20 20 20 20 20 2f 2a 20 43 61 6c 6c 69 6e 67 20       /* Calling 
ae70: 74 68 72 65 61 64 20 63 6f 6e 74 65 78 74 20 2a  thread context *
ae80: 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  /.  SorterRecord
ae90: 20 2a 70 31 2c 20 20 20 20 20 20 20 20 20 20 20   *p1,           
aea0: 20 20 20 20 2f 2a 20 46 69 72 73 74 20 6c 69 73      /* First lis
aeb0: 74 20 74 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20  t to merge */.  
aec0: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 32  SorterRecord *p2
aed0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
aee0: 2f 2a 20 53 65 63 6f 6e 64 20 6c 69 73 74 20 74  /* Second list t
aef0: 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20 53 6f 72  o merge */.  Sor
af00: 74 65 72 52 65 63 6f 72 64 20 2a 2a 70 70 4f 75  terRecord **ppOu
af10: 74 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  t            /* 
af20: 4f 55 54 3a 20 48 65 61 64 20 6f 66 20 6d 65 72  OUT: Head of mer
af30: 67 65 64 20 6c 69 73 74 20 2a 2f 0a 29 7b 0a 20  ged list */.){. 
af40: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
af50: 46 69 6e 61 6c 20 3d 20 30 3b 0a 20 20 53 6f 72  Final = 0;.  Sor
af60: 74 65 72 52 65 63 6f 72 64 20 2a 2a 70 70 20 3d  terRecord **pp =
af70: 20 26 70 46 69 6e 61 6c 3b 0a 20 20 76 6f 69 64   &pFinal;.  void
af80: 20 2a 70 56 61 6c 32 20 3d 20 70 32 20 3f 20 53   *pVal2 = p2 ? S
af90: 52 56 41 4c 28 70 32 29 20 3a 20 30 3b 0a 0a 20  RVAL(p2) : 0;.. 
afa0: 20 77 68 69 6c 65 28 20 70 31 20 26 26 20 70 32   while( p1 && p2
afb0: 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 65 73 3b   ){.    int res;
afc0: 0a 20 20 20 20 72 65 73 20 3d 20 76 64 62 65 53  .    res = vdbeS
afd0: 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 70 54 61  orterCompare(pTa
afe0: 73 6b 2c 20 53 52 56 41 4c 28 70 31 29 2c 20 70  sk, SRVAL(p1), p
aff0: 31 2d 3e 6e 56 61 6c 2c 20 70 56 61 6c 32 2c 20  1->nVal, pVal2, 
b000: 70 32 2d 3e 6e 56 61 6c 29 3b 0a 20 20 20 20 69  p2->nVal);.    i
b010: 66 28 20 72 65 73 3c 3d 30 20 29 7b 0a 20 20 20  f( res<=0 ){.   
b020: 20 20 20 2a 70 70 20 3d 20 70 31 3b 0a 20 20 20     *pp = p1;.   
b030: 20 20 20 70 70 20 3d 20 26 70 31 2d 3e 75 2e 70     pp = &p1->u.p
b040: 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 31 20 3d  Next;.      p1 =
b050: 20 70 31 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20 20   p1->u.pNext;.  
b060: 20 20 20 20 70 56 61 6c 32 20 3d 20 30 3b 0a 20      pVal2 = 0;. 
b070: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
b080: 2a 70 70 20 3d 20 70 32 3b 0a 20 20 20 20 20 20  *pp = p2;.      
b090: 20 70 70 20 3d 20 26 70 32 2d 3e 75 2e 70 4e 65   pp = &p2->u.pNe
b0a0: 78 74 3b 0a 20 20 20 20 20 20 70 32 20 3d 20 70  xt;.      p2 = p
b0b0: 32 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20 20 20 20  2->u.pNext;.    
b0c0: 20 20 69 66 28 20 70 32 3d 3d 30 20 29 20 62 72    if( p2==0 ) br
b0d0: 65 61 6b 3b 0a 20 20 20 20 20 20 70 56 61 6c 32  eak;.      pVal2
b0e0: 20 3d 20 53 52 56 41 4c 28 70 32 29 3b 0a 20 20   = SRVAL(p2);.  
b0f0: 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 70 20 3d 20    }.  }.  *pp = 
b100: 70 31 20 3f 20 70 31 20 3a 20 70 32 3b 0a 20 20  p1 ? p1 : p2;.  
b110: 2a 70 70 4f 75 74 20 3d 20 70 46 69 6e 61 6c 3b  *ppOut = pFinal;
b120: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74  .}../*.** Sort t
b130: 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f  he linked list o
b140: 66 20 72 65 63 6f 72 64 73 20 68 65 61 64 65 64  f records headed
b150: 20 61 74 20 70 54 61 73 6b 2d 3e 70 4c 69 73 74   at pTask->pList
b160: 2e 20 52 65 74 75 72 6e 20 0a 2a 2a 20 53 51 4c  . Return .** SQL
b170: 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73  ITE_OK if succes
b180: 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69  sful, or an SQLi
b190: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 28 69  te error code (i
b1a0: 2e 65 2e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  .e. SQLITE_NOMEM
b1b0: 29 20 69 66 20 0a 2a 2a 20 61 6e 20 65 72 72 6f  ) if .** an erro
b1c0: 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61  r occurs..*/.sta
b1d0: 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74  tic int vdbeSort
b1e0: 65 72 53 6f 72 74 28 53 6f 72 74 53 75 62 74 61  erSort(SortSubta
b1f0: 73 6b 20 2a 70 54 61 73 6b 2c 20 53 6f 72 74 65  sk *pTask, Sorte
b200: 72 4c 69 73 74 20 2a 70 4c 69 73 74 29 7b 0a 20  rList *pList){. 
b210: 20 69 6e 74 20 69 3b 0a 20 20 53 6f 72 74 65 72   int i;.  Sorter
b220: 52 65 63 6f 72 64 20 2a 2a 61 53 6c 6f 74 3b 0a  Record **aSlot;.
b230: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
b240: 70 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20  p;.  int rc;..  
b250: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 41 6c 6c  rc = vdbeSortAll
b260: 6f 63 55 6e 70 61 63 6b 65 64 28 70 54 61 73 6b  ocUnpacked(pTask
b270: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
b280: 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
b290: 72 63 3b 0a 0a 20 20 61 53 6c 6f 74 20 3d 20 28  rc;..  aSlot = (
b2a0: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 2a 29  SorterRecord **)
b2b0: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72  sqlite3MallocZer
b2c0: 6f 28 36 34 20 2a 20 73 69 7a 65 6f 66 28 53 6f  o(64 * sizeof(So
b2d0: 72 74 65 72 52 65 63 6f 72 64 20 2a 29 29 3b 0a  rterRecord *));.
b2e0: 20 20 69 66 28 20 21 61 53 6c 6f 74 20 29 7b 0a    if( !aSlot ){.
b2f0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
b300: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20  E_NOMEM;.  }..  
b310: 70 20 3d 20 70 4c 69 73 74 2d 3e 70 4c 69 73 74  p = pList->pList
b320: 3b 0a 20 20 77 68 69 6c 65 28 20 70 20 29 7b 0a  ;.  while( p ){.
b330: 20 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64      SorterRecord
b340: 20 2a 70 4e 65 78 74 3b 0a 20 20 20 20 69 66 28   *pNext;.    if(
b350: 20 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f 72 79 20   pList->aMemory 
b360: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 28 75 38  ){.      if( (u8
b370: 2a 29 70 3d 3d 70 4c 69 73 74 2d 3e 61 4d 65 6d  *)p==pList->aMem
b380: 6f 72 79 20 29 7b 0a 20 20 20 20 20 20 20 20 70  ory ){.        p
b390: 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 20 20  Next = 0;.      
b3a0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 61  }else{.        a
b3b0: 73 73 65 72 74 28 20 70 2d 3e 75 2e 69 4e 65 78  ssert( p->u.iNex
b3c0: 74 3c 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53  t<sqlite3MallocS
b3d0: 69 7a 65 28 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f  ize(pList->aMemo
b3e0: 72 79 29 20 29 3b 0a 20 20 20 20 20 20 20 20 70  ry) );.        p
b3f0: 4e 65 78 74 20 3d 20 28 53 6f 72 74 65 72 52 65  Next = (SorterRe
b400: 63 6f 72 64 2a 29 26 70 4c 69 73 74 2d 3e 61 4d  cord*)&pList->aM
b410: 65 6d 6f 72 79 5b 70 2d 3e 75 2e 69 4e 65 78 74  emory[p->u.iNext
b420: 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  ];.      }.    }
b430: 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 4e 65 78  else{.      pNex
b440: 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74 3b 0a  t = p->u.pNext;.
b450: 20 20 20 20 7d 0a 0a 20 20 20 20 70 2d 3e 75 2e      }..    p->u.
b460: 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 66  pNext = 0;.    f
b470: 6f 72 28 69 3d 30 3b 20 61 53 6c 6f 74 5b 69 5d  or(i=0; aSlot[i]
b480: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 76 64  ; i++){.      vd
b490: 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28 70 54  beSorterMerge(pT
b4a0: 61 73 6b 2c 20 70 2c 20 61 53 6c 6f 74 5b 69 5d  ask, p, aSlot[i]
b4b0: 2c 20 26 70 29 3b 0a 20 20 20 20 20 20 61 53 6c  , &p);.      aSl
b4c0: 6f 74 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 7d  ot[i] = 0;.    }
b4d0: 0a 20 20 20 20 61 53 6c 6f 74 5b 69 5d 20 3d 20  .    aSlot[i] = 
b4e0: 70 3b 0a 20 20 20 20 70 20 3d 20 70 4e 65 78 74  p;.    p = pNext
b4f0: 3b 0a 20 20 7d 0a 0a 20 20 70 20 3d 20 30 3b 0a  ;.  }..  p = 0;.
b500: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 36 34 3b    for(i=0; i<64;
b510: 20 69 2b 2b 29 7b 0a 20 20 20 20 76 64 62 65 53   i++){.    vdbeS
b520: 6f 72 74 65 72 4d 65 72 67 65 28 70 54 61 73 6b  orterMerge(pTask
b530: 2c 20 70 2c 20 61 53 6c 6f 74 5b 69 5d 2c 20 26  , p, aSlot[i], &
b540: 70 29 3b 0a 20 20 7d 0a 20 20 70 4c 69 73 74 2d  p);.  }.  pList-
b550: 3e 70 4c 69 73 74 20 3d 20 70 3b 0a 0a 20 20 73  >pList = p;..  s
b560: 71 6c 69 74 65 33 5f 66 72 65 65 28 61 53 6c 6f  qlite3_free(aSlo
b570: 74 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 54  t);.  assert( pT
b580: 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 2d 3e  ask->pUnpacked->
b590: 65 72 72 43 6f 64 65 3d 3d 53 51 4c 49 54 45 5f  errCode==SQLITE_
b5a0: 4f 4b 20 0a 20 20 20 20 20 20 20 7c 7c 20 70 54  OK .       || pT
b5b0: 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 2d 3e  ask->pUnpacked->
b5c0: 65 72 72 43 6f 64 65 3d 3d 53 51 4c 49 54 45 5f  errCode==SQLITE_
b5d0: 4e 4f 4d 45 4d 20 0a 20 20 29 3b 0a 20 20 72 65  NOMEM .  );.  re
b5e0: 74 75 72 6e 20 70 54 61 73 6b 2d 3e 70 55 6e 70  turn pTask->pUnp
b5f0: 61 63 6b 65 64 2d 3e 65 72 72 43 6f 64 65 3b 0a  acked->errCode;.
b600: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c  }../*.** Initial
b610: 69 7a 65 20 61 20 50 4d 41 2d 77 72 69 74 65 72  ize a PMA-writer
b620: 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74 61 74   object..*/.stat
b630: 69 63 20 76 6f 69 64 20 76 64 62 65 50 6d 61 57  ic void vdbePmaW
b640: 72 69 74 65 72 49 6e 69 74 28 0a 20 20 73 71 6c  riterInit(.  sql
b650: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 64 2c 20  ite3_file *pFd, 
b660: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
b670: 46 69 6c 65 20 68 61 6e 64 6c 65 20 74 6f 20 77  File handle to w
b680: 72 69 74 65 20 74 6f 20 2a 2f 0a 20 20 50 6d 61  rite to */.  Pma
b690: 57 72 69 74 65 72 20 2a 70 2c 20 20 20 20 20 20  Writer *p,      
b6a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
b6b0: 4f 62 6a 65 63 74 20 74 6f 20 70 6f 70 75 6c 61  Object to popula
b6c0: 74 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66  te */.  int nBuf
b6d0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
b6e0: 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65          /* Buffe
b6f0: 72 20 73 69 7a 65 20 2a 2f 0a 20 20 69 36 34 20  r size */.  i64 
b700: 69 53 74 61 72 74 20 20 20 20 20 20 20 20 20 20  iStart          
b710: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
b720: 66 66 73 65 74 20 6f 66 20 70 46 64 20 74 6f 20  ffset of pFd to 
b730: 62 65 67 69 6e 20 77 72 69 74 69 6e 67 20 61 74  begin writing at
b740: 20 2a 2f 0a 29 7b 0a 20 20 6d 65 6d 73 65 74 28   */.){.  memset(
b750: 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50 6d 61  p, 0, sizeof(Pma
b760: 57 72 69 74 65 72 29 29 3b 0a 20 20 70 2d 3e 61  Writer));.  p->a
b770: 42 75 66 66 65 72 20 3d 20 28 75 38 2a 29 73 71  Buffer = (u8*)sq
b780: 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 6e 42 75 66  lite3Malloc(nBuf
b790: 29 3b 0a 20 20 69 66 28 20 21 70 2d 3e 61 42 75  );.  if( !p->aBu
b7a0: 66 66 65 72 20 29 7b 0a 20 20 20 20 70 2d 3e 65  ffer ){.    p->e
b7b0: 46 57 45 72 72 20 3d 20 53 51 4c 49 54 45 5f 4e  FWErr = SQLITE_N
b7c0: 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  OMEM;.  }else{. 
b7d0: 20 20 20 70 2d 3e 69 42 75 66 45 6e 64 20 3d 20     p->iBufEnd = 
b7e0: 70 2d 3e 69 42 75 66 53 74 61 72 74 20 3d 20 28  p->iBufStart = (
b7f0: 69 53 74 61 72 74 20 25 20 6e 42 75 66 29 3b 0a  iStart % nBuf);.
b800: 20 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66      p->iWriteOff
b810: 20 3d 20 69 53 74 61 72 74 20 2d 20 70 2d 3e 69   = iStart - p->i
b820: 42 75 66 53 74 61 72 74 3b 0a 20 20 20 20 70 2d  BufStart;.    p-
b830: 3e 6e 42 75 66 66 65 72 20 3d 20 6e 42 75 66 3b  >nBuffer = nBuf;
b840: 0a 20 20 20 20 70 2d 3e 70 46 64 20 3d 20 70 46  .    p->pFd = pF
b850: 64 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  d;.  }.}../*.** 
b860: 57 72 69 74 65 20 6e 44 61 74 61 20 62 79 74 65  Write nData byte
b870: 73 20 6f 66 20 64 61 74 61 20 74 6f 20 74 68 65  s of data to the
b880: 20 50 4d 41 2e 20 52 65 74 75 72 6e 20 53 51 4c   PMA. Return SQL
b890: 49 54 45 5f 4f 4b 0a 2a 2a 20 69 66 20 73 75 63  ITE_OK.** if suc
b8a0: 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53  cessful, or an S
b8b0: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
b8c0: 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   if an error occ
b8d0: 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  urs..*/.static v
b8e0: 6f 69 64 20 76 64 62 65 50 6d 61 57 72 69 74 65  oid vdbePmaWrite
b8f0: 42 6c 6f 62 28 50 6d 61 57 72 69 74 65 72 20 2a  Blob(PmaWriter *
b900: 70 2c 20 75 38 20 2a 70 44 61 74 61 2c 20 69 6e  p, u8 *pData, in
b910: 74 20 6e 44 61 74 61 29 7b 0a 20 20 69 6e 74 20  t nData){.  int 
b920: 6e 52 65 6d 20 3d 20 6e 44 61 74 61 3b 0a 20 20  nRem = nData;.  
b930: 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30 20 26 26  while( nRem>0 &&
b940: 20 70 2d 3e 65 46 57 45 72 72 3d 3d 30 20 29 7b   p->eFWErr==0 ){
b950: 0a 20 20 20 20 69 6e 74 20 6e 43 6f 70 79 20 3d  .    int nCopy =
b960: 20 6e 52 65 6d 3b 0a 20 20 20 20 69 66 28 20 6e   nRem;.    if( n
b970: 43 6f 70 79 3e 28 70 2d 3e 6e 42 75 66 66 65 72  Copy>(p->nBuffer
b980: 20 2d 20 70 2d 3e 69 42 75 66 45 6e 64 29 20 29   - p->iBufEnd) )
b990: 7b 0a 20 20 20 20 20 20 6e 43 6f 70 79 20 3d 20  {.      nCopy = 
b9a0: 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 70 2d 3e  p->nBuffer - p->
b9b0: 69 42 75 66 45 6e 64 3b 0a 20 20 20 20 7d 0a 0a  iBufEnd;.    }..
b9c0: 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d 3e 61      memcpy(&p->a
b9d0: 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 45 6e  Buffer[p->iBufEn
b9e0: 64 5d 2c 20 26 70 44 61 74 61 5b 6e 44 61 74 61  d], &pData[nData
b9f0: 2d 6e 52 65 6d 5d 2c 20 6e 43 6f 70 79 29 3b 0a  -nRem], nCopy);.
ba00: 20 20 20 20 70 2d 3e 69 42 75 66 45 6e 64 20 2b      p->iBufEnd +
ba10: 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 69 66 28  = nCopy;.    if(
ba20: 20 70 2d 3e 69 42 75 66 45 6e 64 3d 3d 70 2d 3e   p->iBufEnd==p->
ba30: 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20 20  nBuffer ){.     
ba40: 20 70 2d 3e 65 46 57 45 72 72 20 3d 20 73 71 6c   p->eFWErr = sql
ba50: 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d 3e 70  ite3OsWrite(p->p
ba60: 46 64 2c 20 0a 20 20 20 20 20 20 20 20 20 20 26  Fd, .          &
ba70: 70 2d 3e 61 42 75 66 66 65 72 5b 70 2d 3e 69 42  p->aBuffer[p->iB
ba80: 75 66 53 74 61 72 74 5d 2c 20 70 2d 3e 69 42 75  ufStart], p->iBu
ba90: 66 45 6e 64 20 2d 20 70 2d 3e 69 42 75 66 53 74  fEnd - p->iBufSt
baa0: 61 72 74 2c 20 0a 20 20 20 20 20 20 20 20 20 20  art, .          
bab0: 70 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b 20 70  p->iWriteOff + p
bac0: 2d 3e 69 42 75 66 53 74 61 72 74 0a 20 20 20 20  ->iBufStart.    
bad0: 20 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e 69 42    );.      p->iB
bae0: 75 66 53 74 61 72 74 20 3d 20 70 2d 3e 69 42 75  ufStart = p->iBu
baf0: 66 45 6e 64 20 3d 20 30 3b 0a 20 20 20 20 20 20  fEnd = 0;.      
bb00: 70 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b 3d 20  p->iWriteOff += 
bb10: 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20 20  p->nBuffer;.    
bb20: 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 2d  }.    assert( p-
bb30: 3e 69 42 75 66 45 6e 64 3c 70 2d 3e 6e 42 75 66  >iBufEnd<p->nBuf
bb40: 66 65 72 20 29 3b 0a 0a 20 20 20 20 6e 52 65 6d  fer );..    nRem
bb50: 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20 7d 0a 7d   -= nCopy;.  }.}
bb60: 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68 20 61 6e  ../*.** Flush an
bb70: 79 20 62 75 66 66 65 72 65 64 20 64 61 74 61 20  y buffered data 
bb80: 74 6f 20 64 69 73 6b 20 61 6e 64 20 63 6c 65 61  to disk and clea
bb90: 6e 20 75 70 20 74 68 65 20 50 4d 41 2d 77 72 69  n up the PMA-wri
bba0: 74 65 72 20 6f 62 6a 65 63 74 2e 0a 2a 2a 20 54  ter object..** T
bbb0: 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20 75 73  he results of us
bbc0: 69 6e 67 20 74 68 65 20 50 4d 41 2d 77 72 69 74  ing the PMA-writ
bbd0: 65 72 20 61 66 74 65 72 20 74 68 69 73 20 63 61  er after this ca
bbe0: 6c 6c 20 61 72 65 20 75 6e 64 65 66 69 6e 65 64  ll are undefined
bbf0: 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 53 51 4c 49  ..** Return SQLI
bc00: 54 45 5f 4f 4b 20 69 66 20 66 6c 75 73 68 69 6e  TE_OK if flushin
bc10: 67 20 74 68 65 20 62 75 66 66 65 72 65 64 20 64  g the buffered d
bc20: 61 74 61 20 73 75 63 63 65 65 64 73 20 6f 72 20  ata succeeds or 
bc30: 69 73 20 6e 6f 74 20 0a 2a 2a 20 72 65 71 75 69  is not .** requi
bc40: 72 65 64 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  red. Otherwise, 
bc50: 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74 65  return an SQLite
bc60: 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a   error code..**.
bc70: 2a 2a 20 42 65 66 6f 72 65 20 72 65 74 75 72 6e  ** Before return
bc80: 69 6e 67 2c 20 73 65 74 20 2a 70 69 45 6f 66 20  ing, set *piEof 
bc90: 74 6f 20 74 68 65 20 6f 66 66 73 65 74 20 69 6d  to the offset im
bca0: 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77  mediately follow
bcb0: 69 6e 67 20 74 68 65 0a 2a 2a 20 6c 61 73 74 20  ing the.** last 
bcc0: 62 79 74 65 20 77 72 69 74 74 65 6e 20 74 6f 20  byte written to 
bcd0: 74 68 65 20 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61  the file..*/.sta
bce0: 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d 61 57  tic int vdbePmaW
bcf0: 72 69 74 65 72 46 69 6e 69 73 68 28 50 6d 61 57  riterFinish(PmaW
bd00: 72 69 74 65 72 20 2a 70 2c 20 69 36 34 20 2a 70  riter *p, i64 *p
bd10: 69 45 6f 66 29 7b 0a 20 20 69 6e 74 20 72 63 3b  iEof){.  int rc;
bd20: 0a 20 20 69 66 28 20 70 2d 3e 65 46 57 45 72 72  .  if( p->eFWErr
bd30: 3d 3d 30 20 26 26 20 41 4c 57 41 59 53 28 70 2d  ==0 && ALWAYS(p-
bd40: 3e 61 42 75 66 66 65 72 29 20 26 26 20 70 2d 3e  >aBuffer) && p->
bd50: 69 42 75 66 45 6e 64 3e 70 2d 3e 69 42 75 66 53  iBufEnd>p->iBufS
bd60: 74 61 72 74 20 29 7b 0a 20 20 20 20 70 2d 3e 65  tart ){.    p->e
bd70: 46 57 45 72 72 20 3d 20 73 71 6c 69 74 65 33 4f  FWErr = sqlite3O
bd80: 73 57 72 69 74 65 28 70 2d 3e 70 46 64 2c 20 0a  sWrite(p->pFd, .
bd90: 20 20 20 20 20 20 20 20 26 70 2d 3e 61 42 75 66          &p->aBuf
bda0: 66 65 72 5b 70 2d 3e 69 42 75 66 53 74 61 72 74  fer[p->iBufStart
bdb0: 5d 2c 20 70 2d 3e 69 42 75 66 45 6e 64 20 2d 20  ], p->iBufEnd - 
bdc0: 70 2d 3e 69 42 75 66 53 74 61 72 74 2c 20 0a 20  p->iBufStart, . 
bdd0: 20 20 20 20 20 20 20 70 2d 3e 69 57 72 69 74 65         p->iWrite
bde0: 4f 66 66 20 2b 20 70 2d 3e 69 42 75 66 53 74 61  Off + p->iBufSta
bdf0: 72 74 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 20 20  rt.    );.  }.  
be00: 2a 70 69 45 6f 66 20 3d 20 28 70 2d 3e 69 57 72  *piEof = (p->iWr
be10: 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42 75 66  iteOff + p->iBuf
be20: 45 6e 64 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  End);.  sqlite3_
be30: 66 72 65 65 28 70 2d 3e 61 42 75 66 66 65 72 29  free(p->aBuffer)
be40: 3b 0a 20 20 72 63 20 3d 20 70 2d 3e 65 46 57 45  ;.  rc = p->eFWE
be50: 72 72 3b 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20  rr;.  memset(p, 
be60: 30 2c 20 73 69 7a 65 6f 66 28 50 6d 61 57 72 69  0, sizeof(PmaWri
be70: 74 65 72 29 29 3b 0a 20 20 72 65 74 75 72 6e 20  ter));.  return 
be80: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69  rc;.}../*.** Wri
be90: 74 65 20 76 61 6c 75 65 20 69 56 61 6c 20 65 6e  te value iVal en
bea0: 63 6f 64 65 64 20 61 73 20 61 20 76 61 72 69 6e  coded as a varin
beb0: 74 20 74 6f 20 74 68 65 20 50 4d 41 2e 20 52 65  t to the PMA. Re
bec0: 74 75 72 6e 20 0a 2a 2a 20 53 51 4c 49 54 45 5f  turn .** SQLITE_
bed0: 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  OK if successful
bee0: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65  , or an SQLite e
bef0: 72 72 6f 72 20 63 6f 64 65 20 69 66 20 61 6e 20  rror code if an 
bf00: 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f  error occurs..*/
bf10: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62  .static void vdb
bf20: 65 50 6d 61 57 72 69 74 65 56 61 72 69 6e 74 28  ePmaWriteVarint(
bf30: 50 6d 61 57 72 69 74 65 72 20 2a 70 2c 20 75 36  PmaWriter *p, u6
bf40: 34 20 69 56 61 6c 29 7b 0a 20 20 69 6e 74 20 6e  4 iVal){.  int n
bf50: 42 79 74 65 3b 20 0a 20 20 75 38 20 61 42 79 74  Byte; .  u8 aByt
bf60: 65 5b 31 30 5d 3b 0a 20 20 6e 42 79 74 65 20 3d  e[10];.  nByte =
bf70: 20 73 71 6c 69 74 65 33 50 75 74 56 61 72 69 6e   sqlite3PutVarin
bf80: 74 28 61 42 79 74 65 2c 20 69 56 61 6c 29 3b 0a  t(aByte, iVal);.
bf90: 20 20 76 64 62 65 50 6d 61 57 72 69 74 65 42 6c    vdbePmaWriteBl
bfa0: 6f 62 28 70 2c 20 61 42 79 74 65 2c 20 6e 42 79  ob(p, aByte, nBy
bfb0: 74 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72  te);.}../*.** Wr
bfc0: 69 74 65 20 74 68 65 20 63 75 72 72 65 6e 74 20  ite the current 
bfd0: 63 6f 6e 74 65 6e 74 73 20 6f 66 20 69 6e 2d 6d  contents of in-m
bfe0: 65 6d 6f 72 79 20 6c 69 6e 6b 65 64 2d 6c 69 73  emory linked-lis
bff0: 74 20 70 4c 69 73 74 20 74 6f 20 61 20 6c 65 76  t pList to a lev
c000: 65 6c 2d 30 0a 2a 2a 20 50 4d 41 20 69 6e 20 74  el-0.** PMA in t
c010: 68 65 20 74 65 6d 70 20 66 69 6c 65 20 62 65 6c  he temp file bel
c020: 6f 6e 67 69 6e 67 20 74 6f 20 73 75 62 2d 74 61  onging to sub-ta
c030: 73 6b 20 70 54 61 73 6b 2e 20 52 65 74 75 72 6e  sk pTask. Return
c040: 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 0a 2a   SQLITE_OK if .*
c050: 2a 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72  * successful, or
c060: 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
c070: 20 63 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e   code otherwise.
c080: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66 6f 72 6d 61  .**.** The forma
c090: 74 20 6f 66 20 61 20 50 4d 41 20 69 73 3a 0a 2a  t of a PMA is:.*
c0a0: 2a 0a 2a 2a 20 20 20 20 20 2a 20 41 20 76 61 72  *.**     * A var
c0b0: 69 6e 74 2e 20 54 68 69 73 20 76 61 72 69 6e 74  int. This varint
c0c0: 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 74 6f   contains the to
c0d0: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79  tal number of by
c0e0: 74 65 73 20 6f 66 20 63 6f 6e 74 65 6e 74 0a 2a  tes of content.*
c0f0: 2a 20 20 20 20 20 20 20 69 6e 20 74 68 65 20 50  *       in the P
c100: 4d 41 20 28 6e 6f 74 20 69 6e 63 6c 75 64 69 6e  MA (not includin
c110: 67 20 74 68 65 20 76 61 72 69 6e 74 20 69 74 73  g the varint its
c120: 65 6c 66 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20  elf)..**.**     
c130: 2a 20 4f 6e 65 20 6f 72 20 6d 6f 72 65 20 72 65  * One or more re
c140: 63 6f 72 64 73 20 70 61 63 6b 65 64 20 65 6e 64  cords packed end
c150: 2d 74 6f 2d 65 6e 64 20 69 6e 20 6f 72 64 65 72  -to-end in order
c160: 20 6f 66 20 61 73 63 65 6e 64 69 6e 67 20 6b 65   of ascending ke
c170: 79 73 2e 20 0a 2a 2a 20 20 20 20 20 20 20 45 61  ys. .**       Ea
c180: 63 68 20 72 65 63 6f 72 64 20 63 6f 6e 73 69 73  ch record consis
c190: 74 73 20 6f 66 20 61 20 76 61 72 69 6e 74 20 66  ts of a varint f
c1a0: 6f 6c 6c 6f 77 65 64 20 62 79 20 61 20 62 6c 6f  ollowed by a blo
c1b0: 62 20 6f 66 20 64 61 74 61 20 28 74 68 65 20 0a  b of data (the .
c1c0: 2a 2a 20 20 20 20 20 20 20 6b 65 79 29 2e 20 54  **       key). T
c1d0: 68 65 20 76 61 72 69 6e 74 20 69 73 20 74 68 65  he varint is the
c1e0: 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   number of bytes
c1f0: 20 69 6e 20 74 68 65 20 62 6c 6f 62 20 6f 66 20   in the blob of 
c200: 64 61 74 61 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  data..*/.static 
c210: 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72 4c 69  int vdbeSorterLi
c220: 73 74 54 6f 50 4d 41 28 53 6f 72 74 53 75 62 74  stToPMA(SortSubt
c230: 61 73 6b 20 2a 70 54 61 73 6b 2c 20 53 6f 72 74  ask *pTask, Sort
c240: 65 72 4c 69 73 74 20 2a 70 4c 69 73 74 29 7b 0a  erList *pList){.
c250: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20 3d 20    sqlite3 *db = 
c260: 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e  pTask->pSorter->
c270: 64 62 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  db;.  int rc = S
c280: 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
c290: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
c2a0: 63 6f 64 65 20 2a 2f 0a 20 20 50 6d 61 57 72 69  code */.  PmaWri
c2b0: 74 65 72 20 77 72 69 74 65 72 3b 20 20 20 20 20  ter writer;     
c2c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a            /* Obj
c2d0: 65 63 74 20 75 73 65 64 20 74 6f 20 77 72 69 74  ect used to writ
c2e0: 65 20 74 6f 20 74 68 65 20 66 69 6c 65 20 2a 2f  e to the file */
c2f0: 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
c300: 44 45 42 55 47 0a 20 20 2f 2a 20 53 65 74 20 69  DEBUG.  /* Set i
c310: 53 7a 20 74 6f 20 74 68 65 20 65 78 70 65 63 74  Sz to the expect
c320: 65 64 20 73 69 7a 65 20 6f 66 20 66 69 6c 65 20  ed size of file 
c330: 70 54 61 73 6b 2d 3e 66 69 6c 65 20 61 66 74 65  pTask->file afte
c340: 72 20 77 72 69 74 69 6e 67 20 74 68 65 20 50 4d  r writing the PM
c350: 41 2e 20 0a 20 20 2a 2a 20 54 68 69 73 20 69 73  A. .  ** This is
c360: 20 75 73 65 64 20 62 79 20 61 6e 20 61 73 73 65   used by an asse
c370: 72 74 28 29 20 73 74 61 74 65 6d 65 6e 74 20 61  rt() statement a
c380: 74 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 69  t the end of thi
c390: 73 20 66 75 6e 63 74 69 6f 6e 2e 20 20 2a 2f 0a  s function.  */.
c3a0: 20 20 69 36 34 20 69 53 7a 20 3d 20 70 4c 69 73    i64 iSz = pLis
c3b0: 74 2d 3e 73 7a 50 4d 41 20 2b 20 73 71 6c 69 74  t->szPMA + sqlit
c3c0: 65 33 56 61 72 69 6e 74 4c 65 6e 28 70 4c 69 73  e3VarintLen(pLis
c3d0: 74 2d 3e 73 7a 50 4d 41 29 20 2b 20 70 54 61 73  t->szPMA) + pTas
c3e0: 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 3b 0a 23 65  k->file.iEof;.#e
c3f0: 6e 64 69 66 0a 0a 20 20 76 64 62 65 53 6f 72 74  ndif..  vdbeSort
c400: 65 72 57 6f 72 6b 44 65 62 75 67 28 70 54 61 73  erWorkDebug(pTas
c410: 6b 2c 20 22 65 6e 74 65 72 22 29 3b 0a 20 20 6d  k, "enter");.  m
c420: 65 6d 73 65 74 28 26 77 72 69 74 65 72 2c 20 30  emset(&writer, 0
c430: 2c 20 73 69 7a 65 6f 66 28 50 6d 61 57 72 69 74  , sizeof(PmaWrit
c440: 65 72 29 29 3b 0a 20 20 61 73 73 65 72 74 28 20  er));.  assert( 
c450: 70 4c 69 73 74 2d 3e 73 7a 50 4d 41 3e 30 20 29  pList->szPMA>0 )
c460: 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 66  ;..  /* If the f
c470: 69 72 73 74 20 74 65 6d 70 6f 72 61 72 79 20 50  irst temporary P
c480: 4d 41 20 66 69 6c 65 20 68 61 73 20 6e 6f 74 20  MA file has not 
c490: 62 65 65 6e 20 6f 70 65 6e 65 64 2c 20 6f 70 65  been opened, ope
c4a0: 6e 20 69 74 20 6e 6f 77 2e 20 2a 2f 0a 20 20 69  n it now. */.  i
c4b0: 66 28 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70  f( pTask->file.p
c4c0: 46 64 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20  Fd==0 ){.    rc 
c4d0: 3d 20 76 64 62 65 53 6f 72 74 65 72 4f 70 65 6e  = vdbeSorterOpen
c4e0: 54 65 6d 70 46 69 6c 65 28 64 62 2c 20 30 2c 20  TempFile(db, 0, 
c4f0: 26 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64  &pTask->file.pFd
c500: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 72  );.    assert( r
c510: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20  c!=SQLITE_OK || 
c520: 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64 20  pTask->file.pFd 
c530: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
c540: 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 3d  Task->file.iEof=
c550: 3d 30 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  =0 );.    assert
c560: 28 20 70 54 61 73 6b 2d 3e 6e 50 4d 41 3d 3d 30  ( pTask->nPMA==0
c570: 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54 72   );.  }..  /* Tr
c580: 79 20 74 6f 20 67 65 74 20 74 68 65 20 66 69 6c  y to get the fil
c590: 65 20 74 6f 20 6d 65 6d 6f 72 79 20 6d 61 70 20  e to memory map 
c5a0: 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  */.  if( rc==SQL
c5b0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 64  ITE_OK ){.    vd
c5c0: 62 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46 69  beSorterExtendFi
c5d0: 6c 65 28 64 62 2c 20 70 54 61 73 6b 2d 3e 66 69  le(db, pTask->fi
c5e0: 6c 65 2e 70 46 64 2c 20 70 54 61 73 6b 2d 3e 66  le.pFd, pTask->f
c5f0: 69 6c 65 2e 69 45 6f 66 2b 70 4c 69 73 74 2d 3e  ile.iEof+pList->
c600: 73 7a 50 4d 41 2b 39 29 3b 0a 20 20 7d 0a 0a 20  szPMA+9);.  }.. 
c610: 20 2f 2a 20 53 6f 72 74 20 74 68 65 20 6c 69 73   /* Sort the lis
c620: 74 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53  t */.  if( rc==S
c630: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
c640: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 53  rc = vdbeSorterS
c650: 6f 72 74 28 70 54 61 73 6b 2c 20 70 4c 69 73 74  ort(pTask, pList
c660: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63  );.  }..  if( rc
c670: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
c680: 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20     SorterRecord 
c690: 2a 70 3b 0a 20 20 20 20 53 6f 72 74 65 72 52 65  *p;.    SorterRe
c6a0: 63 6f 72 64 20 2a 70 4e 65 78 74 20 3d 20 30 3b  cord *pNext = 0;
c6b0: 0a 0a 20 20 20 20 76 64 62 65 50 6d 61 57 72 69  ..    vdbePmaWri
c6c0: 74 65 72 49 6e 69 74 28 70 54 61 73 6b 2d 3e 66  terInit(pTask->f
c6d0: 69 6c 65 2e 70 46 64 2c 20 26 77 72 69 74 65 72  ile.pFd, &writer
c6e0: 2c 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72  , pTask->pSorter
c6f0: 2d 3e 70 67 73 7a 2c 0a 20 20 20 20 20 20 20 20  ->pgsz,.        
c700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 54                pT
c710: 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 29 3b  ask->file.iEof);
c720: 0a 20 20 20 20 70 54 61 73 6b 2d 3e 6e 50 4d 41  .    pTask->nPMA
c730: 2b 2b 3b 0a 20 20 20 20 76 64 62 65 50 6d 61 57  ++;.    vdbePmaW
c740: 72 69 74 65 56 61 72 69 6e 74 28 26 77 72 69 74  riteVarint(&writ
c750: 65 72 2c 20 70 4c 69 73 74 2d 3e 73 7a 50 4d 41  er, pList->szPMA
c760: 29 3b 0a 20 20 20 20 66 6f 72 28 70 3d 70 4c 69  );.    for(p=pLi
c770: 73 74 2d 3e 70 4c 69 73 74 3b 20 70 3b 20 70 3d  st->pList; p; p=
c780: 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 70 4e  pNext){.      pN
c790: 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74  ext = p->u.pNext
c7a0: 3b 0a 20 20 20 20 20 20 76 64 62 65 50 6d 61 57  ;.      vdbePmaW
c7b0: 72 69 74 65 56 61 72 69 6e 74 28 26 77 72 69 74  riteVarint(&writ
c7c0: 65 72 2c 20 70 2d 3e 6e 56 61 6c 29 3b 0a 20 20  er, p->nVal);.  
c7d0: 20 20 20 20 76 64 62 65 50 6d 61 57 72 69 74 65      vdbePmaWrite
c7e0: 42 6c 6f 62 28 26 77 72 69 74 65 72 2c 20 53 52  Blob(&writer, SR
c7f0: 56 41 4c 28 70 29 2c 20 70 2d 3e 6e 56 61 6c 29  VAL(p), p->nVal)
c800: 3b 0a 20 20 20 20 20 20 69 66 28 20 70 4c 69 73  ;.      if( pLis
c810: 74 2d 3e 61 4d 65 6d 6f 72 79 3d 3d 30 20 29 20  t->aMemory==0 ) 
c820: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b  sqlite3_free(p);
c830: 0a 20 20 20 20 7d 0a 20 20 20 20 70 4c 69 73 74  .    }.    pList
c840: 2d 3e 70 4c 69 73 74 20 3d 20 70 3b 0a 20 20 20  ->pList = p;.   
c850: 20 72 63 20 3d 20 76 64 62 65 50 6d 61 57 72 69   rc = vdbePmaWri
c860: 74 65 72 46 69 6e 69 73 68 28 26 77 72 69 74 65  terFinish(&write
c870: 72 2c 20 26 70 54 61 73 6b 2d 3e 66 69 6c 65 2e  r, &pTask->file.
c880: 69 45 6f 66 29 3b 0a 20 20 7d 0a 0a 20 20 76 64  iEof);.  }..  vd
c890: 62 65 53 6f 72 74 65 72 57 6f 72 6b 44 65 62 75  beSorterWorkDebu
c8a0: 67 28 70 54 61 73 6b 2c 20 22 65 78 69 74 22 29  g(pTask, "exit")
c8b0: 3b 0a 20 20 61 73 73 65 72 74 28 20 72 63 21 3d  ;.  assert( rc!=
c8c0: 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 4c 69  SQLITE_OK || pLi
c8d0: 73 74 2d 3e 70 4c 69 73 74 3d 3d 30 20 29 3b 0a  st->pList==0 );.
c8e0: 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51    assert( rc!=SQ
c8f0: 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 54 61 73 6b  LITE_OK || pTask
c900: 2d 3e 66 69 6c 65 2e 69 45 6f 66 3d 3d 69 53 7a  ->file.iEof==iSz
c910: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   );.  return rc;
c920: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63  .}../*.** Advanc
c930: 65 20 74 68 65 20 4d 65 72 67 65 45 6e 67 69 6e  e the MergeEngin
c940: 65 20 70 4d 65 72 67 65 20 28 70 61 73 73 65 64  e pMerge (passed
c950: 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61   as the second a
c960: 72 67 75 6d 65 6e 74 29 20 74 6f 0a 2a 2a 20 69  rgument) to.** i
c970: 74 73 20 6e 65 78 74 20 65 6e 74 72 79 2e 20 20  ts next entry.  
c980: 53 65 74 20 2a 70 62 45 6f 66 20 74 6f 20 74 72  Set *pbEof to tr
c990: 75 65 20 74 68 65 72 65 20 69 73 20 6e 6f 20 6e  ue there is no n
c9a0: 65 78 74 20 65 6e 74 72 79 20 62 65 63 61 75 73  ext entry becaus
c9b0: 65 0a 2a 2a 20 74 68 65 20 4d 65 72 67 65 45 6e  e.** the MergeEn
c9c0: 67 69 6e 65 20 68 61 73 20 72 65 61 63 68 65 64  gine has reached
c9d0: 20 74 68 65 20 65 6e 64 20 6f 66 20 61 6c 6c 20   the end of all 
c9e0: 69 74 73 20 69 6e 70 75 74 73 2e 0a 2a 2a 0a 2a  its inputs..**.*
c9f0: 2a 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  * Return SQLITE_
ca00: 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  OK if successful
ca10: 20 6f 72 20 61 6e 20 65 72 72 6f 72 20 63 6f 64   or an error cod
ca20: 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  e if an error oc
ca30: 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  curs..*/.static 
ca40: 69 6e 74 20 76 64 62 65 4d 65 72 67 65 45 6e 67  int vdbeMergeEng
ca50: 69 6e 65 53 74 65 70 28 0a 20 20 53 6f 72 74 53  ineStep(.  SortS
ca60: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20  ubtask *pTask,  
ca70: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 74 68 72        /* The thr
ca80: 65 61 64 20 69 6e 20 77 68 69 63 68 20 74 68 69  ead in which thi
ca90: 73 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 72 75  s MergeEngine ru
caa0: 6e 73 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67  ns */.  MergeEng
cab0: 69 6e 65 20 2a 70 4d 65 72 67 65 72 2c 20 20 20  ine *pMerger,   
cac0: 20 20 20 2f 2a 20 54 68 65 20 6d 65 72 67 65 20     /* The merge 
cad0: 65 6e 67 69 6e 65 20 74 6f 20 61 64 76 61 6e 63  engine to advanc
cae0: 65 20 74 6f 20 74 68 65 20 6e 65 78 74 20 72 6f  e to the next ro
caf0: 77 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 62 45 6f  w */.  int *pbEo
cb00: 66 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f               
cb10: 20 20 2f 2a 20 53 65 74 20 54 52 55 45 20 61 74    /* Set TRUE at
cb20: 20 45 4f 46 2e 20 20 53 65 74 20 66 61 6c 73 65   EOF.  Set false
cb30: 20 66 6f 72 20 6d 6f 72 65 20 63 6f 6e 74 65 6e   for more conten
cb40: 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63  t */.){.  int rc
cb50: 3b 0a 20 20 69 6e 74 20 69 50 72 65 76 20 3d 20  ;.  int iPrev = 
cb60: 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 31  pMerger->aTree[1
cb70: 5d 3b 2f 2a 20 49 6e 64 65 78 20 6f 66 20 50 6d  ];/* Index of Pm
cb80: 61 52 65 61 64 65 72 20 74 6f 20 61 64 76 61 6e  aReader to advan
cb90: 63 65 20 2a 2f 0a 0a 20 20 2f 2a 20 41 20 4d 65  ce */..  /* A Me
cba0: 72 67 65 45 6e 67 69 6e 65 20 6f 62 6a 65 63 74  rgeEngine object
cbb0: 20 69 73 20 6f 6e 6c 79 20 75 73 65 64 20 62 79   is only used by
cbc0: 20 61 20 73 69 6e 67 6c 65 20 74 68 72 65 61 64   a single thread
cbd0: 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 4d   */.  assert( pM
cbe0: 65 72 67 65 72 2d 3e 70 54 61 73 6b 3d 3d 30 20  erger->pTask==0 
cbf0: 7c 7c 20 70 4d 65 72 67 65 72 2d 3e 70 54 61 73  || pMerger->pTas
cc00: 6b 3d 3d 70 54 61 73 6b 20 29 3b 0a 20 20 70 4d  k==pTask );.  pM
cc10: 65 72 67 65 72 2d 3e 70 54 61 73 6b 20 3d 20 70  erger->pTask = p
cc20: 54 61 73 6b 3b 0a 0a 20 20 2f 2a 20 41 64 76 61  Task;..  /* Adva
cc30: 6e 63 65 20 74 68 65 20 63 75 72 72 65 6e 74 20  nce the current 
cc40: 50 6d 61 52 65 61 64 65 72 20 2a 2f 0a 20 20 72  PmaReader */.  r
cc50: 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65  c = vdbePmaReade
cc60: 72 4e 65 78 74 28 26 70 4d 65 72 67 65 72 2d 3e  rNext(&pMerger->
cc70: 61 52 65 61 64 72 5b 69 50 72 65 76 5d 29 3b 0a  aReadr[iPrev]);.
cc80: 0a 20 20 2f 2a 20 55 70 64 61 74 65 20 63 6f 6e  .  /* Update con
cc90: 74 65 6e 74 73 20 6f 66 20 61 54 72 65 65 5b 5d  tents of aTree[]
cca0: 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   */.  if( rc==SQ
ccb0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69  LITE_OK ){.    i
ccc0: 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20  nt i;           
ccd0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
cce0: 64 65 78 20 6f 66 20 61 54 72 65 65 5b 5d 20 74  dex of aTree[] t
ccf0: 6f 20 72 65 63 61 6c 63 75 6c 61 74 65 20 2a 2f  o recalculate */
cd00: 0a 20 20 20 20 50 6d 61 52 65 61 64 65 72 20 2a  .    PmaReader *
cd10: 70 52 65 61 64 72 31 3b 20 20 20 20 20 20 20 20  pReadr1;        
cd20: 20 2f 2a 20 46 69 72 73 74 20 50 6d 61 52 65 61   /* First PmaRea
cd30: 64 65 72 20 74 6f 20 63 6f 6d 70 61 72 65 20 2a  der to compare *
cd40: 2f 0a 20 20 20 20 50 6d 61 52 65 61 64 65 72 20  /.    PmaReader 
cd50: 2a 70 52 65 61 64 72 32 3b 20 20 20 20 20 20 20  *pReadr2;       
cd60: 20 20 2f 2a 20 53 65 63 6f 6e 64 20 50 6d 61 52    /* Second PmaR
cd70: 65 61 64 65 72 20 74 6f 20 63 6f 6d 70 61 72 65  eader to compare
cd80: 20 2a 2f 0a 20 20 20 20 75 38 20 2a 70 4b 65 79   */.    u8 *pKey
cd90: 32 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  2;              
cda0: 20 20 20 20 2f 2a 20 54 6f 20 70 52 65 61 64 72      /* To pReadr
cdb0: 32 2d 3e 61 4b 65 79 2c 20 6f 72 20 30 20 69 66  2->aKey, or 0 if
cdc0: 20 72 65 63 6f 72 64 20 63 61 63 68 65 64 20 2a   record cached *
cdd0: 2f 0a 0a 20 20 20 20 2f 2a 20 46 69 6e 64 20 74  /..    /* Find t
cde0: 68 65 20 66 69 72 73 74 20 74 77 6f 20 50 6d 61  he first two Pma
cdf0: 52 65 61 64 65 72 73 20 74 6f 20 63 6f 6d 70 61  Readers to compa
ce00: 72 65 2e 20 54 68 65 20 6f 6e 65 20 74 68 61 74  re. The one that
ce10: 20 77 61 73 20 6a 75 73 74 0a 20 20 20 20 2a 2a   was just.    **
ce20: 20 61 64 76 61 6e 63 65 64 20 28 69 50 72 65 76   advanced (iPrev
ce30: 29 20 61 6e 64 20 74 68 65 20 6f 6e 65 20 6e 65  ) and the one ne
ce40: 78 74 20 74 6f 20 69 74 20 69 6e 20 74 68 65 20  xt to it in the 
ce50: 61 72 72 61 79 2e 20 20 2a 2f 0a 20 20 20 20 70  array.  */.    p
ce60: 52 65 61 64 72 31 20 3d 20 26 70 4d 65 72 67 65  Readr1 = &pMerge
ce70: 72 2d 3e 61 52 65 61 64 72 5b 28 69 50 72 65 76  r->aReadr[(iPrev
ce80: 20 26 20 30 78 46 46 46 45 29 5d 3b 0a 20 20 20   & 0xFFFE)];.   
ce90: 20 70 52 65 61 64 72 32 20 3d 20 26 70 4d 65 72   pReadr2 = &pMer
cea0: 67 65 72 2d 3e 61 52 65 61 64 72 5b 28 69 50 72  ger->aReadr[(iPr
ceb0: 65 76 20 7c 20 30 78 30 30 30 31 29 5d 3b 0a 20  ev | 0x0001)];. 
cec0: 20 20 20 70 4b 65 79 32 20 3d 20 70 52 65 61 64     pKey2 = pRead
ced0: 72 32 2d 3e 61 4b 65 79 3b 0a 0a 20 20 20 20 66  r2->aKey;..    f
cee0: 6f 72 28 69 3d 28 70 4d 65 72 67 65 72 2d 3e 6e  or(i=(pMerger->n
cef0: 54 72 65 65 2b 69 50 72 65 76 29 2f 32 3b 20 69  Tree+iPrev)/2; i
cf00: 3e 30 3b 20 69 3d 69 2f 32 29 7b 0a 20 20 20 20  >0; i=i/2){.    
cf10: 20 20 2f 2a 20 43 6f 6d 70 61 72 65 20 70 52 65    /* Compare pRe
cf20: 61 64 72 31 20 61 6e 64 20 70 52 65 61 64 72 32  adr1 and pReadr2
cf30: 2e 20 53 74 6f 72 65 20 74 68 65 20 72 65 73 75  . Store the resu
cf40: 6c 74 20 69 6e 20 76 61 72 69 61 62 6c 65 20 69  lt in variable i
cf50: 52 65 73 2e 20 2a 2f 0a 20 20 20 20 20 20 69 6e  Res. */.      in
cf60: 74 20 69 52 65 73 3b 0a 20 20 20 20 20 20 69 66  t iRes;.      if
cf70: 28 20 70 52 65 61 64 72 31 2d 3e 70 46 64 3d 3d  ( pReadr1->pFd==
cf80: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 69 52 65  0 ){.        iRe
cf90: 73 20 3d 20 2b 31 3b 0a 20 20 20 20 20 20 7d 65  s = +1;.      }e
cfa0: 6c 73 65 20 69 66 28 20 70 52 65 61 64 72 32 2d  lse if( pReadr2-
cfb0: 3e 70 46 64 3d 3d 30 20 29 7b 0a 20 20 20 20 20  >pFd==0 ){.     
cfc0: 20 20 20 69 52 65 73 20 3d 20 2d 31 3b 0a 20 20     iRes = -1;.  
cfd0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
cfe0: 20 20 20 69 52 65 73 20 3d 20 76 64 62 65 53 6f     iRes = vdbeSo
cff0: 72 74 65 72 43 6f 6d 70 61 72 65 28 70 54 61 73  rterCompare(pTas
d000: 6b 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 20  k, .            
d010: 70 52 65 61 64 72 31 2d 3e 61 4b 65 79 2c 20 70  pReadr1->aKey, p
d020: 52 65 61 64 72 31 2d 3e 6e 4b 65 79 2c 20 70 4b  Readr1->nKey, pK
d030: 65 79 32 2c 20 70 52 65 61 64 72 32 2d 3e 6e 4b  ey2, pReadr2->nK
d040: 65 79 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 20  ey.        );.  
d050: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20      }..      /* 
d060: 49 66 20 70 52 65 61 64 72 31 20 63 6f 6e 74 61  If pReadr1 conta
d070: 69 6e 65 64 20 74 68 65 20 73 6d 61 6c 6c 65 72  ined the smaller
d080: 20 76 61 6c 75 65 2c 20 73 65 74 20 61 54 72 65   value, set aTre
d090: 65 5b 69 5d 20 74 6f 20 69 74 73 20 69 6e 64 65  e[i] to its inde
d0a0: 78 2e 0a 20 20 20 20 20 20 2a 2a 20 54 68 65 6e  x..      ** Then
d0b0: 20 73 65 74 20 70 52 65 61 64 72 32 20 74 6f 20   set pReadr2 to 
d0c0: 74 68 65 20 6e 65 78 74 20 50 6d 61 52 65 61 64  the next PmaRead
d0d0: 65 72 20 74 6f 20 63 6f 6d 70 61 72 65 20 74 6f  er to compare to
d0e0: 20 70 52 65 61 64 72 31 2e 20 49 6e 20 74 68 69   pReadr1. In thi
d0f0: 73 0a 20 20 20 20 20 20 2a 2a 20 63 61 73 65 20  s.      ** case 
d100: 74 68 65 72 65 20 69 73 20 6e 6f 20 63 61 63 68  there is no cach
d110: 65 20 6f 66 20 70 52 65 61 64 72 32 20 69 6e 20  e of pReadr2 in 
d120: 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64  pTask->pUnpacked
d130: 2c 20 73 6f 20 73 65 74 0a 20 20 20 20 20 20 2a  , so set.      *
d140: 2a 20 70 4b 65 79 32 20 74 6f 20 70 6f 69 6e 74  * pKey2 to point
d150: 20 74 6f 20 74 68 65 20 72 65 63 6f 72 64 20 62   to the record b
d160: 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 70 52 65 61  elonging to pRea
d170: 64 72 32 2e 0a 20 20 20 20 20 20 2a 2a 0a 20 20  dr2..      **.  
d180: 20 20 20 20 2a 2a 20 41 6c 74 65 72 6e 61 74 69      ** Alternati
d190: 76 65 6c 79 2c 20 69 66 20 70 52 65 61 64 72 32  vely, if pReadr2
d1a0: 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 73 6d   contains the sm
d1b0: 61 6c 6c 65 72 20 6f 66 20 74 68 65 20 74 77 6f  aller of the two
d1c0: 20 76 61 6c 75 65 73 2c 0a 20 20 20 20 20 20 2a   values,.      *
d1d0: 2a 20 73 65 74 20 61 54 72 65 65 5b 69 5d 20 74  * set aTree[i] t
d1e0: 6f 20 69 74 73 20 69 6e 64 65 78 20 61 6e 64 20  o its index and 
d1f0: 75 70 64 61 74 65 20 70 52 65 61 64 72 31 2e 20  update pReadr1. 
d200: 49 66 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d  If vdbeSorterCom
d210: 70 61 72 65 28 29 0a 20 20 20 20 20 20 2a 2a 20  pare().      ** 
d220: 77 61 73 20 61 63 74 75 61 6c 6c 79 20 63 61 6c  was actually cal
d230: 6c 65 64 20 61 62 6f 76 65 2c 20 74 68 65 6e 20  led above, then 
d240: 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64  pTask->pUnpacked
d250: 20 6e 6f 77 20 63 6f 6e 74 61 69 6e 73 0a 20 20   now contains.  
d260: 20 20 20 20 2a 2a 20 61 20 76 61 6c 75 65 20 65      ** a value e
d270: 71 75 69 76 61 6c 65 6e 74 20 74 6f 20 70 52 65  quivalent to pRe
d280: 61 64 72 32 2e 20 53 6f 20 73 65 74 20 70 4b 65  adr2. So set pKe
d290: 79 32 20 74 6f 20 4e 55 4c 4c 20 74 6f 20 70 72  y2 to NULL to pr
d2a0: 65 76 65 6e 74 0a 20 20 20 20 20 20 2a 2a 20 76  event.      ** v
d2b0: 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65  dbeSorterCompare
d2c0: 28 29 20 66 72 6f 6d 20 64 65 63 6f 64 69 6e 67  () from decoding
d2d0: 20 70 52 65 61 64 72 32 20 61 67 61 69 6e 2e 0a   pReadr2 again..
d2e0: 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a        **.      *
d2f0: 2a 20 49 66 20 74 68 65 20 74 77 6f 20 76 61 6c  * If the two val
d300: 75 65 73 20 77 65 72 65 20 65 71 75 61 6c 2c 20  ues were equal, 
d310: 74 68 65 6e 20 74 68 65 20 76 61 6c 75 65 20 66  then the value f
d320: 72 6f 6d 20 74 68 65 20 6f 6c 64 65 73 74 0a 20  rom the oldest. 
d330: 20 20 20 20 20 2a 2a 20 50 4d 41 20 73 68 6f 75       ** PMA shou
d340: 6c 64 20 62 65 20 63 6f 6e 73 69 64 65 72 65 64  ld be considered
d350: 20 73 6d 61 6c 6c 65 72 2e 20 54 68 65 20 56 64   smaller. The Vd
d360: 62 65 53 6f 72 74 65 72 2e 61 52 65 61 64 72 5b  beSorter.aReadr[
d370: 5d 20 61 72 72 61 79 0a 20 20 20 20 20 20 2a 2a  ] array.      **
d380: 20 69 73 20 73 6f 72 74 65 64 20 66 72 6f 6d 20   is sorted from 
d390: 6f 6c 64 65 73 74 20 74 6f 20 6e 65 77 65 73 74  oldest to newest
d3a0: 2c 20 73 6f 20 70 52 65 61 64 72 31 20 63 6f 6e  , so pReadr1 con
d3b0: 74 61 69 6e 73 20 6f 6c 64 65 72 20 76 61 6c 75  tains older valu
d3c0: 65 73 0a 20 20 20 20 20 20 2a 2a 20 74 68 61 6e  es.      ** than
d3d0: 20 70 52 65 61 64 72 32 20 69 66 66 20 28 70 52   pReadr2 iff (pR
d3e0: 65 61 64 72 31 3c 70 52 65 61 64 72 32 29 2e 20  eadr1<pReadr2). 
d3f0: 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 69 52   */.      if( iR
d400: 65 73 3c 30 20 7c 7c 20 28 69 52 65 73 3d 3d 30  es<0 || (iRes==0
d410: 20 26 26 20 70 52 65 61 64 72 31 3c 70 52 65 61   && pReadr1<pRea
d420: 64 72 32 29 20 29 7b 0a 20 20 20 20 20 20 20 20  dr2) ){.        
d430: 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69  pMerger->aTree[i
d440: 5d 20 3d 20 28 69 6e 74 29 28 70 52 65 61 64 72  ] = (int)(pReadr
d450: 31 20 2d 20 70 4d 65 72 67 65 72 2d 3e 61 52 65  1 - pMerger->aRe
d460: 61 64 72 29 3b 0a 20 20 20 20 20 20 20 20 70 52  adr);.        pR
d470: 65 61 64 72 32 20 3d 20 26 70 4d 65 72 67 65 72  eadr2 = &pMerger
d480: 2d 3e 61 52 65 61 64 72 5b 20 70 4d 65 72 67 65  ->aReadr[ pMerge
d490: 72 2d 3e 61 54 72 65 65 5b 69 20 5e 20 30 78 30  r->aTree[i ^ 0x0
d4a0: 30 30 31 5d 20 5d 3b 0a 20 20 20 20 20 20 20 20  001] ];.        
d4b0: 70 4b 65 79 32 20 3d 20 70 52 65 61 64 72 32 2d  pKey2 = pReadr2-
d4c0: 3e 61 4b 65 79 3b 0a 20 20 20 20 20 20 7d 65 6c  >aKey;.      }el
d4d0: 73 65 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20  se{.        if( 
d4e0: 70 52 65 61 64 72 31 2d 3e 70 46 64 20 29 20 70  pReadr1->pFd ) p
d4f0: 4b 65 79 32 20 3d 20 30 3b 0a 20 20 20 20 20 20  Key2 = 0;.      
d500: 20 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65    pMerger->aTree
d510: 5b 69 5d 20 3d 20 28 69 6e 74 29 28 70 52 65 61  [i] = (int)(pRea
d520: 64 72 32 20 2d 20 70 4d 65 72 67 65 72 2d 3e 61  dr2 - pMerger->a
d530: 52 65 61 64 72 29 3b 0a 20 20 20 20 20 20 20 20  Readr);.        
d540: 70 52 65 61 64 72 31 20 3d 20 26 70 4d 65 72 67  pReadr1 = &pMerg
d550: 65 72 2d 3e 61 52 65 61 64 72 5b 20 70 4d 65 72  er->aReadr[ pMer
d560: 67 65 72 2d 3e 61 54 72 65 65 5b 69 20 5e 20 30  ger->aTree[i ^ 0
d570: 78 30 30 30 31 5d 20 5d 3b 0a 20 20 20 20 20 20  x0001] ];.      
d580: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 2a 70 62 45  }.    }.    *pbE
d590: 6f 66 20 3d 20 28 70 4d 65 72 67 65 72 2d 3e 61  of = (pMerger->a
d5a0: 52 65 61 64 72 5b 70 4d 65 72 67 65 72 2d 3e 61  Readr[pMerger->a
d5b0: 54 72 65 65 5b 31 5d 5d 2e 70 46 64 3d 3d 30 29  Tree[1]].pFd==0)
d5c0: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
d5d0: 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 3f  (rc==SQLITE_OK ?
d5e0: 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65   pTask->pUnpacke
d5f0: 64 2d 3e 65 72 72 43 6f 64 65 20 3a 20 72 63 29  d->errCode : rc)
d600: 3b 0a 7d 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f  ;.}..#if SQLITE_
d610: 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41  MAX_WORKER_THREA
d620: 44 53 3e 30 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d  DS>0./*.** The m
d630: 61 69 6e 20 72 6f 75 74 69 6e 65 20 66 6f 72 20  ain routine for 
d640: 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61  background threa
d650: 64 73 20 74 68 61 74 20 77 72 69 74 65 20 6c 65  ds that write le
d660: 76 65 6c 2d 30 20 50 4d 41 73 2e 0a 2a 2f 0a 73  vel-0 PMAs..*/.s
d670: 74 61 74 69 63 20 76 6f 69 64 20 2a 76 64 62 65  tatic void *vdbe
d680: 53 6f 72 74 65 72 46 6c 75 73 68 54 68 72 65 61  SorterFlushThrea
d690: 64 28 76 6f 69 64 20 2a 70 43 74 78 29 7b 0a 20  d(void *pCtx){. 
d6a0: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
d6b0: 61 73 6b 20 3d 20 28 53 6f 72 74 53 75 62 74 61  ask = (SortSubta
d6c0: 73 6b 2a 29 70 43 74 78 3b 0a 20 20 69 6e 74 20  sk*)pCtx;.  int 
d6d0: 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rc;             
d6e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
d6f0: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
d700: 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 62  assert( pTask->b
d710: 44 6f 6e 65 3d 3d 30 20 29 3b 0a 20 20 72 63 20  Done==0 );.  rc 
d720: 3d 20 76 64 62 65 53 6f 72 74 65 72 4c 69 73 74  = vdbeSorterList
d730: 54 6f 50 4d 41 28 70 54 61 73 6b 2c 20 26 70 54  ToPMA(pTask, &pT
d740: 61 73 6b 2d 3e 6c 69 73 74 29 3b 0a 20 20 70 54  ask->list);.  pT
d750: 61 73 6b 2d 3e 62 44 6f 6e 65 20 3d 20 31 3b 0a  ask->bDone = 1;.
d760: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
d770: 49 4e 54 5f 54 4f 5f 50 54 52 28 72 63 29 3b 0a  INT_TO_PTR(rc);.
d780: 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49  }.#endif /* SQLI
d790: 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48  TE_MAX_WORKER_TH
d7a0: 52 45 41 44 53 3e 30 20 2a 2f 0a 0a 2f 2a 0a 2a  READS>0 */../*.*
d7b0: 2a 20 46 6c 75 73 68 20 74 68 65 20 63 75 72 72  * Flush the curr
d7c0: 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  ent contents of 
d7d0: 56 64 62 65 53 6f 72 74 65 72 2e 6c 69 73 74 20  VdbeSorter.list 
d7e0: 74 6f 20 61 20 6e 65 77 20 50 4d 41 2c 20 70 6f  to a new PMA, po
d7f0: 73 73 69 62 6c 79 0a 2a 2a 20 75 73 69 6e 67 20  ssibly.** using 
d800: 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  a background thr
d810: 65 61 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ead..*/.static i
d820: 6e 74 20 76 64 62 65 53 6f 72 74 65 72 46 6c 75  nt vdbeSorterFlu
d830: 73 68 50 4d 41 28 56 64 62 65 53 6f 72 74 65 72  shPMA(VdbeSorter
d840: 20 2a 70 53 6f 72 74 65 72 29 7b 0a 23 69 66 20   *pSorter){.#if 
d850: 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45  SQLITE_MAX_WORKE
d860: 52 5f 54 48 52 45 41 44 53 3d 3d 30 0a 20 20 70  R_THREADS==0.  p
d870: 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41 20  Sorter->bUsePMA 
d880: 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 76 64  = 1;.  return vd
d890: 62 65 53 6f 72 74 65 72 4c 69 73 74 54 6f 50 4d  beSorterListToPM
d8a0: 41 28 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73  A(&pSorter->aTas
d8b0: 6b 5b 30 5d 2c 20 26 70 53 6f 72 74 65 72 2d 3e  k[0], &pSorter->
d8c0: 6c 69 73 74 29 3b 0a 23 65 6c 73 65 0a 20 20 69  list);.#else.  i
d8d0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
d8e0: 4b 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 53 6f  K;.  int i;.  So
d8f0: 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b  rtSubtask *pTask
d900: 20 3d 20 30 3b 20 20 20 20 2f 2a 20 54 68 72 65   = 0;    /* Thre
d910: 61 64 20 63 6f 6e 74 65 78 74 20 75 73 65 64 20  ad context used 
d920: 74 6f 20 63 72 65 61 74 65 20 6e 65 77 20 50 4d  to create new PM
d930: 41 20 2a 2f 0a 20 20 69 6e 74 20 6e 57 6f 72 6b  A */.  int nWork
d940: 65 72 20 3d 20 28 70 53 6f 72 74 65 72 2d 3e 6e  er = (pSorter->n
d950: 54 61 73 6b 2d 31 29 3b 0a 0a 20 20 2f 2a 20 53  Task-1);..  /* S
d960: 65 74 20 74 68 65 20 66 6c 61 67 20 74 6f 20 69  et the flag to i
d970: 6e 64 69 63 61 74 65 20 74 68 61 74 20 61 74 20  ndicate that at 
d980: 6c 65 61 73 74 20 6f 6e 65 20 50 4d 41 20 68 61  least one PMA ha
d990: 73 20 62 65 65 6e 20 77 72 69 74 74 65 6e 2e 20  s been written. 
d9a0: 0a 20 20 2a 2a 20 4f 72 20 77 69 6c 6c 20 62 65  .  ** Or will be
d9b0: 2c 20 61 6e 79 68 6f 77 2e 20 20 2a 2f 0a 20 20  , anyhow.  */.  
d9c0: 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41  pSorter->bUsePMA
d9d0: 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20 53 65 6c 65   = 1;..  /* Sele
d9e0: 63 74 20 61 20 73 75 62 2d 74 61 73 6b 20 74 6f  ct a sub-task to
d9f0: 20 73 6f 72 74 20 61 6e 64 20 66 6c 75 73 68 20   sort and flush 
da00: 74 68 65 20 63 75 72 72 65 6e 74 20 6c 69 73 74  the current list
da10: 20 6f 66 20 69 6e 2d 6d 65 6d 6f 72 79 0a 20 20   of in-memory.  
da20: 2a 2a 20 72 65 63 6f 72 64 73 20 74 6f 20 64 69  ** records to di
da30: 73 6b 2e 20 49 66 20 74 68 65 20 73 6f 72 74 65  sk. If the sorte
da40: 72 20 69 73 20 72 75 6e 6e 69 6e 67 20 69 6e 20  r is running in 
da50: 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20 6d  multi-threaded m
da60: 6f 64 65 2c 0a 20 20 2a 2a 20 72 6f 75 6e 64 2d  ode,.  ** round-
da70: 72 6f 62 69 6e 20 62 65 74 77 65 65 6e 20 74 68  robin between th
da80: 65 20 66 69 72 73 74 20 28 70 53 6f 72 74 65 72  e first (pSorter
da90: 2d 3e 6e 54 61 73 6b 2d 31 29 20 74 61 73 6b 73  ->nTask-1) tasks
daa0: 2e 20 45 78 63 65 70 74 2c 20 69 66 0a 20 20 2a  . Except, if.  *
dab0: 2a 20 74 68 65 20 62 61 63 6b 67 72 6f 75 6e 64  * the background
dac0: 20 74 68 72 65 61 64 20 66 72 6f 6d 20 61 20 73   thread from a s
dad0: 75 62 2d 74 61 73 6b 73 20 70 72 65 76 69 6f 75  ub-tasks previou
dae0: 73 20 74 75 72 6e 20 69 73 20 73 74 69 6c 6c 20  s turn is still 
daf0: 72 75 6e 6e 69 6e 67 2c 0a 20 20 2a 2a 20 73 6b  running,.  ** sk
db00: 69 70 20 69 74 2e 20 49 66 20 74 68 65 20 66 69  ip it. If the fi
db10: 72 73 74 20 28 70 53 6f 72 74 65 72 2d 3e 6e 54  rst (pSorter->nT
db20: 61 73 6b 2d 31 29 20 73 75 62 2d 74 61 73 6b 73  ask-1) sub-tasks
db30: 20 61 72 65 20 61 6c 6c 20 73 74 69 6c 6c 20 62   are all still b
db40: 75 73 79 2c 0a 20 20 2a 2a 20 66 61 6c 6c 20 62  usy,.  ** fall b
db50: 61 63 6b 20 74 6f 20 75 73 69 6e 67 20 74 68 65  ack to using the
db60: 20 66 69 6e 61 6c 20 73 75 62 2d 74 61 73 6b 2e   final sub-task.
db70: 20 54 68 65 20 66 69 72 73 74 20 28 70 53 6f 72   The first (pSor
db80: 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 0a 20 20  ter->nTask-1).  
db90: 2a 2a 20 73 75 62 2d 74 61 73 6b 73 20 61 72 65  ** sub-tasks are
dba0: 20 70 72 65 66 65 72 65 64 20 61 73 20 74 68 65   prefered as the
dbb0: 79 20 75 73 65 20 62 61 63 6b 67 72 6f 75 6e 64  y use background
dbc0: 20 74 68 72 65 61 64 73 20 2d 20 74 68 65 20 66   threads - the f
dbd0: 69 6e 61 6c 20 0a 20 20 2a 2a 20 73 75 62 2d 74  inal .  ** sub-t
dbe0: 61 73 6b 20 75 73 65 73 20 74 68 65 20 6d 61 69  ask uses the mai
dbf0: 6e 20 74 68 72 65 61 64 2e 20 2a 2f 0a 20 20 66  n thread. */.  f
dc00: 6f 72 28 69 3d 30 3b 20 69 3c 6e 57 6f 72 6b 65  or(i=0; i<nWorke
dc10: 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74  r; i++){.    int
dc20: 20 69 54 65 73 74 20 3d 20 28 70 53 6f 72 74 65   iTest = (pSorte
dc30: 72 2d 3e 69 50 72 65 76 20 2b 20 69 20 2b 20 31  r->iPrev + i + 1
dc40: 29 20 25 20 6e 57 6f 72 6b 65 72 3b 0a 20 20 20  ) % nWorker;.   
dc50: 20 70 54 61 73 6b 20 3d 20 26 70 53 6f 72 74 65   pTask = &pSorte
dc60: 72 2d 3e 61 54 61 73 6b 5b 69 54 65 73 74 5d 3b  r->aTask[iTest];
dc70: 0a 20 20 20 20 69 66 28 20 70 54 61 73 6b 2d 3e  .    if( pTask->
dc80: 62 44 6f 6e 65 20 29 7b 0a 20 20 20 20 20 20 72  bDone ){.      r
dc90: 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4a 6f  c = vdbeSorterJo
dca0: 69 6e 54 68 72 65 61 64 28 70 54 61 73 6b 29 3b  inThread(pTask);
dcb0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72  .    }.    if( r
dcc0: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20  c!=SQLITE_OK || 
dcd0: 70 54 61 73 6b 2d 3e 70 54 68 72 65 61 64 3d 3d  pTask->pThread==
dce0: 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a  0 ) break;.  }..
dcf0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
dd00: 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 66 28 20 69  _OK ){.    if( i
dd10: 3d 3d 6e 57 6f 72 6b 65 72 20 29 7b 0a 20 20 20  ==nWorker ){.   
dd20: 20 20 20 2f 2a 20 55 73 65 20 74 68 65 20 66 6f     /* Use the fo
dd30: 72 65 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  reground thread 
dd40: 66 6f 72 20 74 68 69 73 20 6f 70 65 72 61 74 69  for this operati
dd50: 6f 6e 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d  on */.      rc =
dd60: 20 76 64 62 65 53 6f 72 74 65 72 4c 69 73 74 54   vdbeSorterListT
dd70: 6f 50 4d 41 28 26 70 53 6f 72 74 65 72 2d 3e 61  oPMA(&pSorter->a
dd80: 54 61 73 6b 5b 6e 57 6f 72 6b 65 72 5d 2c 20 26  Task[nWorker], &
dd90: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 29 3b 0a  pSorter->list);.
dda0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
ddb0: 20 2f 2a 20 4c 61 75 6e 63 68 20 61 20 62 61 63   /* Launch a bac
ddc0: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 66  kground thread f
ddd0: 6f 72 20 74 68 69 73 20 6f 70 65 72 61 74 69 6f  or this operatio
dde0: 6e 20 2a 2f 0a 20 20 20 20 20 20 75 38 20 2a 61  n */.      u8 *a
ddf0: 4d 65 6d 20 3d 20 70 54 61 73 6b 2d 3e 6c 69 73  Mem = pTask->lis
de00: 74 2e 61 4d 65 6d 6f 72 79 3b 0a 20 20 20 20 20  t.aMemory;.     
de10: 20 76 6f 69 64 20 2a 70 43 74 78 20 3d 20 28 76   void *pCtx = (v
de20: 6f 69 64 2a 29 70 54 61 73 6b 3b 0a 0a 20 20 20  oid*)pTask;..   
de30: 20 20 20 61 73 73 65 72 74 28 20 70 54 61 73 6b     assert( pTask
de40: 2d 3e 70 54 68 72 65 61 64 3d 3d 30 20 26 26 20  ->pThread==0 && 
de50: 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 3d 3d 30 20  pTask->bDone==0 
de60: 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  );.      assert(
de70: 20 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 70 4c 69   pTask->list.pLi
de80: 73 74 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 61  st==0 );.      a
de90: 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 6c 69  ssert( pTask->li
dea0: 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30 20 7c 7c  st.aMemory==0 ||
deb0: 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61   pSorter->list.a
dec0: 4d 65 6d 6f 72 79 21 3d 30 20 29 3b 0a 0a 20 20  Memory!=0 );..  
ded0: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 69 50 72      pSorter->iPr
dee0: 65 76 20 3d 20 28 70 54 61 73 6b 20 2d 20 70 53  ev = (pTask - pS
def0: 6f 72 74 65 72 2d 3e 61 54 61 73 6b 29 3b 0a 20  orter->aTask);. 
df00: 20 20 20 20 20 70 54 61 73 6b 2d 3e 6c 69 73 74       pTask->list
df10: 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74   = pSorter->list
df20: 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d  ;.      pSorter-
df30: 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d 20 30 3b  >list.pList = 0;
df40: 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  .      pSorter->
df50: 6c 69 73 74 2e 73 7a 50 4d 41 20 3d 20 30 3b 0a  list.szPMA = 0;.
df60: 20 20 20 20 20 20 69 66 28 20 61 4d 65 6d 20 29        if( aMem )
df70: 7b 0a 20 20 20 20 20 20 20 20 70 53 6f 72 74 65  {.        pSorte
df80: 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20  r->list.aMemory 
df90: 3d 20 61 4d 65 6d 3b 0a 20 20 20 20 20 20 20 20  = aMem;.        
dfa0: 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79  pSorter->nMemory
dfb0: 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63   = sqlite3Malloc
dfc0: 53 69 7a 65 28 61 4d 65 6d 29 3b 0a 20 20 20 20  Size(aMem);.    
dfd0: 20 20 7d 65 6c 73 65 20 69 66 28 20 70 53 6f 72    }else if( pSor
dfe0: 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72  ter->list.aMemor
dff0: 79 20 29 7b 0a 20 20 20 20 20 20 20 20 70 53 6f  y ){.        pSo
e000: 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f  rter->list.aMemo
e010: 72 79 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c  ry = sqlite3Mall
e020: 6f 63 28 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d  oc(pSorter->nMem
e030: 6f 72 79 29 3b 0a 20 20 20 20 20 20 20 20 69 66  ory);.        if
e040: 28 20 21 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74  ( !pSorter->list
e050: 2e 61 4d 65 6d 6f 72 79 20 29 20 72 65 74 75 72  .aMemory ) retur
e060: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
e070: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 72        }..      r
e080: 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 43 72  c = vdbeSorterCr
e090: 65 61 74 65 54 68 72 65 61 64 28 70 54 61 73 6b  eateThread(pTask
e0a0: 2c 20 76 64 62 65 53 6f 72 74 65 72 46 6c 75 73  , vdbeSorterFlus
e0b0: 68 54 68 72 65 61 64 2c 20 70 43 74 78 29 3b 0a  hThread, pCtx);.
e0c0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
e0d0: 75 72 6e 20 72 63 3b 0a 23 65 6e 64 69 66 20 2f  urn rc;.#endif /
e0e0: 2a 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52  * SQLITE_MAX_WOR
e0f0: 4b 45 52 5f 54 48 52 45 41 44 53 21 3d 30 20 2a  KER_THREADS!=0 *
e100: 2f 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61  /.}../*.** Add a
e110: 20 72 65 63 6f 72 64 20 74 6f 20 74 68 65 20 73   record to the s
e120: 6f 72 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71  orter..*/.int sq
e130: 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 57  lite3VdbeSorterW
e140: 72 69 74 65 28 0a 20 20 63 6f 6e 73 74 20 56 64  rite(.  const Vd
e150: 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  beCursor *pCsr, 
e160: 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65          /* Sorte
e170: 72 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 4d 65  r cursor */.  Me
e180: 6d 20 2a 70 56 61 6c 20 20 20 20 20 20 20 20 20  m *pVal         
e190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
e1a0: 20 4d 65 6d 6f 72 79 20 63 65 6c 6c 20 63 6f 6e   Memory cell con
e1b0: 74 61 69 6e 69 6e 67 20 72 65 63 6f 72 64 20 2a  taining record *
e1c0: 2f 0a 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65  /.){.  VdbeSorte
e1d0: 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73  r *pSorter = pCs
e1e0: 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e  r->pSorter;.  in
e1f0: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
e200: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
e210: 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a   Return Code */.
e220: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
e230: 70 4e 65 77 3b 20 20 20 20 20 20 20 20 20 20 20  pNew;           
e240: 20 20 2f 2a 20 4e 65 77 20 6c 69 73 74 20 65 6c    /* New list el
e250: 65 6d 65 6e 74 20 2a 2f 0a 0a 20 20 69 6e 74 20  ement */..  int 
e260: 62 46 6c 75 73 68 3b 20 20 20 20 20 20 20 20 20  bFlush;         
e270: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
e280: 72 75 65 20 74 6f 20 66 6c 75 73 68 20 63 6f 6e  rue to flush con
e290: 74 65 6e 74 73 20 6f 66 20 6d 65 6d 6f 72 79 20  tents of memory 
e2a0: 74 6f 20 50 4d 41 20 2a 2f 0a 20 20 69 6e 74 20  to PMA */.  int 
e2b0: 6e 52 65 71 3b 20 20 20 20 20 20 20 20 20 20 20  nReq;           
e2c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
e2d0: 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72  ytes of memory r
e2e0: 65 71 75 69 72 65 64 20 2a 2f 0a 20 20 69 6e 74  equired */.  int
e2f0: 20 6e 50 4d 41 3b 20 20 20 20 20 20 20 20 20 20   nPMA;          
e300: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
e310: 42 79 74 65 73 20 6f 66 20 50 4d 41 20 73 70 61  Bytes of PMA spa
e320: 63 65 20 72 65 71 75 69 72 65 64 20 2a 2f 0a 0a  ce required */..
e330: 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65    assert( pSorte
e340: 72 20 29 3b 0a 0a 20 20 2f 2a 20 46 69 67 75 72  r );..  /* Figur
e350: 65 20 6f 75 74 20 77 68 65 74 68 65 72 20 6f 72  e out whether or
e360: 20 6e 6f 74 20 74 68 65 20 63 75 72 72 65 6e 74   not the current
e370: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65 6d   contents of mem
e380: 6f 72 79 20 73 68 6f 75 6c 64 20 62 65 0a 20 20  ory should be.  
e390: 2a 2a 20 66 6c 75 73 68 65 64 20 74 6f 20 61 20  ** flushed to a 
e3a0: 50 4d 41 20 62 65 66 6f 72 65 20 63 6f 6e 74 69  PMA before conti
e3b0: 6e 75 69 6e 67 2e 20 49 66 20 73 6f 2c 20 64 6f  nuing. If so, do
e3c0: 20 73 6f 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49   so..  **.  ** I
e3d0: 66 20 75 73 69 6e 67 20 74 68 65 20 73 69 6e 67  f using the sing
e3e0: 6c 65 20 6c 61 72 67 65 20 61 6c 6c 6f 63 61 74  le large allocat
e3f0: 69 6f 6e 20 6d 6f 64 65 20 28 70 53 6f 72 74 65  ion mode (pSorte
e400: 72 2d 3e 61 4d 65 6d 6f 72 79 21 3d 30 29 2c 20  r->aMemory!=0), 
e410: 74 68 65 6e 0a 20 20 2a 2a 20 66 6c 75 73 68 20  then.  ** flush 
e420: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
e430: 6d 65 6d 6f 72 79 20 74 6f 20 61 20 6e 65 77 20  memory to a new 
e440: 50 4d 41 20 69 66 20 28 61 29 20 61 74 20 6c 65  PMA if (a) at le
e450: 61 73 74 20 6f 6e 65 20 76 61 6c 75 65 20 69 73  ast one value is
e460: 0a 20 20 2a 2a 20 61 6c 72 65 61 64 79 20 69 6e  .  ** already in
e470: 20 6d 65 6d 6f 72 79 20 61 6e 64 20 28 62 29 20   memory and (b) 
e480: 74 68 65 20 6e 65 77 20 76 61 6c 75 65 20 77 69  the new value wi
e490: 6c 6c 20 6e 6f 74 20 66 69 74 20 69 6e 20 6d 65  ll not fit in me
e4a0: 6d 6f 72 79 2e 0a 20 20 2a 2a 20 0a 20 20 2a 2a  mory..  ** .  **
e4b0: 20 4f 72 2c 20 69 66 20 75 73 69 6e 67 20 73 65   Or, if using se
e4c0: 70 61 72 61 74 65 20 61 6c 6c 6f 63 61 74 69 6f  parate allocatio
e4d0: 6e 73 20 66 6f 72 20 65 61 63 68 20 72 65 63 6f  ns for each reco
e4e0: 72 64 2c 20 66 6c 75 73 68 20 74 68 65 20 63 6f  rd, flush the co
e4f0: 6e 74 65 6e 74 73 0a 20 20 2a 2a 20 6f 66 20 6d  ntents.  ** of m
e500: 65 6d 6f 72 79 20 74 6f 20 61 20 50 4d 41 20 69  emory to a PMA i
e510: 66 20 65 69 74 68 65 72 20 6f 66 20 74 68 65 20  f either of the 
e520: 66 6f 6c 6c 6f 77 69 6e 67 20 61 72 65 20 74 72  following are tr
e530: 75 65 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20  ue:.  **.  **   
e540: 2a 20 54 68 65 20 74 6f 74 61 6c 20 6d 65 6d 6f  * The total memo
e550: 72 79 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72  ry allocated for
e560: 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c   the in-memory l
e570: 69 73 74 20 69 73 20 67 72 65 61 74 65 72 20 0a  ist is greater .
e580: 20 20 2a 2a 20 20 20 20 20 74 68 61 6e 20 28 70    **     than (p
e590: 61 67 65 2d 73 69 7a 65 20 2a 20 63 61 63 68 65  age-size * cache
e5a0: 2d 73 69 7a 65 29 2c 20 6f 72 0a 20 20 2a 2a 0a  -size), or.  **.
e5b0: 20 20 2a 2a 20 20 20 2a 20 54 68 65 20 74 6f 74    **   * The tot
e5c0: 61 6c 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61  al memory alloca
e5d0: 74 65 64 20 66 6f 72 20 74 68 65 20 69 6e 2d 6d  ted for the in-m
e5e0: 65 6d 6f 72 79 20 6c 69 73 74 20 69 73 20 67 72  emory list is gr
e5f0: 65 61 74 65 72 20 0a 20 20 2a 2a 20 20 20 20 20  eater .  **     
e600: 74 68 61 6e 20 28 70 61 67 65 2d 73 69 7a 65 20  than (page-size 
e610: 2a 20 31 30 29 20 61 6e 64 20 73 71 6c 69 74 65  * 10) and sqlite
e620: 33 48 65 61 70 4e 65 61 72 6c 79 46 75 6c 6c 28  3HeapNearlyFull(
e630: 29 20 72 65 74 75 72 6e 73 20 74 72 75 65 2e 0a  ) returns true..
e640: 20 20 2a 2f 0a 20 20 6e 52 65 71 20 3d 20 70 56    */.  nReq = pV
e650: 61 6c 2d 3e 6e 20 2b 20 73 69 7a 65 6f 66 28 53  al->n + sizeof(S
e660: 6f 72 74 65 72 52 65 63 6f 72 64 29 3b 0a 20 20  orterRecord);.  
e670: 6e 50 4d 41 20 3d 20 70 56 61 6c 2d 3e 6e 20 2b  nPMA = pVal->n +
e680: 20 73 71 6c 69 74 65 33 56 61 72 69 6e 74 4c 65   sqlite3VarintLe
e690: 6e 28 70 56 61 6c 2d 3e 6e 29 3b 0a 20 20 69 66  n(pVal->n);.  if
e6a0: 28 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61  ( pSorter->mxPma
e6b0: 53 69 7a 65 20 29 7b 0a 20 20 20 20 69 66 28 20  Size ){.    if( 
e6c0: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d  pSorter->list.aM
e6d0: 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20 20 62  emory ){.      b
e6e0: 46 6c 75 73 68 20 3d 20 70 53 6f 72 74 65 72 2d  Flush = pSorter-
e6f0: 3e 69 4d 65 6d 6f 72 79 20 26 26 20 28 70 53 6f  >iMemory && (pSo
e700: 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 2b 6e 52  rter->iMemory+nR
e710: 65 71 29 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d  eq) > pSorter->m
e720: 78 50 6d 61 53 69 7a 65 3b 0a 20 20 20 20 7d 65  xPmaSize;.    }e
e730: 6c 73 65 7b 0a 20 20 20 20 20 20 62 46 6c 75 73  lse{.      bFlus
e740: 68 20 3d 20 28 0a 20 20 20 20 20 20 20 20 20 20  h = (.          
e750: 28 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 73  (pSorter->list.s
e760: 7a 50 4d 41 20 3e 20 70 53 6f 72 74 65 72 2d 3e  zPMA > pSorter->
e770: 6d 78 50 6d 61 53 69 7a 65 29 0a 20 20 20 20 20  mxPmaSize).     
e780: 20 20 7c 7c 20 28 70 53 6f 72 74 65 72 2d 3e 6c    || (pSorter->l
e790: 69 73 74 2e 73 7a 50 4d 41 20 3e 20 70 53 6f 72  ist.szPMA > pSor
e7a0: 74 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a 65 20 26  ter->mnPmaSize &
e7b0: 26 20 73 71 6c 69 74 65 33 48 65 61 70 4e 65 61  & sqlite3HeapNea
e7c0: 72 6c 79 46 75 6c 6c 28 29 29 0a 20 20 20 20 20  rlyFull()).     
e7d0: 20 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66   );.    }.    if
e7e0: 28 20 62 46 6c 75 73 68 20 29 7b 0a 20 20 20 20  ( bFlush ){.    
e7f0: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
e800: 72 46 6c 75 73 68 50 4d 41 28 70 53 6f 72 74 65  rFlushPMA(pSorte
e810: 72 29 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65  r);.      pSorte
e820: 72 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 3d 20  r->list.szPMA = 
e830: 30 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72  0;.      pSorter
e840: 2d 3e 69 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a 20  ->iMemory = 0;. 
e850: 20 20 20 20 20 61 73 73 65 72 74 28 20 72 63 21       assert( rc!
e860: 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53  =SQLITE_OK || pS
e870: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73  orter->list.pLis
e880: 74 3d 3d 30 20 29 3b 0a 20 20 20 20 7d 0a 20 20  t==0 );.    }.  
e890: 7d 0a 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69  }..  pSorter->li
e8a0: 73 74 2e 73 7a 50 4d 41 20 2b 3d 20 6e 50 4d 41  st.szPMA += nPMA
e8b0: 3b 0a 20 20 69 66 28 20 6e 50 4d 41 3e 70 53 6f  ;.  if( nPMA>pSo
e8c0: 72 74 65 72 2d 3e 6d 78 4b 65 79 73 69 7a 65 20  rter->mxKeysize 
e8d0: 29 7b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  ){.    pSorter->
e8e0: 6d 78 4b 65 79 73 69 7a 65 20 3d 20 6e 50 4d 41  mxKeysize = nPMA
e8f0: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 53 6f  ;.  }..  if( pSo
e900: 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f  rter->list.aMemo
e910: 72 79 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 4d  ry ){.    int nM
e920: 69 6e 20 3d 20 70 53 6f 72 74 65 72 2d 3e 69 4d  in = pSorter->iM
e930: 65 6d 6f 72 79 20 2b 20 6e 52 65 71 3b 0a 0a 20  emory + nReq;.. 
e940: 20 20 20 69 66 28 20 6e 4d 69 6e 3e 70 53 6f 72     if( nMin>pSor
e950: 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 29 7b 0a  ter->nMemory ){.
e960: 20 20 20 20 20 20 75 38 20 2a 61 4e 65 77 3b 0a        u8 *aNew;.
e970: 20 20 20 20 20 20 69 6e 74 20 6e 4e 65 77 20 3d        int nNew =
e980: 20 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72   pSorter->nMemor
e990: 79 20 2a 20 32 3b 0a 20 20 20 20 20 20 77 68 69  y * 2;.      whi
e9a0: 6c 65 28 20 6e 4e 65 77 20 3c 20 6e 4d 69 6e 20  le( nNew < nMin 
e9b0: 29 20 6e 4e 65 77 20 3d 20 6e 4e 65 77 2a 32 3b  ) nNew = nNew*2;
e9c0: 0a 20 20 20 20 20 20 69 66 28 20 6e 4e 65 77 20  .      if( nNew 
e9d0: 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61  > pSorter->mxPma
e9e0: 53 69 7a 65 20 29 20 6e 4e 65 77 20 3d 20 70 53  Size ) nNew = pS
e9f0: 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65  orter->mxPmaSize
ea00: 3b 0a 20 20 20 20 20 20 69 66 28 20 6e 4e 65 77  ;.      if( nNew
ea10: 20 3c 20 6e 4d 69 6e 20 29 20 6e 4e 65 77 20 3d   < nMin ) nNew =
ea20: 20 6e 4d 69 6e 3b 0a 0a 20 20 20 20 20 20 61 4e   nMin;..      aN
ea30: 65 77 20 3d 20 73 71 6c 69 74 65 33 52 65 61 6c  ew = sqlite3Real
ea40: 6c 6f 63 28 70 53 6f 72 74 65 72 2d 3e 6c 69 73  loc(pSorter->lis
ea50: 74 2e 61 4d 65 6d 6f 72 79 2c 20 6e 4e 65 77 29  t.aMemory, nNew)
ea60: 3b 0a 20 20 20 20 20 20 69 66 28 20 21 61 4e 65  ;.      if( !aNe
ea70: 77 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  w ) return SQLIT
ea80: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 70  E_NOMEM;.      p
ea90: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69  Sorter->list.pLi
eaa0: 73 74 20 3d 20 28 53 6f 72 74 65 72 52 65 63 6f  st = (SorterReco
eab0: 72 64 2a 29 28 0a 20 20 20 20 20 20 20 20 20 20  rd*)(.          
eac0: 61 4e 65 77 20 2b 20 28 28 75 38 2a 29 70 53 6f  aNew + ((u8*)pSo
ead0: 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74  rter->list.pList
eae0: 20 2d 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74   - pSorter->list
eaf0: 2e 61 4d 65 6d 6f 72 79 29 0a 20 20 20 20 20 20  .aMemory).      
eb00: 29 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72  );.      pSorter
eb10: 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 3d  ->list.aMemory =
eb20: 20 61 4e 65 77 3b 0a 20 20 20 20 20 20 70 53 6f   aNew;.      pSo
eb30: 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 3d 20  rter->nMemory = 
eb40: 6e 4e 65 77 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  nNew;.    }..   
eb50: 20 70 4e 65 77 20 3d 20 28 53 6f 72 74 65 72 52   pNew = (SorterR
eb60: 65 63 6f 72 64 2a 29 26 70 53 6f 72 74 65 72 2d  ecord*)&pSorter-
eb70: 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 5b 70 53  >list.aMemory[pS
eb80: 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 5d 3b  orter->iMemory];
eb90: 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 69 4d  .    pSorter->iM
eba0: 65 6d 6f 72 79 20 2b 3d 20 52 4f 55 4e 44 38 28  emory += ROUND8(
ebb0: 6e 52 65 71 29 3b 0a 20 20 20 20 70 4e 65 77 2d  nReq);.    pNew-
ebc0: 3e 75 2e 69 4e 65 78 74 20 3d 20 28 69 6e 74 29  >u.iNext = (int)
ebd0: 28 28 75 38 2a 29 28 70 53 6f 72 74 65 72 2d 3e  ((u8*)(pSorter->
ebe0: 6c 69 73 74 2e 70 4c 69 73 74 29 20 2d 20 70 53  list.pList) - pS
ebf0: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d  orter->list.aMem
ec00: 6f 72 79 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  ory);.  }else{. 
ec10: 20 20 20 70 4e 65 77 20 3d 20 28 53 6f 72 74 65     pNew = (Sorte
ec20: 72 52 65 63 6f 72 64 20 2a 29 73 71 6c 69 74 65  rRecord *)sqlite
ec30: 33 4d 61 6c 6c 6f 63 28 6e 52 65 71 29 3b 0a 20  3Malloc(nReq);. 
ec40: 20 20 20 69 66 28 20 70 4e 65 77 3d 3d 30 20 29     if( pNew==0 )
ec50: 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53  {.      return S
ec60: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
ec70: 20 7d 0a 20 20 20 20 70 4e 65 77 2d 3e 75 2e 70   }.    pNew->u.p
ec80: 4e 65 78 74 20 3d 20 70 53 6f 72 74 65 72 2d 3e  Next = pSorter->
ec90: 6c 69 73 74 2e 70 4c 69 73 74 3b 0a 20 20 7d 0a  list.pList;.  }.
eca0: 0a 20 20 6d 65 6d 63 70 79 28 53 52 56 41 4c 28  .  memcpy(SRVAL(
ecb0: 70 4e 65 77 29 2c 20 70 56 61 6c 2d 3e 7a 2c 20  pNew), pVal->z, 
ecc0: 70 56 61 6c 2d 3e 6e 29 3b 0a 20 20 70 4e 65 77  pVal->n);.  pNew
ecd0: 2d 3e 6e 56 61 6c 20 3d 20 70 56 61 6c 2d 3e 6e  ->nVal = pVal->n
ece0: 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73  ;.  pSorter->lis
ecf0: 74 2e 70 4c 69 73 74 20 3d 20 70 4e 65 77 3b 0a  t.pList = pNew;.
ed00: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
ed10: 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 6b 65 79 73  ./*.** Read keys
ed20: 20 66 72 6f 6d 20 70 49 6e 63 72 2d 3e 70 4d 65   from pIncr->pMe
ed30: 72 67 65 72 20 61 6e 64 20 70 6f 70 75 6c 61 74  rger and populat
ed40: 65 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31  e pIncr->aFile[1
ed50: 5d 2e 20 54 68 65 20 66 6f 72 6d 61 74 0a 2a 2a  ]. The format.**
ed60: 20 6f 66 20 74 68 65 20 64 61 74 61 20 73 74 6f   of the data sto
ed70: 72 65 64 20 69 6e 20 61 46 69 6c 65 5b 31 5d 20  red in aFile[1] 
ed80: 69 73 20 74 68 65 20 73 61 6d 65 20 61 73 20 74  is the same as t
ed90: 68 61 74 20 75 73 65 64 20 62 79 20 72 65 67 75  hat used by regu
eda0: 6c 61 72 20 50 4d 41 73 2c 0a 2a 2a 20 65 78 63  lar PMAs,.** exc
edb0: 65 70 74 20 74 68 61 74 20 74 68 65 20 6e 75 6d  ept that the num
edc0: 62 65 72 2d 6f 66 2d 62 79 74 65 73 20 76 61 72  ber-of-bytes var
edd0: 69 6e 74 20 69 73 20 6f 6d 69 74 74 65 64 20 66  int is omitted f
ede0: 72 6f 6d 20 74 68 65 20 73 74 61 72 74 2e 0a 2a  rom the start..*
edf0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
ee00: 65 49 6e 63 72 50 6f 70 75 6c 61 74 65 28 49 6e  eIncrPopulate(In
ee10: 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 29  crMerger *pIncr)
ee20: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
ee30: 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 72 63  ITE_OK;.  int rc
ee40: 32 3b 0a 20 20 69 36 34 20 69 53 74 61 72 74 20  2;.  i64 iStart 
ee50: 3d 20 70 49 6e 63 72 2d 3e 69 53 74 61 72 74 4f  = pIncr->iStartO
ee60: 66 66 3b 0a 20 20 53 6f 72 74 65 72 46 69 6c 65  ff;.  SorterFile
ee70: 20 2a 70 4f 75 74 20 3d 20 26 70 49 6e 63 72 2d   *pOut = &pIncr-
ee80: 3e 61 46 69 6c 65 5b 31 5d 3b 0a 20 20 53 6f 72  >aFile[1];.  Sor
ee90: 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 20  tSubtask *pTask 
eea0: 3d 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b 3b 0a  = pIncr->pTask;.
eeb0: 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70    MergeEngine *p
eec0: 4d 65 72 67 65 72 20 3d 20 70 49 6e 63 72 2d 3e  Merger = pIncr->
eed0: 70 4d 65 72 67 65 72 3b 0a 20 20 50 6d 61 57 72  pMerger;.  PmaWr
eee0: 69 74 65 72 20 77 72 69 74 65 72 3b 0a 20 20 61  iter writer;.  a
eef0: 73 73 65 72 74 28 20 70 49 6e 63 72 2d 3e 62 45  ssert( pIncr->bE
ef00: 6f 66 3d 3d 30 20 29 3b 0a 0a 20 20 76 64 62 65  of==0 );..  vdbe
ef10: 53 6f 72 74 65 72 50 6f 70 75 6c 61 74 65 44 65  SorterPopulateDe
ef20: 62 75 67 28 70 54 61 73 6b 2c 20 22 65 6e 74 65  bug(pTask, "ente
ef30: 72 22 29 3b 0a 0a 20 20 76 64 62 65 50 6d 61 57  r");..  vdbePmaW
ef40: 72 69 74 65 72 49 6e 69 74 28 70 4f 75 74 2d 3e  riterInit(pOut->
ef50: 70 46 64 2c 20 26 77 72 69 74 65 72 2c 20 70 54  pFd, &writer, pT
ef60: 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 67  ask->pSorter->pg
ef70: 73 7a 2c 20 69 53 74 61 72 74 29 3b 0a 20 20 77  sz, iStart);.  w
ef80: 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45  hile( rc==SQLITE
ef90: 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 64  _OK ){.    int d
efa0: 75 6d 6d 79 3b 0a 20 20 20 20 50 6d 61 52 65 61  ummy;.    PmaRea
efb0: 64 65 72 20 2a 70 52 65 61 64 65 72 20 3d 20 26  der *pReader = &
efc0: 70 4d 65 72 67 65 72 2d 3e 61 52 65 61 64 72 5b  pMerger->aReadr[
efd0: 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b   pMerger->aTree[
efe0: 31 5d 20 5d 3b 0a 20 20 20 20 69 6e 74 20 6e 4b  1] ];.    int nK
eff0: 65 79 20 3d 20 70 52 65 61 64 65 72 2d 3e 6e 4b  ey = pReader->nK
f000: 65 79 3b 0a 20 20 20 20 69 36 34 20 69 45 6f 66  ey;.    i64 iEof
f010: 20 3d 20 77 72 69 74 65 72 2e 69 57 72 69 74 65   = writer.iWrite
f020: 4f 66 66 20 2b 20 77 72 69 74 65 72 2e 69 42 75  Off + writer.iBu
f030: 66 45 6e 64 3b 0a 0a 20 20 20 20 2f 2a 20 43 68  fEnd;..    /* Ch
f040: 65 63 6b 20 69 66 20 74 68 65 20 6f 75 74 70 75  eck if the outpu
f050: 74 20 66 69 6c 65 20 69 73 20 66 75 6c 6c 20 6f  t file is full o
f060: 72 20 69 66 20 74 68 65 20 69 6e 70 75 74 20 68  r if the input h
f070: 61 73 20 62 65 65 6e 20 65 78 68 61 75 73 74 65  as been exhauste
f080: 64 2e 0a 20 20 20 20 2a 2a 20 49 6e 20 65 69 74  d..    ** In eit
f090: 68 65 72 20 63 61 73 65 20 65 78 69 74 20 74 68  her case exit th
f0a0: 65 20 6c 6f 6f 70 2e 20 2a 2f 0a 20 20 20 20 69  e loop. */.    i
f0b0: 66 28 20 70 52 65 61 64 65 72 2d 3e 70 46 64 3d  f( pReader->pFd=
f0c0: 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  =0 ) break;.    
f0d0: 69 66 28 20 28 69 45 6f 66 20 2b 20 6e 4b 65 79  if( (iEof + nKey
f0e0: 20 2b 20 73 71 6c 69 74 65 33 56 61 72 69 6e 74   + sqlite3Varint
f0f0: 4c 65 6e 28 6e 4b 65 79 29 29 3e 28 69 53 74 61  Len(nKey))>(iSta
f100: 72 74 20 2b 20 70 49 6e 63 72 2d 3e 6d 78 53 7a  rt + pIncr->mxSz
f110: 29 20 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20  ) ) break;..    
f120: 2f 2a 20 57 72 69 74 65 20 74 68 65 20 6e 65 78  /* Write the nex
f130: 74 20 6b 65 79 20 74 6f 20 74 68 65 20 6f 75 74  t key to the out
f140: 70 75 74 2e 20 2a 2f 0a 20 20 20 20 76 64 62 65  put. */.    vdbe
f150: 50 6d 61 57 72 69 74 65 56 61 72 69 6e 74 28 26  PmaWriteVarint(&
f160: 77 72 69 74 65 72 2c 20 6e 4b 65 79 29 3b 0a 20  writer, nKey);. 
f170: 20 20 20 76 64 62 65 50 6d 61 57 72 69 74 65 42     vdbePmaWriteB
f180: 6c 6f 62 28 26 77 72 69 74 65 72 2c 20 70 52 65  lob(&writer, pRe
f190: 61 64 65 72 2d 3e 61 4b 65 79 2c 20 6e 4b 65 79  ader->aKey, nKey
f1a0: 29 3b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65  );.    rc = vdbe
f1b0: 4d 65 72 67 65 45 6e 67 69 6e 65 53 74 65 70 28  MergeEngineStep(
f1c0: 70 54 61 73 6b 2c 20 70 49 6e 63 72 2d 3e 70 4d  pTask, pIncr->pM
f1d0: 65 72 67 65 72 2c 20 26 64 75 6d 6d 79 29 3b 0a  erger, &dummy);.
f1e0: 20 20 7d 0a 0a 20 20 72 63 32 20 3d 20 76 64 62    }..  rc2 = vdb
f1f0: 65 50 6d 61 57 72 69 74 65 72 46 69 6e 69 73 68  ePmaWriterFinish
f200: 28 26 77 72 69 74 65 72 2c 20 26 70 4f 75 74 2d  (&writer, &pOut-
f210: 3e 69 45 6f 66 29 3b 0a 20 20 69 66 28 20 72 63  >iEof);.  if( rc
f220: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63  ==SQLITE_OK ) rc
f230: 20 3d 20 72 63 32 3b 0a 20 20 76 64 62 65 53 6f   = rc2;.  vdbeSo
f240: 72 74 65 72 50 6f 70 75 6c 61 74 65 44 65 62 75  rterPopulateDebu
f250: 67 28 70 54 61 73 6b 2c 20 22 65 78 69 74 22 29  g(pTask, "exit")
f260: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
f270: 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58  ..#if SQLITE_MAX
f280: 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e  _WORKER_THREADS>
f290: 30 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d 61 69 6e  0./*.** The main
f2a0: 20 72 6f 75 74 69 6e 65 20 66 6f 72 20 62 61 63   routine for bac
f2b0: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 73 20  kground threads 
f2c0: 74 68 61 74 20 70 6f 70 75 6c 61 74 65 20 61 46  that populate aF
f2d0: 69 6c 65 5b 31 5d 20 6f 66 0a 2a 2a 20 6d 75 6c  ile[1] of.** mul
f2e0: 74 69 2d 74 68 72 65 61 64 65 64 20 49 6e 63 72  ti-threaded Incr
f2f0: 4d 65 72 67 65 72 20 6f 62 6a 65 63 74 73 2e 0a  Merger objects..
f300: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a  */.static void *
f310: 76 64 62 65 49 6e 63 72 50 6f 70 75 6c 61 74 65  vdbeIncrPopulate
f320: 54 68 72 65 61 64 28 76 6f 69 64 20 2a 70 43 74  Thread(void *pCt
f330: 78 29 7b 0a 20 20 49 6e 63 72 4d 65 72 67 65 72  x){.  IncrMerger
f340: 20 2a 70 49 6e 63 72 20 3d 20 28 49 6e 63 72 4d   *pIncr = (IncrM
f350: 65 72 67 65 72 2a 29 70 43 74 78 3b 0a 20 20 76  erger*)pCtx;.  v
f360: 6f 69 64 20 2a 70 52 65 74 20 3d 20 53 51 4c 49  oid *pRet = SQLI
f370: 54 45 5f 49 4e 54 5f 54 4f 5f 50 54 52 28 20 76  TE_INT_TO_PTR( v
f380: 64 62 65 49 6e 63 72 50 6f 70 75 6c 61 74 65 28  dbeIncrPopulate(
f390: 70 49 6e 63 72 29 20 29 3b 0a 20 20 70 49 6e 63  pIncr) );.  pInc
f3a0: 72 2d 3e 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 20  r->pTask->bDone 
f3b0: 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 70 52  = 1;.  return pR
f3c0: 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 61 75  et;.}../*.** Lau
f3d0: 6e 63 68 20 61 20 62 61 63 6b 67 72 6f 75 6e 64  nch a background
f3e0: 20 74 68 72 65 61 64 20 74 6f 20 70 6f 70 75 6c   thread to popul
f3f0: 61 74 65 20 61 46 69 6c 65 5b 31 5d 20 6f 66 20  ate aFile[1] of 
f400: 70 49 6e 63 72 2e 0a 2a 2f 0a 73 74 61 74 69 63  pIncr..*/.static
f410: 20 69 6e 74 20 76 64 62 65 49 6e 63 72 42 67 50   int vdbeIncrBgP
f420: 6f 70 75 6c 61 74 65 28 49 6e 63 72 4d 65 72 67  opulate(IncrMerg
f430: 65 72 20 2a 70 49 6e 63 72 29 7b 0a 20 20 76 6f  er *pIncr){.  vo
f440: 69 64 20 2a 70 20 3d 20 28 76 6f 69 64 2a 29 70  id *p = (void*)p
f450: 49 6e 63 72 3b 0a 20 20 61 73 73 65 72 74 28 20  Incr;.  assert( 
f460: 70 49 6e 63 72 2d 3e 62 55 73 65 54 68 72 65 61  pIncr->bUseThrea
f470: 64 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 76 64  d );.  return vd
f480: 62 65 53 6f 72 74 65 72 43 72 65 61 74 65 54 68  beSorterCreateTh
f490: 72 65 61 64 28 70 49 6e 63 72 2d 3e 70 54 61 73  read(pIncr->pTas
f4a0: 6b 2c 20 76 64 62 65 49 6e 63 72 50 6f 70 75 6c  k, vdbeIncrPopul
f4b0: 61 74 65 54 68 72 65 61 64 2c 20 70 29 3b 0a 7d  ateThread, p);.}
f4c0: 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 54  .#endif../*.** T
f4d0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
f4e0: 63 61 6c 6c 65 64 20 77 68 65 6e 20 74 68 65 20  called when the 
f4f0: 50 6d 61 52 65 61 64 65 72 20 63 6f 72 72 65 73  PmaReader corres
f500: 70 6f 6e 64 69 6e 67 20 74 6f 20 70 49 6e 63 72  ponding to pIncr
f510: 20 68 61 73 0a 2a 2a 20 66 69 6e 69 73 68 65 64   has.** finished
f520: 20 72 65 61 64 69 6e 67 20 74 68 65 20 63 6f 6e   reading the con
f530: 74 65 6e 74 73 20 6f 66 20 61 46 69 6c 65 5b 30  tents of aFile[0
f540: 5d 2e 20 49 74 73 20 70 75 72 70 6f 73 65 20 69  ]. Its purpose i
f550: 73 20 74 6f 20 22 72 65 66 69 6c 6c 22 0a 2a 2a  s to "refill".**
f560: 20 61 46 69 6c 65 5b 30 5d 20 73 75 63 68 20 74   aFile[0] such t
f570: 68 61 74 20 74 68 65 20 50 6d 61 52 65 61 64 65  hat the PmaReade
f580: 72 20 73 68 6f 75 6c 64 20 73 74 61 72 74 20 72  r should start r
f590: 65 72 65 61 64 69 6e 67 20 69 74 20 66 72 6f 6d  ereading it from
f5a0: 20 74 68 65 0a 2a 2a 20 62 65 67 69 6e 6e 69 6e   the.** beginnin
f5b0: 67 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 73 69 6e  g..**.** For sin
f5c0: 67 6c 65 2d 74 68 72 65 61 64 65 64 20 6f 62 6a  gle-threaded obj
f5d0: 65 63 74 73 2c 20 74 68 69 73 20 69 73 20 61 63  ects, this is ac
f5e0: 63 6f 6d 70 6c 69 73 68 65 64 20 62 79 20 6c 69  complished by li
f5f0: 74 65 72 61 6c 6c 79 20 72 65 61 64 69 6e 67 20  terally reading 
f600: 0a 2a 2a 20 6b 65 79 73 20 66 72 6f 6d 20 70 49  .** keys from pI
f610: 6e 63 72 2d 3e 70 4d 65 72 67 65 72 20 61 6e 64  ncr->pMerger and
f620: 20 72 65 70 6f 70 75 6c 61 74 69 6e 67 20 61 46   repopulating aF
f630: 69 6c 65 5b 30 5d 2e 20 0a 2a 2a 0a 2a 2a 20 46  ile[0]. .**.** F
f640: 6f 72 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65  or multi-threade
f650: 64 20 6f 62 6a 65 63 74 73 2c 20 61 6c 6c 20 74  d objects, all t
f660: 68 61 74 20 69 73 20 72 65 71 75 69 72 65 64 20  hat is required 
f670: 69 73 20 74 6f 20 77 61 69 74 20 75 6e 74 69 6c  is to wait until
f680: 20 74 68 65 20 0a 2a 2a 20 62 61 63 6b 67 72 6f   the .** backgro
f690: 75 6e 64 20 74 68 72 65 61 64 20 69 73 20 66 69  und thread is fi
f6a0: 6e 69 73 68 65 64 20 28 69 66 20 69 74 20 69 73  nished (if it is
f6b0: 20 6e 6f 74 20 61 6c 72 65 61 64 79 29 20 61 6e   not already) an
f6c0: 64 20 74 68 65 6e 20 73 77 61 70 20 0a 2a 2a 20  d then swap .** 
f6d0: 61 46 69 6c 65 5b 30 5d 20 61 6e 64 20 61 46 69  aFile[0] and aFi
f6e0: 6c 65 5b 31 5d 20 69 6e 20 70 6c 61 63 65 2e 20  le[1] in place. 
f6f0: 49 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  If the contents 
f700: 6f 66 20 70 4d 65 72 67 65 72 20 68 61 76 65 20  of pMerger have 
f710: 6e 6f 74 0a 2a 2a 20 62 65 65 6e 20 65 78 68 61  not.** been exha
f720: 75 73 74 65 64 2c 20 74 68 69 73 20 66 75 6e 63  usted, this func
f730: 74 69 6f 6e 20 61 6c 73 6f 20 6c 61 75 6e 63 68  tion also launch
f740: 65 73 20 61 20 6e 65 77 20 62 61 63 6b 67 72 6f  es a new backgro
f750: 75 6e 64 20 74 68 72 65 61 64 0a 2a 2a 20 74 6f  und thread.** to
f760: 20 70 6f 70 75 6c 61 74 65 20 74 68 65 20 6e 65   populate the ne
f770: 77 20 61 46 69 6c 65 5b 31 5d 2e 0a 2a 2a 0a 2a  w aFile[1]..**.*
f780: 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72  * SQLITE_OK is r
f790: 65 74 75 72 6e 65 64 20 6f 6e 20 73 75 63 63 65  eturned on succe
f7a0: 73 73 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65  ss, or an SQLite
f7b0: 20 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65   error code othe
f7c0: 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  rwise..*/.static
f7d0: 20 69 6e 74 20 76 64 62 65 49 6e 63 72 53 77 61   int vdbeIncrSwa
f7e0: 70 28 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49  p(IncrMerger *pI
f7f0: 6e 63 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  ncr){.  int rc =
f800: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 23 69 66   SQLITE_OK;..#if
f810: 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b   SQLITE_MAX_WORK
f820: 45 52 5f 54 48 52 45 41 44 53 3e 30 0a 20 20 69  ER_THREADS>0.  i
f830: 66 28 20 70 49 6e 63 72 2d 3e 62 55 73 65 54 68  f( pIncr->bUseTh
f840: 72 65 61 64 20 29 7b 0a 20 20 20 20 72 63 20 3d  read ){.    rc =
f850: 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e 54   vdbeSorterJoinT
f860: 68 72 65 61 64 28 70 49 6e 63 72 2d 3e 70 54 61  hread(pIncr->pTa
f870: 73 6b 29 3b 0a 0a 20 20 20 20 69 66 28 20 72 63  sk);..    if( rc
f880: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
f890: 20 20 20 20 20 53 6f 72 74 65 72 46 69 6c 65 20       SorterFile 
f8a0: 66 30 20 3d 20 70 49 6e 63 72 2d 3e 61 46 69 6c  f0 = pIncr->aFil
f8b0: 65 5b 30 5d 3b 0a 20 20 20 20 20 20 70 49 6e 63  e[0];.      pInc
f8c0: 72 2d 3e 61 46 69 6c 65 5b 30 5d 20 3d 20 70 49  r->aFile[0] = pI
f8d0: 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 3b 0a 20  ncr->aFile[1];. 
f8e0: 20 20 20 20 20 70 49 6e 63 72 2d 3e 61 46 69 6c       pIncr->aFil
f8f0: 65 5b 31 5d 20 3d 20 66 30 3b 0a 20 20 20 20 7d  e[1] = f0;.    }
f900: 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ..    if( rc==SQ
f910: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
f920: 20 69 66 28 20 70 49 6e 63 72 2d 3e 61 46 69 6c   if( pIncr->aFil
f930: 65 5b 30 5d 2e 69 45 6f 66 3d 3d 70 49 6e 63 72  e[0].iEof==pIncr
f940: 2d 3e 69 53 74 61 72 74 4f 66 66 20 29 7b 0a 20  ->iStartOff ){. 
f950: 20 20 20 20 20 20 20 70 49 6e 63 72 2d 3e 62 45         pIncr->bE
f960: 6f 66 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 65  of = 1;.      }e
f970: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 72 63 20  lse{.        rc 
f980: 3d 20 76 64 62 65 49 6e 63 72 42 67 50 6f 70 75  = vdbeIncrBgPopu
f990: 6c 61 74 65 28 70 49 6e 63 72 29 3b 0a 20 20 20  late(pIncr);.   
f9a0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 65 6c     }.    }.  }el
f9b0: 73 65 0a 23 65 6e 64 69 66 0a 20 20 7b 0a 20 20  se.#endif.  {.  
f9c0: 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72 50    rc = vdbeIncrP
f9d0: 6f 70 75 6c 61 74 65 28 70 49 6e 63 72 29 3b 0a  opulate(pIncr);.
f9e0: 20 20 20 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65      pIncr->aFile
f9f0: 5b 30 5d 20 3d 20 70 49 6e 63 72 2d 3e 61 46 69  [0] = pIncr->aFi
fa00: 6c 65 5b 31 5d 3b 0a 20 20 20 20 69 66 28 20 70  le[1];.    if( p
fa10: 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e 69  Incr->aFile[0].i
fa20: 45 6f 66 3d 3d 70 49 6e 63 72 2d 3e 69 53 74 61  Eof==pIncr->iSta
fa30: 72 74 4f 66 66 20 29 7b 0a 20 20 20 20 20 20 70  rtOff ){.      p
fa40: 49 6e 63 72 2d 3e 62 45 6f 66 20 3d 20 31 3b 0a  Incr->bEof = 1;.
fa50: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
fa60: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
fa70: 20 41 6c 6c 6f 63 61 74 65 20 61 6e 64 20 72 65   Allocate and re
fa80: 74 75 72 6e 20 61 20 6e 65 77 20 49 6e 63 72 4d  turn a new IncrM
fa90: 65 72 67 65 72 20 6f 62 6a 65 63 74 20 74 6f 20  erger object to 
faa0: 72 65 61 64 20 64 61 74 61 20 66 72 6f 6d 20 70  read data from p
fab0: 4d 65 72 67 65 72 2e 0a 2a 2a 0a 2a 2a 20 49 66  Merger..**.** If
fac0: 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74 69 6f   an OOM conditio
fad0: 6e 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65 64  n is encountered
fae0: 2c 20 72 65 74 75 72 6e 20 4e 55 4c 4c 2e 20 49  , return NULL. I
faf0: 6e 20 74 68 69 73 20 63 61 73 65 20 66 72 65 65  n this case free
fb00: 20 74 68 65 0a 2a 2a 20 70 4d 65 72 67 65 72 20   the.** pMerger 
fb10: 61 72 67 75 6d 65 6e 74 20 62 65 66 6f 72 65 20  argument before 
fb20: 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74  returning..*/.st
fb30: 61 74 69 63 20 69 6e 74 20 76 64 62 65 49 6e 63  atic int vdbeInc
fb40: 72 4e 65 77 28 0a 20 20 53 6f 72 74 53 75 62 74  rNew(.  SortSubt
fb50: 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20 20 20  ask *pTask,     
fb60: 2f 2a 20 54 68 65 20 74 68 72 65 61 64 20 74 68  /* The thread th
fb70: 61 74 20 77 69 6c 6c 20 62 65 20 75 73 69 6e 67  at will be using
fb80: 20 74 68 65 20 6e 65 77 20 49 6e 63 72 4d 65 72   the new IncrMer
fb90: 67 65 72 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e  ger */.  MergeEn
fba0: 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 2c 20 20  gine *pMerger,  
fbb0: 20 2f 2a 20 54 68 65 20 4d 65 72 67 65 45 6e 67   /* The MergeEng
fbc0: 69 6e 65 20 74 68 61 74 20 74 68 65 20 49 6e 63  ine that the Inc
fbd0: 72 4d 65 72 67 65 72 20 77 69 6c 6c 20 63 6f 6e  rMerger will con
fbe0: 74 72 6f 6c 20 2a 2f 0a 20 20 49 6e 63 72 4d 65  trol */.  IncrMe
fbf0: 72 67 65 72 20 2a 2a 70 70 4f 75 74 20 20 20 20  rger **ppOut    
fc00: 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 6e    /* Write the n
fc10: 65 77 20 49 6e 63 72 4d 65 72 67 65 72 20 68 65  ew IncrMerger he
fc20: 72 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  re */.){.  int r
fc30: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
fc40: 20 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e   IncrMerger *pIn
fc50: 63 72 20 3d 20 2a 70 70 4f 75 74 20 3d 20 28 49  cr = *ppOut = (I
fc60: 6e 63 72 4d 65 72 67 65 72 2a 29 0a 20 20 20 20  ncrMerger*).    
fc70: 20 20 20 28 73 71 6c 69 74 65 33 46 61 75 6c 74     (sqlite3Fault
fc80: 53 69 6d 28 31 30 30 29 20 3f 20 30 20 3a 20 73  Sim(100) ? 0 : s
fc90: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f  qlite3MallocZero
fca0: 28 73 69 7a 65 6f 66 28 2a 70 49 6e 63 72 29 29  (sizeof(*pIncr))
fcb0: 29 3b 0a 20 20 69 66 28 20 70 49 6e 63 72 20 29  );.  if( pIncr )
fcc0: 7b 0a 20 20 20 20 70 49 6e 63 72 2d 3e 70 4d 65  {.    pIncr->pMe
fcd0: 72 67 65 72 20 3d 20 70 4d 65 72 67 65 72 3b 0a  rger = pMerger;.
fce0: 20 20 20 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b      pIncr->pTask
fcf0: 20 3d 20 70 54 61 73 6b 3b 0a 20 20 20 20 70 49   = pTask;.    pI
fd00: 6e 63 72 2d 3e 6d 78 53 7a 20 3d 20 4d 41 58 28  ncr->mxSz = MAX(
fd10: 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e  pTask->pSorter->
fd20: 6d 78 4b 65 79 73 69 7a 65 2b 39 2c 70 54 61 73  mxKeysize+9,pTas
fd30: 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d  k->pSorter->mxPm
fd40: 61 53 69 7a 65 2f 32 29 3b 0a 20 20 20 20 70 54  aSize/2);.    pT
fd50: 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 20  ask->file2.iEof 
fd60: 2b 3d 20 70 49 6e 63 72 2d 3e 6d 78 53 7a 3b 0a  += pIncr->mxSz;.
fd70: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 76 64 62    }else{.    vdb
fd80: 65 4d 65 72 67 65 45 6e 67 69 6e 65 46 72 65 65  eMergeEngineFree
fd90: 28 70 4d 65 72 67 65 72 29 3b 0a 20 20 20 20 72  (pMerger);.    r
fda0: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
fdb0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
fdc0: 63 3b 0a 7d 0a 0a 23 69 66 20 53 51 4c 49 54 45  c;.}..#if SQLITE
fdd0: 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45  _MAX_WORKER_THRE
fde0: 41 44 53 3e 30 0a 2f 2a 0a 2a 2a 20 53 65 74 20  ADS>0./*.** Set 
fdf0: 74 68 65 20 22 75 73 65 2d 74 68 72 65 61 64 73  the "use-threads
fe00: 22 20 66 6c 61 67 20 6f 6e 20 6f 62 6a 65 63 74  " flag on object
fe10: 20 70 49 6e 63 72 2e 0a 2a 2f 0a 73 74 61 74 69   pIncr..*/.stati
fe20: 63 20 76 6f 69 64 20 76 64 62 65 49 6e 63 72 53  c void vdbeIncrS
fe30: 65 74 54 68 72 65 61 64 73 28 49 6e 63 72 4d 65  etThreads(IncrMe
fe40: 72 67 65 72 20 2a 70 49 6e 63 72 29 7b 0a 20 20  rger *pIncr){.  
fe50: 70 49 6e 63 72 2d 3e 62 55 73 65 54 68 72 65 61  pIncr->bUseThrea
fe60: 64 20 3d 20 31 3b 0a 20 20 70 49 6e 63 72 2d 3e  d = 1;.  pIncr->
fe70: 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f  pTask->file2.iEo
fe80: 66 20 2d 3d 20 70 49 6e 63 72 2d 3e 6d 78 53 7a  f -= pIncr->mxSz
fe90: 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51  ;.}.#endif /* SQ
fea0: 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f  LITE_MAX_WORKER_
feb0: 54 48 52 45 41 44 53 3e 30 20 2a 2f 0a 0a 0a 0a  THREADS>0 */....
fec0: 2f 2a 0a 2a 2a 20 52 65 63 6f 6d 70 75 74 65 20  /*.** Recompute 
fed0: 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69  pMerger->aTree[i
fee0: 4f 75 74 5d 20 62 79 20 63 6f 6d 70 61 72 69 6e  Out] by comparin
fef0: 67 20 74 68 65 20 6e 65 78 74 20 6b 65 79 73 20  g the next keys 
ff00: 6f 6e 20 74 68 65 0a 2a 2a 20 74 77 6f 20 50 6d  on the.** two Pm
ff10: 61 52 65 61 64 65 72 73 20 74 68 61 74 20 66 65  aReaders that fe
ff20: 65 64 20 74 68 61 74 20 65 6e 74 72 79 2e 20 20  ed that entry.  
ff30: 4e 65 69 74 68 65 72 20 6f 66 20 74 68 65 20 50  Neither of the P
ff40: 6d 61 52 65 61 64 65 72 73 0a 2a 2a 20 61 72 65  maReaders.** are
ff50: 20 61 64 76 61 6e 63 65 64 2e 20 20 54 68 69 73   advanced.  This
ff60: 20 72 6f 75 74 69 6e 65 20 6d 65 72 65 6c 79 20   routine merely 
ff70: 64 6f 65 73 20 74 68 65 20 63 6f 6d 70 61 72 69  does the compari
ff80: 73 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  son..*/.static v
ff90: 6f 69 64 20 76 64 62 65 4d 65 72 67 65 45 6e 67  oid vdbeMergeEng
ffa0: 69 6e 65 43 6f 6d 70 61 72 65 28 0a 20 20 4d 65  ineCompare(.  Me
ffb0: 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67  rgeEngine *pMerg
ffc0: 65 72 2c 20 20 2f 2a 20 4d 65 72 67 65 20 65 6e  er,  /* Merge en
ffd0: 67 69 6e 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20  gine containing 
ffe0: 50 6d 61 52 65 61 64 65 72 73 20 74 6f 20 63 6f  PmaReaders to co
fff0: 6d 70 61 72 65 20 2a 2f 0a 20 20 69 6e 74 20 69  mpare */.  int i
10000 4f 75 74 20 20 20 20 20 20 20 20 20 20 20 20 20  Out             
10010 20 20 2f 2a 20 53 74 6f 72 65 20 74 68 65 20 72    /* Store the r
10020 65 73 75 6c 74 20 69 6e 20 70 4d 65 72 67 65 72  esult in pMerger
10030 2d 3e 61 54 72 65 65 5b 69 4f 75 74 5d 20 2a 2f  ->aTree[iOut] */
10040 0a 29 7b 0a 20 20 69 6e 74 20 69 31 3b 0a 20 20  .){.  int i1;.  
10050 69 6e 74 20 69 32 3b 0a 20 20 69 6e 74 20 69 52  int i2;.  int iR
10060 65 73 3b 0a 20 20 50 6d 61 52 65 61 64 65 72 20  es;.  PmaReader 
10070 2a 70 31 3b 0a 20 20 50 6d 61 52 65 61 64 65 72  *p1;.  PmaReader
10080 20 2a 70 32 3b 0a 0a 20 20 61 73 73 65 72 74 28   *p2;..  assert(
10090 20 69 4f 75 74 3c 70 4d 65 72 67 65 72 2d 3e 6e   iOut<pMerger->n
100a0 54 72 65 65 20 26 26 20 69 4f 75 74 3e 30 20 29  Tree && iOut>0 )
100b0 3b 0a 0a 20 20 69 66 28 20 69 4f 75 74 3e 3d 28  ;..  if( iOut>=(
100c0 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65 2f 32  pMerger->nTree/2
100d0 29 20 29 7b 0a 20 20 20 20 69 31 20 3d 20 28 69  ) ){.    i1 = (i
100e0 4f 75 74 20 2d 20 70 4d 65 72 67 65 72 2d 3e 6e  Out - pMerger->n
100f0 54 72 65 65 2f 32 29 20 2a 20 32 3b 0a 20 20 20  Tree/2) * 2;.   
10100 20 69 32 20 3d 20 69 31 20 2b 20 31 3b 0a 20 20   i2 = i1 + 1;.  
10110 7d 65 6c 73 65 7b 0a 20 20 20 20 69 31 20 3d 20  }else{.    i1 = 
10120 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69  pMerger->aTree[i
10130 4f 75 74 2a 32 5d 3b 0a 20 20 20 20 69 32 20 3d  Out*2];.    i2 =
10140 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b   pMerger->aTree[
10150 69 4f 75 74 2a 32 2b 31 5d 3b 0a 20 20 7d 0a 0a  iOut*2+1];.  }..
10160 20 20 70 31 20 3d 20 26 70 4d 65 72 67 65 72 2d    p1 = &pMerger-
10170 3e 61 52 65 61 64 72 5b 69 31 5d 3b 0a 20 20 70  >aReadr[i1];.  p
10180 32 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 52  2 = &pMerger->aR
10190 65 61 64 72 5b 69 32 5d 3b 0a 0a 20 20 69 66 28  eadr[i2];..  if(
101a0 20 70 31 2d 3e 70 46 64 3d 3d 30 20 29 7b 0a 20   p1->pFd==0 ){. 
101b0 20 20 20 69 52 65 73 20 3d 20 69 32 3b 0a 20 20     iRes = i2;.  
101c0 7d 65 6c 73 65 20 69 66 28 20 70 32 2d 3e 70 46  }else if( p2->pF
101d0 64 3d 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 73  d==0 ){.    iRes
101e0 20 3d 20 69 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a   = i1;.  }else{.
101f0 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 20 20 20      int res;.   
10200 20 61 73 73 65 72 74 28 20 70 4d 65 72 67 65 72   assert( pMerger
10210 2d 3e 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b  ->pTask->pUnpack
10220 65 64 21 3d 30 20 29 3b 20 20 2f 2a 20 66 72 6f  ed!=0 );  /* fro
10230 6d 20 76 64 62 65 53 6f 72 74 53 75 62 74 61 73  m vdbeSortSubtas
10240 6b 4d 61 69 6e 28 29 20 2a 2f 0a 20 20 20 20 72  kMain() */.    r
10250 65 73 20 3d 20 76 64 62 65 53 6f 72 74 65 72 43  es = vdbeSorterC
10260 6f 6d 70 61 72 65 28 0a 20 20 20 20 20 20 20 20  ompare(.        
10270 70 4d 65 72 67 65 72 2d 3e 70 54 61 73 6b 2c 20  pMerger->pTask, 
10280 70 31 2d 3e 61 4b 65 79 2c 20 70 31 2d 3e 6e 4b  p1->aKey, p1->nK
10290 65 79 2c 20 70 32 2d 3e 61 4b 65 79 2c 20 70 32  ey, p2->aKey, p2
102a0 2d 3e 6e 4b 65 79 0a 20 20 20 20 29 3b 0a 20 20  ->nKey.    );.  
102b0 20 20 69 66 28 20 72 65 73 3c 3d 30 20 29 7b 0a    if( res<=0 ){.
102c0 20 20 20 20 20 20 69 52 65 73 20 3d 20 69 31 3b        iRes = i1;
102d0 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
102e0 20 20 69 52 65 73 20 3d 20 69 32 3b 0a 20 20 20    iRes = i2;.   
102f0 20 7d 0a 20 20 7d 0a 0a 20 20 70 4d 65 72 67 65   }.  }..  pMerge
10300 72 2d 3e 61 54 72 65 65 5b 69 4f 75 74 5d 20 3d  r->aTree[iOut] =
10310 20 69 52 65 73 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20   iRes;.}../*.** 
10320 41 6c 6c 6f 77 65 64 20 76 61 6c 75 65 73 20 66  Allowed values f
10330 6f 72 20 74 68 65 20 65 4d 6f 64 65 20 70 61 72  or the eMode par
10340 61 6d 65 74 65 72 20 74 6f 20 76 64 62 65 4d 65  ameter to vdbeMe
10350 72 67 65 45 6e 67 69 6e 65 49 6e 69 74 28 29 0a  rgeEngineInit().
10360 2a 2a 20 61 6e 64 20 76 64 62 65 50 6d 61 52 65  ** and vdbePmaRe
10370 61 64 65 72 49 6e 63 72 4d 65 72 67 65 49 6e 69  aderIncrMergeIni
10380 74 28 29 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  t()..*/.#define 
10390 49 4e 43 52 49 4e 49 54 5f 4e 4f 52 4d 41 4c 20  INCRINIT_NORMAL 
103a0 30 0a 23 64 65 66 69 6e 65 20 49 4e 43 52 49 4e  0.#define INCRIN
103b0 49 54 5f 54 41 53 4b 20 20 20 31 0a 23 64 65 66  IT_TASK   1.#def
103c0 69 6e 65 20 49 4e 43 52 49 4e 49 54 5f 52 4f 4f  ine INCRINIT_ROO
103d0 54 20 20 20 32 0a 0a 2f 2a 20 46 6f 72 77 61 72  T   2../* Forwar
103e0 64 20 72 65 66 65 72 65 6e 63 65 2e 0a 2a 2a 20  d reference..** 
103f0 54 68 65 20 76 64 62 65 49 6e 63 72 4d 65 72 67  The vdbeIncrMerg
10400 65 49 6e 69 74 28 29 20 61 6e 64 20 76 64 62 65  eInit() and vdbe
10410 50 6d 61 52 65 61 64 65 72 49 6e 63 72 4d 65 72  PmaReaderIncrMer
10420 67 65 49 6e 69 74 28 29 20 72 6f 75 74 69 6e 65  geInit() routine
10430 73 20 63 61 6c 6c 20 65 61 63 68 0a 2a 2a 20 6f  s call each.** o
10440 74 68 65 72 20 28 77 68 65 6e 20 62 75 69 6c 64  ther (when build
10450 69 6e 67 20 61 20 6d 65 72 67 65 20 74 72 65 65  ing a merge tree
10460 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  )..*/.static int
10470 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 49 6e   vdbePmaReaderIn
10480 63 72 4d 65 72 67 65 49 6e 69 74 28 50 6d 61 52  crMergeInit(PmaR
10490 65 61 64 65 72 20 2a 70 52 65 61 64 72 2c 20 69  eader *pReadr, i
104a0 6e 74 20 65 4d 6f 64 65 29 3b 0a 0a 2f 2a 0a 2a  nt eMode);../*.*
104b0 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65  * Initialize the
104c0 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 6f 62 6a   MergeEngine obj
104d0 65 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68  ect passed as th
104e0 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e  e second argumen
104f0 74 2e 20 4f 6e 63 65 20 74 68 69 73 0a 2a 2a 20  t. Once this.** 
10500 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73  function returns
10510 2c 20 74 68 65 20 66 69 72 73 74 20 6b 65 79 20  , the first key 
10520 6f 66 20 6d 65 72 67 65 64 20 64 61 74 61 20 6d  of merged data m
10530 61 79 20 62 65 20 72 65 61 64 20 66 72 6f 6d 20  ay be read from 
10540 74 68 65 20 0a 2a 2a 20 4d 65 72 67 65 45 6e 67  the .** MergeEng
10550 69 6e 65 20 6f 62 6a 65 63 74 20 69 6e 20 74 68  ine object in th
10560 65 20 75 73 75 61 6c 20 66 61 73 68 69 6f 6e 2e  e usual fashion.
10570 0a 2a 2a 0a 2a 2a 20 49 66 20 61 72 67 75 6d 65  .**.** If argume
10580 6e 74 20 65 4d 6f 64 65 20 69 73 20 49 4e 43 52  nt eMode is INCR
10590 49 4e 49 54 5f 52 4f 4f 54 2c 20 74 68 65 6e 20  INIT_ROOT, then 
105a0 69 74 20 69 73 20 61 73 73 75 6d 65 64 20 74 68  it is assumed th
105b0 61 74 20 61 6e 79 20 49 6e 63 72 4d 65 72 67 65  at any IncrMerge
105c0 0a 2a 2a 20 6f 62 6a 65 63 74 73 20 61 74 74 61  .** objects atta
105d0 63 68 65 64 20 74 6f 20 74 68 65 20 50 6d 61 52  ched to the PmaR
105e0 65 61 64 65 72 20 6f 62 6a 65 63 74 73 20 74 68  eader objects th
105f0 61 74 20 74 68 65 20 6d 65 72 67 65 72 20 72 65  at the merger re
10600 61 64 73 20 66 72 6f 6d 20 68 61 76 65 0a 2a 2a  ads from have.**
10610 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 70 6f   already been po
10620 70 75 6c 61 74 65 64 2c 20 62 75 74 20 74 68 61  pulated, but tha
10630 74 20 74 68 65 79 20 68 61 76 65 20 6e 6f 74 20  t they have not 
10640 79 65 74 20 70 6f 70 75 6c 61 74 65 64 20 61 46  yet populated aF
10650 69 6c 65 5b 30 5d 20 61 6e 64 0a 2a 2a 20 73 65  ile[0] and.** se
10660 74 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 20  t the PmaReader 
10670 6f 62 6a 65 63 74 73 20 75 70 20 74 6f 20 72 65  objects up to re
10680 61 64 20 66 72 6f 6d 20 69 74 2e 20 49 6e 20 74  ad from it. In t
10690 68 69 73 20 63 61 73 65 20 61 6c 6c 20 74 68 61  his case all tha
106a0 74 20 69 73 0a 2a 2a 20 72 65 71 75 69 72 65 64  t is.** required
106b0 20 69 73 20 74 6f 20 63 61 6c 6c 20 76 64 62 65   is to call vdbe
106c0 50 6d 61 52 65 61 64 65 72 4e 65 78 74 28 29 20  PmaReaderNext() 
106d0 6f 6e 20 65 61 63 68 20 50 6d 61 52 65 61 64 65  on each PmaReade
106e0 72 20 74 6f 20 70 6f 69 6e 74 20 69 74 20 61 74  r to point it at
106f0 0a 2a 2a 20 69 74 73 20 66 69 72 73 74 20 6b 65  .** its first ke
10700 79 2e 0a 2a 2a 0a 2a 2a 20 4f 74 68 65 72 77 69  y..**.** Otherwi
10710 73 65 2c 20 69 66 20 65 4d 6f 64 65 20 69 73 20  se, if eMode is 
10720 61 6e 79 20 76 61 6c 75 65 20 6f 74 68 65 72 20  any value other 
10730 74 68 61 6e 20 49 4e 43 52 49 4e 49 54 5f 52 4f  than INCRINIT_RO
10740 4f 54 2c 20 74 68 65 6e 20 75 73 65 20 0a 2a 2a  OT, then use .**
10750 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 49 6e   vdbePmaReaderIn
10760 63 72 4d 65 72 67 65 49 6e 69 74 28 29 20 74 6f  crMergeInit() to
10770 20 69 6e 69 74 69 61 6c 69 7a 65 20 65 61 63 68   initialize each
10780 20 50 6d 61 52 65 61 64 65 72 20 74 68 61 74 20   PmaReader that 
10790 66 65 65 64 73 20 64 61 74 61 20 0a 2a 2a 20 74  feeds data .** t
107a0 6f 20 70 4d 65 72 67 65 72 2e 0a 2a 2a 0a 2a 2a  o pMerger..**.**
107b0 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65   SQLITE_OK is re
107c0 74 75 72 6e 65 64 20 69 66 20 73 75 63 63 65 73  turned if succes
107d0 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69  sful, or an SQLi
107e0 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 6f 74  te error code ot
107f0 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74  herwise..*/.stat
10800 69 63 20 69 6e 74 20 76 64 62 65 4d 65 72 67 65  ic int vdbeMerge
10810 45 6e 67 69 6e 65 49 6e 69 74 28 0a 20 20 53 6f  EngineInit(.  So
10820 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b  rtSubtask *pTask
10830 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
10840 20 54 68 72 65 61 64 20 74 68 61 74 20 77 69 6c   Thread that wil
10850 6c 20 72 75 6e 20 70 4d 65 72 67 65 72 20 2a 2f  l run pMerger */
10860 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a  .  MergeEngine *
10870 70 4d 65 72 67 65 72 2c 20 20 20 20 20 20 20 20  pMerger,        
10880 20 20 20 2f 2a 20 4d 65 72 67 65 45 6e 67 69 6e     /* MergeEngin
10890 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20  e to initialize 
108a0 2a 2f 0a 20 20 69 6e 74 20 65 4d 6f 64 65 20 20  */.  int eMode  
108b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
108c0 20 20 20 20 20 2f 2a 20 4f 6e 65 20 6f 66 20 74       /* One of t
108d0 68 65 20 49 4e 43 52 49 4e 49 54 5f 58 58 58 20  he INCRINIT_XXX 
108e0 63 6f 6e 73 74 61 6e 74 73 20 2a 2f 0a 29 7b 0a  constants */.){.
108f0 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
10900 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20  E_OK;           
10910 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
10920 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20   */.  int i;    
10930 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10940 20 20 20 20 20 20 2f 2a 20 46 6f 72 20 6c 6f 6f        /* For loo
10950 70 69 6e 67 20 6f 76 65 72 20 50 6d 61 52 65 61  ping over PmaRea
10960 64 65 72 20 6f 62 6a 65 63 74 73 20 2a 2f 0a 20  der objects */. 
10970 20 69 6e 74 20 6e 54 72 65 65 20 3d 20 70 4d 65   int nTree = pMe
10980 72 67 65 72 2d 3e 6e 54 72 65 65 3b 0a 0a 20 20  rger->nTree;..  
10990 2f 2a 20 56 65 72 69 66 79 20 74 68 61 74 20 74  /* Verify that t
109a0 68 65 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 69  he MergeEngine i
109b0 73 20 61 73 73 69 67 6e 65 64 20 74 6f 20 61 20  s assigned to a 
109c0 73 69 6e 67 6c 65 20 74 68 72 65 61 64 20 2a 2f  single thread */
109d0 0a 20 20 61 73 73 65 72 74 28 20 70 4d 65 72 67  .  assert( pMerg
109e0 65 72 2d 3e 70 54 61 73 6b 3d 3d 30 20 7c 7c 20  er->pTask==0 || 
109f0 70 4d 65 72 67 65 72 2d 3e 70 54 61 73 6b 3d 3d  pMerger->pTask==
10a00 70 54 61 73 6b 20 29 3b 0a 20 20 70 4d 65 72 67  pTask );.  pMerg
10a10 65 72 2d 3e 70 54 61 73 6b 20 3d 20 70 54 61 73  er->pTask = pTas
10a20 6b 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  k;..  for(i=0; i
10a30 3c 6e 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20 20  <nTree; i++){.  
10a40 20 20 69 66 28 20 65 4d 6f 64 65 3d 3d 49 4e 43    if( eMode==INC
10a50 52 49 4e 49 54 5f 52 4f 4f 54 20 29 7b 0a 20 20  RINIT_ROOT ){.  
10a60 20 20 20 20 2f 2a 20 50 6d 61 52 65 61 64 65 72      /* PmaReader
10a70 73 20 73 68 6f 75 6c 64 20 62 65 20 6e 6f 72 6d  s should be norm
10a80 61 6c 6c 79 20 69 6e 69 74 69 61 6c 69 7a 65 64  ally initialized
10a90 20 69 6e 20 6f 72 64 65 72 2c 20 61 73 20 69 66   in order, as if
10aa0 20 74 68 65 79 20 61 72 65 0a 20 20 20 20 20 20   they are.      
10ab0 2a 2a 20 72 65 61 64 69 6e 67 20 66 72 6f 6d 20  ** reading from 
10ac0 74 68 65 20 73 61 6d 65 20 74 65 6d 70 20 66 69  the same temp fi
10ad0 6c 65 20 74 68 69 73 20 6d 61 6b 65 73 20 66 6f  le this makes fo
10ae0 72 20 6d 6f 72 65 20 6c 69 6e 65 61 72 20 66 69  r more linear fi
10af0 6c 65 20 49 4f 2e 0a 20 20 20 20 20 20 2a 2a 20  le IO..      ** 
10b00 48 6f 77 65 76 65 72 2c 20 69 6e 20 74 68 65 20  However, in the 
10b10 49 4e 43 52 49 4e 49 54 5f 52 4f 4f 54 20 63 61  INCRINIT_ROOT ca
10b20 73 65 2c 20 69 66 20 50 6d 61 52 65 61 64 65 72  se, if PmaReader
10b30 20 61 52 65 61 64 72 5b 6e 54 61 73 6b 2d 31 5d   aReadr[nTask-1]
10b40 20 69 73 0a 20 20 20 20 20 20 2a 2a 20 69 6e 20   is.      ** in 
10b50 75 73 65 20 69 74 20 77 69 6c 6c 20 62 6c 6f 63  use it will bloc
10b60 6b 20 74 68 65 20 76 64 62 65 50 6d 61 52 65 61  k the vdbePmaRea
10b70 64 65 72 4e 65 78 74 28 29 20 63 61 6c 6c 20 77  derNext() call w
10b80 68 69 6c 65 20 69 74 20 75 73 65 73 0a 20 20 20  hile it uses.   
10b90 20 20 20 2a 2a 20 74 68 65 20 6d 61 69 6e 20 74     ** the main t
10ba0 68 72 65 61 64 20 74 6f 20 66 69 6c 6c 20 69 74  hread to fill it
10bb0 73 20 62 75 66 66 65 72 2e 20 53 6f 20 63 61 6c  s buffer. So cal
10bc0 6c 69 6e 67 20 50 6d 61 52 65 61 64 65 72 4e 65  ling PmaReaderNe
10bd0 78 74 28 29 0a 20 20 20 20 20 20 2a 2a 20 6f 6e  xt().      ** on
10be0 20 74 68 69 73 20 50 6d 61 52 65 61 64 65 72 20   this PmaReader 
10bf0 62 65 66 6f 72 65 20 61 6e 79 20 6f 66 20 74 68  before any of th
10c00 65 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64  e multi-threaded
10c10 20 50 6d 61 52 65 61 64 65 72 73 20 74 61 6b 65   PmaReaders take
10c20 73 0a 20 20 20 20 20 20 2a 2a 20 62 65 74 74 65  s.      ** bette
10c30 72 20 61 64 76 61 6e 74 61 67 65 20 6f 66 20 6d  r advantage of m
10c40 75 6c 74 69 2d 70 72 6f 63 65 73 73 6f 72 20 68  ulti-processor h
10c50 61 72 64 77 61 72 65 2e 20 2a 2f 0a 20 20 20 20  ardware. */.    
10c60 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65    rc = vdbePmaRe
10c70 61 64 65 72 4e 65 78 74 28 26 70 4d 65 72 67 65  aderNext(&pMerge
10c80 72 2d 3e 61 52 65 61 64 72 5b 6e 54 72 65 65 2d  r->aReadr[nTree-
10c90 69 2d 31 5d 29 3b 0a 20 20 20 20 7d 65 6c 73 65  i-1]);.    }else
10ca0 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62  {.      rc = vdb
10cb0 65 50 6d 61 52 65 61 64 65 72 49 6e 63 72 4d 65  ePmaReaderIncrMe
10cc0 72 67 65 49 6e 69 74 28 26 70 4d 65 72 67 65 72  rgeInit(&pMerger
10cd0 2d 3e 61 52 65 61 64 72 5b 69 5d 2c 20 49 4e 43  ->aReadr[i], INC
10ce0 52 49 4e 49 54 5f 4e 4f 52 4d 41 4c 29 3b 0a 20  RINIT_NORMAL);. 
10cf0 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 21     }.    if( rc!
10d00 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
10d10 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 66  urn rc;.  }..  f
10d20 6f 72 28 69 3d 70 4d 65 72 67 65 72 2d 3e 6e 54  or(i=pMerger->nT
10d30 72 65 65 2d 31 3b 20 69 3e 30 3b 20 69 2d 2d 29  ree-1; i>0; i--)
10d40 7b 0a 20 20 20 20 76 64 62 65 4d 65 72 67 65 45  {.    vdbeMergeE
10d50 6e 67 69 6e 65 43 6f 6d 70 61 72 65 28 70 4d 65  ngineCompare(pMe
10d60 72 67 65 72 2c 20 69 29 3b 0a 20 20 7d 0a 20 20  rger, i);.  }.  
10d70 72 65 74 75 72 6e 20 70 54 61 73 6b 2d 3e 70 55  return pTask->pU
10d80 6e 70 61 63 6b 65 64 2d 3e 65 72 72 43 6f 64 65  npacked->errCode
10d90 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69  ;.}../*.** Initi
10da0 61 6c 69 7a 65 20 74 68 65 20 49 6e 63 72 4d 65  alize the IncrMe
10db0 72 67 65 20 66 69 65 6c 64 20 6f 66 20 61 20 50  rge field of a P
10dc0 6d 61 52 65 61 64 65 72 2e 0a 2a 2a 0a 2a 2a 20  maReader..**.** 
10dd0 49 66 20 74 68 65 20 50 6d 61 52 65 61 64 65 72  If the PmaReader
10de0 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66   passed as the f
10df0 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 69 73  irst argument is
10e00 20 6e 6f 74 20 61 6e 20 69 6e 63 72 65 6d 65 6e   not an incremen
10e10 74 61 6c 2d 72 65 61 64 65 72 0a 2a 2a 20 28 69  tal-reader.** (i
10e20 66 20 70 52 65 61 64 72 2d 3e 70 49 6e 63 72 3d  f pReadr->pIncr=
10e30 3d 30 29 2c 20 74 68 65 6e 20 74 68 69 73 20 66  =0), then this f
10e40 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d  unction is a no-
10e50 6f 70 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69  op. Otherwise, i
10e60 74 20 73 65 72 76 65 73 0a 2a 2a 20 74 6f 20 6f  t serves.** to o
10e70 70 65 6e 20 61 6e 64 2f 6f 72 20 69 6e 69 74 69  pen and/or initi
10e80 61 6c 69 7a 65 20 74 68 65 20 74 65 6d 70 20 66  alize the temp f
10e90 69 6c 65 20 72 65 6c 61 74 65 64 20 66 69 65 6c  ile related fiel
10ea0 64 73 20 6f 66 20 74 68 65 20 49 6e 63 72 4d 65  ds of the IncrMe
10eb0 72 67 65 0a 2a 2a 20 6f 62 6a 65 63 74 20 61 74  rge.** object at
10ec0 20 28 70 52 65 61 64 72 2d 3e 70 49 6e 63 72 29   (pReadr->pIncr)
10ed0 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 72 67 75 6d  ..**.** If argum
10ee0 65 6e 74 20 65 4d 6f 64 65 20 69 73 20 73 65 74  ent eMode is set
10ef0 20 74 6f 20 49 4e 43 52 49 4e 49 54 5f 4e 4f 52   to INCRINIT_NOR
10f00 4d 41 4c 2c 20 74 68 65 6e 20 61 6c 6c 20 50 6d  MAL, then all Pm
10f10 61 52 65 61 64 65 72 73 0a 2a 2a 20 69 6e 20 74  aReaders.** in t
10f20 68 65 20 73 75 62 2d 74 72 65 65 20 68 65 61 64  he sub-tree head
10f30 65 64 20 62 79 20 70 52 65 61 64 72 20 61 72 65  ed by pReadr are
10f40 20 61 6c 73 6f 20 69 6e 69 74 69 61 6c 69 7a 65   also initialize
10f50 64 2e 20 44 61 74 61 20 69 73 20 74 68 65 6e 20  d. Data is then 
10f60 6c 6f 61 64 65 64 0a 2a 2a 20 69 6e 74 6f 20 74  loaded.** into t
10f70 68 65 20 62 75 66 66 65 72 73 20 62 65 6c 6f 6e  he buffers belon
10f80 67 69 6e 67 20 74 6f 20 70 52 65 61 64 72 20 61  ging to pReadr a
10f90 6e 64 20 69 74 20 69 73 20 73 65 74 20 74 6f 0a  nd it is set to.
10fa0 2a 2a 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20  ** point to the 
10fb0 66 69 72 73 74 20 6b 65 79 20 69 6e 20 69 74 73  first key in its
10fc0 20 72 61 6e 67 65 2e 0a 2a 2a 0a 2a 2a 20 49 66   range..**.** If
10fd0 20 61 72 67 75 6d 65 6e 74 20 65 4d 6f 64 65 20   argument eMode 
10fe0 69 73 20 73 65 74 20 74 6f 20 49 4e 43 52 49 4e  is set to INCRIN
10ff0 49 54 5f 54 41 53 4b 2c 20 74 68 65 6e 20 70 52  IT_TASK, then pR
11000 65 61 64 72 20 69 73 20 67 75 61 72 61 6e 74 65  eadr is guarante
11010 65 64 0a 2a 2a 20 74 6f 20 62 65 20 61 20 6d 75  ed.** to be a mu
11020 6c 74 69 2d 74 68 72 65 61 64 65 64 20 50 6d 61  lti-threaded Pma
11030 52 65 61 64 65 72 20 61 6e 64 20 74 68 69 73 20  Reader and this 
11040 66 75 6e 63 74 69 6f 6e 20 69 73 20 62 65 69 6e  function is bein
11050 67 20 63 61 6c 6c 65 64 20 69 6e 20 61 0a 2a 2a  g called in a.**
11060 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65   background thre
11070 61 64 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65  ad. In this case
11080 20 61 6c 6c 20 50 6d 61 52 65 61 64 65 72 73 20   all PmaReaders 
11090 69 6e 20 74 68 65 20 73 75 62 2d 74 72 65 65 20  in the sub-tree 
110a0 61 72 65 20 0a 2a 2a 20 69 6e 69 74 69 61 6c 69  are .** initiali
110b0 7a 65 64 20 61 73 20 66 6f 72 20 49 4e 43 52 49  zed as for INCRI
110c0 4e 49 54 5f 4e 4f 52 4d 41 4c 20 61 6e 64 20 74  NIT_NORMAL and t
110d0 68 65 20 61 46 69 6c 65 5b 31 5d 20 62 75 66 66  he aFile[1] buff
110e0 65 72 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 0a  er belonging to.
110f0 2a 2a 20 70 52 65 61 64 72 20 69 73 20 70 6f 70  ** pReadr is pop
11100 75 6c 61 74 65 64 2e 20 48 6f 77 65 76 65 72 2c  ulated. However,
11110 20 70 52 65 61 64 72 20 69 74 73 65 6c 66 20 69   pReadr itself i
11120 73 20 6e 6f 74 20 73 65 74 20 75 70 20 74 6f 20  s not set up to 
11130 70 6f 69 6e 74 0a 2a 2a 20 74 6f 20 69 74 73 20  point.** to its 
11140 66 69 72 73 74 20 6b 65 79 2e 20 41 20 63 61 6c  first key. A cal
11150 6c 20 74 6f 20 76 64 62 65 50 6d 61 52 65 61 64  l to vdbePmaRead
11160 65 72 4e 65 78 74 28 29 20 69 73 20 73 74 69 6c  erNext() is stil
11170 6c 20 72 65 71 75 69 72 65 64 20 74 6f 20 64 6f  l required to do
11180 0a 2a 2a 20 74 68 61 74 2e 20 0a 2a 2a 0a 2a 2a  .** that. .**.**
11190 20 54 68 65 20 72 65 61 73 6f 6e 20 74 68 69 73   The reason this
111a0 20 66 75 6e 63 74 69 6f 6e 20 64 6f 65 73 20 6e   function does n
111b0 6f 74 20 63 61 6c 6c 20 76 64 62 65 50 6d 61 52  ot call vdbePmaR
111c0 65 61 64 65 72 4e 65 78 74 28 29 20 69 6d 6d 65  eaderNext() imme
111d0 64 69 61 74 65 6c 79 20 0a 2a 2a 20 69 6e 20 74  diately .** in t
111e0 68 65 20 49 4e 43 52 49 4e 49 54 5f 54 41 53 4b  he INCRINIT_TASK
111f0 20 63 61 73 65 20 69 73 20 74 68 61 74 20 76 64   case is that vd
11200 62 65 50 6d 61 52 65 61 64 65 72 4e 65 78 74 28  bePmaReaderNext(
11210 29 20 61 73 73 75 6d 65 73 20 74 68 61 74 20 69  ) assumes that i
11220 74 20 68 61 73 0a 2a 2a 20 74 6f 20 62 6c 6f 63  t has.** to bloc
11230 6b 20 6f 6e 20 74 68 72 65 61 64 20 28 70 54 61  k on thread (pTa
11240 73 6b 2d 3e 74 68 72 65 61 64 29 20 62 65 66 6f  sk->thread) befo
11250 72 65 20 61 63 63 65 73 73 69 6e 67 20 61 46 69  re accessing aFi
11260 6c 65 5b 31 5d 2e 20 42 75 74 2c 20 73 69 6e 63  le[1]. But, sinc
11270 65 0a 2a 2a 20 74 68 69 73 20 65 6e 74 69 72 65  e.** this entire
11280 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 62 65 69   function is bei
11290 6e 67 20 72 75 6e 20 62 79 20 74 68 72 65 61 64  ng run by thread
112a0 20 28 70 54 61 73 6b 2d 3e 74 68 72 65 61 64 29   (pTask->thread)
112b0 2c 20 74 68 61 74 20 77 69 6c 6c 0a 2a 2a 20 6c  , that will.** l
112c0 65 61 64 20 74 6f 20 74 68 65 20 63 75 72 72 65  ead to the curre
112d0 6e 74 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68  nt background th
112e0 72 65 61 64 20 61 74 74 65 6d 70 74 69 6e 67 20  read attempting 
112f0 74 6f 20 6a 6f 69 6e 20 69 74 73 65 6c 66 2e 0a  to join itself..
11300 2a 2a 0a 2a 2a 20 46 69 6e 61 6c 6c 79 2c 20 69  **.** Finally, i
11310 66 20 61 72 67 75 6d 65 6e 74 20 65 4d 6f 64 65  f argument eMode
11320 20 69 73 20 73 65 74 20 74 6f 20 49 4e 43 52 49   is set to INCRI
11330 4e 49 54 5f 52 4f 4f 54 2c 20 69 74 20 6d 61 79  NIT_ROOT, it may
11340 20 62 65 20 61 73 73 75 6d 65 64 0a 2a 2a 20 74   be assumed.** t
11350 68 61 74 20 70 52 65 61 64 72 2d 3e 70 49 6e 63  hat pReadr->pInc
11360 72 20 69 73 20 61 20 6d 75 6c 74 69 2d 74 68 72  r is a multi-thr
11370 65 61 64 65 64 20 49 6e 63 72 4d 65 72 67 65 20  eaded IncrMerge 
11380 6f 62 6a 65 63 74 73 2c 20 61 6e 64 20 74 68 61  objects, and tha
11390 74 20 61 6c 6c 0a 2a 2a 20 63 68 69 6c 64 2d 74  t all.** child-t
113a0 72 65 65 73 20 68 61 76 65 20 61 6c 72 65 61 64  rees have alread
113b0 79 20 62 65 65 6e 20 69 6e 69 74 69 61 6c 69 7a  y been initializ
113c0 65 64 20 75 73 69 6e 67 20 49 6e 63 72 49 6e 69  ed using IncrIni
113d0 74 28 49 4e 43 52 49 4e 49 54 5f 54 41 53 4b 29  t(INCRINIT_TASK)
113e0 2e 0a 2a 2a 20 49 6e 20 74 68 69 73 20 63 61 73  ..** In this cas
113f0 65 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 4e  e vdbePmaReaderN
11400 65 78 74 28 29 20 69 73 20 63 61 6c 6c 65 64 20  ext() is called 
11410 6f 6e 20 61 6c 6c 20 63 68 69 6c 64 20 50 6d 61  on all child Pma
11420 52 65 61 64 65 72 73 20 61 6e 64 0a 2a 2a 20 74  Readers and.** t
11430 68 65 20 63 75 72 72 65 6e 74 20 50 6d 61 52 65  he current PmaRe
11440 61 64 65 72 20 73 65 74 20 74 6f 20 70 6f 69 6e  ader set to poin
11450 74 20 74 6f 20 74 68 65 20 66 69 72 73 74 20 6b  t to the first k
11460 65 79 20 69 6e 20 69 74 73 20 72 61 6e 67 65 2e  ey in its range.
11470 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b  .**.** SQLITE_OK
11480 20 69 73 20 72 65 74 75 72 6e 65 64 20 69 66 20   is returned if 
11490 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61  successful, or a
114a0 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  n SQLite error c
114b0 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a  ode otherwise..*
114c0 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
114d0 65 50 6d 61 52 65 61 64 65 72 49 6e 63 72 4d 65  ePmaReaderIncrMe
114e0 72 67 65 49 6e 69 74 28 50 6d 61 52 65 61 64 65  rgeInit(PmaReade
114f0 72 20 2a 70 52 65 61 64 72 2c 20 69 6e 74 20 65  r *pReadr, int e
11500 4d 6f 64 65 29 7b 0a 20 20 69 6e 74 20 72 63 20  Mode){.  int rc 
11510 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 49  = SQLITE_OK;.  I
11520 6e 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63 72  ncrMerger *pIncr
11530 20 3d 20 70 52 65 61 64 72 2d 3e 70 49 6e 63 72   = pReadr->pIncr
11540 3b 0a 20 20 69 66 28 20 70 49 6e 63 72 20 29 7b  ;.  if( pIncr ){
11550 0a 20 20 20 20 53 6f 72 74 53 75 62 74 61 73 6b  .    SortSubtask
11560 20 2a 70 54 61 73 6b 20 3d 20 70 49 6e 63 72 2d   *pTask = pIncr-
11570 3e 70 54 61 73 6b 3b 0a 20 20 20 20 73 71 6c 69  >pTask;.    sqli
11580 74 65 33 20 2a 64 62 20 3d 20 70 54 61 73 6b 2d  te3 *db = pTask-
11590 3e 70 53 6f 72 74 65 72 2d 3e 64 62 3b 0a 0a 20  >pSorter->db;.. 
115a0 20 20 20 72 63 20 3d 20 76 64 62 65 4d 65 72 67     rc = vdbeMerg
115b0 65 45 6e 67 69 6e 65 49 6e 69 74 28 70 54 61 73  eEngineInit(pTas
115c0 6b 2c 20 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65  k, pIncr->pMerge
115d0 72 2c 20 65 4d 6f 64 65 29 3b 0a 0a 20 20 20 20  r, eMode);..    
115e0 2f 2a 20 53 65 74 20 75 70 20 74 68 65 20 72 65  /* Set up the re
115f0 71 75 69 72 65 64 20 66 69 6c 65 73 20 66 6f 72  quired files for
11600 20 70 49 6e 63 72 2e 20 41 20 6d 75 6c 74 69 2d   pIncr. A multi-
11610 74 68 65 61 64 65 64 20 49 6e 63 72 4d 65 72 67  theaded IncrMerg
11620 65 20 6f 62 6a 65 63 74 0a 20 20 20 20 2a 2a 20  e object.    ** 
11630 72 65 71 75 69 72 65 73 20 74 77 6f 20 74 65 6d  requires two tem
11640 70 20 66 69 6c 65 73 20 74 6f 20 69 74 73 65 6c  p files to itsel
11650 66 2c 20 77 68 65 72 65 61 73 20 61 20 73 69 6e  f, whereas a sin
11660 67 6c 65 2d 74 68 72 65 61 64 65 64 20 6f 62 6a  gle-threaded obj
11670 65 63 74 0a 20 20 20 20 2a 2a 20 6f 6e 6c 79 20  ect.    ** only 
11680 72 65 71 75 69 72 65 73 20 61 20 72 65 67 69 6f  requires a regio
11690 6e 20 6f 66 20 70 54 61 73 6b 2d 3e 66 69 6c 65  n of pTask->file
116a0 32 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63  2. */.    if( rc
116b0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
116c0 20 20 20 20 20 69 6e 74 20 6d 78 53 7a 20 3d 20       int mxSz = 
116d0 70 49 6e 63 72 2d 3e 6d 78 53 7a 3b 0a 23 69 66  pIncr->mxSz;.#if
116e0 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b   SQLITE_MAX_WORK
116f0 45 52 5f 54 48 52 45 41 44 53 3e 30 0a 20 20 20  ER_THREADS>0.   
11700 20 20 20 69 66 28 20 70 49 6e 63 72 2d 3e 62 55     if( pIncr->bU
11710 73 65 54 68 72 65 61 64 20 29 7b 0a 20 20 20 20  seThread ){.    
11720 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
11730 74 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28  terOpenTempFile(
11740 64 62 2c 20 6d 78 53 7a 2c 20 26 70 49 6e 63 72  db, mxSz, &pIncr
11750 2d 3e 61 46 69 6c 65 5b 30 5d 2e 70 46 64 29 3b  ->aFile[0].pFd);
11760 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d  .        if( rc=
11770 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
11780 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62          rc = vdb
11790 65 53 6f 72 74 65 72 4f 70 65 6e 54 65 6d 70 46  eSorterOpenTempF
117a0 69 6c 65 28 64 62 2c 20 6d 78 53 7a 2c 20 26 70  ile(db, mxSz, &p
117b0 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 2e 70  Incr->aFile[1].p
117c0 46 64 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  Fd);.        }. 
117d0 20 20 20 20 20 7d 65 6c 73 65 0a 23 65 6e 64 69       }else.#endi
117e0 66 0a 20 20 20 20 20 20 2f 2a 69 66 28 20 21 70  f.      /*if( !p
117f0 49 6e 63 72 2d 3e 62 55 73 65 54 68 72 65 61 64  Incr->bUseThread
11800 20 29 2a 2f 7b 0a 20 20 20 20 20 20 20 20 69 66   )*/{.        if
11810 28 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70  ( pTask->file2.p
11820 46 64 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  Fd==0 ){.       
11830 20 20 20 61 73 73 65 72 74 28 20 70 54 61 73 6b     assert( pTask
11840 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 3e 30 20 29  ->file2.iEof>0 )
11850 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d  ;.          rc =
11860 20 76 64 62 65 53 6f 72 74 65 72 4f 70 65 6e 54   vdbeSorterOpenT
11870 65 6d 70 46 69 6c 65 28 64 62 2c 20 70 54 61 73  empFile(db, pTas
11880 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 2c 20 26  k->file2.iEof, &
11890 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64  pTask->file2.pFd
118a0 29 3b 0a 20 20 20 20 20 20 20 20 20 20 70 54 61  );.          pTa
118b0 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 20 3d  sk->file2.iEof =
118c0 20 30 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20   0;.        }.  
118d0 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
118e0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
118f0 20 20 20 20 20 70 49 6e 63 72 2d 3e 61 46 69 6c       pIncr->aFil
11900 65 5b 31 5d 2e 70 46 64 20 3d 20 70 54 61 73 6b  e[1].pFd = pTask
11910 2d 3e 66 69 6c 65 32 2e 70 46 64 3b 0a 20 20 20  ->file2.pFd;.   
11920 20 20 20 20 20 20 20 70 49 6e 63 72 2d 3e 69 53         pIncr->iS
11930 74 61 72 74 4f 66 66 20 3d 20 70 54 61 73 6b 2d  tartOff = pTask-
11940 3e 66 69 6c 65 32 2e 69 45 6f 66 3b 0a 20 20 20  >file2.iEof;.   
11950 20 20 20 20 20 20 20 70 54 61 73 6b 2d 3e 66 69         pTask->fi
11960 6c 65 32 2e 69 45 6f 66 20 2b 3d 20 6d 78 53 7a  le2.iEof += mxSz
11970 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
11980 20 20 7d 0a 20 20 20 20 7d 0a 0a 23 69 66 20 53    }.    }..#if S
11990 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52  QLITE_MAX_WORKER
119a0 5f 54 48 52 45 41 44 53 3e 30 0a 20 20 20 20 69  _THREADS>0.    i
119b0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
119c0 20 26 26 20 70 49 6e 63 72 2d 3e 62 55 73 65 54   && pIncr->bUseT
119d0 68 72 65 61 64 20 29 7b 0a 20 20 20 20 20 20 2f  hread ){.      /
119e0 2a 20 55 73 65 20 74 68 65 20 63 75 72 72 65 6e  * Use the curren
119f0 74 20 74 68 72 65 61 64 20 74 6f 20 70 6f 70 75  t thread to popu
11a00 6c 61 74 65 20 61 46 69 6c 65 5b 31 5d 2c 20 65  late aFile[1], e
11a10 76 65 6e 20 74 68 6f 75 67 68 20 74 68 69 73 0a  ven though this.
11a20 20 20 20 20 20 20 2a 2a 20 50 6d 61 52 65 61 64        ** PmaRead
11a30 65 72 20 69 73 20 6d 75 6c 74 69 2d 74 68 72 65  er is multi-thre
11a40 61 64 65 64 2e 20 54 68 65 20 72 65 61 73 6f 6e  aded. The reason
11a50 20 62 65 69 6e 67 20 74 68 61 74 20 74 68 69 73   being that this
11a60 20 66 75 6e 63 74 69 6f 6e 0a 20 20 20 20 20 20   function.      
11a70 2a 2a 20 69 73 20 61 6c 72 65 61 64 79 20 72 75  ** is already ru
11a80 6e 6e 69 6e 67 20 69 6e 20 62 61 63 6b 67 72 6f  nning in backgro
11a90 75 6e 64 20 74 68 72 65 61 64 20 70 49 6e 63 72  und thread pIncr
11aa0 2d 3e 70 54 61 73 6b 2d 3e 74 68 72 65 61 64 2e  ->pTask->thread.
11ab0 20 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72 74   */.      assert
11ac0 28 20 65 4d 6f 64 65 3d 3d 49 4e 43 52 49 4e 49  ( eMode==INCRINI
11ad0 54 5f 52 4f 4f 54 20 7c 7c 20 65 4d 6f 64 65 3d  T_ROOT || eMode=
11ae0 3d 49 4e 43 52 49 4e 49 54 5f 54 41 53 4b 20 29  =INCRINIT_TASK )
11af0 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62  ;.      rc = vdb
11b00 65 49 6e 63 72 50 6f 70 75 6c 61 74 65 28 70 49  eIncrPopulate(pI
11b10 6e 63 72 29 3b 0a 20 20 20 20 7d 0a 23 65 6e 64  ncr);.    }.#end
11b20 69 66 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  if..    if( rc==
11b30 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 65 4d 6f  SQLITE_OK && eMo
11b40 64 65 21 3d 49 4e 43 52 49 4e 49 54 5f 54 41 53  de!=INCRINIT_TAS
11b50 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  K ){.      rc = 
11b60 76 64 62 65 50 6d 61 52 65 61 64 65 72 4e 65 78  vdbePmaReaderNex
11b70 74 28 70 52 65 61 64 72 29 3b 0a 20 20 20 20 7d  t(pReadr);.    }
11b80 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
11b90 3b 0a 7d 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f  ;.}..#if SQLITE_
11ba0 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41  MAX_WORKER_THREA
11bb0 44 53 3e 30 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d  DS>0./*.** The m
11bc0 61 69 6e 20 72 6f 75 74 69 6e 65 20 66 6f 72 20  ain routine for 
11bd0 76 64 62 65 50 6d 61 52 65 61 64 65 72 49 6e 63  vdbePmaReaderInc
11be0 72 4d 65 72 67 65 49 6e 69 74 28 29 20 6f 70 65  rMergeInit() ope
11bf0 72 61 74 69 6f 6e 73 20 72 75 6e 20 69 6e 20 0a  rations run in .
11c00 2a 2a 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68  ** background th
11c10 72 65 61 64 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  reads..*/.static
11c20 20 76 6f 69 64 20 2a 76 64 62 65 50 6d 61 52 65   void *vdbePmaRe
11c30 61 64 65 72 42 67 49 6e 69 74 28 76 6f 69 64 20  aderBgInit(void 
11c40 2a 70 43 74 78 29 7b 0a 20 20 50 6d 61 52 65 61  *pCtx){.  PmaRea
11c50 64 65 72 20 2a 70 52 65 61 64 65 72 20 3d 20 28  der *pReader = (
11c60 50 6d 61 52 65 61 64 65 72 2a 29 70 43 74 78 3b  PmaReader*)pCtx;
11c70 0a 20 20 76 6f 69 64 20 2a 70 52 65 74 20 3d 20  .  void *pRet = 
11c80 53 51 4c 49 54 45 5f 49 4e 54 5f 54 4f 5f 50 54  SQLITE_INT_TO_PT
11c90 52 28 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  R(.             
11ca0 20 20 20 20 20 76 64 62 65 50 6d 61 52 65 61 64       vdbePmaRead
11cb0 65 72 49 6e 63 72 4d 65 72 67 65 49 6e 69 74 28  erIncrMergeInit(
11cc0 70 52 65 61 64 65 72 2c 49 4e 43 52 49 4e 49 54  pReader,INCRINIT
11cd0 5f 54 41 53 4b 29 0a 20 20 20 20 20 20 20 20 20  _TASK).         
11ce0 20 20 20 20 20 20 29 3b 0a 20 20 70 52 65 61 64        );.  pRead
11cf0 65 72 2d 3e 70 49 6e 63 72 2d 3e 70 54 61 73 6b  er->pIncr->pTask
11d00 2d 3e 62 44 6f 6e 65 20 3d 20 31 3b 0a 20 20 72  ->bDone = 1;.  r
11d10 65 74 75 72 6e 20 70 52 65 74 3b 0a 7d 0a 0a 2f  eturn pRet;.}../
11d20 2a 0a 2a 2a 20 55 73 65 20 61 20 62 61 63 6b 67  *.** Use a backg
11d30 72 6f 75 6e 64 20 74 68 72 65 61 64 20 74 6f 20  round thread to 
11d40 69 6e 76 6f 6b 65 20 76 64 62 65 50 6d 61 52 65  invoke vdbePmaRe
11d50 61 64 65 72 49 6e 63 72 4d 65 72 67 65 49 6e 69  aderIncrMergeIni
11d60 74 28 49 4e 43 52 49 4e 49 54 5f 54 41 53 4b 29  t(INCRINIT_TASK)
11d70 20 0a 2a 2a 20 6f 6e 20 74 68 65 20 74 68 65 20   .** on the the 
11d80 50 6d 61 52 65 61 64 65 72 20 6f 62 6a 65 63 74  PmaReader object
11d90 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66   passed as the f
11da0 69 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a  irst argument..*
11db0 2a 0a 2a 2a 20 54 68 69 73 20 63 61 6c 6c 20 77  *.** This call w
11dc0 69 6c 6c 20 69 6e 69 74 69 61 6c 69 7a 65 20 74  ill initialize t
11dd0 68 65 20 76 61 72 69 6f 75 73 20 66 69 65 6c 64  he various field
11de0 73 20 6f 66 20 74 68 65 20 70 52 65 61 64 72 2d  s of the pReadr-
11df0 3e 70 49 6e 63 72 20 0a 2a 2a 20 73 74 72 75 63  >pIncr .** struc
11e00 74 75 72 65 20 61 6e 64 2c 20 69 66 20 69 74 20  ture and, if it 
11e10 69 73 20 61 20 6d 75 6c 74 69 2d 74 68 72 65 61  is a multi-threa
11e20 64 65 64 20 49 6e 63 72 4d 65 72 67 65 72 2c 20  ded IncrMerger, 
11e30 6c 61 75 6e 63 68 20 61 20 0a 2a 2a 20 62 61 63  launch a .** bac
11e40 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 74  kground thread t
11e50 6f 20 70 6f 70 75 6c 61 74 65 20 61 46 69 6c 65  o populate aFile
11e60 5b 31 5d 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  [1]..*/.static i
11e70 6e 74 20 76 64 62 65 50 6d 61 52 65 61 64 65 72  nt vdbePmaReader
11e80 42 67 49 6e 63 72 49 6e 69 74 28 50 6d 61 52 65  BgIncrInit(PmaRe
11e90 61 64 65 72 20 2a 70 52 65 61 64 72 29 7b 0a 20  ader *pReadr){. 
11ea0 20 76 6f 69 64 20 2a 70 43 74 78 20 3d 20 28 76   void *pCtx = (v
11eb0 6f 69 64 2a 29 70 52 65 61 64 72 3b 0a 20 20 72  oid*)pReadr;.  r
11ec0 65 74 75 72 6e 20 76 64 62 65 53 6f 72 74 65 72  eturn vdbeSorter
11ed0 43 72 65 61 74 65 54 68 72 65 61 64 28 70 52 65  CreateThread(pRe
11ee0 61 64 72 2d 3e 70 49 6e 63 72 2d 3e 70 54 61 73  adr->pIncr->pTas
11ef0 6b 2c 20 76 64 62 65 50 6d 61 52 65 61 64 65 72  k, vdbePmaReader
11f00 42 67 49 6e 69 74 2c 20 70 43 74 78 29 3b 0a 7d  BgInit, pCtx);.}
11f10 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 41  .#endif../*.** A
11f20 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 4d 65  llocate a new Me
11f30 72 67 65 45 6e 67 69 6e 65 20 6f 62 6a 65 63 74  rgeEngine object
11f40 20 74 6f 20 6d 65 72 67 65 20 74 68 65 20 63 6f   to merge the co
11f50 6e 74 65 6e 74 73 20 6f 66 20 6e 50 4d 41 20 6c  ntents of nPMA l
11f60 65 76 65 6c 2d 30 0a 2a 2a 20 50 4d 41 73 20 66  evel-0.** PMAs f
11f70 72 6f 6d 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e  rom pTask->file.
11f80 20 49 66 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63   If no error occ
11f90 75 72 73 2c 20 73 65 74 20 2a 70 70 4f 75 74 20  urs, set *ppOut 
11fa0 74 6f 20 70 6f 69 6e 74 20 74 6f 0a 2a 2a 20 74  to point to.** t
11fb0 68 65 20 6e 65 77 20 6f 62 6a 65 63 74 20 61 6e  he new object an
11fc0 64 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  d return SQLITE_
11fd0 4f 4b 2e 20 4f 72 2c 20 69 66 20 61 6e 20 65 72  OK. Or, if an er
11fe0 72 6f 72 20 64 6f 65 73 20 6f 63 63 75 72 2c 20  ror does occur, 
11ff0 73 65 74 20 2a 70 70 4f 75 74 0a 2a 2a 20 74 6f  set *ppOut.** to
12000 20 4e 55 4c 4c 20 61 6e 64 20 72 65 74 75 72 6e   NULL and return
12010 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
12020 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 57 68 65   code..**.** Whe
12030 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
12040 69 73 20 63 61 6c 6c 65 64 2c 20 2a 70 69 4f 66  is called, *piOf
12050 66 73 65 74 20 69 73 20 73 65 74 20 74 6f 20 74  fset is set to t
12060 68 65 20 6f 66 66 73 65 74 20 6f 66 20 74 68 65  he offset of the
12070 0a 2a 2a 20 66 69 72 73 74 20 50 4d 41 20 74 6f  .** first PMA to
12080 20 72 65 61 64 20 66 72 6f 6d 20 70 54 61 73 6b   read from pTask
12090 2d 3e 66 69 6c 65 2e 20 41 73 73 75 6d 69 6e 67  ->file. Assuming
120a0 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73   no error occurs
120b0 2c 20 69 74 20 69 73 20 0a 2a 2a 20 73 65 74 20  , it is .** set 
120c0 74 6f 20 74 68 65 20 6f 66 66 73 65 74 20 69 6d  to the offset im
120d0 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77  mediately follow
120e0 69 6e 67 20 74 68 65 20 6c 61 73 74 20 62 79 74  ing the last byt
120f0 65 20 6f 66 20 74 68 65 20 6c 61 73 74 0a 2a 2a  e of the last.**
12100 20 50 4d 41 20 62 65 66 6f 72 65 20 72 65 74 75   PMA before retu
12110 72 6e 69 6e 67 2e 20 49 66 20 61 6e 20 65 72 72  rning. If an err
12120 6f 72 20 64 6f 65 73 20 6f 63 63 75 72 2c 20 74  or does occur, t
12130 68 65 6e 20 74 68 65 20 66 69 6e 61 6c 20 76 61  hen the final va
12140 6c 75 65 20 6f 66 0a 2a 2a 20 2a 70 69 4f 66 66  lue of.** *piOff
12150 73 65 74 20 69 73 20 75 6e 64 65 66 69 6e 65 64  set is undefined
12160 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
12170 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4c  vdbeMergeEngineL
12180 65 76 65 6c 30 28 0a 20 20 53 6f 72 74 53 75 62  evel0(.  SortSub
12190 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20 20  task *pTask,    
121a0 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74           /* Sort
121b0 65 72 20 74 61 73 6b 20 74 6f 20 72 65 61 64 20  er task to read 
121c0 66 72 6f 6d 20 2a 2f 0a 20 20 69 6e 74 20 6e 50  from */.  int nP
121d0 4d 41 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  MA,             
121e0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
121f0 62 65 72 20 6f 66 20 50 4d 41 73 20 74 6f 20 72  ber of PMAs to r
12200 65 61 64 20 2a 2f 0a 20 20 69 36 34 20 2a 70 69  ead */.  i64 *pi
12210 4f 66 66 73 65 74 2c 20 20 20 20 20 20 20 20 20  Offset,         
12220 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f           /* IN/O
12230 55 54 3a 20 52 65 61 64 72 20 6f 66 66 73 65 74  UT: Readr offset
12240 20 69 6e 20 70 54 61 73 6b 2d 3e 66 69 6c 65 20   in pTask->file 
12250 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65  */.  MergeEngine
12260 20 2a 2a 70 70 4f 75 74 20 20 20 20 20 20 20 20   **ppOut        
12270 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 65 77       /* OUT: New
12280 20 6d 65 72 67 65 2d 65 6e 67 69 6e 65 20 2a 2f   merge-engine */
12290 0a 29 7b 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e  .){.  MergeEngin
122a0 65 20 2a 70 4e 65 77 3b 20 20 20 20 20 20 20 20  e *pNew;        
122b0 20 20 20 20 20 20 2f 2a 20 4d 65 72 67 65 20 65        /* Merge e
122c0 6e 67 69 6e 65 20 74 6f 20 72 65 74 75 72 6e 20  ngine to return 
122d0 2a 2f 0a 20 20 69 36 34 20 69 4f 66 66 20 3d 20  */.  i64 iOff = 
122e0 2a 70 69 4f 66 66 73 65 74 3b 0a 20 20 69 6e 74  *piOffset;.  int
122f0 20 69 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53   i;.  int rc = S
12300 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2a 70 70  QLITE_OK;..  *pp
12310 4f 75 74 20 3d 20 70 4e 65 77 20 3d 20 76 64 62  Out = pNew = vdb
12320 65 4d 65 72 67 65 45 6e 67 69 6e 65 4e 65 77 28  eMergeEngineNew(
12330 6e 50 4d 41 29 3b 0a 20 20 69 66 28 20 70 4e 65  nPMA);.  if( pNe
12340 77 3d 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49  w==0 ) rc = SQLI
12350 54 45 5f 4e 4f 4d 45 4d 3b 0a 0a 20 20 66 6f 72  TE_NOMEM;..  for
12360 28 69 3d 30 3b 20 69 3c 6e 50 4d 41 20 26 26 20  (i=0; i<nPMA && 
12370 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69  rc==SQLITE_OK; i
12380 2b 2b 29 7b 0a 20 20 20 20 69 36 34 20 6e 44 75  ++){.    i64 nDu
12390 6d 6d 79 3b 0a 20 20 20 20 50 6d 61 52 65 61 64  mmy;.    PmaRead
123a0 65 72 20 2a 70 52 65 61 64 72 20 3d 20 26 70 4e  er *pReadr = &pN
123b0 65 77 2d 3e 61 52 65 61 64 72 5b 69 5d 3b 0a 20  ew->aReadr[i];. 
123c0 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52     rc = vdbePmaR
123d0 65 61 64 65 72 49 6e 69 74 28 70 54 61 73 6b 2c  eaderInit(pTask,
123e0 20 26 70 54 61 73 6b 2d 3e 66 69 6c 65 2c 20 69   &pTask->file, i
123f0 4f 66 66 2c 20 70 52 65 61 64 72 2c 20 26 6e 44  Off, pReadr, &nD
12400 75 6d 6d 79 29 3b 0a 20 20 20 20 69 4f 66 66 20  ummy);.    iOff 
12410 3d 20 70 52 65 61 64 72 2d 3e 69 45 6f 66 3b 0a  = pReadr->iEof;.
12420 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53    }..  if( rc!=S
12430 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
12440 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46  vdbeMergeEngineF
12450 72 65 65 28 70 4e 65 77 29 3b 0a 20 20 20 20 2a  ree(pNew);.    *
12460 70 70 4f 75 74 20 3d 20 30 3b 0a 20 20 7d 0a 20  ppOut = 0;.  }. 
12470 20 2a 70 69 4f 66 66 73 65 74 20 3d 20 69 4f 66   *piOffset = iOf
12480 66 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  f;.  return rc;.
12490 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
124a0 74 68 65 20 64 65 70 74 68 20 6f 66 20 61 20 74  the depth of a t
124b0 72 65 65 20 63 6f 6d 70 72 69 73 69 6e 67 20 6e  ree comprising n
124c0 50 4d 41 20 50 4d 41 73 2c 20 61 73 73 75 6d 69  PMA PMAs, assumi
124d0 6e 67 20 61 20 66 61 6e 6f 75 74 20 6f 66 0a 2a  ng a fanout of.*
124e0 2a 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52  * SORTER_MAX_MER
124f0 47 45 5f 43 4f 55 4e 54 2e 20 54 68 65 20 72 65  GE_COUNT. The re
12500 74 75 72 6e 65 64 20 76 61 6c 75 65 20 64 6f 65  turned value doe
12510 73 20 6e 6f 74 20 69 6e 63 6c 75 64 65 20 6c 65  s not include le
12520 61 66 20 6e 6f 64 65 73 2e 0a 2a 2a 0a 2a 2a 20  af nodes..**.** 
12530 69 2e 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 6e 50 4d  i.e..**.**   nPM
12540 41 3c 3d 31 36 20 20 20 20 2d 3e 20 54 72 65 65  A<=16    -> Tree
12550 44 65 70 74 68 28 29 20 3d 3d 20 30 0a 2a 2a 20  Depth() == 0.** 
12560 20 20 6e 50 4d 41 3c 3d 32 35 36 20 20 20 2d 3e    nPMA<=256   ->
12570 20 54 72 65 65 44 65 70 74 68 28 29 20 3d 3d 20   TreeDepth() == 
12580 31 0a 2a 2a 20 20 20 6e 50 4d 41 3c 3d 36 35 35  1.**   nPMA<=655
12590 33 36 20 2d 3e 20 54 72 65 65 44 65 70 74 68 28  36 -> TreeDepth(
125a0 29 20 3d 3d 20 32 0a 2a 2f 0a 73 74 61 74 69 63  ) == 2.*/.static
125b0 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72 54   int vdbeSorterT
125c0 72 65 65 44 65 70 74 68 28 69 6e 74 20 6e 50 4d  reeDepth(int nPM
125d0 41 29 7b 0a 20 20 69 6e 74 20 6e 44 65 70 74 68  A){.  int nDepth
125e0 20 3d 20 30 3b 0a 20 20 69 36 34 20 6e 44 69 76   = 0;.  i64 nDiv
125f0 20 3d 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45   = SORTER_MAX_ME
12600 52 47 45 5f 43 4f 55 4e 54 3b 0a 20 20 77 68 69  RGE_COUNT;.  whi
12610 6c 65 28 20 6e 44 69 76 20 3c 20 28 69 36 34 29  le( nDiv < (i64)
12620 6e 50 4d 41 20 29 7b 0a 20 20 20 20 6e 44 69 76  nPMA ){.    nDiv
12630 20 3d 20 6e 44 69 76 20 2a 20 53 4f 52 54 45 52   = nDiv * SORTER
12640 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
12650 3b 0a 20 20 20 20 6e 44 65 70 74 68 2b 2b 3b 0a  ;.    nDepth++;.
12660 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 6e 44 65    }.  return nDe
12670 70 74 68 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 70 52  pth;.}../*.** pR
12680 6f 6f 74 20 69 73 20 74 68 65 20 72 6f 6f 74 20  oot is the root 
12690 6f 66 20 61 6e 20 69 6e 63 72 65 6d 65 6e 74 61  of an incrementa
126a0 6c 20 6d 65 72 67 65 2d 74 72 65 65 20 77 69 74  l merge-tree wit
126b0 68 20 64 65 70 74 68 20 6e 44 65 70 74 68 20 28  h depth nDepth (
126c0 61 63 63 6f 72 64 69 6e 67 0a 2a 2a 20 74 6f 20  according.** to 
126d0 76 64 62 65 53 6f 72 74 65 72 54 72 65 65 44 65  vdbeSorterTreeDe
126e0 70 74 68 28 29 29 2e 20 70 4c 65 61 66 20 69 73  pth()). pLeaf is
126f0 20 74 68 65 20 69 53 65 71 27 74 68 20 6c 65 61   the iSeq'th lea
12700 66 20 74 6f 20 62 65 20 61 64 64 65 64 20 74 6f  f to be added to
12710 20 74 68 65 0a 2a 2a 20 74 72 65 65 2c 20 63 6f   the.** tree, co
12720 75 6e 74 69 6e 67 20 66 72 6f 6d 20 7a 65 72 6f  unting from zero
12730 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
12740 61 64 64 73 20 70 4c 65 61 66 20 74 6f 20 74 68  adds pLeaf to th
12750 65 20 74 72 65 65 2e 0a 2a 2a 0a 2a 2a 20 49 66  e tree..**.** If
12760 20 73 75 63 63 65 73 73 66 75 6c 2c 20 53 51 4c   successful, SQL
12770 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e  ITE_OK is return
12780 65 64 2e 20 49 66 20 61 6e 20 65 72 72 6f 72 20  ed. If an error 
12790 6f 63 63 75 72 73 2c 20 61 6e 20 53 51 4c 69 74  occurs, an SQLit
127a0 65 20 65 72 72 6f 72 0a 2a 2a 20 63 6f 64 65 20  e error.** code 
127b0 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20  is returned and 
127c0 70 4c 65 61 66 20 69 73 20 66 72 65 65 64 2e 0a  pLeaf is freed..
127d0 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
127e0 62 65 53 6f 72 74 65 72 41 64 64 54 6f 54 72 65  beSorterAddToTre
127f0 65 28 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b  e(.  SortSubtask
12800 20 2a 70 54 61 73 6b 2c 20 20 20 20 20 20 20 20   *pTask,        
12810 20 20 20 20 20 2f 2a 20 54 61 73 6b 20 63 6f 6e       /* Task con
12820 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 44  text */.  int nD
12830 65 70 74 68 2c 20 20 20 20 20 20 20 20 20 20 20  epth,           
12840 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 65 70            /* Dep
12850 74 68 20 6f 66 20 74 72 65 65 20 61 63 63 6f 72  th of tree accor
12860 64 69 6e 67 20 74 6f 20 54 72 65 65 44 65 70 74  ding to TreeDept
12870 68 28 29 20 2a 2f 0a 20 20 69 6e 74 20 69 53 65  h() */.  int iSe
12880 71 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  q,              
12890 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 71 75           /* Sequ
128a0 65 6e 63 65 20 6e 75 6d 62 65 72 20 6f 66 20 6c  ence number of l
128b0 65 61 66 20 77 69 74 68 69 6e 20 74 72 65 65 20  eaf within tree 
128c0 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65  */.  MergeEngine
128d0 20 2a 70 52 6f 6f 74 2c 20 20 20 20 20 20 20 20   *pRoot,        
128e0 20 20 20 20 20 2f 2a 20 52 6f 6f 74 20 6f 66 20       /* Root of 
128f0 74 72 65 65 20 2a 2f 0a 20 20 4d 65 72 67 65 45  tree */.  MergeE
12900 6e 67 69 6e 65 20 2a 70 4c 65 61 66 20 20 20 20  ngine *pLeaf    
12910 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 65 61            /* Lea
12920 66 20 74 6f 20 61 64 64 20 74 6f 20 74 72 65 65  f to add to tree
12930 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20   */.){.  int rc 
12940 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
12950 6e 74 20 6e 44 69 76 20 3d 20 31 3b 0a 20 20 69  nt nDiv = 1;.  i
12960 6e 74 20 69 3b 0a 20 20 4d 65 72 67 65 45 6e 67  nt i;.  MergeEng
12970 69 6e 65 20 2a 70 20 3d 20 70 52 6f 6f 74 3b 0a  ine *p = pRoot;.
12980 20 20 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49    IncrMerger *pI
12990 6e 63 72 3b 0a 0a 20 20 72 63 20 3d 20 76 64 62  ncr;..  rc = vdb
129a0 65 49 6e 63 72 4e 65 77 28 70 54 61 73 6b 2c 20  eIncrNew(pTask, 
129b0 70 4c 65 61 66 2c 20 26 70 49 6e 63 72 29 3b 0a  pLeaf, &pIncr);.
129c0 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 6e 44  .  for(i=1; i<nD
129d0 65 70 74 68 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  epth; i++){.    
129e0 6e 44 69 76 20 3d 20 6e 44 69 76 20 2a 20 53 4f  nDiv = nDiv * SO
129f0 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
12a00 4f 55 4e 54 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72  OUNT;.  }..  for
12a10 28 69 3d 31 3b 20 69 3c 6e 44 65 70 74 68 20 26  (i=1; i<nDepth &
12a20 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b  & rc==SQLITE_OK;
12a30 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 20 69   i++){.    int i
12a40 49 74 65 72 20 3d 20 28 69 53 65 71 20 2f 20 6e  Iter = (iSeq / n
12a50 44 69 76 29 20 25 20 53 4f 52 54 45 52 5f 4d 41  Div) % SORTER_MA
12a60 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3b 0a 20  X_MERGE_COUNT;. 
12a70 20 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70 52     PmaReader *pR
12a80 65 61 64 72 20 3d 20 26 70 2d 3e 61 52 65 61 64  eadr = &p->aRead
12a90 72 5b 69 49 74 65 72 5d 3b 0a 0a 20 20 20 20 69  r[iIter];..    i
12aa0 66 28 20 70 52 65 61 64 72 2d 3e 70 49 6e 63 72  f( pReadr->pIncr
12ab0 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 4d 65 72  ==0 ){.      Mer
12ac0 67 65 45 6e 67 69 6e 65 20 2a 70 4e 65 77 20 3d  geEngine *pNew =
12ad0 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65   vdbeMergeEngine
12ae0 4e 65 77 28 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  New(SORTER_MAX_M
12af0 45 52 47 45 5f 43 4f 55 4e 54 29 3b 0a 20 20 20  ERGE_COUNT);.   
12b00 20 20 20 69 66 28 20 70 4e 65 77 3d 3d 30 20 29     if( pNew==0 )
12b10 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53  {.        rc = S
12b20 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
12b30 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
12b40 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72 4e    rc = vdbeIncrN
12b50 65 77 28 70 54 61 73 6b 2c 20 70 4e 65 77 2c 20  ew(pTask, pNew, 
12b60 26 70 52 65 61 64 72 2d 3e 70 49 6e 63 72 29 3b  &pReadr->pIncr);
12b70 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
12b80 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
12b90 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 70 20  E_OK ){.      p 
12ba0 3d 20 70 52 65 61 64 72 2d 3e 70 49 6e 63 72 2d  = pReadr->pIncr-
12bb0 3e 70 4d 65 72 67 65 72 3b 0a 20 20 20 20 20 20  >pMerger;.      
12bc0 6e 44 69 76 20 3d 20 6e 44 69 76 20 2f 20 53 4f  nDiv = nDiv / SO
12bd0 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
12be0 4f 55 4e 54 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  OUNT;.    }.  }.
12bf0 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
12c00 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 2d 3e 61  E_OK ){.    p->a
12c10 52 65 61 64 72 5b 69 53 65 71 20 25 20 53 4f 52  Readr[iSeq % SOR
12c20 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
12c30 55 4e 54 5d 2e 70 49 6e 63 72 20 3d 20 70 49 6e  UNT].pIncr = pIn
12c40 63 72 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  cr;.  }else{.   
12c50 20 76 64 62 65 49 6e 63 72 46 72 65 65 28 70 49   vdbeIncrFree(pI
12c60 6e 63 72 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  ncr);.  }.  retu
12c70 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
12c80 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
12c90 20 63 61 6c 6c 65 64 20 61 73 20 70 61 72 74 20   called as part 
12ca0 6f 66 20 61 20 53 6f 72 74 65 72 52 65 77 69 6e  of a SorterRewin
12cb0 64 28 29 20 6f 70 65 72 61 74 69 6f 6e 20 6f 6e  d() operation on
12cc0 20 61 20 73 6f 72 74 65 72 0a 2a 2a 20 74 68 61   a sorter.** tha
12cd0 74 20 68 61 73 20 61 6c 72 65 61 64 79 20 77 72  t has already wr
12ce0 69 74 74 65 6e 20 74 77 6f 20 6f 72 20 6d 6f 72  itten two or mor
12cf0 65 20 6c 65 76 65 6c 2d 30 20 50 4d 41 73 20 74  e level-0 PMAs t
12d00 6f 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 74 65  o one or more te
12d10 6d 70 0a 2a 2a 20 66 69 6c 65 73 2e 20 49 74 20  mp.** files. It 
12d20 62 75 69 6c 64 73 20 61 20 74 72 65 65 20 6f 66  builds a tree of
12d30 20 4d 65 72 67 65 45 6e 67 69 6e 65 2f 49 6e 63   MergeEngine/Inc
12d40 72 4d 65 72 67 65 72 2f 50 6d 61 52 65 61 64 65  rMerger/PmaReade
12d50 72 20 6f 62 6a 65 63 74 73 20 74 68 61 74 20 0a  r objects that .
12d60 2a 2a 20 63 61 6e 20 62 65 20 75 73 65 64 20 74  ** can be used t
12d70 6f 20 69 6e 63 72 65 6d 65 6e 74 61 6c 6c 79 20  o incrementally 
12d80 6d 65 72 67 65 20 61 6c 6c 20 50 4d 41 73 20 6f  merge all PMAs o
12d90 6e 20 64 69 73 6b 2e 0a 2a 2a 0a 2a 2a 20 49 66  n disk..**.** If
12da0 20 73 75 63 63 65 73 73 66 75 6c 2c 20 53 51 4c   successful, SQL
12db0 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e  ITE_OK is return
12dc0 65 64 20 61 6e 64 20 2a 70 70 4f 75 74 20 73 65  ed and *ppOut se
12dd0 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68  t to point to th
12de0 65 0a 2a 2a 20 4d 65 72 67 65 45 6e 67 69 6e 65  e.** MergeEngine
12df0 20 6f 62 6a 65 63 74 20 61 74 20 74 68 65 20 72   object at the r
12e00 6f 6f 74 20 6f 66 20 74 68 65 20 74 72 65 65 20  oot of the tree 
12e10 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  before returning
12e20 2e 20 4f 72 2c 20 69 66 20 61 6e 0a 2a 2a 20 65  . Or, if an.** e
12e30 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 61 6e 20  rror occurs, an 
12e40 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
12e50 65 20 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e  e is returned an
12e60 64 20 74 68 65 20 66 69 6e 61 6c 20 76 61 6c 75  d the final valu
12e70 65 20 0a 2a 2a 20 6f 66 20 2a 70 70 4f 75 74 20  e .** of *ppOut 
12e80 69 73 20 75 6e 64 65 66 69 6e 65 64 2e 0a 2a 2f  is undefined..*/
12e90 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65  .static int vdbe
12ea0 53 6f 72 74 65 72 4d 65 72 67 65 54 72 65 65 42  SorterMergeTreeB
12eb0 75 69 6c 64 28 0a 20 20 56 64 62 65 53 6f 72 74  uild(.  VdbeSort
12ec0 65 72 20 2a 70 53 6f 72 74 65 72 2c 20 20 20 20  er *pSorter,    
12ed0 20 20 20 2f 2a 20 54 68 65 20 56 44 42 45 20 63     /* The VDBE c
12ee0 75 72 73 6f 72 20 74 68 61 74 20 69 6d 70 6c 65  ursor that imple
12ef0 6d 65 6e 74 73 20 74 68 65 20 73 6f 72 74 20 2a  ments the sort *
12f00 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  /.  MergeEngine 
12f10 2a 2a 70 70 4f 75 74 20 20 20 20 20 20 20 20 2f  **ppOut        /
12f20 2a 20 57 72 69 74 65 20 74 68 65 20 4d 65 72 67  * Write the Merg
12f30 65 45 6e 67 69 6e 65 20 68 65 72 65 20 2a 2f 0a  eEngine here */.
12f40 29 7b 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65  ){.  MergeEngine
12f50 20 2a 70 4d 61 69 6e 20 3d 20 30 3b 0a 20 20 69   *pMain = 0;.  i
12f60 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
12f70 4b 3b 0a 20 20 69 6e 74 20 69 54 61 73 6b 3b 0a  K;.  int iTask;.
12f80 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f  .#if SQLITE_MAX_
12f90 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30  WORKER_THREADS>0
12fa0 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 73 6f 72  .  /* If the sor
12fb0 74 65 72 20 75 73 65 73 20 6d 6f 72 65 20 74 68  ter uses more th
12fc0 61 6e 20 6f 6e 65 20 74 61 73 6b 2c 20 74 68 65  an one task, the
12fd0 6e 20 63 72 65 61 74 65 20 74 68 65 20 74 6f 70  n create the top
12fe0 2d 6c 65 76 65 6c 20 0a 20 20 2a 2a 20 4d 65 72  -level .  ** Mer
12ff0 67 65 45 6e 67 69 6e 65 20 68 65 72 65 2e 20 54  geEngine here. T
13000 68 69 73 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  his MergeEngine 
13010 77 69 6c 6c 20 72 65 61 64 20 64 61 74 61 20 66  will read data f
13020 72 6f 6d 20 65 78 61 63 74 6c 79 20 0a 20 20 2a  rom exactly .  *
13030 2a 20 6f 6e 65 20 50 6d 61 52 65 61 64 65 72 20  * one PmaReader 
13040 70 65 72 20 73 75 62 2d 74 61 73 6b 2e 20 20 2a  per sub-task.  *
13050 2f 0a 20 20 61 73 73 65 72 74 28 20 70 53 6f 72  /.  assert( pSor
13060 74 65 72 2d 3e 62 55 73 65 54 68 72 65 61 64 73  ter->bUseThreads
13070 20 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 6e 54 61   || pSorter->nTa
13080 73 6b 3d 3d 31 20 29 3b 0a 20 20 69 66 28 20 70  sk==1 );.  if( p
13090 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3e 31 20  Sorter->nTask>1 
130a0 29 7b 0a 20 20 20 20 70 4d 61 69 6e 20 3d 20 76  ){.    pMain = v
130b0 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4e 65  dbeMergeEngineNe
130c0 77 28 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b  w(pSorter->nTask
130d0 29 3b 0a 20 20 20 20 69 66 28 20 70 4d 61 69 6e  );.    if( pMain
130e0 3d 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49 54  ==0 ) rc = SQLIT
130f0 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 23 65 6e  E_NOMEM;.  }.#en
13100 64 69 66 0a 0a 20 20 66 6f 72 28 69 54 61 73 6b  dif..  for(iTask
13110 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  =0; rc==SQLITE_O
13120 4b 20 26 26 20 69 54 61 73 6b 3c 70 53 6f 72 74  K && iTask<pSort
13130 65 72 2d 3e 6e 54 61 73 6b 3b 20 69 54 61 73 6b  er->nTask; iTask
13140 2b 2b 29 7b 0a 20 20 20 20 53 6f 72 74 53 75 62  ++){.    SortSub
13150 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20 26 70  task *pTask = &p
13160 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 69 54  Sorter->aTask[iT
13170 61 73 6b 5d 3b 0a 20 20 20 20 69 66 28 20 70 54  ask];.    if( pT
13180 61 73 6b 2d 3e 6e 50 4d 41 20 29 7b 0a 20 20 20  ask->nPMA ){.   
13190 20 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a     MergeEngine *
131a0 70 52 6f 6f 74 20 3d 20 30 3b 20 20 20 20 20 2f  pRoot = 0;     /
131b0 2a 20 52 6f 6f 74 20 6e 6f 64 65 20 6f 66 20 74  * Root node of t
131c0 72 65 65 20 66 6f 72 20 74 68 69 73 20 74 61 73  ree for this tas
131d0 6b 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e  k */.      int n
131e0 44 65 70 74 68 20 3d 20 76 64 62 65 53 6f 72 74  Depth = vdbeSort
131f0 65 72 54 72 65 65 44 65 70 74 68 28 70 54 61 73  erTreeDepth(pTas
13200 6b 2d 3e 6e 50 4d 41 29 3b 0a 20 20 20 20 20 20  k->nPMA);.      
13210 69 36 34 20 69 52 65 61 64 4f 66 66 20 3d 20 30  i64 iReadOff = 0
13220 3b 0a 0a 20 20 20 20 20 20 69 66 28 20 70 54 61  ;..      if( pTa
13230 73 6b 2d 3e 6e 50 4d 41 3c 3d 53 4f 52 54 45 52  sk->nPMA<=SORTER
13240 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
13250 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d   ){.        rc =
13260 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65   vdbeMergeEngine
13270 4c 65 76 65 6c 30 28 70 54 61 73 6b 2c 20 70 54  Level0(pTask, pT
13280 61 73 6b 2d 3e 6e 50 4d 41 2c 20 26 69 52 65 61  ask->nPMA, &iRea
13290 64 4f 66 66 2c 20 26 70 52 6f 6f 74 29 3b 0a 20  dOff, &pRoot);. 
132a0 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
132b0 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20      int i;.     
132c0 20 20 20 69 6e 74 20 69 53 65 71 20 3d 20 30 3b     int iSeq = 0;
132d0 0a 20 20 20 20 20 20 20 20 70 52 6f 6f 74 20 3d  .        pRoot =
132e0 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65   vdbeMergeEngine
132f0 4e 65 77 28 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  New(SORTER_MAX_M
13300 45 52 47 45 5f 43 4f 55 4e 54 29 3b 0a 20 20 20  ERGE_COUNT);.   
13310 20 20 20 20 20 69 66 28 20 70 52 6f 6f 74 3d 3d       if( pRoot==
13320 30 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  0 ) rc = SQLITE_
13330 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 20 20 66  NOMEM;.        f
13340 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61 73 6b 2d  or(i=0; i<pTask-
13350 3e 6e 50 4d 41 20 26 26 20 72 63 3d 3d 53 51 4c  >nPMA && rc==SQL
13360 49 54 45 5f 4f 4b 3b 20 69 20 2b 3d 20 53 4f 52  ITE_OK; i += SOR
13370 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
13380 55 4e 54 29 7b 0a 20 20 20 20 20 20 20 20 20 20  UNT){.          
13390 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65  MergeEngine *pMe
133a0 72 67 65 72 20 3d 20 30 3b 20 2f 2a 20 4e 65 77  rger = 0; /* New
133b0 20 6c 65 76 65 6c 2d 30 20 50 4d 41 20 6d 65 72   level-0 PMA mer
133c0 67 65 72 20 2a 2f 0a 20 20 20 20 20 20 20 20 20  ger */.         
133d0 20 69 6e 74 20 6e 52 65 61 64 65 72 3b 20 20 20   int nReader;   
133e0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
133f0 6d 62 65 72 20 6f 66 20 6c 65 76 65 6c 2d 30 20  mber of level-0 
13400 50 4d 41 73 20 74 6f 20 6d 65 72 67 65 20 2a 2f  PMAs to merge */
13410 0a 0a 20 20 20 20 20 20 20 20 20 20 6e 52 65 61  ..          nRea
13420 64 65 72 20 3d 20 4d 49 4e 28 70 54 61 73 6b 2d  der = MIN(pTask-
13430 3e 6e 50 4d 41 20 2d 20 69 2c 20 53 4f 52 54 45  >nPMA - i, SORTE
13440 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
13450 54 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63  T);.          rc
13460 20 3d 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69   = vdbeMergeEngi
13470 6e 65 4c 65 76 65 6c 30 28 70 54 61 73 6b 2c 20  neLevel0(pTask, 
13480 6e 52 65 61 64 65 72 2c 20 26 69 52 65 61 64 4f  nReader, &iReadO
13490 66 66 2c 20 26 70 4d 65 72 67 65 72 29 3b 0a 20  ff, &pMerger);. 
134a0 20 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d           if( rc=
134b0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
134c0 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 76            rc = v
134d0 64 62 65 53 6f 72 74 65 72 41 64 64 54 6f 54 72  dbeSorterAddToTr
134e0 65 65 28 70 54 61 73 6b 2c 20 6e 44 65 70 74 68  ee(pTask, nDepth
134f0 2c 20 69 53 65 71 2b 2b 2c 20 70 52 6f 6f 74 2c  , iSeq++, pRoot,
13500 20 70 4d 65 72 67 65 72 29 3b 0a 20 20 20 20 20   pMerger);.     
13510 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d       }.        }
13520 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
13530 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
13540 4b 20 29 7b 0a 23 69 66 20 53 51 4c 49 54 45 5f  K ){.#if SQLITE_
13550 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41  MAX_WORKER_THREA
13560 44 53 3e 30 0a 20 20 20 20 20 20 20 20 69 66 28  DS>0.        if(
13570 20 70 4d 61 69 6e 21 3d 30 20 29 7b 0a 20 20 20   pMain!=0 ){.   
13580 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65         rc = vdbe
13590 49 6e 63 72 4e 65 77 28 70 54 61 73 6b 2c 20 70  IncrNew(pTask, p
135a0 52 6f 6f 74 2c 20 26 70 4d 61 69 6e 2d 3e 61 52  Root, &pMain->aR
135b0 65 61 64 72 5b 69 54 61 73 6b 5d 2e 70 49 6e 63  eadr[iTask].pInc
135c0 72 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73  r);.        }els
135d0 65 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20 20  e.#endif.       
135e0 20 7b 0a 20 20 20 20 20 20 20 20 20 20 61 73 73   {.          ass
135f0 65 72 74 28 20 70 4d 61 69 6e 3d 3d 30 20 29 3b  ert( pMain==0 );
13600 0a 20 20 20 20 20 20 20 20 20 20 70 4d 61 69 6e  .          pMain
13610 20 3d 20 70 52 6f 6f 74 3b 0a 20 20 20 20 20 20   = pRoot;.      
13620 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b    }.      }else{
13630 0a 20 20 20 20 20 20 20 20 76 64 62 65 4d 65 72  .        vdbeMer
13640 67 65 45 6e 67 69 6e 65 46 72 65 65 28 70 52 6f  geEngineFree(pRo
13650 6f 74 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ot);.      }.   
13660 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63   }.  }..  if( rc
13670 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
13680 20 20 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69     vdbeMergeEngi
13690 6e 65 46 72 65 65 28 70 4d 61 69 6e 29 3b 0a 20  neFree(pMain);. 
136a0 20 20 20 70 4d 61 69 6e 20 3d 20 30 3b 0a 20 20     pMain = 0;.  
136b0 7d 0a 20 20 2a 70 70 4f 75 74 20 3d 20 70 4d 61  }.  *ppOut = pMa
136c0 69 6e 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  in;.  return rc;
136d0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
136e0 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
136f0 64 20 61 73 20 70 61 72 74 20 6f 66 20 61 6e 20  d as part of an 
13700 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
13710 72 52 65 77 69 6e 64 28 29 20 6f 70 65 72 61 74  rRewind() operat
13720 69 6f 6e 0a 2a 2a 20 6f 6e 20 61 20 73 6f 72 74  ion.** on a sort
13730 65 72 20 74 68 61 74 20 68 61 73 20 77 72 69 74  er that has writ
13740 74 65 6e 20 74 77 6f 20 6f 72 20 6d 6f 72 65 20  ten two or more 
13750 50 4d 41 73 20 74 6f 20 74 65 6d 70 6f 72 61 72  PMAs to temporar
13760 79 20 66 69 6c 65 73 2e 20 49 74 20 73 65 74 73  y files. It sets
13770 0a 2a 2a 20 75 70 20 65 69 74 68 65 72 20 56 64  .** up either Vd
13780 62 65 53 6f 72 74 65 72 2e 70 4d 65 72 67 65 72  beSorter.pMerger
13790 20 28 66 6f 72 20 73 69 6e 67 6c 65 20 74 68 72   (for single thr
137a0 65 61 64 65 64 20 73 6f 72 74 65 72 73 29 20 6f  eaded sorters) o
137b0 72 20 70 52 65 61 64 65 72 0a 2a 2a 20 28 66 6f  r pReader.** (fo
137c0 72 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64  r multi-threaded
137d0 20 73 6f 72 74 65 72 73 29 20 73 6f 20 74 68 61   sorters) so tha
137e0 74 20 69 74 20 63 61 6e 20 62 65 20 75 73 65 64  t it can be used
137f0 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f   to iterate thro
13800 75 67 68 0a 2a 2a 20 61 6c 6c 20 72 65 63 6f 72  ugh.** all recor
13810 64 73 20 73 74 6f 72 65 64 20 69 6e 20 74 68 65  ds stored in the
13820 20 73 6f 72 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 53   sorter..**.** S
13830 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75  QLITE_OK is retu
13840 72 6e 65 64 20 69 66 20 73 75 63 63 65 73 73 66  rned if successf
13850 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65  ul, or an SQLite
13860 20 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65   error code othe
13870 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  rwise..*/.static
13880 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72 53   int vdbeSorterS
13890 65 74 75 70 4d 65 72 67 65 28 56 64 62 65 53 6f  etupMerge(VdbeSo
138a0 72 74 65 72 20 2a 70 53 6f 72 74 65 72 29 7b 0a  rter *pSorter){.
138b0 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
138c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
138d0 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
138e0 20 2a 2f 0a 20 20 53 6f 72 74 53 75 62 74 61 73   */.  SortSubtas
138f0 6b 20 2a 70 54 61 73 6b 30 20 3d 20 26 70 53 6f  k *pTask0 = &pSo
13900 72 74 65 72 2d 3e 61 54 61 73 6b 5b 30 5d 3b 0a  rter->aTask[0];.
13910 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70    MergeEngine *p
13920 4d 61 69 6e 20 3d 20 30 3b 0a 23 69 66 20 53 51  Main = 0;.#if SQ
13930 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f  LITE_MAX_WORKER_
13940 54 48 52 45 41 44 53 0a 20 20 73 71 6c 69 74 65  THREADS.  sqlite
13950 33 20 2a 64 62 20 3d 20 70 54 61 73 6b 30 2d 3e  3 *db = pTask0->
13960 70 53 6f 72 74 65 72 2d 3e 64 62 3b 0a 23 65 6e  pSorter->db;.#en
13970 64 69 66 0a 0a 20 20 72 63 20 3d 20 76 64 62 65  dif..  rc = vdbe
13980 53 6f 72 74 65 72 4d 65 72 67 65 54 72 65 65 42  SorterMergeTreeB
13990 75 69 6c 64 28 70 53 6f 72 74 65 72 2c 20 26 70  uild(pSorter, &p
139a0 4d 61 69 6e 29 3b 0a 20 20 69 66 28 20 72 63 3d  Main);.  if( rc=
139b0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 23 69  =SQLITE_OK ){.#i
139c0 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52  f SQLITE_MAX_WOR
139d0 4b 45 52 5f 54 48 52 45 41 44 53 0a 20 20 20 20  KER_THREADS.    
139e0 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d  assert( pSorter-
139f0 3e 62 55 73 65 54 68 72 65 61 64 73 3d 3d 30 20  >bUseThreads==0 
13a00 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73  || pSorter->nTas
13a10 6b 3e 31 20 29 3b 0a 20 20 20 20 69 66 28 20 70  k>1 );.    if( p
13a20 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68 72 65  Sorter->bUseThre
13a30 61 64 73 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  ads ){.      int
13a40 20 69 54 61 73 6b 3b 0a 20 20 20 20 20 20 50 6d   iTask;.      Pm
13a50 61 52 65 61 64 65 72 20 2a 70 52 65 61 64 72 3b  aReader *pReadr;
13a60 0a 20 20 20 20 20 20 53 6f 72 74 53 75 62 74 61  .      SortSubta
13a70 73 6b 20 2a 70 4c 61 73 74 20 3d 20 26 70 53 6f  sk *pLast = &pSo
13a80 72 74 65 72 2d 3e 61 54 61 73 6b 5b 70 53 6f 72  rter->aTask[pSor
13a90 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 5d 3b 0a 20  ter->nTask-1];. 
13aa0 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f       rc = vdbeSo
13ab0 72 74 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64 28  rtAllocUnpacked(
13ac0 70 4c 61 73 74 29 3b 0a 20 20 20 20 20 20 69 66  pLast);.      if
13ad0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
13ae0 29 7b 0a 20 20 20 20 20 20 20 20 70 52 65 61 64  ){.        pRead
13af0 72 20 3d 20 28 50 6d 61 52 65 61 64 65 72 2a 29  r = (PmaReader*)
13b00 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f 63 5a  sqlite3DbMallocZ
13b10 65 72 6f 28 64 62 2c 20 73 69 7a 65 6f 66 28 50  ero(db, sizeof(P
13b20 6d 61 52 65 61 64 65 72 29 29 3b 0a 20 20 20 20  maReader));.    
13b30 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 52 65      pSorter->pRe
13b40 61 64 65 72 20 3d 20 70 52 65 61 64 72 3b 0a 20  ader = pReadr;. 
13b50 20 20 20 20 20 20 20 69 66 28 20 70 52 65 61 64         if( pRead
13b60 72 3d 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49  r==0 ) rc = SQLI
13b70 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20  TE_NOMEM;.      
13b80 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  }.      if( rc==
13b90 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
13ba0 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e       rc = vdbeIn
13bb0 63 72 4e 65 77 28 70 4c 61 73 74 2c 20 70 4d 61  crNew(pLast, pMa
13bc0 69 6e 2c 20 26 70 52 65 61 64 72 2d 3e 70 49 6e  in, &pReadr->pIn
13bd0 63 72 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  cr);.        if(
13be0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
13bf0 7b 0a 20 20 20 20 20 20 20 20 20 20 76 64 62 65  {.          vdbe
13c00 49 6e 63 72 53 65 74 54 68 72 65 61 64 73 28 70  IncrSetThreads(p
13c10 52 65 61 64 72 2d 3e 70 49 6e 63 72 29 3b 0a 20  Readr->pIncr);. 
13c20 20 20 20 20 20 20 20 20 20 66 6f 72 28 69 54 61           for(iTa
13c30 73 6b 3d 30 3b 20 69 54 61 73 6b 3c 28 70 53 6f  sk=0; iTask<(pSo
13c40 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 3b 20  rter->nTask-1); 
13c50 69 54 61 73 6b 2b 2b 29 7b 0a 20 20 20 20 20 20  iTask++){.      
13c60 20 20 20 20 20 20 49 6e 63 72 4d 65 72 67 65 72        IncrMerger
13c70 20 2a 70 49 6e 63 72 3b 0a 20 20 20 20 20 20 20   *pIncr;.       
13c80 20 20 20 20 20 69 66 28 20 28 70 49 6e 63 72 20       if( (pIncr 
13c90 3d 20 70 4d 61 69 6e 2d 3e 61 52 65 61 64 72 5b  = pMain->aReadr[
13ca0 69 54 61 73 6b 5d 2e 70 49 6e 63 72 29 20 29 7b  iTask].pIncr) ){
13cb0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 76  .              v
13cc0 64 62 65 49 6e 63 72 53 65 74 54 68 72 65 61 64  dbeIncrSetThread
13cd0 73 28 70 49 6e 63 72 29 3b 0a 20 20 20 20 20 20  s(pIncr);.      
13ce0 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
13cf0 70 49 6e 63 72 2d 3e 70 54 61 73 6b 21 3d 70 4c  pIncr->pTask!=pL
13d00 61 73 74 20 29 3b 0a 20 20 20 20 20 20 20 20 20  ast );.         
13d10 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 7d     }.          }
13d20 0a 20 20 20 20 20 20 20 20 20 20 66 6f 72 28 69  .          for(i
13d30 54 61 73 6b 3d 30 3b 20 72 63 3d 3d 53 51 4c 49  Task=0; rc==SQLI
13d40 54 45 5f 4f 4b 20 26 26 20 69 54 61 73 6b 3c 70  TE_OK && iTask<p
13d50 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3b 20 69  Sorter->nTask; i
13d60 54 61 73 6b 2b 2b 29 7b 0a 20 20 20 20 20 20 20  Task++){.       
13d70 20 20 20 20 20 50 6d 61 52 65 61 64 65 72 20 2a       PmaReader *
13d80 70 20 3d 20 26 70 4d 61 69 6e 2d 3e 61 52 65 61  p = &pMain->aRea
13d90 64 72 5b 69 54 61 73 6b 5d 3b 0a 20 20 20 20 20  dr[iTask];.     
13da0 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70         assert( p
13db0 2d 3e 70 49 6e 63 72 3d 3d 30 20 7c 7c 20 70 2d  ->pIncr==0 || p-
13dc0 3e 70 49 6e 63 72 2d 3e 70 54 61 73 6b 3d 3d 26  >pIncr->pTask==&
13dd0 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 69  pSorter->aTask[i
13de0 54 61 73 6b 5d 20 29 3b 0a 20 20 20 20 20 20 20  Task] );.       
13df0 20 20 20 20 20 69 66 28 20 70 2d 3e 70 49 6e 63       if( p->pInc
13e00 72 20 29 7b 20 0a 20 20 20 20 20 20 20 20 20 20  r ){ .          
13e10 20 20 20 20 69 66 28 20 69 54 61 73 6b 3d 3d 70      if( iTask==p
13e20 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 20  Sorter->nTask-1 
13e30 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ){.             
13e40 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52     rc = vdbePmaR
13e50 65 61 64 65 72 49 6e 63 72 4d 65 72 67 65 49 6e  eaderIncrMergeIn
13e60 69 74 28 70 2c 20 49 4e 43 52 49 4e 49 54 5f 54  it(p, INCRINIT_T
13e70 41 53 4b 29 3b 0a 20 20 20 20 20 20 20 20 20 20  ASK);.          
13e80 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
13e90 20 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20             rc = 
13ea0 76 64 62 65 50 6d 61 52 65 61 64 65 72 42 67 49  vdbePmaReaderBgI
13eb0 6e 63 72 49 6e 69 74 28 70 29 3b 0a 20 20 20 20  ncrInit(p);.    
13ec0 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
13ed0 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
13ee0 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a      }.        }.
13ef0 20 20 20 20 20 20 20 20 70 4d 61 69 6e 20 3d 20          pMain = 
13f00 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  0;.      }.     
13f10 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
13f20 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63  OK ){.        rc
13f30 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65 72   = vdbePmaReader
13f40 49 6e 63 72 4d 65 72 67 65 49 6e 69 74 28 70 52  IncrMergeInit(pR
13f50 65 61 64 72 2c 20 49 4e 43 52 49 4e 49 54 5f 52  eadr, INCRINIT_R
13f60 4f 4f 54 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  OOT);.      }.  
13f70 20 20 7d 65 6c 73 65 0a 23 65 6e 64 69 66 0a 20    }else.#endif. 
13f80 20 20 20 7b 0a 20 20 20 20 20 20 72 63 20 3d 20     {.      rc = 
13f90 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 49  vdbeMergeEngineI
13fa0 6e 69 74 28 70 54 61 73 6b 30 2c 20 70 4d 61 69  nit(pTask0, pMai
13fb0 6e 2c 20 49 4e 43 52 49 4e 49 54 5f 4e 4f 52 4d  n, INCRINIT_NORM
13fc0 41 4c 29 3b 0a 20 20 20 20 20 20 70 53 6f 72 74  AL);.      pSort
13fd0 65 72 2d 3e 70 4d 65 72 67 65 72 20 3d 20 70 4d  er->pMerger = pM
13fe0 61 69 6e 3b 0a 20 20 20 20 20 20 70 4d 61 69 6e  ain;.      pMain
13ff0 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a   = 0;.    }.  }.
14000 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
14010 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 64 62 65  E_OK ){.    vdbe
14020 4d 65 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28  MergeEngineFree(
14030 70 4d 61 69 6e 29 3b 0a 20 20 7d 0a 20 20 72 65  pMain);.  }.  re
14040 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a  turn rc;.}.../*.
14050 2a 2a 20 4f 6e 63 65 20 74 68 65 20 73 6f 72 74  ** Once the sort
14060 65 72 20 68 61 73 20 62 65 65 6e 20 70 6f 70 75  er has been popu
14070 6c 61 74 65 64 20 62 79 20 63 61 6c 6c 73 20 74  lated by calls t
14080 6f 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72  o sqlite3VdbeSor
14090 74 65 72 57 72 69 74 65 2c 0a 2a 2a 20 74 68 69  terWrite,.** thi
140a0 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
140b0 6c 6c 65 64 20 74 6f 20 70 72 65 70 61 72 65 20  lled to prepare 
140c0 66 6f 72 20 69 74 65 72 61 74 69 6e 67 20 74 68  for iterating th
140d0 72 6f 75 67 68 20 74 68 65 20 72 65 63 6f 72 64  rough the record
140e0 73 0a 2a 2a 20 69 6e 20 73 6f 72 74 65 64 20 6f  s.** in sorted o
140f0 72 64 65 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  rder..*/.int sql
14100 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 52 65  ite3VdbeSorterRe
14110 77 69 6e 64 28 63 6f 6e 73 74 20 56 64 62 65 43  wind(const VdbeC
14120 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74  ursor *pCsr, int
14130 20 2a 70 62 45 6f 66 29 7b 0a 20 20 56 64 62 65   *pbEof){.  Vdbe
14140 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20  Sorter *pSorter 
14150 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b  = pCsr->pSorter;
14160 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
14170 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
14180 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
14190 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20  e */..  assert( 
141a0 70 53 6f 72 74 65 72 20 29 3b 0a 0a 20 20 2f 2a  pSorter );..  /*
141b0 20 49 66 20 6e 6f 20 64 61 74 61 20 68 61 73 20   If no data has 
141c0 62 65 65 6e 20 77 72 69 74 74 65 6e 20 74 6f 20  been written to 
141d0 64 69 73 6b 2c 20 74 68 65 6e 20 64 6f 20 6e 6f  disk, then do no
141e0 74 20 64 6f 20 73 6f 20 6e 6f 77 2e 20 49 6e 73  t do so now. Ins
141f0 74 65 61 64 2c 0a 20 20 2a 2a 20 73 6f 72 74 20  tead,.  ** sort 
14200 74 68 65 20 56 64 62 65 53 6f 72 74 65 72 2e 70  the VdbeSorter.p
14210 52 65 63 6f 72 64 20 6c 69 73 74 2e 20 54 68 65  Record list. The
14220 20 76 64 62 65 20 6c 61 79 65 72 20 77 69 6c 6c   vdbe layer will
14230 20 72 65 61 64 20 64 61 74 61 20 64 69 72 65 63   read data direc
14240 74 6c 79 0a 20 20 2a 2a 20 66 72 6f 6d 20 74 68  tly.  ** from th
14250 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74  e in-memory list
14260 2e 20 20 2a 2f 0a 20 20 69 66 28 20 70 53 6f 72  .  */.  if( pSor
14270 74 65 72 2d 3e 62 55 73 65 50 4d 41 3d 3d 30 20  ter->bUsePMA==0 
14280 29 7b 0a 20 20 20 20 69 66 28 20 70 53 6f 72 74  ){.    if( pSort
14290 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 29  er->list.pList )
142a0 7b 0a 20 20 20 20 20 20 2a 70 62 45 6f 66 20 3d  {.      *pbEof =
142b0 20 30 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 76   0;.      rc = v
142c0 64 62 65 53 6f 72 74 65 72 53 6f 72 74 28 26 70  dbeSorterSort(&p
142d0 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 30 5d  Sorter->aTask[0]
142e0 2c 20 26 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74  , &pSorter->list
142f0 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
14300 20 20 20 20 2a 70 62 45 6f 66 20 3d 20 31 3b 0a      *pbEof = 1;.
14310 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75 72 6e      }.    return
14320 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 57   rc;.  }..  /* W
14330 72 69 74 65 20 74 68 65 20 63 75 72 72 65 6e 74  rite the current
14340 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20   in-memory list 
14350 74 6f 20 61 20 50 4d 41 2e 20 57 68 65 6e 20 74  to a PMA. When t
14360 68 65 20 56 64 62 65 53 6f 72 74 65 72 57 72 69  he VdbeSorterWri
14370 74 65 28 29 20 0a 20 20 2a 2a 20 66 75 6e 63 74  te() .  ** funct
14380 69 6f 6e 20 66 6c 75 73 68 65 73 20 74 68 65 20  ion flushes the 
14390 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65 6d 6f  contents of memo
143a0 72 79 20 74 6f 20 64 69 73 6b 2c 20 69 74 20 69  ry to disk, it i
143b0 6d 6d 65 64 69 61 74 65 6c 79 20 61 6c 77 61 79  mmediately alway
143c0 73 0a 20 20 2a 2a 20 63 72 65 61 74 65 73 20 61  s.  ** creates a
143d0 20 6e 65 77 20 6c 69 73 74 20 63 6f 6e 73 69 73   new list consis
143e0 74 69 6e 67 20 6f 66 20 61 20 73 69 6e 67 6c 65  ting of a single
143f0 20 6b 65 79 20 69 6d 6d 65 64 69 61 74 65 6c 79   key immediately
14400 20 61 66 74 65 72 77 61 72 64 73 2e 0a 20 20 2a   afterwards..  *
14410 2a 20 53 6f 20 74 68 65 20 6c 69 73 74 20 69 73  * So the list is
14420 20 6e 65 76 65 72 20 65 6d 70 74 79 20 61 74 20   never empty at 
14430 74 68 69 73 20 70 6f 69 6e 74 2e 20 20 2a 2f 0a  this point.  */.
14440 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65    assert( pSorte
14450 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 29 3b  r->list.pList );
14460 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74  .  rc = vdbeSort
14470 65 72 46 6c 75 73 68 50 4d 41 28 70 53 6f 72 74  erFlushPMA(pSort
14480 65 72 29 3b 0a 0a 20 20 2f 2a 20 4a 6f 69 6e 20  er);..  /* Join 
14490 61 6c 6c 20 74 68 72 65 61 64 73 20 2a 2f 0a 20  all threads */. 
144a0 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
144b0 4a 6f 69 6e 41 6c 6c 28 70 53 6f 72 74 65 72 2c  JoinAll(pSorter,
144c0 20 72 63 29 3b 0a 0a 20 20 76 64 62 65 53 6f 72   rc);..  vdbeSor
144d0 74 65 72 52 65 77 69 6e 64 44 65 62 75 67 28 22  terRewindDebug("
144e0 72 65 77 69 6e 64 22 29 3b 0a 0a 20 20 2f 2a 20  rewind");..  /* 
144f0 41 73 73 75 6d 69 6e 67 20 6e 6f 20 65 72 72 6f  Assuming no erro
14500 72 73 20 68 61 76 65 20 6f 63 63 75 72 72 65 64  rs have occurred
14510 2c 20 73 65 74 20 75 70 20 61 20 6d 65 72 67 65  , set up a merge
14520 72 20 73 74 72 75 63 74 75 72 65 20 74 6f 20 0a  r structure to .
14530 20 20 2a 2a 20 69 6e 63 72 65 6d 65 6e 74 61 6c    ** incremental
14540 6c 79 20 72 65 61 64 20 61 6e 64 20 6d 65 72 67  ly read and merg
14550 65 20 61 6c 6c 20 72 65 6d 61 69 6e 69 6e 67 20  e all remaining 
14560 50 4d 41 73 2e 20 20 2a 2f 0a 20 20 61 73 73 65  PMAs.  */.  asse
14570 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 70 52 65  rt( pSorter->pRe
14580 61 64 65 72 3d 3d 30 20 29 3b 0a 20 20 69 66 28  ader==0 );.  if(
14590 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
145a0 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53  {.    rc = vdbeS
145b0 6f 72 74 65 72 53 65 74 75 70 4d 65 72 67 65 28  orterSetupMerge(
145c0 70 53 6f 72 74 65 72 29 3b 0a 20 20 20 20 2a 70  pSorter);.    *p
145d0 62 45 6f 66 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20  bEof = 0;.  }.. 
145e0 20 76 64 62 65 53 6f 72 74 65 72 52 65 77 69 6e   vdbeSorterRewin
145f0 64 44 65 62 75 67 28 22 72 65 77 69 6e 64 64 6f  dDebug("rewinddo
14600 6e 65 22 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  ne");.  return r
14610 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61  c;.}../*.** Adva
14620 6e 63 65 20 74 6f 20 74 68 65 20 6e 65 78 74 20  nce to the next 
14630 65 6c 65 6d 65 6e 74 20 69 6e 20 74 68 65 20 73  element in the s
14640 6f 72 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71  orter..*/.int sq
14650 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 4e  lite3VdbeSorterN
14660 65 78 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c  ext(sqlite3 *db,
14670 20 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f   const VdbeCurso
14680 72 20 2a 70 43 73 72 2c 20 69 6e 74 20 2a 70 62  r *pCsr, int *pb
14690 45 6f 66 29 7b 0a 20 20 56 64 62 65 53 6f 72 74  Eof){.  VdbeSort
146a0 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43  er *pSorter = pC
146b0 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69  sr->pSorter;.  i
146c0 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
146d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
146e0 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
146f0 0a 0a 20 20 61 73 73 65 72 74 28 20 70 53 6f 72  ..  assert( pSor
14700 74 65 72 2d 3e 62 55 73 65 50 4d 41 20 7c 7c 20  ter->bUsePMA || 
14710 28 70 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65  (pSorter->pReade
14720 72 3d 3d 30 20 26 26 20 70 53 6f 72 74 65 72 2d  r==0 && pSorter-
14730 3e 70 4d 65 72 67 65 72 3d 3d 30 29 20 29 3b 0a  >pMerger==0) );.
14740 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 62    if( pSorter->b
14750 55 73 65 50 4d 41 20 29 7b 0a 20 20 20 20 61 73  UsePMA ){.    as
14760 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 70  sert( pSorter->p
14770 52 65 61 64 65 72 3d 3d 30 20 7c 7c 20 70 53 6f  Reader==0 || pSo
14780 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 3d 3d 30  rter->pMerger==0
14790 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20   );.    assert( 
147a0 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68 72  pSorter->bUseThr
147b0 65 61 64 73 3d 3d 30 20 7c 7c 20 70 53 6f 72 74  eads==0 || pSort
147c0 65 72 2d 3e 70 52 65 61 64 65 72 20 29 3b 0a 20  er->pReader );. 
147d0 20 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74     assert( pSort
147e0 65 72 2d 3e 62 55 73 65 54 68 72 65 61 64 73 3d  er->bUseThreads=
147f0 3d 31 20 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 70  =1 || pSorter->p
14800 4d 65 72 67 65 72 20 29 3b 0a 23 69 66 20 53 51  Merger );.#if SQ
14810 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f  LITE_MAX_WORKER_
14820 54 48 52 45 41 44 53 3e 30 0a 20 20 20 20 69 66  THREADS>0.    if
14830 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54  ( pSorter->bUseT
14840 68 72 65 61 64 73 20 29 7b 0a 20 20 20 20 20 20  hreads ){.      
14850 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64  rc = vdbePmaRead
14860 65 72 4e 65 78 74 28 70 53 6f 72 74 65 72 2d 3e  erNext(pSorter->
14870 70 52 65 61 64 65 72 29 3b 0a 20 20 20 20 20 20  pReader);.      
14880 2a 70 62 45 6f 66 20 3d 20 28 70 53 6f 72 74 65  *pbEof = (pSorte
14890 72 2d 3e 70 52 65 61 64 65 72 2d 3e 70 46 64 3d  r->pReader->pFd=
148a0 3d 30 29 3b 0a 20 20 20 20 7d 65 6c 73 65 0a 23  =0);.    }else.#
148b0 65 6e 64 69 66 0a 20 20 20 20 2f 2a 69 66 28 20  endif.    /*if( 
148c0 21 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68  !pSorter->bUseTh
148d0 72 65 61 64 73 20 29 2a 2f 20 7b 0a 20 20 20 20  reads )*/ {.    
148e0 20 20 72 63 20 3d 20 76 64 62 65 4d 65 72 67 65    rc = vdbeMerge
148f0 45 6e 67 69 6e 65 53 74 65 70 28 26 70 53 6f 72  EngineStep(&pSor
14900 74 65 72 2d 3e 61 54 61 73 6b 5b 30 5d 2c 20 70  ter->aTask[0], p
14910 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 2c  Sorter->pMerger,
14920 20 70 62 45 6f 66 29 3b 0a 20 20 20 20 7d 0a 20   pbEof);.    }. 
14930 20 7d 65 6c 73 65 7b 0a 20 20 20 20 53 6f 72 74   }else{.    Sort
14940 65 72 52 65 63 6f 72 64 20 2a 70 46 72 65 65 20  erRecord *pFree 
14950 3d 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e  = pSorter->list.
14960 70 4c 69 73 74 3b 0a 20 20 20 20 70 53 6f 72 74  pList;.    pSort
14970 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d  er->list.pList =
14980 20 70 46 72 65 65 2d 3e 75 2e 70 4e 65 78 74 3b   pFree->u.pNext;
14990 0a 20 20 20 20 70 46 72 65 65 2d 3e 75 2e 70 4e  .    pFree->u.pN
149a0 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 69 66 28  ext = 0;.    if(
149b0 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61   pSorter->list.a
149c0 4d 65 6d 6f 72 79 3d 3d 30 20 29 20 76 64 62 65  Memory==0 ) vdbe
149d0 53 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65 65  SorterRecordFree
149e0 28 64 62 2c 20 70 46 72 65 65 29 3b 0a 20 20 20  (db, pFree);.   
149f0 20 2a 70 62 45 6f 66 20 3d 20 21 70 53 6f 72 74   *pbEof = !pSort
14a00 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 3b 0a  er->list.pList;.
14a10 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
14a20 4f 4b 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  OK;.  }.  return
14a30 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65   rc;.}../*.** Re
14a40 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74  turn a pointer t
14a50 6f 20 61 20 62 75 66 66 65 72 20 6f 77 6e 65 64  o a buffer owned
14a60 20 62 79 20 74 68 65 20 73 6f 72 74 65 72 20 74   by the sorter t
14a70 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  hat contains the
14a80 20 0a 2a 2a 20 63 75 72 72 65 6e 74 20 6b 65 79   .** current key
14a90 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
14aa0 20 2a 76 64 62 65 53 6f 72 74 65 72 52 6f 77 6b   *vdbeSorterRowk
14ab0 65 79 28 0a 20 20 63 6f 6e 73 74 20 56 64 62 65  ey(.  const Vdbe
14ac0 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 2c  Sorter *pSorter,
14ad0 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20        /* Sorter 
14ae0 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e 74 20  object */.  int 
14af0 2a 70 6e 4b 65 79 20 20 20 20 20 20 20 20 20 20  *pnKey          
14b00 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
14b10 55 54 3a 20 53 69 7a 65 20 6f 66 20 63 75 72 72  UT: Size of curr
14b20 65 6e 74 20 6b 65 79 20 69 6e 20 62 79 74 65 73  ent key in bytes
14b30 20 2a 2f 0a 29 7b 0a 20 20 76 6f 69 64 20 2a 70   */.){.  void *p
14b40 4b 65 79 3b 0a 20 20 69 66 28 20 70 53 6f 72 74  Key;.  if( pSort
14b50 65 72 2d 3e 62 55 73 65 50 4d 41 20 29 7b 0a 20  er->bUsePMA ){. 
14b60 20 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70 52     PmaReader *pR
14b70 65 61 64 65 72 3b 0a 23 69 66 20 53 51 4c 49 54  eader;.#if SQLIT
14b80 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52  E_MAX_WORKER_THR
14b90 45 41 44 53 3e 30 0a 20 20 20 20 69 66 28 20 70  EADS>0.    if( p
14ba0 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68 72 65  Sorter->bUseThre
14bb0 61 64 73 20 29 7b 0a 20 20 20 20 20 20 70 52 65  ads ){.      pRe
14bc0 61 64 65 72 20 3d 20 70 53 6f 72 74 65 72 2d 3e  ader = pSorter->
14bd0 70 52 65 61 64 65 72 3b 0a 20 20 20 20 7d 65 6c  pReader;.    }el
14be0 73 65 0a 23 65 6e 64 69 66 0a 20 20 20 20 2f 2a  se.#endif.    /*
14bf0 69 66 28 20 21 70 53 6f 72 74 65 72 2d 3e 62 55  if( !pSorter->bU
14c00 73 65 54 68 72 65 61 64 73 20 29 2a 2f 7b 0a 20  seThreads )*/{. 
14c10 20 20 20 20 20 70 52 65 61 64 65 72 20 3d 20 26       pReader = &
14c20 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72  pSorter->pMerger
14c30 2d 3e 61 52 65 61 64 72 5b 70 53 6f 72 74 65 72  ->aReadr[pSorter
14c40 2d 3e 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65  ->pMerger->aTree
14c50 5b 31 5d 5d 3b 0a 20 20 20 20 7d 0a 20 20 20 20  [1]];.    }.    
14c60 2a 70 6e 4b 65 79 20 3d 20 70 52 65 61 64 65 72  *pnKey = pReader
14c70 2d 3e 6e 4b 65 79 3b 0a 20 20 20 20 70 4b 65 79  ->nKey;.    pKey
14c80 20 3d 20 70 52 65 61 64 65 72 2d 3e 61 4b 65 79   = pReader->aKey
14c90 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2a  ;.  }else{.    *
14ca0 70 6e 4b 65 79 20 3d 20 70 53 6f 72 74 65 72 2d  pnKey = pSorter-
14cb0 3e 6c 69 73 74 2e 70 4c 69 73 74 2d 3e 6e 56 61  >list.pList->nVa
14cc0 6c 3b 0a 20 20 20 20 70 4b 65 79 20 3d 20 53 52  l;.    pKey = SR
14cd0 56 41 4c 28 70 53 6f 72 74 65 72 2d 3e 6c 69 73  VAL(pSorter->lis
14ce0 74 2e 70 4c 69 73 74 29 3b 0a 20 20 7d 0a 20 20  t.pList);.  }.  
14cf0 72 65 74 75 72 6e 20 70 4b 65 79 3b 0a 7d 0a 0a  return pKey;.}..
14d00 2f 2a 0a 2a 2a 20 43 6f 70 79 20 74 68 65 20 63  /*.** Copy the c
14d10 75 72 72 65 6e 74 20 73 6f 72 74 65 72 20 6b 65  urrent sorter ke
14d20 79 20 69 6e 74 6f 20 74 68 65 20 6d 65 6d 6f 72  y into the memor
14d30 79 20 63 65 6c 6c 20 70 4f 75 74 2e 0a 2a 2f 0a  y cell pOut..*/.
14d40 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65 53  int sqlite3VdbeS
14d50 6f 72 74 65 72 52 6f 77 6b 65 79 28 63 6f 6e 73  orterRowkey(cons
14d60 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43  t VdbeCursor *pC
14d70 73 72 2c 20 4d 65 6d 20 2a 70 4f 75 74 29 7b 0a  sr, Mem *pOut){.
14d80 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
14d90 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53  orter = pCsr->pS
14da0 6f 72 74 65 72 3b 0a 20 20 76 6f 69 64 20 2a 70  orter;.  void *p
14db0 4b 65 79 3b 20 69 6e 74 20 6e 4b 65 79 3b 20 20  Key; int nKey;  
14dc0 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74           /* Sort
14dd0 65 72 20 6b 65 79 20 74 6f 20 63 6f 70 79 20 69  er key to copy i
14de0 6e 74 6f 20 70 4f 75 74 20 2a 2f 0a 0a 20 20 70  nto pOut */..  p
14df0 4b 65 79 20 3d 20 76 64 62 65 53 6f 72 74 65 72  Key = vdbeSorter
14e00 52 6f 77 6b 65 79 28 70 53 6f 72 74 65 72 2c 20  Rowkey(pSorter, 
14e10 26 6e 4b 65 79 29 3b 0a 20 20 69 66 28 20 73 71  &nKey);.  if( sq
14e20 6c 69 74 65 33 56 64 62 65 4d 65 6d 47 72 6f 77  lite3VdbeMemGrow
14e30 28 70 4f 75 74 2c 20 6e 4b 65 79 2c 20 30 29 20  (pOut, nKey, 0) 
14e40 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
14e50 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a  LITE_NOMEM;.  }.
14e60 20 20 70 4f 75 74 2d 3e 6e 20 3d 20 6e 4b 65 79    pOut->n = nKey
14e70 3b 0a 20 20 4d 65 6d 53 65 74 54 79 70 65 46 6c  ;.  MemSetTypeFl
14e80 61 67 28 70 4f 75 74 2c 20 4d 45 4d 5f 42 6c 6f  ag(pOut, MEM_Blo
14e90 62 29 3b 0a 20 20 6d 65 6d 63 70 79 28 70 4f 75  b);.  memcpy(pOu
14ea0 74 2d 3e 7a 2c 20 70 4b 65 79 2c 20 6e 4b 65 79  t->z, pKey, nKey
14eb0 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  );..  return SQL
14ec0 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
14ed0 20 43 6f 6d 70 61 72 65 20 74 68 65 20 6b 65 79   Compare the key
14ee0 20 69 6e 20 6d 65 6d 6f 72 79 20 63 65 6c 6c 20   in memory cell 
14ef0 70 56 61 6c 20 77 69 74 68 20 74 68 65 20 6b 65  pVal with the ke
14f00 79 20 74 68 61 74 20 74 68 65 20 73 6f 72 74 65  y that the sorte
14f10 72 20 63 75 72 73 6f 72 0a 2a 2a 20 70 61 73 73  r cursor.** pass
14f20 65 64 20 61 73 20 74 68 65 20 66 69 72 73 74 20  ed as the first 
14f30 61 72 67 75 6d 65 6e 74 20 63 75 72 72 65 6e 74  argument current
14f40 6c 79 20 70 6f 69 6e 74 73 20 74 6f 2e 20 46 6f  ly points to. Fo
14f50 72 20 74 68 65 20 70 75 72 70 6f 73 65 73 20 6f  r the purposes o
14f60 66 0a 2a 2a 20 74 68 65 20 63 6f 6d 70 61 72 69  f.** the compari
14f70 73 6f 6e 2c 20 69 67 6e 6f 72 65 20 74 68 65 20  son, ignore the 
14f80 72 6f 77 69 64 20 66 69 65 6c 64 20 61 74 20 74  rowid field at t
14f90 68 65 20 65 6e 64 20 6f 66 20 65 61 63 68 20 72  he end of each r
14fa0 65 63 6f 72 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  ecord..**.** If 
14fb0 74 68 65 20 73 6f 72 74 65 72 20 63 75 72 73 6f  the sorter curso
14fc0 72 20 6b 65 79 20 63 6f 6e 74 61 69 6e 73 20 61  r key contains a
14fd0 6e 79 20 4e 55 4c 4c 20 76 61 6c 75 65 73 2c 20  ny NULL values, 
14fe0 63 6f 6e 73 69 64 65 72 20 69 74 20 74 6f 20 62  consider it to b
14ff0 65 0a 2a 2a 20 6c 65 73 73 20 74 68 61 6e 20 70  e.** less than p
15000 56 61 6c 2e 20 45 76 65 6e 20 69 66 20 70 56 61  Val. Even if pVa
15010 6c 20 61 6c 73 6f 20 63 6f 6e 74 61 69 6e 73 20  l also contains 
15020 4e 55 4c 4c 20 76 61 6c 75 65 73 2e 0a 2a 2a 0a  NULL values..**.
15030 2a 2a 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f  ** If an error o
15040 63 63 75 72 73 2c 20 72 65 74 75 72 6e 20 61 6e  ccurs, return an
15050 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
15060 64 65 20 28 69 2e 65 2e 20 53 51 4c 49 54 45 5f  de (i.e. SQLITE_
15070 4e 4f 4d 45 4d 29 2e 0a 2a 2a 20 4f 74 68 65 72  NOMEM)..** Other
15080 77 69 73 65 2c 20 73 65 74 20 2a 70 52 65 73 20  wise, set *pRes 
15090 74 6f 20 61 20 6e 65 67 61 74 69 76 65 2c 20 7a  to a negative, z
150a0 65 72 6f 20 6f 72 20 70 6f 73 69 74 69 76 65 20  ero or positive 
150b0 76 61 6c 75 65 20 69 66 20 74 68 65 0a 2a 2a 20  value if the.** 
150c0 6b 65 79 20 69 6e 20 70 56 61 6c 20 69 73 20 73  key in pVal is s
150d0 6d 61 6c 6c 65 72 20 74 68 61 6e 2c 20 65 71 75  maller than, equ
150e0 61 6c 20 74 6f 20 6f 72 20 6c 61 72 67 65 72 20  al to or larger 
150f0 74 68 61 6e 20 74 68 65 20 63 75 72 72 65 6e 74  than the current
15100 20 73 6f 72 74 65 72 0a 2a 2a 20 6b 65 79 2e 0a   sorter.** key..
15110 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  **.** This routi
15120 6e 65 20 66 6f 72 6d 73 20 74 68 65 20 63 6f 72  ne forms the cor
15130 65 20 6f 66 20 74 68 65 20 4f 50 5f 53 6f 72 74  e of the OP_Sort
15140 65 72 43 6f 6d 70 61 72 65 20 6f 70 63 6f 64 65  erCompare opcode
15150 2c 20 77 68 69 63 68 20 69 6e 0a 2a 2a 20 74 75  , which in.** tu
15160 72 6e 20 69 73 20 75 73 65 64 20 74 6f 20 76 65  rn is used to ve
15170 72 69 66 79 20 75 6e 69 71 75 65 6e 65 73 73 20  rify uniqueness 
15180 77 68 65 6e 20 63 6f 6e 73 74 72 75 63 74 69 6e  when constructin
15190 67 20 61 20 55 4e 49 51 55 45 20 49 4e 44 45 58  g a UNIQUE INDEX
151a0 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
151b0 56 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72  VdbeSorterCompar
151c0 65 28 0a 20 20 63 6f 6e 73 74 20 56 64 62 65 43  e(.  const VdbeC
151d0 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 20 20 20  ursor *pCsr,    
151e0 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 63       /* Sorter c
151f0 75 72 73 6f 72 20 2a 2f 0a 20 20 4d 65 6d 20 2a  ursor */.  Mem *
15200 70 56 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20  pVal,           
15210 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61             /* Va
15220 6c 75 65 20 74 6f 20 63 6f 6d 70 61 72 65 20 74  lue to compare t
15230 6f 20 63 75 72 72 65 6e 74 20 73 6f 72 74 65 72  o current sorter
15240 20 6b 65 79 20 2a 2f 0a 20 20 69 6e 74 20 6e 49   key */.  int nI
15250 67 6e 6f 72 65 2c 20 20 20 20 20 20 20 20 20 20  gnore,          
15260 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 67 6e            /* Ign
15270 6f 72 65 20 74 68 69 73 20 6d 61 6e 79 20 66 69  ore this many fi
15280 65 6c 64 73 20 61 74 20 74 68 65 20 65 6e 64 20  elds at the end 
15290 2a 2f 0a 20 20 69 6e 74 20 2a 70 52 65 73 20 20  */.  int *pRes  
152a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
152b0 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 52 65 73       /* OUT: Res
152c0 75 6c 74 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f  ult of compariso
152d0 6e 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65 53 6f  n */.){.  VdbeSo
152e0 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20  rter *pSorter = 
152f0 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20  pCsr->pSorter;. 
15300 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20   UnpackedRecord 
15310 2a 72 32 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70  *r2 = pSorter->p
15320 55 6e 70 61 63 6b 65 64 3b 0a 20 20 4b 65 79 49  Unpacked;.  KeyI
15330 6e 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 20 3d 20  nfo *pKeyInfo = 
15340 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 3b 0a  pCsr->pKeyInfo;.
15350 20 20 69 6e 74 20 69 3b 0a 20 20 76 6f 69 64 20    int i;.  void 
15360 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b 65 79 3b  *pKey; int nKey;
15370 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f             /* So
15380 72 74 65 72 20 6b 65 79 20 74 6f 20 63 6f 6d 70  rter key to comp
15390 61 72 65 20 70 56 61 6c 20 77 69 74 68 20 2a 2f  are pVal with */
153a0 0a 0a 20 20 69 66 28 20 72 32 3d 3d 30 20 29 7b  ..  if( r2==0 ){
153b0 0a 20 20 20 20 63 68 61 72 20 2a 70 3b 0a 20 20  .    char *p;.  
153c0 20 20 72 32 20 3d 20 70 53 6f 72 74 65 72 2d 3e    r2 = pSorter->
153d0 70 55 6e 70 61 63 6b 65 64 20 3d 20 73 71 6c 69  pUnpacked = sqli
153e0 74 65 33 56 64 62 65 41 6c 6c 6f 63 55 6e 70 61  te3VdbeAllocUnpa
153f0 63 6b 65 64 52 65 63 6f 72 64 28 70 4b 65 79 49  ckedRecord(pKeyI
15400 6e 66 6f 2c 30 2c 30 2c 26 70 29 3b 0a 20 20 20  nfo,0,0,&p);.   
15410 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72   assert( pSorter
15420 2d 3e 70 55 6e 70 61 63 6b 65 64 3d 3d 28 55 6e  ->pUnpacked==(Un
15430 70 61 63 6b 65 64 52 65 63 6f 72 64 2a 29 70 20  packedRecord*)p 
15440 29 3b 0a 20 20 20 20 69 66 28 20 72 32 3d 3d 30  );.    if( r2==0
15450 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
15460 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 72 32 2d 3e  _NOMEM;.    r2->
15470 6e 46 69 65 6c 64 20 3d 20 70 4b 65 79 49 6e 66  nField = pKeyInf
15480 6f 2d 3e 6e 46 69 65 6c 64 2d 6e 49 67 6e 6f 72  o->nField-nIgnor
15490 65 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28  e;.  }.  assert(
154a0 20 72 32 2d 3e 6e 46 69 65 6c 64 3e 3d 70 4b 65   r2->nField>=pKe
154b0 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64 2d 6e 49  yInfo->nField-nI
154c0 67 6e 6f 72 65 20 29 3b 0a 0a 20 20 70 4b 65 79  gnore );..  pKey
154d0 20 3d 20 76 64 62 65 53 6f 72 74 65 72 52 6f 77   = vdbeSorterRow
154e0 6b 65 79 28 70 53 6f 72 74 65 72 2c 20 26 6e 4b  key(pSorter, &nK
154f0 65 79 29 3b 0a 20 20 73 71 6c 69 74 65 33 56 64  ey);.  sqlite3Vd
15500 62 65 52 65 63 6f 72 64 55 6e 70 61 63 6b 28 70  beRecordUnpack(p
15510 4b 65 79 49 6e 66 6f 2c 20 6e 4b 65 79 2c 20 70  KeyInfo, nKey, p
15520 4b 65 79 2c 20 72 32 29 3b 0a 20 20 66 6f 72 28  Key, r2);.  for(
15530 69 3d 30 3b 20 69 3c 72 32 2d 3e 6e 46 69 65 6c  i=0; i<r2->nFiel
15540 64 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  d; i++){.    if(
15550 20 72 32 2d 3e 61 4d 65 6d 5b 69 5d 2e 66 6c 61   r2->aMem[i].fla
15560 67 73 20 26 20 4d 45 4d 5f 4e 75 6c 6c 20 29 7b  gs & MEM_Null ){
15570 0a 20 20 20 20 20 20 2a 70 52 65 73 20 3d 20 2d  .      *pRes = -
15580 31 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  1;.      return 
15590 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d  SQLITE_OK;.    }
155a0 0a 20 20 7d 0a 0a 20 20 2a 70 52 65 73 20 3d 20  .  }..  *pRes = 
155b0 73 71 6c 69 74 65 33 56 64 62 65 52 65 63 6f 72  sqlite3VdbeRecor
155c0 64 43 6f 6d 70 61 72 65 28 70 56 61 6c 2d 3e 6e  dCompare(pVal->n
155d0 2c 20 70 56 61 6c 2d 3e 7a 2c 20 72 32 2c 20 30  , pVal->z, r2, 0
155e0 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  );.  return SQLI
155f0 54 45 5f 4f 4b 3b 0a 7d 0a                       TE_OK;.}.