/ Hex Artifact Content
Login

Artifact acaefad52f6345a06fcfe2ec7da0c7d7d2569c39:


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 23 69 66 6e 64 65  beInt.h"..#ifnde
0290: 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4d 45  f SQLITE_OMIT_ME
02a0: 52 47 45 5f 53 4f 52 54 0a 0a 74 79 70 65 64 65  RGE_SORT..typede
02b0: 66 20 73 74 72 75 63 74 20 56 64 62 65 53 6f 72  f struct VdbeSor
02c0: 74 65 72 49 74 65 72 20 56 64 62 65 53 6f 72 74  terIter VdbeSort
02d0: 65 72 49 74 65 72 3b 0a 74 79 70 65 64 65 66 20  erIter;.typedef 
02e0: 73 74 72 75 63 74 20 53 6f 72 74 65 72 52 65 63  struct SorterRec
02f0: 6f 72 64 20 53 6f 72 74 65 72 52 65 63 6f 72 64  ord SorterRecord
0300: 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ;.typedef struct
0310: 20 46 69 6c 65 57 72 69 74 65 72 20 46 69 6c 65   FileWriter File
0320: 57 72 69 74 65 72 3b 0a 0a 2f 2a 0a 2a 2a 20 4e  Writer;../*.** N
0330: 4f 54 45 53 20 4f 4e 20 44 41 54 41 20 53 54 52  OTES ON DATA STR
0340: 55 43 54 55 52 45 20 55 53 45 44 20 46 4f 52 20  UCTURE USED FOR 
0350: 4e 2d 57 41 59 20 4d 45 52 47 45 53 3a 0a 2a 2a  N-WAY MERGES:.**
0360: 0a 2a 2a 20 41 73 20 6b 65 79 73 20 61 72 65 20  .** As keys are 
0370: 61 64 64 65 64 20 74 6f 20 74 68 65 20 73 6f 72  added to the sor
0380: 74 65 72 2c 20 74 68 65 79 20 61 72 65 20 77 72  ter, they are wr
0390: 69 74 74 65 6e 20 74 6f 20 64 69 73 6b 20 69 6e  itten to disk in
03a0: 20 61 20 73 65 72 69 65 73 0a 2a 2a 20 6f 66 20   a series.** of 
03b0: 73 6f 72 74 65 64 20 70 61 63 6b 65 64 2d 6d 65  sorted packed-me
03c0: 6d 6f 72 79 2d 61 72 72 61 79 73 20 28 50 4d 41  mory-arrays (PMA
03d0: 73 29 2e 20 54 68 65 20 73 69 7a 65 20 6f 66 20  s). The size of 
03e0: 65 61 63 68 20 50 4d 41 20 69 73 20 72 6f 75 67  each PMA is roug
03f0: 68 6c 79 0a 2a 2a 20 74 68 65 20 73 61 6d 65 20  hly.** the same 
0400: 61 73 20 74 68 65 20 63 61 63 68 65 2d 73 69 7a  as the cache-siz
0410: 65 20 61 6c 6c 6f 77 65 64 20 66 6f 72 20 74 65  e allowed for te
0420: 6d 70 6f 72 61 72 79 20 64 61 74 61 62 61 73 65  mporary database
0430: 73 2e 20 49 6e 20 6f 72 64 65 72 0a 2a 2a 20 74  s. In order.** t
0440: 6f 20 61 6c 6c 6f 77 20 74 68 65 20 63 61 6c 6c  o allow the call
0450: 65 72 20 74 6f 20 65 78 74 72 61 63 74 20 6b 65  er to extract ke
0460: 79 73 20 66 72 6f 6d 20 74 68 65 20 73 6f 72 74  ys from the sort
0470: 65 72 20 69 6e 20 73 6f 72 74 65 64 20 6f 72 64  er in sorted ord
0480: 65 72 2c 0a 2a 2a 20 61 6c 6c 20 50 4d 41 73 20  er,.** all PMAs 
0490: 63 75 72 72 65 6e 74 6c 79 20 73 74 6f 72 65 64  currently stored
04a0: 20 6f 6e 20 64 69 73 6b 20 6d 75 73 74 20 62 65   on disk must be
04b0: 20 6d 65 72 67 65 64 20 74 6f 67 65 74 68 65 72   merged together
04c0: 2e 20 54 68 69 73 20 63 6f 6d 6d 65 6e 74 0a 2a  . This comment.*
04d0: 2a 20 64 65 73 63 72 69 62 65 73 20 74 68 65 20  * describes the 
04e0: 64 61 74 61 20 73 74 72 75 63 74 75 72 65 20 75  data structure u
04f0: 73 65 64 20 74 6f 20 64 6f 20 73 6f 2e 20 54 68  sed to do so. Th
0500: 65 20 73 74 72 75 63 74 75 72 65 20 73 75 70 70  e structure supp
0510: 6f 72 74 73 20 0a 2a 2a 20 6d 65 72 67 69 6e 67  orts .** merging
0520: 20 61 6e 79 20 6e 75 6d 62 65 72 20 6f 66 20 61   any number of a
0530: 72 72 61 79 73 20 69 6e 20 61 20 73 69 6e 67 6c  rrays in a singl
0540: 65 20 70 61 73 73 20 77 69 74 68 20 6e 6f 20 72  e pass with no r
0550: 65 64 75 6e 64 61 6e 74 20 63 6f 6d 70 61 72 69  edundant compari
0560: 73 6f 6e 20 0a 2a 2a 20 6f 70 65 72 61 74 69 6f  son .** operatio
0570: 6e 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 49  ns..**.** The aI
0580: 74 65 72 5b 5d 20 61 72 72 61 79 20 63 6f 6e 74  ter[] array cont
0590: 61 69 6e 73 20 61 6e 20 69 74 65 72 61 74 6f 72  ains an iterator
05a0: 20 66 6f 72 20 65 61 63 68 20 6f 66 20 74 68 65   for each of the
05b0: 20 50 4d 41 73 20 62 65 69 6e 67 20 6d 65 72 67   PMAs being merg
05c0: 65 64 2e 0a 2a 2a 20 41 6e 20 61 49 74 65 72 5b  ed..** An aIter[
05d0: 5d 20 69 74 65 72 61 74 6f 72 20 65 69 74 68 65  ] iterator eithe
05e0: 72 20 70 6f 69 6e 74 73 20 74 6f 20 61 20 76 61  r points to a va
05f0: 6c 69 64 20 6b 65 79 20 6f 72 20 65 6c 73 65 20  lid key or else 
0600: 69 73 20 61 74 20 45 4f 46 2e 20 46 6f 72 20 0a  is at EOF. For .
0610: 2a 2a 20 74 68 65 20 70 75 72 70 6f 73 65 73 20  ** the purposes 
0620: 6f 66 20 74 68 65 20 70 61 72 61 67 72 61 70 68  of the paragraph
0630: 73 20 62 65 6c 6f 77 2c 20 77 65 20 61 73 73 75  s below, we assu
0640: 6d 65 20 74 68 61 74 20 74 68 65 20 61 72 72 61  me that the arra
0650: 79 20 69 73 20 61 63 74 75 61 6c 6c 79 20 0a 2a  y is actually .*
0660: 2a 20 4e 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20  * N elements in 
0670: 73 69 7a 65 2c 20 77 68 65 72 65 20 4e 20 69 73  size, where N is
0680: 20 74 68 65 20 73 6d 61 6c 6c 65 73 74 20 70 6f   the smallest po
0690: 77 65 72 20 6f 66 20 32 20 67 72 65 61 74 65 72  wer of 2 greater
06a0: 20 74 6f 20 6f 72 20 65 71 75 61 6c 20 0a 2a 2a   to or equal .**
06b0: 20 74 6f 20 74 68 65 20 6e 75 6d 62 65 72 20 6f   to the number o
06c0: 66 20 69 74 65 72 61 74 6f 72 73 20 62 65 69 6e  f iterators bein
06d0: 67 20 6d 65 72 67 65 64 2e 20 54 68 65 20 65 78  g merged. The ex
06e0: 74 72 61 20 61 49 74 65 72 5b 5d 20 65 6c 65 6d  tra aIter[] elem
06f0: 65 6e 74 73 20 61 72 65 20 0a 2a 2a 20 74 72 65  ents are .** tre
0700: 61 74 65 64 20 61 73 20 69 66 20 74 68 65 79 20  ated as if they 
0710: 61 72 65 20 65 6d 70 74 79 20 28 61 6c 77 61 79  are empty (alway
0720: 73 20 61 74 20 45 4f 46 29 2e 0a 2a 2a 0a 2a 2a  s at EOF)..**.**
0730: 20 54 68 65 20 61 54 72 65 65 5b 5d 20 61 72 72   The aTree[] arr
0740: 61 79 20 69 73 20 61 6c 73 6f 20 4e 20 65 6c 65  ay is also N ele
0750: 6d 65 6e 74 73 20 69 6e 20 73 69 7a 65 2e 20 54  ments in size. T
0760: 68 65 20 76 61 6c 75 65 20 6f 66 20 4e 20 69 73  he value of N is
0770: 20 73 74 6f 72 65 64 20 69 6e 0a 2a 2a 20 74 68   stored in.** th
0780: 65 20 56 64 62 65 53 6f 72 74 65 72 2e 6e 54 72  e VdbeSorter.nTr
0790: 65 65 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2a 0a  ee variable..**.
07a0: 2a 2a 20 54 68 65 20 66 69 6e 61 6c 20 28 4e 2f  ** The final (N/
07b0: 32 29 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20 61  2) elements of a
07c0: 54 72 65 65 5b 5d 20 63 6f 6e 74 61 69 6e 20 74  Tree[] contain t
07d0: 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20 63 6f  he results of co
07e0: 6d 70 61 72 69 6e 67 0a 2a 2a 20 70 61 69 72 73  mparing.** pairs
07f0: 20 6f 66 20 69 74 65 72 61 74 6f 72 20 6b 65 79   of iterator key
0800: 73 20 74 6f 67 65 74 68 65 72 2e 20 45 6c 65 6d  s together. Elem
0810: 65 6e 74 20 69 20 63 6f 6e 74 61 69 6e 73 20 74  ent i contains t
0820: 68 65 20 72 65 73 75 6c 74 20 6f 66 20 0a 2a 2a  he result of .**
0830: 20 63 6f 6d 70 61 72 69 6e 67 20 61 49 74 65 72   comparing aIter
0840: 5b 32 2a 69 2d 4e 5d 20 61 6e 64 20 61 49 74 65  [2*i-N] and aIte
0850: 72 5b 32 2a 69 2d 4e 2b 31 5d 2e 20 57 68 69 63  r[2*i-N+1]. Whic
0860: 68 65 76 65 72 20 6b 65 79 20 69 73 20 73 6d 61  hever key is sma
0870: 6c 6c 65 72 2c 20 74 68 65 0a 2a 2a 20 61 54 72  ller, the.** aTr
0880: 65 65 20 65 6c 65 6d 65 6e 74 20 69 73 20 73 65  ee element is se
0890: 74 20 74 6f 20 74 68 65 20 69 6e 64 65 78 20 6f  t to the index o
08a0: 66 20 69 74 2e 20 0a 2a 2a 0a 2a 2a 20 46 6f 72  f it. .**.** For
08b0: 20 74 68 65 20 70 75 72 70 6f 73 65 73 20 6f 66   the purposes of
08c0: 20 74 68 69 73 20 63 6f 6d 70 61 72 69 73 6f 6e   this comparison
08d0: 2c 20 45 4f 46 20 69 73 20 63 6f 6e 73 69 64 65  , EOF is conside
08e0: 72 65 64 20 67 72 65 61 74 65 72 20 74 68 61 6e  red greater than
08f0: 20 61 6e 79 0a 2a 2a 20 6f 74 68 65 72 20 6b 65   any.** other ke
0900: 79 20 76 61 6c 75 65 2e 20 49 66 20 74 68 65 20  y value. If the 
0910: 6b 65 79 73 20 61 72 65 20 65 71 75 61 6c 20 28  keys are equal (
0920: 6f 6e 6c 79 20 70 6f 73 73 69 62 6c 65 20 77 69  only possible wi
0930: 74 68 20 74 77 6f 20 45 4f 46 0a 2a 2a 20 76 61  th two EOF.** va
0940: 6c 75 65 73 29 2c 20 69 74 20 64 6f 65 73 6e 27  lues), it doesn'
0950: 74 20 6d 61 74 74 65 72 20 77 68 69 63 68 20 69  t matter which i
0960: 6e 64 65 78 20 69 73 20 73 74 6f 72 65 64 2e 0a  ndex is stored..
0970: 2a 2a 0a 2a 2a 20 54 68 65 20 28 4e 2f 34 29 20  **.** The (N/4) 
0980: 65 6c 65 6d 65 6e 74 73 20 6f 66 20 61 54 72 65  elements of aTre
0990: 65 5b 5d 20 74 68 61 74 20 70 72 65 63 65 65 64  e[] that preceed
09a0: 20 74 68 65 20 66 69 6e 61 6c 20 28 4e 2f 32 29   the final (N/2)
09b0: 20 64 65 73 63 72 69 62 65 64 20 0a 2a 2a 20 61   described .** a
09c0: 62 6f 76 65 20 63 6f 6e 74 61 69 6e 73 20 74 68  bove contains th
09d0: 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20 73  e index of the s
09e0: 6d 61 6c 6c 65 73 74 20 6f 66 20 65 61 63 68 20  mallest of each 
09f0: 62 6c 6f 63 6b 20 6f 66 20 34 20 69 74 65 72 61  block of 4 itera
0a00: 74 6f 72 73 2e 0a 2a 2a 20 41 6e 64 20 73 6f 20  tors..** And so 
0a10: 6f 6e 2e 20 53 6f 20 74 68 61 74 20 61 54 72 65  on. So that aTre
0a20: 65 5b 31 5d 20 63 6f 6e 74 61 69 6e 73 20 74 68  e[1] contains th
0a30: 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20 69  e index of the i
0a40: 74 65 72 61 74 6f 72 20 74 68 61 74 20 0a 2a 2a  terator that .**
0a50: 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74   currently point
0a60: 73 20 74 6f 20 74 68 65 20 73 6d 61 6c 6c 65 73  s to the smalles
0a70: 74 20 6b 65 79 20 76 61 6c 75 65 2e 20 61 54 72  t key value. aTr
0a80: 65 65 5b 30 5d 20 69 73 20 75 6e 75 73 65 64 2e  ee[0] is unused.
0a90: 0a 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65 3a 0a  .**.** Example:.
0aa0: 2a 2a 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b  **.**     aIter[
0ab0: 30 5d 20 2d 3e 20 42 61 6e 61 6e 61 0a 2a 2a 20  0] -> Banana.** 
0ac0: 20 20 20 20 61 49 74 65 72 5b 31 5d 20 2d 3e 20      aIter[1] -> 
0ad0: 46 65 69 6a 6f 61 0a 2a 2a 20 20 20 20 20 61 49  Feijoa.**     aI
0ae0: 74 65 72 5b 32 5d 20 2d 3e 20 45 6c 64 65 72 62  ter[2] -> Elderb
0af0: 65 72 72 79 0a 2a 2a 20 20 20 20 20 61 49 74 65  erry.**     aIte
0b00: 72 5b 33 5d 20 2d 3e 20 43 75 72 72 61 6e 74 0a  r[3] -> Currant.
0b10: 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 34 5d 20  **     aIter[4] 
0b20: 2d 3e 20 47 72 61 70 65 66 72 75 69 74 0a 2a 2a  -> Grapefruit.**
0b30: 20 20 20 20 20 61 49 74 65 72 5b 35 5d 20 2d 3e       aIter[5] ->
0b40: 20 41 70 70 6c 65 0a 2a 2a 20 20 20 20 20 61 49   Apple.**     aI
0b50: 74 65 72 5b 36 5d 20 2d 3e 20 44 75 72 69 61 6e  ter[6] -> Durian
0b60: 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 37 5d  .**     aIter[7]
0b70: 20 2d 3e 20 45 4f 46 0a 2a 2a 0a 2a 2a 20 20 20   -> EOF.**.**   
0b80: 20 20 61 54 72 65 65 5b 5d 20 3d 20 7b 20 58 2c    aTree[] = { X,
0b90: 20 35 20 20 20 30 2c 20 35 20 20 20 20 30 2c 20   5   0, 5    0, 
0ba0: 33 2c 20 35 2c 20 36 20 7d 0a 2a 2a 0a 2a 2a 20  3, 5, 6 }.**.** 
0bb0: 54 68 65 20 63 75 72 72 65 6e 74 20 65 6c 65 6d  The current elem
0bc0: 65 6e 74 20 69 73 20 22 41 70 70 6c 65 22 20 28  ent is "Apple" (
0bd0: 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68 65  the value of the
0be0: 20 6b 65 79 20 69 6e 64 69 63 61 74 65 64 20 62   key indicated b
0bf0: 79 20 0a 2a 2a 20 69 74 65 72 61 74 6f 72 20 35  y .** iterator 5
0c00: 29 2e 20 57 68 65 6e 20 74 68 65 20 4e 65 78 74  ). When the Next
0c10: 28 29 20 6f 70 65 72 61 74 69 6f 6e 20 69 73 20  () operation is 
0c20: 69 6e 76 6f 6b 65 64 2c 20 69 74 65 72 61 74 6f  invoked, iterato
0c30: 72 20 35 20 77 69 6c 6c 0a 2a 2a 20 62 65 20 61  r 5 will.** be a
0c40: 64 76 61 6e 63 65 64 20 74 6f 20 74 68 65 20 6e  dvanced to the n
0c50: 65 78 74 20 6b 65 79 20 69 6e 20 69 74 73 20 73  ext key in its s
0c60: 65 67 6d 65 6e 74 2e 20 53 61 79 20 74 68 65 20  egment. Say the 
0c70: 6e 65 78 74 20 6b 65 79 20 69 73 0a 2a 2a 20 22  next key is.** "
0c80: 45 67 67 70 6c 61 6e 74 22 3a 0a 2a 2a 0a 2a 2a  Eggplant":.**.**
0c90: 20 20 20 20 20 61 49 74 65 72 5b 35 5d 20 2d 3e       aIter[5] ->
0ca0: 20 45 67 67 70 6c 61 6e 74 0a 2a 2a 0a 2a 2a 20   Eggplant.**.** 
0cb0: 54 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  The contents of 
0cc0: 61 54 72 65 65 5b 5d 20 61 72 65 20 75 70 64 61  aTree[] are upda
0cd0: 74 65 64 20 66 69 72 73 74 20 62 79 20 63 6f 6d  ted first by com
0ce0: 70 61 72 69 6e 67 20 74 68 65 20 6e 65 77 20 69  paring the new i
0cf0: 74 65 72 61 74 6f 72 0a 2a 2a 20 35 20 6b 65 79  terator.** 5 key
0d00: 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e 74 20   to the current 
0d10: 6b 65 79 20 6f 66 20 69 74 65 72 61 74 6f 72 20  key of iterator 
0d20: 34 20 28 73 74 69 6c 6c 20 22 47 72 61 70 65 66  4 (still "Grapef
0d30: 72 75 69 74 22 29 2e 20 54 68 65 20 69 74 65 72  ruit"). The iter
0d40: 61 74 6f 72 0a 2a 2a 20 35 20 76 61 6c 75 65 20  ator.** 5 value 
0d50: 69 73 20 73 74 69 6c 6c 20 73 6d 61 6c 6c 65 72  is still smaller
0d60: 2c 20 73 6f 20 61 54 72 65 65 5b 36 5d 20 69 73  , so aTree[6] is
0d70: 20 73 65 74 20 74 6f 20 35 2e 20 41 6e 64 20 73   set to 5. And s
0d80: 6f 20 6f 6e 20 75 70 20 74 68 65 20 74 72 65 65  o on up the tree
0d90: 2e 0a 2a 2a 20 54 68 65 20 76 61 6c 75 65 20 6f  ..** The value o
0da0: 66 20 69 74 65 72 61 74 6f 72 20 36 20 2d 20 22  f iterator 6 - "
0db0: 44 75 72 69 61 6e 22 20 2d 20 69 73 20 6e 6f 77  Durian" - is now
0dc0: 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 74 68   smaller than th
0dd0: 61 74 20 6f 66 20 69 74 65 72 61 74 6f 72 0a 2a  at of iterator.*
0de0: 2a 20 35 2c 20 73 6f 20 61 54 72 65 65 5b 33 5d  * 5, so aTree[3]
0df0: 20 69 73 20 73 65 74 20 74 6f 20 36 2e 20 4b 65   is set to 6. Ke
0e00: 79 20 30 20 69 73 20 73 6d 61 6c 6c 65 72 20 74  y 0 is smaller t
0e10: 68 61 6e 20 6b 65 79 20 36 20 28 42 61 6e 61 6e  han key 6 (Banan
0e20: 61 3c 44 75 72 69 61 6e 29 2c 0a 2a 2a 20 73 6f  a<Durian),.** so
0e30: 20 74 68 65 20 76 61 6c 75 65 20 77 72 69 74 74   the value writt
0e40: 65 6e 20 69 6e 74 6f 20 65 6c 65 6d 65 6e 74 20  en into element 
0e50: 31 20 6f 66 20 74 68 65 20 61 72 72 61 79 20 69  1 of the array i
0e60: 73 20 30 2e 20 41 73 20 66 6f 6c 6c 6f 77 73 3a  s 0. As follows:
0e70: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 54 72 65 65  .**.**     aTree
0e80: 5b 5d 20 3d 20 7b 20 58 2c 20 30 20 20 20 30 2c  [] = { X, 0   0,
0e90: 20 36 20 20 20 20 30 2c 20 33 2c 20 35 2c 20 36   6    0, 3, 5, 6
0ea0: 20 7d 0a 2a 2a 0a 2a 2a 20 49 6e 20 6f 74 68 65   }.**.** In othe
0eb0: 72 20 77 6f 72 64 73 2c 20 65 61 63 68 20 74 69  r words, each ti
0ec0: 6d 65 20 77 65 20 61 64 76 61 6e 63 65 20 74 6f  me we advance to
0ed0: 20 74 68 65 20 6e 65 78 74 20 73 6f 72 74 65 72   the next sorter
0ee0: 20 65 6c 65 6d 65 6e 74 2c 20 6c 6f 67 32 28 4e   element, log2(N
0ef0: 29 0a 2a 2a 20 6b 65 79 20 63 6f 6d 70 61 72 69  ).** key compari
0f00: 73 6f 6e 20 6f 70 65 72 61 74 69 6f 6e 73 20 61  son operations a
0f10: 72 65 20 72 65 71 75 69 72 65 64 2c 20 77 68 65  re required, whe
0f20: 72 65 20 4e 20 69 73 20 74 68 65 20 6e 75 6d 62  re N is the numb
0f30: 65 72 20 6f 66 20 73 65 67 6d 65 6e 74 73 0a 2a  er of segments.*
0f40: 2a 20 62 65 69 6e 67 20 6d 65 72 67 65 64 20 28  * being merged (
0f50: 72 6f 75 6e 64 65 64 20 75 70 20 74 6f 20 74 68  rounded up to th
0f60: 65 20 6e 65 78 74 20 70 6f 77 65 72 20 6f 66 20  e next power of 
0f70: 32 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 56 64  2)..*/.struct Vd
0f80: 62 65 53 6f 72 74 65 72 20 7b 0a 20 20 69 36 34  beSorter {.  i64
0f90: 20 69 57 72 69 74 65 4f 66 66 3b 20 20 20 20 20   iWriteOff;     
0fa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0fb0: 43 75 72 72 65 6e 74 20 77 72 69 74 65 20 6f 66  Current write of
0fc0: 66 73 65 74 20 77 69 74 68 69 6e 20 66 69 6c 65  fset within file
0fd0: 20 70 54 65 6d 70 31 20 2a 2f 0a 20 20 69 36 34   pTemp1 */.  i64
0fe0: 20 69 52 65 61 64 4f 66 66 3b 20 20 20 20 20 20   iReadOff;      
0ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1000: 43 75 72 72 65 6e 74 20 72 65 61 64 20 6f 66 66  Current read off
1010: 73 65 74 20 77 69 74 68 69 6e 20 66 69 6c 65 20  set within file 
1020: 70 54 65 6d 70 31 20 2a 2f 0a 20 20 69 6e 74 20  pTemp1 */.  int 
1030: 6e 49 6e 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20  nInMemory;      
1040: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
1050: 75 72 72 65 6e 74 20 73 69 7a 65 20 6f 66 20 70  urrent size of p
1060: 52 65 63 6f 72 64 20 6c 69 73 74 20 61 73 20 50  Record list as P
1070: 4d 41 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 72 65  MA */.  int nTre
1080: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
1090: 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20          /* Used 
10a0: 73 69 7a 65 20 6f 66 20 61 54 72 65 65 2f 61 49  size of aTree/aI
10b0: 74 65 72 20 28 70 6f 77 65 72 20 6f 66 20 32 29  ter (power of 2)
10c0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 4d 41 3b 20   */.  int nPMA; 
10d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10e0: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
10f0: 6f 66 20 50 4d 41 73 20 73 74 6f 72 65 64 20 69  of PMAs stored i
1100: 6e 20 70 54 65 6d 70 31 20 2a 2f 0a 20 20 69 6e  n pTemp1 */.  in
1110: 74 20 6d 6e 50 6d 61 53 69 7a 65 3b 20 20 20 20  t mnPmaSize;    
1120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1130: 20 4d 69 6e 69 6d 75 6d 20 50 4d 41 20 73 69 7a   Minimum PMA siz
1140: 65 2c 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20  e, in bytes */. 
1150: 20 69 6e 74 20 6d 78 50 6d 61 53 69 7a 65 3b 20   int mxPmaSize; 
1160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1170: 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 50 4d 41 20   /* Maximum PMA 
1180: 73 69 7a 65 2c 20 69 6e 20 62 79 74 65 73 2e 20  size, in bytes. 
1190: 20 30 3d 3d 6e 6f 20 6c 69 6d 69 74 20 2a 2f 0a   0==no limit */.
11a0: 20 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72    VdbeSorterIter
11b0: 20 2a 61 49 74 65 72 3b 20 20 20 20 20 20 20 20   *aIter;        
11c0: 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 69 74    /* Array of it
11d0: 65 72 61 74 6f 72 73 20 74 6f 20 6d 65 72 67 65  erators to merge
11e0: 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 54 72 65 65   */.  int *aTree
11f0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1200: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
1210: 20 73 74 61 74 65 20 6f 66 20 69 6e 63 72 65 6d   state of increm
1220: 65 6e 74 61 6c 20 6d 65 72 67 65 20 2a 2f 0a 20  ental merge */. 
1230: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
1240: 54 65 6d 70 31 3b 20 20 20 20 20 20 20 20 20 20  Temp1;          
1250: 20 2f 2a 20 50 4d 41 20 66 69 6c 65 20 31 20 2a   /* PMA file 1 *
1260: 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64  /.  SorterRecord
1270: 20 2a 70 52 65 63 6f 72 64 3b 20 20 20 20 20 20   *pRecord;      
1280: 20 20 20 20 2f 2a 20 48 65 61 64 20 6f 66 20 69      /* Head of i
1290: 6e 2d 6d 65 6d 6f 72 79 20 72 65 63 6f 72 64 20  n-memory record 
12a0: 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 52  list */.  int nR
12b0: 65 63 6f 72 64 3b 20 20 20 20 20 20 20 20 20 20  ecord;          
12c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
12d0: 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20  ber of elements 
12e0: 6f 6e 20 74 68 65 20 70 52 65 63 6f 72 64 20 6c  on the pRecord l
12f0: 69 73 74 20 2a 2f 0a 20 20 55 6e 70 61 63 6b 65  ist */.  Unpacke
1300: 64 52 65 63 6f 72 64 20 2a 70 55 6e 70 61 63 6b  dRecord *pUnpack
1310: 65 64 3b 20 20 20 20 20 20 2f 2a 20 55 73 65 64  ed;      /* Used
1320: 20 74 6f 20 75 6e 70 61 63 6b 20 6b 65 79 73 20   to unpack keys 
1330: 2a 2f 0a 20 20 4b 65 79 49 6e 66 6f 20 2a 70 4b  */.  KeyInfo *pK
1340: 65 79 49 6e 66 6f 3b 20 20 20 20 20 20 20 20 20  eyInfo;         
1350: 20 20 20 20 20 2f 2a 20 43 6f 70 79 20 6f 66 20       /* Copy of 
1360: 63 75 72 73 6f 72 20 4b 65 79 49 6e 66 6f 20 77  cursor KeyInfo w
1370: 69 74 68 6f 75 74 20 64 62 20 70 74 72 20 2a 2f  ithout db ptr */
1380: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b 20  .  sqlite3 *db; 
1390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13a0: 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 63     /* Database c
13b0: 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 7d 3b 0a  onnection */.};.
13c0: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66 6f 6c 6c 6f  ./*.** The follo
13d0: 77 69 6e 67 20 74 79 70 65 20 69 73 20 61 6e 20  wing type is an 
13e0: 69 74 65 72 61 74 6f 72 20 66 6f 72 20 61 20 50  iterator for a P
13f0: 4d 41 2e 20 49 74 20 63 61 63 68 65 73 20 74 68  MA. It caches th
1400: 65 20 63 75 72 72 65 6e 74 20 6b 65 79 20 69 6e  e current key in
1410: 20 0a 2a 2a 20 76 61 72 69 61 62 6c 65 73 20 6e   .** variables n
1420: 4b 65 79 2f 61 4b 65 79 2e 20 49 66 20 74 68 65  Key/aKey. If the
1430: 20 69 74 65 72 61 74 6f 72 20 69 73 20 61 74 20   iterator is at 
1440: 45 4f 46 2c 20 70 46 69 6c 65 3d 3d 30 2e 0a 2a  EOF, pFile==0..*
1450: 2f 0a 73 74 72 75 63 74 20 56 64 62 65 53 6f 72  /.struct VdbeSor
1460: 74 65 72 49 74 65 72 20 7b 0a 20 20 69 36 34 20  terIter {.  i64 
1470: 69 52 65 61 64 4f 66 66 3b 20 20 20 20 20 20 20  iReadOff;       
1480: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
1490: 75 72 72 65 6e 74 20 72 65 61 64 20 6f 66 66 73  urrent read offs
14a0: 65 74 20 2a 2f 0a 20 20 69 36 34 20 69 45 6f 66  et */.  i64 iEof
14b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
14c0: 20 20 20 20 20 20 20 20 2f 2a 20 31 20 62 79 74          /* 1 byt
14d0: 65 20 70 61 73 74 20 45 4f 46 20 66 6f 72 20 74  e past EOF for t
14e0: 68 69 73 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a  his iterator */.
14f0: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b 20 20    sqlite3 *db;  
1500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1510: 20 20 2f 2a 20 43 6f 72 72 65 73 70 6f 6e 64 69    /* Correspondi
1520: 6e 67 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e  ng database conn
1530: 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20  ection */.  int 
1540: 6e 41 6c 6c 6f 63 3b 20 20 20 20 20 20 20 20 20  nAlloc;         
1550: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
1560: 79 74 65 73 20 6f 66 20 73 70 61 63 65 20 61 74  ytes of space at
1570: 20 61 41 6c 6c 6f 63 20 2a 2f 0a 20 20 69 6e 74   aAlloc */.  int
1580: 20 6e 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20   nKey;          
1590: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
15a0: 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  Number of bytes 
15b0: 69 6e 20 6b 65 79 20 2a 2f 0a 20 20 73 71 6c 69  in key */.  sqli
15c0: 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 3b  te3_file *pFile;
15d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
15e0: 69 6c 65 20 69 74 65 72 61 74 6f 72 20 69 73 20  ile iterator is 
15f0: 72 65 61 64 69 6e 67 20 66 72 6f 6d 20 2a 2f 0a  reading from */.
1600: 20 20 75 38 20 2a 61 41 6c 6c 6f 63 3b 20 20 20    u8 *aAlloc;   
1610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1620: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 64 20 73    /* Allocated s
1630: 70 61 63 65 20 2a 2f 0a 20 20 75 38 20 2a 61 4b  pace */.  u8 *aK
1640: 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ey;             
1650: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
1660: 6e 74 65 72 20 74 6f 20 63 75 72 72 65 6e 74 20  nter to current 
1670: 6b 65 79 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75  key */.  u8 *aBu
1680: 66 66 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  ffer;           
1690: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72           /* Curr
16a0: 65 6e 74 20 72 65 61 64 20 62 75 66 66 65 72 20  ent read buffer 
16b0: 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66 66 65 72  */.  int nBuffer
16c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
16d0: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
16e0: 72 65 61 64 20 62 75 66 66 65 72 20 69 6e 20 62  read buffer in b
16f0: 79 74 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  ytes */.};../*.*
1700: 2a 20 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66  * An instance of
1710: 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65 20   this structure 
1720: 69 73 20 75 73 65 64 20 74 6f 20 6f 72 67 61 6e  is used to organ
1730: 69 7a 65 20 74 68 65 20 73 74 72 65 61 6d 20 6f  ize the stream o
1740: 66 20 72 65 63 6f 72 64 73 0a 2a 2a 20 62 65 69  f records.** bei
1750: 6e 67 20 77 72 69 74 74 65 6e 20 74 6f 20 66 69  ng written to fi
1760: 6c 65 73 20 62 79 20 74 68 65 20 6d 65 72 67 65  les by the merge
1770: 2d 73 6f 72 74 20 63 6f 64 65 20 69 6e 74 6f 20  -sort code into 
1780: 61 6c 69 67 6e 65 64 2c 20 70 61 67 65 2d 73 69  aligned, page-si
1790: 7a 65 64 0a 2a 2a 20 62 6c 6f 63 6b 73 2e 20 20  zed.** blocks.  
17a0: 44 6f 69 6e 67 20 61 6c 6c 20 49 2f 4f 20 69 6e  Doing all I/O in
17b0: 20 61 6c 69 67 6e 65 64 20 70 61 67 65 2d 73 69   aligned page-si
17c0: 7a 65 64 20 62 6c 6f 63 6b 73 20 68 65 6c 70 73  zed blocks helps
17d0: 20 49 2f 4f 20 74 6f 20 67 6f 0a 2a 2a 20 66 61   I/O to go.** fa
17e0: 73 74 65 72 20 6f 6e 20 6d 61 6e 79 20 6f 70 65  ster on many ope
17f0: 72 61 74 69 6e 67 20 73 79 73 74 65 6d 73 2e 0a  rating systems..
1800: 2a 2f 0a 73 74 72 75 63 74 20 46 69 6c 65 57 72  */.struct FileWr
1810: 69 74 65 72 20 7b 0a 20 20 69 6e 74 20 65 46 57  iter {.  int eFW
1820: 45 72 72 3b 20 20 20 20 20 20 20 20 20 20 20 20  Err;            
1830: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 6f 6e 2d           /* Non-
1840: 7a 65 72 6f 20 69 66 20 69 6e 20 61 6e 20 65 72  zero if in an er
1850: 72 6f 72 20 73 74 61 74 65 20 2a 2f 0a 20 20 75  ror state */.  u
1860: 38 20 2a 61 42 75 66 66 65 72 3b 20 20 20 20 20  8 *aBuffer;     
1870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1880: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 77 72 69  * Pointer to wri
1890: 74 65 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 69  te buffer */.  i
18a0: 6e 74 20 6e 42 75 66 66 65 72 3b 20 20 20 20 20  nt nBuffer;     
18b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
18c0: 2a 20 53 69 7a 65 20 6f 66 20 77 72 69 74 65 20  * Size of write 
18d0: 62 75 66 66 65 72 20 69 6e 20 62 79 74 65 73 20  buffer in bytes 
18e0: 2a 2f 0a 20 20 69 6e 74 20 69 42 75 66 53 74 61  */.  int iBufSta
18f0: 72 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rt;             
1900: 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 62 79       /* First by
1910: 74 65 20 6f 66 20 62 75 66 66 65 72 20 74 6f 20  te of buffer to 
1920: 77 72 69 74 65 20 2a 2f 0a 20 20 69 6e 74 20 69  write */.  int i
1930: 42 75 66 45 6e 64 3b 20 20 20 20 20 20 20 20 20  BufEnd;         
1940: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61             /* La
1950: 73 74 20 62 79 74 65 20 6f 66 20 62 75 66 66 65  st byte of buffe
1960: 72 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20  r to write */.  
1970: 69 36 34 20 69 57 72 69 74 65 4f 66 66 3b 20 20  i64 iWriteOff;  
1980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1990: 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20 73 74 61  /* Offset of sta
19a0: 72 74 20 6f 66 20 62 75 66 66 65 72 20 69 6e 20  rt of buffer in 
19b0: 66 69 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65  file */.  sqlite
19c0: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20  3_file *pFile;  
19d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c            /* Fil
19e0: 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f  e to write to */
19f0: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 74 72  .};../*.** A str
1a00: 75 63 74 75 72 65 20 74 6f 20 73 74 6f 72 65 20  ucture to store 
1a10: 61 20 73 69 6e 67 6c 65 20 72 65 63 6f 72 64 2e  a single record.
1a20: 20 41 6c 6c 20 69 6e 2d 6d 65 6d 6f 72 79 20 72   All in-memory r
1a30: 65 63 6f 72 64 73 20 61 72 65 20 63 6f 6e 6e 65  ecords are conne
1a40: 63 74 65 64 0a 2a 2a 20 74 6f 67 65 74 68 65 72  cted.** together
1a50: 20 69 6e 74 6f 20 61 20 6c 69 6e 6b 65 64 20 6c   into a linked l
1a60: 69 73 74 20 68 65 61 64 65 64 20 61 74 20 56 64  ist headed at Vd
1a70: 62 65 53 6f 72 74 65 72 2e 70 52 65 63 6f 72 64  beSorter.pRecord
1a80: 20 75 73 69 6e 67 20 74 68 65 20 0a 2a 2a 20 53   using the .** S
1a90: 6f 72 74 65 72 52 65 63 6f 72 64 2e 70 4e 65 78  orterRecord.pNex
1aa0: 74 20 70 6f 69 6e 74 65 72 2e 0a 2a 2f 0a 73 74  t pointer..*/.st
1ab0: 72 75 63 74 20 53 6f 72 74 65 72 52 65 63 6f 72  ruct SorterRecor
1ac0: 64 20 7b 0a 20 20 76 6f 69 64 20 2a 70 56 61 6c  d {.  void *pVal
1ad0: 3b 0a 20 20 69 6e 74 20 6e 56 61 6c 3b 0a 20 20  ;.  int nVal;.  
1ae0: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e  SorterRecord *pN
1af0: 65 78 74 3b 0a 7d 3b 0a 0a 2f 2a 20 4d 69 6e 69  ext;.};../* Mini
1b00: 6d 75 6d 20 61 6c 6c 6f 77 61 62 6c 65 20 76 61  mum allowable va
1b10: 6c 75 65 20 66 6f 72 20 74 68 65 20 56 64 62 65  lue for the Vdbe
1b20: 53 6f 72 74 65 72 2e 6e 57 6f 72 6b 69 6e 67 20  Sorter.nWorking 
1b30: 76 61 72 69 61 62 6c 65 20 2a 2f 0a 23 64 65 66  variable */.#def
1b40: 69 6e 65 20 53 4f 52 54 45 52 5f 4d 49 4e 5f 57  ine SORTER_MIN_W
1b50: 4f 52 4b 49 4e 47 20 31 30 0a 0a 2f 2a 20 4d 61  ORKING 10../* Ma
1b60: 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20  ximum number of 
1b70: 73 65 67 6d 65 6e 74 73 20 74 6f 20 6d 65 72 67  segments to merg
1b80: 65 20 69 6e 20 61 20 73 69 6e 67 6c 65 20 70 61  e in a single pa
1b90: 73 73 2e 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53  ss. */.#define S
1ba0: 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f  ORTER_MAX_MERGE_
1bb0: 43 4f 55 4e 54 20 31 36 0a 0a 2f 2a 0a 2a 2a 20  COUNT 16../*.** 
1bc0: 46 72 65 65 20 61 6c 6c 20 6d 65 6d 6f 72 79 20  Free all memory 
1bd0: 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 74 68 65  belonging to the
1be0: 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20   VdbeSorterIter 
1bf0: 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20 61 73  object passed as
1c00: 20 74 68 65 20 73 65 63 6f 6e 64 0a 2a 2a 20 61   the second.** a
1c10: 72 67 75 6d 65 6e 74 2e 20 41 6c 6c 20 73 74 72  rgument. All str
1c20: 75 63 74 75 72 65 20 66 69 65 6c 64 73 20 61 72  ucture fields ar
1c30: 65 20 73 65 74 20 74 6f 20 7a 65 72 6f 20 62 65  e set to zero be
1c40: 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a  fore returning..
1c50: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76  */.static void v
1c60: 64 62 65 53 6f 72 74 65 72 49 74 65 72 5a 65 72  dbeSorterIterZer
1c70: 6f 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 56  o(sqlite3 *db, V
1c80: 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70  dbeSorterIter *p
1c90: 49 74 65 72 29 7b 0a 20 20 73 71 6c 69 74 65 33  Iter){.  sqlite3
1ca0: 44 62 46 72 65 65 28 64 62 2c 20 70 49 74 65 72  DbFree(db, pIter
1cb0: 2d 3e 61 41 6c 6c 6f 63 29 3b 0a 20 20 73 71 6c  ->aAlloc);.  sql
1cc0: 69 74 65 33 44 62 46 72 65 65 28 64 62 2c 20 70  ite3DbFree(db, p
1cd0: 49 74 65 72 2d 3e 61 42 75 66 66 65 72 29 3b 0a  Iter->aBuffer);.
1ce0: 20 20 6d 65 6d 73 65 74 28 70 49 74 65 72 2c 20    memset(pIter, 
1cf0: 30 2c 20 73 69 7a 65 6f 66 28 56 64 62 65 53 6f  0, sizeof(VdbeSo
1d00: 72 74 65 72 49 74 65 72 29 29 3b 0a 7d 0a 0a 2f  rterIter));.}../
1d10: 2a 0a 2a 2a 20 52 65 61 64 20 6e 42 79 74 65 20  *.** Read nByte 
1d20: 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 66 72  bytes of data fr
1d30: 6f 6d 20 74 68 65 20 73 74 72 65 61 6d 20 6f 66  om the stream of
1d40: 20 64 61 74 61 20 69 74 65 72 61 74 65 64 20 62   data iterated b
1d50: 79 20 6f 62 6a 65 63 74 20 70 2e 0a 2a 2a 20 49  y object p..** I
1d60: 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 73 65  f successful, se
1d70: 74 20 2a 70 70 4f 75 74 20 74 6f 20 70 6f 69 6e  t *ppOut to poin
1d80: 74 20 74 6f 20 61 20 62 75 66 66 65 72 20 63 6f  t to a buffer co
1d90: 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 64 61 74  ntaining the dat
1da0: 61 0a 2a 2a 20 61 6e 64 20 72 65 74 75 72 6e 20  a.** and return 
1db0: 53 51 4c 49 54 45 5f 4f 4b 2e 20 4f 74 68 65 72  SQLITE_OK. Other
1dc0: 77 69 73 65 2c 20 69 66 20 61 6e 20 65 72 72 6f  wise, if an erro
1dd0: 72 20 6f 63 63 75 72 73 2c 20 72 65 74 75 72 6e  r occurs, return
1de0: 20 61 6e 20 53 51 4c 69 74 65 0a 2a 2a 20 65 72   an SQLite.** er
1df0: 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20  ror code..**.** 
1e00: 54 68 65 20 62 75 66 66 65 72 20 69 6e 64 69 63  The buffer indic
1e10: 61 74 65 64 20 62 79 20 2a 70 70 4f 75 74 20 6d  ated by *ppOut m
1e20: 61 79 20 6f 6e 6c 79 20 62 65 20 63 6f 6e 73 69  ay only be consi
1e30: 64 65 72 65 64 20 76 61 6c 69 64 20 75 6e 74 69  dered valid unti
1e40: 6c 20 74 68 65 0a 2a 2a 20 6e 65 78 74 20 63 61  l the.** next ca
1e50: 6c 6c 20 74 6f 20 74 68 69 73 20 66 75 6e 63 74  ll to this funct
1e60: 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ion..*/.static i
1e70: 6e 74 20 76 64 62 65 53 6f 72 74 65 72 49 74 65  nt vdbeSorterIte
1e80: 72 52 65 61 64 28 0a 20 20 56 64 62 65 53 6f 72  rRead(.  VdbeSor
1e90: 74 65 72 49 74 65 72 20 2a 70 2c 20 20 20 20 20  terIter *p,     
1ea0: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72           /* Iter
1eb0: 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  ator */.  int nB
1ec0: 79 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  yte,            
1ed0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74            /* Byt
1ee0: 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 72 65  es of data to re
1ef0: 61 64 20 2a 2f 0a 20 20 75 38 20 2a 2a 70 70 4f  ad */.  u8 **ppO
1f00: 75 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ut              
1f10: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
1f20: 50 6f 69 6e 74 65 72 20 74 6f 20 62 75 66 66 65  Pointer to buffe
1f30: 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64 61 74  r containing dat
1f40: 61 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 42  a */.){.  int iB
1f50: 75 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  uf;             
1f60: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66            /* Off
1f70: 73 65 74 20 77 69 74 68 69 6e 20 62 75 66 66 65  set within buffe
1f80: 72 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a  r to read from *
1f90: 2f 0a 20 20 69 6e 74 20 6e 41 76 61 69 6c 3b 20  /.  int nAvail; 
1fa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fb0: 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20      /* Bytes of 
1fc0: 64 61 74 61 20 61 76 61 69 6c 61 62 6c 65 20 69  data available i
1fd0: 6e 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 61 73  n buffer */.  as
1fe0: 73 65 72 74 28 20 70 2d 3e 61 42 75 66 66 65 72  sert( p->aBuffer
1ff0: 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65   );..  /* If the
2000: 72 65 20 69 73 20 6e 6f 20 6d 6f 72 65 20 64 61  re is no more da
2010: 74 61 20 74 6f 20 62 65 20 72 65 61 64 20 66 72  ta to be read fr
2020: 6f 6d 20 74 68 65 20 62 75 66 66 65 72 2c 20 72  om the buffer, r
2030: 65 61 64 20 74 68 65 20 6e 65 78 74 20 0a 20 20  ead the next .  
2040: 2a 2a 20 70 2d 3e 6e 42 75 66 66 65 72 20 62 79  ** p->nBuffer by
2050: 74 65 73 20 6f 66 20 64 61 74 61 20 66 72 6f 6d  tes of data from
2060: 20 74 68 65 20 66 69 6c 65 20 69 6e 74 6f 20 69   the file into i
2070: 74 2e 20 4f 72 2c 20 69 66 20 74 68 65 72 65 20  t. Or, if there 
2080: 61 72 65 20 6c 65 73 73 0a 20 20 2a 2a 20 74 68  are less.  ** th
2090: 61 6e 20 70 2d 3e 6e 42 75 66 66 65 72 20 62 79  an p->nBuffer by
20a0: 74 65 73 20 72 65 6d 61 69 6e 69 6e 67 20 69 6e  tes remaining in
20b0: 20 74 68 65 20 50 4d 41 2c 20 72 65 61 64 20 61   the PMA, read a
20c0: 6c 6c 20 72 65 6d 61 69 6e 69 6e 67 20 64 61 74  ll remaining dat
20d0: 61 2e 20 20 2a 2f 0a 20 20 69 42 75 66 20 3d 20  a.  */.  iBuf = 
20e0: 70 2d 3e 69 52 65 61 64 4f 66 66 20 25 20 70 2d  p->iReadOff % p-
20f0: 3e 6e 42 75 66 66 65 72 3b 0a 20 20 69 66 28 20  >nBuffer;.  if( 
2100: 69 42 75 66 3d 3d 30 20 29 7b 0a 20 20 20 20 69  iBuf==0 ){.    i
2110: 6e 74 20 6e 52 65 61 64 3b 20 20 20 20 20 20 20  nt nRead;       
2120: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2130: 42 79 74 65 73 20 74 6f 20 72 65 61 64 20 66 72  Bytes to read fr
2140: 6f 6d 20 64 69 73 6b 20 2a 2f 0a 20 20 20 20 69  om disk */.    i
2150: 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
2160: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2170: 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28 29 20  sqlite3OsRead() 
2180: 72 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 0a  return code */..
2190: 20 20 20 20 2f 2a 20 44 65 74 65 72 6d 69 6e 65      /* Determine
21a0: 20 68 6f 77 20 6d 61 6e 79 20 62 79 74 65 73 20   how many bytes 
21b0: 6f 66 20 64 61 74 61 20 74 6f 20 72 65 61 64 2e  of data to read.
21c0: 20 2a 2f 0a 20 20 20 20 6e 52 65 61 64 20 3d 20   */.    nRead = 
21d0: 28 69 6e 74 29 28 70 2d 3e 69 45 6f 66 20 2d 20  (int)(p->iEof - 
21e0: 70 2d 3e 69 52 65 61 64 4f 66 66 29 3b 0a 20 20  p->iReadOff);.  
21f0: 20 20 69 66 28 20 6e 52 65 61 64 3e 70 2d 3e 6e    if( nRead>p->n
2200: 42 75 66 66 65 72 20 29 20 6e 52 65 61 64 20 3d  Buffer ) nRead =
2210: 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20   p->nBuffer;.   
2220: 20 61 73 73 65 72 74 28 20 6e 52 65 61 64 3e 30   assert( nRead>0
2230: 20 29 3b 0a 0a 20 20 20 20 2f 2a 20 52 65 61 64   );..    /* Read
2240: 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 66   data from the f
2250: 69 6c 65 2e 20 52 65 74 75 72 6e 20 65 61 72 6c  ile. Return earl
2260: 79 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  y if an error oc
2270: 63 75 72 73 2e 20 2a 2f 0a 20 20 20 20 72 63 20  curs. */.    rc 
2280: 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28  = sqlite3OsRead(
2290: 70 2d 3e 70 46 69 6c 65 2c 20 70 2d 3e 61 42 75  p->pFile, p->aBu
22a0: 66 66 65 72 2c 20 6e 52 65 61 64 2c 20 70 2d 3e  ffer, nRead, p->
22b0: 69 52 65 61 64 4f 66 66 29 3b 0a 20 20 20 20 61  iReadOff);.    a
22c0: 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54  ssert( rc!=SQLIT
22d0: 45 5f 49 4f 45 52 52 5f 53 48 4f 52 54 5f 52 45  E_IOERR_SHORT_RE
22e0: 41 44 20 29 3b 0a 20 20 20 20 69 66 28 20 72 63  AD );.    if( rc
22f0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
2300: 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 6e  turn rc;.  }.  n
2310: 41 76 61 69 6c 20 3d 20 70 2d 3e 6e 42 75 66 66  Avail = p->nBuff
2320: 65 72 20 2d 20 69 42 75 66 3b 20 0a 0a 20 20 69  er - iBuf; ..  i
2330: 66 28 20 6e 42 79 74 65 3c 3d 6e 41 76 61 69 6c  f( nByte<=nAvail
2340: 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20 72   ){.    /* The r
2350: 65 71 75 65 73 74 65 64 20 64 61 74 61 20 69 73  equested data is
2360: 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 74 68   available in th
2370: 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 62 75 66 66  e in-memory buff
2380: 65 72 2e 20 49 6e 20 74 68 69 73 0a 20 20 20 20  er. In this.    
2390: 2a 2a 20 63 61 73 65 20 74 68 65 72 65 20 69 73  ** case there is
23a0: 20 6e 6f 20 6e 65 65 64 20 74 6f 20 6d 61 6b 65   no need to make
23b0: 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 64   a copy of the d
23c0: 61 74 61 2c 20 6a 75 73 74 20 72 65 74 75 72 6e  ata, just return
23d0: 20 61 20 0a 20 20 20 20 2a 2a 20 70 6f 69 6e 74   a .    ** point
23e0: 65 72 20 69 6e 74 6f 20 74 68 65 20 62 75 66 66  er into the buff
23f0: 65 72 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72  er to the caller
2400: 2e 20 20 2a 2f 0a 20 20 20 20 2a 70 70 4f 75 74  .  */.    *ppOut
2410: 20 3d 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 69   = &p->aBuffer[i
2420: 42 75 66 5d 3b 0a 20 20 20 20 70 2d 3e 69 52 65  Buf];.    p->iRe
2430: 61 64 4f 66 66 20 2b 3d 20 6e 42 79 74 65 3b 0a  adOff += nByte;.
2440: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20    }else{.    /* 
2450: 54 68 65 20 72 65 71 75 65 73 74 65 64 20 64 61  The requested da
2460: 74 61 20 69 73 20 6e 6f 74 20 61 6c 6c 20 61 76  ta is not all av
2470: 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65 20 69  ailable in the i
2480: 6e 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65 72 2e  n-memory buffer.
2490: 0a 20 20 20 20 2a 2a 20 49 6e 20 74 68 69 73 20  .    ** In this 
24a0: 63 61 73 65 2c 20 61 6c 6c 6f 63 61 74 65 20 73  case, allocate s
24b0: 70 61 63 65 20 61 74 20 70 2d 3e 61 41 6c 6c 6f  pace at p->aAllo
24c0: 63 5b 5d 20 74 6f 20 63 6f 70 79 20 74 68 65 20  c[] to copy the 
24d0: 72 65 71 75 65 73 74 65 64 0a 20 20 20 20 2a 2a  requested.    **
24e0: 20 72 61 6e 67 65 20 69 6e 74 6f 2e 20 54 68 65   range into. The
24f0: 6e 20 72 65 74 75 72 6e 20 61 20 63 6f 70 79 20  n return a copy 
2500: 6f 66 20 70 6f 69 6e 74 65 72 20 70 2d 3e 61 41  of pointer p->aA
2510: 6c 6c 6f 63 20 74 6f 20 74 68 65 20 63 61 6c 6c  lloc to the call
2520: 65 72 2e 20 20 2a 2f 0a 20 20 20 20 69 6e 74 20  er.  */.    int 
2530: 6e 52 65 6d 3b 20 20 20 20 20 20 20 20 20 20 20  nRem;           
2540: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74            /* Byt
2550: 65 73 20 72 65 6d 61 69 6e 69 6e 67 20 74 6f 20  es remaining to 
2560: 63 6f 70 79 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20  copy */..    /* 
2570: 45 78 74 65 6e 64 20 74 68 65 20 70 2d 3e 61 41  Extend the p->aA
2580: 6c 6c 6f 63 5b 5d 20 61 6c 6c 6f 63 61 74 69 6f  lloc[] allocatio
2590: 6e 20 69 66 20 72 65 71 75 69 72 65 64 2e 20 2a  n if required. *
25a0: 2f 0a 20 20 20 20 69 66 28 20 70 2d 3e 6e 41 6c  /.    if( p->nAl
25b0: 6c 6f 63 3c 6e 42 79 74 65 20 29 7b 0a 20 20 20  loc<nByte ){.   
25c0: 20 20 20 69 6e 74 20 6e 4e 65 77 20 3d 20 70 2d     int nNew = p-
25d0: 3e 6e 41 6c 6c 6f 63 2a 32 3b 0a 20 20 20 20 20  >nAlloc*2;.     
25e0: 20 77 68 69 6c 65 28 20 6e 42 79 74 65 3e 6e 4e   while( nByte>nN
25f0: 65 77 20 29 20 6e 4e 65 77 20 3d 20 6e 4e 65 77  ew ) nNew = nNew
2600: 2a 32 3b 0a 20 20 20 20 20 20 70 2d 3e 61 41 6c  *2;.      p->aAl
2610: 6c 6f 63 20 3d 20 73 71 6c 69 74 65 33 44 62 52  loc = sqlite3DbR
2620: 65 61 6c 6c 6f 63 4f 72 46 72 65 65 28 70 2d 3e  eallocOrFree(p->
2630: 64 62 2c 20 70 2d 3e 61 41 6c 6c 6f 63 2c 20 6e  db, p->aAlloc, n
2640: 4e 65 77 29 3b 0a 20 20 20 20 20 20 69 66 28 20  New);.      if( 
2650: 21 70 2d 3e 61 41 6c 6c 6f 63 20 29 20 72 65 74  !p->aAlloc ) ret
2660: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
2670: 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 41 6c 6c 6f  ;.      p->nAllo
2680: 63 20 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 7d 0a  c = nNew;.    }.
2690: 0a 20 20 20 20 2f 2a 20 43 6f 70 79 20 61 73 20  .    /* Copy as 
26a0: 6d 75 63 68 20 64 61 74 61 20 61 73 20 69 73 20  much data as is 
26b0: 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65  available in the
26c0: 20 62 75 66 66 65 72 20 69 6e 74 6f 20 74 68 65   buffer into the
26d0: 20 73 74 61 72 74 20 6f 66 0a 20 20 20 20 2a 2a   start of.    **
26e0: 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 2e 20 20 2a   p->aAlloc[].  *
26f0: 2f 0a 20 20 20 20 6d 65 6d 63 70 79 28 70 2d 3e  /.    memcpy(p->
2700: 61 41 6c 6c 6f 63 2c 20 26 70 2d 3e 61 42 75 66  aAlloc, &p->aBuf
2710: 66 65 72 5b 69 42 75 66 5d 2c 20 6e 41 76 61 69  fer[iBuf], nAvai
2720: 6c 29 3b 0a 20 20 20 20 70 2d 3e 69 52 65 61 64  l);.    p->iRead
2730: 4f 66 66 20 2b 3d 20 6e 41 76 61 69 6c 3b 0a 20  Off += nAvail;. 
2740: 20 20 20 6e 52 65 6d 20 3d 20 6e 42 79 74 65 20     nRem = nByte 
2750: 2d 20 6e 41 76 61 69 6c 3b 0a 0a 20 20 20 20 2f  - nAvail;..    /
2760: 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  * The following 
2770: 6c 6f 6f 70 20 63 6f 70 69 65 73 20 75 70 20 74  loop copies up t
2780: 6f 20 70 2d 3e 6e 42 75 66 66 65 72 20 62 79 74  o p->nBuffer byt
2790: 65 73 20 70 65 72 20 69 74 65 72 61 74 69 6f 6e  es per iteration
27a0: 20 69 6e 74 6f 0a 20 20 20 20 2a 2a 20 74 68 65   into.    ** the
27b0: 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 62 75 66   p->aAlloc[] buf
27c0: 66 65 72 2e 20 20 2a 2f 0a 20 20 20 20 77 68 69  fer.  */.    whi
27d0: 6c 65 28 20 6e 52 65 6d 3e 30 20 29 7b 0a 20 20  le( nRem>0 ){.  
27e0: 20 20 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20      int rc;     
27f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2800: 2f 2a 20 76 64 62 65 53 6f 72 74 65 72 49 74 65  /* vdbeSorterIte
2810: 72 52 65 61 64 28 29 20 72 65 74 75 72 6e 20 63  rRead() return c
2820: 6f 64 65 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74  ode */.      int
2830: 20 6e 43 6f 70 79 3b 20 20 20 20 20 20 20 20 20   nCopy;         
2840: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
2850: 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f 20 63  er of bytes to c
2860: 6f 70 79 20 2a 2f 0a 20 20 20 20 20 20 75 38 20  opy */.      u8 
2870: 2a 61 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20  *aNext;         
2880: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
2890: 74 65 72 20 74 6f 20 62 75 66 66 65 72 20 74 6f  ter to buffer to
28a0: 20 63 6f 70 79 20 64 61 74 61 20 66 72 6f 6d 20   copy data from 
28b0: 2a 2f 0a 0a 20 20 20 20 20 20 6e 43 6f 70 79 20  */..      nCopy 
28c0: 3d 20 6e 52 65 6d 3b 0a 20 20 20 20 20 20 69 66  = nRem;.      if
28d0: 28 20 6e 52 65 6d 3e 70 2d 3e 6e 42 75 66 66 65  ( nRem>p->nBuffe
28e0: 72 20 29 20 6e 43 6f 70 79 20 3d 20 70 2d 3e 6e  r ) nCopy = p->n
28f0: 42 75 66 66 65 72 3b 0a 20 20 20 20 20 20 72 63  Buffer;.      rc
2900: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 49 74 65   = vdbeSorterIte
2910: 72 52 65 61 64 28 70 2c 20 6e 43 6f 70 79 2c 20  rRead(p, nCopy, 
2920: 26 61 4e 65 78 74 29 3b 0a 20 20 20 20 20 20 69  &aNext);.      i
2930: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
2940: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
2950: 20 20 20 20 61 73 73 65 72 74 28 20 61 4e 65 78      assert( aNex
2960: 74 21 3d 70 2d 3e 61 41 6c 6c 6f 63 20 29 3b 0a  t!=p->aAlloc );.
2970: 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d        memcpy(&p-
2980: 3e 61 41 6c 6c 6f 63 5b 6e 42 79 74 65 20 2d 20  >aAlloc[nByte - 
2990: 6e 52 65 6d 5d 2c 20 61 4e 65 78 74 2c 20 6e 43  nRem], aNext, nC
29a0: 6f 70 79 29 3b 0a 20 20 20 20 20 20 6e 52 65 6d  opy);.      nRem
29b0: 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 7d   -= nCopy;.    }
29c0: 0a 0a 20 20 20 20 2a 70 70 4f 75 74 20 3d 20 70  ..    *ppOut = p
29d0: 2d 3e 61 41 6c 6c 6f 63 3b 0a 20 20 7d 0a 0a 20  ->aAlloc;.  }.. 
29e0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
29f0: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64  K;.}../*.** Read
2a00: 20 61 20 76 61 72 69 6e 74 20 66 72 6f 6d 20 74   a varint from t
2a10: 68 65 20 73 74 72 65 61 6d 20 6f 66 20 64 61 74  he stream of dat
2a20: 61 20 61 63 63 65 73 73 65 64 20 62 79 20 70 2e  a accessed by p.
2a30: 20 53 65 74 20 2a 70 6e 4f 75 74 20 74 6f 0a 2a   Set *pnOut to.*
2a40: 2a 20 74 68 65 20 76 61 6c 75 65 20 72 65 61 64  * the value read
2a50: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2a60: 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 56 61  vdbeSorterIterVa
2a70: 72 69 6e 74 28 56 64 62 65 53 6f 72 74 65 72 49  rint(VdbeSorterI
2a80: 74 65 72 20 2a 70 2c 20 75 36 34 20 2a 70 6e 4f  ter *p, u64 *pnO
2a90: 75 74 29 7b 0a 20 20 69 6e 74 20 69 42 75 66 3b  ut){.  int iBuf;
2aa0: 0a 0a 20 20 69 42 75 66 20 3d 20 70 2d 3e 69 52  ..  iBuf = p->iR
2ab0: 65 61 64 4f 66 66 20 25 20 70 2d 3e 6e 42 75 66  eadOff % p->nBuf
2ac0: 66 65 72 3b 0a 20 20 69 66 28 20 69 42 75 66 20  fer;.  if( iBuf 
2ad0: 26 26 20 28 70 2d 3e 6e 42 75 66 66 65 72 2d 69  && (p->nBuffer-i
2ae0: 42 75 66 29 3e 3d 39 20 29 7b 0a 20 20 20 20 70  Buf)>=9 ){.    p
2af0: 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 73 71  ->iReadOff += sq
2b00: 6c 69 74 65 33 47 65 74 56 61 72 69 6e 74 28 26  lite3GetVarint(&
2b10: 70 2d 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d  p->aBuffer[iBuf]
2b20: 2c 20 70 6e 4f 75 74 29 3b 0a 20 20 7d 65 6c 73  , pnOut);.  }els
2b30: 65 7b 0a 20 20 20 20 75 38 20 61 56 61 72 69 6e  e{.    u8 aVarin
2b40: 74 5b 31 36 5d 2c 20 2a 61 3b 0a 20 20 20 20 69  t[16], *a;.    i
2b50: 6e 74 20 69 20 3d 20 30 2c 20 72 63 3b 0a 20 20  nt i = 0, rc;.  
2b60: 20 20 64 6f 7b 0a 20 20 20 20 20 20 72 63 20 3d    do{.      rc =
2b70: 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 52   vdbeSorterIterR
2b80: 65 61 64 28 70 2c 20 31 2c 20 26 61 29 3b 0a 20  ead(p, 1, &a);. 
2b90: 20 20 20 20 20 69 66 28 20 72 63 20 29 20 72 65       if( rc ) re
2ba0: 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 61  turn rc;.      a
2bb0: 56 61 72 69 6e 74 5b 28 69 2b 2b 29 26 30 78 66  Varint[(i++)&0xf
2bc0: 5d 20 3d 20 61 5b 30 5d 3b 0a 20 20 20 20 7d 77  ] = a[0];.    }w
2bd0: 68 69 6c 65 28 20 28 61 5b 30 5d 26 30 78 38 30  hile( (a[0]&0x80
2be0: 29 21 3d 30 20 29 3b 0a 20 20 20 20 73 71 6c 69  )!=0 );.    sqli
2bf0: 74 65 33 47 65 74 56 61 72 69 6e 74 28 61 56 61  te3GetVarint(aVa
2c00: 72 69 6e 74 2c 20 70 6e 4f 75 74 29 3b 0a 20 20  rint, pnOut);.  
2c10: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  }..  return SQLI
2c20: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a  TE_OK;.}.../*.**
2c30: 20 41 64 76 61 6e 63 65 20 69 74 65 72 61 74 6f   Advance iterato
2c40: 72 20 70 49 74 65 72 20 74 6f 20 74 68 65 20 6e  r pIter to the n
2c50: 65 78 74 20 6b 65 79 20 69 6e 20 69 74 73 20 50  ext key in its P
2c60: 4d 41 2e 20 52 65 74 75 72 6e 20 53 51 4c 49 54  MA. Return SQLIT
2c70: 45 5f 4f 4b 20 69 66 0a 2a 2a 20 6e 6f 20 65 72  E_OK if.** no er
2c80: 72 6f 72 20 6f 63 63 75 72 73 2c 20 6f 72 20 61  ror occurs, or a
2c90: 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  n SQLite error c
2ca0: 6f 64 65 20 69 66 20 6f 6e 65 20 64 6f 65 73 2e  ode if one does.
2cb0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
2cc0: 64 62 65 53 6f 72 74 65 72 49 74 65 72 4e 65 78  dbeSorterIterNex
2cd0: 74 28 0a 20 20 56 64 62 65 53 6f 72 74 65 72 49  t(.  VdbeSorterI
2ce0: 74 65 72 20 2a 70 49 74 65 72 20 20 20 20 20 20  ter *pIter      
2cf0: 20 20 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72       /* Iterator
2d00: 20 74 6f 20 61 64 76 61 6e 63 65 20 2a 2f 0a 29   to advance */.)
2d10: 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  {.  int rc;     
2d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2d30: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f      /* Return Co
2d40: 64 65 20 2a 2f 0a 20 20 75 36 34 20 6e 52 65 63  de */.  u64 nRec
2d50: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
2d60: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
2d70: 6f 66 20 72 65 63 6f 72 64 20 69 6e 20 62 79 74  of record in byt
2d80: 65 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20  es */.  sqlite3 
2d90: 2a 64 62 20 3d 20 70 49 74 65 72 2d 3e 64 62 3b  *db = pIter->db;
2da0: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
2db0: 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a  ase connection *
2dc0: 2f 0a 0a 20 20 69 66 28 20 70 49 74 65 72 2d 3e  /..  if( pIter->
2dd0: 69 52 65 61 64 4f 66 66 3e 3d 70 49 74 65 72 2d  iReadOff>=pIter-
2de0: 3e 69 45 6f 66 20 29 7b 0a 20 20 20 20 2f 2a 20  >iEof ){.    /* 
2df0: 54 68 69 73 20 69 73 20 61 6e 20 45 4f 46 20 63  This is an EOF c
2e00: 6f 6e 64 69 74 69 6f 6e 20 2a 2f 0a 20 20 20 20  ondition */.    
2e10: 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 5a 65  vdbeSorterIterZe
2e20: 72 6f 28 64 62 2c 20 70 49 74 65 72 29 3b 0a 20  ro(db, pIter);. 
2e30: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
2e40: 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d  _OK;.  }..  rc =
2e50: 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 56   vdbeSorterIterV
2e60: 61 72 69 6e 74 28 70 49 74 65 72 2c 20 26 6e 52  arint(pIter, &nR
2e70: 65 63 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  ec);.  if( rc==S
2e80: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
2e90: 70 49 74 65 72 2d 3e 6e 4b 65 79 20 3d 20 28 69  pIter->nKey = (i
2ea0: 6e 74 29 6e 52 65 63 3b 0a 20 20 20 20 72 63 20  nt)nRec;.    rc 
2eb0: 3d 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72  = vdbeSorterIter
2ec0: 52 65 61 64 28 70 49 74 65 72 2c 20 28 69 6e 74  Read(pIter, (int
2ed0: 29 6e 52 65 63 2c 20 26 70 49 74 65 72 2d 3e 61  )nRec, &pIter->a
2ee0: 4b 65 79 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  Key);.  }..  ret
2ef0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
2f00: 20 49 6e 69 74 69 61 6c 69 7a 65 20 69 74 65 72   Initialize iter
2f10: 61 74 6f 72 20 70 49 74 65 72 20 74 6f 20 73 63  ator pIter to sc
2f20: 61 6e 20 74 68 72 6f 75 67 68 20 74 68 65 20 50  an through the P
2f30: 4d 41 20 73 74 6f 72 65 64 20 69 6e 20 66 69 6c  MA stored in fil
2f40: 65 20 70 46 69 6c 65 0a 2a 2a 20 73 74 61 72 74  e pFile.** start
2f50: 69 6e 67 20 61 74 20 6f 66 66 73 65 74 20 69 53  ing at offset iS
2f60: 74 61 72 74 20 61 6e 64 20 65 6e 64 69 6e 67 20  tart and ending 
2f70: 61 74 20 6f 66 66 73 65 74 20 69 45 6f 66 2d 31  at offset iEof-1
2f80: 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
2f90: 0a 2a 2a 20 6c 65 61 76 65 73 20 74 68 65 20 69  .** leaves the i
2fa0: 74 65 72 61 74 6f 72 20 70 6f 69 6e 74 69 6e 67  terator pointing
2fb0: 20 74 6f 20 74 68 65 20 66 69 72 73 74 20 6b 65   to the first ke
2fc0: 79 20 69 6e 20 74 68 65 20 50 4d 41 20 28 6f 72  y in the PMA (or
2fd0: 20 45 4f 46 20 69 66 20 74 68 65 20 0a 2a 2a 20   EOF if the .** 
2fe0: 50 4d 41 20 69 73 20 65 6d 70 74 79 29 2e 0a 2a  PMA is empty)..*
2ff0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76 64 62  /.static int vdb
3000: 65 53 6f 72 74 65 72 49 74 65 72 49 6e 69 74 28  eSorterIterInit(
3010: 0a 20 20 63 6f 6e 73 74 20 56 64 62 65 53 6f 72  .  const VdbeSor
3020: 74 65 72 20 2a 70 53 6f 72 74 65 72 2c 20 20 20  ter *pSorter,   
3030: 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 6f 62 6a     /* Sorter obj
3040: 65 63 74 20 2a 2f 0a 20 20 69 36 34 20 69 53 74  ect */.  i64 iSt
3050: 61 72 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  art,            
3060: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74 61 72           /* Star
3070: 74 20 6f 66 66 73 65 74 20 69 6e 20 70 46 69 6c  t offset in pFil
3080: 65 20 2a 2f 0a 20 20 56 64 62 65 53 6f 72 74 65  e */.  VdbeSorte
3090: 72 49 74 65 72 20 2a 70 49 74 65 72 2c 20 20 20  rIter *pIter,   
30a0: 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72 61 74         /* Iterat
30b0: 6f 72 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 2a  or to populate *
30c0: 2f 0a 20 20 69 36 34 20 2a 70 6e 42 79 74 65 20  /.  i64 *pnByte 
30d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
30e0: 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 49      /* IN/OUT: I
30f0: 6e 63 72 65 6d 65 6e 74 20 74 68 69 73 20 76 61  ncrement this va
3100: 6c 75 65 20 62 79 20 50 4d 41 20 73 69 7a 65 20  lue by PMA size 
3110: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  */.){.  int rc =
3120: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e   SQLITE_OK;.  in
3130: 74 20 6e 42 75 66 3b 0a 20 20 73 71 6c 69 74 65  t nBuf;.  sqlite
3140: 33 20 2a 64 62 20 3d 20 70 53 6f 72 74 65 72 2d  3 *db = pSorter-
3150: 3e 64 62 3b 0a 0a 20 20 6e 42 75 66 20 3d 20 73  >db;..  nBuf = s
3160: 71 6c 69 74 65 33 42 74 72 65 65 47 65 74 50 61  qlite3BtreeGetPa
3170: 67 65 53 69 7a 65 28 64 62 2d 3e 61 44 62 5b 30  geSize(db->aDb[0
3180: 5d 2e 70 42 74 29 3b 0a 0a 20 20 61 73 73 65 72  ].pBt);..  asser
3190: 74 28 20 70 53 6f 72 74 65 72 2d 3e 69 57 72 69  t( pSorter->iWri
31a0: 74 65 4f 66 66 3e 69 53 74 61 72 74 20 29 3b 0a  teOff>iStart );.
31b0: 20 20 61 73 73 65 72 74 28 20 70 49 74 65 72 2d    assert( pIter-
31c0: 3e 61 41 6c 6c 6f 63 3d 3d 30 20 29 3b 0a 20 20  >aAlloc==0 );.  
31d0: 61 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e 61  assert( pIter->a
31e0: 42 75 66 66 65 72 3d 3d 30 20 29 3b 0a 20 20 70  Buffer==0 );.  p
31f0: 49 74 65 72 2d 3e 70 46 69 6c 65 20 3d 20 70 53  Iter->pFile = pS
3200: 6f 72 74 65 72 2d 3e 70 54 65 6d 70 31 3b 0a 20  orter->pTemp1;. 
3210: 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66 66   pIter->iReadOff
3220: 20 3d 20 69 53 74 61 72 74 3b 0a 20 20 70 49 74   = iStart;.  pIt
3230: 65 72 2d 3e 64 62 20 3d 20 64 62 3b 0a 20 20 70  er->db = db;.  p
3240: 49 74 65 72 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 31  Iter->nAlloc = 1
3250: 32 38 3b 0a 20 20 70 49 74 65 72 2d 3e 61 41 6c  28;.  pIter->aAl
3260: 6c 6f 63 20 3d 20 28 75 38 20 2a 29 73 71 6c 69  loc = (u8 *)sqli
3270: 74 65 33 44 62 4d 61 6c 6c 6f 63 52 61 77 28 64  te3DbMallocRaw(d
3280: 62 2c 20 70 49 74 65 72 2d 3e 6e 41 6c 6c 6f 63  b, pIter->nAlloc
3290: 29 3b 0a 20 20 70 49 74 65 72 2d 3e 6e 42 75 66  );.  pIter->nBuf
32a0: 66 65 72 20 3d 20 6e 42 75 66 3b 0a 20 20 70 49  fer = nBuf;.  pI
32b0: 74 65 72 2d 3e 61 42 75 66 66 65 72 20 3d 20 28  ter->aBuffer = (
32c0: 75 38 20 2a 29 73 71 6c 69 74 65 33 44 62 4d 61  u8 *)sqlite3DbMa
32d0: 6c 6c 6f 63 52 61 77 28 64 62 2c 20 6e 42 75 66  llocRaw(db, nBuf
32e0: 29 3b 0a 0a 20 20 69 66 28 20 21 70 49 74 65 72  );..  if( !pIter
32f0: 2d 3e 61 42 75 66 66 65 72 20 29 7b 0a 20 20 20  ->aBuffer ){.   
3300: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
3310: 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  EM;.  }else{.   
3320: 20 69 6e 74 20 69 42 75 66 3b 0a 0a 20 20 20 20   int iBuf;..    
3330: 69 42 75 66 20 3d 20 69 53 74 61 72 74 20 25 20  iBuf = iStart % 
3340: 6e 42 75 66 3b 0a 20 20 20 20 69 66 28 20 69 42  nBuf;.    if( iB
3350: 75 66 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  uf ){.      int 
3360: 6e 52 65 61 64 20 3d 20 6e 42 75 66 20 2d 20 69  nRead = nBuf - i
3370: 42 75 66 3b 0a 20 20 20 20 20 20 69 66 28 20 28  Buf;.      if( (
3380: 69 53 74 61 72 74 20 2b 20 6e 52 65 61 64 29 20  iStart + nRead) 
3390: 3e 20 70 53 6f 72 74 65 72 2d 3e 69 57 72 69 74  > pSorter->iWrit
33a0: 65 4f 66 66 20 29 7b 0a 20 20 20 20 20 20 20 20  eOff ){.        
33b0: 6e 52 65 61 64 20 3d 20 28 69 6e 74 29 28 70 53  nRead = (int)(pS
33c0: 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f 66 66  orter->iWriteOff
33d0: 20 2d 20 69 53 74 61 72 74 29 3b 0a 20 20 20 20   - iStart);.    
33e0: 20 20 7d 0a 20 20 20 20 20 20 72 63 20 3d 20 73    }.      rc = s
33f0: 71 6c 69 74 65 33 4f 73 52 65 61 64 28 0a 20 20  qlite3OsRead(.  
3400: 20 20 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d          pSorter-
3410: 3e 70 54 65 6d 70 31 2c 20 26 70 49 74 65 72 2d  >pTemp1, &pIter-
3420: 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d 2c 20  >aBuffer[iBuf], 
3430: 6e 52 65 61 64 2c 20 69 53 74 61 72 74 0a 20 20  nRead, iStart.  
3440: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 61 73 73      );.      ass
3450: 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f  ert( rc!=SQLITE_
3460: 49 4f 45 52 52 5f 53 48 4f 52 54 5f 52 45 41 44  IOERR_SHORT_READ
3470: 20 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69   );.    }..    i
3480: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
3490: 20 29 7b 0a 20 20 20 20 20 20 75 36 34 20 6e 42   ){.      u64 nB
34a0: 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  yte;            
34b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
34c0: 7a 65 20 6f 66 20 50 4d 41 20 69 6e 20 62 79 74  ze of PMA in byt
34d0: 65 73 20 2a 2f 0a 20 20 20 20 20 20 70 49 74 65  es */.      pIte
34e0: 72 2d 3e 69 45 6f 66 20 3d 20 70 53 6f 72 74 65  r->iEof = pSorte
34f0: 72 2d 3e 69 57 72 69 74 65 4f 66 66 3b 0a 20 20  r->iWriteOff;.  
3500: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
3510: 74 65 72 49 74 65 72 56 61 72 69 6e 74 28 70 49  terIterVarint(pI
3520: 74 65 72 2c 20 26 6e 42 79 74 65 29 3b 0a 20 20  ter, &nByte);.  
3530: 20 20 20 20 70 49 74 65 72 2d 3e 69 45 6f 66 20      pIter->iEof 
3540: 3d 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66  = pIter->iReadOf
3550: 66 20 2b 20 6e 42 79 74 65 3b 0a 20 20 20 20 20  f + nByte;.     
3560: 20 2a 70 6e 42 79 74 65 20 2b 3d 20 6e 42 79 74   *pnByte += nByt
3570: 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  e;.    }.  }..  
3580: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
3590: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64  K ){.    rc = vd
35a0: 62 65 53 6f 72 74 65 72 49 74 65 72 4e 65 78 74  beSorterIterNext
35b0: 28 70 49 74 65 72 29 3b 0a 20 20 7d 0a 20 20 72  (pIter);.  }.  r
35c0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a  eturn rc;.}.../*
35d0: 0a 2a 2a 20 43 6f 6d 70 61 72 65 20 6b 65 79 31  .** Compare key1
35e0: 20 28 62 75 66 66 65 72 20 70 4b 65 79 31 2c 20   (buffer pKey1, 
35f0: 73 69 7a 65 20 6e 4b 65 79 31 20 62 79 74 65 73  size nKey1 bytes
3600: 29 20 77 69 74 68 20 6b 65 79 32 20 28 62 75 66  ) with key2 (buf
3610: 66 65 72 20 70 4b 65 79 32 2c 20 0a 2a 2a 20 73  fer pKey2, .** s
3620: 69 7a 65 20 6e 4b 65 79 32 20 62 79 74 65 73 29  ize nKey2 bytes)
3630: 2e 20 20 41 72 67 75 6d 65 6e 74 20 70 4b 65 79  .  Argument pKey
3640: 49 6e 66 6f 20 73 75 70 70 6c 69 65 73 20 74 68  Info supplies th
3650: 65 20 63 6f 6c 6c 61 74 69 6f 6e 20 66 75 6e 63  e collation func
3660: 74 69 6f 6e 73 0a 2a 2a 20 75 73 65 64 20 62 79  tions.** used by
3670: 20 74 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2e   the comparison.
3680: 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   If an error occ
3690: 75 72 73 2c 20 72 65 74 75 72 6e 20 61 6e 20 53  urs, return an S
36a0: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
36b0: 2e 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20  ..** Otherwise, 
36c0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
36d0: 20 61 6e 64 20 73 65 74 20 2a 70 52 65 73 20 74   and set *pRes t
36e0: 6f 20 61 20 6e 65 67 61 74 69 76 65 2c 20 7a 65  o a negative, ze
36f0: 72 6f 20 6f 72 20 70 6f 73 69 74 69 76 65 0a 2a  ro or positive.*
3700: 2a 20 76 61 6c 75 65 2c 20 64 65 70 65 6e 64 69  * value, dependi
3710: 6e 67 20 6f 6e 20 77 68 65 74 68 65 72 20 6b 65  ng on whether ke
3720: 79 31 20 69 73 20 73 6d 61 6c 6c 65 72 2c 20 65  y1 is smaller, e
3730: 71 75 61 6c 20 74 6f 20 6f 72 20 6c 61 72 67 65  qual to or large
3740: 72 20 74 68 61 6e 20 6b 65 79 32 2e 0a 2a 2a 0a  r than key2..**.
3750: 2a 2a 20 49 66 20 74 68 65 20 62 4f 6d 69 74 52  ** If the bOmitR
3760: 6f 77 69 64 20 61 72 67 75 6d 65 6e 74 20 69 73  owid argument is
3770: 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 61 73 73 75 6d   non-zero, assum
3780: 65 20 62 6f 74 68 20 6b 65 79 73 20 65 6e 64 20  e both keys end 
3790: 69 6e 20 61 20 72 6f 77 69 64 0a 2a 2a 20 66 69  in a rowid.** fi
37a0: 65 6c 64 2e 20 46 6f 72 20 74 68 65 20 70 75 72  eld. For the pur
37b0: 70 6f 73 65 73 20 6f 66 20 74 68 65 20 63 6f 6d  poses of the com
37c0: 70 61 72 69 73 6f 6e 2c 20 69 67 6e 6f 72 65 20  parison, ignore 
37d0: 69 74 2e 20 41 6c 73 6f 2c 20 69 66 20 62 4f 6d  it. Also, if bOm
37e0: 69 74 52 6f 77 69 64 0a 2a 2a 20 69 73 20 74 72  itRowid.** is tr
37f0: 75 65 20 61 6e 64 20 6b 65 79 31 20 63 6f 6e 74  ue and key1 cont
3800: 61 69 6e 73 20 65 76 65 6e 20 61 20 73 69 6e 67  ains even a sing
3810: 6c 65 20 4e 55 4c 4c 20 76 61 6c 75 65 2c 20 69  le NULL value, i
3820: 74 20 69 73 20 63 6f 6e 73 69 64 65 72 65 64 20  t is considered 
3830: 74 6f 0a 2a 2a 20 62 65 20 6c 65 73 73 20 74 68  to.** be less th
3840: 61 6e 20 6b 65 79 32 2e 20 45 76 65 6e 20 69 66  an key2. Even if
3850: 20 6b 65 79 32 20 61 6c 73 6f 20 63 6f 6e 74 61   key2 also conta
3860: 69 6e 73 20 4e 55 4c 4c 20 76 61 6c 75 65 73 2e  ins NULL values.
3870: 0a 2a 2a 0a 2a 2a 20 49 66 20 70 4b 65 79 32 20  .**.** If pKey2 
3880: 69 73 20 70 61 73 73 65 64 20 61 20 4e 55 4c 4c  is passed a NULL
3890: 20 70 6f 69 6e 74 65 72 2c 20 74 68 65 6e 20 69   pointer, then i
38a0: 74 20 69 73 20 61 73 73 75 6d 65 64 20 74 68 61  t is assumed tha
38b0: 74 20 74 68 65 20 70 43 73 72 2d 3e 61 53 70 61  t the pCsr->aSpa
38c0: 63 65 0a 2a 2a 20 68 61 73 20 62 65 65 6e 20 61  ce.** has been a
38d0: 6c 6c 6f 63 61 74 65 64 20 61 6e 64 20 63 6f 6e  llocated and con
38e0: 74 61 69 6e 73 20 61 6e 20 75 6e 70 61 63 6b 65  tains an unpacke
38f0: 64 20 72 65 63 6f 72 64 20 74 68 61 74 20 69 73  d record that is
3900: 20 75 73 65 64 20 61 73 20 6b 65 79 32 2e 0a 2a   used as key2..*
3910: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64  /.static void vd
3920: 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28  beSorterCompare(
3930: 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70  .  VdbeSorter *p
3940: 53 6f 72 74 65 72 2c 20 20 20 20 20 20 20 20 20  Sorter,         
3950: 20 20 20 2f 2a 20 54 68 65 20 73 6f 72 74 65 72     /* The sorter
3960: 20 2a 2f 0a 20 20 69 6e 74 20 62 4f 6d 69 74 52   */.  int bOmitR
3970: 6f 77 69 64 2c 20 20 20 20 20 20 20 20 20 20 20  owid,           
3980: 20 20 20 20 20 20 2f 2a 20 49 67 6e 6f 72 65 20        /* Ignore 
3990: 72 6f 77 69 64 20 66 69 65 6c 64 20 61 74 20 65  rowid field at e
39a0: 6e 64 20 6f 66 20 6b 65 79 73 20 2a 2f 0a 20 20  nd of keys */.  
39b0: 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 4b 65 79  const void *pKey
39c0: 31 2c 20 69 6e 74 20 6e 4b 65 79 31 2c 20 20 20  1, int nKey1,   
39d0: 2f 2a 20 4c 65 66 74 20 73 69 64 65 20 6f 66 20  /* Left side of 
39e0: 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f 0a 20 20  comparison */.  
39f0: 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 4b 65 79  const void *pKey
3a00: 32 2c 20 69 6e 74 20 6e 4b 65 79 32 2c 20 20 20  2, int nKey2,   
3a10: 2f 2a 20 52 69 67 68 74 20 73 69 64 65 20 6f 66  /* Right side of
3a20: 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f 0a 20   comparison */. 
3a30: 20 69 6e 74 20 2a 70 52 65 73 2c 20 20 20 20 20   int *pRes,     
3a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a50: 20 2f 2a 20 4f 55 54 3a 20 52 65 73 75 6c 74 20   /* OUT: Result 
3a60: 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f  of comparison */
3a70: 0a 20 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72  .  UnpackedRecor
3a80: 64 20 2a 72 32 20 20 20 20 20 20 20 20 20 20 20  d *r2           
3a90: 20 20 20 2f 2a 20 53 70 61 63 65 20 74 6f 20 68     /* Space to h
3aa0: 6f 6c 64 20 74 68 65 20 75 6e 70 61 63 6b 65 64  old the unpacked
3ab0: 20 4b 65 79 32 20 72 65 63 6f 72 64 20 2a 2f 0a   Key2 record */.
3ac0: 29 7b 0a 20 20 4b 65 79 49 6e 66 6f 20 2a 70 4b  ){.  KeyInfo *pK
3ad0: 65 79 49 6e 66 6f 20 3d 20 70 53 6f 72 74 65 72  eyInfo = pSorter
3ae0: 2d 3e 70 4b 65 79 49 6e 66 6f 3b 0a 20 20 69 6e  ->pKeyInfo;.  in
3af0: 74 20 69 3b 0a 0a 20 20 69 66 28 20 70 4b 65 79  t i;..  if( pKey
3b00: 32 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  2 ){.    assert(
3b10: 20 72 32 21 3d 30 20 29 3b 0a 20 20 20 20 73 71   r2!=0 );.    sq
3b20: 6c 69 74 65 33 56 64 62 65 52 65 63 6f 72 64 55  lite3VdbeRecordU
3b30: 6e 70 61 63 6b 28 70 4b 65 79 49 6e 66 6f 2c 20  npack(pKeyInfo, 
3b40: 6e 4b 65 79 32 2c 20 70 4b 65 79 32 2c 20 72 32  nKey2, pKey2, r2
3b50: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 62 4f  );.  }..  if( bO
3b60: 6d 69 74 52 6f 77 69 64 20 29 7b 0a 20 20 20 20  mitRowid ){.    
3b70: 72 32 2d 3e 6e 46 69 65 6c 64 20 3d 20 70 4b 65  r2->nField = pKe
3b80: 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64 3b 0a 20  yInfo->nField;. 
3b90: 20 20 20 61 73 73 65 72 74 28 20 72 32 2d 3e 6e     assert( r2->n
3ba0: 46 69 65 6c 64 3e 30 20 29 3b 0a 20 20 20 20 66  Field>0 );.    f
3bb0: 6f 72 28 69 3d 30 3b 20 69 3c 72 32 2d 3e 6e 46  or(i=0; i<r2->nF
3bc0: 69 65 6c 64 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  ield; i++){.    
3bd0: 20 20 69 66 28 20 72 32 2d 3e 61 4d 65 6d 5b 69    if( r2->aMem[i
3be0: 5d 2e 66 6c 61 67 73 20 26 20 4d 45 4d 5f 4e 75  ].flags & MEM_Nu
3bf0: 6c 6c 20 29 7b 0a 20 20 20 20 20 20 20 20 2a 70  ll ){.        *p
3c00: 52 65 73 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20  Res = -1;.      
3c10: 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20 20 20    return;.      
3c20: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 72 32 2d 3e  }.    }.    r2->
3c30: 66 6c 61 67 73 20 7c 3d 20 55 4e 50 41 43 4b 45  flags |= UNPACKE
3c40: 44 5f 50 52 45 46 49 58 5f 4d 41 54 43 48 3b 0a  D_PREFIX_MATCH;.
3c50: 20 20 7d 0a 0a 20 20 2a 70 52 65 73 20 3d 20 73    }..  *pRes = s
3c60: 71 6c 69 74 65 33 56 64 62 65 52 65 63 6f 72 64  qlite3VdbeRecord
3c70: 43 6f 6d 70 61 72 65 28 6e 4b 65 79 31 2c 20 70  Compare(nKey1, p
3c80: 4b 65 79 31 2c 20 72 32 29 3b 0a 7d 0a 0a 2f 2a  Key1, r2);.}../*
3c90: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
3ca0: 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 63  n is called to c
3cb0: 6f 6d 70 61 72 65 20 74 77 6f 20 69 74 65 72 61  ompare two itera
3cc0: 74 6f 72 20 6b 65 79 73 20 77 68 65 6e 20 6d 65  tor keys when me
3cd0: 72 67 69 6e 67 20 0a 2a 2a 20 6d 75 6c 74 69 70  rging .** multip
3ce0: 6c 65 20 62 2d 74 72 65 65 20 73 65 67 6d 65 6e  le b-tree segmen
3cf0: 74 73 2e 20 50 61 72 61 6d 65 74 65 72 20 69 4f  ts. Parameter iO
3d00: 75 74 20 69 73 20 74 68 65 20 69 6e 64 65 78 20  ut is the index 
3d10: 6f 66 20 74 68 65 20 61 54 72 65 65 5b 5d 20 0a  of the aTree[] .
3d20: 2a 2a 20 76 61 6c 75 65 20 74 6f 20 72 65 63 61  ** value to reca
3d30: 6c 63 75 6c 61 74 65 2e 0a 2a 2f 0a 73 74 61 74  lculate..*/.stat
3d40: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
3d50: 72 44 6f 43 6f 6d 70 61 72 65 28 56 64 62 65 53  rDoCompare(VdbeS
3d60: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 2c 20  orter *pSorter, 
3d70: 69 6e 74 20 69 4f 75 74 29 7b 0a 20 20 69 6e 74  int iOut){.  int
3d80: 20 69 31 3b 0a 20 20 69 6e 74 20 69 32 3b 0a 20   i1;.  int i2;. 
3d90: 20 69 6e 74 20 69 52 65 73 3b 0a 20 20 56 64 62   int iRes;.  Vdb
3da0: 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70 31 3b  eSorterIter *p1;
3db0: 0a 20 20 56 64 62 65 53 6f 72 74 65 72 49 74 65  .  VdbeSorterIte
3dc0: 72 20 2a 70 32 3b 0a 0a 20 20 61 73 73 65 72 74  r *p2;..  assert
3dd0: 28 20 69 4f 75 74 3c 70 53 6f 72 74 65 72 2d 3e  ( iOut<pSorter->
3de0: 6e 54 72 65 65 20 26 26 20 69 4f 75 74 3e 30 20  nTree && iOut>0 
3df0: 29 3b 0a 0a 20 20 69 66 28 20 69 4f 75 74 3e 3d  );..  if( iOut>=
3e00: 28 70 53 6f 72 74 65 72 2d 3e 6e 54 72 65 65 2f  (pSorter->nTree/
3e10: 32 29 20 29 7b 0a 20 20 20 20 69 31 20 3d 20 28  2) ){.    i1 = (
3e20: 69 4f 75 74 20 2d 20 70 53 6f 72 74 65 72 2d 3e  iOut - pSorter->
3e30: 6e 54 72 65 65 2f 32 29 20 2a 20 32 3b 0a 20 20  nTree/2) * 2;.  
3e40: 20 20 69 32 20 3d 20 69 31 20 2b 20 31 3b 0a 20    i2 = i1 + 1;. 
3e50: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 31 20 3d   }else{.    i1 =
3e60: 20 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b   pSorter->aTree[
3e70: 69 4f 75 74 2a 32 5d 3b 0a 20 20 20 20 69 32 20  iOut*2];.    i2 
3e80: 3d 20 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65  = pSorter->aTree
3e90: 5b 69 4f 75 74 2a 32 2b 31 5d 3b 0a 20 20 7d 0a  [iOut*2+1];.  }.
3ea0: 0a 20 20 70 31 20 3d 20 26 70 53 6f 72 74 65 72  .  p1 = &pSorter
3eb0: 2d 3e 61 49 74 65 72 5b 69 31 5d 3b 0a 20 20 70  ->aIter[i1];.  p
3ec0: 32 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 49  2 = &pSorter->aI
3ed0: 74 65 72 5b 69 32 5d 3b 0a 0a 20 20 69 66 28 20  ter[i2];..  if( 
3ee0: 70 31 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a  p1->pFile==0 ){.
3ef0: 20 20 20 20 69 52 65 73 20 3d 20 69 32 3b 0a 20      iRes = i2;. 
3f00: 20 7d 65 6c 73 65 20 69 66 28 20 70 32 2d 3e 70   }else if( p2->p
3f10: 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69  File==0 ){.    i
3f20: 52 65 73 20 3d 20 69 31 3b 0a 20 20 7d 65 6c 73  Res = i1;.  }els
3f30: 65 7b 0a 20 20 20 20 69 6e 74 20 72 65 73 3b 0a  e{.    int res;.
3f40: 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 43 6f      vdbeSorterCo
3f50: 6d 70 61 72 65 28 0a 20 20 20 20 20 20 20 20 70  mpare(.        p
3f60: 53 6f 72 74 65 72 2c 20 30 2c 20 70 31 2d 3e 61  Sorter, 0, p1->a
3f70: 4b 65 79 2c 20 70 31 2d 3e 6e 4b 65 79 2c 20 70  Key, p1->nKey, p
3f80: 32 2d 3e 61 4b 65 79 2c 20 70 32 2d 3e 6e 4b 65  2->aKey, p2->nKe
3f90: 79 2c 20 26 72 65 73 2c 0a 20 20 20 20 20 20 20  y, &res,.       
3fa0: 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63   pSorter->pUnpac
3fb0: 6b 65 64 0a 20 20 20 20 29 3b 0a 20 20 20 20 69  ked.    );.    i
3fc0: 66 28 20 72 65 73 3c 3d 30 20 29 7b 0a 20 20 20  f( res<=0 ){.   
3fd0: 20 20 20 69 52 65 73 20 3d 20 69 31 3b 0a 20 20     iRes = i1;.  
3fe0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69    }else{.      i
3ff0: 52 65 73 20 3d 20 69 32 3b 0a 20 20 20 20 7d 0a  Res = i2;.    }.
4000: 20 20 7d 0a 0a 20 20 70 53 6f 72 74 65 72 2d 3e    }..  pSorter->
4010: 61 54 72 65 65 5b 69 4f 75 74 5d 20 3d 20 69 52  aTree[iOut] = iR
4020: 65 73 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  es;.  return SQL
4030: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
4040: 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20   Initialize the 
4050: 74 65 6d 70 6f 72 61 72 79 20 69 6e 64 65 78 20  temporary index 
4060: 63 75 72 73 6f 72 20 6a 75 73 74 20 6f 70 65 6e  cursor just open
4070: 65 64 20 61 73 20 61 20 73 6f 72 74 65 72 20 63  ed as a sorter c
4080: 75 72 73 6f 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71  ursor..*/.int sq
4090: 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 49  lite3VdbeSorterI
40a0: 6e 69 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c  nit(sqlite3 *db,
40b0: 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73   VdbeCursor *pCs
40c0: 72 29 7b 0a 20 20 69 6e 74 20 70 67 73 7a 3b 20  r){.  int pgsz; 
40d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
40e0: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 73 69        /* Page si
40f0: 7a 65 20 6f 66 20 6d 61 69 6e 20 64 61 74 61 62  ze of main datab
4100: 61 73 65 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 43  ase */.  int mxC
4110: 61 63 68 65 3b 20 20 20 20 20 20 20 20 20 20 20  ache;           
4120: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61 63 68           /* Cach
4130: 65 20 73 69 7a 65 20 2a 2f 0a 20 20 56 64 62 65  e size */.  Vdbe
4140: 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 3b  Sorter *pSorter;
4150: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
4160: 68 65 20 6e 65 77 20 73 6f 72 74 65 72 20 2a 2f  he new sorter */
4170: 0a 20 20 63 68 61 72 20 2a 64 3b 20 20 20 20 20  .  char *d;     
4180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4190: 20 20 20 2f 2a 20 44 75 6d 6d 79 20 2a 2f 0a 20     /* Dummy */. 
41a0: 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20   int nByte;     
41b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
41c0: 20 2f 2a 20 42 79 74 65 73 20 69 6e 20 70 4b 65   /* Bytes in pKe
41d0: 79 49 6e 66 6f 20 2a 2f 0a 0a 20 20 61 73 73 65  yInfo */..  asse
41e0: 72 74 28 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e  rt( pCsr->pKeyIn
41f0: 66 6f 20 26 26 20 70 43 73 72 2d 3e 70 42 74 3d  fo && pCsr->pBt=
4200: 3d 30 20 29 3b 0a 20 20 70 43 73 72 2d 3e 70 53  =0 );.  pCsr->pS
4210: 6f 72 74 65 72 20 3d 20 70 53 6f 72 74 65 72 20  orter = pSorter 
4220: 3d 20 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f  = sqlite3DbMallo
4230: 63 5a 65 72 6f 28 64 62 2c 20 73 69 7a 65 6f 66  cZero(db, sizeof
4240: 28 56 64 62 65 53 6f 72 74 65 72 29 29 3b 0a 20  (VdbeSorter));. 
4250: 20 69 66 28 20 70 53 6f 72 74 65 72 3d 3d 30 20   if( pSorter==0 
4260: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
4270: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a  LITE_NOMEM;.  }.
4280: 20 20 70 53 6f 72 74 65 72 2d 3e 64 62 20 3d 20    pSorter->db = 
4290: 64 62 3b 0a 20 20 0a 20 20 70 53 6f 72 74 65 72  db;.  .  pSorter
42a0: 2d 3e 70 55 6e 70 61 63 6b 65 64 20 3d 20 73 71  ->pUnpacked = sq
42b0: 6c 69 74 65 33 56 64 62 65 41 6c 6c 6f 63 55 6e  lite3VdbeAllocUn
42c0: 70 61 63 6b 65 64 52 65 63 6f 72 64 28 70 43 73  packedRecord(pCs
42d0: 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20 30 2c 20  r->pKeyInfo, 0, 
42e0: 30 2c 20 26 64 29 3b 0a 20 20 69 66 28 20 70 53  0, &d);.  if( pS
42f0: 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64  orter->pUnpacked
4300: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
4310: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 61 73 73  ITE_NOMEM;.  ass
4320: 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 70 55  ert( pSorter->pU
4330: 6e 70 61 63 6b 65 64 3d 3d 28 55 6e 70 61 63 6b  npacked==(Unpack
4340: 65 64 52 65 63 6f 72 64 20 2a 29 64 20 29 3b 0a  edRecord *)d );.
4350: 0a 20 20 2f 2a 20 70 53 6f 72 74 65 72 2d 3e 70  .  /* pSorter->p
4360: 4b 65 79 49 6e 66 6f 20 69 73 20 61 20 63 6f 70  KeyInfo is a cop
4370: 79 20 6f 66 20 70 43 73 72 2d 3e 70 4b 65 79 49  y of pCsr->pKeyI
4380: 6e 66 6f 20 77 69 74 68 20 74 68 65 20 64 62 20  nfo with the db 
4390: 66 69 65 6c 64 20 73 65 74 20 74 6f 0a 20 20 2a  field set to.  *
43a0: 2a 20 7a 65 72 6f 2e 20 20 57 65 20 75 73 65 20  * zero.  We use 
43b0: 74 68 69 73 20 6d 6f 64 69 66 69 65 64 20 70 4b  this modified pK
43c0: 65 79 49 6e 66 6f 20 66 6f 72 20 73 6f 72 74 69  eyInfo for sorti
43d0: 6e 67 20 73 6f 20 74 68 61 74 20 6e 6f 20 6c 6f  ng so that no lo
43e0: 6f 6b 61 73 69 64 65 0a 20 20 2a 2a 20 6d 65 6d  okaside.  ** mem
43f0: 6f 72 79 20 77 69 6c 6c 20 62 65 20 75 73 65 64  ory will be used
4400: 2c 20 73 6f 20 74 68 61 74 20 73 6f 72 74 69 6e  , so that sortin
4410: 67 20 63 61 6e 20 70 72 6f 63 65 65 64 20 69 6e  g can proceed in
4420: 20 70 61 72 61 6c 6c 65 6c 20 69 6e 20 6d 75 6c   parallel in mul
4430: 74 69 70 6c 65 0a 20 20 2a 2a 20 74 68 72 65 61  tiple.  ** threa
4440: 64 73 2e 0a 20 20 2a 2f 0a 20 20 6e 42 79 74 65  ds..  */.  nByte
4450: 20 3d 20 73 69 7a 65 6f 66 28 4b 65 79 49 6e 66   = sizeof(KeyInf
4460: 6f 29 20 2b 20 28 70 43 73 72 2d 3e 70 4b 65 79  o) + (pCsr->pKey
4470: 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64 20 2d 20 31  Info->nField - 1
4480: 29 2a 73 69 7a 65 6f 66 28 43 6f 6c 6c 53 65 71  )*sizeof(CollSeq
4490: 2a 29 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 70  *);.  pSorter->p
44a0: 4b 65 79 49 6e 66 6f 20 3d 20 73 71 6c 69 74 65  KeyInfo = sqlite
44b0: 33 44 62 4d 61 6c 6c 6f 63 52 61 77 28 64 62 2c  3DbMallocRaw(db,
44c0: 20 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20 70   nByte);.  if( p
44d0: 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49 6e 66 6f  Sorter->pKeyInfo
44e0: 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72  ==0 ){.    retur
44f0: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
4500: 20 20 7d 0a 20 20 6d 65 6d 63 70 79 28 70 53 6f    }.  memcpy(pSo
4510: 72 74 65 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20  rter->pKeyInfo, 
4520: 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20  pCsr->pKeyInfo, 
4530: 6e 42 79 74 65 29 3b 0a 20 20 70 53 6f 72 74 65  nByte);.  pSorte
4540: 72 2d 3e 70 4b 65 79 49 6e 66 6f 2d 3e 64 62 20  r->pKeyInfo->db 
4550: 3d 20 30 3b 20 20 0a 0a 20 20 69 66 28 20 21 73  = 0;  ..  if( !s
4560: 71 6c 69 74 65 33 54 65 6d 70 49 6e 4d 65 6d 6f  qlite3TempInMemo
4570: 72 79 28 64 62 29 20 29 7b 0a 20 20 20 20 70 67  ry(db) ){.    pg
4580: 73 7a 20 3d 20 73 71 6c 69 74 65 33 42 74 72 65  sz = sqlite3Btre
4590: 65 47 65 74 50 61 67 65 53 69 7a 65 28 64 62 2d  eGetPageSize(db-
45a0: 3e 61 44 62 5b 30 5d 2e 70 42 74 29 3b 0a 20 20  >aDb[0].pBt);.  
45b0: 20 20 70 53 6f 72 74 65 72 2d 3e 6d 6e 50 6d 61    pSorter->mnPma
45c0: 53 69 7a 65 20 3d 20 53 4f 52 54 45 52 5f 4d 49  Size = SORTER_MI
45d0: 4e 5f 57 4f 52 4b 49 4e 47 20 2a 20 70 67 73 7a  N_WORKING * pgsz
45e0: 3b 0a 20 20 20 20 6d 78 43 61 63 68 65 20 3d 20  ;.    mxCache = 
45f0: 64 62 2d 3e 61 44 62 5b 30 5d 2e 70 53 63 68 65  db->aDb[0].pSche
4600: 6d 61 2d 3e 63 61 63 68 65 5f 73 69 7a 65 3b 0a  ma->cache_size;.
4610: 20 20 20 20 69 66 28 20 6d 78 43 61 63 68 65 3c      if( mxCache<
4620: 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49  SORTER_MIN_WORKI
4630: 4e 47 20 29 20 6d 78 43 61 63 68 65 20 3d 20 53  NG ) mxCache = S
4640: 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e  ORTER_MIN_WORKIN
4650: 47 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  G;.    pSorter->
4660: 6d 78 50 6d 61 53 69 7a 65 20 3d 20 6d 78 43 61  mxPmaSize = mxCa
4670: 63 68 65 20 2a 20 70 67 73 7a 3b 0a 20 20 7d 0a  che * pgsz;.  }.
4680: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
4690: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72  _OK;.}../*.** Fr
46a0: 65 65 20 74 68 65 20 6c 69 73 74 20 6f 66 20 73  ee the list of s
46b0: 6f 72 74 65 64 20 72 65 63 6f 72 64 73 20 73 74  orted records st
46c0: 61 72 74 69 6e 67 20 61 74 20 70 52 65 63 6f 72  arting at pRecor
46d0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
46e0: 64 20 76 64 62 65 53 6f 72 74 65 72 52 65 63 6f  d vdbeSorterReco
46f0: 72 64 46 72 65 65 28 73 71 6c 69 74 65 33 20 2a  rdFree(sqlite3 *
4700: 64 62 2c 20 53 6f 72 74 65 72 52 65 63 6f 72 64  db, SorterRecord
4710: 20 2a 70 52 65 63 6f 72 64 29 7b 0a 20 20 53 6f   *pRecord){.  So
4720: 72 74 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a 20  rterRecord *p;. 
4730: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
4740: 4e 65 78 74 3b 0a 20 20 66 6f 72 28 70 3d 70 52  Next;.  for(p=pR
4750: 65 63 6f 72 64 3b 20 70 3b 20 70 3d 70 4e 65 78  ecord; p; p=pNex
4760: 74 29 7b 0a 20 20 20 20 70 4e 65 78 74 20 3d 20  t){.    pNext = 
4770: 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 73 71  p->pNext;.    sq
4780: 6c 69 74 65 33 44 62 46 72 65 65 28 64 62 2c 20  lite3DbFree(db, 
4790: 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  p);.  }.}../*.**
47a0: 20 46 72 65 65 20 61 6e 79 20 63 75 72 73 6f 72   Free any cursor
47b0: 20 63 6f 6d 70 6f 6e 65 6e 74 73 20 61 6c 6c 6f   components allo
47c0: 63 61 74 65 64 20 62 79 20 73 71 6c 69 74 65 33  cated by sqlite3
47d0: 56 64 62 65 53 6f 72 74 65 72 58 58 58 20 72 6f  VdbeSorterXXX ro
47e0: 75 74 69 6e 65 73 2e 0a 2a 2f 0a 76 6f 69 64 20  utines..*/.void 
47f0: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
4800: 72 43 6c 6f 73 65 28 56 64 62 65 43 75 72 73 6f  rClose(VdbeCurso
4810: 72 20 2a 70 43 73 72 29 7b 0a 20 20 56 64 62 65  r *pCsr){.  Vdbe
4820: 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20  Sorter *pSorter 
4830: 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b  = pCsr->pSorter;
4840: 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72 20 29  .  if( pSorter )
4850: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 20 2a 64  {.    sqlite3 *d
4860: 62 20 3d 20 70 53 6f 72 74 65 72 2d 3e 64 62 3b  b = pSorter->db;
4870: 0a 20 20 20 20 69 66 28 20 70 53 6f 72 74 65 72  .    if( pSorter
4880: 2d 3e 61 49 74 65 72 20 29 7b 0a 20 20 20 20 20  ->aIter ){.     
4890: 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 66 6f   int i;.      fo
48a0: 72 28 69 3d 30 3b 20 69 3c 70 53 6f 72 74 65 72  r(i=0; i<pSorter
48b0: 2d 3e 6e 54 72 65 65 3b 20 69 2b 2b 29 7b 0a 20  ->nTree; i++){. 
48c0: 20 20 20 20 20 20 20 76 64 62 65 53 6f 72 74 65         vdbeSorte
48d0: 72 49 74 65 72 5a 65 72 6f 28 64 62 2c 20 26 70  rIterZero(db, &p
48e0: 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b 69 5d  Sorter->aIter[i]
48f0: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  );.      }.     
4900: 20 73 71 6c 69 74 65 33 44 62 46 72 65 65 28 64   sqlite3DbFree(d
4910: 62 2c 20 70 53 6f 72 74 65 72 2d 3e 61 49 74 65  b, pSorter->aIte
4920: 72 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  r);.    }.    if
4930: 28 20 70 53 6f 72 74 65 72 2d 3e 70 54 65 6d 70  ( pSorter->pTemp
4940: 31 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  1 ){.      sqlit
4950: 65 33 4f 73 43 6c 6f 73 65 46 72 65 65 28 70 53  e3OsCloseFree(pS
4960: 6f 72 74 65 72 2d 3e 70 54 65 6d 70 31 29 3b 0a  orter->pTemp1);.
4970: 20 20 20 20 7d 0a 20 20 20 20 76 64 62 65 53 6f      }.    vdbeSo
4980: 72 74 65 72 52 65 63 6f 72 64 46 72 65 65 28 64  rterRecordFree(d
4990: 62 2c 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63  b, pSorter->pRec
49a0: 6f 72 64 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  ord);.    sqlite
49b0: 33 44 62 46 72 65 65 28 64 62 2c 20 70 53 6f 72  3DbFree(db, pSor
49c0: 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64 29 3b  ter->pUnpacked);
49d0: 0a 20 20 20 20 73 71 6c 69 74 65 33 44 62 46 72  .    sqlite3DbFr
49e0: 65 65 28 64 62 2c 20 70 53 6f 72 74 65 72 2d 3e  ee(db, pSorter->
49f0: 70 4b 65 79 49 6e 66 6f 29 3b 0a 20 20 20 20 73  pKeyInfo);.    s
4a00: 71 6c 69 74 65 33 44 62 46 72 65 65 28 64 62 2c  qlite3DbFree(db,
4a10: 20 70 53 6f 72 74 65 72 29 3b 0a 20 20 20 20 70   pSorter);.    p
4a20: 43 73 72 2d 3e 70 53 6f 72 74 65 72 20 3d 20 30  Csr->pSorter = 0
4a30: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  ;.  }.}../*.** A
4a40: 6c 6c 6f 63 61 74 65 20 73 70 61 63 65 20 66 6f  llocate space fo
4a50: 72 20 61 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20  r a file-handle 
4a60: 61 6e 64 20 6f 70 65 6e 20 61 20 74 65 6d 70 6f  and open a tempo
4a70: 72 61 72 79 20 66 69 6c 65 2e 20 49 66 20 73 75  rary file. If su
4a80: 63 63 65 73 73 66 75 6c 2c 0a 2a 2a 20 73 65 74  ccessful,.** set
4a90: 20 2a 70 70 46 69 6c 65 20 74 6f 20 70 6f 69 6e   *ppFile to poin
4aa0: 74 20 74 6f 20 74 68 65 20 6d 61 6c 6c 6f 63 27  t to the malloc'
4ab0: 64 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20 61 6e  d file-handle an
4ac0: 64 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  d return SQLITE_
4ad0: 4f 4b 2e 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65  OK..** Otherwise
4ae0: 2c 20 73 65 74 20 2a 70 70 46 69 6c 65 20 74 6f  , set *ppFile to
4af0: 20 30 20 61 6e 64 20 72 65 74 75 72 6e 20 61 6e   0 and return an
4b00: 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
4b10: 64 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  de..*/.static in
4b20: 74 20 76 64 62 65 53 6f 72 74 65 72 4f 70 65 6e  t vdbeSorterOpen
4b30: 54 65 6d 70 46 69 6c 65 28 73 71 6c 69 74 65 33  TempFile(sqlite3
4b40: 20 2a 64 62 2c 20 73 71 6c 69 74 65 33 5f 66 69   *db, sqlite3_fi
4b50: 6c 65 20 2a 2a 70 70 46 69 6c 65 29 7b 0a 20 20  le **ppFile){.  
4b60: 69 6e 74 20 64 75 6d 6d 79 3b 0a 20 20 72 65 74  int dummy;.  ret
4b70: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 4f 70 65  urn sqlite3OsOpe
4b80: 6e 4d 61 6c 6c 6f 63 28 64 62 2d 3e 70 56 66 73  nMalloc(db->pVfs
4b90: 2c 20 30 2c 20 70 70 46 69 6c 65 2c 0a 20 20 20  , 0, ppFile,.   
4ba0: 20 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 54     SQLITE_OPEN_T
4bb0: 45 4d 50 5f 4a 4f 55 52 4e 41 4c 20 7c 0a 20 20  EMP_JOURNAL |.  
4bc0: 20 20 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f      SQLITE_OPEN_
4bd0: 52 45 41 44 57 52 49 54 45 20 20 20 20 7c 20 53  READWRITE    | S
4be0: 51 4c 49 54 45 5f 4f 50 45 4e 5f 43 52 45 41 54  QLITE_OPEN_CREAT
4bf0: 45 20 7c 0a 20 20 20 20 20 20 53 51 4c 49 54 45  E |.      SQLITE
4c00: 5f 4f 50 45 4e 5f 45 58 43 4c 55 53 49 56 45 20  _OPEN_EXCLUSIVE 
4c10: 20 20 20 7c 20 53 51 4c 49 54 45 5f 4f 50 45 4e     | SQLITE_OPEN
4c20: 5f 44 45 4c 45 54 45 4f 4e 43 4c 4f 53 45 2c 20  _DELETEONCLOSE, 
4c30: 26 64 75 6d 6d 79 0a 20 20 29 3b 0a 7d 0a 0a 2f  &dummy.  );.}../
4c40: 2a 0a 2a 2a 20 4d 65 72 67 65 20 74 68 65 20 74  *.** Merge the t
4c50: 77 6f 20 73 6f 72 74 65 64 20 6c 69 73 74 73 20  wo sorted lists 
4c60: 70 31 20 61 6e 64 20 70 32 20 69 6e 74 6f 20 61  p1 and p2 into a
4c70: 20 73 69 6e 67 6c 65 20 6c 69 73 74 2e 0a 2a 2a   single list..**
4c80: 20 53 65 74 20 2a 70 70 4f 75 74 20 74 6f 20 74   Set *ppOut to t
4c90: 68 65 20 68 65 61 64 20 6f 66 20 74 68 65 20 6e  he head of the n
4ca0: 65 77 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61 74  ew list..*/.stat
4cb0: 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74  ic void vdbeSort
4cc0: 65 72 4d 65 72 67 65 28 0a 20 20 56 64 62 65 53  erMerge(.  VdbeS
4cd0: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 2c 20  orter *pSorter, 
4ce0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
4cf0: 65 20 73 6f 72 74 65 72 20 6f 62 6a 65 63 74 20  e sorter object 
4d00: 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72  */.  SorterRecor
4d10: 64 20 2a 70 31 2c 20 20 20 20 20 20 20 20 20 20  d *p1,          
4d20: 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 6c 69       /* First li
4d30: 73 74 20 74 6f 20 6d 65 72 67 65 20 2a 2f 0a 20  st to merge */. 
4d40: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
4d50: 32 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  2,              
4d60: 20 2f 2a 20 53 65 63 6f 6e 64 20 6c 69 73 74 20   /* Second list 
4d70: 74 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20 53 6f  to merge */.  So
4d80: 72 74 65 72 52 65 63 6f 72 64 20 2a 2a 70 70 4f  rterRecord **ppO
4d90: 75 74 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ut,           /*
4da0: 20 4f 55 54 3a 20 48 65 61 64 20 6f 66 20 6d 65   OUT: Head of me
4db0: 72 67 65 64 20 6c 69 73 74 20 2a 2f 0a 20 20 55  rged list */.  U
4dc0: 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20 2a 70  npackedRecord *p
4dd0: 55 6e 70 61 63 6b 65 64 20 20 20 20 20 20 20 2f  Unpacked       /
4de0: 2a 20 53 70 61 63 65 20 74 6f 20 68 6f 6c 64 20  * Space to hold 
4df0: 61 6e 20 75 6e 70 61 63 6b 65 64 20 72 65 63 6f  an unpacked reco
4e00: 72 64 20 2a 2f 0a 29 7b 0a 20 20 53 6f 72 74 65  rd */.){.  Sorte
4e10: 72 52 65 63 6f 72 64 20 2a 70 46 69 6e 61 6c 20  rRecord *pFinal 
4e20: 3d 20 30 3b 0a 20 20 53 6f 72 74 65 72 52 65 63  = 0;.  SorterRec
4e30: 6f 72 64 20 2a 2a 70 70 20 3d 20 26 70 46 69 6e  ord **pp = &pFin
4e40: 61 6c 3b 0a 20 20 76 6f 69 64 20 2a 70 56 61 6c  al;.  void *pVal
4e50: 32 20 3d 20 70 32 20 3f 20 70 32 2d 3e 70 56 61  2 = p2 ? p2->pVa
4e60: 6c 20 3a 20 30 3b 0a 0a 20 20 77 68 69 6c 65 28  l : 0;..  while(
4e70: 20 70 31 20 26 26 20 70 32 20 29 7b 0a 20 20 20   p1 && p2 ){.   
4e80: 20 69 6e 74 20 72 65 73 3b 0a 20 20 20 20 76 64   int res;.    vd
4e90: 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28  beSorterCompare(
4ea0: 70 53 6f 72 74 65 72 2c 20 30 2c 20 70 31 2d 3e  pSorter, 0, p1->
4eb0: 70 56 61 6c 2c 20 70 31 2d 3e 6e 56 61 6c 2c 20  pVal, p1->nVal, 
4ec0: 70 56 61 6c 32 2c 20 70 32 2d 3e 6e 56 61 6c 2c  pVal2, p2->nVal,
4ed0: 20 26 72 65 73 2c 0a 20 20 20 20 20 20 20 20 20   &res,.         
4ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 55 6e               pUn
4ef0: 70 61 63 6b 65 64 29 3b 0a 20 20 20 20 69 66 28  packed);.    if(
4f00: 20 72 65 73 3c 3d 30 20 29 7b 0a 20 20 20 20 20   res<=0 ){.     
4f10: 20 2a 70 70 20 3d 20 70 31 3b 0a 20 20 20 20 20   *pp = p1;.     
4f20: 20 70 70 20 3d 20 26 70 31 2d 3e 70 4e 65 78 74   pp = &p1->pNext
4f30: 3b 0a 20 20 20 20 20 20 70 31 20 3d 20 70 31 2d  ;.      p1 = p1-
4f40: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 56  >pNext;.      pV
4f50: 61 6c 32 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c  al2 = 0;.    }el
4f60: 73 65 7b 0a 20 20 20 20 20 20 2a 70 70 20 3d 20  se{.      *pp = 
4f70: 70 32 3b 0a 20 20 20 20 20 20 20 70 70 20 3d 20  p2;.       pp = 
4f80: 26 70 32 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  &p2->pNext;.    
4f90: 20 20 70 32 20 3d 20 70 32 2d 3e 70 4e 65 78 74    p2 = p2->pNext
4fa0: 3b 0a 20 20 20 20 20 20 69 66 28 20 70 32 3d 3d  ;.      if( p2==
4fb0: 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  0 ) break;.     
4fc0: 20 70 56 61 6c 32 20 3d 20 70 32 2d 3e 70 56 61   pVal2 = p2->pVa
4fd0: 6c 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a  l;.    }.  }.  *
4fe0: 70 70 20 3d 20 70 31 20 3f 20 70 31 20 3a 20 70  pp = p1 ? p1 : p
4ff0: 32 3b 0a 20 20 2a 70 70 4f 75 74 20 3d 20 70 46  2;.  *ppOut = pF
5000: 69 6e 61 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 42  inal;.}../*.** B
5010: 61 63 6b 67 72 6f 75 6e 64 20 73 6f 72 74 69 6e  ackground sortin
5020: 67 20 74 61 73 6b 0a 2a 2f 0a 74 79 70 65 64 65  g task.*/.typede
5030: 66 20 73 74 72 75 63 74 20 53 6f 72 74 54 61 73  f struct SortTas
5040: 6b 20 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72  k {.  VdbeSorter
5050: 20 2a 70 53 6f 72 74 65 72 3b 20 20 20 20 20 20   *pSorter;      
5060: 20 20 20 20 2f 2a 20 54 68 65 20 73 6f 72 74 65      /* The sorte
5070: 72 20 66 6f 72 20 77 68 69 63 68 20 74 68 69 73  r for which this
5080: 20 74 61 73 6b 20 77 6f 72 6b 73 20 2a 2f 0a 20   task works */. 
5090: 20 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 20   UnpackedRecord 
50a0: 2a 70 55 6e 70 61 63 6b 65 64 3b 20 20 20 20 2f  *pUnpacked;    /
50b0: 2a 20 53 70 61 63 65 20 74 6f 20 68 6f 6c 64 20  * Space to hold 
50c0: 61 6e 20 75 6e 70 61 63 6b 65 64 20 6b 65 79 20  an unpacked key 
50d0: 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72  */.  SorterRecor
50e0: 64 20 2a 70 4c 69 73 74 3b 20 20 20 20 20 20 20  d *pList;       
50f0: 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20 65 6c     /* List of el
5100: 65 6d 65 6e 74 73 20 74 6f 20 62 65 20 73 6f 72  ements to be sor
5110: 74 65 64 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52  ted */.  SorterR
5120: 65 63 6f 72 64 20 2a 2a 61 70 53 6c 6f 74 3b 20  ecord **apSlot; 
5130: 20 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 20 6d         /* Temp m
5140: 65 6d 6f 72 79 20 66 6f 72 20 74 68 65 20 6d 65  emory for the me
5150: 72 67 65 20 73 6f 72 74 20 2a 2f 0a 7d 20 53 6f  rge sort */.} So
5160: 72 74 54 61 73 6b 3b 0a 0a 2f 2a 0a 2a 2a 20 44  rtTask;../*.** D
5170: 6f 20 61 20 73 6f 72 74 20 69 6e 20 61 20 62 61  o a sort in a ba
5180: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 0a  ckground thread.
5190: 2a 2f 0a 76 6f 69 64 20 2a 76 64 62 65 53 6f 72  */.void *vdbeSor
51a0: 74 65 72 42 61 63 6b 67 72 6f 75 6e 64 53 6f 72  terBackgroundSor
51b0: 74 28 53 6f 72 74 54 61 73 6b 20 2a 70 54 61 73  t(SortTask *pTas
51c0: 6b 29 7b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f  k){.  SorterReco
51d0: 72 64 20 2a 70 20 3d 20 70 54 61 73 6b 2d 3e 70  rd *p = pTask->p
51e0: 4c 69 73 74 3b 0a 20 20 53 6f 72 74 65 72 52 65  List;.  SorterRe
51f0: 63 6f 72 64 20 2a 2a 61 20 3d 20 70 54 61 73 6b  cord **a = pTask
5200: 2d 3e 61 70 53 6c 6f 74 3b 0a 20 20 69 6e 74 20  ->apSlot;.  int 
5210: 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  i;.  for(i=0; i<
5220: 36 34 3b 20 69 2b 2b 29 20 61 5b 69 5d 20 3d 20  64; i++) a[i] = 
5230: 30 3b 0a 20 20 77 68 69 6c 65 28 20 70 20 29 7b  0;.  while( p ){
5240: 0a 20 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72  .    SorterRecor
5250: 64 20 2a 70 4e 65 78 74 20 3d 20 70 2d 3e 70 4e  d *pNext = p->pN
5260: 65 78 74 3b 0a 20 20 20 20 70 2d 3e 70 4e 65 78  ext;.    p->pNex
5270: 74 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28 69  t = 0;.    for(i
5280: 3d 30 3b 20 61 5b 69 5d 3b 20 69 2b 2b 29 7b 0a  =0; a[i]; i++){.
5290: 20 20 20 20 20 20 69 66 28 20 61 5b 69 5d 3d 3d        if( a[i]==
52a0: 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  0 ) break;.     
52b0: 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65   vdbeSorterMerge
52c0: 28 70 54 61 73 6b 2d 3e 70 53 6f 72 74 65 72 2c  (pTask->pSorter,
52d0: 20 61 5b 69 5d 2c 20 70 2c 20 26 70 2c 20 70 54   a[i], p, &p, pT
52e0: 61 73 6b 2d 3e 70 55 6e 70 61 63 6b 65 64 29 3b  ask->pUnpacked);
52f0: 0a 20 20 20 20 20 20 61 5b 69 5d 20 3d 20 30 3b  .      a[i] = 0;
5300: 0a 20 20 20 20 7d 0a 20 20 20 20 61 5b 69 5d 20  .    }.    a[i] 
5310: 3d 20 70 3b 0a 20 20 20 20 70 20 3d 20 70 4e 65  = p;.    p = pNe
5320: 78 74 3b 0a 20 20 7d 0a 20 20 70 20 3d 20 30 3b  xt;.  }.  p = 0;
5330: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 36 34  .  for(i=0; i<64
5340: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 76 64 62 65  ; i++){.    vdbe
5350: 53 6f 72 74 65 72 4d 65 72 67 65 28 70 54 61 73  SorterMerge(pTas
5360: 6b 2d 3e 70 53 6f 72 74 65 72 2c 20 61 5b 69 5d  k->pSorter, a[i]
5370: 2c 20 70 2c 20 26 70 2c 20 70 54 61 73 6b 2d 3e  , p, &p, pTask->
5380: 70 55 6e 70 61 63 6b 65 64 29 3b 0a 20 20 7d 0a  pUnpacked);.  }.
5390: 20 20 70 54 61 73 6b 2d 3e 70 4c 69 73 74 20 3d    pTask->pList =
53a0: 20 70 3b 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a   p;.  return p;.
53b0: 7d 0a 0a 2f 2a 0a 2a 2a 20 44 69 76 69 64 65 20  }../*.** Divide 
53c0: 61 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66  a linked list of
53d0: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 6f 62   SorterRecord ob
53e0: 6a 65 63 74 73 20 69 6e 74 6f 20 74 77 6f 20 73  jects into two s
53f0: 65 70 61 72 61 74 65 0a 2a 2a 20 6c 69 6e 6b 65  eparate.** linke
5400: 64 20 6c 69 73 74 73 0a 2a 2f 0a 73 74 61 74 69  d lists.*/.stati
5410: 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65  c void vdbeSorte
5420: 72 44 69 76 69 64 65 4c 69 73 74 28 0a 20 20 53  rDivideList(.  S
5430: 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 49 6e  orterRecord *pIn
5440: 2c 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6c  ,       /* The l
5450: 69 73 74 20 74 6f 20 62 65 20 64 69 76 69 64 65  ist to be divide
5460: 64 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63  d */.  SorterRec
5470: 6f 72 64 20 2a 2a 70 70 4f 75 74 31 2c 20 20 20  ord **ppOut1,   
5480: 2f 2a 20 57 72 69 74 65 20 74 68 65 20 66 69 72  /* Write the fir
5490: 73 74 20 6c 69 73 74 20 68 65 72 65 20 2a 2f 0a  st list here */.
54a0: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
54b0: 2a 70 70 4f 75 74 32 20 20 20 20 2f 2a 20 57 72  *ppOut2    /* Wr
54c0: 69 74 65 20 74 68 65 20 73 65 63 6f 6e 64 20 6c  ite the second l
54d0: 69 73 74 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20  ist here */.){. 
54e0: 20 69 6e 74 20 69 20 3d 20 30 3b 0a 20 20 2a 70   int i = 0;.  *p
54f0: 70 4f 75 74 31 20 3d 20 2a 70 70 4f 75 74 32 20  pOut1 = *ppOut2 
5500: 3d 20 30 3b 0a 20 20 77 68 69 6c 65 28 20 70 49  = 0;.  while( pI
5510: 6e 20 29 7b 0a 20 20 20 20 53 6f 72 74 65 72 52  n ){.    SorterR
5520: 65 63 6f 72 64 20 2a 70 4e 65 78 74 20 3d 20 70  ecord *pNext = p
5530: 49 6e 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 70  In->pNext;.    p
5540: 49 6e 2d 3e 70 4e 65 78 74 20 3d 20 30 3b 0a 20  In->pNext = 0;. 
5550: 20 20 20 69 66 28 20 69 20 26 20 31 20 29 7b 0a     if( i & 1 ){.
5560: 20 20 20 20 20 20 2a 70 70 4f 75 74 31 20 3d 20        *ppOut1 = 
5570: 70 49 6e 3b 0a 20 20 20 20 20 20 70 70 4f 75 74  pIn;.      ppOut
5580: 31 20 3d 20 26 70 49 6e 2d 3e 70 4e 65 78 74 3b  1 = &pIn->pNext;
5590: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
55a0: 20 20 2a 70 70 4f 75 74 32 20 3d 20 70 49 6e 3b    *ppOut2 = pIn;
55b0: 0a 20 20 20 20 20 20 70 70 4f 75 74 32 20 3d 20  .      ppOut2 = 
55c0: 26 70 49 6e 2d 3e 70 4e 65 78 74 3b 0a 20 20 20  &pIn->pNext;.   
55d0: 20 7d 0a 20 20 20 20 69 2b 2b 3b 0a 20 20 20 20   }.    i++;.    
55e0: 70 49 6e 20 3d 20 70 4e 65 78 74 3b 0a 20 20 7d  pIn = pNext;.  }
55f0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74  .}../*.** Sort t
5600: 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f  he linked list o
5610: 66 20 72 65 63 6f 72 64 73 20 68 65 61 64 65 64  f records headed
5620: 20 61 74 20 70 43 73 72 2d 3e 70 52 65 63 6f 72   at pCsr->pRecor
5630: 64 2e 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45  d. Return SQLITE
5640: 5f 4f 4b 0a 2a 2a 20 69 66 20 73 75 63 63 65 73  _OK.** if succes
5650: 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69  sful, or an SQLi
5660: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 28 69  te error code (i
5670: 2e 65 2e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  .e. SQLITE_NOMEM
5680: 29 20 69 66 20 61 6e 20 65 72 72 6f 72 0a 2a 2a  ) if an error.**
5690: 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74   occurs..*/.stat
56a0: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
56b0: 72 53 6f 72 74 28 56 64 62 65 53 6f 72 74 65 72  rSort(VdbeSorter
56c0: 20 2a 70 53 6f 72 74 65 72 29 7b 0a 20 20 69 6e   *pSorter){.  in
56d0: 74 20 72 63 3b 0a 20 20 63 68 61 72 20 2a 70 44  t rc;.  char *pD
56e0: 75 6d 6d 79 20 3d 20 30 3b 0a 20 20 69 6e 74 20  ummy = 0;.  int 
56f0: 6e 42 79 74 65 41 2c 20 6e 42 79 74 65 42 3b 0a  nByteA, nByteB;.
5700: 20 20 53 6f 72 74 54 61 73 6b 20 61 54 61 73 6b    SortTask aTask
5710: 5b 32 5d 3b 0a 20 20 53 51 4c 69 74 65 54 68 72  [2];.  SQLiteThr
5720: 65 61 64 20 2a 70 54 68 72 65 61 64 3b 0a 0a 20  ead *pThread;.. 
5730: 20 6e 42 79 74 65 41 20 3d 20 36 34 2a 73 69 7a   nByteA = 64*siz
5740: 65 6f 66 28 53 6f 72 74 65 72 52 65 63 6f 72 64  eof(SorterRecord
5750: 2a 29 3b 0a 20 20 6e 42 79 74 65 42 20 3d 20 52  *);.  nByteB = R
5760: 4f 55 4e 44 38 28 73 69 7a 65 6f 66 28 55 6e 70  OUND8(sizeof(Unp
5770: 61 63 6b 65 64 52 65 63 6f 72 64 29 29 3b 0a 20  ackedRecord));. 
5780: 20 6e 42 79 74 65 42 20 2b 3d 20 73 69 7a 65 6f   nByteB += sizeo
5790: 66 28 4d 65 6d 29 2a 28 70 53 6f 72 74 65 72 2d  f(Mem)*(pSorter-
57a0: 3e 70 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c  >pKeyInfo->nFiel
57b0: 64 2b 31 29 3b 0a 0a 20 20 61 54 61 73 6b 5b 30  d+1);..  aTask[0
57c0: 5d 2e 61 70 53 6c 6f 74 20 3d 20 28 53 6f 72 74  ].apSlot = (Sort
57d0: 65 72 52 65 63 6f 72 64 20 2a 2a 29 73 71 6c 69  erRecord **)sqli
57e0: 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 32 2a  te3MallocZero(2*
57f0: 28 6e 42 79 74 65 41 20 2b 20 6e 42 79 74 65 42  (nByteA + nByteB
5800: 29 29 3b 0a 20 20 69 66 28 20 21 61 54 61 73 6b  ));.  if( !aTask
5810: 5b 30 5d 2e 61 70 53 6c 6f 74 20 29 7b 0a 20 20  [0].apSlot ){.  
5820: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
5830: 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 61 54 61  NOMEM;.  }.  aTa
5840: 73 6b 5b 30 5d 2e 70 53 6f 72 74 65 72 20 3d 20  sk[0].pSorter = 
5850: 70 53 6f 72 74 65 72 3b 0a 20 20 61 54 61 73 6b  pSorter;.  aTask
5860: 5b 30 5d 2e 70 55 6e 70 61 63 6b 65 64 20 3d 20  [0].pUnpacked = 
5870: 73 71 6c 69 74 65 33 56 64 62 65 41 6c 6c 6f 63  sqlite3VdbeAlloc
5880: 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 28 70  UnpackedRecord(p
5890: 53 6f 72 74 65 72 2d 3e 70 4b 65 79 49 6e 66 6f  Sorter->pKeyInfo
58a0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
58b0: 20 20 20 20 20 20 20 20 20 20 20 20 28 63 68 61              (cha
58c0: 72 2a 29 26 61 54 61 73 6b 5b 30 5d 2e 61 70 53  r*)&aTask[0].apS
58d0: 6c 6f 74 5b 36 34 5d 2c 20 6e 42 79 74 65 42 2c  lot[64], nByteB,
58e0: 20 26 70 44 75 6d 6d 79 29 3b 0a 20 20 61 73 73   &pDummy);.  ass
58f0: 65 72 74 28 20 70 44 75 6d 6d 79 3d 3d 30 20 29  ert( pDummy==0 )
5900: 3b 0a 20 20 61 54 61 73 6b 5b 31 5d 2e 61 70 53  ;.  aTask[1].apS
5910: 6c 6f 74 20 3d 20 28 53 6f 72 74 65 72 52 65 63  lot = (SorterRec
5920: 6f 72 64 2a 2a 29 28 28 6e 42 79 74 65 41 2b 6e  ord**)((nByteA+n
5930: 42 79 74 65 42 29 2b 28 63 68 61 72 2a 29 61 54  ByteB)+(char*)aT
5940: 61 73 6b 5b 30 5d 2e 61 70 53 6c 6f 74 29 3b 0a  ask[0].apSlot);.
5950: 20 20 61 54 61 73 6b 5b 31 5d 2e 70 53 6f 72 74    aTask[1].pSort
5960: 65 72 20 3d 20 70 53 6f 72 74 65 72 3b 0a 20 20  er = pSorter;.  
5970: 61 54 61 73 6b 5b 31 5d 2e 70 55 6e 70 61 63 6b  aTask[1].pUnpack
5980: 65 64 20 3d 20 73 71 6c 69 74 65 33 56 64 62 65  ed = sqlite3Vdbe
5990: 41 6c 6c 6f 63 55 6e 70 61 63 6b 65 64 52 65 63  AllocUnpackedRec
59a0: 6f 72 64 28 70 53 6f 72 74 65 72 2d 3e 70 4b 65  ord(pSorter->pKe
59b0: 79 49 6e 66 6f 2c 0a 20 20 20 20 20 20 20 20 20  yInfo,.         
59c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
59d0: 20 28 63 68 61 72 2a 29 26 61 54 61 73 6b 5b 31   (char*)&aTask[1
59e0: 5d 2e 61 70 53 6c 6f 74 5b 36 34 5d 2c 20 6e 42  ].apSlot[64], nB
59f0: 79 74 65 42 2c 20 26 70 44 75 6d 6d 79 29 3b 0a  yteB, &pDummy);.
5a00: 20 20 61 73 73 65 72 74 28 20 70 44 75 6d 6d 79    assert( pDummy
5a10: 3d 3d 30 20 29 3b 0a 0a 20 20 76 64 62 65 53 6f  ==0 );..  vdbeSo
5a20: 72 74 65 72 44 69 76 69 64 65 4c 69 73 74 28 70  rterDivideList(p
5a30: 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 2c  Sorter->pRecord,
5a40: 20 26 61 54 61 73 6b 5b 30 5d 2e 70 4c 69 73 74   &aTask[0].pList
5a50: 2c 20 26 61 54 61 73 6b 5b 31 5d 2e 70 4c 69 73  , &aTask[1].pLis
5a60: 74 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  t);.  rc = sqlit
5a70: 65 33 54 68 72 65 61 64 43 72 65 61 74 65 28 26  e3ThreadCreate(&
5a80: 70 54 68 72 65 61 64 2c 20 0a 20 20 20 20 20 20  pThread, .      
5a90: 20 20 20 20 28 76 6f 69 64 2a 28 2a 29 28 76 6f      (void*(*)(vo
5aa0: 69 64 2a 29 29 76 64 62 65 53 6f 72 74 65 72 42  id*))vdbeSorterB
5ab0: 61 63 6b 67 72 6f 75 6e 64 53 6f 72 74 2c 20 26  ackgroundSort, &
5ac0: 61 54 61 73 6b 5b 30 5d 29 3b 0a 20 20 76 64 62  aTask[0]);.  vdb
5ad0: 65 53 6f 72 74 65 72 42 61 63 6b 67 72 6f 75 6e  eSorterBackgroun
5ae0: 64 53 6f 72 74 28 26 61 54 61 73 6b 5b 31 5d 29  dSort(&aTask[1])
5af0: 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
5b00: 54 45 5f 4e 4f 4d 45 4d 20 29 7b 0a 20 20 20 20  TE_NOMEM ){.    
5b10: 76 64 62 65 53 6f 72 74 65 72 42 61 63 6b 67 72  vdbeSorterBackgr
5b20: 6f 75 6e 64 53 6f 72 74 28 26 61 54 61 73 6b 5b  oundSort(&aTask[
5b30: 30 5d 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  0]);.  }else{.  
5b40: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 54 68    rc = sqlite3Th
5b50: 72 65 61 64 4a 6f 69 6e 28 70 54 68 72 65 61 64  readJoin(pThread
5b60: 2c 20 28 76 6f 69 64 2a 2a 29 26 70 44 75 6d 6d  , (void**)&pDumm
5b70: 79 29 3b 0a 20 20 7d 0a 20 20 76 64 62 65 53 6f  y);.  }.  vdbeSo
5b80: 72 74 65 72 4d 65 72 67 65 28 70 53 6f 72 74 65  rterMerge(pSorte
5b90: 72 2c 20 61 54 61 73 6b 5b 30 5d 2e 70 4c 69 73  r, aTask[0].pLis
5ba0: 74 2c 20 61 54 61 73 6b 5b 31 5d 2e 70 4c 69 73  t, aTask[1].pLis
5bb0: 74 2c 20 26 70 53 6f 72 74 65 72 2d 3e 70 52 65  t, &pSorter->pRe
5bc0: 63 6f 72 64 2c 0a 20 20 20 20 20 20 20 20 20 20  cord,.          
5bd0: 20 20 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d          pSorter-
5be0: 3e 70 55 6e 70 61 63 6b 65 64 29 3b 0a 20 20 73  >pUnpacked);.  s
5bf0: 71 6c 69 74 65 33 5f 66 72 65 65 28 61 54 61 73  qlite3_free(aTas
5c00: 6b 5b 30 5d 2e 61 70 53 6c 6f 74 29 3b 0a 20 20  k[0].apSlot);.  
5c10: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
5c20: 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61  .** Initialize a
5c30: 20 66 69 6c 65 2d 77 72 69 74 65 72 20 6f 62 6a   file-writer obj
5c40: 65 63 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ect..*/.static v
5c50: 6f 69 64 20 66 69 6c 65 57 72 69 74 65 72 49 6e  oid fileWriterIn
5c60: 69 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  it(.  sqlite3 *d
5c70: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b,              
5c80: 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
5c90: 65 20 28 66 6f 72 20 6d 61 6c 6c 6f 63 29 20 2a  e (for malloc) *
5ca0: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  /.  sqlite3_file
5cb0: 20 2a 70 46 69 6c 65 2c 20 20 20 20 20 20 20 20   *pFile,        
5cc0: 20 20 20 20 2f 2a 20 46 69 6c 65 20 74 6f 20 77      /* File to w
5cd0: 72 69 74 65 20 74 6f 20 2a 2f 0a 20 20 46 69 6c  rite to */.  Fil
5ce0: 65 57 72 69 74 65 72 20 2a 70 2c 20 20 20 20 20  eWriter *p,     
5cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5d00: 4f 62 6a 65 63 74 20 74 6f 20 70 6f 70 75 6c 61  Object to popula
5d10: 74 65 20 2a 2f 0a 20 20 69 36 34 20 69 53 74 61  te */.  i64 iSta
5d20: 72 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20  rt              
5d30: 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65          /* Offse
5d40: 74 20 6f 66 20 70 46 69 6c 65 20 74 6f 20 62 65  t of pFile to be
5d50: 67 69 6e 20 77 72 69 74 69 6e 67 20 61 74 20 2a  gin writing at *
5d60: 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e 42 75 66 20  /.){.  int nBuf 
5d70: 3d 20 73 71 6c 69 74 65 33 42 74 72 65 65 47 65  = sqlite3BtreeGe
5d80: 74 50 61 67 65 53 69 7a 65 28 64 62 2d 3e 61 44  tPageSize(db->aD
5d90: 62 5b 30 5d 2e 70 42 74 29 3b 0a 0a 20 20 6d 65  b[0].pBt);..  me
5da0: 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f  mset(p, 0, sizeo
5db0: 66 28 46 69 6c 65 57 72 69 74 65 72 29 29 3b 0a  f(FileWriter));.
5dc0: 20 20 70 2d 3e 61 42 75 66 66 65 72 20 3d 20 28    p->aBuffer = (
5dd0: 75 38 20 2a 29 73 71 6c 69 74 65 33 44 62 4d 61  u8 *)sqlite3DbMa
5de0: 6c 6c 6f 63 52 61 77 28 64 62 2c 20 6e 42 75 66  llocRaw(db, nBuf
5df0: 29 3b 0a 20 20 69 66 28 20 21 70 2d 3e 61 42 75  );.  if( !p->aBu
5e00: 66 66 65 72 20 29 7b 0a 20 20 20 20 70 2d 3e 65  ffer ){.    p->e
5e10: 46 57 45 72 72 20 3d 20 53 51 4c 49 54 45 5f 4e  FWErr = SQLITE_N
5e20: 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  OMEM;.  }else{. 
5e30: 20 20 20 70 2d 3e 69 42 75 66 45 6e 64 20 3d 20     p->iBufEnd = 
5e40: 70 2d 3e 69 42 75 66 53 74 61 72 74 20 3d 20 28  p->iBufStart = (
5e50: 69 53 74 61 72 74 20 25 20 6e 42 75 66 29 3b 0a  iStart % nBuf);.
5e60: 20 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66      p->iWriteOff
5e70: 20 3d 20 69 53 74 61 72 74 20 2d 20 70 2d 3e 69   = iStart - p->i
5e80: 42 75 66 53 74 61 72 74 3b 0a 20 20 20 20 70 2d  BufStart;.    p-
5e90: 3e 6e 42 75 66 66 65 72 20 3d 20 6e 42 75 66 3b  >nBuffer = nBuf;
5ea0: 0a 20 20 20 20 70 2d 3e 70 46 69 6c 65 20 3d 20  .    p->pFile = 
5eb0: 70 46 69 6c 65 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  pFile;.  }.}../*
5ec0: 0a 2a 2a 20 57 72 69 74 65 20 6e 44 61 74 61 20  .** Write nData 
5ed0: 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 74 6f  bytes of data to
5ee0: 20 74 68 65 20 66 69 6c 65 2d 77 72 69 74 65 20   the file-write 
5ef0: 6f 62 6a 65 63 74 2e 20 52 65 74 75 72 6e 20 53  object. Return S
5f00: 51 4c 49 54 45 5f 4f 4b 0a 2a 2a 20 69 66 20 73  QLITE_OK.** if s
5f10: 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e  uccessful, or an
5f20: 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
5f30: 64 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f  de if an error o
5f40: 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  ccurs..*/.static
5f50: 20 76 6f 69 64 20 66 69 6c 65 57 72 69 74 65 72   void fileWriter
5f60: 57 72 69 74 65 28 46 69 6c 65 57 72 69 74 65 72  Write(FileWriter
5f70: 20 2a 70 2c 20 75 38 20 2a 70 44 61 74 61 2c 20   *p, u8 *pData, 
5f80: 69 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20 69 6e  int nData){.  in
5f90: 74 20 6e 52 65 6d 20 3d 20 6e 44 61 74 61 3b 0a  t nRem = nData;.
5fa0: 20 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30 20    while( nRem>0 
5fb0: 26 26 20 70 2d 3e 65 46 57 45 72 72 3d 3d 30 20  && p->eFWErr==0 
5fc0: 29 7b 0a 20 20 20 20 69 6e 74 20 6e 43 6f 70 79  ){.    int nCopy
5fd0: 20 3d 20 6e 52 65 6d 3b 0a 20 20 20 20 69 66 28   = nRem;.    if(
5fe0: 20 6e 43 6f 70 79 3e 28 70 2d 3e 6e 42 75 66 66   nCopy>(p->nBuff
5ff0: 65 72 20 2d 20 70 2d 3e 69 42 75 66 45 6e 64 29  er - p->iBufEnd)
6000: 20 29 7b 0a 20 20 20 20 20 20 6e 43 6f 70 79 20   ){.      nCopy 
6010: 3d 20 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 70  = p->nBuffer - p
6020: 2d 3e 69 42 75 66 45 6e 64 3b 0a 20 20 20 20 7d  ->iBufEnd;.    }
6030: 0a 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d  ..    memcpy(&p-
6040: 3e 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66  >aBuffer[p->iBuf
6050: 45 6e 64 5d 2c 20 26 70 44 61 74 61 5b 6e 44 61  End], &pData[nDa
6060: 74 61 2d 6e 52 65 6d 5d 2c 20 6e 43 6f 70 79 29  ta-nRem], nCopy)
6070: 3b 0a 20 20 20 20 70 2d 3e 69 42 75 66 45 6e 64  ;.    p->iBufEnd
6080: 20 2b 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 69   += nCopy;.    i
6090: 66 28 20 70 2d 3e 69 42 75 66 45 6e 64 3d 3d 70  f( p->iBufEnd==p
60a0: 2d 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20  ->nBuffer ){.   
60b0: 20 20 20 70 2d 3e 65 46 57 45 72 72 20 3d 20 73     p->eFWErr = s
60c0: 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d  qlite3OsWrite(p-
60d0: 3e 70 46 69 6c 65 2c 20 0a 20 20 20 20 20 20 20  >pFile, .       
60e0: 20 20 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 70     &p->aBuffer[p
60f0: 2d 3e 69 42 75 66 53 74 61 72 74 5d 2c 20 70 2d  ->iBufStart], p-
6100: 3e 69 42 75 66 45 6e 64 20 2d 20 70 2d 3e 69 42  >iBufEnd - p->iB
6110: 75 66 53 74 61 72 74 2c 20 0a 20 20 20 20 20 20  ufStart, .      
6120: 20 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66      p->iWriteOff
6130: 20 2b 20 70 2d 3e 69 42 75 66 53 74 61 72 74 0a   + p->iBufStart.
6140: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 70        );.      p
6150: 2d 3e 69 42 75 66 53 74 61 72 74 20 3d 20 70 2d  ->iBufStart = p-
6160: 3e 69 42 75 66 45 6e 64 20 3d 20 30 3b 0a 20 20  >iBufEnd = 0;.  
6170: 20 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66      p->iWriteOff
6180: 20 2b 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a   += p->nBuffer;.
6190: 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74      }.    assert
61a0: 28 20 70 2d 3e 69 42 75 66 45 6e 64 3c 70 2d 3e  ( p->iBufEnd<p->
61b0: 6e 42 75 66 66 65 72 20 29 3b 0a 0a 20 20 20 20  nBuffer );..    
61c0: 6e 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20  nRem -= nCopy;. 
61d0: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73   }.}../*.** Flus
61e0: 68 20 61 6e 79 20 62 75 66 66 65 72 65 64 20 64  h any buffered d
61f0: 61 74 61 20 74 6f 20 64 69 73 6b 20 61 6e 64 20  ata to disk and 
6200: 63 6c 65 61 6e 20 75 70 20 74 68 65 20 66 69 6c  clean up the fil
6210: 65 2d 77 72 69 74 65 72 20 6f 62 6a 65 63 74 2e  e-writer object.
6220: 0a 2a 2a 20 54 68 65 20 72 65 73 75 6c 74 73 20  .** The results 
6230: 6f 66 20 75 73 69 6e 67 20 74 68 65 20 66 69 6c  of using the fil
6240: 65 2d 77 72 69 74 65 72 20 61 66 74 65 72 20 74  e-writer after t
6250: 68 69 73 20 63 61 6c 6c 20 61 72 65 20 75 6e 64  his call are und
6260: 65 66 69 6e 65 64 2e 0a 2a 2a 20 52 65 74 75 72  efined..** Retur
6270: 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 66  n SQLITE_OK if f
6280: 6c 75 73 68 69 6e 67 20 74 68 65 20 62 75 66 66  lushing the buff
6290: 65 72 65 64 20 64 61 74 61 20 73 75 63 63 65 65  ered data succee
62a0: 64 73 20 6f 72 20 69 73 20 6e 6f 74 20 0a 2a 2a  ds or is not .**
62b0: 20 72 65 71 75 69 72 65 64 2e 20 4f 74 68 65 72   required. Other
62c0: 77 69 73 65 2c 20 72 65 74 75 72 6e 20 61 6e 20  wise, return an 
62d0: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
62e0: 65 2e 0a 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65 20  e..**.** Before 
62f0: 72 65 74 75 72 6e 69 6e 67 2c 20 73 65 74 20 2a  returning, set *
6300: 70 69 45 6f 66 20 74 6f 20 74 68 65 20 6f 66 66  piEof to the off
6310: 73 65 74 20 69 6d 6d 65 64 69 61 74 65 6c 79 20  set immediately 
6320: 66 6f 6c 6c 6f 77 69 6e 67 20 74 68 65 0a 2a 2a  following the.**
6330: 20 6c 61 73 74 20 62 79 74 65 20 77 72 69 74 74   last byte writt
6340: 65 6e 20 74 6f 20 74 68 65 20 66 69 6c 65 2e 0a  en to the file..
6350: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69  */.static int fi
6360: 6c 65 57 72 69 74 65 72 46 69 6e 69 73 68 28 73  leWriterFinish(s
6370: 71 6c 69 74 65 33 20 2a 64 62 2c 20 46 69 6c 65  qlite3 *db, File
6380: 57 72 69 74 65 72 20 2a 70 2c 20 69 36 34 20 2a  Writer *p, i64 *
6390: 70 69 45 6f 66 29 7b 0a 20 20 69 6e 74 20 72 63  piEof){.  int rc
63a0: 3b 0a 20 20 69 66 28 20 70 2d 3e 65 46 57 45 72  ;.  if( p->eFWEr
63b0: 72 3d 3d 30 20 26 26 20 41 4c 57 41 59 53 28 70  r==0 && ALWAYS(p
63c0: 2d 3e 61 42 75 66 66 65 72 29 20 26 26 20 70 2d  ->aBuffer) && p-
63d0: 3e 69 42 75 66 45 6e 64 3e 70 2d 3e 69 42 75 66  >iBufEnd>p->iBuf
63e0: 53 74 61 72 74 20 29 7b 0a 20 20 20 20 70 2d 3e  Start ){.    p->
63f0: 65 46 57 45 72 72 20 3d 20 73 71 6c 69 74 65 33  eFWErr = sqlite3
6400: 4f 73 57 72 69 74 65 28 70 2d 3e 70 46 69 6c 65  OsWrite(p->pFile
6410: 2c 20 0a 20 20 20 20 20 20 20 20 26 70 2d 3e 61  , .        &p->a
6420: 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 53 74  Buffer[p->iBufSt
6430: 61 72 74 5d 2c 20 70 2d 3e 69 42 75 66 45 6e 64  art], p->iBufEnd
6440: 20 2d 20 70 2d 3e 69 42 75 66 53 74 61 72 74 2c   - p->iBufStart,
6450: 20 0a 20 20 20 20 20 20 20 20 70 2d 3e 69 57 72   .        p->iWr
6460: 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42 75 66  iteOff + p->iBuf
6470: 53 74 61 72 74 0a 20 20 20 20 29 3b 0a 20 20 7d  Start.    );.  }
6480: 0a 20 20 2a 70 69 45 6f 66 20 3d 20 28 70 2d 3e  .  *piEof = (p->
6490: 69 57 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69  iWriteOff + p->i
64a0: 42 75 66 45 6e 64 29 3b 0a 20 20 73 71 6c 69 74  BufEnd);.  sqlit
64b0: 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 2d 3e  e3DbFree(db, p->
64c0: 61 42 75 66 66 65 72 29 3b 0a 20 20 72 63 20 3d  aBuffer);.  rc =
64d0: 20 70 2d 3e 65 46 57 45 72 72 3b 0a 20 20 6d 65   p->eFWErr;.  me
64e0: 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f  mset(p, 0, sizeo
64f0: 66 28 46 69 6c 65 57 72 69 74 65 72 29 29 3b 0a  f(FileWriter));.
6500: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
6510: 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 76 61 6c 75  /*.** Write valu
6520: 65 20 69 56 61 6c 20 65 6e 63 6f 64 65 64 20 61  e iVal encoded a
6530: 73 20 61 20 76 61 72 69 6e 74 20 74 6f 20 74 68  s a varint to th
6540: 65 20 66 69 6c 65 2d 77 72 69 74 65 20 6f 62 6a  e file-write obj
6550: 65 63 74 2e 20 52 65 74 75 72 6e 20 0a 2a 2a 20  ect. Return .** 
6560: 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63  SQLITE_OK if suc
6570: 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53  cessful, or an S
6580: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
6590: 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   if an error occ
65a0: 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  urs..*/.static v
65b0: 6f 69 64 20 66 69 6c 65 57 72 69 74 65 72 57 72  oid fileWriterWr
65c0: 69 74 65 56 61 72 69 6e 74 28 46 69 6c 65 57 72  iteVarint(FileWr
65d0: 69 74 65 72 20 2a 70 2c 20 75 36 34 20 69 56 61  iter *p, u64 iVa
65e0: 6c 29 7b 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b  l){.  int nByte;
65f0: 20 0a 20 20 75 38 20 61 42 79 74 65 5b 31 30 5d   .  u8 aByte[10]
6600: 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 71 6c 69  ;.  nByte = sqli
6610: 74 65 33 50 75 74 56 61 72 69 6e 74 28 61 42 79  te3PutVarint(aBy
6620: 74 65 2c 20 69 56 61 6c 29 3b 0a 20 20 66 69 6c  te, iVal);.  fil
6630: 65 57 72 69 74 65 72 57 72 69 74 65 28 70 2c 20  eWriterWrite(p, 
6640: 61 42 79 74 65 2c 20 6e 42 79 74 65 29 3b 0a 7d  aByte, nByte);.}
6650: 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 74 68  ../*.** Write th
6660: 65 20 63 75 72 72 65 6e 74 20 63 6f 6e 74 65 6e  e current conten
6670: 74 73 20 6f 66 20 74 68 65 20 69 6e 2d 6d 65 6d  ts of the in-mem
6680: 6f 72 79 20 6c 69 6e 6b 65 64 2d 6c 69 73 74 20  ory linked-list 
6690: 74 6f 20 61 20 50 4d 41 2e 20 52 65 74 75 72 6e  to a PMA. Return
66a0: 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66  .** SQLITE_OK if
66b0: 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20   successful, or 
66c0: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
66d0: 63 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a  code otherwise..
66e0: 2a 2a 0a 2a 2a 20 54 68 65 20 66 6f 72 6d 61 74  **.** The format
66f0: 20 6f 66 20 61 20 50 4d 41 20 69 73 3a 0a 2a 2a   of a PMA is:.**
6700: 0a 2a 2a 20 20 20 20 20 2a 20 41 20 76 61 72 69  .**     * A vari
6710: 6e 74 2e 20 54 68 69 73 20 76 61 72 69 6e 74 20  nt. This varint 
6720: 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 74 6f 74  contains the tot
6730: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  al number of byt
6740: 65 73 20 6f 66 20 63 6f 6e 74 65 6e 74 0a 2a 2a  es of content.**
6750: 20 20 20 20 20 20 20 69 6e 20 74 68 65 20 50 4d         in the PM
6760: 41 20 28 6e 6f 74 20 69 6e 63 6c 75 64 69 6e 67  A (not including
6770: 20 74 68 65 20 76 61 72 69 6e 74 20 69 74 73 65   the varint itse
6780: 6c 66 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a  lf)..**.**     *
6790: 20 4f 6e 65 20 6f 72 20 6d 6f 72 65 20 72 65 63   One or more rec
67a0: 6f 72 64 73 20 70 61 63 6b 65 64 20 65 6e 64 2d  ords packed end-
67b0: 74 6f 2d 65 6e 64 20 69 6e 20 6f 72 64 65 72 20  to-end in order 
67c0: 6f 66 20 61 73 63 65 6e 64 69 6e 67 20 6b 65 79  of ascending key
67d0: 73 2e 20 0a 2a 2a 20 20 20 20 20 20 20 45 61 63  s. .**       Eac
67e0: 68 20 72 65 63 6f 72 64 20 63 6f 6e 73 69 73 74  h record consist
67f0: 73 20 6f 66 20 61 20 76 61 72 69 6e 74 20 66 6f  s of a varint fo
6800: 6c 6c 6f 77 65 64 20 62 79 20 61 20 62 6c 6f 62  llowed by a blob
6810: 20 6f 66 20 64 61 74 61 20 28 74 68 65 20 0a 2a   of data (the .*
6820: 2a 20 20 20 20 20 20 20 6b 65 79 29 2e 20 54 68  *       key). Th
6830: 65 20 76 61 72 69 6e 74 20 69 73 20 74 68 65 20  e varint is the 
6840: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
6850: 69 6e 20 74 68 65 20 62 6c 6f 62 20 6f 66 20 64  in the blob of d
6860: 61 74 61 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ata..*/.static i
6870: 6e 74 20 76 64 62 65 53 6f 72 74 65 72 4c 69 73  nt vdbeSorterLis
6880: 74 54 6f 50 4d 41 28 56 64 62 65 53 6f 72 74 65  tToPMA(VdbeSorte
6890: 72 20 2a 70 53 6f 72 74 65 72 29 7b 0a 20 20 69  r *pSorter){.  i
68a0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
68b0: 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  K;             /
68c0: 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
68d0: 0a 20 20 46 69 6c 65 57 72 69 74 65 72 20 77 72  .  FileWriter wr
68e0: 69 74 65 72 3b 0a 20 20 73 71 6c 69 74 65 33 20  iter;.  sqlite3 
68f0: 2a 64 62 20 3d 20 70 53 6f 72 74 65 72 2d 3e 64  *db = pSorter->d
6900: 62 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 77 72  b;..  memset(&wr
6910: 69 74 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28  iter, 0, sizeof(
6920: 46 69 6c 65 57 72 69 74 65 72 29 29 3b 0a 0a 20  FileWriter));.. 
6930: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6e 49   if( pSorter->nI
6940: 6e 4d 65 6d 6f 72 79 3d 3d 30 20 29 7b 0a 20 20  nMemory==0 ){.  
6950: 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65    assert( pSorte
6960: 72 2d 3e 70 52 65 63 6f 72 64 3d 3d 30 20 29 3b  r->pRecord==0 );
6970: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 53 6f  .    assert( pSo
6980: 72 74 65 72 2d 3e 6e 52 65 63 6f 72 64 3d 3d 30  rter->nRecord==0
6990: 20 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 72   );.    return r
69a0: 63 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20 76  c;.  }..  rc = v
69b0: 64 62 65 53 6f 72 74 65 72 53 6f 72 74 28 70 53  dbeSorterSort(pS
69c0: 6f 72 74 65 72 29 3b 0a 0a 20 20 2f 2a 20 49 66  orter);..  /* If
69d0: 20 74 68 65 20 66 69 72 73 74 20 74 65 6d 70 6f   the first tempo
69e0: 72 61 72 79 20 50 4d 41 20 66 69 6c 65 20 68 61  rary PMA file ha
69f0: 73 20 6e 6f 74 20 62 65 65 6e 20 6f 70 65 6e 65  s not been opene
6a00: 64 2c 20 6f 70 65 6e 20 69 74 20 6e 6f 77 2e 20  d, open it now. 
6a10: 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  */.  if( rc==SQL
6a20: 49 54 45 5f 4f 4b 20 26 26 20 70 53 6f 72 74 65  ITE_OK && pSorte
6a30: 72 2d 3e 70 54 65 6d 70 31 3d 3d 30 20 29 7b 0a  r->pTemp1==0 ){.
6a40: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
6a50: 74 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28  terOpenTempFile(
6a60: 64 62 2c 20 26 70 53 6f 72 74 65 72 2d 3e 70 54  db, &pSorter->pT
6a70: 65 6d 70 31 29 3b 0a 20 20 20 20 61 73 73 65 72  emp1);.    asser
6a80: 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  t( rc!=SQLITE_OK
6a90: 20 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 70 54 65   || pSorter->pTe
6aa0: 6d 70 31 20 29 3b 0a 20 20 20 20 61 73 73 65 72  mp1 );.    asser
6ab0: 74 28 20 70 53 6f 72 74 65 72 2d 3e 69 57 72 69  t( pSorter->iWri
6ac0: 74 65 4f 66 66 3d 3d 30 20 29 3b 0a 20 20 20 20  teOff==0 );.    
6ad0: 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d  assert( pSorter-
6ae0: 3e 6e 50 4d 41 3d 3d 30 20 29 3b 0a 20 20 7d 0a  >nPMA==0 );.  }.
6af0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
6b00: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 53 6f 72 74  E_OK ){.    Sort
6b10: 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a 20 20 20  erRecord *p;.   
6b20: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
6b30: 4e 65 78 74 20 3d 20 30 3b 0a 0a 20 20 20 20 66  Next = 0;..    f
6b40: 69 6c 65 57 72 69 74 65 72 49 6e 69 74 28 64 62  ileWriterInit(db
6b50: 2c 20 70 53 6f 72 74 65 72 2d 3e 70 54 65 6d 70  , pSorter->pTemp
6b60: 31 2c 20 26 77 72 69 74 65 72 2c 20 70 53 6f 72  1, &writer, pSor
6b70: 74 65 72 2d 3e 69 57 72 69 74 65 4f 66 66 29 3b  ter->iWriteOff);
6b80: 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6e 50  .    pSorter->nP
6b90: 4d 41 2b 2b 3b 0a 20 20 20 20 66 69 6c 65 57 72  MA++;.    fileWr
6ba0: 69 74 65 72 57 72 69 74 65 56 61 72 69 6e 74 28  iterWriteVarint(
6bb0: 26 77 72 69 74 65 72 2c 20 70 53 6f 72 74 65 72  &writer, pSorter
6bc0: 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 29 3b 0a 20 20  ->nInMemory);.  
6bd0: 20 20 66 6f 72 28 70 3d 70 53 6f 72 74 65 72 2d    for(p=pSorter-
6be0: 3e 70 52 65 63 6f 72 64 3b 20 70 3b 20 70 3d 70  >pRecord; p; p=p
6bf0: 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 70 4e 65  Next){.      pNe
6c00: 78 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20  xt = p->pNext;. 
6c10: 20 20 20 20 20 66 69 6c 65 57 72 69 74 65 72 57       fileWriterW
6c20: 72 69 74 65 56 61 72 69 6e 74 28 26 77 72 69 74  riteVarint(&writ
6c30: 65 72 2c 20 70 2d 3e 6e 56 61 6c 29 3b 0a 20 20  er, p->nVal);.  
6c40: 20 20 20 20 66 69 6c 65 57 72 69 74 65 72 57 72      fileWriterWr
6c50: 69 74 65 28 26 77 72 69 74 65 72 2c 20 70 2d 3e  ite(&writer, p->
6c60: 70 56 61 6c 2c 20 70 2d 3e 6e 56 61 6c 29 3b 0a  pVal, p->nVal);.
6c70: 20 20 20 20 20 20 73 71 6c 69 74 65 33 44 62 46        sqlite3DbF
6c80: 72 65 65 28 64 62 2c 20 70 29 3b 0a 20 20 20 20  ree(db, p);.    
6c90: 7d 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70  }.    pSorter->p
6ca0: 52 65 63 6f 72 64 20 3d 20 30 3b 0a 20 20 20 20  Record = 0;.    
6cb0: 70 53 6f 72 74 65 72 2d 3e 6e 52 65 63 6f 72 64  pSorter->nRecord
6cc0: 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d 20 66   = 0;.    rc = f
6cd0: 69 6c 65 57 72 69 74 65 72 46 69 6e 69 73 68 28  ileWriterFinish(
6ce0: 64 62 2c 20 26 77 72 69 74 65 72 2c 20 26 70 53  db, &writer, &pS
6cf0: 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f 66 66  orter->iWriteOff
6d00: 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  );.  }..  return
6d10: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64   rc;.}../*.** Ad
6d20: 64 20 61 20 72 65 63 6f 72 64 20 74 6f 20 74 68  d a record to th
6d30: 65 20 73 6f 72 74 65 72 2e 0a 2a 2f 0a 69 6e 74  e sorter..*/.int
6d40: 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74   sqlite3VdbeSort
6d50: 65 72 57 72 69 74 65 28 0a 20 20 63 6f 6e 73 74  erWrite(.  const
6d60: 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73   VdbeCursor *pCs
6d70: 72 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f  r,         /* So
6d80: 72 74 65 72 20 63 75 72 73 6f 72 20 2a 2f 0a 20  rter cursor */. 
6d90: 20 4d 65 6d 20 2a 70 56 61 6c 20 20 20 20 20 20   Mem *pVal      
6da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6db0: 20 2f 2a 20 4d 65 6d 6f 72 79 20 63 65 6c 6c 20   /* Memory cell 
6dc0: 63 6f 6e 74 61 69 6e 69 6e 67 20 72 65 63 6f 72  containing recor
6dd0: 64 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65 53 6f  d */.){.  VdbeSo
6de0: 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20  rter *pSorter = 
6df0: 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20  pCsr->pSorter;. 
6e00: 20 73 71 6c 69 74 65 33 20 2a 64 62 20 3d 20 70   sqlite3 *db = p
6e10: 53 6f 72 74 65 72 2d 3e 64 62 3b 0a 20 20 69 6e  Sorter->db;.  in
6e20: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
6e30: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
6e40: 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a   Return Code */.
6e50: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
6e60: 70 4e 65 77 3b 20 20 20 20 20 20 20 20 20 20 20  pNew;           
6e70: 20 20 2f 2a 20 4e 65 77 20 6c 69 73 74 20 65 6c    /* New list el
6e80: 65 6d 65 6e 74 20 2a 2f 0a 0a 20 20 61 73 73 65  ement */..  asse
6e90: 72 74 28 20 70 53 6f 72 74 65 72 20 29 3b 0a 20  rt( pSorter );. 
6ea0: 20 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d   pSorter->nInMem
6eb0: 6f 72 79 20 2b 3d 20 73 71 6c 69 74 65 33 56 61  ory += sqlite3Va
6ec0: 72 69 6e 74 4c 65 6e 28 70 56 61 6c 2d 3e 6e 29  rintLen(pVal->n)
6ed0: 20 2b 20 70 56 61 6c 2d 3e 6e 3b 0a 0a 20 20 70   + pVal->n;..  p
6ee0: 4e 65 77 20 3d 20 28 53 6f 72 74 65 72 52 65 63  New = (SorterRec
6ef0: 6f 72 64 20 2a 29 73 71 6c 69 74 65 33 44 62 4d  ord *)sqlite3DbM
6f00: 61 6c 6c 6f 63 52 61 77 28 64 62 2c 20 70 56 61  allocRaw(db, pVa
6f10: 6c 2d 3e 6e 20 2b 20 73 69 7a 65 6f 66 28 53 6f  l->n + sizeof(So
6f20: 72 74 65 72 52 65 63 6f 72 64 29 29 3b 0a 20 20  rterRecord));.  
6f30: 69 66 28 20 70 4e 65 77 3d 3d 30 20 29 7b 0a 20  if( pNew==0 ){. 
6f40: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
6f50: 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  OMEM;.  }else{. 
6f60: 20 20 20 70 4e 65 77 2d 3e 70 56 61 6c 20 3d 20     pNew->pVal = 
6f70: 28 76 6f 69 64 20 2a 29 26 70 4e 65 77 5b 31 5d  (void *)&pNew[1]
6f80: 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 70 4e 65  ;.    memcpy(pNe
6f90: 77 2d 3e 70 56 61 6c 2c 20 70 56 61 6c 2d 3e 7a  w->pVal, pVal->z
6fa0: 2c 20 70 56 61 6c 2d 3e 6e 29 3b 0a 20 20 20 20  , pVal->n);.    
6fb0: 70 4e 65 77 2d 3e 6e 56 61 6c 20 3d 20 70 56 61  pNew->nVal = pVa
6fc0: 6c 2d 3e 6e 3b 0a 20 20 20 20 70 4e 65 77 2d 3e  l->n;.    pNew->
6fd0: 70 4e 65 78 74 20 3d 20 70 53 6f 72 74 65 72 2d  pNext = pSorter-
6fe0: 3e 70 52 65 63 6f 72 64 3b 0a 20 20 20 20 70 53  >pRecord;.    pS
6ff0: 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 3d  orter->pRecord =
7000: 20 70 4e 65 77 3b 0a 20 20 20 20 70 53 6f 72 74   pNew;.    pSort
7010: 65 72 2d 3e 6e 52 65 63 6f 72 64 2b 2b 3b 0a 20  er->nRecord++;. 
7020: 20 7d 0a 0a 20 20 2f 2a 20 53 65 65 20 69 66 20   }..  /* See if 
7030: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
7040: 74 68 65 20 73 6f 72 74 65 72 20 73 68 6f 75 6c  the sorter shoul
7050: 64 20 6e 6f 77 20 62 65 20 77 72 69 74 74 65 6e  d now be written
7060: 20 6f 75 74 2e 20 54 68 65 79 0a 20 20 2a 2a 20   out. They.  ** 
7070: 61 72 65 20 77 72 69 74 74 65 6e 20 6f 75 74 20  are written out 
7080: 77 68 65 6e 20 65 69 74 68 65 72 20 6f 66 20 74  when either of t
7090: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 72 65  he following are
70a0: 20 74 72 75 65 3a 0a 20 20 2a 2a 0a 20 20 2a 2a   true:.  **.  **
70b0: 20 20 20 2a 20 54 68 65 20 74 6f 74 61 6c 20 6d     * The total m
70c0: 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 65 64 20  emory allocated 
70d0: 66 6f 72 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72  for the in-memor
70e0: 79 20 6c 69 73 74 20 69 73 20 67 72 65 61 74 65  y list is greate
70f0: 72 20 0a 20 20 2a 2a 20 20 20 20 20 74 68 61 6e  r .  **     than
7100: 20 28 70 61 67 65 2d 73 69 7a 65 20 2a 20 63 61   (page-size * ca
7110: 63 68 65 2d 73 69 7a 65 29 2c 20 6f 72 0a 20 20  che-size), or.  
7120: 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 54 68 65 20  **.  **   * The 
7130: 74 6f 74 61 6c 20 6d 65 6d 6f 72 79 20 61 6c 6c  total memory all
7140: 6f 63 61 74 65 64 20 66 6f 72 20 74 68 65 20 69  ocated for the i
7150: 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20 69 73  n-memory list is
7160: 20 67 72 65 61 74 65 72 20 0a 20 20 2a 2a 20 20   greater .  **  
7170: 20 20 20 74 68 61 6e 20 28 70 61 67 65 2d 73 69     than (page-si
7180: 7a 65 20 2a 20 31 30 29 20 61 6e 64 20 73 71 6c  ze * 10) and sql
7190: 69 74 65 33 48 65 61 70 4e 65 61 72 6c 79 46 75  ite3HeapNearlyFu
71a0: 6c 6c 28 29 20 72 65 74 75 72 6e 73 20 74 72 75  ll() returns tru
71b0: 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 72 63  e..  */.  if( rc
71c0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70  ==SQLITE_OK && p
71d0: 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a  Sorter->mxPmaSiz
71e0: 65 3e 30 20 26 26 20 28 0a 20 20 20 20 20 20 20  e>0 && (.       
71f0: 20 28 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65   (pSorter->nInMe
7200: 6d 6f 72 79 3e 70 53 6f 72 74 65 72 2d 3e 6d 78  mory>pSorter->mx
7210: 50 6d 61 53 69 7a 65 29 0a 20 20 20 20 20 7c 7c  PmaSize).     ||
7220: 20 28 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65   (pSorter->nInMe
7230: 6d 6f 72 79 3e 70 53 6f 72 74 65 72 2d 3e 6d 6e  mory>pSorter->mn
7240: 50 6d 61 53 69 7a 65 20 26 26 20 73 71 6c 69 74  PmaSize && sqlit
7250: 65 33 48 65 61 70 4e 65 61 72 6c 79 46 75 6c 6c  e3HeapNearlyFull
7260: 28 29 29 0a 20 20 29 29 7b 0a 23 69 66 64 65 66  ()).  )){.#ifdef
7270: 20 53 51 4c 49 54 45 5f 44 45 42 55 47 0a 20 20   SQLITE_DEBUG.  
7280: 20 20 69 36 34 20 6e 45 78 70 65 63 74 20 3d 20    i64 nExpect = 
7290: 70 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f  pSorter->iWriteO
72a0: 66 66 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ff.             
72b0: 20 20 20 2b 20 73 71 6c 69 74 65 33 56 61 72 69     + sqlite3Vari
72c0: 6e 74 4c 65 6e 28 70 53 6f 72 74 65 72 2d 3e 6e  ntLen(pSorter->n
72d0: 49 6e 4d 65 6d 6f 72 79 29 0a 20 20 20 20 20 20  InMemory).      
72e0: 20 20 20 20 20 20 20 20 20 20 2b 20 70 53 6f 72            + pSor
72f0: 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 3b 0a  ter->nInMemory;.
7300: 23 65 6e 64 69 66 0a 20 20 20 20 72 63 20 3d 20  #endif.    rc = 
7310: 76 64 62 65 53 6f 72 74 65 72 4c 69 73 74 54 6f  vdbeSorterListTo
7320: 50 4d 41 28 70 53 6f 72 74 65 72 29 3b 0a 20 20  PMA(pSorter);.  
7330: 20 20 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65    pSorter->nInMe
7340: 6d 6f 72 79 20 3d 20 30 3b 0a 20 20 20 20 61 73  mory = 0;.    as
7350: 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45  sert( rc!=SQLITE
7360: 5f 4f 4b 20 7c 7c 20 28 6e 45 78 70 65 63 74 3d  _OK || (nExpect=
7370: 3d 70 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65  =pSorter->iWrite
7380: 4f 66 66 29 20 29 3b 0a 20 20 7d 0a 0a 20 20 72  Off) );.  }..  r
7390: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
73a0: 2a 2a 20 48 65 6c 70 65 72 20 66 75 6e 63 74 69  ** Helper functi
73b0: 6f 6e 20 66 6f 72 20 73 71 6c 69 74 65 33 56 64  on for sqlite3Vd
73c0: 62 65 53 6f 72 74 65 72 52 65 77 69 6e 64 28 29  beSorterRewind()
73d0: 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  . .*/.static int
73e0: 20 76 64 62 65 53 6f 72 74 65 72 49 6e 69 74 4d   vdbeSorterInitM
73f0: 65 72 67 65 28 0a 20 20 56 64 62 65 53 6f 72 74  erge(.  VdbeSort
7400: 65 72 20 2a 70 53 6f 72 74 65 72 2c 20 20 20 20  er *pSorter,    
7410: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 73          /* The s
7420: 6f 72 74 65 72 20 2a 2f 0a 20 20 69 36 34 20 2a  orter */.  i64 *
7430: 70 6e 42 79 74 65 20 20 20 20 20 20 20 20 20 20  pnByte          
7440: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 75             /* Su
7450: 6d 20 6f 66 20 62 79 74 65 73 20 69 6e 20 61 6c  m of bytes in al
7460: 6c 20 6f 70 65 6e 65 64 20 50 4d 41 73 20 2a 2f  l opened PMAs */
7470: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
7480: 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
7490: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
74a0: 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 69 3b  code */.  int i;
74b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
74c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65            /* Use
74d0: 64 20 74 6f 20 69 74 65 72 61 74 6f 72 20 74 68  d to iterator th
74e0: 72 6f 75 67 68 20 61 49 74 65 72 5b 5d 20 2a 2f  rough aIter[] */
74f0: 0a 20 20 69 36 34 20 6e 42 79 74 65 20 3d 20 30  .  i64 nByte = 0
7500: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
7510: 20 20 20 2f 2a 20 54 6f 74 61 6c 20 62 79 74 65     /* Total byte
7520: 73 20 69 6e 20 61 6c 6c 20 6f 70 65 6e 65 64 20  s in all opened 
7530: 50 4d 41 73 20 2a 2f 0a 0a 20 20 2f 2a 20 49 6e  PMAs */..  /* In
7540: 69 74 69 61 6c 69 7a 65 20 74 68 65 20 69 74 65  itialize the ite
7550: 72 61 74 6f 72 73 2e 20 2a 2f 0a 20 20 66 6f 72  rators. */.  for
7560: 28 69 3d 30 3b 20 69 3c 53 4f 52 54 45 52 5f 4d  (i=0; i<SORTER_M
7570: 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3b 20  AX_MERGE_COUNT; 
7580: 69 2b 2b 29 7b 0a 20 20 20 20 56 64 62 65 53 6f  i++){.    VdbeSo
7590: 72 74 65 72 49 74 65 72 20 2a 70 49 74 65 72 20  rterIter *pIter 
75a0: 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 49 74 65  = &pSorter->aIte
75b0: 72 5b 69 5d 3b 0a 20 20 20 20 72 63 20 3d 20 76  r[i];.    rc = v
75c0: 64 62 65 53 6f 72 74 65 72 49 74 65 72 49 6e 69  dbeSorterIterIni
75d0: 74 28 70 53 6f 72 74 65 72 2c 20 70 53 6f 72 74  t(pSorter, pSort
75e0: 65 72 2d 3e 69 52 65 61 64 4f 66 66 2c 20 70 49  er->iReadOff, pI
75f0: 74 65 72 2c 20 26 6e 42 79 74 65 29 3b 0a 20 20  ter, &nByte);.  
7600: 20 20 70 53 6f 72 74 65 72 2d 3e 69 52 65 61 64    pSorter->iRead
7610: 4f 66 66 20 3d 20 70 49 74 65 72 2d 3e 69 45 6f  Off = pIter->iEo
7620: 66 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 72  f;.    assert( r
7630: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20  c!=SQLITE_OK || 
7640: 70 53 6f 72 74 65 72 2d 3e 69 52 65 61 64 4f 66  pSorter->iReadOf
7650: 66 3c 3d 70 53 6f 72 74 65 72 2d 3e 69 57 72 69  f<=pSorter->iWri
7660: 74 65 4f 66 66 20 29 3b 0a 20 20 20 20 69 66 28  teOff );.    if(
7670: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c   rc!=SQLITE_OK |
7680: 7c 20 70 53 6f 72 74 65 72 2d 3e 69 52 65 61 64  | pSorter->iRead
7690: 4f 66 66 3e 3d 70 53 6f 72 74 65 72 2d 3e 69 57  Off>=pSorter->iW
76a0: 72 69 74 65 4f 66 66 20 29 20 62 72 65 61 6b 3b  riteOff ) break;
76b0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 6e 69 74 69  .  }..  /* Initi
76c0: 61 6c 69 7a 65 20 74 68 65 20 61 54 72 65 65 5b  alize the aTree[
76d0: 5d 20 61 72 72 61 79 2e 20 2a 2f 0a 20 20 66 6f  ] array. */.  fo
76e0: 72 28 69 3d 70 53 6f 72 74 65 72 2d 3e 6e 54 72  r(i=pSorter->nTr
76f0: 65 65 2d 31 3b 20 72 63 3d 3d 53 51 4c 49 54 45  ee-1; rc==SQLITE
7700: 5f 4f 4b 20 26 26 20 69 3e 30 3b 20 69 2d 2d 29  _OK && i>0; i--)
7710: 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53  {.    rc = vdbeS
7720: 6f 72 74 65 72 44 6f 43 6f 6d 70 61 72 65 28 70  orterDoCompare(p
7730: 53 6f 72 74 65 72 2c 20 69 29 3b 0a 20 20 7d 0a  Sorter, i);.  }.
7740: 0a 20 20 2a 70 6e 42 79 74 65 20 3d 20 6e 42 79  .  *pnByte = nBy
7750: 74 65 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  te;.  return rc;
7760: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 6e 63 65 20 74  .}../*.** Once t
7770: 68 65 20 73 6f 72 74 65 72 20 68 61 73 20 62 65  he sorter has be
7780: 65 6e 20 70 6f 70 75 6c 61 74 65 64 2c 20 74 68  en populated, th
7790: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
77a0: 61 6c 6c 65 64 20 74 6f 20 70 72 65 70 61 72 65  alled to prepare
77b0: 0a 2a 2a 20 66 6f 72 20 69 74 65 72 61 74 69 6e  .** for iteratin
77c0: 67 20 74 68 72 6f 75 67 68 20 69 74 73 20 63 6f  g through its co
77d0: 6e 74 65 6e 74 73 20 69 6e 20 73 6f 72 74 65 64  ntents in sorted
77e0: 20 6f 72 64 65 72 2e 0a 2a 2f 0a 69 6e 74 20 73   order..*/.int s
77f0: 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72  qlite3VdbeSorter
7800: 52 65 77 69 6e 64 28 63 6f 6e 73 74 20 56 64 62  Rewind(const Vdb
7810: 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69  eCursor *pCsr, i
7820: 6e 74 20 2a 70 62 45 6f 66 29 7b 0a 20 20 56 64  nt *pbEof){.  Vd
7830: 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
7840: 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65  r = pCsr->pSorte
7850: 72 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  r;.  sqlite3 *db
7860: 20 3d 20 70 53 6f 72 74 65 72 2d 3e 64 62 3b 0a   = pSorter->db;.
7870: 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
7880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7890: 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
78a0: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69   */.  sqlite3_fi
78b0: 6c 65 20 2a 70 54 65 6d 70 32 20 3d 20 30 3b 20  le *pTemp2 = 0; 
78c0: 20 20 20 20 20 20 2f 2a 20 53 65 63 6f 6e 64 20        /* Second 
78d0: 74 65 6d 70 20 66 69 6c 65 20 74 6f 20 75 73 65  temp file to use
78e0: 20 2a 2f 0a 20 20 69 36 34 20 69 57 72 69 74 65   */.  i64 iWrite
78f0: 32 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  2 = 0;          
7900: 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 6f        /* Write o
7910: 66 66 73 65 74 20 66 6f 72 20 70 54 65 6d 70 32  ffset for pTemp2
7920: 20 2a 2f 0a 20 20 69 6e 74 20 6e 49 74 65 72 3b   */.  int nIter;
7930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7940: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
7950: 6f 66 20 69 74 65 72 61 74 6f 72 73 20 75 73 65  of iterators use
7960: 64 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65  d */.  int nByte
7970: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
7980: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
7990: 6f 66 20 73 70 61 63 65 20 72 65 71 75 69 72 65  of space require
79a0: 64 20 66 6f 72 20 61 49 74 65 72 2f 61 54 72 65  d for aIter/aTre
79b0: 65 20 2a 2f 0a 20 20 69 6e 74 20 4e 20 3d 20 32  e */.  int N = 2
79c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
79d0: 20 20 20 20 20 20 20 2f 2a 20 50 6f 77 65 72 20         /* Power 
79e0: 6f 66 20 32 20 3e 3d 20 6e 49 74 65 72 20 2a 2f  of 2 >= nIter */
79f0: 0a 0a 20 20 61 73 73 65 72 74 28 20 70 53 6f 72  ..  assert( pSor
7a00: 74 65 72 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20  ter );..  /* If 
7a10: 6e 6f 20 64 61 74 61 20 68 61 73 20 62 65 65 6e  no data has been
7a20: 20 77 72 69 74 74 65 6e 20 74 6f 20 64 69 73 6b   written to disk
7a30: 2c 20 74 68 65 6e 20 64 6f 20 6e 6f 74 20 64 6f  , then do not do
7a40: 20 73 6f 20 6e 6f 77 2e 20 49 6e 73 74 65 61 64   so now. Instead
7a50: 2c 0a 20 20 2a 2a 20 73 6f 72 74 20 74 68 65 20  ,.  ** sort the 
7a60: 56 64 62 65 53 6f 72 74 65 72 2e 70 52 65 63 6f  VdbeSorter.pReco
7a70: 72 64 20 6c 69 73 74 2e 20 54 68 65 20 76 64 62  rd list. The vdb
7a80: 65 20 6c 61 79 65 72 20 77 69 6c 6c 20 72 65 61  e layer will rea
7a90: 64 20 64 61 74 61 20 64 69 72 65 63 74 6c 79 0a  d data directly.
7aa0: 20 20 2a 2a 20 66 72 6f 6d 20 74 68 65 20 69 6e    ** from the in
7ab0: 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 2e 20 20 2a  -memory list.  *
7ac0: 2f 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d  /.  if( pSorter-
7ad0: 3e 6e 50 4d 41 3d 3d 30 20 29 7b 0a 20 20 20 20  >nPMA==0 ){.    
7ae0: 2a 70 62 45 6f 66 20 3d 20 21 70 53 6f 72 74 65  *pbEof = !pSorte
7af0: 72 2d 3e 70 52 65 63 6f 72 64 3b 0a 20 20 20 20  r->pRecord;.    
7b00: 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d  assert( pSorter-
7b10: 3e 61 54 72 65 65 3d 3d 30 20 29 3b 0a 20 20 20  >aTree==0 );.   
7b20: 20 72 65 74 75 72 6e 20 76 64 62 65 53 6f 72 74   return vdbeSort
7b30: 65 72 53 6f 72 74 28 70 53 6f 72 74 65 72 29 3b  erSort(pSorter);
7b40: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 57 72 69 74 65  .  }..  /* Write
7b50: 20 74 68 65 20 63 75 72 72 65 6e 74 20 69 6e 2d   the current in-
7b60: 6d 65 6d 6f 72 79 20 6c 69 73 74 20 74 6f 20 61  memory list to a
7b70: 20 50 4d 41 2e 20 2a 2f 0a 20 20 72 63 20 3d 20   PMA. */.  rc = 
7b80: 76 64 62 65 53 6f 72 74 65 72 4c 69 73 74 54 6f  vdbeSorterListTo
7b90: 50 4d 41 28 70 53 6f 72 74 65 72 29 3b 0a 20 20  PMA(pSorter);.  
7ba0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
7bb0: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a  K ) return rc;..
7bc0: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 73 70    /* Allocate sp
7bd0: 61 63 65 20 66 6f 72 20 61 49 74 65 72 5b 5d 20  ace for aIter[] 
7be0: 61 6e 64 20 61 54 72 65 65 5b 5d 2e 20 2a 2f 0a  and aTree[]. */.
7bf0: 20 20 6e 49 74 65 72 20 3d 20 70 53 6f 72 74 65    nIter = pSorte
7c00: 72 2d 3e 6e 50 4d 41 3b 0a 20 20 69 66 28 20 6e  r->nPMA;.  if( n
7c10: 49 74 65 72 3e 53 4f 52 54 45 52 5f 4d 41 58 5f  Iter>SORTER_MAX_
7c20: 4d 45 52 47 45 5f 43 4f 55 4e 54 20 29 20 6e 49  MERGE_COUNT ) nI
7c30: 74 65 72 20 3d 20 53 4f 52 54 45 52 5f 4d 41 58  ter = SORTER_MAX
7c40: 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3b 0a 20 20  _MERGE_COUNT;.  
7c50: 61 73 73 65 72 74 28 20 6e 49 74 65 72 3e 30 20  assert( nIter>0 
7c60: 29 3b 0a 20 20 77 68 69 6c 65 28 20 4e 3c 6e 49  );.  while( N<nI
7c70: 74 65 72 20 29 20 4e 20 2b 3d 20 4e 3b 0a 20 20  ter ) N += N;.  
7c80: 6e 42 79 74 65 20 3d 20 4e 20 2a 20 28 73 69 7a  nByte = N * (siz
7c90: 65 6f 66 28 69 6e 74 29 20 2b 20 73 69 7a 65 6f  eof(int) + sizeo
7ca0: 66 28 56 64 62 65 53 6f 72 74 65 72 49 74 65 72  f(VdbeSorterIter
7cb0: 29 29 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 61  ));.  pSorter->a
7cc0: 49 74 65 72 20 3d 20 28 56 64 62 65 53 6f 72 74  Iter = (VdbeSort
7cd0: 65 72 49 74 65 72 20 2a 29 73 71 6c 69 74 65 33  erIter *)sqlite3
7ce0: 44 62 4d 61 6c 6c 6f 63 5a 65 72 6f 28 64 62 2c  DbMallocZero(db,
7cf0: 20 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20 21   nByte);.  if( !
7d00: 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 20 29  pSorter->aIter )
7d10: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
7d20: 4f 4d 45 4d 3b 0a 20 20 70 53 6f 72 74 65 72 2d  OMEM;.  pSorter-
7d30: 3e 61 54 72 65 65 20 3d 20 28 69 6e 74 20 2a 29  >aTree = (int *)
7d40: 26 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b  &pSorter->aIter[
7d50: 4e 5d 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6e  N];.  pSorter->n
7d60: 54 72 65 65 20 3d 20 4e 3b 0a 0a 20 20 64 6f 20  Tree = N;..  do 
7d70: 7b 0a 20 20 20 20 69 6e 74 20 69 4e 65 77 3b 20  {.    int iNew; 
7d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7d90: 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20      /* Index of 
7da0: 6e 65 77 2c 20 6d 65 72 67 65 64 2c 20 50 4d 41  new, merged, PMA
7db0: 20 2a 2f 0a 0a 20 20 20 20 66 6f 72 28 69 4e 65   */..    for(iNe
7dc0: 77 3d 30 3b 20 0a 20 20 20 20 20 20 20 20 72 63  w=0; .        rc
7dd0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69  ==SQLITE_OK && i
7de0: 4e 65 77 2a 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  New*SORTER_MAX_M
7df0: 45 52 47 45 5f 43 4f 55 4e 54 3c 70 53 6f 72 74  ERGE_COUNT<pSort
7e00: 65 72 2d 3e 6e 50 4d 41 3b 20 0a 20 20 20 20 20  er->nPMA; .     
7e10: 20 20 20 69 4e 65 77 2b 2b 0a 20 20 20 20 29 7b     iNew++.    ){
7e20: 0a 20 20 20 20 20 20 69 6e 74 20 72 63 32 3b 20  .      int rc2; 
7e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7e40: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
7e50: 65 20 66 72 6f 6d 20 66 69 6c 65 57 72 69 74 65  e from fileWrite
7e60: 72 46 69 6e 69 73 68 28 29 20 2a 2f 0a 20 20 20  rFinish() */.   
7e70: 20 20 20 46 69 6c 65 57 72 69 74 65 72 20 77 72     FileWriter wr
7e80: 69 74 65 72 3b 20 20 20 20 20 20 20 20 20 20 2f  iter;          /
7e90: 2a 20 4f 62 6a 65 63 74 20 75 73 65 64 20 74 6f  * Object used to
7ea0: 20 77 72 69 74 65 20 74 6f 20 64 69 73 6b 20 2a   write to disk *
7eb0: 2f 0a 20 20 20 20 20 20 69 36 34 20 6e 57 72 69  /.      i64 nWri
7ec0: 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  te;             
7ed0: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
7ee0: 20 62 79 74 65 73 20 69 6e 20 6e 65 77 20 50 4d   bytes in new PM
7ef0: 41 20 2a 2f 0a 0a 20 20 20 20 20 20 6d 65 6d 73  A */..      mems
7f00: 65 74 28 26 77 72 69 74 65 72 2c 20 30 2c 20 73  et(&writer, 0, s
7f10: 69 7a 65 6f 66 28 46 69 6c 65 57 72 69 74 65 72  izeof(FileWriter
7f20: 29 29 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 49 66  ));..      /* If
7f30: 20 74 68 65 72 65 20 61 72 65 20 53 4f 52 54 45   there are SORTE
7f40: 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
7f50: 54 20 6f 72 20 6c 65 73 73 20 50 4d 41 73 20 69  T or less PMAs i
7f60: 6e 20 66 69 6c 65 20 70 54 65 6d 70 31 2c 0a 20  n file pTemp1,. 
7f70: 20 20 20 20 20 2a 2a 20 69 6e 69 74 69 61 6c 69       ** initiali
7f80: 7a 65 20 61 6e 20 69 74 65 72 61 74 6f 72 20 66  ze an iterator f
7f90: 6f 72 20 65 61 63 68 20 6f 66 20 74 68 65 6d 20  or each of them 
7fa0: 61 6e 64 20 62 72 65 61 6b 20 6f 75 74 20 6f 66  and break out of
7fb0: 20 74 68 65 20 6c 6f 6f 70 2e 0a 20 20 20 20 20   the loop..     
7fc0: 20 2a 2a 20 54 68 65 73 65 20 69 74 65 72 61 74   ** These iterat
7fd0: 6f 72 73 20 77 69 6c 6c 20 62 65 20 69 6e 63 72  ors will be incr
7fe0: 65 6d 65 6e 74 61 6c 6c 79 20 6d 65 72 67 65 64  ementally merged
7ff0: 20 61 73 20 74 68 65 20 56 44 42 45 20 6c 61 79   as the VDBE lay
8000: 65 72 20 63 61 6c 6c 73 0a 20 20 20 20 20 20 2a  er calls.      *
8010: 2a 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72  * sqlite3VdbeSor
8020: 74 65 72 4e 65 78 74 28 29 2e 0a 20 20 20 20 20  terNext()..     
8030: 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 4f 74 68   **.      ** Oth
8040: 65 72 77 69 73 65 2c 20 69 66 20 70 54 65 6d 70  erwise, if pTemp
8050: 31 20 63 6f 6e 74 61 69 6e 73 20 6d 6f 72 65 20  1 contains more 
8060: 74 68 61 6e 20 53 4f 52 54 45 52 5f 4d 41 58 5f  than SORTER_MAX_
8070: 4d 45 52 47 45 5f 43 4f 55 4e 54 20 50 4d 41 73  MERGE_COUNT PMAs
8080: 2c 0a 20 20 20 20 20 20 2a 2a 20 69 6e 69 74 69  ,.      ** initi
8090: 61 6c 69 7a 65 20 69 6e 74 65 72 61 74 6f 72 73  alize interators
80a0: 20 66 6f 72 20 53 4f 52 54 45 52 5f 4d 41 58 5f   for SORTER_MAX_
80b0: 4d 45 52 47 45 5f 43 4f 55 4e 54 20 6f 66 20 74  MERGE_COUNT of t
80c0: 68 65 6d 2e 20 54 68 65 73 65 20 50 4d 41 73 0a  hem. These PMAs.
80d0: 20 20 20 20 20 20 2a 2a 20 61 72 65 20 6d 65 72        ** are mer
80e0: 67 65 64 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c  ged into a singl
80f0: 65 20 50 4d 41 20 74 68 61 74 20 69 73 20 77 72  e PMA that is wr
8100: 69 74 74 65 6e 20 74 6f 20 66 69 6c 65 20 70 54  itten to file pT
8110: 65 6d 70 32 2e 0a 20 20 20 20 20 20 2a 2f 0a 20  emp2..      */. 
8120: 20 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f       rc = vdbeSo
8130: 72 74 65 72 49 6e 69 74 4d 65 72 67 65 28 70 53  rterInitMerge(pS
8140: 6f 72 74 65 72 2c 20 26 6e 57 72 69 74 65 29 3b  orter, &nWrite);
8150: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 72  .      assert( r
8160: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20  c!=SQLITE_OK || 
8170: 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b 20  pSorter->aIter[ 
8180: 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 31  pSorter->aTree[1
8190: 5d 20 5d 2e 70 46 69 6c 65 20 29 3b 0a 20 20 20  ] ].pFile );.   
81a0: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
81b0: 45 5f 4f 4b 20 7c 7c 20 70 53 6f 72 74 65 72 2d  E_OK || pSorter-
81c0: 3e 6e 50 4d 41 3c 3d 53 4f 52 54 45 52 5f 4d 41  >nPMA<=SORTER_MA
81d0: 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20 29 7b  X_MERGE_COUNT ){
81e0: 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
81f0: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f        }..      /
8200: 2a 20 4f 70 65 6e 20 74 68 65 20 73 65 63 6f 6e  * Open the secon
8210: 64 20 74 65 6d 70 20 66 69 6c 65 2c 20 69 66 20  d temp file, if 
8220: 69 74 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64  it is not alread
8230: 79 20 6f 70 65 6e 2e 20 2a 2f 0a 20 20 20 20 20  y open. */.     
8240: 20 69 66 28 20 70 54 65 6d 70 32 3d 3d 30 20 29   if( pTemp2==0 )
8250: 7b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  {.        assert
8260: 28 20 69 57 72 69 74 65 32 3d 3d 30 20 29 3b 0a  ( iWrite2==0 );.
8270: 20 20 20 20 20 20 20 20 72 63 20 3d 20 76 64 62          rc = vdb
8280: 65 53 6f 72 74 65 72 4f 70 65 6e 54 65 6d 70 46  eSorterOpenTempF
8290: 69 6c 65 28 64 62 2c 20 26 70 54 65 6d 70 32 29  ile(db, &pTemp2)
82a0: 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  ;.      }..     
82b0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
82c0: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e  OK ){.        in
82d0: 74 20 62 45 6f 66 20 3d 20 30 3b 0a 20 20 20 20  t bEof = 0;.    
82e0: 20 20 20 20 66 69 6c 65 57 72 69 74 65 72 49 6e      fileWriterIn
82f0: 69 74 28 64 62 2c 20 70 54 65 6d 70 32 2c 20 26  it(db, pTemp2, &
8300: 77 72 69 74 65 72 2c 20 69 57 72 69 74 65 32 29  writer, iWrite2)
8310: 3b 0a 20 20 20 20 20 20 20 20 66 69 6c 65 57 72  ;.        fileWr
8320: 69 74 65 72 57 72 69 74 65 56 61 72 69 6e 74 28  iterWriteVarint(
8330: 26 77 72 69 74 65 72 2c 20 6e 57 72 69 74 65 29  &writer, nWrite)
8340: 3b 0a 20 20 20 20 20 20 20 20 77 68 69 6c 65 28  ;.        while(
8350: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
8360: 26 20 62 45 6f 66 3d 3d 30 20 29 7b 0a 20 20 20  & bEof==0 ){.   
8370: 20 20 20 20 20 20 20 56 64 62 65 53 6f 72 74 65         VdbeSorte
8380: 72 49 74 65 72 20 2a 70 49 74 65 72 20 3d 20 26  rIter *pIter = &
8390: 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b 20  pSorter->aIter[ 
83a0: 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 31  pSorter->aTree[1
83b0: 5d 20 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 61  ] ];.          a
83c0: 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e 70 46  ssert( pIter->pF
83d0: 69 6c 65 20 29 3b 0a 0a 20 20 20 20 20 20 20 20  ile );..        
83e0: 20 20 66 69 6c 65 57 72 69 74 65 72 57 72 69 74    fileWriterWrit
83f0: 65 56 61 72 69 6e 74 28 26 77 72 69 74 65 72 2c  eVarint(&writer,
8400: 20 70 49 74 65 72 2d 3e 6e 4b 65 79 29 3b 0a 20   pIter->nKey);. 
8410: 20 20 20 20 20 20 20 20 20 66 69 6c 65 57 72 69           fileWri
8420: 74 65 72 57 72 69 74 65 28 26 77 72 69 74 65 72  terWrite(&writer
8430: 2c 20 70 49 74 65 72 2d 3e 61 4b 65 79 2c 20 70  , pIter->aKey, p
8440: 49 74 65 72 2d 3e 6e 4b 65 79 29 3b 0a 20 20 20  Iter->nKey);.   
8450: 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69         rc = sqli
8460: 74 65 33 56 64 62 65 53 6f 72 74 65 72 4e 65 78  te3VdbeSorterNex
8470: 74 28 70 43 73 72 2c 20 26 62 45 6f 66 29 3b 0a  t(pCsr, &bEof);.
8480: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
8490: 20 20 72 63 32 20 3d 20 66 69 6c 65 57 72 69 74    rc2 = fileWrit
84a0: 65 72 46 69 6e 69 73 68 28 64 62 2c 20 26 77 72  erFinish(db, &wr
84b0: 69 74 65 72 2c 20 26 69 57 72 69 74 65 32 29 3b  iter, &iWrite2);
84c0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d  .        if( rc=
84d0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20  =SQLITE_OK ) rc 
84e0: 3d 20 72 63 32 3b 0a 20 20 20 20 20 20 7d 0a 20  = rc2;.      }. 
84f0: 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 70 53     }..    if( pS
8500: 6f 72 74 65 72 2d 3e 6e 50 4d 41 3c 3d 53 4f 52  orter->nPMA<=SOR
8510: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
8520: 55 4e 54 20 29 7b 0a 20 20 20 20 20 20 62 72 65  UNT ){.      bre
8530: 61 6b 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ak;.    }else{. 
8540: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6c       sqlite3_fil
8550: 65 20 2a 70 54 6d 70 20 3d 20 70 53 6f 72 74 65  e *pTmp = pSorte
8560: 72 2d 3e 70 54 65 6d 70 31 3b 0a 20 20 20 20 20  r->pTemp1;.     
8570: 20 70 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 20 3d   pSorter->nPMA =
8580: 20 69 4e 65 77 3b 0a 20 20 20 20 20 20 70 53 6f   iNew;.      pSo
8590: 72 74 65 72 2d 3e 70 54 65 6d 70 31 20 3d 20 70  rter->pTemp1 = p
85a0: 54 65 6d 70 32 3b 0a 20 20 20 20 20 20 70 54 65  Temp2;.      pTe
85b0: 6d 70 32 20 3d 20 70 54 6d 70 3b 0a 20 20 20 20  mp2 = pTmp;.    
85c0: 20 20 70 53 6f 72 74 65 72 2d 3e 69 57 72 69 74    pSorter->iWrit
85d0: 65 4f 66 66 20 3d 20 69 57 72 69 74 65 32 3b 0a  eOff = iWrite2;.
85e0: 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 69        pSorter->i
85f0: 52 65 61 64 4f 66 66 20 3d 20 30 3b 0a 20 20 20  ReadOff = 0;.   
8600: 20 20 20 69 57 72 69 74 65 32 20 3d 20 30 3b 0a     iWrite2 = 0;.
8610: 20 20 20 20 7d 0a 20 20 7d 77 68 69 6c 65 28 20      }.  }while( 
8620: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b  rc==SQLITE_OK );
8630: 0a 0a 20 20 69 66 28 20 70 54 65 6d 70 32 20 29  ..  if( pTemp2 )
8640: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43  {.    sqlite3OsC
8650: 6c 6f 73 65 46 72 65 65 28 70 54 65 6d 70 32 29  loseFree(pTemp2)
8660: 3b 0a 20 20 7d 0a 20 20 2a 70 62 45 6f 66 20 3d  ;.  }.  *pbEof =
8670: 20 28 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72   (pSorter->aIter
8680: 5b 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b  [pSorter->aTree[
8690: 31 5d 5d 2e 70 46 69 6c 65 3d 3d 30 29 3b 0a 20  1]].pFile==0);. 
86a0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
86b0: 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 74 6f 20  *.** Advance to 
86c0: 74 68 65 20 6e 65 78 74 20 65 6c 65 6d 65 6e 74  the next element
86d0: 20 69 6e 20 74 68 65 20 73 6f 72 74 65 72 2e 0a   in the sorter..
86e0: 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64  */.int sqlite3Vd
86f0: 62 65 53 6f 72 74 65 72 4e 65 78 74 28 63 6f 6e  beSorterNext(con
8700: 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70  st VdbeCursor *p
8710: 43 73 72 2c 20 69 6e 74 20 2a 70 62 45 6f 66 29  Csr, int *pbEof)
8720: 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a  {.  VdbeSorter *
8730: 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e  pSorter = pCsr->
8740: 70 53 6f 72 74 65 72 3b 0a 20 20 73 71 6c 69 74  pSorter;.  sqlit
8750: 65 33 20 2a 64 62 20 3d 20 70 53 6f 72 74 65 72  e3 *db = pSorter
8760: 2d 3e 64 62 3b 0a 20 20 69 6e 74 20 72 63 3b 20  ->db;.  int rc; 
8770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8780: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
8790: 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 69 66 28  n code */..  if(
87a0: 20 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 20   pSorter->aTree 
87b0: 29 7b 0a 20 20 20 20 69 6e 74 20 69 50 72 65 76  ){.    int iPrev
87c0: 20 3d 20 70 53 6f 72 74 65 72 2d 3e 61 54 72 65   = pSorter->aTre
87d0: 65 5b 31 5d 3b 2f 2a 20 49 6e 64 65 78 20 6f 66  e[1];/* Index of
87e0: 20 69 74 65 72 61 74 6f 72 20 74 6f 20 61 64 76   iterator to adv
87f0: 61 6e 63 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20  ance */.    int 
8800: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
8810: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64            /* Ind
8820: 65 78 20 6f 66 20 61 54 72 65 65 5b 5d 20 74 6f  ex of aTree[] to
8830: 20 72 65 63 61 6c 63 75 6c 61 74 65 20 2a 2f 0a   recalculate */.
8840: 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f  .    rc = vdbeSo
8850: 72 74 65 72 49 74 65 72 4e 65 78 74 28 26 70 53  rterIterNext(&pS
8860: 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b 69 50 72  orter->aIter[iPr
8870: 65 76 5d 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d  ev]);.    for(i=
8880: 28 70 53 6f 72 74 65 72 2d 3e 6e 54 72 65 65 2b  (pSorter->nTree+
8890: 69 50 72 65 76 29 2f 32 3b 20 72 63 3d 3d 53 51  iPrev)/2; rc==SQ
88a0: 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3e 30 3b 20  LITE_OK && i>0; 
88b0: 69 3d 69 2f 32 29 7b 0a 20 20 20 20 20 20 72 63  i=i/2){.      rc
88c0: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 44 6f 43   = vdbeSorterDoC
88d0: 6f 6d 70 61 72 65 28 70 53 6f 72 74 65 72 2c 20  ompare(pSorter, 
88e0: 69 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2a  i);.    }..    *
88f0: 70 62 45 6f 66 20 3d 20 28 70 53 6f 72 74 65 72  pbEof = (pSorter
8900: 2d 3e 61 49 74 65 72 5b 70 53 6f 72 74 65 72 2d  ->aIter[pSorter-
8910: 3e 61 54 72 65 65 5b 31 5d 5d 2e 70 46 69 6c 65  >aTree[1]].pFile
8920: 3d 3d 30 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  ==0);.  }else{. 
8930: 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20     SorterRecord 
8940: 2a 70 46 72 65 65 20 3d 20 70 53 6f 72 74 65 72  *pFree = pSorter
8950: 2d 3e 70 52 65 63 6f 72 64 3b 0a 20 20 20 20 70  ->pRecord;.    p
8960: 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20  Sorter->pRecord 
8970: 3d 20 70 46 72 65 65 2d 3e 70 4e 65 78 74 3b 0a  = pFree->pNext;.
8980: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6e 52 65      pSorter->nRe
8990: 63 6f 72 64 2d 2d 3b 0a 20 20 20 20 70 46 72 65  cord--;.    pFre
89a0: 65 2d 3e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20  e->pNext = 0;.  
89b0: 20 20 76 64 62 65 53 6f 72 74 65 72 52 65 63 6f    vdbeSorterReco
89c0: 72 64 46 72 65 65 28 64 62 2c 20 70 46 72 65 65  rdFree(db, pFree
89d0: 29 3b 0a 20 20 20 20 2a 70 62 45 6f 66 20 3d 20  );.    *pbEof = 
89e0: 21 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72  !pSorter->pRecor
89f0: 64 3b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49  d;.    rc = SQLI
8a00: 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 20 20 72 65 74  TE_OK;.  }.  ret
8a10: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
8a20: 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65   Return a pointe
8a30: 72 20 74 6f 20 61 20 62 75 66 66 65 72 20 6f 77  r to a buffer ow
8a40: 6e 65 64 20 62 79 20 74 68 65 20 73 6f 72 74 65  ned by the sorte
8a50: 72 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20  r that contains 
8a60: 74 68 65 20 0a 2a 2a 20 63 75 72 72 65 6e 74 20  the .** current 
8a70: 6b 65 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  key..*/.static v
8a80: 6f 69 64 20 2a 76 64 62 65 53 6f 72 74 65 72 52  oid *vdbeSorterR
8a90: 6f 77 6b 65 79 28 0a 20 20 63 6f 6e 73 74 20 56  owkey(.  const V
8aa0: 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
8ab0: 65 72 2c 20 20 20 20 20 20 2f 2a 20 53 6f 72 74  er,      /* Sort
8ac0: 65 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69  er object */.  i
8ad0: 6e 74 20 2a 70 6e 4b 65 79 20 20 20 20 20 20 20  nt *pnKey       
8ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8af0: 2a 20 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20 63  * OUT: Size of c
8b00: 75 72 72 65 6e 74 20 6b 65 79 20 69 6e 20 62 79  urrent key in by
8b10: 74 65 73 20 2a 2f 0a 29 7b 0a 20 20 76 6f 69 64  tes */.){.  void
8b20: 20 2a 70 4b 65 79 3b 0a 20 20 69 66 28 20 70 53   *pKey;.  if( pS
8b30: 6f 72 74 65 72 2d 3e 61 54 72 65 65 20 29 7b 0a  orter->aTree ){.
8b40: 20 20 20 20 56 64 62 65 53 6f 72 74 65 72 49 74      VdbeSorterIt
8b50: 65 72 20 2a 70 49 74 65 72 3b 0a 20 20 20 20 70  er *pIter;.    p
8b60: 49 74 65 72 20 3d 20 26 70 53 6f 72 74 65 72 2d  Iter = &pSorter-
8b70: 3e 61 49 74 65 72 5b 20 70 53 6f 72 74 65 72 2d  >aIter[ pSorter-
8b80: 3e 61 54 72 65 65 5b 31 5d 20 5d 3b 0a 20 20 20  >aTree[1] ];.   
8b90: 20 2a 70 6e 4b 65 79 20 3d 20 70 49 74 65 72 2d   *pnKey = pIter-
8ba0: 3e 6e 4b 65 79 3b 0a 20 20 20 20 70 4b 65 79 20  >nKey;.    pKey 
8bb0: 3d 20 70 49 74 65 72 2d 3e 61 4b 65 79 3b 0a 20  = pIter->aKey;. 
8bc0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2a 70 6e 4b   }else{.    *pnK
8bd0: 65 79 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 52  ey = pSorter->pR
8be0: 65 63 6f 72 64 2d 3e 6e 56 61 6c 3b 0a 20 20 20  ecord->nVal;.   
8bf0: 20 70 4b 65 79 20 3d 20 70 53 6f 72 74 65 72 2d   pKey = pSorter-
8c00: 3e 70 52 65 63 6f 72 64 2d 3e 70 56 61 6c 3b 0a  >pRecord->pVal;.
8c10: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 4b 65    }.  return pKe
8c20: 79 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79  y;.}../*.** Copy
8c30: 20 74 68 65 20 63 75 72 72 65 6e 74 20 73 6f 72   the current sor
8c40: 74 65 72 20 6b 65 79 20 69 6e 74 6f 20 74 68 65  ter key into the
8c50: 20 6d 65 6d 6f 72 79 20 63 65 6c 6c 20 70 4f 75   memory cell pOu
8c60: 74 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  t..*/.int sqlite
8c70: 33 56 64 62 65 53 6f 72 74 65 72 52 6f 77 6b 65  3VdbeSorterRowke
8c80: 79 28 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73  y(const VdbeCurs
8c90: 6f 72 20 2a 70 43 73 72 2c 20 4d 65 6d 20 2a 70  or *pCsr, Mem *p
8ca0: 4f 75 74 29 7b 0a 20 20 56 64 62 65 53 6f 72 74  Out){.  VdbeSort
8cb0: 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43  er *pSorter = pC
8cc0: 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 76  sr->pSorter;.  v
8cd0: 6f 69 64 20 2a 70 4b 65 79 3b 20 69 6e 74 20 6e  oid *pKey; int n
8ce0: 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 2f  Key;           /
8cf0: 2a 20 53 6f 72 74 65 72 20 6b 65 79 20 74 6f 20  * Sorter key to 
8d00: 63 6f 70 79 20 69 6e 74 6f 20 70 4f 75 74 20 2a  copy into pOut *
8d10: 2f 0a 0a 20 20 70 4b 65 79 20 3d 20 76 64 62 65  /..  pKey = vdbe
8d20: 53 6f 72 74 65 72 52 6f 77 6b 65 79 28 70 53 6f  SorterRowkey(pSo
8d30: 72 74 65 72 2c 20 26 6e 4b 65 79 29 3b 0a 20 20  rter, &nKey);.  
8d40: 69 66 28 20 73 71 6c 69 74 65 33 56 64 62 65 4d  if( sqlite3VdbeM
8d50: 65 6d 47 72 6f 77 28 70 4f 75 74 2c 20 6e 4b 65  emGrow(pOut, nKe
8d60: 79 2c 20 30 29 20 29 7b 0a 20 20 20 20 72 65 74  y, 0) ){.    ret
8d70: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
8d80: 3b 0a 20 20 7d 0a 20 20 70 4f 75 74 2d 3e 6e 20  ;.  }.  pOut->n 
8d90: 3d 20 6e 4b 65 79 3b 0a 20 20 4d 65 6d 53 65 74  = nKey;.  MemSet
8da0: 54 79 70 65 46 6c 61 67 28 70 4f 75 74 2c 20 4d  TypeFlag(pOut, M
8db0: 45 4d 5f 42 6c 6f 62 29 3b 0a 20 20 6d 65 6d 63  EM_Blob);.  memc
8dc0: 70 79 28 70 4f 75 74 2d 3e 7a 2c 20 70 4b 65 79  py(pOut->z, pKey
8dd0: 2c 20 6e 4b 65 79 29 3b 0a 0a 20 20 72 65 74 75  , nKey);..  retu
8de0: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
8df0: 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 61 72 65 20 74  ./*.** Compare t
8e00: 68 65 20 6b 65 79 20 69 6e 20 6d 65 6d 6f 72 79  he key in memory
8e10: 20 63 65 6c 6c 20 70 56 61 6c 20 77 69 74 68 20   cell pVal with 
8e20: 74 68 65 20 6b 65 79 20 74 68 61 74 20 74 68 65  the key that the
8e30: 20 73 6f 72 74 65 72 20 63 75 72 73 6f 72 0a 2a   sorter cursor.*
8e40: 2a 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20  * passed as the 
8e50: 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 63  first argument c
8e60: 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20  urrently points 
8e70: 74 6f 2e 20 46 6f 72 20 74 68 65 20 70 75 72 70  to. For the purp
8e80: 6f 73 65 73 20 6f 66 0a 2a 2a 20 74 68 65 20 63  oses of.** the c
8e90: 6f 6d 70 61 72 69 73 6f 6e 2c 20 69 67 6e 6f 72  omparison, ignor
8ea0: 65 20 74 68 65 20 72 6f 77 69 64 20 66 69 65 6c  e the rowid fiel
8eb0: 64 20 61 74 20 74 68 65 20 65 6e 64 20 6f 66 20  d at the end of 
8ec0: 65 61 63 68 20 72 65 63 6f 72 64 2e 0a 2a 2a 0a  each record..**.
8ed0: 2a 2a 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f  ** If an error o
8ee0: 63 63 75 72 73 2c 20 72 65 74 75 72 6e 20 61 6e  ccurs, return an
8ef0: 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
8f00: 64 65 20 28 69 2e 65 2e 20 53 51 4c 49 54 45 5f  de (i.e. SQLITE_
8f10: 4e 4f 4d 45 4d 29 2e 0a 2a 2a 20 4f 74 68 65 72  NOMEM)..** Other
8f20: 77 69 73 65 2c 20 73 65 74 20 2a 70 52 65 73 20  wise, set *pRes 
8f30: 74 6f 20 61 20 6e 65 67 61 74 69 76 65 2c 20 7a  to a negative, z
8f40: 65 72 6f 20 6f 72 20 70 6f 73 69 74 69 76 65 20  ero or positive 
8f50: 76 61 6c 75 65 20 69 66 20 74 68 65 0a 2a 2a 20  value if the.** 
8f60: 6b 65 79 20 69 6e 20 70 56 61 6c 20 69 73 20 73  key in pVal is s
8f70: 6d 61 6c 6c 65 72 20 74 68 61 6e 2c 20 65 71 75  maller than, equ
8f80: 61 6c 20 74 6f 20 6f 72 20 6c 61 72 67 65 72 20  al to or larger 
8f90: 74 68 61 6e 20 74 68 65 20 63 75 72 72 65 6e 74  than the current
8fa0: 20 73 6f 72 74 65 72 0a 2a 2a 20 6b 65 79 2e 0a   sorter.** key..
8fb0: 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64  */.int sqlite3Vd
8fc0: 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28  beSorterCompare(
8fd0: 0a 20 20 63 6f 6e 73 74 20 56 64 62 65 43 75 72  .  const VdbeCur
8fe0: 73 6f 72 20 2a 70 43 73 72 2c 20 20 20 20 20 20  sor *pCsr,      
8ff0: 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 63 75 72     /* Sorter cur
9000: 73 6f 72 20 2a 2f 0a 20 20 4d 65 6d 20 2a 70 56  sor */.  Mem *pV
9010: 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
9020: 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75           /* Valu
9030: 65 20 74 6f 20 63 6f 6d 70 61 72 65 20 74 6f 20  e to compare to 
9040: 63 75 72 72 65 6e 74 20 73 6f 72 74 65 72 20 6b  current sorter k
9050: 65 79 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 52 65  ey */.  int *pRe
9060: 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s               
9070: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
9080: 52 65 73 75 6c 74 20 6f 66 20 63 6f 6d 70 61 72  Result of compar
9090: 69 73 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 56 64 62  ison */.){.  Vdb
90a0: 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72  eSorter *pSorter
90b0: 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72   = pCsr->pSorter
90c0: 3b 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 3b 20  ;.  void *pKey; 
90d0: 69 6e 74 20 6e 4b 65 79 3b 20 20 20 20 20 20 20  int nKey;       
90e0: 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 6b 65      /* Sorter ke
90f0: 79 20 74 6f 20 63 6f 6d 70 61 72 65 20 70 56 61  y to compare pVa
9100: 6c 20 77 69 74 68 20 2a 2f 0a 0a 20 20 70 4b 65  l with */..  pKe
9110: 79 20 3d 20 76 64 62 65 53 6f 72 74 65 72 52 6f  y = vdbeSorterRo
9120: 77 6b 65 79 28 70 53 6f 72 74 65 72 2c 20 26 6e  wkey(pSorter, &n
9130: 4b 65 79 29 3b 0a 20 20 76 64 62 65 53 6f 72 74  Key);.  vdbeSort
9140: 65 72 43 6f 6d 70 61 72 65 28 70 53 6f 72 74 65  erCompare(pSorte
9150: 72 2c 20 31 2c 20 70 56 61 6c 2d 3e 7a 2c 20 70  r, 1, pVal->z, p
9160: 56 61 6c 2d 3e 6e 2c 20 70 4b 65 79 2c 20 6e 4b  Val->n, pKey, nK
9170: 65 79 2c 20 70 52 65 73 2c 0a 20 20 20 20 20 20  ey, pRes,.      
9180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 53                pS
9190: 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64  orter->pUnpacked
91a0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  );.  return SQLI
91b0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64 69 66  TE_OK;.}..#endif
91c0: 20 2f 2a 20 23 69 66 6e 64 65 66 20 53 51 4c 49   /* #ifndef SQLI
91d0: 54 45 5f 4f 4d 49 54 5f 4d 45 52 47 45 5f 53 4f  TE_OMIT_MERGE_SO
91e0: 52 54 20 2a 2f 0a                                RT */.