/ Hex Artifact Content
Login

Artifact 2881297f4acdba5908078c5d7f00635288a1ca08:


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 34 0a 23 65 6e 64 69 66 0a 0a 2f  READ 4.#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 20 20 75   on pList */.  u
0dd0: 38 20 2a 61 4c 69 73 74 4d 65 6d 6f 72 79 3b 20  8 *aListMemory; 
0de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0df0: 2a 20 52 65 63 6f 72 64 73 20 6d 65 6d 6f 72 79  * Records memory
0e00: 20 28 6f 72 20 4e 55 4c 4c 29 20 2a 2f 0a 0a 20   (or NULL) */.. 
0e10: 20 69 6e 74 20 6e 50 4d 41 3b 20 20 20 20 20 20   int nPMA;      
0e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e30: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 50 4d   /* Number of PM
0e40: 41 73 20 63 75 72 72 65 6e 74 6c 79 20 69 6e 20  As currently in 
0e50: 70 54 65 6d 70 31 20 2a 2f 0a 20 20 69 36 34 20  pTemp1 */.  i64 
0e60: 69 54 65 6d 70 31 4f 66 66 3b 20 20 20 20 20 20  iTemp1Off;      
0e70: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
0e80: 66 66 73 65 74 20 74 6f 20 77 72 69 74 65 20 74  ffset to write t
0e90: 6f 20 69 6e 20 70 54 65 6d 70 31 20 2a 2f 0a 20  o in pTemp1 */. 
0ea0: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
0eb0: 54 65 6d 70 31 3b 20 20 20 20 20 20 20 20 20 20  Temp1;          
0ec0: 20 2f 2a 20 46 69 6c 65 20 74 6f 20 77 72 69 74   /* File to writ
0ed0: 65 20 50 4d 41 73 20 74 6f 2c 20 6f 72 20 4e 55  e PMAs to, or NU
0ee0: 4c 4c 20 2a 2f 0a 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a  LL */.};.../*.**
0ef0: 20 4e 4f 54 45 53 20 4f 4e 20 44 41 54 41 20 53   NOTES ON DATA S
0f00: 54 52 55 43 54 55 52 45 20 55 53 45 44 20 46 4f  TRUCTURE USED FO
0f10: 52 20 4e 2d 57 41 59 20 4d 45 52 47 45 53 3a 0a  R N-WAY MERGES:.
0f20: 2a 2a 0a 2a 2a 20 41 73 20 6b 65 79 73 20 61 72  **.** As keys ar
0f30: 65 20 61 64 64 65 64 20 74 6f 20 74 68 65 20 73  e added to the s
0f40: 6f 72 74 65 72 2c 20 74 68 65 79 20 61 72 65 20  orter, they are 
0f50: 77 72 69 74 74 65 6e 20 74 6f 20 64 69 73 6b 20  written to disk 
0f60: 69 6e 20 61 20 73 65 72 69 65 73 0a 2a 2a 20 6f  in a series.** o
0f70: 66 20 73 6f 72 74 65 64 20 70 61 63 6b 65 64 2d  f sorted packed-
0f80: 6d 65 6d 6f 72 79 2d 61 72 72 61 79 73 20 28 50  memory-arrays (P
0f90: 4d 41 73 29 2e 20 54 68 65 20 73 69 7a 65 20 6f  MAs). The size o
0fa0: 66 20 65 61 63 68 20 50 4d 41 20 69 73 20 72 6f  f each PMA is ro
0fb0: 75 67 68 6c 79 0a 2a 2a 20 74 68 65 20 73 61 6d  ughly.** the sam
0fc0: 65 20 61 73 20 74 68 65 20 63 61 63 68 65 2d 73  e as the cache-s
0fd0: 69 7a 65 20 61 6c 6c 6f 77 65 64 20 66 6f 72 20  ize allowed for 
0fe0: 74 65 6d 70 6f 72 61 72 79 20 64 61 74 61 62 61  temporary databa
0ff0: 73 65 73 2e 20 49 6e 20 6f 72 64 65 72 0a 2a 2a  ses. In order.**
1000: 20 74 6f 20 61 6c 6c 6f 77 20 74 68 65 20 63 61   to allow the ca
1010: 6c 6c 65 72 20 74 6f 20 65 78 74 72 61 63 74 20  ller to extract 
1020: 6b 65 79 73 20 66 72 6f 6d 20 74 68 65 20 73 6f  keys from the so
1030: 72 74 65 72 20 69 6e 20 73 6f 72 74 65 64 20 6f  rter in sorted o
1040: 72 64 65 72 2c 0a 2a 2a 20 61 6c 6c 20 50 4d 41  rder,.** all PMA
1050: 73 20 63 75 72 72 65 6e 74 6c 79 20 73 74 6f 72  s currently stor
1060: 65 64 20 6f 6e 20 64 69 73 6b 20 6d 75 73 74 20  ed on disk must 
1070: 62 65 20 6d 65 72 67 65 64 20 74 6f 67 65 74 68  be merged togeth
1080: 65 72 2e 20 54 68 69 73 20 63 6f 6d 6d 65 6e 74  er. This comment
1090: 0a 2a 2a 20 64 65 73 63 72 69 62 65 73 20 74 68  .** describes th
10a0: 65 20 64 61 74 61 20 73 74 72 75 63 74 75 72 65  e data structure
10b0: 20 75 73 65 64 20 74 6f 20 64 6f 20 73 6f 2e 20   used to do so. 
10c0: 54 68 65 20 73 74 72 75 63 74 75 72 65 20 73 75  The structure su
10d0: 70 70 6f 72 74 73 20 0a 2a 2a 20 6d 65 72 67 69  pports .** mergi
10e0: 6e 67 20 61 6e 79 20 6e 75 6d 62 65 72 20 6f 66  ng any number of
10f0: 20 61 72 72 61 79 73 20 69 6e 20 61 20 73 69 6e   arrays in a sin
1100: 67 6c 65 20 70 61 73 73 20 77 69 74 68 20 6e 6f  gle pass with no
1110: 20 72 65 64 75 6e 64 61 6e 74 20 63 6f 6d 70 61   redundant compa
1120: 72 69 73 6f 6e 20 0a 2a 2a 20 6f 70 65 72 61 74  rison .** operat
1130: 69 6f 6e 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ions..**.** The 
1140: 61 49 74 65 72 5b 5d 20 61 72 72 61 79 20 63 6f  aIter[] array co
1150: 6e 74 61 69 6e 73 20 61 6e 20 69 74 65 72 61 74  ntains an iterat
1160: 6f 72 20 66 6f 72 20 65 61 63 68 20 6f 66 20 74  or for each of t
1170: 68 65 20 50 4d 41 73 20 62 65 69 6e 67 20 6d 65  he PMAs being me
1180: 72 67 65 64 2e 0a 2a 2a 20 41 6e 20 61 49 74 65  rged..** An aIte
1190: 72 5b 5d 20 69 74 65 72 61 74 6f 72 20 65 69 74  r[] iterator eit
11a0: 68 65 72 20 70 6f 69 6e 74 73 20 74 6f 20 61 20  her points to a 
11b0: 76 61 6c 69 64 20 6b 65 79 20 6f 72 20 65 6c 73  valid key or els
11c0: 65 20 69 73 20 61 74 20 45 4f 46 2e 20 46 6f 72  e is at EOF. For
11d0: 20 0a 2a 2a 20 74 68 65 20 70 75 72 70 6f 73 65   .** the purpose
11e0: 73 20 6f 66 20 74 68 65 20 70 61 72 61 67 72 61  s of the paragra
11f0: 70 68 73 20 62 65 6c 6f 77 2c 20 77 65 20 61 73  phs below, we as
1200: 73 75 6d 65 20 74 68 61 74 20 74 68 65 20 61 72  sume that the ar
1210: 72 61 79 20 69 73 20 61 63 74 75 61 6c 6c 79 20  ray is actually 
1220: 0a 2a 2a 20 4e 20 65 6c 65 6d 65 6e 74 73 20 69  .** N elements i
1230: 6e 20 73 69 7a 65 2c 20 77 68 65 72 65 20 4e 20  n size, where N 
1240: 69 73 20 74 68 65 20 73 6d 61 6c 6c 65 73 74 20  is the smallest 
1250: 70 6f 77 65 72 20 6f 66 20 32 20 67 72 65 61 74  power of 2 great
1260: 65 72 20 74 6f 20 6f 72 20 65 71 75 61 6c 20 0a  er to or equal .
1270: 2a 2a 20 74 6f 20 74 68 65 20 6e 75 6d 62 65 72  ** to the number
1280: 20 6f 66 20 69 74 65 72 61 74 6f 72 73 20 62 65   of iterators be
1290: 69 6e 67 20 6d 65 72 67 65 64 2e 20 54 68 65 20  ing merged. The 
12a0: 65 78 74 72 61 20 61 49 74 65 72 5b 5d 20 65 6c  extra aIter[] el
12b0: 65 6d 65 6e 74 73 20 61 72 65 20 0a 2a 2a 20 74  ements are .** t
12c0: 72 65 61 74 65 64 20 61 73 20 69 66 20 74 68 65  reated as if the
12d0: 79 20 61 72 65 20 65 6d 70 74 79 20 28 61 6c 77  y are empty (alw
12e0: 61 79 73 20 61 74 20 45 4f 46 29 2e 0a 2a 2a 0a  ays at EOF)..**.
12f0: 2a 2a 20 54 68 65 20 61 54 72 65 65 5b 5d 20 61  ** The aTree[] a
1300: 72 72 61 79 20 69 73 20 61 6c 73 6f 20 4e 20 65  rray is also N e
1310: 6c 65 6d 65 6e 74 73 20 69 6e 20 73 69 7a 65 2e  lements in size.
1320: 20 54 68 65 20 76 61 6c 75 65 20 6f 66 20 4e 20   The value of N 
1330: 69 73 20 73 74 6f 72 65 64 20 69 6e 0a 2a 2a 20  is stored in.** 
1340: 74 68 65 20 56 64 62 65 53 6f 72 74 65 72 2e 6e  the VdbeSorter.n
1350: 54 72 65 65 20 76 61 72 69 61 62 6c 65 2e 0a 2a  Tree variable..*
1360: 2a 0a 2a 2a 20 54 68 65 20 66 69 6e 61 6c 20 28  *.** The final (
1370: 4e 2f 32 29 20 65 6c 65 6d 65 6e 74 73 20 6f 66  N/2) elements of
1380: 20 61 54 72 65 65 5b 5d 20 63 6f 6e 74 61 69 6e   aTree[] contain
1390: 20 74 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20   the results of 
13a0: 63 6f 6d 70 61 72 69 6e 67 0a 2a 2a 20 70 61 69  comparing.** pai
13b0: 72 73 20 6f 66 20 69 74 65 72 61 74 6f 72 20 6b  rs of iterator k
13c0: 65 79 73 20 74 6f 67 65 74 68 65 72 2e 20 45 6c  eys together. El
13d0: 65 6d 65 6e 74 20 69 20 63 6f 6e 74 61 69 6e 73  ement i contains
13e0: 20 74 68 65 20 72 65 73 75 6c 74 20 6f 66 20 0a   the result of .
13f0: 2a 2a 20 63 6f 6d 70 61 72 69 6e 67 20 61 49 74  ** comparing aIt
1400: 65 72 5b 32 2a 69 2d 4e 5d 20 61 6e 64 20 61 49  er[2*i-N] and aI
1410: 74 65 72 5b 32 2a 69 2d 4e 2b 31 5d 2e 20 57 68  ter[2*i-N+1]. Wh
1420: 69 63 68 65 76 65 72 20 6b 65 79 20 69 73 20 73  ichever key is s
1430: 6d 61 6c 6c 65 72 2c 20 74 68 65 0a 2a 2a 20 61  maller, the.** a
1440: 54 72 65 65 20 65 6c 65 6d 65 6e 74 20 69 73 20  Tree element is 
1450: 73 65 74 20 74 6f 20 74 68 65 20 69 6e 64 65 78  set to the index
1460: 20 6f 66 20 69 74 2e 20 0a 2a 2a 0a 2a 2a 20 46   of it. .**.** F
1470: 6f 72 20 74 68 65 20 70 75 72 70 6f 73 65 73 20  or the purposes 
1480: 6f 66 20 74 68 69 73 20 63 6f 6d 70 61 72 69 73  of this comparis
1490: 6f 6e 2c 20 45 4f 46 20 69 73 20 63 6f 6e 73 69  on, EOF is consi
14a0: 64 65 72 65 64 20 67 72 65 61 74 65 72 20 74 68  dered greater th
14b0: 61 6e 20 61 6e 79 0a 2a 2a 20 6f 74 68 65 72 20  an any.** other 
14c0: 6b 65 79 20 76 61 6c 75 65 2e 20 49 66 20 74 68  key value. If th
14d0: 65 20 6b 65 79 73 20 61 72 65 20 65 71 75 61 6c  e keys are equal
14e0: 20 28 6f 6e 6c 79 20 70 6f 73 73 69 62 6c 65 20   (only possible 
14f0: 77 69 74 68 20 74 77 6f 20 45 4f 46 0a 2a 2a 20  with two EOF.** 
1500: 76 61 6c 75 65 73 29 2c 20 69 74 20 64 6f 65 73  values), it does
1510: 6e 27 74 20 6d 61 74 74 65 72 20 77 68 69 63 68  n't matter which
1520: 20 69 6e 64 65 78 20 69 73 20 73 74 6f 72 65 64   index is stored
1530: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 28 4e 2f 34  ..**.** The (N/4
1540: 29 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20 61 54  ) elements of aT
1550: 72 65 65 5b 5d 20 74 68 61 74 20 70 72 65 63 65  ree[] that prece
1560: 64 65 20 74 68 65 20 66 69 6e 61 6c 20 28 4e 2f  de the final (N/
1570: 32 29 20 64 65 73 63 72 69 62 65 64 20 0a 2a 2a  2) described .**
1580: 20 61 62 6f 76 65 20 63 6f 6e 74 61 69 6e 73 20   above contains 
1590: 74 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65  the index of the
15a0: 20 73 6d 61 6c 6c 65 73 74 20 6f 66 20 65 61 63   smallest of eac
15b0: 68 20 62 6c 6f 63 6b 20 6f 66 20 34 20 69 74 65  h block of 4 ite
15c0: 72 61 74 6f 72 73 2e 0a 2a 2a 20 41 6e 64 20 73  rators..** And s
15d0: 6f 20 6f 6e 2e 20 53 6f 20 74 68 61 74 20 61 54  o on. So that aT
15e0: 72 65 65 5b 31 5d 20 63 6f 6e 74 61 69 6e 73 20  ree[1] contains 
15f0: 74 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65  the index of the
1600: 20 69 74 65 72 61 74 6f 72 20 74 68 61 74 20 0a   iterator that .
1610: 2a 2a 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69  ** currently poi
1620: 6e 74 73 20 74 6f 20 74 68 65 20 73 6d 61 6c 6c  nts to the small
1630: 65 73 74 20 6b 65 79 20 76 61 6c 75 65 2e 20 61  est key value. a
1640: 54 72 65 65 5b 30 5d 20 69 73 20 75 6e 75 73 65  Tree[0] is unuse
1650: 64 2e 0a 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65  d..**.** Example
1660: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 49 74 65  :.**.**     aIte
1670: 72 5b 30 5d 20 2d 3e 20 42 61 6e 61 6e 61 0a 2a  r[0] -> Banana.*
1680: 2a 20 20 20 20 20 61 49 74 65 72 5b 31 5d 20 2d  *     aIter[1] -
1690: 3e 20 46 65 69 6a 6f 61 0a 2a 2a 20 20 20 20 20  > Feijoa.**     
16a0: 61 49 74 65 72 5b 32 5d 20 2d 3e 20 45 6c 64 65  aIter[2] -> Elde
16b0: 72 62 65 72 72 79 0a 2a 2a 20 20 20 20 20 61 49  rberry.**     aI
16c0: 74 65 72 5b 33 5d 20 2d 3e 20 43 75 72 72 61 6e  ter[3] -> Curran
16d0: 74 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 34  t.**     aIter[4
16e0: 5d 20 2d 3e 20 47 72 61 70 65 66 72 75 69 74 0a  ] -> Grapefruit.
16f0: 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 35 5d 20  **     aIter[5] 
1700: 2d 3e 20 41 70 70 6c 65 0a 2a 2a 20 20 20 20 20  -> Apple.**     
1710: 61 49 74 65 72 5b 36 5d 20 2d 3e 20 44 75 72 69  aIter[6] -> Duri
1720: 61 6e 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b  an.**     aIter[
1730: 37 5d 20 2d 3e 20 45 4f 46 0a 2a 2a 0a 2a 2a 20  7] -> EOF.**.** 
1740: 20 20 20 20 61 54 72 65 65 5b 5d 20 3d 20 7b 20      aTree[] = { 
1750: 58 2c 20 35 20 20 20 30 2c 20 35 20 20 20 20 30  X, 5   0, 5    0
1760: 2c 20 33 2c 20 35 2c 20 36 20 7d 0a 2a 2a 0a 2a  , 3, 5, 6 }.**.*
1770: 2a 20 54 68 65 20 63 75 72 72 65 6e 74 20 65 6c  * The current el
1780: 65 6d 65 6e 74 20 69 73 20 22 41 70 70 6c 65 22  ement is "Apple"
1790: 20 28 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74   (the value of t
17a0: 68 65 20 6b 65 79 20 69 6e 64 69 63 61 74 65 64  he key indicated
17b0: 20 62 79 20 0a 2a 2a 20 69 74 65 72 61 74 6f 72   by .** iterator
17c0: 20 35 29 2e 20 57 68 65 6e 20 74 68 65 20 4e 65   5). When the Ne
17d0: 78 74 28 29 20 6f 70 65 72 61 74 69 6f 6e 20 69  xt() operation i
17e0: 73 20 69 6e 76 6f 6b 65 64 2c 20 69 74 65 72 61  s invoked, itera
17f0: 74 6f 72 20 35 20 77 69 6c 6c 0a 2a 2a 20 62 65  tor 5 will.** be
1800: 20 61 64 76 61 6e 63 65 64 20 74 6f 20 74 68 65   advanced to the
1810: 20 6e 65 78 74 20 6b 65 79 20 69 6e 20 69 74 73   next key in its
1820: 20 73 65 67 6d 65 6e 74 2e 20 53 61 79 20 74 68   segment. Say th
1830: 65 20 6e 65 78 74 20 6b 65 79 20 69 73 0a 2a 2a  e next key is.**
1840: 20 22 45 67 67 70 6c 61 6e 74 22 3a 0a 2a 2a 0a   "Eggplant":.**.
1850: 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 35 5d 20  **     aIter[5] 
1860: 2d 3e 20 45 67 67 70 6c 61 6e 74 0a 2a 2a 0a 2a  -> Eggplant.**.*
1870: 2a 20 54 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  * The contents o
1880: 66 20 61 54 72 65 65 5b 5d 20 61 72 65 20 75 70  f aTree[] are up
1890: 64 61 74 65 64 20 66 69 72 73 74 20 62 79 20 63  dated first by c
18a0: 6f 6d 70 61 72 69 6e 67 20 74 68 65 20 6e 65 77  omparing the new
18b0: 20 69 74 65 72 61 74 6f 72 0a 2a 2a 20 35 20 6b   iterator.** 5 k
18c0: 65 79 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e  ey to the curren
18d0: 74 20 6b 65 79 20 6f 66 20 69 74 65 72 61 74 6f  t key of iterato
18e0: 72 20 34 20 28 73 74 69 6c 6c 20 22 47 72 61 70  r 4 (still "Grap
18f0: 65 66 72 75 69 74 22 29 2e 20 54 68 65 20 69 74  efruit"). The it
1900: 65 72 61 74 6f 72 0a 2a 2a 20 35 20 76 61 6c 75  erator.** 5 valu
1910: 65 20 69 73 20 73 74 69 6c 6c 20 73 6d 61 6c 6c  e is still small
1920: 65 72 2c 20 73 6f 20 61 54 72 65 65 5b 36 5d 20  er, so aTree[6] 
1930: 69 73 20 73 65 74 20 74 6f 20 35 2e 20 41 6e 64  is set to 5. And
1940: 20 73 6f 20 6f 6e 20 75 70 20 74 68 65 20 74 72   so on up the tr
1950: 65 65 2e 0a 2a 2a 20 54 68 65 20 76 61 6c 75 65  ee..** The value
1960: 20 6f 66 20 69 74 65 72 61 74 6f 72 20 36 20 2d   of iterator 6 -
1970: 20 22 44 75 72 69 61 6e 22 20 2d 20 69 73 20 6e   "Durian" - is n
1980: 6f 77 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20  ow smaller than 
1990: 74 68 61 74 20 6f 66 20 69 74 65 72 61 74 6f 72  that of iterator
19a0: 0a 2a 2a 20 35 2c 20 73 6f 20 61 54 72 65 65 5b  .** 5, so aTree[
19b0: 33 5d 20 69 73 20 73 65 74 20 74 6f 20 36 2e 20  3] is set to 6. 
19c0: 4b 65 79 20 30 20 69 73 20 73 6d 61 6c 6c 65 72  Key 0 is smaller
19d0: 20 74 68 61 6e 20 6b 65 79 20 36 20 28 42 61 6e   than key 6 (Ban
19e0: 61 6e 61 3c 44 75 72 69 61 6e 29 2c 0a 2a 2a 20  ana<Durian),.** 
19f0: 73 6f 20 74 68 65 20 76 61 6c 75 65 20 77 72 69  so the value wri
1a00: 74 74 65 6e 20 69 6e 74 6f 20 65 6c 65 6d 65 6e  tten into elemen
1a10: 74 20 31 20 6f 66 20 74 68 65 20 61 72 72 61 79  t 1 of the array
1a20: 20 69 73 20 30 2e 20 41 73 20 66 6f 6c 6c 6f 77   is 0. As follow
1a30: 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 54 72  s:.**.**     aTr
1a40: 65 65 5b 5d 20 3d 20 7b 20 58 2c 20 30 20 20 20  ee[] = { X, 0   
1a50: 30 2c 20 36 20 20 20 20 30 2c 20 33 2c 20 35 2c  0, 6    0, 3, 5,
1a60: 20 36 20 7d 0a 2a 2a 0a 2a 2a 20 49 6e 20 6f 74   6 }.**.** In ot
1a70: 68 65 72 20 77 6f 72 64 73 2c 20 65 61 63 68 20  her words, each 
1a80: 74 69 6d 65 20 77 65 20 61 64 76 61 6e 63 65 20  time we advance 
1a90: 74 6f 20 74 68 65 20 6e 65 78 74 20 73 6f 72 74  to the next sort
1aa0: 65 72 20 65 6c 65 6d 65 6e 74 2c 20 6c 6f 67 32  er element, log2
1ab0: 28 4e 29 0a 2a 2a 20 6b 65 79 20 63 6f 6d 70 61  (N).** key compa
1ac0: 72 69 73 6f 6e 20 6f 70 65 72 61 74 69 6f 6e 73  rison operations
1ad0: 20 61 72 65 20 72 65 71 75 69 72 65 64 2c 20 77   are required, w
1ae0: 68 65 72 65 20 4e 20 69 73 20 74 68 65 20 6e 75  here N is the nu
1af0: 6d 62 65 72 20 6f 66 20 73 65 67 6d 65 6e 74 73  mber of segments
1b00: 0a 2a 2a 20 62 65 69 6e 67 20 6d 65 72 67 65 64  .** being merged
1b10: 20 28 72 6f 75 6e 64 65 64 20 75 70 20 74 6f 20   (rounded up to 
1b20: 74 68 65 20 6e 65 78 74 20 70 6f 77 65 72 20 6f  the next power o
1b30: 66 20 32 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  f 2)..*/.struct 
1b40: 53 6f 72 74 65 72 4d 65 72 67 65 72 20 7b 0a 20  SorterMerger {. 
1b50: 20 69 6e 74 20 6e 54 72 65 65 3b 20 20 20 20 20   int nTree;     
1b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b70: 20 2f 2a 20 55 73 65 64 20 73 69 7a 65 20 6f 66   /* Used size of
1b80: 20 61 54 72 65 65 2f 61 49 74 65 72 20 28 70 6f   aTree/aIter (po
1b90: 77 65 72 20 6f 66 20 32 29 20 2a 2f 0a 20 20 69  wer of 2) */.  i
1ba0: 6e 74 20 2a 61 54 72 65 65 3b 20 20 20 20 20 20  nt *aTree;      
1bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1bc0: 2a 20 43 75 72 72 65 6e 74 20 73 74 61 74 65 20  * Current state 
1bd0: 6f 66 20 69 6e 63 72 65 6d 65 6e 74 61 6c 20 6d  of incremental m
1be0: 65 72 67 65 20 2a 2f 0a 20 20 56 64 62 65 53 6f  erge */.  VdbeSo
1bf0: 72 74 65 72 49 74 65 72 20 2a 61 49 74 65 72 3b  rterIter *aIter;
1c00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72            /* Arr
1c10: 61 79 20 6f 66 20 69 74 65 72 61 74 6f 72 73 20  ay of iterators 
1c20: 74 6f 20 6d 65 72 67 65 20 64 61 74 61 20 66 72  to merge data fr
1c30: 6f 6d 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  om */.};../*.** 
1c40: 4d 61 69 6e 20 73 6f 72 74 65 72 20 73 74 72 75  Main sorter stru
1c50: 63 74 75 72 65 2e 20 41 20 73 69 6e 67 6c 65 20  cture. A single 
1c60: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73  instance of this
1c70: 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f   is allocated fo
1c80: 72 20 65 61 63 68 20 0a 2a 2a 20 73 6f 72 74 65  r each .** sorte
1c90: 72 20 63 75 72 73 6f 72 20 63 72 65 61 74 65 64  r cursor created
1ca0: 20 62 79 20 74 68 65 20 56 44 42 45 2e 0a 2a 2f   by the VDBE..*/
1cb0: 0a 73 74 72 75 63 74 20 56 64 62 65 53 6f 72 74  .struct VdbeSort
1cc0: 65 72 20 7b 0a 20 20 69 6e 74 20 6e 49 6e 4d 65  er {.  int nInMe
1cd0: 6d 6f 72 79 3b 20 20 20 20 20 20 20 20 20 20 20  mory;           
1ce0: 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e         /* Curren
1cf0: 74 20 73 69 7a 65 20 6f 66 20 70 52 65 63 6f 72  t size of pRecor
1d00: 64 20 6c 69 73 74 20 61 73 20 50 4d 41 20 2a 2f  d list as PMA */
1d10: 0a 20 20 69 6e 74 20 6d 6e 50 6d 61 53 69 7a 65  .  int mnPmaSize
1d20: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1d30: 20 20 20 2f 2a 20 4d 69 6e 69 6d 75 6d 20 50 4d     /* Minimum PM
1d40: 41 20 73 69 7a 65 2c 20 69 6e 20 62 79 74 65 73  A size, in bytes
1d50: 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 50 6d 61 53   */.  int mxPmaS
1d60: 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ize;            
1d70: 20 20 20 20 20 20 2f 2a 20 4d 61 78 69 6d 75 6d        /* Maximum
1d80: 20 50 4d 41 20 73 69 7a 65 2c 20 69 6e 20 62 79   PMA size, in by
1d90: 74 65 73 2e 20 20 30 3d 3d 6e 6f 20 6c 69 6d 69  tes.  0==no limi
1da0: 74 20 2a 2f 0a 20 20 69 6e 74 20 62 55 73 65 50  t */.  int bUseP
1db0: 4d 41 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  MA;             
1dc0: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69         /* True i
1dd0: 66 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 50 4d  f one or more PM
1de0: 41 73 20 63 72 65 61 74 65 64 20 2a 2f 0a 20 20  As created */.  
1df0: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 52  SorterRecord *pR
1e00: 65 63 6f 72 64 3b 20 20 20 20 20 20 20 20 20 20  ecord;          
1e10: 2f 2a 20 48 65 61 64 20 6f 66 20 69 6e 2d 6d 65  /* Head of in-me
1e20: 6d 6f 72 79 20 72 65 63 6f 72 64 20 6c 69 73 74  mory record list
1e30: 20 2a 2f 0a 20 20 53 6f 72 74 65 72 4d 65 72 67   */.  SorterMerg
1e40: 65 72 20 2a 70 4d 65 72 67 65 72 3b 20 20 20 20  er *pMerger;    
1e50: 20 20 20 20 20 20 2f 2a 20 46 6f 72 20 66 69 6e        /* For fin
1e60: 61 6c 20 6d 65 72 67 65 20 6f 66 20 50 4d 41 73  al merge of PMAs
1e70: 20 28 62 79 20 63 61 6c 6c 65 72 29 20 2a 2f 20   (by caller) */ 
1e80: 0a 20 20 75 38 20 2a 61 4d 65 6d 6f 72 79 3b 20  .  u8 *aMemory; 
1e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ea0: 20 20 20 2f 2a 20 42 6c 6f 63 6b 20 6f 66 20 6d     /* Block of m
1eb0: 65 6d 6f 72 79 20 74 6f 20 61 6c 6c 6f 63 20 72  emory to alloc r
1ec0: 65 63 6f 72 64 73 20 66 72 6f 6d 20 2a 2f 0a 20  ecords from */. 
1ed0: 20 69 6e 74 20 69 4d 65 6d 6f 72 79 3b 20 20 20   int iMemory;   
1ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ef0: 20 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20 66 69   /* Offset of fi
1f00: 72 73 74 20 66 72 65 65 20 62 79 74 65 20 69 6e  rst free byte in
1f10: 20 61 4d 65 6d 6f 72 79 20 2a 2f 0a 20 20 69 6e   aMemory */.  in
1f20: 74 20 6e 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20  t nMemory;      
1f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1f40: 20 53 69 7a 65 20 6f 66 20 61 4d 65 6d 6f 72 79   Size of aMemory
1f50: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 6e 20 62   allocation in b
1f60: 79 74 65 73 20 2a 2f 0a 20 20 53 6f 72 74 65 72  ytes */.  Sorter
1f70: 54 68 72 65 61 64 20 61 54 68 72 65 61 64 5b 53  Thread aThread[S
1f80: 51 4c 49 54 45 5f 4d 41 58 5f 53 4f 52 54 45 52  QLITE_MAX_SORTER
1f90: 5f 54 48 52 45 41 44 5d 3b 0a 7d 3b 0a 0a 2f 2a  _THREAD];.};../*
1fa0: 0a 2a 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e  .** The followin
1fb0: 67 20 74 79 70 65 20 69 73 20 61 6e 20 69 74 65  g type is an ite
1fc0: 72 61 74 6f 72 20 66 6f 72 20 61 20 50 4d 41 2e  rator for a PMA.
1fd0: 20 49 74 20 63 61 63 68 65 73 20 74 68 65 20 63   It caches the c
1fe0: 75 72 72 65 6e 74 20 6b 65 79 20 69 6e 20 0a 2a  urrent key in .*
1ff0: 2a 20 76 61 72 69 61 62 6c 65 73 20 6e 4b 65 79  * variables nKey
2000: 2f 61 4b 65 79 2e 20 49 66 20 74 68 65 20 69 74  /aKey. If the it
2010: 65 72 61 74 6f 72 20 69 73 20 61 74 20 45 4f 46  erator is at EOF
2020: 2c 20 70 46 69 6c 65 3d 3d 30 2e 0a 2a 2f 0a 73  , pFile==0..*/.s
2030: 74 72 75 63 74 20 56 64 62 65 53 6f 72 74 65 72  truct VdbeSorter
2040: 49 74 65 72 20 7b 0a 20 20 69 36 34 20 69 52 65  Iter {.  i64 iRe
2050: 61 64 4f 66 66 3b 20 20 20 20 20 20 20 20 20 20  adOff;          
2060: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72           /* Curr
2070: 65 6e 74 20 72 65 61 64 20 6f 66 66 73 65 74 20  ent read offset 
2080: 2a 2f 0a 20 20 69 36 34 20 69 45 6f 66 3b 20 20  */.  i64 iEof;  
2090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20a0: 20 20 20 20 20 2f 2a 20 31 20 62 79 74 65 20 70       /* 1 byte p
20b0: 61 73 74 20 45 4f 46 20 66 6f 72 20 74 68 69 73  ast EOF for this
20c0: 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69   iterator */.  i
20d0: 6e 74 20 6e 41 6c 6c 6f 63 3b 20 20 20 20 20 20  nt nAlloc;      
20e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
20f0: 2a 20 42 79 74 65 73 20 6f 66 20 73 70 61 63 65  * Bytes of space
2100: 20 61 74 20 61 41 6c 6c 6f 63 20 2a 2f 0a 20 20   at aAlloc */.  
2110: 69 6e 74 20 6e 4b 65 79 3b 20 20 20 20 20 20 20  int nKey;       
2120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2130: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74  /* Number of byt
2140: 65 73 20 69 6e 20 6b 65 79 20 2a 2f 0a 20 20 73  es in key */.  s
2150: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
2160: 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  le;            /
2170: 2a 20 46 69 6c 65 20 69 74 65 72 61 74 6f 72 20  * File iterator 
2180: 69 73 20 72 65 61 64 69 6e 67 20 66 72 6f 6d 20  is reading from 
2190: 2a 2f 0a 20 20 75 38 20 2a 61 41 6c 6c 6f 63 3b  */.  u8 *aAlloc;
21a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21b0: 20 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65       /* Allocate
21c0: 64 20 73 70 61 63 65 20 2a 2f 0a 20 20 75 38 20  d space */.  u8 
21d0: 2a 61 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20  *aKey;          
21e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
21f0: 50 6f 69 6e 74 65 72 20 74 6f 20 63 75 72 72 65  Pointer to curre
2200: 6e 74 20 6b 65 79 20 2a 2f 0a 20 20 75 38 20 2a  nt key */.  u8 *
2210: 61 42 75 66 66 65 72 3b 20 20 20 20 20 20 20 20  aBuffer;        
2220: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
2230: 75 72 72 65 6e 74 20 72 65 61 64 20 62 75 66 66  urrent read buff
2240: 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66  er */.  int nBuf
2250: 66 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20  fer;            
2260: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
2270: 6f 66 20 72 65 61 64 20 62 75 66 66 65 72 20 69  of read buffer i
2280: 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 75 38 20  n bytes */.  u8 
2290: 2a 61 4d 61 70 3b 20 20 20 20 20 20 20 20 20 20  *aMap;          
22a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
22b0: 50 6f 69 6e 74 65 72 20 74 6f 20 6d 61 70 70 69  Pointer to mappi
22c0: 6e 67 20 6f 66 20 65 6e 74 69 72 65 20 66 69 6c  ng of entire fil
22d0: 65 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41  e */.};../*.** A
22e0: 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68  n instance of th
22f0: 69 73 20 73 74 72 75 63 74 75 72 65 20 69 73 20  is structure is 
2300: 75 73 65 64 20 74 6f 20 6f 72 67 61 6e 69 7a 65  used to organize
2310: 20 74 68 65 20 73 74 72 65 61 6d 20 6f 66 20 72   the stream of r
2320: 65 63 6f 72 64 73 0a 2a 2a 20 62 65 69 6e 67 20  ecords.** being 
2330: 77 72 69 74 74 65 6e 20 74 6f 20 66 69 6c 65 73  written to files
2340: 20 62 79 20 74 68 65 20 6d 65 72 67 65 2d 73 6f   by the merge-so
2350: 72 74 20 63 6f 64 65 20 69 6e 74 6f 20 61 6c 69  rt code into ali
2360: 67 6e 65 64 2c 20 70 61 67 65 2d 73 69 7a 65 64  gned, page-sized
2370: 0a 2a 2a 20 62 6c 6f 63 6b 73 2e 20 20 44 6f 69  .** blocks.  Doi
2380: 6e 67 20 61 6c 6c 20 49 2f 4f 20 69 6e 20 61 6c  ng all I/O in al
2390: 69 67 6e 65 64 20 70 61 67 65 2d 73 69 7a 65 64  igned page-sized
23a0: 20 62 6c 6f 63 6b 73 20 68 65 6c 70 73 20 49 2f   blocks helps I/
23b0: 4f 20 74 6f 20 67 6f 0a 2a 2a 20 66 61 73 74 65  O to go.** faste
23c0: 72 20 6f 6e 20 6d 61 6e 79 20 6f 70 65 72 61 74  r on many operat
23d0: 69 6e 67 20 73 79 73 74 65 6d 73 2e 0a 2a 2f 0a  ing systems..*/.
23e0: 73 74 72 75 63 74 20 46 69 6c 65 57 72 69 74 65  struct FileWrite
23f0: 72 20 7b 0a 20 20 69 6e 74 20 65 46 57 45 72 72  r {.  int eFWErr
2400: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
2410: 20 20 20 20 20 20 2f 2a 20 4e 6f 6e 2d 7a 65 72        /* Non-zer
2420: 6f 20 69 66 20 69 6e 20 61 6e 20 65 72 72 6f 72  o if in an error
2430: 20 73 74 61 74 65 20 2a 2f 0a 20 20 75 38 20 2a   state */.  u8 *
2440: 61 42 75 66 66 65 72 3b 20 20 20 20 20 20 20 20  aBuffer;        
2450: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
2460: 6f 69 6e 74 65 72 20 74 6f 20 77 72 69 74 65 20  ointer to write 
2470: 62 75 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74 20  buffer */.  int 
2480: 6e 42 75 66 66 65 72 3b 20 20 20 20 20 20 20 20  nBuffer;        
2490: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
24a0: 69 7a 65 20 6f 66 20 77 72 69 74 65 20 62 75 66  ize of write buf
24b0: 66 65 72 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  fer in bytes */.
24c0: 20 20 69 6e 74 20 69 42 75 66 53 74 61 72 74 3b    int iBufStart;
24d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24e0: 20 20 2f 2a 20 46 69 72 73 74 20 62 79 74 65 20    /* First byte 
24f0: 6f 66 20 62 75 66 66 65 72 20 74 6f 20 77 72 69  of buffer to wri
2500: 74 65 20 2a 2f 0a 20 20 69 6e 74 20 69 42 75 66  te */.  int iBuf
2510: 45 6e 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  End;            
2520: 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 73 74 20          /* Last 
2530: 62 79 74 65 20 6f 66 20 62 75 66 66 65 72 20 74  byte of buffer t
2540: 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 69 36 34  o write */.  i64
2550: 20 69 57 72 69 74 65 4f 66 66 3b 20 20 20 20 20   iWriteOff;     
2560: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2570: 4f 66 66 73 65 74 20 6f 66 20 73 74 61 72 74 20  Offset of start 
2580: 6f 66 20 62 75 66 66 65 72 20 69 6e 20 66 69 6c  of buffer in fil
2590: 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66  e */.  sqlite3_f
25a0: 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20 20 20  ile *pFile;     
25b0: 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 74         /* File t
25c0: 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a 7d 3b  o write to */.};
25d0: 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 74 72 75 63 74  ../*.** A struct
25e0: 75 72 65 20 74 6f 20 73 74 6f 72 65 20 61 20 73  ure to store a s
25f0: 69 6e 67 6c 65 20 72 65 63 6f 72 64 2e 20 41 6c  ingle record. Al
2600: 6c 20 69 6e 2d 6d 65 6d 6f 72 79 20 72 65 63 6f  l in-memory reco
2610: 72 64 73 20 61 72 65 20 63 6f 6e 6e 65 63 74 65  rds are connecte
2620: 64 0a 2a 2a 20 74 6f 67 65 74 68 65 72 20 69 6e  d.** together in
2630: 74 6f 20 61 20 6c 69 6e 6b 65 64 20 6c 69 73 74  to a linked list
2640: 20 68 65 61 64 65 64 20 61 74 20 56 64 62 65 53   headed at VdbeS
2650: 6f 72 74 65 72 2e 70 52 65 63 6f 72 64 2e 0a 2a  orter.pRecord..*
2660: 2a 0a 2a 2a 20 48 6f 77 20 74 68 65 20 6c 69 6e  *.** How the lin
2670: 6b 65 64 20 6c 69 73 74 20 69 73 20 63 6f 6e 6e  ked list is conn
2680: 65 63 74 65 64 20 64 65 70 65 6e 64 73 20 6f 6e  ected depends on
2690: 20 68 6f 77 20 6d 65 6d 6f 72 79 20 69 73 20 62   how memory is b
26a0: 65 69 6e 67 20 6d 61 6e 61 67 65 64 0a 2a 2a 20  eing managed.** 
26b0: 62 79 20 74 68 69 73 20 6d 6f 64 75 6c 65 2e 20  by this module. 
26c0: 49 66 20 75 73 69 6e 67 20 61 20 73 65 70 61 72  If using a separ
26d0: 61 74 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66  ate allocation f
26e0: 6f 72 20 65 61 63 68 20 69 6e 2d 6d 65 6d 6f 72  or each in-memor
26f0: 79 20 72 65 63 6f 72 64 0a 2a 2a 20 28 56 64 62  y record.** (Vdb
2700: 65 53 6f 72 74 65 72 2e 61 4d 65 6d 6f 72 79 3d  eSorter.aMemory=
2710: 3d 30 29 2c 20 74 68 65 6e 20 74 68 65 20 6c 69  =0), then the li
2720: 73 74 20 69 73 20 61 6c 77 61 79 73 20 63 6f 6e  st is always con
2730: 6e 65 63 74 65 64 20 75 73 69 6e 67 20 74 68 65  nected using the
2740: 0a 2a 2a 20 53 6f 72 74 65 72 52 65 63 6f 72 64  .** SorterRecord
2750: 2e 75 2e 70 4e 65 78 74 20 70 6f 69 6e 74 65 72  .u.pNext pointer
2760: 73 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 69 66 20  s..**.** Or, if 
2770: 75 73 69 6e 67 20 74 68 65 20 73 69 6e 67 6c 65  using the single
2780: 20 6c 61 72 67 65 20 61 6c 6c 6f 63 61 74 69 6f   large allocatio
2790: 6e 20 6d 65 74 68 6f 64 20 28 56 64 62 65 53 6f  n method (VdbeSo
27a0: 72 74 65 72 2e 61 4d 65 6d 6f 72 79 21 3d 30 29  rter.aMemory!=0)
27b0: 2c 0a 2a 2a 20 74 68 65 6e 20 77 68 69 6c 65 20  ,.** then while 
27c0: 72 65 63 6f 72 64 73 20 61 72 65 20 62 65 69 6e  records are bein
27d0: 67 20 61 63 63 75 6d 75 6c 61 74 65 64 20 74 68  g accumulated th
27e0: 65 20 6c 69 73 74 20 69 73 20 6c 69 6e 6b 65 64  e list is linked
27f0: 20 75 73 69 6e 67 20 74 68 65 0a 2a 2a 20 53 6f   using the.** So
2800: 72 74 65 72 52 65 63 6f 72 64 2e 75 2e 69 4e 65  rterRecord.u.iNe
2810: 78 74 20 6f 66 66 73 65 74 2e 20 54 68 69 73 20  xt offset. This 
2820: 69 73 20 62 65 63 61 75 73 65 20 74 68 65 20 61  is because the a
2830: 4d 65 6d 6f 72 79 5b 5d 20 61 72 72 61 79 20 6d  Memory[] array m
2840: 61 79 0a 2a 2a 20 62 65 20 73 71 6c 69 74 65 33  ay.** be sqlite3
2850: 52 65 61 6c 6c 6f 63 28 29 65 64 20 77 68 69 6c  Realloc()ed whil
2860: 65 20 72 65 63 6f 72 64 73 20 61 72 65 20 62 65  e records are be
2870: 69 6e 67 20 61 63 63 75 6d 75 6c 61 74 65 64 2e  ing accumulated.
2880: 20 4f 6e 63 65 20 74 68 65 20 56 4d 0a 2a 2a 20   Once the VM.** 
2890: 68 61 73 20 66 69 6e 69 73 68 65 64 20 70 61 73  has finished pas
28a0: 73 69 6e 67 20 72 65 63 6f 72 64 73 20 74 6f 20  sing records to 
28b0: 74 68 65 20 73 6f 72 74 65 72 2c 20 6f 72 20 77  the sorter, or w
28c0: 68 65 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72  hen the in-memor
28d0: 79 20 62 75 66 66 65 72 0a 2a 2a 20 69 73 20 66  y buffer.** is f
28e0: 75 6c 6c 2c 20 74 68 65 20 6c 69 73 74 20 69 73  ull, the list is
28f0: 20 73 6f 72 74 65 64 2e 20 41 73 20 70 61 72 74   sorted. As part
2900: 20 6f 66 20 74 68 65 20 73 6f 72 74 69 6e 67 20   of the sorting 
2910: 70 72 6f 63 65 73 73 2c 20 69 74 20 69 73 0a 2a  process, it is.*
2920: 2a 20 63 6f 6e 76 65 72 74 65 64 20 74 6f 20 75  * converted to u
2930: 73 65 20 74 68 65 20 53 6f 72 74 65 72 52 65 63  se the SorterRec
2940: 6f 72 64 2e 75 2e 70 4e 65 78 74 20 70 6f 69 6e  ord.u.pNext poin
2950: 74 65 72 73 2e 20 53 65 65 20 66 75 6e 63 74 69  ters. See functi
2960: 6f 6e 0a 2a 2a 20 76 64 62 65 53 6f 72 74 65 72  on.** vdbeSorter
2970: 53 6f 72 74 28 29 20 66 6f 72 20 64 65 74 61 69  Sort() for detai
2980: 6c 73 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 53 6f  ls..*/.struct So
2990: 72 74 65 72 52 65 63 6f 72 64 20 7b 0a 20 20 69  rterRecord {.  i
29a0: 6e 74 20 6e 56 61 6c 3b 0a 20 20 75 6e 69 6f 6e  nt nVal;.  union
29b0: 20 7b 0a 20 20 20 20 53 6f 72 74 65 72 52 65 63   {.    SorterRec
29c0: 6f 72 64 20 2a 70 4e 65 78 74 3b 20 20 20 20 20  ord *pNext;     
29d0: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
29e0: 74 6f 20 6e 65 78 74 20 72 65 63 6f 72 64 20 69  to next record i
29f0: 6e 20 6c 69 73 74 20 2a 2f 0a 20 20 20 20 69 6e  n list */.    in
2a00: 74 20 69 4e 65 78 74 3b 20 20 20 20 20 20 20 20  t iNext;        
2a10: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
2a20: 66 66 73 65 74 20 77 69 74 68 69 6e 20 61 4d 65  ffset within aMe
2a30: 6d 6f 72 79 20 6f 66 20 6e 65 78 74 20 72 65 63  mory of next rec
2a40: 6f 72 64 20 2a 2f 0a 20 20 7d 20 75 3b 0a 7d 3b  ord */.  } u;.};
2a50: 0a 0a 2f 2a 20 52 65 74 75 72 6e 20 61 20 70 6f  ../* Return a po
2a60: 69 6e 74 65 72 20 74 6f 20 74 68 65 20 62 75 66  inter to the buf
2a70: 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74  fer containing t
2a80: 68 65 20 72 65 63 6f 72 64 20 64 61 74 61 20 66  he record data f
2a90: 6f 72 20 53 6f 72 74 65 72 52 65 63 6f 72 64 0a  or SorterRecord.
2aa0: 2a 2a 20 6f 62 6a 65 63 74 20 70 2e 20 53 68 6f  ** object p. Sho
2ab0: 75 6c 64 20 62 65 20 75 73 65 64 20 61 73 20 69  uld be used as i
2ac0: 66 3a 0a 2a 2a 0a 2a 2a 20 20 20 76 6f 69 64 20  f:.**.**   void 
2ad0: 2a 53 52 56 41 4c 28 53 6f 72 74 65 72 52 65 63  *SRVAL(SorterRec
2ae0: 6f 72 64 20 2a 70 29 20 7b 20 72 65 74 75 72 6e  ord *p) { return
2af0: 20 28 76 6f 69 64 2a 29 26 70 5b 31 5d 3b 20 7d   (void*)&p[1]; }
2b00: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 53 52 56 41  .*/.#define SRVA
2b10: 4c 28 70 29 20 28 28 76 6f 69 64 2a 29 28 28 53  L(p) ((void*)((S
2b20: 6f 72 74 65 72 52 65 63 6f 72 64 2a 29 28 70 29  orterRecord*)(p)
2b30: 20 2b 20 31 29 29 0a 0a 2f 2a 20 54 68 65 20 6d   + 1))../* The m
2b40: 69 6e 69 6d 75 6d 20 50 4d 41 20 73 69 7a 65 20  inimum PMA size 
2b50: 69 73 20 73 65 74 20 74 6f 20 74 68 69 73 20 76  is set to this v
2b60: 61 6c 75 65 20 6d 75 6c 74 69 70 6c 69 65 64 20  alue multiplied 
2b70: 62 79 20 74 68 65 20 64 61 74 61 62 61 73 65 0a  by the database.
2b80: 2a 2a 20 70 61 67 65 20 73 69 7a 65 20 69 6e 20  ** page size in 
2b90: 62 79 74 65 73 2e 20 20 2a 2f 0a 23 64 65 66 69  bytes.  */.#defi
2ba0: 6e 65 20 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f  ne SORTER_MIN_WO
2bb0: 52 4b 49 4e 47 20 31 30 0a 0a 2f 2a 20 4d 61 78  RKING 10../* Max
2bc0: 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20 73  imum number of s
2bd0: 65 67 6d 65 6e 74 73 20 74 6f 20 6d 65 72 67 65  egments to merge
2be0: 20 69 6e 20 61 20 73 69 6e 67 6c 65 20 70 61 73   in a single pas
2bf0: 73 2e 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53 4f  s. */.#define SO
2c00: 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
2c10: 4f 55 4e 54 20 31 36 0a 0a 2f 2a 0a 2a 2a 20 46  OUNT 16../*.** F
2c20: 72 65 65 20 61 6c 6c 20 6d 65 6d 6f 72 79 20 62  ree all memory b
2c30: 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 74 68 65 20  elonging to the 
2c40: 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 6f  VdbeSorterIter o
2c50: 62 6a 65 63 74 20 70 61 73 73 65 64 20 61 73 20  bject passed as 
2c60: 74 68 65 20 73 65 63 6f 6e 64 0a 2a 2a 20 61 72  the second.** ar
2c70: 67 75 6d 65 6e 74 2e 20 41 6c 6c 20 73 74 72 75  gument. All stru
2c80: 63 74 75 72 65 20 66 69 65 6c 64 73 20 61 72 65  cture fields are
2c90: 20 73 65 74 20 74 6f 20 7a 65 72 6f 20 62 65 66   set to zero bef
2ca0: 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a  ore returning..*
2cb0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64  /.static void vd
2cc0: 62 65 53 6f 72 74 65 72 49 74 65 72 5a 65 72 6f  beSorterIterZero
2cd0: 28 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20  (VdbeSorterIter 
2ce0: 2a 70 49 74 65 72 29 7b 0a 20 20 73 71 6c 69 74  *pIter){.  sqlit
2cf0: 65 33 5f 66 72 65 65 28 70 49 74 65 72 2d 3e 61  e3_free(pIter->a
2d00: 41 6c 6c 6f 63 29 3b 0a 20 20 73 71 6c 69 74 65  Alloc);.  sqlite
2d10: 33 5f 66 72 65 65 28 70 49 74 65 72 2d 3e 61 42  3_free(pIter->aB
2d20: 75 66 66 65 72 29 3b 0a 20 20 69 66 28 20 70 49  uffer);.  if( pI
2d30: 74 65 72 2d 3e 61 4d 61 70 20 29 20 73 71 6c 69  ter->aMap ) sqli
2d40: 74 65 33 4f 73 55 6e 66 65 74 63 68 28 70 49 74  te3OsUnfetch(pIt
2d50: 65 72 2d 3e 70 46 69 6c 65 2c 20 30 2c 20 70 49  er->pFile, 0, pI
2d60: 74 65 72 2d 3e 61 4d 61 70 29 3b 0a 20 20 6d 65  ter->aMap);.  me
2d70: 6d 73 65 74 28 70 49 74 65 72 2c 20 30 2c 20 73  mset(pIter, 0, s
2d80: 69 7a 65 6f 66 28 56 64 62 65 53 6f 72 74 65 72  izeof(VdbeSorter
2d90: 49 74 65 72 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  Iter));.}../*.**
2da0: 20 52 65 61 64 20 6e 42 79 74 65 20 62 79 74 65   Read nByte byte
2db0: 73 20 6f 66 20 64 61 74 61 20 66 72 6f 6d 20 74  s of data from t
2dc0: 68 65 20 73 74 72 65 61 6d 20 6f 66 20 64 61 74  he stream of dat
2dd0: 61 20 69 74 65 72 61 74 65 64 20 62 79 20 6f 62  a iterated by ob
2de0: 6a 65 63 74 20 70 2e 0a 2a 2a 20 49 66 20 73 75  ject p..** If su
2df0: 63 63 65 73 73 66 75 6c 2c 20 73 65 74 20 2a 70  ccessful, set *p
2e00: 70 4f 75 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f  pOut to point to
2e10: 20 61 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69   a buffer contai
2e20: 6e 69 6e 67 20 74 68 65 20 64 61 74 61 0a 2a 2a  ning the data.**
2e30: 20 61 6e 64 20 72 65 74 75 72 6e 20 53 51 4c 49   and return SQLI
2e40: 54 45 5f 4f 4b 2e 20 4f 74 68 65 72 77 69 73 65  TE_OK. Otherwise
2e50: 2c 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  , if an error oc
2e60: 63 75 72 73 2c 20 72 65 74 75 72 6e 20 61 6e 20  curs, return an 
2e70: 53 51 4c 69 74 65 0a 2a 2a 20 65 72 72 6f 72 20  SQLite.** error 
2e80: 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  code..**.** The 
2e90: 62 75 66 66 65 72 20 69 6e 64 69 63 61 74 65 64  buffer indicated
2ea0: 20 62 79 20 2a 70 70 4f 75 74 20 6d 61 79 20 6f   by *ppOut may o
2eb0: 6e 6c 79 20 62 65 20 63 6f 6e 73 69 64 65 72 65  nly be considere
2ec0: 64 20 76 61 6c 69 64 20 75 6e 74 69 6c 20 74 68  d valid until th
2ed0: 65 0a 2a 2a 20 6e 65 78 74 20 63 61 6c 6c 20 74  e.** next call t
2ee0: 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 2e  o this function.
2ef0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
2f00: 64 62 65 53 6f 72 74 65 72 49 74 65 72 52 65 61  dbeSorterIterRea
2f10: 64 28 0a 20 20 56 64 62 65 53 6f 72 74 65 72 49  d(.  VdbeSorterI
2f20: 74 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20  ter *p,         
2f30: 20 20 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72       /* Iterator
2f40: 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65 2c   */.  int nByte,
2f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2f60: 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f        /* Bytes o
2f70: 66 20 64 61 74 61 20 74 6f 20 72 65 61 64 20 2a  f data to read *
2f80: 2f 0a 20 20 75 38 20 2a 2a 70 70 4f 75 74 20 20  /.  u8 **ppOut  
2f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2fa0: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e      /* OUT: Poin
2fb0: 74 65 72 20 74 6f 20 62 75 66 66 65 72 20 63 6f  ter to buffer co
2fc0: 6e 74 61 69 6e 69 6e 67 20 64 61 74 61 20 2a 2f  ntaining data */
2fd0: 0a 29 7b 0a 20 20 69 6e 74 20 69 42 75 66 3b 20  .){.  int iBuf; 
2fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2ff0: 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20        /* Offset 
3000: 77 69 74 68 69 6e 20 62 75 66 66 65 72 20 74 6f  within buffer to
3010: 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20   read from */.  
3020: 69 6e 74 20 6e 41 76 61 69 6c 3b 20 20 20 20 20  int nAvail;     
3030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3040: 2f 2a 20 42 79 74 65 73 20 6f 66 20 64 61 74 61  /* Bytes of data
3050: 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 62 75   available in bu
3060: 66 66 65 72 20 2a 2f 0a 0a 20 20 69 66 28 20 70  ffer */..  if( p
3070: 2d 3e 61 4d 61 70 20 29 7b 0a 20 20 20 20 2a 70  ->aMap ){.    *p
3080: 70 4f 75 74 20 3d 20 26 70 2d 3e 61 4d 61 70 5b  pOut = &p->aMap[
3090: 70 2d 3e 69 52 65 61 64 4f 66 66 5d 3b 0a 20 20  p->iReadOff];.  
30a0: 20 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d    p->iReadOff +=
30b0: 20 6e 42 79 74 65 3b 0a 20 20 20 20 72 65 74 75   nByte;.    retu
30c0: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20  rn SQLITE_OK;.  
30d0: 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e  }..  assert( p->
30e0: 61 42 75 66 66 65 72 20 29 3b 0a 0a 20 20 2f 2a  aBuffer );..  /*
30f0: 20 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20   If there is no 
3100: 6d 6f 72 65 20 64 61 74 61 20 74 6f 20 62 65 20  more data to be 
3110: 72 65 61 64 20 66 72 6f 6d 20 74 68 65 20 62 75  read from the bu
3120: 66 66 65 72 2c 20 72 65 61 64 20 74 68 65 20 6e  ffer, read the n
3130: 65 78 74 20 0a 20 20 2a 2a 20 70 2d 3e 6e 42 75  ext .  ** p->nBu
3140: 66 66 65 72 20 62 79 74 65 73 20 6f 66 20 64 61  ffer bytes of da
3150: 74 61 20 66 72 6f 6d 20 74 68 65 20 66 69 6c 65  ta from the file
3160: 20 69 6e 74 6f 20 69 74 2e 20 4f 72 2c 20 69 66   into it. Or, if
3170: 20 74 68 65 72 65 20 61 72 65 20 6c 65 73 73 0a   there are less.
3180: 20 20 2a 2a 20 74 68 61 6e 20 70 2d 3e 6e 42 75    ** than p->nBu
3190: 66 66 65 72 20 62 79 74 65 73 20 72 65 6d 61 69  ffer bytes remai
31a0: 6e 69 6e 67 20 69 6e 20 74 68 65 20 50 4d 41 2c  ning in the PMA,
31b0: 20 72 65 61 64 20 61 6c 6c 20 72 65 6d 61 69 6e   read all remain
31c0: 69 6e 67 20 64 61 74 61 2e 20 20 2a 2f 0a 20 20  ing data.  */.  
31d0: 69 42 75 66 20 3d 20 70 2d 3e 69 52 65 61 64 4f  iBuf = p->iReadO
31e0: 66 66 20 25 20 70 2d 3e 6e 42 75 66 66 65 72 3b  ff % p->nBuffer;
31f0: 0a 20 20 69 66 28 20 69 42 75 66 3d 3d 30 20 29  .  if( iBuf==0 )
3200: 7b 0a 20 20 20 20 69 6e 74 20 6e 52 65 61 64 3b  {.    int nRead;
3210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3220: 20 20 20 20 2f 2a 20 42 79 74 65 73 20 74 6f 20      /* Bytes to 
3230: 72 65 61 64 20 66 72 6f 6d 20 64 69 73 6b 20 2a  read from disk *
3240: 2f 0a 20 20 20 20 69 6e 74 20 72 63 3b 20 20 20  /.    int rc;   
3250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3260: 20 20 20 20 2f 2a 20 73 71 6c 69 74 65 33 4f 73      /* sqlite3Os
3270: 52 65 61 64 28 29 20 72 65 74 75 72 6e 20 63 6f  Read() return co
3280: 64 65 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 44 65  de */..    /* De
3290: 74 65 72 6d 69 6e 65 20 68 6f 77 20 6d 61 6e 79  termine how many
32a0: 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 74   bytes of data t
32b0: 6f 20 72 65 61 64 2e 20 2a 2f 0a 20 20 20 20 69  o read. */.    i
32c0: 66 28 20 28 70 2d 3e 69 45 6f 66 20 2d 20 70 2d  f( (p->iEof - p-
32d0: 3e 69 52 65 61 64 4f 66 66 29 20 3e 20 28 69 36  >iReadOff) > (i6
32e0: 34 29 70 2d 3e 6e 42 75 66 66 65 72 20 29 7b 0a  4)p->nBuffer ){.
32f0: 20 20 20 20 20 20 6e 52 65 61 64 20 3d 20 70 2d        nRead = p-
3300: 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20 20 7d 65  >nBuffer;.    }e
3310: 6c 73 65 7b 0a 20 20 20 20 20 20 6e 52 65 61 64  lse{.      nRead
3320: 20 3d 20 28 69 6e 74 29 28 70 2d 3e 69 45 6f 66   = (int)(p->iEof
3330: 20 2d 20 70 2d 3e 69 52 65 61 64 4f 66 66 29 3b   - p->iReadOff);
3340: 0a 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72  .    }.    asser
3350: 74 28 20 6e 52 65 61 64 3e 30 20 29 3b 0a 0a 20  t( nRead>0 );.. 
3360: 20 20 20 2f 2a 20 52 65 61 64 20 64 61 74 61 20     /* Read data 
3370: 66 72 6f 6d 20 74 68 65 20 66 69 6c 65 2e 20 52  from the file. R
3380: 65 74 75 72 6e 20 65 61 72 6c 79 20 69 66 20 61  eturn early if a
3390: 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 20  n error occurs. 
33a0: 2a 2f 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  */.    rc = sqli
33b0: 74 65 33 4f 73 52 65 61 64 28 70 2d 3e 70 46 69  te3OsRead(p->pFi
33c0: 6c 65 2c 20 70 2d 3e 61 42 75 66 66 65 72 2c 20  le, p->aBuffer, 
33d0: 6e 52 65 61 64 2c 20 70 2d 3e 69 52 65 61 64 4f  nRead, p->iReadO
33e0: 66 66 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  ff);.    assert(
33f0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 49 4f 45 52   rc!=SQLITE_IOER
3400: 52 5f 53 48 4f 52 54 5f 52 45 41 44 20 29 3b 0a  R_SHORT_READ );.
3410: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
3420: 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
3430: 63 3b 0a 20 20 7d 0a 20 20 6e 41 76 61 69 6c 20  c;.  }.  nAvail 
3440: 3d 20 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 69  = p->nBuffer - i
3450: 42 75 66 3b 20 0a 0a 20 20 69 66 28 20 6e 42 79  Buf; ..  if( nBy
3460: 74 65 3c 3d 6e 41 76 61 69 6c 20 29 7b 0a 20 20  te<=nAvail ){.  
3470: 20 20 2f 2a 20 54 68 65 20 72 65 71 75 65 73 74    /* The request
3480: 65 64 20 64 61 74 61 20 69 73 20 61 76 61 69 6c  ed data is avail
3490: 61 62 6c 65 20 69 6e 20 74 68 65 20 69 6e 2d 6d  able in the in-m
34a0: 65 6d 6f 72 79 20 62 75 66 66 65 72 2e 20 49 6e  emory buffer. In
34b0: 20 74 68 69 73 0a 20 20 20 20 2a 2a 20 63 61 73   this.    ** cas
34c0: 65 20 74 68 65 72 65 20 69 73 20 6e 6f 20 6e 65  e there is no ne
34d0: 65 64 20 74 6f 20 6d 61 6b 65 20 61 20 63 6f 70  ed to make a cop
34e0: 79 20 6f 66 20 74 68 65 20 64 61 74 61 2c 20 6a  y of the data, j
34f0: 75 73 74 20 72 65 74 75 72 6e 20 61 20 0a 20 20  ust return a .  
3500: 20 20 2a 2a 20 70 6f 69 6e 74 65 72 20 69 6e 74    ** pointer int
3510: 6f 20 74 68 65 20 62 75 66 66 65 72 20 74 6f 20  o the buffer to 
3520: 74 68 65 20 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a  the caller.  */.
3530: 20 20 20 20 2a 70 70 4f 75 74 20 3d 20 26 70 2d      *ppOut = &p-
3540: 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d 3b 0a  >aBuffer[iBuf];.
3550: 20 20 20 20 70 2d 3e 69 52 65 61 64 4f 66 66 20      p->iReadOff 
3560: 2b 3d 20 6e 42 79 74 65 3b 0a 20 20 7d 65 6c 73  += nByte;.  }els
3570: 65 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20 72 65  e{.    /* The re
3580: 71 75 65 73 74 65 64 20 64 61 74 61 20 69 73 20  quested data is 
3590: 6e 6f 74 20 61 6c 6c 20 61 76 61 69 6c 61 62 6c  not all availabl
35a0: 65 20 69 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f  e in the in-memo
35b0: 72 79 20 62 75 66 66 65 72 2e 0a 20 20 20 20 2a  ry buffer..    *
35c0: 2a 20 49 6e 20 74 68 69 73 20 63 61 73 65 2c 20  * In this case, 
35d0: 61 6c 6c 6f 63 61 74 65 20 73 70 61 63 65 20 61  allocate space a
35e0: 74 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 74 6f  t p->aAlloc[] to
35f0: 20 63 6f 70 79 20 74 68 65 20 72 65 71 75 65 73   copy the reques
3600: 74 65 64 0a 20 20 20 20 2a 2a 20 72 61 6e 67 65  ted.    ** range
3610: 20 69 6e 74 6f 2e 20 54 68 65 6e 20 72 65 74 75   into. Then retu
3620: 72 6e 20 61 20 63 6f 70 79 20 6f 66 20 70 6f 69  rn a copy of poi
3630: 6e 74 65 72 20 70 2d 3e 61 41 6c 6c 6f 63 20 74  nter p->aAlloc t
3640: 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 20 2a  o the caller.  *
3650: 2f 0a 20 20 20 20 69 6e 74 20 6e 52 65 6d 3b 20  /.    int nRem; 
3660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3670: 20 20 20 20 2f 2a 20 42 79 74 65 73 20 72 65 6d      /* Bytes rem
3680: 61 69 6e 69 6e 67 20 74 6f 20 63 6f 70 79 20 2a  aining to copy *
3690: 2f 0a 0a 20 20 20 20 2f 2a 20 45 78 74 65 6e 64  /..    /* Extend
36a0: 20 74 68 65 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d   the p->aAlloc[]
36b0: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 66 20 72   allocation if r
36c0: 65 71 75 69 72 65 64 2e 20 2a 2f 0a 20 20 20 20  equired. */.    
36d0: 69 66 28 20 70 2d 3e 6e 41 6c 6c 6f 63 3c 6e 42  if( p->nAlloc<nB
36e0: 79 74 65 20 29 7b 0a 20 20 20 20 20 20 75 38 20  yte ){.      u8 
36f0: 2a 61 4e 65 77 3b 0a 20 20 20 20 20 20 69 6e 74  *aNew;.      int
3700: 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e 41 6c 6c 6f   nNew = p->nAllo
3710: 63 2a 32 3b 0a 20 20 20 20 20 20 77 68 69 6c 65  c*2;.      while
3720: 28 20 6e 42 79 74 65 3e 6e 4e 65 77 20 29 20 6e  ( nByte>nNew ) n
3730: 4e 65 77 20 3d 20 6e 4e 65 77 2a 32 3b 0a 20 20  New = nNew*2;.  
3740: 20 20 20 20 61 4e 65 77 20 3d 20 73 71 6c 69 74      aNew = sqlit
3750: 65 33 52 65 61 6c 6c 6f 63 28 70 2d 3e 61 41 6c  e3Realloc(p->aAl
3760: 6c 6f 63 2c 20 6e 4e 65 77 29 3b 0a 20 20 20 20  loc, nNew);.    
3770: 20 20 69 66 28 20 21 61 4e 65 77 20 29 20 72 65    if( !aNew ) re
3780: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
3790: 4d 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 41 6c 6c  M;.      p->nAll
37a0: 6f 63 20 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 20  oc = nNew;.     
37b0: 20 70 2d 3e 61 41 6c 6c 6f 63 20 3d 20 61 4e 65   p->aAlloc = aNe
37c0: 77 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  w;.    }..    /*
37d0: 20 43 6f 70 79 20 61 73 20 6d 75 63 68 20 64 61   Copy as much da
37e0: 74 61 20 61 73 20 69 73 20 61 76 61 69 6c 61 62  ta as is availab
37f0: 6c 65 20 69 6e 20 74 68 65 20 62 75 66 66 65 72  le in the buffer
3800: 20 69 6e 74 6f 20 74 68 65 20 73 74 61 72 74 20   into the start 
3810: 6f 66 0a 20 20 20 20 2a 2a 20 70 2d 3e 61 41 6c  of.    ** p->aAl
3820: 6c 6f 63 5b 5d 2e 20 20 2a 2f 0a 20 20 20 20 6d  loc[].  */.    m
3830: 65 6d 63 70 79 28 70 2d 3e 61 41 6c 6c 6f 63 2c  emcpy(p->aAlloc,
3840: 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 69 42 75   &p->aBuffer[iBu
3850: 66 5d 2c 20 6e 41 76 61 69 6c 29 3b 0a 20 20 20  f], nAvail);.   
3860: 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20   p->iReadOff += 
3870: 6e 41 76 61 69 6c 3b 0a 20 20 20 20 6e 52 65 6d  nAvail;.    nRem
3880: 20 3d 20 6e 42 79 74 65 20 2d 20 6e 41 76 61 69   = nByte - nAvai
3890: 6c 3b 0a 0a 20 20 20 20 2f 2a 20 54 68 65 20 66  l;..    /* The f
38a0: 6f 6c 6c 6f 77 69 6e 67 20 6c 6f 6f 70 20 63 6f  ollowing loop co
38b0: 70 69 65 73 20 75 70 20 74 6f 20 70 2d 3e 6e 42  pies up to p->nB
38c0: 75 66 66 65 72 20 62 79 74 65 73 20 70 65 72 20  uffer bytes per 
38d0: 69 74 65 72 61 74 69 6f 6e 20 69 6e 74 6f 0a 20  iteration into. 
38e0: 20 20 20 2a 2a 20 74 68 65 20 70 2d 3e 61 41 6c     ** the p->aAl
38f0: 6c 6f 63 5b 5d 20 62 75 66 66 65 72 2e 20 20 2a  loc[] buffer.  *
3900: 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 6e 52 65  /.    while( nRe
3910: 6d 3e 30 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  m>0 ){.      int
3920: 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
3930: 20 20 20 20 20 20 20 20 20 2f 2a 20 76 64 62 65           /* vdbe
3940: 53 6f 72 74 65 72 49 74 65 72 52 65 61 64 28 29  SorterIterRead()
3950: 20 72 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a   return code */.
3960: 20 20 20 20 20 20 69 6e 74 20 6e 43 6f 70 79 3b        int nCopy;
3970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3980: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62    /* Number of b
3990: 79 74 65 73 20 74 6f 20 63 6f 70 79 20 2a 2f 0a  ytes to copy */.
39a0: 20 20 20 20 20 20 75 38 20 2a 61 4e 65 78 74 3b        u8 *aNext;
39b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
39c0: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
39d0: 62 75 66 66 65 72 20 74 6f 20 63 6f 70 79 20 64  buffer to copy d
39e0: 61 74 61 20 66 72 6f 6d 20 2a 2f 0a 0a 20 20 20  ata from */..   
39f0: 20 20 20 6e 43 6f 70 79 20 3d 20 6e 52 65 6d 3b     nCopy = nRem;
3a00: 0a 20 20 20 20 20 20 69 66 28 20 6e 52 65 6d 3e  .      if( nRem>
3a10: 70 2d 3e 6e 42 75 66 66 65 72 20 29 20 6e 43 6f  p->nBuffer ) nCo
3a20: 70 79 20 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b  py = p->nBuffer;
3a30: 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65  .      rc = vdbe
3a40: 53 6f 72 74 65 72 49 74 65 72 52 65 61 64 28 70  SorterIterRead(p
3a50: 2c 20 6e 43 6f 70 79 2c 20 26 61 4e 65 78 74 29  , nCopy, &aNext)
3a60: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  ;.      if( rc!=
3a70: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
3a80: 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 61 73 73  rn rc;.      ass
3a90: 65 72 74 28 20 61 4e 65 78 74 21 3d 70 2d 3e 61  ert( aNext!=p->a
3aa0: 41 6c 6c 6f 63 20 29 3b 0a 20 20 20 20 20 20 6d  Alloc );.      m
3ab0: 65 6d 63 70 79 28 26 70 2d 3e 61 41 6c 6c 6f 63  emcpy(&p->aAlloc
3ac0: 5b 6e 42 79 74 65 20 2d 20 6e 52 65 6d 5d 2c 20  [nByte - nRem], 
3ad0: 61 4e 65 78 74 2c 20 6e 43 6f 70 79 29 3b 0a 20  aNext, nCopy);. 
3ae0: 20 20 20 20 20 6e 52 65 6d 20 2d 3d 20 6e 43 6f       nRem -= nCo
3af0: 70 79 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2a  py;.    }..    *
3b00: 70 70 4f 75 74 20 3d 20 70 2d 3e 61 41 6c 6c 6f  ppOut = p->aAllo
3b10: 63 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  c;.  }..  return
3b20: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
3b30: 2a 0a 2a 2a 20 52 65 61 64 20 61 20 76 61 72 69  *.** Read a vari
3b40: 6e 74 20 66 72 6f 6d 20 74 68 65 20 73 74 72 65  nt from the stre
3b50: 61 6d 20 6f 66 20 64 61 74 61 20 61 63 63 65 73  am of data acces
3b60: 73 65 64 20 62 79 20 70 2e 20 53 65 74 20 2a 70  sed by p. Set *p
3b70: 6e 4f 75 74 20 74 6f 0a 2a 2a 20 74 68 65 20 76  nOut to.** the v
3b80: 61 6c 75 65 20 72 65 61 64 2e 0a 2a 2f 0a 73 74  alue read..*/.st
3b90: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
3ba0: 74 65 72 49 74 65 72 56 61 72 69 6e 74 28 56 64  terIterVarint(Vd
3bb0: 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70 2c  beSorterIter *p,
3bc0: 20 75 36 34 20 2a 70 6e 4f 75 74 29 7b 0a 20 20   u64 *pnOut){.  
3bd0: 69 6e 74 20 69 42 75 66 3b 0a 0a 20 20 69 66 28  int iBuf;..  if(
3be0: 20 70 2d 3e 61 4d 61 70 20 29 7b 0a 20 20 20 20   p->aMap ){.    
3bf0: 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 73  p->iReadOff += s
3c00: 71 6c 69 74 65 33 47 65 74 56 61 72 69 6e 74 28  qlite3GetVarint(
3c10: 26 70 2d 3e 61 4d 61 70 5b 70 2d 3e 69 52 65 61  &p->aMap[p->iRea
3c20: 64 4f 66 66 5d 2c 20 70 6e 4f 75 74 29 3b 0a 20  dOff], pnOut);. 
3c30: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 42 75 66   }else{.    iBuf
3c40: 20 3d 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 25   = p->iReadOff %
3c50: 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20   p->nBuffer;.   
3c60: 20 69 66 28 20 69 42 75 66 20 26 26 20 28 70 2d   if( iBuf && (p-
3c70: 3e 6e 42 75 66 66 65 72 2d 69 42 75 66 29 3e 3d  >nBuffer-iBuf)>=
3c80: 39 20 29 7b 0a 20 20 20 20 20 20 70 2d 3e 69 52  9 ){.      p->iR
3c90: 65 61 64 4f 66 66 20 2b 3d 20 73 71 6c 69 74 65  eadOff += sqlite
3ca0: 33 47 65 74 56 61 72 69 6e 74 28 26 70 2d 3e 61  3GetVarint(&p->a
3cb0: 42 75 66 66 65 72 5b 69 42 75 66 5d 2c 20 70 6e  Buffer[iBuf], pn
3cc0: 4f 75 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  Out);.    }else{
3cd0: 0a 20 20 20 20 20 20 75 38 20 61 56 61 72 69 6e  .      u8 aVarin
3ce0: 74 5b 31 36 5d 2c 20 2a 61 3b 0a 20 20 20 20 20  t[16], *a;.     
3cf0: 20 69 6e 74 20 69 20 3d 20 30 2c 20 72 63 3b 0a   int i = 0, rc;.
3d00: 20 20 20 20 20 20 64 6f 7b 0a 20 20 20 20 20 20        do{.      
3d10: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
3d20: 72 49 74 65 72 52 65 61 64 28 70 2c 20 31 2c 20  rIterRead(p, 1, 
3d30: 26 61 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  &a);.        if(
3d40: 20 72 63 20 29 20 72 65 74 75 72 6e 20 72 63 3b   rc ) return rc;
3d50: 0a 20 20 20 20 20 20 20 20 61 56 61 72 69 6e 74  .        aVarint
3d60: 5b 28 69 2b 2b 29 26 30 78 66 5d 20 3d 20 61 5b  [(i++)&0xf] = a[
3d70: 30 5d 3b 0a 20 20 20 20 20 20 7d 77 68 69 6c 65  0];.      }while
3d80: 28 20 28 61 5b 30 5d 26 30 78 38 30 29 21 3d 30  ( (a[0]&0x80)!=0
3d90: 20 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   );.      sqlite
3da0: 33 47 65 74 56 61 72 69 6e 74 28 61 56 61 72 69  3GetVarint(aVari
3db0: 6e 74 2c 20 70 6e 4f 75 74 29 3b 0a 20 20 20 20  nt, pnOut);.    
3dc0: 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  }.  }..  return 
3dd0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f  SQLITE_OK;.}.../
3de0: 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 69 74 65  *.** Advance ite
3df0: 72 61 74 6f 72 20 70 49 74 65 72 20 74 6f 20 74  rator pIter to t
3e00: 68 65 20 6e 65 78 74 20 6b 65 79 20 69 6e 20 69  he next key in i
3e10: 74 73 20 50 4d 41 2e 20 52 65 74 75 72 6e 20 53  ts PMA. Return S
3e20: 51 4c 49 54 45 5f 4f 4b 20 69 66 0a 2a 2a 20 6e  QLITE_OK if.** n
3e30: 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20  o error occurs, 
3e40: 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  or an SQLite err
3e50: 6f 72 20 63 6f 64 65 20 69 66 20 6f 6e 65 20 64  or code if one d
3e60: 6f 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  oes..*/.static i
3e70: 6e 74 20 76 64 62 65 53 6f 72 74 65 72 49 74 65  nt vdbeSorterIte
3e80: 72 4e 65 78 74 28 56 64 62 65 53 6f 72 74 65 72  rNext(VdbeSorter
3e90: 49 74 65 72 20 2a 70 49 74 65 72 29 7b 0a 20 20  Iter *pIter){.  
3ea0: 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
3eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3ec0: 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a  /* Return Code *
3ed0: 2f 0a 20 20 75 36 34 20 6e 52 65 63 20 3d 20 30  /.  u64 nRec = 0
3ee0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
3ef0: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 72      /* Size of r
3f00: 65 63 6f 72 64 20 69 6e 20 62 79 74 65 73 20 2a  ecord in bytes *
3f10: 2f 0a 0a 20 20 69 66 28 20 70 49 74 65 72 2d 3e  /..  if( pIter->
3f20: 69 52 65 61 64 4f 66 66 3e 3d 70 49 74 65 72 2d  iReadOff>=pIter-
3f30: 3e 69 45 6f 66 20 29 7b 0a 20 20 20 20 2f 2a 20  >iEof ){.    /* 
3f40: 54 68 69 73 20 69 73 20 61 6e 20 45 4f 46 20 63  This is an EOF c
3f50: 6f 6e 64 69 74 69 6f 6e 20 2a 2f 0a 20 20 20 20  ondition */.    
3f60: 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 5a 65  vdbeSorterIterZe
3f70: 72 6f 28 70 49 74 65 72 29 3b 0a 20 20 20 20 72  ro(pIter);.    r
3f80: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
3f90: 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20 76 64 62  .  }..  rc = vdb
3fa0: 65 53 6f 72 74 65 72 49 74 65 72 56 61 72 69 6e  eSorterIterVarin
3fb0: 74 28 70 49 74 65 72 2c 20 26 6e 52 65 63 29 3b  t(pIter, &nRec);
3fc0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
3fd0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 49 74 65  E_OK ){.    pIte
3fe0: 72 2d 3e 6e 4b 65 79 20 3d 20 28 69 6e 74 29 6e  r->nKey = (int)n
3ff0: 52 65 63 3b 0a 20 20 20 20 72 63 20 3d 20 76 64  Rec;.    rc = vd
4000: 62 65 53 6f 72 74 65 72 49 74 65 72 52 65 61 64  beSorterIterRead
4010: 28 70 49 74 65 72 2c 20 28 69 6e 74 29 6e 52 65  (pIter, (int)nRe
4020: 63 2c 20 26 70 49 74 65 72 2d 3e 61 4b 65 79 29  c, &pIter->aKey)
4030: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
4040: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69  rc;.}../*.** Ini
4050: 74 69 61 6c 69 7a 65 20 69 74 65 72 61 74 6f 72  tialize iterator
4060: 20 70 49 74 65 72 20 74 6f 20 73 63 61 6e 20 74   pIter to scan t
4070: 68 72 6f 75 67 68 20 74 68 65 20 50 4d 41 20 73  hrough the PMA s
4080: 74 6f 72 65 64 20 69 6e 20 66 69 6c 65 20 70 46  tored in file pF
4090: 69 6c 65 0a 2a 2a 20 73 74 61 72 74 69 6e 67 20  ile.** starting 
40a0: 61 74 20 6f 66 66 73 65 74 20 69 53 74 61 72 74  at offset iStart
40b0: 20 61 6e 64 20 65 6e 64 69 6e 67 20 61 74 20 6f   and ending at o
40c0: 66 66 73 65 74 20 69 45 6f 66 2d 31 2e 20 54 68  ffset iEof-1. Th
40d0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 0a 2a 2a 20  is function .** 
40e0: 6c 65 61 76 65 73 20 74 68 65 20 69 74 65 72 61  leaves the itera
40f0: 74 6f 72 20 70 6f 69 6e 74 69 6e 67 20 74 6f 20  tor pointing to 
4100: 74 68 65 20 66 69 72 73 74 20 6b 65 79 20 69 6e  the first key in
4110: 20 74 68 65 20 50 4d 41 20 28 6f 72 20 45 4f 46   the PMA (or EOF
4120: 20 69 66 20 74 68 65 20 0a 2a 2a 20 50 4d 41 20   if the .** PMA 
4130: 69 73 20 65 6d 70 74 79 29 2e 0a 2a 2f 0a 73 74  is empty)..*/.st
4140: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
4150: 74 65 72 49 74 65 72 49 6e 69 74 28 0a 20 20 53  terIterInit(.  S
4160: 6f 72 74 65 72 54 68 72 65 61 64 20 2a 70 54 68  orterThread *pTh
4170: 72 65 61 64 2c 20 20 20 20 20 20 20 20 20 20 2f  read,          /
4180: 2a 20 54 68 72 65 61 64 20 63 6f 6e 74 65 78 74  * Thread context
4190: 20 2a 2f 0a 20 20 69 36 34 20 69 53 74 61 72 74   */.  i64 iStart
41a0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
41b0: 20 20 20 20 20 20 2f 2a 20 53 74 61 72 74 20 6f        /* Start o
41c0: 66 66 73 65 74 20 69 6e 20 70 54 68 72 65 61 64  ffset in pThread
41d0: 2d 3e 70 54 65 6d 70 31 20 2a 2f 0a 20 20 56 64  ->pTemp1 */.  Vd
41e0: 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70 49  beSorterIter *pI
41f0: 74 65 72 2c 20 20 20 20 20 20 20 20 20 20 2f 2a  ter,          /*
4200: 20 49 74 65 72 61 74 6f 72 20 74 6f 20 70 6f 70   Iterator to pop
4210: 75 6c 61 74 65 20 2a 2f 0a 20 20 69 36 34 20 2a  ulate */.  i64 *
4220: 70 6e 42 79 74 65 20 20 20 20 20 20 20 20 20 20  pnByte          
4230: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e             /* IN
4240: 2f 4f 55 54 3a 20 49 6e 63 72 65 6d 65 6e 74 20  /OUT: Increment 
4250: 74 68 69 73 20 76 61 6c 75 65 20 62 79 20 50 4d  this value by PM
4260: 41 20 73 69 7a 65 20 2a 2f 0a 29 7b 0a 20 20 69  A size */.){.  i
4270: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
4280: 4b 3b 0a 20 20 69 6e 74 20 6e 42 75 66 20 3d 20  K;.  int nBuf = 
4290: 70 54 68 72 65 61 64 2d 3e 70 67 73 7a 3b 0a 20  pThread->pgsz;. 
42a0: 20 76 6f 69 64 20 2a 70 4d 61 70 20 3d 20 30 3b   void *pMap = 0;
42b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
42c0: 20 2f 2a 20 4d 61 70 70 69 6e 67 20 6f 66 20 74   /* Mapping of t
42d0: 65 6d 70 20 66 69 6c 65 20 2a 2f 0a 0a 20 20 61  emp file */..  a
42e0: 73 73 65 72 74 28 20 70 54 68 72 65 61 64 2d 3e  ssert( pThread->
42f0: 69 54 65 6d 70 31 4f 66 66 3e 69 53 74 61 72 74  iTemp1Off>iStart
4300: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 49   );.  assert( pI
4310: 74 65 72 2d 3e 61 41 6c 6c 6f 63 3d 3d 30 20 29  ter->aAlloc==0 )
4320: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 49 74 65  ;.  assert( pIte
4330: 72 2d 3e 61 42 75 66 66 65 72 3d 3d 30 20 29 3b  r->aBuffer==0 );
4340: 0a 20 20 70 49 74 65 72 2d 3e 70 46 69 6c 65 20  .  pIter->pFile 
4350: 3d 20 70 54 68 72 65 61 64 2d 3e 70 54 65 6d 70  = pThread->pTemp
4360: 31 3b 0a 20 20 70 49 74 65 72 2d 3e 69 52 65 61  1;.  pIter->iRea
4370: 64 4f 66 66 20 3d 20 69 53 74 61 72 74 3b 0a 20  dOff = iStart;. 
4380: 20 70 49 74 65 72 2d 3e 6e 41 6c 6c 6f 63 20 3d   pIter->nAlloc =
4390: 20 31 32 38 3b 0a 20 20 70 49 74 65 72 2d 3e 61   128;.  pIter->a
43a0: 41 6c 6c 6f 63 20 3d 20 28 75 38 2a 29 73 71 6c  Alloc = (u8*)sql
43b0: 69 74 65 33 4d 61 6c 6c 6f 63 28 70 49 74 65 72  ite3Malloc(pIter
43c0: 2d 3e 6e 41 6c 6c 6f 63 29 3b 0a 0a 20 20 2f 2a  ->nAlloc);..  /*
43d0: 20 54 72 79 20 74 6f 20 78 46 65 74 63 68 28 29   Try to xFetch()
43e0: 20 61 20 6d 61 70 70 69 6e 67 20 6f 66 20 74 68   a mapping of th
43f0: 65 20 65 6e 74 69 72 65 20 74 65 6d 70 20 66 69  e entire temp fi
4400: 6c 65 2e 20 49 66 20 74 68 69 73 20 69 73 20 70  le. If this is p
4410: 6f 73 73 69 62 6c 65 2c 0a 20 20 2a 2a 20 74 68  ossible,.  ** th
4420: 65 20 50 4d 41 20 77 69 6c 6c 20 62 65 20 72 65  e PMA will be re
4430: 61 64 20 76 69 61 20 74 68 65 20 6d 61 70 70 69  ad via the mappi
4440: 6e 67 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 75  ng. Otherwise, u
4450: 73 65 20 78 52 65 61 64 28 29 2e 20 20 2a 2f 0a  se xRead().  */.
4460: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
4470: 46 65 74 63 68 28 70 49 74 65 72 2d 3e 70 46 69  Fetch(pIter->pFi
4480: 6c 65 2c 20 30 2c 20 70 54 68 72 65 61 64 2d 3e  le, 0, pThread->
4490: 69 54 65 6d 70 31 4f 66 66 2c 20 26 70 4d 61 70  iTemp1Off, &pMap
44a0: 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  );..  if( rc==SQ
44b0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69  LITE_OK ){.    i
44c0: 66 28 20 70 4d 61 70 20 29 7b 0a 20 20 20 20 20  f( pMap ){.     
44d0: 20 70 49 74 65 72 2d 3e 61 4d 61 70 20 3d 20 28   pIter->aMap = (
44e0: 75 38 2a 29 70 4d 61 70 3b 0a 20 20 20 20 7d 65  u8*)pMap;.    }e
44f0: 6c 73 65 7b 0a 20 20 20 20 20 20 70 49 74 65 72  lse{.      pIter
4500: 2d 3e 6e 42 75 66 66 65 72 20 3d 20 6e 42 75 66  ->nBuffer = nBuf
4510: 3b 0a 20 20 20 20 20 20 70 49 74 65 72 2d 3e 61  ;.      pIter->a
4520: 42 75 66 66 65 72 20 3d 20 28 75 38 2a 29 73 71  Buffer = (u8*)sq
4530: 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 6e 42 75 66  lite3Malloc(nBuf
4540: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21 70 49  );.      if( !pI
4550: 74 65 72 2d 3e 61 42 75 66 66 65 72 20 29 7b 0a  ter->aBuffer ){.
4560: 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
4570: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
4580: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
4590: 69 6e 74 20 69 42 75 66 20 3d 20 69 53 74 61 72  int iBuf = iStar
45a0: 74 20 25 20 6e 42 75 66 3b 0a 20 20 20 20 20 20  t % nBuf;.      
45b0: 20 20 69 66 28 20 69 42 75 66 20 29 7b 0a 20 20    if( iBuf ){.  
45c0: 20 20 20 20 20 20 20 20 69 6e 74 20 6e 52 65 61          int nRea
45d0: 64 20 3d 20 6e 42 75 66 20 2d 20 69 42 75 66 3b  d = nBuf - iBuf;
45e0: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 28  .          if( (
45f0: 69 53 74 61 72 74 20 2b 20 6e 52 65 61 64 29 20  iStart + nRead) 
4600: 3e 20 70 54 68 72 65 61 64 2d 3e 69 54 65 6d 70  > pThread->iTemp
4610: 31 4f 66 66 20 29 7b 0a 20 20 20 20 20 20 20 20  1Off ){.        
4620: 20 20 20 20 6e 52 65 61 64 20 3d 20 28 69 6e 74      nRead = (int
4630: 29 28 70 54 68 72 65 61 64 2d 3e 69 54 65 6d 70  )(pThread->iTemp
4640: 31 4f 66 66 20 2d 20 69 53 74 61 72 74 29 3b 0a  1Off - iStart);.
4650: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
4660: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
4670: 65 33 4f 73 52 65 61 64 28 0a 20 20 20 20 20 20  e3OsRead(.      
4680: 20 20 20 20 20 20 20 20 70 54 68 72 65 61 64 2d          pThread-
4690: 3e 70 54 65 6d 70 31 2c 20 26 70 49 74 65 72 2d  >pTemp1, &pIter-
46a0: 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d 2c 20  >aBuffer[iBuf], 
46b0: 6e 52 65 61 64 2c 20 69 53 74 61 72 74 0a 20 20  nRead, iStart.  
46c0: 20 20 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20              );. 
46d0: 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28           assert(
46e0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 49 4f 45 52   rc!=SQLITE_IOER
46f0: 52 5f 53 48 4f 52 54 5f 52 45 41 44 20 29 3b 0a  R_SHORT_READ );.
4700: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
4710: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  }.    }.  }..  i
4720: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
4730: 20 29 7b 0a 20 20 20 20 75 36 34 20 6e 42 79 74   ){.    u64 nByt
4740: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
4750: 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
4760: 20 50 4d 41 20 69 6e 20 62 79 74 65 73 20 2a 2f   PMA in bytes */
4770: 0a 20 20 20 20 70 49 74 65 72 2d 3e 69 45 6f 66  .    pIter->iEof
4780: 20 3d 20 70 54 68 72 65 61 64 2d 3e 69 54 65 6d   = pThread->iTem
4790: 70 31 4f 66 66 3b 0a 20 20 20 20 72 63 20 3d 20  p1Off;.    rc = 
47a0: 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 56 61  vdbeSorterIterVa
47b0: 72 69 6e 74 28 70 49 74 65 72 2c 20 26 6e 42 79  rint(pIter, &nBy
47c0: 74 65 29 3b 0a 20 20 20 20 70 49 74 65 72 2d 3e  te);.    pIter->
47d0: 69 45 6f 66 20 3d 20 70 49 74 65 72 2d 3e 69 52  iEof = pIter->iR
47e0: 65 61 64 4f 66 66 20 2b 20 6e 42 79 74 65 3b 0a  eadOff + nByte;.
47f0: 20 20 20 20 2a 70 6e 42 79 74 65 20 2b 3d 20 6e      *pnByte += n
4800: 42 79 74 65 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  Byte;.  }..  if(
4810: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
4820: 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53  {.    rc = vdbeS
4830: 6f 72 74 65 72 49 74 65 72 4e 65 78 74 28 70 49  orterIterNext(pI
4840: 74 65 72 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  ter);.  }.  retu
4850: 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a  rn rc;.}.../*.**
4860: 20 43 6f 6d 70 61 72 65 20 6b 65 79 31 20 28 62   Compare key1 (b
4870: 75 66 66 65 72 20 70 4b 65 79 31 2c 20 73 69 7a  uffer pKey1, siz
4880: 65 20 6e 4b 65 79 31 20 62 79 74 65 73 29 20 77  e nKey1 bytes) w
4890: 69 74 68 20 6b 65 79 32 20 28 62 75 66 66 65 72  ith key2 (buffer
48a0: 20 70 4b 65 79 32 2c 20 0a 2a 2a 20 73 69 7a 65   pKey2, .** size
48b0: 20 6e 4b 65 79 32 20 62 79 74 65 73 29 2e 20 20   nKey2 bytes).  
48c0: 41 72 67 75 6d 65 6e 74 20 70 4b 65 79 49 6e 66  Argument pKeyInf
48d0: 6f 20 73 75 70 70 6c 69 65 73 20 74 68 65 20 63  o supplies the c
48e0: 6f 6c 6c 61 74 69 6f 6e 20 66 75 6e 63 74 69 6f  ollation functio
48f0: 6e 73 0a 2a 2a 20 75 73 65 64 20 62 79 20 74 68  ns.** used by th
4900: 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2e 20 49 66  e comparison. If
4910: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
4920: 2c 20 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69  , return an SQLi
4930: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a  te error code..*
4940: 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 72 65 74  * Otherwise, ret
4950: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 61 6e  urn SQLITE_OK an
4960: 64 20 73 65 74 20 2a 70 52 65 73 20 74 6f 20 61  d set *pRes to a
4970: 20 6e 65 67 61 74 69 76 65 2c 20 7a 65 72 6f 20   negative, zero 
4980: 6f 72 20 70 6f 73 69 74 69 76 65 0a 2a 2a 20 76  or positive.** v
4990: 61 6c 75 65 2c 20 64 65 70 65 6e 64 69 6e 67 20  alue, depending 
49a0: 6f 6e 20 77 68 65 74 68 65 72 20 6b 65 79 31 20  on whether key1 
49b0: 69 73 20 73 6d 61 6c 6c 65 72 2c 20 65 71 75 61  is smaller, equa
49c0: 6c 20 74 6f 20 6f 72 20 6c 61 72 67 65 72 20 74  l to or larger t
49d0: 68 61 6e 20 6b 65 79 32 2e 0a 2a 2a 0a 2a 2a 20  han key2..**.** 
49e0: 49 66 20 74 68 65 20 62 4f 6d 69 74 52 6f 77 69  If the bOmitRowi
49f0: 64 20 61 72 67 75 6d 65 6e 74 20 69 73 20 6e 6f  d argument is no
4a00: 6e 2d 7a 65 72 6f 2c 20 61 73 73 75 6d 65 20 62  n-zero, assume b
4a10: 6f 74 68 20 6b 65 79 73 20 65 6e 64 20 69 6e 20  oth keys end in 
4a20: 61 20 72 6f 77 69 64 0a 2a 2a 20 66 69 65 6c 64  a rowid.** field
4a30: 2e 20 46 6f 72 20 74 68 65 20 70 75 72 70 6f 73  . For the purpos
4a40: 65 73 20 6f 66 20 74 68 65 20 63 6f 6d 70 61 72  es of the compar
4a50: 69 73 6f 6e 2c 20 69 67 6e 6f 72 65 20 69 74 2e  ison, ignore it.
4a60: 20 41 6c 73 6f 2c 20 69 66 20 62 4f 6d 69 74 52   Also, if bOmitR
4a70: 6f 77 69 64 0a 2a 2a 20 69 73 20 74 72 75 65 20  owid.** is true 
4a80: 61 6e 64 20 6b 65 79 31 20 63 6f 6e 74 61 69 6e  and key1 contain
4a90: 73 20 65 76 65 6e 20 61 20 73 69 6e 67 6c 65 20  s even a single 
4aa0: 4e 55 4c 4c 20 76 61 6c 75 65 2c 20 69 74 20 69  NULL value, it i
4ab0: 73 20 63 6f 6e 73 69 64 65 72 65 64 20 74 6f 0a  s considered to.
4ac0: 2a 2a 20 62 65 20 6c 65 73 73 20 74 68 61 6e 20  ** be less than 
4ad0: 6b 65 79 32 2e 20 45 76 65 6e 20 69 66 20 6b 65  key2. Even if ke
4ae0: 79 32 20 61 6c 73 6f 20 63 6f 6e 74 61 69 6e 73  y2 also contains
4af0: 20 4e 55 4c 4c 20 76 61 6c 75 65 73 2e 0a 2a 2a   NULL values..**
4b00: 0a 2a 2a 20 49 66 20 70 4b 65 79 32 20 69 73 20  .** If pKey2 is 
4b10: 70 61 73 73 65 64 20 61 20 4e 55 4c 4c 20 70 6f  passed a NULL po
4b20: 69 6e 74 65 72 2c 20 74 68 65 6e 20 69 74 20 69  inter, then it i
4b30: 73 20 61 73 73 75 6d 65 64 20 74 68 61 74 20 74  s assumed that t
4b40: 68 65 20 70 43 73 72 2d 3e 61 53 70 61 63 65 0a  he pCsr->aSpace.
4b50: 2a 2a 20 68 61 73 20 62 65 65 6e 20 61 6c 6c 6f  ** has been allo
4b60: 63 61 74 65 64 20 61 6e 64 20 63 6f 6e 74 61 69  cated and contai
4b70: 6e 73 20 61 6e 20 75 6e 70 61 63 6b 65 64 20 72  ns an unpacked r
4b80: 65 63 6f 72 64 20 74 68 61 74 20 69 73 20 75 73  ecord that is us
4b90: 65 64 20 61 73 20 6b 65 79 32 2e 0a 2a 2f 0a 73  ed as key2..*/.s
4ba0: 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 53  tatic void vdbeS
4bb0: 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 0a 20 20  orterCompare(.  
4bc0: 53 6f 72 74 65 72 54 68 72 65 61 64 20 2a 70 54  SorterThread *pT
4bd0: 68 72 65 61 64 2c 20 20 20 20 20 20 20 20 20 20  hread,          
4be0: 2f 2a 20 54 68 72 65 61 64 20 63 6f 6e 74 65 78  /* Thread contex
4bf0: 74 20 28 66 6f 72 20 70 4b 65 79 49 6e 66 6f 29  t (for pKeyInfo)
4c00: 20 2a 2f 0a 20 20 69 6e 74 20 6e 49 67 6e 6f 72   */.  int nIgnor
4c10: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
4c20: 20 20 20 20 20 20 2f 2a 20 49 67 6e 6f 72 65 20        /* Ignore 
4c30: 74 68 65 20 6c 61 73 74 20 6e 49 67 6e 6f 72 65  the last nIgnore
4c40: 20 66 69 65 6c 64 73 20 2a 2f 0a 20 20 63 6f 6e   fields */.  con
4c50: 73 74 20 76 6f 69 64 20 2a 70 4b 65 79 31 2c 20  st void *pKey1, 
4c60: 69 6e 74 20 6e 4b 65 79 31 2c 20 20 20 2f 2a 20  int nKey1,   /* 
4c70: 4c 65 66 74 20 73 69 64 65 20 6f 66 20 63 6f 6d  Left side of com
4c80: 70 61 72 69 73 6f 6e 20 2a 2f 0a 20 20 63 6f 6e  parison */.  con
4c90: 73 74 20 76 6f 69 64 20 2a 70 4b 65 79 32 2c 20  st void *pKey2, 
4ca0: 69 6e 74 20 6e 4b 65 79 32 2c 20 20 20 2f 2a 20  int nKey2,   /* 
4cb0: 52 69 67 68 74 20 73 69 64 65 20 6f 66 20 63 6f  Right side of co
4cc0: 6d 70 61 72 69 73 6f 6e 20 2a 2f 0a 20 20 69 6e  mparison */.  in
4cd0: 74 20 2a 70 52 65 73 20 20 20 20 20 20 20 20 20  t *pRes         
4ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4cf0: 20 4f 55 54 3a 20 52 65 73 75 6c 74 20 6f 66 20   OUT: Result of 
4d00: 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f 0a 29 7b  comparison */.){
4d10: 0a 20 20 4b 65 79 49 6e 66 6f 20 2a 70 4b 65 79  .  KeyInfo *pKey
4d20: 49 6e 66 6f 20 3d 20 70 54 68 72 65 61 64 2d 3e  Info = pThread->
4d30: 70 4b 65 79 49 6e 66 6f 3b 0a 20 20 55 6e 70 61  pKeyInfo;.  Unpa
4d40: 63 6b 65 64 52 65 63 6f 72 64 20 2a 72 32 20 3d  ckedRecord *r2 =
4d50: 20 70 54 68 72 65 61 64 2d 3e 70 55 6e 70 61 63   pThread->pUnpac
4d60: 6b 65 64 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20  ked;.  int i;.. 
4d70: 20 69 66 28 20 70 4b 65 79 32 20 29 7b 0a 20 20   if( pKey2 ){.  
4d80: 20 20 73 71 6c 69 74 65 33 56 64 62 65 52 65 63    sqlite3VdbeRec
4d90: 6f 72 64 55 6e 70 61 63 6b 28 70 4b 65 79 49 6e  ordUnpack(pKeyIn
4da0: 66 6f 2c 20 6e 4b 65 79 32 2c 20 70 4b 65 79 32  fo, nKey2, pKey2
4db0: 2c 20 72 32 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  , r2);.  }..  if
4dc0: 28 20 6e 49 67 6e 6f 72 65 20 29 7b 0a 20 20 20  ( nIgnore ){.   
4dd0: 20 72 32 2d 3e 6e 46 69 65 6c 64 20 3d 20 70 4b   r2->nField = pK
4de0: 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64 20 2d  eyInfo->nField -
4df0: 20 6e 49 67 6e 6f 72 65 3b 0a 20 20 20 20 61 73   nIgnore;.    as
4e00: 73 65 72 74 28 20 72 32 2d 3e 6e 46 69 65 6c 64  sert( r2->nField
4e10: 3e 30 20 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d  >0 );.    for(i=
4e20: 30 3b 20 69 3c 72 32 2d 3e 6e 46 69 65 6c 64 3b  0; i<r2->nField;
4e30: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28   i++){.      if(
4e40: 20 72 32 2d 3e 61 4d 65 6d 5b 69 5d 2e 66 6c 61   r2->aMem[i].fla
4e50: 67 73 20 26 20 4d 45 4d 5f 4e 75 6c 6c 20 29 7b  gs & MEM_Null ){
4e60: 0a 20 20 20 20 20 20 20 20 2a 70 52 65 73 20 3d  .        *pRes =
4e70: 20 2d 31 3b 0a 20 20 20 20 20 20 20 20 72 65 74   -1;.        ret
4e80: 75 72 6e 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  urn;.      }.   
4e90: 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 72   }.    assert( r
4ea0: 32 2d 3e 64 65 66 61 75 6c 74 5f 72 63 3d 3d 30  2->default_rc==0
4eb0: 20 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 52 65 73   );.  }..  *pRes
4ec0: 20 3d 20 73 71 6c 69 74 65 33 56 64 62 65 52 65   = sqlite3VdbeRe
4ed0: 63 6f 72 64 43 6f 6d 70 61 72 65 28 6e 4b 65 79  cordCompare(nKey
4ee0: 31 2c 20 70 4b 65 79 31 2c 20 72 32 2c 20 30 29  1, pKey1, r2, 0)
4ef0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
4f00: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
4f10: 65 64 20 74 6f 20 63 6f 6d 70 61 72 65 20 74 77  ed to compare tw
4f20: 6f 20 69 74 65 72 61 74 6f 72 20 6b 65 79 73 20  o iterator keys 
4f30: 77 68 65 6e 20 6d 65 72 67 69 6e 67 20 0a 2a 2a  when merging .**
4f40: 20 6d 75 6c 74 69 70 6c 65 20 62 2d 74 72 65 65   multiple b-tree
4f50: 20 73 65 67 6d 65 6e 74 73 2e 20 50 61 72 61 6d   segments. Param
4f60: 65 74 65 72 20 69 4f 75 74 20 69 73 20 74 68 65  eter iOut is the
4f70: 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20 61 54   index of the aT
4f80: 72 65 65 5b 5d 20 0a 2a 2a 20 76 61 6c 75 65 20  ree[] .** value 
4f90: 74 6f 20 72 65 63 61 6c 63 75 6c 61 74 65 2e 0a  to recalculate..
4fa0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
4fb0: 62 65 53 6f 72 74 65 72 44 6f 43 6f 6d 70 61 72  beSorterDoCompar
4fc0: 65 28 0a 20 20 53 6f 72 74 65 72 54 68 72 65 61  e(.  SorterThrea
4fd0: 64 20 2a 70 54 68 72 65 61 64 2c 20 0a 20 20 53  d *pThread, .  S
4fe0: 6f 72 74 65 72 4d 65 72 67 65 72 20 2a 70 4d 65  orterMerger *pMe
4ff0: 72 67 65 72 2c 20 0a 20 20 69 6e 74 20 69 4f 75  rger, .  int iOu
5000: 74 0a 29 7b 0a 20 20 69 6e 74 20 69 31 3b 0a 20  t.){.  int i1;. 
5010: 20 69 6e 74 20 69 32 3b 0a 20 20 69 6e 74 20 69   int i2;.  int i
5020: 52 65 73 3b 0a 20 20 56 64 62 65 53 6f 72 74 65  Res;.  VdbeSorte
5030: 72 49 74 65 72 20 2a 70 31 3b 0a 20 20 56 64 62  rIter *p1;.  Vdb
5040: 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70 32 3b  eSorterIter *p2;
5050: 0a 0a 20 20 61 73 73 65 72 74 28 20 69 4f 75 74  ..  assert( iOut
5060: 3c 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65 20  <pMerger->nTree 
5070: 26 26 20 69 4f 75 74 3e 30 20 29 3b 0a 0a 20 20  && iOut>0 );..  
5080: 69 66 28 20 69 4f 75 74 3e 3d 28 70 4d 65 72 67  if( iOut>=(pMerg
5090: 65 72 2d 3e 6e 54 72 65 65 2f 32 29 20 29 7b 0a  er->nTree/2) ){.
50a0: 20 20 20 20 69 31 20 3d 20 28 69 4f 75 74 20 2d      i1 = (iOut -
50b0: 20 70 4d 65 72 67 65 72 2d 3e 6e 54 72 65 65 2f   pMerger->nTree/
50c0: 32 29 20 2a 20 32 3b 0a 20 20 20 20 69 32 20 3d  2) * 2;.    i2 =
50d0: 20 69 31 20 2b 20 31 3b 0a 20 20 7d 65 6c 73 65   i1 + 1;.  }else
50e0: 7b 0a 20 20 20 20 69 31 20 3d 20 70 4d 65 72 67  {.    i1 = pMerg
50f0: 65 72 2d 3e 61 54 72 65 65 5b 69 4f 75 74 2a 32  er->aTree[iOut*2
5100: 5d 3b 0a 20 20 20 20 69 32 20 3d 20 70 4d 65 72  ];.    i2 = pMer
5110: 67 65 72 2d 3e 61 54 72 65 65 5b 69 4f 75 74 2a  ger->aTree[iOut*
5120: 32 2b 31 5d 3b 0a 20 20 7d 0a 0a 20 20 70 31 20  2+1];.  }..  p1 
5130: 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65  = &pMerger->aIte
5140: 72 5b 69 31 5d 3b 0a 20 20 70 32 20 3d 20 26 70  r[i1];.  p2 = &p
5150: 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 69 32  Merger->aIter[i2
5160: 5d 3b 0a 0a 20 20 69 66 28 20 70 31 2d 3e 70 46  ];..  if( p1->pF
5170: 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69 52  ile==0 ){.    iR
5180: 65 73 20 3d 20 69 32 3b 0a 20 20 7d 65 6c 73 65  es = i2;.  }else
5190: 20 69 66 28 20 70 32 2d 3e 70 46 69 6c 65 3d 3d   if( p2->pFile==
51a0: 30 20 29 7b 0a 20 20 20 20 69 52 65 73 20 3d 20  0 ){.    iRes = 
51b0: 69 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  i1;.  }else{.   
51c0: 20 69 6e 74 20 72 65 73 3b 0a 20 20 20 20 61 73   int res;.    as
51d0: 73 65 72 74 28 20 70 54 68 72 65 61 64 2d 3e 70  sert( pThread->p
51e0: 55 6e 70 61 63 6b 65 64 21 3d 30 20 29 3b 20 20  Unpacked!=0 );  
51f0: 2f 2a 20 61 6c 6c 6f 63 61 74 65 64 20 69 6e 20  /* allocated in 
5200: 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28  vdbeSorterMerge(
5210: 29 20 2a 2f 0a 20 20 20 20 76 64 62 65 53 6f 72  ) */.    vdbeSor
5220: 74 65 72 43 6f 6d 70 61 72 65 28 0a 20 20 20 20  terCompare(.    
5230: 20 20 20 20 70 54 68 72 65 61 64 2c 20 30 2c 20      pThread, 0, 
5240: 70 31 2d 3e 61 4b 65 79 2c 20 70 31 2d 3e 6e 4b  p1->aKey, p1->nK
5250: 65 79 2c 20 70 32 2d 3e 61 4b 65 79 2c 20 70 32  ey, p2->aKey, p2
5260: 2d 3e 6e 4b 65 79 2c 20 26 72 65 73 0a 20 20 20  ->nKey, &res.   
5270: 20 29 3b 0a 20 20 20 20 69 66 28 20 72 65 73 3c   );.    if( res<
5280: 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 52 65 73  =0 ){.      iRes
5290: 20 3d 20 69 31 3b 0a 20 20 20 20 7d 65 6c 73 65   = i1;.    }else
52a0: 7b 0a 20 20 20 20 20 20 69 52 65 73 20 3d 20 69  {.      iRes = i
52b0: 32 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  2;.    }.  }..  
52c0: 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65 5b 69  pMerger->aTree[i
52d0: 4f 75 74 5d 20 3d 20 69 52 65 73 3b 0a 20 20 72  Out] = iRes;.  r
52e0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
52f0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61  .}../*.** Initia
5300: 6c 69 7a 65 20 74 68 65 20 74 65 6d 70 6f 72 61  lize the tempora
5310: 72 79 20 69 6e 64 65 78 20 63 75 72 73 6f 72 20  ry index cursor 
5320: 6a 75 73 74 20 6f 70 65 6e 65 64 20 61 73 20 61  just opened as a
5330: 20 73 6f 72 74 65 72 20 63 75 72 73 6f 72 2e 0a   sorter cursor..
5340: 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64  */.int sqlite3Vd
5350: 62 65 53 6f 72 74 65 72 49 6e 69 74 28 73 71 6c  beSorterInit(sql
5360: 69 74 65 33 20 2a 64 62 2c 20 56 64 62 65 43 75  ite3 *db, VdbeCu
5370: 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 69  rsor *pCsr){.  i
5380: 6e 74 20 70 67 73 7a 3b 20 20 20 20 20 20 20 20  nt pgsz;        
5390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
53a0: 2a 20 50 61 67 65 20 73 69 7a 65 20 6f 66 20 6d  * Page size of m
53b0: 61 69 6e 20 64 61 74 61 62 61 73 65 20 2a 2f 0a  ain database */.
53c0: 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20    int i;        
53d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
53e0: 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65    /* Used to ite
53f0: 72 61 74 65 20 74 68 72 6f 75 67 68 20 61 54 68  rate through aTh
5400: 72 65 61 64 5b 5d 20 2a 2f 0a 20 20 69 6e 74 20  read[] */.  int 
5410: 6d 78 43 61 63 68 65 3b 20 20 20 20 20 20 20 20  mxCache;        
5420: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
5430: 61 63 68 65 20 73 69 7a 65 20 2a 2f 0a 20 20 56  ache size */.  V
5440: 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
5450: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  er;            /
5460: 2a 20 54 68 65 20 6e 65 77 20 73 6f 72 74 65 72  * The new sorter
5470: 20 2a 2f 0a 20 20 4b 65 79 49 6e 66 6f 20 2a 70   */.  KeyInfo *p
5480: 4b 65 79 49 6e 66 6f 3b 20 20 20 20 20 20 20 20  KeyInfo;        
5490: 20 20 20 20 20 20 2f 2a 20 43 6f 70 79 20 6f 66        /* Copy of
54a0: 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 20   pCsr->pKeyInfo 
54b0: 77 69 74 68 20 64 62 3d 3d 30 20 2a 2f 0a 20 20  with db==0 */.  
54c0: 69 6e 74 20 73 7a 4b 65 79 49 6e 66 6f 3b 20 20  int szKeyInfo;  
54d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
54e0: 2f 2a 20 53 69 7a 65 20 6f 66 20 70 43 73 72 2d  /* Size of pCsr-
54f0: 3e 70 4b 65 79 49 6e 66 6f 20 69 6e 20 62 79 74  >pKeyInfo in byt
5500: 65 73 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d  es */.  int rc =
5510: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 61   SQLITE_OK;..  a
5520: 73 73 65 72 74 28 20 70 43 73 72 2d 3e 70 4b 65  ssert( pCsr->pKe
5530: 79 49 6e 66 6f 20 26 26 20 70 43 73 72 2d 3e 70  yInfo && pCsr->p
5540: 42 74 3d 3d 30 20 29 3b 0a 20 20 73 7a 4b 65 79  Bt==0 );.  szKey
5550: 49 6e 66 6f 20 3d 20 73 69 7a 65 6f 66 28 4b 65  Info = sizeof(Ke
5560: 79 49 6e 66 6f 29 20 2b 20 28 70 43 73 72 2d 3e  yInfo) + (pCsr->
5570: 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64  pKeyInfo->nField
5580: 2d 31 29 2a 73 69 7a 65 6f 66 28 43 6f 6c 6c 53  -1)*sizeof(CollS
5590: 65 71 2a 29 3b 0a 20 20 70 53 6f 72 74 65 72 20  eq*);.  pSorter 
55a0: 3d 20 28 56 64 62 65 53 6f 72 74 65 72 2a 29 73  = (VdbeSorter*)s
55b0: 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f 63 5a 65  qlite3DbMallocZe
55c0: 72 6f 28 64 62 2c 20 73 69 7a 65 6f 66 28 56 64  ro(db, sizeof(Vd
55d0: 62 65 53 6f 72 74 65 72 29 2b 73 7a 4b 65 79 49  beSorter)+szKeyI
55e0: 6e 66 6f 29 3b 0a 20 20 70 43 73 72 2d 3e 70 53  nfo);.  pCsr->pS
55f0: 6f 72 74 65 72 20 3d 20 70 53 6f 72 74 65 72 3b  orter = pSorter;
5600: 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72 3d 3d  .  if( pSorter==
5610: 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  0 ){.    rc = SQ
5620: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65  LITE_NOMEM;.  }e
5630: 6c 73 65 7b 0a 20 20 20 20 70 4b 65 79 49 6e 66  lse{.    pKeyInf
5640: 6f 20 3d 20 28 4b 65 79 49 6e 66 6f 2a 29 26 70  o = (KeyInfo*)&p
5650: 53 6f 72 74 65 72 5b 31 5d 3b 0a 20 20 20 20 6d  Sorter[1];.    m
5660: 65 6d 63 70 79 28 70 4b 65 79 49 6e 66 6f 2c 20  emcpy(pKeyInfo, 
5670: 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20  pCsr->pKeyInfo, 
5680: 73 7a 4b 65 79 49 6e 66 6f 29 3b 0a 20 20 20 20  szKeyInfo);.    
5690: 70 4b 65 79 49 6e 66 6f 2d 3e 64 62 20 3d 20 30  pKeyInfo->db = 0
56a0: 3b 0a 20 20 20 20 70 67 73 7a 20 3d 20 73 71 6c  ;.    pgsz = sql
56b0: 69 74 65 33 42 74 72 65 65 47 65 74 50 61 67 65  ite3BtreeGetPage
56c0: 53 69 7a 65 28 64 62 2d 3e 61 44 62 5b 30 5d 2e  Size(db->aDb[0].
56d0: 70 42 74 29 3b 0a 0a 20 20 20 20 66 6f 72 28 69  pBt);..    for(i
56e0: 3d 30 3b 20 69 3c 53 51 4c 49 54 45 5f 4d 41 58  =0; i<SQLITE_MAX
56f0: 5f 53 4f 52 54 45 52 5f 54 48 52 45 41 44 3b 20  _SORTER_THREAD; 
5700: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 53 6f 72 74  i++){.      Sort
5710: 65 72 54 68 72 65 61 64 20 2a 70 54 68 72 65 61  erThread *pThrea
5720: 64 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 54  d = &pSorter->aT
5730: 68 72 65 61 64 5b 69 5d 3b 0a 20 20 20 20 20 20  hread[i];.      
5740: 70 54 68 72 65 61 64 2d 3e 70 4b 65 79 49 6e 66  pThread->pKeyInf
5750: 6f 20 3d 20 70 4b 65 79 49 6e 66 6f 3b 0a 20 20  o = pKeyInfo;.  
5760: 20 20 20 20 70 54 68 72 65 61 64 2d 3e 70 56 66      pThread->pVf
5770: 73 20 3d 20 64 62 2d 3e 70 56 66 73 3b 0a 20 20  s = db->pVfs;.  
5780: 20 20 20 20 70 54 68 72 65 61 64 2d 3e 70 67 73      pThread->pgs
5790: 7a 20 3d 20 70 67 73 7a 3b 0a 20 20 20 20 7d 0a  z = pgsz;.    }.
57a0: 0a 20 20 20 20 69 66 28 20 21 73 71 6c 69 74 65  .    if( !sqlite
57b0: 33 54 65 6d 70 49 6e 4d 65 6d 6f 72 79 28 64 62  3TempInMemory(db
57c0: 29 20 29 7b 0a 20 20 20 20 20 20 70 53 6f 72 74  ) ){.      pSort
57d0: 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a 65 20 3d 20  er->mnPmaSize = 
57e0: 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49  SORTER_MIN_WORKI
57f0: 4e 47 20 2a 20 70 67 73 7a 3b 0a 20 20 20 20 20  NG * pgsz;.     
5800: 20 6d 78 43 61 63 68 65 20 3d 20 64 62 2d 3e 61   mxCache = db->a
5810: 44 62 5b 30 5d 2e 70 53 63 68 65 6d 61 2d 3e 63  Db[0].pSchema->c
5820: 61 63 68 65 5f 73 69 7a 65 3b 0a 20 20 20 20 20  ache_size;.     
5830: 20 69 66 28 20 6d 78 43 61 63 68 65 3c 53 4f 52   if( mxCache<SOR
5840: 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20  TER_MIN_WORKING 
5850: 29 20 6d 78 43 61 63 68 65 20 3d 20 53 4f 52 54  ) mxCache = SORT
5860: 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 3b 0a  ER_MIN_WORKING;.
5870: 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6d        pSorter->m
5880: 78 50 6d 61 53 69 7a 65 20 3d 20 6d 78 43 61 63  xPmaSize = mxCac
5890: 68 65 20 2a 20 70 67 73 7a 3b 0a 0a 20 20 20 20  he * pgsz;..    
58a0: 20 20 2f 2a 20 49 66 20 74 68 65 20 61 70 70 6c    /* If the appl
58b0: 69 63 61 74 69 6f 6e 20 69 73 20 75 73 69 6e 67  ication is using
58c0: 20 6d 65 6d 73 79 73 33 20 6f 72 20 6d 65 6d 73   memsys3 or mems
58d0: 79 73 35 2c 20 75 73 65 20 61 20 73 65 70 61 72  ys5, use a separ
58e0: 61 74 65 20 0a 20 20 20 20 20 20 2a 2a 20 61 6c  ate .      ** al
58f0: 6c 6f 63 61 74 69 6f 6e 20 66 6f 72 20 65 61 63  location for eac
5900: 68 20 73 6f 72 74 2d 6b 65 79 20 69 6e 20 6d 65  h sort-key in me
5910: 6d 6f 72 79 2e 20 4f 74 68 65 72 77 69 73 65 2c  mory. Otherwise,
5920: 20 75 73 65 20 61 20 73 69 6e 67 6c 65 20 62 69   use a single bi
5930: 67 0a 20 20 20 20 20 20 2a 2a 20 61 6c 6c 6f 63  g.      ** alloc
5940: 61 74 69 6f 6e 20 61 74 20 70 53 6f 72 74 65 72  ation at pSorter
5950: 2d 3e 61 4d 65 6d 6f 72 79 20 66 6f 72 20 61 6c  ->aMemory for al
5960: 6c 20 73 6f 72 74 2d 6b 65 79 73 2e 20 20 2a 2f  l sort-keys.  */
5970: 0a 20 20 20 20 20 20 69 66 28 20 73 71 6c 69 74  .      if( sqlit
5980: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70  e3GlobalConfig.p
5990: 48 65 61 70 3d 3d 30 20 29 7b 0a 20 20 20 20 20  Heap==0 ){.     
59a0: 20 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74     assert( pSort
59b0: 65 72 2d 3e 69 4d 65 6d 6f 72 79 3d 3d 30 20 29  er->iMemory==0 )
59c0: 3b 0a 20 20 20 20 20 20 20 20 70 53 6f 72 74 65  ;.        pSorte
59d0: 72 2d 3e 6e 4d 65 6d 6f 72 79 20 3d 20 70 67 73  r->nMemory = pgs
59e0: 7a 3b 0a 20 20 20 20 20 20 20 20 70 53 6f 72 74  z;.        pSort
59f0: 65 72 2d 3e 61 4d 65 6d 6f 72 79 20 3d 20 28 75  er->aMemory = (u
5a00: 38 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  8*)sqlite3Malloc
5a10: 28 70 67 73 7a 29 3b 0a 20 20 20 20 20 20 20 20  (pgsz);.        
5a20: 69 66 28 20 21 70 53 6f 72 74 65 72 2d 3e 61 4d  if( !pSorter->aM
5a30: 65 6d 6f 72 79 20 29 20 72 63 20 3d 20 53 51 4c  emory ) rc = SQL
5a40: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
5a50: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
5a60: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
5a70: 0a 2a 2a 20 46 72 65 65 20 74 68 65 20 6c 69 73  .** Free the lis
5a80: 74 20 6f 66 20 73 6f 72 74 65 64 20 72 65 63 6f  t of sorted reco
5a90: 72 64 73 20 73 74 61 72 74 69 6e 67 20 61 74 20  rds starting at 
5aa0: 70 52 65 63 6f 72 64 2e 0a 2a 2f 0a 73 74 61 74  pRecord..*/.stat
5ab0: 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74  ic void vdbeSort
5ac0: 65 72 52 65 63 6f 72 64 46 72 65 65 28 73 71 6c  erRecordFree(sql
5ad0: 69 74 65 33 20 2a 64 62 2c 20 53 6f 72 74 65 72  ite3 *db, Sorter
5ae0: 52 65 63 6f 72 64 20 2a 70 52 65 63 6f 72 64 29  Record *pRecord)
5af0: 7b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  {.  SorterRecord
5b00: 20 2a 70 3b 0a 20 20 53 6f 72 74 65 72 52 65 63   *p;.  SorterRec
5b10: 6f 72 64 20 2a 70 4e 65 78 74 3b 0a 20 20 66 6f  ord *pNext;.  fo
5b20: 72 28 70 3d 70 52 65 63 6f 72 64 3b 20 70 3b 20  r(p=pRecord; p; 
5b30: 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 4e  p=pNext){.    pN
5b40: 65 78 74 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74  ext = p->u.pNext
5b50: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 44 62 46  ;.    sqlite3DbF
5b60: 72 65 65 28 64 62 2c 20 70 29 3b 0a 20 20 7d 0a  ree(db, p);.  }.
5b70: 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6c  }../*.** Free al
5b80: 6c 20 72 65 73 6f 75 72 63 65 73 20 6f 77 6e 65  l resources owne
5b90: 64 20 62 79 20 74 68 65 20 6f 62 6a 65 63 74 20  d by the object 
5ba0: 69 6e 64 69 63 61 74 65 64 20 62 79 20 61 72 67  indicated by arg
5bb0: 75 6d 65 6e 74 20 70 54 68 72 65 61 64 2e 20 41  ument pThread. A
5bc0: 6c 6c 20 0a 2a 2a 20 66 69 65 6c 64 73 20 6f 66  ll .** fields of
5bd0: 20 2a 70 54 68 72 65 61 64 20 61 72 65 20 7a 65   *pThread are ze
5be0: 72 6f 65 64 20 62 65 66 6f 72 65 20 72 65 74 75  roed before retu
5bf0: 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63  rning..*/.static
5c00: 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72   void vdbeSorter
5c10: 54 68 72 65 61 64 43 6c 65 61 6e 75 70 28 73 71  ThreadCleanup(sq
5c20: 6c 69 74 65 33 20 2a 64 62 2c 20 53 6f 72 74 65  lite3 *db, Sorte
5c30: 72 54 68 72 65 61 64 20 2a 70 54 68 72 65 61 64  rThread *pThread
5c40: 29 7b 0a 20 20 73 71 6c 69 74 65 33 44 62 46 72  ){.  sqlite3DbFr
5c50: 65 65 28 64 62 2c 20 70 54 68 72 65 61 64 2d 3e  ee(db, pThread->
5c60: 70 55 6e 70 61 63 6b 65 64 29 3b 0a 20 20 70 54  pUnpacked);.  pT
5c70: 68 72 65 61 64 2d 3e 70 55 6e 70 61 63 6b 65 64  hread->pUnpacked
5c80: 20 3d 20 30 3b 0a 20 20 69 66 28 20 70 54 68 72   = 0;.  if( pThr
5c90: 65 61 64 2d 3e 61 4c 69 73 74 4d 65 6d 6f 72 79  ead->aListMemory
5ca0: 3d 3d 30 20 29 7b 0a 20 20 20 20 76 64 62 65 53  ==0 ){.    vdbeS
5cb0: 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65 65 28  orterRecordFree(
5cc0: 30 2c 20 70 54 68 72 65 61 64 2d 3e 70 4c 69 73  0, pThread->pLis
5cd0: 74 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  t);.  }else{.   
5ce0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 54   sqlite3_free(pT
5cf0: 68 72 65 61 64 2d 3e 61 4c 69 73 74 4d 65 6d 6f  hread->aListMemo
5d00: 72 79 29 3b 0a 20 20 20 20 70 54 68 72 65 61 64  ry);.    pThread
5d10: 2d 3e 61 4c 69 73 74 4d 65 6d 6f 72 79 20 3d 20  ->aListMemory = 
5d20: 30 3b 0a 20 20 7d 0a 20 20 70 54 68 72 65 61 64  0;.  }.  pThread
5d30: 2d 3e 70 4c 69 73 74 20 3d 20 30 3b 0a 20 20 69  ->pList = 0;.  i
5d40: 66 28 20 70 54 68 72 65 61 64 2d 3e 70 54 65 6d  f( pThread->pTem
5d50: 70 31 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  p1 ){.    sqlite
5d60: 33 4f 73 43 6c 6f 73 65 46 72 65 65 28 70 54 68  3OsCloseFree(pTh
5d70: 72 65 61 64 2d 3e 70 54 65 6d 70 31 29 3b 0a 20  read->pTemp1);. 
5d80: 20 20 20 70 54 68 72 65 61 64 2d 3e 70 54 65 6d     pThread->pTem
5d90: 70 31 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f  p1 = 0;.  }.}../
5da0: 2a 0a 2a 2a 20 4a 6f 69 6e 20 61 6c 6c 20 74 68  *.** Join all th
5db0: 72 65 61 64 73 2e 20 20 0a 2a 2f 0a 73 74 61 74  reads.  .*/.stat
5dc0: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
5dd0: 72 4a 6f 69 6e 41 6c 6c 28 56 64 62 65 53 6f 72  rJoinAll(VdbeSor
5de0: 74 65 72 20 2a 70 53 6f 72 74 65 72 2c 20 69 6e  ter *pSorter, in
5df0: 74 20 72 63 69 6e 29 7b 0a 20 20 69 6e 74 20 72  t rcin){.  int r
5e00: 63 20 3d 20 72 63 69 6e 3b 0a 20 20 69 6e 74 20  c = rcin;.  int 
5e10: 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  i;.  for(i=0; i<
5e20: 53 51 4c 49 54 45 5f 4d 41 58 5f 53 4f 52 54 45  SQLITE_MAX_SORTE
5e30: 52 5f 54 48 52 45 41 44 3b 20 69 2b 2b 29 7b 0a  R_THREAD; i++){.
5e40: 20 20 20 20 53 6f 72 74 65 72 54 68 72 65 61 64      SorterThread
5e50: 20 2a 70 54 68 72 65 61 64 20 3d 20 26 70 53 6f   *pThread = &pSo
5e60: 72 74 65 72 2d 3e 61 54 68 72 65 61 64 5b 69 5d  rter->aThread[i]
5e70: 3b 0a 20 20 20 20 69 66 28 20 70 54 68 72 65 61  ;.    if( pThrea
5e80: 64 2d 3e 70 54 68 72 65 61 64 20 29 7b 0a 20 20  d->pThread ){.  
5e90: 20 20 20 20 76 6f 69 64 20 2a 70 52 65 74 3b 0a      void *pRet;.
5ea0: 20 20 20 20 20 20 69 6e 74 20 72 63 32 20 3d 20        int rc2 = 
5eb0: 73 71 6c 69 74 65 33 54 68 72 65 61 64 4a 6f 69  sqlite3ThreadJoi
5ec0: 6e 28 70 54 68 72 65 61 64 2d 3e 70 54 68 72 65  n(pThread->pThre
5ed0: 61 64 2c 20 26 70 52 65 74 29 3b 0a 20 20 20 20  ad, &pRet);.    
5ee0: 20 20 70 54 68 72 65 61 64 2d 3e 70 54 68 72 65    pThread->pThre
5ef0: 61 64 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 54  ad = 0;.      pT
5f00: 68 72 65 61 64 2d 3e 62 44 6f 6e 65 20 3d 20 30  hread->bDone = 0
5f10: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ;.      if( rc==
5f20: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d  SQLITE_OK ) rc =
5f30: 20 72 63 32 3b 0a 20 20 20 20 20 20 69 66 28 20   rc2;.      if( 
5f40: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc==SQLITE_OK ) 
5f50: 72 63 20 3d 20 53 51 4c 49 54 45 5f 50 54 52 5f  rc = SQLITE_PTR_
5f60: 54 4f 5f 49 4e 54 28 70 52 65 74 29 3b 0a 20 20  TO_INT(pRet);.  
5f70: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
5f80: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 6c   rc;.}../*.** Al
5f90: 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 53 6f 72  locate a new Sor
5fa0: 74 65 72 4d 65 72 67 65 72 20 6f 62 6a 65 63 74  terMerger object
5fb0: 20 77 69 74 68 20 73 70 61 63 65 20 66 6f 72 20   with space for 
5fc0: 6e 49 74 65 72 20 69 74 65 72 61 74 6f 72 73 2e  nIter iterators.
5fd0: 0a 2a 2f 0a 73 74 61 74 69 63 20 53 6f 72 74 65  .*/.static Sorte
5fe0: 72 4d 65 72 67 65 72 20 2a 76 64 62 65 53 6f 72  rMerger *vdbeSor
5ff0: 74 65 72 4d 65 72 67 65 72 4e 65 77 28 69 6e 74  terMergerNew(int
6000: 20 6e 49 74 65 72 29 7b 0a 20 20 69 6e 74 20 4e   nIter){.  int N
6010: 20 3d 20 32 3b 20 20 20 20 20 20 20 20 20 20 20   = 2;           
6020: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6d             /* Sm
6030: 61 6c 6c 65 73 74 20 70 6f 77 65 72 20 6f 66 20  allest power of 
6040: 74 77 6f 20 3e 3d 20 6e 49 74 65 72 20 2a 2f 0a  two >= nIter */.
6050: 20 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20    int nByte;    
6060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6070: 20 20 2f 2a 20 54 6f 74 61 6c 20 62 79 74 65 73    /* Total bytes
6080: 20 6f 66 20 73 70 61 63 65 20 74 6f 20 61 6c 6c   of space to all
6090: 6f 63 61 74 65 20 2a 2f 0a 20 20 53 6f 72 74 65  ocate */.  Sorte
60a0: 72 4d 65 72 67 65 72 20 2a 70 4e 65 77 3b 20 20  rMerger *pNew;  
60b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f             /* Po
60c0: 69 6e 74 65 72 20 74 6f 20 61 6c 6c 6f 63 61 74  inter to allocat
60d0: 65 64 20 6f 62 6a 65 63 74 20 74 6f 20 72 65 74  ed object to ret
60e0: 75 72 6e 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74  urn */..  assert
60f0: 28 20 6e 49 74 65 72 3c 3d 53 4f 52 54 45 52 5f  ( nIter<=SORTER_
6100: 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20  MAX_MERGE_COUNT 
6110: 29 3b 0a 20 20 77 68 69 6c 65 28 20 4e 3c 6e 49  );.  while( N<nI
6120: 74 65 72 20 29 20 4e 20 2b 3d 20 4e 3b 0a 20 20  ter ) N += N;.  
6130: 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 53  nByte = sizeof(S
6140: 6f 72 74 65 72 4d 65 72 67 65 72 29 20 2b 20 4e  orterMerger) + N
6150: 20 2a 20 28 73 69 7a 65 6f 66 28 69 6e 74 29 20   * (sizeof(int) 
6160: 2b 20 73 69 7a 65 6f 66 28 56 64 62 65 53 6f 72  + sizeof(VdbeSor
6170: 74 65 72 49 74 65 72 29 29 3b 0a 0a 20 20 70 4e  terIter));..  pN
6180: 65 77 20 3d 20 28 53 6f 72 74 65 72 4d 65 72 67  ew = (SorterMerg
6190: 65 72 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  er*)sqlite3Mallo
61a0: 63 5a 65 72 6f 28 6e 42 79 74 65 29 3b 0a 20 20  cZero(nByte);.  
61b0: 69 66 28 20 70 4e 65 77 20 29 7b 0a 20 20 20 20  if( pNew ){.    
61c0: 70 4e 65 77 2d 3e 6e 54 72 65 65 20 3d 20 4e 3b  pNew->nTree = N;
61d0: 0a 20 20 20 20 70 4e 65 77 2d 3e 61 49 74 65 72  .    pNew->aIter
61e0: 20 3d 20 28 56 64 62 65 53 6f 72 74 65 72 49 74   = (VdbeSorterIt
61f0: 65 72 2a 29 26 70 4e 65 77 5b 31 5d 3b 0a 20 20  er*)&pNew[1];.  
6200: 20 20 70 4e 65 77 2d 3e 61 54 72 65 65 20 3d 20    pNew->aTree = 
6210: 28 69 6e 74 2a 29 26 70 4e 65 77 2d 3e 61 49 74  (int*)&pNew->aIt
6220: 65 72 5b 4e 5d 3b 0a 20 20 7d 0a 20 20 72 65 74  er[N];.  }.  ret
6230: 75 72 6e 20 70 4e 65 77 3b 0a 7d 0a 0a 2f 2a 0a  urn pNew;.}../*.
6240: 2a 2a 20 52 65 73 65 74 20 61 20 6d 65 72 67 65  ** Reset a merge
6250: 72 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  r.*/.static void
6260: 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65   vdbeSorterMerge
6270: 72 52 65 73 65 74 28 53 6f 72 74 65 72 4d 65 72  rReset(SorterMer
6280: 67 65 72 20 2a 70 4d 65 72 67 65 72 29 7b 0a 20  ger *pMerger){. 
6290: 20 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 70 4d   int i;.  if( pM
62a0: 65 72 67 65 72 20 29 7b 0a 20 20 20 20 66 6f 72  erger ){.    for
62b0: 28 69 3d 30 3b 20 69 3c 70 4d 65 72 67 65 72 2d  (i=0; i<pMerger-
62c0: 3e 6e 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20 20  >nTree; i++){.  
62d0: 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 49 74      vdbeSorterIt
62e0: 65 72 5a 65 72 6f 28 26 70 4d 65 72 67 65 72 2d  erZero(&pMerger-
62f0: 3e 61 49 74 65 72 5b 69 5d 29 3b 0a 20 20 20 20  >aIter[i]);.    
6300: 7d 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  }.  }.}.../*.** 
6310: 46 72 65 65 20 74 68 65 20 53 6f 72 74 65 72 4d  Free the SorterM
6320: 65 72 67 65 72 20 6f 62 6a 65 63 74 20 70 61 73  erger object pas
6330: 73 65 64 20 61 73 20 74 68 65 20 6f 6e 6c 79 20  sed as the only 
6340: 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61  argument..*/.sta
6350: 74 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72  tic void vdbeSor
6360: 74 65 72 4d 65 72 67 65 72 46 72 65 65 28 53 6f  terMergerFree(So
6370: 72 74 65 72 4d 65 72 67 65 72 20 2a 70 4d 65 72  rterMerger *pMer
6380: 67 65 72 29 7b 0a 20 20 76 64 62 65 53 6f 72 74  ger){.  vdbeSort
6390: 65 72 4d 65 72 67 65 72 52 65 73 65 74 28 70 4d  erMergerReset(pM
63a0: 65 72 67 65 72 29 3b 0a 20 20 73 71 6c 69 74 65  erger);.  sqlite
63b0: 33 5f 66 72 65 65 28 70 4d 65 72 67 65 72 29 3b  3_free(pMerger);
63c0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65 74 20  .}../*.** Reset 
63d0: 61 20 73 6f 72 74 69 6e 67 20 63 75 72 73 6f 72  a sorting cursor
63e0: 20 62 61 63 6b 20 74 6f 20 69 74 73 20 6f 72 69   back to its ori
63f0: 67 69 6e 61 6c 20 65 6d 70 74 79 20 73 74 61 74  ginal empty stat
6400: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  e..*/.void sqlit
6410: 65 33 56 64 62 65 53 6f 72 74 65 72 52 65 73 65  e3VdbeSorterRese
6420: 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 56  t(sqlite3 *db, V
6430: 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
6440: 65 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  er){.  int i;.  
6450: 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e 41 6c  vdbeSorterJoinAl
6460: 6c 28 70 53 6f 72 74 65 72 2c 20 53 51 4c 49 54  l(pSorter, SQLIT
6470: 45 5f 4f 4b 29 3b 0a 20 20 66 6f 72 28 69 3d 30  E_OK);.  for(i=0
6480: 3b 20 69 3c 53 51 4c 49 54 45 5f 4d 41 58 5f 53  ; i<SQLITE_MAX_S
6490: 4f 52 54 45 52 5f 54 48 52 45 41 44 3b 20 69 2b  ORTER_THREAD; i+
64a0: 2b 29 7b 0a 20 20 20 20 53 6f 72 74 65 72 54 68  +){.    SorterTh
64b0: 72 65 61 64 20 2a 70 54 68 72 65 61 64 20 3d 20  read *pThread = 
64c0: 26 70 53 6f 72 74 65 72 2d 3e 61 54 68 72 65 61  &pSorter->aThrea
64d0: 64 5b 69 5d 3b 0a 20 20 20 20 76 64 62 65 53 6f  d[i];.    vdbeSo
64e0: 72 74 65 72 54 68 72 65 61 64 43 6c 65 61 6e 75  rterThreadCleanu
64f0: 70 28 64 62 2c 20 70 54 68 72 65 61 64 29 3b 0a  p(db, pThread);.
6500: 20 20 7d 0a 20 20 69 66 28 20 70 53 6f 72 74 65    }.  if( pSorte
6510: 72 2d 3e 61 4d 65 6d 6f 72 79 3d 3d 30 20 29 7b  r->aMemory==0 ){
6520: 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 52  .    vdbeSorterR
6530: 65 63 6f 72 64 46 72 65 65 28 30 2c 20 70 53 6f  ecordFree(0, pSo
6540: 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 29 3b 0a  rter->pRecord);.
6550: 20 20 7d 0a 20 20 76 64 62 65 53 6f 72 74 65 72    }.  vdbeSorter
6560: 4d 65 72 67 65 72 52 65 73 65 74 28 70 53 6f 72  MergerReset(pSor
6570: 74 65 72 2d 3e 70 4d 65 72 67 65 72 29 3b 0a 20  ter->pMerger);. 
6580: 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72   pSorter->pRecor
6590: 64 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74 65 72  d = 0;.  pSorter
65a0: 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20 3d 20 30 3b  ->nInMemory = 0;
65b0: 0a 20 20 70 53 6f 72 74 65 72 2d 3e 62 55 73 65  .  pSorter->bUse
65c0: 50 4d 41 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74  PMA = 0;.  pSort
65d0: 65 72 2d 3e 69 4d 65 6d 6f 72 79 20 3d 20 30 3b  er->iMemory = 0;
65e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61  .}../*.** Free a
65f0: 6e 79 20 63 75 72 73 6f 72 20 63 6f 6d 70 6f 6e  ny cursor compon
6600: 65 6e 74 73 20 61 6c 6c 6f 63 61 74 65 64 20 62  ents allocated b
6610: 79 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72  y sqlite3VdbeSor
6620: 74 65 72 58 58 58 20 72 6f 75 74 69 6e 65 73 2e  terXXX routines.
6630: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
6640: 56 64 62 65 53 6f 72 74 65 72 43 6c 6f 73 65 28  VdbeSorterClose(
6650: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 56 64 62  sqlite3 *db, Vdb
6660: 65 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a  eCursor *pCsr){.
6670: 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
6680: 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53  orter = pCsr->pS
6690: 6f 72 74 65 72 3b 0a 20 20 69 66 28 20 70 53 6f  orter;.  if( pSo
66a0: 72 74 65 72 20 29 7b 0a 20 20 20 20 73 71 6c 69  rter ){.    sqli
66b0: 74 65 33 56 64 62 65 53 6f 72 74 65 72 52 65 73  te3VdbeSorterRes
66c0: 65 74 28 64 62 2c 20 70 53 6f 72 74 65 72 29 3b  et(db, pSorter);
66d0: 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 4d  .    vdbeSorterM
66e0: 65 72 67 65 72 46 72 65 65 28 70 53 6f 72 74 65  ergerFree(pSorte
66f0: 72 2d 3e 70 4d 65 72 67 65 72 29 3b 0a 20 20 20  r->pMerger);.   
6700: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 53   sqlite3_free(pS
6710: 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 29 3b  orter->aMemory);
6720: 0a 20 20 20 20 73 71 6c 69 74 65 33 44 62 46 72  .    sqlite3DbFr
6730: 65 65 28 64 62 2c 20 70 53 6f 72 74 65 72 29 3b  ee(db, pSorter);
6740: 0a 20 20 20 20 70 43 73 72 2d 3e 70 53 6f 72 74  .    pCsr->pSort
6750: 65 72 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f  er = 0;.  }.}../
6760: 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 73 70  *.** Allocate sp
6770: 61 63 65 20 66 6f 72 20 61 20 66 69 6c 65 2d 68  ace for a file-h
6780: 61 6e 64 6c 65 20 61 6e 64 20 6f 70 65 6e 20 61  andle and open a
6790: 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 2e   temporary file.
67a0: 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 0a   If successful,.
67b0: 2a 2a 20 73 65 74 20 2a 70 70 46 69 6c 65 20 74  ** set *ppFile t
67c0: 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 6d  o point to the m
67d0: 61 6c 6c 6f 63 27 64 20 66 69 6c 65 2d 68 61 6e  alloc'd file-han
67e0: 64 6c 65 20 61 6e 64 20 72 65 74 75 72 6e 20 53  dle and return S
67f0: 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2a 20 4f 74 68  QLITE_OK..** Oth
6800: 65 72 77 69 73 65 2c 20 73 65 74 20 2a 70 70 46  erwise, set *ppF
6810: 69 6c 65 20 74 6f 20 30 20 61 6e 64 20 72 65 74  ile to 0 and ret
6820: 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72  urn an SQLite er
6830: 72 6f 72 20 63 6f 64 65 2e 0a 2a 2f 0a 73 74 61  ror code..*/.sta
6840: 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74  tic int vdbeSort
6850: 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 73  erOpenTempFile(s
6860: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
6870: 2c 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a  , sqlite3_file *
6880: 2a 70 70 46 69 6c 65 29 7b 0a 20 20 69 6e 74 20  *ppFile){.  int 
6890: 72 63 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  rc;.  rc = sqlit
68a0: 65 33 4f 73 4f 70 65 6e 4d 61 6c 6c 6f 63 28 70  e3OsOpenMalloc(p
68b0: 56 66 73 2c 20 30 2c 20 70 70 46 69 6c 65 2c 0a  Vfs, 0, ppFile,.
68c0: 20 20 20 20 20 20 53 51 4c 49 54 45 5f 4f 50 45        SQLITE_OPE
68d0: 4e 5f 54 45 4d 50 5f 4a 4f 55 52 4e 41 4c 20 7c  N_TEMP_JOURNAL |
68e0: 0a 20 20 20 20 20 20 53 51 4c 49 54 45 5f 4f 50  .      SQLITE_OP
68f0: 45 4e 5f 52 45 41 44 57 52 49 54 45 20 20 20 20  EN_READWRITE    
6900: 7c 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 43 52  | SQLITE_OPEN_CR
6910: 45 41 54 45 20 7c 0a 20 20 20 20 20 20 53 51 4c  EATE |.      SQL
6920: 49 54 45 5f 4f 50 45 4e 5f 45 58 43 4c 55 53 49  ITE_OPEN_EXCLUSI
6930: 56 45 20 20 20 20 7c 20 53 51 4c 49 54 45 5f 4f  VE    | SQLITE_O
6940: 50 45 4e 5f 44 45 4c 45 54 45 4f 4e 43 4c 4f 53  PEN_DELETEONCLOS
6950: 45 2c 20 26 72 63 0a 20 20 29 3b 0a 20 20 69 66  E, &rc.  );.  if
6960: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
6970: 29 7b 0a 20 20 20 20 69 36 34 20 6d 61 78 20 3d  ){.    i64 max =
6980: 20 53 51 4c 49 54 45 5f 4d 41 58 5f 4d 4d 41 50   SQLITE_MAX_MMAP
6990: 5f 53 49 5a 45 3b 0a 20 20 20 20 73 71 6c 69 74  _SIZE;.    sqlit
69a0: 65 33 4f 73 46 69 6c 65 43 6f 6e 74 72 6f 6c 48  e3OsFileControlH
69b0: 69 6e 74 28 20 2a 70 70 46 69 6c 65 2c 20 53 51  int( *ppFile, SQ
69c0: 4c 49 54 45 5f 46 43 4e 54 4c 5f 4d 4d 41 50 5f  LITE_FCNTL_MMAP_
69d0: 53 49 5a 45 2c 20 28 76 6f 69 64 2a 29 26 6d 61  SIZE, (void*)&ma
69e0: 78 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  x);.  }.  return
69f0: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 65   rc;.}../*.** Me
6a00: 72 67 65 20 74 68 65 20 74 77 6f 20 73 6f 72 74  rge the two sort
6a10: 65 64 20 6c 69 73 74 73 20 70 31 20 61 6e 64 20  ed lists p1 and 
6a20: 70 32 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65  p2 into a single
6a30: 20 6c 69 73 74 2e 0a 2a 2a 20 53 65 74 20 2a 70   list..** Set *p
6a40: 70 4f 75 74 20 74 6f 20 74 68 65 20 68 65 61 64  pOut to the head
6a50: 20 6f 66 20 74 68 65 20 6e 65 77 20 6c 69 73 74   of the new list
6a60: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
6a70: 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65   vdbeSorterMerge
6a80: 28 0a 20 20 53 6f 72 74 65 72 54 68 72 65 61 64  (.  SorterThread
6a90: 20 2a 70 54 68 72 65 61 64 2c 20 20 20 20 20 20   *pThread,      
6aa0: 20 20 20 20 2f 2a 20 43 61 6c 6c 69 6e 67 20 74      /* Calling t
6ab0: 68 72 65 61 64 20 63 6f 6e 74 65 78 74 20 2a 2f  hread context */
6ac0: 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20  .  SorterRecord 
6ad0: 2a 70 31 2c 20 20 20 20 20 20 20 20 20 20 20 20  *p1,            
6ae0: 20 20 20 2f 2a 20 46 69 72 73 74 20 6c 69 73 74     /* First list
6af0: 20 74 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20 53   to merge */.  S
6b00: 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 32 2c  orterRecord *p2,
6b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6b20: 2a 20 53 65 63 6f 6e 64 20 6c 69 73 74 20 74 6f  * Second list to
6b30: 20 6d 65 72 67 65 20 2a 2f 0a 20 20 53 6f 72 74   merge */.  Sort
6b40: 65 72 52 65 63 6f 72 64 20 2a 2a 70 70 4f 75 74  erRecord **ppOut
6b50: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
6b60: 55 54 3a 20 48 65 61 64 20 6f 66 20 6d 65 72 67  UT: Head of merg
6b70: 65 64 20 6c 69 73 74 20 2a 2f 0a 29 7b 0a 20 20  ed list */.){.  
6b80: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 46  SorterRecord *pF
6b90: 69 6e 61 6c 20 3d 20 30 3b 0a 20 20 53 6f 72 74  inal = 0;.  Sort
6ba0: 65 72 52 65 63 6f 72 64 20 2a 2a 70 70 20 3d 20  erRecord **pp = 
6bb0: 26 70 46 69 6e 61 6c 3b 0a 20 20 76 6f 69 64 20  &pFinal;.  void 
6bc0: 2a 70 56 61 6c 32 20 3d 20 70 32 20 3f 20 53 52  *pVal2 = p2 ? SR
6bd0: 56 41 4c 28 70 32 29 20 3a 20 30 3b 0a 0a 20 20  VAL(p2) : 0;..  
6be0: 77 68 69 6c 65 28 20 70 31 20 26 26 20 70 32 20  while( p1 && p2 
6bf0: 29 7b 0a 20 20 20 20 69 6e 74 20 72 65 73 3b 0a  ){.    int res;.
6c00: 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 43 6f      vdbeSorterCo
6c10: 6d 70 61 72 65 28 70 54 68 72 65 61 64 2c 20 30  mpare(pThread, 0
6c20: 2c 20 53 52 56 41 4c 28 70 31 29 2c 20 70 31 2d  , SRVAL(p1), p1-
6c30: 3e 6e 56 61 6c 2c 20 70 56 61 6c 32 2c 20 70 32  >nVal, pVal2, p2
6c40: 2d 3e 6e 56 61 6c 2c 20 26 72 65 73 29 3b 0a 20  ->nVal, &res);. 
6c50: 20 20 20 69 66 28 20 72 65 73 3c 3d 30 20 29 7b     if( res<=0 ){
6c60: 0a 20 20 20 20 20 20 2a 70 70 20 3d 20 70 31 3b  .      *pp = p1;
6c70: 0a 20 20 20 20 20 20 70 70 20 3d 20 26 70 31 2d  .      pp = &p1-
6c80: 3e 75 2e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  >u.pNext;.      
6c90: 70 31 20 3d 20 70 31 2d 3e 75 2e 70 4e 65 78 74  p1 = p1->u.pNext
6ca0: 3b 0a 20 20 20 20 20 20 70 56 61 6c 32 20 3d 20  ;.      pVal2 = 
6cb0: 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  0;.    }else{.  
6cc0: 20 20 20 20 2a 70 70 20 3d 20 70 32 3b 0a 20 20      *pp = p2;.  
6cd0: 20 20 20 20 20 70 70 20 3d 20 26 70 32 2d 3e 75       pp = &p2->u
6ce0: 2e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 32  .pNext;.      p2
6cf0: 20 3d 20 70 32 2d 3e 75 2e 70 4e 65 78 74 3b 0a   = p2->u.pNext;.
6d00: 20 20 20 20 20 20 69 66 28 20 70 32 3d 3d 30 20        if( p2==0 
6d10: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 70  ) break;.      p
6d20: 56 61 6c 32 20 3d 20 53 52 56 41 4c 28 70 32 29  Val2 = SRVAL(p2)
6d30: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70  ;.    }.  }.  *p
6d40: 70 20 3d 20 70 31 20 3f 20 70 31 20 3a 20 70 32  p = p1 ? p1 : p2
6d50: 3b 0a 20 20 2a 70 70 4f 75 74 20 3d 20 70 46 69  ;.  *ppOut = pFi
6d60: 6e 61 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f  nal;.}../*.** So
6d70: 72 74 20 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69  rt the linked li
6d80: 73 74 20 6f 66 20 72 65 63 6f 72 64 73 20 68 65  st of records he
6d90: 61 64 65 64 20 61 74 20 70 54 68 72 65 61 64 2d  aded at pThread-
6da0: 3e 70 4c 69 73 74 2e 20 52 65 74 75 72 6e 20 0a  >pList. Return .
6db0: 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20  ** SQLITE_OK if 
6dc0: 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61  successful, or a
6dd0: 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  n SQLite error c
6de0: 6f 64 65 20 28 69 2e 65 2e 20 53 51 4c 49 54 45  ode (i.e. SQLITE
6df0: 5f 4e 4f 4d 45 4d 29 20 69 66 20 0a 2a 2a 20 61  _NOMEM) if .** a
6e00: 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a  n error occurs..
6e10: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
6e20: 62 65 53 6f 72 74 65 72 53 6f 72 74 28 53 6f 72  beSorterSort(Sor
6e30: 74 65 72 54 68 72 65 61 64 20 2a 70 54 68 72 65  terThread *pThre
6e40: 61 64 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  ad){.  int i;.  
6e50: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 2a 61  SorterRecord **a
6e60: 53 6c 6f 74 3b 0a 20 20 53 6f 72 74 65 72 52 65  Slot;.  SorterRe
6e70: 63 6f 72 64 20 2a 70 3b 0a 0a 20 20 61 53 6c 6f  cord *p;..  aSlo
6e80: 74 20 3d 20 28 53 6f 72 74 65 72 52 65 63 6f 72  t = (SorterRecor
6e90: 64 20 2a 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c  d **)sqlite3Mall
6ea0: 6f 63 5a 65 72 6f 28 36 34 20 2a 20 73 69 7a 65  ocZero(64 * size
6eb0: 6f 66 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20  of(SorterRecord 
6ec0: 2a 29 29 3b 0a 20 20 69 66 28 20 21 61 53 6c 6f  *));.  if( !aSlo
6ed0: 74 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  t ){.    return 
6ee0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
6ef0: 7d 0a 0a 20 20 70 20 3d 20 70 54 68 72 65 61 64  }..  p = pThread
6f00: 2d 3e 70 4c 69 73 74 3b 0a 20 20 77 68 69 6c 65  ->pList;.  while
6f10: 28 20 70 20 29 7b 0a 20 20 20 20 53 6f 72 74 65  ( p ){.    Sorte
6f20: 72 52 65 63 6f 72 64 20 2a 70 4e 65 78 74 3b 0a  rRecord *pNext;.
6f30: 20 20 20 20 69 66 28 20 70 54 68 72 65 61 64 2d      if( pThread-
6f40: 3e 61 4c 69 73 74 4d 65 6d 6f 72 79 20 29 7b 0a  >aListMemory ){.
6f50: 20 20 20 20 20 20 69 66 28 20 28 75 38 2a 29 70        if( (u8*)p
6f60: 3d 3d 70 54 68 72 65 61 64 2d 3e 61 4c 69 73 74  ==pThread->aList
6f70: 4d 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20 20  Memory ){.      
6f80: 20 20 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20    pNext = 0;.   
6f90: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
6fa0: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 75 2e 69    assert( p->u.i
6fb0: 4e 65 78 74 3c 73 71 6c 69 74 65 33 4d 61 6c 6c  Next<sqlite3Mall
6fc0: 6f 63 53 69 7a 65 28 70 54 68 72 65 61 64 2d 3e  ocSize(pThread->
6fd0: 61 4c 69 73 74 4d 65 6d 6f 72 79 29 20 29 3b 0a  aListMemory) );.
6fe0: 20 20 20 20 20 20 20 20 70 4e 65 78 74 20 3d 20          pNext = 
6ff0: 28 53 6f 72 74 65 72 52 65 63 6f 72 64 2a 29 26  (SorterRecord*)&
7000: 70 54 68 72 65 61 64 2d 3e 61 4c 69 73 74 4d 65  pThread->aListMe
7010: 6d 6f 72 79 5b 70 2d 3e 75 2e 69 4e 65 78 74 5d  mory[p->u.iNext]
7020: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65  ;.      }.    }e
7030: 6c 73 65 7b 0a 20 20 20 20 20 20 70 4e 65 78 74  lse{.      pNext
7040: 20 3d 20 70 2d 3e 75 2e 70 4e 65 78 74 3b 0a 20   = p->u.pNext;. 
7050: 20 20 20 7d 0a 0a 20 20 20 20 70 2d 3e 75 2e 70     }..    p->u.p
7060: 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 66 6f  Next = 0;.    fo
7070: 72 28 69 3d 30 3b 20 61 53 6c 6f 74 5b 69 5d 3b  r(i=0; aSlot[i];
7080: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 76 64 62   i++){.      vdb
7090: 65 53 6f 72 74 65 72 4d 65 72 67 65 28 70 54 68  eSorterMerge(pTh
70a0: 72 65 61 64 2c 20 70 2c 20 61 53 6c 6f 74 5b 69  read, p, aSlot[i
70b0: 5d 2c 20 26 70 29 3b 0a 20 20 20 20 20 20 61 53  ], &p);.      aS
70c0: 6c 6f 74 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20  lot[i] = 0;.    
70d0: 7d 0a 20 20 20 20 61 53 6c 6f 74 5b 69 5d 20 3d  }.    aSlot[i] =
70e0: 20 70 3b 0a 20 20 20 20 70 20 3d 20 70 4e 65 78   p;.    p = pNex
70f0: 74 3b 0a 20 20 7d 0a 0a 20 20 70 20 3d 20 30 3b  t;.  }..  p = 0;
7100: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 36 34  .  for(i=0; i<64
7110: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 76 64 62 65  ; i++){.    vdbe
7120: 53 6f 72 74 65 72 4d 65 72 67 65 28 70 54 68 72  SorterMerge(pThr
7130: 65 61 64 2c 20 70 2c 20 61 53 6c 6f 74 5b 69 5d  ead, p, aSlot[i]
7140: 2c 20 26 70 29 3b 0a 20 20 7d 0a 20 20 70 54 68  , &p);.  }.  pTh
7150: 72 65 61 64 2d 3e 70 4c 69 73 74 20 3d 20 70 3b  read->pList = p;
7160: 0a 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ..  sqlite3_free
7170: 28 61 53 6c 6f 74 29 3b 0a 20 20 72 65 74 75 72  (aSlot);.  retur
7180: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
7190: 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65  /*.** Initialize
71a0: 20 61 20 66 69 6c 65 2d 77 72 69 74 65 72 20 6f   a file-writer o
71b0: 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  bject..*/.static
71c0: 20 76 6f 69 64 20 66 69 6c 65 57 72 69 74 65 72   void fileWriter
71d0: 49 6e 69 74 28 0a 20 20 73 71 6c 69 74 65 33 5f  Init(.  sqlite3_
71e0: 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 20 20 20  file *pFile,    
71f0: 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20          /* File 
7200: 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a 20  to write to */. 
7210: 20 46 69 6c 65 57 72 69 74 65 72 20 2a 70 2c 20   FileWriter *p, 
7220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7230: 20 2f 2a 20 4f 62 6a 65 63 74 20 74 6f 20 70 6f   /* Object to po
7240: 70 75 6c 61 74 65 20 2a 2f 0a 20 20 69 6e 74 20  pulate */.  int 
7250: 6e 42 75 66 2c 20 20 20 20 20 20 20 20 20 20 20  nBuf,           
7260: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
7270: 75 66 66 65 72 20 73 69 7a 65 20 2a 2f 0a 20 20  uffer size */.  
7280: 69 36 34 20 69 53 74 61 72 74 20 20 20 20 20 20  i64 iStart      
7290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
72a0: 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20 70 46 69  /* Offset of pFi
72b0: 6c 65 20 74 6f 20 62 65 67 69 6e 20 77 72 69 74  le to begin writ
72c0: 69 6e 67 20 61 74 20 2a 2f 0a 29 7b 0a 20 20 6d  ing at */.){.  m
72d0: 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65  emset(p, 0, size
72e0: 6f 66 28 46 69 6c 65 57 72 69 74 65 72 29 29 3b  of(FileWriter));
72f0: 0a 20 20 70 2d 3e 61 42 75 66 66 65 72 20 3d 20  .  p->aBuffer = 
7300: 28 75 38 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c  (u8*)sqlite3Mall
7310: 6f 63 28 6e 42 75 66 29 3b 0a 20 20 69 66 28 20  oc(nBuf);.  if( 
7320: 21 70 2d 3e 61 42 75 66 66 65 72 20 29 7b 0a 20  !p->aBuffer ){. 
7330: 20 20 20 70 2d 3e 65 46 57 45 72 72 20 3d 20 53     p->eFWErr = S
7340: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d  QLITE_NOMEM;.  }
7350: 65 6c 73 65 7b 0a 20 20 20 20 70 2d 3e 69 42 75  else{.    p->iBu
7360: 66 45 6e 64 20 3d 20 70 2d 3e 69 42 75 66 53 74  fEnd = p->iBufSt
7370: 61 72 74 20 3d 20 28 69 53 74 61 72 74 20 25 20  art = (iStart % 
7380: 6e 42 75 66 29 3b 0a 20 20 20 20 70 2d 3e 69 57  nBuf);.    p->iW
7390: 72 69 74 65 4f 66 66 20 3d 20 69 53 74 61 72 74  riteOff = iStart
73a0: 20 2d 20 70 2d 3e 69 42 75 66 53 74 61 72 74 3b   - p->iBufStart;
73b0: 0a 20 20 20 20 70 2d 3e 6e 42 75 66 66 65 72 20  .    p->nBuffer 
73c0: 3d 20 6e 42 75 66 3b 0a 20 20 20 20 70 2d 3e 70  = nBuf;.    p->p
73d0: 46 69 6c 65 20 3d 20 70 46 69 6c 65 3b 0a 20 20  File = pFile;.  
73e0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65  }.}../*.** Write
73f0: 20 6e 44 61 74 61 20 62 79 74 65 73 20 6f 66 20   nData bytes of 
7400: 64 61 74 61 20 74 6f 20 74 68 65 20 66 69 6c 65  data to the file
7410: 2d 77 72 69 74 65 20 6f 62 6a 65 63 74 2e 20 52  -write object. R
7420: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 0a  eturn SQLITE_OK.
7430: 2a 2a 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  ** if successful
7440: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65  , or an SQLite e
7450: 72 72 6f 72 20 63 6f 64 65 20 69 66 20 61 6e 20  rror code if an 
7460: 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f  error occurs..*/
7470: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 69 6c  .static void fil
7480: 65 57 72 69 74 65 72 57 72 69 74 65 28 46 69 6c  eWriterWrite(Fil
7490: 65 57 72 69 74 65 72 20 2a 70 2c 20 75 38 20 2a  eWriter *p, u8 *
74a0: 70 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74 61  pData, int nData
74b0: 29 7b 0a 20 20 69 6e 74 20 6e 52 65 6d 20 3d 20  ){.  int nRem = 
74c0: 6e 44 61 74 61 3b 0a 20 20 77 68 69 6c 65 28 20  nData;.  while( 
74d0: 6e 52 65 6d 3e 30 20 26 26 20 70 2d 3e 65 46 57  nRem>0 && p->eFW
74e0: 45 72 72 3d 3d 30 20 29 7b 0a 20 20 20 20 69 6e  Err==0 ){.    in
74f0: 74 20 6e 43 6f 70 79 20 3d 20 6e 52 65 6d 3b 0a  t nCopy = nRem;.
7500: 20 20 20 20 69 66 28 20 6e 43 6f 70 79 3e 28 70      if( nCopy>(p
7510: 2d 3e 6e 42 75 66 66 65 72 20 2d 20 70 2d 3e 69  ->nBuffer - p->i
7520: 42 75 66 45 6e 64 29 20 29 7b 0a 20 20 20 20 20  BufEnd) ){.     
7530: 20 6e 43 6f 70 79 20 3d 20 70 2d 3e 6e 42 75 66   nCopy = p->nBuf
7540: 66 65 72 20 2d 20 70 2d 3e 69 42 75 66 45 6e 64  fer - p->iBufEnd
7550: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 6d 65 6d  ;.    }..    mem
7560: 63 70 79 28 26 70 2d 3e 61 42 75 66 66 65 72 5b  cpy(&p->aBuffer[
7570: 70 2d 3e 69 42 75 66 45 6e 64 5d 2c 20 26 70 44  p->iBufEnd], &pD
7580: 61 74 61 5b 6e 44 61 74 61 2d 6e 52 65 6d 5d 2c  ata[nData-nRem],
7590: 20 6e 43 6f 70 79 29 3b 0a 20 20 20 20 70 2d 3e   nCopy);.    p->
75a0: 69 42 75 66 45 6e 64 20 2b 3d 20 6e 43 6f 70 79  iBufEnd += nCopy
75b0: 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 69 42 75  ;.    if( p->iBu
75c0: 66 45 6e 64 3d 3d 70 2d 3e 6e 42 75 66 66 65 72  fEnd==p->nBuffer
75d0: 20 29 7b 0a 20 20 20 20 20 20 70 2d 3e 65 46 57   ){.      p->eFW
75e0: 45 72 72 20 3d 20 73 71 6c 69 74 65 33 4f 73 57  Err = sqlite3OsW
75f0: 72 69 74 65 28 70 2d 3e 70 46 69 6c 65 2c 20 0a  rite(p->pFile, .
7600: 20 20 20 20 20 20 20 20 20 20 26 70 2d 3e 61 42            &p->aB
7610: 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 53 74 61  uffer[p->iBufSta
7620: 72 74 5d 2c 20 70 2d 3e 69 42 75 66 45 6e 64 20  rt], p->iBufEnd 
7630: 2d 20 70 2d 3e 69 42 75 66 53 74 61 72 74 2c 20  - p->iBufStart, 
7640: 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e 69 57  .          p->iW
7650: 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42 75  riteOff + p->iBu
7660: 66 53 74 61 72 74 0a 20 20 20 20 20 20 29 3b 0a  fStart.      );.
7670: 20 20 20 20 20 20 70 2d 3e 69 42 75 66 53 74 61        p->iBufSta
7680: 72 74 20 3d 20 70 2d 3e 69 42 75 66 45 6e 64 20  rt = p->iBufEnd 
7690: 3d 20 30 3b 0a 20 20 20 20 20 20 70 2d 3e 69 57  = 0;.      p->iW
76a0: 72 69 74 65 4f 66 66 20 2b 3d 20 70 2d 3e 6e 42  riteOff += p->nB
76b0: 75 66 66 65 72 3b 0a 20 20 20 20 7d 0a 20 20 20  uffer;.    }.   
76c0: 20 61 73 73 65 72 74 28 20 70 2d 3e 69 42 75 66   assert( p->iBuf
76d0: 45 6e 64 3c 70 2d 3e 6e 42 75 66 66 65 72 20 29  End<p->nBuffer )
76e0: 3b 0a 0a 20 20 20 20 6e 52 65 6d 20 2d 3d 20 6e  ;..    nRem -= n
76f0: 43 6f 70 79 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  Copy;.  }.}../*.
7700: 2a 2a 20 46 6c 75 73 68 20 61 6e 79 20 62 75 66  ** Flush any buf
7710: 66 65 72 65 64 20 64 61 74 61 20 74 6f 20 64 69  fered data to di
7720: 73 6b 20 61 6e 64 20 63 6c 65 61 6e 20 75 70 20  sk and clean up 
7730: 74 68 65 20 66 69 6c 65 2d 77 72 69 74 65 72 20  the file-writer 
7740: 6f 62 6a 65 63 74 2e 0a 2a 2a 20 54 68 65 20 72  object..** The r
7750: 65 73 75 6c 74 73 20 6f 66 20 75 73 69 6e 67 20  esults of using 
7760: 74 68 65 20 66 69 6c 65 2d 77 72 69 74 65 72 20  the file-writer 
7770: 61 66 74 65 72 20 74 68 69 73 20 63 61 6c 6c 20  after this call 
7780: 61 72 65 20 75 6e 64 65 66 69 6e 65 64 2e 0a 2a  are undefined..*
7790: 2a 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  * Return SQLITE_
77a0: 4f 4b 20 69 66 20 66 6c 75 73 68 69 6e 67 20 74  OK if flushing t
77b0: 68 65 20 62 75 66 66 65 72 65 64 20 64 61 74 61  he buffered data
77c0: 20 73 75 63 63 65 65 64 73 20 6f 72 20 69 73 20   succeeds or is 
77d0: 6e 6f 74 20 0a 2a 2a 20 72 65 71 75 69 72 65 64  not .** required
77e0: 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 72 65 74  . Otherwise, ret
77f0: 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72  urn an SQLite er
7800: 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20  ror code..**.** 
7810: 42 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  Before returning
7820: 2c 20 73 65 74 20 2a 70 69 45 6f 66 20 74 6f 20  , set *piEof to 
7830: 74 68 65 20 6f 66 66 73 65 74 20 69 6d 6d 65 64  the offset immed
7840: 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 69 6e 67  iately following
7850: 20 74 68 65 0a 2a 2a 20 6c 61 73 74 20 62 79 74   the.** last byt
7860: 65 20 77 72 69 74 74 65 6e 20 74 6f 20 74 68 65  e written to the
7870: 20 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63   file..*/.static
7880: 20 69 6e 74 20 66 69 6c 65 57 72 69 74 65 72 46   int fileWriterF
7890: 69 6e 69 73 68 28 46 69 6c 65 57 72 69 74 65 72  inish(FileWriter
78a0: 20 2a 70 2c 20 69 36 34 20 2a 70 69 45 6f 66 29   *p, i64 *piEof)
78b0: 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 66  {.  int rc;.  if
78c0: 28 20 70 2d 3e 65 46 57 45 72 72 3d 3d 30 20 26  ( p->eFWErr==0 &
78d0: 26 20 41 4c 57 41 59 53 28 70 2d 3e 61 42 75 66  & ALWAYS(p->aBuf
78e0: 66 65 72 29 20 26 26 20 70 2d 3e 69 42 75 66 45  fer) && p->iBufE
78f0: 6e 64 3e 70 2d 3e 69 42 75 66 53 74 61 72 74 20  nd>p->iBufStart 
7900: 29 7b 0a 20 20 20 20 70 2d 3e 65 46 57 45 72 72  ){.    p->eFWErr
7910: 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74   = sqlite3OsWrit
7920: 65 28 70 2d 3e 70 46 69 6c 65 2c 20 0a 20 20 20  e(p->pFile, .   
7930: 20 20 20 20 20 26 70 2d 3e 61 42 75 66 66 65 72       &p->aBuffer
7940: 5b 70 2d 3e 69 42 75 66 53 74 61 72 74 5d 2c 20  [p->iBufStart], 
7950: 70 2d 3e 69 42 75 66 45 6e 64 20 2d 20 70 2d 3e  p->iBufEnd - p->
7960: 69 42 75 66 53 74 61 72 74 2c 20 0a 20 20 20 20  iBufStart, .    
7970: 20 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66      p->iWriteOff
7980: 20 2b 20 70 2d 3e 69 42 75 66 53 74 61 72 74 0a   + p->iBufStart.
7990: 20 20 20 20 29 3b 0a 20 20 7d 0a 20 20 2a 70 69      );.  }.  *pi
79a0: 45 6f 66 20 3d 20 28 70 2d 3e 69 57 72 69 74 65  Eof = (p->iWrite
79b0: 4f 66 66 20 2b 20 70 2d 3e 69 42 75 66 45 6e 64  Off + p->iBufEnd
79c0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
79d0: 65 28 70 2d 3e 61 42 75 66 66 65 72 29 3b 0a 20  e(p->aBuffer);. 
79e0: 20 72 63 20 3d 20 70 2d 3e 65 46 57 45 72 72 3b   rc = p->eFWErr;
79f0: 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20  .  memset(p, 0, 
7a00: 73 69 7a 65 6f 66 28 46 69 6c 65 57 72 69 74 65  sizeof(FileWrite
7a10: 72 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  r));.  return rc
7a20: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65  ;.}../*.** Write
7a30: 20 76 61 6c 75 65 20 69 56 61 6c 20 65 6e 63 6f   value iVal enco
7a40: 64 65 64 20 61 73 20 61 20 76 61 72 69 6e 74 20  ded as a varint 
7a50: 74 6f 20 74 68 65 20 66 69 6c 65 2d 77 72 69 74  to the file-writ
7a60: 65 20 6f 62 6a 65 63 74 2e 20 52 65 74 75 72 6e  e object. Return
7a70: 20 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69   .** SQLITE_OK i
7a80: 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72  f successful, or
7a90: 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
7aa0: 20 63 6f 64 65 20 69 66 20 61 6e 20 65 72 72 6f   code if an erro
7ab0: 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61  r occurs..*/.sta
7ac0: 74 69 63 20 76 6f 69 64 20 66 69 6c 65 57 72 69  tic void fileWri
7ad0: 74 65 72 57 72 69 74 65 56 61 72 69 6e 74 28 46  terWriteVarint(F
7ae0: 69 6c 65 57 72 69 74 65 72 20 2a 70 2c 20 75 36  ileWriter *p, u6
7af0: 34 20 69 56 61 6c 29 7b 0a 20 20 69 6e 74 20 6e  4 iVal){.  int n
7b00: 42 79 74 65 3b 20 0a 20 20 75 38 20 61 42 79 74  Byte; .  u8 aByt
7b10: 65 5b 31 30 5d 3b 0a 20 20 6e 42 79 74 65 20 3d  e[10];.  nByte =
7b20: 20 73 71 6c 69 74 65 33 50 75 74 56 61 72 69 6e   sqlite3PutVarin
7b30: 74 28 61 42 79 74 65 2c 20 69 56 61 6c 29 3b 0a  t(aByte, iVal);.
7b40: 20 20 66 69 6c 65 57 72 69 74 65 72 57 72 69 74    fileWriterWrit
7b50: 65 28 70 2c 20 61 42 79 74 65 2c 20 6e 42 79 74  e(p, aByte, nByt
7b60: 65 29 3b 0a 7d 0a 0a 23 69 66 20 53 51 4c 49 54  e);.}..#if SQLIT
7b70: 45 5f 4d 41 58 5f 4d 4d 41 50 5f 53 49 5a 45 3e  E_MAX_MMAP_SIZE>
7b80: 30 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66 69 72 73  0./*.** The firs
7b90: 74 20 61 72 67 75 6d 65 6e 74 20 69 73 20 61 20  t argument is a 
7ba0: 66 69 6c 65 2d 68 61 6e 64 6c 65 20 6f 70 65 6e  file-handle open
7bb0: 20 6f 6e 20 61 20 74 65 6d 70 6f 72 61 72 79 20   on a temporary 
7bc0: 66 69 6c 65 2e 20 54 68 65 20 66 69 6c 65 0a 2a  file. The file.*
7bd0: 2a 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 20  * is guaranteed 
7be0: 74 6f 20 62 65 20 6e 42 79 74 65 20 62 79 74 65  to be nByte byte
7bf0: 73 20 6f 72 20 73 6d 61 6c 6c 65 72 20 69 6e 20  s or smaller in 
7c00: 73 69 7a 65 2e 20 54 68 69 73 20 66 75 6e 63 74  size. This funct
7c10: 69 6f 6e 0a 2a 2a 20 61 74 74 65 6d 70 74 73 20  ion.** attempts 
7c20: 74 6f 20 65 78 74 65 6e 64 20 74 68 65 20 66 69  to extend the fi
7c30: 6c 65 20 74 6f 20 6e 42 79 74 65 20 62 79 74 65  le to nByte byte
7c40: 73 20 69 6e 20 73 69 7a 65 20 61 6e 64 20 74 6f  s in size and to
7c50: 20 65 6e 73 75 72 65 20 74 68 61 74 0a 2a 2a 20   ensure that.** 
7c60: 74 68 65 20 56 46 53 20 68 61 73 20 6d 65 6d 6f  the VFS has memo
7c70: 72 79 20 6d 61 70 70 65 64 20 69 74 2e 0a 2a 2a  ry mapped it..**
7c80: 0a 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e  .** Whether or n
7c90: 6f 74 20 74 68 65 20 66 69 6c 65 20 64 6f 65 73  ot the file does
7ca0: 20 65 6e 64 20 75 70 20 6d 65 6d 6f 72 79 20 6d   end up memory m
7cb0: 61 70 70 65 64 20 6f 66 20 63 6f 75 72 73 65 20  apped of course 
7cc0: 64 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20 74 68  depends on.** th
7cd0: 65 20 73 70 65 63 69 66 69 63 20 56 46 53 20 69  e specific VFS i
7ce0: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a  mplementation..*
7cf0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
7d00: 65 53 6f 72 74 65 72 45 78 74 65 6e 64 46 69 6c  eSorterExtendFil
7d10: 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a  e(sqlite3_file *
7d20: 70 46 69 6c 65 2c 20 69 36 34 20 6e 42 79 74 65  pFile, i64 nByte
7d30: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 71  ){.  int rc = sq
7d40: 6c 69 74 65 33 4f 73 54 72 75 6e 63 61 74 65 28  lite3OsTruncate(
7d50: 70 46 69 6c 65 2c 20 6e 42 79 74 65 29 3b 0a 20  pFile, nByte);. 
7d60: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
7d70: 4f 4b 20 29 7b 0a 20 20 20 20 76 6f 69 64 20 2a  OK ){.    void *
7d80: 70 20 3d 20 30 3b 0a 20 20 20 20 73 71 6c 69 74  p = 0;.    sqlit
7d90: 65 33 4f 73 46 65 74 63 68 28 70 46 69 6c 65 2c  e3OsFetch(pFile,
7da0: 20 30 2c 20 6e 42 79 74 65 2c 20 26 70 29 3b 0a   0, nByte, &p);.
7db0: 20 20 20 20 73 71 6c 69 74 65 33 4f 73 55 6e 66      sqlite3OsUnf
7dc0: 65 74 63 68 28 70 46 69 6c 65 2c 20 30 2c 20 70  etch(pFile, 0, p
7dd0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
7de0: 72 63 3b 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65  rc;.}.#else.# de
7df0: 66 69 6e 65 20 76 64 62 65 53 6f 72 74 65 72 45  fine vdbeSorterE
7e00: 78 74 65 6e 64 46 69 6c 65 28 78 2c 79 29 20 53  xtendFile(x,y) S
7e10: 51 4c 49 54 45 5f 4f 4b 0a 23 65 6e 64 69 66 0a  QLITE_OK.#endif.
7e20: 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 74 68  ../*.** Write th
7e30: 65 20 63 75 72 72 65 6e 74 20 63 6f 6e 74 65 6e  e current conten
7e40: 74 73 20 6f 66 20 74 68 65 20 69 6e 2d 6d 65 6d  ts of the in-mem
7e50: 6f 72 79 20 6c 69 6e 6b 65 64 2d 6c 69 73 74 20  ory linked-list 
7e60: 74 6f 20 61 20 50 4d 41 2e 20 52 65 74 75 72 6e  to a PMA. Return
7e70: 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66  .** SQLITE_OK if
7e80: 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20   successful, or 
7e90: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
7ea0: 63 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a  code otherwise..
7eb0: 2a 2a 0a 2a 2a 20 54 68 65 20 66 6f 72 6d 61 74  **.** The format
7ec0: 20 6f 66 20 61 20 50 4d 41 20 69 73 3a 0a 2a 2a   of a PMA is:.**
7ed0: 0a 2a 2a 20 20 20 20 20 2a 20 41 20 76 61 72 69  .**     * A vari
7ee0: 6e 74 2e 20 54 68 69 73 20 76 61 72 69 6e 74 20  nt. This varint 
7ef0: 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 74 6f 74  contains the tot
7f00: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  al number of byt
7f10: 65 73 20 6f 66 20 63 6f 6e 74 65 6e 74 0a 2a 2a  es of content.**
7f20: 20 20 20 20 20 20 20 69 6e 20 74 68 65 20 50 4d         in the PM
7f30: 41 20 28 6e 6f 74 20 69 6e 63 6c 75 64 69 6e 67  A (not including
7f40: 20 74 68 65 20 76 61 72 69 6e 74 20 69 74 73 65   the varint itse
7f50: 6c 66 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a  lf)..**.**     *
7f60: 20 4f 6e 65 20 6f 72 20 6d 6f 72 65 20 72 65 63   One or more rec
7f70: 6f 72 64 73 20 70 61 63 6b 65 64 20 65 6e 64 2d  ords packed end-
7f80: 74 6f 2d 65 6e 64 20 69 6e 20 6f 72 64 65 72 20  to-end in order 
7f90: 6f 66 20 61 73 63 65 6e 64 69 6e 67 20 6b 65 79  of ascending key
7fa0: 73 2e 20 0a 2a 2a 20 20 20 20 20 20 20 45 61 63  s. .**       Eac
7fb0: 68 20 72 65 63 6f 72 64 20 63 6f 6e 73 69 73 74  h record consist
7fc0: 73 20 6f 66 20 61 20 76 61 72 69 6e 74 20 66 6f  s of a varint fo
7fd0: 6c 6c 6f 77 65 64 20 62 79 20 61 20 62 6c 6f 62  llowed by a blob
7fe0: 20 6f 66 20 64 61 74 61 20 28 74 68 65 20 0a 2a   of data (the .*
7ff0: 2a 20 20 20 20 20 20 20 6b 65 79 29 2e 20 54 68  *       key). Th
8000: 65 20 76 61 72 69 6e 74 20 69 73 20 74 68 65 20  e varint is the 
8010: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
8020: 69 6e 20 74 68 65 20 62 6c 6f 62 20 6f 66 20 64  in the blob of d
8030: 61 74 61 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ata..*/.static i
8040: 6e 74 20 76 64 62 65 53 6f 72 74 65 72 4c 69 73  nt vdbeSorterLis
8050: 74 54 6f 50 4d 41 28 53 6f 72 74 65 72 54 68 72  tToPMA(SorterThr
8060: 65 61 64 20 2a 70 54 68 72 65 61 64 29 7b 0a 20  ead *pThread){. 
8070: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
8080: 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20  _OK;            
8090: 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
80a0: 2a 2f 0a 20 20 46 69 6c 65 57 72 69 74 65 72 20  */.  FileWriter 
80b0: 77 72 69 74 65 72 3b 20 20 20 20 20 20 20 20 20  writer;         
80c0: 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63 74 20 75       /* Object u
80d0: 73 65 64 20 74 6f 20 77 72 69 74 65 20 74 6f 20  sed to write to 
80e0: 74 68 65 20 66 69 6c 65 20 2a 2f 0a 0a 20 20 6d  the file */..  m
80f0: 65 6d 73 65 74 28 26 77 72 69 74 65 72 2c 20 30  emset(&writer, 0
8100: 2c 20 73 69 7a 65 6f 66 28 46 69 6c 65 57 72 69  , sizeof(FileWri
8110: 74 65 72 29 29 3b 0a 20 20 61 73 73 65 72 74 28  ter));.  assert(
8120: 20 70 54 68 72 65 61 64 2d 3e 6e 49 6e 4d 65 6d   pThread->nInMem
8130: 6f 72 79 3e 30 20 29 3b 0a 0a 20 20 2f 2a 20 49  ory>0 );..  /* I
8140: 66 20 74 68 65 20 66 69 72 73 74 20 74 65 6d 70  f the first temp
8150: 6f 72 61 72 79 20 50 4d 41 20 66 69 6c 65 20 68  orary PMA file h
8160: 61 73 20 6e 6f 74 20 62 65 65 6e 20 6f 70 65 6e  as not been open
8170: 65 64 2c 20 6f 70 65 6e 20 69 74 20 6e 6f 77 2e  ed, open it now.
8180: 20 2a 2f 0a 20 20 69 66 28 20 70 54 68 72 65 61   */.  if( pThrea
8190: 64 2d 3e 70 54 65 6d 70 31 3d 3d 30 20 29 7b 0a  d->pTemp1==0 ){.
81a0: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
81b0: 74 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28  terOpenTempFile(
81c0: 70 54 68 72 65 61 64 2d 3e 70 56 66 73 2c 20 26  pThread->pVfs, &
81d0: 70 54 68 72 65 61 64 2d 3e 70 54 65 6d 70 31 29  pThread->pTemp1)
81e0: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 72 63  ;.    assert( rc
81f0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70  !=SQLITE_OK || p
8200: 54 68 72 65 61 64 2d 3e 70 54 65 6d 70 31 20 29  Thread->pTemp1 )
8210: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 54  ;.    assert( pT
8220: 68 72 65 61 64 2d 3e 69 54 65 6d 70 31 4f 66 66  hread->iTemp1Off
8230: 3d 3d 30 20 29 3b 0a 20 20 20 20 61 73 73 65 72  ==0 );.    asser
8240: 74 28 20 70 54 68 72 65 61 64 2d 3e 6e 50 4d 41  t( pThread->nPMA
8250: 3d 3d 30 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  ==0 );.  }..  /*
8260: 20 54 72 79 20 74 6f 20 67 65 74 20 74 68 65 20   Try to get the 
8270: 66 69 6c 65 20 74 6f 20 6d 65 6d 6f 72 79 20 6d  file to memory m
8280: 61 70 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d  ap */.  if( rc==
8290: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
82a0: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
82b0: 45 78 74 65 6e 64 46 69 6c 65 28 0a 20 20 20 20  ExtendFile(.    
82c0: 20 20 20 20 70 54 68 72 65 61 64 2d 3e 70 54 65      pThread->pTe
82d0: 6d 70 31 2c 20 70 54 68 72 65 61 64 2d 3e 69 54  mp1, pThread->iT
82e0: 65 6d 70 31 4f 66 66 20 2b 20 70 54 68 72 65 61  emp1Off + pThrea
82f0: 64 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20 2b 20 39  d->nInMemory + 9
8300: 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a 20 20 69  .    );.  }..  i
8310: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
8320: 20 29 7b 0a 20 20 20 20 53 6f 72 74 65 72 52 65   ){.    SorterRe
8330: 63 6f 72 64 20 2a 70 3b 0a 20 20 20 20 53 6f 72  cord *p;.    Sor
8340: 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65 78 74  terRecord *pNext
8350: 20 3d 20 30 3b 0a 0a 20 20 20 20 66 69 6c 65 57   = 0;..    fileW
8360: 72 69 74 65 72 49 6e 69 74 28 70 54 68 72 65 61  riterInit(pThrea
8370: 64 2d 3e 70 54 65 6d 70 31 2c 20 26 77 72 69 74  d->pTemp1, &writ
8380: 65 72 2c 20 70 54 68 72 65 61 64 2d 3e 70 67 73  er, pThread->pgs
8390: 7a 2c 20 70 54 68 72 65 61 64 2d 3e 69 54 65 6d  z, pThread->iTem
83a0: 70 31 4f 66 66 29 3b 0a 20 20 20 20 70 54 68 72  p1Off);.    pThr
83b0: 65 61 64 2d 3e 6e 50 4d 41 2b 2b 3b 0a 20 20 20  ead->nPMA++;.   
83c0: 20 66 69 6c 65 57 72 69 74 65 72 57 72 69 74 65   fileWriterWrite
83d0: 56 61 72 69 6e 74 28 26 77 72 69 74 65 72 2c 20  Varint(&writer, 
83e0: 70 54 68 72 65 61 64 2d 3e 6e 49 6e 4d 65 6d 6f  pThread->nInMemo
83f0: 72 79 29 3b 0a 20 20 20 20 66 6f 72 28 70 3d 70  ry);.    for(p=p
8400: 54 68 72 65 61 64 2d 3e 70 4c 69 73 74 3b 20 70  Thread->pList; p
8410: 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20  ; p=pNext){.    
8420: 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e 75 2e 70    pNext = p->u.p
8430: 4e 65 78 74 3b 0a 20 20 20 20 20 20 66 69 6c 65  Next;.      file
8440: 57 72 69 74 65 72 57 72 69 74 65 56 61 72 69 6e  WriterWriteVarin
8450: 74 28 26 77 72 69 74 65 72 2c 20 70 2d 3e 6e 56  t(&writer, p->nV
8460: 61 6c 29 3b 0a 20 20 20 20 20 20 66 69 6c 65 57  al);.      fileW
8470: 72 69 74 65 72 57 72 69 74 65 28 26 77 72 69 74  riterWrite(&writ
8480: 65 72 2c 20 53 52 56 41 4c 28 70 29 2c 20 70 2d  er, SRVAL(p), p-
8490: 3e 6e 56 61 6c 29 3b 0a 20 20 20 20 20 20 69 66  >nVal);.      if
84a0: 28 20 70 54 68 72 65 61 64 2d 3e 61 4c 69 73 74  ( pThread->aList
84b0: 4d 65 6d 6f 72 79 3d 3d 30 20 29 20 73 71 6c 69  Memory==0 ) sqli
84c0: 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20 20  te3_free(p);.   
84d0: 20 7d 0a 20 20 20 20 70 54 68 72 65 61 64 2d 3e   }.    pThread->
84e0: 70 4c 69 73 74 20 3d 20 70 3b 0a 20 20 20 20 72  pList = p;.    r
84f0: 63 20 3d 20 66 69 6c 65 57 72 69 74 65 72 46 69  c = fileWriterFi
8500: 6e 69 73 68 28 26 77 72 69 74 65 72 2c 20 26 70  nish(&writer, &p
8510: 54 68 72 65 61 64 2d 3e 69 54 65 6d 70 31 4f 66  Thread->iTemp1Of
8520: 66 29 3b 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72  f);.  }..  asser
8530: 74 28 20 70 54 68 72 65 61 64 2d 3e 70 4c 69 73  t( pThread->pLis
8540: 74 3d 3d 30 20 7c 7c 20 72 63 21 3d 53 51 4c 49  t==0 || rc!=SQLI
8550: 54 45 5f 4f 4b 20 29 3b 0a 20 20 72 65 74 75 72  TE_OK );.  retur
8560: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  n rc;.}../*.** A
8570: 64 76 61 6e 63 65 20 74 68 65 20 53 6f 72 74 65  dvance the Sorte
8580: 72 4d 65 72 67 65 72 20 69 74 65 72 61 74 6f 72  rMerger iterator
8590: 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 73   passed as the s
85a0: 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 74  econd argument t
85b0: 6f 0a 2a 2a 20 74 68 65 20 6e 65 78 74 20 65 6e  o.** the next en
85c0: 74 72 79 2e 20 53 65 74 20 2a 70 62 45 6f 66 20  try. Set *pbEof 
85d0: 74 6f 20 74 72 75 65 20 69 66 20 74 68 69 73 20  to true if this 
85e0: 6d 65 61 6e 73 20 74 68 65 20 69 74 65 72 61 74  means the iterat
85f0: 6f 72 20 68 61 73 20 0a 2a 2a 20 72 65 61 63 68  or has .** reach
8600: 65 64 20 45 4f 46 2e 0a 2a 2a 0a 2a 2a 20 52 65  ed EOF..**.** Re
8610: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69  turn SQLITE_OK i
8620: 66 20 73 75 63 63 65 73 73 66 75 6c 20 6f 72 20  f successful or 
8630: 61 6e 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66  an error code if
8640: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
8650: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
8660: 76 64 62 65 53 6f 72 74 65 72 4e 65 78 74 28 0a  vdbeSorterNext(.
8670: 20 20 53 6f 72 74 65 72 54 68 72 65 61 64 20 2a    SorterThread *
8680: 70 54 68 72 65 61 64 2c 20 0a 20 20 53 6f 72 74  pThread, .  Sort
8690: 65 72 4d 65 72 67 65 72 20 2a 70 4d 65 72 67 65  erMerger *pMerge
86a0: 72 2c 20 0a 20 20 69 6e 74 20 2a 70 62 45 6f 66  r, .  int *pbEof
86b0: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  .){.  int rc;.  
86c0: 69 6e 74 20 69 50 72 65 76 20 3d 20 70 4d 65 72  int iPrev = pMer
86d0: 67 65 72 2d 3e 61 54 72 65 65 5b 31 5d 3b 2f 2a  ger->aTree[1];/*
86e0: 20 49 6e 64 65 78 20 6f 66 20 69 74 65 72 61 74   Index of iterat
86f0: 6f 72 20 74 6f 20 61 64 76 61 6e 63 65 20 2a 2f  or to advance */
8700: 0a 0a 20 20 2f 2a 20 41 64 76 61 6e 63 65 20 74  ..  /* Advance t
8710: 68 65 20 63 75 72 72 65 6e 74 20 69 74 65 72 61  he current itera
8720: 74 6f 72 20 2a 2f 0a 20 20 72 63 20 3d 20 76 64  tor */.  rc = vd
8730: 62 65 53 6f 72 74 65 72 49 74 65 72 4e 65 78 74  beSorterIterNext
8740: 28 26 70 4d 65 72 67 65 72 2d 3e 61 49 74 65 72  (&pMerger->aIter
8750: 5b 69 50 72 65 76 5d 29 3b 0a 0a 20 20 2f 2a 20  [iPrev]);..  /* 
8760: 55 70 64 61 74 65 20 63 6f 6e 74 65 6e 74 73 20  Update contents 
8770: 6f 66 20 61 54 72 65 65 5b 5d 20 2a 2f 0a 20 20  of aTree[] */.  
8780: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
8790: 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b 20  K ){.    int i; 
87a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
87b0: 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66       /* Index of
87c0: 20 61 54 72 65 65 5b 5d 20 74 6f 20 72 65 63 61   aTree[] to reca
87d0: 6c 63 75 6c 61 74 65 20 2a 2f 0a 20 20 20 20 56  lculate */.    V
87e0: 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70  dbeSorterIter *p
87f0: 49 74 65 72 31 3b 20 20 20 20 20 2f 2a 20 46 69  Iter1;     /* Fi
8800: 72 73 74 20 69 74 65 72 61 74 6f 72 20 74 6f 20  rst iterator to 
8810: 63 6f 6d 70 61 72 65 20 2a 2f 0a 20 20 20 20 56  compare */.    V
8820: 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70  dbeSorterIter *p
8830: 49 74 65 72 32 3b 20 20 20 20 20 2f 2a 20 53 65  Iter2;     /* Se
8840: 63 6f 6e 64 20 69 74 65 72 61 74 6f 72 20 74 6f  cond iterator to
8850: 20 63 6f 6d 70 61 72 65 20 2a 2f 0a 20 20 20 20   compare */.    
8860: 75 38 20 2a 70 4b 65 79 32 3b 20 20 20 20 20 20  u8 *pKey2;      
8870: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
8880: 6f 20 70 49 74 65 72 32 2d 3e 61 4b 65 79 2c 20  o pIter2->aKey, 
8890: 6f 72 20 30 20 69 66 20 72 65 63 6f 72 64 20 63  or 0 if record c
88a0: 61 63 68 65 64 20 2a 2f 0a 0a 20 20 20 20 2f 2a  ached */..    /*
88b0: 20 46 69 6e 64 20 74 68 65 20 66 69 72 73 74 20   Find the first 
88c0: 74 77 6f 20 69 74 65 72 61 74 6f 72 73 20 74 6f  two iterators to
88d0: 20 63 6f 6d 70 61 72 65 2e 20 54 68 65 20 6f 6e   compare. The on
88e0: 65 20 74 68 61 74 20 77 61 73 20 6a 75 73 74 0a  e that was just.
88f0: 20 20 20 20 2a 2a 20 61 64 76 61 6e 63 65 64 20      ** advanced 
8900: 28 69 50 72 65 76 29 20 61 6e 64 20 74 68 65 20  (iPrev) and the 
8910: 6f 6e 65 20 6e 65 78 74 20 74 6f 20 69 74 20 69  one next to it i
8920: 6e 20 74 68 65 20 61 72 72 61 79 2e 20 20 2a 2f  n the array.  */
8930: 0a 20 20 20 20 70 49 74 65 72 31 20 3d 20 26 70  .    pIter1 = &p
8940: 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 28 69  Merger->aIter[(i
8950: 50 72 65 76 20 26 20 30 78 46 46 46 45 29 5d 3b  Prev & 0xFFFE)];
8960: 0a 20 20 20 20 70 49 74 65 72 32 20 3d 20 26 70  .    pIter2 = &p
8970: 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 28 69  Merger->aIter[(i
8980: 50 72 65 76 20 7c 20 30 78 30 30 30 31 29 5d 3b  Prev | 0x0001)];
8990: 0a 20 20 20 20 70 4b 65 79 32 20 3d 20 70 49 74  .    pKey2 = pIt
89a0: 65 72 32 2d 3e 61 4b 65 79 3b 0a 0a 20 20 20 20  er2->aKey;..    
89b0: 66 6f 72 28 69 3d 28 70 4d 65 72 67 65 72 2d 3e  for(i=(pMerger->
89c0: 6e 54 72 65 65 2b 69 50 72 65 76 29 2f 32 3b 20  nTree+iPrev)/2; 
89d0: 69 3e 30 3b 20 69 3d 69 2f 32 29 7b 0a 20 20 20  i>0; i=i/2){.   
89e0: 20 20 20 2f 2a 20 43 6f 6d 70 61 72 65 20 70 49     /* Compare pI
89f0: 74 65 72 31 20 61 6e 64 20 70 49 74 65 72 32 2e  ter1 and pIter2.
8a00: 20 53 74 6f 72 65 20 74 68 65 20 72 65 73 75 6c   Store the resul
8a10: 74 20 69 6e 20 76 61 72 69 61 62 6c 65 20 69 52  t in variable iR
8a20: 65 73 2e 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74  es. */.      int
8a30: 20 69 52 65 73 3b 0a 20 20 20 20 20 20 69 66 28   iRes;.      if(
8a40: 20 70 49 74 65 72 31 2d 3e 70 46 69 6c 65 3d 3d   pIter1->pFile==
8a50: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 69 52 65  0 ){.        iRe
8a60: 73 20 3d 20 2b 31 3b 0a 20 20 20 20 20 20 7d 65  s = +1;.      }e
8a70: 6c 73 65 20 69 66 28 20 70 49 74 65 72 32 2d 3e  lse if( pIter2->
8a80: 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20  pFile==0 ){.    
8a90: 20 20 20 20 69 52 65 73 20 3d 20 2d 31 3b 0a 20      iRes = -1;. 
8aa0: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
8ab0: 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 43 6f      vdbeSorterCo
8ac0: 6d 70 61 72 65 28 70 54 68 72 65 61 64 2c 20 30  mpare(pThread, 0
8ad0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 49  ,.            pI
8ae0: 74 65 72 31 2d 3e 61 4b 65 79 2c 20 70 49 74 65  ter1->aKey, pIte
8af0: 72 31 2d 3e 6e 4b 65 79 2c 20 70 4b 65 79 32 2c  r1->nKey, pKey2,
8b00: 20 70 49 74 65 72 32 2d 3e 6e 4b 65 79 2c 20 26   pIter2->nKey, &
8b10: 69 52 65 73 0a 20 20 20 20 20 20 20 20 29 3b 0a  iRes.        );.
8b20: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f        }..      /
8b30: 2a 20 49 66 20 70 49 74 65 72 31 20 63 6f 6e 74  * If pIter1 cont
8b40: 61 69 6e 65 64 20 74 68 65 20 73 6d 61 6c 6c 65  ained the smalle
8b50: 72 20 76 61 6c 75 65 2c 20 73 65 74 20 61 54 72  r value, set aTr
8b60: 65 65 5b 69 5d 20 74 6f 20 69 74 73 20 69 6e 64  ee[i] to its ind
8b70: 65 78 2e 0a 20 20 20 20 20 20 2a 2a 20 54 68 65  ex..      ** The
8b80: 6e 20 73 65 74 20 70 49 74 65 72 32 20 74 6f 20  n set pIter2 to 
8b90: 74 68 65 20 6e 65 78 74 20 69 74 65 72 61 74 6f  the next iterato
8ba0: 72 20 74 6f 20 63 6f 6d 70 61 72 65 20 74 6f 20  r to compare to 
8bb0: 70 49 74 65 72 31 2e 20 49 6e 20 74 68 69 73 0a  pIter1. In this.
8bc0: 20 20 20 20 20 20 2a 2a 20 63 61 73 65 20 74 68        ** case th
8bd0: 65 72 65 20 69 73 20 6e 6f 20 63 61 63 68 65 20  ere is no cache 
8be0: 6f 66 20 70 49 74 65 72 32 20 69 6e 20 70 54 68  of pIter2 in pTh
8bf0: 72 65 61 64 2d 3e 70 55 6e 70 61 63 6b 65 64 2c  read->pUnpacked,
8c00: 20 73 6f 20 73 65 74 0a 20 20 20 20 20 20 2a 2a   so set.      **
8c10: 20 70 4b 65 79 32 20 74 6f 20 70 6f 69 6e 74 20   pKey2 to point 
8c20: 74 6f 20 74 68 65 20 72 65 63 6f 72 64 20 62 65  to the record be
8c30: 6c 6f 6e 67 69 6e 67 20 74 6f 20 70 49 74 65 72  longing to pIter
8c40: 32 2e 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20 20  2..      **.    
8c50: 20 20 2a 2a 20 41 6c 74 65 72 6e 61 74 69 76 65    ** Alternative
8c60: 6c 79 2c 20 69 66 20 70 49 74 65 72 32 20 63 6f  ly, if pIter2 co
8c70: 6e 74 61 69 6e 73 20 74 68 65 20 73 6d 61 6c 6c  ntains the small
8c80: 65 72 20 6f 66 20 74 68 65 20 74 77 6f 20 76 61  er of the two va
8c90: 6c 75 65 73 2c 0a 20 20 20 20 20 20 2a 2a 20 73  lues,.      ** s
8ca0: 65 74 20 61 54 72 65 65 5b 69 5d 20 74 6f 20 69  et aTree[i] to i
8cb0: 74 73 20 69 6e 64 65 78 20 61 6e 64 20 75 70 64  ts index and upd
8cc0: 61 74 65 20 70 49 74 65 72 31 2e 20 49 66 20 76  ate pIter1. If v
8cd0: 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65  dbeSorterCompare
8ce0: 28 29 0a 20 20 20 20 20 20 2a 2a 20 77 61 73 20  ().      ** was 
8cf0: 61 63 74 75 61 6c 6c 79 20 63 61 6c 6c 65 64 20  actually called 
8d00: 61 62 6f 76 65 2c 20 74 68 65 6e 20 70 54 68 72  above, then pThr
8d10: 65 61 64 2d 3e 70 55 6e 70 61 63 6b 65 64 20 6e  ead->pUnpacked n
8d20: 6f 77 20 63 6f 6e 74 61 69 6e 73 0a 20 20 20 20  ow contains.    
8d30: 20 20 2a 2a 20 61 20 76 61 6c 75 65 20 65 71 75    ** a value equ
8d40: 69 76 61 6c 65 6e 74 20 74 6f 20 70 49 74 65 72  ivalent to pIter
8d50: 32 2e 20 53 6f 20 73 65 74 20 70 4b 65 79 32 20  2. So set pKey2 
8d60: 74 6f 20 4e 55 4c 4c 20 74 6f 20 70 72 65 76 65  to NULL to preve
8d70: 6e 74 0a 20 20 20 20 20 20 2a 2a 20 76 64 62 65  nt.      ** vdbe
8d80: 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 29 20  SorterCompare() 
8d90: 66 72 6f 6d 20 64 65 63 6f 64 69 6e 67 20 70 49  from decoding pI
8da0: 74 65 72 32 20 61 67 61 69 6e 2e 0a 20 20 20 20  ter2 again..    
8db0: 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 49 66    **.      ** If
8dc0: 20 74 68 65 20 74 77 6f 20 76 61 6c 75 65 73 20   the two values 
8dd0: 77 65 72 65 20 65 71 75 61 6c 2c 20 74 68 65 6e  were equal, then
8de0: 20 74 68 65 20 76 61 6c 75 65 20 66 72 6f 6d 20   the value from 
8df0: 74 68 65 20 6f 6c 64 65 73 74 0a 20 20 20 20 20  the oldest.     
8e00: 20 2a 2a 20 50 4d 41 20 73 68 6f 75 6c 64 20 62   ** PMA should b
8e10: 65 20 63 6f 6e 73 69 64 65 72 65 64 20 73 6d 61  e considered sma
8e20: 6c 6c 65 72 2e 20 54 68 65 20 56 64 62 65 53 6f  ller. The VdbeSo
8e30: 72 74 65 72 2e 61 49 74 65 72 5b 5d 20 61 72 72  rter.aIter[] arr
8e40: 61 79 0a 20 20 20 20 20 20 2a 2a 20 69 73 20 73  ay.      ** is s
8e50: 6f 72 74 65 64 20 66 72 6f 6d 20 6f 6c 64 65 73  orted from oldes
8e60: 74 20 74 6f 20 6e 65 77 65 73 74 2c 20 73 6f 20  t to newest, so 
8e70: 70 49 74 65 72 31 20 63 6f 6e 74 61 69 6e 73 20  pIter1 contains 
8e80: 6f 6c 64 65 72 20 76 61 6c 75 65 73 0a 20 20 20  older values.   
8e90: 20 20 20 2a 2a 20 74 68 61 6e 20 70 49 74 65 72     ** than pIter
8ea0: 32 20 69 66 66 20 28 70 49 74 65 72 31 3c 70 49  2 iff (pIter1<pI
8eb0: 74 65 72 32 29 2e 20 20 2a 2f 0a 20 20 20 20 20  ter2).  */.     
8ec0: 20 69 66 28 20 69 52 65 73 3c 30 20 7c 7c 20 28   if( iRes<0 || (
8ed0: 69 52 65 73 3d 3d 30 20 26 26 20 70 49 74 65 72  iRes==0 && pIter
8ee0: 31 3c 70 49 74 65 72 32 29 20 29 7b 0a 20 20 20  1<pIter2) ){.   
8ef0: 20 20 20 20 20 70 4d 65 72 67 65 72 2d 3e 61 54       pMerger->aT
8f00: 72 65 65 5b 69 5d 20 3d 20 28 69 6e 74 29 28 70  ree[i] = (int)(p
8f10: 49 74 65 72 31 20 2d 20 70 4d 65 72 67 65 72 2d  Iter1 - pMerger-
8f20: 3e 61 49 74 65 72 29 3b 0a 20 20 20 20 20 20 20  >aIter);.       
8f30: 20 70 49 74 65 72 32 20 3d 20 26 70 4d 65 72 67   pIter2 = &pMerg
8f40: 65 72 2d 3e 61 49 74 65 72 5b 20 70 4d 65 72 67  er->aIter[ pMerg
8f50: 65 72 2d 3e 61 54 72 65 65 5b 69 20 5e 20 30 78  er->aTree[i ^ 0x
8f60: 30 30 30 31 5d 20 5d 3b 0a 20 20 20 20 20 20 20  0001] ];.       
8f70: 20 70 4b 65 79 32 20 3d 20 70 49 74 65 72 32 2d   pKey2 = pIter2-
8f80: 3e 61 4b 65 79 3b 0a 20 20 20 20 20 20 7d 65 6c  >aKey;.      }el
8f90: 73 65 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20  se{.        if( 
8fa0: 70 49 74 65 72 31 2d 3e 70 46 69 6c 65 20 29 20  pIter1->pFile ) 
8fb0: 70 4b 65 79 32 20 3d 20 30 3b 0a 20 20 20 20 20  pKey2 = 0;.     
8fc0: 20 20 20 70 4d 65 72 67 65 72 2d 3e 61 54 72 65     pMerger->aTre
8fd0: 65 5b 69 5d 20 3d 20 28 69 6e 74 29 28 70 49 74  e[i] = (int)(pIt
8fe0: 65 72 32 20 2d 20 70 4d 65 72 67 65 72 2d 3e 61  er2 - pMerger->a
8ff0: 49 74 65 72 29 3b 0a 20 20 20 20 20 20 20 20 70  Iter);.        p
9000: 49 74 65 72 31 20 3d 20 26 70 4d 65 72 67 65 72  Iter1 = &pMerger
9010: 2d 3e 61 49 74 65 72 5b 20 70 4d 65 72 67 65 72  ->aIter[ pMerger
9020: 2d 3e 61 54 72 65 65 5b 69 20 5e 20 30 78 30 30  ->aTree[i ^ 0x00
9030: 30 31 5d 20 5d 3b 0a 20 20 20 20 20 20 7d 0a 20  01] ];.      }. 
9040: 20 20 20 7d 0a 20 20 20 20 2a 70 62 45 6f 66 20     }.    *pbEof 
9050: 3d 20 28 70 4d 65 72 67 65 72 2d 3e 61 49 74 65  = (pMerger->aIte
9060: 72 5b 70 4d 65 72 67 65 72 2d 3e 61 54 72 65 65  r[pMerger->aTree
9070: 5b 31 5d 5d 2e 70 46 69 6c 65 3d 3d 30 29 3b 0a  [1]].pFile==0);.
9080: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
9090: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d  ;.}../*.** The m
90a0: 61 69 6e 20 72 6f 75 74 69 6e 65 20 66 6f 72 20  ain routine for 
90b0: 73 6f 72 74 65 72 2d 74 68 72 65 61 64 20 6f 70  sorter-thread op
90c0: 65 72 61 74 69 6f 6e 73 2e 0a 2a 2f 0a 73 74 61  erations..*/.sta
90d0: 74 69 63 20 76 6f 69 64 20 2a 76 64 62 65 53 6f  tic void *vdbeSo
90e0: 72 74 65 72 54 68 72 65 61 64 4d 61 69 6e 28 76  rterThreadMain(v
90f0: 6f 69 64 20 2a 70 43 74 78 29 7b 0a 20 20 69 6e  oid *pCtx){.  in
9100: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
9110: 3b 0a 20 20 53 6f 72 74 65 72 54 68 72 65 61 64  ;.  SorterThread
9120: 20 2a 70 54 68 72 65 61 64 20 3d 20 28 53 6f 72   *pThread = (Sor
9130: 74 65 72 54 68 72 65 61 64 2a 29 70 43 74 78 3b  terThread*)pCtx;
9140: 0a 0a 20 20 61 73 73 65 72 74 28 20 70 54 68 72  ..  assert( pThr
9150: 65 61 64 2d 3e 65 57 6f 72 6b 3d 3d 53 4f 52 54  ead->eWork==SORT
9160: 45 52 5f 54 48 52 45 41 44 5f 53 4f 52 54 0a 20  ER_THREAD_SORT. 
9170: 20 20 20 20 20 20 7c 7c 20 70 54 68 72 65 61 64        || pThread
9180: 2d 3e 65 57 6f 72 6b 3d 3d 53 4f 52 54 45 52 5f  ->eWork==SORTER_
9190: 54 48 52 45 41 44 5f 54 4f 5f 50 4d 41 0a 20 20  THREAD_TO_PMA.  
91a0: 20 20 20 20 20 7c 7c 20 70 54 68 72 65 61 64 2d       || pThread-
91b0: 3e 65 57 6f 72 6b 3d 3d 53 4f 52 54 45 52 5f 54  >eWork==SORTER_T
91c0: 48 52 45 41 44 5f 43 4f 4e 53 0a 20 20 29 3b 0a  HREAD_CONS.  );.
91d0: 20 20 61 73 73 65 72 74 28 20 70 54 68 72 65 61    assert( pThrea
91e0: 64 2d 3e 62 44 6f 6e 65 3d 3d 30 20 29 3b 0a 0a  d->bDone==0 );..
91f0: 20 20 69 66 28 20 70 54 68 72 65 61 64 2d 3e 70    if( pThread->p
9200: 55 6e 70 61 63 6b 65 64 3d 3d 30 20 29 7b 0a 20  Unpacked==0 ){. 
9210: 20 20 20 63 68 61 72 20 2a 70 46 72 65 65 3b 0a     char *pFree;.
9220: 20 20 20 20 70 54 68 72 65 61 64 2d 3e 70 55 6e      pThread->pUn
9230: 70 61 63 6b 65 64 20 3d 20 73 71 6c 69 74 65 33  packed = sqlite3
9240: 56 64 62 65 41 6c 6c 6f 63 55 6e 70 61 63 6b 65  VdbeAllocUnpacke
9250: 64 52 65 63 6f 72 64 28 0a 20 20 20 20 20 20 20  dRecord(.       
9260: 20 70 54 68 72 65 61 64 2d 3e 70 4b 65 79 49 6e   pThread->pKeyIn
9270: 66 6f 2c 20 30 2c 20 30 2c 20 26 70 46 72 65 65  fo, 0, 0, &pFree
9280: 0a 20 20 20 20 29 3b 0a 20 20 20 20 61 73 73 65  .    );.    asse
9290: 72 74 28 20 70 54 68 72 65 61 64 2d 3e 70 55 6e  rt( pThread->pUn
92a0: 70 61 63 6b 65 64 3d 3d 28 55 6e 70 61 63 6b 65  packed==(Unpacke
92b0: 64 52 65 63 6f 72 64 2a 29 70 46 72 65 65 20 29  dRecord*)pFree )
92c0: 3b 0a 20 20 20 20 69 66 28 20 70 46 72 65 65 3d  ;.    if( pFree=
92d0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  =0 ){.      rc =
92e0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
92f0: 20 20 20 20 20 67 6f 74 6f 20 74 68 72 65 61 64       goto thread
9300: 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20  _out;.    }.    
9310: 70 54 68 72 65 61 64 2d 3e 70 55 6e 70 61 63 6b  pThread->pUnpack
9320: 65 64 2d 3e 6e 46 69 65 6c 64 20 3d 20 70 54 68  ed->nField = pTh
9330: 72 65 61 64 2d 3e 70 4b 65 79 49 6e 66 6f 2d 3e  read->pKeyInfo->
9340: 6e 46 69 65 6c 64 3b 0a 20 20 7d 0a 0a 20 20 69  nField;.  }..  i
9350: 66 28 20 70 54 68 72 65 61 64 2d 3e 65 57 6f 72  f( pThread->eWor
9360: 6b 3d 3d 53 4f 52 54 45 52 5f 54 48 52 45 41 44  k==SORTER_THREAD
9370: 5f 43 4f 4e 53 20 29 7b 0a 20 20 20 20 61 73 73  _CONS ){.    ass
9380: 65 72 74 28 20 70 54 68 72 65 61 64 2d 3e 70 4c  ert( pThread->pL
9390: 69 73 74 3d 3d 30 20 29 3b 0a 20 20 20 20 77 68  ist==0 );.    wh
93a0: 69 6c 65 28 20 70 54 68 72 65 61 64 2d 3e 6e 50  ile( pThread->nP
93b0: 4d 41 3e 70 54 68 72 65 61 64 2d 3e 6e 43 6f 6e  MA>pThread->nCon
93c0: 73 6f 6c 69 64 61 74 65 20 26 26 20 72 63 3d 3d  solidate && rc==
93d0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
93e0: 20 20 20 69 6e 74 20 6e 49 74 65 72 20 3d 20 4d     int nIter = M
93f0: 49 4e 28 70 54 68 72 65 61 64 2d 3e 6e 50 4d 41  IN(pThread->nPMA
9400: 2c 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52  , SORTER_MAX_MER
9410: 47 45 5f 43 4f 55 4e 54 29 3b 0a 20 20 20 20 20  GE_COUNT);.     
9420: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
9430: 54 65 6d 70 32 20 3d 20 30 3b 20 20 20 20 20 2f  Temp2 = 0;     /
9440: 2a 20 53 65 63 6f 6e 64 20 74 65 6d 70 20 66 69  * Second temp fi
9450: 6c 65 20 74 6f 20 75 73 65 20 2a 2f 0a 20 20 20  le to use */.   
9460: 20 20 20 53 6f 72 74 65 72 4d 65 72 67 65 72 20     SorterMerger 
9470: 2a 70 4d 65 72 67 65 72 3b 20 20 20 20 20 20 20  *pMerger;       
9480: 20 2f 2a 20 4f 62 6a 65 63 74 20 66 6f 72 20 72   /* Object for r
9490: 65 61 64 69 6e 67 2f 6d 65 72 67 69 6e 67 20 50  eading/merging P
94a0: 4d 41 20 64 61 74 61 20 2a 2f 0a 20 20 20 20 20  MA data */.     
94b0: 20 69 36 34 20 69 52 65 61 64 4f 66 66 20 3d 20   i64 iReadOff = 
94c0: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  0;             /
94d0: 2a 20 4f 66 66 73 65 74 20 69 6e 20 70 54 65 6d  * Offset in pTem
94e0: 70 31 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20  p1 to read from 
94f0: 2a 2f 0a 20 20 20 20 20 20 69 36 34 20 69 57 72  */.      i64 iWr
9500: 69 74 65 4f 66 66 20 3d 20 30 3b 20 20 20 20 20  iteOff = 0;     
9510: 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74         /* Offset
9520: 20 69 6e 20 70 54 65 6d 70 32 20 74 6f 20 77 72   in pTemp2 to wr
9530: 69 74 65 20 74 6f 20 2a 2f 0a 20 20 20 20 20 20  ite to */.      
9540: 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 0a 20 20  int i;.      .  
9550: 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20      /* Allocate 
9560: 61 20 6d 65 72 67 65 72 20 6f 62 6a 65 63 74 20  a merger object 
9570: 74 6f 20 6d 65 72 67 65 20 50 4d 41 73 20 74 6f  to merge PMAs to
9580: 67 65 74 68 65 72 2e 20 2a 2f 0a 20 20 20 20 20  gether. */.     
9590: 20 70 4d 65 72 67 65 72 20 3d 20 76 64 62 65 53   pMerger = vdbeS
95a0: 6f 72 74 65 72 4d 65 72 67 65 72 4e 65 77 28 6e  orterMergerNew(n
95b0: 49 74 65 72 29 3b 0a 20 20 20 20 20 20 69 66 28  Iter);.      if(
95c0: 20 70 4d 65 72 67 65 72 3d 3d 30 20 29 7b 0a 20   pMerger==0 ){. 
95d0: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
95e0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20  TE_NOMEM;.      
95f0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d    break;.      }
9600: 0a 0a 20 20 20 20 20 20 2f 2a 20 4f 70 65 6e 20  ..      /* Open 
9610: 61 20 73 65 63 6f 6e 64 20 74 65 6d 70 20 66 69  a second temp fi
9620: 6c 65 20 74 6f 20 77 72 69 74 65 20 6d 65 72 67  le to write merg
9630: 65 64 20 64 61 74 61 20 74 6f 20 2a 2f 0a 20 20  ed data to */.  
9640: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
9650: 74 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28  terOpenTempFile(
9660: 70 54 68 72 65 61 64 2d 3e 70 56 66 73 2c 20 26  pThread->pVfs, &
9670: 70 54 65 6d 70 32 29 3b 0a 20 20 20 20 20 20 69  pTemp2);.      i
9680: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
9690: 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d   ){.        rc =
96a0: 20 76 64 62 65 53 6f 72 74 65 72 45 78 74 65 6e   vdbeSorterExten
96b0: 64 46 69 6c 65 28 70 54 65 6d 70 32 2c 20 70 54  dFile(pTemp2, pT
96c0: 68 72 65 61 64 2d 3e 69 54 65 6d 70 31 4f 66 66  hread->iTemp1Off
96d0: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  );.      }.     
96e0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
96f0: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 76 64  OK ){.        vd
9700: 62 65 53 6f 72 74 65 72 4d 65 72 67 65 72 46 72  beSorterMergerFr
9710: 65 65 28 70 4d 65 72 67 65 72 29 3b 0a 20 20 20  ee(pMerger);.   
9720: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
9730: 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 54 68    }..      /* Th
9740: 69 73 20 6c 6f 6f 70 20 72 75 6e 73 20 6f 6e 63  is loop runs onc
9750: 65 20 66 6f 72 20 65 61 63 68 20 6f 75 74 70 75  e for each outpu
9760: 74 20 50 4d 41 2e 20 45 61 63 68 20 6f 75 74 70  t PMA. Each outp
9770: 75 74 20 50 4d 41 20 69 73 20 6d 61 64 65 0a 20  ut PMA is made. 
9780: 20 20 20 20 20 2a 2a 20 6f 66 20 64 61 74 61 20       ** of data 
9790: 6d 65 72 67 65 64 20 66 72 6f 6d 20 75 70 20 74  merged from up t
97a0: 6f 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52  o SORTER_MAX_MER
97b0: 47 45 5f 43 4f 55 4e 54 20 69 6e 70 75 74 20 50  GE_COUNT input P
97c0: 4d 41 73 2e 20 2a 2f 0a 20 20 20 20 20 20 66 6f  MAs. */.      fo
97d0: 72 28 69 3d 30 3b 20 69 3c 70 54 68 72 65 61 64  r(i=0; i<pThread
97e0: 2d 3e 6e 50 4d 41 3b 20 69 2b 3d 53 4f 52 54 45  ->nPMA; i+=SORTE
97f0: 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
9800: 54 29 7b 0a 20 20 20 20 20 20 20 20 46 69 6c 65  T){.        File
9810: 57 72 69 74 65 72 20 77 72 69 74 65 72 3b 20 20  Writer writer;  
9820: 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63 74 20        /* Object 
9830: 66 6f 72 20 77 72 69 74 69 6e 67 20 64 61 74 61  for writing data
9840: 20 74 6f 20 70 54 65 6d 70 32 20 2a 2f 0a 20 20   to pTemp2 */.  
9850: 20 20 20 20 20 20 69 36 34 20 6e 4f 75 74 20 3d        i64 nOut =
9860: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
9870: 2f 2a 20 42 79 74 65 73 20 6f 66 20 64 61 74 61  /* Bytes of data
9880: 20 69 6e 20 6f 75 74 70 75 74 20 50 4d 41 20 2a   in output PMA *
9890: 2f 0a 20 20 20 20 20 20 20 20 69 6e 74 20 62 45  /.        int bE
98a0: 6f 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  of = 0;.        
98b0: 69 6e 74 20 72 63 32 3b 0a 0a 20 20 20 20 20 20  int rc2;..      
98c0: 20 20 2f 2a 20 43 6f 6e 66 69 67 75 72 65 20 74    /* Configure t
98d0: 68 65 20 6d 65 72 67 65 72 20 6f 62 6a 65 63 74  he merger object
98e0: 20 74 6f 20 72 65 61 64 20 61 6e 64 20 6d 65 72   to read and mer
98f0: 67 65 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65  ge data from the
9900: 20 6e 65 78 74 20 0a 20 20 20 20 20 20 20 20 2a   next .        *
9910: 2a 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52  * SORTER_MAX_MER
9920: 47 45 5f 43 4f 55 4e 54 20 50 4d 41 73 20 69 6e  GE_COUNT PMAs in
9930: 20 70 54 65 6d 70 31 20 28 6f 72 20 66 72 6f 6d   pTemp1 (or from
9940: 20 61 6c 6c 20 72 65 6d 61 69 6e 69 6e 67 20 50   all remaining P
9950: 4d 41 73 2c 0a 20 20 20 20 20 20 20 20 2a 2a 20  MAs,.        ** 
9960: 69 66 20 74 68 61 74 20 69 73 20 66 65 77 65 72  if that is fewer
9970: 29 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20 69 6e  ). */.        in
9980: 74 20 69 49 74 65 72 3b 0a 20 20 20 20 20 20 20  t iIter;.       
9990: 20 66 6f 72 28 69 49 74 65 72 3d 30 3b 20 69 49   for(iIter=0; iI
99a0: 74 65 72 3c 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  ter<SORTER_MAX_M
99b0: 45 52 47 45 5f 43 4f 55 4e 54 3b 20 69 49 74 65  ERGE_COUNT; iIte
99c0: 72 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20  r++){.          
99d0: 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a  VdbeSorterIter *
99e0: 70 49 74 65 72 20 3d 20 26 70 4d 65 72 67 65 72  pIter = &pMerger
99f0: 2d 3e 61 49 74 65 72 5b 69 49 74 65 72 5d 3b 0a  ->aIter[iIter];.
9a00: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 76            rc = v
9a10: 64 62 65 53 6f 72 74 65 72 49 74 65 72 49 6e 69  dbeSorterIterIni
9a20: 74 28 70 54 68 72 65 61 64 2c 20 69 52 65 61 64  t(pThread, iRead
9a30: 4f 66 66 2c 20 70 49 74 65 72 2c 20 26 6e 4f 75  Off, pIter, &nOu
9a40: 74 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69 52  t);.          iR
9a50: 65 61 64 4f 66 66 20 3d 20 70 49 74 65 72 2d 3e  eadOff = pIter->
9a60: 69 45 6f 66 3b 0a 20 20 20 20 20 20 20 20 20 20  iEof;.          
9a70: 69 66 28 20 69 52 65 61 64 4f 66 66 3e 3d 70 54  if( iReadOff>=pT
9a80: 68 72 65 61 64 2d 3e 69 54 65 6d 70 31 4f 66 66  hread->iTemp1Off
9a90: 20 7c 7c 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f   || rc!=SQLITE_O
9aa0: 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  K ) break;.     
9ab0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 66 6f 72     }.        for
9ac0: 28 69 49 74 65 72 3d 70 4d 65 72 67 65 72 2d 3e  (iIter=pMerger->
9ad0: 6e 54 72 65 65 2d 31 3b 20 72 63 3d 3d 53 51 4c  nTree-1; rc==SQL
9ae0: 49 54 45 5f 4f 4b 20 26 26 20 69 49 74 65 72 3e  ITE_OK && iIter>
9af0: 30 3b 20 69 49 74 65 72 2d 2d 29 7b 0a 20 20 20  0; iIter--){.   
9b00: 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65         rc = vdbe
9b10: 53 6f 72 74 65 72 44 6f 43 6f 6d 70 61 72 65 28  SorterDoCompare(
9b20: 70 54 68 72 65 61 64 2c 20 70 4d 65 72 67 65 72  pThread, pMerger
9b30: 2c 20 69 49 74 65 72 29 3b 0a 20 20 20 20 20 20  , iIter);.      
9b40: 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 66 69 6c    }..        fil
9b50: 65 57 72 69 74 65 72 49 6e 69 74 28 70 54 65 6d  eWriterInit(pTem
9b60: 70 32 2c 20 26 77 72 69 74 65 72 2c 20 70 54 68  p2, &writer, pTh
9b70: 72 65 61 64 2d 3e 70 67 73 7a 2c 20 69 57 72 69  read->pgsz, iWri
9b80: 74 65 4f 66 66 29 3b 0a 20 20 20 20 20 20 20 20  teOff);.        
9b90: 66 69 6c 65 57 72 69 74 65 72 57 72 69 74 65 56  fileWriterWriteV
9ba0: 61 72 69 6e 74 28 26 77 72 69 74 65 72 2c 20 6e  arint(&writer, n
9bb0: 4f 75 74 29 3b 0a 20 20 20 20 20 20 20 20 77 68  Out);.        wh
9bc0: 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ile( rc==SQLITE_
9bd0: 4f 4b 20 26 26 20 62 45 6f 66 3d 3d 30 20 29 7b  OK && bEof==0 ){
9be0: 0a 20 20 20 20 20 20 20 20 20 20 56 64 62 65 53  .          VdbeS
9bf0: 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74 65 72  orterIter *pIter
9c00: 20 3d 20 26 70 4d 65 72 67 65 72 2d 3e 61 49 74   = &pMerger->aIt
9c10: 65 72 5b 20 70 4d 65 72 67 65 72 2d 3e 61 54 72  er[ pMerger->aTr
9c20: 65 65 5b 31 5d 20 5d 3b 0a 20 20 20 20 20 20 20  ee[1] ];.       
9c30: 20 20 20 61 73 73 65 72 74 28 20 70 49 74 65 72     assert( pIter
9c40: 2d 3e 70 46 69 6c 65 21 3d 30 20 29 3b 20 20 20  ->pFile!=0 );   
9c50: 20 20 20 20 20 2f 2a 20 70 49 74 65 72 20 69 73       /* pIter is
9c60: 20 6e 6f 74 20 61 74 20 45 4f 46 20 2a 2f 0a 20   not at EOF */. 
9c70: 20 20 20 20 20 20 20 20 20 66 69 6c 65 57 72 69           fileWri
9c80: 74 65 72 57 72 69 74 65 56 61 72 69 6e 74 28 26  terWriteVarint(&
9c90: 77 72 69 74 65 72 2c 20 70 49 74 65 72 2d 3e 6e  writer, pIter->n
9ca0: 4b 65 79 29 3b 0a 20 20 20 20 20 20 20 20 20 20  Key);.          
9cb0: 66 69 6c 65 57 72 69 74 65 72 57 72 69 74 65 28  fileWriterWrite(
9cc0: 26 77 72 69 74 65 72 2c 20 70 49 74 65 72 2d 3e  &writer, pIter->
9cd0: 61 4b 65 79 2c 20 70 49 74 65 72 2d 3e 6e 4b 65  aKey, pIter->nKe
9ce0: 79 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63  y);.          rc
9cf0: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4e 65 78   = vdbeSorterNex
9d00: 74 28 70 54 68 72 65 61 64 2c 20 70 4d 65 72 67  t(pThread, pMerg
9d10: 65 72 2c 20 26 62 45 6f 66 29 3b 0a 20 20 20 20  er, &bEof);.    
9d20: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 72 63      }.        rc
9d30: 32 20 3d 20 66 69 6c 65 57 72 69 74 65 72 46 69  2 = fileWriterFi
9d40: 6e 69 73 68 28 26 77 72 69 74 65 72 2c 20 26 69  nish(&writer, &i
9d50: 57 72 69 74 65 4f 66 66 29 3b 0a 20 20 20 20 20  WriteOff);.     
9d60: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
9d70: 45 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63 32 3b  E_OK ) rc = rc2;
9d80: 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
9d90: 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65 72  vdbeSorterMerger
9da0: 46 72 65 65 28 70 4d 65 72 67 65 72 29 3b 0a 20  Free(pMerger);. 
9db0: 20 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43 6c       sqlite3OsCl
9dc0: 6f 73 65 46 72 65 65 28 70 54 68 72 65 61 64 2d  oseFree(pThread-
9dd0: 3e 70 54 65 6d 70 31 29 3b 0a 20 20 20 20 20 20  >pTemp1);.      
9de0: 70 54 68 72 65 61 64 2d 3e 70 54 65 6d 70 31 20  pThread->pTemp1 
9df0: 3d 20 70 54 65 6d 70 32 3b 0a 20 20 20 20 20 20  = pTemp2;.      
9e00: 70 54 68 72 65 61 64 2d 3e 6e 50 4d 41 20 3d 20  pThread->nPMA = 
9e10: 28 69 20 2f 20 53 4f 52 54 45 52 5f 4d 41 58 5f  (i / SORTER_MAX_
9e20: 4d 45 52 47 45 5f 43 4f 55 4e 54 29 3b 0a 20 20  MERGE_COUNT);.  
9e30: 20 20 20 20 70 54 68 72 65 61 64 2d 3e 69 54 65      pThread->iTe
9e40: 6d 70 31 4f 66 66 20 3d 20 69 57 72 69 74 65 4f  mp1Off = iWriteO
9e50: 66 66 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73  ff;.    }.  }els
9e60: 65 7b 0a 20 20 20 20 2f 2a 20 53 6f 72 74 20 74  e{.    /* Sort t
9e70: 68 65 20 70 54 68 72 65 61 64 2d 3e 70 4c 69 73  he pThread->pLis
9e80: 74 20 6c 69 73 74 20 2a 2f 0a 20 20 20 20 72 63  t list */.    rc
9e90: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 53 6f 72   = vdbeSorterSor
9ea0: 74 28 70 54 68 72 65 61 64 29 3b 0a 0a 20 20 20  t(pThread);..   
9eb0: 20 2f 2a 20 49 66 20 72 65 71 75 69 72 65 64 2c   /* If required,
9ec0: 20 77 72 69 74 65 20 74 68 65 20 6c 69 73 74 20   write the list 
9ed0: 6f 75 74 20 74 6f 20 61 20 50 4d 41 2e 20 2a 2f  out to a PMA. */
9ee0: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
9ef0: 49 54 45 5f 4f 4b 20 26 26 20 70 54 68 72 65 61  ITE_OK && pThrea
9f00: 64 2d 3e 65 57 6f 72 6b 3d 3d 53 4f 52 54 45 52  d->eWork==SORTER
9f10: 5f 54 48 52 45 41 44 5f 54 4f 5f 50 4d 41 20 29  _THREAD_TO_PMA )
9f20: 7b 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  {.#ifdef SQLITE_
9f30: 44 45 42 55 47 0a 20 20 20 20 20 20 69 36 34 20  DEBUG.      i64 
9f40: 6e 45 78 70 65 63 74 20 3d 20 70 54 68 72 65 61  nExpect = pThrea
9f50: 64 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 0a 20 20 20  d->nInMemory.   
9f60: 20 20 20 20 20 2b 20 73 71 6c 69 74 65 33 56 61       + sqlite3Va
9f70: 72 69 6e 74 4c 65 6e 28 70 54 68 72 65 61 64 2d  rintLen(pThread-
9f80: 3e 6e 49 6e 4d 65 6d 6f 72 79 29 0a 20 20 20 20  >nInMemory).    
9f90: 20 20 20 20 2b 20 70 54 68 72 65 61 64 2d 3e 69      + pThread->i
9fa0: 54 65 6d 70 31 4f 66 66 3b 0a 23 65 6e 64 69 66  Temp1Off;.#endif
9fb0: 0a 20 20 20 20 20 20 72 63 20 3d 20 76 64 62 65  .      rc = vdbe
9fc0: 53 6f 72 74 65 72 4c 69 73 74 54 6f 50 4d 41 28  SorterListToPMA(
9fd0: 70 54 68 72 65 61 64 29 3b 0a 20 20 20 20 20 20  pThread);.      
9fe0: 61 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49  assert( rc!=SQLI
9ff0: 54 45 5f 4f 4b 20 7c 7c 20 28 6e 45 78 70 65 63  TE_OK || (nExpec
a000: 74 3d 3d 70 54 68 72 65 61 64 2d 3e 69 54 65 6d  t==pThread->iTem
a010: 70 31 4f 66 66 29 20 29 3b 0a 20 20 20 20 7d 0a  p1Off) );.    }.
a020: 20 20 7d 0a 0a 20 74 68 72 65 61 64 5f 6f 75 74    }.. thread_out
a030: 3a 0a 20 20 70 54 68 72 65 61 64 2d 3e 62 44 6f  :.  pThread->bDo
a040: 6e 65 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e  ne = 1;.  return
a050: 20 53 51 4c 49 54 45 5f 49 4e 54 5f 54 4f 5f 50   SQLITE_INT_TO_P
a060: 54 52 28 72 63 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  TR(rc);.}../*.**
a070: 20 52 75 6e 20 74 68 65 20 61 63 74 69 76 69 74   Run the activit
a080: 79 20 73 63 68 65 64 75 6c 65 64 20 62 79 20 74  y scheduled by t
a090: 68 65 20 6f 62 6a 65 63 74 20 70 61 73 73 65 64  he object passed
a0a0: 20 61 73 20 74 68 65 20 6f 6e 6c 79 20 61 72 67   as the only arg
a0b0: 75 6d 65 6e 74 0a 2a 2a 20 69 6e 20 74 68 65 20  ument.** in the 
a0c0: 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 2e 0a  current thread..
a0d0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
a0e0: 62 65 53 6f 72 74 65 72 52 75 6e 54 68 72 65 61  beSorterRunThrea
a0f0: 64 28 53 6f 72 74 65 72 54 68 72 65 61 64 20 2a  d(SorterThread *
a100: 70 54 68 72 65 61 64 29 7b 0a 20 20 69 6e 74 20  pThread){.  int 
a110: 72 63 20 3d 20 53 51 4c 49 54 45 5f 50 54 52 5f  rc = SQLITE_PTR_
a120: 54 4f 5f 49 4e 54 28 20 76 64 62 65 53 6f 72 74  TO_INT( vdbeSort
a130: 65 72 54 68 72 65 61 64 4d 61 69 6e 28 28 76 6f  erThreadMain((vo
a140: 69 64 2a 29 70 54 68 72 65 61 64 29 20 29 3b 0a  id*)pThread) );.
a150: 20 20 61 73 73 65 72 74 28 20 70 54 68 72 65 61    assert( pThrea
a160: 64 2d 3e 62 44 6f 6e 65 20 29 3b 0a 20 20 70 54  d->bDone );.  pT
a170: 68 72 65 61 64 2d 3e 62 44 6f 6e 65 20 3d 20 30  hread->bDone = 0
a180: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
a190: 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68 20 74 68  ../*.** Flush th
a1a0: 65 20 63 75 72 72 65 6e 74 20 63 6f 6e 74 65 6e  e current conten
a1b0: 74 73 20 6f 66 20 56 64 62 65 53 6f 72 74 65 72  ts of VdbeSorter
a1c0: 2e 70 52 65 63 6f 72 64 20 74 6f 20 61 20 6e 65  .pRecord to a ne
a1d0: 77 20 50 4d 41 2c 20 70 6f 73 73 69 62 6c 79 0a  w PMA, possibly.
a1e0: 2a 2a 20 75 73 69 6e 67 20 61 20 62 61 63 6b 67  ** using a backg
a1f0: 72 6f 75 6e 64 20 74 68 72 65 61 64 2e 0a 2a 2a  round thread..**
a200: 0a 2a 2a 20 49 66 20 61 72 67 75 6d 65 6e 74 20  .** If argument 
a210: 62 46 67 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c  bFg is non-zero,
a220: 20 74 68 65 20 6f 70 65 72 61 74 69 6f 6e 20 61   the operation a
a230: 6c 77 61 79 73 20 75 73 65 73 20 74 68 65 20 63  lways uses the c
a240: 61 6c 6c 69 6e 67 20 74 68 72 65 61 64 2e 0a 2a  alling thread..*
a250: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
a260: 65 53 6f 72 74 65 72 46 6c 75 73 68 50 4d 41 28  eSorterFlushPMA(
a270: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 63 6f 6e  sqlite3 *db, con
a280: 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70  st VdbeCursor *p
a290: 43 73 72 2c 20 69 6e 74 20 62 46 67 29 7b 0a 20  Csr, int bFg){. 
a2a0: 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f   VdbeSorter *pSo
a2b0: 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f  rter = pCsr->pSo
a2c0: 72 74 65 72 3b 0a 20 20 69 6e 74 20 72 63 20 3d  rter;.  int rc =
a2d0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e   SQLITE_OK;.  in
a2e0: 74 20 69 3b 0a 20 20 53 6f 72 74 65 72 54 68 72  t i;.  SorterThr
a2f0: 65 61 64 20 2a 70 54 68 72 65 61 64 3b 20 20 20  ead *pThread;   
a300: 20 20 20 20 20 2f 2a 20 54 68 72 65 61 64 20 63       /* Thread c
a310: 6f 6e 74 65 78 74 20 75 73 65 64 20 74 6f 20 63  ontext used to c
a320: 72 65 61 74 65 20 6e 65 77 20 50 4d 41 20 2a 2f  reate new PMA */
a330: 0a 0a 20 20 70 53 6f 72 74 65 72 2d 3e 62 55 73  ..  pSorter->bUs
a340: 65 50 4d 41 20 3d 20 31 3b 0a 20 20 66 6f 72 28  ePMA = 1;.  for(
a350: 69 3d 30 3b 20 41 4c 57 41 59 53 28 20 69 3c 53  i=0; ALWAYS( i<S
a360: 51 4c 49 54 45 5f 4d 41 58 5f 53 4f 52 54 45 52  QLITE_MAX_SORTER
a370: 5f 54 48 52 45 41 44 20 29 3b 20 69 2b 2b 29 7b  _THREAD ); i++){
a380: 0a 20 20 20 20 70 54 68 72 65 61 64 20 3d 20 26  .    pThread = &
a390: 70 53 6f 72 74 65 72 2d 3e 61 54 68 72 65 61 64  pSorter->aThread
a3a0: 5b 69 5d 3b 0a 20 20 20 20 69 66 28 20 70 54 68  [i];.    if( pTh
a3b0: 72 65 61 64 2d 3e 62 44 6f 6e 65 20 29 7b 0a 20  read->bDone ){. 
a3c0: 20 20 20 20 20 76 6f 69 64 20 2a 70 52 65 74 3b       void *pRet;
a3d0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70  .      assert( p
a3e0: 54 68 72 65 61 64 2d 3e 70 54 68 72 65 61 64 20  Thread->pThread 
a3f0: 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71  );.      rc = sq
a400: 6c 69 74 65 33 54 68 72 65 61 64 4a 6f 69 6e 28  lite3ThreadJoin(
a410: 70 54 68 72 65 61 64 2d 3e 70 54 68 72 65 61 64  pThread->pThread
a420: 2c 20 26 70 52 65 74 29 3b 0a 20 20 20 20 20 20  , &pRet);.      
a430: 70 54 68 72 65 61 64 2d 3e 70 54 68 72 65 61 64  pThread->pThread
a440: 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 54 68 72   = 0;.      pThr
a450: 65 61 64 2d 3e 62 44 6f 6e 65 20 3d 20 30 3b 0a  ead->bDone = 0;.
a460: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
a470: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
a480: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 50     rc = SQLITE_P
a490: 54 52 5f 54 4f 5f 49 4e 54 28 70 52 65 74 29 3b  TR_TO_INT(pRet);
a4a0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
a4b0: 20 20 20 69 66 28 20 70 54 68 72 65 61 64 2d 3e     if( pThread->
a4c0: 70 54 68 72 65 61 64 3d 3d 30 20 29 20 62 72 65  pThread==0 ) bre
a4d0: 61 6b 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72  ak;.  }..  if( r
a4e0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
a4f0: 20 20 20 20 69 6e 74 20 62 55 73 65 46 67 20 3d      int bUseFg =
a500: 20 28 62 46 67 20 7c 7c 20 69 3d 3d 28 53 51 4c   (bFg || i==(SQL
a510: 49 54 45 5f 4d 41 58 5f 53 4f 52 54 45 52 5f 54  ITE_MAX_SORTER_T
a520: 48 52 45 41 44 2d 31 29 29 3b 0a 0a 20 20 20 20  HREAD-1));..    
a530: 61 73 73 65 72 74 28 20 70 54 68 72 65 61 64 2d  assert( pThread-
a540: 3e 70 54 68 72 65 61 64 3d 3d 30 20 26 26 20 70  >pThread==0 && p
a550: 54 68 72 65 61 64 2d 3e 62 44 6f 6e 65 3d 3d 30  Thread->bDone==0
a560: 20 29 3b 0a 20 20 20 20 70 54 68 72 65 61 64 2d   );.    pThread-
a570: 3e 65 57 6f 72 6b 20 3d 20 53 4f 52 54 45 52 5f  >eWork = SORTER_
a580: 54 48 52 45 41 44 5f 54 4f 5f 50 4d 41 3b 0a 20  THREAD_TO_PMA;. 
a590: 20 20 20 70 54 68 72 65 61 64 2d 3e 70 4c 69 73     pThread->pLis
a5a0: 74 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 52 65  t = pSorter->pRe
a5b0: 63 6f 72 64 3b 0a 20 20 20 20 70 54 68 72 65 61  cord;.    pThrea
a5c0: 64 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20 3d 20 70  d->nInMemory = p
a5d0: 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72  Sorter->nInMemor
a5e0: 79 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  y;.    pSorter->
a5f0: 6e 49 6e 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a 20  nInMemory = 0;. 
a600: 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63     pSorter->pRec
a610: 6f 72 64 20 3d 20 30 3b 0a 0a 20 20 20 20 69 66  ord = 0;..    if
a620: 28 20 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f  ( pSorter->aMemo
a630: 72 79 20 29 7b 0a 20 20 20 20 20 20 75 38 20 2a  ry ){.      u8 *
a640: 61 4d 65 6d 20 3d 20 70 54 68 72 65 61 64 2d 3e  aMem = pThread->
a650: 61 4c 69 73 74 4d 65 6d 6f 72 79 3b 0a 20 20 20  aListMemory;.   
a660: 20 20 20 70 54 68 72 65 61 64 2d 3e 61 4c 69 73     pThread->aLis
a670: 74 4d 65 6d 6f 72 79 20 3d 20 70 53 6f 72 74 65  tMemory = pSorte
a680: 72 2d 3e 61 4d 65 6d 6f 72 79 3b 0a 20 20 20 20  r->aMemory;.    
a690: 20 20 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f    pSorter->aMemo
a6a0: 72 79 20 3d 20 61 4d 65 6d 3b 0a 20 20 20 20 7d  ry = aMem;.    }
a6b0: 0a 0a 20 20 20 20 69 66 28 20 62 55 73 65 46 67  ..    if( bUseFg
a6c0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  ==0 ){.      /* 
a6d0: 4c 61 75 6e 63 68 20 61 20 62 61 63 6b 67 72 6f  Launch a backgro
a6e0: 75 6e 64 20 74 68 72 65 61 64 20 66 6f 72 20 74  und thread for t
a6f0: 68 69 73 20 6f 70 65 72 61 74 69 6f 6e 20 2a 2f  his operation */
a700: 0a 20 20 20 20 20 20 76 6f 69 64 20 2a 70 43 74  .      void *pCt
a710: 78 20 3d 20 28 76 6f 69 64 2a 29 70 54 68 72 65  x = (void*)pThre
a720: 61 64 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74  ad;.      assert
a730: 28 20 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f  ( pSorter->aMemo
a740: 72 79 3d 3d 30 20 7c 7c 20 70 54 68 72 65 61 64  ry==0 || pThread
a750: 2d 3e 61 4c 69 73 74 4d 65 6d 6f 72 79 21 3d 30  ->aListMemory!=0
a760: 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 54   );.      if( pT
a770: 68 72 65 61 64 2d 3e 61 4c 69 73 74 4d 65 6d 6f  hread->aListMemo
a780: 72 79 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  ry ){.        if
a790: 28 20 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f  ( pSorter->aMemo
a7a0: 72 79 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  ry==0 ){.       
a7b0: 20 20 20 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d     pSorter->aMem
a7c0: 6f 72 79 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c  ory = sqlite3Mal
a7d0: 6c 6f 63 28 70 53 6f 72 74 65 72 2d 3e 6e 4d 65  loc(pSorter->nMe
a7e0: 6d 6f 72 79 29 3b 0a 20 20 20 20 20 20 20 20 20  mory);.         
a7f0: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 61 4d   if( pSorter->aM
a800: 65 6d 6f 72 79 3d 3d 30 20 29 20 72 65 74 75 72  emory==0 ) retur
a810: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
a820: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
a830: 20 20 20 20 20 20 20 20 20 70 53 6f 72 74 65 72           pSorter
a840: 2d 3e 6e 4d 65 6d 6f 72 79 20 3d 20 73 71 6c 69  ->nMemory = sqli
a850: 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 53  te3MallocSize(pS
a860: 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 29 3b  orter->aMemory);
a870: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
a880: 20 7d 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71   }.      rc = sq
a890: 6c 69 74 65 33 54 68 72 65 61 64 43 72 65 61 74  lite3ThreadCreat
a8a0: 65 28 26 70 54 68 72 65 61 64 2d 3e 70 54 68 72  e(&pThread->pThr
a8b0: 65 61 64 2c 20 76 64 62 65 53 6f 72 74 65 72 54  ead, vdbeSorterT
a8c0: 68 72 65 61 64 4d 61 69 6e 2c 20 70 43 74 78 29  hreadMain, pCtx)
a8d0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
a8e0: 20 20 20 2f 2a 20 55 73 65 20 74 68 65 20 66 6f     /* Use the fo
a8f0: 72 65 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  reground thread 
a900: 66 6f 72 20 74 68 69 73 20 6f 70 65 72 61 74 69  for this operati
a910: 6f 6e 20 2a 2f 0a 20 20 20 20 20 20 75 38 20 2a  on */.      u8 *
a920: 61 4d 65 6d 3b 0a 20 20 20 20 20 20 72 63 20 3d  aMem;.      rc =
a930: 20 76 64 62 65 53 6f 72 74 65 72 52 75 6e 54 68   vdbeSorterRunTh
a940: 72 65 61 64 28 70 54 68 72 65 61 64 29 3b 0a 20  read(pThread);. 
a950: 20 20 20 20 20 61 4d 65 6d 20 3d 20 70 54 68 72       aMem = pThr
a960: 65 61 64 2d 3e 61 4c 69 73 74 4d 65 6d 6f 72 79  ead->aListMemory
a970: 3b 0a 20 20 20 20 20 20 70 54 68 72 65 61 64 2d  ;.      pThread-
a980: 3e 61 4c 69 73 74 4d 65 6d 6f 72 79 20 3d 20 70  >aListMemory = p
a990: 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 3b  Sorter->aMemory;
a9a0: 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  .      pSorter->
a9b0: 61 4d 65 6d 6f 72 79 20 3d 20 61 4d 65 6d 3b 0a  aMemory = aMem;.
a9c0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
a9d0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
a9e0: 20 41 64 64 20 61 20 72 65 63 6f 72 64 20 74 6f   Add a record to
a9f0: 20 74 68 65 20 73 6f 72 74 65 72 2e 0a 2a 2f 0a   the sorter..*/.
aa00: 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65 53  int sqlite3VdbeS
aa10: 6f 72 74 65 72 57 72 69 74 65 28 0a 20 20 73 71  orterWrite(.  sq
aa20: 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20  lite3 *db,      
aa30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
aa40: 20 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65   Database handle
aa50: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 56 64 62 65   */.  const Vdbe
aa60: 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 20 20  Cursor *pCsr,   
aa70: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
aa80: 6f 72 74 65 72 20 63 75 72 73 6f 72 20 2a 2f 0a  orter cursor */.
aa90: 20 20 4d 65 6d 20 2a 70 56 61 6c 20 20 20 20 20    Mem *pVal     
aaa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
aab0: 20 20 2f 2a 20 4d 65 6d 6f 72 79 20 63 65 6c 6c    /* Memory cell
aac0: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 72 65 63 6f   containing reco
aad0: 72 64 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65 53  rd */.){.  VdbeS
aae0: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d  orter *pSorter =
aaf0: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a   pCsr->pSorter;.
ab00: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
ab10: 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20  E_OK;           
ab20: 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65    /* Return Code
ab30: 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f   */.  SorterReco
ab40: 72 64 20 2a 70 4e 65 77 3b 20 20 20 20 20 20 20  rd *pNew;       
ab50: 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 6c 69 73        /* New lis
ab60: 74 20 65 6c 65 6d 65 6e 74 20 2a 2f 0a 0a 20 20  t element */..  
ab70: 69 6e 74 20 62 46 6c 75 73 68 3b 20 20 20 20 20  int bFlush;     
ab80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ab90: 2f 2a 20 54 72 75 65 20 74 6f 20 66 6c 75 73 68  /* True to flush
aba0: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 6d 65 6d   contents of mem
abb0: 6f 72 79 20 74 6f 20 50 4d 41 20 2a 2f 0a 20 20  ory to PMA */.  
abc0: 69 6e 74 20 6e 52 65 71 3b 20 20 20 20 20 20 20  int nReq;       
abd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
abe0: 2f 2a 20 42 79 74 65 73 20 6f 66 20 6d 65 6d 6f  /* Bytes of memo
abf0: 72 79 20 72 65 71 75 69 72 65 64 20 2a 2f 0a 20  ry required */. 
ac00: 20 69 6e 74 20 6e 50 4d 41 3b 20 20 20 20 20 20   int nPMA;      
ac10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ac20: 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 50 4d 41   /* Bytes of PMA
ac30: 20 73 70 61 63 65 20 72 65 71 75 69 72 65 64 20   space required 
ac40: 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 53  */..  assert( pS
ac50: 6f 72 74 65 72 20 29 3b 0a 0a 20 20 2f 2a 20 46  orter );..  /* F
ac60: 69 67 75 72 65 20 6f 75 74 20 77 68 65 74 68 65  igure out whethe
ac70: 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 63 75 72  r or not the cur
ac80: 72 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f 66  rent contents of
ac90: 20 6d 65 6d 6f 72 79 20 73 68 6f 75 6c 64 20 62   memory should b
aca0: 65 0a 20 20 2a 2a 20 66 6c 75 73 68 65 64 20 74  e.  ** flushed t
acb0: 6f 20 61 20 50 4d 41 20 62 65 66 6f 72 65 20 63  o a PMA before c
acc0: 6f 6e 74 69 6e 75 69 6e 67 2e 20 49 66 20 73 6f  ontinuing. If so
acd0: 2c 20 64 6f 20 73 6f 2e 0a 20 20 2a 2a 0a 20 20  , do so..  **.  
ace0: 2a 2a 20 49 66 20 75 73 69 6e 67 20 74 68 65 20  ** If using the 
acf0: 73 69 6e 67 6c 65 20 6c 61 72 67 65 20 61 6c 6c  single large all
ad00: 6f 63 61 74 69 6f 6e 20 6d 6f 64 65 20 28 70 53  ocation mode (pS
ad10: 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 21 3d  orter->aMemory!=
ad20: 30 29 2c 20 74 68 65 6e 0a 20 20 2a 2a 20 66 6c  0), then.  ** fl
ad30: 75 73 68 20 74 68 65 20 63 6f 6e 74 65 6e 74 73  ush the contents
ad40: 20 6f 66 20 6d 65 6d 6f 72 79 20 74 6f 20 61 20   of memory to a 
ad50: 6e 65 77 20 50 4d 41 20 69 66 20 28 61 29 20 61  new PMA if (a) a
ad60: 74 20 6c 65 61 73 74 20 6f 6e 65 20 76 61 6c 75  t least one valu
ad70: 65 20 69 73 0a 20 20 2a 2a 20 61 6c 72 65 61 64  e is.  ** alread
ad80: 79 20 69 6e 20 6d 65 6d 6f 72 79 20 61 6e 64 20  y in memory and 
ad90: 28 62 29 20 74 68 65 20 6e 65 77 20 76 61 6c 75  (b) the new valu
ada0: 65 20 77 69 6c 6c 20 6e 6f 74 20 66 69 74 20 69  e will not fit i
adb0: 6e 20 6d 65 6d 6f 72 79 2e 0a 20 20 2a 2a 20 0a  n memory..  ** .
adc0: 20 20 2a 2a 20 4f 72 2c 20 69 66 20 75 73 69 6e    ** Or, if usin
add0: 67 20 73 65 70 61 72 61 74 65 20 61 6c 6c 6f 63  g separate alloc
ade0: 61 74 69 6f 6e 73 20 66 6f 72 20 65 61 63 68 20  ations for each 
adf0: 72 65 63 6f 72 64 2c 20 66 6c 75 73 68 20 74 68  record, flush th
ae00: 65 20 63 6f 6e 74 65 6e 74 73 0a 20 20 2a 2a 20  e contents.  ** 
ae10: 6f 66 20 6d 65 6d 6f 72 79 20 74 6f 20 61 20 50  of memory to a P
ae20: 4d 41 20 69 66 20 65 69 74 68 65 72 20 6f 66 20  MA if either of 
ae30: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 72  the following ar
ae40: 65 20 74 72 75 65 3a 0a 20 20 2a 2a 0a 20 20 2a  e true:.  **.  *
ae50: 2a 20 20 20 2a 20 54 68 65 20 74 6f 74 61 6c 20  *   * The total 
ae60: 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 65 64  memory allocated
ae70: 20 66 6f 72 20 74 68 65 20 69 6e 2d 6d 65 6d 6f   for the in-memo
ae80: 72 79 20 6c 69 73 74 20 69 73 20 67 72 65 61 74  ry list is great
ae90: 65 72 20 0a 20 20 2a 2a 20 20 20 20 20 74 68 61  er .  **     tha
aea0: 6e 20 28 70 61 67 65 2d 73 69 7a 65 20 2a 20 63  n (page-size * c
aeb0: 61 63 68 65 2d 73 69 7a 65 29 2c 20 6f 72 0a 20  ache-size), or. 
aec0: 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 54 68 65   **.  **   * The
aed0: 20 74 6f 74 61 6c 20 6d 65 6d 6f 72 79 20 61 6c   total memory al
aee0: 6c 6f 63 61 74 65 64 20 66 6f 72 20 74 68 65 20  located for the 
aef0: 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20 69  in-memory list i
af00: 73 20 67 72 65 61 74 65 72 20 0a 20 20 2a 2a 20  s greater .  ** 
af10: 20 20 20 20 74 68 61 6e 20 28 70 61 67 65 2d 73      than (page-s
af20: 69 7a 65 20 2a 20 31 30 29 20 61 6e 64 20 73 71  ize * 10) and sq
af30: 6c 69 74 65 33 48 65 61 70 4e 65 61 72 6c 79 46  lite3HeapNearlyF
af40: 75 6c 6c 28 29 20 72 65 74 75 72 6e 73 20 74 72  ull() returns tr
af50: 75 65 2e 0a 20 20 2a 2f 0a 20 20 6e 52 65 71 20  ue..  */.  nReq 
af60: 3d 20 70 56 61 6c 2d 3e 6e 20 2b 20 73 69 7a 65  = pVal->n + size
af70: 6f 66 28 53 6f 72 74 65 72 52 65 63 6f 72 64 29  of(SorterRecord)
af80: 3b 0a 20 20 6e 50 4d 41 20 3d 20 70 56 61 6c 2d  ;.  nPMA = pVal-
af90: 3e 6e 20 2b 20 73 71 6c 69 74 65 33 56 61 72 69  >n + sqlite3Vari
afa0: 6e 74 4c 65 6e 28 70 56 61 6c 2d 3e 6e 29 3b 0a  ntLen(pVal->n);.
afb0: 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6d    if( pSorter->m
afc0: 78 50 6d 61 53 69 7a 65 20 29 7b 0a 20 20 20 20  xPmaSize ){.    
afd0: 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 61 4d 65  if( pSorter->aMe
afe0: 6d 6f 72 79 20 29 7b 0a 20 20 20 20 20 20 62 46  mory ){.      bF
aff0: 6c 75 73 68 20 3d 20 70 53 6f 72 74 65 72 2d 3e  lush = pSorter->
b000: 69 4d 65 6d 6f 72 79 20 26 26 20 28 70 53 6f 72  iMemory && (pSor
b010: 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 2b 6e 52 65  ter->iMemory+nRe
b020: 71 29 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 78  q) > pSorter->mx
b030: 50 6d 61 53 69 7a 65 3b 0a 20 20 20 20 7d 65 6c  PmaSize;.    }el
b040: 73 65 7b 0a 20 20 20 20 20 20 62 46 6c 75 73 68  se{.      bFlush
b050: 20 3d 20 28 0a 20 20 20 20 20 20 20 20 20 20 28   = (.          (
b060: 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f  pSorter->nInMemo
b070: 72 79 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 78  ry > pSorter->mx
b080: 50 6d 61 53 69 7a 65 29 0a 20 20 20 20 20 20 20  PmaSize).       
b090: 7c 7c 20 28 70 53 6f 72 74 65 72 2d 3e 6e 49 6e  || (pSorter->nIn
b0a0: 4d 65 6d 6f 72 79 20 3e 20 70 53 6f 72 74 65 72  Memory > pSorter
b0b0: 2d 3e 6d 6e 50 6d 61 53 69 7a 65 20 26 26 20 73  ->mnPmaSize && s
b0c0: 71 6c 69 74 65 33 48 65 61 70 4e 65 61 72 6c 79  qlite3HeapNearly
b0d0: 46 75 6c 6c 28 29 29 0a 20 20 20 20 20 20 29 3b  Full()).      );
b0e0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 62  .    }.    if( b
b0f0: 46 6c 75 73 68 20 29 7b 0a 20 20 20 20 20 20 72  Flush ){.      r
b100: 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 46 6c  c = vdbeSorterFl
b110: 75 73 68 50 4d 41 28 64 62 2c 20 70 43 73 72 2c  ushPMA(db, pCsr,
b120: 20 30 29 3b 0a 20 20 20 20 20 20 70 53 6f 72 74   0);.      pSort
b130: 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20 3d 20  er->nInMemory = 
b140: 30 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72  0;.      pSorter
b150: 2d 3e 69 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a 20  ->iMemory = 0;. 
b160: 20 20 20 20 20 61 73 73 65 72 74 28 20 72 63 21       assert( rc!
b170: 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53  =SQLITE_OK || pS
b180: 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 3d 3d  orter->pRecord==
b190: 30 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  0 );.    }.  }..
b1a0: 20 20 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65    pSorter->nInMe
b1b0: 6d 6f 72 79 20 2b 3d 20 6e 50 4d 41 3b 0a 0a 20  mory += nPMA;.. 
b1c0: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 61 4d   if( pSorter->aM
b1d0: 65 6d 6f 72 79 20 29 7b 0a 20 20 20 20 69 6e 74  emory ){.    int
b1e0: 20 6e 4d 69 6e 20 3d 20 70 53 6f 72 74 65 72 2d   nMin = pSorter-
b1f0: 3e 69 4d 65 6d 6f 72 79 20 2b 20 6e 52 65 71 3b  >iMemory + nReq;
b200: 0a 0a 20 20 20 20 69 66 28 20 6e 4d 69 6e 3e 70  ..    if( nMin>p
b210: 53 6f 72 74 65 72 2d 3e 6e 4d 65 6d 6f 72 79 20  Sorter->nMemory 
b220: 29 7b 0a 20 20 20 20 20 20 75 38 20 2a 61 4e 65  ){.      u8 *aNe
b230: 77 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e 65  w;.      int nNe
b240: 77 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6e 4d 65  w = pSorter->nMe
b250: 6d 6f 72 79 20 2a 20 32 3b 0a 20 20 20 20 20 20  mory * 2;.      
b260: 77 68 69 6c 65 28 20 6e 4e 65 77 20 3c 20 6e 4d  while( nNew < nM
b270: 69 6e 20 29 20 6e 4e 65 77 20 3d 20 6e 4e 65 77  in ) nNew = nNew
b280: 2a 32 3b 0a 20 20 20 20 20 20 69 66 28 20 6e 4e  *2;.      if( nN
b290: 65 77 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 78  ew > pSorter->mx
b2a0: 50 6d 61 53 69 7a 65 20 29 20 6e 4e 65 77 20 3d  PmaSize ) nNew =
b2b0: 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53   pSorter->mxPmaS
b2c0: 69 7a 65 3b 0a 20 20 20 20 20 20 69 66 28 20 6e  ize;.      if( n
b2d0: 4e 65 77 20 3c 20 6e 4d 69 6e 20 29 20 6e 4e 65  New < nMin ) nNe
b2e0: 77 20 3d 20 6e 4d 69 6e 3b 0a 0a 20 20 20 20 20  w = nMin;..     
b2f0: 20 61 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 52   aNew = sqlite3R
b300: 65 61 6c 6c 6f 63 28 70 53 6f 72 74 65 72 2d 3e  ealloc(pSorter->
b310: 61 4d 65 6d 6f 72 79 2c 20 6e 4e 65 77 29 3b 0a  aMemory, nNew);.
b320: 20 20 20 20 20 20 69 66 28 20 21 61 4e 65 77 20        if( !aNew 
b330: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
b340: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 70 53 6f  NOMEM;.      pSo
b350: 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 3d 20  rter->pRecord = 
b360: 61 4e 65 77 20 2b 20 28 28 75 38 2a 29 70 53 6f  aNew + ((u8*)pSo
b370: 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 2d 20  rter->pRecord - 
b380: 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79  pSorter->aMemory
b390: 29 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72  );.      pSorter
b3a0: 2d 3e 61 4d 65 6d 6f 72 79 20 3d 20 61 4e 65 77  ->aMemory = aNew
b3b0: 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d  ;.      pSorter-
b3c0: 3e 6e 4d 65 6d 6f 72 79 20 3d 20 6e 4e 65 77 3b  >nMemory = nNew;
b3d0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 4e 65 77  .    }..    pNew
b3e0: 20 3d 20 28 53 6f 72 74 65 72 52 65 63 6f 72 64   = (SorterRecord
b3f0: 2a 29 26 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d  *)&pSorter->aMem
b400: 6f 72 79 5b 70 53 6f 72 74 65 72 2d 3e 69 4d 65  ory[pSorter->iMe
b410: 6d 6f 72 79 5d 3b 0a 20 20 20 20 70 53 6f 72 74  mory];.    pSort
b420: 65 72 2d 3e 69 4d 65 6d 6f 72 79 20 2b 3d 20 52  er->iMemory += R
b430: 4f 55 4e 44 38 28 6e 52 65 71 29 3b 0a 20 20 20  OUND8(nReq);.   
b440: 20 70 4e 65 77 2d 3e 75 2e 69 4e 65 78 74 20 3d   pNew->u.iNext =
b450: 20 28 75 38 2a 29 28 70 53 6f 72 74 65 72 2d 3e   (u8*)(pSorter->
b460: 70 52 65 63 6f 72 64 29 20 2d 20 70 53 6f 72 74  pRecord) - pSort
b470: 65 72 2d 3e 61 4d 65 6d 6f 72 79 3b 0a 20 20 7d  er->aMemory;.  }
b480: 65 6c 73 65 7b 0a 20 20 20 20 70 4e 65 77 20 3d  else{.    pNew =
b490: 20 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a   (SorterRecord *
b4a0: 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 6e  )sqlite3Malloc(n
b4b0: 52 65 71 29 3b 0a 20 20 20 20 69 66 28 20 70 4e  Req);.    if( pN
b4c0: 65 77 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72  ew==0 ){.      r
b4d0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
b4e0: 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 4e  EM;.    }.    pN
b4f0: 65 77 2d 3e 75 2e 70 4e 65 78 74 20 3d 20 70 53  ew->u.pNext = pS
b500: 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 3b 0a  orter->pRecord;.
b510: 20 20 7d 0a 0a 20 20 6d 65 6d 63 70 79 28 53 52    }..  memcpy(SR
b520: 56 41 4c 28 70 4e 65 77 29 2c 20 70 56 61 6c 2d  VAL(pNew), pVal-
b530: 3e 7a 2c 20 70 56 61 6c 2d 3e 6e 29 3b 0a 20 20  >z, pVal->n);.  
b540: 70 4e 65 77 2d 3e 6e 56 61 6c 20 3d 20 70 56 61  pNew->nVal = pVa
b550: 6c 2d 3e 6e 3b 0a 20 20 70 53 6f 72 74 65 72 2d  l->n;.  pSorter-
b560: 3e 70 52 65 63 6f 72 64 20 3d 20 70 4e 65 77 3b  >pRecord = pNew;
b570: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
b580: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
b590: 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20  he total number 
b5a0: 6f 66 20 50 4d 41 73 20 69 6e 20 61 6c 6c 20 74  of PMAs in all t
b5b0: 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 73 2e 0a  emporary files..
b5c0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64  */.static int vd
b5d0: 62 65 53 6f 72 74 65 72 43 6f 75 6e 74 50 4d 41  beSorterCountPMA
b5e0: 28 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f  (VdbeSorter *pSo
b5f0: 72 74 65 72 29 7b 0a 20 20 69 6e 74 20 6e 50 4d  rter){.  int nPM
b600: 41 20 3d 20 30 3b 0a 20 20 69 6e 74 20 69 3b 0a  A = 0;.  int i;.
b610: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 53 51 4c    for(i=0; i<SQL
b620: 49 54 45 5f 4d 41 58 5f 53 4f 52 54 45 52 5f 54  ITE_MAX_SORTER_T
b630: 48 52 45 41 44 3b 20 69 2b 2b 29 7b 0a 20 20 20  HREAD; i++){.   
b640: 20 6e 50 4d 41 20 2b 3d 20 70 53 6f 72 74 65 72   nPMA += pSorter
b650: 2d 3e 61 54 68 72 65 61 64 5b 69 5d 2e 6e 50 4d  ->aThread[i].nPM
b660: 41 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  A;.  }.  return 
b670: 6e 50 4d 41 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f  nPMA;.}../*.** O
b680: 6e 63 65 20 74 68 65 20 73 6f 72 74 65 72 20 68  nce the sorter h
b690: 61 73 20 62 65 65 6e 20 70 6f 70 75 6c 61 74 65  as been populate
b6a0: 64 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  d, this function
b6b0: 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 70 72   is called to pr
b6c0: 65 70 61 72 65 0a 2a 2a 20 66 6f 72 20 69 74 65  epare.** for ite
b6d0: 72 61 74 69 6e 67 20 74 68 72 6f 75 67 68 20 69  rating through i
b6e0: 74 73 20 63 6f 6e 74 65 6e 74 73 20 69 6e 20 73  ts contents in s
b6f0: 6f 72 74 65 64 20 6f 72 64 65 72 2e 0a 2a 2f 0a  orted order..*/.
b700: 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65 53  int sqlite3VdbeS
b710: 6f 72 74 65 72 52 65 77 69 6e 64 28 73 71 6c 69  orterRewind(sqli
b720: 74 65 33 20 2a 64 62 2c 20 63 6f 6e 73 74 20 56  te3 *db, const V
b730: 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c  dbeCursor *pCsr,
b740: 20 69 6e 74 20 2a 70 62 45 6f 66 29 7b 0a 20 20   int *pbEof){.  
b750: 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72  VdbeSorter *pSor
b760: 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72  ter = pCsr->pSor
b770: 74 65 72 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20  ter;.  int rc = 
b780: 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20  SQLITE_OK;      
b790: 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
b7a0: 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 61 73 73 65   code */..  asse
b7b0: 72 74 28 20 70 53 6f 72 74 65 72 20 29 3b 0a 0a  rt( pSorter );..
b7c0: 20 20 2f 2a 20 49 66 20 6e 6f 20 64 61 74 61 20    /* If no data 
b7d0: 68 61 73 20 62 65 65 6e 20 77 72 69 74 74 65 6e  has been written
b7e0: 20 74 6f 20 64 69 73 6b 2c 20 74 68 65 6e 20 64   to disk, then d
b7f0: 6f 20 6e 6f 74 20 64 6f 20 73 6f 20 6e 6f 77 2e  o not do so now.
b800: 20 49 6e 73 74 65 61 64 2c 0a 20 20 2a 2a 20 73   Instead,.  ** s
b810: 6f 72 74 20 74 68 65 20 56 64 62 65 53 6f 72 74  ort the VdbeSort
b820: 65 72 2e 70 52 65 63 6f 72 64 20 6c 69 73 74 2e  er.pRecord list.
b830: 20 54 68 65 20 76 64 62 65 20 6c 61 79 65 72 20   The vdbe layer 
b840: 77 69 6c 6c 20 72 65 61 64 20 64 61 74 61 20 64  will read data d
b850: 69 72 65 63 74 6c 79 0a 20 20 2a 2a 20 66 72 6f  irectly.  ** fro
b860: 6d 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20  m the in-memory 
b870: 6c 69 73 74 2e 20 20 2a 2f 0a 20 20 69 66 28 20  list.  */.  if( 
b880: 70 53 6f 72 74 65 72 2d 3e 62 55 73 65 50 4d 41  pSorter->bUsePMA
b890: 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 70  ==0 ){.    if( p
b8a0: 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20  Sorter->pRecord 
b8b0: 29 7b 0a 20 20 20 20 20 20 53 6f 72 74 65 72 54  ){.      SorterT
b8c0: 68 72 65 61 64 20 2a 70 54 68 72 65 61 64 20 3d  hread *pThread =
b8d0: 20 26 70 53 6f 72 74 65 72 2d 3e 61 54 68 72 65   &pSorter->aThre
b8e0: 61 64 5b 30 5d 3b 0a 20 20 20 20 20 20 2a 70 62  ad[0];.      *pb
b8f0: 45 6f 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 70  Eof = 0;.      p
b900: 54 68 72 65 61 64 2d 3e 70 4c 69 73 74 20 3d 20  Thread->pList = 
b910: 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64  pSorter->pRecord
b920: 3b 0a 20 20 20 20 20 20 70 54 68 72 65 61 64 2d  ;.      pThread-
b930: 3e 65 57 6f 72 6b 20 3d 20 53 4f 52 54 45 52 5f  >eWork = SORTER_
b940: 54 48 52 45 41 44 5f 53 4f 52 54 3b 0a 20 20 20  THREAD_SORT;.   
b950: 20 20 20 61 73 73 65 72 74 28 20 70 54 68 72 65     assert( pThre
b960: 61 64 2d 3e 61 4c 69 73 74 4d 65 6d 6f 72 79 3d  ad->aListMemory=
b970: 3d 30 20 29 3b 0a 20 20 20 20 20 20 70 54 68 72  =0 );.      pThr
b980: 65 61 64 2d 3e 61 4c 69 73 74 4d 65 6d 6f 72 79  ead->aListMemory
b990: 20 3d 20 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d   = pSorter->aMem
b9a0: 6f 72 79 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  ory;.      rc = 
b9b0: 76 64 62 65 53 6f 72 74 65 72 52 75 6e 54 68 72  vdbeSorterRunThr
b9c0: 65 61 64 28 70 54 68 72 65 61 64 29 3b 0a 20 20  ead(pThread);.  
b9d0: 20 20 20 20 70 54 68 72 65 61 64 2d 3e 61 4c 69      pThread->aLi
b9e0: 73 74 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a 20 20  stMemory = 0;.  
b9f0: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 52 65      pSorter->pRe
ba00: 63 6f 72 64 20 3d 20 70 54 68 72 65 61 64 2d 3e  cord = pThread->
ba10: 70 4c 69 73 74 3b 0a 20 20 20 20 20 20 70 54 68  pList;.      pTh
ba20: 72 65 61 64 2d 3e 70 4c 69 73 74 20 3d 20 30 3b  read->pList = 0;
ba30: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
ba40: 20 20 2a 70 62 45 6f 66 20 3d 20 31 3b 0a 20 20    *pbEof = 1;.  
ba50: 20 20 7d 0a 20 20 20 20 72 65 74 75 72 6e 20 72    }.    return r
ba60: 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 57 72 69  c;.  }..  /* Wri
ba70: 74 65 20 74 68 65 20 63 75 72 72 65 6e 74 20 69  te the current i
ba80: 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20 74 6f  n-memory list to
ba90: 20 61 20 50 4d 41 2e 20 2a 2f 0a 20 20 69 66 28   a PMA. */.  if(
baa0: 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72   pSorter->pRecor
bab0: 64 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64  d ){.    rc = vd
bac0: 62 65 53 6f 72 74 65 72 46 6c 75 73 68 50 4d 41  beSorterFlushPMA
bad0: 28 64 62 2c 20 70 43 73 72 2c 20 31 29 3b 0a 20  (db, pCsr, 1);. 
bae0: 20 7d 0a 0a 20 20 2f 2a 20 4a 6f 69 6e 20 61 6c   }..  /* Join al
baf0: 6c 20 74 68 72 65 61 64 73 20 2a 2f 0a 20 20 72  l threads */.  r
bb00: 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4a 6f  c = vdbeSorterJo
bb10: 69 6e 41 6c 6c 28 70 53 6f 72 74 65 72 2c 20 72  inAll(pSorter, r
bb20: 63 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65  c);..  /* If the
bb30: 72 65 20 61 72 65 20 6d 6f 72 65 20 74 68 61 6e  re are more than
bb40: 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47   SORTER_MAX_MERG
bb50: 45 5f 43 4f 55 4e 54 20 50 4d 41 73 20 6f 6e 20  E_COUNT PMAs on 
bb60: 64 69 73 6b 2c 20 6d 65 72 67 65 0a 20 20 2a 2a  disk, merge.  **
bb70: 20 73 6f 6d 65 20 6f 66 20 74 68 65 6d 20 74 6f   some of them to
bb80: 67 65 74 68 65 72 20 73 6f 20 74 68 61 74 20 74  gether so that t
bb90: 68 69 73 20 69 73 20 6e 6f 20 6c 6f 6e 67 65 72  his is no longer
bba0: 20 74 68 65 20 63 61 73 65 2e 20 2a 2f 0a 20 20   the case. */.  
bbb0: 61 73 73 65 72 74 28 20 53 4f 52 54 45 52 5f 4d  assert( SORTER_M
bbc0: 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3e 3d  AX_MERGE_COUNT>=
bbd0: 53 51 4c 49 54 45 5f 4d 41 58 5f 53 4f 52 54 45  SQLITE_MAX_SORTE
bbe0: 52 5f 54 48 52 45 41 44 20 29 3b 0a 20 20 69 66  R_THREAD );.  if
bbf0: 28 20 76 64 62 65 53 6f 72 74 65 72 43 6f 75 6e  ( vdbeSorterCoun
bc00: 74 50 4d 41 28 70 53 6f 72 74 65 72 29 3e 53 4f  tPMA(pSorter)>SO
bc10: 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
bc20: 4f 55 4e 54 20 29 7b 0a 20 20 20 20 69 6e 74 20  OUNT ){.    int 
bc30: 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  i;.    for(i=0; 
bc40: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
bc50: 20 69 3c 53 51 4c 49 54 45 5f 4d 41 58 5f 53 4f   i<SQLITE_MAX_SO
bc60: 52 54 45 52 5f 54 48 52 45 41 44 3b 20 69 2b 2b  RTER_THREAD; i++
bc70: 29 7b 0a 20 20 20 20 20 20 53 6f 72 74 65 72 54  ){.      SorterT
bc80: 68 72 65 61 64 20 2a 70 54 68 72 65 61 64 20 3d  hread *pThread =
bc90: 20 26 70 53 6f 72 74 65 72 2d 3e 61 54 68 72 65   &pSorter->aThre
bca0: 61 64 5b 69 5d 3b 0a 20 20 20 20 20 20 69 66 28  ad[i];.      if(
bcb0: 20 70 54 68 72 65 61 64 2d 3e 70 54 65 6d 70 31   pThread->pTemp1
bcc0: 20 29 7b 0a 20 20 20 20 20 20 20 20 70 54 68 72   ){.        pThr
bcd0: 65 61 64 2d 3e 6e 43 6f 6e 73 6f 6c 69 64 61 74  ead->nConsolidat
bce0: 65 20 3d 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  e = SORTER_MAX_M
bcf0: 45 52 47 45 5f 43 4f 55 4e 54 2f 53 51 4c 49 54  ERGE_COUNT/SQLIT
bd00: 45 5f 4d 41 58 5f 53 4f 52 54 45 52 5f 54 48 52  E_MAX_SORTER_THR
bd10: 45 41 44 3b 0a 20 20 20 20 20 20 20 20 70 54 68  EAD;.        pTh
bd20: 72 65 61 64 2d 3e 65 57 6f 72 6b 20 3d 20 53 4f  read->eWork = SO
bd30: 52 54 45 52 5f 54 48 52 45 41 44 5f 43 4f 4e 53  RTER_THREAD_CONS
bd40: 3b 0a 0a 20 20 20 20 20 20 20 20 69 66 28 20 69  ;..        if( i
bd50: 3c 28 53 51 4c 49 54 45 5f 4d 41 58 5f 53 4f 52  <(SQLITE_MAX_SOR
bd60: 54 45 52 5f 54 48 52 45 41 44 2d 31 29 20 29 7b  TER_THREAD-1) ){
bd70: 0a 20 20 20 20 20 20 20 20 20 20 76 6f 69 64 20  .          void 
bd80: 2a 70 43 74 78 20 3d 20 28 76 6f 69 64 2a 29 70  *pCtx = (void*)p
bd90: 54 68 72 65 61 64 3b 0a 20 20 20 20 20 20 20 20  Thread;.        
bda0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 54 68    rc = sqlite3Th
bdb0: 72 65 61 64 43 72 65 61 74 65 28 26 70 54 68 72  readCreate(&pThr
bdc0: 65 61 64 2d 3e 70 54 68 72 65 61 64 2c 76 64 62  ead->pThread,vdb
bdd0: 65 53 6f 72 74 65 72 54 68 72 65 61 64 4d 61 69  eSorterThreadMai
bde0: 6e 2c 70 43 74 78 29 3b 0a 20 20 20 20 20 20 20  n,pCtx);.       
bdf0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
be00: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
be10: 72 52 75 6e 54 68 72 65 61 64 28 70 54 68 72 65  rRunThread(pThre
be20: 61 64 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  ad);.        }. 
be30: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
be40: 0a 0a 20 20 2f 2a 20 4a 6f 69 6e 20 61 6c 6c 20  ..  /* Join all 
be50: 74 68 72 65 61 64 73 20 2a 2f 0a 20 20 72 63 20  threads */.  rc 
be60: 3d 20 76 64 62 65 53 6f 72 74 65 72 4a 6f 69 6e  = vdbeSorterJoin
be70: 41 6c 6c 28 70 53 6f 72 74 65 72 2c 20 72 63 29  All(pSorter, rc)
be80: 3b 0a 0a 20 20 2f 2a 20 41 73 73 75 6d 69 6e 67  ;..  /* Assuming
be90: 20 6e 6f 20 65 72 72 6f 72 73 20 68 61 76 65 20   no errors have 
bea0: 6f 63 63 75 72 72 65 64 2c 20 73 65 74 20 75 70  occurred, set up
beb0: 20 61 20 6d 65 72 67 65 72 20 73 74 72 75 63 74   a merger struct
bec0: 75 72 65 20 74 6f 20 72 65 61 64 0a 20 20 2a 2a  ure to read.  **
bed0: 20 61 6e 64 20 6d 65 72 67 65 20 61 6c 6c 20 72   and merge all r
bee0: 65 6d 61 69 6e 69 6e 67 20 50 4d 41 73 2e 20 20  emaining PMAs.  
bef0: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 53 6f  */.  assert( pSo
bf00: 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 3d 3d 30  rter->pMerger==0
bf10: 20 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   );.  if( rc==SQ
bf20: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69  LITE_OK ){.    i
bf30: 6e 74 20 6e 49 74 65 72 20 3d 20 30 3b 20 20 20  nt nIter = 0;   
bf40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
bf50: 4e 75 6d 62 65 72 20 6f 66 20 69 74 65 72 61 74  Number of iterat
bf60: 6f 72 73 20 75 73 65 64 20 2a 2f 0a 20 20 20 20  ors used */.    
bf70: 69 6e 74 20 69 3b 0a 20 20 20 20 53 6f 72 74 65  int i;.    Sorte
bf80: 72 4d 65 72 67 65 72 20 2a 70 4d 65 72 67 65 72  rMerger *pMerger
bf90: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69  ;.    for(i=0; i
bfa0: 3c 53 51 4c 49 54 45 5f 4d 41 58 5f 53 4f 52 54  <SQLITE_MAX_SORT
bfb0: 45 52 5f 54 48 52 45 41 44 3b 20 69 2b 2b 29 7b  ER_THREAD; i++){
bfc0: 0a 20 20 20 20 20 20 6e 49 74 65 72 20 2b 3d 20  .      nIter += 
bfd0: 70 53 6f 72 74 65 72 2d 3e 61 54 68 72 65 61 64  pSorter->aThread
bfe0: 5b 69 5d 2e 6e 50 4d 41 3b 0a 20 20 20 20 7d 0a  [i].nPMA;.    }.
bff0: 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 4d  .    pSorter->pM
c000: 65 72 67 65 72 20 3d 20 70 4d 65 72 67 65 72 20  erger = pMerger 
c010: 3d 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67  = vdbeSorterMerg
c020: 65 72 4e 65 77 28 6e 49 74 65 72 29 3b 0a 20 20  erNew(nIter);.  
c030: 20 20 69 66 28 20 70 4d 65 72 67 65 72 3d 3d 30    if( pMerger==0
c040: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53   ){.      rc = S
c050: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
c060: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 6e   }else{.      in
c070: 74 20 69 49 74 65 72 20 3d 20 30 3b 0a 20 20 20  t iIter = 0;.   
c080: 20 20 20 69 6e 74 20 69 54 68 72 65 61 64 20 3d     int iThread =
c090: 20 30 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 54   0;.      for(iT
c0a0: 68 72 65 61 64 3d 30 3b 20 69 54 68 72 65 61 64  hread=0; iThread
c0b0: 3c 53 51 4c 49 54 45 5f 4d 41 58 5f 53 4f 52 54  <SQLITE_MAX_SORT
c0c0: 45 52 5f 54 48 52 45 41 44 3b 20 69 54 68 72 65  ER_THREAD; iThre
c0d0: 61 64 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 69  ad++){.        i
c0e0: 6e 74 20 69 50 4d 41 3b 0a 20 20 20 20 20 20 20  nt iPMA;.       
c0f0: 20 69 36 34 20 69 52 65 61 64 4f 66 66 20 3d 20   i64 iReadOff = 
c100: 30 3b 0a 20 20 20 20 20 20 20 20 53 6f 72 74 65  0;.        Sorte
c110: 72 54 68 72 65 61 64 20 2a 70 54 68 72 65 61 64  rThread *pThread
c120: 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 54 68   = &pSorter->aTh
c130: 72 65 61 64 5b 69 54 68 72 65 61 64 5d 3b 0a 20  read[iThread];. 
c140: 20 20 20 20 20 20 20 66 6f 72 28 69 50 4d 41 3d         for(iPMA=
c150: 30 3b 20 69 50 4d 41 3c 70 54 68 72 65 61 64 2d  0; iPMA<pThread-
c160: 3e 6e 50 4d 41 20 26 26 20 72 63 3d 3d 53 51 4c  >nPMA && rc==SQL
c170: 49 54 45 5f 4f 4b 3b 20 69 50 4d 41 2b 2b 29 7b  ITE_OK; iPMA++){
c180: 0a 20 20 20 20 20 20 20 20 20 20 69 36 34 20 6e  .          i64 n
c190: 44 75 6d 6d 79 20 3d 20 30 3b 0a 20 20 20 20 20  Dummy = 0;.     
c1a0: 20 20 20 20 20 56 64 62 65 53 6f 72 74 65 72 49       VdbeSorterI
c1b0: 74 65 72 20 2a 70 49 74 65 72 20 3d 20 26 70 4d  ter *pIter = &pM
c1c0: 65 72 67 65 72 2d 3e 61 49 74 65 72 5b 69 49 74  erger->aIter[iIt
c1d0: 65 72 2b 2b 5d 3b 0a 20 20 20 20 20 20 20 20 20  er++];.         
c1e0: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
c1f0: 49 74 65 72 49 6e 69 74 28 70 54 68 72 65 61 64  IterInit(pThread
c200: 2c 20 69 52 65 61 64 4f 66 66 2c 20 70 49 74 65  , iReadOff, pIte
c210: 72 2c 20 26 6e 44 75 6d 6d 79 29 3b 0a 20 20 20  r, &nDummy);.   
c220: 20 20 20 20 20 20 20 69 52 65 61 64 4f 66 66 20         iReadOff 
c230: 3d 20 70 49 74 65 72 2d 3e 69 45 6f 66 3b 0a 20  = pIter->iEof;. 
c240: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
c250: 0a 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 70 4d  ..      for(i=pM
c260: 65 72 67 65 72 2d 3e 6e 54 72 65 65 2d 31 3b 20  erger->nTree-1; 
c270: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
c280: 20 69 3e 30 3b 20 69 2d 2d 29 7b 0a 20 20 20 20   i>0; i--){.    
c290: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
c2a0: 74 65 72 44 6f 43 6f 6d 70 61 72 65 28 26 70 53  terDoCompare(&pS
c2b0: 6f 72 74 65 72 2d 3e 61 54 68 72 65 61 64 5b 30  orter->aThread[0
c2c0: 5d 2c 20 70 4d 65 72 67 65 72 2c 20 69 29 3b 0a  ], pMerger, i);.
c2d0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
c2e0: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
c2f0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70  ITE_OK ){.    *p
c300: 62 45 6f 66 20 3d 20 28 70 53 6f 72 74 65 72 2d  bEof = (pSorter-
c310: 3e 70 4d 65 72 67 65 72 2d 3e 61 49 74 65 72 5b  >pMerger->aIter[
c320: 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72  pSorter->pMerger
c330: 2d 3e 61 54 72 65 65 5b 31 5d 5d 2e 70 46 69 6c  ->aTree[1]].pFil
c340: 65 3d 3d 30 29 3b 0a 20 20 7d 0a 20 20 72 65 74  e==0);.  }.  ret
c350: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
c360: 20 41 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20   Advance to the 
c370: 6e 65 78 74 20 65 6c 65 6d 65 6e 74 20 69 6e 20  next element in 
c380: 74 68 65 20 73 6f 72 74 65 72 2e 0a 2a 2f 0a 69  the sorter..*/.i
c390: 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f  nt sqlite3VdbeSo
c3a0: 72 74 65 72 4e 65 78 74 28 73 71 6c 69 74 65 33  rterNext(sqlite3
c3b0: 20 2a 64 62 2c 20 63 6f 6e 73 74 20 56 64 62 65   *db, const Vdbe
c3c0: 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e  Cursor *pCsr, in
c3d0: 74 20 2a 70 62 45 6f 66 29 7b 0a 20 20 56 64 62  t *pbEof){.  Vdb
c3e0: 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72  eSorter *pSorter
c3f0: 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72   = pCsr->pSorter
c400: 3b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  ;.  int rc;     
c410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c420: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f      /* Return co
c430: 64 65 20 2a 2f 0a 0a 20 20 69 66 28 20 70 53 6f  de */..  if( pSo
c440: 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 20 29 7b  rter->pMerger ){
c450: 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f  .    rc = vdbeSo
c460: 72 74 65 72 4e 65 78 74 28 26 70 53 6f 72 74 65  rterNext(&pSorte
c470: 72 2d 3e 61 54 68 72 65 61 64 5b 30 5d 2c 20 70  r->aThread[0], p
c480: 53 6f 72 74 65 72 2d 3e 70 4d 65 72 67 65 72 2c  Sorter->pMerger,
c490: 20 70 62 45 6f 66 29 3b 0a 20 20 7d 65 6c 73 65   pbEof);.  }else
c4a0: 7b 0a 20 20 20 20 53 6f 72 74 65 72 52 65 63 6f  {.    SorterReco
c4b0: 72 64 20 2a 70 46 72 65 65 20 3d 20 70 53 6f 72  rd *pFree = pSor
c4c0: 74 65 72 2d 3e 70 52 65 63 6f 72 64 3b 0a 20 20  ter->pRecord;.  
c4d0: 20 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f    pSorter->pReco
c4e0: 72 64 20 3d 20 70 46 72 65 65 2d 3e 75 2e 70 4e  rd = pFree->u.pN
c4f0: 65 78 74 3b 0a 20 20 20 20 70 46 72 65 65 2d 3e  ext;.    pFree->
c500: 75 2e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20  u.pNext = 0;.   
c510: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 61 4d   if( pSorter->aM
c520: 65 6d 6f 72 79 3d 3d 30 20 29 20 76 64 62 65 53  emory==0 ) vdbeS
c530: 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65 65 28  orterRecordFree(
c540: 64 62 2c 20 70 46 72 65 65 29 3b 0a 20 20 20 20  db, pFree);.    
c550: 2a 70 62 45 6f 66 20 3d 20 21 70 53 6f 72 74 65  *pbEof = !pSorte
c560: 72 2d 3e 70 52 65 63 6f 72 64 3b 0a 20 20 20 20  r->pRecord;.    
c570: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
c580: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
c590: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
c5a0: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20   a pointer to a 
c5b0: 62 75 66 66 65 72 20 6f 77 6e 65 64 20 62 79 20  buffer owned by 
c5c0: 74 68 65 20 73 6f 72 74 65 72 20 74 68 61 74 20  the sorter that 
c5d0: 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 0a 2a 2a  contains the .**
c5e0: 20 63 75 72 72 65 6e 74 20 6b 65 79 2e 0a 2a 2f   current key..*/
c5f0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a 76 64  .static void *vd
c600: 62 65 53 6f 72 74 65 72 52 6f 77 6b 65 79 28 0a  beSorterRowkey(.
c610: 20 20 63 6f 6e 73 74 20 56 64 62 65 53 6f 72 74    const VdbeSort
c620: 65 72 20 2a 70 53 6f 72 74 65 72 2c 20 20 20 20  er *pSorter,    
c630: 20 20 2f 2a 20 53 6f 72 74 65 72 20 6f 62 6a 65    /* Sorter obje
c640: 63 74 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4b  ct */.  int *pnK
c650: 65 79 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ey              
c660: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
c670: 53 69 7a 65 20 6f 66 20 63 75 72 72 65 6e 74 20  Size of current 
c680: 6b 65 79 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  key in bytes */.
c690: 29 7b 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 3b  ){.  void *pKey;
c6a0: 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e  .  if( pSorter->
c6b0: 70 4d 65 72 67 65 72 20 29 7b 0a 20 20 20 20 56  pMerger ){.    V
c6c0: 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70  dbeSorterIter *p
c6d0: 49 74 65 72 3b 0a 20 20 20 20 70 49 74 65 72 20  Iter;.    pIter 
c6e0: 3d 20 26 70 53 6f 72 74 65 72 2d 3e 70 4d 65 72  = &pSorter->pMer
c6f0: 67 65 72 2d 3e 61 49 74 65 72 5b 20 70 53 6f 72  ger->aIter[ pSor
c700: 74 65 72 2d 3e 70 4d 65 72 67 65 72 2d 3e 61 54  ter->pMerger->aT
c710: 72 65 65 5b 31 5d 20 5d 3b 0a 20 20 20 20 2a 70  ree[1] ];.    *p
c720: 6e 4b 65 79 20 3d 20 70 49 74 65 72 2d 3e 6e 4b  nKey = pIter->nK
c730: 65 79 3b 0a 20 20 20 20 70 4b 65 79 20 3d 20 70  ey;.    pKey = p
c740: 49 74 65 72 2d 3e 61 4b 65 79 3b 0a 20 20 7d 65  Iter->aKey;.  }e
c750: 6c 73 65 7b 0a 20 20 20 20 2a 70 6e 4b 65 79 20  lse{.    *pnKey 
c760: 3d 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f  = pSorter->pReco
c770: 72 64 2d 3e 6e 56 61 6c 3b 0a 20 20 20 20 70 4b  rd->nVal;.    pK
c780: 65 79 20 3d 20 53 52 56 41 4c 28 70 53 6f 72 74  ey = SRVAL(pSort
c790: 65 72 2d 3e 70 52 65 63 6f 72 64 29 3b 0a 20 20  er->pRecord);.  
c7a0: 7d 0a 20 20 72 65 74 75 72 6e 20 70 4b 65 79 3b  }.  return pKey;
c7b0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20 74  .}../*.** Copy t
c7c0: 68 65 20 63 75 72 72 65 6e 74 20 73 6f 72 74 65  he current sorte
c7d0: 72 20 6b 65 79 20 69 6e 74 6f 20 74 68 65 20 6d  r key into the m
c7e0: 65 6d 6f 72 79 20 63 65 6c 6c 20 70 4f 75 74 2e  emory cell pOut.
c7f0: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56  .*/.int sqlite3V
c800: 64 62 65 53 6f 72 74 65 72 52 6f 77 6b 65 79 28  dbeSorterRowkey(
c810: 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72  const VdbeCursor
c820: 20 2a 70 43 73 72 2c 20 4d 65 6d 20 2a 70 4f 75   *pCsr, Mem *pOu
c830: 74 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72  t){.  VdbeSorter
c840: 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72   *pSorter = pCsr
c850: 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 76 6f 69  ->pSorter;.  voi
c860: 64 20 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b 65  d *pKey; int nKe
c870: 79 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  y;           /* 
c880: 53 6f 72 74 65 72 20 6b 65 79 20 74 6f 20 63 6f  Sorter key to co
c890: 70 79 20 69 6e 74 6f 20 70 4f 75 74 20 2a 2f 0a  py into pOut */.
c8a0: 0a 20 20 70 4b 65 79 20 3d 20 76 64 62 65 53 6f  .  pKey = vdbeSo
c8b0: 72 74 65 72 52 6f 77 6b 65 79 28 70 53 6f 72 74  rterRowkey(pSort
c8c0: 65 72 2c 20 26 6e 4b 65 79 29 3b 0a 20 20 69 66  er, &nKey);.  if
c8d0: 28 20 73 71 6c 69 74 65 33 56 64 62 65 4d 65 6d  ( sqlite3VdbeMem
c8e0: 47 72 6f 77 28 70 4f 75 74 2c 20 6e 4b 65 79 2c  Grow(pOut, nKey,
c8f0: 20 30 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72   0) ){.    retur
c900: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
c910: 20 20 7d 0a 20 20 70 4f 75 74 2d 3e 6e 20 3d 20    }.  pOut->n = 
c920: 6e 4b 65 79 3b 0a 20 20 4d 65 6d 53 65 74 54 79  nKey;.  MemSetTy
c930: 70 65 46 6c 61 67 28 70 4f 75 74 2c 20 4d 45 4d  peFlag(pOut, MEM
c940: 5f 42 6c 6f 62 29 3b 0a 20 20 6d 65 6d 63 70 79  _Blob);.  memcpy
c950: 28 70 4f 75 74 2d 3e 7a 2c 20 70 4b 65 79 2c 20  (pOut->z, pKey, 
c960: 6e 4b 65 79 29 3b 0a 0a 20 20 72 65 74 75 72 6e  nKey);..  return
c970: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
c980: 2a 0a 2a 2a 20 43 6f 6d 70 61 72 65 20 74 68 65  *.** Compare the
c990: 20 6b 65 79 20 69 6e 20 6d 65 6d 6f 72 79 20 63   key in memory c
c9a0: 65 6c 6c 20 70 56 61 6c 20 77 69 74 68 20 74 68  ell pVal with th
c9b0: 65 20 6b 65 79 20 74 68 61 74 20 74 68 65 20 73  e key that the s
c9c0: 6f 72 74 65 72 20 63 75 72 73 6f 72 0a 2a 2a 20  orter cursor.** 
c9d0: 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69  passed as the fi
c9e0: 72 73 74 20 61 72 67 75 6d 65 6e 74 20 63 75 72  rst argument cur
c9f0: 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f  rently points to
ca00: 2e 20 46 6f 72 20 74 68 65 20 70 75 72 70 6f 73  . For the purpos
ca10: 65 73 20 6f 66 0a 2a 2a 20 74 68 65 20 63 6f 6d  es of.** the com
ca20: 70 61 72 69 73 6f 6e 2c 20 69 67 6e 6f 72 65 20  parison, ignore 
ca30: 74 68 65 20 72 6f 77 69 64 20 66 69 65 6c 64 20  the rowid field 
ca40: 61 74 20 74 68 65 20 65 6e 64 20 6f 66 20 65 61  at the end of ea
ca50: 63 68 20 72 65 63 6f 72 64 2e 0a 2a 2a 0a 2a 2a  ch record..**.**
ca60: 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   If an error occ
ca70: 75 72 73 2c 20 72 65 74 75 72 6e 20 61 6e 20 53  urs, return an S
ca80: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
ca90: 20 28 69 2e 65 2e 20 53 51 4c 49 54 45 5f 4e 4f   (i.e. SQLITE_NO
caa0: 4d 45 4d 29 2e 0a 2a 2a 20 4f 74 68 65 72 77 69  MEM)..** Otherwi
cab0: 73 65 2c 20 73 65 74 20 2a 70 52 65 73 20 74 6f  se, set *pRes to
cac0: 20 61 20 6e 65 67 61 74 69 76 65 2c 20 7a 65 72   a negative, zer
cad0: 6f 20 6f 72 20 70 6f 73 69 74 69 76 65 20 76 61  o or positive va
cae0: 6c 75 65 20 69 66 20 74 68 65 0a 2a 2a 20 6b 65  lue if the.** ke
caf0: 79 20 69 6e 20 70 56 61 6c 20 69 73 20 73 6d 61  y in pVal is sma
cb00: 6c 6c 65 72 20 74 68 61 6e 2c 20 65 71 75 61 6c  ller than, equal
cb10: 20 74 6f 20 6f 72 20 6c 61 72 67 65 72 20 74 68   to or larger th
cb20: 61 6e 20 74 68 65 20 63 75 72 72 65 6e 74 20 73  an the current s
cb30: 6f 72 74 65 72 0a 2a 2a 20 6b 65 79 2e 0a 2a 2f  orter.** key..*/
cb40: 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65  .int sqlite3Vdbe
cb50: 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 0a 20  SorterCompare(. 
cb60: 20 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f   const VdbeCurso
cb70: 72 20 2a 70 43 73 72 2c 20 20 20 20 20 20 20 20  r *pCsr,        
cb80: 20 2f 2a 20 53 6f 72 74 65 72 20 63 75 72 73 6f   /* Sorter curso
cb90: 72 20 2a 2f 0a 20 20 4d 65 6d 20 2a 70 56 61 6c  r */.  Mem *pVal
cba0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
cbb0: 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20         /* Value 
cbc0: 74 6f 20 63 6f 6d 70 61 72 65 20 74 6f 20 63 75  to compare to cu
cbd0: 72 72 65 6e 74 20 73 6f 72 74 65 72 20 6b 65 79  rrent sorter key
cbe0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 49 67 6e 6f 72   */.  int nIgnor
cbf0: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
cc00: 20 20 20 20 20 20 2f 2a 20 49 67 6e 6f 72 65 20        /* Ignore 
cc10: 74 68 69 73 20 6d 61 6e 79 20 66 69 65 6c 64 73  this many fields
cc20: 20 61 74 20 74 68 65 20 65 6e 64 20 2a 2f 0a 20   at the end */. 
cc30: 20 69 6e 74 20 2a 70 52 65 73 20 20 20 20 20 20   int *pRes      
cc40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cc50: 20 2f 2a 20 4f 55 54 3a 20 52 65 73 75 6c 74 20   /* OUT: Result 
cc60: 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f  of comparison */
cc70: 0a 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72  .){.  VdbeSorter
cc80: 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72   *pSorter = pCsr
cc90: 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 53 6f 72  ->pSorter;.  Sor
cca0: 74 65 72 54 68 72 65 61 64 20 2a 70 4d 61 69 6e  terThread *pMain
ccb0: 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 54 68   = &pSorter->aTh
ccc0: 72 65 61 64 5b 30 5d 3b 0a 20 20 76 6f 69 64 20  read[0];.  void 
ccd0: 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b 65 79 3b  *pKey; int nKey;
cce0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f             /* So
ccf0: 72 74 65 72 20 6b 65 79 20 74 6f 20 63 6f 6d 70  rter key to comp
cd00: 61 72 65 20 70 56 61 6c 20 77 69 74 68 20 2a 2f  are pVal with */
cd10: 0a 0a 20 20 70 4b 65 79 20 3d 20 76 64 62 65 53  ..  pKey = vdbeS
cd20: 6f 72 74 65 72 52 6f 77 6b 65 79 28 70 53 6f 72  orterRowkey(pSor
cd30: 74 65 72 2c 20 26 6e 4b 65 79 29 3b 0a 20 20 76  ter, &nKey);.  v
cd40: 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65  dbeSorterCompare
cd50: 28 70 4d 61 69 6e 2c 20 6e 49 67 6e 6f 72 65 2c  (pMain, nIgnore,
cd60: 20 70 56 61 6c 2d 3e 7a 2c 20 70 56 61 6c 2d 3e   pVal->z, pVal->
cd70: 6e 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 2c 20 70  n, pKey, nKey, p
cd80: 52 65 73 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  Res);.  return S
cd90: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a              QLITE_OK;.}.