/ Hex Artifact Content
Login

Artifact 6bcf73fb160ee5bb8ce8a8ec61fda268b081dbb7:


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 54 41 42 4c 45 20 73 74 61 74 65 6d  ATE TABLE 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 65 78 74 65 72 6e 61 6c 20 6d 65 72  s a external mer
02b0: 67 65 20 73 6f 72 74 0a 2a 2a 20 61 6c 67 6f 72  ge sort.** algor
02c0: 69 74 68 6d 20 74 68 61 74 20 69 73 20 65 66 66  ithm that is eff
02d0: 69 63 69 65 6e 74 20 65 76 65 6e 20 69 66 20 74  icient even if t
02e0: 68 65 20 61 67 67 72 65 67 61 74 65 20 73 69 7a  he aggregate siz
02f0: 65 20 6f 66 20 0a 2a 2a 20 74 68 65 20 65 6c 65  e of .** the ele
0300: 6d 65 6e 74 73 20 62 65 69 6e 67 20 73 6f 72 74  ments being sort
0310: 65 64 20 65 78 63 65 65 64 73 20 74 68 65 20 61  ed exceeds the a
0320: 76 61 69 6c 61 62 6c 65 20 6d 65 6d 6f 72 79 2e  vailable memory.
0330: 0a 2a 2a 0a 2a 2a 20 48 65 72 65 20 69 73 20 74  .**.** Here is t
0340: 68 65 20 28 69 6e 74 65 72 6e 61 6c 2c 20 6e 6f  he (internal, no
0350: 6e 2d 41 50 49 29 20 69 6e 74 65 72 66 61 63 65  n-API) interface
0360: 20 62 65 74 77 65 65 6e 20 74 68 69 73 20 6d 6f   between this mo
0370: 64 75 6c 65 20 61 6e 64 20 74 68 65 0a 2a 2a 20  dule and the.** 
0380: 72 65 73 74 20 6f 66 20 74 68 65 20 53 51 4c 69  rest of the SQLi
0390: 74 65 20 73 79 73 74 65 6d 3a 0a 2a 2a 0a 2a 2a  te system:.**.**
03a0: 20 20 20 20 73 71 6c 69 74 65 33 56 64 62 65 53      sqlite3VdbeS
03b0: 6f 72 74 65 72 49 6e 69 74 28 29 20 20 20 20 20  orterInit()     
03c0: 20 20 43 72 65 61 74 65 20 61 20 6e 65 77 20 56    Create a new V
03d0: 64 62 65 53 6f 72 74 65 72 20 6f 62 6a 65 63 74  dbeSorter object
03e0: 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71 6c 69 74  ..**.**    sqlit
03f0: 65 33 56 64 62 65 53 6f 72 74 65 72 57 72 69 74  e3VdbeSorterWrit
0400: 65 28 29 20 20 20 20 20 20 41 64 64 20 61 20 73  e()      Add a s
0410: 69 6e 67 6c 65 20 6e 65 77 20 72 6f 77 20 74 6f  ingle new row to
0420: 20 74 68 65 20 56 64 62 65 53 6f 72 74 65 72 0a   the VdbeSorter.
0430: 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  **              
0440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0450: 20 20 20 20 6f 62 6a 65 63 74 2e 20 20 54 68 65      object.  The
0460: 20 72 6f 77 20 69 73 20 61 20 62 69 6e 61 72 79   row is a binary
0470: 20 62 6c 6f 62 20 69 6e 20 74 68 65 0a 2a 2a 20   blob in the.** 
0480: 20 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 4f 50 5f 4d 61 6b 65 52 65 63 6f 72 64 20 66   OP_MakeRecord f
04b0: 6f 72 6d 61 74 20 74 68 61 74 20 63 6f 6e 74 61  ormat that conta
04c0: 69 6e 73 20 62 6f 74 68 0a 2a 2a 20 20 20 20 20  ins 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 74 68 65               the
04f0: 20 4f 52 44 45 52 20 42 59 20 6b 65 79 20 63 6f   ORDER BY key co
0500: 6c 75 6d 6e 73 20 61 6e 64 20 72 65 73 75 6c 74  lumns and result
0510: 20 63 6f 6c 75 6d 6e 73 0a 2a 2a 20 20 20 20 20   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 69 6e 20               in 
0540: 74 68 65 20 63 61 73 65 20 6f 66 20 61 20 53 45  the case of a SE
0550: 4c 45 43 54 20 77 2f 20 4f 52 44 45 52 20 42 59  LECT w/ ORDER BY
0560: 2c 20 6f 72 0a 2a 2a 20 20 20 20 20 20 20 20 20  , 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 74 68 65 20 63 6f 6d           the com
0590: 70 6c 65 74 65 20 72 65 63 6f 72 64 20 66 6f 72  plete record for
05a0: 20 61 6e 20 69 6e 64 65 78 20 65 6e 74 72 79 0a   an index entry.
05b0: 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  **              
05c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05d0: 20 20 20 20 69 6e 20 74 68 65 20 63 61 73 65 20      in the case 
05e0: 6f 66 20 61 20 43 52 45 41 54 45 20 49 4e 44 45  of a CREATE INDE
05f0: 58 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71 6c 69  X..**.**    sqli
0600: 74 65 33 56 64 62 65 53 6f 72 74 65 72 52 65 77  te3VdbeSorterRew
0610: 69 6e 64 28 29 20 20 20 20 20 53 6f 72 74 20 61  ind()     Sort a
0620: 6c 6c 20 63 6f 6e 74 65 6e 74 20 70 72 65 76 69  ll content previ
0630: 6f 75 73 6c 79 20 61 64 64 65 64 2e 0a 2a 2a 20  ously added..** 
0640: 20 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 50 6f 73 69 74 69 6f 6e 20 74 68 65 20 72 65   Position the re
0670: 61 64 20 63 75 72 73 6f 72 20 6f 6e 20 74 68 65  ad cursor on the
0680: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20  .**             
0690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06a0: 20 20 20 20 20 66 69 72 73 74 20 73 6f 72 74 65       first sorte
06b0: 64 20 65 6c 65 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a  d element..**.**
06c0: 20 20 20 20 73 71 6c 69 74 65 33 56 64 62 65 53      sqlite3VdbeS
06d0: 6f 72 74 65 72 4e 65 78 74 28 29 20 20 20 20 20  orterNext()     
06e0: 20 20 41 64 76 61 6e 63 65 20 74 68 65 20 72 65    Advance the re
06f0: 61 64 20 63 75 72 73 6f 72 20 74 6f 20 74 68 65  ad cursor to the
0700: 20 6e 65 78 74 20 73 6f 72 74 65 64 0a 2a 2a 20   next sorted.** 
0710: 20 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 65 6c 65 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20   element..**.** 
0740: 20 20 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f     sqlite3VdbeSo
0750: 72 74 65 72 52 6f 77 6b 65 79 28 29 20 20 20 20  rterRowkey()    
0760: 20 52 65 74 75 72 6e 20 74 68 65 20 63 6f 6d 70   Return the comp
0770: 6c 65 74 65 20 62 69 6e 61 72 79 20 62 6c 6f 62  lete binary blob
0780: 20 66 6f 72 20 74 68 65 0a 2a 2a 20 20 20 20 20   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 72 6f 77               row
07b0: 20 63 75 72 72 65 6e 74 6c 79 20 75 6e 64 65 72   currently under
07c0: 20 74 68 65 20 72 65 61 64 20 63 75 72 73 6f 72   the read cursor
07d0: 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71 6c 69 74  ..**.**    sqlit
07e0: 65 33 56 64 62 65 53 6f 72 74 65 72 43 6f 6d 70  e3VdbeSorterComp
07f0: 61 72 65 28 29 20 20 20 20 43 6f 6d 70 61 72 65  are()    Compare
0800: 20 74 68 65 20 62 69 6e 61 72 79 20 62 6c 6f 62   the binary blob
0810: 20 66 6f 72 20 74 68 65 20 72 6f 77 0a 2a 2a 20   for the row.** 
0820: 20 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 63 75 72 72 65 6e 74 6c 79 20 75 6e 64 65 72   currently under
0850: 20 74 68 65 20 72 65 61 64 20 63 75 72 73 6f 72   the read cursor
0860: 20 61 67 61 69 6e 73 74 0a 2a 2a 20 20 20 20 20   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 61 6e 6f               ano
0890: 74 68 65 72 20 62 69 6e 61 72 79 20 62 6c 6f 62  ther binary blob
08a0: 20 58 20 61 6e 64 20 72 65 70 6f 72 74 20 69 66   X and report if
08b0: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20  .**             
08c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08d0: 20 20 20 20 20 58 20 69 73 20 73 74 72 69 63 74       X is strict
08e0: 6c 79 20 6c 65 73 73 20 74 68 61 6e 20 74 68 65  ly less than the
08f0: 20 72 65 61 64 20 63 75 72 73 6f 72 2e 0a 2a 2a   read cursor..**
0900: 20 20 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 55 73 65 64 20 74 6f 20 65 6e 66 6f 72 63    Used to enforc
0930: 65 20 75 6e 69 71 75 65 6e 65 73 73 20 69 6e 20  e uniqueness in 
0940: 61 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20  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 43 52 45 41 54 45 20 55 4e 49        CREATE UNI
0970: 51 55 45 20 49 4e 44 45 58 20 73 74 61 74 65 6d  QUE INDEX statem
0980: 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71  ent..**.**    sq
0990: 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 43  lite3VdbeSorterC
09a0: 6c 6f 73 65 28 29 20 20 20 20 20 20 43 6c 6f 73  lose()      Clos
09b0: 65 20 74 68 65 20 56 64 62 65 53 6f 72 74 65 72  e the VdbeSorter
09c0: 20 6f 62 6a 65 63 74 20 61 6e 64 20 72 65 63 6c   object and recl
09d0: 61 69 6d 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  aim.**          
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 61 6c 6c 20 72 65 73 6f          all reso
0a00: 75 72 63 65 73 2e 0a 2a 2a 0a 2a 2a 20 20 20 20  urces..**.**    
0a10: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
0a20: 72 52 65 73 65 74 28 29 20 20 20 20 20 20 52 65  rReset()      Re
0a30: 66 75 72 62 69 73 68 20 74 68 65 20 56 64 62 65  furbish the Vdbe
0a40: 53 6f 72 74 65 72 20 66 6f 72 20 72 65 75 73 65  Sorter for reuse
0a50: 2e 20 20 54 68 69 73 0a 2a 2a 20 20 20 20 20 20  .  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 69 73 20 6c              is l
0a80: 69 6b 65 20 43 6c 6f 73 65 28 29 20 66 6f 6c 6c  ike Close() foll
0a90: 6f 77 65 64 20 62 79 20 49 6e 69 74 28 29 20 6f  owed by Init() o
0aa0: 6e 6c 79 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  nly.**          
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 6d 75 63 68 20 66 61 73          much fas
0ad0: 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 69  ter..**.** The i
0ae0: 6e 74 65 72 66 61 63 65 73 20 61 62 6f 76 65 20  nterfaces above 
0af0: 6d 75 73 74 20 62 65 20 63 61 6c 6c 65 64 20 69  must be called i
0b00: 6e 20 61 20 70 61 72 74 69 63 75 6c 61 72 20 6f  n a particular o
0b10: 72 64 65 72 2e 20 20 57 72 69 74 65 28 29 20 63  rder.  Write() c
0b20: 61 6e 20 0a 2a 2a 20 6f 6e 6c 79 20 6f 63 63 75  an .** only occu
0b30: 72 20 69 6e 20 62 65 74 77 65 65 6e 20 49 6e 69  r in between Ini
0b40: 74 28 29 2f 52 65 73 65 74 28 29 20 61 6e 64 20  t()/Reset() and 
0b50: 52 65 77 69 6e 64 28 29 2e 20 20 4e 65 78 74 28  Rewind().  Next(
0b60: 29 2c 20 52 6f 77 6b 65 79 28 29 2c 20 61 6e 64  ), Rowkey(), and
0b70: 0a 2a 2a 20 43 6f 6d 70 61 72 65 28 29 20 63 61  .** Compare() ca
0b80: 6e 20 6f 6e 6c 79 20 6f 63 63 75 72 20 69 6e 20  n only occur in 
0b90: 62 65 74 77 65 65 6e 20 52 65 77 69 6e 64 28 29  between Rewind()
0ba0: 20 61 6e 64 20 43 6c 6f 73 65 28 29 2f 52 65 73   and Close()/Res
0bb0: 65 74 28 29 2e 0a 2a 2a 0a 2a 2f 0a 0a 23 69 6e  et()..**.*/..#in
0bc0: 63 6c 75 64 65 20 22 73 71 6c 69 74 65 49 6e 74  clude "sqliteInt
0bd0: 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 76 64  .h".#include "vd
0be0: 62 65 49 6e 74 2e 68 22 0a 0a 0a 74 79 70 65 64  beInt.h"...typed
0bf0: 65 66 20 73 74 72 75 63 74 20 56 64 62 65 53 6f  ef struct VdbeSo
0c00: 72 74 65 72 49 74 65 72 20 56 64 62 65 53 6f 72  rterIter VdbeSor
0c10: 74 65 72 49 74 65 72 3b 0a 74 79 70 65 64 65 66  terIter;.typedef
0c20: 20 73 74 72 75 63 74 20 53 6f 72 74 65 72 52 65   struct SorterRe
0c30: 63 6f 72 64 20 53 6f 72 74 65 72 52 65 63 6f 72  cord SorterRecor
0c40: 64 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  d;.typedef struc
0c50: 74 20 46 69 6c 65 57 72 69 74 65 72 20 46 69 6c  t FileWriter Fil
0c60: 65 57 72 69 74 65 72 3b 0a 0a 2f 2a 0a 2a 2a 20  eWriter;../*.** 
0c70: 4e 4f 54 45 53 20 4f 4e 20 44 41 54 41 20 53 54  NOTES ON DATA ST
0c80: 52 55 43 54 55 52 45 20 55 53 45 44 20 46 4f 52  RUCTURE USED FOR
0c90: 20 4e 2d 57 41 59 20 4d 45 52 47 45 53 3a 0a 2a   N-WAY MERGES:.*
0ca0: 2a 0a 2a 2a 20 41 73 20 6b 65 79 73 20 61 72 65  *.** As keys are
0cb0: 20 61 64 64 65 64 20 74 6f 20 74 68 65 20 73 6f   added to the so
0cc0: 72 74 65 72 2c 20 74 68 65 79 20 61 72 65 20 77  rter, they are w
0cd0: 72 69 74 74 65 6e 20 74 6f 20 64 69 73 6b 20 69  ritten to disk i
0ce0: 6e 20 61 20 73 65 72 69 65 73 0a 2a 2a 20 6f 66  n a series.** of
0cf0: 20 73 6f 72 74 65 64 20 70 61 63 6b 65 64 2d 6d   sorted packed-m
0d00: 65 6d 6f 72 79 2d 61 72 72 61 79 73 20 28 50 4d  emory-arrays (PM
0d10: 41 73 29 2e 20 54 68 65 20 73 69 7a 65 20 6f 66  As). The size of
0d20: 20 65 61 63 68 20 50 4d 41 20 69 73 20 72 6f 75   each PMA is rou
0d30: 67 68 6c 79 0a 2a 2a 20 74 68 65 20 73 61 6d 65  ghly.** the same
0d40: 20 61 73 20 74 68 65 20 63 61 63 68 65 2d 73 69   as the cache-si
0d50: 7a 65 20 61 6c 6c 6f 77 65 64 20 66 6f 72 20 74  ze allowed for t
0d60: 65 6d 70 6f 72 61 72 79 20 64 61 74 61 62 61 73  emporary databas
0d70: 65 73 2e 20 49 6e 20 6f 72 64 65 72 0a 2a 2a 20  es. In order.** 
0d80: 74 6f 20 61 6c 6c 6f 77 20 74 68 65 20 63 61 6c  to allow the cal
0d90: 6c 65 72 20 74 6f 20 65 78 74 72 61 63 74 20 6b  ler to extract k
0da0: 65 79 73 20 66 72 6f 6d 20 74 68 65 20 73 6f 72  eys from the sor
0db0: 74 65 72 20 69 6e 20 73 6f 72 74 65 64 20 6f 72  ter in sorted or
0dc0: 64 65 72 2c 0a 2a 2a 20 61 6c 6c 20 50 4d 41 73  der,.** all PMAs
0dd0: 20 63 75 72 72 65 6e 74 6c 79 20 73 74 6f 72 65   currently store
0de0: 64 20 6f 6e 20 64 69 73 6b 20 6d 75 73 74 20 62  d on disk must b
0df0: 65 20 6d 65 72 67 65 64 20 74 6f 67 65 74 68 65  e merged togethe
0e00: 72 2e 20 54 68 69 73 20 63 6f 6d 6d 65 6e 74 0a  r. This comment.
0e10: 2a 2a 20 64 65 73 63 72 69 62 65 73 20 74 68 65  ** describes the
0e20: 20 64 61 74 61 20 73 74 72 75 63 74 75 72 65 20   data structure 
0e30: 75 73 65 64 20 74 6f 20 64 6f 20 73 6f 2e 20 54  used to do so. T
0e40: 68 65 20 73 74 72 75 63 74 75 72 65 20 73 75 70  he structure sup
0e50: 70 6f 72 74 73 20 0a 2a 2a 20 6d 65 72 67 69 6e  ports .** mergin
0e60: 67 20 61 6e 79 20 6e 75 6d 62 65 72 20 6f 66 20  g any number of 
0e70: 61 72 72 61 79 73 20 69 6e 20 61 20 73 69 6e 67  arrays in a sing
0e80: 6c 65 20 70 61 73 73 20 77 69 74 68 20 6e 6f 20  le pass with no 
0e90: 72 65 64 75 6e 64 61 6e 74 20 63 6f 6d 70 61 72  redundant compar
0ea0: 69 73 6f 6e 20 0a 2a 2a 20 6f 70 65 72 61 74 69  ison .** operati
0eb0: 6f 6e 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61  ons..**.** The a
0ec0: 49 74 65 72 5b 5d 20 61 72 72 61 79 20 63 6f 6e  Iter[] array con
0ed0: 74 61 69 6e 73 20 61 6e 20 69 74 65 72 61 74 6f  tains an iterato
0ee0: 72 20 66 6f 72 20 65 61 63 68 20 6f 66 20 74 68  r for each of th
0ef0: 65 20 50 4d 41 73 20 62 65 69 6e 67 20 6d 65 72  e PMAs being mer
0f00: 67 65 64 2e 0a 2a 2a 20 41 6e 20 61 49 74 65 72  ged..** An aIter
0f10: 5b 5d 20 69 74 65 72 61 74 6f 72 20 65 69 74 68  [] iterator eith
0f20: 65 72 20 70 6f 69 6e 74 73 20 74 6f 20 61 20 76  er points to a v
0f30: 61 6c 69 64 20 6b 65 79 20 6f 72 20 65 6c 73 65  alid key or else
0f40: 20 69 73 20 61 74 20 45 4f 46 2e 20 46 6f 72 20   is at EOF. For 
0f50: 0a 2a 2a 20 74 68 65 20 70 75 72 70 6f 73 65 73  .** the purposes
0f60: 20 6f 66 20 74 68 65 20 70 61 72 61 67 72 61 70   of the paragrap
0f70: 68 73 20 62 65 6c 6f 77 2c 20 77 65 20 61 73 73  hs below, we ass
0f80: 75 6d 65 20 74 68 61 74 20 74 68 65 20 61 72 72  ume that the arr
0f90: 61 79 20 69 73 20 61 63 74 75 61 6c 6c 79 20 0a  ay is actually .
0fa0: 2a 2a 20 4e 20 65 6c 65 6d 65 6e 74 73 20 69 6e  ** N elements in
0fb0: 20 73 69 7a 65 2c 20 77 68 65 72 65 20 4e 20 69   size, where N i
0fc0: 73 20 74 68 65 20 73 6d 61 6c 6c 65 73 74 20 70  s the smallest p
0fd0: 6f 77 65 72 20 6f 66 20 32 20 67 72 65 61 74 65  ower of 2 greate
0fe0: 72 20 74 6f 20 6f 72 20 65 71 75 61 6c 20 0a 2a  r to or equal .*
0ff0: 2a 20 74 6f 20 74 68 65 20 6e 75 6d 62 65 72 20  * to the number 
1000: 6f 66 20 69 74 65 72 61 74 6f 72 73 20 62 65 69  of iterators bei
1010: 6e 67 20 6d 65 72 67 65 64 2e 20 54 68 65 20 65  ng merged. The e
1020: 78 74 72 61 20 61 49 74 65 72 5b 5d 20 65 6c 65  xtra aIter[] ele
1030: 6d 65 6e 74 73 20 61 72 65 20 0a 2a 2a 20 74 72  ments are .** tr
1040: 65 61 74 65 64 20 61 73 20 69 66 20 74 68 65 79  eated as if they
1050: 20 61 72 65 20 65 6d 70 74 79 20 28 61 6c 77 61   are empty (alwa
1060: 79 73 20 61 74 20 45 4f 46 29 2e 0a 2a 2a 0a 2a  ys at EOF)..**.*
1070: 2a 20 54 68 65 20 61 54 72 65 65 5b 5d 20 61 72  * The aTree[] ar
1080: 72 61 79 20 69 73 20 61 6c 73 6f 20 4e 20 65 6c  ray is also N el
1090: 65 6d 65 6e 74 73 20 69 6e 20 73 69 7a 65 2e 20  ements in size. 
10a0: 54 68 65 20 76 61 6c 75 65 20 6f 66 20 4e 20 69  The value of N i
10b0: 73 20 73 74 6f 72 65 64 20 69 6e 0a 2a 2a 20 74  s stored in.** t
10c0: 68 65 20 56 64 62 65 53 6f 72 74 65 72 2e 6e 54  he VdbeSorter.nT
10d0: 72 65 65 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2a  ree variable..**
10e0: 0a 2a 2a 20 54 68 65 20 66 69 6e 61 6c 20 28 4e  .** The final (N
10f0: 2f 32 29 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20  /2) elements of 
1100: 61 54 72 65 65 5b 5d 20 63 6f 6e 74 61 69 6e 20  aTree[] contain 
1110: 74 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20 63  the results of c
1120: 6f 6d 70 61 72 69 6e 67 0a 2a 2a 20 70 61 69 72  omparing.** pair
1130: 73 20 6f 66 20 69 74 65 72 61 74 6f 72 20 6b 65  s of iterator ke
1140: 79 73 20 74 6f 67 65 74 68 65 72 2e 20 45 6c 65  ys together. Ele
1150: 6d 65 6e 74 20 69 20 63 6f 6e 74 61 69 6e 73 20  ment i contains 
1160: 74 68 65 20 72 65 73 75 6c 74 20 6f 66 20 0a 2a  the result of .*
1170: 2a 20 63 6f 6d 70 61 72 69 6e 67 20 61 49 74 65  * comparing aIte
1180: 72 5b 32 2a 69 2d 4e 5d 20 61 6e 64 20 61 49 74  r[2*i-N] and aIt
1190: 65 72 5b 32 2a 69 2d 4e 2b 31 5d 2e 20 57 68 69  er[2*i-N+1]. Whi
11a0: 63 68 65 76 65 72 20 6b 65 79 20 69 73 20 73 6d  chever key is sm
11b0: 61 6c 6c 65 72 2c 20 74 68 65 0a 2a 2a 20 61 54  aller, the.** aT
11c0: 72 65 65 20 65 6c 65 6d 65 6e 74 20 69 73 20 73  ree element is s
11d0: 65 74 20 74 6f 20 74 68 65 20 69 6e 64 65 78 20  et to the index 
11e0: 6f 66 20 69 74 2e 20 0a 2a 2a 0a 2a 2a 20 46 6f  of it. .**.** Fo
11f0: 72 20 74 68 65 20 70 75 72 70 6f 73 65 73 20 6f  r the purposes o
1200: 66 20 74 68 69 73 20 63 6f 6d 70 61 72 69 73 6f  f this compariso
1210: 6e 2c 20 45 4f 46 20 69 73 20 63 6f 6e 73 69 64  n, EOF is consid
1220: 65 72 65 64 20 67 72 65 61 74 65 72 20 74 68 61  ered greater tha
1230: 6e 20 61 6e 79 0a 2a 2a 20 6f 74 68 65 72 20 6b  n any.** other k
1240: 65 79 20 76 61 6c 75 65 2e 20 49 66 20 74 68 65  ey value. If the
1250: 20 6b 65 79 73 20 61 72 65 20 65 71 75 61 6c 20   keys are equal 
1260: 28 6f 6e 6c 79 20 70 6f 73 73 69 62 6c 65 20 77  (only possible w
1270: 69 74 68 20 74 77 6f 20 45 4f 46 0a 2a 2a 20 76  ith two EOF.** v
1280: 61 6c 75 65 73 29 2c 20 69 74 20 64 6f 65 73 6e  alues), it doesn
1290: 27 74 20 6d 61 74 74 65 72 20 77 68 69 63 68 20  't matter which 
12a0: 69 6e 64 65 78 20 69 73 20 73 74 6f 72 65 64 2e  index is stored.
12b0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 28 4e 2f 34 29  .**.** The (N/4)
12c0: 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20 61 54 72   elements of aTr
12d0: 65 65 5b 5d 20 74 68 61 74 20 70 72 65 63 65 64  ee[] that preced
12e0: 65 20 74 68 65 20 66 69 6e 61 6c 20 28 4e 2f 32  e the final (N/2
12f0: 29 20 64 65 73 63 72 69 62 65 64 20 0a 2a 2a 20  ) described .** 
1300: 61 62 6f 76 65 20 63 6f 6e 74 61 69 6e 73 20 74  above contains t
1310: 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20  he index of the 
1320: 73 6d 61 6c 6c 65 73 74 20 6f 66 20 65 61 63 68  smallest of each
1330: 20 62 6c 6f 63 6b 20 6f 66 20 34 20 69 74 65 72   block of 4 iter
1340: 61 74 6f 72 73 2e 0a 2a 2a 20 41 6e 64 20 73 6f  ators..** And so
1350: 20 6f 6e 2e 20 53 6f 20 74 68 61 74 20 61 54 72   on. So that aTr
1360: 65 65 5b 31 5d 20 63 6f 6e 74 61 69 6e 73 20 74  ee[1] contains t
1370: 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20  he index of the 
1380: 69 74 65 72 61 74 6f 72 20 74 68 61 74 20 0a 2a  iterator that .*
1390: 2a 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e  * currently poin
13a0: 74 73 20 74 6f 20 74 68 65 20 73 6d 61 6c 6c 65  ts to the smalle
13b0: 73 74 20 6b 65 79 20 76 61 6c 75 65 2e 20 61 54  st key value. aT
13c0: 72 65 65 5b 30 5d 20 69 73 20 75 6e 75 73 65 64  ree[0] is unused
13d0: 2e 0a 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65 3a  ..**.** Example:
13e0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 49 74 65 72  .**.**     aIter
13f0: 5b 30 5d 20 2d 3e 20 42 61 6e 61 6e 61 0a 2a 2a  [0] -> Banana.**
1400: 20 20 20 20 20 61 49 74 65 72 5b 31 5d 20 2d 3e       aIter[1] ->
1410: 20 46 65 69 6a 6f 61 0a 2a 2a 20 20 20 20 20 61   Feijoa.**     a
1420: 49 74 65 72 5b 32 5d 20 2d 3e 20 45 6c 64 65 72  Iter[2] -> Elder
1430: 62 65 72 72 79 0a 2a 2a 20 20 20 20 20 61 49 74  berry.**     aIt
1440: 65 72 5b 33 5d 20 2d 3e 20 43 75 72 72 61 6e 74  er[3] -> Currant
1450: 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 34 5d  .**     aIter[4]
1460: 20 2d 3e 20 47 72 61 70 65 66 72 75 69 74 0a 2a   -> Grapefruit.*
1470: 2a 20 20 20 20 20 61 49 74 65 72 5b 35 5d 20 2d  *     aIter[5] -
1480: 3e 20 41 70 70 6c 65 0a 2a 2a 20 20 20 20 20 61  > Apple.**     a
1490: 49 74 65 72 5b 36 5d 20 2d 3e 20 44 75 72 69 61  Iter[6] -> Duria
14a0: 6e 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 37  n.**     aIter[7
14b0: 5d 20 2d 3e 20 45 4f 46 0a 2a 2a 0a 2a 2a 20 20  ] -> EOF.**.**  
14c0: 20 20 20 61 54 72 65 65 5b 5d 20 3d 20 7b 20 58     aTree[] = { X
14d0: 2c 20 35 20 20 20 30 2c 20 35 20 20 20 20 30 2c  , 5   0, 5    0,
14e0: 20 33 2c 20 35 2c 20 36 20 7d 0a 2a 2a 0a 2a 2a   3, 5, 6 }.**.**
14f0: 20 54 68 65 20 63 75 72 72 65 6e 74 20 65 6c 65   The current ele
1500: 6d 65 6e 74 20 69 73 20 22 41 70 70 6c 65 22 20  ment is "Apple" 
1510: 28 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68  (the value of th
1520: 65 20 6b 65 79 20 69 6e 64 69 63 61 74 65 64 20  e key indicated 
1530: 62 79 20 0a 2a 2a 20 69 74 65 72 61 74 6f 72 20  by .** iterator 
1540: 35 29 2e 20 57 68 65 6e 20 74 68 65 20 4e 65 78  5). When the Nex
1550: 74 28 29 20 6f 70 65 72 61 74 69 6f 6e 20 69 73  t() operation is
1560: 20 69 6e 76 6f 6b 65 64 2c 20 69 74 65 72 61 74   invoked, iterat
1570: 6f 72 20 35 20 77 69 6c 6c 0a 2a 2a 20 62 65 20  or 5 will.** be 
1580: 61 64 76 61 6e 63 65 64 20 74 6f 20 74 68 65 20  advanced to the 
1590: 6e 65 78 74 20 6b 65 79 20 69 6e 20 69 74 73 20  next key in its 
15a0: 73 65 67 6d 65 6e 74 2e 20 53 61 79 20 74 68 65  segment. Say the
15b0: 20 6e 65 78 74 20 6b 65 79 20 69 73 0a 2a 2a 20   next key is.** 
15c0: 22 45 67 67 70 6c 61 6e 74 22 3a 0a 2a 2a 0a 2a  "Eggplant":.**.*
15d0: 2a 20 20 20 20 20 61 49 74 65 72 5b 35 5d 20 2d  *     aIter[5] -
15e0: 3e 20 45 67 67 70 6c 61 6e 74 0a 2a 2a 0a 2a 2a  > Eggplant.**.**
15f0: 20 54 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   The contents of
1600: 20 61 54 72 65 65 5b 5d 20 61 72 65 20 75 70 64   aTree[] are upd
1610: 61 74 65 64 20 66 69 72 73 74 20 62 79 20 63 6f  ated first by co
1620: 6d 70 61 72 69 6e 67 20 74 68 65 20 6e 65 77 20  mparing the new 
1630: 69 74 65 72 61 74 6f 72 0a 2a 2a 20 35 20 6b 65  iterator.** 5 ke
1640: 79 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e 74  y to the current
1650: 20 6b 65 79 20 6f 66 20 69 74 65 72 61 74 6f 72   key of iterator
1660: 20 34 20 28 73 74 69 6c 6c 20 22 47 72 61 70 65   4 (still "Grape
1670: 66 72 75 69 74 22 29 2e 20 54 68 65 20 69 74 65  fruit"). The ite
1680: 72 61 74 6f 72 0a 2a 2a 20 35 20 76 61 6c 75 65  rator.** 5 value
1690: 20 69 73 20 73 74 69 6c 6c 20 73 6d 61 6c 6c 65   is still smalle
16a0: 72 2c 20 73 6f 20 61 54 72 65 65 5b 36 5d 20 69  r, so aTree[6] i
16b0: 73 20 73 65 74 20 74 6f 20 35 2e 20 41 6e 64 20  s set to 5. And 
16c0: 73 6f 20 6f 6e 20 75 70 20 74 68 65 20 74 72 65  so on up the tre
16d0: 65 2e 0a 2a 2a 20 54 68 65 20 76 61 6c 75 65 20  e..** The value 
16e0: 6f 66 20 69 74 65 72 61 74 6f 72 20 36 20 2d 20  of iterator 6 - 
16f0: 22 44 75 72 69 61 6e 22 20 2d 20 69 73 20 6e 6f  "Durian" - is no
1700: 77 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 74  w smaller than t
1710: 68 61 74 20 6f 66 20 69 74 65 72 61 74 6f 72 0a  hat of iterator.
1720: 2a 2a 20 35 2c 20 73 6f 20 61 54 72 65 65 5b 33  ** 5, so aTree[3
1730: 5d 20 69 73 20 73 65 74 20 74 6f 20 36 2e 20 4b  ] is set to 6. K
1740: 65 79 20 30 20 69 73 20 73 6d 61 6c 6c 65 72 20  ey 0 is smaller 
1750: 74 68 61 6e 20 6b 65 79 20 36 20 28 42 61 6e 61  than key 6 (Bana
1760: 6e 61 3c 44 75 72 69 61 6e 29 2c 0a 2a 2a 20 73  na<Durian),.** s
1770: 6f 20 74 68 65 20 76 61 6c 75 65 20 77 72 69 74  o the value writ
1780: 74 65 6e 20 69 6e 74 6f 20 65 6c 65 6d 65 6e 74  ten into element
1790: 20 31 20 6f 66 20 74 68 65 20 61 72 72 61 79 20   1 of the array 
17a0: 69 73 20 30 2e 20 41 73 20 66 6f 6c 6c 6f 77 73  is 0. As follows
17b0: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 54 72 65  :.**.**     aTre
17c0: 65 5b 5d 20 3d 20 7b 20 58 2c 20 30 20 20 20 30  e[] = { X, 0   0
17d0: 2c 20 36 20 20 20 20 30 2c 20 33 2c 20 35 2c 20  , 6    0, 3, 5, 
17e0: 36 20 7d 0a 2a 2a 0a 2a 2a 20 49 6e 20 6f 74 68  6 }.**.** In oth
17f0: 65 72 20 77 6f 72 64 73 2c 20 65 61 63 68 20 74  er words, each t
1800: 69 6d 65 20 77 65 20 61 64 76 61 6e 63 65 20 74  ime we advance t
1810: 6f 20 74 68 65 20 6e 65 78 74 20 73 6f 72 74 65  o the next sorte
1820: 72 20 65 6c 65 6d 65 6e 74 2c 20 6c 6f 67 32 28  r element, log2(
1830: 4e 29 0a 2a 2a 20 6b 65 79 20 63 6f 6d 70 61 72  N).** key compar
1840: 69 73 6f 6e 20 6f 70 65 72 61 74 69 6f 6e 73 20  ison operations 
1850: 61 72 65 20 72 65 71 75 69 72 65 64 2c 20 77 68  are required, wh
1860: 65 72 65 20 4e 20 69 73 20 74 68 65 20 6e 75 6d  ere N is the num
1870: 62 65 72 20 6f 66 20 73 65 67 6d 65 6e 74 73 0a  ber of segments.
1880: 2a 2a 20 62 65 69 6e 67 20 6d 65 72 67 65 64 20  ** being merged 
1890: 28 72 6f 75 6e 64 65 64 20 75 70 20 74 6f 20 74  (rounded up to t
18a0: 68 65 20 6e 65 78 74 20 70 6f 77 65 72 20 6f 66  he next power of
18b0: 20 32 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 56   2)..*/.struct V
18c0: 64 62 65 53 6f 72 74 65 72 20 7b 0a 20 20 69 36  dbeSorter {.  i6
18d0: 34 20 69 57 72 69 74 65 4f 66 66 3b 20 20 20 20  4 iWriteOff;    
18e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
18f0: 20 43 75 72 72 65 6e 74 20 77 72 69 74 65 20 6f   Current write o
1900: 66 66 73 65 74 20 77 69 74 68 69 6e 20 66 69 6c  ffset within fil
1910: 65 20 70 54 65 6d 70 31 20 2a 2f 0a 20 20 69 36  e pTemp1 */.  i6
1920: 34 20 69 52 65 61 64 4f 66 66 3b 20 20 20 20 20  4 iReadOff;     
1930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1940: 20 43 75 72 72 65 6e 74 20 72 65 61 64 20 6f 66   Current read of
1950: 66 73 65 74 20 77 69 74 68 69 6e 20 66 69 6c 65  fset within file
1960: 20 70 54 65 6d 70 31 20 2a 2f 0a 20 20 69 6e 74   pTemp1 */.  int
1970: 20 6e 49 6e 4d 65 6d 6f 72 79 3b 20 20 20 20 20   nInMemory;     
1980: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1990: 43 75 72 72 65 6e 74 20 73 69 7a 65 20 6f 66 20  Current size of 
19a0: 70 52 65 63 6f 72 64 20 6c 69 73 74 20 61 73 20  pRecord list as 
19b0: 50 4d 41 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 72  PMA */.  int nTr
19c0: 65 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ee;             
19d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64           /* Used
19e0: 20 73 69 7a 65 20 6f 66 20 61 54 72 65 65 2f 61   size of aTree/a
19f0: 49 74 65 72 20 28 70 6f 77 65 72 20 6f 66 20 32  Iter (power of 2
1a00: 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 4d 41 3b  ) */.  int nPMA;
1a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a20: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
1a30: 20 6f 66 20 50 4d 41 73 20 73 74 6f 72 65 64 20   of PMAs stored 
1a40: 69 6e 20 70 54 65 6d 70 31 20 2a 2f 0a 20 20 69  in pTemp1 */.  i
1a50: 6e 74 20 6d 6e 50 6d 61 53 69 7a 65 3b 20 20 20  nt mnPmaSize;   
1a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1a70: 2a 20 4d 69 6e 69 6d 75 6d 20 50 4d 41 20 73 69  * Minimum PMA si
1a80: 7a 65 2c 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  ze, in bytes */.
1a90: 20 20 69 6e 74 20 6d 78 50 6d 61 53 69 7a 65 3b    int mxPmaSize;
1aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ab0: 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 50 4d 41    /* Maximum PMA
1ac0: 20 73 69 7a 65 2c 20 69 6e 20 62 79 74 65 73 2e   size, in bytes.
1ad0: 20 20 30 3d 3d 6e 6f 20 6c 69 6d 69 74 20 2a 2f    0==no limit */
1ae0: 0a 20 20 56 64 62 65 53 6f 72 74 65 72 49 74 65  .  VdbeSorterIte
1af0: 72 20 2a 61 49 74 65 72 3b 20 20 20 20 20 20 20  r *aIter;       
1b00: 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 69     /* Array of i
1b10: 74 65 72 61 74 6f 72 73 20 74 6f 20 6d 65 72 67  terators to merg
1b20: 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 54 72 65  e */.  int *aTre
1b30: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
1b40: 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e         /* Curren
1b50: 74 20 73 74 61 74 65 20 6f 66 20 69 6e 63 72 65  t state of incre
1b60: 6d 65 6e 74 61 6c 20 6d 65 72 67 65 20 2a 2f 0a  mental merge */.
1b70: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
1b80: 70 54 65 6d 70 31 3b 20 20 20 20 20 20 20 20 20  pTemp1;         
1b90: 20 20 2f 2a 20 50 4d 41 20 66 69 6c 65 20 31 20    /* PMA file 1 
1ba0: 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72  */.  SorterRecor
1bb0: 64 20 2a 70 52 65 63 6f 72 64 3b 20 20 20 20 20  d *pRecord;     
1bc0: 20 20 20 20 20 2f 2a 20 48 65 61 64 20 6f 66 20       /* Head of 
1bd0: 69 6e 2d 6d 65 6d 6f 72 79 20 72 65 63 6f 72 64  in-memory record
1be0: 20 6c 69 73 74 20 2a 2f 0a 20 20 55 6e 70 61 63   list */.  Unpac
1bf0: 6b 65 64 52 65 63 6f 72 64 20 2a 70 55 6e 70 61  kedRecord *pUnpa
1c00: 63 6b 65 64 3b 20 20 20 20 20 20 2f 2a 20 55 73  cked;      /* Us
1c10: 65 64 20 74 6f 20 75 6e 70 61 63 6b 20 6b 65 79  ed to unpack key
1c20: 73 20 2a 2f 0a 20 20 75 38 2a 20 61 4d 65 6d 6f  s */.  u8* aMemo
1c30: 72 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ry;             
1c40: 20 20 20 20 20 20 20 2f 2a 20 42 6c 6f 63 6b 20         /* Block 
1c50: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 72 65 63 6f  to allocate reco
1c60: 72 64 73 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 6e  rds from */.  in
1c70: 74 20 69 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20  t iMemory;      
1c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1c90: 20 4f 66 66 73 65 74 20 6f 66 20 66 72 65 65 20   Offset of free 
1ca0: 73 70 61 63 65 20 69 6e 20 61 4d 65 6d 6f 72 79  space in aMemory
1cb0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 4d 65 6d 6f 72   */.  int nMemor
1cc0: 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  y;              
1cd0: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
1ce0: 20 73 69 7a 65 20 6f 66 20 61 6c 6c 6f 63 61 74   size of allocat
1cf0: 69 6f 6e 20 61 74 20 61 4d 65 6d 6f 72 79 20 2a  ion at aMemory *
1d00: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20  /.};../*.** The 
1d10: 66 6f 6c 6c 6f 77 69 6e 67 20 74 79 70 65 20 69  following type i
1d20: 73 20 61 6e 20 69 74 65 72 61 74 6f 72 20 66 6f  s an iterator fo
1d30: 72 20 61 20 50 4d 41 2e 20 49 74 20 63 61 63 68  r a PMA. It cach
1d40: 65 73 20 74 68 65 20 63 75 72 72 65 6e 74 20 6b  es the current k
1d50: 65 79 20 69 6e 20 0a 2a 2a 20 76 61 72 69 61 62  ey in .** variab
1d60: 6c 65 73 20 6e 4b 65 79 2f 61 4b 65 79 2e 20 49  les nKey/aKey. I
1d70: 66 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 69  f the iterator i
1d80: 73 20 61 74 20 45 4f 46 2c 20 70 46 69 6c 65 3d  s at EOF, pFile=
1d90: 3d 30 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 56 64  =0..*/.struct Vd
1da0: 62 65 53 6f 72 74 65 72 49 74 65 72 20 7b 0a 20  beSorterIter {. 
1db0: 20 69 36 34 20 69 52 65 61 64 4f 66 66 3b 20 20   i64 iReadOff;  
1dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1dd0: 20 2f 2a 20 43 75 72 72 65 6e 74 20 72 65 61 64   /* Current read
1de0: 20 6f 66 66 73 65 74 20 2a 2f 0a 20 20 69 36 34   offset */.  i64
1df0: 20 69 45 6f 66 3b 20 20 20 20 20 20 20 20 20 20   iEof;          
1e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1e10: 31 20 62 79 74 65 20 70 61 73 74 20 45 4f 46 20  1 byte past EOF 
1e20: 66 6f 72 20 74 68 69 73 20 69 74 65 72 61 74 6f  for this iterato
1e30: 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 6c 6c 6f  r */.  int nAllo
1e40: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
1e50: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
1e60: 6f 66 20 73 70 61 63 65 20 61 74 20 61 41 6c 6c  of space at aAll
1e70: 6f 63 20 2a 2f 0a 20 20 69 6e 74 20 6e 4b 65 79  oc */.  int nKey
1e80: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1e90: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
1ea0: 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 6b 65  r of bytes in ke
1eb0: 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66  y */.  sqlite3_f
1ec0: 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20 20 20  ile *pFile;     
1ed0: 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 69         /* File i
1ee0: 74 65 72 61 74 6f 72 20 69 73 20 72 65 61 64 69  terator is readi
1ef0: 6e 67 20 66 72 6f 6d 20 2a 2f 0a 20 20 75 38 20  ng from */.  u8 
1f00: 2a 61 41 6c 6c 6f 63 3b 20 20 20 20 20 20 20 20  *aAlloc;        
1f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1f20: 41 6c 6c 6f 63 61 74 65 64 20 73 70 61 63 65 20  Allocated space 
1f30: 2a 2f 0a 20 20 75 38 20 2a 61 4b 65 79 3b 20 20  */.  u8 *aKey;  
1f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f50: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
1f60: 74 6f 20 63 75 72 72 65 6e 74 20 6b 65 79 20 2a  to current key *
1f70: 2f 0a 20 20 75 38 20 2a 61 42 75 66 66 65 72 3b  /.  u8 *aBuffer;
1f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f90: 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 72      /* Current r
1fa0: 65 61 64 20 62 75 66 66 65 72 20 2a 2f 0a 20 20  ead buffer */.  
1fb0: 69 6e 74 20 6e 42 75 66 66 65 72 3b 20 20 20 20  int nBuffer;    
1fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fd0: 2f 2a 20 53 69 7a 65 20 6f 66 20 72 65 61 64 20  /* Size of read 
1fe0: 62 75 66 66 65 72 20 69 6e 20 62 79 74 65 73 20  buffer in bytes 
1ff0: 2a 2f 0a 20 20 75 38 20 2a 61 4d 61 70 3b 20 20  */.  u8 *aMap;  
2000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2010: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
2020: 74 6f 20 6d 61 70 70 69 6e 67 20 6f 66 20 70 46  to mapping of pF
2030: 69 6c 65 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a  ile */.};../*.**
2040: 20 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20   An instance of 
2050: 74 68 69 73 20 73 74 72 75 63 74 75 72 65 20 69  this structure i
2060: 73 20 75 73 65 64 20 74 6f 20 6f 72 67 61 6e 69  s used to organi
2070: 7a 65 20 74 68 65 20 73 74 72 65 61 6d 20 6f 66  ze the stream of
2080: 20 72 65 63 6f 72 64 73 0a 2a 2a 20 62 65 69 6e   records.** bein
2090: 67 20 77 72 69 74 74 65 6e 20 74 6f 20 66 69 6c  g written to fil
20a0: 65 73 20 62 79 20 74 68 65 20 6d 65 72 67 65 2d  es by the merge-
20b0: 73 6f 72 74 20 63 6f 64 65 20 69 6e 74 6f 20 61  sort code into a
20c0: 6c 69 67 6e 65 64 2c 20 70 61 67 65 2d 73 69 7a  ligned, page-siz
20d0: 65 64 0a 2a 2a 20 62 6c 6f 63 6b 73 2e 20 20 44  ed.** blocks.  D
20e0: 6f 69 6e 67 20 61 6c 6c 20 49 2f 4f 20 69 6e 20  oing all I/O in 
20f0: 61 6c 69 67 6e 65 64 20 70 61 67 65 2d 73 69 7a  aligned page-siz
2100: 65 64 20 62 6c 6f 63 6b 73 20 68 65 6c 70 73 20  ed blocks helps 
2110: 49 2f 4f 20 74 6f 20 67 6f 0a 2a 2a 20 66 61 73  I/O to go.** fas
2120: 74 65 72 20 6f 6e 20 6d 61 6e 79 20 6f 70 65 72  ter on many oper
2130: 61 74 69 6e 67 20 73 79 73 74 65 6d 73 2e 0a 2a  ating systems..*
2140: 2f 0a 73 74 72 75 63 74 20 46 69 6c 65 57 72 69  /.struct FileWri
2150: 74 65 72 20 7b 0a 20 20 69 6e 74 20 65 46 57 45  ter {.  int eFWE
2160: 72 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rr;             
2170: 20 20 20 20 20 20 20 20 2f 2a 20 4e 6f 6e 2d 7a          /* Non-z
2180: 65 72 6f 20 69 66 20 69 6e 20 61 6e 20 65 72 72  ero if in an err
2190: 6f 72 20 73 74 61 74 65 20 2a 2f 0a 20 20 75 38  or state */.  u8
21a0: 20 2a 61 42 75 66 66 65 72 3b 20 20 20 20 20 20   *aBuffer;      
21b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
21c0: 20 50 6f 69 6e 74 65 72 20 74 6f 20 77 72 69 74   Pointer to writ
21d0: 65 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 69 6e  e buffer */.  in
21e0: 74 20 6e 42 75 66 66 65 72 3b 20 20 20 20 20 20  t nBuffer;      
21f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2200: 20 53 69 7a 65 20 6f 66 20 77 72 69 74 65 20 62   Size of write b
2210: 75 66 66 65 72 20 69 6e 20 62 79 74 65 73 20 2a  uffer in bytes *
2220: 2f 0a 20 20 69 6e 74 20 69 42 75 66 53 74 61 72  /.  int iBufStar
2230: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
2240: 20 20 20 20 2f 2a 20 46 69 72 73 74 20 62 79 74      /* First byt
2250: 65 20 6f 66 20 62 75 66 66 65 72 20 74 6f 20 77  e of buffer to w
2260: 72 69 74 65 20 2a 2f 0a 20 20 69 6e 74 20 69 42  rite */.  int iB
2270: 75 66 45 6e 64 3b 20 20 20 20 20 20 20 20 20 20  ufEnd;          
2280: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 73            /* Las
2290: 74 20 62 79 74 65 20 6f 66 20 62 75 66 66 65 72  t byte of buffer
22a0: 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 69   to write */.  i
22b0: 36 34 20 69 57 72 69 74 65 4f 66 66 3b 20 20 20  64 iWriteOff;   
22c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
22d0: 2a 20 4f 66 66 73 65 74 20 6f 66 20 73 74 61 72  * Offset of star
22e0: 74 20 6f 66 20 62 75 66 66 65 72 20 69 6e 20 66  t of buffer in f
22f0: 69 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ile */.  sqlite3
2300: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20  _file *pFile;   
2310: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65           /* File
2320: 20 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a   to write to */.
2330: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 74 72 75  };../*.** A stru
2340: 63 74 75 72 65 20 74 6f 20 73 74 6f 72 65 20 61  cture to store a
2350: 20 73 69 6e 67 6c 65 20 72 65 63 6f 72 64 2e 20   single record. 
2360: 41 6c 6c 20 69 6e 2d 6d 65 6d 6f 72 79 20 72 65  All in-memory re
2370: 63 6f 72 64 73 20 61 72 65 20 63 6f 6e 6e 65 63  cords are connec
2380: 74 65 64 0a 2a 2a 20 74 6f 67 65 74 68 65 72 20  ted.** together 
2390: 69 6e 74 6f 20 61 20 6c 69 6e 6b 65 64 20 6c 69  into a linked li
23a0: 73 74 20 68 65 61 64 65 64 20 61 74 20 56 64 62  st headed at Vdb
23b0: 65 53 6f 72 74 65 72 2e 70 52 65 63 6f 72 64 2e  eSorter.pRecord.
23c0: 0a 2a 2a 0a 2a 2a 20 48 6f 77 20 74 68 65 20 6c  .**.** How the l
23d0: 69 6e 6b 65 64 20 6c 69 73 74 20 69 73 20 63 6f  inked list is co
23e0: 6e 6e 65 63 74 65 64 20 64 65 70 65 6e 64 73 20  nnected depends 
23f0: 6f 6e 20 68 6f 77 20 6d 65 6d 6f 72 79 20 69 73  on how memory is
2400: 20 62 65 69 6e 67 20 6d 61 6e 61 67 65 64 0a 2a   being managed.*
2410: 2a 20 62 79 20 74 68 69 73 20 6d 6f 64 75 6c 65  * by this module
2420: 2e 20 49 66 20 75 73 69 6e 67 20 61 20 73 65 70  . If using a sep
2430: 61 72 61 74 65 20 61 6c 6c 6f 63 61 74 69 6f 6e  arate allocation
2440: 20 66 6f 72 20 65 61 63 68 20 69 6e 2d 6d 65 6d   for each in-mem
2450: 6f 72 79 20 72 65 63 6f 72 64 0a 2a 2a 20 28 56  ory record.** (V
2460: 64 62 65 53 6f 72 74 65 72 2e 61 4d 65 6d 6f 72  dbeSorter.aMemor
2470: 79 3d 3d 30 29 2c 20 74 68 65 6e 20 74 68 65 20  y==0), then the 
2480: 6c 69 73 74 20 69 73 20 61 6c 77 61 79 73 20 63  list is always c
2490: 6f 6e 6e 65 63 74 65 64 20 75 73 69 6e 67 20 74  onnected using t
24a0: 68 65 20 0a 2a 2a 20 53 6f 72 74 65 72 52 65 63  he .** SorterRec
24b0: 6f 72 64 2e 75 2e 70 4e 65 78 74 20 70 6f 69 6e  ord.u.pNext poin
24c0: 74 65 72 73 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20  ters..**.** Or, 
24d0: 69 66 20 75 73 69 6e 67 20 74 68 65 20 73 69 6e  if using the sin
24e0: 67 6c 65 20 6c 61 72 67 65 20 61 6c 6c 6f 63 61  gle large alloca
24f0: 74 69 6f 6e 20 6d 65 74 68 6f 64 20 28 56 64 62  tion method (Vdb
2500: 65 53 6f 72 74 65 72 2e 61 4d 65 6d 6f 72 79 21  eSorter.aMemory!
2510: 3d 30 29 2c 0a 2a 2a 20 74 68 65 6e 20 77 68 69  =0),.** then whi
2520: 6c 65 20 72 65 63 6f 72 64 73 20 61 72 65 20 62  le records are b
2530: 65 69 6e 67 20 61 63 63 75 6d 75 6c 61 74 65 64  eing accumulated
2540: 20 74 68 65 20 6c 69 73 74 20 69 73 20 6c 69 6e   the list is lin
2550: 6b 65 64 20 75 73 69 6e 67 20 74 68 65 0a 2a 2a  ked using the.**
2560: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 75 2e   SorterRecord.u.
2570: 69 4e 65 78 74 20 6f 66 66 73 65 74 2e 20 54 68  iNext offset. Th
2580: 69 73 20 69 73 20 62 65 63 61 75 73 65 20 74 68  is is because th
2590: 65 20 61 4d 65 6d 6f 72 79 5b 5d 20 61 72 72 61  e aMemory[] arra
25a0: 79 20 6d 61 79 0a 2a 2a 20 62 65 20 73 71 6c 69  y may.** be sqli
25b0: 74 65 33 52 65 61 6c 6c 6f 63 28 29 65 64 20 77  te3Realloc()ed w
25c0: 68 69 6c 65 20 72 65 63 6f 72 64 73 20 61 72 65  hile records are
25d0: 20 62 65 69 6e 67 20 61 63 63 75 6d 75 6c 61 74   being accumulat
25e0: 65 64 2e 20 4f 6e 63 65 20 74 68 65 20 56 4d 0a  ed. Once the VM.
25f0: 2a 2a 20 68 61 73 20 66 69 6e 69 73 68 65 64 20  ** has finished 
2600: 70 61 73 73 69 6e 67 20 72 65 63 6f 72 64 73 20  passing records 
2610: 74 6f 20 74 68 65 20 73 6f 72 74 65 72 2c 20 6f  to the sorter, o
2620: 72 20 77 68 65 6e 20 74 68 65 20 69 6e 2d 6d 65  r when the in-me
2630: 6d 6f 72 79 20 62 75 66 66 65 72 0a 2a 2a 20 69  mory buffer.** i
2640: 73 20 66 75 6c 6c 2c 20 74 68 65 20 6c 69 73 74  s full, the list
2650: 20 69 73 20 73 6f 72 74 65 64 2e 20 41 73 20 70   is sorted. As p
2660: 61 72 74 20 6f 66 20 74 68 65 20 73 6f 72 74 69  art of the sorti
2670: 6e 67 20 70 72 6f 63 65 73 73 2c 20 69 74 20 69  ng process, it i
2680: 73 0a 2a 2a 20 63 6f 6e 76 65 72 74 65 64 20 74  s.** converted t
2690: 6f 20 75 73 65 20 74 68 65 20 53 6f 72 74 65 72  o use the Sorter
26a0: 52 65 63 6f 72 64 2e 75 2e 70 4e 65 78 74 20 70  Record.u.pNext p
26b0: 6f 69 6e 74 65 72 73 2e 20 53 65 65 20 66 75 6e  ointers. See fun
26c0: 63 74 69 6f 6e 0a 2a 2a 20 76 64 62 65 53 6f 72  ction.** vdbeSor
26d0: 74 65 72 53 6f 72 74 28 29 20 66 6f 72 20 64 65  terSort() for de
26e0: 74 61 69 6c 73 2e 0a 2a 2f 0a 73 74 72 75 63 74  tails..*/.struct
26f0: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 7b 0a   SorterRecord {.
2700: 20 20 69 6e 74 20 6e 56 61 6c 3b 0a 20 20 75 6e    int nVal;.  un
2710: 69 6f 6e 20 7b 0a 20 20 20 20 53 6f 72 74 65 72  ion {.    Sorter
2720: 52 65 63 6f 72 64 20 2a 70 4e 65 78 74 3b 20 20  Record *pNext;  
2730: 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74          /* Point
2740: 65 72 20 74 6f 20 6e 65 78 74 20 72 65 63 6f 72  er to next recor
2750: 64 20 69 6e 20 6c 69 73 74 20 2a 2f 0a 20 20 20  d in list */.   
2760: 20 69 6e 74 20 69 4e 65 78 74 3b 20 20 20 20 20   int iNext;     
2770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2780: 2a 20 4f 66 66 73 65 74 20 77 69 74 68 69 6e 20  * Offset within 
2790: 61 4d 65 6d 6f 72 79 20 6f 66 20 6e 65 78 74 20  aMemory of next 
27a0: 72 65 63 6f 72 64 20 2a 2f 0a 20 20 7d 20 75 3b  record */.  } u;
27b0: 0a 7d 3b 0a 0a 2f 2a 20 52 65 74 75 72 6e 20 61  .};../* Return a
27c0: 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20   pointer to the 
27d0: 62 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e  buffer containin
27e0: 67 20 74 68 65 20 72 65 63 6f 72 64 20 64 61 74  g the record dat
27f0: 61 20 66 6f 72 20 53 6f 72 74 65 72 52 65 63 6f  a for SorterReco
2800: 72 64 0a 2a 2a 20 6f 62 6a 65 63 74 20 70 2e 20  rd.** object p. 
2810: 53 68 6f 75 6c 64 20 62 65 20 75 73 65 64 20 61  Should be used a
2820: 73 20 69 66 3a 0a 2a 2a 0a 2a 2a 20 20 20 76 6f  s if:.**.**   vo
2830: 69 64 20 2a 53 52 56 41 4c 28 53 6f 72 74 65 72  id *SRVAL(Sorter
2840: 52 65 63 6f 72 64 20 2a 70 29 20 7b 20 72 65 74  Record *p) { ret
2850: 75 72 6e 20 28 76 6f 69 64 2a 29 26 70 5b 31 5d  urn (void*)&p[1]
2860: 3b 20 7d 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 53  ; }.*/.#define S
2870: 52 56 41 4c 28 70 29 20 28 28 76 6f 69 64 2a 29  RVAL(p) ((void*)
2880: 28 28 53 6f 72 74 65 72 52 65 63 6f 72 64 2a 29  ((SorterRecord*)
2890: 28 70 29 20 2b 20 31 29 29 0a 0a 2f 2a 20 4d 69  (p) + 1))../* Mi
28a0: 6e 69 6d 75 6d 20 61 6c 6c 6f 77 61 62 6c 65 20  nimum allowable 
28b0: 76 61 6c 75 65 20 66 6f 72 20 74 68 65 20 56 64  value for the Vd
28c0: 62 65 53 6f 72 74 65 72 2e 6e 57 6f 72 6b 69 6e  beSorter.nWorkin
28d0: 67 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a 23 64  g variable */.#d
28e0: 65 66 69 6e 65 20 53 4f 52 54 45 52 5f 4d 49 4e  efine SORTER_MIN
28f0: 5f 57 4f 52 4b 49 4e 47 20 31 30 0a 0a 2f 2a 20  _WORKING 10../* 
2900: 4d 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f  Maximum number o
2910: 66 20 73 65 67 6d 65 6e 74 73 20 74 6f 20 6d 65  f segments to me
2920: 72 67 65 20 69 6e 20 61 20 73 69 6e 67 6c 65 20  rge in a single 
2930: 70 61 73 73 2e 20 2a 2f 0a 23 64 65 66 69 6e 65  pass. */.#define
2940: 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47   SORTER_MAX_MERG
2950: 45 5f 43 4f 55 4e 54 20 31 36 0a 0a 2f 2a 0a 2a  E_COUNT 16../*.*
2960: 2a 20 46 72 65 65 20 61 6c 6c 20 6d 65 6d 6f 72  * Free all memor
2970: 79 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 74  y belonging to t
2980: 68 65 20 56 64 62 65 53 6f 72 74 65 72 49 74 65  he VdbeSorterIte
2990: 72 20 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20  r object passed 
29a0: 61 73 20 74 68 65 20 73 65 63 6f 6e 64 0a 2a 2a  as the second.**
29b0: 20 61 72 67 75 6d 65 6e 74 2e 20 41 6c 6c 20 73   argument. All s
29c0: 74 72 75 63 74 75 72 65 20 66 69 65 6c 64 73 20  tructure fields 
29d0: 61 72 65 20 73 65 74 20 74 6f 20 7a 65 72 6f 20  are set to zero 
29e0: 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  before returning
29f0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
2a00: 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 5a   vdbeSorterIterZ
2a10: 65 72 6f 28 73 71 6c 69 74 65 33 20 2a 64 62 2c  ero(sqlite3 *db,
2a20: 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20   VdbeSorterIter 
2a30: 2a 70 49 74 65 72 29 7b 0a 20 20 73 71 6c 69 74  *pIter){.  sqlit
2a40: 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 49 74  e3DbFree(db, pIt
2a50: 65 72 2d 3e 61 41 6c 6c 6f 63 29 3b 0a 20 20 73  er->aAlloc);.  s
2a60: 71 6c 69 74 65 33 44 62 46 72 65 65 28 64 62 2c  qlite3DbFree(db,
2a70: 20 70 49 74 65 72 2d 3e 61 42 75 66 66 65 72 29   pIter->aBuffer)
2a80: 3b 0a 20 20 69 66 28 20 70 49 74 65 72 2d 3e 61  ;.  if( pIter->a
2a90: 4d 61 70 20 29 20 73 71 6c 69 74 65 33 4f 73 55  Map ) sqlite3OsU
2aa0: 6e 66 65 74 63 68 28 70 49 74 65 72 2d 3e 70 46  nfetch(pIter->pF
2ab0: 69 6c 65 2c 20 30 2c 20 70 49 74 65 72 2d 3e 61  ile, 0, pIter->a
2ac0: 4d 61 70 29 3b 0a 20 20 6d 65 6d 73 65 74 28 70  Map);.  memset(p
2ad0: 49 74 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28  Iter, 0, sizeof(
2ae0: 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 29 29  VdbeSorterIter))
2af0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20  ;.}../*.** Read 
2b00: 6e 42 79 74 65 20 62 79 74 65 73 20 6f 66 20 64  nByte bytes of d
2b10: 61 74 61 20 66 72 6f 6d 20 74 68 65 20 73 74 72  ata from the str
2b20: 65 61 6d 20 6f 66 20 64 61 74 61 20 69 74 65 72  eam of data iter
2b30: 61 74 65 64 20 62 79 20 6f 62 6a 65 63 74 20 70  ated by object p
2b40: 2e 0a 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66  ..** If successf
2b50: 75 6c 2c 20 73 65 74 20 2a 70 70 4f 75 74 20 74  ul, set *ppOut t
2b60: 6f 20 70 6f 69 6e 74 20 74 6f 20 61 20 62 75 66  o point to a buf
2b70: 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74  fer containing t
2b80: 68 65 20 64 61 74 61 0a 2a 2a 20 61 6e 64 20 72  he data.** and r
2b90: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e  eturn SQLITE_OK.
2ba0: 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20 61   Otherwise, if a
2bb0: 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20  n error occurs, 
2bc0: 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74 65  return an SQLite
2bd0: 0a 2a 2a 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a  .** error code..
2be0: 2a 2a 0a 2a 2a 20 54 68 65 20 62 75 66 66 65 72  **.** The buffer
2bf0: 20 69 6e 64 69 63 61 74 65 64 20 62 79 20 2a 70   indicated by *p
2c00: 70 4f 75 74 20 6d 61 79 20 6f 6e 6c 79 20 62 65  pOut may only be
2c10: 20 63 6f 6e 73 69 64 65 72 65 64 20 76 61 6c 69   considered vali
2c20: 64 20 75 6e 74 69 6c 20 74 68 65 0a 2a 2a 20 6e  d until the.** n
2c30: 65 78 74 20 63 61 6c 6c 20 74 6f 20 74 68 69 73  ext call to this
2c40: 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74   function..*/.st
2c50: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
2c60: 74 65 72 49 74 65 72 52 65 61 64 28 0a 20 20 73  terIterRead(.  s
2c70: 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20  qlite3 *db,     
2c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2c90: 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c  * Database handl
2ca0: 65 20 28 66 6f 72 20 6d 61 6c 6c 6f 63 29 20 2a  e (for malloc) *
2cb0: 2f 0a 20 20 56 64 62 65 53 6f 72 74 65 72 49 74  /.  VdbeSorterIt
2cc0: 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20  er *p,          
2cd0: 20 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20      /* Iterator 
2ce0: 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65 2c 20  */.  int nByte, 
2cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2d00: 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66       /* Bytes of
2d10: 20 64 61 74 61 20 74 6f 20 72 65 61 64 20 2a 2f   data to read */
2d20: 0a 20 20 75 38 20 2a 2a 70 70 4f 75 74 20 20 20  .  u8 **ppOut   
2d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2d40: 20 20 20 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74     /* OUT: Point
2d50: 65 72 20 74 6f 20 62 75 66 66 65 72 20 63 6f 6e  er to buffer con
2d60: 74 61 69 6e 69 6e 67 20 64 61 74 61 20 2a 2f 0a  taining data */.
2d70: 29 7b 0a 20 20 69 6e 74 20 69 42 75 66 3b 20 20  ){.  int iBuf;  
2d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2d90: 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 77       /* Offset w
2da0: 69 74 68 69 6e 20 62 75 66 66 65 72 20 74 6f 20  ithin buffer to 
2db0: 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20 69  read from */.  i
2dc0: 6e 74 20 6e 41 76 61 69 6c 3b 20 20 20 20 20 20  nt nAvail;      
2dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2de0: 2a 20 42 79 74 65 73 20 6f 66 20 64 61 74 61 20  * Bytes of data 
2df0: 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 62 75 66  available in buf
2e00: 66 65 72 20 2a 2f 0a 0a 20 20 69 66 28 20 70 2d  fer */..  if( p-
2e10: 3e 61 4d 61 70 20 29 7b 0a 20 20 20 20 2a 70 70  >aMap ){.    *pp
2e20: 4f 75 74 20 3d 20 26 70 2d 3e 61 4d 61 70 5b 70  Out = &p->aMap[p
2e30: 2d 3e 69 52 65 61 64 4f 66 66 5d 3b 0a 20 20 20  ->iReadOff];.   
2e40: 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20   p->iReadOff += 
2e50: 6e 42 79 74 65 3b 0a 20 20 20 20 72 65 74 75 72  nByte;.    retur
2e60: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d  n SQLITE_OK;.  }
2e70: 0a 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61  ..  assert( p->a
2e80: 42 75 66 66 65 72 20 29 3b 0a 0a 20 20 2f 2a 20  Buffer );..  /* 
2e90: 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20 6d  If there is no m
2ea0: 6f 72 65 20 64 61 74 61 20 74 6f 20 62 65 20 72  ore data to be r
2eb0: 65 61 64 20 66 72 6f 6d 20 74 68 65 20 62 75 66  ead from the buf
2ec0: 66 65 72 2c 20 72 65 61 64 20 74 68 65 20 6e 65  fer, read the ne
2ed0: 78 74 20 0a 20 20 2a 2a 20 70 2d 3e 6e 42 75 66  xt .  ** p->nBuf
2ee0: 66 65 72 20 62 79 74 65 73 20 6f 66 20 64 61 74  fer bytes of dat
2ef0: 61 20 66 72 6f 6d 20 74 68 65 20 66 69 6c 65 20  a from the file 
2f00: 69 6e 74 6f 20 69 74 2e 20 4f 72 2c 20 69 66 20  into it. Or, if 
2f10: 74 68 65 72 65 20 61 72 65 20 6c 65 73 73 0a 20  there are less. 
2f20: 20 2a 2a 20 74 68 61 6e 20 70 2d 3e 6e 42 75 66   ** than p->nBuf
2f30: 66 65 72 20 62 79 74 65 73 20 72 65 6d 61 69 6e  fer bytes remain
2f40: 69 6e 67 20 69 6e 20 74 68 65 20 50 4d 41 2c 20  ing in the PMA, 
2f50: 72 65 61 64 20 61 6c 6c 20 72 65 6d 61 69 6e 69  read all remaini
2f60: 6e 67 20 64 61 74 61 2e 20 20 2a 2f 0a 20 20 69  ng data.  */.  i
2f70: 42 75 66 20 3d 20 70 2d 3e 69 52 65 61 64 4f 66  Buf = p->iReadOf
2f80: 66 20 25 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a  f % p->nBuffer;.
2f90: 20 20 69 66 28 20 69 42 75 66 3d 3d 30 20 29 7b    if( iBuf==0 ){
2fa0: 0a 20 20 20 20 69 6e 74 20 6e 52 65 61 64 3b 20  .    int nRead; 
2fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2fc0: 20 20 20 2f 2a 20 42 79 74 65 73 20 74 6f 20 72     /* Bytes to r
2fd0: 65 61 64 20 66 72 6f 6d 20 64 69 73 6b 20 2a 2f  ead from disk */
2fe0: 0a 20 20 20 20 69 6e 74 20 72 63 3b 20 20 20 20  .    int rc;    
2ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3000: 20 20 20 2f 2a 20 73 71 6c 69 74 65 33 4f 73 52     /* sqlite3OsR
3010: 65 61 64 28 29 20 72 65 74 75 72 6e 20 63 6f 64  ead() return cod
3020: 65 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 44 65 74  e */..    /* Det
3030: 65 72 6d 69 6e 65 20 68 6f 77 20 6d 61 6e 79 20  ermine how many 
3040: 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 74 6f  bytes of data to
3050: 20 72 65 61 64 2e 20 2a 2f 0a 20 20 20 20 69 66   read. */.    if
3060: 28 20 28 70 2d 3e 69 45 6f 66 20 2d 20 70 2d 3e  ( (p->iEof - p->
3070: 69 52 65 61 64 4f 66 66 29 20 3e 20 28 69 36 34  iReadOff) > (i64
3080: 29 70 2d 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20  )p->nBuffer ){. 
3090: 20 20 20 20 20 6e 52 65 61 64 20 3d 20 70 2d 3e       nRead = p->
30a0: 6e 42 75 66 66 65 72 3b 0a 20 20 20 20 7d 65 6c  nBuffer;.    }el
30b0: 73 65 7b 0a 20 20 20 20 20 20 6e 52 65 61 64 20  se{.      nRead 
30c0: 3d 20 28 69 6e 74 29 28 70 2d 3e 69 45 6f 66 20  = (int)(p->iEof 
30d0: 2d 20 70 2d 3e 69 52 65 61 64 4f 66 66 29 3b 0a  - p->iReadOff);.
30e0: 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74      }.    assert
30f0: 28 20 6e 52 65 61 64 3e 30 20 29 3b 0a 0a 20 20  ( nRead>0 );..  
3100: 20 20 2f 2a 20 52 65 61 64 20 64 61 74 61 20 66    /* Read data f
3110: 72 6f 6d 20 74 68 65 20 66 69 6c 65 2e 20 52 65  rom the file. Re
3120: 74 75 72 6e 20 65 61 72 6c 79 20 69 66 20 61 6e  turn early if an
3130: 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 20 2a   error occurs. *
3140: 2f 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  /.    rc = sqlit
3150: 65 33 4f 73 52 65 61 64 28 70 2d 3e 70 46 69 6c  e3OsRead(p->pFil
3160: 65 2c 20 70 2d 3e 61 42 75 66 66 65 72 2c 20 6e  e, p->aBuffer, n
3170: 52 65 61 64 2c 20 70 2d 3e 69 52 65 61 64 4f 66  Read, p->iReadOf
3180: 66 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  f);.    assert( 
3190: 72 63 21 3d 53 51 4c 49 54 45 5f 49 4f 45 52 52  rc!=SQLITE_IOERR
31a0: 5f 53 48 4f 52 54 5f 52 45 41 44 20 29 3b 0a 20  _SHORT_READ );. 
31b0: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
31c0: 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  E_OK ) return rc
31d0: 3b 0a 20 20 7d 0a 20 20 6e 41 76 61 69 6c 20 3d  ;.  }.  nAvail =
31e0: 20 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 69 42   p->nBuffer - iB
31f0: 75 66 3b 20 0a 0a 20 20 69 66 28 20 6e 42 79 74  uf; ..  if( nByt
3200: 65 3c 3d 6e 41 76 61 69 6c 20 29 7b 0a 20 20 20  e<=nAvail ){.   
3210: 20 2f 2a 20 54 68 65 20 72 65 71 75 65 73 74 65   /* The requeste
3220: 64 20 64 61 74 61 20 69 73 20 61 76 61 69 6c 61  d data is availa
3230: 62 6c 65 20 69 6e 20 74 68 65 20 69 6e 2d 6d 65  ble in the in-me
3240: 6d 6f 72 79 20 62 75 66 66 65 72 2e 20 49 6e 20  mory buffer. In 
3250: 74 68 69 73 0a 20 20 20 20 2a 2a 20 63 61 73 65  this.    ** case
3260: 20 74 68 65 72 65 20 69 73 20 6e 6f 20 6e 65 65   there is no nee
3270: 64 20 74 6f 20 6d 61 6b 65 20 61 20 63 6f 70 79  d to make a copy
3280: 20 6f 66 20 74 68 65 20 64 61 74 61 2c 20 6a 75   of the data, ju
3290: 73 74 20 72 65 74 75 72 6e 20 61 20 0a 20 20 20  st return a .   
32a0: 20 2a 2a 20 70 6f 69 6e 74 65 72 20 69 6e 74 6f   ** pointer into
32b0: 20 74 68 65 20 62 75 66 66 65 72 20 74 6f 20 74   the buffer to t
32c0: 68 65 20 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a 20  he caller.  */. 
32d0: 20 20 20 2a 70 70 4f 75 74 20 3d 20 26 70 2d 3e     *ppOut = &p->
32e0: 61 42 75 66 66 65 72 5b 69 42 75 66 5d 3b 0a 20  aBuffer[iBuf];. 
32f0: 20 20 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b     p->iReadOff +
3300: 3d 20 6e 42 79 74 65 3b 0a 20 20 7d 65 6c 73 65  = nByte;.  }else
3310: 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20 72 65 71  {.    /* The req
3320: 75 65 73 74 65 64 20 64 61 74 61 20 69 73 20 6e  uested data is n
3330: 6f 74 20 61 6c 6c 20 61 76 61 69 6c 61 62 6c 65  ot all available
3340: 20 69 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72   in the in-memor
3350: 79 20 62 75 66 66 65 72 2e 0a 20 20 20 20 2a 2a  y buffer..    **
3360: 20 49 6e 20 74 68 69 73 20 63 61 73 65 2c 20 61   In this case, a
3370: 6c 6c 6f 63 61 74 65 20 73 70 61 63 65 20 61 74  llocate space at
3380: 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 74 6f 20   p->aAlloc[] to 
3390: 63 6f 70 79 20 74 68 65 20 72 65 71 75 65 73 74  copy the request
33a0: 65 64 0a 20 20 20 20 2a 2a 20 72 61 6e 67 65 20  ed.    ** range 
33b0: 69 6e 74 6f 2e 20 54 68 65 6e 20 72 65 74 75 72  into. Then retur
33c0: 6e 20 61 20 63 6f 70 79 20 6f 66 20 70 6f 69 6e  n a copy of poin
33d0: 74 65 72 20 70 2d 3e 61 41 6c 6c 6f 63 20 74 6f  ter p->aAlloc to
33e0: 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 20 2a 2f   the caller.  */
33f0: 0a 20 20 20 20 69 6e 74 20 6e 52 65 6d 3b 20 20  .    int nRem;  
3400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3410: 20 20 20 2f 2a 20 42 79 74 65 73 20 72 65 6d 61     /* Bytes rema
3420: 69 6e 69 6e 67 20 74 6f 20 63 6f 70 79 20 2a 2f  ining to copy */
3430: 0a 0a 20 20 20 20 2f 2a 20 45 78 74 65 6e 64 20  ..    /* Extend 
3440: 74 68 65 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20  the p->aAlloc[] 
3450: 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 66 20 72 65  allocation if re
3460: 71 75 69 72 65 64 2e 20 2a 2f 0a 20 20 20 20 69  quired. */.    i
3470: 66 28 20 70 2d 3e 6e 41 6c 6c 6f 63 3c 6e 42 79  f( p->nAlloc<nBy
3480: 74 65 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  te ){.      int 
3490: 6e 4e 65 77 20 3d 20 70 2d 3e 6e 41 6c 6c 6f 63  nNew = p->nAlloc
34a0: 2a 32 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28  *2;.      while(
34b0: 20 6e 42 79 74 65 3e 6e 4e 65 77 20 29 20 6e 4e   nByte>nNew ) nN
34c0: 65 77 20 3d 20 6e 4e 65 77 2a 32 3b 0a 20 20 20  ew = nNew*2;.   
34d0: 20 20 20 70 2d 3e 61 41 6c 6c 6f 63 20 3d 20 73     p->aAlloc = s
34e0: 71 6c 69 74 65 33 44 62 52 65 61 6c 6c 6f 63 4f  qlite3DbReallocO
34f0: 72 46 72 65 65 28 64 62 2c 20 70 2d 3e 61 41 6c  rFree(db, p->aAl
3500: 6c 6f 63 2c 20 6e 4e 65 77 29 3b 0a 20 20 20 20  loc, nNew);.    
3510: 20 20 69 66 28 20 21 70 2d 3e 61 41 6c 6c 6f 63    if( !p->aAlloc
3520: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
3530: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 70 2d  _NOMEM;.      p-
3540: 3e 6e 41 6c 6c 6f 63 20 3d 20 6e 4e 65 77 3b 0a  >nAlloc = nNew;.
3550: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 43 6f      }..    /* Co
3560: 70 79 20 61 73 20 6d 75 63 68 20 64 61 74 61 20  py as much data 
3570: 61 73 20 69 73 20 61 76 61 69 6c 61 62 6c 65 20  as is available 
3580: 69 6e 20 74 68 65 20 62 75 66 66 65 72 20 69 6e  in the buffer in
3590: 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 0a  to the start of.
35a0: 20 20 20 20 2a 2a 20 70 2d 3e 61 41 6c 6c 6f 63      ** p->aAlloc
35b0: 5b 5d 2e 20 20 2a 2f 0a 20 20 20 20 6d 65 6d 63  [].  */.    memc
35c0: 70 79 28 70 2d 3e 61 41 6c 6c 6f 63 2c 20 26 70  py(p->aAlloc, &p
35d0: 2d 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d 2c  ->aBuffer[iBuf],
35e0: 20 6e 41 76 61 69 6c 29 3b 0a 20 20 20 20 70 2d   nAvail);.    p-
35f0: 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e 41 76  >iReadOff += nAv
3600: 61 69 6c 3b 0a 20 20 20 20 6e 52 65 6d 20 3d 20  ail;.    nRem = 
3610: 6e 42 79 74 65 20 2d 20 6e 41 76 61 69 6c 3b 0a  nByte - nAvail;.
3620: 0a 20 20 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c  .    /* The foll
3630: 6f 77 69 6e 67 20 6c 6f 6f 70 20 63 6f 70 69 65  owing loop copie
3640: 73 20 75 70 20 74 6f 20 70 2d 3e 6e 42 75 66 66  s up to p->nBuff
3650: 65 72 20 62 79 74 65 73 20 70 65 72 20 69 74 65  er bytes per ite
3660: 72 61 74 69 6f 6e 20 69 6e 74 6f 0a 20 20 20 20  ration into.    
3670: 2a 2a 20 74 68 65 20 70 2d 3e 61 41 6c 6c 6f 63  ** the p->aAlloc
3680: 5b 5d 20 62 75 66 66 65 72 2e 20 20 2a 2f 0a 20  [] buffer.  */. 
3690: 20 20 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30     while( nRem>0
36a0: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72 63   ){.      int rc
36b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
36c0: 20 20 20 20 20 20 2f 2a 20 76 64 62 65 53 6f 72        /* vdbeSor
36d0: 74 65 72 49 74 65 72 52 65 61 64 28 29 20 72 65  terIterRead() re
36e0: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 20  turn code */.   
36f0: 20 20 20 69 6e 74 20 6e 43 6f 70 79 3b 20 20 20     int nCopy;   
3700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3710: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  * Number of byte
3720: 73 20 74 6f 20 63 6f 70 79 20 2a 2f 0a 20 20 20  s to copy */.   
3730: 20 20 20 75 38 20 2a 61 4e 65 78 74 3b 20 20 20     u8 *aNext;   
3740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3750: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 62 75 66  * Pointer to buf
3760: 66 65 72 20 74 6f 20 63 6f 70 79 20 64 61 74 61  fer to copy data
3770: 20 66 72 6f 6d 20 2a 2f 0a 0a 20 20 20 20 20 20   from */..      
3780: 6e 43 6f 70 79 20 3d 20 6e 52 65 6d 3b 0a 20 20  nCopy = nRem;.  
3790: 20 20 20 20 69 66 28 20 6e 52 65 6d 3e 70 2d 3e      if( nRem>p->
37a0: 6e 42 75 66 66 65 72 20 29 20 6e 43 6f 70 79 20  nBuffer ) nCopy 
37b0: 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20  = p->nBuffer;.  
37c0: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
37d0: 74 65 72 49 74 65 72 52 65 61 64 28 64 62 2c 20  terIterRead(db, 
37e0: 70 2c 20 6e 43 6f 70 79 2c 20 26 61 4e 65 78 74  p, nCopy, &aNext
37f0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  );.      if( rc!
3800: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
3810: 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 61 73  urn rc;.      as
3820: 73 65 72 74 28 20 61 4e 65 78 74 21 3d 70 2d 3e  sert( aNext!=p->
3830: 61 41 6c 6c 6f 63 20 29 3b 0a 20 20 20 20 20 20  aAlloc );.      
3840: 6d 65 6d 63 70 79 28 26 70 2d 3e 61 41 6c 6c 6f  memcpy(&p->aAllo
3850: 63 5b 6e 42 79 74 65 20 2d 20 6e 52 65 6d 5d 2c  c[nByte - nRem],
3860: 20 61 4e 65 78 74 2c 20 6e 43 6f 70 79 29 3b 0a   aNext, nCopy);.
3870: 20 20 20 20 20 20 6e 52 65 6d 20 2d 3d 20 6e 43        nRem -= nC
3880: 6f 70 79 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  opy;.    }..    
3890: 2a 70 70 4f 75 74 20 3d 20 70 2d 3e 61 41 6c 6c  *ppOut = p->aAll
38a0: 6f 63 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  oc;.  }..  retur
38b0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
38c0: 2f 2a 0a 2a 2a 20 52 65 61 64 20 61 20 76 61 72  /*.** Read a var
38d0: 69 6e 74 20 66 72 6f 6d 20 74 68 65 20 73 74 72  int from the str
38e0: 65 61 6d 20 6f 66 20 64 61 74 61 20 61 63 63 65  eam of data acce
38f0: 73 73 65 64 20 62 79 20 70 2e 20 53 65 74 20 2a  ssed by p. Set *
3900: 70 6e 4f 75 74 20 74 6f 0a 2a 2a 20 74 68 65 20  pnOut to.** the 
3910: 76 61 6c 75 65 20 72 65 61 64 2e 0a 2a 2f 0a 73  value read..*/.s
3920: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
3930: 72 74 65 72 49 74 65 72 56 61 72 69 6e 74 28 73  rterIterVarint(s
3940: 71 6c 69 74 65 33 20 2a 64 62 2c 20 56 64 62 65  qlite3 *db, Vdbe
3950: 53 6f 72 74 65 72 49 74 65 72 20 2a 70 2c 20 75  SorterIter *p, u
3960: 36 34 20 2a 70 6e 4f 75 74 29 7b 0a 20 20 69 6e  64 *pnOut){.  in
3970: 74 20 69 42 75 66 3b 0a 0a 20 20 69 66 28 20 70  t iBuf;..  if( p
3980: 2d 3e 61 4d 61 70 20 29 7b 0a 20 20 20 20 70 2d  ->aMap ){.    p-
3990: 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 73 71 6c  >iReadOff += sql
39a0: 69 74 65 33 47 65 74 56 61 72 69 6e 74 28 26 70  ite3GetVarint(&p
39b0: 2d 3e 61 4d 61 70 5b 70 2d 3e 69 52 65 61 64 4f  ->aMap[p->iReadO
39c0: 66 66 5d 2c 20 70 6e 4f 75 74 29 3b 0a 20 20 7d  ff], pnOut);.  }
39d0: 65 6c 73 65 7b 0a 20 20 20 20 69 42 75 66 20 3d  else{.    iBuf =
39e0: 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 25 20 70   p->iReadOff % p
39f0: 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20 20 69  ->nBuffer;.    i
3a00: 66 28 20 69 42 75 66 20 26 26 20 28 70 2d 3e 6e  f( iBuf && (p->n
3a10: 42 75 66 66 65 72 2d 69 42 75 66 29 3e 3d 39 20  Buffer-iBuf)>=9 
3a20: 29 7b 0a 20 20 20 20 20 20 70 2d 3e 69 52 65 61  ){.      p->iRea
3a30: 64 4f 66 66 20 2b 3d 20 73 71 6c 69 74 65 33 47  dOff += sqlite3G
3a40: 65 74 56 61 72 69 6e 74 28 26 70 2d 3e 61 42 75  etVarint(&p->aBu
3a50: 66 66 65 72 5b 69 42 75 66 5d 2c 20 70 6e 4f 75  ffer[iBuf], pnOu
3a60: 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  t);.    }else{. 
3a70: 20 20 20 20 20 75 38 20 61 56 61 72 69 6e 74 5b       u8 aVarint[
3a80: 31 36 5d 2c 20 2a 61 3b 0a 20 20 20 20 20 20 69  16], *a;.      i
3a90: 6e 74 20 69 20 3d 20 30 2c 20 72 63 3b 0a 20 20  nt i = 0, rc;.  
3aa0: 20 20 20 20 64 6f 7b 0a 20 20 20 20 20 20 20 20      do{.        
3ab0: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 49  rc = vdbeSorterI
3ac0: 74 65 72 52 65 61 64 28 64 62 2c 20 70 2c 20 31  terRead(db, p, 1
3ad0: 2c 20 26 61 29 3b 0a 20 20 20 20 20 20 20 20 69  , &a);.        i
3ae0: 66 28 20 72 63 20 29 20 72 65 74 75 72 6e 20 72  f( rc ) return r
3af0: 63 3b 0a 20 20 20 20 20 20 20 20 61 56 61 72 69  c;.        aVari
3b00: 6e 74 5b 28 69 2b 2b 29 26 30 78 66 5d 20 3d 20  nt[(i++)&0xf] = 
3b10: 61 5b 30 5d 3b 0a 20 20 20 20 20 20 7d 77 68 69  a[0];.      }whi
3b20: 6c 65 28 20 28 61 5b 30 5d 26 30 78 38 30 29 21  le( (a[0]&0x80)!
3b30: 3d 30 20 29 3b 0a 20 20 20 20 20 20 73 71 6c 69  =0 );.      sqli
3b40: 74 65 33 47 65 74 56 61 72 69 6e 74 28 61 56 61  te3GetVarint(aVa
3b50: 72 69 6e 74 2c 20 70 6e 4f 75 74 29 3b 0a 20 20  rint, pnOut);.  
3b60: 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
3b70: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
3b80: 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 69  ./*.** Advance i
3b90: 74 65 72 61 74 6f 72 20 70 49 74 65 72 20 74 6f  terator pIter to
3ba0: 20 74 68 65 20 6e 65 78 74 20 6b 65 79 20 69 6e   the next key in
3bb0: 20 69 74 73 20 50 4d 41 2e 20 52 65 74 75 72 6e   its PMA. Return
3bc0: 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 0a 2a 2a   SQLITE_OK if.**
3bd0: 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73   no error occurs
3be0: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65  , or an SQLite e
3bf0: 72 72 6f 72 20 63 6f 64 65 20 69 66 20 6f 6e 65  rror code if one
3c00: 20 64 6f 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63   does..*/.static
3c10: 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72 49   int vdbeSorterI
3c20: 74 65 72 4e 65 78 74 28 0a 20 20 73 71 6c 69 74  terNext(.  sqlit
3c30: 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20  e3 *db,         
3c40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
3c50: 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 28 66  tabase handle (f
3c60: 6f 72 20 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c  or sqlite3DbMall
3c70: 6f 63 28 29 20 29 20 2a 2f 0a 20 20 56 64 62 65  oc() ) */.  Vdbe
3c80: 53 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74 65  SorterIter *pIte
3c90: 72 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49  r           /* I
3ca0: 74 65 72 61 74 6f 72 20 74 6f 20 61 64 76 61 6e  terator to advan
3cb0: 63 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  ce */.){.  int r
3cc0: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
3cd0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
3ce0: 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 75  turn Code */.  u
3cf0: 36 34 20 6e 52 65 63 20 3d 20 30 3b 20 20 20 20  64 nRec = 0;    
3d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3d10: 2a 20 53 69 7a 65 20 6f 66 20 72 65 63 6f 72 64  * Size of record
3d20: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 0a 20 20   in bytes */..  
3d30: 69 66 28 20 70 49 74 65 72 2d 3e 69 52 65 61 64  if( pIter->iRead
3d40: 4f 66 66 3e 3d 70 49 74 65 72 2d 3e 69 45 6f 66  Off>=pIter->iEof
3d50: 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 69 73 20   ){.    /* This 
3d60: 69 73 20 61 6e 20 45 4f 46 20 63 6f 6e 64 69 74  is an EOF condit
3d70: 69 6f 6e 20 2a 2f 0a 20 20 20 20 76 64 62 65 53  ion */.    vdbeS
3d80: 6f 72 74 65 72 49 74 65 72 5a 65 72 6f 28 64 62  orterIterZero(db
3d90: 2c 20 70 49 74 65 72 29 3b 0a 20 20 20 20 72 65  , pIter);.    re
3da0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
3db0: 20 20 7d 0a 0a 20 20 72 63 20 3d 20 76 64 62 65    }..  rc = vdbe
3dc0: 53 6f 72 74 65 72 49 74 65 72 56 61 72 69 6e 74  SorterIterVarint
3dd0: 28 64 62 2c 20 70 49 74 65 72 2c 20 26 6e 52 65  (db, pIter, &nRe
3de0: 63 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  c);.  if( rc==SQ
3df0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70  LITE_OK ){.    p
3e00: 49 74 65 72 2d 3e 6e 4b 65 79 20 3d 20 28 69 6e  Iter->nKey = (in
3e10: 74 29 6e 52 65 63 3b 0a 20 20 20 20 72 63 20 3d  t)nRec;.    rc =
3e20: 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 52   vdbeSorterIterR
3e30: 65 61 64 28 64 62 2c 20 70 49 74 65 72 2c 20 28  ead(db, pIter, (
3e40: 69 6e 74 29 6e 52 65 63 2c 20 26 70 49 74 65 72  int)nRec, &pIter
3e50: 2d 3e 61 4b 65 79 29 3b 0a 20 20 7d 0a 0a 20 20  ->aKey);.  }..  
3e60: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
3e70: 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 69  .** Initialize i
3e80: 74 65 72 61 74 6f 72 20 70 49 74 65 72 20 74 6f  terator pIter to
3e90: 20 73 63 61 6e 20 74 68 72 6f 75 67 68 20 74 68   scan through th
3ea0: 65 20 50 4d 41 20 73 74 6f 72 65 64 20 69 6e 20  e PMA stored in 
3eb0: 66 69 6c 65 20 70 46 69 6c 65 0a 2a 2a 20 73 74  file pFile.** st
3ec0: 61 72 74 69 6e 67 20 61 74 20 6f 66 66 73 65 74  arting at offset
3ed0: 20 69 53 74 61 72 74 20 61 6e 64 20 65 6e 64 69   iStart and endi
3ee0: 6e 67 20 61 74 20 6f 66 66 73 65 74 20 69 45 6f  ng at offset iEo
3ef0: 66 2d 31 2e 20 54 68 69 73 20 66 75 6e 63 74 69  f-1. This functi
3f00: 6f 6e 20 0a 2a 2a 20 6c 65 61 76 65 73 20 74 68  on .** leaves th
3f10: 65 20 69 74 65 72 61 74 6f 72 20 70 6f 69 6e 74  e iterator point
3f20: 69 6e 67 20 74 6f 20 74 68 65 20 66 69 72 73 74  ing to the first
3f30: 20 6b 65 79 20 69 6e 20 74 68 65 20 50 4d 41 20   key in the PMA 
3f40: 28 6f 72 20 45 4f 46 20 69 66 20 74 68 65 20 0a  (or EOF if the .
3f50: 2a 2a 20 50 4d 41 20 69 73 20 65 6d 70 74 79 29  ** PMA is empty)
3f60: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3f70: 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 49 6e  vdbeSorterIterIn
3f80: 69 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  it(.  sqlite3 *d
3f90: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b,              
3fa0: 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
3fb0: 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f  e handle */.  co
3fc0: 6e 73 74 20 56 64 62 65 53 6f 72 74 65 72 20 2a  nst VdbeSorter *
3fd0: 70 53 6f 72 74 65 72 2c 20 20 20 20 20 20 2f 2a  pSorter,      /*
3fe0: 20 53 6f 72 74 65 72 20 6f 62 6a 65 63 74 20 2a   Sorter object *
3ff0: 2f 0a 20 20 69 36 34 20 69 53 74 61 72 74 2c 20  /.  i64 iStart, 
4000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4010: 20 20 20 20 2f 2a 20 53 74 61 72 74 20 6f 66 66      /* Start off
4020: 73 65 74 20 69 6e 20 70 46 69 6c 65 20 2a 2f 0a  set in pFile */.
4030: 20 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72    VdbeSorterIter
4040: 20 2a 70 49 74 65 72 2c 20 20 20 20 20 20 20 20   *pIter,        
4050: 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 74 6f    /* Iterator to
4060: 20 70 6f 70 75 6c 61 74 65 20 2a 2f 0a 20 20 69   populate */.  i
4070: 36 34 20 2a 70 6e 42 79 74 65 20 20 20 20 20 20  64 *pnByte      
4080: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4090: 2a 20 49 4e 2f 4f 55 54 3a 20 49 6e 63 72 65 6d  * IN/OUT: Increm
40a0: 65 6e 74 20 74 68 69 73 20 76 61 6c 75 65 20 62  ent this value b
40b0: 79 20 50 4d 41 20 73 69 7a 65 20 2a 2f 0a 29 7b  y PMA size */.){
40c0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
40d0: 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 42 75  TE_OK;.  int nBu
40e0: 66 3b 0a 20 20 76 6f 69 64 20 2a 70 4d 61 70 3b  f;.  void *pMap;
40f0: 0a 0a 20 20 6e 42 75 66 20 3d 20 73 71 6c 69 74  ..  nBuf = sqlit
4100: 65 33 42 74 72 65 65 47 65 74 50 61 67 65 53 69  e3BtreeGetPageSi
4110: 7a 65 28 64 62 2d 3e 61 44 62 5b 30 5d 2e 70 42  ze(db->aDb[0].pB
4120: 74 29 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  t);..  assert( p
4130: 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f 66  Sorter->iWriteOf
4140: 66 3e 69 53 74 61 72 74 20 29 3b 0a 20 20 61 73  f>iStart );.  as
4150: 73 65 72 74 28 20 70 49 74 65 72 2d 3e 61 41 6c  sert( pIter->aAl
4160: 6c 6f 63 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65  loc==0 );.  asse
4170: 72 74 28 20 70 49 74 65 72 2d 3e 61 42 75 66 66  rt( pIter->aBuff
4180: 65 72 3d 3d 30 20 29 3b 0a 20 20 70 49 74 65 72  er==0 );.  pIter
4190: 2d 3e 70 46 69 6c 65 20 3d 20 70 53 6f 72 74 65  ->pFile = pSorte
41a0: 72 2d 3e 70 54 65 6d 70 31 3b 0a 20 20 70 49 74  r->pTemp1;.  pIt
41b0: 65 72 2d 3e 69 52 65 61 64 4f 66 66 20 3d 20 69  er->iReadOff = i
41c0: 53 74 61 72 74 3b 0a 20 20 70 49 74 65 72 2d 3e  Start;.  pIter->
41d0: 6e 41 6c 6c 6f 63 20 3d 20 31 32 38 3b 0a 20 20  nAlloc = 128;.  
41e0: 70 49 74 65 72 2d 3e 61 41 6c 6c 6f 63 20 3d 20  pIter->aAlloc = 
41f0: 28 75 38 20 2a 29 73 71 6c 69 74 65 33 44 62 4d  (u8 *)sqlite3DbM
4200: 61 6c 6c 6f 63 52 61 77 28 64 62 2c 20 70 49 74  allocRaw(db, pIt
4210: 65 72 2d 3e 6e 41 6c 6c 6f 63 29 3b 0a 0a 20 20  er->nAlloc);..  
4220: 2f 2a 20 53 65 65 20 69 66 20 74 68 69 73 20 50  /* See if this P
4230: 4d 41 20 63 61 6e 20 62 65 20 72 65 61 64 20 75  MA can be read u
4240: 73 69 6e 67 20 78 46 65 74 63 68 2e 20 2a 2f 0a  sing xFetch. */.
4250: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
4260: 46 65 74 63 68 28 70 49 74 65 72 2d 3e 70 46 69  Fetch(pIter->pFi
4270: 6c 65 2c 20 30 2c 20 70 53 6f 72 74 65 72 2d 3e  le, 0, pSorter->
4280: 69 57 72 69 74 65 4f 66 66 2c 20 26 70 4d 61 70  iWriteOff, &pMap
4290: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
42a0: 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
42b0: 72 63 3b 0a 20 20 69 66 28 20 70 4d 61 70 20 29  rc;.  if( pMap )
42c0: 7b 0a 20 20 20 20 70 49 74 65 72 2d 3e 61 4d 61  {.    pIter->aMa
42d0: 70 20 3d 20 28 75 38 2a 29 70 4d 61 70 3b 0a 20  p = (u8*)pMap;. 
42e0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 49 74 65   }else{.    pIte
42f0: 72 2d 3e 6e 42 75 66 66 65 72 20 3d 20 6e 42 75  r->nBuffer = nBu
4300: 66 3b 0a 20 20 20 20 70 49 74 65 72 2d 3e 61 42  f;.    pIter->aB
4310: 75 66 66 65 72 20 3d 20 28 75 38 20 2a 29 73 71  uffer = (u8 *)sq
4320: 6c 69 74 65 33 44 62 4d 61 6c 6c 6f 63 52 61 77  lite3DbMallocRaw
4330: 28 64 62 2c 20 6e 42 75 66 29 3b 0a 0a 20 20 20  (db, nBuf);..   
4340: 20 69 66 28 20 21 70 49 74 65 72 2d 3e 61 42 75   if( !pIter->aBu
4350: 66 66 65 72 20 29 7b 0a 20 20 20 20 20 20 72 63  ffer ){.      rc
4360: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
4370: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
4380: 20 20 69 6e 74 20 69 42 75 66 3b 0a 0a 20 20 20    int iBuf;..   
4390: 20 20 20 69 42 75 66 20 3d 20 69 53 74 61 72 74     iBuf = iStart
43a0: 20 25 20 6e 42 75 66 3b 0a 20 20 20 20 20 20 69   % nBuf;.      i
43b0: 66 28 20 69 42 75 66 20 29 7b 0a 20 20 20 20 20  f( iBuf ){.     
43c0: 20 20 20 69 6e 74 20 6e 52 65 61 64 20 3d 20 6e     int nRead = n
43d0: 42 75 66 20 2d 20 69 42 75 66 3b 0a 20 20 20 20  Buf - iBuf;.    
43e0: 20 20 20 20 69 66 28 20 28 69 53 74 61 72 74 20      if( (iStart 
43f0: 2b 20 6e 52 65 61 64 29 20 3e 20 70 53 6f 72 74  + nRead) > pSort
4400: 65 72 2d 3e 69 57 72 69 74 65 4f 66 66 20 29 7b  er->iWriteOff ){
4410: 0a 20 20 20 20 20 20 20 20 20 20 6e 52 65 61 64  .          nRead
4420: 20 3d 20 28 69 6e 74 29 28 70 53 6f 72 74 65 72   = (int)(pSorter
4430: 2d 3e 69 57 72 69 74 65 4f 66 66 20 2d 20 69 53  ->iWriteOff - iS
4440: 74 61 72 74 29 3b 0a 20 20 20 20 20 20 20 20 7d  tart);.        }
4450: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 71  .        rc = sq
4460: 6c 69 74 65 33 4f 73 52 65 61 64 28 0a 20 20 20  lite3OsRead(.   
4470: 20 20 20 20 20 20 20 20 20 70 53 6f 72 74 65 72           pSorter
4480: 2d 3e 70 54 65 6d 70 31 2c 20 26 70 49 74 65 72  ->pTemp1, &pIter
4490: 2d 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d 2c  ->aBuffer[iBuf],
44a0: 20 6e 52 65 61 64 2c 20 69 53 74 61 72 74 0a 20   nRead, iStart. 
44b0: 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20         );.      
44c0: 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51    assert( rc!=SQ
44d0: 4c 49 54 45 5f 49 4f 45 52 52 5f 53 48 4f 52 54  LITE_IOERR_SHORT
44e0: 5f 52 45 41 44 20 29 3b 0a 20 20 20 20 20 20 7d  _READ );.      }
44f0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
4500: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
4510: 29 7b 0a 20 20 20 20 75 36 34 20 6e 42 79 74 65  ){.    u64 nByte
4520: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4530: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
4540: 6f 66 20 50 4d 41 20 69 6e 20 62 79 74 65 73 20  of PMA in bytes 
4550: 2a 2f 0a 20 20 20 20 70 49 74 65 72 2d 3e 69 45  */.    pIter->iE
4560: 6f 66 20 3d 20 70 53 6f 72 74 65 72 2d 3e 69 57  of = pSorter->iW
4570: 72 69 74 65 4f 66 66 3b 0a 20 20 20 20 72 63 20  riteOff;.    rc 
4580: 3d 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72  = vdbeSorterIter
4590: 56 61 72 69 6e 74 28 64 62 2c 20 70 49 74 65 72  Varint(db, pIter
45a0: 2c 20 26 6e 42 79 74 65 29 3b 0a 20 20 20 20 70  , &nByte);.    p
45b0: 49 74 65 72 2d 3e 69 45 6f 66 20 3d 20 70 49 74  Iter->iEof = pIt
45c0: 65 72 2d 3e 69 52 65 61 64 4f 66 66 20 2b 20 6e  er->iReadOff + n
45d0: 42 79 74 65 3b 0a 20 20 20 20 2a 70 6e 42 79 74  Byte;.    *pnByt
45e0: 65 20 2b 3d 20 6e 42 79 74 65 3b 0a 20 20 7d 0a  e += nByte;.  }.
45f0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
4600: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
4610: 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 4e   vdbeSorterIterN
4620: 65 78 74 28 64 62 2c 20 70 49 74 65 72 29 3b 0a  ext(db, pIter);.
4630: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
4640: 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 61  .}.../*.** Compa
4650: 72 65 20 6b 65 79 31 20 28 62 75 66 66 65 72 20  re key1 (buffer 
4660: 70 4b 65 79 31 2c 20 73 69 7a 65 20 6e 4b 65 79  pKey1, size nKey
4670: 31 20 62 79 74 65 73 29 20 77 69 74 68 20 6b 65  1 bytes) with ke
4680: 79 32 20 28 62 75 66 66 65 72 20 70 4b 65 79 32  y2 (buffer pKey2
4690: 2c 20 0a 2a 2a 20 73 69 7a 65 20 6e 4b 65 79 32  , .** size nKey2
46a0: 20 62 79 74 65 73 29 2e 20 20 41 72 67 75 6d 65   bytes).  Argume
46b0: 6e 74 20 70 4b 65 79 49 6e 66 6f 20 73 75 70 70  nt pKeyInfo supp
46c0: 6c 69 65 73 20 74 68 65 20 63 6f 6c 6c 61 74 69  lies the collati
46d0: 6f 6e 20 66 75 6e 63 74 69 6f 6e 73 0a 2a 2a 20  on functions.** 
46e0: 75 73 65 64 20 62 79 20 74 68 65 20 63 6f 6d 70  used by the comp
46f0: 61 72 69 73 6f 6e 2e 20 49 66 20 61 6e 20 65 72  arison. If an er
4700: 72 6f 72 20 6f 63 63 75 72 73 2c 20 72 65 74 75  ror occurs, retu
4710: 72 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  rn an SQLite err
4720: 6f 72 20 63 6f 64 65 2e 0a 2a 2a 20 4f 74 68 65  or code..** Othe
4730: 72 77 69 73 65 2c 20 72 65 74 75 72 6e 20 53 51  rwise, return SQ
4740: 4c 49 54 45 5f 4f 4b 20 61 6e 64 20 73 65 74 20  LITE_OK and set 
4750: 2a 70 52 65 73 20 74 6f 20 61 20 6e 65 67 61 74  *pRes to a negat
4760: 69 76 65 2c 20 7a 65 72 6f 20 6f 72 20 70 6f 73  ive, zero or pos
4770: 69 74 69 76 65 0a 2a 2a 20 76 61 6c 75 65 2c 20  itive.** value, 
4780: 64 65 70 65 6e 64 69 6e 67 20 6f 6e 20 77 68 65  depending on whe
4790: 74 68 65 72 20 6b 65 79 31 20 69 73 20 73 6d 61  ther key1 is sma
47a0: 6c 6c 65 72 2c 20 65 71 75 61 6c 20 74 6f 20 6f  ller, equal to o
47b0: 72 20 6c 61 72 67 65 72 20 74 68 61 6e 20 6b 65  r larger than ke
47c0: 79 32 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  y2..**.** If the
47d0: 20 62 4f 6d 69 74 52 6f 77 69 64 20 61 72 67 75   bOmitRowid argu
47e0: 6d 65 6e 74 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f  ment is non-zero
47f0: 2c 20 61 73 73 75 6d 65 20 62 6f 74 68 20 6b 65  , assume both ke
4800: 79 73 20 65 6e 64 20 69 6e 20 61 20 72 6f 77 69  ys end in a rowi
4810: 64 0a 2a 2a 20 66 69 65 6c 64 2e 20 46 6f 72 20  d.** field. For 
4820: 74 68 65 20 70 75 72 70 6f 73 65 73 20 6f 66 20  the purposes of 
4830: 74 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2c 20  the comparison, 
4840: 69 67 6e 6f 72 65 20 69 74 2e 20 41 6c 73 6f 2c  ignore it. Also,
4850: 20 69 66 20 62 4f 6d 69 74 52 6f 77 69 64 0a 2a   if bOmitRowid.*
4860: 2a 20 69 73 20 74 72 75 65 20 61 6e 64 20 6b 65  * is true and ke
4870: 79 31 20 63 6f 6e 74 61 69 6e 73 20 65 76 65 6e  y1 contains even
4880: 20 61 20 73 69 6e 67 6c 65 20 4e 55 4c 4c 20 76   a single NULL v
4890: 61 6c 75 65 2c 20 69 74 20 69 73 20 63 6f 6e 73  alue, it is cons
48a0: 69 64 65 72 65 64 20 74 6f 0a 2a 2a 20 62 65 20  idered to.** be 
48b0: 6c 65 73 73 20 74 68 61 6e 20 6b 65 79 32 2e 20  less than key2. 
48c0: 45 76 65 6e 20 69 66 20 6b 65 79 32 20 61 6c 73  Even if key2 als
48d0: 6f 20 63 6f 6e 74 61 69 6e 73 20 4e 55 4c 4c 20  o contains NULL 
48e0: 76 61 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 49 66  values..**.** If
48f0: 20 70 4b 65 79 32 20 69 73 20 70 61 73 73 65 64   pKey2 is passed
4900: 20 61 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2c   a NULL pointer,
4910: 20 74 68 65 6e 20 69 74 20 69 73 20 61 73 73 75   then it is assu
4920: 6d 65 64 20 74 68 61 74 20 74 68 65 20 70 43 73  med that the pCs
4930: 72 2d 3e 61 53 70 61 63 65 0a 2a 2a 20 68 61 73  r->aSpace.** has
4940: 20 62 65 65 6e 20 61 6c 6c 6f 63 61 74 65 64 20   been allocated 
4950: 61 6e 64 20 63 6f 6e 74 61 69 6e 73 20 61 6e 20  and contains an 
4960: 75 6e 70 61 63 6b 65 64 20 72 65 63 6f 72 64 20  unpacked record 
4970: 74 68 61 74 20 69 73 20 75 73 65 64 20 61 73 20  that is used as 
4980: 6b 65 79 32 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  key2..*/.static 
4990: 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72 43  void vdbeSorterC
49a0: 6f 6d 70 61 72 65 28 0a 20 20 63 6f 6e 73 74 20  ompare(.  const 
49b0: 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72  VdbeCursor *pCsr
49c0: 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72  ,         /* Cur
49d0: 73 6f 72 20 6f 62 6a 65 63 74 20 28 66 6f 72 20  sor object (for 
49e0: 70 4b 65 79 49 6e 66 6f 29 20 2a 2f 0a 20 20 69  pKeyInfo) */.  i
49f0: 6e 74 20 6e 49 67 6e 6f 72 65 2c 20 20 20 20 20  nt nIgnore,     
4a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4a10: 2a 20 49 67 6e 6f 72 65 20 74 68 65 20 6c 61 73  * Ignore the las
4a20: 74 20 6e 49 67 6e 6f 72 65 20 66 69 65 6c 64 73  t nIgnore fields
4a30: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64   */.  const void
4a40: 20 2a 70 4b 65 79 31 2c 20 69 6e 74 20 6e 4b 65   *pKey1, int nKe
4a50: 79 31 2c 20 20 20 2f 2a 20 4c 65 66 74 20 73 69  y1,   /* Left si
4a60: 64 65 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e  de of comparison
4a70: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64   */.  const void
4a80: 20 2a 70 4b 65 79 32 2c 20 69 6e 74 20 6e 4b 65   *pKey2, int nKe
4a90: 79 32 2c 20 20 20 2f 2a 20 52 69 67 68 74 20 73  y2,   /* Right s
4aa0: 69 64 65 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f  ide of compariso
4ab0: 6e 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 52 65 73  n */.  int *pRes
4ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4ad0: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 52         /* OUT: R
4ae0: 65 73 75 6c 74 20 6f 66 20 63 6f 6d 70 61 72 69  esult of compari
4af0: 73 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 4b 65 79 49  son */.){.  KeyI
4b00: 6e 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 20 3d 20  nfo *pKeyInfo = 
4b10: 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 3b 0a  pCsr->pKeyInfo;.
4b20: 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
4b30: 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53  orter = pCsr->pS
4b40: 6f 72 74 65 72 3b 0a 20 20 55 6e 70 61 63 6b 65  orter;.  Unpacke
4b50: 64 52 65 63 6f 72 64 20 2a 72 32 20 3d 20 70 53  dRecord *r2 = pS
4b60: 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64  orter->pUnpacked
4b70: 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 69 66  ;.  int i;..  if
4b80: 28 20 70 4b 65 79 32 20 29 7b 0a 20 20 20 20 73  ( pKey2 ){.    s
4b90: 71 6c 69 74 65 33 56 64 62 65 52 65 63 6f 72 64  qlite3VdbeRecord
4ba0: 55 6e 70 61 63 6b 28 70 4b 65 79 49 6e 66 6f 2c  Unpack(pKeyInfo,
4bb0: 20 6e 4b 65 79 32 2c 20 70 4b 65 79 32 2c 20 72   nKey2, pKey2, r
4bc0: 32 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6e  2);.  }..  if( n
4bd0: 49 67 6e 6f 72 65 20 29 7b 0a 20 20 20 20 72 32  Ignore ){.    r2
4be0: 2d 3e 6e 46 69 65 6c 64 20 3d 20 70 4b 65 79 49  ->nField = pKeyI
4bf0: 6e 66 6f 2d 3e 6e 46 69 65 6c 64 20 2d 20 6e 49  nfo->nField - nI
4c00: 67 6e 6f 72 65 3b 0a 20 20 20 20 61 73 73 65 72  gnore;.    asser
4c10: 74 28 20 72 32 2d 3e 6e 46 69 65 6c 64 3e 30 20  t( r2->nField>0 
4c20: 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  );.    for(i=0; 
4c30: 69 3c 72 32 2d 3e 6e 46 69 65 6c 64 3b 20 69 2b  i<r2->nField; i+
4c40: 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 72 32  +){.      if( r2
4c50: 2d 3e 61 4d 65 6d 5b 69 5d 2e 66 6c 61 67 73 20  ->aMem[i].flags 
4c60: 26 20 4d 45 4d 5f 4e 75 6c 6c 20 29 7b 0a 20 20  & MEM_Null ){.  
4c70: 20 20 20 20 20 20 2a 70 52 65 73 20 3d 20 2d 31        *pRes = -1
4c80: 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ;.        return
4c90: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
4ca0: 20 20 20 20 61 73 73 65 72 74 28 20 72 32 2d 3e      assert( r2->
4cb0: 64 65 66 61 75 6c 74 5f 72 63 3d 3d 30 20 29 3b  default_rc==0 );
4cc0: 0a 20 20 7d 0a 0a 20 20 2a 70 52 65 73 20 3d 20  .  }..  *pRes = 
4cd0: 73 71 6c 69 74 65 33 56 64 62 65 52 65 63 6f 72  sqlite3VdbeRecor
4ce0: 64 43 6f 6d 70 61 72 65 28 6e 4b 65 79 31 2c 20  dCompare(nKey1, 
4cf0: 70 4b 65 79 31 2c 20 72 32 2c 20 30 29 3b 0a 7d  pKey1, r2, 0);.}
4d00: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
4d10: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20  ction is called 
4d20: 74 6f 20 63 6f 6d 70 61 72 65 20 74 77 6f 20 69  to compare two i
4d30: 74 65 72 61 74 6f 72 20 6b 65 79 73 20 77 68 65  terator keys whe
4d40: 6e 20 6d 65 72 67 69 6e 67 20 0a 2a 2a 20 6d 75  n merging .** mu
4d50: 6c 74 69 70 6c 65 20 62 2d 74 72 65 65 20 73 65  ltiple b-tree se
4d60: 67 6d 65 6e 74 73 2e 20 50 61 72 61 6d 65 74 65  gments. Paramete
4d70: 72 20 69 4f 75 74 20 69 73 20 74 68 65 20 69 6e  r iOut is the in
4d80: 64 65 78 20 6f 66 20 74 68 65 20 61 54 72 65 65  dex of the aTree
4d90: 5b 5d 20 0a 2a 2a 20 76 61 6c 75 65 20 74 6f 20  [] .** value to 
4da0: 72 65 63 61 6c 63 75 6c 61 74 65 2e 0a 2a 2f 0a  recalculate..*/.
4db0: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53  static int vdbeS
4dc0: 6f 72 74 65 72 44 6f 43 6f 6d 70 61 72 65 28 63  orterDoCompare(c
4dd0: 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72 20  onst VdbeCursor 
4de0: 2a 70 43 73 72 2c 20 69 6e 74 20 69 4f 75 74 29  *pCsr, int iOut)
4df0: 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a  {.  VdbeSorter *
4e00: 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e  pSorter = pCsr->
4e10: 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 69  pSorter;.  int i
4e20: 31 3b 0a 20 20 69 6e 74 20 69 32 3b 0a 20 20 69  1;.  int i2;.  i
4e30: 6e 74 20 69 52 65 73 3b 0a 20 20 56 64 62 65 53  nt iRes;.  VdbeS
4e40: 6f 72 74 65 72 49 74 65 72 20 2a 70 31 3b 0a 20  orterIter *p1;. 
4e50: 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20   VdbeSorterIter 
4e60: 2a 70 32 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  *p2;..  assert( 
4e70: 69 4f 75 74 3c 70 53 6f 72 74 65 72 2d 3e 6e 54  iOut<pSorter->nT
4e80: 72 65 65 20 26 26 20 69 4f 75 74 3e 30 20 29 3b  ree && iOut>0 );
4e90: 0a 0a 20 20 69 66 28 20 69 4f 75 74 3e 3d 28 70  ..  if( iOut>=(p
4ea0: 53 6f 72 74 65 72 2d 3e 6e 54 72 65 65 2f 32 29  Sorter->nTree/2)
4eb0: 20 29 7b 0a 20 20 20 20 69 31 20 3d 20 28 69 4f   ){.    i1 = (iO
4ec0: 75 74 20 2d 20 70 53 6f 72 74 65 72 2d 3e 6e 54  ut - pSorter->nT
4ed0: 72 65 65 2f 32 29 20 2a 20 32 3b 0a 20 20 20 20  ree/2) * 2;.    
4ee0: 69 32 20 3d 20 69 31 20 2b 20 31 3b 0a 20 20 7d  i2 = i1 + 1;.  }
4ef0: 65 6c 73 65 7b 0a 20 20 20 20 69 31 20 3d 20 70  else{.    i1 = p
4f00: 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 69 4f  Sorter->aTree[iO
4f10: 75 74 2a 32 5d 3b 0a 20 20 20 20 69 32 20 3d 20  ut*2];.    i2 = 
4f20: 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 69  pSorter->aTree[i
4f30: 4f 75 74 2a 32 2b 31 5d 3b 0a 20 20 7d 0a 0a 20  Out*2+1];.  }.. 
4f40: 20 70 31 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e   p1 = &pSorter->
4f50: 61 49 74 65 72 5b 69 31 5d 3b 0a 20 20 70 32 20  aIter[i1];.  p2 
4f60: 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 49 74 65  = &pSorter->aIte
4f70: 72 5b 69 32 5d 3b 0a 0a 20 20 69 66 28 20 70 31  r[i2];..  if( p1
4f80: 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20  ->pFile==0 ){.  
4f90: 20 20 69 52 65 73 20 3d 20 69 32 3b 0a 20 20 7d    iRes = i2;.  }
4fa0: 65 6c 73 65 20 69 66 28 20 70 32 2d 3e 70 46 69  else if( p2->pFi
4fb0: 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69 52 65  le==0 ){.    iRe
4fc0: 73 20 3d 20 69 31 3b 0a 20 20 7d 65 6c 73 65 7b  s = i1;.  }else{
4fd0: 0a 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 20 20  .    int res;.  
4fe0: 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
4ff0: 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b  pSorter->pUnpack
5000: 65 64 21 3d 30 20 29 3b 20 20 2f 2a 20 61 6c 6c  ed!=0 );  /* all
5010: 6f 63 61 74 65 64 20 69 6e 20 76 64 62 65 53 6f  ocated in vdbeSo
5020: 72 74 65 72 4d 65 72 67 65 28 29 20 2a 2f 0a 20  rterMerge() */. 
5030: 20 20 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d     vdbeSorterCom
5040: 70 61 72 65 28 0a 20 20 20 20 20 20 20 20 70 43  pare(.        pC
5050: 73 72 2c 20 30 2c 20 70 31 2d 3e 61 4b 65 79 2c  sr, 0, p1->aKey,
5060: 20 70 31 2d 3e 6e 4b 65 79 2c 20 70 32 2d 3e 61   p1->nKey, p2->a
5070: 4b 65 79 2c 20 70 32 2d 3e 6e 4b 65 79 2c 20 26  Key, p2->nKey, &
5080: 72 65 73 0a 20 20 20 20 29 3b 0a 20 20 20 20 69  res.    );.    i
5090: 66 28 20 72 65 73 3c 3d 30 20 29 7b 0a 20 20 20  f( res<=0 ){.   
50a0: 20 20 20 69 52 65 73 20 3d 20 69 31 3b 0a 20 20     iRes = i1;.  
50b0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69    }else{.      i
50c0: 52 65 73 20 3d 20 69 32 3b 0a 20 20 20 20 7d 0a  Res = i2;.    }.
50d0: 20 20 7d 0a 0a 20 20 70 53 6f 72 74 65 72 2d 3e    }..  pSorter->
50e0: 61 54 72 65 65 5b 69 4f 75 74 5d 20 3d 20 69 52  aTree[iOut] = iR
50f0: 65 73 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  es;.  return SQL
5100: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
5110: 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20   Initialize the 
5120: 74 65 6d 70 6f 72 61 72 79 20 69 6e 64 65 78 20  temporary index 
5130: 63 75 72 73 6f 72 20 6a 75 73 74 20 6f 70 65 6e  cursor just open
5140: 65 64 20 61 73 20 61 20 73 6f 72 74 65 72 20 63  ed as a sorter c
5150: 75 72 73 6f 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71  ursor..*/.int sq
5160: 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 49  lite3VdbeSorterI
5170: 6e 69 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c  nit(sqlite3 *db,
5180: 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73   VdbeCursor *pCs
5190: 72 29 7b 0a 20 20 69 6e 74 20 70 67 73 7a 3b 20  r){.  int pgsz; 
51a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
51b0: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 73 69        /* Page si
51c0: 7a 65 20 6f 66 20 6d 61 69 6e 20 64 61 74 61 62  ze of main datab
51d0: 61 73 65 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 43  ase */.  int mxC
51e0: 61 63 68 65 3b 20 20 20 20 20 20 20 20 20 20 20  ache;           
51f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61 63 68           /* Cach
5200: 65 20 73 69 7a 65 20 2a 2f 0a 20 20 56 64 62 65  e size */.  Vdbe
5210: 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 3b  Sorter *pSorter;
5220: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
5230: 68 65 20 6e 65 77 20 73 6f 72 74 65 72 20 2a 2f  he new sorter */
5240: 0a 20 20 63 68 61 72 20 2a 64 3b 20 20 20 20 20  .  char *d;     
5250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5260: 20 20 20 2f 2a 20 44 75 6d 6d 79 20 2a 2f 0a 0a     /* Dummy */..
5270: 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
5280: 70 4b 65 79 49 6e 66 6f 20 26 26 20 70 43 73 72  pKeyInfo && pCsr
5290: 2d 3e 70 42 74 3d 3d 30 20 29 3b 0a 20 20 70 43  ->pBt==0 );.  pC
52a0: 73 72 2d 3e 70 53 6f 72 74 65 72 20 3d 20 70 53  sr->pSorter = pS
52b0: 6f 72 74 65 72 20 3d 20 73 71 6c 69 74 65 33 44  orter = sqlite3D
52c0: 62 4d 61 6c 6c 6f 63 5a 65 72 6f 28 64 62 2c 20  bMallocZero(db, 
52d0: 73 69 7a 65 6f 66 28 56 64 62 65 53 6f 72 74 65  sizeof(VdbeSorte
52e0: 72 29 29 3b 0a 20 20 69 66 28 20 70 53 6f 72 74  r));.  if( pSort
52f0: 65 72 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74  er==0 ){.    ret
5300: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
5310: 3b 0a 20 20 7d 0a 20 20 0a 20 20 70 53 6f 72 74  ;.  }.  .  pSort
5320: 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64 20 3d 20  er->pUnpacked = 
5330: 73 71 6c 69 74 65 33 56 64 62 65 41 6c 6c 6f 63  sqlite3VdbeAlloc
5340: 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 28 70  UnpackedRecord(p
5350: 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20 30  Csr->pKeyInfo, 0
5360: 2c 20 30 2c 20 26 64 29 3b 0a 20 20 69 66 28 20  , 0, &d);.  if( 
5370: 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b  pSorter->pUnpack
5380: 65 64 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53  ed==0 ) return S
5390: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 61  QLITE_NOMEM;.  a
53a0: 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e  ssert( pSorter->
53b0: 70 55 6e 70 61 63 6b 65 64 3d 3d 28 55 6e 70 61  pUnpacked==(Unpa
53c0: 63 6b 65 64 52 65 63 6f 72 64 20 2a 29 64 20 29  ckedRecord *)d )
53d0: 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e  ;.  pSorter->pUn
53e0: 70 61 63 6b 65 64 2d 3e 6e 46 69 65 6c 64 20 3d  packed->nField =
53f0: 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2d   pCsr->pKeyInfo-
5400: 3e 6e 46 69 65 6c 64 3b 0a 0a 20 20 69 66 28 20  >nField;..  if( 
5410: 21 73 71 6c 69 74 65 33 54 65 6d 70 49 6e 4d 65  !sqlite3TempInMe
5420: 6d 6f 72 79 28 64 62 29 20 29 7b 0a 20 20 20 20  mory(db) ){.    
5430: 70 67 73 7a 20 3d 20 73 71 6c 69 74 65 33 42 74  pgsz = sqlite3Bt
5440: 72 65 65 47 65 74 50 61 67 65 53 69 7a 65 28 64  reeGetPageSize(d
5450: 62 2d 3e 61 44 62 5b 30 5d 2e 70 42 74 29 3b 0a  b->aDb[0].pBt);.
5460: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6d 6e 50      pSorter->mnP
5470: 6d 61 53 69 7a 65 20 3d 20 53 4f 52 54 45 52 5f  maSize = SORTER_
5480: 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20 2a 20 70 67  MIN_WORKING * pg
5490: 73 7a 3b 0a 20 20 20 20 6d 78 43 61 63 68 65 20  sz;.    mxCache 
54a0: 3d 20 64 62 2d 3e 61 44 62 5b 30 5d 2e 70 53 63  = db->aDb[0].pSc
54b0: 68 65 6d 61 2d 3e 63 61 63 68 65 5f 73 69 7a 65  hema->cache_size
54c0: 3b 0a 20 20 20 20 69 66 28 20 6d 78 43 61 63 68  ;.    if( mxCach
54d0: 65 3c 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52  e<SORTER_MIN_WOR
54e0: 4b 49 4e 47 20 29 20 6d 78 43 61 63 68 65 20 3d  KING ) mxCache =
54f0: 20 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b   SORTER_MIN_WORK
5500: 49 4e 47 3b 0a 20 20 20 20 70 53 6f 72 74 65 72  ING;.    pSorter
5510: 2d 3e 6d 78 50 6d 61 53 69 7a 65 20 3d 20 6d 78  ->mxPmaSize = mx
5520: 43 61 63 68 65 20 2a 20 70 67 73 7a 3b 0a 0a 20  Cache * pgsz;.. 
5530: 20 20 20 2f 2a 20 49 66 20 74 68 65 20 61 70 70     /* If the app
5540: 6c 69 63 61 74 69 6f 6e 20 69 73 20 75 73 69 6e  lication is usin
5550: 67 20 6d 65 6d 73 79 73 33 20 6f 72 20 6d 65 6d  g memsys3 or mem
5560: 73 79 73 35 2c 20 75 73 65 20 61 20 73 65 70 61  sys5, use a sepa
5570: 72 61 74 65 20 0a 20 20 20 20 2a 2a 20 61 6c 6c  rate .    ** all
5580: 6f 63 61 74 69 6f 6e 20 66 6f 72 20 65 61 63 68  ocation for each
5590: 20 73 6f 72 74 2d 6b 65 79 20 69 6e 20 6d 65 6d   sort-key in mem
55a0: 6f 72 79 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  ory. Otherwise, 
55b0: 75 73 65 20 61 20 73 69 6e 67 6c 65 20 62 69 67  use a single big
55c0: 0a 20 20 20 20 2a 2a 20 61 6c 6c 6f 63 61 74 69  .    ** allocati
55d0: 6f 6e 20 61 74 20 70 53 6f 72 74 65 72 2d 3e 61  on at pSorter->a
55e0: 4d 65 6d 6f 72 79 20 66 6f 72 20 61 6c 6c 20 73  Memory for all s
55f0: 6f 72 74 2d 6b 65 79 73 2e 20 20 2a 2f 0a 20 20  ort-keys.  */.  
5600: 20 20 69 66 28 20 73 71 6c 69 74 65 33 47 6c 6f    if( sqlite3Glo
5610: 62 61 6c 43 6f 6e 66 69 67 2e 70 48 65 61 70 3d  balConfig.pHeap=
5620: 3d 30 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65  =0 ){.      asse
5630: 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65  rt( pSorter->iMe
5640: 6d 6f 72 79 3d 3d 30 20 29 3b 0a 20 20 20 20 20  mory==0 );.     
5650: 20 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72   pSorter->nMemor
5660: 79 20 3d 20 70 67 73 7a 3b 0a 20 20 20 20 20 20  y = pgsz;.      
5670: 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79  pSorter->aMemory
5680: 20 3d 20 28 75 38 2a 29 73 71 6c 69 74 65 33 4d   = (u8*)sqlite3M
5690: 61 6c 6c 6f 63 28 70 53 6f 72 74 65 72 2d 3e 6e  alloc(pSorter->n
56a0: 4d 65 6d 6f 72 79 29 3b 0a 20 20 20 20 20 20 69  Memory);.      i
56b0: 66 28 20 21 70 53 6f 72 74 65 72 2d 3e 61 4d 65  f( !pSorter->aMe
56c0: 6d 6f 72 79 20 29 20 72 65 74 75 72 6e 20 53 51  mory ) return SQ
56d0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
56e0: 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  }.  }..  return 
56f0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
5700: 0a 2a 2a 20 46 72 65 65 20 74 68 65 20 6c 69 73  .** Free the lis
5710: 74 20 6f 66 20 73 6f 72 74 65 64 20 72 65 63 6f  t of sorted reco
5720: 72 64 73 20 73 74 61 72 74 69 6e 67 20 61 74 20  rds starting at 
5730: 70 52 65 63 6f 72 64 2e 0a 2a 2f 0a 73 74 61 74  pRecord..*/.stat
5740: 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74  ic void vdbeSort
5750: 65 72 52 65 63 6f 72 64 46 72 65 65 28 73 71 6c  erRecordFree(sql
5760: 69 74 65 33 20 2a 64 62 2c 20 53 6f 72 74 65 72  ite3 *db, Sorter
5770: 52 65 63 6f 72 64 20 2a 70 52 65 63 6f 72 64 29  Record *pRecord)
5780: 7b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  {.  SorterRecord
5790: 20 2a 70 3b 0a 20 20 53 6f 72 74 65 72 52 65 63   *p;.  SorterRec
57a0: 6f 72 64 20 2a 70 4e 65 78 74 3b 0a 20 20 66 6f  ord *pNext;.  fo
57b0: 72 28 70 3d 70 52 65 63 6f 72 64 3b 20 70 3b 20  r(p=pRecord; p; 
57c0: 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 4e  p=pNext){.    pN
57d0: 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74  ext = p->u.pNext
57e0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 44 62 46  ;.    sqlite3DbF
57f0: 72 65 65 28 64 62 2c 20 70 29 3b 0a 20 20 7d 0a  ree(db, p);.  }.
5800: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65 74 20 61  }../*.** Reset a
5810: 20 73 6f 72 74 69 6e 67 20 63 75 72 73 6f 72 20   sorting cursor 
5820: 62 61 63 6b 20 74 6f 20 69 74 73 20 6f 72 69 67  back to its orig
5830: 69 6e 61 6c 20 65 6d 70 74 79 20 73 74 61 74 65  inal empty state
5840: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
5850: 33 56 64 62 65 53 6f 72 74 65 72 52 65 73 65 74  3VdbeSorterReset
5860: 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 56 64  (sqlite3 *db, Vd
5870: 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
5880: 72 29 7b 0a 20 20 69 66 28 20 70 53 6f 72 74 65  r){.  if( pSorte
5890: 72 2d 3e 61 49 74 65 72 20 29 7b 0a 20 20 20 20  r->aIter ){.    
58a0: 69 6e 74 20 69 3b 0a 20 20 20 20 66 6f 72 28 69  int i;.    for(i
58b0: 3d 30 3b 20 69 3c 70 53 6f 72 74 65 72 2d 3e 6e  =0; i<pSorter->n
58c0: 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  Tree; i++){.    
58d0: 20 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72    vdbeSorterIter
58e0: 5a 65 72 6f 28 64 62 2c 20 26 70 53 6f 72 74 65  Zero(db, &pSorte
58f0: 72 2d 3e 61 49 74 65 72 5b 69 5d 29 3b 0a 20 20  r->aIter[i]);.  
5900: 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 44    }.    sqlite3D
5910: 62 46 72 65 65 28 64 62 2c 20 70 53 6f 72 74 65  bFree(db, pSorte
5920: 72 2d 3e 61 49 74 65 72 29 3b 0a 20 20 20 20 70  r->aIter);.    p
5930: 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 20 3d 20  Sorter->aIter = 
5940: 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 53 6f  0;.  }.  if( pSo
5950: 72 74 65 72 2d 3e 70 54 65 6d 70 31 20 29 7b 0a  rter->pTemp1 ){.
5960: 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43 6c 6f      sqlite3OsClo
5970: 73 65 46 72 65 65 28 70 53 6f 72 74 65 72 2d 3e  seFree(pSorter->
5980: 70 54 65 6d 70 31 29 3b 0a 20 20 20 20 70 53 6f  pTemp1);.    pSo
5990: 72 74 65 72 2d 3e 70 54 65 6d 70 31 20 3d 20 30  rter->pTemp1 = 0
59a0: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 53 6f 72  ;.  }.  if( pSor
59b0: 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 3d 3d 30 20  ter->aMemory==0 
59c0: 29 7b 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65  ){.    vdbeSorte
59d0: 72 52 65 63 6f 72 64 46 72 65 65 28 64 62 2c 20  rRecordFree(db, 
59e0: 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64  pSorter->pRecord
59f0: 29 3b 0a 20 20 7d 0a 20 20 70 53 6f 72 74 65 72  );.  }.  pSorter
5a00: 2d 3e 70 52 65 63 6f 72 64 20 3d 20 30 3b 0a 20  ->pRecord = 0;. 
5a10: 20 70 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65   pSorter->iWrite
5a20: 4f 66 66 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74  Off = 0;.  pSort
5a30: 65 72 2d 3e 69 52 65 61 64 4f 66 66 20 3d 20 30  er->iReadOff = 0
5a40: 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6e 49 6e  ;.  pSorter->nIn
5a50: 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a 20 20 70 53  Memory = 0;.  pS
5a60: 6f 72 74 65 72 2d 3e 6e 54 72 65 65 20 3d 20 30  orter->nTree = 0
5a70: 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6e 50 4d  ;.  pSorter->nPM
5a80: 41 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74 65 72  A = 0;.  pSorter
5a90: 2d 3e 61 54 72 65 65 20 3d 20 30 3b 0a 20 20 70  ->aTree = 0;.  p
5aa0: 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 20  Sorter->iMemory 
5ab0: 3d 20 30 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 46  = 0;.}.../*.** F
5ac0: 72 65 65 20 61 6e 79 20 63 75 72 73 6f 72 20 63  ree any cursor c
5ad0: 6f 6d 70 6f 6e 65 6e 74 73 20 61 6c 6c 6f 63 61  omponents alloca
5ae0: 74 65 64 20 62 79 20 73 71 6c 69 74 65 33 56 64  ted by sqlite3Vd
5af0: 62 65 53 6f 72 74 65 72 58 58 58 20 72 6f 75 74  beSorterXXX rout
5b00: 69 6e 65 73 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  ines..*/.void sq
5b10: 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 43  lite3VdbeSorterC
5b20: 6c 6f 73 65 28 73 71 6c 69 74 65 33 20 2a 64 62  lose(sqlite3 *db
5b30: 2c 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43  , VdbeCursor *pC
5b40: 73 72 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65  sr){.  VdbeSorte
5b50: 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73  r *pSorter = pCs
5b60: 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69 66  r->pSorter;.  if
5b70: 28 20 70 53 6f 72 74 65 72 20 29 7b 0a 20 20 20  ( pSorter ){.   
5b80: 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74   sqlite3VdbeSort
5b90: 65 72 52 65 73 65 74 28 64 62 2c 20 70 53 6f 72  erReset(db, pSor
5ba0: 74 65 72 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  ter);.    sqlite
5bb0: 33 44 62 46 72 65 65 28 64 62 2c 20 70 53 6f 72  3DbFree(db, pSor
5bc0: 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64 29 3b  ter->pUnpacked);
5bd0: 0a 20 20 20 20 73 71 6c 69 74 65 33 44 62 46 72  .    sqlite3DbFr
5be0: 65 65 28 64 62 2c 20 70 53 6f 72 74 65 72 2d 3e  ee(db, pSorter->
5bf0: 61 4d 65 6d 6f 72 79 29 3b 0a 20 20 20 20 73 71  aMemory);.    sq
5c00: 6c 69 74 65 33 44 62 46 72 65 65 28 64 62 2c 20  lite3DbFree(db, 
5c10: 70 53 6f 72 74 65 72 29 3b 0a 20 20 20 20 70 43  pSorter);.    pC
5c20: 73 72 2d 3e 70 53 6f 72 74 65 72 20 3d 20 30 3b  sr->pSorter = 0;
5c30: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 6c  .  }.}../*.** Al
5c40: 6c 6f 63 61 74 65 20 73 70 61 63 65 20 66 6f 72  locate space for
5c50: 20 61 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20 61   a file-handle a
5c60: 6e 64 20 6f 70 65 6e 20 61 20 74 65 6d 70 6f 72  nd open a tempor
5c70: 61 72 79 20 66 69 6c 65 2e 20 49 66 20 73 75 63  ary file. If suc
5c80: 63 65 73 73 66 75 6c 2c 0a 2a 2a 20 73 65 74 20  cessful,.** set 
5c90: 2a 70 70 46 69 6c 65 20 74 6f 20 70 6f 69 6e 74  *ppFile to point
5ca0: 20 74 6f 20 74 68 65 20 6d 61 6c 6c 6f 63 27 64   to the malloc'd
5cb0: 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20 61 6e 64   file-handle and
5cc0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
5cd0: 4b 2e 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c  K..** Otherwise,
5ce0: 20 73 65 74 20 2a 70 70 46 69 6c 65 20 74 6f 20   set *ppFile to 
5cf0: 30 20 61 6e 64 20 72 65 74 75 72 6e 20 61 6e 20  0 and return an 
5d00: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
5d10: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
5d20: 20 76 64 62 65 53 6f 72 74 65 72 4f 70 65 6e 54   vdbeSorterOpenT
5d30: 65 6d 70 46 69 6c 65 28 73 71 6c 69 74 65 33 20  empFile(sqlite3 
5d40: 2a 64 62 2c 20 73 71 6c 69 74 65 33 5f 66 69 6c  *db, sqlite3_fil
5d50: 65 20 2a 2a 70 70 46 69 6c 65 29 7b 0a 20 20 69  e **ppFile){.  i
5d60: 6e 74 20 72 63 3b 0a 20 20 72 63 20 3d 20 73 71  nt rc;.  rc = sq
5d70: 6c 69 74 65 33 4f 73 4f 70 65 6e 4d 61 6c 6c 6f  lite3OsOpenMallo
5d80: 63 28 64 62 2d 3e 70 56 66 73 2c 20 30 2c 20 70  c(db->pVfs, 0, p
5d90: 70 46 69 6c 65 2c 0a 20 20 20 20 20 20 53 51 4c  pFile,.      SQL
5da0: 49 54 45 5f 4f 50 45 4e 5f 54 45 4d 50 5f 4a 4f  ITE_OPEN_TEMP_JO
5db0: 55 52 4e 41 4c 20 7c 0a 20 20 20 20 20 20 53 51  URNAL |.      SQ
5dc0: 4c 49 54 45 5f 4f 50 45 4e 5f 52 45 41 44 57 52  LITE_OPEN_READWR
5dd0: 49 54 45 20 20 20 20 7c 20 53 51 4c 49 54 45 5f  ITE    | SQLITE_
5de0: 4f 50 45 4e 5f 43 52 45 41 54 45 20 7c 0a 20 20  OPEN_CREATE |.  
5df0: 20 20 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f      SQLITE_OPEN_
5e00: 45 58 43 4c 55 53 49 56 45 20 20 20 20 7c 20 53  EXCLUSIVE    | S
5e10: 51 4c 49 54 45 5f 4f 50 45 4e 5f 44 45 4c 45 54  QLITE_OPEN_DELET
5e20: 45 4f 4e 43 4c 4f 53 45 2c 20 26 72 63 0a 20 20  EONCLOSE, &rc.  
5e30: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  );.  if( rc==SQL
5e40: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 36  ITE_OK ){.    i6
5e50: 34 20 6d 61 78 20 3d 20 53 51 4c 49 54 45 5f 4d  4 max = SQLITE_M
5e60: 41 58 5f 4d 4d 41 50 5f 53 49 5a 45 3b 0a 20 20  AX_MMAP_SIZE;.  
5e70: 20 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 43    sqlite3OsFileC
5e80: 6f 6e 74 72 6f 6c 48 69 6e 74 28 20 2a 70 70 46  ontrolHint( *ppF
5e90: 69 6c 65 2c 20 53 51 4c 49 54 45 5f 46 43 4e 54  ile, SQLITE_FCNT
5ea0: 4c 5f 4d 4d 41 50 5f 53 49 5a 45 2c 20 28 76 6f  L_MMAP_SIZE, (vo
5eb0: 69 64 2a 29 26 6d 61 78 29 3b 0a 20 20 7d 0a 20  id*)&max);.  }. 
5ec0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
5ed0: 2a 0a 2a 2a 20 4d 65 72 67 65 20 74 68 65 20 74  *.** Merge the t
5ee0: 77 6f 20 73 6f 72 74 65 64 20 6c 69 73 74 73 20  wo sorted lists 
5ef0: 70 31 20 61 6e 64 20 70 32 20 69 6e 74 6f 20 61  p1 and p2 into a
5f00: 20 73 69 6e 67 6c 65 20 6c 69 73 74 2e 0a 2a 2a   single list..**
5f10: 20 53 65 74 20 2a 70 70 4f 75 74 20 74 6f 20 74   Set *ppOut to t
5f20: 68 65 20 68 65 61 64 20 6f 66 20 74 68 65 20 6e  he head of the n
5f30: 65 77 20 6c 69 73 74 2e 0a 2a 2a 0a 2a 2a 20 49  ew list..**.** I
5f40: 6e 20 63 61 73 65 73 20 77 68 65 72 65 20 6b 65  n cases where ke
5f50: 79 20 76 61 6c 75 65 73 20 61 72 65 20 65 71 75  y values are equ
5f60: 61 6c 2c 20 6b 65 79 73 20 66 72 6f 6d 20 6c 69  al, keys from li
5f70: 73 74 20 70 31 20 61 72 65 20 63 6f 6e 73 69 64  st p1 are consid
5f80: 65 72 65 64 0a 2a 2a 20 74 6f 20 62 65 20 73 6d  ered.** to be sm
5f90: 61 6c 6c 65 72 20 74 68 61 6e 20 6c 69 73 74 20  aller than list 
5fa0: 70 32 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  p2..*/.static vo
5fb0: 69 64 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72  id vdbeSorterMer
5fc0: 67 65 28 0a 20 20 63 6f 6e 73 74 20 56 64 62 65  ge(.  const Vdbe
5fd0: 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 20 20  Cursor *pCsr,   
5fe0: 20 20 20 20 20 20 2f 2a 20 46 6f 72 20 70 4b 65        /* For pKe
5ff0: 79 49 6e 66 6f 20 2a 2f 0a 20 20 53 6f 72 74 65  yInfo */.  Sorte
6000: 72 52 65 63 6f 72 64 20 2a 70 31 2c 20 20 20 20  rRecord *p1,    
6010: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69             /* Fi
6020: 72 73 74 20 6c 69 73 74 20 74 6f 20 6d 65 72 67  rst list to merg
6030: 65 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63  e */.  SorterRec
6040: 6f 72 64 20 2a 70 32 2c 20 20 20 20 20 20 20 20  ord *p2,        
6050: 20 20 20 20 20 20 20 2f 2a 20 53 65 63 6f 6e 64         /* Second
6060: 20 6c 69 73 74 20 74 6f 20 6d 65 72 67 65 20 2a   list to merge *
6070: 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  /.  SorterRecord
6080: 20 2a 2a 70 70 4f 75 74 20 20 20 20 20 20 20 20   **ppOut        
6090: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 48 65 61 64      /* OUT: Head
60a0: 20 6f 66 20 6d 65 72 67 65 64 20 6c 69 73 74 20   of merged list 
60b0: 2a 2f 0a 29 7b 0a 20 20 53 6f 72 74 65 72 52 65  */.){.  SorterRe
60c0: 63 6f 72 64 20 2a 70 46 69 6e 61 6c 20 3d 20 30  cord *pFinal = 0
60d0: 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  ;.  SorterRecord
60e0: 20 2a 2a 70 70 20 3d 20 26 70 46 69 6e 61 6c 3b   **pp = &pFinal;
60f0: 0a 20 20 76 6f 69 64 20 2a 70 56 61 6c 32 20 3d  .  void *pVal2 =
6100: 20 70 32 20 3f 20 53 52 56 41 4c 28 70 32 29 20   p2 ? SRVAL(p2) 
6110: 3a 20 30 3b 0a 0a 20 20 77 68 69 6c 65 28 20 70  : 0;..  while( p
6120: 31 20 26 26 20 70 32 20 29 7b 0a 20 20 20 20 69  1 && p2 ){.    i
6130: 6e 74 20 72 65 73 3b 0a 20 20 20 20 76 64 62 65  nt res;.    vdbe
6140: 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 70 43  SorterCompare(pC
6150: 73 72 2c 20 30 2c 20 53 52 56 41 4c 28 70 31 29  sr, 0, SRVAL(p1)
6160: 2c 20 70 31 2d 3e 6e 56 61 6c 2c 20 70 56 61 6c  , p1->nVal, pVal
6170: 32 2c 20 70 32 2d 3e 6e 56 61 6c 2c 20 26 72 65  2, p2->nVal, &re
6180: 73 29 3b 0a 20 20 20 20 69 66 28 20 72 65 73 3c  s);.    if( res<
6190: 3d 30 20 29 7b 0a 20 20 20 20 20 20 2a 70 70 20  =0 ){.      *pp 
61a0: 3d 20 70 31 3b 0a 20 20 20 20 20 20 70 70 20 3d  = p1;.      pp =
61b0: 20 26 70 31 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20   &p1->u.pNext;. 
61c0: 20 20 20 20 20 70 31 20 3d 20 70 31 2d 3e 75 2e       p1 = p1->u.
61d0: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 56 61  pNext;.      pVa
61e0: 6c 32 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73  l2 = 0;.    }els
61f0: 65 7b 0a 20 20 20 20 20 20 2a 70 70 20 3d 20 70  e{.      *pp = p
6200: 32 3b 0a 20 20 20 20 20 20 20 70 70 20 3d 20 26  2;.       pp = &
6210: 70 32 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20 20 20  p2->u.pNext;.   
6220: 20 20 20 70 32 20 3d 20 70 32 2d 3e 75 2e 70 4e     p2 = p2->u.pN
6230: 65 78 74 3b 0a 20 20 20 20 20 20 69 66 28 20 70  ext;.      if( p
6240: 32 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20  2==0 ) break;.  
6250: 20 20 20 20 70 56 61 6c 32 20 3d 20 53 52 56 41      pVal2 = SRVA
6260: 4c 28 70 32 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  L(p2);.    }.  }
6270: 0a 20 20 2a 70 70 20 3d 20 70 31 20 3f 20 70 31  .  *pp = p1 ? p1
6280: 20 3a 20 70 32 3b 0a 20 20 2a 70 70 4f 75 74 20   : p2;.  *ppOut 
6290: 3d 20 70 46 69 6e 61 6c 3b 0a 7d 0a 0a 2f 2a 0a  = pFinal;.}../*.
62a0: 2a 2a 20 53 6f 72 74 20 74 68 65 20 6c 69 6e 6b  ** Sort the link
62b0: 65 64 20 6c 69 73 74 20 6f 66 20 72 65 63 6f 72  ed list of recor
62c0: 64 73 20 68 65 61 64 65 64 20 61 74 20 70 43 73  ds headed at pCs
62d0: 72 2d 3e 70 52 65 63 6f 72 64 2e 20 52 65 74 75  r->pRecord. Retu
62e0: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 0a 2a 2a 20  rn SQLITE_OK.** 
62f0: 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f  if successful, o
6300: 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  r an SQLite erro
6310: 72 20 63 6f 64 65 20 28 69 2e 65 2e 20 53 51 4c  r code (i.e. SQL
6320: 49 54 45 5f 4e 4f 4d 45 4d 29 20 69 66 20 61 6e  ITE_NOMEM) if an
6330: 20 65 72 72 6f 72 0a 2a 2a 20 6f 63 63 75 72 73   error.** occurs
6340: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 6f 72 74  ..**.** The sort
6350: 20 69 73 20 72 65 71 75 69 72 65 64 20 74 6f 20   is required to 
6360: 62 65 20 73 74 61 62 6c 65 20 2d 20 69 66 20 74  be stable - if t
6370: 77 6f 20 65 6c 65 6d 65 6e 74 73 20 63 6f 6d 70  wo elements comp
6380: 61 72 65 20 61 73 20 65 71 75 61 6c 0a 2a 2a 20  are as equal.** 
6390: 74 68 65 6e 20 74 68 65 20 6f 6e 65 20 61 64 64  then the one add
63a0: 65 64 20 74 6f 20 74 68 65 20 73 6f 72 74 65 72  ed to the sorter
63b0: 20 66 69 72 73 74 20 69 73 20 63 6f 6e 73 69 64   first is consid
63c0: 65 72 65 64 20 74 68 65 20 73 6d 61 6c 6c 65 72  ered the smaller
63d0: 2e 0a 2a 2a 20 43 75 72 72 65 6e 74 6c 79 2c 20  ..** Currently, 
63e0: 74 68 65 20 6c 69 73 74 20 69 73 20 73 6f 72 74  the list is sort
63f0: 65 64 20 66 72 6f 6d 20 6e 65 77 65 73 74 20 74  ed from newest t
6400: 6f 20 6f 6c 64 65 73 74 20 2d 20 70 53 6f 72 74  o oldest - pSort
6410: 65 72 2d 3e 70 52 65 63 6f 72 64 0a 2a 2a 20 70  er->pRecord.** p
6420: 6f 69 6e 74 73 20 74 6f 20 74 68 65 20 6d 6f 73  oints to the mos
6430: 74 20 72 65 63 65 6e 74 6c 79 20 61 64 64 65 64  t recently added
6440: 20 73 6f 72 74 20 6b 65 79 2e 0a 2a 2f 0a 73 74   sort key..*/.st
6450: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
6460: 74 65 72 53 6f 72 74 28 63 6f 6e 73 74 20 56 64  terSort(const Vd
6470: 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b  beCursor *pCsr){
6480: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 53 6f 72 74  .  int i;.  Sort
6490: 65 72 52 65 63 6f 72 64 20 2a 2a 61 53 6c 6f 74  erRecord **aSlot
64a0: 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  ;.  SorterRecord
64b0: 20 2a 70 3b 0a 20 20 56 64 62 65 53 6f 72 74 65   *p;.  VdbeSorte
64c0: 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73  r *pSorter = pCs
64d0: 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 0a 20 20 61  r->pSorter;..  a
64e0: 53 6c 6f 74 20 3d 20 28 53 6f 72 74 65 72 52 65  Slot = (SorterRe
64f0: 63 6f 72 64 20 2a 2a 29 73 71 6c 69 74 65 33 4d  cord **)sqlite3M
6500: 61 6c 6c 6f 63 5a 65 72 6f 28 36 34 20 2a 20 73  allocZero(64 * s
6510: 69 7a 65 6f 66 28 53 6f 72 74 65 72 52 65 63 6f  izeof(SorterReco
6520: 72 64 20 2a 29 29 3b 0a 20 20 69 66 28 20 21 61  rd *));.  if( !a
6530: 53 6c 6f 74 20 29 7b 0a 20 20 20 20 72 65 74 75  Slot ){.    retu
6540: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
6550: 0a 20 20 7d 0a 0a 20 20 70 20 3d 20 70 53 6f 72  .  }..  p = pSor
6560: 74 65 72 2d 3e 70 52 65 63 6f 72 64 3b 0a 20 20  ter->pRecord;.  
6570: 77 68 69 6c 65 28 20 70 20 29 7b 0a 20 20 20 20  while( p ){.    
6580: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e  SorterRecord *pN
6590: 65 78 74 3b 0a 20 20 20 20 69 66 28 20 70 53 6f  ext;.    if( pSo
65a0: 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 20 29 7b  rter->aMemory ){
65b0: 0a 20 20 20 20 20 20 69 66 28 20 28 75 38 2a 29  .      if( (u8*)
65c0: 70 3d 3d 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d  p==pSorter->aMem
65d0: 6f 72 79 20 29 7b 0a 20 20 20 20 20 20 20 20 70  ory ){.        p
65e0: 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 20 20  Next = 0;.      
65f0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 61  }else{.        a
6600: 73 73 65 72 74 28 20 70 2d 3e 75 2e 69 4e 65 78  ssert( p->u.iNex
6610: 74 3c 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f  t<pSorter->nMemo
6620: 72 79 20 29 3b 0a 20 20 20 20 20 20 20 20 70 4e  ry );.        pN
6630: 65 78 74 20 3d 20 28 53 6f 72 74 65 72 52 65 63  ext = (SorterRec
6640: 6f 72 64 2a 29 26 70 53 6f 72 74 65 72 2d 3e 61  ord*)&pSorter->a
6650: 4d 65 6d 6f 72 79 5b 70 2d 3e 75 2e 69 4e 65 78  Memory[p->u.iNex
6660: 74 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  t];.      }.    
6670: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 4e 65  }else{.      pNe
6680: 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74 3b  xt = p->u.pNext;
6690: 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d 3e 75 2e  .    }.    p->u.
66a0: 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 66  pNext = 0;.    f
66b0: 6f 72 28 69 3d 30 3b 20 61 53 6c 6f 74 5b 69 5d  or(i=0; aSlot[i]
66c0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 76 64  ; i++){.      vd
66d0: 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28 70 43  beSorterMerge(pC
66e0: 73 72 2c 20 70 2c 20 61 53 6c 6f 74 5b 69 5d 2c  sr, p, aSlot[i],
66f0: 20 26 70 29 3b 0a 20 20 20 20 20 20 61 53 6c 6f   &p);.      aSlo
6700: 74 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  t[i] = 0;.    }.
6710: 20 20 20 20 61 53 6c 6f 74 5b 69 5d 20 3d 20 70      aSlot[i] = p
6720: 3b 0a 20 20 20 20 70 20 3d 20 70 4e 65 78 74 3b  ;.    p = pNext;
6730: 0a 20 20 7d 0a 0a 20 20 70 20 3d 20 30 3b 0a 20  .  }..  p = 0;. 
6740: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 36 34 3b 20   for(i=0; i<64; 
6750: 69 2b 2b 29 7b 0a 20 20 20 20 76 64 62 65 53 6f  i++){.    vdbeSo
6760: 72 74 65 72 4d 65 72 67 65 28 70 43 73 72 2c 20  rterMerge(pCsr, 
6770: 70 2c 20 61 53 6c 6f 74 5b 69 5d 2c 20 26 70 29  p, aSlot[i], &p)
6780: 3b 0a 20 20 7d 0a 20 20 70 53 6f 72 74 65 72 2d  ;.  }.  pSorter-
6790: 3e 70 52 65 63 6f 72 64 20 3d 20 70 3b 0a 0a 20  >pRecord = p;.. 
67a0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 53   sqlite3_free(aS
67b0: 6c 6f 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  lot);.  return S
67c0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
67d0: 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61 20  ** Initialize a 
67e0: 66 69 6c 65 2d 77 72 69 74 65 72 20 6f 62 6a 65  file-writer obje
67f0: 63 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ct..*/.static vo
6800: 69 64 20 66 69 6c 65 57 72 69 74 65 72 49 6e 69  id fileWriterIni
6810: 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  t(.  sqlite3 *db
6820: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
6830: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
6840: 20 28 66 6f 72 20 6d 61 6c 6c 6f 63 29 20 2a 2f   (for malloc) */
6850: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
6860: 2a 70 46 69 6c 65 2c 20 20 20 20 20 20 20 20 20  *pFile,         
6870: 20 20 20 2f 2a 20 46 69 6c 65 20 74 6f 20 77 72     /* File to wr
6880: 69 74 65 20 74 6f 20 2a 2f 0a 20 20 46 69 6c 65  ite to */.  File
6890: 57 72 69 74 65 72 20 2a 70 2c 20 20 20 20 20 20  Writer *p,      
68a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
68b0: 62 6a 65 63 74 20 74 6f 20 70 6f 70 75 6c 61 74  bject to populat
68c0: 65 20 2a 2f 0a 20 20 69 36 34 20 69 53 74 61 72  e */.  i64 iStar
68d0: 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t               
68e0: 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74         /* Offset
68f0: 20 6f 66 20 70 46 69 6c 65 20 74 6f 20 62 65 67   of pFile to beg
6900: 69 6e 20 77 72 69 74 69 6e 67 20 61 74 20 2a 2f  in writing at */
6910: 0a 29 7b 0a 20 20 69 6e 74 20 6e 42 75 66 20 3d  .){.  int nBuf =
6920: 20 73 71 6c 69 74 65 33 42 74 72 65 65 47 65 74   sqlite3BtreeGet
6930: 50 61 67 65 53 69 7a 65 28 64 62 2d 3e 61 44 62  PageSize(db->aDb
6940: 5b 30 5d 2e 70 42 74 29 3b 0a 0a 20 20 6d 65 6d  [0].pBt);..  mem
6950: 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f 66  set(p, 0, sizeof
6960: 28 46 69 6c 65 57 72 69 74 65 72 29 29 3b 0a 20  (FileWriter));. 
6970: 20 70 2d 3e 61 42 75 66 66 65 72 20 3d 20 28 75   p->aBuffer = (u
6980: 38 20 2a 29 73 71 6c 69 74 65 33 44 62 4d 61 6c  8 *)sqlite3DbMal
6990: 6c 6f 63 52 61 77 28 64 62 2c 20 6e 42 75 66 29  locRaw(db, nBuf)
69a0: 3b 0a 20 20 69 66 28 20 21 70 2d 3e 61 42 75 66  ;.  if( !p->aBuf
69b0: 66 65 72 20 29 7b 0a 20 20 20 20 70 2d 3e 65 46  fer ){.    p->eF
69c0: 57 45 72 72 20 3d 20 53 51 4c 49 54 45 5f 4e 4f  WErr = SQLITE_NO
69d0: 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  MEM;.  }else{.  
69e0: 20 20 70 2d 3e 69 42 75 66 45 6e 64 20 3d 20 70    p->iBufEnd = p
69f0: 2d 3e 69 42 75 66 53 74 61 72 74 20 3d 20 28 69  ->iBufStart = (i
6a00: 53 74 61 72 74 20 25 20 6e 42 75 66 29 3b 0a 20  Start % nBuf);. 
6a10: 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20     p->iWriteOff 
6a20: 3d 20 69 53 74 61 72 74 20 2d 20 70 2d 3e 69 42  = iStart - p->iB
6a30: 75 66 53 74 61 72 74 3b 0a 20 20 20 20 70 2d 3e  ufStart;.    p->
6a40: 6e 42 75 66 66 65 72 20 3d 20 6e 42 75 66 3b 0a  nBuffer = nBuf;.
6a50: 20 20 20 20 70 2d 3e 70 46 69 6c 65 20 3d 20 70      p->pFile = p
6a60: 46 69 6c 65 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  File;.  }.}../*.
6a70: 2a 2a 20 57 72 69 74 65 20 6e 44 61 74 61 20 62  ** Write nData b
6a80: 79 74 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20  ytes of data to 
6a90: 74 68 65 20 66 69 6c 65 2d 77 72 69 74 65 20 6f  the file-write o
6aa0: 62 6a 65 63 74 2e 20 52 65 74 75 72 6e 20 53 51  bject. Return SQ
6ab0: 4c 49 54 45 5f 4f 4b 0a 2a 2a 20 69 66 20 73 75  LITE_OK.** if su
6ac0: 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20  ccessful, or an 
6ad0: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
6ae0: 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  e if an error oc
6af0: 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  curs..*/.static 
6b00: 76 6f 69 64 20 66 69 6c 65 57 72 69 74 65 72 57  void fileWriterW
6b10: 72 69 74 65 28 46 69 6c 65 57 72 69 74 65 72 20  rite(FileWriter 
6b20: 2a 70 2c 20 75 38 20 2a 70 44 61 74 61 2c 20 69  *p, u8 *pData, i
6b30: 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20 69 6e 74  nt nData){.  int
6b40: 20 6e 52 65 6d 20 3d 20 6e 44 61 74 61 3b 0a 20   nRem = nData;. 
6b50: 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30 20 26   while( nRem>0 &
6b60: 26 20 70 2d 3e 65 46 57 45 72 72 3d 3d 30 20 29  & p->eFWErr==0 )
6b70: 7b 0a 20 20 20 20 69 6e 74 20 6e 43 6f 70 79 20  {.    int nCopy 
6b80: 3d 20 6e 52 65 6d 3b 0a 20 20 20 20 69 66 28 20  = nRem;.    if( 
6b90: 6e 43 6f 70 79 3e 28 70 2d 3e 6e 42 75 66 66 65  nCopy>(p->nBuffe
6ba0: 72 20 2d 20 70 2d 3e 69 42 75 66 45 6e 64 29 20  r - p->iBufEnd) 
6bb0: 29 7b 0a 20 20 20 20 20 20 6e 43 6f 70 79 20 3d  ){.      nCopy =
6bc0: 20 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 70 2d   p->nBuffer - p-
6bd0: 3e 69 42 75 66 45 6e 64 3b 0a 20 20 20 20 7d 0a  >iBufEnd;.    }.
6be0: 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d 3e  .    memcpy(&p->
6bf0: 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 45  aBuffer[p->iBufE
6c00: 6e 64 5d 2c 20 26 70 44 61 74 61 5b 6e 44 61 74  nd], &pData[nDat
6c10: 61 2d 6e 52 65 6d 5d 2c 20 6e 43 6f 70 79 29 3b  a-nRem], nCopy);
6c20: 0a 20 20 20 20 70 2d 3e 69 42 75 66 45 6e 64 20  .    p->iBufEnd 
6c30: 2b 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 69 66  += nCopy;.    if
6c40: 28 20 70 2d 3e 69 42 75 66 45 6e 64 3d 3d 70 2d  ( p->iBufEnd==p-
6c50: 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20  >nBuffer ){.    
6c60: 20 20 70 2d 3e 65 46 57 45 72 72 20 3d 20 73 71    p->eFWErr = sq
6c70: 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d 3e  lite3OsWrite(p->
6c80: 70 46 69 6c 65 2c 20 0a 20 20 20 20 20 20 20 20  pFile, .        
6c90: 20 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 70 2d    &p->aBuffer[p-
6ca0: 3e 69 42 75 66 53 74 61 72 74 5d 2c 20 70 2d 3e  >iBufStart], p->
6cb0: 69 42 75 66 45 6e 64 20 2d 20 70 2d 3e 69 42 75  iBufEnd - p->iBu
6cc0: 66 53 74 61 72 74 2c 20 0a 20 20 20 20 20 20 20  fStart, .       
6cd0: 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20     p->iWriteOff 
6ce0: 2b 20 70 2d 3e 69 42 75 66 53 74 61 72 74 0a 20  + p->iBufStart. 
6cf0: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 70 2d       );.      p-
6d00: 3e 69 42 75 66 53 74 61 72 74 20 3d 20 70 2d 3e  >iBufStart = p->
6d10: 69 42 75 66 45 6e 64 20 3d 20 30 3b 0a 20 20 20  iBufEnd = 0;.   
6d20: 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20     p->iWriteOff 
6d30: 2b 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20  += p->nBuffer;. 
6d40: 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28     }.    assert(
6d50: 20 70 2d 3e 69 42 75 66 45 6e 64 3c 70 2d 3e 6e   p->iBufEnd<p->n
6d60: 42 75 66 66 65 72 20 29 3b 0a 0a 20 20 20 20 6e  Buffer );..    n
6d70: 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20  Rem -= nCopy;.  
6d80: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68  }.}../*.** Flush
6d90: 20 61 6e 79 20 62 75 66 66 65 72 65 64 20 64 61   any buffered da
6da0: 74 61 20 74 6f 20 64 69 73 6b 20 61 6e 64 20 63  ta to disk and c
6db0: 6c 65 61 6e 20 75 70 20 74 68 65 20 66 69 6c 65  lean up the file
6dc0: 2d 77 72 69 74 65 72 20 6f 62 6a 65 63 74 2e 0a  -writer object..
6dd0: 2a 2a 20 54 68 65 20 72 65 73 75 6c 74 73 20 6f  ** The results o
6de0: 66 20 75 73 69 6e 67 20 74 68 65 20 66 69 6c 65  f using the file
6df0: 2d 77 72 69 74 65 72 20 61 66 74 65 72 20 74 68  -writer after th
6e00: 69 73 20 63 61 6c 6c 20 61 72 65 20 75 6e 64 65  is call are unde
6e10: 66 69 6e 65 64 2e 0a 2a 2a 20 52 65 74 75 72 6e  fined..** Return
6e20: 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 66 6c   SQLITE_OK if fl
6e30: 75 73 68 69 6e 67 20 74 68 65 20 62 75 66 66 65  ushing the buffe
6e40: 72 65 64 20 64 61 74 61 20 73 75 63 63 65 65 64  red data succeed
6e50: 73 20 6f 72 20 69 73 20 6e 6f 74 20 0a 2a 2a 20  s or is not .** 
6e60: 72 65 71 75 69 72 65 64 2e 20 4f 74 68 65 72 77  required. Otherw
6e70: 69 73 65 2c 20 72 65 74 75 72 6e 20 61 6e 20 53  ise, return an S
6e80: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
6e90: 2e 0a 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65 20 72  ..**.** Before r
6ea0: 65 74 75 72 6e 69 6e 67 2c 20 73 65 74 20 2a 70  eturning, set *p
6eb0: 69 45 6f 66 20 74 6f 20 74 68 65 20 6f 66 66 73  iEof to the offs
6ec0: 65 74 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 66  et immediately f
6ed0: 6f 6c 6c 6f 77 69 6e 67 20 74 68 65 0a 2a 2a 20  ollowing the.** 
6ee0: 6c 61 73 74 20 62 79 74 65 20 77 72 69 74 74 65  last byte writte
6ef0: 6e 20 74 6f 20 74 68 65 20 66 69 6c 65 2e 0a 2a  n to the file..*
6f00: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69 6c  /.static int fil
6f10: 65 57 72 69 74 65 72 46 69 6e 69 73 68 28 73 71  eWriterFinish(sq
6f20: 6c 69 74 65 33 20 2a 64 62 2c 20 46 69 6c 65 57  lite3 *db, FileW
6f30: 72 69 74 65 72 20 2a 70 2c 20 69 36 34 20 2a 70  riter *p, i64 *p
6f40: 69 45 6f 66 29 7b 0a 20 20 69 6e 74 20 72 63 3b  iEof){.  int rc;
6f50: 0a 20 20 69 66 28 20 70 2d 3e 65 46 57 45 72 72  .  if( p->eFWErr
6f60: 3d 3d 30 20 26 26 20 41 4c 57 41 59 53 28 70 2d  ==0 && ALWAYS(p-
6f70: 3e 61 42 75 66 66 65 72 29 20 26 26 20 70 2d 3e  >aBuffer) && p->
6f80: 69 42 75 66 45 6e 64 3e 70 2d 3e 69 42 75 66 53  iBufEnd>p->iBufS
6f90: 74 61 72 74 20 29 7b 0a 20 20 20 20 70 2d 3e 65  tart ){.    p->e
6fa0: 46 57 45 72 72 20 3d 20 73 71 6c 69 74 65 33 4f  FWErr = sqlite3O
6fb0: 73 57 72 69 74 65 28 70 2d 3e 70 46 69 6c 65 2c  sWrite(p->pFile,
6fc0: 20 0a 20 20 20 20 20 20 20 20 26 70 2d 3e 61 42   .        &p->aB
6fd0: 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 53 74 61  uffer[p->iBufSta
6fe0: 72 74 5d 2c 20 70 2d 3e 69 42 75 66 45 6e 64 20  rt], p->iBufEnd 
6ff0: 2d 20 70 2d 3e 69 42 75 66 53 74 61 72 74 2c 20  - p->iBufStart, 
7000: 0a 20 20 20 20 20 20 20 20 70 2d 3e 69 57 72 69  .        p->iWri
7010: 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42 75 66 53  teOff + p->iBufS
7020: 74 61 72 74 0a 20 20 20 20 29 3b 0a 20 20 7d 0a  tart.    );.  }.
7030: 20 20 2a 70 69 45 6f 66 20 3d 20 28 70 2d 3e 69    *piEof = (p->i
7040: 57 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42  WriteOff + p->iB
7050: 75 66 45 6e 64 29 3b 0a 20 20 73 71 6c 69 74 65  ufEnd);.  sqlite
7060: 33 44 62 46 72 65 65 28 64 62 2c 20 70 2d 3e 61  3DbFree(db, p->a
7070: 42 75 66 66 65 72 29 3b 0a 20 20 72 63 20 3d 20  Buffer);.  rc = 
7080: 70 2d 3e 65 46 57 45 72 72 3b 0a 20 20 6d 65 6d  p->eFWErr;.  mem
7090: 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f 66  set(p, 0, sizeof
70a0: 28 46 69 6c 65 57 72 69 74 65 72 29 29 3b 0a 20  (FileWriter));. 
70b0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
70c0: 2a 0a 2a 2a 20 57 72 69 74 65 20 76 61 6c 75 65  *.** Write value
70d0: 20 69 56 61 6c 20 65 6e 63 6f 64 65 64 20 61 73   iVal encoded as
70e0: 20 61 20 76 61 72 69 6e 74 20 74 6f 20 74 68 65   a varint to the
70f0: 20 66 69 6c 65 2d 77 72 69 74 65 20 6f 62 6a 65   file-write obje
7100: 63 74 2e 20 52 65 74 75 72 6e 20 0a 2a 2a 20 53  ct. Return .** S
7110: 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63  QLITE_OK if succ
7120: 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51  essful, or an SQ
7130: 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20  Lite error code 
7140: 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  if an error occu
7150: 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  rs..*/.static vo
7160: 69 64 20 66 69 6c 65 57 72 69 74 65 72 57 72 69  id fileWriterWri
7170: 74 65 56 61 72 69 6e 74 28 46 69 6c 65 57 72 69  teVarint(FileWri
7180: 74 65 72 20 2a 70 2c 20 75 36 34 20 69 56 61 6c  ter *p, u64 iVal
7190: 29 7b 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b 20  ){.  int nByte; 
71a0: 0a 20 20 75 38 20 61 42 79 74 65 5b 31 30 5d 3b  .  u8 aByte[10];
71b0: 0a 20 20 6e 42 79 74 65 20 3d 20 73 71 6c 69 74  .  nByte = sqlit
71c0: 65 33 50 75 74 56 61 72 69 6e 74 28 61 42 79 74  e3PutVarint(aByt
71d0: 65 2c 20 69 56 61 6c 29 3b 0a 20 20 66 69 6c 65  e, iVal);.  file
71e0: 57 72 69 74 65 72 57 72 69 74 65 28 70 2c 20 61  WriterWrite(p, a
71f0: 42 79 74 65 2c 20 6e 42 79 74 65 29 3b 0a 7d 0a  Byte, nByte);.}.
7200: 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41 58 5f  .#if SQLITE_MAX_
7210: 4d 4d 41 50 5f 53 49 5a 45 3e 30 0a 2f 2a 0a 2a  MMAP_SIZE>0./*.*
7220: 2a 20 54 68 65 20 66 69 72 73 74 20 61 72 67 75  * The first argu
7230: 6d 65 6e 74 20 69 73 20 61 20 66 69 6c 65 2d 68  ment is a file-h
7240: 61 6e 64 6c 65 20 6f 70 65 6e 20 6f 6e 20 61 20  andle open on a 
7250: 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 2e 20  temporary file. 
7260: 54 68 65 20 66 69 6c 65 0a 2a 2a 20 69 73 20 67  The file.** is g
7270: 75 61 72 61 6e 74 65 65 64 20 74 6f 20 62 65 20  uaranteed to be 
7280: 6e 42 79 74 65 20 62 79 74 65 73 20 6f 72 20 73  nByte bytes or s
7290: 6d 61 6c 6c 65 72 20 69 6e 20 73 69 7a 65 2e 20  maller in size. 
72a0: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 0a 2a  This function .*
72b0: 2a 20 61 74 74 65 6d 70 74 73 20 74 6f 20 65 78  * attempts to ex
72c0: 74 65 6e 64 20 74 68 65 20 66 69 6c 65 20 74 6f  tend the file to
72d0: 20 6e 42 79 74 65 20 62 79 74 65 73 20 69 6e 20   nByte bytes in 
72e0: 73 69 7a 65 20 61 6e 64 20 74 6f 20 65 6e 73 75  size and to ensu
72f0: 72 65 20 74 68 61 74 0a 2a 2a 20 74 68 65 20 56  re that.** the V
7300: 46 53 20 68 61 73 20 6d 65 6d 6f 72 79 20 6d 61  FS has memory ma
7310: 70 70 65 64 20 69 74 2e 0a 2a 2a 0a 2a 2a 20 57  pped it..**.** W
7320: 68 65 74 68 65 72 20 6f 72 20 6e 6f 74 20 74 68  hether or not th
7330: 65 20 66 69 6c 65 20 64 6f 65 73 20 65 6e 64 20  e file does end 
7340: 75 70 20 6d 65 6d 6f 72 79 20 6d 61 70 70 65 64  up memory mapped
7350: 20 6f 66 20 63 6f 75 72 73 65 20 64 65 70 65 6e   of course depen
7360: 64 73 20 6f 6e 20 0a 2a 2a 20 74 68 65 20 73 70  ds on .** the sp
7370: 65 63 69 66 69 63 20 56 46 53 20 69 6d 70 6c 65  ecific VFS imple
7380: 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a 73 74  mentation..*/.st
7390: 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f  atic void vdbeSo
73a0: 72 74 65 72 45 78 74 65 6e 64 46 69 6c 65 28 73  rterExtendFile(s
73b0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
73c0: 6c 65 2c 20 69 36 34 20 6e 42 79 74 65 29 7b 0a  le, i64 nByte){.
73d0: 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 69 74    int rc = sqlit
73e0: 65 33 4f 73 54 72 75 6e 63 61 74 65 28 70 46 69  e3OsTruncate(pFi
73f0: 6c 65 2c 20 6e 42 79 74 65 29 3b 0a 20 20 69 66  le, nByte);.  if
7400: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
7410: 29 7b 0a 20 20 20 20 76 6f 69 64 20 2a 70 20 3d  ){.    void *p =
7420: 20 30 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f   0;.    sqlite3O
7430: 73 46 65 74 63 68 28 70 46 69 6c 65 2c 20 30 2c  sFetch(pFile, 0,
7440: 20 6e 42 79 74 65 2c 20 26 70 29 3b 0a 20 20 20   nByte, &p);.   
7450: 20 73 71 6c 69 74 65 33 4f 73 55 6e 66 65 74 63   sqlite3OsUnfetc
7460: 68 28 70 46 69 6c 65 2c 20 30 2c 20 70 29 3b 0a  h(pFile, 0, p);.
7470: 20 20 7d 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65    }.}.#else.# de
7480: 66 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72 45  fine vdbeSorterE
7490: 78 74 65 6e 64 46 69 6c 65 28 78 2c 79 29 0a 23  xtendFile(x,y).#
74a0: 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 57 72 69  endif../*.** Wri
74b0: 74 65 20 74 68 65 20 63 75 72 72 65 6e 74 20 63  te the current c
74c0: 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 69  ontents of the i
74d0: 6e 2d 6d 65 6d 6f 72 79 20 6c 69 6e 6b 65 64 2d  n-memory linked-
74e0: 6c 69 73 74 20 74 6f 20 61 20 50 4d 41 2e 20 52  list to a PMA. R
74f0: 65 74 75 72 6e 0a 2a 2a 20 53 51 4c 49 54 45 5f  eturn.** SQLITE_
7500: 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  OK if successful
7510: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65  , or an SQLite e
7520: 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77  rror code otherw
7530: 69 73 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66  ise..**.** The f
7540: 6f 72 6d 61 74 20 6f 66 20 61 20 50 4d 41 20 69  ormat of a PMA i
7550: 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 41  s:.**.**     * A
7560: 20 76 61 72 69 6e 74 2e 20 54 68 69 73 20 76 61   varint. This va
7570: 72 69 6e 74 20 63 6f 6e 74 61 69 6e 73 20 74 68  rint contains th
7580: 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f  e total number o
7590: 66 20 62 79 74 65 73 20 6f 66 20 63 6f 6e 74 65  f bytes of conte
75a0: 6e 74 0a 2a 2a 20 20 20 20 20 20 20 69 6e 20 74  nt.**       in t
75b0: 68 65 20 50 4d 41 20 28 6e 6f 74 20 69 6e 63 6c  he PMA (not incl
75c0: 75 64 69 6e 67 20 74 68 65 20 76 61 72 69 6e 74  uding the varint
75d0: 20 69 74 73 65 6c 66 29 2e 0a 2a 2a 0a 2a 2a 20   itself)..**.** 
75e0: 20 20 20 20 2a 20 4f 6e 65 20 6f 72 20 6d 6f 72      * One or mor
75f0: 65 20 72 65 63 6f 72 64 73 20 70 61 63 6b 65 64  e records packed
7600: 20 65 6e 64 2d 74 6f 2d 65 6e 64 20 69 6e 20 6f   end-to-end in o
7610: 72 64 65 72 20 6f 66 20 61 73 63 65 6e 64 69 6e  rder of ascendin
7620: 67 20 6b 65 79 73 2e 20 0a 2a 2a 20 20 20 20 20  g keys. .**     
7630: 20 20 45 61 63 68 20 72 65 63 6f 72 64 20 63 6f    Each record co
7640: 6e 73 69 73 74 73 20 6f 66 20 61 20 76 61 72 69  nsists of a vari
7650: 6e 74 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 61  nt followed by a
7660: 20 62 6c 6f 62 20 6f 66 20 64 61 74 61 20 28 74   blob of data (t
7670: 68 65 20 0a 2a 2a 20 20 20 20 20 20 20 6b 65 79  he .**       key
7680: 29 2e 20 54 68 65 20 76 61 72 69 6e 74 20 69 73  ). The varint is
7690: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62   the number of b
76a0: 79 74 65 73 20 69 6e 20 74 68 65 20 62 6c 6f 62  ytes in the blob
76b0: 20 6f 66 20 64 61 74 61 2e 0a 2a 2f 0a 73 74 61   of data..*/.sta
76c0: 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74  tic int vdbeSort
76d0: 65 72 4c 69 73 74 54 6f 50 4d 41 28 73 71 6c 69  erListToPMA(sqli
76e0: 74 65 33 20 2a 64 62 2c 20 63 6f 6e 73 74 20 56  te3 *db, const V
76f0: 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 29  dbeCursor *pCsr)
7700: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
7710: 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20  ITE_OK;         
7720: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f      /* Return co
7730: 64 65 20 2a 2f 0a 20 20 56 64 62 65 53 6f 72 74  de */.  VdbeSort
7740: 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43  er *pSorter = pC
7750: 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 46  sr->pSorter;.  F
7760: 69 6c 65 57 72 69 74 65 72 20 77 72 69 74 65 72  ileWriter writer
7770: 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 77 72 69  ;..  memset(&wri
7780: 74 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 46  ter, 0, sizeof(F
7790: 69 6c 65 57 72 69 74 65 72 29 29 3b 0a 0a 20 20  ileWriter));..  
77a0: 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6e 49 6e  if( pSorter->nIn
77b0: 4d 65 6d 6f 72 79 3d 3d 30 20 29 7b 0a 20 20 20  Memory==0 ){.   
77c0: 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72   assert( pSorter
77d0: 2d 3e 70 52 65 63 6f 72 64 3d 3d 30 20 29 3b 0a  ->pRecord==0 );.
77e0: 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
77f0: 20 7d 0a 0a 20 20 72 63 20 3d 20 76 64 62 65 53   }..  rc = vdbeS
7800: 6f 72 74 65 72 53 6f 72 74 28 70 43 73 72 29 3b  orterSort(pCsr);
7810: 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69  ..  /* If the fi
7820: 72 73 74 20 74 65 6d 70 6f 72 61 72 79 20 50 4d  rst temporary PM
7830: 41 20 66 69 6c 65 20 68 61 73 20 6e 6f 74 20 62  A file has not b
7840: 65 65 6e 20 6f 70 65 6e 65 64 2c 20 6f 70 65 6e  een opened, open
7850: 20 69 74 20 6e 6f 77 2e 20 2a 2f 0a 20 20 69 66   it now. */.  if
7860: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
7870: 26 26 20 70 53 6f 72 74 65 72 2d 3e 70 54 65 6d  && pSorter->pTem
7880: 70 31 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20  p1==0 ){.    rc 
7890: 3d 20 76 64 62 65 53 6f 72 74 65 72 4f 70 65 6e  = vdbeSorterOpen
78a0: 54 65 6d 70 46 69 6c 65 28 64 62 2c 20 26 70 53  TempFile(db, &pS
78b0: 6f 72 74 65 72 2d 3e 70 54 65 6d 70 31 29 3b 0a  orter->pTemp1);.
78c0: 20 20 20 20 61 73 73 65 72 74 28 20 72 63 21 3d      assert( rc!=
78d0: 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53 6f  SQLITE_OK || pSo
78e0: 72 74 65 72 2d 3e 70 54 65 6d 70 31 20 29 3b 0a  rter->pTemp1 );.
78f0: 20 20 20 20 61 73 73 65 72 74 28 20 70 53 6f 72      assert( pSor
7900: 74 65 72 2d 3e 69 57 72 69 74 65 4f 66 66 3d 3d  ter->iWriteOff==
7910: 30 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  0 );.    assert(
7920: 20 70 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 3d 3d   pSorter->nPMA==
7930: 30 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54  0 );.  }..  /* T
7940: 72 79 20 74 6f 20 67 65 74 20 74 68 65 20 66 69  ry to get the fi
7950: 6c 65 20 74 6f 20 6d 65 6d 6f 72 79 20 6d 61 70  le to memory map
7960: 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   */.  if( rc==SQ
7970: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76  LITE_OK ){.    v
7980: 64 62 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46  dbeSorterExtendF
7990: 69 6c 65 28 0a 20 20 20 20 20 20 70 53 6f 72 74  ile(.      pSort
79a0: 65 72 2d 3e 70 54 65 6d 70 31 2c 20 70 53 6f 72  er->pTemp1, pSor
79b0: 74 65 72 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b  ter->iWriteOff +
79c0: 20 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d   pSorter->nInMem
79d0: 6f 72 79 20 2b 20 39 0a 20 20 20 20 29 3b 0a 20  ory + 9.    );. 
79e0: 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
79f0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 53  LITE_OK ){.    S
7a00: 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a  orterRecord *p;.
7a10: 20 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64      SorterRecord
7a20: 20 2a 70 4e 65 78 74 20 3d 20 30 3b 0a 0a 20 20   *pNext = 0;..  
7a30: 20 20 66 69 6c 65 57 72 69 74 65 72 49 6e 69 74    fileWriterInit
7a40: 28 64 62 2c 20 70 53 6f 72 74 65 72 2d 3e 70 54  (db, pSorter->pT
7a50: 65 6d 70 31 2c 20 26 77 72 69 74 65 72 2c 20 70  emp1, &writer, p
7a60: 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f 66  Sorter->iWriteOf
7a70: 66 29 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d  f);.    pSorter-
7a80: 3e 6e 50 4d 41 2b 2b 3b 0a 20 20 20 20 66 69 6c  >nPMA++;.    fil
7a90: 65 57 72 69 74 65 72 57 72 69 74 65 56 61 72 69  eWriterWriteVari
7aa0: 6e 74 28 26 77 72 69 74 65 72 2c 20 70 53 6f 72  nt(&writer, pSor
7ab0: 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 29 3b  ter->nInMemory);
7ac0: 0a 20 20 20 20 66 6f 72 28 70 3d 70 53 6f 72 74  .    for(p=pSort
7ad0: 65 72 2d 3e 70 52 65 63 6f 72 64 3b 20 70 3b 20  er->pRecord; p; 
7ae0: 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20  p=pNext){.      
7af0: 70 4e 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65  pNext = p->u.pNe
7b00: 78 74 3b 0a 20 20 20 20 20 20 66 69 6c 65 57 72  xt;.      fileWr
7b10: 69 74 65 72 57 72 69 74 65 56 61 72 69 6e 74 28  iterWriteVarint(
7b20: 26 77 72 69 74 65 72 2c 20 70 2d 3e 6e 56 61 6c  &writer, p->nVal
7b30: 29 3b 0a 20 20 20 20 20 20 66 69 6c 65 57 72 69  );.      fileWri
7b40: 74 65 72 57 72 69 74 65 28 26 77 72 69 74 65 72  terWrite(&writer
7b50: 2c 20 53 52 56 41 4c 28 70 29 2c 20 70 2d 3e 6e  , SRVAL(p), p->n
7b60: 56 61 6c 29 3b 0a 20 20 20 20 20 20 69 66 28 20  Val);.      if( 
7b70: 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79  pSorter->aMemory
7b80: 3d 3d 30 20 29 20 73 71 6c 69 74 65 33 44 62 46  ==0 ) sqlite3DbF
7b90: 72 65 65 28 64 62 2c 20 70 29 3b 0a 20 20 20 20  ree(db, p);.    
7ba0: 7d 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70  }.    pSorter->p
7bb0: 52 65 63 6f 72 64 20 3d 20 70 3b 0a 20 20 20 20  Record = p;.    
7bc0: 72 63 20 3d 20 66 69 6c 65 57 72 69 74 65 72 46  rc = fileWriterF
7bd0: 69 6e 69 73 68 28 64 62 2c 20 26 77 72 69 74 65  inish(db, &write
7be0: 72 2c 20 26 70 53 6f 72 74 65 72 2d 3e 69 57 72  r, &pSorter->iWr
7bf0: 69 74 65 4f 66 66 29 3b 0a 20 20 7d 0a 0a 20 20  iteOff);.  }..  
7c00: 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 61 4d 65  if( pSorter->aMe
7c10: 6d 6f 72 79 20 29 20 70 53 6f 72 74 65 72 2d 3e  mory ) pSorter->
7c20: 70 52 65 63 6f 72 64 20 3d 20 30 3b 0a 20 20 61  pRecord = 0;.  a
7c30: 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e  ssert( pSorter->
7c40: 70 52 65 63 6f 72 64 3d 3d 30 20 7c 7c 20 72 63  pRecord==0 || rc
7c50: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20  !=SQLITE_OK );. 
7c60: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
7c70: 2a 0a 2a 2a 20 41 64 64 20 61 20 72 65 63 6f 72  *.** Add a recor
7c80: 64 20 74 6f 20 74 68 65 20 73 6f 72 74 65 72 2e  d to the sorter.
7c90: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56  .*/.int sqlite3V
7ca0: 64 62 65 53 6f 72 74 65 72 57 72 69 74 65 28 0a  dbeSorterWrite(.
7cb0: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20    sqlite3 *db,  
7cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7cd0: 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61    /* Database ha
7ce0: 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  ndle */.  const 
7cf0: 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72  VdbeCursor *pCsr
7d00: 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72  ,         /* Sor
7d10: 74 65 72 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20  ter cursor */.  
7d20: 4d 65 6d 20 2a 70 56 61 6c 20 20 20 20 20 20 20  Mem *pVal       
7d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7d40: 2f 2a 20 4d 65 6d 6f 72 79 20 63 65 6c 6c 20 63  /* Memory cell c
7d50: 6f 6e 74 61 69 6e 69 6e 67 20 72 65 63 6f 72 64  ontaining record
7d60: 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65 53 6f 72   */.){.  VdbeSor
7d70: 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70  ter *pSorter = p
7d80: 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20  Csr->pSorter;.  
7d90: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
7da0: 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  OK;             
7db0: 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a  /* Return Code *
7dc0: 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  /.  SorterRecord
7dd0: 20 2a 70 4e 65 77 3b 20 20 20 20 20 20 20 20 20   *pNew;         
7de0: 20 20 20 20 2f 2a 20 4e 65 77 20 6c 69 73 74 20      /* New list 
7df0: 65 6c 65 6d 65 6e 74 20 2a 2f 0a 0a 20 20 69 6e  element */..  in
7e00: 74 20 62 46 6c 75 73 68 3b 20 20 20 20 20 20 20  t bFlush;       
7e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7e20: 20 54 72 75 65 20 74 6f 20 66 6c 75 73 68 20 63   True to flush c
7e30: 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65 6d 6f 72  ontents of memor
7e40: 79 20 74 6f 20 50 4d 41 20 2a 2f 0a 20 20 69 6e  y to PMA */.  in
7e50: 74 20 6e 52 65 71 3b 20 20 20 20 20 20 20 20 20  t nReq;         
7e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7e70: 20 42 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79   Bytes of memory
7e80: 20 72 65 71 75 69 72 65 64 20 2a 2f 0a 20 20 69   required */.  i
7e90: 6e 74 20 6e 50 4d 41 3b 20 20 20 20 20 20 20 20  nt nPMA;        
7ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7eb0: 2a 20 42 79 74 65 73 20 6f 66 20 50 4d 41 20 73  * Bytes of PMA s
7ec0: 70 61 63 65 20 72 65 71 75 69 72 65 64 20 2a 2f  pace required */
7ed0: 0a 0a 20 20 61 73 73 65 72 74 28 20 70 53 6f 72  ..  assert( pSor
7ee0: 74 65 72 20 29 3b 0a 0a 20 20 2f 2a 20 46 69 67  ter );..  /* Fig
7ef0: 75 72 65 20 6f 75 74 20 77 68 65 74 68 65 72 20  ure out whether 
7f00: 6f 72 20 6e 6f 74 20 74 68 65 20 63 75 72 72 65  or not the curre
7f10: 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d  nt contents of m
7f20: 65 6d 6f 72 79 20 73 68 6f 75 6c 64 20 62 65 0a  emory should be.
7f30: 20 20 2a 2a 20 66 6c 75 73 68 65 64 20 74 6f 20    ** flushed to 
7f40: 61 20 50 4d 41 20 62 65 66 6f 72 65 20 63 6f 6e  a PMA before con
7f50: 74 69 6e 75 69 6e 67 2e 20 49 66 20 73 6f 2c 20  tinuing. If so, 
7f60: 64 6f 20 73 6f 2e 0a 20 20 2a 2a 0a 20 20 2a 2a  do so..  **.  **
7f70: 20 49 66 20 75 73 69 6e 67 20 74 68 65 20 73 69   If using the si
7f80: 6e 67 6c 65 20 6c 61 72 67 65 20 61 6c 6c 6f 63  ngle large alloc
7f90: 61 74 69 6f 6e 20 6d 6f 64 65 20 28 70 53 6f 72  ation mode (pSor
7fa0: 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 21 3d 30 29  ter->aMemory!=0)
7fb0: 2c 20 74 68 65 6e 0a 20 20 2a 2a 20 66 6c 75 73  , then.  ** flus
7fc0: 68 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  h the contents o
7fd0: 66 20 6d 65 6d 6f 72 79 20 74 6f 20 61 20 6e 65  f memory to a ne
7fe0: 77 20 50 4d 41 20 69 66 20 28 61 29 20 61 74 20  w PMA if (a) at 
7ff0: 6c 65 61 73 74 20 6f 6e 65 20 76 61 6c 75 65 20  least one value 
8000: 69 73 0a 20 20 2a 2a 20 61 6c 72 65 61 64 79 20  is.  ** already 
8010: 69 6e 20 6d 65 6d 6f 72 79 20 61 6e 64 20 28 62  in memory and (b
8020: 29 20 74 68 65 20 6e 65 77 20 76 61 6c 75 65 20  ) the new value 
8030: 77 69 6c 6c 20 6e 6f 74 20 66 69 74 20 69 6e 20  will not fit in 
8040: 6d 65 6d 6f 72 79 2e 0a 20 20 2a 2a 20 0a 20 20  memory..  ** .  
8050: 2a 2a 20 4f 72 2c 20 69 66 20 75 73 69 6e 67 20  ** Or, if using 
8060: 73 65 70 61 72 61 74 65 20 61 6c 6c 6f 63 61 74  separate allocat
8070: 69 6f 6e 73 20 66 6f 72 20 65 61 63 68 20 72 65  ions for each re
8080: 63 6f 72 64 2c 20 66 6c 75 73 68 20 74 68 65 20  cord, flush the 
8090: 63 6f 6e 74 65 6e 74 73 0a 20 20 2a 2a 20 6f 66  contents.  ** of
80a0: 20 6d 65 6d 6f 72 79 20 74 6f 20 61 20 50 4d 41   memory to a PMA
80b0: 20 69 66 20 65 69 74 68 65 72 20 6f 66 20 74 68   if either of th
80c0: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 72 65 20  e following are 
80d0: 74 72 75 65 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20  true:.  **.  ** 
80e0: 20 20 2a 20 54 68 65 20 74 6f 74 61 6c 20 6d 65    * The total me
80f0: 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 65 64 20 66  mory allocated f
8100: 6f 72 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79  or the in-memory
8110: 20 6c 69 73 74 20 69 73 20 67 72 65 61 74 65 72   list is greater
8120: 20 0a 20 20 2a 2a 20 20 20 20 20 74 68 61 6e 20   .  **     than 
8130: 28 70 61 67 65 2d 73 69 7a 65 20 2a 20 63 61 63  (page-size * cac
8140: 68 65 2d 73 69 7a 65 29 2c 20 6f 72 0a 20 20 2a  he-size), or.  *
8150: 2a 0a 20 20 2a 2a 20 20 20 2a 20 54 68 65 20 74  *.  **   * The t
8160: 6f 74 61 6c 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f  otal memory allo
8170: 63 61 74 65 64 20 66 6f 72 20 74 68 65 20 69 6e  cated for the in
8180: 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20 69 73 20  -memory list is 
8190: 67 72 65 61 74 65 72 20 0a 20 20 2a 2a 20 20 20  greater .  **   
81a0: 20 20 74 68 61 6e 20 28 70 61 67 65 2d 73 69 7a    than (page-siz
81b0: 65 20 2a 20 31 30 29 20 61 6e 64 20 73 71 6c 69  e * 10) and sqli
81c0: 74 65 33 48 65 61 70 4e 65 61 72 6c 79 46 75 6c  te3HeapNearlyFul
81d0: 6c 28 29 20 72 65 74 75 72 6e 73 20 74 72 75 65  l() returns true
81e0: 2e 0a 20 20 2a 2f 0a 20 20 6e 52 65 71 20 3d 20  ..  */.  nReq = 
81f0: 70 56 61 6c 2d 3e 6e 20 2b 20 73 69 7a 65 6f 66  pVal->n + sizeof
8200: 28 53 6f 72 74 65 72 52 65 63 6f 72 64 29 3b 0a  (SorterRecord);.
8210: 20 20 6e 50 4d 41 20 3d 20 70 56 61 6c 2d 3e 6e    nPMA = pVal->n
8220: 20 2b 20 73 71 6c 69 74 65 33 56 61 72 69 6e 74   + sqlite3Varint
8230: 4c 65 6e 28 70 56 61 6c 2d 3e 6e 29 3b 0a 20 20  Len(pVal->n);.  
8240: 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 61 4d 65  if( pSorter->aMe
8250: 6d 6f 72 79 20 29 7b 0a 20 20 20 20 62 46 6c 75  mory ){.    bFlu
8260: 73 68 20 3d 20 70 53 6f 72 74 65 72 2d 3e 69 4d  sh = pSorter->iM
8270: 65 6d 6f 72 79 20 26 26 20 28 70 53 6f 72 74 65  emory && (pSorte
8280: 72 2d 3e 69 4d 65 6d 6f 72 79 2b 6e 52 65 71 29  r->iMemory+nReq)
8290: 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d   > pSorter->mxPm
82a0: 61 53 69 7a 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a  aSize;.  }else{.
82b0: 20 20 20 20 62 46 6c 75 73 68 20 3d 20 28 0a 20      bFlush = (. 
82c0: 20 20 20 20 20 20 20 28 70 53 6f 72 74 65 72 2d         (pSorter-
82d0: 3e 6e 49 6e 4d 65 6d 6f 72 79 20 3e 20 70 53 6f  >nInMemory > pSo
82e0: 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65 29  rter->mxPmaSize)
82f0: 0a 20 20 20 20 20 7c 7c 20 28 70 53 6f 72 74 65  .     || (pSorte
8300: 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20 3e 20 70  r->nInMemory > p
8310: 53 6f 72 74 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a  Sorter->mnPmaSiz
8320: 65 20 26 26 20 73 71 6c 69 74 65 33 48 65 61 70  e && sqlite3Heap
8330: 4e 65 61 72 6c 79 46 75 6c 6c 28 29 29 0a 20 20  NearlyFull()).  
8340: 20 20 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 62    );.  }.  if( b
8350: 46 6c 75 73 68 20 29 7b 0a 23 69 66 64 65 66 20  Flush ){.#ifdef 
8360: 53 51 4c 49 54 45 5f 44 45 42 55 47 0a 20 20 20  SQLITE_DEBUG.   
8370: 20 69 36 34 20 6e 45 78 70 65 63 74 20 3d 20 70   i64 nExpect = p
8380: 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f 66  Sorter->iWriteOf
8390: 66 0a 20 20 20 20 20 20 2b 20 73 71 6c 69 74 65  f.      + sqlite
83a0: 33 56 61 72 69 6e 74 4c 65 6e 28 70 53 6f 72 74  3VarintLen(pSort
83b0: 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 29 0a 20  er->nInMemory). 
83c0: 20 20 20 20 20 2b 20 70 53 6f 72 74 65 72 2d 3e       + pSorter->
83d0: 6e 49 6e 4d 65 6d 6f 72 79 3b 0a 23 65 6e 64 69  nInMemory;.#endi
83e0: 66 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53  f.    rc = vdbeS
83f0: 6f 72 74 65 72 4c 69 73 74 54 6f 50 4d 41 28 64  orterListToPMA(d
8400: 62 2c 20 70 43 73 72 29 3b 0a 20 20 20 20 70 53  b, pCsr);.    pS
8410: 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79  orter->nInMemory
8420: 20 3d 20 30 3b 0a 20 20 20 20 70 53 6f 72 74 65   = 0;.    pSorte
8430: 72 2d 3e 69 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a  r->iMemory = 0;.
8440: 20 20 20 20 61 73 73 65 72 74 28 20 72 63 21 3d      assert( rc!=
8450: 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 28 6e 45  SQLITE_OK || (nE
8460: 78 70 65 63 74 3d 3d 70 53 6f 72 74 65 72 2d 3e  xpect==pSorter->
8470: 69 57 72 69 74 65 4f 66 66 29 20 29 3b 0a 20 20  iWriteOff) );.  
8480: 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51    assert( rc!=SQ
8490: 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53 6f 72 74  LITE_OK || pSort
84a0: 65 72 2d 3e 70 52 65 63 6f 72 64 3d 3d 30 20 29  er->pRecord==0 )
84b0: 3b 0a 20 20 7d 0a 0a 20 20 70 53 6f 72 74 65 72  ;.  }..  pSorter
84c0: 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20 2b 3d 20 6e  ->nInMemory += n
84d0: 50 4d 41 3b 0a 0a 20 20 69 66 28 20 70 53 6f 72  PMA;..  if( pSor
84e0: 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 20 29 7b 0a  ter->aMemory ){.
84f0: 20 20 20 20 69 6e 74 20 6e 4d 69 6e 20 3d 20 70      int nMin = p
8500: 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 20  Sorter->iMemory 
8510: 2b 20 6e 52 65 71 3b 0a 0a 20 20 20 20 69 66 28  + nReq;..    if(
8520: 20 6e 4d 69 6e 3e 70 53 6f 72 74 65 72 2d 3e 6e   nMin>pSorter->n
8530: 4d 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20 20  Memory ){.      
8540: 75 38 20 2a 61 4e 65 77 3b 0a 20 20 20 20 20 20  u8 *aNew;.      
8550: 69 6e 74 20 6e 4e 65 77 20 3d 20 70 53 6f 72 74  int nNew = pSort
8560: 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 2a 20 32 3b  er->nMemory * 2;
8570: 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 6e 4e  .      while( nN
8580: 65 77 20 3c 20 6e 4d 69 6e 20 29 20 6e 4e 65 77  ew < nMin ) nNew
8590: 20 3d 20 6e 4e 65 77 2a 32 3b 0a 20 20 20 20 20   = nNew*2;.     
85a0: 20 69 66 28 20 6e 4e 65 77 20 3e 20 70 53 6f 72   if( nNew > pSor
85b0: 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65 20 29  ter->mxPmaSize )
85c0: 20 6e 4e 65 77 20 3d 20 70 53 6f 72 74 65 72 2d   nNew = pSorter-
85d0: 3e 6d 78 50 6d 61 53 69 7a 65 3b 0a 20 20 20 20  >mxPmaSize;.    
85e0: 20 20 69 66 28 20 6e 4e 65 77 20 3c 20 6e 4d 69    if( nNew < nMi
85f0: 6e 20 29 20 6e 4e 65 77 20 3d 20 6e 4d 69 6e 3b  n ) nNew = nMin;
8600: 0a 0a 20 20 20 20 20 20 61 4e 65 77 20 3d 20 73  ..      aNew = s
8610: 71 6c 69 74 65 33 52 65 61 6c 6c 6f 63 28 70 53  qlite3Realloc(pS
8620: 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 2c 20  orter->aMemory, 
8630: 6e 4e 65 77 29 3b 0a 20 20 20 20 20 20 69 66 28  nNew);.      if(
8640: 20 21 61 4e 65 77 20 29 20 72 65 74 75 72 6e 20   !aNew ) return 
8650: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
8660: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 52 65      pSorter->pRe
8670: 63 6f 72 64 20 3d 20 28 53 6f 72 74 65 72 52 65  cord = (SorterRe
8680: 63 6f 72 64 2a 29 0a 20 20 20 20 20 20 20 20 20  cord*).         
8690: 20 20 28 61 4e 65 77 20 2b 20 28 28 75 38 2a 29    (aNew + ((u8*)
86a0: 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64  pSorter->pRecord
86b0: 20 2d 20 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d   - pSorter->aMem
86c0: 6f 72 79 29 29 3b 0a 20 20 20 20 20 20 70 53 6f  ory));.      pSo
86d0: 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 20 3d 20  rter->aMemory = 
86e0: 61 4e 65 77 3b 0a 20 20 20 20 20 20 70 53 6f 72  aNew;.      pSor
86f0: 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 3d 20 6e  ter->nMemory = n
8700: 4e 65 77 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  New;.    }..    
8710: 70 4e 65 77 20 3d 20 28 53 6f 72 74 65 72 52 65  pNew = (SorterRe
8720: 63 6f 72 64 2a 29 26 70 53 6f 72 74 65 72 2d 3e  cord*)&pSorter->
8730: 61 4d 65 6d 6f 72 79 5b 70 53 6f 72 74 65 72 2d  aMemory[pSorter-
8740: 3e 69 4d 65 6d 6f 72 79 5d 3b 0a 20 20 20 20 70  >iMemory];.    p
8750: 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 20  Sorter->iMemory 
8760: 2b 3d 20 52 4f 55 4e 44 38 28 6e 52 65 71 29 3b  += ROUND8(nReq);
8770: 0a 20 20 20 20 70 4e 65 77 2d 3e 75 2e 69 4e 65  .    pNew->u.iNe
8780: 78 74 20 3d 20 28 75 38 2a 29 28 70 53 6f 72 74  xt = (u8*)(pSort
8790: 65 72 2d 3e 70 52 65 63 6f 72 64 29 20 2d 20 70  er->pRecord) - p
87a0: 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 3b  Sorter->aMemory;
87b0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 4e  .  }else{.    pN
87c0: 65 77 20 3d 20 28 53 6f 72 74 65 72 52 65 63 6f  ew = (SorterReco
87d0: 72 64 20 2a 29 73 71 6c 69 74 65 33 44 62 4d 61  rd *)sqlite3DbMa
87e0: 6c 6c 6f 63 52 61 77 28 64 62 2c 20 70 56 61 6c  llocRaw(db, pVal
87f0: 2d 3e 6e 2b 73 69 7a 65 6f 66 28 53 6f 72 74 65  ->n+sizeof(Sorte
8800: 72 52 65 63 6f 72 64 29 29 3b 0a 20 20 20 20 69  rRecord));.    i
8810: 66 28 20 70 4e 65 77 3d 3d 30 20 29 7b 0a 20 20  f( pNew==0 ){.  
8820: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
8830: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20  E_NOMEM;.    }. 
8840: 20 20 20 70 4e 65 77 2d 3e 75 2e 70 4e 65 78 74     pNew->u.pNext
8850: 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63   = pSorter->pRec
8860: 6f 72 64 3b 0a 20 20 7d 0a 0a 20 20 6d 65 6d 63  ord;.  }..  memc
8870: 70 79 28 53 52 56 41 4c 28 70 4e 65 77 29 2c 20  py(SRVAL(pNew), 
8880: 70 56 61 6c 2d 3e 7a 2c 20 70 56 61 6c 2d 3e 6e  pVal->z, pVal->n
8890: 29 3b 0a 20 20 70 4e 65 77 2d 3e 6e 56 61 6c 20  );.  pNew->nVal 
88a0: 3d 20 70 56 61 6c 2d 3e 6e 3b 0a 20 20 70 53 6f  = pVal->n;.  pSo
88b0: 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 3d 20  rter->pRecord = 
88c0: 70 4e 65 77 3b 0a 0a 20 20 72 65 74 75 72 6e 20  pNew;..  return 
88d0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 48 65 6c  rc;.}../*.** Hel
88e0: 70 65 72 20 66 75 6e 63 74 69 6f 6e 20 66 6f 72  per function for
88f0: 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74   sqlite3VdbeSort
8900: 65 72 52 65 77 69 6e 64 28 29 2e 20 0a 2a 2f 0a  erRewind(). .*/.
8910: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53  static int vdbeS
8920: 6f 72 74 65 72 49 6e 69 74 4d 65 72 67 65 28 0a  orterInitMerge(.
8930: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20    sqlite3 *db,  
8940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8950: 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61    /* Database ha
8960: 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  ndle */.  const 
8970: 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72  VdbeCursor *pCsr
8980: 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72  ,         /* Cur
8990: 73 6f 72 20 68 61 6e 64 6c 65 20 66 6f 72 20 74  sor handle for t
89a0: 68 69 73 20 73 6f 72 74 65 72 20 2a 2f 0a 20 20  his sorter */.  
89b0: 69 36 34 20 2a 70 6e 42 79 74 65 20 20 20 20 20  i64 *pnByte     
89c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
89d0: 2f 2a 20 53 75 6d 20 6f 66 20 62 79 74 65 73 20  /* Sum of bytes 
89e0: 69 6e 20 61 6c 6c 20 6f 70 65 6e 65 64 20 50 4d  in all opened PM
89f0: 41 73 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65 53  As */.){.  VdbeS
8a00: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d  orter *pSorter =
8a10: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a   pCsr->pSorter;.
8a20: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
8a30: 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20  E_OK;           
8a40: 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
8a50: 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20   */.  int i;    
8a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8a70: 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f        /* Used to
8a80: 20 69 74 65 72 61 74 6f 72 20 74 68 72 6f 75 67   iterator throug
8a90: 68 20 61 49 74 65 72 5b 5d 20 2a 2f 0a 20 20 69  h aIter[] */.  i
8aa0: 36 34 20 6e 42 79 74 65 20 3d 20 30 3b 20 20 20  64 nByte = 0;   
8ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8ac0: 2a 20 54 6f 74 61 6c 20 62 79 74 65 73 20 69 6e  * Total bytes in
8ad0: 20 61 6c 6c 20 6f 70 65 6e 65 64 20 50 4d 41 73   all opened PMAs
8ae0: 20 2a 2f 0a 0a 20 20 2f 2a 20 49 6e 69 74 69 61   */..  /* Initia
8af0: 6c 69 7a 65 20 74 68 65 20 69 74 65 72 61 74 6f  lize the iterato
8b00: 72 73 2e 20 49 74 65 72 61 74 6f 72 20 30 20 63  rs. Iterator 0 c
8b10: 6f 6e 74 61 69 6e 73 20 74 68 65 20 6f 6c 64 65  ontains the olde
8b20: 73 74 20 64 61 74 61 2e 20 2a 2f 0a 20 20 66 6f  st data. */.  fo
8b30: 72 28 69 3d 30 3b 20 69 3c 53 4f 52 54 45 52 5f  r(i=0; i<SORTER_
8b40: 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3b  MAX_MERGE_COUNT;
8b50: 20 69 2b 2b 29 7b 0a 20 20 20 20 56 64 62 65 53   i++){.    VdbeS
8b60: 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74 65 72  orterIter *pIter
8b70: 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 49 74   = &pSorter->aIt
8b80: 65 72 5b 69 5d 3b 0a 20 20 20 20 72 63 20 3d 20  er[i];.    rc = 
8b90: 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 49 6e  vdbeSorterIterIn
8ba0: 69 74 28 64 62 2c 20 70 53 6f 72 74 65 72 2c 20  it(db, pSorter, 
8bb0: 70 53 6f 72 74 65 72 2d 3e 69 52 65 61 64 4f 66  pSorter->iReadOf
8bc0: 66 2c 20 70 49 74 65 72 2c 20 26 6e 42 79 74 65  f, pIter, &nByte
8bd0: 29 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  );.    pSorter->
8be0: 69 52 65 61 64 4f 66 66 20 3d 20 70 49 74 65 72  iReadOff = pIter
8bf0: 2d 3e 69 45 6f 66 3b 0a 20 20 20 20 61 73 73 65  ->iEof;.    asse
8c00: 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  rt( rc!=SQLITE_O
8c10: 4b 20 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 69 52  K || pSorter->iR
8c20: 65 61 64 4f 66 66 3c 3d 70 53 6f 72 74 65 72 2d  eadOff<=pSorter-
8c30: 3e 69 57 72 69 74 65 4f 66 66 20 29 3b 0a 20 20  >iWriteOff );.  
8c40: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
8c50: 5f 4f 4b 20 7c 7c 20 70 53 6f 72 74 65 72 2d 3e  _OK || pSorter->
8c60: 69 52 65 61 64 4f 66 66 3e 3d 70 53 6f 72 74 65  iReadOff>=pSorte
8c70: 72 2d 3e 69 57 72 69 74 65 4f 66 66 20 29 20 62  r->iWriteOff ) b
8c80: 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  reak;.  }..  /* 
8c90: 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 61  Initialize the a
8ca0: 54 72 65 65 5b 5d 20 61 72 72 61 79 2e 20 2a 2f  Tree[] array. */
8cb0: 0a 20 20 66 6f 72 28 69 3d 70 53 6f 72 74 65 72  .  for(i=pSorter
8cc0: 2d 3e 6e 54 72 65 65 2d 31 3b 20 72 63 3d 3d 53  ->nTree-1; rc==S
8cd0: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3e 30 3b  QLITE_OK && i>0;
8ce0: 20 69 2d 2d 29 7b 0a 20 20 20 20 72 63 20 3d 20   i--){.    rc = 
8cf0: 76 64 62 65 53 6f 72 74 65 72 44 6f 43 6f 6d 70  vdbeSorterDoComp
8d00: 61 72 65 28 70 43 73 72 2c 20 69 29 3b 0a 20 20  are(pCsr, i);.  
8d10: 7d 0a 0a 20 20 2a 70 6e 42 79 74 65 20 3d 20 6e  }..  *pnByte = n
8d20: 42 79 74 65 3b 0a 20 20 72 65 74 75 72 6e 20 72  Byte;.  return r
8d30: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 6e 63 65  c;.}../*.** Once
8d40: 20 74 68 65 20 73 6f 72 74 65 72 20 68 61 73 20   the sorter has 
8d50: 62 65 65 6e 20 70 6f 70 75 6c 61 74 65 64 2c 20  been populated, 
8d60: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  this function is
8d70: 20 63 61 6c 6c 65 64 20 74 6f 20 70 72 65 70 61   called to prepa
8d80: 72 65 0a 2a 2a 20 66 6f 72 20 69 74 65 72 61 74  re.** for iterat
8d90: 69 6e 67 20 74 68 72 6f 75 67 68 20 69 74 73 20  ing through its 
8da0: 63 6f 6e 74 65 6e 74 73 20 69 6e 20 73 6f 72 74  contents in sort
8db0: 65 64 20 6f 72 64 65 72 2e 0a 2a 2f 0a 69 6e 74  ed order..*/.int
8dc0: 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74   sqlite3VdbeSort
8dd0: 65 72 52 65 77 69 6e 64 28 73 71 6c 69 74 65 33  erRewind(sqlite3
8de0: 20 2a 64 62 2c 20 63 6f 6e 73 74 20 56 64 62 65   *db, const Vdbe
8df0: 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e  Cursor *pCsr, in
8e00: 74 20 2a 70 62 45 6f 66 29 7b 0a 20 20 56 64 62  t *pbEof){.  Vdb
8e10: 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72  eSorter *pSorter
8e20: 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72   = pCsr->pSorter
8e30: 3b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  ;.  int rc;     
8e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8e50: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f      /* Return co
8e60: 64 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  de */.  sqlite3_
8e70: 66 69 6c 65 20 2a 70 54 65 6d 70 32 20 3d 20 30  file *pTemp2 = 0
8e80: 3b 20 20 20 20 20 20 20 2f 2a 20 53 65 63 6f 6e  ;       /* Secon
8e90: 64 20 74 65 6d 70 20 66 69 6c 65 20 74 6f 20 75  d temp file to u
8ea0: 73 65 20 2a 2f 0a 20 20 69 36 34 20 69 57 72 69  se */.  i64 iWri
8eb0: 74 65 32 20 3d 20 30 3b 20 20 20 20 20 20 20 20  te2 = 0;        
8ec0: 20 20 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65          /* Write
8ed0: 20 6f 66 66 73 65 74 20 66 6f 72 20 70 54 65 6d   offset for pTem
8ee0: 70 32 20 2a 2f 0a 20 20 69 6e 74 20 6e 49 74 65  p2 */.  int nIte
8ef0: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
8f00: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
8f10: 72 20 6f 66 20 69 74 65 72 61 74 6f 72 73 20 75  r of iterators u
8f20: 73 65 64 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79  sed */.  int nBy
8f30: 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  te;             
8f40: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65           /* Byte
8f50: 73 20 6f 66 20 73 70 61 63 65 20 72 65 71 75 69  s of space requi
8f60: 72 65 64 20 66 6f 72 20 61 49 74 65 72 2f 61 54  red for aIter/aT
8f70: 72 65 65 20 2a 2f 0a 20 20 69 6e 74 20 4e 20 3d  ree */.  int N =
8f80: 20 32 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   2;             
8f90: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 77 65           /* Powe
8fa0: 72 20 6f 66 20 32 20 3e 3d 20 6e 49 74 65 72 20  r of 2 >= nIter 
8fb0: 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 53  */..  assert( pS
8fc0: 6f 72 74 65 72 20 29 3b 0a 0a 20 20 2f 2a 20 49  orter );..  /* I
8fd0: 66 20 6e 6f 20 64 61 74 61 20 68 61 73 20 62 65  f no data has be
8fe0: 65 6e 20 77 72 69 74 74 65 6e 20 74 6f 20 64 69  en written to di
8ff0: 73 6b 2c 20 74 68 65 6e 20 64 6f 20 6e 6f 74 20  sk, then do not 
9000: 64 6f 20 73 6f 20 6e 6f 77 2e 20 49 6e 73 74 65  do so now. Inste
9010: 61 64 2c 0a 20 20 2a 2a 20 73 6f 72 74 20 74 68  ad,.  ** sort th
9020: 65 20 56 64 62 65 53 6f 72 74 65 72 2e 70 52 65  e VdbeSorter.pRe
9030: 63 6f 72 64 20 6c 69 73 74 2e 20 54 68 65 20 76  cord list. The v
9040: 64 62 65 20 6c 61 79 65 72 20 77 69 6c 6c 20 72  dbe layer will r
9050: 65 61 64 20 64 61 74 61 20 64 69 72 65 63 74 6c  ead data directl
9060: 79 0a 20 20 2a 2a 20 66 72 6f 6d 20 74 68 65 20  y.  ** from the 
9070: 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 2e 20  in-memory list. 
9080: 20 2a 2f 0a 20 20 69 66 28 20 70 53 6f 72 74 65   */.  if( pSorte
9090: 72 2d 3e 6e 50 4d 41 3d 3d 30 20 29 7b 0a 20 20  r->nPMA==0 ){.  
90a0: 20 20 2a 70 62 45 6f 66 20 3d 20 21 70 53 6f 72    *pbEof = !pSor
90b0: 74 65 72 2d 3e 70 52 65 63 6f 72 64 3b 0a 20 20  ter->pRecord;.  
90c0: 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65    assert( pSorte
90d0: 72 2d 3e 61 54 72 65 65 3d 3d 30 20 29 3b 0a 20  r->aTree==0 );. 
90e0: 20 20 20 72 65 74 75 72 6e 20 76 64 62 65 53 6f     return vdbeSo
90f0: 72 74 65 72 53 6f 72 74 28 70 43 73 72 29 3b 0a  rterSort(pCsr);.
9100: 20 20 7d 0a 0a 20 20 2f 2a 20 57 72 69 74 65 20    }..  /* Write 
9110: 74 68 65 20 63 75 72 72 65 6e 74 20 69 6e 2d 6d  the current in-m
9120: 65 6d 6f 72 79 20 6c 69 73 74 20 74 6f 20 61 20  emory list to a 
9130: 50 4d 41 2e 20 2a 2f 0a 20 20 72 63 20 3d 20 76  PMA. */.  rc = v
9140: 64 62 65 53 6f 72 74 65 72 4c 69 73 74 54 6f 50  dbeSorterListToP
9150: 4d 41 28 64 62 2c 20 70 43 73 72 29 3b 0a 20 20  MA(db, pCsr);.  
9160: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
9170: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a  K ) return rc;..
9180: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 73 70    /* Allocate sp
9190: 61 63 65 20 66 6f 72 20 61 49 74 65 72 5b 5d 20  ace for aIter[] 
91a0: 61 6e 64 20 61 54 72 65 65 5b 5d 2e 20 2a 2f 0a  and aTree[]. */.
91b0: 20 20 6e 49 74 65 72 20 3d 20 70 53 6f 72 74 65    nIter = pSorte
91c0: 72 2d 3e 6e 50 4d 41 3b 0a 20 20 69 66 28 20 6e  r->nPMA;.  if( n
91d0: 49 74 65 72 3e 53 4f 52 54 45 52 5f 4d 41 58 5f  Iter>SORTER_MAX_
91e0: 4d 45 52 47 45 5f 43 4f 55 4e 54 20 29 20 6e 49  MERGE_COUNT ) nI
91f0: 74 65 72 20 3d 20 53 4f 52 54 45 52 5f 4d 41 58  ter = SORTER_MAX
9200: 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3b 0a 20 20  _MERGE_COUNT;.  
9210: 61 73 73 65 72 74 28 20 6e 49 74 65 72 3e 30 20  assert( nIter>0 
9220: 29 3b 0a 20 20 77 68 69 6c 65 28 20 4e 3c 6e 49  );.  while( N<nI
9230: 74 65 72 20 29 20 4e 20 2b 3d 20 4e 3b 0a 20 20  ter ) N += N;.  
9240: 6e 42 79 74 65 20 3d 20 4e 20 2a 20 28 73 69 7a  nByte = N * (siz
9250: 65 6f 66 28 69 6e 74 29 20 2b 20 73 69 7a 65 6f  eof(int) + sizeo
9260: 66 28 56 64 62 65 53 6f 72 74 65 72 49 74 65 72  f(VdbeSorterIter
9270: 29 29 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 61  ));.  pSorter->a
9280: 49 74 65 72 20 3d 20 28 56 64 62 65 53 6f 72 74  Iter = (VdbeSort
9290: 65 72 49 74 65 72 20 2a 29 73 71 6c 69 74 65 33  erIter *)sqlite3
92a0: 44 62 4d 61 6c 6c 6f 63 5a 65 72 6f 28 64 62 2c  DbMallocZero(db,
92b0: 20 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20 21   nByte);.  if( !
92c0: 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 20 29  pSorter->aIter )
92d0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
92e0: 4f 4d 45 4d 3b 0a 20 20 70 53 6f 72 74 65 72 2d  OMEM;.  pSorter-
92f0: 3e 61 54 72 65 65 20 3d 20 28 69 6e 74 20 2a 29  >aTree = (int *)
9300: 26 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b  &pSorter->aIter[
9310: 4e 5d 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6e  N];.  pSorter->n
9320: 54 72 65 65 20 3d 20 4e 3b 0a 0a 20 20 77 68 69  Tree = N;..  whi
9330: 6c 65 28 31 29 7b 0a 20 20 20 20 69 6e 74 20 69  le(1){.    int i
9340: 4e 65 77 3b 20 20 20 20 20 20 20 20 20 20 20 20  New;            
9350: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65           /* Inde
9360: 78 20 6f 66 20 6e 65 77 2c 20 6d 65 72 67 65 64  x of new, merged
9370: 2c 20 50 4d 41 20 2a 2f 0a 0a 20 20 20 20 66 6f  , PMA */..    fo
9380: 72 28 69 4e 65 77 3d 30 3b 20 0a 20 20 20 20 20  r(iNew=0; .     
9390: 20 20 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b     rc==SQLITE_OK
93a0: 20 26 26 20 69 4e 65 77 2a 53 4f 52 54 45 52 5f   && iNew*SORTER_
93b0: 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3c  MAX_MERGE_COUNT<
93c0: 70 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 3b 20 0a  pSorter->nPMA; .
93d0: 20 20 20 20 20 20 20 20 69 4e 65 77 2b 2b 0a 20          iNew++. 
93e0: 20 20 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20     ){.      int 
93f0: 72 63 32 3b 20 20 20 20 20 20 20 20 20 20 20 20  rc2;            
9400: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
9410: 6e 20 63 6f 64 65 20 66 72 6f 6d 20 66 69 6c 65  n code from file
9420: 57 72 69 74 65 72 46 69 6e 69 73 68 28 29 20 2a  WriterFinish() *
9430: 2f 0a 20 20 20 20 20 20 46 69 6c 65 57 72 69 74  /.      FileWrit
9440: 65 72 20 77 72 69 74 65 72 3b 20 20 20 20 20 20  er writer;      
9450: 20 20 20 20 2f 2a 20 4f 62 6a 65 63 74 20 75 73      /* Object us
9460: 65 64 20 74 6f 20 77 72 69 74 65 20 74 6f 20 64  ed to write to d
9470: 69 73 6b 20 2a 2f 0a 20 20 20 20 20 20 69 36 34  isk */.      i64
9480: 20 6e 57 72 69 74 65 3b 20 20 20 20 20 20 20 20   nWrite;        
9490: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
94a0: 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 6e  er of bytes in n
94b0: 65 77 20 50 4d 41 20 2a 2f 0a 0a 20 20 20 20 20  ew PMA */..     
94c0: 20 6d 65 6d 73 65 74 28 26 77 72 69 74 65 72 2c   memset(&writer,
94d0: 20 30 2c 20 73 69 7a 65 6f 66 28 46 69 6c 65 57   0, sizeof(FileW
94e0: 72 69 74 65 72 29 29 3b 0a 0a 20 20 20 20 20 20  riter));..      
94f0: 2f 2a 20 49 66 20 74 68 65 72 65 20 61 72 65 20  /* If there are 
9500: 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45  SORTER_MAX_MERGE
9510: 5f 43 4f 55 4e 54 20 6f 72 20 6c 65 73 73 20 50  _COUNT or less P
9520: 4d 41 73 20 69 6e 20 66 69 6c 65 20 70 54 65 6d  MAs in file pTem
9530: 70 31 2c 0a 20 20 20 20 20 20 2a 2a 20 69 6e 69  p1,.      ** ini
9540: 74 69 61 6c 69 7a 65 20 61 6e 20 69 74 65 72 61  tialize an itera
9550: 74 6f 72 20 66 6f 72 20 65 61 63 68 20 6f 66 20  tor for each of 
9560: 74 68 65 6d 20 61 6e 64 20 62 72 65 61 6b 20 6f  them and break o
9570: 75 74 20 6f 66 20 74 68 65 20 6c 6f 6f 70 2e 0a  ut of the loop..
9580: 20 20 20 20 20 20 2a 2a 20 54 68 65 73 65 20 69        ** These i
9590: 74 65 72 61 74 6f 72 73 20 77 69 6c 6c 20 62 65  terators will be
95a0: 20 69 6e 63 72 65 6d 65 6e 74 61 6c 6c 79 20 6d   incrementally m
95b0: 65 72 67 65 64 20 61 73 20 74 68 65 20 56 44 42  erged as the VDB
95c0: 45 20 6c 61 79 65 72 20 63 61 6c 6c 73 0a 20 20  E layer calls.  
95d0: 20 20 20 20 2a 2a 20 73 71 6c 69 74 65 33 56 64      ** sqlite3Vd
95e0: 62 65 53 6f 72 74 65 72 4e 65 78 74 28 29 2e 0a  beSorterNext()..
95f0: 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a        **.      *
9600: 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20  * Otherwise, if 
9610: 70 54 65 6d 70 31 20 63 6f 6e 74 61 69 6e 73 20  pTemp1 contains 
9620: 6d 6f 72 65 20 74 68 61 6e 20 53 4f 52 54 45 52  more than SORTER
9630: 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
9640: 20 50 4d 41 73 2c 0a 20 20 20 20 20 20 2a 2a 20   PMAs,.      ** 
9650: 69 6e 69 74 69 61 6c 69 7a 65 20 69 6e 74 65 72  initialize inter
9660: 61 74 6f 72 73 20 66 6f 72 20 53 4f 52 54 45 52  ators for SORTER
9670: 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
9680: 20 6f 66 20 74 68 65 6d 2e 20 54 68 65 73 65 20   of them. These 
9690: 50 4d 41 73 0a 20 20 20 20 20 20 2a 2a 20 61 72  PMAs.      ** ar
96a0: 65 20 6d 65 72 67 65 64 20 69 6e 74 6f 20 61 20  e merged into a 
96b0: 73 69 6e 67 6c 65 20 50 4d 41 20 74 68 61 74 20  single PMA that 
96c0: 69 73 20 77 72 69 74 74 65 6e 20 74 6f 20 66 69  is written to fi
96d0: 6c 65 20 70 54 65 6d 70 32 2e 0a 20 20 20 20 20  le pTemp2..     
96e0: 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 76   */.      rc = v
96f0: 64 62 65 53 6f 72 74 65 72 49 6e 69 74 4d 65 72  dbeSorterInitMer
9700: 67 65 28 64 62 2c 20 70 43 73 72 2c 20 26 6e 57  ge(db, pCsr, &nW
9710: 72 69 74 65 29 3b 0a 20 20 20 20 20 20 61 73 73  rite);.      ass
9720: 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f  ert( rc!=SQLITE_
9730: 4f 4b 20 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 61  OK || pSorter->a
9740: 49 74 65 72 5b 20 70 53 6f 72 74 65 72 2d 3e 61  Iter[ pSorter->a
9750: 54 72 65 65 5b 31 5d 20 5d 2e 70 46 69 6c 65 20  Tree[1] ].pFile 
9760: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  );.      if( rc!
9770: 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53  =SQLITE_OK || pS
9780: 6f 72 74 65 72 2d 3e 6e 50 4d 41 3c 3d 53 4f 52  orter->nPMA<=SOR
9790: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
97a0: 55 4e 54 20 29 7b 0a 20 20 20 20 20 20 20 20 62  UNT ){.        b
97b0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20  reak;.      }.. 
97c0: 20 20 20 20 20 2f 2a 20 4f 70 65 6e 20 74 68 65       /* Open the
97d0: 20 73 65 63 6f 6e 64 20 74 65 6d 70 20 66 69 6c   second temp fil
97e0: 65 2c 20 69 66 20 69 74 20 69 73 20 6e 6f 74 20  e, if it is not 
97f0: 61 6c 72 65 61 64 79 20 6f 70 65 6e 2e 20 2a 2f  already open. */
9800: 0a 20 20 20 20 20 20 69 66 28 20 70 54 65 6d 70  .      if( pTemp
9810: 32 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  2==0 ){.        
9820: 61 73 73 65 72 74 28 20 69 57 72 69 74 65 32 3d  assert( iWrite2=
9830: 3d 30 20 29 3b 0a 20 20 20 20 20 20 20 20 72 63  =0 );.        rc
9840: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4f 70 65   = vdbeSorterOpe
9850: 6e 54 65 6d 70 46 69 6c 65 28 64 62 2c 20 26 70  nTempFile(db, &p
9860: 54 65 6d 70 32 29 3b 0a 20 20 20 20 20 20 20 20  Temp2);.        
9870: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
9880: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 76  K ){.          v
9890: 64 62 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46  dbeSorterExtendF
98a0: 69 6c 65 28 70 54 65 6d 70 32 2c 20 70 53 6f 72  ile(pTemp2, pSor
98b0: 74 65 72 2d 3e 69 57 72 69 74 65 4f 66 66 29 3b  ter->iWriteOff);
98c0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
98d0: 20 7d 0a 0a 20 20 20 20 20 20 69 66 28 20 72 63   }..      if( rc
98e0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
98f0: 20 20 20 20 20 20 20 69 6e 74 20 62 45 6f 66 20         int bEof 
9900: 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 66 69 6c  = 0;.        fil
9910: 65 57 72 69 74 65 72 49 6e 69 74 28 64 62 2c 20  eWriterInit(db, 
9920: 70 54 65 6d 70 32 2c 20 26 77 72 69 74 65 72 2c  pTemp2, &writer,
9930: 20 69 57 72 69 74 65 32 29 3b 0a 20 20 20 20 20   iWrite2);.     
9940: 20 20 20 66 69 6c 65 57 72 69 74 65 72 57 72 69     fileWriterWri
9950: 74 65 56 61 72 69 6e 74 28 26 77 72 69 74 65 72  teVarint(&writer
9960: 2c 20 6e 57 72 69 74 65 29 3b 0a 20 20 20 20 20  , nWrite);.     
9970: 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51     while( rc==SQ
9980: 4c 49 54 45 5f 4f 4b 20 26 26 20 62 45 6f 66 3d  LITE_OK && bEof=
9990: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  =0 ){.          
99a0: 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a  VdbeSorterIter *
99b0: 70 49 74 65 72 20 3d 20 26 70 53 6f 72 74 65 72  pIter = &pSorter
99c0: 2d 3e 61 49 74 65 72 5b 20 70 53 6f 72 74 65 72  ->aIter[ pSorter
99d0: 2d 3e 61 54 72 65 65 5b 31 5d 20 5d 3b 0a 20 20  ->aTree[1] ];.  
99e0: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
99f0: 70 49 74 65 72 2d 3e 70 46 69 6c 65 20 29 3b 0a  pIter->pFile );.
9a00: 0a 20 20 20 20 20 20 20 20 20 20 66 69 6c 65 57  .          fileW
9a10: 72 69 74 65 72 57 72 69 74 65 56 61 72 69 6e 74  riterWriteVarint
9a20: 28 26 77 72 69 74 65 72 2c 20 70 49 74 65 72 2d  (&writer, pIter-
9a30: 3e 6e 4b 65 79 29 3b 0a 20 20 20 20 20 20 20 20  >nKey);.        
9a40: 20 20 66 69 6c 65 57 72 69 74 65 72 57 72 69 74    fileWriterWrit
9a50: 65 28 26 77 72 69 74 65 72 2c 20 70 49 74 65 72  e(&writer, pIter
9a60: 2d 3e 61 4b 65 79 2c 20 70 49 74 65 72 2d 3e 6e  ->aKey, pIter->n
9a70: 4b 65 79 29 3b 0a 20 20 20 20 20 20 20 20 20 20  Key);.          
9a80: 72 63 20 3d 20 73 71 6c 69 74 65 33 56 64 62 65  rc = sqlite3Vdbe
9a90: 53 6f 72 74 65 72 4e 65 78 74 28 64 62 2c 20 70  SorterNext(db, p
9aa0: 43 73 72 2c 20 26 62 45 6f 66 29 3b 0a 20 20 20  Csr, &bEof);.   
9ab0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 72       }.        r
9ac0: 63 32 20 3d 20 66 69 6c 65 57 72 69 74 65 72 46  c2 = fileWriterF
9ad0: 69 6e 69 73 68 28 64 62 2c 20 26 77 72 69 74 65  inish(db, &write
9ae0: 72 2c 20 26 69 57 72 69 74 65 32 29 3b 0a 20 20  r, &iWrite2);.  
9af0: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
9b00: 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 72  LITE_OK ) rc = r
9b10: 63 32 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  c2;.      }.    
9b20: 7d 0a 20 20 20 20 69 66 28 20 72 63 20 29 20 62  }.    if( rc ) b
9b30: 72 65 61 6b 3b 0a 0a 20 20 20 20 69 66 28 20 70  reak;..    if( p
9b40: 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 3c 3d 53 4f  Sorter->nPMA<=SO
9b50: 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
9b60: 4f 55 4e 54 20 29 7b 0a 20 20 20 20 20 20 62 72  OUNT ){.      br
9b70: 65 61 6b 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  eak;.    }else{.
9b80: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69        sqlite3_fi
9b90: 6c 65 20 2a 70 54 6d 70 20 3d 20 70 53 6f 72 74  le *pTmp = pSort
9ba0: 65 72 2d 3e 70 54 65 6d 70 31 3b 0a 20 20 20 20  er->pTemp1;.    
9bb0: 20 20 70 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 20    pSorter->nPMA 
9bc0: 3d 20 69 4e 65 77 3b 0a 20 20 20 20 20 20 70 53  = iNew;.      pS
9bd0: 6f 72 74 65 72 2d 3e 70 54 65 6d 70 31 20 3d 20  orter->pTemp1 = 
9be0: 70 54 65 6d 70 32 3b 0a 20 20 20 20 20 20 70 54  pTemp2;.      pT
9bf0: 65 6d 70 32 20 3d 20 70 54 6d 70 3b 0a 20 20 20  emp2 = pTmp;.   
9c00: 20 20 20 70 53 6f 72 74 65 72 2d 3e 69 57 72 69     pSorter->iWri
9c10: 74 65 4f 66 66 20 3d 20 69 57 72 69 74 65 32 3b  teOff = iWrite2;
9c20: 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  .      pSorter->
9c30: 69 52 65 61 64 4f 66 66 20 3d 20 30 3b 0a 20 20  iReadOff = 0;.  
9c40: 20 20 20 20 69 57 72 69 74 65 32 20 3d 20 30 3b      iWrite2 = 0;
9c50: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
9c60: 28 20 70 54 65 6d 70 32 20 29 7b 0a 20 20 20 20  ( pTemp2 ){.    
9c70: 73 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 46 72  sqlite3OsCloseFr
9c80: 65 65 28 70 54 65 6d 70 32 29 3b 0a 20 20 7d 0a  ee(pTemp2);.  }.
9c90: 20 20 2a 70 62 45 6f 66 20 3d 20 28 70 53 6f 72    *pbEof = (pSor
9ca0: 74 65 72 2d 3e 61 49 74 65 72 5b 70 53 6f 72 74  ter->aIter[pSort
9cb0: 65 72 2d 3e 61 54 72 65 65 5b 31 5d 5d 2e 70 46  er->aTree[1]].pF
9cc0: 69 6c 65 3d 3d 30 29 3b 0a 20 20 72 65 74 75 72  ile==0);.  retur
9cd0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  n rc;.}../*.** A
9ce0: 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20 6e 65  dvance to the ne
9cf0: 78 74 20 65 6c 65 6d 65 6e 74 20 69 6e 20 74 68  xt element in th
9d00: 65 20 73 6f 72 74 65 72 2e 0a 2a 2f 0a 69 6e 74  e sorter..*/.int
9d10: 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74   sqlite3VdbeSort
9d20: 65 72 4e 65 78 74 28 73 71 6c 69 74 65 33 20 2a  erNext(sqlite3 *
9d30: 64 62 2c 20 63 6f 6e 73 74 20 56 64 62 65 43 75  db, const VdbeCu
9d40: 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74 20  rsor *pCsr, int 
9d50: 2a 70 62 45 6f 66 29 7b 0a 20 20 56 64 62 65 53  *pbEof){.  VdbeS
9d60: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d  orter *pSorter =
9d70: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a   pCsr->pSorter;.
9d80: 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
9d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9da0: 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
9db0: 20 2a 2f 0a 0a 20 20 69 66 28 20 70 53 6f 72 74   */..  if( pSort
9dc0: 65 72 2d 3e 61 54 72 65 65 20 29 7b 0a 20 20 20  er->aTree ){.   
9dd0: 20 69 6e 74 20 69 50 72 65 76 20 3d 20 70 53 6f   int iPrev = pSo
9de0: 72 74 65 72 2d 3e 61 54 72 65 65 5b 31 5d 3b 2f  rter->aTree[1];/
9df0: 2a 20 49 6e 64 65 78 20 6f 66 20 69 74 65 72 61  * Index of itera
9e00: 74 6f 72 20 74 6f 20 61 64 76 61 6e 63 65 20 2a  tor to advance *
9e10: 2f 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53  /.    rc = vdbeS
9e20: 6f 72 74 65 72 49 74 65 72 4e 65 78 74 28 64 62  orterIterNext(db
9e30: 2c 20 26 70 53 6f 72 74 65 72 2d 3e 61 49 74 65  , &pSorter->aIte
9e40: 72 5b 69 50 72 65 76 5d 29 3b 0a 20 20 20 20 69  r[iPrev]);.    i
9e50: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
9e60: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b   ){.      int i;
9e70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9e80: 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f        /* Index o
9e90: 66 20 61 54 72 65 65 5b 5d 20 74 6f 20 72 65 63  f aTree[] to rec
9ea0: 61 6c 63 75 6c 61 74 65 20 2a 2f 0a 20 20 20 20  alculate */.    
9eb0: 20 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72    VdbeSorterIter
9ec0: 20 2a 70 49 74 65 72 31 3b 20 20 20 20 20 2f 2a   *pIter1;     /*
9ed0: 20 46 69 72 73 74 20 69 74 65 72 61 74 6f 72 20   First iterator 
9ee0: 74 6f 20 63 6f 6d 70 61 72 65 20 2a 2f 0a 20 20  to compare */.  
9ef0: 20 20 20 20 56 64 62 65 53 6f 72 74 65 72 49 74      VdbeSorterIt
9f00: 65 72 20 2a 70 49 74 65 72 32 3b 20 20 20 20 20  er *pIter2;     
9f10: 2f 2a 20 53 65 63 6f 6e 64 20 69 74 65 72 61 74  /* Second iterat
9f20: 6f 72 20 74 6f 20 63 6f 6d 70 61 72 65 20 2a 2f  or to compare */
9f30: 0a 20 20 20 20 20 20 75 38 20 2a 70 4b 65 79 32  .      u8 *pKey2
9f40: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
9f50: 20 20 20 2f 2a 20 54 6f 20 70 49 74 65 72 32 2d     /* To pIter2-
9f60: 3e 61 4b 65 79 2c 20 6f 72 20 30 20 69 66 20 72  >aKey, or 0 if r
9f70: 65 63 6f 72 64 20 63 61 63 68 65 64 20 2a 2f 0a  ecord cached */.
9f80: 0a 20 20 20 20 20 20 2f 2a 20 46 69 6e 64 20 74  .      /* Find t
9f90: 68 65 20 66 69 72 73 74 20 74 77 6f 20 69 74 65  he first two ite
9fa0: 72 61 74 6f 72 73 20 74 6f 20 63 6f 6d 70 61 72  rators to compar
9fb0: 65 2e 20 54 68 65 20 6f 6e 65 20 74 68 61 74 20  e. The one that 
9fc0: 77 61 73 20 6a 75 73 74 0a 20 20 20 20 20 20 2a  was just.      *
9fd0: 2a 20 61 64 76 61 6e 63 65 64 20 28 69 50 72 65  * advanced (iPre
9fe0: 76 29 20 61 6e 64 20 74 68 65 20 6f 6e 65 20 6e  v) and the one n
9ff0: 65 78 74 20 74 6f 20 69 74 20 69 6e 20 74 68 65  ext to it in the
a000: 20 61 72 72 61 79 2e 20 20 2a 2f 0a 20 20 20 20   array.  */.    
a010: 20 20 70 49 74 65 72 31 20 3d 20 26 70 53 6f 72    pIter1 = &pSor
a020: 74 65 72 2d 3e 61 49 74 65 72 5b 28 69 50 72 65  ter->aIter[(iPre
a030: 76 20 26 20 30 78 46 46 46 45 29 5d 3b 0a 20 20  v & 0xFFFE)];.  
a040: 20 20 20 20 70 49 74 65 72 32 20 3d 20 26 70 53      pIter2 = &pS
a050: 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b 28 69 50  orter->aIter[(iP
a060: 72 65 76 20 7c 20 30 78 30 30 30 31 29 5d 3b 0a  rev | 0x0001)];.
a070: 20 20 20 20 20 20 70 4b 65 79 32 20 3d 20 70 49        pKey2 = pI
a080: 74 65 72 32 2d 3e 61 4b 65 79 3b 0a 0a 20 20 20  ter2->aKey;..   
a090: 20 20 20 66 6f 72 28 69 3d 28 70 53 6f 72 74 65     for(i=(pSorte
a0a0: 72 2d 3e 6e 54 72 65 65 2b 69 50 72 65 76 29 2f  r->nTree+iPrev)/
a0b0: 32 3b 20 69 3e 30 3b 20 69 3d 69 2f 32 29 7b 0a  2; i>0; i=i/2){.
a0c0: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6d 70 61          /* Compa
a0d0: 72 65 20 70 49 74 65 72 31 20 61 6e 64 20 70 49  re pIter1 and pI
a0e0: 74 65 72 32 2e 20 53 74 6f 72 65 20 74 68 65 20  ter2. Store the 
a0f0: 72 65 73 75 6c 74 20 69 6e 20 76 61 72 69 61 62  result in variab
a100: 6c 65 20 69 52 65 73 2e 20 2a 2f 0a 20 20 20 20  le iRes. */.    
a110: 20 20 20 20 69 6e 74 20 69 52 65 73 3b 0a 20 20      int iRes;.  
a120: 20 20 20 20 20 20 69 66 28 20 70 49 74 65 72 31        if( pIter1
a130: 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20  ->pFile==0 ){.  
a140: 20 20 20 20 20 20 20 20 69 52 65 73 20 3d 20 2b          iRes = +
a150: 31 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65  1;.        }else
a160: 20 69 66 28 20 70 49 74 65 72 32 2d 3e 70 46 69   if( pIter2->pFi
a170: 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  le==0 ){.       
a180: 20 20 20 69 52 65 73 20 3d 20 2d 31 3b 0a 20 20     iRes = -1;.  
a190: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
a1a0: 20 20 20 20 20 20 20 76 64 62 65 53 6f 72 74 65         vdbeSorte
a1b0: 72 43 6f 6d 70 61 72 65 28 70 43 73 72 2c 20 30  rCompare(pCsr, 0
a1c0: 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  , .             
a1d0: 20 70 49 74 65 72 31 2d 3e 61 4b 65 79 2c 20 70   pIter1->aKey, p
a1e0: 49 74 65 72 31 2d 3e 6e 4b 65 79 2c 20 70 4b 65  Iter1->nKey, pKe
a1f0: 79 32 2c 20 70 49 74 65 72 32 2d 3e 6e 4b 65 79  y2, pIter2->nKey
a200: 2c 20 26 69 52 65 73 0a 20 20 20 20 20 20 20 20  , &iRes.        
a210: 20 20 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a    );.        }..
a220: 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 70 49          /* If pI
a230: 74 65 72 31 20 63 6f 6e 74 61 69 6e 65 64 20 74  ter1 contained t
a240: 68 65 20 73 6d 61 6c 6c 65 72 20 76 61 6c 75 65  he smaller value
a250: 2c 20 73 65 74 20 61 54 72 65 65 5b 69 5d 20 74  , set aTree[i] t
a260: 6f 20 69 74 73 20 69 6e 64 65 78 2e 0a 20 20 20  o its index..   
a270: 20 20 20 20 20 2a 2a 20 54 68 65 6e 20 73 65 74       ** Then set
a280: 20 70 49 74 65 72 32 20 74 6f 20 74 68 65 20 6e   pIter2 to the n
a290: 65 78 74 20 69 74 65 72 61 74 6f 72 20 74 6f 20  ext iterator to 
a2a0: 63 6f 6d 70 61 72 65 20 74 6f 20 70 49 74 65 72  compare to pIter
a2b0: 31 2e 20 49 6e 20 74 68 69 73 0a 20 20 20 20 20  1. In this.     
a2c0: 20 20 20 2a 2a 20 63 61 73 65 20 74 68 65 72 65     ** case there
a2d0: 20 69 73 20 6e 6f 20 63 61 63 68 65 20 6f 66 20   is no cache of 
a2e0: 70 49 74 65 72 32 20 69 6e 20 70 53 6f 72 74 65  pIter2 in pSorte
a2f0: 72 2d 3e 70 55 6e 70 61 63 6b 65 64 2c 20 73 6f  r->pUnpacked, so
a300: 20 73 65 74 0a 20 20 20 20 20 20 20 20 2a 2a 20   set.        ** 
a310: 70 4b 65 79 32 20 74 6f 20 70 6f 69 6e 74 20 74  pKey2 to point t
a320: 6f 20 74 68 65 20 72 65 63 6f 72 64 20 62 65 6c  o the record bel
a330: 6f 6e 67 69 6e 67 20 74 6f 20 70 49 74 65 72 32  onging to pIter2
a340: 2e 0a 20 20 20 20 20 20 20 20 2a 2a 0a 20 20 20  ..        **.   
a350: 20 20 20 20 20 2a 2a 20 41 6c 74 65 72 6e 61 74       ** Alternat
a360: 69 76 65 6c 79 2c 20 69 66 20 70 49 74 65 72 32  ively, if pIter2
a370: 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 73 6d   contains the sm
a380: 61 6c 6c 65 72 20 6f 66 20 74 68 65 20 74 77 6f  aller of the two
a390: 20 76 61 6c 75 65 73 2c 0a 20 20 20 20 20 20 20   values,.       
a3a0: 20 2a 2a 20 73 65 74 20 61 54 72 65 65 5b 69 5d   ** set aTree[i]
a3b0: 20 74 6f 20 69 74 73 20 69 6e 64 65 78 20 61 6e   to its index an
a3c0: 64 20 75 70 64 61 74 65 20 70 49 74 65 72 31 2e  d update pIter1.
a3d0: 20 49 66 20 76 64 62 65 53 6f 72 74 65 72 43 6f   If vdbeSorterCo
a3e0: 6d 70 61 72 65 28 29 0a 20 20 20 20 20 20 20 20  mpare().        
a3f0: 2a 2a 20 77 61 73 20 61 63 74 75 61 6c 6c 79 20  ** was actually 
a400: 63 61 6c 6c 65 64 20 61 62 6f 76 65 2c 20 74 68  called above, th
a410: 65 6e 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70  en pSorter->pUnp
a420: 61 63 6b 65 64 20 6e 6f 77 20 63 6f 6e 74 61 69  acked now contai
a430: 6e 73 0a 20 20 20 20 20 20 20 20 2a 2a 20 61 20  ns.        ** a 
a440: 76 61 6c 75 65 20 65 71 75 69 76 61 6c 65 6e 74  value equivalent
a450: 20 74 6f 20 70 49 74 65 72 32 2e 20 53 6f 20 73   to pIter2. So s
a460: 65 74 20 70 4b 65 79 32 20 74 6f 20 4e 55 4c 4c  et pKey2 to NULL
a470: 20 74 6f 20 70 72 65 76 65 6e 74 0a 20 20 20 20   to prevent.    
a480: 20 20 20 20 2a 2a 20 76 64 62 65 53 6f 72 74 65      ** vdbeSorte
a490: 72 43 6f 6d 70 61 72 65 28 29 20 66 72 6f 6d 20  rCompare() from 
a4a0: 64 65 63 6f 64 69 6e 67 20 70 49 74 65 72 32 20  decoding pIter2 
a4b0: 61 67 61 69 6e 2e 20 20 0a 20 20 20 20 20 20 20  again.  .       
a4c0: 20 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 49   **.        ** I
a4d0: 66 20 74 68 65 20 74 77 6f 20 76 61 6c 75 65 73  f the two values
a4e0: 20 77 65 72 65 20 65 71 75 61 6c 2c 20 74 68 65   were equal, the
a4f0: 6e 20 74 68 65 20 76 61 6c 75 65 20 66 72 6f 6d  n the value from
a500: 20 74 68 65 20 6f 6c 64 65 73 74 0a 20 20 20 20   the oldest.    
a510: 20 20 20 20 2a 2a 20 50 4d 41 20 73 68 6f 75 6c      ** PMA shoul
a520: 64 20 62 65 20 63 6f 6e 73 69 64 65 72 65 64 20  d be considered 
a530: 73 6d 61 6c 6c 65 72 2e 20 54 68 65 20 56 64 62  smaller. The Vdb
a540: 65 53 6f 72 74 65 72 2e 61 49 74 65 72 5b 5d 20  eSorter.aIter[] 
a550: 61 72 72 61 79 0a 20 20 20 20 20 20 20 20 2a 2a  array.        **
a560: 20 69 73 20 73 6f 72 74 65 64 20 66 72 6f 6d 20   is sorted from 
a570: 6f 6c 64 65 73 74 20 74 6f 20 6e 65 77 65 73 74  oldest to newest
a580: 2c 20 73 6f 20 70 49 74 65 72 31 20 63 6f 6e 74  , so pIter1 cont
a590: 61 69 6e 73 20 6f 6c 64 65 72 20 76 61 6c 75 65  ains older value
a5a0: 73 0a 20 20 20 20 20 20 20 20 2a 2a 20 74 68 61  s.        ** tha
a5b0: 6e 20 70 49 74 65 72 32 20 69 66 66 20 28 70 49  n pIter2 iff (pI
a5c0: 74 65 72 31 3c 70 49 74 65 72 32 29 2e 20 20 2a  ter1<pIter2).  *
a5d0: 2f 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 52  /.        if( iR
a5e0: 65 73 3c 30 20 7c 7c 20 28 69 52 65 73 3d 3d 30  es<0 || (iRes==0
a5f0: 20 26 26 20 70 49 74 65 72 31 3c 70 49 74 65 72   && pIter1<pIter
a600: 32 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  2) ){.          
a610: 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 69  pSorter->aTree[i
a620: 5d 20 3d 20 28 69 6e 74 29 28 70 49 74 65 72 31  ] = (int)(pIter1
a630: 20 2d 20 70 53 6f 72 74 65 72 2d 3e 61 49 74 65   - pSorter->aIte
a640: 72 29 3b 0a 20 20 20 20 20 20 20 20 20 20 70 49  r);.          pI
a650: 74 65 72 32 20 3d 20 26 70 53 6f 72 74 65 72 2d  ter2 = &pSorter-
a660: 3e 61 49 74 65 72 5b 20 70 53 6f 72 74 65 72 2d  >aIter[ pSorter-
a670: 3e 61 54 72 65 65 5b 69 20 5e 20 30 78 30 30 30  >aTree[i ^ 0x000
a680: 31 5d 20 5d 3b 0a 20 20 20 20 20 20 20 20 20 20  1] ];.          
a690: 70 4b 65 79 32 20 3d 20 70 49 74 65 72 32 2d 3e  pKey2 = pIter2->
a6a0: 61 4b 65 79 3b 0a 20 20 20 20 20 20 20 20 7d 65  aKey;.        }e
a6b0: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 69  lse{.          i
a6c0: 66 28 20 70 49 74 65 72 31 2d 3e 70 46 69 6c 65  f( pIter1->pFile
a6d0: 20 29 20 70 4b 65 79 32 20 3d 20 30 3b 0a 20 20   ) pKey2 = 0;.  
a6e0: 20 20 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d          pSorter-
a6f0: 3e 61 54 72 65 65 5b 69 5d 20 3d 20 28 69 6e 74  >aTree[i] = (int
a700: 29 28 70 49 74 65 72 32 20 2d 20 70 53 6f 72 74  )(pIter2 - pSort
a710: 65 72 2d 3e 61 49 74 65 72 29 3b 0a 20 20 20 20  er->aIter);.    
a720: 20 20 20 20 20 20 70 49 74 65 72 31 20 3d 20 26        pIter1 = &
a730: 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b 20  pSorter->aIter[ 
a740: 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 69  pSorter->aTree[i
a750: 20 5e 20 30 78 30 30 30 31 5d 20 5d 3b 0a 20 20   ^ 0x0001] ];.  
a760: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
a770: 20 20 20 20 20 20 2a 70 62 45 6f 66 20 3d 20 28        *pbEof = (
a780: 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b 70  pSorter->aIter[p
a790: 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 31 5d  Sorter->aTree[1]
a7a0: 5d 2e 70 46 69 6c 65 3d 3d 30 29 3b 0a 20 20 20  ].pFile==0);.   
a7b0: 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20   }.  }else{.    
a7c0: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 46  SorterRecord *pF
a7d0: 72 65 65 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70  ree = pSorter->p
a7e0: 52 65 63 6f 72 64 3b 0a 20 20 20 20 70 53 6f 72  Record;.    pSor
a7f0: 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 3d 20 70  ter->pRecord = p
a800: 46 72 65 65 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20  Free->u.pNext;. 
a810: 20 20 20 70 46 72 65 65 2d 3e 75 2e 70 4e 65 78     pFree->u.pNex
a820: 74 20 3d 20 30 3b 0a 20 20 20 20 69 66 28 20 70  t = 0;.    if( p
a830: 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 3d  Sorter->aMemory=
a840: 3d 30 20 29 7b 0a 20 20 20 20 20 20 76 64 62 65  =0 ){.      vdbe
a850: 53 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65 65  SorterRecordFree
a860: 28 64 62 2c 20 70 46 72 65 65 29 3b 0a 20 20 20  (db, pFree);.   
a870: 20 7d 0a 20 20 20 20 2a 70 62 45 6f 66 20 3d 20   }.    *pbEof = 
a880: 21 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72  !pSorter->pRecor
a890: 64 3b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49  d;.    rc = SQLI
a8a0: 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 20 20 72 65 74  TE_OK;.  }.  ret
a8b0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
a8c0: 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65   Return a pointe
a8d0: 72 20 74 6f 20 61 20 62 75 66 66 65 72 20 6f 77  r to a buffer ow
a8e0: 6e 65 64 20 62 79 20 74 68 65 20 73 6f 72 74 65  ned by the sorte
a8f0: 72 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20  r that contains 
a900: 74 68 65 20 0a 2a 2a 20 63 75 72 72 65 6e 74 20  the .** current 
a910: 6b 65 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  key..*/.static v
a920: 6f 69 64 20 2a 76 64 62 65 53 6f 72 74 65 72 52  oid *vdbeSorterR
a930: 6f 77 6b 65 79 28 0a 20 20 63 6f 6e 73 74 20 56  owkey(.  const V
a940: 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
a950: 65 72 2c 20 20 20 20 20 20 2f 2a 20 53 6f 72 74  er,      /* Sort
a960: 65 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69  er object */.  i
a970: 6e 74 20 2a 70 6e 4b 65 79 20 20 20 20 20 20 20  nt *pnKey       
a980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
a990: 2a 20 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20 63  * OUT: Size of c
a9a0: 75 72 72 65 6e 74 20 6b 65 79 20 69 6e 20 62 79  urrent key in by
a9b0: 74 65 73 20 2a 2f 0a 29 7b 0a 20 20 76 6f 69 64  tes */.){.  void
a9c0: 20 2a 70 4b 65 79 3b 0a 20 20 69 66 28 20 70 53   *pKey;.  if( pS
a9d0: 6f 72 74 65 72 2d 3e 61 54 72 65 65 20 29 7b 0a  orter->aTree ){.
a9e0: 20 20 20 20 56 64 62 65 53 6f 72 74 65 72 49 74      VdbeSorterIt
a9f0: 65 72 20 2a 70 49 74 65 72 3b 0a 20 20 20 20 70  er *pIter;.    p
aa00: 49 74 65 72 20 3d 20 26 70 53 6f 72 74 65 72 2d  Iter = &pSorter-
aa10: 3e 61 49 74 65 72 5b 20 70 53 6f 72 74 65 72 2d  >aIter[ pSorter-
aa20: 3e 61 54 72 65 65 5b 31 5d 20 5d 3b 0a 20 20 20  >aTree[1] ];.   
aa30: 20 2a 70 6e 4b 65 79 20 3d 20 70 49 74 65 72 2d   *pnKey = pIter-
aa40: 3e 6e 4b 65 79 3b 0a 20 20 20 20 70 4b 65 79 20  >nKey;.    pKey 
aa50: 3d 20 70 49 74 65 72 2d 3e 61 4b 65 79 3b 0a 20  = pIter->aKey;. 
aa60: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2a 70 6e 4b   }else{.    *pnK
aa70: 65 79 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 52  ey = pSorter->pR
aa80: 65 63 6f 72 64 2d 3e 6e 56 61 6c 3b 0a 20 20 20  ecord->nVal;.   
aa90: 20 70 4b 65 79 20 3d 20 53 52 56 41 4c 28 70 53   pKey = SRVAL(pS
aaa0: 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 29 3b  orter->pRecord);
aab0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 4b  .  }.  return pK
aac0: 65 79 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70  ey;.}../*.** Cop
aad0: 79 20 74 68 65 20 63 75 72 72 65 6e 74 20 73 6f  y the current so
aae0: 72 74 65 72 20 6b 65 79 20 69 6e 74 6f 20 74 68  rter key into th
aaf0: 65 20 6d 65 6d 6f 72 79 20 63 65 6c 6c 20 70 4f  e memory cell pO
ab00: 75 74 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ut..*/.int sqlit
ab10: 65 33 56 64 62 65 53 6f 72 74 65 72 52 6f 77 6b  e3VdbeSorterRowk
ab20: 65 79 28 63 6f 6e 73 74 20 56 64 62 65 43 75 72  ey(const VdbeCur
ab30: 73 6f 72 20 2a 70 43 73 72 2c 20 4d 65 6d 20 2a  sor *pCsr, Mem *
ab40: 70 4f 75 74 29 7b 0a 20 20 56 64 62 65 53 6f 72  pOut){.  VdbeSor
ab50: 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70  ter *pSorter = p
ab60: 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20  Csr->pSorter;.  
ab70: 76 6f 69 64 20 2a 70 4b 65 79 3b 20 69 6e 74 20  void *pKey; int 
ab80: 6e 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20  nKey;           
ab90: 2f 2a 20 53 6f 72 74 65 72 20 6b 65 79 20 74 6f  /* Sorter key to
aba0: 20 63 6f 70 79 20 69 6e 74 6f 20 70 4f 75 74 20   copy into pOut 
abb0: 2a 2f 0a 0a 20 20 70 4b 65 79 20 3d 20 76 64 62  */..  pKey = vdb
abc0: 65 53 6f 72 74 65 72 52 6f 77 6b 65 79 28 70 53  eSorterRowkey(pS
abd0: 6f 72 74 65 72 2c 20 26 6e 4b 65 79 29 3b 0a 20  orter, &nKey);. 
abe0: 20 69 66 28 20 73 71 6c 69 74 65 33 56 64 62 65   if( sqlite3Vdbe
abf0: 4d 65 6d 47 72 6f 77 28 70 4f 75 74 2c 20 6e 4b  MemGrow(pOut, nK
ac00: 65 79 2c 20 30 29 20 29 7b 0a 20 20 20 20 72 65  ey, 0) ){.    re
ac10: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
ac20: 4d 3b 0a 20 20 7d 0a 20 20 70 4f 75 74 2d 3e 6e  M;.  }.  pOut->n
ac30: 20 3d 20 6e 4b 65 79 3b 0a 20 20 4d 65 6d 53 65   = nKey;.  MemSe
ac40: 74 54 79 70 65 46 6c 61 67 28 70 4f 75 74 2c 20  tTypeFlag(pOut, 
ac50: 4d 45 4d 5f 42 6c 6f 62 29 3b 0a 20 20 6d 65 6d  MEM_Blob);.  mem
ac60: 63 70 79 28 70 4f 75 74 2d 3e 7a 2c 20 70 4b 65  cpy(pOut->z, pKe
ac70: 79 2c 20 6e 4b 65 79 29 3b 0a 0a 20 20 72 65 74  y, nKey);..  ret
ac80: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
ac90: 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 61 72 65 20  ../*.** Compare 
aca0: 74 68 65 20 6b 65 79 20 69 6e 20 6d 65 6d 6f 72  the key in memor
acb0: 79 20 63 65 6c 6c 20 70 56 61 6c 20 77 69 74 68  y cell pVal with
acc0: 20 74 68 65 20 6b 65 79 20 74 68 61 74 20 74 68   the key that th
acd0: 65 20 73 6f 72 74 65 72 20 63 75 72 73 6f 72 0a  e sorter cursor.
ace0: 2a 2a 20 70 61 73 73 65 64 20 61 73 20 74 68 65  ** passed as the
acf0: 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20   first argument 
ad00: 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73  currently points
ad10: 20 74 6f 2e 20 46 6f 72 20 74 68 65 20 70 75 72   to. For the pur
ad20: 70 6f 73 65 73 20 6f 66 0a 2a 2a 20 74 68 65 20  poses of.** the 
ad30: 63 6f 6d 70 61 72 69 73 6f 6e 2c 20 69 67 6e 6f  comparison, igno
ad40: 72 65 20 74 68 65 20 72 6f 77 69 64 20 66 69 65  re the rowid fie
ad50: 6c 64 20 61 74 20 74 68 65 20 65 6e 64 20 6f 66  ld at the end of
ad60: 20 65 61 63 68 20 72 65 63 6f 72 64 2e 0a 2a 2a   each record..**
ad70: 0a 2a 2a 20 49 66 20 61 6e 20 65 72 72 6f 72 20  .** If an error 
ad80: 6f 63 63 75 72 73 2c 20 72 65 74 75 72 6e 20 61  occurs, return a
ad90: 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  n SQLite error c
ada0: 6f 64 65 20 28 69 2e 65 2e 20 53 51 4c 49 54 45  ode (i.e. SQLITE
adb0: 5f 4e 4f 4d 45 4d 29 2e 0a 2a 2a 20 4f 74 68 65  _NOMEM)..** Othe
adc0: 72 77 69 73 65 2c 20 73 65 74 20 2a 70 52 65 73  rwise, set *pRes
add0: 20 74 6f 20 61 20 6e 65 67 61 74 69 76 65 2c 20   to a negative, 
ade0: 7a 65 72 6f 20 6f 72 20 70 6f 73 69 74 69 76 65  zero or positive
adf0: 20 76 61 6c 75 65 20 69 66 20 74 68 65 0a 2a 2a   value if the.**
ae00: 20 6b 65 79 20 69 6e 20 70 56 61 6c 20 69 73 20   key in pVal is 
ae10: 73 6d 61 6c 6c 65 72 20 74 68 61 6e 2c 20 65 71  smaller than, eq
ae20: 75 61 6c 20 74 6f 20 6f 72 20 6c 61 72 67 65 72  ual to or larger
ae30: 20 74 68 61 6e 20 74 68 65 20 63 75 72 72 65 6e   than the curren
ae40: 74 20 73 6f 72 74 65 72 0a 2a 2a 20 6b 65 79 2e  t sorter.** key.
ae50: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56  .*/.int sqlite3V
ae60: 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65  dbeSorterCompare
ae70: 28 0a 20 20 63 6f 6e 73 74 20 56 64 62 65 43 75  (.  const VdbeCu
ae80: 72 73 6f 72 20 2a 70 43 73 72 2c 20 20 20 20 20  rsor *pCsr,     
ae90: 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 63 75      /* Sorter cu
aea0: 72 73 6f 72 20 2a 2f 0a 20 20 4d 65 6d 20 2a 70  rsor */.  Mem *p
aeb0: 56 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20  Val,            
aec0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c            /* Val
aed0: 75 65 20 74 6f 20 63 6f 6d 70 61 72 65 20 74 6f  ue to compare to
aee0: 20 63 75 72 72 65 6e 74 20 73 6f 72 74 65 72 20   current sorter 
aef0: 6b 65 79 20 2a 2f 0a 20 20 69 6e 74 20 6e 49 67  key */.  int nIg
af00: 6e 6f 72 65 2c 20 20 20 20 20 20 20 20 20 20 20  nore,           
af10: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 67 6e 6f           /* Igno
af20: 72 65 20 74 68 69 73 20 6d 61 6e 79 20 66 69 65  re this many fie
af30: 6c 64 73 20 61 74 20 74 68 65 20 65 6e 64 20 2a  lds at the end *
af40: 2f 0a 20 20 69 6e 74 20 2a 70 52 65 73 20 20 20  /.  int *pRes   
af50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
af60: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 52 65 73 75      /* OUT: Resu
af70: 6c 74 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e  lt of comparison
af80: 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65 53 6f 72   */.){.  VdbeSor
af90: 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70  ter *pSorter = p
afa0: 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20  Csr->pSorter;.  
afb0: 76 6f 69 64 20 2a 70 4b 65 79 3b 20 69 6e 74 20  void *pKey; int 
afc0: 6e 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20  nKey;           
afd0: 2f 2a 20 53 6f 72 74 65 72 20 6b 65 79 20 74 6f  /* Sorter key to
afe0: 20 63 6f 6d 70 61 72 65 20 70 56 61 6c 20 77 69   compare pVal wi
aff0: 74 68 20 2a 2f 0a 0a 20 20 70 4b 65 79 20 3d 20  th */..  pKey = 
b000: 76 64 62 65 53 6f 72 74 65 72 52 6f 77 6b 65 79  vdbeSorterRowkey
b010: 28 70 53 6f 72 74 65 72 2c 20 26 6e 4b 65 79 29  (pSorter, &nKey)
b020: 3b 0a 20 20 76 64 62 65 53 6f 72 74 65 72 43 6f  ;.  vdbeSorterCo
b030: 6d 70 61 72 65 28 70 43 73 72 2c 20 6e 49 67 6e  mpare(pCsr, nIgn
b040: 6f 72 65 2c 20 70 56 61 6c 2d 3e 7a 2c 20 70 56  ore, pVal->z, pV
b050: 61 6c 2d 3e 6e 2c 20 70 4b 65 79 2c 20 6e 4b 65  al->n, pKey, nKe
b060: 79 2c 20 70 52 65 73 29 3b 0a 20 20 72 65 74 75  y, pRes);.  retu
b070: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.