/ Hex Artifact Content
Login

Artifact 2e7f683464fd5db3be4beaa1ff2d39e24fcb64b8:


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 22 50 52 41 47 4d 41 20 74 68  ng.** "PRAGMA th
13f0: 72 65 61 64 73 3d 4e 22 20 77 69 74 68 20 73 6f  reads=N" with so
1400: 6d 65 20 76 61 6c 75 65 20 6f 66 20 4e 20 67 72  me value of N gr
1410: 65 61 74 65 72 20 74 68 61 6e 20 30 2e 0a 2a 2a  eater than 0..**
1420: 0a 2a 2a 20 57 68 65 6e 20 52 65 77 69 6e 64 28  .** When Rewind(
1430: 29 20 69 73 20 63 61 6c 6c 65 64 2c 20 61 6e 79  ) is called, any
1440: 20 64 61 74 61 20 72 65 6d 61 69 6e 69 6e 67 20   data remaining 
1450: 69 6e 20 6d 65 6d 6f 72 79 20 69 73 20 66 6c 75  in memory is flu
1460: 73 68 65 64 20 74 6f 20 61 20 0a 2a 2a 20 66 69  shed to a .** fi
1470: 6e 61 6c 20 50 4d 41 2e 20 53 6f 20 61 74 20 74  nal PMA. So at t
1480: 68 69 73 20 70 6f 69 6e 74 20 74 68 65 20 64 61  his point the da
1490: 74 61 20 69 73 20 73 74 6f 72 65 64 20 69 6e 20  ta is stored in 
14a0: 73 6f 6d 65 20 6e 75 6d 62 65 72 20 6f 66 20 73  some number of s
14b0: 6f 72 74 65 64 0a 2a 2a 20 50 4d 41 73 20 77 69  orted.** PMAs wi
14c0: 74 68 69 6e 20 74 65 6d 70 6f 72 61 72 79 20 66  thin temporary f
14d0: 69 6c 65 73 20 6f 6e 20 64 69 73 6b 2e 0a 2a 2a  iles on disk..**
14e0: 0a 2a 2a 20 49 66 20 74 68 65 72 65 20 61 72 65  .** If there are
14f0: 20 66 65 77 65 72 20 74 68 61 6e 20 53 4f 52 54   fewer than SORT
1500: 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55  ER_MAX_MERGE_COU
1510: 4e 54 20 50 4d 41 73 20 69 6e 20 74 6f 74 61 6c  NT PMAs in total
1520: 20 61 6e 64 20 74 68 65 0a 2a 2a 20 73 6f 72 74   and the.** sort
1530: 65 72 20 69 73 20 72 75 6e 6e 69 6e 67 20 69 6e  er is running in
1540: 20 73 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64   single-threaded
1550: 20 6d 6f 64 65 2c 20 74 68 65 6e 20 74 68 65 73   mode, then thes
1560: 65 20 50 4d 41 73 20 61 72 65 20 6d 65 72 67 65  e PMAs are merge
1570: 64 0a 2a 2a 20 69 6e 63 72 65 6d 65 6e 74 61 6c  d.** incremental
1580: 6c 79 20 61 73 20 6b 65 79 73 20 61 72 65 20 72  ly as keys are r
1590: 65 74 72 65 69 76 65 64 20 66 72 6f 6d 20 74 68  etreived from th
15a0: 65 20 73 6f 72 74 65 72 20 62 79 20 74 68 65 20  e sorter by the 
15b0: 56 44 42 45 2e 20 20 54 68 65 0a 2a 2a 20 4d 65  VDBE.  The.** Me
15c0: 72 67 65 45 6e 67 69 6e 65 20 6f 62 6a 65 63 74  rgeEngine object
15d0: 2c 20 64 65 73 63 72 69 62 65 64 20 69 6e 20 66  , described in f
15e0: 75 72 74 68 65 72 20 64 65 74 61 69 6c 20 62 65  urther detail be
15f0: 6c 6f 77 2c 20 70 65 72 66 6f 72 6d 73 20 74 68  low, performs th
1600: 69 73 0a 2a 2a 20 6d 65 72 67 65 2e 0a 2a 2a 0a  is.** merge..**.
1610: 2a 2a 20 4f 72 2c 20 69 66 20 72 75 6e 6e 69 6e  ** Or, if runnin
1620: 67 20 69 6e 20 6d 75 6c 74 69 2d 74 68 72 65 61  g in multi-threa
1630: 64 65 64 20 6d 6f 64 65 2c 20 74 68 65 6e 20 61  ded mode, then a
1640: 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65   background thre
1650: 61 64 20 69 73 0a 2a 2a 20 6c 61 75 6e 63 68 65  ad is.** launche
1660: 64 20 74 6f 20 6d 65 72 67 65 20 74 68 65 20 65  d to merge the e
1670: 78 69 73 74 69 6e 67 20 50 4d 41 73 2e 20 4f 6e  xisting PMAs. On
1680: 63 65 20 74 68 65 20 62 61 63 6b 67 72 6f 75 6e  ce the backgroun
1690: 64 20 74 68 72 65 61 64 20 68 61 73 0a 2a 2a 20  d thread has.** 
16a0: 6d 65 72 67 65 64 20 54 20 62 79 74 65 73 20 6f  merged T bytes o
16b0: 66 20 64 61 74 61 20 69 6e 74 6f 20 61 20 73 69  f data into a si
16c0: 6e 67 6c 65 20 73 6f 72 74 65 64 20 50 4d 41 2c  ngle sorted PMA,
16d0: 20 74 68 65 20 6d 61 69 6e 20 74 68 72 65 61 64   the main thread
16e0: 20 0a 2a 2a 20 62 65 67 69 6e 73 20 72 65 61 64   .** begins read
16f0: 69 6e 67 20 6b 65 79 73 20 66 72 6f 6d 20 74 68  ing keys from th
1700: 61 74 20 50 4d 41 20 77 68 69 6c 65 20 74 68 65  at PMA while the
1710: 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65   background thre
1720: 61 64 20 70 72 6f 63 65 65 64 73 0a 2a 2a 20 77  ad proceeds.** w
1730: 69 74 68 20 6d 65 72 67 69 6e 67 20 74 68 65 20  ith merging the 
1740: 6e 65 78 74 20 54 20 62 79 74 65 73 20 6f 66 20  next T bytes of 
1750: 64 61 74 61 2e 20 41 6e 64 20 73 6f 20 6f 6e 2e  data. And so on.
1760: 0a 2a 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 65 72  .**.** Parameter
1770: 20 54 20 69 73 20 73 65 74 20 74 6f 20 68 61 6c   T is set to hal
1780: 66 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74  f the value of t
1790: 68 65 20 6d 65 6d 6f 72 79 20 74 68 72 65 73 68  he memory thresh
17a0: 6f 6c 64 20 75 73 65 64 20 0a 2a 2a 20 62 79 20  old used .** by 
17b0: 57 72 69 74 65 28 29 20 61 62 6f 76 65 20 74 6f  Write() above to
17c0: 20 64 65 74 65 72 6d 69 6e 65 20 77 68 65 6e 20   determine when 
17d0: 74 6f 20 63 72 65 61 74 65 20 61 20 6e 65 77 20  to create a new 
17e0: 50 4d 41 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  PMA..**.** If th
17f0: 65 72 65 20 61 72 65 20 6d 6f 72 65 20 74 68 61  ere are more tha
1800: 6e 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52  n SORTER_MAX_MER
1810: 47 45 5f 43 4f 55 4e 54 20 50 4d 41 73 20 69 6e  GE_COUNT PMAs in
1820: 20 74 6f 74 61 6c 20 77 68 65 6e 20 0a 2a 2a 20   total when .** 
1830: 52 65 77 69 6e 64 28 29 20 69 73 20 63 61 6c 6c  Rewind() is call
1840: 65 64 2c 20 74 68 65 6e 20 61 20 68 69 65 72 61  ed, then a hiera
1850: 72 63 68 79 20 6f 66 20 69 6e 63 72 65 6d 65 6e  rchy of incremen
1860: 74 61 6c 2d 6d 65 72 67 65 73 20 69 73 20 75 73  tal-merges is us
1870: 65 64 2e 20 0a 2a 2a 20 46 69 72 73 74 2c 20 54  ed. .** First, T
1880: 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 66   bytes of data f
1890: 72 6f 6d 20 74 68 65 20 66 69 72 73 74 20 53 4f  rom the first SO
18a0: 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
18b0: 4f 55 4e 54 20 50 4d 41 73 20 6f 6e 20 0a 2a 2a  OUNT PMAs on .**
18c0: 20 64 69 73 6b 20 61 72 65 20 6d 65 72 67 65 64   disk are merged
18d0: 20 74 6f 67 65 74 68 65 72 2e 20 54 68 65 6e 20   together. Then 
18e0: 54 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20  T bytes of data 
18f0: 66 72 6f 6d 20 74 68 65 20 73 65 63 6f 6e 64 20  from the second 
1900: 73 65 74 2c 20 61 6e 64 0a 2a 2a 20 73 6f 20 6f  set, and.** so o
1910: 6e 2c 20 73 75 63 68 20 74 68 61 74 20 6e 6f 20  n, such that no 
1920: 6f 70 65 72 61 74 69 6f 6e 20 65 76 65 72 20 6d  operation ever m
1930: 65 72 67 65 73 20 6d 6f 72 65 20 74 68 61 6e 20  erges more than 
1940: 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45  SORTER_MAX_MERGE
1950: 5f 43 4f 55 4e 54 0a 2a 2a 20 50 4d 41 73 20 61  _COUNT.** PMAs a
1960: 74 20 61 20 74 69 6d 65 2e 20 54 68 69 73 20 64  t a time. This d
1970: 6f 6e 65 20 69 73 20 74 6f 20 69 6d 70 72 6f 76  one is to improv
1980: 65 20 6c 6f 63 61 6c 69 74 79 2e 0a 2a 2a 0a 2a  e locality..**.*
1990: 2a 20 49 66 20 72 75 6e 6e 69 6e 67 20 69 6e 20  * If running in 
19a0: 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20 6d  multi-threaded m
19b0: 6f 64 65 20 61 6e 64 20 74 68 65 72 65 20 61 72  ode and there ar
19c0: 65 20 6d 6f 72 65 20 74 68 61 6e 0a 2a 2a 20 53  e more than.** S
19d0: 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f  ORTER_MAX_MERGE_
19e0: 43 4f 55 4e 54 20 50 4d 41 73 20 6f 6e 20 64 69  COUNT PMAs on di
19f0: 73 6b 20 77 68 65 6e 20 52 65 77 69 6e 64 28 29  sk when Rewind()
1a00: 20 69 73 20 63 61 6c 6c 65 64 2c 20 74 68 65 6e   is called, then
1a10: 20 6d 6f 72 65 0a 2a 2a 20 74 68 61 6e 20 6f 6e   more.** than on
1a20: 65 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  e background thr
1a30: 65 61 64 20 6d 61 79 20 62 65 20 63 72 65 61 74  ead may be creat
1a40: 65 64 2e 20 53 70 65 63 69 66 69 63 61 6c 6c 79  ed. Specifically
1a50: 2c 20 74 68 65 72 65 20 6d 61 79 20 62 65 0a 2a  , there may be.*
1a60: 2a 20 6f 6e 65 20 62 61 63 6b 67 72 6f 75 6e 64  * one background
1a70: 20 74 68 72 65 61 64 20 66 6f 72 20 65 61 63 68   thread for each
1a80: 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 20   temporary file 
1a90: 6f 6e 20 64 69 73 6b 2c 20 61 6e 64 20 6f 6e 65  on disk, and one
1aa0: 20 62 61 63 6b 67 72 6f 75 6e 64 0a 2a 2a 20 74   background.** t
1ab0: 68 72 65 61 64 20 74 6f 20 6d 65 72 67 65 20 74  hread to merge t
1ac0: 68 65 20 6f 75 74 70 75 74 20 6f 66 20 65 61 63  he output of eac
1ad0: 68 20 6f 66 20 74 68 65 20 6f 74 68 65 72 73 20  h of the others 
1ae0: 74 6f 20 61 20 73 69 6e 67 6c 65 20 50 4d 41 20  to a single PMA 
1af0: 66 6f 72 0a 2a 2a 20 74 68 65 20 6d 61 69 6e 20  for.** the main 
1b00: 74 68 72 65 61 64 20 74 6f 20 72 65 61 64 20 66  thread to read f
1b10: 72 6f 6d 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65  rom..*/.#include
1b20: 20 22 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a 23   "sqliteInt.h".#
1b30: 69 6e 63 6c 75 64 65 20 22 76 64 62 65 49 6e 74  include "vdbeInt
1b40: 2e 68 22 0a 0a 2f 2a 20 0a 2a 2a 20 49 66 20 53  .h"../* .** If S
1b50: 51 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f 52 54  QLITE_DEBUG_SORT
1b60: 45 52 5f 54 48 52 45 41 44 53 20 69 73 20 64 65  ER_THREADS is de
1b70: 66 69 6e 65 64 2c 20 74 68 69 73 20 6d 6f 64 75  fined, this modu
1b80: 6c 65 20 6f 75 74 70 75 74 73 20 76 61 72 69 6f  le outputs vario
1b90: 75 73 0a 2a 2a 20 6d 65 73 73 61 67 65 73 20 74  us.** messages t
1ba0: 6f 20 73 74 64 65 72 72 20 74 68 61 74 20 6d 61  o stderr that ma
1bb0: 79 20 62 65 20 68 65 6c 70 66 75 6c 20 69 6e 20  y be helpful in 
1bc0: 75 6e 64 65 72 73 74 61 6e 64 69 6e 67 20 74 68  understanding th
1bd0: 65 20 70 65 72 66 6f 72 6d 61 6e 63 65 0a 2a 2a  e performance.**
1be0: 20 63 68 61 72 61 63 74 65 72 69 73 74 69 63 73   characteristics
1bf0: 20 6f 66 20 74 68 65 20 73 6f 72 74 65 72 20 69   of the sorter i
1c00: 6e 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64  n multi-threaded
1c10: 20 6d 6f 64 65 2e 0a 2a 2f 0a 23 69 66 20 30 0a   mode..*/.#if 0.
1c20: 23 20 64 65 66 69 6e 65 20 53 51 4c 49 54 45 5f  # define SQLITE_
1c30: 44 45 42 55 47 5f 53 4f 52 54 45 52 5f 54 48 52  DEBUG_SORTER_THR
1c40: 45 41 44 53 20 31 0a 23 65 6e 64 69 66 0a 0a 2f  EADS 1.#endif../
1c50: 2a 0a 2a 2a 20 48 61 72 64 2d 63 6f 64 65 64 20  *.** Hard-coded 
1c60: 6d 61 78 69 6d 75 6d 20 61 6d 6f 75 6e 74 20 6f  maximum amount o
1c70: 66 20 64 61 74 61 20 74 6f 20 61 63 63 75 6d 75  f data to accumu
1c80: 6c 61 74 65 20 69 6e 20 6d 65 6d 6f 72 79 20 62  late in memory b
1c90: 65 66 6f 72 65 20 66 6c 75 73 68 69 6e 67 0a 2a  efore flushing.*
1ca0: 2a 20 74 6f 20 61 20 6c 65 76 65 6c 20 30 20 50  * to a level 0 P
1cb0: 4d 41 2e 20 54 68 65 20 70 75 72 70 6f 73 65 20  MA. The purpose 
1cc0: 6f 66 20 74 68 69 73 20 6c 69 6d 69 74 20 69 73  of this limit is
1cd0: 20 74 6f 20 70 72 65 76 65 6e 74 20 76 61 72 69   to prevent vari
1ce0: 6f 75 73 20 69 6e 74 65 67 65 72 0a 2a 2a 20 6f  ous integer.** o
1cf0: 76 65 72 66 6c 6f 77 73 2e 20 35 31 32 4d 69 42  verflows. 512MiB
1d00: 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 53 51 4c  ..*/.#define SQL
1d10: 49 54 45 5f 4d 41 58 5f 50 4d 41 53 5a 20 20 20  ITE_MAX_PMASZ   
1d20: 20 28 31 3c 3c 32 39 29 0a 0a 2f 2a 0a 2a 2a 20   (1<<29)../*.** 
1d30: 50 72 69 76 61 74 65 20 6f 62 6a 65 63 74 73 20  Private objects 
1d40: 75 73 65 64 20 62 79 20 74 68 65 20 73 6f 72 74  used by the sort
1d50: 65 72 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74  er.*/.typedef st
1d60: 72 75 63 74 20 4d 65 72 67 65 45 6e 67 69 6e 65  ruct MergeEngine
1d70: 20 4d 65 72 67 65 45 6e 67 69 6e 65 3b 20 20 20   MergeEngine;   
1d80: 20 20 2f 2a 20 4d 65 72 67 65 20 50 4d 41 73 20    /* Merge PMAs 
1d90: 74 6f 67 65 74 68 65 72 20 2a 2f 0a 74 79 70 65  together */.type
1da0: 64 65 66 20 73 74 72 75 63 74 20 50 6d 61 52 65  def struct PmaRe
1db0: 61 64 65 72 20 50 6d 61 52 65 61 64 65 72 3b 20  ader PmaReader; 
1dc0: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 63 72 65          /* Incre
1dd0: 6d 65 6e 74 61 6c 6c 79 20 72 65 61 64 20 6f 6e  mentally read on
1de0: 65 20 50 4d 41 20 2a 2f 0a 74 79 70 65 64 65 66  e PMA */.typedef
1df0: 20 73 74 72 75 63 74 20 50 6d 61 57 72 69 74 65   struct PmaWrite
1e00: 72 20 50 6d 61 57 72 69 74 65 72 3b 20 20 20 20  r PmaWriter;    
1e10: 20 20 20 20 20 2f 2a 20 49 6e 63 72 65 6d 65 6e       /* Incremen
1e20: 74 61 6c 6c 79 20 77 72 69 74 65 20 6f 6e 65 20  tally write one 
1e30: 50 4d 41 20 2a 2f 0a 74 79 70 65 64 65 66 20 73  PMA */.typedef s
1e40: 74 72 75 63 74 20 53 6f 72 74 65 72 52 65 63 6f  truct SorterReco
1e50: 72 64 20 53 6f 72 74 65 72 52 65 63 6f 72 64 3b  rd SorterRecord;
1e60: 20 20 20 2f 2a 20 41 20 72 65 63 6f 72 64 20 62     /* A record b
1e70: 65 69 6e 67 20 73 6f 72 74 65 64 20 2a 2f 0a 74  eing sorted */.t
1e80: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53 6f  ypedef struct So
1e90: 72 74 53 75 62 74 61 73 6b 20 53 6f 72 74 53 75  rtSubtask SortSu
1ea0: 62 74 61 73 6b 3b 20 20 20 20 20 2f 2a 20 41 20  btask;     /* A 
1eb0: 73 75 62 2d 74 61 73 6b 20 69 6e 20 74 68 65 20  sub-task in the 
1ec0: 73 6f 72 74 20 70 72 6f 63 65 73 73 20 2a 2f 0a  sort process */.
1ed0: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53  typedef struct S
1ee0: 6f 72 74 65 72 46 69 6c 65 20 53 6f 72 74 65 72  orterFile Sorter
1ef0: 46 69 6c 65 3b 20 20 20 20 20 20 20 2f 2a 20 54  File;       /* T
1f00: 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 20 6f 62  emporary file ob
1f10: 6a 65 63 74 20 77 72 61 70 70 65 72 20 2a 2f 0a  ject wrapper */.
1f20: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53  typedef struct S
1f30: 6f 72 74 65 72 4c 69 73 74 20 53 6f 72 74 65 72  orterList Sorter
1f40: 4c 69 73 74 3b 20 20 20 20 20 20 20 2f 2a 20 49  List;       /* I
1f50: 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20 6f 66  n-memory list of
1f60: 20 72 65 63 6f 72 64 73 20 2a 2f 0a 74 79 70 65   records */.type
1f70: 64 65 66 20 73 74 72 75 63 74 20 49 6e 63 72 4d  def struct IncrM
1f80: 65 72 67 65 72 20 49 6e 63 72 4d 65 72 67 65 72  erger IncrMerger
1f90: 3b 20 20 20 20 20 20 20 2f 2a 20 52 65 61 64 20  ;       /* Read 
1fa0: 26 20 6d 65 72 67 65 20 6d 75 6c 74 69 70 6c 65  & merge multiple
1fb0: 20 50 4d 41 73 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20   PMAs */../*.** 
1fc0: 41 20 63 6f 6e 74 61 69 6e 65 72 20 66 6f 72 20  A container for 
1fd0: 61 20 74 65 6d 70 20 66 69 6c 65 20 68 61 6e 64  a temp file hand
1fe0: 6c 65 20 61 6e 64 20 74 68 65 20 63 75 72 72 65  le and the curre
1ff0: 6e 74 20 61 6d 6f 75 6e 74 20 6f 66 20 64 61 74  nt amount of dat
2000: 61 20 0a 2a 2a 20 73 74 6f 72 65 64 20 69 6e 20  a .** stored in 
2010: 74 68 65 20 66 69 6c 65 2e 0a 2a 2f 0a 73 74 72  the file..*/.str
2020: 75 63 74 20 53 6f 72 74 65 72 46 69 6c 65 20 7b  uct SorterFile {
2030: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
2040: 2a 70 46 64 3b 20 20 20 20 20 20 20 20 20 20 20  *pFd;           
2050: 20 20 20 2f 2a 20 46 69 6c 65 20 68 61 6e 64 6c     /* File handl
2060: 65 20 2a 2f 0a 20 20 69 36 34 20 69 45 6f 66 3b  e */.  i64 iEof;
2070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2080: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
2090: 6f 66 20 64 61 74 61 20 73 74 6f 72 65 64 20 69  of data stored i
20a0: 6e 20 70 46 64 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  n pFd */.};../*.
20b0: 2a 2a 20 41 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20  ** An in-memory 
20c0: 6c 69 73 74 20 6f 66 20 6f 62 6a 65 63 74 73 20  list of objects 
20d0: 74 6f 20 62 65 20 73 6f 72 74 65 64 2e 0a 2a 2a  to be sorted..**
20e0: 0a 2a 2a 20 49 66 20 61 4d 65 6d 6f 72 79 3d 3d  .** If aMemory==
20f0: 30 20 74 68 65 6e 20 65 61 63 68 20 6f 62 6a 65  0 then each obje
2100: 63 74 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 20  ct is allocated 
2110: 73 65 70 61 72 61 74 65 6c 79 20 61 6e 64 20 74  separately and t
2120: 68 65 20 6f 62 6a 65 63 74 73 0a 2a 2a 20 61 72  he objects.** ar
2130: 65 20 63 6f 6e 6e 65 63 74 65 64 20 75 73 69 6e  e connected usin
2140: 67 20 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 75  g SorterRecord.u
2150: 2e 70 4e 65 78 74 2e 20 20 49 66 20 61 4d 65 6d  .pNext.  If aMem
2160: 6f 72 79 21 3d 30 20 74 68 65 6e 20 61 6c 6c 20  ory!=0 then all 
2170: 6f 62 6a 65 63 74 73 0a 2a 2a 20 61 72 65 20 73  objects.** are s
2180: 74 6f 72 65 64 20 69 6e 20 74 68 65 20 61 4d 65  tored in the aMe
2190: 6d 6f 72 79 5b 5d 20 62 75 6c 6b 20 6d 65 6d 6f  mory[] bulk memo
21a0: 72 79 2c 20 6f 6e 65 20 72 69 67 68 74 20 61 66  ry, one right af
21b0: 74 65 72 20 74 68 65 20 6f 74 68 65 72 2c 20 61  ter the other, a
21c0: 6e 64 0a 2a 2a 20 61 72 65 20 63 6f 6e 6e 65 63  nd.** are connec
21d0: 74 65 64 20 75 73 69 6e 67 20 53 6f 72 74 65 72  ted using Sorter
21e0: 52 65 63 6f 72 64 2e 75 2e 69 4e 65 78 74 2e 0a  Record.u.iNext..
21f0: 2a 2f 0a 73 74 72 75 63 74 20 53 6f 72 74 65 72  */.struct Sorter
2200: 4c 69 73 74 20 7b 0a 20 20 53 6f 72 74 65 72 52  List {.  SorterR
2210: 65 63 6f 72 64 20 2a 70 4c 69 73 74 3b 20 20 20  ecord *pList;   
2220: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 6e 6b           /* Link
2230: 65 64 20 6c 69 73 74 20 6f 66 20 72 65 63 6f 72  ed list of recor
2240: 64 73 20 2a 2f 0a 20 20 75 38 20 2a 61 4d 65 6d  ds */.  u8 *aMem
2250: 6f 72 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  ory;            
2260: 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 6e 6f          /* If no
2270: 6e 2d 4e 55 4c 4c 2c 20 62 75 6c 6b 20 6d 65 6d  n-NULL, bulk mem
2280: 6f 72 79 20 74 6f 20 68 6f 6c 64 20 70 4c 69 73  ory to hold pLis
2290: 74 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 4d 41  t */.  int szPMA
22a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
22b0: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
22c0: 66 20 70 4c 69 73 74 20 61 73 20 50 4d 41 20 69  f pList as PMA i
22d0: 6e 20 62 79 74 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f  n bytes */.};../
22e0: 2a 0a 2a 2a 20 54 68 65 20 4d 65 72 67 65 45 6e  *.** The MergeEn
22f0: 67 69 6e 65 20 6f 62 6a 65 63 74 20 69 73 20 75  gine object is u
2300: 73 65 64 20 74 6f 20 63 6f 6d 62 69 6e 65 20 74  sed to combine t
2310: 77 6f 20 6f 72 20 6d 6f 72 65 20 73 6d 61 6c 6c  wo or more small
2320: 65 72 20 50 4d 41 73 20 69 6e 74 6f 0a 2a 2a 20  er PMAs into.** 
2330: 6f 6e 65 20 62 69 67 20 50 4d 41 20 75 73 69 6e  one big PMA usin
2340: 67 20 61 20 6d 65 72 67 65 20 6f 70 65 72 61 74  g a merge operat
2350: 69 6f 6e 2e 20 20 53 65 70 61 72 61 74 65 20 50  ion.  Separate P
2360: 4d 41 73 20 61 6c 6c 20 6e 65 65 64 20 74 6f 20  MAs all need to 
2370: 62 65 0a 2a 2a 20 63 6f 6d 62 69 6e 65 64 20 69  be.** combined i
2380: 6e 74 6f 20 6f 6e 65 20 62 69 67 20 50 4d 41 20  nto one big PMA 
2390: 69 6e 20 6f 72 64 65 72 20 74 6f 20 62 65 20 61  in order to be a
23a0: 62 6c 65 20 74 6f 20 73 74 65 70 20 74 68 72 6f  ble to step thro
23b0: 75 67 68 20 74 68 65 20 73 6f 72 74 65 64 0a 2a  ugh the sorted.*
23c0: 2a 20 72 65 63 6f 72 64 73 20 69 6e 20 6f 72 64  * records in ord
23d0: 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 52  er..**.** The aR
23e0: 65 61 64 72 5b 5d 20 61 72 72 61 79 20 63 6f 6e  eadr[] array con
23f0: 74 61 69 6e 73 20 61 20 50 6d 61 52 65 61 64 65  tains a PmaReade
2400: 72 20 6f 62 6a 65 63 74 20 66 6f 72 20 65 61 63  r object for eac
2410: 68 20 6f 66 20 74 68 65 20 50 4d 41 73 20 62 65  h of the PMAs be
2420: 69 6e 67 0a 2a 2a 20 6d 65 72 67 65 64 2e 20 20  ing.** merged.  
2430: 41 6e 20 61 52 65 61 64 72 5b 5d 20 6f 62 6a 65  An aReadr[] obje
2440: 63 74 20 65 69 74 68 65 72 20 70 6f 69 6e 74 73  ct either points
2450: 20 74 6f 20 61 20 76 61 6c 69 64 20 6b 65 79 20   to a valid key 
2460: 6f 72 20 65 6c 73 65 20 69 73 20 61 74 20 45 4f  or else is at EO
2470: 46 2e 0a 2a 2a 20 28 22 45 4f 46 22 20 6d 65 61  F..** ("EOF" mea
2480: 6e 73 20 22 45 6e 64 20 4f 66 20 46 69 6c 65 22  ns "End Of File"
2490: 2e 20 20 57 68 65 6e 20 61 52 65 61 64 72 5b 5d  .  When aReadr[]
24a0: 20 69 73 20 61 74 20 45 4f 46 20 74 68 65 72 65   is at EOF there
24b0: 20 69 73 20 6e 6f 20 6d 6f 72 65 20 64 61 74 61   is no more data
24c0: 2e 29 0a 2a 2a 20 46 6f 72 20 74 68 65 20 70 75  .).** For the pu
24d0: 72 70 6f 73 65 73 20 6f 66 20 74 68 65 20 70 61  rposes of the pa
24e0: 72 61 67 72 61 70 68 73 20 62 65 6c 6f 77 2c 20  ragraphs below, 
24f0: 77 65 20 61 73 73 75 6d 65 20 74 68 61 74 20 74  we assume that t
2500: 68 65 20 61 72 72 61 79 20 69 73 0a 2a 2a 20 61  he array is.** a
2510: 63 74 75 61 6c 6c 79 20 4e 20 65 6c 65 6d 65 6e  ctually N elemen
2520: 74 73 20 69 6e 20 73 69 7a 65 2c 20 77 68 65 72  ts in size, wher
2530: 65 20 4e 20 69 73 20 74 68 65 20 73 6d 61 6c 6c  e N is the small
2540: 65 73 74 20 70 6f 77 65 72 20 6f 66 20 32 20 67  est power of 2 g
2550: 72 65 61 74 65 72 0a 2a 2a 20 74 6f 20 6f 72 20  reater.** to or 
2560: 65 71 75 61 6c 20 74 6f 20 74 68 65 20 6e 75 6d  equal to the num
2570: 62 65 72 20 6f 66 20 50 4d 41 73 20 62 65 69 6e  ber of PMAs bein
2580: 67 20 6d 65 72 67 65 64 2e 20 54 68 65 20 65 78  g merged. The ex
2590: 74 72 61 20 61 52 65 61 64 72 5b 5d 20 65 6c 65  tra aReadr[] ele
25a0: 6d 65 6e 74 73 0a 2a 2a 20 61 72 65 20 74 72 65  ments.** are tre
25b0: 61 74 65 64 20 61 73 20 69 66 20 74 68 65 79 20  ated as if they 
25c0: 61 72 65 20 65 6d 70 74 79 20 28 61 6c 77 61 79  are empty (alway
25d0: 73 20 61 74 20 45 4f 46 29 2e 0a 2a 2a 0a 2a 2a  s at EOF)..**.**
25e0: 20 54 68 65 20 61 54 72 65 65 5b 5d 20 61 72 72   The aTree[] arr
25f0: 61 79 20 69 73 20 61 6c 73 6f 20 4e 20 65 6c 65  ay is also N ele
2600: 6d 65 6e 74 73 20 69 6e 20 73 69 7a 65 2e 20 54  ments in size. T
2610: 68 65 20 76 61 6c 75 65 20 6f 66 20 4e 20 69 73  he value of N is
2620: 20 73 74 6f 72 65 64 20 69 6e 0a 2a 2a 20 74 68   stored in.** th
2630: 65 20 4d 65 72 67 65 45 6e 67 69 6e 65 2e 6e 54  e MergeEngine.nT
2640: 72 65 65 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2a  ree variable..**
2650: 0a 2a 2a 20 54 68 65 20 66 69 6e 61 6c 20 28 4e  .** The final (N
2660: 2f 32 29 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20  /2) elements of 
2670: 61 54 72 65 65 5b 5d 20 63 6f 6e 74 61 69 6e 20  aTree[] contain 
2680: 74 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20 63  the results of c
2690: 6f 6d 70 61 72 69 6e 67 0a 2a 2a 20 70 61 69 72  omparing.** pair
26a0: 73 20 6f 66 20 50 4d 41 20 6b 65 79 73 20 74 6f  s of PMA keys to
26b0: 67 65 74 68 65 72 2e 20 45 6c 65 6d 65 6e 74 20  gether. Element 
26c0: 69 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 72  i contains the r
26d0: 65 73 75 6c 74 20 6f 66 20 0a 2a 2a 20 63 6f 6d  esult of .** com
26e0: 70 61 72 69 6e 67 20 61 52 65 61 64 72 5b 32 2a  paring aReadr[2*
26f0: 69 2d 4e 5d 20 61 6e 64 20 61 52 65 61 64 72 5b  i-N] and aReadr[
2700: 32 2a 69 2d 4e 2b 31 5d 2e 20 57 68 69 63 68 65  2*i-N+1]. Whiche
2710: 76 65 72 20 6b 65 79 20 69 73 20 73 6d 61 6c 6c  ver key is small
2720: 65 72 2c 20 74 68 65 0a 2a 2a 20 61 54 72 65 65  er, the.** aTree
2730: 20 65 6c 65 6d 65 6e 74 20 69 73 20 73 65 74 20   element is set 
2740: 74 6f 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20  to the index of 
2750: 69 74 2e 20 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 74  it. .**.** For t
2760: 68 65 20 70 75 72 70 6f 73 65 73 20 6f 66 20 74  he purposes of t
2770: 68 69 73 20 63 6f 6d 70 61 72 69 73 6f 6e 2c 20  his comparison, 
2780: 45 4f 46 20 69 73 20 63 6f 6e 73 69 64 65 72 65  EOF is considere
2790: 64 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 61  d greater than a
27a0: 6e 79 0a 2a 2a 20 6f 74 68 65 72 20 6b 65 79 20  ny.** other key 
27b0: 76 61 6c 75 65 2e 20 49 66 20 74 68 65 20 6b 65  value. If the ke
27c0: 79 73 20 61 72 65 20 65 71 75 61 6c 20 28 6f 6e  ys are equal (on
27d0: 6c 79 20 70 6f 73 73 69 62 6c 65 20 77 69 74 68  ly possible with
27e0: 20 74 77 6f 20 45 4f 46 0a 2a 2a 20 76 61 6c 75   two EOF.** valu
27f0: 65 73 29 2c 20 69 74 20 64 6f 65 73 6e 27 74 20  es), it doesn't 
2800: 6d 61 74 74 65 72 20 77 68 69 63 68 20 69 6e 64  matter which ind
2810: 65 78 20 69 73 20 73 74 6f 72 65 64 2e 0a 2a 2a  ex is stored..**
2820: 0a 2a 2a 20 54 68 65 20 28 4e 2f 34 29 20 65 6c  .** The (N/4) el
2830: 65 6d 65 6e 74 73 20 6f 66 20 61 54 72 65 65 5b  ements of aTree[
2840: 5d 20 74 68 61 74 20 70 72 65 63 65 64 65 20 74  ] that precede t
2850: 68 65 20 66 69 6e 61 6c 20 28 4e 2f 32 29 20 64  he final (N/2) d
2860: 65 73 63 72 69 62 65 64 20 0a 2a 2a 20 61 62 6f  escribed .** abo
2870: 76 65 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  ve contains the 
2880: 69 6e 64 65 78 20 6f 66 20 74 68 65 20 73 6d 61  index of the sma
2890: 6c 6c 65 73 74 20 6f 66 20 65 61 63 68 20 62 6c  llest of each bl
28a0: 6f 63 6b 20 6f 66 20 34 20 50 6d 61 52 65 61 64  ock of 4 PmaRead
28b0: 65 72 73 0a 2a 2a 20 41 6e 64 20 73 6f 20 6f 6e  ers.** And so on
28c0: 2e 20 53 6f 20 74 68 61 74 20 61 54 72 65 65 5b  . So that aTree[
28d0: 31 5d 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  1] contains the 
28e0: 69 6e 64 65 78 20 6f 66 20 74 68 65 20 50 6d 61  index of the Pma
28f0: 52 65 61 64 65 72 20 74 68 61 74 20 0a 2a 2a 20  Reader that .** 
2900: 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73  currently points
2910: 20 74 6f 20 74 68 65 20 73 6d 61 6c 6c 65 73 74   to the smallest
2920: 20 6b 65 79 20 76 61 6c 75 65 2e 20 61 54 72 65   key value. aTre
2930: 65 5b 30 5d 20 69 73 20 75 6e 75 73 65 64 2e 0a  e[0] is unused..
2940: 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65 3a 0a 2a  **.** Example:.*
2950: 2a 0a 2a 2a 20 20 20 20 20 61 52 65 61 64 72 5b  *.**     aReadr[
2960: 30 5d 20 2d 3e 20 42 61 6e 61 6e 61 0a 2a 2a 20  0] -> Banana.** 
2970: 20 20 20 20 61 52 65 61 64 72 5b 31 5d 20 2d 3e      aReadr[1] ->
2980: 20 46 65 69 6a 6f 61 0a 2a 2a 20 20 20 20 20 61   Feijoa.**     a
2990: 52 65 61 64 72 5b 32 5d 20 2d 3e 20 45 6c 64 65  Readr[2] -> Elde
29a0: 72 62 65 72 72 79 0a 2a 2a 20 20 20 20 20 61 52  rberry.**     aR
29b0: 65 61 64 72 5b 33 5d 20 2d 3e 20 43 75 72 72 61  eadr[3] -> Curra
29c0: 6e 74 0a 2a 2a 20 20 20 20 20 61 52 65 61 64 72  nt.**     aReadr
29d0: 5b 34 5d 20 2d 3e 20 47 72 61 70 65 66 72 75 69  [4] -> Grapefrui
29e0: 74 0a 2a 2a 20 20 20 20 20 61 52 65 61 64 72 5b  t.**     aReadr[
29f0: 35 5d 20 2d 3e 20 41 70 70 6c 65 0a 2a 2a 20 20  5] -> Apple.**  
2a00: 20 20 20 61 52 65 61 64 72 5b 36 5d 20 2d 3e 20     aReadr[6] -> 
2a10: 44 75 72 69 61 6e 0a 2a 2a 20 20 20 20 20 61 52  Durian.**     aR
2a20: 65 61 64 72 5b 37 5d 20 2d 3e 20 45 4f 46 0a 2a  eadr[7] -> EOF.*
2a30: 2a 0a 2a 2a 20 20 20 20 20 61 54 72 65 65 5b 5d  *.**     aTree[]
2a40: 20 3d 20 7b 20 58 2c 20 35 20 20 20 30 2c 20 35   = { X, 5   0, 5
2a50: 20 20 20 20 30 2c 20 33 2c 20 35 2c 20 36 20 7d      0, 3, 5, 6 }
2a60: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 75 72 72 65  .**.** The curre
2a70: 6e 74 20 65 6c 65 6d 65 6e 74 20 69 73 20 22 41  nt element is "A
2a80: 70 70 6c 65 22 20 28 74 68 65 20 76 61 6c 75 65  pple" (the value
2a90: 20 6f 66 20 74 68 65 20 6b 65 79 20 69 6e 64 69   of the key indi
2aa0: 63 61 74 65 64 20 62 79 20 0a 2a 2a 20 50 6d 61  cated by .** Pma
2ab0: 52 65 61 64 65 72 20 35 29 2e 20 57 68 65 6e 20  Reader 5). When 
2ac0: 74 68 65 20 4e 65 78 74 28 29 20 6f 70 65 72 61  the Next() opera
2ad0: 74 69 6f 6e 20 69 73 20 69 6e 76 6f 6b 65 64 2c  tion is invoked,
2ae0: 20 50 6d 61 52 65 61 64 65 72 20 35 20 77 69 6c   PmaReader 5 wil
2af0: 6c 0a 2a 2a 20 62 65 20 61 64 76 61 6e 63 65 64  l.** be advanced
2b00: 20 74 6f 20 74 68 65 20 6e 65 78 74 20 6b 65 79   to the next key
2b10: 20 69 6e 20 69 74 73 20 73 65 67 6d 65 6e 74 2e   in its segment.
2b20: 20 53 61 79 20 74 68 65 20 6e 65 78 74 20 6b 65   Say the next ke
2b30: 79 20 69 73 0a 2a 2a 20 22 45 67 67 70 6c 61 6e  y is.** "Eggplan
2b40: 74 22 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 52  t":.**.**     aR
2b50: 65 61 64 72 5b 35 5d 20 2d 3e 20 45 67 67 70 6c  eadr[5] -> Eggpl
2b60: 61 6e 74 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f  ant.**.** The co
2b70: 6e 74 65 6e 74 73 20 6f 66 20 61 54 72 65 65 5b  ntents of aTree[
2b80: 5d 20 61 72 65 20 75 70 64 61 74 65 64 20 66 69  ] are updated fi
2b90: 72 73 74 20 62 79 20 63 6f 6d 70 61 72 69 6e 67  rst by comparing
2ba0: 20 74 68 65 20 6e 65 77 20 50 6d 61 52 65 61 64   the new PmaRead
2bb0: 65 72 0a 2a 2a 20 35 20 6b 65 79 20 74 6f 20 74  er.** 5 key to t
2bc0: 68 65 20 63 75 72 72 65 6e 74 20 6b 65 79 20 6f  he current key o
2bd0: 66 20 50 6d 61 52 65 61 64 65 72 20 34 20 28 73  f PmaReader 4 (s
2be0: 74 69 6c 6c 20 22 47 72 61 70 65 66 72 75 69 74  till "Grapefruit
2bf0: 22 29 2e 20 54 68 65 20 50 6d 61 52 65 61 64 65  "). The PmaReade
2c00: 72 0a 2a 2a 20 35 20 76 61 6c 75 65 20 69 73 20  r.** 5 value is 
2c10: 73 74 69 6c 6c 20 73 6d 61 6c 6c 65 72 2c 20 73  still smaller, s
2c20: 6f 20 61 54 72 65 65 5b 36 5d 20 69 73 20 73 65  o aTree[6] is se
2c30: 74 20 74 6f 20 35 2e 20 41 6e 64 20 73 6f 20 6f  t to 5. And so o
2c40: 6e 20 75 70 20 74 68 65 20 74 72 65 65 2e 0a 2a  n up the tree..*
2c50: 2a 20 54 68 65 20 76 61 6c 75 65 20 6f 66 20 50  * The value of P
2c60: 6d 61 52 65 61 64 65 72 20 36 20 2d 20 22 44 75  maReader 6 - "Du
2c70: 72 69 61 6e 22 20 2d 20 69 73 20 6e 6f 77 20 73  rian" - is now s
2c80: 6d 61 6c 6c 65 72 20 74 68 61 6e 20 74 68 61 74  maller than that
2c90: 20 6f 66 20 50 6d 61 52 65 61 64 65 72 0a 2a 2a   of PmaReader.**
2ca0: 20 35 2c 20 73 6f 20 61 54 72 65 65 5b 33 5d 20   5, so aTree[3] 
2cb0: 69 73 20 73 65 74 20 74 6f 20 36 2e 20 4b 65 79  is set to 6. Key
2cc0: 20 30 20 69 73 20 73 6d 61 6c 6c 65 72 20 74 68   0 is smaller th
2cd0: 61 6e 20 6b 65 79 20 36 20 28 42 61 6e 61 6e 61  an key 6 (Banana
2ce0: 3c 44 75 72 69 61 6e 29 2c 0a 2a 2a 20 73 6f 20  <Durian),.** so 
2cf0: 74 68 65 20 76 61 6c 75 65 20 77 72 69 74 74 65  the value writte
2d00: 6e 20 69 6e 74 6f 20 65 6c 65 6d 65 6e 74 20 31  n into element 1
2d10: 20 6f 66 20 74 68 65 20 61 72 72 61 79 20 69 73   of the array is
2d20: 20 30 2e 20 41 73 20 66 6f 6c 6c 6f 77 73 3a 0a   0. As follows:.
2d30: 2a 2a 0a 2a 2a 20 20 20 20 20 61 54 72 65 65 5b  **.**     aTree[
2d40: 5d 20 3d 20 7b 20 58 2c 20 30 20 20 20 30 2c 20  ] = { X, 0   0, 
2d50: 36 20 20 20 20 30 2c 20 33 2c 20 35 2c 20 36 20  6    0, 3, 5, 6 
2d60: 7d 0a 2a 2a 0a 2a 2a 20 49 6e 20 6f 74 68 65 72  }.**.** In other
2d70: 20 77 6f 72 64 73 2c 20 65 61 63 68 20 74 69 6d   words, each tim
2d80: 65 20 77 65 20 61 64 76 61 6e 63 65 20 74 6f 20  e we advance to 
2d90: 74 68 65 20 6e 65 78 74 20 73 6f 72 74 65 72 20  the next sorter 
2da0: 65 6c 65 6d 65 6e 74 2c 20 6c 6f 67 32 28 4e 29  element, log2(N)
2db0: 0a 2a 2a 20 6b 65 79 20 63 6f 6d 70 61 72 69 73  .** key comparis
2dc0: 6f 6e 20 6f 70 65 72 61 74 69 6f 6e 73 20 61 72  on operations ar
2dd0: 65 20 72 65 71 75 69 72 65 64 2c 20 77 68 65 72  e required, wher
2de0: 65 20 4e 20 69 73 20 74 68 65 20 6e 75 6d 62 65  e N is the numbe
2df0: 72 20 6f 66 20 73 65 67 6d 65 6e 74 73 0a 2a 2a  r of segments.**
2e00: 20 62 65 69 6e 67 20 6d 65 72 67 65 64 20 28 72   being merged (r
2e10: 6f 75 6e 64 65 64 20 75 70 20 74 6f 20 74 68 65  ounded up to the
2e20: 20 6e 65 78 74 20 70 6f 77 65 72 20 6f 66 20 32   next power of 2
2e30: 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 4d 65 72  )..*/.struct Mer
2e40: 67 65 45 6e 67 69 6e 65 20 7b 0a 20 20 69 6e 74  geEngine {.  int
2e50: 20 6e 54 72 65 65 3b 20 20 20 20 20 20 20 20 20   nTree;         
2e60: 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20          /* Used 
2e70: 73 69 7a 65 20 6f 66 20 61 54 72 65 65 2f 61 52  size of aTree/aR
2e80: 65 61 64 72 20 28 70 6f 77 65 72 20 6f 66 20 32  eadr (power of 2
2e90: 29 20 2a 2f 0a 20 20 53 6f 72 74 53 75 62 74 61  ) */.  SortSubta
2ea0: 73 6b 20 2a 70 54 61 73 6b 3b 20 20 20 20 20 20  sk *pTask;      
2eb0: 20 20 2f 2a 20 55 73 65 64 20 62 79 20 74 68 69    /* Used by thi
2ec0: 73 20 74 68 72 65 61 64 20 6f 6e 6c 79 20 2a 2f  s thread only */
2ed0: 0a 20 20 69 6e 74 20 2a 61 54 72 65 65 3b 20 20  .  int *aTree;  
2ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2ef0: 20 43 75 72 72 65 6e 74 20 73 74 61 74 65 20 6f   Current state o
2f00: 66 20 69 6e 63 72 65 6d 65 6e 74 61 6c 20 6d 65  f incremental me
2f10: 72 67 65 20 2a 2f 0a 20 20 50 6d 61 52 65 61 64  rge */.  PmaRead
2f20: 65 72 20 2a 61 52 65 61 64 72 3b 20 20 20 20 20  er *aReadr;     
2f30: 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20      /* Array of 
2f40: 50 6d 61 52 65 61 64 65 72 73 20 74 6f 20 6d 65  PmaReaders to me
2f50: 72 67 65 20 64 61 74 61 20 66 72 6f 6d 20 2a 2f  rge data from */
2f60: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  .};../*.** This 
2f70: 6f 62 6a 65 63 74 20 72 65 70 72 65 73 65 6e 74  object represent
2f80: 73 20 61 20 73 69 6e 67 6c 65 20 74 68 72 65 61  s a single threa
2f90: 64 20 6f 66 20 63 6f 6e 74 72 6f 6c 20 69 6e 20  d of control in 
2fa0: 61 20 73 6f 72 74 20 6f 70 65 72 61 74 69 6f 6e  a sort operation
2fb0: 2e 0a 2a 2a 20 45 78 61 63 74 6c 79 20 56 64 62  ..** Exactly Vdb
2fc0: 65 53 6f 72 74 65 72 2e 6e 54 61 73 6b 20 69 6e  eSorter.nTask in
2fd0: 73 74 61 6e 63 65 73 20 6f 66 20 74 68 69 73 20  stances of this 
2fe0: 6f 62 6a 65 63 74 20 61 72 65 20 61 6c 6c 6f 63  object are alloc
2ff0: 61 74 65 64 0a 2a 2a 20 61 73 20 70 61 72 74 20  ated.** as part 
3000: 6f 66 20 65 61 63 68 20 56 64 62 65 53 6f 72 74  of each VdbeSort
3010: 65 72 20 6f 62 6a 65 63 74 2e 20 49 6e 73 74 61  er object. Insta
3020: 6e 63 65 73 20 61 72 65 20 6e 65 76 65 72 20 61  nces are never a
3030: 6c 6c 6f 63 61 74 65 64 20 61 6e 79 0a 2a 2a 20  llocated any.** 
3040: 6f 74 68 65 72 20 77 61 79 2e 20 56 64 62 65 53  other way. VdbeS
3050: 6f 72 74 65 72 2e 6e 54 61 73 6b 20 69 73 20 73  orter.nTask is s
3060: 65 74 20 74 6f 20 74 68 65 20 6e 75 6d 62 65 72  et to the number
3070: 20 6f 66 20 77 6f 72 6b 65 72 20 74 68 72 65 61   of worker threa
3080: 64 73 20 61 6c 6c 6f 77 65 64 0a 2a 2a 20 28 73  ds allowed.** (s
3090: 65 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  ee SQLITE_CONFIG
30a0: 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 29  _WORKER_THREADS)
30b0: 20 70 6c 75 73 20 6f 6e 65 20 28 74 68 65 20 6d   plus one (the m
30c0: 61 69 6e 20 74 68 72 65 61 64 29 2e 20 20 54 68  ain thread).  Th
30d0: 75 73 20 66 6f 72 0a 2a 2a 20 73 69 6e 67 6c 65  us for.** single
30e0: 2d 74 68 72 65 61 64 65 64 20 6f 70 65 72 61 74  -threaded operat
30f0: 69 6f 6e 2c 20 74 68 65 72 65 20 69 73 20 65 78  ion, there is ex
3100: 61 63 74 6c 79 20 6f 6e 65 20 69 6e 73 74 61 6e  actly one instan
3110: 63 65 20 6f 66 20 74 68 69 73 20 6f 62 6a 65 63  ce of this objec
3120: 74 0a 2a 2a 20 61 6e 64 20 66 6f 72 20 6d 75 6c  t.** and for mul
3130: 74 69 2d 74 68 72 65 61 64 65 64 20 6f 70 65 72  ti-threaded oper
3140: 61 74 69 6f 6e 20 74 68 65 72 65 20 61 72 65 20  ation there are 
3150: 74 77 6f 20 6f 72 20 6d 6f 72 65 20 69 6e 73 74  two or more inst
3160: 61 6e 63 65 73 2e 0a 2a 2a 0a 2a 2a 20 45 73 73  ances..**.** Ess
3170: 65 6e 74 69 61 6c 6c 79 2c 20 74 68 69 73 20 73  entially, this s
3180: 74 72 75 63 74 75 72 65 20 63 6f 6e 74 61 69 6e  tructure contain
3190: 73 20 61 6c 6c 20 74 68 6f 73 65 20 66 69 65 6c  s all those fiel
31a0: 64 73 20 6f 66 20 74 68 65 20 56 64 62 65 53 6f  ds of the VdbeSo
31b0: 72 74 65 72 0a 2a 2a 20 73 74 72 75 63 74 75 72  rter.** structur
31c0: 65 20 66 6f 72 20 77 68 69 63 68 20 65 61 63 68  e for which each
31d0: 20 74 68 72 65 61 64 20 72 65 71 75 69 72 65 73   thread requires
31e0: 20 61 20 73 65 70 61 72 61 74 65 20 69 6e 73 74   a separate inst
31f0: 61 6e 63 65 2e 20 46 6f 72 20 65 78 61 6d 70 6c  ance. For exampl
3200: 65 2c 0a 2a 2a 20 65 61 63 68 20 74 68 72 65 61  e,.** each threa
3210: 64 20 72 65 71 75 72 69 65 73 20 69 74 73 20 6f  d requries its o
3220: 77 6e 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72  wn UnpackedRecor
3230: 64 20 6f 62 6a 65 63 74 20 74 6f 20 75 6e 70 61  d object to unpa
3240: 63 6b 20 72 65 63 6f 72 64 73 20 69 6e 0a 2a 2a  ck records in.**
3250: 20 61 73 20 70 61 72 74 20 6f 66 20 63 6f 6d 70   as part of comp
3260: 61 72 69 73 6f 6e 20 6f 70 65 72 61 74 69 6f 6e  arison operation
3270: 73 2e 0a 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65 20  s..**.** Before 
3280: 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  a background thr
3290: 65 61 64 20 69 73 20 6c 61 75 6e 63 68 65 64 2c  ead is launched,
32a0: 20 76 61 72 69 61 62 6c 65 20 62 44 6f 6e 65 20   variable bDone 
32b0: 69 73 20 73 65 74 20 74 6f 20 30 2e 20 54 68 65  is set to 0. The
32c0: 6e 2c 20 0a 2a 2a 20 72 69 67 68 74 20 62 65 66  n, .** right bef
32d0: 6f 72 65 20 69 74 20 65 78 69 74 73 2c 20 74 68  ore it exits, th
32e0: 65 20 74 68 72 65 61 64 20 69 74 73 65 6c 66 20  e thread itself 
32f0: 73 65 74 73 20 62 44 6f 6e 65 20 74 6f 20 31 2e  sets bDone to 1.
3300: 20 54 68 69 73 20 69 73 20 75 73 65 64 20 66 6f   This is used fo
3310: 72 20 0a 2a 2a 20 74 77 6f 20 70 75 72 70 6f 73  r .** two purpos
3320: 65 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 57  es:.**.**   1. W
3330: 68 65 6e 20 66 6c 75 73 68 69 6e 67 20 74 68 65  hen flushing the
3340: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65 6d   contents of mem
3350: 6f 72 79 20 74 6f 20 61 20 6c 65 76 65 6c 2d 30  ory to a level-0
3360: 20 50 4d 41 20 6f 6e 20 64 69 73 6b 2c 20 74 6f   PMA on disk, to
3370: 0a 2a 2a 20 20 20 20 20 20 61 74 74 65 6d 70 74  .**      attempt
3380: 20 74 6f 20 73 65 6c 65 63 74 20 61 20 53 6f 72   to select a Sor
3390: 74 53 75 62 74 61 73 6b 20 66 6f 72 20 77 68 69  tSubtask for whi
33a0: 63 68 20 74 68 65 72 65 20 69 73 20 6e 6f 74 20  ch there is not 
33b0: 61 6c 72 65 61 64 79 20 61 6e 0a 2a 2a 20 20 20  already an.**   
33c0: 20 20 20 61 63 74 69 76 65 20 62 61 63 6b 67 72     active backgr
33d0: 6f 75 6e 64 20 74 68 72 65 61 64 20 28 73 69 6e  ound thread (sin
33e0: 63 65 20 64 6f 69 6e 67 20 73 6f 20 63 61 75 73  ce doing so caus
33f0: 65 73 20 74 68 65 20 6d 61 69 6e 20 74 68 72 65  es the main thre
3400: 61 64 0a 2a 2a 20 20 20 20 20 20 74 6f 20 62 6c  ad.**      to bl
3410: 6f 63 6b 20 75 6e 74 69 6c 20 69 74 20 66 69 6e  ock until it fin
3420: 69 73 68 65 73 29 2e 0a 2a 2a 0a 2a 2a 20 20 20  ishes)..**.**   
3430: 32 2e 20 49 66 20 53 51 4c 49 54 45 5f 44 45 42  2. If SQLITE_DEB
3440: 55 47 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44  UG_SORTER_THREAD
3450: 53 20 69 73 20 64 65 66 69 6e 65 64 2c 20 74 6f  S is defined, to
3460: 20 64 65 74 65 72 6d 69 6e 65 20 69 66 20 61 20   determine if a 
3470: 63 61 6c 6c 0a 2a 2a 20 20 20 20 20 20 74 6f 20  call.**      to 
3480: 73 71 6c 69 74 65 33 54 68 72 65 61 64 4a 6f 69  sqlite3ThreadJoi
3490: 6e 28 29 20 69 73 20 6c 69 6b 65 6c 79 20 74 6f  n() is likely to
34a0: 20 62 6c 6f 63 6b 2e 20 43 61 73 65 73 20 74 68   block. Cases th
34b0: 61 74 20 61 72 65 20 6c 69 6b 65 6c 79 20 74 6f  at are likely to
34c0: 0a 2a 2a 20 20 20 20 20 20 62 6c 6f 63 6b 20 70  .**      block p
34d0: 72 6f 76 6f 6b 65 20 64 65 62 75 67 67 69 6e 67  rovoke debugging
34e0: 20 6f 75 74 70 75 74 2e 0a 2a 2a 0a 2a 2a 20 49   output..**.** I
34f0: 6e 20 62 6f 74 68 20 63 61 73 65 73 2c 20 74 68  n both cases, th
3500: 65 20 65 66 66 65 63 74 73 20 6f 66 20 74 68 65  e effects of the
3510: 20 6d 61 69 6e 20 74 68 72 65 61 64 20 73 65 65   main thread see
3520: 69 6e 67 20 28 62 44 6f 6e 65 3d 3d 30 29 20 65  ing (bDone==0) e
3530: 76 65 6e 0a 2a 2a 20 61 66 74 65 72 20 74 68 65  ven.** after the
3540: 20 74 68 72 65 61 64 20 68 61 73 20 66 69 6e 69   thread has fini
3550: 73 68 65 64 20 61 72 65 20 6e 6f 74 20 64 69 72  shed are not dir
3560: 65 2e 20 53 6f 20 77 65 20 64 6f 6e 27 74 20 77  e. So we don't w
3570: 6f 72 72 79 20 61 62 6f 75 74 0a 2a 2a 20 6d 65  orry about.** me
3580: 6d 6f 72 79 20 62 61 72 72 69 65 72 73 20 61 6e  mory barriers an
3590: 64 20 73 75 63 68 20 68 65 72 65 2e 0a 2a 2f 0a  d such here..*/.
35a0: 74 79 70 65 64 65 66 20 69 6e 74 20 28 2a 53 6f  typedef int (*So
35b0: 72 74 65 72 43 6f 6d 70 61 72 65 29 28 53 6f 72  rterCompare)(Sor
35c0: 74 53 75 62 74 61 73 6b 2a 2c 69 6e 74 2a 2c 63  tSubtask*,int*,c
35d0: 6f 6e 73 74 20 76 6f 69 64 2a 2c 69 6e 74 2c 63  onst void*,int,c
35e0: 6f 6e 73 74 20 76 6f 69 64 2a 2c 69 6e 74 29 3b  onst void*,int);
35f0: 0a 73 74 72 75 63 74 20 53 6f 72 74 53 75 62 74  .struct SortSubt
3600: 61 73 6b 20 7b 0a 20 20 53 51 4c 69 74 65 54 68  ask {.  SQLiteTh
3610: 72 65 61 64 20 2a 70 54 68 72 65 61 64 3b 20 20  read *pThread;  
3620: 20 20 20 20 20 20 20 20 2f 2a 20 42 61 63 6b 67          /* Backg
3630: 72 6f 75 6e 64 20 74 68 72 65 61 64 2c 20 69 66  round thread, if
3640: 20 61 6e 79 20 2a 2f 0a 20 20 69 6e 74 20 62 44   any */.  int bD
3650: 6f 6e 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  one;            
3660: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74            /* Set
3670: 20 69 66 20 74 68 72 65 61 64 20 69 73 20 66 69   if thread is fi
3680: 6e 69 73 68 65 64 20 62 75 74 20 6e 6f 74 20 6a  nished but not j
3690: 6f 69 6e 65 64 20 2a 2f 0a 20 20 56 64 62 65 53  oined */.  VdbeS
36a0: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 3b 20  orter *pSorter; 
36b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f             /* So
36c0: 72 74 65 72 20 74 68 61 74 20 6f 77 6e 73 20 74  rter that owns t
36d0: 68 69 73 20 73 75 62 2d 74 61 73 6b 20 2a 2f 0a  his sub-task */.
36e0: 20 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64    UnpackedRecord
36f0: 20 2a 70 55 6e 70 61 63 6b 65 64 3b 20 20 20 20   *pUnpacked;    
3700: 20 20 2f 2a 20 53 70 61 63 65 20 74 6f 20 75 6e    /* Space to un
3710: 70 61 63 6b 20 61 20 72 65 63 6f 72 64 20 2a 2f  pack a record */
3720: 0a 20 20 53 6f 72 74 65 72 4c 69 73 74 20 6c 69  .  SorterList li
3730: 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  st;             
3740: 20 20 20 2f 2a 20 4c 69 73 74 20 66 6f 72 20 74     /* List for t
3750: 68 72 65 61 64 20 74 6f 20 77 72 69 74 65 20 74  hread to write t
3760: 6f 20 61 20 50 4d 41 20 2a 2f 0a 20 20 69 6e 74  o a PMA */.  int
3770: 20 6e 50 4d 41 3b 20 20 20 20 20 20 20 20 20 20   nPMA;          
3780: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3790: 4e 75 6d 62 65 72 20 6f 66 20 50 4d 41 73 20 63  Number of PMAs c
37a0: 75 72 72 65 6e 74 6c 79 20 69 6e 20 66 69 6c 65  urrently in file
37b0: 20 2a 2f 0a 20 20 53 6f 72 74 65 72 43 6f 6d 70   */.  SorterComp
37c0: 61 72 65 20 78 43 6f 6d 70 61 72 65 3b 20 20 20  are xCompare;   
37d0: 20 20 20 20 20 20 2f 2a 20 43 6f 6d 70 61 72 65        /* Compare
37e0: 20 66 75 6e 63 74 69 6f 6e 20 74 6f 20 75 73 65   function to use
37f0: 20 2a 2f 0a 20 20 53 6f 72 74 65 72 46 69 6c 65   */.  SorterFile
3800: 20 66 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20   file;          
3810: 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 20 66 69        /* Temp fi
3820: 6c 65 20 66 6f 72 20 6c 65 76 65 6c 2d 30 20 50  le for level-0 P
3830: 4d 41 73 20 2a 2f 0a 20 20 53 6f 72 74 65 72 46  MAs */.  SorterF
3840: 69 6c 65 20 66 69 6c 65 32 3b 20 20 20 20 20 20  ile file2;      
3850: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 70 61 63           /* Spac
3860: 65 20 66 6f 72 20 6f 74 68 65 72 20 50 4d 41 73  e for other PMAs
3870: 20 2a 2f 0a 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 4d   */.};.../*.** M
3880: 61 69 6e 20 73 6f 72 74 65 72 20 73 74 72 75 63  ain sorter struc
3890: 74 75 72 65 2e 20 41 20 73 69 6e 67 6c 65 20 69  ture. A single i
38a0: 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20  nstance of this 
38b0: 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72  is allocated for
38c0: 20 65 61 63 68 20 0a 2a 2a 20 73 6f 72 74 65 72   each .** sorter
38d0: 20 63 75 72 73 6f 72 20 63 72 65 61 74 65 64 20   cursor created 
38e0: 62 79 20 74 68 65 20 56 44 42 45 2e 0a 2a 2a 0a  by the VDBE..**.
38f0: 2a 2a 20 6d 78 4b 65 79 73 69 7a 65 3a 0a 2a 2a  ** mxKeysize:.**
3900: 20 20 20 41 73 20 72 65 63 6f 72 64 73 20 61 72     As records ar
3910: 65 20 61 64 64 65 64 20 74 6f 20 74 68 65 20 73  e added to the s
3920: 6f 72 74 65 72 20 62 79 20 63 61 6c 6c 73 20 74  orter by calls t
3930: 6f 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72  o sqlite3VdbeSor
3940: 74 65 72 57 72 69 74 65 28 29 2c 0a 2a 2a 20 20  terWrite(),.**  
3950: 20 74 68 69 73 20 76 61 72 69 61 62 6c 65 20 69   this variable i
3960: 73 20 75 70 64 61 74 65 64 20 73 6f 20 61 73 20  s updated so as 
3970: 74 6f 20 62 65 20 73 65 74 20 74 6f 20 74 68 65  to be set to the
3980: 20 73 69 7a 65 20 6f 6e 20 64 69 73 6b 20 6f 66   size on disk of
3990: 20 74 68 65 0a 2a 2a 20 20 20 6c 61 72 67 65 73   the.**   larges
39a0: 74 20 72 65 63 6f 72 64 20 69 6e 20 74 68 65 20  t record in the 
39b0: 73 6f 72 74 65 72 2e 0a 2a 2f 0a 73 74 72 75 63  sorter..*/.struc
39c0: 74 20 56 64 62 65 53 6f 72 74 65 72 20 7b 0a 20  t VdbeSorter {. 
39d0: 20 69 6e 74 20 6d 6e 50 6d 61 53 69 7a 65 3b 20   int mnPmaSize; 
39e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
39f0: 20 2f 2a 20 4d 69 6e 69 6d 75 6d 20 50 4d 41 20   /* Minimum PMA 
3a00: 73 69 7a 65 2c 20 69 6e 20 62 79 74 65 73 20 2a  size, in bytes *
3a10: 2f 0a 20 20 69 6e 74 20 6d 78 50 6d 61 53 69 7a  /.  int mxPmaSiz
3a20: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
3a30: 20 20 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 50      /* Maximum P
3a40: 4d 41 20 73 69 7a 65 2c 20 69 6e 20 62 79 74 65  MA size, in byte
3a50: 73 2e 20 20 30 3d 3d 6e 6f 20 6c 69 6d 69 74 20  s.  0==no limit 
3a60: 2a 2f 0a 20 20 69 6e 74 20 6d 78 4b 65 79 73 69  */.  int mxKeysi
3a70: 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ze;             
3a80: 20 20 20 20 20 2f 2a 20 4c 61 72 67 65 73 74 20       /* Largest 
3a90: 73 65 72 69 61 6c 69 7a 65 64 20 6b 65 79 20 73  serialized key s
3aa0: 65 65 6e 20 73 6f 20 66 61 72 20 2a 2f 0a 20 20  een so far */.  
3ab0: 69 6e 74 20 70 67 73 7a 3b 20 20 20 20 20 20 20  int pgsz;       
3ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3ad0: 2f 2a 20 4d 61 69 6e 20 64 61 74 61 62 61 73 65  /* Main database
3ae0: 20 70 61 67 65 20 73 69 7a 65 20 2a 2f 0a 20 20   page size */.  
3af0: 50 6d 61 52 65 61 64 65 72 20 2a 70 52 65 61 64  PmaReader *pRead
3b00: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  er;             
3b10: 2f 2a 20 52 65 61 64 72 20 64 61 74 61 20 66 72  /* Readr data fr
3b20: 6f 6d 20 68 65 72 65 20 61 66 74 65 72 20 52 65  om here after Re
3b30: 77 69 6e 64 28 29 20 2a 2f 0a 20 20 4d 65 72 67  wind() */.  Merg
3b40: 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67 65 72  eEngine *pMerger
3b50: 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f  ;           /* O
3b60: 72 20 68 65 72 65 2c 20 69 66 20 62 55 73 65 54  r here, if bUseT
3b70: 68 72 65 61 64 73 3d 3d 30 20 2a 2f 0a 20 20 73  hreads==0 */.  s
3b80: 71 6c 69 74 65 33 20 2a 64 62 3b 20 20 20 20 20  qlite3 *db;     
3b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3ba0: 2a 20 44 61 74 61 62 61 73 65 20 63 6f 6e 6e 65  * Database conne
3bb0: 63 74 69 6f 6e 20 2a 2f 0a 20 20 4b 65 79 49 6e  ction */.  KeyIn
3bc0: 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 3b 20 20 20  fo *pKeyInfo;   
3bd0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48 6f             /* Ho
3be0: 77 20 74 6f 20 63 6f 6d 70 61 72 65 20 72 65 63  w to compare rec
3bf0: 6f 72 64 73 20 2a 2f 0a 20 20 55 6e 70 61 63 6b  ords */.  Unpack
3c00: 65 64 52 65 63 6f 72 64 20 2a 70 55 6e 70 61 63  edRecord *pUnpac
3c10: 6b 65 64 3b 20 20 20 20 20 20 2f 2a 20 55 73 65  ked;      /* Use
3c20: 64 20 62 79 20 56 64 62 65 53 6f 72 74 65 72 43  d by VdbeSorterC
3c30: 6f 6d 70 61 72 65 28 29 20 2a 2f 0a 20 20 53 6f  ompare() */.  So
3c40: 72 74 65 72 4c 69 73 74 20 6c 69 73 74 3b 20 20  rterList list;  
3c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3c60: 20 4c 69 73 74 20 6f 66 20 69 6e 2d 6d 65 6d 6f   List of in-memo
3c70: 72 79 20 72 65 63 6f 72 64 73 20 2a 2f 0a 20 20  ry records */.  
3c80: 69 6e 74 20 69 4d 65 6d 6f 72 79 3b 20 20 20 20  int iMemory;    
3c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3ca0: 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20 66 72 65  /* Offset of fre
3cb0: 65 20 73 70 61 63 65 20 69 6e 20 6c 69 73 74 2e  e space in list.
3cc0: 61 4d 65 6d 6f 72 79 20 2a 2f 0a 20 20 69 6e 74  aMemory */.  int
3cd0: 20 6e 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20 20   nMemory;       
3ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3cf0: 53 69 7a 65 20 6f 66 20 6c 69 73 74 2e 61 4d 65  Size of list.aMe
3d00: 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 20  mory allocation 
3d10: 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 75 38  in bytes */.  u8
3d20: 20 62 55 73 65 50 4d 41 3b 20 20 20 20 20 20 20   bUsePMA;       
3d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3d40: 20 54 72 75 65 20 69 66 20 6f 6e 65 20 6f 72 20   True if one or 
3d50: 6d 6f 72 65 20 50 4d 41 73 20 63 72 65 61 74 65  more PMAs create
3d60: 64 20 2a 2f 0a 20 20 75 38 20 62 55 73 65 54 68  d */.  u8 bUseTh
3d70: 72 65 61 64 73 3b 20 20 20 20 20 20 20 20 20 20  reads;          
3d80: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74         /* True t
3d90: 6f 20 75 73 65 20 62 61 63 6b 67 72 6f 75 6e 64  o use background
3da0: 20 74 68 72 65 61 64 73 20 2a 2f 0a 20 20 75 38   threads */.  u8
3db0: 20 69 50 72 65 76 3b 20 20 20 20 20 20 20 20 20   iPrev;         
3dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3dd0: 20 50 72 65 76 69 6f 75 73 20 74 68 72 65 61 64   Previous thread
3de0: 20 75 73 65 64 20 74 6f 20 66 6c 75 73 68 20 50   used to flush P
3df0: 4d 41 20 2a 2f 0a 20 20 75 38 20 6e 54 61 73 6b  MA */.  u8 nTask
3e00: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
3e10: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
3e20: 6f 66 20 61 54 61 73 6b 5b 5d 20 61 72 72 61 79  of aTask[] array
3e30: 20 2a 2f 0a 20 20 75 38 20 74 79 70 65 4d 61 73   */.  u8 typeMas
3e40: 6b 3b 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b  k;.  SortSubtask
3e50: 20 61 54 61 73 6b 5b 31 5d 3b 20 20 20 20 20 20   aTask[1];      
3e60: 20 20 20 20 20 2f 2a 20 4f 6e 65 20 6f 72 20 6d       /* One or m
3e70: 6f 72 65 20 73 75 62 74 61 73 6b 73 20 2a 2f 0a  ore subtasks */.
3e80: 7d 3b 0a 0a 23 64 65 66 69 6e 65 20 53 4f 52 54  };..#define SORT
3e90: 45 52 5f 54 59 50 45 5f 49 4e 54 45 47 45 52 20  ER_TYPE_INTEGER 
3ea0: 30 78 30 31 0a 23 64 65 66 69 6e 65 20 53 4f 52  0x01.#define SOR
3eb0: 54 45 52 5f 54 59 50 45 5f 54 45 58 54 20 20 20  TER_TYPE_TEXT   
3ec0: 20 30 78 30 32 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20   0x02../*.** An 
3ed0: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20  instance of the 
3ee0: 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74  following object
3ef0: 20 69 73 20 75 73 65 64 20 74 6f 20 72 65 61 64   is used to read
3f00: 20 72 65 63 6f 72 64 73 20 6f 75 74 20 6f 66 20   records out of 
3f10: 61 0a 2a 2a 20 50 4d 41 2c 20 69 6e 20 73 6f 72  a.** PMA, in sor
3f20: 74 65 64 20 6f 72 64 65 72 2e 20 20 54 68 65 20  ted order.  The 
3f30: 6e 65 78 74 20 6b 65 79 20 74 6f 20 62 65 20 72  next key to be r
3f40: 65 61 64 20 69 73 20 63 61 63 68 65 64 20 69 6e  ead is cached in
3f50: 20 6e 4b 65 79 2f 61 4b 65 79 2e 0a 2a 2a 20 61   nKey/aKey..** a
3f60: 4b 65 79 20 6d 69 67 68 74 20 70 6f 69 6e 74 20  Key might point 
3f70: 69 6e 74 6f 20 61 4d 61 70 20 6f 72 20 69 6e 74  into aMap or int
3f80: 6f 20 61 42 75 66 66 65 72 2e 20 20 49 66 20 6e  o aBuffer.  If n
3f90: 65 69 74 68 65 72 20 6f 66 20 74 68 6f 73 65 20  either of those 
3fa0: 6c 6f 63 61 74 69 6f 6e 73 0a 2a 2a 20 63 6f 6e  locations.** con
3fb0: 74 61 69 6e 20 61 20 63 6f 6e 74 69 67 75 6f 75  tain a contiguou
3fc0: 73 20 72 65 70 72 65 73 65 6e 74 61 74 69 6f 6e  s representation
3fd0: 20 6f 66 20 74 68 65 20 6b 65 79 2c 20 74 68 65   of the key, the
3fe0: 6e 20 61 41 6c 6c 6f 63 20 69 73 20 61 6c 6c 6f  n aAlloc is allo
3ff0: 63 61 74 65 64 0a 2a 2a 20 61 6e 64 20 74 68 65  cated.** and the
4000: 20 6b 65 79 20 69 73 20 63 6f 70 69 65 64 20 69   key is copied i
4010: 6e 74 6f 20 61 41 6c 6c 6f 63 20 61 6e 64 20 61  nto aAlloc and a
4020: 4b 65 79 20 69 73 20 6d 61 64 65 20 74 6f 20 70  Key is made to p
4030: 6f 69 74 6e 20 74 6f 20 61 41 6c 6c 6f 63 2e 0a  oitn to aAlloc..
4040: 2a 2a 0a 2a 2a 20 70 46 64 3d 3d 30 20 61 74 20  **.** pFd==0 at 
4050: 45 4f 46 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50  EOF..*/.struct P
4060: 6d 61 52 65 61 64 65 72 20 7b 0a 20 20 69 36 34  maReader {.  i64
4070: 20 69 52 65 61 64 4f 66 66 3b 20 20 20 20 20 20   iReadOff;      
4080: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72           /* Curr
4090: 65 6e 74 20 72 65 61 64 20 6f 66 66 73 65 74 20  ent read offset 
40a0: 2a 2f 0a 20 20 69 36 34 20 69 45 6f 66 3b 20 20  */.  i64 iEof;  
40b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
40c0: 20 2f 2a 20 31 20 62 79 74 65 20 70 61 73 74 20   /* 1 byte past 
40d0: 45 4f 46 20 66 6f 72 20 74 68 69 73 20 50 6d 61  EOF for this Pma
40e0: 52 65 61 64 65 72 20 2a 2f 0a 20 20 69 6e 74 20  Reader */.  int 
40f0: 6e 41 6c 6c 6f 63 3b 20 20 20 20 20 20 20 20 20  nAlloc;         
4100: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
4110: 20 6f 66 20 73 70 61 63 65 20 61 74 20 61 41 6c   of space at aAl
4120: 6c 6f 63 20 2a 2f 0a 20 20 69 6e 74 20 6e 4b 65  loc */.  int nKe
4130: 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  y;              
4140: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
4150: 66 20 62 79 74 65 73 20 69 6e 20 6b 65 79 20 2a  f bytes in key *
4160: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  /.  sqlite3_file
4170: 20 2a 70 46 64 3b 20 20 20 20 20 20 20 20 20 20   *pFd;          
4180: 2f 2a 20 46 69 6c 65 20 68 61 6e 64 6c 65 20 77  /* File handle w
4190: 65 20 61 72 65 20 72 65 61 64 69 6e 67 20 66 72  e are reading fr
41a0: 6f 6d 20 2a 2f 0a 20 20 75 38 20 2a 61 41 6c 6c  om */.  u8 *aAll
41b0: 6f 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  oc;             
41c0: 20 20 20 20 2f 2a 20 53 70 61 63 65 20 66 6f 72      /* Space for
41d0: 20 61 4b 65 79 20 69 66 20 61 42 75 66 66 65 72   aKey if aBuffer
41e0: 20 61 6e 64 20 70 4d 61 70 20 77 6f 6e 74 20 77   and pMap wont w
41f0: 6f 72 6b 20 2a 2f 0a 20 20 75 38 20 2a 61 4b 65  ork */.  u8 *aKe
4200: 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  y;              
4210: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
4220: 74 6f 20 63 75 72 72 65 6e 74 20 6b 65 79 20 2a  to current key *
4230: 2f 0a 20 20 75 38 20 2a 61 42 75 66 66 65 72 3b  /.  u8 *aBuffer;
4240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4250: 2f 2a 20 43 75 72 72 65 6e 74 20 72 65 61 64 20  /* Current read 
4260: 62 75 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74 20  buffer */.  int 
4270: 6e 42 75 66 66 65 72 3b 20 20 20 20 20 20 20 20  nBuffer;        
4280: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
4290: 6f 66 20 72 65 61 64 20 62 75 66 66 65 72 20 69  of read buffer i
42a0: 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 75 38 20  n bytes */.  u8 
42b0: 2a 61 4d 61 70 3b 20 20 20 20 20 20 20 20 20 20  *aMap;          
42c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
42d0: 74 65 72 20 74 6f 20 6d 61 70 70 69 6e 67 20 6f  ter to mapping o
42e0: 66 20 65 6e 74 69 72 65 20 66 69 6c 65 20 2a 2f  f entire file */
42f0: 0a 20 20 49 6e 63 72 4d 65 72 67 65 72 20 2a 70  .  IncrMerger *p
4300: 49 6e 63 72 3b 20 20 20 20 20 20 20 20 20 20 2f  Incr;          /
4310: 2a 20 49 6e 63 72 65 6d 65 6e 74 61 6c 20 6d 65  * Incremental me
4320: 72 67 65 72 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  rger */.};../*.*
4330: 2a 20 4e 6f 72 6d 61 6c 6c 79 2c 20 61 20 50 6d  * Normally, a Pm
4340: 61 52 65 61 64 65 72 20 6f 62 6a 65 63 74 20 69  aReader object i
4350: 74 65 72 61 74 65 73 20 74 68 72 6f 75 67 68 20  terates through 
4360: 61 6e 20 65 78 69 73 74 69 6e 67 20 50 4d 41 20  an existing PMA 
4370: 73 74 6f 72 65 64 20 0a 2a 2a 20 77 69 74 68 69  stored .** withi
4380: 6e 20 61 20 74 65 6d 70 20 66 69 6c 65 2e 20 48  n a temp file. H
4390: 6f 77 65 76 65 72 2c 20 69 66 20 74 68 65 20 50  owever, if the P
43a0: 6d 61 52 65 61 64 65 72 2e 70 49 6e 63 72 20 76  maReader.pIncr v
43b0: 61 72 69 61 62 6c 65 20 70 6f 69 6e 74 73 20 74  ariable points t
43c0: 6f 0a 2a 2a 20 61 6e 20 6f 62 6a 65 63 74 20 6f  o.** an object o
43d0: 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  f the following 
43e0: 74 79 70 65 2c 20 69 74 20 6d 61 79 20 62 65 20  type, it may be 
43f0: 75 73 65 64 20 74 6f 20 69 74 65 72 61 74 65 2f  used to iterate/
4400: 6d 65 72 67 65 20 74 68 72 6f 75 67 68 0a 2a 2a  merge through.**
4410: 20 6d 75 6c 74 69 70 6c 65 20 50 4d 41 73 20 73   multiple PMAs s
4420: 69 6d 75 6c 74 61 6e 65 6f 75 73 6c 79 2e 0a 2a  imultaneously..*
4430: 2a 0a 2a 2a 20 54 68 65 72 65 20 61 72 65 20 74  *.** There are t
4440: 77 6f 20 74 79 70 65 73 20 6f 66 20 49 6e 63 72  wo types of Incr
4450: 4d 65 72 67 65 72 20 6f 62 6a 65 63 74 20 2d 20  Merger object - 
4460: 73 69 6e 67 6c 65 20 28 62 55 73 65 54 68 72 65  single (bUseThre
4470: 61 64 3d 3d 30 29 20 61 6e 64 20 0a 2a 2a 20 6d  ad==0) and .** m
4480: 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20 28 62  ulti-threaded (b
4490: 55 73 65 54 68 72 65 61 64 3d 3d 31 29 2e 20 0a  UseThread==1). .
44a0: 2a 2a 0a 2a 2a 20 41 20 6d 75 6c 74 69 2d 74 68  **.** A multi-th
44b0: 72 65 61 64 65 64 20 49 6e 63 72 4d 65 72 67 65  readed IncrMerge
44c0: 72 20 6f 62 6a 65 63 74 20 75 73 65 73 20 74 77  r object uses tw
44d0: 6f 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65  o temporary file
44e0: 73 20 2d 20 61 46 69 6c 65 5b 30 5d 20 0a 2a 2a  s - aFile[0] .**
44f0: 20 61 6e 64 20 61 46 69 6c 65 5b 31 5d 2e 20 4e   and aFile[1]. N
4500: 65 69 74 68 65 72 20 66 69 6c 65 20 69 73 20 61  either file is a
4510: 6c 6c 6f 77 65 64 20 74 6f 20 67 72 6f 77 20 74  llowed to grow t
4520: 6f 20 6d 6f 72 65 20 74 68 61 6e 20 6d 78 53 7a  o more than mxSz
4530: 20 62 79 74 65 73 20 69 6e 20 0a 2a 2a 20 73 69   bytes in .** si
4540: 7a 65 2e 20 57 68 65 6e 20 74 68 65 20 49 6e 63  ze. When the Inc
4550: 72 4d 65 72 67 65 72 20 69 73 20 69 6e 69 74 69  rMerger is initi
4560: 61 6c 69 7a 65 64 2c 20 69 74 20 72 65 61 64 73  alized, it reads
4570: 20 65 6e 6f 75 67 68 20 64 61 74 61 20 66 72 6f   enough data fro
4580: 6d 20 0a 2a 2a 20 70 4d 65 72 67 65 72 20 74 6f  m .** pMerger to
4590: 20 70 6f 70 75 6c 61 74 65 20 61 46 69 6c 65 5b   populate aFile[
45a0: 30 5d 2e 20 49 74 20 74 68 65 6e 20 73 65 74 73  0]. It then sets
45b0: 20 76 61 72 69 61 62 6c 65 73 20 77 69 74 68 69   variables withi
45c0: 6e 20 74 68 65 20 0a 2a 2a 20 63 6f 72 72 65 73  n the .** corres
45d0: 70 6f 6e 64 69 6e 67 20 50 6d 61 52 65 61 64 65  ponding PmaReade
45e0: 72 20 6f 62 6a 65 63 74 20 74 6f 20 72 65 61 64  r object to read
45f0: 20 66 72 6f 6d 20 74 68 61 74 20 66 69 6c 65 20   from that file 
4600: 61 6e 64 20 6b 69 63 6b 73 20 6f 66 66 20 0a 2a  and kicks off .*
4610: 2a 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74  * a background t
4620: 68 72 65 61 64 20 74 6f 20 70 6f 70 75 6c 61 74  hread to populat
4630: 65 20 61 46 69 6c 65 5b 31 5d 20 77 69 74 68 20  e aFile[1] with 
4640: 74 68 65 20 6e 65 78 74 20 6d 78 53 7a 20 62 79  the next mxSz by
4650: 74 65 73 20 6f 66 20 0a 2a 2a 20 73 6f 72 74 65  tes of .** sorte
4660: 64 20 72 65 63 6f 72 64 20 64 61 74 61 20 66 72  d record data fr
4670: 6f 6d 20 70 4d 65 72 67 65 72 2e 20 0a 2a 2a 0a  om pMerger. .**.
4680: 2a 2a 20 57 68 65 6e 20 74 68 65 20 50 6d 61 52  ** When the PmaR
4690: 65 61 64 65 72 20 72 65 61 63 68 65 73 20 74 68  eader reaches th
46a0: 65 20 65 6e 64 20 6f 66 20 61 46 69 6c 65 5b 30  e end of aFile[0
46b0: 5d 2c 20 69 74 20 62 6c 6f 63 6b 73 20 75 6e 74  ], it blocks unt
46c0: 69 6c 20 74 68 65 0a 2a 2a 20 62 61 63 6b 67 72  il the.** backgr
46d0: 6f 75 6e 64 20 74 68 72 65 61 64 20 68 61 73 20  ound thread has 
46e0: 66 69 6e 69 73 68 65 64 20 70 6f 70 75 6c 61 74  finished populat
46f0: 69 6e 67 20 61 46 69 6c 65 5b 31 5d 2e 20 49 74  ing aFile[1]. It
4700: 20 74 68 65 6e 20 65 78 63 68 61 6e 67 65 73 0a   then exchanges.
4710: 2a 2a 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  ** the contents 
4720: 6f 66 20 74 68 65 20 61 46 69 6c 65 5b 30 5d 20  of the aFile[0] 
4730: 61 6e 64 20 61 46 69 6c 65 5b 31 5d 20 76 61 72  and aFile[1] var
4740: 69 61 62 6c 65 73 20 77 69 74 68 69 6e 20 74 68  iables within th
4750: 69 73 20 73 74 72 75 63 74 75 72 65 2c 0a 2a 2a  is structure,.**
4760: 20 73 65 74 73 20 74 68 65 20 50 6d 61 52 65 61   sets the PmaRea
4770: 64 65 72 20 66 69 65 6c 64 73 20 74 6f 20 72 65  der fields to re
4780: 61 64 20 66 72 6f 6d 20 74 68 65 20 6e 65 77 20  ad from the new 
4790: 61 46 69 6c 65 5b 30 5d 20 61 6e 64 20 6b 69 63  aFile[0] and kic
47a0: 6b 73 20 6f 66 66 0a 2a 2a 20 61 6e 6f 74 68 65  ks off.** anothe
47b0: 72 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  r background thr
47c0: 65 61 64 20 74 6f 20 70 6f 70 75 6c 61 74 65 20  ead to populate 
47d0: 74 68 65 20 6e 65 77 20 61 46 69 6c 65 5b 31 5d  the new aFile[1]
47e0: 2e 20 41 6e 64 20 73 6f 20 6f 6e 2c 20 75 6e 74  . And so on, unt
47f0: 69 6c 0a 2a 2a 20 74 68 65 20 63 6f 6e 74 65 6e  il.** the conten
4800: 74 73 20 6f 66 20 70 4d 65 72 67 65 72 20 61 72  ts of pMerger ar
4810: 65 20 65 78 68 61 75 73 74 65 64 2e 0a 2a 2a 0a  e exhausted..**.
4820: 2a 2a 20 41 20 73 69 6e 67 6c 65 2d 74 68 72 65  ** A single-thre
4830: 61 64 65 64 20 49 6e 63 72 4d 65 72 67 65 72 20  aded IncrMerger 
4840: 64 6f 65 73 20 6e 6f 74 20 6f 70 65 6e 20 61 6e  does not open an
4850: 79 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65  y temporary file
4860: 73 20 6f 66 20 69 74 73 0a 2a 2a 20 6f 77 6e 2e  s of its.** own.
4870: 20 49 6e 73 74 65 61 64 2c 20 69 74 20 68 61 73   Instead, it has
4880: 20 65 78 63 6c 75 73 69 76 65 20 61 63 63 65 73   exclusive acces
4890: 73 20 74 6f 20 6d 78 53 7a 20 62 79 74 65 73 20  s to mxSz bytes 
48a0: 6f 66 20 73 70 61 63 65 20 62 65 67 69 6e 6e 69  of space beginni
48b0: 6e 67 0a 2a 2a 20 61 74 20 6f 66 66 73 65 74 20  ng.** at offset 
48c0: 69 53 74 61 72 74 4f 66 66 20 6f 66 20 66 69 6c  iStartOff of fil
48d0: 65 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 20  e pTask->file2. 
48e0: 41 6e 64 20 69 6e 73 74 65 61 64 20 6f 66 20 75  And instead of u
48f0: 73 69 6e 67 20 61 20 0a 2a 2a 20 62 61 63 6b 67  sing a .** backg
4900: 72 6f 75 6e 64 20 74 68 72 65 61 64 20 74 6f 20  round thread to 
4910: 70 72 65 70 61 72 65 20 64 61 74 61 20 66 6f 72  prepare data for
4920: 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 2c 20   the PmaReader, 
4930: 77 69 74 68 20 61 20 73 69 6e 67 6c 65 0a 2a 2a  with a single.**
4940: 20 74 68 72 65 61 64 65 64 20 49 6e 63 72 4d 65   threaded IncrMe
4950: 72 67 65 72 20 74 68 65 20 61 6c 6c 6f 63 61 74  rger the allocat
4960: 65 20 70 61 72 74 20 6f 66 20 70 54 61 73 6b 2d  e part of pTask-
4970: 3e 66 69 6c 65 32 20 69 73 20 22 72 65 66 69 6c  >file2 is "refil
4980: 6c 65 64 22 20 77 69 74 68 0a 2a 2a 20 6b 65 79  led" with.** key
4990: 73 20 66 72 6f 6d 20 70 4d 65 72 67 65 72 20 62  s from pMerger b
49a0: 79 20 74 68 65 20 63 61 6c 6c 69 6e 67 20 74 68  y the calling th
49b0: 72 65 61 64 20 77 68 65 6e 65 76 65 72 20 74 68  read whenever th
49c0: 65 20 50 6d 61 52 65 61 64 65 72 20 72 75 6e 73  e PmaReader runs
49d0: 20 6f 75 74 0a 2a 2a 20 6f 66 20 64 61 74 61 2e   out.** of data.
49e0: 0a 2a 2f 0a 73 74 72 75 63 74 20 49 6e 63 72 4d  .*/.struct IncrM
49f0: 65 72 67 65 72 20 7b 0a 20 20 53 6f 72 74 53 75  erger {.  SortSu
4a00: 62 74 61 73 6b 20 2a 70 54 61 73 6b 3b 20 20 20  btask *pTask;   
4a10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61 73            /* Tas
4a20: 6b 20 74 68 61 74 20 6f 77 6e 73 20 74 68 69 73  k that owns this
4a30: 20 6d 65 72 67 65 72 20 2a 2f 0a 20 20 4d 65 72   merger */.  Mer
4a40: 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67 65  geEngine *pMerge
4a50: 72 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  r;           /* 
4a60: 4d 65 72 67 65 20 65 6e 67 69 6e 65 20 74 68 72  Merge engine thr
4a70: 65 61 64 20 72 65 61 64 73 20 64 61 74 61 20 66  ead reads data f
4a80: 72 6f 6d 20 2a 2f 0a 20 20 69 36 34 20 69 53 74  rom */.  i64 iSt
4a90: 61 72 74 4f 66 66 3b 20 20 20 20 20 20 20 20 20  artOff;         
4aa0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73           /* Offs
4ab0: 65 74 20 74 6f 20 73 74 61 72 74 20 77 72 69 74  et to start writ
4ac0: 69 6e 67 20 66 69 6c 65 20 61 74 20 2a 2f 0a 20  ing file at */. 
4ad0: 20 69 6e 74 20 6d 78 53 7a 3b 20 20 20 20 20 20   int mxSz;      
4ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4af0: 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 62 79 74 65   /* Maximum byte
4b00: 73 20 6f 66 20 64 61 74 61 20 74 6f 20 73 74 6f  s of data to sto
4b10: 72 65 20 2a 2f 0a 20 20 69 6e 74 20 62 45 6f 66  re */.  int bEof
4b20: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4b30: 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74 20 74          /* Set t
4b40: 6f 20 74 72 75 65 20 77 68 65 6e 20 6d 65 72 67  o true when merg
4b50: 65 20 69 73 20 66 69 6e 69 73 68 65 64 20 2a 2f  e is finished */
4b60: 0a 20 20 69 6e 74 20 62 55 73 65 54 68 72 65 61  .  int bUseThrea
4b70: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
4b80: 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 75 73     /* True to us
4b90: 65 20 61 20 62 67 20 74 68 72 65 61 64 20 66 6f  e a bg thread fo
4ba0: 72 20 74 68 69 73 20 6f 62 6a 65 63 74 20 2a 2f  r this object */
4bb0: 0a 20 20 53 6f 72 74 65 72 46 69 6c 65 20 61 46  .  SorterFile aF
4bc0: 69 6c 65 5b 32 5d 3b 20 20 20 20 20 20 20 20 20  ile[2];         
4bd0: 20 20 20 2f 2a 20 61 46 69 6c 65 5b 30 5d 20 66     /* aFile[0] f
4be0: 6f 72 20 72 65 61 64 69 6e 67 2c 20 5b 31 5d 20  or reading, [1] 
4bf0: 66 6f 72 20 77 72 69 74 69 6e 67 20 2a 2f 0a 7d  for writing */.}
4c00: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73 74  ;../*.** An inst
4c10: 61 6e 63 65 20 6f 66 20 74 68 69 73 20 6f 62 6a  ance of this obj
4c20: 65 63 74 20 69 73 20 75 73 65 64 20 66 6f 72 20  ect is used for 
4c30: 77 72 69 74 69 6e 67 20 61 20 50 4d 41 2e 0a 2a  writing a PMA..*
4c40: 2a 0a 2a 2a 20 54 68 65 20 50 4d 41 20 69 73 20  *.** The PMA is 
4c50: 77 72 69 74 74 65 6e 20 6f 6e 65 20 72 65 63 6f  written one reco
4c60: 72 64 20 61 74 20 61 20 74 69 6d 65 2e 20 20 45  rd at a time.  E
4c70: 61 63 68 20 72 65 63 6f 72 64 20 69 73 20 6f 66  ach record is of
4c80: 20 61 6e 20 61 72 62 69 74 72 61 72 79 0a 2a 2a   an arbitrary.**
4c90: 20 73 69 7a 65 2e 20 20 42 75 74 20 49 2f 4f 20   size.  But I/O 
4ca0: 69 73 20 6d 6f 72 65 20 65 66 66 69 63 69 65 6e  is more efficien
4cb0: 74 20 69 66 20 69 74 20 6f 63 63 75 72 73 20 69  t if it occurs i
4cc0: 6e 20 70 61 67 65 2d 73 69 7a 65 64 20 62 6c 6f  n page-sized blo
4cd0: 63 6b 73 20 77 68 65 72 65 0a 2a 2a 20 65 61 63  cks where.** eac
4ce0: 68 20 62 6c 6f 63 6b 20 69 73 20 61 6c 69 67 6e  h block is align
4cf0: 65 64 20 6f 6e 20 61 20 70 61 67 65 20 62 6f 75  ed on a page bou
4d00: 6e 64 61 72 79 2e 20 20 54 68 69 73 20 6f 62 6a  ndary.  This obj
4d10: 65 63 74 20 63 61 63 68 65 73 20 77 72 69 74 65  ect caches write
4d20: 73 20 74 6f 0a 2a 2a 20 74 68 65 20 50 4d 41 20  s to.** the PMA 
4d30: 73 6f 20 74 68 61 74 20 61 6c 69 67 6e 65 64 2c  so that aligned,
4d40: 20 70 61 67 65 2d 73 69 7a 65 20 62 6c 6f 63 6b   page-size block
4d50: 73 20 61 72 65 20 77 72 69 74 74 65 6e 2e 0a 2a  s are written..*
4d60: 2f 0a 73 74 72 75 63 74 20 50 6d 61 57 72 69 74  /.struct PmaWrit
4d70: 65 72 20 7b 0a 20 20 69 6e 74 20 65 46 57 45 72  er {.  int eFWEr
4d80: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
4d90: 20 20 20 20 20 20 20 2f 2a 20 4e 6f 6e 2d 7a 65         /* Non-ze
4da0: 72 6f 20 69 66 20 69 6e 20 61 6e 20 65 72 72 6f  ro if in an erro
4db0: 72 20 73 74 61 74 65 20 2a 2f 0a 20 20 75 38 20  r state */.  u8 
4dc0: 2a 61 42 75 66 66 65 72 3b 20 20 20 20 20 20 20  *aBuffer;       
4dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4de0: 50 6f 69 6e 74 65 72 20 74 6f 20 77 72 69 74 65  Pointer to write
4df0: 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74   buffer */.  int
4e00: 20 6e 42 75 66 66 65 72 3b 20 20 20 20 20 20 20   nBuffer;       
4e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4e20: 53 69 7a 65 20 6f 66 20 77 72 69 74 65 20 62 75  Size of write bu
4e30: 66 66 65 72 20 69 6e 20 62 79 74 65 73 20 2a 2f  ffer in bytes */
4e40: 0a 20 20 69 6e 74 20 69 42 75 66 53 74 61 72 74  .  int iBufStart
4e50: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4e60: 20 20 20 2f 2a 20 46 69 72 73 74 20 62 79 74 65     /* First byte
4e70: 20 6f 66 20 62 75 66 66 65 72 20 74 6f 20 77 72   of buffer to wr
4e80: 69 74 65 20 2a 2f 0a 20 20 69 6e 74 20 69 42 75  ite */.  int iBu
4e90: 66 45 6e 64 3b 20 20 20 20 20 20 20 20 20 20 20  fEnd;           
4ea0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 73 74           /* Last
4eb0: 20 62 79 74 65 20 6f 66 20 62 75 66 66 65 72 20   byte of buffer 
4ec0: 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 69 36  to write */.  i6
4ed0: 34 20 69 57 72 69 74 65 4f 66 66 3b 20 20 20 20  4 iWriteOff;    
4ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4ef0: 20 4f 66 66 73 65 74 20 6f 66 20 73 74 61 72 74   Offset of start
4f00: 20 6f 66 20 62 75 66 66 65 72 20 69 6e 20 66 69   of buffer in fi
4f10: 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  le */.  sqlite3_
4f20: 66 69 6c 65 20 2a 70 46 64 3b 20 20 20 20 20 20  file *pFd;      
4f30: 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20          /* File 
4f40: 68 61 6e 64 6c 65 20 74 6f 20 77 72 69 74 65 20  handle to write 
4f50: 74 6f 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  to */.};../*.** 
4f60: 54 68 69 73 20 6f 62 6a 65 63 74 20 69 73 20 74  This object is t
4f70: 68 65 20 68 65 61 64 65 72 20 6f 6e 20 61 20 73  he header on a s
4f80: 69 6e 67 6c 65 20 72 65 63 6f 72 64 20 77 68 69  ingle record whi
4f90: 6c 65 20 74 68 61 74 20 72 65 63 6f 72 64 20 69  le that record i
4fa0: 73 20 62 65 69 6e 67 0a 2a 2a 20 68 65 6c 64 20  s being.** held 
4fb0: 69 6e 20 6d 65 6d 6f 72 79 20 61 6e 64 20 70 72  in memory and pr
4fc0: 69 6f 72 20 74 6f 20 62 65 69 6e 67 20 77 72 69  ior to being wri
4fd0: 74 74 65 6e 20 6f 75 74 20 61 73 20 70 61 72 74  tten out as part
4fe0: 20 6f 66 20 61 20 50 4d 41 2e 0a 2a 2a 0a 2a 2a   of a PMA..**.**
4ff0: 20 48 6f 77 20 74 68 65 20 6c 69 6e 6b 65 64 20   How the linked 
5000: 6c 69 73 74 20 69 73 20 63 6f 6e 6e 65 63 74 65  list is connecte
5010: 64 20 64 65 70 65 6e 64 73 20 6f 6e 20 68 6f 77  d depends on how
5020: 20 6d 65 6d 6f 72 79 20 69 73 20 62 65 69 6e 67   memory is being
5030: 20 6d 61 6e 61 67 65 64 0a 2a 2a 20 62 79 20 74   managed.** by t
5040: 68 69 73 20 6d 6f 64 75 6c 65 2e 20 49 66 20 75  his module. If u
5050: 73 69 6e 67 20 61 20 73 65 70 61 72 61 74 65 20  sing a separate 
5060: 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 6f 72 20 65  allocation for e
5070: 61 63 68 20 69 6e 2d 6d 65 6d 6f 72 79 20 72 65  ach in-memory re
5080: 63 6f 72 64 0a 2a 2a 20 28 56 64 62 65 53 6f 72  cord.** (VdbeSor
5090: 74 65 72 2e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  ter.list.aMemory
50a0: 3d 3d 30 29 2c 20 74 68 65 6e 20 74 68 65 20 6c  ==0), then the l
50b0: 69 73 74 20 69 73 20 61 6c 77 61 79 73 20 63 6f  ist is always co
50c0: 6e 6e 65 63 74 65 64 20 75 73 69 6e 67 20 74 68  nnected using th
50d0: 65 0a 2a 2a 20 53 6f 72 74 65 72 52 65 63 6f 72  e.** SorterRecor
50e0: 64 2e 75 2e 70 4e 65 78 74 20 70 6f 69 6e 74 65  d.u.pNext pointe
50f0: 72 73 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 69 66  rs..**.** Or, if
5100: 20 75 73 69 6e 67 20 74 68 65 20 73 69 6e 67 6c   using the singl
5110: 65 20 6c 61 72 67 65 20 61 6c 6c 6f 63 61 74 69  e large allocati
5120: 6f 6e 20 6d 65 74 68 6f 64 20 28 56 64 62 65 53  on method (VdbeS
5130: 6f 72 74 65 72 2e 6c 69 73 74 2e 61 4d 65 6d 6f  orter.list.aMemo
5140: 72 79 21 3d 30 29 2c 0a 2a 2a 20 74 68 65 6e 20  ry!=0),.** then 
5150: 77 68 69 6c 65 20 72 65 63 6f 72 64 73 20 61 72  while records ar
5160: 65 20 62 65 69 6e 67 20 61 63 63 75 6d 75 6c 61  e being accumula
5170: 74 65 64 20 74 68 65 20 6c 69 73 74 20 69 73 20  ted the list is 
5180: 6c 69 6e 6b 65 64 20 75 73 69 6e 67 20 74 68 65  linked using the
5190: 0a 2a 2a 20 53 6f 72 74 65 72 52 65 63 6f 72 64  .** SorterRecord
51a0: 2e 75 2e 69 4e 65 78 74 20 6f 66 66 73 65 74 2e  .u.iNext offset.
51b0: 20 54 68 69 73 20 69 73 20 62 65 63 61 75 73 65   This is because
51c0: 20 74 68 65 20 61 4d 65 6d 6f 72 79 5b 5d 20 61   the aMemory[] a
51d0: 72 72 61 79 20 6d 61 79 0a 2a 2a 20 62 65 20 73  rray may.** be s
51e0: 71 6c 69 74 65 33 52 65 61 6c 6c 6f 63 28 29 65  qlite3Realloc()e
51f0: 64 20 77 68 69 6c 65 20 72 65 63 6f 72 64 73 20  d while records 
5200: 61 72 65 20 62 65 69 6e 67 20 61 63 63 75 6d 75  are being accumu
5210: 6c 61 74 65 64 2e 20 4f 6e 63 65 20 74 68 65 20  lated. Once the 
5220: 56 4d 0a 2a 2a 20 68 61 73 20 66 69 6e 69 73 68  VM.** has finish
5230: 65 64 20 70 61 73 73 69 6e 67 20 72 65 63 6f 72  ed passing recor
5240: 64 73 20 74 6f 20 74 68 65 20 73 6f 72 74 65 72  ds to the sorter
5250: 2c 20 6f 72 20 77 68 65 6e 20 74 68 65 20 69 6e  , or when the in
5260: 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65 72 0a 2a  -memory buffer.*
5270: 2a 20 69 73 20 66 75 6c 6c 2c 20 74 68 65 20 6c  * is full, the l
5280: 69 73 74 20 69 73 20 73 6f 72 74 65 64 2e 20 41  ist is sorted. A
5290: 73 20 70 61 72 74 20 6f 66 20 74 68 65 20 73 6f  s part of the so
52a0: 72 74 69 6e 67 20 70 72 6f 63 65 73 73 2c 20 69  rting process, i
52b0: 74 20 69 73 0a 2a 2a 20 63 6f 6e 76 65 72 74 65  t is.** converte
52c0: 64 20 74 6f 20 75 73 65 20 74 68 65 20 53 6f 72  d to use the Sor
52d0: 74 65 72 52 65 63 6f 72 64 2e 75 2e 70 4e 65 78  terRecord.u.pNex
52e0: 74 20 70 6f 69 6e 74 65 72 73 2e 20 53 65 65 20  t pointers. See 
52f0: 66 75 6e 63 74 69 6f 6e 0a 2a 2a 20 76 64 62 65  function.** vdbe
5300: 53 6f 72 74 65 72 53 6f 72 74 28 29 20 66 6f 72  SorterSort() for
5310: 20 64 65 74 61 69 6c 73 2e 0a 2a 2f 0a 73 74 72   details..*/.str
5320: 75 63 74 20 53 6f 72 74 65 72 52 65 63 6f 72 64  uct SorterRecord
5330: 20 7b 0a 20 20 69 6e 74 20 6e 56 61 6c 3b 20 20   {.  int nVal;  
5340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5350: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
5360: 74 68 65 20 72 65 63 6f 72 64 20 69 6e 20 62 79  the record in by
5370: 74 65 73 20 2a 2f 0a 20 20 75 6e 69 6f 6e 20 7b  tes */.  union {
5380: 0a 20 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72  .    SorterRecor
5390: 64 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20  d *pNext;       
53a0: 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
53b0: 20 6e 65 78 74 20 72 65 63 6f 72 64 20 69 6e 20   next record in 
53c0: 6c 69 73 74 20 2a 2f 0a 20 20 20 20 69 6e 74 20  list */.    int 
53d0: 69 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20 20  iNext;          
53e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66            /* Off
53f0: 73 65 74 20 77 69 74 68 69 6e 20 61 4d 65 6d 6f  set within aMemo
5400: 72 79 20 6f 66 20 6e 65 78 74 20 72 65 63 6f 72  ry of next recor
5410: 64 20 2a 2f 0a 20 20 7d 20 75 3b 0a 20 20 2f 2a  d */.  } u;.  /*
5420: 20 54 68 65 20 64 61 74 61 20 66 6f 72 20 74 68   The data for th
5430: 65 20 72 65 63 6f 72 64 20 69 6d 6d 65 64 69 61  e record immedia
5440: 74 65 6c 79 20 66 6f 6c 6c 6f 77 73 20 74 68 69  tely follows thi
5450: 73 20 68 65 61 64 65 72 20 2a 2f 0a 7d 3b 0a 0a  s header */.};..
5460: 2f 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e  /* Return a poin
5470: 74 65 72 20 74 6f 20 74 68 65 20 62 75 66 66 65  ter to the buffe
5480: 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65  r containing the
5490: 20 72 65 63 6f 72 64 20 64 61 74 61 20 66 6f 72   record data for
54a0: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 0a 2a 2a   SorterRecord.**
54b0: 20 6f 62 6a 65 63 74 20 70 2e 20 53 68 6f 75 6c   object p. Shoul
54c0: 64 20 62 65 20 75 73 65 64 20 61 73 20 69 66 3a  d be used as if:
54d0: 0a 2a 2a 0a 2a 2a 20 20 20 76 6f 69 64 20 2a 53  .**.**   void *S
54e0: 52 56 41 4c 28 53 6f 72 74 65 72 52 65 63 6f 72  RVAL(SorterRecor
54f0: 64 20 2a 70 29 20 7b 20 72 65 74 75 72 6e 20 28  d *p) { return (
5500: 76 6f 69 64 2a 29 26 70 5b 31 5d 3b 20 7d 0a 2a  void*)&p[1]; }.*
5510: 2f 0a 23 64 65 66 69 6e 65 20 53 52 56 41 4c 28  /.#define SRVAL(
5520: 70 29 20 28 28 76 6f 69 64 2a 29 28 28 53 6f 72  p) ((void*)((Sor
5530: 74 65 72 52 65 63 6f 72 64 2a 29 28 70 29 20 2b  terRecord*)(p) +
5540: 20 31 29 29 0a 0a 0a 2f 2a 20 4d 61 78 69 6d 75   1)).../* Maximu
5550: 6d 20 6e 75 6d 62 65 72 20 6f 66 20 50 4d 41 73  m number of PMAs
5560: 20 74 68 61 74 20 61 20 73 69 6e 67 6c 65 20 4d   that a single M
5570: 65 72 67 65 45 6e 67 69 6e 65 20 63 61 6e 20 6d  ergeEngine can m
5580: 65 72 67 65 20 2a 2f 0a 23 64 65 66 69 6e 65 20  erge */.#define 
5590: 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45  SORTER_MAX_MERGE
55a0: 5f 43 4f 55 4e 54 20 31 36 0a 0a 73 74 61 74 69  _COUNT 16..stati
55b0: 63 20 69 6e 74 20 76 64 62 65 49 6e 63 72 53 77  c int vdbeIncrSw
55c0: 61 70 28 49 6e 63 72 4d 65 72 67 65 72 2a 29 3b  ap(IncrMerger*);
55d0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62  .static void vdb
55e0: 65 49 6e 63 72 46 72 65 65 28 49 6e 63 72 4d 65  eIncrFree(IncrMe
55f0: 72 67 65 72 20 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20  rger *);../*.** 
5600: 46 72 65 65 20 61 6c 6c 20 6d 65 6d 6f 72 79 20  Free all memory 
5610: 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 74 68 65  belonging to the
5620: 20 50 6d 61 52 65 61 64 65 72 20 6f 62 6a 65 63   PmaReader objec
5630: 74 20 70 61 73 73 65 64 20 61 73 20 74 68 65 0a  t passed as the.
5640: 2a 2a 20 61 72 67 75 6d 65 6e 74 2e 20 41 6c 6c  ** argument. All
5650: 20 73 74 72 75 63 74 75 72 65 20 66 69 65 6c 64   structure field
5660: 73 20 61 72 65 20 73 65 74 20 74 6f 20 7a 65 72  s are set to zer
5670: 6f 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69  o before returni
5680: 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ng..*/.static vo
5690: 69 64 20 76 64 62 65 50 6d 61 52 65 61 64 65 72  id vdbePmaReader
56a0: 43 6c 65 61 72 28 50 6d 61 52 65 61 64 65 72 20  Clear(PmaReader 
56b0: 2a 70 52 65 61 64 72 29 7b 0a 20 20 73 71 6c 69  *pReadr){.  sqli
56c0: 74 65 33 5f 66 72 65 65 28 70 52 65 61 64 72 2d  te3_free(pReadr-
56d0: 3e 61 41 6c 6c 6f 63 29 3b 0a 20 20 73 71 6c 69  >aAlloc);.  sqli
56e0: 74 65 33 5f 66 72 65 65 28 70 52 65 61 64 72 2d  te3_free(pReadr-
56f0: 3e 61 42 75 66 66 65 72 29 3b 0a 20 20 69 66 28  >aBuffer);.  if(
5700: 20 70 52 65 61 64 72 2d 3e 61 4d 61 70 20 29 20   pReadr->aMap ) 
5710: 73 71 6c 69 74 65 33 4f 73 55 6e 66 65 74 63 68  sqlite3OsUnfetch
5720: 28 70 52 65 61 64 72 2d 3e 70 46 64 2c 20 30 2c  (pReadr->pFd, 0,
5730: 20 70 52 65 61 64 72 2d 3e 61 4d 61 70 29 3b 0a   pReadr->aMap);.
5740: 20 20 76 64 62 65 49 6e 63 72 46 72 65 65 28 70    vdbeIncrFree(p
5750: 52 65 61 64 72 2d 3e 70 49 6e 63 72 29 3b 0a 20  Readr->pIncr);. 
5760: 20 6d 65 6d 73 65 74 28 70 52 65 61 64 72 2c 20   memset(pReadr, 
5770: 30 2c 20 73 69 7a 65 6f 66 28 50 6d 61 52 65 61  0, sizeof(PmaRea
5780: 64 65 72 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  der));.}../*.** 
5790: 52 65 61 64 20 74 68 65 20 6e 65 78 74 20 6e 42  Read the next nB
57a0: 79 74 65 20 62 79 74 65 73 20 6f 66 20 64 61 74  yte bytes of dat
57b0: 61 20 66 72 6f 6d 20 74 68 65 20 50 4d 41 20 70  a from the PMA p
57c0: 2e 0a 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66  ..** If successf
57d0: 75 6c 2c 20 73 65 74 20 2a 70 70 4f 75 74 20 74  ul, set *ppOut t
57e0: 6f 20 70 6f 69 6e 74 20 74 6f 20 61 20 62 75 66  o point to a buf
57f0: 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74  fer containing t
5800: 68 65 20 64 61 74 61 0a 2a 2a 20 61 6e 64 20 72  he data.** and r
5810: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e  eturn SQLITE_OK.
5820: 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20 61   Otherwise, if a
5830: 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20  n error occurs, 
5840: 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74 65  return an SQLite
5850: 0a 2a 2a 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a  .** error code..
5860: 2a 2a 0a 2a 2a 20 54 68 65 20 62 75 66 66 65 72  **.** The buffer
5870: 20 72 65 74 75 72 6e 65 64 20 69 6e 20 2a 70 70   returned in *pp
5880: 4f 75 74 20 69 73 20 6f 6e 6c 79 20 76 61 6c 69  Out is only vali
5890: 64 20 75 6e 74 69 6c 20 74 68 65 0a 2a 2a 20 6e  d until the.** n
58a0: 65 78 74 20 63 61 6c 6c 20 74 6f 20 74 68 69 73  ext call to this
58b0: 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74   function..*/.st
58c0: 61 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d 61  atic int vdbePma
58d0: 52 65 61 64 42 6c 6f 62 28 0a 20 20 50 6d 61 52  ReadBlob(.  PmaR
58e0: 65 61 64 65 72 20 2a 70 2c 20 20 20 20 20 20 20  eader *p,       
58f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
5900: 6d 61 52 65 61 64 65 72 20 66 72 6f 6d 20 77 68  maReader from wh
5910: 69 63 68 20 74 6f 20 74 61 6b 65 20 74 68 65 20  ich to take the 
5920: 62 6c 6f 62 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  blob */.  int nB
5930: 79 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  yte,            
5940: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74            /* Byt
5950: 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 72 65  es of data to re
5960: 61 64 20 2a 2f 0a 20 20 75 38 20 2a 2a 70 70 4f  ad */.  u8 **ppO
5970: 75 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ut              
5980: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
5990: 50 6f 69 6e 74 65 72 20 74 6f 20 62 75 66 66 65  Pointer to buffe
59a0: 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64 61 74  r containing dat
59b0: 61 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 42  a */.){.  int iB
59c0: 75 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  uf;             
59d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66            /* Off
59e0: 73 65 74 20 77 69 74 68 69 6e 20 62 75 66 66 65  set within buffe
59f0: 72 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a  r to read from *
5a00: 2f 0a 20 20 69 6e 74 20 6e 41 76 61 69 6c 3b 20  /.  int nAvail; 
5a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a20: 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20      /* Bytes of 
5a30: 64 61 74 61 20 61 76 61 69 6c 61 62 6c 65 20 69  data available i
5a40: 6e 20 62 75 66 66 65 72 20 2a 2f 0a 0a 20 20 69  n buffer */..  i
5a50: 66 28 20 70 2d 3e 61 4d 61 70 20 29 7b 0a 20 20  f( p->aMap ){.  
5a60: 20 20 2a 70 70 4f 75 74 20 3d 20 26 70 2d 3e 61    *ppOut = &p->a
5a70: 4d 61 70 5b 70 2d 3e 69 52 65 61 64 4f 66 66 5d  Map[p->iReadOff]
5a80: 3b 0a 20 20 20 20 70 2d 3e 69 52 65 61 64 4f 66  ;.    p->iReadOf
5a90: 66 20 2b 3d 20 6e 42 79 74 65 3b 0a 20 20 20 20  f += nByte;.    
5aa0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
5ab0: 3b 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 28  ;.  }..  assert(
5ac0: 20 70 2d 3e 61 42 75 66 66 65 72 20 29 3b 0a 0a   p->aBuffer );..
5ad0: 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20 69 73    /* If there is
5ae0: 20 6e 6f 20 6d 6f 72 65 20 64 61 74 61 20 74 6f   no more data to
5af0: 20 62 65 20 72 65 61 64 20 66 72 6f 6d 20 74 68   be read from th
5b00: 65 20 62 75 66 66 65 72 2c 20 72 65 61 64 20 74  e buffer, read t
5b10: 68 65 20 6e 65 78 74 20 0a 20 20 2a 2a 20 70 2d  he next .  ** p-
5b20: 3e 6e 42 75 66 66 65 72 20 62 79 74 65 73 20 6f  >nBuffer bytes o
5b30: 66 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20  f data from the 
5b40: 66 69 6c 65 20 69 6e 74 6f 20 69 74 2e 20 4f 72  file into it. Or
5b50: 2c 20 69 66 20 74 68 65 72 65 20 61 72 65 20 6c  , if there are l
5b60: 65 73 73 0a 20 20 2a 2a 20 74 68 61 6e 20 70 2d  ess.  ** than p-
5b70: 3e 6e 42 75 66 66 65 72 20 62 79 74 65 73 20 72  >nBuffer bytes r
5b80: 65 6d 61 69 6e 69 6e 67 20 69 6e 20 74 68 65 20  emaining in the 
5b90: 50 4d 41 2c 20 72 65 61 64 20 61 6c 6c 20 72 65  PMA, read all re
5ba0: 6d 61 69 6e 69 6e 67 20 64 61 74 61 2e 20 20 2a  maining data.  *
5bb0: 2f 0a 20 20 69 42 75 66 20 3d 20 70 2d 3e 69 52  /.  iBuf = p->iR
5bc0: 65 61 64 4f 66 66 20 25 20 70 2d 3e 6e 42 75 66  eadOff % p->nBuf
5bd0: 66 65 72 3b 0a 20 20 69 66 28 20 69 42 75 66 3d  fer;.  if( iBuf=
5be0: 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 52  =0 ){.    int nR
5bf0: 65 61 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  ead;            
5c00: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
5c10: 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 64 69   to read from di
5c20: 73 6b 20 2a 2f 0a 20 20 20 20 69 6e 74 20 72 63  sk */.    int rc
5c30: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
5c40: 20 20 20 20 20 20 20 20 2f 2a 20 73 71 6c 69 74          /* sqlit
5c50: 65 33 4f 73 52 65 61 64 28 29 20 72 65 74 75 72  e3OsRead() retur
5c60: 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 20 20 2f  n code */..    /
5c70: 2a 20 44 65 74 65 72 6d 69 6e 65 20 68 6f 77 20  * Determine how 
5c80: 6d 61 6e 79 20 62 79 74 65 73 20 6f 66 20 64 61  many bytes of da
5c90: 74 61 20 74 6f 20 72 65 61 64 2e 20 2a 2f 0a 20  ta to read. */. 
5ca0: 20 20 20 69 66 28 20 28 70 2d 3e 69 45 6f 66 20     if( (p->iEof 
5cb0: 2d 20 70 2d 3e 69 52 65 61 64 4f 66 66 29 20 3e  - p->iReadOff) >
5cc0: 20 28 69 36 34 29 70 2d 3e 6e 42 75 66 66 65 72   (i64)p->nBuffer
5cd0: 20 29 7b 0a 20 20 20 20 20 20 6e 52 65 61 64 20   ){.      nRead 
5ce0: 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20  = p->nBuffer;.  
5cf0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6e    }else{.      n
5d00: 52 65 61 64 20 3d 20 28 69 6e 74 29 28 70 2d 3e  Read = (int)(p->
5d10: 69 45 6f 66 20 2d 20 70 2d 3e 69 52 65 61 64 4f  iEof - p->iReadO
5d20: 66 66 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61  ff);.    }.    a
5d30: 73 73 65 72 74 28 20 6e 52 65 61 64 3e 30 20 29  ssert( nRead>0 )
5d40: 3b 0a 0a 20 20 20 20 2f 2a 20 52 65 61 64 72 20  ;..    /* Readr 
5d50: 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 66 69  data from the fi
5d60: 6c 65 2e 20 52 65 74 75 72 6e 20 65 61 72 6c 79  le. Return early
5d70: 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   if an error occ
5d80: 75 72 73 2e 20 2a 2f 0a 20 20 20 20 72 63 20 3d  urs. */.    rc =
5d90: 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70   sqlite3OsRead(p
5da0: 2d 3e 70 46 64 2c 20 70 2d 3e 61 42 75 66 66 65  ->pFd, p->aBuffe
5db0: 72 2c 20 6e 52 65 61 64 2c 20 70 2d 3e 69 52 65  r, nRead, p->iRe
5dc0: 61 64 4f 66 66 29 3b 0a 20 20 20 20 61 73 73 65  adOff);.    asse
5dd0: 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 49  rt( rc!=SQLITE_I
5de0: 4f 45 52 52 5f 53 48 4f 52 54 5f 52 45 41 44 20  OERR_SHORT_READ 
5df0: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53  );.    if( rc!=S
5e00: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
5e10: 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 6e 41 76 61  n rc;.  }.  nAva
5e20: 69 6c 20 3d 20 70 2d 3e 6e 42 75 66 66 65 72 20  il = p->nBuffer 
5e30: 2d 20 69 42 75 66 3b 20 0a 0a 20 20 69 66 28 20  - iBuf; ..  if( 
5e40: 6e 42 79 74 65 3c 3d 6e 41 76 61 69 6c 20 29 7b  nByte<=nAvail ){
5e50: 0a 20 20 20 20 2f 2a 20 54 68 65 20 72 65 71 75  .    /* The requ
5e60: 65 73 74 65 64 20 64 61 74 61 20 69 73 20 61 76  ested data is av
5e70: 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65 20 69  ailable in the i
5e80: 6e 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65 72 2e  n-memory buffer.
5e90: 20 49 6e 20 74 68 69 73 0a 20 20 20 20 2a 2a 20   In this.    ** 
5ea0: 63 61 73 65 20 74 68 65 72 65 20 69 73 20 6e 6f  case there is no
5eb0: 20 6e 65 65 64 20 74 6f 20 6d 61 6b 65 20 61 20   need to make a 
5ec0: 63 6f 70 79 20 6f 66 20 74 68 65 20 64 61 74 61  copy of the data
5ed0: 2c 20 6a 75 73 74 20 72 65 74 75 72 6e 20 61 20  , just return a 
5ee0: 0a 20 20 20 20 2a 2a 20 70 6f 69 6e 74 65 72 20  .    ** pointer 
5ef0: 69 6e 74 6f 20 74 68 65 20 62 75 66 66 65 72 20  into the buffer 
5f00: 74 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 20  to the caller.  
5f10: 2a 2f 0a 20 20 20 20 2a 70 70 4f 75 74 20 3d 20  */.    *ppOut = 
5f20: 26 70 2d 3e 61 42 75 66 66 65 72 5b 69 42 75 66  &p->aBuffer[iBuf
5f30: 5d 3b 0a 20 20 20 20 70 2d 3e 69 52 65 61 64 4f  ];.    p->iReadO
5f40: 66 66 20 2b 3d 20 6e 42 79 74 65 3b 0a 20 20 7d  ff += nByte;.  }
5f50: 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 54 68 65  else{.    /* The
5f60: 20 72 65 71 75 65 73 74 65 64 20 64 61 74 61 20   requested data 
5f70: 69 73 20 6e 6f 74 20 61 6c 6c 20 61 76 61 69 6c  is not all avail
5f80: 61 62 6c 65 20 69 6e 20 74 68 65 20 69 6e 2d 6d  able in the in-m
5f90: 65 6d 6f 72 79 20 62 75 66 66 65 72 2e 0a 20 20  emory buffer..  
5fa0: 20 20 2a 2a 20 49 6e 20 74 68 69 73 20 63 61 73    ** In this cas
5fb0: 65 2c 20 61 6c 6c 6f 63 61 74 65 20 73 70 61 63  e, allocate spac
5fc0: 65 20 61 74 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d  e at p->aAlloc[]
5fd0: 20 74 6f 20 63 6f 70 79 20 74 68 65 20 72 65 71   to copy the req
5fe0: 75 65 73 74 65 64 0a 20 20 20 20 2a 2a 20 72 61  uested.    ** ra
5ff0: 6e 67 65 20 69 6e 74 6f 2e 20 54 68 65 6e 20 72  nge into. Then r
6000: 65 74 75 72 6e 20 61 20 63 6f 70 79 20 6f 66 20  eturn a copy of 
6010: 70 6f 69 6e 74 65 72 20 70 2d 3e 61 41 6c 6c 6f  pointer p->aAllo
6020: 63 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e  c to the caller.
6030: 20 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 52 65    */.    int nRe
6040: 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  m;              
6050: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
6060: 72 65 6d 61 69 6e 69 6e 67 20 74 6f 20 63 6f 70  remaining to cop
6070: 79 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 45 78 74  y */..    /* Ext
6080: 65 6e 64 20 74 68 65 20 70 2d 3e 61 41 6c 6c 6f  end the p->aAllo
6090: 63 5b 5d 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69  c[] allocation i
60a0: 66 20 72 65 71 75 69 72 65 64 2e 20 2a 2f 0a 20  f required. */. 
60b0: 20 20 20 69 66 28 20 70 2d 3e 6e 41 6c 6c 6f 63     if( p->nAlloc
60c0: 3c 6e 42 79 74 65 20 29 7b 0a 20 20 20 20 20 20  <nByte ){.      
60d0: 75 38 20 2a 61 4e 65 77 3b 0a 20 20 20 20 20 20  u8 *aNew;.      
60e0: 69 6e 74 20 6e 4e 65 77 20 3d 20 4d 41 58 28 31  int nNew = MAX(1
60f0: 32 38 2c 20 70 2d 3e 6e 41 6c 6c 6f 63 2a 32 29  28, p->nAlloc*2)
6100: 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 6e  ;.      while( n
6110: 42 79 74 65 3e 6e 4e 65 77 20 29 20 6e 4e 65 77  Byte>nNew ) nNew
6120: 20 3d 20 6e 4e 65 77 2a 32 3b 0a 20 20 20 20 20   = nNew*2;.     
6130: 20 61 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 52   aNew = sqlite3R
6140: 65 61 6c 6c 6f 63 28 70 2d 3e 61 41 6c 6c 6f 63  ealloc(p->aAlloc
6150: 2c 20 6e 4e 65 77 29 3b 0a 20 20 20 20 20 20 69  , nNew);.      i
6160: 66 28 20 21 61 4e 65 77 20 29 20 72 65 74 75 72  f( !aNew ) retur
6170: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
6180: 20 20 20 20 20 20 70 2d 3e 6e 41 6c 6c 6f 63 20        p->nAlloc 
6190: 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 70 2d  = nNew;.      p-
61a0: 3e 61 41 6c 6c 6f 63 20 3d 20 61 4e 65 77 3b 0a  >aAlloc = aNew;.
61b0: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 43 6f      }..    /* Co
61c0: 70 79 20 61 73 20 6d 75 63 68 20 64 61 74 61 20  py as much data 
61d0: 61 73 20 69 73 20 61 76 61 69 6c 61 62 6c 65 20  as is available 
61e0: 69 6e 20 74 68 65 20 62 75 66 66 65 72 20 69 6e  in the buffer in
61f0: 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 0a  to the start of.
6200: 20 20 20 20 2a 2a 20 70 2d 3e 61 41 6c 6c 6f 63      ** p->aAlloc
6210: 5b 5d 2e 20 20 2a 2f 0a 20 20 20 20 6d 65 6d 63  [].  */.    memc
6220: 70 79 28 70 2d 3e 61 41 6c 6c 6f 63 2c 20 26 70  py(p->aAlloc, &p
6230: 2d 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d 2c  ->aBuffer[iBuf],
6240: 20 6e 41 76 61 69 6c 29 3b 0a 20 20 20 20 70 2d   nAvail);.    p-
6250: 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e 41 76  >iReadOff += nAv
6260: 61 69 6c 3b 0a 20 20 20 20 6e 52 65 6d 20 3d 20  ail;.    nRem = 
6270: 6e 42 79 74 65 20 2d 20 6e 41 76 61 69 6c 3b 0a  nByte - nAvail;.
6280: 0a 20 20 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c  .    /* The foll
6290: 6f 77 69 6e 67 20 6c 6f 6f 70 20 63 6f 70 69 65  owing loop copie
62a0: 73 20 75 70 20 74 6f 20 70 2d 3e 6e 42 75 66 66  s up to p->nBuff
62b0: 65 72 20 62 79 74 65 73 20 70 65 72 20 69 74 65  er bytes per ite
62c0: 72 61 74 69 6f 6e 20 69 6e 74 6f 0a 20 20 20 20  ration into.    
62d0: 2a 2a 20 74 68 65 20 70 2d 3e 61 41 6c 6c 6f 63  ** the p->aAlloc
62e0: 5b 5d 20 62 75 66 66 65 72 2e 20 20 2a 2f 0a 20  [] buffer.  */. 
62f0: 20 20 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30     while( nRem>0
6300: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72 63   ){.      int rc
6310: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
6320: 20 20 20 20 20 20 2f 2a 20 76 64 62 65 50 6d 61        /* vdbePma
6330: 52 65 61 64 42 6c 6f 62 28 29 20 72 65 74 75 72  ReadBlob() retur
6340: 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 20 20 20 20  n code */.      
6350: 69 6e 74 20 6e 43 6f 70 79 3b 20 20 20 20 20 20  int nCopy;      
6360: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
6370: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 74  umber of bytes t
6380: 6f 20 63 6f 70 79 20 2a 2f 0a 20 20 20 20 20 20  o copy */.      
6390: 75 38 20 2a 61 4e 65 78 74 3b 20 20 20 20 20 20  u8 *aNext;      
63a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
63b0: 6f 69 6e 74 65 72 20 74 6f 20 62 75 66 66 65 72  ointer to buffer
63c0: 20 74 6f 20 63 6f 70 79 20 64 61 74 61 20 66 72   to copy data fr
63d0: 6f 6d 20 2a 2f 0a 0a 20 20 20 20 20 20 6e 43 6f  om */..      nCo
63e0: 70 79 20 3d 20 6e 52 65 6d 3b 0a 20 20 20 20 20  py = nRem;.     
63f0: 20 69 66 28 20 6e 52 65 6d 3e 70 2d 3e 6e 42 75   if( nRem>p->nBu
6400: 66 66 65 72 20 29 20 6e 43 6f 70 79 20 3d 20 70  ffer ) nCopy = p
6410: 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20 20 20  ->nBuffer;.     
6420: 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61   rc = vdbePmaRea
6430: 64 42 6c 6f 62 28 70 2c 20 6e 43 6f 70 79 2c 20  dBlob(p, nCopy, 
6440: 26 61 4e 65 78 74 29 3b 0a 20 20 20 20 20 20 69  &aNext);.      i
6450: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
6460: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
6470: 20 20 20 20 61 73 73 65 72 74 28 20 61 4e 65 78      assert( aNex
6480: 74 21 3d 70 2d 3e 61 41 6c 6c 6f 63 20 29 3b 0a  t!=p->aAlloc );.
6490: 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d        memcpy(&p-
64a0: 3e 61 41 6c 6c 6f 63 5b 6e 42 79 74 65 20 2d 20  >aAlloc[nByte - 
64b0: 6e 52 65 6d 5d 2c 20 61 4e 65 78 74 2c 20 6e 43  nRem], aNext, nC
64c0: 6f 70 79 29 3b 0a 20 20 20 20 20 20 6e 52 65 6d  opy);.      nRem
64d0: 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 7d   -= nCopy;.    }
64e0: 0a 0a 20 20 20 20 2a 70 70 4f 75 74 20 3d 20 70  ..    *ppOut = p
64f0: 2d 3e 61 41 6c 6c 6f 63 3b 0a 20 20 7d 0a 0a 20  ->aAlloc;.  }.. 
6500: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
6510: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64  K;.}../*.** Read
6520: 20 61 20 76 61 72 69 6e 74 20 66 72 6f 6d 20 74   a varint from t
6530: 68 65 20 73 74 72 65 61 6d 20 6f 66 20 64 61 74  he stream of dat
6540: 61 20 61 63 63 65 73 73 65 64 20 62 79 20 70 2e  a accessed by p.
6550: 20 53 65 74 20 2a 70 6e 4f 75 74 20 74 6f 0a 2a   Set *pnOut to.*
6560: 2a 20 74 68 65 20 76 61 6c 75 65 20 72 65 61 64  * the value read
6570: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
6580: 76 64 62 65 50 6d 61 52 65 61 64 56 61 72 69 6e  vdbePmaReadVarin
6590: 74 28 50 6d 61 52 65 61 64 65 72 20 2a 70 2c 20  t(PmaReader *p, 
65a0: 75 36 34 20 2a 70 6e 4f 75 74 29 7b 0a 20 20 69  u64 *pnOut){.  i
65b0: 6e 74 20 69 42 75 66 3b 0a 0a 20 20 69 66 28 20  nt iBuf;..  if( 
65c0: 70 2d 3e 61 4d 61 70 20 29 7b 0a 20 20 20 20 70  p->aMap ){.    p
65d0: 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 73 71  ->iReadOff += sq
65e0: 6c 69 74 65 33 47 65 74 56 61 72 69 6e 74 28 26  lite3GetVarint(&
65f0: 70 2d 3e 61 4d 61 70 5b 70 2d 3e 69 52 65 61 64  p->aMap[p->iRead
6600: 4f 66 66 5d 2c 20 70 6e 4f 75 74 29 3b 0a 20 20  Off], pnOut);.  
6610: 7d 65 6c 73 65 7b 0a 20 20 20 20 69 42 75 66 20  }else{.    iBuf 
6620: 3d 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 25 20  = p->iReadOff % 
6630: 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20 20  p->nBuffer;.    
6640: 69 66 28 20 69 42 75 66 20 26 26 20 28 70 2d 3e  if( iBuf && (p->
6650: 6e 42 75 66 66 65 72 2d 69 42 75 66 29 3e 3d 39  nBuffer-iBuf)>=9
6660: 20 29 7b 0a 20 20 20 20 20 20 70 2d 3e 69 52 65   ){.      p->iRe
6670: 61 64 4f 66 66 20 2b 3d 20 73 71 6c 69 74 65 33  adOff += sqlite3
6680: 47 65 74 56 61 72 69 6e 74 28 26 70 2d 3e 61 42  GetVarint(&p->aB
6690: 75 66 66 65 72 5b 69 42 75 66 5d 2c 20 70 6e 4f  uffer[iBuf], pnO
66a0: 75 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  ut);.    }else{.
66b0: 20 20 20 20 20 20 75 38 20 61 56 61 72 69 6e 74        u8 aVarint
66c0: 5b 31 36 5d 2c 20 2a 61 3b 0a 20 20 20 20 20 20  [16], *a;.      
66d0: 69 6e 74 20 69 20 3d 20 30 2c 20 72 63 3b 0a 20  int i = 0, rc;. 
66e0: 20 20 20 20 20 64 6f 7b 0a 20 20 20 20 20 20 20       do{.       
66f0: 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61   rc = vdbePmaRea
6700: 64 42 6c 6f 62 28 70 2c 20 31 2c 20 26 61 29 3b  dBlob(p, 1, &a);
6710: 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63 20  .        if( rc 
6720: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20  ) return rc;.   
6730: 20 20 20 20 20 61 56 61 72 69 6e 74 5b 28 69 2b       aVarint[(i+
6740: 2b 29 26 30 78 66 5d 20 3d 20 61 5b 30 5d 3b 0a  +)&0xf] = a[0];.
6750: 20 20 20 20 20 20 7d 77 68 69 6c 65 28 20 28 61        }while( (a
6760: 5b 30 5d 26 30 78 38 30 29 21 3d 30 20 29 3b 0a  [0]&0x80)!=0 );.
6770: 20 20 20 20 20 20 73 71 6c 69 74 65 33 47 65 74        sqlite3Get
6780: 56 61 72 69 6e 74 28 61 56 61 72 69 6e 74 2c 20  Varint(aVarint, 
6790: 70 6e 4f 75 74 29 3b 0a 20 20 20 20 7d 0a 20 20  pnOut);.    }.  
67a0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  }..  return SQLI
67b0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
67c0: 41 74 74 65 6d 70 74 20 74 6f 20 6d 65 6d 6f 72  Attempt to memor
67d0: 79 20 6d 61 70 20 66 69 6c 65 20 70 46 69 6c 65  y map file pFile
67e0: 2e 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c  . If successful,
67f0: 20 73 65 74 20 2a 70 70 20 74 6f 20 70 6f 69 6e   set *pp to poin
6800: 74 20 74 6f 20 74 68 65 0a 2a 2a 20 6e 65 77 20  t to the.** new 
6810: 6d 61 70 70 69 6e 67 20 61 6e 64 20 72 65 74 75  mapping and retu
6820: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 49 66  rn SQLITE_OK. If
6830: 20 74 68 65 20 6d 61 70 70 69 6e 67 20 69 73 20   the mapping is 
6840: 6e 6f 74 20 61 74 74 65 6d 70 74 65 64 20 0a 2a  not attempted .*
6850: 2a 20 28 62 65 63 61 75 73 65 20 74 68 65 20 66  * (because the f
6860: 69 6c 65 20 69 73 20 74 6f 6f 20 6c 61 72 67 65  ile is too large
6870: 20 6f 72 20 74 68 65 20 56 46 53 20 6c 61 79 65   or the VFS laye
6880: 72 20 69 73 20 63 6f 6e 66 69 67 75 72 65 64 20  r is configured 
6890: 6e 6f 74 20 74 6f 20 75 73 65 0a 2a 2a 20 6d 6d  not to use.** mm
68a0: 61 70 29 2c 20 72 65 74 75 72 6e 20 53 51 4c 49  ap), return SQLI
68b0: 54 45 5f 4f 4b 20 61 6e 64 20 73 65 74 20 2a 70  TE_OK and set *p
68c0: 70 20 74 6f 20 4e 55 4c 4c 2e 0a 2a 2a 0a 2a 2a  p to NULL..**.**
68d0: 20 4f 72 2c 20 69 66 20 61 6e 20 65 72 72 6f 72   Or, if an error
68e0: 20 6f 63 63 75 72 73 2c 20 72 65 74 75 72 6e 20   occurs, return 
68f0: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
6900: 63 6f 64 65 2e 20 54 68 65 20 66 69 6e 61 6c 20  code. The final 
6910: 76 61 6c 75 65 20 6f 66 0a 2a 2a 20 2a 70 70 20  value of.** *pp 
6920: 69 73 20 75 6e 64 65 66 69 6e 65 64 20 69 6e 20  is undefined in 
6930: 74 68 69 73 20 63 61 73 65 2e 0a 2a 2f 0a 73 74  this case..*/.st
6940: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
6950: 74 65 72 4d 61 70 46 69 6c 65 28 53 6f 72 74 53  terMapFile(SortS
6960: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 53  ubtask *pTask, S
6970: 6f 72 74 65 72 46 69 6c 65 20 2a 70 46 69 6c 65  orterFile *pFile
6980: 2c 20 75 38 20 2a 2a 70 70 29 7b 0a 20 20 69 6e  , u8 **pp){.  in
6990: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
69a0: 3b 0a 20 20 69 66 28 20 70 46 69 6c 65 2d 3e 69  ;.  if( pFile->i
69b0: 45 6f 66 3c 3d 28 69 36 34 29 28 70 54 61 73 6b  Eof<=(i64)(pTask
69c0: 2d 3e 70 53 6f 72 74 65 72 2d 3e 64 62 2d 3e 6e  ->pSorter->db->n
69d0: 4d 61 78 53 6f 72 74 65 72 4d 6d 61 70 29 20 29  MaxSorterMmap) )
69e0: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69  {.    sqlite3_fi
69f0: 6c 65 20 2a 70 46 64 20 3d 20 70 46 69 6c 65 2d  le *pFd = pFile-
6a00: 3e 70 46 64 3b 0a 20 20 20 20 69 66 28 20 70 46  >pFd;.    if( pF
6a10: 64 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 69 56 65  d->pMethods->iVe
6a20: 72 73 69 6f 6e 3e 3d 33 20 29 7b 0a 20 20 20 20  rsion>=3 ){.    
6a30: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
6a40: 46 65 74 63 68 28 70 46 64 2c 20 30 2c 20 28 69  Fetch(pFd, 0, (i
6a50: 6e 74 29 70 46 69 6c 65 2d 3e 69 45 6f 66 2c 20  nt)pFile->iEof, 
6a60: 28 76 6f 69 64 2a 2a 29 70 70 29 3b 0a 20 20 20  (void**)pp);.   
6a70: 20 20 20 74 65 73 74 63 61 73 65 28 20 72 63 21     testcase( rc!
6a80: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20  =SQLITE_OK );.  
6a90: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
6aa0: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 74   rc;.}../*.** At
6ab0: 74 61 63 68 20 50 6d 61 52 65 61 64 65 72 20 70  tach PmaReader p
6ac0: 52 65 61 64 72 20 74 6f 20 66 69 6c 65 20 70 46  Readr to file pF
6ad0: 69 6c 65 20 28 69 66 20 69 74 20 69 73 20 6e 6f  ile (if it is no
6ae0: 74 20 61 6c 72 65 61 64 79 20 61 74 74 61 63 68  t already attach
6af0: 65 64 20 74 6f 0a 2a 2a 20 74 68 61 74 20 66 69  ed to.** that fi
6b00: 6c 65 29 20 61 6e 64 20 73 65 65 6b 20 69 74 20  le) and seek it 
6b10: 74 6f 20 6f 66 66 73 65 74 20 69 4f 66 66 20 77  to offset iOff w
6b20: 69 74 68 69 6e 20 74 68 65 20 66 69 6c 65 2e 20  ithin the file. 
6b30: 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   Return SQLITE_O
6b40: 4b 20 0a 2a 2a 20 69 66 20 73 75 63 63 65 73 73  K .** if success
6b50: 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74  ful, or an SQLit
6b60: 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20  e error code if 
6b70: 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e  an error occurs.
6b80: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
6b90: 64 62 65 50 6d 61 52 65 61 64 65 72 53 65 65 6b  dbePmaReaderSeek
6ba0: 28 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20  (.  SortSubtask 
6bb0: 2a 70 54 61 73 6b 2c 20 20 20 20 20 20 20 20 20  *pTask,         
6bc0: 20 20 20 20 2f 2a 20 54 61 73 6b 20 63 6f 6e 74      /* Task cont
6bd0: 65 78 74 20 2a 2f 0a 20 20 50 6d 61 52 65 61 64  ext */.  PmaRead
6be0: 65 72 20 2a 70 52 65 61 64 72 2c 20 20 20 20 20  er *pReadr,     
6bf0: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 61 64           /* Read
6c00: 65 72 20 77 68 6f 73 65 20 63 75 72 73 6f 72 20  er whose cursor 
6c10: 69 73 20 74 6f 20 62 65 20 6d 6f 76 65 64 20 2a  is to be moved *
6c20: 2f 0a 20 20 53 6f 72 74 65 72 46 69 6c 65 20 2a  /.  SorterFile *
6c30: 70 46 69 6c 65 2c 20 20 20 20 20 20 20 20 20 20  pFile,          
6c40: 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 66 69      /* Sorter fi
6c50: 6c 65 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20  le to read from 
6c60: 2a 2f 0a 20 20 69 36 34 20 69 4f 66 66 20 20 20  */.  i64 iOff   
6c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6c80: 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 69       /* Offset i
6c90: 6e 20 70 46 69 6c 65 20 2a 2f 0a 29 7b 0a 20 20  n pFile */.){.  
6ca0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
6cb0: 4f 4b 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  OK;..  assert( p
6cc0: 52 65 61 64 72 2d 3e 70 49 6e 63 72 3d 3d 30 20  Readr->pIncr==0 
6cd0: 7c 7c 20 70 52 65 61 64 72 2d 3e 70 49 6e 63 72  || pReadr->pIncr
6ce0: 2d 3e 62 45 6f 66 3d 3d 30 20 29 3b 0a 0a 20 20  ->bEof==0 );..  
6cf0: 69 66 28 20 73 71 6c 69 74 65 33 46 61 75 6c 74  if( sqlite3Fault
6d00: 53 69 6d 28 32 30 31 29 20 29 20 72 65 74 75 72  Sim(201) ) retur
6d10: 6e 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f 52  n SQLITE_IOERR_R
6d20: 45 41 44 3b 0a 20 20 69 66 28 20 70 52 65 61 64  EAD;.  if( pRead
6d30: 72 2d 3e 61 4d 61 70 20 29 7b 0a 20 20 20 20 73  r->aMap ){.    s
6d40: 71 6c 69 74 65 33 4f 73 55 6e 66 65 74 63 68 28  qlite3OsUnfetch(
6d50: 70 52 65 61 64 72 2d 3e 70 46 64 2c 20 30 2c 20  pReadr->pFd, 0, 
6d60: 70 52 65 61 64 72 2d 3e 61 4d 61 70 29 3b 0a 20  pReadr->aMap);. 
6d70: 20 20 20 70 52 65 61 64 72 2d 3e 61 4d 61 70 20     pReadr->aMap 
6d80: 3d 20 30 3b 0a 20 20 7d 0a 20 20 70 52 65 61 64  = 0;.  }.  pRead
6d90: 72 2d 3e 69 52 65 61 64 4f 66 66 20 3d 20 69 4f  r->iReadOff = iO
6da0: 66 66 3b 0a 20 20 70 52 65 61 64 72 2d 3e 69 45  ff;.  pReadr->iE
6db0: 6f 66 20 3d 20 70 46 69 6c 65 2d 3e 69 45 6f 66  of = pFile->iEof
6dc0: 3b 0a 20 20 70 52 65 61 64 72 2d 3e 70 46 64 20  ;.  pReadr->pFd 
6dd0: 3d 20 70 46 69 6c 65 2d 3e 70 46 64 3b 0a 0a 20  = pFile->pFd;.. 
6de0: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
6df0: 4d 61 70 46 69 6c 65 28 70 54 61 73 6b 2c 20 70  MapFile(pTask, p
6e00: 46 69 6c 65 2c 20 26 70 52 65 61 64 72 2d 3e 61  File, &pReadr->a
6e10: 4d 61 70 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d  Map);.  if( rc==
6e20: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 52 65  SQLITE_OK && pRe
6e30: 61 64 72 2d 3e 61 4d 61 70 3d 3d 30 20 29 7b 0a  adr->aMap==0 ){.
6e40: 20 20 20 20 69 6e 74 20 70 67 73 7a 20 3d 20 70      int pgsz = p
6e50: 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 70  Task->pSorter->p
6e60: 67 73 7a 3b 0a 20 20 20 20 69 6e 74 20 69 42 75  gsz;.    int iBu
6e70: 66 20 3d 20 70 52 65 61 64 72 2d 3e 69 52 65 61  f = pReadr->iRea
6e80: 64 4f 66 66 20 25 20 70 67 73 7a 3b 0a 20 20 20  dOff % pgsz;.   
6e90: 20 69 66 28 20 70 52 65 61 64 72 2d 3e 61 42 75   if( pReadr->aBu
6ea0: 66 66 65 72 3d 3d 30 20 29 7b 0a 20 20 20 20 20  ffer==0 ){.     
6eb0: 20 70 52 65 61 64 72 2d 3e 61 42 75 66 66 65 72   pReadr->aBuffer
6ec0: 20 3d 20 28 75 38 2a 29 73 71 6c 69 74 65 33 4d   = (u8*)sqlite3M
6ed0: 61 6c 6c 6f 63 28 70 67 73 7a 29 3b 0a 20 20 20  alloc(pgsz);.   
6ee0: 20 20 20 69 66 28 20 70 52 65 61 64 72 2d 3e 61     if( pReadr->a
6ef0: 42 75 66 66 65 72 3d 3d 30 20 29 20 72 63 20 3d  Buffer==0 ) rc =
6f00: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
6f10: 20 20 20 20 20 70 52 65 61 64 72 2d 3e 6e 42 75       pReadr->nBu
6f20: 66 66 65 72 20 3d 20 70 67 73 7a 3b 0a 20 20 20  ffer = pgsz;.   
6f30: 20 7d 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53   }.    if( rc==S
6f40: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 42 75 66  QLITE_OK && iBuf
6f50: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 52   ){.      int nR
6f60: 65 61 64 20 3d 20 70 67 73 7a 20 2d 20 69 42 75  ead = pgsz - iBu
6f70: 66 3b 0a 20 20 20 20 20 20 69 66 28 20 28 70 52  f;.      if( (pR
6f80: 65 61 64 72 2d 3e 69 52 65 61 64 4f 66 66 20 2b  eadr->iReadOff +
6f90: 20 6e 52 65 61 64 29 20 3e 20 70 52 65 61 64 72   nRead) > pReadr
6fa0: 2d 3e 69 45 6f 66 20 29 7b 0a 20 20 20 20 20 20  ->iEof ){.      
6fb0: 20 20 6e 52 65 61 64 20 3d 20 28 69 6e 74 29 28    nRead = (int)(
6fc0: 70 52 65 61 64 72 2d 3e 69 45 6f 66 20 2d 20 70  pReadr->iEof - p
6fd0: 52 65 61 64 72 2d 3e 69 52 65 61 64 4f 66 66 29  Readr->iReadOff)
6fe0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
6ff0: 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65  rc = sqlite3OsRe
7000: 61 64 28 0a 20 20 20 20 20 20 20 20 20 20 70 52  ad(.          pR
7010: 65 61 64 72 2d 3e 70 46 64 2c 20 26 70 52 65 61  eadr->pFd, &pRea
7020: 64 72 2d 3e 61 42 75 66 66 65 72 5b 69 42 75 66  dr->aBuffer[iBuf
7030: 5d 2c 20 6e 52 65 61 64 2c 20 70 52 65 61 64 72  ], nRead, pReadr
7040: 2d 3e 69 52 65 61 64 4f 66 66 0a 20 20 20 20 20  ->iReadOff.     
7050: 20 29 3b 0a 20 20 20 20 20 20 74 65 73 74 63 61   );.      testca
7060: 73 65 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  se( rc!=SQLITE_O
7070: 4b 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  K );.    }.  }..
7080: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
7090: 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 50 6d  /*.** Advance Pm
70a0: 61 52 65 61 64 65 72 20 70 52 65 61 64 72 20 74  aReader pReadr t
70b0: 6f 20 74 68 65 20 6e 65 78 74 20 6b 65 79 20 69  o the next key i
70c0: 6e 20 69 74 73 20 50 4d 41 2e 20 52 65 74 75 72  n its PMA. Retur
70d0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 0a 2a  n SQLITE_OK if.*
70e0: 2a 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72  * no error occur
70f0: 73 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20  s, or an SQLite 
7100: 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20 6f 6e  error code if on
7110: 65 20 64 6f 65 73 2e 0a 2a 2f 0a 73 74 61 74 69  e does..*/.stati
7120: 63 20 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61  c int vdbePmaRea
7130: 64 65 72 4e 65 78 74 28 50 6d 61 52 65 61 64 65  derNext(PmaReade
7140: 72 20 2a 70 52 65 61 64 72 29 7b 0a 20 20 69 6e  r *pReadr){.  in
7150: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
7160: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
7170: 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a   Return Code */.
7180: 20 20 75 36 34 20 6e 52 65 63 20 3d 20 30 3b 20    u64 nRec = 0; 
7190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
71a0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 72 65 63    /* Size of rec
71b0: 6f 72 64 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  ord in bytes */.
71c0: 0a 0a 20 20 69 66 28 20 70 52 65 61 64 72 2d 3e  ..  if( pReadr->
71d0: 69 52 65 61 64 4f 66 66 3e 3d 70 52 65 61 64 72  iReadOff>=pReadr
71e0: 2d 3e 69 45 6f 66 20 29 7b 0a 20 20 20 20 49 6e  ->iEof ){.    In
71f0: 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 20  crMerger *pIncr 
7200: 3d 20 70 52 65 61 64 72 2d 3e 70 49 6e 63 72 3b  = pReadr->pIncr;
7210: 0a 20 20 20 20 69 6e 74 20 62 45 6f 66 20 3d 20  .    int bEof = 
7220: 31 3b 0a 20 20 20 20 69 66 28 20 70 49 6e 63 72  1;.    if( pIncr
7230: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 76   ){.      rc = v
7240: 64 62 65 49 6e 63 72 53 77 61 70 28 70 49 6e 63  dbeIncrSwap(pInc
7250: 72 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  r);.      if( rc
7260: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70  ==SQLITE_OK && p
7270: 49 6e 63 72 2d 3e 62 45 6f 66 3d 3d 30 20 29 7b  Incr->bEof==0 ){
7280: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64  .        rc = vd
7290: 62 65 50 6d 61 52 65 61 64 65 72 53 65 65 6b 28  bePmaReaderSeek(
72a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 49 6e  .            pIn
72b0: 63 72 2d 3e 70 54 61 73 6b 2c 20 70 52 65 61 64  cr->pTask, pRead
72c0: 72 2c 20 26 70 49 6e 63 72 2d 3e 61 46 69 6c 65  r, &pIncr->aFile
72d0: 5b 30 5d 2c 20 70 49 6e 63 72 2d 3e 69 53 74 61  [0], pIncr->iSta
72e0: 72 74 4f 66 66 0a 20 20 20 20 20 20 20 20 29 3b  rtOff.        );
72f0: 0a 20 20 20 20 20 20 20 20 62 45 6f 66 20 3d 20  .        bEof = 
7300: 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  0;.      }.    }
7310: 0a 0a 20 20 20 20 69 66 28 20 62 45 6f 66 20 29  ..    if( bEof )
7320: 7b 0a 20 20 20 20 20 20 2f 2a 20 54 68 69 73 20  {.      /* This 
7330: 69 73 20 61 6e 20 45 4f 46 20 63 6f 6e 64 69 74  is an EOF condit
7340: 69 6f 6e 20 2a 2f 0a 20 20 20 20 20 20 76 64 62  ion */.      vdb
7350: 65 50 6d 61 52 65 61 64 65 72 43 6c 65 61 72 28  ePmaReaderClear(
7360: 70 52 65 61 64 72 29 3b 0a 20 20 20 20 20 20 74  pReadr);.      t
7370: 65 73 74 63 61 73 65 28 20 72 63 21 3d 53 51 4c  estcase( rc!=SQL
7380: 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 20 20 20 20  ITE_OK );.      
7390: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d  return rc;.    }
73a0: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
73b0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
73c0: 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61   rc = vdbePmaRea
73d0: 64 56 61 72 69 6e 74 28 70 52 65 61 64 72 2c 20  dVarint(pReadr, 
73e0: 26 6e 52 65 63 29 3b 0a 20 20 7d 0a 20 20 69 66  &nRec);.  }.  if
73f0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
7400: 29 7b 0a 20 20 20 20 70 52 65 61 64 72 2d 3e 6e  ){.    pReadr->n
7410: 4b 65 79 20 3d 20 28 69 6e 74 29 6e 52 65 63 3b  Key = (int)nRec;
7420: 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d  .    rc = vdbePm
7430: 61 52 65 61 64 42 6c 6f 62 28 70 52 65 61 64 72  aReadBlob(pReadr
7440: 2c 20 28 69 6e 74 29 6e 52 65 63 2c 20 26 70 52  , (int)nRec, &pR
7450: 65 61 64 72 2d 3e 61 4b 65 79 29 3b 0a 20 20 20  eadr->aKey);.   
7460: 20 74 65 73 74 63 61 73 65 28 20 72 63 21 3d 53   testcase( rc!=S
7470: 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 7d 0a  QLITE_OK );.  }.
7480: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
7490: 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a  ./*.** Initializ
74a0: 65 20 50 6d 61 52 65 61 64 65 72 20 70 52 65 61  e PmaReader pRea
74b0: 64 72 20 74 6f 20 73 63 61 6e 20 74 68 72 6f 75  dr to scan throu
74c0: 67 68 20 74 68 65 20 50 4d 41 20 73 74 6f 72 65  gh the PMA store
74d0: 64 20 69 6e 20 66 69 6c 65 20 70 46 69 6c 65 0a  d in file pFile.
74e0: 2a 2a 20 73 74 61 72 74 69 6e 67 20 61 74 20 6f  ** starting at o
74f0: 66 66 73 65 74 20 69 53 74 61 72 74 20 61 6e 64  ffset iStart and
7500: 20 65 6e 64 69 6e 67 20 61 74 20 6f 66 66 73 65   ending at offse
7510: 74 20 69 45 6f 66 2d 31 2e 20 54 68 69 73 20 66  t iEof-1. This f
7520: 75 6e 63 74 69 6f 6e 20 0a 2a 2a 20 6c 65 61 76  unction .** leav
7530: 65 73 20 74 68 65 20 50 6d 61 52 65 61 64 65 72  es the PmaReader
7540: 20 70 6f 69 6e 74 69 6e 67 20 74 6f 20 74 68 65   pointing to the
7550: 20 66 69 72 73 74 20 6b 65 79 20 69 6e 20 74 68   first key in th
7560: 65 20 50 4d 41 20 28 6f 72 20 45 4f 46 20 69 66  e PMA (or EOF if
7570: 20 74 68 65 20 0a 2a 2a 20 50 4d 41 20 69 73 20   the .** PMA is 
7580: 65 6d 70 74 79 29 2e 0a 2a 2a 0a 2a 2a 20 49 66  empty)..**.** If
7590: 20 74 68 65 20 70 6e 42 79 74 65 20 70 61 72 61   the pnByte para
75a0: 6d 65 74 65 72 20 69 73 20 4e 55 4c 4c 2c 20 74  meter is NULL, t
75b0: 68 65 6e 20 69 74 20 69 73 20 61 73 73 75 6d 65  hen it is assume
75c0: 64 20 74 68 61 74 20 74 68 65 20 66 69 6c 65 20  d that the file 
75d0: 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 61 20 73  .** contains a s
75e0: 69 6e 67 6c 65 20 50 4d 41 2c 20 61 6e 64 20 74  ingle PMA, and t
75f0: 68 61 74 20 74 68 61 74 20 50 4d 41 20 6f 6d 69  hat that PMA omi
7600: 74 73 20 74 68 65 20 69 6e 69 74 69 61 6c 20 6c  ts the initial l
7610: 65 6e 67 74 68 20 76 61 72 69 6e 74 2e 0a 2a 2f  ength varint..*/
7620: 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65  .static int vdbe
7630: 50 6d 61 52 65 61 64 65 72 49 6e 69 74 28 0a 20  PmaReaderInit(. 
7640: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
7650: 61 73 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20  ask,            
7660: 20 2f 2a 20 54 61 73 6b 20 63 6f 6e 74 65 78 74   /* Task context
7670: 20 2a 2f 0a 20 20 53 6f 72 74 65 72 46 69 6c 65   */.  SorterFile
7680: 20 2a 70 46 69 6c 65 2c 20 20 20 20 20 20 20 20   *pFile,        
7690: 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20        /* Sorter 
76a0: 66 69 6c 65 20 74 6f 20 72 65 61 64 20 66 72 6f  file to read fro
76b0: 6d 20 2a 2f 0a 20 20 69 36 34 20 69 53 74 61 72  m */.  i64 iStar
76c0: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
76d0: 20 20 20 20 20 20 20 2f 2a 20 53 74 61 72 74 20         /* Start 
76e0: 6f 66 66 73 65 74 20 69 6e 20 70 46 69 6c 65 20  offset in pFile 
76f0: 2a 2f 0a 20 20 50 6d 61 52 65 61 64 65 72 20 2a  */.  PmaReader *
7700: 70 52 65 61 64 72 2c 20 20 20 20 20 20 20 20 20  pReadr,         
7710: 20 20 20 20 20 2f 2a 20 50 6d 61 52 65 61 64 65       /* PmaReade
7720: 72 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f  r to populate */
7730: 0a 20 20 69 36 34 20 2a 70 6e 42 79 74 65 20 20  .  i64 *pnByte  
7740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7750: 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 49 6e     /* IN/OUT: In
7760: 63 72 65 6d 65 6e 74 20 74 68 69 73 20 76 61 6c  crement this val
7770: 75 65 20 62 79 20 50 4d 41 20 73 69 7a 65 20 2a  ue by PMA size *
7780: 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a  /.){.  int rc;..
7790: 20 20 61 73 73 65 72 74 28 20 70 46 69 6c 65 2d    assert( pFile-
77a0: 3e 69 45 6f 66 3e 69 53 74 61 72 74 20 29 3b 0a  >iEof>iStart );.
77b0: 20 20 61 73 73 65 72 74 28 20 70 52 65 61 64 72    assert( pReadr
77c0: 2d 3e 61 41 6c 6c 6f 63 3d 3d 30 20 26 26 20 70  ->aAlloc==0 && p
77d0: 52 65 61 64 72 2d 3e 6e 41 6c 6c 6f 63 3d 3d 30  Readr->nAlloc==0
77e0: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 52   );.  assert( pR
77f0: 65 61 64 72 2d 3e 61 42 75 66 66 65 72 3d 3d 30  eadr->aBuffer==0
7800: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 52   );.  assert( pR
7810: 65 61 64 72 2d 3e 61 4d 61 70 3d 3d 30 20 29 3b  eadr->aMap==0 );
7820: 0a 0a 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61  ..  rc = vdbePma
7830: 52 65 61 64 65 72 53 65 65 6b 28 70 54 61 73 6b  ReaderSeek(pTask
7840: 2c 20 70 52 65 61 64 72 2c 20 70 46 69 6c 65 2c  , pReadr, pFile,
7850: 20 69 53 74 61 72 74 29 3b 0a 20 20 69 66 28 20   iStart);.  if( 
7860: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
7870: 0a 20 20 20 20 75 36 34 20 6e 42 79 74 65 3b 20  .    u64 nByte; 
7880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7890: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 50 4d     /* Size of PM
78a0: 41 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  A in bytes */.  
78b0: 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65    rc = vdbePmaRe
78c0: 61 64 56 61 72 69 6e 74 28 70 52 65 61 64 72 2c  adVarint(pReadr,
78d0: 20 26 6e 42 79 74 65 29 3b 0a 20 20 20 20 70 52   &nByte);.    pR
78e0: 65 61 64 72 2d 3e 69 45 6f 66 20 3d 20 70 52 65  eadr->iEof = pRe
78f0: 61 64 72 2d 3e 69 52 65 61 64 4f 66 66 20 2b 20  adr->iReadOff + 
7900: 6e 42 79 74 65 3b 0a 20 20 20 20 2a 70 6e 42 79  nByte;.    *pnBy
7910: 74 65 20 2b 3d 20 6e 42 79 74 65 3b 0a 20 20 7d  te += nByte;.  }
7920: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
7930: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  TE_OK ){.    rc 
7940: 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 4e  = vdbePmaReaderN
7950: 65 78 74 28 70 52 65 61 64 72 29 3b 0a 20 20 7d  ext(pReadr);.  }
7960: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
7970: 0a 2f 2a 0a 2a 2a 20 41 20 76 65 72 73 69 6f 6e  ./*.** A version
7980: 20 6f 66 20 76 64 62 65 53 6f 72 74 65 72 43 6f   of vdbeSorterCo
7990: 6d 70 61 72 65 28 29 20 74 68 61 74 20 61 73 73  mpare() that ass
79a0: 75 6d 65 73 20 74 68 61 74 20 69 74 20 68 61 73  umes that it has
79b0: 20 61 6c 72 65 61 64 79 20 62 65 65 6e 0a 2a 2a   already been.**
79c0: 20 64 65 74 65 72 6d 69 6e 65 64 20 74 68 61 74   determined that
79d0: 20 74 68 65 20 66 69 72 73 74 20 66 69 65 6c 64   the first field
79e0: 20 6f 66 20 6b 65 79 31 20 69 73 20 65 71 75 61   of key1 is equa
79f0: 6c 20 74 6f 20 74 68 65 20 66 69 72 73 74 20 66  l to the first f
7a00: 69 65 6c 64 20 6f 66 20 0a 2a 2a 20 6b 65 79 32  ield of .** key2
7a10: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
7a20: 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72  vdbeSorterCompar
7a30: 65 54 61 69 6c 28 0a 20 20 53 6f 72 74 53 75 62  eTail(.  SortSub
7a40: 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20 20  task *pTask,    
7a50: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 75 62 74           /* Subt
7a60: 61 73 6b 20 63 6f 6e 74 65 78 74 20 28 66 6f 72  ask context (for
7a70: 20 70 4b 65 79 49 6e 66 6f 29 20 2a 2f 0a 20 20   pKeyInfo) */.  
7a80: 69 6e 74 20 2a 70 62 4b 65 79 32 43 61 63 68 65  int *pbKey2Cache
7a90: 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d,              
7aa0: 2f 2a 20 54 72 75 65 20 69 66 20 70 54 61 73 6b  /* True if pTask
7ab0: 2d 3e 70 55 6e 70 61 63 6b 65 64 20 69 73 20 70  ->pUnpacked is p
7ac0: 4b 65 79 32 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  Key2 */.  const 
7ad0: 76 6f 69 64 20 2a 70 4b 65 79 31 2c 20 69 6e 74  void *pKey1, int
7ae0: 20 6e 4b 65 79 31 2c 20 20 20 2f 2a 20 4c 65 66   nKey1,   /* Lef
7af0: 74 20 73 69 64 65 20 6f 66 20 63 6f 6d 70 61 72  t side of compar
7b00: 69 73 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  ison */.  const 
7b10: 76 6f 69 64 20 2a 70 4b 65 79 32 2c 20 69 6e 74  void *pKey2, int
7b20: 20 6e 4b 65 79 32 20 20 20 20 2f 2a 20 52 69 67   nKey2    /* Rig
7b30: 68 74 20 73 69 64 65 20 6f 66 20 63 6f 6d 70 61  ht side of compa
7b40: 72 69 73 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 55 6e  rison */.){.  Un
7b50: 70 61 63 6b 65 64 52 65 63 6f 72 64 20 2a 72 32  packedRecord *r2
7b60: 20 3d 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63   = pTask->pUnpac
7b70: 6b 65 64 3b 0a 20 20 69 66 28 20 2a 70 62 4b 65  ked;.  if( *pbKe
7b80: 79 32 43 61 63 68 65 64 3d 3d 30 20 29 7b 0a 20  y2Cached==0 ){. 
7b90: 20 20 20 73 71 6c 69 74 65 33 56 64 62 65 52 65     sqlite3VdbeRe
7ba0: 63 6f 72 64 55 6e 70 61 63 6b 28 70 54 61 73 6b  cordUnpack(pTask
7bb0: 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49  ->pSorter->pKeyI
7bc0: 6e 66 6f 2c 20 6e 4b 65 79 32 2c 20 70 4b 65 79  nfo, nKey2, pKey
7bd0: 32 2c 20 72 32 29 3b 0a 20 20 20 20 2a 70 62 4b  2, r2);.    *pbK
7be0: 65 79 32 43 61 63 68 65 64 20 3d 20 31 3b 0a 20  ey2Cached = 1;. 
7bf0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69   }.  return sqli
7c00: 74 65 33 56 64 62 65 52 65 63 6f 72 64 43 6f 6d  te3VdbeRecordCom
7c10: 70 61 72 65 57 69 74 68 53 6b 69 70 28 6e 4b 65  pareWithSkip(nKe
7c20: 79 31 2c 20 70 4b 65 79 31 2c 20 72 32 2c 20 31  y1, pKey1, r2, 1
7c30: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70  );.}../*.** Comp
7c40: 61 72 65 20 6b 65 79 31 20 28 62 75 66 66 65 72  are key1 (buffer
7c50: 20 70 4b 65 79 31 2c 20 73 69 7a 65 20 6e 4b 65   pKey1, size nKe
7c60: 79 31 20 62 79 74 65 73 29 20 77 69 74 68 20 6b  y1 bytes) with k
7c70: 65 79 32 20 28 62 75 66 66 65 72 20 70 4b 65 79  ey2 (buffer pKey
7c80: 32 2c 20 0a 2a 2a 20 73 69 7a 65 20 6e 4b 65 79  2, .** size nKey
7c90: 32 20 62 79 74 65 73 29 2e 20 55 73 65 20 28 70  2 bytes). Use (p
7ca0: 54 61 73 6b 2d 3e 70 4b 65 79 49 6e 66 6f 29 20  Task->pKeyInfo) 
7cb0: 66 6f 72 20 74 68 65 20 63 6f 6c 6c 61 74 69 6f  for the collatio
7cc0: 6e 20 73 65 71 75 65 6e 63 65 73 0a 2a 2a 20 75  n sequences.** u
7cd0: 73 65 64 20 62 79 20 74 68 65 20 63 6f 6d 70 61  sed by the compa
7ce0: 72 69 73 6f 6e 2e 20 52 65 74 75 72 6e 20 74 68  rison. Return th
7cf0: 65 20 72 65 73 75 6c 74 20 6f 66 20 74 68 65 20  e result of the 
7d00: 63 6f 6d 70 61 72 69 73 6f 6e 2e 0a 2a 2a 0a 2a  comparison..**.*
7d10: 2a 20 49 66 20 49 4e 2f 4f 55 54 20 70 61 72 61  * If IN/OUT para
7d20: 6d 65 74 65 72 20 2a 70 62 4b 65 79 32 43 61 63  meter *pbKey2Cac
7d30: 68 65 64 20 69 73 20 74 72 75 65 20 77 68 65 6e  hed is true when
7d40: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
7d50: 73 20 63 61 6c 6c 65 64 2c 0a 2a 2a 20 69 74 20  s called,.** it 
7d60: 69 73 20 61 73 73 75 6d 65 64 20 74 68 61 74 20  is assumed that 
7d70: 28 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65  (pTask->pUnpacke
7d80: 64 29 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  d) contains the 
7d90: 75 6e 70 61 63 6b 65 64 20 76 65 72 73 69 6f 6e  unpacked version
7da0: 0a 2a 2a 20 6f 66 20 6b 65 79 32 2e 20 49 66 20  .** of key2. If 
7db0: 69 74 20 69 73 20 66 61 6c 73 65 2c 20 28 70 54  it is false, (pT
7dc0: 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 29 20  ask->pUnpacked) 
7dd0: 69 73 20 70 6f 70 75 6c 61 74 65 64 20 77 69 74  is populated wit
7de0: 68 20 74 68 65 20 75 6e 70 61 63 6b 65 64 0a 2a  h the unpacked.*
7df0: 2a 20 76 65 72 73 69 6f 6e 20 6f 66 20 6b 65 79  * version of key
7e00: 32 20 61 6e 64 20 2a 70 62 4b 65 79 32 43 61 63  2 and *pbKey2Cac
7e10: 68 65 64 20 73 65 74 20 74 6f 20 74 72 75 65 20  hed set to true 
7e20: 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  before returning
7e30: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 4f 4f  ..**.** If an OO
7e40: 4d 20 65 72 72 6f 72 20 69 73 20 65 6e 63 6f 75  M error is encou
7e50: 6e 74 65 72 65 64 2c 20 28 70 54 61 73 6b 2d 3e  ntered, (pTask->
7e60: 70 55 6e 70 61 63 6b 65 64 2d 3e 65 72 72 6f 72  pUnpacked->error
7e70: 5f 72 63 29 20 69 73 20 73 65 74 0a 2a 2a 20 74  _rc) is set.** t
7e80: 6f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 2e 0a  o SQLITE_NOMEM..
7e90: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
7ea0: 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28  beSorterCompare(
7eb0: 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a  .  SortSubtask *
7ec0: 70 54 61 73 6b 2c 20 20 20 20 20 20 20 20 20 20  pTask,          
7ed0: 20 20 20 2f 2a 20 53 75 62 74 61 73 6b 20 63 6f     /* Subtask co
7ee0: 6e 74 65 78 74 20 28 66 6f 72 20 70 4b 65 79 49  ntext (for pKeyI
7ef0: 6e 66 6f 29 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  nfo) */.  int *p
7f00: 62 4b 65 79 32 43 61 63 68 65 64 2c 20 20 20 20  bKey2Cached,    
7f10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
7f20: 65 20 69 66 20 70 54 61 73 6b 2d 3e 70 55 6e 70  e if pTask->pUnp
7f30: 61 63 6b 65 64 20 69 73 20 70 4b 65 79 32 20 2a  acked is pKey2 *
7f40: 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a  /.  const void *
7f50: 70 4b 65 79 31 2c 20 69 6e 74 20 6e 4b 65 79 31  pKey1, int nKey1
7f60: 2c 20 20 20 2f 2a 20 4c 65 66 74 20 73 69 64 65  ,   /* Left side
7f70: 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a   of comparison *
7f80: 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a  /.  const void *
7f90: 70 4b 65 79 32 2c 20 69 6e 74 20 6e 4b 65 79 32  pKey2, int nKey2
7fa0: 20 20 20 20 2f 2a 20 52 69 67 68 74 20 73 69 64      /* Right sid
7fb0: 65 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20  e of comparison 
7fc0: 2a 2f 0a 29 7b 0a 20 20 55 6e 70 61 63 6b 65 64  */.){.  Unpacked
7fd0: 52 65 63 6f 72 64 20 2a 72 32 20 3d 20 70 54 61  Record *r2 = pTa
7fe0: 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 3b 0a 20  sk->pUnpacked;. 
7ff0: 20 69 66 28 20 21 2a 70 62 4b 65 79 32 43 61 63   if( !*pbKey2Cac
8000: 68 65 64 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  hed ){.    sqlit
8010: 65 33 56 64 62 65 52 65 63 6f 72 64 55 6e 70 61  e3VdbeRecordUnpa
8020: 63 6b 28 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65  ck(pTask->pSorte
8030: 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20 6e 4b 65  r->pKeyInfo, nKe
8040: 79 32 2c 20 70 4b 65 79 32 2c 20 72 32 29 3b 0a  y2, pKey2, r2);.
8050: 20 20 20 20 2a 70 62 4b 65 79 32 43 61 63 68 65      *pbKey2Cache
8060: 64 20 3d 20 31 3b 0a 20 20 7d 0a 20 20 72 65 74  d = 1;.  }.  ret
8070: 75 72 6e 20 73 71 6c 69 74 65 33 56 64 62 65 52  urn sqlite3VdbeR
8080: 65 63 6f 72 64 43 6f 6d 70 61 72 65 28 6e 4b 65  ecordCompare(nKe
8090: 79 31 2c 20 70 4b 65 79 31 2c 20 72 32 29 3b 0a  y1, pKey1, r2);.
80a0: 7d 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 70 65 63 69  }../*.** A speci
80b0: 61 6c 6c 79 20 6f 70 74 69 6d 69 7a 65 64 20 76  ally optimized v
80c0: 65 72 73 69 6f 6e 20 6f 66 20 76 64 62 65 53 6f  ersion of vdbeSo
80d0: 72 74 65 72 43 6f 6d 70 61 72 65 28 29 20 74 68  rterCompare() th
80e0: 61 74 20 61 73 73 75 6d 65 73 20 74 68 61 74 0a  at assumes that.
80f0: 2a 2a 20 74 68 65 20 66 69 72 73 74 20 66 69 65  ** the first fie
8100: 6c 64 20 6f 66 20 65 61 63 68 20 6b 65 79 20 69  ld of each key i
8110: 73 20 61 20 54 45 58 54 20 76 61 6c 75 65 20 61  s a TEXT value a
8120: 6e 64 20 74 68 61 74 20 74 68 65 20 63 6f 6c 6c  nd that the coll
8130: 61 74 69 6f 6e 0a 2a 2a 20 73 65 71 75 65 6e 63  ation.** sequenc
8140: 65 20 74 6f 20 63 6f 6d 70 61 72 65 20 74 68 65  e to compare the
8150: 6d 20 77 69 74 68 20 69 73 20 42 49 4e 41 52 59  m with is BINARY
8160: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
8170: 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72  vdbeSorterCompar
8180: 65 54 65 78 74 28 0a 20 20 53 6f 72 74 53 75 62  eText(.  SortSub
8190: 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20 20  task *pTask,    
81a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 75 62 74           /* Subt
81b0: 61 73 6b 20 63 6f 6e 74 65 78 74 20 28 66 6f 72  ask context (for
81c0: 20 70 4b 65 79 49 6e 66 6f 29 20 2a 2f 0a 20 20   pKeyInfo) */.  
81d0: 69 6e 74 20 2a 70 62 4b 65 79 32 43 61 63 68 65  int *pbKey2Cache
81e0: 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d,              
81f0: 2f 2a 20 54 72 75 65 20 69 66 20 70 54 61 73 6b  /* True if pTask
8200: 2d 3e 70 55 6e 70 61 63 6b 65 64 20 69 73 20 70  ->pUnpacked is p
8210: 4b 65 79 32 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  Key2 */.  const 
8220: 76 6f 69 64 20 2a 70 4b 65 79 31 2c 20 69 6e 74  void *pKey1, int
8230: 20 6e 4b 65 79 31 2c 20 20 20 2f 2a 20 4c 65 66   nKey1,   /* Lef
8240: 74 20 73 69 64 65 20 6f 66 20 63 6f 6d 70 61 72  t side of compar
8250: 69 73 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  ison */.  const 
8260: 76 6f 69 64 20 2a 70 4b 65 79 32 2c 20 69 6e 74  void *pKey2, int
8270: 20 6e 4b 65 79 32 20 20 20 20 2f 2a 20 52 69 67   nKey2    /* Rig
8280: 68 74 20 73 69 64 65 20 6f 66 20 63 6f 6d 70 61  ht side of compa
8290: 72 69 73 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 63 6f  rison */.){.  co
82a0: 6e 73 74 20 75 38 20 2a 20 63 6f 6e 73 74 20 70  nst u8 * const p
82b0: 31 20 3d 20 28 63 6f 6e 73 74 20 75 38 20 2a 20  1 = (const u8 * 
82c0: 63 6f 6e 73 74 29 70 4b 65 79 31 3b 0a 20 20 63  const)pKey1;.  c
82d0: 6f 6e 73 74 20 75 38 20 2a 20 63 6f 6e 73 74 20  onst u8 * const 
82e0: 70 32 20 3d 20 28 63 6f 6e 73 74 20 75 38 20 2a  p2 = (const u8 *
82f0: 20 63 6f 6e 73 74 29 70 4b 65 79 32 3b 0a 20 20   const)pKey2;.  
8300: 63 6f 6e 73 74 20 75 38 20 2a 20 63 6f 6e 73 74  const u8 * const
8310: 20 76 31 20 3d 20 26 70 31 5b 20 70 31 5b 30 5d   v1 = &p1[ p1[0]
8320: 20 5d 3b 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72   ];   /* Pointer
8330: 20 74 6f 20 76 61 6c 75 65 20 31 20 2a 2f 0a 20   to value 1 */. 
8340: 20 63 6f 6e 73 74 20 75 38 20 2a 20 63 6f 6e 73   const u8 * cons
8350: 74 20 76 32 20 3d 20 26 70 32 5b 20 70 32 5b 30  t v2 = &p2[ p2[0
8360: 5d 20 5d 3b 20 20 20 2f 2a 20 50 6f 69 6e 74 65  ] ];   /* Pointe
8370: 72 20 74 6f 20 76 61 6c 75 65 20 32 20 2a 2f 0a  r to value 2 */.
8380: 0a 20 20 69 6e 74 20 6e 31 3b 0a 20 20 69 6e 74  .  int n1;.  int
8390: 20 6e 32 3b 0a 20 20 69 6e 74 20 72 65 73 3b 0a   n2;.  int res;.
83a0: 0a 20 20 67 65 74 56 61 72 69 6e 74 33 32 28 26  .  getVarint32(&
83b0: 70 31 5b 31 5d 2c 20 6e 31 29 3b 20 6e 31 20 3d  p1[1], n1); n1 =
83c0: 20 28 6e 31 20 2d 20 31 33 29 20 2f 20 32 3b 0a   (n1 - 13) / 2;.
83d0: 20 20 67 65 74 56 61 72 69 6e 74 33 32 28 26 70    getVarint32(&p
83e0: 32 5b 31 5d 2c 20 6e 32 29 3b 20 6e 32 20 3d 20  2[1], n2); n2 = 
83f0: 28 6e 32 20 2d 20 31 33 29 20 2f 20 32 3b 0a 20  (n2 - 13) / 2;. 
8400: 20 72 65 73 20 3d 20 6d 65 6d 63 6d 70 28 76 31   res = memcmp(v1
8410: 2c 20 76 32 2c 20 4d 49 4e 28 6e 31 2c 20 6e 32  , v2, MIN(n1, n2
8420: 29 29 3b 0a 20 20 69 66 28 20 72 65 73 3d 3d 30  ));.  if( res==0
8430: 20 29 7b 0a 20 20 20 20 72 65 73 20 3d 20 6e 31   ){.    res = n1
8440: 20 2d 20 6e 32 3b 0a 20 20 7d 0a 0a 20 20 69 66   - n2;.  }..  if
8450: 28 20 72 65 73 3d 3d 30 20 29 7b 0a 20 20 20 20  ( res==0 ){.    
8460: 69 66 28 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74  if( pTask->pSort
8470: 65 72 2d 3e 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46  er->pKeyInfo->nF
8480: 69 65 6c 64 3e 31 20 29 7b 0a 20 20 20 20 20 20  ield>1 ){.      
8490: 72 65 73 20 3d 20 76 64 62 65 53 6f 72 74 65 72  res = vdbeSorter
84a0: 43 6f 6d 70 61 72 65 54 61 69 6c 28 0a 20 20 20  CompareTail(.   
84b0: 20 20 20 20 20 20 20 70 54 61 73 6b 2c 20 70 62         pTask, pb
84c0: 4b 65 79 32 43 61 63 68 65 64 2c 20 70 4b 65 79  Key2Cached, pKey
84d0: 31 2c 20 6e 4b 65 79 31 2c 20 70 4b 65 79 32 2c  1, nKey1, pKey2,
84e0: 20 6e 4b 65 79 32 0a 20 20 20 20 20 20 29 3b 0a   nKey2.      );.
84f0: 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20      }.  }else{. 
8500: 20 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 70 53     if( pTask->pS
8510: 6f 72 74 65 72 2d 3e 70 4b 65 79 49 6e 66 6f 2d  orter->pKeyInfo-
8520: 3e 61 53 6f 72 74 4f 72 64 65 72 5b 30 5d 20 29  >aSortOrder[0] )
8530: 7b 0a 20 20 20 20 20 20 72 65 73 20 3d 20 72 65  {.      res = re
8540: 73 20 2a 20 2d 31 3b 0a 20 20 20 20 7d 0a 20 20  s * -1;.    }.  
8550: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 65 73 3b  }..  return res;
8560: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 70 65 63  .}../*.** A spec
8570: 69 61 6c 6c 79 20 6f 70 74 69 6d 69 7a 65 64 20  ially optimized 
8580: 76 65 72 73 69 6f 6e 20 6f 66 20 76 64 62 65 53  version of vdbeS
8590: 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 29 20 74  orterCompare() t
85a0: 68 61 74 20 61 73 73 75 6d 65 73 20 74 68 61 74  hat assumes that
85b0: 0a 2a 2a 20 74 68 65 20 66 69 72 73 74 20 66 69  .** the first fi
85c0: 65 6c 64 20 6f 66 20 65 61 63 68 20 6b 65 79 20  eld of each key 
85d0: 69 73 20 61 6e 20 49 4e 54 45 47 45 52 20 76 61  is an INTEGER va
85e0: 6c 75 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  lue..*/.static i
85f0: 6e 74 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d  nt vdbeSorterCom
8600: 70 61 72 65 49 6e 74 28 0a 20 20 53 6f 72 74 53  pareInt(.  SortS
8610: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20  ubtask *pTask,  
8620: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 75             /* Su
8630: 62 74 61 73 6b 20 63 6f 6e 74 65 78 74 20 28 66  btask context (f
8640: 6f 72 20 70 4b 65 79 49 6e 66 6f 29 20 2a 2f 0a  or pKeyInfo) */.
8650: 20 20 69 6e 74 20 2a 70 62 4b 65 79 32 43 61 63    int *pbKey2Cac
8660: 68 65 64 2c 20 20 20 20 20 20 20 20 20 20 20 20  hed,            
8670: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 70 54 61    /* True if pTa
8680: 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 20 69 73  sk->pUnpacked is
8690: 20 70 4b 65 79 32 20 2a 2f 0a 20 20 63 6f 6e 73   pKey2 */.  cons
86a0: 74 20 76 6f 69 64 20 2a 70 4b 65 79 31 2c 20 69  t void *pKey1, i
86b0: 6e 74 20 6e 4b 65 79 31 2c 20 20 20 2f 2a 20 4c  nt nKey1,   /* L
86c0: 65 66 74 20 73 69 64 65 20 6f 66 20 63 6f 6d 70  eft side of comp
86d0: 61 72 69 73 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73  arison */.  cons
86e0: 74 20 76 6f 69 64 20 2a 70 4b 65 79 32 2c 20 69  t void *pKey2, i
86f0: 6e 74 20 6e 4b 65 79 32 20 20 20 20 2f 2a 20 52  nt nKey2    /* R
8700: 69 67 68 74 20 73 69 64 65 20 6f 66 20 63 6f 6d  ight side of com
8710: 70 61 72 69 73 6f 6e 20 2a 2f 0a 29 7b 0a 20 20  parison */.){.  
8720: 63 6f 6e 73 74 20 75 38 20 2a 20 63 6f 6e 73 74  const u8 * const
8730: 20 70 31 20 3d 20 28 63 6f 6e 73 74 20 75 38 20   p1 = (const u8 
8740: 2a 20 63 6f 6e 73 74 29 70 4b 65 79 31 3b 0a 20  * const)pKey1;. 
8750: 20 63 6f 6e 73 74 20 75 38 20 2a 20 63 6f 6e 73   const u8 * cons
8760: 74 20 70 32 20 3d 20 28 63 6f 6e 73 74 20 75 38  t p2 = (const u8
8770: 20 2a 20 63 6f 6e 73 74 29 70 4b 65 79 32 3b 0a   * const)pKey2;.
8780: 20 20 63 6f 6e 73 74 20 69 6e 74 20 73 31 20 3d    const int s1 =
8790: 20 70 31 5b 31 5d 3b 20 20 20 20 20 20 20 20 20   p1[1];         
87a0: 20 20 20 20 20 20 20 20 2f 2a 20 4c 65 66 74 20          /* Left 
87b0: 68 61 6e 64 20 73 65 72 69 61 6c 20 74 79 70 65  hand serial type
87c0: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20   */.  const int 
87d0: 73 32 20 3d 20 70 32 5b 31 5d 3b 20 20 20 20 20  s2 = p2[1];     
87e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
87f0: 69 67 68 74 20 68 61 6e 64 20 73 65 72 69 61 6c  ight hand serial
8800: 20 74 79 70 65 20 2a 2f 0a 20 20 63 6f 6e 73 74   type */.  const
8810: 20 75 38 20 2a 20 63 6f 6e 73 74 20 76 31 20 3d   u8 * const v1 =
8820: 20 26 70 31 5b 20 70 31 5b 30 5d 20 5d 3b 20 20   &p1[ p1[0] ];  
8830: 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 76   /* Pointer to v
8840: 61 6c 75 65 20 31 20 2a 2f 0a 20 20 63 6f 6e 73  alue 1 */.  cons
8850: 74 20 75 38 20 2a 20 63 6f 6e 73 74 20 76 32 20  t u8 * const v2 
8860: 3d 20 26 70 32 5b 20 70 32 5b 30 5d 20 5d 3b 20  = &p2[ p2[0] ]; 
8870: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
8880: 76 61 6c 75 65 20 32 20 2a 2f 0a 20 20 69 6e 74  value 2 */.  int
8890: 20 72 65 73 3b 20 20 20 20 20 20 20 20 20 20 20   res;           
88a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
88b0: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 76 61 6c     /* Return val
88c0: 75 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28  ue */..  assert(
88d0: 20 28 73 31 3e 30 20 26 26 20 73 31 3c 37 29 20   (s1>0 && s1<7) 
88e0: 7c 7c 20 73 31 3d 3d 38 20 7c 7c 20 73 31 3d 3d  || s1==8 || s1==
88f0: 39 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 28  9 );.  assert( (
8900: 73 32 3e 30 20 26 26 20 73 32 3c 37 29 20 7c 7c  s2>0 && s2<7) ||
8910: 20 73 32 3d 3d 38 20 7c 7c 20 73 32 3d 3d 39 20   s2==8 || s2==9 
8920: 29 3b 0a 0a 20 20 69 66 28 20 73 31 3e 37 20 26  );..  if( s1>7 &
8930: 26 20 73 32 3e 37 20 29 7b 0a 20 20 20 20 72 65  & s2>7 ){.    re
8940: 73 20 3d 20 73 31 20 2d 20 73 32 3b 0a 20 20 7d  s = s1 - s2;.  }
8950: 65 6c 73 65 7b 0a 20 20 20 20 69 66 28 20 73 31  else{.    if( s1
8960: 3d 3d 73 32 20 29 7b 0a 20 20 20 20 20 20 69 66  ==s2 ){.      if
8970: 28 20 28 2a 76 31 20 5e 20 2a 76 32 29 20 26 20  ( (*v1 ^ *v2) & 
8980: 30 78 38 30 20 29 7b 0a 20 20 20 20 20 20 20 20  0x80 ){.        
8990: 2f 2a 20 54 68 65 20 74 77 6f 20 76 61 6c 75 65  /* The two value
89a0: 73 20 68 61 76 65 20 64 69 66 66 65 72 65 6e 74  s have different
89b0: 20 73 69 67 6e 73 20 2a 2f 0a 20 20 20 20 20 20   signs */.      
89c0: 20 20 72 65 73 20 3d 20 28 2a 76 31 20 26 20 30    res = (*v1 & 0
89d0: 78 38 30 29 20 3f 20 2d 31 20 3a 20 2b 31 3b 0a  x80) ? -1 : +1;.
89e0: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
89f0: 20 20 20 20 20 2f 2a 20 54 68 65 20 74 77 6f 20       /* The two 
8a00: 76 61 6c 75 65 73 20 68 61 76 65 20 74 68 65 20  values have the 
8a10: 73 61 6d 65 20 73 69 67 6e 2e 20 43 6f 6d 70 61  same sign. Compa
8a20: 72 65 20 75 73 69 6e 67 20 6d 65 6d 63 6d 70 28  re using memcmp(
8a30: 29 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20 73 74  ). */.        st
8a40: 61 74 69 63 20 63 6f 6e 73 74 20 75 38 20 61 4c  atic const u8 aL
8a50: 65 6e 5b 5d 20 3d 20 7b 30 2c 20 31 2c 20 32 2c  en[] = {0, 1, 2,
8a60: 20 33 2c 20 34 2c 20 36 2c 20 38 20 7d 3b 0a 20   3, 4, 6, 8 };. 
8a70: 20 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20         int i;.  
8a80: 20 20 20 20 20 20 72 65 73 20 3d 20 30 3b 0a 20        res = 0;. 
8a90: 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20         for(i=0; 
8aa0: 69 3c 61 4c 65 6e 5b 73 31 5d 3b 20 69 2b 2b 29  i<aLen[s1]; i++)
8ab0: 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  {.          if( 
8ac0: 28 72 65 73 20 3d 20 76 31 5b 69 5d 20 2d 20 76  (res = v1[i] - v
8ad0: 32 5b 69 5d 29 20 29 20 62 72 65 61 6b 3b 0a 20  2[i]) ) break;. 
8ae0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
8af0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
8b00: 20 20 69 66 28 20 73 32 3e 37 20 29 7b 0a 20 20    if( s2>7 ){.  
8b10: 20 20 20 20 20 20 72 65 73 20 3d 20 2b 31 3b 0a        res = +1;.
8b20: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
8b30: 73 31 3e 37 20 29 7b 0a 20 20 20 20 20 20 20 20  s1>7 ){.        
8b40: 72 65 73 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20  res = -1;.      
8b50: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 72  }else{.        r
8b60: 65 73 20 3d 20 73 31 20 2d 20 73 32 3b 0a 20 20  es = s1 - s2;.  
8b70: 20 20 20 20 7d 0a 20 20 20 20 20 20 61 73 73 65      }.      asse
8b80: 72 74 28 20 72 65 73 21 3d 30 20 29 3b 0a 0a 20  rt( res!=0 );.. 
8b90: 20 20 20 20 20 69 66 28 20 72 65 73 3e 30 20 29       if( res>0 )
8ba0: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 2a 76  {.        if( *v
8bb0: 31 20 26 20 30 78 38 30 20 29 20 72 65 73 20 3d  1 & 0x80 ) res =
8bc0: 20 2d 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65   -1;.      }else
8bd0: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 2a 76  {.        if( *v
8be0: 32 20 26 20 30 78 38 30 20 29 20 72 65 73 20 3d  2 & 0x80 ) res =
8bf0: 20 2b 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20   +1;.      }.   
8c00: 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 65   }.  }..  if( re
8c10: 73 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20  s==0 ){.    if( 
8c20: 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e  pTask->pSorter->
8c30: 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64  pKeyInfo->nField
8c40: 3e 31 20 29 7b 0a 20 20 20 20 20 20 72 65 73 20  >1 ){.      res 
8c50: 3d 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70  = vdbeSorterComp
8c60: 61 72 65 54 61 69 6c 28 0a 20 20 20 20 20 20 20  areTail(.       
8c70: 20 20 20 70 54 61 73 6b 2c 20 70 62 4b 65 79 32     pTask, pbKey2
8c80: 43 61 63 68 65 64 2c 20 70 4b 65 79 31 2c 20 6e  Cached, pKey1, n
8c90: 4b 65 79 31 2c 20 70 4b 65 79 32 2c 20 6e 4b 65  Key1, pKey2, nKe
8ca0: 79 32 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20  y2.      );.    
8cb0: 7d 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 70 54  }.  }else if( pT
8cc0: 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 4b  ask->pSorter->pK
8cd0: 65 79 49 6e 66 6f 2d 3e 61 53 6f 72 74 4f 72 64  eyInfo->aSortOrd
8ce0: 65 72 5b 30 5d 20 29 7b 0a 20 20 20 20 72 65 73  er[0] ){.    res
8cf0: 20 3d 20 72 65 73 20 2a 20 2d 31 3b 0a 20 20 7d   = res * -1;.  }
8d00: 0a 0a 20 20 72 65 74 75 72 6e 20 72 65 73 3b 0a  ..  return res;.
8d10: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c  }../*.** Initial
8d20: 69 7a 65 20 74 68 65 20 74 65 6d 70 6f 72 61 72  ize the temporar
8d30: 79 20 69 6e 64 65 78 20 63 75 72 73 6f 72 20 6a  y index cursor j
8d40: 75 73 74 20 6f 70 65 6e 65 64 20 61 73 20 61 20  ust opened as a 
8d50: 73 6f 72 74 65 72 20 63 75 72 73 6f 72 2e 0a 2a  sorter cursor..*
8d60: 2a 0a 2a 2a 20 55 73 75 61 6c 6c 79 2c 20 74 68  *.** Usually, th
8d70: 65 20 73 6f 72 74 65 72 20 6d 6f 64 75 6c 65 20  e sorter module 
8d80: 75 73 65 73 20 74 68 65 20 76 61 6c 75 65 20 6f  uses the value o
8d90: 66 20 28 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66  f (pCsr->pKeyInf
8da0: 6f 2d 3e 6e 46 69 65 6c 64 29 0a 2a 2a 20 74 6f  o->nField).** to
8db0: 20 64 65 74 65 72 6d 69 6e 65 20 74 68 65 20 6e   determine the n
8dc0: 75 6d 62 65 72 20 6f 66 20 66 69 65 6c 64 73 20  umber of fields 
8dd0: 74 68 61 74 20 73 68 6f 75 6c 64 20 62 65 20 63  that should be c
8de0: 6f 6d 70 61 72 65 64 20 66 72 6f 6d 20 74 68 65  ompared from the
8df0: 0a 2a 2a 20 72 65 63 6f 72 64 73 20 62 65 69 6e  .** records bein
8e00: 67 20 73 6f 72 74 65 64 2e 20 48 6f 77 65 76 65  g sorted. Howeve
8e10: 72 2c 20 69 66 20 74 68 65 20 76 61 6c 75 65 20  r, if the value 
8e20: 70 61 73 73 65 64 20 61 73 20 61 72 67 75 6d 65  passed as argume
8e30: 6e 74 20 6e 46 69 65 6c 64 0a 2a 2a 20 69 73 20  nt nField.** is 
8e40: 6e 6f 6e 2d 7a 65 72 6f 20 61 6e 64 20 74 68 65  non-zero and the
8e50: 20 73 6f 72 74 65 72 20 69 73 20 61 62 6c 65 20   sorter is able 
8e60: 74 6f 20 67 75 61 72 61 6e 74 65 65 20 61 20 73  to guarantee a s
8e70: 74 61 62 6c 65 20 73 6f 72 74 2c 20 6e 46 69 65  table sort, nFie
8e80: 6c 64 0a 2a 2a 20 69 73 20 75 73 65 64 20 69 6e  ld.** is used in
8e90: 73 74 65 61 64 2e 20 54 68 69 73 20 69 73 20 75  stead. This is u
8ea0: 73 65 64 20 77 68 65 6e 20 73 6f 72 74 69 6e 67  sed when sorting
8eb0: 20 72 65 63 6f 72 64 73 20 66 6f 72 20 61 20 43   records for a C
8ec0: 52 45 41 54 45 20 49 4e 44 45 58 0a 2a 2a 20 73  REATE INDEX.** s
8ed0: 74 61 74 65 6d 65 6e 74 2e 20 49 6e 20 74 68 69  tatement. In thi
8ee0: 73 20 63 61 73 65 2c 20 6b 65 79 73 20 61 72 65  s case, keys are
8ef0: 20 61 6c 77 61 79 73 20 64 65 6c 69 76 65 72 65   always delivere
8f00: 64 20 74 6f 20 74 68 65 20 73 6f 72 74 65 72 20  d to the sorter 
8f10: 69 6e 0a 2a 2a 20 6f 72 64 65 72 20 6f 66 20 74  in.** order of t
8f20: 68 65 20 70 72 69 6d 61 72 79 20 6b 65 79 2c 20  he primary key, 
8f30: 77 68 69 63 68 20 68 61 70 70 65 6e 73 20 74 6f  which happens to
8f40: 20 62 65 20 6d 61 6b 65 20 75 70 20 74 68 65 20   be make up the 
8f50: 66 69 6e 61 6c 20 70 61 72 74 20 0a 2a 2a 20 6f  final part .** o
8f60: 66 20 74 68 65 20 72 65 63 6f 72 64 73 20 62 65  f the records be
8f70: 69 6e 67 20 73 6f 72 74 65 64 2e 20 53 6f 20 69  ing sorted. So i
8f80: 66 20 74 68 65 20 73 6f 72 74 20 69 73 20 73 74  f the sort is st
8f90: 61 62 6c 65 2c 20 74 68 65 72 65 20 69 73 20 6e  able, there is n
8fa0: 65 76 65 72 0a 2a 2a 20 61 6e 79 20 72 65 61 73  ever.** any reas
8fb0: 6f 6e 20 74 6f 20 63 6f 6d 70 61 72 65 20 50 4b  on to compare PK
8fc0: 20 66 69 65 6c 64 73 20 61 6e 64 20 74 68 65 79   fields and they
8fd0: 20 63 61 6e 20 62 65 20 69 67 6e 6f 72 65 64 20   can be ignored 
8fe0: 66 6f 72 20 61 20 73 6d 61 6c 6c 0a 2a 2a 20 70  for a small.** p
8ff0: 65 72 66 6f 72 6d 61 6e 63 65 20 62 6f 6f 73 74  erformance boost
9000: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 6f 72 74  ..**.** The sort
9010: 65 72 20 63 61 6e 20 67 75 61 72 61 6e 74 65 65  er can guarantee
9020: 20 61 20 73 74 61 62 6c 65 20 73 6f 72 74 20 77   a stable sort w
9030: 68 65 6e 20 72 75 6e 6e 69 6e 67 20 69 6e 20 73  hen running in s
9040: 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64 0a 2a  ingle-threaded.*
9050: 2a 20 6d 6f 64 65 2c 20 62 75 74 20 6e 6f 74 20  * mode, but not 
9060: 69 6e 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65  in multi-threade
9070: 64 20 6d 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 53 51  d mode..**.** SQ
9080: 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72  LITE_OK is retur
9090: 6e 65 64 20 69 66 20 73 75 63 63 65 73 73 66 75  ned if successfu
90a0: 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20  l, or an SQLite 
90b0: 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72  error code other
90c0: 77 69 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  wise..*/.int sql
90d0: 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 49 6e  ite3VdbeSorterIn
90e0: 69 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  it(.  sqlite3 *d
90f0: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b,              
9100: 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
9110: 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 28 66 6f  e connection (fo
9120: 72 20 6d 61 6c 6c 6f 63 28 29 29 20 2a 2f 0a 20  r malloc()) */. 
9130: 20 69 6e 74 20 6e 46 69 65 6c 64 2c 20 20 20 20   int nField,    
9140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9150: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 6b 65   /* Number of ke
9160: 79 20 66 69 65 6c 64 73 20 69 6e 20 65 61 63 68  y fields in each
9170: 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20 56 64 62   record */.  Vdb
9180: 65 43 75 72 73 6f 72 20 2a 70 43 73 72 20 20 20  eCursor *pCsr   
9190: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
91a0: 43 75 72 73 6f 72 20 74 68 61 74 20 68 6f 6c 64  Cursor that hold
91b0: 73 20 74 68 65 20 6e 65 77 20 73 6f 72 74 65 72  s the new sorter
91c0: 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 70 67 73   */.){.  int pgs
91d0: 7a 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  z;              
91e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65           /* Page
91f0: 20 73 69 7a 65 20 6f 66 20 6d 61 69 6e 20 64 61   size of main da
9200: 74 61 62 61 73 65 20 2a 2f 0a 20 20 69 6e 74 20  tabase */.  int 
9210: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
9220: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55              /* U
9230: 73 65 64 20 74 6f 20 69 74 65 72 61 74 65 20 74  sed to iterate t
9240: 68 72 6f 75 67 68 20 61 54 61 73 6b 5b 5d 20 2a  hrough aTask[] *
9250: 2f 0a 20 20 69 6e 74 20 6d 78 43 61 63 68 65 3b  /.  int mxCache;
9260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9270: 20 20 20 20 2f 2a 20 43 61 63 68 65 20 73 69 7a      /* Cache siz
9280: 65 20 2a 2f 0a 20 20 56 64 62 65 53 6f 72 74 65  e */.  VdbeSorte
9290: 72 20 2a 70 53 6f 72 74 65 72 3b 20 20 20 20 20  r *pSorter;     
92a0: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6e 65         /* The ne
92b0: 77 20 73 6f 72 74 65 72 20 2a 2f 0a 20 20 4b 65  w sorter */.  Ke
92c0: 79 49 6e 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 3b  yInfo *pKeyInfo;
92d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
92e0: 20 43 6f 70 79 20 6f 66 20 70 43 73 72 2d 3e 70   Copy of pCsr->p
92f0: 4b 65 79 49 6e 66 6f 20 77 69 74 68 20 64 62 3d  KeyInfo with db=
9300: 3d 30 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 4b 65  =0 */.  int szKe
9310: 79 49 6e 66 6f 3b 20 20 20 20 20 20 20 20 20 20  yInfo;          
9320: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
9330: 6f 66 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66  of pCsr->pKeyInf
9340: 6f 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  o in bytes */.  
9350: 69 6e 74 20 73 7a 3b 20 20 20 20 20 20 20 20 20  int sz;         
9360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9370: 2f 2a 20 53 69 7a 65 20 6f 66 20 70 53 6f 72 74  /* Size of pSort
9380: 65 72 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20  er in bytes */. 
9390: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
93a0: 5f 4f 4b 3b 0a 23 69 66 20 53 51 4c 49 54 45 5f  _OK;.#if SQLITE_
93b0: 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41  MAX_WORKER_THREA
93c0: 44 53 3d 3d 30 0a 23 20 64 65 66 69 6e 65 20 6e  DS==0.# define n
93d0: 57 6f 72 6b 65 72 20 30 0a 23 65 6c 73 65 0a 20  Worker 0.#else. 
93e0: 20 69 6e 74 20 6e 57 6f 72 6b 65 72 3b 0a 23 65   int nWorker;.#e
93f0: 6e 64 69 66 0a 0a 20 20 2f 2a 20 49 6e 69 74 69  ndif..  /* Initi
9400: 61 6c 69 7a 65 20 74 68 65 20 75 70 70 65 72 20  alize the upper 
9410: 6c 69 6d 69 74 20 6f 6e 20 74 68 65 20 6e 75 6d  limit on the num
9420: 62 65 72 20 6f 66 20 77 6f 72 6b 65 72 20 74 68  ber of worker th
9430: 72 65 61 64 73 20 2a 2f 0a 23 69 66 20 53 51 4c  reads */.#if SQL
9440: 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54  ITE_MAX_WORKER_T
9450: 48 52 45 41 44 53 3e 30 0a 20 20 69 66 28 20 73  HREADS>0.  if( s
9460: 71 6c 69 74 65 33 54 65 6d 70 49 6e 4d 65 6d 6f  qlite3TempInMemo
9470: 72 79 28 64 62 29 20 7c 7c 20 73 71 6c 69 74 65  ry(db) || sqlite
9480: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62 43  3GlobalConfig.bC
9490: 6f 72 65 4d 75 74 65 78 3d 3d 30 20 29 7b 0a 20  oreMutex==0 ){. 
94a0: 20 20 20 6e 57 6f 72 6b 65 72 20 3d 20 30 3b 0a     nWorker = 0;.
94b0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 6e 57 6f    }else{.    nWo
94c0: 72 6b 65 72 20 3d 20 64 62 2d 3e 61 4c 69 6d 69  rker = db->aLimi
94d0: 74 5b 53 51 4c 49 54 45 5f 4c 49 4d 49 54 5f 57  t[SQLITE_LIMIT_W
94e0: 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 5d 3b 0a  ORKER_THREADS];.
94f0: 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 2f 2a    }.#endif..  /*
9500: 20 44 6f 20 6e 6f 74 20 61 6c 6c 6f 77 20 74 68   Do not allow th
9510: 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f  e total number o
9520: 66 20 74 68 72 65 61 64 73 20 28 6d 61 69 6e 20  f threads (main 
9530: 74 68 72 65 61 64 20 2b 20 61 6c 6c 20 77 6f 72  thread + all wor
9540: 6b 65 72 73 29 0a 20 20 2a 2a 20 74 6f 20 65 78  kers).  ** to ex
9550: 63 65 65 64 20 74 68 65 20 6d 61 78 69 6d 75 6d  ceed the maximum
9560: 20 6d 65 72 67 65 20 63 6f 75 6e 74 20 2a 2f 0a   merge count */.
9570: 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57  #if SQLITE_MAX_W
9580: 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 3d 53  ORKER_THREADS>=S
9590: 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f  ORTER_MAX_MERGE_
95a0: 43 4f 55 4e 54 0a 20 20 69 66 28 20 6e 57 6f 72  COUNT.  if( nWor
95b0: 6b 65 72 3e 3d 53 4f 52 54 45 52 5f 4d 41 58 5f  ker>=SORTER_MAX_
95c0: 4d 45 52 47 45 5f 43 4f 55 4e 54 20 29 7b 0a 20  MERGE_COUNT ){. 
95d0: 20 20 20 6e 57 6f 72 6b 65 72 20 3d 20 53 4f 52     nWorker = SOR
95e0: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
95f0: 55 4e 54 2d 31 3b 0a 20 20 7d 0a 23 65 6e 64 69  UNT-1;.  }.#endi
9600: 66 0a 0a 20 20 61 73 73 65 72 74 28 20 70 43 73  f..  assert( pCs
9610: 72 2d 3e 70 4b 65 79 49 6e 66 6f 20 26 26 20 70  r->pKeyInfo && p
9620: 43 73 72 2d 3e 70 42 74 3d 3d 30 20 29 3b 0a 20  Csr->pBt==0 );. 
9630: 20 73 7a 4b 65 79 49 6e 66 6f 20 3d 20 73 69 7a   szKeyInfo = siz
9640: 65 6f 66 28 4b 65 79 49 6e 66 6f 29 20 2b 20 28  eof(KeyInfo) + (
9650: 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2d 3e  pCsr->pKeyInfo->
9660: 6e 46 69 65 6c 64 2d 31 29 2a 73 69 7a 65 6f 66  nField-1)*sizeof
9670: 28 43 6f 6c 6c 53 65 71 2a 29 3b 0a 20 20 73 7a  (CollSeq*);.  sz
9680: 20 3d 20 73 69 7a 65 6f 66 28 56 64 62 65 53 6f   = sizeof(VdbeSo
9690: 72 74 65 72 29 20 2b 20 6e 57 6f 72 6b 65 72 20  rter) + nWorker 
96a0: 2a 20 73 69 7a 65 6f 66 28 53 6f 72 74 53 75 62  * sizeof(SortSub
96b0: 74 61 73 6b 29 3b 0a 0a 20 20 70 53 6f 72 74 65  task);..  pSorte
96c0: 72 20 3d 20 28 56 64 62 65 53 6f 72 74 65 72 2a  r = (VdbeSorter*
96d0: 29 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f 63  )sqlite3DbMalloc
96e0: 5a 65 72 6f 28 64 62 2c 20 73 7a 20 2b 20 73 7a  Zero(db, sz + sz
96f0: 4b 65 79 49 6e 66 6f 29 3b 0a 20 20 70 43 73 72  KeyInfo);.  pCsr
9700: 2d 3e 70 53 6f 72 74 65 72 20 3d 20 70 53 6f 72  ->pSorter = pSor
9710: 74 65 72 3b 0a 20 20 69 66 28 20 70 53 6f 72 74  ter;.  if( pSort
9720: 65 72 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20  er==0 ){.    rc 
9730: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
9740: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 53 6f    }else{.    pSo
9750: 72 74 65 72 2d 3e 70 4b 65 79 49 6e 66 6f 20 3d  rter->pKeyInfo =
9760: 20 70 4b 65 79 49 6e 66 6f 20 3d 20 28 4b 65 79   pKeyInfo = (Key
9770: 49 6e 66 6f 2a 29 28 28 75 38 2a 29 70 53 6f 72  Info*)((u8*)pSor
9780: 74 65 72 20 2b 20 73 7a 29 3b 0a 20 20 20 20 6d  ter + sz);.    m
9790: 65 6d 63 70 79 28 70 4b 65 79 49 6e 66 6f 2c 20  emcpy(pKeyInfo, 
97a0: 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20  pCsr->pKeyInfo, 
97b0: 73 7a 4b 65 79 49 6e 66 6f 29 3b 0a 20 20 20 20  szKeyInfo);.    
97c0: 70 4b 65 79 49 6e 66 6f 2d 3e 64 62 20 3d 20 30  pKeyInfo->db = 0
97d0: 3b 0a 20 20 20 20 69 66 28 20 6e 46 69 65 6c 64  ;.    if( nField
97e0: 20 26 26 20 6e 57 6f 72 6b 65 72 3d 3d 30 20 29   && nWorker==0 )
97f0: 7b 0a 20 20 20 20 20 20 70 4b 65 79 49 6e 66 6f  {.      pKeyInfo
9800: 2d 3e 6e 58 46 69 65 6c 64 20 2b 3d 20 28 70 4b  ->nXField += (pK
9810: 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64 20 2d  eyInfo->nField -
9820: 20 6e 46 69 65 6c 64 29 3b 0a 20 20 20 20 20 20   nField);.      
9830: 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64  pKeyInfo->nField
9840: 20 3d 20 6e 46 69 65 6c 64 3b 0a 20 20 20 20 7d   = nField;.    }
9850: 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 67  .    pSorter->pg
9860: 73 7a 20 3d 20 70 67 73 7a 20 3d 20 73 71 6c 69  sz = pgsz = sqli
9870: 74 65 33 42 74 72 65 65 47 65 74 50 61 67 65 53  te3BtreeGetPageS
9880: 69 7a 65 28 64 62 2d 3e 61 44 62 5b 30 5d 2e 70  ize(db->aDb[0].p
9890: 42 74 29 3b 0a 20 20 20 20 70 53 6f 72 74 65 72  Bt);.    pSorter
98a0: 2d 3e 6e 54 61 73 6b 20 3d 20 6e 57 6f 72 6b 65  ->nTask = nWorke
98b0: 72 20 2b 20 31 3b 0a 20 20 20 20 70 53 6f 72 74  r + 1;.    pSort
98c0: 65 72 2d 3e 69 50 72 65 76 20 3d 20 6e 57 6f 72  er->iPrev = nWor
98d0: 6b 65 72 2d 31 3b 0a 20 20 20 20 70 53 6f 72 74  ker-1;.    pSort
98e0: 65 72 2d 3e 62 55 73 65 54 68 72 65 61 64 73 20  er->bUseThreads 
98f0: 3d 20 28 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73  = (pSorter->nTas
9900: 6b 3e 31 29 3b 0a 20 20 20 20 70 53 6f 72 74 65  k>1);.    pSorte
9910: 72 2d 3e 64 62 20 3d 20 64 62 3b 0a 20 20 20 20  r->db = db;.    
9920: 66 6f 72 28 69 3d 30 3b 20 69 3c 70 53 6f 72 74  for(i=0; i<pSort
9930: 65 72 2d 3e 6e 54 61 73 6b 3b 20 69 2b 2b 29 7b  er->nTask; i++){
9940: 0a 20 20 20 20 20 20 53 6f 72 74 53 75 62 74 61  .      SortSubta
9950: 73 6b 20 2a 70 54 61 73 6b 20 3d 20 26 70 53 6f  sk *pTask = &pSo
9960: 72 74 65 72 2d 3e 61 54 61 73 6b 5b 69 5d 3b 0a  rter->aTask[i];.
9970: 20 20 20 20 20 20 70 54 61 73 6b 2d 3e 70 53 6f        pTask->pSo
9980: 72 74 65 72 20 3d 20 70 53 6f 72 74 65 72 3b 0a  rter = pSorter;.
9990: 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 21      }..    if( !
99a0: 73 71 6c 69 74 65 33 54 65 6d 70 49 6e 4d 65 6d  sqlite3TempInMem
99b0: 6f 72 79 28 64 62 29 20 29 7b 0a 20 20 20 20 20  ory(db) ){.     
99c0: 20 75 33 32 20 73 7a 50 6d 61 20 3d 20 73 71 6c   u32 szPma = sql
99d0: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
99e0: 2e 73 7a 50 6d 61 3b 0a 20 20 20 20 20 20 70 53  .szPma;.      pS
99f0: 6f 72 74 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a 65  orter->mnPmaSize
9a00: 20 3d 20 73 7a 50 6d 61 20 2a 20 70 67 73 7a 3b   = szPma * pgsz;
9a10: 0a 20 20 20 20 20 20 6d 78 43 61 63 68 65 20 3d  .      mxCache =
9a20: 20 64 62 2d 3e 61 44 62 5b 30 5d 2e 70 53 63 68   db->aDb[0].pSch
9a30: 65 6d 61 2d 3e 63 61 63 68 65 5f 73 69 7a 65 3b  ema->cache_size;
9a40: 0a 20 20 20 20 20 20 69 66 28 20 6d 78 43 61 63  .      if( mxCac
9a50: 68 65 3c 28 69 6e 74 29 73 7a 50 6d 61 20 29 20  he<(int)szPma ) 
9a60: 6d 78 43 61 63 68 65 20 3d 20 28 69 6e 74 29 73  mxCache = (int)s
9a70: 7a 50 6d 61 3b 0a 20 20 20 20 20 20 70 53 6f 72  zPma;.      pSor
9a80: 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65 20 3d  ter->mxPmaSize =
9a90: 20 4d 49 4e 28 28 69 36 34 29 6d 78 43 61 63 68   MIN((i64)mxCach
9aa0: 65 2a 70 67 73 7a 2c 20 53 51 4c 49 54 45 5f 4d  e*pgsz, SQLITE_M
9ab0: 41 58 5f 50 4d 41 53 5a 29 3b 0a 0a 20 20 20 20  AX_PMASZ);..    
9ac0: 20 20 2f 2a 20 45 56 49 44 45 4e 43 45 2d 4f 46    /* EVIDENCE-OF
9ad0: 3a 20 52 2d 32 36 37 34 37 2d 36 31 37 31 39 20  : R-26747-61719 
9ae0: 57 68 65 6e 20 74 68 65 20 61 70 70 6c 69 63 61  When the applica
9af0: 74 69 6f 6e 20 70 72 6f 76 69 64 65 73 20 61 6e  tion provides an
9b00: 79 20 61 6d 6f 75 6e 74 20 6f 66 0a 20 20 20 20  y amount of.    
9b10: 20 20 2a 2a 20 73 63 72 61 74 63 68 20 6d 65 6d    ** scratch mem
9b20: 6f 72 79 20 75 73 69 6e 67 20 53 51 4c 49 54 45  ory using SQLITE
9b30: 5f 43 4f 4e 46 49 47 5f 53 43 52 41 54 43 48 2c  _CONFIG_SCRATCH,
9b40: 20 53 51 4c 69 74 65 20 61 76 6f 69 64 73 20 75   SQLite avoids u
9b50: 6e 6e 65 63 65 73 73 61 72 79 0a 20 20 20 20 20  nnecessary.     
9b60: 20 2a 2a 20 6c 61 72 67 65 20 68 65 61 70 20 61   ** large heap a
9b70: 6c 6c 6f 63 61 74 69 6f 6e 73 2e 0a 20 20 20 20  llocations..    
9b80: 20 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 73    */.      if( s
9b90: 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66  qlite3GlobalConf
9ba0: 69 67 2e 70 53 63 72 61 74 63 68 3d 3d 30 20 29  ig.pScratch==0 )
9bb0: 7b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  {.        assert
9bc0: 28 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f  ( pSorter->iMemo
9bd0: 72 79 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 20  ry==0 );.       
9be0: 20 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72   pSorter->nMemor
9bf0: 79 20 3d 20 70 67 73 7a 3b 0a 20 20 20 20 20 20  y = pgsz;.      
9c00: 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e    pSorter->list.
9c10: 61 4d 65 6d 6f 72 79 20 3d 20 28 75 38 2a 29 73  aMemory = (u8*)s
9c20: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 70 67 73  qlite3Malloc(pgs
9c30: 7a 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  z);.        if( 
9c40: 21 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61  !pSorter->list.a
9c50: 4d 65 6d 6f 72 79 20 29 20 72 63 20 3d 20 53 51  Memory ) rc = SQ
9c60: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
9c70: 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69    }.    }..    i
9c80: 66 28 20 28 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46  f( (pKeyInfo->nF
9c90: 69 65 6c 64 2b 70 4b 65 79 49 6e 66 6f 2d 3e 6e  ield+pKeyInfo->n
9ca0: 58 46 69 65 6c 64 29 3c 31 33 20 0a 20 20 20 20  XField)<13 .    
9cb0: 20 26 26 20 28 70 4b 65 79 49 6e 66 6f 2d 3e 61   && (pKeyInfo->a
9cc0: 43 6f 6c 6c 5b 30 5d 3d 3d 30 20 7c 7c 20 70 4b  Coll[0]==0 || pK
9cd0: 65 79 49 6e 66 6f 2d 3e 61 43 6f 6c 6c 5b 30 5d  eyInfo->aColl[0]
9ce0: 3d 3d 64 62 2d 3e 70 44 66 6c 74 43 6f 6c 6c 29  ==db->pDfltColl)
9cf0: 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 70 53  .    ){.      pS
9d00: 6f 72 74 65 72 2d 3e 74 79 70 65 4d 61 73 6b 20  orter->typeMask 
9d10: 3d 20 53 4f 52 54 45 52 5f 54 59 50 45 5f 49 4e  = SORTER_TYPE_IN
9d20: 54 45 47 45 52 20 7c 20 53 4f 52 54 45 52 5f 54  TEGER | SORTER_T
9d30: 59 50 45 5f 54 45 58 54 3b 0a 20 20 20 20 7d 0a  YPE_TEXT;.    }.
9d40: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
9d50: 3b 0a 7d 0a 23 75 6e 64 65 66 20 6e 57 6f 72 6b  ;.}.#undef nWork
9d60: 65 72 20 20 20 2f 2a 20 44 65 66 69 6e 65 64 20  er   /* Defined 
9d70: 61 74 20 74 68 65 20 74 6f 70 20 6f 66 20 74 68  at the top of th
9d80: 69 73 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 0a  is function */..
9d90: 2f 2a 0a 2a 2a 20 46 72 65 65 20 74 68 65 20 6c  /*.** Free the l
9da0: 69 73 74 20 6f 66 20 73 6f 72 74 65 64 20 72 65  ist of sorted re
9db0: 63 6f 72 64 73 20 73 74 61 72 74 69 6e 67 20 61  cords starting a
9dc0: 74 20 70 52 65 63 6f 72 64 2e 0a 2a 2f 0a 73 74  t pRecord..*/.st
9dd0: 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f  atic void vdbeSo
9de0: 72 74 65 72 52 65 63 6f 72 64 46 72 65 65 28 73  rterRecordFree(s
9df0: 71 6c 69 74 65 33 20 2a 64 62 2c 20 53 6f 72 74  qlite3 *db, Sort
9e00: 65 72 52 65 63 6f 72 64 20 2a 70 52 65 63 6f 72  erRecord *pRecor
9e10: 64 29 7b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f  d){.  SorterReco
9e20: 72 64 20 2a 70 3b 0a 20 20 53 6f 72 74 65 72 52  rd *p;.  SorterR
9e30: 65 63 6f 72 64 20 2a 70 4e 65 78 74 3b 0a 20 20  ecord *pNext;.  
9e40: 66 6f 72 28 70 3d 70 52 65 63 6f 72 64 3b 20 70  for(p=pRecord; p
9e50: 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20  ; p=pNext){.    
9e60: 70 4e 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65  pNext = p->u.pNe
9e70: 78 74 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 44  xt;.    sqlite3D
9e80: 62 46 72 65 65 28 64 62 2c 20 70 29 3b 0a 20 20  bFree(db, p);.  
9e90: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20  }.}../*.** Free 
9ea0: 61 6c 6c 20 72 65 73 6f 75 72 63 65 73 20 6f 77  all resources ow
9eb0: 6e 65 64 20 62 79 20 74 68 65 20 6f 62 6a 65 63  ned by the objec
9ec0: 74 20 69 6e 64 69 63 61 74 65 64 20 62 79 20 61  t indicated by a
9ed0: 72 67 75 6d 65 6e 74 20 70 54 61 73 6b 2e 20 41  rgument pTask. A
9ee0: 6c 6c 20 0a 2a 2a 20 66 69 65 6c 64 73 20 6f 66  ll .** fields of
9ef0: 20 2a 70 54 61 73 6b 20 61 72 65 20 7a 65 72 6f   *pTask are zero
9f00: 65 64 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e  ed before return
9f10: 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ing..*/.static v
9f20: 6f 69 64 20 76 64 62 65 53 6f 72 74 53 75 62 74  oid vdbeSortSubt
9f30: 61 73 6b 43 6c 65 61 6e 75 70 28 73 71 6c 69 74  askCleanup(sqlit
9f40: 65 33 20 2a 64 62 2c 20 53 6f 72 74 53 75 62 74  e3 *db, SortSubt
9f50: 61 73 6b 20 2a 70 54 61 73 6b 29 7b 0a 20 20 73  ask *pTask){.  s
9f60: 71 6c 69 74 65 33 44 62 46 72 65 65 28 64 62 2c  qlite3DbFree(db,
9f70: 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65   pTask->pUnpacke
9f80: 64 29 3b 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d  d);.#if SQLITE_M
9f90: 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44  AX_WORKER_THREAD
9fa0: 53 3e 30 0a 20 20 2f 2a 20 70 54 61 73 6b 2d 3e  S>0.  /* pTask->
9fb0: 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 63 61 6e  list.aMemory can
9fc0: 20 6f 6e 6c 79 20 62 65 20 6e 6f 6e 2d 7a 65 72   only be non-zer
9fd0: 6f 20 69 66 20 69 74 20 77 61 73 20 68 61 6e 64  o if it was hand
9fe0: 65 64 20 6d 65 6d 6f 72 79 0a 20 20 2a 2a 20 66  ed memory.  ** f
9ff0: 72 6f 6d 20 74 68 65 20 6d 61 69 6e 20 74 68 72  rom the main thr
a000: 65 61 64 2e 20 20 54 68 61 74 20 6f 6e 6c 79 20  ead.  That only 
a010: 6f 63 63 75 72 73 20 53 51 4c 49 54 45 5f 4d 41  occurs SQLITE_MA
a020: 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53  X_WORKER_THREADS
a030: 3e 30 20 2a 2f 0a 20 20 69 66 28 20 70 54 61 73  >0 */.  if( pTas
a040: 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20  k->list.aMemory 
a050: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  ){.    sqlite3_f
a060: 72 65 65 28 70 54 61 73 6b 2d 3e 6c 69 73 74 2e  ree(pTask->list.
a070: 61 4d 65 6d 6f 72 79 29 3b 0a 20 20 7d 65 6c 73  aMemory);.  }els
a080: 65 0a 23 65 6e 64 69 66 0a 20 20 7b 0a 20 20 20  e.#endif.  {.   
a090: 20 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e   assert( pTask->
a0a0: 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30 20  list.aMemory==0 
a0b0: 29 3b 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65  );.    vdbeSorte
a0c0: 72 52 65 63 6f 72 64 46 72 65 65 28 30 2c 20 70  rRecordFree(0, p
a0d0: 54 61 73 6b 2d 3e 6c 69 73 74 2e 70 4c 69 73 74  Task->list.pList
a0e0: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 54 61  );.  }.  if( pTa
a0f0: 73 6b 2d 3e 66 69 6c 65 2e 70 46 64 20 29 7b 0a  sk->file.pFd ){.
a100: 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43 6c 6f      sqlite3OsClo
a110: 73 65 46 72 65 65 28 70 54 61 73 6b 2d 3e 66 69  seFree(pTask->fi
a120: 6c 65 2e 70 46 64 29 3b 0a 20 20 7d 0a 20 20 69  le.pFd);.  }.  i
a130: 66 28 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e  f( pTask->file2.
a140: 70 46 64 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  pFd ){.    sqlit
a150: 65 33 4f 73 43 6c 6f 73 65 46 72 65 65 28 70 54  e3OsCloseFree(pT
a160: 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64 29 3b  ask->file2.pFd);
a170: 0a 20 20 7d 0a 20 20 6d 65 6d 73 65 74 28 70 54  .  }.  memset(pT
a180: 61 73 6b 2c 20 30 2c 20 73 69 7a 65 6f 66 28 53  ask, 0, sizeof(S
a190: 6f 72 74 53 75 62 74 61 73 6b 29 29 3b 0a 7d 0a  ortSubtask));.}.
a1a0: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 44  .#ifdef SQLITE_D
a1b0: 45 42 55 47 5f 53 4f 52 54 45 52 5f 54 48 52 45  EBUG_SORTER_THRE
a1c0: 41 44 53 0a 73 74 61 74 69 63 20 76 6f 69 64 20  ADS.static void 
a1d0: 76 64 62 65 53 6f 72 74 65 72 57 6f 72 6b 44 65  vdbeSorterWorkDe
a1e0: 62 75 67 28 53 6f 72 74 53 75 62 74 61 73 6b 20  bug(SortSubtask 
a1f0: 2a 70 54 61 73 6b 2c 20 63 6f 6e 73 74 20 63 68  *pTask, const ch
a200: 61 72 20 2a 7a 45 76 65 6e 74 29 7b 0a 20 20 69  ar *zEvent){.  i
a210: 36 34 20 74 3b 0a 20 20 69 6e 74 20 69 54 61 73  64 t;.  int iTas
a220: 6b 20 3d 20 28 70 54 61 73 6b 20 2d 20 70 54 61  k = (pTask - pTa
a230: 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 61 54 61  sk->pSorter->aTa
a240: 73 6b 29 3b 0a 20 20 73 71 6c 69 74 65 33 4f 73  sk);.  sqlite3Os
a250: 43 75 72 72 65 6e 74 54 69 6d 65 49 6e 74 36 34  CurrentTimeInt64
a260: 28 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d  (pTask->pSorter-
a270: 3e 64 62 2d 3e 70 56 66 73 2c 20 26 74 29 3b 0a  >db->pVfs, &t);.
a280: 20 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72    fprintf(stderr
a290: 2c 20 22 25 6c 6c 64 3a 25 64 20 25 73 5c 6e 22  , "%lld:%d %s\n"
a2a0: 2c 20 74 2c 20 69 54 61 73 6b 2c 20 7a 45 76 65  , t, iTask, zEve
a2b0: 6e 74 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f  nt);.}.static vo
a2c0: 69 64 20 76 64 62 65 53 6f 72 74 65 72 52 65 77  id vdbeSorterRew
a2d0: 69 6e 64 44 65 62 75 67 28 63 6f 6e 73 74 20 63  indDebug(const c
a2e0: 68 61 72 20 2a 7a 45 76 65 6e 74 29 7b 0a 20 20  har *zEvent){.  
a2f0: 69 36 34 20 74 3b 0a 20 20 73 71 6c 69 74 65 33  i64 t;.  sqlite3
a300: 4f 73 43 75 72 72 65 6e 74 54 69 6d 65 49 6e 74  OsCurrentTimeInt
a310: 36 34 28 73 71 6c 69 74 65 33 5f 76 66 73 5f 66  64(sqlite3_vfs_f
a320: 69 6e 64 28 30 29 2c 20 26 74 29 3b 0a 20 20 66  ind(0), &t);.  f
a330: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
a340: 25 6c 6c 64 3a 58 20 25 73 5c 6e 22 2c 20 74 2c  %lld:X %s\n", t,
a350: 20 7a 45 76 65 6e 74 29 3b 0a 7d 0a 73 74 61 74   zEvent);.}.stat
a360: 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74  ic void vdbeSort
a370: 65 72 50 6f 70 75 6c 61 74 65 44 65 62 75 67 28  erPopulateDebug(
a380: 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a  .  SortSubtask *
a390: 70 54 61 73 6b 2c 0a 20 20 63 6f 6e 73 74 20 63  pTask,.  const c
a3a0: 68 61 72 20 2a 7a 45 76 65 6e 74 0a 29 7b 0a 20  har *zEvent.){. 
a3b0: 20 69 36 34 20 74 3b 0a 20 20 69 6e 74 20 69 54   i64 t;.  int iT
a3c0: 61 73 6b 20 3d 20 28 70 54 61 73 6b 20 2d 20 70  ask = (pTask - p
a3d0: 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 61  Task->pSorter->a
a3e0: 54 61 73 6b 29 3b 0a 20 20 73 71 6c 69 74 65 33  Task);.  sqlite3
a3f0: 4f 73 43 75 72 72 65 6e 74 54 69 6d 65 49 6e 74  OsCurrentTimeInt
a400: 36 34 28 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65  64(pTask->pSorte
a410: 72 2d 3e 64 62 2d 3e 70 56 66 73 2c 20 26 74 29  r->db->pVfs, &t)
a420: 3b 0a 20 20 66 70 72 69 6e 74 66 28 73 74 64 65  ;.  fprintf(stde
a430: 72 72 2c 20 22 25 6c 6c 64 3a 62 67 25 64 20 25  rr, "%lld:bg%d %
a440: 73 5c 6e 22 2c 20 74 2c 20 69 54 61 73 6b 2c 20  s\n", t, iTask, 
a450: 7a 45 76 65 6e 74 29 3b 0a 7d 0a 73 74 61 74 69  zEvent);.}.stati
a460: 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65  c void vdbeSorte
a470: 72 42 6c 6f 63 6b 44 65 62 75 67 28 0a 20 20 53  rBlockDebug(.  S
a480: 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
a490: 6b 2c 0a 20 20 69 6e 74 20 62 42 6c 6f 63 6b 65  k,.  int bBlocke
a4a0: 64 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  d,.  const char 
a4b0: 2a 7a 45 76 65 6e 74 0a 29 7b 0a 20 20 69 66 28  *zEvent.){.  if(
a4c0: 20 62 42 6c 6f 63 6b 65 64 20 29 7b 0a 20 20 20   bBlocked ){.   
a4d0: 20 69 36 34 20 74 3b 0a 20 20 20 20 73 71 6c 69   i64 t;.    sqli
a4e0: 74 65 33 4f 73 43 75 72 72 65 6e 74 54 69 6d 65  te3OsCurrentTime
a4f0: 49 6e 74 36 34 28 70 54 61 73 6b 2d 3e 70 53 6f  Int64(pTask->pSo
a500: 72 74 65 72 2d 3e 64 62 2d 3e 70 56 66 73 2c 20  rter->db->pVfs, 
a510: 26 74 29 3b 0a 20 20 20 20 66 70 72 69 6e 74 66  &t);.    fprintf
a520: 28 73 74 64 65 72 72 2c 20 22 25 6c 6c 64 3a 6d  (stderr, "%lld:m
a530: 61 69 6e 20 25 73 5c 6e 22 2c 20 74 2c 20 7a 45  ain %s\n", t, zE
a540: 76 65 6e 74 29 3b 0a 20 20 7d 0a 7d 0a 23 65 6c  vent);.  }.}.#el
a550: 73 65 0a 23 20 64 65 66 69 6e 65 20 76 64 62 65  se.# define vdbe
a560: 53 6f 72 74 65 72 57 6f 72 6b 44 65 62 75 67 28  SorterWorkDebug(
a570: 78 2c 79 29 0a 23 20 64 65 66 69 6e 65 20 76 64  x,y).# define vd
a580: 62 65 53 6f 72 74 65 72 52 65 77 69 6e 64 44 65  beSorterRewindDe
a590: 62 75 67 28 79 29 0a 23 20 64 65 66 69 6e 65 20  bug(y).# define 
a5a0: 76 64 62 65 53 6f 72 74 65 72 50 6f 70 75 6c 61  vdbeSorterPopula
a5b0: 74 65 44 65 62 75 67 28 78 2c 79 29 0a 23 20 64  teDebug(x,y).# d
a5c0: 65 66 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72  efine vdbeSorter
a5d0: 42 6c 6f 63 6b 44 65 62 75 67 28 78 2c 79 2c 7a  BlockDebug(x,y,z
a5e0: 29 0a 23 65 6e 64 69 66 0a 0a 23 69 66 20 53 51  ).#endif..#if SQ
a5f0: 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f  LITE_MAX_WORKER_
a600: 54 48 52 45 41 44 53 3e 30 0a 2f 2a 0a 2a 2a 20  THREADS>0./*.** 
a610: 4a 6f 69 6e 20 74 68 72 65 61 64 20 70 54 61 73  Join thread pTas
a620: 6b 2d 3e 74 68 72 65 61 64 2e 0a 2a 2f 0a 73 74  k->thread..*/.st
a630: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
a640: 74 65 72 4a 6f 69 6e 54 68 72 65 61 64 28 53 6f  terJoinThread(So
a650: 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b  rtSubtask *pTask
a660: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
a670: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70  LITE_OK;.  if( p
a680: 54 61 73 6b 2d 3e 70 54 68 72 65 61 64 20 29 7b  Task->pThread ){
a690: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 44  .#ifdef SQLITE_D
a6a0: 45 42 55 47 5f 53 4f 52 54 45 52 5f 54 48 52 45  EBUG_SORTER_THRE
a6b0: 41 44 53 0a 20 20 20 20 69 6e 74 20 62 44 6f 6e  ADS.    int bDon
a6c0: 65 20 3d 20 70 54 61 73 6b 2d 3e 62 44 6f 6e 65  e = pTask->bDone
a6d0: 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 76 6f 69  ;.#endif.    voi
a6e0: 64 20 2a 70 52 65 74 20 3d 20 53 51 4c 49 54 45  d *pRet = SQLITE
a6f0: 5f 49 4e 54 5f 54 4f 5f 50 54 52 28 53 51 4c 49  _INT_TO_PTR(SQLI
a700: 54 45 5f 45 52 52 4f 52 29 3b 0a 20 20 20 20 76  TE_ERROR);.    v
a710: 64 62 65 53 6f 72 74 65 72 42 6c 6f 63 6b 44 65  dbeSorterBlockDe
a720: 62 75 67 28 70 54 61 73 6b 2c 20 21 62 44 6f 6e  bug(pTask, !bDon
a730: 65 2c 20 22 65 6e 74 65 72 22 29 3b 0a 20 20 20  e, "enter");.   
a740: 20 28 76 6f 69 64 29 73 71 6c 69 74 65 33 54 68   (void)sqlite3Th
a750: 72 65 61 64 4a 6f 69 6e 28 70 54 61 73 6b 2d 3e  readJoin(pTask->
a760: 70 54 68 72 65 61 64 2c 20 26 70 52 65 74 29 3b  pThread, &pRet);
a770: 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 42  .    vdbeSorterB
a780: 6c 6f 63 6b 44 65 62 75 67 28 70 54 61 73 6b 2c  lockDebug(pTask,
a790: 20 21 62 44 6f 6e 65 2c 20 22 65 78 69 74 22 29   !bDone, "exit")
a7a0: 3b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54  ;.    rc = SQLIT
a7b0: 45 5f 50 54 52 5f 54 4f 5f 49 4e 54 28 70 52 65  E_PTR_TO_INT(pRe
a7c0: 74 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  t);.    assert( 
a7d0: 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 3d 3d 31 20  pTask->bDone==1 
a7e0: 29 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 62 44  );.    pTask->bD
a7f0: 6f 6e 65 20 3d 20 30 3b 0a 20 20 20 20 70 54 61  one = 0;.    pTa
a800: 73 6b 2d 3e 70 54 68 72 65 61 64 20 3d 20 30 3b  sk->pThread = 0;
a810: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
a820: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 61 75 6e 63  ;.}../*.** Launc
a830: 68 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74  h a background t
a840: 68 72 65 61 64 20 74 6f 20 72 75 6e 20 78 54 61  hread to run xTa
a850: 73 6b 28 70 49 6e 29 2e 0a 2a 2f 0a 73 74 61 74  sk(pIn)..*/.stat
a860: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
a870: 72 43 72 65 61 74 65 54 68 72 65 61 64 28 0a 20  rCreateThread(. 
a880: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
a890: 61 73 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20  ask,            
a8a0: 20 2f 2a 20 54 68 72 65 61 64 20 77 69 6c 6c 20   /* Thread will 
a8b0: 75 73 65 20 74 68 69 73 20 74 61 73 6b 20 6f 62  use this task ob
a8c0: 6a 65 63 74 20 2a 2f 0a 20 20 76 6f 69 64 20 2a  ject */.  void *
a8d0: 28 2a 78 54 61 73 6b 29 28 76 6f 69 64 2a 29 2c  (*xTask)(void*),
a8e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 6f 75            /* Rou
a8f0: 74 69 6e 65 20 74 6f 20 72 75 6e 20 69 6e 20 61  tine to run in a
a900: 20 73 65 70 61 72 61 74 65 20 74 68 72 65 61 64   separate thread
a910: 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 49 6e 20   */.  void *pIn 
a920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a930: 20 20 20 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e        /* Argumen
a940: 74 20 70 61 73 73 65 64 20 69 6e 74 6f 20 78 54  t passed into xT
a950: 61 73 6b 28 29 20 2a 2f 0a 29 7b 0a 20 20 61 73  ask() */.){.  as
a960: 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 70 54 68  sert( pTask->pTh
a970: 72 65 61 64 3d 3d 30 20 26 26 20 70 54 61 73 6b  read==0 && pTask
a980: 2d 3e 62 44 6f 6e 65 3d 3d 30 20 29 3b 0a 20 20  ->bDone==0 );.  
a990: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 54 68  return sqlite3Th
a9a0: 72 65 61 64 43 72 65 61 74 65 28 26 70 54 61 73  readCreate(&pTas
a9b0: 6b 2d 3e 70 54 68 72 65 61 64 2c 20 78 54 61 73  k->pThread, xTas
a9c0: 6b 2c 20 70 49 6e 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  k, pIn);.}../*.*
a9d0: 2a 20 4a 6f 69 6e 20 61 6c 6c 20 6f 75 74 73 74  * Join all outst
a9e0: 61 6e 64 69 6e 67 20 74 68 72 65 61 64 73 20 6c  anding threads l
a9f0: 61 75 6e 63 68 65 64 20 62 79 20 53 6f 72 74 65  aunched by Sorte
aa00: 72 57 72 69 74 65 28 29 20 74 6f 20 63 72 65 61  rWrite() to crea
aa10: 74 65 20 0a 2a 2a 20 6c 65 76 65 6c 2d 30 20 50  te .** level-0 P
aa20: 4d 41 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  MAs..*/.static i
aa30: 6e 74 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69  nt vdbeSorterJoi
aa40: 6e 41 6c 6c 28 56 64 62 65 53 6f 72 74 65 72 20  nAll(VdbeSorter 
aa50: 2a 70 53 6f 72 74 65 72 2c 20 69 6e 74 20 72 63  *pSorter, int rc
aa60: 69 6e 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  in){.  int rc = 
aa70: 72 63 69 6e 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a  rcin;.  int i;..
aa80: 20 20 2f 2a 20 54 68 69 73 20 66 75 6e 63 74 69    /* This functi
aa90: 6f 6e 20 69 73 20 61 6c 77 61 79 73 20 63 61 6c  on is always cal
aaa0: 6c 65 64 20 62 79 20 74 68 65 20 6d 61 69 6e 20  led by the main 
aab0: 75 73 65 72 20 74 68 72 65 61 64 2e 0a 20 20 2a  user thread..  *
aac0: 2a 0a 20 20 2a 2a 20 49 66 20 74 68 69 73 20 66  *.  ** If this f
aad0: 75 6e 63 74 69 6f 6e 20 69 73 20 62 65 69 6e 67  unction is being
aae0: 20 63 61 6c 6c 65 64 20 61 66 74 65 72 20 53 6f   called after So
aaf0: 72 74 65 72 52 65 77 69 6e 64 28 29 20 68 61 73  rterRewind() has
ab00: 20 62 65 65 6e 20 63 61 6c 6c 65 64 2c 20 0a 20   been called, . 
ab10: 20 2a 2a 20 69 74 20 69 73 20 70 6f 73 73 69 62   ** it is possib
ab20: 6c 65 20 74 68 61 74 20 74 68 72 65 61 64 20 70  le that thread p
ab30: 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 70 53  Sorter->aTask[pS
ab40: 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 5d 2e  orter->nTask-1].
ab50: 70 54 68 72 65 61 64 0a 20 20 2a 2a 20 69 73 20  pThread.  ** is 
ab60: 63 75 72 72 65 6e 74 6c 79 20 61 74 74 65 6d 70  currently attemp
ab70: 74 20 74 6f 20 6a 6f 69 6e 20 6f 6e 65 20 6f 66  t to join one of
ab80: 20 74 68 65 20 6f 74 68 65 72 20 74 68 72 65 61   the other threa
ab90: 64 73 2e 20 54 6f 20 61 76 6f 69 64 20 61 20 72  ds. To avoid a r
aba0: 61 63 65 0a 20 20 2a 2a 20 63 6f 6e 64 69 74 69  ace.  ** conditi
abb0: 6f 6e 20 77 68 65 72 65 20 74 68 69 73 20 74 68  on where this th
abc0: 72 65 61 64 20 61 6c 73 6f 20 61 74 74 65 6d 70  read also attemp
abd0: 74 73 20 74 6f 20 6a 6f 69 6e 20 74 68 65 20 73  ts to join the s
abe0: 61 6d 65 20 6f 62 6a 65 63 74 2c 20 6a 6f 69 6e  ame object, join
abf0: 20 0a 20 20 2a 2a 20 74 68 72 65 61 64 20 70 53   .  ** thread pS
ac00: 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 70 53 6f  orter->aTask[pSo
ac10: 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 5d 2e 70  rter->nTask-1].p
ac20: 54 68 72 65 61 64 20 66 69 72 73 74 2e 20 2a 2f  Thread first. */
ac30: 0a 20 20 66 6f 72 28 69 3d 70 53 6f 72 74 65 72  .  for(i=pSorter
ac40: 2d 3e 6e 54 61 73 6b 2d 31 3b 20 69 3e 3d 30 3b  ->nTask-1; i>=0;
ac50: 20 69 2d 2d 29 7b 0a 20 20 20 20 53 6f 72 74 53   i--){.    SortS
ac60: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20  ubtask *pTask = 
ac70: 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b  &pSorter->aTask[
ac80: 69 5d 3b 0a 20 20 20 20 69 6e 74 20 72 63 32 20  i];.    int rc2 
ac90: 3d 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e  = vdbeSorterJoin
aca0: 54 68 72 65 61 64 28 70 54 61 73 6b 29 3b 0a 20  Thread(pTask);. 
acb0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
acc0: 45 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63 32 3b  E_OK ) rc = rc2;
acd0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
ace0: 3b 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65 66 69  ;.}.#else.# defi
acf0: 6e 65 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69  ne vdbeSorterJoi
ad00: 6e 41 6c 6c 28 78 2c 72 63 69 6e 29 20 28 72 63  nAll(x,rcin) (rc
ad10: 69 6e 29 0a 23 20 64 65 66 69 6e 65 20 76 64 62  in).# define vdb
ad20: 65 53 6f 72 74 65 72 4a 6f 69 6e 54 68 72 65 61  eSorterJoinThrea
ad30: 64 28 70 54 61 73 6b 29 20 53 51 4c 49 54 45 5f  d(pTask) SQLITE_
ad40: 4f 4b 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a  OK.#endif../*.**
ad50: 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20   Allocate a new 
ad60: 4d 65 72 67 65 45 6e 67 69 6e 65 20 6f 62 6a 65  MergeEngine obje
ad70: 63 74 20 63 61 70 61 62 6c 65 20 6f 66 20 68 61  ct capable of ha
ad80: 6e 64 6c 69 6e 67 20 75 70 20 74 6f 0a 2a 2a 20  ndling up to.** 
ad90: 6e 52 65 61 64 65 72 20 50 6d 61 52 65 61 64 65  nReader PmaReade
ada0: 72 20 69 6e 70 75 74 73 2e 0a 2a 2a 0a 2a 2a 20  r inputs..**.** 
adb0: 6e 52 65 61 64 65 72 20 69 73 20 61 75 74 6f 6d  nReader is autom
adc0: 61 74 69 63 61 6c 6c 79 20 72 6f 75 6e 64 65 64  atically rounded
add0: 20 75 70 20 74 6f 20 74 68 65 20 6e 65 78 74 20   up to the next 
ade0: 70 6f 77 65 72 20 6f 66 20 74 77 6f 2e 0a 2a 2a  power of two..**
adf0: 20 6e 52 65 61 64 65 72 20 6d 61 79 20 6e 6f 74   nReader may not
ae00: 20 65 78 63 65 65 64 20 53 4f 52 54 45 52 5f 4d   exceed SORTER_M
ae10: 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20 65  AX_MERGE_COUNT e
ae20: 76 65 6e 20 61 66 74 65 72 20 72 6f 75 6e 64 69  ven after roundi
ae30: 6e 67 20 75 70 2e 0a 2a 2f 0a 73 74 61 74 69 63  ng up..*/.static
ae40: 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 76 64   MergeEngine *vd
ae50: 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4e 65 77  beMergeEngineNew
ae60: 28 69 6e 74 20 6e 52 65 61 64 65 72 29 7b 0a 20  (int nReader){. 
ae70: 20 69 6e 74 20 4e 20 3d 20 32 3b 20 20 20 20 20   int N = 2;     
ae80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ae90: 20 2f 2a 20 53 6d 61 6c 6c 65 73 74 20 70 6f 77   /* Smallest pow
aea0: 65 72 20 6f 66 20 74 77 6f 20 3e 3d 20 6e 52 65  er of two >= nRe
aeb0: 61 64 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  ader */.  int nB
aec0: 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  yte;            
aed0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 74            /* Tot
aee0: 61 6c 20 62 79 74 65 73 20 6f 66 20 73 70 61 63  al bytes of spac
aef0: 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f  e to allocate */
af00: 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a  .  MergeEngine *
af10: 70 4e 65 77 3b 20 20 20 20 20 20 20 20 20 20 20  pNew;           
af20: 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
af30: 20 61 6c 6c 6f 63 61 74 65 64 20 6f 62 6a 65 63   allocated objec
af40: 74 20 74 6f 20 72 65 74 75 72 6e 20 2a 2f 0a 0a  t to return */..
af50: 20 20 61 73 73 65 72 74 28 20 6e 52 65 61 64 65    assert( nReade
af60: 72 3c 3d 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45  r<=SORTER_MAX_ME
af70: 52 47 45 5f 43 4f 55 4e 54 20 29 3b 0a 0a 20 20  RGE_COUNT );..  
af80: 77 68 69 6c 65 28 20 4e 3c 6e 52 65 61 64 65 72  while( N<nReader
af90: 20 29 20 4e 20 2b 3d 20 4e 3b 0a 20 20 6e 42 79   ) N += N;.  nBy
afa0: 74 65 20 3d 20 73 69 7a 65 6f 66 28 4d 65 72 67  te = sizeof(Merg
afb0: 65 45 6e 67 69 6e 65 29 20 2b 20 4e 20 2a 20 28  eEngine) + N * (
afc0: 73 69 7a 65 6f 66 28 69 6e 74 29 20 2b 20 73 69  sizeof(int) + si
afd0: 7a 65 6f 66 28 50 6d 61 52 65 61 64 65 72 29 29  zeof(PmaReader))
afe0: 3b 0a 0a 20 20 70 4e 65 77 20 3d 20 73 71 6c 69  ;..  pNew = sqli
aff0: 74 65 33 46 61 75 6c 74 53 69 6d 28 31 30 30 29  te3FaultSim(100)
b000: 20 3f 20 30 20 3a 20 28 4d 65 72 67 65 45 6e 67   ? 0 : (MergeEng
b010: 69 6e 65 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c  ine*)sqlite3Mall
b020: 6f 63 5a 65 72 6f 28 6e 42 79 74 65 29 3b 0a 20  ocZero(nByte);. 
b030: 20 69 66 28 20 70 4e 65 77 20 29 7b 0a 20 20 20   if( pNew ){.   
b040: 20 70 4e 65 77 2d 3e 6e 54 72 65 65 20 3d 20 4e   pNew->nTree = N
b050: 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 70 54 61 73  ;.    pNew->pTas
b060: 6b 20 3d 20 30 3b 0a 20 20 20 20 70 4e 65 77 2d  k = 0;.    pNew-
b070: 3e 61 52 65 61 64 72 20 3d 20 28 50 6d 61 52 65  >aReadr = (PmaRe
b080: 61 64 65 72 2a 29 26 70 4e 65 77 5b 31 5d 3b 0a  ader*)&pNew[1];.
b090: 20 20 20 20 70 4e 65 77 2d 3e 61 54 72 65 65 20      pNew->aTree 
b0a0: 3d 20 28 69 6e 74 2a 29 26 70 4e 65 77 2d 3e 61  = (int*)&pNew->a
b0b0: 52 65 61 64 72 5b 4e 5d 3b 0a 20 20 7d 0a 20 20  Readr[N];.  }.  
b0c0: 72 65 74 75 72 6e 20 70 4e 65 77 3b 0a 7d 0a 0a  return pNew;.}..
b0d0: 2f 2a 0a 2a 2a 20 46 72 65 65 20 74 68 65 20 4d  /*.** Free the M
b0e0: 65 72 67 65 45 6e 67 69 6e 65 20 6f 62 6a 65 63  ergeEngine objec
b0f0: 74 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20  t passed as the 
b100: 6f 6e 6c 79 20 61 72 67 75 6d 65 6e 74 2e 0a 2a  only argument..*
b110: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64  /.static void vd
b120: 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46 72 65  beMergeEngineFre
b130: 65 28 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70  e(MergeEngine *p
b140: 4d 65 72 67 65 72 29 7b 0a 20 20 69 6e 74 20 69  Merger){.  int i
b150: 3b 0a 20 20 69 66 28 20 70 4d 65 72 67 65 72 20  ;.  if( pMerger 
b160: 29 7b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  ){.    for(i=0; 
b170: 69 3c 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65  i<pMerger->nTree
b180: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 76 64  ; i++){.      vd
b190: 62 65 50 6d 61 52 65 61 64 65 72 43 6c 65 61 72  bePmaReaderClear
b1a0: 28 26 70 4d 65 72 67 65 72 2d 3e 61 52 65 61 64  (&pMerger->aRead
b1b0: 72 5b 69 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  r[i]);.    }.  }
b1c0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
b1d0: 70 4d 65 72 67 65 72 29 3b 0a 7d 0a 0a 2f 2a 0a  pMerger);.}../*.
b1e0: 2a 2a 20 46 72 65 65 20 61 6c 6c 20 72 65 73 6f  ** Free all reso
b1f0: 75 72 63 65 73 20 61 73 73 6f 63 69 61 74 65 64  urces associated
b200: 20 77 69 74 68 20 74 68 65 20 49 6e 63 72 4d 65   with the IncrMe
b210: 72 67 65 72 20 6f 62 6a 65 63 74 20 69 6e 64 69  rger object indi
b220: 63 61 74 65 64 20 62 79 0a 2a 2a 20 74 68 65 20  cated by.** the 
b230: 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 0a  first argument..
b240: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76  */.static void v
b250: 64 62 65 49 6e 63 72 46 72 65 65 28 49 6e 63 72  dbeIncrFree(Incr
b260: 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 29 7b 0a  Merger *pIncr){.
b270: 20 20 69 66 28 20 70 49 6e 63 72 20 29 7b 0a 23    if( pIncr ){.#
b280: 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f  if SQLITE_MAX_WO
b290: 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 0a 20  RKER_THREADS>0. 
b2a0: 20 20 20 69 66 28 20 70 49 6e 63 72 2d 3e 62 55     if( pIncr->bU
b2b0: 73 65 54 68 72 65 61 64 20 29 7b 0a 20 20 20 20  seThread ){.    
b2c0: 20 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e    vdbeSorterJoin
b2d0: 54 68 72 65 61 64 28 70 49 6e 63 72 2d 3e 70 54  Thread(pIncr->pT
b2e0: 61 73 6b 29 3b 0a 20 20 20 20 20 20 69 66 28 20  ask);.      if( 
b2f0: 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e  pIncr->aFile[0].
b300: 70 46 64 20 29 20 73 71 6c 69 74 65 33 4f 73 43  pFd ) sqlite3OsC
b310: 6c 6f 73 65 46 72 65 65 28 70 49 6e 63 72 2d 3e  loseFree(pIncr->
b320: 61 46 69 6c 65 5b 30 5d 2e 70 46 64 29 3b 0a 20  aFile[0].pFd);. 
b330: 20 20 20 20 20 69 66 28 20 70 49 6e 63 72 2d 3e       if( pIncr->
b340: 61 46 69 6c 65 5b 31 5d 2e 70 46 64 20 29 20 73  aFile[1].pFd ) s
b350: 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 46 72 65  qlite3OsCloseFre
b360: 65 28 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31  e(pIncr->aFile[1
b370: 5d 2e 70 46 64 29 3b 0a 20 20 20 20 7d 0a 23 65  ].pFd);.    }.#e
b380: 6e 64 69 66 0a 20 20 20 20 76 64 62 65 4d 65 72  ndif.    vdbeMer
b390: 67 65 45 6e 67 69 6e 65 46 72 65 65 28 70 49 6e  geEngineFree(pIn
b3a0: 63 72 2d 3e 70 4d 65 72 67 65 72 29 3b 0a 20 20  cr->pMerger);.  
b3b0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
b3c0: 49 6e 63 72 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  Incr);.  }.}../*
b3d0: 0a 2a 2a 20 52 65 73 65 74 20 61 20 73 6f 72 74  .** Reset a sort
b3e0: 69 6e 67 20 63 75 72 73 6f 72 20 62 61 63 6b 20  ing cursor back 
b3f0: 74 6f 20 69 74 73 20 6f 72 69 67 69 6e 61 6c 20  to its original 
b400: 65 6d 70 74 79 20 73 74 61 74 65 2e 0a 2a 2f 0a  empty state..*/.
b410: 76 6f 69 64 20 73 71 6c 69 74 65 33 56 64 62 65  void sqlite3Vdbe
b420: 53 6f 72 74 65 72 52 65 73 65 74 28 73 71 6c 69  SorterReset(sqli
b430: 74 65 33 20 2a 64 62 2c 20 56 64 62 65 53 6f 72  te3 *db, VdbeSor
b440: 74 65 72 20 2a 70 53 6f 72 74 65 72 29 7b 0a 20  ter *pSorter){. 
b450: 20 69 6e 74 20 69 3b 0a 20 20 28 76 6f 69 64 29   int i;.  (void)
b460: 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e 41 6c  vdbeSorterJoinAl
b470: 6c 28 70 53 6f 72 74 65 72 2c 20 53 51 4c 49 54  l(pSorter, SQLIT
b480: 45 5f 4f 4b 29 3b 0a 20 20 61 73 73 65 72 74 28  E_OK);.  assert(
b490: 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68   pSorter->bUseTh
b4a0: 72 65 61 64 73 20 7c 7c 20 70 53 6f 72 74 65 72  reads || pSorter
b4b0: 2d 3e 70 52 65 61 64 65 72 3d 3d 30 20 29 3b 0a  ->pReader==0 );.
b4c0: 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57  #if SQLITE_MAX_W
b4d0: 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 0a  ORKER_THREADS>0.
b4e0: 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 70    if( pSorter->p
b4f0: 52 65 61 64 65 72 20 29 7b 0a 20 20 20 20 76 64  Reader ){.    vd
b500: 62 65 50 6d 61 52 65 61 64 65 72 43 6c 65 61 72  bePmaReaderClear
b510: 28 70 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65  (pSorter->pReade
b520: 72 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 44  r);.    sqlite3D
b530: 62 46 72 65 65 28 64 62 2c 20 70 53 6f 72 74 65  bFree(db, pSorte
b540: 72 2d 3e 70 52 65 61 64 65 72 29 3b 0a 20 20 20  r->pReader);.   
b550: 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65   pSorter->pReade
b560: 72 20 3d 20 30 3b 0a 20 20 7d 0a 23 65 6e 64 69  r = 0;.  }.#endi
b570: 66 0a 20 20 76 64 62 65 4d 65 72 67 65 45 6e 67  f.  vdbeMergeEng
b580: 69 6e 65 46 72 65 65 28 70 53 6f 72 74 65 72 2d  ineFree(pSorter-
b590: 3e 70 4d 65 72 67 65 72 29 3b 0a 20 20 70 53 6f  >pMerger);.  pSo
b5a0: 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 20 3d 20  rter->pMerger = 
b5b0: 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  0;.  for(i=0; i<
b5c0: 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3b 20  pSorter->nTask; 
b5d0: 69 2b 2b 29 7b 0a 20 20 20 20 53 6f 72 74 53 75  i++){.    SortSu
b5e0: 62 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20 26  btask *pTask = &
b5f0: 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 69  pSorter->aTask[i
b600: 5d 3b 0a 20 20 20 20 76 64 62 65 53 6f 72 74 53  ];.    vdbeSortS
b610: 75 62 74 61 73 6b 43 6c 65 61 6e 75 70 28 64 62  ubtaskCleanup(db
b620: 2c 20 70 54 61 73 6b 29 3b 0a 20 20 20 20 70 54  , pTask);.    pT
b630: 61 73 6b 2d 3e 70 53 6f 72 74 65 72 20 3d 20 70  ask->pSorter = p
b640: 53 6f 72 74 65 72 3b 0a 20 20 7d 0a 20 20 69 66  Sorter;.  }.  if
b650: 28 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e  ( pSorter->list.
b660: 61 4d 65 6d 6f 72 79 3d 3d 30 20 29 7b 0a 20 20  aMemory==0 ){.  
b670: 20 20 76 64 62 65 53 6f 72 74 65 72 52 65 63 6f    vdbeSorterReco
b680: 72 64 46 72 65 65 28 30 2c 20 70 53 6f 72 74 65  rdFree(0, pSorte
b690: 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 29 3b 0a  r->list.pList);.
b6a0: 20 20 7d 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6c    }.  pSorter->l
b6b0: 69 73 74 2e 70 4c 69 73 74 20 3d 20 30 3b 0a 20  ist.pList = 0;. 
b6c0: 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 73   pSorter->list.s
b6d0: 7a 50 4d 41 20 3d 20 30 3b 0a 20 20 70 53 6f 72  zPMA = 0;.  pSor
b6e0: 74 65 72 2d 3e 62 55 73 65 50 4d 41 20 3d 20 30  ter->bUsePMA = 0
b6f0: 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65  ;.  pSorter->iMe
b700: 6d 6f 72 79 20 3d 20 30 3b 0a 20 20 70 53 6f 72  mory = 0;.  pSor
b710: 74 65 72 2d 3e 6d 78 4b 65 79 73 69 7a 65 20 3d  ter->mxKeysize =
b720: 20 30 3b 0a 20 20 73 71 6c 69 74 65 33 44 62 46   0;.  sqlite3DbF
b730: 72 65 65 28 64 62 2c 20 70 53 6f 72 74 65 72 2d  ree(db, pSorter-
b740: 3e 70 55 6e 70 61 63 6b 65 64 29 3b 0a 20 20 70  >pUnpacked);.  p
b750: 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65  Sorter->pUnpacke
b760: 64 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  d = 0;.}../*.** 
b770: 46 72 65 65 20 61 6e 79 20 63 75 72 73 6f 72 20  Free any cursor 
b780: 63 6f 6d 70 6f 6e 65 6e 74 73 20 61 6c 6c 6f 63  components alloc
b790: 61 74 65 64 20 62 79 20 73 71 6c 69 74 65 33 56  ated by sqlite3V
b7a0: 64 62 65 53 6f 72 74 65 72 58 58 58 20 72 6f 75  dbeSorterXXX rou
b7b0: 74 69 6e 65 73 2e 0a 2a 2f 0a 76 6f 69 64 20 73  tines..*/.void s
b7c0: 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72  qlite3VdbeSorter
b7d0: 43 6c 6f 73 65 28 73 71 6c 69 74 65 33 20 2a 64  Close(sqlite3 *d
b7e0: 62 2c 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70  b, VdbeCursor *p
b7f0: 43 73 72 29 7b 0a 20 20 56 64 62 65 53 6f 72 74  Csr){.  VdbeSort
b800: 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43  er *pSorter = pC
b810: 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69  sr->pSorter;.  i
b820: 66 28 20 70 53 6f 72 74 65 72 20 29 7b 0a 20 20  f( pSorter ){.  
b830: 20 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72    sqlite3VdbeSor
b840: 74 65 72 52 65 73 65 74 28 64 62 2c 20 70 53 6f  terReset(db, pSo
b850: 72 74 65 72 29 3b 0a 20 20 20 20 73 71 6c 69 74  rter);.    sqlit
b860: 65 33 5f 66 72 65 65 28 70 53 6f 72 74 65 72 2d  e3_free(pSorter-
b870: 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 29 3b 0a  >list.aMemory);.
b880: 20 20 20 20 73 71 6c 69 74 65 33 44 62 46 72 65      sqlite3DbFre
b890: 65 28 64 62 2c 20 70 53 6f 72 74 65 72 29 3b 0a  e(db, pSorter);.
b8a0: 20 20 20 20 70 43 73 72 2d 3e 70 53 6f 72 74 65      pCsr->pSorte
b8b0: 72 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 23 69  r = 0;.  }.}..#i
b8c0: 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 4d 4d 41  f SQLITE_MAX_MMA
b8d0: 50 5f 53 49 5a 45 3e 30 0a 2f 2a 0a 2a 2a 20 54  P_SIZE>0./*.** T
b8e0: 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e  he first argumen
b8f0: 74 20 69 73 20 61 20 66 69 6c 65 2d 68 61 6e 64  t is a file-hand
b900: 6c 65 20 6f 70 65 6e 20 6f 6e 20 61 20 74 65 6d  le open on a tem
b910: 70 6f 72 61 72 79 20 66 69 6c 65 2e 20 54 68 65  porary file. The
b920: 20 66 69 6c 65 0a 2a 2a 20 69 73 20 67 75 61 72   file.** is guar
b930: 61 6e 74 65 65 64 20 74 6f 20 62 65 20 6e 42 79  anteed to be nBy
b940: 74 65 20 62 79 74 65 73 20 6f 72 20 73 6d 61 6c  te bytes or smal
b950: 6c 65 72 20 69 6e 20 73 69 7a 65 2e 20 54 68 69  ler in size. Thi
b960: 73 20 66 75 6e 63 74 69 6f 6e 0a 2a 2a 20 61 74  s function.** at
b970: 74 65 6d 70 74 73 20 74 6f 20 65 78 74 65 6e 64  tempts to extend
b980: 20 74 68 65 20 66 69 6c 65 20 74 6f 20 6e 42 79   the file to nBy
b990: 74 65 20 62 79 74 65 73 20 69 6e 20 73 69 7a 65  te bytes in size
b9a0: 20 61 6e 64 20 74 6f 20 65 6e 73 75 72 65 20 74   and to ensure t
b9b0: 68 61 74 0a 2a 2a 20 74 68 65 20 56 46 53 20 68  hat.** the VFS h
b9c0: 61 73 20 6d 65 6d 6f 72 79 20 6d 61 70 70 65 64  as memory mapped
b9d0: 20 69 74 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 74 68   it..**.** Wheth
b9e0: 65 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 66 69  er or not the fi
b9f0: 6c 65 20 64 6f 65 73 20 65 6e 64 20 75 70 20 6d  le does end up m
ba00: 65 6d 6f 72 79 20 6d 61 70 70 65 64 20 6f 66 20  emory mapped of 
ba10: 63 6f 75 72 73 65 20 64 65 70 65 6e 64 73 20 6f  course depends o
ba20: 6e 0a 2a 2a 20 74 68 65 20 73 70 65 63 69 66 69  n.** the specifi
ba30: 63 20 56 46 53 20 69 6d 70 6c 65 6d 65 6e 74 61  c VFS implementa
ba40: 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  tion..*/.static 
ba50: 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72 45  void vdbeSorterE
ba60: 78 74 65 6e 64 46 69 6c 65 28 73 71 6c 69 74 65  xtendFile(sqlite
ba70: 33 20 2a 64 62 2c 20 73 71 6c 69 74 65 33 5f 66  3 *db, sqlite3_f
ba80: 69 6c 65 20 2a 70 46 64 2c 20 69 36 34 20 6e 42  ile *pFd, i64 nB
ba90: 79 74 65 29 7b 0a 20 20 69 66 28 20 6e 42 79 74  yte){.  if( nByt
baa0: 65 3c 3d 28 69 36 34 29 28 64 62 2d 3e 6e 4d 61  e<=(i64)(db->nMa
bab0: 78 53 6f 72 74 65 72 4d 6d 61 70 29 20 26 26 20  xSorterMmap) && 
bac0: 70 46 64 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 69  pFd->pMethods->i
bad0: 56 65 72 73 69 6f 6e 3e 3d 33 20 29 7b 0a 20 20  Version>=3 ){.  
bae0: 20 20 76 6f 69 64 20 2a 70 20 3d 20 30 3b 0a 20    void *p = 0;. 
baf0: 20 20 20 69 6e 74 20 63 68 75 6e 6b 73 69 7a 65     int chunksize
bb00: 20 3d 20 34 2a 31 30 32 34 3b 0a 20 20 20 20 73   = 4*1024;.    s
bb10: 71 6c 69 74 65 33 4f 73 46 69 6c 65 43 6f 6e 74  qlite3OsFileCont
bb20: 72 6f 6c 48 69 6e 74 28 70 46 64 2c 20 53 51 4c  rolHint(pFd, SQL
bb30: 49 54 45 5f 46 43 4e 54 4c 5f 43 48 55 4e 4b 5f  ITE_FCNTL_CHUNK_
bb40: 53 49 5a 45 2c 20 26 63 68 75 6e 6b 73 69 7a 65  SIZE, &chunksize
bb50: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73  );.    sqlite3Os
bb60: 46 69 6c 65 43 6f 6e 74 72 6f 6c 48 69 6e 74 28  FileControlHint(
bb70: 70 46 64 2c 20 53 51 4c 49 54 45 5f 46 43 4e 54  pFd, SQLITE_FCNT
bb80: 4c 5f 53 49 5a 45 5f 48 49 4e 54 2c 20 26 6e 42  L_SIZE_HINT, &nB
bb90: 79 74 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  yte);.    sqlite
bba0: 33 4f 73 46 65 74 63 68 28 70 46 64 2c 20 30 2c  3OsFetch(pFd, 0,
bbb0: 20 28 69 6e 74 29 6e 42 79 74 65 2c 20 26 70 29   (int)nByte, &p)
bbc0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 55  ;.    sqlite3OsU
bbd0: 6e 66 65 74 63 68 28 70 46 64 2c 20 30 2c 20 70  nfetch(pFd, 0, p
bbe0: 29 3b 0a 20 20 7d 0a 7d 0a 23 65 6c 73 65 0a 23  );.  }.}.#else.#
bbf0: 20 64 65 66 69 6e 65 20 76 64 62 65 53 6f 72 74   define vdbeSort
bc00: 65 72 45 78 74 65 6e 64 46 69 6c 65 28 78 2c 79  erExtendFile(x,y
bc10: 2c 7a 29 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a  ,z).#endif../*.*
bc20: 2a 20 41 6c 6c 6f 63 61 74 65 20 73 70 61 63 65  * Allocate space
bc30: 20 66 6f 72 20 61 20 66 69 6c 65 2d 68 61 6e 64   for a file-hand
bc40: 6c 65 20 61 6e 64 20 6f 70 65 6e 20 61 20 74 65  le and open a te
bc50: 6d 70 6f 72 61 72 79 20 66 69 6c 65 2e 20 49 66  mporary file. If
bc60: 20 73 75 63 63 65 73 73 66 75 6c 2c 0a 2a 2a 20   successful,.** 
bc70: 73 65 74 20 2a 70 70 46 64 20 74 6f 20 70 6f 69  set *ppFd to poi
bc80: 6e 74 20 74 6f 20 74 68 65 20 6d 61 6c 6c 6f 63  nt to the malloc
bc90: 27 64 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20 61  'd file-handle a
bca0: 6e 64 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  nd return SQLITE
bcb0: 5f 4f 4b 2e 0a 2a 2a 20 4f 74 68 65 72 77 69 73  _OK..** Otherwis
bcc0: 65 2c 20 73 65 74 20 2a 70 70 46 64 20 74 6f 20  e, set *ppFd to 
bcd0: 30 20 61 6e 64 20 72 65 74 75 72 6e 20 61 6e 20  0 and return an 
bce0: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
bcf0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
bd00: 20 76 64 62 65 53 6f 72 74 65 72 4f 70 65 6e 54   vdbeSorterOpenT
bd10: 65 6d 70 46 69 6c 65 28 0a 20 20 73 71 6c 69 74  empFile(.  sqlit
bd20: 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20  e3 *db,         
bd30: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
bd40: 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 64 6f  tabase handle do
bd50: 69 6e 67 20 73 6f 72 74 20 2a 2f 0a 20 20 69 36  ing sort */.  i6
bd60: 34 20 6e 45 78 74 65 6e 64 2c 20 20 20 20 20 20  4 nExtend,      
bd70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
bd80: 20 41 74 74 65 6d 70 74 20 74 6f 20 65 78 74 65   Attempt to exte
bd90: 6e 64 20 66 69 6c 65 20 74 6f 20 74 68 69 73 20  nd file to this 
bda0: 73 69 7a 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65  size */.  sqlite
bdb0: 33 5f 66 69 6c 65 20 2a 2a 70 70 46 64 0a 29 7b  3_file **ppFd.){
bdc0: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 66 28  .  int rc;.  if(
bdd0: 20 73 71 6c 69 74 65 33 46 61 75 6c 74 53 69 6d   sqlite3FaultSim
bde0: 28 32 30 32 29 20 29 20 72 65 74 75 72 6e 20 53  (202) ) return S
bdf0: 51 4c 49 54 45 5f 49 4f 45 52 52 5f 41 43 43 45  QLITE_IOERR_ACCE
be00: 53 53 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  SS;.  rc = sqlit
be10: 65 33 4f 73 4f 70 65 6e 4d 61 6c 6c 6f 63 28 64  e3OsOpenMalloc(d
be20: 62 2d 3e 70 56 66 73 2c 20 30 2c 20 70 70 46 64  b->pVfs, 0, ppFd
be30: 2c 0a 20 20 20 20 20 20 53 51 4c 49 54 45 5f 4f  ,.      SQLITE_O
be40: 50 45 4e 5f 54 45 4d 50 5f 4a 4f 55 52 4e 41 4c  PEN_TEMP_JOURNAL
be50: 20 7c 0a 20 20 20 20 20 20 53 51 4c 49 54 45 5f   |.      SQLITE_
be60: 4f 50 45 4e 5f 52 45 41 44 57 52 49 54 45 20 20  OPEN_READWRITE  
be70: 20 20 7c 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f    | SQLITE_OPEN_
be80: 43 52 45 41 54 45 20 7c 0a 20 20 20 20 20 20 53  CREATE |.      S
be90: 51 4c 49 54 45 5f 4f 50 45 4e 5f 45 58 43 4c 55  QLITE_OPEN_EXCLU
bea0: 53 49 56 45 20 20 20 20 7c 20 53 51 4c 49 54 45  SIVE    | SQLITE
beb0: 5f 4f 50 45 4e 5f 44 45 4c 45 54 45 4f 4e 43 4c  _OPEN_DELETEONCL
bec0: 4f 53 45 2c 20 26 72 63 0a 20 20 29 3b 0a 20 20  OSE, &rc.  );.  
bed0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
bee0: 4b 20 29 7b 0a 20 20 20 20 69 36 34 20 6d 61 78  K ){.    i64 max
bef0: 20 3d 20 53 51 4c 49 54 45 5f 4d 41 58 5f 4d 4d   = SQLITE_MAX_MM
bf00: 41 50 5f 53 49 5a 45 3b 0a 20 20 20 20 73 71 6c  AP_SIZE;.    sql
bf10: 69 74 65 33 4f 73 46 69 6c 65 43 6f 6e 74 72 6f  ite3OsFileContro
bf20: 6c 48 69 6e 74 28 2a 70 70 46 64 2c 20 53 51 4c  lHint(*ppFd, SQL
bf30: 49 54 45 5f 46 43 4e 54 4c 5f 4d 4d 41 50 5f 53  ITE_FCNTL_MMAP_S
bf40: 49 5a 45 2c 20 28 76 6f 69 64 2a 29 26 6d 61 78  IZE, (void*)&max
bf50: 29 3b 0a 20 20 20 20 69 66 28 20 6e 45 78 74 65  );.    if( nExte
bf60: 6e 64 3e 30 20 29 7b 0a 20 20 20 20 20 20 76 64  nd>0 ){.      vd
bf70: 62 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46 69  beSorterExtendFi
bf80: 6c 65 28 64 62 2c 20 2a 70 70 46 64 2c 20 6e 45  le(db, *ppFd, nE
bf90: 78 74 65 6e 64 29 3b 0a 20 20 20 20 7d 0a 20 20  xtend);.    }.  
bfa0: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
bfb0: 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 69 74 20 68 61  ../*.** If it ha
bfc0: 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 62 65  s not already be
bfd0: 65 6e 20 61 6c 6c 6f 63 61 74 65 64 2c 20 61 6c  en allocated, al
bfe0: 6c 6f 63 61 74 65 20 74 68 65 20 55 6e 70 61 63  locate the Unpac
bff0: 6b 65 64 52 65 63 6f 72 64 20 0a 2a 2a 20 73 74  kedRecord .** st
c000: 72 75 63 74 75 72 65 20 61 74 20 70 54 61 73 6b  ructure at pTask
c010: 2d 3e 70 55 6e 70 61 63 6b 65 64 2e 20 52 65 74  ->pUnpacked. Ret
c020: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66  urn SQLITE_OK if
c030: 20 73 75 63 63 65 73 73 66 75 6c 20 28 6f 72 20   successful (or 
c040: 0a 2a 2a 20 69 66 20 6e 6f 20 61 6c 6c 6f 63 61  .** if no alloca
c050: 74 69 6f 6e 20 77 61 73 20 72 65 71 75 69 72 65  tion was require
c060: 64 29 2c 20 6f 72 20 53 51 4c 49 54 45 5f 4e 4f  d), or SQLITE_NO
c070: 4d 45 4d 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a  MEM otherwise..*
c080: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
c090: 65 53 6f 72 74 41 6c 6c 6f 63 55 6e 70 61 63 6b  eSortAllocUnpack
c0a0: 65 64 28 53 6f 72 74 53 75 62 74 61 73 6b 20 2a  ed(SortSubtask *
c0b0: 70 54 61 73 6b 29 7b 0a 20 20 69 66 28 20 70 54  pTask){.  if( pT
c0c0: 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 3d 3d  ask->pUnpacked==
c0d0: 30 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 70  0 ){.    char *p
c0e0: 46 72 65 65 3b 0a 20 20 20 20 70 54 61 73 6b 2d  Free;.    pTask-
c0f0: 3e 70 55 6e 70 61 63 6b 65 64 20 3d 20 73 71 6c  >pUnpacked = sql
c100: 69 74 65 33 56 64 62 65 41 6c 6c 6f 63 55 6e 70  ite3VdbeAllocUnp
c110: 61 63 6b 65 64 52 65 63 6f 72 64 28 0a 20 20 20  ackedRecord(.   
c120: 20 20 20 20 20 70 54 61 73 6b 2d 3e 70 53 6f 72       pTask->pSor
c130: 74 65 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20 30  ter->pKeyInfo, 0
c140: 2c 20 30 2c 20 26 70 46 72 65 65 0a 20 20 20 20  , 0, &pFree.    
c150: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
c160: 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 3d  Task->pUnpacked=
c170: 3d 28 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64  =(UnpackedRecord
c180: 2a 29 70 46 72 65 65 20 29 3b 0a 20 20 20 20 69  *)pFree );.    i
c190: 66 28 20 70 46 72 65 65 3d 3d 30 20 29 20 72 65  f( pFree==0 ) re
c1a0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
c1b0: 4d 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 70 55  M;.    pTask->pU
c1c0: 6e 70 61 63 6b 65 64 2d 3e 6e 46 69 65 6c 64 20  npacked->nField 
c1d0: 3d 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72  = pTask->pSorter
c1e0: 2d 3e 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69 65  ->pKeyInfo->nFie
c1f0: 6c 64 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 70  ld;.    pTask->p
c200: 55 6e 70 61 63 6b 65 64 2d 3e 65 72 72 43 6f 64  Unpacked->errCod
c210: 65 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74  e = 0;.  }.  ret
c220: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
c230: 0a 0a 0a 2f 2a 0a 2a 2a 20 4d 65 72 67 65 20 74  .../*.** Merge t
c240: 68 65 20 74 77 6f 20 73 6f 72 74 65 64 20 6c 69  he two sorted li
c250: 73 74 73 20 70 31 20 61 6e 64 20 70 32 20 69 6e  sts p1 and p2 in
c260: 74 6f 20 61 20 73 69 6e 67 6c 65 20 6c 69 73 74  to a single list
c270: 2e 0a 2a 2a 20 53 65 74 20 2a 70 70 4f 75 74 20  ..** Set *ppOut 
c280: 74 6f 20 74 68 65 20 68 65 61 64 20 6f 66 20 74  to the head of t
c290: 68 65 20 6e 65 77 20 6c 69 73 74 2e 0a 2a 2f 0a  he new list..*/.
c2a0: 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65  static void vdbe
c2b0: 53 6f 72 74 65 72 4d 65 72 67 65 28 0a 20 20 53  SorterMerge(.  S
c2c0: 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
c2d0: 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  k,             /
c2e0: 2a 20 43 61 6c 6c 69 6e 67 20 74 68 72 65 61 64  * Calling thread
c2f0: 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 53 6f   context */.  So
c300: 72 74 65 72 52 65 63 6f 72 64 20 2a 70 31 2c 20  rterRecord *p1, 
c310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c320: 20 46 69 72 73 74 20 6c 69 73 74 20 74 6f 20 6d   First list to m
c330: 65 72 67 65 20 2a 2f 0a 20 20 53 6f 72 74 65 72  erge */.  Sorter
c340: 52 65 63 6f 72 64 20 2a 70 32 2c 20 20 20 20 20  Record *p2,     
c350: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 63            /* Sec
c360: 6f 6e 64 20 6c 69 73 74 20 74 6f 20 6d 65 72 67  ond list to merg
c370: 65 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63  e */.  SorterRec
c380: 6f 72 64 20 2a 2a 70 70 4f 75 74 20 20 20 20 20  ord **ppOut     
c390: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 48         /* OUT: H
c3a0: 65 61 64 20 6f 66 20 6d 65 72 67 65 64 20 6c 69  ead of merged li
c3b0: 73 74 20 2a 2f 0a 29 7b 0a 20 20 53 6f 72 74 65  st */.){.  Sorte
c3c0: 72 52 65 63 6f 72 64 20 2a 70 46 69 6e 61 6c 20  rRecord *pFinal 
c3d0: 3d 20 30 3b 0a 20 20 53 6f 72 74 65 72 52 65 63  = 0;.  SorterRec
c3e0: 6f 72 64 20 2a 2a 70 70 20 3d 20 26 70 46 69 6e  ord **pp = &pFin
c3f0: 61 6c 3b 0a 20 20 69 6e 74 20 62 43 61 63 68 65  al;.  int bCache
c400: 64 20 3d 20 30 3b 0a 0a 20 20 77 68 69 6c 65 28  d = 0;..  while(
c410: 20 70 31 20 26 26 20 70 32 20 29 7b 0a 20 20 20   p1 && p2 ){.   
c420: 20 69 6e 74 20 72 65 73 3b 0a 20 20 20 20 72 65   int res;.    re
c430: 73 20 3d 20 70 54 61 73 6b 2d 3e 78 43 6f 6d 70  s = pTask->xComp
c440: 61 72 65 28 0a 20 20 20 20 20 20 20 20 70 54 61  are(.        pTa
c450: 73 6b 2c 20 26 62 43 61 63 68 65 64 2c 20 53 52  sk, &bCached, SR
c460: 56 41 4c 28 70 31 29 2c 20 70 31 2d 3e 6e 56 61  VAL(p1), p1->nVa
c470: 6c 2c 20 53 52 56 41 4c 28 70 32 29 2c 20 70 32  l, SRVAL(p2), p2
c480: 2d 3e 6e 56 61 6c 0a 20 20 20 20 29 3b 0a 0a 20  ->nVal.    );.. 
c490: 20 20 20 69 66 28 20 72 65 73 3c 3d 30 20 29 7b     if( res<=0 ){
c4a0: 0a 20 20 20 20 20 20 2a 70 70 20 3d 20 70 31 3b  .      *pp = p1;
c4b0: 0a 20 20 20 20 20 20 70 70 20 3d 20 26 70 31 2d  .      pp = &p1-
c4c0: 3e 75 2e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  >u.pNext;.      
c4d0: 70 31 20 3d 20 70 31 2d 3e 75 2e 70 4e 65 78 74  p1 = p1->u.pNext
c4e0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
c4f0: 20 20 20 2a 70 70 20 3d 20 70 32 3b 0a 20 20 20     *pp = p2;.   
c500: 20 20 20 70 70 20 3d 20 26 70 32 2d 3e 75 2e 70     pp = &p2->u.p
c510: 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 32 20 3d  Next;.      p2 =
c520: 20 70 32 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20 20   p2->u.pNext;.  
c530: 20 20 20 20 62 43 61 63 68 65 64 20 3d 20 30 3b      bCached = 0;
c540: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 70  .    }.  }.  *pp
c550: 20 3d 20 70 31 20 3f 20 70 31 20 3a 20 70 32 3b   = p1 ? p1 : p2;
c560: 0a 20 20 2a 70 70 4f 75 74 20 3d 20 70 46 69 6e  .  *ppOut = pFin
c570: 61 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  al;.}../*.** Ret
c580: 75 72 6e 20 74 68 65 20 53 6f 72 74 65 72 43 6f  urn the SorterCo
c590: 6d 70 61 72 65 20 66 75 6e 63 74 69 6f 6e 20 74  mpare function t
c5a0: 6f 20 63 6f 6d 70 61 72 65 20 76 61 6c 75 65 73  o compare values
c5b0: 20 63 6f 6c 6c 65 63 74 65 64 20 62 79 20 74 68   collected by th
c5c0: 65 0a 2a 2a 20 73 6f 72 74 65 72 20 6f 62 6a 65  e.** sorter obje
c5d0: 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68 65  ct passed as the
c5e0: 20 6f 6e 6c 79 20 61 72 67 75 6d 65 6e 74 2e 0a   only argument..
c5f0: 2a 2f 0a 73 74 61 74 69 63 20 53 6f 72 74 65 72  */.static Sorter
c600: 43 6f 6d 70 61 72 65 20 76 64 62 65 53 6f 72 74  Compare vdbeSort
c610: 65 72 47 65 74 43 6f 6d 70 61 72 65 28 56 64 62  erGetCompare(Vdb
c620: 65 53 6f 72 74 65 72 20 2a 70 29 7b 0a 20 20 69  eSorter *p){.  i
c630: 66 28 20 70 2d 3e 74 79 70 65 4d 61 73 6b 3d 3d  f( p->typeMask==
c640: 53 4f 52 54 45 52 5f 54 59 50 45 5f 49 4e 54 45  SORTER_TYPE_INTE
c650: 47 45 52 20 29 7b 0a 20 20 20 20 72 65 74 75 72  GER ){.    retur
c660: 6e 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70  n vdbeSorterComp
c670: 61 72 65 49 6e 74 3b 0a 20 20 7d 65 6c 73 65 20  areInt;.  }else 
c680: 69 66 28 20 70 2d 3e 74 79 70 65 4d 61 73 6b 3d  if( p->typeMask=
c690: 3d 53 4f 52 54 45 52 5f 54 59 50 45 5f 54 45 58  =SORTER_TYPE_TEX
c6a0: 54 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  T ){.    return 
c6b0: 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72  vdbeSorterCompar
c6c0: 65 54 65 78 74 3b 20 0a 20 20 7d 0a 20 20 72 65  eText; .  }.  re
c6d0: 74 75 72 6e 20 76 64 62 65 53 6f 72 74 65 72 43  turn vdbeSorterC
c6e0: 6f 6d 70 61 72 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ompare;.}../*.**
c6f0: 20 53 6f 72 74 20 74 68 65 20 6c 69 6e 6b 65 64   Sort the linked
c700: 20 6c 69 73 74 20 6f 66 20 72 65 63 6f 72 64 73   list of records
c710: 20 68 65 61 64 65 64 20 61 74 20 70 54 61 73 6b   headed at pTask
c720: 2d 3e 70 4c 69 73 74 2e 20 52 65 74 75 72 6e 20  ->pList. Return 
c730: 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66  .** SQLITE_OK if
c740: 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20   successful, or 
c750: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
c760: 63 6f 64 65 20 28 69 2e 65 2e 20 53 51 4c 49 54  code (i.e. SQLIT
c770: 45 5f 4e 4f 4d 45 4d 29 20 69 66 20 0a 2a 2a 20  E_NOMEM) if .** 
c780: 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e  an error occurs.
c790: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
c7a0: 64 62 65 53 6f 72 74 65 72 53 6f 72 74 28 53 6f  dbeSorterSort(So
c7b0: 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b  rtSubtask *pTask
c7c0: 2c 20 53 6f 72 74 65 72 4c 69 73 74 20 2a 70 4c  , SorterList *pL
c7d0: 69 73 74 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  ist){.  int i;. 
c7e0: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 2a   SorterRecord **
c7f0: 61 53 6c 6f 74 3b 0a 20 20 53 6f 72 74 65 72 52  aSlot;.  SorterR
c800: 65 63 6f 72 64 20 2a 70 3b 0a 20 20 69 6e 74 20  ecord *p;.  int 
c810: 72 63 3b 0a 0a 20 20 72 63 20 3d 20 76 64 62 65  rc;..  rc = vdbe
c820: 53 6f 72 74 41 6c 6c 6f 63 55 6e 70 61 63 6b 65  SortAllocUnpacke
c830: 64 28 70 54 61 73 6b 29 3b 0a 20 20 69 66 28 20  d(pTask);.  if( 
c840: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
c850: 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 70 20  return rc;..  p 
c860: 3d 20 70 4c 69 73 74 2d 3e 70 4c 69 73 74 3b 0a  = pList->pList;.
c870: 20 20 70 54 61 73 6b 2d 3e 78 43 6f 6d 70 61 72    pTask->xCompar
c880: 65 20 3d 20 76 64 62 65 53 6f 72 74 65 72 47 65  e = vdbeSorterGe
c890: 74 43 6f 6d 70 61 72 65 28 70 54 61 73 6b 2d 3e  tCompare(pTask->
c8a0: 70 53 6f 72 74 65 72 29 3b 0a 0a 20 20 61 53 6c  pSorter);..  aSl
c8b0: 6f 74 20 3d 20 28 53 6f 72 74 65 72 52 65 63 6f  ot = (SorterReco
c8c0: 72 64 20 2a 2a 29 73 71 6c 69 74 65 33 4d 61 6c  rd **)sqlite3Mal
c8d0: 6c 6f 63 5a 65 72 6f 28 36 34 20 2a 20 73 69 7a  locZero(64 * siz
c8e0: 65 6f 66 28 53 6f 72 74 65 72 52 65 63 6f 72 64  eof(SorterRecord
c8f0: 20 2a 29 29 3b 0a 20 20 69 66 28 20 21 61 53 6c   *));.  if( !aSl
c900: 6f 74 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  ot ){.    return
c910: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
c920: 20 7d 0a 0a 20 20 77 68 69 6c 65 28 20 70 20 29   }..  while( p )
c930: 7b 0a 20 20 20 20 53 6f 72 74 65 72 52 65 63 6f  {.    SorterReco
c940: 72 64 20 2a 70 4e 65 78 74 3b 0a 20 20 20 20 69  rd *pNext;.    i
c950: 66 28 20 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f 72  f( pList->aMemor
c960: 79 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 28  y ){.      if( (
c970: 75 38 2a 29 70 3d 3d 70 4c 69 73 74 2d 3e 61 4d  u8*)p==pList->aM
c980: 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20 20 20  emory ){.       
c990: 20 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20   pNext = 0;.    
c9a0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
c9b0: 20 61 73 73 65 72 74 28 20 70 2d 3e 75 2e 69 4e   assert( p->u.iN
c9c0: 65 78 74 3c 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  ext<sqlite3Mallo
c9d0: 63 53 69 7a 65 28 70 4c 69 73 74 2d 3e 61 4d 65  cSize(pList->aMe
c9e0: 6d 6f 72 79 29 20 29 3b 0a 20 20 20 20 20 20 20  mory) );.       
c9f0: 20 70 4e 65 78 74 20 3d 20 28 53 6f 72 74 65 72   pNext = (Sorter
ca00: 52 65 63 6f 72 64 2a 29 26 70 4c 69 73 74 2d 3e  Record*)&pList->
ca10: 61 4d 65 6d 6f 72 79 5b 70 2d 3e 75 2e 69 4e 65  aMemory[p->u.iNe
ca20: 78 74 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  xt];.      }.   
ca30: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 4e   }else{.      pN
ca40: 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74  ext = p->u.pNext
ca50: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 2d 3e  ;.    }..    p->
ca60: 75 2e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20  u.pNext = 0;.   
ca70: 20 66 6f 72 28 69 3d 30 3b 20 61 53 6c 6f 74 5b   for(i=0; aSlot[
ca80: 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  i]; i++){.      
ca90: 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28  vdbeSorterMerge(
caa0: 70 54 61 73 6b 2c 20 70 2c 20 61 53 6c 6f 74 5b  pTask, p, aSlot[
cab0: 69 5d 2c 20 26 70 29 3b 0a 20 20 20 20 20 20 61  i], &p);.      a
cac0: 53 6c 6f 74 5b 69 5d 20 3d 20 30 3b 0a 20 20 20  Slot[i] = 0;.   
cad0: 20 7d 0a 20 20 20 20 61 53 6c 6f 74 5b 69 5d 20   }.    aSlot[i] 
cae0: 3d 20 70 3b 0a 20 20 20 20 70 20 3d 20 70 4e 65  = p;.    p = pNe
caf0: 78 74 3b 0a 20 20 7d 0a 0a 20 20 70 20 3d 20 30  xt;.  }..  p = 0
cb00: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 36  ;.  for(i=0; i<6
cb10: 34 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 76 64 62  4; i++){.    vdb
cb20: 65 53 6f 72 74 65 72 4d 65 72 67 65 28 70 54 61  eSorterMerge(pTa
cb30: 73 6b 2c 20 70 2c 20 61 53 6c 6f 74 5b 69 5d 2c  sk, p, aSlot[i],
cb40: 20 26 70 29 3b 0a 20 20 7d 0a 20 20 70 4c 69 73   &p);.  }.  pLis
cb50: 74 2d 3e 70 4c 69 73 74 20 3d 20 70 3b 0a 0a 20  t->pList = p;.. 
cb60: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 53   sqlite3_free(aS
cb70: 6c 6f 74 29 3b 0a 20 20 61 73 73 65 72 74 28 20  lot);.  assert( 
cb80: 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64  pTask->pUnpacked
cb90: 2d 3e 65 72 72 43 6f 64 65 3d 3d 53 51 4c 49 54  ->errCode==SQLIT
cba0: 45 5f 4f 4b 20 0a 20 20 20 20 20 20 20 7c 7c 20  E_OK .       || 
cbb0: 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64  pTask->pUnpacked
cbc0: 2d 3e 65 72 72 43 6f 64 65 3d 3d 53 51 4c 49 54  ->errCode==SQLIT
cbd0: 45 5f 4e 4f 4d 45 4d 20 0a 20 20 29 3b 0a 20 20  E_NOMEM .  );.  
cbe0: 72 65 74 75 72 6e 20 70 54 61 73 6b 2d 3e 70 55  return pTask->pU
cbf0: 6e 70 61 63 6b 65 64 2d 3e 65 72 72 43 6f 64 65  npacked->errCode
cc00: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69  ;.}../*.** Initi
cc10: 61 6c 69 7a 65 20 61 20 50 4d 41 2d 77 72 69 74  alize a PMA-writ
cc20: 65 72 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74  er object..*/.st
cc30: 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 50 6d  atic void vdbePm
cc40: 61 57 72 69 74 65 72 49 6e 69 74 28 0a 20 20 73  aWriterInit(.  s
cc50: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 64  qlite3_file *pFd
cc60: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
cc70: 2a 20 46 69 6c 65 20 68 61 6e 64 6c 65 20 74 6f  * File handle to
cc80: 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a 20 20 50   write to */.  P
cc90: 6d 61 57 72 69 74 65 72 20 2a 70 2c 20 20 20 20  maWriter *p,    
cca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
ccb0: 2a 20 4f 62 6a 65 63 74 20 74 6f 20 70 6f 70 75  * Object to popu
ccc0: 6c 61 74 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  late */.  int nB
ccd0: 75 66 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  uf,             
cce0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66            /* Buf
ccf0: 66 65 72 20 73 69 7a 65 20 2a 2f 0a 20 20 69 36  fer size */.  i6
cd00: 34 20 69 53 74 61 72 74 20 20 20 20 20 20 20 20  4 iStart        
cd10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
cd20: 20 4f 66 66 73 65 74 20 6f 66 20 70 46 64 20 74   Offset of pFd t
cd30: 6f 20 62 65 67 69 6e 20 77 72 69 74 69 6e 67 20  o begin writing 
cd40: 61 74 20 2a 2f 0a 29 7b 0a 20 20 6d 65 6d 73 65  at */.){.  memse
cd50: 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50  t(p, 0, sizeof(P
cd60: 6d 61 57 72 69 74 65 72 29 29 3b 0a 20 20 70 2d  maWriter));.  p-
cd70: 3e 61 42 75 66 66 65 72 20 3d 20 28 75 38 2a 29  >aBuffer = (u8*)
cd80: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 6e 42  sqlite3Malloc(nB
cd90: 75 66 29 3b 0a 20 20 69 66 28 20 21 70 2d 3e 61  uf);.  if( !p->a
cda0: 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20 70 2d  Buffer ){.    p-
cdb0: 3e 65 46 57 45 72 72 20 3d 20 53 51 4c 49 54 45  >eFWErr = SQLITE
cdc0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b  _NOMEM;.  }else{
cdd0: 0a 20 20 20 20 70 2d 3e 69 42 75 66 45 6e 64 20  .    p->iBufEnd 
cde0: 3d 20 70 2d 3e 69 42 75 66 53 74 61 72 74 20 3d  = p->iBufStart =
cdf0: 20 28 69 53 74 61 72 74 20 25 20 6e 42 75 66 29   (iStart % nBuf)
ce00: 3b 0a 20 20 20 20 70 2d 3e 69 57 72 69 74 65 4f  ;.    p->iWriteO
ce10: 66 66 20 3d 20 69 53 74 61 72 74 20 2d 20 70 2d  ff = iStart - p-
ce20: 3e 69 42 75 66 53 74 61 72 74 3b 0a 20 20 20 20  >iBufStart;.    
ce30: 70 2d 3e 6e 42 75 66 66 65 72 20 3d 20 6e 42 75  p->nBuffer = nBu
ce40: 66 3b 0a 20 20 20 20 70 2d 3e 70 46 64 20 3d 20  f;.    p->pFd = 
ce50: 70 46 64 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  pFd;.  }.}../*.*
ce60: 2a 20 57 72 69 74 65 20 6e 44 61 74 61 20 62 79  * Write nData by
ce70: 74 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 74  tes of data to t
ce80: 68 65 20 50 4d 41 2e 20 52 65 74 75 72 6e 20 53  he PMA. Return S
ce90: 51 4c 49 54 45 5f 4f 4b 0a 2a 2a 20 69 66 20 73  QLITE_OK.** if s
cea0: 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e  uccessful, or an
ceb0: 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
cec0: 64 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f  de if an error o
ced0: 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  ccurs..*/.static
cee0: 20 76 6f 69 64 20 76 64 62 65 50 6d 61 57 72 69   void vdbePmaWri
cef0: 74 65 42 6c 6f 62 28 50 6d 61 57 72 69 74 65 72  teBlob(PmaWriter
cf00: 20 2a 70 2c 20 75 38 20 2a 70 44 61 74 61 2c 20   *p, u8 *pData, 
cf10: 69 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20 69 6e  int nData){.  in
cf20: 74 20 6e 52 65 6d 20 3d 20 6e 44 61 74 61 3b 0a  t nRem = nData;.
cf30: 20 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30 20    while( nRem>0 
cf40: 26 26 20 70 2d 3e 65 46 57 45 72 72 3d 3d 30 20  && p->eFWErr==0 
cf50: 29 7b 0a 20 20 20 20 69 6e 74 20 6e 43 6f 70 79  ){.    int nCopy
cf60: 20 3d 20 6e 52 65 6d 3b 0a 20 20 20 20 69 66 28   = nRem;.    if(
cf70: 20 6e 43 6f 70 79 3e 28 70 2d 3e 6e 42 75 66 66   nCopy>(p->nBuff
cf80: 65 72 20 2d 20 70 2d 3e 69 42 75 66 45 6e 64 29  er - p->iBufEnd)
cf90: 20 29 7b 0a 20 20 20 20 20 20 6e 43 6f 70 79 20   ){.      nCopy 
cfa0: 3d 20 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 70  = p->nBuffer - p
cfb0: 2d 3e 69 42 75 66 45 6e 64 3b 0a 20 20 20 20 7d  ->iBufEnd;.    }
cfc0: 0a 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d  ..    memcpy(&p-
cfd0: 3e 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66  >aBuffer[p->iBuf
cfe0: 45 6e 64 5d 2c 20 26 70 44 61 74 61 5b 6e 44 61  End], &pData[nDa
cff0: 74 61 2d 6e 52 65 6d 5d 2c 20 6e 43 6f 70 79 29  ta-nRem], nCopy)
d000: 3b 0a 20 20 20 20 70 2d 3e 69 42 75 66 45 6e 64  ;.    p->iBufEnd
d010: 20 2b 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 69   += nCopy;.    i
d020: 66 28 20 70 2d 3e 69 42 75 66 45 6e 64 3d 3d 70  f( p->iBufEnd==p
d030: 2d 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20  ->nBuffer ){.   
d040: 20 20 20 70 2d 3e 65 46 57 45 72 72 20 3d 20 73     p->eFWErr = s
d050: 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d  qlite3OsWrite(p-
d060: 3e 70 46 64 2c 20 0a 20 20 20 20 20 20 20 20 20  >pFd, .         
d070: 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 70 2d 3e   &p->aBuffer[p->
d080: 69 42 75 66 53 74 61 72 74 5d 2c 20 70 2d 3e 69  iBufStart], p->i
d090: 42 75 66 45 6e 64 20 2d 20 70 2d 3e 69 42 75 66  BufEnd - p->iBuf
d0a0: 53 74 61 72 74 2c 20 0a 20 20 20 20 20 20 20 20  Start, .        
d0b0: 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b    p->iWriteOff +
d0c0: 20 70 2d 3e 69 42 75 66 53 74 61 72 74 0a 20 20   p->iBufStart.  
d0d0: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e      );.      p->
d0e0: 69 42 75 66 53 74 61 72 74 20 3d 20 70 2d 3e 69  iBufStart = p->i
d0f0: 42 75 66 45 6e 64 20 3d 20 30 3b 0a 20 20 20 20  BufEnd = 0;.    
d100: 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b    p->iWriteOff +
d110: 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20  = p->nBuffer;.  
d120: 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20    }.    assert( 
d130: 70 2d 3e 69 42 75 66 45 6e 64 3c 70 2d 3e 6e 42  p->iBufEnd<p->nB
d140: 75 66 66 65 72 20 29 3b 0a 0a 20 20 20 20 6e 52  uffer );..    nR
d150: 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20 7d  em -= nCopy;.  }
d160: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68 20  .}../*.** Flush 
d170: 61 6e 79 20 62 75 66 66 65 72 65 64 20 64 61 74  any buffered dat
d180: 61 20 74 6f 20 64 69 73 6b 20 61 6e 64 20 63 6c  a to disk and cl
d190: 65 61 6e 20 75 70 20 74 68 65 20 50 4d 41 2d 77  ean up the PMA-w
d1a0: 72 69 74 65 72 20 6f 62 6a 65 63 74 2e 0a 2a 2a  riter object..**
d1b0: 20 54 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20   The results of 
d1c0: 75 73 69 6e 67 20 74 68 65 20 50 4d 41 2d 77 72  using the PMA-wr
d1d0: 69 74 65 72 20 61 66 74 65 72 20 74 68 69 73 20  iter after this 
d1e0: 63 61 6c 6c 20 61 72 65 20 75 6e 64 65 66 69 6e  call are undefin
d1f0: 65 64 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 53 51  ed..** Return SQ
d200: 4c 49 54 45 5f 4f 4b 20 69 66 20 66 6c 75 73 68  LITE_OK if flush
d210: 69 6e 67 20 74 68 65 20 62 75 66 66 65 72 65 64  ing the buffered
d220: 20 64 61 74 61 20 73 75 63 63 65 65 64 73 20 6f   data succeeds o
d230: 72 20 69 73 20 6e 6f 74 20 0a 2a 2a 20 72 65 71  r is not .** req
d240: 75 69 72 65 64 2e 20 4f 74 68 65 72 77 69 73 65  uired. Otherwise
d250: 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69  , return an SQLi
d260: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a  te error code..*
d270: 2a 0a 2a 2a 20 42 65 66 6f 72 65 20 72 65 74 75  *.** Before retu
d280: 72 6e 69 6e 67 2c 20 73 65 74 20 2a 70 69 45 6f  rning, set *piEo
d290: 66 20 74 6f 20 74 68 65 20 6f 66 66 73 65 74 20  f to the offset 
d2a0: 69 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c 6c  immediately foll
d2b0: 6f 77 69 6e 67 20 74 68 65 0a 2a 2a 20 6c 61 73  owing the.** las
d2c0: 74 20 62 79 74 65 20 77 72 69 74 74 65 6e 20 74  t byte written t
d2d0: 6f 20 74 68 65 20 66 69 6c 65 2e 0a 2a 2f 0a 73  o the file..*/.s
d2e0: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d  tatic int vdbePm
d2f0: 61 57 72 69 74 65 72 46 69 6e 69 73 68 28 50 6d  aWriterFinish(Pm
d300: 61 57 72 69 74 65 72 20 2a 70 2c 20 69 36 34 20  aWriter *p, i64 
d310: 2a 70 69 45 6f 66 29 7b 0a 20 20 69 6e 74 20 72  *piEof){.  int r
d320: 63 3b 0a 20 20 69 66 28 20 70 2d 3e 65 46 57 45  c;.  if( p->eFWE
d330: 72 72 3d 3d 30 20 26 26 20 41 4c 57 41 59 53 28  rr==0 && ALWAYS(
d340: 70 2d 3e 61 42 75 66 66 65 72 29 20 26 26 20 70  p->aBuffer) && p
d350: 2d 3e 69 42 75 66 45 6e 64 3e 70 2d 3e 69 42 75  ->iBufEnd>p->iBu
d360: 66 53 74 61 72 74 20 29 7b 0a 20 20 20 20 70 2d  fStart ){.    p-
d370: 3e 65 46 57 45 72 72 20 3d 20 73 71 6c 69 74 65  >eFWErr = sqlite
d380: 33 4f 73 57 72 69 74 65 28 70 2d 3e 70 46 64 2c  3OsWrite(p->pFd,
d390: 20 0a 20 20 20 20 20 20 20 20 26 70 2d 3e 61 42   .        &p->aB
d3a0: 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 53 74 61  uffer[p->iBufSta
d3b0: 72 74 5d 2c 20 70 2d 3e 69 42 75 66 45 6e 64 20  rt], p->iBufEnd 
d3c0: 2d 20 70 2d 3e 69 42 75 66 53 74 61 72 74 2c 20  - p->iBufStart, 
d3d0: 0a 20 20 20 20 20 20 20 20 70 2d 3e 69 57 72 69  .        p->iWri
d3e0: 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42 75 66 53  teOff + p->iBufS
d3f0: 74 61 72 74 0a 20 20 20 20 29 3b 0a 20 20 7d 0a  tart.    );.  }.
d400: 20 20 2a 70 69 45 6f 66 20 3d 20 28 70 2d 3e 69    *piEof = (p->i
d410: 57 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42  WriteOff + p->iB
d420: 75 66 45 6e 64 29 3b 0a 20 20 73 71 6c 69 74 65  ufEnd);.  sqlite
d430: 33 5f 66 72 65 65 28 70 2d 3e 61 42 75 66 66 65  3_free(p->aBuffe
d440: 72 29 3b 0a 20 20 72 63 20 3d 20 70 2d 3e 65 46  r);.  rc = p->eF
d450: 57 45 72 72 3b 0a 20 20 6d 65 6d 73 65 74 28 70  WErr;.  memset(p
d460: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50 6d 61 57  , 0, sizeof(PmaW
d470: 72 69 74 65 72 29 29 3b 0a 20 20 72 65 74 75 72  riter));.  retur
d480: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57  n rc;.}../*.** W
d490: 72 69 74 65 20 76 61 6c 75 65 20 69 56 61 6c 20  rite value iVal 
d4a0: 65 6e 63 6f 64 65 64 20 61 73 20 61 20 76 61 72  encoded as a var
d4b0: 69 6e 74 20 74 6f 20 74 68 65 20 50 4d 41 2e 20  int to the PMA. 
d4c0: 52 65 74 75 72 6e 20 0a 2a 2a 20 53 51 4c 49 54  Return .** SQLIT
d4d0: 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66  E_OK if successf
d4e0: 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65  ul, or an SQLite
d4f0: 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20 61   error code if a
d500: 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a  n error occurs..
d510: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76  */.static void v
d520: 64 62 65 50 6d 61 57 72 69 74 65 56 61 72 69 6e  dbePmaWriteVarin
d530: 74 28 50 6d 61 57 72 69 74 65 72 20 2a 70 2c 20  t(PmaWriter *p, 
d540: 75 36 34 20 69 56 61 6c 29 7b 0a 20 20 69 6e 74  u64 iVal){.  int
d550: 20 6e 42 79 74 65 3b 20 0a 20 20 75 38 20 61 42   nByte; .  u8 aB
d560: 79 74 65 5b 31 30 5d 3b 0a 20 20 6e 42 79 74 65  yte[10];.  nByte
d570: 20 3d 20 73 71 6c 69 74 65 33 50 75 74 56 61 72   = sqlite3PutVar
d580: 69 6e 74 28 61 42 79 74 65 2c 20 69 56 61 6c 29  int(aByte, iVal)
d590: 3b 0a 20 20 76 64 62 65 50 6d 61 57 72 69 74 65  ;.  vdbePmaWrite
d5a0: 42 6c 6f 62 28 70 2c 20 61 42 79 74 65 2c 20 6e  Blob(p, aByte, n
d5b0: 42 79 74 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  Byte);.}../*.** 
d5c0: 57 72 69 74 65 20 74 68 65 20 63 75 72 72 65 6e  Write the curren
d5d0: 74 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 69 6e  t contents of in
d5e0: 2d 6d 65 6d 6f 72 79 20 6c 69 6e 6b 65 64 2d 6c  -memory linked-l
d5f0: 69 73 74 20 70 4c 69 73 74 20 74 6f 20 61 20 6c  ist pList to a l
d600: 65 76 65 6c 2d 30 0a 2a 2a 20 50 4d 41 20 69 6e  evel-0.** PMA in
d610: 20 74 68 65 20 74 65 6d 70 20 66 69 6c 65 20 62   the temp file b
d620: 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 73 75 62 2d  elonging to sub-
d630: 74 61 73 6b 20 70 54 61 73 6b 2e 20 52 65 74 75  task pTask. Retu
d640: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20  rn SQLITE_OK if 
d650: 0a 2a 2a 20 73 75 63 63 65 73 73 66 75 6c 2c 20  .** successful, 
d660: 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  or an SQLite err
d670: 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77 69 73  or code otherwis
d680: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66 6f 72  e..**.** The for
d690: 6d 61 74 20 6f 66 20 61 20 50 4d 41 20 69 73 3a  mat of a PMA is:
d6a0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 41 20 76  .**.**     * A v
d6b0: 61 72 69 6e 74 2e 20 54 68 69 73 20 76 61 72 69  arint. This vari
d6c0: 6e 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  nt contains the 
d6d0: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  total number of 
d6e0: 62 79 74 65 73 20 6f 66 20 63 6f 6e 74 65 6e 74  bytes of content
d6f0: 0a 2a 2a 20 20 20 20 20 20 20 69 6e 20 74 68 65  .**       in the
d700: 20 50 4d 41 20 28 6e 6f 74 20 69 6e 63 6c 75 64   PMA (not includ
d710: 69 6e 67 20 74 68 65 20 76 61 72 69 6e 74 20 69  ing the varint i
d720: 74 73 65 6c 66 29 2e 0a 2a 2a 0a 2a 2a 20 20 20  tself)..**.**   
d730: 20 20 2a 20 4f 6e 65 20 6f 72 20 6d 6f 72 65 20    * One or more 
d740: 72 65 63 6f 72 64 73 20 70 61 63 6b 65 64 20 65  records packed e
d750: 6e 64 2d 74 6f 2d 65 6e 64 20 69 6e 20 6f 72 64  nd-to-end in ord
d760: 65 72 20 6f 66 20 61 73 63 65 6e 64 69 6e 67 20  er of ascending 
d770: 6b 65 79 73 2e 20 0a 2a 2a 20 20 20 20 20 20 20  keys. .**       
d780: 45 61 63 68 20 72 65 63 6f 72 64 20 63 6f 6e 73  Each record cons
d790: 69 73 74 73 20 6f 66 20 61 20 76 61 72 69 6e 74  ists of a varint
d7a0: 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 61 20 62   followed by a b
d7b0: 6c 6f 62 20 6f 66 20 64 61 74 61 20 28 74 68 65  lob of data (the
d7c0: 20 0a 2a 2a 20 20 20 20 20 20 20 6b 65 79 29 2e   .**       key).
d7d0: 20 54 68 65 20 76 61 72 69 6e 74 20 69 73 20 74   The varint is t
d7e0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  he number of byt
d7f0: 65 73 20 69 6e 20 74 68 65 20 62 6c 6f 62 20 6f  es in the blob o
d800: 66 20 64 61 74 61 2e 0a 2a 2f 0a 73 74 61 74 69  f data..*/.stati
d810: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72  c int vdbeSorter
d820: 4c 69 73 74 54 6f 50 4d 41 28 53 6f 72 74 53 75  ListToPMA(SortSu
d830: 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 53 6f  btask *pTask, So
d840: 72 74 65 72 4c 69 73 74 20 2a 70 4c 69 73 74 29  rterList *pList)
d850: 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20  {.  sqlite3 *db 
d860: 3d 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72  = pTask->pSorter
d870: 2d 3e 64 62 3b 0a 20 20 69 6e 74 20 72 63 20 3d  ->db;.  int rc =
d880: 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20   SQLITE_OK;     
d890: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
d8a0: 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 50 6d 61 57  n code */.  PmaW
d8b0: 72 69 74 65 72 20 77 72 69 74 65 72 3b 20 20 20  riter writer;   
d8c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
d8d0: 62 6a 65 63 74 20 75 73 65 64 20 74 6f 20 77 72  bject used to wr
d8e0: 69 74 65 20 74 6f 20 74 68 65 20 66 69 6c 65 20  ite to the file 
d8f0: 2a 2f 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  */..#ifdef SQLIT
d900: 45 5f 44 45 42 55 47 0a 20 20 2f 2a 20 53 65 74  E_DEBUG.  /* Set
d910: 20 69 53 7a 20 74 6f 20 74 68 65 20 65 78 70 65   iSz to the expe
d920: 63 74 65 64 20 73 69 7a 65 20 6f 66 20 66 69 6c  cted size of fil
d930: 65 20 70 54 61 73 6b 2d 3e 66 69 6c 65 20 61 66  e pTask->file af
d940: 74 65 72 20 77 72 69 74 69 6e 67 20 74 68 65 20  ter writing the 
d950: 50 4d 41 2e 20 0a 20 20 2a 2a 20 54 68 69 73 20  PMA. .  ** This 
d960: 69 73 20 75 73 65 64 20 62 79 20 61 6e 20 61 73  is used by an as
d970: 73 65 72 74 28 29 20 73 74 61 74 65 6d 65 6e 74  sert() statement
d980: 20 61 74 20 74 68 65 20 65 6e 64 20 6f 66 20 74   at the end of t
d990: 68 69 73 20 66 75 6e 63 74 69 6f 6e 2e 20 20 2a  his function.  *
d9a0: 2f 0a 20 20 69 36 34 20 69 53 7a 20 3d 20 70 4c  /.  i64 iSz = pL
d9b0: 69 73 74 2d 3e 73 7a 50 4d 41 20 2b 20 73 71 6c  ist->szPMA + sql
d9c0: 69 74 65 33 56 61 72 69 6e 74 4c 65 6e 28 70 4c  ite3VarintLen(pL
d9d0: 69 73 74 2d 3e 73 7a 50 4d 41 29 20 2b 20 70 54  ist->szPMA) + pT
d9e0: 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 3b 0a  ask->file.iEof;.
d9f0: 23 65 6e 64 69 66 0a 0a 20 20 76 64 62 65 53 6f  #endif..  vdbeSo
da00: 72 74 65 72 57 6f 72 6b 44 65 62 75 67 28 70 54  rterWorkDebug(pT
da10: 61 73 6b 2c 20 22 65 6e 74 65 72 22 29 3b 0a 20  ask, "enter");. 
da20: 20 6d 65 6d 73 65 74 28 26 77 72 69 74 65 72 2c   memset(&writer,
da30: 20 30 2c 20 73 69 7a 65 6f 66 28 50 6d 61 57 72   0, sizeof(PmaWr
da40: 69 74 65 72 29 29 3b 0a 20 20 61 73 73 65 72 74  iter));.  assert
da50: 28 20 70 4c 69 73 74 2d 3e 73 7a 50 4d 41 3e 30  ( pList->szPMA>0
da60: 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65   );..  /* If the
da70: 20 66 69 72 73 74 20 74 65 6d 70 6f 72 61 72 79   first temporary
da80: 20 50 4d 41 20 66 69 6c 65 20 68 61 73 20 6e 6f   PMA file has no
da90: 74 20 62 65 65 6e 20 6f 70 65 6e 65 64 2c 20 6f  t been opened, o
daa0: 70 65 6e 20 69 74 20 6e 6f 77 2e 20 2a 2f 0a 20  pen it now. */. 
dab0: 20 69 66 28 20 70 54 61 73 6b 2d 3e 66 69 6c 65   if( pTask->file
dac0: 2e 70 46 64 3d 3d 30 20 29 7b 0a 20 20 20 20 72  .pFd==0 ){.    r
dad0: 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4f 70  c = vdbeSorterOp
dae0: 65 6e 54 65 6d 70 46 69 6c 65 28 64 62 2c 20 30  enTempFile(db, 0
daf0: 2c 20 26 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70  , &pTask->file.p
db00: 46 64 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  Fd);.    assert(
db10: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c   rc!=SQLITE_OK |
db20: 7c 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46  | pTask->file.pF
db30: 64 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  d );.    assert(
db40: 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f   pTask->file.iEo
db50: 66 3d 3d 30 20 29 3b 0a 20 20 20 20 61 73 73 65  f==0 );.    asse
db60: 72 74 28 20 70 54 61 73 6b 2d 3e 6e 50 4d 41 3d  rt( pTask->nPMA=
db70: 3d 30 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  =0 );.  }..  /* 
db80: 54 72 79 20 74 6f 20 67 65 74 20 74 68 65 20 66  Try to get the f
db90: 69 6c 65 20 74 6f 20 6d 65 6d 6f 72 79 20 6d 61  ile to memory ma
dba0: 70 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53  p */.  if( rc==S
dbb0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
dbc0: 76 64 62 65 53 6f 72 74 65 72 45 78 74 65 6e 64  vdbeSorterExtend
dbd0: 46 69 6c 65 28 64 62 2c 20 70 54 61 73 6b 2d 3e  File(db, pTask->
dbe0: 66 69 6c 65 2e 70 46 64 2c 20 70 54 61 73 6b 2d  file.pFd, pTask-
dbf0: 3e 66 69 6c 65 2e 69 45 6f 66 2b 70 4c 69 73 74  >file.iEof+pList
dc00: 2d 3e 73 7a 50 4d 41 2b 39 29 3b 0a 20 20 7d 0a  ->szPMA+9);.  }.
dc10: 0a 20 20 2f 2a 20 53 6f 72 74 20 74 68 65 20 6c  .  /* Sort the l
dc20: 69 73 74 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d  ist */.  if( rc=
dc30: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
dc40: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
dc50: 72 53 6f 72 74 28 70 54 61 73 6b 2c 20 70 4c 69  rSort(pTask, pLi
dc60: 73 74 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  st);.  }..  if( 
dc70: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
dc80: 0a 20 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72  .    SorterRecor
dc90: 64 20 2a 70 3b 0a 20 20 20 20 53 6f 72 74 65 72  d *p;.    Sorter
dca0: 52 65 63 6f 72 64 20 2a 70 4e 65 78 74 20 3d 20  Record *pNext = 
dcb0: 30 3b 0a 0a 20 20 20 20 76 64 62 65 50 6d 61 57  0;..    vdbePmaW
dcc0: 72 69 74 65 72 49 6e 69 74 28 70 54 61 73 6b 2d  riterInit(pTask-
dcd0: 3e 66 69 6c 65 2e 70 46 64 2c 20 26 77 72 69 74  >file.pFd, &writ
dce0: 65 72 2c 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74  er, pTask->pSort
dcf0: 65 72 2d 3e 70 67 73 7a 2c 0a 20 20 20 20 20 20  er->pgsz,.      
dd00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dd10: 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66  pTask->file.iEof
dd20: 29 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 6e 50  );.    pTask->nP
dd30: 4d 41 2b 2b 3b 0a 20 20 20 20 76 64 62 65 50 6d  MA++;.    vdbePm
dd40: 61 57 72 69 74 65 56 61 72 69 6e 74 28 26 77 72  aWriteVarint(&wr
dd50: 69 74 65 72 2c 20 70 4c 69 73 74 2d 3e 73 7a 50  iter, pList->szP
dd60: 4d 41 29 3b 0a 20 20 20 20 66 6f 72 28 70 3d 70  MA);.    for(p=p
dd70: 4c 69 73 74 2d 3e 70 4c 69 73 74 3b 20 70 3b 20  List->pList; p; 
dd80: 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20  p=pNext){.      
dd90: 70 4e 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65  pNext = p->u.pNe
dda0: 78 74 3b 0a 20 20 20 20 20 20 76 64 62 65 50 6d  xt;.      vdbePm
ddb0: 61 57 72 69 74 65 56 61 72 69 6e 74 28 26 77 72  aWriteVarint(&wr
ddc0: 69 74 65 72 2c 20 70 2d 3e 6e 56 61 6c 29 3b 0a  iter, p->nVal);.
ddd0: 20 20 20 20 20 20 76 64 62 65 50 6d 61 57 72 69        vdbePmaWri
dde0: 74 65 42 6c 6f 62 28 26 77 72 69 74 65 72 2c 20  teBlob(&writer, 
ddf0: 53 52 56 41 4c 28 70 29 2c 20 70 2d 3e 6e 56 61  SRVAL(p), p->nVa
de00: 6c 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 4c  l);.      if( pL
de10: 69 73 74 2d 3e 61 4d 65 6d 6f 72 79 3d 3d 30 20  ist->aMemory==0 
de20: 29 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70  ) sqlite3_free(p
de30: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 4c 69  );.    }.    pLi
de40: 73 74 2d 3e 70 4c 69 73 74 20 3d 20 70 3b 0a 20  st->pList = p;. 
de50: 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 57     rc = vdbePmaW
de60: 72 69 74 65 72 46 69 6e 69 73 68 28 26 77 72 69  riterFinish(&wri
de70: 74 65 72 2c 20 26 70 54 61 73 6b 2d 3e 66 69 6c  ter, &pTask->fil
de80: 65 2e 69 45 6f 66 29 3b 0a 20 20 7d 0a 0a 20 20  e.iEof);.  }..  
de90: 76 64 62 65 53 6f 72 74 65 72 57 6f 72 6b 44 65  vdbeSorterWorkDe
dea0: 62 75 67 28 70 54 61 73 6b 2c 20 22 65 78 69 74  bug(pTask, "exit
deb0: 22 29 3b 0a 20 20 61 73 73 65 72 74 28 20 72 63  ");.  assert( rc
dec0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70  !=SQLITE_OK || p
ded0: 4c 69 73 74 2d 3e 70 4c 69 73 74 3d 3d 30 20 29  List->pList==0 )
dee0: 3b 0a 20 20 61 73 73 65 72 74 28 20 72 63 21 3d  ;.  assert( rc!=
def0: 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 54 61  SQLITE_OK || pTa
df00: 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 3d 3d 69  sk->file.iEof==i
df10: 53 7a 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  Sz );.  return r
df20: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61  c;.}../*.** Adva
df30: 6e 63 65 20 74 68 65 20 4d 65 72 67 65 45 6e 67  nce the MergeEng
df40: 69 6e 65 20 74 6f 20 69 74 73 20 6e 65 78 74 20  ine to its next 
df50: 65 6e 74 72 79 2e 0a 2a 2a 20 53 65 74 20 2a 70  entry..** Set *p
df60: 62 45 6f 66 20 74 6f 20 74 72 75 65 20 74 68 65  bEof to true the
df70: 72 65 20 69 73 20 6e 6f 20 6e 65 78 74 20 65 6e  re is no next en
df80: 74 72 79 20 62 65 63 61 75 73 65 0a 2a 2a 20 74  try because.** t
df90: 68 65 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 68  he MergeEngine h
dfa0: 61 73 20 72 65 61 63 68 65 64 20 74 68 65 20 65  as reached the e
dfb0: 6e 64 20 6f 66 20 61 6c 6c 20 69 74 73 20 69 6e  nd of all its in
dfc0: 70 75 74 73 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75  puts..**.** Retu
dfd0: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20  rn SQLITE_OK if 
dfe0: 73 75 63 63 65 73 73 66 75 6c 20 6f 72 20 61 6e  successful or an
dff0: 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20 61   error code if a
e000: 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a  n error occurs..
e010: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
e020: 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 53 74 65  beMergeEngineSte
e030: 70 28 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65  p(.  MergeEngine
e040: 20 2a 70 4d 65 72 67 65 72 2c 20 20 20 20 20 20   *pMerger,      
e050: 2f 2a 20 54 68 65 20 6d 65 72 67 65 20 65 6e 67  /* The merge eng
e060: 69 6e 65 20 74 6f 20 61 64 76 61 6e 63 65 20 74  ine to advance t
e070: 6f 20 74 68 65 20 6e 65 78 74 20 72 6f 77 20 2a  o the next row *
e080: 2f 0a 20 20 69 6e 74 20 2a 70 62 45 6f 66 20 20  /.  int *pbEof  
e090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
e0a0: 2a 20 53 65 74 20 54 52 55 45 20 61 74 20 45 4f  * Set TRUE at EO
e0b0: 46 2e 20 20 53 65 74 20 66 61 6c 73 65 20 66 6f  F.  Set false fo
e0c0: 72 20 6d 6f 72 65 20 63 6f 6e 74 65 6e 74 20 2a  r more content *
e0d0: 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  /.){.  int rc;. 
e0e0: 20 69 6e 74 20 69 50 72 65 76 20 3d 20 70 4d 65   int iPrev = pMe
e0f0: 72 67 65 72 2d 3e 61 54 72 65 65 5b 31 5d 3b 2f  rger->aTree[1];/
e100: 2a 20 49 6e 64 65 78 20 6f 66 20 50 6d 61 52 65  * Index of PmaRe
e110: 61 64 65 72 20 74 6f 20 61 64 76 61 6e 63 65 20  ader to advance 
e120: 2a 2f 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b  */.  SortSubtask
e130: 20 2a 70 54 61 73 6b 20 3d 20 70 4d 65 72 67 65   *pTask = pMerge
e140: 72 2d 3e 70 54 61 73 6b 3b 0a 0a 20 20 2f 2a 20  r->pTask;..  /* 
e150: 41 64 76 61 6e 63 65 20 74 68 65 20 63 75 72 72  Advance the curr
e160: 65 6e 74 20 50 6d 61 52 65 61 64 65 72 20 2a 2f  ent PmaReader */
e170: 0a 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52  .  rc = vdbePmaR
e180: 65 61 64 65 72 4e 65 78 74 28 26 70 4d 65 72 67  eaderNext(&pMerg
e190: 65 72 2d 3e 61 52 65 61 64 72 5b 69 50 72 65 76  er->aReadr[iPrev
e1a0: 5d 29 3b 0a 0a 20 20 2f 2a 20 55 70 64 61 74 65  ]);..  /* Update
e1b0: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61 54 72   contents of aTr
e1c0: 65 65 5b 5d 20 2a 2f 0a 20 20 69 66 28 20 72 63  ee[] */.  if( rc
e1d0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
e1e0: 20 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20     int i;       
e1f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
e200: 2a 20 49 6e 64 65 78 20 6f 66 20 61 54 72 65 65  * Index of aTree
e210: 5b 5d 20 74 6f 20 72 65 63 61 6c 63 75 6c 61 74  [] to recalculat
e220: 65 20 2a 2f 0a 20 20 20 20 50 6d 61 52 65 61 64  e */.    PmaRead
e230: 65 72 20 2a 70 52 65 61 64 72 31 3b 20 20 20 20  er *pReadr1;    
e240: 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 50 6d       /* First Pm
e250: 61 52 65 61 64 65 72 20 74 6f 20 63 6f 6d 70 61  aReader to compa
e260: 72 65 20 2a 2f 0a 20 20 20 20 50 6d 61 52 65 61  re */.    PmaRea
e270: 64 65 72 20 2a 70 52 65 61 64 72 32 3b 20 20 20  der *pReadr2;   
e280: 20 20 20 20 20 20 2f 2a 20 53 65 63 6f 6e 64 20        /* Second 
e290: 50 6d 61 52 65 61 64 65 72 20 74 6f 20 63 6f 6d  PmaReader to com
e2a0: 70 61 72 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20  pare */.    int 
e2b0: 62 43 61 63 68 65 64 20 3d 20 30 3b 0a 0a 20 20  bCached = 0;..  
e2c0: 20 20 2f 2a 20 46 69 6e 64 20 74 68 65 20 66 69    /* Find the fi
e2d0: 72 73 74 20 74 77 6f 20 50 6d 61 52 65 61 64 65  rst two PmaReade
e2e0: 72 73 20 74 6f 20 63 6f 6d 70 61 72 65 2e 20 54  rs to compare. T
e2f0: 68 65 20 6f 6e 65 20 74 68 61 74 20 77 61 73 20  he one that was 
e300: 6a 75 73 74 0a 20 20 20 20 2a 2a 20 61 64 76 61  just.    ** adva
e310: 6e 63 65 64 20 28 69 50 72 65 76 29 20 61 6e 64  nced (iPrev) and
e320: 20 74 68 65 20 6f 6e 65 20 6e 65 78 74 20 74 6f   the one next to
e330: 20 69 74 20 69 6e 20 74 68 65 20 61 72 72 61 79   it in the array
e340: 2e 20 20 2a 2f 0a 20 20 20 20 70 52 65 61 64 72  .  */.    pReadr
e350: 31 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 52  1 = &pMerger->aR
e360: 65 61 64 72 5b 28 69 50 72 65 76 20 26 20 30 78  eadr[(iPrev & 0x
e370: 46 46 46 45 29 5d 3b 0a 20 20 20 20 70 52 65 61  FFFE)];.    pRea
e380: 64 72 32 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e  dr2 = &pMerger->
e390: 61 52 65 61 64 72 5b 28 69 50 72 65 76 20 7c 20  aReadr[(iPrev | 
e3a0: 30 78 30 30 30 31 29 5d 3b 0a 0a 20 20 20 20 66  0x0001)];..    f
e3b0: 6f 72 28 69 3d 28 70 4d 65 72 67 65 72 2d 3e 6e  or(i=(pMerger->n
e3c0: 54 72 65 65 2b 69 50 72 65 76 29 2f 32 3b 20 69  Tree+iPrev)/2; i
e3d0: 3e 30 3b 20 69 3d 69 2f 32 29 7b 0a 20 20 20 20  >0; i=i/2){.    
e3e0: 20 20 2f 2a 20 43 6f 6d 70 61 72 65 20 70 52 65    /* Compare pRe
e3f0: 61 64 72 31 20 61 6e 64 20 70 52 65 61 64 72 32  adr1 and pReadr2
e400: 2e 20 53 74 6f 72 65 20 74 68 65 20 72 65 73 75  . Store the resu
e410: 6c 74 20 69 6e 20 76 61 72 69 61 62 6c 65 20 69  lt in variable i
e420: 52 65 73 2e 20 2a 2f 0a 20 20 20 20 20 20 69 6e  Res. */.      in
e430: 74 20 69 52 65 73 3b 0a 20 20 20 20 20 20 69 66  t iRes;.      if
e440: 28 20 70 52 65 61 64 72 31 2d 3e 70 46 64 3d 3d  ( pReadr1->pFd==
e450: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 69 52 65  0 ){.        iRe
e460: 73 20 3d 20 2b 31 3b 0a 20 20 20 20 20 20 7d 65  s = +1;.      }e
e470: 6c 73 65 20 69 66 28 20 70 52 65 61 64 72 32 2d  lse if( pReadr2-
e480: 3e 70 46 64 3d 3d 30 20 29 7b 0a 20 20 20 20 20  >pFd==0 ){.     
e490: 20 20 20 69 52 65 73 20 3d 20 2d 31 3b 0a 20 20     iRes = -1;.  
e4a0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
e4b0: 20 20 20 69 52 65 73 20 3d 20 70 54 61 73 6b 2d     iRes = pTask-
e4c0: 3e 78 43 6f 6d 70 61 72 65 28 70 54 61 73 6b 2c  >xCompare(pTask,
e4d0: 20 26 62 43 61 63 68 65 64 2c 0a 20 20 20 20 20   &bCached,.     
e4e0: 20 20 20 20 20 20 20 70 52 65 61 64 72 31 2d 3e         pReadr1->
e4f0: 61 4b 65 79 2c 20 70 52 65 61 64 72 31 2d 3e 6e  aKey, pReadr1->n
e500: 4b 65 79 2c 20 70 52 65 61 64 72 32 2d 3e 61 4b  Key, pReadr2->aK
e510: 65 79 2c 20 70 52 65 61 64 72 32 2d 3e 6e 4b 65  ey, pReadr2->nKe
e520: 79 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20  y.        );.   
e530: 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 49     }..      /* I
e540: 66 20 70 52 65 61 64 72 31 20 63 6f 6e 74 61 69  f pReadr1 contai
e550: 6e 65 64 20 74 68 65 20 73 6d 61 6c 6c 65 72 20  ned the smaller 
e560: 76 61 6c 75 65 2c 20 73 65 74 20 61 54 72 65 65  value, set aTree
e570: 5b 69 5d 20 74 6f 20 69 74 73 20 69 6e 64 65 78  [i] to its index
e580: 2e 0a 20 20 20 20 20 20 2a 2a 20 54 68 65 6e 20  ..      ** Then 
e590: 73 65 74 20 70 52 65 61 64 72 32 20 74 6f 20 74  set pReadr2 to t
e5a0: 68 65 20 6e 65 78 74 20 50 6d 61 52 65 61 64 65  he next PmaReade
e5b0: 72 20 74 6f 20 63 6f 6d 70 61 72 65 20 74 6f 20  r to compare to 
e5c0: 70 52 65 61 64 72 31 2e 20 49 6e 20 74 68 69 73  pReadr1. In this
e5d0: 0a 20 20 20 20 20 20 2a 2a 20 63 61 73 65 20 74  .      ** case t
e5e0: 68 65 72 65 20 69 73 20 6e 6f 20 63 61 63 68 65  here is no cache
e5f0: 20 6f 66 20 70 52 65 61 64 72 32 20 69 6e 20 70   of pReadr2 in p
e600: 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 2c  Task->pUnpacked,
e610: 20 73 6f 20 73 65 74 0a 20 20 20 20 20 20 2a 2a   so set.      **
e620: 20 70 4b 65 79 32 20 74 6f 20 70 6f 69 6e 74 20   pKey2 to point 
e630: 74 6f 20 74 68 65 20 72 65 63 6f 72 64 20 62 65  to the record be
e640: 6c 6f 6e 67 69 6e 67 20 74 6f 20 70 52 65 61 64  longing to pRead
e650: 72 32 2e 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20  r2..      **.   
e660: 20 20 20 2a 2a 20 41 6c 74 65 72 6e 61 74 69 76     ** Alternativ
e670: 65 6c 79 2c 20 69 66 20 70 52 65 61 64 72 32 20  ely, if pReadr2 
e680: 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 73 6d 61  contains the sma
e690: 6c 6c 65 72 20 6f 66 20 74 68 65 20 74 77 6f 20  ller of the two 
e6a0: 76 61 6c 75 65 73 2c 0a 20 20 20 20 20 20 2a 2a  values,.      **
e6b0: 20 73 65 74 20 61 54 72 65 65 5b 69 5d 20 74 6f   set aTree[i] to
e6c0: 20 69 74 73 20 69 6e 64 65 78 20 61 6e 64 20 75   its index and u
e6d0: 70 64 61 74 65 20 70 52 65 61 64 72 31 2e 20 49  pdate pReadr1. I
e6e0: 66 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70  f vdbeSorterComp
e6f0: 61 72 65 28 29 0a 20 20 20 20 20 20 2a 2a 20 77  are().      ** w
e700: 61 73 20 61 63 74 75 61 6c 6c 79 20 63 61 6c 6c  as actually call
e710: 65 64 20 61 62 6f 76 65 2c 20 74 68 65 6e 20 70  ed above, then p
e720: 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 20  Task->pUnpacked 
e730: 6e 6f 77 20 63 6f 6e 74 61 69 6e 73 0a 20 20 20  now contains.   
e740: 20 20 20 2a 2a 20 61 20 76 61 6c 75 65 20 65 71     ** a value eq
e750: 75 69 76 61 6c 65 6e 74 20 74 6f 20 70 52 65 61  uivalent to pRea
e760: 64 72 32 2e 20 53 6f 20 73 65 74 20 70 4b 65 79  dr2. So set pKey
e770: 32 20 74 6f 20 4e 55 4c 4c 20 74 6f 20 70 72 65  2 to NULL to pre
e780: 76 65 6e 74 0a 20 20 20 20 20 20 2a 2a 20 76 64  vent.      ** vd
e790: 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28  beSorterCompare(
e7a0: 29 20 66 72 6f 6d 20 64 65 63 6f 64 69 6e 67 20  ) from decoding 
e7b0: 70 52 65 61 64 72 32 20 61 67 61 69 6e 2e 0a 20  pReadr2 again.. 
e7c0: 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a       **.      **
e7d0: 20 49 66 20 74 68 65 20 74 77 6f 20 76 61 6c 75   If the two valu
e7e0: 65 73 20 77 65 72 65 20 65 71 75 61 6c 2c 20 74  es were equal, t
e7f0: 68 65 6e 20 74 68 65 20 76 61 6c 75 65 20 66 72  hen the value fr
e800: 6f 6d 20 74 68 65 20 6f 6c 64 65 73 74 0a 20 20  om the oldest.  
e810: 20 20 20 20 2a 2a 20 50 4d 41 20 73 68 6f 75 6c      ** PMA shoul
e820: 64 20 62 65 20 63 6f 6e 73 69 64 65 72 65 64 20  d be considered 
e830: 73 6d 61 6c 6c 65 72 2e 20 54 68 65 20 56 64 62  smaller. The Vdb
e840: 65 53 6f 72 74 65 72 2e 61 52 65 61 64 72 5b 5d  eSorter.aReadr[]
e850: 20 61 72 72 61 79 0a 20 20 20 20 20 20 2a 2a 20   array.      ** 
e860: 69 73 20 73 6f 72 74 65 64 20 66 72 6f 6d 20 6f  is sorted from o
e870: 6c 64 65 73 74 20 74 6f 20 6e 65 77 65 73 74 2c  ldest to newest,
e880: 20 73 6f 20 70 52 65 61 64 72 31 20 63 6f 6e 74   so pReadr1 cont
e890: 61 69 6e 73 20 6f 6c 64 65 72 20 76 61 6c 75 65  ains older value
e8a0: 73 0a 20 20 20 20 20 20 2a 2a 20 74 68 61 6e 20  s.      ** than 
e8b0: 70 52 65 61 64 72 32 20 69 66 66 20 28 70 52 65  pReadr2 iff (pRe
e8c0: 61 64 72 31 3c 70 52 65 61 64 72 32 29 2e 20 20  adr1<pReadr2).  
e8d0: 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 69 52 65  */.      if( iRe
e8e0: 73 3c 30 20 7c 7c 20 28 69 52 65 73 3d 3d 30 20  s<0 || (iRes==0 
e8f0: 26 26 20 70 52 65 61 64 72 31 3c 70 52 65 61 64  && pReadr1<pRead
e900: 72 32 29 20 29 7b 0a 20 20 20 20 20 20 20 20 70  r2) ){.        p
e910: 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 5d  Merger->aTree[i]
e920: 20 3d 20 28 69 6e 74 29 28 70 52 65 61 64 72 31   = (int)(pReadr1
e930: 20 2d 20 70 4d 65 72 67 65 72 2d 3e 61 52 65 61   - pMerger->aRea
e940: 64 72 29 3b 0a 20 20 20 20 20 20 20 20 70 52 65  dr);.        pRe
e950: 61 64 72 32 20 3d 20 26 70 4d 65 72 67 65 72 2d  adr2 = &pMerger-
e960: 3e 61 52 65 61 64 72 5b 20 70 4d 65 72 67 65 72  >aReadr[ pMerger
e970: 2d 3e 61 54 72 65 65 5b 69 20 5e 20 30 78 30 30  ->aTree[i ^ 0x00
e980: 30 31 5d 20 5d 3b 0a 20 20 20 20 20 20 20 20 62  01] ];.        b
e990: 43 61 63 68 65 64 20 3d 20 30 3b 0a 20 20 20 20  Cached = 0;.    
e9a0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
e9b0: 20 69 66 28 20 70 52 65 61 64 72 31 2d 3e 70 46   if( pReadr1->pF
e9c0: 64 20 29 20 62 43 61 63 68 65 64 20 3d 20 30 3b  d ) bCached = 0;
e9d0: 0a 20 20 20 20 20 20 20 20 70 4d 65 72 67 65 72  .        pMerger
e9e0: 2d 3e 61 54 72 65 65 5b 69 5d 20 3d 20 28 69 6e  ->aTree[i] = (in
e9f0: 74 29 28 70 52 65 61 64 72 32 20 2d 20 70 4d 65  t)(pReadr2 - pMe
ea00: 72 67 65 72 2d 3e 61 52 65 61 64 72 29 3b 0a 20  rger->aReadr);. 
ea10: 20 20 20 20 20 20 20 70 52 65 61 64 72 31 20 3d         pReadr1 =
ea20: 20 26 70 4d 65 72 67 65 72 2d 3e 61 52 65 61 64   &pMerger->aRead
ea30: 72 5b 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65  r[ pMerger->aTre
ea40: 65 5b 69 20 5e 20 30 78 30 30 30 31 5d 20 5d 3b  e[i ^ 0x0001] ];
ea50: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
ea60: 20 20 20 2a 70 62 45 6f 66 20 3d 20 28 70 4d 65     *pbEof = (pMe
ea70: 72 67 65 72 2d 3e 61 52 65 61 64 72 5b 70 4d 65  rger->aReadr[pMe
ea80: 72 67 65 72 2d 3e 61 54 72 65 65 5b 31 5d 5d 2e  rger->aTree[1]].
ea90: 70 46 64 3d 3d 30 29 3b 0a 20 20 7d 0a 0a 20 20  pFd==0);.  }..  
eaa0: 72 65 74 75 72 6e 20 28 72 63 3d 3d 53 51 4c 49  return (rc==SQLI
eab0: 54 45 5f 4f 4b 20 3f 20 70 54 61 73 6b 2d 3e 70  TE_OK ? pTask->p
eac0: 55 6e 70 61 63 6b 65 64 2d 3e 65 72 72 43 6f 64  Unpacked->errCod
ead0: 65 20 3a 20 72 63 29 3b 0a 7d 0a 0a 23 69 66 20  e : rc);.}..#if 
eae0: 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45  SQLITE_MAX_WORKE
eaf0: 52 5f 54 48 52 45 41 44 53 3e 30 0a 2f 2a 0a 2a  R_THREADS>0./*.*
eb00: 2a 20 54 68 65 20 6d 61 69 6e 20 72 6f 75 74 69  * The main routi
eb10: 6e 65 20 66 6f 72 20 62 61 63 6b 67 72 6f 75 6e  ne for backgroun
eb20: 64 20 74 68 72 65 61 64 73 20 74 68 61 74 20 77  d threads that w
eb30: 72 69 74 65 20 6c 65 76 65 6c 2d 30 20 50 4d 41  rite level-0 PMA
eb40: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  s..*/.static voi
eb50: 64 20 2a 76 64 62 65 53 6f 72 74 65 72 46 6c 75  d *vdbeSorterFlu
eb60: 73 68 54 68 72 65 61 64 28 76 6f 69 64 20 2a 70  shThread(void *p
eb70: 43 74 78 29 7b 0a 20 20 53 6f 72 74 53 75 62 74  Ctx){.  SortSubt
eb80: 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20 28 53 6f  ask *pTask = (So
eb90: 72 74 53 75 62 74 61 73 6b 2a 29 70 43 74 78 3b  rtSubtask*)pCtx;
eba0: 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
ebb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ebc0: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
ebd0: 65 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70  e */.  assert( p
ebe0: 54 61 73 6b 2d 3e 62 44 6f 6e 65 3d 3d 30 20 29  Task->bDone==0 )
ebf0: 3b 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72  ;.  rc = vdbeSor
ec00: 74 65 72 4c 69 73 74 54 6f 50 4d 41 28 70 54 61  terListToPMA(pTa
ec10: 73 6b 2c 20 26 70 54 61 73 6b 2d 3e 6c 69 73 74  sk, &pTask->list
ec20: 29 3b 0a 20 20 70 54 61 73 6b 2d 3e 62 44 6f 6e  );.  pTask->bDon
ec30: 65 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20  e = 1;.  return 
ec40: 53 51 4c 49 54 45 5f 49 4e 54 5f 54 4f 5f 50 54  SQLITE_INT_TO_PT
ec50: 52 28 72 63 29 3b 0a 7d 0a 23 65 6e 64 69 66 20  R(rc);.}.#endif 
ec60: 2f 2a 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f  /* SQLITE_MAX_WO
ec70: 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 20 2a  RKER_THREADS>0 *
ec80: 2f 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68 20 74  /../*.** Flush t
ec90: 68 65 20 63 75 72 72 65 6e 74 20 63 6f 6e 74 65  he current conte
eca0: 6e 74 73 20 6f 66 20 56 64 62 65 53 6f 72 74 65  nts of VdbeSorte
ecb0: 72 2e 6c 69 73 74 20 74 6f 20 61 20 6e 65 77 20  r.list to a new 
ecc0: 50 4d 41 2c 20 70 6f 73 73 69 62 6c 79 0a 2a 2a  PMA, possibly.**
ecd0: 20 75 73 69 6e 67 20 61 20 62 61 63 6b 67 72 6f   using a backgro
ece0: 75 6e 64 20 74 68 72 65 61 64 2e 0a 2a 2f 0a 73  und thread..*/.s
ecf0: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
ed00: 72 74 65 72 46 6c 75 73 68 50 4d 41 28 56 64 62  rterFlushPMA(Vdb
ed10: 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72  eSorter *pSorter
ed20: 29 7b 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41  ){.#if SQLITE_MA
ed30: 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53  X_WORKER_THREADS
ed40: 3d 3d 30 0a 20 20 70 53 6f 72 74 65 72 2d 3e 62  ==0.  pSorter->b
ed50: 55 73 65 50 4d 41 20 3d 20 31 3b 0a 20 20 72 65  UsePMA = 1;.  re
ed60: 74 75 72 6e 20 76 64 62 65 53 6f 72 74 65 72 4c  turn vdbeSorterL
ed70: 69 73 74 54 6f 50 4d 41 28 26 70 53 6f 72 74 65  istToPMA(&pSorte
ed80: 72 2d 3e 61 54 61 73 6b 5b 30 5d 2c 20 26 70 53  r->aTask[0], &pS
ed90: 6f 72 74 65 72 2d 3e 6c 69 73 74 29 3b 0a 23 65  orter->list);.#e
eda0: 6c 73 65 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  lse.  int rc = S
edb0: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20  QLITE_OK;.  int 
edc0: 69 3b 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b  i;.  SortSubtask
edd0: 20 2a 70 54 61 73 6b 20 3d 20 30 3b 20 20 20 20   *pTask = 0;    
ede0: 2f 2a 20 54 68 72 65 61 64 20 63 6f 6e 74 65 78  /* Thread contex
edf0: 74 20 75 73 65 64 20 74 6f 20 63 72 65 61 74 65  t used to create
ee00: 20 6e 65 77 20 50 4d 41 20 2a 2f 0a 20 20 69 6e   new PMA */.  in
ee10: 74 20 6e 57 6f 72 6b 65 72 20 3d 20 28 70 53 6f  t nWorker = (pSo
ee20: 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 3b 0a  rter->nTask-1);.
ee30: 0a 20 20 2f 2a 20 53 65 74 20 74 68 65 20 66 6c  .  /* Set the fl
ee40: 61 67 20 74 6f 20 69 6e 64 69 63 61 74 65 20 74  ag to indicate t
ee50: 68 61 74 20 61 74 20 6c 65 61 73 74 20 6f 6e 65  hat at least one
ee60: 20 50 4d 41 20 68 61 73 20 62 65 65 6e 20 77 72   PMA has been wr
ee70: 69 74 74 65 6e 2e 20 0a 20 20 2a 2a 20 4f 72 20  itten. .  ** Or 
ee80: 77 69 6c 6c 20 62 65 2c 20 61 6e 79 68 6f 77 2e  will be, anyhow.
ee90: 20 20 2a 2f 0a 20 20 70 53 6f 72 74 65 72 2d 3e    */.  pSorter->
eea0: 62 55 73 65 50 4d 41 20 3d 20 31 3b 0a 0a 20 20  bUsePMA = 1;..  
eeb0: 2f 2a 20 53 65 6c 65 63 74 20 61 20 73 75 62 2d  /* Select a sub-
eec0: 74 61 73 6b 20 74 6f 20 73 6f 72 74 20 61 6e 64  task to sort and
eed0: 20 66 6c 75 73 68 20 74 68 65 20 63 75 72 72 65   flush the curre
eee0: 6e 74 20 6c 69 73 74 20 6f 66 20 69 6e 2d 6d 65  nt list of in-me
eef0: 6d 6f 72 79 0a 20 20 2a 2a 20 72 65 63 6f 72 64  mory.  ** record
ef00: 73 20 74 6f 20 64 69 73 6b 2e 20 49 66 20 74 68  s to disk. If th
ef10: 65 20 73 6f 72 74 65 72 20 69 73 20 72 75 6e 6e  e sorter is runn
ef20: 69 6e 67 20 69 6e 20 6d 75 6c 74 69 2d 74 68 72  ing in multi-thr
ef30: 65 61 64 65 64 20 6d 6f 64 65 2c 0a 20 20 2a 2a  eaded mode,.  **
ef40: 20 72 6f 75 6e 64 2d 72 6f 62 69 6e 20 62 65 74   round-robin bet
ef50: 77 65 65 6e 20 74 68 65 20 66 69 72 73 74 20 28  ween the first (
ef60: 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31  pSorter->nTask-1
ef70: 29 20 74 61 73 6b 73 2e 20 45 78 63 65 70 74 2c  ) tasks. Except,
ef80: 20 69 66 0a 20 20 2a 2a 20 74 68 65 20 62 61 63   if.  ** the bac
ef90: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 66  kground thread f
efa0: 72 6f 6d 20 61 20 73 75 62 2d 74 61 73 6b 73 20  rom a sub-tasks 
efb0: 70 72 65 76 69 6f 75 73 20 74 75 72 6e 20 69 73  previous turn is
efc0: 20 73 74 69 6c 6c 20 72 75 6e 6e 69 6e 67 2c 0a   still running,.
efd0: 20 20 2a 2a 20 73 6b 69 70 20 69 74 2e 20 49 66    ** skip it. If
efe0: 20 74 68 65 20 66 69 72 73 74 20 28 70 53 6f 72   the first (pSor
eff0: 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 20 73 75  ter->nTask-1) su
f000: 62 2d 74 61 73 6b 73 20 61 72 65 20 61 6c 6c 20  b-tasks are all 
f010: 73 74 69 6c 6c 20 62 75 73 79 2c 0a 20 20 2a 2a  still busy,.  **
f020: 20 66 61 6c 6c 20 62 61 63 6b 20 74 6f 20 75 73   fall back to us
f030: 69 6e 67 20 74 68 65 20 66 69 6e 61 6c 20 73 75  ing the final su
f040: 62 2d 74 61 73 6b 2e 20 54 68 65 20 66 69 72 73  b-task. The firs
f050: 74 20 28 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73  t (pSorter->nTas
f060: 6b 2d 31 29 0a 20 20 2a 2a 20 73 75 62 2d 74 61  k-1).  ** sub-ta
f070: 73 6b 73 20 61 72 65 20 70 72 65 66 65 72 65 64  sks are prefered
f080: 20 61 73 20 74 68 65 79 20 75 73 65 20 62 61 63   as they use bac
f090: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 73 20  kground threads 
f0a0: 2d 20 74 68 65 20 66 69 6e 61 6c 20 0a 20 20 2a  - the final .  *
f0b0: 2a 20 73 75 62 2d 74 61 73 6b 20 75 73 65 73 20  * sub-task uses 
f0c0: 74 68 65 20 6d 61 69 6e 20 74 68 72 65 61 64 2e  the main thread.
f0d0: 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69   */.  for(i=0; i
f0e0: 3c 6e 57 6f 72 6b 65 72 3b 20 69 2b 2b 29 7b 0a  <nWorker; i++){.
f0f0: 20 20 20 20 69 6e 74 20 69 54 65 73 74 20 3d 20      int iTest = 
f100: 28 70 53 6f 72 74 65 72 2d 3e 69 50 72 65 76 20  (pSorter->iPrev 
f110: 2b 20 69 20 2b 20 31 29 20 25 20 6e 57 6f 72 6b  + i + 1) % nWork
f120: 65 72 3b 0a 20 20 20 20 70 54 61 73 6b 20 3d 20  er;.    pTask = 
f130: 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b  &pSorter->aTask[
f140: 69 54 65 73 74 5d 3b 0a 20 20 20 20 69 66 28 20  iTest];.    if( 
f150: 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 20 29 7b 0a  pTask->bDone ){.
f160: 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53        rc = vdbeS
f170: 6f 72 74 65 72 4a 6f 69 6e 54 68 72 65 61 64 28  orterJoinThread(
f180: 70 54 61 73 6b 29 3b 0a 20 20 20 20 7d 0a 20 20  pTask);.    }.  
f190: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
f1a0: 5f 4f 4b 20 7c 7c 20 70 54 61 73 6b 2d 3e 70 54  _OK || pTask->pT
f1b0: 68 72 65 61 64 3d 3d 30 20 29 20 62 72 65 61 6b  hread==0 ) break
f1c0: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  ;.  }..  if( rc=
f1d0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
f1e0: 20 20 69 66 28 20 69 3d 3d 6e 57 6f 72 6b 65 72    if( i==nWorker
f1f0: 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 55 73 65   ){.      /* Use
f200: 20 74 68 65 20 66 6f 72 65 67 72 6f 75 6e 64 20   the foreground 
f210: 74 68 72 65 61 64 20 66 6f 72 20 74 68 69 73 20  thread for this 
f220: 6f 70 65 72 61 74 69 6f 6e 20 2a 2f 0a 20 20 20  operation */.   
f230: 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74     rc = vdbeSort
f240: 65 72 4c 69 73 74 54 6f 50 4d 41 28 26 70 53 6f  erListToPMA(&pSo
f250: 72 74 65 72 2d 3e 61 54 61 73 6b 5b 6e 57 6f 72  rter->aTask[nWor
f260: 6b 65 72 5d 2c 20 26 70 53 6f 72 74 65 72 2d 3e  ker], &pSorter->
f270: 6c 69 73 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65  list);.    }else
f280: 7b 0a 20 20 20 20 20 20 2f 2a 20 4c 61 75 6e 63  {.      /* Launc
f290: 68 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74  h a background t
f2a0: 68 72 65 61 64 20 66 6f 72 20 74 68 69 73 20 6f  hread for this o
f2b0: 70 65 72 61 74 69 6f 6e 20 2a 2f 0a 20 20 20 20  peration */.    
f2c0: 20 20 75 38 20 2a 61 4d 65 6d 20 3d 20 70 54 61    u8 *aMem = pTa
f2d0: 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  sk->list.aMemory
f2e0: 3b 0a 20 20 20 20 20 20 76 6f 69 64 20 2a 70 43  ;.      void *pC
f2f0: 74 78 20 3d 20 28 76 6f 69 64 2a 29 70 54 61 73  tx = (void*)pTas
f300: 6b 3b 0a 0a 20 20 20 20 20 20 61 73 73 65 72 74  k;..      assert
f310: 28 20 70 54 61 73 6b 2d 3e 70 54 68 72 65 61 64  ( pTask->pThread
f320: 3d 3d 30 20 26 26 20 70 54 61 73 6b 2d 3e 62 44  ==0 && pTask->bD
f330: 6f 6e 65 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20  one==0 );.      
f340: 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 6c  assert( pTask->l
f350: 69 73 74 2e 70 4c 69 73 74 3d 3d 30 20 29 3b 0a  ist.pList==0 );.
f360: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 54        assert( pT
f370: 61 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72  ask->list.aMemor
f380: 79 3d 3d 30 20 7c 7c 20 70 53 6f 72 74 65 72 2d  y==0 || pSorter-
f390: 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 21 3d 30  >list.aMemory!=0
f3a0: 20 29 3b 0a 0a 20 20 20 20 20 20 70 53 6f 72 74   );..      pSort
f3b0: 65 72 2d 3e 69 50 72 65 76 20 3d 20 28 75 38 29  er->iPrev = (u8)
f3c0: 28 70 54 61 73 6b 20 2d 20 70 53 6f 72 74 65 72  (pTask - pSorter
f3d0: 2d 3e 61 54 61 73 6b 29 3b 0a 20 20 20 20 20 20  ->aTask);.      
f3e0: 70 54 61 73 6b 2d 3e 6c 69 73 74 20 3d 20 70 53  pTask->list = pS
f3f0: 6f 72 74 65 72 2d 3e 6c 69 73 74 3b 0a 20 20 20  orter->list;.   
f400: 20 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74     pSorter->list
f410: 2e 70 4c 69 73 74 20 3d 20 30 3b 0a 20 20 20 20  .pList = 0;.    
f420: 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e    pSorter->list.
f430: 73 7a 50 4d 41 20 3d 20 30 3b 0a 20 20 20 20 20  szPMA = 0;.     
f440: 20 69 66 28 20 61 4d 65 6d 20 29 7b 0a 20 20 20   if( aMem ){.   
f450: 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69       pSorter->li
f460: 73 74 2e 61 4d 65 6d 6f 72 79 20 3d 20 61 4d 65  st.aMemory = aMe
f470: 6d 3b 0a 20 20 20 20 20 20 20 20 70 53 6f 72 74  m;.        pSort
f480: 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 3d 20 73 71  er->nMemory = sq
f490: 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28  lite3MallocSize(
f4a0: 61 4d 65 6d 29 3b 0a 20 20 20 20 20 20 7d 65 6c  aMem);.      }el
f4b0: 73 65 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e  se if( pSorter->
f4c0: 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 29 7b 0a  list.aMemory ){.
f4d0: 20 20 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d          pSorter-
f4e0: 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 3d 20  >list.aMemory = 
f4f0: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 70 53  sqlite3Malloc(pS
f500: 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 29 3b  orter->nMemory);
f510: 0a 20 20 20 20 20 20 20 20 69 66 28 20 21 70 53  .        if( !pS
f520: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d  orter->list.aMem
f530: 6f 72 79 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ory ) return SQL
f540: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
f550: 20 7d 0a 0a 20 20 20 20 20 20 72 63 20 3d 20 76   }..      rc = v
f560: 64 62 65 53 6f 72 74 65 72 43 72 65 61 74 65 54  dbeSorterCreateT
f570: 68 72 65 61 64 28 70 54 61 73 6b 2c 20 76 64 62  hread(pTask, vdb
f580: 65 53 6f 72 74 65 72 46 6c 75 73 68 54 68 72 65  eSorterFlushThre
f590: 61 64 2c 20 70 43 74 78 29 3b 0a 20 20 20 20 7d  ad, pCtx);.    }
f5a0: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
f5b0: 63 3b 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c  c;.#endif /* SQL
f5c0: 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54  ITE_MAX_WORKER_T
f5d0: 48 52 45 41 44 53 21 3d 30 20 2a 2f 0a 7d 0a 0a  HREADS!=0 */.}..
f5e0: 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 72 65 63 6f  /*.** Add a reco
f5f0: 72 64 20 74 6f 20 74 68 65 20 73 6f 72 74 65 72  rd to the sorter
f600: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
f610: 56 64 62 65 53 6f 72 74 65 72 57 72 69 74 65 28  VdbeSorterWrite(
f620: 0a 20 20 63 6f 6e 73 74 20 56 64 62 65 43 75 72  .  const VdbeCur
f630: 73 6f 72 20 2a 70 43 73 72 2c 20 20 20 20 20 20  sor *pCsr,      
f640: 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 63 75 72     /* Sorter cur
f650: 73 6f 72 20 2a 2f 0a 20 20 4d 65 6d 20 2a 70 56  sor */.  Mem *pV
f660: 61 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  al              
f670: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 65 6d 6f           /* Memo
f680: 72 79 20 63 65 6c 6c 20 63 6f 6e 74 61 69 6e 69  ry cell containi
f690: 6e 67 20 72 65 63 6f 72 64 20 2a 2f 0a 29 7b 0a  ng record */.){.
f6a0: 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
f6b0: 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53  orter = pCsr->pS
f6c0: 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 72 63 20  orter;.  int rc 
f6d0: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20  = SQLITE_OK;    
f6e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
f6f0: 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 53 6f 72  rn Code */.  Sor
f700: 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65 77 3b  terRecord *pNew;
f710: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
f720: 4e 65 77 20 6c 69 73 74 20 65 6c 65 6d 65 6e 74  New list element
f730: 20 2a 2f 0a 0a 20 20 69 6e 74 20 62 46 6c 75 73   */..  int bFlus
f740: 68 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  h;              
f750: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74         /* True t
f760: 6f 20 66 6c 75 73 68 20 63 6f 6e 74 65 6e 74 73  o flush contents
f770: 20 6f 66 20 6d 65 6d 6f 72 79 20 74 6f 20 50 4d   of memory to PM
f780: 41 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 71 3b  A */.  int nReq;
f790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f7a0: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
f7b0: 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71 75 69 72  of memory requir
f7c0: 65 64 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 4d 41  ed */.  int nPMA
f7d0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
f7e0: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
f7f0: 20 6f 66 20 50 4d 41 20 73 70 61 63 65 20 72 65   of PMA space re
f800: 71 75 69 72 65 64 20 2a 2f 0a 20 20 69 6e 74 20  quired */.  int 
f810: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
f820: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73              /* s
f830: 65 72 69 61 6c 20 74 79 70 65 20 6f 66 20 66 69  erial type of fi
f840: 72 73 74 20 72 65 63 6f 72 64 20 66 69 65 6c 64  rst record field
f850: 20 2a 2f 0a 0a 20 20 67 65 74 56 61 72 69 6e 74   */..  getVarint
f860: 33 32 28 28 63 6f 6e 73 74 20 75 38 2a 29 26 70  32((const u8*)&p
f870: 56 61 6c 2d 3e 7a 5b 31 5d 2c 20 74 29 3b 0a 20  Val->z[1], t);. 
f880: 20 69 66 28 20 74 3e 30 20 26 26 20 74 3c 31 30   if( t>0 && t<10
f890: 20 26 26 20 74 21 3d 37 20 29 7b 0a 20 20 20 20   && t!=7 ){.    
f8a0: 70 53 6f 72 74 65 72 2d 3e 74 79 70 65 4d 61 73  pSorter->typeMas
f8b0: 6b 20 26 3d 20 53 4f 52 54 45 52 5f 54 59 50 45  k &= SORTER_TYPE
f8c0: 5f 49 4e 54 45 47 45 52 3b 0a 20 20 7d 65 6c 73  _INTEGER;.  }els
f8d0: 65 20 69 66 28 20 74 3e 31 30 20 26 26 20 28 74  e if( t>10 && (t
f8e0: 20 26 20 30 78 30 31 29 20 29 7b 0a 20 20 20 20   & 0x01) ){.    
f8f0: 70 53 6f 72 74 65 72 2d 3e 74 79 70 65 4d 61 73  pSorter->typeMas
f900: 6b 20 26 3d 20 53 4f 52 54 45 52 5f 54 59 50 45  k &= SORTER_TYPE
f910: 5f 54 45 58 54 3b 0a 20 20 7d 65 6c 73 65 7b 0a  _TEXT;.  }else{.
f920: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 74 79 70      pSorter->typ
f930: 65 4d 61 73 6b 20 3d 20 30 3b 0a 20 20 7d 0a 0a  eMask = 0;.  }..
f940: 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65    assert( pSorte
f950: 72 20 29 3b 0a 0a 20 20 2f 2a 20 46 69 67 75 72  r );..  /* Figur
f960: 65 20 6f 75 74 20 77 68 65 74 68 65 72 20 6f 72  e out whether or
f970: 20 6e 6f 74 20 74 68 65 20 63 75 72 72 65 6e 74   not the current
f980: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65 6d   contents of mem
f990: 6f 72 79 20 73 68 6f 75 6c 64 20 62 65 0a 20 20  ory should be.  
f9a0: 2a 2a 20 66 6c 75 73 68 65 64 20 74 6f 20 61 20  ** flushed to a 
f9b0: 50 4d 41 20 62 65 66 6f 72 65 20 63 6f 6e 74 69  PMA before conti
f9c0: 6e 75 69 6e 67 2e 20 49 66 20 73 6f 2c 20 64 6f  nuing. If so, do
f9d0: 20 73 6f 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49   so..  **.  ** I
f9e0: 66 20 75 73 69 6e 67 20 74 68 65 20 73 69 6e 67  f using the sing
f9f0: 6c 65 20 6c 61 72 67 65 20 61 6c 6c 6f 63 61 74  le large allocat
fa00: 69 6f 6e 20 6d 6f 64 65 20 28 70 53 6f 72 74 65  ion mode (pSorte
fa10: 72 2d 3e 61 4d 65 6d 6f 72 79 21 3d 30 29 2c 20  r->aMemory!=0), 
fa20: 74 68 65 6e 0a 20 20 2a 2a 20 66 6c 75 73 68 20  then.  ** flush 
fa30: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
fa40: 6d 65 6d 6f 72 79 20 74 6f 20 61 20 6e 65 77 20  memory to a new 
fa50: 50 4d 41 20 69 66 20 28 61 29 20 61 74 20 6c 65  PMA if (a) at le
fa60: 61 73 74 20 6f 6e 65 20 76 61 6c 75 65 20 69 73  ast one value is
fa70: 0a 20 20 2a 2a 20 61 6c 72 65 61 64 79 20 69 6e  .  ** already in
fa80: 20 6d 65 6d 6f 72 79 20 61 6e 64 20 28 62 29 20   memory and (b) 
fa90: 74 68 65 20 6e 65 77 20 76 61 6c 75 65 20 77 69  the new value wi
faa0: 6c 6c 20 6e 6f 74 20 66 69 74 20 69 6e 20 6d 65  ll not fit in me
fab0: 6d 6f 72 79 2e 0a 20 20 2a 2a 20 0a 20 20 2a 2a  mory..  ** .  **
fac0: 20 4f 72 2c 20 69 66 20 75 73 69 6e 67 20 73 65   Or, if using se
fad0: 70 61 72 61 74 65 20 61 6c 6c 6f 63 61 74 69 6f  parate allocatio
fae0: 6e 73 20 66 6f 72 20 65 61 63 68 20 72 65 63 6f  ns for each reco
faf0: 72 64 2c 20 66 6c 75 73 68 20 74 68 65 20 63 6f  rd, flush the co
fb00: 6e 74 65 6e 74 73 0a 20 20 2a 2a 20 6f 66 20 6d  ntents.  ** of m
fb10: 65 6d 6f 72 79 20 74 6f 20 61 20 50 4d 41 20 69  emory to a PMA i
fb20: 66 20 65 69 74 68 65 72 20 6f 66 20 74 68 65 20  f either of the 
fb30: 66 6f 6c 6c 6f 77 69 6e 67 20 61 72 65 20 74 72  following are tr
fb40: 75 65 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20  ue:.  **.  **   
fb50: 2a 20 54 68 65 20 74 6f 74 61 6c 20 6d 65 6d 6f  * The total memo
fb60: 72 79 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72  ry allocated for
fb70: 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c   the in-memory l
fb80: 69 73 74 20 69 73 20 67 72 65 61 74 65 72 20 0a  ist is greater .
fb90: 20 20 2a 2a 20 20 20 20 20 74 68 61 6e 20 28 70    **     than (p
fba0: 61 67 65 2d 73 69 7a 65 20 2a 20 63 61 63 68 65  age-size * cache
fbb0: 2d 73 69 7a 65 29 2c 20 6f 72 0a 20 20 2a 2a 0a  -size), or.  **.
fbc0: 20 20 2a 2a 20 20 20 2a 20 54 68 65 20 74 6f 74    **   * The tot
fbd0: 61 6c 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61  al memory alloca
fbe0: 74 65 64 20 66 6f 72 20 74 68 65 20 69 6e 2d 6d  ted for the in-m
fbf0: 65 6d 6f 72 79 20 6c 69 73 74 20 69 73 20 67 72  emory list is gr
fc00: 65 61 74 65 72 20 0a 20 20 2a 2a 20 20 20 20 20  eater .  **     
fc10: 74 68 61 6e 20 28 70 61 67 65 2d 73 69 7a 65 20  than (page-size 
fc20: 2a 20 31 30 29 20 61 6e 64 20 73 71 6c 69 74 65  * 10) and sqlite
fc30: 33 48 65 61 70 4e 65 61 72 6c 79 46 75 6c 6c 28  3HeapNearlyFull(
fc40: 29 20 72 65 74 75 72 6e 73 20 74 72 75 65 2e 0a  ) returns true..
fc50: 20 20 2a 2f 0a 20 20 6e 52 65 71 20 3d 20 70 56    */.  nReq = pV
fc60: 61 6c 2d 3e 6e 20 2b 20 73 69 7a 65 6f 66 28 53  al->n + sizeof(S
fc70: 6f 72 74 65 72 52 65 63 6f 72 64 29 3b 0a 20 20  orterRecord);.  
fc80: 6e 50 4d 41 20 3d 20 70 56 61 6c 2d 3e 6e 20 2b  nPMA = pVal->n +
fc90: 20 73 71 6c 69 74 65 33 56 61 72 69 6e 74 4c 65   sqlite3VarintLe
fca0: 6e 28 70 56 61 6c 2d 3e 6e 29 3b 0a 20 20 69 66  n(pVal->n);.  if
fcb0: 28 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61  ( pSorter->mxPma
fcc0: 53 69 7a 65 20 29 7b 0a 20 20 20 20 69 66 28 20  Size ){.    if( 
fcd0: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d  pSorter->list.aM
fce0: 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20 20 62  emory ){.      b
fcf0: 46 6c 75 73 68 20 3d 20 70 53 6f 72 74 65 72 2d  Flush = pSorter-
fd00: 3e 69 4d 65 6d 6f 72 79 20 26 26 20 28 70 53 6f  >iMemory && (pSo
fd10: 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 2b 6e 52  rter->iMemory+nR
fd20: 65 71 29 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d  eq) > pSorter->m
fd30: 78 50 6d 61 53 69 7a 65 3b 0a 20 20 20 20 7d 65  xPmaSize;.    }e
fd40: 6c 73 65 7b 0a 20 20 20 20 20 20 62 46 6c 75 73  lse{.      bFlus
fd50: 68 20 3d 20 28 0a 20 20 20 20 20 20 20 20 20 20  h = (.          
fd60: 28 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 73  (pSorter->list.s
fd70: 7a 50 4d 41 20 3e 20 70 53 6f 72 74 65 72 2d 3e  zPMA > pSorter->
fd80: 6d 78 50 6d 61 53 69 7a 65 29 0a 20 20 20 20 20  mxPmaSize).     
fd90: 20 20 7c 7c 20 28 70 53 6f 72 74 65 72 2d 3e 6c    || (pSorter->l
fda0: 69 73 74 2e 73 7a 50 4d 41 20 3e 20 70 53 6f 72  ist.szPMA > pSor
fdb0: 74 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a 65 20 26  ter->mnPmaSize &
fdc0: 26 20 73 71 6c 69 74 65 33 48 65 61 70 4e 65 61  & sqlite3HeapNea
fdd0: 72 6c 79 46 75 6c 6c 28 29 29 0a 20 20 20 20 20  rlyFull()).     
fde0: 20 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66   );.    }.    if
fdf0: 28 20 62 46 6c 75 73 68 20 29 7b 0a 20 20 20 20  ( bFlush ){.    
fe00: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
fe10: 72 46 6c 75 73 68 50 4d 41 28 70 53 6f 72 74 65  rFlushPMA(pSorte
fe20: 72 29 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65  r);.      pSorte
fe30: 72 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 3d 20  r->list.szPMA = 
fe40: 30 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72  0;.      pSorter
fe50: 2d 3e 69 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a 20  ->iMemory = 0;. 
fe60: 20 20 20 20 20 61 73 73 65 72 74 28 20 72 63 21       assert( rc!
fe70: 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53  =SQLITE_OK || pS
fe80: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73  orter->list.pLis
fe90: 74 3d 3d 30 20 29 3b 0a 20 20 20 20 7d 0a 20 20  t==0 );.    }.  
fea0: 7d 0a 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69  }..  pSorter->li
feb0: 73 74 2e 73 7a 50 4d 41 20 2b 3d 20 6e 50 4d 41  st.szPMA += nPMA
fec0: 3b 0a 20 20 69 66 28 20 6e 50 4d 41 3e 70 53 6f  ;.  if( nPMA>pSo
fed0: 72 74 65 72 2d 3e 6d 78 4b 65 79 73 69 7a 65 20  rter->mxKeysize 
fee0: 29 7b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  ){.    pSorter->
fef0: 6d 78 4b 65 79 73 69 7a 65 20 3d 20 6e 50 4d 41  mxKeysize = nPMA
ff00: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 53 6f  ;.  }..  if( pSo
ff10: 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f  rter->list.aMemo
ff20: 72 79 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 4d  ry ){.    int nM
ff30: 69 6e 20 3d 20 70 53 6f 72 74 65 72 2d 3e 69 4d  in = pSorter->iM
ff40: 65 6d 6f 72 79 20 2b 20 6e 52 65 71 3b 0a 0a 20  emory + nReq;.. 
ff50: 20 20 20 69 66 28 20 6e 4d 69 6e 3e 70 53 6f 72     if( nMin>pSor
ff60: 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 29 7b 0a  ter->nMemory ){.
ff70: 20 20 20 20 20 20 75 38 20 2a 61 4e 65 77 3b 0a        u8 *aNew;.
ff80: 20 20 20 20 20 20 69 6e 74 20 6e 4e 65 77 20 3d        int nNew =
ff90: 20 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72   pSorter->nMemor
ffa0: 79 20 2a 20 32 3b 0a 20 20 20 20 20 20 77 68 69  y * 2;.      whi
ffb0: 6c 65 28 20 6e 4e 65 77 20 3c 20 6e 4d 69 6e 20  le( nNew < nMin 
ffc0: 29 20 6e 4e 65 77 20 3d 20 6e 4e 65 77 2a 32 3b  ) nNew = nNew*2;
ffd0: 0a 20 20 20 20 20 20 69 66 28 20 6e 4e 65 77 20  .      if( nNew 
ffe0: 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61  > pSorter->mxPma
fff0: 53 69 7a 65 20 29 20 6e 4e 65 77 20 3d 20 70 53  Size ) nNew = pS
10000 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65  orter->mxPmaSize
10010 3b 0a 20 20 20 20 20 20 69 66 28 20 6e 4e 65 77  ;.      if( nNew
10020 20 3c 20 6e 4d 69 6e 20 29 20 6e 4e 65 77 20 3d   < nMin ) nNew =
10030 20 6e 4d 69 6e 3b 0a 0a 20 20 20 20 20 20 61 4e   nMin;..      aN
10040 65 77 20 3d 20 73 71 6c 69 74 65 33 52 65 61 6c  ew = sqlite3Real
10050 6c 6f 63 28 70 53 6f 72 74 65 72 2d 3e 6c 69 73  loc(pSorter->lis
10060 74 2e 61 4d 65 6d 6f 72 79 2c 20 6e 4e 65 77 29  t.aMemory, nNew)
10070 3b 0a 20 20 20 20 20 20 69 66 28 20 21 61 4e 65  ;.      if( !aNe
10080 77 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  w ) return SQLIT
10090 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 70  E_NOMEM;.      p
100a0 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69  Sorter->list.pLi
100b0 73 74 20 3d 20 28 53 6f 72 74 65 72 52 65 63 6f  st = (SorterReco
100c0 72 64 2a 29 28 0a 20 20 20 20 20 20 20 20 20 20  rd*)(.          
100d0 61 4e 65 77 20 2b 20 28 28 75 38 2a 29 70 53 6f  aNew + ((u8*)pSo
100e0 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74  rter->list.pList
100f0 20 2d 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74   - pSorter->list
10100 2e 61 4d 65 6d 6f 72 79 29 0a 20 20 20 20 20 20  .aMemory).      
10110 29 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72  );.      pSorter
10120 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 3d  ->list.aMemory =
10130 20 61 4e 65 77 3b 0a 20 20 20 20 20 20 70 53 6f   aNew;.      pSo
10140 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 3d 20  rter->nMemory = 
10150 6e 4e 65 77 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  nNew;.    }..   
10160 20 70 4e 65 77 20 3d 20 28 53 6f 72 74 65 72 52   pNew = (SorterR
10170 65 63 6f 72 64 2a 29 26 70 53 6f 72 74 65 72 2d  ecord*)&pSorter-
10180 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 5b 70 53  >list.aMemory[pS
10190 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 5d 3b  orter->iMemory];
101a0 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 69 4d  .    pSorter->iM
101b0 65 6d 6f 72 79 20 2b 3d 20 52 4f 55 4e 44 38 28  emory += ROUND8(
101c0 6e 52 65 71 29 3b 0a 20 20 20 20 70 4e 65 77 2d  nReq);.    pNew-
101d0 3e 75 2e 69 4e 65 78 74 20 3d 20 28 69 6e 74 29  >u.iNext = (int)
101e0 28 28 75 38 2a 29 28 70 53 6f 72 74 65 72 2d 3e  ((u8*)(pSorter->
101f0 6c 69 73 74 2e 70 4c 69 73 74 29 20 2d 20 70 53  list.pList) - pS
10200 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d  orter->list.aMem
10210 6f 72 79 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  ory);.  }else{. 
10220 20 20 20 70 4e 65 77 20 3d 20 28 53 6f 72 74 65     pNew = (Sorte
10230 72 52 65 63 6f 72 64 20 2a 29 73 71 6c 69 74 65  rRecord *)sqlite
10240 33 4d 61 6c 6c 6f 63 28 6e 52 65 71 29 3b 0a 20  3Malloc(nReq);. 
10250 20 20 20 69 66 28 20 70 4e 65 77 3d 3d 30 20 29     if( pNew==0 )
10260 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53  {.      return S
10270 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
10280 20 7d 0a 20 20 20 20 70 4e 65 77 2d 3e 75 2e 70   }.    pNew->u.p
10290 4e 65 78 74 20 3d 20 70 53 6f 72 74 65 72 2d 3e  Next = pSorter->
102a0 6c 69 73 74 2e 70 4c 69 73 74 3b 0a 20 20 7d 0a  list.pList;.  }.
102b0 0a 20 20 6d 65 6d 63 70 79 28 53 52 56 41 4c 28  .  memcpy(SRVAL(
102c0 70 4e 65 77 29 2c 20 70 56 61 6c 2d 3e 7a 2c 20  pNew), pVal->z, 
102d0 70 56 61 6c 2d 3e 6e 29 3b 0a 20 20 70 4e 65 77  pVal->n);.  pNew
102e0 2d 3e 6e 56 61 6c 20 3d 20 70 56 61 6c 2d 3e 6e  ->nVal = pVal->n
102f0 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73  ;.  pSorter->lis
10300 74 2e 70 4c 69 73 74 20 3d 20 70 4e 65 77 3b 0a  t.pList = pNew;.
10310 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
10320 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 6b 65 79 73  ./*.** Read keys
10330 20 66 72 6f 6d 20 70 49 6e 63 72 2d 3e 70 4d 65   from pIncr->pMe
10340 72 67 65 72 20 61 6e 64 20 70 6f 70 75 6c 61 74  rger and populat
10350 65 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31  e pIncr->aFile[1
10360 5d 2e 20 54 68 65 20 66 6f 72 6d 61 74 0a 2a 2a  ]. The format.**
10370 20 6f 66 20 74 68 65 20 64 61 74 61 20 73 74 6f   of the data sto
10380 72 65 64 20 69 6e 20 61 46 69 6c 65 5b 31 5d 20  red in aFile[1] 
10390 69 73 20 74 68 65 20 73 61 6d 65 20 61 73 20 74  is the same as t
103a0 68 61 74 20 75 73 65 64 20 62 79 20 72 65 67 75  hat used by regu
103b0 6c 61 72 20 50 4d 41 73 2c 0a 2a 2a 20 65 78 63  lar PMAs,.** exc
103c0 65 70 74 20 74 68 61 74 20 74 68 65 20 6e 75 6d  ept that the num
103d0 62 65 72 2d 6f 66 2d 62 79 74 65 73 20 76 61 72  ber-of-bytes var
103e0 69 6e 74 20 69 73 20 6f 6d 69 74 74 65 64 20 66  int is omitted f
103f0 72 6f 6d 20 74 68 65 20 73 74 61 72 74 2e 0a 2a  rom the start..*
10400 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
10410 65 49 6e 63 72 50 6f 70 75 6c 61 74 65 28 49 6e  eIncrPopulate(In
10420 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 29  crMerger *pIncr)
10430 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
10440 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 72 63  ITE_OK;.  int rc
10450 32 3b 0a 20 20 69 36 34 20 69 53 74 61 72 74 20  2;.  i64 iStart 
10460 3d 20 70 49 6e 63 72 2d 3e 69 53 74 61 72 74 4f  = pIncr->iStartO
10470 66 66 3b 0a 20 20 53 6f 72 74 65 72 46 69 6c 65  ff;.  SorterFile
10480 20 2a 70 4f 75 74 20 3d 20 26 70 49 6e 63 72 2d   *pOut = &pIncr-
10490 3e 61 46 69 6c 65 5b 31 5d 3b 0a 20 20 53 6f 72  >aFile[1];.  Sor
104a0 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 20  tSubtask *pTask 
104b0 3d 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b 3b 0a  = pIncr->pTask;.
104c0 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70    MergeEngine *p
104d0 4d 65 72 67 65 72 20 3d 20 70 49 6e 63 72 2d 3e  Merger = pIncr->
104e0 70 4d 65 72 67 65 72 3b 0a 20 20 50 6d 61 57 72  pMerger;.  PmaWr
104f0 69 74 65 72 20 77 72 69 74 65 72 3b 0a 20 20 61  iter writer;.  a
10500 73 73 65 72 74 28 20 70 49 6e 63 72 2d 3e 62 45  ssert( pIncr->bE
10510 6f 66 3d 3d 30 20 29 3b 0a 0a 20 20 76 64 62 65  of==0 );..  vdbe
10520 53 6f 72 74 65 72 50 6f 70 75 6c 61 74 65 44 65  SorterPopulateDe
10530 62 75 67 28 70 54 61 73 6b 2c 20 22 65 6e 74 65  bug(pTask, "ente
10540 72 22 29 3b 0a 0a 20 20 76 64 62 65 50 6d 61 57  r");..  vdbePmaW
10550 72 69 74 65 72 49 6e 69 74 28 70 4f 75 74 2d 3e  riterInit(pOut->
10560 70 46 64 2c 20 26 77 72 69 74 65 72 2c 20 70 54  pFd, &writer, pT
10570 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 67  ask->pSorter->pg
10580 73 7a 2c 20 69 53 74 61 72 74 29 3b 0a 20 20 77  sz, iStart);.  w
10590 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45  hile( rc==SQLITE
105a0 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 64  _OK ){.    int d
105b0 75 6d 6d 79 3b 0a 20 20 20 20 50 6d 61 52 65 61  ummy;.    PmaRea
105c0 64 65 72 20 2a 70 52 65 61 64 65 72 20 3d 20 26  der *pReader = &
105d0 70 4d 65 72 67 65 72 2d 3e 61 52 65 61 64 72 5b  pMerger->aReadr[
105e0 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b   pMerger->aTree[
105f0 31 5d 20 5d 3b 0a 20 20 20 20 69 6e 74 20 6e 4b  1] ];.    int nK
10600 65 79 20 3d 20 70 52 65 61 64 65 72 2d 3e 6e 4b  ey = pReader->nK
10610 65 79 3b 0a 20 20 20 20 69 36 34 20 69 45 6f 66  ey;.    i64 iEof
10620 20 3d 20 77 72 69 74 65 72 2e 69 57 72 69 74 65   = writer.iWrite
10630 4f 66 66 20 2b 20 77 72 69 74 65 72 2e 69 42 75  Off + writer.iBu
10640 66 45 6e 64 3b 0a 0a 20 20 20 20 2f 2a 20 43 68  fEnd;..    /* Ch
10650 65 63 6b 20 69 66 20 74 68 65 20 6f 75 74 70 75  eck if the outpu
10660 74 20 66 69 6c 65 20 69 73 20 66 75 6c 6c 20 6f  t file is full o
10670 72 20 69 66 20 74 68 65 20 69 6e 70 75 74 20 68  r if the input h
10680 61 73 20 62 65 65 6e 20 65 78 68 61 75 73 74 65  as been exhauste
10690 64 2e 0a 20 20 20 20 2a 2a 20 49 6e 20 65 69 74  d..    ** In eit
106a0 68 65 72 20 63 61 73 65 20 65 78 69 74 20 74 68  her case exit th
106b0 65 20 6c 6f 6f 70 2e 20 2a 2f 0a 20 20 20 20 69  e loop. */.    i
106c0 66 28 20 70 52 65 61 64 65 72 2d 3e 70 46 64 3d  f( pReader->pFd=
106d0 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  =0 ) break;.    
106e0 69 66 28 20 28 69 45 6f 66 20 2b 20 6e 4b 65 79  if( (iEof + nKey
106f0 20 2b 20 73 71 6c 69 74 65 33 56 61 72 69 6e 74   + sqlite3Varint
10700 4c 65 6e 28 6e 4b 65 79 29 29 3e 28 69 53 74 61  Len(nKey))>(iSta
10710 72 74 20 2b 20 70 49 6e 63 72 2d 3e 6d 78 53 7a  rt + pIncr->mxSz
10720 29 20 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20  ) ) break;..    
10730 2f 2a 20 57 72 69 74 65 20 74 68 65 20 6e 65 78  /* Write the nex
10740 74 20 6b 65 79 20 74 6f 20 74 68 65 20 6f 75 74  t key to the out
10750 70 75 74 2e 20 2a 2f 0a 20 20 20 20 76 64 62 65  put. */.    vdbe
10760 50 6d 61 57 72 69 74 65 56 61 72 69 6e 74 28 26  PmaWriteVarint(&
10770 77 72 69 74 65 72 2c 20 6e 4b 65 79 29 3b 0a 20  writer, nKey);. 
10780 20 20 20 76 64 62 65 50 6d 61 57 72 69 74 65 42     vdbePmaWriteB
10790 6c 6f 62 28 26 77 72 69 74 65 72 2c 20 70 52 65  lob(&writer, pRe
107a0 61 64 65 72 2d 3e 61 4b 65 79 2c 20 6e 4b 65 79  ader->aKey, nKey
107b0 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
107c0 49 6e 63 72 2d 3e 70 4d 65 72 67 65 72 2d 3e 70  Incr->pMerger->p
107d0 54 61 73 6b 3d 3d 70 54 61 73 6b 20 29 3b 0a 20  Task==pTask );. 
107e0 20 20 20 72 63 20 3d 20 76 64 62 65 4d 65 72 67     rc = vdbeMerg
107f0 65 45 6e 67 69 6e 65 53 74 65 70 28 70 49 6e 63  eEngineStep(pInc
10800 72 2d 3e 70 4d 65 72 67 65 72 2c 20 26 64 75 6d  r->pMerger, &dum
10810 6d 79 29 3b 0a 20 20 7d 0a 0a 20 20 72 63 32 20  my);.  }..  rc2 
10820 3d 20 76 64 62 65 50 6d 61 57 72 69 74 65 72 46  = vdbePmaWriterF
10830 69 6e 69 73 68 28 26 77 72 69 74 65 72 2c 20 26  inish(&writer, &
10840 70 4f 75 74 2d 3e 69 45 6f 66 29 3b 0a 20 20 69  pOut->iEof);.  i
10850 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
10860 20 29 20 72 63 20 3d 20 72 63 32 3b 0a 20 20 76   ) rc = rc2;.  v
10870 64 62 65 53 6f 72 74 65 72 50 6f 70 75 6c 61 74  dbeSorterPopulat
10880 65 44 65 62 75 67 28 70 54 61 73 6b 2c 20 22 65  eDebug(pTask, "e
10890 78 69 74 22 29 3b 0a 20 20 72 65 74 75 72 6e 20  xit");.  return 
108a0 72 63 3b 0a 7d 0a 0a 23 69 66 20 53 51 4c 49 54  rc;.}..#if SQLIT
108b0 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52  E_MAX_WORKER_THR
108c0 45 41 44 53 3e 30 0a 2f 2a 0a 2a 2a 20 54 68 65  EADS>0./*.** The
108d0 20 6d 61 69 6e 20 72 6f 75 74 69 6e 65 20 66 6f   main routine fo
108e0 72 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  r background thr
108f0 65 61 64 73 20 74 68 61 74 20 70 6f 70 75 6c 61  eads that popula
10900 74 65 20 61 46 69 6c 65 5b 31 5d 20 6f 66 0a 2a  te aFile[1] of.*
10910 2a 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64  * multi-threaded
10920 20 49 6e 63 72 4d 65 72 67 65 72 20 6f 62 6a 65   IncrMerger obje
10930 63 74 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  cts..*/.static v
10940 6f 69 64 20 2a 76 64 62 65 49 6e 63 72 50 6f 70  oid *vdbeIncrPop
10950 75 6c 61 74 65 54 68 72 65 61 64 28 76 6f 69 64  ulateThread(void
10960 20 2a 70 43 74 78 29 7b 0a 20 20 49 6e 63 72 4d   *pCtx){.  IncrM
10970 65 72 67 65 72 20 2a 70 49 6e 63 72 20 3d 20 28  erger *pIncr = (
10980 49 6e 63 72 4d 65 72 67 65 72 2a 29 70 43 74 78  IncrMerger*)pCtx
10990 3b 0a 20 20 76 6f 69 64 20 2a 70 52 65 74 20 3d  ;.  void *pRet =
109a0 20 53 51 4c 49 54 45 5f 49 4e 54 5f 54 4f 5f 50   SQLITE_INT_TO_P
109b0 54 52 28 20 76 64 62 65 49 6e 63 72 50 6f 70 75  TR( vdbeIncrPopu
109c0 6c 61 74 65 28 70 49 6e 63 72 29 20 29 3b 0a 20  late(pIncr) );. 
109d0 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b 2d 3e 62   pIncr->pTask->b
109e0 44 6f 6e 65 20 3d 20 31 3b 0a 20 20 72 65 74 75  Done = 1;.  retu
109f0 72 6e 20 70 52 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a  rn pRet;.}../*.*
10a00 2a 20 4c 61 75 6e 63 68 20 61 20 62 61 63 6b 67  * Launch a backg
10a10 72 6f 75 6e 64 20 74 68 72 65 61 64 20 74 6f 20  round thread to 
10a20 70 6f 70 75 6c 61 74 65 20 61 46 69 6c 65 5b 31  populate aFile[1
10a30 5d 20 6f 66 20 70 49 6e 63 72 2e 0a 2a 2f 0a 73  ] of pIncr..*/.s
10a40 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 49 6e  tatic int vdbeIn
10a50 63 72 42 67 50 6f 70 75 6c 61 74 65 28 49 6e 63  crBgPopulate(Inc
10a60 72 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 29 7b  rMerger *pIncr){
10a70 0a 20 20 76 6f 69 64 20 2a 70 20 3d 20 28 76 6f  .  void *p = (vo
10a80 69 64 2a 29 70 49 6e 63 72 3b 0a 20 20 61 73 73  id*)pIncr;.  ass
10a90 65 72 74 28 20 70 49 6e 63 72 2d 3e 62 55 73 65  ert( pIncr->bUse
10aa0 54 68 72 65 61 64 20 29 3b 0a 20 20 72 65 74 75  Thread );.  retu
10ab0 72 6e 20 76 64 62 65 53 6f 72 74 65 72 43 72 65  rn vdbeSorterCre
10ac0 61 74 65 54 68 72 65 61 64 28 70 49 6e 63 72 2d  ateThread(pIncr-
10ad0 3e 70 54 61 73 6b 2c 20 76 64 62 65 49 6e 63 72  >pTask, vdbeIncr
10ae0 50 6f 70 75 6c 61 74 65 54 68 72 65 61 64 2c 20  PopulateThread, 
10af0 70 29 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a  p);.}.#endif../*
10b00 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
10b10 6e 20 69 73 20 63 61 6c 6c 65 64 20 77 68 65 6e  n is called when
10b20 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 20 63   the PmaReader c
10b30 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20  orresponding to 
10b40 70 49 6e 63 72 20 68 61 73 0a 2a 2a 20 66 69 6e  pIncr has.** fin
10b50 69 73 68 65 64 20 72 65 61 64 69 6e 67 20 74 68  ished reading th
10b60 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61 46  e contents of aF
10b70 69 6c 65 5b 30 5d 2e 20 49 74 73 20 70 75 72 70  ile[0]. Its purp
10b80 6f 73 65 20 69 73 20 74 6f 20 22 72 65 66 69 6c  ose is to "refil
10b90 6c 22 0a 2a 2a 20 61 46 69 6c 65 5b 30 5d 20 73  l".** aFile[0] s
10ba0 75 63 68 20 74 68 61 74 20 74 68 65 20 50 6d 61  uch that the Pma
10bb0 52 65 61 64 65 72 20 73 68 6f 75 6c 64 20 73 74  Reader should st
10bc0 61 72 74 20 72 65 72 65 61 64 69 6e 67 20 69 74  art rereading it
10bd0 20 66 72 6f 6d 20 74 68 65 0a 2a 2a 20 62 65 67   from the.** beg
10be0 69 6e 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 46 6f  inning..**.** Fo
10bf0 72 20 73 69 6e 67 6c 65 2d 74 68 72 65 61 64 65  r single-threade
10c00 64 20 6f 62 6a 65 63 74 73 2c 20 74 68 69 73 20  d objects, this 
10c10 69 73 20 61 63 63 6f 6d 70 6c 69 73 68 65 64 20  is accomplished 
10c20 62 79 20 6c 69 74 65 72 61 6c 6c 79 20 72 65 61  by literally rea
10c30 64 69 6e 67 20 0a 2a 2a 20 6b 65 79 73 20 66 72  ding .** keys fr
10c40 6f 6d 20 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65  om pIncr->pMerge
10c50 72 20 61 6e 64 20 72 65 70 6f 70 75 6c 61 74 69  r and repopulati
10c60 6e 67 20 61 46 69 6c 65 5b 30 5d 2e 20 0a 2a 2a  ng aFile[0]. .**
10c70 0a 2a 2a 20 46 6f 72 20 6d 75 6c 74 69 2d 74 68  .** For multi-th
10c80 72 65 61 64 65 64 20 6f 62 6a 65 63 74 73 2c 20  readed objects, 
10c90 61 6c 6c 20 74 68 61 74 20 69 73 20 72 65 71 75  all that is requ
10ca0 69 72 65 64 20 69 73 20 74 6f 20 77 61 69 74 20  ired is to wait 
10cb0 75 6e 74 69 6c 20 74 68 65 20 0a 2a 2a 20 62 61  until the .** ba
10cc0 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
10cd0 69 73 20 66 69 6e 69 73 68 65 64 20 28 69 66 20  is finished (if 
10ce0 69 74 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64  it is not alread
10cf0 79 29 20 61 6e 64 20 74 68 65 6e 20 73 77 61 70  y) and then swap
10d00 20 0a 2a 2a 20 61 46 69 6c 65 5b 30 5d 20 61 6e   .** aFile[0] an
10d10 64 20 61 46 69 6c 65 5b 31 5d 20 69 6e 20 70 6c  d aFile[1] in pl
10d20 61 63 65 2e 20 49 66 20 74 68 65 20 63 6f 6e 74  ace. If the cont
10d30 65 6e 74 73 20 6f 66 20 70 4d 65 72 67 65 72 20  ents of pMerger 
10d40 68 61 76 65 20 6e 6f 74 0a 2a 2a 20 62 65 65 6e  have not.** been
10d50 20 65 78 68 61 75 73 74 65 64 2c 20 74 68 69 73   exhausted, this
10d60 20 66 75 6e 63 74 69 6f 6e 20 61 6c 73 6f 20 6c   function also l
10d70 61 75 6e 63 68 65 73 20 61 20 6e 65 77 20 62 61  aunches a new ba
10d80 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 0a  ckground thread.
10d90 2a 2a 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 74  ** to populate t
10da0 68 65 20 6e 65 77 20 61 46 69 6c 65 5b 31 5d 2e  he new aFile[1].
10db0 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b  .**.** SQLITE_OK
10dc0 20 69 73 20 72 65 74 75 72 6e 65 64 20 6f 6e 20   is returned on 
10dd0 73 75 63 63 65 73 73 2c 20 6f 72 20 61 6e 20 53  success, or an S
10de0 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
10df0 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73   otherwise..*/.s
10e00 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 49 6e  tatic int vdbeIn
10e10 63 72 53 77 61 70 28 49 6e 63 72 4d 65 72 67 65  crSwap(IncrMerge
10e20 72 20 2a 70 49 6e 63 72 29 7b 0a 20 20 69 6e 74  r *pIncr){.  int
10e30 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
10e40 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58  ..#if SQLITE_MAX
10e50 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e  _WORKER_THREADS>
10e60 30 0a 20 20 69 66 28 20 70 49 6e 63 72 2d 3e 62  0.  if( pIncr->b
10e70 55 73 65 54 68 72 65 61 64 20 29 7b 0a 20 20 20  UseThread ){.   
10e80 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
10e90 4a 6f 69 6e 54 68 72 65 61 64 28 70 49 6e 63 72  JoinThread(pIncr
10ea0 2d 3e 70 54 61 73 6b 29 3b 0a 0a 20 20 20 20 69  ->pTask);..    i
10eb0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
10ec0 20 29 7b 0a 20 20 20 20 20 20 53 6f 72 74 65 72   ){.      Sorter
10ed0 46 69 6c 65 20 66 30 20 3d 20 70 49 6e 63 72 2d  File f0 = pIncr-
10ee0 3e 61 46 69 6c 65 5b 30 5d 3b 0a 20 20 20 20 20  >aFile[0];.     
10ef0 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d   pIncr->aFile[0]
10f00 20 3d 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b   = pIncr->aFile[
10f10 31 5d 3b 0a 20 20 20 20 20 20 70 49 6e 63 72 2d  1];.      pIncr-
10f20 3e 61 46 69 6c 65 5b 31 5d 20 3d 20 66 30 3b 0a  >aFile[1] = f0;.
10f30 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72      }..    if( r
10f40 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
10f50 20 20 20 20 20 20 69 66 28 20 70 49 6e 63 72 2d        if( pIncr-
10f60 3e 61 46 69 6c 65 5b 30 5d 2e 69 45 6f 66 3d 3d  >aFile[0].iEof==
10f70 70 49 6e 63 72 2d 3e 69 53 74 61 72 74 4f 66 66  pIncr->iStartOff
10f80 20 29 7b 0a 20 20 20 20 20 20 20 20 70 49 6e 63   ){.        pInc
10f90 72 2d 3e 62 45 6f 66 20 3d 20 31 3b 0a 20 20 20  r->bEof = 1;.   
10fa0 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
10fb0 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72 42    rc = vdbeIncrB
10fc0 67 50 6f 70 75 6c 61 74 65 28 70 49 6e 63 72 29  gPopulate(pIncr)
10fd0 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
10fe0 20 20 7d 65 6c 73 65 0a 23 65 6e 64 69 66 0a 20    }else.#endif. 
10ff0 20 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65   {.    rc = vdbe
11000 49 6e 63 72 50 6f 70 75 6c 61 74 65 28 70 49 6e  IncrPopulate(pIn
11010 63 72 29 3b 0a 20 20 20 20 70 49 6e 63 72 2d 3e  cr);.    pIncr->
11020 61 46 69 6c 65 5b 30 5d 20 3d 20 70 49 6e 63 72  aFile[0] = pIncr
11030 2d 3e 61 46 69 6c 65 5b 31 5d 3b 0a 20 20 20 20  ->aFile[1];.    
11040 69 66 28 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65  if( pIncr->aFile
11050 5b 30 5d 2e 69 45 6f 66 3d 3d 70 49 6e 63 72 2d  [0].iEof==pIncr-
11060 3e 69 53 74 61 72 74 4f 66 66 20 29 7b 0a 20 20  >iStartOff ){.  
11070 20 20 20 20 70 49 6e 63 72 2d 3e 62 45 6f 66 20      pIncr->bEof 
11080 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  = 1;.    }.  }..
11090 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
110a0 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61  /*.** Allocate a
110b0 6e 64 20 72 65 74 75 72 6e 20 61 20 6e 65 77 20  nd return a new 
110c0 49 6e 63 72 4d 65 72 67 65 72 20 6f 62 6a 65 63  IncrMerger objec
110d0 74 20 74 6f 20 72 65 61 64 20 64 61 74 61 20 66  t to read data f
110e0 72 6f 6d 20 70 4d 65 72 67 65 72 2e 0a 2a 2a 0a  rom pMerger..**.
110f0 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e  ** If an OOM con
11100 64 69 74 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e  dition is encoun
11110 74 65 72 65 64 2c 20 72 65 74 75 72 6e 20 4e 55  tered, return NU
11120 4c 4c 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65  LL. In this case
11130 20 66 72 65 65 20 74 68 65 0a 2a 2a 20 70 4d 65   free the.** pMe
11140 72 67 65 72 20 61 72 67 75 6d 65 6e 74 20 62 65  rger argument be
11150 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a  fore returning..
11160 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
11170 62 65 49 6e 63 72 4d 65 72 67 65 72 4e 65 77 28  beIncrMergerNew(
11180 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a  .  SortSubtask *
11190 70 54 61 73 6b 2c 20 20 20 20 20 2f 2a 20 54 68  pTask,     /* Th
111a0 65 20 74 68 72 65 61 64 20 74 68 61 74 20 77 69  e thread that wi
111b0 6c 6c 20 62 65 20 75 73 69 6e 67 20 74 68 65 20  ll be using the 
111c0 6e 65 77 20 49 6e 63 72 4d 65 72 67 65 72 20 2a  new IncrMerger *
111d0 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  /.  MergeEngine 
111e0 2a 70 4d 65 72 67 65 72 2c 20 20 20 2f 2a 20 54  *pMerger,   /* T
111f0 68 65 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 74  he MergeEngine t
11200 68 61 74 20 74 68 65 20 49 6e 63 72 4d 65 72 67  hat the IncrMerg
11210 65 72 20 77 69 6c 6c 20 63 6f 6e 74 72 6f 6c 20  er will control 
11220 2a 2f 0a 20 20 49 6e 63 72 4d 65 72 67 65 72 20  */.  IncrMerger 
11230 2a 2a 70 70 4f 75 74 20 20 20 20 20 20 2f 2a 20  **ppOut      /* 
11240 57 72 69 74 65 20 74 68 65 20 6e 65 77 20 49 6e  Write the new In
11250 63 72 4d 65 72 67 65 72 20 68 65 72 65 20 2a 2f  crMerger here */
11260 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
11270 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 49 6e 63 72  QLITE_OK;.  Incr
11280 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 20 3d 20  Merger *pIncr = 
11290 2a 70 70 4f 75 74 20 3d 20 28 49 6e 63 72 4d 65  *ppOut = (IncrMe
112a0 72 67 65 72 2a 29 0a 20 20 20 20 20 20 20 28 73  rger*).       (s
112b0 71 6c 69 74 65 33 46 61 75 6c 74 53 69 6d 28 31  qlite3FaultSim(1
112c0 30 30 29 20 3f 20 30 20 3a 20 73 71 6c 69 74 65  00) ? 0 : sqlite
112d0 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65  3MallocZero(size
112e0 6f 66 28 2a 70 49 6e 63 72 29 29 29 3b 0a 20 20  of(*pIncr)));.  
112f0 69 66 28 20 70 49 6e 63 72 20 29 7b 0a 20 20 20  if( pIncr ){.   
11300 20 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65 72 20   pIncr->pMerger 
11310 3d 20 70 4d 65 72 67 65 72 3b 0a 20 20 20 20 70  = pMerger;.    p
11320 49 6e 63 72 2d 3e 70 54 61 73 6b 20 3d 20 70 54  Incr->pTask = pT
11330 61 73 6b 3b 0a 20 20 20 20 70 49 6e 63 72 2d 3e  ask;.    pIncr->
11340 6d 78 53 7a 20 3d 20 4d 41 58 28 70 54 61 73 6b  mxSz = MAX(pTask
11350 2d 3e 70 53 6f 72 74 65 72 2d 3e 6d 78 4b 65 79  ->pSorter->mxKey
11360 73 69 7a 65 2b 39 2c 70 54 61 73 6b 2d 3e 70 53  size+9,pTask->pS
11370 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65  orter->mxPmaSize
11380 2f 32 29 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e  /2);.    pTask->
11390 66 69 6c 65 32 2e 69 45 6f 66 20 2b 3d 20 70 49  file2.iEof += pI
113a0 6e 63 72 2d 3e 6d 78 53 7a 3b 0a 20 20 7d 65 6c  ncr->mxSz;.  }el
113b0 73 65 7b 0a 20 20 20 20 76 64 62 65 4d 65 72 67  se{.    vdbeMerg
113c0 65 45 6e 67 69 6e 65 46 72 65 65 28 70 4d 65 72  eEngineFree(pMer
113d0 67 65 72 29 3b 0a 20 20 20 20 72 63 20 3d 20 53  ger);.    rc = S
113e0 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d  QLITE_NOMEM;.  }
113f0 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
11400 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f  .#if SQLITE_MAX_
11410 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30  WORKER_THREADS>0
11420 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 22  ./*.** Set the "
11430 75 73 65 2d 74 68 72 65 61 64 73 22 20 66 6c 61  use-threads" fla
11440 67 20 6f 6e 20 6f 62 6a 65 63 74 20 70 49 6e 63  g on object pInc
11450 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  r..*/.static voi
11460 64 20 76 64 62 65 49 6e 63 72 4d 65 72 67 65 72  d vdbeIncrMerger
11470 53 65 74 54 68 72 65 61 64 73 28 49 6e 63 72 4d  SetThreads(IncrM
11480 65 72 67 65 72 20 2a 70 49 6e 63 72 29 7b 0a 20  erger *pIncr){. 
11490 20 70 49 6e 63 72 2d 3e 62 55 73 65 54 68 72 65   pIncr->bUseThre
114a0 61 64 20 3d 20 31 3b 0a 20 20 70 49 6e 63 72 2d  ad = 1;.  pIncr-
114b0 3e 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45  >pTask->file2.iE
114c0 6f 66 20 2d 3d 20 70 49 6e 63 72 2d 3e 6d 78 53  of -= pIncr->mxS
114d0 7a 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53  z;.}.#endif /* S
114e0 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52  QLITE_MAX_WORKER
114f0 5f 54 48 52 45 41 44 53 3e 30 20 2a 2f 0a 0a 0a  _THREADS>0 */...
11500 0a 2f 2a 0a 2a 2a 20 52 65 63 6f 6d 70 75 74 65  ./*.** Recompute
11510 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b   pMerger->aTree[
11520 69 4f 75 74 5d 20 62 79 20 63 6f 6d 70 61 72 69  iOut] by compari
11530 6e 67 20 74 68 65 20 6e 65 78 74 20 6b 65 79 73  ng the next keys
11540 20 6f 6e 20 74 68 65 0a 2a 2a 20 74 77 6f 20 50   on the.** two P
11550 6d 61 52 65 61 64 65 72 73 20 74 68 61 74 20 66  maReaders that f
11560 65 65 64 20 74 68 61 74 20 65 6e 74 72 79 2e 20  eed that entry. 
11570 20 4e 65 69 74 68 65 72 20 6f 66 20 74 68 65 20   Neither of the 
11580 50 6d 61 52 65 61 64 65 72 73 0a 2a 2a 20 61 72  PmaReaders.** ar
11590 65 20 61 64 76 61 6e 63 65 64 2e 20 20 54 68 69  e advanced.  Thi
115a0 73 20 72 6f 75 74 69 6e 65 20 6d 65 72 65 6c 79  s routine merely
115b0 20 64 6f 65 73 20 74 68 65 20 63 6f 6d 70 61 72   does the compar
115c0 69 73 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ison..*/.static 
115d0 76 6f 69 64 20 76 64 62 65 4d 65 72 67 65 45 6e  void vdbeMergeEn
115e0 67 69 6e 65 43 6f 6d 70 61 72 65 28 0a 20 20 4d  gineCompare(.  M
115f0 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72  ergeEngine *pMer
11600 67 65 72 2c 20 20 2f 2a 20 4d 65 72 67 65 20 65  ger,  /* Merge e
11610 6e 67 69 6e 65 20 63 6f 6e 74 61 69 6e 69 6e 67  ngine containing
11620 20 50 6d 61 52 65 61 64 65 72 73 20 74 6f 20 63   PmaReaders to c
11630 6f 6d 70 61 72 65 20 2a 2f 0a 20 20 69 6e 74 20  ompare */.  int 
11640 69 4f 75 74 20 20 20 20 20 20 20 20 20 20 20 20  iOut            
11650 20 20 20 2f 2a 20 53 74 6f 72 65 20 74 68 65 20     /* Store the 
11660 72 65 73 75 6c 74 20 69 6e 20 70 4d 65 72 67 65  result in pMerge
11670 72 2d 3e 61 54 72 65 65 5b 69 4f 75 74 5d 20 2a  r->aTree[iOut] *
11680 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 31 3b 0a 20  /.){.  int i1;. 
11690 20 69 6e 74 20 69 32 3b 0a 20 20 69 6e 74 20 69   int i2;.  int i
116a0 52 65 73 3b 0a 20 20 50 6d 61 52 65 61 64 65 72  Res;.  PmaReader
116b0 20 2a 70 31 3b 0a 20 20 50 6d 61 52 65 61 64 65   *p1;.  PmaReade
116c0 72 20 2a 70 32 3b 0a 0a 20 20 61 73 73 65 72 74  r *p2;..  assert
116d0 28 20 69 4f 75 74 3c 70 4d 65 72 67 65 72 2d 3e  ( iOut<pMerger->
116e0 6e 54 72 65 65 20 26 26 20 69 4f 75 74 3e 30 20  nTree && iOut>0 
116f0 29 3b 0a 0a 20 20 69 66 28 20 69 4f 75 74 3e 3d  );..  if( iOut>=
11700 28 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65 2f  (pMerger->nTree/
11710 32 29 20 29 7b 0a 20 20 20 20 69 31 20 3d 20 28  2) ){.    i1 = (
11720 69 4f 75 74 20 2d 20 70 4d 65 72 67 65 72 2d 3e  iOut - pMerger->
11730 6e 54 72 65 65 2f 32 29 20 2a 20 32 3b 0a 20 20  nTree/2) * 2;.  
11740 20 20 69 32 20 3d 20 69 31 20 2b 20 31 3b 0a 20    i2 = i1 + 1;. 
11750 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 31 20 3d   }else{.    i1 =
11760 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b   pMerger->aTree[
11770 69 4f 75 74 2a 32 5d 3b 0a 20 20 20 20 69 32 20  iOut*2];.    i2 
11780 3d 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65  = pMerger->aTree
11790 5b 69 4f 75 74 2a 32 2b 31 5d 3b 0a 20 20 7d 0a  [iOut*2+1];.  }.
117a0 0a 20 20 70 31 20 3d 20 26 70 4d 65 72 67 65 72  .  p1 = &pMerger
117b0 2d 3e 61 52 65 61 64 72 5b 69 31 5d 3b 0a 20 20  ->aReadr[i1];.  
117c0 70 32 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61  p2 = &pMerger->a
117d0 52 65 61 64 72 5b 69 32 5d 3b 0a 0a 20 20 69 66  Readr[i2];..  if
117e0 28 20 70 31 2d 3e 70 46 64 3d 3d 30 20 29 7b 0a  ( p1->pFd==0 ){.
117f0 20 20 20 20 69 52 65 73 20 3d 20 69 32 3b 0a 20      iRes = i2;. 
11800 20 7d 65 6c 73 65 20 69 66 28 20 70 32 2d 3e 70   }else if( p2->p
11810 46 64 3d 3d 30 20 29 7b 0a 20 20 20 20 69 52 65  Fd==0 ){.    iRe
11820 73 20 3d 20 69 31 3b 0a 20 20 7d 65 6c 73 65 7b  s = i1;.  }else{
11830 0a 20 20 20 20 53 6f 72 74 53 75 62 74 61 73 6b  .    SortSubtask
11840 20 2a 70 54 61 73 6b 20 3d 20 70 4d 65 72 67 65   *pTask = pMerge
11850 72 2d 3e 70 54 61 73 6b 3b 0a 20 20 20 20 69 6e  r->pTask;.    in
11860 74 20 62 43 61 63 68 65 64 20 3d 20 30 3b 0a 20  t bCached = 0;. 
11870 20 20 20 69 6e 74 20 72 65 73 3b 0a 20 20 20 20     int res;.    
11880 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 70  assert( pTask->p
11890 55 6e 70 61 63 6b 65 64 21 3d 30 20 29 3b 20 20  Unpacked!=0 );  
118a0 2f 2a 20 66 72 6f 6d 20 76 64 62 65 53 6f 72 74  /* from vdbeSort
118b0 53 75 62 74 61 73 6b 4d 61 69 6e 28 29 20 2a 2f  SubtaskMain() */
118c0 0a 20 20 20 20 72 65 73 20 3d 20 70 54 61 73 6b  .    res = pTask
118d0 2d 3e 78 43 6f 6d 70 61 72 65 28 0a 20 20 20 20  ->xCompare(.    
118e0 20 20 20 20 70 54 61 73 6b 2c 20 26 62 43 61 63      pTask, &bCac
118f0 68 65 64 2c 20 70 31 2d 3e 61 4b 65 79 2c 20 70  hed, p1->aKey, p
11900 31 2d 3e 6e 4b 65 79 2c 20 70 32 2d 3e 61 4b 65  1->nKey, p2->aKe
11910 79 2c 20 70 32 2d 3e 6e 4b 65 79 0a 20 20 20 20  y, p2->nKey.    
11920 29 3b 0a 20 20 20 20 69 66 28 20 72 65 73 3c 3d  );.    if( res<=
11930 30 20 29 7b 0a 20 20 20 20 20 20 69 52 65 73 20  0 ){.      iRes 
11940 3d 20 69 31 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  = i1;.    }else{
11950 0a 20 20 20 20 20 20 69 52 65 73 20 3d 20 69 32  .      iRes = i2
11960 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 70  ;.    }.  }..  p
11970 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 4f  Merger->aTree[iO
11980 75 74 5d 20 3d 20 69 52 65 73 3b 0a 7d 0a 0a 2f  ut] = iRes;.}../
11990 2a 0a 2a 2a 20 41 6c 6c 6f 77 65 64 20 76 61 6c  *.** Allowed val
119a0 75 65 73 20 66 6f 72 20 74 68 65 20 65 4d 6f 64  ues for the eMod
119b0 65 20 70 61 72 61 6d 65 74 65 72 20 74 6f 20 76  e parameter to v
119c0 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 49 6e  dbeMergeEngineIn
119d0 69 74 28 29 0a 2a 2a 20 61 6e 64 20 76 64 62 65  it().** and vdbe
119e0 50 6d 61 52 65 61 64 65 72 49 6e 63 72 4d 65 72  PmaReaderIncrMer
119f0 67 65 49 6e 69 74 28 29 2e 0a 2a 2a 0a 2a 2a 20  geInit()..**.** 
11a00 4f 6e 6c 79 20 49 4e 43 52 49 4e 49 54 5f 4e 4f  Only INCRINIT_NO
11a10 52 4d 41 4c 20 69 73 20 76 61 6c 69 64 20 69 6e  RMAL is valid in
11a20 20 73 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64   single-threaded
11a30 20 62 75 69 6c 64 73 20 28 77 68 65 6e 0a 2a 2a   builds (when.**
11a40 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b   SQLITE_MAX_WORK
11a50 45 52 5f 54 48 52 45 41 44 53 3d 3d 30 29 2e 20  ER_THREADS==0). 
11a60 20 54 68 65 20 6f 74 68 65 72 20 76 61 6c 75 65   The other value
11a70 73 20 61 72 65 20 6f 6e 6c 79 20 75 73 65 64 0a  s are only used.
11a80 2a 2a 20 77 68 65 6e 20 74 68 65 72 65 20 65 78  ** when there ex
11a90 69 73 74 73 20 6f 6e 65 20 6f 72 20 6d 6f 72 65  ists one or more
11aa0 20 73 65 70 61 72 61 74 65 20 77 6f 72 6b 65 72   separate worker
11ab0 20 74 68 72 65 61 64 73 2e 0a 2a 2f 0a 23 64 65   threads..*/.#de
11ac0 66 69 6e 65 20 49 4e 43 52 49 4e 49 54 5f 4e 4f  fine INCRINIT_NO
11ad0 52 4d 41 4c 20 30 0a 23 64 65 66 69 6e 65 20 49  RMAL 0.#define I
11ae0 4e 43 52 49 4e 49 54 5f 54 41 53 4b 20 20 20 31  NCRINIT_TASK   1
11af0 0a 23 64 65 66 69 6e 65 20 49 4e 43 52 49 4e 49  .#define INCRINI
11b00 54 5f 52 4f 4f 54 20 20 20 32 0a 0a 2f 2a 20 46  T_ROOT   2../* F
11b10 6f 72 77 61 72 64 20 72 65 66 65 72 65 6e 63 65  orward reference
11b20 2e 0a 2a 2a 20 54 68 65 20 76 64 62 65 49 6e 63  ..** The vdbeInc
11b30 72 4d 65 72 67 65 49 6e 69 74 28 29 20 61 6e 64  rMergeInit() and
11b40 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 49 6e   vdbePmaReaderIn
11b50 63 72 4d 65 72 67 65 49 6e 69 74 28 29 20 72 6f  crMergeInit() ro
11b60 75 74 69 6e 65 73 20 63 61 6c 6c 20 65 61 63 68  utines call each
11b70 0a 2a 2a 20 6f 74 68 65 72 20 28 77 68 65 6e 20  .** other (when 
11b80 62 75 69 6c 64 69 6e 67 20 61 20 6d 65 72 67 65  building a merge
11b90 20 74 72 65 65 29 2e 0a 2a 2f 0a 73 74 61 74 69   tree)..*/.stati
11ba0 63 20 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61  c int vdbePmaRea
11bb0 64 65 72 49 6e 63 72 4d 65 72 67 65 49 6e 69 74  derIncrMergeInit
11bc0 28 50 6d 61 52 65 61 64 65 72 20 2a 70 52 65 61  (PmaReader *pRea
11bd0 64 72 2c 20 69 6e 74 20 65 4d 6f 64 65 29 3b 0a  dr, int eMode);.
11be0 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a  ./*.** Initializ
11bf0 65 20 74 68 65 20 4d 65 72 67 65 45 6e 67 69 6e  e the MergeEngin
11c00 65 20 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20  e object passed 
11c10 61 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72  as the second ar
11c20 67 75 6d 65 6e 74 2e 20 4f 6e 63 65 20 74 68 69  gument. Once thi
11c30 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 72 65  s.** function re
11c40 74 75 72 6e 73 2c 20 74 68 65 20 66 69 72 73 74  turns, the first
11c50 20 6b 65 79 20 6f 66 20 6d 65 72 67 65 64 20 64   key of merged d
11c60 61 74 61 20 6d 61 79 20 62 65 20 72 65 61 64 20  ata may be read 
11c70 66 72 6f 6d 20 74 68 65 20 0a 2a 2a 20 4d 65 72  from the .** Mer
11c80 67 65 45 6e 67 69 6e 65 20 6f 62 6a 65 63 74 20  geEngine object 
11c90 69 6e 20 74 68 65 20 75 73 75 61 6c 20 66 61 73  in the usual fas
11ca0 68 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61  hion..**.** If a
11cb0 72 67 75 6d 65 6e 74 20 65 4d 6f 64 65 20 69 73  rgument eMode is
11cc0 20 49 4e 43 52 49 4e 49 54 5f 52 4f 4f 54 2c 20   INCRINIT_ROOT, 
11cd0 74 68 65 6e 20 69 74 20 69 73 20 61 73 73 75 6d  then it is assum
11ce0 65 64 20 74 68 61 74 20 61 6e 79 20 49 6e 63 72  ed that any Incr
11cf0 4d 65 72 67 65 0a 2a 2a 20 6f 62 6a 65 63 74 73  Merge.** objects
11d00 20 61 74 74 61 63 68 65 64 20 74 6f 20 74 68 65   attached to the
11d10 20 50 6d 61 52 65 61 64 65 72 20 6f 62 6a 65 63   PmaReader objec
11d20 74 73 20 74 68 61 74 20 74 68 65 20 6d 65 72 67  ts that the merg
11d30 65 72 20 72 65 61 64 73 20 66 72 6f 6d 20 68 61  er reads from ha
11d40 76 65 0a 2a 2a 20 61 6c 72 65 61 64 79 20 62 65  ve.** already be
11d50 65 6e 20 70 6f 70 75 6c 61 74 65 64 2c 20 62 75  en populated, bu
11d60 74 20 74 68 61 74 20 74 68 65 79 20 68 61 76 65  t that they have
11d70 20 6e 6f 74 20 79 65 74 20 70 6f 70 75 6c 61 74   not yet populat
11d80 65 64 20 61 46 69 6c 65 5b 30 5d 20 61 6e 64 0a  ed aFile[0] and.
11d90 2a 2a 20 73 65 74 20 74 68 65 20 50 6d 61 52 65  ** set the PmaRe
11da0 61 64 65 72 20 6f 62 6a 65 63 74 73 20 75 70 20  ader objects up 
11db0 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 69 74 2e  to read from it.
11dc0 20 49 6e 20 74 68 69 73 20 63 61 73 65 20 61 6c   In this case al
11dd0 6c 20 74 68 61 74 20 69 73 0a 2a 2a 20 72 65 71  l that is.** req
11de0 75 69 72 65 64 20 69 73 20 74 6f 20 63 61 6c 6c  uired is to call
11df0 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 4e 65   vdbePmaReaderNe
11e00 78 74 28 29 20 6f 6e 20 65 61 63 68 20 50 6d 61  xt() on each Pma
11e10 52 65 61 64 65 72 20 74 6f 20 70 6f 69 6e 74 20  Reader to point 
11e20 69 74 20 61 74 0a 2a 2a 20 69 74 73 20 66 69 72  it at.** its fir
11e30 73 74 20 6b 65 79 2e 0a 2a 2a 0a 2a 2a 20 4f 74  st key..**.** Ot
11e40 68 65 72 77 69 73 65 2c 20 69 66 20 65 4d 6f 64  herwise, if eMod
11e50 65 20 69 73 20 61 6e 79 20 76 61 6c 75 65 20 6f  e is any value o
11e60 74 68 65 72 20 74 68 61 6e 20 49 4e 43 52 49 4e  ther than INCRIN
11e70 49 54 5f 52 4f 4f 54 2c 20 74 68 65 6e 20 75 73  IT_ROOT, then us
11e80 65 20 0a 2a 2a 20 76 64 62 65 50 6d 61 52 65 61  e .** vdbePmaRea
11e90 64 65 72 49 6e 63 72 4d 65 72 67 65 49 6e 69 74  derIncrMergeInit
11ea0 28 29 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65  () to initialize
11eb0 20 65 61 63 68 20 50 6d 61 52 65 61 64 65 72 20   each PmaReader 
11ec0 74 68 61 74 20 66 65 65 64 73 20 64 61 74 61 20  that feeds data 
11ed0 0a 2a 2a 20 74 6f 20 70 4d 65 72 67 65 72 2e 0a  .** to pMerger..
11ee0 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20  **.** SQLITE_OK 
11ef0 69 73 20 72 65 74 75 72 6e 65 64 20 69 66 20 73  is returned if s
11f00 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e  uccessful, or an
11f10 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
11f20 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f  de otherwise..*/
11f30 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65  .static int vdbe
11f40 4d 65 72 67 65 45 6e 67 69 6e 65 49 6e 69 74 28  MergeEngineInit(
11f50 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a  .  SortSubtask *
11f60 70 54 61 73 6b 2c 20 20 20 20 20 20 20 20 20 20  pTask,          
11f70 20 20 20 2f 2a 20 54 68 72 65 61 64 20 74 68 61     /* Thread tha
11f80 74 20 77 69 6c 6c 20 72 75 6e 20 70 4d 65 72 67  t will run pMerg
11f90 65 72 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67  er */.  MergeEng
11fa0 69 6e 65 20 2a 70 4d 65 72 67 65 72 2c 20 20 20  ine *pMerger,   
11fb0 20 20 20 20 20 20 20 20 2f 2a 20 4d 65 72 67 65          /* Merge
11fc0 45 6e 67 69 6e 65 20 74 6f 20 69 6e 69 74 69 61  Engine to initia
11fd0 6c 69 7a 65 20 2a 2f 0a 20 20 69 6e 74 20 65 4d  lize */.  int eM
11fe0 6f 64 65 20 20 20 20 20 20 20 20 20 20 20 20 20  ode             
11ff0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e 65            /* One
12000 20 6f 66 20 74 68 65 20 49 4e 43 52 49 4e 49 54   of the INCRINIT
12010 5f 58 58 58 20 63 6f 6e 73 74 61 6e 74 73 20 2a  _XXX constants *
12020 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  /.){.  int rc = 
12030 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20  SQLITE_OK;      
12040 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
12050 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 69   code */.  int i
12060 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
12070 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6f             /* Fo
12080 72 20 6c 6f 6f 70 69 6e 67 20 6f 76 65 72 20 50  r looping over P
12090 6d 61 52 65 61 64 65 72 20 6f 62 6a 65 63 74 73  maReader objects
120a0 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 72 65 65 20   */.  int nTree 
120b0 3d 20 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65  = pMerger->nTree
120c0 3b 0a 0a 20 20 2f 2a 20 65 4d 6f 64 65 20 69 73  ;..  /* eMode is
120d0 20 61 6c 77 61 79 73 20 49 4e 43 52 49 4e 49 54   always INCRINIT
120e0 5f 4e 4f 52 4d 41 4c 20 69 6e 20 73 69 6e 67 6c  _NORMAL in singl
120f0 65 2d 74 68 72 65 61 64 65 64 20 6d 6f 64 65 20  e-threaded mode 
12100 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 53 51 4c  */.  assert( SQL
12110 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54  ITE_MAX_WORKER_T
12120 48 52 45 41 44 53 3e 30 20 7c 7c 20 65 4d 6f 64  HREADS>0 || eMod
12130 65 3d 3d 49 4e 43 52 49 4e 49 54 5f 4e 4f 52 4d  e==INCRINIT_NORM
12140 41 4c 20 29 3b 0a 0a 20 20 2f 2a 20 56 65 72 69  AL );..  /* Veri
12150 66 79 20 74 68 61 74 20 74 68 65 20 4d 65 72 67  fy that the Merg
12160 65 45 6e 67 69 6e 65 20 69 73 20 61 73 73 69 67  eEngine is assig
12170 6e 65 64 20 74 6f 20 61 20 73 69 6e 67 6c 65 20  ned to a single 
12180 74 68 72 65 61 64 20 2a 2f 0a 20 20 61 73 73 65  thread */.  asse
12190 72 74 28 20 70 4d 65 72 67 65 72 2d 3e 70 54 61  rt( pMerger->pTa
121a0 73 6b 3d 3d 30 20 29 3b 0a 20 20 70 4d 65 72 67  sk==0 );.  pMerg
121b0 65 72 2d 3e 70 54 61 73 6b 20 3d 20 70 54 61 73  er->pTask = pTas
121c0 6b 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  k;..  for(i=0; i
121d0 3c 6e 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20 20  <nTree; i++){.  
121e0 20 20 69 66 28 20 53 51 4c 49 54 45 5f 4d 41 58    if( SQLITE_MAX
121f0 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e  _WORKER_THREADS>
12200 30 20 26 26 20 65 4d 6f 64 65 3d 3d 49 4e 43 52  0 && eMode==INCR
12210 49 4e 49 54 5f 52 4f 4f 54 20 29 7b 0a 20 20 20  INIT_ROOT ){.   
12220 20 20 20 2f 2a 20 50 6d 61 52 65 61 64 65 72 73     /* PmaReaders
12230 20 73 68 6f 75 6c 64 20 62 65 20 6e 6f 72 6d 61   should be norma
12240 6c 6c 79 20 69 6e 69 74 69 61 6c 69 7a 65 64 20  lly initialized 
12250 69 6e 20 6f 72 64 65 72 2c 20 61 73 20 69 66 20  in order, as if 
12260 74 68 65 79 20 61 72 65 0a 20 20 20 20 20 20 2a  they are.      *
12270 2a 20 72 65 61 64 69 6e 67 20 66 72 6f 6d 20 74  * reading from t
12280 68 65 20 73 61 6d 65 20 74 65 6d 70 20 66 69 6c  he same temp fil
12290 65 20 74 68 69 73 20 6d 61 6b 65 73 20 66 6f 72  e this makes for
122a0 20 6d 6f 72 65 20 6c 69 6e 65 61 72 20 66 69 6c   more linear fil
122b0 65 20 49 4f 2e 0a 20 20 20 20 20 20 2a 2a 20 48  e IO..      ** H
122c0 6f 77 65 76 65 72 2c 20 69 6e 20 74 68 65 20 49  owever, in the I
122d0 4e 43 52 49 4e 49 54 5f 52 4f 4f 54 20 63 61 73  NCRINIT_ROOT cas
122e0 65 2c 20 69 66 20 50 6d 61 52 65 61 64 65 72 20  e, if PmaReader 
122f0 61 52 65 61 64 72 5b 6e 54 61 73 6b 2d 31 5d 20  aReadr[nTask-1] 
12300 69 73 0a 20 20 20 20 20 20 2a 2a 20 69 6e 20 75  is.      ** in u
12310 73 65 20 69 74 20 77 69 6c 6c 20 62 6c 6f 63 6b  se it will block
12320 20 74 68 65 20 76 64 62 65 50 6d 61 52 65 61 64   the vdbePmaRead
12330 65 72 4e 65 78 74 28 29 20 63 61 6c 6c 20 77 68  erNext() call wh
12340 69 6c 65 20 69 74 20 75 73 65 73 0a 20 20 20 20  ile it uses.    
12350 20 20 2a 2a 20 74 68 65 20 6d 61 69 6e 20 74 68    ** the main th
12360 72 65 61 64 20 74 6f 20 66 69 6c 6c 20 69 74 73  read to fill its
12370 20 62 75 66 66 65 72 2e 20 53 6f 20 63 61 6c 6c   buffer. So call
12380 69 6e 67 20 50 6d 61 52 65 61 64 65 72 4e 65 78  ing PmaReaderNex
12390 74 28 29 0a 20 20 20 20 20 20 2a 2a 20 6f 6e 20  t().      ** on 
123a0 74 68 69 73 20 50 6d 61 52 65 61 64 65 72 20 62  this PmaReader b
123b0 65 66 6f 72 65 20 61 6e 79 20 6f 66 20 74 68 65  efore any of the
123c0 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20   multi-threaded 
123d0 50 6d 61 52 65 61 64 65 72 73 20 74 61 6b 65 73  PmaReaders takes
123e0 0a 20 20 20 20 20 20 2a 2a 20 62 65 74 74 65 72  .      ** better
123f0 20 61 64 76 61 6e 74 61 67 65 20 6f 66 20 6d 75   advantage of mu
12400 6c 74 69 2d 70 72 6f 63 65 73 73 6f 72 20 68 61  lti-processor ha
12410 72 64 77 61 72 65 2e 20 2a 2f 0a 20 20 20 20 20  rdware. */.     
12420 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61   rc = vdbePmaRea
12430 64 65 72 4e 65 78 74 28 26 70 4d 65 72 67 65 72  derNext(&pMerger
12440 2d 3e 61 52 65 61 64 72 5b 6e 54 72 65 65 2d 69  ->aReadr[nTree-i
12450 2d 31 5d 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  -1]);.    }else{
12460 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65  .      rc = vdbe
12470 50 6d 61 52 65 61 64 65 72 49 6e 63 72 4d 65 72  PmaReaderIncrMer
12480 67 65 49 6e 69 74 28 26 70 4d 65 72 67 65 72 2d  geInit(&pMerger-
12490 3e 61 52 65 61 64 72 5b 69 5d 2c 20 49 4e 43 52  >aReadr[i], INCR
124a0 49 4e 49 54 5f 4e 4f 52 4d 41 4c 29 3b 0a 20 20  INIT_NORMAL);.  
124b0 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 21 3d    }.    if( rc!=
124c0 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
124d0 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 66 6f  rn rc;.  }..  fo
124e0 72 28 69 3d 70 4d 65 72 67 65 72 2d 3e 6e 54 72  r(i=pMerger->nTr
124f0 65 65 2d 31 3b 20 69 3e 30 3b 20 69 2d 2d 29 7b  ee-1; i>0; i--){
12500 0a 20 20 20 20 76 64 62 65 4d 65 72 67 65 45 6e  .    vdbeMergeEn
12510 67 69 6e 65 43 6f 6d 70 61 72 65 28 70 4d 65 72  gineCompare(pMer
12520 67 65 72 2c 20 69 29 3b 0a 20 20 7d 0a 20 20 72  ger, i);.  }.  r
12530 65 74 75 72 6e 20 70 54 61 73 6b 2d 3e 70 55 6e  eturn pTask->pUn
12540 70 61 63 6b 65 64 2d 3e 65 72 72 43 6f 64 65 3b  packed->errCode;
12550 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61  .}../*.** Initia
12560 6c 69 7a 65 20 74 68 65 20 49 6e 63 72 4d 65 72  lize the IncrMer
12570 67 65 20 66 69 65 6c 64 20 6f 66 20 61 20 50 6d  ge field of a Pm
12580 61 52 65 61 64 65 72 2e 0a 2a 2a 0a 2a 2a 20 49  aReader..**.** I
12590 66 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 20  f the PmaReader 
125a0 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69  passed as the fi
125b0 72 73 74 20 61 72 67 75 6d 65 6e 74 20 69 73 20  rst argument is 
125c0 6e 6f 74 20 61 6e 20 69 6e 63 72 65 6d 65 6e 74  not an increment
125d0 61 6c 2d 72 65 61 64 65 72 0a 2a 2a 20 28 69 66  al-reader.** (if
125e0 20 70 52 65 61 64 72 2d 3e 70 49 6e 63 72 3d 3d   pReadr->pIncr==
125f0 30 29 2c 20 74 68 65 6e 20 74 68 69 73 20 66 75  0), then this fu
12600 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f  nction is a no-o
12610 70 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69 74  p. Otherwise, it
12620 20 73 65 72 76 65 73 0a 2a 2a 20 74 6f 20 6f 70   serves.** to op
12630 65 6e 20 61 6e 64 2f 6f 72 20 69 6e 69 74 69 61  en and/or initia
12640 6c 69 7a 65 20 74 68 65 20 74 65 6d 70 20 66 69  lize the temp fi
12650 6c 65 20 72 65 6c 61 74 65 64 20 66 69 65 6c 64  le related field
12660 73 20 6f 66 20 74 68 65 20 49 6e 63 72 4d 65 72  s of the IncrMer
12670 67 65 0a 2a 2a 20 6f 62 6a 65 63 74 20 61 74 20  ge.** object at 
12680 28 70 52 65 61 64 72 2d 3e 70 49 6e 63 72 29 2e  (pReadr->pIncr).
12690 0a 2a 2a 0a 2a 2a 20 49 66 20 61 72 67 75 6d 65  .**.** If argume
126a0 6e 74 20 65 4d 6f 64 65 20 69 73 20 73 65 74 20  nt eMode is set 
126b0 74 6f 20 49 4e 43 52 49 4e 49 54 5f 4e 4f 52 4d  to INCRINIT_NORM
126c0 41 4c 2c 20 74 68 65 6e 20 61 6c 6c 20 50 6d 61  AL, then all Pma
126d0 52 65 61 64 65 72 73 0a 2a 2a 20 69 6e 20 74 68  Readers.** in th
126e0 65 20 73 75 62 2d 74 72 65 65 20 68 65 61 64 65  e sub-tree heade
126f0 64 20 62 79 20 70 52 65 61 64 72 20 61 72 65 20  d by pReadr are 
12700 61 6c 73 6f 20 69 6e 69 74 69 61 6c 69 7a 65 64  also initialized
12710 2e 20 44 61 74 61 20 69 73 20 74 68 65 6e 20 6c  . Data is then l
12720 6f 61 64 65 64 0a 2a 2a 20 69 6e 74 6f 20 74 68  oaded.** into th
12730 65 20 62 75 66 66 65 72 73 20 62 65 6c 6f 6e 67  e buffers belong
12740 69 6e 67 20 74 6f 20 70 52 65 61 64 72 20 61 6e  ing to pReadr an
12750 64 20 69 74 20 69 73 20 73 65 74 20 74 6f 0a 2a  d it is set to.*
12760 2a 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 66  * point to the f
12770 69 72 73 74 20 6b 65 79 20 69 6e 20 69 74 73 20  irst key in its 
12780 72 61 6e 67 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  range..**.** If 
12790 61 72 67 75 6d 65 6e 74 20 65 4d 6f 64 65 20 69  argument eMode i
127a0 73 20 73 65 74 20 74 6f 20 49 4e 43 52 49 4e 49  s set to INCRINI
127b0 54 5f 54 41 53 4b 2c 20 74 68 65 6e 20 70 52 65  T_TASK, then pRe
127c0 61 64 72 20 69 73 20 67 75 61 72 61 6e 74 65 65  adr is guarantee
127d0 64 0a 2a 2a 20 74 6f 20 62 65 20 61 20 6d 75 6c  d.** to be a mul
127e0 74 69 2d 74 68 72 65 61 64 65 64 20 50 6d 61 52  ti-threaded PmaR
127f0 65 61 64 65 72 20 61 6e 64 20 74 68 69 73 20 66  eader and this f
12800 75 6e 63 74 69 6f 6e 20 69 73 20 62 65 69 6e 67  unction is being
12810 20 63 61 6c 6c 65 64 20 69 6e 20 61 0a 2a 2a 20   called in a.** 
12820 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61  background threa
12830 64 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65 20  d. In this case 
12840 61 6c 6c 20 50 6d 61 52 65 61 64 65 72 73 20 69  all PmaReaders i
12850 6e 20 74 68 65 20 73 75 62 2d 74 72 65 65 20 61  n the sub-tree a
12860 72 65 20 0a 2a 2a 20 69 6e 69 74 69 61 6c 69 7a  re .** initializ
12870 65 64 20 61 73 20 66 6f 72 20 49 4e 43 52 49 4e  ed as for INCRIN
12880 49 54 5f 4e 4f 52 4d 41 4c 20 61 6e 64 20 74 68  IT_NORMAL and th
12890 65 20 61 46 69 6c 65 5b 31 5d 20 62 75 66 66 65  e aFile[1] buffe
128a0 72 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 0a 2a  r belonging to.*
128b0 2a 20 70 52 65 61 64 72 20 69 73 20 70 6f 70 75  * pReadr is popu
128c0 6c 61 74 65 64 2e 20 48 6f 77 65 76 65 72 2c 20  lated. However, 
128d0 70 52 65 61 64 72 20 69 74 73 65 6c 66 20 69 73  pReadr itself is
128e0 20 6e 6f 74 20 73 65 74 20 75 70 20 74 6f 20 70   not set up to p
128f0 6f 69 6e 74 0a 2a 2a 20 74 6f 20 69 74 73 20 66  oint.** to its f
12900 69 72 73 74 20 6b 65 79 2e 20 41 20 63 61 6c 6c  irst key. A call
12910 20 74 6f 20 76 64 62 65 50 6d 61 52 65 61 64 65   to vdbePmaReade
12920 72 4e 65 78 74 28 29 20 69 73 20 73 74 69 6c 6c  rNext() is still
12930 20 72 65 71 75 69 72 65 64 20 74 6f 20 64 6f 0a   required to do.
12940 2a 2a 20 74 68 61 74 2e 20 0a 2a 2a 0a 2a 2a 20  ** that. .**.** 
12950 54 68 65 20 72 65 61 73 6f 6e 20 74 68 69 73 20  The reason this 
12960 66 75 6e 63 74 69 6f 6e 20 64 6f 65 73 20 6e 6f  function does no
12970 74 20 63 61 6c 6c 20 76 64 62 65 50 6d 61 52 65  t call vdbePmaRe
12980 61 64 65 72 4e 65 78 74 28 29 20 69 6d 6d 65 64  aderNext() immed
12990 69 61 74 65 6c 79 20 0a 2a 2a 20 69 6e 20 74 68  iately .** in th
129a0 65 20 49 4e 43 52 49 4e 49 54 5f 54 41 53 4b 20  e INCRINIT_TASK 
129b0 63 61 73 65 20 69 73 20 74 68 61 74 20 76 64 62  case is that vdb
129c0 65 50 6d 61 52 65 61 64 65 72 4e 65 78 74 28 29  ePmaReaderNext()
129d0 20 61 73 73 75 6d 65 73 20 74 68 61 74 20 69 74   assumes that it
129e0 20 68 61 73 0a 2a 2a 20 74 6f 20 62 6c 6f 63 6b   has.** to block
129f0 20 6f 6e 20 74 68 72 65 61 64 20 28 70 54 61 73   on thread (pTas
12a00 6b 2d 3e 74 68 72 65 61 64 29 20 62 65 66 6f 72  k->thread) befor
12a10 65 20 61 63 63 65 73 73 69 6e 67 20 61 46 69 6c  e accessing aFil
12a20 65 5b 31 5d 2e 20 42 75 74 2c 20 73 69 6e 63 65  e[1]. But, since
12a30 0a 2a 2a 20 74 68 69 73 20 65 6e 74 69 72 65 20  .** this entire 
12a40 66 75 6e 63 74 69 6f 6e 20 69 73 20 62 65 69 6e  function is bein
12a50 67 20 72 75 6e 20 62 79 20 74 68 72 65 61 64 20  g run by thread 
12a60 28 70 54 61 73 6b 2d 3e 74 68 72 65 61 64 29 2c  (pTask->thread),
12a70 20 74 68 61 74 20 77 69 6c 6c 0a 2a 2a 20 6c 65   that will.** le
12a80 61 64 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e  ad to the curren
12a90 74 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  t background thr
12aa0 65 61 64 20 61 74 74 65 6d 70 74 69 6e 67 20 74  ead attempting t
12ab0 6f 20 6a 6f 69 6e 20 69 74 73 65 6c 66 2e 0a 2a  o join itself..*
12ac0 2a 0a 2a 2a 20 46 69 6e 61 6c 6c 79 2c 20 69 66  *.** Finally, if
12ad0 20 61 72 67 75 6d 65 6e 74 20 65 4d 6f 64 65 20   argument eMode 
12ae0 69 73 20 73 65 74 20 74 6f 20 49 4e 43 52 49 4e  is set to INCRIN
12af0 49 54 5f 52 4f 4f 54 2c 20 69 74 20 6d 61 79 20  IT_ROOT, it may 
12b00 62 65 20 61 73 73 75 6d 65 64 0a 2a 2a 20 74 68  be assumed.** th
12b10 61 74 20 70 52 65 61 64 72 2d 3e 70 49 6e 63 72  at pReadr->pIncr
12b20 20 69 73 20 61 20 6d 75 6c 74 69 2d 74 68 72 65   is a multi-thre
12b30 61 64 65 64 20 49 6e 63 72 4d 65 72 67 65 20 6f  aded IncrMerge o
12b40 62 6a 65 63 74 73 2c 20 61 6e 64 20 74 68 61 74  bjects, and that
12b50 20 61 6c 6c 0a 2a 2a 20 63 68 69 6c 64 2d 74 72   all.** child-tr
12b60 65 65 73 20 68 61 76 65 20 61 6c 72 65 61 64 79  ees have already
12b70 20 62 65 65 6e 20 69 6e 69 74 69 61 6c 69 7a 65   been initialize
12b80 64 20 75 73 69 6e 67 20 49 6e 63 72 49 6e 69 74  d using IncrInit
12b90 28 49 4e 43 52 49 4e 49 54 5f 54 41 53 4b 29 2e  (INCRINIT_TASK).
12ba0 0a 2a 2a 20 49 6e 20 74 68 69 73 20 63 61 73 65  .** In this case
12bb0 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 4e 65   vdbePmaReaderNe
12bc0 78 74 28 29 20 69 73 20 63 61 6c 6c 65 64 20 6f  xt() is called o
12bd0 6e 20 61 6c 6c 20 63 68 69 6c 64 20 50 6d 61 52  n all child PmaR
12be0 65 61 64 65 72 73 20 61 6e 64 0a 2a 2a 20 74 68  eaders and.** th
12bf0 65 20 63 75 72 72 65 6e 74 20 50 6d 61 52 65 61  e current PmaRea
12c00 64 65 72 20 73 65 74 20 74 6f 20 70 6f 69 6e 74  der set to point
12c10 20 74 6f 20 74 68 65 20 66 69 72 73 74 20 6b 65   to the first ke
12c20 79 20 69 6e 20 69 74 73 20 72 61 6e 67 65 2e 0a  y in its range..
12c30 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20  **.** SQLITE_OK 
12c40 69 73 20 72 65 74 75 72 6e 65 64 20 69 66 20 73  is returned if s
12c50 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e  uccessful, or an
12c60 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
12c70 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f  de otherwise..*/
12c80 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65  .static int vdbe
12c90 50 6d 61 52 65 61 64 65 72 49 6e 63 72 4d 65 72  PmaReaderIncrMer
12ca0 67 65 49 6e 69 74 28 50 6d 61 52 65 61 64 65 72  geInit(PmaReader
12cb0 20 2a 70 52 65 61 64 72 2c 20 69 6e 74 20 65 4d   *pReadr, int eM
12cc0 6f 64 65 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  ode){.  int rc =
12cd0 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 49 6e   SQLITE_OK;.  In
12ce0 63 72 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 20  crMerger *pIncr 
12cf0 3d 20 70 52 65 61 64 72 2d 3e 70 49 6e 63 72 3b  = pReadr->pIncr;
12d00 0a 0a 20 20 2f 2a 20 65 4d 6f 64 65 20 69 73 20  ..  /* eMode is 
12d10 61 6c 77 61 79 73 20 49 4e 43 52 49 4e 49 54 5f  always INCRINIT_
12d20 4e 4f 52 4d 41 4c 20 69 6e 20 73 69 6e 67 6c 65  NORMAL in single
12d30 2d 74 68 72 65 61 64 65 64 20 6d 6f 64 65 20 2a  -threaded mode *
12d40 2f 0a 20 20 61 73 73 65 72 74 28 20 53 51 4c 49  /.  assert( SQLI
12d50 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48  TE_MAX_WORKER_TH
12d60 52 45 41 44 53 3e 30 20 7c 7c 20 65 4d 6f 64 65  READS>0 || eMode
12d70 3d 3d 49 4e 43 52 49 4e 49 54 5f 4e 4f 52 4d 41  ==INCRINIT_NORMA
12d80 4c 20 29 3b 0a 0a 20 20 69 66 28 20 70 49 6e 63  L );..  if( pInc
12d90 72 20 29 7b 0a 20 20 20 20 53 6f 72 74 53 75 62  r ){.    SortSub
12da0 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20 70 49  task *pTask = pI
12db0 6e 63 72 2d 3e 70 54 61 73 6b 3b 0a 20 20 20 20  ncr->pTask;.    
12dc0 73 71 6c 69 74 65 33 20 2a 64 62 20 3d 20 70 54  sqlite3 *db = pT
12dd0 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 64 62  ask->pSorter->db
12de0 3b 0a 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65  ;..    rc = vdbe
12df0 4d 65 72 67 65 45 6e 67 69 6e 65 49 6e 69 74 28  MergeEngineInit(
12e00 70 54 61 73 6b 2c 20 70 49 6e 63 72 2d 3e 70 4d  pTask, pIncr->pM
12e10 65 72 67 65 72 2c 20 65 4d 6f 64 65 29 3b 0a 0a  erger, eMode);..
12e20 20 20 20 20 2f 2a 20 53 65 74 20 75 70 20 74 68      /* Set up th
12e30 65 20 72 65 71 75 69 72 65 64 20 66 69 6c 65 73  e required files
12e40 20 66 6f 72 20 70 49 6e 63 72 2e 20 41 20 6d 75   for pIncr. A mu
12e50 6c 74 69 2d 74 68 65 61 64 65 64 20 49 6e 63 72  lti-theaded Incr
12e60 4d 65 72 67 65 20 6f 62 6a 65 63 74 0a 20 20 20  Merge object.   
12e70 20 2a 2a 20 72 65 71 75 69 72 65 73 20 74 77 6f   ** requires two
12e80 20 74 65 6d 70 20 66 69 6c 65 73 20 74 6f 20 69   temp files to i
12e90 74 73 65 6c 66 2c 20 77 68 65 72 65 61 73 20 61  tself, whereas a
12ea0 20 73 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64   single-threaded
12eb0 20 6f 62 6a 65 63 74 0a 20 20 20 20 2a 2a 20 6f   object.    ** o
12ec0 6e 6c 79 20 72 65 71 75 69 72 65 73 20 61 20 72  nly requires a r
12ed0 65 67 69 6f 6e 20 6f 66 20 70 54 61 73 6b 2d 3e  egion of pTask->
12ee0 66 69 6c 65 32 2e 20 2a 2f 0a 20 20 20 20 69 66  file2. */.    if
12ef0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
12f00 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6d 78 53  ){.      int mxS
12f10 7a 20 3d 20 70 49 6e 63 72 2d 3e 6d 78 53 7a 3b  z = pIncr->mxSz;
12f20 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f  .#if SQLITE_MAX_
12f30 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30  WORKER_THREADS>0
12f40 0a 20 20 20 20 20 20 69 66 28 20 70 49 6e 63 72  .      if( pIncr
12f50 2d 3e 62 55 73 65 54 68 72 65 61 64 20 29 7b 0a  ->bUseThread ){.
12f60 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62          rc = vdb
12f70 65 53 6f 72 74 65 72 4f 70 65 6e 54 65 6d 70 46  eSorterOpenTempF
12f80 69 6c 65 28 64 62 2c 20 6d 78 53 7a 2c 20 26 70  ile(db, mxSz, &p
12f90 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e 70  Incr->aFile[0].p
12fa0 46 64 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  Fd);.        if(
12fb0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
12fc0 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d  {.          rc =
12fd0 20 76 64 62 65 53 6f 72 74 65 72 4f 70 65 6e 54   vdbeSorterOpenT
12fe0 65 6d 70 46 69 6c 65 28 64 62 2c 20 6d 78 53 7a  empFile(db, mxSz
12ff0 2c 20 26 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b  , &pIncr->aFile[
13000 31 5d 2e 70 46 64 29 3b 0a 20 20 20 20 20 20 20  1].pFd);.       
13010 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 0a 23   }.      }else.#
13020 65 6e 64 69 66 0a 20 20 20 20 20 20 2f 2a 69 66  endif.      /*if
13030 28 20 21 70 49 6e 63 72 2d 3e 62 55 73 65 54 68  ( !pIncr->bUseTh
13040 72 65 61 64 20 29 2a 2f 7b 0a 20 20 20 20 20 20  read )*/{.      
13050 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 66 69 6c    if( pTask->fil
13060 65 32 2e 70 46 64 3d 3d 30 20 29 7b 0a 20 20 20  e2.pFd==0 ){.   
13070 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70         assert( p
13080 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66  Task->file2.iEof
13090 3e 30 20 29 3b 0a 20 20 20 20 20 20 20 20 20 20  >0 );.          
130a0 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4f  rc = vdbeSorterO
130b0 70 65 6e 54 65 6d 70 46 69 6c 65 28 64 62 2c 20  penTempFile(db, 
130c0 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f  pTask->file2.iEo
130d0 66 2c 20 26 70 54 61 73 6b 2d 3e 66 69 6c 65 32  f, &pTask->file2
130e0 2e 70 46 64 29 3b 0a 20 20 20 20 20 20 20 20 20  .pFd);.         
130f0 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45   pTask->file2.iE
13100 6f 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  of = 0;.        
13110 7d 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  }.        if( rc
13120 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
13130 20 20 20 20 20 20 20 20 20 70 49 6e 63 72 2d 3e           pIncr->
13140 61 46 69 6c 65 5b 31 5d 2e 70 46 64 20 3d 20 70  aFile[1].pFd = p
13150 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64 3b  Task->file2.pFd;
13160 0a 20 20 20 20 20 20 20 20 20 20 70 49 6e 63 72  .          pIncr
13170 2d 3e 69 53 74 61 72 74 4f 66 66 20 3d 20 70 54  ->iStartOff = pT
13180 61 73 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 3b  ask->file2.iEof;
13190 0a 20 20 20 20 20 20 20 20 20 20 70 54 61 73 6b  .          pTask
131a0 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 20 2b 3d 20  ->file2.iEof += 
131b0 6d 78 53 7a 3b 0a 20 20 20 20 20 20 20 20 7d 0a  mxSz;.        }.
131c0 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 23        }.    }..#
131d0 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f  if SQLITE_MAX_WO
131e0 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 0a 20  RKER_THREADS>0. 
131f0 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
13200 45 5f 4f 4b 20 26 26 20 70 49 6e 63 72 2d 3e 62  E_OK && pIncr->b
13210 55 73 65 54 68 72 65 61 64 20 29 7b 0a 20 20 20  UseThread ){.   
13220 20 20 20 2f 2a 20 55 73 65 20 74 68 65 20 63 75     /* Use the cu
13230 72 72 65 6e 74 20 74 68 72 65 61 64 20 74 6f 20  rrent thread to 
13240 70 6f 70 75 6c 61 74 65 20 61 46 69 6c 65 5b 31  populate aFile[1
13250 5d 2c 20 65 76 65 6e 20 74 68 6f 75 67 68 20 74  ], even though t
13260 68 69 73 0a 20 20 20 20 20 20 2a 2a 20 50 6d 61  his.      ** Pma
13270 52 65 61 64 65 72 20 69 73 20 6d 75 6c 74 69 2d  Reader is multi-
13280 74 68 72 65 61 64 65 64 2e 20 54 68 65 20 72 65  threaded. The re
13290 61 73 6f 6e 20 62 65 69 6e 67 20 74 68 61 74 20  ason being that 
132a0 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 0a 20 20  this function.  
132b0 20 20 20 20 2a 2a 20 69 73 20 61 6c 72 65 61 64      ** is alread
132c0 79 20 72 75 6e 6e 69 6e 67 20 69 6e 20 62 61 63  y running in bac
132d0 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 70  kground thread p
132e0 49 6e 63 72 2d 3e 70 54 61 73 6b 2d 3e 74 68 72  Incr->pTask->thr
132f0 65 61 64 2e 20 2a 2f 0a 20 20 20 20 20 20 61 73  ead. */.      as
13300 73 65 72 74 28 20 65 4d 6f 64 65 3d 3d 49 4e 43  sert( eMode==INC
13310 52 49 4e 49 54 5f 52 4f 4f 54 20 7c 7c 20 65 4d  RINIT_ROOT || eM
13320 6f 64 65 3d 3d 49 4e 43 52 49 4e 49 54 5f 54 41  ode==INCRINIT_TA
13330 53 4b 20 29 3b 0a 20 20 20 20 20 20 72 63 20 3d  SK );.      rc =
13340 20 76 64 62 65 49 6e 63 72 50 6f 70 75 6c 61 74   vdbeIncrPopulat
13350 65 28 70 49 6e 63 72 29 3b 0a 20 20 20 20 7d 0a  e(pIncr);.    }.
13360 23 65 6e 64 69 66 0a 0a 20 20 20 20 69 66 28 20  #endif..    if( 
13370 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 0a 20 20  rc==SQLITE_OK.  
13380 20 20 20 26 26 20 28 53 51 4c 49 54 45 5f 4d 41     && (SQLITE_MA
13390 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53  X_WORKER_THREADS
133a0 3d 3d 30 20 7c 7c 20 65 4d 6f 64 65 21 3d 49 4e  ==0 || eMode!=IN
133b0 43 52 49 4e 49 54 5f 54 41 53 4b 29 0a 20 20 20  CRINIT_TASK).   
133c0 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 76   ){.      rc = v
133d0 64 62 65 50 6d 61 52 65 61 64 65 72 4e 65 78 74  dbePmaReaderNext
133e0 28 70 52 65 61 64 72 29 3b 0a 20 20 20 20 7d 0a  (pReadr);.    }.
133f0 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
13400 0a 7d 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d  .}..#if SQLITE_M
13410 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44  AX_WORKER_THREAD
13420 53 3e 30 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d 61  S>0./*.** The ma
13430 69 6e 20 72 6f 75 74 69 6e 65 20 66 6f 72 20 76  in routine for v
13440 64 62 65 50 6d 61 52 65 61 64 65 72 49 6e 63 72  dbePmaReaderIncr
13450 4d 65 72 67 65 49 6e 69 74 28 29 20 6f 70 65 72  MergeInit() oper
13460 61 74 69 6f 6e 73 20 72 75 6e 20 69 6e 20 0a 2a  ations run in .*
13470 2a 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  * background thr
13480 65 61 64 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  eads..*/.static 
13490 76 6f 69 64 20 2a 76 64 62 65 50 6d 61 52 65 61  void *vdbePmaRea
134a0 64 65 72 42 67 49 6e 69 74 28 76 6f 69 64 20 2a  derBgInit(void *
134b0 70 43 74 78 29 7b 0a 20 20 50 6d 61 52 65 61 64  pCtx){.  PmaRead
134c0 65 72 20 2a 70 52 65 61 64 65 72 20 3d 20 28 50  er *pReader = (P
134d0 6d 61 52 65 61 64 65 72 2a 29 70 43 74 78 3b 0a  maReader*)pCtx;.
134e0 20 20 76 6f 69 64 20 2a 70 52 65 74 20 3d 20 53    void *pRet = S
134f0 51 4c 49 54 45 5f 49 4e 54 5f 54 4f 5f 50 54 52  QLITE_INT_TO_PTR
13500 28 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  (.              
13510 20 20 20 20 76 64 62 65 50 6d 61 52 65 61 64 65      vdbePmaReade
13520 72 49 6e 63 72 4d 65 72 67 65 49 6e 69 74 28 70  rIncrMergeInit(p
13530 52 65 61 64 65 72 2c 49 4e 43 52 49 4e 49 54 5f  Reader,INCRINIT_
13540 54 41 53 4b 29 0a 20 20 20 20 20 20 20 20 20 20  TASK).          
13550 20 20 20 20 20 29 3b 0a 20 20 70 52 65 61 64 65       );.  pReade
13560 72 2d 3e 70 49 6e 63 72 2d 3e 70 54 61 73 6b 2d  r->pIncr->pTask-
13570 3e 62 44 6f 6e 65 20 3d 20 31 3b 0a 20 20 72 65  >bDone = 1;.  re
13580 74 75 72 6e 20 70 52 65 74 3b 0a 7d 0a 0a 2f 2a  turn pRet;.}../*
13590 0a 2a 2a 20 55 73 65 20 61 20 62 61 63 6b 67 72  .** Use a backgr
135a0 6f 75 6e 64 20 74 68 72 65 61 64 20 74 6f 20 69  ound thread to i
135b0 6e 76 6f 6b 65 20 76 64 62 65 50 6d 61 52 65 61  nvoke vdbePmaRea
135c0 64 65 72 49 6e 63 72 4d 65 72 67 65 49 6e 69 74  derIncrMergeInit
135d0 28 49 4e 43 52 49 4e 49 54 5f 54 41 53 4b 29 20  (INCRINIT_TASK) 
135e0 0a 2a 2a 20 6f 6e 20 74 68 65 20 50 6d 61 52 65  .** on the PmaRe
135f0 61 64 65 72 20 6f 62 6a 65 63 74 20 70 61 73 73  ader object pass
13600 65 64 20 61 73 20 74 68 65 20 66 69 72 73 74 20  ed as the first 
13610 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20  argument..**.** 
13620 54 68 69 73 20 63 61 6c 6c 20 77 69 6c 6c 20 69  This call will i
13630 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 76 61  nitialize the va
13640 72 69 6f 75 73 20 66 69 65 6c 64 73 20 6f 66 20  rious fields of 
13650 74 68 65 20 70 52 65 61 64 72 2d 3e 70 49 6e 63  the pReadr->pInc
13660 72 20 0a 2a 2a 20 73 74 72 75 63 74 75 72 65 20  r .** structure 
13670 61 6e 64 2c 20 69 66 20 69 74 20 69 73 20 61 20  and, if it is a 
13680 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20 49  multi-threaded I
13690 6e 63 72 4d 65 72 67 65 72 2c 20 6c 61 75 6e 63  ncrMerger, launc
136a0 68 20 61 20 0a 2a 2a 20 62 61 63 6b 67 72 6f 75  h a .** backgrou
136b0 6e 64 20 74 68 72 65 61 64 20 74 6f 20 70 6f 70  nd thread to pop
136c0 75 6c 61 74 65 20 61 46 69 6c 65 5b 31 5d 2e 0a  ulate aFile[1]..
136d0 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
136e0 62 65 50 6d 61 52 65 61 64 65 72 42 67 49 6e 63  bePmaReaderBgInc
136f0 72 49 6e 69 74 28 50 6d 61 52 65 61 64 65 72 20  rInit(PmaReader 
13700 2a 70 52 65 61 64 72 29 7b 0a 20 20 76 6f 69 64  *pReadr){.  void
13710 20 2a 70 43 74 78 20 3d 20 28 76 6f 69 64 2a 29   *pCtx = (void*)
13720 70 52 65 61 64 72 3b 0a 20 20 72 65 74 75 72 6e  pReadr;.  return
13730 20 76 64 62 65 53 6f 72 74 65 72 43 72 65 61 74   vdbeSorterCreat
13740 65 54 68 72 65 61 64 28 70 52 65 61 64 72 2d 3e  eThread(pReadr->
13750 70 49 6e 63 72 2d 3e 70 54 61 73 6b 2c 20 76 64  pIncr->pTask, vd
13760 62 65 50 6d 61 52 65 61 64 65 72 42 67 49 6e 69  bePmaReaderBgIni
13770 74 2c 20 70 43 74 78 29 3b 0a 7d 0a 23 65 6e 64  t, pCtx);.}.#end
13780 69 66 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61  if../*.** Alloca
13790 74 65 20 61 20 6e 65 77 20 4d 65 72 67 65 45 6e  te a new MergeEn
137a0 67 69 6e 65 20 6f 62 6a 65 63 74 20 74 6f 20 6d  gine object to m
137b0 65 72 67 65 20 74 68 65 20 63 6f 6e 74 65 6e 74  erge the content
137c0 73 20 6f 66 20 6e 50 4d 41 20 6c 65 76 65 6c 2d  s of nPMA level-
137d0 30 0a 2a 2a 20 50 4d 41 73 20 66 72 6f 6d 20 70  0.** PMAs from p
137e0 54 61 73 6b 2d 3e 66 69 6c 65 2e 20 49 66 20 6e  Task->file. If n
137f0 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20  o error occurs, 
13800 73 65 74 20 2a 70 70 4f 75 74 20 74 6f 20 70 6f  set *ppOut to po
13810 69 6e 74 20 74 6f 0a 2a 2a 20 74 68 65 20 6e 65  int to.** the ne
13820 77 20 6f 62 6a 65 63 74 20 61 6e 64 20 72 65 74  w object and ret
13830 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 4f  urn SQLITE_OK. O
13840 72 2c 20 69 66 20 61 6e 20 65 72 72 6f 72 20 64  r, if an error d
13850 6f 65 73 20 6f 63 63 75 72 2c 20 73 65 74 20 2a  oes occur, set *
13860 70 70 4f 75 74 0a 2a 2a 20 74 6f 20 4e 55 4c 4c  ppOut.** to NULL
13870 20 61 6e 64 20 72 65 74 75 72 6e 20 61 6e 20 53   and return an S
13880 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
13890 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 74 68 69  ..**.** When thi
138a0 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
138b0 6c 6c 65 64 2c 20 2a 70 69 4f 66 66 73 65 74 20  lled, *piOffset 
138c0 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 6f 66  is set to the of
138d0 66 73 65 74 20 6f 66 20 74 68 65 0a 2a 2a 20 66  fset of the.** f
138e0 69 72 73 74 20 50 4d 41 20 74 6f 20 72 65 61 64  irst PMA to read
138f0 20 66 72 6f 6d 20 70 54 61 73 6b 2d 3e 66 69 6c   from pTask->fil
13900 65 2e 20 41 73 73 75 6d 69 6e 67 20 6e 6f 20 65  e. Assuming no e
13910 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 69 74 20  rror occurs, it 
13920 69 73 20 0a 2a 2a 20 73 65 74 20 74 6f 20 74 68  is .** set to th
13930 65 20 6f 66 66 73 65 74 20 69 6d 6d 65 64 69 61  e offset immedia
13940 74 65 6c 79 20 66 6f 6c 6c 6f 77 69 6e 67 20 74  tely following t
13950 68 65 20 6c 61 73 74 20 62 79 74 65 20 6f 66 20  he last byte of 
13960 74 68 65 20 6c 61 73 74 0a 2a 2a 20 50 4d 41 20  the last.** PMA 
13970 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  before returning
13980 2e 20 49 66 20 61 6e 20 65 72 72 6f 72 20 64 6f  . If an error do
13990 65 73 20 6f 63 63 75 72 2c 20 74 68 65 6e 20 74  es occur, then t
139a0 68 65 20 66 69 6e 61 6c 20 76 61 6c 75 65 20 6f  he final value o
139b0 66 0a 2a 2a 20 2a 70 69 4f 66 66 73 65 74 20 69  f.** *piOffset i
139c0 73 20 75 6e 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a  s undefined..*/.
139d0 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 4d  static int vdbeM
139e0 65 72 67 65 45 6e 67 69 6e 65 4c 65 76 65 6c 30  ergeEngineLevel0
139f0 28 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20  (.  SortSubtask 
13a00 2a 70 54 61 73 6b 2c 20 20 20 20 20 20 20 20 20  *pTask,         
13a10 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 74 61      /* Sorter ta
13a20 73 6b 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20  sk to read from 
13a30 2a 2f 0a 20 20 69 6e 74 20 6e 50 4d 41 2c 20 20  */.  int nPMA,  
13a40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13a50 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
13a60 66 20 50 4d 41 73 20 74 6f 20 72 65 61 64 20 2a  f PMAs to read *
13a70 2f 0a 20 20 69 36 34 20 2a 70 69 4f 66 66 73 65  /.  i64 *piOffse
13a80 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
13a90 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 52      /* IN/OUT: R
13aa0 65 61 64 72 20 6f 66 66 73 65 74 20 69 6e 20 70  eadr offset in p
13ab0 54 61 73 6b 2d 3e 66 69 6c 65 20 2a 2f 0a 20 20  Task->file */.  
13ac0 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 2a 70 70  MergeEngine **pp
13ad0 4f 75 74 20 20 20 20 20 20 20 20 20 20 20 20 20  Out             
13ae0 2f 2a 20 4f 55 54 3a 20 4e 65 77 20 6d 65 72 67  /* OUT: New merg
13af0 65 2d 65 6e 67 69 6e 65 20 2a 2f 0a 29 7b 0a 20  e-engine */.){. 
13b00 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4e   MergeEngine *pN
13b10 65 77 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ew;             
13b20 20 2f 2a 20 4d 65 72 67 65 20 65 6e 67 69 6e 65   /* Merge engine
13b30 20 74 6f 20 72 65 74 75 72 6e 20 2a 2f 0a 20 20   to return */.  
13b40 69 36 34 20 69 4f 66 66 20 3d 20 2a 70 69 4f 66  i64 iOff = *piOf
13b50 66 73 65 74 3b 0a 20 20 69 6e 74 20 69 3b 0a 20  fset;.  int i;. 
13b60 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
13b70 5f 4f 4b 3b 0a 0a 20 20 2a 70 70 4f 75 74 20 3d  _OK;..  *ppOut =
13b80 20 70 4e 65 77 20 3d 20 76 64 62 65 4d 65 72 67   pNew = vdbeMerg
13b90 65 45 6e 67 69 6e 65 4e 65 77 28 6e 50 4d 41 29  eEngineNew(nPMA)
13ba0 3b 0a 20 20 69 66 28 20 70 4e 65 77 3d 3d 30 20  ;.  if( pNew==0 
13bb0 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f  ) rc = SQLITE_NO
13bc0 4d 45 4d 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b  MEM;..  for(i=0;
13bd0 20 69 3c 6e 50 4d 41 20 26 26 20 72 63 3d 3d 53   i<nPMA && rc==S
13be0 51 4c 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a  QLITE_OK; i++){.
13bf0 20 20 20 20 69 36 34 20 6e 44 75 6d 6d 79 3b 0a      i64 nDummy;.
13c00 20 20 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70      PmaReader *p
13c10 52 65 61 64 72 20 3d 20 26 70 4e 65 77 2d 3e 61  Readr = &pNew->a
13c20 52 65 61 64 72 5b 69 5d 3b 0a 20 20 20 20 72 63  Readr[i];.    rc
13c30 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65 72   = vdbePmaReader
13c40 49 6e 69 74 28 70 54 61 73 6b 2c 20 26 70 54 61  Init(pTask, &pTa
13c50 73 6b 2d 3e 66 69 6c 65 2c 20 69 4f 66 66 2c 20  sk->file, iOff, 
13c60 70 52 65 61 64 72 2c 20 26 6e 44 75 6d 6d 79 29  pReadr, &nDummy)
13c70 3b 0a 20 20 20 20 69 4f 66 66 20 3d 20 70 52 65  ;.    iOff = pRe
13c80 61 64 72 2d 3e 69 45 6f 66 3b 0a 20 20 7d 0a 0a  adr->iEof;.  }..
13c90 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
13ca0 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 64 62 65 4d  _OK ){.    vdbeM
13cb0 65 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28 70  ergeEngineFree(p
13cc0 4e 65 77 29 3b 0a 20 20 20 20 2a 70 70 4f 75 74  New);.    *ppOut
13cd0 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 2a 70 69 4f   = 0;.  }.  *piO
13ce0 66 66 73 65 74 20 3d 20 69 4f 66 66 3b 0a 20 20  ffset = iOff;.  
13cf0 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
13d00 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 64  .** Return the d
13d10 65 70 74 68 20 6f 66 20 61 20 74 72 65 65 20 63  epth of a tree c
13d20 6f 6d 70 72 69 73 69 6e 67 20 6e 50 4d 41 20 50  omprising nPMA P
13d30 4d 41 73 2c 20 61 73 73 75 6d 69 6e 67 20 61 20  MAs, assuming a 
13d40 66 61 6e 6f 75 74 20 6f 66 0a 2a 2a 20 53 4f 52  fanout of.** SOR
13d50 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
13d60 55 4e 54 2e 20 54 68 65 20 72 65 74 75 72 6e 65  UNT. The returne
13d70 64 20 76 61 6c 75 65 20 64 6f 65 73 20 6e 6f 74  d value does not
13d80 20 69 6e 63 6c 75 64 65 20 6c 65 61 66 20 6e 6f   include leaf no
13d90 64 65 73 2e 0a 2a 2a 0a 2a 2a 20 69 2e 65 2e 0a  des..**.** i.e..
13da0 2a 2a 0a 2a 2a 20 20 20 6e 50 4d 41 3c 3d 31 36  **.**   nPMA<=16
13db0 20 20 20 20 2d 3e 20 54 72 65 65 44 65 70 74 68      -> TreeDepth
13dc0 28 29 20 3d 3d 20 30 0a 2a 2a 20 20 20 6e 50 4d  () == 0.**   nPM
13dd0 41 3c 3d 32 35 36 20 20 20 2d 3e 20 54 72 65 65  A<=256   -> Tree
13de0 44 65 70 74 68 28 29 20 3d 3d 20 31 0a 2a 2a 20  Depth() == 1.** 
13df0 20 20 6e 50 4d 41 3c 3d 36 35 35 33 36 20 2d 3e    nPMA<=65536 ->
13e00 20 54 72 65 65 44 65 70 74 68 28 29 20 3d 3d 20   TreeDepth() == 
13e10 32 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  2.*/.static int 
13e20 76 64 62 65 53 6f 72 74 65 72 54 72 65 65 44 65  vdbeSorterTreeDe
13e30 70 74 68 28 69 6e 74 20 6e 50 4d 41 29 7b 0a 20  pth(int nPMA){. 
13e40 20 69 6e 74 20 6e 44 65 70 74 68 20 3d 20 30 3b   int nDepth = 0;
13e50 0a 20 20 69 36 34 20 6e 44 69 76 20 3d 20 53 4f  .  i64 nDiv = SO
13e60 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
13e70 4f 55 4e 54 3b 0a 20 20 77 68 69 6c 65 28 20 6e  OUNT;.  while( n
13e80 44 69 76 20 3c 20 28 69 36 34 29 6e 50 4d 41 20  Div < (i64)nPMA 
13e90 29 7b 0a 20 20 20 20 6e 44 69 76 20 3d 20 6e 44  ){.    nDiv = nD
13ea0 69 76 20 2a 20 53 4f 52 54 45 52 5f 4d 41 58 5f  iv * SORTER_MAX_
13eb0 4d 45 52 47 45 5f 43 4f 55 4e 54 3b 0a 20 20 20  MERGE_COUNT;.   
13ec0 20 6e 44 65 70 74 68 2b 2b 3b 0a 20 20 7d 0a 20   nDepth++;.  }. 
13ed0 20 72 65 74 75 72 6e 20 6e 44 65 70 74 68 3b 0a   return nDepth;.
13ee0 7d 0a 0a 2f 2a 0a 2a 2a 20 70 52 6f 6f 74 20 69  }../*.** pRoot i
13ef0 73 20 74 68 65 20 72 6f 6f 74 20 6f 66 20 61 6e  s the root of an
13f00 20 69 6e 63 72 65 6d 65 6e 74 61 6c 20 6d 65 72   incremental mer
13f10 67 65 2d 74 72 65 65 20 77 69 74 68 20 64 65 70  ge-tree with dep
13f20 74 68 20 6e 44 65 70 74 68 20 28 61 63 63 6f 72  th nDepth (accor
13f30 64 69 6e 67 0a 2a 2a 20 74 6f 20 76 64 62 65 53  ding.** to vdbeS
13f40 6f 72 74 65 72 54 72 65 65 44 65 70 74 68 28 29  orterTreeDepth()
13f50 29 2e 20 70 4c 65 61 66 20 69 73 20 74 68 65 20  ). pLeaf is the 
13f60 69 53 65 71 27 74 68 20 6c 65 61 66 20 74 6f 20  iSeq'th leaf to 
13f70 62 65 20 61 64 64 65 64 20 74 6f 20 74 68 65 0a  be added to the.
13f80 2a 2a 20 74 72 65 65 2c 20 63 6f 75 6e 74 69 6e  ** tree, countin
13f90 67 20 66 72 6f 6d 20 7a 65 72 6f 2e 20 54 68 69  g from zero. Thi
13fa0 73 20 66 75 6e 63 74 69 6f 6e 20 61 64 64 73 20  s function adds 
13fb0 70 4c 65 61 66 20 74 6f 20 74 68 65 20 74 72 65  pLeaf to the tre
13fc0 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63  e..**.** If succ
13fd0 65 73 73 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f  essful, SQLITE_O
13fe0 4b 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 49  K is returned. I
13ff0 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
14000 73 2c 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  s, an SQLite err
14010 6f 72 0a 2a 2a 20 63 6f 64 65 20 69 73 20 72 65  or.** code is re
14020 74 75 72 6e 65 64 20 61 6e 64 20 70 4c 65 61 66  turned and pLeaf
14030 20 69 73 20 66 72 65 65 64 2e 0a 2a 2f 0a 73 74   is freed..*/.st
14040 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
14050 74 65 72 41 64 64 54 6f 54 72 65 65 28 0a 20 20  terAddToTree(.  
14060 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61  SortSubtask *pTa
14070 73 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  sk,             
14080 2f 2a 20 54 61 73 6b 20 63 6f 6e 74 65 78 74 20  /* Task context 
14090 2a 2f 0a 20 20 69 6e 74 20 6e 44 65 70 74 68 2c  */.  int nDepth,
140a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
140b0 20 20 20 20 20 2f 2a 20 44 65 70 74 68 20 6f 66       /* Depth of
140c0 20 74 72 65 65 20 61 63 63 6f 72 64 69 6e 67 20   tree according 
140d0 74 6f 20 54 72 65 65 44 65 70 74 68 28 29 20 2a  to TreeDepth() *
140e0 2f 0a 20 20 69 6e 74 20 69 53 65 71 2c 20 20 20  /.  int iSeq,   
140f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14100 20 20 20 20 2f 2a 20 53 65 71 75 65 6e 63 65 20      /* Sequence 
14110 6e 75 6d 62 65 72 20 6f 66 20 6c 65 61 66 20 77  number of leaf w
14120 69 74 68 69 6e 20 74 72 65 65 20 2a 2f 0a 20 20  ithin tree */.  
14130 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 52 6f  MergeEngine *pRo
14140 6f 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ot,             
14150 2f 2a 20 52 6f 6f 74 20 6f 66 20 74 72 65 65 20  /* Root of tree 
14160 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65  */.  MergeEngine
14170 20 2a 70 4c 65 61 66 20 20 20 20 20 20 20 20 20   *pLeaf         
14180 20 20 20 20 20 2f 2a 20 4c 65 61 66 20 74 6f 20       /* Leaf to 
14190 61 64 64 20 74 6f 20 74 72 65 65 20 2a 2f 0a 29  add to tree */.)
141a0 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
141b0 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 44  ITE_OK;.  int nD
141c0 69 76 20 3d 20 31 3b 0a 20 20 69 6e 74 20 69 3b  iv = 1;.  int i;
141d0 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a  .  MergeEngine *
141e0 70 20 3d 20 70 52 6f 6f 74 3b 0a 20 20 49 6e 63  p = pRoot;.  Inc
141f0 72 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 3b 0a  rMerger *pIncr;.
14200 0a 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72  .  rc = vdbeIncr
14210 4d 65 72 67 65 72 4e 65 77 28 70 54 61 73 6b 2c  MergerNew(pTask,
14220 20 70 4c 65 61 66 2c 20 26 70 49 6e 63 72 29 3b   pLeaf, &pIncr);
14230 0a 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 6e  ..  for(i=1; i<n
14240 44 65 70 74 68 3b 20 69 2b 2b 29 7b 0a 20 20 20  Depth; i++){.   
14250 20 6e 44 69 76 20 3d 20 6e 44 69 76 20 2a 20 53   nDiv = nDiv * S
14260 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f  ORTER_MAX_MERGE_
14270 43 4f 55 4e 54 3b 0a 20 20 7d 0a 0a 20 20 66 6f  COUNT;.  }..  fo
14280 72 28 69 3d 31 3b 20 69 3c 6e 44 65 70 74 68 20  r(i=1; i<nDepth 
14290 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  && rc==SQLITE_OK
142a0 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 20  ; i++){.    int 
142b0 69 49 74 65 72 20 3d 20 28 69 53 65 71 20 2f 20  iIter = (iSeq / 
142c0 6e 44 69 76 29 20 25 20 53 4f 52 54 45 52 5f 4d  nDiv) % SORTER_M
142d0 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3b 0a  AX_MERGE_COUNT;.
142e0 20 20 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70      PmaReader *p
142f0 52 65 61 64 72 20 3d 20 26 70 2d 3e 61 52 65 61  Readr = &p->aRea
14300 64 72 5b 69 49 74 65 72 5d 3b 0a 0a 20 20 20 20  dr[iIter];..    
14310 69 66 28 20 70 52 65 61 64 72 2d 3e 70 49 6e 63  if( pReadr->pInc
14320 72 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 4d 65  r==0 ){.      Me
14330 72 67 65 45 6e 67 69 6e 65 20 2a 70 4e 65 77 20  rgeEngine *pNew 
14340 3d 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e  = vdbeMergeEngin
14350 65 4e 65 77 28 53 4f 52 54 45 52 5f 4d 41 58 5f  eNew(SORTER_MAX_
14360 4d 45 52 47 45 5f 43 4f 55 4e 54 29 3b 0a 20 20  MERGE_COUNT);.  
14370 20 20 20 20 69 66 28 20 70 4e 65 77 3d 3d 30 20      if( pNew==0 
14380 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  ){.        rc = 
14390 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
143a0 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
143b0 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72     rc = vdbeIncr
143c0 4d 65 72 67 65 72 4e 65 77 28 70 54 61 73 6b 2c  MergerNew(pTask,
143d0 20 70 4e 65 77 2c 20 26 70 52 65 61 64 72 2d 3e   pNew, &pReadr->
143e0 70 49 6e 63 72 29 3b 0a 20 20 20 20 20 20 7d 0a  pIncr);.      }.
143f0 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63      }.    if( rc
14400 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
14410 20 20 20 20 20 70 20 3d 20 70 52 65 61 64 72 2d       p = pReadr-
14420 3e 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65 72 3b  >pIncr->pMerger;
14430 0a 20 20 20 20 20 20 6e 44 69 76 20 3d 20 6e 44  .      nDiv = nD
14440 69 76 20 2f 20 53 4f 52 54 45 52 5f 4d 41 58 5f  iv / SORTER_MAX_
14450 4d 45 52 47 45 5f 43 4f 55 4e 54 3b 0a 20 20 20  MERGE_COUNT;.   
14460 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63   }.  }..  if( rc
14470 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
14480 20 20 20 70 2d 3e 61 52 65 61 64 72 5b 69 53 65     p->aReadr[iSe
14490 71 20 25 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  q % SORTER_MAX_M
144a0 45 52 47 45 5f 43 4f 55 4e 54 5d 2e 70 49 6e 63  ERGE_COUNT].pInc
144b0 72 20 3d 20 70 49 6e 63 72 3b 0a 20 20 7d 65 6c  r = pIncr;.  }el
144c0 73 65 7b 0a 20 20 20 20 76 64 62 65 49 6e 63 72  se{.    vdbeIncr
144d0 46 72 65 65 28 70 49 6e 63 72 29 3b 0a 20 20 7d  Free(pIncr);.  }
144e0 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
144f0 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
14500 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 61  tion is called a
14510 73 20 70 61 72 74 20 6f 66 20 61 20 53 6f 72 74  s part of a Sort
14520 65 72 52 65 77 69 6e 64 28 29 20 6f 70 65 72 61  erRewind() opera
14530 74 69 6f 6e 20 6f 6e 20 61 20 73 6f 72 74 65 72  tion on a sorter
14540 0a 2a 2a 20 74 68 61 74 20 68 61 73 20 61 6c 72  .** that has alr
14550 65 61 64 79 20 77 72 69 74 74 65 6e 20 74 77 6f  eady written two
14560 20 6f 72 20 6d 6f 72 65 20 6c 65 76 65 6c 2d 30   or more level-0
14570 20 50 4d 41 73 20 74 6f 20 6f 6e 65 20 6f 72 20   PMAs to one or 
14580 6d 6f 72 65 20 74 65 6d 70 0a 2a 2a 20 66 69 6c  more temp.** fil
14590 65 73 2e 20 49 74 20 62 75 69 6c 64 73 20 61 20  es. It builds a 
145a0 74 72 65 65 20 6f 66 20 4d 65 72 67 65 45 6e 67  tree of MergeEng
145b0 69 6e 65 2f 49 6e 63 72 4d 65 72 67 65 72 2f 50  ine/IncrMerger/P
145c0 6d 61 52 65 61 64 65 72 20 6f 62 6a 65 63 74 73  maReader objects
145d0 20 74 68 61 74 20 0a 2a 2a 20 63 61 6e 20 62 65   that .** can be
145e0 20 75 73 65 64 20 74 6f 20 69 6e 63 72 65 6d 65   used to increme
145f0 6e 74 61 6c 6c 79 20 6d 65 72 67 65 20 61 6c 6c  ntally merge all
14600 20 50 4d 41 73 20 6f 6e 20 64 69 73 6b 2e 0a 2a   PMAs on disk..*
14610 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66  *.** If successf
14620 75 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73  ul, SQLITE_OK is
14630 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 2a 70   returned and *p
14640 70 4f 75 74 20 73 65 74 20 74 6f 20 70 6f 69 6e  pOut set to poin
14650 74 20 74 6f 20 74 68 65 0a 2a 2a 20 4d 65 72 67  t to the.** Merg
14660 65 45 6e 67 69 6e 65 20 6f 62 6a 65 63 74 20 61  eEngine object a
14670 74 20 74 68 65 20 72 6f 6f 74 20 6f 66 20 74 68  t the root of th
14680 65 20 74 72 65 65 20 62 65 66 6f 72 65 20 72 65  e tree before re
14690 74 75 72 6e 69 6e 67 2e 20 4f 72 2c 20 69 66 20  turning. Or, if 
146a0 61 6e 0a 2a 2a 20 65 72 72 6f 72 20 6f 63 63 75  an.** error occu
146b0 72 73 2c 20 61 6e 20 53 51 4c 69 74 65 20 65 72  rs, an SQLite er
146c0 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74 75  ror code is retu
146d0 72 6e 65 64 20 61 6e 64 20 74 68 65 20 66 69 6e  rned and the fin
146e0 61 6c 20 76 61 6c 75 65 20 0a 2a 2a 20 6f 66 20  al value .** of 
146f0 2a 70 70 4f 75 74 20 69 73 20 75 6e 64 65 66 69  *ppOut is undefi
14700 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ned..*/.static i
14710 6e 74 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72  nt vdbeSorterMer
14720 67 65 54 72 65 65 42 75 69 6c 64 28 0a 20 20 56  geTreeBuild(.  V
14730 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
14740 65 72 2c 20 20 20 20 20 20 20 2f 2a 20 54 68 65  er,       /* The
14750 20 56 44 42 45 20 63 75 72 73 6f 72 20 74 68 61   VDBE cursor tha
14760 74 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68 65  t implements the
14770 20 73 6f 72 74 20 2a 2f 0a 20 20 4d 65 72 67 65   sort */.  Merge
14780 45 6e 67 69 6e 65 20 2a 2a 70 70 4f 75 74 20 20  Engine **ppOut  
14790 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74        /* Write t
147a0 68 65 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 68  he MergeEngine h
147b0 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 4d 65 72 67  ere */.){.  Merg
147c0 65 45 6e 67 69 6e 65 20 2a 70 4d 61 69 6e 20 3d  eEngine *pMain =
147d0 20 30 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53   0;.  int rc = S
147e0 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20  QLITE_OK;.  int 
147f0 69 54 61 73 6b 3b 0a 0a 23 69 66 20 53 51 4c 49  iTask;..#if SQLI
14800 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48  TE_MAX_WORKER_TH
14810 52 45 41 44 53 3e 30 0a 20 20 2f 2a 20 49 66 20  READS>0.  /* If 
14820 74 68 65 20 73 6f 72 74 65 72 20 75 73 65 73 20  the sorter uses 
14830 6d 6f 72 65 20 74 68 61 6e 20 6f 6e 65 20 74 61  more than one ta
14840 73 6b 2c 20 74 68 65 6e 20 63 72 65 61 74 65 20  sk, then create 
14850 74 68 65 20 74 6f 70 2d 6c 65 76 65 6c 20 0a 20  the top-level . 
14860 20 2a 2a 20 4d 65 72 67 65 45 6e 67 69 6e 65 20   ** MergeEngine 
14870 68 65 72 65 2e 20 54 68 69 73 20 4d 65 72 67 65  here. This Merge
14880 45 6e 67 69 6e 65 20 77 69 6c 6c 20 72 65 61 64  Engine will read
14890 20 64 61 74 61 20 66 72 6f 6d 20 65 78 61 63 74   data from exact
148a0 6c 79 20 0a 20 20 2a 2a 20 6f 6e 65 20 50 6d 61  ly .  ** one Pma
148b0 52 65 61 64 65 72 20 70 65 72 20 73 75 62 2d 74  Reader per sub-t
148c0 61 73 6b 2e 20 20 2a 2f 0a 20 20 61 73 73 65 72  ask.  */.  asser
148d0 74 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65  t( pSorter->bUse
148e0 54 68 72 65 61 64 73 20 7c 7c 20 70 53 6f 72 74  Threads || pSort
148f0 65 72 2d 3e 6e 54 61 73 6b 3d 3d 31 20 29 3b 0a  er->nTask==1 );.
14900 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6e    if( pSorter->n
14910 54 61 73 6b 3e 31 20 29 7b 0a 20 20 20 20 70 4d  Task>1 ){.    pM
14920 61 69 6e 20 3d 20 76 64 62 65 4d 65 72 67 65 45  ain = vdbeMergeE
14930 6e 67 69 6e 65 4e 65 77 28 70 53 6f 72 74 65 72  ngineNew(pSorter
14940 2d 3e 6e 54 61 73 6b 29 3b 0a 20 20 20 20 69 66  ->nTask);.    if
14950 28 20 70 4d 61 69 6e 3d 3d 30 20 29 20 72 63 20  ( pMain==0 ) rc 
14960 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
14970 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 66 6f    }.#endif..  fo
14980 72 28 69 54 61 73 6b 3d 30 3b 20 72 63 3d 3d 53  r(iTask=0; rc==S
14990 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 54 61 73  QLITE_OK && iTas
149a0 6b 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b  k<pSorter->nTask
149b0 3b 20 69 54 61 73 6b 2b 2b 29 7b 0a 20 20 20 20  ; iTask++){.    
149c0 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61  SortSubtask *pTa
149d0 73 6b 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61  sk = &pSorter->a
149e0 54 61 73 6b 5b 69 54 61 73 6b 5d 3b 0a 20 20 20  Task[iTask];.   
149f0 20 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e   assert( pTask->
14a00 6e 50 4d 41 3e 30 20 7c 7c 20 53 51 4c 49 54 45  nPMA>0 || SQLITE
14a10 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45  _MAX_WORKER_THRE
14a20 41 44 53 3e 30 20 29 3b 0a 20 20 20 20 69 66 28  ADS>0 );.    if(
14a30 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b   SQLITE_MAX_WORK
14a40 45 52 5f 54 48 52 45 41 44 53 3d 3d 30 20 7c 7c  ER_THREADS==0 ||
14a50 20 70 54 61 73 6b 2d 3e 6e 50 4d 41 20 29 7b 0a   pTask->nPMA ){.
14a60 20 20 20 20 20 20 4d 65 72 67 65 45 6e 67 69 6e        MergeEngin
14a70 65 20 2a 70 52 6f 6f 74 20 3d 20 30 3b 20 20 20  e *pRoot = 0;   
14a80 20 20 2f 2a 20 52 6f 6f 74 20 6e 6f 64 65 20 6f    /* Root node o
14a90 66 20 74 72 65 65 20 66 6f 72 20 74 68 69 73 20  f tree for this 
14aa0 74 61 73 6b 20 2a 2f 0a 20 20 20 20 20 20 69 6e  task */.      in
14ab0 74 20 6e 44 65 70 74 68 20 3d 20 76 64 62 65 53  t nDepth = vdbeS
14ac0 6f 72 74 65 72 54 72 65 65 44 65 70 74 68 28 70  orterTreeDepth(p
14ad0 54 61 73 6b 2d 3e 6e 50 4d 41 29 3b 0a 20 20 20  Task->nPMA);.   
14ae0 20 20 20 69 36 34 20 69 52 65 61 64 4f 66 66 20     i64 iReadOff 
14af0 3d 20 30 3b 0a 0a 20 20 20 20 20 20 69 66 28 20  = 0;..      if( 
14b00 70 54 61 73 6b 2d 3e 6e 50 4d 41 3c 3d 53 4f 52  pTask->nPMA<=SOR
14b10 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
14b20 55 4e 54 20 29 7b 0a 20 20 20 20 20 20 20 20 72  UNT ){.        r
14b30 63 20 3d 20 76 64 62 65 4d 65 72 67 65 45 6e 67  c = vdbeMergeEng
14b40 69 6e 65 4c 65 76 65 6c 30 28 70 54 61 73 6b 2c  ineLevel0(pTask,
14b50 20 70 54 61 73 6b 2d 3e 6e 50 4d 41 2c 20 26 69   pTask->nPMA, &i
14b60 52 65 61 64 4f 66 66 2c 20 26 70 52 6f 6f 74 29  ReadOff, &pRoot)
14b70 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
14b80 20 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20         int i;.  
14b90 20 20 20 20 20 20 69 6e 74 20 69 53 65 71 20 3d        int iSeq =
14ba0 20 30 3b 0a 20 20 20 20 20 20 20 20 70 52 6f 6f   0;.        pRoo
14bb0 74 20 3d 20 76 64 62 65 4d 65 72 67 65 45 6e 67  t = vdbeMergeEng
14bc0 69 6e 65 4e 65 77 28 53 4f 52 54 45 52 5f 4d 41  ineNew(SORTER_MA
14bd0 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 29 3b 0a  X_MERGE_COUNT);.
14be0 20 20 20 20 20 20 20 20 69 66 28 20 70 52 6f 6f          if( pRoo
14bf0 74 3d 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49  t==0 ) rc = SQLI
14c00 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20  TE_NOMEM;.      
14c10 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61    for(i=0; i<pTa
14c20 73 6b 2d 3e 6e 50 4d 41 20 26 26 20 72 63 3d 3d  sk->nPMA && rc==
14c30 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 20 2b 3d 20  SQLITE_OK; i += 
14c40 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45  SORTER_MAX_MERGE
14c50 5f 43 4f 55 4e 54 29 7b 0a 20 20 20 20 20 20 20  _COUNT){.       
14c60 20 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a     MergeEngine *
14c70 70 4d 65 72 67 65 72 20 3d 20 30 3b 20 2f 2a 20  pMerger = 0; /* 
14c80 4e 65 77 20 6c 65 76 65 6c 2d 30 20 50 4d 41 20  New level-0 PMA 
14c90 6d 65 72 67 65 72 20 2a 2f 0a 20 20 20 20 20 20  merger */.      
14ca0 20 20 20 20 69 6e 74 20 6e 52 65 61 64 65 72 3b      int nReader;
14cb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
14cc0 20 4e 75 6d 62 65 72 20 6f 66 20 6c 65 76 65 6c   Number of level
14cd0 2d 30 20 50 4d 41 73 20 74 6f 20 6d 65 72 67 65  -0 PMAs to merge
14ce0 20 2a 2f 0a 0a 20 20 20 20 20 20 20 20 20 20 6e   */..          n
14cf0 52 65 61 64 65 72 20 3d 20 4d 49 4e 28 70 54 61  Reader = MIN(pTa
14d00 73 6b 2d 3e 6e 50 4d 41 20 2d 20 69 2c 20 53 4f  sk->nPMA - i, SO
14d10 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
14d20 4f 55 4e 54 29 3b 0a 20 20 20 20 20 20 20 20 20  OUNT);.         
14d30 20 72 63 20 3d 20 76 64 62 65 4d 65 72 67 65 45   rc = vdbeMergeE
14d40 6e 67 69 6e 65 4c 65 76 65 6c 30 28 70 54 61 73  ngineLevel0(pTas
14d50 6b 2c 20 6e 52 65 61 64 65 72 2c 20 26 69 52 65  k, nReader, &iRe
14d60 61 64 4f 66 66 2c 20 26 70 4d 65 72 67 65 72 29  adOff, &pMerger)
14d70 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
14d80 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
14d90 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 63 20  .            rc 
14da0 3d 20 76 64 62 65 53 6f 72 74 65 72 41 64 64 54  = vdbeSorterAddT
14db0 6f 54 72 65 65 28 70 54 61 73 6b 2c 20 6e 44 65  oTree(pTask, nDe
14dc0 70 74 68 2c 20 69 53 65 71 2b 2b 2c 20 70 52 6f  pth, iSeq++, pRo
14dd0 6f 74 2c 20 70 4d 65 72 67 65 72 29 3b 0a 20 20  ot, pMerger);.  
14de0 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
14df0 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20    }.      }..   
14e00 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
14e10 45 5f 4f 4b 20 29 7b 0a 23 69 66 20 53 51 4c 49  E_OK ){.#if SQLI
14e20 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48  TE_MAX_WORKER_TH
14e30 52 45 41 44 53 3e 30 0a 20 20 20 20 20 20 20 20  READS>0.        
14e40 69 66 28 20 70 4d 61 69 6e 21 3d 30 20 29 7b 0a  if( pMain!=0 ){.
14e50 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 76            rc = v
14e60 64 62 65 49 6e 63 72 4d 65 72 67 65 72 4e 65 77  dbeIncrMergerNew
14e70 28 70 54 61 73 6b 2c 20 70 52 6f 6f 74 2c 20 26  (pTask, pRoot, &
14e80 70 4d 61 69 6e 2d 3e 61 52 65 61 64 72 5b 69 54  pMain->aReadr[iT
14e90 61 73 6b 5d 2e 70 49 6e 63 72 29 3b 0a 20 20 20  ask].pIncr);.   
14ea0 20 20 20 20 20 7d 65 6c 73 65 0a 23 65 6e 64 69       }else.#endi
14eb0 66 0a 20 20 20 20 20 20 20 20 7b 0a 20 20 20 20  f.        {.    
14ec0 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 4d        assert( pM
14ed0 61 69 6e 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20  ain==0 );.      
14ee0 20 20 20 20 70 4d 61 69 6e 20 3d 20 70 52 6f 6f      pMain = pRoo
14ef0 74 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  t;.        }.   
14f00 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
14f10 20 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e    vdbeMergeEngin
14f20 65 46 72 65 65 28 70 52 6f 6f 74 29 3b 0a 20 20  eFree(pRoot);.  
14f30 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
14f40 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
14f50 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 64 62 65  E_OK ){.    vdbe
14f60 4d 65 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28  MergeEngineFree(
14f70 70 4d 61 69 6e 29 3b 0a 20 20 20 20 70 4d 61 69  pMain);.    pMai
14f80 6e 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 2a 70 70  n = 0;.  }.  *pp
14f90 4f 75 74 20 3d 20 70 4d 61 69 6e 3b 0a 20 20 72  Out = pMain;.  r
14fa0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
14fb0 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
14fc0 20 69 73 20 63 61 6c 6c 65 64 20 61 73 20 70 61   is called as pa
14fd0 72 74 20 6f 66 20 61 6e 20 73 71 6c 69 74 65 33  rt of an sqlite3
14fe0 56 64 62 65 53 6f 72 74 65 72 52 65 77 69 6e 64  VdbeSorterRewind
14ff0 28 29 20 6f 70 65 72 61 74 69 6f 6e 0a 2a 2a 20  () operation.** 
15000 6f 6e 20 61 20 73 6f 72 74 65 72 20 74 68 61 74  on a sorter that
15010 20 68 61 73 20 77 72 69 74 74 65 6e 20 74 77 6f   has written two
15020 20 6f 72 20 6d 6f 72 65 20 50 4d 41 73 20 74 6f   or more PMAs to
15030 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 73   temporary files
15040 2e 20 49 74 20 73 65 74 73 0a 2a 2a 20 75 70 20  . It sets.** up 
15050 65 69 74 68 65 72 20 56 64 62 65 53 6f 72 74 65  either VdbeSorte
15060 72 2e 70 4d 65 72 67 65 72 20 28 66 6f 72 20 73  r.pMerger (for s
15070 69 6e 67 6c 65 20 74 68 72 65 61 64 65 64 20 73  ingle threaded s
15080 6f 72 74 65 72 73 29 20 6f 72 20 70 52 65 61 64  orters) or pRead
15090 65 72 0a 2a 2a 20 28 66 6f 72 20 6d 75 6c 74 69  er.** (for multi
150a0 2d 74 68 72 65 61 64 65 64 20 73 6f 72 74 65 72  -threaded sorter
150b0 73 29 20 73 6f 20 74 68 61 74 20 69 74 20 63 61  s) so that it ca
150c0 6e 20 62 65 20 75 73 65 64 20 74 6f 20 69 74 65  n be used to ite
150d0 72 61 74 65 20 74 68 72 6f 75 67 68 0a 2a 2a 20  rate through.** 
150e0 61 6c 6c 20 72 65 63 6f 72 64 73 20 73 74 6f 72  all records stor
150f0 65 64 20 69 6e 20 74 68 65 20 73 6f 72 74 65 72  ed in the sorter
15100 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f  ..**.** SQLITE_O
15110 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 69 66  K is returned if
15120 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20   successful, or 
15130 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
15140 63 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a  code otherwise..
15150 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
15160 62 65 53 6f 72 74 65 72 53 65 74 75 70 4d 65 72  beSorterSetupMer
15170 67 65 28 56 64 62 65 53 6f 72 74 65 72 20 2a 70  ge(VdbeSorter *p
15180 53 6f 72 74 65 72 29 7b 0a 20 20 69 6e 74 20 72  Sorter){.  int r
15190 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
151a0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
151b0 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 53  turn code */.  S
151c0 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
151d0 6b 30 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61  k0 = &pSorter->a
151e0 54 61 73 6b 5b 30 5d 3b 0a 20 20 4d 65 72 67 65  Task[0];.  Merge
151f0 45 6e 67 69 6e 65 20 2a 70 4d 61 69 6e 20 3d 20  Engine *pMain = 
15200 30 3b 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41  0;.#if SQLITE_MA
15210 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53  X_WORKER_THREADS
15220 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20 3d  .  sqlite3 *db =
15230 20 70 54 61 73 6b 30 2d 3e 70 53 6f 72 74 65 72   pTask0->pSorter
15240 2d 3e 64 62 3b 0a 20 20 69 6e 74 20 69 3b 0a 20  ->db;.  int i;. 
15250 20 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 20 78   SorterCompare x
15260 43 6f 6d 70 61 72 65 20 3d 20 76 64 62 65 53 6f  Compare = vdbeSo
15270 72 74 65 72 47 65 74 43 6f 6d 70 61 72 65 28 70  rterGetCompare(p
15280 53 6f 72 74 65 72 29 3b 0a 20 20 66 6f 72 28 69  Sorter);.  for(i
15290 3d 30 3b 20 69 3c 70 53 6f 72 74 65 72 2d 3e 6e  =0; i<pSorter->n
152a0 54 61 73 6b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  Task; i++){.    
152b0 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 69  pSorter->aTask[i
152c0 5d 2e 78 43 6f 6d 70 61 72 65 20 3d 20 78 43 6f  ].xCompare = xCo
152d0 6d 70 61 72 65 3b 0a 20 20 7d 0a 23 65 6e 64 69  mpare;.  }.#endi
152e0 66 0a 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f  f..  rc = vdbeSo
152f0 72 74 65 72 4d 65 72 67 65 54 72 65 65 42 75 69  rterMergeTreeBui
15300 6c 64 28 70 53 6f 72 74 65 72 2c 20 26 70 4d 61  ld(pSorter, &pMa
15310 69 6e 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  in);.  if( rc==S
15320 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 23 69 66 20  QLITE_OK ){.#if 
15330 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45  SQLITE_MAX_WORKE
15340 52 5f 54 48 52 45 41 44 53 0a 20 20 20 20 61 73  R_THREADS.    as
15350 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 62  sert( pSorter->b
15360 55 73 65 54 68 72 65 61 64 73 3d 3d 30 20 7c 7c  UseThreads==0 ||
15370 20 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3e   pSorter->nTask>
15380 31 20 29 3b 0a 20 20 20 20 69 66 28 20 70 53 6f  1 );.    if( pSo
15390 72 74 65 72 2d 3e 62 55 73 65 54 68 72 65 61 64  rter->bUseThread
153a0 73 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69  s ){.      int i
153b0 54 61 73 6b 3b 0a 20 20 20 20 20 20 50 6d 61 52  Task;.      PmaR
153c0 65 61 64 65 72 20 2a 70 52 65 61 64 72 20 3d 20  eader *pReadr = 
153d0 30 3b 0a 20 20 20 20 20 20 53 6f 72 74 53 75 62  0;.      SortSub
153e0 74 61 73 6b 20 2a 70 4c 61 73 74 20 3d 20 26 70  task *pLast = &p
153f0 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 70 53  Sorter->aTask[pS
15400 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 5d 3b  orter->nTask-1];
15410 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65  .      rc = vdbe
15420 53 6f 72 74 41 6c 6c 6f 63 55 6e 70 61 63 6b 65  SortAllocUnpacke
15430 64 28 70 4c 61 73 74 29 3b 0a 20 20 20 20 20 20  d(pLast);.      
15440 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
15450 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 70 52 65  K ){.        pRe
15460 61 64 72 20 3d 20 28 50 6d 61 52 65 61 64 65 72  adr = (PmaReader
15470 2a 29 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f  *)sqlite3DbMallo
15480 63 5a 65 72 6f 28 64 62 2c 20 73 69 7a 65 6f 66  cZero(db, sizeof
15490 28 50 6d 61 52 65 61 64 65 72 29 29 3b 0a 20 20  (PmaReader));.  
154a0 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70        pSorter->p
154b0 52 65 61 64 65 72 20 3d 20 70 52 65 61 64 72 3b  Reader = pReadr;
154c0 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 52 65  .        if( pRe
154d0 61 64 72 3d 3d 30 20 29 20 72 63 20 3d 20 53 51  adr==0 ) rc = SQ
154e0 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
154f0 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63    }.      if( rc
15500 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
15510 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65         rc = vdbe
15520 49 6e 63 72 4d 65 72 67 65 72 4e 65 77 28 70 4c  IncrMergerNew(pL
15530 61 73 74 2c 20 70 4d 61 69 6e 2c 20 26 70 52 65  ast, pMain, &pRe
15540 61 64 72 2d 3e 70 49 6e 63 72 29 3b 0a 20 20 20  adr->pIncr);.   
15550 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
15560 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
15570 20 20 20 20 76 64 62 65 49 6e 63 72 4d 65 72 67      vdbeIncrMerg
15580 65 72 53 65 74 54 68 72 65 61 64 73 28 70 52 65  erSetThreads(pRe
15590 61 64 72 2d 3e 70 49 6e 63 72 29 3b 0a 20 20 20  adr->pIncr);.   
155a0 20 20 20 20 20 20 20 66 6f 72 28 69 54 61 73 6b         for(iTask
155b0 3d 30 3b 20 69 54 61 73 6b 3c 28 70 53 6f 72 74  =0; iTask<(pSort
155c0 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 3b 20 69 54  er->nTask-1); iT
155d0 61 73 6b 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ask++){.        
155e0 20 20 20 20 49 6e 63 72 4d 65 72 67 65 72 20 2a      IncrMerger *
155f0 70 49 6e 63 72 3b 0a 20 20 20 20 20 20 20 20 20  pIncr;.         
15600 20 20 20 69 66 28 20 28 70 49 6e 63 72 20 3d 20     if( (pIncr = 
15610 70 4d 61 69 6e 2d 3e 61 52 65 61 64 72 5b 69 54  pMain->aReadr[iT
15620 61 73 6b 5d 2e 70 49 6e 63 72 29 20 29 7b 0a 20  ask].pIncr) ){. 
15630 20 20 20 20 20 20 20 20 20 20 20 20 20 76 64 62               vdb
15640 65 49 6e 63 72 4d 65 72 67 65 72 53 65 74 54 68  eIncrMergerSetTh
15650 72 65 61 64 73 28 70 49 6e 63 72 29 3b 0a 20 20  reads(pIncr);.  
15660 20 20 20 20 20 20 20 20 20 20 20 20 61 73 73 65              asse
15670 72 74 28 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b  rt( pIncr->pTask
15680 21 3d 70 4c 61 73 74 20 29 3b 0a 20 20 20 20 20  !=pLast );.     
15690 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
156a0 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 66     }.          f
156b0 6f 72 28 69 54 61 73 6b 3d 30 3b 20 72 63 3d 3d  or(iTask=0; rc==
156c0 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 54 61  SQLITE_OK && iTa
156d0 73 6b 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73  sk<pSorter->nTas
156e0 6b 3b 20 69 54 61 73 6b 2b 2b 29 7b 0a 20 20 20  k; iTask++){.   
156f0 20 20 20 20 20 20 20 20 20 50 6d 61 52 65 61 64           PmaRead
15700 65 72 20 2a 70 20 3d 20 26 70 4d 61 69 6e 2d 3e  er *p = &pMain->
15710 61 52 65 61 64 72 5b 69 54 61 73 6b 5d 3b 0a 20  aReadr[iTask];. 
15720 20 20 20 20 20 20 20 20 20 20 20 61 73 73 65 72             asser
15730 74 28 20 70 2d 3e 70 49 6e 63 72 3d 3d 30 20 7c  t( p->pIncr==0 |
15740 7c 20 70 2d 3e 70 49 6e 63 72 2d 3e 70 54 61 73  | p->pIncr->pTas
15750 6b 3d 3d 26 70 53 6f 72 74 65 72 2d 3e 61 54 61  k==&pSorter->aTa
15760 73 6b 5b 69 54 61 73 6b 5d 20 29 3b 0a 20 20 20  sk[iTask] );.   
15770 20 20 20 20 20 20 20 20 20 69 66 28 20 70 2d 3e           if( p->
15780 70 49 6e 63 72 20 29 7b 20 0a 20 20 20 20 20 20  pIncr ){ .      
15790 20 20 20 20 20 20 20 20 69 66 28 20 69 54 61 73          if( iTas
157a0 6b 3d 3d 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73  k==pSorter->nTas
157b0 6b 2d 31 20 29 7b 0a 20 20 20 20 20 20 20 20 20  k-1 ){.         
157c0 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65         rc = vdbe
157d0 50 6d 61 52 65 61 64 65 72 49 6e 63 72 4d 65 72  PmaReaderIncrMer
157e0 67 65 49 6e 69 74 28 70 2c 20 49 4e 43 52 49 4e  geInit(p, INCRIN
157f0 49 54 5f 54 41 53 4b 29 3b 0a 20 20 20 20 20 20  IT_TASK);.      
15800 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
15810 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72                 r
15820 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65  c = vdbePmaReade
15830 72 42 67 49 6e 63 72 49 6e 69 74 28 70 29 3b 0a  rBgIncrInit(p);.
15840 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a                }.
15850 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20              }.  
15860 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
15870 20 20 7d 0a 20 20 20 20 20 20 20 20 70 4d 61 69    }.        pMai
15880 6e 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20  n = 0;.      }. 
15890 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
158a0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
158b0 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65    rc = vdbePmaRe
158c0 61 64 65 72 49 6e 63 72 4d 65 72 67 65 49 6e 69  aderIncrMergeIni
158d0 74 28 70 52 65 61 64 72 2c 20 49 4e 43 52 49 4e  t(pReadr, INCRIN
158e0 49 54 5f 52 4f 4f 54 29 3b 0a 20 20 20 20 20 20  IT_ROOT);.      
158f0 7d 0a 20 20 20 20 7d 65 6c 73 65 0a 23 65 6e 64  }.    }else.#end
15900 69 66 0a 20 20 20 20 7b 0a 20 20 20 20 20 20 72  if.    {.      r
15910 63 20 3d 20 76 64 62 65 4d 65 72 67 65 45 6e 67  c = vdbeMergeEng
15920 69 6e 65 49 6e 69 74 28 70 54 61 73 6b 30 2c 20  ineInit(pTask0, 
15930 70 4d 61 69 6e 2c 20 49 4e 43 52 49 4e 49 54 5f  pMain, INCRINIT_
15940 4e 4f 52 4d 41 4c 29 3b 0a 20 20 20 20 20 20 70  NORMAL);.      p
15950 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 20  Sorter->pMerger 
15960 3d 20 70 4d 61 69 6e 3b 0a 20 20 20 20 20 20 70  = pMain;.      p
15970 4d 61 69 6e 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  Main = 0;.    }.
15980 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53    }..  if( rc!=S
15990 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
159a0 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46  vdbeMergeEngineF
159b0 72 65 65 28 70 4d 61 69 6e 29 3b 0a 20 20 7d 0a  ree(pMain);.  }.
159c0 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
159d0 0a 2f 2a 0a 2a 2a 20 4f 6e 63 65 20 74 68 65 20  ./*.** Once the 
159e0 73 6f 72 74 65 72 20 68 61 73 20 62 65 65 6e 20  sorter has been 
159f0 70 6f 70 75 6c 61 74 65 64 20 62 79 20 63 61 6c  populated by cal
15a00 6c 73 20 74 6f 20 73 71 6c 69 74 65 33 56 64 62  ls to sqlite3Vdb
15a10 65 53 6f 72 74 65 72 57 72 69 74 65 2c 0a 2a 2a  eSorterWrite,.**
15a20 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
15a30 73 20 63 61 6c 6c 65 64 20 74 6f 20 70 72 65 70  s called to prep
15a40 61 72 65 20 66 6f 72 20 69 74 65 72 61 74 69 6e  are for iteratin
15a50 67 20 74 68 72 6f 75 67 68 20 74 68 65 20 72 65  g through the re
15a60 63 6f 72 64 73 0a 2a 2a 20 69 6e 20 73 6f 72 74  cords.** in sort
15a70 65 64 20 6f 72 64 65 72 2e 0a 2a 2f 0a 69 6e 74  ed order..*/.int
15a80 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74   sqlite3VdbeSort
15a90 65 72 52 65 77 69 6e 64 28 63 6f 6e 73 74 20 56  erRewind(const V
15aa0 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c  dbeCursor *pCsr,
15ab0 20 69 6e 74 20 2a 70 62 45 6f 66 29 7b 0a 20 20   int *pbEof){.  
15ac0 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72  VdbeSorter *pSor
15ad0 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72  ter = pCsr->pSor
15ae0 74 65 72 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20  ter;.  int rc = 
15af0 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20  SQLITE_OK;      
15b00 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
15b10 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 61 73 73 65   code */..  asse
15b20 72 74 28 20 70 53 6f 72 74 65 72 20 29 3b 0a 0a  rt( pSorter );..
15b30 20 20 2f 2a 20 49 66 20 6e 6f 20 64 61 74 61 20    /* If no data 
15b40 68 61 73 20 62 65 65 6e 20 77 72 69 74 74 65 6e  has been written
15b50 20 74 6f 20 64 69 73 6b 2c 20 74 68 65 6e 20 64   to disk, then d
15b60 6f 20 6e 6f 74 20 64 6f 20 73 6f 20 6e 6f 77 2e  o not do so now.
15b70 20 49 6e 73 74 65 61 64 2c 0a 20 20 2a 2a 20 73   Instead,.  ** s
15b80 6f 72 74 20 74 68 65 20 56 64 62 65 53 6f 72 74  ort the VdbeSort
15b90 65 72 2e 70 52 65 63 6f 72 64 20 6c 69 73 74 2e  er.pRecord list.
15ba0 20 54 68 65 20 76 64 62 65 20 6c 61 79 65 72 20   The vdbe layer 
15bb0 77 69 6c 6c 20 72 65 61 64 20 64 61 74 61 20 64  will read data d
15bc0 69 72 65 63 74 6c 79 0a 20 20 2a 2a 20 66 72 6f  irectly.  ** fro
15bd0 6d 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20  m the in-memory 
15be0 6c 69 73 74 2e 20 20 2a 2f 0a 20 20 69 66 28 20  list.  */.  if( 
15bf0 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41  pSorter->bUsePMA
15c00 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 70  ==0 ){.    if( p
15c10 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69  Sorter->list.pLi
15c20 73 74 20 29 7b 0a 20 20 20 20 20 20 2a 70 62 45  st ){.      *pbE
15c30 6f 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 63  of = 0;.      rc
15c40 20 3d 20 76 64 62 65 53 6f 72 74 65 72 53 6f 72   = vdbeSorterSor
15c50 74 28 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73  t(&pSorter->aTas
15c60 6b 5b 30 5d 2c 20 26 70 53 6f 72 74 65 72 2d 3e  k[0], &pSorter->
15c70 6c 69 73 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65  list);.    }else
15c80 7b 0a 20 20 20 20 20 20 2a 70 62 45 6f 66 20 3d  {.      *pbEof =
15c90 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65   1;.    }.    re
15ca0 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20  turn rc;.  }..  
15cb0 2f 2a 20 57 72 69 74 65 20 74 68 65 20 63 75 72  /* Write the cur
15cc0 72 65 6e 74 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c  rent in-memory l
15cd0 69 73 74 20 74 6f 20 61 20 50 4d 41 2e 20 57 68  ist to a PMA. Wh
15ce0 65 6e 20 74 68 65 20 56 64 62 65 53 6f 72 74 65  en the VdbeSorte
15cf0 72 57 72 69 74 65 28 29 20 0a 20 20 2a 2a 20 66  rWrite() .  ** f
15d00 75 6e 63 74 69 6f 6e 20 66 6c 75 73 68 65 73 20  unction flushes 
15d10 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
15d20 6d 65 6d 6f 72 79 20 74 6f 20 64 69 73 6b 2c 20  memory to disk, 
15d30 69 74 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 61  it immediately a
15d40 6c 77 61 79 73 0a 20 20 2a 2a 20 63 72 65 61 74  lways.  ** creat
15d50 65 73 20 61 20 6e 65 77 20 6c 69 73 74 20 63 6f  es a new list co
15d60 6e 73 69 73 74 69 6e 67 20 6f 66 20 61 20 73 69  nsisting of a si
15d70 6e 67 6c 65 20 6b 65 79 20 69 6d 6d 65 64 69 61  ngle key immedia
15d80 74 65 6c 79 20 61 66 74 65 72 77 61 72 64 73 2e  tely afterwards.
15d90 0a 20 20 2a 2a 20 53 6f 20 74 68 65 20 6c 69 73  .  ** So the lis
15da0 74 20 69 73 20 6e 65 76 65 72 20 65 6d 70 74 79  t is never empty
15db0 20 61 74 20 74 68 69 73 20 70 6f 69 6e 74 2e 20   at this point. 
15dc0 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 53   */.  assert( pS
15dd0 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73  orter->list.pLis
15de0 74 20 29 3b 0a 20 20 72 63 20 3d 20 76 64 62 65  t );.  rc = vdbe
15df0 53 6f 72 74 65 72 46 6c 75 73 68 50 4d 41 28 70  SorterFlushPMA(p
15e00 53 6f 72 74 65 72 29 3b 0a 0a 20 20 2f 2a 20 4a  Sorter);..  /* J
15e10 6f 69 6e 20 61 6c 6c 20 74 68 72 65 61 64 73 20  oin all threads 
15e20 2a 2f 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f  */.  rc = vdbeSo
15e30 72 74 65 72 4a 6f 69 6e 41 6c 6c 28 70 53 6f 72  rterJoinAll(pSor
15e40 74 65 72 2c 20 72 63 29 3b 0a 0a 20 20 76 64 62  ter, rc);..  vdb
15e50 65 53 6f 72 74 65 72 52 65 77 69 6e 64 44 65 62  eSorterRewindDeb
15e60 75 67 28 22 72 65 77 69 6e 64 22 29 3b 0a 0a 20  ug("rewind");.. 
15e70 20 2f 2a 20 41 73 73 75 6d 69 6e 67 20 6e 6f 20   /* Assuming no 
15e80 65 72 72 6f 72 73 20 68 61 76 65 20 6f 63 63 75  errors have occu
15e90 72 72 65 64 2c 20 73 65 74 20 75 70 20 61 20 6d  rred, set up a m
15ea0 65 72 67 65 72 20 73 74 72 75 63 74 75 72 65 20  erger structure 
15eb0 74 6f 20 0a 20 20 2a 2a 20 69 6e 63 72 65 6d 65  to .  ** increme
15ec0 6e 74 61 6c 6c 79 20 72 65 61 64 20 61 6e 64 20  ntally read and 
15ed0 6d 65 72 67 65 20 61 6c 6c 20 72 65 6d 61 69 6e  merge all remain
15ee0 69 6e 67 20 50 4d 41 73 2e 20 20 2a 2f 0a 20 20  ing PMAs.  */.  
15ef0 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d  assert( pSorter-
15f00 3e 70 52 65 61 64 65 72 3d 3d 30 20 29 3b 0a 20  >pReader==0 );. 
15f10 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
15f20 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 76  OK ){.    rc = v
15f30 64 62 65 53 6f 72 74 65 72 53 65 74 75 70 4d 65  dbeSorterSetupMe
15f40 72 67 65 28 70 53 6f 72 74 65 72 29 3b 0a 20 20  rge(pSorter);.  
15f50 20 20 2a 70 62 45 6f 66 20 3d 20 30 3b 0a 20 20    *pbEof = 0;.  
15f60 7d 0a 0a 20 20 76 64 62 65 53 6f 72 74 65 72 52  }..  vdbeSorterR
15f70 65 77 69 6e 64 44 65 62 75 67 28 22 72 65 77 69  ewindDebug("rewi
15f80 6e 64 64 6f 6e 65 22 29 3b 0a 20 20 72 65 74 75  nddone");.  retu
15f90 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
15fa0 41 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20 6e  Advance to the n
15fb0 65 78 74 20 65 6c 65 6d 65 6e 74 20 69 6e 20 74  ext element in t
15fc0 68 65 20 73 6f 72 74 65 72 2e 0a 2a 2f 0a 69 6e  he sorter..*/.in
15fd0 74 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72  t sqlite3VdbeSor
15fe0 74 65 72 4e 65 78 74 28 73 71 6c 69 74 65 33 20  terNext(sqlite3 
15ff0 2a 64 62 2c 20 63 6f 6e 73 74 20 56 64 62 65 43  *db, const VdbeC
16000 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74  ursor *pCsr, int
16010 20 2a 70 62 45 6f 66 29 7b 0a 20 20 56 64 62 65   *pbEof){.  Vdbe
16020 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20  Sorter *pSorter 
16030 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b  = pCsr->pSorter;
16040 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
16050 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16060 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
16070 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20  e */..  assert( 
16080 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41  pSorter->bUsePMA
16090 20 7c 7c 20 28 70 53 6f 72 74 65 72 2d 3e 70 52   || (pSorter->pR
160a0 65 61 64 65 72 3d 3d 30 20 26 26 20 70 53 6f 72  eader==0 && pSor
160b0 74 65 72 2d 3e 70 4d 65 72 67 65 72 3d 3d 30 29  ter->pMerger==0)
160c0 20 29 3b 0a 20 20 69 66 28 20 70 53 6f 72 74 65   );.  if( pSorte
160d0 72 2d 3e 62 55 73 65 50 4d 41 20 29 7b 0a 20 20  r->bUsePMA ){.  
160e0 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65    assert( pSorte
160f0 72 2d 3e 70 52 65 61 64 65 72 3d 3d 30 20 7c 7c  r->pReader==0 ||
16100 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65   pSorter->pMerge
16110 72 3d 3d 30 20 29 3b 0a 20 20 20 20 61 73 73 65  r==0 );.    asse
16120 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73  rt( pSorter->bUs
16130 65 54 68 72 65 61 64 73 3d 3d 30 20 7c 7c 20 70  eThreads==0 || p
16140 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72 20  Sorter->pReader 
16150 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
16160 53 6f 72 74 65 72 2d 3e 62 55 73 65 54 68 72 65  Sorter->bUseThre
16170 61 64 73 3d 3d 31 20 7c 7c 20 70 53 6f 72 74 65  ads==1 || pSorte
16180 72 2d 3e 70 4d 65 72 67 65 72 20 29 3b 0a 23 69  r->pMerger );.#i
16190 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52  f SQLITE_MAX_WOR
161a0 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 0a 20 20  KER_THREADS>0.  
161b0 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 62    if( pSorter->b
161c0 55 73 65 54 68 72 65 61 64 73 20 29 7b 0a 20 20  UseThreads ){.  
161d0 20 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61      rc = vdbePma
161e0 52 65 61 64 65 72 4e 65 78 74 28 70 53 6f 72 74  ReaderNext(pSort
161f0 65 72 2d 3e 70 52 65 61 64 65 72 29 3b 0a 20 20  er->pReader);.  
16200 20 20 20 20 2a 70 62 45 6f 66 20 3d 20 28 70 53      *pbEof = (pS
16210 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72 2d 3e  orter->pReader->
16220 70 46 64 3d 3d 30 29 3b 0a 20 20 20 20 7d 65 6c  pFd==0);.    }el
16230 73 65 0a 23 65 6e 64 69 66 0a 20 20 20 20 2f 2a  se.#endif.    /*
16240 69 66 28 20 21 70 53 6f 72 74 65 72 2d 3e 62 55  if( !pSorter->bU
16250 73 65 54 68 72 65 61 64 73 20 29 2a 2f 20 7b 0a  seThreads )*/ {.
16260 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 53        assert( pS
16270 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 21 3d  orter->pMerger!=
16280 30 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72  0 );.      asser
16290 74 28 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72  t( pSorter->pMer
162a0 67 65 72 2d 3e 70 54 61 73 6b 3d 3d 28 26 70 53  ger->pTask==(&pS
162b0 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 30 5d 29  orter->aTask[0])
162c0 20 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 76   );.      rc = v
162d0 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 53 74  dbeMergeEngineSt
162e0 65 70 28 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72  ep(pSorter->pMer
162f0 67 65 72 2c 20 70 62 45 6f 66 29 3b 0a 20 20 20  ger, pbEof);.   
16300 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20   }.  }else{.    
16310 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 46  SorterRecord *pF
16320 72 65 65 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6c  ree = pSorter->l
16330 69 73 74 2e 70 4c 69 73 74 3b 0a 20 20 20 20 70  ist.pList;.    p
16340 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69  Sorter->list.pLi
16350 73 74 20 3d 20 70 46 72 65 65 2d 3e 75 2e 70 4e  st = pFree->u.pN
16360 65 78 74 3b 0a 20 20 20 20 70 46 72 65 65 2d 3e  ext;.    pFree->
16370 75 2e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20  u.pNext = 0;.   
16380 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6c 69   if( pSorter->li
16390 73 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30 20 29 20  st.aMemory==0 ) 
163a0 76 64 62 65 53 6f 72 74 65 72 52 65 63 6f 72 64  vdbeSorterRecord
163b0 46 72 65 65 28 64 62 2c 20 70 46 72 65 65 29 3b  Free(db, pFree);
163c0 0a 20 20 20 20 2a 70 62 45 6f 66 20 3d 20 21 70  .    *pbEof = !p
163d0 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69  Sorter->list.pLi
163e0 73 74 3b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c  st;.    rc = SQL
163f0 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 20 20 72 65  ITE_OK;.  }.  re
16400 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
16410 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74  * Return a point
16420 65 72 20 74 6f 20 61 20 62 75 66 66 65 72 20 6f  er to a buffer o
16430 77 6e 65 64 20 62 79 20 74 68 65 20 73 6f 72 74  wned by the sort
16440 65 72 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73  er that contains
16450 20 74 68 65 20 0a 2a 2a 20 63 75 72 72 65 6e 74   the .** current
16460 20 6b 65 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20   key..*/.static 
16470 76 6f 69 64 20 2a 76 64 62 65 53 6f 72 74 65 72  void *vdbeSorter
16480 52 6f 77 6b 65 79 28 0a 20 20 63 6f 6e 73 74 20  Rowkey(.  const 
16490 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72  VdbeSorter *pSor
164a0 74 65 72 2c 20 20 20 20 20 20 2f 2a 20 53 6f 72  ter,      /* Sor
164b0 74 65 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20  ter object */.  
164c0 69 6e 74 20 2a 70 6e 4b 65 79 20 20 20 20 20 20  int *pnKey      
164d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
164e0 2f 2a 20 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20  /* OUT: Size of 
164f0 63 75 72 72 65 6e 74 20 6b 65 79 20 69 6e 20 62  current key in b
16500 79 74 65 73 20 2a 2f 0a 29 7b 0a 20 20 76 6f 69  ytes */.){.  voi
16510 64 20 2a 70 4b 65 79 3b 0a 20 20 69 66 28 20 70  d *pKey;.  if( p
16520 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41 20  Sorter->bUsePMA 
16530 29 7b 0a 20 20 20 20 50 6d 61 52 65 61 64 65 72  ){.    PmaReader
16540 20 2a 70 52 65 61 64 65 72 3b 0a 23 69 66 20 53   *pReader;.#if S
16550 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52  QLITE_MAX_WORKER
16560 5f 54 48 52 45 41 44 53 3e 30 0a 20 20 20 20 69  _THREADS>0.    i
16570 66 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65  f( pSorter->bUse
16580 54 68 72 65 61 64 73 20 29 7b 0a 20 20 20 20 20  Threads ){.     
16590 20 70 52 65 61 64 65 72 20 3d 20 70 53 6f 72 74   pReader = pSort
165a0 65 72 2d 3e 70 52 65 61 64 65 72 3b 0a 20 20 20  er->pReader;.   
165b0 20 7d 65 6c 73 65 0a 23 65 6e 64 69 66 0a 20 20   }else.#endif.  
165c0 20 20 2f 2a 69 66 28 20 21 70 53 6f 72 74 65 72    /*if( !pSorter
165d0 2d 3e 62 55 73 65 54 68 72 65 61 64 73 20 29 2a  ->bUseThreads )*
165e0 2f 7b 0a 20 20 20 20 20 20 70 52 65 61 64 65 72  /{.      pReader
165f0 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 70 4d 65   = &pSorter->pMe
16600 72 67 65 72 2d 3e 61 52 65 61 64 72 5b 70 53 6f  rger->aReadr[pSo
16610 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 2d 3e 61  rter->pMerger->a
16620 54 72 65 65 5b 31 5d 5d 3b 0a 20 20 20 20 7d 0a  Tree[1]];.    }.
16630 20 20 20 20 2a 70 6e 4b 65 79 20 3d 20 70 52 65      *pnKey = pRe
16640 61 64 65 72 2d 3e 6e 4b 65 79 3b 0a 20 20 20 20  ader->nKey;.    
16650 70 4b 65 79 20 3d 20 70 52 65 61 64 65 72 2d 3e  pKey = pReader->
16660 61 4b 65 79 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  aKey;.  }else{. 
16670 20 20 20 2a 70 6e 4b 65 79 20 3d 20 70 53 6f 72     *pnKey = pSor
16680 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 2d  ter->list.pList-
16690 3e 6e 56 61 6c 3b 0a 20 20 20 20 70 4b 65 79 20  >nVal;.    pKey 
166a0 3d 20 53 52 56 41 4c 28 70 53 6f 72 74 65 72 2d  = SRVAL(pSorter-
166b0 3e 6c 69 73 74 2e 70 4c 69 73 74 29 3b 0a 20 20  >list.pList);.  
166c0 7d 0a 20 20 72 65 74 75 72 6e 20 70 4b 65 79 3b  }.  return pKey;
166d0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20 74  .}../*.** Copy t
166e0 68 65 20 63 75 72 72 65 6e 74 20 73 6f 72 74 65  he current sorte
166f0 72 20 6b 65 79 20 69 6e 74 6f 20 74 68 65 20 6d  r key into the m
16700 65 6d 6f 72 79 20 63 65 6c 6c 20 70 4f 75 74 2e  emory cell pOut.
16710 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56  .*/.int sqlite3V
16720 64 62 65 53 6f 72 74 65 72 52 6f 77 6b 65 79 28  dbeSorterRowkey(
16730 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72  const VdbeCursor
16740 20 2a 70 43 73 72 2c 20 4d 65 6d 20 2a 70 4f 75   *pCsr, Mem *pOu
16750 74 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72  t){.  VdbeSorter
16760 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72   *pSorter = pCsr
16770 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 76 6f 69  ->pSorter;.  voi
16780 64 20 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b 65  d *pKey; int nKe
16790 79 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  y;           /* 
167a0 53 6f 72 74 65 72 20 6b 65 79 20 74 6f 20 63 6f  Sorter key to co
167b0 70 79 20 69 6e 74 6f 20 70 4f 75 74 20 2a 2f 0a  py into pOut */.
167c0 0a 20 20 70 4b 65 79 20 3d 20 76 64 62 65 53 6f  .  pKey = vdbeSo
167d0 72 74 65 72 52 6f 77 6b 65 79 28 70 53 6f 72 74  rterRowkey(pSort
167e0 65 72 2c 20 26 6e 4b 65 79 29 3b 0a 20 20 69 66  er, &nKey);.  if
167f0 28 20 73 71 6c 69 74 65 33 56 64 62 65 4d 65 6d  ( sqlite3VdbeMem
16800 43 6c 65 61 72 41 6e 64 52 65 73 69 7a 65 28 70  ClearAndResize(p
16810 4f 75 74 2c 20 6e 4b 65 79 29 20 29 7b 0a 20 20  Out, nKey) ){.  
16820 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
16830 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 70 4f 75  NOMEM;.  }.  pOu
16840 74 2d 3e 6e 20 3d 20 6e 4b 65 79 3b 0a 20 20 4d  t->n = nKey;.  M
16850 65 6d 53 65 74 54 79 70 65 46 6c 61 67 28 70 4f  emSetTypeFlag(pO
16860 75 74 2c 20 4d 45 4d 5f 42 6c 6f 62 29 3b 0a 20  ut, MEM_Blob);. 
16870 20 6d 65 6d 63 70 79 28 70 4f 75 74 2d 3e 7a 2c   memcpy(pOut->z,
16880 20 70 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 0a 20   pKey, nKey);.. 
16890 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
168a0 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70  K;.}../*.** Comp
168b0 61 72 65 20 74 68 65 20 6b 65 79 20 69 6e 20 6d  are the key in m
168c0 65 6d 6f 72 79 20 63 65 6c 6c 20 70 56 61 6c 20  emory cell pVal 
168d0 77 69 74 68 20 74 68 65 20 6b 65 79 20 74 68 61  with the key tha
168e0 74 20 74 68 65 20 73 6f 72 74 65 72 20 63 75 72  t the sorter cur
168f0 73 6f 72 0a 2a 2a 20 70 61 73 73 65 64 20 61 73  sor.** passed as
16900 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d   the first argum
16910 65 6e 74 20 63 75 72 72 65 6e 74 6c 79 20 70 6f  ent currently po
16920 69 6e 74 73 20 74 6f 2e 20 46 6f 72 20 74 68 65  ints to. For the
16930 20 70 75 72 70 6f 73 65 73 20 6f 66 0a 2a 2a 20   purposes of.** 
16940 74 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2c 20  the comparison, 
16950 69 67 6e 6f 72 65 20 74 68 65 20 72 6f 77 69 64  ignore the rowid
16960 20 66 69 65 6c 64 20 61 74 20 74 68 65 20 65 6e   field at the en
16970 64 20 6f 66 20 65 61 63 68 20 72 65 63 6f 72 64  d of each record
16980 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 73  ..**.** If the s
16990 6f 72 74 65 72 20 63 75 72 73 6f 72 20 6b 65 79  orter cursor key
169a0 20 63 6f 6e 74 61 69 6e 73 20 61 6e 79 20 4e 55   contains any NU
169b0 4c 4c 20 76 61 6c 75 65 73 2c 20 63 6f 6e 73 69  LL values, consi
169c0 64 65 72 20 69 74 20 74 6f 20 62 65 0a 2a 2a 20  der it to be.** 
169d0 6c 65 73 73 20 74 68 61 6e 20 70 56 61 6c 2e 20  less than pVal. 
169e0 45 76 65 6e 20 69 66 20 70 56 61 6c 20 61 6c 73  Even if pVal als
169f0 6f 20 63 6f 6e 74 61 69 6e 73 20 4e 55 4c 4c 20  o contains NULL 
16a00 76 61 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 49 66  values..**.** If
16a10 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
16a20 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69  , return an SQLi
16a30 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 28 69  te error code (i
16a40 2e 65 2e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  .e. SQLITE_NOMEM
16a50 29 2e 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c  )..** Otherwise,
16a60 20 73 65 74 20 2a 70 52 65 73 20 74 6f 20 61 20   set *pRes to a 
16a70 6e 65 67 61 74 69 76 65 2c 20 7a 65 72 6f 20 6f  negative, zero o
16a80 72 20 70 6f 73 69 74 69 76 65 20 76 61 6c 75 65  r positive value
16a90 20 69 66 20 74 68 65 0a 2a 2a 20 6b 65 79 20 69   if the.** key i
16aa0 6e 20 70 56 61 6c 20 69 73 20 73 6d 61 6c 6c 65  n pVal is smalle
16ab0 72 20 74 68 61 6e 2c 20 65 71 75 61 6c 20 74 6f  r than, equal to
16ac0 20 6f 72 20 6c 61 72 67 65 72 20 74 68 61 6e 20   or larger than 
16ad0 74 68 65 20 63 75 72 72 65 6e 74 20 73 6f 72 74  the current sort
16ae0 65 72 0a 2a 2a 20 6b 65 79 2e 0a 2a 2a 0a 2a 2a  er.** key..**.**
16af0 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 66 6f   This routine fo
16b00 72 6d 73 20 74 68 65 20 63 6f 72 65 20 6f 66 20  rms the core of 
16b10 74 68 65 20 4f 50 5f 53 6f 72 74 65 72 43 6f 6d  the OP_SorterCom
16b20 70 61 72 65 20 6f 70 63 6f 64 65 2c 20 77 68 69  pare opcode, whi
16b30 63 68 20 69 6e 0a 2a 2a 20 74 75 72 6e 20 69 73  ch in.** turn is
16b40 20 75 73 65 64 20 74 6f 20 76 65 72 69 66 79 20   used to verify 
16b50 75 6e 69 71 75 65 6e 65 73 73 20 77 68 65 6e 20  uniqueness when 
16b60 63 6f 6e 73 74 72 75 63 74 69 6e 67 20 61 20 55  constructing a U
16b70 4e 49 51 55 45 20 49 4e 44 45 58 2e 0a 2a 2f 0a  NIQUE INDEX..*/.
16b80 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65 53  int sqlite3VdbeS
16b90 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 0a 20 20  orterCompare(.  
16ba0 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72  const VdbeCursor
16bb0 20 2a 70 43 73 72 2c 20 20 20 20 20 20 20 20 20   *pCsr,         
16bc0 2f 2a 20 53 6f 72 74 65 72 20 63 75 72 73 6f 72  /* Sorter cursor
16bd0 20 2a 2f 0a 20 20 4d 65 6d 20 2a 70 56 61 6c 2c   */.  Mem *pVal,
16be0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16bf0 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 74        /* Value t
16c00 6f 20 63 6f 6d 70 61 72 65 20 74 6f 20 63 75 72  o compare to cur
16c10 72 65 6e 74 20 73 6f 72 74 65 72 20 6b 65 79 20  rent sorter key 
16c20 2a 2f 0a 20 20 69 6e 74 20 6e 4b 65 79 43 6f 6c  */.  int nKeyCol
16c30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
16c40 20 20 20 20 20 2f 2a 20 43 6f 6d 70 61 72 65 20       /* Compare 
16c50 74 68 69 73 20 6d 61 6e 79 20 63 6f 6c 75 6d 6e  this many column
16c60 73 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 52 65 73  s */.  int *pRes
16c70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16c80 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 52         /* OUT: R
16c90 65 73 75 6c 74 20 6f 66 20 63 6f 6d 70 61 72 69  esult of compari
16ca0 73 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65  son */.){.  Vdbe
16cb0 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20  Sorter *pSorter 
16cc0 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b  = pCsr->pSorter;
16cd0 0a 20 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72  .  UnpackedRecor
16ce0 64 20 2a 72 32 20 3d 20 70 53 6f 72 74 65 72 2d  d *r2 = pSorter-
16cf0 3e 70 55 6e 70 61 63 6b 65 64 3b 0a 20 20 4b 65  >pUnpacked;.  Ke
16d00 79 49 6e 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 20  yInfo *pKeyInfo 
16d10 3d 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f  = pCsr->pKeyInfo
16d20 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 76 6f 69  ;.  int i;.  voi
16d30 64 20 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b 65  d *pKey; int nKe
16d40 79 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  y;           /* 
16d50 53 6f 72 74 65 72 20 6b 65 79 20 74 6f 20 63 6f  Sorter key to co
16d60 6d 70 61 72 65 20 70 56 61 6c 20 77 69 74 68 20  mpare pVal with 
16d70 2a 2f 0a 0a 20 20 69 66 28 20 72 32 3d 3d 30 20  */..  if( r2==0 
16d80 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 70 3b 0a  ){.    char *p;.
16d90 20 20 20 20 72 32 20 3d 20 70 53 6f 72 74 65 72      r2 = pSorter
16da0 2d 3e 70 55 6e 70 61 63 6b 65 64 20 3d 20 73 71  ->pUnpacked = sq
16db0 6c 69 74 65 33 56 64 62 65 41 6c 6c 6f 63 55 6e  lite3VdbeAllocUn
16dc0 70 61 63 6b 65 64 52 65 63 6f 72 64 28 70 4b 65  packedRecord(pKe
16dd0 79 49 6e 66 6f 2c 30 2c 30 2c 26 70 29 3b 0a 20  yInfo,0,0,&p);. 
16de0 20 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74     assert( pSort
16df0 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64 3d 3d 28  er->pUnpacked==(
16e00 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 2a 29  UnpackedRecord*)
16e10 70 20 29 3b 0a 20 20 20 20 69 66 28 20 72 32 3d  p );.    if( r2=
16e20 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  =0 ) return SQLI
16e30 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 72 32  TE_NOMEM;.    r2
16e40 2d 3e 6e 46 69 65 6c 64 20 3d 20 6e 4b 65 79 43  ->nField = nKeyC
16e50 6f 6c 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74  ol;.  }.  assert
16e60 28 20 72 32 2d 3e 6e 46 69 65 6c 64 3d 3d 6e 4b  ( r2->nField==nK
16e70 65 79 43 6f 6c 20 29 3b 0a 0a 20 20 70 4b 65 79  eyCol );..  pKey
16e80 20 3d 20 76 64 62 65 53 6f 72 74 65 72 52 6f 77   = vdbeSorterRow
16e90 6b 65 79 28 70 53 6f 72 74 65 72 2c 20 26 6e 4b  key(pSorter, &nK
16ea0 65 79 29 3b 0a 20 20 73 71 6c 69 74 65 33 56 64  ey);.  sqlite3Vd
16eb0 62 65 52 65 63 6f 72 64 55 6e 70 61 63 6b 28 70  beRecordUnpack(p
16ec0 4b 65 79 49 6e 66 6f 2c 20 6e 4b 65 79 2c 20 70  KeyInfo, nKey, p
16ed0 4b 65 79 2c 20 72 32 29 3b 0a 20 20 66 6f 72 28  Key, r2);.  for(
16ee0 69 3d 30 3b 20 69 3c 6e 4b 65 79 43 6f 6c 3b 20  i=0; i<nKeyCol; 
16ef0 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 72 32  i++){.    if( r2
16f00 2d 3e 61 4d 65 6d 5b 69 5d 2e 66 6c 61 67 73 20  ->aMem[i].flags 
16f10 26 20 4d 45 4d 5f 4e 75 6c 6c 20 29 7b 0a 20 20  & MEM_Null ){.  
16f20 20 20 20 20 2a 70 52 65 73 20 3d 20 2d 31 3b 0a      *pRes = -1;.
16f30 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c        return SQL
16f40 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20  ITE_OK;.    }.  
16f50 7d 0a 0a 20 20 2a 70 52 65 73 20 3d 20 73 71 6c  }..  *pRes = sql
16f60 69 74 65 33 56 64 62 65 52 65 63 6f 72 64 43 6f  ite3VdbeRecordCo
16f70 6d 70 61 72 65 28 70 56 61 6c 2d 3e 6e 2c 20 70  mpare(pVal->n, p
16f80 56 61 6c 2d 3e 7a 2c 20 72 32 29 3b 0a 20 20 72  Val->z, r2);.  r
16f90 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
16fa0 0a 7d 0a                                         .}.