/ Hex Artifact Content
Login

Artifact c61ca318681c0e7267da8be3abfca8469652a7e9:


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 55 6e 70 61 63 6b  list */.  Unpack
12b0: 65 64 52 65 63 6f 72 64 20 2a 70 55 6e 70 61 63  edRecord *pUnpac
12c0: 6b 65 64 3b 20 20 20 20 20 20 2f 2a 20 55 73 65  ked;      /* Use
12d0: 64 20 74 6f 20 75 6e 70 61 63 6b 20 6b 65 79 73  d to unpack keys
12e0: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68   */.};../*.** Th
12f0: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 79 70 65  e following type
1300: 20 69 73 20 61 6e 20 69 74 65 72 61 74 6f 72 20   is an iterator 
1310: 66 6f 72 20 61 20 50 4d 41 2e 20 49 74 20 63 61  for a PMA. It ca
1320: 63 68 65 73 20 74 68 65 20 63 75 72 72 65 6e 74  ches the current
1330: 20 6b 65 79 20 69 6e 20 0a 2a 2a 20 76 61 72 69   key in .** vari
1340: 61 62 6c 65 73 20 6e 4b 65 79 2f 61 4b 65 79 2e  ables nKey/aKey.
1350: 20 49 66 20 74 68 65 20 69 74 65 72 61 74 6f 72   If the iterator
1360: 20 69 73 20 61 74 20 45 4f 46 2c 20 70 46 69 6c   is at EOF, pFil
1370: 65 3d 3d 30 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  e==0..*/.struct 
1380: 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 7b  VdbeSorterIter {
1390: 0a 20 20 69 36 34 20 69 52 65 61 64 4f 66 66 3b  .  i64 iReadOff;
13a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13b0: 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 72 65     /* Current re
13c0: 61 64 20 6f 66 66 73 65 74 20 2a 2f 0a 20 20 69  ad offset */.  i
13d0: 36 34 20 69 45 6f 66 3b 20 20 20 20 20 20 20 20  64 iEof;        
13e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
13f0: 2a 20 31 20 62 79 74 65 20 70 61 73 74 20 45 4f  * 1 byte past EO
1400: 46 20 66 6f 72 20 74 68 69 73 20 69 74 65 72 61  F for this itera
1410: 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 6c  tor */.  int nAl
1420: 6c 6f 63 3b 20 20 20 20 20 20 20 20 20 20 20 20  loc;            
1430: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65           /* Byte
1440: 73 20 6f 66 20 73 70 61 63 65 20 61 74 20 61 41  s of space at aA
1450: 6c 6c 6f 63 20 2a 2f 0a 20 20 69 6e 74 20 6e 4b  lloc */.  int nK
1460: 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ey;             
1470: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
1480: 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
1490: 6b 65 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  key */.  sqlite3
14a0: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20  _file *pFile;   
14b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65           /* File
14c0: 20 69 74 65 72 61 74 6f 72 20 69 73 20 72 65 61   iterator is rea
14d0: 64 69 6e 67 20 66 72 6f 6d 20 2a 2f 0a 20 20 75  ding from */.  u
14e0: 38 20 2a 61 41 6c 6c 6f 63 3b 20 20 20 20 20 20  8 *aAlloc;      
14f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1500: 2a 20 41 6c 6c 6f 63 61 74 65 64 20 73 70 61 63  * Allocated spac
1510: 65 20 2a 2f 0a 20 20 75 38 20 2a 61 4b 65 79 3b  e */.  u8 *aKey;
1520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1530: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
1540: 72 20 74 6f 20 63 75 72 72 65 6e 74 20 6b 65 79  r to current key
1550: 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75 66 66 65   */.  u8 *aBuffe
1560: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
1570: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
1580: 20 72 65 61 64 20 62 75 66 66 65 72 20 2a 2f 0a   read buffer */.
1590: 20 20 69 6e 74 20 6e 42 75 66 66 65 72 3b 20 20    int nBuffer;  
15a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15b0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 72 65 61    /* Size of rea
15c0: 64 20 62 75 66 66 65 72 20 69 6e 20 62 79 74 65  d buffer in byte
15d0: 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41  s */.};../*.** A
15e0: 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68  n instance of th
15f0: 69 73 20 73 74 72 75 63 74 75 72 65 20 69 73 20  is structure is 
1600: 75 73 65 64 20 74 6f 20 6f 72 67 61 6e 69 7a 65  used to organize
1610: 20 74 68 65 20 73 74 72 65 61 6d 20 6f 66 20 72   the stream of r
1620: 65 63 6f 72 64 73 0a 2a 2a 20 62 65 69 6e 67 20  ecords.** being 
1630: 77 72 69 74 74 65 6e 20 74 6f 20 66 69 6c 65 73  written to files
1640: 20 62 79 20 74 68 65 20 6d 65 72 67 65 2d 73 6f   by the merge-so
1650: 72 74 20 63 6f 64 65 20 69 6e 74 6f 20 61 6c 69  rt code into ali
1660: 67 6e 65 64 2c 20 70 61 67 65 2d 73 69 7a 65 64  gned, page-sized
1670: 0a 2a 2a 20 62 6c 6f 63 6b 73 2e 20 20 44 6f 69  .** blocks.  Doi
1680: 6e 67 20 61 6c 6c 20 49 2f 4f 20 69 6e 20 61 6c  ng all I/O in al
1690: 69 67 6e 65 64 20 70 61 67 65 2d 73 69 7a 65 64  igned page-sized
16a0: 20 62 6c 6f 63 6b 73 20 68 65 6c 70 73 20 49 2f   blocks helps I/
16b0: 4f 20 74 6f 20 67 6f 0a 2a 2a 20 66 61 73 74 65  O to go.** faste
16c0: 72 20 6f 6e 20 6d 61 6e 79 20 6f 70 65 72 61 74  r on many operat
16d0: 69 6e 67 20 73 79 73 74 65 6d 73 2e 0a 2a 2f 0a  ing systems..*/.
16e0: 73 74 72 75 63 74 20 46 69 6c 65 57 72 69 74 65  struct FileWrite
16f0: 72 20 7b 0a 20 20 69 6e 74 20 65 46 57 45 72 72  r {.  int eFWErr
1700: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1710: 20 20 20 20 20 20 2f 2a 20 4e 6f 6e 2d 7a 65 72        /* Non-zer
1720: 6f 20 69 66 20 69 6e 20 61 6e 20 65 72 72 6f 72  o if in an error
1730: 20 73 74 61 74 65 20 2a 2f 0a 20 20 75 38 20 2a   state */.  u8 *
1740: 61 42 75 66 66 65 72 3b 20 20 20 20 20 20 20 20  aBuffer;        
1750: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
1760: 6f 69 6e 74 65 72 20 74 6f 20 77 72 69 74 65 20  ointer to write 
1770: 62 75 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74 20  buffer */.  int 
1780: 6e 42 75 66 66 65 72 3b 20 20 20 20 20 20 20 20  nBuffer;        
1790: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
17a0: 69 7a 65 20 6f 66 20 77 72 69 74 65 20 62 75 66  ize of write buf
17b0: 66 65 72 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  fer in bytes */.
17c0: 20 20 69 6e 74 20 69 42 75 66 53 74 61 72 74 3b    int iBufStart;
17d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17e0: 20 20 2f 2a 20 46 69 72 73 74 20 62 79 74 65 20    /* First byte 
17f0: 6f 66 20 62 75 66 66 65 72 20 74 6f 20 77 72 69  of buffer to wri
1800: 74 65 20 2a 2f 0a 20 20 69 6e 74 20 69 42 75 66  te */.  int iBuf
1810: 45 6e 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  End;            
1820: 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 73 74 20          /* Last 
1830: 62 79 74 65 20 6f 66 20 62 75 66 66 65 72 20 74  byte of buffer t
1840: 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 69 36 34  o write */.  i64
1850: 20 69 57 72 69 74 65 4f 66 66 3b 20 20 20 20 20   iWriteOff;     
1860: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1870: 4f 66 66 73 65 74 20 6f 66 20 73 74 61 72 74 20  Offset of start 
1880: 6f 66 20 62 75 66 66 65 72 20 69 6e 20 66 69 6c  of buffer in fil
1890: 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66  e */.  sqlite3_f
18a0: 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20 20 20  ile *pFile;     
18b0: 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 74         /* File t
18c0: 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a 7d 3b  o write to */.};
18d0: 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 74 72 75 63 74  ../*.** A struct
18e0: 75 72 65 20 74 6f 20 73 74 6f 72 65 20 61 20 73  ure to store a s
18f0: 69 6e 67 6c 65 20 72 65 63 6f 72 64 2e 20 41 6c  ingle record. Al
1900: 6c 20 69 6e 2d 6d 65 6d 6f 72 79 20 72 65 63 6f  l in-memory reco
1910: 72 64 73 20 61 72 65 20 63 6f 6e 6e 65 63 74 65  rds are connecte
1920: 64 0a 2a 2a 20 74 6f 67 65 74 68 65 72 20 69 6e  d.** together in
1930: 74 6f 20 61 20 6c 69 6e 6b 65 64 20 6c 69 73 74  to a linked list
1940: 20 68 65 61 64 65 64 20 61 74 20 56 64 62 65 53   headed at VdbeS
1950: 6f 72 74 65 72 2e 70 52 65 63 6f 72 64 20 75 73  orter.pRecord us
1960: 69 6e 67 20 74 68 65 20 0a 2a 2a 20 53 6f 72 74  ing the .** Sort
1970: 65 72 52 65 63 6f 72 64 2e 70 4e 65 78 74 20 70  erRecord.pNext p
1980: 6f 69 6e 74 65 72 2e 0a 2a 2f 0a 73 74 72 75 63  ointer..*/.struc
1990: 74 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 7b  t SorterRecord {
19a0: 0a 20 20 76 6f 69 64 20 2a 70 56 61 6c 3b 0a 20  .  void *pVal;. 
19b0: 20 69 6e 74 20 6e 56 61 6c 3b 0a 20 20 53 6f 72   int nVal;.  Sor
19c0: 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65 78 74  terRecord *pNext
19d0: 3b 0a 7d 3b 0a 0a 2f 2a 20 4d 69 6e 69 6d 75 6d  ;.};../* Minimum
19e0: 20 61 6c 6c 6f 77 61 62 6c 65 20 76 61 6c 75 65   allowable value
19f0: 20 66 6f 72 20 74 68 65 20 56 64 62 65 53 6f 72   for the VdbeSor
1a00: 74 65 72 2e 6e 57 6f 72 6b 69 6e 67 20 76 61 72  ter.nWorking var
1a10: 69 61 62 6c 65 20 2a 2f 0a 23 64 65 66 69 6e 65  iable */.#define
1a20: 20 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b   SORTER_MIN_WORK
1a30: 49 4e 47 20 31 30 0a 0a 2f 2a 20 4d 61 78 69 6d  ING 10../* Maxim
1a40: 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20 73 65 67  um number of seg
1a50: 6d 65 6e 74 73 20 74 6f 20 6d 65 72 67 65 20 69  ments to merge i
1a60: 6e 20 61 20 73 69 6e 67 6c 65 20 70 61 73 73 2e  n a single pass.
1a70: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53 4f 52 54   */.#define SORT
1a80: 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55  ER_MAX_MERGE_COU
1a90: 4e 54 20 31 36 0a 0a 2f 2a 0a 2a 2a 20 46 72 65  NT 16../*.** Fre
1aa0: 65 20 61 6c 6c 20 6d 65 6d 6f 72 79 20 62 65 6c  e all memory bel
1ab0: 6f 6e 67 69 6e 67 20 74 6f 20 74 68 65 20 56 64  onging to the Vd
1ac0: 62 65 53 6f 72 74 65 72 49 74 65 72 20 6f 62 6a  beSorterIter obj
1ad0: 65 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68  ect passed as th
1ae0: 65 20 73 65 63 6f 6e 64 0a 2a 2a 20 61 72 67 75  e second.** argu
1af0: 6d 65 6e 74 2e 20 41 6c 6c 20 73 74 72 75 63 74  ment. All struct
1b00: 75 72 65 20 66 69 65 6c 64 73 20 61 72 65 20 73  ure fields are s
1b10: 65 74 20 74 6f 20 7a 65 72 6f 20 62 65 66 6f 72  et to zero befor
1b20: 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a  e returning..*/.
1b30: 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65  static void vdbe
1b40: 53 6f 72 74 65 72 49 74 65 72 5a 65 72 6f 28 73  SorterIterZero(s
1b50: 71 6c 69 74 65 33 20 2a 64 62 2c 20 56 64 62 65  qlite3 *db, Vdbe
1b60: 53 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74 65  SorterIter *pIte
1b70: 72 29 7b 0a 20 20 73 71 6c 69 74 65 33 44 62 46  r){.  sqlite3DbF
1b80: 72 65 65 28 64 62 2c 20 70 49 74 65 72 2d 3e 61  ree(db, pIter->a
1b90: 41 6c 6c 6f 63 29 3b 0a 20 20 73 71 6c 69 74 65  Alloc);.  sqlite
1ba0: 33 44 62 46 72 65 65 28 64 62 2c 20 70 49 74 65  3DbFree(db, pIte
1bb0: 72 2d 3e 61 42 75 66 66 65 72 29 3b 0a 20 20 6d  r->aBuffer);.  m
1bc0: 65 6d 73 65 74 28 70 49 74 65 72 2c 20 30 2c 20  emset(pIter, 0, 
1bd0: 73 69 7a 65 6f 66 28 56 64 62 65 53 6f 72 74 65  sizeof(VdbeSorte
1be0: 72 49 74 65 72 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  rIter));.}../*.*
1bf0: 2a 20 52 65 61 64 20 6e 42 79 74 65 20 62 79 74  * Read nByte byt
1c00: 65 73 20 6f 66 20 64 61 74 61 20 66 72 6f 6d 20  es of data from 
1c10: 74 68 65 20 73 74 72 65 61 6d 20 6f 66 20 64 61  the stream of da
1c20: 74 61 20 69 74 65 72 61 74 65 64 20 62 79 20 6f  ta iterated by o
1c30: 62 6a 65 63 74 20 70 2e 0a 2a 2a 20 49 66 20 73  bject p..** If s
1c40: 75 63 63 65 73 73 66 75 6c 2c 20 73 65 74 20 2a  uccessful, set *
1c50: 70 70 4f 75 74 20 74 6f 20 70 6f 69 6e 74 20 74  ppOut to point t
1c60: 6f 20 61 20 62 75 66 66 65 72 20 63 6f 6e 74 61  o a buffer conta
1c70: 69 6e 69 6e 67 20 74 68 65 20 64 61 74 61 0a 2a  ining the data.*
1c80: 2a 20 61 6e 64 20 72 65 74 75 72 6e 20 53 51 4c  * and return SQL
1c90: 49 54 45 5f 4f 4b 2e 20 4f 74 68 65 72 77 69 73  ITE_OK. Otherwis
1ca0: 65 2c 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f  e, if an error o
1cb0: 63 63 75 72 73 2c 20 72 65 74 75 72 6e 20 61 6e  ccurs, return an
1cc0: 20 53 51 4c 69 74 65 0a 2a 2a 20 65 72 72 6f 72   SQLite.** error
1cd0: 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65   code..**.** The
1ce0: 20 62 75 66 66 65 72 20 69 6e 64 69 63 61 74 65   buffer indicate
1cf0: 64 20 62 79 20 2a 70 70 4f 75 74 20 6d 61 79 20  d by *ppOut may 
1d00: 6f 6e 6c 79 20 62 65 20 63 6f 6e 73 69 64 65 72  only be consider
1d10: 65 64 20 76 61 6c 69 64 20 75 6e 74 69 6c 20 74  ed valid until t
1d20: 68 65 0a 2a 2a 20 6e 65 78 74 20 63 61 6c 6c 20  he.** next call 
1d30: 74 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  to this function
1d40: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
1d50: 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 52 65  vdbeSorterIterRe
1d60: 61 64 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  ad(.  sqlite3 *d
1d70: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b,              
1d80: 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
1d90: 65 20 68 61 6e 64 6c 65 20 28 66 6f 72 20 6d 61  e handle (for ma
1da0: 6c 6c 6f 63 29 20 2a 2f 0a 20 20 56 64 62 65 53  lloc) */.  VdbeS
1db0: 6f 72 74 65 72 49 74 65 72 20 2a 70 2c 20 20 20  orterIter *p,   
1dc0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 74             /* It
1dd0: 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20  erator */.  int 
1de0: 6e 42 79 74 65 2c 20 20 20 20 20 20 20 20 20 20  nByte,          
1df0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
1e00: 79 74 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20  ytes of data to 
1e10: 72 65 61 64 20 2a 2f 0a 20 20 75 38 20 2a 2a 70  read */.  u8 **p
1e20: 70 4f 75 74 20 20 20 20 20 20 20 20 20 20 20 20  pOut            
1e30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
1e40: 3a 20 50 6f 69 6e 74 65 72 20 74 6f 20 62 75 66  : Pointer to buf
1e50: 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64  fer containing d
1e60: 61 74 61 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  ata */.){.  int 
1e70: 69 42 75 66 3b 20 20 20 20 20 20 20 20 20 20 20  iBuf;           
1e80: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
1e90: 66 66 73 65 74 20 77 69 74 68 69 6e 20 62 75 66  ffset within buf
1ea0: 66 65 72 20 74 6f 20 72 65 61 64 20 66 72 6f 6d  fer to read from
1eb0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 76 61 69 6c   */.  int nAvail
1ec0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1ed0: 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f        /* Bytes o
1ee0: 66 20 64 61 74 61 20 61 76 61 69 6c 61 62 6c 65  f data available
1ef0: 20 69 6e 20 62 75 66 66 65 72 20 2a 2f 0a 20 20   in buffer */.  
1f00: 61 73 73 65 72 74 28 20 70 2d 3e 61 42 75 66 66  assert( p->aBuff
1f10: 65 72 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74  er );..  /* If t
1f20: 68 65 72 65 20 69 73 20 6e 6f 20 6d 6f 72 65 20  here is no more 
1f30: 64 61 74 61 20 74 6f 20 62 65 20 72 65 61 64 20  data to be read 
1f40: 66 72 6f 6d 20 74 68 65 20 62 75 66 66 65 72 2c  from the buffer,
1f50: 20 72 65 61 64 20 74 68 65 20 6e 65 78 74 20 0a   read the next .
1f60: 20 20 2a 2a 20 70 2d 3e 6e 42 75 66 66 65 72 20    ** p->nBuffer 
1f70: 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 66 72  bytes of data fr
1f80: 6f 6d 20 74 68 65 20 66 69 6c 65 20 69 6e 74 6f  om the file into
1f90: 20 69 74 2e 20 4f 72 2c 20 69 66 20 74 68 65 72   it. Or, if ther
1fa0: 65 20 61 72 65 20 6c 65 73 73 0a 20 20 2a 2a 20  e are less.  ** 
1fb0: 74 68 61 6e 20 70 2d 3e 6e 42 75 66 66 65 72 20  than p->nBuffer 
1fc0: 62 79 74 65 73 20 72 65 6d 61 69 6e 69 6e 67 20  bytes remaining 
1fd0: 69 6e 20 74 68 65 20 50 4d 41 2c 20 72 65 61 64  in the PMA, read
1fe0: 20 61 6c 6c 20 72 65 6d 61 69 6e 69 6e 67 20 64   all remaining d
1ff0: 61 74 61 2e 20 20 2a 2f 0a 20 20 69 42 75 66 20  ata.  */.  iBuf 
2000: 3d 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 25 20  = p->iReadOff % 
2010: 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 69 66  p->nBuffer;.  if
2020: 28 20 69 42 75 66 3d 3d 30 20 29 7b 0a 20 20 20  ( iBuf==0 ){.   
2030: 20 69 6e 74 20 6e 52 65 61 64 3b 20 20 20 20 20   int nRead;     
2040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2050: 2a 20 42 79 74 65 73 20 74 6f 20 72 65 61 64 20  * Bytes to read 
2060: 66 72 6f 6d 20 64 69 73 6b 20 2a 2f 0a 20 20 20  from disk */.   
2070: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
2080: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2090: 2a 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28  * sqlite3OsRead(
20a0: 29 20 72 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  ) return code */
20b0: 0a 0a 20 20 20 20 2f 2a 20 44 65 74 65 72 6d 69  ..    /* Determi
20c0: 6e 65 20 68 6f 77 20 6d 61 6e 79 20 62 79 74 65  ne how many byte
20d0: 73 20 6f 66 20 64 61 74 61 20 74 6f 20 72 65 61  s of data to rea
20e0: 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 28 70  d. */.    if( (p
20f0: 2d 3e 69 45 6f 66 20 2d 20 70 2d 3e 69 52 65 61  ->iEof - p->iRea
2100: 64 4f 66 66 29 20 3e 20 28 69 36 34 29 70 2d 3e  dOff) > (i64)p->
2110: 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20 20  nBuffer ){.     
2120: 20 6e 52 65 61 64 20 3d 20 70 2d 3e 6e 42 75 66   nRead = p->nBuf
2130: 66 65 72 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  fer;.    }else{.
2140: 20 20 20 20 20 20 6e 52 65 61 64 20 3d 20 28 69        nRead = (i
2150: 6e 74 29 28 70 2d 3e 69 45 6f 66 20 2d 20 70 2d  nt)(p->iEof - p-
2160: 3e 69 52 65 61 64 4f 66 66 29 3b 0a 20 20 20 20  >iReadOff);.    
2170: 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 6e 52  }.    assert( nR
2180: 65 61 64 3e 30 20 29 3b 0a 0a 20 20 20 20 2f 2a  ead>0 );..    /*
2190: 20 52 65 61 64 20 64 61 74 61 20 66 72 6f 6d 20   Read data from 
21a0: 74 68 65 20 66 69 6c 65 2e 20 52 65 74 75 72 6e  the file. Return
21b0: 20 65 61 72 6c 79 20 69 66 20 61 6e 20 65 72 72   early if an err
21c0: 6f 72 20 6f 63 63 75 72 73 2e 20 2a 2f 0a 20 20  or occurs. */.  
21d0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
21e0: 52 65 61 64 28 70 2d 3e 70 46 69 6c 65 2c 20 70  Read(p->pFile, p
21f0: 2d 3e 61 42 75 66 66 65 72 2c 20 6e 52 65 61 64  ->aBuffer, nRead
2200: 2c 20 70 2d 3e 69 52 65 61 64 4f 66 66 29 3b 0a  , p->iReadOff);.
2210: 20 20 20 20 61 73 73 65 72 74 28 20 72 63 21 3d      assert( rc!=
2220: 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f 53 48 4f  SQLITE_IOERR_SHO
2230: 52 54 5f 52 45 41 44 20 29 3b 0a 20 20 20 20 69  RT_READ );.    i
2240: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
2250: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
2260: 7d 0a 20 20 6e 41 76 61 69 6c 20 3d 20 70 2d 3e  }.  nAvail = p->
2270: 6e 42 75 66 66 65 72 20 2d 20 69 42 75 66 3b 20  nBuffer - iBuf; 
2280: 0a 0a 20 20 69 66 28 20 6e 42 79 74 65 3c 3d 6e  ..  if( nByte<=n
2290: 41 76 61 69 6c 20 29 7b 0a 20 20 20 20 2f 2a 20  Avail ){.    /* 
22a0: 54 68 65 20 72 65 71 75 65 73 74 65 64 20 64 61  The requested da
22b0: 74 61 20 69 73 20 61 76 61 69 6c 61 62 6c 65 20  ta is available 
22c0: 69 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79  in the in-memory
22d0: 20 62 75 66 66 65 72 2e 20 49 6e 20 74 68 69 73   buffer. In this
22e0: 0a 20 20 20 20 2a 2a 20 63 61 73 65 20 74 68 65  .    ** case the
22f0: 72 65 20 69 73 20 6e 6f 20 6e 65 65 64 20 74 6f  re is no need to
2300: 20 6d 61 6b 65 20 61 20 63 6f 70 79 20 6f 66 20   make a copy of 
2310: 74 68 65 20 64 61 74 61 2c 20 6a 75 73 74 20 72  the data, just r
2320: 65 74 75 72 6e 20 61 20 0a 20 20 20 20 2a 2a 20  eturn a .    ** 
2330: 70 6f 69 6e 74 65 72 20 69 6e 74 6f 20 74 68 65  pointer into the
2340: 20 62 75 66 66 65 72 20 74 6f 20 74 68 65 20 63   buffer to the c
2350: 61 6c 6c 65 72 2e 20 20 2a 2f 0a 20 20 20 20 2a  aller.  */.    *
2360: 70 70 4f 75 74 20 3d 20 26 70 2d 3e 61 42 75 66  ppOut = &p->aBuf
2370: 66 65 72 5b 69 42 75 66 5d 3b 0a 20 20 20 20 70  fer[iBuf];.    p
2380: 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e 42  ->iReadOff += nB
2390: 79 74 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  yte;.  }else{.  
23a0: 20 20 2f 2a 20 54 68 65 20 72 65 71 75 65 73 74    /* The request
23b0: 65 64 20 64 61 74 61 20 69 73 20 6e 6f 74 20 61  ed data is not a
23c0: 6c 6c 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20  ll available in 
23d0: 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 62 75  the in-memory bu
23e0: 66 66 65 72 2e 0a 20 20 20 20 2a 2a 20 49 6e 20  ffer..    ** In 
23f0: 74 68 69 73 20 63 61 73 65 2c 20 61 6c 6c 6f 63  this case, alloc
2400: 61 74 65 20 73 70 61 63 65 20 61 74 20 70 2d 3e  ate space at p->
2410: 61 41 6c 6c 6f 63 5b 5d 20 74 6f 20 63 6f 70 79  aAlloc[] to copy
2420: 20 74 68 65 20 72 65 71 75 65 73 74 65 64 0a 20   the requested. 
2430: 20 20 20 2a 2a 20 72 61 6e 67 65 20 69 6e 74 6f     ** range into
2440: 2e 20 54 68 65 6e 20 72 65 74 75 72 6e 20 61 20  . Then return a 
2450: 63 6f 70 79 20 6f 66 20 70 6f 69 6e 74 65 72 20  copy of pointer 
2460: 70 2d 3e 61 41 6c 6c 6f 63 20 74 6f 20 74 68 65  p->aAlloc to the
2470: 20 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a 20 20 20   caller.  */.   
2480: 20 69 6e 74 20 6e 52 65 6d 3b 20 20 20 20 20 20   int nRem;      
2490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
24a0: 2a 20 42 79 74 65 73 20 72 65 6d 61 69 6e 69 6e  * Bytes remainin
24b0: 67 20 74 6f 20 63 6f 70 79 20 2a 2f 0a 0a 20 20  g to copy */..  
24c0: 20 20 2f 2a 20 45 78 74 65 6e 64 20 74 68 65 20    /* Extend the 
24d0: 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 61 6c 6c 6f  p->aAlloc[] allo
24e0: 63 61 74 69 6f 6e 20 69 66 20 72 65 71 75 69 72  cation if requir
24f0: 65 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 70  ed. */.    if( p
2500: 2d 3e 6e 41 6c 6c 6f 63 3c 6e 42 79 74 65 20 29  ->nAlloc<nByte )
2510: 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e 65 77  {.      int nNew
2520: 20 3d 20 70 2d 3e 6e 41 6c 6c 6f 63 2a 32 3b 0a   = p->nAlloc*2;.
2530: 20 20 20 20 20 20 77 68 69 6c 65 28 20 6e 42 79        while( nBy
2540: 74 65 3e 6e 4e 65 77 20 29 20 6e 4e 65 77 20 3d  te>nNew ) nNew =
2550: 20 6e 4e 65 77 2a 32 3b 0a 20 20 20 20 20 20 70   nNew*2;.      p
2560: 2d 3e 61 41 6c 6c 6f 63 20 3d 20 73 71 6c 69 74  ->aAlloc = sqlit
2570: 65 33 44 62 52 65 61 6c 6c 6f 63 4f 72 46 72 65  e3DbReallocOrFre
2580: 65 28 64 62 2c 20 70 2d 3e 61 41 6c 6c 6f 63 2c  e(db, p->aAlloc,
2590: 20 6e 4e 65 77 29 3b 0a 20 20 20 20 20 20 69 66   nNew);.      if
25a0: 28 20 21 70 2d 3e 61 41 6c 6c 6f 63 20 29 20 72  ( !p->aAlloc ) r
25b0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
25c0: 45 4d 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 41 6c  EM;.      p->nAl
25d0: 6c 6f 63 20 3d 20 6e 4e 65 77 3b 0a 20 20 20 20  loc = nNew;.    
25e0: 7d 0a 0a 20 20 20 20 2f 2a 20 43 6f 70 79 20 61  }..    /* Copy a
25f0: 73 20 6d 75 63 68 20 64 61 74 61 20 61 73 20 69  s much data as i
2600: 73 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 74  s available in t
2610: 68 65 20 62 75 66 66 65 72 20 69 6e 74 6f 20 74  he buffer into t
2620: 68 65 20 73 74 61 72 74 20 6f 66 0a 20 20 20 20  he start of.    
2630: 2a 2a 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 2e 20  ** p->aAlloc[]. 
2640: 20 2a 2f 0a 20 20 20 20 6d 65 6d 63 70 79 28 70   */.    memcpy(p
2650: 2d 3e 61 41 6c 6c 6f 63 2c 20 26 70 2d 3e 61 42  ->aAlloc, &p->aB
2660: 75 66 66 65 72 5b 69 42 75 66 5d 2c 20 6e 41 76  uffer[iBuf], nAv
2670: 61 69 6c 29 3b 0a 20 20 20 20 70 2d 3e 69 52 65  ail);.    p->iRe
2680: 61 64 4f 66 66 20 2b 3d 20 6e 41 76 61 69 6c 3b  adOff += nAvail;
2690: 0a 20 20 20 20 6e 52 65 6d 20 3d 20 6e 42 79 74  .    nRem = nByt
26a0: 65 20 2d 20 6e 41 76 61 69 6c 3b 0a 0a 20 20 20  e - nAvail;..   
26b0: 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e   /* The followin
26c0: 67 20 6c 6f 6f 70 20 63 6f 70 69 65 73 20 75 70  g loop copies up
26d0: 20 74 6f 20 70 2d 3e 6e 42 75 66 66 65 72 20 62   to p->nBuffer b
26e0: 79 74 65 73 20 70 65 72 20 69 74 65 72 61 74 69  ytes per iterati
26f0: 6f 6e 20 69 6e 74 6f 0a 20 20 20 20 2a 2a 20 74  on into.    ** t
2700: 68 65 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 62  he p->aAlloc[] b
2710: 75 66 66 65 72 2e 20 20 2a 2f 0a 20 20 20 20 77  uffer.  */.    w
2720: 68 69 6c 65 28 20 6e 52 65 6d 3e 30 20 29 7b 0a  hile( nRem>0 ){.
2730: 20 20 20 20 20 20 69 6e 74 20 72 63 3b 20 20 20        int rc;   
2740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2750: 20 20 2f 2a 20 76 64 62 65 53 6f 72 74 65 72 49    /* vdbeSorterI
2760: 74 65 72 52 65 61 64 28 29 20 72 65 74 75 72 6e  terRead() return
2770: 20 63 6f 64 65 20 2a 2f 0a 20 20 20 20 20 20 69   code */.      i
2780: 6e 74 20 6e 43 6f 70 79 3b 20 20 20 20 20 20 20  nt nCopy;       
2790: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
27a0: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f  mber of bytes to
27b0: 20 63 6f 70 79 20 2a 2f 0a 20 20 20 20 20 20 75   copy */.      u
27c0: 38 20 2a 61 4e 65 78 74 3b 20 20 20 20 20 20 20  8 *aNext;       
27d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f             /* Po
27e0: 69 6e 74 65 72 20 74 6f 20 62 75 66 66 65 72 20  inter to buffer 
27f0: 74 6f 20 63 6f 70 79 20 64 61 74 61 20 66 72 6f  to copy data fro
2800: 6d 20 2a 2f 0a 0a 20 20 20 20 20 20 6e 43 6f 70  m */..      nCop
2810: 79 20 3d 20 6e 52 65 6d 3b 0a 20 20 20 20 20 20  y = nRem;.      
2820: 69 66 28 20 6e 52 65 6d 3e 70 2d 3e 6e 42 75 66  if( nRem>p->nBuf
2830: 66 65 72 20 29 20 6e 43 6f 70 79 20 3d 20 70 2d  fer ) nCopy = p-
2840: 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20 20 20 20  >nBuffer;.      
2850: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 49  rc = vdbeSorterI
2860: 74 65 72 52 65 61 64 28 64 62 2c 20 70 2c 20 6e  terRead(db, p, n
2870: 43 6f 70 79 2c 20 26 61 4e 65 78 74 29 3b 0a 20  Copy, &aNext);. 
2880: 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c       if( rc!=SQL
2890: 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
28a0: 72 63 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74  rc;.      assert
28b0: 28 20 61 4e 65 78 74 21 3d 70 2d 3e 61 41 6c 6c  ( aNext!=p->aAll
28c0: 6f 63 20 29 3b 0a 20 20 20 20 20 20 6d 65 6d 63  oc );.      memc
28d0: 70 79 28 26 70 2d 3e 61 41 6c 6c 6f 63 5b 6e 42  py(&p->aAlloc[nB
28e0: 79 74 65 20 2d 20 6e 52 65 6d 5d 2c 20 61 4e 65  yte - nRem], aNe
28f0: 78 74 2c 20 6e 43 6f 70 79 29 3b 0a 20 20 20 20  xt, nCopy);.    
2900: 20 20 6e 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b    nRem -= nCopy;
2910: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2a 70 70 4f  .    }..    *ppO
2920: 75 74 20 3d 20 70 2d 3e 61 41 6c 6c 6f 63 3b 0a  ut = p->aAlloc;.
2930: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51    }..  return SQ
2940: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  LITE_OK;.}../*.*
2950: 2a 20 52 65 61 64 20 61 20 76 61 72 69 6e 74 20  * Read a varint 
2960: 66 72 6f 6d 20 74 68 65 20 73 74 72 65 61 6d 20  from the stream 
2970: 6f 66 20 64 61 74 61 20 61 63 63 65 73 73 65 64  of data accessed
2980: 20 62 79 20 70 2e 20 53 65 74 20 2a 70 6e 4f 75   by p. Set *pnOu
2990: 74 20 74 6f 0a 2a 2a 20 74 68 65 20 76 61 6c 75  t to.** the valu
29a0: 65 20 72 65 61 64 2e 0a 2a 2f 0a 73 74 61 74 69  e read..*/.stati
29b0: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72  c int vdbeSorter
29c0: 49 74 65 72 56 61 72 69 6e 74 28 73 71 6c 69 74  IterVarint(sqlit
29d0: 65 33 20 2a 64 62 2c 20 56 64 62 65 53 6f 72 74  e3 *db, VdbeSort
29e0: 65 72 49 74 65 72 20 2a 70 2c 20 75 36 34 20 2a  erIter *p, u64 *
29f0: 70 6e 4f 75 74 29 7b 0a 20 20 69 6e 74 20 69 42  pnOut){.  int iB
2a00: 75 66 3b 0a 0a 20 20 69 42 75 66 20 3d 20 70 2d  uf;..  iBuf = p-
2a10: 3e 69 52 65 61 64 4f 66 66 20 25 20 70 2d 3e 6e  >iReadOff % p->n
2a20: 42 75 66 66 65 72 3b 0a 20 20 69 66 28 20 69 42  Buffer;.  if( iB
2a30: 75 66 20 26 26 20 28 70 2d 3e 6e 42 75 66 66 65  uf && (p->nBuffe
2a40: 72 2d 69 42 75 66 29 3e 3d 39 20 29 7b 0a 20 20  r-iBuf)>=9 ){.  
2a50: 20 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d    p->iReadOff +=
2a60: 20 73 71 6c 69 74 65 33 47 65 74 56 61 72 69 6e   sqlite3GetVarin
2a70: 74 28 26 70 2d 3e 61 42 75 66 66 65 72 5b 69 42  t(&p->aBuffer[iB
2a80: 75 66 5d 2c 20 70 6e 4f 75 74 29 3b 0a 20 20 7d  uf], pnOut);.  }
2a90: 65 6c 73 65 7b 0a 20 20 20 20 75 38 20 61 56 61  else{.    u8 aVa
2aa0: 72 69 6e 74 5b 31 36 5d 2c 20 2a 61 3b 0a 20 20  rint[16], *a;.  
2ab0: 20 20 69 6e 74 20 69 20 3d 20 30 2c 20 72 63 3b    int i = 0, rc;
2ac0: 0a 20 20 20 20 64 6f 7b 0a 20 20 20 20 20 20 72  .    do{.      r
2ad0: 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 49 74  c = vdbeSorterIt
2ae0: 65 72 52 65 61 64 28 64 62 2c 20 70 2c 20 31 2c  erRead(db, p, 1,
2af0: 20 26 61 29 3b 0a 20 20 20 20 20 20 69 66 28 20   &a);.      if( 
2b00: 72 63 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  rc ) return rc;.
2b10: 20 20 20 20 20 20 61 56 61 72 69 6e 74 5b 28 69        aVarint[(i
2b20: 2b 2b 29 26 30 78 66 5d 20 3d 20 61 5b 30 5d 3b  ++)&0xf] = a[0];
2b30: 0a 20 20 20 20 7d 77 68 69 6c 65 28 20 28 61 5b  .    }while( (a[
2b40: 30 5d 26 30 78 38 30 29 21 3d 30 20 29 3b 0a 20  0]&0x80)!=0 );. 
2b50: 20 20 20 73 71 6c 69 74 65 33 47 65 74 56 61 72     sqlite3GetVar
2b60: 69 6e 74 28 61 56 61 72 69 6e 74 2c 20 70 6e 4f  int(aVarint, pnO
2b70: 75 74 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  ut);.  }..  retu
2b80: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
2b90: 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20  ../*.** Advance 
2ba0: 69 74 65 72 61 74 6f 72 20 70 49 74 65 72 20 74  iterator pIter t
2bb0: 6f 20 74 68 65 20 6e 65 78 74 20 6b 65 79 20 69  o the next key i
2bc0: 6e 20 69 74 73 20 50 4d 41 2e 20 52 65 74 75 72  n its PMA. Retur
2bd0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 0a 2a  n SQLITE_OK if.*
2be0: 2a 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72  * no error occur
2bf0: 73 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20  s, or an SQLite 
2c00: 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20 6f 6e  error code if on
2c10: 65 20 64 6f 65 73 2e 0a 2a 2f 0a 73 74 61 74 69  e does..*/.stati
2c20: 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72  c int vdbeSorter
2c30: 49 74 65 72 4e 65 78 74 28 0a 20 20 73 71 6c 69  IterNext(.  sqli
2c40: 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20  te3 *db,        
2c50: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
2c60: 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 28  atabase handle (
2c70: 66 6f 72 20 73 71 6c 69 74 65 33 44 62 4d 61 6c  for sqlite3DbMal
2c80: 6c 6f 63 28 29 20 29 20 2a 2f 0a 20 20 56 64 62  loc() ) */.  Vdb
2c90: 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74  eSorterIter *pIt
2ca0: 65 72 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  er           /* 
2cb0: 49 74 65 72 61 74 6f 72 20 74 6f 20 61 64 76 61  Iterator to adva
2cc0: 6e 63 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  nce */.){.  int 
2cd0: 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rc;             
2ce0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
2cf0: 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20  eturn Code */.  
2d00: 75 36 34 20 6e 52 65 63 20 3d 20 30 3b 20 20 20  u64 nRec = 0;   
2d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2d20: 2f 2a 20 53 69 7a 65 20 6f 66 20 72 65 63 6f 72  /* Size of recor
2d30: 64 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 0a 20  d in bytes */.. 
2d40: 20 69 66 28 20 70 49 74 65 72 2d 3e 69 52 65 61   if( pIter->iRea
2d50: 64 4f 66 66 3e 3d 70 49 74 65 72 2d 3e 69 45 6f  dOff>=pIter->iEo
2d60: 66 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 69 73  f ){.    /* This
2d70: 20 69 73 20 61 6e 20 45 4f 46 20 63 6f 6e 64 69   is an EOF condi
2d80: 74 69 6f 6e 20 2a 2f 0a 20 20 20 20 76 64 62 65  tion */.    vdbe
2d90: 53 6f 72 74 65 72 49 74 65 72 5a 65 72 6f 28 64  SorterIterZero(d
2da0: 62 2c 20 70 49 74 65 72 29 3b 0a 20 20 20 20 72  b, pIter);.    r
2db0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
2dc0: 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20 76 64 62  .  }..  rc = vdb
2dd0: 65 53 6f 72 74 65 72 49 74 65 72 56 61 72 69 6e  eSorterIterVarin
2de0: 74 28 64 62 2c 20 70 49 74 65 72 2c 20 26 6e 52  t(db, pIter, &nR
2df0: 65 63 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  ec);.  if( rc==S
2e00: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
2e10: 70 49 74 65 72 2d 3e 6e 4b 65 79 20 3d 20 28 69  pIter->nKey = (i
2e20: 6e 74 29 6e 52 65 63 3b 0a 20 20 20 20 72 63 20  nt)nRec;.    rc 
2e30: 3d 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72  = vdbeSorterIter
2e40: 52 65 61 64 28 64 62 2c 20 70 49 74 65 72 2c 20  Read(db, pIter, 
2e50: 28 69 6e 74 29 6e 52 65 63 2c 20 26 70 49 74 65  (int)nRec, &pIte
2e60: 72 2d 3e 61 4b 65 79 29 3b 0a 20 20 7d 0a 0a 20  r->aKey);.  }.. 
2e70: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
2e80: 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20  *.** Initialize 
2e90: 69 74 65 72 61 74 6f 72 20 70 49 74 65 72 20 74  iterator pIter t
2ea0: 6f 20 73 63 61 6e 20 74 68 72 6f 75 67 68 20 74  o scan through t
2eb0: 68 65 20 50 4d 41 20 73 74 6f 72 65 64 20 69 6e  he PMA stored in
2ec0: 20 66 69 6c 65 20 70 46 69 6c 65 0a 2a 2a 20 73   file pFile.** s
2ed0: 74 61 72 74 69 6e 67 20 61 74 20 6f 66 66 73 65  tarting at offse
2ee0: 74 20 69 53 74 61 72 74 20 61 6e 64 20 65 6e 64  t iStart and end
2ef0: 69 6e 67 20 61 74 20 6f 66 66 73 65 74 20 69 45  ing at offset iE
2f00: 6f 66 2d 31 2e 20 54 68 69 73 20 66 75 6e 63 74  of-1. This funct
2f10: 69 6f 6e 20 0a 2a 2a 20 6c 65 61 76 65 73 20 74  ion .** leaves t
2f20: 68 65 20 69 74 65 72 61 74 6f 72 20 70 6f 69 6e  he iterator poin
2f30: 74 69 6e 67 20 74 6f 20 74 68 65 20 66 69 72 73  ting to the firs
2f40: 74 20 6b 65 79 20 69 6e 20 74 68 65 20 50 4d 41  t key in the PMA
2f50: 20 28 6f 72 20 45 4f 46 20 69 66 20 74 68 65 20   (or EOF if the 
2f60: 0a 2a 2a 20 50 4d 41 20 69 73 20 65 6d 70 74 79  .** PMA is empty
2f70: 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  )..*/.static int
2f80: 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 49   vdbeSorterIterI
2f90: 6e 69 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a  nit(.  sqlite3 *
2fa0: 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  db,             
2fb0: 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61         /* Databa
2fc0: 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 63  se handle */.  c
2fd0: 6f 6e 73 74 20 56 64 62 65 53 6f 72 74 65 72 20  onst VdbeSorter 
2fe0: 2a 70 53 6f 72 74 65 72 2c 20 20 20 20 20 20 2f  *pSorter,      /
2ff0: 2a 20 53 6f 72 74 65 72 20 6f 62 6a 65 63 74 20  * Sorter object 
3000: 2a 2f 0a 20 20 69 36 34 20 69 53 74 61 72 74 2c  */.  i64 iStart,
3010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3020: 20 20 20 20 20 2f 2a 20 53 74 61 72 74 20 6f 66       /* Start of
3030: 66 73 65 74 20 69 6e 20 70 46 69 6c 65 20 2a 2f  fset in pFile */
3040: 0a 20 20 56 64 62 65 53 6f 72 74 65 72 49 74 65  .  VdbeSorterIte
3050: 72 20 2a 70 49 74 65 72 2c 20 20 20 20 20 20 20  r *pIter,       
3060: 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 74     /* Iterator t
3070: 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f 0a 20 20  o populate */.  
3080: 69 36 34 20 2a 70 6e 42 79 74 65 20 20 20 20 20  i64 *pnByte     
3090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
30a0: 2f 2a 20 49 4e 2f 4f 55 54 3a 20 49 6e 63 72 65  /* IN/OUT: Incre
30b0: 6d 65 6e 74 20 74 68 69 73 20 76 61 6c 75 65 20  ment this value 
30c0: 62 79 20 50 4d 41 20 73 69 7a 65 20 2a 2f 0a 29  by PMA size */.)
30d0: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
30e0: 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 42  ITE_OK;.  int nB
30f0: 75 66 3b 0a 0a 20 20 6e 42 75 66 20 3d 20 73 71  uf;..  nBuf = sq
3100: 6c 69 74 65 33 42 74 72 65 65 47 65 74 50 61 67  lite3BtreeGetPag
3110: 65 53 69 7a 65 28 64 62 2d 3e 61 44 62 5b 30 5d  eSize(db->aDb[0]
3120: 2e 70 42 74 29 3b 0a 0a 20 20 61 73 73 65 72 74  .pBt);..  assert
3130: 28 20 70 53 6f 72 74 65 72 2d 3e 69 57 72 69 74  ( pSorter->iWrit
3140: 65 4f 66 66 3e 69 53 74 61 72 74 20 29 3b 0a 20  eOff>iStart );. 
3150: 20 61 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e   assert( pIter->
3160: 61 41 6c 6c 6f 63 3d 3d 30 20 29 3b 0a 20 20 61  aAlloc==0 );.  a
3170: 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e 61 42  ssert( pIter->aB
3180: 75 66 66 65 72 3d 3d 30 20 29 3b 0a 20 20 70 49  uffer==0 );.  pI
3190: 74 65 72 2d 3e 70 46 69 6c 65 20 3d 20 70 53 6f  ter->pFile = pSo
31a0: 72 74 65 72 2d 3e 70 54 65 6d 70 31 3b 0a 20 20  rter->pTemp1;.  
31b0: 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66 66 20  pIter->iReadOff 
31c0: 3d 20 69 53 74 61 72 74 3b 0a 20 20 70 49 74 65  = iStart;.  pIte
31d0: 72 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 31 32 38 3b  r->nAlloc = 128;
31e0: 0a 20 20 70 49 74 65 72 2d 3e 61 41 6c 6c 6f 63  .  pIter->aAlloc
31f0: 20 3d 20 28 75 38 20 2a 29 73 71 6c 69 74 65 33   = (u8 *)sqlite3
3200: 44 62 4d 61 6c 6c 6f 63 52 61 77 28 64 62 2c 20  DbMallocRaw(db, 
3210: 70 49 74 65 72 2d 3e 6e 41 6c 6c 6f 63 29 3b 0a  pIter->nAlloc);.
3220: 20 20 70 49 74 65 72 2d 3e 6e 42 75 66 66 65 72    pIter->nBuffer
3230: 20 3d 20 6e 42 75 66 3b 0a 20 20 70 49 74 65 72   = nBuf;.  pIter
3240: 2d 3e 61 42 75 66 66 65 72 20 3d 20 28 75 38 20  ->aBuffer = (u8 
3250: 2a 29 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f  *)sqlite3DbMallo
3260: 63 52 61 77 28 64 62 2c 20 6e 42 75 66 29 3b 0a  cRaw(db, nBuf);.
3270: 0a 20 20 69 66 28 20 21 70 49 74 65 72 2d 3e 61  .  if( !pIter->a
3280: 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20 72 63  Buffer ){.    rc
3290: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
32a0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e  .  }else{.    in
32b0: 74 20 69 42 75 66 3b 0a 0a 20 20 20 20 69 42 75  t iBuf;..    iBu
32c0: 66 20 3d 20 69 53 74 61 72 74 20 25 20 6e 42 75  f = iStart % nBu
32d0: 66 3b 0a 20 20 20 20 69 66 28 20 69 42 75 66 20  f;.    if( iBuf 
32e0: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 52 65  ){.      int nRe
32f0: 61 64 20 3d 20 6e 42 75 66 20 2d 20 69 42 75 66  ad = nBuf - iBuf
3300: 3b 0a 20 20 20 20 20 20 69 66 28 20 28 69 53 74  ;.      if( (iSt
3310: 61 72 74 20 2b 20 6e 52 65 61 64 29 20 3e 20 70  art + nRead) > p
3320: 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f 66  Sorter->iWriteOf
3330: 66 20 29 7b 0a 20 20 20 20 20 20 20 20 6e 52 65  f ){.        nRe
3340: 61 64 20 3d 20 28 69 6e 74 29 28 70 53 6f 72 74  ad = (int)(pSort
3350: 65 72 2d 3e 69 57 72 69 74 65 4f 66 66 20 2d 20  er->iWriteOff - 
3360: 69 53 74 61 72 74 29 3b 0a 20 20 20 20 20 20 7d  iStart);.      }
3370: 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
3380: 74 65 33 4f 73 52 65 61 64 28 0a 20 20 20 20 20  te3OsRead(.     
3390: 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 54       pSorter->pT
33a0: 65 6d 70 31 2c 20 26 70 49 74 65 72 2d 3e 61 42  emp1, &pIter->aB
33b0: 75 66 66 65 72 5b 69 42 75 66 5d 2c 20 6e 52 65  uffer[iBuf], nRe
33c0: 61 64 2c 20 69 53 74 61 72 74 0a 20 20 20 20 20  ad, iStart.     
33d0: 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74   );.      assert
33e0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 49 4f 45  ( rc!=SQLITE_IOE
33f0: 52 52 5f 53 48 4f 52 54 5f 52 45 41 44 20 29 3b  RR_SHORT_READ );
3400: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20  .    }..    if( 
3410: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
3420: 0a 20 20 20 20 20 20 75 36 34 20 6e 42 79 74 65  .      u64 nByte
3430: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
3440: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
3450: 6f 66 20 50 4d 41 20 69 6e 20 62 79 74 65 73 20  of PMA in bytes 
3460: 2a 2f 0a 20 20 20 20 20 20 70 49 74 65 72 2d 3e  */.      pIter->
3470: 69 45 6f 66 20 3d 20 70 53 6f 72 74 65 72 2d 3e  iEof = pSorter->
3480: 69 57 72 69 74 65 4f 66 66 3b 0a 20 20 20 20 20  iWriteOff;.     
3490: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
34a0: 49 74 65 72 56 61 72 69 6e 74 28 64 62 2c 20 70  IterVarint(db, p
34b0: 49 74 65 72 2c 20 26 6e 42 79 74 65 29 3b 0a 20  Iter, &nByte);. 
34c0: 20 20 20 20 20 70 49 74 65 72 2d 3e 69 45 6f 66       pIter->iEof
34d0: 20 3d 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f   = pIter->iReadO
34e0: 66 66 20 2b 20 6e 42 79 74 65 3b 0a 20 20 20 20  ff + nByte;.    
34f0: 20 20 2a 70 6e 42 79 74 65 20 2b 3d 20 6e 42 79    *pnByte += nBy
3500: 74 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  te;.    }.  }.. 
3510: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
3520: 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 76  OK ){.    rc = v
3530: 64 62 65 53 6f 72 74 65 72 49 74 65 72 4e 65 78  dbeSorterIterNex
3540: 74 28 64 62 2c 20 70 49 74 65 72 29 3b 0a 20 20  t(db, pIter);.  
3550: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
3560: 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 61 72 65  .../*.** Compare
3570: 20 6b 65 79 31 20 28 62 75 66 66 65 72 20 70 4b   key1 (buffer pK
3580: 65 79 31 2c 20 73 69 7a 65 20 6e 4b 65 79 31 20  ey1, size nKey1 
3590: 62 79 74 65 73 29 20 77 69 74 68 20 6b 65 79 32  bytes) with key2
35a0: 20 28 62 75 66 66 65 72 20 70 4b 65 79 32 2c 20   (buffer pKey2, 
35b0: 0a 2a 2a 20 73 69 7a 65 20 6e 4b 65 79 32 20 62  .** size nKey2 b
35c0: 79 74 65 73 29 2e 20 20 41 72 67 75 6d 65 6e 74  ytes).  Argument
35d0: 20 70 4b 65 79 49 6e 66 6f 20 73 75 70 70 6c 69   pKeyInfo suppli
35e0: 65 73 20 74 68 65 20 63 6f 6c 6c 61 74 69 6f 6e  es the collation
35f0: 20 66 75 6e 63 74 69 6f 6e 73 0a 2a 2a 20 75 73   functions.** us
3600: 65 64 20 62 79 20 74 68 65 20 63 6f 6d 70 61 72  ed by the compar
3610: 69 73 6f 6e 2e 20 49 66 20 61 6e 20 65 72 72 6f  ison. If an erro
3620: 72 20 6f 63 63 75 72 73 2c 20 72 65 74 75 72 6e  r occurs, return
3630: 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
3640: 20 63 6f 64 65 2e 0a 2a 2a 20 4f 74 68 65 72 77   code..** Otherw
3650: 69 73 65 2c 20 72 65 74 75 72 6e 20 53 51 4c 49  ise, return SQLI
3660: 54 45 5f 4f 4b 20 61 6e 64 20 73 65 74 20 2a 70  TE_OK and set *p
3670: 52 65 73 20 74 6f 20 61 20 6e 65 67 61 74 69 76  Res to a negativ
3680: 65 2c 20 7a 65 72 6f 20 6f 72 20 70 6f 73 69 74  e, zero or posit
3690: 69 76 65 0a 2a 2a 20 76 61 6c 75 65 2c 20 64 65  ive.** value, de
36a0: 70 65 6e 64 69 6e 67 20 6f 6e 20 77 68 65 74 68  pending on wheth
36b0: 65 72 20 6b 65 79 31 20 69 73 20 73 6d 61 6c 6c  er key1 is small
36c0: 65 72 2c 20 65 71 75 61 6c 20 74 6f 20 6f 72 20  er, equal to or 
36d0: 6c 61 72 67 65 72 20 74 68 61 6e 20 6b 65 79 32  larger than key2
36e0: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 62  ..**.** If the b
36f0: 4f 6d 69 74 52 6f 77 69 64 20 61 72 67 75 6d 65  OmitRowid argume
3700: 6e 74 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20  nt is non-zero, 
3710: 61 73 73 75 6d 65 20 62 6f 74 68 20 6b 65 79 73  assume both keys
3720: 20 65 6e 64 20 69 6e 20 61 20 72 6f 77 69 64 0a   end in a rowid.
3730: 2a 2a 20 66 69 65 6c 64 2e 20 46 6f 72 20 74 68  ** field. For th
3740: 65 20 70 75 72 70 6f 73 65 73 20 6f 66 20 74 68  e purposes of th
3750: 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2c 20 69 67  e comparison, ig
3760: 6e 6f 72 65 20 69 74 2e 20 41 6c 73 6f 2c 20 69  nore it. Also, i
3770: 66 20 62 4f 6d 69 74 52 6f 77 69 64 0a 2a 2a 20  f bOmitRowid.** 
3780: 69 73 20 74 72 75 65 20 61 6e 64 20 6b 65 79 31  is true and key1
3790: 20 63 6f 6e 74 61 69 6e 73 20 65 76 65 6e 20 61   contains even a
37a0: 20 73 69 6e 67 6c 65 20 4e 55 4c 4c 20 76 61 6c   single NULL val
37b0: 75 65 2c 20 69 74 20 69 73 20 63 6f 6e 73 69 64  ue, it is consid
37c0: 65 72 65 64 20 74 6f 0a 2a 2a 20 62 65 20 6c 65  ered to.** be le
37d0: 73 73 20 74 68 61 6e 20 6b 65 79 32 2e 20 45 76  ss than key2. Ev
37e0: 65 6e 20 69 66 20 6b 65 79 32 20 61 6c 73 6f 20  en if key2 also 
37f0: 63 6f 6e 74 61 69 6e 73 20 4e 55 4c 4c 20 76 61  contains NULL va
3800: 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 70  lues..**.** If p
3810: 4b 65 79 32 20 69 73 20 70 61 73 73 65 64 20 61  Key2 is passed a
3820: 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2c 20 74   NULL pointer, t
3830: 68 65 6e 20 69 74 20 69 73 20 61 73 73 75 6d 65  hen it is assume
3840: 64 20 74 68 61 74 20 74 68 65 20 70 43 73 72 2d  d that the pCsr-
3850: 3e 61 53 70 61 63 65 0a 2a 2a 20 68 61 73 20 62  >aSpace.** has b
3860: 65 65 6e 20 61 6c 6c 6f 63 61 74 65 64 20 61 6e  een allocated an
3870: 64 20 63 6f 6e 74 61 69 6e 73 20 61 6e 20 75 6e  d contains an un
3880: 70 61 63 6b 65 64 20 72 65 63 6f 72 64 20 74 68  packed record th
3890: 61 74 20 69 73 20 75 73 65 64 20 61 73 20 6b 65  at is used as ke
38a0: 79 32 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  y2..*/.static vo
38b0: 69 64 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d  id vdbeSorterCom
38c0: 70 61 72 65 28 0a 20 20 63 6f 6e 73 74 20 56 64  pare(.  const Vd
38d0: 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  beCursor *pCsr, 
38e0: 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 73 6f          /* Curso
38f0: 72 20 6f 62 6a 65 63 74 20 28 66 6f 72 20 70 4b  r object (for pK
3900: 65 79 49 6e 66 6f 29 20 2a 2f 0a 20 20 69 6e 74  eyInfo) */.  int
3910: 20 62 4f 6d 69 74 52 6f 77 69 64 2c 20 20 20 20   bOmitRowid,    
3920: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3930: 49 67 6e 6f 72 65 20 72 6f 77 69 64 20 66 69 65  Ignore rowid fie
3940: 6c 64 20 61 74 20 65 6e 64 20 6f 66 20 6b 65 79  ld at end of key
3950: 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69  s */.  const voi
3960: 64 20 2a 70 4b 65 79 31 2c 20 69 6e 74 20 6e 4b  d *pKey1, int nK
3970: 65 79 31 2c 20 20 20 2f 2a 20 4c 65 66 74 20 73  ey1,   /* Left s
3980: 69 64 65 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f  ide of compariso
3990: 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69  n */.  const voi
39a0: 64 20 2a 70 4b 65 79 32 2c 20 69 6e 74 20 6e 4b  d *pKey2, int nK
39b0: 65 79 32 2c 20 20 20 2f 2a 20 52 69 67 68 74 20  ey2,   /* Right 
39c0: 73 69 64 65 20 6f 66 20 63 6f 6d 70 61 72 69 73  side of comparis
39d0: 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 52 65  on */.  int *pRe
39e0: 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s               
39f0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
3a00: 52 65 73 75 6c 74 20 6f 66 20 63 6f 6d 70 61 72  Result of compar
3a10: 69 73 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 4b 65 79  ison */.){.  Key
3a20: 49 6e 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 20 3d  Info *pKeyInfo =
3a30: 20 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 3b   pCsr->pKeyInfo;
3a40: 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70  .  VdbeSorter *p
3a50: 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70  Sorter = pCsr->p
3a60: 53 6f 72 74 65 72 3b 0a 20 20 55 6e 70 61 63 6b  Sorter;.  Unpack
3a70: 65 64 52 65 63 6f 72 64 20 2a 72 32 20 3d 20 70  edRecord *r2 = p
3a80: 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65  Sorter->pUnpacke
3a90: 64 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 69  d;.  int i;..  i
3aa0: 66 28 20 70 4b 65 79 32 20 29 7b 0a 20 20 20 20  f( pKey2 ){.    
3ab0: 73 71 6c 69 74 65 33 56 64 62 65 52 65 63 6f 72  sqlite3VdbeRecor
3ac0: 64 55 6e 70 61 63 6b 28 70 4b 65 79 49 6e 66 6f  dUnpack(pKeyInfo
3ad0: 2c 20 6e 4b 65 79 32 2c 20 70 4b 65 79 32 2c 20  , nKey2, pKey2, 
3ae0: 72 32 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  r2);.  }..  if( 
3af0: 62 4f 6d 69 74 52 6f 77 69 64 20 29 7b 0a 20 20  bOmitRowid ){.  
3b00: 20 20 72 32 2d 3e 6e 46 69 65 6c 64 20 3d 20 70    r2->nField = p
3b10: 4b 65 79 49 6e 66 6f 2d 3e 6e 46 69 65 6c 64 3b  KeyInfo->nField;
3b20: 0a 20 20 20 20 61 73 73 65 72 74 28 20 72 32 2d  .    assert( r2-
3b30: 3e 6e 46 69 65 6c 64 3e 30 20 29 3b 0a 20 20 20  >nField>0 );.   
3b40: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 72 32 2d 3e   for(i=0; i<r2->
3b50: 6e 46 69 65 6c 64 3b 20 69 2b 2b 29 7b 0a 20 20  nField; i++){.  
3b60: 20 20 20 20 69 66 28 20 72 32 2d 3e 61 4d 65 6d      if( r2->aMem
3b70: 5b 69 5d 2e 66 6c 61 67 73 20 26 20 4d 45 4d 5f  [i].flags & MEM_
3b80: 4e 75 6c 6c 20 29 7b 0a 20 20 20 20 20 20 20 20  Null ){.        
3b90: 2a 70 52 65 73 20 3d 20 2d 31 3b 0a 20 20 20 20  *pRes = -1;.    
3ba0: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20      return;.    
3bb0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 72 32    }.    }.    r2
3bc0: 2d 3e 66 6c 61 67 73 20 7c 3d 20 55 4e 50 41 43  ->flags |= UNPAC
3bd0: 4b 45 44 5f 50 52 45 46 49 58 5f 4d 41 54 43 48  KED_PREFIX_MATCH
3be0: 3b 0a 20 20 7d 0a 0a 20 20 2a 70 52 65 73 20 3d  ;.  }..  *pRes =
3bf0: 20 73 71 6c 69 74 65 33 56 64 62 65 52 65 63 6f   sqlite3VdbeReco
3c00: 72 64 43 6f 6d 70 61 72 65 28 6e 4b 65 79 31 2c  rdCompare(nKey1,
3c10: 20 70 4b 65 79 31 2c 20 72 32 29 3b 0a 7d 0a 0a   pKey1, r2);.}..
3c20: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
3c30: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f  ion is called to
3c40: 20 63 6f 6d 70 61 72 65 20 74 77 6f 20 69 74 65   compare two ite
3c50: 72 61 74 6f 72 20 6b 65 79 73 20 77 68 65 6e 20  rator keys when 
3c60: 6d 65 72 67 69 6e 67 20 0a 2a 2a 20 6d 75 6c 74  merging .** mult
3c70: 69 70 6c 65 20 62 2d 74 72 65 65 20 73 65 67 6d  iple b-tree segm
3c80: 65 6e 74 73 2e 20 50 61 72 61 6d 65 74 65 72 20  ents. Parameter 
3c90: 69 4f 75 74 20 69 73 20 74 68 65 20 69 6e 64 65  iOut is the inde
3ca0: 78 20 6f 66 20 74 68 65 20 61 54 72 65 65 5b 5d  x of the aTree[]
3cb0: 20 0a 2a 2a 20 76 61 6c 75 65 20 74 6f 20 72 65   .** value to re
3cc0: 63 61 6c 63 75 6c 61 74 65 2e 0a 2a 2f 0a 73 74  calculate..*/.st
3cd0: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
3ce0: 74 65 72 44 6f 43 6f 6d 70 61 72 65 28 63 6f 6e  terDoCompare(con
3cf0: 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70  st VdbeCursor *p
3d00: 43 73 72 2c 20 69 6e 74 20 69 4f 75 74 29 7b 0a  Csr, int iOut){.
3d10: 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
3d20: 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53  orter = pCsr->pS
3d30: 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 69 31 3b  orter;.  int i1;
3d40: 0a 20 20 69 6e 74 20 69 32 3b 0a 20 20 69 6e 74  .  int i2;.  int
3d50: 20 69 52 65 73 3b 0a 20 20 56 64 62 65 53 6f 72   iRes;.  VdbeSor
3d60: 74 65 72 49 74 65 72 20 2a 70 31 3b 0a 20 20 56  terIter *p1;.  V
3d70: 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70  dbeSorterIter *p
3d80: 32 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 69 4f  2;..  assert( iO
3d90: 75 74 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 72 65  ut<pSorter->nTre
3da0: 65 20 26 26 20 69 4f 75 74 3e 30 20 29 3b 0a 0a  e && iOut>0 );..
3db0: 20 20 69 66 28 20 69 4f 75 74 3e 3d 28 70 53 6f    if( iOut>=(pSo
3dc0: 72 74 65 72 2d 3e 6e 54 72 65 65 2f 32 29 20 29  rter->nTree/2) )
3dd0: 7b 0a 20 20 20 20 69 31 20 3d 20 28 69 4f 75 74  {.    i1 = (iOut
3de0: 20 2d 20 70 53 6f 72 74 65 72 2d 3e 6e 54 72 65   - pSorter->nTre
3df0: 65 2f 32 29 20 2a 20 32 3b 0a 20 20 20 20 69 32  e/2) * 2;.    i2
3e00: 20 3d 20 69 31 20 2b 20 31 3b 0a 20 20 7d 65 6c   = i1 + 1;.  }el
3e10: 73 65 7b 0a 20 20 20 20 69 31 20 3d 20 70 53 6f  se{.    i1 = pSo
3e20: 72 74 65 72 2d 3e 61 54 72 65 65 5b 69 4f 75 74  rter->aTree[iOut
3e30: 2a 32 5d 3b 0a 20 20 20 20 69 32 20 3d 20 70 53  *2];.    i2 = pS
3e40: 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 69 4f 75  orter->aTree[iOu
3e50: 74 2a 32 2b 31 5d 3b 0a 20 20 7d 0a 0a 20 20 70  t*2+1];.  }..  p
3e60: 31 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 49  1 = &pSorter->aI
3e70: 74 65 72 5b 69 31 5d 3b 0a 20 20 70 32 20 3d 20  ter[i1];.  p2 = 
3e80: 26 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b  &pSorter->aIter[
3e90: 69 32 5d 3b 0a 0a 20 20 69 66 28 20 70 31 2d 3e  i2];..  if( p1->
3ea0: 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20  pFile==0 ){.    
3eb0: 69 52 65 73 20 3d 20 69 32 3b 0a 20 20 7d 65 6c  iRes = i2;.  }el
3ec0: 73 65 20 69 66 28 20 70 32 2d 3e 70 46 69 6c 65  se if( p2->pFile
3ed0: 3d 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 73 20  ==0 ){.    iRes 
3ee0: 3d 20 69 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  = i1;.  }else{. 
3ef0: 20 20 20 69 6e 74 20 72 65 73 3b 0a 20 20 20 20     int res;.    
3f00: 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e 70 53  assert( pCsr->pS
3f10: 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64  orter->pUnpacked
3f20: 21 3d 30 20 29 3b 20 20 2f 2a 20 61 6c 6c 6f 63  !=0 );  /* alloc
3f30: 61 74 65 64 20 69 6e 20 76 64 62 65 53 6f 72 74  ated in vdbeSort
3f40: 65 72 4d 65 72 67 65 28 29 20 2a 2f 0a 20 20 20  erMerge() */.   
3f50: 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61   vdbeSorterCompa
3f60: 72 65 28 0a 20 20 20 20 20 20 20 20 70 43 73 72  re(.        pCsr
3f70: 2c 20 30 2c 20 70 31 2d 3e 61 4b 65 79 2c 20 70  , 0, p1->aKey, p
3f80: 31 2d 3e 6e 4b 65 79 2c 20 70 32 2d 3e 61 4b 65  1->nKey, p2->aKe
3f90: 79 2c 20 70 32 2d 3e 6e 4b 65 79 2c 20 26 72 65  y, p2->nKey, &re
3fa0: 73 0a 20 20 20 20 29 3b 0a 20 20 20 20 69 66 28  s.    );.    if(
3fb0: 20 72 65 73 3c 3d 30 20 29 7b 0a 20 20 20 20 20   res<=0 ){.     
3fc0: 20 69 52 65 73 20 3d 20 69 31 3b 0a 20 20 20 20   iRes = i1;.    
3fd0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 52 65  }else{.      iRe
3fe0: 73 20 3d 20 69 32 3b 0a 20 20 20 20 7d 0a 20 20  s = i2;.    }.  
3ff0: 7d 0a 0a 20 20 70 53 6f 72 74 65 72 2d 3e 61 54  }..  pSorter->aT
4000: 72 65 65 5b 69 4f 75 74 5d 20 3d 20 69 52 65 73  ree[iOut] = iRes
4010: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
4020: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  E_OK;.}../*.** I
4030: 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 74 65  nitialize the te
4040: 6d 70 6f 72 61 72 79 20 69 6e 64 65 78 20 63 75  mporary index cu
4050: 72 73 6f 72 20 6a 75 73 74 20 6f 70 65 6e 65 64  rsor just opened
4060: 20 61 73 20 61 20 73 6f 72 74 65 72 20 63 75 72   as a sorter cur
4070: 73 6f 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  sor..*/.int sqli
4080: 74 65 33 56 64 62 65 53 6f 72 74 65 72 49 6e 69  te3VdbeSorterIni
4090: 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 56  t(sqlite3 *db, V
40a0: 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 29  dbeCursor *pCsr)
40b0: 7b 0a 20 20 69 6e 74 20 70 67 73 7a 3b 20 20 20  {.  int pgsz;   
40c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
40d0: 20 20 20 20 2f 2a 20 50 61 67 65 20 73 69 7a 65      /* Page size
40e0: 20 6f 66 20 6d 61 69 6e 20 64 61 74 61 62 61 73   of main databas
40f0: 65 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 43 61 63  e */.  int mxCac
4100: 68 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  he;             
4110: 20 20 20 20 20 20 20 2f 2a 20 43 61 63 68 65 20         /* Cache 
4120: 73 69 7a 65 20 2a 2f 0a 20 20 56 64 62 65 53 6f  size */.  VdbeSo
4130: 72 74 65 72 20 2a 70 53 6f 72 74 65 72 3b 20 20  rter *pSorter;  
4140: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
4150: 20 6e 65 77 20 73 6f 72 74 65 72 20 2a 2f 0a 20   new sorter */. 
4160: 20 63 68 61 72 20 2a 64 3b 20 20 20 20 20 20 20   char *d;       
4170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4180: 20 2f 2a 20 44 75 6d 6d 79 20 2a 2f 0a 0a 20 20   /* Dummy */..  
4190: 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e 70 4b  assert( pCsr->pK
41a0: 65 79 49 6e 66 6f 20 26 26 20 70 43 73 72 2d 3e  eyInfo && pCsr->
41b0: 70 42 74 3d 3d 30 20 29 3b 0a 20 20 70 43 73 72  pBt==0 );.  pCsr
41c0: 2d 3e 70 53 6f 72 74 65 72 20 3d 20 70 53 6f 72  ->pSorter = pSor
41d0: 74 65 72 20 3d 20 73 71 6c 69 74 65 33 44 62 4d  ter = sqlite3DbM
41e0: 61 6c 6c 6f 63 5a 65 72 6f 28 64 62 2c 20 73 69  allocZero(db, si
41f0: 7a 65 6f 66 28 56 64 62 65 53 6f 72 74 65 72 29  zeof(VdbeSorter)
4200: 29 3b 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72  );.  if( pSorter
4210: 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72  ==0 ){.    retur
4220: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
4230: 20 20 7d 0a 20 20 0a 20 20 70 53 6f 72 74 65 72    }.  .  pSorter
4240: 2d 3e 70 55 6e 70 61 63 6b 65 64 20 3d 20 73 71  ->pUnpacked = sq
4250: 6c 69 74 65 33 56 64 62 65 41 6c 6c 6f 63 55 6e  lite3VdbeAllocUn
4260: 70 61 63 6b 65 64 52 65 63 6f 72 64 28 70 43 73  packedRecord(pCs
4270: 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20 30 2c 20  r->pKeyInfo, 0, 
4280: 30 2c 20 26 64 29 3b 0a 20 20 69 66 28 20 70 53  0, &d);.  if( pS
4290: 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64  orter->pUnpacked
42a0: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
42b0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 61 73 73  ITE_NOMEM;.  ass
42c0: 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 70 55  ert( pSorter->pU
42d0: 6e 70 61 63 6b 65 64 3d 3d 28 55 6e 70 61 63 6b  npacked==(Unpack
42e0: 65 64 52 65 63 6f 72 64 20 2a 29 64 20 29 3b 0a  edRecord *)d );.
42f0: 0a 20 20 69 66 28 20 21 73 71 6c 69 74 65 33 54  .  if( !sqlite3T
4300: 65 6d 70 49 6e 4d 65 6d 6f 72 79 28 64 62 29 20  empInMemory(db) 
4310: 29 7b 0a 20 20 20 20 70 67 73 7a 20 3d 20 73 71  ){.    pgsz = sq
4320: 6c 69 74 65 33 42 74 72 65 65 47 65 74 50 61 67  lite3BtreeGetPag
4330: 65 53 69 7a 65 28 64 62 2d 3e 61 44 62 5b 30 5d  eSize(db->aDb[0]
4340: 2e 70 42 74 29 3b 0a 20 20 20 20 70 53 6f 72 74  .pBt);.    pSort
4350: 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a 65 20 3d 20  er->mnPmaSize = 
4360: 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49  SORTER_MIN_WORKI
4370: 4e 47 20 2a 20 70 67 73 7a 3b 0a 20 20 20 20 6d  NG * pgsz;.    m
4380: 78 43 61 63 68 65 20 3d 20 64 62 2d 3e 61 44 62  xCache = db->aDb
4390: 5b 30 5d 2e 70 53 63 68 65 6d 61 2d 3e 63 61 63  [0].pSchema->cac
43a0: 68 65 5f 73 69 7a 65 3b 0a 20 20 20 20 69 66 28  he_size;.    if(
43b0: 20 6d 78 43 61 63 68 65 3c 53 4f 52 54 45 52 5f   mxCache<SORTER_
43c0: 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20 29 20 6d 78  MIN_WORKING ) mx
43d0: 43 61 63 68 65 20 3d 20 53 4f 52 54 45 52 5f 4d  Cache = SORTER_M
43e0: 49 4e 5f 57 4f 52 4b 49 4e 47 3b 0a 20 20 20 20  IN_WORKING;.    
43f0: 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69  pSorter->mxPmaSi
4400: 7a 65 20 3d 20 6d 78 43 61 63 68 65 20 2a 20 70  ze = mxCache * p
4410: 67 73 7a 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  gsz;.  }..  retu
4420: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
4430: 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 74 68 65 20  ./*.** Free the 
4440: 6c 69 73 74 20 6f 66 20 73 6f 72 74 65 64 20 72  list of sorted r
4450: 65 63 6f 72 64 73 20 73 74 61 72 74 69 6e 67 20  ecords starting 
4460: 61 74 20 70 52 65 63 6f 72 64 2e 0a 2a 2f 0a 73  at pRecord..*/.s
4470: 74 61 74 69 63 20 76 6f 69 64 20 76 64 62 65 53  tatic void vdbeS
4480: 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65 65 28  orterRecordFree(
4490: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 53 6f 72  sqlite3 *db, Sor
44a0: 74 65 72 52 65 63 6f 72 64 20 2a 70 52 65 63 6f  terRecord *pReco
44b0: 72 64 29 7b 0a 20 20 53 6f 72 74 65 72 52 65 63  rd){.  SorterRec
44c0: 6f 72 64 20 2a 70 3b 0a 20 20 53 6f 72 74 65 72  ord *p;.  Sorter
44d0: 52 65 63 6f 72 64 20 2a 70 4e 65 78 74 3b 0a 20  Record *pNext;. 
44e0: 20 66 6f 72 28 70 3d 70 52 65 63 6f 72 64 3b 20   for(p=pRecord; 
44f0: 70 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20  p; p=pNext){.   
4500: 20 70 4e 65 78 74 20 3d 20 70 2d 3e 70 4e 65 78   pNext = p->pNex
4510: 74 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 44 62  t;.    sqlite3Db
4520: 46 72 65 65 28 64 62 2c 20 70 29 3b 0a 20 20 7d  Free(db, p);.  }
4530: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61  .}../*.** Free a
4540: 6e 79 20 63 75 72 73 6f 72 20 63 6f 6d 70 6f 6e  ny cursor compon
4550: 65 6e 74 73 20 61 6c 6c 6f 63 61 74 65 64 20 62  ents allocated b
4560: 79 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72  y sqlite3VdbeSor
4570: 74 65 72 58 58 58 20 72 6f 75 74 69 6e 65 73 2e  terXXX routines.
4580: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
4590: 56 64 62 65 53 6f 72 74 65 72 43 6c 6f 73 65 28  VdbeSorterClose(
45a0: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 56 64 62  sqlite3 *db, Vdb
45b0: 65 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a  eCursor *pCsr){.
45c0: 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
45d0: 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53  orter = pCsr->pS
45e0: 6f 72 74 65 72 3b 0a 20 20 69 66 28 20 70 53 6f  orter;.  if( pSo
45f0: 72 74 65 72 20 29 7b 0a 20 20 20 20 69 66 28 20  rter ){.    if( 
4600: 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 20 29  pSorter->aIter )
4610: 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20  {.      int i;. 
4620: 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c       for(i=0; i<
4630: 70 53 6f 72 74 65 72 2d 3e 6e 54 72 65 65 3b 20  pSorter->nTree; 
4640: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 76 64  i++){.        vd
4650: 62 65 53 6f 72 74 65 72 49 74 65 72 5a 65 72 6f  beSorterIterZero
4660: 28 64 62 2c 20 26 70 53 6f 72 74 65 72 2d 3e 61  (db, &pSorter->a
4670: 49 74 65 72 5b 69 5d 29 3b 0a 20 20 20 20 20 20  Iter[i]);.      
4680: 7d 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 44  }.      sqlite3D
4690: 62 46 72 65 65 28 64 62 2c 20 70 53 6f 72 74 65  bFree(db, pSorte
46a0: 72 2d 3e 61 49 74 65 72 29 3b 0a 20 20 20 20 7d  r->aIter);.    }
46b0: 0a 20 20 20 20 69 66 28 20 70 53 6f 72 74 65 72  .    if( pSorter
46c0: 2d 3e 70 54 65 6d 70 31 20 29 7b 0a 20 20 20 20  ->pTemp1 ){.    
46d0: 20 20 73 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65    sqlite3OsClose
46e0: 46 72 65 65 28 70 53 6f 72 74 65 72 2d 3e 70 54  Free(pSorter->pT
46f0: 65 6d 70 31 29 3b 0a 20 20 20 20 7d 0a 20 20 20  emp1);.    }.   
4700: 20 76 64 62 65 53 6f 72 74 65 72 52 65 63 6f 72   vdbeSorterRecor
4710: 64 46 72 65 65 28 64 62 2c 20 70 53 6f 72 74 65  dFree(db, pSorte
4720: 72 2d 3e 70 52 65 63 6f 72 64 29 3b 0a 20 20 20  r->pRecord);.   
4730: 20 73 71 6c 69 74 65 33 44 62 46 72 65 65 28 64   sqlite3DbFree(d
4740: 62 2c 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70  b, pSorter->pUnp
4750: 61 63 6b 65 64 29 3b 0a 20 20 20 20 73 71 6c 69  acked);.    sqli
4760: 74 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 53  te3DbFree(db, pS
4770: 6f 72 74 65 72 29 3b 0a 20 20 20 20 70 43 73 72  orter);.    pCsr
4780: 2d 3e 70 53 6f 72 74 65 72 20 3d 20 30 3b 0a 20  ->pSorter = 0;. 
4790: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f   }.}../*.** Allo
47a0: 63 61 74 65 20 73 70 61 63 65 20 66 6f 72 20 61  cate space for a
47b0: 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20 61 6e 64   file-handle and
47c0: 20 6f 70 65 6e 20 61 20 74 65 6d 70 6f 72 61 72   open a temporar
47d0: 79 20 66 69 6c 65 2e 20 49 66 20 73 75 63 63 65  y file. If succe
47e0: 73 73 66 75 6c 2c 0a 2a 2a 20 73 65 74 20 2a 70  ssful,.** set *p
47f0: 70 46 69 6c 65 20 74 6f 20 70 6f 69 6e 74 20 74  pFile to point t
4800: 6f 20 74 68 65 20 6d 61 6c 6c 6f 63 27 64 20 66  o the malloc'd f
4810: 69 6c 65 2d 68 61 6e 64 6c 65 20 61 6e 64 20 72  ile-handle and r
4820: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e  eturn SQLITE_OK.
4830: 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 73  .** Otherwise, s
4840: 65 74 20 2a 70 70 46 69 6c 65 20 74 6f 20 30 20  et *ppFile to 0 
4850: 61 6e 64 20 72 65 74 75 72 6e 20 61 6e 20 53 51  and return an SQ
4860: 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e  Lite error code.
4870: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
4880: 64 62 65 53 6f 72 74 65 72 4f 70 65 6e 54 65 6d  dbeSorterOpenTem
4890: 70 46 69 6c 65 28 73 71 6c 69 74 65 33 20 2a 64  pFile(sqlite3 *d
48a0: 62 2c 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  b, sqlite3_file 
48b0: 2a 2a 70 70 46 69 6c 65 29 7b 0a 20 20 69 6e 74  **ppFile){.  int
48c0: 20 64 75 6d 6d 79 3b 0a 20 20 72 65 74 75 72 6e   dummy;.  return
48d0: 20 73 71 6c 69 74 65 33 4f 73 4f 70 65 6e 4d 61   sqlite3OsOpenMa
48e0: 6c 6c 6f 63 28 64 62 2d 3e 70 56 66 73 2c 20 30  lloc(db->pVfs, 0
48f0: 2c 20 70 70 46 69 6c 65 2c 0a 20 20 20 20 20 20  , ppFile,.      
4900: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 54 45 4d 50  SQLITE_OPEN_TEMP
4910: 5f 4a 4f 55 52 4e 41 4c 20 7c 0a 20 20 20 20 20  _JOURNAL |.     
4920: 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 52 45 41   SQLITE_OPEN_REA
4930: 44 57 52 49 54 45 20 20 20 20 7c 20 53 51 4c 49  DWRITE    | SQLI
4940: 54 45 5f 4f 50 45 4e 5f 43 52 45 41 54 45 20 7c  TE_OPEN_CREATE |
4950: 0a 20 20 20 20 20 20 53 51 4c 49 54 45 5f 4f 50  .      SQLITE_OP
4960: 45 4e 5f 45 58 43 4c 55 53 49 56 45 20 20 20 20  EN_EXCLUSIVE    
4970: 7c 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 44 45  | SQLITE_OPEN_DE
4980: 4c 45 54 45 4f 4e 43 4c 4f 53 45 2c 20 26 64 75  LETEONCLOSE, &du
4990: 6d 6d 79 0a 20 20 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  mmy.  );.}../*.*
49a0: 2a 20 4d 65 72 67 65 20 74 68 65 20 74 77 6f 20  * Merge the two 
49b0: 73 6f 72 74 65 64 20 6c 69 73 74 73 20 70 31 20  sorted lists p1 
49c0: 61 6e 64 20 70 32 20 69 6e 74 6f 20 61 20 73 69  and p2 into a si
49d0: 6e 67 6c 65 20 6c 69 73 74 2e 0a 2a 2a 20 53 65  ngle list..** Se
49e0: 74 20 2a 70 70 4f 75 74 20 74 6f 20 74 68 65 20  t *ppOut to the 
49f0: 68 65 61 64 20 6f 66 20 74 68 65 20 6e 65 77 20  head of the new 
4a00: 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  list..*/.static 
4a10: 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72 4d  void vdbeSorterM
4a20: 65 72 67 65 28 0a 20 20 63 6f 6e 73 74 20 56 64  erge(.  const Vd
4a30: 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  beCursor *pCsr, 
4a40: 20 20 20 20 20 20 20 20 2f 2a 20 46 6f 72 20 70          /* For p
4a50: 4b 65 79 49 6e 66 6f 20 2a 2f 0a 20 20 53 6f 72  KeyInfo */.  Sor
4a60: 74 65 72 52 65 63 6f 72 64 20 2a 70 31 2c 20 20  terRecord *p1,  
4a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4a80: 46 69 72 73 74 20 6c 69 73 74 20 74 6f 20 6d 65  First list to me
4a90: 72 67 65 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52  rge */.  SorterR
4aa0: 65 63 6f 72 64 20 2a 70 32 2c 20 20 20 20 20 20  ecord *p2,      
4ab0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 63 6f           /* Seco
4ac0: 6e 64 20 6c 69 73 74 20 74 6f 20 6d 65 72 67 65  nd list to merge
4ad0: 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f   */.  SorterReco
4ae0: 72 64 20 2a 2a 70 70 4f 75 74 20 20 20 20 20 20  rd **ppOut      
4af0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 48 65        /* OUT: He
4b00: 61 64 20 6f 66 20 6d 65 72 67 65 64 20 6c 69 73  ad of merged lis
4b10: 74 20 2a 2f 0a 29 7b 0a 20 20 53 6f 72 74 65 72  t */.){.  Sorter
4b20: 52 65 63 6f 72 64 20 2a 70 46 69 6e 61 6c 20 3d  Record *pFinal =
4b30: 20 30 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f   0;.  SorterReco
4b40: 72 64 20 2a 2a 70 70 20 3d 20 26 70 46 69 6e 61  rd **pp = &pFina
4b50: 6c 3b 0a 20 20 76 6f 69 64 20 2a 70 56 61 6c 32  l;.  void *pVal2
4b60: 20 3d 20 70 32 20 3f 20 70 32 2d 3e 70 56 61 6c   = p2 ? p2->pVal
4b70: 20 3a 20 30 3b 0a 0a 20 20 77 68 69 6c 65 28 20   : 0;..  while( 
4b80: 70 31 20 26 26 20 70 32 20 29 7b 0a 20 20 20 20  p1 && p2 ){.    
4b90: 69 6e 74 20 72 65 73 3b 0a 20 20 20 20 76 64 62  int res;.    vdb
4ba0: 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28 70  eSorterCompare(p
4bb0: 43 73 72 2c 20 30 2c 20 70 31 2d 3e 70 56 61 6c  Csr, 0, p1->pVal
4bc0: 2c 20 70 31 2d 3e 6e 56 61 6c 2c 20 70 56 61 6c  , p1->nVal, pVal
4bd0: 32 2c 20 70 32 2d 3e 6e 56 61 6c 2c 20 26 72 65  2, p2->nVal, &re
4be0: 73 29 3b 0a 20 20 20 20 69 66 28 20 72 65 73 3c  s);.    if( res<
4bf0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 2a 70 70 20  =0 ){.      *pp 
4c00: 3d 20 70 31 3b 0a 20 20 20 20 20 20 70 70 20 3d  = p1;.      pp =
4c10: 20 26 70 31 2d 3e 70 4e 65 78 74 3b 0a 20 20 20   &p1->pNext;.   
4c20: 20 20 20 70 31 20 3d 20 70 31 2d 3e 70 4e 65 78     p1 = p1->pNex
4c30: 74 3b 0a 20 20 20 20 20 20 70 56 61 6c 32 20 3d  t;.      pVal2 =
4c40: 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20   0;.    }else{. 
4c50: 20 20 20 20 20 2a 70 70 20 3d 20 70 32 3b 0a 20       *pp = p2;. 
4c60: 20 20 20 20 20 20 70 70 20 3d 20 26 70 32 2d 3e        pp = &p2->
4c70: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 32 20  pNext;.      p2 
4c80: 3d 20 70 32 2d 3e 70 4e 65 78 74 3b 0a 20 20 20  = p2->pNext;.   
4c90: 20 20 20 69 66 28 20 70 32 3d 3d 30 20 29 20 62     if( p2==0 ) b
4ca0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 70 56 61 6c  reak;.      pVal
4cb0: 32 20 3d 20 70 32 2d 3e 70 56 61 6c 3b 0a 20 20  2 = p2->pVal;.  
4cc0: 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 70 20 3d 20    }.  }.  *pp = 
4cd0: 70 31 20 3f 20 70 31 20 3a 20 70 32 3b 0a 20 20  p1 ? p1 : p2;.  
4ce0: 2a 70 70 4f 75 74 20 3d 20 70 46 69 6e 61 6c 3b  *ppOut = pFinal;
4cf0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74  .}../*.** Sort t
4d00: 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f  he linked list o
4d10: 66 20 72 65 63 6f 72 64 73 20 68 65 61 64 65 64  f records headed
4d20: 20 61 74 20 70 43 73 72 2d 3e 70 52 65 63 6f 72   at pCsr->pRecor
4d30: 64 2e 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45  d. Return SQLITE
4d40: 5f 4f 4b 0a 2a 2a 20 69 66 20 73 75 63 63 65 73  _OK.** if succes
4d50: 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69  sful, or an SQLi
4d60: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 28 69  te error code (i
4d70: 2e 65 2e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  .e. SQLITE_NOMEM
4d80: 29 20 69 66 20 61 6e 20 65 72 72 6f 72 0a 2a 2a  ) if an error.**
4d90: 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74   occurs..*/.stat
4da0: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
4db0: 72 53 6f 72 74 28 63 6f 6e 73 74 20 56 64 62 65  rSort(const Vdbe
4dc0: 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20  Cursor *pCsr){. 
4dd0: 20 69 6e 74 20 69 3b 0a 20 20 53 6f 72 74 65 72   int i;.  Sorter
4de0: 52 65 63 6f 72 64 20 2a 2a 61 53 6c 6f 74 3b 0a  Record **aSlot;.
4df0: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
4e00: 70 3b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20  p;.  VdbeSorter 
4e10: 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d  *pSorter = pCsr-
4e20: 3e 70 53 6f 72 74 65 72 3b 0a 0a 20 20 61 53 6c  >pSorter;..  aSl
4e30: 6f 74 20 3d 20 28 53 6f 72 74 65 72 52 65 63 6f  ot = (SorterReco
4e40: 72 64 20 2a 2a 29 73 71 6c 69 74 65 33 4d 61 6c  rd **)sqlite3Mal
4e50: 6c 6f 63 5a 65 72 6f 28 36 34 20 2a 20 73 69 7a  locZero(64 * siz
4e60: 65 6f 66 28 53 6f 72 74 65 72 52 65 63 6f 72 64  eof(SorterRecord
4e70: 20 2a 29 29 3b 0a 20 20 69 66 28 20 21 61 53 6c   *));.  if( !aSl
4e80: 6f 74 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  ot ){.    return
4e90: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
4ea0: 20 7d 0a 0a 20 20 70 20 3d 20 70 53 6f 72 74 65   }..  p = pSorte
4eb0: 72 2d 3e 70 52 65 63 6f 72 64 3b 0a 20 20 77 68  r->pRecord;.  wh
4ec0: 69 6c 65 28 20 70 20 29 7b 0a 20 20 20 20 53 6f  ile( p ){.    So
4ed0: 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65 78  rterRecord *pNex
4ee0: 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20  t = p->pNext;.  
4ef0: 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 30 3b 0a    p->pNext = 0;.
4f00: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 61 53 6c      for(i=0; aSl
4f10: 6f 74 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20  ot[i]; i++){.   
4f20: 20 20 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72     vdbeSorterMer
4f30: 67 65 28 70 43 73 72 2c 20 70 2c 20 61 53 6c 6f  ge(pCsr, p, aSlo
4f40: 74 5b 69 5d 2c 20 26 70 29 3b 0a 20 20 20 20 20  t[i], &p);.     
4f50: 20 61 53 6c 6f 74 5b 69 5d 20 3d 20 30 3b 0a 20   aSlot[i] = 0;. 
4f60: 20 20 20 7d 0a 20 20 20 20 61 53 6c 6f 74 5b 69     }.    aSlot[i
4f70: 5d 20 3d 20 70 3b 0a 20 20 20 20 70 20 3d 20 70  ] = p;.    p = p
4f80: 4e 65 78 74 3b 0a 20 20 7d 0a 0a 20 20 70 20 3d  Next;.  }..  p =
4f90: 20 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69   0;.  for(i=0; i
4fa0: 3c 36 34 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 76  <64; i++){.    v
4fb0: 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28 70  dbeSorterMerge(p
4fc0: 43 73 72 2c 20 70 2c 20 61 53 6c 6f 74 5b 69 5d  Csr, p, aSlot[i]
4fd0: 2c 20 26 70 29 3b 0a 20 20 7d 0a 20 20 70 53 6f  , &p);.  }.  pSo
4fe0: 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 3d 20  rter->pRecord = 
4ff0: 70 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  p;..  sqlite3_fr
5000: 65 65 28 61 53 6c 6f 74 29 3b 0a 20 20 72 65 74  ee(aSlot);.  ret
5010: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
5020: 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69  ../*.** Initiali
5030: 7a 65 20 61 20 66 69 6c 65 2d 77 72 69 74 65 72  ze a file-writer
5040: 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74 61 74   object..*/.stat
5050: 69 63 20 76 6f 69 64 20 66 69 6c 65 57 72 69 74  ic void fileWrit
5060: 65 72 49 6e 69 74 28 0a 20 20 73 71 6c 69 74 65  erInit(.  sqlite
5070: 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20  3 *db,          
5080: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
5090: 61 62 61 73 65 20 28 66 6f 72 20 6d 61 6c 6c 6f  abase (for mallo
50a0: 63 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  c) */.  sqlite3_
50b0: 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 20 20 20  file *pFile,    
50c0: 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20          /* File 
50d0: 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a 20  to write to */. 
50e0: 20 46 69 6c 65 57 72 69 74 65 72 20 2a 70 2c 20   FileWriter *p, 
50f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5100: 20 2f 2a 20 4f 62 6a 65 63 74 20 74 6f 20 70 6f   /* Object to po
5110: 70 75 6c 61 74 65 20 2a 2f 0a 20 20 69 36 34 20  pulate */.  i64 
5120: 69 53 74 61 72 74 20 20 20 20 20 20 20 20 20 20  iStart          
5130: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
5140: 66 66 73 65 74 20 6f 66 20 70 46 69 6c 65 20 74  ffset of pFile t
5150: 6f 20 62 65 67 69 6e 20 77 72 69 74 69 6e 67 20  o begin writing 
5160: 61 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e  at */.){.  int n
5170: 42 75 66 20 3d 20 73 71 6c 69 74 65 33 42 74 72  Buf = sqlite3Btr
5180: 65 65 47 65 74 50 61 67 65 53 69 7a 65 28 64 62  eeGetPageSize(db
5190: 2d 3e 61 44 62 5b 30 5d 2e 70 42 74 29 3b 0a 0a  ->aDb[0].pBt);..
51a0: 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73    memset(p, 0, s
51b0: 69 7a 65 6f 66 28 46 69 6c 65 57 72 69 74 65 72  izeof(FileWriter
51c0: 29 29 3b 0a 20 20 70 2d 3e 61 42 75 66 66 65 72  ));.  p->aBuffer
51d0: 20 3d 20 28 75 38 20 2a 29 73 71 6c 69 74 65 33   = (u8 *)sqlite3
51e0: 44 62 4d 61 6c 6c 6f 63 52 61 77 28 64 62 2c 20  DbMallocRaw(db, 
51f0: 6e 42 75 66 29 3b 0a 20 20 69 66 28 20 21 70 2d  nBuf);.  if( !p-
5200: 3e 61 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20  >aBuffer ){.    
5210: 70 2d 3e 65 46 57 45 72 72 20 3d 20 53 51 4c 49  p->eFWErr = SQLI
5220: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73  TE_NOMEM;.  }els
5230: 65 7b 0a 20 20 20 20 70 2d 3e 69 42 75 66 45 6e  e{.    p->iBufEn
5240: 64 20 3d 20 70 2d 3e 69 42 75 66 53 74 61 72 74  d = p->iBufStart
5250: 20 3d 20 28 69 53 74 61 72 74 20 25 20 6e 42 75   = (iStart % nBu
5260: 66 29 3b 0a 20 20 20 20 70 2d 3e 69 57 72 69 74  f);.    p->iWrit
5270: 65 4f 66 66 20 3d 20 69 53 74 61 72 74 20 2d 20  eOff = iStart - 
5280: 70 2d 3e 69 42 75 66 53 74 61 72 74 3b 0a 20 20  p->iBufStart;.  
5290: 20 20 70 2d 3e 6e 42 75 66 66 65 72 20 3d 20 6e    p->nBuffer = n
52a0: 42 75 66 3b 0a 20 20 20 20 70 2d 3e 70 46 69 6c  Buf;.    p->pFil
52b0: 65 20 3d 20 70 46 69 6c 65 3b 0a 20 20 7d 0a 7d  e = pFile;.  }.}
52c0: 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 6e 44  ../*.** Write nD
52d0: 61 74 61 20 62 79 74 65 73 20 6f 66 20 64 61 74  ata bytes of dat
52e0: 61 20 74 6f 20 74 68 65 20 66 69 6c 65 2d 77 72  a to the file-wr
52f0: 69 74 65 20 6f 62 6a 65 63 74 2e 20 52 65 74 75  ite object. Retu
5300: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 0a 2a 2a 20  rn SQLITE_OK.** 
5310: 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f  if successful, o
5320: 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  r an SQLite erro
5330: 72 20 63 6f 64 65 20 69 66 20 61 6e 20 65 72 72  r code if an err
5340: 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74  or occurs..*/.st
5350: 61 74 69 63 20 76 6f 69 64 20 66 69 6c 65 57 72  atic void fileWr
5360: 69 74 65 72 57 72 69 74 65 28 46 69 6c 65 57 72  iterWrite(FileWr
5370: 69 74 65 72 20 2a 70 2c 20 75 38 20 2a 70 44 61  iter *p, u8 *pDa
5380: 74 61 2c 20 69 6e 74 20 6e 44 61 74 61 29 7b 0a  ta, int nData){.
5390: 20 20 69 6e 74 20 6e 52 65 6d 20 3d 20 6e 44 61    int nRem = nDa
53a0: 74 61 3b 0a 20 20 77 68 69 6c 65 28 20 6e 52 65  ta;.  while( nRe
53b0: 6d 3e 30 20 26 26 20 70 2d 3e 65 46 57 45 72 72  m>0 && p->eFWErr
53c0: 3d 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e  ==0 ){.    int n
53d0: 43 6f 70 79 20 3d 20 6e 52 65 6d 3b 0a 20 20 20  Copy = nRem;.   
53e0: 20 69 66 28 20 6e 43 6f 70 79 3e 28 70 2d 3e 6e   if( nCopy>(p->n
53f0: 42 75 66 66 65 72 20 2d 20 70 2d 3e 69 42 75 66  Buffer - p->iBuf
5400: 45 6e 64 29 20 29 7b 0a 20 20 20 20 20 20 6e 43  End) ){.      nC
5410: 6f 70 79 20 3d 20 70 2d 3e 6e 42 75 66 66 65 72  opy = p->nBuffer
5420: 20 2d 20 70 2d 3e 69 42 75 66 45 6e 64 3b 0a 20   - p->iBufEnd;. 
5430: 20 20 20 7d 0a 0a 20 20 20 20 6d 65 6d 63 70 79     }..    memcpy
5440: 28 26 70 2d 3e 61 42 75 66 66 65 72 5b 70 2d 3e  (&p->aBuffer[p->
5450: 69 42 75 66 45 6e 64 5d 2c 20 26 70 44 61 74 61  iBufEnd], &pData
5460: 5b 6e 44 61 74 61 2d 6e 52 65 6d 5d 2c 20 6e 43  [nData-nRem], nC
5470: 6f 70 79 29 3b 0a 20 20 20 20 70 2d 3e 69 42 75  opy);.    p->iBu
5480: 66 45 6e 64 20 2b 3d 20 6e 43 6f 70 79 3b 0a 20  fEnd += nCopy;. 
5490: 20 20 20 69 66 28 20 70 2d 3e 69 42 75 66 45 6e     if( p->iBufEn
54a0: 64 3d 3d 70 2d 3e 6e 42 75 66 66 65 72 20 29 7b  d==p->nBuffer ){
54b0: 0a 20 20 20 20 20 20 70 2d 3e 65 46 57 45 72 72  .      p->eFWErr
54c0: 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74   = sqlite3OsWrit
54d0: 65 28 70 2d 3e 70 46 69 6c 65 2c 20 0a 20 20 20  e(p->pFile, .   
54e0: 20 20 20 20 20 20 20 26 70 2d 3e 61 42 75 66 66         &p->aBuff
54f0: 65 72 5b 70 2d 3e 69 42 75 66 53 74 61 72 74 5d  er[p->iBufStart]
5500: 2c 20 70 2d 3e 69 42 75 66 45 6e 64 20 2d 20 70  , p->iBufEnd - p
5510: 2d 3e 69 42 75 66 53 74 61 72 74 2c 20 0a 20 20  ->iBufStart, .  
5520: 20 20 20 20 20 20 20 20 70 2d 3e 69 57 72 69 74          p->iWrit
5530: 65 4f 66 66 20 2b 20 70 2d 3e 69 42 75 66 53 74  eOff + p->iBufSt
5540: 61 72 74 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  art.      );.   
5550: 20 20 20 70 2d 3e 69 42 75 66 53 74 61 72 74 20     p->iBufStart 
5560: 3d 20 70 2d 3e 69 42 75 66 45 6e 64 20 3d 20 30  = p->iBufEnd = 0
5570: 3b 0a 20 20 20 20 20 20 70 2d 3e 69 57 72 69 74  ;.      p->iWrit
5580: 65 4f 66 66 20 2b 3d 20 70 2d 3e 6e 42 75 66 66  eOff += p->nBuff
5590: 65 72 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 73  er;.    }.    as
55a0: 73 65 72 74 28 20 70 2d 3e 69 42 75 66 45 6e 64  sert( p->iBufEnd
55b0: 3c 70 2d 3e 6e 42 75 66 66 65 72 20 29 3b 0a 0a  <p->nBuffer );..
55c0: 20 20 20 20 6e 52 65 6d 20 2d 3d 20 6e 43 6f 70      nRem -= nCop
55d0: 79 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  y;.  }.}../*.** 
55e0: 46 6c 75 73 68 20 61 6e 79 20 62 75 66 66 65 72  Flush any buffer
55f0: 65 64 20 64 61 74 61 20 74 6f 20 64 69 73 6b 20  ed data to disk 
5600: 61 6e 64 20 63 6c 65 61 6e 20 75 70 20 74 68 65  and clean up the
5610: 20 66 69 6c 65 2d 77 72 69 74 65 72 20 6f 62 6a   file-writer obj
5620: 65 63 74 2e 0a 2a 2a 20 54 68 65 20 72 65 73 75  ect..** The resu
5630: 6c 74 73 20 6f 66 20 75 73 69 6e 67 20 74 68 65  lts of using the
5640: 20 66 69 6c 65 2d 77 72 69 74 65 72 20 61 66 74   file-writer aft
5650: 65 72 20 74 68 69 73 20 63 61 6c 6c 20 61 72 65  er this call are
5660: 20 75 6e 64 65 66 69 6e 65 64 2e 0a 2a 2a 20 52   undefined..** R
5670: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20  eturn SQLITE_OK 
5680: 69 66 20 66 6c 75 73 68 69 6e 67 20 74 68 65 20  if flushing the 
5690: 62 75 66 66 65 72 65 64 20 64 61 74 61 20 73 75  buffered data su
56a0: 63 63 65 65 64 73 20 6f 72 20 69 73 20 6e 6f 74  cceeds or is not
56b0: 20 0a 2a 2a 20 72 65 71 75 69 72 65 64 2e 20 4f   .** required. O
56c0: 74 68 65 72 77 69 73 65 2c 20 72 65 74 75 72 6e  therwise, return
56d0: 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
56e0: 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 42 65 66   code..**.** Bef
56f0: 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2c 20 73  ore returning, s
5700: 65 74 20 2a 70 69 45 6f 66 20 74 6f 20 74 68 65  et *piEof to the
5710: 20 6f 66 66 73 65 74 20 69 6d 6d 65 64 69 61 74   offset immediat
5720: 65 6c 79 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68  ely following th
5730: 65 0a 2a 2a 20 6c 61 73 74 20 62 79 74 65 20 77  e.** last byte w
5740: 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20 66 69  ritten to the fi
5750: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
5760: 74 20 66 69 6c 65 57 72 69 74 65 72 46 69 6e 69  t fileWriterFini
5770: 73 68 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  sh(sqlite3 *db, 
5780: 46 69 6c 65 57 72 69 74 65 72 20 2a 70 2c 20 69  FileWriter *p, i
5790: 36 34 20 2a 70 69 45 6f 66 29 7b 0a 20 20 69 6e  64 *piEof){.  in
57a0: 74 20 72 63 3b 0a 20 20 69 66 28 20 70 2d 3e 65  t rc;.  if( p->e
57b0: 46 57 45 72 72 3d 3d 30 20 26 26 20 41 4c 57 41  FWErr==0 && ALWA
57c0: 59 53 28 70 2d 3e 61 42 75 66 66 65 72 29 20 26  YS(p->aBuffer) &
57d0: 26 20 70 2d 3e 69 42 75 66 45 6e 64 3e 70 2d 3e  & p->iBufEnd>p->
57e0: 69 42 75 66 53 74 61 72 74 20 29 7b 0a 20 20 20  iBufStart ){.   
57f0: 20 70 2d 3e 65 46 57 45 72 72 20 3d 20 73 71 6c   p->eFWErr = sql
5800: 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d 3e 70  ite3OsWrite(p->p
5810: 46 69 6c 65 2c 20 0a 20 20 20 20 20 20 20 20 26  File, .        &
5820: 70 2d 3e 61 42 75 66 66 65 72 5b 70 2d 3e 69 42  p->aBuffer[p->iB
5830: 75 66 53 74 61 72 74 5d 2c 20 70 2d 3e 69 42 75  ufStart], p->iBu
5840: 66 45 6e 64 20 2d 20 70 2d 3e 69 42 75 66 53 74  fEnd - p->iBufSt
5850: 61 72 74 2c 20 0a 20 20 20 20 20 20 20 20 70 2d  art, .        p-
5860: 3e 69 57 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e  >iWriteOff + p->
5870: 69 42 75 66 53 74 61 72 74 0a 20 20 20 20 29 3b  iBufStart.    );
5880: 0a 20 20 7d 0a 20 20 2a 70 69 45 6f 66 20 3d 20  .  }.  *piEof = 
5890: 28 70 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b 20  (p->iWriteOff + 
58a0: 70 2d 3e 69 42 75 66 45 6e 64 29 3b 0a 20 20 73  p->iBufEnd);.  s
58b0: 71 6c 69 74 65 33 44 62 46 72 65 65 28 64 62 2c  qlite3DbFree(db,
58c0: 20 70 2d 3e 61 42 75 66 66 65 72 29 3b 0a 20 20   p->aBuffer);.  
58d0: 72 63 20 3d 20 70 2d 3e 65 46 57 45 72 72 3b 0a  rc = p->eFWErr;.
58e0: 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73    memset(p, 0, s
58f0: 69 7a 65 6f 66 28 46 69 6c 65 57 72 69 74 65 72  izeof(FileWriter
5900: 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ));.  return rc;
5910: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20  .}../*.** Write 
5920: 76 61 6c 75 65 20 69 56 61 6c 20 65 6e 63 6f 64  value iVal encod
5930: 65 64 20 61 73 20 61 20 76 61 72 69 6e 74 20 74  ed as a varint t
5940: 6f 20 74 68 65 20 66 69 6c 65 2d 77 72 69 74 65  o the file-write
5950: 20 6f 62 6a 65 63 74 2e 20 52 65 74 75 72 6e 20   object. Return 
5960: 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66  .** SQLITE_OK if
5970: 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20   successful, or 
5980: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
5990: 63 6f 64 65 20 69 66 20 61 6e 20 65 72 72 6f 72  code if an error
59a0: 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74   occurs..*/.stat
59b0: 69 63 20 76 6f 69 64 20 66 69 6c 65 57 72 69 74  ic void fileWrit
59c0: 65 72 57 72 69 74 65 56 61 72 69 6e 74 28 46 69  erWriteVarint(Fi
59d0: 6c 65 57 72 69 74 65 72 20 2a 70 2c 20 75 36 34  leWriter *p, u64
59e0: 20 69 56 61 6c 29 7b 0a 20 20 69 6e 74 20 6e 42   iVal){.  int nB
59f0: 79 74 65 3b 20 0a 20 20 75 38 20 61 42 79 74 65  yte; .  u8 aByte
5a00: 5b 31 30 5d 3b 0a 20 20 6e 42 79 74 65 20 3d 20  [10];.  nByte = 
5a10: 73 71 6c 69 74 65 33 50 75 74 56 61 72 69 6e 74  sqlite3PutVarint
5a20: 28 61 42 79 74 65 2c 20 69 56 61 6c 29 3b 0a 20  (aByte, iVal);. 
5a30: 20 66 69 6c 65 57 72 69 74 65 72 57 72 69 74 65   fileWriterWrite
5a40: 28 70 2c 20 61 42 79 74 65 2c 20 6e 42 79 74 65  (p, aByte, nByte
5a50: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74  );.}../*.** Writ
5a60: 65 20 74 68 65 20 63 75 72 72 65 6e 74 20 63 6f  e the current co
5a70: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 69 6e  ntents of the in
5a80: 2d 6d 65 6d 6f 72 79 20 6c 69 6e 6b 65 64 2d 6c  -memory linked-l
5a90: 69 73 74 20 74 6f 20 61 20 50 4d 41 2e 20 52 65  ist to a PMA. Re
5aa0: 74 75 72 6e 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f  turn.** SQLITE_O
5ab0: 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c  K if successful,
5ac0: 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72   or an SQLite er
5ad0: 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77 69  ror code otherwi
5ae0: 73 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66 6f  se..**.** The fo
5af0: 72 6d 61 74 20 6f 66 20 61 20 50 4d 41 20 69 73  rmat of a PMA is
5b00: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 41 20  :.**.**     * A 
5b10: 76 61 72 69 6e 74 2e 20 54 68 69 73 20 76 61 72  varint. This var
5b20: 69 6e 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  int contains the
5b30: 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66   total number of
5b40: 20 62 79 74 65 73 20 6f 66 20 63 6f 6e 74 65 6e   bytes of conten
5b50: 74 0a 2a 2a 20 20 20 20 20 20 20 69 6e 20 74 68  t.**       in th
5b60: 65 20 50 4d 41 20 28 6e 6f 74 20 69 6e 63 6c 75  e PMA (not inclu
5b70: 64 69 6e 67 20 74 68 65 20 76 61 72 69 6e 74 20  ding the varint 
5b80: 69 74 73 65 6c 66 29 2e 0a 2a 2a 0a 2a 2a 20 20  itself)..**.**  
5b90: 20 20 20 2a 20 4f 6e 65 20 6f 72 20 6d 6f 72 65     * One or more
5ba0: 20 72 65 63 6f 72 64 73 20 70 61 63 6b 65 64 20   records packed 
5bb0: 65 6e 64 2d 74 6f 2d 65 6e 64 20 69 6e 20 6f 72  end-to-end in or
5bc0: 64 65 72 20 6f 66 20 61 73 63 65 6e 64 69 6e 67  der of ascending
5bd0: 20 6b 65 79 73 2e 20 0a 2a 2a 20 20 20 20 20 20   keys. .**      
5be0: 20 45 61 63 68 20 72 65 63 6f 72 64 20 63 6f 6e   Each record con
5bf0: 73 69 73 74 73 20 6f 66 20 61 20 76 61 72 69 6e  sists of a varin
5c00: 74 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 61 20  t followed by a 
5c10: 62 6c 6f 62 20 6f 66 20 64 61 74 61 20 28 74 68  blob of data (th
5c20: 65 20 0a 2a 2a 20 20 20 20 20 20 20 6b 65 79 29  e .**       key)
5c30: 2e 20 54 68 65 20 76 61 72 69 6e 74 20 69 73 20  . The varint is 
5c40: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79  the number of by
5c50: 74 65 73 20 69 6e 20 74 68 65 20 62 6c 6f 62 20  tes in the blob 
5c60: 6f 66 20 64 61 74 61 2e 0a 2a 2f 0a 73 74 61 74  of data..*/.stat
5c70: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
5c80: 72 4c 69 73 74 54 6f 50 4d 41 28 73 71 6c 69 74  rListToPMA(sqlit
5c90: 65 33 20 2a 64 62 2c 20 63 6f 6e 73 74 20 56 64  e3 *db, const Vd
5ca0: 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b  beCursor *pCsr){
5cb0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
5cc0: 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
5cd0: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
5ce0: 65 20 2a 2f 0a 20 20 56 64 62 65 53 6f 72 74 65  e */.  VdbeSorte
5cf0: 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73  r *pSorter = pCs
5d00: 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 46 69  r->pSorter;.  Fi
5d10: 6c 65 57 72 69 74 65 72 20 77 72 69 74 65 72 3b  leWriter writer;
5d20: 0a 0a 20 20 6d 65 6d 73 65 74 28 26 77 72 69 74  ..  memset(&writ
5d30: 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 46 69  er, 0, sizeof(Fi
5d40: 6c 65 57 72 69 74 65 72 29 29 3b 0a 0a 20 20 69  leWriter));..  i
5d50: 66 28 20 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d  f( pSorter->nInM
5d60: 65 6d 6f 72 79 3d 3d 30 20 29 7b 0a 20 20 20 20  emory==0 ){.    
5d70: 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d  assert( pSorter-
5d80: 3e 70 52 65 63 6f 72 64 3d 3d 30 20 29 3b 0a 20  >pRecord==0 );. 
5d90: 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
5da0: 7d 0a 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f  }..  rc = vdbeSo
5db0: 72 74 65 72 53 6f 72 74 28 70 43 73 72 29 3b 0a  rterSort(pCsr);.
5dc0: 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69 72  .  /* If the fir
5dd0: 73 74 20 74 65 6d 70 6f 72 61 72 79 20 50 4d 41  st temporary PMA
5de0: 20 66 69 6c 65 20 68 61 73 20 6e 6f 74 20 62 65   file has not be
5df0: 65 6e 20 6f 70 65 6e 65 64 2c 20 6f 70 65 6e 20  en opened, open 
5e00: 69 74 20 6e 6f 77 2e 20 2a 2f 0a 20 20 69 66 28  it now. */.  if(
5e10: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
5e20: 26 20 70 53 6f 72 74 65 72 2d 3e 70 54 65 6d 70  & pSorter->pTemp
5e30: 31 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d  1==0 ){.    rc =
5e40: 20 76 64 62 65 53 6f 72 74 65 72 4f 70 65 6e 54   vdbeSorterOpenT
5e50: 65 6d 70 46 69 6c 65 28 64 62 2c 20 26 70 53 6f  empFile(db, &pSo
5e60: 72 74 65 72 2d 3e 70 54 65 6d 70 31 29 3b 0a 20  rter->pTemp1);. 
5e70: 20 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 53     assert( rc!=S
5e80: 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53 6f 72  QLITE_OK || pSor
5e90: 74 65 72 2d 3e 70 54 65 6d 70 31 20 29 3b 0a 20  ter->pTemp1 );. 
5ea0: 20 20 20 61 73 73 65 72 74 28 20 70 53 6f 72 74     assert( pSort
5eb0: 65 72 2d 3e 69 57 72 69 74 65 4f 66 66 3d 3d 30  er->iWriteOff==0
5ec0: 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20   );.    assert( 
5ed0: 70 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 3d 3d 30  pSorter->nPMA==0
5ee0: 20 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72   );.  }..  if( r
5ef0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
5f00: 20 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64      SorterRecord
5f10: 20 2a 70 3b 0a 20 20 20 20 53 6f 72 74 65 72 52   *p;.    SorterR
5f20: 65 63 6f 72 64 20 2a 70 4e 65 78 74 20 3d 20 30  ecord *pNext = 0
5f30: 3b 0a 0a 20 20 20 20 66 69 6c 65 57 72 69 74 65  ;..    fileWrite
5f40: 72 49 6e 69 74 28 64 62 2c 20 70 53 6f 72 74 65  rInit(db, pSorte
5f50: 72 2d 3e 70 54 65 6d 70 31 2c 20 26 77 72 69 74  r->pTemp1, &writ
5f60: 65 72 2c 20 70 53 6f 72 74 65 72 2d 3e 69 57 72  er, pSorter->iWr
5f70: 69 74 65 4f 66 66 29 3b 0a 20 20 20 20 70 53 6f  iteOff);.    pSo
5f80: 72 74 65 72 2d 3e 6e 50 4d 41 2b 2b 3b 0a 20 20  rter->nPMA++;.  
5f90: 20 20 66 69 6c 65 57 72 69 74 65 72 57 72 69 74    fileWriterWrit
5fa0: 65 56 61 72 69 6e 74 28 26 77 72 69 74 65 72 2c  eVarint(&writer,
5fb0: 20 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d   pSorter->nInMem
5fc0: 6f 72 79 29 3b 0a 20 20 20 20 66 6f 72 28 70 3d  ory);.    for(p=
5fd0: 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64  pSorter->pRecord
5fe0: 3b 20 70 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20  ; p; p=pNext){. 
5ff0: 20 20 20 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e       pNext = p->
6000: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 66 69 6c  pNext;.      fil
6010: 65 57 72 69 74 65 72 57 72 69 74 65 56 61 72 69  eWriterWriteVari
6020: 6e 74 28 26 77 72 69 74 65 72 2c 20 70 2d 3e 6e  nt(&writer, p->n
6030: 56 61 6c 29 3b 0a 20 20 20 20 20 20 66 69 6c 65  Val);.      file
6040: 57 72 69 74 65 72 57 72 69 74 65 28 26 77 72 69  WriterWrite(&wri
6050: 74 65 72 2c 20 70 2d 3e 70 56 61 6c 2c 20 70 2d  ter, p->pVal, p-
6060: 3e 6e 56 61 6c 29 3b 0a 20 20 20 20 20 20 73 71  >nVal);.      sq
6070: 6c 69 74 65 33 44 62 46 72 65 65 28 64 62 2c 20  lite3DbFree(db, 
6080: 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 53  p);.    }.    pS
6090: 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 3d  orter->pRecord =
60a0: 20 70 3b 0a 20 20 20 20 72 63 20 3d 20 66 69 6c   p;.    rc = fil
60b0: 65 57 72 69 74 65 72 46 69 6e 69 73 68 28 64 62  eWriterFinish(db
60c0: 2c 20 26 77 72 69 74 65 72 2c 20 26 70 53 6f 72  , &writer, &pSor
60d0: 74 65 72 2d 3e 69 57 72 69 74 65 4f 66 66 29 3b  ter->iWriteOff);
60e0: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
60f0: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20  c;.}../*.** Add 
6100: 61 20 72 65 63 6f 72 64 20 74 6f 20 74 68 65 20  a record to the 
6110: 73 6f 72 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20 73  sorter..*/.int s
6120: 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72  qlite3VdbeSorter
6130: 57 72 69 74 65 28 0a 20 20 73 71 6c 69 74 65 33  Write(.  sqlite3
6140: 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20 20   *db,           
6150: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
6160: 62 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20  base handle */. 
6170: 20 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f   const VdbeCurso
6180: 72 20 2a 70 43 73 72 2c 20 20 20 20 20 20 20 20  r *pCsr,        
6190: 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72         /* Sorter
61a0: 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 4d 65 6d   cursor */.  Mem
61b0: 20 2a 70 56 61 6c 20 20 20 20 20 20 20 20 20 20   *pVal          
61c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
61d0: 4d 65 6d 6f 72 79 20 63 65 6c 6c 20 63 6f 6e 74  Memory cell cont
61e0: 61 69 6e 69 6e 67 20 72 65 63 6f 72 64 20 2a 2f  aining record */
61f0: 0a 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72  .){.  VdbeSorter
6200: 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72   *pSorter = pCsr
6210: 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74  ->pSorter;.  int
6220: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
6230: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6240: 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20  Return Code */. 
6250: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
6260: 4e 65 77 3b 20 20 20 20 20 20 20 20 20 20 20 20  New;            
6270: 20 2f 2a 20 4e 65 77 20 6c 69 73 74 20 65 6c 65   /* New list ele
6280: 6d 65 6e 74 20 2a 2f 0a 0a 20 20 61 73 73 65 72  ment */..  asser
6290: 74 28 20 70 53 6f 72 74 65 72 20 29 3b 0a 20 20  t( pSorter );.  
62a0: 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f  pSorter->nInMemo
62b0: 72 79 20 2b 3d 20 73 71 6c 69 74 65 33 56 61 72  ry += sqlite3Var
62c0: 69 6e 74 4c 65 6e 28 70 56 61 6c 2d 3e 6e 29 20  intLen(pVal->n) 
62d0: 2b 20 70 56 61 6c 2d 3e 6e 3b 0a 0a 20 20 70 4e  + pVal->n;..  pN
62e0: 65 77 20 3d 20 28 53 6f 72 74 65 72 52 65 63 6f  ew = (SorterReco
62f0: 72 64 20 2a 29 73 71 6c 69 74 65 33 44 62 4d 61  rd *)sqlite3DbMa
6300: 6c 6c 6f 63 52 61 77 28 64 62 2c 20 70 56 61 6c  llocRaw(db, pVal
6310: 2d 3e 6e 20 2b 20 73 69 7a 65 6f 66 28 53 6f 72  ->n + sizeof(Sor
6320: 74 65 72 52 65 63 6f 72 64 29 29 3b 0a 20 20 69  terRecord));.  i
6330: 66 28 20 70 4e 65 77 3d 3d 30 20 29 7b 0a 20 20  f( pNew==0 ){.  
6340: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
6350: 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  MEM;.  }else{.  
6360: 20 20 70 4e 65 77 2d 3e 70 56 61 6c 20 3d 20 28    pNew->pVal = (
6370: 76 6f 69 64 20 2a 29 26 70 4e 65 77 5b 31 5d 3b  void *)&pNew[1];
6380: 0a 20 20 20 20 6d 65 6d 63 70 79 28 70 4e 65 77  .    memcpy(pNew
6390: 2d 3e 70 56 61 6c 2c 20 70 56 61 6c 2d 3e 7a 2c  ->pVal, pVal->z,
63a0: 20 70 56 61 6c 2d 3e 6e 29 3b 0a 20 20 20 20 70   pVal->n);.    p
63b0: 4e 65 77 2d 3e 6e 56 61 6c 20 3d 20 70 56 61 6c  New->nVal = pVal
63c0: 2d 3e 6e 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 70  ->n;.    pNew->p
63d0: 4e 65 78 74 20 3d 20 70 53 6f 72 74 65 72 2d 3e  Next = pSorter->
63e0: 70 52 65 63 6f 72 64 3b 0a 20 20 20 20 70 53 6f  pRecord;.    pSo
63f0: 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 3d 20  rter->pRecord = 
6400: 70 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  pNew;.  }..  /* 
6410: 53 65 65 20 69 66 20 74 68 65 20 63 6f 6e 74 65  See if the conte
6420: 6e 74 73 20 6f 66 20 74 68 65 20 73 6f 72 74 65  nts of the sorte
6430: 72 20 73 68 6f 75 6c 64 20 6e 6f 77 20 62 65 20  r should now be 
6440: 77 72 69 74 74 65 6e 20 6f 75 74 2e 20 54 68 65  written out. The
6450: 79 0a 20 20 2a 2a 20 61 72 65 20 77 72 69 74 74  y.  ** are writt
6460: 65 6e 20 6f 75 74 20 77 68 65 6e 20 65 69 74 68  en out when eith
6470: 65 72 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77  er of the follow
6480: 69 6e 67 20 61 72 65 20 74 72 75 65 3a 0a 20 20  ing are true:.  
6490: 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 54 68 65 20  **.  **   * The 
64a0: 74 6f 74 61 6c 20 6d 65 6d 6f 72 79 20 61 6c 6c  total memory all
64b0: 6f 63 61 74 65 64 20 66 6f 72 20 74 68 65 20 69  ocated for the i
64c0: 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20 69 73  n-memory list is
64d0: 20 67 72 65 61 74 65 72 20 0a 20 20 2a 2a 20 20   greater .  **  
64e0: 20 20 20 74 68 61 6e 20 28 70 61 67 65 2d 73 69     than (page-si
64f0: 7a 65 20 2a 20 63 61 63 68 65 2d 73 69 7a 65 29  ze * cache-size)
6500: 2c 20 6f 72 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20  , or.  **.  **  
6510: 20 2a 20 54 68 65 20 74 6f 74 61 6c 20 6d 65 6d   * The total mem
6520: 6f 72 79 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f  ory allocated fo
6530: 72 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20  r the in-memory 
6540: 6c 69 73 74 20 69 73 20 67 72 65 61 74 65 72 20  list is greater 
6550: 0a 20 20 2a 2a 20 20 20 20 20 74 68 61 6e 20 28  .  **     than (
6560: 70 61 67 65 2d 73 69 7a 65 20 2a 20 31 30 29 20  page-size * 10) 
6570: 61 6e 64 20 73 71 6c 69 74 65 33 48 65 61 70 4e  and sqlite3HeapN
6580: 65 61 72 6c 79 46 75 6c 6c 28 29 20 72 65 74 75  earlyFull() retu
6590: 72 6e 73 20 74 72 75 65 2e 0a 20 20 2a 2f 0a 20  rns true..  */. 
65a0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
65b0: 4f 4b 20 26 26 20 70 53 6f 72 74 65 72 2d 3e 6d  OK && pSorter->m
65c0: 78 50 6d 61 53 69 7a 65 3e 30 20 26 26 20 28 0a  xPmaSize>0 && (.
65d0: 20 20 20 20 20 20 20 20 28 70 53 6f 72 74 65 72          (pSorter
65e0: 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 3e 70 53 6f 72  ->nInMemory>pSor
65f0: 74 65 72 2d 3e 6d 78 50 6d 61 53 69 7a 65 29 0a  ter->mxPmaSize).
6600: 20 20 20 20 20 7c 7c 20 28 70 53 6f 72 74 65 72       || (pSorter
6610: 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 3e 70 53 6f 72  ->nInMemory>pSor
6620: 74 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a 65 20 26  ter->mnPmaSize &
6630: 26 20 73 71 6c 69 74 65 33 48 65 61 70 4e 65 61  & sqlite3HeapNea
6640: 72 6c 79 46 75 6c 6c 28 29 29 0a 20 20 29 29 7b  rlyFull()).  )){
6650: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 44  .#ifdef SQLITE_D
6660: 45 42 55 47 0a 20 20 20 20 69 36 34 20 6e 45 78  EBUG.    i64 nEx
6670: 70 65 63 74 20 3d 20 70 53 6f 72 74 65 72 2d 3e  pect = pSorter->
6680: 69 57 72 69 74 65 4f 66 66 0a 20 20 20 20 20 20  iWriteOff.      
6690: 20 20 20 20 20 20 20 20 20 20 2b 20 73 71 6c 69            + sqli
66a0: 74 65 33 56 61 72 69 6e 74 4c 65 6e 28 70 53 6f  te3VarintLen(pSo
66b0: 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 29  rter->nInMemory)
66c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
66d0: 20 2b 20 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d   + pSorter->nInM
66e0: 65 6d 6f 72 79 3b 0a 23 65 6e 64 69 66 0a 20 20  emory;.#endif.  
66f0: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
6700: 72 4c 69 73 74 54 6f 50 4d 41 28 64 62 2c 20 70  rListToPMA(db, p
6710: 43 73 72 29 3b 0a 20 20 20 20 70 53 6f 72 74 65  Csr);.    pSorte
6720: 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20 3d 20 30  r->nInMemory = 0
6730: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 72 63  ;.    assert( rc
6740: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 28  !=SQLITE_OK || (
6750: 6e 45 78 70 65 63 74 3d 3d 70 53 6f 72 74 65 72  nExpect==pSorter
6760: 2d 3e 69 57 72 69 74 65 4f 66 66 29 20 29 3b 0a  ->iWriteOff) );.
6770: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
6780: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 48 65 6c 70 65  ;.}../*.** Helpe
6790: 72 20 66 75 6e 63 74 69 6f 6e 20 66 6f 72 20 73  r function for s
67a0: 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72  qlite3VdbeSorter
67b0: 52 65 77 69 6e 64 28 29 2e 20 0a 2a 2f 0a 73 74  Rewind(). .*/.st
67c0: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
67d0: 74 65 72 49 6e 69 74 4d 65 72 67 65 28 0a 20 20  terInitMerge(.  
67e0: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20  sqlite3 *db,    
67f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6800: 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e 64  /* Database hand
6810: 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 56 64  le */.  const Vd
6820: 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  beCursor *pCsr, 
6830: 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 73 6f          /* Curso
6840: 72 20 68 61 6e 64 6c 65 20 66 6f 72 20 74 68 69  r handle for thi
6850: 73 20 73 6f 72 74 65 72 20 2a 2f 0a 20 20 69 36  s sorter */.  i6
6860: 34 20 2a 70 6e 42 79 74 65 20 20 20 20 20 20 20  4 *pnByte       
6870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6880: 20 53 75 6d 20 6f 66 20 62 79 74 65 73 20 69 6e   Sum of bytes in
6890: 20 61 6c 6c 20 6f 70 65 6e 65 64 20 50 4d 41 73   all opened PMAs
68a0: 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65 53 6f 72   */.){.  VdbeSor
68b0: 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70  ter *pSorter = p
68c0: 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20  Csr->pSorter;.  
68d0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
68e0: 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  OK;             
68f0: 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
6900: 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20  /.  int i;      
6910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6920: 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69      /* Used to i
6930: 74 65 72 61 74 6f 72 20 74 68 72 6f 75 67 68 20  terator through 
6940: 61 49 74 65 72 5b 5d 20 2a 2f 0a 20 20 69 36 34  aIter[] */.  i64
6950: 20 6e 42 79 74 65 20 3d 20 30 3b 20 20 20 20 20   nByte = 0;     
6960: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6970: 54 6f 74 61 6c 20 62 79 74 65 73 20 69 6e 20 61  Total bytes in a
6980: 6c 6c 20 6f 70 65 6e 65 64 20 50 4d 41 73 20 2a  ll opened PMAs *
6990: 2f 0a 0a 20 20 2f 2a 20 49 6e 69 74 69 61 6c 69  /..  /* Initiali
69a0: 7a 65 20 74 68 65 20 69 74 65 72 61 74 6f 72 73  ze the iterators
69b0: 2e 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20  . */.  for(i=0; 
69c0: 69 3c 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52  i<SORTER_MAX_MER
69d0: 47 45 5f 43 4f 55 4e 54 3b 20 69 2b 2b 29 7b 0a  GE_COUNT; i++){.
69e0: 20 20 20 20 56 64 62 65 53 6f 72 74 65 72 49 74      VdbeSorterIt
69f0: 65 72 20 2a 70 49 74 65 72 20 3d 20 26 70 53 6f  er *pIter = &pSo
6a00: 72 74 65 72 2d 3e 61 49 74 65 72 5b 69 5d 3b 0a  rter->aIter[i];.
6a10: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
6a20: 74 65 72 49 74 65 72 49 6e 69 74 28 64 62 2c 20  terIterInit(db, 
6a30: 70 53 6f 72 74 65 72 2c 20 70 53 6f 72 74 65 72  pSorter, pSorter
6a40: 2d 3e 69 52 65 61 64 4f 66 66 2c 20 70 49 74 65  ->iReadOff, pIte
6a50: 72 2c 20 26 6e 42 79 74 65 29 3b 0a 20 20 20 20  r, &nByte);.    
6a60: 70 53 6f 72 74 65 72 2d 3e 69 52 65 61 64 4f 66  pSorter->iReadOf
6a70: 66 20 3d 20 70 49 74 65 72 2d 3e 69 45 6f 66 3b  f = pIter->iEof;
6a80: 0a 20 20 20 20 61 73 73 65 72 74 28 20 72 63 21  .    assert( rc!
6a90: 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53  =SQLITE_OK || pS
6aa0: 6f 72 74 65 72 2d 3e 69 52 65 61 64 4f 66 66 3c  orter->iReadOff<
6ab0: 3d 70 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65  =pSorter->iWrite
6ac0: 4f 66 66 20 29 3b 0a 20 20 20 20 69 66 28 20 72  Off );.    if( r
6ad0: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20  c!=SQLITE_OK || 
6ae0: 70 53 6f 72 74 65 72 2d 3e 69 52 65 61 64 4f 66  pSorter->iReadOf
6af0: 66 3e 3d 70 53 6f 72 74 65 72 2d 3e 69 57 72 69  f>=pSorter->iWri
6b00: 74 65 4f 66 66 20 29 20 62 72 65 61 6b 3b 0a 20  teOff ) break;. 
6b10: 20 7d 0a 0a 20 20 2f 2a 20 49 6e 69 74 69 61 6c   }..  /* Initial
6b20: 69 7a 65 20 74 68 65 20 61 54 72 65 65 5b 5d 20  ize the aTree[] 
6b30: 61 72 72 61 79 2e 20 2a 2f 0a 20 20 66 6f 72 28  array. */.  for(
6b40: 69 3d 70 53 6f 72 74 65 72 2d 3e 6e 54 72 65 65  i=pSorter->nTree
6b50: 2d 31 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  -1; rc==SQLITE_O
6b60: 4b 20 26 26 20 69 3e 30 3b 20 69 2d 2d 29 7b 0a  K && i>0; i--){.
6b70: 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72      rc = vdbeSor
6b80: 74 65 72 44 6f 43 6f 6d 70 61 72 65 28 70 43 73  terDoCompare(pCs
6b90: 72 2c 20 69 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70  r, i);.  }..  *p
6ba0: 6e 42 79 74 65 20 3d 20 6e 42 79 74 65 3b 0a 20  nByte = nByte;. 
6bb0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
6bc0: 2a 0a 2a 2a 20 4f 6e 63 65 20 74 68 65 20 73 6f  *.** Once the so
6bd0: 72 74 65 72 20 68 61 73 20 62 65 65 6e 20 70 6f  rter has been po
6be0: 70 75 6c 61 74 65 64 2c 20 74 68 69 73 20 66 75  pulated, this fu
6bf0: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
6c00: 20 74 6f 20 70 72 65 70 61 72 65 0a 2a 2a 20 66   to prepare.** f
6c10: 6f 72 20 69 74 65 72 61 74 69 6e 67 20 74 68 72  or iterating thr
6c20: 6f 75 67 68 20 69 74 73 20 63 6f 6e 74 65 6e 74  ough its content
6c30: 73 20 69 6e 20 73 6f 72 74 65 64 20 6f 72 64 65  s in sorted orde
6c40: 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  r..*/.int sqlite
6c50: 33 56 64 62 65 53 6f 72 74 65 72 52 65 77 69 6e  3VdbeSorterRewin
6c60: 64 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 63  d(sqlite3 *db, c
6c70: 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72 20  onst VdbeCursor 
6c80: 2a 70 43 73 72 2c 20 69 6e 74 20 2a 70 62 45 6f  *pCsr, int *pbEo
6c90: 66 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72  f){.  VdbeSorter
6ca0: 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72   *pSorter = pCsr
6cb0: 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74  ->pSorter;.  int
6cc0: 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
6cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6ce0: 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
6cf0: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
6d00: 54 65 6d 70 32 20 3d 20 30 3b 20 20 20 20 20 20  Temp2 = 0;      
6d10: 20 2f 2a 20 53 65 63 6f 6e 64 20 74 65 6d 70 20   /* Second temp 
6d20: 66 69 6c 65 20 74 6f 20 75 73 65 20 2a 2f 0a 20  file to use */. 
6d30: 20 69 36 34 20 69 57 72 69 74 65 32 20 3d 20 30   i64 iWrite2 = 0
6d40: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
6d50: 20 2f 2a 20 57 72 69 74 65 20 6f 66 66 73 65 74   /* Write offset
6d60: 20 66 6f 72 20 70 54 65 6d 70 32 20 2a 2f 0a 20   for pTemp2 */. 
6d70: 20 69 6e 74 20 6e 49 74 65 72 3b 20 20 20 20 20   int nIter;     
6d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d90: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 69 74   /* Number of it
6da0: 65 72 61 74 6f 72 73 20 75 73 65 64 20 2a 2f 0a  erators used */.
6db0: 20 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20    int nByte;    
6dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6dd0: 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 73 70    /* Bytes of sp
6de0: 61 63 65 20 72 65 71 75 69 72 65 64 20 66 6f 72  ace required for
6df0: 20 61 49 74 65 72 2f 61 54 72 65 65 20 2a 2f 0a   aIter/aTree */.
6e00: 20 20 69 6e 74 20 4e 20 3d 20 32 3b 20 20 20 20    int N = 2;    
6e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6e20: 20 20 2f 2a 20 50 6f 77 65 72 20 6f 66 20 32 20    /* Power of 2 
6e30: 3e 3d 20 6e 49 74 65 72 20 2a 2f 0a 0a 20 20 61  >= nIter */..  a
6e40: 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 20 29  ssert( pSorter )
6e50: 3b 0a 0a 20 20 2f 2a 20 49 66 20 6e 6f 20 64 61  ;..  /* If no da
6e60: 74 61 20 68 61 73 20 62 65 65 6e 20 77 72 69 74  ta has been writ
6e70: 74 65 6e 20 74 6f 20 64 69 73 6b 2c 20 74 68 65  ten to disk, the
6e80: 6e 20 64 6f 20 6e 6f 74 20 64 6f 20 73 6f 20 6e  n do not do so n
6e90: 6f 77 2e 20 49 6e 73 74 65 61 64 2c 0a 20 20 2a  ow. Instead,.  *
6ea0: 2a 20 73 6f 72 74 20 74 68 65 20 56 64 62 65 53  * sort the VdbeS
6eb0: 6f 72 74 65 72 2e 70 52 65 63 6f 72 64 20 6c 69  orter.pRecord li
6ec0: 73 74 2e 20 54 68 65 20 76 64 62 65 20 6c 61 79  st. The vdbe lay
6ed0: 65 72 20 77 69 6c 6c 20 72 65 61 64 20 64 61 74  er will read dat
6ee0: 61 20 64 69 72 65 63 74 6c 79 0a 20 20 2a 2a 20  a directly.  ** 
6ef0: 66 72 6f 6d 20 74 68 65 20 69 6e 2d 6d 65 6d 6f  from the in-memo
6f00: 72 79 20 6c 69 73 74 2e 20 20 2a 2f 0a 20 20 69  ry list.  */.  i
6f10: 66 28 20 70 53 6f 72 74 65 72 2d 3e 6e 50 4d 41  f( pSorter->nPMA
6f20: 3d 3d 30 20 29 7b 0a 20 20 20 20 2a 70 62 45 6f  ==0 ){.    *pbEo
6f30: 66 20 3d 20 21 70 53 6f 72 74 65 72 2d 3e 70 52  f = !pSorter->pR
6f40: 65 63 6f 72 64 3b 0a 20 20 20 20 61 73 73 65 72  ecord;.    asser
6f50: 74 28 20 70 53 6f 72 74 65 72 2d 3e 61 54 72 65  t( pSorter->aTre
6f60: 65 3d 3d 30 20 29 3b 0a 20 20 20 20 72 65 74 75  e==0 );.    retu
6f70: 72 6e 20 76 64 62 65 53 6f 72 74 65 72 53 6f 72  rn vdbeSorterSor
6f80: 74 28 70 43 73 72 29 3b 0a 20 20 7d 0a 0a 20 20  t(pCsr);.  }..  
6f90: 2f 2a 20 57 72 69 74 65 20 74 68 65 20 63 75 72  /* Write the cur
6fa0: 72 65 6e 74 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c  rent in-memory l
6fb0: 69 73 74 20 74 6f 20 61 20 50 4d 41 2e 20 2a 2f  ist to a PMA. */
6fc0: 0a 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74  .  rc = vdbeSort
6fd0: 65 72 4c 69 73 74 54 6f 50 4d 41 28 64 62 2c 20  erListToPMA(db, 
6fe0: 70 43 73 72 29 3b 0a 20 20 69 66 28 20 72 63 21  pCsr);.  if( rc!
6ff0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
7000: 75 72 6e 20 72 63 3b 0a 0a 20 20 2f 2a 20 41 6c  urn rc;..  /* Al
7010: 6c 6f 63 61 74 65 20 73 70 61 63 65 20 66 6f 72  locate space for
7020: 20 61 49 74 65 72 5b 5d 20 61 6e 64 20 61 54 72   aIter[] and aTr
7030: 65 65 5b 5d 2e 20 2a 2f 0a 20 20 6e 49 74 65 72  ee[]. */.  nIter
7040: 20 3d 20 70 53 6f 72 74 65 72 2d 3e 6e 50 4d 41   = pSorter->nPMA
7050: 3b 0a 20 20 69 66 28 20 6e 49 74 65 72 3e 53 4f  ;.  if( nIter>SO
7060: 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
7070: 4f 55 4e 54 20 29 20 6e 49 74 65 72 20 3d 20 53  OUNT ) nIter = S
7080: 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f  ORTER_MAX_MERGE_
7090: 43 4f 55 4e 54 3b 0a 20 20 61 73 73 65 72 74 28  COUNT;.  assert(
70a0: 20 6e 49 74 65 72 3e 30 20 29 3b 0a 20 20 77 68   nIter>0 );.  wh
70b0: 69 6c 65 28 20 4e 3c 6e 49 74 65 72 20 29 20 4e  ile( N<nIter ) N
70c0: 20 2b 3d 20 4e 3b 0a 20 20 6e 42 79 74 65 20 3d   += N;.  nByte =
70d0: 20 4e 20 2a 20 28 73 69 7a 65 6f 66 28 69 6e 74   N * (sizeof(int
70e0: 29 20 2b 20 73 69 7a 65 6f 66 28 56 64 62 65 53  ) + sizeof(VdbeS
70f0: 6f 72 74 65 72 49 74 65 72 29 29 3b 0a 20 20 70  orterIter));.  p
7100: 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 20 3d 20  Sorter->aIter = 
7110: 28 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20  (VdbeSorterIter 
7120: 2a 29 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f  *)sqlite3DbMallo
7130: 63 5a 65 72 6f 28 64 62 2c 20 6e 42 79 74 65 29  cZero(db, nByte)
7140: 3b 0a 20 20 69 66 28 20 21 70 53 6f 72 74 65 72  ;.  if( !pSorter
7150: 2d 3e 61 49 74 65 72 20 29 20 72 65 74 75 72 6e  ->aIter ) return
7160: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
7170: 20 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 20   pSorter->aTree 
7180: 3d 20 28 69 6e 74 20 2a 29 26 70 53 6f 72 74 65  = (int *)&pSorte
7190: 72 2d 3e 61 49 74 65 72 5b 4e 5d 3b 0a 20 20 70  r->aIter[N];.  p
71a0: 53 6f 72 74 65 72 2d 3e 6e 54 72 65 65 20 3d 20  Sorter->nTree = 
71b0: 4e 3b 0a 0a 20 20 64 6f 20 7b 0a 20 20 20 20 69  N;..  do {.    i
71c0: 6e 74 20 69 4e 65 77 3b 20 20 20 20 20 20 20 20  nt iNew;        
71d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
71e0: 49 6e 64 65 78 20 6f 66 20 6e 65 77 2c 20 6d 65  Index of new, me
71f0: 72 67 65 64 2c 20 50 4d 41 20 2a 2f 0a 0a 20 20  rged, PMA */..  
7200: 20 20 66 6f 72 28 69 4e 65 77 3d 30 3b 20 0a 20    for(iNew=0; . 
7210: 20 20 20 20 20 20 20 72 63 3d 3d 53 51 4c 49 54         rc==SQLIT
7220: 45 5f 4f 4b 20 26 26 20 69 4e 65 77 2a 53 4f 52  E_OK && iNew*SOR
7230: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
7240: 55 4e 54 3c 70 53 6f 72 74 65 72 2d 3e 6e 50 4d  UNT<pSorter->nPM
7250: 41 3b 20 0a 20 20 20 20 20 20 20 20 69 4e 65 77  A; .        iNew
7260: 2b 2b 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20  ++.    ){.      
7270: 69 6e 74 20 72 63 32 3b 20 20 20 20 20 20 20 20  int rc2;        
7280: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
7290: 65 74 75 72 6e 20 63 6f 64 65 20 66 72 6f 6d 20  eturn code from 
72a0: 66 69 6c 65 57 72 69 74 65 72 46 69 6e 69 73 68  fileWriterFinish
72b0: 28 29 20 2a 2f 0a 20 20 20 20 20 20 46 69 6c 65  () */.      File
72c0: 57 72 69 74 65 72 20 77 72 69 74 65 72 3b 20 20  Writer writer;  
72d0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63          /* Objec
72e0: 74 20 75 73 65 64 20 74 6f 20 77 72 69 74 65 20  t used to write 
72f0: 74 6f 20 64 69 73 6b 20 2a 2f 0a 20 20 20 20 20  to disk */.     
7300: 20 69 36 34 20 6e 57 72 69 74 65 3b 20 20 20 20   i64 nWrite;    
7310: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7320: 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  Number of bytes 
7330: 69 6e 20 6e 65 77 20 50 4d 41 20 2a 2f 0a 0a 20  in new PMA */.. 
7340: 20 20 20 20 20 6d 65 6d 73 65 74 28 26 77 72 69       memset(&wri
7350: 74 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 46  ter, 0, sizeof(F
7360: 69 6c 65 57 72 69 74 65 72 29 29 3b 0a 0a 20 20  ileWriter));..  
7370: 20 20 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20      /* If there 
7380: 61 72 65 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d  are SORTER_MAX_M
7390: 45 52 47 45 5f 43 4f 55 4e 54 20 6f 72 20 6c 65  ERGE_COUNT or le
73a0: 73 73 20 50 4d 41 73 20 69 6e 20 66 69 6c 65 20  ss PMAs in file 
73b0: 70 54 65 6d 70 31 2c 0a 20 20 20 20 20 20 2a 2a  pTemp1,.      **
73c0: 20 69 6e 69 74 69 61 6c 69 7a 65 20 61 6e 20 69   initialize an i
73d0: 74 65 72 61 74 6f 72 20 66 6f 72 20 65 61 63 68  terator for each
73e0: 20 6f 66 20 74 68 65 6d 20 61 6e 64 20 62 72 65   of them and bre
73f0: 61 6b 20 6f 75 74 20 6f 66 20 74 68 65 20 6c 6f  ak out of the lo
7400: 6f 70 2e 0a 20 20 20 20 20 20 2a 2a 20 54 68 65  op..      ** The
7410: 73 65 20 69 74 65 72 61 74 6f 72 73 20 77 69 6c  se iterators wil
7420: 6c 20 62 65 20 69 6e 63 72 65 6d 65 6e 74 61 6c  l be incremental
7430: 6c 79 20 6d 65 72 67 65 64 20 61 73 20 74 68 65  ly merged as the
7440: 20 56 44 42 45 20 6c 61 79 65 72 20 63 61 6c 6c   VDBE layer call
7450: 73 0a 20 20 20 20 20 20 2a 2a 20 73 71 6c 69 74  s.      ** sqlit
7460: 65 33 56 64 62 65 53 6f 72 74 65 72 4e 65 78 74  e3VdbeSorterNext
7470: 28 29 2e 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20  ()..      **.   
7480: 20 20 20 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c     ** Otherwise,
7490: 20 69 66 20 70 54 65 6d 70 31 20 63 6f 6e 74 61   if pTemp1 conta
74a0: 69 6e 73 20 6d 6f 72 65 20 74 68 61 6e 20 53 4f  ins more than SO
74b0: 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
74c0: 4f 55 4e 54 20 50 4d 41 73 2c 0a 20 20 20 20 20  OUNT PMAs,.     
74d0: 20 2a 2a 20 69 6e 69 74 69 61 6c 69 7a 65 20 69   ** initialize i
74e0: 6e 74 65 72 61 74 6f 72 73 20 66 6f 72 20 53 4f  nterators for SO
74f0: 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
7500: 4f 55 4e 54 20 6f 66 20 74 68 65 6d 2e 20 54 68  OUNT of them. Th
7510: 65 73 65 20 50 4d 41 73 0a 20 20 20 20 20 20 2a  ese PMAs.      *
7520: 2a 20 61 72 65 20 6d 65 72 67 65 64 20 69 6e 74  * are merged int
7530: 6f 20 61 20 73 69 6e 67 6c 65 20 50 4d 41 20 74  o a single PMA t
7540: 68 61 74 20 69 73 20 77 72 69 74 74 65 6e 20 74  hat is written t
7550: 6f 20 66 69 6c 65 20 70 54 65 6d 70 32 2e 0a 20  o file pTemp2.. 
7560: 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 72 63       */.      rc
7570: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 49 6e 69   = vdbeSorterIni
7580: 74 4d 65 72 67 65 28 64 62 2c 20 70 43 73 72 2c  tMerge(db, pCsr,
7590: 20 26 6e 57 72 69 74 65 29 3b 0a 20 20 20 20 20   &nWrite);.     
75a0: 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c   assert( rc!=SQL
75b0: 49 54 45 5f 4f 4b 20 7c 7c 20 70 53 6f 72 74 65  ITE_OK || pSorte
75c0: 72 2d 3e 61 49 74 65 72 5b 20 70 53 6f 72 74 65  r->aIter[ pSorte
75d0: 72 2d 3e 61 54 72 65 65 5b 31 5d 20 5d 2e 70 46  r->aTree[1] ].pF
75e0: 69 6c 65 20 29 3b 0a 20 20 20 20 20 20 69 66 28  ile );.      if(
75f0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c   rc!=SQLITE_OK |
7600: 7c 20 70 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 3c  | pSorter->nPMA<
7610: 3d 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47  =SORTER_MAX_MERG
7620: 45 5f 43 4f 55 4e 54 20 29 7b 0a 20 20 20 20 20  E_COUNT ){.     
7630: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
7640: 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 4f 70 65 6e  }..      /* Open
7650: 20 74 68 65 20 73 65 63 6f 6e 64 20 74 65 6d 70   the second temp
7660: 20 66 69 6c 65 2c 20 69 66 20 69 74 20 69 73 20   file, if it is 
7670: 6e 6f 74 20 61 6c 72 65 61 64 79 20 6f 70 65 6e  not already open
7680: 2e 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 70  . */.      if( p
7690: 54 65 6d 70 32 3d 3d 30 20 29 7b 0a 20 20 20 20  Temp2==0 ){.    
76a0: 20 20 20 20 61 73 73 65 72 74 28 20 69 57 72 69      assert( iWri
76b0: 74 65 32 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20  te2==0 );.      
76c0: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
76d0: 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 64 62  rOpenTempFile(db
76e0: 2c 20 26 70 54 65 6d 70 32 29 3b 0a 20 20 20 20  , &pTemp2);.    
76f0: 20 20 7d 0a 0a 20 20 20 20 20 20 69 66 28 20 72    }..      if( r
7700: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
7710: 20 20 20 20 20 20 20 20 69 6e 74 20 62 45 6f 66          int bEof
7720: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 66 69   = 0;.        fi
7730: 6c 65 57 72 69 74 65 72 49 6e 69 74 28 64 62 2c  leWriterInit(db,
7740: 20 70 54 65 6d 70 32 2c 20 26 77 72 69 74 65 72   pTemp2, &writer
7750: 2c 20 69 57 72 69 74 65 32 29 3b 0a 20 20 20 20  , iWrite2);.    
7760: 20 20 20 20 66 69 6c 65 57 72 69 74 65 72 57 72      fileWriterWr
7770: 69 74 65 56 61 72 69 6e 74 28 26 77 72 69 74 65  iteVarint(&write
7780: 72 2c 20 6e 57 72 69 74 65 29 3b 0a 20 20 20 20  r, nWrite);.    
7790: 20 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 53      while( rc==S
77a0: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 62 45 6f 66  QLITE_OK && bEof
77b0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ==0 ){.         
77c0: 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20   VdbeSorterIter 
77d0: 2a 70 49 74 65 72 20 3d 20 26 70 53 6f 72 74 65  *pIter = &pSorte
77e0: 72 2d 3e 61 49 74 65 72 5b 20 70 53 6f 72 74 65  r->aIter[ pSorte
77f0: 72 2d 3e 61 54 72 65 65 5b 31 5d 20 5d 3b 0a 20  r->aTree[1] ];. 
7800: 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28           assert(
7810: 20 70 49 74 65 72 2d 3e 70 46 69 6c 65 20 29 3b   pIter->pFile );
7820: 0a 0a 20 20 20 20 20 20 20 20 20 20 66 69 6c 65  ..          file
7830: 57 72 69 74 65 72 57 72 69 74 65 56 61 72 69 6e  WriterWriteVarin
7840: 74 28 26 77 72 69 74 65 72 2c 20 70 49 74 65 72  t(&writer, pIter
7850: 2d 3e 6e 4b 65 79 29 3b 0a 20 20 20 20 20 20 20  ->nKey);.       
7860: 20 20 20 66 69 6c 65 57 72 69 74 65 72 57 72 69     fileWriterWri
7870: 74 65 28 26 77 72 69 74 65 72 2c 20 70 49 74 65  te(&writer, pIte
7880: 72 2d 3e 61 4b 65 79 2c 20 70 49 74 65 72 2d 3e  r->aKey, pIter->
7890: 6e 4b 65 79 29 3b 0a 20 20 20 20 20 20 20 20 20  nKey);.         
78a0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 56 64 62   rc = sqlite3Vdb
78b0: 65 53 6f 72 74 65 72 4e 65 78 74 28 64 62 2c 20  eSorterNext(db, 
78c0: 70 43 73 72 2c 20 26 62 45 6f 66 29 3b 0a 20 20  pCsr, &bEof);.  
78d0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
78e0: 72 63 32 20 3d 20 66 69 6c 65 57 72 69 74 65 72  rc2 = fileWriter
78f0: 46 69 6e 69 73 68 28 64 62 2c 20 26 77 72 69 74  Finish(db, &writ
7900: 65 72 2c 20 26 69 57 72 69 74 65 32 29 3b 0a 20  er, &iWrite2);. 
7910: 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
7920: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20  QLITE_OK ) rc = 
7930: 72 63 32 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  rc2;.      }.   
7940: 20 7d 0a 0a 20 20 20 20 69 66 28 20 70 53 6f 72   }..    if( pSor
7950: 74 65 72 2d 3e 6e 50 4d 41 3c 3d 53 4f 52 54 45  ter->nPMA<=SORTE
7960: 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
7970: 54 20 29 7b 0a 20 20 20 20 20 20 62 72 65 61 6b  T ){.      break
7980: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
7990: 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20     sqlite3_file 
79a0: 2a 70 54 6d 70 20 3d 20 70 53 6f 72 74 65 72 2d  *pTmp = pSorter-
79b0: 3e 70 54 65 6d 70 31 3b 0a 20 20 20 20 20 20 70  >pTemp1;.      p
79c0: 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 20 3d 20 69  Sorter->nPMA = i
79d0: 4e 65 77 3b 0a 20 20 20 20 20 20 70 53 6f 72 74  New;.      pSort
79e0: 65 72 2d 3e 70 54 65 6d 70 31 20 3d 20 70 54 65  er->pTemp1 = pTe
79f0: 6d 70 32 3b 0a 20 20 20 20 20 20 70 54 65 6d 70  mp2;.      pTemp
7a00: 32 20 3d 20 70 54 6d 70 3b 0a 20 20 20 20 20 20  2 = pTmp;.      
7a10: 70 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f  pSorter->iWriteO
7a20: 66 66 20 3d 20 69 57 72 69 74 65 32 3b 0a 20 20  ff = iWrite2;.  
7a30: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 69 52 65      pSorter->iRe
7a40: 61 64 4f 66 66 20 3d 20 30 3b 0a 20 20 20 20 20  adOff = 0;.     
7a50: 20 69 57 72 69 74 65 32 20 3d 20 30 3b 0a 20 20   iWrite2 = 0;.  
7a60: 20 20 7d 0a 20 20 7d 77 68 69 6c 65 28 20 72 63    }.  }while( rc
7a70: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 0a  ==SQLITE_OK );..
7a80: 20 20 69 66 28 20 70 54 65 6d 70 32 20 29 7b 0a    if( pTemp2 ){.
7a90: 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43 6c 6f      sqlite3OsClo
7aa0: 73 65 46 72 65 65 28 70 54 65 6d 70 32 29 3b 0a  seFree(pTemp2);.
7ab0: 20 20 7d 0a 20 20 2a 70 62 45 6f 66 20 3d 20 28    }.  *pbEof = (
7ac0: 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b 70  pSorter->aIter[p
7ad0: 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 31 5d  Sorter->aTree[1]
7ae0: 5d 2e 70 46 69 6c 65 3d 3d 30 29 3b 0a 20 20 72  ].pFile==0);.  r
7af0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
7b00: 2a 2a 20 41 64 76 61 6e 63 65 20 74 6f 20 74 68  ** Advance to th
7b10: 65 20 6e 65 78 74 20 65 6c 65 6d 65 6e 74 20 69  e next element i
7b20: 6e 20 74 68 65 20 73 6f 72 74 65 72 2e 0a 2a 2f  n the sorter..*/
7b30: 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65  .int sqlite3Vdbe
7b40: 53 6f 72 74 65 72 4e 65 78 74 28 73 71 6c 69 74  SorterNext(sqlit
7b50: 65 33 20 2a 64 62 2c 20 63 6f 6e 73 74 20 56 64  e3 *db, const Vd
7b60: 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  beCursor *pCsr, 
7b70: 69 6e 74 20 2a 70 62 45 6f 66 29 7b 0a 20 20 56  int *pbEof){.  V
7b80: 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
7b90: 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74  er = pCsr->pSort
7ba0: 65 72 3b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20  er;.  int rc;   
7bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7bc0: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
7bd0: 63 6f 64 65 20 2a 2f 0a 0a 20 20 69 66 28 20 70  code */..  if( p
7be0: 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 20 29 7b  Sorter->aTree ){
7bf0: 0a 20 20 20 20 69 6e 74 20 69 50 72 65 76 20 3d  .    int iPrev =
7c00: 20 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b   pSorter->aTree[
7c10: 31 5d 3b 2f 2a 20 49 6e 64 65 78 20 6f 66 20 69  1];/* Index of i
7c20: 74 65 72 61 74 6f 72 20 74 6f 20 61 64 76 61 6e  terator to advan
7c30: 63 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 3b  ce */.    int i;
7c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7c50: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78          /* Index
7c60: 20 6f 66 20 61 54 72 65 65 5b 5d 20 74 6f 20 72   of aTree[] to r
7c70: 65 63 61 6c 63 75 6c 61 74 65 20 2a 2f 0a 0a 20  ecalculate */.. 
7c80: 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74     rc = vdbeSort
7c90: 65 72 49 74 65 72 4e 65 78 74 28 64 62 2c 20 26  erIterNext(db, &
7ca0: 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b 69  pSorter->aIter[i
7cb0: 50 72 65 76 5d 29 3b 0a 20 20 20 20 66 6f 72 28  Prev]);.    for(
7cc0: 69 3d 28 70 53 6f 72 74 65 72 2d 3e 6e 54 72 65  i=(pSorter->nTre
7cd0: 65 2b 69 50 72 65 76 29 2f 32 3b 20 72 63 3d 3d  e+iPrev)/2; rc==
7ce0: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3e 30  SQLITE_OK && i>0
7cf0: 3b 20 69 3d 69 2f 32 29 7b 0a 20 20 20 20 20 20  ; i=i/2){.      
7d00: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 44  rc = vdbeSorterD
7d10: 6f 43 6f 6d 70 61 72 65 28 70 43 73 72 2c 20 69  oCompare(pCsr, i
7d20: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2a 70  );.    }..    *p
7d30: 62 45 6f 66 20 3d 20 28 70 53 6f 72 74 65 72 2d  bEof = (pSorter-
7d40: 3e 61 49 74 65 72 5b 70 53 6f 72 74 65 72 2d 3e  >aIter[pSorter->
7d50: 61 54 72 65 65 5b 31 5d 5d 2e 70 46 69 6c 65 3d  aTree[1]].pFile=
7d60: 3d 30 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  =0);.  }else{.  
7d70: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
7d80: 70 46 72 65 65 20 3d 20 70 53 6f 72 74 65 72 2d  pFree = pSorter-
7d90: 3e 70 52 65 63 6f 72 64 3b 0a 20 20 20 20 70 53  >pRecord;.    pS
7da0: 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20 3d  orter->pRecord =
7db0: 20 70 46 72 65 65 2d 3e 70 4e 65 78 74 3b 0a 20   pFree->pNext;. 
7dc0: 20 20 20 70 46 72 65 65 2d 3e 70 4e 65 78 74 20     pFree->pNext 
7dd0: 3d 20 30 3b 0a 20 20 20 20 76 64 62 65 53 6f 72  = 0;.    vdbeSor
7de0: 74 65 72 52 65 63 6f 72 64 46 72 65 65 28 64 62  terRecordFree(db
7df0: 2c 20 70 46 72 65 65 29 3b 0a 20 20 20 20 2a 70  , pFree);.    *p
7e00: 62 45 6f 66 20 3d 20 21 70 53 6f 72 74 65 72 2d  bEof = !pSorter-
7e10: 3e 70 52 65 63 6f 72 64 3b 0a 20 20 20 20 72 63  >pRecord;.    rc
7e20: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
7e30: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
7e40: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61  ../*.** Return a
7e50: 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 62 75   pointer to a bu
7e60: 66 66 65 72 20 6f 77 6e 65 64 20 62 79 20 74 68  ffer owned by th
7e70: 65 20 73 6f 72 74 65 72 20 74 68 61 74 20 63 6f  e sorter that co
7e80: 6e 74 61 69 6e 73 20 74 68 65 20 0a 2a 2a 20 63  ntains the .** c
7e90: 75 72 72 65 6e 74 20 6b 65 79 2e 0a 2a 2f 0a 73  urrent key..*/.s
7ea0: 74 61 74 69 63 20 76 6f 69 64 20 2a 76 64 62 65  tatic void *vdbe
7eb0: 53 6f 72 74 65 72 52 6f 77 6b 65 79 28 0a 20 20  SorterRowkey(.  
7ec0: 63 6f 6e 73 74 20 56 64 62 65 53 6f 72 74 65 72  const VdbeSorter
7ed0: 20 2a 70 53 6f 72 74 65 72 2c 20 20 20 20 20 20   *pSorter,      
7ee0: 2f 2a 20 53 6f 72 74 65 72 20 6f 62 6a 65 63 74  /* Sorter object
7ef0: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4b 65 79   */.  int *pnKey
7f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7f10: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 53 69        /* OUT: Si
7f20: 7a 65 20 6f 66 20 63 75 72 72 65 6e 74 20 6b 65  ze of current ke
7f30: 79 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 29 7b  y in bytes */.){
7f40: 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 3b 0a 20  .  void *pKey;. 
7f50: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 61 54   if( pSorter->aT
7f60: 72 65 65 20 29 7b 0a 20 20 20 20 56 64 62 65 53  ree ){.    VdbeS
7f70: 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74 65 72  orterIter *pIter
7f80: 3b 0a 20 20 20 20 70 49 74 65 72 20 3d 20 26 70  ;.    pIter = &p
7f90: 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b 20 70  Sorter->aIter[ p
7fa0: 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 31 5d  Sorter->aTree[1]
7fb0: 20 5d 3b 0a 20 20 20 20 2a 70 6e 4b 65 79 20 3d   ];.    *pnKey =
7fc0: 20 70 49 74 65 72 2d 3e 6e 4b 65 79 3b 0a 20 20   pIter->nKey;.  
7fd0: 20 20 70 4b 65 79 20 3d 20 70 49 74 65 72 2d 3e    pKey = pIter->
7fe0: 61 4b 65 79 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  aKey;.  }else{. 
7ff0: 20 20 20 2a 70 6e 4b 65 79 20 3d 20 70 53 6f 72     *pnKey = pSor
8000: 74 65 72 2d 3e 70 52 65 63 6f 72 64 2d 3e 6e 56  ter->pRecord->nV
8010: 61 6c 3b 0a 20 20 20 20 70 4b 65 79 20 3d 20 70  al;.    pKey = p
8020: 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 2d  Sorter->pRecord-
8030: 3e 70 56 61 6c 3b 0a 20 20 7d 0a 20 20 72 65 74  >pVal;.  }.  ret
8040: 75 72 6e 20 70 4b 65 79 3b 0a 7d 0a 0a 2f 2a 0a  urn pKey;.}../*.
8050: 2a 2a 20 43 6f 70 79 20 74 68 65 20 63 75 72 72  ** Copy the curr
8060: 65 6e 74 20 73 6f 72 74 65 72 20 6b 65 79 20 69  ent sorter key i
8070: 6e 74 6f 20 74 68 65 20 6d 65 6d 6f 72 79 20 63  nto the memory c
8080: 65 6c 6c 20 70 4f 75 74 2e 0a 2a 2f 0a 69 6e 74  ell pOut..*/.int
8090: 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74   sqlite3VdbeSort
80a0: 65 72 52 6f 77 6b 65 79 28 63 6f 6e 73 74 20 56  erRowkey(const V
80b0: 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c  dbeCursor *pCsr,
80c0: 20 4d 65 6d 20 2a 70 4f 75 74 29 7b 0a 20 20 56   Mem *pOut){.  V
80d0: 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  dbeSorter *pSort
80e0: 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74  er = pCsr->pSort
80f0: 65 72 3b 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79  er;.  void *pKey
8100: 3b 20 69 6e 74 20 6e 4b 65 79 3b 20 20 20 20 20  ; int nKey;     
8110: 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20        /* Sorter 
8120: 6b 65 79 20 74 6f 20 63 6f 70 79 20 69 6e 74 6f  key to copy into
8130: 20 70 4f 75 74 20 2a 2f 0a 0a 20 20 70 4b 65 79   pOut */..  pKey
8140: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 52 6f 77   = vdbeSorterRow
8150: 6b 65 79 28 70 53 6f 72 74 65 72 2c 20 26 6e 4b  key(pSorter, &nK
8160: 65 79 29 3b 0a 20 20 69 66 28 20 73 71 6c 69 74  ey);.  if( sqlit
8170: 65 33 56 64 62 65 4d 65 6d 47 72 6f 77 28 70 4f  e3VdbeMemGrow(pO
8180: 75 74 2c 20 6e 4b 65 79 2c 20 30 29 20 29 7b 0a  ut, nKey, 0) ){.
8190: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
81a0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 70  E_NOMEM;.  }.  p
81b0: 4f 75 74 2d 3e 6e 20 3d 20 6e 4b 65 79 3b 0a 20  Out->n = nKey;. 
81c0: 20 4d 65 6d 53 65 74 54 79 70 65 46 6c 61 67 28   MemSetTypeFlag(
81d0: 70 4f 75 74 2c 20 4d 45 4d 5f 42 6c 6f 62 29 3b  pOut, MEM_Blob);
81e0: 0a 20 20 6d 65 6d 63 70 79 28 70 4f 75 74 2d 3e  .  memcpy(pOut->
81f0: 7a 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a  z, pKey, nKey);.
8200: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
8210: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f  _OK;.}../*.** Co
8220: 6d 70 61 72 65 20 74 68 65 20 6b 65 79 20 69 6e  mpare the key in
8230: 20 6d 65 6d 6f 72 79 20 63 65 6c 6c 20 70 56 61   memory cell pVa
8240: 6c 20 77 69 74 68 20 74 68 65 20 6b 65 79 20 74  l with the key t
8250: 68 61 74 20 74 68 65 20 73 6f 72 74 65 72 20 63  hat the sorter c
8260: 75 72 73 6f 72 0a 2a 2a 20 70 61 73 73 65 64 20  ursor.** passed 
8270: 61 73 20 74 68 65 20 66 69 72 73 74 20 61 72 67  as the first arg
8280: 75 6d 65 6e 74 20 63 75 72 72 65 6e 74 6c 79 20  ument currently 
8290: 70 6f 69 6e 74 73 20 74 6f 2e 20 46 6f 72 20 74  points to. For t
82a0: 68 65 20 70 75 72 70 6f 73 65 73 20 6f 66 0a 2a  he purposes of.*
82b0: 2a 20 74 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e  * the comparison
82c0: 2c 20 69 67 6e 6f 72 65 20 74 68 65 20 72 6f 77  , ignore the row
82d0: 69 64 20 66 69 65 6c 64 20 61 74 20 74 68 65 20  id field at the 
82e0: 65 6e 64 20 6f 66 20 65 61 63 68 20 72 65 63 6f  end of each reco
82f0: 72 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20  rd..**.** If an 
8300: 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 72 65  error occurs, re
8310: 74 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 20 65  turn an SQLite e
8320: 72 72 6f 72 20 63 6f 64 65 20 28 69 2e 65 2e 20  rror code (i.e. 
8330: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 2e 0a 2a  SQLITE_NOMEM)..*
8340: 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 73 65 74  * Otherwise, set
8350: 20 2a 70 52 65 73 20 74 6f 20 61 20 6e 65 67 61   *pRes to a nega
8360: 74 69 76 65 2c 20 7a 65 72 6f 20 6f 72 20 70 6f  tive, zero or po
8370: 73 69 74 69 76 65 20 76 61 6c 75 65 20 69 66 20  sitive value if 
8380: 74 68 65 0a 2a 2a 20 6b 65 79 20 69 6e 20 70 56  the.** key in pV
8390: 61 6c 20 69 73 20 73 6d 61 6c 6c 65 72 20 74 68  al is smaller th
83a0: 61 6e 2c 20 65 71 75 61 6c 20 74 6f 20 6f 72 20  an, equal to or 
83b0: 6c 61 72 67 65 72 20 74 68 61 6e 20 74 68 65 20  larger than the 
83c0: 63 75 72 72 65 6e 74 20 73 6f 72 74 65 72 0a 2a  current sorter.*
83d0: 2a 20 6b 65 79 2e 0a 2a 2f 0a 69 6e 74 20 73 71  * key..*/.int sq
83e0: 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 43  lite3VdbeSorterC
83f0: 6f 6d 70 61 72 65 28 0a 20 20 63 6f 6e 73 74 20  ompare(.  const 
8400: 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72  VdbeCursor *pCsr
8410: 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72  ,         /* Sor
8420: 74 65 72 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20  ter cursor */.  
8430: 4d 65 6d 20 2a 70 56 61 6c 2c 20 20 20 20 20 20  Mem *pVal,      
8440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8450: 2f 2a 20 56 61 6c 75 65 20 74 6f 20 63 6f 6d 70  /* Value to comp
8460: 61 72 65 20 74 6f 20 63 75 72 72 65 6e 74 20 73  are to current s
8470: 6f 72 74 65 72 20 6b 65 79 20 2a 2f 0a 20 20 69  orter key */.  i
8480: 6e 74 20 2a 70 52 65 73 20 20 20 20 20 20 20 20  nt *pRes        
8490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
84a0: 2a 20 4f 55 54 3a 20 52 65 73 75 6c 74 20 6f 66  * OUT: Result of
84b0: 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f 0a 29   comparison */.)
84c0: 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a  {.  VdbeSorter *
84d0: 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e  pSorter = pCsr->
84e0: 70 53 6f 72 74 65 72 3b 0a 20 20 76 6f 69 64 20  pSorter;.  void 
84f0: 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b 65 79 3b  *pKey; int nKey;
8500: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f             /* So
8510: 72 74 65 72 20 6b 65 79 20 74 6f 20 63 6f 6d 70  rter key to comp
8520: 61 72 65 20 70 56 61 6c 20 77 69 74 68 20 2a 2f  are pVal with */
8530: 0a 0a 20 20 70 4b 65 79 20 3d 20 76 64 62 65 53  ..  pKey = vdbeS
8540: 6f 72 74 65 72 52 6f 77 6b 65 79 28 70 53 6f 72  orterRowkey(pSor
8550: 74 65 72 2c 20 26 6e 4b 65 79 29 3b 0a 20 20 76  ter, &nKey);.  v
8560: 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65  dbeSorterCompare
8570: 28 70 43 73 72 2c 20 31 2c 20 70 56 61 6c 2d 3e  (pCsr, 1, pVal->
8580: 7a 2c 20 70 56 61 6c 2d 3e 6e 2c 20 70 4b 65 79  z, pVal->n, pKey
8590: 2c 20 6e 4b 65 79 2c 20 70 52 65 73 29 3b 0a 20  , nKey, pRes);. 
85a0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
85b0: 4b 3b 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20  K;.}..#endif /* 
85c0: 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f  #ifndef SQLITE_O
85d0: 4d 49 54 5f 4d 45 52 47 45 5f 53 4f 52 54 20 2a  MIT_MERGE_SORT *
85e0: 2f 0a                                            /.