/ Hex Artifact Content
Login

Artifact 3e8827bb9d12465556357c24641f8805a7e2bba0:


0000: 2f 2a 0a 2a 2a 20 32 30 31 31 2d 30 37 2d 30 39  /*.** 2011-07-09
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a  ***************.
0170: 2a 2a 20 54 68 69 73 20 66 69 6c 65 20 63 6f 6e  ** This file con
0180: 74 61 69 6e 73 20 63 6f 64 65 20 66 6f 72 20 74  tains code for t
0190: 68 65 20 56 64 62 65 53 6f 72 74 65 72 20 6f 62  he VdbeSorter ob
01a0: 6a 65 63 74 2c 20 75 73 65 64 20 69 6e 20 63 6f  ject, used in co
01b0: 6e 63 65 72 74 20 77 69 74 68 0a 2a 2a 20 61 20  ncert with.** a 
01c0: 56 64 62 65 43 75 72 73 6f 72 20 74 6f 20 73 6f  VdbeCursor to so
01d0: 72 74 20 6c 61 72 67 65 20 6e 75 6d 62 65 72 73  rt large numbers
01e0: 20 6f 66 20 6b 65 79 73 20 66 6f 72 20 43 52 45   of keys for CRE
01f0: 41 54 45 20 49 4e 44 45 58 20 73 74 61 74 65 6d  ATE INDEX statem
0200: 65 6e 74 73 0a 2a 2a 20 6f 72 20 62 79 20 53 45  ents.** or by SE
0210: 4c 45 43 54 20 73 74 61 74 65 6d 65 6e 74 73 20  LECT statements 
0220: 77 69 74 68 20 4f 52 44 45 52 20 42 59 20 63 6c  with ORDER BY cl
0230: 61 75 73 65 73 20 74 68 61 74 20 63 61 6e 6e 6f  auses that canno
0240: 74 20 62 65 20 73 61 74 69 73 66 69 65 64 0a 2a  t be satisfied.*
0250: 2a 20 75 73 69 6e 67 20 69 6e 64 65 78 65 73 20  * using indexes 
0260: 61 6e 64 20 77 69 74 68 6f 75 74 20 4c 49 4d 49  and without LIMI
0270: 54 20 63 6c 61 75 73 65 73 2e 0a 2a 2a 0a 2a 2a  T clauses..**.**
0280: 20 54 68 65 20 56 64 62 65 53 6f 72 74 65 72 20   The VdbeSorter 
0290: 6f 62 6a 65 63 74 20 69 6d 70 6c 65 6d 65 6e 74  object implement
02a0: 73 20 61 20 6d 75 6c 74 69 2d 74 68 72 65 61 64  s a multi-thread
02b0: 65 64 20 65 78 74 65 72 6e 61 6c 20 6d 65 72 67  ed external merg
02c0: 65 20 73 6f 72 74 0a 2a 2a 20 61 6c 67 6f 72 69  e sort.** algori
02d0: 74 68 6d 20 74 68 61 74 20 69 73 20 65 66 66 69  thm that is effi
02e0: 63 69 65 6e 74 20 65 76 65 6e 20 69 66 20 74 68  cient even if th
02f0: 65 20 6e 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d  e number of elem
0300: 65 6e 74 73 20 62 65 69 6e 67 20 73 6f 72 74 65  ents being sorte
0310: 64 0a 2a 2a 20 65 78 63 65 65 64 73 20 74 68 65  d.** exceeds the
0320: 20 61 76 61 69 6c 61 62 6c 65 20 6d 65 6d 6f 72   available memor
0330: 79 2e 0a 2a 2a 0a 2a 2a 20 48 65 72 65 20 69 73  y..**.** Here is
0340: 20 74 68 65 20 28 69 6e 74 65 72 6e 61 6c 2c 20   the (internal, 
0350: 6e 6f 6e 2d 41 50 49 29 20 69 6e 74 65 72 66 61  non-API) interfa
0360: 63 65 20 62 65 74 77 65 65 6e 20 74 68 69 73 20  ce between this 
0370: 6d 6f 64 75 6c 65 20 61 6e 64 20 74 68 65 0a 2a  module and the.*
0380: 2a 20 72 65 73 74 20 6f 66 20 74 68 65 20 53 51  * rest of the SQ
0390: 4c 69 74 65 20 73 79 73 74 65 6d 3a 0a 2a 2a 0a  Lite system:.**.
03a0: 2a 2a 20 20 20 20 73 71 6c 69 74 65 33 56 64 62  **    sqlite3Vdb
03b0: 65 53 6f 72 74 65 72 49 6e 69 74 28 29 20 20 20  eSorterInit()   
03c0: 20 20 20 20 43 72 65 61 74 65 20 61 20 6e 65 77      Create a new
03d0: 20 56 64 62 65 53 6f 72 74 65 72 20 6f 62 6a 65   VdbeSorter obje
03e0: 63 74 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71 6c  ct..**.**    sql
03f0: 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 57 72  ite3VdbeSorterWr
0400: 69 74 65 28 29 20 20 20 20 20 20 41 64 64 20 61  ite()      Add a
0410: 20 73 69 6e 67 6c 65 20 6e 65 77 20 72 6f 77 20   single new row 
0420: 74 6f 20 74 68 65 20 56 64 62 65 53 6f 72 74 65  to the VdbeSorte
0430: 72 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20  r.**            
0440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0450: 20 20 20 20 20 20 6f 62 6a 65 63 74 2e 20 20 54        object.  T
0460: 68 65 20 72 6f 77 20 69 73 20 61 20 62 69 6e 61  he row is a bina
0470: 72 79 20 62 6c 6f 62 20 69 6e 20 74 68 65 0a 2a  ry blob in the.*
0480: 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  *               
0490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04a0: 20 20 20 4f 50 5f 4d 61 6b 65 52 65 63 6f 72 64     OP_MakeRecord
04b0: 20 66 6f 72 6d 61 74 20 74 68 61 74 20 63 6f 6e   format that con
04c0: 74 61 69 6e 73 20 62 6f 74 68 0a 2a 2a 20 20 20  tains both.**   
04d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 74                 t
04f0: 68 65 20 4f 52 44 45 52 20 42 59 20 6b 65 79 20  he ORDER BY key 
0500: 63 6f 6c 75 6d 6e 73 20 61 6e 64 20 72 65 73 75  columns and resu
0510: 6c 74 20 63 6f 6c 75 6d 6e 73 0a 2a 2a 20 20 20  lt columns.**   
0520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
0540: 6e 20 74 68 65 20 63 61 73 65 20 6f 66 20 61 20  n the case of a 
0550: 53 45 4c 45 43 54 20 77 2f 20 4f 52 44 45 52 20  SELECT w/ ORDER 
0560: 42 59 2c 20 6f 72 0a 2a 2a 20 20 20 20 20 20 20  BY, or.**       
0570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0580: 20 20 20 20 20 20 20 20 20 20 20 74 68 65 20 63             the c
0590: 6f 6d 70 6c 65 74 65 20 72 65 63 6f 72 64 20 66  omplete record f
05a0: 6f 72 20 61 6e 20 69 6e 64 65 78 20 65 6e 74 72  or an index entr
05b0: 79 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20  y.**            
05c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05d0: 20 20 20 20 20 20 69 6e 20 74 68 65 20 63 61 73        in the cas
05e0: 65 20 6f 66 20 61 20 43 52 45 41 54 45 20 49 4e  e of a CREATE IN
05f0: 44 45 58 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71  DEX..**.**    sq
0600: 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 52  lite3VdbeSorterR
0610: 65 77 69 6e 64 28 29 20 20 20 20 20 53 6f 72 74  ewind()     Sort
0620: 20 61 6c 6c 20 63 6f 6e 74 65 6e 74 20 70 72 65   all content pre
0630: 76 69 6f 75 73 6c 79 20 61 64 64 65 64 2e 0a 2a  viously added..*
0640: 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  *               
0650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0660: 20 20 20 50 6f 73 69 74 69 6f 6e 20 74 68 65 20     Position the 
0670: 72 65 61 64 20 63 75 72 73 6f 72 20 6f 6e 20 74  read cursor on t
0680: 68 65 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20  he.**           
0690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06a0: 20 20 20 20 20 20 20 66 69 72 73 74 20 73 6f 72         first sor
06b0: 74 65 64 20 65 6c 65 6d 65 6e 74 2e 0a 2a 2a 0a  ted element..**.
06c0: 2a 2a 20 20 20 20 73 71 6c 69 74 65 33 56 64 62  **    sqlite3Vdb
06d0: 65 53 6f 72 74 65 72 4e 65 78 74 28 29 20 20 20  eSorterNext()   
06e0: 20 20 20 20 41 64 76 61 6e 63 65 20 74 68 65 20      Advance the 
06f0: 72 65 61 64 20 63 75 72 73 6f 72 20 74 6f 20 74  read cursor to t
0700: 68 65 20 6e 65 78 74 20 73 6f 72 74 65 64 0a 2a  he next sorted.*
0710: 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  *               
0720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0730: 20 20 20 65 6c 65 6d 65 6e 74 2e 0a 2a 2a 0a 2a     element..**.*
0740: 2a 20 20 20 20 73 71 6c 69 74 65 33 56 64 62 65  *    sqlite3Vdbe
0750: 53 6f 72 74 65 72 52 6f 77 6b 65 79 28 29 20 20  SorterRowkey()  
0760: 20 20 20 52 65 74 75 72 6e 20 74 68 65 20 63 6f     Return the co
0770: 6d 70 6c 65 74 65 20 62 69 6e 61 72 79 20 62 6c  mplete binary bl
0780: 6f 62 20 66 6f 72 20 74 68 65 0a 2a 2a 20 20 20  ob for the.**   
0790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72                 r
07b0: 6f 77 20 63 75 72 72 65 6e 74 6c 79 20 75 6e 64  ow currently und
07c0: 65 72 20 74 68 65 20 72 65 61 64 20 63 75 72 73  er the read curs
07d0: 6f 72 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71 6c  or..**.**    sql
07e0: 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 43 6f  ite3VdbeSorterCo
07f0: 6d 70 61 72 65 28 29 20 20 20 20 43 6f 6d 70 61  mpare()    Compa
0800: 72 65 20 74 68 65 20 62 69 6e 61 72 79 20 62 6c  re the binary bl
0810: 6f 62 20 66 6f 72 20 74 68 65 20 72 6f 77 0a 2a  ob for the row.*
0820: 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  *               
0830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0840: 20 20 20 63 75 72 72 65 6e 74 6c 79 20 75 6e 64     currently und
0850: 65 72 20 74 68 65 20 72 65 61 64 20 63 75 72 73  er the read curs
0860: 6f 72 20 61 67 61 69 6e 73 74 0a 2a 2a 20 20 20  or against.**   
0870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61                 a
0890: 6e 6f 74 68 65 72 20 62 69 6e 61 72 79 20 62 6c  nother binary bl
08a0: 6f 62 20 58 20 61 6e 64 20 72 65 70 6f 72 74 20  ob X and report 
08b0: 69 66 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20  if.**           
08c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08d0: 20 20 20 20 20 20 20 58 20 69 73 20 73 74 72 69         X is stri
08e0: 63 74 6c 79 20 6c 65 73 73 20 74 68 61 6e 20 74  ctly less than t
08f0: 68 65 20 72 65 61 64 20 63 75 72 73 6f 72 2e 0a  he read cursor..
0900: 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  **              
0910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0920: 20 20 20 20 55 73 65 64 20 74 6f 20 65 6e 66 6f      Used to enfo
0930: 72 63 65 20 75 6e 69 71 75 65 6e 65 73 73 20 69  rce uniqueness i
0940: 6e 20 61 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  n a.**          
0950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0960: 20 20 20 20 20 20 20 20 43 52 45 41 54 45 20 55          CREATE U
0970: 4e 49 51 55 45 20 49 4e 44 45 58 20 73 74 61 74  NIQUE INDEX stat
0980: 65 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 20 20 20  ement..**.**    
0990: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
09a0: 72 43 6c 6f 73 65 28 29 20 20 20 20 20 20 43 6c  rClose()      Cl
09b0: 6f 73 65 20 74 68 65 20 56 64 62 65 53 6f 72 74  ose the VdbeSort
09c0: 65 72 20 6f 62 6a 65 63 74 20 61 6e 64 20 72 65  er object and re
09d0: 63 6c 61 69 6d 0a 2a 2a 20 20 20 20 20 20 20 20  claim.**        
09e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09f0: 20 20 20 20 20 20 20 20 20 20 61 6c 6c 20 72 65            all re
0a00: 73 6f 75 72 63 65 73 2e 0a 2a 2a 0a 2a 2a 20 20  sources..**.**  
0a10: 20 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72    sqlite3VdbeSor
0a20: 74 65 72 52 65 73 65 74 28 29 20 20 20 20 20 20  terReset()      
0a30: 52 65 66 75 72 62 69 73 68 20 74 68 65 20 56 64  Refurbish the Vd
0a40: 62 65 53 6f 72 74 65 72 20 66 6f 72 20 72 65 75  beSorter for reu
0a50: 73 65 2e 20 20 54 68 69 73 0a 2a 2a 20 20 20 20  se.  This.**    
0a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 73                is
0a80: 20 6c 69 6b 65 20 43 6c 6f 73 65 28 29 20 66 6f   like Close() fo
0a90: 6c 6c 6f 77 65 64 20 62 79 20 49 6e 69 74 28 29  llowed by Init()
0aa0: 20 6f 6e 6c 79 0a 2a 2a 20 20 20 20 20 20 20 20   only.**        
0ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ac0: 20 20 20 20 20 20 20 20 20 20 6d 75 63 68 20 66            much f
0ad0: 61 73 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  aster..**.** The
0ae0: 20 69 6e 74 65 72 66 61 63 65 73 20 61 62 6f 76   interfaces abov
0af0: 65 20 6d 75 73 74 20 62 65 20 63 61 6c 6c 65 64  e must be called
0b00: 20 69 6e 20 61 20 70 61 72 74 69 63 75 6c 61 72   in a particular
0b10: 20 6f 72 64 65 72 2e 20 20 57 72 69 74 65 28 29   order.  Write()
0b20: 20 63 61 6e 20 0a 2a 2a 20 6f 6e 6c 79 20 6f 63   can .** only oc
0b30: 63 75 72 20 69 6e 20 62 65 74 77 65 65 6e 20 49  cur in between I
0b40: 6e 69 74 28 29 2f 52 65 73 65 74 28 29 20 61 6e  nit()/Reset() an
0b50: 64 20 52 65 77 69 6e 64 28 29 2e 20 20 4e 65 78  d Rewind().  Nex
0b60: 74 28 29 2c 20 52 6f 77 6b 65 79 28 29 2c 20 61  t(), Rowkey(), a
0b70: 6e 64 0a 2a 2a 20 43 6f 6d 70 61 72 65 28 29 20  nd.** Compare() 
0b80: 63 61 6e 20 6f 6e 6c 79 20 6f 63 63 75 72 20 69  can only occur i
0b90: 6e 20 62 65 74 77 65 65 6e 20 52 65 77 69 6e 64  n between Rewind
0ba0: 28 29 20 61 6e 64 20 43 6c 6f 73 65 28 29 2f 52  () and Close()/R
0bb0: 65 73 65 74 28 29 2e 20 69 2e 65 2e 0a 2a 2a 0a  eset(). i.e..**.
0bc0: 2a 2a 20 20 20 49 6e 69 74 28 29 0a 2a 2a 20 20  **   Init().**  
0bd0: 20 66 6f 72 20 65 61 63 68 20 72 65 63 6f 72 64   for each record
0be0: 3a 20 57 72 69 74 65 28 29 0a 2a 2a 20 20 20 52  : Write().**   R
0bf0: 65 77 69 6e 64 28 29 0a 2a 2a 20 20 20 20 20 52  ewind().**     R
0c00: 6f 77 6b 65 79 28 29 2f 43 6f 6d 70 61 72 65 28  owkey()/Compare(
0c10: 29 0a 2a 2a 20 20 20 4e 65 78 74 28 29 20 0a 2a  ).**   Next() .*
0c20: 2a 20 20 20 43 6c 6f 73 65 28 29 0a 2a 2a 0a 2a  *   Close().**.*
0c30: 2a 20 41 6c 67 6f 72 69 74 68 6d 3a 0a 2a 2a 0a  * Algorithm:.**.
0c40: 2a 2a 20 52 65 63 6f 72 64 73 20 70 61 73 73 65  ** Records passe
0c50: 64 20 74 6f 20 74 68 65 20 73 6f 72 74 65 72 20  d to the sorter 
0c60: 76 69 61 20 63 61 6c 6c 73 20 74 6f 20 57 72 69  via calls to Wri
0c70: 74 65 28 29 20 61 72 65 20 69 6e 69 74 69 61 6c  te() are initial
0c80: 6c 79 20 68 65 6c 64 20 0a 2a 2a 20 75 6e 73 6f  ly held .** unso
0c90: 72 74 65 64 20 69 6e 20 6d 61 69 6e 20 6d 65 6d  rted in main mem
0ca0: 6f 72 79 2e 20 41 73 73 75 6d 69 6e 67 20 74 68  ory. Assuming th
0cb0: 65 20 61 6d 6f 75 6e 74 20 6f 66 20 6d 65 6d 6f  e amount of memo
0cc0: 72 79 20 75 73 65 64 20 6e 65 76 65 72 20 65 78  ry used never ex
0cd0: 63 65 65 64 73 0a 2a 2a 20 61 20 74 68 72 65 73  ceeds.** a thres
0ce0: 68 6f 6c 64 2c 20 77 68 65 6e 20 52 65 77 69 6e  hold, when Rewin
0cf0: 64 28 29 20 69 73 20 63 61 6c 6c 65 64 20 74 68  d() is called th
0d00: 65 20 73 65 74 20 6f 66 20 72 65 63 6f 72 64 73  e set of records
0d10: 20 69 73 20 73 6f 72 74 65 64 20 75 73 69 6e 67   is sorted using
0d20: 0a 2a 2a 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79  .** an in-memory
0d30: 20 6d 65 72 67 65 20 73 6f 72 74 2e 20 49 6e 20   merge sort. In 
0d40: 74 68 69 73 20 63 61 73 65 2c 20 6e 6f 20 74 65  this case, no te
0d50: 6d 70 6f 72 61 72 79 20 66 69 6c 65 73 20 61 72  mporary files ar
0d60: 65 20 72 65 71 75 69 72 65 64 0a 2a 2a 20 61 6e  e required.** an
0d70: 64 20 73 75 62 73 65 71 75 65 6e 74 20 63 61 6c  d subsequent cal
0d80: 6c 73 20 74 6f 20 52 6f 77 6b 65 79 28 29 2c 20  ls to Rowkey(), 
0d90: 4e 65 78 74 28 29 20 61 6e 64 20 43 6f 6d 70 61  Next() and Compa
0da0: 72 65 28 29 20 72 65 61 64 20 72 65 63 6f 72 64  re() read record
0db0: 73 20 0a 2a 2a 20 64 69 72 65 63 74 6c 79 20 66  s .** directly f
0dc0: 72 6f 6d 20 6d 61 69 6e 20 6d 65 6d 6f 72 79 2e  rom main memory.
0dd0: 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 61 6d  .**.** If the am
0de0: 6f 75 6e 74 20 6f 66 20 73 70 61 63 65 20 75 73  ount of space us
0df0: 65 64 20 74 6f 20 73 74 6f 72 65 20 72 65 63 6f  ed to store reco
0e00: 72 64 73 20 69 6e 20 6d 61 69 6e 20 6d 65 6d 6f  rds in main memo
0e10: 72 79 20 65 78 63 65 65 64 73 20 74 68 65 0a 2a  ry exceeds the.*
0e20: 2a 20 74 68 72 65 73 68 6f 6c 64 2c 20 74 68 65  * threshold, the
0e30: 6e 20 74 68 65 20 73 65 74 20 6f 66 20 72 65 63  n the set of rec
0e40: 6f 72 64 73 20 63 75 72 72 65 6e 74 6c 79 20 69  ords currently i
0e50: 6e 20 6d 65 6d 6f 72 79 20 61 72 65 20 73 6f 72  n memory are sor
0e60: 74 65 64 20 61 6e 64 0a 2a 2a 20 77 72 69 74 74  ted and.** writt
0e70: 65 6e 20 74 6f 20 61 20 74 65 6d 70 6f 72 61 72  en to a temporar
0e80: 79 20 66 69 6c 65 20 69 6e 20 22 50 61 63 6b 65  y file in "Packe
0e90: 64 20 4d 65 6d 6f 72 79 20 41 72 72 61 79 22 20  d Memory Array" 
0ea0: 28 50 4d 41 29 20 66 6f 72 6d 61 74 2e 0a 2a 2a  (PMA) format..**
0eb0: 20 41 20 50 4d 41 20 63 72 65 61 74 65 64 20 61   A PMA created a
0ec0: 74 20 74 68 69 73 20 70 6f 69 6e 74 20 69 73 20  t this point is 
0ed0: 6b 6e 6f 77 6e 20 61 73 20 61 20 22 6c 65 76 65  known as a "leve
0ee0: 6c 2d 30 20 50 4d 41 22 2e 20 48 69 67 68 65 72  l-0 PMA". Higher
0ef0: 20 6c 65 76 65 6c 73 0a 2a 2a 20 6f 66 20 50 4d   levels.** of PM
0f00: 41 73 20 6d 61 79 20 62 65 20 63 72 65 61 74 65  As may be create
0f10: 64 20 62 79 20 6d 65 72 67 69 6e 67 20 65 78 69  d by merging exi
0f20: 73 74 69 6e 67 20 50 4d 41 73 20 74 6f 67 65 74  sting PMAs toget
0f30: 68 65 72 20 2d 20 66 6f 72 20 65 78 61 6d 70 6c  her - for exampl
0f40: 65 0a 2a 2a 20 6d 65 72 67 69 6e 67 20 74 77 6f  e.** merging two
0f50: 20 6f 72 20 6d 6f 72 65 20 6c 65 76 65 6c 2d 30   or more level-0
0f60: 20 50 4d 41 73 20 74 6f 67 65 74 68 65 72 20 63   PMAs together c
0f70: 72 65 61 74 65 73 20 61 20 6c 65 76 65 6c 2d 31  reates a level-1
0f80: 20 50 4d 41 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20   PMA..**.** The 
0f90: 74 68 72 65 73 68 6f 6c 64 20 66 6f 72 20 74 68  threshold for th
0fa0: 65 20 61 6d 6f 75 6e 74 20 6f 66 20 6d 61 69 6e  e amount of main
0fb0: 20 6d 65 6d 6f 72 79 20 74 6f 20 75 73 65 20 62   memory to use b
0fc0: 65 66 6f 72 65 20 66 6c 75 73 68 69 6e 67 20 0a  efore flushing .
0fd0: 2a 2a 20 72 65 63 6f 72 64 73 20 74 6f 20 61 20  ** records to a 
0fe0: 50 4d 41 20 69 73 20 72 6f 75 67 68 6c 79 20 74  PMA is roughly t
0ff0: 68 65 20 73 61 6d 65 20 61 73 20 74 68 65 20 6c  he same as the l
1000: 69 6d 69 74 20 63 6f 6e 66 69 67 75 72 65 64 20  imit configured 
1010: 66 6f 72 20 74 68 65 0a 2a 2a 20 70 61 67 65 2d  for the.** page-
1020: 63 61 63 68 65 20 6f 66 20 74 68 65 20 6d 61 69  cache of the mai
1030: 6e 20 64 61 74 61 62 61 73 65 2e 20 53 70 65 63  n database. Spec
1040: 69 66 69 63 61 6c 6c 79 2c 20 74 68 65 20 74 68  ifically, the th
1050: 72 65 73 68 6f 6c 64 20 69 73 20 73 65 74 20 74  reshold is set t
1060: 6f 20 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 20  o .** the value 
1070: 72 65 74 75 72 6e 65 64 20 6d 75 6c 74 69 70 6c  returned multipl
1080: 69 65 64 20 62 79 20 22 50 52 41 47 4d 41 20 6d  ied by "PRAGMA m
1090: 61 69 6e 2e 70 61 67 65 5f 73 69 7a 65 22 20 6d  ain.page_size" m
10a0: 75 6c 74 69 70 6c 65 64 20 62 79 20 0a 2a 2a 20  ultipled by .** 
10b0: 74 68 61 74 20 72 65 74 75 72 6e 65 64 20 62 79  that returned by
10c0: 20 22 50 52 41 47 4d 41 20 6d 61 69 6e 2e 63 61   "PRAGMA main.ca
10d0: 63 68 65 5f 73 69 7a 65 22 2c 20 69 6e 20 62 79  che_size", in by
10e0: 74 65 73 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  tes..**.** If th
10f0: 65 20 73 6f 72 74 65 72 20 69 73 20 72 75 6e 6e  e sorter is runn
1100: 69 6e 67 20 69 6e 20 73 69 6e 67 6c 65 2d 74 68  ing in single-th
1110: 72 65 61 64 65 64 20 6d 6f 64 65 2c 20 74 68 65  readed mode, the
1120: 6e 20 61 6c 6c 20 50 4d 41 73 20 67 65 6e 65 72  n all PMAs gener
1130: 61 74 65 64 0a 2a 2a 20 61 72 65 20 61 70 70 65  ated.** are appe
1140: 6e 64 65 64 20 74 6f 20 61 20 73 69 6e 67 6c 65  nded to a single
1150: 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 2e   temporary file.
1160: 20 4f 72 2c 20 69 66 20 74 68 65 20 73 6f 72 74   Or, if the sort
1170: 65 72 20 69 73 20 72 75 6e 6e 69 6e 67 20 69 6e  er is running in
1180: 0a 2a 2a 20 6d 75 6c 74 69 2d 74 68 72 65 61 64  .** multi-thread
1190: 65 64 20 6d 6f 64 65 20 74 68 65 6e 20 75 70 20  ed mode then up 
11a0: 74 6f 20 28 4e 2b 31 29 20 74 65 6d 70 6f 72 61  to (N+1) tempora
11b0: 72 79 20 66 69 6c 65 73 20 6d 61 79 20 62 65 20  ry files may be 
11c0: 6f 70 65 6e 65 64 2c 20 77 68 65 72 65 0a 2a 2a  opened, where.**
11d0: 20 4e 20 69 73 20 74 68 65 20 63 6f 6e 66 69 67   N is the config
11e0: 75 72 65 64 20 6e 75 6d 62 65 72 20 6f 66 20 77  ured number of w
11f0: 6f 72 6b 65 72 20 74 68 72 65 61 64 73 2e 20 49  orker threads. I
1200: 6e 20 74 68 69 73 20 63 61 73 65 2c 20 69 6e 73  n this case, ins
1210: 74 65 61 64 20 6f 66 0a 2a 2a 20 73 6f 72 74 69  tead of.** sorti
1220: 6e 67 20 74 68 65 20 72 65 63 6f 72 64 73 20 61  ng the records a
1230: 6e 64 20 77 72 69 74 69 6e 67 20 74 68 65 20 50  nd writing the P
1240: 4d 41 20 74 6f 20 61 20 74 65 6d 70 6f 72 61 72  MA to a temporar
1250: 79 20 66 69 6c 65 20 69 74 73 65 6c 66 2c 20 74  y file itself, t
1260: 68 65 0a 2a 2a 20 63 61 6c 6c 69 6e 67 20 74 68  he.** calling th
1270: 72 65 61 64 20 75 73 75 61 6c 6c 79 20 6c 61 75  read usually lau
1280: 6e 63 68 65 73 20 61 20 77 6f 72 6b 65 72 20 74  nches a worker t
1290: 68 72 65 61 64 20 74 6f 20 64 6f 20 73 6f 2e 20  hread to do so. 
12a0: 45 78 63 65 70 74 2c 20 69 66 0a 2a 2a 20 74 68  Except, if.** th
12b0: 65 72 65 20 61 72 65 20 61 6c 72 65 61 64 79 20  ere are already 
12c0: 4e 20 77 6f 72 6b 65 72 20 74 68 72 65 61 64 73  N worker threads
12d0: 20 72 75 6e 6e 69 6e 67 2c 20 74 68 65 20 6d 61   running, the ma
12e0: 69 6e 20 74 68 72 65 61 64 20 64 6f 65 73 20 74  in thread does t
12f0: 68 65 20 77 6f 72 6b 0a 2a 2a 20 69 74 73 65 6c  he work.** itsel
1300: 66 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 6f 72  f..**.** The sor
1310: 74 65 72 20 69 73 20 72 75 6e 6e 69 6e 67 20 69  ter is running i
1320: 6e 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64  n multi-threaded
1330: 20 6d 6f 64 65 20 69 66 20 28 61 29 20 74 68 65   mode if (a) the
1340: 20 6c 69 62 72 61 72 79 20 77 61 73 20 62 75 69   library was bui
1350: 6c 74 0a 2a 2a 20 77 69 74 68 20 70 72 65 2d 70  lt.** with pre-p
1360: 72 6f 63 65 73 73 6f 72 20 73 79 6d 62 6f 6c 20  rocessor symbol 
1370: 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45  SQLITE_MAX_WORKE
1380: 52 5f 54 48 52 45 41 44 53 20 73 65 74 20 74 6f  R_THREADS set to
1390: 20 61 20 76 61 6c 75 65 20 67 72 65 61 74 65 72   a value greater
13a0: 0a 2a 2a 20 74 68 61 6e 20 7a 65 72 6f 2c 20 61  .** than zero, a
13b0: 6e 64 20 28 62 29 20 77 6f 72 6b 65 72 20 74 68  nd (b) worker th
13c0: 72 65 61 64 73 20 68 61 76 65 20 62 65 65 6e 20  reads have been 
13d0: 65 6e 61 62 6c 65 64 20 61 74 20 72 75 6e 74 69  enabled at runti
13e0: 6d 65 20 62 79 20 63 61 6c 6c 69 6e 67 0a 2a 2a  me by calling.**
13f0: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28   sqlite3_config(
1400: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 57 4f  SQLITE_CONFIG_WO
1410: 52 4b 45 52 5f 54 48 52 45 41 44 53 2c 20 2e 2e  RKER_THREADS, ..
1420: 2e 29 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 52  .)..**.** When R
1430: 65 77 69 6e 64 28 29 20 69 73 20 63 61 6c 6c 65  ewind() is calle
1440: 64 2c 20 61 6e 79 20 64 61 74 61 20 72 65 6d 61  d, any data rema
1450: 69 6e 69 6e 67 20 69 6e 20 6d 65 6d 6f 72 79 20  ining in memory 
1460: 69 73 20 66 6c 75 73 68 65 64 20 74 6f 20 61 20  is flushed to a 
1470: 0a 2a 2a 20 66 69 6e 61 6c 20 50 4d 41 2e 20 53  .** final PMA. S
1480: 6f 20 61 74 20 74 68 69 73 20 70 6f 69 6e 74 20  o at this point 
1490: 74 68 65 20 64 61 74 61 20 69 73 20 73 74 6f 72  the data is stor
14a0: 65 64 20 69 6e 20 73 6f 6d 65 20 6e 75 6d 62 65  ed in some numbe
14b0: 72 20 6f 66 20 73 6f 72 74 65 64 0a 2a 2a 20 50  r of sorted.** P
14c0: 4d 41 73 20 77 69 74 68 69 6e 20 74 65 6d 70 6f  MAs within tempo
14d0: 72 61 72 79 20 66 69 6c 65 73 20 6f 6e 20 64 69  rary files on di
14e0: 73 6b 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  sk..**.** If the
14f0: 72 65 20 61 72 65 20 66 65 77 65 72 20 74 68 61  re are fewer tha
1500: 6e 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52  n SORTER_MAX_MER
1510: 47 45 5f 43 4f 55 4e 54 20 50 4d 41 73 20 69 6e  GE_COUNT PMAs in
1520: 20 74 6f 74 61 6c 20 61 6e 64 20 74 68 65 0a 2a   total and the.*
1530: 2a 20 73 6f 72 74 65 72 20 69 73 20 72 75 6e 6e  * sorter is runn
1540: 69 6e 67 20 69 6e 20 73 69 6e 67 6c 65 2d 74 68  ing in single-th
1550: 72 65 61 64 65 64 20 6d 6f 64 65 2c 20 74 68 65  readed mode, the
1560: 6e 20 74 68 65 73 65 20 50 4d 41 73 20 61 72 65  n these PMAs are
1570: 20 6d 65 72 67 65 64 0a 2a 2a 20 69 6e 63 72 65   merged.** incre
1580: 6d 65 6e 74 61 6c 6c 79 20 61 73 20 6b 65 79 73  mentally as keys
1590: 20 61 72 65 20 72 65 74 72 65 69 76 65 64 20 66   are retreived f
15a0: 72 6f 6d 20 74 68 65 20 73 6f 72 74 65 72 20 62  rom the sorter b
15b0: 79 20 74 68 65 20 56 44 42 45 2e 20 53 65 65 0a  y the VDBE. See.
15c0: 2a 2a 20 63 6f 6d 6d 65 6e 74 73 20 61 62 6f 76  ** comments abov
15d0: 65 20 6f 62 6a 65 63 74 20 4d 65 72 67 65 45 6e  e object MergeEn
15e0: 67 69 6e 65 20 62 65 6c 6f 77 20 66 6f 72 20 64  gine below for d
15f0: 65 74 61 69 6c 73 2e 0a 2a 2a 0a 2a 2a 20 4f 72  etails..**.** Or
1600: 2c 20 69 66 20 72 75 6e 6e 69 6e 67 20 69 6e 20  , if running in 
1610: 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20 6d  multi-threaded m
1620: 6f 64 65 2c 20 74 68 65 6e 20 61 20 62 61 63 6b  ode, then a back
1630: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 69 73  ground thread is
1640: 0a 2a 2a 20 6c 61 75 6e 63 68 65 64 20 74 6f 20  .** launched to 
1650: 6d 65 72 67 65 20 74 68 65 20 65 78 69 73 74 69  merge the existi
1660: 6e 67 20 50 4d 41 73 2e 20 4f 6e 63 65 20 74 68  ng PMAs. Once th
1670: 65 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  e background thr
1680: 65 61 64 20 68 61 73 0a 2a 2a 20 6d 65 72 67 65  ead has.** merge
1690: 64 20 54 20 62 79 74 65 73 20 6f 66 20 64 61 74  d T bytes of dat
16a0: 61 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65 20  a into a single 
16b0: 73 6f 72 74 65 64 20 50 4d 41 2c 20 74 68 65 20  sorted PMA, the 
16c0: 6d 61 69 6e 20 74 68 72 65 61 64 20 0a 2a 2a 20  main thread .** 
16d0: 62 65 67 69 6e 73 20 72 65 61 64 69 6e 67 20 6b  begins reading k
16e0: 65 79 73 20 66 72 6f 6d 20 74 68 61 74 20 50 4d  eys from that PM
16f0: 41 20 77 68 69 6c 65 20 74 68 65 20 62 61 63 6b  A while the back
1700: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 70 72  ground thread pr
1710: 6f 63 65 65 64 73 0a 2a 2a 20 77 69 74 68 20 6d  oceeds.** with m
1720: 65 72 67 69 6e 67 20 74 68 65 20 6e 65 78 74 20  erging the next 
1730: 54 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 2e  T bytes of data.
1740: 20 41 6e 64 20 73 6f 20 6f 6e 2e 0a 2a 2a 0a 2a   And so on..**.*
1750: 2a 20 50 61 72 61 6d 65 74 65 72 20 54 20 69 73  * Parameter T is
1760: 20 73 65 74 20 74 6f 20 68 61 6c 66 20 74 68 65   set to half the
1770: 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 6d 65   value of the me
1780: 6d 6f 72 79 20 74 68 72 65 73 68 6f 6c 64 20 75  mory threshold u
1790: 73 65 64 20 0a 2a 2a 20 62 79 20 57 72 69 74 65  sed .** by Write
17a0: 28 29 20 61 62 6f 76 65 20 74 6f 20 64 65 74 65  () above to dete
17b0: 72 6d 69 6e 65 20 77 68 65 6e 20 74 6f 20 63 72  rmine when to cr
17c0: 65 61 74 65 20 61 20 6e 65 77 20 50 4d 41 2e 0a  eate a new PMA..
17d0: 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65 20 61  **.** If there a
17e0: 72 65 20 6d 6f 72 65 20 74 68 61 6e 20 53 4f 52  re more than SOR
17f0: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
1800: 55 4e 54 20 50 4d 41 73 20 69 6e 20 74 6f 74 61  UNT PMAs in tota
1810: 6c 20 77 68 65 6e 20 0a 2a 2a 20 52 65 77 69 6e  l when .** Rewin
1820: 64 28 29 20 69 73 20 63 61 6c 6c 65 64 2c 20 74  d() is called, t
1830: 68 65 6e 20 61 20 68 69 65 72 61 72 63 68 79 20  hen a hierarchy 
1840: 6f 66 20 69 6e 63 72 65 6d 65 6e 74 61 6c 2d 6d  of incremental-m
1850: 65 72 67 65 73 20 69 73 20 75 73 65 64 2e 20 0a  erges is used. .
1860: 2a 2a 20 46 69 72 73 74 2c 20 54 20 62 79 74 65  ** First, T byte
1870: 73 20 6f 66 20 64 61 74 61 20 66 72 6f 6d 20 74  s of data from t
1880: 68 65 20 66 69 72 73 74 20 53 4f 52 54 45 52 5f  he first SORTER_
1890: 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20  MAX_MERGE_COUNT 
18a0: 50 4d 41 73 20 6f 6e 20 0a 2a 2a 20 64 69 73 6b  PMAs on .** disk
18b0: 20 61 72 65 20 6d 65 72 67 65 64 20 74 6f 67 65   are merged toge
18c0: 74 68 65 72 2e 20 54 68 65 6e 20 54 20 62 79 74  ther. Then T byt
18d0: 65 73 20 6f 66 20 64 61 74 61 20 66 72 6f 6d 20  es of data from 
18e0: 74 68 65 20 73 65 63 6f 6e 64 20 73 65 74 2c 20  the second set, 
18f0: 61 6e 64 0a 2a 2a 20 73 6f 20 6f 6e 2c 20 73 75  and.** so on, su
1900: 63 68 20 74 68 61 74 20 6e 6f 20 6f 70 65 72 61  ch that no opera
1910: 74 69 6f 6e 20 65 76 65 72 20 6d 65 72 67 65 73  tion ever merges
1920: 20 6d 6f 72 65 20 74 68 61 6e 20 53 4f 52 54 45   more than SORTE
1930: 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
1940: 54 0a 2a 2a 20 50 4d 41 73 20 61 74 20 61 20 74  T.** PMAs at a t
1950: 69 6d 65 2e 20 54 68 69 73 20 64 6f 6e 65 20 69  ime. This done i
1960: 73 20 74 6f 20 69 6d 70 72 6f 76 65 20 6c 6f 63  s to improve loc
1970: 61 6c 69 74 79 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  ality..**.** If 
1980: 72 75 6e 6e 69 6e 67 20 69 6e 20 6d 75 6c 74 69  running in multi
1990: 2d 74 68 72 65 61 64 65 64 20 6d 6f 64 65 20 61  -threaded mode a
19a0: 6e 64 20 74 68 65 72 65 20 61 72 65 20 6d 6f 72  nd there are mor
19b0: 65 20 74 68 61 6e 0a 2a 2a 20 53 4f 52 54 45 52  e than.** SORTER
19c0: 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
19d0: 20 50 4d 41 73 20 6f 6e 20 64 69 73 6b 20 77 68   PMAs on disk wh
19e0: 65 6e 20 52 65 77 69 6e 64 28 29 20 69 73 20 63  en Rewind() is c
19f0: 61 6c 6c 65 64 2c 20 74 68 65 6e 20 6d 6f 72 65  alled, then more
1a00: 0a 2a 2a 20 74 68 61 6e 20 6f 6e 65 20 62 61 63  .** than one bac
1a10: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 6d  kground thread m
1a20: 61 79 20 62 65 20 63 72 65 61 74 65 64 2e 20 53  ay be created. S
1a30: 70 65 63 69 66 69 63 61 6c 6c 79 2c 20 74 68 65  pecifically, the
1a40: 72 65 20 6d 61 79 20 62 65 0a 2a 2a 20 6f 6e 65  re may be.** one
1a50: 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65   background thre
1a60: 61 64 20 66 6f 72 20 65 61 63 68 20 74 65 6d 70  ad for each temp
1a70: 6f 72 61 72 79 20 66 69 6c 65 20 6f 6e 20 64 69  orary file on di
1a80: 73 6b 2c 20 61 6e 64 20 6f 6e 65 20 62 61 63 6b  sk, and one back
1a90: 67 72 6f 75 6e 64 0a 2a 2a 20 74 68 72 65 61 64  ground.** thread
1aa0: 20 74 6f 20 6d 65 72 67 65 20 74 68 65 20 6f 75   to merge the ou
1ab0: 74 70 75 74 20 6f 66 20 65 61 63 68 20 6f 66 20  tput of each of 
1ac0: 74 68 65 20 6f 74 68 65 72 73 20 74 6f 20 61 20  the others to a 
1ad0: 73 69 6e 67 6c 65 20 50 4d 41 20 66 6f 72 0a 2a  single PMA for.*
1ae0: 2a 20 74 68 65 20 6d 61 69 6e 20 74 68 72 65 61  * the main threa
1af0: 64 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 2e 0a  d to read from..
1b00: 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c  */.#include "sql
1b10: 69 74 65 49 6e 74 2e 68 22 0a 23 69 6e 63 6c 75  iteInt.h".#inclu
1b20: 64 65 20 22 76 64 62 65 49 6e 74 2e 68 22 0a 0a  de "vdbeInt.h"..
1b30: 2f 2a 20 0a 2a 2a 20 49 66 20 53 51 4c 49 54 45  /* .** If SQLITE
1b40: 5f 44 45 42 55 47 5f 53 4f 52 54 45 52 5f 54 48  _DEBUG_SORTER_TH
1b50: 52 45 41 44 53 20 69 73 20 64 65 66 69 6e 65 64  READS is defined
1b60: 2c 20 74 68 69 73 20 6d 6f 64 75 6c 65 20 6f 75  , this module ou
1b70: 74 70 75 74 73 20 76 61 72 69 6f 75 73 0a 2a 2a  tputs various.**
1b80: 20 6d 65 73 73 61 67 65 73 20 74 6f 20 73 74 64   messages to std
1b90: 65 72 72 20 74 68 61 74 20 6d 61 79 20 62 65 20  err that may be 
1ba0: 68 65 6c 70 66 75 6c 20 69 6e 20 75 6e 64 65 72  helpful in under
1bb0: 73 74 61 6e 64 69 6e 67 20 74 68 65 20 70 65 72  standing the per
1bc0: 66 6f 72 6d 61 6e 63 65 0a 2a 2a 20 63 68 61 72  formance.** char
1bd0: 61 63 74 65 72 69 73 74 69 63 73 20 6f 66 20 74  acteristics of t
1be0: 68 65 20 73 6f 72 74 65 72 20 69 6e 20 6d 75 6c  he sorter in mul
1bf0: 74 69 2d 74 68 72 65 61 64 65 64 20 6d 6f 64 65  ti-threaded mode
1c00: 2e 0a 2a 2f 0a 23 69 66 20 30 0a 23 20 64 65 66  ..*/.#if 0.# def
1c10: 69 6e 65 20 53 51 4c 49 54 45 5f 44 45 42 55 47  ine SQLITE_DEBUG
1c20: 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44 53 20  _SORTER_THREADS 
1c30: 31 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20  1.#endif../*.** 
1c40: 50 72 69 76 61 74 65 20 6f 62 6a 65 63 74 73 20  Private objects 
1c50: 75 73 65 64 20 62 79 20 74 68 65 20 73 6f 72 74  used by the sort
1c60: 65 72 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74  er.*/.typedef st
1c70: 72 75 63 74 20 4d 65 72 67 65 45 6e 67 69 6e 65  ruct MergeEngine
1c80: 20 4d 65 72 67 65 45 6e 67 69 6e 65 3b 20 20 20   MergeEngine;   
1c90: 20 20 2f 2a 20 4d 65 72 67 65 20 50 4d 41 73 20    /* Merge PMAs 
1ca0: 74 6f 67 65 74 68 65 72 20 2a 2f 0a 74 79 70 65  together */.type
1cb0: 64 65 66 20 73 74 72 75 63 74 20 50 6d 61 52 65  def struct PmaRe
1cc0: 61 64 65 72 20 50 6d 61 52 65 61 64 65 72 3b 20  ader PmaReader; 
1cd0: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 63 72 65          /* Incre
1ce0: 6d 65 6e 74 61 6c 6c 79 20 72 65 61 64 20 6f 6e  mentally read on
1cf0: 65 20 50 4d 41 20 2a 2f 0a 74 79 70 65 64 65 66  e PMA */.typedef
1d00: 20 73 74 72 75 63 74 20 50 6d 61 57 72 69 74 65   struct PmaWrite
1d10: 72 20 50 6d 61 57 72 69 74 65 72 3b 20 20 20 20  r PmaWriter;    
1d20: 20 20 20 20 20 2f 2a 20 49 6e 63 72 65 6d 65 6e       /* Incremen
1d30: 74 61 6c 6c 79 20 77 72 69 74 65 20 6f 6e 65 20  tally write one 
1d40: 50 4d 41 20 2a 2f 0a 74 79 70 65 64 65 66 20 73  PMA */.typedef s
1d50: 74 72 75 63 74 20 53 6f 72 74 65 72 52 65 63 6f  truct SorterReco
1d60: 72 64 20 53 6f 72 74 65 72 52 65 63 6f 72 64 3b  rd SorterRecord;
1d70: 20 20 20 2f 2a 20 41 20 72 65 63 6f 72 64 20 62     /* A record b
1d80: 65 69 6e 67 20 73 6f 72 74 65 64 20 2a 2f 0a 74  eing sorted */.t
1d90: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53 6f  ypedef struct So
1da0: 72 74 53 75 62 74 61 73 6b 20 53 6f 72 74 53 75  rtSubtask SortSu
1db0: 62 74 61 73 6b 3b 20 20 20 20 20 2f 2a 20 41 20  btask;     /* A 
1dc0: 73 75 62 2d 74 61 73 6b 20 69 6e 20 74 68 65 20  sub-task in the 
1dd0: 73 6f 72 74 20 70 72 6f 63 65 73 73 20 2a 2f 0a  sort process */.
1de0: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53  typedef struct S
1df0: 6f 72 74 65 72 46 69 6c 65 20 53 6f 72 74 65 72  orterFile Sorter
1e00: 46 69 6c 65 3b 20 20 20 20 20 20 20 2f 2a 20 54  File;       /* T
1e10: 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 20 6f 62  emporary file ob
1e20: 6a 65 63 74 20 77 72 61 70 70 65 72 20 2a 2f 0a  ject wrapper */.
1e30: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53  typedef struct S
1e40: 6f 72 74 65 72 4c 69 73 74 20 53 6f 72 74 65 72  orterList Sorter
1e50: 4c 69 73 74 3b 20 20 20 20 20 20 20 2f 2a 20 49  List;       /* I
1e60: 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20 6f 66  n-memory list of
1e70: 20 72 65 63 6f 72 64 73 20 2a 2f 0a 74 79 70 65   records */.type
1e80: 64 65 66 20 73 74 72 75 63 74 20 49 6e 63 72 4d  def struct IncrM
1e90: 65 72 67 65 72 20 49 6e 63 72 4d 65 72 67 65 72  erger IncrMerger
1ea0: 3b 20 20 20 20 20 20 20 2f 2a 20 52 65 61 64 20  ;       /* Read 
1eb0: 26 20 6d 65 72 67 65 20 6d 75 6c 74 69 70 6c 65  & merge multiple
1ec0: 20 50 4d 41 73 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20   PMAs */../*.** 
1ed0: 41 20 63 6f 6e 74 61 69 6e 65 72 20 66 6f 72 20  A container for 
1ee0: 61 20 74 65 6d 70 20 66 69 6c 65 20 68 61 6e 64  a temp file hand
1ef0: 6c 65 20 61 6e 64 20 74 68 65 20 63 75 72 72 65  le and the curre
1f00: 6e 74 20 61 6d 6f 75 6e 74 20 6f 66 20 64 61 74  nt amount of dat
1f10: 61 20 0a 2a 2a 20 73 74 6f 72 65 64 20 69 6e 20  a .** stored in 
1f20: 74 68 65 20 66 69 6c 65 2e 0a 2a 2f 0a 73 74 72  the file..*/.str
1f30: 75 63 74 20 53 6f 72 74 65 72 46 69 6c 65 20 7b  uct SorterFile {
1f40: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
1f50: 2a 70 46 64 3b 20 20 20 20 20 20 20 20 20 20 20  *pFd;           
1f60: 20 20 20 2f 2a 20 46 69 6c 65 20 68 61 6e 64 6c     /* File handl
1f70: 65 20 2a 2f 0a 20 20 69 36 34 20 69 45 6f 66 3b  e */.  i64 iEof;
1f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f90: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
1fa0: 6f 66 20 64 61 74 61 20 73 74 6f 72 65 64 20 69  of data stored i
1fb0: 6e 20 70 46 64 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  n pFd */.};../*.
1fc0: 2a 2a 20 41 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20  ** An in-memory 
1fd0: 6c 69 73 74 20 6f 66 20 6f 62 6a 65 63 74 73 20  list of objects 
1fe0: 74 6f 20 62 65 20 73 6f 72 74 65 64 2e 0a 2a 2a  to be sorted..**
1ff0: 0a 2a 2a 20 49 66 20 61 4d 65 6d 6f 72 79 3d 3d  .** If aMemory==
2000: 30 20 74 68 65 6e 20 65 61 63 68 20 6f 62 6a 65  0 then each obje
2010: 63 74 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 20  ct is allocated 
2020: 73 65 70 61 72 61 74 65 6c 79 20 61 6e 64 20 74  separately and t
2030: 68 65 20 6f 62 6a 65 63 74 73 0a 2a 2a 20 61 72  he objects.** ar
2040: 65 20 63 6f 6e 6e 65 63 74 65 64 20 75 73 69 6e  e connected usin
2050: 67 20 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 75  g SorterRecord.u
2060: 2e 70 4e 65 78 74 2e 20 20 49 66 20 61 4d 65 6d  .pNext.  If aMem
2070: 6f 72 79 21 3d 30 20 74 68 65 6e 20 61 6c 6c 20  ory!=0 then all 
2080: 6f 62 6a 65 63 74 73 0a 2a 2a 20 61 72 65 20 73  objects.** are s
2090: 74 6f 72 65 64 20 69 6e 20 74 68 65 20 61 4d 65  tored in the aMe
20a0: 6d 6f 72 79 5b 5d 20 62 75 6c 6b 20 6d 65 6d 6f  mory[] bulk memo
20b0: 72 79 2c 20 6f 6e 65 20 72 69 67 68 74 20 61 66  ry, one right af
20c0: 74 65 72 20 74 68 65 20 6f 74 68 65 72 2c 20 61  ter the other, a
20d0: 6e 64 0a 2a 2a 20 61 72 65 20 63 6f 6e 6e 65 63  nd.** are connec
20e0: 74 65 64 20 75 73 69 6e 67 20 53 6f 72 74 65 72  ted using Sorter
20f0: 52 65 63 6f 72 64 2e 75 2e 69 4e 65 78 74 2e 0a  Record.u.iNext..
2100: 2a 2f 0a 73 74 72 75 63 74 20 53 6f 72 74 65 72  */.struct Sorter
2110: 4c 69 73 74 20 7b 0a 20 20 53 6f 72 74 65 72 52  List {.  SorterR
2120: 65 63 6f 72 64 20 2a 70 4c 69 73 74 3b 20 20 20  ecord *pList;   
2130: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 6e 6b           /* Link
2140: 65 64 20 6c 69 73 74 20 6f 66 20 72 65 63 6f 72  ed list of recor
2150: 64 73 20 2a 2f 0a 20 20 75 38 20 2a 61 4d 65 6d  ds */.  u8 *aMem
2160: 6f 72 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  ory;            
2170: 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 6e 6f          /* If no
2180: 6e 2d 4e 55 4c 4c 2c 20 62 75 6c 6b 20 6d 65 6d  n-NULL, bulk mem
2190: 6f 72 79 20 74 6f 20 68 6f 6c 64 20 70 4c 69 73  ory to hold pLis
21a0: 74 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 4d 41  t */.  int szPMA
21b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
21c0: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
21d0: 66 20 70 4c 69 73 74 20 61 73 20 50 4d 41 20 69  f pList as PMA i
21e0: 6e 20 62 79 74 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f  n bytes */.};../
21f0: 2a 0a 2a 2a 20 54 68 65 20 4d 65 72 67 65 45 6e  *.** The MergeEn
2200: 67 69 6e 65 20 6f 62 6a 65 63 74 20 69 73 20 75  gine object is u
2210: 73 65 64 20 74 6f 20 63 6f 6d 62 69 6e 65 20 74  sed to combine t
2220: 77 6f 20 6f 72 20 6d 6f 72 65 20 73 6d 61 6c 6c  wo or more small
2230: 65 72 20 50 4d 41 73 20 69 6e 74 6f 0a 2a 2a 20  er PMAs into.** 
2240: 6f 6e 65 20 62 69 67 20 50 4d 41 20 75 73 69 6e  one big PMA usin
2250: 67 20 61 20 6d 65 72 67 65 20 6f 70 65 72 61 74  g a merge operat
2260: 69 6f 6e 2e 20 20 53 65 70 61 72 61 74 65 20 50  ion.  Separate P
2270: 4d 41 73 20 61 6c 6c 20 6e 65 65 64 20 74 6f 20  MAs all need to 
2280: 62 65 0a 2a 2a 20 63 6f 6d 62 69 6e 65 64 20 69  be.** combined i
2290: 6e 74 6f 20 6f 6e 65 20 62 69 67 20 50 4d 41 20  nto one big PMA 
22a0: 69 6e 20 6f 72 64 65 72 20 74 6f 20 62 65 20 61  in order to be a
22b0: 62 6c 65 20 74 6f 20 73 74 65 70 20 74 68 72 6f  ble to step thro
22c0: 75 67 68 20 74 68 65 20 73 6f 72 74 65 64 0a 2a  ugh the sorted.*
22d0: 2a 20 72 65 63 6f 72 64 73 20 69 6e 20 6f 72 64  * records in ord
22e0: 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 49  er..**.** The aI
22f0: 74 65 72 5b 5d 20 61 72 72 61 79 20 63 6f 6e 74  ter[] array cont
2300: 61 69 6e 73 20 61 20 50 6d 61 52 65 61 64 65 72  ains a PmaReader
2310: 20 6f 62 6a 65 63 74 20 66 6f 72 20 65 61 63 68   object for each
2320: 20 6f 66 20 74 68 65 20 50 4d 41 73 20 62 65 69   of the PMAs bei
2330: 6e 67 0a 2a 2a 20 6d 65 72 67 65 64 2e 20 20 41  ng.** merged.  A
2340: 6e 20 61 49 74 65 72 5b 5d 20 6f 62 6a 65 63 74  n aIter[] object
2350: 20 65 69 74 68 65 72 20 70 6f 69 6e 74 73 20 74   either points t
2360: 6f 20 61 20 76 61 6c 69 64 20 6b 65 79 20 6f 72  o a valid key or
2370: 20 65 6c 73 65 20 69 73 20 61 74 20 45 4f 46 2e   else is at EOF.
2380: 0a 2a 2a 20 46 6f 72 20 74 68 65 20 70 75 72 70  .** For the purp
2390: 6f 73 65 73 20 6f 66 20 74 68 65 20 70 61 72 61  oses of the para
23a0: 67 72 61 70 68 73 20 62 65 6c 6f 77 2c 20 77 65  graphs below, we
23b0: 20 61 73 73 75 6d 65 20 74 68 61 74 20 74 68 65   assume that the
23c0: 20 61 72 72 61 79 20 69 73 0a 2a 2a 20 61 63 74   array is.** act
23d0: 75 61 6c 6c 79 20 4e 20 65 6c 65 6d 65 6e 74 73  ually N elements
23e0: 20 69 6e 20 73 69 7a 65 2c 20 77 68 65 72 65 20   in size, where 
23f0: 4e 20 69 73 20 74 68 65 20 73 6d 61 6c 6c 65 73  N is the smalles
2400: 74 20 70 6f 77 65 72 20 6f 66 20 32 20 67 72 65  t power of 2 gre
2410: 61 74 65 72 0a 2a 2a 20 74 6f 20 6f 72 20 65 71  ater.** to or eq
2420: 75 61 6c 20 74 6f 20 74 68 65 20 6e 75 6d 62 65  ual to the numbe
2430: 72 20 6f 66 20 50 4d 41 73 20 62 65 69 6e 67 20  r of PMAs being 
2440: 6d 65 72 67 65 64 2e 20 54 68 65 20 65 78 74 72  merged. The extr
2450: 61 20 61 49 74 65 72 5b 5d 20 65 6c 65 6d 65 6e  a aIter[] elemen
2460: 74 73 0a 2a 2a 20 61 72 65 20 74 72 65 61 74 65  ts.** are treate
2470: 64 20 61 73 20 69 66 20 74 68 65 79 20 61 72 65  d as if they are
2480: 20 65 6d 70 74 79 20 28 61 6c 77 61 79 73 20 61   empty (always a
2490: 74 20 45 4f 46 29 2e 0a 2a 2a 0a 2a 2a 20 54 68  t EOF)..**.** Th
24a0: 65 20 61 54 72 65 65 5b 5d 20 61 72 72 61 79 20  e aTree[] array 
24b0: 69 73 20 61 6c 73 6f 20 4e 20 65 6c 65 6d 65 6e  is also N elemen
24c0: 74 73 20 69 6e 20 73 69 7a 65 2e 20 54 68 65 20  ts in size. The 
24d0: 76 61 6c 75 65 20 6f 66 20 4e 20 69 73 20 73 74  value of N is st
24e0: 6f 72 65 64 20 69 6e 0a 2a 2a 20 74 68 65 20 4d  ored in.** the M
24f0: 65 72 67 65 45 6e 67 69 6e 65 2e 6e 54 72 65 65  ergeEngine.nTree
2500: 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a   variable..**.**
2510: 20 54 68 65 20 66 69 6e 61 6c 20 28 4e 2f 32 29   The final (N/2)
2520: 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20 61 54 72   elements of aTr
2530: 65 65 5b 5d 20 63 6f 6e 74 61 69 6e 20 74 68 65  ee[] contain the
2540: 20 72 65 73 75 6c 74 73 20 6f 66 20 63 6f 6d 70   results of comp
2550: 61 72 69 6e 67 0a 2a 2a 20 70 61 69 72 73 20 6f  aring.** pairs o
2560: 66 20 50 4d 41 20 6b 65 79 73 20 74 6f 67 65 74  f PMA keys toget
2570: 68 65 72 2e 20 45 6c 65 6d 65 6e 74 20 69 20 63  her. Element i c
2580: 6f 6e 74 61 69 6e 73 20 74 68 65 20 72 65 73 75  ontains the resu
2590: 6c 74 20 6f 66 20 0a 2a 2a 20 63 6f 6d 70 61 72  lt of .** compar
25a0: 69 6e 67 20 61 49 74 65 72 5b 32 2a 69 2d 4e 5d  ing aIter[2*i-N]
25b0: 20 61 6e 64 20 61 49 74 65 72 5b 32 2a 69 2d 4e   and aIter[2*i-N
25c0: 2b 31 5d 2e 20 57 68 69 63 68 65 76 65 72 20 6b  +1]. Whichever k
25d0: 65 79 20 69 73 20 73 6d 61 6c 6c 65 72 2c 20 74  ey is smaller, t
25e0: 68 65 0a 2a 2a 20 61 54 72 65 65 20 65 6c 65 6d  he.** aTree elem
25f0: 65 6e 74 20 69 73 20 73 65 74 20 74 6f 20 74 68  ent is set to th
2600: 65 20 69 6e 64 65 78 20 6f 66 20 69 74 2e 20 0a  e index of it. .
2610: 2a 2a 0a 2a 2a 20 46 6f 72 20 74 68 65 20 70 75  **.** For the pu
2620: 72 70 6f 73 65 73 20 6f 66 20 74 68 69 73 20 63  rposes of this c
2630: 6f 6d 70 61 72 69 73 6f 6e 2c 20 45 4f 46 20 69  omparison, EOF i
2640: 73 20 63 6f 6e 73 69 64 65 72 65 64 20 67 72 65  s considered gre
2650: 61 74 65 72 20 74 68 61 6e 20 61 6e 79 0a 2a 2a  ater than any.**
2660: 20 6f 74 68 65 72 20 6b 65 79 20 76 61 6c 75 65   other key value
2670: 2e 20 49 66 20 74 68 65 20 6b 65 79 73 20 61 72  . If the keys ar
2680: 65 20 65 71 75 61 6c 20 28 6f 6e 6c 79 20 70 6f  e equal (only po
2690: 73 73 69 62 6c 65 20 77 69 74 68 20 74 77 6f 20  ssible with two 
26a0: 45 4f 46 0a 2a 2a 20 76 61 6c 75 65 73 29 2c 20  EOF.** values), 
26b0: 69 74 20 64 6f 65 73 6e 27 74 20 6d 61 74 74 65  it doesn't matte
26c0: 72 20 77 68 69 63 68 20 69 6e 64 65 78 20 69 73  r which index is
26d0: 20 73 74 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 54   stored..**.** T
26e0: 68 65 20 28 4e 2f 34 29 20 65 6c 65 6d 65 6e 74  he (N/4) element
26f0: 73 20 6f 66 20 61 54 72 65 65 5b 5d 20 74 68 61  s of aTree[] tha
2700: 74 20 70 72 65 63 65 64 65 20 74 68 65 20 66 69  t precede the fi
2710: 6e 61 6c 20 28 4e 2f 32 29 20 64 65 73 63 72 69  nal (N/2) descri
2720: 62 65 64 20 0a 2a 2a 20 61 62 6f 76 65 20 63 6f  bed .** above co
2730: 6e 74 61 69 6e 73 20 74 68 65 20 69 6e 64 65 78  ntains the index
2740: 20 6f 66 20 74 68 65 20 73 6d 61 6c 6c 65 73 74   of the smallest
2750: 20 6f 66 20 65 61 63 68 20 62 6c 6f 63 6b 20 6f   of each block o
2760: 66 20 34 20 69 74 65 72 61 74 6f 72 73 2e 0a 2a  f 4 iterators..*
2770: 2a 20 41 6e 64 20 73 6f 20 6f 6e 2e 20 53 6f 20  * And so on. So 
2780: 74 68 61 74 20 61 54 72 65 65 5b 31 5d 20 63 6f  that aTree[1] co
2790: 6e 74 61 69 6e 73 20 74 68 65 20 69 6e 64 65 78  ntains the index
27a0: 20 6f 66 20 74 68 65 20 69 74 65 72 61 74 6f 72   of the iterator
27b0: 20 74 68 61 74 20 0a 2a 2a 20 63 75 72 72 65 6e   that .** curren
27c0: 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f 20 74 68  tly points to th
27d0: 65 20 73 6d 61 6c 6c 65 73 74 20 6b 65 79 20 76  e smallest key v
27e0: 61 6c 75 65 2e 20 61 54 72 65 65 5b 30 5d 20 69  alue. aTree[0] i
27f0: 73 20 75 6e 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20  s unused..**.** 
2800: 45 78 61 6d 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20  Example:.**.**  
2810: 20 20 20 61 49 74 65 72 5b 30 5d 20 2d 3e 20 42     aIter[0] -> B
2820: 61 6e 61 6e 61 0a 2a 2a 20 20 20 20 20 61 49 74  anana.**     aIt
2830: 65 72 5b 31 5d 20 2d 3e 20 46 65 69 6a 6f 61 0a  er[1] -> Feijoa.
2840: 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 32 5d 20  **     aIter[2] 
2850: 2d 3e 20 45 6c 64 65 72 62 65 72 72 79 0a 2a 2a  -> Elderberry.**
2860: 20 20 20 20 20 61 49 74 65 72 5b 33 5d 20 2d 3e       aIter[3] ->
2870: 20 43 75 72 72 61 6e 74 0a 2a 2a 20 20 20 20 20   Currant.**     
2880: 61 49 74 65 72 5b 34 5d 20 2d 3e 20 47 72 61 70  aIter[4] -> Grap
2890: 65 66 72 75 69 74 0a 2a 2a 20 20 20 20 20 61 49  efruit.**     aI
28a0: 74 65 72 5b 35 5d 20 2d 3e 20 41 70 70 6c 65 0a  ter[5] -> Apple.
28b0: 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 36 5d 20  **     aIter[6] 
28c0: 2d 3e 20 44 75 72 69 61 6e 0a 2a 2a 20 20 20 20  -> Durian.**    
28d0: 20 61 49 74 65 72 5b 37 5d 20 2d 3e 20 45 4f 46   aIter[7] -> EOF
28e0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 54 72 65 65  .**.**     aTree
28f0: 5b 5d 20 3d 20 7b 20 58 2c 20 35 20 20 20 30 2c  [] = { X, 5   0,
2900: 20 35 20 20 20 20 30 2c 20 33 2c 20 35 2c 20 36   5    0, 3, 5, 6
2910: 20 7d 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 75 72   }.**.** The cur
2920: 72 65 6e 74 20 65 6c 65 6d 65 6e 74 20 69 73 20  rent element is 
2930: 22 41 70 70 6c 65 22 20 28 74 68 65 20 76 61 6c  "Apple" (the val
2940: 75 65 20 6f 66 20 74 68 65 20 6b 65 79 20 69 6e  ue of the key in
2950: 64 69 63 61 74 65 64 20 62 79 20 0a 2a 2a 20 69  dicated by .** i
2960: 74 65 72 61 74 6f 72 20 35 29 2e 20 57 68 65 6e  terator 5). When
2970: 20 74 68 65 20 4e 65 78 74 28 29 20 6f 70 65 72   the Next() oper
2980: 61 74 69 6f 6e 20 69 73 20 69 6e 76 6f 6b 65 64  ation is invoked
2990: 2c 20 69 74 65 72 61 74 6f 72 20 35 20 77 69 6c  , iterator 5 wil
29a0: 6c 0a 2a 2a 20 62 65 20 61 64 76 61 6e 63 65 64  l.** be advanced
29b0: 20 74 6f 20 74 68 65 20 6e 65 78 74 20 6b 65 79   to the next key
29c0: 20 69 6e 20 69 74 73 20 73 65 67 6d 65 6e 74 2e   in its segment.
29d0: 20 53 61 79 20 74 68 65 20 6e 65 78 74 20 6b 65   Say the next ke
29e0: 79 20 69 73 0a 2a 2a 20 22 45 67 67 70 6c 61 6e  y is.** "Eggplan
29f0: 74 22 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 49  t":.**.**     aI
2a00: 74 65 72 5b 35 5d 20 2d 3e 20 45 67 67 70 6c 61  ter[5] -> Eggpla
2a10: 6e 74 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f 6e  nt.**.** The con
2a20: 74 65 6e 74 73 20 6f 66 20 61 54 72 65 65 5b 5d  tents of aTree[]
2a30: 20 61 72 65 20 75 70 64 61 74 65 64 20 66 69 72   are updated fir
2a40: 73 74 20 62 79 20 63 6f 6d 70 61 72 69 6e 67 20  st by comparing 
2a50: 74 68 65 20 6e 65 77 20 69 74 65 72 61 74 6f 72  the new iterator
2a60: 0a 2a 2a 20 35 20 6b 65 79 20 74 6f 20 74 68 65  .** 5 key to the
2a70: 20 63 75 72 72 65 6e 74 20 6b 65 79 20 6f 66 20   current key of 
2a80: 69 74 65 72 61 74 6f 72 20 34 20 28 73 74 69 6c  iterator 4 (stil
2a90: 6c 20 22 47 72 61 70 65 66 72 75 69 74 22 29 2e  l "Grapefruit").
2aa0: 20 54 68 65 20 69 74 65 72 61 74 6f 72 0a 2a 2a   The iterator.**
2ab0: 20 35 20 76 61 6c 75 65 20 69 73 20 73 74 69 6c   5 value is stil
2ac0: 6c 20 73 6d 61 6c 6c 65 72 2c 20 73 6f 20 61 54  l smaller, so aT
2ad0: 72 65 65 5b 36 5d 20 69 73 20 73 65 74 20 74 6f  ree[6] is set to
2ae0: 20 35 2e 20 41 6e 64 20 73 6f 20 6f 6e 20 75 70   5. And so on up
2af0: 20 74 68 65 20 74 72 65 65 2e 0a 2a 2a 20 54 68   the tree..** Th
2b00: 65 20 76 61 6c 75 65 20 6f 66 20 69 74 65 72 61  e value of itera
2b10: 74 6f 72 20 36 20 2d 20 22 44 75 72 69 61 6e 22  tor 6 - "Durian"
2b20: 20 2d 20 69 73 20 6e 6f 77 20 73 6d 61 6c 6c 65   - is now smalle
2b30: 72 20 74 68 61 6e 20 74 68 61 74 20 6f 66 20 69  r than that of i
2b40: 74 65 72 61 74 6f 72 0a 2a 2a 20 35 2c 20 73 6f  terator.** 5, so
2b50: 20 61 54 72 65 65 5b 33 5d 20 69 73 20 73 65 74   aTree[3] is set
2b60: 20 74 6f 20 36 2e 20 4b 65 79 20 30 20 69 73 20   to 6. Key 0 is 
2b70: 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 6b 65 79  smaller than key
2b80: 20 36 20 28 42 61 6e 61 6e 61 3c 44 75 72 69 61   6 (Banana<Duria
2b90: 6e 29 2c 0a 2a 2a 20 73 6f 20 74 68 65 20 76 61  n),.** so the va
2ba0: 6c 75 65 20 77 72 69 74 74 65 6e 20 69 6e 74 6f  lue written into
2bb0: 20 65 6c 65 6d 65 6e 74 20 31 20 6f 66 20 74 68   element 1 of th
2bc0: 65 20 61 72 72 61 79 20 69 73 20 30 2e 20 41 73  e array is 0. As
2bd0: 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20   follows:.**.** 
2be0: 20 20 20 20 61 54 72 65 65 5b 5d 20 3d 20 7b 20      aTree[] = { 
2bf0: 58 2c 20 30 20 20 20 30 2c 20 36 20 20 20 20 30  X, 0   0, 6    0
2c00: 2c 20 33 2c 20 35 2c 20 36 20 7d 0a 2a 2a 0a 2a  , 3, 5, 6 }.**.*
2c10: 2a 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64 73  * In other words
2c20: 2c 20 65 61 63 68 20 74 69 6d 65 20 77 65 20 61  , each time we a
2c30: 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20 6e 65  dvance to the ne
2c40: 78 74 20 73 6f 72 74 65 72 20 65 6c 65 6d 65 6e  xt sorter elemen
2c50: 74 2c 20 6c 6f 67 32 28 4e 29 0a 2a 2a 20 6b 65  t, log2(N).** ke
2c60: 79 20 63 6f 6d 70 61 72 69 73 6f 6e 20 6f 70 65  y comparison ope
2c70: 72 61 74 69 6f 6e 73 20 61 72 65 20 72 65 71 75  rations are requ
2c80: 69 72 65 64 2c 20 77 68 65 72 65 20 4e 20 69 73  ired, where N is
2c90: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 73   the number of s
2ca0: 65 67 6d 65 6e 74 73 0a 2a 2a 20 62 65 69 6e 67  egments.** being
2cb0: 20 6d 65 72 67 65 64 20 28 72 6f 75 6e 64 65 64   merged (rounded
2cc0: 20 75 70 20 74 6f 20 74 68 65 20 6e 65 78 74 20   up to the next 
2cd0: 70 6f 77 65 72 20 6f 66 20 32 29 2e 0a 2a 2f 0a  power of 2)..*/.
2ce0: 73 74 72 75 63 74 20 4d 65 72 67 65 45 6e 67 69  struct MergeEngi
2cf0: 6e 65 20 7b 0a 20 20 69 6e 74 20 6e 54 72 65 65  ne {.  int nTree
2d00: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
2d10: 20 20 2f 2a 20 55 73 65 64 20 73 69 7a 65 20 6f    /* Used size o
2d20: 66 20 61 54 72 65 65 2f 61 49 74 65 72 20 28 70  f aTree/aIter (p
2d30: 6f 77 65 72 20 6f 66 20 32 29 20 2a 2f 0a 20 20  ower of 2) */.  
2d40: 69 6e 74 20 2a 61 54 72 65 65 3b 20 20 20 20 20  int *aTree;     
2d50: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
2d60: 72 72 65 6e 74 20 73 74 61 74 65 20 6f 66 20 69  rrent state of i
2d70: 6e 63 72 65 6d 65 6e 74 61 6c 20 6d 65 72 67 65  ncremental merge
2d80: 20 2a 2f 0a 20 20 50 6d 61 52 65 61 64 65 72 20   */.  PmaReader 
2d90: 2a 61 49 74 65 72 3b 20 20 20 20 20 20 20 20 20  *aIter;         
2da0: 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 69 74 65   /* Array of ite
2db0: 72 61 74 6f 72 73 20 74 6f 20 6d 65 72 67 65 20  rators to merge 
2dc0: 64 61 74 61 20 66 72 6f 6d 20 2a 2f 0a 7d 3b 0a  data from */.};.
2dd0: 0a 2f 2a 0a 2a 2a 20 45 78 61 63 74 6c 79 20 56  ./*.** Exactly V
2de0: 64 62 65 53 6f 72 74 65 72 2e 6e 54 61 73 6b 20  dbeSorter.nTask 
2df0: 69 6e 73 74 61 6e 63 65 73 20 6f 66 20 74 68 69  instances of thi
2e00: 73 20 6f 62 6a 65 63 74 20 61 72 65 20 61 6c 6c  s object are all
2e10: 6f 63 61 74 65 64 0a 2a 2a 20 61 73 20 70 61 72  ocated.** as par
2e20: 74 20 6f 66 20 65 61 63 68 20 56 64 62 65 53 6f  t of each VdbeSo
2e30: 72 74 65 72 20 6f 62 6a 65 63 74 2e 20 49 6e 73  rter object. Ins
2e40: 74 61 6e 63 65 73 20 61 72 65 20 6e 65 76 65 72  tances are never
2e50: 20 61 6c 6c 6f 63 61 74 65 64 20 61 6e 79 0a 2a   allocated any.*
2e60: 2a 20 6f 74 68 65 72 20 77 61 79 2e 20 56 64 62  * other way. Vdb
2e70: 65 53 6f 72 74 65 72 2e 6e 54 61 73 6b 20 69 73  eSorter.nTask is
2e80: 20 73 65 74 20 74 6f 20 74 68 65 20 6e 75 6d 62   set to the numb
2e90: 65 72 20 6f 66 20 77 6f 72 6b 65 72 20 74 68 72  er of worker thr
2ea0: 65 61 64 73 20 61 6c 6c 6f 77 65 64 0a 2a 2a 20  eads allowed.** 
2eb0: 28 73 65 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46  (see SQLITE_CONF
2ec0: 49 47 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44  IG_WORKER_THREAD
2ed0: 53 29 20 70 6c 75 73 20 6f 6e 65 20 28 74 68 65  S) plus one (the
2ee0: 20 6d 61 69 6e 20 74 68 72 65 61 64 29 2e 0a 2a   main thread)..*
2ef0: 2a 0a 2a 2a 20 45 73 73 65 6e 74 69 61 6c 6c 79  *.** Essentially
2f00: 2c 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65  , this structure
2f10: 20 63 6f 6e 74 61 69 6e 73 20 61 6c 6c 20 74 68   contains all th
2f20: 6f 73 65 20 66 69 65 6c 64 73 20 6f 66 20 74 68  ose fields of th
2f30: 65 20 56 64 62 65 53 6f 72 74 65 72 0a 2a 2a 20  e VdbeSorter.** 
2f40: 73 74 72 75 63 74 75 72 65 20 66 6f 72 20 77 68  structure for wh
2f50: 69 63 68 20 65 61 63 68 20 74 68 72 65 61 64 20  ich each thread 
2f60: 72 65 71 75 69 72 65 73 20 61 20 73 65 70 61 72  requires a separ
2f70: 61 74 65 20 69 6e 73 74 61 6e 63 65 2e 20 46 6f  ate instance. Fo
2f80: 72 20 65 78 61 6d 70 6c 65 2c 0a 2a 2a 20 65 61  r example,.** ea
2f90: 63 68 20 74 68 72 65 61 64 20 72 65 71 75 72 69  ch thread requri
2fa0: 65 73 20 69 74 73 20 6f 77 6e 20 55 6e 70 61 63  es its own Unpac
2fb0: 6b 65 64 52 65 63 6f 72 64 20 6f 62 6a 65 63 74  kedRecord object
2fc0: 20 74 6f 20 75 6e 70 61 63 6b 20 72 65 63 6f 72   to unpack recor
2fd0: 64 73 20 69 6e 0a 2a 2a 20 61 73 20 70 61 72 74  ds in.** as part
2fe0: 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 6f   of comparison o
2ff0: 70 65 72 61 74 69 6f 6e 73 2e 0a 2a 2a 0a 2a 2a  perations..**.**
3000: 20 42 65 66 6f 72 65 20 61 20 62 61 63 6b 67 72   Before a backgr
3010: 6f 75 6e 64 20 74 68 72 65 61 64 20 69 73 20 6c  ound thread is l
3020: 61 75 6e 63 68 65 64 2c 20 76 61 72 69 61 62 6c  aunched, variabl
3030: 65 20 62 44 6f 6e 65 20 69 73 20 73 65 74 20 74  e bDone is set t
3040: 6f 20 30 2e 20 54 68 65 6e 2c 20 0a 2a 2a 20 72  o 0. Then, .** r
3050: 69 67 68 74 20 62 65 66 6f 72 65 20 69 74 20 65  ight before it e
3060: 78 69 74 73 2c 20 74 68 65 20 74 68 72 65 61 64  xits, the thread
3070: 20 69 74 73 65 6c 66 20 73 65 74 73 20 62 44 6f   itself sets bDo
3080: 6e 65 20 74 6f 20 31 2e 20 54 68 69 73 20 69 73  ne to 1. This is
3090: 20 75 73 65 64 20 66 6f 72 20 0a 2a 2a 20 74 77   used for .** tw
30a0: 6f 20 70 75 72 70 6f 73 65 73 3a 0a 2a 2a 0a 2a  o purposes:.**.*
30b0: 2a 20 20 20 31 2e 20 57 68 65 6e 20 66 6c 75 73  *   1. When flus
30c0: 68 69 6e 67 20 74 68 65 20 63 6f 6e 74 65 6e 74  hing the content
30d0: 73 20 6f 66 20 6d 65 6d 6f 72 79 20 74 6f 20 61  s of memory to a
30e0: 20 6c 65 76 65 6c 2d 30 20 50 4d 41 20 6f 6e 20   level-0 PMA on 
30f0: 64 69 73 6b 2c 20 74 6f 0a 2a 2a 20 20 20 20 20  disk, to.**     
3100: 20 61 74 74 65 6d 70 74 20 74 6f 20 73 65 6c 65   attempt to sele
3110: 63 74 20 61 20 53 6f 72 74 53 75 62 74 61 73 6b  ct a SortSubtask
3120: 20 66 6f 72 20 77 68 69 63 68 20 74 68 65 72 65   for which there
3130: 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20   is not already 
3140: 61 6e 0a 2a 2a 20 20 20 20 20 20 61 63 74 69 76  an.**      activ
3150: 65 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  e background thr
3160: 65 61 64 20 28 73 69 6e 63 65 20 64 6f 69 6e 67  ead (since doing
3170: 20 73 6f 20 63 61 75 73 65 73 20 74 68 65 20 6d   so causes the m
3180: 61 69 6e 20 74 68 72 65 61 64 0a 2a 2a 20 20 20  ain thread.**   
3190: 20 20 20 74 6f 20 62 6c 6f 63 6b 20 75 6e 74 69     to block unti
31a0: 6c 20 69 74 20 66 69 6e 69 73 68 65 73 29 2e 0a  l it finishes)..
31b0: 2a 2a 0a 2a 2a 20 20 20 32 2e 20 49 66 20 53 51  **.**   2. If SQ
31c0: 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f 52 54 45  LITE_DEBUG_SORTE
31d0: 52 5f 54 48 52 45 41 44 53 20 69 73 20 64 65 66  R_THREADS is def
31e0: 69 6e 65 64 2c 20 74 6f 20 64 65 74 65 72 6d 69  ined, to determi
31f0: 6e 65 20 69 66 20 61 20 63 61 6c 6c 0a 2a 2a 20  ne if a call.** 
3200: 20 20 20 20 20 74 6f 20 73 71 6c 69 74 65 33 54       to sqlite3T
3210: 68 72 65 61 64 4a 6f 69 6e 28 29 20 69 73 20 6c  hreadJoin() is l
3220: 69 6b 65 6c 79 20 74 6f 20 62 6c 6f 63 6b 2e 20  ikely to block. 
3230: 43 61 73 65 73 20 74 68 61 74 20 61 72 65 20 6c  Cases that are l
3240: 69 6b 65 6c 79 20 74 6f 0a 2a 2a 20 20 20 20 20  ikely to.**     
3250: 20 62 6c 6f 63 6b 20 70 72 6f 76 6f 6b 65 20 64   block provoke d
3260: 65 62 75 67 67 69 6e 67 20 6f 75 74 70 75 74 2e  ebugging output.
3270: 0a 2a 2a 0a 2a 2a 20 49 6e 20 62 6f 74 68 20 63  .**.** In both c
3280: 61 73 65 73 2c 20 74 68 65 20 65 66 66 65 63 74  ases, the effect
3290: 73 20 6f 66 20 74 68 65 20 6d 61 69 6e 20 74 68  s of the main th
32a0: 72 65 61 64 20 73 65 65 69 6e 67 20 28 62 44 6f  read seeing (bDo
32b0: 6e 65 3d 3d 30 29 20 65 76 65 6e 0a 2a 2a 20 61  ne==0) even.** a
32c0: 66 74 65 72 20 74 68 65 20 74 68 72 65 61 64 20  fter the thread 
32d0: 68 61 73 20 66 69 6e 69 73 68 65 64 20 61 72 65  has finished are
32e0: 20 6e 6f 74 20 64 69 72 65 2e 20 53 6f 20 77 65   not dire. So we
32f0: 20 64 6f 6e 27 74 20 77 6f 72 72 79 20 61 62 6f   don't worry abo
3300: 75 74 0a 2a 2a 20 6d 65 6d 6f 72 79 20 62 61 72  ut.** memory bar
3310: 72 69 65 72 73 20 61 6e 64 20 73 75 63 68 20 68  riers and such h
3320: 65 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 53  ere..*/.struct S
3330: 6f 72 74 53 75 62 74 61 73 6b 20 7b 0a 20 20 53  ortSubtask {.  S
3340: 51 4c 69 74 65 54 68 72 65 61 64 20 2a 70 54 68  QLiteThread *pTh
3350: 72 65 61 64 3b 20 20 20 20 20 20 20 20 20 20 2f  read;          /
3360: 2a 20 42 61 63 6b 67 72 6f 75 6e 64 20 74 68 72  * Background thr
3370: 65 61 64 2c 20 69 66 20 61 6e 79 20 2a 2f 0a 20  ead, if any */. 
3380: 20 69 6e 74 20 62 44 6f 6e 65 3b 20 20 20 20 20   int bDone;     
3390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
33a0: 20 2f 2a 20 53 65 74 20 69 66 20 74 68 72 65 61   /* Set if threa
33b0: 64 20 69 73 20 66 69 6e 69 73 68 65 64 20 62 75  d is finished bu
33c0: 74 20 6e 6f 74 20 6a 6f 69 6e 65 64 20 2a 2f 0a  t not joined */.
33d0: 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
33e0: 6f 72 74 65 72 3b 20 20 20 20 20 20 20 20 20 20  orter;          
33f0: 20 20 2f 2a 20 53 6f 72 74 65 72 20 74 68 61 74    /* Sorter that
3400: 20 6f 77 6e 73 20 74 68 69 73 20 73 75 62 2d 74   owns this sub-t
3410: 61 73 6b 20 2a 2f 0a 20 20 55 6e 70 61 63 6b 65  ask */.  Unpacke
3420: 64 52 65 63 6f 72 64 20 2a 70 55 6e 70 61 63 6b  dRecord *pUnpack
3430: 65 64 3b 20 20 20 20 20 20 2f 2a 20 53 70 61 63  ed;      /* Spac
3440: 65 20 74 6f 20 75 6e 70 61 63 6b 20 61 20 72 65  e to unpack a re
3450: 63 6f 72 64 20 2a 2f 0a 20 20 53 6f 72 74 65 72  cord */.  Sorter
3460: 4c 69 73 74 20 6c 69 73 74 3b 20 20 20 20 20 20  List list;      
3470: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 73            /* Lis
3480: 74 20 66 6f 72 20 74 68 72 65 61 64 20 74 6f 20  t for thread to 
3490: 77 72 69 74 65 20 74 6f 20 61 20 50 4d 41 20 2a  write to a PMA *
34a0: 2f 0a 20 20 69 6e 74 20 6e 50 4d 41 3b 20 20 20  /.  int nPMA;   
34b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
34c0: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
34d0: 20 50 4d 41 73 20 63 75 72 72 65 6e 74 6c 79 20   PMAs currently 
34e0: 69 6e 20 66 69 6c 65 20 2a 2f 0a 20 20 53 6f 72  in file */.  Sor
34f0: 74 65 72 46 69 6c 65 20 66 69 6c 65 3b 20 20 20  terFile file;   
3500: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3510: 54 65 6d 70 20 66 69 6c 65 20 66 6f 72 20 6c 65  Temp file for le
3520: 76 65 6c 2d 30 20 50 4d 41 73 20 2a 2f 0a 20 20  vel-0 PMAs */.  
3530: 53 6f 72 74 65 72 46 69 6c 65 20 66 69 6c 65 32  SorterFile file2
3540: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
3550: 2f 2a 20 53 70 61 63 65 20 66 6f 72 20 6f 74 68  /* Space for oth
3560: 65 72 20 50 4d 41 73 20 2a 2f 0a 7d 3b 0a 0a 2f  er PMAs */.};../
3570: 2a 0a 2a 2a 20 4d 61 69 6e 20 73 6f 72 74 65 72  *.** Main sorter
3580: 20 73 74 72 75 63 74 75 72 65 2e 20 41 20 73 69   structure. A si
3590: 6e 67 6c 65 20 69 6e 73 74 61 6e 63 65 20 6f 66  ngle instance of
35a0: 20 74 68 69 73 20 69 73 20 61 6c 6c 6f 63 61 74   this is allocat
35b0: 65 64 20 66 6f 72 20 65 61 63 68 20 0a 2a 2a 20  ed for each .** 
35c0: 73 6f 72 74 65 72 20 63 75 72 73 6f 72 20 63 72  sorter cursor cr
35d0: 65 61 74 65 64 20 62 79 20 74 68 65 20 56 44 42  eated by the VDB
35e0: 45 2e 0a 2a 2a 0a 2a 2a 20 6d 78 4b 65 79 73 69  E..**.** mxKeysi
35f0: 7a 65 3a 0a 2a 2a 20 20 20 41 73 20 72 65 63 6f  ze:.**   As reco
3600: 72 64 73 20 61 72 65 20 61 64 64 65 64 20 74 6f  rds are added to
3610: 20 74 68 65 20 73 6f 72 74 65 72 20 62 79 20 63   the sorter by c
3620: 61 6c 6c 73 20 74 6f 20 73 71 6c 69 74 65 33 56  alls to sqlite3V
3630: 64 62 65 53 6f 72 74 65 72 57 72 69 74 65 28 29  dbeSorterWrite()
3640: 2c 0a 2a 2a 20 20 20 74 68 69 73 20 76 61 72 69  ,.**   this vari
3650: 61 62 6c 65 20 69 73 20 75 70 64 61 74 65 64 20  able is updated 
3660: 73 6f 20 61 73 20 74 6f 20 62 65 20 73 65 74 20  so as to be set 
3670: 74 6f 20 74 68 65 20 73 69 7a 65 20 6f 6e 20 64  to the size on d
3680: 69 73 6b 20 6f 66 20 74 68 65 0a 2a 2a 20 20 20  isk of the.**   
3690: 6c 61 72 67 65 73 74 20 72 65 63 6f 72 64 20 69  largest record i
36a0: 6e 20 74 68 65 20 73 6f 72 74 65 72 2e 0a 2a 2f  n the sorter..*/
36b0: 0a 73 74 72 75 63 74 20 56 64 62 65 53 6f 72 74  .struct VdbeSort
36c0: 65 72 20 7b 0a 20 20 69 6e 74 20 6d 6e 50 6d 61  er {.  int mnPma
36d0: 53 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20  Size;           
36e0: 20 20 20 20 20 20 20 2f 2a 20 4d 69 6e 69 6d 75         /* Minimu
36f0: 6d 20 50 4d 41 20 73 69 7a 65 2c 20 69 6e 20 62  m PMA size, in b
3700: 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6d 78  ytes */.  int mx
3710: 50 6d 61 53 69 7a 65 3b 20 20 20 20 20 20 20 20  PmaSize;        
3720: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 78            /* Max
3730: 69 6d 75 6d 20 50 4d 41 20 73 69 7a 65 2c 20 69  imum PMA size, i
3740: 6e 20 62 79 74 65 73 2e 20 20 30 3d 3d 6e 6f 20  n bytes.  0==no 
3750: 6c 69 6d 69 74 20 2a 2f 0a 20 20 69 6e 74 20 6d  limit */.  int m
3760: 78 4b 65 79 73 69 7a 65 3b 20 20 20 20 20 20 20  xKeysize;       
3770: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61             /* La
3780: 72 67 65 73 74 20 73 65 72 69 61 6c 69 7a 65 64  rgest serialized
3790: 20 6b 65 79 20 73 65 65 6e 20 73 6f 20 66 61 72   key seen so far
37a0: 20 2a 2f 0a 20 20 69 6e 74 20 70 67 73 7a 3b 20   */.  int pgsz; 
37b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
37c0: 20 20 20 20 20 20 2f 2a 20 4d 61 69 6e 20 64 61        /* Main da
37d0: 74 61 62 61 73 65 20 70 61 67 65 20 73 69 7a 65  tabase page size
37e0: 20 2a 2f 0a 20 20 50 6d 61 52 65 61 64 65 72 20   */.  PmaReader 
37f0: 2a 70 52 65 61 64 65 72 3b 20 20 20 20 20 20 20  *pReader;       
3800: 20 20 20 20 20 20 2f 2a 20 52 65 61 64 20 64 61        /* Read da
3810: 74 61 20 66 72 6f 6d 20 68 65 72 65 20 61 66 74  ta from here aft
3820: 65 72 20 52 65 77 69 6e 64 28 29 20 2a 2f 0a 20  er Rewind() */. 
3830: 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d   MergeEngine *pM
3840: 65 72 67 65 72 3b 20 20 20 20 20 20 20 20 20 20  erger;          
3850: 20 2f 2a 20 4f 72 20 68 65 72 65 2c 20 69 66 20   /* Or here, if 
3860: 62 55 73 65 54 68 72 65 61 64 73 3d 3d 30 20 2a  bUseThreads==0 *
3870: 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b  /.  sqlite3 *db;
3880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3890: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
38a0: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20  connection */.  
38b0: 4b 65 79 49 6e 66 6f 20 2a 70 4b 65 79 49 6e 66  KeyInfo *pKeyInf
38c0: 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  o;              
38d0: 2f 2a 20 48 6f 77 20 74 6f 20 63 6f 6d 70 61 72  /* How to compar
38e0: 65 20 72 65 63 6f 72 64 73 20 2a 2f 0a 20 20 55  e records */.  U
38f0: 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20 2a 70  npackedRecord *p
3900: 55 6e 70 61 63 6b 65 64 3b 20 20 20 20 20 20 2f  Unpacked;      /
3910: 2a 20 55 73 65 64 20 62 79 20 56 64 62 65 53 6f  * Used by VdbeSo
3920: 72 74 65 72 43 6f 6d 70 61 72 65 28 29 20 2a 2f  rterCompare() */
3930: 0a 20 20 53 6f 72 74 65 72 4c 69 73 74 20 6c 69  .  SorterList li
3940: 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  st;             
3950: 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20 69 6e     /* List of in
3960: 2d 6d 65 6d 6f 72 79 20 72 65 63 6f 72 64 73 20  -memory records 
3970: 2a 2f 0a 20 20 69 6e 74 20 69 4d 65 6d 6f 72 79  */.  int iMemory
3980: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
3990: 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 6f       /* Offset o
39a0: 66 20 66 72 65 65 20 73 70 61 63 65 20 69 6e 20  f free space in 
39b0: 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 2a 2f 0a  list.aMemory */.
39c0: 20 20 69 6e 74 20 6e 4d 65 6d 6f 72 79 3b 20 20    int nMemory;  
39d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
39e0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 6c 69 73    /* Size of lis
39f0: 74 2e 61 4d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61  t.aMemory alloca
3a00: 74 69 6f 6e 20 69 6e 20 62 79 74 65 73 20 2a 2f  tion in bytes */
3a10: 0a 20 20 75 38 20 62 55 73 65 50 4d 41 3b 20 20  .  u8 bUsePMA;  
3a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a30: 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 6f 6e     /* True if on
3a40: 65 20 6f 72 20 6d 6f 72 65 20 50 4d 41 73 20 63  e or more PMAs c
3a50: 72 65 61 74 65 64 20 2a 2f 0a 20 20 75 38 20 62  reated */.  u8 b
3a60: 55 73 65 54 68 72 65 61 64 73 3b 20 20 20 20 20  UseThreads;     
3a70: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
3a80: 72 75 65 20 74 6f 20 75 73 65 20 62 61 63 6b 67  rue to use backg
3a90: 72 6f 75 6e 64 20 74 68 72 65 61 64 73 20 2a 2f  round threads */
3aa0: 0a 20 20 75 38 20 69 50 72 65 76 3b 20 20 20 20  .  u8 iPrev;    
3ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3ac0: 20 20 20 2f 2a 20 50 72 65 76 69 6f 75 73 20 74     /* Previous t
3ad0: 68 72 65 61 64 20 75 73 65 64 20 74 6f 20 66 6c  hread used to fl
3ae0: 75 73 68 20 50 4d 41 20 2a 2f 0a 20 20 75 38 20  ush PMA */.  u8 
3af0: 6e 54 61 73 6b 3b 20 20 20 20 20 20 20 20 20 20  nTask;          
3b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3b10: 53 69 7a 65 20 6f 66 20 61 54 61 73 6b 5b 5d 20  Size of aTask[] 
3b20: 61 72 72 61 79 20 2a 2f 0a 20 20 53 6f 72 74 53  array */.  SortS
3b30: 75 62 74 61 73 6b 20 61 54 61 73 6b 5b 31 5d 3b  ubtask aTask[1];
3b40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e             /* On
3b50: 65 20 6f 72 20 6d 6f 72 65 20 73 75 62 74 61 73  e or more subtas
3b60: 6b 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  ks */.};../*.** 
3b70: 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74  An instance of t
3b80: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a  he following obj
3b90: 65 63 74 20 69 73 20 75 73 65 64 20 74 6f 20 72  ect is used to r
3ba0: 65 61 64 20 72 65 63 6f 72 64 73 20 6f 75 74 20  ead records out 
3bb0: 6f 66 20 61 0a 2a 2a 20 50 4d 41 2c 20 69 6e 20  of a.** PMA, in 
3bc0: 73 6f 72 74 65 64 20 6f 72 64 65 72 2e 20 20 54  sorted order.  T
3bd0: 68 65 20 6e 65 78 74 20 6b 65 79 20 74 6f 20 62  he next key to b
3be0: 65 20 72 65 61 64 20 69 73 20 63 61 63 68 65 64  e read is cached
3bf0: 20 69 6e 20 6e 4b 65 79 2f 61 4b 65 79 2e 0a 2a   in nKey/aKey..*
3c00: 2a 20 70 46 69 6c 65 3d 3d 30 20 61 74 20 45 4f  * pFile==0 at EO
3c10: 46 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 6d 61  F..*/.struct Pma
3c20: 52 65 61 64 65 72 20 7b 0a 20 20 69 36 34 20 69  Reader {.  i64 i
3c30: 52 65 61 64 4f 66 66 3b 20 20 20 20 20 20 20 20  ReadOff;        
3c40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
3c50: 72 72 65 6e 74 20 72 65 61 64 20 6f 66 66 73 65  rrent read offse
3c60: 74 20 2a 2f 0a 20 20 69 36 34 20 69 45 6f 66 3b  t */.  i64 iEof;
3c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3c80: 20 20 20 20 20 20 20 2f 2a 20 31 20 62 79 74 65         /* 1 byte
3c90: 20 70 61 73 74 20 45 4f 46 20 66 6f 72 20 74 68   past EOF for th
3ca0: 69 73 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20  is iterator */. 
3cb0: 20 69 6e 74 20 6e 41 6c 6c 6f 63 3b 20 20 20 20   int nAlloc;    
3cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3cd0: 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 73 70 61   /* Bytes of spa
3ce0: 63 65 20 61 74 20 61 41 6c 6c 6f 63 20 2a 2f 0a  ce at aAlloc */.
3cf0: 20 20 69 6e 74 20 6e 4b 65 79 3b 20 20 20 20 20    int nKey;     
3d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3d10: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62    /* Number of b
3d20: 79 74 65 73 20 69 6e 20 6b 65 79 20 2a 2f 0a 20  ytes in key */. 
3d30: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
3d40: 46 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20  File;           
3d50: 20 2f 2a 20 46 69 6c 65 20 69 74 65 72 61 74 6f   /* File iterato
3d60: 72 20 69 73 20 72 65 61 64 69 6e 67 20 66 72 6f  r is reading fro
3d70: 6d 20 2a 2f 0a 20 20 75 38 20 2a 61 41 6c 6c 6f  m */.  u8 *aAllo
3d80: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
3d90: 20 20 20 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61         /* Alloca
3da0: 74 65 64 20 73 70 61 63 65 20 2a 2f 0a 20 20 75  ted space */.  u
3db0: 38 20 2a 61 4b 65 79 3b 20 20 20 20 20 20 20 20  8 *aKey;        
3dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3dd0: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 63 75 72  * Pointer to cur
3de0: 72 65 6e 74 20 6b 65 79 20 2a 2f 0a 20 20 75 38  rent key */.  u8
3df0: 20 2a 61 42 75 66 66 65 72 3b 20 20 20 20 20 20   *aBuffer;      
3e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3e10: 20 43 75 72 72 65 6e 74 20 72 65 61 64 20 62 75   Current read bu
3e20: 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  ffer */.  int nB
3e30: 75 66 66 65 72 3b 20 20 20 20 20 20 20 20 20 20  uffer;          
3e40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
3e50: 65 20 6f 66 20 72 65 61 64 20 62 75 66 66 65 72  e of read buffer
3e60: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 75   in bytes */.  u
3e70: 38 20 2a 61 4d 61 70 3b 20 20 20 20 20 20 20 20  8 *aMap;        
3e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3e90: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 6d 61 70  * Pointer to map
3ea0: 70 69 6e 67 20 6f 66 20 65 6e 74 69 72 65 20 66  ping of entire f
3eb0: 69 6c 65 20 2a 2f 0a 20 20 49 6e 63 72 4d 65 72  ile */.  IncrMer
3ec0: 67 65 72 20 2a 70 49 6e 63 72 3b 20 20 20 20 20  ger *pIncr;     
3ed0: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 63 72           /* Incr
3ee0: 65 6d 65 6e 74 61 6c 20 6d 65 72 67 65 72 20 2a  emental merger *
3ef0: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 4e 6f 72 6d  /.};../*.** Norm
3f00: 61 6c 6c 79 2c 20 61 20 50 6d 61 52 65 61 64 65  ally, a PmaReade
3f10: 72 20 6f 62 6a 65 63 74 20 69 74 65 72 61 74 65  r object iterate
3f20: 73 20 74 68 72 6f 75 67 68 20 61 6e 20 65 78 69  s through an exi
3f30: 73 74 69 6e 67 20 50 4d 41 20 73 74 6f 72 65 64  sting PMA stored
3f40: 20 0a 2a 2a 20 77 69 74 68 69 6e 20 61 20 74 65   .** within a te
3f50: 6d 70 20 66 69 6c 65 2e 20 48 6f 77 65 76 65 72  mp file. However
3f60: 2c 20 69 66 20 74 68 65 20 50 6d 61 52 65 61 64  , if the PmaRead
3f70: 65 72 2e 70 49 6e 63 72 20 76 61 72 69 61 62 6c  er.pIncr variabl
3f80: 65 20 70 6f 69 6e 74 73 20 74 6f 0a 2a 2a 20 61  e points to.** a
3f90: 6e 20 6f 62 6a 65 63 74 20 6f 66 20 74 68 65 20  n object of the 
3fa0: 66 6f 6c 6c 6f 77 69 6e 67 20 74 79 70 65 2c 20  following type, 
3fb0: 69 74 20 6d 61 79 20 62 65 20 75 73 65 64 20 74  it may be used t
3fc0: 6f 20 69 74 65 72 61 74 65 2f 6d 65 72 67 65 20  o iterate/merge 
3fd0: 74 68 72 6f 75 67 68 0a 2a 2a 20 6d 75 6c 74 69  through.** multi
3fe0: 70 6c 65 20 50 4d 41 73 20 73 69 6d 75 6c 74 61  ple PMAs simulta
3ff0: 6e 65 6f 75 73 6c 79 2e 0a 2a 2a 0a 2a 2a 20 54  neously..**.** T
4000: 68 65 72 65 20 61 72 65 20 74 77 6f 20 74 79 70  here are two typ
4010: 65 73 20 6f 66 20 49 6e 63 72 4d 65 72 67 65 72  es of IncrMerger
4020: 20 6f 62 6a 65 63 74 20 2d 20 73 69 6e 67 6c 65   object - single
4030: 20 28 62 55 73 65 54 68 72 65 61 64 3d 3d 30 29   (bUseThread==0)
4040: 20 61 6e 64 20 0a 2a 2a 20 6d 75 6c 74 69 2d 74   and .** multi-t
4050: 68 72 65 61 64 65 64 20 28 62 55 73 65 54 68 72  hreaded (bUseThr
4060: 65 61 64 3d 3d 31 29 2e 20 0a 2a 2a 0a 2a 2a 20  ead==1). .**.** 
4070: 41 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64  A multi-threaded
4080: 20 49 6e 63 72 4d 65 72 67 65 72 20 6f 62 6a 65   IncrMerger obje
4090: 63 74 20 75 73 65 73 20 74 77 6f 20 74 65 6d 70  ct uses two temp
40a0: 6f 72 61 72 79 20 66 69 6c 65 73 20 2d 20 61 46  orary files - aF
40b0: 69 6c 65 5b 30 5d 20 0a 2a 2a 20 61 6e 64 20 61  ile[0] .** and a
40c0: 46 69 6c 65 5b 31 5d 2e 20 4e 65 69 74 68 65 72  File[1]. Neither
40d0: 20 66 69 6c 65 20 69 73 20 61 6c 6c 6f 77 65 64   file is allowed
40e0: 20 74 6f 20 67 72 6f 77 20 74 6f 20 6d 6f 72 65   to grow to more
40f0: 20 74 68 61 6e 20 6d 78 53 7a 20 62 79 74 65 73   than mxSz bytes
4100: 20 69 6e 20 0a 2a 2a 20 73 69 7a 65 2e 20 57 68   in .** size. Wh
4110: 65 6e 20 74 68 65 20 49 6e 63 72 4d 65 72 67 65  en the IncrMerge
4120: 72 20 69 73 20 69 6e 69 74 69 61 6c 69 7a 65 64  r is initialized
4130: 2c 20 69 74 20 72 65 61 64 73 20 65 6e 6f 75 67  , it reads enoug
4140: 68 20 64 61 74 61 20 66 72 6f 6d 20 0a 2a 2a 20  h data from .** 
4150: 70 4d 65 72 67 65 72 20 74 6f 20 70 6f 70 75 6c  pMerger to popul
4160: 61 74 65 20 61 46 69 6c 65 5b 30 5d 2e 20 49 74  ate aFile[0]. It
4170: 20 74 68 65 6e 20 73 65 74 73 20 76 61 72 69 61   then sets varia
4180: 62 6c 65 73 20 77 69 74 68 69 6e 20 74 68 65 20  bles within the 
4190: 0a 2a 2a 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e  .** correspondin
41a0: 67 20 50 6d 61 52 65 61 64 65 72 20 6f 62 6a 65  g PmaReader obje
41b0: 63 74 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20  ct to read from 
41c0: 74 68 61 74 20 66 69 6c 65 20 61 6e 64 20 6b 69  that file and ki
41d0: 63 6b 73 20 6f 66 66 20 0a 2a 2a 20 61 20 62 61  cks off .** a ba
41e0: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
41f0: 74 6f 20 70 6f 70 75 6c 61 74 65 20 61 46 69 6c  to populate aFil
4200: 65 5b 31 5d 20 77 69 74 68 20 74 68 65 20 6e 65  e[1] with the ne
4210: 78 74 20 6d 78 53 7a 20 62 79 74 65 73 20 6f 66  xt mxSz bytes of
4220: 20 0a 2a 2a 20 73 6f 72 74 65 64 20 72 65 63 6f   .** sorted reco
4230: 72 64 20 64 61 74 61 20 66 72 6f 6d 20 70 4d 65  rd data from pMe
4240: 72 67 65 72 2e 20 0a 2a 2a 0a 2a 2a 20 57 68 65  rger. .**.** Whe
4250: 6e 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 20  n the PmaReader 
4260: 72 65 61 63 68 65 73 20 74 68 65 20 65 6e 64 20  reaches the end 
4270: 6f 66 20 61 46 69 6c 65 5b 30 5d 2c 20 69 74 20  of aFile[0], it 
4280: 62 6c 6f 63 6b 73 20 75 6e 74 69 6c 20 74 68 65  blocks until the
4290: 0a 2a 2a 20 62 61 63 6b 67 72 6f 75 6e 64 20 74  .** background t
42a0: 68 72 65 61 64 20 68 61 73 20 66 69 6e 69 73 68  hread has finish
42b0: 65 64 20 70 6f 70 75 6c 61 74 69 6e 67 20 61 46  ed populating aF
42c0: 69 6c 65 5b 31 5d 2e 20 49 74 20 74 68 65 6e 20  ile[1]. It then 
42d0: 65 78 63 68 61 6e 67 65 73 0a 2a 2a 20 74 68 65  exchanges.** the
42e0: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
42f0: 20 61 46 69 6c 65 5b 30 5d 20 61 6e 64 20 61 46   aFile[0] and aF
4300: 69 6c 65 5b 31 5d 20 76 61 72 69 61 62 6c 65 73  ile[1] variables
4310: 20 77 69 74 68 69 6e 20 74 68 69 73 20 73 74 72   within this str
4320: 75 63 74 75 72 65 2c 0a 2a 2a 20 73 65 74 73 20  ucture,.** sets 
4330: 74 68 65 20 50 6d 61 52 65 61 64 65 72 20 66 69  the PmaReader fi
4340: 65 6c 64 73 20 74 6f 20 72 65 61 64 20 66 72 6f  elds to read fro
4350: 6d 20 74 68 65 20 6e 65 77 20 61 46 69 6c 65 5b  m the new aFile[
4360: 30 5d 20 61 6e 64 20 6b 69 63 6b 73 20 6f 66 66  0] and kicks off
4370: 0a 2a 2a 20 61 6e 6f 74 68 65 72 20 62 61 63 6b  .** another back
4380: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 74 6f  ground thread to
4390: 20 70 6f 70 75 6c 61 74 65 20 74 68 65 20 6e 65   populate the ne
43a0: 77 20 61 46 69 6c 65 5b 31 5d 2e 20 41 6e 64 20  w aFile[1]. And 
43b0: 73 6f 20 6f 6e 2c 20 75 6e 74 69 6c 0a 2a 2a 20  so on, until.** 
43c0: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
43d0: 70 4d 65 72 67 65 72 20 61 72 65 20 65 78 68 61  pMerger are exha
43e0: 75 73 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 41 20 73  usted..**.** A s
43f0: 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64 20 49  ingle-threaded I
4400: 6e 63 72 4d 65 72 67 65 72 20 64 6f 65 73 20 6e  ncrMerger does n
4410: 6f 74 20 6f 70 65 6e 20 61 6e 79 20 74 65 6d 70  ot open any temp
4420: 6f 72 61 72 79 20 66 69 6c 65 73 20 6f 66 20 69  orary files of i
4430: 74 73 0a 2a 2a 20 6f 77 6e 2e 20 49 6e 73 74 65  ts.** own. Inste
4440: 61 64 2c 20 69 74 20 68 61 73 20 65 78 63 6c 75  ad, it has exclu
4450: 73 69 76 65 20 61 63 63 65 73 73 20 74 6f 20 6d  sive access to m
4460: 78 53 7a 20 62 79 74 65 73 20 6f 66 20 73 70 61  xSz bytes of spa
4470: 63 65 20 62 65 67 69 6e 6e 69 6e 67 0a 2a 2a 20  ce beginning.** 
4480: 61 74 20 6f 66 66 73 65 74 20 69 53 74 61 72 74  at offset iStart
4490: 4f 66 66 20 6f 66 20 66 69 6c 65 20 70 54 61 73  Off of file pTas
44a0: 6b 2d 3e 66 69 6c 65 32 2e 20 41 6e 64 20 69 6e  k->file2. And in
44b0: 73 74 65 61 64 20 6f 66 20 75 73 69 6e 67 20 61  stead of using a
44c0: 20 0a 2a 2a 20 62 61 63 6b 67 72 6f 75 6e 64 20   .** background 
44d0: 74 68 72 65 61 64 20 74 6f 20 70 72 65 70 61 72  thread to prepar
44e0: 65 20 64 61 74 61 20 66 6f 72 20 74 68 65 20 50  e data for the P
44f0: 6d 61 52 65 61 64 65 72 2c 20 77 69 74 68 20 61  maReader, with a
4500: 20 73 69 6e 67 6c 65 0a 2a 2a 20 74 68 72 65 61   single.** threa
4510: 64 65 64 20 49 6e 63 72 4d 65 72 67 65 72 20 74  ded IncrMerger t
4520: 68 65 20 61 6c 6c 6f 63 61 74 65 20 70 61 72 74  he allocate part
4530: 20 6f 66 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32   of pTask->file2
4540: 20 69 73 20 22 72 65 66 69 6c 6c 65 64 22 20 77   is "refilled" w
4550: 69 74 68 0a 2a 2a 20 6b 65 79 73 20 66 72 6f 6d  ith.** keys from
4560: 20 70 4d 65 72 67 65 72 20 62 79 20 74 68 65 20   pMerger by the 
4570: 63 61 6c 6c 69 6e 67 20 74 68 72 65 61 64 20 77  calling thread w
4580: 68 65 6e 65 76 65 72 20 74 68 65 20 50 6d 61 52  henever the PmaR
4590: 65 61 64 65 72 20 72 75 6e 73 20 6f 75 74 0a 2a  eader runs out.*
45a0: 2a 20 6f 66 20 64 61 74 61 2e 0a 2a 2f 0a 73 74  * of data..*/.st
45b0: 72 75 63 74 20 49 6e 63 72 4d 65 72 67 65 72 20  ruct IncrMerger 
45c0: 7b 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20  {.  SortSubtask 
45d0: 2a 70 54 61 73 6b 3b 20 20 20 20 20 20 20 20 20  *pTask;         
45e0: 20 20 20 20 2f 2a 20 54 61 73 6b 20 74 68 61 74      /* Task that
45f0: 20 6f 77 6e 73 20 74 68 69 73 20 6d 65 72 67 65   owns this merge
4600: 72 20 2a 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69  r */.  MergeEngi
4610: 6e 65 20 2a 70 4d 65 72 67 65 72 3b 20 20 20 20  ne *pMerger;    
4620: 20 20 20 20 20 20 20 2f 2a 20 4d 65 72 67 65 20         /* Merge 
4630: 65 6e 67 69 6e 65 20 74 68 72 65 61 64 20 72 65  engine thread re
4640: 61 64 73 20 64 61 74 61 20 66 72 6f 6d 20 2a 2f  ads data from */
4650: 0a 20 20 69 36 34 20 69 53 74 61 72 74 4f 66 66  .  i64 iStartOff
4660: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4670: 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 74 6f 20     /* Offset to 
4680: 73 74 61 72 74 20 77 72 69 74 69 6e 67 20 66 69  start writing fi
4690: 6c 65 20 61 74 20 2a 2f 0a 20 20 69 6e 74 20 6d  le at */.  int m
46a0: 78 53 7a 3b 20 20 20 20 20 20 20 20 20 20 20 20  xSz;            
46b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61             /* Ma
46c0: 78 69 6d 75 6d 20 62 79 74 65 73 20 6f 66 20 64  ximum bytes of d
46d0: 61 74 61 20 74 6f 20 73 74 6f 72 65 20 2a 2f 0a  ata to store */.
46e0: 20 20 69 6e 74 20 62 45 6f 66 3b 20 20 20 20 20    int bEof;     
46f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4700: 20 20 2f 2a 20 53 65 74 20 74 6f 20 74 72 75 65    /* Set to true
4710: 20 77 68 65 6e 20 6d 65 72 67 65 20 69 73 20 66   when merge is f
4720: 69 6e 69 73 68 65 64 20 2a 2f 0a 20 20 69 6e 74  inished */.  int
4730: 20 62 55 73 65 54 68 72 65 61 64 3b 20 20 20 20   bUseThread;    
4740: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4750: 54 72 75 65 20 74 6f 20 75 73 65 20 61 20 62 67  True to use a bg
4760: 20 74 68 72 65 61 64 20 66 6f 72 20 74 68 69 73   thread for this
4770: 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 53 6f 72   object */.  Sor
4780: 74 65 72 46 69 6c 65 20 61 46 69 6c 65 5b 32 5d  terFile aFile[2]
4790: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
47a0: 61 46 69 6c 65 5b 30 5d 20 66 6f 72 20 72 65 61  aFile[0] for rea
47b0: 64 69 6e 67 2c 20 5b 31 5d 20 66 6f 72 20 77 72  ding, [1] for wr
47c0: 69 74 69 6e 67 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  iting */.};../*.
47d0: 2a 2a 20 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f  ** An instance o
47e0: 66 20 74 68 69 73 20 6f 62 6a 65 63 74 20 69 73  f this object is
47f0: 20 75 73 65 64 20 66 6f 72 20 77 72 69 74 69 6e   used for writin
4800: 67 20 61 20 50 4d 41 2e 0a 2a 2a 0a 2a 2a 20 54  g a PMA..**.** T
4810: 68 65 20 50 4d 41 20 69 73 20 77 72 69 74 74 65  he PMA is writte
4820: 6e 20 6f 6e 65 20 72 65 63 6f 72 64 20 61 74 20  n one record at 
4830: 61 20 74 69 6d 65 2e 20 20 45 61 63 68 20 72 65  a time.  Each re
4840: 63 6f 72 64 20 69 73 20 6f 66 20 61 6e 20 61 72  cord is of an ar
4850: 62 69 74 72 61 72 79 0a 2a 2a 20 73 69 7a 65 2e  bitrary.** size.
4860: 20 20 42 75 74 20 49 2f 4f 20 69 73 20 6d 6f 72    But I/O is mor
4870: 65 20 65 66 66 69 63 69 65 6e 74 20 69 66 20 69  e efficient if i
4880: 74 20 6f 63 63 75 72 73 20 69 6e 20 70 61 67 65  t occurs in page
4890: 2d 73 69 7a 65 64 20 62 6c 6f 63 6b 73 20 77 68  -sized blocks wh
48a0: 65 72 65 0a 2a 2a 20 65 61 63 68 20 62 6c 6f 63  ere.** each bloc
48b0: 6b 20 69 73 20 61 6c 69 67 6e 65 64 20 6f 6e 20  k is aligned on 
48c0: 61 20 70 61 67 65 20 62 6f 75 6e 64 61 72 79 2e  a page boundary.
48d0: 20 20 54 68 69 73 20 6f 62 6a 65 63 74 20 63 61    This object ca
48e0: 63 68 65 73 20 77 72 69 74 65 73 20 74 6f 0a 2a  ches writes to.*
48f0: 2a 20 74 68 65 20 50 4d 41 20 73 6f 20 74 68 61  * the PMA so tha
4900: 74 20 61 6c 69 67 6e 65 64 2c 20 70 61 67 65 2d  t aligned, page-
4910: 73 69 7a 65 20 62 6c 6f 63 6b 73 20 61 72 65 20  size blocks are 
4920: 77 72 69 74 74 65 6e 2e 0a 2a 2f 0a 73 74 72 75  written..*/.stru
4930: 63 74 20 50 6d 61 57 72 69 74 65 72 20 7b 0a 20  ct PmaWriter {. 
4940: 20 69 6e 74 20 65 46 57 45 72 72 3b 20 20 20 20   int eFWErr;    
4950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4960: 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20 69 66 20   /* Non-zero if 
4970: 69 6e 20 61 6e 20 65 72 72 6f 72 20 73 74 61 74  in an error stat
4980: 65 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75 66 66  e */.  u8 *aBuff
4990: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  er;             
49a0: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
49b0: 72 20 74 6f 20 77 72 69 74 65 20 62 75 66 66 65  r to write buffe
49c0: 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66 66  r */.  int nBuff
49d0: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  er;             
49e0: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
49f0: 66 20 77 72 69 74 65 20 62 75 66 66 65 72 20 69  f write buffer i
4a00: 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74  n bytes */.  int
4a10: 20 69 42 75 66 53 74 61 72 74 3b 20 20 20 20 20   iBufStart;     
4a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4a30: 46 69 72 73 74 20 62 79 74 65 20 6f 66 20 62 75  First byte of bu
4a40: 66 66 65 72 20 74 6f 20 77 72 69 74 65 20 2a 2f  ffer to write */
4a50: 0a 20 20 69 6e 74 20 69 42 75 66 45 6e 64 3b 20  .  int iBufEnd; 
4a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4a70: 20 20 20 2f 2a 20 4c 61 73 74 20 62 79 74 65 20     /* Last byte 
4a80: 6f 66 20 62 75 66 66 65 72 20 74 6f 20 77 72 69  of buffer to wri
4a90: 74 65 20 2a 2f 0a 20 20 69 36 34 20 69 57 72 69  te */.  i64 iWri
4aa0: 74 65 4f 66 66 3b 20 20 20 20 20 20 20 20 20 20  teOff;          
4ab0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65          /* Offse
4ac0: 74 20 6f 66 20 73 74 61 72 74 20 6f 66 20 62 75  t of start of bu
4ad0: 66 66 65 72 20 69 6e 20 66 69 6c 65 20 2a 2f 0a  ffer in file */.
4ae0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
4af0: 70 46 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20  pFile;          
4b00: 20 20 2f 2a 20 46 69 6c 65 20 74 6f 20 77 72 69    /* File to wri
4b10: 74 65 20 74 6f 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  te to */.};../*.
4b20: 2a 2a 20 54 68 69 73 20 6f 62 6a 65 63 74 20 69  ** This object i
4b30: 73 20 74 68 65 20 68 65 61 64 65 72 20 6f 6e 20  s the header on 
4b40: 61 20 73 69 6e 67 6c 65 20 72 65 63 6f 72 64 20  a single record 
4b50: 77 68 69 6c 65 20 74 68 61 74 20 72 65 63 6f 72  while that recor
4b60: 64 20 69 73 20 62 65 69 6e 67 0a 2a 2a 20 68 65  d is being.** he
4b70: 6c 64 20 69 6e 20 6d 65 6d 6f 72 79 20 61 6e 64  ld in memory and
4b80: 20 70 72 69 6f 72 20 74 6f 20 62 65 69 6e 67 20   prior to being 
4b90: 77 72 69 74 74 65 6e 20 6f 75 74 20 61 73 20 70  written out as p
4ba0: 61 72 74 20 6f 66 20 61 20 50 4d 41 2e 0a 2a 2a  art of a PMA..**
4bb0: 0a 2a 2a 20 48 6f 77 20 74 68 65 20 6c 69 6e 6b  .** How the link
4bc0: 65 64 20 6c 69 73 74 20 69 73 20 63 6f 6e 6e 65  ed list is conne
4bd0: 63 74 65 64 20 64 65 70 65 6e 64 73 20 6f 6e 20  cted depends on 
4be0: 68 6f 77 20 6d 65 6d 6f 72 79 20 69 73 20 62 65  how memory is be
4bf0: 69 6e 67 20 6d 61 6e 61 67 65 64 0a 2a 2a 20 62  ing managed.** b
4c00: 79 20 74 68 69 73 20 6d 6f 64 75 6c 65 2e 20 49  y this module. I
4c10: 66 20 75 73 69 6e 67 20 61 20 73 65 70 61 72 61  f using a separa
4c20: 74 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 6f  te allocation fo
4c30: 72 20 65 61 63 68 20 69 6e 2d 6d 65 6d 6f 72 79  r each in-memory
4c40: 20 72 65 63 6f 72 64 0a 2a 2a 20 28 56 64 62 65   record.** (Vdbe
4c50: 53 6f 72 74 65 72 2e 6c 69 73 74 2e 61 4d 65 6d  Sorter.list.aMem
4c60: 6f 72 79 3d 3d 30 29 2c 20 74 68 65 6e 20 74 68  ory==0), then th
4c70: 65 20 6c 69 73 74 20 69 73 20 61 6c 77 61 79 73  e list is always
4c80: 20 63 6f 6e 6e 65 63 74 65 64 20 75 73 69 6e 67   connected using
4c90: 20 74 68 65 0a 2a 2a 20 53 6f 72 74 65 72 52 65   the.** SorterRe
4ca0: 63 6f 72 64 2e 75 2e 70 4e 65 78 74 20 70 6f 69  cord.u.pNext poi
4cb0: 6e 74 65 72 73 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c  nters..**.** Or,
4cc0: 20 69 66 20 75 73 69 6e 67 20 74 68 65 20 73 69   if using the si
4cd0: 6e 67 6c 65 20 6c 61 72 67 65 20 61 6c 6c 6f 63  ngle large alloc
4ce0: 61 74 69 6f 6e 20 6d 65 74 68 6f 64 20 28 56 64  ation method (Vd
4cf0: 62 65 53 6f 72 74 65 72 2e 6c 69 73 74 2e 61 4d  beSorter.list.aM
4d00: 65 6d 6f 72 79 21 3d 30 29 2c 0a 2a 2a 20 74 68  emory!=0),.** th
4d10: 65 6e 20 77 68 69 6c 65 20 72 65 63 6f 72 64 73  en while records
4d20: 20 61 72 65 20 62 65 69 6e 67 20 61 63 63 75 6d   are being accum
4d30: 75 6c 61 74 65 64 20 74 68 65 20 6c 69 73 74 20  ulated the list 
4d40: 69 73 20 6c 69 6e 6b 65 64 20 75 73 69 6e 67 20  is linked using 
4d50: 74 68 65 0a 2a 2a 20 53 6f 72 74 65 72 52 65 63  the.** SorterRec
4d60: 6f 72 64 2e 75 2e 69 4e 65 78 74 20 6f 66 66 73  ord.u.iNext offs
4d70: 65 74 2e 20 54 68 69 73 20 69 73 20 62 65 63 61  et. This is beca
4d80: 75 73 65 20 74 68 65 20 61 4d 65 6d 6f 72 79 5b  use the aMemory[
4d90: 5d 20 61 72 72 61 79 20 6d 61 79 0a 2a 2a 20 62  ] array may.** b
4da0: 65 20 73 71 6c 69 74 65 33 52 65 61 6c 6c 6f 63  e sqlite3Realloc
4db0: 28 29 65 64 20 77 68 69 6c 65 20 72 65 63 6f 72  ()ed while recor
4dc0: 64 73 20 61 72 65 20 62 65 69 6e 67 20 61 63 63  ds are being acc
4dd0: 75 6d 75 6c 61 74 65 64 2e 20 4f 6e 63 65 20 74  umulated. Once t
4de0: 68 65 20 56 4d 0a 2a 2a 20 68 61 73 20 66 69 6e  he VM.** has fin
4df0: 69 73 68 65 64 20 70 61 73 73 69 6e 67 20 72 65  ished passing re
4e00: 63 6f 72 64 73 20 74 6f 20 74 68 65 20 73 6f 72  cords to the sor
4e10: 74 65 72 2c 20 6f 72 20 77 68 65 6e 20 74 68 65  ter, or when the
4e20: 20 69 6e 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65   in-memory buffe
4e30: 72 0a 2a 2a 20 69 73 20 66 75 6c 6c 2c 20 74 68  r.** is full, th
4e40: 65 20 6c 69 73 74 20 69 73 20 73 6f 72 74 65 64  e list is sorted
4e50: 2e 20 41 73 20 70 61 72 74 20 6f 66 20 74 68 65  . As part of the
4e60: 20 73 6f 72 74 69 6e 67 20 70 72 6f 63 65 73 73   sorting process
4e70: 2c 20 69 74 20 69 73 0a 2a 2a 20 63 6f 6e 76 65  , it is.** conve
4e80: 72 74 65 64 20 74 6f 20 75 73 65 20 74 68 65 20  rted to use the 
4e90: 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 75 2e 70  SorterRecord.u.p
4ea0: 4e 65 78 74 20 70 6f 69 6e 74 65 72 73 2e 20 53  Next pointers. S
4eb0: 65 65 20 66 75 6e 63 74 69 6f 6e 0a 2a 2a 20 76  ee function.** v
4ec0: 64 62 65 53 6f 72 74 65 72 53 6f 72 74 28 29 20  dbeSorterSort() 
4ed0: 66 6f 72 20 64 65 74 61 69 6c 73 2e 0a 2a 2f 0a  for details..*/.
4ee0: 73 74 72 75 63 74 20 53 6f 72 74 65 72 52 65 63  struct SorterRec
4ef0: 6f 72 64 20 7b 0a 20 20 69 6e 74 20 6e 56 61 6c  ord {.  int nVal
4f00: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4f10: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
4f20: 6f 66 20 74 68 65 20 72 65 63 6f 72 64 20 69 6e  of the record in
4f30: 20 62 79 74 65 73 20 2a 2f 0a 20 20 75 6e 69 6f   bytes */.  unio
4f40: 6e 20 7b 0a 20 20 20 20 53 6f 72 74 65 72 52 65  n {.    SorterRe
4f50: 63 6f 72 64 20 2a 70 4e 65 78 74 3b 20 20 20 20  cord *pNext;    
4f60: 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
4f70: 20 74 6f 20 6e 65 78 74 20 72 65 63 6f 72 64 20   to next record 
4f80: 69 6e 20 6c 69 73 74 20 2a 2f 0a 20 20 20 20 69  in list */.    i
4f90: 6e 74 20 69 4e 65 78 74 3b 20 20 20 20 20 20 20  nt iNext;       
4fa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4fb0: 4f 66 66 73 65 74 20 77 69 74 68 69 6e 20 61 4d  Offset within aM
4fc0: 65 6d 6f 72 79 20 6f 66 20 6e 65 78 74 20 72 65  emory of next re
4fd0: 63 6f 72 64 20 2a 2f 0a 20 20 7d 20 75 3b 0a 20  cord */.  } u;. 
4fe0: 20 2f 2a 20 54 68 65 20 64 61 74 61 20 66 6f 72   /* The data for
4ff0: 20 74 68 65 20 72 65 63 6f 72 64 20 69 6d 6d 65   the record imme
5000: 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 73 20  diately follows 
5010: 74 68 69 73 20 68 65 61 64 65 72 20 2a 2f 0a 7d  this header */.}
5020: 3b 0a 0a 2f 2a 20 52 65 74 75 72 6e 20 61 20 70  ;../* Return a p
5030: 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 62 75  ointer to the bu
5040: 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ffer containing 
5050: 74 68 65 20 72 65 63 6f 72 64 20 64 61 74 61 20  the record data 
5060: 66 6f 72 20 53 6f 72 74 65 72 52 65 63 6f 72 64  for SorterRecord
5070: 0a 2a 2a 20 6f 62 6a 65 63 74 20 70 2e 20 53 68  .** object p. Sh
5080: 6f 75 6c 64 20 62 65 20 75 73 65 64 20 61 73 20  ould be used as 
5090: 69 66 3a 0a 2a 2a 0a 2a 2a 20 20 20 76 6f 69 64  if:.**.**   void
50a0: 20 2a 53 52 56 41 4c 28 53 6f 72 74 65 72 52 65   *SRVAL(SorterRe
50b0: 63 6f 72 64 20 2a 70 29 20 7b 20 72 65 74 75 72  cord *p) { retur
50c0: 6e 20 28 76 6f 69 64 2a 29 26 70 5b 31 5d 3b 20  n (void*)&p[1]; 
50d0: 7d 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 53 52 56  }.*/.#define SRV
50e0: 41 4c 28 70 29 20 28 28 76 6f 69 64 2a 29 28 28  AL(p) ((void*)((
50f0: 53 6f 72 74 65 72 52 65 63 6f 72 64 2a 29 28 70  SorterRecord*)(p
5100: 29 20 2b 20 31 29 29 0a 0a 2f 2a 20 54 68 65 20  ) + 1))../* The 
5110: 6d 69 6e 69 6d 75 6d 20 50 4d 41 20 73 69 7a 65  minimum PMA size
5120: 20 69 73 20 73 65 74 20 74 6f 20 74 68 69 73 20   is set to this 
5130: 76 61 6c 75 65 20 6d 75 6c 74 69 70 6c 69 65 64  value multiplied
5140: 20 62 79 20 74 68 65 20 64 61 74 61 62 61 73 65   by the database
5150: 0a 2a 2a 20 70 61 67 65 20 73 69 7a 65 20 69 6e  .** page size in
5160: 20 62 79 74 65 73 2e 20 20 2a 2f 0a 23 64 65 66   bytes.  */.#def
5170: 69 6e 65 20 53 4f 52 54 45 52 5f 4d 49 4e 5f 57  ine SORTER_MIN_W
5180: 4f 52 4b 49 4e 47 20 31 30 0a 0a 2f 2a 20 4d 61  ORKING 10../* Ma
5190: 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20  ximum number of 
51a0: 50 4d 41 73 20 74 68 61 74 20 61 20 73 69 6e 67  PMAs that a sing
51b0: 6c 65 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 63  le MergeEngine c
51c0: 61 6e 20 6d 65 72 67 65 20 2a 2f 0a 23 64 65 66  an merge */.#def
51d0: 69 6e 65 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  ine SORTER_MAX_M
51e0: 45 52 47 45 5f 43 4f 55 4e 54 20 31 36 0a 0a 73  ERGE_COUNT 16..s
51f0: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 49 6e  tatic int vdbeIn
5200: 63 72 53 77 61 70 28 49 6e 63 72 4d 65 72 67 65  crSwap(IncrMerge
5210: 72 2a 29 3b 0a 73 74 61 74 69 63 20 76 6f 69 64  r*);.static void
5220: 20 76 64 62 65 49 6e 63 72 46 72 65 65 28 49 6e   vdbeIncrFree(In
5230: 63 72 4d 65 72 67 65 72 20 2a 29 3b 0a 0a 2f 2a  crMerger *);../*
5240: 0a 2a 2a 20 46 72 65 65 20 61 6c 6c 20 6d 65 6d  .** Free all mem
5250: 6f 72 79 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f  ory belonging to
5260: 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 20 6f   the PmaReader o
5270: 62 6a 65 63 74 20 70 61 73 73 65 64 20 61 73 20  bject passed as 
5280: 74 68 65 20 73 65 63 6f 6e 64 0a 2a 2a 20 61 72  the second.** ar
5290: 67 75 6d 65 6e 74 2e 20 41 6c 6c 20 73 74 72 75  gument. All stru
52a0: 63 74 75 72 65 20 66 69 65 6c 64 73 20 61 72 65  cture fields are
52b0: 20 73 65 74 20 74 6f 20 7a 65 72 6f 20 62 65 66   set to zero bef
52c0: 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a  ore returning..*
52d0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64  /.static void vd
52e0: 62 65 50 6d 61 52 65 61 64 65 72 43 6c 65 61 72  bePmaReaderClear
52f0: 28 50 6d 61 52 65 61 64 65 72 20 2a 70 49 74 65  (PmaReader *pIte
5300: 72 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  r){.  sqlite3_fr
5310: 65 65 28 70 49 74 65 72 2d 3e 61 41 6c 6c 6f 63  ee(pIter->aAlloc
5320: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
5330: 65 28 70 49 74 65 72 2d 3e 61 42 75 66 66 65 72  e(pIter->aBuffer
5340: 29 3b 0a 20 20 69 66 28 20 70 49 74 65 72 2d 3e  );.  if( pIter->
5350: 61 4d 61 70 20 29 20 73 71 6c 69 74 65 33 4f 73  aMap ) sqlite3Os
5360: 55 6e 66 65 74 63 68 28 70 49 74 65 72 2d 3e 70  Unfetch(pIter->p
5370: 46 69 6c 65 2c 20 30 2c 20 70 49 74 65 72 2d 3e  File, 0, pIter->
5380: 61 4d 61 70 29 3b 0a 20 20 69 66 28 20 70 49 74  aMap);.  if( pIt
5390: 65 72 2d 3e 70 49 6e 63 72 20 29 20 76 64 62 65  er->pIncr ) vdbe
53a0: 49 6e 63 72 46 72 65 65 28 70 49 74 65 72 2d 3e  IncrFree(pIter->
53b0: 70 49 6e 63 72 29 3b 0a 20 20 6d 65 6d 73 65 74  pIncr);.  memset
53c0: 28 70 49 74 65 72 2c 20 30 2c 20 73 69 7a 65 6f  (pIter, 0, sizeo
53d0: 66 28 50 6d 61 52 65 61 64 65 72 29 29 3b 0a 7d  f(PmaReader));.}
53e0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 6e 42 79  ../*.** Read nBy
53f0: 74 65 20 62 79 74 65 73 20 6f 66 20 64 61 74 61  te bytes of data
5400: 20 66 72 6f 6d 20 74 68 65 20 73 74 72 65 61 6d   from the stream
5410: 20 6f 66 20 64 61 74 61 20 69 74 65 72 61 74 65   of data iterate
5420: 64 20 62 79 20 6f 62 6a 65 63 74 20 70 2e 0a 2a  d by object p..*
5430: 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c  * If successful,
5440: 20 73 65 74 20 2a 70 70 4f 75 74 20 74 6f 20 70   set *ppOut to p
5450: 6f 69 6e 74 20 74 6f 20 61 20 62 75 66 66 65 72  oint to a buffer
5460: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20   containing the 
5470: 64 61 74 61 0a 2a 2a 20 61 6e 64 20 72 65 74 75  data.** and retu
5480: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 4f 74  rn SQLITE_OK. Ot
5490: 68 65 72 77 69 73 65 2c 20 69 66 20 61 6e 20 65  herwise, if an e
54a0: 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 72 65 74  rror occurs, ret
54b0: 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 0a 2a 2a  urn an SQLite.**
54c0: 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a   error code..**.
54d0: 2a 2a 20 54 68 65 20 62 75 66 66 65 72 20 69 6e  ** The buffer in
54e0: 64 69 63 61 74 65 64 20 62 79 20 2a 70 70 4f 75  dicated by *ppOu
54f0: 74 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 63 6f  t may only be co
5500: 6e 73 69 64 65 72 65 64 20 76 61 6c 69 64 20 75  nsidered valid u
5510: 6e 74 69 6c 20 74 68 65 0a 2a 2a 20 6e 65 78 74  ntil the.** next
5520: 20 63 61 6c 6c 20 74 6f 20 74 68 69 73 20 66 75   call to this fu
5530: 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69  nction..*/.stati
5540: 63 20 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61  c int vdbePmaRea
5550: 64 42 6c 6f 62 28 0a 20 20 50 6d 61 52 65 61 64  dBlob(.  PmaRead
5560: 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20  er *p,          
5570: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72           /* Iter
5580: 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  ator */.  int nB
5590: 79 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  yte,            
55a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74            /* Byt
55b0: 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 72 65  es of data to re
55c0: 61 64 20 2a 2f 0a 20 20 75 38 20 2a 2a 70 70 4f  ad */.  u8 **ppO
55d0: 75 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ut              
55e0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
55f0: 50 6f 69 6e 74 65 72 20 74 6f 20 62 75 66 66 65  Pointer to buffe
5600: 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64 61 74  r containing dat
5610: 61 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 42  a */.){.  int iB
5620: 75 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  uf;             
5630: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66            /* Off
5640: 73 65 74 20 77 69 74 68 69 6e 20 62 75 66 66 65  set within buffe
5650: 72 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a  r to read from *
5660: 2f 0a 20 20 69 6e 74 20 6e 41 76 61 69 6c 3b 20  /.  int nAvail; 
5670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5680: 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20      /* Bytes of 
5690: 64 61 74 61 20 61 76 61 69 6c 61 62 6c 65 20 69  data available i
56a0: 6e 20 62 75 66 66 65 72 20 2a 2f 0a 0a 20 20 69  n buffer */..  i
56b0: 66 28 20 70 2d 3e 61 4d 61 70 20 29 7b 0a 20 20  f( p->aMap ){.  
56c0: 20 20 2a 70 70 4f 75 74 20 3d 20 26 70 2d 3e 61    *ppOut = &p->a
56d0: 4d 61 70 5b 70 2d 3e 69 52 65 61 64 4f 66 66 5d  Map[p->iReadOff]
56e0: 3b 0a 20 20 20 20 70 2d 3e 69 52 65 61 64 4f 66  ;.    p->iReadOf
56f0: 66 20 2b 3d 20 6e 42 79 74 65 3b 0a 20 20 20 20  f += nByte;.    
5700: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
5710: 3b 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 28  ;.  }..  assert(
5720: 20 70 2d 3e 61 42 75 66 66 65 72 20 29 3b 0a 0a   p->aBuffer );..
5730: 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20 69 73    /* If there is
5740: 20 6e 6f 20 6d 6f 72 65 20 64 61 74 61 20 74 6f   no more data to
5750: 20 62 65 20 72 65 61 64 20 66 72 6f 6d 20 74 68   be read from th
5760: 65 20 62 75 66 66 65 72 2c 20 72 65 61 64 20 74  e buffer, read t
5770: 68 65 20 6e 65 78 74 20 0a 20 20 2a 2a 20 70 2d  he next .  ** p-
5780: 3e 6e 42 75 66 66 65 72 20 62 79 74 65 73 20 6f  >nBuffer bytes o
5790: 66 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20  f data from the 
57a0: 66 69 6c 65 20 69 6e 74 6f 20 69 74 2e 20 4f 72  file into it. Or
57b0: 2c 20 69 66 20 74 68 65 72 65 20 61 72 65 20 6c  , if there are l
57c0: 65 73 73 0a 20 20 2a 2a 20 74 68 61 6e 20 70 2d  ess.  ** than p-
57d0: 3e 6e 42 75 66 66 65 72 20 62 79 74 65 73 20 72  >nBuffer bytes r
57e0: 65 6d 61 69 6e 69 6e 67 20 69 6e 20 74 68 65 20  emaining in the 
57f0: 50 4d 41 2c 20 72 65 61 64 20 61 6c 6c 20 72 65  PMA, read all re
5800: 6d 61 69 6e 69 6e 67 20 64 61 74 61 2e 20 20 2a  maining data.  *
5810: 2f 0a 20 20 69 42 75 66 20 3d 20 70 2d 3e 69 52  /.  iBuf = p->iR
5820: 65 61 64 4f 66 66 20 25 20 70 2d 3e 6e 42 75 66  eadOff % p->nBuf
5830: 66 65 72 3b 0a 20 20 69 66 28 20 69 42 75 66 3d  fer;.  if( iBuf=
5840: 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 52  =0 ){.    int nR
5850: 65 61 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  ead;            
5860: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
5870: 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 64 69   to read from di
5880: 73 6b 20 2a 2f 0a 20 20 20 20 69 6e 74 20 72 63  sk */.    int rc
5890: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
58a0: 20 20 20 20 20 20 20 20 2f 2a 20 73 71 6c 69 74          /* sqlit
58b0: 65 33 4f 73 52 65 61 64 28 29 20 72 65 74 75 72  e3OsRead() retur
58c0: 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 20 20 2f  n code */..    /
58d0: 2a 20 44 65 74 65 72 6d 69 6e 65 20 68 6f 77 20  * Determine how 
58e0: 6d 61 6e 79 20 62 79 74 65 73 20 6f 66 20 64 61  many bytes of da
58f0: 74 61 20 74 6f 20 72 65 61 64 2e 20 2a 2f 0a 20  ta to read. */. 
5900: 20 20 20 69 66 28 20 28 70 2d 3e 69 45 6f 66 20     if( (p->iEof 
5910: 2d 20 70 2d 3e 69 52 65 61 64 4f 66 66 29 20 3e  - p->iReadOff) >
5920: 20 28 69 36 34 29 70 2d 3e 6e 42 75 66 66 65 72   (i64)p->nBuffer
5930: 20 29 7b 0a 20 20 20 20 20 20 6e 52 65 61 64 20   ){.      nRead 
5940: 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20  = p->nBuffer;.  
5950: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6e    }else{.      n
5960: 52 65 61 64 20 3d 20 28 69 6e 74 29 28 70 2d 3e  Read = (int)(p->
5970: 69 45 6f 66 20 2d 20 70 2d 3e 69 52 65 61 64 4f  iEof - p->iReadO
5980: 66 66 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61  ff);.    }.    a
5990: 73 73 65 72 74 28 20 6e 52 65 61 64 3e 30 20 29  ssert( nRead>0 )
59a0: 3b 0a 0a 20 20 20 20 2f 2a 20 52 65 61 64 20 64  ;..    /* Read d
59b0: 61 74 61 20 66 72 6f 6d 20 74 68 65 20 66 69 6c  ata from the fil
59c0: 65 2e 20 52 65 74 75 72 6e 20 65 61 72 6c 79 20  e. Return early 
59d0: 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  if an error occu
59e0: 72 73 2e 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20  rs. */.    rc = 
59f0: 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70 2d  sqlite3OsRead(p-
5a00: 3e 70 46 69 6c 65 2c 20 70 2d 3e 61 42 75 66 66  >pFile, p->aBuff
5a10: 65 72 2c 20 6e 52 65 61 64 2c 20 70 2d 3e 69 52  er, nRead, p->iR
5a20: 65 61 64 4f 66 66 29 3b 0a 20 20 20 20 61 73 73  eadOff);.    ass
5a30: 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f  ert( rc!=SQLITE_
5a40: 49 4f 45 52 52 5f 53 48 4f 52 54 5f 52 45 41 44  IOERR_SHORT_READ
5a50: 20 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d   );.    if( rc!=
5a60: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
5a70: 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 6e 41 76  rn rc;.  }.  nAv
5a80: 61 69 6c 20 3d 20 70 2d 3e 6e 42 75 66 66 65 72  ail = p->nBuffer
5a90: 20 2d 20 69 42 75 66 3b 20 0a 0a 20 20 69 66 28   - iBuf; ..  if(
5aa0: 20 6e 42 79 74 65 3c 3d 6e 41 76 61 69 6c 20 29   nByte<=nAvail )
5ab0: 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20 72 65 71  {.    /* The req
5ac0: 75 65 73 74 65 64 20 64 61 74 61 20 69 73 20 61  uested data is a
5ad0: 76 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65 20  vailable in the 
5ae0: 69 6e 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65 72  in-memory buffer
5af0: 2e 20 49 6e 20 74 68 69 73 0a 20 20 20 20 2a 2a  . In this.    **
5b00: 20 63 61 73 65 20 74 68 65 72 65 20 69 73 20 6e   case there is n
5b10: 6f 20 6e 65 65 64 20 74 6f 20 6d 61 6b 65 20 61  o need to make a
5b20: 20 63 6f 70 79 20 6f 66 20 74 68 65 20 64 61 74   copy of the dat
5b30: 61 2c 20 6a 75 73 74 20 72 65 74 75 72 6e 20 61  a, just return a
5b40: 20 0a 20 20 20 20 2a 2a 20 70 6f 69 6e 74 65 72   .    ** pointer
5b50: 20 69 6e 74 6f 20 74 68 65 20 62 75 66 66 65 72   into the buffer
5b60: 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e 20   to the caller. 
5b70: 20 2a 2f 0a 20 20 20 20 2a 70 70 4f 75 74 20 3d   */.    *ppOut =
5b80: 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 69 42 75   &p->aBuffer[iBu
5b90: 66 5d 3b 0a 20 20 20 20 70 2d 3e 69 52 65 61 64  f];.    p->iRead
5ba0: 4f 66 66 20 2b 3d 20 6e 42 79 74 65 3b 0a 20 20  Off += nByte;.  
5bb0: 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 54 68  }else{.    /* Th
5bc0: 65 20 72 65 71 75 65 73 74 65 64 20 64 61 74 61  e requested data
5bd0: 20 69 73 20 6e 6f 74 20 61 6c 6c 20 61 76 61 69   is not all avai
5be0: 6c 61 62 6c 65 20 69 6e 20 74 68 65 20 69 6e 2d  lable in the in-
5bf0: 6d 65 6d 6f 72 79 20 62 75 66 66 65 72 2e 0a 20  memory buffer.. 
5c00: 20 20 20 2a 2a 20 49 6e 20 74 68 69 73 20 63 61     ** In this ca
5c10: 73 65 2c 20 61 6c 6c 6f 63 61 74 65 20 73 70 61  se, allocate spa
5c20: 63 65 20 61 74 20 70 2d 3e 61 41 6c 6c 6f 63 5b  ce at p->aAlloc[
5c30: 5d 20 74 6f 20 63 6f 70 79 20 74 68 65 20 72 65  ] to copy the re
5c40: 71 75 65 73 74 65 64 0a 20 20 20 20 2a 2a 20 72  quested.    ** r
5c50: 61 6e 67 65 20 69 6e 74 6f 2e 20 54 68 65 6e 20  ange into. Then 
5c60: 72 65 74 75 72 6e 20 61 20 63 6f 70 79 20 6f 66  return a copy of
5c70: 20 70 6f 69 6e 74 65 72 20 70 2d 3e 61 41 6c 6c   pointer p->aAll
5c80: 6f 63 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72  oc to the caller
5c90: 2e 20 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 52  .  */.    int nR
5ca0: 65 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  em;             
5cb0: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
5cc0: 20 72 65 6d 61 69 6e 69 6e 67 20 74 6f 20 63 6f   remaining to co
5cd0: 70 79 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 45 78  py */..    /* Ex
5ce0: 74 65 6e 64 20 74 68 65 20 70 2d 3e 61 41 6c 6c  tend the p->aAll
5cf0: 6f 63 5b 5d 20 61 6c 6c 6f 63 61 74 69 6f 6e 20  oc[] allocation 
5d00: 69 66 20 72 65 71 75 69 72 65 64 2e 20 2a 2f 0a  if required. */.
5d10: 20 20 20 20 69 66 28 20 70 2d 3e 6e 41 6c 6c 6f      if( p->nAllo
5d20: 63 3c 6e 42 79 74 65 20 29 7b 0a 20 20 20 20 20  c<nByte ){.     
5d30: 20 75 38 20 2a 61 4e 65 77 3b 0a 20 20 20 20 20   u8 *aNew;.     
5d40: 20 69 6e 74 20 6e 4e 65 77 20 3d 20 4d 41 58 28   int nNew = MAX(
5d50: 31 32 38 2c 20 70 2d 3e 6e 41 6c 6c 6f 63 2a 32  128, p->nAlloc*2
5d60: 29 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20  );.      while( 
5d70: 6e 42 79 74 65 3e 6e 4e 65 77 20 29 20 6e 4e 65  nByte>nNew ) nNe
5d80: 77 20 3d 20 6e 4e 65 77 2a 32 3b 0a 20 20 20 20  w = nNew*2;.    
5d90: 20 20 61 4e 65 77 20 3d 20 73 71 6c 69 74 65 33    aNew = sqlite3
5da0: 52 65 61 6c 6c 6f 63 28 70 2d 3e 61 41 6c 6c 6f  Realloc(p->aAllo
5db0: 63 2c 20 6e 4e 65 77 29 3b 0a 20 20 20 20 20 20  c, nNew);.      
5dc0: 69 66 28 20 21 61 4e 65 77 20 29 20 72 65 74 75  if( !aNew ) retu
5dd0: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
5de0: 0a 20 20 20 20 20 20 70 2d 3e 6e 41 6c 6c 6f 63  .      p->nAlloc
5df0: 20 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 70   = nNew;.      p
5e00: 2d 3e 61 41 6c 6c 6f 63 20 3d 20 61 4e 65 77 3b  ->aAlloc = aNew;
5e10: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 43  .    }..    /* C
5e20: 6f 70 79 20 61 73 20 6d 75 63 68 20 64 61 74 61  opy as much data
5e30: 20 61 73 20 69 73 20 61 76 61 69 6c 61 62 6c 65   as is available
5e40: 20 69 6e 20 74 68 65 20 62 75 66 66 65 72 20 69   in the buffer i
5e50: 6e 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66  nto the start of
5e60: 0a 20 20 20 20 2a 2a 20 70 2d 3e 61 41 6c 6c 6f  .    ** p->aAllo
5e70: 63 5b 5d 2e 20 20 2a 2f 0a 20 20 20 20 6d 65 6d  c[].  */.    mem
5e80: 63 70 79 28 70 2d 3e 61 41 6c 6c 6f 63 2c 20 26  cpy(p->aAlloc, &
5e90: 70 2d 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d  p->aBuffer[iBuf]
5ea0: 2c 20 6e 41 76 61 69 6c 29 3b 0a 20 20 20 20 70  , nAvail);.    p
5eb0: 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e 41  ->iReadOff += nA
5ec0: 76 61 69 6c 3b 0a 20 20 20 20 6e 52 65 6d 20 3d  vail;.    nRem =
5ed0: 20 6e 42 79 74 65 20 2d 20 6e 41 76 61 69 6c 3b   nByte - nAvail;
5ee0: 0a 0a 20 20 20 20 2f 2a 20 54 68 65 20 66 6f 6c  ..    /* The fol
5ef0: 6c 6f 77 69 6e 67 20 6c 6f 6f 70 20 63 6f 70 69  lowing loop copi
5f00: 65 73 20 75 70 20 74 6f 20 70 2d 3e 6e 42 75 66  es up to p->nBuf
5f10: 66 65 72 20 62 79 74 65 73 20 70 65 72 20 69 74  fer bytes per it
5f20: 65 72 61 74 69 6f 6e 20 69 6e 74 6f 0a 20 20 20  eration into.   
5f30: 20 2a 2a 20 74 68 65 20 70 2d 3e 61 41 6c 6c 6f   ** the p->aAllo
5f40: 63 5b 5d 20 62 75 66 66 65 72 2e 20 20 2a 2f 0a  c[] buffer.  */.
5f50: 20 20 20 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e      while( nRem>
5f60: 30 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72  0 ){.      int r
5f70: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
5f80: 20 20 20 20 20 20 20 2f 2a 20 76 64 62 65 50 6d         /* vdbePm
5f90: 61 52 65 61 64 42 6c 6f 62 28 29 20 72 65 74 75  aReadBlob() retu
5fa0: 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 20 20 20  rn code */.     
5fb0: 20 69 6e 74 20 6e 43 6f 70 79 3b 20 20 20 20 20   int nCopy;     
5fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5fd0: 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  Number of bytes 
5fe0: 74 6f 20 63 6f 70 79 20 2a 2f 0a 20 20 20 20 20  to copy */.     
5ff0: 20 75 38 20 2a 61 4e 65 78 74 3b 20 20 20 20 20   u8 *aNext;     
6000: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6010: 50 6f 69 6e 74 65 72 20 74 6f 20 62 75 66 66 65  Pointer to buffe
6020: 72 20 74 6f 20 63 6f 70 79 20 64 61 74 61 20 66  r to copy data f
6030: 72 6f 6d 20 2a 2f 0a 0a 20 20 20 20 20 20 6e 43  rom */..      nC
6040: 6f 70 79 20 3d 20 6e 52 65 6d 3b 0a 20 20 20 20  opy = nRem;.    
6050: 20 20 69 66 28 20 6e 52 65 6d 3e 70 2d 3e 6e 42    if( nRem>p->nB
6060: 75 66 66 65 72 20 29 20 6e 43 6f 70 79 20 3d 20  uffer ) nCopy = 
6070: 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20 20  p->nBuffer;.    
6080: 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65    rc = vdbePmaRe
6090: 61 64 42 6c 6f 62 28 70 2c 20 6e 43 6f 70 79 2c  adBlob(p, nCopy,
60a0: 20 26 61 4e 65 78 74 29 3b 0a 20 20 20 20 20 20   &aNext);.      
60b0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
60c0: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  K ) return rc;. 
60d0: 20 20 20 20 20 61 73 73 65 72 74 28 20 61 4e 65       assert( aNe
60e0: 78 74 21 3d 70 2d 3e 61 41 6c 6c 6f 63 20 29 3b  xt!=p->aAlloc );
60f0: 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 70  .      memcpy(&p
6100: 2d 3e 61 41 6c 6c 6f 63 5b 6e 42 79 74 65 20 2d  ->aAlloc[nByte -
6110: 20 6e 52 65 6d 5d 2c 20 61 4e 65 78 74 2c 20 6e   nRem], aNext, n
6120: 43 6f 70 79 29 3b 0a 20 20 20 20 20 20 6e 52 65  Copy);.      nRe
6130: 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20  m -= nCopy;.    
6140: 7d 0a 0a 20 20 20 20 2a 70 70 4f 75 74 20 3d 20  }..    *ppOut = 
6150: 70 2d 3e 61 41 6c 6c 6f 63 3b 0a 20 20 7d 0a 0a  p->aAlloc;.  }..
6160: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
6170: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61  OK;.}../*.** Rea
6180: 64 20 61 20 76 61 72 69 6e 74 20 66 72 6f 6d 20  d a varint from 
6190: 74 68 65 20 73 74 72 65 61 6d 20 6f 66 20 64 61  the stream of da
61a0: 74 61 20 61 63 63 65 73 73 65 64 20 62 79 20 70  ta accessed by p
61b0: 2e 20 53 65 74 20 2a 70 6e 4f 75 74 20 74 6f 0a  . Set *pnOut to.
61c0: 2a 2a 20 74 68 65 20 76 61 6c 75 65 20 72 65 61  ** the value rea
61d0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
61e0: 20 76 64 62 65 50 6d 61 52 65 61 64 56 61 72 69   vdbePmaReadVari
61f0: 6e 74 28 50 6d 61 52 65 61 64 65 72 20 2a 70 2c  nt(PmaReader *p,
6200: 20 75 36 34 20 2a 70 6e 4f 75 74 29 7b 0a 20 20   u64 *pnOut){.  
6210: 69 6e 74 20 69 42 75 66 3b 0a 0a 20 20 69 66 28  int iBuf;..  if(
6220: 20 70 2d 3e 61 4d 61 70 20 29 7b 0a 20 20 20 20   p->aMap ){.    
6230: 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 73  p->iReadOff += s
6240: 71 6c 69 74 65 33 47 65 74 56 61 72 69 6e 74 28  qlite3GetVarint(
6250: 26 70 2d 3e 61 4d 61 70 5b 70 2d 3e 69 52 65 61  &p->aMap[p->iRea
6260: 64 4f 66 66 5d 2c 20 70 6e 4f 75 74 29 3b 0a 20  dOff], pnOut);. 
6270: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 42 75 66   }else{.    iBuf
6280: 20 3d 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 25   = p->iReadOff %
6290: 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20   p->nBuffer;.   
62a0: 20 69 66 28 20 69 42 75 66 20 26 26 20 28 70 2d   if( iBuf && (p-
62b0: 3e 6e 42 75 66 66 65 72 2d 69 42 75 66 29 3e 3d  >nBuffer-iBuf)>=
62c0: 39 20 29 7b 0a 20 20 20 20 20 20 70 2d 3e 69 52  9 ){.      p->iR
62d0: 65 61 64 4f 66 66 20 2b 3d 20 73 71 6c 69 74 65  eadOff += sqlite
62e0: 33 47 65 74 56 61 72 69 6e 74 28 26 70 2d 3e 61  3GetVarint(&p->a
62f0: 42 75 66 66 65 72 5b 69 42 75 66 5d 2c 20 70 6e  Buffer[iBuf], pn
6300: 4f 75 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  Out);.    }else{
6310: 0a 20 20 20 20 20 20 75 38 20 61 56 61 72 69 6e  .      u8 aVarin
6320: 74 5b 31 36 5d 2c 20 2a 61 3b 0a 20 20 20 20 20  t[16], *a;.     
6330: 20 69 6e 74 20 69 20 3d 20 30 2c 20 72 63 3b 0a   int i = 0, rc;.
6340: 20 20 20 20 20 20 64 6f 7b 0a 20 20 20 20 20 20        do{.      
6350: 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65    rc = vdbePmaRe
6360: 61 64 42 6c 6f 62 28 70 2c 20 31 2c 20 26 61 29  adBlob(p, 1, &a)
6370: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
6380: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
6390: 20 20 20 20 20 20 61 56 61 72 69 6e 74 5b 28 69        aVarint[(i
63a0: 2b 2b 29 26 30 78 66 5d 20 3d 20 61 5b 30 5d 3b  ++)&0xf] = a[0];
63b0: 0a 20 20 20 20 20 20 7d 77 68 69 6c 65 28 20 28  .      }while( (
63c0: 61 5b 30 5d 26 30 78 38 30 29 21 3d 30 20 29 3b  a[0]&0x80)!=0 );
63d0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 47 65  .      sqlite3Ge
63e0: 74 56 61 72 69 6e 74 28 61 56 61 72 69 6e 74 2c  tVarint(aVarint,
63f0: 20 70 6e 4f 75 74 29 3b 0a 20 20 20 20 7d 0a 20   pnOut);.    }. 
6400: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c   }..  return SQL
6410: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
6420: 20 41 74 74 65 6d 70 74 20 74 6f 20 6d 65 6d 6f   Attempt to memo
6430: 72 79 20 6d 61 70 20 66 69 6c 65 20 70 46 69 6c  ry map file pFil
6440: 65 2e 20 49 66 20 73 75 63 63 65 73 73 66 75 6c  e. If successful
6450: 2c 20 73 65 74 20 2a 70 70 20 74 6f 20 70 6f 69  , set *pp to poi
6460: 6e 74 20 74 6f 20 74 68 65 0a 2a 2a 20 6e 65 77  nt to the.** new
6470: 20 6d 61 70 70 69 6e 67 20 61 6e 64 20 72 65 74   mapping and ret
6480: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 49  urn SQLITE_OK. I
6490: 66 20 74 68 65 20 6d 61 70 70 69 6e 67 20 69 73  f the mapping is
64a0: 20 6e 6f 74 20 61 74 74 65 6d 70 74 65 64 20 0a   not attempted .
64b0: 2a 2a 20 28 62 65 63 61 75 73 65 20 74 68 65 20  ** (because the 
64c0: 66 69 6c 65 20 69 73 20 74 6f 6f 20 6c 61 72 67  file is too larg
64d0: 65 20 6f 72 20 74 68 65 20 56 46 53 20 6c 61 79  e or the VFS lay
64e0: 65 72 20 69 73 20 63 6f 6e 66 69 67 75 72 65 64  er is configured
64f0: 20 6e 6f 74 20 74 6f 20 75 73 65 0a 2a 2a 20 6d   not to use.** m
6500: 6d 61 70 29 2c 20 72 65 74 75 72 6e 20 53 51 4c  map), return SQL
6510: 49 54 45 5f 4f 4b 20 61 6e 64 20 73 65 74 20 2a  ITE_OK and set *
6520: 70 70 20 74 6f 20 4e 55 4c 4c 2e 0a 2a 2a 0a 2a  pp to NULL..**.*
6530: 2a 20 4f 72 2c 20 69 66 20 61 6e 20 65 72 72 6f  * Or, if an erro
6540: 72 20 6f 63 63 75 72 73 2c 20 72 65 74 75 72 6e  r occurs, return
6550: 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
6560: 20 63 6f 64 65 2e 20 54 68 65 20 66 69 6e 61 6c   code. The final
6570: 20 76 61 6c 75 65 20 6f 66 0a 2a 2a 20 2a 70 70   value of.** *pp
6580: 20 69 73 20 75 6e 64 65 66 69 6e 65 64 20 69 6e   is undefined in
6590: 20 74 68 69 73 20 63 61 73 65 2e 0a 2a 2f 0a 73   this case..*/.s
65a0: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
65b0: 72 74 65 72 4d 61 70 46 69 6c 65 28 53 6f 72 74  rterMapFile(Sort
65c0: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20  Subtask *pTask, 
65d0: 53 6f 72 74 65 72 46 69 6c 65 20 2a 70 46 69 6c  SorterFile *pFil
65e0: 65 2c 20 75 38 20 2a 2a 70 70 29 7b 0a 20 20 69  e, u8 **pp){.  i
65f0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
6600: 4b 3b 0a 20 20 69 66 28 20 70 46 69 6c 65 2d 3e  K;.  if( pFile->
6610: 69 45 6f 66 3c 3d 28 69 36 34 29 28 70 54 61 73  iEof<=(i64)(pTas
6620: 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 64 62 2d 3e  k->pSorter->db->
6630: 6e 4d 61 78 53 6f 72 74 65 72 4d 6d 61 70 29 20  nMaxSorterMmap) 
6640: 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  ){.    rc = sqli
6650: 74 65 33 4f 73 46 65 74 63 68 28 70 46 69 6c 65  te3OsFetch(pFile
6660: 2d 3e 70 46 64 2c 20 30 2c 20 28 69 6e 74 29 70  ->pFd, 0, (int)p
6670: 46 69 6c 65 2d 3e 69 45 6f 66 2c 20 28 76 6f 69  File->iEof, (voi
6680: 64 2a 2a 29 70 70 29 3b 0a 20 20 7d 0a 20 20 72  d**)pp);.  }.  r
6690: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
66a0: 2a 2a 20 53 65 65 6b 20 69 74 65 72 61 74 6f 72  ** Seek iterator
66b0: 20 70 49 74 65 72 20 74 6f 20 6f 66 66 73 65 74   pIter to offset
66c0: 20 69 4f 66 66 20 77 69 74 68 69 6e 20 66 69 6c   iOff within fil
66d0: 65 20 70 46 69 6c 65 2e 20 52 65 74 75 72 6e 20  e pFile. Return 
66e0: 53 51 4c 49 54 45 5f 4f 4b 20 0a 2a 2a 20 69 66  SQLITE_OK .** if
66f0: 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20   successful, or 
6700: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
6710: 63 6f 64 65 20 69 66 20 61 6e 20 65 72 72 6f 72  code if an error
6720: 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74   occurs..*/.stat
6730: 69 63 20 69 6e 74 20 76 64 62 65 50 6d 61 52 65  ic int vdbePmaRe
6740: 61 64 65 72 53 65 65 6b 28 0a 20 20 53 6f 72 74  aderSeek(.  Sort
6750: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20  Subtask *pTask, 
6760: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
6770: 61 73 6b 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20  ask context */. 
6780: 20 50 6d 61 52 65 61 64 65 72 20 2a 70 49 74 65   PmaReader *pIte
6790: 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r,              
67a0: 20 2f 2a 20 49 74 65 72 61 74 65 20 74 6f 20 70   /* Iterate to p
67b0: 6f 70 75 6c 61 74 65 20 2a 2f 0a 20 20 53 6f 72  opulate */.  Sor
67c0: 74 65 72 46 69 6c 65 20 2a 70 46 69 6c 65 2c 20  terFile *pFile, 
67d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
67e0: 53 6f 72 74 65 72 20 66 69 6c 65 20 74 6f 20 72  Sorter file to r
67f0: 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 36  ead from */.  i6
6800: 34 20 69 4f 66 66 20 20 20 20 20 20 20 20 20 20  4 iOff          
6810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6820: 20 4f 66 66 73 65 74 20 69 6e 20 70 46 69 6c 65   Offset in pFile
6830: 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20   */.){.  int rc 
6840: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20  = SQLITE_OK;..  
6850: 61 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e 70  assert( pIter->p
6860: 49 6e 63 72 3d 3d 30 20 7c 7c 20 70 49 74 65 72  Incr==0 || pIter
6870: 2d 3e 70 49 6e 63 72 2d 3e 62 45 6f 66 3d 3d 30  ->pIncr->bEof==0
6880: 20 29 3b 0a 0a 20 20 69 66 28 20 70 49 74 65 72   );..  if( pIter
6890: 2d 3e 61 4d 61 70 20 29 7b 0a 20 20 20 20 73 71  ->aMap ){.    sq
68a0: 6c 69 74 65 33 4f 73 55 6e 66 65 74 63 68 28 70  lite3OsUnfetch(p
68b0: 49 74 65 72 2d 3e 70 46 69 6c 65 2c 20 30 2c 20  Iter->pFile, 0, 
68c0: 70 49 74 65 72 2d 3e 61 4d 61 70 29 3b 0a 20 20  pIter->aMap);.  
68d0: 20 20 70 49 74 65 72 2d 3e 61 4d 61 70 20 3d 20    pIter->aMap = 
68e0: 30 3b 0a 20 20 7d 0a 20 20 70 49 74 65 72 2d 3e  0;.  }.  pIter->
68f0: 69 52 65 61 64 4f 66 66 20 3d 20 69 4f 66 66 3b  iReadOff = iOff;
6900: 0a 20 20 70 49 74 65 72 2d 3e 69 45 6f 66 20 3d  .  pIter->iEof =
6910: 20 70 46 69 6c 65 2d 3e 69 45 6f 66 3b 0a 20 20   pFile->iEof;.  
6920: 70 49 74 65 72 2d 3e 70 46 69 6c 65 20 3d 20 70  pIter->pFile = p
6930: 46 69 6c 65 2d 3e 70 46 64 3b 0a 0a 20 20 72 63  File->pFd;..  rc
6940: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4d 61 70   = vdbeSorterMap
6950: 46 69 6c 65 28 70 54 61 73 6b 2c 20 70 46 69 6c  File(pTask, pFil
6960: 65 2c 20 26 70 49 74 65 72 2d 3e 61 4d 61 70 29  e, &pIter->aMap)
6970: 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
6980: 54 45 5f 4f 4b 20 26 26 20 70 49 74 65 72 2d 3e  TE_OK && pIter->
6990: 61 4d 61 70 3d 3d 30 20 29 7b 0a 20 20 20 20 69  aMap==0 ){.    i
69a0: 6e 74 20 70 67 73 7a 20 3d 20 70 54 61 73 6b 2d  nt pgsz = pTask-
69b0: 3e 70 53 6f 72 74 65 72 2d 3e 70 67 73 7a 3b 0a  >pSorter->pgsz;.
69c0: 20 20 20 20 69 6e 74 20 69 42 75 66 20 3d 20 70      int iBuf = p
69d0: 49 74 65 72 2d 3e 69 52 65 61 64 4f 66 66 20 25  Iter->iReadOff %
69e0: 20 70 67 73 7a 3b 0a 20 20 20 20 69 66 28 20 70   pgsz;.    if( p
69f0: 49 74 65 72 2d 3e 61 42 75 66 66 65 72 3d 3d 30  Iter->aBuffer==0
6a00: 20 29 7b 0a 20 20 20 20 20 20 70 49 74 65 72 2d   ){.      pIter-
6a10: 3e 61 42 75 66 66 65 72 20 3d 20 28 75 38 2a 29  >aBuffer = (u8*)
6a20: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 70 67  sqlite3Malloc(pg
6a30: 73 7a 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70  sz);.      if( p
6a40: 49 74 65 72 2d 3e 61 42 75 66 66 65 72 3d 3d 30  Iter->aBuffer==0
6a50: 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e   ) rc = SQLITE_N
6a60: 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 70 49 74 65  OMEM;.      pIte
6a70: 72 2d 3e 6e 42 75 66 66 65 72 20 3d 20 70 67 73  r->nBuffer = pgs
6a80: 7a 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  z;.    }.    if(
6a90: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
6aa0: 26 20 69 42 75 66 20 29 7b 0a 20 20 20 20 20 20  & iBuf ){.      
6ab0: 69 6e 74 20 6e 52 65 61 64 20 3d 20 70 67 73 7a  int nRead = pgsz
6ac0: 20 2d 20 69 42 75 66 3b 0a 20 20 20 20 20 20 69   - iBuf;.      i
6ad0: 66 28 20 28 70 49 74 65 72 2d 3e 69 52 65 61 64  f( (pIter->iRead
6ae0: 4f 66 66 20 2b 20 6e 52 65 61 64 29 20 3e 20 70  Off + nRead) > p
6af0: 49 74 65 72 2d 3e 69 45 6f 66 20 29 7b 0a 20 20  Iter->iEof ){.  
6b00: 20 20 20 20 20 20 6e 52 65 61 64 20 3d 20 28 69        nRead = (i
6b10: 6e 74 29 28 70 49 74 65 72 2d 3e 69 45 6f 66 20  nt)(pIter->iEof 
6b20: 2d 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66  - pIter->iReadOf
6b30: 66 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  f);.      }.    
6b40: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
6b50: 52 65 61 64 28 0a 20 20 20 20 20 20 20 20 20 20  Read(.          
6b60: 70 49 74 65 72 2d 3e 70 46 69 6c 65 2c 20 26 70  pIter->pFile, &p
6b70: 49 74 65 72 2d 3e 61 42 75 66 66 65 72 5b 69 42  Iter->aBuffer[iB
6b80: 75 66 5d 2c 20 6e 52 65 61 64 2c 20 70 49 74 65  uf], nRead, pIte
6b90: 72 2d 3e 69 52 65 61 64 4f 66 66 0a 20 20 20 20  r->iReadOff.    
6ba0: 20 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72    );.      asser
6bb0: 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 49 4f  t( rc!=SQLITE_IO
6bc0: 45 52 52 5f 53 48 4f 52 54 5f 52 45 41 44 20 29  ERR_SHORT_READ )
6bd0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  ;.    }.  }..  r
6be0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
6bf0: 2a 2a 20 41 64 76 61 6e 63 65 20 69 74 65 72 61  ** Advance itera
6c00: 74 6f 72 20 70 49 74 65 72 20 74 6f 20 74 68 65  tor pIter to the
6c10: 20 6e 65 78 74 20 6b 65 79 20 69 6e 20 69 74 73   next key in its
6c20: 20 50 4d 41 2e 20 52 65 74 75 72 6e 20 53 51 4c   PMA. Return SQL
6c30: 49 54 45 5f 4f 4b 20 69 66 0a 2a 2a 20 6e 6f 20  ITE_OK if.** no 
6c40: 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 6f 72  error occurs, or
6c50: 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
6c60: 20 63 6f 64 65 20 69 66 20 6f 6e 65 20 64 6f 65   code if one doe
6c70: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  s..*/.static int
6c80: 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 4e 65   vdbePmaReaderNe
6c90: 78 74 28 50 6d 61 52 65 61 64 65 72 20 2a 70 49  xt(PmaReader *pI
6ca0: 74 65 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  ter){.  int rc =
6cb0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20   SQLITE_OK;     
6cc0: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
6cd0: 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 75 36 34 20  n Code */.  u64 
6ce0: 6e 52 65 63 20 3d 20 30 3b 20 20 20 20 20 20 20  nRec = 0;       
6cf0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
6d00: 69 7a 65 20 6f 66 20 72 65 63 6f 72 64 20 69 6e  ize of record in
6d10: 20 62 79 74 65 73 20 2a 2f 0a 0a 20 20 69 66 28   bytes */..  if(
6d20: 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66 66   pIter->iReadOff
6d30: 3e 3d 70 49 74 65 72 2d 3e 69 45 6f 66 20 29 7b  >=pIter->iEof ){
6d40: 0a 20 20 20 20 49 6e 63 72 4d 65 72 67 65 72 20  .    IncrMerger 
6d50: 2a 70 49 6e 63 72 20 3d 20 70 49 74 65 72 2d 3e  *pIncr = pIter->
6d60: 70 49 6e 63 72 3b 0a 20 20 20 20 69 6e 74 20 62  pIncr;.    int b
6d70: 45 6f 66 20 3d 20 31 3b 0a 20 20 20 20 69 66 28  Eof = 1;.    if(
6d80: 20 70 49 6e 63 72 20 29 7b 0a 20 20 20 20 20 20   pIncr ){.      
6d90: 72 63 20 3d 20 76 64 62 65 49 6e 63 72 53 77 61  rc = vdbeIncrSwa
6da0: 70 28 70 49 6e 63 72 29 3b 0a 20 20 20 20 20 20  p(pIncr);.      
6db0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
6dc0: 4b 20 26 26 20 70 49 6e 63 72 2d 3e 62 45 6f 66  K && pIncr->bEof
6dd0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72  ==0 ){.        r
6de0: 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65  c = vdbePmaReade
6df0: 72 53 65 65 6b 28 0a 20 20 20 20 20 20 20 20 20  rSeek(.         
6e00: 20 20 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b 2c     pIncr->pTask,
6e10: 20 70 49 74 65 72 2c 20 26 70 49 6e 63 72 2d 3e   pIter, &pIncr->
6e20: 61 46 69 6c 65 5b 30 5d 2c 20 70 49 6e 63 72 2d  aFile[0], pIncr-
6e30: 3e 69 53 74 61 72 74 4f 66 66 0a 20 20 20 20 20  >iStartOff.     
6e40: 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 62 45     );.        bE
6e50: 6f 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a  of = 0;.      }.
6e60: 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 62      }..    if( b
6e70: 45 6f 66 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  Eof ){.      /* 
6e80: 54 68 69 73 20 69 73 20 61 6e 20 45 4f 46 20 63  This is an EOF c
6e90: 6f 6e 64 69 74 69 6f 6e 20 2a 2f 0a 20 20 20 20  ondition */.    
6ea0: 20 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 43    vdbePmaReaderC
6eb0: 6c 65 61 72 28 70 49 74 65 72 29 3b 0a 20 20 20  lear(pIter);.   
6ec0: 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
6ed0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72    }.  }..  if( r
6ee0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
6ef0: 20 20 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61      rc = vdbePma
6f00: 52 65 61 64 56 61 72 69 6e 74 28 70 49 74 65 72  ReadVarint(pIter
6f10: 2c 20 26 6e 52 65 63 29 3b 0a 20 20 7d 0a 20 20  , &nRec);.  }.  
6f20: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
6f30: 4b 20 29 7b 0a 20 20 20 20 70 49 74 65 72 2d 3e  K ){.    pIter->
6f40: 6e 4b 65 79 20 3d 20 28 69 6e 74 29 6e 52 65 63  nKey = (int)nRec
6f50: 3b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 50  ;.    rc = vdbeP
6f60: 6d 61 52 65 61 64 42 6c 6f 62 28 70 49 74 65 72  maReadBlob(pIter
6f70: 2c 20 28 69 6e 74 29 6e 52 65 63 2c 20 26 70 49  , (int)nRec, &pI
6f80: 74 65 72 2d 3e 61 4b 65 79 29 3b 0a 20 20 7d 0a  ter->aKey);.  }.
6f90: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
6fa0: 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a  ./*.** Initializ
6fb0: 65 20 69 74 65 72 61 74 6f 72 20 70 49 74 65 72  e iterator pIter
6fc0: 20 74 6f 20 73 63 61 6e 20 74 68 72 6f 75 67 68   to scan through
6fd0: 20 74 68 65 20 50 4d 41 20 73 74 6f 72 65 64 20   the PMA stored 
6fe0: 69 6e 20 66 69 6c 65 20 70 46 69 6c 65 0a 2a 2a  in file pFile.**
6ff0: 20 73 74 61 72 74 69 6e 67 20 61 74 20 6f 66 66   starting at off
7000: 73 65 74 20 69 53 74 61 72 74 20 61 6e 64 20 65  set iStart and e
7010: 6e 64 69 6e 67 20 61 74 20 6f 66 66 73 65 74 20  nding at offset 
7020: 69 45 6f 66 2d 31 2e 20 54 68 69 73 20 66 75 6e  iEof-1. This fun
7030: 63 74 69 6f 6e 20 0a 2a 2a 20 6c 65 61 76 65 73  ction .** leaves
7040: 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 70 6f   the iterator po
7050: 69 6e 74 69 6e 67 20 74 6f 20 74 68 65 20 66 69  inting to the fi
7060: 72 73 74 20 6b 65 79 20 69 6e 20 74 68 65 20 50  rst key in the P
7070: 4d 41 20 28 6f 72 20 45 4f 46 20 69 66 20 74 68  MA (or EOF if th
7080: 65 20 0a 2a 2a 20 50 4d 41 20 69 73 20 65 6d 70  e .** PMA is emp
7090: 74 79 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  ty)..**.** If th
70a0: 65 20 70 6e 42 79 74 65 20 70 61 72 61 6d 65 74  e pnByte paramet
70b0: 65 72 20 69 73 20 4e 55 4c 4c 2c 20 74 68 65 6e  er is NULL, then
70c0: 20 69 74 20 69 73 20 61 73 73 75 6d 65 64 20 74   it is assumed t
70d0: 68 61 74 20 74 68 65 20 66 69 6c 65 20 0a 2a 2a  hat the file .**
70e0: 20 63 6f 6e 74 61 69 6e 73 20 61 20 73 69 6e 67   contains a sing
70f0: 6c 65 20 50 4d 41 2c 20 61 6e 64 20 74 68 61 74  le PMA, and that
7100: 20 74 68 61 74 20 50 4d 41 20 6f 6d 69 74 73 20   that PMA omits 
7110: 74 68 65 20 69 6e 69 74 69 61 6c 20 6c 65 6e 67  the initial leng
7120: 74 68 20 76 61 72 69 6e 74 2e 0a 2a 2f 0a 73 74  th varint..*/.st
7130: 61 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d 61  atic int vdbePma
7140: 52 65 61 64 65 72 49 6e 69 74 28 0a 20 20 53 6f  ReaderInit(.  So
7150: 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b  rtSubtask *pTask
7160: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
7170: 20 54 61 73 6b 20 63 6f 6e 74 65 78 74 20 2a 2f   Task context */
7180: 0a 20 20 53 6f 72 74 65 72 46 69 6c 65 20 2a 70  .  SorterFile *p
7190: 46 69 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20  File,           
71a0: 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 66 69 6c     /* Sorter fil
71b0: 65 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a  e to read from *
71c0: 2f 0a 20 20 69 36 34 20 69 53 74 61 72 74 2c 20  /.  i64 iStart, 
71d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
71e0: 20 20 20 20 2f 2a 20 53 74 61 72 74 20 6f 66 66      /* Start off
71f0: 73 65 74 20 69 6e 20 70 46 69 6c 65 20 2a 2f 0a  set in pFile */.
7200: 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70 49 74    PmaReader *pIt
7210: 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  er,             
7220: 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 74 6f    /* Iterator to
7230: 20 70 6f 70 75 6c 61 74 65 20 2a 2f 0a 20 20 69   populate */.  i
7240: 36 34 20 2a 70 6e 42 79 74 65 20 20 20 20 20 20  64 *pnByte      
7250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7260: 2a 20 49 4e 2f 4f 55 54 3a 20 49 6e 63 72 65 6d  * IN/OUT: Increm
7270: 65 6e 74 20 74 68 69 73 20 76 61 6c 75 65 20 62  ent this value b
7280: 79 20 50 4d 41 20 73 69 7a 65 20 2a 2f 0a 29 7b  y PMA size */.){
7290: 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 61 73  .  int rc;..  as
72a0: 73 65 72 74 28 20 70 46 69 6c 65 2d 3e 69 45 6f  sert( pFile->iEo
72b0: 66 3e 69 53 74 61 72 74 20 29 3b 0a 20 20 61 73  f>iStart );.  as
72c0: 73 65 72 74 28 20 70 49 74 65 72 2d 3e 61 41 6c  sert( pIter->aAl
72d0: 6c 6f 63 3d 3d 30 20 26 26 20 70 49 74 65 72 2d  loc==0 && pIter-
72e0: 3e 6e 41 6c 6c 6f 63 3d 3d 30 20 29 3b 0a 20 20  >nAlloc==0 );.  
72f0: 61 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e 61  assert( pIter->a
7300: 42 75 66 66 65 72 3d 3d 30 20 29 3b 0a 20 20 61  Buffer==0 );.  a
7310: 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e 61 4d  ssert( pIter->aM
7320: 61 70 3d 3d 30 20 29 3b 0a 0a 20 20 72 63 20 3d  ap==0 );..  rc =
7330: 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 53 65   vdbePmaReaderSe
7340: 65 6b 28 70 54 61 73 6b 2c 20 70 49 74 65 72 2c  ek(pTask, pIter,
7350: 20 70 46 69 6c 65 2c 20 69 53 74 61 72 74 29 3b   pFile, iStart);
7360: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
7370: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 75 36 34 20  E_OK ){.    u64 
7380: 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20 20 20  nByte;          
7390: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
73a0: 65 20 6f 66 20 50 4d 41 20 69 6e 20 62 79 74 65  e of PMA in byte
73b0: 73 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 76 64  s */.    rc = vd
73c0: 62 65 50 6d 61 52 65 61 64 56 61 72 69 6e 74 28  bePmaReadVarint(
73d0: 70 49 74 65 72 2c 20 26 6e 42 79 74 65 29 3b 0a  pIter, &nByte);.
73e0: 20 20 20 20 70 49 74 65 72 2d 3e 69 45 6f 66 20      pIter->iEof 
73f0: 3d 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66  = pIter->iReadOf
7400: 66 20 2b 20 6e 42 79 74 65 3b 0a 20 20 20 20 2a  f + nByte;.    *
7410: 70 6e 42 79 74 65 20 2b 3d 20 6e 42 79 74 65 3b  pnByte += nByte;
7420: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
7430: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
7440: 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61   rc = vdbePmaRea
7450: 64 65 72 4e 65 78 74 28 70 49 74 65 72 29 3b 0a  derNext(pIter);.
7460: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
7470: 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 61  .}.../*.** Compa
7480: 72 65 20 6b 65 79 31 20 28 62 75 66 66 65 72 20  re key1 (buffer 
7490: 70 4b 65 79 31 2c 20 73 69 7a 65 20 6e 4b 65 79  pKey1, size nKey
74a0: 31 20 62 79 74 65 73 29 20 77 69 74 68 20 6b 65  1 bytes) with ke
74b0: 79 32 20 28 62 75 66 66 65 72 20 70 4b 65 79 32  y2 (buffer pKey2
74c0: 2c 20 0a 2a 2a 20 73 69 7a 65 20 6e 4b 65 79 32  , .** size nKey2
74d0: 20 62 79 74 65 73 29 2e 20 55 73 65 20 28 70 54   bytes). Use (pT
74e0: 61 73 6b 2d 3e 70 4b 65 79 49 6e 66 6f 29 20 66  ask->pKeyInfo) f
74f0: 6f 72 20 74 68 65 20 63 6f 6c 6c 61 74 69 6f 6e  or the collation
7500: 20 73 65 71 75 65 6e 63 65 73 0a 2a 2a 20 75 73   sequences.** us
7510: 65 64 20 62 79 20 74 68 65 20 63 6f 6d 70 61 72  ed by the compar
7520: 69 73 6f 6e 2e 20 52 65 74 75 72 6e 20 74 68 65  ison. Return the
7530: 20 72 65 73 75 6c 74 20 6f 66 20 74 68 65 20 63   result of the c
7540: 6f 6d 70 61 72 69 73 6f 6e 2e 0a 2a 2a 0a 2a 2a  omparison..**.**
7550: 20 42 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e   Before returnin
7560: 67 2c 20 6f 62 6a 65 63 74 20 28 70 54 61 73 6b  g, object (pTask
7570: 2d 3e 70 55 6e 70 61 63 6b 65 64 29 20 69 73 20  ->pUnpacked) is 
7580: 70 6f 70 75 6c 61 74 65 64 20 77 69 74 68 20 74  populated with t
7590: 68 65 0a 2a 2a 20 75 6e 70 61 63 6b 65 64 20 76  he.** unpacked v
75a0: 65 72 73 69 6f 6e 20 6f 66 20 6b 65 79 32 2e 20  ersion of key2. 
75b0: 4f 72 2c 20 69 66 20 70 4b 65 79 32 20 69 73 20  Or, if pKey2 is 
75c0: 70 61 73 73 65 64 20 61 20 4e 55 4c 4c 20 70 6f  passed a NULL po
75d0: 69 6e 74 65 72 2c 20 74 68 65 6e 20 69 74 20 0a  inter, then it .
75e0: 2a 2a 20 69 73 20 61 73 73 75 6d 65 64 20 74 68  ** is assumed th
75f0: 61 74 20 74 68 65 20 28 70 54 61 73 6b 2d 3e 70  at the (pTask->p
7600: 55 6e 70 61 63 6b 65 64 29 20 73 74 72 75 63 74  Unpacked) struct
7610: 75 72 65 20 61 6c 72 65 61 64 79 20 63 6f 6e 74  ure already cont
7620: 61 69 6e 73 20 74 68 65 20 0a 2a 2a 20 75 6e 70  ains the .** unp
7630: 61 63 6b 65 64 20 6b 65 79 20 74 6f 20 75 73 65  acked key to use
7640: 20 61 73 20 6b 65 79 32 2e 0a 2a 2a 0a 2a 2a 20   as key2..**.** 
7650: 49 66 20 61 6e 20 4f 4f 4d 20 65 72 72 6f 72 20  If an OOM error 
7660: 69 73 20 65 6e 63 6f 75 6e 74 65 72 65 64 2c 20  is encountered, 
7670: 28 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65  (pTask->pUnpacke
7680: 64 2d 3e 65 72 72 6f 72 5f 72 63 29 20 69 73 20  d->error_rc) is 
7690: 73 65 74 0a 2a 2a 20 74 6f 20 53 51 4c 49 54 45  set.** to SQLITE
76a0: 5f 4e 4f 4d 45 4d 2e 0a 2a 2f 0a 73 74 61 74 69  _NOMEM..*/.stati
76b0: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72  c int vdbeSorter
76c0: 43 6f 6d 70 61 72 65 28 0a 20 20 53 6f 72 74 53  Compare(.  SortS
76d0: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20  ubtask *pTask,  
76e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 75             /* Su
76f0: 62 74 61 73 6b 20 63 6f 6e 74 65 78 74 20 28 66  btask context (f
7700: 6f 72 20 70 4b 65 79 49 6e 66 6f 29 20 2a 2f 0a  or pKeyInfo) */.
7710: 20 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 4b    const void *pK
7720: 65 79 31 2c 20 69 6e 74 20 6e 4b 65 79 31 2c 20  ey1, int nKey1, 
7730: 20 20 2f 2a 20 4c 65 66 74 20 73 69 64 65 20 6f    /* Left side o
7740: 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f 0a  f comparison */.
7750: 20 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 4b    const void *pK
7760: 65 79 32 2c 20 69 6e 74 20 6e 4b 65 79 32 20 20  ey2, int nKey2  
7770: 20 20 2f 2a 20 52 69 67 68 74 20 73 69 64 65 20    /* Right side 
7780: 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f  of comparison */
7790: 0a 29 7b 0a 20 20 55 6e 70 61 63 6b 65 64 52 65  .){.  UnpackedRe
77a0: 63 6f 72 64 20 2a 72 32 20 3d 20 70 54 61 73 6b  cord *r2 = pTask
77b0: 2d 3e 70 55 6e 70 61 63 6b 65 64 3b 0a 20 20 69  ->pUnpacked;.  i
77c0: 66 28 20 70 4b 65 79 32 20 29 7b 0a 20 20 20 20  f( pKey2 ){.    
77d0: 73 71 6c 69 74 65 33 56 64 62 65 52 65 63 6f 72  sqlite3VdbeRecor
77e0: 64 55 6e 70 61 63 6b 28 70 54 61 73 6b 2d 3e 70  dUnpack(pTask->p
77f0: 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49 6e 66 6f  Sorter->pKeyInfo
7800: 2c 20 6e 4b 65 79 32 2c 20 70 4b 65 79 32 2c 20  , nKey2, pKey2, 
7810: 72 32 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  r2);.  }.  retur
7820: 6e 20 73 71 6c 69 74 65 33 56 64 62 65 52 65 63  n sqlite3VdbeRec
7830: 6f 72 64 43 6f 6d 70 61 72 65 28 6e 4b 65 79 31  ordCompare(nKey1
7840: 2c 20 70 4b 65 79 31 2c 20 72 32 2c 20 30 29 3b  , pKey1, r2, 0);
7850: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
7860: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
7870: 64 20 74 6f 20 63 6f 6d 70 61 72 65 20 74 77 6f  d to compare two
7880: 20 69 74 65 72 61 74 6f 72 20 6b 65 79 73 20 77   iterator keys w
7890: 68 65 6e 20 6d 65 72 67 69 6e 67 20 0a 2a 2a 20  hen merging .** 
78a0: 6d 75 6c 74 69 70 6c 65 20 62 2d 74 72 65 65 20  multiple b-tree 
78b0: 73 65 67 6d 65 6e 74 73 2e 20 50 61 72 61 6d 65  segments. Parame
78c0: 74 65 72 20 69 4f 75 74 20 69 73 20 74 68 65 20  ter iOut is the 
78d0: 69 6e 64 65 78 20 6f 66 20 74 68 65 20 61 54 72  index of the aTr
78e0: 65 65 5b 5d 20 0a 2a 2a 20 76 61 6c 75 65 20 74  ee[] .** value t
78f0: 6f 20 72 65 63 61 6c 63 75 6c 61 74 65 2e 0a 2a  o recalculate..*
7900: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
7910: 65 53 6f 72 74 65 72 44 6f 43 6f 6d 70 61 72 65  eSorterDoCompare
7920: 28 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20  (.  SortSubtask 
7930: 2a 70 54 61 73 6b 2c 20 0a 20 20 4d 65 72 67 65  *pTask, .  Merge
7940: 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 2c  Engine *pMerger,
7950: 20 0a 20 20 69 6e 74 20 69 4f 75 74 0a 29 7b 0a   .  int iOut.){.
7960: 20 20 69 6e 74 20 69 31 3b 0a 20 20 69 6e 74 20    int i1;.  int 
7970: 69 32 3b 0a 20 20 69 6e 74 20 69 52 65 73 3b 0a  i2;.  int iRes;.
7980: 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70 31 3b    PmaReader *p1;
7990: 0a 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70 32  .  PmaReader *p2
79a0: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 69 4f 75  ;..  assert( iOu
79b0: 74 3c 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65  t<pMerger->nTree
79c0: 20 26 26 20 69 4f 75 74 3e 30 20 29 3b 0a 0a 20   && iOut>0 );.. 
79d0: 20 69 66 28 20 69 4f 75 74 3e 3d 28 70 4d 65 72   if( iOut>=(pMer
79e0: 67 65 72 2d 3e 6e 54 72 65 65 2f 32 29 20 29 7b  ger->nTree/2) ){
79f0: 0a 20 20 20 20 69 31 20 3d 20 28 69 4f 75 74 20  .    i1 = (iOut 
7a00: 2d 20 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65  - pMerger->nTree
7a10: 2f 32 29 20 2a 20 32 3b 0a 20 20 20 20 69 32 20  /2) * 2;.    i2 
7a20: 3d 20 69 31 20 2b 20 31 3b 0a 20 20 7d 65 6c 73  = i1 + 1;.  }els
7a30: 65 7b 0a 20 20 20 20 69 31 20 3d 20 70 4d 65 72  e{.    i1 = pMer
7a40: 67 65 72 2d 3e 61 54 72 65 65 5b 69 4f 75 74 2a  ger->aTree[iOut*
7a50: 32 5d 3b 0a 20 20 20 20 69 32 20 3d 20 70 4d 65  2];.    i2 = pMe
7a60: 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 4f 75 74  rger->aTree[iOut
7a70: 2a 32 2b 31 5d 3b 0a 20 20 7d 0a 0a 20 20 70 31  *2+1];.  }..  p1
7a80: 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49 74   = &pMerger->aIt
7a90: 65 72 5b 69 31 5d 3b 0a 20 20 70 32 20 3d 20 26  er[i1];.  p2 = &
7aa0: 70 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 69  pMerger->aIter[i
7ab0: 32 5d 3b 0a 0a 20 20 69 66 28 20 70 31 2d 3e 70  2];..  if( p1->p
7ac0: 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69  File==0 ){.    i
7ad0: 52 65 73 20 3d 20 69 32 3b 0a 20 20 7d 65 6c 73  Res = i2;.  }els
7ae0: 65 20 69 66 28 20 70 32 2d 3e 70 46 69 6c 65 3d  e if( p2->pFile=
7af0: 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 73 20 3d  =0 ){.    iRes =
7b00: 20 69 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20   i1;.  }else{.  
7b10: 20 20 69 6e 74 20 72 65 73 3b 0a 20 20 20 20 61    int res;.    a
7b20: 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 70 55  ssert( pTask->pU
7b30: 6e 70 61 63 6b 65 64 21 3d 30 20 29 3b 20 20 2f  npacked!=0 );  /
7b40: 2a 20 61 6c 6c 6f 63 61 74 65 64 20 69 6e 20 76  * allocated in v
7b50: 64 62 65 53 6f 72 74 53 75 62 74 61 73 6b 4d 61  dbeSortSubtaskMa
7b60: 69 6e 28 29 20 2a 2f 0a 20 20 20 20 72 65 73 20  in() */.    res 
7b70: 3d 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70  = vdbeSorterComp
7b80: 61 72 65 28 0a 20 20 20 20 20 20 20 20 70 54 61  are(.        pTa
7b90: 73 6b 2c 20 70 31 2d 3e 61 4b 65 79 2c 20 70 31  sk, p1->aKey, p1
7ba0: 2d 3e 6e 4b 65 79 2c 20 70 32 2d 3e 61 4b 65 79  ->nKey, p2->aKey
7bb0: 2c 20 70 32 2d 3e 6e 4b 65 79 0a 20 20 20 20 29  , p2->nKey.    )
7bc0: 3b 0a 20 20 20 20 69 66 28 20 72 65 73 3c 3d 30  ;.    if( res<=0
7bd0: 20 29 7b 0a 20 20 20 20 20 20 69 52 65 73 20 3d   ){.      iRes =
7be0: 20 69 31 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a   i1;.    }else{.
7bf0: 20 20 20 20 20 20 69 52 65 73 20 3d 20 69 32 3b        iRes = i2;
7c00: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 70 4d  .    }.  }..  pM
7c10: 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 4f 75  erger->aTree[iOu
7c20: 74 5d 20 3d 20 69 52 65 73 3b 0a 20 20 72 65 74  t] = iRes;.  ret
7c30: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
7c40: 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69  ../*.** Initiali
7c50: 7a 65 20 74 68 65 20 74 65 6d 70 6f 72 61 72 79  ze the temporary
7c60: 20 69 6e 64 65 78 20 63 75 72 73 6f 72 20 6a 75   index cursor ju
7c70: 73 74 20 6f 70 65 6e 65 64 20 61 73 20 61 20 73  st opened as a s
7c80: 6f 72 74 65 72 20 63 75 72 73 6f 72 2e 0a 2a 2a  orter cursor..**
7c90: 0a 2a 2a 20 55 73 75 61 6c 6c 79 2c 20 74 68 65  .** Usually, the
7ca0: 20 73 6f 72 74 65 72 20 6d 6f 64 75 6c 65 20 75   sorter module u
7cb0: 73 65 73 20 74 68 65 20 76 61 6c 75 65 20 6f 66  ses the value of
7cc0: 20 28 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f   (pCsr->pKeyInfo
7cd0: 2d 3e 6e 46 69 65 6c 64 29 0a 2a 2a 20 74 6f 20  ->nField).** to 
7ce0: 64 65 74 65 72 6d 69 6e 65 20 74 68 65 20 6e 75  determine the nu
7cf0: 6d 62 65 72 20 6f 66 20 66 69 65 6c 64 73 20 74  mber of fields t
7d00: 68 61 74 20 73 68 6f 75 6c 64 20 62 65 20 63 6f  hat should be co
7d10: 6d 70 61 72 65 64 20 66 72 6f 6d 20 74 68 65 0a  mpared from the.
7d20: 2a 2a 20 72 65 63 6f 72 64 73 20 62 65 69 6e 67  ** records being
7d30: 20 73 6f 72 74 65 64 2e 20 48 6f 77 65 76 65 72   sorted. However
7d40: 2c 20 69 66 20 74 68 65 20 76 61 6c 75 65 20 70  , if the value p
7d50: 61 73 73 65 64 20 61 73 20 61 72 67 75 6d 65 6e  assed as argumen
7d60: 74 20 6e 46 69 65 6c 64 0a 2a 2a 20 69 73 20 6e  t nField.** is n
7d70: 6f 6e 2d 7a 65 72 6f 20 61 6e 64 20 74 68 65 20  on-zero and the 
7d80: 73 6f 72 74 65 72 20 69 73 20 61 62 6c 65 20 74  sorter is able t
7d90: 6f 20 67 75 61 72 61 6e 74 65 65 20 61 20 73 74  o guarantee a st
7da0: 61 62 6c 65 20 73 6f 72 74 2c 20 6e 46 69 65 6c  able sort, nFiel
7db0: 64 0a 2a 2a 20 69 73 20 75 73 65 64 20 69 6e 73  d.** is used ins
7dc0: 74 65 61 64 2e 20 54 68 69 73 20 69 73 20 75 73  tead. This is us
7dd0: 65 64 20 77 68 65 6e 20 73 6f 72 74 69 6e 67 20  ed when sorting 
7de0: 72 65 63 6f 72 64 73 20 66 6f 72 20 61 20 43 52  records for a CR
7df0: 45 41 54 45 20 49 4e 44 45 58 0a 2a 2a 20 73 74  EATE INDEX.** st
7e00: 61 74 65 6d 65 6e 74 2e 20 49 6e 20 74 68 69 73  atement. In this
7e10: 20 63 61 73 65 2c 20 6b 65 79 73 20 61 72 65 20   case, keys are 
7e20: 61 6c 77 61 79 73 20 64 65 6c 69 76 65 72 65 64  always delivered
7e30: 20 74 6f 20 74 68 65 20 73 6f 72 74 65 72 20 69   to the sorter i
7e40: 6e 0a 2a 2a 20 6f 72 64 65 72 20 6f 66 20 74 68  n.** order of th
7e50: 65 20 70 72 69 6d 61 72 79 20 6b 65 79 2c 20 77  e primary key, w
7e60: 68 69 63 68 20 68 61 70 70 65 6e 73 20 74 6f 20  hich happens to 
7e70: 62 65 20 6d 61 6b 65 20 75 70 20 74 68 65 20 66  be make up the f
7e80: 69 6e 61 6c 20 70 61 72 74 20 0a 2a 2a 20 6f 66  inal part .** of
7e90: 20 74 68 65 20 72 65 63 6f 72 64 73 20 62 65 69   the records bei
7ea0: 6e 67 20 73 6f 72 74 65 64 2e 20 53 6f 20 69 66  ng sorted. So if
7eb0: 20 74 68 65 20 73 6f 72 74 20 69 73 20 73 74 61   the sort is sta
7ec0: 62 6c 65 2c 20 74 68 65 72 65 20 69 73 20 6e 65  ble, there is ne
7ed0: 76 65 72 0a 2a 2a 20 61 6e 79 20 72 65 61 73 6f  ver.** any reaso
7ee0: 6e 20 74 6f 20 63 6f 6d 70 61 72 65 20 50 4b 20  n to compare PK 
7ef0: 66 69 65 6c 64 73 20 61 6e 64 20 74 68 65 79 20  fields and they 
7f00: 63 61 6e 20 62 65 20 69 67 6e 6f 72 65 64 20 66  can be ignored f
7f10: 6f 72 20 61 20 73 6d 61 6c 6c 0a 2a 2a 20 70 65  or a small.** pe
7f20: 72 66 6f 72 6d 61 6e 63 65 20 62 6f 6f 73 74 2e  rformance boost.
7f30: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 6f 72 74 65  .**.** The sorte
7f40: 72 20 63 61 6e 20 67 75 61 72 61 6e 74 65 65 20  r can guarantee 
7f50: 61 20 73 74 61 62 6c 65 20 73 6f 72 74 20 77 68  a stable sort wh
7f60: 65 6e 20 72 75 6e 6e 69 6e 67 20 69 6e 20 73 69  en running in si
7f70: 6e 67 6c 65 2d 74 68 72 65 61 64 65 64 0a 2a 2a  ngle-threaded.**
7f80: 20 6d 6f 64 65 2c 20 62 75 74 20 6e 6f 74 20 69   mode, but not i
7f90: 6e 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64  n multi-threaded
7fa0: 20 6d 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c   mode..**.** SQL
7fb0: 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e  ITE_OK is return
7fc0: 65 64 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  ed if successful
7fd0: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65  , or an SQLite e
7fe0: 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77  rror code otherw
7ff0: 69 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  ise..*/.int sqli
8000: 74 65 33 56 64 62 65 53 6f 72 74 65 72 49 6e 69  te3VdbeSorterIni
8010: 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  t(.  sqlite3 *db
8020: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8030: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
8040: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 28 66 6f 72   connection (for
8050: 20 6d 61 6c 6c 6f 63 28 29 29 20 2a 2f 0a 20 20   malloc()) */.  
8060: 69 6e 74 20 6e 46 69 65 6c 64 2c 20 20 20 20 20  int nField,     
8070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8080: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 6b 65 79  /* Number of key
8090: 20 66 69 65 6c 64 73 20 69 6e 20 65 61 63 68 20   fields in each 
80a0: 72 65 63 6f 72 64 20 2a 2f 0a 20 20 56 64 62 65  record */.  Vdbe
80b0: 43 75 72 73 6f 72 20 2a 70 43 73 72 20 20 20 20  Cursor *pCsr    
80c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
80d0: 75 72 73 6f 72 20 74 68 61 74 20 68 6f 6c 64 73  ursor that holds
80e0: 20 74 68 65 20 6e 65 77 20 73 6f 72 74 65 72 20   the new sorter 
80f0: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 70 67 73 7a  */.){.  int pgsz
8100: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
8110: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20          /* Page 
8120: 73 69 7a 65 20 6f 66 20 6d 61 69 6e 20 64 61 74  size of main dat
8130: 61 62 61 73 65 20 2a 2f 0a 20 20 69 6e 74 20 69  abase */.  int i
8140: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
8150: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73             /* Us
8160: 65 64 20 74 6f 20 69 74 65 72 61 74 65 20 74 68  ed to iterate th
8170: 72 6f 75 67 68 20 61 54 61 73 6b 5b 5d 20 2a 2f  rough aTask[] */
8180: 0a 20 20 69 6e 74 20 6d 78 43 61 63 68 65 3b 20  .  int mxCache; 
8190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
81a0: 20 20 20 2f 2a 20 43 61 63 68 65 20 73 69 7a 65     /* Cache size
81b0: 20 2a 2f 0a 20 20 56 64 62 65 53 6f 72 74 65 72   */.  VdbeSorter
81c0: 20 2a 70 53 6f 72 74 65 72 3b 20 20 20 20 20 20   *pSorter;      
81d0: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77        /* The new
81e0: 20 73 6f 72 74 65 72 20 2a 2f 0a 20 20 4b 65 79   sorter */.  Key
81f0: 49 6e 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 3b 20  Info *pKeyInfo; 
8200: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8210: 43 6f 70 79 20 6f 66 20 70 43 73 72 2d 3e 70 4b  Copy of pCsr->pK
8220: 65 79 49 6e 66 6f 20 77 69 74 68 20 64 62 3d 3d  eyInfo with db==
8230: 30 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 4b 65 79  0 */.  int szKey
8240: 49 6e 66 6f 3b 20 20 20 20 20 20 20 20 20 20 20  Info;           
8250: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
8260: 66 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f  f pCsr->pKeyInfo
8270: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69   in bytes */.  i
8280: 6e 74 20 73 7a 3b 20 20 20 20 20 20 20 20 20 20  nt sz;          
8290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
82a0: 2a 20 53 69 7a 65 20 6f 66 20 70 53 6f 72 74 65  * Size of pSorte
82b0: 72 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  r in bytes */.  
82c0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
82d0: 4f 4b 3b 0a 20 20 69 6e 74 20 6e 57 6f 72 6b 65  OK;.  int nWorke
82e0: 72 20 3d 20 28 73 71 6c 69 74 65 33 47 6c 6f 62  r = (sqlite3Glob
82f0: 61 6c 43 6f 6e 66 69 67 2e 62 43 6f 72 65 4d 75  alConfig.bCoreMu
8300: 74 65 78 3f 73 71 6c 69 74 65 33 47 6c 6f 62 61  tex?sqlite3Globa
8310: 6c 43 6f 6e 66 69 67 2e 6e 57 6f 72 6b 65 72 3a  lConfig.nWorker:
8320: 30 29 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  0);..  assert( p
8330: 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 20 26 26  Csr->pKeyInfo &&
8340: 20 70 43 73 72 2d 3e 70 42 74 3d 3d 30 20 29 3b   pCsr->pBt==0 );
8350: 0a 20 20 73 7a 4b 65 79 49 6e 66 6f 20 3d 20 73  .  szKeyInfo = s
8360: 69 7a 65 6f 66 28 4b 65 79 49 6e 66 6f 29 20 2b  izeof(KeyInfo) +
8370: 20 28 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f   (pCsr->pKeyInfo
8380: 2d 3e 6e 46 69 65 6c 64 2d 31 29 2a 73 69 7a 65  ->nField-1)*size
8390: 6f 66 28 43 6f 6c 6c 53 65 71 2a 29 3b 0a 20 20  of(CollSeq*);.  
83a0: 73 7a 20 3d 20 73 69 7a 65 6f 66 28 56 64 62 65  sz = sizeof(Vdbe
83b0: 53 6f 72 74 65 72 29 20 2b 20 6e 57 6f 72 6b 65  Sorter) + nWorke
83c0: 72 20 2a 20 73 69 7a 65 6f 66 28 53 6f 72 74 53  r * sizeof(SortS
83d0: 75 62 74 61 73 6b 29 3b 0a 0a 20 20 70 53 6f 72  ubtask);..  pSor
83e0: 74 65 72 20 3d 20 28 56 64 62 65 53 6f 72 74 65  ter = (VdbeSorte
83f0: 72 2a 29 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c  r*)sqlite3DbMall
8400: 6f 63 5a 65 72 6f 28 64 62 2c 20 73 7a 20 2b 20  ocZero(db, sz + 
8410: 73 7a 4b 65 79 49 6e 66 6f 29 3b 0a 20 20 70 43  szKeyInfo);.  pC
8420: 73 72 2d 3e 70 53 6f 72 74 65 72 20 3d 20 70 53  sr->pSorter = pS
8430: 6f 72 74 65 72 3b 0a 20 20 69 66 28 20 70 53 6f  orter;.  if( pSo
8440: 72 74 65 72 3d 3d 30 20 29 7b 0a 20 20 20 20 72  rter==0 ){.    r
8450: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
8460: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70  ;.  }else{.    p
8470: 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49 6e 66 6f  Sorter->pKeyInfo
8480: 20 3d 20 70 4b 65 79 49 6e 66 6f 20 3d 20 28 4b   = pKeyInfo = (K
8490: 65 79 49 6e 66 6f 2a 29 28 28 75 38 2a 29 70 53  eyInfo*)((u8*)pS
84a0: 6f 72 74 65 72 20 2b 20 73 7a 29 3b 0a 20 20 20  orter + sz);.   
84b0: 20 6d 65 6d 63 70 79 28 70 4b 65 79 49 6e 66 6f   memcpy(pKeyInfo
84c0: 2c 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f  , pCsr->pKeyInfo
84d0: 2c 20 73 7a 4b 65 79 49 6e 66 6f 29 3b 0a 20 20  , szKeyInfo);.  
84e0: 20 20 70 4b 65 79 49 6e 66 6f 2d 3e 64 62 20 3d    pKeyInfo->db =
84f0: 20 30 3b 0a 20 20 20 20 69 66 28 20 6e 46 69 65   0;.    if( nFie
8500: 6c 64 20 26 26 20 6e 57 6f 72 6b 65 72 3d 3d 30  ld && nWorker==0
8510: 20 29 20 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69   ) pKeyInfo->nFi
8520: 65 6c 64 20 3d 20 6e 46 69 65 6c 64 3b 0a 20 20  eld = nField;.  
8530: 20 20 70 53 6f 72 74 65 72 2d 3e 70 67 73 7a 20    pSorter->pgsz 
8540: 3d 20 70 67 73 7a 20 3d 20 73 71 6c 69 74 65 33  = pgsz = sqlite3
8550: 42 74 72 65 65 47 65 74 50 61 67 65 53 69 7a 65  BtreeGetPageSize
8560: 28 64 62 2d 3e 61 44 62 5b 30 5d 2e 70 42 74 29  (db->aDb[0].pBt)
8570: 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6e  ;.    pSorter->n
8580: 54 61 73 6b 20 3d 20 6e 57 6f 72 6b 65 72 20 2b  Task = nWorker +
8590: 20 31 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d   1;.    pSorter-
85a0: 3e 62 55 73 65 54 68 72 65 61 64 73 20 3d 20 28  >bUseThreads = (
85b0: 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3e 31  pSorter->nTask>1
85c0: 29 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  );.    pSorter->
85d0: 64 62 20 3d 20 64 62 3b 0a 20 20 20 20 66 6f 72  db = db;.    for
85e0: 28 69 3d 30 3b 20 69 3c 70 53 6f 72 74 65 72 2d  (i=0; i<pSorter-
85f0: 3e 6e 54 61 73 6b 3b 20 69 2b 2b 29 7b 0a 20 20  >nTask; i++){.  
8600: 20 20 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20      SortSubtask 
8610: 2a 70 54 61 73 6b 20 3d 20 26 70 53 6f 72 74 65  *pTask = &pSorte
8620: 72 2d 3e 61 54 61 73 6b 5b 69 5d 3b 0a 20 20 20  r->aTask[i];.   
8630: 20 20 20 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65     pTask->pSorte
8640: 72 20 3d 20 70 53 6f 72 74 65 72 3b 0a 20 20 20  r = pSorter;.   
8650: 20 7d 0a 0a 20 20 20 20 69 66 28 20 21 73 71 6c   }..    if( !sql
8660: 69 74 65 33 54 65 6d 70 49 6e 4d 65 6d 6f 72 79  ite3TempInMemory
8670: 28 64 62 29 20 29 7b 0a 20 20 20 20 20 20 70 53  (db) ){.      pS
8680: 6f 72 74 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a 65  orter->mnPmaSize
8690: 20 3d 20 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f   = SORTER_MIN_WO
86a0: 52 4b 49 4e 47 20 2a 20 70 67 73 7a 3b 0a 20 20  RKING * pgsz;.  
86b0: 20 20 20 20 6d 78 43 61 63 68 65 20 3d 20 64 62      mxCache = db
86c0: 2d 3e 61 44 62 5b 30 5d 2e 70 53 63 68 65 6d 61  ->aDb[0].pSchema
86d0: 2d 3e 63 61 63 68 65 5f 73 69 7a 65 3b 0a 20 20  ->cache_size;.  
86e0: 20 20 20 20 69 66 28 20 6d 78 43 61 63 68 65 3c      if( mxCache<
86f0: 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49  SORTER_MIN_WORKI
8700: 4e 47 20 29 20 6d 78 43 61 63 68 65 20 3d 20 53  NG ) mxCache = S
8710: 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e  ORTER_MIN_WORKIN
8720: 47 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72  G;.      pSorter
8730: 2d 3e 6d 78 50 6d 61 53 69 7a 65 20 3d 20 6d 78  ->mxPmaSize = mx
8740: 43 61 63 68 65 20 2a 20 70 67 73 7a 3b 0a 0a 20  Cache * pgsz;.. 
8750: 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 61       /* If the a
8760: 70 70 6c 69 63 61 74 69 6f 6e 20 69 73 20 75 73  pplication is us
8770: 69 6e 67 20 6d 65 6d 73 79 73 33 20 6f 72 20 6d  ing memsys3 or m
8780: 65 6d 73 79 73 35 2c 20 75 73 65 20 61 20 73 65  emsys5, use a se
8790: 70 61 72 61 74 65 20 0a 20 20 20 20 20 20 2a 2a  parate .      **
87a0: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 6f 72 20   allocation for 
87b0: 65 61 63 68 20 73 6f 72 74 2d 6b 65 79 20 69 6e  each sort-key in
87c0: 20 6d 65 6d 6f 72 79 2e 20 4f 74 68 65 72 77 69   memory. Otherwi
87d0: 73 65 2c 20 75 73 65 20 61 20 73 69 6e 67 6c 65  se, use a single
87e0: 20 62 69 67 0a 20 20 20 20 20 20 2a 2a 20 61 6c   big.      ** al
87f0: 6c 6f 63 61 74 69 6f 6e 20 61 74 20 70 53 6f 72  location at pSor
8800: 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 20 66 6f 72  ter->aMemory for
8810: 20 61 6c 6c 20 73 6f 72 74 2d 6b 65 79 73 2e 20   all sort-keys. 
8820: 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 73 71   */.      if( sq
8830: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
8840: 67 2e 70 48 65 61 70 3d 3d 30 20 29 7b 0a 20 20  g.pHeap==0 ){.  
8850: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 53        assert( pS
8860: 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 3d 3d  orter->iMemory==
8870: 30 20 29 3b 0a 20 20 20 20 20 20 20 20 70 53 6f  0 );.        pSo
8880: 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 3d 20  rter->nMemory = 
8890: 70 67 73 7a 3b 0a 20 20 20 20 20 20 20 20 70 53  pgsz;.        pS
88a0: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d  orter->list.aMem
88b0: 6f 72 79 20 3d 20 28 75 38 2a 29 73 71 6c 69 74  ory = (u8*)sqlit
88c0: 65 33 4d 61 6c 6c 6f 63 28 70 67 73 7a 29 3b 0a  e3Malloc(pgsz);.
88d0: 20 20 20 20 20 20 20 20 69 66 28 20 21 70 53 6f          if( !pSo
88e0: 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f  rter->list.aMemo
88f0: 72 79 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45  ry ) rc = SQLITE
8900: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 7d 0a  _NOMEM;.      }.
8910: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
8920: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
8930: 20 46 72 65 65 20 74 68 65 20 6c 69 73 74 20 6f   Free the list o
8940: 66 20 73 6f 72 74 65 64 20 72 65 63 6f 72 64 73  f sorted records
8950: 20 73 74 61 72 74 69 6e 67 20 61 74 20 70 52 65   starting at pRe
8960: 63 6f 72 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  cord..*/.static 
8970: 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72 52  void vdbeSorterR
8980: 65 63 6f 72 64 46 72 65 65 28 73 71 6c 69 74 65  ecordFree(sqlite
8990: 33 20 2a 64 62 2c 20 53 6f 72 74 65 72 52 65 63  3 *db, SorterRec
89a0: 6f 72 64 20 2a 70 52 65 63 6f 72 64 29 7b 0a 20  ord *pRecord){. 
89b0: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
89c0: 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  ;.  SorterRecord
89d0: 20 2a 70 4e 65 78 74 3b 0a 20 20 66 6f 72 28 70   *pNext;.  for(p
89e0: 3d 70 52 65 63 6f 72 64 3b 20 70 3b 20 70 3d 70  =pRecord; p; p=p
89f0: 4e 65 78 74 29 7b 0a 20 20 20 20 70 4e 65 78 74  Next){.    pNext
8a00: 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20   = p->u.pNext;. 
8a10: 20 20 20 73 71 6c 69 74 65 33 44 62 46 72 65 65     sqlite3DbFree
8a20: 28 64 62 2c 20 70 29 3b 0a 20 20 7d 0a 7d 0a 0a  (db, p);.  }.}..
8a30: 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6c 6c 20 72  /*.** Free all r
8a40: 65 73 6f 75 72 63 65 73 20 6f 77 6e 65 64 20 62  esources owned b
8a50: 79 20 74 68 65 20 6f 62 6a 65 63 74 20 69 6e 64  y the object ind
8a60: 69 63 61 74 65 64 20 62 79 20 61 72 67 75 6d 65  icated by argume
8a70: 6e 74 20 70 54 61 73 6b 2e 20 41 6c 6c 20 0a 2a  nt pTask. All .*
8a80: 2a 20 66 69 65 6c 64 73 20 6f 66 20 2a 70 54 61  * fields of *pTa
8a90: 73 6b 20 61 72 65 20 7a 65 72 6f 65 64 20 62 65  sk are zeroed be
8aa0: 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a  fore returning..
8ab0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76  */.static void v
8ac0: 64 62 65 53 6f 72 74 53 75 62 74 61 73 6b 43 6c  dbeSortSubtaskCl
8ad0: 65 61 6e 75 70 28 73 71 6c 69 74 65 33 20 2a 64  eanup(sqlite3 *d
8ae0: 62 2c 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a  b, SortSubtask *
8af0: 70 54 61 73 6b 29 7b 0a 20 20 73 71 6c 69 74 65  pTask){.  sqlite
8b00: 33 44 62 46 72 65 65 28 64 62 2c 20 70 54 61 73  3DbFree(db, pTas
8b10: 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 29 3b 0a 20  k->pUnpacked);. 
8b20: 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65   pTask->pUnpacke
8b30: 64 20 3d 20 30 3b 0a 20 20 69 66 28 20 70 54 61  d = 0;.  if( pTa
8b40: 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  sk->list.aMemory
8b50: 3d 3d 30 20 29 7b 0a 20 20 20 20 76 64 62 65 53  ==0 ){.    vdbeS
8b60: 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65 65 28  orterRecordFree(
8b70: 30 2c 20 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 70  0, pTask->list.p
8b80: 4c 69 73 74 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  List);.  }else{.
8b90: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
8ba0: 28 70 54 61 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65  (pTask->list.aMe
8bb0: 6d 6f 72 79 29 3b 0a 20 20 20 20 70 54 61 73 6b  mory);.    pTask
8bc0: 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 3d  ->list.aMemory =
8bd0: 20 30 3b 0a 20 20 7d 0a 20 20 70 54 61 73 6b 2d   0;.  }.  pTask-
8be0: 3e 6c 69 73 74 2e 70 4c 69 73 74 20 3d 20 30 3b  >list.pList = 0;
8bf0: 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 66 69  .  if( pTask->fi
8c00: 6c 65 2e 70 46 64 20 29 7b 0a 20 20 20 20 73 71  le.pFd ){.    sq
8c10: 6c 69 74 65 33 4f 73 43 6c 6f 73 65 46 72 65 65  lite3OsCloseFree
8c20: 28 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 70 46 64  (pTask->file.pFd
8c30: 29 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 66 69  );.    pTask->fi
8c40: 6c 65 2e 70 46 64 20 3d 20 30 3b 0a 20 20 20 20  le.pFd = 0;.    
8c50: 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66  pTask->file.iEof
8c60: 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20   = 0;.  }.  if( 
8c70: 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64  pTask->file2.pFd
8c80: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f   ){.    sqlite3O
8c90: 73 43 6c 6f 73 65 46 72 65 65 28 70 54 61 73 6b  sCloseFree(pTask
8ca0: 2d 3e 66 69 6c 65 32 2e 70 46 64 29 3b 0a 20 20  ->file2.pFd);.  
8cb0: 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70    pTask->file2.p
8cc0: 46 64 20 3d 20 30 3b 0a 20 20 20 20 70 54 61 73  Fd = 0;.    pTas
8cd0: 6b 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 20 3d 20  k->file2.iEof = 
8ce0: 30 3b 0a 20 20 7d 0a 7d 0a 0a 23 69 66 64 65 66  0;.  }.}..#ifdef
8cf0: 20 53 51 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f   SQLITE_DEBUG_SO
8d00: 52 54 45 52 5f 54 48 52 45 41 44 53 0a 73 74 61  RTER_THREADS.sta
8d10: 74 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72  tic void vdbeSor
8d20: 74 65 72 57 6f 72 6b 44 65 62 75 67 28 53 6f 72  terWorkDebug(Sor
8d30: 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c  tSubtask *pTask,
8d40: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45 76   const char *zEv
8d50: 65 6e 74 29 7b 0a 20 20 69 36 34 20 74 3b 0a 20  ent){.  i64 t;. 
8d60: 20 69 6e 74 20 69 54 61 73 6b 20 3d 20 28 70 54   int iTask = (pT
8d70: 61 73 6b 20 2d 20 70 54 61 73 6b 2d 3e 70 53 6f  ask - pTask->pSo
8d80: 72 74 65 72 2d 3e 61 54 61 73 6b 29 3b 0a 20 20  rter->aTask);.  
8d90: 73 71 6c 69 74 65 33 4f 73 43 75 72 72 65 6e 74  sqlite3OsCurrent
8da0: 54 69 6d 65 49 6e 74 36 34 28 70 54 61 73 6b 2d  TimeInt64(pTask-
8db0: 3e 70 53 6f 72 74 65 72 2d 3e 64 62 2d 3e 70 56  >pSorter->db->pV
8dc0: 66 73 2c 20 26 74 29 3b 0a 20 20 66 70 72 69 6e  fs, &t);.  fprin
8dd0: 74 66 28 73 74 64 65 72 72 2c 20 22 25 6c 6c 64  tf(stderr, "%lld
8de0: 3a 25 64 20 25 73 5c 6e 22 2c 20 74 2c 20 69 54  :%d %s\n", t, iT
8df0: 61 73 6b 2c 20 7a 45 76 65 6e 74 29 3b 0a 7d 0a  ask, zEvent);.}.
8e00: 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65  static void vdbe
8e10: 53 6f 72 74 65 72 52 65 77 69 6e 64 44 65 62 75  SorterRewindDebu
8e20: 67 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45  g(const char *zE
8e30: 76 65 6e 74 29 7b 0a 20 20 69 36 34 20 74 3b 0a  vent){.  i64 t;.
8e40: 20 20 73 71 6c 69 74 65 33 4f 73 43 75 72 72 65    sqlite3OsCurre
8e50: 6e 74 54 69 6d 65 49 6e 74 36 34 28 73 71 6c 69  ntTimeInt64(sqli
8e60: 74 65 33 5f 76 66 73 5f 66 69 6e 64 28 30 29 2c  te3_vfs_find(0),
8e70: 20 26 74 29 3b 0a 20 20 66 70 72 69 6e 74 66 28   &t);.  fprintf(
8e80: 73 74 64 65 72 72 2c 20 22 25 6c 6c 64 3a 58 20  stderr, "%lld:X 
8e90: 25 73 5c 6e 22 2c 20 74 2c 20 7a 45 76 65 6e 74  %s\n", t, zEvent
8ea0: 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64  );.}.static void
8eb0: 20 76 64 62 65 53 6f 72 74 65 72 50 6f 70 75 6c   vdbeSorterPopul
8ec0: 61 74 65 44 65 62 75 67 28 0a 20 20 53 6f 72 74  ateDebug(.  Sort
8ed0: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 0a  Subtask *pTask,.
8ee0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45    const char *zE
8ef0: 76 65 6e 74 0a 29 7b 0a 20 20 69 36 34 20 74 3b  vent.){.  i64 t;
8f00: 0a 20 20 69 6e 74 20 69 54 61 73 6b 20 3d 20 28  .  int iTask = (
8f10: 70 54 61 73 6b 20 2d 20 70 54 61 73 6b 2d 3e 70  pTask - pTask->p
8f20: 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 29 3b 0a  Sorter->aTask);.
8f30: 20 20 73 71 6c 69 74 65 33 4f 73 43 75 72 72 65    sqlite3OsCurre
8f40: 6e 74 54 69 6d 65 49 6e 74 36 34 28 70 54 61 73  ntTimeInt64(pTas
8f50: 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 64 62 2d 3e  k->pSorter->db->
8f60: 70 56 66 73 2c 20 26 74 29 3b 0a 20 20 66 70 72  pVfs, &t);.  fpr
8f70: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25 6c  intf(stderr, "%l
8f80: 6c 64 3a 62 67 25 64 20 25 73 5c 6e 22 2c 20 74  ld:bg%d %s\n", t
8f90: 2c 20 69 54 61 73 6b 2c 20 7a 45 76 65 6e 74 29  , iTask, zEvent)
8fa0: 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20  ;.}.static void 
8fb0: 76 64 62 65 53 6f 72 74 65 72 42 6c 6f 63 6b 44  vdbeSorterBlockD
8fc0: 65 62 75 67 28 0a 20 20 53 6f 72 74 53 75 62 74  ebug(.  SortSubt
8fd0: 61 73 6b 20 2a 70 54 61 73 6b 2c 0a 20 20 69 6e  ask *pTask,.  in
8fe0: 74 20 62 42 6c 6f 63 6b 65 64 2c 0a 20 20 63 6f  t bBlocked,.  co
8ff0: 6e 73 74 20 63 68 61 72 20 2a 7a 45 76 65 6e 74  nst char *zEvent
9000: 0a 29 7b 0a 20 20 69 66 28 20 62 42 6c 6f 63 6b  .){.  if( bBlock
9010: 65 64 20 29 7b 0a 20 20 20 20 69 36 34 20 74 3b  ed ){.    i64 t;
9020: 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43 75  .    sqlite3OsCu
9030: 72 72 65 6e 74 54 69 6d 65 49 6e 74 36 34 28 70  rrentTimeInt64(p
9040: 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 64  Task->pSorter->d
9050: 62 2d 3e 70 56 66 73 2c 20 26 74 29 3b 0a 20 20  b->pVfs, &t);.  
9060: 20 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72    fprintf(stderr
9070: 2c 20 22 25 6c 6c 64 3a 6d 61 69 6e 20 25 73 5c  , "%lld:main %s\
9080: 6e 22 2c 20 74 2c 20 7a 45 76 65 6e 74 29 3b 0a  n", t, zEvent);.
9090: 20 20 7d 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65    }.}.#else.# de
90a0: 66 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72 57  fine vdbeSorterW
90b0: 6f 72 6b 44 65 62 75 67 28 78 2c 79 29 0a 23 20  orkDebug(x,y).# 
90c0: 64 65 66 69 6e 65 20 76 64 62 65 53 6f 72 74 65  define vdbeSorte
90d0: 72 52 65 77 69 6e 64 44 65 62 75 67 28 79 29 0a  rRewindDebug(y).
90e0: 23 20 64 65 66 69 6e 65 20 76 64 62 65 53 6f 72  # define vdbeSor
90f0: 74 65 72 50 6f 70 75 6c 61 74 65 44 65 62 75 67  terPopulateDebug
9100: 28 78 2c 79 29 0a 23 20 64 65 66 69 6e 65 20 76  (x,y).# define v
9110: 64 62 65 53 6f 72 74 65 72 42 6c 6f 63 6b 44 65  dbeSorterBlockDe
9120: 62 75 67 28 78 2c 79 2c 7a 29 0a 23 65 6e 64 69  bug(x,y,z).#endi
9130: 66 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41  f..#if SQLITE_MA
9140: 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53  X_WORKER_THREADS
9150: 3e 30 0a 2f 2a 0a 2a 2a 20 4a 6f 69 6e 20 74 68  >0./*.** Join th
9160: 72 65 61 64 20 70 54 61 73 6b 2d 3e 74 68 72 65  read pTask->thre
9170: 61 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ad..*/.static in
9180: 74 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e  t vdbeSorterJoin
9190: 54 68 72 65 61 64 28 53 6f 72 74 53 75 62 74 61  Thread(SortSubta
91a0: 73 6b 20 2a 70 54 61 73 6b 29 7b 0a 20 20 69 6e  sk *pTask){.  in
91b0: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
91c0: 3b 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 70  ;.  if( pTask->p
91d0: 54 68 72 65 61 64 20 29 7b 0a 23 69 66 64 65 66  Thread ){.#ifdef
91e0: 20 53 51 4c 49 54 45 5f 44 45 42 55 47 5f 53 4f   SQLITE_DEBUG_SO
91f0: 52 54 45 52 5f 54 48 52 45 41 44 53 0a 20 20 20  RTER_THREADS.   
9200: 20 69 6e 74 20 62 44 6f 6e 65 20 3d 20 70 54 61   int bDone = pTa
9210: 73 6b 2d 3e 62 44 6f 6e 65 3b 0a 23 65 6e 64 69  sk->bDone;.#endi
9220: 66 0a 20 20 20 20 76 6f 69 64 20 2a 70 52 65 74  f.    void *pRet
9230: 3b 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65 72  ;.    vdbeSorter
9240: 42 6c 6f 63 6b 44 65 62 75 67 28 70 54 61 73 6b  BlockDebug(pTask
9250: 2c 20 21 62 44 6f 6e 65 2c 20 22 65 6e 74 65 72  , !bDone, "enter
9260: 22 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c  ");.    rc = sql
9270: 69 74 65 33 54 68 72 65 61 64 4a 6f 69 6e 28 70  ite3ThreadJoin(p
9280: 54 61 73 6b 2d 3e 70 54 68 72 65 61 64 2c 20 26  Task->pThread, &
9290: 70 52 65 74 29 3b 0a 20 20 20 20 76 64 62 65 53  pRet);.    vdbeS
92a0: 6f 72 74 65 72 42 6c 6f 63 6b 44 65 62 75 67 28  orterBlockDebug(
92b0: 70 54 61 73 6b 2c 20 21 62 44 6f 6e 65 2c 20 22  pTask, !bDone, "
92c0: 65 78 69 74 22 29 3b 0a 20 20 20 20 69 66 28 20  exit");.    if( 
92d0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc==SQLITE_OK ) 
92e0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 50 54 52 5f  rc = SQLITE_PTR_
92f0: 54 4f 5f 49 4e 54 28 70 52 65 74 29 3b 0a 20 20  TO_INT(pRet);.  
9300: 20 20 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d    assert( pTask-
9310: 3e 62 44 6f 6e 65 3d 3d 31 20 29 3b 0a 20 20 20  >bDone==1 );.   
9320: 20 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 20 3d 20   pTask->bDone = 
9330: 30 3b 0a 20 20 20 20 70 54 61 73 6b 2d 3e 70 54  0;.    pTask->pT
9340: 68 72 65 61 64 20 3d 20 30 3b 0a 20 20 7d 0a 20  hread = 0;.  }. 
9350: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
9360: 2a 0a 2a 2a 20 4c 61 75 6e 63 68 20 61 20 62 61  *.** Launch a ba
9370: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
9380: 74 6f 20 72 75 6e 20 78 54 61 73 6b 28 70 49 6e  to run xTask(pIn
9390: 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  )..*/.static int
93a0: 20 76 64 62 65 53 6f 72 74 65 72 43 72 65 61 74   vdbeSorterCreat
93b0: 65 54 68 72 65 61 64 28 0a 20 20 53 6f 72 74 53  eThread(.  SortS
93c0: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20  ubtask *pTask,  
93d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
93e0: 72 65 61 64 20 77 69 6c 6c 20 75 73 65 20 74 68  read will use th
93f0: 69 73 20 74 61 73 6b 20 6f 62 6a 65 63 74 20 2a  is task object *
9400: 2f 0a 20 20 76 6f 69 64 20 2a 28 2a 78 54 61 73  /.  void *(*xTas
9410: 6b 29 28 76 6f 69 64 2a 29 2c 20 20 20 20 20 20  k)(void*),      
9420: 20 20 20 20 2f 2a 20 52 6f 75 74 69 6e 65 20 74      /* Routine t
9430: 6f 20 72 75 6e 20 69 6e 20 61 20 73 65 70 61 72  o run in a separ
9440: 61 74 65 20 74 68 72 65 61 64 20 2a 2f 0a 20 20  ate thread */.  
9450: 76 6f 69 64 20 2a 70 49 6e 20 20 20 20 20 20 20  void *pIn       
9460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9470: 2f 2a 20 41 72 67 75 6d 65 6e 74 20 70 61 73 73  /* Argument pass
9480: 65 64 20 69 6e 74 6f 20 78 54 61 73 6b 28 29 20  ed into xTask() 
9490: 2a 2f 0a 29 7b 0a 20 20 61 73 73 65 72 74 28 20  */.){.  assert( 
94a0: 70 54 61 73 6b 2d 3e 70 54 68 72 65 61 64 3d 3d  pTask->pThread==
94b0: 30 20 26 26 20 70 54 61 73 6b 2d 3e 62 44 6f 6e  0 && pTask->bDon
94c0: 65 3d 3d 30 20 29 3b 0a 20 20 72 65 74 75 72 6e  e==0 );.  return
94d0: 20 73 71 6c 69 74 65 33 54 68 72 65 61 64 43 72   sqlite3ThreadCr
94e0: 65 61 74 65 28 26 70 54 61 73 6b 2d 3e 70 54 68  eate(&pTask->pTh
94f0: 72 65 61 64 2c 20 78 54 61 73 6b 2c 20 70 49 6e  read, xTask, pIn
9500: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4a 6f 69 6e  );.}../*.** Join
9510: 20 61 6c 6c 20 6f 75 74 73 74 61 6e 64 69 6e 67   all outstanding
9520: 20 74 68 72 65 61 64 73 20 6c 61 75 6e 63 68 65   threads launche
9530: 64 20 62 79 20 53 6f 72 74 65 72 57 72 69 74 65  d by SorterWrite
9540: 28 29 20 74 6f 20 63 72 65 61 74 65 20 0a 2a 2a  () to create .**
9550: 20 6c 65 76 65 6c 2d 30 20 50 4d 41 73 2e 0a 2a   level-0 PMAs..*
9560: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
9570: 65 53 6f 72 74 65 72 4a 6f 69 6e 41 6c 6c 28 56  eSorterJoinAll(V
9580: 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
9590: 65 72 2c 20 69 6e 74 20 72 63 69 6e 29 7b 0a 20  er, int rcin){. 
95a0: 20 69 6e 74 20 72 63 20 3d 20 72 63 69 6e 3b 0a   int rc = rcin;.
95b0: 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69    int i;.  for(i
95c0: 3d 30 3b 20 69 3c 70 53 6f 72 74 65 72 2d 3e 6e  =0; i<pSorter->n
95d0: 54 61 73 6b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  Task; i++){.    
95e0: 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61  SortSubtask *pTa
95f0: 73 6b 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61  sk = &pSorter->a
9600: 54 61 73 6b 5b 69 5d 3b 0a 20 20 20 20 69 6e 74  Task[i];.    int
9610: 20 72 63 32 20 3d 20 76 64 62 65 53 6f 72 74 65   rc2 = vdbeSorte
9620: 72 4a 6f 69 6e 54 68 72 65 61 64 28 70 54 61 73  rJoinThread(pTas
9630: 6b 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  k);.    if( rc==
9640: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d  SQLITE_OK ) rc =
9650: 20 72 63 32 3b 0a 20 20 7d 0a 20 20 72 65 74 75   rc2;.  }.  retu
9660: 72 6e 20 72 63 3b 0a 7d 0a 23 65 6c 73 65 0a 23  rn rc;.}.#else.#
9670: 20 64 65 66 69 6e 65 20 76 64 62 65 53 6f 72 74   define vdbeSort
9680: 65 72 4a 6f 69 6e 41 6c 6c 28 78 2c 72 63 69 6e  erJoinAll(x,rcin
9690: 29 20 28 72 63 69 6e 29 0a 23 20 64 65 66 69 6e  ) (rcin).# defin
96a0: 65 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e  e vdbeSorterJoin
96b0: 54 68 72 65 61 64 28 70 54 61 73 6b 29 20 53 51  Thread(pTask) SQ
96c0: 4c 49 54 45 5f 4f 4b 0a 23 65 6e 64 69 66 0a 0a  LITE_OK.#endif..
96d0: 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61  /*.** Allocate a
96e0: 20 6e 65 77 20 4d 65 72 67 65 45 6e 67 69 6e 65   new MergeEngine
96f0: 20 6f 62 6a 65 63 74 20 77 69 74 68 20 73 70 61   object with spa
9700: 63 65 20 66 6f 72 20 6e 49 74 65 72 20 69 74 65  ce for nIter ite
9710: 72 61 74 6f 72 73 2e 0a 2a 2f 0a 73 74 61 74 69  rators..*/.stati
9720: 63 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 76  c MergeEngine *v
9730: 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4e 65  dbeMergeEngineNe
9740: 77 28 69 6e 74 20 6e 49 74 65 72 29 7b 0a 20 20  w(int nIter){.  
9750: 69 6e 74 20 4e 20 3d 20 32 3b 20 20 20 20 20 20  int N = 2;      
9760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9770: 2f 2a 20 53 6d 61 6c 6c 65 73 74 20 70 6f 77 65  /* Smallest powe
9780: 72 20 6f 66 20 74 77 6f 20 3e 3d 20 6e 49 74 65  r of two >= nIte
9790: 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65  r */.  int nByte
97a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
97b0: 20 20 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20         /* Total 
97c0: 62 79 74 65 73 20 6f 66 20 73 70 61 63 65 20 74  bytes of space t
97d0: 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20 20  o allocate */.  
97e0: 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 4e 65  MergeEngine *pNe
97f0: 77 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  w;              
9800: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 61 6c  /* Pointer to al
9810: 6c 6f 63 61 74 65 64 20 6f 62 6a 65 63 74 20 74  located object t
9820: 6f 20 72 65 74 75 72 6e 20 2a 2f 0a 0a 20 20 61  o return */..  a
9830: 73 73 65 72 74 28 20 6e 49 74 65 72 3c 3d 53 4f  ssert( nIter<=SO
9840: 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
9850: 4f 55 4e 54 20 29 3b 0a 0a 20 20 77 68 69 6c 65  OUNT );..  while
9860: 28 20 4e 3c 6e 49 74 65 72 20 29 20 4e 20 2b 3d  ( N<nIter ) N +=
9870: 20 4e 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 69   N;.  nByte = si
9880: 7a 65 6f 66 28 4d 65 72 67 65 45 6e 67 69 6e 65  zeof(MergeEngine
9890: 29 20 2b 20 4e 20 2a 20 28 73 69 7a 65 6f 66 28  ) + N * (sizeof(
98a0: 69 6e 74 29 20 2b 20 73 69 7a 65 6f 66 28 50 6d  int) + sizeof(Pm
98b0: 61 52 65 61 64 65 72 29 29 3b 0a 0a 20 20 70 4e  aReader));..  pN
98c0: 65 77 20 3d 20 28 4d 65 72 67 65 45 6e 67 69 6e  ew = (MergeEngin
98d0: 65 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  e*)sqlite3Malloc
98e0: 5a 65 72 6f 28 6e 42 79 74 65 29 3b 0a 20 20 69  Zero(nByte);.  i
98f0: 66 28 20 70 4e 65 77 20 29 7b 0a 20 20 20 20 70  f( pNew ){.    p
9900: 4e 65 77 2d 3e 6e 54 72 65 65 20 3d 20 4e 3b 0a  New->nTree = N;.
9910: 20 20 20 20 70 4e 65 77 2d 3e 61 49 74 65 72 20      pNew->aIter 
9920: 3d 20 28 50 6d 61 52 65 61 64 65 72 2a 29 26 70  = (PmaReader*)&p
9930: 4e 65 77 5b 31 5d 3b 0a 20 20 20 20 70 4e 65 77  New[1];.    pNew
9940: 2d 3e 61 54 72 65 65 20 3d 20 28 69 6e 74 2a 29  ->aTree = (int*)
9950: 26 70 4e 65 77 2d 3e 61 49 74 65 72 5b 4e 5d 3b  &pNew->aIter[N];
9960: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 4e  .  }.  return pN
9970: 65 77 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65  ew;.}../*.** Fre
9980: 65 20 74 68 65 20 4d 65 72 67 65 45 6e 67 69 6e  e the MergeEngin
9990: 65 20 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20  e object passed 
99a0: 61 73 20 74 68 65 20 6f 6e 6c 79 20 61 72 67 75  as the only argu
99b0: 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ment..*/.static 
99c0: 76 6f 69 64 20 76 64 62 65 4d 65 72 67 65 45 6e  void vdbeMergeEn
99d0: 67 69 6e 65 46 72 65 65 28 4d 65 72 67 65 45 6e  gineFree(MergeEn
99e0: 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 29 7b 0a  gine *pMerger){.
99f0: 20 20 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 70    int i;.  if( p
9a00: 4d 65 72 67 65 72 20 29 7b 0a 20 20 20 20 66 6f  Merger ){.    fo
9a10: 72 28 69 3d 30 3b 20 69 3c 70 4d 65 72 67 65 72  r(i=0; i<pMerger
9a20: 2d 3e 6e 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20  ->nTree; i++){. 
9a30: 20 20 20 20 20 76 64 62 65 50 6d 61 52 65 61 64       vdbePmaRead
9a40: 65 72 43 6c 65 61 72 28 26 70 4d 65 72 67 65 72  erClear(&pMerger
9a50: 2d 3e 61 49 74 65 72 5b 69 5d 29 3b 0a 20 20 20  ->aIter[i]);.   
9a60: 20 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33   }.  }.  sqlite3
9a70: 5f 66 72 65 65 28 70 4d 65 72 67 65 72 29 3b 0a  _free(pMerger);.
9a80: 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6c  }../*.** Free al
9a90: 6c 20 72 65 73 6f 75 72 63 65 73 20 61 73 73 6f  l resources asso
9aa0: 63 69 61 74 65 64 20 77 69 74 68 20 74 68 65 20  ciated with the 
9ab0: 49 6e 63 72 4d 65 72 67 65 72 20 6f 62 6a 65 63  IncrMerger objec
9ac0: 74 20 69 6e 64 69 63 61 74 65 64 20 62 79 0a 2a  t indicated by.*
9ad0: 2a 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75  * the first argu
9ae0: 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ment..*/.static 
9af0: 76 6f 69 64 20 76 64 62 65 49 6e 63 72 46 72 65  void vdbeIncrFre
9b00: 65 28 49 6e 63 72 4d 65 72 67 65 72 20 2a 70 49  e(IncrMerger *pI
9b10: 6e 63 72 29 7b 0a 20 20 69 66 28 20 70 49 6e 63  ncr){.  if( pInc
9b20: 72 20 29 7b 0a 23 69 66 20 53 51 4c 49 54 45 5f  r ){.#if SQLITE_
9b30: 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41  MAX_WORKER_THREA
9b40: 44 53 3e 30 0a 20 20 20 20 69 66 28 20 70 49 6e  DS>0.    if( pIn
9b50: 63 72 2d 3e 62 55 73 65 54 68 72 65 61 64 20 29  cr->bUseThread )
9b60: 7b 0a 20 20 20 20 20 20 76 64 62 65 53 6f 72 74  {.      vdbeSort
9b70: 65 72 4a 6f 69 6e 54 68 72 65 61 64 28 70 49 6e  erJoinThread(pIn
9b80: 63 72 2d 3e 70 54 61 73 6b 29 3b 0a 20 20 20 20  cr->pTask);.    
9b90: 20 20 69 66 28 20 70 49 6e 63 72 2d 3e 61 46 69    if( pIncr->aFi
9ba0: 6c 65 5b 30 5d 2e 70 46 64 20 29 20 73 71 6c 69  le[0].pFd ) sqli
9bb0: 74 65 33 4f 73 43 6c 6f 73 65 46 72 65 65 28 70  te3OsCloseFree(p
9bc0: 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 2e 70  Incr->aFile[0].p
9bd0: 46 64 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70  Fd);.      if( p
9be0: 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d 2e 70  Incr->aFile[1].p
9bf0: 46 64 20 29 20 73 71 6c 69 74 65 33 4f 73 43 6c  Fd ) sqlite3OsCl
9c00: 6f 73 65 46 72 65 65 28 70 49 6e 63 72 2d 3e 61  oseFree(pIncr->a
9c10: 46 69 6c 65 5b 31 5d 2e 70 46 64 29 3b 0a 20 20  File[1].pFd);.  
9c20: 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 20 20 76    }.#endif.    v
9c30: 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46 72  dbeMergeEngineFr
9c40: 65 65 28 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65  ee(pIncr->pMerge
9c50: 72 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  r);.    sqlite3_
9c60: 66 72 65 65 28 70 49 6e 63 72 29 3b 0a 20 20 7d  free(pIncr);.  }
9c70: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65 74 20  .}../*.** Reset 
9c80: 61 20 73 6f 72 74 69 6e 67 20 63 75 72 73 6f 72  a sorting cursor
9c90: 20 62 61 63 6b 20 74 6f 20 69 74 73 20 6f 72 69   back to its ori
9ca0: 67 69 6e 61 6c 20 65 6d 70 74 79 20 73 74 61 74  ginal empty stat
9cb0: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  e..*/.void sqlit
9cc0: 65 33 56 64 62 65 53 6f 72 74 65 72 52 65 73 65  e3VdbeSorterRese
9cd0: 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 56  t(sqlite3 *db, V
9ce0: 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
9cf0: 65 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  er){.  int i;.  
9d00: 28 76 6f 69 64 29 76 64 62 65 53 6f 72 74 65 72  (void)vdbeSorter
9d10: 4a 6f 69 6e 41 6c 6c 28 70 53 6f 72 74 65 72 2c  JoinAll(pSorter,
9d20: 20 53 51 4c 49 54 45 5f 4f 4b 29 3b 0a 20 20 69   SQLITE_OK);.  i
9d30: 66 28 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 61  f( pSorter->pRea
9d40: 64 65 72 20 29 7b 0a 20 20 20 20 76 64 62 65 50  der ){.    vdbeP
9d50: 6d 61 52 65 61 64 65 72 43 6c 65 61 72 28 70 53  maReaderClear(pS
9d60: 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72 29 3b  orter->pReader);
9d70: 0a 20 20 20 20 73 71 6c 69 74 65 33 44 62 46 72  .    sqlite3DbFr
9d80: 65 65 28 64 62 2c 20 70 53 6f 72 74 65 72 2d 3e  ee(db, pSorter->
9d90: 70 52 65 61 64 65 72 29 3b 0a 20 20 20 20 70 53  pReader);.    pS
9da0: 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72 20 3d  orter->pReader =
9db0: 20 30 3b 0a 20 20 7d 0a 20 20 76 64 62 65 4d 65   0;.  }.  vdbeMe
9dc0: 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28 70 53  rgeEngineFree(pS
9dd0: 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 29 3b  orter->pMerger);
9de0: 0a 20 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72  .  pSorter->pMer
9df0: 67 65 72 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69  ger = 0;.  for(i
9e00: 3d 30 3b 20 69 3c 70 53 6f 72 74 65 72 2d 3e 6e  =0; i<pSorter->n
9e10: 54 61 73 6b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  Task; i++){.    
9e20: 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61  SortSubtask *pTa
9e30: 73 6b 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61  sk = &pSorter->a
9e40: 54 61 73 6b 5b 69 5d 3b 0a 20 20 20 20 76 64 62  Task[i];.    vdb
9e50: 65 53 6f 72 74 53 75 62 74 61 73 6b 43 6c 65 61  eSortSubtaskClea
9e60: 6e 75 70 28 64 62 2c 20 70 54 61 73 6b 29 3b 0a  nup(db, pTask);.
9e70: 20 20 7d 0a 20 20 69 66 28 20 70 53 6f 72 74 65    }.  if( pSorte
9e80: 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 3d  r->list.aMemory=
9e90: 3d 30 20 29 7b 0a 20 20 20 20 76 64 62 65 53 6f  =0 ){.    vdbeSo
9ea0: 72 74 65 72 52 65 63 6f 72 64 46 72 65 65 28 30  rterRecordFree(0
9eb0: 2c 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e  , pSorter->list.
9ec0: 70 4c 69 73 74 29 3b 0a 20 20 7d 0a 20 20 70 53  pList);.  }.  pS
9ed0: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73  orter->list.pLis
9ee0: 74 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74 65 72  t = 0;.  pSorter
9ef0: 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 3d 20 30  ->list.szPMA = 0
9f00: 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 62 55 73  ;.  pSorter->bUs
9f10: 65 50 4d 41 20 3d 20 30 3b 0a 20 20 70 53 6f 72  ePMA = 0;.  pSor
9f20: 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 20 3d 20 30  ter->iMemory = 0
9f30: 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6d 78 4b  ;.  pSorter->mxK
9f40: 65 79 73 69 7a 65 20 3d 20 30 3b 0a 20 20 73 71  eysize = 0;.  sq
9f50: 6c 69 74 65 33 44 62 46 72 65 65 28 64 62 2c 20  lite3DbFree(db, 
9f60: 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b  pSorter->pUnpack
9f70: 65 64 29 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e  ed);.  pSorter->
9f80: 70 55 6e 70 61 63 6b 65 64 20 3d 20 30 3b 0a 7d  pUnpacked = 0;.}
9f90: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 79  ../*.** Free any
9fa0: 20 63 75 72 73 6f 72 20 63 6f 6d 70 6f 6e 65 6e   cursor componen
9fb0: 74 73 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20  ts allocated by 
9fc0: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
9fd0: 72 58 58 58 20 72 6f 75 74 69 6e 65 73 2e 0a 2a  rXXX routines..*
9fe0: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 56 64  /.void sqlite3Vd
9ff0: 62 65 53 6f 72 74 65 72 43 6c 6f 73 65 28 73 71  beSorterClose(sq
a000: 6c 69 74 65 33 20 2a 64 62 2c 20 56 64 62 65 43  lite3 *db, VdbeC
a010: 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20  ursor *pCsr){.  
a020: 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72  VdbeSorter *pSor
a030: 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72  ter = pCsr->pSor
a040: 74 65 72 3b 0a 20 20 69 66 28 20 70 53 6f 72 74  ter;.  if( pSort
a050: 65 72 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  er ){.    sqlite
a060: 33 56 64 62 65 53 6f 72 74 65 72 52 65 73 65 74  3VdbeSorterReset
a070: 28 64 62 2c 20 70 53 6f 72 74 65 72 29 3b 0a 20  (db, pSorter);. 
a080: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
a090: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d  pSorter->list.aM
a0a0: 65 6d 6f 72 79 29 3b 0a 20 20 20 20 73 71 6c 69  emory);.    sqli
a0b0: 74 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 53  te3DbFree(db, pS
a0c0: 6f 72 74 65 72 29 3b 0a 20 20 20 20 70 43 73 72  orter);.    pCsr
a0d0: 2d 3e 70 53 6f 72 74 65 72 20 3d 20 30 3b 0a 20  ->pSorter = 0;. 
a0e0: 20 7d 0a 7d 0a 0a 23 69 66 20 53 51 4c 49 54 45   }.}..#if SQLITE
a0f0: 5f 4d 41 58 5f 4d 4d 41 50 5f 53 49 5a 45 3e 30  _MAX_MMAP_SIZE>0
a100: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66 69 72 73 74  ./*.** The first
a110: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 61 20 66   argument is a f
a120: 69 6c 65 2d 68 61 6e 64 6c 65 20 6f 70 65 6e 20  ile-handle open 
a130: 6f 6e 20 61 20 74 65 6d 70 6f 72 61 72 79 20 66  on a temporary f
a140: 69 6c 65 2e 20 54 68 65 20 66 69 6c 65 0a 2a 2a  ile. The file.**
a150: 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 74   is guaranteed t
a160: 6f 20 62 65 20 6e 42 79 74 65 20 62 79 74 65 73  o be nByte bytes
a170: 20 6f 72 20 73 6d 61 6c 6c 65 72 20 69 6e 20 73   or smaller in s
a180: 69 7a 65 2e 20 54 68 69 73 20 66 75 6e 63 74 69  ize. This functi
a190: 6f 6e 0a 2a 2a 20 61 74 74 65 6d 70 74 73 20 74  on.** attempts t
a1a0: 6f 20 65 78 74 65 6e 64 20 74 68 65 20 66 69 6c  o extend the fil
a1b0: 65 20 74 6f 20 6e 42 79 74 65 20 62 79 74 65 73  e to nByte bytes
a1c0: 20 69 6e 20 73 69 7a 65 20 61 6e 64 20 74 6f 20   in size and to 
a1d0: 65 6e 73 75 72 65 20 74 68 61 74 0a 2a 2a 20 74  ensure that.** t
a1e0: 68 65 20 56 46 53 20 68 61 73 20 6d 65 6d 6f 72  he VFS has memor
a1f0: 79 20 6d 61 70 70 65 64 20 69 74 2e 0a 2a 2a 0a  y mapped it..**.
a200: 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e 6f  ** Whether or no
a210: 74 20 74 68 65 20 66 69 6c 65 20 64 6f 65 73 20  t the file does 
a220: 65 6e 64 20 75 70 20 6d 65 6d 6f 72 79 20 6d 61  end up memory ma
a230: 70 70 65 64 20 6f 66 20 63 6f 75 72 73 65 20 64  pped of course d
a240: 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20 74 68 65  epends on.** the
a250: 20 73 70 65 63 69 66 69 63 20 56 46 53 20 69 6d   specific VFS im
a260: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f  plementation..*/
a270: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62  .static void vdb
a280: 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46 69 6c  eSorterExtendFil
a290: 65 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 73  e(sqlite3 *db, s
a2a0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
a2b0: 6c 65 2c 20 69 36 34 20 6e 42 79 74 65 29 7b 0a  le, i64 nByte){.
a2c0: 20 20 69 66 28 20 6e 42 79 74 65 3c 3d 28 69 36    if( nByte<=(i6
a2d0: 34 29 28 64 62 2d 3e 6e 4d 61 78 53 6f 72 74 65  4)(db->nMaxSorte
a2e0: 72 4d 6d 61 70 29 20 29 7b 0a 20 20 20 20 69 6e  rMmap) ){.    in
a2f0: 74 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73  t rc = sqlite3Os
a300: 54 72 75 6e 63 61 74 65 28 70 46 69 6c 65 2c 20  Truncate(pFile, 
a310: 6e 42 79 74 65 29 3b 0a 20 20 20 20 69 66 28 20  nByte);.    if( 
a320: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
a330: 0a 20 20 20 20 20 20 76 6f 69 64 20 2a 70 20 3d  .      void *p =
a340: 20 30 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   0;.      sqlite
a350: 33 4f 73 46 65 74 63 68 28 70 46 69 6c 65 2c 20  3OsFetch(pFile, 
a360: 30 2c 20 28 69 6e 74 29 6e 42 79 74 65 2c 20 26  0, (int)nByte, &
a370: 70 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  p);.      sqlite
a380: 33 4f 73 55 6e 66 65 74 63 68 28 70 46 69 6c 65  3OsUnfetch(pFile
a390: 2c 20 30 2c 20 70 29 3b 0a 20 20 20 20 7d 0a 20  , 0, p);.    }. 
a3a0: 20 7d 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65 66   }.}.#else.# def
a3b0: 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72 45 78  ine vdbeSorterEx
a3c0: 74 65 6e 64 46 69 6c 65 28 78 2c 79 2c 7a 29 20  tendFile(x,y,z) 
a3d0: 53 51 4c 49 54 45 5f 4f 4b 0a 23 65 6e 64 69 66  SQLITE_OK.#endif
a3e0: 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65  ../*.** Allocate
a3f0: 20 73 70 61 63 65 20 66 6f 72 20 61 20 66 69 6c   space for a fil
a400: 65 2d 68 61 6e 64 6c 65 20 61 6e 64 20 6f 70 65  e-handle and ope
a410: 6e 20 61 20 74 65 6d 70 6f 72 61 72 79 20 66 69  n a temporary fi
a420: 6c 65 2e 20 49 66 20 73 75 63 63 65 73 73 66 75  le. If successfu
a430: 6c 2c 0a 2a 2a 20 73 65 74 20 2a 70 70 46 69 6c  l,.** set *ppFil
a440: 65 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68  e to point to th
a450: 65 20 6d 61 6c 6c 6f 63 27 64 20 66 69 6c 65 2d  e malloc'd file-
a460: 68 61 6e 64 6c 65 20 61 6e 64 20 72 65 74 75 72  handle and retur
a470: 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2a 20  n SQLITE_OK..** 
a480: 4f 74 68 65 72 77 69 73 65 2c 20 73 65 74 20 2a  Otherwise, set *
a490: 70 70 46 69 6c 65 20 74 6f 20 30 20 61 6e 64 20  ppFile to 0 and 
a4a0: 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74 65  return an SQLite
a4b0: 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2f 0a   error code..*/.
a4c0: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53  static int vdbeS
a4d0: 6f 72 74 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c  orterOpenTempFil
a4e0: 65 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  e(.  sqlite3 *db
a4f0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
a500: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
a510: 20 68 61 6e 64 6c 65 20 64 6f 69 6e 67 20 73 6f   handle doing so
a520: 72 74 20 2a 2f 0a 20 20 69 36 34 20 6e 45 78 74  rt */.  i64 nExt
a530: 65 6e 64 2c 20 20 20 20 20 20 20 20 20 20 20 20  end,            
a540: 20 20 20 20 20 20 20 20 2f 2a 20 41 74 74 65 6d          /* Attem
a550: 70 74 20 74 6f 20 65 78 74 65 6e 64 20 66 69 6c  pt to extend fil
a560: 65 20 74 6f 20 74 68 69 73 20 73 69 7a 65 20 2a  e to this size *
a570: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  /.  sqlite3_file
a580: 20 2a 2a 70 70 46 69 6c 65 0a 29 7b 0a 20 20 69   **ppFile.){.  i
a590: 6e 74 20 72 63 3b 0a 20 20 72 63 20 3d 20 73 71  nt rc;.  rc = sq
a5a0: 6c 69 74 65 33 4f 73 4f 70 65 6e 4d 61 6c 6c 6f  lite3OsOpenMallo
a5b0: 63 28 64 62 2d 3e 70 56 66 73 2c 20 30 2c 20 70  c(db->pVfs, 0, p
a5c0: 70 46 69 6c 65 2c 0a 20 20 20 20 20 20 53 51 4c  pFile,.      SQL
a5d0: 49 54 45 5f 4f 50 45 4e 5f 54 45 4d 50 5f 4a 4f  ITE_OPEN_TEMP_JO
a5e0: 55 52 4e 41 4c 20 7c 0a 20 20 20 20 20 20 53 51  URNAL |.      SQ
a5f0: 4c 49 54 45 5f 4f 50 45 4e 5f 52 45 41 44 57 52  LITE_OPEN_READWR
a600: 49 54 45 20 20 20 20 7c 20 53 51 4c 49 54 45 5f  ITE    | SQLITE_
a610: 4f 50 45 4e 5f 43 52 45 41 54 45 20 7c 0a 20 20  OPEN_CREATE |.  
a620: 20 20 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f      SQLITE_OPEN_
a630: 45 58 43 4c 55 53 49 56 45 20 20 20 20 7c 20 53  EXCLUSIVE    | S
a640: 51 4c 49 54 45 5f 4f 50 45 4e 5f 44 45 4c 45 54  QLITE_OPEN_DELET
a650: 45 4f 4e 43 4c 4f 53 45 2c 20 26 72 63 0a 20 20  EONCLOSE, &rc.  
a660: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  );.  if( rc==SQL
a670: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 36  ITE_OK ){.    i6
a680: 34 20 6d 61 78 20 3d 20 53 51 4c 49 54 45 5f 4d  4 max = SQLITE_M
a690: 41 58 5f 4d 4d 41 50 5f 53 49 5a 45 3b 0a 20 20  AX_MMAP_SIZE;.  
a6a0: 20 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 43    sqlite3OsFileC
a6b0: 6f 6e 74 72 6f 6c 48 69 6e 74 28 2a 70 70 46 69  ontrolHint(*ppFi
a6c0: 6c 65 2c 20 53 51 4c 49 54 45 5f 46 43 4e 54 4c  le, SQLITE_FCNTL
a6d0: 5f 4d 4d 41 50 5f 53 49 5a 45 2c 20 28 76 6f 69  _MMAP_SIZE, (voi
a6e0: 64 2a 29 26 6d 61 78 29 3b 0a 20 20 20 20 69 66  d*)&max);.    if
a6f0: 28 20 6e 45 78 74 65 6e 64 3e 30 20 29 7b 0a 20  ( nExtend>0 ){. 
a700: 20 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 45       vdbeSorterE
a710: 78 74 65 6e 64 46 69 6c 65 28 64 62 2c 20 2a 70  xtendFile(db, *p
a720: 70 46 69 6c 65 2c 20 6e 45 78 74 65 6e 64 29 3b  pFile, nExtend);
a730: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
a740: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
a750: 20 49 66 20 69 74 20 68 61 73 20 6e 6f 74 20 61   If it has not a
a760: 6c 72 65 61 64 79 20 62 65 65 6e 20 61 6c 6c 6f  lready been allo
a770: 63 61 74 65 64 2c 20 61 6c 6c 6f 63 61 74 65 20  cated, allocate 
a780: 74 68 65 20 55 6e 70 61 63 6b 65 64 52 65 63 6f  the UnpackedReco
a790: 72 64 20 0a 2a 2a 20 73 74 72 75 63 74 75 72 65  rd .** structure
a7a0: 20 61 74 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61   at pTask->pUnpa
a7b0: 63 6b 65 64 2e 20 52 65 74 75 72 6e 20 53 51 4c  cked. Return SQL
a7c0: 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73  ITE_OK if succes
a7d0: 73 66 75 6c 20 28 6f 72 20 0a 2a 2a 20 69 66 20  sful (or .** if 
a7e0: 6e 6f 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 77 61  no allocation wa
a7f0: 73 20 72 65 71 75 69 72 65 64 29 2c 20 6f 72 20  s required), or 
a800: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 6f 74 68  SQLITE_NOMEM oth
a810: 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69  erwise..*/.stati
a820: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 41 6c  c int vdbeSortAl
a830: 6c 6f 63 55 6e 70 61 63 6b 65 64 28 53 6f 72 74  locUnpacked(Sort
a840: 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 29 7b  Subtask *pTask){
a850: 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 70 55  .  if( pTask->pU
a860: 6e 70 61 63 6b 65 64 3d 3d 30 20 29 7b 0a 20 20  npacked==0 ){.  
a870: 20 20 63 68 61 72 20 2a 70 46 72 65 65 3b 0a 20    char *pFree;. 
a880: 20 20 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63     pTask->pUnpac
a890: 6b 65 64 20 3d 20 73 71 6c 69 74 65 33 56 64 62  ked = sqlite3Vdb
a8a0: 65 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64 52 65  eAllocUnpackedRe
a8b0: 63 6f 72 64 28 0a 20 20 20 20 20 20 20 20 70 54  cord(.        pT
a8c0: 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 4b  ask->pSorter->pK
a8d0: 65 79 49 6e 66 6f 2c 20 30 2c 20 30 2c 20 26 70  eyInfo, 0, 0, &p
a8e0: 46 72 65 65 0a 20 20 20 20 29 3b 0a 20 20 20 20  Free.    );.    
a8f0: 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 70  assert( pTask->p
a900: 55 6e 70 61 63 6b 65 64 3d 3d 28 55 6e 70 61 63  Unpacked==(Unpac
a910: 6b 65 64 52 65 63 6f 72 64 2a 29 70 46 72 65 65  kedRecord*)pFree
a920: 20 29 3b 0a 20 20 20 20 69 66 28 20 70 46 72 65   );.    if( pFre
a930: 65 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  e==0 ) return SQ
a940: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
a950: 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64  pTask->pUnpacked
a960: 2d 3e 6e 46 69 65 6c 64 20 3d 20 70 54 61 73 6b  ->nField = pTask
a970: 2d 3e 70 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49  ->pSorter->pKeyI
a980: 6e 66 6f 2d 3e 6e 46 69 65 6c 64 3b 0a 20 20 20  nfo->nField;.   
a990: 20 70 54 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65   pTask->pUnpacke
a9a0: 64 2d 3e 65 72 72 43 6f 64 65 20 3d 20 30 3b 0a  d->errCode = 0;.
a9b0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c    }.  return SQL
a9c0: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  ITE_OK;.}.../*.*
a9d0: 2a 20 4d 65 72 67 65 20 74 68 65 20 74 77 6f 20  * Merge the two 
a9e0: 73 6f 72 74 65 64 20 6c 69 73 74 73 20 70 31 20  sorted lists p1 
a9f0: 61 6e 64 20 70 32 20 69 6e 74 6f 20 61 20 73 69  and p2 into a si
aa00: 6e 67 6c 65 20 6c 69 73 74 2e 0a 2a 2a 20 53 65  ngle list..** Se
aa10: 74 20 2a 70 70 4f 75 74 20 74 6f 20 74 68 65 20  t *ppOut to the 
aa20: 68 65 61 64 20 6f 66 20 74 68 65 20 6e 65 77 20  head of the new 
aa30: 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  list..*/.static 
aa40: 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72 4d  void vdbeSorterM
aa50: 65 72 67 65 28 0a 20 20 53 6f 72 74 53 75 62 74  erge(.  SortSubt
aa60: 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20 20 20  ask *pTask,     
aa70: 20 20 20 20 20 20 20 20 2f 2a 20 43 61 6c 6c 69          /* Calli
aa80: 6e 67 20 74 68 72 65 61 64 20 63 6f 6e 74 65 78  ng thread contex
aa90: 74 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63  t */.  SorterRec
aaa0: 6f 72 64 20 2a 70 31 2c 20 20 20 20 20 20 20 20  ord *p1,        
aab0: 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20         /* First 
aac0: 6c 69 73 74 20 74 6f 20 6d 65 72 67 65 20 2a 2f  list to merge */
aad0: 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20  .  SorterRecord 
aae0: 2a 70 32 2c 20 20 20 20 20 20 20 20 20 20 20 20  *p2,            
aaf0: 20 20 20 2f 2a 20 53 65 63 6f 6e 64 20 6c 69 73     /* Second lis
ab00: 74 20 74 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20  t to merge */.  
ab10: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 2a 70  SorterRecord **p
ab20: 70 4f 75 74 20 20 20 20 20 20 20 20 20 20 20 20  pOut            
ab30: 2f 2a 20 4f 55 54 3a 20 48 65 61 64 20 6f 66 20  /* OUT: Head of 
ab40: 6d 65 72 67 65 64 20 6c 69 73 74 20 2a 2f 0a 29  merged list */.)
ab50: 7b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  {.  SorterRecord
ab60: 20 2a 70 46 69 6e 61 6c 20 3d 20 30 3b 0a 20 20   *pFinal = 0;.  
ab70: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 2a 70  SorterRecord **p
ab80: 70 20 3d 20 26 70 46 69 6e 61 6c 3b 0a 20 20 76  p = &pFinal;.  v
ab90: 6f 69 64 20 2a 70 56 61 6c 32 20 3d 20 70 32 20  oid *pVal2 = p2 
aba0: 3f 20 53 52 56 41 4c 28 70 32 29 20 3a 20 30 3b  ? SRVAL(p2) : 0;
abb0: 0a 0a 20 20 77 68 69 6c 65 28 20 70 31 20 26 26  ..  while( p1 &&
abc0: 20 70 32 20 29 7b 0a 20 20 20 20 69 6e 74 20 72   p2 ){.    int r
abd0: 65 73 3b 0a 20 20 20 20 72 65 73 20 3d 20 76 64  es;.    res = vd
abe0: 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28  beSorterCompare(
abf0: 70 54 61 73 6b 2c 20 53 52 56 41 4c 28 70 31 29  pTask, SRVAL(p1)
ac00: 2c 20 70 31 2d 3e 6e 56 61 6c 2c 20 70 56 61 6c  , p1->nVal, pVal
ac10: 32 2c 20 70 32 2d 3e 6e 56 61 6c 29 3b 0a 20 20  2, p2->nVal);.  
ac20: 20 20 69 66 28 20 72 65 73 3c 3d 30 20 29 7b 0a    if( res<=0 ){.
ac30: 20 20 20 20 20 20 2a 70 70 20 3d 20 70 31 3b 0a        *pp = p1;.
ac40: 20 20 20 20 20 20 70 70 20 3d 20 26 70 31 2d 3e        pp = &p1->
ac50: 75 2e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70  u.pNext;.      p
ac60: 31 20 3d 20 70 31 2d 3e 75 2e 70 4e 65 78 74 3b  1 = p1->u.pNext;
ac70: 0a 20 20 20 20 20 20 70 56 61 6c 32 20 3d 20 30  .      pVal2 = 0
ac80: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
ac90: 20 20 20 2a 70 70 20 3d 20 70 32 3b 0a 20 20 20     *pp = p2;.   
aca0: 20 20 20 20 70 70 20 3d 20 26 70 32 2d 3e 75 2e      pp = &p2->u.
acb0: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 32 20  pNext;.      p2 
acc0: 3d 20 70 32 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20  = p2->u.pNext;. 
acd0: 20 20 20 20 20 69 66 28 20 70 32 3d 3d 30 20 29       if( p2==0 )
ace0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 70 56   break;.      pV
acf0: 61 6c 32 20 3d 20 53 52 56 41 4c 28 70 32 29 3b  al2 = SRVAL(p2);
ad00: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 70  .    }.  }.  *pp
ad10: 20 3d 20 70 31 20 3f 20 70 31 20 3a 20 70 32 3b   = p1 ? p1 : p2;
ad20: 0a 20 20 2a 70 70 4f 75 74 20 3d 20 70 46 69 6e  .  *ppOut = pFin
ad30: 61 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72  al;.}../*.** Sor
ad40: 74 20 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73  t the linked lis
ad50: 74 20 6f 66 20 72 65 63 6f 72 64 73 20 68 65 61  t of records hea
ad60: 64 65 64 20 61 74 20 70 54 61 73 6b 2d 3e 70 4c  ded at pTask->pL
ad70: 69 73 74 2e 20 52 65 74 75 72 6e 20 0a 2a 2a 20  ist. Return .** 
ad80: 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63  SQLITE_OK if suc
ad90: 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53  cessful, or an S
ada0: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
adb0: 20 28 69 2e 65 2e 20 53 51 4c 49 54 45 5f 4e 4f   (i.e. SQLITE_NO
adc0: 4d 45 4d 29 20 69 66 20 0a 2a 2a 20 61 6e 20 65  MEM) if .** an e
add0: 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a  rror occurs..*/.
ade0: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53  static int vdbeS
adf0: 6f 72 74 65 72 53 6f 72 74 28 53 6f 72 74 53 75  orterSort(SortSu
ae00: 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 53 6f  btask *pTask, So
ae10: 72 74 65 72 4c 69 73 74 20 2a 70 4c 69 73 74 29  rterList *pList)
ae20: 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 53 6f 72  {.  int i;.  Sor
ae30: 74 65 72 52 65 63 6f 72 64 20 2a 2a 61 53 6c 6f  terRecord **aSlo
ae40: 74 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72  t;.  SorterRecor
ae50: 64 20 2a 70 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  d *p;.  int rc;.
ae60: 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74  .  rc = vdbeSort
ae70: 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64 28 70 54  AllocUnpacked(pT
ae80: 61 73 6b 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  ask);.  if( rc!=
ae90: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
aea0: 72 6e 20 72 63 3b 0a 0a 20 20 61 53 6c 6f 74 20  rn rc;..  aSlot 
aeb0: 3d 20 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20  = (SorterRecord 
aec0: 2a 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  **)sqlite3Malloc
aed0: 5a 65 72 6f 28 36 34 20 2a 20 73 69 7a 65 6f 66  Zero(64 * sizeof
aee0: 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 29  (SorterRecord *)
aef0: 29 3b 0a 20 20 69 66 28 20 21 61 53 6c 6f 74 20  );.  if( !aSlot 
af00: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
af10: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a  LITE_NOMEM;.  }.
af20: 0a 20 20 70 20 3d 20 70 4c 69 73 74 2d 3e 70 4c  .  p = pList->pL
af30: 69 73 74 3b 0a 20 20 77 68 69 6c 65 28 20 70 20  ist;.  while( p 
af40: 29 7b 0a 20 20 20 20 53 6f 72 74 65 72 52 65 63  ){.    SorterRec
af50: 6f 72 64 20 2a 70 4e 65 78 74 3b 0a 20 20 20 20  ord *pNext;.    
af60: 69 66 28 20 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f  if( pList->aMemo
af70: 72 79 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  ry ){.      if( 
af80: 28 75 38 2a 29 70 3d 3d 70 4c 69 73 74 2d 3e 61  (u8*)p==pList->a
af90: 4d 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20 20  Memory ){.      
afa0: 20 20 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20    pNext = 0;.   
afb0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
afc0: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 75 2e 69    assert( p->u.i
afd0: 4e 65 78 74 3c 73 71 6c 69 74 65 33 4d 61 6c 6c  Next<sqlite3Mall
afe0: 6f 63 53 69 7a 65 28 70 4c 69 73 74 2d 3e 61 4d  ocSize(pList->aM
aff0: 65 6d 6f 72 79 29 20 29 3b 0a 20 20 20 20 20 20  emory) );.      
b000: 20 20 70 4e 65 78 74 20 3d 20 28 53 6f 72 74 65    pNext = (Sorte
b010: 72 52 65 63 6f 72 64 2a 29 26 70 4c 69 73 74 2d  rRecord*)&pList-
b020: 3e 61 4d 65 6d 6f 72 79 5b 70 2d 3e 75 2e 69 4e  >aMemory[p->u.iN
b030: 65 78 74 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20  ext];.      }.  
b040: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70    }else{.      p
b050: 4e 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78  Next = p->u.pNex
b060: 74 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 2d  t;.    }..    p-
b070: 3e 75 2e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20  >u.pNext = 0;.  
b080: 20 20 66 6f 72 28 69 3d 30 3b 20 61 53 6c 6f 74    for(i=0; aSlot
b090: 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  [i]; i++){.     
b0a0: 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65   vdbeSorterMerge
b0b0: 28 70 54 61 73 6b 2c 20 70 2c 20 61 53 6c 6f 74  (pTask, p, aSlot
b0c0: 5b 69 5d 2c 20 26 70 29 3b 0a 20 20 20 20 20 20  [i], &p);.      
b0d0: 61 53 6c 6f 74 5b 69 5d 20 3d 20 30 3b 0a 20 20  aSlot[i] = 0;.  
b0e0: 20 20 7d 0a 20 20 20 20 61 53 6c 6f 74 5b 69 5d    }.    aSlot[i]
b0f0: 20 3d 20 70 3b 0a 20 20 20 20 70 20 3d 20 70 4e   = p;.    p = pN
b100: 65 78 74 3b 0a 20 20 7d 0a 0a 20 20 70 20 3d 20  ext;.  }..  p = 
b110: 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  0;.  for(i=0; i<
b120: 36 34 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 76 64  64; i++){.    vd
b130: 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28 70 54  beSorterMerge(pT
b140: 61 73 6b 2c 20 70 2c 20 61 53 6c 6f 74 5b 69 5d  ask, p, aSlot[i]
b150: 2c 20 26 70 29 3b 0a 20 20 7d 0a 20 20 70 4c 69  , &p);.  }.  pLi
b160: 73 74 2d 3e 70 4c 69 73 74 20 3d 20 70 3b 0a 0a  st->pList = p;..
b170: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61    sqlite3_free(a
b180: 53 6c 6f 74 29 3b 0a 20 20 69 66 28 20 70 54 61  Slot);.  if( pTa
b190: 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 2d 3e 65  sk->pUnpacked->e
b1a0: 72 72 43 6f 64 65 20 29 7b 0a 20 20 20 20 61 73  rrCode ){.    as
b1b0: 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 70 55 6e  sert( pTask->pUn
b1c0: 70 61 63 6b 65 64 2d 3e 65 72 72 43 6f 64 65 3d  packed->errCode=
b1d0: 3d 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 29 3b  =SQLITE_NOMEM );
b1e0: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
b1f0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20  TE_NOMEM;.  }.  
b200: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
b210: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69  ;.}../*.** Initi
b220: 61 6c 69 7a 65 20 61 20 50 4d 41 2d 77 72 69 74  alize a PMA-writ
b230: 65 72 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74  er object..*/.st
b240: 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 50 6d  atic void vdbePm
b250: 61 57 72 69 74 65 72 49 6e 69 74 28 0a 20 20 73  aWriterInit(.  s
b260: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
b270: 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  le,            /
b280: 2a 20 46 69 6c 65 20 74 6f 20 77 72 69 74 65 20  * File to write 
b290: 74 6f 20 2a 2f 0a 20 20 50 6d 61 57 72 69 74 65  to */.  PmaWrite
b2a0: 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20  r *p,           
b2b0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63          /* Objec
b2c0: 74 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f  t to populate */
b2d0: 0a 20 20 69 6e 74 20 6e 42 75 66 2c 20 20 20 20  .  int nBuf,    
b2e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b2f0: 20 20 20 2f 2a 20 42 75 66 66 65 72 20 73 69 7a     /* Buffer siz
b300: 65 20 2a 2f 0a 20 20 69 36 34 20 69 53 74 61 72  e */.  i64 iStar
b310: 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t               
b320: 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74         /* Offset
b330: 20 6f 66 20 70 46 69 6c 65 20 74 6f 20 62 65 67   of pFile to beg
b340: 69 6e 20 77 72 69 74 69 6e 67 20 61 74 20 2a 2f  in writing at */
b350: 0a 29 7b 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20  .){.  memset(p, 
b360: 30 2c 20 73 69 7a 65 6f 66 28 50 6d 61 57 72 69  0, sizeof(PmaWri
b370: 74 65 72 29 29 3b 0a 20 20 70 2d 3e 61 42 75 66  ter));.  p->aBuf
b380: 66 65 72 20 3d 20 28 75 38 2a 29 73 71 6c 69 74  fer = (u8*)sqlit
b390: 65 33 4d 61 6c 6c 6f 63 28 6e 42 75 66 29 3b 0a  e3Malloc(nBuf);.
b3a0: 20 20 69 66 28 20 21 70 2d 3e 61 42 75 66 66 65    if( !p->aBuffe
b3b0: 72 20 29 7b 0a 20 20 20 20 70 2d 3e 65 46 57 45  r ){.    p->eFWE
b3c0: 72 72 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rr = SQLITE_NOME
b3d0: 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  M;.  }else{.    
b3e0: 70 2d 3e 69 42 75 66 45 6e 64 20 3d 20 70 2d 3e  p->iBufEnd = p->
b3f0: 69 42 75 66 53 74 61 72 74 20 3d 20 28 69 53 74  iBufStart = (iSt
b400: 61 72 74 20 25 20 6e 42 75 66 29 3b 0a 20 20 20  art % nBuf);.   
b410: 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20 3d 20   p->iWriteOff = 
b420: 69 53 74 61 72 74 20 2d 20 70 2d 3e 69 42 75 66  iStart - p->iBuf
b430: 53 74 61 72 74 3b 0a 20 20 20 20 70 2d 3e 6e 42  Start;.    p->nB
b440: 75 66 66 65 72 20 3d 20 6e 42 75 66 3b 0a 20 20  uffer = nBuf;.  
b450: 20 20 70 2d 3e 70 46 69 6c 65 20 3d 20 70 46 69    p->pFile = pFi
b460: 6c 65 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  le;.  }.}../*.**
b470: 20 57 72 69 74 65 20 6e 44 61 74 61 20 62 79 74   Write nData byt
b480: 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 74 68  es of data to th
b490: 65 20 50 4d 41 2e 20 52 65 74 75 72 6e 20 53 51  e PMA. Return SQ
b4a0: 4c 49 54 45 5f 4f 4b 0a 2a 2a 20 69 66 20 73 75  LITE_OK.** if su
b4b0: 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20  ccessful, or an 
b4c0: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
b4d0: 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  e if an error oc
b4e0: 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  curs..*/.static 
b4f0: 76 6f 69 64 20 76 64 62 65 50 6d 61 57 72 69 74  void vdbePmaWrit
b500: 65 42 6c 6f 62 28 50 6d 61 57 72 69 74 65 72 20  eBlob(PmaWriter 
b510: 2a 70 2c 20 75 38 20 2a 70 44 61 74 61 2c 20 69  *p, u8 *pData, i
b520: 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20 69 6e 74  nt nData){.  int
b530: 20 6e 52 65 6d 20 3d 20 6e 44 61 74 61 3b 0a 20   nRem = nData;. 
b540: 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30 20 26   while( nRem>0 &
b550: 26 20 70 2d 3e 65 46 57 45 72 72 3d 3d 30 20 29  & p->eFWErr==0 )
b560: 7b 0a 20 20 20 20 69 6e 74 20 6e 43 6f 70 79 20  {.    int nCopy 
b570: 3d 20 6e 52 65 6d 3b 0a 20 20 20 20 69 66 28 20  = nRem;.    if( 
b580: 6e 43 6f 70 79 3e 28 70 2d 3e 6e 42 75 66 66 65  nCopy>(p->nBuffe
b590: 72 20 2d 20 70 2d 3e 69 42 75 66 45 6e 64 29 20  r - p->iBufEnd) 
b5a0: 29 7b 0a 20 20 20 20 20 20 6e 43 6f 70 79 20 3d  ){.      nCopy =
b5b0: 20 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 70 2d   p->nBuffer - p-
b5c0: 3e 69 42 75 66 45 6e 64 3b 0a 20 20 20 20 7d 0a  >iBufEnd;.    }.
b5d0: 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d 3e  .    memcpy(&p->
b5e0: 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 45  aBuffer[p->iBufE
b5f0: 6e 64 5d 2c 20 26 70 44 61 74 61 5b 6e 44 61 74  nd], &pData[nDat
b600: 61 2d 6e 52 65 6d 5d 2c 20 6e 43 6f 70 79 29 3b  a-nRem], nCopy);
b610: 0a 20 20 20 20 70 2d 3e 69 42 75 66 45 6e 64 20  .    p->iBufEnd 
b620: 2b 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 69 66  += nCopy;.    if
b630: 28 20 70 2d 3e 69 42 75 66 45 6e 64 3d 3d 70 2d  ( p->iBufEnd==p-
b640: 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20  >nBuffer ){.    
b650: 20 20 70 2d 3e 65 46 57 45 72 72 20 3d 20 73 71    p->eFWErr = sq
b660: 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d 3e  lite3OsWrite(p->
b670: 70 46 69 6c 65 2c 20 0a 20 20 20 20 20 20 20 20  pFile, .        
b680: 20 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 70 2d    &p->aBuffer[p-
b690: 3e 69 42 75 66 53 74 61 72 74 5d 2c 20 70 2d 3e  >iBufStart], p->
b6a0: 69 42 75 66 45 6e 64 20 2d 20 70 2d 3e 69 42 75  iBufEnd - p->iBu
b6b0: 66 53 74 61 72 74 2c 20 0a 20 20 20 20 20 20 20  fStart, .       
b6c0: 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20     p->iWriteOff 
b6d0: 2b 20 70 2d 3e 69 42 75 66 53 74 61 72 74 0a 20  + p->iBufStart. 
b6e0: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 70 2d       );.      p-
b6f0: 3e 69 42 75 66 53 74 61 72 74 20 3d 20 70 2d 3e  >iBufStart = p->
b700: 69 42 75 66 45 6e 64 20 3d 20 30 3b 0a 20 20 20  iBufEnd = 0;.   
b710: 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20     p->iWriteOff 
b720: 2b 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20  += p->nBuffer;. 
b730: 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28     }.    assert(
b740: 20 70 2d 3e 69 42 75 66 45 6e 64 3c 70 2d 3e 6e   p->iBufEnd<p->n
b750: 42 75 66 66 65 72 20 29 3b 0a 0a 20 20 20 20 6e  Buffer );..    n
b760: 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20  Rem -= nCopy;.  
b770: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68  }.}../*.** Flush
b780: 20 61 6e 79 20 62 75 66 66 65 72 65 64 20 64 61   any buffered da
b790: 74 61 20 74 6f 20 64 69 73 6b 20 61 6e 64 20 63  ta to disk and c
b7a0: 6c 65 61 6e 20 75 70 20 74 68 65 20 50 4d 41 2d  lean up the PMA-
b7b0: 77 72 69 74 65 72 20 6f 62 6a 65 63 74 2e 0a 2a  writer object..*
b7c0: 2a 20 54 68 65 20 72 65 73 75 6c 74 73 20 6f 66  * The results of
b7d0: 20 75 73 69 6e 67 20 74 68 65 20 50 4d 41 2d 77   using the PMA-w
b7e0: 72 69 74 65 72 20 61 66 74 65 72 20 74 68 69 73  riter after this
b7f0: 20 63 61 6c 6c 20 61 72 65 20 75 6e 64 65 66 69   call are undefi
b800: 6e 65 64 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 53  ned..** Return S
b810: 51 4c 49 54 45 5f 4f 4b 20 69 66 20 66 6c 75 73  QLITE_OK if flus
b820: 68 69 6e 67 20 74 68 65 20 62 75 66 66 65 72 65  hing the buffere
b830: 64 20 64 61 74 61 20 73 75 63 63 65 65 64 73 20  d data succeeds 
b840: 6f 72 20 69 73 20 6e 6f 74 20 0a 2a 2a 20 72 65  or is not .** re
b850: 71 75 69 72 65 64 2e 20 4f 74 68 65 72 77 69 73  quired. Otherwis
b860: 65 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c  e, return an SQL
b870: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a  ite error code..
b880: 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65 20 72 65 74  **.** Before ret
b890: 75 72 6e 69 6e 67 2c 20 73 65 74 20 2a 70 69 45  urning, set *piE
b8a0: 6f 66 20 74 6f 20 74 68 65 20 6f 66 66 73 65 74  of to the offset
b8b0: 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c   immediately fol
b8c0: 6c 6f 77 69 6e 67 20 74 68 65 0a 2a 2a 20 6c 61  lowing the.** la
b8d0: 73 74 20 62 79 74 65 20 77 72 69 74 74 65 6e 20  st byte written 
b8e0: 74 6f 20 74 68 65 20 66 69 6c 65 2e 0a 2a 2f 0a  to the file..*/.
b8f0: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 50  static int vdbeP
b900: 6d 61 57 72 69 74 65 72 46 69 6e 69 73 68 28 50  maWriterFinish(P
b910: 6d 61 57 72 69 74 65 72 20 2a 70 2c 20 69 36 34  maWriter *p, i64
b920: 20 2a 70 69 45 6f 66 29 7b 0a 20 20 69 6e 74 20   *piEof){.  int 
b930: 72 63 3b 0a 20 20 69 66 28 20 70 2d 3e 65 46 57  rc;.  if( p->eFW
b940: 45 72 72 3d 3d 30 20 26 26 20 41 4c 57 41 59 53  Err==0 && ALWAYS
b950: 28 70 2d 3e 61 42 75 66 66 65 72 29 20 26 26 20  (p->aBuffer) && 
b960: 70 2d 3e 69 42 75 66 45 6e 64 3e 70 2d 3e 69 42  p->iBufEnd>p->iB
b970: 75 66 53 74 61 72 74 20 29 7b 0a 20 20 20 20 70  ufStart ){.    p
b980: 2d 3e 65 46 57 45 72 72 20 3d 20 73 71 6c 69 74  ->eFWErr = sqlit
b990: 65 33 4f 73 57 72 69 74 65 28 70 2d 3e 70 46 69  e3OsWrite(p->pFi
b9a0: 6c 65 2c 20 0a 20 20 20 20 20 20 20 20 26 70 2d  le, .        &p-
b9b0: 3e 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66  >aBuffer[p->iBuf
b9c0: 53 74 61 72 74 5d 2c 20 70 2d 3e 69 42 75 66 45  Start], p->iBufE
b9d0: 6e 64 20 2d 20 70 2d 3e 69 42 75 66 53 74 61 72  nd - p->iBufStar
b9e0: 74 2c 20 0a 20 20 20 20 20 20 20 20 70 2d 3e 69  t, .        p->i
b9f0: 57 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42  WriteOff + p->iB
ba00: 75 66 53 74 61 72 74 0a 20 20 20 20 29 3b 0a 20  ufStart.    );. 
ba10: 20 7d 0a 20 20 2a 70 69 45 6f 66 20 3d 20 28 70   }.  *piEof = (p
ba20: 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b 20 70 2d  ->iWriteOff + p-
ba30: 3e 69 42 75 66 45 6e 64 29 3b 0a 20 20 73 71 6c  >iBufEnd);.  sql
ba40: 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 42 75  ite3_free(p->aBu
ba50: 66 66 65 72 29 3b 0a 20 20 72 63 20 3d 20 70 2d  ffer);.  rc = p-
ba60: 3e 65 46 57 45 72 72 3b 0a 20 20 6d 65 6d 73 65  >eFWErr;.  memse
ba70: 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50  t(p, 0, sizeof(P
ba80: 6d 61 57 72 69 74 65 72 29 29 3b 0a 20 20 72 65  maWriter));.  re
ba90: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
baa0: 2a 20 57 72 69 74 65 20 76 61 6c 75 65 20 69 56  * Write value iV
bab0: 61 6c 20 65 6e 63 6f 64 65 64 20 61 73 20 61 20  al encoded as a 
bac0: 76 61 72 69 6e 74 20 74 6f 20 74 68 65 20 50 4d  varint to the PM
bad0: 41 2e 20 52 65 74 75 72 6e 20 0a 2a 2a 20 53 51  A. Return .** SQ
bae0: 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65  LITE_OK if succe
baf0: 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c  ssful, or an SQL
bb00: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69  ite error code i
bb10: 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
bb20: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  s..*/.static voi
bb30: 64 20 76 64 62 65 50 6d 61 57 72 69 74 65 56 61  d vdbePmaWriteVa
bb40: 72 69 6e 74 28 50 6d 61 57 72 69 74 65 72 20 2a  rint(PmaWriter *
bb50: 70 2c 20 75 36 34 20 69 56 61 6c 29 7b 0a 20 20  p, u64 iVal){.  
bb60: 69 6e 74 20 6e 42 79 74 65 3b 20 0a 20 20 75 38  int nByte; .  u8
bb70: 20 61 42 79 74 65 5b 31 30 5d 3b 0a 20 20 6e 42   aByte[10];.  nB
bb80: 79 74 65 20 3d 20 73 71 6c 69 74 65 33 50 75 74  yte = sqlite3Put
bb90: 56 61 72 69 6e 74 28 61 42 79 74 65 2c 20 69 56  Varint(aByte, iV
bba0: 61 6c 29 3b 0a 20 20 76 64 62 65 50 6d 61 57 72  al);.  vdbePmaWr
bbb0: 69 74 65 42 6c 6f 62 28 70 2c 20 61 42 79 74 65  iteBlob(p, aByte
bbc0: 2c 20 6e 42 79 74 65 29 3b 0a 7d 0a 0a 2f 2a 0a  , nByte);.}../*.
bbd0: 2a 2a 20 57 72 69 74 65 20 74 68 65 20 63 75 72  ** Write the cur
bbe0: 72 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f 66  rent contents of
bbf0: 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 6e 6b 65   in-memory linke
bc00: 64 2d 6c 69 73 74 20 70 4c 69 73 74 20 74 6f 20  d-list pList to 
bc10: 61 20 6c 65 76 65 6c 2d 30 0a 2a 2a 20 50 4d 41  a level-0.** PMA
bc20: 20 69 6e 20 74 68 65 20 74 65 6d 70 20 66 69 6c   in the temp fil
bc30: 65 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 73  e belonging to s
bc40: 75 62 2d 74 61 73 6b 20 70 54 61 73 6b 2e 20 52  ub-task pTask. R
bc50: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20  eturn SQLITE_OK 
bc60: 69 66 20 0a 2a 2a 20 73 75 63 63 65 73 73 66 75  if .** successfu
bc70: 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20  l, or an SQLite 
bc80: 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72  error code other
bc90: 77 69 73 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  wise..**.** The 
bca0: 66 6f 72 6d 61 74 20 6f 66 20 61 20 50 4d 41 20  format of a PMA 
bcb0: 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20  is:.**.**     * 
bcc0: 41 20 76 61 72 69 6e 74 2e 20 54 68 69 73 20 76  A varint. This v
bcd0: 61 72 69 6e 74 20 63 6f 6e 74 61 69 6e 73 20 74  arint contains t
bce0: 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20  he total number 
bcf0: 6f 66 20 62 79 74 65 73 20 6f 66 20 63 6f 6e 74  of bytes of cont
bd00: 65 6e 74 0a 2a 2a 20 20 20 20 20 20 20 69 6e 20  ent.**       in 
bd10: 74 68 65 20 50 4d 41 20 28 6e 6f 74 20 69 6e 63  the PMA (not inc
bd20: 6c 75 64 69 6e 67 20 74 68 65 20 76 61 72 69 6e  luding the varin
bd30: 74 20 69 74 73 65 6c 66 29 2e 0a 2a 2a 0a 2a 2a  t itself)..**.**
bd40: 20 20 20 20 20 2a 20 4f 6e 65 20 6f 72 20 6d 6f       * One or mo
bd50: 72 65 20 72 65 63 6f 72 64 73 20 70 61 63 6b 65  re records packe
bd60: 64 20 65 6e 64 2d 74 6f 2d 65 6e 64 20 69 6e 20  d end-to-end in 
bd70: 6f 72 64 65 72 20 6f 66 20 61 73 63 65 6e 64 69  order of ascendi
bd80: 6e 67 20 6b 65 79 73 2e 20 0a 2a 2a 20 20 20 20  ng keys. .**    
bd90: 20 20 20 45 61 63 68 20 72 65 63 6f 72 64 20 63     Each record c
bda0: 6f 6e 73 69 73 74 73 20 6f 66 20 61 20 76 61 72  onsists of a var
bdb0: 69 6e 74 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20  int followed by 
bdc0: 61 20 62 6c 6f 62 20 6f 66 20 64 61 74 61 20 28  a blob of data (
bdd0: 74 68 65 20 0a 2a 2a 20 20 20 20 20 20 20 6b 65  the .**       ke
bde0: 79 29 2e 20 54 68 65 20 76 61 72 69 6e 74 20 69  y). The varint i
bdf0: 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  s the number of 
be00: 62 79 74 65 73 20 69 6e 20 74 68 65 20 62 6c 6f  bytes in the blo
be10: 62 20 6f 66 20 64 61 74 61 2e 0a 2a 2f 0a 73 74  b of data..*/.st
be20: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
be30: 74 65 72 4c 69 73 74 54 6f 50 4d 41 28 53 6f 72  terListToPMA(Sor
be40: 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c  tSubtask *pTask,
be50: 20 53 6f 72 74 65 72 4c 69 73 74 20 2a 70 4c 69   SorterList *pLi
be60: 73 74 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a  st){.  sqlite3 *
be70: 64 62 20 3d 20 70 54 61 73 6b 2d 3e 70 53 6f 72  db = pTask->pSor
be80: 74 65 72 2d 3e 64 62 3b 0a 20 20 69 6e 74 20 72  ter->db;.  int r
be90: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20  c = SQLITE_OK;  
bea0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
beb0: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 50  turn code */.  P
bec0: 6d 61 57 72 69 74 65 72 20 77 72 69 74 65 72 3b  maWriter writer;
bed0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
bee0: 2a 20 4f 62 6a 65 63 74 20 75 73 65 64 20 74 6f  * Object used to
bef0: 20 77 72 69 74 65 20 74 6f 20 74 68 65 20 66 69   write to the fi
bf00: 6c 65 20 2a 2f 0a 0a 23 69 66 64 65 66 20 53 51  le */..#ifdef SQ
bf10: 4c 49 54 45 5f 44 45 42 55 47 0a 20 20 2f 2a 20  LITE_DEBUG.  /* 
bf20: 53 65 74 20 69 53 7a 20 74 6f 20 74 68 65 20 65  Set iSz to the e
bf30: 78 70 65 63 74 65 64 20 73 69 7a 65 20 6f 66 20  xpected size of 
bf40: 66 69 6c 65 20 70 54 61 73 6b 2d 3e 66 69 6c 65  file pTask->file
bf50: 20 61 66 74 65 72 20 77 72 69 74 69 6e 67 20 74   after writing t
bf60: 68 65 20 50 4d 41 2e 20 0a 20 20 2a 2a 20 54 68  he PMA. .  ** Th
bf70: 69 73 20 69 73 20 75 73 65 64 20 62 79 20 61 6e  is is used by an
bf80: 20 61 73 73 65 72 74 28 29 20 73 74 61 74 65 6d   assert() statem
bf90: 65 6e 74 20 61 74 20 74 68 65 20 65 6e 64 20 6f  ent at the end o
bfa0: 66 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 2e  f this function.
bfb0: 20 20 2a 2f 0a 20 20 69 36 34 20 69 53 7a 20 3d    */.  i64 iSz =
bfc0: 20 70 4c 69 73 74 2d 3e 73 7a 50 4d 41 20 2b 20   pList->szPMA + 
bfd0: 73 71 6c 69 74 65 33 56 61 72 69 6e 74 4c 65 6e  sqlite3VarintLen
bfe0: 28 70 4c 69 73 74 2d 3e 73 7a 50 4d 41 29 20 2b  (pList->szPMA) +
bff0: 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f   pTask->file.iEo
c000: 66 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 76 64 62  f;.#endif..  vdb
c010: 65 53 6f 72 74 65 72 57 6f 72 6b 44 65 62 75 67  eSorterWorkDebug
c020: 28 70 54 61 73 6b 2c 20 22 65 6e 74 65 72 22 29  (pTask, "enter")
c030: 3b 0a 20 20 6d 65 6d 73 65 74 28 26 77 72 69 74  ;.  memset(&writ
c040: 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50 6d  er, 0, sizeof(Pm
c050: 61 57 72 69 74 65 72 29 29 3b 0a 20 20 61 73 73  aWriter));.  ass
c060: 65 72 74 28 20 70 4c 69 73 74 2d 3e 73 7a 50 4d  ert( pList->szPM
c070: 41 3e 30 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20  A>0 );..  /* If 
c080: 74 68 65 20 66 69 72 73 74 20 74 65 6d 70 6f 72  the first tempor
c090: 61 72 79 20 50 4d 41 20 66 69 6c 65 20 68 61 73  ary PMA file has
c0a0: 20 6e 6f 74 20 62 65 65 6e 20 6f 70 65 6e 65 64   not been opened
c0b0: 2c 20 6f 70 65 6e 20 69 74 20 6e 6f 77 2e 20 2a  , open it now. *
c0c0: 2f 0a 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 66  /.  if( pTask->f
c0d0: 69 6c 65 2e 70 46 64 3d 3d 30 20 29 7b 0a 20 20  ile.pFd==0 ){.  
c0e0: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
c0f0: 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 64 62  rOpenTempFile(db
c100: 2c 20 30 2c 20 26 70 54 61 73 6b 2d 3e 66 69 6c  , 0, &pTask->fil
c110: 65 2e 70 46 64 29 3b 0a 20 20 20 20 61 73 73 65  e.pFd);.    asse
c120: 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  rt( rc!=SQLITE_O
c130: 4b 20 7c 7c 20 70 54 61 73 6b 2d 3e 66 69 6c 65  K || pTask->file
c140: 2e 70 46 64 20 29 3b 0a 20 20 20 20 61 73 73 65  .pFd );.    asse
c150: 72 74 28 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e  rt( pTask->file.
c160: 69 45 6f 66 3d 3d 30 20 29 3b 0a 20 20 20 20 61  iEof==0 );.    a
c170: 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e 6e 50  ssert( pTask->nP
c180: 4d 41 3d 3d 30 20 29 3b 0a 20 20 7d 0a 0a 20 20  MA==0 );.  }..  
c190: 2f 2a 20 54 72 79 20 74 6f 20 67 65 74 20 74 68  /* Try to get th
c1a0: 65 20 66 69 6c 65 20 74 6f 20 6d 65 6d 6f 72 79  e file to memory
c1b0: 20 6d 61 70 20 2a 2f 0a 20 20 69 66 28 20 72 63   map */.  if( rc
c1c0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
c1d0: 20 20 20 76 64 62 65 53 6f 72 74 65 72 45 78 74     vdbeSorterExt
c1e0: 65 6e 64 46 69 6c 65 28 64 62 2c 20 70 54 61 73  endFile(db, pTas
c1f0: 6b 2d 3e 66 69 6c 65 2e 70 46 64 2c 20 70 54 61  k->file.pFd, pTa
c200: 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66 2b 70 4c  sk->file.iEof+pL
c210: 69 73 74 2d 3e 73 7a 50 4d 41 2b 39 29 3b 0a 20  ist->szPMA+9);. 
c220: 20 7d 0a 0a 20 20 2f 2a 20 53 6f 72 74 20 74 68   }..  /* Sort th
c230: 65 20 6c 69 73 74 20 2a 2f 0a 20 20 69 66 28 20  e list */.  if( 
c240: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
c250: 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f  .    rc = vdbeSo
c260: 72 74 65 72 53 6f 72 74 28 70 54 61 73 6b 2c 20  rterSort(pTask, 
c270: 70 4c 69 73 74 29 3b 0a 20 20 7d 0a 0a 20 20 69  pList);.  }..  i
c280: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
c290: 20 29 7b 0a 20 20 20 20 53 6f 72 74 65 72 52 65   ){.    SorterRe
c2a0: 63 6f 72 64 20 2a 70 3b 0a 20 20 20 20 53 6f 72  cord *p;.    Sor
c2b0: 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65 78 74  terRecord *pNext
c2c0: 20 3d 20 30 3b 0a 0a 20 20 20 20 76 64 62 65 50   = 0;..    vdbeP
c2d0: 6d 61 57 72 69 74 65 72 49 6e 69 74 28 70 54 61  maWriterInit(pTa
c2e0: 73 6b 2d 3e 66 69 6c 65 2e 70 46 64 2c 20 26 77  sk->file.pFd, &w
c2f0: 72 69 74 65 72 2c 20 70 54 61 73 6b 2d 3e 70 53  riter, pTask->pS
c300: 6f 72 74 65 72 2d 3e 70 67 73 7a 2c 0a 20 20 20  orter->pgsz,.   
c310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c320: 20 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69     pTask->file.i
c330: 45 6f 66 29 3b 0a 20 20 20 20 70 54 61 73 6b 2d  Eof);.    pTask-
c340: 3e 6e 50 4d 41 2b 2b 3b 0a 20 20 20 20 76 64 62  >nPMA++;.    vdb
c350: 65 50 6d 61 57 72 69 74 65 56 61 72 69 6e 74 28  ePmaWriteVarint(
c360: 26 77 72 69 74 65 72 2c 20 70 4c 69 73 74 2d 3e  &writer, pList->
c370: 73 7a 50 4d 41 29 3b 0a 20 20 20 20 66 6f 72 28  szPMA);.    for(
c380: 70 3d 70 4c 69 73 74 2d 3e 70 4c 69 73 74 3b 20  p=pList->pList; 
c390: 70 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20  p; p=pNext){.   
c3a0: 20 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e 75 2e     pNext = p->u.
c3b0: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 76 64 62  pNext;.      vdb
c3c0: 65 50 6d 61 57 72 69 74 65 56 61 72 69 6e 74 28  ePmaWriteVarint(
c3d0: 26 77 72 69 74 65 72 2c 20 70 2d 3e 6e 56 61 6c  &writer, p->nVal
c3e0: 29 3b 0a 20 20 20 20 20 20 76 64 62 65 50 6d 61  );.      vdbePma
c3f0: 57 72 69 74 65 42 6c 6f 62 28 26 77 72 69 74 65  WriteBlob(&write
c400: 72 2c 20 53 52 56 41 4c 28 70 29 2c 20 70 2d 3e  r, SRVAL(p), p->
c410: 6e 56 61 6c 29 3b 0a 20 20 20 20 20 20 69 66 28  nVal);.      if(
c420: 20 70 4c 69 73 74 2d 3e 61 4d 65 6d 6f 72 79 3d   pList->aMemory=
c430: 3d 30 20 29 20 73 71 6c 69 74 65 33 5f 66 72 65  =0 ) sqlite3_fre
c440: 65 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  e(p);.    }.    
c450: 70 4c 69 73 74 2d 3e 70 4c 69 73 74 20 3d 20 70  pList->pList = p
c460: 3b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 50  ;.    rc = vdbeP
c470: 6d 61 57 72 69 74 65 72 46 69 6e 69 73 68 28 26  maWriterFinish(&
c480: 77 72 69 74 65 72 2c 20 26 70 54 61 73 6b 2d 3e  writer, &pTask->
c490: 66 69 6c 65 2e 69 45 6f 66 29 3b 0a 20 20 7d 0a  file.iEof);.  }.
c4a0: 0a 20 20 76 64 62 65 53 6f 72 74 65 72 57 6f 72  .  vdbeSorterWor
c4b0: 6b 44 65 62 75 67 28 70 54 61 73 6b 2c 20 22 65  kDebug(pTask, "e
c4c0: 78 69 74 22 29 3b 0a 20 20 61 73 73 65 72 74 28  xit");.  assert(
c4d0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c   rc!=SQLITE_OK |
c4e0: 7c 20 70 4c 69 73 74 2d 3e 70 4c 69 73 74 3d 3d  | pList->pList==
c4f0: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 72  0 );.  assert( r
c500: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20  c!=SQLITE_OK || 
c510: 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 69 45 6f 66  pTask->file.iEof
c520: 3d 3d 69 53 7a 20 29 3b 0a 20 20 72 65 74 75 72  ==iSz );.  retur
c530: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  n rc;.}../*.** A
c540: 64 76 61 6e 63 65 20 74 68 65 20 4d 65 72 67 65  dvance the Merge
c550: 45 6e 67 69 6e 65 20 69 74 65 72 61 74 6f 72 20  Engine iterator 
c560: 70 61 73 73 65 64 20 61 73 20 74 68 65 20 73 65  passed as the se
c570: 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 74 6f  cond argument to
c580: 0a 2a 2a 20 74 68 65 20 6e 65 78 74 20 65 6e 74  .** the next ent
c590: 72 79 2e 20 53 65 74 20 2a 70 62 45 6f 66 20 74  ry. Set *pbEof t
c5a0: 6f 20 74 72 75 65 20 69 66 20 74 68 69 73 20 6d  o true if this m
c5b0: 65 61 6e 73 20 74 68 65 20 69 74 65 72 61 74 6f  eans the iterato
c5c0: 72 20 68 61 73 20 0a 2a 2a 20 72 65 61 63 68 65  r has .** reache
c5d0: 64 20 45 4f 46 2e 0a 2a 2a 0a 2a 2a 20 52 65 74  d EOF..**.** Ret
c5e0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66  urn SQLITE_OK if
c5f0: 20 73 75 63 63 65 73 73 66 75 6c 20 6f 72 20 61   successful or a
c600: 6e 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20  n error code if 
c610: 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e  an error occurs.
c620: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
c630: 64 62 65 53 6f 72 74 65 72 4e 65 78 74 28 0a 20  dbeSorterNext(. 
c640: 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
c650: 61 73 6b 2c 20 0a 20 20 4d 65 72 67 65 45 6e 67  ask, .  MergeEng
c660: 69 6e 65 20 2a 70 4d 65 72 67 65 72 2c 20 0a 20  ine *pMerger, . 
c670: 20 69 6e 74 20 2a 70 62 45 6f 66 0a 29 7b 0a 20   int *pbEof.){. 
c680: 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69   int rc;.  int i
c690: 50 72 65 76 20 3d 20 70 4d 65 72 67 65 72 2d 3e  Prev = pMerger->
c6a0: 61 54 72 65 65 5b 31 5d 3b 2f 2a 20 49 6e 64 65  aTree[1];/* Inde
c6b0: 78 20 6f 66 20 69 74 65 72 61 74 6f 72 20 74 6f  x of iterator to
c6c0: 20 61 64 76 61 6e 63 65 20 2a 2f 0a 0a 20 20 2f   advance */..  /
c6d0: 2a 20 41 64 76 61 6e 63 65 20 74 68 65 20 63 75  * Advance the cu
c6e0: 72 72 65 6e 74 20 69 74 65 72 61 74 6f 72 20 2a  rrent iterator *
c6f0: 2f 0a 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61  /.  rc = vdbePma
c700: 52 65 61 64 65 72 4e 65 78 74 28 26 70 4d 65 72  ReaderNext(&pMer
c710: 67 65 72 2d 3e 61 49 74 65 72 5b 69 50 72 65 76  ger->aIter[iPrev
c720: 5d 29 3b 0a 0a 20 20 2f 2a 20 55 70 64 61 74 65  ]);..  /* Update
c730: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61 54 72   contents of aTr
c740: 65 65 5b 5d 20 2a 2f 0a 20 20 69 66 28 20 72 63  ee[] */.  if( rc
c750: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
c760: 20 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20     int i;       
c770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c780: 2a 20 49 6e 64 65 78 20 6f 66 20 61 54 72 65 65  * Index of aTree
c790: 5b 5d 20 74 6f 20 72 65 63 61 6c 63 75 6c 61 74  [] to recalculat
c7a0: 65 20 2a 2f 0a 20 20 20 20 50 6d 61 52 65 61 64  e */.    PmaRead
c7b0: 65 72 20 2a 70 49 74 65 72 31 3b 20 20 20 20 20  er *pIter1;     
c7c0: 2f 2a 20 46 69 72 73 74 20 69 74 65 72 61 74 6f  /* First iterato
c7d0: 72 20 74 6f 20 63 6f 6d 70 61 72 65 20 2a 2f 0a  r to compare */.
c7e0: 20 20 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70      PmaReader *p
c7f0: 49 74 65 72 32 3b 20 20 20 20 20 2f 2a 20 53 65  Iter2;     /* Se
c800: 63 6f 6e 64 20 69 74 65 72 61 74 6f 72 20 74 6f  cond iterator to
c810: 20 63 6f 6d 70 61 72 65 20 2a 2f 0a 20 20 20 20   compare */.    
c820: 75 38 20 2a 70 4b 65 79 32 3b 20 20 20 20 20 20  u8 *pKey2;      
c830: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
c840: 6f 20 70 49 74 65 72 32 2d 3e 61 4b 65 79 2c 20  o pIter2->aKey, 
c850: 6f 72 20 30 20 69 66 20 72 65 63 6f 72 64 20 63  or 0 if record c
c860: 61 63 68 65 64 20 2a 2f 0a 0a 20 20 20 20 2f 2a  ached */..    /*
c870: 20 46 69 6e 64 20 74 68 65 20 66 69 72 73 74 20   Find the first 
c880: 74 77 6f 20 69 74 65 72 61 74 6f 72 73 20 74 6f  two iterators to
c890: 20 63 6f 6d 70 61 72 65 2e 20 54 68 65 20 6f 6e   compare. The on
c8a0: 65 20 74 68 61 74 20 77 61 73 20 6a 75 73 74 0a  e that was just.
c8b0: 20 20 20 20 2a 2a 20 61 64 76 61 6e 63 65 64 20      ** advanced 
c8c0: 28 69 50 72 65 76 29 20 61 6e 64 20 74 68 65 20  (iPrev) and the 
c8d0: 6f 6e 65 20 6e 65 78 74 20 74 6f 20 69 74 20 69  one next to it i
c8e0: 6e 20 74 68 65 20 61 72 72 61 79 2e 20 20 2a 2f  n the array.  */
c8f0: 0a 20 20 20 20 70 49 74 65 72 31 20 3d 20 26 70  .    pIter1 = &p
c900: 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 28 69  Merger->aIter[(i
c910: 50 72 65 76 20 26 20 30 78 46 46 46 45 29 5d 3b  Prev & 0xFFFE)];
c920: 0a 20 20 20 20 70 49 74 65 72 32 20 3d 20 26 70  .    pIter2 = &p
c930: 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 28 69  Merger->aIter[(i
c940: 50 72 65 76 20 7c 20 30 78 30 30 30 31 29 5d 3b  Prev | 0x0001)];
c950: 0a 20 20 20 20 70 4b 65 79 32 20 3d 20 70 49 74  .    pKey2 = pIt
c960: 65 72 32 2d 3e 61 4b 65 79 3b 0a 0a 20 20 20 20  er2->aKey;..    
c970: 66 6f 72 28 69 3d 28 70 4d 65 72 67 65 72 2d 3e  for(i=(pMerger->
c980: 6e 54 72 65 65 2b 69 50 72 65 76 29 2f 32 3b 20  nTree+iPrev)/2; 
c990: 69 3e 30 3b 20 69 3d 69 2f 32 29 7b 0a 20 20 20  i>0; i=i/2){.   
c9a0: 20 20 20 2f 2a 20 43 6f 6d 70 61 72 65 20 70 49     /* Compare pI
c9b0: 74 65 72 31 20 61 6e 64 20 70 49 74 65 72 32 2e  ter1 and pIter2.
c9c0: 20 53 74 6f 72 65 20 74 68 65 20 72 65 73 75 6c   Store the resul
c9d0: 74 20 69 6e 20 76 61 72 69 61 62 6c 65 20 69 52  t in variable iR
c9e0: 65 73 2e 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74  es. */.      int
c9f0: 20 69 52 65 73 3b 0a 20 20 20 20 20 20 69 66 28   iRes;.      if(
ca00: 20 70 49 74 65 72 31 2d 3e 70 46 69 6c 65 3d 3d   pIter1->pFile==
ca10: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 69 52 65  0 ){.        iRe
ca20: 73 20 3d 20 2b 31 3b 0a 20 20 20 20 20 20 7d 65  s = +1;.      }e
ca30: 6c 73 65 20 69 66 28 20 70 49 74 65 72 32 2d 3e  lse if( pIter2->
ca40: 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20  pFile==0 ){.    
ca50: 20 20 20 20 69 52 65 73 20 3d 20 2d 31 3b 0a 20      iRes = -1;. 
ca60: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
ca70: 20 20 20 20 69 52 65 73 20 3d 20 76 64 62 65 53      iRes = vdbeS
ca80: 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 70 54 61  orterCompare(pTa
ca90: 73 6b 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20  sk, .           
caa0: 20 70 49 74 65 72 31 2d 3e 61 4b 65 79 2c 20 70   pIter1->aKey, p
cab0: 49 74 65 72 31 2d 3e 6e 4b 65 79 2c 20 70 4b 65  Iter1->nKey, pKe
cac0: 79 32 2c 20 70 49 74 65 72 32 2d 3e 6e 4b 65 79  y2, pIter2->nKey
cad0: 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20  .        );.    
cae0: 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 49 66    }..      /* If
caf0: 20 70 49 74 65 72 31 20 63 6f 6e 74 61 69 6e 65   pIter1 containe
cb00: 64 20 74 68 65 20 73 6d 61 6c 6c 65 72 20 76 61  d the smaller va
cb10: 6c 75 65 2c 20 73 65 74 20 61 54 72 65 65 5b 69  lue, set aTree[i
cb20: 5d 20 74 6f 20 69 74 73 20 69 6e 64 65 78 2e 0a  ] to its index..
cb30: 20 20 20 20 20 20 2a 2a 20 54 68 65 6e 20 73 65        ** Then se
cb40: 74 20 70 49 74 65 72 32 20 74 6f 20 74 68 65 20  t pIter2 to the 
cb50: 6e 65 78 74 20 69 74 65 72 61 74 6f 72 20 74 6f  next iterator to
cb60: 20 63 6f 6d 70 61 72 65 20 74 6f 20 70 49 74 65   compare to pIte
cb70: 72 31 2e 20 49 6e 20 74 68 69 73 0a 20 20 20 20  r1. In this.    
cb80: 20 20 2a 2a 20 63 61 73 65 20 74 68 65 72 65 20    ** case there 
cb90: 69 73 20 6e 6f 20 63 61 63 68 65 20 6f 66 20 70  is no cache of p
cba0: 49 74 65 72 32 20 69 6e 20 70 54 61 73 6b 2d 3e  Iter2 in pTask->
cbb0: 70 55 6e 70 61 63 6b 65 64 2c 20 73 6f 20 73 65  pUnpacked, so se
cbc0: 74 0a 20 20 20 20 20 20 2a 2a 20 70 4b 65 79 32  t.      ** pKey2
cbd0: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65   to point to the
cbe0: 20 72 65 63 6f 72 64 20 62 65 6c 6f 6e 67 69 6e   record belongin
cbf0: 67 20 74 6f 20 70 49 74 65 72 32 2e 0a 20 20 20  g to pIter2..   
cc00: 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 41     **.      ** A
cc10: 6c 74 65 72 6e 61 74 69 76 65 6c 79 2c 20 69 66  lternatively, if
cc20: 20 70 49 74 65 72 32 20 63 6f 6e 74 61 69 6e 73   pIter2 contains
cc30: 20 74 68 65 20 73 6d 61 6c 6c 65 72 20 6f 66 20   the smaller of 
cc40: 74 68 65 20 74 77 6f 20 76 61 6c 75 65 73 2c 0a  the two values,.
cc50: 20 20 20 20 20 20 2a 2a 20 73 65 74 20 61 54 72        ** set aTr
cc60: 65 65 5b 69 5d 20 74 6f 20 69 74 73 20 69 6e 64  ee[i] to its ind
cc70: 65 78 20 61 6e 64 20 75 70 64 61 74 65 20 70 49  ex and update pI
cc80: 74 65 72 31 2e 20 49 66 20 76 64 62 65 53 6f 72  ter1. If vdbeSor
cc90: 74 65 72 43 6f 6d 70 61 72 65 28 29 0a 20 20 20  terCompare().   
cca0: 20 20 20 2a 2a 20 77 61 73 20 61 63 74 75 61 6c     ** was actual
ccb0: 6c 79 20 63 61 6c 6c 65 64 20 61 62 6f 76 65 2c  ly called above,
ccc0: 20 74 68 65 6e 20 70 54 61 73 6b 2d 3e 70 55 6e   then pTask->pUn
ccd0: 70 61 63 6b 65 64 20 6e 6f 77 20 63 6f 6e 74 61  packed now conta
cce0: 69 6e 73 0a 20 20 20 20 20 20 2a 2a 20 61 20 76  ins.      ** a v
ccf0: 61 6c 75 65 20 65 71 75 69 76 61 6c 65 6e 74 20  alue equivalent 
cd00: 74 6f 20 70 49 74 65 72 32 2e 20 53 6f 20 73 65  to pIter2. So se
cd10: 74 20 70 4b 65 79 32 20 74 6f 20 4e 55 4c 4c 20  t pKey2 to NULL 
cd20: 74 6f 20 70 72 65 76 65 6e 74 0a 20 20 20 20 20  to prevent.     
cd30: 20 2a 2a 20 76 64 62 65 53 6f 72 74 65 72 43 6f   ** vdbeSorterCo
cd40: 6d 70 61 72 65 28 29 20 66 72 6f 6d 20 64 65 63  mpare() from dec
cd50: 6f 64 69 6e 67 20 70 49 74 65 72 32 20 61 67 61  oding pIter2 aga
cd60: 69 6e 2e 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20  in..      **.   
cd70: 20 20 20 2a 2a 20 49 66 20 74 68 65 20 74 77 6f     ** If the two
cd80: 20 76 61 6c 75 65 73 20 77 65 72 65 20 65 71 75   values were equ
cd90: 61 6c 2c 20 74 68 65 6e 20 74 68 65 20 76 61 6c  al, then the val
cda0: 75 65 20 66 72 6f 6d 20 74 68 65 20 6f 6c 64 65  ue from the olde
cdb0: 73 74 0a 20 20 20 20 20 20 2a 2a 20 50 4d 41 20  st.      ** PMA 
cdc0: 73 68 6f 75 6c 64 20 62 65 20 63 6f 6e 73 69 64  should be consid
cdd0: 65 72 65 64 20 73 6d 61 6c 6c 65 72 2e 20 54 68  ered smaller. Th
cde0: 65 20 56 64 62 65 53 6f 72 74 65 72 2e 61 49 74  e VdbeSorter.aIt
cdf0: 65 72 5b 5d 20 61 72 72 61 79 0a 20 20 20 20 20  er[] array.     
ce00: 20 2a 2a 20 69 73 20 73 6f 72 74 65 64 20 66 72   ** is sorted fr
ce10: 6f 6d 20 6f 6c 64 65 73 74 20 74 6f 20 6e 65 77  om oldest to new
ce20: 65 73 74 2c 20 73 6f 20 70 49 74 65 72 31 20 63  est, so pIter1 c
ce30: 6f 6e 74 61 69 6e 73 20 6f 6c 64 65 72 20 76 61  ontains older va
ce40: 6c 75 65 73 0a 20 20 20 20 20 20 2a 2a 20 74 68  lues.      ** th
ce50: 61 6e 20 70 49 74 65 72 32 20 69 66 66 20 28 70  an pIter2 iff (p
ce60: 49 74 65 72 31 3c 70 49 74 65 72 32 29 2e 20 20  Iter1<pIter2).  
ce70: 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 69 52 65  */.      if( iRe
ce80: 73 3c 30 20 7c 7c 20 28 69 52 65 73 3d 3d 30 20  s<0 || (iRes==0 
ce90: 26 26 20 70 49 74 65 72 31 3c 70 49 74 65 72 32  && pIter1<pIter2
cea0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 70 4d 65  ) ){.        pMe
ceb0: 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 5d 20 3d  rger->aTree[i] =
cec0: 20 28 69 6e 74 29 28 70 49 74 65 72 31 20 2d 20   (int)(pIter1 - 
ced0: 70 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 29 3b  pMerger->aIter);
cee0: 0a 20 20 20 20 20 20 20 20 70 49 74 65 72 32 20  .        pIter2 
cef0: 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65  = &pMerger->aIte
cf00: 72 5b 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65  r[ pMerger->aTre
cf10: 65 5b 69 20 5e 20 30 78 30 30 30 31 5d 20 5d 3b  e[i ^ 0x0001] ];
cf20: 0a 20 20 20 20 20 20 20 20 70 4b 65 79 32 20 3d  .        pKey2 =
cf30: 20 70 49 74 65 72 32 2d 3e 61 4b 65 79 3b 0a 20   pIter2->aKey;. 
cf40: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
cf50: 20 20 20 20 69 66 28 20 70 49 74 65 72 31 2d 3e      if( pIter1->
cf60: 70 46 69 6c 65 20 29 20 70 4b 65 79 32 20 3d 20  pFile ) pKey2 = 
cf70: 30 3b 0a 20 20 20 20 20 20 20 20 70 4d 65 72 67  0;.        pMerg
cf80: 65 72 2d 3e 61 54 72 65 65 5b 69 5d 20 3d 20 28  er->aTree[i] = (
cf90: 69 6e 74 29 28 70 49 74 65 72 32 20 2d 20 70 4d  int)(pIter2 - pM
cfa0: 65 72 67 65 72 2d 3e 61 49 74 65 72 29 3b 0a 20  erger->aIter);. 
cfb0: 20 20 20 20 20 20 20 70 49 74 65 72 31 20 3d 20         pIter1 = 
cfc0: 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b  &pMerger->aIter[
cfd0: 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b   pMerger->aTree[
cfe0: 69 20 5e 20 30 78 30 30 30 31 5d 20 5d 3b 0a 20  i ^ 0x0001] ];. 
cff0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
d000: 20 2a 70 62 45 6f 66 20 3d 20 28 70 4d 65 72 67   *pbEof = (pMerg
d010: 65 72 2d 3e 61 49 74 65 72 5b 70 4d 65 72 67 65  er->aIter[pMerge
d020: 72 2d 3e 61 54 72 65 65 5b 31 5d 5d 2e 70 46 69  r->aTree[1]].pFi
d030: 6c 65 3d 3d 30 29 3b 0a 20 20 7d 0a 0a 20 20 72  le==0);.  }..  r
d040: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 23 69 66  eturn rc;.}..#if
d050: 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b   SQLITE_MAX_WORK
d060: 45 52 5f 54 48 52 45 41 44 53 3e 30 0a 2f 2a 0a  ER_THREADS>0./*.
d070: 2a 2a 20 54 68 65 20 6d 61 69 6e 20 72 6f 75 74  ** The main rout
d080: 69 6e 65 20 66 6f 72 20 62 61 63 6b 67 72 6f 75  ine for backgrou
d090: 6e 64 20 74 68 72 65 61 64 73 20 74 68 61 74 20  nd threads that 
d0a0: 77 72 69 74 65 20 6c 65 76 65 6c 2d 30 20 50 4d  write level-0 PM
d0b0: 41 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  As..*/.static vo
d0c0: 69 64 20 2a 76 64 62 65 53 6f 72 74 65 72 46 6c  id *vdbeSorterFl
d0d0: 75 73 68 54 68 72 65 61 64 28 76 6f 69 64 20 2a  ushThread(void *
d0e0: 70 43 74 78 29 7b 0a 20 20 53 6f 72 74 53 75 62  pCtx){.  SortSub
d0f0: 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20 28 53  task *pTask = (S
d100: 6f 72 74 53 75 62 74 61 73 6b 2a 29 70 43 74 78  ortSubtask*)pCtx
d110: 3b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  ;.  int rc;     
d120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d130: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f      /* Return co
d140: 64 65 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20  de */.  assert( 
d150: 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 3d 3d 30 20  pTask->bDone==0 
d160: 29 3b 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f  );.  rc = vdbeSo
d170: 72 74 65 72 4c 69 73 74 54 6f 50 4d 41 28 70 54  rterListToPMA(pT
d180: 61 73 6b 2c 20 26 70 54 61 73 6b 2d 3e 6c 69 73  ask, &pTask->lis
d190: 74 29 3b 0a 20 20 70 54 61 73 6b 2d 3e 62 44 6f  t);.  pTask->bDo
d1a0: 6e 65 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e  ne = 1;.  return
d1b0: 20 53 51 4c 49 54 45 5f 49 4e 54 5f 54 4f 5f 50   SQLITE_INT_TO_P
d1c0: 54 52 28 72 63 29 3b 0a 7d 0a 23 65 6e 64 69 66  TR(rc);.}.#endif
d1d0: 20 2f 2a 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57   /* SQLITE_MAX_W
d1e0: 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 20  ORKER_THREADS>0 
d1f0: 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68 20  */../*.** Flush 
d200: 74 68 65 20 63 75 72 72 65 6e 74 20 63 6f 6e 74  the current cont
d210: 65 6e 74 73 20 6f 66 20 56 64 62 65 53 6f 72 74  ents of VdbeSort
d220: 65 72 2e 6c 69 73 74 20 74 6f 20 61 20 6e 65 77  er.list to a new
d230: 20 50 4d 41 2c 20 70 6f 73 73 69 62 6c 79 0a 2a   PMA, possibly.*
d240: 2a 20 75 73 69 6e 67 20 61 20 62 61 63 6b 67 72  * using a backgr
d250: 6f 75 6e 64 20 74 68 72 65 61 64 2e 0a 2a 2f 0a  ound thread..*/.
d260: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53  static int vdbeS
d270: 6f 72 74 65 72 46 6c 75 73 68 50 4d 41 28 56 64  orterFlushPMA(Vd
d280: 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
d290: 72 29 7b 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d  r){.#if SQLITE_M
d2a0: 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44  AX_WORKER_THREAD
d2b0: 53 3d 3d 30 0a 20 20 70 53 6f 72 74 65 72 2d 3e  S==0.  pSorter->
d2c0: 62 55 73 65 50 4d 41 20 3d 20 31 3b 0a 20 20 72  bUsePMA = 1;.  r
d2d0: 65 74 75 72 6e 20 76 64 62 65 53 6f 72 74 65 72  eturn vdbeSorter
d2e0: 4c 69 73 74 54 6f 50 4d 41 28 26 70 53 6f 72 74  ListToPMA(&pSort
d2f0: 65 72 2d 3e 61 54 61 73 6b 5b 30 5d 2c 20 26 70  er->aTask[0], &p
d300: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 29 3b 0a 23  Sorter->list);.#
d310: 65 6c 73 65 0a 20 20 69 6e 74 20 72 63 20 3d 20  else.  int rc = 
d320: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74  SQLITE_OK;.  int
d330: 20 69 3b 0a 20 20 53 6f 72 74 53 75 62 74 61 73   i;.  SortSubtas
d340: 6b 20 2a 70 54 61 73 6b 20 3d 20 30 3b 20 20 20  k *pTask = 0;   
d350: 20 2f 2a 20 54 68 72 65 61 64 20 63 6f 6e 74 65   /* Thread conte
d360: 78 74 20 75 73 65 64 20 74 6f 20 63 72 65 61 74  xt used to creat
d370: 65 20 6e 65 77 20 50 4d 41 20 2a 2f 0a 20 20 69  e new PMA */.  i
d380: 6e 74 20 6e 57 6f 72 6b 65 72 20 3d 20 28 70 53  nt nWorker = (pS
d390: 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 3b  orter->nTask-1);
d3a0: 0a 0a 20 20 2f 2a 20 53 65 74 20 74 68 65 20 66  ..  /* Set the f
d3b0: 6c 61 67 20 74 6f 20 69 6e 64 69 63 61 74 65 20  lag to indicate 
d3c0: 74 68 61 74 20 61 74 20 6c 65 61 73 74 20 6f 6e  that at least on
d3d0: 65 20 50 4d 41 20 68 61 73 20 62 65 65 6e 20 77  e PMA has been w
d3e0: 72 69 74 74 65 6e 2e 20 0a 20 20 2a 2a 20 4f 72  ritten. .  ** Or
d3f0: 20 77 69 6c 6c 20 62 65 2c 20 61 6e 79 68 6f 77   will be, anyhow
d400: 2e 20 20 2a 2f 0a 20 20 70 53 6f 72 74 65 72 2d  .  */.  pSorter-
d410: 3e 62 55 73 65 50 4d 41 20 3d 20 31 3b 0a 0a 20  >bUsePMA = 1;.. 
d420: 20 2f 2a 20 53 65 6c 65 63 74 20 61 20 73 75 62   /* Select a sub
d430: 2d 74 61 73 6b 20 74 6f 20 73 6f 72 74 20 61 6e  -task to sort an
d440: 64 20 66 6c 75 73 68 20 74 68 65 20 63 75 72 72  d flush the curr
d450: 65 6e 74 20 6c 69 73 74 20 6f 66 20 69 6e 2d 6d  ent list of in-m
d460: 65 6d 6f 72 79 0a 20 20 2a 2a 20 72 65 63 6f 72  emory.  ** recor
d470: 64 73 20 74 6f 20 64 69 73 6b 2e 20 49 66 20 74  ds to disk. If t
d480: 68 65 20 73 6f 72 74 65 72 20 69 73 20 72 75 6e  he sorter is run
d490: 6e 69 6e 67 20 69 6e 20 6d 75 6c 74 69 2d 74 68  ning in multi-th
d4a0: 72 65 61 64 65 64 20 6d 6f 64 65 2c 0a 20 20 2a  readed mode,.  *
d4b0: 2a 20 72 6f 75 6e 64 2d 72 6f 62 69 6e 20 62 65  * round-robin be
d4c0: 74 77 65 65 6e 20 74 68 65 20 66 69 72 73 74 20  tween the first 
d4d0: 28 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 2d  (pSorter->nTask-
d4e0: 31 29 20 74 61 73 6b 73 2e 20 45 78 63 65 70 74  1) tasks. Except
d4f0: 2c 20 69 66 0a 20 20 2a 2a 20 74 68 65 20 62 61  , if.  ** the ba
d500: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
d510: 66 72 6f 6d 20 61 20 73 75 62 2d 74 61 73 6b 73  from a sub-tasks
d520: 20 70 72 65 76 69 6f 75 73 20 74 75 72 6e 20 69   previous turn i
d530: 73 20 73 74 69 6c 6c 20 72 75 6e 6e 69 6e 67 2c  s still running,
d540: 0a 20 20 2a 2a 20 73 6b 69 70 20 69 74 2e 20 49  .  ** skip it. I
d550: 66 20 74 68 65 20 66 69 72 73 74 20 28 70 53 6f  f the first (pSo
d560: 72 74 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 20 73  rter->nTask-1) s
d570: 75 62 2d 74 61 73 6b 73 20 61 72 65 20 61 6c 6c  ub-tasks are all
d580: 20 73 74 69 6c 6c 20 62 75 73 79 2c 0a 20 20 2a   still busy,.  *
d590: 2a 20 66 61 6c 6c 20 62 61 63 6b 20 74 6f 20 75  * fall back to u
d5a0: 73 69 6e 67 20 74 68 65 20 66 69 6e 61 6c 20 73  sing the final s
d5b0: 75 62 2d 74 61 73 6b 2e 20 54 68 65 20 66 69 72  ub-task. The fir
d5c0: 73 74 20 28 70 53 6f 72 74 65 72 2d 3e 6e 54 61  st (pSorter->nTa
d5d0: 73 6b 2d 31 29 0a 20 20 2a 2a 20 73 75 62 2d 74  sk-1).  ** sub-t
d5e0: 61 73 6b 73 20 61 72 65 20 70 72 65 66 65 72 65  asks are prefere
d5f0: 64 20 61 73 20 74 68 65 79 20 75 73 65 20 62 61  d as they use ba
d600: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 73  ckground threads
d610: 20 2d 20 74 68 65 20 66 69 6e 61 6c 20 0a 20 20   - the final .  
d620: 2a 2a 20 73 75 62 2d 74 61 73 6b 20 75 73 65 73  ** sub-task uses
d630: 20 74 68 65 20 6d 61 69 6e 20 74 68 72 65 61 64   the main thread
d640: 2e 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20  . */.  for(i=0; 
d650: 69 3c 6e 57 6f 72 6b 65 72 3b 20 69 2b 2b 29 7b  i<nWorker; i++){
d660: 0a 20 20 20 20 69 6e 74 20 69 54 65 73 74 20 3d  .    int iTest =
d670: 20 28 70 53 6f 72 74 65 72 2d 3e 69 50 72 65 76   (pSorter->iPrev
d680: 20 2b 20 69 20 2b 20 31 29 20 25 20 6e 57 6f 72   + i + 1) % nWor
d690: 6b 65 72 3b 0a 20 20 20 20 70 54 61 73 6b 20 3d  ker;.    pTask =
d6a0: 20 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b   &pSorter->aTask
d6b0: 5b 69 54 65 73 74 5d 3b 0a 20 20 20 20 69 66 28  [iTest];.    if(
d6c0: 20 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 20 29 7b   pTask->bDone ){
d6d0: 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65  .      rc = vdbe
d6e0: 53 6f 72 74 65 72 4a 6f 69 6e 54 68 72 65 61 64  SorterJoinThread
d6f0: 28 70 54 61 73 6b 29 3b 0a 20 20 20 20 7d 0a 20  (pTask);.    }. 
d700: 20 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 70 54     if( pTask->pT
d710: 68 72 65 61 64 3d 3d 30 20 7c 7c 20 72 63 21 3d  hread==0 || rc!=
d720: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61  SQLITE_OK ) brea
d730: 6b 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63  k;.  }..  if( rc
d740: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
d750: 20 20 20 69 66 28 20 69 3d 3d 6e 57 6f 72 6b 65     if( i==nWorke
d760: 72 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 55 73  r ){.      /* Us
d770: 65 20 74 68 65 20 66 6f 72 65 67 72 6f 75 6e 64  e the foreground
d780: 20 74 68 72 65 61 64 20 66 6f 72 20 74 68 69 73   thread for this
d790: 20 6f 70 65 72 61 74 69 6f 6e 20 2a 2f 0a 20 20   operation */.  
d7a0: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
d7b0: 74 65 72 4c 69 73 74 54 6f 50 4d 41 28 26 70 53  terListToPMA(&pS
d7c0: 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 6e 57 6f  orter->aTask[nWo
d7d0: 72 6b 65 72 5d 2c 20 26 70 53 6f 72 74 65 72 2d  rker], &pSorter-
d7e0: 3e 6c 69 73 74 29 3b 0a 20 20 20 20 7d 65 6c 73  >list);.    }els
d7f0: 65 7b 0a 20 20 20 20 20 20 2f 2a 20 4c 61 75 6e  e{.      /* Laun
d800: 63 68 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20  ch a background 
d810: 74 68 72 65 61 64 20 66 6f 72 20 74 68 69 73 20  thread for this 
d820: 6f 70 65 72 61 74 69 6f 6e 20 2a 2f 0a 20 20 20  operation */.   
d830: 20 20 20 75 38 20 2a 61 4d 65 6d 20 3d 20 70 54     u8 *aMem = pT
d840: 61 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72  ask->list.aMemor
d850: 79 3b 0a 20 20 20 20 20 20 76 6f 69 64 20 2a 70  y;.      void *p
d860: 43 74 78 20 3d 20 28 76 6f 69 64 2a 29 70 54 61  Ctx = (void*)pTa
d870: 73 6b 3b 0a 0a 20 20 20 20 20 20 61 73 73 65 72  sk;..      asser
d880: 74 28 20 70 54 61 73 6b 2d 3e 70 54 68 72 65 61  t( pTask->pThrea
d890: 64 3d 3d 30 20 26 26 20 70 54 61 73 6b 2d 3e 62  d==0 && pTask->b
d8a0: 44 6f 6e 65 3d 3d 30 20 29 3b 0a 20 20 20 20 20  Done==0 );.     
d8b0: 20 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e   assert( pTask->
d8c0: 6c 69 73 74 2e 70 4c 69 73 74 3d 3d 30 20 29 3b  list.pList==0 );
d8d0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70  .      assert( p
d8e0: 54 61 73 6b 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f  Task->list.aMemo
d8f0: 72 79 3d 3d 30 20 7c 7c 20 70 53 6f 72 74 65 72  ry==0 || pSorter
d900: 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 21 3d  ->list.aMemory!=
d910: 30 20 29 3b 0a 0a 20 20 20 20 20 20 70 53 6f 72  0 );..      pSor
d920: 74 65 72 2d 3e 69 50 72 65 76 20 3d 20 28 70 54  ter->iPrev = (pT
d930: 61 73 6b 20 2d 20 70 53 6f 72 74 65 72 2d 3e 61  ask - pSorter->a
d940: 54 61 73 6b 29 3b 0a 20 20 20 20 20 20 70 54 61  Task);.      pTa
d950: 73 6b 2d 3e 6c 69 73 74 20 3d 20 70 53 6f 72 74  sk->list = pSort
d960: 65 72 2d 3e 6c 69 73 74 3b 0a 20 20 20 20 20 20  er->list;.      
d970: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c  pSorter->list.pL
d980: 69 73 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 70  ist = 0;.      p
d990: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 73 7a 50  Sorter->list.szP
d9a0: 4d 41 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 66  MA = 0;.      if
d9b0: 28 20 61 4d 65 6d 20 29 7b 0a 20 20 20 20 20 20  ( aMem ){.      
d9c0: 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e    pSorter->list.
d9d0: 61 4d 65 6d 6f 72 79 20 3d 20 61 4d 65 6d 3b 0a  aMemory = aMem;.
d9e0: 20 20 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d          pSorter-
d9f0: 3e 6e 4d 65 6d 6f 72 79 20 3d 20 73 71 6c 69 74  >nMemory = sqlit
da00: 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 61 4d 65  e3MallocSize(aMe
da10: 6d 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20  m);.      }else 
da20: 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73  if( pSorter->lis
da30: 74 2e 61 4d 65 6d 6f 72 79 20 29 7b 0a 20 20 20  t.aMemory ){.   
da40: 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69       pSorter->li
da50: 73 74 2e 61 4d 65 6d 6f 72 79 20 3d 20 73 71 6c  st.aMemory = sql
da60: 69 74 65 33 4d 61 6c 6c 6f 63 28 70 53 6f 72 74  ite3Malloc(pSort
da70: 65 72 2d 3e 6e 4d 65 6d 6f 72 79 29 3b 0a 20 20  er->nMemory);.  
da80: 20 20 20 20 20 20 69 66 28 20 21 70 53 6f 72 74        if( !pSort
da90: 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  er->list.aMemory
daa0: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
dab0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 7d 0a  _NOMEM;.      }.
dac0: 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65  .      rc = vdbe
dad0: 53 6f 72 74 65 72 43 72 65 61 74 65 54 68 72 65  SorterCreateThre
dae0: 61 64 28 70 54 61 73 6b 2c 20 76 64 62 65 53 6f  ad(pTask, vdbeSo
daf0: 72 74 65 72 46 6c 75 73 68 54 68 72 65 61 64 2c  rterFlushThread,
db00: 20 70 43 74 78 29 3b 0a 20 20 20 20 7d 0a 20 20   pCtx);.    }.  
db10: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
db20: 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45  #endif /* SQLITE
db30: 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45  _MAX_WORKER_THRE
db40: 41 44 53 21 3d 30 20 2a 2f 0a 7d 0a 0a 2f 2a 0a  ADS!=0 */.}../*.
db50: 2a 2a 20 41 64 64 20 61 20 72 65 63 6f 72 64 20  ** Add a record 
db60: 74 6f 20 74 68 65 20 73 6f 72 74 65 72 2e 0a 2a  to the sorter..*
db70: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62  /.int sqlite3Vdb
db80: 65 53 6f 72 74 65 72 57 72 69 74 65 28 0a 20 20  eSorterWrite(.  
db90: 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72  const VdbeCursor
dba0: 20 2a 70 43 73 72 2c 20 20 20 20 20 20 20 20 20   *pCsr,         
dbb0: 2f 2a 20 53 6f 72 74 65 72 20 63 75 72 73 6f 72  /* Sorter cursor
dbc0: 20 2a 2f 0a 20 20 4d 65 6d 20 2a 70 56 61 6c 20   */.  Mem *pVal 
dbd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dbe0: 20 20 20 20 20 20 2f 2a 20 4d 65 6d 6f 72 79 20        /* Memory 
dbf0: 63 65 6c 6c 20 63 6f 6e 74 61 69 6e 69 6e 67 20  cell containing 
dc00: 72 65 63 6f 72 64 20 2a 2f 0a 29 7b 0a 20 20 56  record */.){.  V
dc10: 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
dc20: 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74  er = pCsr->pSort
dc30: 65 72 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  er;.  int rc = S
dc40: 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
dc50: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
dc60: 43 6f 64 65 20 2a 2f 0a 20 20 53 6f 72 74 65 72  Code */.  Sorter
dc70: 52 65 63 6f 72 64 20 2a 70 4e 65 77 3b 20 20 20  Record *pNew;   
dc80: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 77            /* New
dc90: 20 6c 69 73 74 20 65 6c 65 6d 65 6e 74 20 2a 2f   list element */
dca0: 0a 0a 20 20 69 6e 74 20 62 46 6c 75 73 68 3b 20  ..  int bFlush; 
dcb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dcc0: 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 66      /* True to f
dcd0: 6c 75 73 68 20 63 6f 6e 74 65 6e 74 73 20 6f 66  lush contents of
dce0: 20 6d 65 6d 6f 72 79 20 74 6f 20 50 4d 41 20 2a   memory to PMA *
dcf0: 2f 0a 20 20 69 6e 74 20 6e 52 65 71 3b 20 20 20  /.  int nReq;   
dd00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dd10: 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20      /* Bytes of 
dd20: 6d 65 6d 6f 72 79 20 72 65 71 75 69 72 65 64 20  memory required 
dd30: 2a 2f 0a 20 20 69 6e 74 20 6e 50 4d 41 3b 20 20  */.  int nPMA;  
dd40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dd50: 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66       /* Bytes of
dd60: 20 50 4d 41 20 73 70 61 63 65 20 72 65 71 75 69   PMA space requi
dd70: 72 65 64 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74  red */..  assert
dd80: 28 20 70 53 6f 72 74 65 72 20 29 3b 0a 0a 20 20  ( pSorter );..  
dd90: 2f 2a 20 46 69 67 75 72 65 20 6f 75 74 20 77 68  /* Figure out wh
dda0: 65 74 68 65 72 20 6f 72 20 6e 6f 74 20 74 68 65  ether or not the
ddb0: 20 63 75 72 72 65 6e 74 20 63 6f 6e 74 65 6e 74   current content
ddc0: 73 20 6f 66 20 6d 65 6d 6f 72 79 20 73 68 6f 75  s of memory shou
ddd0: 6c 64 20 62 65 0a 20 20 2a 2a 20 66 6c 75 73 68  ld be.  ** flush
dde0: 65 64 20 74 6f 20 61 20 50 4d 41 20 62 65 66 6f  ed to a PMA befo
ddf0: 72 65 20 63 6f 6e 74 69 6e 75 69 6e 67 2e 20 49  re continuing. I
de00: 66 20 73 6f 2c 20 64 6f 20 73 6f 2e 0a 20 20 2a  f so, do so..  *
de10: 2a 0a 20 20 2a 2a 20 49 66 20 75 73 69 6e 67 20  *.  ** If using 
de20: 74 68 65 20 73 69 6e 67 6c 65 20 6c 61 72 67 65  the single large
de30: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6d 6f 64 65   allocation mode
de40: 20 28 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f   (pSorter->aMemo
de50: 72 79 21 3d 30 29 2c 20 74 68 65 6e 0a 20 20 2a  ry!=0), then.  *
de60: 2a 20 66 6c 75 73 68 20 74 68 65 20 63 6f 6e 74  * flush the cont
de70: 65 6e 74 73 20 6f 66 20 6d 65 6d 6f 72 79 20 74  ents of memory t
de80: 6f 20 61 20 6e 65 77 20 50 4d 41 20 69 66 20 28  o a new PMA if (
de90: 61 29 20 61 74 20 6c 65 61 73 74 20 6f 6e 65 20  a) at least one 
dea0: 76 61 6c 75 65 20 69 73 0a 20 20 2a 2a 20 61 6c  value is.  ** al
deb0: 72 65 61 64 79 20 69 6e 20 6d 65 6d 6f 72 79 20  ready in memory 
dec0: 61 6e 64 20 28 62 29 20 74 68 65 20 6e 65 77 20  and (b) the new 
ded0: 76 61 6c 75 65 20 77 69 6c 6c 20 6e 6f 74 20 66  value will not f
dee0: 69 74 20 69 6e 20 6d 65 6d 6f 72 79 2e 0a 20 20  it in memory..  
def0: 2a 2a 20 0a 20 20 2a 2a 20 4f 72 2c 20 69 66 20  ** .  ** Or, if 
df00: 75 73 69 6e 67 20 73 65 70 61 72 61 74 65 20 61  using separate a
df10: 6c 6c 6f 63 61 74 69 6f 6e 73 20 66 6f 72 20 65  llocations for e
df20: 61 63 68 20 72 65 63 6f 72 64 2c 20 66 6c 75 73  ach record, flus
df30: 68 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 0a 20  h the contents. 
df40: 20 2a 2a 20 6f 66 20 6d 65 6d 6f 72 79 20 74 6f   ** of memory to
df50: 20 61 20 50 4d 41 20 69 66 20 65 69 74 68 65 72   a PMA if either
df60: 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e   of the followin
df70: 67 20 61 72 65 20 74 72 75 65 3a 0a 20 20 2a 2a  g are true:.  **
df80: 0a 20 20 2a 2a 20 20 20 2a 20 54 68 65 20 74 6f  .  **   * The to
df90: 74 61 6c 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63  tal memory alloc
dfa0: 61 74 65 64 20 66 6f 72 20 74 68 65 20 69 6e 2d  ated for the in-
dfb0: 6d 65 6d 6f 72 79 20 6c 69 73 74 20 69 73 20 67  memory list is g
dfc0: 72 65 61 74 65 72 20 0a 20 20 2a 2a 20 20 20 20  reater .  **    
dfd0: 20 74 68 61 6e 20 28 70 61 67 65 2d 73 69 7a 65   than (page-size
dfe0: 20 2a 20 63 61 63 68 65 2d 73 69 7a 65 29 2c 20   * cache-size), 
dff0: 6f 72 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a  or.  **.  **   *
e000: 20 54 68 65 20 74 6f 74 61 6c 20 6d 65 6d 6f 72   The total memor
e010: 79 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20  y allocated for 
e020: 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69  the in-memory li
e030: 73 74 20 69 73 20 67 72 65 61 74 65 72 20 0a 20  st is greater . 
e040: 20 2a 2a 20 20 20 20 20 74 68 61 6e 20 28 70 61   **     than (pa
e050: 67 65 2d 73 69 7a 65 20 2a 20 31 30 29 20 61 6e  ge-size * 10) an
e060: 64 20 73 71 6c 69 74 65 33 48 65 61 70 4e 65 61  d sqlite3HeapNea
e070: 72 6c 79 46 75 6c 6c 28 29 20 72 65 74 75 72 6e  rlyFull() return
e080: 73 20 74 72 75 65 2e 0a 20 20 2a 2f 0a 20 20 6e  s true..  */.  n
e090: 52 65 71 20 3d 20 70 56 61 6c 2d 3e 6e 20 2b 20  Req = pVal->n + 
e0a0: 73 69 7a 65 6f 66 28 53 6f 72 74 65 72 52 65 63  sizeof(SorterRec
e0b0: 6f 72 64 29 3b 0a 20 20 6e 50 4d 41 20 3d 20 70  ord);.  nPMA = p
e0c0: 56 61 6c 2d 3e 6e 20 2b 20 73 71 6c 69 74 65 33  Val->n + sqlite3
e0d0: 56 61 72 69 6e 74 4c 65 6e 28 70 56 61 6c 2d 3e  VarintLen(pVal->
e0e0: 6e 29 3b 0a 20 20 69 66 28 20 70 53 6f 72 74 65  n);.  if( pSorte
e0f0: 72 2d 3e 6d 78 50 6d 61 53 69 7a 65 20 29 7b 0a  r->mxPmaSize ){.
e100: 20 20 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d      if( pSorter-
e110: 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79 20 29 7b  >list.aMemory ){
e120: 0a 20 20 20 20 20 20 62 46 6c 75 73 68 20 3d 20  .      bFlush = 
e130: 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79  pSorter->iMemory
e140: 20 26 26 20 28 70 53 6f 72 74 65 72 2d 3e 69 4d   && (pSorter->iM
e150: 65 6d 6f 72 79 2b 6e 52 65 71 29 20 3e 20 70 53  emory+nReq) > pS
e160: 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65  orter->mxPmaSize
e170: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
e180: 20 20 20 62 46 6c 75 73 68 20 3d 20 28 0a 20 20     bFlush = (.  
e190: 20 20 20 20 20 20 20 20 28 70 53 6f 72 74 65 72          (pSorter
e1a0: 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41 20 3e 20 70  ->list.szPMA > p
e1b0: 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a  Sorter->mxPmaSiz
e1c0: 65 29 0a 20 20 20 20 20 20 20 7c 7c 20 28 70 53  e).       || (pS
e1d0: 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 73 7a 50 4d  orter->list.szPM
e1e0: 41 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 6e 50  A > pSorter->mnP
e1f0: 6d 61 53 69 7a 65 20 26 26 20 73 71 6c 69 74 65  maSize && sqlite
e200: 33 48 65 61 70 4e 65 61 72 6c 79 46 75 6c 6c 28  3HeapNearlyFull(
e210: 29 29 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20  )).      );.    
e220: 7d 0a 20 20 20 20 69 66 28 20 62 46 6c 75 73 68  }.    if( bFlush
e230: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 76   ){.      rc = v
e240: 64 62 65 53 6f 72 74 65 72 46 6c 75 73 68 50 4d  dbeSorterFlushPM
e250: 41 28 70 53 6f 72 74 65 72 29 3b 0a 20 20 20 20  A(pSorter);.    
e260: 20 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e    pSorter->list.
e270: 73 7a 50 4d 41 20 3d 20 30 3b 0a 20 20 20 20 20  szPMA = 0;.     
e280: 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72   pSorter->iMemor
e290: 79 20 3d 20 30 3b 0a 20 20 20 20 20 20 61 73 73  y = 0;.      ass
e2a0: 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f  ert( rc!=SQLITE_
e2b0: 4f 4b 20 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 6c  OK || pSorter->l
e2c0: 69 73 74 2e 70 4c 69 73 74 3d 3d 30 20 29 3b 0a  ist.pList==0 );.
e2d0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 70 53 6f      }.  }..  pSo
e2e0: 72 74 65 72 2d 3e 6c 69 73 74 2e 73 7a 50 4d 41  rter->list.szPMA
e2f0: 20 2b 3d 20 6e 50 4d 41 3b 0a 20 20 69 66 28 20   += nPMA;.  if( 
e300: 6e 50 4d 41 3e 70 53 6f 72 74 65 72 2d 3e 6d 78  nPMA>pSorter->mx
e310: 4b 65 79 73 69 7a 65 20 29 7b 0a 20 20 20 20 70  Keysize ){.    p
e320: 53 6f 72 74 65 72 2d 3e 6d 78 4b 65 79 73 69 7a  Sorter->mxKeysiz
e330: 65 20 3d 20 6e 50 4d 41 3b 0a 20 20 7d 0a 0a 20  e = nPMA;.  }.. 
e340: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6c 69   if( pSorter->li
e350: 73 74 2e 61 4d 65 6d 6f 72 79 20 29 7b 0a 20 20  st.aMemory ){.  
e360: 20 20 69 6e 74 20 6e 4d 69 6e 20 3d 20 70 53 6f    int nMin = pSo
e370: 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 20 2b 20  rter->iMemory + 
e380: 6e 52 65 71 3b 0a 0a 20 20 20 20 69 66 28 20 6e  nReq;..    if( n
e390: 4d 69 6e 3e 70 53 6f 72 74 65 72 2d 3e 6e 4d 65  Min>pSorter->nMe
e3a0: 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20 20 75 38  mory ){.      u8
e3b0: 20 2a 61 4e 65 77 3b 0a 20 20 20 20 20 20 69 6e   *aNew;.      in
e3c0: 74 20 6e 4e 65 77 20 3d 20 70 53 6f 72 74 65 72  t nNew = pSorter
e3d0: 2d 3e 6e 4d 65 6d 6f 72 79 20 2a 20 32 3b 0a 20  ->nMemory * 2;. 
e3e0: 20 20 20 20 20 77 68 69 6c 65 28 20 6e 4e 65 77       while( nNew
e3f0: 20 3c 20 6e 4d 69 6e 20 29 20 6e 4e 65 77 20 3d   < nMin ) nNew =
e400: 20 6e 4e 65 77 2a 32 3b 0a 20 20 20 20 20 20 69   nNew*2;.      i
e410: 66 28 20 6e 4e 65 77 20 3e 20 70 53 6f 72 74 65  f( nNew > pSorte
e420: 72 2d 3e 6d 78 50 6d 61 53 69 7a 65 20 29 20 6e  r->mxPmaSize ) n
e430: 4e 65 77 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6d  New = pSorter->m
e440: 78 50 6d 61 53 69 7a 65 3b 0a 20 20 20 20 20 20  xPmaSize;.      
e450: 69 66 28 20 6e 4e 65 77 20 3c 20 6e 4d 69 6e 20  if( nNew < nMin 
e460: 29 20 6e 4e 65 77 20 3d 20 6e 4d 69 6e 3b 0a 0a  ) nNew = nMin;..
e470: 20 20 20 20 20 20 61 4e 65 77 20 3d 20 73 71 6c        aNew = sql
e480: 69 74 65 33 52 65 61 6c 6c 6f 63 28 70 53 6f 72  ite3Realloc(pSor
e490: 74 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72  ter->list.aMemor
e4a0: 79 2c 20 6e 4e 65 77 29 3b 0a 20 20 20 20 20 20  y, nNew);.      
e4b0: 69 66 28 20 21 61 4e 65 77 20 29 20 72 65 74 75  if( !aNew ) retu
e4c0: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
e4d0: 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  .      pSorter->
e4e0: 6c 69 73 74 2e 70 4c 69 73 74 20 3d 20 28 53 6f  list.pList = (So
e4f0: 72 74 65 72 52 65 63 6f 72 64 2a 29 28 0a 20 20  rterRecord*)(.  
e500: 20 20 20 20 20 20 20 20 61 4e 65 77 20 2b 20 28          aNew + (
e510: 28 75 38 2a 29 70 53 6f 72 74 65 72 2d 3e 6c 69  (u8*)pSorter->li
e520: 73 74 2e 70 4c 69 73 74 20 2d 20 70 53 6f 72 74  st.pList - pSort
e530: 65 72 2d 3e 6c 69 73 74 2e 61 4d 65 6d 6f 72 79  er->list.aMemory
e540: 29 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20  ).      );.     
e550: 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61   pSorter->list.a
e560: 4d 65 6d 6f 72 79 20 3d 20 61 4e 65 77 3b 0a 20  Memory = aNew;. 
e570: 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6e 4d       pSorter->nM
e580: 65 6d 6f 72 79 20 3d 20 6e 4e 65 77 3b 0a 20 20  emory = nNew;.  
e590: 20 20 7d 0a 0a 20 20 20 20 70 4e 65 77 20 3d 20    }..    pNew = 
e5a0: 28 53 6f 72 74 65 72 52 65 63 6f 72 64 2a 29 26  (SorterRecord*)&
e5b0: 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 61 4d  pSorter->list.aM
e5c0: 65 6d 6f 72 79 5b 70 53 6f 72 74 65 72 2d 3e 69  emory[pSorter->i
e5d0: 4d 65 6d 6f 72 79 5d 3b 0a 20 20 20 20 70 53 6f  Memory];.    pSo
e5e0: 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 20 2b 3d  rter->iMemory +=
e5f0: 20 52 4f 55 4e 44 38 28 6e 52 65 71 29 3b 0a 20   ROUND8(nReq);. 
e600: 20 20 20 70 4e 65 77 2d 3e 75 2e 69 4e 65 78 74     pNew->u.iNext
e610: 20 3d 20 28 69 6e 74 29 28 28 75 38 2a 29 28 70   = (int)((u8*)(p
e620: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69  Sorter->list.pLi
e630: 73 74 29 20 2d 20 70 53 6f 72 74 65 72 2d 3e 6c  st) - pSorter->l
e640: 69 73 74 2e 61 4d 65 6d 6f 72 79 29 3b 0a 20 20  ist.aMemory);.  
e650: 7d 65 6c 73 65 7b 0a 20 20 20 20 70 4e 65 77 20  }else{.    pNew 
e660: 3d 20 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20  = (SorterRecord 
e670: 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28  *)sqlite3Malloc(
e680: 6e 52 65 71 29 3b 0a 20 20 20 20 69 66 28 20 70  nReq);.    if( p
e690: 4e 65 77 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  New==0 ){.      
e6a0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
e6b0: 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  MEM;.    }.    p
e6c0: 4e 65 77 2d 3e 75 2e 70 4e 65 78 74 20 3d 20 70  New->u.pNext = p
e6d0: 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69  Sorter->list.pLi
e6e0: 73 74 3b 0a 20 20 7d 0a 0a 20 20 6d 65 6d 63 70  st;.  }..  memcp
e6f0: 79 28 53 52 56 41 4c 28 70 4e 65 77 29 2c 20 70  y(SRVAL(pNew), p
e700: 56 61 6c 2d 3e 7a 2c 20 70 56 61 6c 2d 3e 6e 29  Val->z, pVal->n)
e710: 3b 0a 20 20 70 4e 65 77 2d 3e 6e 56 61 6c 20 3d  ;.  pNew->nVal =
e720: 20 70 56 61 6c 2d 3e 6e 3b 0a 20 20 70 53 6f 72   pVal->n;.  pSor
e730: 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73 74 20  ter->list.pList 
e740: 3d 20 70 4e 65 77 3b 0a 0a 20 20 72 65 74 75 72  = pNew;..  retur
e750: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  n rc;.}../*.** R
e760: 65 61 64 20 6b 65 79 73 20 66 72 6f 6d 20 70 49  ead keys from pI
e770: 6e 63 72 2d 3e 70 4d 65 72 67 65 72 20 61 6e 64  ncr->pMerger and
e780: 20 70 6f 70 75 6c 61 74 65 20 70 49 6e 63 72 2d   populate pIncr-
e790: 3e 61 46 69 6c 65 5b 31 5d 2e 20 54 68 65 20 66  >aFile[1]. The f
e7a0: 6f 72 6d 61 74 0a 2a 2a 20 6f 66 20 74 68 65 20  ormat.** of the 
e7b0: 64 61 74 61 20 73 74 6f 72 65 64 20 69 6e 20 61  data stored in a
e7c0: 46 69 6c 65 5b 31 5d 20 69 73 20 74 68 65 20 73  File[1] is the s
e7d0: 61 6d 65 20 61 73 20 74 68 61 74 20 75 73 65 64  ame as that used
e7e0: 20 62 79 20 72 65 67 75 6c 61 72 20 50 4d 41 73   by regular PMAs
e7f0: 2c 0a 2a 2a 20 65 78 63 65 70 74 20 74 68 61 74  ,.** except that
e800: 20 74 68 65 20 6e 75 6d 62 65 72 2d 6f 66 2d 62   the number-of-b
e810: 79 74 65 73 20 76 61 72 69 6e 74 20 69 73 20 6f  ytes varint is o
e820: 6d 69 74 74 65 64 20 66 72 6f 6d 20 74 68 65 20  mitted from the 
e830: 73 74 61 72 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  start..*/.static
e840: 20 69 6e 74 20 76 64 62 65 49 6e 63 72 50 6f 70   int vdbeIncrPop
e850: 75 6c 61 74 65 28 49 6e 63 72 4d 65 72 67 65 72  ulate(IncrMerger
e860: 20 2a 70 49 6e 63 72 29 7b 0a 20 20 69 6e 74 20   *pIncr){.  int 
e870: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
e880: 20 20 69 6e 74 20 72 63 32 3b 0a 20 20 69 36 34    int rc2;.  i64
e890: 20 69 53 74 61 72 74 20 3d 20 70 49 6e 63 72 2d   iStart = pIncr-
e8a0: 3e 69 53 74 61 72 74 4f 66 66 3b 0a 20 20 53 6f  >iStartOff;.  So
e8b0: 72 74 65 72 46 69 6c 65 20 2a 70 4f 75 74 20 3d  rterFile *pOut =
e8c0: 20 26 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31   &pIncr->aFile[1
e8d0: 5d 3b 0a 20 20 53 6f 72 74 53 75 62 74 61 73 6b  ];.  SortSubtask
e8e0: 20 2a 70 54 61 73 6b 20 3d 20 70 49 6e 63 72 2d   *pTask = pIncr-
e8f0: 3e 70 54 61 73 6b 3b 0a 20 20 4d 65 72 67 65 45  >pTask;.  MergeE
e900: 6e 67 69 6e 65 20 2a 70 4d 65 72 67 65 72 20 3d  ngine *pMerger =
e910: 20 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65 72 3b   pIncr->pMerger;
e920: 0a 20 20 50 6d 61 57 72 69 74 65 72 20 77 72 69  .  PmaWriter wri
e930: 74 65 72 3b 0a 20 20 61 73 73 65 72 74 28 20 70  ter;.  assert( p
e940: 49 6e 63 72 2d 3e 62 45 6f 66 3d 3d 30 20 29 3b  Incr->bEof==0 );
e950: 0a 0a 20 20 76 64 62 65 53 6f 72 74 65 72 50 6f  ..  vdbeSorterPo
e960: 70 75 6c 61 74 65 44 65 62 75 67 28 70 54 61 73  pulateDebug(pTas
e970: 6b 2c 20 22 65 6e 74 65 72 22 29 3b 0a 0a 20 20  k, "enter");..  
e980: 76 64 62 65 50 6d 61 57 72 69 74 65 72 49 6e 69  vdbePmaWriterIni
e990: 74 28 70 4f 75 74 2d 3e 70 46 64 2c 20 26 77 72  t(pOut->pFd, &wr
e9a0: 69 74 65 72 2c 20 70 54 61 73 6b 2d 3e 70 53 6f  iter, pTask->pSo
e9b0: 72 74 65 72 2d 3e 70 67 73 7a 2c 20 69 53 74 61  rter->pgsz, iSta
e9c0: 72 74 29 3b 0a 20 20 77 68 69 6c 65 28 20 72 63  rt);.  while( rc
e9d0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
e9e0: 20 20 20 69 6e 74 20 64 75 6d 6d 79 3b 0a 20 20     int dummy;.  
e9f0: 20 20 50 6d 61 52 65 61 64 65 72 20 2a 70 52 65    PmaReader *pRe
ea00: 61 64 65 72 20 3d 20 26 70 4d 65 72 67 65 72 2d  ader = &pMerger-
ea10: 3e 61 49 74 65 72 5b 20 70 4d 65 72 67 65 72 2d  >aIter[ pMerger-
ea20: 3e 61 54 72 65 65 5b 31 5d 20 5d 3b 0a 20 20 20  >aTree[1] ];.   
ea30: 20 69 6e 74 20 6e 4b 65 79 20 3d 20 70 52 65 61   int nKey = pRea
ea40: 64 65 72 2d 3e 6e 4b 65 79 3b 0a 20 20 20 20 69  der->nKey;.    i
ea50: 36 34 20 69 45 6f 66 20 3d 20 77 72 69 74 65 72  64 iEof = writer
ea60: 2e 69 57 72 69 74 65 4f 66 66 20 2b 20 77 72 69  .iWriteOff + wri
ea70: 74 65 72 2e 69 42 75 66 45 6e 64 3b 0a 0a 20 20  ter.iBufEnd;..  
ea80: 20 20 2f 2a 20 43 68 65 63 6b 20 69 66 20 74 68    /* Check if th
ea90: 65 20 6f 75 74 70 75 74 20 66 69 6c 65 20 69 73  e output file is
eaa0: 20 66 75 6c 6c 20 6f 72 20 69 66 20 74 68 65 20   full or if the 
eab0: 69 6e 70 75 74 20 68 61 73 20 62 65 65 6e 20 65  input has been e
eac0: 78 68 61 75 73 74 65 64 2e 0a 20 20 20 20 2a 2a  xhausted..    **
ead0: 20 49 6e 20 65 69 74 68 65 72 20 63 61 73 65 20   In either case 
eae0: 65 78 69 74 20 74 68 65 20 6c 6f 6f 70 2e 20 2a  exit the loop. *
eaf0: 2f 0a 20 20 20 20 69 66 28 20 70 52 65 61 64 65  /.    if( pReade
eb00: 72 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 20 62 72  r->pFile==0 ) br
eb10: 65 61 6b 3b 0a 20 20 20 20 69 66 28 20 28 69 45  eak;.    if( (iE
eb20: 6f 66 20 2b 20 6e 4b 65 79 20 2b 20 73 71 6c 69  of + nKey + sqli
eb30: 74 65 33 56 61 72 69 6e 74 4c 65 6e 28 6e 4b 65  te3VarintLen(nKe
eb40: 79 29 29 3e 28 69 53 74 61 72 74 20 2b 20 70 49  y))>(iStart + pI
eb50: 6e 63 72 2d 3e 6d 78 53 7a 29 20 29 20 62 72 65  ncr->mxSz) ) bre
eb60: 61 6b 3b 0a 0a 20 20 20 20 2f 2a 20 57 72 69 74  ak;..    /* Writ
eb70: 65 20 74 68 65 20 6e 65 78 74 20 6b 65 79 20 74  e the next key t
eb80: 6f 20 74 68 65 20 6f 75 74 70 75 74 2e 20 2a 2f  o the output. */
eb90: 0a 20 20 20 20 76 64 62 65 50 6d 61 57 72 69 74  .    vdbePmaWrit
eba0: 65 56 61 72 69 6e 74 28 26 77 72 69 74 65 72 2c  eVarint(&writer,
ebb0: 20 6e 4b 65 79 29 3b 0a 20 20 20 20 76 64 62 65   nKey);.    vdbe
ebc0: 50 6d 61 57 72 69 74 65 42 6c 6f 62 28 26 77 72  PmaWriteBlob(&wr
ebd0: 69 74 65 72 2c 20 70 52 65 61 64 65 72 2d 3e 61  iter, pReader->a
ebe0: 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 20 20 20 20  Key, nKey);.    
ebf0: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4e  rc = vdbeSorterN
ec00: 65 78 74 28 70 54 61 73 6b 2c 20 70 49 6e 63 72  ext(pTask, pIncr
ec10: 2d 3e 70 4d 65 72 67 65 72 2c 20 26 64 75 6d 6d  ->pMerger, &dumm
ec20: 79 29 3b 0a 20 20 7d 0a 0a 20 20 72 63 32 20 3d  y);.  }..  rc2 =
ec30: 20 76 64 62 65 50 6d 61 57 72 69 74 65 72 46 69   vdbePmaWriterFi
ec40: 6e 69 73 68 28 26 77 72 69 74 65 72 2c 20 26 70  nish(&writer, &p
ec50: 4f 75 74 2d 3e 69 45 6f 66 29 3b 0a 20 20 69 66  Out->iEof);.  if
ec60: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
ec70: 29 20 72 63 20 3d 20 72 63 32 3b 0a 20 20 76 64  ) rc = rc2;.  vd
ec80: 62 65 53 6f 72 74 65 72 50 6f 70 75 6c 61 74 65  beSorterPopulate
ec90: 44 65 62 75 67 28 70 54 61 73 6b 2c 20 22 65 78  Debug(pTask, "ex
eca0: 69 74 22 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  it");.  return r
ecb0: 63 3b 0a 7d 0a 0a 23 69 66 20 53 51 4c 49 54 45  c;.}..#if SQLITE
ecc0: 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45  _MAX_WORKER_THRE
ecd0: 41 44 53 3e 30 0a 2f 2a 0a 2a 2a 20 54 68 65 20  ADS>0./*.** The 
ece0: 6d 61 69 6e 20 72 6f 75 74 69 6e 65 20 66 6f 72  main routine for
ecf0: 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65   background thre
ed00: 61 64 73 20 74 68 61 74 20 70 6f 70 75 6c 61 74  ads that populat
ed10: 65 20 61 46 69 6c 65 5b 31 5d 20 6f 66 0a 2a 2a  e aFile[1] of.**
ed20: 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20   multi-threaded 
ed30: 49 6e 63 72 4d 65 72 67 65 72 20 6f 62 6a 65 63  IncrMerger objec
ed40: 74 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ts..*/.static vo
ed50: 69 64 20 2a 76 64 62 65 49 6e 63 72 50 6f 70 75  id *vdbeIncrPopu
ed60: 6c 61 74 65 54 68 72 65 61 64 28 76 6f 69 64 20  lateThread(void 
ed70: 2a 70 43 74 78 29 7b 0a 20 20 49 6e 63 72 4d 65  *pCtx){.  IncrMe
ed80: 72 67 65 72 20 2a 70 49 6e 63 72 20 3d 20 28 49  rger *pIncr = (I
ed90: 6e 63 72 4d 65 72 67 65 72 2a 29 70 43 74 78 3b  ncrMerger*)pCtx;
eda0: 0a 20 20 76 6f 69 64 20 2a 70 52 65 74 20 3d 20  .  void *pRet = 
edb0: 53 51 4c 49 54 45 5f 49 4e 54 5f 54 4f 5f 50 54  SQLITE_INT_TO_PT
edc0: 52 28 20 76 64 62 65 49 6e 63 72 50 6f 70 75 6c  R( vdbeIncrPopul
edd0: 61 74 65 28 70 49 6e 63 72 29 20 29 3b 0a 20 20  ate(pIncr) );.  
ede0: 70 49 6e 63 72 2d 3e 70 54 61 73 6b 2d 3e 62 44  pIncr->pTask->bD
edf0: 6f 6e 65 20 3d 20 31 3b 0a 20 20 72 65 74 75 72  one = 1;.  retur
ee00: 6e 20 70 52 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  n pRet;.}../*.**
ee10: 20 4c 61 75 6e 63 68 20 61 20 62 61 63 6b 67 72   Launch a backgr
ee20: 6f 75 6e 64 20 74 68 72 65 61 64 20 74 6f 20 70  ound thread to p
ee30: 6f 70 75 6c 61 74 65 20 61 46 69 6c 65 5b 31 5d  opulate aFile[1]
ee40: 20 6f 66 20 70 49 6e 63 72 2e 0a 2a 2f 0a 73 74   of pIncr..*/.st
ee50: 61 74 69 63 20 69 6e 74 20 76 64 62 65 49 6e 63  atic int vdbeInc
ee60: 72 42 67 50 6f 70 75 6c 61 74 65 28 49 6e 63 72  rBgPopulate(Incr
ee70: 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 29 7b 0a  Merger *pIncr){.
ee80: 20 20 76 6f 69 64 20 2a 70 20 3d 20 28 76 6f 69    void *p = (voi
ee90: 64 2a 29 70 49 6e 63 72 3b 0a 20 20 61 73 73 65  d*)pIncr;.  asse
eea0: 72 74 28 20 70 49 6e 63 72 2d 3e 62 55 73 65 54  rt( pIncr->bUseT
eeb0: 68 72 65 61 64 20 29 3b 0a 20 20 72 65 74 75 72  hread );.  retur
eec0: 6e 20 76 64 62 65 53 6f 72 74 65 72 43 72 65 61  n vdbeSorterCrea
eed0: 74 65 54 68 72 65 61 64 28 70 49 6e 63 72 2d 3e  teThread(pIncr->
eee0: 70 54 61 73 6b 2c 20 76 64 62 65 49 6e 63 72 50  pTask, vdbeIncrP
eef0: 6f 70 75 6c 61 74 65 54 68 72 65 61 64 2c 20 70  opulateThread, p
ef00: 29 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a  );.}.#endif../*.
ef10: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
ef20: 20 69 73 20 63 61 6c 6c 65 64 20 77 68 65 6e 20   is called when 
ef30: 74 68 65 20 50 6d 61 52 65 61 64 65 72 20 63 6f  the PmaReader co
ef40: 72 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20 70  rresponding to p
ef50: 49 6e 63 72 20 68 61 73 0a 2a 2a 20 66 69 6e 69  Incr has.** fini
ef60: 73 68 65 64 20 72 65 61 64 69 6e 67 20 74 68 65  shed reading the
ef70: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61 46 69   contents of aFi
ef80: 6c 65 5b 30 5d 2e 20 49 74 73 20 70 75 72 70 6f  le[0]. Its purpo
ef90: 73 65 20 69 73 20 74 6f 20 22 72 65 66 69 6c 6c  se is to "refill
efa0: 22 0a 2a 2a 20 61 46 69 6c 65 5b 30 5d 20 73 75  ".** aFile[0] su
efb0: 63 68 20 74 68 61 74 20 74 68 65 20 69 74 65 72  ch that the iter
efc0: 61 74 6f 72 20 73 68 6f 75 6c 64 20 73 74 61 72  ator should star
efd0: 74 20 72 65 72 65 61 64 69 6e 67 20 69 74 20 66  t rereading it f
efe0: 72 6f 6d 20 74 68 65 0a 2a 2a 20 62 65 67 69 6e  rom the.** begin
eff0: 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 20  ning..**.** For 
f000: 73 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64 20  single-threaded 
f010: 6f 62 6a 65 63 74 73 2c 20 74 68 69 73 20 69 73  objects, this is
f020: 20 61 63 63 6f 6d 70 6c 69 73 68 65 64 20 62 79   accomplished by
f030: 20 6c 69 74 65 72 61 6c 6c 79 20 72 65 61 64 69   literally readi
f040: 6e 67 20 0a 2a 2a 20 6b 65 79 73 20 66 72 6f 6d  ng .** keys from
f050: 20 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65 72 20   pIncr->pMerger 
f060: 61 6e 64 20 72 65 70 6f 70 75 6c 61 74 69 6e 67  and repopulating
f070: 20 61 46 69 6c 65 5b 30 5d 2e 20 0a 2a 2a 0a 2a   aFile[0]. .**.*
f080: 2a 20 46 6f 72 20 6d 75 6c 74 69 2d 74 68 72 65  * For multi-thre
f090: 61 64 65 64 20 6f 62 6a 65 63 74 73 2c 20 61 6c  aded objects, al
f0a0: 6c 20 74 68 61 74 20 69 73 20 72 65 71 75 69 72  l that is requir
f0b0: 65 64 20 69 73 20 74 6f 20 77 61 69 74 20 75 6e  ed is to wait un
f0c0: 74 69 6c 20 74 68 65 20 0a 2a 2a 20 62 61 63 6b  til the .** back
f0d0: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20 69 73  ground thread is
f0e0: 20 66 69 6e 69 73 68 65 64 20 28 69 66 20 69 74   finished (if it
f0f0: 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 29   is not already)
f100: 20 61 6e 64 20 74 68 65 6e 20 73 77 61 70 20 0a   and then swap .
f110: 2a 2a 20 61 46 69 6c 65 5b 30 5d 20 61 6e 64 20  ** aFile[0] and 
f120: 61 46 69 6c 65 5b 31 5d 20 69 6e 20 70 6c 61 63  aFile[1] in plac
f130: 65 2e 20 49 66 20 74 68 65 20 63 6f 6e 74 65 6e  e. If the conten
f140: 74 73 20 6f 66 20 70 4d 65 72 67 65 72 20 68 61  ts of pMerger ha
f150: 76 65 20 6e 6f 74 0a 2a 2a 20 62 65 65 6e 20 65  ve not.** been e
f160: 78 68 61 75 73 74 65 64 2c 20 74 68 69 73 20 66  xhausted, this f
f170: 75 6e 63 74 69 6f 6e 20 61 6c 73 6f 20 6c 61 75  unction also lau
f180: 6e 63 68 65 73 20 61 20 6e 65 77 20 62 61 63 6b  nches a new back
f190: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 0a 2a 2a  ground thread.**
f1a0: 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 74 68 65   to populate the
f1b0: 20 6e 65 77 20 61 46 69 6c 65 5b 31 5d 2e 0a 2a   new aFile[1]..*
f1c0: 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69  *.** SQLITE_OK i
f1d0: 73 20 72 65 74 75 72 6e 65 64 20 6f 6e 20 73 75  s returned on su
f1e0: 63 63 65 73 73 2c 20 6f 72 20 61 6e 20 53 51 4c  ccess, or an SQL
f1f0: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 6f  ite error code o
f200: 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61  therwise..*/.sta
f210: 74 69 63 20 69 6e 74 20 76 64 62 65 49 6e 63 72  tic int vdbeIncr
f220: 53 77 61 70 28 49 6e 63 72 4d 65 72 67 65 72 20  Swap(IncrMerger 
f230: 2a 70 49 6e 63 72 29 7b 0a 20 20 69 6e 74 20 72  *pIncr){.  int r
f240: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a  c = SQLITE_OK;..
f250: 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f 57  #if SQLITE_MAX_W
f260: 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30 0a  ORKER_THREADS>0.
f270: 20 20 69 66 28 20 70 49 6e 63 72 2d 3e 62 55 73    if( pIncr->bUs
f280: 65 54 68 72 65 61 64 20 29 7b 0a 20 20 20 20 72  eThread ){.    r
f290: 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4a 6f  c = vdbeSorterJo
f2a0: 69 6e 54 68 72 65 61 64 28 70 49 6e 63 72 2d 3e  inThread(pIncr->
f2b0: 70 54 61 73 6b 29 3b 0a 0a 20 20 20 20 69 66 28  pTask);..    if(
f2c0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
f2d0: 7b 0a 20 20 20 20 20 20 53 6f 72 74 65 72 46 69  {.      SorterFi
f2e0: 6c 65 20 66 30 20 3d 20 70 49 6e 63 72 2d 3e 61  le f0 = pIncr->a
f2f0: 46 69 6c 65 5b 30 5d 3b 0a 20 20 20 20 20 20 70  File[0];.      p
f300: 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30 5d 20 3d  Incr->aFile[0] =
f310: 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 31 5d   pIncr->aFile[1]
f320: 3b 0a 20 20 20 20 20 20 70 49 6e 63 72 2d 3e 61  ;.      pIncr->a
f330: 46 69 6c 65 5b 31 5d 20 3d 20 66 30 3b 0a 20 20  File[1] = f0;.  
f340: 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72 63 3d    }..    if( rc=
f350: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
f360: 20 20 20 20 69 66 28 20 70 49 6e 63 72 2d 3e 61      if( pIncr->a
f370: 46 69 6c 65 5b 30 5d 2e 69 45 6f 66 3d 3d 70 49  File[0].iEof==pI
f380: 6e 63 72 2d 3e 69 53 74 61 72 74 4f 66 66 20 29  ncr->iStartOff )
f390: 7b 0a 20 20 20 20 20 20 20 20 70 49 6e 63 72 2d  {.        pIncr-
f3a0: 3e 62 45 6f 66 20 3d 20 31 3b 0a 20 20 20 20 20  >bEof = 1;.     
f3b0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
f3c0: 72 63 20 3d 20 76 64 62 65 49 6e 63 72 42 67 50  rc = vdbeIncrBgP
f3d0: 6f 70 75 6c 61 74 65 28 70 49 6e 63 72 29 3b 0a  opulate(pIncr);.
f3e0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
f3f0: 7d 65 6c 73 65 0a 23 65 6e 64 69 66 0a 20 20 7b  }else.#endif.  {
f400: 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e  .    rc = vdbeIn
f410: 63 72 50 6f 70 75 6c 61 74 65 28 70 49 6e 63 72  crPopulate(pIncr
f420: 29 3b 0a 20 20 20 20 70 49 6e 63 72 2d 3e 61 46  );.    pIncr->aF
f430: 69 6c 65 5b 30 5d 20 3d 20 70 49 6e 63 72 2d 3e  ile[0] = pIncr->
f440: 61 46 69 6c 65 5b 31 5d 3b 0a 20 20 20 20 69 66  aFile[1];.    if
f450: 28 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b 30  ( pIncr->aFile[0
f460: 5d 2e 69 45 6f 66 3d 3d 70 49 6e 63 72 2d 3e 69  ].iEof==pIncr->i
f470: 53 74 61 72 74 4f 66 66 20 29 7b 0a 20 20 20 20  StartOff ){.    
f480: 20 20 70 49 6e 63 72 2d 3e 62 45 6f 66 20 3d 20    pIncr->bEof = 
f490: 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  1;.    }.  }..  
f4a0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
f4b0: 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61 6e 64  .** Allocate and
f4c0: 20 72 65 74 75 72 6e 20 61 20 6e 65 77 20 49 6e   return a new In
f4d0: 63 72 4d 65 72 67 65 72 20 6f 62 6a 65 63 74 20  crMerger object 
f4e0: 74 6f 20 72 65 61 64 20 64 61 74 61 20 66 72 6f  to read data fro
f4f0: 6d 20 70 4d 65 72 67 65 72 2e 0a 2a 2a 0a 2a 2a  m pMerger..**.**
f500: 20 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69   If an OOM condi
f510: 74 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e 74 65  tion is encounte
f520: 72 65 64 2c 20 72 65 74 75 72 6e 20 4e 55 4c 4c  red, return NULL
f530: 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65 20 66  . In this case f
f540: 72 65 65 20 74 68 65 0a 2a 2a 20 70 4d 65 72 67  ree the.** pMerg
f550: 65 72 20 61 72 67 75 6d 65 6e 74 20 62 65 66 6f  er argument befo
f560: 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2f  re returning..*/
f570: 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65  .static int vdbe
f580: 49 6e 63 72 4e 65 77 28 0a 20 20 53 6f 72 74 53  IncrNew(.  SortS
f590: 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 2c 20 0a  ubtask *pTask, .
f5a0: 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70    MergeEngine *p
f5b0: 4d 65 72 67 65 72 2c 0a 20 20 49 6e 63 72 4d 65  Merger,.  IncrMe
f5c0: 72 67 65 72 20 2a 2a 70 70 4f 75 74 0a 29 7b 0a  rger **ppOut.){.
f5d0: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
f5e0: 45 5f 4f 4b 3b 0a 20 20 49 6e 63 72 4d 65 72 67  E_OK;.  IncrMerg
f5f0: 65 72 20 2a 70 49 6e 63 72 20 3d 20 2a 70 70 4f  er *pIncr = *ppO
f600: 75 74 20 3d 20 28 49 6e 63 72 4d 65 72 67 65 72  ut = (IncrMerger
f610: 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  *)sqlite3_malloc
f620: 28 73 69 7a 65 6f 66 28 49 6e 63 72 4d 65 72 67  (sizeof(IncrMerg
f630: 65 72 29 29 3b 0a 20 20 69 66 28 20 70 49 6e 63  er));.  if( pInc
f640: 72 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28  r ){.    memset(
f650: 70 49 6e 63 72 2c 20 30 2c 20 73 69 7a 65 6f 66  pIncr, 0, sizeof
f660: 28 49 6e 63 72 4d 65 72 67 65 72 29 29 3b 0a 20  (IncrMerger));. 
f670: 20 20 20 70 49 6e 63 72 2d 3e 70 4d 65 72 67 65     pIncr->pMerge
f680: 72 20 3d 20 70 4d 65 72 67 65 72 3b 0a 20 20 20  r = pMerger;.   
f690: 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b 20 3d 20   pIncr->pTask = 
f6a0: 70 54 61 73 6b 3b 0a 20 20 20 20 70 49 6e 63 72  pTask;.    pIncr
f6b0: 2d 3e 6d 78 53 7a 20 3d 20 4d 41 58 28 70 54 61  ->mxSz = MAX(pTa
f6c0: 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e 6d 78 4b  sk->pSorter->mxK
f6d0: 65 79 73 69 7a 65 2b 39 2c 70 54 61 73 6b 2d 3e  eysize+9,pTask->
f6e0: 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69  pSorter->mxPmaSi
f6f0: 7a 65 2f 32 29 3b 0a 20 20 20 20 70 54 61 73 6b  ze/2);.    pTask
f700: 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 20 2b 3d 20  ->file2.iEof += 
f710: 70 49 6e 63 72 2d 3e 6d 78 53 7a 3b 0a 20 20 7d  pIncr->mxSz;.  }
f720: 65 6c 73 65 7b 0a 20 20 20 20 76 64 62 65 4d 65  else{.    vdbeMe
f730: 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28 70 4d  rgeEngineFree(pM
f740: 65 72 67 65 72 29 3b 0a 20 20 20 20 72 63 20 3d  erger);.    rc =
f750: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
f760: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
f770: 7d 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41  }..#if SQLITE_MA
f780: 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53  X_WORKER_THREADS
f790: 3e 30 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65  >0./*.** Set the
f7a0: 20 22 75 73 65 2d 74 68 72 65 61 64 73 22 20 66   "use-threads" f
f7b0: 6c 61 67 20 6f 6e 20 6f 62 6a 65 63 74 20 70 49  lag on object pI
f7c0: 6e 63 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ncr..*/.static v
f7d0: 6f 69 64 20 76 64 62 65 49 6e 63 72 53 65 74 54  oid vdbeIncrSetT
f7e0: 68 72 65 61 64 73 28 49 6e 63 72 4d 65 72 67 65  hreads(IncrMerge
f7f0: 72 20 2a 70 49 6e 63 72 2c 20 69 6e 74 20 62 55  r *pIncr, int bU
f800: 73 65 54 68 72 65 61 64 29 7b 0a 20 20 69 66 28  seThread){.  if(
f810: 20 62 55 73 65 54 68 72 65 61 64 20 29 7b 0a 20   bUseThread ){. 
f820: 20 20 20 70 49 6e 63 72 2d 3e 62 55 73 65 54 68     pIncr->bUseTh
f830: 72 65 61 64 20 3d 20 31 3b 0a 20 20 20 20 70 49  read = 1;.    pI
f840: 6e 63 72 2d 3e 70 54 61 73 6b 2d 3e 66 69 6c 65  ncr->pTask->file
f850: 32 2e 69 45 6f 66 20 2d 3d 20 70 49 6e 63 72 2d  2.iEof -= pIncr-
f860: 3e 6d 78 53 7a 3b 0a 20 20 7d 0a 7d 0a 23 65 6e  >mxSz;.  }.}.#en
f870: 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 4d 41  dif /* SQLITE_MA
f880: 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53  X_WORKER_THREADS
f890: 3e 30 20 2a 2f 0a 0a 23 64 65 66 69 6e 65 20 49  >0 */..#define I
f8a0: 4e 43 52 49 4e 49 54 5f 4e 4f 52 4d 41 4c 20 30  NCRINIT_NORMAL 0
f8b0: 0a 23 64 65 66 69 6e 65 20 49 4e 43 52 49 4e 49  .#define INCRINI
f8c0: 54 5f 54 41 53 4b 20 20 20 31 0a 23 64 65 66 69  T_TASK   1.#defi
f8d0: 6e 65 20 49 4e 43 52 49 4e 49 54 5f 52 4f 4f 54  ne INCRINIT_ROOT
f8e0: 20 20 20 32 0a 73 74 61 74 69 63 20 69 6e 74 20     2.static int 
f8f0: 76 64 62 65 50 6d 61 52 65 61 64 65 72 49 6e 63  vdbePmaReaderInc
f900: 72 49 6e 69 74 28 50 6d 61 52 65 61 64 65 72 20  rInit(PmaReader 
f910: 2a 70 49 74 65 72 2c 20 69 6e 74 20 65 4d 6f 64  *pIter, int eMod
f920: 65 29 3b 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69  e);../*.** Initi
f930: 61 6c 69 7a 65 20 74 68 65 20 6d 65 72 67 65 72  alize the merger
f940: 20 61 72 67 75 6d 65 6e 74 20 70 61 73 73 65 64   argument passed
f950: 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61   as the second a
f960: 72 67 75 6d 65 6e 74 2e 20 4f 6e 63 65 20 74 68  rgument. Once th
f970: 69 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 72  is.** function r
f980: 65 74 75 72 6e 73 2c 20 74 68 65 20 66 69 72 73  eturns, the firs
f990: 74 20 6b 65 79 20 6f 66 20 6d 65 72 67 65 64 20  t key of merged 
f9a0: 64 61 74 61 20 6d 61 79 20 62 65 20 72 65 61 64  data may be read
f9b0: 20 66 72 6f 6d 20 74 68 65 20 6d 65 72 67 65 72   from the merger
f9c0: 0a 2a 2a 20 6f 62 6a 65 63 74 20 69 6e 20 74 68  .** object in th
f9d0: 65 20 75 73 75 61 6c 20 66 61 73 68 69 6f 6e 2e  e usual fashion.
f9e0: 0a 2a 2a 0a 2a 2a 20 49 66 20 61 72 67 75 6d 65  .**.** If argume
f9f0: 6e 74 20 65 4d 6f 64 65 20 69 73 20 49 4e 43 52  nt eMode is INCR
fa00: 49 4e 49 54 5f 52 4f 4f 54 2c 20 74 68 65 6e 20  INIT_ROOT, then 
fa10: 69 74 20 69 73 20 61 73 73 75 6d 65 64 20 74 68  it is assumed th
fa20: 61 74 20 61 6e 79 20 49 6e 63 72 4d 65 72 67 65  at any IncrMerge
fa30: 0a 2a 2a 20 6f 62 6a 65 63 74 73 20 61 74 74 61  .** objects atta
fa40: 63 68 65 64 20 74 6f 20 74 68 65 20 50 6d 61 52  ched to the PmaR
fa50: 65 61 64 65 72 20 6f 62 6a 65 63 74 73 20 74 68  eader objects th
fa60: 61 74 20 74 68 65 20 6d 65 72 67 65 72 20 72 65  at the merger re
fa70: 61 64 73 20 66 72 6f 6d 20 68 61 76 65 0a 2a 2a  ads from have.**
fa80: 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 70 6f   already been po
fa90: 70 75 6c 61 74 65 64 2c 20 62 75 74 20 74 68 61  pulated, but tha
faa0: 74 20 74 68 65 79 20 68 61 76 65 20 6e 6f 74 20  t they have not 
fab0: 79 65 74 20 70 6f 70 75 6c 61 74 65 64 20 61 46  yet populated aF
fac0: 69 6c 65 5b 30 5d 20 61 6e 64 0a 2a 2a 20 73 65  ile[0] and.** se
fad0: 74 20 74 68 65 20 50 6d 61 52 65 61 64 65 72 20  t the PmaReader 
fae0: 6f 62 6a 65 63 74 73 20 75 70 20 74 6f 20 72 65  objects up to re
faf0: 61 64 20 66 72 6f 6d 20 69 74 2e 20 49 6e 20 74  ad from it. In t
fb00: 68 69 73 20 63 61 73 65 20 61 6c 6c 20 74 68 61  his case all tha
fb10: 74 20 69 73 0a 2a 2a 20 72 65 71 75 69 72 65 64  t is.** required
fb20: 20 69 73 20 74 6f 20 63 61 6c 6c 20 76 64 62 65   is to call vdbe
fb30: 50 6d 61 52 65 61 64 65 72 4e 65 78 74 28 29 20  PmaReaderNext() 
fb40: 6f 6e 20 65 61 63 68 20 69 74 65 72 61 74 6f 72  on each iterator
fb50: 20 74 6f 20 70 6f 69 6e 74 20 69 74 20 61 74 0a   to point it at.
fb60: 2a 2a 20 69 74 73 20 66 69 72 73 74 20 6b 65 79  ** its first key
fb70: 2e 0a 2a 2a 0a 2a 2a 20 4f 74 68 65 72 77 69 73  ..**.** Otherwis
fb80: 65 2c 20 69 66 20 65 4d 6f 64 65 20 69 73 20 61  e, if eMode is a
fb90: 6e 79 20 76 61 6c 75 65 20 6f 74 68 65 72 20 74  ny value other t
fba0: 68 61 6e 20 49 4e 43 52 49 4e 49 54 5f 52 4f 4f  han INCRINIT_ROO
fbb0: 54 2c 20 74 68 65 6e 20 75 73 65 20 0a 2a 2a 20  T, then use .** 
fbc0: 76 64 62 65 50 6d 61 52 65 61 64 65 72 49 6e 63  vdbePmaReaderInc
fbd0: 72 49 6e 69 74 28 29 20 74 6f 20 69 6e 69 74 69  rInit() to initi
fbe0: 61 6c 69 7a 65 20 65 61 63 68 20 50 6d 61 52 65  alize each PmaRe
fbf0: 61 64 65 72 20 74 68 61 74 20 66 65 65 64 73 20  ader that feeds 
fc00: 64 61 74 61 20 0a 2a 2a 20 74 6f 20 70 4d 65 72  data .** to pMer
fc10: 67 65 72 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54  ger..**.** SQLIT
fc20: 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64  E_OK is returned
fc30: 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   if successful, 
fc40: 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  or an SQLite err
fc50: 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77 69 73  or code otherwis
fc60: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
fc70: 20 76 64 62 65 49 6e 63 72 49 6e 69 74 4d 65 72   vdbeIncrInitMer
fc80: 67 65 72 28 0a 20 20 53 6f 72 74 53 75 62 74 61  ger(.  SortSubta
fc90: 73 6b 20 2a 70 54 61 73 6b 2c 20 0a 20 20 4d 65  sk *pTask, .  Me
fca0: 72 67 65 45 6e 67 69 6e 65 20 2a 70 4d 65 72 67  rgeEngine *pMerg
fcb0: 65 72 2c 20 0a 20 20 69 6e 74 20 65 4d 6f 64 65  er, .  int eMode
fcc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fcd0: 20 20 20 20 20 20 20 2f 2a 20 4f 6e 65 20 6f 66         /* One of
fce0: 20 74 68 65 20 49 4e 43 52 49 4e 49 54 5f 58 58   the INCRINIT_XX
fcf0: 58 20 63 6f 6e 73 74 61 6e 74 73 20 2a 2f 0a 29  X constants */.)
fd00: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
fd10: 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20  ITE_OK;         
fd20: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f      /* Return co
fd30: 64 65 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20  de */.  int i;  
fd40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fd50: 20 20 20 20 20 20 20 20 2f 2a 20 46 6f 72 20 69          /* For i
fd60: 74 65 72 61 74 69 6e 67 20 74 68 72 6f 75 67 68  terating through
fd70: 20 50 6d 61 52 65 61 64 65 72 20 6f 62 6a 65 63   PmaReader objec
fd80: 74 73 20 2a 2f 0a 0a 20 20 66 6f 72 28 69 3d 30  ts */..  for(i=0
fd90: 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ; rc==SQLITE_OK 
fda0: 26 26 20 69 3c 70 4d 65 72 67 65 72 2d 3e 6e 54  && i<pMerger->nT
fdb0: 72 65 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69  ree; i++){.    i
fdc0: 66 28 20 65 4d 6f 64 65 3d 3d 49 4e 43 52 49 4e  f( eMode==INCRIN
fdd0: 49 54 5f 52 4f 4f 54 20 29 7b 0a 20 20 20 20 20  IT_ROOT ){.     
fde0: 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61   rc = vdbePmaRea
fdf0: 64 65 72 4e 65 78 74 28 26 70 4d 65 72 67 65 72  derNext(&pMerger
fe00: 2d 3e 61 49 74 65 72 5b 69 5d 29 3b 0a 20 20 20  ->aIter[i]);.   
fe10: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63   }else{.      rc
fe20: 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65 72   = vdbePmaReader
fe30: 49 6e 63 72 49 6e 69 74 28 26 70 4d 65 72 67 65  IncrInit(&pMerge
fe40: 72 2d 3e 61 49 74 65 72 5b 69 5d 2c 20 49 4e 43  r->aIter[i], INC
fe50: 52 49 4e 49 54 5f 4e 4f 52 4d 41 4c 29 3b 0a 20  RINIT_NORMAL);. 
fe60: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 66 6f 72 28     }.  }..  for(
fe70: 69 3d 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65  i=pMerger->nTree
fe80: 2d 31 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  -1; rc==SQLITE_O
fe90: 4b 20 26 26 20 69 3e 30 3b 20 69 2d 2d 29 7b 0a  K && i>0; i--){.
fea0: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
feb0: 74 65 72 44 6f 43 6f 6d 70 61 72 65 28 70 54 61  terDoCompare(pTa
fec0: 73 6b 2c 20 70 4d 65 72 67 65 72 2c 20 69 29 3b  sk, pMerger, i);
fed0: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
fee0: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74  c;.}../*.** If t
fef0: 68 65 20 50 6d 61 52 65 61 64 65 72 20 70 61 73  he PmaReader pas
ff00: 73 65 64 20 61 73 20 74 68 65 20 66 69 72 73 74  sed as the first
ff10: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 6e 6f 74   argument is not
ff20: 20 61 6e 20 69 6e 63 72 65 6d 65 6e 74 61 6c 2d   an incremental-
ff30: 72 65 61 64 65 72 0a 2a 2a 20 28 69 66 20 70 49  reader.** (if pI
ff40: 74 65 72 2d 3e 70 49 6e 63 72 3d 3d 30 29 2c 20  ter->pIncr==0), 
ff50: 74 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69  then this functi
ff60: 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 20 4f  on is a no-op. O
ff70: 74 68 65 72 77 69 73 65 2c 20 69 74 20 73 65 72  therwise, it ser
ff80: 76 65 73 0a 2a 2a 20 74 6f 20 6f 70 65 6e 20 61  ves.** to open a
ff90: 6e 64 2f 6f 72 20 69 6e 69 74 69 61 6c 69 7a 65  nd/or initialize
ffa0: 20 74 68 65 20 74 65 6d 70 20 66 69 6c 65 20 72   the temp file r
ffb0: 65 6c 61 74 65 64 20 66 69 65 6c 64 73 20 6f 66  elated fields of
ffc0: 20 74 68 65 20 49 6e 63 72 4d 65 72 67 65 0a 2a   the IncrMerge.*
ffd0: 2a 20 6f 62 6a 65 63 74 20 61 74 20 28 70 49 74  * object at (pIt
ffe0: 65 72 2d 3e 70 49 6e 63 72 29 2e 0a 2a 2a 0a 2a  er->pIncr)..**.*
fff0: 2a 20 49 66 20 61 72 67 75 6d 65 6e 74 20 65 4d  * If argument eM
10000 6f 64 65 20 69 73 20 73 65 74 20 74 6f 20 49 4e  ode is set to IN
10010 43 52 49 4e 49 54 5f 4e 4f 52 4d 41 4c 2c 20 74  CRINIT_NORMAL, t
10020 68 65 6e 20 50 6d 61 52 65 61 64 65 72 20 69 74  hen PmaReader it
10030 65 72 61 74 6f 72 73 0a 2a 2a 20 69 6e 20 74 68  erators.** in th
10040 65 20 73 75 62 2d 74 72 65 65 20 68 65 61 64 65  e sub-tree heade
10050 64 20 62 79 20 70 49 74 65 72 20 61 72 65 20 61  d by pIter are a
10060 6c 73 6f 20 69 6e 69 74 69 61 6c 69 7a 65 64 2e  lso initialized.
10070 20 44 61 74 61 20 69 73 20 74 68 65 6e 20 6c 6f   Data is then lo
10080 61 64 65 64 0a 2a 2a 20 69 6e 74 6f 20 74 68 65  aded.** into the
10090 20 62 75 66 66 65 72 73 20 62 65 6c 6f 6e 67 69   buffers belongi
100a0 6e 67 20 74 6f 20 74 68 69 73 20 69 74 65 72 61  ng to this itera
100b0 74 6f 72 2c 20 70 49 74 65 72 2c 20 61 6e 64 20  tor, pIter, and 
100c0 69 74 20 69 73 20 73 65 74 20 74 6f 0a 2a 2a 20  it is set to.** 
100d0 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 66 69 72  point to the fir
100e0 73 74 20 6b 65 79 20 69 6e 20 69 74 73 20 72 61  st key in its ra
100f0 6e 67 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 72  nge..**.** If ar
10100 67 75 6d 65 6e 74 20 65 4d 6f 64 65 20 69 73 20  gument eMode is 
10110 73 65 74 20 74 6f 20 49 4e 43 52 49 4e 49 54 5f  set to INCRINIT_
10120 54 41 53 4b 2c 20 74 68 65 6e 20 50 6d 61 52 65  TASK, then PmaRe
10130 61 64 65 72 20 69 73 20 67 75 61 72 61 6e 74 65  ader is guarante
10140 65 64 0a 2a 2a 20 74 6f 20 62 65 20 61 20 6d 75  ed.** to be a mu
10150 6c 74 69 2d 74 68 72 65 61 64 65 64 20 69 74 65  lti-threaded ite
10160 72 61 74 6f 72 20 61 6e 64 20 74 68 69 73 20 66  rator and this f
10170 75 6e 63 74 69 6f 6e 20 69 73 20 62 65 69 6e 67  unction is being
10180 20 63 61 6c 6c 65 64 20 69 6e 20 61 0a 2a 2a 20   called in a.** 
10190 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61  background threa
101a0 64 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65 20  d. In this case 
101b0 61 6c 6c 20 69 74 65 72 61 74 6f 72 73 20 69 6e  all iterators in
101c0 20 74 68 65 20 73 75 62 2d 74 72 65 65 20 61 72   the sub-tree ar
101d0 65 20 0a 2a 2a 20 69 6e 69 74 69 61 6c 69 7a 65  e .** initialize
101e0 64 20 61 73 20 66 6f 72 20 49 4e 43 52 49 4e 49  d as for INCRINI
101f0 54 5f 4e 4f 52 4d 41 4c 20 61 6e 64 20 74 68 65  T_NORMAL and the
10200 20 61 46 69 6c 65 5b 31 5d 20 62 75 66 66 65 72   aFile[1] buffer
10210 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 0a 2a 2a   belonging to.**
10220 20 70 49 74 65 72 20 69 73 20 70 6f 70 75 6c 61   pIter is popula
10230 74 65 64 2e 20 48 6f 77 65 76 65 72 2c 20 74 68  ted. However, th
10240 65 20 69 74 65 72 61 74 6f 72 20 69 74 73 65 6c  e iterator itsel
10250 66 20 69 73 20 6e 6f 74 20 73 65 74 20 75 70 20  f is not set up 
10260 74 6f 20 70 6f 69 6e 74 0a 2a 2a 20 74 6f 20 69  to point.** to i
10270 74 73 20 66 69 72 73 74 20 6b 65 79 2e 20 41 20  ts first key. A 
10280 63 61 6c 6c 20 74 6f 20 76 64 62 65 50 6d 61 52  call to vdbePmaR
10290 65 61 64 65 72 4e 65 78 74 28 29 20 69 73 20 73  eaderNext() is s
102a0 74 69 6c 6c 20 72 65 71 75 69 72 65 64 20 74 6f  till required to
102b0 20 64 6f 0a 2a 2a 20 74 68 61 74 2e 20 0a 2a 2a   do.** that. .**
102c0 0a 2a 2a 20 54 68 65 20 72 65 61 73 6f 6e 20 74  .** The reason t
102d0 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 64 6f 65  his function doe
102e0 73 20 6e 6f 74 20 63 61 6c 6c 20 76 64 62 65 50  s not call vdbeP
102f0 6d 61 52 65 61 64 65 72 4e 65 78 74 28 29 20 69  maReaderNext() i
10300 6d 6d 65 64 69 61 74 65 6c 79 20 0a 2a 2a 20 69  mmediately .** i
10310 6e 20 74 68 65 20 49 4e 43 52 49 4e 49 54 5f 54  n the INCRINIT_T
10320 41 53 4b 20 63 61 73 65 20 69 73 20 74 68 61 74  ASK case is that
10330 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 4e 65   vdbePmaReaderNe
10340 78 74 28 29 20 61 73 73 75 6d 65 73 20 74 68 61  xt() assumes tha
10350 74 20 68 61 73 0a 2a 2a 20 74 6f 20 62 6c 6f 63  t has.** to bloc
10360 6b 20 6f 6e 20 74 68 72 65 61 64 20 28 70 54 61  k on thread (pTa
10370 73 6b 2d 3e 74 68 72 65 61 64 29 20 62 65 66 6f  sk->thread) befo
10380 72 65 20 61 63 63 65 73 73 69 6e 67 20 61 46 69  re accessing aFi
10390 6c 65 5b 31 5d 2e 20 42 75 74 2c 20 73 69 6e 63  le[1]. But, sinc
103a0 65 0a 2a 2a 20 74 68 69 73 20 65 6e 74 69 72 65  e.** this entire
103b0 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 62 65 69   function is bei
103c0 6e 67 20 72 75 6e 20 62 79 20 74 68 72 65 61 64  ng run by thread
103d0 20 28 70 54 61 73 6b 2d 3e 74 68 72 65 61 64 29   (pTask->thread)
103e0 2c 20 74 68 61 74 20 77 69 6c 6c 0a 2a 2a 20 6c  , that will.** l
103f0 65 61 64 20 74 6f 20 74 68 65 20 63 75 72 72 65  ead to the curre
10400 6e 74 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68  nt background th
10410 72 65 61 64 20 61 74 74 65 6d 70 74 69 6e 67 20  read attempting 
10420 74 6f 20 6a 6f 69 6e 20 69 74 73 65 6c 66 2e 0a  to join itself..
10430 2a 2a 0a 2a 2a 20 46 69 6e 61 6c 6c 79 2c 20 69  **.** Finally, i
10440 66 20 61 72 67 75 6d 65 6e 74 20 65 4d 6f 64 65  f argument eMode
10450 20 69 73 20 73 65 74 20 74 6f 20 49 4e 43 52 49   is set to INCRI
10460 4e 49 54 5f 52 4f 4f 54 2c 20 69 74 20 6d 61 79  NIT_ROOT, it may
10470 20 62 65 20 61 73 73 75 6d 65 64 0a 2a 2a 20 74   be assumed.** t
10480 68 61 74 20 70 49 74 65 72 2d 3e 70 49 6e 63 72  hat pIter->pIncr
10490 20 69 73 20 61 20 6d 75 6c 74 69 2d 74 68 72 65   is a multi-thre
104a0 61 64 65 64 20 49 6e 63 72 4d 65 72 67 65 20 6f  aded IncrMerge o
104b0 62 6a 65 63 74 73 2c 20 61 6e 64 20 74 68 61 74  bjects, and that
104c0 20 61 6c 6c 0a 2a 2a 20 63 68 69 6c 64 2d 74 72   all.** child-tr
104d0 65 65 73 20 68 61 76 65 20 61 6c 72 65 61 64 79  ees have already
104e0 20 62 65 65 6e 20 69 6e 69 74 69 61 6c 69 7a 65   been initialize
104f0 64 20 75 73 69 6e 67 20 49 6e 63 72 49 6e 69 74  d using IncrInit
10500 28 49 4e 43 52 49 4e 49 54 5f 54 41 53 4b 29 2e  (INCRINIT_TASK).
10510 0a 2a 2a 20 49 6e 20 74 68 69 73 20 63 61 73 65  .** In this case
10520 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 4e 65   vdbePmaReaderNe
10530 78 74 28 29 20 69 73 20 63 61 6c 6c 65 64 20 6f  xt() is called o
10540 6e 20 61 6c 6c 20 63 68 69 6c 64 20 69 74 65 72  n all child iter
10550 61 74 6f 72 73 20 61 6e 64 0a 2a 2a 20 74 68 65  ators and.** the
10560 20 63 75 72 72 65 6e 74 20 69 74 65 72 61 74 6f   current iterato
10570 72 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74  r set to point t
10580 6f 20 74 68 65 20 66 69 72 73 74 20 6b 65 79 20  o the first key 
10590 69 6e 20 69 74 73 20 72 61 6e 67 65 2e 0a 2a 2a  in its range..**
105a0 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73  .** SQLITE_OK is
105b0 20 72 65 74 75 72 6e 65 64 20 69 66 20 73 75 63   returned if suc
105c0 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53  cessful, or an S
105d0 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
105e0 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73   otherwise..*/.s
105f0 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 50 6d  tatic int vdbePm
10600 61 52 65 61 64 65 72 49 6e 63 72 49 6e 69 74 28  aReaderIncrInit(
10610 50 6d 61 52 65 61 64 65 72 20 2a 70 49 74 65 72  PmaReader *pIter
10620 2c 20 69 6e 74 20 65 4d 6f 64 65 29 7b 0a 20 20  , int eMode){.  
10630 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
10640 4f 4b 3b 0a 20 20 49 6e 63 72 4d 65 72 67 65 72  OK;.  IncrMerger
10650 20 2a 70 49 6e 63 72 20 3d 20 70 49 74 65 72 2d   *pIncr = pIter-
10660 3e 70 49 6e 63 72 3b 0a 20 20 69 66 28 20 70 49  >pIncr;.  if( pI
10670 6e 63 72 20 29 7b 0a 20 20 20 20 53 6f 72 74 53  ncr ){.    SortS
10680 75 62 74 61 73 6b 20 2a 70 54 61 73 6b 20 3d 20  ubtask *pTask = 
10690 70 49 6e 63 72 2d 3e 70 54 61 73 6b 3b 0a 20 20  pIncr->pTask;.  
106a0 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20 3d 20    sqlite3 *db = 
106b0 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2d 3e  pTask->pSorter->
106c0 64 62 3b 0a 0a 20 20 20 20 72 63 20 3d 20 76 64  db;..    rc = vd
106d0 62 65 49 6e 63 72 49 6e 69 74 4d 65 72 67 65 72  beIncrInitMerger
106e0 28 70 54 61 73 6b 2c 20 70 49 6e 63 72 2d 3e 70  (pTask, pIncr->p
106f0 4d 65 72 67 65 72 2c 20 65 4d 6f 64 65 29 3b 0a  Merger, eMode);.
10700 0a 20 20 20 20 2f 2a 20 53 65 74 20 75 70 20 74  .    /* Set up t
10710 68 65 20 72 65 71 75 69 72 65 64 20 66 69 6c 65  he required file
10720 73 20 66 6f 72 20 70 49 6e 63 72 2e 20 41 20 6d  s for pIncr. A m
10730 75 6c 74 69 2d 74 68 65 61 64 65 64 20 49 6e 63  ulti-theaded Inc
10740 72 4d 65 72 67 65 20 6f 62 6a 65 63 74 0a 20 20  rMerge object.  
10750 20 20 2a 2a 20 72 65 71 75 69 72 65 73 20 74 77    ** requires tw
10760 6f 20 74 65 6d 70 20 66 69 6c 65 73 20 74 6f 20  o temp files to 
10770 69 74 73 65 6c 66 2c 20 77 68 65 72 65 61 73 20  itself, whereas 
10780 61 20 73 69 6e 67 6c 65 2d 74 68 72 65 61 64 65  a single-threade
10790 64 20 6f 62 6a 65 63 74 0a 20 20 20 20 2a 2a 20  d object.    ** 
107a0 6f 6e 6c 79 20 72 65 71 75 69 72 65 73 20 61 20  only requires a 
107b0 72 65 67 69 6f 6e 20 6f 66 20 70 54 61 73 6b 2d  region of pTask-
107c0 3e 66 69 6c 65 32 2e 20 2a 2f 0a 20 20 20 20 69  >file2. */.    i
107d0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
107e0 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6d 78   ){.      int mx
107f0 53 7a 20 3d 20 70 49 6e 63 72 2d 3e 6d 78 53 7a  Sz = pIncr->mxSz
10800 3b 0a 20 20 20 20 20 20 69 66 28 20 70 49 6e 63  ;.      if( pInc
10810 72 2d 3e 62 55 73 65 54 68 72 65 61 64 3d 3d 30  r->bUseThread==0
10820 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20   ){.        if( 
10830 70 54 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64  pTask->file2.pFd
10840 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ==0 ){.         
10850 20 61 73 73 65 72 74 28 20 70 54 61 73 6b 2d 3e   assert( pTask->
10860 66 69 6c 65 32 2e 69 45 6f 66 3e 30 20 29 3b 0a  file2.iEof>0 );.
10870 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 76            rc = v
10880 64 62 65 53 6f 72 74 65 72 4f 70 65 6e 54 65 6d  dbeSorterOpenTem
10890 70 46 69 6c 65 28 64 62 2c 20 70 54 61 73 6b 2d  pFile(db, pTask-
108a0 3e 66 69 6c 65 32 2e 69 45 6f 66 2c 20 26 70 54  >file2.iEof, &pT
108b0 61 73 6b 2d 3e 66 69 6c 65 32 2e 70 46 64 29 3b  ask->file2.pFd);
108c0 0a 20 20 20 20 20 20 20 20 20 20 70 54 61 73 6b  .          pTask
108d0 2d 3e 66 69 6c 65 32 2e 69 45 6f 66 20 3d 20 30  ->file2.iEof = 0
108e0 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
108f0 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
10900 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  TE_OK ){.       
10910 20 20 20 70 49 6e 63 72 2d 3e 61 46 69 6c 65 5b     pIncr->aFile[
10920 31 5d 2e 70 46 64 20 3d 20 70 54 61 73 6b 2d 3e  1].pFd = pTask->
10930 66 69 6c 65 32 2e 70 46 64 3b 0a 20 20 20 20 20  file2.pFd;.     
10940 20 20 20 20 20 70 49 6e 63 72 2d 3e 69 53 74 61       pIncr->iSta
10950 72 74 4f 66 66 20 3d 20 70 54 61 73 6b 2d 3e 66  rtOff = pTask->f
10960 69 6c 65 32 2e 69 45 6f 66 3b 0a 20 20 20 20 20  ile2.iEof;.     
10970 20 20 20 20 20 70 54 61 73 6b 2d 3e 66 69 6c 65       pTask->file
10980 32 2e 69 45 6f 66 20 2b 3d 20 6d 78 53 7a 3b 0a  2.iEof += mxSz;.
10990 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
109a0 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 72  }else{.        r
109b0 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4f 70  c = vdbeSorterOp
109c0 65 6e 54 65 6d 70 46 69 6c 65 28 64 62 2c 20 6d  enTempFile(db, m
109d0 78 53 7a 2c 20 26 70 49 6e 63 72 2d 3e 61 46 69  xSz, &pIncr->aFi
109e0 6c 65 5b 30 5d 2e 70 46 64 29 3b 0a 20 20 20 20  le[0].pFd);.    
109f0 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
10a00 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  TE_OK ){.       
10a10 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74     rc = vdbeSort
10a20 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 64  erOpenTempFile(d
10a30 62 2c 20 6d 78 53 7a 2c 20 26 70 49 6e 63 72 2d  b, mxSz, &pIncr-
10a40 3e 61 46 69 6c 65 5b 31 5d 2e 70 46 64 29 3b 0a  >aFile[1].pFd);.
10a50 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
10a60 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  }.    }..    if(
10a70 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
10a80 26 20 70 49 6e 63 72 2d 3e 62 55 73 65 54 68 72  & pIncr->bUseThr
10a90 65 61 64 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  ead ){.      /* 
10aa0 55 73 65 20 74 68 65 20 63 75 72 72 65 6e 74 20  Use the current 
10ab0 74 68 72 65 61 64 20 74 6f 20 70 6f 70 75 6c 61  thread to popula
10ac0 74 65 20 61 46 69 6c 65 5b 31 5d 2c 20 65 76 65  te aFile[1], eve
10ad0 6e 20 74 68 6f 75 67 68 20 74 68 69 73 0a 20 20  n though this.  
10ae0 20 20 20 20 2a 2a 20 69 74 65 72 61 74 6f 72 20      ** iterator 
10af0 69 73 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65  is multi-threade
10b00 64 2e 20 54 68 65 20 72 65 61 73 6f 6e 20 62 65  d. The reason be
10b10 69 6e 67 20 74 68 61 74 20 74 68 69 73 20 66 75  ing that this fu
10b20 6e 63 74 69 6f 6e 0a 20 20 20 20 20 20 2a 2a 20  nction.      ** 
10b30 69 73 20 61 6c 72 65 61 64 79 20 72 75 6e 6e 69  is already runni
10b40 6e 67 20 69 6e 20 62 61 63 6b 67 72 6f 75 6e 64  ng in background
10b50 20 74 68 72 65 61 64 20 70 49 6e 63 72 2d 3e 70   thread pIncr->p
10b60 54 61 73 6b 2d 3e 74 68 72 65 61 64 2e 20 2a 2f  Task->thread. */
10b70 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 65  .      assert( e
10b80 4d 6f 64 65 3d 3d 49 4e 43 52 49 4e 49 54 5f 52  Mode==INCRINIT_R
10b90 4f 4f 54 20 7c 7c 20 65 4d 6f 64 65 3d 3d 49 4e  OOT || eMode==IN
10ba0 43 52 49 4e 49 54 5f 54 41 53 4b 20 29 3b 0a 20  CRINIT_TASK );. 
10bb0 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 49 6e       rc = vdbeIn
10bc0 63 72 50 6f 70 75 6c 61 74 65 28 70 49 6e 63 72  crPopulate(pIncr
10bd0 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66  );.    }..    if
10be0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
10bf0 26 26 20 65 4d 6f 64 65 21 3d 49 4e 43 52 49 4e  && eMode!=INCRIN
10c00 49 54 5f 54 41 53 4b 20 29 7b 0a 20 20 20 20 20  IT_TASK ){.     
10c10 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61   rc = vdbePmaRea
10c20 64 65 72 4e 65 78 74 28 70 49 74 65 72 29 3b 0a  derNext(pIter);.
10c30 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
10c40 72 6e 20 72 63 3b 0a 7d 0a 0a 23 69 66 20 53 51  rn rc;.}..#if SQ
10c50 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f  LITE_MAX_WORKER_
10c60 54 48 52 45 41 44 53 3e 30 0a 2f 2a 0a 2a 2a 20  THREADS>0./*.** 
10c70 54 68 65 20 6d 61 69 6e 20 72 6f 75 74 69 6e 65  The main routine
10c80 20 66 6f 72 20 76 64 62 65 50 6d 61 52 65 61 64   for vdbePmaRead
10c90 65 72 49 6e 63 72 49 6e 69 74 28 29 20 6f 70 65  erIncrInit() ope
10ca0 72 61 74 69 6f 6e 73 20 72 75 6e 20 69 6e 20 0a  rations run in .
10cb0 2a 2a 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68  ** background th
10cc0 72 65 61 64 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  reads..*/.static
10cd0 20 76 6f 69 64 20 2a 76 64 62 65 50 6d 61 52 65   void *vdbePmaRe
10ce0 61 64 65 72 42 67 49 6e 69 74 28 76 6f 69 64 20  aderBgInit(void 
10cf0 2a 70 43 74 78 29 7b 0a 20 20 50 6d 61 52 65 61  *pCtx){.  PmaRea
10d00 64 65 72 20 2a 70 52 65 61 64 65 72 20 3d 20 28  der *pReader = (
10d10 50 6d 61 52 65 61 64 65 72 2a 29 70 43 74 78 3b  PmaReader*)pCtx;
10d20 0a 20 20 76 6f 69 64 20 2a 70 52 65 74 20 3d 20  .  void *pRet = 
10d30 53 51 4c 49 54 45 5f 49 4e 54 5f 54 4f 5f 50 54  SQLITE_INT_TO_PT
10d40 52 28 76 64 62 65 50 6d 61 52 65 61 64 65 72 49  R(vdbePmaReaderI
10d50 6e 63 72 49 6e 69 74 28 70 52 65 61 64 65 72 2c  ncrInit(pReader,
10d60 49 4e 43 52 49 4e 49 54 5f 54 41 53 4b 29 29 3b  INCRINIT_TASK));
10d70 0a 20 20 70 52 65 61 64 65 72 2d 3e 70 49 6e 63  .  pReader->pInc
10d80 72 2d 3e 70 54 61 73 6b 2d 3e 62 44 6f 6e 65 20  r->pTask->bDone 
10d90 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 70 52  = 1;.  return pR
10da0 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73 65  et;.}../*.** Use
10db0 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68   a background th
10dc0 72 65 61 64 20 74 6f 20 69 6e 76 6f 6b 65 20 76  read to invoke v
10dd0 64 62 65 50 6d 61 52 65 61 64 65 72 49 6e 63 72  dbePmaReaderIncr
10de0 49 6e 69 74 28 49 4e 43 52 49 4e 49 54 5f 54 41  Init(INCRINIT_TA
10df0 53 4b 29 20 0a 2a 2a 20 6f 6e 20 74 68 65 20 74  SK) .** on the t
10e00 68 65 20 50 6d 61 52 65 61 64 65 72 20 6f 62 6a  he PmaReader obj
10e10 65 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68  ect passed as th
10e20 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
10e30 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 63 61 6c  ..**.** This cal
10e40 6c 20 77 69 6c 6c 20 69 6e 69 74 69 61 6c 69 7a  l will initializ
10e50 65 20 74 68 65 20 76 61 72 69 6f 75 73 20 66 69  e the various fi
10e60 65 6c 64 73 20 6f 66 20 74 68 65 20 70 49 74 65  elds of the pIte
10e70 72 2d 3e 70 49 6e 63 72 20 0a 2a 2a 20 73 74 72  r->pIncr .** str
10e80 75 63 74 75 72 65 20 61 6e 64 2c 20 69 66 20 69  ucture and, if i
10e90 74 20 69 73 20 61 20 6d 75 6c 74 69 2d 74 68 72  t is a multi-thr
10ea0 65 61 64 65 64 20 49 6e 63 72 4d 65 72 67 65 72  eaded IncrMerger
10eb0 2c 20 6c 61 75 6e 63 68 20 61 20 0a 2a 2a 20 62  , launch a .** b
10ec0 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64  ackground thread
10ed0 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 61 46 69   to populate aFi
10ee0 6c 65 5b 31 5d 2e 0a 2a 2f 0a 73 74 61 74 69 63  le[1]..*/.static
10ef0 20 69 6e 74 20 76 64 62 65 50 6d 61 52 65 61 64   int vdbePmaRead
10f00 65 72 42 67 49 6e 63 72 49 6e 69 74 28 50 6d 61  erBgIncrInit(Pma
10f10 52 65 61 64 65 72 20 2a 70 49 74 65 72 29 7b 0a  Reader *pIter){.
10f20 20 20 76 6f 69 64 20 2a 70 43 74 78 20 3d 20 28    void *pCtx = (
10f30 76 6f 69 64 2a 29 70 49 74 65 72 3b 0a 20 20 72  void*)pIter;.  r
10f40 65 74 75 72 6e 20 76 64 62 65 53 6f 72 74 65 72  eturn vdbeSorter
10f50 43 72 65 61 74 65 54 68 72 65 61 64 28 70 49 74  CreateThread(pIt
10f60 65 72 2d 3e 70 49 6e 63 72 2d 3e 70 54 61 73 6b  er->pIncr->pTask
10f70 2c 20 76 64 62 65 50 6d 61 52 65 61 64 65 72 42  , vdbePmaReaderB
10f80 67 49 6e 69 74 2c 20 70 43 74 78 29 3b 0a 7d 0a  gInit, pCtx);.}.
10f90 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 41 6c  #endif../*.** Al
10fa0 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 4d 65 72  locate a new Mer
10fb0 67 65 45 6e 67 69 6e 65 20 6f 62 6a 65 63 74 20  geEngine object 
10fc0 74 6f 20 6d 65 72 67 65 20 74 68 65 20 63 6f 6e  to merge the con
10fd0 74 65 6e 74 73 20 6f 66 20 6e 50 4d 41 20 6c 65  tents of nPMA le
10fe0 76 65 6c 2d 30 0a 2a 2a 20 50 4d 41 73 20 66 72  vel-0.** PMAs fr
10ff0 6f 6d 20 70 54 61 73 6b 2d 3e 66 69 6c 65 2e 20  om pTask->file. 
11000 49 66 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75  If no error occu
11010 72 73 2c 20 73 65 74 20 2a 70 70 4f 75 74 20 74  rs, set *ppOut t
11020 6f 20 70 6f 69 6e 74 20 74 6f 0a 2a 2a 20 74 68  o point to.** th
11030 65 20 6e 65 77 20 6f 62 6a 65 63 74 20 61 6e 64  e new object and
11040 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
11050 4b 2e 20 4f 72 2c 20 69 66 20 61 6e 20 65 72 72  K. Or, if an err
11060 6f 72 20 64 6f 65 73 20 6f 63 63 75 72 2c 20 73  or does occur, s
11070 65 74 20 2a 70 70 4f 75 74 0a 2a 2a 20 74 6f 20  et *ppOut.** to 
11080 4e 55 4c 4c 20 61 6e 64 20 72 65 74 75 72 6e 20  NULL and return 
11090 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
110a0 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 6e  code..**.** When
110b0 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
110c0 73 20 63 61 6c 6c 65 64 2c 20 2a 70 69 4f 66 66  s called, *piOff
110d0 73 65 74 20 69 73 20 73 65 74 20 74 6f 20 74 68  set is set to th
110e0 65 20 6f 66 66 73 65 74 20 6f 66 20 74 68 65 0a  e offset of the.
110f0 2a 2a 20 66 69 72 73 74 20 50 4d 41 20 74 6f 20  ** first PMA to 
11100 72 65 61 64 20 66 72 6f 6d 20 70 54 61 73 6b 2d  read from pTask-
11110 3e 66 69 6c 65 2e 20 41 73 73 75 6d 69 6e 67 20  >file. Assuming 
11120 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c  no error occurs,
11130 20 69 74 20 69 73 20 0a 2a 2a 20 73 65 74 20 74   it is .** set t
11140 6f 20 74 68 65 20 6f 66 66 73 65 74 20 69 6d 6d  o the offset imm
11150 65 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 69  ediately followi
11160 6e 67 20 74 68 65 20 6c 61 73 74 20 62 79 74 65  ng the last byte
11170 20 6f 66 20 74 68 65 20 6c 61 73 74 0a 2a 2a 20   of the last.** 
11180 50 4d 41 20 62 65 66 6f 72 65 20 72 65 74 75 72  PMA before retur
11190 6e 69 6e 67 2e 20 49 66 20 61 6e 20 65 72 72 6f  ning. If an erro
111a0 72 20 64 6f 65 73 20 6f 63 63 75 72 2c 20 74 68  r does occur, th
111b0 65 6e 20 74 68 65 20 66 69 6e 61 6c 20 76 61 6c  en the final val
111c0 75 65 20 6f 66 0a 2a 2a 20 2a 70 69 4f 66 66 73  ue of.** *piOffs
111d0 65 74 20 69 73 20 75 6e 64 65 66 69 6e 65 64 2e  et is undefined.
111e0 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
111f0 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4c 65  dbeMergeEngineLe
11200 76 65 6c 30 28 0a 20 20 53 6f 72 74 53 75 62 74  vel0(.  SortSubt
11210 61 73 6b 20 2a 70 54 61 73 6b 2c 20 20 20 20 20  ask *pTask,     
11220 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65          /* Sorte
11230 72 20 74 61 73 6b 20 74 6f 20 72 65 61 64 20 66  r task to read f
11240 72 6f 6d 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 4d  rom */.  int nPM
11250 41 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  A,              
11260 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
11270 65 72 20 6f 66 20 50 4d 41 73 20 74 6f 20 72 65  er of PMAs to re
11280 61 64 20 2a 2f 0a 20 20 69 36 34 20 2a 70 69 4f  ad */.  i64 *piO
11290 66 66 73 65 74 2c 20 20 20 20 20 20 20 20 20 20  ffset,          
112a0 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55          /* IN/OU
112b0 54 3a 20 52 65 61 64 20 6f 66 66 73 65 74 20 69  T: Read offset i
112c0 6e 20 70 54 61 73 6b 2d 3e 66 69 6c 65 20 2a 2f  n pTask->file */
112d0 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a  .  MergeEngine *
112e0 2a 70 70 4f 75 74 20 20 20 20 20 20 20 20 20 20  *ppOut          
112f0 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 65 77 20 6d     /* OUT: New m
11300 65 72 67 65 2d 65 6e 67 69 6e 65 20 2a 2f 0a 29  erge-engine */.)
11310 7b 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  {.  MergeEngine 
11320 2a 70 4e 65 77 3b 20 20 20 20 20 20 20 20 20 20  *pNew;          
11330 20 20 20 20 2f 2a 20 4d 65 72 67 65 20 65 6e 67      /* Merge eng
11340 69 6e 65 20 74 6f 20 72 65 74 75 72 6e 20 2a 2f  ine to return */
11350 0a 20 20 69 36 34 20 69 4f 66 66 20 3d 20 2a 70  .  i64 iOff = *p
11360 69 4f 66 66 73 65 74 3b 0a 20 20 69 6e 74 20 69  iOffset;.  int i
11370 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  ;.  int rc = SQL
11380 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2a 70 70 4f 75  ITE_OK;..  *ppOu
11390 74 20 3d 20 70 4e 65 77 20 3d 20 76 64 62 65 4d  t = pNew = vdbeM
113a0 65 72 67 65 45 6e 67 69 6e 65 4e 65 77 28 6e 50  ergeEngineNew(nP
113b0 4d 41 29 3b 0a 20 20 69 66 28 20 70 4e 65 77 3d  MA);.  if( pNew=
113c0 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45  =0 ) rc = SQLITE
113d0 5f 4e 4f 4d 45 4d 3b 0a 0a 20 20 66 6f 72 28 69  _NOMEM;..  for(i
113e0 3d 30 3b 20 69 3c 6e 50 4d 41 20 26 26 20 72 63  =0; i<nPMA && rc
113f0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 2b 2b  ==SQLITE_OK; i++
11400 29 7b 0a 20 20 20 20 69 36 34 20 6e 44 75 6d 6d  ){.    i64 nDumm
11410 79 3b 0a 20 20 20 20 50 6d 61 52 65 61 64 65 72  y;.    PmaReader
11420 20 2a 70 49 74 65 72 20 3d 20 26 70 4e 65 77 2d   *pIter = &pNew-
11430 3e 61 49 74 65 72 5b 69 5d 3b 0a 20 20 20 20 72  >aIter[i];.    r
11440 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64 65  c = vdbePmaReade
11450 72 49 6e 69 74 28 70 54 61 73 6b 2c 20 26 70 54  rInit(pTask, &pT
11460 61 73 6b 2d 3e 66 69 6c 65 2c 20 69 4f 66 66 2c  ask->file, iOff,
11470 20 70 49 74 65 72 2c 20 26 6e 44 75 6d 6d 79 29   pIter, &nDummy)
11480 3b 0a 20 20 20 20 69 4f 66 66 20 3d 20 70 49 74  ;.    iOff = pIt
11490 65 72 2d 3e 69 45 6f 66 3b 0a 20 20 7d 0a 0a 20  er->iEof;.  }.. 
114a0 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
114b0 4f 4b 20 29 7b 0a 20 20 20 20 76 64 62 65 4d 65  OK ){.    vdbeMe
114c0 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28 70 4e  rgeEngineFree(pN
114d0 65 77 29 3b 0a 20 20 20 20 2a 70 70 4f 75 74 20  ew);.    *ppOut 
114e0 3d 20 30 3b 0a 20 20 7d 0a 20 20 2a 70 69 4f 66  = 0;.  }.  *piOf
114f0 66 73 65 74 20 3d 20 69 4f 66 66 3b 0a 20 20 72  fset = iOff;.  r
11500 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
11510 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 64 65  ** Return the de
11520 70 74 68 20 6f 66 20 61 20 74 72 65 65 20 63 6f  pth of a tree co
11530 6d 70 72 69 73 69 6e 67 20 6e 50 4d 41 20 50 4d  mprising nPMA PM
11540 41 73 2c 20 61 73 73 75 6d 69 6e 67 20 61 20 66  As, assuming a f
11550 61 6e 6f 75 74 20 6f 66 0a 2a 2a 20 53 4f 52 54  anout of.** SORT
11560 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55  ER_MAX_MERGE_COU
11570 4e 54 2e 20 54 68 65 20 72 65 74 75 72 6e 65 64  NT. The returned
11580 20 76 61 6c 75 65 20 64 6f 65 73 20 6e 6f 74 20   value does not 
11590 69 6e 63 6c 75 64 65 20 6c 65 61 66 20 6e 6f 64  include leaf nod
115a0 65 73 2e 0a 2a 2a 0a 2a 2a 20 69 2e 65 2e 0a 2a  es..**.** i.e..*
115b0 2a 0a 2a 2a 20 20 20 6e 50 4d 41 3c 3d 31 36 20  *.**   nPMA<=16 
115c0 20 20 20 2d 3e 20 54 72 65 65 44 65 70 74 68 28     -> TreeDepth(
115d0 29 20 3d 3d 20 30 0a 2a 2a 20 20 20 6e 50 4d 41  ) == 0.**   nPMA
115e0 3c 3d 32 35 36 20 20 20 2d 3e 20 54 72 65 65 44  <=256   -> TreeD
115f0 65 70 74 68 28 29 20 3d 3d 20 31 0a 2a 2a 20 20  epth() == 1.**  
11600 20 6e 50 4d 41 3c 3d 36 35 35 33 36 20 2d 3e 20   nPMA<=65536 -> 
11610 54 72 65 65 44 65 70 74 68 28 29 20 3d 3d 20 32  TreeDepth() == 2
11620 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
11630 64 62 65 53 6f 72 74 65 72 54 72 65 65 44 65 70  dbeSorterTreeDep
11640 74 68 28 69 6e 74 20 6e 50 4d 41 29 7b 0a 20 20  th(int nPMA){.  
11650 69 6e 74 20 6e 44 65 70 74 68 20 3d 20 30 3b 0a  int nDepth = 0;.
11660 20 20 69 36 34 20 6e 44 69 76 20 3d 20 53 4f 52    i64 nDiv = SOR
11670 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
11680 55 4e 54 3b 0a 20 20 77 68 69 6c 65 28 20 6e 44  UNT;.  while( nD
11690 69 76 20 3c 20 28 69 36 34 29 6e 50 4d 41 20 29  iv < (i64)nPMA )
116a0 7b 0a 20 20 20 20 6e 44 69 76 20 3d 20 6e 44 69  {.    nDiv = nDi
116b0 76 20 2a 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  v * SORTER_MAX_M
116c0 45 52 47 45 5f 43 4f 55 4e 54 3b 0a 20 20 20 20  ERGE_COUNT;.    
116d0 6e 44 65 70 74 68 2b 2b 3b 0a 20 20 7d 0a 20 20  nDepth++;.  }.  
116e0 72 65 74 75 72 6e 20 6e 44 65 70 74 68 3b 0a 7d  return nDepth;.}
116f0 0a 0a 2f 2a 0a 2a 2a 20 70 52 6f 6f 74 20 69 73  ../*.** pRoot is
11700 20 74 68 65 20 72 6f 6f 74 20 6f 66 20 61 6e 20   the root of an 
11710 69 6e 63 72 65 6d 65 6e 74 61 6c 20 6d 65 72 67  incremental merg
11720 65 2d 74 72 65 65 20 77 69 74 68 20 64 65 70 74  e-tree with dept
11730 68 20 6e 44 65 70 74 68 20 28 61 63 63 6f 72 64  h nDepth (accord
11740 69 6e 67 0a 2a 2a 20 74 6f 20 76 64 62 65 53 6f  ing.** to vdbeSo
11750 72 74 65 72 54 72 65 65 44 65 70 74 68 28 29 29  rterTreeDepth())
11760 2e 20 70 4c 65 61 66 20 69 73 20 74 68 65 20 69  . pLeaf is the i
11770 53 65 71 27 74 68 20 6c 65 61 66 20 74 6f 20 62  Seq'th leaf to b
11780 65 20 61 64 64 65 64 20 74 6f 20 74 68 65 0a 2a  e added to the.*
11790 2a 20 74 72 65 65 2c 20 63 6f 75 6e 74 69 6e 67  * tree, counting
117a0 20 66 72 6f 6d 20 7a 65 72 6f 2e 20 54 68 69 73   from zero. This
117b0 20 66 75 6e 63 74 69 6f 6e 20 61 64 64 73 20 70   function adds p
117c0 4c 65 61 66 20 74 6f 20 74 68 65 20 74 72 65 65  Leaf to the tree
117d0 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65  ..**.** If succe
117e0 73 73 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b  ssful, SQLITE_OK
117f0 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 49 66   is returned. If
11800 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
11810 2c 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  , an SQLite erro
11820 72 0a 2a 2a 20 63 6f 64 65 20 69 73 20 72 65 74  r.** code is ret
11830 75 72 6e 65 64 20 61 6e 64 20 70 4c 65 61 66 20  urned and pLeaf 
11840 69 73 20 66 72 65 65 64 2e 0a 2a 2f 0a 73 74 61  is freed..*/.sta
11850 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74  tic int vdbeSort
11860 65 72 41 64 64 54 6f 54 72 65 65 28 0a 20 20 53  erAddToTree(.  S
11870 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
11880 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  k,             /
11890 2a 20 54 61 73 6b 20 63 6f 6e 74 65 78 74 20 2a  * Task context *
118a0 2f 0a 20 20 69 6e 74 20 6e 44 65 70 74 68 2c 20  /.  int nDepth, 
118b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
118c0 20 20 20 20 2f 2a 20 44 65 70 74 68 20 6f 66 20      /* Depth of 
118d0 74 72 65 65 20 61 63 63 6f 72 64 69 6e 67 20 74  tree according t
118e0 6f 20 54 72 65 65 44 65 70 74 68 28 29 20 2a 2f  o TreeDepth() */
118f0 0a 20 20 69 6e 74 20 69 53 65 71 2c 20 20 20 20  .  int iSeq,    
11900 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11910 20 20 20 2f 2a 20 53 65 71 75 65 6e 63 65 20 6e     /* Sequence n
11920 75 6d 62 65 72 20 6f 66 20 6c 65 61 66 20 77 69  umber of leaf wi
11930 74 68 69 6e 20 74 72 65 65 20 2a 2f 0a 20 20 4d  thin tree */.  M
11940 65 72 67 65 45 6e 67 69 6e 65 20 2a 70 52 6f 6f  ergeEngine *pRoo
11950 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  t,             /
11960 2a 20 52 6f 6f 74 20 6f 66 20 74 72 65 65 20 2a  * Root of tree *
11970 2f 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  /.  MergeEngine 
11980 2a 70 4c 65 61 66 20 20 20 20 20 20 20 20 20 20  *pLeaf          
11990 20 20 20 20 2f 2a 20 4c 65 61 66 20 74 6f 20 61      /* Leaf to a
119a0 64 64 20 74 6f 20 74 72 65 65 20 2a 2f 0a 29 7b  dd to tree */.){
119b0 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
119c0 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 44 69  TE_OK;.  int nDi
119d0 76 20 3d 20 31 3b 0a 20 20 69 6e 74 20 69 3b 0a  v = 1;.  int i;.
119e0 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 2a 70    MergeEngine *p
119f0 20 3d 20 70 52 6f 6f 74 3b 0a 20 20 49 6e 63 72   = pRoot;.  Incr
11a00 4d 65 72 67 65 72 20 2a 70 49 6e 63 72 3b 0a 0a  Merger *pIncr;..
11a10 20 20 72 63 20 3d 20 76 64 62 65 49 6e 63 72 4e    rc = vdbeIncrN
11a20 65 77 28 70 54 61 73 6b 2c 20 70 4c 65 61 66 2c  ew(pTask, pLeaf,
11a30 20 26 70 49 6e 63 72 29 3b 0a 0a 20 20 66 6f 72   &pIncr);..  for
11a40 28 69 3d 31 3b 20 69 3c 6e 44 65 70 74 68 3b 20  (i=1; i<nDepth; 
11a50 69 2b 2b 29 7b 0a 20 20 20 20 6e 44 69 76 20 3d  i++){.    nDiv =
11a60 20 6e 44 69 76 20 2a 20 53 4f 52 54 45 52 5f 4d   nDiv * SORTER_M
11a70 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3b 0a  AX_MERGE_COUNT;.
11a80 20 20 7d 0a 0a 20 20 66 6f 72 28 69 3d 31 3b 20    }..  for(i=1; 
11a90 69 3c 6e 44 65 70 74 68 20 26 26 20 72 63 3d 3d  i<nDepth && rc==
11aa0 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b  SQLITE_OK; i++){
11ab0 0a 20 20 20 20 69 6e 74 20 69 49 74 65 72 20 3d  .    int iIter =
11ac0 20 28 69 53 65 71 20 2f 20 6e 44 69 76 29 20 25   (iSeq / nDiv) %
11ad0 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47   SORTER_MAX_MERG
11ae0 45 5f 43 4f 55 4e 54 3b 0a 20 20 20 20 50 6d 61  E_COUNT;.    Pma
11af0 52 65 61 64 65 72 20 2a 70 49 74 65 72 20 3d 20  Reader *pIter = 
11b00 26 70 2d 3e 61 49 74 65 72 5b 69 49 74 65 72 5d  &p->aIter[iIter]
11b10 3b 0a 0a 20 20 20 20 69 66 28 20 70 49 74 65 72  ;..    if( pIter
11b20 2d 3e 70 49 6e 63 72 3d 3d 30 20 29 7b 0a 20 20  ->pIncr==0 ){.  
11b30 20 20 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20      MergeEngine 
11b40 2a 70 4e 65 77 20 3d 20 76 64 62 65 4d 65 72 67  *pNew = vdbeMerg
11b50 65 45 6e 67 69 6e 65 4e 65 77 28 53 4f 52 54 45  eEngineNew(SORTE
11b60 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
11b70 54 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 4e  T);.      if( pN
11b80 65 77 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  ew==0 ){.       
11b90 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
11ba0 45 4d 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  EM;.      }else{
11bb0 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64  .        rc = vd
11bc0 62 65 49 6e 63 72 4e 65 77 28 70 54 61 73 6b 2c  beIncrNew(pTask,
11bd0 20 70 4e 65 77 2c 20 26 70 49 74 65 72 2d 3e 70   pNew, &pIter->p
11be0 49 6e 63 72 29 3b 0a 20 20 20 20 20 20 7d 0a 20  Incr);.      }. 
11bf0 20 20 20 7d 0a 0a 20 20 20 20 70 20 3d 20 70 49     }..    p = pI
11c00 74 65 72 2d 3e 70 49 6e 63 72 2d 3e 70 4d 65 72  ter->pIncr->pMer
11c10 67 65 72 3b 0a 20 20 20 20 6e 44 69 76 20 3d 20  ger;.    nDiv = 
11c20 6e 44 69 76 20 2f 20 53 4f 52 54 45 52 5f 4d 41  nDiv / SORTER_MA
11c30 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3b 0a 20  X_MERGE_COUNT;. 
11c40 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
11c50 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70  LITE_OK ){.    p
11c60 2d 3e 61 49 74 65 72 5b 69 53 65 71 20 25 20 53  ->aIter[iSeq % S
11c70 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f  ORTER_MAX_MERGE_
11c80 43 4f 55 4e 54 5d 2e 70 49 6e 63 72 20 3d 20 70  COUNT].pIncr = p
11c90 49 6e 63 72 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  Incr;.  }else{. 
11ca0 20 20 20 76 64 62 65 49 6e 63 72 46 72 65 65 28     vdbeIncrFree(
11cb0 70 49 6e 63 72 29 3b 0a 20 20 7d 0a 20 20 72 65  pIncr);.  }.  re
11cc0 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
11cd0 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
11ce0 69 73 20 63 61 6c 6c 65 64 20 61 73 20 70 61 72  is called as par
11cf0 74 20 6f 66 20 61 20 53 6f 72 74 65 72 52 65 77  t of a SorterRew
11d00 69 6e 64 28 29 20 6f 70 65 72 61 74 69 6f 6e 20  ind() operation 
11d10 6f 6e 20 61 20 73 6f 72 74 65 72 0a 2a 2a 20 74  on a sorter.** t
11d20 68 61 74 20 68 61 73 20 61 6c 72 65 61 64 79 20  hat has already 
11d30 77 72 69 74 74 65 6e 20 74 77 6f 20 6f 72 20 6d  written two or m
11d40 6f 72 65 20 6c 65 76 65 6c 2d 30 20 50 4d 41 73  ore level-0 PMAs
11d50 20 74 6f 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20   to one or more 
11d60 74 65 6d 70 0a 2a 2a 20 66 69 6c 65 73 2e 20 49  temp.** files. I
11d70 74 20 62 75 69 6c 64 73 20 61 20 74 72 65 65 20  t builds a tree 
11d80 6f 66 20 4d 65 72 67 65 45 6e 67 69 6e 65 2f 49  of MergeEngine/I
11d90 6e 63 72 4d 65 72 67 65 72 2f 50 6d 61 52 65 61  ncrMerger/PmaRea
11da0 64 65 72 20 6f 62 6a 65 63 74 73 20 74 68 61 74  der objects that
11db0 20 0a 2a 2a 20 63 61 6e 20 62 65 20 75 73 65 64   .** can be used
11dc0 20 74 6f 20 69 6e 63 72 65 6d 65 6e 74 61 6c 6c   to incrementall
11dd0 79 20 6d 65 72 67 65 20 61 6c 6c 20 50 4d 41 73  y merge all PMAs
11de0 20 6f 6e 20 64 69 73 6b 2e 0a 2a 2a 0a 2a 2a 20   on disk..**.** 
11df0 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 53  If successful, S
11e00 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75  QLITE_OK is retu
11e10 72 6e 65 64 20 61 6e 64 20 2a 70 70 4f 75 74 20  rned and *ppOut 
11e20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  set to point to 
11e30 74 68 65 0a 2a 2a 20 4d 65 72 67 65 45 6e 67 69  the.** MergeEngi
11e40 6e 65 20 6f 62 6a 65 63 74 20 61 74 20 74 68 65  ne object at the
11e50 20 72 6f 6f 74 20 6f 66 20 74 68 65 20 74 72 65   root of the tre
11e60 65 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69  e before returni
11e70 6e 67 2e 20 4f 72 2c 20 69 66 20 61 6e 0a 2a 2a  ng. Or, if an.**
11e80 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 61   error occurs, a
11e90 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  n SQLite error c
11ea0 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65 64 20  ode is returned 
11eb0 61 6e 64 20 74 68 65 20 66 69 6e 61 6c 20 76 61  and the final va
11ec0 6c 75 65 20 0a 2a 2a 20 6f 66 20 2a 70 70 4f 75  lue .** of *ppOu
11ed0 74 20 69 73 20 75 6e 64 65 66 69 6e 65 64 2e 0a  t is undefined..
11ee0 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
11ef0 62 65 53 6f 72 74 65 72 4d 65 72 67 65 54 72 65  beSorterMergeTre
11f00 65 42 75 69 6c 64 28 56 64 62 65 53 6f 72 74 65  eBuild(VdbeSorte
11f10 72 20 2a 70 53 6f 72 74 65 72 2c 20 4d 65 72 67  r *pSorter, Merg
11f20 65 45 6e 67 69 6e 65 20 2a 2a 70 70 4f 75 74 29  eEngine **ppOut)
11f30 7b 0a 20 20 4d 65 72 67 65 45 6e 67 69 6e 65 20  {.  MergeEngine 
11f40 2a 70 4d 61 69 6e 20 3d 20 30 3b 0a 20 20 69 6e  *pMain = 0;.  in
11f50 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
11f60 3b 0a 20 20 69 6e 74 20 69 54 61 73 6b 3b 0a 0a  ;.  int iTask;..
11f70 20 20 2f 2a 20 49 66 20 74 68 65 20 73 6f 72 74    /* If the sort
11f80 65 72 20 75 73 65 73 20 6d 6f 72 65 20 74 68 61  er uses more tha
11f90 6e 20 6f 6e 65 20 74 61 73 6b 2c 20 74 68 65 6e  n one task, then
11fa0 20 63 72 65 61 74 65 20 74 68 65 20 74 6f 70 2d   create the top-
11fb0 6c 65 76 65 6c 20 0a 20 20 2a 2a 20 4d 65 72 67  level .  ** Merg
11fc0 65 45 6e 67 69 6e 65 20 68 65 72 65 2e 20 54 68  eEngine here. Th
11fd0 69 73 20 4d 65 72 67 65 45 6e 67 69 6e 65 20 77  is MergeEngine w
11fe0 69 6c 6c 20 72 65 61 64 20 64 61 74 61 20 66 72  ill read data fr
11ff0 6f 6d 20 65 78 61 63 74 6c 79 20 0a 20 20 2a 2a  om exactly .  **
12000 20 6f 6e 65 20 50 6d 61 52 65 61 64 65 72 20 70   one PmaReader p
12010 65 72 20 73 75 62 2d 74 61 73 6b 2e 20 20 2a 2f  er sub-task.  */
12020 0a 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74  .  assert( pSort
12030 65 72 2d 3e 62 55 73 65 54 68 72 65 61 64 73 20  er->bUseThreads 
12040 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73  || pSorter->nTas
12050 6b 3d 3d 31 20 29 3b 0a 20 20 69 66 28 20 70 53  k==1 );.  if( pS
12060 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 3e 31 20 29  orter->nTask>1 )
12070 7b 0a 20 20 20 20 70 4d 61 69 6e 20 3d 20 76 64  {.    pMain = vd
12080 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 4e 65 77  beMergeEngineNew
12090 28 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b 29  (pSorter->nTask)
120a0 3b 0a 20 20 20 20 69 66 28 20 70 4d 61 69 6e 3d  ;.    if( pMain=
120b0 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45  =0 ) rc = SQLITE
120c0 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20 66  _NOMEM;.  }..  f
120d0 6f 72 28 69 54 61 73 6b 3d 30 3b 20 69 54 61 73  or(iTask=0; iTas
120e0 6b 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b  k<pSorter->nTask
120f0 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f   && rc==SQLITE_O
12100 4b 3b 20 69 54 61 73 6b 2b 2b 29 7b 0a 20 20 20  K; iTask++){.   
12110 20 53 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54   SortSubtask *pT
12120 61 73 6b 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e  ask = &pSorter->
12130 61 54 61 73 6b 5b 69 54 61 73 6b 5d 3b 0a 20 20  aTask[iTask];.  
12140 20 20 69 66 28 20 70 54 61 73 6b 2d 3e 6e 50 4d    if( pTask->nPM
12150 41 20 29 7b 0a 20 20 20 20 20 20 4d 65 72 67 65  A ){.      Merge
12160 45 6e 67 69 6e 65 20 2a 70 52 6f 6f 74 20 3d 20  Engine *pRoot = 
12170 30 3b 20 20 20 20 20 2f 2a 20 52 6f 6f 74 20 6e  0;     /* Root n
12180 6f 64 65 20 6f 66 20 74 72 65 65 20 66 6f 72 20  ode of tree for 
12190 74 68 69 73 20 74 61 73 6b 20 2a 2f 0a 20 20 20  this task */.   
121a0 20 20 20 69 6e 74 20 6e 44 65 70 74 68 20 3d 20     int nDepth = 
121b0 76 64 62 65 53 6f 72 74 65 72 54 72 65 65 44 65  vdbeSorterTreeDe
121c0 70 74 68 28 70 54 61 73 6b 2d 3e 6e 50 4d 41 29  pth(pTask->nPMA)
121d0 3b 0a 20 20 20 20 20 20 69 36 34 20 69 52 65 61  ;.      i64 iRea
121e0 64 4f 66 66 20 3d 20 30 3b 0a 0a 20 20 20 20 20  dOff = 0;..     
121f0 20 69 66 28 20 70 54 61 73 6b 2d 3e 6e 50 4d 41   if( pTask->nPMA
12200 3c 3d 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52  <=SORTER_MAX_MER
12210 47 45 5f 43 4f 55 4e 54 20 29 7b 0a 20 20 20 20  GE_COUNT ){.    
12220 20 20 20 20 72 63 20 3d 20 76 64 62 65 4d 65 72      rc = vdbeMer
12230 67 65 45 6e 67 69 6e 65 4c 65 76 65 6c 30 28 70  geEngineLevel0(p
12240 54 61 73 6b 2c 20 70 54 61 73 6b 2d 3e 6e 50 4d  Task, pTask->nPM
12250 41 2c 20 26 69 52 65 61 64 4f 66 66 2c 20 26 70  A, &iReadOff, &p
12260 52 6f 6f 74 29 3b 0a 20 20 20 20 20 20 7d 65 6c  Root);.      }el
12270 73 65 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20  se{.        int 
12280 69 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69  i;.        int i
12290 53 65 71 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  Seq = 0;.       
122a0 20 70 52 6f 6f 74 20 3d 20 76 64 62 65 4d 65 72   pRoot = vdbeMer
122b0 67 65 45 6e 67 69 6e 65 4e 65 77 28 53 4f 52 54  geEngineNew(SORT
122c0 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55  ER_MAX_MERGE_COU
122d0 4e 54 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  NT);.        if(
122e0 20 70 52 6f 6f 74 3d 3d 30 20 29 20 72 63 20 3d   pRoot==0 ) rc =
122f0 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
12300 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20         for(i=0; 
12310 69 3c 70 54 61 73 6b 2d 3e 6e 50 4d 41 20 26 26  i<pTask->nPMA &&
12320 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20   rc==SQLITE_OK; 
12330 69 20 2b 3d 20 53 4f 52 54 45 52 5f 4d 41 58 5f  i += SORTER_MAX_
12340 4d 45 52 47 45 5f 43 4f 55 4e 54 29 7b 0a 20 20  MERGE_COUNT){.  
12350 20 20 20 20 20 20 20 20 4d 65 72 67 65 45 6e 67          MergeEng
12360 69 6e 65 20 2a 70 4d 65 72 67 65 72 20 3d 20 30  ine *pMerger = 0
12370 3b 20 2f 2a 20 4e 65 77 20 6c 65 76 65 6c 2d 30  ; /* New level-0
12380 20 50 4d 41 20 6d 65 72 67 65 72 20 2a 2f 0a 20   PMA merger */. 
12390 20 20 20 20 20 20 20 20 20 69 6e 74 20 6e 52 65           int nRe
123a0 61 64 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  ader;           
123b0 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
123c0 6c 65 76 65 6c 2d 30 20 50 4d 41 73 20 74 6f 20  level-0 PMAs to 
123d0 6d 65 72 67 65 20 2a 2f 0a 0a 20 20 20 20 20 20  merge */..      
123e0 20 20 20 20 6e 52 65 61 64 65 72 20 3d 20 4d 49      nReader = MI
123f0 4e 28 70 54 61 73 6b 2d 3e 6e 50 4d 41 20 2d 20  N(pTask->nPMA - 
12400 69 2c 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45  i, SORTER_MAX_ME
12410 52 47 45 5f 43 4f 55 4e 54 29 3b 0a 20 20 20 20  RGE_COUNT);.    
12420 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 4d        rc = vdbeM
12430 65 72 67 65 45 6e 67 69 6e 65 4c 65 76 65 6c 30  ergeEngineLevel0
12440 28 70 54 61 73 6b 2c 20 6e 52 65 61 64 65 72 2c  (pTask, nReader,
12450 20 26 69 52 65 61 64 4f 66 66 2c 20 26 70 4d 65   &iReadOff, &pMe
12460 72 67 65 72 29 3b 0a 20 20 20 20 20 20 20 20 20  rger);.         
12470 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
12480 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  OK ){.          
12490 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
124a0 72 41 64 64 54 6f 54 72 65 65 28 70 54 61 73 6b  rAddToTree(pTask
124b0 2c 20 6e 44 65 70 74 68 2c 20 69 53 65 71 2b 2b  , nDepth, iSeq++
124c0 2c 20 70 52 6f 6f 74 2c 20 70 4d 65 72 67 65 72  , pRoot, pMerger
124d0 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20  );.          }. 
124e0 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
124f0 0a 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ..      if( rc==
12500 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
12510 20 20 20 20 20 69 66 28 20 70 4d 61 69 6e 3d 3d       if( pMain==
12520 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70  0 ){.          p
12530 4d 61 69 6e 20 3d 20 70 52 6f 6f 74 3b 0a 20 20  Main = pRoot;.  
12540 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
12550 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65         rc = vdbe
12560 49 6e 63 72 4e 65 77 28 70 54 61 73 6b 2c 20 70  IncrNew(pTask, p
12570 52 6f 6f 74 2c 20 26 70 4d 61 69 6e 2d 3e 61 49  Root, &pMain->aI
12580 74 65 72 5b 69 54 61 73 6b 5d 2e 70 49 6e 63 72  ter[iTask].pIncr
12590 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  );.        }.   
125a0 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
125b0 20 20 76 64 62 65 4d 65 72 67 65 45 6e 67 69 6e    vdbeMergeEngin
125c0 65 46 72 65 65 28 70 52 6f 6f 74 29 3b 0a 20 20  eFree(pRoot);.  
125d0 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
125e0 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
125f0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 64 62 65  E_OK ){.    vdbe
12600 4d 65 72 67 65 45 6e 67 69 6e 65 46 72 65 65 28  MergeEngineFree(
12610 70 4d 61 69 6e 29 3b 0a 20 20 20 20 70 4d 61 69  pMain);.    pMai
12620 6e 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 2a 70 70  n = 0;.  }.  *pp
12630 4f 75 74 20 3d 20 70 4d 61 69 6e 3b 0a 20 20 72  Out = pMain;.  r
12640 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
12650 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
12660 20 69 73 20 63 61 6c 6c 65 64 20 61 73 20 70 61   is called as pa
12670 72 74 20 6f 66 20 61 6e 20 73 71 6c 69 74 65 33  rt of an sqlite3
12680 56 64 62 65 53 6f 72 74 65 72 52 65 77 69 6e 64  VdbeSorterRewind
12690 28 29 20 6f 70 65 72 61 74 69 6f 6e 0a 2a 2a 20  () operation.** 
126a0 6f 6e 20 61 20 73 6f 72 74 65 72 20 74 68 61 74  on a sorter that
126b0 20 68 61 73 20 77 72 69 74 74 65 6e 20 74 77 6f   has written two
126c0 20 6f 72 20 6d 6f 72 65 20 50 4d 41 73 20 74 6f   or more PMAs to
126d0 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 73   temporary files
126e0 2e 20 49 74 20 73 65 74 73 0a 2a 2a 20 75 70 20  . It sets.** up 
126f0 65 69 74 68 65 72 20 56 64 62 65 53 6f 72 74 65  either VdbeSorte
12700 72 2e 70 4d 65 72 67 65 72 20 28 66 6f 72 20 73  r.pMerger (for s
12710 69 6e 67 6c 65 20 74 68 72 65 61 64 65 64 20 73  ingle threaded s
12720 6f 72 74 65 72 73 29 20 6f 72 20 70 52 65 61 64  orters) or pRead
12730 65 72 0a 2a 2a 20 28 66 6f 72 20 6d 75 6c 74 69  er.** (for multi
12740 2d 74 68 72 65 61 64 65 64 20 73 6f 72 74 65 72  -threaded sorter
12750 73 29 20 73 6f 20 74 68 61 74 20 69 74 20 63 61  s) so that it ca
12760 6e 20 62 65 20 75 73 65 64 20 74 6f 20 69 74 65  n be used to ite
12770 72 61 74 65 20 74 68 72 6f 75 67 68 0a 2a 2a 20  rate through.** 
12780 61 6c 6c 20 72 65 63 6f 72 64 73 20 73 74 6f 72  all records stor
12790 65 64 20 69 6e 20 74 68 65 20 73 6f 72 74 65 72  ed in the sorter
127a0 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f  ..**.** SQLITE_O
127b0 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 69 66  K is returned if
127c0 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20   successful, or 
127d0 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
127e0 63 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a  code otherwise..
127f0 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
12800 62 65 53 6f 72 74 65 72 53 65 74 75 70 4d 65 72  beSorterSetupMer
12810 67 65 28 56 64 62 65 53 6f 72 74 65 72 20 2a 70  ge(VdbeSorter *p
12820 53 6f 72 74 65 72 29 7b 0a 20 20 69 6e 74 20 72  Sorter){.  int r
12830 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
12840 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
12850 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 53  turn code */.  S
12860 6f 72 74 53 75 62 74 61 73 6b 20 2a 70 54 61 73  ortSubtask *pTas
12870 6b 30 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61  k0 = &pSorter->a
12880 54 61 73 6b 5b 30 5d 3b 0a 20 20 4d 65 72 67 65  Task[0];.  Merge
12890 45 6e 67 69 6e 65 20 2a 70 4d 61 69 6e 20 3d 20  Engine *pMain = 
128a0 30 3b 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41  0;.#if SQLITE_MA
128b0 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53  X_WORKER_THREADS
128c0 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20 3d  .  sqlite3 *db =
128d0 20 70 54 61 73 6b 30 2d 3e 70 53 6f 72 74 65 72   pTask0->pSorter
128e0 2d 3e 64 62 3b 0a 23 65 6e 64 69 66 0a 0a 20 20  ->db;.#endif..  
128f0 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4d  rc = vdbeSorterM
12900 65 72 67 65 54 72 65 65 42 75 69 6c 64 28 70 53  ergeTreeBuild(pS
12910 6f 72 74 65 72 2c 20 26 70 4d 61 69 6e 29 3b 0a  orter, &pMain);.
12920 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
12930 5f 4f 4b 20 29 7b 0a 23 69 66 20 53 51 4c 49 54  _OK ){.#if SQLIT
12940 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52  E_MAX_WORKER_THR
12950 45 41 44 53 0a 20 20 20 20 69 66 28 20 70 53 6f  EADS.    if( pSo
12960 72 74 65 72 2d 3e 62 55 73 65 54 68 72 65 61 64  rter->bUseThread
12970 73 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69  s ){.      int i
12980 54 61 73 6b 3b 0a 20 20 20 20 20 20 50 6d 61 52  Task;.      PmaR
12990 65 61 64 65 72 20 2a 70 49 74 65 72 3b 0a 20 20  eader *pIter;.  
129a0 20 20 20 20 53 6f 72 74 53 75 62 74 61 73 6b 20      SortSubtask 
129b0 2a 70 4c 61 73 74 20 3d 20 26 70 53 6f 72 74 65  *pLast = &pSorte
129c0 72 2d 3e 61 54 61 73 6b 5b 70 53 6f 72 74 65 72  r->aTask[pSorter
129d0 2d 3e 6e 54 61 73 6b 2d 31 5d 3b 0a 20 20 20 20  ->nTask-1];.    
129e0 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 41    rc = vdbeSortA
129f0 6c 6c 6f 63 55 6e 70 61 63 6b 65 64 28 70 4c 61  llocUnpacked(pLa
12a00 73 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  st);.      if( r
12a10 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
12a20 20 20 20 20 20 20 20 20 70 49 74 65 72 20 3d 20          pIter = 
12a30 28 50 6d 61 52 65 61 64 65 72 2a 29 73 71 6c 69  (PmaReader*)sqli
12a40 74 65 33 44 62 4d 61 6c 6c 6f 63 5a 65 72 6f 28  te3DbMallocZero(
12a50 64 62 2c 20 73 69 7a 65 6f 66 28 50 6d 61 52 65  db, sizeof(PmaRe
12a60 61 64 65 72 29 29 3b 0a 20 20 20 20 20 20 20 20  ader));.        
12a70 70 53 6f 72 74 65 72 2d 3e 70 52 65 61 64 65 72  pSorter->pReader
12a80 20 3d 20 70 49 74 65 72 3b 0a 20 20 20 20 20 20   = pIter;.      
12a90 20 20 69 66 28 20 70 49 74 65 72 3d 3d 30 20 29    if( pIter==0 )
12aa0 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
12ab0 45 4d 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  EM;.      }.    
12ac0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
12ad0 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72  _OK ){.        r
12ae0 63 20 3d 20 76 64 62 65 49 6e 63 72 4e 65 77 28  c = vdbeIncrNew(
12af0 70 4c 61 73 74 2c 20 70 4d 61 69 6e 2c 20 26 70  pLast, pMain, &p
12b00 49 74 65 72 2d 3e 70 49 6e 63 72 29 3b 0a 20 20  Iter->pIncr);.  
12b10 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
12b20 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
12b30 20 20 20 20 20 76 64 62 65 49 6e 63 72 53 65 74       vdbeIncrSet
12b40 54 68 72 65 61 64 73 28 70 49 74 65 72 2d 3e 70  Threads(pIter->p
12b50 49 6e 63 72 2c 20 70 53 6f 72 74 65 72 2d 3e 62  Incr, pSorter->b
12b60 55 73 65 54 68 72 65 61 64 73 29 3b 0a 20 20 20  UseThreads);.   
12b70 20 20 20 20 20 20 20 66 6f 72 28 69 54 61 73 6b         for(iTask
12b80 3d 30 3b 20 69 54 61 73 6b 3c 28 70 53 6f 72 74  =0; iTask<(pSort
12b90 65 72 2d 3e 6e 54 61 73 6b 2d 31 29 3b 20 69 54  er->nTask-1); iT
12ba0 61 73 6b 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ask++){.        
12bb0 20 20 20 20 49 6e 63 72 4d 65 72 67 65 72 20 2a      IncrMerger *
12bc0 70 49 6e 63 72 3b 0a 20 20 20 20 20 20 20 20 20  pIncr;.         
12bd0 20 20 20 69 66 28 20 28 70 49 6e 63 72 20 3d 20     if( (pIncr = 
12be0 70 4d 61 69 6e 2d 3e 61 49 74 65 72 5b 69 54 61  pMain->aIter[iTa
12bf0 73 6b 5d 2e 70 49 6e 63 72 29 20 29 7b 0a 20 20  sk].pIncr) ){.  
12c00 20 20 20 20 20 20 20 20 20 20 20 20 76 64 62 65              vdbe
12c10 49 6e 63 72 53 65 74 54 68 72 65 61 64 73 28 70  IncrSetThreads(p
12c20 49 6e 63 72 2c 20 70 53 6f 72 74 65 72 2d 3e 62  Incr, pSorter->b
12c30 55 73 65 54 68 72 65 61 64 73 29 3b 0a 20 20 20  UseThreads);.   
12c40 20 20 20 20 20 20 20 20 20 20 20 61 73 73 65 72             asser
12c50 74 28 20 70 49 6e 63 72 2d 3e 70 54 61 73 6b 21  t( pIncr->pTask!
12c60 3d 70 4c 61 73 74 20 29 3b 0a 20 20 20 20 20 20  =pLast );.      
12c70 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
12c80 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 69 66    }.          if
12c90 28 20 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73 6b  ( pSorter->nTask
12ca0 3e 31 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  >1 ){.          
12cb0 20 20 66 6f 72 28 69 54 61 73 6b 3d 30 3b 20 72    for(iTask=0; r
12cc0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
12cd0 69 54 61 73 6b 3c 70 53 6f 72 74 65 72 2d 3e 6e  iTask<pSorter->n
12ce0 54 61 73 6b 3b 20 69 54 61 73 6b 2b 2b 29 7b 0a  Task; iTask++){.
12cf0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 50 6d                Pm
12d00 61 52 65 61 64 65 72 20 2a 70 20 3d 20 26 70 4d  aReader *p = &pM
12d10 61 69 6e 2d 3e 61 49 74 65 72 5b 69 54 61 73 6b  ain->aIter[iTask
12d20 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ];.             
12d30 20 61 73 73 65 72 74 28 20 70 2d 3e 70 49 6e 63   assert( p->pInc
12d40 72 3d 3d 30 20 7c 7c 20 70 2d 3e 70 49 6e 63 72  r==0 || p->pIncr
12d50 2d 3e 70 54 61 73 6b 3d 3d 26 70 53 6f 72 74 65  ->pTask==&pSorte
12d60 72 2d 3e 61 54 61 73 6b 5b 69 54 61 73 6b 5d 20  r->aTask[iTask] 
12d70 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  );.             
12d80 20 69 66 28 20 70 2d 3e 70 49 6e 63 72 20 29 7b   if( p->pIncr ){
12d90 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61   rc = vdbePmaRea
12da0 64 65 72 42 67 49 6e 63 72 49 6e 69 74 28 70 29  derBgIncrInit(p)
12db0 3b 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20  ; }.            
12dc0 7d 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  }.          }.  
12dd0 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
12de0 70 4d 61 69 6e 20 3d 20 30 3b 0a 20 20 20 20 20  pMain = 0;.     
12df0 20 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d   }.      if( rc=
12e00 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
12e10 20 20 20 20 20 20 69 6e 74 20 65 4d 6f 64 65 20        int eMode 
12e20 3d 20 28 70 53 6f 72 74 65 72 2d 3e 6e 54 61 73  = (pSorter->nTas
12e30 6b 3e 31 20 3f 20 49 4e 43 52 49 4e 49 54 5f 52  k>1 ? INCRINIT_R
12e40 4f 4f 54 20 3a 20 49 4e 43 52 49 4e 49 54 5f 4e  OOT : INCRINIT_N
12e50 4f 52 4d 41 4c 29 3b 0a 20 20 20 20 20 20 20 20  ORMAL);.        
12e60 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65 61 64  rc = vdbePmaRead
12e70 65 72 49 6e 63 72 49 6e 69 74 28 70 49 74 65 72  erIncrInit(pIter
12e80 2c 20 65 4d 6f 64 65 29 3b 0a 20 20 20 20 20 20  , eMode);.      
12e90 7d 0a 20 20 20 20 7d 65 6c 73 65 0a 23 65 6e 64  }.    }else.#end
12ea0 69 66 0a 20 20 20 20 7b 0a 20 20 20 20 20 20 72  if.    {.      r
12eb0 63 20 3d 20 76 64 62 65 49 6e 63 72 49 6e 69 74  c = vdbeIncrInit
12ec0 4d 65 72 67 65 72 28 70 54 61 73 6b 30 2c 20 70  Merger(pTask0, p
12ed0 4d 61 69 6e 2c 20 49 4e 43 52 49 4e 49 54 5f 4e  Main, INCRINIT_N
12ee0 4f 52 4d 41 4c 29 3b 0a 20 20 20 20 20 20 70 53  ORMAL);.      pS
12ef0 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 20 3d  orter->pMerger =
12f00 20 70 4d 61 69 6e 3b 0a 20 20 20 20 20 20 70 4d   pMain;.      pM
12f10 61 69 6e 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20  ain = 0;.    }. 
12f20 20 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53 51   }..  if( rc!=SQ
12f30 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76  LITE_OK ){.    v
12f40 64 62 65 4d 65 72 67 65 45 6e 67 69 6e 65 46 72  dbeMergeEngineFr
12f50 65 65 28 70 4d 61 69 6e 29 3b 0a 20 20 7d 0a 20  ee(pMain);.  }. 
12f60 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a   return rc;.}...
12f70 2f 2a 0a 2a 2a 20 4f 6e 63 65 20 74 68 65 20 73  /*.** Once the s
12f80 6f 72 74 65 72 20 68 61 73 20 62 65 65 6e 20 70  orter has been p
12f90 6f 70 75 6c 61 74 65 64 20 62 79 20 63 61 6c 6c  opulated by call
12fa0 73 20 74 6f 20 73 71 6c 69 74 65 33 56 64 62 65  s to sqlite3Vdbe
12fb0 53 6f 72 74 65 72 57 72 69 74 65 2c 0a 2a 2a 20  SorterWrite,.** 
12fc0 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  this function is
12fd0 20 63 61 6c 6c 65 64 20 74 6f 20 70 72 65 70 61   called to prepa
12fe0 72 65 20 66 6f 72 20 69 74 65 72 61 74 69 6e 67  re for iterating
12ff0 20 74 68 72 6f 75 67 68 20 74 68 65 20 72 65 63   through the rec
13000 6f 72 64 73 0a 2a 2a 20 69 6e 20 73 6f 72 74 65  ords.** in sorte
13010 64 20 6f 72 64 65 72 2e 0a 2a 2f 0a 69 6e 74 20  d order..*/.int 
13020 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
13030 72 52 65 77 69 6e 64 28 63 6f 6e 73 74 20 56 64  rRewind(const Vd
13040 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  beCursor *pCsr, 
13050 69 6e 74 20 2a 70 62 45 6f 66 29 7b 0a 20 20 56  int *pbEof){.  V
13060 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
13070 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74  er = pCsr->pSort
13080 65 72 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  er;.  int rc = S
13090 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
130a0 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
130b0 63 6f 64 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72  code */..  asser
130c0 74 28 20 70 53 6f 72 74 65 72 20 29 3b 0a 0a 20  t( pSorter );.. 
130d0 20 2f 2a 20 49 66 20 6e 6f 20 64 61 74 61 20 68   /* If no data h
130e0 61 73 20 62 65 65 6e 20 77 72 69 74 74 65 6e 20  as been written 
130f0 74 6f 20 64 69 73 6b 2c 20 74 68 65 6e 20 64 6f  to disk, then do
13100 20 6e 6f 74 20 64 6f 20 73 6f 20 6e 6f 77 2e 20   not do so now. 
13110 49 6e 73 74 65 61 64 2c 0a 20 20 2a 2a 20 73 6f  Instead,.  ** so
13120 72 74 20 74 68 65 20 56 64 62 65 53 6f 72 74 65  rt the VdbeSorte
13130 72 2e 70 52 65 63 6f 72 64 20 6c 69 73 74 2e 20  r.pRecord list. 
13140 54 68 65 20 76 64 62 65 20 6c 61 79 65 72 20 77  The vdbe layer w
13150 69 6c 6c 20 72 65 61 64 20 64 61 74 61 20 64 69  ill read data di
13160 72 65 63 74 6c 79 0a 20 20 2a 2a 20 66 72 6f 6d  rectly.  ** from
13170 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c   the in-memory l
13180 69 73 74 2e 20 20 2a 2f 0a 20 20 69 66 28 20 70  ist.  */.  if( p
13190 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41 3d  Sorter->bUsePMA=
131a0 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 70 53  =0 ){.    if( pS
131b0 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73  orter->list.pLis
131c0 74 20 29 7b 0a 20 20 20 20 20 20 2a 70 62 45 6f  t ){.      *pbEo
131d0 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 63 20  f = 0;.      rc 
131e0 3d 20 76 64 62 65 53 6f 72 74 65 72 53 6f 72 74  = vdbeSorterSort
131f0 28 26 70 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b  (&pSorter->aTask
13200 5b 30 5d 2c 20 26 70 53 6f 72 74 65 72 2d 3e 6c  [0], &pSorter->l
13210 69 73 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  ist);.    }else{
13220 0a 20 20 20 20 20 20 2a 70 62 45 6f 66 20 3d 20  .      *pbEof = 
13230 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74  1;.    }.    ret
13240 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f  urn rc;.  }..  /
13250 2a 20 57 72 69 74 65 20 74 68 65 20 63 75 72 72  * Write the curr
13260 65 6e 74 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69  ent in-memory li
13270 73 74 20 74 6f 20 61 20 50 4d 41 2e 20 2a 2f 0a  st to a PMA. */.
13280 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6c    if( pSorter->l
13290 69 73 74 2e 70 4c 69 73 74 20 29 7b 0a 20 20 20  ist.pList ){.   
132a0 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
132b0 46 6c 75 73 68 50 4d 41 28 70 53 6f 72 74 65 72  FlushPMA(pSorter
132c0 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4a 6f 69  );.  }..  /* Joi
132d0 6e 20 61 6c 6c 20 74 68 72 65 61 64 73 20 2a 2f  n all threads */
132e0 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74  .  rc = vdbeSort
132f0 65 72 4a 6f 69 6e 41 6c 6c 28 70 53 6f 72 74 65  erJoinAll(pSorte
13300 72 2c 20 72 63 29 3b 0a 0a 20 20 76 64 62 65 53  r, rc);..  vdbeS
13310 6f 72 74 65 72 52 65 77 69 6e 64 44 65 62 75 67  orterRewindDebug
13320 28 22 72 65 77 69 6e 64 22 29 3b 0a 0a 20 20 2f  ("rewind");..  /
13330 2a 20 41 73 73 75 6d 69 6e 67 20 6e 6f 20 65 72  * Assuming no er
13340 72 6f 72 73 20 68 61 76 65 20 6f 63 63 75 72 72  rors have occurr
13350 65 64 2c 20 73 65 74 20 75 70 20 61 20 6d 65 72  ed, set up a mer
13360 67 65 72 20 73 74 72 75 63 74 75 72 65 20 74 6f  ger structure to
13370 20 0a 20 20 2a 2a 20 69 6e 63 72 65 6d 65 6e 74   .  ** increment
13380 61 6c 6c 79 20 72 65 61 64 20 61 6e 64 20 6d 65  ally read and me
13390 72 67 65 20 61 6c 6c 20 72 65 6d 61 69 6e 69 6e  rge all remainin
133a0 67 20 50 4d 41 73 2e 20 20 2a 2f 0a 20 20 61 73  g PMAs.  */.  as
133b0 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 70  sert( pSorter->p
133c0 52 65 61 64 65 72 3d 3d 30 20 29 3b 0a 20 20 69  Reader==0 );.  i
133d0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
133e0 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62   ){.    rc = vdb
133f0 65 53 6f 72 74 65 72 53 65 74 75 70 4d 65 72 67  eSorterSetupMerg
13400 65 28 70 53 6f 72 74 65 72 29 3b 0a 20 20 20 20  e(pSorter);.    
13410 2a 70 62 45 6f 66 20 3d 20 30 3b 0a 20 20 7d 0a  *pbEof = 0;.  }.
13420 0a 20 20 76 64 62 65 53 6f 72 74 65 72 52 65 77  .  vdbeSorterRew
13430 69 6e 64 44 65 62 75 67 28 22 72 65 77 69 6e 64  indDebug("rewind
13440 64 6f 6e 65 22 29 3b 0a 20 20 72 65 74 75 72 6e  done");.  return
13450 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64   rc;.}../*.** Ad
13460 76 61 6e 63 65 20 74 6f 20 74 68 65 20 6e 65 78  vance to the nex
13470 74 20 65 6c 65 6d 65 6e 74 20 69 6e 20 74 68 65  t element in the
13480 20 73 6f 72 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20   sorter..*/.int 
13490 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
134a0 72 4e 65 78 74 28 73 71 6c 69 74 65 33 20 2a 64  rNext(sqlite3 *d
134b0 62 2c 20 63 6f 6e 73 74 20 56 64 62 65 43 75 72  b, const VdbeCur
134c0 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74 20 2a  sor *pCsr, int *
134d0 70 62 45 6f 66 29 7b 0a 20 20 56 64 62 65 53 6f  pbEof){.  VdbeSo
134e0 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20  rter *pSorter = 
134f0 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20  pCsr->pSorter;. 
13500 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
13510 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13520 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
13530 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 53  */..  assert( pS
13540 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41 20 7c  orter->bUsePMA |
13550 7c 20 28 70 53 6f 72 74 65 72 2d 3e 70 52 65 61  | (pSorter->pRea
13560 64 65 72 3d 3d 30 20 26 26 20 70 53 6f 72 74 65  der==0 && pSorte
13570 72 2d 3e 70 4d 65 72 67 65 72 3d 3d 30 29 20 29  r->pMerger==0) )
13580 3b 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d  ;.  if( pSorter-
13590 3e 62 55 73 65 50 4d 41 20 29 7b 0a 20 20 20 20  >bUsePMA ){.    
135a0 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d  assert( pSorter-
135b0 3e 70 52 65 61 64 65 72 3d 3d 30 20 7c 7c 20 70  >pReader==0 || p
135c0 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 3d  Sorter->pMerger=
135d0 3d 30 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  =0 );.    assert
135e0 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 54  ( pSorter->bUseT
135f0 68 72 65 61 64 73 3d 3d 30 20 7c 7c 20 70 53 6f  hreads==0 || pSo
13600 72 74 65 72 2d 3e 70 52 65 61 64 65 72 20 29 3b  rter->pReader );
13610 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 53 6f  .    assert( pSo
13620 72 74 65 72 2d 3e 62 55 73 65 54 68 72 65 61 64  rter->bUseThread
13630 73 3d 3d 31 20 7c 7c 20 70 53 6f 72 74 65 72 2d  s==1 || pSorter-
13640 3e 70 4d 65 72 67 65 72 20 29 3b 0a 20 20 20 20  >pMerger );.    
13650 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73  if( pSorter->bUs
13660 65 54 68 72 65 61 64 73 20 29 7b 0a 20 20 20 20  eThreads ){.    
13670 20 20 72 63 20 3d 20 76 64 62 65 50 6d 61 52 65    rc = vdbePmaRe
13680 61 64 65 72 4e 65 78 74 28 70 53 6f 72 74 65 72  aderNext(pSorter
13690 2d 3e 70 52 65 61 64 65 72 29 3b 0a 20 20 20 20  ->pReader);.    
136a0 20 20 2a 70 62 45 6f 66 20 3d 20 28 70 53 6f 72    *pbEof = (pSor
136b0 74 65 72 2d 3e 70 52 65 61 64 65 72 2d 3e 70 46  ter->pReader->pF
136c0 69 6c 65 3d 3d 30 29 3b 0a 20 20 20 20 7d 65 6c  ile==0);.    }el
136d0 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 76  se{.      rc = v
136e0 64 62 65 53 6f 72 74 65 72 4e 65 78 74 28 26 70  dbeSorterNext(&p
136f0 53 6f 72 74 65 72 2d 3e 61 54 61 73 6b 5b 30 5d  Sorter->aTask[0]
13700 2c 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67  , pSorter->pMerg
13710 65 72 2c 20 70 62 45 6f 66 29 3b 0a 20 20 20 20  er, pbEof);.    
13720 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 53  }.  }else{.    S
13730 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 46 72  orterRecord *pFr
13740 65 65 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6c 69  ee = pSorter->li
13750 73 74 2e 70 4c 69 73 74 3b 0a 20 20 20 20 70 53  st.pList;.    pS
13760 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73  orter->list.pLis
13770 74 20 3d 20 70 46 72 65 65 2d 3e 75 2e 70 4e 65  t = pFree->u.pNe
13780 78 74 3b 0a 20 20 20 20 70 46 72 65 65 2d 3e 75  xt;.    pFree->u
13790 2e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20  .pNext = 0;.    
137a0 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6c 69 73  if( pSorter->lis
137b0 74 2e 61 4d 65 6d 6f 72 79 3d 3d 30 20 29 20 76  t.aMemory==0 ) v
137c0 64 62 65 53 6f 72 74 65 72 52 65 63 6f 72 64 46  dbeSorterRecordF
137d0 72 65 65 28 64 62 2c 20 70 46 72 65 65 29 3b 0a  ree(db, pFree);.
137e0 20 20 20 20 2a 70 62 45 6f 66 20 3d 20 21 70 53      *pbEof = !pS
137f0 6f 72 74 65 72 2d 3e 6c 69 73 74 2e 70 4c 69 73  orter->list.pLis
13800 74 3b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49  t;.    rc = SQLI
13810 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 20 20 72 65 74  TE_OK;.  }.  ret
13820 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
13830 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65   Return a pointe
13840 72 20 74 6f 20 61 20 62 75 66 66 65 72 20 6f 77  r to a buffer ow
13850 6e 65 64 20 62 79 20 74 68 65 20 73 6f 72 74 65  ned by the sorte
13860 72 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20  r that contains 
13870 74 68 65 20 0a 2a 2a 20 63 75 72 72 65 6e 74 20  the .** current 
13880 6b 65 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  key..*/.static v
13890 6f 69 64 20 2a 76 64 62 65 53 6f 72 74 65 72 52  oid *vdbeSorterR
138a0 6f 77 6b 65 79 28 0a 20 20 63 6f 6e 73 74 20 56  owkey(.  const V
138b0 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
138c0 65 72 2c 20 20 20 20 20 20 2f 2a 20 53 6f 72 74  er,      /* Sort
138d0 65 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69  er object */.  i
138e0 6e 74 20 2a 70 6e 4b 65 79 20 20 20 20 20 20 20  nt *pnKey       
138f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
13900 2a 20 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20 63  * OUT: Size of c
13910 75 72 72 65 6e 74 20 6b 65 79 20 69 6e 20 62 79  urrent key in by
13920 74 65 73 20 2a 2f 0a 29 7b 0a 20 20 76 6f 69 64  tes */.){.  void
13930 20 2a 70 4b 65 79 3b 0a 20 20 69 66 28 20 70 53   *pKey;.  if( pS
13940 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41 20 29  orter->bUsePMA )
13950 7b 0a 20 20 20 20 50 6d 61 52 65 61 64 65 72 20  {.    PmaReader 
13960 2a 70 52 65 61 64 65 72 20 3d 20 28 70 53 6f 72  *pReader = (pSor
13970 74 65 72 2d 3e 62 55 73 65 54 68 72 65 61 64 73  ter->bUseThreads
13980 20 3f 0a 20 20 20 20 20 20 20 20 70 53 6f 72 74   ?.        pSort
13990 65 72 2d 3e 70 52 65 61 64 65 72 20 3a 20 26 70  er->pReader : &p
139a0 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 2d  Sorter->pMerger-
139b0 3e 61 49 74 65 72 5b 70 53 6f 72 74 65 72 2d 3e  >aIter[pSorter->
139c0 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 31  pMerger->aTree[1
139d0 5d 5d 0a 20 20 20 20 29 3b 0a 20 20 20 20 2a 70  ]].    );.    *p
139e0 6e 4b 65 79 20 3d 20 70 52 65 61 64 65 72 2d 3e  nKey = pReader->
139f0 6e 4b 65 79 3b 0a 20 20 20 20 70 4b 65 79 20 3d  nKey;.    pKey =
13a00 20 70 52 65 61 64 65 72 2d 3e 61 4b 65 79 3b 0a   pReader->aKey;.
13a10 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2a 70 6e    }else{.    *pn
13a20 4b 65 79 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6c  Key = pSorter->l
13a30 69 73 74 2e 70 4c 69 73 74 2d 3e 6e 56 61 6c 3b  ist.pList->nVal;
13a40 0a 20 20 20 20 70 4b 65 79 20 3d 20 53 52 56 41  .    pKey = SRVA
13a50 4c 28 70 53 6f 72 74 65 72 2d 3e 6c 69 73 74 2e  L(pSorter->list.
13a60 70 4c 69 73 74 29 3b 0a 20 20 7d 0a 20 20 72 65  pList);.  }.  re
13a70 74 75 72 6e 20 70 4b 65 79 3b 0a 7d 0a 0a 2f 2a  turn pKey;.}../*
13a80 0a 2a 2a 20 43 6f 70 79 20 74 68 65 20 63 75 72  .** Copy the cur
13a90 72 65 6e 74 20 73 6f 72 74 65 72 20 6b 65 79 20  rent sorter key 
13aa0 69 6e 74 6f 20 74 68 65 20 6d 65 6d 6f 72 79 20  into the memory 
13ab0 63 65 6c 6c 20 70 4f 75 74 2e 0a 2a 2f 0a 69 6e  cell pOut..*/.in
13ac0 74 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72  t sqlite3VdbeSor
13ad0 74 65 72 52 6f 77 6b 65 79 28 63 6f 6e 73 74 20  terRowkey(const 
13ae0 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72  VdbeCursor *pCsr
13af0 2c 20 4d 65 6d 20 2a 70 4f 75 74 29 7b 0a 20 20  , Mem *pOut){.  
13b00 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72  VdbeSorter *pSor
13b10 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72  ter = pCsr->pSor
13b20 74 65 72 3b 0a 20 20 76 6f 69 64 20 2a 70 4b 65  ter;.  void *pKe
13b30 79 3b 20 69 6e 74 20 6e 4b 65 79 3b 20 20 20 20  y; int nKey;    
13b40 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72         /* Sorter
13b50 20 6b 65 79 20 74 6f 20 63 6f 70 79 20 69 6e 74   key to copy int
13b60 6f 20 70 4f 75 74 20 2a 2f 0a 0a 20 20 70 4b 65  o pOut */..  pKe
13b70 79 20 3d 20 76 64 62 65 53 6f 72 74 65 72 52 6f  y = vdbeSorterRo
13b80 77 6b 65 79 28 70 53 6f 72 74 65 72 2c 20 26 6e  wkey(pSorter, &n
13b90 4b 65 79 29 3b 0a 20 20 69 66 28 20 73 71 6c 69  Key);.  if( sqli
13ba0 74 65 33 56 64 62 65 4d 65 6d 47 72 6f 77 28 70  te3VdbeMemGrow(p
13bb0 4f 75 74 2c 20 6e 4b 65 79 2c 20 30 29 20 29 7b  Out, nKey, 0) ){
13bc0 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
13bd0 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20  TE_NOMEM;.  }.  
13be0 70 4f 75 74 2d 3e 6e 20 3d 20 6e 4b 65 79 3b 0a  pOut->n = nKey;.
13bf0 20 20 4d 65 6d 53 65 74 54 79 70 65 46 6c 61 67    MemSetTypeFlag
13c00 28 70 4f 75 74 2c 20 4d 45 4d 5f 42 6c 6f 62 29  (pOut, MEM_Blob)
13c10 3b 0a 20 20 6d 65 6d 63 70 79 28 70 4f 75 74 2d  ;.  memcpy(pOut-
13c20 3e 7a 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 29 3b  >z, pKey, nKey);
13c30 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ..  return SQLIT
13c40 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  E_OK;.}../*.** C
13c50 6f 6d 70 61 72 65 20 74 68 65 20 6b 65 79 20 69  ompare the key i
13c60 6e 20 6d 65 6d 6f 72 79 20 63 65 6c 6c 20 70 56  n memory cell pV
13c70 61 6c 20 77 69 74 68 20 74 68 65 20 6b 65 79 20  al with the key 
13c80 74 68 61 74 20 74 68 65 20 73 6f 72 74 65 72 20  that the sorter 
13c90 63 75 72 73 6f 72 0a 2a 2a 20 70 61 73 73 65 64  cursor.** passed
13ca0 20 61 73 20 74 68 65 20 66 69 72 73 74 20 61 72   as the first ar
13cb0 67 75 6d 65 6e 74 20 63 75 72 72 65 6e 74 6c 79  gument currently
13cc0 20 70 6f 69 6e 74 73 20 74 6f 2e 20 46 6f 72 20   points to. For 
13cd0 74 68 65 20 70 75 72 70 6f 73 65 73 20 6f 66 0a  the purposes of.
13ce0 2a 2a 20 74 68 65 20 63 6f 6d 70 61 72 69 73 6f  ** the compariso
13cf0 6e 2c 20 69 67 6e 6f 72 65 20 74 68 65 20 72 6f  n, ignore the ro
13d00 77 69 64 20 66 69 65 6c 64 20 61 74 20 74 68 65  wid field at the
13d10 20 65 6e 64 20 6f 66 20 65 61 63 68 20 72 65 63   end of each rec
13d20 6f 72 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  ord..**.** If th
13d30 65 20 73 6f 72 74 65 72 20 63 75 72 73 6f 72 20  e sorter cursor 
13d40 6b 65 79 20 63 6f 6e 74 61 69 6e 73 20 61 6e 79  key contains any
13d50 20 4e 55 4c 4c 20 76 61 6c 75 65 73 2c 20 63 6f   NULL values, co
13d60 6e 73 69 64 65 72 20 69 74 20 74 6f 20 62 65 0a  nsider it to be.
13d70 2a 2a 20 6c 65 73 73 20 74 68 61 6e 20 70 56 61  ** less than pVa
13d80 6c 2e 20 45 76 65 6e 20 69 66 20 70 56 61 6c 20  l. Even if pVal 
13d90 61 6c 73 6f 20 63 6f 6e 74 61 69 6e 73 20 4e 55  also contains NU
13da0 4c 4c 20 76 61 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a  LL values..**.**
13db0 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   If an error occ
13dc0 75 72 73 2c 20 72 65 74 75 72 6e 20 61 6e 20 53  urs, return an S
13dd0 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
13de0 20 28 69 2e 65 2e 20 53 51 4c 49 54 45 5f 4e 4f   (i.e. SQLITE_NO
13df0 4d 45 4d 29 2e 0a 2a 2a 20 4f 74 68 65 72 77 69  MEM)..** Otherwi
13e00 73 65 2c 20 73 65 74 20 2a 70 52 65 73 20 74 6f  se, set *pRes to
13e10 20 61 20 6e 65 67 61 74 69 76 65 2c 20 7a 65 72   a negative, zer
13e20 6f 20 6f 72 20 70 6f 73 69 74 69 76 65 20 76 61  o or positive va
13e30 6c 75 65 20 69 66 20 74 68 65 0a 2a 2a 20 6b 65  lue if the.** ke
13e40 79 20 69 6e 20 70 56 61 6c 20 69 73 20 73 6d 61  y in pVal is sma
13e50 6c 6c 65 72 20 74 68 61 6e 2c 20 65 71 75 61 6c  ller than, equal
13e60 20 74 6f 20 6f 72 20 6c 61 72 67 65 72 20 74 68   to or larger th
13e70 61 6e 20 74 68 65 20 63 75 72 72 65 6e 74 20 73  an the current s
13e80 6f 72 74 65 72 0a 2a 2a 20 6b 65 79 2e 0a 2a 2a  orter.** key..**
13e90 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
13ea0 20 66 6f 72 6d 73 20 74 68 65 20 63 6f 72 65 20   forms the core 
13eb0 6f 66 20 74 68 65 20 4f 50 5f 53 6f 72 74 65 72  of the OP_Sorter
13ec0 43 6f 6d 70 61 72 65 20 6f 70 63 6f 64 65 2c 20  Compare opcode, 
13ed0 77 68 69 63 68 20 69 6e 0a 2a 2a 20 74 75 72 6e  which in.** turn
13ee0 20 69 73 20 75 73 65 64 20 74 6f 20 76 65 72 69   is used to veri
13ef0 66 79 20 75 6e 69 71 75 65 6e 65 73 73 20 77 68  fy uniqueness wh
13f00 65 6e 20 63 6f 6e 73 74 72 75 63 74 69 6e 67 20  en constructing 
13f10 61 20 55 4e 49 51 55 45 20 49 4e 44 45 58 2e 0a  a UNIQUE INDEX..
13f20 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64  */.int sqlite3Vd
13f30 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28  beSorterCompare(
13f40 0a 20 20 63 6f 6e 73 74 20 56 64 62 65 43 75 72  .  const VdbeCur
13f50 73 6f 72 20 2a 70 43 73 72 2c 20 20 20 20 20 20  sor *pCsr,      
13f60 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 63 75 72     /* Sorter cur
13f70 73 6f 72 20 2a 2f 0a 20 20 4d 65 6d 20 2a 70 56  sor */.  Mem *pV
13f80 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
13f90 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75           /* Valu
13fa0 65 20 74 6f 20 63 6f 6d 70 61 72 65 20 74 6f 20  e to compare to 
13fb0 63 75 72 72 65 6e 74 20 73 6f 72 74 65 72 20 6b  current sorter k
13fc0 65 79 20 2a 2f 0a 20 20 69 6e 74 20 6e 49 67 6e  ey */.  int nIgn
13fd0 6f 72 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ore,            
13fe0 20 20 20 20 20 20 20 20 2f 2a 20 49 67 6e 6f 72          /* Ignor
13ff0 65 20 74 68 69 73 20 6d 61 6e 79 20 66 69 65 6c  e this many fiel
14000 64 73 20 61 74 20 74 68 65 20 65 6e 64 20 2a 2f  ds at the end */
14010 0a 20 20 69 6e 74 20 2a 70 52 65 73 20 20 20 20  .  int *pRes    
14020 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14030 20 20 20 2f 2a 20 4f 55 54 3a 20 52 65 73 75 6c     /* OUT: Resul
14040 74 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20  t of comparison 
14050 2a 2f 0a 29 7b 0a 20 20 56 64 62 65 53 6f 72 74  */.){.  VdbeSort
14060 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43  er *pSorter = pC
14070 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 55  sr->pSorter;.  U
14080 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20 2a 72  npackedRecord *r
14090 32 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e  2 = pSorter->pUn
140a0 70 61 63 6b 65 64 3b 0a 20 20 4b 65 79 49 6e 66  packed;.  KeyInf
140b0 6f 20 2a 70 4b 65 79 49 6e 66 6f 20 3d 20 70 43  o *pKeyInfo = pC
140c0 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 3b 0a 20 20  sr->pKeyInfo;.  
140d0 69 6e 74 20 69 3b 0a 20 20 76 6f 69 64 20 2a 70  int i;.  void *p
140e0 4b 65 79 3b 20 69 6e 74 20 6e 4b 65 79 3b 20 20  Key; int nKey;  
140f0 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74           /* Sort
14100 65 72 20 6b 65 79 20 74 6f 20 63 6f 6d 70 61 72  er key to compar
14110 65 20 70 56 61 6c 20 77 69 74 68 20 2a 2f 0a 0a  e pVal with */..
14120 20 20 69 66 28 20 72 32 3d 3d 30 20 29 7b 0a 20    if( r2==0 ){. 
14130 20 20 20 63 68 61 72 20 2a 70 3b 0a 20 20 20 20     char *p;.    
14140 72 32 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 55  r2 = pSorter->pU
14150 6e 70 61 63 6b 65 64 20 3d 20 73 71 6c 69 74 65  npacked = sqlite
14160 33 56 64 62 65 41 6c 6c 6f 63 55 6e 70 61 63 6b  3VdbeAllocUnpack
14170 65 64 52 65 63 6f 72 64 28 70 4b 65 79 49 6e 66  edRecord(pKeyInf
14180 6f 2c 30 2c 30 2c 26 70 29 3b 0a 20 20 20 20 61  o,0,0,&p);.    a
14190 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e  ssert( pSorter->
141a0 70 55 6e 70 61 63 6b 65 64 3d 3d 28 55 6e 70 61  pUnpacked==(Unpa
141b0 63 6b 65 64 52 65 63 6f 72 64 2a 29 70 20 29 3b  ckedRecord*)p );
141c0 0a 20 20 20 20 69 66 28 20 72 32 3d 3d 30 20 29  .    if( r2==0 )
141d0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
141e0 4f 4d 45 4d 3b 0a 20 20 20 20 72 32 2d 3e 6e 46  OMEM;.    r2->nF
141f0 69 65 6c 64 20 3d 20 70 4b 65 79 49 6e 66 6f 2d  ield = pKeyInfo-
14200 3e 6e 46 69 65 6c 64 2d 6e 49 67 6e 6f 72 65 3b  >nField-nIgnore;
14210 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28 20 72  .  }.  assert( r
14220 32 2d 3e 6e 46 69 65 6c 64 3e 3d 70 4b 65 79 49  2->nField>=pKeyI
14230 6e 66 6f 2d 3e 6e 46 69 65 6c 64 2d 6e 49 67 6e  nfo->nField-nIgn
14240 6f 72 65 20 29 3b 0a 0a 20 20 70 4b 65 79 20 3d  ore );..  pKey =
14250 20 76 64 62 65 53 6f 72 74 65 72 52 6f 77 6b 65   vdbeSorterRowke
14260 79 28 70 53 6f 72 74 65 72 2c 20 26 6e 4b 65 79  y(pSorter, &nKey
14270 29 3b 0a 20 20 73 71 6c 69 74 65 33 56 64 62 65  );.  sqlite3Vdbe
14280 52 65 63 6f 72 64 55 6e 70 61 63 6b 28 70 4b 65  RecordUnpack(pKe
14290 79 49 6e 66 6f 2c 20 6e 4b 65 79 2c 20 70 4b 65  yInfo, nKey, pKe
142a0 79 2c 20 72 32 29 3b 0a 20 20 66 6f 72 28 69 3d  y, r2);.  for(i=
142b0 30 3b 20 69 3c 72 32 2d 3e 6e 46 69 65 6c 64 3b  0; i<r2->nField;
142c0 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 72   i++){.    if( r
142d0 32 2d 3e 61 4d 65 6d 5b 69 5d 2e 66 6c 61 67 73  2->aMem[i].flags
142e0 20 26 20 4d 45 4d 5f 4e 75 6c 6c 20 29 7b 0a 20   & MEM_Null ){. 
142f0 20 20 20 20 20 2a 70 52 65 73 20 3d 20 2d 31 3b       *pRes = -1;
14300 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51  .      return SQ
14310 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20  LITE_OK;.    }. 
14320 20 7d 0a 0a 20 20 2a 70 52 65 73 20 3d 20 73 71   }..  *pRes = sq
14330 6c 69 74 65 33 56 64 62 65 52 65 63 6f 72 64 43  lite3VdbeRecordC
14340 6f 6d 70 61 72 65 28 70 56 61 6c 2d 3e 6e 2c 20  ompare(pVal->n, 
14350 70 56 61 6c 2d 3e 7a 2c 20 72 32 2c 20 30 29 3b  pVal->z, r2, 0);
14360 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
14370 5f 4f 4b 3b 0a 7d 0a                             _OK;.}.