/ Hex Artifact Content
Login

Artifact 0fbaf5b3ec3e779d81c4db4eb2f0ae5f44fbb02c:


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 4d 61 78 69 6d 75 6d 20 6e 75 6d  *.** Maximum num
0370: 62 65 72 20 6f 66 20 74 68 72 65 61 64 73 20 74  ber of threads t
0380: 6f 20 75 73 65 2e 20 53 65 74 74 69 6e 67 20 74  o use. Setting t
0390: 68 69 73 20 76 61 6c 75 65 20 74 6f 20 31 20 66  his value to 1 f
03a0: 6f 72 63 65 73 20 61 6c 6c 0a 2a 2a 20 6f 70 65  orces all.** ope
03b0: 72 61 74 69 6f 6e 73 20 74 6f 20 62 65 20 73 69  rations to be si
03c0: 6e 67 6c 65 2d 74 68 72 65 61 64 65 64 2e 0a 2a  ngle-threaded..*
03d0: 2f 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45  /.#ifndef SQLITE
03e0: 5f 4d 41 58 5f 53 4f 52 54 45 52 5f 54 48 52 45  _MAX_SORTER_THRE
03f0: 41 44 0a 23 20 64 65 66 69 6e 65 20 53 51 4c 49  AD.# define SQLI
0400: 54 45 5f 4d 41 58 5f 53 4f 52 54 45 52 5f 54 48  TE_MAX_SORTER_TH
0410: 52 45 41 44 20 31 0a 23 65 6e 64 69 66 0a 0a 2f  READ 1.#endif../
0420: 2a 0a 2a 2a 20 43 61 6e 64 69 64 61 74 65 20 76  *.** Candidate v
0430: 61 6c 75 65 73 20 66 6f 72 20 53 6f 72 74 65 72  alues for Sorter
0440: 54 68 72 65 61 64 2e 65 57 6f 72 6b 0a 2a 2f 0a  Thread.eWork.*/.
0450: 23 64 65 66 69 6e 65 20 53 4f 52 54 45 52 5f 54  #define SORTER_T
0460: 48 52 45 41 44 5f 53 4f 52 54 20 20 20 31 0a 23  HREAD_SORT   1.#
0470: 64 65 66 69 6e 65 20 53 4f 52 54 45 52 5f 54 48  define SORTER_TH
0480: 52 45 41 44 5f 54 4f 5f 50 4d 41 20 32 0a 23 64  READ_TO_PMA 2.#d
0490: 65 66 69 6e 65 20 53 4f 52 54 45 52 5f 54 48 52  efine SORTER_THR
04a0: 45 41 44 5f 43 4f 4e 53 20 20 20 33 0a 0a 2f 2a  EAD_CONS   3../*
04b0: 0a 2a 2a 20 4d 75 63 68 20 6f 66 20 74 68 65 20  .** Much of the 
04c0: 77 6f 72 6b 20 70 65 72 66 6f 72 6d 65 64 20 69  work performed i
04d0: 6e 20 74 68 69 73 20 6d 6f 64 75 6c 65 20 74 6f  n this module to
04e0: 20 73 6f 72 74 20 74 68 65 20 6c 69 73 74 20 6f   sort the list o
04f0: 66 20 72 65 63 6f 72 64 73 20 69 73 20 0a 2a 2a  f records is .**
0500: 20 62 72 6f 6b 65 6e 20 64 6f 77 6e 20 69 6e 74   broken down int
0510: 6f 20 73 6d 61 6c 6c 65 72 20 75 6e 69 74 73 20  o smaller units 
0520: 74 68 61 74 20 6d 61 79 20 62 65 20 70 65 66 6f  that may be pefo
0530: 72 6d 65 64 20 69 6e 20 70 61 72 61 6c 6c 65 6c  rmed in parallel
0540: 2e 20 49 6e 20 6f 72 64 65 72 0a 2a 2a 20 74 6f  . In order.** to
0550: 20 70 65 72 66 6f 72 6d 20 73 75 63 68 20 61 20   perform such a 
0560: 75 6e 69 74 20 6f 66 20 77 6f 72 6b 2c 20 61 6e  unit of work, an
0570: 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65   instance of the
0580: 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 74 72 75 63   following struc
0590: 74 75 72 65 0a 2a 2a 20 69 73 20 63 6f 6e 66 69  ture.** is confi
05a0: 67 75 72 65 64 20 61 6e 64 20 70 61 73 73 65 64  gured and passed
05b0: 20 74 6f 20 76 64 62 65 53 6f 72 74 65 72 54 68   to vdbeSorterTh
05c0: 72 65 61 64 4d 61 69 6e 28 29 20 2d 20 65 69 74  readMain() - eit
05d0: 68 65 72 20 64 69 72 65 63 74 6c 79 20 62 79 20  her directly by 
05e0: 0a 2a 2a 20 74 68 65 20 6d 61 69 6e 20 74 68 72  .** the main thr
05f0: 65 61 64 20 6f 72 20 76 69 61 20 61 20 62 61 63  ead or via a bac
0600: 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 2e 0a  kground thread..
0610: 2a 2a 0a 2a 2a 20 45 78 61 63 74 6c 79 20 53 51  **.** Exactly SQ
0620: 4c 49 54 45 5f 4d 41 58 5f 53 4f 52 54 45 52 5f  LITE_MAX_SORTER_
0630: 54 48 52 45 41 44 20 69 6e 73 74 61 6e 63 65 73  THREAD instances
0640: 20 6f 66 20 74 68 69 73 20 73 74 72 75 63 74 75   of this structu
0650: 72 65 20 61 72 65 20 61 6c 6c 6f 63 61 74 65 64  re are allocated
0660: 0a 2a 2a 20 61 73 20 70 61 72 74 20 6f 66 20 65  .** as part of e
0670: 61 63 68 20 56 64 62 65 53 6f 72 74 65 72 20 6f  ach VdbeSorter o
0680: 62 6a 65 63 74 2e 20 49 6e 73 74 61 6e 63 65 73  bject. Instances
0690: 20 61 72 65 20 6e 65 76 65 72 20 61 6c 6c 6f 63   are never alloc
06a0: 61 74 65 64 20 61 6e 79 20 6f 74 68 65 72 0a 2a  ated any other.*
06b0: 2a 20 77 61 79 2e 0a 2a 2a 0a 2a 2a 20 57 68 65  * way..**.** Whe
06c0: 6e 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74  n a background t
06d0: 68 72 65 61 64 20 69 73 20 6c 61 75 6e 63 68 65  hread is launche
06e0: 64 20 74 6f 20 70 65 72 66 6f 72 6d 20 77 6f 72  d to perform wor
06f0: 6b 2c 20 53 6f 72 74 65 72 54 68 72 65 61 64 2e  k, SorterThread.
0700: 62 44 6f 6e 65 0a 2a 2a 20 69 73 20 73 65 74 20  bDone.** is set 
0710: 74 6f 20 30 20 61 6e 64 20 74 68 65 20 53 6f 72  to 0 and the Sor
0720: 74 65 72 54 68 72 65 61 64 2e 70 54 68 72 65 61  terThread.pThrea
0730: 64 20 76 61 72 69 61 62 6c 65 20 73 65 74 20 74  d variable set t
0740: 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 0a 2a  o point to the.*
0750: 2a 20 74 68 72 65 61 64 20 68 61 6e 64 6c 65 2e  * thread handle.
0760: 20 53 6f 72 74 65 72 54 68 72 65 61 64 2e 62 44   SorterThread.bD
0770: 6f 6e 65 20 69 73 20 73 65 74 20 74 6f 20 31 20  one is set to 1 
0780: 28 74 6f 20 69 6e 64 69 63 61 74 65 20 74 6f 20  (to indicate to 
0790: 74 68 65 20 6d 61 69 6e 0a 2a 2a 20 74 68 72 65  the main.** thre
07a0: 61 64 20 74 68 61 74 20 6a 6f 69 6e 69 6e 67 20  ad that joining 
07b0: 53 6f 72 74 65 72 54 68 72 65 61 64 2e 70 54 68  SorterThread.pTh
07c0: 72 65 61 64 20 77 69 6c 6c 20 6e 6f 74 20 62 6c  read will not bl
07d0: 6f 63 6b 29 20 62 65 66 6f 72 65 20 74 68 65 20  ock) before the 
07e0: 74 68 72 65 61 64 0a 2a 2a 20 65 78 69 74 73 2e  thread.** exits.
07f0: 20 53 6f 72 74 65 72 54 68 72 65 61 64 2e 70 54   SorterThread.pT
0800: 68 72 65 61 64 20 61 6e 64 20 62 44 6f 6e 65 20  hread and bDone 
0810: 61 72 65 20 61 6c 77 61 79 73 20 63 6c 65 61 72  are always clear
0820: 65 64 20 61 66 74 65 72 20 74 68 65 20 0a 2a 2a  ed after the .**
0830: 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65   background thre
0840: 61 64 20 68 61 73 20 62 65 65 6e 20 6a 6f 69 6e  ad has been join
0850: 65 64 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 65 20 6f 62  ed..**.** One ob
0860: 6a 65 63 74 20 28 73 70 65 63 69 66 69 63 61 6c  ject (specifical
0870: 6c 79 2c 20 56 64 62 65 53 6f 72 74 65 72 2e 61  ly, VdbeSorter.a
0880: 54 68 72 65 61 64 5b 53 51 4c 49 54 45 5f 4d 41  Thread[SQLITE_MA
0890: 58 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44 2d  X_SORTER_THREAD-
08a0: 31 5d 29 0a 2a 2a 20 69 73 20 72 65 73 65 72 76  1]).** is reserv
08b0: 65 64 20 66 6f 72 20 74 68 65 20 66 6f 72 65 67  ed for the foreg
08c0: 72 6f 75 6e 64 20 74 68 72 65 61 64 2e 0a 2a 2a  round thread..**
08d0: 0a 2a 2a 20 54 68 65 20 6e 61 74 75 72 65 20 6f  .** The nature o
08e0: 66 20 74 68 65 20 77 6f 72 6b 20 70 65 72 66 6f  f the work perfo
08f0: 72 6d 65 64 20 69 73 20 64 65 74 65 72 6d 69 6e  rmed is determin
0900: 65 64 20 62 79 20 53 6f 72 74 65 72 54 68 72 65  ed by SorterThre
0910: 61 64 2e 65 57 6f 72 6b 2c 0a 2a 2a 20 61 73 20  ad.eWork,.** as 
0920: 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20  follows:.**.**  
0930: 20 53 4f 52 54 45 52 5f 54 48 52 45 41 44 5f 53   SORTER_THREAD_S
0940: 4f 52 54 3a 0a 2a 2a 20 20 20 20 20 53 6f 72 74  ORT:.**     Sort
0950: 20 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74   the linked list
0960: 20 6f 66 20 72 65 63 6f 72 64 73 20 61 74 20 53   of records at S
0970: 6f 72 74 65 72 54 68 72 65 61 64 2e 70 4c 69 73  orterThread.pLis
0980: 74 2e 0a 2a 2a 0a 2a 2a 20 20 20 53 4f 52 54 45  t..**.**   SORTE
0990: 52 5f 54 48 52 45 41 44 5f 54 4f 5f 50 4d 41 3a  R_THREAD_TO_PMA:
09a0: 0a 2a 2a 20 20 20 20 20 53 6f 72 74 20 74 68 65  .**     Sort the
09b0: 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20   linked list of 
09c0: 72 65 63 6f 72 64 73 20 61 74 20 53 6f 72 74 65  records at Sorte
09d0: 72 54 68 72 65 61 64 2e 70 4c 69 73 74 2c 20 61  rThread.pList, a
09e0: 6e 64 20 77 72 69 74 65 0a 2a 2a 20 20 20 20 20  nd write.**     
09f0: 74 68 65 20 72 65 73 75 6c 74 73 20 74 6f 20 61  the results to a
0a00: 20 6e 65 77 20 50 4d 41 20 69 6e 20 74 65 6d 70   new PMA in temp
0a10: 20 66 69 6c 65 20 53 6f 72 74 65 72 54 68 72 65   file SorterThre
0a20: 61 64 2e 70 54 65 6d 70 31 2e 20 4f 70 65 6e 0a  ad.pTemp1. Open.
0a30: 2a 2a 20 20 20 20 20 74 68 65 20 74 65 6d 70 20  **     the temp 
0a40: 66 69 6c 65 20 69 66 20 69 74 20 69 73 20 6e 6f  file if it is no
0a50: 74 20 61 6c 72 65 61 64 79 20 6f 70 65 6e 2e 0a  t already open..
0a60: 2a 2a 0a 2a 2a 20 20 20 53 4f 52 54 45 52 5f 54  **.**   SORTER_T
0a70: 48 52 45 41 44 5f 43 4f 4e 53 3a 0a 2a 2a 20 20  HREAD_CONS:.**  
0a80: 20 20 20 4d 65 72 67 65 20 65 78 69 73 74 69 6e     Merge existin
0a90: 67 20 50 4d 41 73 20 75 6e 74 69 6c 20 53 6f 72  g PMAs until Sor
0aa0: 74 65 72 54 68 72 65 61 64 2e 6e 43 6f 6e 73 6f  terThread.nConso
0ab0: 6c 69 64 61 74 65 20 6f 72 20 66 65 77 65 72 0a  lidate or fewer.
0ac0: 2a 2a 20 20 20 20 20 72 65 6d 61 69 6e 20 69 6e  **     remain in
0ad0: 20 74 65 6d 70 20 66 69 6c 65 20 53 6f 72 74 65   temp file Sorte
0ae0: 72 54 68 72 65 61 64 2e 70 54 65 6d 70 31 2e 0a  rThread.pTemp1..
0af0: 2a 2f 0a 73 74 72 75 63 74 20 53 6f 72 74 65 72  */.struct Sorter
0b00: 54 68 72 65 61 64 20 7b 0a 20 20 53 51 4c 69 74  Thread {.  SQLit
0b10: 65 54 68 72 65 61 64 20 2a 70 54 68 72 65 61 64  eThread *pThread
0b20: 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68  ;          /* Th
0b30: 72 65 61 64 20 68 61 6e 64 6c 65 2c 20 6f 72 20  read handle, or 
0b40: 4e 55 4c 4c 20 2a 2f 0a 20 20 69 6e 74 20 62 44  NULL */.  int bD
0b50: 6f 6e 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  one;            
0b60: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74            /* Set
0b70: 20 74 6f 20 74 72 75 65 20 62 79 20 70 54 68 72   to true by pThr
0b80: 65 61 64 20 77 68 65 6e 20 66 69 6e 69 73 68 65  ead when finishe
0b90: 64 20 2a 2f 0a 0a 20 20 73 71 6c 69 74 65 33 5f  d */..  sqlite3_
0ba0: 76 66 73 20 2a 70 56 66 73 3b 20 20 20 20 20 20  vfs *pVfs;      
0bb0: 20 20 20 20 20 20 20 20 2f 2a 20 56 46 53 20 75          /* VFS u
0bc0: 73 65 64 20 74 6f 20 6f 70 65 6e 20 74 65 6d 70  sed to open temp
0bd0: 6f 72 61 72 79 20 66 69 6c 65 73 20 2a 2f 0a 20  orary files */. 
0be0: 20 4b 65 79 49 6e 66 6f 20 2a 70 4b 65 79 49 6e   KeyInfo *pKeyIn
0bf0: 66 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  fo;             
0c00: 20 2f 2a 20 48 6f 77 20 74 6f 20 63 6f 6d 70 61   /* How to compa
0c10: 72 65 20 72 65 63 6f 72 64 73 20 2a 2f 0a 20 20  re records */.  
0c20: 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20 2a  UnpackedRecord *
0c30: 70 55 6e 70 61 63 6b 65 64 3b 20 20 20 20 20 20  pUnpacked;      
0c40: 2f 2a 20 53 70 61 63 65 20 74 6f 20 75 6e 70 61  /* Space to unpa
0c50: 63 6b 20 61 20 72 65 63 6f 72 64 20 2a 2f 0a 20  ck a record */. 
0c60: 20 69 6e 74 20 70 67 73 7a 3b 20 20 20 20 20 20   int pgsz;      
0c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c80: 20 2f 2a 20 4d 61 69 6e 20 64 61 74 61 62 61 73   /* Main databas
0c90: 65 20 70 61 67 65 20 73 69 7a 65 20 2a 2f 0a 0a  e page size */..
0ca0: 20 20 75 38 20 65 57 6f 72 6b 3b 20 20 20 20 20    u8 eWork;     
0cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0cc0: 20 20 2f 2a 20 4f 6e 65 20 6f 66 20 74 68 65 20    /* One of the 
0cd0: 53 4f 52 54 45 52 5f 54 48 52 45 41 44 5f 2a 20  SORTER_THREAD_* 
0ce0: 63 6f 6e 73 74 61 6e 74 73 20 2a 2f 0a 20 20 69  constants */.  i
0cf0: 6e 74 20 6e 43 6f 6e 73 6f 6c 69 64 61 74 65 3b  nt nConsolidate;
0d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0d10: 2a 20 46 6f 72 20 54 48 52 45 41 44 5f 43 4f 4e  * For THREAD_CON
0d20: 53 2c 20 6d 61 78 20 66 69 6e 61 6c 20 50 4d 41  S, max final PMA
0d30: 73 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63  s */.  SorterRec
0d40: 6f 72 64 20 2a 70 4c 69 73 74 3b 20 20 20 20 20  ord *pList;     
0d50: 20 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f         /* List o
0d60: 66 20 72 65 63 6f 72 64 73 20 66 6f 72 20 70 54  f records for pT
0d70: 68 72 65 61 64 20 74 6f 20 73 6f 72 74 20 2a 2f  hread to sort */
0d80: 0a 20 20 69 6e 74 20 6e 49 6e 4d 65 6d 6f 72 79  .  int nInMemory
0d90: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0da0: 20 20 20 2f 2a 20 45 78 70 65 63 74 65 64 20 73     /* Expected s
0db0: 69 7a 65 20 6f 66 20 50 4d 41 20 62 61 73 65 64  ize of PMA based
0dc0: 20 6f 6e 20 70 4c 69 73 74 20 2a 2f 0a 0a 20 20   on pList */..  
0dd0: 69 6e 74 20 6e 50 4d 41 3b 20 20 20 20 20 20 20  int nPMA;       
0de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0df0: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 50 4d 41  /* Number of PMA
0e00: 73 20 63 75 72 72 65 6e 74 6c 79 20 69 6e 20 70  s currently in p
0e10: 54 65 6d 70 31 20 2a 2f 0a 20 20 69 36 34 20 69  Temp1 */.  i64 i
0e20: 54 65 6d 70 31 4f 66 66 3b 20 20 20 20 20 20 20  Temp1Off;       
0e30: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66             /* Of
0e40: 66 73 65 74 20 74 6f 20 77 72 69 74 65 20 74 6f  fset to write to
0e50: 20 69 6e 20 70 54 65 6d 70 31 20 2a 2f 0a 20 20   in pTemp1 */.  
0e60: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 54  sqlite3_file *pT
0e70: 65 6d 70 31 3b 20 20 20 20 20 20 20 20 20 20 20  emp1;           
0e80: 2f 2a 20 46 69 6c 65 20 74 6f 20 77 72 69 74 65  /* File to write
0e90: 20 50 4d 41 73 20 74 6f 2c 20 6f 72 20 4e 55 4c   PMAs to, or NUL
0ea0: 4c 20 2a 2f 0a 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20  L */.};.../*.** 
0eb0: 4e 4f 54 45 53 20 4f 4e 20 44 41 54 41 20 53 54  NOTES ON DATA ST
0ec0: 52 55 43 54 55 52 45 20 55 53 45 44 20 46 4f 52  RUCTURE USED FOR
0ed0: 20 4e 2d 57 41 59 20 4d 45 52 47 45 53 3a 0a 2a   N-WAY MERGES:.*
0ee0: 2a 0a 2a 2a 20 41 73 20 6b 65 79 73 20 61 72 65  *.** As keys are
0ef0: 20 61 64 64 65 64 20 74 6f 20 74 68 65 20 73 6f   added to the so
0f00: 72 74 65 72 2c 20 74 68 65 79 20 61 72 65 20 77  rter, they are w
0f10: 72 69 74 74 65 6e 20 74 6f 20 64 69 73 6b 20 69  ritten to disk i
0f20: 6e 20 61 20 73 65 72 69 65 73 0a 2a 2a 20 6f 66  n a series.** of
0f30: 20 73 6f 72 74 65 64 20 70 61 63 6b 65 64 2d 6d   sorted packed-m
0f40: 65 6d 6f 72 79 2d 61 72 72 61 79 73 20 28 50 4d  emory-arrays (PM
0f50: 41 73 29 2e 20 54 68 65 20 73 69 7a 65 20 6f 66  As). The size of
0f60: 20 65 61 63 68 20 50 4d 41 20 69 73 20 72 6f 75   each PMA is rou
0f70: 67 68 6c 79 0a 2a 2a 20 74 68 65 20 73 61 6d 65  ghly.** the same
0f80: 20 61 73 20 74 68 65 20 63 61 63 68 65 2d 73 69   as the cache-si
0f90: 7a 65 20 61 6c 6c 6f 77 65 64 20 66 6f 72 20 74  ze allowed for t
0fa0: 65 6d 70 6f 72 61 72 79 20 64 61 74 61 62 61 73  emporary databas
0fb0: 65 73 2e 20 49 6e 20 6f 72 64 65 72 0a 2a 2a 20  es. In order.** 
0fc0: 74 6f 20 61 6c 6c 6f 77 20 74 68 65 20 63 61 6c  to allow the cal
0fd0: 6c 65 72 20 74 6f 20 65 78 74 72 61 63 74 20 6b  ler to extract k
0fe0: 65 79 73 20 66 72 6f 6d 20 74 68 65 20 73 6f 72  eys from the sor
0ff0: 74 65 72 20 69 6e 20 73 6f 72 74 65 64 20 6f 72  ter in sorted or
1000: 64 65 72 2c 0a 2a 2a 20 61 6c 6c 20 50 4d 41 73  der,.** all PMAs
1010: 20 63 75 72 72 65 6e 74 6c 79 20 73 74 6f 72 65   currently store
1020: 64 20 6f 6e 20 64 69 73 6b 20 6d 75 73 74 20 62  d on disk must b
1030: 65 20 6d 65 72 67 65 64 20 74 6f 67 65 74 68 65  e merged togethe
1040: 72 2e 20 54 68 69 73 20 63 6f 6d 6d 65 6e 74 0a  r. This comment.
1050: 2a 2a 20 64 65 73 63 72 69 62 65 73 20 74 68 65  ** describes the
1060: 20 64 61 74 61 20 73 74 72 75 63 74 75 72 65 20   data structure 
1070: 75 73 65 64 20 74 6f 20 64 6f 20 73 6f 2e 20 54  used to do so. T
1080: 68 65 20 73 74 72 75 63 74 75 72 65 20 73 75 70  he structure sup
1090: 70 6f 72 74 73 20 0a 2a 2a 20 6d 65 72 67 69 6e  ports .** mergin
10a0: 67 20 61 6e 79 20 6e 75 6d 62 65 72 20 6f 66 20  g any number of 
10b0: 61 72 72 61 79 73 20 69 6e 20 61 20 73 69 6e 67  arrays in a sing
10c0: 6c 65 20 70 61 73 73 20 77 69 74 68 20 6e 6f 20  le pass with no 
10d0: 72 65 64 75 6e 64 61 6e 74 20 63 6f 6d 70 61 72  redundant compar
10e0: 69 73 6f 6e 20 0a 2a 2a 20 6f 70 65 72 61 74 69  ison .** operati
10f0: 6f 6e 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61  ons..**.** The a
1100: 49 74 65 72 5b 5d 20 61 72 72 61 79 20 63 6f 6e  Iter[] array con
1110: 74 61 69 6e 73 20 61 6e 20 69 74 65 72 61 74 6f  tains an iterato
1120: 72 20 66 6f 72 20 65 61 63 68 20 6f 66 20 74 68  r for each of th
1130: 65 20 50 4d 41 73 20 62 65 69 6e 67 20 6d 65 72  e PMAs being mer
1140: 67 65 64 2e 0a 2a 2a 20 41 6e 20 61 49 74 65 72  ged..** An aIter
1150: 5b 5d 20 69 74 65 72 61 74 6f 72 20 65 69 74 68  [] iterator eith
1160: 65 72 20 70 6f 69 6e 74 73 20 74 6f 20 61 20 76  er points to a v
1170: 61 6c 69 64 20 6b 65 79 20 6f 72 20 65 6c 73 65  alid key or else
1180: 20 69 73 20 61 74 20 45 4f 46 2e 20 46 6f 72 20   is at EOF. For 
1190: 0a 2a 2a 20 74 68 65 20 70 75 72 70 6f 73 65 73  .** the purposes
11a0: 20 6f 66 20 74 68 65 20 70 61 72 61 67 72 61 70   of the paragrap
11b0: 68 73 20 62 65 6c 6f 77 2c 20 77 65 20 61 73 73  hs below, we ass
11c0: 75 6d 65 20 74 68 61 74 20 74 68 65 20 61 72 72  ume that the arr
11d0: 61 79 20 69 73 20 61 63 74 75 61 6c 6c 79 20 0a  ay is actually .
11e0: 2a 2a 20 4e 20 65 6c 65 6d 65 6e 74 73 20 69 6e  ** N elements in
11f0: 20 73 69 7a 65 2c 20 77 68 65 72 65 20 4e 20 69   size, where N i
1200: 73 20 74 68 65 20 73 6d 61 6c 6c 65 73 74 20 70  s the smallest p
1210: 6f 77 65 72 20 6f 66 20 32 20 67 72 65 61 74 65  ower of 2 greate
1220: 72 20 74 6f 20 6f 72 20 65 71 75 61 6c 20 0a 2a  r to or equal .*
1230: 2a 20 74 6f 20 74 68 65 20 6e 75 6d 62 65 72 20  * to the number 
1240: 6f 66 20 69 74 65 72 61 74 6f 72 73 20 62 65 69  of iterators bei
1250: 6e 67 20 6d 65 72 67 65 64 2e 20 54 68 65 20 65  ng merged. The e
1260: 78 74 72 61 20 61 49 74 65 72 5b 5d 20 65 6c 65  xtra aIter[] ele
1270: 6d 65 6e 74 73 20 61 72 65 20 0a 2a 2a 20 74 72  ments are .** tr
1280: 65 61 74 65 64 20 61 73 20 69 66 20 74 68 65 79  eated as if they
1290: 20 61 72 65 20 65 6d 70 74 79 20 28 61 6c 77 61   are empty (alwa
12a0: 79 73 20 61 74 20 45 4f 46 29 2e 0a 2a 2a 0a 2a  ys at EOF)..**.*
12b0: 2a 20 54 68 65 20 61 54 72 65 65 5b 5d 20 61 72  * The aTree[] ar
12c0: 72 61 79 20 69 73 20 61 6c 73 6f 20 4e 20 65 6c  ray is also N el
12d0: 65 6d 65 6e 74 73 20 69 6e 20 73 69 7a 65 2e 20  ements in size. 
12e0: 54 68 65 20 76 61 6c 75 65 20 6f 66 20 4e 20 69  The value of N i
12f0: 73 20 73 74 6f 72 65 64 20 69 6e 0a 2a 2a 20 74  s stored in.** t
1300: 68 65 20 56 64 62 65 53 6f 72 74 65 72 2e 6e 54  he VdbeSorter.nT
1310: 72 65 65 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2a  ree variable..**
1320: 0a 2a 2a 20 54 68 65 20 66 69 6e 61 6c 20 28 4e  .** The final (N
1330: 2f 32 29 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20  /2) elements of 
1340: 61 54 72 65 65 5b 5d 20 63 6f 6e 74 61 69 6e 20  aTree[] contain 
1350: 74 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20 63  the results of c
1360: 6f 6d 70 61 72 69 6e 67 0a 2a 2a 20 70 61 69 72  omparing.** pair
1370: 73 20 6f 66 20 69 74 65 72 61 74 6f 72 20 6b 65  s of iterator ke
1380: 79 73 20 74 6f 67 65 74 68 65 72 2e 20 45 6c 65  ys together. Ele
1390: 6d 65 6e 74 20 69 20 63 6f 6e 74 61 69 6e 73 20  ment i contains 
13a0: 74 68 65 20 72 65 73 75 6c 74 20 6f 66 20 0a 2a  the result of .*
13b0: 2a 20 63 6f 6d 70 61 72 69 6e 67 20 61 49 74 65  * comparing aIte
13c0: 72 5b 32 2a 69 2d 4e 5d 20 61 6e 64 20 61 49 74  r[2*i-N] and aIt
13d0: 65 72 5b 32 2a 69 2d 4e 2b 31 5d 2e 20 57 68 69  er[2*i-N+1]. Whi
13e0: 63 68 65 76 65 72 20 6b 65 79 20 69 73 20 73 6d  chever key is sm
13f0: 61 6c 6c 65 72 2c 20 74 68 65 0a 2a 2a 20 61 54  aller, the.** aT
1400: 72 65 65 20 65 6c 65 6d 65 6e 74 20 69 73 20 73  ree element is s
1410: 65 74 20 74 6f 20 74 68 65 20 69 6e 64 65 78 20  et to the index 
1420: 6f 66 20 69 74 2e 20 0a 2a 2a 0a 2a 2a 20 46 6f  of it. .**.** Fo
1430: 72 20 74 68 65 20 70 75 72 70 6f 73 65 73 20 6f  r the purposes o
1440: 66 20 74 68 69 73 20 63 6f 6d 70 61 72 69 73 6f  f this compariso
1450: 6e 2c 20 45 4f 46 20 69 73 20 63 6f 6e 73 69 64  n, EOF is consid
1460: 65 72 65 64 20 67 72 65 61 74 65 72 20 74 68 61  ered greater tha
1470: 6e 20 61 6e 79 0a 2a 2a 20 6f 74 68 65 72 20 6b  n any.** other k
1480: 65 79 20 76 61 6c 75 65 2e 20 49 66 20 74 68 65  ey value. If the
1490: 20 6b 65 79 73 20 61 72 65 20 65 71 75 61 6c 20   keys are equal 
14a0: 28 6f 6e 6c 79 20 70 6f 73 73 69 62 6c 65 20 77  (only possible w
14b0: 69 74 68 20 74 77 6f 20 45 4f 46 0a 2a 2a 20 76  ith two EOF.** v
14c0: 61 6c 75 65 73 29 2c 20 69 74 20 64 6f 65 73 6e  alues), it doesn
14d0: 27 74 20 6d 61 74 74 65 72 20 77 68 69 63 68 20  't matter which 
14e0: 69 6e 64 65 78 20 69 73 20 73 74 6f 72 65 64 2e  index is stored.
14f0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 28 4e 2f 34 29  .**.** The (N/4)
1500: 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20 61 54 72   elements of aTr
1510: 65 65 5b 5d 20 74 68 61 74 20 70 72 65 63 65 64  ee[] that preced
1520: 65 20 74 68 65 20 66 69 6e 61 6c 20 28 4e 2f 32  e the final (N/2
1530: 29 20 64 65 73 63 72 69 62 65 64 20 0a 2a 2a 20  ) described .** 
1540: 61 62 6f 76 65 20 63 6f 6e 74 61 69 6e 73 20 74  above contains t
1550: 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20  he index of the 
1560: 73 6d 61 6c 6c 65 73 74 20 6f 66 20 65 61 63 68  smallest of each
1570: 20 62 6c 6f 63 6b 20 6f 66 20 34 20 69 74 65 72   block of 4 iter
1580: 61 74 6f 72 73 2e 0a 2a 2a 20 41 6e 64 20 73 6f  ators..** And so
1590: 20 6f 6e 2e 20 53 6f 20 74 68 61 74 20 61 54 72   on. So that aTr
15a0: 65 65 5b 31 5d 20 63 6f 6e 74 61 69 6e 73 20 74  ee[1] contains t
15b0: 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20  he index of the 
15c0: 69 74 65 72 61 74 6f 72 20 74 68 61 74 20 0a 2a  iterator that .*
15d0: 2a 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e  * currently poin
15e0: 74 73 20 74 6f 20 74 68 65 20 73 6d 61 6c 6c 65  ts to the smalle
15f0: 73 74 20 6b 65 79 20 76 61 6c 75 65 2e 20 61 54  st key value. aT
1600: 72 65 65 5b 30 5d 20 69 73 20 75 6e 75 73 65 64  ree[0] is unused
1610: 2e 0a 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65 3a  ..**.** Example:
1620: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 49 74 65 72  .**.**     aIter
1630: 5b 30 5d 20 2d 3e 20 42 61 6e 61 6e 61 0a 2a 2a  [0] -> Banana.**
1640: 20 20 20 20 20 61 49 74 65 72 5b 31 5d 20 2d 3e       aIter[1] ->
1650: 20 46 65 69 6a 6f 61 0a 2a 2a 20 20 20 20 20 61   Feijoa.**     a
1660: 49 74 65 72 5b 32 5d 20 2d 3e 20 45 6c 64 65 72  Iter[2] -> Elder
1670: 62 65 72 72 79 0a 2a 2a 20 20 20 20 20 61 49 74  berry.**     aIt
1680: 65 72 5b 33 5d 20 2d 3e 20 43 75 72 72 61 6e 74  er[3] -> Currant
1690: 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 34 5d  .**     aIter[4]
16a0: 20 2d 3e 20 47 72 61 70 65 66 72 75 69 74 0a 2a   -> Grapefruit.*
16b0: 2a 20 20 20 20 20 61 49 74 65 72 5b 35 5d 20 2d  *     aIter[5] -
16c0: 3e 20 41 70 70 6c 65 0a 2a 2a 20 20 20 20 20 61  > Apple.**     a
16d0: 49 74 65 72 5b 36 5d 20 2d 3e 20 44 75 72 69 61  Iter[6] -> Duria
16e0: 6e 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 37  n.**     aIter[7
16f0: 5d 20 2d 3e 20 45 4f 46 0a 2a 2a 0a 2a 2a 20 20  ] -> EOF.**.**  
1700: 20 20 20 61 54 72 65 65 5b 5d 20 3d 20 7b 20 58     aTree[] = { X
1710: 2c 20 35 20 20 20 30 2c 20 35 20 20 20 20 30 2c  , 5   0, 5    0,
1720: 20 33 2c 20 35 2c 20 36 20 7d 0a 2a 2a 0a 2a 2a   3, 5, 6 }.**.**
1730: 20 54 68 65 20 63 75 72 72 65 6e 74 20 65 6c 65   The current ele
1740: 6d 65 6e 74 20 69 73 20 22 41 70 70 6c 65 22 20  ment is "Apple" 
1750: 28 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68  (the value of th
1760: 65 20 6b 65 79 20 69 6e 64 69 63 61 74 65 64 20  e key indicated 
1770: 62 79 20 0a 2a 2a 20 69 74 65 72 61 74 6f 72 20  by .** iterator 
1780: 35 29 2e 20 57 68 65 6e 20 74 68 65 20 4e 65 78  5). When the Nex
1790: 74 28 29 20 6f 70 65 72 61 74 69 6f 6e 20 69 73  t() operation is
17a0: 20 69 6e 76 6f 6b 65 64 2c 20 69 74 65 72 61 74   invoked, iterat
17b0: 6f 72 20 35 20 77 69 6c 6c 0a 2a 2a 20 62 65 20  or 5 will.** be 
17c0: 61 64 76 61 6e 63 65 64 20 74 6f 20 74 68 65 20  advanced to the 
17d0: 6e 65 78 74 20 6b 65 79 20 69 6e 20 69 74 73 20  next key in its 
17e0: 73 65 67 6d 65 6e 74 2e 20 53 61 79 20 74 68 65  segment. Say the
17f0: 20 6e 65 78 74 20 6b 65 79 20 69 73 0a 2a 2a 20   next key is.** 
1800: 22 45 67 67 70 6c 61 6e 74 22 3a 0a 2a 2a 0a 2a  "Eggplant":.**.*
1810: 2a 20 20 20 20 20 61 49 74 65 72 5b 35 5d 20 2d  *     aIter[5] -
1820: 3e 20 45 67 67 70 6c 61 6e 74 0a 2a 2a 0a 2a 2a  > Eggplant.**.**
1830: 20 54 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   The contents of
1840: 20 61 54 72 65 65 5b 5d 20 61 72 65 20 75 70 64   aTree[] are upd
1850: 61 74 65 64 20 66 69 72 73 74 20 62 79 20 63 6f  ated first by co
1860: 6d 70 61 72 69 6e 67 20 74 68 65 20 6e 65 77 20  mparing the new 
1870: 69 74 65 72 61 74 6f 72 0a 2a 2a 20 35 20 6b 65  iterator.** 5 ke
1880: 79 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e 74  y to the current
1890: 20 6b 65 79 20 6f 66 20 69 74 65 72 61 74 6f 72   key of iterator
18a0: 20 34 20 28 73 74 69 6c 6c 20 22 47 72 61 70 65   4 (still "Grape
18b0: 66 72 75 69 74 22 29 2e 20 54 68 65 20 69 74 65  fruit"). The ite
18c0: 72 61 74 6f 72 0a 2a 2a 20 35 20 76 61 6c 75 65  rator.** 5 value
18d0: 20 69 73 20 73 74 69 6c 6c 20 73 6d 61 6c 6c 65   is still smalle
18e0: 72 2c 20 73 6f 20 61 54 72 65 65 5b 36 5d 20 69  r, so aTree[6] i
18f0: 73 20 73 65 74 20 74 6f 20 35 2e 20 41 6e 64 20  s set to 5. And 
1900: 73 6f 20 6f 6e 20 75 70 20 74 68 65 20 74 72 65  so on up the tre
1910: 65 2e 0a 2a 2a 20 54 68 65 20 76 61 6c 75 65 20  e..** The value 
1920: 6f 66 20 69 74 65 72 61 74 6f 72 20 36 20 2d 20  of iterator 6 - 
1930: 22 44 75 72 69 61 6e 22 20 2d 20 69 73 20 6e 6f  "Durian" - is no
1940: 77 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 74  w smaller than t
1950: 68 61 74 20 6f 66 20 69 74 65 72 61 74 6f 72 0a  hat of iterator.
1960: 2a 2a 20 35 2c 20 73 6f 20 61 54 72 65 65 5b 33  ** 5, so aTree[3
1970: 5d 20 69 73 20 73 65 74 20 74 6f 20 36 2e 20 4b  ] is set to 6. K
1980: 65 79 20 30 20 69 73 20 73 6d 61 6c 6c 65 72 20  ey 0 is smaller 
1990: 74 68 61 6e 20 6b 65 79 20 36 20 28 42 61 6e 61  than key 6 (Bana
19a0: 6e 61 3c 44 75 72 69 61 6e 29 2c 0a 2a 2a 20 73  na<Durian),.** s
19b0: 6f 20 74 68 65 20 76 61 6c 75 65 20 77 72 69 74  o the value writ
19c0: 74 65 6e 20 69 6e 74 6f 20 65 6c 65 6d 65 6e 74  ten into element
19d0: 20 31 20 6f 66 20 74 68 65 20 61 72 72 61 79 20   1 of the array 
19e0: 69 73 20 30 2e 20 41 73 20 66 6f 6c 6c 6f 77 73  is 0. As follows
19f0: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 54 72 65  :.**.**     aTre
1a00: 65 5b 5d 20 3d 20 7b 20 58 2c 20 30 20 20 20 30  e[] = { X, 0   0
1a10: 2c 20 36 20 20 20 20 30 2c 20 33 2c 20 35 2c 20  , 6    0, 3, 5, 
1a20: 36 20 7d 0a 2a 2a 0a 2a 2a 20 49 6e 20 6f 74 68  6 }.**.** In oth
1a30: 65 72 20 77 6f 72 64 73 2c 20 65 61 63 68 20 74  er words, each t
1a40: 69 6d 65 20 77 65 20 61 64 76 61 6e 63 65 20 74  ime we advance t
1a50: 6f 20 74 68 65 20 6e 65 78 74 20 73 6f 72 74 65  o the next sorte
1a60: 72 20 65 6c 65 6d 65 6e 74 2c 20 6c 6f 67 32 28  r element, log2(
1a70: 4e 29 0a 2a 2a 20 6b 65 79 20 63 6f 6d 70 61 72  N).** key compar
1a80: 69 73 6f 6e 20 6f 70 65 72 61 74 69 6f 6e 73 20  ison operations 
1a90: 61 72 65 20 72 65 71 75 69 72 65 64 2c 20 77 68  are required, wh
1aa0: 65 72 65 20 4e 20 69 73 20 74 68 65 20 6e 75 6d  ere N is the num
1ab0: 62 65 72 20 6f 66 20 73 65 67 6d 65 6e 74 73 0a  ber of segments.
1ac0: 2a 2a 20 62 65 69 6e 67 20 6d 65 72 67 65 64 20  ** being merged 
1ad0: 28 72 6f 75 6e 64 65 64 20 75 70 20 74 6f 20 74  (rounded up to t
1ae0: 68 65 20 6e 65 78 74 20 70 6f 77 65 72 20 6f 66  he next power of
1af0: 20 32 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 53   2)..*/.struct S
1b00: 6f 72 74 65 72 4d 65 72 67 65 72 20 7b 0a 20 20  orterMerger {.  
1b10: 69 6e 74 20 6e 54 72 65 65 3b 20 20 20 20 20 20  int nTree;      
1b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b30: 2f 2a 20 55 73 65 64 20 73 69 7a 65 20 6f 66 20  /* Used size of 
1b40: 61 54 72 65 65 2f 61 49 74 65 72 20 28 70 6f 77  aTree/aIter (pow
1b50: 65 72 20 6f 66 20 32 29 20 2a 2f 0a 20 20 69 6e  er of 2) */.  in
1b60: 74 20 2a 61 54 72 65 65 3b 20 20 20 20 20 20 20  t *aTree;       
1b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1b80: 20 43 75 72 72 65 6e 74 20 73 74 61 74 65 20 6f   Current state o
1b90: 66 20 69 6e 63 72 65 6d 65 6e 74 61 6c 20 6d 65  f incremental me
1ba0: 72 67 65 20 2a 2f 0a 20 20 56 64 62 65 53 6f 72  rge */.  VdbeSor
1bb0: 74 65 72 49 74 65 72 20 2a 61 49 74 65 72 3b 20  terIter *aIter; 
1bc0: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61           /* Arra
1bd0: 79 20 6f 66 20 69 74 65 72 61 74 6f 72 73 20 74  y of iterators t
1be0: 6f 20 6d 65 72 67 65 20 64 61 74 61 20 66 72 6f  o merge data fro
1bf0: 6d 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 4d  m */.};../*.** M
1c00: 61 69 6e 20 73 6f 72 74 65 72 20 73 74 72 75 63  ain sorter struc
1c10: 74 75 72 65 2e 20 41 20 73 69 6e 67 6c 65 20 69  ture. A single i
1c20: 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20  nstance of this 
1c30: 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72  is allocated for
1c40: 20 65 61 63 68 20 0a 2a 2a 20 73 6f 72 74 65 72   each .** sorter
1c50: 20 63 75 72 73 6f 72 20 63 72 65 61 74 65 64 20   cursor created 
1c60: 62 79 20 74 68 65 20 56 44 42 45 2e 0a 2a 2f 0a  by the VDBE..*/.
1c70: 73 74 72 75 63 74 20 56 64 62 65 53 6f 72 74 65  struct VdbeSorte
1c80: 72 20 7b 0a 20 20 69 6e 74 20 6e 49 6e 4d 65 6d  r {.  int nInMem
1c90: 6f 72 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  ory;            
1ca0: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
1cb0: 20 73 69 7a 65 20 6f 66 20 70 52 65 63 6f 72 64   size of pRecord
1cc0: 20 6c 69 73 74 20 61 73 20 50 4d 41 20 2a 2f 0a   list as PMA */.
1cd0: 20 20 69 6e 74 20 6d 6e 50 6d 61 53 69 7a 65 3b    int mnPmaSize;
1ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cf0: 20 20 2f 2a 20 4d 69 6e 69 6d 75 6d 20 50 4d 41    /* Minimum PMA
1d00: 20 73 69 7a 65 2c 20 69 6e 20 62 79 74 65 73 20   size, in bytes 
1d10: 2a 2f 0a 20 20 69 6e 74 20 6d 78 50 6d 61 53 69  */.  int mxPmaSi
1d20: 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ze;             
1d30: 20 20 20 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20       /* Maximum 
1d40: 50 4d 41 20 73 69 7a 65 2c 20 69 6e 20 62 79 74  PMA size, in byt
1d50: 65 73 2e 20 20 30 3d 3d 6e 6f 20 6c 69 6d 69 74  es.  0==no limit
1d60: 20 2a 2f 0a 20 20 69 6e 74 20 62 55 73 65 50 4d   */.  int bUsePM
1d70: 41 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  A;              
1d80: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
1d90: 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 50 4d 41   one or more PMA
1da0: 73 20 63 72 65 61 74 65 64 20 2a 2f 0a 20 20 53  s created */.  S
1db0: 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 52 65  orterRecord *pRe
1dc0: 63 6f 72 64 3b 20 20 20 20 20 20 20 20 20 20 2f  cord;          /
1dd0: 2a 20 48 65 61 64 20 6f 66 20 69 6e 2d 6d 65 6d  * Head of in-mem
1de0: 6f 72 79 20 72 65 63 6f 72 64 20 6c 69 73 74 20  ory record list 
1df0: 2a 2f 0a 20 20 53 6f 72 74 65 72 4d 65 72 67 65  */.  SorterMerge
1e00: 72 20 2a 70 4d 65 72 67 65 72 3b 20 20 20 20 20  r *pMerger;     
1e10: 20 20 20 20 20 2f 2a 20 46 6f 72 20 66 69 6e 61       /* For fina
1e20: 6c 20 6d 65 72 67 65 20 6f 66 20 50 4d 41 73 20  l merge of PMAs 
1e30: 28 62 79 20 63 61 6c 6c 65 72 29 20 2a 2f 20 0a  (by caller) */ .
1e40: 20 20 53 6f 72 74 65 72 54 68 72 65 61 64 20 61    SorterThread a
1e50: 54 68 72 65 61 64 5b 53 51 4c 49 54 45 5f 4d 41  Thread[SQLITE_MA
1e60: 58 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44 5d  X_SORTER_THREAD]
1e70: 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20  ;.};../*.** The 
1e80: 66 6f 6c 6c 6f 77 69 6e 67 20 74 79 70 65 20 69  following type i
1e90: 73 20 61 6e 20 69 74 65 72 61 74 6f 72 20 66 6f  s an iterator fo
1ea0: 72 20 61 20 50 4d 41 2e 20 49 74 20 63 61 63 68  r a PMA. It cach
1eb0: 65 73 20 74 68 65 20 63 75 72 72 65 6e 74 20 6b  es the current k
1ec0: 65 79 20 69 6e 20 0a 2a 2a 20 76 61 72 69 61 62  ey in .** variab
1ed0: 6c 65 73 20 6e 4b 65 79 2f 61 4b 65 79 2e 20 49  les nKey/aKey. I
1ee0: 66 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 69  f the iterator i
1ef0: 73 20 61 74 20 45 4f 46 2c 20 70 46 69 6c 65 3d  s at EOF, pFile=
1f00: 3d 30 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 56 64  =0..*/.struct Vd
1f10: 62 65 53 6f 72 74 65 72 49 74 65 72 20 7b 0a 20  beSorterIter {. 
1f20: 20 69 36 34 20 69 52 65 61 64 4f 66 66 3b 20 20   i64 iReadOff;  
1f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f40: 20 2f 2a 20 43 75 72 72 65 6e 74 20 72 65 61 64   /* Current read
1f50: 20 6f 66 66 73 65 74 20 2a 2f 0a 20 20 69 36 34   offset */.  i64
1f60: 20 69 45 6f 66 3b 20 20 20 20 20 20 20 20 20 20   iEof;          
1f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1f80: 31 20 62 79 74 65 20 70 61 73 74 20 45 4f 46 20  1 byte past EOF 
1f90: 66 6f 72 20 74 68 69 73 20 69 74 65 72 61 74 6f  for this iterato
1fa0: 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 6c 6c 6f  r */.  int nAllo
1fb0: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
1fc0: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
1fd0: 6f 66 20 73 70 61 63 65 20 61 74 20 61 41 6c 6c  of space at aAll
1fe0: 6f 63 20 2a 2f 0a 20 20 69 6e 74 20 6e 4b 65 79  oc */.  int nKey
1ff0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
2000: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
2010: 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 6b 65  r of bytes in ke
2020: 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66  y */.  sqlite3_f
2030: 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20 20 20  ile *pFile;     
2040: 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 69         /* File i
2050: 74 65 72 61 74 6f 72 20 69 73 20 72 65 61 64 69  terator is readi
2060: 6e 67 20 66 72 6f 6d 20 2a 2f 0a 20 20 75 38 20  ng from */.  u8 
2070: 2a 61 41 6c 6c 6f 63 3b 20 20 20 20 20 20 20 20  *aAlloc;        
2080: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2090: 41 6c 6c 6f 63 61 74 65 64 20 73 70 61 63 65 20  Allocated space 
20a0: 2a 2f 0a 20 20 75 38 20 2a 61 4b 65 79 3b 20 20  */.  u8 *aKey;  
20b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20c0: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
20d0: 74 6f 20 63 75 72 72 65 6e 74 20 6b 65 79 20 2a  to current key *
20e0: 2f 0a 20 20 75 38 20 2a 61 42 75 66 66 65 72 3b  /.  u8 *aBuffer;
20f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2100: 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 72      /* Current r
2110: 65 61 64 20 62 75 66 66 65 72 20 2a 2f 0a 20 20  ead buffer */.  
2120: 69 6e 74 20 6e 42 75 66 66 65 72 3b 20 20 20 20  int nBuffer;    
2130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2140: 2f 2a 20 53 69 7a 65 20 6f 66 20 72 65 61 64 20  /* Size of read 
2150: 62 75 66 66 65 72 20 69 6e 20 62 79 74 65 73 20  buffer in bytes 
2160: 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20  */.};../*.** An 
2170: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73  instance of this
2180: 20 73 74 72 75 63 74 75 72 65 20 69 73 20 75 73   structure is us
2190: 65 64 20 74 6f 20 6f 72 67 61 6e 69 7a 65 20 74  ed to organize t
21a0: 68 65 20 73 74 72 65 61 6d 20 6f 66 20 72 65 63  he stream of rec
21b0: 6f 72 64 73 0a 2a 2a 20 62 65 69 6e 67 20 77 72  ords.** being wr
21c0: 69 74 74 65 6e 20 74 6f 20 66 69 6c 65 73 20 62  itten to files b
21d0: 79 20 74 68 65 20 6d 65 72 67 65 2d 73 6f 72 74  y the merge-sort
21e0: 20 63 6f 64 65 20 69 6e 74 6f 20 61 6c 69 67 6e   code into align
21f0: 65 64 2c 20 70 61 67 65 2d 73 69 7a 65 64 0a 2a  ed, page-sized.*
2200: 2a 20 62 6c 6f 63 6b 73 2e 20 20 44 6f 69 6e 67  * blocks.  Doing
2210: 20 61 6c 6c 20 49 2f 4f 20 69 6e 20 61 6c 69 67   all I/O in alig
2220: 6e 65 64 20 70 61 67 65 2d 73 69 7a 65 64 20 62  ned page-sized b
2230: 6c 6f 63 6b 73 20 68 65 6c 70 73 20 49 2f 4f 20  locks helps I/O 
2240: 74 6f 20 67 6f 0a 2a 2a 20 66 61 73 74 65 72 20  to go.** faster 
2250: 6f 6e 20 6d 61 6e 79 20 6f 70 65 72 61 74 69 6e  on many operatin
2260: 67 20 73 79 73 74 65 6d 73 2e 0a 2a 2f 0a 73 74  g systems..*/.st
2270: 72 75 63 74 20 46 69 6c 65 57 72 69 74 65 72 20  ruct FileWriter 
2280: 7b 0a 20 20 69 6e 74 20 65 46 57 45 72 72 3b 20  {.  int eFWErr; 
2290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22a0: 20 20 20 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20      /* Non-zero 
22b0: 69 66 20 69 6e 20 61 6e 20 65 72 72 6f 72 20 73  if in an error s
22c0: 74 61 74 65 20 2a 2f 0a 20 20 75 38 20 2a 61 42  tate */.  u8 *aB
22d0: 75 66 66 65 72 3b 20 20 20 20 20 20 20 20 20 20  uffer;          
22e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
22f0: 6e 74 65 72 20 74 6f 20 77 72 69 74 65 20 62 75  nter to write bu
2300: 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  ffer */.  int nB
2310: 75 66 66 65 72 3b 20 20 20 20 20 20 20 20 20 20  uffer;          
2320: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
2330: 65 20 6f 66 20 77 72 69 74 65 20 62 75 66 66 65  e of write buffe
2340: 72 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  r in bytes */.  
2350: 69 6e 74 20 69 42 75 66 53 74 61 72 74 3b 20 20  int iBufStart;  
2360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2370: 2f 2a 20 46 69 72 73 74 20 62 79 74 65 20 6f 66  /* First byte of
2380: 20 62 75 66 66 65 72 20 74 6f 20 77 72 69 74 65   buffer to write
2390: 20 2a 2f 0a 20 20 69 6e 74 20 69 42 75 66 45 6e   */.  int iBufEn
23a0: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
23b0: 20 20 20 20 20 20 2f 2a 20 4c 61 73 74 20 62 79        /* Last by
23c0: 74 65 20 6f 66 20 62 75 66 66 65 72 20 74 6f 20  te of buffer to 
23d0: 77 72 69 74 65 20 2a 2f 0a 20 20 69 36 34 20 69  write */.  i64 i
23e0: 57 72 69 74 65 4f 66 66 3b 20 20 20 20 20 20 20  WriteOff;       
23f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66             /* Of
2400: 66 73 65 74 20 6f 66 20 73 74 61 72 74 20 6f 66  fset of start of
2410: 20 62 75 66 66 65 72 20 69 6e 20 66 69 6c 65 20   buffer in file 
2420: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  */.  sqlite3_fil
2430: 65 20 2a 70 46 69 6c 65 3b 20 20 20 20 20 20 20  e *pFile;       
2440: 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 74 6f 20       /* File to 
2450: 77 72 69 74 65 20 74 6f 20 2a 2f 0a 7d 3b 0a 0a  write to */.};..
2460: 2f 2a 0a 2a 2a 20 41 20 73 74 72 75 63 74 75 72  /*.** A structur
2470: 65 20 74 6f 20 73 74 6f 72 65 20 61 20 73 69 6e  e to store a sin
2480: 67 6c 65 20 72 65 63 6f 72 64 2e 20 41 6c 6c 20  gle record. All 
2490: 69 6e 2d 6d 65 6d 6f 72 79 20 72 65 63 6f 72 64  in-memory record
24a0: 73 20 61 72 65 20 63 6f 6e 6e 65 63 74 65 64 0a  s are connected.
24b0: 2a 2a 20 74 6f 67 65 74 68 65 72 20 69 6e 74 6f  ** together into
24c0: 20 61 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 68   a linked list h
24d0: 65 61 64 65 64 20 61 74 20 56 64 62 65 53 6f 72  eaded at VdbeSor
24e0: 74 65 72 2e 70 52 65 63 6f 72 64 20 75 73 69 6e  ter.pRecord usin
24f0: 67 20 74 68 65 20 0a 2a 2a 20 53 6f 72 74 65 72  g the .** Sorter
2500: 52 65 63 6f 72 64 2e 70 4e 65 78 74 20 70 6f 69  Record.pNext poi
2510: 6e 74 65 72 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  nter..*/.struct 
2520: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 7b 0a 20  SorterRecord {. 
2530: 20 76 6f 69 64 20 2a 70 56 61 6c 3b 0a 20 20 69   void *pVal;.  i
2540: 6e 74 20 6e 56 61 6c 3b 0a 20 20 53 6f 72 74 65  nt nVal;.  Sorte
2550: 72 52 65 63 6f 72 64 20 2a 70 4e 65 78 74 3b 0a  rRecord *pNext;.
2560: 7d 3b 0a 0a 2f 2a 20 54 68 65 20 6d 69 6e 69 6d  };../* The minim
2570: 75 6d 20 50 4d 41 20 73 69 7a 65 20 69 73 20 73  um PMA size is s
2580: 65 74 20 74 6f 20 74 68 69 73 20 76 61 6c 75 65  et to this value
2590: 20 6d 75 6c 74 69 70 6c 69 65 64 20 62 79 20 74   multiplied by t
25a0: 68 65 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 70  he database.** p
25b0: 61 67 65 20 73 69 7a 65 20 69 6e 20 62 79 74 65  age size in byte
25c0: 73 2e 20 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53  s.  */.#define S
25d0: 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e  ORTER_MIN_WORKIN
25e0: 47 20 31 30 0a 0a 2f 2a 20 4d 61 78 69 6d 75 6d  G 10../* Maximum
25f0: 20 6e 75 6d 62 65 72 20 6f 66 20 73 65 67 6d 65   number of segme
2600: 6e 74 73 20 74 6f 20 6d 65 72 67 65 20 69 6e 20  nts to merge in 
2610: 61 20 73 69 6e 67 6c 65 20 70 61 73 73 2e 20 2a  a single pass. *
2620: 2f 0a 23 64 65 66 69 6e 65 20 53 4f 52 54 45 52  /.#define SORTER
2630: 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
2640: 20 31 36 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20   16../*.** Free 
2650: 61 6c 6c 20 6d 65 6d 6f 72 79 20 62 65 6c 6f 6e  all memory belon
2660: 67 69 6e 67 20 74 6f 20 74 68 65 20 56 64 62 65  ging to the Vdbe
2670: 53 6f 72 74 65 72 49 74 65 72 20 6f 62 6a 65 63  SorterIter objec
2680: 74 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20  t passed as the 
2690: 73 65 63 6f 6e 64 0a 2a 2a 20 61 72 67 75 6d 65  second.** argume
26a0: 6e 74 2e 20 41 6c 6c 20 73 74 72 75 63 74 75 72  nt. All structur
26b0: 65 20 66 69 65 6c 64 73 20 61 72 65 20 73 65 74  e fields are set
26c0: 20 74 6f 20 7a 65 72 6f 20 62 65 66 6f 72 65 20   to zero before 
26d0: 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74  returning..*/.st
26e0: 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f  atic void vdbeSo
26f0: 72 74 65 72 49 74 65 72 5a 65 72 6f 28 56 64 62  rterIterZero(Vdb
2700: 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74  eSorterIter *pIt
2710: 65 72 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66  er){.  sqlite3_f
2720: 72 65 65 28 70 49 74 65 72 2d 3e 61 41 6c 6c 6f  ree(pIter->aAllo
2730: 63 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  c);.  sqlite3_fr
2740: 65 65 28 70 49 74 65 72 2d 3e 61 42 75 66 66 65  ee(pIter->aBuffe
2750: 72 29 3b 0a 20 20 6d 65 6d 73 65 74 28 70 49 74  r);.  memset(pIt
2760: 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 56 64  er, 0, sizeof(Vd
2770: 62 65 53 6f 72 74 65 72 49 74 65 72 29 29 3b 0a  beSorterIter));.
2780: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 6e 42  }../*.** Read nB
2790: 79 74 65 20 62 79 74 65 73 20 6f 66 20 64 61 74  yte bytes of dat
27a0: 61 20 66 72 6f 6d 20 74 68 65 20 73 74 72 65 61  a from the strea
27b0: 6d 20 6f 66 20 64 61 74 61 20 69 74 65 72 61 74  m of data iterat
27c0: 65 64 20 62 79 20 6f 62 6a 65 63 74 20 70 2e 0a  ed by object p..
27d0: 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c  ** If successful
27e0: 2c 20 73 65 74 20 2a 70 70 4f 75 74 20 74 6f 20  , set *ppOut to 
27f0: 70 6f 69 6e 74 20 74 6f 20 61 20 62 75 66 66 65  point to a buffe
2800: 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65  r containing the
2810: 20 64 61 74 61 0a 2a 2a 20 61 6e 64 20 72 65 74   data.** and ret
2820: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 4f  urn SQLITE_OK. O
2830: 74 68 65 72 77 69 73 65 2c 20 69 66 20 61 6e 20  therwise, if an 
2840: 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 72 65  error occurs, re
2850: 74 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 0a 2a  turn an SQLite.*
2860: 2a 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a  * error code..**
2870: 0a 2a 2a 20 54 68 65 20 62 75 66 66 65 72 20 69  .** The buffer i
2880: 6e 64 69 63 61 74 65 64 20 62 79 20 2a 70 70 4f  ndicated by *ppO
2890: 75 74 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 63  ut may only be c
28a0: 6f 6e 73 69 64 65 72 65 64 20 76 61 6c 69 64 20  onsidered valid 
28b0: 75 6e 74 69 6c 20 74 68 65 0a 2a 2a 20 6e 65 78  until the.** nex
28c0: 74 20 63 61 6c 6c 20 74 6f 20 74 68 69 73 20 66  t call to this f
28d0: 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74  unction..*/.stat
28e0: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
28f0: 72 49 74 65 72 52 65 61 64 28 0a 20 20 56 64 62  rIterRead(.  Vdb
2900: 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70 2c 20  eSorterIter *p, 
2910: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2920: 49 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69 6e  Iterator */.  in
2930: 74 20 6e 42 79 74 65 2c 20 20 20 20 20 20 20 20  t nByte,        
2940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2950: 20 42 79 74 65 73 20 6f 66 20 64 61 74 61 20 74   Bytes of data t
2960: 6f 20 72 65 61 64 20 2a 2f 0a 20 20 75 38 20 2a  o read */.  u8 *
2970: 2a 70 70 4f 75 74 20 20 20 20 20 20 20 20 20 20  *ppOut          
2980: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
2990: 55 54 3a 20 50 6f 69 6e 74 65 72 20 74 6f 20 62  UT: Pointer to b
29a0: 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67  uffer containing
29b0: 20 64 61 74 61 20 2a 2f 0a 29 7b 0a 20 20 69 6e   data */.){.  in
29c0: 74 20 69 42 75 66 3b 20 20 20 20 20 20 20 20 20  t iBuf;         
29d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
29e0: 20 4f 66 66 73 65 74 20 77 69 74 68 69 6e 20 62   Offset within b
29f0: 75 66 66 65 72 20 74 6f 20 72 65 61 64 20 66 72  uffer to read fr
2a00: 6f 6d 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 76 61  om */.  int nAva
2a10: 69 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  il;             
2a20: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
2a30: 20 6f 66 20 64 61 74 61 20 61 76 61 69 6c 61 62   of data availab
2a40: 6c 65 20 69 6e 20 62 75 66 66 65 72 20 2a 2f 0a  le in buffer */.
2a50: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61 42 75    assert( p->aBu
2a60: 66 66 65 72 20 29 3b 0a 0a 20 20 2f 2a 20 49 66  ffer );..  /* If
2a70: 20 74 68 65 72 65 20 69 73 20 6e 6f 20 6d 6f 72   there is no mor
2a80: 65 20 64 61 74 61 20 74 6f 20 62 65 20 72 65 61  e data to be rea
2a90: 64 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66 65  d from the buffe
2aa0: 72 2c 20 72 65 61 64 20 74 68 65 20 6e 65 78 74  r, read the next
2ab0: 20 0a 20 20 2a 2a 20 70 2d 3e 6e 42 75 66 66 65   .  ** p->nBuffe
2ac0: 72 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20  r bytes of data 
2ad0: 66 72 6f 6d 20 74 68 65 20 66 69 6c 65 20 69 6e  from the file in
2ae0: 74 6f 20 69 74 2e 20 4f 72 2c 20 69 66 20 74 68  to it. Or, if th
2af0: 65 72 65 20 61 72 65 20 6c 65 73 73 0a 20 20 2a  ere are less.  *
2b00: 2a 20 74 68 61 6e 20 70 2d 3e 6e 42 75 66 66 65  * than p->nBuffe
2b10: 72 20 62 79 74 65 73 20 72 65 6d 61 69 6e 69 6e  r bytes remainin
2b20: 67 20 69 6e 20 74 68 65 20 50 4d 41 2c 20 72 65  g in the PMA, re
2b30: 61 64 20 61 6c 6c 20 72 65 6d 61 69 6e 69 6e 67  ad all remaining
2b40: 20 64 61 74 61 2e 20 20 2a 2f 0a 20 20 69 42 75   data.  */.  iBu
2b50: 66 20 3d 20 70 2d 3e 69 52 65 61 64 4f 66 66 20  f = p->iReadOff 
2b60: 25 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20  % p->nBuffer;.  
2b70: 69 66 28 20 69 42 75 66 3d 3d 30 20 29 7b 0a 20  if( iBuf==0 ){. 
2b80: 20 20 20 69 6e 74 20 6e 52 65 61 64 3b 20 20 20     int nRead;   
2b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2ba0: 20 2f 2a 20 42 79 74 65 73 20 74 6f 20 72 65 61   /* Bytes to rea
2bb0: 64 20 66 72 6f 6d 20 64 69 73 6b 20 2a 2f 0a 20  d from disk */. 
2bc0: 20 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20     int rc;      
2bd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2be0: 20 2f 2a 20 73 71 6c 69 74 65 33 4f 73 52 65 61   /* sqlite3OsRea
2bf0: 64 28 29 20 72 65 74 75 72 6e 20 63 6f 64 65 20  d() return code 
2c00: 2a 2f 0a 0a 20 20 20 20 2f 2a 20 44 65 74 65 72  */..    /* Deter
2c10: 6d 69 6e 65 20 68 6f 77 20 6d 61 6e 79 20 62 79  mine how many by
2c20: 74 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 72  tes of data to r
2c30: 65 61 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20  ead. */.    if( 
2c40: 28 70 2d 3e 69 45 6f 66 20 2d 20 70 2d 3e 69 52  (p->iEof - p->iR
2c50: 65 61 64 4f 66 66 29 20 3e 20 28 69 36 34 29 70  eadOff) > (i64)p
2c60: 2d 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20  ->nBuffer ){.   
2c70: 20 20 20 6e 52 65 61 64 20 3d 20 70 2d 3e 6e 42     nRead = p->nB
2c80: 75 66 66 65 72 3b 0a 20 20 20 20 7d 65 6c 73 65  uffer;.    }else
2c90: 7b 0a 20 20 20 20 20 20 6e 52 65 61 64 20 3d 20  {.      nRead = 
2ca0: 28 69 6e 74 29 28 70 2d 3e 69 45 6f 66 20 2d 20  (int)(p->iEof - 
2cb0: 70 2d 3e 69 52 65 61 64 4f 66 66 29 3b 0a 20 20  p->iReadOff);.  
2cc0: 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20    }.    assert( 
2cd0: 6e 52 65 61 64 3e 30 20 29 3b 0a 0a 20 20 20 20  nRead>0 );..    
2ce0: 2f 2a 20 52 65 61 64 20 64 61 74 61 20 66 72 6f  /* Read data fro
2cf0: 6d 20 74 68 65 20 66 69 6c 65 2e 20 52 65 74 75  m the file. Retu
2d00: 72 6e 20 65 61 72 6c 79 20 69 66 20 61 6e 20 65  rn early if an e
2d10: 72 72 6f 72 20 6f 63 63 75 72 73 2e 20 2a 2f 0a  rror occurs. */.
2d20: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
2d30: 4f 73 52 65 61 64 28 70 2d 3e 70 46 69 6c 65 2c  OsRead(p->pFile,
2d40: 20 70 2d 3e 61 42 75 66 66 65 72 2c 20 6e 52 65   p->aBuffer, nRe
2d50: 61 64 2c 20 70 2d 3e 69 52 65 61 64 4f 66 66 29  ad, p->iReadOff)
2d60: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 72 63  ;.    assert( rc
2d70: 21 3d 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f 53  !=SQLITE_IOERR_S
2d80: 48 4f 52 54 5f 52 45 41 44 20 29 3b 0a 20 20 20  HORT_READ );.   
2d90: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
2da0: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
2db0: 20 20 7d 0a 20 20 6e 41 76 61 69 6c 20 3d 20 70    }.  nAvail = p
2dc0: 2d 3e 6e 42 75 66 66 65 72 20 2d 20 69 42 75 66  ->nBuffer - iBuf
2dd0: 3b 20 0a 0a 20 20 69 66 28 20 6e 42 79 74 65 3c  ; ..  if( nByte<
2de0: 3d 6e 41 76 61 69 6c 20 29 7b 0a 20 20 20 20 2f  =nAvail ){.    /
2df0: 2a 20 54 68 65 20 72 65 71 75 65 73 74 65 64 20  * The requested 
2e00: 64 61 74 61 20 69 73 20 61 76 61 69 6c 61 62 6c  data is availabl
2e10: 65 20 69 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f  e in the in-memo
2e20: 72 79 20 62 75 66 66 65 72 2e 20 49 6e 20 74 68  ry buffer. In th
2e30: 69 73 0a 20 20 20 20 2a 2a 20 63 61 73 65 20 74  is.    ** case t
2e40: 68 65 72 65 20 69 73 20 6e 6f 20 6e 65 65 64 20  here is no need 
2e50: 74 6f 20 6d 61 6b 65 20 61 20 63 6f 70 79 20 6f  to make a copy o
2e60: 66 20 74 68 65 20 64 61 74 61 2c 20 6a 75 73 74  f the data, just
2e70: 20 72 65 74 75 72 6e 20 61 20 0a 20 20 20 20 2a   return a .    *
2e80: 2a 20 70 6f 69 6e 74 65 72 20 69 6e 74 6f 20 74  * pointer into t
2e90: 68 65 20 62 75 66 66 65 72 20 74 6f 20 74 68 65  he buffer to the
2ea0: 20 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a 20 20 20   caller.  */.   
2eb0: 20 2a 70 70 4f 75 74 20 3d 20 26 70 2d 3e 61 42   *ppOut = &p->aB
2ec0: 75 66 66 65 72 5b 69 42 75 66 5d 3b 0a 20 20 20  uffer[iBuf];.   
2ed0: 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20   p->iReadOff += 
2ee0: 6e 42 79 74 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a  nByte;.  }else{.
2ef0: 20 20 20 20 2f 2a 20 54 68 65 20 72 65 71 75 65      /* The reque
2f00: 73 74 65 64 20 64 61 74 61 20 69 73 20 6e 6f 74  sted data is not
2f10: 20 61 6c 6c 20 61 76 61 69 6c 61 62 6c 65 20 69   all available i
2f20: 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20  n the in-memory 
2f30: 62 75 66 66 65 72 2e 0a 20 20 20 20 2a 2a 20 49  buffer..    ** I
2f40: 6e 20 74 68 69 73 20 63 61 73 65 2c 20 61 6c 6c  n this case, all
2f50: 6f 63 61 74 65 20 73 70 61 63 65 20 61 74 20 70  ocate space at p
2f60: 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 74 6f 20 63 6f  ->aAlloc[] to co
2f70: 70 79 20 74 68 65 20 72 65 71 75 65 73 74 65 64  py the requested
2f80: 0a 20 20 20 20 2a 2a 20 72 61 6e 67 65 20 69 6e  .    ** range in
2f90: 74 6f 2e 20 54 68 65 6e 20 72 65 74 75 72 6e 20  to. Then return 
2fa0: 61 20 63 6f 70 79 20 6f 66 20 70 6f 69 6e 74 65  a copy of pointe
2fb0: 72 20 70 2d 3e 61 41 6c 6c 6f 63 20 74 6f 20 74  r p->aAlloc to t
2fc0: 68 65 20 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a 20  he caller.  */. 
2fd0: 20 20 20 69 6e 74 20 6e 52 65 6d 3b 20 20 20 20     int nRem;    
2fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2ff0: 20 2f 2a 20 42 79 74 65 73 20 72 65 6d 61 69 6e   /* Bytes remain
3000: 69 6e 67 20 74 6f 20 63 6f 70 79 20 2a 2f 0a 0a  ing to copy */..
3010: 20 20 20 20 2f 2a 20 45 78 74 65 6e 64 20 74 68      /* Extend th
3020: 65 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 61 6c  e p->aAlloc[] al
3030: 6c 6f 63 61 74 69 6f 6e 20 69 66 20 72 65 71 75  location if requ
3040: 69 72 65 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28  ired. */.    if(
3050: 20 70 2d 3e 6e 41 6c 6c 6f 63 3c 6e 42 79 74 65   p->nAlloc<nByte
3060: 20 29 7b 0a 20 20 20 20 20 20 75 38 20 2a 61 4e   ){.      u8 *aN
3070: 65 77 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e  ew;.      int nN
3080: 65 77 20 3d 20 70 2d 3e 6e 41 6c 6c 6f 63 2a 32  ew = p->nAlloc*2
3090: 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 6e  ;.      while( n
30a0: 42 79 74 65 3e 6e 4e 65 77 20 29 20 6e 4e 65 77  Byte>nNew ) nNew
30b0: 20 3d 20 6e 4e 65 77 2a 32 3b 0a 20 20 20 20 20   = nNew*2;.     
30c0: 20 61 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 52   aNew = sqlite3R
30d0: 65 61 6c 6c 6f 63 28 70 2d 3e 61 41 6c 6c 6f 63  ealloc(p->aAlloc
30e0: 2c 20 6e 4e 65 77 29 3b 0a 20 20 20 20 20 20 69  , nNew);.      i
30f0: 66 28 20 21 61 4e 65 77 20 29 20 72 65 74 75 72  f( !aNew ) retur
3100: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
3110: 20 20 20 20 20 20 70 2d 3e 6e 41 6c 6c 6f 63 20        p->nAlloc 
3120: 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 70 2d  = nNew;.      p-
3130: 3e 61 41 6c 6c 6f 63 20 3d 20 61 4e 65 77 3b 0a  >aAlloc = aNew;.
3140: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 43 6f      }..    /* Co
3150: 70 79 20 61 73 20 6d 75 63 68 20 64 61 74 61 20  py as much data 
3160: 61 73 20 69 73 20 61 76 61 69 6c 61 62 6c 65 20  as is available 
3170: 69 6e 20 74 68 65 20 62 75 66 66 65 72 20 69 6e  in the buffer in
3180: 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 0a  to the start of.
3190: 20 20 20 20 2a 2a 20 70 2d 3e 61 41 6c 6c 6f 63      ** p->aAlloc
31a0: 5b 5d 2e 20 20 2a 2f 0a 20 20 20 20 6d 65 6d 63  [].  */.    memc
31b0: 70 79 28 70 2d 3e 61 41 6c 6c 6f 63 2c 20 26 70  py(p->aAlloc, &p
31c0: 2d 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d 2c  ->aBuffer[iBuf],
31d0: 20 6e 41 76 61 69 6c 29 3b 0a 20 20 20 20 70 2d   nAvail);.    p-
31e0: 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e 41 76  >iReadOff += nAv
31f0: 61 69 6c 3b 0a 20 20 20 20 6e 52 65 6d 20 3d 20  ail;.    nRem = 
3200: 6e 42 79 74 65 20 2d 20 6e 41 76 61 69 6c 3b 0a  nByte - nAvail;.
3210: 0a 20 20 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c  .    /* The foll
3220: 6f 77 69 6e 67 20 6c 6f 6f 70 20 63 6f 70 69 65  owing loop copie
3230: 73 20 75 70 20 74 6f 20 70 2d 3e 6e 42 75 66 66  s up to p->nBuff
3240: 65 72 20 62 79 74 65 73 20 70 65 72 20 69 74 65  er bytes per ite
3250: 72 61 74 69 6f 6e 20 69 6e 74 6f 0a 20 20 20 20  ration into.    
3260: 2a 2a 20 74 68 65 20 70 2d 3e 61 41 6c 6c 6f 63  ** the p->aAlloc
3270: 5b 5d 20 62 75 66 66 65 72 2e 20 20 2a 2f 0a 20  [] buffer.  */. 
3280: 20 20 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30     while( nRem>0
3290: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72 63   ){.      int rc
32a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
32b0: 20 20 20 20 20 20 2f 2a 20 76 64 62 65 53 6f 72        /* vdbeSor
32c0: 74 65 72 49 74 65 72 52 65 61 64 28 29 20 72 65  terIterRead() re
32d0: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 20  turn code */.   
32e0: 20 20 20 69 6e 74 20 6e 43 6f 70 79 3b 20 20 20     int nCopy;   
32f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3300: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  * Number of byte
3310: 73 20 74 6f 20 63 6f 70 79 20 2a 2f 0a 20 20 20  s to copy */.   
3320: 20 20 20 75 38 20 2a 61 4e 65 78 74 3b 20 20 20     u8 *aNext;   
3330: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3340: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 62 75 66  * Pointer to buf
3350: 66 65 72 20 74 6f 20 63 6f 70 79 20 64 61 74 61  fer to copy data
3360: 20 66 72 6f 6d 20 2a 2f 0a 0a 20 20 20 20 20 20   from */..      
3370: 6e 43 6f 70 79 20 3d 20 6e 52 65 6d 3b 0a 20 20  nCopy = nRem;.  
3380: 20 20 20 20 69 66 28 20 6e 52 65 6d 3e 70 2d 3e      if( nRem>p->
3390: 6e 42 75 66 66 65 72 20 29 20 6e 43 6f 70 79 20  nBuffer ) nCopy 
33a0: 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20  = p->nBuffer;.  
33b0: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
33c0: 74 65 72 49 74 65 72 52 65 61 64 28 70 2c 20 6e  terIterRead(p, n
33d0: 43 6f 70 79 2c 20 26 61 4e 65 78 74 29 3b 0a 20  Copy, &aNext);. 
33e0: 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c       if( rc!=SQL
33f0: 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
3400: 72 63 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74  rc;.      assert
3410: 28 20 61 4e 65 78 74 21 3d 70 2d 3e 61 41 6c 6c  ( aNext!=p->aAll
3420: 6f 63 20 29 3b 0a 20 20 20 20 20 20 6d 65 6d 63  oc );.      memc
3430: 70 79 28 26 70 2d 3e 61 41 6c 6c 6f 63 5b 6e 42  py(&p->aAlloc[nB
3440: 79 74 65 20 2d 20 6e 52 65 6d 5d 2c 20 61 4e 65  yte - nRem], aNe
3450: 78 74 2c 20 6e 43 6f 70 79 29 3b 0a 20 20 20 20  xt, nCopy);.    
3460: 20 20 6e 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b    nRem -= nCopy;
3470: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2a 70 70 4f  .    }..    *ppO
3480: 75 74 20 3d 20 70 2d 3e 61 41 6c 6c 6f 63 3b 0a  ut = p->aAlloc;.
3490: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51    }..  return SQ
34a0: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  LITE_OK;.}../*.*
34b0: 2a 20 52 65 61 64 20 61 20 76 61 72 69 6e 74 20  * Read a varint 
34c0: 66 72 6f 6d 20 74 68 65 20 73 74 72 65 61 6d 20  from the stream 
34d0: 6f 66 20 64 61 74 61 20 61 63 63 65 73 73 65 64  of data accessed
34e0: 20 62 79 20 70 2e 20 53 65 74 20 2a 70 6e 4f 75   by p. Set *pnOu
34f0: 74 20 74 6f 0a 2a 2a 20 74 68 65 20 76 61 6c 75  t to.** the valu
3500: 65 20 72 65 61 64 2e 0a 2a 2f 0a 73 74 61 74 69  e read..*/.stati
3510: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72  c int vdbeSorter
3520: 49 74 65 72 56 61 72 69 6e 74 28 56 64 62 65 53  IterVarint(VdbeS
3530: 6f 72 74 65 72 49 74 65 72 20 2a 70 2c 20 75 36  orterIter *p, u6
3540: 34 20 2a 70 6e 4f 75 74 29 7b 0a 20 20 69 6e 74  4 *pnOut){.  int
3550: 20 69 42 75 66 3b 0a 0a 20 20 69 42 75 66 20 3d   iBuf;..  iBuf =
3560: 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 25 20 70   p->iReadOff % p
3570: 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 69 66 28  ->nBuffer;.  if(
3580: 20 69 42 75 66 20 26 26 20 28 70 2d 3e 6e 42 75   iBuf && (p->nBu
3590: 66 66 65 72 2d 69 42 75 66 29 3e 3d 39 20 29 7b  ffer-iBuf)>=9 ){
35a0: 0a 20 20 20 20 70 2d 3e 69 52 65 61 64 4f 66 66  .    p->iReadOff
35b0: 20 2b 3d 20 73 71 6c 69 74 65 33 47 65 74 56 61   += sqlite3GetVa
35c0: 72 69 6e 74 28 26 70 2d 3e 61 42 75 66 66 65 72  rint(&p->aBuffer
35d0: 5b 69 42 75 66 5d 2c 20 70 6e 4f 75 74 29 3b 0a  [iBuf], pnOut);.
35e0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 75 38 20    }else{.    u8 
35f0: 61 56 61 72 69 6e 74 5b 31 36 5d 2c 20 2a 61 3b  aVarint[16], *a;
3600: 0a 20 20 20 20 69 6e 74 20 69 20 3d 20 30 2c 20  .    int i = 0, 
3610: 72 63 3b 0a 20 20 20 20 64 6f 7b 0a 20 20 20 20  rc;.    do{.    
3620: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
3630: 72 49 74 65 72 52 65 61 64 28 70 2c 20 31 2c 20  rIterRead(p, 1, 
3640: 26 61 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  &a);.      if( r
3650: 63 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  c ) return rc;. 
3660: 20 20 20 20 20 61 56 61 72 69 6e 74 5b 28 69 2b       aVarint[(i+
3670: 2b 29 26 30 78 66 5d 20 3d 20 61 5b 30 5d 3b 0a  +)&0xf] = a[0];.
3680: 20 20 20 20 7d 77 68 69 6c 65 28 20 28 61 5b 30      }while( (a[0
3690: 5d 26 30 78 38 30 29 21 3d 30 20 29 3b 0a 20 20  ]&0x80)!=0 );.  
36a0: 20 20 73 71 6c 69 74 65 33 47 65 74 56 61 72 69    sqlite3GetVari
36b0: 6e 74 28 61 56 61 72 69 6e 74 2c 20 70 6e 4f 75  nt(aVarint, pnOu
36c0: 74 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  t);.  }..  retur
36d0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
36e0: 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 69  ./*.** Advance i
36f0: 74 65 72 61 74 6f 72 20 70 49 74 65 72 20 74 6f  terator pIter to
3700: 20 74 68 65 20 6e 65 78 74 20 6b 65 79 20 69 6e   the next key in
3710: 20 69 74 73 20 50 4d 41 2e 20 52 65 74 75 72 6e   its PMA. Return
3720: 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 0a 2a 2a   SQLITE_OK if.**
3730: 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73   no error occurs
3740: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65  , or an SQLite e
3750: 72 72 6f 72 20 63 6f 64 65 20 69 66 20 6f 6e 65  rror code if one
3760: 20 64 6f 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63   does..*/.static
3770: 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72 49   int vdbeSorterI
3780: 74 65 72 4e 65 78 74 28 56 64 62 65 53 6f 72 74  terNext(VdbeSort
3790: 65 72 49 74 65 72 20 2a 70 49 74 65 72 29 7b 0a  erIter *pIter){.
37a0: 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
37b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
37c0: 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65    /* Return Code
37d0: 20 2a 2f 0a 20 20 75 36 34 20 6e 52 65 63 20 3d   */.  u64 nRec =
37e0: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
37f0: 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
3800: 20 72 65 63 6f 72 64 20 69 6e 20 62 79 74 65 73   record in bytes
3810: 20 2a 2f 0a 0a 20 20 69 66 28 20 70 49 74 65 72   */..  if( pIter
3820: 2d 3e 69 52 65 61 64 4f 66 66 3e 3d 70 49 74 65  ->iReadOff>=pIte
3830: 72 2d 3e 69 45 6f 66 20 29 7b 0a 20 20 20 20 2f  r->iEof ){.    /
3840: 2a 20 54 68 69 73 20 69 73 20 61 6e 20 45 4f 46  * This is an EOF
3850: 20 63 6f 6e 64 69 74 69 6f 6e 20 2a 2f 0a 20 20   condition */.  
3860: 20 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72    vdbeSorterIter
3870: 5a 65 72 6f 28 70 49 74 65 72 29 3b 0a 20 20 20  Zero(pIter);.   
3880: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
3890: 4b 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20 76  K;.  }..  rc = v
38a0: 64 62 65 53 6f 72 74 65 72 49 74 65 72 56 61 72  dbeSorterIterVar
38b0: 69 6e 74 28 70 49 74 65 72 2c 20 26 6e 52 65 63  int(pIter, &nRec
38c0: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  );.  if( rc==SQL
38d0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 49  ITE_OK ){.    pI
38e0: 74 65 72 2d 3e 6e 4b 65 79 20 3d 20 28 69 6e 74  ter->nKey = (int
38f0: 29 6e 52 65 63 3b 0a 20 20 20 20 72 63 20 3d 20  )nRec;.    rc = 
3900: 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 52 65  vdbeSorterIterRe
3910: 61 64 28 70 49 74 65 72 2c 20 28 69 6e 74 29 6e  ad(pIter, (int)n
3920: 52 65 63 2c 20 26 70 49 74 65 72 2d 3e 61 4b 65  Rec, &pIter->aKe
3930: 79 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  y);.  }..  retur
3940: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  n rc;.}../*.** I
3950: 6e 69 74 69 61 6c 69 7a 65 20 69 74 65 72 61 74  nitialize iterat
3960: 6f 72 20 70 49 74 65 72 20 74 6f 20 73 63 61 6e  or pIter to scan
3970: 20 74 68 72 6f 75 67 68 20 74 68 65 20 50 4d 41   through the PMA
3980: 20 73 74 6f 72 65 64 20 69 6e 20 66 69 6c 65 20   stored in file 
3990: 70 46 69 6c 65 0a 2a 2a 20 73 74 61 72 74 69 6e  pFile.** startin
39a0: 67 20 61 74 20 6f 66 66 73 65 74 20 69 53 74 61  g at offset iSta
39b0: 72 74 20 61 6e 64 20 65 6e 64 69 6e 67 20 61 74  rt and ending at
39c0: 20 6f 66 66 73 65 74 20 69 45 6f 66 2d 31 2e 20   offset iEof-1. 
39d0: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 0a 2a  This function .*
39e0: 2a 20 6c 65 61 76 65 73 20 74 68 65 20 69 74 65  * leaves the ite
39f0: 72 61 74 6f 72 20 70 6f 69 6e 74 69 6e 67 20 74  rator pointing t
3a00: 6f 20 74 68 65 20 66 69 72 73 74 20 6b 65 79 20  o the first key 
3a10: 69 6e 20 74 68 65 20 50 4d 41 20 28 6f 72 20 45  in the PMA (or E
3a20: 4f 46 20 69 66 20 74 68 65 20 0a 2a 2a 20 50 4d  OF if the .** PM
3a30: 41 20 69 73 20 65 6d 70 74 79 29 2e 0a 2a 2f 0a  A is empty)..*/.
3a40: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53  static int vdbeS
3a50: 6f 72 74 65 72 49 74 65 72 49 6e 69 74 28 0a 20  orterIterInit(. 
3a60: 20 53 6f 72 74 65 72 54 68 72 65 61 64 20 2a 70   SorterThread *p
3a70: 54 68 72 65 61 64 2c 20 20 20 20 20 20 20 20 20  Thread,         
3a80: 20 2f 2a 20 54 68 72 65 61 64 20 63 6f 6e 74 65   /* Thread conte
3a90: 78 74 20 2a 2f 0a 20 20 69 36 34 20 69 53 74 61  xt */.  i64 iSta
3aa0: 72 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  rt,             
3ab0: 20 20 20 20 20 20 20 20 2f 2a 20 53 74 61 72 74          /* Start
3ac0: 20 6f 66 66 73 65 74 20 69 6e 20 70 54 68 72 65   offset in pThre
3ad0: 61 64 2d 3e 70 54 65 6d 70 31 20 2a 2f 0a 20 20  ad->pTemp1 */.  
3ae0: 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a  VdbeSorterIter *
3af0: 70 49 74 65 72 2c 20 20 20 20 20 20 20 20 20 20  pIter,          
3b00: 2f 2a 20 49 74 65 72 61 74 6f 72 20 74 6f 20 70  /* Iterator to p
3b10: 6f 70 75 6c 61 74 65 20 2a 2f 0a 20 20 69 36 34  opulate */.  i64
3b20: 20 2a 70 6e 42 79 74 65 20 20 20 20 20 20 20 20   *pnByte        
3b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3b40: 49 4e 2f 4f 55 54 3a 20 49 6e 63 72 65 6d 65 6e  IN/OUT: Incremen
3b50: 74 20 74 68 69 73 20 76 61 6c 75 65 20 62 79 20  t this value by 
3b60: 50 4d 41 20 73 69 7a 65 20 2a 2f 0a 29 7b 0a 20  PMA size */.){. 
3b70: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
3b80: 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 42 75 66 20  _OK;.  int nBuf 
3b90: 3d 20 70 54 68 72 65 61 64 2d 3e 70 67 73 7a 3b  = pThread->pgsz;
3ba0: 0a 0a 20 20 61 73 73 65 72 74 28 20 70 54 68 72  ..  assert( pThr
3bb0: 65 61 64 2d 3e 69 54 65 6d 70 31 4f 66 66 3e 69  ead->iTemp1Off>i
3bc0: 53 74 61 72 74 20 29 3b 0a 20 20 61 73 73 65 72  Start );.  asser
3bd0: 74 28 20 70 49 74 65 72 2d 3e 61 41 6c 6c 6f 63  t( pIter->aAlloc
3be0: 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==0 );.  assert(
3bf0: 20 70 49 74 65 72 2d 3e 61 42 75 66 66 65 72 3d   pIter->aBuffer=
3c00: 3d 30 20 29 3b 0a 20 20 70 49 74 65 72 2d 3e 70  =0 );.  pIter->p
3c10: 46 69 6c 65 20 3d 20 70 54 68 72 65 61 64 2d 3e  File = pThread->
3c20: 70 54 65 6d 70 31 3b 0a 20 20 70 49 74 65 72 2d  pTemp1;.  pIter-
3c30: 3e 69 52 65 61 64 4f 66 66 20 3d 20 69 53 74 61  >iReadOff = iSta
3c40: 72 74 3b 0a 20 20 70 49 74 65 72 2d 3e 6e 41 6c  rt;.  pIter->nAl
3c50: 6c 6f 63 20 3d 20 31 32 38 3b 0a 20 20 70 49 74  loc = 128;.  pIt
3c60: 65 72 2d 3e 61 41 6c 6c 6f 63 20 3d 20 28 75 38  er->aAlloc = (u8
3c70: 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28  *)sqlite3Malloc(
3c80: 70 49 74 65 72 2d 3e 6e 41 6c 6c 6f 63 29 3b 0a  pIter->nAlloc);.
3c90: 20 20 70 49 74 65 72 2d 3e 6e 42 75 66 66 65 72    pIter->nBuffer
3ca0: 20 3d 20 6e 42 75 66 3b 0a 20 20 70 49 74 65 72   = nBuf;.  pIter
3cb0: 2d 3e 61 42 75 66 66 65 72 20 3d 20 28 75 38 2a  ->aBuffer = (u8*
3cc0: 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 6e  )sqlite3Malloc(n
3cd0: 42 75 66 29 3b 0a 0a 20 20 69 66 28 20 21 70 49  Buf);..  if( !pI
3ce0: 74 65 72 2d 3e 61 42 75 66 66 65 72 20 29 7b 0a  ter->aBuffer ){.
3cf0: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
3d00: 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a  NOMEM;.  }else{.
3d10: 20 20 20 20 69 6e 74 20 69 42 75 66 3b 0a 0a 20      int iBuf;.. 
3d20: 20 20 20 69 42 75 66 20 3d 20 69 53 74 61 72 74     iBuf = iStart
3d30: 20 25 20 6e 42 75 66 3b 0a 20 20 20 20 69 66 28   % nBuf;.    if(
3d40: 20 69 42 75 66 20 29 7b 0a 20 20 20 20 20 20 69   iBuf ){.      i
3d50: 6e 74 20 6e 52 65 61 64 20 3d 20 6e 42 75 66 20  nt nRead = nBuf 
3d60: 2d 20 69 42 75 66 3b 0a 20 20 20 20 20 20 69 66  - iBuf;.      if
3d70: 28 20 28 69 53 74 61 72 74 20 2b 20 6e 52 65 61  ( (iStart + nRea
3d80: 64 29 20 3e 20 70 54 68 72 65 61 64 2d 3e 69 54  d) > pThread->iT
3d90: 65 6d 70 31 4f 66 66 20 29 7b 0a 20 20 20 20 20  emp1Off ){.     
3da0: 20 20 20 6e 52 65 61 64 20 3d 20 28 69 6e 74 29     nRead = (int)
3db0: 28 70 54 68 72 65 61 64 2d 3e 69 54 65 6d 70 31  (pThread->iTemp1
3dc0: 4f 66 66 20 2d 20 69 53 74 61 72 74 29 3b 0a 20  Off - iStart);. 
3dd0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72 63 20       }.      rc 
3de0: 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28  = sqlite3OsRead(
3df0: 0a 20 20 20 20 20 20 20 20 20 20 70 54 68 72 65  .          pThre
3e00: 61 64 2d 3e 70 54 65 6d 70 31 2c 20 26 70 49 74  ad->pTemp1, &pIt
3e10: 65 72 2d 3e 61 42 75 66 66 65 72 5b 69 42 75 66  er->aBuffer[iBuf
3e20: 5d 2c 20 6e 52 65 61 64 2c 20 69 53 74 61 72 74  ], nRead, iStart
3e30: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20  .      );.      
3e40: 61 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49  assert( rc!=SQLI
3e50: 54 45 5f 49 4f 45 52 52 5f 53 48 4f 52 54 5f 52  TE_IOERR_SHORT_R
3e60: 45 41 44 20 29 3b 0a 20 20 20 20 7d 0a 0a 20 20  EAD );.    }..  
3e70: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
3e80: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 75 36 34  _OK ){.      u64
3e90: 20 6e 42 79 74 65 3b 0a 20 20 20 20 20 20 70 49   nByte;.      pI
3ea0: 74 65 72 2d 3e 69 45 6f 66 20 3d 20 70 54 68 72  ter->iEof = pThr
3eb0: 65 61 64 2d 3e 69 54 65 6d 70 31 4f 66 66 3b 0a  ead->iTemp1Off;.
3ec0: 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53        rc = vdbeS
3ed0: 6f 72 74 65 72 49 74 65 72 56 61 72 69 6e 74 28  orterIterVarint(
3ee0: 70 49 74 65 72 2c 20 26 6e 42 79 74 65 29 3b 0a  pIter, &nByte);.
3ef0: 20 20 20 20 20 20 70 49 74 65 72 2d 3e 69 45 6f        pIter->iEo
3f00: 66 20 3d 20 70 49 74 65 72 2d 3e 69 52 65 61 64  f = pIter->iRead
3f10: 4f 66 66 20 2b 20 6e 42 79 74 65 3b 0a 20 20 20  Off + nByte;.   
3f20: 20 20 20 2a 70 6e 42 79 74 65 20 2b 3d 20 6e 42     *pnByte += nB
3f30: 79 74 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  yte;.    }.  }..
3f40: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
3f50: 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
3f60: 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 4e 65  vdbeSorterIterNe
3f70: 78 74 28 70 49 74 65 72 29 3b 0a 20 20 7d 0a 20  xt(pIter);.  }. 
3f80: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a   return rc;.}...
3f90: 2f 2a 0a 2a 2a 20 43 6f 6d 70 61 72 65 20 6b 65  /*.** Compare ke
3fa0: 79 31 20 28 62 75 66 66 65 72 20 70 4b 65 79 31  y1 (buffer pKey1
3fb0: 2c 20 73 69 7a 65 20 6e 4b 65 79 31 20 62 79 74  , size nKey1 byt
3fc0: 65 73 29 20 77 69 74 68 20 6b 65 79 32 20 28 62  es) with key2 (b
3fd0: 75 66 66 65 72 20 70 4b 65 79 32 2c 20 0a 2a 2a  uffer pKey2, .**
3fe0: 20 73 69 7a 65 20 6e 4b 65 79 32 20 62 79 74 65   size nKey2 byte
3ff0: 73 29 2e 20 20 41 72 67 75 6d 65 6e 74 20 70 4b  s).  Argument pK
4000: 65 79 49 6e 66 6f 20 73 75 70 70 6c 69 65 73 20  eyInfo supplies 
4010: 74 68 65 20 63 6f 6c 6c 61 74 69 6f 6e 20 66 75  the collation fu
4020: 6e 63 74 69 6f 6e 73 0a 2a 2a 20 75 73 65 64 20  nctions.** used 
4030: 62 79 20 74 68 65 20 63 6f 6d 70 61 72 69 73 6f  by the compariso
4040: 6e 2e 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f  n. If an error o
4050: 63 63 75 72 73 2c 20 72 65 74 75 72 6e 20 61 6e  ccurs, return an
4060: 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
4070: 64 65 2e 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65  de..** Otherwise
4080: 2c 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  , return SQLITE_
4090: 4f 4b 20 61 6e 64 20 73 65 74 20 2a 70 52 65 73  OK and set *pRes
40a0: 20 74 6f 20 61 20 6e 65 67 61 74 69 76 65 2c 20   to a negative, 
40b0: 7a 65 72 6f 20 6f 72 20 70 6f 73 69 74 69 76 65  zero or positive
40c0: 0a 2a 2a 20 76 61 6c 75 65 2c 20 64 65 70 65 6e  .** value, depen
40d0: 64 69 6e 67 20 6f 6e 20 77 68 65 74 68 65 72 20  ding on whether 
40e0: 6b 65 79 31 20 69 73 20 73 6d 61 6c 6c 65 72 2c  key1 is smaller,
40f0: 20 65 71 75 61 6c 20 74 6f 20 6f 72 20 6c 61 72   equal to or lar
4100: 67 65 72 20 74 68 61 6e 20 6b 65 79 32 2e 0a 2a  ger than key2..*
4110: 2a 0a 2a 2a 20 49 66 20 74 68 65 20 62 4f 6d 69  *.** If the bOmi
4120: 74 52 6f 77 69 64 20 61 72 67 75 6d 65 6e 74 20  tRowid argument 
4130: 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 61 73 73  is non-zero, ass
4140: 75 6d 65 20 62 6f 74 68 20 6b 65 79 73 20 65 6e  ume both keys en
4150: 64 20 69 6e 20 61 20 72 6f 77 69 64 0a 2a 2a 20  d in a rowid.** 
4160: 66 69 65 6c 64 2e 20 46 6f 72 20 74 68 65 20 70  field. For the p
4170: 75 72 70 6f 73 65 73 20 6f 66 20 74 68 65 20 63  urposes of the c
4180: 6f 6d 70 61 72 69 73 6f 6e 2c 20 69 67 6e 6f 72  omparison, ignor
4190: 65 20 69 74 2e 20 41 6c 73 6f 2c 20 69 66 20 62  e it. Also, if b
41a0: 4f 6d 69 74 52 6f 77 69 64 0a 2a 2a 20 69 73 20  OmitRowid.** is 
41b0: 74 72 75 65 20 61 6e 64 20 6b 65 79 31 20 63 6f  true and key1 co
41c0: 6e 74 61 69 6e 73 20 65 76 65 6e 20 61 20 73 69  ntains even a si
41d0: 6e 67 6c 65 20 4e 55 4c 4c 20 76 61 6c 75 65 2c  ngle NULL value,
41e0: 20 69 74 20 69 73 20 63 6f 6e 73 69 64 65 72 65   it is considere
41f0: 64 20 74 6f 0a 2a 2a 20 62 65 20 6c 65 73 73 20  d to.** be less 
4200: 74 68 61 6e 20 6b 65 79 32 2e 20 45 76 65 6e 20  than key2. Even 
4210: 69 66 20 6b 65 79 32 20 61 6c 73 6f 20 63 6f 6e  if key2 also con
4220: 74 61 69 6e 73 20 4e 55 4c 4c 20 76 61 6c 75 65  tains NULL value
4230: 73 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 70 4b 65 79  s..**.** If pKey
4240: 32 20 69 73 20 70 61 73 73 65 64 20 61 20 4e 55  2 is passed a NU
4250: 4c 4c 20 70 6f 69 6e 74 65 72 2c 20 74 68 65 6e  LL pointer, then
4260: 20 69 74 20 69 73 20 61 73 73 75 6d 65 64 20 74   it is assumed t
4270: 68 61 74 20 74 68 65 20 70 43 73 72 2d 3e 61 53  hat the pCsr->aS
4280: 70 61 63 65 0a 2a 2a 20 68 61 73 20 62 65 65 6e  pace.** has been
4290: 20 61 6c 6c 6f 63 61 74 65 64 20 61 6e 64 20 63   allocated and c
42a0: 6f 6e 74 61 69 6e 73 20 61 6e 20 75 6e 70 61 63  ontains an unpac
42b0: 6b 65 64 20 72 65 63 6f 72 64 20 74 68 61 74 20  ked record that 
42c0: 69 73 20 75 73 65 64 20 61 73 20 6b 65 79 32 2e  is used as key2.
42d0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
42e0: 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72  vdbeSorterCompar
42f0: 65 28 0a 20 20 53 6f 72 74 65 72 54 68 72 65 61  e(.  SorterThrea
4300: 64 20 2a 70 54 68 72 65 61 64 2c 20 20 20 20 20  d *pThread,     
4310: 20 20 20 20 20 2f 2a 20 54 68 72 65 61 64 20 63       /* Thread c
4320: 6f 6e 74 65 78 74 20 28 66 6f 72 20 70 4b 65 79  ontext (for pKey
4330: 49 6e 66 6f 29 20 2a 2f 0a 20 20 69 6e 74 20 6e  Info) */.  int n
4340: 49 67 6e 6f 72 65 2c 20 20 20 20 20 20 20 20 20  Ignore,         
4350: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 67             /* Ig
4360: 6e 6f 72 65 20 74 68 65 20 6c 61 73 74 20 6e 49  nore the last nI
4370: 67 6e 6f 72 65 20 66 69 65 6c 64 73 20 2a 2f 0a  gnore fields */.
4380: 20 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 4b    const void *pK
4390: 65 79 31 2c 20 69 6e 74 20 6e 4b 65 79 31 2c 20  ey1, int nKey1, 
43a0: 20 20 2f 2a 20 4c 65 66 74 20 73 69 64 65 20 6f    /* Left side o
43b0: 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f 0a  f comparison */.
43c0: 20 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 4b    const void *pK
43d0: 65 79 32 2c 20 69 6e 74 20 6e 4b 65 79 32 2c 20  ey2, int nKey2, 
43e0: 20 20 2f 2a 20 52 69 67 68 74 20 73 69 64 65 20    /* Right side 
43f0: 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f  of comparison */
4400: 0a 20 20 69 6e 74 20 2a 70 52 65 73 20 20 20 20  .  int *pRes    
4410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4420: 20 20 20 2f 2a 20 4f 55 54 3a 20 52 65 73 75 6c     /* OUT: Resul
4430: 74 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20  t of comparison 
4440: 2a 2f 0a 29 7b 0a 20 20 4b 65 79 49 6e 66 6f 20  */.){.  KeyInfo 
4450: 2a 70 4b 65 79 49 6e 66 6f 20 3d 20 70 54 68 72  *pKeyInfo = pThr
4460: 65 61 64 2d 3e 70 4b 65 79 49 6e 66 6f 3b 0a 20  ead->pKeyInfo;. 
4470: 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20   UnpackedRecord 
4480: 2a 72 32 20 3d 20 70 54 68 72 65 61 64 2d 3e 70  *r2 = pThread->p
4490: 55 6e 70 61 63 6b 65 64 3b 0a 20 20 69 6e 74 20  Unpacked;.  int 
44a0: 69 3b 0a 0a 20 20 69 66 28 20 70 4b 65 79 32 20  i;..  if( pKey2 
44b0: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 56 64  ){.    sqlite3Vd
44c0: 62 65 52 65 63 6f 72 64 55 6e 70 61 63 6b 28 70  beRecordUnpack(p
44d0: 4b 65 79 49 6e 66 6f 2c 20 6e 4b 65 79 32 2c 20  KeyInfo, nKey2, 
44e0: 70 4b 65 79 32 2c 20 72 32 29 3b 0a 20 20 7d 0a  pKey2, r2);.  }.
44f0: 0a 20 20 69 66 28 20 6e 49 67 6e 6f 72 65 20 29  .  if( nIgnore )
4500: 7b 0a 20 20 20 20 72 32 2d 3e 6e 46 69 65 6c 64  {.    r2->nField
4510: 20 3d 20 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69   = pKeyInfo->nFi
4520: 65 6c 64 20 2d 20 6e 49 67 6e 6f 72 65 3b 0a 20  eld - nIgnore;. 
4530: 20 20 20 61 73 73 65 72 74 28 20 72 32 2d 3e 6e     assert( r2->n
4540: 46 69 65 6c 64 3e 30 20 29 3b 0a 20 20 20 20 66  Field>0 );.    f
4550: 6f 72 28 69 3d 30 3b 20 69 3c 72 32 2d 3e 6e 46  or(i=0; i<r2->nF
4560: 69 65 6c 64 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  ield; i++){.    
4570: 20 20 69 66 28 20 72 32 2d 3e 61 4d 65 6d 5b 69    if( r2->aMem[i
4580: 5d 2e 66 6c 61 67 73 20 26 20 4d 45 4d 5f 4e 75  ].flags & MEM_Nu
4590: 6c 6c 20 29 7b 0a 20 20 20 20 20 20 20 20 2a 70  ll ){.        *p
45a0: 52 65 73 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20  Res = -1;.      
45b0: 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20 20 20    return;.      
45c0: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65  }.    }.    asse
45d0: 72 74 28 20 72 32 2d 3e 64 65 66 61 75 6c 74 5f  rt( r2->default_
45e0: 72 63 3d 3d 30 20 29 3b 0a 20 20 7d 0a 0a 20 20  rc==0 );.  }..  
45f0: 2a 70 52 65 73 20 3d 20 73 71 6c 69 74 65 33 56  *pRes = sqlite3V
4600: 64 62 65 52 65 63 6f 72 64 43 6f 6d 70 61 72 65  dbeRecordCompare
4610: 28 6e 4b 65 79 31 2c 20 70 4b 65 79 31 2c 20 72  (nKey1, pKey1, r
4620: 32 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  2, 0);.}../*.** 
4630: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
4640: 20 63 61 6c 6c 65 64 20 74 6f 20 63 6f 6d 70 61   called to compa
4650: 72 65 20 74 77 6f 20 69 74 65 72 61 74 6f 72 20  re two iterator 
4660: 6b 65 79 73 20 77 68 65 6e 20 6d 65 72 67 69 6e  keys when mergin
4670: 67 20 0a 2a 2a 20 6d 75 6c 74 69 70 6c 65 20 62  g .** multiple b
4680: 2d 74 72 65 65 20 73 65 67 6d 65 6e 74 73 2e 20  -tree segments. 
4690: 50 61 72 61 6d 65 74 65 72 20 69 4f 75 74 20 69  Parameter iOut i
46a0: 73 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20 74  s the index of t
46b0: 68 65 20 61 54 72 65 65 5b 5d 20 0a 2a 2a 20 76  he aTree[] .** v
46c0: 61 6c 75 65 20 74 6f 20 72 65 63 61 6c 63 75 6c  alue to recalcul
46d0: 61 74 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ate..*/.static i
46e0: 6e 74 20 76 64 62 65 53 6f 72 74 65 72 44 6f 43  nt vdbeSorterDoC
46f0: 6f 6d 70 61 72 65 28 0a 20 20 53 6f 72 74 65 72  ompare(.  Sorter
4700: 54 68 72 65 61 64 20 2a 70 54 68 72 65 61 64 2c  Thread *pThread,
4710: 20 0a 20 20 53 6f 72 74 65 72 4d 65 72 67 65 72   .  SorterMerger
4720: 20 2a 70 4d 65 72 67 65 72 2c 20 0a 20 20 69 6e   *pMerger, .  in
4730: 74 20 69 4f 75 74 0a 29 7b 0a 20 20 69 6e 74 20  t iOut.){.  int 
4740: 69 31 3b 0a 20 20 69 6e 74 20 69 32 3b 0a 20 20  i1;.  int i2;.  
4750: 69 6e 74 20 69 52 65 73 3b 0a 20 20 56 64 62 65  int iRes;.  Vdbe
4760: 53 6f 72 74 65 72 49 74 65 72 20 2a 70 31 3b 0a  SorterIter *p1;.
4770: 20 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72    VdbeSorterIter
4780: 20 2a 70 32 3b 0a 0a 20 20 61 73 73 65 72 74 28   *p2;..  assert(
4790: 20 69 4f 75 74 3c 70 4d 65 72 67 65 72 2d 3e 6e   iOut<pMerger->n
47a0: 54 72 65 65 20 26 26 20 69 4f 75 74 3e 30 20 29  Tree && iOut>0 )
47b0: 3b 0a 0a 20 20 69 66 28 20 69 4f 75 74 3e 3d 28  ;..  if( iOut>=(
47c0: 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65 2f 32  pMerger->nTree/2
47d0: 29 20 29 7b 0a 20 20 20 20 69 31 20 3d 20 28 69  ) ){.    i1 = (i
47e0: 4f 75 74 20 2d 20 70 4d 65 72 67 65 72 2d 3e 6e  Out - pMerger->n
47f0: 54 72 65 65 2f 32 29 20 2a 20 32 3b 0a 20 20 20  Tree/2) * 2;.   
4800: 20 69 32 20 3d 20 69 31 20 2b 20 31 3b 0a 20 20   i2 = i1 + 1;.  
4810: 7d 65 6c 73 65 7b 0a 20 20 20 20 69 31 20 3d 20  }else{.    i1 = 
4820: 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69  pMerger->aTree[i
4830: 4f 75 74 2a 32 5d 3b 0a 20 20 20 20 69 32 20 3d  Out*2];.    i2 =
4840: 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b   pMerger->aTree[
4850: 69 4f 75 74 2a 32 2b 31 5d 3b 0a 20 20 7d 0a 0a  iOut*2+1];.  }..
4860: 20 20 70 31 20 3d 20 26 70 4d 65 72 67 65 72 2d    p1 = &pMerger-
4870: 3e 61 49 74 65 72 5b 69 31 5d 3b 0a 20 20 70 32  >aIter[i1];.  p2
4880: 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49 74   = &pMerger->aIt
4890: 65 72 5b 69 32 5d 3b 0a 0a 20 20 69 66 28 20 70  er[i2];..  if( p
48a0: 31 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20  1->pFile==0 ){. 
48b0: 20 20 20 69 52 65 73 20 3d 20 69 32 3b 0a 20 20     iRes = i2;.  
48c0: 7d 65 6c 73 65 20 69 66 28 20 70 32 2d 3e 70 46  }else if( p2->pF
48d0: 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69 52  ile==0 ){.    iR
48e0: 65 73 20 3d 20 69 31 3b 0a 20 20 7d 65 6c 73 65  es = i1;.  }else
48f0: 7b 0a 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 20  {.    int res;. 
4900: 20 20 20 61 73 73 65 72 74 28 20 70 54 68 72 65     assert( pThre
4910: 61 64 2d 3e 70 55 6e 70 61 63 6b 65 64 21 3d 30  ad->pUnpacked!=0
4920: 20 29 3b 20 20 2f 2a 20 61 6c 6c 6f 63 61 74 65   );  /* allocate
4930: 64 20 69 6e 20 76 64 62 65 53 6f 72 74 65 72 4d  d in vdbeSorterM
4940: 65 72 67 65 28 29 20 2a 2f 0a 20 20 20 20 76 64  erge() */.    vd
4950: 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28  beSorterCompare(
4960: 0a 20 20 20 20 20 20 20 20 70 54 68 72 65 61 64  .        pThread
4970: 2c 20 30 2c 20 70 31 2d 3e 61 4b 65 79 2c 20 70  , 0, p1->aKey, p
4980: 31 2d 3e 6e 4b 65 79 2c 20 70 32 2d 3e 61 4b 65  1->nKey, p2->aKe
4990: 79 2c 20 70 32 2d 3e 6e 4b 65 79 2c 20 26 72 65  y, p2->nKey, &re
49a0: 73 0a 20 20 20 20 29 3b 0a 20 20 20 20 69 66 28  s.    );.    if(
49b0: 20 72 65 73 3c 3d 30 20 29 7b 0a 20 20 20 20 20   res<=0 ){.     
49c0: 20 69 52 65 73 20 3d 20 69 31 3b 0a 20 20 20 20   iRes = i1;.    
49d0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 52 65  }else{.      iRe
49e0: 73 20 3d 20 69 32 3b 0a 20 20 20 20 7d 0a 20 20  s = i2;.    }.  
49f0: 7d 0a 0a 20 20 70 4d 65 72 67 65 72 2d 3e 61 54  }..  pMerger->aT
4a00: 72 65 65 5b 69 4f 75 74 5d 20 3d 20 69 52 65 73  ree[iOut] = iRes
4a10: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
4a20: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  E_OK;.}../*.** I
4a30: 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 74 65  nitialize the te
4a40: 6d 70 6f 72 61 72 79 20 69 6e 64 65 78 20 63 75  mporary index cu
4a50: 72 73 6f 72 20 6a 75 73 74 20 6f 70 65 6e 65 64  rsor just opened
4a60: 20 61 73 20 61 20 73 6f 72 74 65 72 20 63 75 72   as a sorter cur
4a70: 73 6f 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  sor..*/.int sqli
4a80: 74 65 33 56 64 62 65 53 6f 72 74 65 72 49 6e 69  te3VdbeSorterIni
4a90: 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 56  t(sqlite3 *db, V
4aa0: 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 29  dbeCursor *pCsr)
4ab0: 7b 0a 20 20 69 6e 74 20 70 67 73 7a 3b 20 20 20  {.  int pgsz;   
4ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4ad0: 20 20 20 20 2f 2a 20 50 61 67 65 20 73 69 7a 65      /* Page size
4ae0: 20 6f 66 20 6d 61 69 6e 20 64 61 74 61 62 61 73   of main databas
4af0: 65 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20  e */.  int i;   
4b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4b10: 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74         /* Used t
4b20: 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67  o iterate throug
4b30: 68 20 61 54 68 72 65 61 64 5b 5d 20 2a 2f 0a 20  h aThread[] */. 
4b40: 20 69 6e 74 20 6d 78 43 61 63 68 65 3b 20 20 20   int mxCache;   
4b50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4b60: 20 2f 2a 20 43 61 63 68 65 20 73 69 7a 65 20 2a   /* Cache size *
4b70: 2f 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a  /.  VdbeSorter *
4b80: 70 53 6f 72 74 65 72 3b 20 20 20 20 20 20 20 20  pSorter;        
4b90: 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77 20 73      /* The new s
4ba0: 6f 72 74 65 72 20 2a 2f 0a 20 20 4b 65 79 49 6e  orter */.  KeyIn
4bb0: 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 3b 20 20 20  fo *pKeyInfo;   
4bc0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
4bd0: 70 79 20 6f 66 20 70 43 73 72 2d 3e 70 4b 65 79  py of pCsr->pKey
4be0: 49 6e 66 6f 20 77 69 74 68 20 64 62 3d 3d 30 20  Info with db==0 
4bf0: 2a 2f 0a 20 20 69 6e 74 20 73 7a 4b 65 79 49 6e  */.  int szKeyIn
4c00: 66 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  fo;             
4c10: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
4c20: 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 20 69  pCsr->pKeyInfo i
4c30: 6e 20 62 79 74 65 73 20 2a 2f 0a 0a 20 20 61 73  n bytes */..  as
4c40: 73 65 72 74 28 20 70 43 73 72 2d 3e 70 4b 65 79  sert( pCsr->pKey
4c50: 49 6e 66 6f 20 26 26 20 70 43 73 72 2d 3e 70 42  Info && pCsr->pB
4c60: 74 3d 3d 30 20 29 3b 0a 20 20 73 7a 4b 65 79 49  t==0 );.  szKeyI
4c70: 6e 66 6f 20 3d 20 73 69 7a 65 6f 66 28 4b 65 79  nfo = sizeof(Key
4c80: 49 6e 66 6f 29 20 2b 20 28 70 43 73 72 2d 3e 70  Info) + (pCsr->p
4c90: 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64 2d  KeyInfo->nField-
4ca0: 31 29 2a 73 69 7a 65 6f 66 28 43 6f 6c 6c 53 65  1)*sizeof(CollSe
4cb0: 71 2a 29 3b 0a 20 20 70 53 6f 72 74 65 72 20 3d  q*);.  pSorter =
4cc0: 20 28 56 64 62 65 53 6f 72 74 65 72 2a 29 73 71   (VdbeSorter*)sq
4cd0: 6c 69 74 65 33 44 62 4d 61 6c 6c 6f 63 5a 65 72  lite3DbMallocZer
4ce0: 6f 28 64 62 2c 20 73 69 7a 65 6f 66 28 56 64 62  o(db, sizeof(Vdb
4cf0: 65 53 6f 72 74 65 72 29 2b 73 7a 4b 65 79 49 6e  eSorter)+szKeyIn
4d00: 66 6f 29 3b 0a 20 20 70 43 73 72 2d 3e 70 53 6f  fo);.  pCsr->pSo
4d10: 72 74 65 72 20 3d 20 70 53 6f 72 74 65 72 3b 0a  rter = pSorter;.
4d20: 20 20 69 66 28 20 70 53 6f 72 74 65 72 3d 3d 30    if( pSorter==0
4d30: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
4d40: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d  QLITE_NOMEM;.  }
4d50: 0a 20 20 70 4b 65 79 49 6e 66 6f 20 3d 20 28 4b  .  pKeyInfo = (K
4d60: 65 79 49 6e 66 6f 2a 29 26 70 53 6f 72 74 65 72  eyInfo*)&pSorter
4d70: 5b 31 5d 3b 0a 20 20 6d 65 6d 63 70 79 28 70 4b  [1];.  memcpy(pK
4d80: 65 79 49 6e 66 6f 2c 20 70 43 73 72 2d 3e 70 4b  eyInfo, pCsr->pK
4d90: 65 79 49 6e 66 6f 2c 20 73 7a 4b 65 79 49 6e 66  eyInfo, szKeyInf
4da0: 6f 29 3b 0a 20 20 70 4b 65 79 49 6e 66 6f 2d 3e  o);.  pKeyInfo->
4db0: 64 62 20 3d 20 30 3b 0a 20 20 70 67 73 7a 20 3d  db = 0;.  pgsz =
4dc0: 20 73 71 6c 69 74 65 33 42 74 72 65 65 47 65 74   sqlite3BtreeGet
4dd0: 50 61 67 65 53 69 7a 65 28 64 62 2d 3e 61 44 62  PageSize(db->aDb
4de0: 5b 30 5d 2e 70 42 74 29 3b 0a 0a 20 20 66 6f 72  [0].pBt);..  for
4df0: 28 69 3d 30 3b 20 69 3c 53 51 4c 49 54 45 5f 4d  (i=0; i<SQLITE_M
4e00: 41 58 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44  AX_SORTER_THREAD
4e10: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 53 6f 72 74  ; i++){.    Sort
4e20: 65 72 54 68 72 65 61 64 20 2a 70 54 68 72 65 61  erThread *pThrea
4e30: 64 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 54  d = &pSorter->aT
4e40: 68 72 65 61 64 5b 69 5d 3b 0a 20 20 20 20 70 54  hread[i];.    pT
4e50: 68 72 65 61 64 2d 3e 70 4b 65 79 49 6e 66 6f 20  hread->pKeyInfo 
4e60: 3d 20 70 4b 65 79 49 6e 66 6f 3b 0a 20 20 20 20  = pKeyInfo;.    
4e70: 70 54 68 72 65 61 64 2d 3e 70 56 66 73 20 3d 20  pThread->pVfs = 
4e80: 64 62 2d 3e 70 56 66 73 3b 0a 20 20 20 20 70 54  db->pVfs;.    pT
4e90: 68 72 65 61 64 2d 3e 70 67 73 7a 20 3d 20 70 67  hread->pgsz = pg
4ea0: 73 7a 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 21  sz;.  }..  if( !
4eb0: 73 71 6c 69 74 65 33 54 65 6d 70 49 6e 4d 65 6d  sqlite3TempInMem
4ec0: 6f 72 79 28 64 62 29 20 29 7b 0a 20 20 20 20 70  ory(db) ){.    p
4ed0: 53 6f 72 74 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a  Sorter->mnPmaSiz
4ee0: 65 20 3d 20 53 4f 52 54 45 52 5f 4d 49 4e 5f 57  e = SORTER_MIN_W
4ef0: 4f 52 4b 49 4e 47 20 2a 20 70 67 73 7a 3b 0a 20  ORKING * pgsz;. 
4f00: 20 20 20 6d 78 43 61 63 68 65 20 3d 20 64 62 2d     mxCache = db-
4f10: 3e 61 44 62 5b 30 5d 2e 70 53 63 68 65 6d 61 2d  >aDb[0].pSchema-
4f20: 3e 63 61 63 68 65 5f 73 69 7a 65 3b 0a 20 20 20  >cache_size;.   
4f30: 20 69 66 28 20 6d 78 43 61 63 68 65 3c 53 4f 52   if( mxCache<SOR
4f40: 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20  TER_MIN_WORKING 
4f50: 29 20 6d 78 43 61 63 68 65 20 3d 20 53 4f 52 54  ) mxCache = SORT
4f60: 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 3b 0a  ER_MIN_WORKING;.
4f70: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50      pSorter->mxP
4f80: 6d 61 53 69 7a 65 20 3d 20 6d 78 43 61 63 68 65  maSize = mxCache
4f90: 20 2a 20 70 67 73 7a 3b 0a 20 20 7d 0a 0a 20 20   * pgsz;.  }..  
4fa0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
4fb0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20  ;.}../*.** Free 
4fc0: 74 68 65 20 6c 69 73 74 20 6f 66 20 73 6f 72 74  the list of sort
4fd0: 65 64 20 72 65 63 6f 72 64 73 20 73 74 61 72 74  ed records start
4fe0: 69 6e 67 20 61 74 20 70 52 65 63 6f 72 64 2e 0a  ing at pRecord..
4ff0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76  */.static void v
5000: 64 62 65 53 6f 72 74 65 72 52 65 63 6f 72 64 46  dbeSorterRecordF
5010: 72 65 65 28 73 71 6c 69 74 65 33 20 2a 64 62 2c  ree(sqlite3 *db,
5020: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
5030: 52 65 63 6f 72 64 29 7b 0a 20 20 53 6f 72 74 65  Record){.  Sorte
5040: 72 52 65 63 6f 72 64 20 2a 70 3b 0a 20 20 53 6f  rRecord *p;.  So
5050: 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65 78  rterRecord *pNex
5060: 74 3b 0a 20 20 66 6f 72 28 70 3d 70 52 65 63 6f  t;.  for(p=pReco
5070: 72 64 3b 20 70 3b 20 70 3d 70 4e 65 78 74 29 7b  rd; p; p=pNext){
5080: 0a 20 20 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e  .    pNext = p->
5090: 70 4e 65 78 74 3b 0a 20 20 20 20 73 71 6c 69 74  pNext;.    sqlit
50a0: 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 29 3b  e3DbFree(db, p);
50b0: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72  .  }.}../*.** Fr
50c0: 65 65 20 61 6c 6c 20 72 65 73 6f 75 72 63 65 73  ee all resources
50d0: 20 6f 77 6e 65 64 20 62 79 20 74 68 65 20 6f 62   owned by the ob
50e0: 6a 65 63 74 20 69 6e 64 69 63 61 74 65 64 20 62  ject indicated b
50f0: 79 20 61 72 67 75 6d 65 6e 74 20 70 54 68 72 65  y argument pThre
5100: 61 64 2e 20 41 6c 6c 20 0a 2a 2a 20 66 69 65 6c  ad. All .** fiel
5110: 64 73 20 6f 66 20 2a 70 54 68 72 65 61 64 20 61  ds of *pThread a
5120: 72 65 20 7a 65 72 6f 65 64 20 62 65 66 6f 72 65  re zeroed before
5130: 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73   returning..*/.s
5140: 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 53  tatic void vdbeS
5150: 6f 72 74 65 72 54 68 72 65 61 64 43 6c 65 61 6e  orterThreadClean
5160: 75 70 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  up(sqlite3 *db, 
5170: 53 6f 72 74 65 72 54 68 72 65 61 64 20 2a 70 54  SorterThread *pT
5180: 68 72 65 61 64 29 7b 0a 20 20 73 71 6c 69 74 65  hread){.  sqlite
5190: 33 44 62 46 72 65 65 28 64 62 2c 20 70 54 68 72  3DbFree(db, pThr
51a0: 65 61 64 2d 3e 70 55 6e 70 61 63 6b 65 64 29 3b  ead->pUnpacked);
51b0: 0a 20 20 70 54 68 72 65 61 64 2d 3e 70 55 6e 70  .  pThread->pUnp
51c0: 61 63 6b 65 64 20 3d 20 30 3b 0a 20 20 76 64 62  acked = 0;.  vdb
51d0: 65 53 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65  eSorterRecordFre
51e0: 65 28 30 2c 20 70 54 68 72 65 61 64 2d 3e 70 4c  e(0, pThread->pL
51f0: 69 73 74 29 3b 0a 20 20 70 54 68 72 65 61 64 2d  ist);.  pThread-
5200: 3e 70 4c 69 73 74 20 3d 20 30 3b 0a 20 20 69 66  >pList = 0;.  if
5210: 28 20 70 54 68 72 65 61 64 2d 3e 70 54 65 6d 70  ( pThread->pTemp
5220: 31 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  1 ){.    sqlite3
5230: 4f 73 43 6c 6f 73 65 46 72 65 65 28 70 54 68 72  OsCloseFree(pThr
5240: 65 61 64 2d 3e 70 54 65 6d 70 31 29 3b 0a 20 20  ead->pTemp1);.  
5250: 20 20 70 54 68 72 65 61 64 2d 3e 70 54 65 6d 70    pThread->pTemp
5260: 31 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  1 = 0;.  }.}../*
5270: 0a 2a 2a 20 4a 6f 69 6e 20 61 6c 6c 20 74 68 72  .** Join all thr
5280: 65 61 64 73 2e 20 20 0a 2a 2f 0a 73 74 61 74 69  eads.  .*/.stati
5290: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72  c int vdbeSorter
52a0: 4a 6f 69 6e 41 6c 6c 28 56 64 62 65 53 6f 72 74  JoinAll(VdbeSort
52b0: 65 72 20 2a 70 53 6f 72 74 65 72 2c 20 69 6e 74  er *pSorter, int
52c0: 20 72 63 69 6e 29 7b 0a 20 20 69 6e 74 20 72 63   rcin){.  int rc
52d0: 20 3d 20 72 63 69 6e 3b 0a 20 20 69 6e 74 20 69   = rcin;.  int i
52e0: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 53  ;.  for(i=0; i<S
52f0: 51 4c 49 54 45 5f 4d 41 58 5f 53 4f 52 54 45 52  QLITE_MAX_SORTER
5300: 5f 54 48 52 45 41 44 3b 20 69 2b 2b 29 7b 0a 20  _THREAD; i++){. 
5310: 20 20 20 53 6f 72 74 65 72 54 68 72 65 61 64 20     SorterThread 
5320: 2a 70 54 68 72 65 61 64 20 3d 20 26 70 53 6f 72  *pThread = &pSor
5330: 74 65 72 2d 3e 61 54 68 72 65 61 64 5b 69 5d 3b  ter->aThread[i];
5340: 0a 20 20 20 20 69 66 28 20 70 54 68 72 65 61 64  .    if( pThread
5350: 2d 3e 70 54 68 72 65 61 64 20 29 7b 0a 20 20 20  ->pThread ){.   
5360: 20 20 20 76 6f 69 64 20 2a 70 52 65 74 3b 0a 20     void *pRet;. 
5370: 20 20 20 20 20 69 6e 74 20 72 63 32 20 3d 20 73       int rc2 = s
5380: 71 6c 69 74 65 33 54 68 72 65 61 64 4a 6f 69 6e  qlite3ThreadJoin
5390: 28 70 54 68 72 65 61 64 2d 3e 70 54 68 72 65 61  (pThread->pThrea
53a0: 64 2c 20 26 70 52 65 74 29 3b 0a 20 20 20 20 20  d, &pRet);.     
53b0: 20 70 54 68 72 65 61 64 2d 3e 70 54 68 72 65 61   pThread->pThrea
53c0: 64 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 54 68  d = 0;.      pTh
53d0: 72 65 61 64 2d 3e 62 44 6f 6e 65 20 3d 20 30 3b  read->bDone = 0;
53e0: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
53f0: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20  QLITE_OK ) rc = 
5400: 72 63 32 3b 0a 20 20 20 20 20 20 69 66 28 20 72  rc2;.      if( r
5410: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c==SQLITE_OK ) r
5420: 63 20 3d 20 53 51 4c 49 54 45 5f 50 54 52 5f 54  c = SQLITE_PTR_T
5430: 4f 5f 49 4e 54 28 70 52 65 74 29 3b 0a 20 20 20  O_INT(pRet);.   
5440: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
5450: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c  rc;.}../*.** All
5460: 6f 63 61 74 65 20 61 20 6e 65 77 20 53 6f 72 74  ocate a new Sort
5470: 65 72 4d 65 72 67 65 72 20 6f 62 6a 65 63 74 20  erMerger object 
5480: 77 69 74 68 20 73 70 61 63 65 20 66 6f 72 20 6e  with space for n
5490: 49 74 65 72 20 69 74 65 72 61 74 6f 72 73 2e 0a  Iter iterators..
54a0: 2a 2f 0a 73 74 61 74 69 63 20 53 6f 72 74 65 72  */.static Sorter
54b0: 4d 65 72 67 65 72 20 2a 76 64 62 65 53 6f 72 74  Merger *vdbeSort
54c0: 65 72 4d 65 72 67 65 72 4e 65 77 28 69 6e 74 20  erMergerNew(int 
54d0: 6e 49 74 65 72 29 7b 0a 20 20 69 6e 74 20 4e 20  nIter){.  int N 
54e0: 3d 20 32 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 2;            
54f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6d 61            /* Sma
5500: 6c 6c 65 73 74 20 70 6f 77 65 72 20 6f 66 20 74  llest power of t
5510: 77 6f 20 3e 3d 20 6e 49 74 65 72 20 2a 2f 0a 20  wo >= nIter */. 
5520: 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20   int nByte;     
5530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5540: 20 2f 2a 20 54 6f 74 61 6c 20 62 79 74 65 73 20   /* Total bytes 
5550: 6f 66 20 73 70 61 63 65 20 74 6f 20 61 6c 6c 6f  of space to allo
5560: 63 61 74 65 20 2a 2f 0a 20 20 53 6f 72 74 65 72  cate */.  Sorter
5570: 4d 65 72 67 65 72 20 2a 70 4e 65 77 3b 20 20 20  Merger *pNew;   
5580: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
5590: 6e 74 65 72 20 74 6f 20 61 6c 6c 6f 63 61 74 65  nter to allocate
55a0: 64 20 6f 62 6a 65 63 74 20 74 6f 20 72 65 74 75  d object to retu
55b0: 72 6e 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28  rn */..  assert(
55c0: 20 6e 49 74 65 72 3c 3d 53 4f 52 54 45 52 5f 4d   nIter<=SORTER_M
55d0: 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20 29  AX_MERGE_COUNT )
55e0: 3b 0a 20 20 77 68 69 6c 65 28 20 4e 3c 6e 49 74  ;.  while( N<nIt
55f0: 65 72 20 29 20 4e 20 2b 3d 20 4e 3b 0a 20 20 6e  er ) N += N;.  n
5600: 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 53 6f  Byte = sizeof(So
5610: 72 74 65 72 4d 65 72 67 65 72 29 20 2b 20 4e 20  rterMerger) + N 
5620: 2a 20 28 73 69 7a 65 6f 66 28 69 6e 74 29 20 2b  * (sizeof(int) +
5630: 20 73 69 7a 65 6f 66 28 56 64 62 65 53 6f 72 74   sizeof(VdbeSort
5640: 65 72 49 74 65 72 29 29 3b 0a 0a 20 20 70 4e 65  erIter));..  pNe
5650: 77 20 3d 20 28 53 6f 72 74 65 72 4d 65 72 67 65  w = (SorterMerge
5660: 72 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  r*)sqlite3Malloc
5670: 5a 65 72 6f 28 6e 42 79 74 65 29 3b 0a 20 20 69  Zero(nByte);.  i
5680: 66 28 20 70 4e 65 77 20 29 7b 0a 20 20 20 20 70  f( pNew ){.    p
5690: 4e 65 77 2d 3e 6e 54 72 65 65 20 3d 20 4e 3b 0a  New->nTree = N;.
56a0: 20 20 20 20 70 4e 65 77 2d 3e 61 49 74 65 72 20      pNew->aIter 
56b0: 3d 20 28 56 64 62 65 53 6f 72 74 65 72 49 74 65  = (VdbeSorterIte
56c0: 72 2a 29 26 70 4e 65 77 5b 31 5d 3b 0a 20 20 20  r*)&pNew[1];.   
56d0: 20 70 4e 65 77 2d 3e 61 54 72 65 65 20 3d 20 28   pNew->aTree = (
56e0: 69 6e 74 2a 29 26 70 4e 65 77 2d 3e 61 49 74 65  int*)&pNew->aIte
56f0: 72 5b 4e 5d 3b 0a 20 20 7d 0a 20 20 72 65 74 75  r[N];.  }.  retu
5700: 72 6e 20 70 4e 65 77 3b 0a 7d 0a 0a 2f 2a 0a 2a  rn pNew;.}../*.*
5710: 2a 20 52 65 73 65 74 20 61 20 6d 65 72 67 65 72  * Reset a merger
5720: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
5730: 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65 72  vdbeSorterMerger
5740: 52 65 73 65 74 28 53 6f 72 74 65 72 4d 65 72 67  Reset(SorterMerg
5750: 65 72 20 2a 70 4d 65 72 67 65 72 29 7b 0a 20 20  er *pMerger){.  
5760: 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 70 4d 65  int i;.  if( pMe
5770: 72 67 65 72 20 29 7b 0a 20 20 20 20 66 6f 72 28  rger ){.    for(
5780: 69 3d 30 3b 20 69 3c 70 4d 65 72 67 65 72 2d 3e  i=0; i<pMerger->
5790: 6e 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20 20 20  nTree; i++){.   
57a0: 20 20 20 76 64 62 65 53 6f 72 74 65 72 49 74 65     vdbeSorterIte
57b0: 72 5a 65 72 6f 28 26 70 4d 65 72 67 65 72 2d 3e  rZero(&pMerger->
57c0: 61 49 74 65 72 5b 69 5d 29 3b 0a 20 20 20 20 7d  aIter[i]);.    }
57d0: 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 46  .  }.}.../*.** F
57e0: 72 65 65 20 74 68 65 20 53 6f 72 74 65 72 4d 65  ree the SorterMe
57f0: 72 67 65 72 20 6f 62 6a 65 63 74 20 70 61 73 73  rger object pass
5800: 65 64 20 61 73 20 74 68 65 20 6f 6e 6c 79 20 61  ed as the only a
5810: 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74  rgument..*/.stat
5820: 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74  ic void vdbeSort
5830: 65 72 4d 65 72 67 65 72 46 72 65 65 28 53 6f 72  erMergerFree(Sor
5840: 74 65 72 4d 65 72 67 65 72 20 2a 70 4d 65 72 67  terMerger *pMerg
5850: 65 72 29 7b 0a 20 20 76 64 62 65 53 6f 72 74 65  er){.  vdbeSorte
5860: 72 4d 65 72 67 65 72 52 65 73 65 74 28 70 4d 65  rMergerReset(pMe
5870: 72 67 65 72 29 3b 0a 20 20 73 71 6c 69 74 65 33  rger);.  sqlite3
5880: 5f 66 72 65 65 28 70 4d 65 72 67 65 72 29 3b 0a  _free(pMerger);.
5890: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65 74 20 61  }../*.** Reset a
58a0: 20 73 6f 72 74 69 6e 67 20 63 75 72 73 6f 72 20   sorting cursor 
58b0: 62 61 63 6b 20 74 6f 20 69 74 73 20 6f 72 69 67  back to its orig
58c0: 69 6e 61 6c 20 65 6d 70 74 79 20 73 74 61 74 65  inal empty state
58d0: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
58e0: 33 56 64 62 65 53 6f 72 74 65 72 52 65 73 65 74  3VdbeSorterReset
58f0: 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 56 64  (sqlite3 *db, Vd
5900: 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
5910: 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 76  r){.  int i;.  v
5920: 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e 41 6c 6c  dbeSorterJoinAll
5930: 28 70 53 6f 72 74 65 72 2c 20 53 51 4c 49 54 45  (pSorter, SQLITE
5940: 5f 4f 4b 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  _OK);.  for(i=0;
5950: 20 69 3c 53 51 4c 49 54 45 5f 4d 41 58 5f 53 4f   i<SQLITE_MAX_SO
5960: 52 54 45 52 5f 54 48 52 45 41 44 3b 20 69 2b 2b  RTER_THREAD; i++
5970: 29 7b 0a 20 20 20 20 53 6f 72 74 65 72 54 68 72  ){.    SorterThr
5980: 65 61 64 20 2a 70 54 68 72 65 61 64 20 3d 20 26  ead *pThread = &
5990: 70 53 6f 72 74 65 72 2d 3e 61 54 68 72 65 61 64  pSorter->aThread
59a0: 5b 69 5d 3b 0a 20 20 20 20 76 64 62 65 53 6f 72  [i];.    vdbeSor
59b0: 74 65 72 54 68 72 65 61 64 43 6c 65 61 6e 75 70  terThreadCleanup
59c0: 28 64 62 2c 20 70 54 68 72 65 61 64 29 3b 0a 20  (db, pThread);. 
59d0: 20 7d 0a 20 20 76 64 62 65 53 6f 72 74 65 72 52   }.  vdbeSorterR
59e0: 65 63 6f 72 64 46 72 65 65 28 30 2c 20 70 53 6f  ecordFree(0, pSo
59f0: 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 29 3b 0a  rter->pRecord);.
5a00: 20 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67    vdbeSorterMerg
5a10: 65 72 52 65 73 65 74 28 70 53 6f 72 74 65 72 2d  erReset(pSorter-
5a20: 3e 70 4d 65 72 67 65 72 29 3b 0a 20 20 70 53 6f  >pMerger);.  pSo
5a30: 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 3d 20  rter->pRecord = 
5a40: 30 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6e 49  0;.  pSorter->nI
5a50: 6e 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a 20 20 70  nMemory = 0;.  p
5a60: 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41 20  Sorter->bUsePMA 
5a70: 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72  = 0;.}../*.** Fr
5a80: 65 65 20 61 6e 79 20 63 75 72 73 6f 72 20 63 6f  ee any cursor co
5a90: 6d 70 6f 6e 65 6e 74 73 20 61 6c 6c 6f 63 61 74  mponents allocat
5aa0: 65 64 20 62 79 20 73 71 6c 69 74 65 33 56 64 62  ed by sqlite3Vdb
5ab0: 65 53 6f 72 74 65 72 58 58 58 20 72 6f 75 74 69  eSorterXXX routi
5ac0: 6e 65 73 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  nes..*/.void sql
5ad0: 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 43 6c  ite3VdbeSorterCl
5ae0: 6f 73 65 28 73 71 6c 69 74 65 33 20 2a 64 62 2c  ose(sqlite3 *db,
5af0: 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73   VdbeCursor *pCs
5b00: 72 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72  r){.  VdbeSorter
5b10: 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72   *pSorter = pCsr
5b20: 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69 66 28  ->pSorter;.  if(
5b30: 20 70 53 6f 72 74 65 72 20 29 7b 0a 20 20 20 20   pSorter ){.    
5b40: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
5b50: 72 52 65 73 65 74 28 64 62 2c 20 70 53 6f 72 74  rReset(db, pSort
5b60: 65 72 29 3b 0a 20 20 20 20 76 64 62 65 53 6f 72  er);.    vdbeSor
5b70: 74 65 72 4d 65 72 67 65 72 46 72 65 65 28 70 53  terMergerFree(pS
5b80: 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 29 3b  orter->pMerger);
5b90: 0a 20 20 20 20 73 71 6c 69 74 65 33 44 62 46 72  .    sqlite3DbFr
5ba0: 65 65 28 64 62 2c 20 70 53 6f 72 74 65 72 29 3b  ee(db, pSorter);
5bb0: 0a 20 20 20 20 70 43 73 72 2d 3e 70 53 6f 72 74  .    pCsr->pSort
5bc0: 65 72 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f  er = 0;.  }.}../
5bd0: 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 73 70  *.** Allocate sp
5be0: 61 63 65 20 66 6f 72 20 61 20 66 69 6c 65 2d 68  ace for a file-h
5bf0: 61 6e 64 6c 65 20 61 6e 64 20 6f 70 65 6e 20 61  andle and open a
5c00: 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 2e   temporary file.
5c10: 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 0a   If successful,.
5c20: 2a 2a 20 73 65 74 20 2a 70 70 46 69 6c 65 20 74  ** set *ppFile t
5c30: 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 6d  o point to the m
5c40: 61 6c 6c 6f 63 27 64 20 66 69 6c 65 2d 68 61 6e  alloc'd file-han
5c50: 64 6c 65 20 61 6e 64 20 72 65 74 75 72 6e 20 53  dle and return S
5c60: 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2a 20 4f 74 68  QLITE_OK..** Oth
5c70: 65 72 77 69 73 65 2c 20 73 65 74 20 2a 70 70 46  erwise, set *ppF
5c80: 69 6c 65 20 74 6f 20 30 20 61 6e 64 20 72 65 74  ile to 0 and ret
5c90: 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72  urn an SQLite er
5ca0: 72 6f 72 20 63 6f 64 65 2e 0a 2a 2f 0a 73 74 61  ror code..*/.sta
5cb0: 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74  tic int vdbeSort
5cc0: 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 73  erOpenTempFile(s
5cd0: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
5ce0: 2c 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a  , sqlite3_file *
5cf0: 2a 70 70 46 69 6c 65 29 7b 0a 20 20 69 6e 74 20  *ppFile){.  int 
5d00: 64 75 6d 6d 79 3b 0a 20 20 72 65 74 75 72 6e 20  dummy;.  return 
5d10: 73 71 6c 69 74 65 33 4f 73 4f 70 65 6e 4d 61 6c  sqlite3OsOpenMal
5d20: 6c 6f 63 28 70 56 66 73 2c 20 30 2c 20 70 70 46  loc(pVfs, 0, ppF
5d30: 69 6c 65 2c 0a 20 20 20 20 20 20 53 51 4c 49 54  ile,.      SQLIT
5d40: 45 5f 4f 50 45 4e 5f 54 45 4d 50 5f 4a 4f 55 52  E_OPEN_TEMP_JOUR
5d50: 4e 41 4c 20 7c 0a 20 20 20 20 20 20 53 51 4c 49  NAL |.      SQLI
5d60: 54 45 5f 4f 50 45 4e 5f 52 45 41 44 57 52 49 54  TE_OPEN_READWRIT
5d70: 45 20 20 20 20 7c 20 53 51 4c 49 54 45 5f 4f 50  E    | SQLITE_OP
5d80: 45 4e 5f 43 52 45 41 54 45 20 7c 0a 20 20 20 20  EN_CREATE |.    
5d90: 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 45 58    SQLITE_OPEN_EX
5da0: 43 4c 55 53 49 56 45 20 20 20 20 7c 20 53 51 4c  CLUSIVE    | SQL
5db0: 49 54 45 5f 4f 50 45 4e 5f 44 45 4c 45 54 45 4f  ITE_OPEN_DELETEO
5dc0: 4e 43 4c 4f 53 45 2c 20 26 64 75 6d 6d 79 0a 20  NCLOSE, &dummy. 
5dd0: 20 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 65 72   );.}../*.** Mer
5de0: 67 65 20 74 68 65 20 74 77 6f 20 73 6f 72 74 65  ge the two sorte
5df0: 64 20 6c 69 73 74 73 20 70 31 20 61 6e 64 20 70  d lists p1 and p
5e00: 32 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65 20  2 into a single 
5e10: 6c 69 73 74 2e 0a 2a 2a 20 53 65 74 20 2a 70 70  list..** Set *pp
5e20: 4f 75 74 20 74 6f 20 74 68 65 20 68 65 61 64 20  Out to the head 
5e30: 6f 66 20 74 68 65 20 6e 65 77 20 6c 69 73 74 2e  of the new list.
5e40: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
5e50: 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28  vdbeSorterMerge(
5e60: 0a 20 20 53 6f 72 74 65 72 54 68 72 65 61 64 20  .  SorterThread 
5e70: 2a 70 54 68 72 65 61 64 2c 20 20 20 20 20 20 20  *pThread,       
5e80: 20 20 20 2f 2a 20 43 61 6c 6c 69 6e 67 20 74 68     /* Calling th
5e90: 72 65 61 64 20 63 6f 6e 74 65 78 74 20 2a 2f 0a  read context */.
5ea0: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
5eb0: 70 31 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  p1,             
5ec0: 20 20 2f 2a 20 46 69 72 73 74 20 6c 69 73 74 20    /* First list 
5ed0: 74 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20 53 6f  to merge */.  So
5ee0: 72 74 65 72 52 65 63 6f 72 64 20 2a 70 32 2c 20  rterRecord *p2, 
5ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5f00: 20 53 65 63 6f 6e 64 20 6c 69 73 74 20 74 6f 20   Second list to 
5f10: 6d 65 72 67 65 20 2a 2f 0a 20 20 53 6f 72 74 65  merge */.  Sorte
5f20: 72 52 65 63 6f 72 64 20 2a 2a 70 70 4f 75 74 20  rRecord **ppOut 
5f30: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
5f40: 54 3a 20 48 65 61 64 20 6f 66 20 6d 65 72 67 65  T: Head of merge
5f50: 64 20 6c 69 73 74 20 2a 2f 0a 29 7b 0a 20 20 53  d list */.){.  S
5f60: 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 46 69  orterRecord *pFi
5f70: 6e 61 6c 20 3d 20 30 3b 0a 20 20 53 6f 72 74 65  nal = 0;.  Sorte
5f80: 72 52 65 63 6f 72 64 20 2a 2a 70 70 20 3d 20 26  rRecord **pp = &
5f90: 70 46 69 6e 61 6c 3b 0a 20 20 76 6f 69 64 20 2a  pFinal;.  void *
5fa0: 70 56 61 6c 32 20 3d 20 70 32 20 3f 20 70 32 2d  pVal2 = p2 ? p2-
5fb0: 3e 70 56 61 6c 20 3a 20 30 3b 0a 0a 20 20 77 68  >pVal : 0;..  wh
5fc0: 69 6c 65 28 20 70 31 20 26 26 20 70 32 20 29 7b  ile( p1 && p2 ){
5fd0: 0a 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 20 20  .    int res;.  
5fe0: 20 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70    vdbeSorterComp
5ff0: 61 72 65 28 70 54 68 72 65 61 64 2c 20 30 2c 20  are(pThread, 0, 
6000: 70 31 2d 3e 70 56 61 6c 2c 20 70 31 2d 3e 6e 56  p1->pVal, p1->nV
6010: 61 6c 2c 20 70 56 61 6c 32 2c 20 70 32 2d 3e 6e  al, pVal2, p2->n
6020: 56 61 6c 2c 20 26 72 65 73 29 3b 0a 20 20 20 20  Val, &res);.    
6030: 69 66 28 20 72 65 73 3c 3d 30 20 29 7b 0a 20 20  if( res<=0 ){.  
6040: 20 20 20 20 2a 70 70 20 3d 20 70 31 3b 0a 20 20      *pp = p1;.  
6050: 20 20 20 20 70 70 20 3d 20 26 70 31 2d 3e 70 4e      pp = &p1->pN
6060: 65 78 74 3b 0a 20 20 20 20 20 20 70 31 20 3d 20  ext;.      p1 = 
6070: 70 31 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20  p1->pNext;.     
6080: 20 70 56 61 6c 32 20 3d 20 30 3b 0a 20 20 20 20   pVal2 = 0;.    
6090: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2a 70 70  }else{.      *pp
60a0: 20 3d 20 70 32 3b 0a 20 20 20 20 20 20 20 70 70   = p2;.       pp
60b0: 20 3d 20 26 70 32 2d 3e 70 4e 65 78 74 3b 0a 20   = &p2->pNext;. 
60c0: 20 20 20 20 20 70 32 20 3d 20 70 32 2d 3e 70 4e       p2 = p2->pN
60d0: 65 78 74 3b 0a 20 20 20 20 20 20 69 66 28 20 70  ext;.      if( p
60e0: 32 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20  2==0 ) break;.  
60f0: 20 20 20 20 70 56 61 6c 32 20 3d 20 70 32 2d 3e      pVal2 = p2->
6100: 70 56 61 6c 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  pVal;.    }.  }.
6110: 20 20 2a 70 70 20 3d 20 70 31 20 3f 20 70 31 20    *pp = p1 ? p1 
6120: 3a 20 70 32 3b 0a 20 20 2a 70 70 4f 75 74 20 3d  : p2;.  *ppOut =
6130: 20 70 46 69 6e 61 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a   pFinal;.}../*.*
6140: 2a 20 53 6f 72 74 20 74 68 65 20 6c 69 6e 6b 65  * Sort the linke
6150: 64 20 6c 69 73 74 20 6f 66 20 72 65 63 6f 72 64  d list of record
6160: 73 20 68 65 61 64 65 64 20 61 74 20 70 54 68 72  s headed at pThr
6170: 65 61 64 2d 3e 70 4c 69 73 74 2e 20 52 65 74 75  ead->pList. Retu
6180: 72 6e 20 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b  rn .** SQLITE_OK
6190: 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   if successful, 
61a0: 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  or an SQLite err
61b0: 6f 72 20 63 6f 64 65 20 28 69 2e 65 2e 20 53 51  or code (i.e. SQ
61c0: 4c 49 54 45 5f 4e 4f 4d 45 4d 29 20 69 66 20 0a  LITE_NOMEM) if .
61d0: 2a 2a 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  ** an error occu
61e0: 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  rs..*/.static in
61f0: 74 20 76 64 62 65 53 6f 72 74 65 72 53 6f 72 74  t vdbeSorterSort
6200: 28 53 6f 72 74 65 72 54 68 72 65 61 64 20 2a 70  (SorterThread *p
6210: 54 68 72 65 61 64 29 7b 0a 20 20 69 6e 74 20 69  Thread){.  int i
6220: 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  ;.  SorterRecord
6230: 20 2a 2a 61 53 6c 6f 74 3b 0a 20 20 53 6f 72 74   **aSlot;.  Sort
6240: 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a 0a 20 20  erRecord *p;..  
6250: 61 53 6c 6f 74 20 3d 20 28 53 6f 72 74 65 72 52  aSlot = (SorterR
6260: 65 63 6f 72 64 20 2a 2a 29 73 71 6c 69 74 65 33  ecord **)sqlite3
6270: 4d 61 6c 6c 6f 63 5a 65 72 6f 28 36 34 20 2a 20  MallocZero(64 * 
6280: 73 69 7a 65 6f 66 28 53 6f 72 74 65 72 52 65 63  sizeof(SorterRec
6290: 6f 72 64 20 2a 29 29 3b 0a 20 20 69 66 28 20 21  ord *));.  if( !
62a0: 61 53 6c 6f 74 20 29 7b 0a 20 20 20 20 72 65 74  aSlot ){.    ret
62b0: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
62c0: 3b 0a 20 20 7d 0a 0a 20 20 70 20 3d 20 70 54 68  ;.  }..  p = pTh
62d0: 72 65 61 64 2d 3e 70 4c 69 73 74 3b 0a 20 20 77  read->pList;.  w
62e0: 68 69 6c 65 28 20 70 20 29 7b 0a 20 20 20 20 53  hile( p ){.    S
62f0: 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65  orterRecord *pNe
6300: 78 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20  xt = p->pNext;. 
6310: 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 30 3b     p->pNext = 0;
6320: 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 61 53  .    for(i=0; aS
6330: 6c 6f 74 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20  lot[i]; i++){.  
6340: 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 4d 65      vdbeSorterMe
6350: 72 67 65 28 70 54 68 72 65 61 64 2c 20 70 2c 20  rge(pThread, p, 
6360: 61 53 6c 6f 74 5b 69 5d 2c 20 26 70 29 3b 0a 20  aSlot[i], &p);. 
6370: 20 20 20 20 20 61 53 6c 6f 74 5b 69 5d 20 3d 20       aSlot[i] = 
6380: 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 53 6c  0;.    }.    aSl
6390: 6f 74 5b 69 5d 20 3d 20 70 3b 0a 20 20 20 20 70  ot[i] = p;.    p
63a0: 20 3d 20 70 4e 65 78 74 3b 0a 20 20 7d 0a 0a 20   = pNext;.  }.. 
63b0: 20 70 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d   p = 0;.  for(i=
63c0: 30 3b 20 69 3c 36 34 3b 20 69 2b 2b 29 7b 0a 20  0; i<64; i++){. 
63d0: 20 20 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72     vdbeSorterMer
63e0: 67 65 28 70 54 68 72 65 61 64 2c 20 70 2c 20 61  ge(pThread, p, a
63f0: 53 6c 6f 74 5b 69 5d 2c 20 26 70 29 3b 0a 20 20  Slot[i], &p);.  
6400: 7d 0a 20 20 70 54 68 72 65 61 64 2d 3e 70 4c 69  }.  pThread->pLi
6410: 73 74 20 3d 20 70 3b 0a 0a 20 20 73 71 6c 69 74  st = p;..  sqlit
6420: 65 33 5f 66 72 65 65 28 61 53 6c 6f 74 29 3b 0a  e3_free(aSlot);.
6430: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
6440: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69  OK;.}../*.** Ini
6450: 74 69 61 6c 69 7a 65 20 61 20 66 69 6c 65 2d 77  tialize a file-w
6460: 72 69 74 65 72 20 6f 62 6a 65 63 74 2e 0a 2a 2f  riter object..*/
6470: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 69 6c  .static void fil
6480: 65 57 72 69 74 65 72 49 6e 69 74 28 0a 20 20 73  eWriterInit(.  s
6490: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
64a0: 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  le,            /
64b0: 2a 20 46 69 6c 65 20 74 6f 20 77 72 69 74 65 20  * File to write 
64c0: 74 6f 20 2a 2f 0a 20 20 46 69 6c 65 57 72 69 74  to */.  FileWrit
64d0: 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20  er *p,          
64e0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63          /* Objec
64f0: 74 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f  t to populate */
6500: 0a 20 20 69 6e 74 20 6e 42 75 66 2c 20 20 20 20  .  int nBuf,    
6510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6520: 20 20 20 2f 2a 20 42 75 66 66 65 72 20 73 69 7a     /* Buffer siz
6530: 65 20 2a 2f 0a 20 20 69 36 34 20 69 53 74 61 72  e */.  i64 iStar
6540: 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t               
6550: 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74         /* Offset
6560: 20 6f 66 20 70 46 69 6c 65 20 74 6f 20 62 65 67   of pFile to beg
6570: 69 6e 20 77 72 69 74 69 6e 67 20 61 74 20 2a 2f  in writing at */
6580: 0a 29 7b 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20  .){.  memset(p, 
6590: 30 2c 20 73 69 7a 65 6f 66 28 46 69 6c 65 57 72  0, sizeof(FileWr
65a0: 69 74 65 72 29 29 3b 0a 20 20 70 2d 3e 61 42 75  iter));.  p->aBu
65b0: 66 66 65 72 20 3d 20 28 75 38 2a 29 73 71 6c 69  ffer = (u8*)sqli
65c0: 74 65 33 4d 61 6c 6c 6f 63 28 6e 42 75 66 29 3b  te3Malloc(nBuf);
65d0: 0a 20 20 69 66 28 20 21 70 2d 3e 61 42 75 66 66  .  if( !p->aBuff
65e0: 65 72 20 29 7b 0a 20 20 20 20 70 2d 3e 65 46 57  er ){.    p->eFW
65f0: 45 72 72 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d  Err = SQLITE_NOM
6600: 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  EM;.  }else{.   
6610: 20 70 2d 3e 69 42 75 66 45 6e 64 20 3d 20 70 2d   p->iBufEnd = p-
6620: 3e 69 42 75 66 53 74 61 72 74 20 3d 20 28 69 53  >iBufStart = (iS
6630: 74 61 72 74 20 25 20 6e 42 75 66 29 3b 0a 20 20  tart % nBuf);.  
6640: 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20 3d    p->iWriteOff =
6650: 20 69 53 74 61 72 74 20 2d 20 70 2d 3e 69 42 75   iStart - p->iBu
6660: 66 53 74 61 72 74 3b 0a 20 20 20 20 70 2d 3e 6e  fStart;.    p->n
6670: 42 75 66 66 65 72 20 3d 20 6e 42 75 66 3b 0a 20  Buffer = nBuf;. 
6680: 20 20 20 70 2d 3e 70 46 69 6c 65 20 3d 20 70 46     p->pFile = pF
6690: 69 6c 65 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  ile;.  }.}../*.*
66a0: 2a 20 57 72 69 74 65 20 6e 44 61 74 61 20 62 79  * Write nData by
66b0: 74 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 74  tes of data to t
66c0: 68 65 20 66 69 6c 65 2d 77 72 69 74 65 20 6f 62  he file-write ob
66d0: 6a 65 63 74 2e 20 52 65 74 75 72 6e 20 53 51 4c  ject. Return SQL
66e0: 49 54 45 5f 4f 4b 0a 2a 2a 20 69 66 20 73 75 63  ITE_OK.** if suc
66f0: 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53  cessful, or an S
6700: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
6710: 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   if an error occ
6720: 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  urs..*/.static v
6730: 6f 69 64 20 66 69 6c 65 57 72 69 74 65 72 57 72  oid fileWriterWr
6740: 69 74 65 28 46 69 6c 65 57 72 69 74 65 72 20 2a  ite(FileWriter *
6750: 70 2c 20 75 38 20 2a 70 44 61 74 61 2c 20 69 6e  p, u8 *pData, in
6760: 74 20 6e 44 61 74 61 29 7b 0a 20 20 69 6e 74 20  t nData){.  int 
6770: 6e 52 65 6d 20 3d 20 6e 44 61 74 61 3b 0a 20 20  nRem = nData;.  
6780: 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30 20 26 26  while( nRem>0 &&
6790: 20 70 2d 3e 65 46 57 45 72 72 3d 3d 30 20 29 7b   p->eFWErr==0 ){
67a0: 0a 20 20 20 20 69 6e 74 20 6e 43 6f 70 79 20 3d  .    int nCopy =
67b0: 20 6e 52 65 6d 3b 0a 20 20 20 20 69 66 28 20 6e   nRem;.    if( n
67c0: 43 6f 70 79 3e 28 70 2d 3e 6e 42 75 66 66 65 72  Copy>(p->nBuffer
67d0: 20 2d 20 70 2d 3e 69 42 75 66 45 6e 64 29 20 29   - p->iBufEnd) )
67e0: 7b 0a 20 20 20 20 20 20 6e 43 6f 70 79 20 3d 20  {.      nCopy = 
67f0: 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 70 2d 3e  p->nBuffer - p->
6800: 69 42 75 66 45 6e 64 3b 0a 20 20 20 20 7d 0a 0a  iBufEnd;.    }..
6810: 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d 3e 61      memcpy(&p->a
6820: 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 45 6e  Buffer[p->iBufEn
6830: 64 5d 2c 20 26 70 44 61 74 61 5b 6e 44 61 74 61  d], &pData[nData
6840: 2d 6e 52 65 6d 5d 2c 20 6e 43 6f 70 79 29 3b 0a  -nRem], nCopy);.
6850: 20 20 20 20 70 2d 3e 69 42 75 66 45 6e 64 20 2b      p->iBufEnd +
6860: 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 69 66 28  = nCopy;.    if(
6870: 20 70 2d 3e 69 42 75 66 45 6e 64 3d 3d 70 2d 3e   p->iBufEnd==p->
6880: 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20 20  nBuffer ){.     
6890: 20 70 2d 3e 65 46 57 45 72 72 20 3d 20 73 71 6c   p->eFWErr = sql
68a0: 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d 3e 70  ite3OsWrite(p->p
68b0: 46 69 6c 65 2c 20 0a 20 20 20 20 20 20 20 20 20  File, .         
68c0: 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 70 2d 3e   &p->aBuffer[p->
68d0: 69 42 75 66 53 74 61 72 74 5d 2c 20 70 2d 3e 69  iBufStart], p->i
68e0: 42 75 66 45 6e 64 20 2d 20 70 2d 3e 69 42 75 66  BufEnd - p->iBuf
68f0: 53 74 61 72 74 2c 20 0a 20 20 20 20 20 20 20 20  Start, .        
6900: 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b    p->iWriteOff +
6910: 20 70 2d 3e 69 42 75 66 53 74 61 72 74 0a 20 20   p->iBufStart.  
6920: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e      );.      p->
6930: 69 42 75 66 53 74 61 72 74 20 3d 20 70 2d 3e 69  iBufStart = p->i
6940: 42 75 66 45 6e 64 20 3d 20 30 3b 0a 20 20 20 20  BufEnd = 0;.    
6950: 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b    p->iWriteOff +
6960: 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20  = p->nBuffer;.  
6970: 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20    }.    assert( 
6980: 70 2d 3e 69 42 75 66 45 6e 64 3c 70 2d 3e 6e 42  p->iBufEnd<p->nB
6990: 75 66 66 65 72 20 29 3b 0a 0a 20 20 20 20 6e 52  uffer );..    nR
69a0: 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20 7d  em -= nCopy;.  }
69b0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68 20  .}../*.** Flush 
69c0: 61 6e 79 20 62 75 66 66 65 72 65 64 20 64 61 74  any buffered dat
69d0: 61 20 74 6f 20 64 69 73 6b 20 61 6e 64 20 63 6c  a to disk and cl
69e0: 65 61 6e 20 75 70 20 74 68 65 20 66 69 6c 65 2d  ean up the file-
69f0: 77 72 69 74 65 72 20 6f 62 6a 65 63 74 2e 0a 2a  writer object..*
6a00: 2a 20 54 68 65 20 72 65 73 75 6c 74 73 20 6f 66  * The results of
6a10: 20 75 73 69 6e 67 20 74 68 65 20 66 69 6c 65 2d   using the file-
6a20: 77 72 69 74 65 72 20 61 66 74 65 72 20 74 68 69  writer after thi
6a30: 73 20 63 61 6c 6c 20 61 72 65 20 75 6e 64 65 66  s call are undef
6a40: 69 6e 65 64 2e 0a 2a 2a 20 52 65 74 75 72 6e 20  ined..** Return 
6a50: 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 66 6c 75  SQLITE_OK if flu
6a60: 73 68 69 6e 67 20 74 68 65 20 62 75 66 66 65 72  shing the buffer
6a70: 65 64 20 64 61 74 61 20 73 75 63 63 65 65 64 73  ed data succeeds
6a80: 20 6f 72 20 69 73 20 6e 6f 74 20 0a 2a 2a 20 72   or is not .** r
6a90: 65 71 75 69 72 65 64 2e 20 4f 74 68 65 72 77 69  equired. Otherwi
6aa0: 73 65 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51  se, return an SQ
6ab0: 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e  Lite error code.
6ac0: 0a 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65 20 72 65  .**.** Before re
6ad0: 74 75 72 6e 69 6e 67 2c 20 73 65 74 20 2a 70 69  turning, set *pi
6ae0: 45 6f 66 20 74 6f 20 74 68 65 20 6f 66 66 73 65  Eof to the offse
6af0: 74 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f  t immediately fo
6b00: 6c 6c 6f 77 69 6e 67 20 74 68 65 0a 2a 2a 20 6c  llowing the.** l
6b10: 61 73 74 20 62 79 74 65 20 77 72 69 74 74 65 6e  ast byte written
6b20: 20 74 6f 20 74 68 65 20 66 69 6c 65 2e 0a 2a 2f   to the file..*/
6b30: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69 6c 65  .static int file
6b40: 57 72 69 74 65 72 46 69 6e 69 73 68 28 46 69 6c  WriterFinish(Fil
6b50: 65 57 72 69 74 65 72 20 2a 70 2c 20 69 36 34 20  eWriter *p, i64 
6b60: 2a 70 69 45 6f 66 29 7b 0a 20 20 69 6e 74 20 72  *piEof){.  int r
6b70: 63 3b 0a 20 20 69 66 28 20 70 2d 3e 65 46 57 45  c;.  if( p->eFWE
6b80: 72 72 3d 3d 30 20 26 26 20 41 4c 57 41 59 53 28  rr==0 && ALWAYS(
6b90: 70 2d 3e 61 42 75 66 66 65 72 29 20 26 26 20 70  p->aBuffer) && p
6ba0: 2d 3e 69 42 75 66 45 6e 64 3e 70 2d 3e 69 42 75  ->iBufEnd>p->iBu
6bb0: 66 53 74 61 72 74 20 29 7b 0a 20 20 20 20 70 2d  fStart ){.    p-
6bc0: 3e 65 46 57 45 72 72 20 3d 20 73 71 6c 69 74 65  >eFWErr = sqlite
6bd0: 33 4f 73 57 72 69 74 65 28 70 2d 3e 70 46 69 6c  3OsWrite(p->pFil
6be0: 65 2c 20 0a 20 20 20 20 20 20 20 20 26 70 2d 3e  e, .        &p->
6bf0: 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 53  aBuffer[p->iBufS
6c00: 74 61 72 74 5d 2c 20 70 2d 3e 69 42 75 66 45 6e  tart], p->iBufEn
6c10: 64 20 2d 20 70 2d 3e 69 42 75 66 53 74 61 72 74  d - p->iBufStart
6c20: 2c 20 0a 20 20 20 20 20 20 20 20 70 2d 3e 69 57  , .        p->iW
6c30: 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42 75  riteOff + p->iBu
6c40: 66 53 74 61 72 74 0a 20 20 20 20 29 3b 0a 20 20  fStart.    );.  
6c50: 7d 0a 20 20 2a 70 69 45 6f 66 20 3d 20 28 70 2d  }.  *piEof = (p-
6c60: 3e 69 57 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e  >iWriteOff + p->
6c70: 69 42 75 66 45 6e 64 29 3b 0a 20 20 73 71 6c 69  iBufEnd);.  sqli
6c80: 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 42 75 66  te3_free(p->aBuf
6c90: 66 65 72 29 3b 0a 20 20 72 63 20 3d 20 70 2d 3e  fer);.  rc = p->
6ca0: 65 46 57 45 72 72 3b 0a 20 20 6d 65 6d 73 65 74  eFWErr;.  memset
6cb0: 28 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28 46 69  (p, 0, sizeof(Fi
6cc0: 6c 65 57 72 69 74 65 72 29 29 3b 0a 20 20 72 65  leWriter));.  re
6cd0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
6ce0: 2a 20 57 72 69 74 65 20 76 61 6c 75 65 20 69 56  * Write value iV
6cf0: 61 6c 20 65 6e 63 6f 64 65 64 20 61 73 20 61 20  al encoded as a 
6d00: 76 61 72 69 6e 74 20 74 6f 20 74 68 65 20 66 69  varint to the fi
6d10: 6c 65 2d 77 72 69 74 65 20 6f 62 6a 65 63 74 2e  le-write object.
6d20: 20 52 65 74 75 72 6e 20 0a 2a 2a 20 53 51 4c 49   Return .** SQLI
6d30: 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73  TE_OK if success
6d40: 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74  ful, or an SQLit
6d50: 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20  e error code if 
6d60: 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e  an error occurs.
6d70: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
6d80: 66 69 6c 65 57 72 69 74 65 72 57 72 69 74 65 56  fileWriterWriteV
6d90: 61 72 69 6e 74 28 46 69 6c 65 57 72 69 74 65 72  arint(FileWriter
6da0: 20 2a 70 2c 20 75 36 34 20 69 56 61 6c 29 7b 0a   *p, u64 iVal){.
6db0: 20 20 69 6e 74 20 6e 42 79 74 65 3b 20 0a 20 20    int nByte; .  
6dc0: 75 38 20 61 42 79 74 65 5b 31 30 5d 3b 0a 20 20  u8 aByte[10];.  
6dd0: 6e 42 79 74 65 20 3d 20 73 71 6c 69 74 65 33 50  nByte = sqlite3P
6de0: 75 74 56 61 72 69 6e 74 28 61 42 79 74 65 2c 20  utVarint(aByte, 
6df0: 69 56 61 6c 29 3b 0a 20 20 66 69 6c 65 57 72 69  iVal);.  fileWri
6e00: 74 65 72 57 72 69 74 65 28 70 2c 20 61 42 79 74  terWrite(p, aByt
6e10: 65 2c 20 6e 42 79 74 65 29 3b 0a 7d 0a 0a 2f 2a  e, nByte);.}../*
6e20: 0a 2a 2a 20 57 72 69 74 65 20 74 68 65 20 63 75  .** Write the cu
6e30: 72 72 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f  rrent contents o
6e40: 66 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20  f the in-memory 
6e50: 6c 69 6e 6b 65 64 2d 6c 69 73 74 20 74 6f 20 61  linked-list to a
6e60: 20 50 4d 41 2e 20 52 65 74 75 72 6e 0a 2a 2a 20   PMA. Return.** 
6e70: 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63  SQLITE_OK if suc
6e80: 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53  cessful, or an S
6e90: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
6ea0: 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2a 0a 2a   otherwise..**.*
6eb0: 2a 20 54 68 65 20 66 6f 72 6d 61 74 20 6f 66 20  * The format of 
6ec0: 61 20 50 4d 41 20 69 73 3a 0a 2a 2a 0a 2a 2a 20  a PMA is:.**.** 
6ed0: 20 20 20 20 2a 20 41 20 76 61 72 69 6e 74 2e 20      * A varint. 
6ee0: 54 68 69 73 20 76 61 72 69 6e 74 20 63 6f 6e 74  This varint cont
6ef0: 61 69 6e 73 20 74 68 65 20 74 6f 74 61 6c 20 6e  ains the total n
6f00: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f  umber of bytes o
6f10: 66 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20 20 20 20  f content.**    
6f20: 20 20 20 69 6e 20 74 68 65 20 50 4d 41 20 28 6e     in the PMA (n
6f30: 6f 74 20 69 6e 63 6c 75 64 69 6e 67 20 74 68 65  ot including the
6f40: 20 76 61 72 69 6e 74 20 69 74 73 65 6c 66 29 2e   varint itself).
6f50: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 4f 6e 65  .**.**     * One
6f60: 20 6f 72 20 6d 6f 72 65 20 72 65 63 6f 72 64 73   or more records
6f70: 20 70 61 63 6b 65 64 20 65 6e 64 2d 74 6f 2d 65   packed end-to-e
6f80: 6e 64 20 69 6e 20 6f 72 64 65 72 20 6f 66 20 61  nd in order of a
6f90: 73 63 65 6e 64 69 6e 67 20 6b 65 79 73 2e 20 0a  scending keys. .
6fa0: 2a 2a 20 20 20 20 20 20 20 45 61 63 68 20 72 65  **       Each re
6fb0: 63 6f 72 64 20 63 6f 6e 73 69 73 74 73 20 6f 66  cord consists of
6fc0: 20 61 20 76 61 72 69 6e 74 20 66 6f 6c 6c 6f 77   a varint follow
6fd0: 65 64 20 62 79 20 61 20 62 6c 6f 62 20 6f 66 20  ed by a blob of 
6fe0: 64 61 74 61 20 28 74 68 65 20 0a 2a 2a 20 20 20  data (the .**   
6ff0: 20 20 20 20 6b 65 79 29 2e 20 54 68 65 20 76 61      key). The va
7000: 72 69 6e 74 20 69 73 20 74 68 65 20 6e 75 6d 62  rint is the numb
7010: 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 74  er of bytes in t
7020: 68 65 20 62 6c 6f 62 20 6f 66 20 64 61 74 61 2e  he blob of data.
7030: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
7040: 64 62 65 53 6f 72 74 65 72 4c 69 73 74 54 6f 50  dbeSorterListToP
7050: 4d 41 28 53 6f 72 74 65 72 54 68 72 65 61 64 20  MA(SorterThread 
7060: 2a 70 54 68 72 65 61 64 29 7b 0a 20 20 69 6e 74  *pThread){.  int
7070: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
7080: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7090: 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
70a0: 20 46 69 6c 65 57 72 69 74 65 72 20 77 72 69 74   FileWriter writ
70b0: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  er;             
70c0: 20 2f 2a 20 4f 62 6a 65 63 74 20 75 73 65 64 20   /* Object used 
70d0: 74 6f 20 77 72 69 74 65 20 74 6f 20 74 68 65 20  to write to the 
70e0: 66 69 6c 65 20 2a 2f 0a 0a 20 20 6d 65 6d 73 65  file */..  memse
70f0: 74 28 26 77 72 69 74 65 72 2c 20 30 2c 20 73 69  t(&writer, 0, si
7100: 7a 65 6f 66 28 46 69 6c 65 57 72 69 74 65 72 29  zeof(FileWriter)
7110: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 54 68  );.  assert( pTh
7120: 72 65 61 64 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 3e  read->nInMemory>
7130: 30 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68  0 );..  /* If th
7140: 65 20 66 69 72 73 74 20 74 65 6d 70 6f 72 61 72  e first temporar
7150: 79 20 50 4d 41 20 66 69 6c 65 20 68 61 73 20 6e  y PMA file has n
7160: 6f 74 20 62 65 65 6e 20 6f 70 65 6e 65 64 2c 20  ot been opened, 
7170: 6f 70 65 6e 20 69 74 20 6e 6f 77 2e 20 2a 2f 0a  open it now. */.
7180: 20 20 69 66 28 20 70 54 68 72 65 61 64 2d 3e 70    if( pThread->p
7190: 54 65 6d 70 31 3d 3d 30 20 29 7b 0a 20 20 20 20  Temp1==0 ){.    
71a0: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4f  rc = vdbeSorterO
71b0: 70 65 6e 54 65 6d 70 46 69 6c 65 28 70 54 68 72  penTempFile(pThr
71c0: 65 61 64 2d 3e 70 56 66 73 2c 20 26 70 54 68 72  ead->pVfs, &pThr
71d0: 65 61 64 2d 3e 70 54 65 6d 70 31 29 3b 0a 20 20  ead->pTemp1);.  
71e0: 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51    assert( rc!=SQ
71f0: 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 54 68 72 65  LITE_OK || pThre
7200: 61 64 2d 3e 70 54 65 6d 70 31 20 29 3b 0a 20 20  ad->pTemp1 );.  
7210: 20 20 61 73 73 65 72 74 28 20 70 54 68 72 65 61    assert( pThrea
7220: 64 2d 3e 69 54 65 6d 70 31 4f 66 66 3d 3d 30 20  d->iTemp1Off==0 
7230: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
7240: 54 68 72 65 61 64 2d 3e 6e 50 4d 41 3d 3d 30 20  Thread->nPMA==0 
7250: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63  );.  }..  if( rc
7260: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
7270: 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20     SorterRecord 
7280: 2a 70 3b 0a 20 20 20 20 53 6f 72 74 65 72 52 65  *p;.    SorterRe
7290: 63 6f 72 64 20 2a 70 4e 65 78 74 20 3d 20 30 3b  cord *pNext = 0;
72a0: 0a 0a 20 20 20 20 66 69 6c 65 57 72 69 74 65 72  ..    fileWriter
72b0: 49 6e 69 74 28 70 54 68 72 65 61 64 2d 3e 70 54  Init(pThread->pT
72c0: 65 6d 70 31 2c 20 26 77 72 69 74 65 72 2c 20 70  emp1, &writer, p
72d0: 54 68 72 65 61 64 2d 3e 70 67 73 7a 2c 20 70 54  Thread->pgsz, pT
72e0: 68 72 65 61 64 2d 3e 69 54 65 6d 70 31 4f 66 66  hread->iTemp1Off
72f0: 29 3b 0a 20 20 20 20 70 54 68 72 65 61 64 2d 3e  );.    pThread->
7300: 6e 50 4d 41 2b 2b 3b 0a 20 20 20 20 66 69 6c 65  nPMA++;.    file
7310: 57 72 69 74 65 72 57 72 69 74 65 56 61 72 69 6e  WriterWriteVarin
7320: 74 28 26 77 72 69 74 65 72 2c 20 70 54 68 72 65  t(&writer, pThre
7330: 61 64 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 29 3b 0a  ad->nInMemory);.
7340: 20 20 20 20 66 6f 72 28 70 3d 70 54 68 72 65 61      for(p=pThrea
7350: 64 2d 3e 70 4c 69 73 74 3b 20 70 3b 20 70 3d 70  d->pList; p; p=p
7360: 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 70 4e 65  Next){.      pNe
7370: 78 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20  xt = p->pNext;. 
7380: 20 20 20 20 20 66 69 6c 65 57 72 69 74 65 72 57       fileWriterW
7390: 72 69 74 65 56 61 72 69 6e 74 28 26 77 72 69 74  riteVarint(&writ
73a0: 65 72 2c 20 70 2d 3e 6e 56 61 6c 29 3b 0a 20 20  er, p->nVal);.  
73b0: 20 20 20 20 66 69 6c 65 57 72 69 74 65 72 57 72      fileWriterWr
73c0: 69 74 65 28 26 77 72 69 74 65 72 2c 20 70 2d 3e  ite(&writer, p->
73d0: 70 56 61 6c 2c 20 70 2d 3e 6e 56 61 6c 29 3b 0a  pVal, p->nVal);.
73e0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
73f0: 65 65 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20  ee(p);.    }.   
7400: 20 70 54 68 72 65 61 64 2d 3e 70 4c 69 73 74 20   pThread->pList 
7410: 3d 20 70 3b 0a 20 20 20 20 72 63 20 3d 20 66 69  = p;.    rc = fi
7420: 6c 65 57 72 69 74 65 72 46 69 6e 69 73 68 28 26  leWriterFinish(&
7430: 77 72 69 74 65 72 2c 20 26 70 54 68 72 65 61 64  writer, &pThread
7440: 2d 3e 69 54 65 6d 70 31 4f 66 66 29 3b 0a 20 20  ->iTemp1Off);.  
7450: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
7460: 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65  }../*.** Advance
7470: 20 74 68 65 20 53 6f 72 74 65 72 4d 65 72 67 65   the SorterMerge
7480: 72 20 69 74 65 72 61 74 6f 72 20 70 61 73 73 65  r iterator passe
7490: 64 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64 20  d as the second 
74a0: 61 72 67 75 6d 65 6e 74 20 74 6f 0a 2a 2a 20 74  argument to.** t
74b0: 68 65 20 6e 65 78 74 20 65 6e 74 72 79 2e 20 53  he next entry. S
74c0: 65 74 20 2a 70 62 45 6f 66 20 74 6f 20 74 72 75  et *pbEof to tru
74d0: 65 20 69 66 20 74 68 69 73 20 6d 65 61 6e 73 20  e if this means 
74e0: 74 68 65 20 69 74 65 72 61 74 6f 72 20 68 61 73  the iterator has
74f0: 20 0a 2a 2a 20 72 65 61 63 68 65 64 20 45 4f 46   .** reached EOF
7500: 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 53  ..**.** Return S
7510: 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63  QLITE_OK if succ
7520: 65 73 73 66 75 6c 20 6f 72 20 61 6e 20 65 72 72  essful or an err
7530: 6f 72 20 63 6f 64 65 20 69 66 20 61 6e 20 65 72  or code if an er
7540: 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73  ror occurs..*/.s
7550: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
7560: 72 74 65 72 4e 65 78 74 28 0a 20 20 53 6f 72 74  rterNext(.  Sort
7570: 65 72 54 68 72 65 61 64 20 2a 70 54 68 72 65 61  erThread *pThrea
7580: 64 2c 20 0a 20 20 53 6f 72 74 65 72 4d 65 72 67  d, .  SorterMerg
7590: 65 72 20 2a 70 4d 65 72 67 65 72 2c 20 0a 20 20  er *pMerger, .  
75a0: 69 6e 74 20 2a 70 62 45 6f 66 0a 29 7b 0a 20 20  int *pbEof.){.  
75b0: 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69 50  int rc;.  int iP
75c0: 72 65 76 20 3d 20 70 4d 65 72 67 65 72 2d 3e 61  rev = pMerger->a
75d0: 54 72 65 65 5b 31 5d 3b 2f 2a 20 49 6e 64 65 78  Tree[1];/* Index
75e0: 20 6f 66 20 69 74 65 72 61 74 6f 72 20 74 6f 20   of iterator to 
75f0: 61 64 76 61 6e 63 65 20 2a 2f 0a 20 20 69 6e 74  advance */.  int
7600: 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
7610: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
7620: 64 65 78 20 6f 66 20 61 54 72 65 65 5b 5d 20 74  dex of aTree[] t
7630: 6f 20 72 65 63 61 6c 63 75 6c 61 74 65 20 2a 2f  o recalculate */
7640: 0a 0a 20 20 2f 2a 20 41 64 76 61 6e 63 65 20 74  ..  /* Advance t
7650: 68 65 20 63 75 72 72 65 6e 74 20 69 74 65 72 61  he current itera
7660: 74 6f 72 20 2a 2f 0a 20 20 72 63 20 3d 20 76 64  tor */.  rc = vd
7670: 62 65 53 6f 72 74 65 72 49 74 65 72 4e 65 78 74  beSorterIterNext
7680: 28 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65 72  (&pMerger->aIter
7690: 5b 69 50 72 65 76 5d 29 3b 0a 0a 20 20 2f 2a 20  [iPrev]);..  /* 
76a0: 55 70 64 61 74 65 20 63 6f 6e 74 65 6e 74 73 20  Update contents 
76b0: 6f 66 20 61 54 72 65 65 5b 5d 20 2a 2f 0a 20 20  of aTree[] */.  
76c0: 66 6f 72 28 69 3d 28 70 4d 65 72 67 65 72 2d 3e  for(i=(pMerger->
76d0: 6e 54 72 65 65 2b 69 50 72 65 76 29 2f 32 3b 20  nTree+iPrev)/2; 
76e0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
76f0: 20 69 3e 30 3b 20 69 3d 69 2f 32 29 7b 0a 20 20   i>0; i=i/2){.  
7700: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
7710: 72 44 6f 43 6f 6d 70 61 72 65 28 70 54 68 72 65  rDoCompare(pThre
7720: 61 64 2c 20 70 4d 65 72 67 65 72 2c 20 69 29 3b  ad, pMerger, i);
7730: 0a 20 20 7d 0a 0a 20 20 2a 70 62 45 6f 66 20 3d  .  }..  *pbEof =
7740: 20 28 70 4d 65 72 67 65 72 2d 3e 61 49 74 65 72   (pMerger->aIter
7750: 5b 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b  [pMerger->aTree[
7760: 31 5d 5d 2e 70 46 69 6c 65 3d 3d 30 29 3b 0a 20  1]].pFile==0);. 
7770: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
7780: 2a 0a 2a 2a 20 54 68 65 20 6d 61 69 6e 20 72 6f  *.** The main ro
7790: 75 74 69 6e 65 20 66 6f 72 20 73 6f 72 74 65 72  utine for sorter
77a0: 2d 74 68 72 65 61 64 20 6f 70 65 72 61 74 69 6f  -thread operatio
77b0: 6e 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ns..*/.static vo
77c0: 69 64 20 2a 76 64 62 65 53 6f 72 74 65 72 54 68  id *vdbeSorterTh
77d0: 72 65 61 64 4d 61 69 6e 28 76 6f 69 64 20 2a 70  readMain(void *p
77e0: 43 74 78 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  Ctx){.  int rc =
77f0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 53 6f   SQLITE_OK;.  So
7800: 72 74 65 72 54 68 72 65 61 64 20 2a 70 54 68 72  rterThread *pThr
7810: 65 61 64 20 3d 20 28 53 6f 72 74 65 72 54 68 72  ead = (SorterThr
7820: 65 61 64 2a 29 70 43 74 78 3b 0a 0a 20 20 61 73  ead*)pCtx;..  as
7830: 73 65 72 74 28 20 70 54 68 72 65 61 64 2d 3e 65  sert( pThread->e
7840: 57 6f 72 6b 3d 3d 53 4f 52 54 45 52 5f 54 48 52  Work==SORTER_THR
7850: 45 41 44 5f 53 4f 52 54 0a 20 20 20 20 20 20 20  EAD_SORT.       
7860: 7c 7c 20 70 54 68 72 65 61 64 2d 3e 65 57 6f 72  || pThread->eWor
7870: 6b 3d 3d 53 4f 52 54 45 52 5f 54 48 52 45 41 44  k==SORTER_THREAD
7880: 5f 54 4f 5f 50 4d 41 0a 20 20 20 20 20 20 20 7c  _TO_PMA.       |
7890: 7c 20 70 54 68 72 65 61 64 2d 3e 65 57 6f 72 6b  | pThread->eWork
78a0: 3d 3d 53 4f 52 54 45 52 5f 54 48 52 45 41 44 5f  ==SORTER_THREAD_
78b0: 43 4f 4e 53 0a 20 20 29 3b 0a 20 20 61 73 73 65  CONS.  );.  asse
78c0: 72 74 28 20 70 54 68 72 65 61 64 2d 3e 62 44 6f  rt( pThread->bDo
78d0: 6e 65 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20  ne==0 );..  if( 
78e0: 70 54 68 72 65 61 64 2d 3e 70 55 6e 70 61 63 6b  pThread->pUnpack
78f0: 65 64 3d 3d 30 20 29 7b 0a 20 20 20 20 63 68 61  ed==0 ){.    cha
7900: 72 20 2a 70 46 72 65 65 3b 0a 20 20 20 20 70 54  r *pFree;.    pT
7910: 68 72 65 61 64 2d 3e 70 55 6e 70 61 63 6b 65 64  hread->pUnpacked
7920: 20 3d 20 73 71 6c 69 74 65 33 56 64 62 65 41 6c   = sqlite3VdbeAl
7930: 6c 6f 63 55 6e 70 61 63 6b 65 64 52 65 63 6f 72  locUnpackedRecor
7940: 64 28 0a 20 20 20 20 20 20 20 20 70 54 68 72 65  d(.        pThre
7950: 61 64 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20 30 2c  ad->pKeyInfo, 0,
7960: 20 30 2c 20 26 70 46 72 65 65 0a 20 20 20 20 29   0, &pFree.    )
7970: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 54  ;.    assert( pT
7980: 68 72 65 61 64 2d 3e 70 55 6e 70 61 63 6b 65 64  hread->pUnpacked
7990: 3d 3d 28 55 6e 70 61 63 6b 65 64 52 65 63 6f 72  ==(UnpackedRecor
79a0: 64 2a 29 70 46 72 65 65 20 29 3b 0a 20 20 20 20  d*)pFree );.    
79b0: 69 66 28 20 70 46 72 65 65 3d 3d 30 20 29 7b 0a  if( pFree==0 ){.
79c0: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
79d0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 67  E_NOMEM;.      g
79e0: 6f 74 6f 20 74 68 72 65 61 64 5f 6f 75 74 3b 0a  oto thread_out;.
79f0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28      }.  }..  if(
7a00: 20 70 54 68 72 65 61 64 2d 3e 65 57 6f 72 6b 3d   pThread->eWork=
7a10: 3d 53 4f 52 54 45 52 5f 54 48 52 45 41 44 5f 43  =SORTER_THREAD_C
7a20: 4f 4e 53 20 29 7b 0a 20 20 20 20 61 73 73 65 72  ONS ){.    asser
7a30: 74 28 20 70 54 68 72 65 61 64 2d 3e 70 4c 69 73  t( pThread->pLis
7a40: 74 3d 3d 30 20 29 3b 0a 20 20 20 20 77 68 69 6c  t==0 );.    whil
7a50: 65 28 20 70 54 68 72 65 61 64 2d 3e 6e 50 4d 41  e( pThread->nPMA
7a60: 3e 70 54 68 72 65 61 64 2d 3e 6e 43 6f 6e 73 6f  >pThread->nConso
7a70: 6c 69 64 61 74 65 20 26 26 20 72 63 3d 3d 53 51  lidate && rc==SQ
7a80: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
7a90: 20 69 6e 74 20 6e 49 74 65 72 20 3d 20 4d 49 4e   int nIter = MIN
7aa0: 28 70 54 68 72 65 61 64 2d 3e 6e 50 4d 41 2c 20  (pThread->nPMA, 
7ab0: 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45  SORTER_MAX_MERGE
7ac0: 5f 43 4f 55 4e 54 29 3b 0a 20 20 20 20 20 20 73  _COUNT);.      s
7ad0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 54 65  qlite3_file *pTe
7ae0: 6d 70 32 20 3d 20 30 3b 20 20 20 20 20 2f 2a 20  mp2 = 0;     /* 
7af0: 53 65 63 6f 6e 64 20 74 65 6d 70 20 66 69 6c 65  Second temp file
7b00: 20 74 6f 20 75 73 65 20 2a 2f 0a 20 20 20 20 20   to use */.     
7b10: 20 53 6f 72 74 65 72 4d 65 72 67 65 72 20 2a 70   SorterMerger *p
7b20: 4d 65 72 67 65 72 3b 20 20 20 20 20 20 20 20 2f  Merger;        /
7b30: 2a 20 4f 62 6a 65 63 74 20 66 6f 72 20 72 65 61  * Object for rea
7b40: 64 69 6e 67 2f 6d 65 72 67 69 6e 67 20 50 4d 41  ding/merging PMA
7b50: 20 64 61 74 61 20 2a 2f 0a 20 20 20 20 20 20 69   data */.      i
7b60: 36 34 20 69 52 65 61 64 4f 66 66 20 3d 20 30 3b  64 iReadOff = 0;
7b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7b80: 4f 66 66 73 65 74 20 69 6e 20 70 54 65 6d 70 31  Offset in pTemp1
7b90: 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f   to read from */
7ba0: 0a 20 20 20 20 20 20 69 36 34 20 69 57 72 69 74  .      i64 iWrit
7bb0: 65 4f 66 66 20 3d 20 30 3b 20 20 20 20 20 20 20  eOff = 0;       
7bc0: 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 69       /* Offset i
7bd0: 6e 20 70 54 65 6d 70 32 20 74 6f 20 77 72 69 74  n pTemp2 to writ
7be0: 65 20 74 6f 20 2a 2f 0a 20 20 20 20 20 20 69 6e  e to */.      in
7bf0: 74 20 69 3b 0a 20 20 20 20 20 20 0a 20 20 20 20  t i;.      .    
7c00: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20    /* Allocate a 
7c10: 6d 65 72 67 65 72 20 6f 62 6a 65 63 74 20 74 6f  merger object to
7c20: 20 6d 65 72 67 65 20 50 4d 41 73 20 74 6f 67 65   merge PMAs toge
7c30: 74 68 65 72 2e 20 2a 2f 0a 20 20 20 20 20 20 70  ther. */.      p
7c40: 4d 65 72 67 65 72 20 3d 20 76 64 62 65 53 6f 72  Merger = vdbeSor
7c50: 74 65 72 4d 65 72 67 65 72 4e 65 77 28 6e 49 74  terMergerNew(nIt
7c60: 65 72 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70  er);.      if( p
7c70: 4d 65 72 67 65 72 3d 3d 30 20 29 7b 0a 20 20 20  Merger==0 ){.   
7c80: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
7c90: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 20 20  _NOMEM;.        
7ca0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a  break;.      }..
7cb0: 20 20 20 20 20 20 2f 2a 20 4f 70 65 6e 20 61 20        /* Open a 
7cc0: 73 65 63 6f 6e 64 20 74 65 6d 70 20 66 69 6c 65  second temp file
7cd0: 20 74 6f 20 77 72 69 74 65 20 6d 65 72 67 65 64   to write merged
7ce0: 20 64 61 74 61 20 74 6f 20 2a 2f 0a 20 20 20 20   data to */.    
7cf0: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
7d00: 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 70 54  rOpenTempFile(pT
7d10: 68 72 65 61 64 2d 3e 70 56 66 73 2c 20 26 70 54  hread->pVfs, &pT
7d20: 65 6d 70 32 29 3b 0a 20 20 20 20 20 20 69 66 28  emp2);.      if(
7d30: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
7d40: 7b 0a 20 20 20 20 20 20 20 20 76 64 62 65 53 6f  {.        vdbeSo
7d50: 72 74 65 72 4d 65 72 67 65 72 46 72 65 65 28 70  rterMergerFree(p
7d60: 4d 65 72 67 65 72 29 3b 0a 20 20 20 20 20 20 20  Merger);.       
7d70: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
7d80: 0a 20 20 20 20 20 20 2f 2a 20 54 68 69 73 20 6c  .      /* This l
7d90: 6f 6f 70 20 72 75 6e 73 20 6f 6e 63 65 20 66 6f  oop runs once fo
7da0: 72 20 65 61 63 68 20 6f 75 74 70 75 74 20 50 4d  r each output PM
7db0: 41 2e 20 45 61 63 68 20 6f 75 74 70 75 74 20 50  A. Each output P
7dc0: 4d 41 20 69 73 20 6d 61 64 65 0a 20 20 20 20 20  MA is made.     
7dd0: 20 2a 2a 20 6f 66 20 64 61 74 61 20 6d 65 72 67   ** of data merg
7de0: 65 64 20 66 72 6f 6d 20 75 70 20 74 6f 20 53 4f  ed from up to SO
7df0: 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
7e00: 4f 55 4e 54 20 69 6e 70 75 74 20 50 4d 41 73 2e  OUNT input PMAs.
7e10: 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72 28 69 3d   */.      for(i=
7e20: 30 3b 20 69 3c 70 54 68 72 65 61 64 2d 3e 6e 50  0; i<pThread->nP
7e30: 4d 41 3b 20 69 2b 3d 53 4f 52 54 45 52 5f 4d 41  MA; i+=SORTER_MA
7e40: 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 29 7b 0a  X_MERGE_COUNT){.
7e50: 20 20 20 20 20 20 20 20 46 69 6c 65 57 72 69 74          FileWrit
7e60: 65 72 20 77 72 69 74 65 72 3b 20 20 20 20 20 20  er writer;      
7e70: 20 20 2f 2a 20 4f 62 6a 65 63 74 20 66 6f 72 20    /* Object for 
7e80: 77 72 69 74 69 6e 67 20 64 61 74 61 20 74 6f 20  writing data to 
7e90: 70 54 65 6d 70 32 20 2a 2f 0a 20 20 20 20 20 20  pTemp2 */.      
7ea0: 20 20 69 36 34 20 6e 4f 75 74 20 3d 20 30 3b 20    i64 nOut = 0; 
7eb0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
7ec0: 79 74 65 73 20 6f 66 20 64 61 74 61 20 69 6e 20  ytes of data in 
7ed0: 6f 75 74 70 75 74 20 50 4d 41 20 2a 2f 0a 20 20  output PMA */.  
7ee0: 20 20 20 20 20 20 69 6e 74 20 62 45 6f 66 20 3d        int bEof =
7ef0: 20 30 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   0;.        int 
7f00: 72 63 32 3b 0a 0a 20 20 20 20 20 20 20 20 2f 2a  rc2;..        /*
7f10: 20 43 6f 6e 66 69 67 75 72 65 20 74 68 65 20 6d   Configure the m
7f20: 65 72 67 65 72 20 6f 62 6a 65 63 74 20 74 6f 20  erger object to 
7f30: 72 65 61 64 20 61 6e 64 20 6d 65 72 67 65 20 64  read and merge d
7f40: 61 74 61 20 66 72 6f 6d 20 74 68 65 20 6e 65 78  ata from the nex
7f50: 74 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 53 4f  t .        ** SO
7f60: 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
7f70: 4f 55 4e 54 20 50 4d 41 73 20 69 6e 20 70 54 65  OUNT PMAs in pTe
7f80: 6d 70 31 20 28 6f 72 20 66 72 6f 6d 20 61 6c 6c  mp1 (or from all
7f90: 20 72 65 6d 61 69 6e 69 6e 67 20 50 4d 41 73 2c   remaining PMAs,
7fa0: 0a 20 20 20 20 20 20 20 20 2a 2a 20 69 66 20 74  .        ** if t
7fb0: 68 61 74 20 69 73 20 66 65 77 65 72 29 2e 20 2a  hat is fewer). *
7fc0: 2f 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 49  /.        int iI
7fd0: 74 65 72 3b 0a 20 20 20 20 20 20 20 20 66 6f 72  ter;.        for
7fe0: 28 69 49 74 65 72 3d 30 3b 20 69 49 74 65 72 3c  (iIter=0; iIter<
7ff0: 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45  SORTER_MAX_MERGE
8000: 5f 43 4f 55 4e 54 3b 20 69 49 74 65 72 2b 2b 29  _COUNT; iIter++)
8010: 7b 0a 20 20 20 20 20 20 20 20 20 20 56 64 62 65  {.          Vdbe
8020: 53 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74 65  SorterIter *pIte
8030: 72 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49  r = &pMerger->aI
8040: 74 65 72 5b 69 49 74 65 72 5d 3b 0a 20 20 20 20  ter[iIter];.    
8050: 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53        rc = vdbeS
8060: 6f 72 74 65 72 49 74 65 72 49 6e 69 74 28 70 54  orterIterInit(pT
8070: 68 72 65 61 64 2c 20 69 52 65 61 64 4f 66 66 2c  hread, iReadOff,
8080: 20 70 49 74 65 72 2c 20 26 6e 4f 75 74 29 3b 0a   pIter, &nOut);.
8090: 20 20 20 20 20 20 20 20 20 20 69 52 65 61 64 4f            iReadO
80a0: 66 66 20 3d 20 70 49 74 65 72 2d 3e 69 45 6f 66  ff = pIter->iEof
80b0: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
80c0: 69 52 65 61 64 4f 66 66 3e 3d 70 54 68 72 65 61  iReadOff>=pThrea
80d0: 64 2d 3e 69 54 65 6d 70 31 4f 66 66 20 7c 7c 20  d->iTemp1Off || 
80e0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
80f0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d  break;.        }
8100: 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69 49 74  .        for(iIt
8110: 65 72 3d 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65  er=pMerger->nTre
8120: 65 2d 31 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f  e-1; rc==SQLITE_
8130: 4f 4b 20 26 26 20 69 49 74 65 72 3e 30 3b 20 69  OK && iIter>0; i
8140: 49 74 65 72 2d 2d 29 7b 0a 20 20 20 20 20 20 20  Iter--){.       
8150: 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74     rc = vdbeSort
8160: 65 72 44 6f 43 6f 6d 70 61 72 65 28 70 54 68 72  erDoCompare(pThr
8170: 65 61 64 2c 20 70 4d 65 72 67 65 72 2c 20 69 49  ead, pMerger, iI
8180: 74 65 72 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  ter);.        }.
8190: 0a 20 20 20 20 20 20 20 20 66 69 6c 65 57 72 69  .        fileWri
81a0: 74 65 72 49 6e 69 74 28 70 54 65 6d 70 32 2c 20  terInit(pTemp2, 
81b0: 26 77 72 69 74 65 72 2c 20 70 54 68 72 65 61 64  &writer, pThread
81c0: 2d 3e 70 67 73 7a 2c 20 69 57 72 69 74 65 4f 66  ->pgsz, iWriteOf
81d0: 66 29 3b 0a 20 20 20 20 20 20 20 20 66 69 6c 65  f);.        file
81e0: 57 72 69 74 65 72 57 72 69 74 65 56 61 72 69 6e  WriterWriteVarin
81f0: 74 28 26 77 72 69 74 65 72 2c 20 6e 4f 75 74 29  t(&writer, nOut)
8200: 3b 0a 20 20 20 20 20 20 20 20 77 68 69 6c 65 28  ;.        while(
8210: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
8220: 26 20 62 45 6f 66 3d 3d 30 20 29 7b 0a 20 20 20  & bEof==0 ){.   
8230: 20 20 20 20 20 20 20 56 64 62 65 53 6f 72 74 65         VdbeSorte
8240: 72 49 74 65 72 20 2a 70 49 74 65 72 20 3d 20 26  rIter *pIter = &
8250: 70 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 20  pMerger->aIter[ 
8260: 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 31  pMerger->aTree[1
8270: 5d 20 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 61  ] ];.          a
8280: 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e 70 46  ssert( pIter->pF
8290: 69 6c 65 21 3d 30 20 29 3b 20 20 20 20 20 20 20  ile!=0 );       
82a0: 20 2f 2a 20 70 49 74 65 72 20 69 73 20 6e 6f 74   /* pIter is not
82b0: 20 61 74 20 45 4f 46 20 2a 2f 0a 20 20 20 20 20   at EOF */.     
82c0: 20 20 20 20 20 66 69 6c 65 57 72 69 74 65 72 57       fileWriterW
82d0: 72 69 74 65 56 61 72 69 6e 74 28 26 77 72 69 74  riteVarint(&writ
82e0: 65 72 2c 20 70 49 74 65 72 2d 3e 6e 4b 65 79 29  er, pIter->nKey)
82f0: 3b 0a 20 20 20 20 20 20 20 20 20 20 66 69 6c 65  ;.          file
8300: 57 72 69 74 65 72 57 72 69 74 65 28 26 77 72 69  WriterWrite(&wri
8310: 74 65 72 2c 20 70 49 74 65 72 2d 3e 61 4b 65 79  ter, pIter->aKey
8320: 2c 20 70 49 74 65 72 2d 3e 6e 4b 65 79 29 3b 0a  , pIter->nKey);.
8330: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 76            rc = v
8340: 64 62 65 53 6f 72 74 65 72 4e 65 78 74 28 70 54  dbeSorterNext(pT
8350: 68 72 65 61 64 2c 20 70 4d 65 72 67 65 72 2c 20  hread, pMerger, 
8360: 26 62 45 6f 66 29 3b 0a 20 20 20 20 20 20 20 20  &bEof);.        
8370: 7d 0a 20 20 20 20 20 20 20 20 72 63 32 20 3d 20  }.        rc2 = 
8380: 66 69 6c 65 57 72 69 74 65 72 46 69 6e 69 73 68  fileWriterFinish
8390: 28 26 77 72 69 74 65 72 2c 20 26 69 57 72 69 74  (&writer, &iWrit
83a0: 65 4f 66 66 29 3b 0a 20 20 20 20 20 20 20 20 69  eOff);.        i
83b0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
83c0: 20 29 20 72 63 20 3d 20 72 63 32 3b 0a 20 20 20   ) rc = rc2;.   
83d0: 20 20 20 7d 0a 0a 20 20 20 20 20 20 76 64 62 65     }..      vdbe
83e0: 53 6f 72 74 65 72 4d 65 72 67 65 72 46 72 65 65  SorterMergerFree
83f0: 28 70 4d 65 72 67 65 72 29 3b 0a 20 20 20 20 20  (pMerger);.     
8400: 20 73 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 46   sqlite3OsCloseF
8410: 72 65 65 28 70 54 68 72 65 61 64 2d 3e 70 54 65  ree(pThread->pTe
8420: 6d 70 31 29 3b 0a 20 20 20 20 20 20 70 54 68 72  mp1);.      pThr
8430: 65 61 64 2d 3e 70 54 65 6d 70 31 20 3d 20 70 54  ead->pTemp1 = pT
8440: 65 6d 70 32 3b 0a 20 20 20 20 20 20 70 54 68 72  emp2;.      pThr
8450: 65 61 64 2d 3e 6e 50 4d 41 20 3d 20 28 69 20 2f  ead->nPMA = (i /
8460: 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47   SORTER_MAX_MERG
8470: 45 5f 43 4f 55 4e 54 29 3b 0a 20 20 20 20 20 20  E_COUNT);.      
8480: 70 54 68 72 65 61 64 2d 3e 69 54 65 6d 70 31 4f  pThread->iTemp1O
8490: 66 66 20 3d 20 69 57 72 69 74 65 4f 66 66 3b 0a  ff = iWriteOff;.
84a0: 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20      }.  }else{. 
84b0: 20 20 20 2f 2a 20 53 6f 72 74 20 74 68 65 20 70     /* Sort the p
84c0: 54 68 72 65 61 64 2d 3e 70 4c 69 73 74 20 6c 69  Thread->pList li
84d0: 73 74 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 76  st */.    rc = v
84e0: 64 62 65 53 6f 72 74 65 72 53 6f 72 74 28 70 54  dbeSorterSort(pT
84f0: 68 72 65 61 64 29 3b 0a 0a 20 20 20 20 2f 2a 20  hread);..    /* 
8500: 49 66 20 72 65 71 75 69 72 65 64 2c 20 77 72 69  If required, wri
8510: 74 65 20 74 68 65 20 6c 69 73 74 20 6f 75 74 20  te the list out 
8520: 74 6f 20 61 20 50 4d 41 2e 20 2a 2f 0a 20 20 20  to a PMA. */.   
8530: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
8540: 4f 4b 20 26 26 20 70 54 68 72 65 61 64 2d 3e 65  OK && pThread->e
8550: 57 6f 72 6b 3d 3d 53 4f 52 54 45 52 5f 54 48 52  Work==SORTER_THR
8560: 45 41 44 5f 54 4f 5f 50 4d 41 20 29 7b 0a 23 69  EAD_TO_PMA ){.#i
8570: 66 64 65 66 20 53 51 4c 49 54 45 5f 44 45 42 55  fdef SQLITE_DEBU
8580: 47 0a 20 20 20 20 20 20 69 36 34 20 6e 45 78 70  G.      i64 nExp
8590: 65 63 74 20 3d 20 70 54 68 72 65 61 64 2d 3e 6e  ect = pThread->n
85a0: 49 6e 4d 65 6d 6f 72 79 0a 20 20 20 20 20 20 20  InMemory.       
85b0: 20 2b 20 73 71 6c 69 74 65 33 56 61 72 69 6e 74   + sqlite3Varint
85c0: 4c 65 6e 28 70 54 68 72 65 61 64 2d 3e 6e 49 6e  Len(pThread->nIn
85d0: 4d 65 6d 6f 72 79 29 0a 20 20 20 20 20 20 20 20  Memory).        
85e0: 2b 20 70 54 68 72 65 61 64 2d 3e 69 54 65 6d 70  + pThread->iTemp
85f0: 31 4f 66 66 3b 0a 23 65 6e 64 69 66 0a 20 20 20  1Off;.#endif.   
8600: 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74     rc = vdbeSort
8610: 65 72 4c 69 73 74 54 6f 50 4d 41 28 70 54 68 72  erListToPMA(pThr
8620: 65 61 64 29 3b 0a 20 20 20 20 20 20 61 73 73 65  ead);.      asse
8630: 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  rt( rc!=SQLITE_O
8640: 4b 20 7c 7c 20 28 6e 45 78 70 65 63 74 3d 3d 70  K || (nExpect==p
8650: 54 68 72 65 61 64 2d 3e 69 54 65 6d 70 31 4f 66  Thread->iTemp1Of
8660: 66 29 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  f) );.    }.  }.
8670: 0a 20 74 68 72 65 61 64 5f 6f 75 74 3a 0a 20 20  . thread_out:.  
8680: 70 54 68 72 65 61 64 2d 3e 62 44 6f 6e 65 20 3d  pThread->bDone =
8690: 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c   1;.  return SQL
86a0: 49 54 45 5f 49 4e 54 5f 54 4f 5f 50 54 52 28 72  ITE_INT_TO_PTR(r
86b0: 63 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 75 6e  c);.}../*.** Run
86c0: 20 74 68 65 20 61 63 74 69 76 69 74 79 20 73 63   the activity sc
86d0: 68 65 64 75 6c 65 64 20 62 79 20 74 68 65 20 6f  heduled by the o
86e0: 62 6a 65 63 74 20 70 61 73 73 65 64 20 61 73 20  bject passed as 
86f0: 74 68 65 20 6f 6e 6c 79 20 61 72 67 75 6d 65 6e  the only argumen
8700: 74 0a 2a 2a 20 69 6e 20 74 68 65 20 63 75 72 72  t.** in the curr
8710: 65 6e 74 20 74 68 72 65 61 64 2e 0a 2a 2f 0a 73  ent thread..*/.s
8720: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
8730: 72 74 65 72 52 75 6e 54 68 72 65 61 64 28 53 6f  rterRunThread(So
8740: 72 74 65 72 54 68 72 65 61 64 20 2a 70 54 68 72  rterThread *pThr
8750: 65 61 64 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  ead){.  int rc =
8760: 20 53 51 4c 49 54 45 5f 50 54 52 5f 54 4f 5f 49   SQLITE_PTR_TO_I
8770: 4e 54 28 20 76 64 62 65 53 6f 72 74 65 72 54 68  NT( vdbeSorterTh
8780: 72 65 61 64 4d 61 69 6e 28 28 76 6f 69 64 2a 29  readMain((void*)
8790: 70 54 68 72 65 61 64 29 20 29 3b 0a 20 20 61 73  pThread) );.  as
87a0: 73 65 72 74 28 20 70 54 68 72 65 61 64 2d 3e 62  sert( pThread->b
87b0: 44 6f 6e 65 20 29 3b 0a 20 20 70 54 68 72 65 61  Done );.  pThrea
87c0: 64 2d 3e 62 44 6f 6e 65 20 3d 20 30 3b 0a 20 20  d->bDone = 0;.  
87d0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
87e0: 0a 2a 2a 20 46 6c 75 73 68 20 74 68 65 20 63 75  .** Flush the cu
87f0: 72 72 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f  rrent contents o
8800: 66 20 56 64 62 65 53 6f 72 74 65 72 2e 70 52 65  f VdbeSorter.pRe
8810: 63 6f 72 64 20 74 6f 20 61 20 6e 65 77 20 50 4d  cord to a new PM
8820: 41 2c 20 70 6f 73 73 69 62 6c 79 0a 2a 2a 20 75  A, possibly.** u
8830: 73 69 6e 67 20 61 20 62 61 63 6b 67 72 6f 75 6e  sing a backgroun
8840: 64 20 74 68 72 65 61 64 2e 0a 2a 2a 0a 2a 2a 20  d thread..**.** 
8850: 49 66 20 61 72 67 75 6d 65 6e 74 20 62 46 67 20  If argument bFg 
8860: 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65  is non-zero, the
8870: 20 6f 70 65 72 61 74 69 6f 6e 20 61 6c 77 61 79   operation alway
8880: 73 20 75 73 65 73 20 74 68 65 20 63 61 6c 6c 69  s uses the calli
8890: 6e 67 20 74 68 72 65 61 64 2e 0a 2a 2f 0a 73 74  ng thread..*/.st
88a0: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
88b0: 74 65 72 46 6c 75 73 68 50 4d 41 28 73 71 6c 69  terFlushPMA(sqli
88c0: 74 65 33 20 2a 64 62 2c 20 63 6f 6e 73 74 20 56  te3 *db, const V
88d0: 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c  dbeCursor *pCsr,
88e0: 20 69 6e 74 20 62 46 67 29 7b 0a 20 20 56 64 62   int bFg){.  Vdb
88f0: 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72  eSorter *pSorter
8900: 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72   = pCsr->pSorter
8910: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  ;.  int rc = SQL
8920: 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 69 3b  ITE_OK;.  int i;
8930: 0a 20 20 53 6f 72 74 65 72 54 68 72 65 61 64 20  .  SorterThread 
8940: 2a 70 54 68 72 65 61 64 3b 20 20 20 20 20 20 20  *pThread;       
8950: 20 2f 2a 20 54 68 72 65 61 64 20 63 6f 6e 74 65   /* Thread conte
8960: 78 74 20 75 73 65 64 20 74 6f 20 63 72 65 61 74  xt used to creat
8970: 65 20 6e 65 77 20 50 4d 41 20 2a 2f 0a 0a 20 20  e new PMA */..  
8980: 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41  pSorter->bUsePMA
8990: 20 3d 20 31 3b 0a 20 20 66 6f 72 28 69 3d 30 3b   = 1;.  for(i=0;
89a0: 20 41 4c 57 41 59 53 28 20 69 3c 53 51 4c 49 54   ALWAYS( i<SQLIT
89b0: 45 5f 4d 41 58 5f 53 4f 52 54 45 52 5f 54 48 52  E_MAX_SORTER_THR
89c0: 45 41 44 20 29 3b 20 69 2b 2b 29 7b 0a 20 20 20  EAD ); i++){.   
89d0: 20 70 54 68 72 65 61 64 20 3d 20 26 70 53 6f 72   pThread = &pSor
89e0: 74 65 72 2d 3e 61 54 68 72 65 61 64 5b 69 5d 3b  ter->aThread[i];
89f0: 0a 20 20 20 20 69 66 28 20 70 54 68 72 65 61 64  .    if( pThread
8a00: 2d 3e 62 44 6f 6e 65 20 29 7b 0a 20 20 20 20 20  ->bDone ){.     
8a10: 20 76 6f 69 64 20 2a 70 52 65 74 3b 0a 20 20 20   void *pRet;.   
8a20: 20 20 20 61 73 73 65 72 74 28 20 70 54 68 72 65     assert( pThre
8a30: 61 64 2d 3e 70 54 68 72 65 61 64 20 29 3b 0a 20  ad->pThread );. 
8a40: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
8a50: 33 54 68 72 65 61 64 4a 6f 69 6e 28 70 54 68 72  3ThreadJoin(pThr
8a60: 65 61 64 2d 3e 70 54 68 72 65 61 64 2c 20 26 70  ead->pThread, &p
8a70: 52 65 74 29 3b 0a 20 20 20 20 20 20 70 54 68 72  Ret);.      pThr
8a80: 65 61 64 2d 3e 70 54 68 72 65 61 64 20 3d 20 30  ead->pThread = 0
8a90: 3b 0a 20 20 20 20 20 20 70 54 68 72 65 61 64 2d  ;.      pThread-
8aa0: 3e 62 44 6f 6e 65 20 3d 20 30 3b 0a 20 20 20 20  >bDone = 0;.    
8ab0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
8ac0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72  _OK ){.        r
8ad0: 63 20 3d 20 53 51 4c 49 54 45 5f 50 54 52 5f 54  c = SQLITE_PTR_T
8ae0: 4f 5f 49 4e 54 28 70 52 65 74 29 3b 0a 20 20 20  O_INT(pRet);.   
8af0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69     }.    }.    i
8b00: 66 28 20 70 54 68 72 65 61 64 2d 3e 70 54 68 72  f( pThread->pThr
8b10: 65 61 64 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a  ead==0 ) break;.
8b20: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53    }..  if( rc==S
8b30: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
8b40: 61 73 73 65 72 74 28 20 70 54 68 72 65 61 64 2d  assert( pThread-
8b50: 3e 70 54 68 72 65 61 64 3d 3d 30 20 26 26 20 70  >pThread==0 && p
8b60: 54 68 72 65 61 64 2d 3e 62 44 6f 6e 65 3d 3d 30  Thread->bDone==0
8b70: 20 29 3b 0a 20 20 20 20 70 54 68 72 65 61 64 2d   );.    pThread-
8b80: 3e 65 57 6f 72 6b 20 3d 20 53 4f 52 54 45 52 5f  >eWork = SORTER_
8b90: 54 48 52 45 41 44 5f 54 4f 5f 50 4d 41 3b 0a 20  THREAD_TO_PMA;. 
8ba0: 20 20 20 70 54 68 72 65 61 64 2d 3e 70 4c 69 73     pThread->pLis
8bb0: 74 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 52 65  t = pSorter->pRe
8bc0: 63 6f 72 64 3b 0a 20 20 20 20 70 54 68 72 65 61  cord;.    pThrea
8bd0: 64 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20 3d 20 70  d->nInMemory = p
8be0: 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72  Sorter->nInMemor
8bf0: 79 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  y;.    pSorter->
8c00: 6e 49 6e 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a 20  nInMemory = 0;. 
8c10: 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63     pSorter->pRec
8c20: 6f 72 64 20 3d 20 30 3b 0a 0a 20 20 20 20 69 66  ord = 0;..    if
8c30: 28 20 62 46 67 20 7c 7c 20 69 3c 28 53 51 4c 49  ( bFg || i<(SQLI
8c40: 54 45 5f 4d 41 58 5f 53 4f 52 54 45 52 5f 54 48  TE_MAX_SORTER_TH
8c50: 52 45 41 44 2d 31 29 20 29 7b 0a 20 20 20 20 20  READ-1) ){.     
8c60: 20 76 6f 69 64 20 2a 70 43 74 78 20 3d 20 28 76   void *pCtx = (v
8c70: 6f 69 64 2a 29 70 54 68 72 65 61 64 3b 0a 20 20  oid*)pThread;.  
8c80: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
8c90: 54 68 72 65 61 64 43 72 65 61 74 65 28 26 70 54  ThreadCreate(&pT
8ca0: 68 72 65 61 64 2d 3e 70 54 68 72 65 61 64 2c 20  hread->pThread, 
8cb0: 76 64 62 65 53 6f 72 74 65 72 54 68 72 65 61 64  vdbeSorterThread
8cc0: 4d 61 69 6e 2c 20 70 43 74 78 29 3b 0a 20 20 20  Main, pCtx);.   
8cd0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a   }else{.      /*
8ce0: 20 55 73 65 20 74 68 65 20 66 6f 72 65 67 72 6f   Use the foregro
8cf0: 75 6e 64 20 74 68 72 65 61 64 20 66 6f 72 20 74  und thread for t
8d00: 68 69 73 20 6f 70 65 72 61 74 69 6f 6e 20 2a 2f  his operation */
8d10: 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65  .      rc = vdbe
8d20: 53 6f 72 74 65 72 52 75 6e 54 68 72 65 61 64 28  SorterRunThread(
8d30: 70 54 68 72 65 61 64 29 3b 0a 20 20 20 20 7d 0a  pThread);.    }.
8d40: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
8d50: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61  ;.}../*.** Add a
8d60: 20 72 65 63 6f 72 64 20 74 6f 20 74 68 65 20 73   record to the s
8d70: 6f 72 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71  orter..*/.int sq
8d80: 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 57  lite3VdbeSorterW
8d90: 72 69 74 65 28 0a 20 20 73 71 6c 69 74 65 33 20  rite(.  sqlite3 
8da0: 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20  *db,            
8db0: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
8dc0: 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20  ase handle */.  
8dd0: 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72  const VdbeCursor
8de0: 20 2a 70 43 73 72 2c 20 20 20 20 20 20 20 20 20   *pCsr,         
8df0: 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20        /* Sorter 
8e00: 63 75 72 73 6f 72 20 2a 2f 0a 20 20 4d 65 6d 20  cursor */.  Mem 
8e10: 2a 70 56 61 6c 20 20 20 20 20 20 20 20 20 20 20  *pVal           
8e20: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d              /* M
8e30: 65 6d 6f 72 79 20 63 65 6c 6c 20 63 6f 6e 74 61  emory cell conta
8e40: 69 6e 69 6e 67 20 72 65 63 6f 72 64 20 2a 2f 0a  ining record */.
8e50: 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20  ){.  VdbeSorter 
8e60: 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d  *pSorter = pCsr-
8e70: 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20  >pSorter;.  int 
8e80: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20  rc = SQLITE_OK; 
8e90: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
8ea0: 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20  eturn Code */.  
8eb0: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e  SorterRecord *pN
8ec0: 65 77 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ew;             
8ed0: 2f 2a 20 4e 65 77 20 6c 69 73 74 20 65 6c 65 6d  /* New list elem
8ee0: 65 6e 74 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74  ent */..  assert
8ef0: 28 20 70 53 6f 72 74 65 72 20 29 3b 0a 20 20 70  ( pSorter );.  p
8f00: 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72  Sorter->nInMemor
8f10: 79 20 2b 3d 20 73 71 6c 69 74 65 33 56 61 72 69  y += sqlite3Vari
8f20: 6e 74 4c 65 6e 28 70 56 61 6c 2d 3e 6e 29 20 2b  ntLen(pVal->n) +
8f30: 20 70 56 61 6c 2d 3e 6e 3b 0a 0a 20 20 70 4e 65   pVal->n;..  pNe
8f40: 77 20 3d 20 28 53 6f 72 74 65 72 52 65 63 6f 72  w = (SorterRecor
8f50: 64 20 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  d *)sqlite3Mallo
8f60: 63 28 70 56 61 6c 2d 3e 6e 20 2b 20 73 69 7a 65  c(pVal->n + size
8f70: 6f 66 28 53 6f 72 74 65 72 52 65 63 6f 72 64 29  of(SorterRecord)
8f80: 29 3b 0a 20 20 69 66 28 20 70 4e 65 77 3d 3d 30  );.  if( pNew==0
8f90: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   ){.    rc = SQL
8fa0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c  ITE_NOMEM;.  }el
8fb0: 73 65 7b 0a 20 20 20 20 70 4e 65 77 2d 3e 70 56  se{.    pNew->pV
8fc0: 61 6c 20 3d 20 28 76 6f 69 64 20 2a 29 26 70 4e  al = (void *)&pN
8fd0: 65 77 5b 31 5d 3b 0a 20 20 20 20 6d 65 6d 63 70  ew[1];.    memcp
8fe0: 79 28 70 4e 65 77 2d 3e 70 56 61 6c 2c 20 70 56  y(pNew->pVal, pV
8ff0: 61 6c 2d 3e 7a 2c 20 70 56 61 6c 2d 3e 6e 29 3b  al->z, pVal->n);
9000: 0a 20 20 20 20 70 4e 65 77 2d 3e 6e 56 61 6c 20  .    pNew->nVal 
9010: 3d 20 70 56 61 6c 2d 3e 6e 3b 0a 20 20 20 20 70  = pVal->n;.    p
9020: 4e 65 77 2d 3e 70 4e 65 78 74 20 3d 20 70 53 6f  New->pNext = pSo
9030: 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 3b 0a 20  rter->pRecord;. 
9040: 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63     pSorter->pRec
9050: 6f 72 64 20 3d 20 70 4e 65 77 3b 0a 20 20 7d 0a  ord = pNew;.  }.
9060: 0a 20 20 2f 2a 20 53 65 65 20 69 66 20 74 68 65  .  /* See if the
9070: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
9080: 20 73 6f 72 74 65 72 20 73 68 6f 75 6c 64 20 6e   sorter should n
9090: 6f 77 20 62 65 20 77 72 69 74 74 65 6e 20 6f 75  ow be written ou
90a0: 74 2e 20 54 68 65 79 0a 20 20 2a 2a 20 61 72 65  t. They.  ** are
90b0: 20 77 72 69 74 74 65 6e 20 6f 75 74 20 77 68 65   written out whe
90c0: 6e 20 65 69 74 68 65 72 20 6f 66 20 74 68 65 20  n either of the 
90d0: 66 6f 6c 6c 6f 77 69 6e 67 20 61 72 65 20 74 72  following are tr
90e0: 75 65 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20  ue:.  **.  **   
90f0: 2a 20 54 68 65 20 74 6f 74 61 6c 20 6d 65 6d 6f  * The total memo
9100: 72 79 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72  ry allocated for
9110: 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c   the in-memory l
9120: 69 73 74 20 69 73 20 67 72 65 61 74 65 72 20 0a  ist is greater .
9130: 20 20 2a 2a 20 20 20 20 20 74 68 61 6e 20 28 70    **     than (p
9140: 61 67 65 2d 73 69 7a 65 20 2a 20 63 61 63 68 65  age-size * cache
9150: 2d 73 69 7a 65 29 2c 20 6f 72 0a 20 20 2a 2a 0a  -size), or.  **.
9160: 20 20 2a 2a 20 20 20 2a 20 54 68 65 20 74 6f 74    **   * The tot
9170: 61 6c 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61  al memory alloca
9180: 74 65 64 20 66 6f 72 20 74 68 65 20 69 6e 2d 6d  ted for the in-m
9190: 65 6d 6f 72 79 20 6c 69 73 74 20 69 73 20 67 72  emory list is gr
91a0: 65 61 74 65 72 20 0a 20 20 2a 2a 20 20 20 20 20  eater .  **     
91b0: 74 68 61 6e 20 28 70 61 67 65 2d 73 69 7a 65 20  than (page-size 
91c0: 2a 20 31 30 29 20 61 6e 64 20 73 71 6c 69 74 65  * 10) and sqlite
91d0: 33 48 65 61 70 4e 65 61 72 6c 79 46 75 6c 6c 28  3HeapNearlyFull(
91e0: 29 20 72 65 74 75 72 6e 73 20 74 72 75 65 2e 0a  ) returns true..
91f0: 20 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53    */.  if( rc==S
9200: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 53 6f 72  QLITE_OK && pSor
9210: 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65 3e 30  ter->mxPmaSize>0
9220: 20 26 26 20 28 0a 20 20 20 20 20 20 20 20 28 70   && (.        (p
9230: 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72  Sorter->nInMemor
9240: 79 3e 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61  y>pSorter->mxPma
9250: 53 69 7a 65 29 0a 20 20 20 20 20 7c 7c 20 28 70  Size).     || (p
9260: 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72  Sorter->nInMemor
9270: 79 3e 70 53 6f 72 74 65 72 2d 3e 6d 6e 50 6d 61  y>pSorter->mnPma
9280: 53 69 7a 65 20 26 26 20 73 71 6c 69 74 65 33 48  Size && sqlite3H
9290: 65 61 70 4e 65 61 72 6c 79 46 75 6c 6c 28 29 29  eapNearlyFull())
92a0: 0a 20 20 29 29 7b 0a 20 20 20 20 72 63 20 3d 20  .  )){.    rc = 
92b0: 76 64 62 65 53 6f 72 74 65 72 46 6c 75 73 68 50  vdbeSorterFlushP
92c0: 4d 41 28 64 62 2c 20 70 43 73 72 2c 20 30 29 3b  MA(db, pCsr, 0);
92d0: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
92e0: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  c;.}../*.** Retu
92f0: 72 6e 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d  rn the total num
9300: 62 65 72 20 6f 66 20 50 4d 41 73 20 69 6e 20 61  ber of PMAs in a
9310: 6c 6c 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c  ll temporary fil
9320: 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  es..*/.static in
9330: 74 20 76 64 62 65 53 6f 72 74 65 72 43 6f 75 6e  t vdbeSorterCoun
9340: 74 50 4d 41 28 56 64 62 65 53 6f 72 74 65 72 20  tPMA(VdbeSorter 
9350: 2a 70 53 6f 72 74 65 72 29 7b 0a 20 20 69 6e 74  *pSorter){.  int
9360: 20 6e 50 4d 41 20 3d 20 30 3b 0a 20 20 69 6e 74   nPMA = 0;.  int
9370: 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69   i;.  for(i=0; i
9380: 3c 53 51 4c 49 54 45 5f 4d 41 58 5f 53 4f 52 54  <SQLITE_MAX_SORT
9390: 45 52 5f 54 48 52 45 41 44 3b 20 69 2b 2b 29 7b  ER_THREAD; i++){
93a0: 0a 20 20 20 20 6e 50 4d 41 20 2b 3d 20 70 53 6f  .    nPMA += pSo
93b0: 72 74 65 72 2d 3e 61 54 68 72 65 61 64 5b 69 5d  rter->aThread[i]
93c0: 2e 6e 50 4d 41 3b 0a 20 20 7d 0a 20 20 72 65 74  .nPMA;.  }.  ret
93d0: 75 72 6e 20 6e 50 4d 41 3b 0a 7d 0a 0a 2f 2a 0a  urn nPMA;.}../*.
93e0: 2a 2a 20 4f 6e 63 65 20 74 68 65 20 73 6f 72 74  ** Once the sort
93f0: 65 72 20 68 61 73 20 62 65 65 6e 20 70 6f 70 75  er has been popu
9400: 6c 61 74 65 64 2c 20 74 68 69 73 20 66 75 6e 63  lated, this func
9410: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74  tion is called t
9420: 6f 20 70 72 65 70 61 72 65 0a 2a 2a 20 66 6f 72  o prepare.** for
9430: 20 69 74 65 72 61 74 69 6e 67 20 74 68 72 6f 75   iterating throu
9440: 67 68 20 69 74 73 20 63 6f 6e 74 65 6e 74 73 20  gh its contents 
9450: 69 6e 20 73 6f 72 74 65 64 20 6f 72 64 65 72 2e  in sorted order.
9460: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56  .*/.int sqlite3V
9470: 64 62 65 53 6f 72 74 65 72 52 65 77 69 6e 64 28  dbeSorterRewind(
9480: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 63 6f 6e  sqlite3 *db, con
9490: 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70  st VdbeCursor *p
94a0: 43 73 72 2c 20 69 6e 74 20 2a 70 62 45 6f 66 29  Csr, int *pbEof)
94b0: 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a  {.  VdbeSorter *
94c0: 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e  pSorter = pCsr->
94d0: 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 72  pSorter;.  int r
94e0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20  c = SQLITE_OK;  
94f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
9500: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20 20  turn code */..  
9510: 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 20  assert( pSorter 
9520: 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 6e 6f 20 64  );..  /* If no d
9530: 61 74 61 20 68 61 73 20 62 65 65 6e 20 77 72 69  ata has been wri
9540: 74 74 65 6e 20 74 6f 20 64 69 73 6b 2c 20 74 68  tten to disk, th
9550: 65 6e 20 64 6f 20 6e 6f 74 20 64 6f 20 73 6f 20  en do not do so 
9560: 6e 6f 77 2e 20 49 6e 73 74 65 61 64 2c 0a 20 20  now. Instead,.  
9570: 2a 2a 20 73 6f 72 74 20 74 68 65 20 56 64 62 65  ** sort the Vdbe
9580: 53 6f 72 74 65 72 2e 70 52 65 63 6f 72 64 20 6c  Sorter.pRecord l
9590: 69 73 74 2e 20 54 68 65 20 76 64 62 65 20 6c 61  ist. The vdbe la
95a0: 79 65 72 20 77 69 6c 6c 20 72 65 61 64 20 64 61  yer will read da
95b0: 74 61 20 64 69 72 65 63 74 6c 79 0a 20 20 2a 2a  ta directly.  **
95c0: 20 66 72 6f 6d 20 74 68 65 20 69 6e 2d 6d 65 6d   from the in-mem
95d0: 6f 72 79 20 6c 69 73 74 2e 20 20 2a 2f 0a 20 20  ory list.  */.  
95e0: 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 62 55 73  if( pSorter->bUs
95f0: 65 50 4d 41 3d 3d 30 20 29 7b 0a 20 20 20 20 69  ePMA==0 ){.    i
9600: 66 28 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63  f( pSorter->pRec
9610: 6f 72 64 20 29 7b 0a 20 20 20 20 20 20 53 6f 72  ord ){.      Sor
9620: 74 65 72 54 68 72 65 61 64 20 2a 70 54 68 72 65  terThread *pThre
9630: 61 64 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61  ad = &pSorter->a
9640: 54 68 72 65 61 64 5b 30 5d 3b 0a 20 20 20 20 20  Thread[0];.     
9650: 20 2a 70 62 45 6f 66 20 3d 20 30 3b 0a 20 20 20   *pbEof = 0;.   
9660: 20 20 20 70 54 68 72 65 61 64 2d 3e 70 4c 69 73     pThread->pLis
9670: 74 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 52 65  t = pSorter->pRe
9680: 63 6f 72 64 3b 0a 20 20 20 20 20 20 70 54 68 72  cord;.      pThr
9690: 65 61 64 2d 3e 65 57 6f 72 6b 20 3d 20 53 4f 52  ead->eWork = SOR
96a0: 54 45 52 5f 54 48 52 45 41 44 5f 53 4f 52 54 3b  TER_THREAD_SORT;
96b0: 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65  .      rc = vdbe
96c0: 53 6f 72 74 65 72 52 75 6e 54 68 72 65 61 64 28  SorterRunThread(
96d0: 70 54 68 72 65 61 64 29 3b 0a 20 20 20 20 20 20  pThread);.      
96e0: 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64  pSorter->pRecord
96f0: 20 3d 20 70 54 68 72 65 61 64 2d 3e 70 4c 69 73   = pThread->pLis
9700: 74 3b 0a 20 20 20 20 20 20 70 54 68 72 65 61 64  t;.      pThread
9710: 2d 3e 70 4c 69 73 74 20 3d 20 30 3b 0a 20 20 20  ->pList = 0;.   
9720: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2a 70   }else{.      *p
9730: 62 45 6f 66 20 3d 20 31 3b 0a 20 20 20 20 7d 0a  bEof = 1;.    }.
9740: 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
9750: 20 7d 0a 0a 20 20 2f 2a 20 57 72 69 74 65 20 74   }..  /* Write t
9760: 68 65 20 63 75 72 72 65 6e 74 20 69 6e 2d 6d 65  he current in-me
9770: 6d 6f 72 79 20 6c 69 73 74 20 74 6f 20 61 20 50  mory list to a P
9780: 4d 41 2e 20 2a 2f 0a 20 20 69 66 28 20 70 53 6f  MA. */.  if( pSo
9790: 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 29 7b  rter->pRecord ){
97a0: 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f  .    rc = vdbeSo
97b0: 72 74 65 72 46 6c 75 73 68 50 4d 41 28 64 62 2c  rterFlushPMA(db,
97c0: 20 70 43 73 72 2c 20 31 29 3b 0a 20 20 7d 0a 0a   pCsr, 1);.  }..
97d0: 20 20 2f 2a 20 4a 6f 69 6e 20 61 6c 6c 20 74 68    /* Join all th
97e0: 72 65 61 64 73 20 2a 2f 0a 20 20 72 63 20 3d 20  reads */.  rc = 
97f0: 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e 41 6c  vdbeSorterJoinAl
9800: 6c 28 70 53 6f 72 74 65 72 2c 20 72 63 29 3b 0a  l(pSorter, rc);.
9810: 0a 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20 61  .  /* If there a
9820: 72 65 20 6d 6f 72 65 20 74 68 61 6e 20 53 4f 52  re more than SOR
9830: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
9840: 55 4e 54 20 50 4d 41 73 20 6f 6e 20 64 69 73 6b  UNT PMAs on disk
9850: 2c 20 6d 65 72 67 65 0a 20 20 2a 2a 20 73 6f 6d  , merge.  ** som
9860: 65 20 6f 66 20 74 68 65 6d 20 74 6f 67 65 74 68  e of them togeth
9870: 65 72 20 73 6f 20 74 68 61 74 20 74 68 69 73 20  er so that this 
9880: 69 73 20 6e 6f 20 6c 6f 6e 67 65 72 20 74 68 65  is no longer the
9890: 20 63 61 73 65 2e 20 2a 2f 0a 20 20 61 73 73 65   case. */.  asse
98a0: 72 74 28 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  rt( SORTER_MAX_M
98b0: 45 52 47 45 5f 43 4f 55 4e 54 3e 3d 53 51 4c 49  ERGE_COUNT>=SQLI
98c0: 54 45 5f 4d 41 58 5f 53 4f 52 54 45 52 5f 54 48  TE_MAX_SORTER_TH
98d0: 52 45 41 44 20 29 3b 0a 20 20 69 66 28 20 76 64  READ );.  if( vd
98e0: 62 65 53 6f 72 74 65 72 43 6f 75 6e 74 50 4d 41  beSorterCountPMA
98f0: 28 70 53 6f 72 74 65 72 29 3e 53 4f 52 54 45 52  (pSorter)>SORTER
9900: 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
9910: 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20   ){.    int i;. 
9920: 20 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d     for(i=0; rc==
9930: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 53  SQLITE_OK && i<S
9940: 51 4c 49 54 45 5f 4d 41 58 5f 53 4f 52 54 45 52  QLITE_MAX_SORTER
9950: 5f 54 48 52 45 41 44 3b 20 69 2b 2b 29 7b 0a 20  _THREAD; i++){. 
9960: 20 20 20 20 20 53 6f 72 74 65 72 54 68 72 65 61       SorterThrea
9970: 64 20 2a 70 54 68 72 65 61 64 20 3d 20 26 70 53  d *pThread = &pS
9980: 6f 72 74 65 72 2d 3e 61 54 68 72 65 61 64 5b 69  orter->aThread[i
9990: 5d 3b 0a 20 20 20 20 20 20 69 66 28 20 70 54 68  ];.      if( pTh
99a0: 72 65 61 64 2d 3e 70 54 65 6d 70 31 20 29 7b 0a  read->pTemp1 ){.
99b0: 20 20 20 20 20 20 20 20 70 54 68 72 65 61 64 2d          pThread-
99c0: 3e 6e 43 6f 6e 73 6f 6c 69 64 61 74 65 20 3d 20  >nConsolidate = 
99d0: 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45  SORTER_MAX_MERGE
99e0: 5f 43 4f 55 4e 54 2f 53 51 4c 49 54 45 5f 4d 41  _COUNT/SQLITE_MA
99f0: 58 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44 3b  X_SORTER_THREAD;
9a00: 0a 20 20 20 20 20 20 20 20 70 54 68 72 65 61 64  .        pThread
9a10: 2d 3e 65 57 6f 72 6b 20 3d 20 53 4f 52 54 45 52  ->eWork = SORTER
9a20: 5f 54 48 52 45 41 44 5f 43 4f 4e 53 3b 0a 0a 20  _THREAD_CONS;.. 
9a30: 20 20 20 20 20 20 20 69 66 28 20 69 3c 28 53 51         if( i<(SQ
9a40: 4c 49 54 45 5f 4d 41 58 5f 53 4f 52 54 45 52 5f  LITE_MAX_SORTER_
9a50: 54 48 52 45 41 44 2d 31 29 20 29 7b 0a 20 20 20  THREAD-1) ){.   
9a60: 20 20 20 20 20 20 20 76 6f 69 64 20 2a 70 43 74         void *pCt
9a70: 78 20 3d 20 28 76 6f 69 64 2a 29 70 54 68 72 65  x = (void*)pThre
9a80: 61 64 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63  ad;.          rc
9a90: 20 3d 20 73 71 6c 69 74 65 33 54 68 72 65 61 64   = sqlite3Thread
9aa0: 43 72 65 61 74 65 28 26 70 54 68 72 65 61 64 2d  Create(&pThread-
9ab0: 3e 70 54 68 72 65 61 64 2c 76 64 62 65 53 6f 72  >pThread,vdbeSor
9ac0: 74 65 72 54 68 72 65 61 64 4d 61 69 6e 2c 70 43  terThreadMain,pC
9ad0: 74 78 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  tx);.        }el
9ae0: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63  se{.          rc
9af0: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 52 75 6e   = vdbeSorterRun
9b00: 54 68 72 65 61 64 28 70 54 68 72 65 61 64 29 3b  Thread(pThread);
9b10: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
9b20: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
9b30: 2f 2a 20 4a 6f 69 6e 20 61 6c 6c 20 74 68 72 65  /* Join all thre
9b40: 61 64 73 20 2a 2f 0a 20 20 72 63 20 3d 20 76 64  ads */.  rc = vd
9b50: 62 65 53 6f 72 74 65 72 4a 6f 69 6e 41 6c 6c 28  beSorterJoinAll(
9b60: 70 53 6f 72 74 65 72 2c 20 72 63 29 3b 0a 0a 20  pSorter, rc);.. 
9b70: 20 2f 2a 20 41 73 73 75 6d 69 6e 67 20 6e 6f 20   /* Assuming no 
9b80: 65 72 72 6f 72 73 20 68 61 76 65 20 6f 63 63 75  errors have occu
9b90: 72 72 65 64 2c 20 73 65 74 20 75 70 20 61 20 6d  rred, set up a m
9ba0: 65 72 67 65 72 20 73 74 72 75 63 74 75 72 65 20  erger structure 
9bb0: 74 6f 20 72 65 61 64 0a 20 20 2a 2a 20 61 6e 64  to read.  ** and
9bc0: 20 6d 65 72 67 65 20 61 6c 6c 20 72 65 6d 61 69   merge all remai
9bd0: 6e 69 6e 67 20 50 4d 41 73 2e 20 20 2a 2f 0a 20  ning PMAs.  */. 
9be0: 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72   assert( pSorter
9bf0: 2d 3e 70 4d 65 72 67 65 72 3d 3d 30 20 29 3b 0a  ->pMerger==0 );.
9c00: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
9c10: 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e  _OK ){.    int n
9c20: 49 74 65 72 20 3d 20 30 3b 20 20 20 20 20 20 20  Iter = 0;       
9c30: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
9c40: 65 72 20 6f 66 20 69 74 65 72 61 74 6f 72 73 20  er of iterators 
9c50: 75 73 65 64 20 2a 2f 0a 20 20 20 20 69 6e 74 20  used */.    int 
9c60: 69 3b 0a 20 20 20 20 53 6f 72 74 65 72 4d 65 72  i;.    SorterMer
9c70: 67 65 72 20 2a 70 4d 65 72 67 65 72 3b 0a 20 20  ger *pMerger;.  
9c80: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 53 51 4c    for(i=0; i<SQL
9c90: 49 54 45 5f 4d 41 58 5f 53 4f 52 54 45 52 5f 54  ITE_MAX_SORTER_T
9ca0: 48 52 45 41 44 3b 20 69 2b 2b 29 7b 0a 20 20 20  HREAD; i++){.   
9cb0: 20 20 20 6e 49 74 65 72 20 2b 3d 20 70 53 6f 72     nIter += pSor
9cc0: 74 65 72 2d 3e 61 54 68 72 65 61 64 5b 69 5d 2e  ter->aThread[i].
9cd0: 6e 50 4d 41 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  nPMA;.    }..   
9ce0: 20 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65   pSorter->pMerge
9cf0: 72 20 3d 20 70 4d 65 72 67 65 72 20 3d 20 76 64  r = pMerger = vd
9d00: 62 65 53 6f 72 74 65 72 4d 65 72 67 65 72 4e 65  beSorterMergerNe
9d10: 77 28 6e 49 74 65 72 29 3b 0a 20 20 20 20 69 66  w(nIter);.    if
9d20: 28 20 70 4d 65 72 67 65 72 3d 3d 30 20 29 7b 0a  ( pMerger==0 ){.
9d30: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
9d40: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c  E_NOMEM;.    }el
9d50: 73 65 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 49  se{.      int iI
9d60: 74 65 72 20 3d 20 30 3b 0a 20 20 20 20 20 20 69  ter = 0;.      i
9d70: 6e 74 20 69 54 68 72 65 61 64 20 3d 20 30 3b 0a  nt iThread = 0;.
9d80: 20 20 20 20 20 20 66 6f 72 28 69 54 68 72 65 61        for(iThrea
9d90: 64 3d 30 3b 20 69 54 68 72 65 61 64 3c 53 51 4c  d=0; iThread<SQL
9da0: 49 54 45 5f 4d 41 58 5f 53 4f 52 54 45 52 5f 54  ITE_MAX_SORTER_T
9db0: 48 52 45 41 44 3b 20 69 54 68 72 65 61 64 2b 2b  HREAD; iThread++
9dc0: 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69  ){.        int i
9dd0: 50 4d 41 3b 0a 20 20 20 20 20 20 20 20 69 36 34  PMA;.        i64
9de0: 20 69 52 65 61 64 4f 66 66 20 3d 20 30 3b 0a 20   iReadOff = 0;. 
9df0: 20 20 20 20 20 20 20 53 6f 72 74 65 72 54 68 72         SorterThr
9e00: 65 61 64 20 2a 70 54 68 72 65 61 64 20 3d 20 26  ead *pThread = &
9e10: 70 53 6f 72 74 65 72 2d 3e 61 54 68 72 65 61 64  pSorter->aThread
9e20: 5b 69 54 68 72 65 61 64 5d 3b 0a 20 20 20 20 20  [iThread];.     
9e30: 20 20 20 66 6f 72 28 69 50 4d 41 3d 30 3b 20 69     for(iPMA=0; i
9e40: 50 4d 41 3c 70 54 68 72 65 61 64 2d 3e 6e 50 4d  PMA<pThread->nPM
9e50: 41 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f  A && rc==SQLITE_
9e60: 4f 4b 3b 20 69 50 4d 41 2b 2b 29 7b 0a 20 20 20  OK; iPMA++){.   
9e70: 20 20 20 20 20 20 20 69 36 34 20 6e 44 75 6d 6d         i64 nDumm
9e80: 79 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 20  y = 0;.         
9e90: 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20   VdbeSorterIter 
9ea0: 2a 70 49 74 65 72 20 3d 20 26 70 4d 65 72 67 65  *pIter = &pMerge
9eb0: 72 2d 3e 61 49 74 65 72 5b 69 49 74 65 72 2b 2b  r->aIter[iIter++
9ec0: 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  ];.          rc 
9ed0: 3d 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72  = vdbeSorterIter
9ee0: 49 6e 69 74 28 70 54 68 72 65 61 64 2c 20 69 52  Init(pThread, iR
9ef0: 65 61 64 4f 66 66 2c 20 70 49 74 65 72 2c 20 26  eadOff, pIter, &
9f00: 6e 44 75 6d 6d 79 29 3b 0a 20 20 20 20 20 20 20  nDummy);.       
9f10: 20 20 20 69 52 65 61 64 4f 66 66 20 3d 20 70 49     iReadOff = pI
9f20: 74 65 72 2d 3e 69 45 6f 66 3b 0a 20 20 20 20 20  ter->iEof;.     
9f30: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20     }.      }..  
9f40: 20 20 20 20 66 6f 72 28 69 3d 70 4d 65 72 67 65      for(i=pMerge
9f50: 72 2d 3e 6e 54 72 65 65 2d 31 3b 20 72 63 3d 3d  r->nTree-1; rc==
9f60: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3e 30  SQLITE_OK && i>0
9f70: 3b 20 69 2d 2d 29 7b 0a 20 20 20 20 20 20 20 20  ; i--){.        
9f80: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 44  rc = vdbeSorterD
9f90: 6f 43 6f 6d 70 61 72 65 28 26 70 53 6f 72 74 65  oCompare(&pSorte
9fa0: 72 2d 3e 61 54 68 72 65 61 64 5b 30 5d 2c 20 70  r->aThread[0], p
9fb0: 4d 65 72 67 65 72 2c 20 69 29 3b 0a 20 20 20 20  Merger, i);.    
9fc0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20    }.    }.  }.. 
9fd0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
9fe0: 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 62 45 6f 66  OK ){.    *pbEof
9ff0: 20 3d 20 28 70 53 6f 72 74 65 72 2d 3e 70 4d 65   = (pSorter->pMe
a000: 72 67 65 72 2d 3e 61 49 74 65 72 5b 70 53 6f 72  rger->aIter[pSor
a010: 74 65 72 2d 3e 70 4d 65 72 67 65 72 2d 3e 61 54  ter->pMerger->aT
a020: 72 65 65 5b 31 5d 5d 2e 70 46 69 6c 65 3d 3d 30  ree[1]].pFile==0
a030: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
a040: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76  rc;.}../*.** Adv
a050: 61 6e 63 65 20 74 6f 20 74 68 65 20 6e 65 78 74  ance to the next
a060: 20 65 6c 65 6d 65 6e 74 20 69 6e 20 74 68 65 20   element in the 
a070: 73 6f 72 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20 73  sorter..*/.int s
a080: 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72  qlite3VdbeSorter
a090: 4e 65 78 74 28 73 71 6c 69 74 65 33 20 2a 64 62  Next(sqlite3 *db
a0a0: 2c 20 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73  , const VdbeCurs
a0b0: 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74 20 2a 70  or *pCsr, int *p
a0c0: 62 45 6f 66 29 7b 0a 20 20 56 64 62 65 53 6f 72  bEof){.  VdbeSor
a0d0: 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70  ter *pSorter = p
a0e0: 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20  Csr->pSorter;.  
a0f0: 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
a100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a110: 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
a120: 2f 0a 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72  /..  if( pSorter
a130: 2d 3e 70 4d 65 72 67 65 72 20 29 7b 0a 20 20 20  ->pMerger ){.   
a140: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
a150: 4e 65 78 74 28 26 70 53 6f 72 74 65 72 2d 3e 61  Next(&pSorter->a
a160: 54 68 72 65 61 64 5b 30 5d 2c 20 70 53 6f 72 74  Thread[0], pSort
a170: 65 72 2d 3e 70 4d 65 72 67 65 72 2c 20 70 62 45  er->pMerger, pbE
a180: 6f 66 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  of);.  }else{.  
a190: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
a1a0: 70 46 72 65 65 20 3d 20 70 53 6f 72 74 65 72 2d  pFree = pSorter-
a1b0: 3e 70 52 65 63 6f 72 64 3b 0a 20 20 20 20 70 53  >pRecord;.    pS
a1c0: 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 3d  orter->pRecord =
a1d0: 20 70 46 72 65 65 2d 3e 70 4e 65 78 74 3b 0a 20   pFree->pNext;. 
a1e0: 20 20 20 70 46 72 65 65 2d 3e 70 4e 65 78 74 20     pFree->pNext 
a1f0: 3d 20 30 3b 0a 20 20 20 20 76 64 62 65 53 6f 72  = 0;.    vdbeSor
a200: 74 65 72 52 65 63 6f 72 64 46 72 65 65 28 64 62  terRecordFree(db
a210: 2c 20 70 46 72 65 65 29 3b 0a 20 20 20 20 2a 70  , pFree);.    *p
a220: 62 45 6f 66 20 3d 20 21 70 53 6f 72 74 65 72 2d  bEof = !pSorter-
a230: 3e 70 52 65 63 6f 72 64 3b 0a 20 20 20 20 72 63  >pRecord;.    rc
a240: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
a250: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
a260: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61  ../*.** Return a
a270: 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 62 75   pointer to a bu
a280: 66 66 65 72 20 6f 77 6e 65 64 20 62 79 20 74 68  ffer owned by th
a290: 65 20 73 6f 72 74 65 72 20 74 68 61 74 20 63 6f  e sorter that co
a2a0: 6e 74 61 69 6e 73 20 74 68 65 20 0a 2a 2a 20 63  ntains the .** c
a2b0: 75 72 72 65 6e 74 20 6b 65 79 2e 0a 2a 2f 0a 73  urrent key..*/.s
a2c0: 74 61 74 69 63 20 76 6f 69 64 20 2a 76 64 62 65  tatic void *vdbe
a2d0: 53 6f 72 74 65 72 52 6f 77 6b 65 79 28 0a 20 20  SorterRowkey(.  
a2e0: 63 6f 6e 73 74 20 56 64 62 65 53 6f 72 74 65 72  const VdbeSorter
a2f0: 20 2a 70 53 6f 72 74 65 72 2c 20 20 20 20 20 20   *pSorter,      
a300: 2f 2a 20 53 6f 72 74 65 72 20 6f 62 6a 65 63 74  /* Sorter object
a310: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4b 65 79   */.  int *pnKey
a320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a330: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 53 69        /* OUT: Si
a340: 7a 65 20 6f 66 20 63 75 72 72 65 6e 74 20 6b 65  ze of current ke
a350: 79 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 29 7b  y in bytes */.){
a360: 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 3b 0a 20  .  void *pKey;. 
a370: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 70 4d   if( pSorter->pM
a380: 65 72 67 65 72 20 29 7b 0a 20 20 20 20 56 64 62  erger ){.    Vdb
a390: 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74  eSorterIter *pIt
a3a0: 65 72 3b 0a 20 20 20 20 70 49 74 65 72 20 3d 20  er;.    pIter = 
a3b0: 26 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65  &pSorter->pMerge
a3c0: 72 2d 3e 61 49 74 65 72 5b 20 70 53 6f 72 74 65  r->aIter[ pSorte
a3d0: 72 2d 3e 70 4d 65 72 67 65 72 2d 3e 61 54 72 65  r->pMerger->aTre
a3e0: 65 5b 31 5d 20 5d 3b 0a 20 20 20 20 2a 70 6e 4b  e[1] ];.    *pnK
a3f0: 65 79 20 3d 20 70 49 74 65 72 2d 3e 6e 4b 65 79  ey = pIter->nKey
a400: 3b 0a 20 20 20 20 70 4b 65 79 20 3d 20 70 49 74  ;.    pKey = pIt
a410: 65 72 2d 3e 61 4b 65 79 3b 0a 20 20 7d 65 6c 73  er->aKey;.  }els
a420: 65 7b 0a 20 20 20 20 2a 70 6e 4b 65 79 20 3d 20  e{.    *pnKey = 
a430: 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64  pSorter->pRecord
a440: 2d 3e 6e 56 61 6c 3b 0a 20 20 20 20 70 4b 65 79  ->nVal;.    pKey
a450: 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63   = pSorter->pRec
a460: 6f 72 64 2d 3e 70 56 61 6c 3b 0a 20 20 7d 0a 20  ord->pVal;.  }. 
a470: 20 72 65 74 75 72 6e 20 70 4b 65 79 3b 0a 7d 0a   return pKey;.}.
a480: 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20 74 68 65 20  ./*.** Copy the 
a490: 63 75 72 72 65 6e 74 20 73 6f 72 74 65 72 20 6b  current sorter k
a4a0: 65 79 20 69 6e 74 6f 20 74 68 65 20 6d 65 6d 6f  ey into the memo
a4b0: 72 79 20 63 65 6c 6c 20 70 4f 75 74 2e 0a 2a 2f  ry cell pOut..*/
a4c0: 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65  .int sqlite3Vdbe
a4d0: 53 6f 72 74 65 72 52 6f 77 6b 65 79 28 63 6f 6e  SorterRowkey(con
a4e0: 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70  st VdbeCursor *p
a4f0: 43 73 72 2c 20 4d 65 6d 20 2a 70 4f 75 74 29 7b  Csr, Mem *pOut){
a500: 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70  .  VdbeSorter *p
a510: 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70  Sorter = pCsr->p
a520: 53 6f 72 74 65 72 3b 0a 20 20 76 6f 69 64 20 2a  Sorter;.  void *
a530: 70 4b 65 79 3b 20 69 6e 74 20 6e 4b 65 79 3b 20  pKey; int nKey; 
a540: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72            /* Sor
a550: 74 65 72 20 6b 65 79 20 74 6f 20 63 6f 70 79 20  ter key to copy 
a560: 69 6e 74 6f 20 70 4f 75 74 20 2a 2f 0a 0a 20 20  into pOut */..  
a570: 70 4b 65 79 20 3d 20 76 64 62 65 53 6f 72 74 65  pKey = vdbeSorte
a580: 72 52 6f 77 6b 65 79 28 70 53 6f 72 74 65 72 2c  rRowkey(pSorter,
a590: 20 26 6e 4b 65 79 29 3b 0a 20 20 69 66 28 20 73   &nKey);.  if( s
a5a0: 71 6c 69 74 65 33 56 64 62 65 4d 65 6d 47 72 6f  qlite3VdbeMemGro
a5b0: 77 28 70 4f 75 74 2c 20 6e 4b 65 79 2c 20 30 29  w(pOut, nKey, 0)
a5c0: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
a5d0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d  QLITE_NOMEM;.  }
a5e0: 0a 20 20 70 4f 75 74 2d 3e 6e 20 3d 20 6e 4b 65  .  pOut->n = nKe
a5f0: 79 3b 0a 20 20 4d 65 6d 53 65 74 54 79 70 65 46  y;.  MemSetTypeF
a600: 6c 61 67 28 70 4f 75 74 2c 20 4d 45 4d 5f 42 6c  lag(pOut, MEM_Bl
a610: 6f 62 29 3b 0a 20 20 6d 65 6d 63 70 79 28 70 4f  ob);.  memcpy(pO
a620: 75 74 2d 3e 7a 2c 20 70 4b 65 79 2c 20 6e 4b 65  ut->z, pKey, nKe
a630: 79 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 53 51  y);..  return SQ
a640: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  LITE_OK;.}../*.*
a650: 2a 20 43 6f 6d 70 61 72 65 20 74 68 65 20 6b 65  * Compare the ke
a660: 79 20 69 6e 20 6d 65 6d 6f 72 79 20 63 65 6c 6c  y in memory cell
a670: 20 70 56 61 6c 20 77 69 74 68 20 74 68 65 20 6b   pVal with the k
a680: 65 79 20 74 68 61 74 20 74 68 65 20 73 6f 72 74  ey that the sort
a690: 65 72 20 63 75 72 73 6f 72 0a 2a 2a 20 70 61 73  er cursor.** pas
a6a0: 73 65 64 20 61 73 20 74 68 65 20 66 69 72 73 74  sed as the first
a6b0: 20 61 72 67 75 6d 65 6e 74 20 63 75 72 72 65 6e   argument curren
a6c0: 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f 2e 20 46  tly points to. F
a6d0: 6f 72 20 74 68 65 20 70 75 72 70 6f 73 65 73 20  or the purposes 
a6e0: 6f 66 0a 2a 2a 20 74 68 65 20 63 6f 6d 70 61 72  of.** the compar
a6f0: 69 73 6f 6e 2c 20 69 67 6e 6f 72 65 20 74 68 65  ison, ignore the
a700: 20 72 6f 77 69 64 20 66 69 65 6c 64 20 61 74 20   rowid field at 
a710: 74 68 65 20 65 6e 64 20 6f 66 20 65 61 63 68 20  the end of each 
a720: 72 65 63 6f 72 64 2e 0a 2a 2a 0a 2a 2a 20 49 66  record..**.** If
a730: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
a740: 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69  , return an SQLi
a750: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 28 69  te error code (i
a760: 2e 65 2e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  .e. SQLITE_NOMEM
a770: 29 2e 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c  )..** Otherwise,
a780: 20 73 65 74 20 2a 70 52 65 73 20 74 6f 20 61 20   set *pRes to a 
a790: 6e 65 67 61 74 69 76 65 2c 20 7a 65 72 6f 20 6f  negative, zero o
a7a0: 72 20 70 6f 73 69 74 69 76 65 20 76 61 6c 75 65  r positive value
a7b0: 20 69 66 20 74 68 65 0a 2a 2a 20 6b 65 79 20 69   if the.** key i
a7c0: 6e 20 70 56 61 6c 20 69 73 20 73 6d 61 6c 6c 65  n pVal is smalle
a7d0: 72 20 74 68 61 6e 2c 20 65 71 75 61 6c 20 74 6f  r than, equal to
a7e0: 20 6f 72 20 6c 61 72 67 65 72 20 74 68 61 6e 20   or larger than 
a7f0: 74 68 65 20 63 75 72 72 65 6e 74 20 73 6f 72 74  the current sort
a800: 65 72 0a 2a 2a 20 6b 65 79 2e 0a 2a 2f 0a 69 6e  er.** key..*/.in
a810: 74 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72  t sqlite3VdbeSor
a820: 74 65 72 43 6f 6d 70 61 72 65 28 0a 20 20 63 6f  terCompare(.  co
a830: 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a  nst VdbeCursor *
a840: 70 43 73 72 2c 20 20 20 20 20 20 20 20 20 2f 2a  pCsr,         /*
a850: 20 53 6f 72 74 65 72 20 63 75 72 73 6f 72 20 2a   Sorter cursor *
a860: 2f 0a 20 20 4d 65 6d 20 2a 70 56 61 6c 2c 20 20  /.  Mem *pVal,  
a870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a880: 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 74 6f 20      /* Value to 
a890: 63 6f 6d 70 61 72 65 20 74 6f 20 63 75 72 72 65  compare to curre
a8a0: 6e 74 20 73 6f 72 74 65 72 20 6b 65 79 20 2a 2f  nt sorter key */
a8b0: 0a 20 20 69 6e 74 20 6e 49 67 6e 6f 72 65 2c 20  .  int nIgnore, 
a8c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a8d0: 20 20 20 2f 2a 20 49 67 6e 6f 72 65 20 74 68 69     /* Ignore thi
a8e0: 73 20 6d 61 6e 79 20 66 69 65 6c 64 73 20 61 74  s many fields at
a8f0: 20 74 68 65 20 65 6e 64 20 2a 2f 0a 20 20 69 6e   the end */.  in
a900: 74 20 2a 70 52 65 73 20 20 20 20 20 20 20 20 20  t *pRes         
a910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
a920: 20 4f 55 54 3a 20 52 65 73 75 6c 74 20 6f 66 20   OUT: Result of 
a930: 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f 0a 29 7b  comparison */.){
a940: 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70  .  VdbeSorter *p
a950: 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70  Sorter = pCsr->p
a960: 53 6f 72 74 65 72 3b 0a 20 20 53 6f 72 74 65 72  Sorter;.  Sorter
a970: 54 68 72 65 61 64 20 2a 70 4d 61 69 6e 20 3d 20  Thread *pMain = 
a980: 26 70 53 6f 72 74 65 72 2d 3e 61 54 68 72 65 61  &pSorter->aThrea
a990: 64 5b 30 5d 3b 0a 20 20 76 6f 69 64 20 2a 70 4b  d[0];.  void *pK
a9a0: 65 79 3b 20 69 6e 74 20 6e 4b 65 79 3b 20 20 20  ey; int nKey;   
a9b0: 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65          /* Sorte
a9c0: 72 20 6b 65 79 20 74 6f 20 63 6f 6d 70 61 72 65  r key to compare
a9d0: 20 70 56 61 6c 20 77 69 74 68 20 2a 2f 0a 0a 20   pVal with */.. 
a9e0: 20 70 4b 65 79 20 3d 20 76 64 62 65 53 6f 72 74   pKey = vdbeSort
a9f0: 65 72 52 6f 77 6b 65 79 28 70 53 6f 72 74 65 72  erRowkey(pSorter
aa00: 2c 20 26 6e 4b 65 79 29 3b 0a 20 20 76 64 62 65  , &nKey);.  vdbe
aa10: 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 70 4d  SorterCompare(pM
aa20: 61 69 6e 2c 20 6e 49 67 6e 6f 72 65 2c 20 70 56  ain, nIgnore, pV
aa30: 61 6c 2d 3e 7a 2c 20 70 56 61 6c 2d 3e 6e 2c 20  al->z, pVal->n, 
aa40: 70 4b 65 79 2c 20 6e 4b 65 79 2c 20 70 52 65 73  pKey, nKey, pRes
aa50: 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  );.  return SQLI
aa60: 54 45 5f 4f 4b 3b 0a 7d 0a                       TE_OK;.}.