/ Hex Artifact Content
Login

Artifact ea221800773dd890cf4d0b1ccee6612b9b24101b:


0000: 2f 2a 0a 2a 2a 20 32 30 31 31 20 4a 75 6c 79 20  /*.** 2011 July 
0010: 39 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  9.**.** The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65  place of.** a le
0060: 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65  gal notice, here
0070: 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a   is a blessing:.
0080: 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75  **.**    May you
0090: 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74   do good and not
00a0: 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79   evil..**    May
00b0: 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76   you find forgiv
00c0: 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65  eness for yourse
00d0: 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f  lf and forgive o
00e0: 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79  thers..**    May
00f0: 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c   you share freel
0100: 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20  y, never taking 
0110: 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69  more than you gi
0120: 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ve..**.*********
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 2a  ****************
0170: 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65 20 63 6f  .** This file co
0180: 6e 74 61 69 6e 73 20 63 6f 64 65 20 66 6f 72 20  ntains code for 
0190: 74 68 65 20 56 64 62 65 53 6f 72 74 65 72 20 6f  the VdbeSorter o
01a0: 62 6a 65 63 74 2c 20 75 73 65 64 20 69 6e 20 63  bject, used in c
01b0: 6f 6e 63 65 72 74 20 77 69 74 68 0a 2a 2a 20 61  oncert with.** a
01c0: 20 56 64 62 65 43 75 72 73 6f 72 20 74 6f 20 73   VdbeCursor to s
01d0: 6f 72 74 20 6c 61 72 67 65 20 6e 75 6d 62 65 72  ort large number
01e0: 73 20 6f 66 20 6b 65 79 73 20 28 61 73 20 6d 61  s of keys (as ma
01f0: 79 20 62 65 20 72 65 71 75 69 72 65 64 2c 20 66  y be required, f
0200: 6f 72 0a 2a 2a 20 65 78 61 6d 70 6c 65 2c 20 62  or.** example, b
0210: 79 20 43 52 45 41 54 45 20 49 4e 44 45 58 20 73  y CREATE INDEX s
0220: 74 61 74 65 6d 65 6e 74 73 20 6f 6e 20 74 61 62  tatements on tab
0230: 6c 65 73 20 74 6f 6f 20 6c 61 72 67 65 20 74 6f  les too large to
0240: 20 66 69 74 20 69 6e 20 6d 61 69 6e 0a 2a 2a 20   fit in main.** 
0250: 6d 65 6d 6f 72 79 29 2e 0a 2a 2f 0a 0a 23 69 6e  memory)..*/..#in
0260: 63 6c 75 64 65 20 22 73 71 6c 69 74 65 49 6e 74  clude "sqliteInt
0270: 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 76 64  .h".#include "vd
0280: 62 65 49 6e 74 2e 68 22 0a 0a 0a 74 79 70 65 64  beInt.h"...typed
0290: 65 66 20 73 74 72 75 63 74 20 56 64 62 65 53 6f  ef struct VdbeSo
02a0: 72 74 65 72 49 74 65 72 20 56 64 62 65 53 6f 72  rterIter VdbeSor
02b0: 74 65 72 49 74 65 72 3b 0a 74 79 70 65 64 65 66  terIter;.typedef
02c0: 20 73 74 72 75 63 74 20 53 6f 72 74 65 72 54 68   struct SorterTh
02d0: 72 65 61 64 20 53 6f 72 74 65 72 54 68 72 65 61  read SorterThrea
02e0: 64 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  d;.typedef struc
02f0: 74 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 53  t SorterRecord S
0300: 6f 72 74 65 72 52 65 63 6f 72 64 3b 0a 74 79 70  orterRecord;.typ
0310: 65 64 65 66 20 73 74 72 75 63 74 20 53 6f 72 74  edef struct Sort
0320: 65 72 4d 65 72 67 65 72 20 53 6f 72 74 65 72 4d  erMerger SorterM
0330: 65 72 67 65 72 3b 0a 74 79 70 65 64 65 66 20 73  erger;.typedef s
0340: 74 72 75 63 74 20 46 69 6c 65 57 72 69 74 65 72  truct FileWriter
0350: 20 46 69 6c 65 57 72 69 74 65 72 3b 0a 0a 0a 2f   FileWriter;.../
0360: 2a 0a 2a 2a 20 43 61 6e 64 69 64 61 74 65 20 76  *.** Candidate v
0370: 61 6c 75 65 73 20 66 6f 72 20 53 6f 72 74 65 72  alues for Sorter
0380: 54 68 72 65 61 64 2e 65 57 6f 72 6b 0a 2a 2f 0a  Thread.eWork.*/.
0390: 23 64 65 66 69 6e 65 20 53 4f 52 54 45 52 5f 54  #define SORTER_T
03a0: 48 52 45 41 44 5f 53 4f 52 54 20 20 20 31 0a 23  HREAD_SORT   1.#
03b0: 64 65 66 69 6e 65 20 53 4f 52 54 45 52 5f 54 48  define SORTER_TH
03c0: 52 45 41 44 5f 54 4f 5f 50 4d 41 20 32 0a 23 64  READ_TO_PMA 2.#d
03d0: 65 66 69 6e 65 20 53 4f 52 54 45 52 5f 54 48 52  efine SORTER_THR
03e0: 45 41 44 5f 43 4f 4e 53 20 20 20 33 0a 0a 2f 2a  EAD_CONS   3../*
03f0: 0a 2a 2a 20 4d 75 63 68 20 6f 66 20 74 68 65 20  .** Much of the 
0400: 77 6f 72 6b 20 70 65 72 66 6f 72 6d 65 64 20 69  work performed i
0410: 6e 20 74 68 69 73 20 6d 6f 64 75 6c 65 20 74 6f  n this module to
0420: 20 73 6f 72 74 20 74 68 65 20 6c 69 73 74 20 6f   sort the list o
0430: 66 20 72 65 63 6f 72 64 73 20 69 73 20 0a 2a 2a  f records is .**
0440: 20 62 72 6f 6b 65 6e 20 64 6f 77 6e 20 69 6e 74   broken down int
0450: 6f 20 73 6d 61 6c 6c 65 72 20 75 6e 69 74 73 20  o smaller units 
0460: 74 68 61 74 20 6d 61 79 20 62 65 20 70 65 66 6f  that may be pefo
0470: 72 6d 65 64 20 69 6e 20 70 61 72 61 6c 6c 65 6c  rmed in parallel
0480: 2e 20 49 6e 20 6f 72 64 65 72 0a 2a 2a 20 74 6f  . In order.** to
0490: 20 70 65 72 66 6f 72 6d 20 73 75 63 68 20 61 20   perform such a 
04a0: 75 6e 69 74 20 6f 66 20 77 6f 72 6b 2c 20 61 6e  unit of work, an
04b0: 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65   instance of the
04c0: 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 74 72 75 63   following struc
04d0: 74 75 72 65 0a 2a 2a 20 69 73 20 63 6f 6e 66 69  ture.** is confi
04e0: 67 75 72 65 64 20 61 6e 64 20 70 61 73 73 65 64  gured and passed
04f0: 20 74 6f 20 76 64 62 65 53 6f 72 74 65 72 54 68   to vdbeSorterTh
0500: 72 65 61 64 4d 61 69 6e 28 29 20 2d 20 65 69 74  readMain() - eit
0510: 68 65 72 20 64 69 72 65 63 74 6c 79 20 62 79 20  her directly by 
0520: 0a 2a 2a 20 74 68 65 20 6d 61 69 6e 20 74 68 72  .** the main thr
0530: 65 61 64 20 6f 72 20 76 69 61 20 61 20 62 61 63  ead or via a bac
0540: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 2e 0a  kground thread..
0550: 2a 2a 0a 2a 2a 20 45 78 61 63 74 6c 79 20 53 6f  **.** Exactly So
0560: 72 74 65 72 54 68 72 65 61 64 2e 6e 54 68 72 65  rterThread.nThre
0570: 61 64 20 69 6e 73 74 61 6e 63 65 73 20 6f 66 20  ad instances of 
0580: 74 68 69 73 20 73 74 72 75 63 74 75 72 65 20 61  this structure a
0590: 72 65 20 61 6c 6c 6f 63 61 74 65 64 0a 2a 2a 20  re allocated.** 
05a0: 61 73 20 70 61 72 74 20 6f 66 20 65 61 63 68 20  as part of each 
05b0: 56 64 62 65 53 6f 72 74 65 72 20 6f 62 6a 65 63  VdbeSorter objec
05c0: 74 2e 20 49 6e 73 74 61 6e 63 65 73 20 61 72 65  t. Instances are
05d0: 20 6e 65 76 65 72 20 61 6c 6c 6f 63 61 74 65 64   never allocated
05e0: 20 61 6e 79 20 6f 74 68 65 72 0a 2a 2a 20 77 61   any other.** wa
05f0: 79 2e 20 53 6f 72 74 65 72 54 68 72 65 61 64 2e  y. SorterThread.
0600: 6e 54 68 72 65 61 64 20 69 73 20 73 65 74 20 74  nThread is set t
0610: 6f 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  o the number of 
0620: 77 6f 72 6b 65 72 20 74 68 72 65 61 64 73 20 61  worker threads a
0630: 6c 6c 6f 77 65 64 0a 2a 2a 20 28 73 65 65 20 53  llowed.** (see S
0640: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 57 4f 52  QLITE_CONFIG_WOR
0650: 4b 45 52 5f 54 48 52 45 41 44 53 29 20 70 6c 75  KER_THREADS) plu
0660: 73 20 6f 6e 65 20 28 74 68 65 20 6d 61 69 6e 20  s one (the main 
0670: 74 68 72 65 61 64 29 2e 0a 2a 2a 0a 2a 2a 20 57  thread)..**.** W
0680: 68 65 6e 20 61 20 62 61 63 6b 67 72 6f 75 6e 64  hen a background
0690: 20 74 68 72 65 61 64 20 69 73 20 6c 61 75 6e 63   thread is launc
06a0: 68 65 64 20 74 6f 20 70 65 72 66 6f 72 6d 20 77  hed to perform w
06b0: 6f 72 6b 2c 20 53 6f 72 74 65 72 54 68 72 65 61  ork, SorterThrea
06c0: 64 2e 62 44 6f 6e 65 0a 2a 2a 20 69 73 20 73 65  d.bDone.** is se
06d0: 74 20 74 6f 20 30 20 61 6e 64 20 74 68 65 20 53  t to 0 and the S
06e0: 6f 72 74 65 72 54 68 72 65 61 64 2e 70 54 68 72  orterThread.pThr
06f0: 65 61 64 20 76 61 72 69 61 62 6c 65 20 73 65 74  ead variable set
0700: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65   to point to the
0710: 0a 2a 2a 20 74 68 72 65 61 64 20 68 61 6e 64 6c  .** thread handl
0720: 65 2e 20 53 6f 72 74 65 72 54 68 72 65 61 64 2e  e. SorterThread.
0730: 62 44 6f 6e 65 20 69 73 20 73 65 74 20 74 6f 20  bDone is set to 
0740: 31 20 28 74 6f 20 69 6e 64 69 63 61 74 65 20 74  1 (to indicate t
0750: 6f 20 74 68 65 20 6d 61 69 6e 0a 2a 2a 20 74 68  o the main.** th
0760: 72 65 61 64 20 74 68 61 74 20 6a 6f 69 6e 69 6e  read that joinin
0770: 67 20 53 6f 72 74 65 72 54 68 72 65 61 64 2e 70  g SorterThread.p
0780: 54 68 72 65 61 64 20 77 69 6c 6c 20 6e 6f 74 20  Thread will not 
0790: 62 6c 6f 63 6b 29 20 62 65 66 6f 72 65 20 74 68  block) before th
07a0: 65 20 74 68 72 65 61 64 0a 2a 2a 20 65 78 69 74  e thread.** exit
07b0: 73 2e 20 53 6f 72 74 65 72 54 68 72 65 61 64 2e  s. SorterThread.
07c0: 70 54 68 72 65 61 64 20 61 6e 64 20 62 44 6f 6e  pThread and bDon
07d0: 65 20 61 72 65 20 61 6c 77 61 79 73 20 63 6c 65  e are always cle
07e0: 61 72 65 64 20 61 66 74 65 72 20 74 68 65 20 0a  ared after the .
07f0: 2a 2a 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68  ** background th
0800: 72 65 61 64 20 68 61 73 20 62 65 65 6e 20 6a 6f  read has been jo
0810: 69 6e 65 64 2e 20 20 54 68 65 20 62 44 6f 6e 65  ined.  The bDone
0820: 20 66 69 65 6c 64 20 69 73 20 69 6e 66 6f 72 6d   field is inform
0830: 61 74 69 6f 6e 61 6c 20 6f 6e 6c 79 2e 0a 2a 2a  ational only..**
0840: 20 49 74 20 69 73 20 6e 65 76 65 72 20 61 63 74   It is never act
0850: 75 61 6c 6c 79 20 75 73 65 64 2c 20 65 78 63 65  ually used, exce
0860: 70 74 20 69 6e 73 69 64 65 20 6f 66 20 61 73 73  pt inside of ass
0870: 65 72 74 28 29 20 73 74 61 74 65 6d 65 6e 74 73  ert() statements
0880: 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 65 20 6f 62 6a 65  ..**.** One obje
0890: 63 74 20 28 73 70 65 63 69 66 69 63 61 6c 6c 79  ct (specifically
08a0: 2c 20 56 64 62 65 53 6f 72 74 65 72 2e 61 54 68  , VdbeSorter.aTh
08b0: 72 65 61 64 5b 53 6f 72 74 65 72 54 68 72 65 61  read[SorterThrea
08c0: 64 2e 6e 54 68 72 65 61 64 2d 31 5d 29 0a 2a 2a  d.nThread-1]).**
08d0: 20 69 73 20 72 65 73 65 72 76 65 64 20 66 6f 72   is reserved for
08e0: 20 74 68 65 20 66 6f 72 65 67 72 6f 75 6e 64 20   the foreground 
08f0: 74 68 72 65 61 64 2e 0a 2a 2a 0a 2a 2a 20 54 68  thread..**.** Th
0900: 65 20 6e 61 74 75 72 65 20 6f 66 20 74 68 65 20  e nature of the 
0910: 77 6f 72 6b 20 70 65 72 66 6f 72 6d 65 64 20 69  work performed i
0920: 73 20 64 65 74 65 72 6d 69 6e 65 64 20 62 79 20  s determined by 
0930: 53 6f 72 74 65 72 54 68 72 65 61 64 2e 65 57 6f  SorterThread.eWo
0940: 72 6b 2c 0a 2a 2a 20 61 73 20 66 6f 6c 6c 6f 77  rk,.** as follow
0950: 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 4f 52 54 45  s:.**.**   SORTE
0960: 52 5f 54 48 52 45 41 44 5f 53 4f 52 54 3a 0a 2a  R_THREAD_SORT:.*
0970: 2a 20 20 20 20 20 53 6f 72 74 20 74 68 65 20 6c  *     Sort the l
0980: 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20 72 65  inked list of re
0990: 63 6f 72 64 73 20 61 74 20 53 6f 72 74 65 72 54  cords at SorterT
09a0: 68 72 65 61 64 2e 70 4c 69 73 74 2e 0a 2a 2a 0a  hread.pList..**.
09b0: 2a 2a 20 20 20 53 4f 52 54 45 52 5f 54 48 52 45  **   SORTER_THRE
09c0: 41 44 5f 54 4f 5f 50 4d 41 3a 0a 2a 2a 20 20 20  AD_TO_PMA:.**   
09d0: 20 20 53 6f 72 74 20 74 68 65 20 6c 69 6e 6b 65    Sort the linke
09e0: 64 20 6c 69 73 74 20 6f 66 20 72 65 63 6f 72 64  d list of record
09f0: 73 20 61 74 20 53 6f 72 74 65 72 54 68 72 65 61  s at SorterThrea
0a00: 64 2e 70 4c 69 73 74 2c 20 61 6e 64 20 77 72 69  d.pList, and wri
0a10: 74 65 0a 2a 2a 20 20 20 20 20 74 68 65 20 72 65  te.**     the re
0a20: 73 75 6c 74 73 20 74 6f 20 61 20 6e 65 77 20 50  sults to a new P
0a30: 4d 41 20 69 6e 20 74 65 6d 70 20 66 69 6c 65 20  MA in temp file 
0a40: 53 6f 72 74 65 72 54 68 72 65 61 64 2e 70 54 65  SorterThread.pTe
0a50: 6d 70 31 2e 20 4f 70 65 6e 0a 2a 2a 20 20 20 20  mp1. Open.**    
0a60: 20 74 68 65 20 74 65 6d 70 20 66 69 6c 65 20 69   the temp file i
0a70: 66 20 69 74 20 69 73 20 6e 6f 74 20 61 6c 72 65  f it is not alre
0a80: 61 64 79 20 6f 70 65 6e 2e 0a 2a 2a 0a 2a 2a 20  ady open..**.** 
0a90: 20 20 53 4f 52 54 45 52 5f 54 48 52 45 41 44 5f    SORTER_THREAD_
0aa0: 43 4f 4e 53 3a 0a 2a 2a 20 20 20 20 20 4d 65 72  CONS:.**     Mer
0ab0: 67 65 20 65 78 69 73 74 69 6e 67 20 50 4d 41 73  ge existing PMAs
0ac0: 20 75 6e 74 69 6c 20 53 6f 72 74 65 72 54 68 72   until SorterThr
0ad0: 65 61 64 2e 6e 43 6f 6e 73 6f 6c 69 64 61 74 65  ead.nConsolidate
0ae0: 20 6f 72 20 66 65 77 65 72 0a 2a 2a 20 20 20 20   or fewer.**    
0af0: 20 72 65 6d 61 69 6e 20 69 6e 20 74 65 6d 70 20   remain in temp 
0b00: 66 69 6c 65 20 53 6f 72 74 65 72 54 68 72 65 61  file SorterThrea
0b10: 64 2e 70 54 65 6d 70 31 2e 0a 2a 2f 0a 73 74 72  d.pTemp1..*/.str
0b20: 75 63 74 20 53 6f 72 74 65 72 54 68 72 65 61 64  uct SorterThread
0b30: 20 7b 0a 20 20 53 51 4c 69 74 65 54 68 72 65 61   {.  SQLiteThrea
0b40: 64 20 2a 70 54 68 72 65 61 64 3b 20 20 20 20 20  d *pThread;     
0b50: 20 20 20 20 20 2f 2a 20 54 68 72 65 61 64 20 68       /* Thread h
0b60: 61 6e 64 6c 65 2c 20 6f 72 20 4e 55 4c 4c 20 2a  andle, or NULL *
0b70: 2f 0a 20 20 69 6e 74 20 62 44 6f 6e 65 3b 20 20  /.  int bDone;  
0b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b90: 20 20 20 20 2f 2a 20 53 65 74 20 74 6f 20 74 72      /* Set to tr
0ba0: 75 65 20 62 79 20 70 54 68 72 65 61 64 20 77 68  ue by pThread wh
0bb0: 65 6e 20 66 69 6e 69 73 68 65 64 20 2a 2f 0a 0a  en finished */..
0bc0: 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70    sqlite3_vfs *p
0bd0: 56 66 73 3b 20 20 20 20 20 20 20 20 20 20 20 20  Vfs;            
0be0: 20 20 2f 2a 20 56 46 53 20 75 73 65 64 20 74 6f    /* VFS used to
0bf0: 20 6f 70 65 6e 20 74 65 6d 70 6f 72 61 72 79 20   open temporary 
0c00: 66 69 6c 65 73 20 2a 2f 0a 20 20 4b 65 79 49 6e  files */.  KeyIn
0c10: 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 3b 20 20 20  fo *pKeyInfo;   
0c20: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48 6f             /* Ho
0c30: 77 20 74 6f 20 63 6f 6d 70 61 72 65 20 72 65 63  w to compare rec
0c40: 6f 72 64 73 20 2a 2f 0a 20 20 55 6e 70 61 63 6b  ords */.  Unpack
0c50: 65 64 52 65 63 6f 72 64 20 2a 70 55 6e 70 61 63  edRecord *pUnpac
0c60: 6b 65 64 3b 20 20 20 20 20 20 2f 2a 20 53 70 61  ked;      /* Spa
0c70: 63 65 20 74 6f 20 75 6e 70 61 63 6b 20 61 20 72  ce to unpack a r
0c80: 65 63 6f 72 64 20 2a 2f 0a 20 20 69 6e 74 20 70  ecord */.  int p
0c90: 67 73 7a 3b 20 20 20 20 20 20 20 20 20 20 20 20  gsz;            
0ca0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61             /* Ma
0cb0: 69 6e 20 64 61 74 61 62 61 73 65 20 70 61 67 65  in database page
0cc0: 20 73 69 7a 65 20 2a 2f 0a 0a 20 20 75 38 20 65   size */..  u8 e
0cd0: 57 6f 72 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Work;           
0ce0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
0cf0: 6e 65 20 6f 66 20 74 68 65 20 53 4f 52 54 45 52  ne of the SORTER
0d00: 5f 54 48 52 45 41 44 5f 2a 20 63 6f 6e 73 74 61  _THREAD_* consta
0d10: 6e 74 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f  nts */.  int nCo
0d20: 6e 73 6f 6c 69 64 61 74 65 3b 20 20 20 20 20 20  nsolidate;      
0d30: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6f 72 20           /* For 
0d40: 54 48 52 45 41 44 5f 43 4f 4e 53 2c 20 6d 61 78  THREAD_CONS, max
0d50: 20 66 69 6e 61 6c 20 50 4d 41 73 20 2a 2f 0a 20   final PMAs */. 
0d60: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
0d70: 4c 69 73 74 3b 20 20 20 20 20 20 20 20 20 20 20  List;           
0d80: 20 2f 2a 20 4c 69 73 74 20 6f 66 20 72 65 63 6f   /* List of reco
0d90: 72 64 73 20 66 6f 72 20 70 54 68 72 65 61 64 20  rds for pThread 
0da0: 74 6f 20 73 6f 72 74 20 2a 2f 0a 20 20 69 6e 74  to sort */.  int
0db0: 20 6e 49 6e 4d 65 6d 6f 72 79 3b 20 20 20 20 20   nInMemory;     
0dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0dd0: 45 78 70 65 63 74 65 64 20 73 69 7a 65 20 6f 66  Expected size of
0de0: 20 50 4d 41 20 62 61 73 65 64 20 6f 6e 20 70 4c   PMA based on pL
0df0: 69 73 74 20 2a 2f 0a 20 20 75 38 20 2a 61 4c 69  ist */.  u8 *aLi
0e00: 73 74 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20 20  stMemory;       
0e10: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 63 6f           /* Reco
0e20: 72 64 73 20 6d 65 6d 6f 72 79 20 28 6f 72 20 4e  rds memory (or N
0e30: 55 4c 4c 29 20 2a 2f 0a 0a 20 20 69 6e 74 20 6e  ULL) */..  int n
0e40: 50 4d 41 3b 20 20 20 20 20 20 20 20 20 20 20 20  PMA;            
0e50: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
0e60: 6d 62 65 72 20 6f 66 20 50 4d 41 73 20 63 75 72  mber of PMAs cur
0e70: 72 65 6e 74 6c 79 20 69 6e 20 70 54 65 6d 70 31  rently in pTemp1
0e80: 20 2a 2f 0a 20 20 69 36 34 20 69 54 65 6d 70 31   */.  i64 iTemp1
0e90: 4f 66 66 3b 20 20 20 20 20 20 20 20 20 20 20 20  Off;            
0ea0: 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20        /* Offset 
0eb0: 74 6f 20 77 72 69 74 65 20 74 6f 20 69 6e 20 70  to write to in p
0ec0: 54 65 6d 70 31 20 2a 2f 0a 20 20 73 71 6c 69 74  Temp1 */.  sqlit
0ed0: 65 33 5f 66 69 6c 65 20 2a 70 54 65 6d 70 31 3b  e3_file *pTemp1;
0ee0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69             /* Fi
0ef0: 6c 65 20 74 6f 20 77 72 69 74 65 20 50 4d 41 73  le to write PMAs
0f00: 20 74 6f 2c 20 6f 72 20 4e 55 4c 4c 20 2a 2f 0a   to, or NULL */.
0f10: 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 4e 4f 54 45 53  };.../*.** NOTES
0f20: 20 4f 4e 20 44 41 54 41 20 53 54 52 55 43 54 55   ON DATA STRUCTU
0f30: 52 45 20 55 53 45 44 20 46 4f 52 20 4e 2d 57 41  RE USED FOR N-WA
0f40: 59 20 4d 45 52 47 45 53 3a 0a 2a 2a 0a 2a 2a 20  Y MERGES:.**.** 
0f50: 41 73 20 6b 65 79 73 20 61 72 65 20 61 64 64 65  As keys are adde
0f60: 64 20 74 6f 20 74 68 65 20 73 6f 72 74 65 72 2c  d to the sorter,
0f70: 20 74 68 65 79 20 61 72 65 20 77 72 69 74 74 65   they are writte
0f80: 6e 20 74 6f 20 64 69 73 6b 20 69 6e 20 61 20 73  n to disk in a s
0f90: 65 72 69 65 73 0a 2a 2a 20 6f 66 20 73 6f 72 74  eries.** of sort
0fa0: 65 64 20 70 61 63 6b 65 64 2d 6d 65 6d 6f 72 79  ed packed-memory
0fb0: 2d 61 72 72 61 79 73 20 28 50 4d 41 73 29 2e 20  -arrays (PMAs). 
0fc0: 54 68 65 20 73 69 7a 65 20 6f 66 20 65 61 63 68  The size of each
0fd0: 20 50 4d 41 20 69 73 20 72 6f 75 67 68 6c 79 0a   PMA is roughly.
0fe0: 2a 2a 20 74 68 65 20 73 61 6d 65 20 61 73 20 74  ** the same as t
0ff0: 68 65 20 63 61 63 68 65 2d 73 69 7a 65 20 61 6c  he cache-size al
1000: 6c 6f 77 65 64 20 66 6f 72 20 74 65 6d 70 6f 72  lowed for tempor
1010: 61 72 79 20 64 61 74 61 62 61 73 65 73 2e 20 49  ary databases. I
1020: 6e 20 6f 72 64 65 72 0a 2a 2a 20 74 6f 20 61 6c  n order.** to al
1030: 6c 6f 77 20 74 68 65 20 63 61 6c 6c 65 72 20 74  low the caller t
1040: 6f 20 65 78 74 72 61 63 74 20 6b 65 79 73 20 66  o extract keys f
1050: 72 6f 6d 20 74 68 65 20 73 6f 72 74 65 72 20 69  rom the sorter i
1060: 6e 20 73 6f 72 74 65 64 20 6f 72 64 65 72 2c 0a  n sorted order,.
1070: 2a 2a 20 61 6c 6c 20 50 4d 41 73 20 63 75 72 72  ** all PMAs curr
1080: 65 6e 74 6c 79 20 73 74 6f 72 65 64 20 6f 6e 20  ently stored on 
1090: 64 69 73 6b 20 6d 75 73 74 20 62 65 20 6d 65 72  disk must be mer
10a0: 67 65 64 20 74 6f 67 65 74 68 65 72 2e 20 54 68  ged together. Th
10b0: 69 73 20 63 6f 6d 6d 65 6e 74 0a 2a 2a 20 64 65  is comment.** de
10c0: 73 63 72 69 62 65 73 20 74 68 65 20 64 61 74 61  scribes the data
10d0: 20 73 74 72 75 63 74 75 72 65 20 75 73 65 64 20   structure used 
10e0: 74 6f 20 64 6f 20 73 6f 2e 20 54 68 65 20 73 74  to do so. The st
10f0: 72 75 63 74 75 72 65 20 73 75 70 70 6f 72 74 73  ructure supports
1100: 20 0a 2a 2a 20 6d 65 72 67 69 6e 67 20 61 6e 79   .** merging any
1110: 20 6e 75 6d 62 65 72 20 6f 66 20 61 72 72 61 79   number of array
1120: 73 20 69 6e 20 61 20 73 69 6e 67 6c 65 20 70 61  s in a single pa
1130: 73 73 20 77 69 74 68 20 6e 6f 20 72 65 64 75 6e  ss with no redun
1140: 64 61 6e 74 20 63 6f 6d 70 61 72 69 73 6f 6e 20  dant comparison 
1150: 0a 2a 2a 20 6f 70 65 72 61 74 69 6f 6e 73 2e 0a  .** operations..
1160: 2a 2a 0a 2a 2a 20 54 68 65 20 61 49 74 65 72 5b  **.** The aIter[
1170: 5d 20 61 72 72 61 79 20 63 6f 6e 74 61 69 6e 73  ] array contains
1180: 20 61 6e 20 69 74 65 72 61 74 6f 72 20 66 6f 72   an iterator for
1190: 20 65 61 63 68 20 6f 66 20 74 68 65 20 50 4d 41   each of the PMA
11a0: 73 20 62 65 69 6e 67 20 6d 65 72 67 65 64 2e 0a  s being merged..
11b0: 2a 2a 20 41 6e 20 61 49 74 65 72 5b 5d 20 69 74  ** An aIter[] it
11c0: 65 72 61 74 6f 72 20 65 69 74 68 65 72 20 70 6f  erator either po
11d0: 69 6e 74 73 20 74 6f 20 61 20 76 61 6c 69 64 20  ints to a valid 
11e0: 6b 65 79 20 6f 72 20 65 6c 73 65 20 69 73 20 61  key or else is a
11f0: 74 20 45 4f 46 2e 20 46 6f 72 20 0a 2a 2a 20 74  t EOF. For .** t
1200: 68 65 20 70 75 72 70 6f 73 65 73 20 6f 66 20 74  he purposes of t
1210: 68 65 20 70 61 72 61 67 72 61 70 68 73 20 62 65  he paragraphs be
1220: 6c 6f 77 2c 20 77 65 20 61 73 73 75 6d 65 20 74  low, we assume t
1230: 68 61 74 20 74 68 65 20 61 72 72 61 79 20 69 73  hat the array is
1240: 20 61 63 74 75 61 6c 6c 79 20 0a 2a 2a 20 4e 20   actually .** N 
1250: 65 6c 65 6d 65 6e 74 73 20 69 6e 20 73 69 7a 65  elements in size
1260: 2c 20 77 68 65 72 65 20 4e 20 69 73 20 74 68 65  , where N is the
1270: 20 73 6d 61 6c 6c 65 73 74 20 70 6f 77 65 72 20   smallest power 
1280: 6f 66 20 32 20 67 72 65 61 74 65 72 20 74 6f 20  of 2 greater to 
1290: 6f 72 20 65 71 75 61 6c 20 0a 2a 2a 20 74 6f 20  or equal .** to 
12a0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 69 74  the number of it
12b0: 65 72 61 74 6f 72 73 20 62 65 69 6e 67 20 6d 65  erators being me
12c0: 72 67 65 64 2e 20 54 68 65 20 65 78 74 72 61 20  rged. The extra 
12d0: 61 49 74 65 72 5b 5d 20 65 6c 65 6d 65 6e 74 73  aIter[] elements
12e0: 20 61 72 65 20 0a 2a 2a 20 74 72 65 61 74 65 64   are .** treated
12f0: 20 61 73 20 69 66 20 74 68 65 79 20 61 72 65 20   as if they are 
1300: 65 6d 70 74 79 20 28 61 6c 77 61 79 73 20 61 74  empty (always at
1310: 20 45 4f 46 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 65   EOF)..**.** The
1320: 20 61 54 72 65 65 5b 5d 20 61 72 72 61 79 20 69   aTree[] array i
1330: 73 20 61 6c 73 6f 20 4e 20 65 6c 65 6d 65 6e 74  s also N element
1340: 73 20 69 6e 20 73 69 7a 65 2e 20 54 68 65 20 76  s in size. The v
1350: 61 6c 75 65 20 6f 66 20 4e 20 69 73 20 73 74 6f  alue of N is sto
1360: 72 65 64 20 69 6e 0a 2a 2a 20 74 68 65 20 56 64  red in.** the Vd
1370: 62 65 53 6f 72 74 65 72 2e 6e 54 72 65 65 20 76  beSorter.nTree v
1380: 61 72 69 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54  ariable..**.** T
1390: 68 65 20 66 69 6e 61 6c 20 28 4e 2f 32 29 20 65  he final (N/2) e
13a0: 6c 65 6d 65 6e 74 73 20 6f 66 20 61 54 72 65 65  lements of aTree
13b0: 5b 5d 20 63 6f 6e 74 61 69 6e 20 74 68 65 20 72  [] contain the r
13c0: 65 73 75 6c 74 73 20 6f 66 20 63 6f 6d 70 61 72  esults of compar
13d0: 69 6e 67 0a 2a 2a 20 70 61 69 72 73 20 6f 66 20  ing.** pairs of 
13e0: 69 74 65 72 61 74 6f 72 20 6b 65 79 73 20 74 6f  iterator keys to
13f0: 67 65 74 68 65 72 2e 20 45 6c 65 6d 65 6e 74 20  gether. Element 
1400: 69 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 72  i contains the r
1410: 65 73 75 6c 74 20 6f 66 20 0a 2a 2a 20 63 6f 6d  esult of .** com
1420: 70 61 72 69 6e 67 20 61 49 74 65 72 5b 32 2a 69  paring aIter[2*i
1430: 2d 4e 5d 20 61 6e 64 20 61 49 74 65 72 5b 32 2a  -N] and aIter[2*
1440: 69 2d 4e 2b 31 5d 2e 20 57 68 69 63 68 65 76 65  i-N+1]. Whicheve
1450: 72 20 6b 65 79 20 69 73 20 73 6d 61 6c 6c 65 72  r key is smaller
1460: 2c 20 74 68 65 0a 2a 2a 20 61 54 72 65 65 20 65  , the.** aTree e
1470: 6c 65 6d 65 6e 74 20 69 73 20 73 65 74 20 74 6f  lement is set to
1480: 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20 69 74   the index of it
1490: 2e 20 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 74 68 65  . .**.** For the
14a0: 20 70 75 72 70 6f 73 65 73 20 6f 66 20 74 68 69   purposes of thi
14b0: 73 20 63 6f 6d 70 61 72 69 73 6f 6e 2c 20 45 4f  s comparison, EO
14c0: 46 20 69 73 20 63 6f 6e 73 69 64 65 72 65 64 20  F is considered 
14d0: 67 72 65 61 74 65 72 20 74 68 61 6e 20 61 6e 79  greater than any
14e0: 0a 2a 2a 20 6f 74 68 65 72 20 6b 65 79 20 76 61  .** other key va
14f0: 6c 75 65 2e 20 49 66 20 74 68 65 20 6b 65 79 73  lue. If the keys
1500: 20 61 72 65 20 65 71 75 61 6c 20 28 6f 6e 6c 79   are equal (only
1510: 20 70 6f 73 73 69 62 6c 65 20 77 69 74 68 20 74   possible with t
1520: 77 6f 20 45 4f 46 0a 2a 2a 20 76 61 6c 75 65 73  wo EOF.** values
1530: 29 2c 20 69 74 20 64 6f 65 73 6e 27 74 20 6d 61  ), it doesn't ma
1540: 74 74 65 72 20 77 68 69 63 68 20 69 6e 64 65 78  tter which index
1550: 20 69 73 20 73 74 6f 72 65 64 2e 0a 2a 2a 0a 2a   is stored..**.*
1560: 2a 20 54 68 65 20 28 4e 2f 34 29 20 65 6c 65 6d  * The (N/4) elem
1570: 65 6e 74 73 20 6f 66 20 61 54 72 65 65 5b 5d 20  ents of aTree[] 
1580: 74 68 61 74 20 70 72 65 63 65 64 65 20 74 68 65  that precede the
1590: 20 66 69 6e 61 6c 20 28 4e 2f 32 29 20 64 65 73   final (N/2) des
15a0: 63 72 69 62 65 64 20 0a 2a 2a 20 61 62 6f 76 65  cribed .** above
15b0: 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 69 6e   contains the in
15c0: 64 65 78 20 6f 66 20 74 68 65 20 73 6d 61 6c 6c  dex of the small
15d0: 65 73 74 20 6f 66 20 65 61 63 68 20 62 6c 6f 63  est of each bloc
15e0: 6b 20 6f 66 20 34 20 69 74 65 72 61 74 6f 72 73  k of 4 iterators
15f0: 2e 0a 2a 2a 20 41 6e 64 20 73 6f 20 6f 6e 2e 20  ..** And so on. 
1600: 53 6f 20 74 68 61 74 20 61 54 72 65 65 5b 31 5d  So that aTree[1]
1610: 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 69 6e   contains the in
1620: 64 65 78 20 6f 66 20 74 68 65 20 69 74 65 72 61  dex of the itera
1630: 74 6f 72 20 74 68 61 74 20 0a 2a 2a 20 63 75 72  tor that .** cur
1640: 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f  rently points to
1650: 20 74 68 65 20 73 6d 61 6c 6c 65 73 74 20 6b 65   the smallest ke
1660: 79 20 76 61 6c 75 65 2e 20 61 54 72 65 65 5b 30  y value. aTree[0
1670: 5d 20 69 73 20 75 6e 75 73 65 64 2e 0a 2a 2a 0a  ] is unused..**.
1680: 2a 2a 20 45 78 61 6d 70 6c 65 3a 0a 2a 2a 0a 2a  ** Example:.**.*
1690: 2a 20 20 20 20 20 61 49 74 65 72 5b 30 5d 20 2d  *     aIter[0] -
16a0: 3e 20 42 61 6e 61 6e 61 0a 2a 2a 20 20 20 20 20  > Banana.**     
16b0: 61 49 74 65 72 5b 31 5d 20 2d 3e 20 46 65 69 6a  aIter[1] -> Feij
16c0: 6f 61 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b  oa.**     aIter[
16d0: 32 5d 20 2d 3e 20 45 6c 64 65 72 62 65 72 72 79  2] -> Elderberry
16e0: 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 33 5d  .**     aIter[3]
16f0: 20 2d 3e 20 43 75 72 72 61 6e 74 0a 2a 2a 20 20   -> Currant.**  
1700: 20 20 20 61 49 74 65 72 5b 34 5d 20 2d 3e 20 47     aIter[4] -> G
1710: 72 61 70 65 66 72 75 69 74 0a 2a 2a 20 20 20 20  rapefruit.**    
1720: 20 61 49 74 65 72 5b 35 5d 20 2d 3e 20 41 70 70   aIter[5] -> App
1730: 6c 65 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b  le.**     aIter[
1740: 36 5d 20 2d 3e 20 44 75 72 69 61 6e 0a 2a 2a 20  6] -> Durian.** 
1750: 20 20 20 20 61 49 74 65 72 5b 37 5d 20 2d 3e 20      aIter[7] -> 
1760: 45 4f 46 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 54  EOF.**.**     aT
1770: 72 65 65 5b 5d 20 3d 20 7b 20 58 2c 20 35 20 20  ree[] = { X, 5  
1780: 20 30 2c 20 35 20 20 20 20 30 2c 20 33 2c 20 35   0, 5    0, 3, 5
1790: 2c 20 36 20 7d 0a 2a 2a 0a 2a 2a 20 54 68 65 20  , 6 }.**.** The 
17a0: 63 75 72 72 65 6e 74 20 65 6c 65 6d 65 6e 74 20  current element 
17b0: 69 73 20 22 41 70 70 6c 65 22 20 28 74 68 65 20  is "Apple" (the 
17c0: 76 61 6c 75 65 20 6f 66 20 74 68 65 20 6b 65 79  value of the key
17d0: 20 69 6e 64 69 63 61 74 65 64 20 62 79 20 0a 2a   indicated by .*
17e0: 2a 20 69 74 65 72 61 74 6f 72 20 35 29 2e 20 57  * iterator 5). W
17f0: 68 65 6e 20 74 68 65 20 4e 65 78 74 28 29 20 6f  hen the Next() o
1800: 70 65 72 61 74 69 6f 6e 20 69 73 20 69 6e 76 6f  peration is invo
1810: 6b 65 64 2c 20 69 74 65 72 61 74 6f 72 20 35 20  ked, iterator 5 
1820: 77 69 6c 6c 0a 2a 2a 20 62 65 20 61 64 76 61 6e  will.** be advan
1830: 63 65 64 20 74 6f 20 74 68 65 20 6e 65 78 74 20  ced to the next 
1840: 6b 65 79 20 69 6e 20 69 74 73 20 73 65 67 6d 65  key in its segme
1850: 6e 74 2e 20 53 61 79 20 74 68 65 20 6e 65 78 74  nt. Say the next
1860: 20 6b 65 79 20 69 73 0a 2a 2a 20 22 45 67 67 70   key is.** "Eggp
1870: 6c 61 6e 74 22 3a 0a 2a 2a 0a 2a 2a 20 20 20 20  lant":.**.**    
1880: 20 61 49 74 65 72 5b 35 5d 20 2d 3e 20 45 67 67   aIter[5] -> Egg
1890: 70 6c 61 6e 74 0a 2a 2a 0a 2a 2a 20 54 68 65 20  plant.**.** The 
18a0: 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61 54 72 65  contents of aTre
18b0: 65 5b 5d 20 61 72 65 20 75 70 64 61 74 65 64 20  e[] are updated 
18c0: 66 69 72 73 74 20 62 79 20 63 6f 6d 70 61 72 69  first by compari
18d0: 6e 67 20 74 68 65 20 6e 65 77 20 69 74 65 72 61  ng the new itera
18e0: 74 6f 72 0a 2a 2a 20 35 20 6b 65 79 20 74 6f 20  tor.** 5 key to 
18f0: 74 68 65 20 63 75 72 72 65 6e 74 20 6b 65 79 20  the current key 
1900: 6f 66 20 69 74 65 72 61 74 6f 72 20 34 20 28 73  of iterator 4 (s
1910: 74 69 6c 6c 20 22 47 72 61 70 65 66 72 75 69 74  till "Grapefruit
1920: 22 29 2e 20 54 68 65 20 69 74 65 72 61 74 6f 72  "). The iterator
1930: 0a 2a 2a 20 35 20 76 61 6c 75 65 20 69 73 20 73  .** 5 value is s
1940: 74 69 6c 6c 20 73 6d 61 6c 6c 65 72 2c 20 73 6f  till smaller, so
1950: 20 61 54 72 65 65 5b 36 5d 20 69 73 20 73 65 74   aTree[6] is set
1960: 20 74 6f 20 35 2e 20 41 6e 64 20 73 6f 20 6f 6e   to 5. And so on
1970: 20 75 70 20 74 68 65 20 74 72 65 65 2e 0a 2a 2a   up the tree..**
1980: 20 54 68 65 20 76 61 6c 75 65 20 6f 66 20 69 74   The value of it
1990: 65 72 61 74 6f 72 20 36 20 2d 20 22 44 75 72 69  erator 6 - "Duri
19a0: 61 6e 22 20 2d 20 69 73 20 6e 6f 77 20 73 6d 61  an" - is now sma
19b0: 6c 6c 65 72 20 74 68 61 6e 20 74 68 61 74 20 6f  ller than that o
19c0: 66 20 69 74 65 72 61 74 6f 72 0a 2a 2a 20 35 2c  f iterator.** 5,
19d0: 20 73 6f 20 61 54 72 65 65 5b 33 5d 20 69 73 20   so aTree[3] is 
19e0: 73 65 74 20 74 6f 20 36 2e 20 4b 65 79 20 30 20  set to 6. Key 0 
19f0: 69 73 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20  is smaller than 
1a00: 6b 65 79 20 36 20 28 42 61 6e 61 6e 61 3c 44 75  key 6 (Banana<Du
1a10: 72 69 61 6e 29 2c 0a 2a 2a 20 73 6f 20 74 68 65  rian),.** so the
1a20: 20 76 61 6c 75 65 20 77 72 69 74 74 65 6e 20 69   value written i
1a30: 6e 74 6f 20 65 6c 65 6d 65 6e 74 20 31 20 6f 66  nto element 1 of
1a40: 20 74 68 65 20 61 72 72 61 79 20 69 73 20 30 2e   the array is 0.
1a50: 20 41 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a   As follows:.**.
1a60: 2a 2a 20 20 20 20 20 61 54 72 65 65 5b 5d 20 3d  **     aTree[] =
1a70: 20 7b 20 58 2c 20 30 20 20 20 30 2c 20 36 20 20   { X, 0   0, 6  
1a80: 20 20 30 2c 20 33 2c 20 35 2c 20 36 20 7d 0a 2a    0, 3, 5, 6 }.*
1a90: 2a 0a 2a 2a 20 49 6e 20 6f 74 68 65 72 20 77 6f  *.** In other wo
1aa0: 72 64 73 2c 20 65 61 63 68 20 74 69 6d 65 20 77  rds, each time w
1ab0: 65 20 61 64 76 61 6e 63 65 20 74 6f 20 74 68 65  e advance to the
1ac0: 20 6e 65 78 74 20 73 6f 72 74 65 72 20 65 6c 65   next sorter ele
1ad0: 6d 65 6e 74 2c 20 6c 6f 67 32 28 4e 29 0a 2a 2a  ment, log2(N).**
1ae0: 20 6b 65 79 20 63 6f 6d 70 61 72 69 73 6f 6e 20   key comparison 
1af0: 6f 70 65 72 61 74 69 6f 6e 73 20 61 72 65 20 72  operations are r
1b00: 65 71 75 69 72 65 64 2c 20 77 68 65 72 65 20 4e  equired, where N
1b10: 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f   is the number o
1b20: 66 20 73 65 67 6d 65 6e 74 73 0a 2a 2a 20 62 65  f segments.** be
1b30: 69 6e 67 20 6d 65 72 67 65 64 20 28 72 6f 75 6e  ing merged (roun
1b40: 64 65 64 20 75 70 20 74 6f 20 74 68 65 20 6e 65  ded up to the ne
1b50: 78 74 20 70 6f 77 65 72 20 6f 66 20 32 29 2e 0a  xt power of 2)..
1b60: 2a 2f 0a 73 74 72 75 63 74 20 53 6f 72 74 65 72  */.struct Sorter
1b70: 4d 65 72 67 65 72 20 7b 0a 20 20 69 6e 74 20 6e  Merger {.  int n
1b80: 54 72 65 65 3b 20 20 20 20 20 20 20 20 20 20 20  Tree;           
1b90: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73             /* Us
1ba0: 65 64 20 73 69 7a 65 20 6f 66 20 61 54 72 65 65  ed size of aTree
1bb0: 2f 61 49 74 65 72 20 28 70 6f 77 65 72 20 6f 66  /aIter (power of
1bc0: 20 32 29 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 54   2) */.  int *aT
1bd0: 72 65 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ree;            
1be0: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72           /* Curr
1bf0: 65 6e 74 20 73 74 61 74 65 20 6f 66 20 69 6e 63  ent state of inc
1c00: 72 65 6d 65 6e 74 61 6c 20 6d 65 72 67 65 20 2a  remental merge *
1c10: 2f 0a 20 20 56 64 62 65 53 6f 72 74 65 72 49 74  /.  VdbeSorterIt
1c20: 65 72 20 2a 61 49 74 65 72 3b 20 20 20 20 20 20  er *aIter;      
1c30: 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20      /* Array of 
1c40: 69 74 65 72 61 74 6f 72 73 20 74 6f 20 6d 65 72  iterators to mer
1c50: 67 65 20 64 61 74 61 20 66 72 6f 6d 20 2a 2f 0a  ge data from */.
1c60: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 4d 61 69 6e 20 73  };../*.** Main s
1c70: 6f 72 74 65 72 20 73 74 72 75 63 74 75 72 65 2e  orter structure.
1c80: 20 41 20 73 69 6e 67 6c 65 20 69 6e 73 74 61 6e   A single instan
1c90: 63 65 20 6f 66 20 74 68 69 73 20 69 73 20 61 6c  ce of this is al
1ca0: 6c 6f 63 61 74 65 64 20 66 6f 72 20 65 61 63 68  located for each
1cb0: 20 0a 2a 2a 20 73 6f 72 74 65 72 20 63 75 72 73   .** sorter curs
1cc0: 6f 72 20 63 72 65 61 74 65 64 20 62 79 20 74 68  or created by th
1cd0: 65 20 56 44 42 45 2e 0a 2a 2f 0a 73 74 72 75 63  e VDBE..*/.struc
1ce0: 74 20 56 64 62 65 53 6f 72 74 65 72 20 7b 0a 20  t VdbeSorter {. 
1cf0: 20 69 6e 74 20 6e 49 6e 4d 65 6d 6f 72 79 3b 20   int nInMemory; 
1d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d10: 20 2f 2a 20 43 75 72 72 65 6e 74 20 73 69 7a 65   /* Current size
1d20: 20 6f 66 20 70 52 65 63 6f 72 64 20 6c 69 73 74   of pRecord list
1d30: 20 61 73 20 50 4d 41 20 2a 2f 0a 20 20 69 6e 74   as PMA */.  int
1d40: 20 6d 6e 50 6d 61 53 69 7a 65 3b 20 20 20 20 20   mnPmaSize;     
1d50: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1d60: 4d 69 6e 69 6d 75 6d 20 50 4d 41 20 73 69 7a 65  Minimum PMA size
1d70: 2c 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  , in bytes */.  
1d80: 69 6e 74 20 6d 78 50 6d 61 53 69 7a 65 3b 20 20  int mxPmaSize;  
1d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1da0: 2f 2a 20 4d 61 78 69 6d 75 6d 20 50 4d 41 20 73  /* Maximum PMA s
1db0: 69 7a 65 2c 20 69 6e 20 62 79 74 65 73 2e 20 20  ize, in bytes.  
1dc0: 30 3d 3d 6e 6f 20 6c 69 6d 69 74 20 2a 2f 0a 20  0==no limit */. 
1dd0: 20 69 6e 74 20 62 55 73 65 50 4d 41 3b 20 20 20   int bUsePMA;   
1de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1df0: 20 2f 2a 20 54 72 75 65 20 69 66 20 6f 6e 65 20   /* True if one 
1e00: 6f 72 20 6d 6f 72 65 20 50 4d 41 73 20 63 72 65  or more PMAs cre
1e10: 61 74 65 64 20 2a 2f 0a 20 20 53 6f 72 74 65 72  ated */.  Sorter
1e20: 52 65 63 6f 72 64 20 2a 70 52 65 63 6f 72 64 3b  Record *pRecord;
1e30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48 65 61            /* Hea
1e40: 64 20 6f 66 20 69 6e 2d 6d 65 6d 6f 72 79 20 72  d of in-memory r
1e50: 65 63 6f 72 64 20 6c 69 73 74 20 2a 2f 0a 20 20  ecord list */.  
1e60: 53 6f 72 74 65 72 4d 65 72 67 65 72 20 2a 70 4d  SorterMerger *pM
1e70: 65 72 67 65 72 3b 20 20 20 20 20 20 20 20 20 20  erger;          
1e80: 2f 2a 20 46 6f 72 20 66 69 6e 61 6c 20 6d 65 72  /* For final mer
1e90: 67 65 20 6f 66 20 50 4d 41 73 20 28 62 79 20 63  ge of PMAs (by c
1ea0: 61 6c 6c 65 72 29 20 2a 2f 20 0a 20 20 75 38 20  aller) */ .  u8 
1eb0: 2a 61 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20 20  *aMemory;       
1ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1ed0: 42 6c 6f 63 6b 20 6f 66 20 6d 65 6d 6f 72 79 20  Block of memory 
1ee0: 74 6f 20 61 6c 6c 6f 63 20 72 65 63 6f 72 64 73  to alloc records
1ef0: 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 6e 74 20 69   from */.  int i
1f00: 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20 20 20 20  Memory;         
1f10: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66             /* Of
1f20: 66 73 65 74 20 6f 66 20 66 69 72 73 74 20 66 72  fset of first fr
1f30: 65 65 20 62 79 74 65 20 69 6e 20 61 4d 65 6d 6f  ee byte in aMemo
1f40: 72 79 20 2a 2f 0a 20 20 69 6e 74 20 6e 4d 65 6d  ry */.  int nMem
1f50: 6f 72 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  ory;            
1f60: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
1f70: 6f 66 20 61 4d 65 6d 6f 72 79 20 61 6c 6c 6f 63  of aMemory alloc
1f80: 61 74 69 6f 6e 20 69 6e 20 62 79 74 65 73 20 2a  ation in bytes *
1f90: 2f 0a 20 20 69 6e 74 20 69 50 72 65 76 3b 20 20  /.  int iPrev;  
1fa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fb0: 20 20 20 20 2f 2a 20 50 72 65 76 69 6f 75 73 20      /* Previous 
1fc0: 74 68 72 65 61 64 20 75 73 65 64 20 74 6f 20 66  thread used to f
1fd0: 6c 75 73 68 20 50 4d 41 20 2a 2f 0a 20 20 69 6e  lush PMA */.  in
1fe0: 74 20 6e 54 68 72 65 61 64 3b 20 20 20 20 20 20  t nThread;      
1ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2000: 20 53 69 7a 65 20 6f 66 20 61 54 68 72 65 61 64   Size of aThread
2010: 5b 5d 20 61 72 72 61 79 20 2a 2f 0a 20 20 53 6f  [] array */.  So
2020: 72 74 65 72 54 68 72 65 61 64 20 61 54 68 72 65  rterThread aThre
2030: 61 64 5b 31 5d 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a  ad[1];.};../*.**
2040: 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74   The following t
2050: 79 70 65 20 69 73 20 61 6e 20 69 74 65 72 61 74  ype is an iterat
2060: 6f 72 20 66 6f 72 20 61 20 50 4d 41 2e 20 49 74  or for a PMA. It
2070: 20 63 61 63 68 65 73 20 74 68 65 20 63 75 72 72   caches the curr
2080: 65 6e 74 20 6b 65 79 20 69 6e 20 0a 2a 2a 20 76  ent key in .** v
2090: 61 72 69 61 62 6c 65 73 20 6e 4b 65 79 2f 61 4b  ariables nKey/aK
20a0: 65 79 2e 20 49 66 20 74 68 65 20 69 74 65 72 61  ey. If the itera
20b0: 74 6f 72 20 69 73 20 61 74 20 45 4f 46 2c 20 70  tor is at EOF, p
20c0: 46 69 6c 65 3d 3d 30 2e 0a 2a 2f 0a 73 74 72 75  File==0..*/.stru
20d0: 63 74 20 56 64 62 65 53 6f 72 74 65 72 49 74 65  ct VdbeSorterIte
20e0: 72 20 7b 0a 20 20 69 36 34 20 69 52 65 61 64 4f  r {.  i64 iReadO
20f0: 66 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ff;             
2100: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
2110: 20 72 65 61 64 20 6f 66 66 73 65 74 20 2a 2f 0a   read offset */.
2120: 20 20 69 36 34 20 69 45 6f 66 3b 20 20 20 20 20    i64 iEof;     
2130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2140: 20 20 2f 2a 20 31 20 62 79 74 65 20 70 61 73 74    /* 1 byte past
2150: 20 45 4f 46 20 66 6f 72 20 74 68 69 73 20 69 74   EOF for this it
2160: 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20  erator */.  int 
2170: 6e 41 6c 6c 6f 63 3b 20 20 20 20 20 20 20 20 20  nAlloc;         
2180: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
2190: 79 74 65 73 20 6f 66 20 73 70 61 63 65 20 61 74  ytes of space at
21a0: 20 61 41 6c 6c 6f 63 20 2a 2f 0a 20 20 69 6e 74   aAlloc */.  int
21b0: 20 6e 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20   nKey;          
21c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
21d0: 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  Number of bytes 
21e0: 69 6e 20 6b 65 79 20 2a 2f 0a 20 20 73 71 6c 69  in key */.  sqli
21f0: 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 3b  te3_file *pFile;
2200: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
2210: 69 6c 65 20 69 74 65 72 61 74 6f 72 20 69 73 20  ile iterator is 
2220: 72 65 61 64 69 6e 67 20 66 72 6f 6d 20 2a 2f 0a  reading from */.
2230: 20 20 75 38 20 2a 61 41 6c 6c 6f 63 3b 20 20 20    u8 *aAlloc;   
2240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2250: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 64 20 73    /* Allocated s
2260: 70 61 63 65 20 2a 2f 0a 20 20 75 38 20 2a 61 4b  pace */.  u8 *aK
2270: 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ey;             
2280: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
2290: 6e 74 65 72 20 74 6f 20 63 75 72 72 65 6e 74 20  nter to current 
22a0: 6b 65 79 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75  key */.  u8 *aBu
22b0: 66 66 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  ffer;           
22c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72           /* Curr
22d0: 65 6e 74 20 72 65 61 64 20 62 75 66 66 65 72 20  ent read buffer 
22e0: 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66 66 65 72  */.  int nBuffer
22f0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
2300: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
2310: 72 65 61 64 20 62 75 66 66 65 72 20 69 6e 20 62  read buffer in b
2320: 79 74 65 73 20 2a 2f 0a 20 20 75 38 20 2a 61 4d  ytes */.  u8 *aM
2330: 61 70 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ap;             
2340: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
2350: 6e 74 65 72 20 74 6f 20 6d 61 70 70 69 6e 67 20  nter to mapping 
2360: 6f 66 20 65 6e 74 69 72 65 20 66 69 6c 65 20 2a  of entire file *
2370: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69  /.};../*.** An i
2380: 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20  nstance of this 
2390: 73 74 72 75 63 74 75 72 65 20 69 73 20 75 73 65  structure is use
23a0: 64 20 74 6f 20 6f 72 67 61 6e 69 7a 65 20 74 68  d to organize th
23b0: 65 20 73 74 72 65 61 6d 20 6f 66 20 72 65 63 6f  e stream of reco
23c0: 72 64 73 0a 2a 2a 20 62 65 69 6e 67 20 77 72 69  rds.** being wri
23d0: 74 74 65 6e 20 74 6f 20 66 69 6c 65 73 20 62 79  tten to files by
23e0: 20 74 68 65 20 6d 65 72 67 65 2d 73 6f 72 74 20   the merge-sort 
23f0: 63 6f 64 65 20 69 6e 74 6f 20 61 6c 69 67 6e 65  code into aligne
2400: 64 2c 20 70 61 67 65 2d 73 69 7a 65 64 0a 2a 2a  d, page-sized.**
2410: 20 62 6c 6f 63 6b 73 2e 20 20 44 6f 69 6e 67 20   blocks.  Doing 
2420: 61 6c 6c 20 49 2f 4f 20 69 6e 20 61 6c 69 67 6e  all I/O in align
2430: 65 64 20 70 61 67 65 2d 73 69 7a 65 64 20 62 6c  ed page-sized bl
2440: 6f 63 6b 73 20 68 65 6c 70 73 20 49 2f 4f 20 74  ocks helps I/O t
2450: 6f 20 67 6f 0a 2a 2a 20 66 61 73 74 65 72 20 6f  o go.** faster o
2460: 6e 20 6d 61 6e 79 20 6f 70 65 72 61 74 69 6e 67  n many operating
2470: 20 73 79 73 74 65 6d 73 2e 0a 2a 2f 0a 73 74 72   systems..*/.str
2480: 75 63 74 20 46 69 6c 65 57 72 69 74 65 72 20 7b  uct FileWriter {
2490: 0a 20 20 69 6e 74 20 65 46 57 45 72 72 3b 20 20  .  int eFWErr;  
24a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24b0: 20 20 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20 69     /* Non-zero i
24c0: 66 20 69 6e 20 61 6e 20 65 72 72 6f 72 20 73 74  f in an error st
24d0: 61 74 65 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75  ate */.  u8 *aBu
24e0: 66 66 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  ffer;           
24f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
2500: 74 65 72 20 74 6f 20 77 72 69 74 65 20 62 75 66  ter to write buf
2510: 66 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 75  fer */.  int nBu
2520: 66 66 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  ffer;           
2530: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
2540: 20 6f 66 20 77 72 69 74 65 20 62 75 66 66 65 72   of write buffer
2550: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69   in bytes */.  i
2560: 6e 74 20 69 42 75 66 53 74 61 72 74 3b 20 20 20  nt iBufStart;   
2570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2580: 2a 20 46 69 72 73 74 20 62 79 74 65 20 6f 66 20  * First byte of 
2590: 62 75 66 66 65 72 20 74 6f 20 77 72 69 74 65 20  buffer to write 
25a0: 2a 2f 0a 20 20 69 6e 74 20 69 42 75 66 45 6e 64  */.  int iBufEnd
25b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
25c0: 20 20 20 20 20 2f 2a 20 4c 61 73 74 20 62 79 74       /* Last byt
25d0: 65 20 6f 66 20 62 75 66 66 65 72 20 74 6f 20 77  e of buffer to w
25e0: 72 69 74 65 20 2a 2f 0a 20 20 69 36 34 20 69 57  rite */.  i64 iW
25f0: 72 69 74 65 4f 66 66 3b 20 20 20 20 20 20 20 20  riteOff;        
2600: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66            /* Off
2610: 73 65 74 20 6f 66 20 73 74 61 72 74 20 6f 66 20  set of start of 
2620: 62 75 66 66 65 72 20 69 6e 20 66 69 6c 65 20 2a  buffer in file *
2630: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  /.  sqlite3_file
2640: 20 2a 70 46 69 6c 65 3b 20 20 20 20 20 20 20 20   *pFile;        
2650: 20 20 20 20 2f 2a 20 46 69 6c 65 20 74 6f 20 77      /* File to w
2660: 72 69 74 65 20 74 6f 20 2a 2f 0a 7d 3b 0a 0a 2f  rite to */.};../
2670: 2a 0a 2a 2a 20 41 20 73 74 72 75 63 74 75 72 65  *.** A structure
2680: 20 74 6f 20 73 74 6f 72 65 20 61 20 73 69 6e 67   to store a sing
2690: 6c 65 20 72 65 63 6f 72 64 2e 20 41 6c 6c 20 69  le record. All i
26a0: 6e 2d 6d 65 6d 6f 72 79 20 72 65 63 6f 72 64 73  n-memory records
26b0: 20 61 72 65 20 63 6f 6e 6e 65 63 74 65 64 0a 2a   are connected.*
26c0: 2a 20 74 6f 67 65 74 68 65 72 20 69 6e 74 6f 20  * together into 
26d0: 61 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 68 65  a linked list he
26e0: 61 64 65 64 20 61 74 20 56 64 62 65 53 6f 72 74  aded at VdbeSort
26f0: 65 72 2e 70 52 65 63 6f 72 64 2e 0a 2a 2a 0a 2a  er.pRecord..**.*
2700: 2a 20 48 6f 77 20 74 68 65 20 6c 69 6e 6b 65 64  * How the linked
2710: 20 6c 69 73 74 20 69 73 20 63 6f 6e 6e 65 63 74   list is connect
2720: 65 64 20 64 65 70 65 6e 64 73 20 6f 6e 20 68 6f  ed depends on ho
2730: 77 20 6d 65 6d 6f 72 79 20 69 73 20 62 65 69 6e  w memory is bein
2740: 67 20 6d 61 6e 61 67 65 64 0a 2a 2a 20 62 79 20  g managed.** by 
2750: 74 68 69 73 20 6d 6f 64 75 6c 65 2e 20 49 66 20  this module. If 
2760: 75 73 69 6e 67 20 61 20 73 65 70 61 72 61 74 65  using a separate
2770: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 6f 72 20   allocation for 
2780: 65 61 63 68 20 69 6e 2d 6d 65 6d 6f 72 79 20 72  each in-memory r
2790: 65 63 6f 72 64 0a 2a 2a 20 28 56 64 62 65 53 6f  ecord.** (VdbeSo
27a0: 72 74 65 72 2e 61 4d 65 6d 6f 72 79 3d 3d 30 29  rter.aMemory==0)
27b0: 2c 20 74 68 65 6e 20 74 68 65 20 6c 69 73 74 20  , then the list 
27c0: 69 73 20 61 6c 77 61 79 73 20 63 6f 6e 6e 65 63  is always connec
27d0: 74 65 64 20 75 73 69 6e 67 20 74 68 65 0a 2a 2a  ted using the.**
27e0: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 75 2e   SorterRecord.u.
27f0: 70 4e 65 78 74 20 70 6f 69 6e 74 65 72 73 2e 0a  pNext pointers..
2800: 2a 2a 0a 2a 2a 20 4f 72 2c 20 69 66 20 75 73 69  **.** Or, if usi
2810: 6e 67 20 74 68 65 20 73 69 6e 67 6c 65 20 6c 61  ng the single la
2820: 72 67 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6d  rge allocation m
2830: 65 74 68 6f 64 20 28 56 64 62 65 53 6f 72 74 65  ethod (VdbeSorte
2840: 72 2e 61 4d 65 6d 6f 72 79 21 3d 30 29 2c 0a 2a  r.aMemory!=0),.*
2850: 2a 20 74 68 65 6e 20 77 68 69 6c 65 20 72 65 63  * then while rec
2860: 6f 72 64 73 20 61 72 65 20 62 65 69 6e 67 20 61  ords are being a
2870: 63 63 75 6d 75 6c 61 74 65 64 20 74 68 65 20 6c  ccumulated the l
2880: 69 73 74 20 69 73 20 6c 69 6e 6b 65 64 20 75 73  ist is linked us
2890: 69 6e 67 20 74 68 65 0a 2a 2a 20 53 6f 72 74 65  ing the.** Sorte
28a0: 72 52 65 63 6f 72 64 2e 75 2e 69 4e 65 78 74 20  rRecord.u.iNext 
28b0: 6f 66 66 73 65 74 2e 20 54 68 69 73 20 69 73 20  offset. This is 
28c0: 62 65 63 61 75 73 65 20 74 68 65 20 61 4d 65 6d  because the aMem
28d0: 6f 72 79 5b 5d 20 61 72 72 61 79 20 6d 61 79 0a  ory[] array may.
28e0: 2a 2a 20 62 65 20 73 71 6c 69 74 65 33 52 65 61  ** be sqlite3Rea
28f0: 6c 6c 6f 63 28 29 65 64 20 77 68 69 6c 65 20 72  lloc()ed while r
2900: 65 63 6f 72 64 73 20 61 72 65 20 62 65 69 6e 67  ecords are being
2910: 20 61 63 63 75 6d 75 6c 61 74 65 64 2e 20 4f 6e   accumulated. On
2920: 63 65 20 74 68 65 20 56 4d 0a 2a 2a 20 68 61 73  ce the VM.** has
2930: 20 66 69 6e 69 73 68 65 64 20 70 61 73 73 69 6e   finished passin
2940: 67 20 72 65 63 6f 72 64 73 20 74 6f 20 74 68 65  g records to the
2950: 20 73 6f 72 74 65 72 2c 20 6f 72 20 77 68 65 6e   sorter, or when
2960: 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 62   the in-memory b
2970: 75 66 66 65 72 0a 2a 2a 20 69 73 20 66 75 6c 6c  uffer.** is full
2980: 2c 20 74 68 65 20 6c 69 73 74 20 69 73 20 73 6f  , the list is so
2990: 72 74 65 64 2e 20 41 73 20 70 61 72 74 20 6f 66  rted. As part of
29a0: 20 74 68 65 20 73 6f 72 74 69 6e 67 20 70 72 6f   the sorting pro
29b0: 63 65 73 73 2c 20 69 74 20 69 73 0a 2a 2a 20 63  cess, it is.** c
29c0: 6f 6e 76 65 72 74 65 64 20 74 6f 20 75 73 65 20  onverted to use 
29d0: 74 68 65 20 53 6f 72 74 65 72 52 65 63 6f 72 64  the SorterRecord
29e0: 2e 75 2e 70 4e 65 78 74 20 70 6f 69 6e 74 65 72  .u.pNext pointer
29f0: 73 2e 20 53 65 65 20 66 75 6e 63 74 69 6f 6e 0a  s. See function.
2a00: 2a 2a 20 76 64 62 65 53 6f 72 74 65 72 53 6f 72  ** vdbeSorterSor
2a10: 74 28 29 20 66 6f 72 20 64 65 74 61 69 6c 73 2e  t() for details.
2a20: 0a 2a 2f 0a 73 74 72 75 63 74 20 53 6f 72 74 65  .*/.struct Sorte
2a30: 72 52 65 63 6f 72 64 20 7b 0a 20 20 69 6e 74 20  rRecord {.  int 
2a40: 6e 56 61 6c 3b 0a 20 20 75 6e 69 6f 6e 20 7b 0a  nVal;.  union {.
2a50: 20 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64      SorterRecord
2a60: 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20 20   *pNext;        
2a70: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
2a80: 6e 65 78 74 20 72 65 63 6f 72 64 20 69 6e 20 6c  next record in l
2a90: 69 73 74 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69  ist */.    int i
2aa0: 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 20  Next;           
2ab0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73           /* Offs
2ac0: 65 74 20 77 69 74 68 69 6e 20 61 4d 65 6d 6f 72  et within aMemor
2ad0: 79 20 6f 66 20 6e 65 78 74 20 72 65 63 6f 72 64  y of next record
2ae0: 20 2a 2f 0a 20 20 7d 20 75 3b 0a 7d 3b 0a 0a 2f   */.  } u;.};../
2af0: 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74  * Return a point
2b00: 65 72 20 74 6f 20 74 68 65 20 62 75 66 66 65 72  er to the buffer
2b10: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20   containing the 
2b20: 72 65 63 6f 72 64 20 64 61 74 61 20 66 6f 72 20  record data for 
2b30: 53 6f 72 74 65 72 52 65 63 6f 72 64 0a 2a 2a 20  SorterRecord.** 
2b40: 6f 62 6a 65 63 74 20 70 2e 20 53 68 6f 75 6c 64  object p. Should
2b50: 20 62 65 20 75 73 65 64 20 61 73 20 69 66 3a 0a   be used as if:.
2b60: 2a 2a 0a 2a 2a 20 20 20 76 6f 69 64 20 2a 53 52  **.**   void *SR
2b70: 56 41 4c 28 53 6f 72 74 65 72 52 65 63 6f 72 64  VAL(SorterRecord
2b80: 20 2a 70 29 20 7b 20 72 65 74 75 72 6e 20 28 76   *p) { return (v
2b90: 6f 69 64 2a 29 26 70 5b 31 5d 3b 20 7d 0a 2a 2f  oid*)&p[1]; }.*/
2ba0: 0a 23 64 65 66 69 6e 65 20 53 52 56 41 4c 28 70  .#define SRVAL(p
2bb0: 29 20 28 28 76 6f 69 64 2a 29 28 28 53 6f 72 74  ) ((void*)((Sort
2bc0: 65 72 52 65 63 6f 72 64 2a 29 28 70 29 20 2b 20  erRecord*)(p) + 
2bd0: 31 29 29 0a 0a 2f 2a 20 54 68 65 20 6d 69 6e 69  1))../* The mini
2be0: 6d 75 6d 20 50 4d 41 20 73 69 7a 65 20 69 73 20  mum PMA size is 
2bf0: 73 65 74 20 74 6f 20 74 68 69 73 20 76 61 6c 75  set to this valu
2c00: 65 20 6d 75 6c 74 69 70 6c 69 65 64 20 62 79 20  e multiplied by 
2c10: 74 68 65 20 64 61 74 61 62 61 73 65 0a 2a 2a 20  the database.** 
2c20: 70 61 67 65 20 73 69 7a 65 20 69 6e 20 62 79 74  page size in byt
2c30: 65 73 2e 20 20 2a 2f 0a 23 64 65 66 69 6e 65 20  es.  */.#define 
2c40: 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49  SORTER_MIN_WORKI
2c50: 4e 47 20 31 30 0a 0a 2f 2a 20 4d 61 78 69 6d 75  NG 10../* Maximu
2c60: 6d 20 6e 75 6d 62 65 72 20 6f 66 20 73 65 67 6d  m number of segm
2c70: 65 6e 74 73 20 74 6f 20 6d 65 72 67 65 20 69 6e  ents to merge in
2c80: 20 61 20 73 69 6e 67 6c 65 20 70 61 73 73 2e 20   a single pass. 
2c90: 2a 2f 0a 23 64 65 66 69 6e 65 20 53 4f 52 54 45  */.#define SORTE
2ca0: 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
2cb0: 54 20 31 36 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65  T 16../*.** Free
2cc0: 20 61 6c 6c 20 6d 65 6d 6f 72 79 20 62 65 6c 6f   all memory belo
2cd0: 6e 67 69 6e 67 20 74 6f 20 74 68 65 20 56 64 62  nging to the Vdb
2ce0: 65 53 6f 72 74 65 72 49 74 65 72 20 6f 62 6a 65  eSorterIter obje
2cf0: 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68 65  ct passed as the
2d00: 20 73 65 63 6f 6e 64 0a 2a 2a 20 61 72 67 75 6d   second.** argum
2d10: 65 6e 74 2e 20 41 6c 6c 20 73 74 72 75 63 74 75  ent. All structu
2d20: 72 65 20 66 69 65 6c 64 73 20 61 72 65 20 73 65  re fields are se
2d30: 74 20 74 6f 20 7a 65 72 6f 20 62 65 66 6f 72 65  t to zero before
2d40: 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73   returning..*/.s
2d50: 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 53  tatic void vdbeS
2d60: 6f 72 74 65 72 49 74 65 72 5a 65 72 6f 28 56 64  orterIterZero(Vd
2d70: 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70 49  beSorterIter *pI
2d80: 74 65 72 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f  ter){.  sqlite3_
2d90: 66 72 65 65 28 70 49 74 65 72 2d 3e 61 41 6c 6c  free(pIter->aAll
2da0: 6f 63 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  oc);.  sqlite3_f
2db0: 72 65 65 28 70 49 74 65 72 2d 3e 61 42 75 66 66  ree(pIter->aBuff
2dc0: 65 72 29 3b 0a 20 20 69 66 28 20 70 49 74 65 72  er);.  if( pIter
2dd0: 2d 3e 61 4d 61 70 20 29 20 73 71 6c 69 74 65 33  ->aMap ) sqlite3
2de0: 4f 73 55 6e 66 65 74 63 68 28 70 49 74 65 72 2d  OsUnfetch(pIter-
2df0: 3e 70 46 69 6c 65 2c 20 30 2c 20 70 49 74 65 72  >pFile, 0, pIter
2e00: 2d 3e 61 4d 61 70 29 3b 0a 20 20 6d 65 6d 73 65  ->aMap);.  memse
2e10: 74 28 70 49 74 65 72 2c 20 30 2c 20 73 69 7a 65  t(pIter, 0, size
2e20: 6f 66 28 56 64 62 65 53 6f 72 74 65 72 49 74 65  of(VdbeSorterIte
2e30: 72 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  r));.}../*.** Re
2e40: 61 64 20 6e 42 79 74 65 20 62 79 74 65 73 20 6f  ad nByte bytes o
2e50: 66 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20  f data from the 
2e60: 73 74 72 65 61 6d 20 6f 66 20 64 61 74 61 20 69  stream of data i
2e70: 74 65 72 61 74 65 64 20 62 79 20 6f 62 6a 65 63  terated by objec
2e80: 74 20 70 2e 0a 2a 2a 20 49 66 20 73 75 63 63 65  t p..** If succe
2e90: 73 73 66 75 6c 2c 20 73 65 74 20 2a 70 70 4f 75  ssful, set *ppOu
2ea0: 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 61 20  t to point to a 
2eb0: 62 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e  buffer containin
2ec0: 67 20 74 68 65 20 64 61 74 61 0a 2a 2a 20 61 6e  g the data.** an
2ed0: 64 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  d return SQLITE_
2ee0: 4f 4b 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69  OK. Otherwise, i
2ef0: 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
2f00: 73 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c  s, return an SQL
2f10: 69 74 65 0a 2a 2a 20 65 72 72 6f 72 20 63 6f 64  ite.** error cod
2f20: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 62 75 66  e..**.** The buf
2f30: 66 65 72 20 69 6e 64 69 63 61 74 65 64 20 62 79  fer indicated by
2f40: 20 2a 70 70 4f 75 74 20 6d 61 79 20 6f 6e 6c 79   *ppOut may only
2f50: 20 62 65 20 63 6f 6e 73 69 64 65 72 65 64 20 76   be considered v
2f60: 61 6c 69 64 20 75 6e 74 69 6c 20 74 68 65 0a 2a  alid until the.*
2f70: 2a 20 6e 65 78 74 20 63 61 6c 6c 20 74 6f 20 74  * next call to t
2f80: 68 69 73 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f  his function..*/
2f90: 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65  .static int vdbe
2fa0: 53 6f 72 74 65 72 49 74 65 72 52 65 61 64 28 0a  SorterIterRead(.
2fb0: 20 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72    VdbeSorterIter
2fc0: 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20 20   *p,            
2fd0: 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 2a 2f    /* Iterator */
2fe0: 0a 20 20 69 6e 74 20 6e 42 79 74 65 2c 20 20 20  .  int nByte,   
2ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3000: 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 64     /* Bytes of d
3010: 61 74 61 20 74 6f 20 72 65 61 64 20 2a 2f 0a 20  ata to read */. 
3020: 20 75 38 20 2a 2a 70 70 4f 75 74 20 20 20 20 20   u8 **ppOut     
3030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3040: 20 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72   /* OUT: Pointer
3050: 20 74 6f 20 62 75 66 66 65 72 20 63 6f 6e 74 61   to buffer conta
3060: 69 6e 69 6e 67 20 64 61 74 61 20 2a 2f 0a 29 7b  ining data */.){
3070: 0a 20 20 69 6e 74 20 69 42 75 66 3b 20 20 20 20  .  int iBuf;    
3080: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3090: 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 77 69 74     /* Offset wit
30a0: 68 69 6e 20 62 75 66 66 65 72 20 74 6f 20 72 65  hin buffer to re
30b0: 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 6e 74  ad from */.  int
30c0: 20 6e 41 76 61 69 6c 3b 20 20 20 20 20 20 20 20   nAvail;        
30d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
30e0: 42 79 74 65 73 20 6f 66 20 64 61 74 61 20 61 76  Bytes of data av
30f0: 61 69 6c 61 62 6c 65 20 69 6e 20 62 75 66 66 65  ailable in buffe
3100: 72 20 2a 2f 0a 0a 20 20 69 66 28 20 70 2d 3e 61  r */..  if( p->a
3110: 4d 61 70 20 29 7b 0a 20 20 20 20 2a 70 70 4f 75  Map ){.    *ppOu
3120: 74 20 3d 20 26 70 2d 3e 61 4d 61 70 5b 70 2d 3e  t = &p->aMap[p->
3130: 69 52 65 61 64 4f 66 66 5d 3b 0a 20 20 20 20 70  iReadOff];.    p
3140: 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e 42  ->iReadOff += nB
3150: 79 74 65 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  yte;.    return 
3160: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a  SQLITE_OK;.  }..
3170: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61 42 75    assert( p->aBu
3180: 66 66 65 72 20 29 3b 0a 0a 20 20 2f 2a 20 49 66  ffer );..  /* If
3190: 20 74 68 65 72 65 20 69 73 20 6e 6f 20 6d 6f 72   there is no mor
31a0: 65 20 64 61 74 61 20 74 6f 20 62 65 20 72 65 61  e data to be rea
31b0: 64 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66 65  d from the buffe
31c0: 72 2c 20 72 65 61 64 20 74 68 65 20 6e 65 78 74  r, read the next
31d0: 20 0a 20 20 2a 2a 20 70 2d 3e 6e 42 75 66 66 65   .  ** p->nBuffe
31e0: 72 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20  r bytes of data 
31f0: 66 72 6f 6d 20 74 68 65 20 66 69 6c 65 20 69 6e  from the file in
3200: 74 6f 20 69 74 2e 20 4f 72 2c 20 69 66 20 74 68  to it. Or, if th
3210: 65 72 65 20 61 72 65 20 6c 65 73 73 0a 20 20 2a  ere are less.  *
3220: 2a 20 74 68 61 6e 20 70 2d 3e 6e 42 75 66 66 65  * than p->nBuffe
3230: 72 20 62 79 74 65 73 20 72 65 6d 61 69 6e 69 6e  r bytes remainin
3240: 67 20 69 6e 20 74 68 65 20 50 4d 41 2c 20 72 65  g in the PMA, re
3250: 61 64 20 61 6c 6c 20 72 65 6d 61 69 6e 69 6e 67  ad all remaining
3260: 20 64 61 74 61 2e 20 20 2a 2f 0a 20 20 69 42 75   data.  */.  iBu
3270: 66 20 3d 20 70 2d 3e 69 52 65 61 64 4f 66 66 20  f = p->iReadOff 
3280: 25 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20  % p->nBuffer;.  
3290: 69 66 28 20 69 42 75 66 3d 3d 30 20 29 7b 0a 20  if( iBuf==0 ){. 
32a0: 20 20 20 69 6e 74 20 6e 52 65 61 64 3b 20 20 20     int nRead;   
32b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
32c0: 20 2f 2a 20 42 79 74 65 73 20 74 6f 20 72 65 61   /* Bytes to rea
32d0: 64 20 66 72 6f 6d 20 64 69 73 6b 20 2a 2f 0a 20  d from disk */. 
32e0: 20 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20     int rc;      
32f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3300: 20 2f 2a 20 73 71 6c 69 74 65 33 4f 73 52 65 61   /* sqlite3OsRea
3310: 64 28 29 20 72 65 74 75 72 6e 20 63 6f 64 65 20  d() return code 
3320: 2a 2f 0a 0a 20 20 20 20 2f 2a 20 44 65 74 65 72  */..    /* Deter
3330: 6d 69 6e 65 20 68 6f 77 20 6d 61 6e 79 20 62 79  mine how many by
3340: 74 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 72  tes of data to r
3350: 65 61 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20  ead. */.    if( 
3360: 28 70 2d 3e 69 45 6f 66 20 2d 20 70 2d 3e 69 52  (p->iEof - p->iR
3370: 65 61 64 4f 66 66 29 20 3e 20 28 69 36 34 29 70  eadOff) > (i64)p
3380: 2d 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20  ->nBuffer ){.   
3390: 20 20 20 6e 52 65 61 64 20 3d 20 70 2d 3e 6e 42     nRead = p->nB
33a0: 75 66 66 65 72 3b 0a 20 20 20 20 7d 65 6c 73 65  uffer;.    }else
33b0: 7b 0a 20 20 20 20 20 20 6e 52 65 61 64 20 3d 20  {.      nRead = 
33c0: 28 69 6e 74 29 28 70 2d 3e 69 45 6f 66 20 2d 20  (int)(p->iEof - 
33d0: 70 2d 3e 69 52 65 61 64 4f 66 66 29 3b 0a 20 20  p->iReadOff);.  
33e0: 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20    }.    assert( 
33f0: 6e 52 65 61 64 3e 30 20 29 3b 0a 0a 20 20 20 20  nRead>0 );..    
3400: 2f 2a 20 52 65 61 64 20 64 61 74 61 20 66 72 6f  /* Read data fro
3410: 6d 20 74 68 65 20 66 69 6c 65 2e 20 52 65 74 75  m the file. Retu
3420: 72 6e 20 65 61 72 6c 79 20 69 66 20 61 6e 20 65  rn early if an e
3430: 72 72 6f 72 20 6f 63 63 75 72 73 2e 20 2a 2f 0a  rror occurs. */.
3440: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
3450: 4f 73 52 65 61 64 28 70 2d 3e 70 46 69 6c 65 2c  OsRead(p->pFile,
3460: 20 70 2d 3e 61 42 75 66 66 65 72 2c 20 6e 52 65   p->aBuffer, nRe
3470: 61 64 2c 20 70 2d 3e 69 52 65 61 64 4f 66 66 29  ad, p->iReadOff)
3480: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 72 63  ;.    assert( rc
3490: 21 3d 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f 53  !=SQLITE_IOERR_S
34a0: 48 4f 52 54 5f 52 45 41 44 20 29 3b 0a 20 20 20  HORT_READ );.   
34b0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
34c0: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
34d0: 20 20 7d 0a 20 20 6e 41 76 61 69 6c 20 3d 20 70    }.  nAvail = p
34e0: 2d 3e 6e 42 75 66 66 65 72 20 2d 20 69 42 75 66  ->nBuffer - iBuf
34f0: 3b 20 0a 0a 20 20 69 66 28 20 6e 42 79 74 65 3c  ; ..  if( nByte<
3500: 3d 6e 41 76 61 69 6c 20 29 7b 0a 20 20 20 20 2f  =nAvail ){.    /
3510: 2a 20 54 68 65 20 72 65 71 75 65 73 74 65 64 20  * The requested 
3520: 64 61 74 61 20 69 73 20 61 76 61 69 6c 61 62 6c  data is availabl
3530: 65 20 69 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f  e in the in-memo
3540: 72 79 20 62 75 66 66 65 72 2e 20 49 6e 20 74 68  ry buffer. In th
3550: 69 73 0a 20 20 20 20 2a 2a 20 63 61 73 65 20 74  is.    ** case t
3560: 68 65 72 65 20 69 73 20 6e 6f 20 6e 65 65 64 20  here is no need 
3570: 74 6f 20 6d 61 6b 65 20 61 20 63 6f 70 79 20 6f  to make a copy o
3580: 66 20 74 68 65 20 64 61 74 61 2c 20 6a 75 73 74  f the data, just
3590: 20 72 65 74 75 72 6e 20 61 20 0a 20 20 20 20 2a   return a .    *
35a0: 2a 20 70 6f 69 6e 74 65 72 20 69 6e 74 6f 20 74  * pointer into t
35b0: 68 65 20 62 75 66 66 65 72 20 74 6f 20 74 68 65  he buffer to the
35c0: 20 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a 20 20 20   caller.  */.   
35d0: 20 2a 70 70 4f 75 74 20 3d 20 26 70 2d 3e 61 42   *ppOut = &p->aB
35e0: 75 66 66 65 72 5b 69 42 75 66 5d 3b 0a 20 20 20  uffer[iBuf];.   
35f0: 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20   p->iReadOff += 
3600: 6e 42 79 74 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a  nByte;.  }else{.
3610: 20 20 20 20 2f 2a 20 54 68 65 20 72 65 71 75 65      /* The reque
3620: 73 74 65 64 20 64 61 74 61 20 69 73 20 6e 6f 74  sted data is not
3630: 20 61 6c 6c 20 61 76 61 69 6c 61 62 6c 65 20 69   all available i
3640: 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20  n the in-memory 
3650: 62 75 66 66 65 72 2e 0a 20 20 20 20 2a 2a 20 49  buffer..    ** I
3660: 6e 20 74 68 69 73 20 63 61 73 65 2c 20 61 6c 6c  n this case, all
3670: 6f 63 61 74 65 20 73 70 61 63 65 20 61 74 20 70  ocate space at p
3680: 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 74 6f 20 63 6f  ->aAlloc[] to co
3690: 70 79 20 74 68 65 20 72 65 71 75 65 73 74 65 64  py the requested
36a0: 0a 20 20 20 20 2a 2a 20 72 61 6e 67 65 20 69 6e  .    ** range in
36b0: 74 6f 2e 20 54 68 65 6e 20 72 65 74 75 72 6e 20  to. Then return 
36c0: 61 20 63 6f 70 79 20 6f 66 20 70 6f 69 6e 74 65  a copy of pointe
36d0: 72 20 70 2d 3e 61 41 6c 6c 6f 63 20 74 6f 20 74  r p->aAlloc to t
36e0: 68 65 20 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a 20  he caller.  */. 
36f0: 20 20 20 69 6e 74 20 6e 52 65 6d 3b 20 20 20 20     int nRem;    
3700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3710: 20 2f 2a 20 42 79 74 65 73 20 72 65 6d 61 69 6e   /* Bytes remain
3720: 69 6e 67 20 74 6f 20 63 6f 70 79 20 2a 2f 0a 0a  ing to copy */..
3730: 20 20 20 20 2f 2a 20 45 78 74 65 6e 64 20 74 68      /* Extend th
3740: 65 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 61 6c  e p->aAlloc[] al
3750: 6c 6f 63 61 74 69 6f 6e 20 69 66 20 72 65 71 75  location if requ
3760: 69 72 65 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28  ired. */.    if(
3770: 20 70 2d 3e 6e 41 6c 6c 6f 63 3c 6e 42 79 74 65   p->nAlloc<nByte
3780: 20 29 7b 0a 20 20 20 20 20 20 75 38 20 2a 61 4e   ){.      u8 *aN
3790: 65 77 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e  ew;.      int nN
37a0: 65 77 20 3d 20 70 2d 3e 6e 41 6c 6c 6f 63 2a 32  ew = p->nAlloc*2
37b0: 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 6e  ;.      while( n
37c0: 42 79 74 65 3e 6e 4e 65 77 20 29 20 6e 4e 65 77  Byte>nNew ) nNew
37d0: 20 3d 20 6e 4e 65 77 2a 32 3b 0a 20 20 20 20 20   = nNew*2;.     
37e0: 20 61 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 52   aNew = sqlite3R
37f0: 65 61 6c 6c 6f 63 28 70 2d 3e 61 41 6c 6c 6f 63  ealloc(p->aAlloc
3800: 2c 20 6e 4e 65 77 29 3b 0a 20 20 20 20 20 20 69  , nNew);.      i
3810: 66 28 20 21 61 4e 65 77 20 29 20 72 65 74 75 72  f( !aNew ) retur
3820: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
3830: 20 20 20 20 20 20 70 2d 3e 6e 41 6c 6c 6f 63 20        p->nAlloc 
3840: 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 70 2d  = nNew;.      p-
3850: 3e 61 41 6c 6c 6f 63 20 3d 20 61 4e 65 77 3b 0a  >aAlloc = aNew;.
3860: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 43 6f      }..    /* Co
3870: 70 79 20 61 73 20 6d 75 63 68 20 64 61 74 61 20  py as much data 
3880: 61 73 20 69 73 20 61 76 61 69 6c 61 62 6c 65 20  as is available 
3890: 69 6e 20 74 68 65 20 62 75 66 66 65 72 20 69 6e  in the buffer in
38a0: 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 0a  to the start of.
38b0: 20 20 20 20 2a 2a 20 70 2d 3e 61 41 6c 6c 6f 63      ** p->aAlloc
38c0: 5b 5d 2e 20 20 2a 2f 0a 20 20 20 20 6d 65 6d 63  [].  */.    memc
38d0: 70 79 28 70 2d 3e 61 41 6c 6c 6f 63 2c 20 26 70  py(p->aAlloc, &p
38e0: 2d 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d 2c  ->aBuffer[iBuf],
38f0: 20 6e 41 76 61 69 6c 29 3b 0a 20 20 20 20 70 2d   nAvail);.    p-
3900: 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e 41 76  >iReadOff += nAv
3910: 61 69 6c 3b 0a 20 20 20 20 6e 52 65 6d 20 3d 20  ail;.    nRem = 
3920: 6e 42 79 74 65 20 2d 20 6e 41 76 61 69 6c 3b 0a  nByte - nAvail;.
3930: 0a 20 20 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c  .    /* The foll
3940: 6f 77 69 6e 67 20 6c 6f 6f 70 20 63 6f 70 69 65  owing loop copie
3950: 73 20 75 70 20 74 6f 20 70 2d 3e 6e 42 75 66 66  s up to p->nBuff
3960: 65 72 20 62 79 74 65 73 20 70 65 72 20 69 74 65  er bytes per ite
3970: 72 61 74 69 6f 6e 20 69 6e 74 6f 0a 20 20 20 20  ration into.    
3980: 2a 2a 20 74 68 65 20 70 2d 3e 61 41 6c 6c 6f 63  ** the p->aAlloc
3990: 5b 5d 20 62 75 66 66 65 72 2e 20 20 2a 2f 0a 20  [] buffer.  */. 
39a0: 20 20 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30     while( nRem>0
39b0: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72 63   ){.      int rc
39c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
39d0: 20 20 20 20 20 20 2f 2a 20 76 64 62 65 53 6f 72        /* vdbeSor
39e0: 74 65 72 49 74 65 72 52 65 61 64 28 29 20 72 65  terIterRead() re
39f0: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 20  turn code */.   
3a00: 20 20 20 69 6e 74 20 6e 43 6f 70 79 3b 20 20 20     int nCopy;   
3a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3a20: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  * Number of byte
3a30: 73 20 74 6f 20 63 6f 70 79 20 2a 2f 0a 20 20 20  s to copy */.   
3a40: 20 20 20 75 38 20 2a 61 4e 65 78 74 3b 20 20 20     u8 *aNext;   
3a50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3a60: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 62 75 66  * Pointer to buf
3a70: 66 65 72 20 74 6f 20 63 6f 70 79 20 64 61 74 61  fer to copy data
3a80: 20 66 72 6f 6d 20 2a 2f 0a 0a 20 20 20 20 20 20   from */..      
3a90: 6e 43 6f 70 79 20 3d 20 6e 52 65 6d 3b 0a 20 20  nCopy = nRem;.  
3aa0: 20 20 20 20 69 66 28 20 6e 52 65 6d 3e 70 2d 3e      if( nRem>p->
3ab0: 6e 42 75 66 66 65 72 20 29 20 6e 43 6f 70 79 20  nBuffer ) nCopy 
3ac0: 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20  = p->nBuffer;.  
3ad0: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
3ae0: 74 65 72 49 74 65 72 52 65 61 64 28 70 2c 20 6e  terIterRead(p, n
3af0: 43 6f 70 79 2c 20 26 61 4e 65 78 74 29 3b 0a 20  Copy, &aNext);. 
3b00: 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c       if( rc!=SQL
3b10: 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
3b20: 72 63 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74  rc;.      assert
3b30: 28 20 61 4e 65 78 74 21 3d 70 2d 3e 61 41 6c 6c  ( aNext!=p->aAll
3b40: 6f 63 20 29 3b 0a 20 20 20 20 20 20 6d 65 6d 63  oc );.      memc
3b50: 70 79 28 26 70 2d 3e 61 41 6c 6c 6f 63 5b 6e 42  py(&p->aAlloc[nB
3b60: 79 74 65 20 2d 20 6e 52 65 6d 5d 2c 20 61 4e 65  yte - nRem], aNe
3b70: 78 74 2c 20 6e 43 6f 70 79 29 3b 0a 20 20 20 20  xt, nCopy);.    
3b80: 20 20 6e 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b    nRem -= nCopy;
3b90: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2a 70 70 4f  .    }..    *ppO
3ba0: 75 74 20 3d 20 70 2d 3e 61 41 6c 6c 6f 63 3b 0a  ut = p->aAlloc;.
3bb0: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51    }..  return SQ
3bc0: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  LITE_OK;.}../*.*
3bd0: 2a 20 52 65 61 64 20 61 20 76 61 72 69 6e 74 20  * Read a varint 
3be0: 66 72 6f 6d 20 74 68 65 20 73 74 72 65 61 6d 20  from the stream 
3bf0: 6f 66 20 64 61 74 61 20 61 63 63 65 73 73 65 64  of data accessed
3c00: 20 62 79 20 70 2e 20 53 65 74 20 2a 70 6e 4f 75   by p. Set *pnOu
3c10: 74 20 74 6f 0a 2a 2a 20 74 68 65 20 76 61 6c 75  t to.** the valu
3c20: 65 20 72 65 61 64 2e 0a 2a 2f 0a 73 74 61 74 69  e read..*/.stati
3c30: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72  c int vdbeSorter
3c40: 49 74 65 72 56 61 72 69 6e 74 28 56 64 62 65 53  IterVarint(VdbeS
3c50: 6f 72 74 65 72 49 74 65 72 20 2a 70 2c 20 75 36  orterIter *p, u6
3c60: 34 20 2a 70 6e 4f 75 74 29 7b 0a 20 20 69 6e 74  4 *pnOut){.  int
3c70: 20 69 42 75 66 3b 0a 0a 20 20 69 66 28 20 70 2d   iBuf;..  if( p-
3c80: 3e 61 4d 61 70 20 29 7b 0a 20 20 20 20 70 2d 3e  >aMap ){.    p->
3c90: 69 52 65 61 64 4f 66 66 20 2b 3d 20 73 71 6c 69  iReadOff += sqli
3ca0: 74 65 33 47 65 74 56 61 72 69 6e 74 28 26 70 2d  te3GetVarint(&p-
3cb0: 3e 61 4d 61 70 5b 70 2d 3e 69 52 65 61 64 4f 66  >aMap[p->iReadOf
3cc0: 66 5d 2c 20 70 6e 4f 75 74 29 3b 0a 20 20 7d 65  f], pnOut);.  }e
3cd0: 6c 73 65 7b 0a 20 20 20 20 69 42 75 66 20 3d 20  lse{.    iBuf = 
3ce0: 70 2d 3e 69 52 65 61 64 4f 66 66 20 25 20 70 2d  p->iReadOff % p-
3cf0: 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20 20 69 66  >nBuffer;.    if
3d00: 28 20 69 42 75 66 20 26 26 20 28 70 2d 3e 6e 42  ( iBuf && (p->nB
3d10: 75 66 66 65 72 2d 69 42 75 66 29 3e 3d 39 20 29  uffer-iBuf)>=9 )
3d20: 7b 0a 20 20 20 20 20 20 70 2d 3e 69 52 65 61 64  {.      p->iRead
3d30: 4f 66 66 20 2b 3d 20 73 71 6c 69 74 65 33 47 65  Off += sqlite3Ge
3d40: 74 56 61 72 69 6e 74 28 26 70 2d 3e 61 42 75 66  tVarint(&p->aBuf
3d50: 66 65 72 5b 69 42 75 66 5d 2c 20 70 6e 4f 75 74  fer[iBuf], pnOut
3d60: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
3d70: 20 20 20 20 75 38 20 61 56 61 72 69 6e 74 5b 31      u8 aVarint[1
3d80: 36 5d 2c 20 2a 61 3b 0a 20 20 20 20 20 20 69 6e  6], *a;.      in
3d90: 74 20 69 20 3d 20 30 2c 20 72 63 3b 0a 20 20 20  t i = 0, rc;.   
3da0: 20 20 20 64 6f 7b 0a 20 20 20 20 20 20 20 20 72     do{.        r
3db0: 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 49 74  c = vdbeSorterIt
3dc0: 65 72 52 65 61 64 28 70 2c 20 31 2c 20 26 61 29  erRead(p, 1, &a)
3dd0: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
3de0: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
3df0: 20 20 20 20 20 20 61 56 61 72 69 6e 74 5b 28 69        aVarint[(i
3e00: 2b 2b 29 26 30 78 66 5d 20 3d 20 61 5b 30 5d 3b  ++)&0xf] = a[0];
3e10: 0a 20 20 20 20 20 20 7d 77 68 69 6c 65 28 20 28  .      }while( (
3e20: 61 5b 30 5d 26 30 78 38 30 29 21 3d 30 20 29 3b  a[0]&0x80)!=0 );
3e30: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 47 65  .      sqlite3Ge
3e40: 74 56 61 72 69 6e 74 28 61 56 61 72 69 6e 74 2c  tVarint(aVarint,
3e50: 20 70 6e 4f 75 74 29 3b 0a 20 20 20 20 7d 0a 20   pnOut);.    }. 
3e60: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c   }..  return SQL
3e70: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  ITE_OK;.}.../*.*
3e80: 2a 20 41 64 76 61 6e 63 65 20 69 74 65 72 61 74  * Advance iterat
3e90: 6f 72 20 70 49 74 65 72 20 74 6f 20 74 68 65 20  or pIter to the 
3ea0: 6e 65 78 74 20 6b 65 79 20 69 6e 20 69 74 73 20  next key in its 
3eb0: 50 4d 41 2e 20 52 65 74 75 72 6e 20 53 51 4c 49  PMA. Return SQLI
3ec0: 54 45 5f 4f 4b 20 69 66 0a 2a 2a 20 6e 6f 20 65  TE_OK if.** no e
3ed0: 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 6f 72 20  rror occurs, or 
3ee0: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
3ef0: 63 6f 64 65 20 69 66 20 6f 6e 65 20 64 6f 65 73  code if one does
3f00: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3f10: 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 4e 65  vdbeSorterIterNe
3f20: 78 74 28 56 64 62 65 53 6f 72 74 65 72 49 74 65  xt(VdbeSorterIte
3f30: 72 20 2a 70 49 74 65 72 29 7b 0a 20 20 69 6e 74  r *pIter){.  int
3f40: 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
3f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3f60: 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20  Return Code */. 
3f70: 20 75 36 34 20 6e 52 65 63 20 3d 20 30 3b 20 20   u64 nRec = 0;  
3f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3f90: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 72 65 63 6f   /* Size of reco
3fa0: 72 64 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 0a  rd in bytes */..
3fb0: 20 20 69 66 28 20 70 49 74 65 72 2d 3e 69 52 65    if( pIter->iRe
3fc0: 61 64 4f 66 66 3e 3d 70 49 74 65 72 2d 3e 69 45  adOff>=pIter->iE
3fd0: 6f 66 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 69  of ){.    /* Thi
3fe0: 73 20 69 73 20 61 6e 20 45 4f 46 20 63 6f 6e 64  s is an EOF cond
3ff0: 69 74 69 6f 6e 20 2a 2f 0a 20 20 20 20 76 64 62  ition */.    vdb
4000: 65 53 6f 72 74 65 72 49 74 65 72 5a 65 72 6f 28  eSorterIterZero(
4010: 70 49 74 65 72 29 3b 0a 20 20 20 20 72 65 74 75  pIter);.    retu
4020: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20  rn SQLITE_OK;.  
4030: 7d 0a 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f  }..  rc = vdbeSo
4040: 72 74 65 72 49 74 65 72 56 61 72 69 6e 74 28 70  rterIterVarint(p
4050: 49 74 65 72 2c 20 26 6e 52 65 63 29 3b 0a 20 20  Iter, &nRec);.  
4060: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
4070: 4b 20 29 7b 0a 20 20 20 20 70 49 74 65 72 2d 3e  K ){.    pIter->
4080: 6e 4b 65 79 20 3d 20 28 69 6e 74 29 6e 52 65 63  nKey = (int)nRec
4090: 3b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53  ;.    rc = vdbeS
40a0: 6f 72 74 65 72 49 74 65 72 52 65 61 64 28 70 49  orterIterRead(pI
40b0: 74 65 72 2c 20 28 69 6e 74 29 6e 52 65 63 2c 20  ter, (int)nRec, 
40c0: 26 70 49 74 65 72 2d 3e 61 4b 65 79 29 3b 0a 20  &pIter->aKey);. 
40d0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
40e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61  .}../*.** Initia
40f0: 6c 69 7a 65 20 69 74 65 72 61 74 6f 72 20 70 49  lize iterator pI
4100: 74 65 72 20 74 6f 20 73 63 61 6e 20 74 68 72 6f  ter to scan thro
4110: 75 67 68 20 74 68 65 20 50 4d 41 20 73 74 6f 72  ugh the PMA stor
4120: 65 64 20 69 6e 20 66 69 6c 65 20 70 46 69 6c 65  ed in file pFile
4130: 0a 2a 2a 20 73 74 61 72 74 69 6e 67 20 61 74 20  .** starting at 
4140: 6f 66 66 73 65 74 20 69 53 74 61 72 74 20 61 6e  offset iStart an
4150: 64 20 65 6e 64 69 6e 67 20 61 74 20 6f 66 66 73  d ending at offs
4160: 65 74 20 69 45 6f 66 2d 31 2e 20 54 68 69 73 20  et iEof-1. This 
4170: 66 75 6e 63 74 69 6f 6e 20 0a 2a 2a 20 6c 65 61  function .** lea
4180: 76 65 73 20 74 68 65 20 69 74 65 72 61 74 6f 72  ves the iterator
4190: 20 70 6f 69 6e 74 69 6e 67 20 74 6f 20 74 68 65   pointing to the
41a0: 20 66 69 72 73 74 20 6b 65 79 20 69 6e 20 74 68   first key in th
41b0: 65 20 50 4d 41 20 28 6f 72 20 45 4f 46 20 69 66  e PMA (or EOF if
41c0: 20 74 68 65 20 0a 2a 2a 20 50 4d 41 20 69 73 20   the .** PMA is 
41d0: 65 6d 70 74 79 29 2e 0a 2a 2f 0a 73 74 61 74 69  empty)..*/.stati
41e0: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72  c int vdbeSorter
41f0: 49 74 65 72 49 6e 69 74 28 0a 20 20 53 6f 72 74  IterInit(.  Sort
4200: 65 72 54 68 72 65 61 64 20 2a 70 54 68 72 65 61  erThread *pThrea
4210: 64 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54  d,          /* T
4220: 68 72 65 61 64 20 63 6f 6e 74 65 78 74 20 2a 2f  hread context */
4230: 0a 20 20 69 36 34 20 69 53 74 61 72 74 2c 20 20  .  i64 iStart,  
4240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4250: 20 20 20 2f 2a 20 53 74 61 72 74 20 6f 66 66 73     /* Start offs
4260: 65 74 20 69 6e 20 70 54 68 72 65 61 64 2d 3e 70  et in pThread->p
4270: 54 65 6d 70 31 20 2a 2f 0a 20 20 56 64 62 65 53  Temp1 */.  VdbeS
4280: 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74 65 72  orterIter *pIter
4290: 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 74  ,          /* It
42a0: 65 72 61 74 6f 72 20 74 6f 20 70 6f 70 75 6c 61  erator to popula
42b0: 74 65 20 2a 2f 0a 20 20 69 36 34 20 2a 70 6e 42  te */.  i64 *pnB
42c0: 79 74 65 20 20 20 20 20 20 20 20 20 20 20 20 20  yte             
42d0: 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55          /* IN/OU
42e0: 54 3a 20 49 6e 63 72 65 6d 65 6e 74 20 74 68 69  T: Increment thi
42f0: 73 20 76 61 6c 75 65 20 62 79 20 50 4d 41 20 73  s value by PMA s
4300: 69 7a 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  ize */.){.  int 
4310: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
4320: 20 20 69 6e 74 20 6e 42 75 66 20 3d 20 70 54 68    int nBuf = pTh
4330: 72 65 61 64 2d 3e 70 67 73 7a 3b 0a 20 20 76 6f  read->pgsz;.  vo
4340: 69 64 20 2a 70 4d 61 70 20 3d 20 30 3b 20 20 20  id *pMap = 0;   
4350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4360: 20 4d 61 70 70 69 6e 67 20 6f 66 20 74 65 6d 70   Mapping of temp
4370: 20 66 69 6c 65 20 2a 2f 0a 0a 20 20 61 73 73 65   file */..  asse
4380: 72 74 28 20 70 54 68 72 65 61 64 2d 3e 69 54 65  rt( pThread->iTe
4390: 6d 70 31 4f 66 66 3e 69 53 74 61 72 74 20 29 3b  mp1Off>iStart );
43a0: 0a 20 20 61 73 73 65 72 74 28 20 70 49 74 65 72  .  assert( pIter
43b0: 2d 3e 61 41 6c 6c 6f 63 3d 3d 30 20 29 3b 0a 20  ->aAlloc==0 );. 
43c0: 20 61 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e   assert( pIter->
43d0: 61 42 75 66 66 65 72 3d 3d 30 20 29 3b 0a 20 20  aBuffer==0 );.  
43e0: 70 49 74 65 72 2d 3e 70 46 69 6c 65 20 3d 20 70  pIter->pFile = p
43f0: 54 68 72 65 61 64 2d 3e 70 54 65 6d 70 31 3b 0a  Thread->pTemp1;.
4400: 20 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66    pIter->iReadOf
4410: 66 20 3d 20 69 53 74 61 72 74 3b 0a 20 20 70 49  f = iStart;.  pI
4420: 74 65 72 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 31 32  ter->nAlloc = 12
4430: 38 3b 0a 20 20 70 49 74 65 72 2d 3e 61 41 6c 6c  8;.  pIter->aAll
4440: 6f 63 20 3d 20 28 75 38 2a 29 73 71 6c 69 74 65  oc = (u8*)sqlite
4450: 33 4d 61 6c 6c 6f 63 28 70 49 74 65 72 2d 3e 6e  3Malloc(pIter->n
4460: 41 6c 6c 6f 63 29 3b 0a 0a 20 20 2f 2a 20 54 72  Alloc);..  /* Tr
4470: 79 20 74 6f 20 78 46 65 74 63 68 28 29 20 61 20  y to xFetch() a 
4480: 6d 61 70 70 69 6e 67 20 6f 66 20 74 68 65 20 65  mapping of the e
4490: 6e 74 69 72 65 20 74 65 6d 70 20 66 69 6c 65 2e  ntire temp file.
44a0: 20 49 66 20 74 68 69 73 20 69 73 20 70 6f 73 73   If this is poss
44b0: 69 62 6c 65 2c 0a 20 20 2a 2a 20 74 68 65 20 50  ible,.  ** the P
44c0: 4d 41 20 77 69 6c 6c 20 62 65 20 72 65 61 64 20  MA will be read 
44d0: 76 69 61 20 74 68 65 20 6d 61 70 70 69 6e 67 2e  via the mapping.
44e0: 20 4f 74 68 65 72 77 69 73 65 2c 20 75 73 65 20   Otherwise, use 
44f0: 78 52 65 61 64 28 29 2e 20 20 2a 2f 0a 20 20 72  xRead().  */.  r
4500: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 46 65 74  c = sqlite3OsFet
4510: 63 68 28 70 49 74 65 72 2d 3e 70 46 69 6c 65 2c  ch(pIter->pFile,
4520: 20 30 2c 20 70 54 68 72 65 61 64 2d 3e 69 54 65   0, pThread->iTe
4530: 6d 70 31 4f 66 66 2c 20 26 70 4d 61 70 29 3b 0a  mp1Off, &pMap);.
4540: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
4550: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 66 28 20  E_OK ){.    if( 
4560: 70 4d 61 70 20 29 7b 0a 20 20 20 20 20 20 70 49  pMap ){.      pI
4570: 74 65 72 2d 3e 61 4d 61 70 20 3d 20 28 75 38 2a  ter->aMap = (u8*
4580: 29 70 4d 61 70 3b 0a 20 20 20 20 7d 65 6c 73 65  )pMap;.    }else
4590: 7b 0a 20 20 20 20 20 20 70 49 74 65 72 2d 3e 6e  {.      pIter->n
45a0: 42 75 66 66 65 72 20 3d 20 6e 42 75 66 3b 0a 20  Buffer = nBuf;. 
45b0: 20 20 20 20 20 70 49 74 65 72 2d 3e 61 42 75 66       pIter->aBuf
45c0: 66 65 72 20 3d 20 28 75 38 2a 29 73 71 6c 69 74  fer = (u8*)sqlit
45d0: 65 33 4d 61 6c 6c 6f 63 28 6e 42 75 66 29 3b 0a  e3Malloc(nBuf);.
45e0: 20 20 20 20 20 20 69 66 28 20 21 70 49 74 65 72        if( !pIter
45f0: 2d 3e 61 42 75 66 66 65 72 20 29 7b 0a 20 20 20  ->aBuffer ){.   
4600: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
4610: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 7d 65  _NOMEM;.      }e
4620: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69 6e 74  lse{.        int
4630: 20 69 42 75 66 20 3d 20 69 53 74 61 72 74 20 25   iBuf = iStart %
4640: 20 6e 42 75 66 3b 0a 20 20 20 20 20 20 20 20 69   nBuf;.        i
4650: 66 28 20 69 42 75 66 20 29 7b 0a 20 20 20 20 20  f( iBuf ){.     
4660: 20 20 20 20 20 69 6e 74 20 6e 52 65 61 64 20 3d       int nRead =
4670: 20 6e 42 75 66 20 2d 20 69 42 75 66 3b 0a 20 20   nBuf - iBuf;.  
4680: 20 20 20 20 20 20 20 20 69 66 28 20 28 69 53 74          if( (iSt
4690: 61 72 74 20 2b 20 6e 52 65 61 64 29 20 3e 20 70  art + nRead) > p
46a0: 54 68 72 65 61 64 2d 3e 69 54 65 6d 70 31 4f 66  Thread->iTemp1Of
46b0: 66 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  f ){.           
46c0: 20 6e 52 65 61 64 20 3d 20 28 69 6e 74 29 28 70   nRead = (int)(p
46d0: 54 68 72 65 61 64 2d 3e 69 54 65 6d 70 31 4f 66  Thread->iTemp1Of
46e0: 66 20 2d 20 69 53 74 61 72 74 29 3b 0a 20 20 20  f - iStart);.   
46f0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
4700: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
4710: 73 52 65 61 64 28 0a 20 20 20 20 20 20 20 20 20  sRead(.         
4720: 20 20 20 20 20 70 54 68 72 65 61 64 2d 3e 70 54       pThread->pT
4730: 65 6d 70 31 2c 20 26 70 49 74 65 72 2d 3e 61 42  emp1, &pIter->aB
4740: 75 66 66 65 72 5b 69 42 75 66 5d 2c 20 6e 52 65  uffer[iBuf], nRe
4750: 61 64 2c 20 69 53 74 61 72 74 0a 20 20 20 20 20  ad, iStart.     
4760: 20 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20           );.    
4770: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 72 63        assert( rc
4780: 21 3d 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f 53  !=SQLITE_IOERR_S
4790: 48 4f 52 54 5f 52 45 41 44 20 29 3b 0a 20 20 20  HORT_READ );.   
47a0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
47b0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20     }.  }..  if( 
47c0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
47d0: 0a 20 20 20 20 75 36 34 20 6e 42 79 74 65 3b 20  .    u64 nByte; 
47e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
47f0: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 50 4d     /* Size of PM
4800: 41 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  A in bytes */.  
4810: 20 20 70 49 74 65 72 2d 3e 69 45 6f 66 20 3d 20    pIter->iEof = 
4820: 70 54 68 72 65 61 64 2d 3e 69 54 65 6d 70 31 4f  pThread->iTemp1O
4830: 66 66 3b 0a 20 20 20 20 72 63 20 3d 20 76 64 62  ff;.    rc = vdb
4840: 65 53 6f 72 74 65 72 49 74 65 72 56 61 72 69 6e  eSorterIterVarin
4850: 74 28 70 49 74 65 72 2c 20 26 6e 42 79 74 65 29  t(pIter, &nByte)
4860: 3b 0a 20 20 20 20 70 49 74 65 72 2d 3e 69 45 6f  ;.    pIter->iEo
4870: 66 20 3d 20 70 49 74 65 72 2d 3e 69 52 65 61 64  f = pIter->iRead
4880: 4f 66 66 20 2b 20 6e 42 79 74 65 3b 0a 20 20 20  Off + nByte;.   
4890: 20 2a 70 6e 42 79 74 65 20 2b 3d 20 6e 42 79 74   *pnByte += nByt
48a0: 65 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63  e;.  }..  if( rc
48b0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
48c0: 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74     rc = vdbeSort
48d0: 65 72 49 74 65 72 4e 65 78 74 28 70 49 74 65 72  erIterNext(pIter
48e0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
48f0: 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6f  rc;.}.../*.** Co
4900: 6d 70 61 72 65 20 6b 65 79 31 20 28 62 75 66 66  mpare key1 (buff
4910: 65 72 20 70 4b 65 79 31 2c 20 73 69 7a 65 20 6e  er pKey1, size n
4920: 4b 65 79 31 20 62 79 74 65 73 29 20 77 69 74 68  Key1 bytes) with
4930: 20 6b 65 79 32 20 28 62 75 66 66 65 72 20 70 4b   key2 (buffer pK
4940: 65 79 32 2c 20 0a 2a 2a 20 73 69 7a 65 20 6e 4b  ey2, .** size nK
4950: 65 79 32 20 62 79 74 65 73 29 2e 20 55 73 65 20  ey2 bytes). Use 
4960: 28 70 54 68 72 65 61 64 2d 3e 70 4b 65 79 49 6e  (pThread->pKeyIn
4970: 66 6f 29 20 66 6f 72 20 74 68 65 20 63 6f 6c 6c  fo) for the coll
4980: 61 74 69 6f 6e 20 73 65 71 75 65 6e 63 65 73 0a  ation sequences.
4990: 2a 2a 20 75 73 65 64 20 62 79 20 74 68 65 20 63  ** used by the c
49a0: 6f 6d 70 61 72 69 73 6f 6e 2e 20 52 65 74 75 72  omparison. Retur
49b0: 6e 20 74 68 65 20 72 65 73 75 6c 74 20 6f 66 20  n the result of 
49c0: 74 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2e 0a  the comparison..
49d0: 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65 20 72 65 74  **.** Before ret
49e0: 75 72 6e 69 6e 67 2c 20 6f 62 6a 65 63 74 20 28  urning, object (
49f0: 70 54 68 72 65 61 64 2d 3e 70 55 6e 70 61 63 6b  pThread->pUnpack
4a00: 65 64 29 20 69 73 20 70 6f 70 75 6c 61 74 65 64  ed) is populated
4a10: 20 77 69 74 68 20 74 68 65 0a 2a 2a 20 75 6e 70   with the.** unp
4a20: 61 63 6b 65 64 20 76 65 72 73 69 6f 6e 20 6f 66  acked version of
4a30: 20 6b 65 79 32 2e 20 4f 72 2c 20 69 66 20 70 4b   key2. Or, if pK
4a40: 65 79 32 20 69 73 20 70 61 73 73 65 64 20 61 20  ey2 is passed a 
4a50: 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2c 20 74 68  NULL pointer, th
4a60: 65 6e 20 69 74 20 0a 2a 2a 20 69 73 20 61 73 73  en it .** is ass
4a70: 75 6d 65 64 20 74 68 61 74 20 74 68 65 20 28 70  umed that the (p
4a80: 54 68 72 65 61 64 2d 3e 70 55 6e 70 61 63 6b 65  Thread->pUnpacke
4a90: 64 29 20 73 74 72 75 63 74 75 72 65 20 61 6c 72  d) structure alr
4aa0: 65 61 64 79 20 63 6f 6e 74 61 69 6e 73 20 74 68  eady contains th
4ab0: 65 20 0a 2a 2a 20 75 6e 70 61 63 6b 65 64 20 6b  e .** unpacked k
4ac0: 65 79 20 74 6f 20 75 73 65 20 61 73 20 6b 65 79  ey to use as key
4ad0: 32 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 4f  2..**.** If an O
4ae0: 4f 4d 20 65 72 72 6f 72 20 69 73 20 65 6e 63 6f  OM error is enco
4af0: 75 6e 74 65 72 65 64 2c 20 28 70 54 68 72 65 61  untered, (pThrea
4b00: 64 2d 3e 70 55 6e 70 61 63 6b 65 64 2d 3e 65 72  d->pUnpacked->er
4b10: 72 6f 72 5f 72 63 29 20 69 73 20 73 65 74 0a 2a  ror_rc) is set.*
4b20: 2a 20 74 6f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  * to SQLITE_NOME
4b30: 4d 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  M..*/.static int
4b40: 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61   vdbeSorterCompa
4b50: 72 65 28 0a 20 20 53 6f 72 74 65 72 54 68 72 65  re(.  SorterThre
4b60: 61 64 20 2a 70 54 68 72 65 61 64 2c 20 20 20 20  ad *pThread,    
4b70: 20 20 20 20 20 20 2f 2a 20 54 68 72 65 61 64 20        /* Thread 
4b80: 63 6f 6e 74 65 78 74 20 28 66 6f 72 20 70 4b 65  context (for pKe
4b90: 79 49 6e 66 6f 29 20 2a 2f 0a 20 20 63 6f 6e 73  yInfo) */.  cons
4ba0: 74 20 76 6f 69 64 20 2a 70 4b 65 79 31 2c 20 69  t void *pKey1, i
4bb0: 6e 74 20 6e 4b 65 79 31 2c 20 20 20 2f 2a 20 4c  nt nKey1,   /* L
4bc0: 65 66 74 20 73 69 64 65 20 6f 66 20 63 6f 6d 70  eft side of comp
4bd0: 61 72 69 73 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73  arison */.  cons
4be0: 74 20 76 6f 69 64 20 2a 70 4b 65 79 32 2c 20 69  t void *pKey2, i
4bf0: 6e 74 20 6e 4b 65 79 32 20 20 20 20 2f 2a 20 52  nt nKey2    /* R
4c00: 69 67 68 74 20 73 69 64 65 20 6f 66 20 63 6f 6d  ight side of com
4c10: 70 61 72 69 73 6f 6e 20 2a 2f 0a 29 7b 0a 20 20  parison */.){.  
4c20: 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20 2a  UnpackedRecord *
4c30: 72 32 20 3d 20 70 54 68 72 65 61 64 2d 3e 70 55  r2 = pThread->pU
4c40: 6e 70 61 63 6b 65 64 3b 0a 20 20 69 66 28 20 70  npacked;.  if( p
4c50: 4b 65 79 32 20 29 7b 0a 20 20 20 20 73 71 6c 69  Key2 ){.    sqli
4c60: 74 65 33 56 64 62 65 52 65 63 6f 72 64 55 6e 70  te3VdbeRecordUnp
4c70: 61 63 6b 28 70 54 68 72 65 61 64 2d 3e 70 4b 65  ack(pThread->pKe
4c80: 79 49 6e 66 6f 2c 20 6e 4b 65 79 32 2c 20 70 4b  yInfo, nKey2, pK
4c90: 65 79 32 2c 20 72 32 29 3b 0a 20 20 7d 0a 20 20  ey2, r2);.  }.  
4ca0: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 56 64  return sqlite3Vd
4cb0: 62 65 52 65 63 6f 72 64 43 6f 6d 70 61 72 65 28  beRecordCompare(
4cc0: 6e 4b 65 79 31 2c 20 70 4b 65 79 31 2c 20 72 32  nKey1, pKey1, r2
4cd0: 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  , 0);.}../*.** T
4ce0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
4cf0: 63 61 6c 6c 65 64 20 74 6f 20 63 6f 6d 70 61 72  called to compar
4d00: 65 20 74 77 6f 20 69 74 65 72 61 74 6f 72 20 6b  e two iterator k
4d10: 65 79 73 20 77 68 65 6e 20 6d 65 72 67 69 6e 67  eys when merging
4d20: 20 0a 2a 2a 20 6d 75 6c 74 69 70 6c 65 20 62 2d   .** multiple b-
4d30: 74 72 65 65 20 73 65 67 6d 65 6e 74 73 2e 20 50  tree segments. P
4d40: 61 72 61 6d 65 74 65 72 20 69 4f 75 74 20 69 73  arameter iOut is
4d50: 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68   the index of th
4d60: 65 20 61 54 72 65 65 5b 5d 20 0a 2a 2a 20 76 61  e aTree[] .** va
4d70: 6c 75 65 20 74 6f 20 72 65 63 61 6c 63 75 6c 61  lue to recalcula
4d80: 74 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  te..*/.static in
4d90: 74 20 76 64 62 65 53 6f 72 74 65 72 44 6f 43 6f  t vdbeSorterDoCo
4da0: 6d 70 61 72 65 28 0a 20 20 53 6f 72 74 65 72 54  mpare(.  SorterT
4db0: 68 72 65 61 64 20 2a 70 54 68 72 65 61 64 2c 20  hread *pThread, 
4dc0: 0a 20 20 53 6f 72 74 65 72 4d 65 72 67 65 72 20  .  SorterMerger 
4dd0: 2a 70 4d 65 72 67 65 72 2c 20 0a 20 20 69 6e 74  *pMerger, .  int
4de0: 20 69 4f 75 74 0a 29 7b 0a 20 20 69 6e 74 20 69   iOut.){.  int i
4df0: 31 3b 0a 20 20 69 6e 74 20 69 32 3b 0a 20 20 69  1;.  int i2;.  i
4e00: 6e 74 20 69 52 65 73 3b 0a 20 20 56 64 62 65 53  nt iRes;.  VdbeS
4e10: 6f 72 74 65 72 49 74 65 72 20 2a 70 31 3b 0a 20  orterIter *p1;. 
4e20: 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20   VdbeSorterIter 
4e30: 2a 70 32 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  *p2;..  assert( 
4e40: 69 4f 75 74 3c 70 4d 65 72 67 65 72 2d 3e 6e 54  iOut<pMerger->nT
4e50: 72 65 65 20 26 26 20 69 4f 75 74 3e 30 20 29 3b  ree && iOut>0 );
4e60: 0a 0a 20 20 69 66 28 20 69 4f 75 74 3e 3d 28 70  ..  if( iOut>=(p
4e70: 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65 2f 32 29  Merger->nTree/2)
4e80: 20 29 7b 0a 20 20 20 20 69 31 20 3d 20 28 69 4f   ){.    i1 = (iO
4e90: 75 74 20 2d 20 70 4d 65 72 67 65 72 2d 3e 6e 54  ut - pMerger->nT
4ea0: 72 65 65 2f 32 29 20 2a 20 32 3b 0a 20 20 20 20  ree/2) * 2;.    
4eb0: 69 32 20 3d 20 69 31 20 2b 20 31 3b 0a 20 20 7d  i2 = i1 + 1;.  }
4ec0: 65 6c 73 65 7b 0a 20 20 20 20 69 31 20 3d 20 70  else{.    i1 = p
4ed0: 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 4f  Merger->aTree[iO
4ee0: 75 74 2a 32 5d 3b 0a 20 20 20 20 69 32 20 3d 20  ut*2];.    i2 = 
4ef0: 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69  pMerger->aTree[i
4f00: 4f 75 74 2a 32 2b 31 5d 3b 0a 20 20 7d 0a 0a 20  Out*2+1];.  }.. 
4f10: 20 70 31 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e   p1 = &pMerger->
4f20: 61 49 74 65 72 5b 69 31 5d 3b 0a 20 20 70 32 20  aIter[i1];.  p2 
4f30: 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65  = &pMerger->aIte
4f40: 72 5b 69 32 5d 3b 0a 0a 20 20 69 66 28 20 70 31  r[i2];..  if( p1
4f50: 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20  ->pFile==0 ){.  
4f60: 20 20 69 52 65 73 20 3d 20 69 32 3b 0a 20 20 7d    iRes = i2;.  }
4f70: 65 6c 73 65 20 69 66 28 20 70 32 2d 3e 70 46 69  else if( p2->pFi
4f80: 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69 52 65  le==0 ){.    iRe
4f90: 73 20 3d 20 69 31 3b 0a 20 20 7d 65 6c 73 65 7b  s = i1;.  }else{
4fa0: 0a 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 20 20  .    int res;.  
4fb0: 20 20 61 73 73 65 72 74 28 20 70 54 68 72 65 61    assert( pThrea
4fc0: 64 2d 3e 70 55 6e 70 61 63 6b 65 64 21 3d 30 20  d->pUnpacked!=0 
4fd0: 29 3b 20 20 2f 2a 20 61 6c 6c 6f 63 61 74 65 64  );  /* allocated
4fe0: 20 69 6e 20 76 64 62 65 53 6f 72 74 65 72 54 68   in vdbeSorterTh
4ff0: 72 65 61 64 4d 61 69 6e 28 29 20 2a 2f 0a 20 20  readMain() */.  
5000: 20 20 72 65 73 20 3d 20 76 64 62 65 53 6f 72 74    res = vdbeSort
5010: 65 72 43 6f 6d 70 61 72 65 28 0a 20 20 20 20 20  erCompare(.     
5020: 20 20 20 70 54 68 72 65 61 64 2c 20 70 31 2d 3e     pThread, p1->
5030: 61 4b 65 79 2c 20 70 31 2d 3e 6e 4b 65 79 2c 20  aKey, p1->nKey, 
5040: 70 32 2d 3e 61 4b 65 79 2c 20 70 32 2d 3e 6e 4b  p2->aKey, p2->nK
5050: 65 79 0a 20 20 20 20 29 3b 0a 20 20 20 20 69 66  ey.    );.    if
5060: 28 20 72 65 73 3c 3d 30 20 29 7b 0a 20 20 20 20  ( res<=0 ){.    
5070: 20 20 69 52 65 73 20 3d 20 69 31 3b 0a 20 20 20    iRes = i1;.   
5080: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 52   }else{.      iR
5090: 65 73 20 3d 20 69 32 3b 0a 20 20 20 20 7d 0a 20  es = i2;.    }. 
50a0: 20 7d 0a 0a 20 20 70 4d 65 72 67 65 72 2d 3e 61   }..  pMerger->a
50b0: 54 72 65 65 5b 69 4f 75 74 5d 20 3d 20 69 52 65  Tree[iOut] = iRe
50c0: 73 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  s;.  return SQLI
50d0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
50e0: 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 74  Initialize the t
50f0: 65 6d 70 6f 72 61 72 79 20 69 6e 64 65 78 20 63  emporary index c
5100: 75 72 73 6f 72 20 6a 75 73 74 20 6f 70 65 6e 65  ursor just opene
5110: 64 20 61 73 20 61 20 73 6f 72 74 65 72 20 63 75  d as a sorter cu
5120: 72 73 6f 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  rsor..*/.int sql
5130: 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 49 6e  ite3VdbeSorterIn
5140: 69 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  it(sqlite3 *db, 
5150: 69 6e 74 20 6e 46 69 65 6c 64 2c 20 56 64 62 65  int nField, Vdbe
5160: 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20  Cursor *pCsr){. 
5170: 20 69 6e 74 20 70 67 73 7a 3b 20 20 20 20 20 20   int pgsz;      
5180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5190: 20 2f 2a 20 50 61 67 65 20 73 69 7a 65 20 6f 66   /* Page size of
51a0: 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20 2a   main database *
51b0: 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20  /.  int i;      
51c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
51d0: 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69      /* Used to i
51e0: 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 61  terate through a
51f0: 54 68 72 65 61 64 5b 5d 20 2a 2f 0a 20 20 69 6e  Thread[] */.  in
5200: 74 20 6d 78 43 61 63 68 65 3b 20 20 20 20 20 20  t mxCache;      
5210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5220: 20 43 61 63 68 65 20 73 69 7a 65 20 2a 2f 0a 20   Cache size */. 
5230: 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f   VdbeSorter *pSo
5240: 72 74 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  rter;           
5250: 20 2f 2a 20 54 68 65 20 6e 65 77 20 73 6f 72 74   /* The new sort
5260: 65 72 20 2a 2f 0a 20 20 4b 65 79 49 6e 66 6f 20  er */.  KeyInfo 
5270: 2a 70 4b 65 79 49 6e 66 6f 3b 20 20 20 20 20 20  *pKeyInfo;      
5280: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 70 79 20          /* Copy 
5290: 6f 66 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66  of pCsr->pKeyInf
52a0: 6f 20 77 69 74 68 20 64 62 3d 3d 30 20 2a 2f 0a  o with db==0 */.
52b0: 20 20 69 6e 74 20 73 7a 4b 65 79 49 6e 66 6f 3b    int szKeyInfo;
52c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
52d0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 70 43 73    /* Size of pCs
52e0: 72 2d 3e 70 4b 65 79 49 6e 66 6f 20 69 6e 20 62  r->pKeyInfo in b
52f0: 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  ytes */.  int sz
5300: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
5310: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
5320: 65 20 6f 66 20 70 53 6f 72 74 65 72 20 69 6e 20  e of pSorter in 
5330: 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20 72  bytes */.  int r
5340: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
5350: 20 69 6e 74 20 6e 57 6f 72 6b 65 72 20 3d 20 28   int nWorker = (
5360: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
5370: 66 69 67 2e 62 43 6f 72 65 4d 75 74 65 78 3f 73  fig.bCoreMutex?s
5380: 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66  qlite3GlobalConf
5390: 69 67 2e 6e 57 6f 72 6b 65 72 3a 30 29 3b 0a 0a  ig.nWorker:0);..
53a0: 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
53b0: 70 4b 65 79 49 6e 66 6f 20 26 26 20 70 43 73 72  pKeyInfo && pCsr
53c0: 2d 3e 70 42 74 3d 3d 30 20 29 3b 0a 20 20 73 7a  ->pBt==0 );.  sz
53d0: 4b 65 79 49 6e 66 6f 20 3d 20 73 69 7a 65 6f 66  KeyInfo = sizeof
53e0: 28 4b 65 79 49 6e 66 6f 29 20 2b 20 28 70 43 73  (KeyInfo) + (pCs
53f0: 72 2d 3e 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69  r->pKeyInfo->nFi
5400: 65 6c 64 2d 31 29 2a 73 69 7a 65 6f 66 28 43 6f  eld-1)*sizeof(Co
5410: 6c 6c 53 65 71 2a 29 3b 0a 20 20 73 7a 20 3d 20  llSeq*);.  sz = 
5420: 73 69 7a 65 6f 66 28 56 64 62 65 53 6f 72 74 65  sizeof(VdbeSorte
5430: 72 29 20 2b 20 6e 57 6f 72 6b 65 72 20 2a 20 73  r) + nWorker * s
5440: 69 7a 65 6f 66 28 53 6f 72 74 65 72 54 68 72 65  izeof(SorterThre
5450: 61 64 29 3b 0a 0a 20 20 70 53 6f 72 74 65 72 20  ad);..  pSorter 
5460: 3d 20 28 56 64 62 65 53 6f 72 74 65 72 2a 29 73  = (VdbeSorter*)s
5470: 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f 63 5a 65  qlite3DbMallocZe
5480: 72 6f 28 64 62 2c 20 73 7a 20 2b 20 73 7a 4b 65  ro(db, sz + szKe
5490: 79 49 6e 66 6f 29 3b 0a 20 20 70 43 73 72 2d 3e  yInfo);.  pCsr->
54a0: 70 53 6f 72 74 65 72 20 3d 20 70 53 6f 72 74 65  pSorter = pSorte
54b0: 72 3b 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72  r;.  if( pSorter
54c0: 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  ==0 ){.    rc = 
54d0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
54e0: 7d 65 6c 73 65 7b 0a 20 20 20 20 70 4b 65 79 49  }else{.    pKeyI
54f0: 6e 66 6f 20 3d 20 28 4b 65 79 49 6e 66 6f 2a 29  nfo = (KeyInfo*)
5500: 28 28 75 38 2a 29 70 53 6f 72 74 65 72 20 2b 20  ((u8*)pSorter + 
5510: 73 7a 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28  sz);.    memcpy(
5520: 70 4b 65 79 49 6e 66 6f 2c 20 70 43 73 72 2d 3e  pKeyInfo, pCsr->
5530: 70 4b 65 79 49 6e 66 6f 2c 20 73 7a 4b 65 79 49  pKeyInfo, szKeyI
5540: 6e 66 6f 29 3b 0a 20 20 20 20 70 4b 65 79 49 6e  nfo);.    pKeyIn
5550: 66 6f 2d 3e 64 62 20 3d 20 30 3b 0a 20 20 20 20  fo->db = 0;.    
5560: 69 66 28 20 6e 46 69 65 6c 64 20 26 26 20 6e 57  if( nField && nW
5570: 6f 72 6b 65 72 3d 3d 30 20 29 20 70 4b 65 79 49  orker==0 ) pKeyI
5580: 6e 66 6f 2d 3e 6e 46 69 65 6c 64 20 3d 20 6e 46  nfo->nField = nF
5590: 69 65 6c 64 3b 0a 20 20 20 20 70 67 73 7a 20 3d  ield;.    pgsz =
55a0: 20 73 71 6c 69 74 65 33 42 74 72 65 65 47 65 74   sqlite3BtreeGet
55b0: 50 61 67 65 53 69 7a 65 28 64 62 2d 3e 61 44 62  PageSize(db->aDb
55c0: 5b 30 5d 2e 70 42 74 29 3b 0a 0a 20 20 20 20 70  [0].pBt);..    p
55d0: 53 6f 72 74 65 72 2d 3e 6e 54 68 72 65 61 64 20  Sorter->nThread 
55e0: 3d 20 6e 57 6f 72 6b 65 72 20 2b 20 31 3b 0a 20  = nWorker + 1;. 
55f0: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 53     for(i=0; i<pS
5600: 6f 72 74 65 72 2d 3e 6e 54 68 72 65 61 64 3b 20  orter->nThread; 
5610: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 53 6f 72 74  i++){.      Sort
5620: 65 72 54 68 72 65 61 64 20 2a 70 54 68 72 65 61  erThread *pThrea
5630: 64 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 54  d = &pSorter->aT
5640: 68 72 65 61 64 5b 69 5d 3b 0a 20 20 20 20 20 20  hread[i];.      
5650: 70 54 68 72 65 61 64 2d 3e 70 4b 65 79 49 6e 66  pThread->pKeyInf
5660: 6f 20 3d 20 70 4b 65 79 49 6e 66 6f 3b 0a 20 20  o = pKeyInfo;.  
5670: 20 20 20 20 70 54 68 72 65 61 64 2d 3e 70 56 66      pThread->pVf
5680: 73 20 3d 20 64 62 2d 3e 70 56 66 73 3b 0a 20 20  s = db->pVfs;.  
5690: 20 20 20 20 70 54 68 72 65 61 64 2d 3e 70 67 73      pThread->pgs
56a0: 7a 20 3d 20 70 67 73 7a 3b 0a 20 20 20 20 7d 0a  z = pgsz;.    }.
56b0: 0a 20 20 20 20 69 66 28 20 21 73 71 6c 69 74 65  .    if( !sqlite
56c0: 33 54 65 6d 70 49 6e 4d 65 6d 6f 72 79 28 64 62  3TempInMemory(db
56d0: 29 20 29 7b 0a 20 20 20 20 20 20 70 53 6f 72 74  ) ){.      pSort
56e0: 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a 65 20 3d 20  er->mnPmaSize = 
56f0: 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49  SORTER_MIN_WORKI
5700: 4e 47 20 2a 20 70 67 73 7a 3b 0a 20 20 20 20 20  NG * pgsz;.     
5710: 20 6d 78 43 61 63 68 65 20 3d 20 64 62 2d 3e 61   mxCache = db->a
5720: 44 62 5b 30 5d 2e 70 53 63 68 65 6d 61 2d 3e 63  Db[0].pSchema->c
5730: 61 63 68 65 5f 73 69 7a 65 3b 0a 20 20 20 20 20  ache_size;.     
5740: 20 69 66 28 20 6d 78 43 61 63 68 65 3c 53 4f 52   if( mxCache<SOR
5750: 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20  TER_MIN_WORKING 
5760: 29 20 6d 78 43 61 63 68 65 20 3d 20 53 4f 52 54  ) mxCache = SORT
5770: 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 3b 0a  ER_MIN_WORKING;.
5780: 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6d        pSorter->m
5790: 78 50 6d 61 53 69 7a 65 20 3d 20 6d 78 43 61 63  xPmaSize = mxCac
57a0: 68 65 20 2a 20 70 67 73 7a 3b 0a 0a 20 20 20 20  he * pgsz;..    
57b0: 20 20 2f 2a 20 49 66 20 74 68 65 20 61 70 70 6c    /* If the appl
57c0: 69 63 61 74 69 6f 6e 20 69 73 20 75 73 69 6e 67  ication is using
57d0: 20 6d 65 6d 73 79 73 33 20 6f 72 20 6d 65 6d 73   memsys3 or mems
57e0: 79 73 35 2c 20 75 73 65 20 61 20 73 65 70 61 72  ys5, use a separ
57f0: 61 74 65 20 0a 20 20 20 20 20 20 2a 2a 20 61 6c  ate .      ** al
5800: 6c 6f 63 61 74 69 6f 6e 20 66 6f 72 20 65 61 63  location for eac
5810: 68 20 73 6f 72 74 2d 6b 65 79 20 69 6e 20 6d 65  h sort-key in me
5820: 6d 6f 72 79 2e 20 4f 74 68 65 72 77 69 73 65 2c  mory. Otherwise,
5830: 20 75 73 65 20 61 20 73 69 6e 67 6c 65 20 62 69   use a single bi
5840: 67 0a 20 20 20 20 20 20 2a 2a 20 61 6c 6c 6f 63  g.      ** alloc
5850: 61 74 69 6f 6e 20 61 74 20 70 53 6f 72 74 65 72  ation at pSorter
5860: 2d 3e 61 4d 65 6d 6f 72 79 20 66 6f 72 20 61 6c  ->aMemory for al
5870: 6c 20 73 6f 72 74 2d 6b 65 79 73 2e 20 20 2a 2f  l sort-keys.  */
5880: 0a 20 20 20 20 20 20 69 66 28 20 73 71 6c 69 74  .      if( sqlit
5890: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70  e3GlobalConfig.p
58a0: 48 65 61 70 3d 3d 30 20 29 7b 0a 20 20 20 20 20  Heap==0 ){.     
58b0: 20 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74     assert( pSort
58c0: 65 72 2d 3e 69 4d 65 6d 6f 72 79 3d 3d 30 20 29  er->iMemory==0 )
58d0: 3b 0a 20 20 20 20 20 20 20 20 70 53 6f 72 74 65  ;.        pSorte
58e0: 72 2d 3e 6e 4d 65 6d 6f 72 79 20 3d 20 70 67 73  r->nMemory = pgs
58f0: 7a 3b 0a 20 20 20 20 20 20 20 20 70 53 6f 72 74  z;.        pSort
5900: 65 72 2d 3e 61 4d 65 6d 6f 72 79 20 3d 20 28 75  er->aMemory = (u
5910: 38 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  8*)sqlite3Malloc
5920: 28 70 67 73 7a 29 3b 0a 20 20 20 20 20 20 20 20  (pgsz);.        
5930: 69 66 28 20 21 70 53 6f 72 74 65 72 2d 3e 61 4d  if( !pSorter->aM
5940: 65 6d 6f 72 79 20 29 20 72 63 20 3d 20 53 51 4c  emory ) rc = SQL
5950: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
5960: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
5970: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
5980: 0a 2a 2a 20 46 72 65 65 20 74 68 65 20 6c 69 73  .** Free the lis
5990: 74 20 6f 66 20 73 6f 72 74 65 64 20 72 65 63 6f  t of sorted reco
59a0: 72 64 73 20 73 74 61 72 74 69 6e 67 20 61 74 20  rds starting at 
59b0: 70 52 65 63 6f 72 64 2e 0a 2a 2f 0a 73 74 61 74  pRecord..*/.stat
59c0: 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74  ic void vdbeSort
59d0: 65 72 52 65 63 6f 72 64 46 72 65 65 28 73 71 6c  erRecordFree(sql
59e0: 69 74 65 33 20 2a 64 62 2c 20 53 6f 72 74 65 72  ite3 *db, Sorter
59f0: 52 65 63 6f 72 64 20 2a 70 52 65 63 6f 72 64 29  Record *pRecord)
5a00: 7b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  {.  SorterRecord
5a10: 20 2a 70 3b 0a 20 20 53 6f 72 74 65 72 52 65 63   *p;.  SorterRec
5a20: 6f 72 64 20 2a 70 4e 65 78 74 3b 0a 20 20 66 6f  ord *pNext;.  fo
5a30: 72 28 70 3d 70 52 65 63 6f 72 64 3b 20 70 3b 20  r(p=pRecord; p; 
5a40: 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 4e  p=pNext){.    pN
5a50: 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74  ext = p->u.pNext
5a60: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 44 62 46  ;.    sqlite3DbF
5a70: 72 65 65 28 64 62 2c 20 70 29 3b 0a 20 20 7d 0a  ree(db, p);.  }.
5a80: 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6c  }../*.** Free al
5a90: 6c 20 72 65 73 6f 75 72 63 65 73 20 6f 77 6e 65  l resources owne
5aa0: 64 20 62 79 20 74 68 65 20 6f 62 6a 65 63 74 20  d by the object 
5ab0: 69 6e 64 69 63 61 74 65 64 20 62 79 20 61 72 67  indicated by arg
5ac0: 75 6d 65 6e 74 20 70 54 68 72 65 61 64 2e 20 41  ument pThread. A
5ad0: 6c 6c 20 0a 2a 2a 20 66 69 65 6c 64 73 20 6f 66  ll .** fields of
5ae0: 20 2a 70 54 68 72 65 61 64 20 61 72 65 20 7a 65   *pThread are ze
5af0: 72 6f 65 64 20 62 65 66 6f 72 65 20 72 65 74 75  roed before retu
5b00: 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63  rning..*/.static
5b10: 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72   void vdbeSorter
5b20: 54 68 72 65 61 64 43 6c 65 61 6e 75 70 28 73 71  ThreadCleanup(sq
5b30: 6c 69 74 65 33 20 2a 64 62 2c 20 53 6f 72 74 65  lite3 *db, Sorte
5b40: 72 54 68 72 65 61 64 20 2a 70 54 68 72 65 61 64  rThread *pThread
5b50: 29 7b 0a 20 20 73 71 6c 69 74 65 33 44 62 46 72  ){.  sqlite3DbFr
5b60: 65 65 28 64 62 2c 20 70 54 68 72 65 61 64 2d 3e  ee(db, pThread->
5b70: 70 55 6e 70 61 63 6b 65 64 29 3b 0a 20 20 70 54  pUnpacked);.  pT
5b80: 68 72 65 61 64 2d 3e 70 55 6e 70 61 63 6b 65 64  hread->pUnpacked
5b90: 20 3d 20 30 3b 0a 20 20 69 66 28 20 70 54 68 72   = 0;.  if( pThr
5ba0: 65 61 64 2d 3e 61 4c 69 73 74 4d 65 6d 6f 72 79  ead->aListMemory
5bb0: 3d 3d 30 20 29 7b 0a 20 20 20 20 76 64 62 65 53  ==0 ){.    vdbeS
5bc0: 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65 65 28  orterRecordFree(
5bd0: 30 2c 20 70 54 68 72 65 61 64 2d 3e 70 4c 69 73  0, pThread->pLis
5be0: 74 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  t);.  }else{.   
5bf0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 54   sqlite3_free(pT
5c00: 68 72 65 61 64 2d 3e 61 4c 69 73 74 4d 65 6d 6f  hread->aListMemo
5c10: 72 79 29 3b 0a 20 20 20 20 70 54 68 72 65 61 64  ry);.    pThread
5c20: 2d 3e 61 4c 69 73 74 4d 65 6d 6f 72 79 20 3d 20  ->aListMemory = 
5c30: 30 3b 0a 20 20 7d 0a 20 20 70 54 68 72 65 61 64  0;.  }.  pThread
5c40: 2d 3e 70 4c 69 73 74 20 3d 20 30 3b 0a 20 20 69  ->pList = 0;.  i
5c50: 66 28 20 70 54 68 72 65 61 64 2d 3e 70 54 65 6d  f( pThread->pTem
5c60: 70 31 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  p1 ){.    sqlite
5c70: 33 4f 73 43 6c 6f 73 65 46 72 65 65 28 70 54 68  3OsCloseFree(pTh
5c80: 72 65 61 64 2d 3e 70 54 65 6d 70 31 29 3b 0a 20  read->pTemp1);. 
5c90: 20 20 20 70 54 68 72 65 61 64 2d 3e 70 54 65 6d     pThread->pTem
5ca0: 70 31 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f  p1 = 0;.  }.}../
5cb0: 2a 0a 2a 2a 20 4a 6f 69 6e 20 61 6c 6c 20 74 68  *.** Join all th
5cc0: 72 65 61 64 73 2e 20 20 0a 2a 2f 0a 23 69 66 20  reads.  .*/.#if 
5cd0: 53 51 4c 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45  SQLITE_MAX_WORKE
5ce0: 52 5f 54 48 52 45 41 44 53 3e 30 0a 73 74 61 74  R_THREADS>0.stat
5cf0: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
5d00: 72 4a 6f 69 6e 41 6c 6c 28 56 64 62 65 53 6f 72  rJoinAll(VdbeSor
5d10: 74 65 72 20 2a 70 53 6f 72 74 65 72 2c 20 69 6e  ter *pSorter, in
5d20: 74 20 72 63 69 6e 29 7b 0a 20 20 69 6e 74 20 72  t rcin){.  int r
5d30: 63 20 3d 20 72 63 69 6e 3b 0a 20 20 69 6e 74 20  c = rcin;.  int 
5d40: 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  i;.  for(i=0; i<
5d50: 70 53 6f 72 74 65 72 2d 3e 6e 54 68 72 65 61 64  pSorter->nThread
5d60: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 53 6f 72 74  ; i++){.    Sort
5d70: 65 72 54 68 72 65 61 64 20 2a 70 54 68 72 65 61  erThread *pThrea
5d80: 64 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 54  d = &pSorter->aT
5d90: 68 72 65 61 64 5b 69 5d 3b 0a 20 20 20 20 69 66  hread[i];.    if
5da0: 28 20 70 54 68 72 65 61 64 2d 3e 70 54 68 72 65  ( pThread->pThre
5db0: 61 64 20 29 7b 0a 20 20 20 20 20 20 76 6f 69 64  ad ){.      void
5dc0: 20 2a 70 52 65 74 3b 0a 20 20 20 20 20 20 69 6e   *pRet;.      in
5dd0: 74 20 72 63 32 20 3d 20 73 71 6c 69 74 65 33 54  t rc2 = sqlite3T
5de0: 68 72 65 61 64 4a 6f 69 6e 28 70 54 68 72 65 61  hreadJoin(pThrea
5df0: 64 2d 3e 70 54 68 72 65 61 64 2c 20 26 70 52 65  d->pThread, &pRe
5e00: 74 29 3b 0a 20 20 20 20 20 20 70 54 68 72 65 61  t);.      pThrea
5e10: 64 2d 3e 70 54 68 72 65 61 64 20 3d 20 30 3b 0a  d->pThread = 0;.
5e20: 20 20 20 20 20 20 70 54 68 72 65 61 64 2d 3e 62        pThread->b
5e30: 44 6f 6e 65 20 3d 20 30 3b 0a 20 20 20 20 20 20  Done = 0;.      
5e40: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
5e50: 4b 20 29 20 72 63 20 3d 20 72 63 32 3b 0a 20 20  K ) rc = rc2;.  
5e60: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
5e70: 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 53 51 4c  TE_OK ) rc = SQL
5e80: 49 54 45 5f 50 54 52 5f 54 4f 5f 49 4e 54 28 70  ITE_PTR_TO_INT(p
5e90: 52 65 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  Ret);.    }.  }.
5ea0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 23    return rc;.}.#
5eb0: 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 76 64  else.# define vd
5ec0: 62 65 53 6f 72 74 65 72 4a 6f 69 6e 41 6c 6c 28  beSorterJoinAll(
5ed0: 78 2c 72 63 69 6e 29 20 28 72 63 69 6e 29 0a 23  x,rcin) (rcin).#
5ee0: 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c  endif../*.** All
5ef0: 6f 63 61 74 65 20 61 20 6e 65 77 20 53 6f 72 74  ocate a new Sort
5f00: 65 72 4d 65 72 67 65 72 20 6f 62 6a 65 63 74 20  erMerger object 
5f10: 77 69 74 68 20 73 70 61 63 65 20 66 6f 72 20 6e  with space for n
5f20: 49 74 65 72 20 69 74 65 72 61 74 6f 72 73 2e 0a  Iter iterators..
5f30: 2a 2f 0a 73 74 61 74 69 63 20 53 6f 72 74 65 72  */.static Sorter
5f40: 4d 65 72 67 65 72 20 2a 76 64 62 65 53 6f 72 74  Merger *vdbeSort
5f50: 65 72 4d 65 72 67 65 72 4e 65 77 28 69 6e 74 20  erMergerNew(int 
5f60: 6e 49 74 65 72 29 7b 0a 20 20 69 6e 74 20 4e 20  nIter){.  int N 
5f70: 3d 20 32 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 2;            
5f80: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6d 61            /* Sma
5f90: 6c 6c 65 73 74 20 70 6f 77 65 72 20 6f 66 20 74  llest power of t
5fa0: 77 6f 20 3e 3d 20 6e 49 74 65 72 20 2a 2f 0a 20  wo >= nIter */. 
5fb0: 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20   int nByte;     
5fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5fd0: 20 2f 2a 20 54 6f 74 61 6c 20 62 79 74 65 73 20   /* Total bytes 
5fe0: 6f 66 20 73 70 61 63 65 20 74 6f 20 61 6c 6c 6f  of space to allo
5ff0: 63 61 74 65 20 2a 2f 0a 20 20 53 6f 72 74 65 72  cate */.  Sorter
6000: 4d 65 72 67 65 72 20 2a 70 4e 65 77 3b 20 20 20  Merger *pNew;   
6010: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
6020: 6e 74 65 72 20 74 6f 20 61 6c 6c 6f 63 61 74 65  nter to allocate
6030: 64 20 6f 62 6a 65 63 74 20 74 6f 20 72 65 74 75  d object to retu
6040: 72 6e 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28  rn */..  assert(
6050: 20 6e 49 74 65 72 3c 3d 53 4f 52 54 45 52 5f 4d   nIter<=SORTER_M
6060: 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20 29  AX_MERGE_COUNT )
6070: 3b 0a 20 20 77 68 69 6c 65 28 20 4e 3c 6e 49 74  ;.  while( N<nIt
6080: 65 72 20 29 20 4e 20 2b 3d 20 4e 3b 0a 20 20 6e  er ) N += N;.  n
6090: 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 53 6f  Byte = sizeof(So
60a0: 72 74 65 72 4d 65 72 67 65 72 29 20 2b 20 4e 20  rterMerger) + N 
60b0: 2a 20 28 73 69 7a 65 6f 66 28 69 6e 74 29 20 2b  * (sizeof(int) +
60c0: 20 73 69 7a 65 6f 66 28 56 64 62 65 53 6f 72 74   sizeof(VdbeSort
60d0: 65 72 49 74 65 72 29 29 3b 0a 0a 20 20 70 4e 65  erIter));..  pNe
60e0: 77 20 3d 20 28 53 6f 72 74 65 72 4d 65 72 67 65  w = (SorterMerge
60f0: 72 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  r*)sqlite3Malloc
6100: 5a 65 72 6f 28 6e 42 79 74 65 29 3b 0a 20 20 69  Zero(nByte);.  i
6110: 66 28 20 70 4e 65 77 20 29 7b 0a 20 20 20 20 70  f( pNew ){.    p
6120: 4e 65 77 2d 3e 6e 54 72 65 65 20 3d 20 4e 3b 0a  New->nTree = N;.
6130: 20 20 20 20 70 4e 65 77 2d 3e 61 49 74 65 72 20      pNew->aIter 
6140: 3d 20 28 56 64 62 65 53 6f 72 74 65 72 49 74 65  = (VdbeSorterIte
6150: 72 2a 29 26 70 4e 65 77 5b 31 5d 3b 0a 20 20 20  r*)&pNew[1];.   
6160: 20 70 4e 65 77 2d 3e 61 54 72 65 65 20 3d 20 28   pNew->aTree = (
6170: 69 6e 74 2a 29 26 70 4e 65 77 2d 3e 61 49 74 65  int*)&pNew->aIte
6180: 72 5b 4e 5d 3b 0a 20 20 7d 0a 20 20 72 65 74 75  r[N];.  }.  retu
6190: 72 6e 20 70 4e 65 77 3b 0a 7d 0a 0a 2f 2a 0a 2a  rn pNew;.}../*.*
61a0: 2a 20 52 65 73 65 74 20 61 20 6d 65 72 67 65 72  * Reset a merger
61b0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
61c0: 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65 72  vdbeSorterMerger
61d0: 52 65 73 65 74 28 53 6f 72 74 65 72 4d 65 72 67  Reset(SorterMerg
61e0: 65 72 20 2a 70 4d 65 72 67 65 72 29 7b 0a 20 20  er *pMerger){.  
61f0: 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 70 4d 65  int i;.  if( pMe
6200: 72 67 65 72 20 29 7b 0a 20 20 20 20 66 6f 72 28  rger ){.    for(
6210: 69 3d 30 3b 20 69 3c 70 4d 65 72 67 65 72 2d 3e  i=0; i<pMerger->
6220: 6e 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20 20 20  nTree; i++){.   
6230: 20 20 20 76 64 62 65 53 6f 72 74 65 72 49 74 65     vdbeSorterIte
6240: 72 5a 65 72 6f 28 26 70 4d 65 72 67 65 72 2d 3e  rZero(&pMerger->
6250: 61 49 74 65 72 5b 69 5d 29 3b 0a 20 20 20 20 7d  aIter[i]);.    }
6260: 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 46  .  }.}.../*.** F
6270: 72 65 65 20 74 68 65 20 53 6f 72 74 65 72 4d 65  ree the SorterMe
6280: 72 67 65 72 20 6f 62 6a 65 63 74 20 70 61 73 73  rger object pass
6290: 65 64 20 61 73 20 74 68 65 20 6f 6e 6c 79 20 61  ed as the only a
62a0: 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74  rgument..*/.stat
62b0: 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74  ic void vdbeSort
62c0: 65 72 4d 65 72 67 65 72 46 72 65 65 28 53 6f 72  erMergerFree(Sor
62d0: 74 65 72 4d 65 72 67 65 72 20 2a 70 4d 65 72 67  terMerger *pMerg
62e0: 65 72 29 7b 0a 20 20 76 64 62 65 53 6f 72 74 65  er){.  vdbeSorte
62f0: 72 4d 65 72 67 65 72 52 65 73 65 74 28 70 4d 65  rMergerReset(pMe
6300: 72 67 65 72 29 3b 0a 20 20 73 71 6c 69 74 65 33  rger);.  sqlite3
6310: 5f 66 72 65 65 28 70 4d 65 72 67 65 72 29 3b 0a  _free(pMerger);.
6320: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65 74 20 61  }../*.** Reset a
6330: 20 73 6f 72 74 69 6e 67 20 63 75 72 73 6f 72 20   sorting cursor 
6340: 62 61 63 6b 20 74 6f 20 69 74 73 20 6f 72 69 67  back to its orig
6350: 69 6e 61 6c 20 65 6d 70 74 79 20 73 74 61 74 65  inal empty state
6360: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
6370: 33 56 64 62 65 53 6f 72 74 65 72 52 65 73 65 74  3VdbeSorterReset
6380: 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 56 64  (sqlite3 *db, Vd
6390: 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
63a0: 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 76  r){.  int i;.  v
63b0: 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e 41 6c 6c  dbeSorterJoinAll
63c0: 28 70 53 6f 72 74 65 72 2c 20 53 51 4c 49 54 45  (pSorter, SQLITE
63d0: 5f 4f 4b 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  _OK);.  for(i=0;
63e0: 20 69 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 68 72   i<pSorter->nThr
63f0: 65 61 64 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 53  ead; i++){.    S
6400: 6f 72 74 65 72 54 68 72 65 61 64 20 2a 70 54 68  orterThread *pTh
6410: 72 65 61 64 20 3d 20 26 70 53 6f 72 74 65 72 2d  read = &pSorter-
6420: 3e 61 54 68 72 65 61 64 5b 69 5d 3b 0a 20 20 20  >aThread[i];.   
6430: 20 76 64 62 65 53 6f 72 74 65 72 54 68 72 65 61   vdbeSorterThrea
6440: 64 43 6c 65 61 6e 75 70 28 64 62 2c 20 70 54 68  dCleanup(db, pTh
6450: 72 65 61 64 29 3b 0a 20 20 7d 0a 20 20 69 66 28  read);.  }.  if(
6460: 20 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72   pSorter->aMemor
6470: 79 3d 3d 30 20 29 7b 0a 20 20 20 20 76 64 62 65  y==0 ){.    vdbe
6480: 53 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65 65  SorterRecordFree
6490: 28 30 2c 20 70 53 6f 72 74 65 72 2d 3e 70 52 65  (0, pSorter->pRe
64a0: 63 6f 72 64 29 3b 0a 20 20 7d 0a 20 20 76 64 62  cord);.  }.  vdb
64b0: 65 53 6f 72 74 65 72 4d 65 72 67 65 72 52 65 73  eSorterMergerRes
64c0: 65 74 28 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72  et(pSorter->pMer
64d0: 67 65 72 29 3b 0a 20 20 70 53 6f 72 74 65 72 2d  ger);.  pSorter-
64e0: 3e 70 52 65 63 6f 72 64 20 3d 20 30 3b 0a 20 20  >pRecord = 0;.  
64f0: 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f  pSorter->nInMemo
6500: 72 79 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74 65  ry = 0;.  pSorte
6510: 72 2d 3e 62 55 73 65 50 4d 41 20 3d 20 30 3b 0a  r->bUsePMA = 0;.
6520: 20 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f    pSorter->iMemo
6530: 72 79 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ry = 0;.}../*.**
6540: 20 46 72 65 65 20 61 6e 79 20 63 75 72 73 6f 72   Free any cursor
6550: 20 63 6f 6d 70 6f 6e 65 6e 74 73 20 61 6c 6c 6f   components allo
6560: 63 61 74 65 64 20 62 79 20 73 71 6c 69 74 65 33  cated by sqlite3
6570: 56 64 62 65 53 6f 72 74 65 72 58 58 58 20 72 6f  VdbeSorterXXX ro
6580: 75 74 69 6e 65 73 2e 0a 2a 2f 0a 76 6f 69 64 20  utines..*/.void 
6590: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
65a0: 72 43 6c 6f 73 65 28 73 71 6c 69 74 65 33 20 2a  rClose(sqlite3 *
65b0: 64 62 2c 20 56 64 62 65 43 75 72 73 6f 72 20 2a  db, VdbeCursor *
65c0: 70 43 73 72 29 7b 0a 20 20 56 64 62 65 53 6f 72  pCsr){.  VdbeSor
65d0: 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70  ter *pSorter = p
65e0: 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20  Csr->pSorter;.  
65f0: 69 66 28 20 70 53 6f 72 74 65 72 20 29 7b 0a 20  if( pSorter ){. 
6600: 20 20 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f     sqlite3VdbeSo
6610: 72 74 65 72 52 65 73 65 74 28 64 62 2c 20 70 53  rterReset(db, pS
6620: 6f 72 74 65 72 29 3b 0a 20 20 20 20 76 64 62 65  orter);.    vdbe
6630: 53 6f 72 74 65 72 4d 65 72 67 65 72 46 72 65 65  SorterMergerFree
6640: 28 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65  (pSorter->pMerge
6650: 72 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  r);.    sqlite3_
6660: 66 72 65 65 28 70 53 6f 72 74 65 72 2d 3e 61 4d  free(pSorter->aM
6670: 65 6d 6f 72 79 29 3b 0a 20 20 20 20 73 71 6c 69  emory);.    sqli
6680: 74 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 53  te3DbFree(db, pS
6690: 6f 72 74 65 72 29 3b 0a 20 20 20 20 70 43 73 72  orter);.    pCsr
66a0: 2d 3e 70 53 6f 72 74 65 72 20 3d 20 30 3b 0a 20  ->pSorter = 0;. 
66b0: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f   }.}../*.** Allo
66c0: 63 61 74 65 20 73 70 61 63 65 20 66 6f 72 20 61  cate space for a
66d0: 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20 61 6e 64   file-handle and
66e0: 20 6f 70 65 6e 20 61 20 74 65 6d 70 6f 72 61 72   open a temporar
66f0: 79 20 66 69 6c 65 2e 20 49 66 20 73 75 63 63 65  y file. If succe
6700: 73 73 66 75 6c 2c 0a 2a 2a 20 73 65 74 20 2a 70  ssful,.** set *p
6710: 70 46 69 6c 65 20 74 6f 20 70 6f 69 6e 74 20 74  pFile to point t
6720: 6f 20 74 68 65 20 6d 61 6c 6c 6f 63 27 64 20 66  o the malloc'd f
6730: 69 6c 65 2d 68 61 6e 64 6c 65 20 61 6e 64 20 72  ile-handle and r
6740: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e  eturn SQLITE_OK.
6750: 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 73  .** Otherwise, s
6760: 65 74 20 2a 70 70 46 69 6c 65 20 74 6f 20 30 20  et *ppFile to 0 
6770: 61 6e 64 20 72 65 74 75 72 6e 20 61 6e 20 53 51  and return an SQ
6780: 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e  Lite error code.
6790: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
67a0: 64 62 65 53 6f 72 74 65 72 4f 70 65 6e 54 65 6d  dbeSorterOpenTem
67b0: 70 46 69 6c 65 28 73 71 6c 69 74 65 33 5f 76 66  pFile(sqlite3_vf
67c0: 73 20 2a 70 56 66 73 2c 20 73 71 6c 69 74 65 33  s *pVfs, sqlite3
67d0: 5f 66 69 6c 65 20 2a 2a 70 70 46 69 6c 65 29 7b  _file **ppFile){
67e0: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 72 63 20  .  int rc;.  rc 
67f0: 3d 20 73 71 6c 69 74 65 33 4f 73 4f 70 65 6e 4d  = sqlite3OsOpenM
6800: 61 6c 6c 6f 63 28 70 56 66 73 2c 20 30 2c 20 70  alloc(pVfs, 0, p
6810: 70 46 69 6c 65 2c 0a 20 20 20 20 20 20 53 51 4c  pFile,.      SQL
6820: 49 54 45 5f 4f 50 45 4e 5f 54 45 4d 50 5f 4a 4f  ITE_OPEN_TEMP_JO
6830: 55 52 4e 41 4c 20 7c 0a 20 20 20 20 20 20 53 51  URNAL |.      SQ
6840: 4c 49 54 45 5f 4f 50 45 4e 5f 52 45 41 44 57 52  LITE_OPEN_READWR
6850: 49 54 45 20 20 20 20 7c 20 53 51 4c 49 54 45 5f  ITE    | SQLITE_
6860: 4f 50 45 4e 5f 43 52 45 41 54 45 20 7c 0a 20 20  OPEN_CREATE |.  
6870: 20 20 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f      SQLITE_OPEN_
6880: 45 58 43 4c 55 53 49 56 45 20 20 20 20 7c 20 53  EXCLUSIVE    | S
6890: 51 4c 49 54 45 5f 4f 50 45 4e 5f 44 45 4c 45 54  QLITE_OPEN_DELET
68a0: 45 4f 4e 43 4c 4f 53 45 2c 20 26 72 63 0a 20 20  EONCLOSE, &rc.  
68b0: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  );.  if( rc==SQL
68c0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 36  ITE_OK ){.    i6
68d0: 34 20 6d 61 78 20 3d 20 53 51 4c 49 54 45 5f 4d  4 max = SQLITE_M
68e0: 41 58 5f 4d 4d 41 50 5f 53 49 5a 45 3b 0a 20 20  AX_MMAP_SIZE;.  
68f0: 20 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 43    sqlite3OsFileC
6900: 6f 6e 74 72 6f 6c 48 69 6e 74 28 20 2a 70 70 46  ontrolHint( *ppF
6910: 69 6c 65 2c 20 53 51 4c 49 54 45 5f 46 43 4e 54  ile, SQLITE_FCNT
6920: 4c 5f 4d 4d 41 50 5f 53 49 5a 45 2c 20 28 76 6f  L_MMAP_SIZE, (vo
6930: 69 64 2a 29 26 6d 61 78 29 3b 0a 20 20 7d 0a 20  id*)&max);.  }. 
6940: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
6950: 2a 0a 2a 2a 20 4d 65 72 67 65 20 74 68 65 20 74  *.** Merge the t
6960: 77 6f 20 73 6f 72 74 65 64 20 6c 69 73 74 73 20  wo sorted lists 
6970: 70 31 20 61 6e 64 20 70 32 20 69 6e 74 6f 20 61  p1 and p2 into a
6980: 20 73 69 6e 67 6c 65 20 6c 69 73 74 2e 0a 2a 2a   single list..**
6990: 20 53 65 74 20 2a 70 70 4f 75 74 20 74 6f 20 74   Set *ppOut to t
69a0: 68 65 20 68 65 61 64 20 6f 66 20 74 68 65 20 6e  he head of the n
69b0: 65 77 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61 74  ew list..*/.stat
69c0: 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74  ic void vdbeSort
69d0: 65 72 4d 65 72 67 65 28 0a 20 20 53 6f 72 74 65  erMerge(.  Sorte
69e0: 72 54 68 72 65 61 64 20 2a 70 54 68 72 65 61 64  rThread *pThread
69f0: 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61  ,          /* Ca
6a00: 6c 6c 69 6e 67 20 74 68 72 65 61 64 20 63 6f 6e  lling thread con
6a10: 74 65 78 74 20 2a 2f 0a 20 20 53 6f 72 74 65 72  text */.  Sorter
6a20: 52 65 63 6f 72 64 20 2a 70 31 2c 20 20 20 20 20  Record *p1,     
6a30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72            /* Fir
6a40: 73 74 20 6c 69 73 74 20 74 6f 20 6d 65 72 67 65  st list to merge
6a50: 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f   */.  SorterReco
6a60: 72 64 20 2a 70 32 2c 20 20 20 20 20 20 20 20 20  rd *p2,         
6a70: 20 20 20 20 20 20 2f 2a 20 53 65 63 6f 6e 64 20        /* Second 
6a80: 6c 69 73 74 20 74 6f 20 6d 65 72 67 65 20 2a 2f  list to merge */
6a90: 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20  .  SorterRecord 
6aa0: 2a 2a 70 70 4f 75 74 20 20 20 20 20 20 20 20 20  **ppOut         
6ab0: 20 20 20 2f 2a 20 4f 55 54 3a 20 48 65 61 64 20     /* OUT: Head 
6ac0: 6f 66 20 6d 65 72 67 65 64 20 6c 69 73 74 20 2a  of merged list *
6ad0: 2f 0a 29 7b 0a 20 20 53 6f 72 74 65 72 52 65 63  /.){.  SorterRec
6ae0: 6f 72 64 20 2a 70 46 69 6e 61 6c 20 3d 20 30 3b  ord *pFinal = 0;
6af0: 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20  .  SorterRecord 
6b00: 2a 2a 70 70 20 3d 20 26 70 46 69 6e 61 6c 3b 0a  **pp = &pFinal;.
6b10: 20 20 76 6f 69 64 20 2a 70 56 61 6c 32 20 3d 20    void *pVal2 = 
6b20: 70 32 20 3f 20 53 52 56 41 4c 28 70 32 29 20 3a  p2 ? SRVAL(p2) :
6b30: 20 30 3b 0a 0a 20 20 77 68 69 6c 65 28 20 70 31   0;..  while( p1
6b40: 20 26 26 20 70 32 20 29 7b 0a 20 20 20 20 69 6e   && p2 ){.    in
6b50: 74 20 72 65 73 3b 0a 20 20 20 20 72 65 73 20 3d  t res;.    res =
6b60: 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61   vdbeSorterCompa
6b70: 72 65 28 70 54 68 72 65 61 64 2c 20 53 52 56 41  re(pThread, SRVA
6b80: 4c 28 70 31 29 2c 20 70 31 2d 3e 6e 56 61 6c 2c  L(p1), p1->nVal,
6b90: 20 70 56 61 6c 32 2c 20 70 32 2d 3e 6e 56 61 6c   pVal2, p2->nVal
6ba0: 29 3b 0a 20 20 20 20 69 66 28 20 72 65 73 3c 3d  );.    if( res<=
6bb0: 30 20 29 7b 0a 20 20 20 20 20 20 2a 70 70 20 3d  0 ){.      *pp =
6bc0: 20 70 31 3b 0a 20 20 20 20 20 20 70 70 20 3d 20   p1;.      pp = 
6bd0: 26 70 31 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20 20  &p1->u.pNext;.  
6be0: 20 20 20 20 70 31 20 3d 20 70 31 2d 3e 75 2e 70      p1 = p1->u.p
6bf0: 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 56 61 6c  Next;.      pVal
6c00: 32 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65  2 = 0;.    }else
6c10: 7b 0a 20 20 20 20 20 20 2a 70 70 20 3d 20 70 32  {.      *pp = p2
6c20: 3b 0a 20 20 20 20 20 20 20 70 70 20 3d 20 26 70  ;.       pp = &p
6c30: 32 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20 20 20 20  2->u.pNext;.    
6c40: 20 20 70 32 20 3d 20 70 32 2d 3e 75 2e 70 4e 65    p2 = p2->u.pNe
6c50: 78 74 3b 0a 20 20 20 20 20 20 69 66 28 20 70 32  xt;.      if( p2
6c60: 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  ==0 ) break;.   
6c70: 20 20 20 70 56 61 6c 32 20 3d 20 53 52 56 41 4c     pVal2 = SRVAL
6c80: 28 70 32 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  (p2);.    }.  }.
6c90: 20 20 2a 70 70 20 3d 20 70 31 20 3f 20 70 31 20    *pp = p1 ? p1 
6ca0: 3a 20 70 32 3b 0a 20 20 2a 70 70 4f 75 74 20 3d  : p2;.  *ppOut =
6cb0: 20 70 46 69 6e 61 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a   pFinal;.}../*.*
6cc0: 2a 20 53 6f 72 74 20 74 68 65 20 6c 69 6e 6b 65  * Sort the linke
6cd0: 64 20 6c 69 73 74 20 6f 66 20 72 65 63 6f 72 64  d list of record
6ce0: 73 20 68 65 61 64 65 64 20 61 74 20 70 54 68 72  s headed at pThr
6cf0: 65 61 64 2d 3e 70 4c 69 73 74 2e 20 52 65 74 75  ead->pList. Retu
6d00: 72 6e 20 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b  rn .** SQLITE_OK
6d10: 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   if successful, 
6d20: 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  or an SQLite err
6d30: 6f 72 20 63 6f 64 65 20 28 69 2e 65 2e 20 53 51  or code (i.e. SQ
6d40: 4c 49 54 45 5f 4e 4f 4d 45 4d 29 20 69 66 20 0a  LITE_NOMEM) if .
6d50: 2a 2a 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  ** an error occu
6d60: 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  rs..*/.static in
6d70: 74 20 76 64 62 65 53 6f 72 74 65 72 53 6f 72 74  t vdbeSorterSort
6d80: 28 53 6f 72 74 65 72 54 68 72 65 61 64 20 2a 70  (SorterThread *p
6d90: 54 68 72 65 61 64 29 7b 0a 20 20 69 6e 74 20 69  Thread){.  int i
6da0: 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  ;.  SorterRecord
6db0: 20 2a 2a 61 53 6c 6f 74 3b 0a 20 20 53 6f 72 74   **aSlot;.  Sort
6dc0: 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a 0a 20 20  erRecord *p;..  
6dd0: 61 53 6c 6f 74 20 3d 20 28 53 6f 72 74 65 72 52  aSlot = (SorterR
6de0: 65 63 6f 72 64 20 2a 2a 29 73 71 6c 69 74 65 33  ecord **)sqlite3
6df0: 4d 61 6c 6c 6f 63 5a 65 72 6f 28 36 34 20 2a 20  MallocZero(64 * 
6e00: 73 69 7a 65 6f 66 28 53 6f 72 74 65 72 52 65 63  sizeof(SorterRec
6e10: 6f 72 64 20 2a 29 29 3b 0a 20 20 69 66 28 20 21  ord *));.  if( !
6e20: 61 53 6c 6f 74 20 29 7b 0a 20 20 20 20 72 65 74  aSlot ){.    ret
6e30: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
6e40: 3b 0a 20 20 7d 0a 0a 20 20 70 20 3d 20 70 54 68  ;.  }..  p = pTh
6e50: 72 65 61 64 2d 3e 70 4c 69 73 74 3b 0a 20 20 77  read->pList;.  w
6e60: 68 69 6c 65 28 20 70 20 29 7b 0a 20 20 20 20 53  hile( p ){.    S
6e70: 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65  orterRecord *pNe
6e80: 78 74 3b 0a 20 20 20 20 69 66 28 20 70 54 68 72  xt;.    if( pThr
6e90: 65 61 64 2d 3e 61 4c 69 73 74 4d 65 6d 6f 72 79  ead->aListMemory
6ea0: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 28 75   ){.      if( (u
6eb0: 38 2a 29 70 3d 3d 70 54 68 72 65 61 64 2d 3e 61  8*)p==pThread->a
6ec0: 4c 69 73 74 4d 65 6d 6f 72 79 20 29 7b 0a 20 20  ListMemory ){.  
6ed0: 20 20 20 20 20 20 70 4e 65 78 74 20 3d 20 30 3b        pNext = 0;
6ee0: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
6ef0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d        assert( p-
6f00: 3e 75 2e 69 4e 65 78 74 3c 73 71 6c 69 74 65 33  >u.iNext<sqlite3
6f10: 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 54 68 72 65  MallocSize(pThre
6f20: 61 64 2d 3e 61 4c 69 73 74 4d 65 6d 6f 72 79 29  ad->aListMemory)
6f30: 20 29 3b 0a 20 20 20 20 20 20 20 20 70 4e 65 78   );.        pNex
6f40: 74 20 3d 20 28 53 6f 72 74 65 72 52 65 63 6f 72  t = (SorterRecor
6f50: 64 2a 29 26 70 54 68 72 65 61 64 2d 3e 61 4c 69  d*)&pThread->aLi
6f60: 73 74 4d 65 6d 6f 72 79 5b 70 2d 3e 75 2e 69 4e  stMemory[p->u.iN
6f70: 65 78 74 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20  ext];.      }.  
6f80: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70    }else{.      p
6f90: 4e 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78  Next = p->u.pNex
6fa0: 74 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 2d  t;.    }..    p-
6fb0: 3e 75 2e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20  >u.pNext = 0;.  
6fc0: 20 20 66 6f 72 28 69 3d 30 3b 20 61 53 6c 6f 74    for(i=0; aSlot
6fd0: 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  [i]; i++){.     
6fe0: 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65   vdbeSorterMerge
6ff0: 28 70 54 68 72 65 61 64 2c 20 70 2c 20 61 53 6c  (pThread, p, aSl
7000: 6f 74 5b 69 5d 2c 20 26 70 29 3b 0a 20 20 20 20  ot[i], &p);.    
7010: 20 20 61 53 6c 6f 74 5b 69 5d 20 3d 20 30 3b 0a    aSlot[i] = 0;.
7020: 20 20 20 20 7d 0a 20 20 20 20 61 53 6c 6f 74 5b      }.    aSlot[
7030: 69 5d 20 3d 20 70 3b 0a 20 20 20 20 70 20 3d 20  i] = p;.    p = 
7040: 70 4e 65 78 74 3b 0a 20 20 7d 0a 0a 20 20 70 20  pNext;.  }..  p 
7050: 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  = 0;.  for(i=0; 
7060: 69 3c 36 34 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  i<64; i++){.    
7070: 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28  vdbeSorterMerge(
7080: 70 54 68 72 65 61 64 2c 20 70 2c 20 61 53 6c 6f  pThread, p, aSlo
7090: 74 5b 69 5d 2c 20 26 70 29 3b 0a 20 20 7d 0a 20  t[i], &p);.  }. 
70a0: 20 70 54 68 72 65 61 64 2d 3e 70 4c 69 73 74 20   pThread->pList 
70b0: 3d 20 70 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f  = p;..  sqlite3_
70c0: 66 72 65 65 28 61 53 6c 6f 74 29 3b 0a 20 20 72  free(aSlot);.  r
70d0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
70e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61  .}../*.** Initia
70f0: 6c 69 7a 65 20 61 20 66 69 6c 65 2d 77 72 69 74  lize a file-writ
7100: 65 72 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74  er object..*/.st
7110: 61 74 69 63 20 76 6f 69 64 20 66 69 6c 65 57 72  atic void fileWr
7120: 69 74 65 72 49 6e 69 74 28 0a 20 20 73 71 6c 69  iterInit(.  sqli
7130: 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c  te3_file *pFile,
7140: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
7150: 69 6c 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20  ile to write to 
7160: 2a 2f 0a 20 20 46 69 6c 65 57 72 69 74 65 72 20  */.  FileWriter 
7170: 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  *p,             
7180: 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63 74 20 74       /* Object t
7190: 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f 0a 20 20  o populate */.  
71a0: 69 6e 74 20 6e 42 75 66 2c 20 20 20 20 20 20 20  int nBuf,       
71b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
71c0: 2f 2a 20 42 75 66 66 65 72 20 73 69 7a 65 20 2a  /* Buffer size *
71d0: 2f 0a 20 20 69 36 34 20 69 53 74 61 72 74 20 20  /.  i64 iStart  
71e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
71f0: 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 6f 66      /* Offset of
7200: 20 70 46 69 6c 65 20 74 6f 20 62 65 67 69 6e 20   pFile to begin 
7210: 77 72 69 74 69 6e 67 20 61 74 20 2a 2f 0a 29 7b  writing at */.){
7220: 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20  .  memset(p, 0, 
7230: 73 69 7a 65 6f 66 28 46 69 6c 65 57 72 69 74 65  sizeof(FileWrite
7240: 72 29 29 3b 0a 20 20 70 2d 3e 61 42 75 66 66 65  r));.  p->aBuffe
7250: 72 20 3d 20 28 75 38 2a 29 73 71 6c 69 74 65 33  r = (u8*)sqlite3
7260: 4d 61 6c 6c 6f 63 28 6e 42 75 66 29 3b 0a 20 20  Malloc(nBuf);.  
7270: 69 66 28 20 21 70 2d 3e 61 42 75 66 66 65 72 20  if( !p->aBuffer 
7280: 29 7b 0a 20 20 20 20 70 2d 3e 65 46 57 45 72 72  ){.    p->eFWErr
7290: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
72a0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 2d  .  }else{.    p-
72b0: 3e 69 42 75 66 45 6e 64 20 3d 20 70 2d 3e 69 42  >iBufEnd = p->iB
72c0: 75 66 53 74 61 72 74 20 3d 20 28 69 53 74 61 72  ufStart = (iStar
72d0: 74 20 25 20 6e 42 75 66 29 3b 0a 20 20 20 20 70  t % nBuf);.    p
72e0: 2d 3e 69 57 72 69 74 65 4f 66 66 20 3d 20 69 53  ->iWriteOff = iS
72f0: 74 61 72 74 20 2d 20 70 2d 3e 69 42 75 66 53 74  tart - p->iBufSt
7300: 61 72 74 3b 0a 20 20 20 20 70 2d 3e 6e 42 75 66  art;.    p->nBuf
7310: 66 65 72 20 3d 20 6e 42 75 66 3b 0a 20 20 20 20  fer = nBuf;.    
7320: 70 2d 3e 70 46 69 6c 65 20 3d 20 70 46 69 6c 65  p->pFile = pFile
7330: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57  ;.  }.}../*.** W
7340: 72 69 74 65 20 6e 44 61 74 61 20 62 79 74 65 73  rite nData bytes
7350: 20 6f 66 20 64 61 74 61 20 74 6f 20 74 68 65 20   of data to the 
7360: 66 69 6c 65 2d 77 72 69 74 65 20 6f 62 6a 65 63  file-write objec
7370: 74 2e 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45  t. Return SQLITE
7380: 5f 4f 4b 0a 2a 2a 20 69 66 20 73 75 63 63 65 73  _OK.** if succes
7390: 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69  sful, or an SQLi
73a0: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66  te error code if
73b0: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
73c0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
73d0: 20 66 69 6c 65 57 72 69 74 65 72 57 72 69 74 65   fileWriterWrite
73e0: 28 46 69 6c 65 57 72 69 74 65 72 20 2a 70 2c 20  (FileWriter *p, 
73f0: 75 38 20 2a 70 44 61 74 61 2c 20 69 6e 74 20 6e  u8 *pData, int n
7400: 44 61 74 61 29 7b 0a 20 20 69 6e 74 20 6e 52 65  Data){.  int nRe
7410: 6d 20 3d 20 6e 44 61 74 61 3b 0a 20 20 77 68 69  m = nData;.  whi
7420: 6c 65 28 20 6e 52 65 6d 3e 30 20 26 26 20 70 2d  le( nRem>0 && p-
7430: 3e 65 46 57 45 72 72 3d 3d 30 20 29 7b 0a 20 20  >eFWErr==0 ){.  
7440: 20 20 69 6e 74 20 6e 43 6f 70 79 20 3d 20 6e 52    int nCopy = nR
7450: 65 6d 3b 0a 20 20 20 20 69 66 28 20 6e 43 6f 70  em;.    if( nCop
7460: 79 3e 28 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20  y>(p->nBuffer - 
7470: 70 2d 3e 69 42 75 66 45 6e 64 29 20 29 7b 0a 20  p->iBufEnd) ){. 
7480: 20 20 20 20 20 6e 43 6f 70 79 20 3d 20 70 2d 3e       nCopy = p->
7490: 6e 42 75 66 66 65 72 20 2d 20 70 2d 3e 69 42 75  nBuffer - p->iBu
74a0: 66 45 6e 64 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  fEnd;.    }..   
74b0: 20 6d 65 6d 63 70 79 28 26 70 2d 3e 61 42 75 66   memcpy(&p->aBuf
74c0: 66 65 72 5b 70 2d 3e 69 42 75 66 45 6e 64 5d 2c  fer[p->iBufEnd],
74d0: 20 26 70 44 61 74 61 5b 6e 44 61 74 61 2d 6e 52   &pData[nData-nR
74e0: 65 6d 5d 2c 20 6e 43 6f 70 79 29 3b 0a 20 20 20  em], nCopy);.   
74f0: 20 70 2d 3e 69 42 75 66 45 6e 64 20 2b 3d 20 6e   p->iBufEnd += n
7500: 43 6f 70 79 3b 0a 20 20 20 20 69 66 28 20 70 2d  Copy;.    if( p-
7510: 3e 69 42 75 66 45 6e 64 3d 3d 70 2d 3e 6e 42 75  >iBufEnd==p->nBu
7520: 66 66 65 72 20 29 7b 0a 20 20 20 20 20 20 70 2d  ffer ){.      p-
7530: 3e 65 46 57 45 72 72 20 3d 20 73 71 6c 69 74 65  >eFWErr = sqlite
7540: 33 4f 73 57 72 69 74 65 28 70 2d 3e 70 46 69 6c  3OsWrite(p->pFil
7550: 65 2c 20 0a 20 20 20 20 20 20 20 20 20 20 26 70  e, .          &p
7560: 2d 3e 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75  ->aBuffer[p->iBu
7570: 66 53 74 61 72 74 5d 2c 20 70 2d 3e 69 42 75 66  fStart], p->iBuf
7580: 45 6e 64 20 2d 20 70 2d 3e 69 42 75 66 53 74 61  End - p->iBufSta
7590: 72 74 2c 20 0a 20 20 20 20 20 20 20 20 20 20 70  rt, .          p
75a0: 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b 20 70 2d  ->iWriteOff + p-
75b0: 3e 69 42 75 66 53 74 61 72 74 0a 20 20 20 20 20  >iBufStart.     
75c0: 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e 69 42 75   );.      p->iBu
75d0: 66 53 74 61 72 74 20 3d 20 70 2d 3e 69 42 75 66  fStart = p->iBuf
75e0: 45 6e 64 20 3d 20 30 3b 0a 20 20 20 20 20 20 70  End = 0;.      p
75f0: 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b 3d 20 70  ->iWriteOff += p
7600: 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20 20 7d  ->nBuffer;.    }
7610: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e  .    assert( p->
7620: 69 42 75 66 45 6e 64 3c 70 2d 3e 6e 42 75 66 66  iBufEnd<p->nBuff
7630: 65 72 20 29 3b 0a 0a 20 20 20 20 6e 52 65 6d 20  er );..    nRem 
7640: 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20 7d 0a 7d 0a  -= nCopy;.  }.}.
7650: 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68 20 61 6e 79  ./*.** Flush any
7660: 20 62 75 66 66 65 72 65 64 20 64 61 74 61 20 74   buffered data t
7670: 6f 20 64 69 73 6b 20 61 6e 64 20 63 6c 65 61 6e  o disk and clean
7680: 20 75 70 20 74 68 65 20 66 69 6c 65 2d 77 72 69   up the file-wri
7690: 74 65 72 20 6f 62 6a 65 63 74 2e 0a 2a 2a 20 54  ter object..** T
76a0: 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20 75 73  he results of us
76b0: 69 6e 67 20 74 68 65 20 66 69 6c 65 2d 77 72 69  ing the file-wri
76c0: 74 65 72 20 61 66 74 65 72 20 74 68 69 73 20 63  ter after this c
76d0: 61 6c 6c 20 61 72 65 20 75 6e 64 65 66 69 6e 65  all are undefine
76e0: 64 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 53 51 4c  d..** Return SQL
76f0: 49 54 45 5f 4f 4b 20 69 66 20 66 6c 75 73 68 69  ITE_OK if flushi
7700: 6e 67 20 74 68 65 20 62 75 66 66 65 72 65 64 20  ng the buffered 
7710: 64 61 74 61 20 73 75 63 63 65 65 64 73 20 6f 72  data succeeds or
7720: 20 69 73 20 6e 6f 74 20 0a 2a 2a 20 72 65 71 75   is not .** requ
7730: 69 72 65 64 2e 20 4f 74 68 65 72 77 69 73 65 2c  ired. Otherwise,
7740: 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74   return an SQLit
7750: 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a  e error code..**
7760: 0a 2a 2a 20 42 65 66 6f 72 65 20 72 65 74 75 72  .** Before retur
7770: 6e 69 6e 67 2c 20 73 65 74 20 2a 70 69 45 6f 66  ning, set *piEof
7780: 20 74 6f 20 74 68 65 20 6f 66 66 73 65 74 20 69   to the offset i
7790: 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f  mmediately follo
77a0: 77 69 6e 67 20 74 68 65 0a 2a 2a 20 6c 61 73 74  wing the.** last
77b0: 20 62 79 74 65 20 77 72 69 74 74 65 6e 20 74 6f   byte written to
77c0: 20 74 68 65 20 66 69 6c 65 2e 0a 2a 2f 0a 73 74   the file..*/.st
77d0: 61 74 69 63 20 69 6e 74 20 66 69 6c 65 57 72 69  atic int fileWri
77e0: 74 65 72 46 69 6e 69 73 68 28 46 69 6c 65 57 72  terFinish(FileWr
77f0: 69 74 65 72 20 2a 70 2c 20 69 36 34 20 2a 70 69  iter *p, i64 *pi
7800: 45 6f 66 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  Eof){.  int rc;.
7810: 20 20 69 66 28 20 70 2d 3e 65 46 57 45 72 72 3d    if( p->eFWErr=
7820: 3d 30 20 26 26 20 41 4c 57 41 59 53 28 70 2d 3e  =0 && ALWAYS(p->
7830: 61 42 75 66 66 65 72 29 20 26 26 20 70 2d 3e 69  aBuffer) && p->i
7840: 42 75 66 45 6e 64 3e 70 2d 3e 69 42 75 66 53 74  BufEnd>p->iBufSt
7850: 61 72 74 20 29 7b 0a 20 20 20 20 70 2d 3e 65 46  art ){.    p->eF
7860: 57 45 72 72 20 3d 20 73 71 6c 69 74 65 33 4f 73  WErr = sqlite3Os
7870: 57 72 69 74 65 28 70 2d 3e 70 46 69 6c 65 2c 20  Write(p->pFile, 
7880: 0a 20 20 20 20 20 20 20 20 26 70 2d 3e 61 42 75  .        &p->aBu
7890: 66 66 65 72 5b 70 2d 3e 69 42 75 66 53 74 61 72  ffer[p->iBufStar
78a0: 74 5d 2c 20 70 2d 3e 69 42 75 66 45 6e 64 20 2d  t], p->iBufEnd -
78b0: 20 70 2d 3e 69 42 75 66 53 74 61 72 74 2c 20 0a   p->iBufStart, .
78c0: 20 20 20 20 20 20 20 20 70 2d 3e 69 57 72 69 74          p->iWrit
78d0: 65 4f 66 66 20 2b 20 70 2d 3e 69 42 75 66 53 74  eOff + p->iBufSt
78e0: 61 72 74 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 20  art.    );.  }. 
78f0: 20 2a 70 69 45 6f 66 20 3d 20 28 70 2d 3e 69 57   *piEof = (p->iW
7900: 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42 75  riteOff + p->iBu
7910: 66 45 6e 64 29 3b 0a 20 20 73 71 6c 69 74 65 33  fEnd);.  sqlite3
7920: 5f 66 72 65 65 28 70 2d 3e 61 42 75 66 66 65 72  _free(p->aBuffer
7930: 29 3b 0a 20 20 72 63 20 3d 20 70 2d 3e 65 46 57  );.  rc = p->eFW
7940: 45 72 72 3b 0a 20 20 6d 65 6d 73 65 74 28 70 2c  Err;.  memset(p,
7950: 20 30 2c 20 73 69 7a 65 6f 66 28 46 69 6c 65 57   0, sizeof(FileW
7960: 72 69 74 65 72 29 29 3b 0a 20 20 72 65 74 75 72  riter));.  retur
7970: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57  n rc;.}../*.** W
7980: 72 69 74 65 20 76 61 6c 75 65 20 69 56 61 6c 20  rite value iVal 
7990: 65 6e 63 6f 64 65 64 20 61 73 20 61 20 76 61 72  encoded as a var
79a0: 69 6e 74 20 74 6f 20 74 68 65 20 66 69 6c 65 2d  int to the file-
79b0: 77 72 69 74 65 20 6f 62 6a 65 63 74 2e 20 52 65  write object. Re
79c0: 74 75 72 6e 20 0a 2a 2a 20 53 51 4c 49 54 45 5f  turn .** SQLITE_
79d0: 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  OK if successful
79e0: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65  , or an SQLite e
79f0: 72 72 6f 72 20 63 6f 64 65 20 69 66 20 61 6e 20  rror code if an 
7a00: 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f  error occurs..*/
7a10: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 69 6c  .static void fil
7a20: 65 57 72 69 74 65 72 57 72 69 74 65 56 61 72 69  eWriterWriteVari
7a30: 6e 74 28 46 69 6c 65 57 72 69 74 65 72 20 2a 70  nt(FileWriter *p
7a40: 2c 20 75 36 34 20 69 56 61 6c 29 7b 0a 20 20 69  , u64 iVal){.  i
7a50: 6e 74 20 6e 42 79 74 65 3b 20 0a 20 20 75 38 20  nt nByte; .  u8 
7a60: 61 42 79 74 65 5b 31 30 5d 3b 0a 20 20 6e 42 79  aByte[10];.  nBy
7a70: 74 65 20 3d 20 73 71 6c 69 74 65 33 50 75 74 56  te = sqlite3PutV
7a80: 61 72 69 6e 74 28 61 42 79 74 65 2c 20 69 56 61  arint(aByte, iVa
7a90: 6c 29 3b 0a 20 20 66 69 6c 65 57 72 69 74 65 72  l);.  fileWriter
7aa0: 57 72 69 74 65 28 70 2c 20 61 42 79 74 65 2c 20  Write(p, aByte, 
7ab0: 6e 42 79 74 65 29 3b 0a 7d 0a 0a 23 69 66 20 53  nByte);.}..#if S
7ac0: 51 4c 49 54 45 5f 4d 41 58 5f 4d 4d 41 50 5f 53  QLITE_MAX_MMAP_S
7ad0: 49 5a 45 3e 30 0a 2f 2a 0a 2a 2a 20 54 68 65 20  IZE>0./*.** The 
7ae0: 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 69  first argument i
7af0: 73 20 61 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20  s a file-handle 
7b00: 6f 70 65 6e 20 6f 6e 20 61 20 74 65 6d 70 6f 72  open on a tempor
7b10: 61 72 79 20 66 69 6c 65 2e 20 54 68 65 20 66 69  ary file. The fi
7b20: 6c 65 0a 2a 2a 20 69 73 20 67 75 61 72 61 6e 74  le.** is guarant
7b30: 65 65 64 20 74 6f 20 62 65 20 6e 42 79 74 65 20  eed to be nByte 
7b40: 62 79 74 65 73 20 6f 72 20 73 6d 61 6c 6c 65 72  bytes or smaller
7b50: 20 69 6e 20 73 69 7a 65 2e 20 54 68 69 73 20 66   in size. This f
7b60: 75 6e 63 74 69 6f 6e 0a 2a 2a 20 61 74 74 65 6d  unction.** attem
7b70: 70 74 73 20 74 6f 20 65 78 74 65 6e 64 20 74 68  pts to extend th
7b80: 65 20 66 69 6c 65 20 74 6f 20 6e 42 79 74 65 20  e file to nByte 
7b90: 62 79 74 65 73 20 69 6e 20 73 69 7a 65 20 61 6e  bytes in size an
7ba0: 64 20 74 6f 20 65 6e 73 75 72 65 20 74 68 61 74  d to ensure that
7bb0: 0a 2a 2a 20 74 68 65 20 56 46 53 20 68 61 73 20  .** the VFS has 
7bc0: 6d 65 6d 6f 72 79 20 6d 61 70 70 65 64 20 69 74  memory mapped it
7bd0: 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 74 68 65 72 20  ..**.** Whether 
7be0: 6f 72 20 6e 6f 74 20 74 68 65 20 66 69 6c 65 20  or not the file 
7bf0: 64 6f 65 73 20 65 6e 64 20 75 70 20 6d 65 6d 6f  does end up memo
7c00: 72 79 20 6d 61 70 70 65 64 20 6f 66 20 63 6f 75  ry mapped of cou
7c10: 72 73 65 20 64 65 70 65 6e 64 73 20 6f 6e 0a 2a  rse depends on.*
7c20: 2a 20 74 68 65 20 73 70 65 63 69 66 69 63 20 56  * the specific V
7c30: 46 53 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  FS implementatio
7c40: 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  n..*/.static int
7c50: 20 76 64 62 65 53 6f 72 74 65 72 45 78 74 65 6e   vdbeSorterExten
7c60: 64 46 69 6c 65 28 73 71 6c 69 74 65 33 5f 66 69  dFile(sqlite3_fi
7c70: 6c 65 20 2a 70 46 69 6c 65 2c 20 69 36 34 20 6e  le *pFile, i64 n
7c80: 42 79 74 65 29 7b 0a 20 20 69 6e 74 20 72 63 20  Byte){.  int rc 
7c90: 3d 20 73 71 6c 69 74 65 33 4f 73 54 72 75 6e 63  = sqlite3OsTrunc
7ca0: 61 74 65 28 70 46 69 6c 65 2c 20 6e 42 79 74 65  ate(pFile, nByte
7cb0: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  );.  if( rc==SQL
7cc0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 6f  ITE_OK ){.    vo
7cd0: 69 64 20 2a 70 20 3d 20 30 3b 0a 20 20 20 20 73  id *p = 0;.    s
7ce0: 71 6c 69 74 65 33 4f 73 46 65 74 63 68 28 70 46  qlite3OsFetch(pF
7cf0: 69 6c 65 2c 20 30 2c 20 6e 42 79 74 65 2c 20 26  ile, 0, nByte, &
7d00: 70 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f  p);.    sqlite3O
7d10: 73 55 6e 66 65 74 63 68 28 70 46 69 6c 65 2c 20  sUnfetch(pFile, 
7d20: 30 2c 20 70 29 3b 0a 20 20 7d 0a 20 20 72 65 74  0, p);.  }.  ret
7d30: 75 72 6e 20 72 63 3b 0a 7d 0a 23 65 6c 73 65 0a  urn rc;.}.#else.
7d40: 23 20 64 65 66 69 6e 65 20 76 64 62 65 53 6f 72  # define vdbeSor
7d50: 74 65 72 45 78 74 65 6e 64 46 69 6c 65 28 78 2c  terExtendFile(x,
7d60: 79 29 20 53 51 4c 49 54 45 5f 4f 4b 0a 23 65 6e  y) SQLITE_OK.#en
7d70: 64 69 66 0a 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74  dif.../*.** Writ
7d80: 65 20 74 68 65 20 63 75 72 72 65 6e 74 20 63 6f  e the current co
7d90: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 69 6e  ntents of the in
7da0: 2d 6d 65 6d 6f 72 79 20 6c 69 6e 6b 65 64 2d 6c  -memory linked-l
7db0: 69 73 74 20 74 6f 20 61 20 50 4d 41 2e 20 52 65  ist to a PMA. Re
7dc0: 74 75 72 6e 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f  turn.** SQLITE_O
7dd0: 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c  K if successful,
7de0: 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72   or an SQLite er
7df0: 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77 69  ror code otherwi
7e00: 73 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66 6f  se..**.** The fo
7e10: 72 6d 61 74 20 6f 66 20 61 20 50 4d 41 20 69 73  rmat of a PMA is
7e20: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 41 20  :.**.**     * A 
7e30: 76 61 72 69 6e 74 2e 20 54 68 69 73 20 76 61 72  varint. This var
7e40: 69 6e 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  int contains the
7e50: 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66   total number of
7e60: 20 62 79 74 65 73 20 6f 66 20 63 6f 6e 74 65 6e   bytes of conten
7e70: 74 0a 2a 2a 20 20 20 20 20 20 20 69 6e 20 74 68  t.**       in th
7e80: 65 20 50 4d 41 20 28 6e 6f 74 20 69 6e 63 6c 75  e PMA (not inclu
7e90: 64 69 6e 67 20 74 68 65 20 76 61 72 69 6e 74 20  ding the varint 
7ea0: 69 74 73 65 6c 66 29 2e 0a 2a 2a 0a 2a 2a 20 20  itself)..**.**  
7eb0: 20 20 20 2a 20 4f 6e 65 20 6f 72 20 6d 6f 72 65     * One or more
7ec0: 20 72 65 63 6f 72 64 73 20 70 61 63 6b 65 64 20   records packed 
7ed0: 65 6e 64 2d 74 6f 2d 65 6e 64 20 69 6e 20 6f 72  end-to-end in or
7ee0: 64 65 72 20 6f 66 20 61 73 63 65 6e 64 69 6e 67  der of ascending
7ef0: 20 6b 65 79 73 2e 20 0a 2a 2a 20 20 20 20 20 20   keys. .**      
7f00: 20 45 61 63 68 20 72 65 63 6f 72 64 20 63 6f 6e   Each record con
7f10: 73 69 73 74 73 20 6f 66 20 61 20 76 61 72 69 6e  sists of a varin
7f20: 74 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 61 20  t followed by a 
7f30: 62 6c 6f 62 20 6f 66 20 64 61 74 61 20 28 74 68  blob of data (th
7f40: 65 20 0a 2a 2a 20 20 20 20 20 20 20 6b 65 79 29  e .**       key)
7f50: 2e 20 54 68 65 20 76 61 72 69 6e 74 20 69 73 20  . The varint is 
7f60: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79  the number of by
7f70: 74 65 73 20 69 6e 20 74 68 65 20 62 6c 6f 62 20  tes in the blob 
7f80: 6f 66 20 64 61 74 61 2e 0a 2a 2f 0a 73 74 61 74  of data..*/.stat
7f90: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
7fa0: 72 4c 69 73 74 54 6f 50 4d 41 28 53 6f 72 74 65  rListToPMA(Sorte
7fb0: 72 54 68 72 65 61 64 20 2a 70 54 68 72 65 61 64  rThread *pThread
7fc0: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
7fd0: 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20  LITE_OK;        
7fe0: 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
7ff0: 6f 64 65 20 2a 2f 0a 20 20 46 69 6c 65 57 72 69  ode */.  FileWri
8000: 74 65 72 20 77 72 69 74 65 72 3b 20 20 20 20 20  ter writer;     
8010: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65           /* Obje
8020: 63 74 20 75 73 65 64 20 74 6f 20 77 72 69 74 65  ct used to write
8030: 20 74 6f 20 74 68 65 20 66 69 6c 65 20 2a 2f 0a   to the file */.
8040: 0a 20 20 6d 65 6d 73 65 74 28 26 77 72 69 74 65  .  memset(&write
8050: 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 46 69 6c  r, 0, sizeof(Fil
8060: 65 57 72 69 74 65 72 29 29 3b 0a 20 20 61 73 73  eWriter));.  ass
8070: 65 72 74 28 20 70 54 68 72 65 61 64 2d 3e 6e 49  ert( pThread->nI
8080: 6e 4d 65 6d 6f 72 79 3e 30 20 29 3b 0a 0a 20 20  nMemory>0 );..  
8090: 2f 2a 20 49 66 20 74 68 65 20 66 69 72 73 74 20  /* If the first 
80a0: 74 65 6d 70 6f 72 61 72 79 20 50 4d 41 20 66 69  temporary PMA fi
80b0: 6c 65 20 68 61 73 20 6e 6f 74 20 62 65 65 6e 20  le has not been 
80c0: 6f 70 65 6e 65 64 2c 20 6f 70 65 6e 20 69 74 20  opened, open it 
80d0: 6e 6f 77 2e 20 2a 2f 0a 20 20 69 66 28 20 70 54  now. */.  if( pT
80e0: 68 72 65 61 64 2d 3e 70 54 65 6d 70 31 3d 3d 30  hread->pTemp1==0
80f0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62   ){.    rc = vdb
8100: 65 53 6f 72 74 65 72 4f 70 65 6e 54 65 6d 70 46  eSorterOpenTempF
8110: 69 6c 65 28 70 54 68 72 65 61 64 2d 3e 70 56 66  ile(pThread->pVf
8120: 73 2c 20 26 70 54 68 72 65 61 64 2d 3e 70 54 65  s, &pThread->pTe
8130: 6d 70 31 29 3b 0a 20 20 20 20 61 73 73 65 72 74  mp1);.    assert
8140: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
8150: 7c 7c 20 70 54 68 72 65 61 64 2d 3e 70 54 65 6d  || pThread->pTem
8160: 70 31 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  p1 );.    assert
8170: 28 20 70 54 68 72 65 61 64 2d 3e 69 54 65 6d 70  ( pThread->iTemp
8180: 31 4f 66 66 3d 3d 30 20 29 3b 0a 20 20 20 20 61  1Off==0 );.    a
8190: 73 73 65 72 74 28 20 70 54 68 72 65 61 64 2d 3e  ssert( pThread->
81a0: 6e 50 4d 41 3d 3d 30 20 29 3b 0a 20 20 7d 0a 0a  nPMA==0 );.  }..
81b0: 20 20 2f 2a 20 54 72 79 20 74 6f 20 67 65 74 20    /* Try to get 
81c0: 74 68 65 20 66 69 6c 65 20 74 6f 20 6d 65 6d 6f  the file to memo
81d0: 72 79 20 6d 61 70 20 2a 2f 0a 20 20 69 66 28 20  ry map */.  if( 
81e0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
81f0: 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f  .    rc = vdbeSo
8200: 72 74 65 72 45 78 74 65 6e 64 46 69 6c 65 28 0a  rterExtendFile(.
8210: 20 20 20 20 20 20 20 20 70 54 68 72 65 61 64 2d          pThread-
8220: 3e 70 54 65 6d 70 31 2c 20 70 54 68 72 65 61 64  >pTemp1, pThread
8230: 2d 3e 69 54 65 6d 70 31 4f 66 66 20 2b 20 70 54  ->iTemp1Off + pT
8240: 68 72 65 61 64 2d 3e 6e 49 6e 4d 65 6d 6f 72 79  hread->nInMemory
8250: 20 2b 20 39 0a 20 20 20 20 29 3b 0a 20 20 7d 0a   + 9.    );.  }.
8260: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
8270: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 53 6f 72 74  E_OK ){.    Sort
8280: 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a 20 20 20  erRecord *p;.   
8290: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
82a0: 4e 65 78 74 20 3d 20 30 3b 0a 0a 20 20 20 20 66  Next = 0;..    f
82b0: 69 6c 65 57 72 69 74 65 72 49 6e 69 74 28 70 54  ileWriterInit(pT
82c0: 68 72 65 61 64 2d 3e 70 54 65 6d 70 31 2c 20 26  hread->pTemp1, &
82d0: 77 72 69 74 65 72 2c 20 70 54 68 72 65 61 64 2d  writer, pThread-
82e0: 3e 70 67 73 7a 2c 20 70 54 68 72 65 61 64 2d 3e  >pgsz, pThread->
82f0: 69 54 65 6d 70 31 4f 66 66 29 3b 0a 20 20 20 20  iTemp1Off);.    
8300: 70 54 68 72 65 61 64 2d 3e 6e 50 4d 41 2b 2b 3b  pThread->nPMA++;
8310: 0a 20 20 20 20 66 69 6c 65 57 72 69 74 65 72 57  .    fileWriterW
8320: 72 69 74 65 56 61 72 69 6e 74 28 26 77 72 69 74  riteVarint(&writ
8330: 65 72 2c 20 70 54 68 72 65 61 64 2d 3e 6e 49 6e  er, pThread->nIn
8340: 4d 65 6d 6f 72 79 29 3b 0a 20 20 20 20 66 6f 72  Memory);.    for
8350: 28 70 3d 70 54 68 72 65 61 64 2d 3e 70 4c 69 73  (p=pThread->pLis
8360: 74 3b 20 70 3b 20 70 3d 70 4e 65 78 74 29 7b 0a  t; p; p=pNext){.
8370: 20 20 20 20 20 20 70 4e 65 78 74 20 3d 20 70 2d        pNext = p-
8380: 3e 75 2e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  >u.pNext;.      
8390: 66 69 6c 65 57 72 69 74 65 72 57 72 69 74 65 56  fileWriterWriteV
83a0: 61 72 69 6e 74 28 26 77 72 69 74 65 72 2c 20 70  arint(&writer, p
83b0: 2d 3e 6e 56 61 6c 29 3b 0a 20 20 20 20 20 20 66  ->nVal);.      f
83c0: 69 6c 65 57 72 69 74 65 72 57 72 69 74 65 28 26  ileWriterWrite(&
83d0: 77 72 69 74 65 72 2c 20 53 52 56 41 4c 28 70 29  writer, SRVAL(p)
83e0: 2c 20 70 2d 3e 6e 56 61 6c 29 3b 0a 20 20 20 20  , p->nVal);.    
83f0: 20 20 69 66 28 20 70 54 68 72 65 61 64 2d 3e 61    if( pThread->a
8400: 4c 69 73 74 4d 65 6d 6f 72 79 3d 3d 30 20 29 20  ListMemory==0 ) 
8410: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b  sqlite3_free(p);
8420: 0a 20 20 20 20 7d 0a 20 20 20 20 70 54 68 72 65  .    }.    pThre
8430: 61 64 2d 3e 70 4c 69 73 74 20 3d 20 70 3b 0a 20  ad->pList = p;. 
8440: 20 20 20 72 63 20 3d 20 66 69 6c 65 57 72 69 74     rc = fileWrit
8450: 65 72 46 69 6e 69 73 68 28 26 77 72 69 74 65 72  erFinish(&writer
8460: 2c 20 26 70 54 68 72 65 61 64 2d 3e 69 54 65 6d  , &pThread->iTem
8470: 70 31 4f 66 66 29 3b 0a 20 20 7d 0a 0a 20 20 61  p1Off);.  }..  a
8480: 73 73 65 72 74 28 20 70 54 68 72 65 61 64 2d 3e  ssert( pThread->
8490: 70 4c 69 73 74 3d 3d 30 20 7c 7c 20 72 63 21 3d  pList==0 || rc!=
84a0: 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72  SQLITE_OK );.  r
84b0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
84c0: 2a 2a 20 41 64 76 61 6e 63 65 20 74 68 65 20 53  ** Advance the S
84d0: 6f 72 74 65 72 4d 65 72 67 65 72 20 69 74 65 72  orterMerger iter
84e0: 61 74 6f 72 20 70 61 73 73 65 64 20 61 73 20 74  ator passed as t
84f0: 68 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65  he second argume
8500: 6e 74 20 74 6f 0a 2a 2a 20 74 68 65 20 6e 65 78  nt to.** the nex
8510: 74 20 65 6e 74 72 79 2e 20 53 65 74 20 2a 70 62  t entry. Set *pb
8520: 45 6f 66 20 74 6f 20 74 72 75 65 20 69 66 20 74  Eof to true if t
8530: 68 69 73 20 6d 65 61 6e 73 20 74 68 65 20 69 74  his means the it
8540: 65 72 61 74 6f 72 20 68 61 73 20 0a 2a 2a 20 72  erator has .** r
8550: 65 61 63 68 65 64 20 45 4f 46 2e 0a 2a 2a 0a 2a  eached EOF..**.*
8560: 2a 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  * Return SQLITE_
8570: 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  OK if successful
8580: 20 6f 72 20 61 6e 20 65 72 72 6f 72 20 63 6f 64   or an error cod
8590: 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  e if an error oc
85a0: 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  curs..*/.static 
85b0: 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72 4e 65  int vdbeSorterNe
85c0: 78 74 28 0a 20 20 53 6f 72 74 65 72 54 68 72 65  xt(.  SorterThre
85d0: 61 64 20 2a 70 54 68 72 65 61 64 2c 20 0a 20 20  ad *pThread, .  
85e0: 53 6f 72 74 65 72 4d 65 72 67 65 72 20 2a 70 4d  SorterMerger *pM
85f0: 65 72 67 65 72 2c 20 0a 20 20 69 6e 74 20 2a 70  erger, .  int *p
8600: 62 45 6f 66 0a 29 7b 0a 20 20 69 6e 74 20 72 63  bEof.){.  int rc
8610: 3b 0a 20 20 69 6e 74 20 69 50 72 65 76 20 3d 20  ;.  int iPrev = 
8620: 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 31  pMerger->aTree[1
8630: 5d 3b 2f 2a 20 49 6e 64 65 78 20 6f 66 20 69 74  ];/* Index of it
8640: 65 72 61 74 6f 72 20 74 6f 20 61 64 76 61 6e 63  erator to advanc
8650: 65 20 2a 2f 0a 0a 20 20 2f 2a 20 41 64 76 61 6e  e */..  /* Advan
8660: 63 65 20 74 68 65 20 63 75 72 72 65 6e 74 20 69  ce the current i
8670: 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 72 63 20  terator */.  rc 
8680: 3d 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72  = vdbeSorterIter
8690: 4e 65 78 74 28 26 70 4d 65 72 67 65 72 2d 3e 61  Next(&pMerger->a
86a0: 49 74 65 72 5b 69 50 72 65 76 5d 29 3b 0a 0a 20  Iter[iPrev]);.. 
86b0: 20 2f 2a 20 55 70 64 61 74 65 20 63 6f 6e 74 65   /* Update conte
86c0: 6e 74 73 20 6f 66 20 61 54 72 65 65 5b 5d 20 2a  nts of aTree[] *
86d0: 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  /.  if( rc==SQLI
86e0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74  TE_OK ){.    int
86f0: 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
8700: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65           /* Inde
8710: 78 20 6f 66 20 61 54 72 65 65 5b 5d 20 74 6f 20  x of aTree[] to 
8720: 72 65 63 61 6c 63 75 6c 61 74 65 20 2a 2f 0a 20  recalculate */. 
8730: 20 20 20 56 64 62 65 53 6f 72 74 65 72 49 74 65     VdbeSorterIte
8740: 72 20 2a 70 49 74 65 72 31 3b 20 20 20 20 20 2f  r *pIter1;     /
8750: 2a 20 46 69 72 73 74 20 69 74 65 72 61 74 6f 72  * First iterator
8760: 20 74 6f 20 63 6f 6d 70 61 72 65 20 2a 2f 0a 20   to compare */. 
8770: 20 20 20 56 64 62 65 53 6f 72 74 65 72 49 74 65     VdbeSorterIte
8780: 72 20 2a 70 49 74 65 72 32 3b 20 20 20 20 20 2f  r *pIter2;     /
8790: 2a 20 53 65 63 6f 6e 64 20 69 74 65 72 61 74 6f  * Second iterato
87a0: 72 20 74 6f 20 63 6f 6d 70 61 72 65 20 2a 2f 0a  r to compare */.
87b0: 20 20 20 20 75 38 20 2a 70 4b 65 79 32 3b 20 20      u8 *pKey2;  
87c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
87d0: 2f 2a 20 54 6f 20 70 49 74 65 72 32 2d 3e 61 4b  /* To pIter2->aK
87e0: 65 79 2c 20 6f 72 20 30 20 69 66 20 72 65 63 6f  ey, or 0 if reco
87f0: 72 64 20 63 61 63 68 65 64 20 2a 2f 0a 0a 20 20  rd cached */..  
8800: 20 20 2f 2a 20 46 69 6e 64 20 74 68 65 20 66 69    /* Find the fi
8810: 72 73 74 20 74 77 6f 20 69 74 65 72 61 74 6f 72  rst two iterator
8820: 73 20 74 6f 20 63 6f 6d 70 61 72 65 2e 20 54 68  s to compare. Th
8830: 65 20 6f 6e 65 20 74 68 61 74 20 77 61 73 20 6a  e one that was j
8840: 75 73 74 0a 20 20 20 20 2a 2a 20 61 64 76 61 6e  ust.    ** advan
8850: 63 65 64 20 28 69 50 72 65 76 29 20 61 6e 64 20  ced (iPrev) and 
8860: 74 68 65 20 6f 6e 65 20 6e 65 78 74 20 74 6f 20  the one next to 
8870: 69 74 20 69 6e 20 74 68 65 20 61 72 72 61 79 2e  it in the array.
8880: 20 20 2a 2f 0a 20 20 20 20 70 49 74 65 72 31 20    */.    pIter1 
8890: 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65  = &pMerger->aIte
88a0: 72 5b 28 69 50 72 65 76 20 26 20 30 78 46 46 46  r[(iPrev & 0xFFF
88b0: 45 29 5d 3b 0a 20 20 20 20 70 49 74 65 72 32 20  E)];.    pIter2 
88c0: 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65  = &pMerger->aIte
88d0: 72 5b 28 69 50 72 65 76 20 7c 20 30 78 30 30 30  r[(iPrev | 0x000
88e0: 31 29 5d 3b 0a 20 20 20 20 70 4b 65 79 32 20 3d  1)];.    pKey2 =
88f0: 20 70 49 74 65 72 32 2d 3e 61 4b 65 79 3b 0a 0a   pIter2->aKey;..
8900: 20 20 20 20 66 6f 72 28 69 3d 28 70 4d 65 72 67      for(i=(pMerg
8910: 65 72 2d 3e 6e 54 72 65 65 2b 69 50 72 65 76 29  er->nTree+iPrev)
8920: 2f 32 3b 20 69 3e 30 3b 20 69 3d 69 2f 32 29 7b  /2; i>0; i=i/2){
8930: 0a 20 20 20 20 20 20 2f 2a 20 43 6f 6d 70 61 72  .      /* Compar
8940: 65 20 70 49 74 65 72 31 20 61 6e 64 20 70 49 74  e pIter1 and pIt
8950: 65 72 32 2e 20 53 74 6f 72 65 20 74 68 65 20 72  er2. Store the r
8960: 65 73 75 6c 74 20 69 6e 20 76 61 72 69 61 62 6c  esult in variabl
8970: 65 20 69 52 65 73 2e 20 2a 2f 0a 20 20 20 20 20  e iRes. */.     
8980: 20 69 6e 74 20 69 52 65 73 3b 0a 20 20 20 20 20   int iRes;.     
8990: 20 69 66 28 20 70 49 74 65 72 31 2d 3e 70 46 69   if( pIter1->pFi
89a0: 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  le==0 ){.       
89b0: 20 69 52 65 73 20 3d 20 2b 31 3b 0a 20 20 20 20   iRes = +1;.    
89c0: 20 20 7d 65 6c 73 65 20 69 66 28 20 70 49 74 65    }else if( pIte
89d0: 72 32 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a  r2->pFile==0 ){.
89e0: 20 20 20 20 20 20 20 20 69 52 65 73 20 3d 20 2d          iRes = -
89f0: 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  1;.      }else{.
8a00: 20 20 20 20 20 20 20 20 69 52 65 73 20 3d 20 76          iRes = v
8a10: 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65  dbeSorterCompare
8a20: 28 70 54 68 72 65 61 64 2c 20 0a 20 20 20 20 20  (pThread, .     
8a30: 20 20 20 20 20 20 20 70 49 74 65 72 31 2d 3e 61         pIter1->a
8a40: 4b 65 79 2c 20 70 49 74 65 72 31 2d 3e 6e 4b 65  Key, pIter1->nKe
8a50: 79 2c 20 70 4b 65 79 32 2c 20 70 49 74 65 72 32  y, pKey2, pIter2
8a60: 2d 3e 6e 4b 65 79 0a 20 20 20 20 20 20 20 20 29  ->nKey.        )
8a70: 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  ;.      }..     
8a80: 20 2f 2a 20 49 66 20 70 49 74 65 72 31 20 63 6f   /* If pIter1 co
8a90: 6e 74 61 69 6e 65 64 20 74 68 65 20 73 6d 61 6c  ntained the smal
8aa0: 6c 65 72 20 76 61 6c 75 65 2c 20 73 65 74 20 61  ler value, set a
8ab0: 54 72 65 65 5b 69 5d 20 74 6f 20 69 74 73 20 69  Tree[i] to its i
8ac0: 6e 64 65 78 2e 0a 20 20 20 20 20 20 2a 2a 20 54  ndex..      ** T
8ad0: 68 65 6e 20 73 65 74 20 70 49 74 65 72 32 20 74  hen set pIter2 t
8ae0: 6f 20 74 68 65 20 6e 65 78 74 20 69 74 65 72 61  o the next itera
8af0: 74 6f 72 20 74 6f 20 63 6f 6d 70 61 72 65 20 74  tor to compare t
8b00: 6f 20 70 49 74 65 72 31 2e 20 49 6e 20 74 68 69  o pIter1. In thi
8b10: 73 0a 20 20 20 20 20 20 2a 2a 20 63 61 73 65 20  s.      ** case 
8b20: 74 68 65 72 65 20 69 73 20 6e 6f 20 63 61 63 68  there is no cach
8b30: 65 20 6f 66 20 70 49 74 65 72 32 20 69 6e 20 70  e of pIter2 in p
8b40: 54 68 72 65 61 64 2d 3e 70 55 6e 70 61 63 6b 65  Thread->pUnpacke
8b50: 64 2c 20 73 6f 20 73 65 74 0a 20 20 20 20 20 20  d, so set.      
8b60: 2a 2a 20 70 4b 65 79 32 20 74 6f 20 70 6f 69 6e  ** pKey2 to poin
8b70: 74 20 74 6f 20 74 68 65 20 72 65 63 6f 72 64 20  t to the record 
8b80: 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 70 49 74  belonging to pIt
8b90: 65 72 32 2e 0a 20 20 20 20 20 20 2a 2a 0a 20 20  er2..      **.  
8ba0: 20 20 20 20 2a 2a 20 41 6c 74 65 72 6e 61 74 69      ** Alternati
8bb0: 76 65 6c 79 2c 20 69 66 20 70 49 74 65 72 32 20  vely, if pIter2 
8bc0: 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 73 6d 61  contains the sma
8bd0: 6c 6c 65 72 20 6f 66 20 74 68 65 20 74 77 6f 20  ller of the two 
8be0: 76 61 6c 75 65 73 2c 0a 20 20 20 20 20 20 2a 2a  values,.      **
8bf0: 20 73 65 74 20 61 54 72 65 65 5b 69 5d 20 74 6f   set aTree[i] to
8c00: 20 69 74 73 20 69 6e 64 65 78 20 61 6e 64 20 75   its index and u
8c10: 70 64 61 74 65 20 70 49 74 65 72 31 2e 20 49 66  pdate pIter1. If
8c20: 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61   vdbeSorterCompa
8c30: 72 65 28 29 0a 20 20 20 20 20 20 2a 2a 20 77 61  re().      ** wa
8c40: 73 20 61 63 74 75 61 6c 6c 79 20 63 61 6c 6c 65  s actually calle
8c50: 64 20 61 62 6f 76 65 2c 20 74 68 65 6e 20 70 54  d above, then pT
8c60: 68 72 65 61 64 2d 3e 70 55 6e 70 61 63 6b 65 64  hread->pUnpacked
8c70: 20 6e 6f 77 20 63 6f 6e 74 61 69 6e 73 0a 20 20   now contains.  
8c80: 20 20 20 20 2a 2a 20 61 20 76 61 6c 75 65 20 65      ** a value e
8c90: 71 75 69 76 61 6c 65 6e 74 20 74 6f 20 70 49 74  quivalent to pIt
8ca0: 65 72 32 2e 20 53 6f 20 73 65 74 20 70 4b 65 79  er2. So set pKey
8cb0: 32 20 74 6f 20 4e 55 4c 4c 20 74 6f 20 70 72 65  2 to NULL to pre
8cc0: 76 65 6e 74 0a 20 20 20 20 20 20 2a 2a 20 76 64  vent.      ** vd
8cd0: 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28  beSorterCompare(
8ce0: 29 20 66 72 6f 6d 20 64 65 63 6f 64 69 6e 67 20  ) from decoding 
8cf0: 70 49 74 65 72 32 20 61 67 61 69 6e 2e 0a 20 20  pIter2 again..  
8d00: 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20      **.      ** 
8d10: 49 66 20 74 68 65 20 74 77 6f 20 76 61 6c 75 65  If the two value
8d20: 73 20 77 65 72 65 20 65 71 75 61 6c 2c 20 74 68  s were equal, th
8d30: 65 6e 20 74 68 65 20 76 61 6c 75 65 20 66 72 6f  en the value fro
8d40: 6d 20 74 68 65 20 6f 6c 64 65 73 74 0a 20 20 20  m the oldest.   
8d50: 20 20 20 2a 2a 20 50 4d 41 20 73 68 6f 75 6c 64     ** PMA should
8d60: 20 62 65 20 63 6f 6e 73 69 64 65 72 65 64 20 73   be considered s
8d70: 6d 61 6c 6c 65 72 2e 20 54 68 65 20 56 64 62 65  maller. The Vdbe
8d80: 53 6f 72 74 65 72 2e 61 49 74 65 72 5b 5d 20 61  Sorter.aIter[] a
8d90: 72 72 61 79 0a 20 20 20 20 20 20 2a 2a 20 69 73  rray.      ** is
8da0: 20 73 6f 72 74 65 64 20 66 72 6f 6d 20 6f 6c 64   sorted from old
8db0: 65 73 74 20 74 6f 20 6e 65 77 65 73 74 2c 20 73  est to newest, s
8dc0: 6f 20 70 49 74 65 72 31 20 63 6f 6e 74 61 69 6e  o pIter1 contain
8dd0: 73 20 6f 6c 64 65 72 20 76 61 6c 75 65 73 0a 20  s older values. 
8de0: 20 20 20 20 20 2a 2a 20 74 68 61 6e 20 70 49 74       ** than pIt
8df0: 65 72 32 20 69 66 66 20 28 70 49 74 65 72 31 3c  er2 iff (pIter1<
8e00: 70 49 74 65 72 32 29 2e 20 20 2a 2f 0a 20 20 20  pIter2).  */.   
8e10: 20 20 20 69 66 28 20 69 52 65 73 3c 30 20 7c 7c     if( iRes<0 ||
8e20: 20 28 69 52 65 73 3d 3d 30 20 26 26 20 70 49 74   (iRes==0 && pIt
8e30: 65 72 31 3c 70 49 74 65 72 32 29 20 29 7b 0a 20  er1<pIter2) ){. 
8e40: 20 20 20 20 20 20 20 70 4d 65 72 67 65 72 2d 3e         pMerger->
8e50: 61 54 72 65 65 5b 69 5d 20 3d 20 28 69 6e 74 29  aTree[i] = (int)
8e60: 28 70 49 74 65 72 31 20 2d 20 70 4d 65 72 67 65  (pIter1 - pMerge
8e70: 72 2d 3e 61 49 74 65 72 29 3b 0a 20 20 20 20 20  r->aIter);.     
8e80: 20 20 20 70 49 74 65 72 32 20 3d 20 26 70 4d 65     pIter2 = &pMe
8e90: 72 67 65 72 2d 3e 61 49 74 65 72 5b 20 70 4d 65  rger->aIter[ pMe
8ea0: 72 67 65 72 2d 3e 61 54 72 65 65 5b 69 20 5e 20  rger->aTree[i ^ 
8eb0: 30 78 30 30 30 31 5d 20 5d 3b 0a 20 20 20 20 20  0x0001] ];.     
8ec0: 20 20 20 70 4b 65 79 32 20 3d 20 70 49 74 65 72     pKey2 = pIter
8ed0: 32 2d 3e 61 4b 65 79 3b 0a 20 20 20 20 20 20 7d  2->aKey;.      }
8ee0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69 66  else{.        if
8ef0: 28 20 70 49 74 65 72 31 2d 3e 70 46 69 6c 65 20  ( pIter1->pFile 
8f00: 29 20 70 4b 65 79 32 20 3d 20 30 3b 0a 20 20 20  ) pKey2 = 0;.   
8f10: 20 20 20 20 20 70 4d 65 72 67 65 72 2d 3e 61 54       pMerger->aT
8f20: 72 65 65 5b 69 5d 20 3d 20 28 69 6e 74 29 28 70  ree[i] = (int)(p
8f30: 49 74 65 72 32 20 2d 20 70 4d 65 72 67 65 72 2d  Iter2 - pMerger-
8f40: 3e 61 49 74 65 72 29 3b 0a 20 20 20 20 20 20 20  >aIter);.       
8f50: 20 70 49 74 65 72 31 20 3d 20 26 70 4d 65 72 67   pIter1 = &pMerg
8f60: 65 72 2d 3e 61 49 74 65 72 5b 20 70 4d 65 72 67  er->aIter[ pMerg
8f70: 65 72 2d 3e 61 54 72 65 65 5b 69 20 5e 20 30 78  er->aTree[i ^ 0x
8f80: 30 30 30 31 5d 20 5d 3b 0a 20 20 20 20 20 20 7d  0001] ];.      }
8f90: 0a 20 20 20 20 7d 0a 20 20 20 20 2a 70 62 45 6f  .    }.    *pbEo
8fa0: 66 20 3d 20 28 70 4d 65 72 67 65 72 2d 3e 61 49  f = (pMerger->aI
8fb0: 74 65 72 5b 70 4d 65 72 67 65 72 2d 3e 61 54 72  ter[pMerger->aTr
8fc0: 65 65 5b 31 5d 5d 2e 70 46 69 6c 65 3d 3d 30 29  ee[1]].pFile==0)
8fd0: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
8fe0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65  rc;.}../*.** The
8ff0: 20 6d 61 69 6e 20 72 6f 75 74 69 6e 65 20 66 6f   main routine fo
9000: 72 20 73 6f 72 74 65 72 2d 74 68 72 65 61 64 20  r sorter-thread 
9010: 6f 70 65 72 61 74 69 6f 6e 73 2e 0a 2a 2f 0a 73  operations..*/.s
9020: 74 61 74 69 63 20 76 6f 69 64 20 2a 76 64 62 65  tatic void *vdbe
9030: 53 6f 72 74 65 72 54 68 72 65 61 64 4d 61 69 6e  SorterThreadMain
9040: 28 76 6f 69 64 20 2a 70 43 74 78 29 7b 0a 20 20  (void *pCtx){.  
9050: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
9060: 4f 4b 3b 0a 20 20 53 6f 72 74 65 72 54 68 72 65  OK;.  SorterThre
9070: 61 64 20 2a 70 54 68 72 65 61 64 20 3d 20 28 53  ad *pThread = (S
9080: 6f 72 74 65 72 54 68 72 65 61 64 2a 29 70 43 74  orterThread*)pCt
9090: 78 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 54  x;..  assert( pT
90a0: 68 72 65 61 64 2d 3e 65 57 6f 72 6b 3d 3d 53 4f  hread->eWork==SO
90b0: 52 54 45 52 5f 54 48 52 45 41 44 5f 53 4f 52 54  RTER_THREAD_SORT
90c0: 0a 20 20 20 20 20 20 20 7c 7c 20 70 54 68 72 65  .       || pThre
90d0: 61 64 2d 3e 65 57 6f 72 6b 3d 3d 53 4f 52 54 45  ad->eWork==SORTE
90e0: 52 5f 54 48 52 45 41 44 5f 54 4f 5f 50 4d 41 0a  R_THREAD_TO_PMA.
90f0: 20 20 20 20 20 20 20 7c 7c 20 70 54 68 72 65 61         || pThrea
9100: 64 2d 3e 65 57 6f 72 6b 3d 3d 53 4f 52 54 45 52  d->eWork==SORTER
9110: 5f 54 48 52 45 41 44 5f 43 4f 4e 53 0a 20 20 29  _THREAD_CONS.  )
9120: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 54 68 72  ;.  assert( pThr
9130: 65 61 64 2d 3e 62 44 6f 6e 65 3d 3d 30 20 29 3b  ead->bDone==0 );
9140: 0a 0a 20 20 69 66 28 20 70 54 68 72 65 61 64 2d  ..  if( pThread-
9150: 3e 70 55 6e 70 61 63 6b 65 64 3d 3d 30 20 29 7b  >pUnpacked==0 ){
9160: 0a 20 20 20 20 63 68 61 72 20 2a 70 46 72 65 65  .    char *pFree
9170: 3b 0a 20 20 20 20 70 54 68 72 65 61 64 2d 3e 70  ;.    pThread->p
9180: 55 6e 70 61 63 6b 65 64 20 3d 20 73 71 6c 69 74  Unpacked = sqlit
9190: 65 33 56 64 62 65 41 6c 6c 6f 63 55 6e 70 61 63  e3VdbeAllocUnpac
91a0: 6b 65 64 52 65 63 6f 72 64 28 0a 20 20 20 20 20  kedRecord(.     
91b0: 20 20 20 70 54 68 72 65 61 64 2d 3e 70 4b 65 79     pThread->pKey
91c0: 49 6e 66 6f 2c 20 30 2c 20 30 2c 20 26 70 46 72  Info, 0, 0, &pFr
91d0: 65 65 0a 20 20 20 20 29 3b 0a 20 20 20 20 61 73  ee.    );.    as
91e0: 73 65 72 74 28 20 70 54 68 72 65 61 64 2d 3e 70  sert( pThread->p
91f0: 55 6e 70 61 63 6b 65 64 3d 3d 28 55 6e 70 61 63  Unpacked==(Unpac
9200: 6b 65 64 52 65 63 6f 72 64 2a 29 70 46 72 65 65  kedRecord*)pFree
9210: 20 29 3b 0a 20 20 20 20 69 66 28 20 70 46 72 65   );.    if( pFre
9220: 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63  e==0 ){.      rc
9230: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
9240: 0a 20 20 20 20 20 20 67 6f 74 6f 20 74 68 72 65  .      goto thre
9250: 61 64 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20  ad_out;.    }.  
9260: 20 20 70 54 68 72 65 61 64 2d 3e 70 55 6e 70 61    pThread->pUnpa
9270: 63 6b 65 64 2d 3e 6e 46 69 65 6c 64 20 3d 20 70  cked->nField = p
9280: 54 68 72 65 61 64 2d 3e 70 4b 65 79 49 6e 66 6f  Thread->pKeyInfo
9290: 2d 3e 6e 46 69 65 6c 64 3b 0a 20 20 20 20 70 54  ->nField;.    pT
92a0: 68 72 65 61 64 2d 3e 70 55 6e 70 61 63 6b 65 64  hread->pUnpacked
92b0: 2d 3e 65 72 72 43 6f 64 65 20 3d 20 30 3b 0a 20  ->errCode = 0;. 
92c0: 20 7d 0a 0a 20 20 69 66 28 20 70 54 68 72 65 61   }..  if( pThrea
92d0: 64 2d 3e 65 57 6f 72 6b 3d 3d 53 4f 52 54 45 52  d->eWork==SORTER
92e0: 5f 54 48 52 45 41 44 5f 43 4f 4e 53 20 29 7b 0a  _THREAD_CONS ){.
92f0: 20 20 20 20 61 73 73 65 72 74 28 20 70 54 68 72      assert( pThr
9300: 65 61 64 2d 3e 70 4c 69 73 74 3d 3d 30 20 29 3b  ead->pList==0 );
9310: 0a 20 20 20 20 77 68 69 6c 65 28 20 70 54 68 72  .    while( pThr
9320: 65 61 64 2d 3e 6e 50 4d 41 3e 70 54 68 72 65 61  ead->nPMA>pThrea
9330: 64 2d 3e 6e 43 6f 6e 73 6f 6c 69 64 61 74 65 20  d->nConsolidate 
9340: 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  && rc==SQLITE_OK
9350: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 49   ){.      int nI
9360: 74 65 72 20 3d 20 4d 49 4e 28 70 54 68 72 65 61  ter = MIN(pThrea
9370: 64 2d 3e 6e 50 4d 41 2c 20 53 4f 52 54 45 52 5f  d->nPMA, SORTER_
9380: 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 29  MAX_MERGE_COUNT)
9390: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
93a0: 66 69 6c 65 20 2a 70 54 65 6d 70 32 20 3d 20 30  file *pTemp2 = 0
93b0: 3b 20 20 20 20 20 2f 2a 20 53 65 63 6f 6e 64 20  ;     /* Second 
93c0: 74 65 6d 70 20 66 69 6c 65 20 74 6f 20 75 73 65  temp file to use
93d0: 20 2a 2f 0a 20 20 20 20 20 20 53 6f 72 74 65 72   */.      Sorter
93e0: 4d 65 72 67 65 72 20 2a 70 4d 65 72 67 65 72 3b  Merger *pMerger;
93f0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63          /* Objec
9400: 74 20 66 6f 72 20 72 65 61 64 69 6e 67 2f 6d 65  t for reading/me
9410: 72 67 69 6e 67 20 50 4d 41 20 64 61 74 61 20 2a  rging PMA data *
9420: 2f 0a 20 20 20 20 20 20 69 36 34 20 69 52 65 61  /.      i64 iRea
9430: 64 4f 66 66 20 3d 20 30 3b 20 20 20 20 20 20 20  dOff = 0;       
9440: 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20        /* Offset 
9450: 69 6e 20 70 54 65 6d 70 31 20 74 6f 20 72 65 61  in pTemp1 to rea
9460: 64 20 66 72 6f 6d 20 2a 2f 0a 20 20 20 20 20 20  d from */.      
9470: 69 36 34 20 69 57 72 69 74 65 4f 66 66 20 3d 20  i64 iWriteOff = 
9480: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  0;            /*
9490: 20 4f 66 66 73 65 74 20 69 6e 20 70 54 65 6d 70   Offset in pTemp
94a0: 32 20 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f  2 to write to */
94b0: 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20  .      int i;.  
94c0: 20 20 20 20 0a 20 20 20 20 20 20 2f 2a 20 41 6c      .      /* Al
94d0: 6c 6f 63 61 74 65 20 61 20 6d 65 72 67 65 72 20  locate a merger 
94e0: 6f 62 6a 65 63 74 20 74 6f 20 6d 65 72 67 65 20  object to merge 
94f0: 50 4d 41 73 20 74 6f 67 65 74 68 65 72 2e 20 2a  PMAs together. *
9500: 2f 0a 20 20 20 20 20 20 70 4d 65 72 67 65 72 20  /.      pMerger 
9510: 3d 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67  = vdbeSorterMerg
9520: 65 72 4e 65 77 28 6e 49 74 65 72 29 3b 0a 20 20  erNew(nIter);.  
9530: 20 20 20 20 69 66 28 20 70 4d 65 72 67 65 72 3d      if( pMerger=
9540: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63  =0 ){.        rc
9550: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
9560: 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
9570: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f        }..      /
9580: 2a 20 4f 70 65 6e 20 61 20 73 65 63 6f 6e 64 20  * Open a second 
9590: 74 65 6d 70 20 66 69 6c 65 20 74 6f 20 77 72 69  temp file to wri
95a0: 74 65 20 6d 65 72 67 65 64 20 64 61 74 61 20 74  te merged data t
95b0: 6f 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20  o */.      rc = 
95c0: 76 64 62 65 53 6f 72 74 65 72 4f 70 65 6e 54 65  vdbeSorterOpenTe
95d0: 6d 70 46 69 6c 65 28 70 54 68 72 65 61 64 2d 3e  mpFile(pThread->
95e0: 70 56 66 73 2c 20 26 70 54 65 6d 70 32 29 3b 0a  pVfs, &pTemp2);.
95f0: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
9600: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
9610: 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74     rc = vdbeSort
9620: 65 72 45 78 74 65 6e 64 46 69 6c 65 28 70 54 65  erExtendFile(pTe
9630: 6d 70 32 2c 20 70 54 68 72 65 61 64 2d 3e 69 54  mp2, pThread->iT
9640: 65 6d 70 31 4f 66 66 29 3b 0a 20 20 20 20 20 20  emp1Off);.      
9650: 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  }.      if( rc!=
9660: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
9670: 20 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 4d       vdbeSorterM
9680: 65 72 67 65 72 46 72 65 65 28 70 4d 65 72 67 65  ergerFree(pMerge
9690: 72 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  r);.        brea
96a0: 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  k;.      }..    
96b0: 20 20 2f 2a 20 54 68 69 73 20 6c 6f 6f 70 20 72    /* This loop r
96c0: 75 6e 73 20 6f 6e 63 65 20 66 6f 72 20 65 61 63  uns once for eac
96d0: 68 20 6f 75 74 70 75 74 20 50 4d 41 2e 20 45 61  h output PMA. Ea
96e0: 63 68 20 6f 75 74 70 75 74 20 50 4d 41 20 69 73  ch output PMA is
96f0: 20 6d 61 64 65 0a 20 20 20 20 20 20 2a 2a 20 6f   made.      ** o
9700: 66 20 64 61 74 61 20 6d 65 72 67 65 64 20 66 72  f data merged fr
9710: 6f 6d 20 75 70 20 74 6f 20 53 4f 52 54 45 52 5f  om up to SORTER_
9720: 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20  MAX_MERGE_COUNT 
9730: 69 6e 70 75 74 20 50 4d 41 73 2e 20 2a 2f 0a 20  input PMAs. */. 
9740: 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c       for(i=0; i<
9750: 70 54 68 72 65 61 64 2d 3e 6e 50 4d 41 3b 20 69  pThread->nPMA; i
9760: 2b 3d 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52  +=SORTER_MAX_MER
9770: 47 45 5f 43 4f 55 4e 54 29 7b 0a 20 20 20 20 20  GE_COUNT){.     
9780: 20 20 20 46 69 6c 65 57 72 69 74 65 72 20 77 72     FileWriter wr
9790: 69 74 65 72 3b 20 20 20 20 20 20 20 20 2f 2a 20  iter;        /* 
97a0: 4f 62 6a 65 63 74 20 66 6f 72 20 77 72 69 74 69  Object for writi
97b0: 6e 67 20 64 61 74 61 20 74 6f 20 70 54 65 6d 70  ng data to pTemp
97c0: 32 20 2a 2f 0a 20 20 20 20 20 20 20 20 69 36 34  2 */.        i64
97d0: 20 6e 4f 75 74 20 3d 20 30 3b 20 20 20 20 20 20   nOut = 0;      
97e0: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
97f0: 6f 66 20 64 61 74 61 20 69 6e 20 6f 75 74 70 75  of data in outpu
9800: 74 20 50 4d 41 20 2a 2f 0a 20 20 20 20 20 20 20  t PMA */.       
9810: 20 69 6e 74 20 62 45 6f 66 20 3d 20 30 3b 0a 20   int bEof = 0;. 
9820: 20 20 20 20 20 20 20 69 6e 74 20 72 63 32 3b 0a         int rc2;.
9830: 0a 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 66  .        /* Conf
9840: 69 67 75 72 65 20 74 68 65 20 6d 65 72 67 65 72  igure the merger
9850: 20 6f 62 6a 65 63 74 20 74 6f 20 72 65 61 64 20   object to read 
9860: 61 6e 64 20 6d 65 72 67 65 20 64 61 74 61 20 66  and merge data f
9870: 72 6f 6d 20 74 68 65 20 6e 65 78 74 20 0a 20 20  rom the next .  
9880: 20 20 20 20 20 20 2a 2a 20 53 4f 52 54 45 52 5f        ** SORTER_
9890: 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20  MAX_MERGE_COUNT 
98a0: 50 4d 41 73 20 69 6e 20 70 54 65 6d 70 31 20 28  PMAs in pTemp1 (
98b0: 6f 72 20 66 72 6f 6d 20 61 6c 6c 20 72 65 6d 61  or from all rema
98c0: 69 6e 69 6e 67 20 50 4d 41 73 2c 0a 20 20 20 20  ining PMAs,.    
98d0: 20 20 20 20 2a 2a 20 69 66 20 74 68 61 74 20 69      ** if that i
98e0: 73 20 66 65 77 65 72 29 2e 20 2a 2f 0a 20 20 20  s fewer). */.   
98f0: 20 20 20 20 20 69 6e 74 20 69 49 74 65 72 3b 0a       int iIter;.
9900: 20 20 20 20 20 20 20 20 66 6f 72 28 69 49 74 65          for(iIte
9910: 72 3d 30 3b 20 69 49 74 65 72 3c 53 4f 52 54 45  r=0; iIter<SORTE
9920: 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
9930: 54 3b 20 69 49 74 65 72 2b 2b 29 7b 0a 20 20 20  T; iIter++){.   
9940: 20 20 20 20 20 20 20 56 64 62 65 53 6f 72 74 65         VdbeSorte
9950: 72 49 74 65 72 20 2a 70 49 74 65 72 20 3d 20 26  rIter *pIter = &
9960: 70 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 69  pMerger->aIter[i
9970: 49 74 65 72 5d 3b 0a 20 20 20 20 20 20 20 20 20  Iter];.         
9980: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
9990: 49 74 65 72 49 6e 69 74 28 70 54 68 72 65 61 64  IterInit(pThread
99a0: 2c 20 69 52 65 61 64 4f 66 66 2c 20 70 49 74 65  , iReadOff, pIte
99b0: 72 2c 20 26 6e 4f 75 74 29 3b 0a 20 20 20 20 20  r, &nOut);.     
99c0: 20 20 20 20 20 69 52 65 61 64 4f 66 66 20 3d 20       iReadOff = 
99d0: 70 49 74 65 72 2d 3e 69 45 6f 66 3b 0a 20 20 20  pIter->iEof;.   
99e0: 20 20 20 20 20 20 20 69 66 28 20 69 52 65 61 64         if( iRead
99f0: 4f 66 66 3e 3d 70 54 68 72 65 61 64 2d 3e 69 54  Off>=pThread->iT
9a00: 65 6d 70 31 4f 66 66 20 7c 7c 20 72 63 21 3d 53  emp1Off || rc!=S
9a10: 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b  QLITE_OK ) break
9a20: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
9a30: 20 20 20 20 66 6f 72 28 69 49 74 65 72 3d 70 4d      for(iIter=pM
9a40: 65 72 67 65 72 2d 3e 6e 54 72 65 65 2d 31 3b 20  erger->nTree-1; 
9a50: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
9a60: 20 69 49 74 65 72 3e 30 3b 20 69 49 74 65 72 2d   iIter>0; iIter-
9a70: 2d 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63  -){.          rc
9a80: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 44 6f 43   = vdbeSorterDoC
9a90: 6f 6d 70 61 72 65 28 70 54 68 72 65 61 64 2c 20  ompare(pThread, 
9aa0: 70 4d 65 72 67 65 72 2c 20 69 49 74 65 72 29 3b  pMerger, iIter);
9ab0: 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  .        }..    
9ac0: 20 20 20 20 66 69 6c 65 57 72 69 74 65 72 49 6e      fileWriterIn
9ad0: 69 74 28 70 54 65 6d 70 32 2c 20 26 77 72 69 74  it(pTemp2, &writ
9ae0: 65 72 2c 20 70 54 68 72 65 61 64 2d 3e 70 67 73  er, pThread->pgs
9af0: 7a 2c 20 69 57 72 69 74 65 4f 66 66 29 3b 0a 20  z, iWriteOff);. 
9b00: 20 20 20 20 20 20 20 66 69 6c 65 57 72 69 74 65         fileWrite
9b10: 72 57 72 69 74 65 56 61 72 69 6e 74 28 26 77 72  rWriteVarint(&wr
9b20: 69 74 65 72 2c 20 6e 4f 75 74 29 3b 0a 20 20 20  iter, nOut);.   
9b30: 20 20 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d       while( rc==
9b40: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 62 45 6f  SQLITE_OK && bEo
9b50: 66 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  f==0 ){.        
9b60: 20 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72    VdbeSorterIter
9b70: 20 2a 70 49 74 65 72 20 3d 20 26 70 4d 65 72 67   *pIter = &pMerg
9b80: 65 72 2d 3e 61 49 74 65 72 5b 20 70 4d 65 72 67  er->aIter[ pMerg
9b90: 65 72 2d 3e 61 54 72 65 65 5b 31 5d 20 5d 3b 0a  er->aTree[1] ];.
9ba0: 20 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74            assert
9bb0: 28 20 70 49 74 65 72 2d 3e 70 46 69 6c 65 21 3d  ( pIter->pFile!=
9bc0: 30 20 29 3b 20 20 20 20 20 20 20 20 2f 2a 20 70  0 );        /* p
9bd0: 49 74 65 72 20 69 73 20 6e 6f 74 20 61 74 20 45  Iter is not at E
9be0: 4f 46 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20  OF */.          
9bf0: 66 69 6c 65 57 72 69 74 65 72 57 72 69 74 65 56  fileWriterWriteV
9c00: 61 72 69 6e 74 28 26 77 72 69 74 65 72 2c 20 70  arint(&writer, p
9c10: 49 74 65 72 2d 3e 6e 4b 65 79 29 3b 0a 20 20 20  Iter->nKey);.   
9c20: 20 20 20 20 20 20 20 66 69 6c 65 57 72 69 74 65         fileWrite
9c30: 72 57 72 69 74 65 28 26 77 72 69 74 65 72 2c 20  rWrite(&writer, 
9c40: 70 49 74 65 72 2d 3e 61 4b 65 79 2c 20 70 49 74  pIter->aKey, pIt
9c50: 65 72 2d 3e 6e 4b 65 79 29 3b 0a 20 20 20 20 20  er->nKey);.     
9c60: 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f       rc = vdbeSo
9c70: 72 74 65 72 4e 65 78 74 28 70 54 68 72 65 61 64  rterNext(pThread
9c80: 2c 20 70 4d 65 72 67 65 72 2c 20 26 62 45 6f 66  , pMerger, &bEof
9c90: 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  );.        }.   
9ca0: 20 20 20 20 20 72 63 32 20 3d 20 66 69 6c 65 57       rc2 = fileW
9cb0: 72 69 74 65 72 46 69 6e 69 73 68 28 26 77 72 69  riterFinish(&wri
9cc0: 74 65 72 2c 20 26 69 57 72 69 74 65 4f 66 66 29  ter, &iWriteOff)
9cd0: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
9ce0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63  ==SQLITE_OK ) rc
9cf0: 20 3d 20 72 63 32 3b 0a 20 20 20 20 20 20 7d 0a   = rc2;.      }.
9d00: 0a 20 20 20 20 20 20 76 64 62 65 53 6f 72 74 65  .      vdbeSorte
9d10: 72 4d 65 72 67 65 72 46 72 65 65 28 70 4d 65 72  rMergerFree(pMer
9d20: 67 65 72 29 3b 0a 20 20 20 20 20 20 73 71 6c 69  ger);.      sqli
9d30: 74 65 33 4f 73 43 6c 6f 73 65 46 72 65 65 28 70  te3OsCloseFree(p
9d40: 54 68 72 65 61 64 2d 3e 70 54 65 6d 70 31 29 3b  Thread->pTemp1);
9d50: 0a 20 20 20 20 20 20 70 54 68 72 65 61 64 2d 3e  .      pThread->
9d60: 70 54 65 6d 70 31 20 3d 20 70 54 65 6d 70 32 3b  pTemp1 = pTemp2;
9d70: 0a 20 20 20 20 20 20 70 54 68 72 65 61 64 2d 3e  .      pThread->
9d80: 6e 50 4d 41 20 3d 20 28 69 20 2f 20 53 4f 52 54  nPMA = (i / SORT
9d90: 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55  ER_MAX_MERGE_COU
9da0: 4e 54 29 3b 0a 20 20 20 20 20 20 70 54 68 72 65  NT);.      pThre
9db0: 61 64 2d 3e 69 54 65 6d 70 31 4f 66 66 20 3d 20  ad->iTemp1Off = 
9dc0: 69 57 72 69 74 65 4f 66 66 3b 0a 20 20 20 20 7d  iWriteOff;.    }
9dd0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a  .  }else{.    /*
9de0: 20 53 6f 72 74 20 74 68 65 20 70 54 68 72 65 61   Sort the pThrea
9df0: 64 2d 3e 70 4c 69 73 74 20 6c 69 73 74 20 2a 2f  d->pList list */
9e00: 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f  .    rc = vdbeSo
9e10: 72 74 65 72 53 6f 72 74 28 70 54 68 72 65 61 64  rterSort(pThread
9e20: 29 3b 0a 0a 20 20 20 20 2f 2a 20 49 66 20 72 65  );..    /* If re
9e30: 71 75 69 72 65 64 2c 20 77 72 69 74 65 20 74 68  quired, write th
9e40: 65 20 6c 69 73 74 20 6f 75 74 20 74 6f 20 61 20  e list out to a 
9e50: 50 4d 41 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20  PMA. */.    if( 
9e60: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
9e70: 20 70 54 68 72 65 61 64 2d 3e 65 57 6f 72 6b 3d   pThread->eWork=
9e80: 3d 53 4f 52 54 45 52 5f 54 48 52 45 41 44 5f 54  =SORTER_THREAD_T
9e90: 4f 5f 50 4d 41 20 29 7b 0a 23 69 66 64 65 66 20  O_PMA ){.#ifdef 
9ea0: 53 51 4c 49 54 45 5f 44 45 42 55 47 0a 20 20 20  SQLITE_DEBUG.   
9eb0: 20 20 20 69 36 34 20 6e 45 78 70 65 63 74 20 3d     i64 nExpect =
9ec0: 20 70 54 68 72 65 61 64 2d 3e 6e 49 6e 4d 65 6d   pThread->nInMem
9ed0: 6f 72 79 0a 20 20 20 20 20 20 20 20 2b 20 73 71  ory.        + sq
9ee0: 6c 69 74 65 33 56 61 72 69 6e 74 4c 65 6e 28 70  lite3VarintLen(p
9ef0: 54 68 72 65 61 64 2d 3e 6e 49 6e 4d 65 6d 6f 72  Thread->nInMemor
9f00: 79 29 0a 20 20 20 20 20 20 20 20 2b 20 70 54 68  y).        + pTh
9f10: 72 65 61 64 2d 3e 69 54 65 6d 70 31 4f 66 66 3b  read->iTemp1Off;
9f20: 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20 72 63  .#endif.      rc
9f30: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4c 69 73   = vdbeSorterLis
9f40: 74 54 6f 50 4d 41 28 70 54 68 72 65 61 64 29 3b  tToPMA(pThread);
9f50: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 72  .      assert( r
9f60: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20  c!=SQLITE_OK || 
9f70: 28 6e 45 78 70 65 63 74 3d 3d 70 54 68 72 65 61  (nExpect==pThrea
9f80: 64 2d 3e 69 54 65 6d 70 31 4f 66 66 29 20 29 3b  d->iTemp1Off) );
9f90: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 74 68 72  .    }.  }.. thr
9fa0: 65 61 64 5f 6f 75 74 3a 0a 20 20 70 54 68 72 65  ead_out:.  pThre
9fb0: 61 64 2d 3e 62 44 6f 6e 65 20 3d 20 31 3b 0a 20  ad->bDone = 1;. 
9fc0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
9fd0: 4f 4b 20 26 26 20 70 54 68 72 65 61 64 2d 3e 70  OK && pThread->p
9fe0: 55 6e 70 61 63 6b 65 64 2d 3e 65 72 72 43 6f 64  Unpacked->errCod
9ff0: 65 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  e ){.    assert(
a000: 20 70 54 68 72 65 61 64 2d 3e 70 55 6e 70 61 63   pThread->pUnpac
a010: 6b 65 64 2d 3e 65 72 72 43 6f 64 65 3d 3d 53 51  ked->errCode==SQ
a020: 4c 49 54 45 5f 4e 4f 4d 45 4d 20 29 3b 0a 20 20  LITE_NOMEM );.  
a030: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
a040: 4d 45 4d 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  MEM;.  }.  retur
a050: 6e 20 53 51 4c 49 54 45 5f 49 4e 54 5f 54 4f 5f  n SQLITE_INT_TO_
a060: 50 54 52 28 72 63 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  PTR(rc);.}../*.*
a070: 2a 20 52 75 6e 20 74 68 65 20 61 63 74 69 76 69  * Run the activi
a080: 74 79 20 73 63 68 65 64 75 6c 65 64 20 62 79 20  ty scheduled by 
a090: 74 68 65 20 6f 62 6a 65 63 74 20 70 61 73 73 65  the object passe
a0a0: 64 20 61 73 20 74 68 65 20 6f 6e 6c 79 20 61 72  d as the only ar
a0b0: 67 75 6d 65 6e 74 0a 2a 2a 20 69 6e 20 74 68 65  gument.** in the
a0c0: 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 2e   current thread.
a0d0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
a0e0: 64 62 65 53 6f 72 74 65 72 52 75 6e 54 68 72 65  dbeSorterRunThre
a0f0: 61 64 28 53 6f 72 74 65 72 54 68 72 65 61 64 20  ad(SorterThread 
a100: 2a 70 54 68 72 65 61 64 29 7b 0a 20 20 69 6e 74  *pThread){.  int
a110: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 50 54 52   rc = SQLITE_PTR
a120: 5f 54 4f 5f 49 4e 54 28 20 76 64 62 65 53 6f 72  _TO_INT( vdbeSor
a130: 74 65 72 54 68 72 65 61 64 4d 61 69 6e 28 28 76  terThreadMain((v
a140: 6f 69 64 2a 29 70 54 68 72 65 61 64 29 20 29 3b  oid*)pThread) );
a150: 0a 20 20 61 73 73 65 72 74 28 20 70 54 68 72 65  .  assert( pThre
a160: 61 64 2d 3e 62 44 6f 6e 65 20 29 3b 0a 20 20 70  ad->bDone );.  p
a170: 54 68 72 65 61 64 2d 3e 62 44 6f 6e 65 20 3d 20  Thread->bDone = 
a180: 30 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  0;.  return rc;.
a190: 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68 20 74  }../*.** Flush t
a1a0: 68 65 20 63 75 72 72 65 6e 74 20 63 6f 6e 74 65  he current conte
a1b0: 6e 74 73 20 6f 66 20 56 64 62 65 53 6f 72 74 65  nts of VdbeSorte
a1c0: 72 2e 70 52 65 63 6f 72 64 20 74 6f 20 61 20 6e  r.pRecord to a n
a1d0: 65 77 20 50 4d 41 2c 20 70 6f 73 73 69 62 6c 79  ew PMA, possibly
a1e0: 0a 2a 2a 20 75 73 69 6e 67 20 61 20 62 61 63 6b  .** using a back
a1f0: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 2e 0a 2a  ground thread..*
a200: 2a 0a 2a 2a 20 49 66 20 61 72 67 75 6d 65 6e 74  *.** If argument
a210: 20 62 46 67 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f   bFg is non-zero
a220: 2c 20 74 68 65 20 6f 70 65 72 61 74 69 6f 6e 20  , the operation 
a230: 61 6c 77 61 79 73 20 75 73 65 73 20 74 68 65 20  always uses the 
a240: 63 61 6c 6c 69 6e 67 20 74 68 72 65 61 64 2e 0a  calling thread..
a250: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
a260: 62 65 53 6f 72 74 65 72 46 6c 75 73 68 50 4d 41  beSorterFlushPMA
a270: 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 63 6f  (sqlite3 *db, co
a280: 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a  nst VdbeCursor *
a290: 70 43 73 72 2c 20 69 6e 74 20 62 46 67 29 7b 0a  pCsr, int bFg){.
a2a0: 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
a2b0: 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53  orter = pCsr->pS
a2c0: 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 72 63 20  orter;.  int rc 
a2d0: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
a2e0: 6e 74 20 69 3b 0a 20 20 53 6f 72 74 65 72 54 68  nt i;.  SorterTh
a2f0: 72 65 61 64 20 2a 70 54 68 72 65 61 64 20 3d 20  read *pThread = 
a300: 30 3b 20 20 20 20 2f 2a 20 54 68 72 65 61 64 20  0;    /* Thread 
a310: 63 6f 6e 74 65 78 74 20 75 73 65 64 20 74 6f 20  context used to 
a320: 63 72 65 61 74 65 20 6e 65 77 20 50 4d 41 20 2a  create new PMA *
a330: 2f 0a 20 20 69 6e 74 20 6e 57 6f 72 6b 65 72 20  /.  int nWorker 
a340: 3d 20 28 70 53 6f 72 74 65 72 2d 3e 6e 54 68 72  = (pSorter->nThr
a350: 65 61 64 2d 31 29 3b 0a 0a 20 20 70 53 6f 72 74  ead-1);..  pSort
a360: 65 72 2d 3e 62 55 73 65 50 4d 41 20 3d 20 31 3b  er->bUsePMA = 1;
a370: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 57  .  for(i=0; i<nW
a380: 6f 72 6b 65 72 3b 20 69 2b 2b 29 7b 0a 20 20 20  orker; i++){.   
a390: 20 69 6e 74 20 69 54 65 73 74 20 3d 20 28 70 53   int iTest = (pS
a3a0: 6f 72 74 65 72 2d 3e 69 50 72 65 76 20 2b 20 69  orter->iPrev + i
a3b0: 20 2b 20 31 29 20 25 20 6e 57 6f 72 6b 65 72 3b   + 1) % nWorker;
a3c0: 0a 20 20 20 20 70 54 68 72 65 61 64 20 3d 20 26  .    pThread = &
a3d0: 70 53 6f 72 74 65 72 2d 3e 61 54 68 72 65 61 64  pSorter->aThread
a3e0: 5b 69 54 65 73 74 5d 3b 0a 23 69 66 20 53 51 4c  [iTest];.#if SQL
a3f0: 49 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54  ITE_MAX_WORKER_T
a400: 48 52 45 41 44 53 3e 30 0a 20 20 20 20 69 66 28  HREADS>0.    if(
a410: 20 70 54 68 72 65 61 64 2d 3e 62 44 6f 6e 65 20   pThread->bDone 
a420: 29 7b 0a 20 20 20 20 20 20 76 6f 69 64 20 2a 70  ){.      void *p
a430: 52 65 74 3b 0a 20 20 20 20 20 20 61 73 73 65 72  Ret;.      asser
a440: 74 28 20 70 54 68 72 65 61 64 2d 3e 70 54 68 72  t( pThread->pThr
a450: 65 61 64 20 29 3b 0a 20 20 20 20 20 20 72 63 20  ead );.      rc 
a460: 3d 20 73 71 6c 69 74 65 33 54 68 72 65 61 64 4a  = sqlite3ThreadJ
a470: 6f 69 6e 28 70 54 68 72 65 61 64 2d 3e 70 54 68  oin(pThread->pTh
a480: 72 65 61 64 2c 20 26 70 52 65 74 29 3b 0a 20 20  read, &pRet);.  
a490: 20 20 20 20 70 54 68 72 65 61 64 2d 3e 70 54 68      pThread->pTh
a4a0: 72 65 61 64 20 3d 20 30 3b 0a 20 20 20 20 20 20  read = 0;.      
a4b0: 70 54 68 72 65 61 64 2d 3e 62 44 6f 6e 65 20 3d  pThread->bDone =
a4c0: 20 30 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63   0;.      if( rc
a4d0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
a4e0: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
a4f0: 54 45 5f 50 54 52 5f 54 4f 5f 49 4e 54 28 70 52  TE_PTR_TO_INT(pR
a500: 65 74 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  et);.      }.   
a510: 20 7d 0a 23 65 6e 64 69 66 0a 20 20 20 20 69 66   }.#endif.    if
a520: 28 20 70 54 68 72 65 61 64 2d 3e 70 54 68 72 65  ( pThread->pThre
a530: 61 64 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20  ad==0 ) break;. 
a540: 20 20 20 70 54 68 72 65 61 64 20 3d 20 30 3b 0a     pThread = 0;.
a550: 20 20 7d 0a 20 20 69 66 28 20 70 54 68 72 65 61    }.  if( pThrea
a560: 64 3d 3d 30 20 29 7b 0a 20 20 20 20 70 54 68 72  d==0 ){.    pThr
a570: 65 61 64 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e  ead = &pSorter->
a580: 61 54 68 72 65 61 64 5b 6e 57 6f 72 6b 65 72 5d  aThread[nWorker]
a590: 3b 0a 20 20 7d 0a 20 20 70 53 6f 72 74 65 72 2d  ;.  }.  pSorter-
a5a0: 3e 69 50 72 65 76 20 3d 20 28 70 54 68 72 65 61  >iPrev = (pThrea
a5b0: 64 20 2d 20 70 53 6f 72 74 65 72 2d 3e 61 54 68  d - pSorter->aTh
a5c0: 72 65 61 64 29 3b 0a 0a 20 20 69 66 28 20 72 63  read);..  if( rc
a5d0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
a5e0: 20 20 20 61 73 73 65 72 74 28 20 70 54 68 72 65     assert( pThre
a5f0: 61 64 2d 3e 70 54 68 72 65 61 64 3d 3d 30 20 26  ad->pThread==0 &
a600: 26 20 70 54 68 72 65 61 64 2d 3e 62 44 6f 6e 65  & pThread->bDone
a610: 3d 3d 30 20 29 3b 0a 20 20 20 20 70 54 68 72 65  ==0 );.    pThre
a620: 61 64 2d 3e 65 57 6f 72 6b 20 3d 20 53 4f 52 54  ad->eWork = SORT
a630: 45 52 5f 54 48 52 45 41 44 5f 54 4f 5f 50 4d 41  ER_THREAD_TO_PMA
a640: 3b 0a 20 20 20 20 70 54 68 72 65 61 64 2d 3e 70  ;.    pThread->p
a650: 4c 69 73 74 20 3d 20 70 53 6f 72 74 65 72 2d 3e  List = pSorter->
a660: 70 52 65 63 6f 72 64 3b 0a 20 20 20 20 70 54 68  pRecord;.    pTh
a670: 72 65 61 64 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20  read->nInMemory 
a680: 3d 20 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65  = pSorter->nInMe
a690: 6d 6f 72 79 3b 0a 20 20 20 20 70 53 6f 72 74 65  mory;.    pSorte
a6a0: 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20 3d 20 30  r->nInMemory = 0
a6b0: 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70  ;.    pSorter->p
a6c0: 52 65 63 6f 72 64 20 3d 20 30 3b 0a 0a 20 20 20  Record = 0;..   
a6d0: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 61 4d   if( pSorter->aM
a6e0: 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20 20 75  emory ){.      u
a6f0: 38 20 2a 61 4d 65 6d 20 3d 20 70 54 68 72 65 61  8 *aMem = pThrea
a700: 64 2d 3e 61 4c 69 73 74 4d 65 6d 6f 72 79 3b 0a  d->aListMemory;.
a710: 20 20 20 20 20 20 70 54 68 72 65 61 64 2d 3e 61        pThread->a
a720: 4c 69 73 74 4d 65 6d 6f 72 79 20 3d 20 70 53 6f  ListMemory = pSo
a730: 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 3b 0a 20  rter->aMemory;. 
a740: 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 61 4d       pSorter->aM
a750: 65 6d 6f 72 79 20 3d 20 61 4d 65 6d 3b 0a 20 20  emory = aMem;.  
a760: 20 20 7d 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f    }..#if SQLITE_
a770: 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41  MAX_WORKER_THREA
a780: 44 53 3e 30 0a 20 20 20 20 69 66 28 20 21 62 46  DS>0.    if( !bF
a790: 67 20 26 26 20 70 54 68 72 65 61 64 21 3d 26 70  g && pThread!=&p
a7a0: 53 6f 72 74 65 72 2d 3e 61 54 68 72 65 61 64 5b  Sorter->aThread[
a7b0: 6e 57 6f 72 6b 65 72 5d 20 29 7b 0a 20 20 20 20  nWorker] ){.    
a7c0: 20 20 2f 2a 20 4c 61 75 6e 63 68 20 61 20 62 61    /* Launch a ba
a7d0: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
a7e0: 66 6f 72 20 74 68 69 73 20 6f 70 65 72 61 74 69  for this operati
a7f0: 6f 6e 20 2a 2f 0a 20 20 20 20 20 20 76 6f 69 64  on */.      void
a800: 20 2a 70 43 74 78 20 3d 20 28 76 6f 69 64 2a 29   *pCtx = (void*)
a810: 70 54 68 72 65 61 64 3b 0a 20 20 20 20 20 20 61  pThread;.      a
a820: 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e  ssert( pSorter->
a830: 61 4d 65 6d 6f 72 79 3d 3d 30 20 7c 7c 20 70 54  aMemory==0 || pT
a840: 68 72 65 61 64 2d 3e 61 4c 69 73 74 4d 65 6d 6f  hread->aListMemo
a850: 72 79 21 3d 30 20 29 3b 0a 20 20 20 20 20 20 69  ry!=0 );.      i
a860: 66 28 20 70 54 68 72 65 61 64 2d 3e 61 4c 69 73  f( pThread->aLis
a870: 74 4d 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20  tMemory ){.     
a880: 20 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e     if( pSorter->
a890: 61 4d 65 6d 6f 72 79 3d 3d 30 20 29 7b 0a 20 20  aMemory==0 ){.  
a8a0: 20 20 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d          pSorter-
a8b0: 3e 61 4d 65 6d 6f 72 79 20 3d 20 73 71 6c 69 74  >aMemory = sqlit
a8c0: 65 33 4d 61 6c 6c 6f 63 28 70 53 6f 72 74 65 72  e3Malloc(pSorter
a8d0: 2d 3e 6e 4d 65 6d 6f 72 79 29 3b 0a 20 20 20 20  ->nMemory);.    
a8e0: 20 20 20 20 20 20 69 66 28 20 70 53 6f 72 74 65        if( pSorte
a8f0: 72 2d 3e 61 4d 65 6d 6f 72 79 3d 3d 30 20 29 20  r->aMemory==0 ) 
a900: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
a910: 4d 45 4d 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  MEM;.        }el
a920: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 70 53  se{.          pS
a930: 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 3d  orter->nMemory =
a940: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69   sqlite3MallocSi
a950: 7a 65 28 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d  ze(pSorter->aMem
a960: 6f 72 79 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  ory);.        }.
a970: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72 63        }.      rc
a980: 20 3d 20 73 71 6c 69 74 65 33 54 68 72 65 61 64   = sqlite3Thread
a990: 43 72 65 61 74 65 28 26 70 54 68 72 65 61 64 2d  Create(&pThread-
a9a0: 3e 70 54 68 72 65 61 64 2c 20 76 64 62 65 53 6f  >pThread, vdbeSo
a9b0: 72 74 65 72 54 68 72 65 61 64 4d 61 69 6e 2c 20  rterThreadMain, 
a9c0: 70 43 74 78 29 3b 0a 20 20 20 20 7d 65 6c 73 65  pCtx);.    }else
a9d0: 0a 23 65 6e 64 69 66 0a 20 20 20 20 7b 0a 20 20  .#endif.    {.  
a9e0: 20 20 20 20 2f 2a 20 55 73 65 20 74 68 65 20 66      /* Use the f
a9f0: 6f 72 65 67 72 6f 75 6e 64 20 74 68 72 65 61 64  oreground thread
aa00: 20 66 6f 72 20 74 68 69 73 20 6f 70 65 72 61 74   for this operat
aa10: 69 6f 6e 20 2a 2f 0a 20 20 20 20 20 20 75 38 20  ion */.      u8 
aa20: 2a 61 4d 65 6d 3b 0a 20 20 20 20 20 20 72 63 20  *aMem;.      rc 
aa30: 3d 20 76 64 62 65 53 6f 72 74 65 72 52 75 6e 54  = vdbeSorterRunT
aa40: 68 72 65 61 64 28 70 54 68 72 65 61 64 29 3b 0a  hread(pThread);.
aa50: 20 20 20 20 20 20 61 4d 65 6d 20 3d 20 70 54 68        aMem = pTh
aa60: 72 65 61 64 2d 3e 61 4c 69 73 74 4d 65 6d 6f 72  read->aListMemor
aa70: 79 3b 0a 20 20 20 20 20 20 70 54 68 72 65 61 64  y;.      pThread
aa80: 2d 3e 61 4c 69 73 74 4d 65 6d 6f 72 79 20 3d 20  ->aListMemory = 
aa90: 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79  pSorter->aMemory
aaa0: 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d  ;.      pSorter-
aab0: 3e 61 4d 65 6d 6f 72 79 20 3d 20 61 4d 65 6d 3b  >aMemory = aMem;
aac0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
aad0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
aae0: 2a 20 41 64 64 20 61 20 72 65 63 6f 72 64 20 74  * Add a record t
aaf0: 6f 20 74 68 65 20 73 6f 72 74 65 72 2e 0a 2a 2f  o the sorter..*/
ab00: 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65  .int sqlite3Vdbe
ab10: 53 6f 72 74 65 72 57 72 69 74 65 28 0a 20 20 73  SorterWrite(.  s
ab20: 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20  qlite3 *db,     
ab30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
ab40: 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c  * Database handl
ab50: 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 56 64 62  e */.  const Vdb
ab60: 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 20  eCursor *pCsr,  
ab70: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
ab80: 53 6f 72 74 65 72 20 63 75 72 73 6f 72 20 2a 2f  Sorter cursor */
ab90: 0a 20 20 4d 65 6d 20 2a 70 56 61 6c 20 20 20 20  .  Mem *pVal    
aba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
abb0: 20 20 20 2f 2a 20 4d 65 6d 6f 72 79 20 63 65 6c     /* Memory cel
abc0: 6c 20 63 6f 6e 74 61 69 6e 69 6e 67 20 72 65 63  l containing rec
abd0: 6f 72 64 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65  ord */.){.  Vdbe
abe0: 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20  Sorter *pSorter 
abf0: 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b  = pCsr->pSorter;
ac00: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
ac10: 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
ac20: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64     /* Return Cod
ac30: 65 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63  e */.  SorterRec
ac40: 6f 72 64 20 2a 70 4e 65 77 3b 20 20 20 20 20 20  ord *pNew;      
ac50: 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 6c 69         /* New li
ac60: 73 74 20 65 6c 65 6d 65 6e 74 20 2a 2f 0a 0a 20  st element */.. 
ac70: 20 69 6e 74 20 62 46 6c 75 73 68 3b 20 20 20 20   int bFlush;    
ac80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ac90: 20 2f 2a 20 54 72 75 65 20 74 6f 20 66 6c 75 73   /* True to flus
aca0: 68 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65  h contents of me
acb0: 6d 6f 72 79 20 74 6f 20 50 4d 41 20 2a 2f 0a 20  mory to PMA */. 
acc0: 20 69 6e 74 20 6e 52 65 71 3b 20 20 20 20 20 20   int nReq;      
acd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ace0: 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 6d 65 6d   /* Bytes of mem
acf0: 6f 72 79 20 72 65 71 75 69 72 65 64 20 2a 2f 0a  ory required */.
ad00: 20 20 69 6e 74 20 6e 50 4d 41 3b 20 20 20 20 20    int nPMA;     
ad10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ad20: 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 50 4d    /* Bytes of PM
ad30: 41 20 73 70 61 63 65 20 72 65 71 75 69 72 65 64  A space required
ad40: 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70   */..  assert( p
ad50: 53 6f 72 74 65 72 20 29 3b 0a 0a 20 20 2f 2a 20  Sorter );..  /* 
ad60: 46 69 67 75 72 65 20 6f 75 74 20 77 68 65 74 68  Figure out wheth
ad70: 65 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 63 75  er or not the cu
ad80: 72 72 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f  rrent contents o
ad90: 66 20 6d 65 6d 6f 72 79 20 73 68 6f 75 6c 64 20  f memory should 
ada0: 62 65 0a 20 20 2a 2a 20 66 6c 75 73 68 65 64 20  be.  ** flushed 
adb0: 74 6f 20 61 20 50 4d 41 20 62 65 66 6f 72 65 20  to a PMA before 
adc0: 63 6f 6e 74 69 6e 75 69 6e 67 2e 20 49 66 20 73  continuing. If s
add0: 6f 2c 20 64 6f 20 73 6f 2e 0a 20 20 2a 2a 0a 20  o, do so..  **. 
ade0: 20 2a 2a 20 49 66 20 75 73 69 6e 67 20 74 68 65   ** If using the
adf0: 20 73 69 6e 67 6c 65 20 6c 61 72 67 65 20 61 6c   single large al
ae00: 6c 6f 63 61 74 69 6f 6e 20 6d 6f 64 65 20 28 70  location mode (p
ae10: 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 21  Sorter->aMemory!
ae20: 3d 30 29 2c 20 74 68 65 6e 0a 20 20 2a 2a 20 66  =0), then.  ** f
ae30: 6c 75 73 68 20 74 68 65 20 63 6f 6e 74 65 6e 74  lush the content
ae40: 73 20 6f 66 20 6d 65 6d 6f 72 79 20 74 6f 20 61  s of memory to a
ae50: 20 6e 65 77 20 50 4d 41 20 69 66 20 28 61 29 20   new PMA if (a) 
ae60: 61 74 20 6c 65 61 73 74 20 6f 6e 65 20 76 61 6c  at least one val
ae70: 75 65 20 69 73 0a 20 20 2a 2a 20 61 6c 72 65 61  ue is.  ** alrea
ae80: 64 79 20 69 6e 20 6d 65 6d 6f 72 79 20 61 6e 64  dy in memory and
ae90: 20 28 62 29 20 74 68 65 20 6e 65 77 20 76 61 6c   (b) the new val
aea0: 75 65 20 77 69 6c 6c 20 6e 6f 74 20 66 69 74 20  ue will not fit 
aeb0: 69 6e 20 6d 65 6d 6f 72 79 2e 0a 20 20 2a 2a 20  in memory..  ** 
aec0: 0a 20 20 2a 2a 20 4f 72 2c 20 69 66 20 75 73 69  .  ** Or, if usi
aed0: 6e 67 20 73 65 70 61 72 61 74 65 20 61 6c 6c 6f  ng separate allo
aee0: 63 61 74 69 6f 6e 73 20 66 6f 72 20 65 61 63 68  cations for each
aef0: 20 72 65 63 6f 72 64 2c 20 66 6c 75 73 68 20 74   record, flush t
af00: 68 65 20 63 6f 6e 74 65 6e 74 73 0a 20 20 2a 2a  he contents.  **
af10: 20 6f 66 20 6d 65 6d 6f 72 79 20 74 6f 20 61 20   of memory to a 
af20: 50 4d 41 20 69 66 20 65 69 74 68 65 72 20 6f 66  PMA if either of
af30: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 61   the following a
af40: 72 65 20 74 72 75 65 3a 0a 20 20 2a 2a 0a 20 20  re true:.  **.  
af50: 2a 2a 20 20 20 2a 20 54 68 65 20 74 6f 74 61 6c  **   * The total
af60: 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 65   memory allocate
af70: 64 20 66 6f 72 20 74 68 65 20 69 6e 2d 6d 65 6d  d for the in-mem
af80: 6f 72 79 20 6c 69 73 74 20 69 73 20 67 72 65 61  ory list is grea
af90: 74 65 72 20 0a 20 20 2a 2a 20 20 20 20 20 74 68  ter .  **     th
afa0: 61 6e 20 28 70 61 67 65 2d 73 69 7a 65 20 2a 20  an (page-size * 
afb0: 63 61 63 68 65 2d 73 69 7a 65 29 2c 20 6f 72 0a  cache-size), or.
afc0: 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 54 68    **.  **   * Th
afd0: 65 20 74 6f 74 61 6c 20 6d 65 6d 6f 72 79 20 61  e total memory a
afe0: 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 74 68 65  llocated for the
aff0: 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20   in-memory list 
b000: 69 73 20 67 72 65 61 74 65 72 20 0a 20 20 2a 2a  is greater .  **
b010: 20 20 20 20 20 74 68 61 6e 20 28 70 61 67 65 2d       than (page-
b020: 73 69 7a 65 20 2a 20 31 30 29 20 61 6e 64 20 73  size * 10) and s
b030: 71 6c 69 74 65 33 48 65 61 70 4e 65 61 72 6c 79  qlite3HeapNearly
b040: 46 75 6c 6c 28 29 20 72 65 74 75 72 6e 73 20 74  Full() returns t
b050: 72 75 65 2e 0a 20 20 2a 2f 0a 20 20 6e 52 65 71  rue..  */.  nReq
b060: 20 3d 20 70 56 61 6c 2d 3e 6e 20 2b 20 73 69 7a   = pVal->n + siz
b070: 65 6f 66 28 53 6f 72 74 65 72 52 65 63 6f 72 64  eof(SorterRecord
b080: 29 3b 0a 20 20 6e 50 4d 41 20 3d 20 70 56 61 6c  );.  nPMA = pVal
b090: 2d 3e 6e 20 2b 20 73 71 6c 69 74 65 33 56 61 72  ->n + sqlite3Var
b0a0: 69 6e 74 4c 65 6e 28 70 56 61 6c 2d 3e 6e 29 3b  intLen(pVal->n);
b0b0: 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e  .  if( pSorter->
b0c0: 6d 78 50 6d 61 53 69 7a 65 20 29 7b 0a 20 20 20  mxPmaSize ){.   
b0d0: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 61 4d   if( pSorter->aM
b0e0: 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20 20 62  emory ){.      b
b0f0: 46 6c 75 73 68 20 3d 20 70 53 6f 72 74 65 72 2d  Flush = pSorter-
b100: 3e 69 4d 65 6d 6f 72 79 20 26 26 20 28 70 53 6f  >iMemory && (pSo
b110: 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 2b 6e 52  rter->iMemory+nR
b120: 65 71 29 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d  eq) > pSorter->m
b130: 78 50 6d 61 53 69 7a 65 3b 0a 20 20 20 20 7d 65  xPmaSize;.    }e
b140: 6c 73 65 7b 0a 20 20 20 20 20 20 62 46 6c 75 73  lse{.      bFlus
b150: 68 20 3d 20 28 0a 20 20 20 20 20 20 20 20 20 20  h = (.          
b160: 28 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d  (pSorter->nInMem
b170: 6f 72 79 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d  ory > pSorter->m
b180: 78 50 6d 61 53 69 7a 65 29 0a 20 20 20 20 20 20  xPmaSize).      
b190: 20 7c 7c 20 28 70 53 6f 72 74 65 72 2d 3e 6e 49   || (pSorter->nI
b1a0: 6e 4d 65 6d 6f 72 79 20 3e 20 70 53 6f 72 74 65  nMemory > pSorte
b1b0: 72 2d 3e 6d 6e 50 6d 61 53 69 7a 65 20 26 26 20  r->mnPmaSize && 
b1c0: 73 71 6c 69 74 65 33 48 65 61 70 4e 65 61 72 6c  sqlite3HeapNearl
b1d0: 79 46 75 6c 6c 28 29 29 0a 20 20 20 20 20 20 29  yFull()).      )
b1e0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
b1f0: 62 46 6c 75 73 68 20 29 7b 0a 20 20 20 20 20 20  bFlush ){.      
b200: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 46  rc = vdbeSorterF
b210: 6c 75 73 68 50 4d 41 28 64 62 2c 20 70 43 73 72  lushPMA(db, pCsr
b220: 2c 20 30 29 3b 0a 20 20 20 20 20 20 70 53 6f 72  , 0);.      pSor
b230: 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20 3d  ter->nInMemory =
b240: 20 30 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65   0;.      pSorte
b250: 72 2d 3e 69 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a  r->iMemory = 0;.
b260: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 72 63        assert( rc
b270: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70  !=SQLITE_OK || p
b280: 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 3d  Sorter->pRecord=
b290: 3d 30 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  =0 );.    }.  }.
b2a0: 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d  .  pSorter->nInM
b2b0: 65 6d 6f 72 79 20 2b 3d 20 6e 50 4d 41 3b 0a 0a  emory += nPMA;..
b2c0: 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 61    if( pSorter->a
b2d0: 4d 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 69 6e  Memory ){.    in
b2e0: 74 20 6e 4d 69 6e 20 3d 20 70 53 6f 72 74 65 72  t nMin = pSorter
b2f0: 2d 3e 69 4d 65 6d 6f 72 79 20 2b 20 6e 52 65 71  ->iMemory + nReq
b300: 3b 0a 0a 20 20 20 20 69 66 28 20 6e 4d 69 6e 3e  ;..    if( nMin>
b310: 70 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79  pSorter->nMemory
b320: 20 29 7b 0a 20 20 20 20 20 20 75 38 20 2a 61 4e   ){.      u8 *aN
b330: 65 77 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e  ew;.      int nN
b340: 65 77 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6e 4d  ew = pSorter->nM
b350: 65 6d 6f 72 79 20 2a 20 32 3b 0a 20 20 20 20 20  emory * 2;.     
b360: 20 77 68 69 6c 65 28 20 6e 4e 65 77 20 3c 20 6e   while( nNew < n
b370: 4d 69 6e 20 29 20 6e 4e 65 77 20 3d 20 6e 4e 65  Min ) nNew = nNe
b380: 77 2a 32 3b 0a 20 20 20 20 20 20 69 66 28 20 6e  w*2;.      if( n
b390: 4e 65 77 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d  New > pSorter->m
b3a0: 78 50 6d 61 53 69 7a 65 20 29 20 6e 4e 65 77 20  xPmaSize ) nNew 
b3b0: 3d 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61  = pSorter->mxPma
b3c0: 53 69 7a 65 3b 0a 20 20 20 20 20 20 69 66 28 20  Size;.      if( 
b3d0: 6e 4e 65 77 20 3c 20 6e 4d 69 6e 20 29 20 6e 4e  nNew < nMin ) nN
b3e0: 65 77 20 3d 20 6e 4d 69 6e 3b 0a 0a 20 20 20 20  ew = nMin;..    
b3f0: 20 20 61 4e 65 77 20 3d 20 73 71 6c 69 74 65 33    aNew = sqlite3
b400: 52 65 61 6c 6c 6f 63 28 70 53 6f 72 74 65 72 2d  Realloc(pSorter-
b410: 3e 61 4d 65 6d 6f 72 79 2c 20 6e 4e 65 77 29 3b  >aMemory, nNew);
b420: 0a 20 20 20 20 20 20 69 66 28 20 21 61 4e 65 77  .      if( !aNew
b430: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
b440: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 70 53  _NOMEM;.      pS
b450: 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 3d  orter->pRecord =
b460: 20 28 53 6f 72 74 65 72 52 65 63 6f 72 64 2a 29   (SorterRecord*)
b470: 28 0a 20 20 20 20 20 20 20 20 20 20 61 4e 65 77  (.          aNew
b480: 20 2b 20 28 28 75 38 2a 29 70 53 6f 72 74 65 72   + ((u8*)pSorter
b490: 2d 3e 70 52 65 63 6f 72 64 20 2d 20 70 53 6f 72  ->pRecord - pSor
b4a0: 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 29 0a 20 20  ter->aMemory).  
b4b0: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 70 53 6f      );.      pSo
b4c0: 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 20 3d 20  rter->aMemory = 
b4d0: 61 4e 65 77 3b 0a 20 20 20 20 20 20 70 53 6f 72  aNew;.      pSor
b4e0: 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20 3d 20 6e  ter->nMemory = n
b4f0: 4e 65 77 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  New;.    }..    
b500: 70 4e 65 77 20 3d 20 28 53 6f 72 74 65 72 52 65  pNew = (SorterRe
b510: 63 6f 72 64 2a 29 26 70 53 6f 72 74 65 72 2d 3e  cord*)&pSorter->
b520: 61 4d 65 6d 6f 72 79 5b 70 53 6f 72 74 65 72 2d  aMemory[pSorter-
b530: 3e 69 4d 65 6d 6f 72 79 5d 3b 0a 20 20 20 20 70  >iMemory];.    p
b540: 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 20  Sorter->iMemory 
b550: 2b 3d 20 52 4f 55 4e 44 38 28 6e 52 65 71 29 3b  += ROUND8(nReq);
b560: 0a 20 20 20 20 70 4e 65 77 2d 3e 75 2e 69 4e 65  .    pNew->u.iNe
b570: 78 74 20 3d 20 28 75 38 2a 29 28 70 53 6f 72 74  xt = (u8*)(pSort
b580: 65 72 2d 3e 70 52 65 63 6f 72 64 29 20 2d 20 70  er->pRecord) - p
b590: 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 3b  Sorter->aMemory;
b5a0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 4e  .  }else{.    pN
b5b0: 65 77 20 3d 20 28 53 6f 72 74 65 72 52 65 63 6f  ew = (SorterReco
b5c0: 72 64 20 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c  rd *)sqlite3Mall
b5d0: 6f 63 28 6e 52 65 71 29 3b 0a 20 20 20 20 69 66  oc(nReq);.    if
b5e0: 28 20 70 4e 65 77 3d 3d 30 20 29 7b 0a 20 20 20  ( pNew==0 ){.   
b5f0: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
b600: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20  _NOMEM;.    }.  
b610: 20 20 70 4e 65 77 2d 3e 75 2e 70 4e 65 78 74 20    pNew->u.pNext 
b620: 3d 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f  = pSorter->pReco
b630: 72 64 3b 0a 20 20 7d 0a 0a 20 20 6d 65 6d 63 70  rd;.  }..  memcp
b640: 79 28 53 52 56 41 4c 28 70 4e 65 77 29 2c 20 70  y(SRVAL(pNew), p
b650: 56 61 6c 2d 3e 7a 2c 20 70 56 61 6c 2d 3e 6e 29  Val->z, pVal->n)
b660: 3b 0a 20 20 70 4e 65 77 2d 3e 6e 56 61 6c 20 3d  ;.  pNew->nVal =
b670: 20 70 56 61 6c 2d 3e 6e 3b 0a 20 20 70 53 6f 72   pVal->n;.  pSor
b680: 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 3d 20 70  ter->pRecord = p
b690: 4e 65 77 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72  New;..  return r
b6a0: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  c;.}../*.** Retu
b6b0: 72 6e 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d  rn the total num
b6c0: 62 65 72 20 6f 66 20 50 4d 41 73 20 69 6e 20 61  ber of PMAs in a
b6d0: 6c 6c 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c  ll temporary fil
b6e0: 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  es..*/.static in
b6f0: 74 20 76 64 62 65 53 6f 72 74 65 72 43 6f 75 6e  t vdbeSorterCoun
b700: 74 50 4d 41 28 56 64 62 65 53 6f 72 74 65 72 20  tPMA(VdbeSorter 
b710: 2a 70 53 6f 72 74 65 72 29 7b 0a 20 20 69 6e 74  *pSorter){.  int
b720: 20 6e 50 4d 41 20 3d 20 30 3b 0a 20 20 69 6e 74   nPMA = 0;.  int
b730: 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69   i;.  for(i=0; i
b740: 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 68 72 65 61  <pSorter->nThrea
b750: 64 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 6e 50 4d  d; i++){.    nPM
b760: 41 20 2b 3d 20 70 53 6f 72 74 65 72 2d 3e 61 54  A += pSorter->aT
b770: 68 72 65 61 64 5b 69 5d 2e 6e 50 4d 41 3b 0a 20  hread[i].nPMA;. 
b780: 20 7d 0a 20 20 72 65 74 75 72 6e 20 6e 50 4d 41   }.  return nPMA
b790: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 6e 63 65 20  ;.}../*.** Once 
b7a0: 74 68 65 20 73 6f 72 74 65 72 20 68 61 73 20 62  the sorter has b
b7b0: 65 65 6e 20 70 6f 70 75 6c 61 74 65 64 2c 20 74  een populated, t
b7c0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
b7d0: 63 61 6c 6c 65 64 20 74 6f 20 70 72 65 70 61 72  called to prepar
b7e0: 65 0a 2a 2a 20 66 6f 72 20 69 74 65 72 61 74 69  e.** for iterati
b7f0: 6e 67 20 74 68 72 6f 75 67 68 20 69 74 73 20 63  ng through its c
b800: 6f 6e 74 65 6e 74 73 20 69 6e 20 73 6f 72 74 65  ontents in sorte
b810: 64 20 6f 72 64 65 72 2e 0a 2a 2f 0a 69 6e 74 20  d order..*/.int 
b820: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
b830: 72 52 65 77 69 6e 64 28 73 71 6c 69 74 65 33 20  rRewind(sqlite3 
b840: 2a 64 62 2c 20 63 6f 6e 73 74 20 56 64 62 65 43  *db, const VdbeC
b850: 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74  ursor *pCsr, int
b860: 20 2a 70 62 45 6f 66 29 7b 0a 20 20 56 64 62 65   *pbEof){.  Vdbe
b870: 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20  Sorter *pSorter 
b880: 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b  = pCsr->pSorter;
b890: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
b8a0: 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
b8b0: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
b8c0: 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20  e */..  assert( 
b8d0: 70 53 6f 72 74 65 72 20 29 3b 0a 0a 20 20 2f 2a  pSorter );..  /*
b8e0: 20 49 66 20 6e 6f 20 64 61 74 61 20 68 61 73 20   If no data has 
b8f0: 62 65 65 6e 20 77 72 69 74 74 65 6e 20 74 6f 20  been written to 
b900: 64 69 73 6b 2c 20 74 68 65 6e 20 64 6f 20 6e 6f  disk, then do no
b910: 74 20 64 6f 20 73 6f 20 6e 6f 77 2e 20 49 6e 73  t do so now. Ins
b920: 74 65 61 64 2c 0a 20 20 2a 2a 20 73 6f 72 74 20  tead,.  ** sort 
b930: 74 68 65 20 56 64 62 65 53 6f 72 74 65 72 2e 70  the VdbeSorter.p
b940: 52 65 63 6f 72 64 20 6c 69 73 74 2e 20 54 68 65  Record list. The
b950: 20 76 64 62 65 20 6c 61 79 65 72 20 77 69 6c 6c   vdbe layer will
b960: 20 72 65 61 64 20 64 61 74 61 20 64 69 72 65 63   read data direc
b970: 74 6c 79 0a 20 20 2a 2a 20 66 72 6f 6d 20 74 68  tly.  ** from th
b980: 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74  e in-memory list
b990: 2e 20 20 2a 2f 0a 20 20 69 66 28 20 70 53 6f 72  .  */.  if( pSor
b9a0: 74 65 72 2d 3e 62 55 73 65 50 4d 41 3d 3d 30 20  ter->bUsePMA==0 
b9b0: 29 7b 0a 20 20 20 20 69 66 28 20 70 53 6f 72 74  ){.    if( pSort
b9c0: 65 72 2d 3e 70 52 65 63 6f 72 64 20 29 7b 0a 20  er->pRecord ){. 
b9d0: 20 20 20 20 20 53 6f 72 74 65 72 54 68 72 65 61       SorterThrea
b9e0: 64 20 2a 70 54 68 72 65 61 64 20 3d 20 26 70 53  d *pThread = &pS
b9f0: 6f 72 74 65 72 2d 3e 61 54 68 72 65 61 64 5b 30  orter->aThread[0
ba00: 5d 3b 0a 20 20 20 20 20 20 2a 70 62 45 6f 66 20  ];.      *pbEof 
ba10: 3d 20 30 3b 0a 20 20 20 20 20 20 70 54 68 72 65  = 0;.      pThre
ba20: 61 64 2d 3e 70 4c 69 73 74 20 3d 20 70 53 6f 72  ad->pList = pSor
ba30: 74 65 72 2d 3e 70 52 65 63 6f 72 64 3b 0a 20 20  ter->pRecord;.  
ba40: 20 20 20 20 70 54 68 72 65 61 64 2d 3e 65 57 6f      pThread->eWo
ba50: 72 6b 20 3d 20 53 4f 52 54 45 52 5f 54 48 52 45  rk = SORTER_THRE
ba60: 41 44 5f 53 4f 52 54 3b 0a 20 20 20 20 20 20 61  AD_SORT;.      a
ba70: 73 73 65 72 74 28 20 70 54 68 72 65 61 64 2d 3e  ssert( pThread->
ba80: 61 4c 69 73 74 4d 65 6d 6f 72 79 3d 3d 30 20 29  aListMemory==0 )
ba90: 3b 0a 20 20 20 20 20 20 70 54 68 72 65 61 64 2d  ;.      pThread-
baa0: 3e 61 4c 69 73 74 4d 65 6d 6f 72 79 20 3d 20 70  >aListMemory = p
bab0: 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 3b  Sorter->aMemory;
bac0: 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65  .      rc = vdbe
bad0: 53 6f 72 74 65 72 52 75 6e 54 68 72 65 61 64 28  SorterRunThread(
bae0: 70 54 68 72 65 61 64 29 3b 0a 20 20 20 20 20 20  pThread);.      
baf0: 70 54 68 72 65 61 64 2d 3e 61 4c 69 73 74 4d 65  pThread->aListMe
bb00: 6d 6f 72 79 20 3d 20 30 3b 0a 20 20 20 20 20 20  mory = 0;.      
bb10: 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64  pSorter->pRecord
bb20: 20 3d 20 70 54 68 72 65 61 64 2d 3e 70 4c 69 73   = pThread->pLis
bb30: 74 3b 0a 20 20 20 20 20 20 70 54 68 72 65 61 64  t;.      pThread
bb40: 2d 3e 70 4c 69 73 74 20 3d 20 30 3b 0a 20 20 20  ->pList = 0;.   
bb50: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2a 70   }else{.      *p
bb60: 62 45 6f 66 20 3d 20 31 3b 0a 20 20 20 20 7d 0a  bEof = 1;.    }.
bb70: 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
bb80: 20 7d 0a 0a 20 20 2f 2a 20 57 72 69 74 65 20 74   }..  /* Write t
bb90: 68 65 20 63 75 72 72 65 6e 74 20 69 6e 2d 6d 65  he current in-me
bba0: 6d 6f 72 79 20 6c 69 73 74 20 74 6f 20 61 20 50  mory list to a P
bbb0: 4d 41 2e 20 2a 2f 0a 20 20 69 66 28 20 70 53 6f  MA. */.  if( pSo
bbc0: 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 29 7b  rter->pRecord ){
bbd0: 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f  .    rc = vdbeSo
bbe0: 72 74 65 72 46 6c 75 73 68 50 4d 41 28 64 62 2c  rterFlushPMA(db,
bbf0: 20 70 43 73 72 2c 20 31 29 3b 0a 20 20 7d 0a 0a   pCsr, 1);.  }..
bc00: 20 20 2f 2a 20 4a 6f 69 6e 20 61 6c 6c 20 74 68    /* Join all th
bc10: 72 65 61 64 73 20 2a 2f 0a 20 20 72 63 20 3d 20  reads */.  rc = 
bc20: 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e 41 6c  vdbeSorterJoinAl
bc30: 6c 28 70 53 6f 72 74 65 72 2c 20 72 63 29 3b 0a  l(pSorter, rc);.
bc40: 0a 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20 61  .  /* If there a
bc50: 72 65 20 6d 6f 72 65 20 74 68 61 6e 20 53 4f 52  re more than SOR
bc60: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
bc70: 55 4e 54 20 50 4d 41 73 20 6f 6e 20 64 69 73 6b  UNT PMAs on disk
bc80: 2c 20 6d 65 72 67 65 0a 20 20 2a 2a 20 73 6f 6d  , merge.  ** som
bc90: 65 20 6f 66 20 74 68 65 6d 20 74 6f 67 65 74 68  e of them togeth
bca0: 65 72 20 73 6f 20 74 68 61 74 20 74 68 69 73 20  er so that this 
bcb0: 69 73 20 6e 6f 20 6c 6f 6e 67 65 72 20 74 68 65  is no longer the
bcc0: 20 63 61 73 65 2e 20 2a 2f 0a 20 20 69 66 28 20   case. */.  if( 
bcd0: 76 64 62 65 53 6f 72 74 65 72 43 6f 75 6e 74 50  vdbeSorterCountP
bce0: 4d 41 28 70 53 6f 72 74 65 72 29 3e 53 4f 52 54  MA(pSorter)>SORT
bcf0: 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55  ER_MAX_MERGE_COU
bd00: 4e 54 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b  NT ){.    int i;
bd10: 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 72 63  .    for(i=0; rc
bd20: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69  ==SQLITE_OK && i
bd30: 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 68 72 65 61  <pSorter->nThrea
bd40: 64 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 53  d; i++){.      S
bd50: 6f 72 74 65 72 54 68 72 65 61 64 20 2a 70 54 68  orterThread *pTh
bd60: 72 65 61 64 20 3d 20 26 70 53 6f 72 74 65 72 2d  read = &pSorter-
bd70: 3e 61 54 68 72 65 61 64 5b 69 5d 3b 0a 20 20 20  >aThread[i];.   
bd80: 20 20 20 69 66 28 20 70 54 68 72 65 61 64 2d 3e     if( pThread->
bd90: 70 54 65 6d 70 31 20 29 7b 0a 20 20 20 20 20 20  pTemp1 ){.      
bda0: 20 20 70 54 68 72 65 61 64 2d 3e 6e 43 6f 6e 73    pThread->nCons
bdb0: 6f 6c 69 64 61 74 65 20 3d 20 53 4f 52 54 45 52  olidate = SORTER
bdc0: 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
bdd0: 20 2f 20 70 53 6f 72 74 65 72 2d 3e 6e 54 68 72   / pSorter->nThr
bde0: 65 61 64 3b 0a 20 20 20 20 20 20 20 20 70 54 68  ead;.        pTh
bdf0: 72 65 61 64 2d 3e 65 57 6f 72 6b 20 3d 20 53 4f  read->eWork = SO
be00: 52 54 45 52 5f 54 48 52 45 41 44 5f 43 4f 4e 53  RTER_THREAD_CONS
be10: 3b 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41  ;..#if SQLITE_MA
be20: 58 5f 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53  X_WORKER_THREADS
be30: 3e 30 0a 20 20 20 20 20 20 20 20 69 66 28 20 69  >0.        if( i
be40: 3c 28 70 53 6f 72 74 65 72 2d 3e 6e 54 68 72 65  <(pSorter->nThre
be50: 61 64 2d 31 29 20 29 7b 0a 20 20 20 20 20 20 20  ad-1) ){.       
be60: 20 20 20 76 6f 69 64 20 2a 70 43 74 78 20 3d 20     void *pCtx = 
be70: 28 76 6f 69 64 2a 29 70 54 68 72 65 61 64 3b 0a  (void*)pThread;.
be80: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 73            rc = s
be90: 71 6c 69 74 65 33 54 68 72 65 61 64 43 72 65 61  qlite3ThreadCrea
bea0: 74 65 28 26 70 54 68 72 65 61 64 2d 3e 70 54 68  te(&pThread->pTh
beb0: 72 65 61 64 2c 76 64 62 65 53 6f 72 74 65 72 54  read,vdbeSorterT
bec0: 68 72 65 61 64 4d 61 69 6e 2c 70 43 74 78 29 3b  hreadMain,pCtx);
bed0: 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 0a 23  .        }else.#
bee0: 65 6e 64 69 66 0a 20 20 20 20 20 20 20 20 7b 0a  endif.        {.
bef0: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 76            rc = v
bf00: 64 62 65 53 6f 72 74 65 72 52 75 6e 54 68 72 65  dbeSorterRunThre
bf10: 61 64 28 70 54 68 72 65 61 64 29 3b 0a 20 20 20  ad(pThread);.   
bf20: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
bf30: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4a     }.  }..  /* J
bf40: 6f 69 6e 20 61 6c 6c 20 74 68 72 65 61 64 73 20  oin all threads 
bf50: 2a 2f 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f  */.  rc = vdbeSo
bf60: 72 74 65 72 4a 6f 69 6e 41 6c 6c 28 70 53 6f 72  rterJoinAll(pSor
bf70: 74 65 72 2c 20 72 63 29 3b 0a 0a 20 20 2f 2a 20  ter, rc);..  /* 
bf80: 41 73 73 75 6d 69 6e 67 20 6e 6f 20 65 72 72 6f  Assuming no erro
bf90: 72 73 20 68 61 76 65 20 6f 63 63 75 72 72 65 64  rs have occurred
bfa0: 2c 20 73 65 74 20 75 70 20 61 20 6d 65 72 67 65  , set up a merge
bfb0: 72 20 73 74 72 75 63 74 75 72 65 20 74 6f 20 72  r structure to r
bfc0: 65 61 64 0a 20 20 2a 2a 20 61 6e 64 20 6d 65 72  ead.  ** and mer
bfd0: 67 65 20 61 6c 6c 20 72 65 6d 61 69 6e 69 6e 67  ge all remaining
bfe0: 20 50 4d 41 73 2e 20 20 2a 2f 0a 20 20 61 73 73   PMAs.  */.  ass
bff0: 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 70 4d  ert( pSorter->pM
c000: 65 72 67 65 72 3d 3d 30 20 29 3b 0a 20 20 69 66  erger==0 );.  if
c010: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
c020: 29 7b 0a 20 20 20 20 69 6e 74 20 6e 49 74 65 72  ){.    int nIter
c030: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
c040: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
c050: 66 20 69 74 65 72 61 74 6f 72 73 20 75 73 65 64  f iterators used
c060: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20   */.    int i;. 
c070: 20 20 20 53 6f 72 74 65 72 4d 65 72 67 65 72 20     SorterMerger 
c080: 2a 70 4d 65 72 67 65 72 3b 0a 20 20 20 20 66 6f  *pMerger;.    fo
c090: 72 28 69 3d 30 3b 20 69 3c 70 53 6f 72 74 65 72  r(i=0; i<pSorter
c0a0: 2d 3e 6e 54 68 72 65 61 64 3b 20 69 2b 2b 29 7b  ->nThread; i++){
c0b0: 0a 20 20 20 20 20 20 6e 49 74 65 72 20 2b 3d 20  .      nIter += 
c0c0: 70 53 6f 72 74 65 72 2d 3e 61 54 68 72 65 61 64  pSorter->aThread
c0d0: 5b 69 5d 2e 6e 50 4d 41 3b 0a 20 20 20 20 7d 0a  [i].nPMA;.    }.
c0e0: 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 4d  .    pSorter->pM
c0f0: 65 72 67 65 72 20 3d 20 70 4d 65 72 67 65 72 20  erger = pMerger 
c100: 3d 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67  = vdbeSorterMerg
c110: 65 72 4e 65 77 28 6e 49 74 65 72 29 3b 0a 20 20  erNew(nIter);.  
c120: 20 20 69 66 28 20 70 4d 65 72 67 65 72 3d 3d 30    if( pMerger==0
c130: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53   ){.      rc = S
c140: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
c150: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 6e   }else{.      in
c160: 74 20 69 49 74 65 72 20 3d 20 30 3b 0a 20 20 20  t iIter = 0;.   
c170: 20 20 20 69 6e 74 20 69 54 68 72 65 61 64 20 3d     int iThread =
c180: 20 30 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 54   0;.      for(iT
c190: 68 72 65 61 64 3d 30 3b 20 69 54 68 72 65 61 64  hread=0; iThread
c1a0: 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 68 72 65 61  <pSorter->nThrea
c1b0: 64 3b 20 69 54 68 72 65 61 64 2b 2b 29 7b 0a 20  d; iThread++){. 
c1c0: 20 20 20 20 20 20 20 69 6e 74 20 69 50 4d 41 3b         int iPMA;
c1d0: 0a 20 20 20 20 20 20 20 20 69 36 34 20 69 52 65  .        i64 iRe
c1e0: 61 64 4f 66 66 20 3d 20 30 3b 0a 20 20 20 20 20  adOff = 0;.     
c1f0: 20 20 20 53 6f 72 74 65 72 54 68 72 65 61 64 20     SorterThread 
c200: 2a 70 54 68 72 65 61 64 20 3d 20 26 70 53 6f 72  *pThread = &pSor
c210: 74 65 72 2d 3e 61 54 68 72 65 61 64 5b 69 54 68  ter->aThread[iTh
c220: 72 65 61 64 5d 3b 0a 20 20 20 20 20 20 20 20 66  read];.        f
c230: 6f 72 28 69 50 4d 41 3d 30 3b 20 69 50 4d 41 3c  or(iPMA=0; iPMA<
c240: 70 54 68 72 65 61 64 2d 3e 6e 50 4d 41 20 26 26  pThread->nPMA &&
c250: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20   rc==SQLITE_OK; 
c260: 69 50 4d 41 2b 2b 29 7b 0a 20 20 20 20 20 20 20  iPMA++){.       
c270: 20 20 20 69 36 34 20 6e 44 75 6d 6d 79 20 3d 20     i64 nDummy = 
c280: 30 3b 0a 20 20 20 20 20 20 20 20 20 20 56 64 62  0;.          Vdb
c290: 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74  eSorterIter *pIt
c2a0: 65 72 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61  er = &pMerger->a
c2b0: 49 74 65 72 5b 69 49 74 65 72 2b 2b 5d 3b 0a 20  Iter[iIter++];. 
c2c0: 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64           rc = vd
c2d0: 62 65 53 6f 72 74 65 72 49 74 65 72 49 6e 69 74  beSorterIterInit
c2e0: 28 70 54 68 72 65 61 64 2c 20 69 52 65 61 64 4f  (pThread, iReadO
c2f0: 66 66 2c 20 70 49 74 65 72 2c 20 26 6e 44 75 6d  ff, pIter, &nDum
c300: 6d 79 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69  my);.          i
c310: 52 65 61 64 4f 66 66 20 3d 20 70 49 74 65 72 2d  ReadOff = pIter-
c320: 3e 69 45 6f 66 3b 0a 20 20 20 20 20 20 20 20 7d  >iEof;.        }
c330: 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
c340: 66 6f 72 28 69 3d 70 4d 65 72 67 65 72 2d 3e 6e  for(i=pMerger->n
c350: 54 72 65 65 2d 31 3b 20 72 63 3d 3d 53 51 4c 49  Tree-1; rc==SQLI
c360: 54 45 5f 4f 4b 20 26 26 20 69 3e 30 3b 20 69 2d  TE_OK && i>0; i-
c370: 2d 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d  -){.        rc =
c380: 20 76 64 62 65 53 6f 72 74 65 72 44 6f 43 6f 6d   vdbeSorterDoCom
c390: 70 61 72 65 28 26 70 53 6f 72 74 65 72 2d 3e 61  pare(&pSorter->a
c3a0: 54 68 72 65 61 64 5b 30 5d 2c 20 70 4d 65 72 67  Thread[0], pMerg
c3b0: 65 72 2c 20 69 29 3b 0a 20 20 20 20 20 20 7d 0a  er, i);.      }.
c3c0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28      }.  }..  if(
c3d0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
c3e0: 7b 0a 20 20 20 20 2a 70 62 45 6f 66 20 3d 20 28  {.    *pbEof = (
c3f0: 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72  pSorter->pMerger
c400: 2d 3e 61 49 74 65 72 5b 70 53 6f 72 74 65 72 2d  ->aIter[pSorter-
c410: 3e 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b  >pMerger->aTree[
c420: 31 5d 5d 2e 70 46 69 6c 65 3d 3d 30 29 3b 0a 20  1]].pFile==0);. 
c430: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
c440: 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65  }../*.** Advance
c450: 20 74 6f 20 74 68 65 20 6e 65 78 74 20 65 6c 65   to the next ele
c460: 6d 65 6e 74 20 69 6e 20 74 68 65 20 73 6f 72 74  ment in the sort
c470: 65 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  er..*/.int sqlit
c480: 65 33 56 64 62 65 53 6f 72 74 65 72 4e 65 78 74  e3VdbeSorterNext
c490: 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 63 6f  (sqlite3 *db, co
c4a0: 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a  nst VdbeCursor *
c4b0: 70 43 73 72 2c 20 69 6e 74 20 2a 70 62 45 6f 66  pCsr, int *pbEof
c4c0: 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20  ){.  VdbeSorter 
c4d0: 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d  *pSorter = pCsr-
c4e0: 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20  >pSorter;.  int 
c4f0: 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rc;             
c500: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
c510: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20  eturn code */.. 
c520: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 70 4d   if( pSorter->pM
c530: 65 72 67 65 72 20 29 7b 0a 20 20 20 20 72 63 20  erger ){.    rc 
c540: 3d 20 76 64 62 65 53 6f 72 74 65 72 4e 65 78 74  = vdbeSorterNext
c550: 28 26 70 53 6f 72 74 65 72 2d 3e 61 54 68 72 65  (&pSorter->aThre
c560: 61 64 5b 30 5d 2c 20 70 53 6f 72 74 65 72 2d 3e  ad[0], pSorter->
c570: 70 4d 65 72 67 65 72 2c 20 70 62 45 6f 66 29 3b  pMerger, pbEof);
c580: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 53 6f  .  }else{.    So
c590: 72 74 65 72 52 65 63 6f 72 64 20 2a 70 46 72 65  rterRecord *pFre
c5a0: 65 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 52 65  e = pSorter->pRe
c5b0: 63 6f 72 64 3b 0a 20 20 20 20 70 53 6f 72 74 65  cord;.    pSorte
c5c0: 72 2d 3e 70 52 65 63 6f 72 64 20 3d 20 70 46 72  r->pRecord = pFr
c5d0: 65 65 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20 20 20  ee->u.pNext;.   
c5e0: 20 70 46 72 65 65 2d 3e 75 2e 70 4e 65 78 74 20   pFree->u.pNext 
c5f0: 3d 20 30 3b 0a 20 20 20 20 69 66 28 20 70 53 6f  = 0;.    if( pSo
c600: 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 3d 3d 30  rter->aMemory==0
c610: 20 29 20 76 64 62 65 53 6f 72 74 65 72 52 65 63   ) vdbeSorterRec
c620: 6f 72 64 46 72 65 65 28 64 62 2c 20 70 46 72 65  ordFree(db, pFre
c630: 65 29 3b 0a 20 20 20 20 2a 70 62 45 6f 66 20 3d  e);.    *pbEof =
c640: 20 21 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f   !pSorter->pReco
c650: 72 64 3b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c  rd;.    rc = SQL
c660: 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 20 20 72 65  ITE_OK;.  }.  re
c670: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
c680: 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74  * Return a point
c690: 65 72 20 74 6f 20 61 20 62 75 66 66 65 72 20 6f  er to a buffer o
c6a0: 77 6e 65 64 20 62 79 20 74 68 65 20 73 6f 72 74  wned by the sort
c6b0: 65 72 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73  er that contains
c6c0: 20 74 68 65 20 0a 2a 2a 20 63 75 72 72 65 6e 74   the .** current
c6d0: 20 6b 65 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20   key..*/.static 
c6e0: 76 6f 69 64 20 2a 76 64 62 65 53 6f 72 74 65 72  void *vdbeSorter
c6f0: 52 6f 77 6b 65 79 28 0a 20 20 63 6f 6e 73 74 20  Rowkey(.  const 
c700: 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72  VdbeSorter *pSor
c710: 74 65 72 2c 20 20 20 20 20 20 2f 2a 20 53 6f 72  ter,      /* Sor
c720: 74 65 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20  ter object */.  
c730: 69 6e 74 20 2a 70 6e 4b 65 79 20 20 20 20 20 20  int *pnKey      
c740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c750: 2f 2a 20 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20  /* OUT: Size of 
c760: 63 75 72 72 65 6e 74 20 6b 65 79 20 69 6e 20 62  current key in b
c770: 79 74 65 73 20 2a 2f 0a 29 7b 0a 20 20 76 6f 69  ytes */.){.  voi
c780: 64 20 2a 70 4b 65 79 3b 0a 20 20 69 66 28 20 70  d *pKey;.  if( p
c790: 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 20  Sorter->pMerger 
c7a0: 29 7b 0a 20 20 20 20 56 64 62 65 53 6f 72 74 65  ){.    VdbeSorte
c7b0: 72 49 74 65 72 20 2a 70 49 74 65 72 3b 0a 20 20  rIter *pIter;.  
c7c0: 20 20 70 49 74 65 72 20 3d 20 26 70 53 6f 72 74    pIter = &pSort
c7d0: 65 72 2d 3e 70 4d 65 72 67 65 72 2d 3e 61 49 74  er->pMerger->aIt
c7e0: 65 72 5b 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65  er[ pSorter->pMe
c7f0: 72 67 65 72 2d 3e 61 54 72 65 65 5b 31 5d 20 5d  rger->aTree[1] ]
c800: 3b 0a 20 20 20 20 2a 70 6e 4b 65 79 20 3d 20 70  ;.    *pnKey = p
c810: 49 74 65 72 2d 3e 6e 4b 65 79 3b 0a 20 20 20 20  Iter->nKey;.    
c820: 70 4b 65 79 20 3d 20 70 49 74 65 72 2d 3e 61 4b  pKey = pIter->aK
c830: 65 79 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ey;.  }else{.   
c840: 20 2a 70 6e 4b 65 79 20 3d 20 70 53 6f 72 74 65   *pnKey = pSorte
c850: 72 2d 3e 70 52 65 63 6f 72 64 2d 3e 6e 56 61 6c  r->pRecord->nVal
c860: 3b 0a 20 20 20 20 70 4b 65 79 20 3d 20 53 52 56  ;.    pKey = SRV
c870: 41 4c 28 70 53 6f 72 74 65 72 2d 3e 70 52 65 63  AL(pSorter->pRec
c880: 6f 72 64 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  ord);.  }.  retu
c890: 72 6e 20 70 4b 65 79 3b 0a 7d 0a 0a 2f 2a 0a 2a  rn pKey;.}../*.*
c8a0: 2a 20 43 6f 70 79 20 74 68 65 20 63 75 72 72 65  * Copy the curre
c8b0: 6e 74 20 73 6f 72 74 65 72 20 6b 65 79 20 69 6e  nt sorter key in
c8c0: 74 6f 20 74 68 65 20 6d 65 6d 6f 72 79 20 63 65  to the memory ce
c8d0: 6c 6c 20 70 4f 75 74 2e 0a 2a 2f 0a 69 6e 74 20  ll pOut..*/.int 
c8e0: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
c8f0: 72 52 6f 77 6b 65 79 28 63 6f 6e 73 74 20 56 64  rRowkey(const Vd
c900: 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  beCursor *pCsr, 
c910: 4d 65 6d 20 2a 70 4f 75 74 29 7b 0a 20 20 56 64  Mem *pOut){.  Vd
c920: 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
c930: 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65  r = pCsr->pSorte
c940: 72 3b 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 3b  r;.  void *pKey;
c950: 20 69 6e 74 20 6e 4b 65 79 3b 20 20 20 20 20 20   int nKey;      
c960: 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 6b       /* Sorter k
c970: 65 79 20 74 6f 20 63 6f 70 79 20 69 6e 74 6f 20  ey to copy into 
c980: 70 4f 75 74 20 2a 2f 0a 0a 20 20 70 4b 65 79 20  pOut */..  pKey 
c990: 3d 20 76 64 62 65 53 6f 72 74 65 72 52 6f 77 6b  = vdbeSorterRowk
c9a0: 65 79 28 70 53 6f 72 74 65 72 2c 20 26 6e 4b 65  ey(pSorter, &nKe
c9b0: 79 29 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65  y);.  if( sqlite
c9c0: 33 56 64 62 65 4d 65 6d 47 72 6f 77 28 70 4f 75  3VdbeMemGrow(pOu
c9d0: 74 2c 20 6e 4b 65 79 2c 20 30 29 20 29 7b 0a 20  t, nKey, 0) ){. 
c9e0: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
c9f0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 70 4f  _NOMEM;.  }.  pO
ca00: 75 74 2d 3e 6e 20 3d 20 6e 4b 65 79 3b 0a 20 20  ut->n = nKey;.  
ca10: 4d 65 6d 53 65 74 54 79 70 65 46 6c 61 67 28 70  MemSetTypeFlag(p
ca20: 4f 75 74 2c 20 4d 45 4d 5f 42 6c 6f 62 29 3b 0a  Out, MEM_Blob);.
ca30: 20 20 6d 65 6d 63 70 79 28 70 4f 75 74 2d 3e 7a    memcpy(pOut->z
ca40: 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 0a  , pKey, nKey);..
ca50: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
ca60: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d  OK;.}../*.** Com
ca70: 70 61 72 65 20 74 68 65 20 6b 65 79 20 69 6e 20  pare the key in 
ca80: 6d 65 6d 6f 72 79 20 63 65 6c 6c 20 70 56 61 6c  memory cell pVal
ca90: 20 77 69 74 68 20 74 68 65 20 6b 65 79 20 74 68   with the key th
caa0: 61 74 20 74 68 65 20 73 6f 72 74 65 72 20 63 75  at the sorter cu
cab0: 72 73 6f 72 0a 2a 2a 20 70 61 73 73 65 64 20 61  rsor.** passed a
cac0: 73 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75  s the first argu
cad0: 6d 65 6e 74 20 63 75 72 72 65 6e 74 6c 79 20 70  ment currently p
cae0: 6f 69 6e 74 73 20 74 6f 2e 20 46 6f 72 20 74 68  oints to. For th
caf0: 65 20 70 75 72 70 6f 73 65 73 20 6f 66 0a 2a 2a  e purposes of.**
cb00: 20 74 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2c   the comparison,
cb10: 20 69 67 6e 6f 72 65 20 74 68 65 20 72 6f 77 69   ignore the rowi
cb20: 64 20 66 69 65 6c 64 20 61 74 20 74 68 65 20 65  d field at the e
cb30: 6e 64 20 6f 66 20 65 61 63 68 20 72 65 63 6f 72  nd of each recor
cb40: 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20  d..**.** If the 
cb50: 73 6f 72 74 65 72 20 63 75 72 73 6f 72 20 6b 65  sorter cursor ke
cb60: 79 20 63 6f 6e 74 61 69 6e 73 20 61 6e 79 20 4e  y contains any N
cb70: 55 4c 4c 20 76 61 6c 75 65 73 2c 20 63 6f 6e 73  ULL values, cons
cb80: 69 64 65 72 20 69 74 20 74 6f 20 62 65 0a 2a 2a  ider it to be.**
cb90: 20 6c 65 73 73 20 74 68 61 6e 20 70 56 61 6c 2e   less than pVal.
cba0: 20 45 76 6e 20 69 66 20 70 56 61 6c 20 61 6c 73   Evn if pVal als
cbb0: 6f 20 63 6f 6e 74 61 69 6e 73 20 4e 55 4c 4c 20  o contains NULL 
cbc0: 76 61 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 49 66  values..**.** If
cbd0: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
cbe0: 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69  , return an SQLi
cbf0: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 28 69  te error code (i
cc00: 2e 65 2e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  .e. SQLITE_NOMEM
cc10: 29 2e 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c  )..** Otherwise,
cc20: 20 73 65 74 20 2a 70 52 65 73 20 74 6f 20 61 20   set *pRes to a 
cc30: 6e 65 67 61 74 69 76 65 2c 20 7a 65 72 6f 20 6f  negative, zero o
cc40: 72 20 70 6f 73 69 74 69 76 65 20 76 61 6c 75 65  r positive value
cc50: 20 69 66 20 74 68 65 0a 2a 2a 20 6b 65 79 20 69   if the.** key i
cc60: 6e 20 70 56 61 6c 20 69 73 20 73 6d 61 6c 6c 65  n pVal is smalle
cc70: 72 20 74 68 61 6e 2c 20 65 71 75 61 6c 20 74 6f  r than, equal to
cc80: 20 6f 72 20 6c 61 72 67 65 72 20 74 68 61 6e 20   or larger than 
cc90: 74 68 65 20 63 75 72 72 65 6e 74 20 73 6f 72 74  the current sort
cca0: 65 72 0a 2a 2a 20 6b 65 79 2e 0a 2a 2f 0a 69 6e  er.** key..*/.in
ccb0: 74 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72  t sqlite3VdbeSor
ccc0: 74 65 72 43 6f 6d 70 61 72 65 28 0a 20 20 63 6f  terCompare(.  co
ccd0: 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a  nst VdbeCursor *
cce0: 70 43 73 72 2c 20 20 20 20 20 20 20 20 20 2f 2a  pCsr,         /*
ccf0: 20 53 6f 72 74 65 72 20 63 75 72 73 6f 72 20 2a   Sorter cursor *
cd00: 2f 0a 20 20 4d 65 6d 20 2a 70 56 61 6c 2c 20 20  /.  Mem *pVal,  
cd10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cd20: 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 74 6f 20      /* Value to 
cd30: 63 6f 6d 70 61 72 65 20 74 6f 20 63 75 72 72 65  compare to curre
cd40: 6e 74 20 73 6f 72 74 65 72 20 6b 65 79 20 2a 2f  nt sorter key */
cd50: 0a 20 20 69 6e 74 20 6e 49 67 6e 6f 72 65 2c 20  .  int nIgnore, 
cd60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cd70: 20 20 20 2f 2a 20 49 67 6e 6f 72 65 20 74 68 69     /* Ignore thi
cd80: 73 20 6d 61 6e 79 20 66 69 65 6c 64 73 20 61 74  s many fields at
cd90: 20 74 68 65 20 65 6e 64 20 2a 2f 0a 20 20 69 6e   the end */.  in
cda0: 74 20 2a 70 52 65 73 20 20 20 20 20 20 20 20 20  t *pRes         
cdb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
cdc0: 20 4f 55 54 3a 20 52 65 73 75 6c 74 20 6f 66 20   OUT: Result of 
cdd0: 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f 0a 29 7b  comparison */.){
cde0: 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70  .  VdbeSorter *p
cdf0: 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70  Sorter = pCsr->p
ce00: 53 6f 72 74 65 72 3b 0a 20 20 55 6e 70 61 63 6b  Sorter;.  Unpack
ce10: 65 64 52 65 63 6f 72 64 20 2a 72 32 20 3d 20 70  edRecord *r2 = p
ce20: 53 6f 72 74 65 72 2d 3e 61 54 68 72 65 61 64 5b  Sorter->aThread[
ce30: 30 5d 2e 70 55 6e 70 61 63 6b 65 64 3b 0a 20 20  0].pUnpacked;.  
ce40: 4b 65 79 49 6e 66 6f 20 2a 70 4b 65 79 49 6e 66  KeyInfo *pKeyInf
ce50: 6f 20 3d 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e  o = pCsr->pKeyIn
ce60: 66 6f 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 76  fo;.  int i;.  v
ce70: 6f 69 64 20 2a 70 4b 65 79 3b 20 69 6e 74 20 6e  oid *pKey; int n
ce80: 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 2f  Key;           /
ce90: 2a 20 53 6f 72 74 65 72 20 6b 65 79 20 74 6f 20  * Sorter key to 
cea0: 63 6f 6d 70 61 72 65 20 70 56 61 6c 20 77 69 74  compare pVal wit
ceb0: 68 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20  h */..  assert( 
cec0: 72 32 2d 3e 6e 46 69 65 6c 64 3e 3d 70 4b 65 79  r2->nField>=pKey
ced0: 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64 2d 6e 49 67  Info->nField-nIg
cee0: 6e 6f 72 65 20 29 3b 0a 20 20 72 32 2d 3e 6e 46  nore );.  r2->nF
cef0: 69 65 6c 64 20 3d 20 70 4b 65 79 49 6e 66 6f 2d  ield = pKeyInfo-
cf00: 3e 6e 46 69 65 6c 64 2d 6e 49 67 6e 6f 72 65 3b  >nField-nIgnore;
cf10: 0a 0a 20 20 70 4b 65 79 20 3d 20 76 64 62 65 53  ..  pKey = vdbeS
cf20: 6f 72 74 65 72 52 6f 77 6b 65 79 28 70 53 6f 72  orterRowkey(pSor
cf30: 74 65 72 2c 20 26 6e 4b 65 79 29 3b 0a 20 20 73  ter, &nKey);.  s
cf40: 71 6c 69 74 65 33 56 64 62 65 52 65 63 6f 72 64  qlite3VdbeRecord
cf50: 55 6e 70 61 63 6b 28 70 4b 65 79 49 6e 66 6f 2c  Unpack(pKeyInfo,
cf60: 20 6e 4b 65 79 2c 20 70 4b 65 79 2c 20 72 32 29   nKey, pKey, r2)
cf70: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 72  ;.  for(i=0; i<r
cf80: 32 2d 3e 6e 46 69 65 6c 64 3b 20 69 2b 2b 29 7b  2->nField; i++){
cf90: 0a 20 20 20 20 69 66 28 20 72 32 2d 3e 61 4d 65  .    if( r2->aMe
cfa0: 6d 5b 69 5d 2e 66 6c 61 67 73 20 26 20 4d 45 4d  m[i].flags & MEM
cfb0: 5f 4e 75 6c 6c 20 29 7b 0a 20 20 20 20 20 20 2a  _Null ){.      *
cfc0: 70 52 65 73 20 3d 20 2d 31 3b 0a 20 20 20 20 20  pRes = -1;.     
cfd0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
cfe0: 4b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  K;.    }.  }..  
cff0: 2a 70 52 65 73 20 3d 20 73 71 6c 69 74 65 33 56  *pRes = sqlite3V
d000: 64 62 65 52 65 63 6f 72 64 43 6f 6d 70 61 72 65  dbeRecordCompare
d010: 28 70 56 61 6c 2d 3e 6e 2c 20 70 56 61 6c 2d 3e  (pVal->n, pVal->
d020: 7a 2c 20 72 32 2c 20 30 29 3b 0a 20 20 72 65 74  z, r2, 0);.  ret
d030: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
d040: 0a                                               .