/ Hex Artifact Content
Login

Artifact d46f384af1997a4441ef9c65759181954efc89cf:


0000: 2f 2a 0a 2a 2a 20 32 30 31 31 20 4a 75 6c 79 20  /*.** 2011 July 
0010: 39 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  9.**.** The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65  place of.** a le
0060: 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65  gal notice, here
0070: 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a   is a blessing:.
0080: 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75  **.**    May you
0090: 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74   do good and not
00a0: 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79   evil..**    May
00b0: 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76   you find forgiv
00c0: 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65  eness for yourse
00d0: 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f  lf and forgive o
00e0: 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79  thers..**    May
00f0: 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c   you share freel
0100: 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20  y, never taking 
0110: 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69  more than you gi
0120: 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ve..**.*********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65 20 63 6f  .** This file co
0180: 6e 74 61 69 6e 73 20 63 6f 64 65 20 66 6f 72 20  ntains code for 
0190: 74 68 65 20 56 64 62 65 53 6f 72 74 65 72 20 6f  the VdbeSorter o
01a0: 62 6a 65 63 74 2c 20 75 73 65 64 20 69 6e 20 63  bject, used in c
01b0: 6f 6e 63 65 72 74 20 77 69 74 68 0a 2a 2a 20 61  oncert with.** a
01c0: 20 56 64 62 65 43 75 72 73 6f 72 20 74 6f 20 73   VdbeCursor to s
01d0: 6f 72 74 20 6c 61 72 67 65 20 6e 75 6d 62 65 72  ort large number
01e0: 73 20 6f 66 20 6b 65 79 73 20 28 61 73 20 6d 61  s of keys (as ma
01f0: 79 20 62 65 20 72 65 71 75 69 72 65 64 2c 20 66  y be required, f
0200: 6f 72 0a 2a 2a 20 65 78 61 6d 70 6c 65 2c 20 62  or.** example, b
0210: 79 20 43 52 45 41 54 45 20 49 4e 44 45 58 20 73  y CREATE INDEX s
0220: 74 61 74 65 6d 65 6e 74 73 20 6f 6e 20 74 61 62  tatements on tab
0230: 6c 65 73 20 74 6f 6f 20 6c 61 72 67 65 20 74 6f  les too large to
0240: 20 66 69 74 20 69 6e 20 6d 61 69 6e 0a 2a 2a 20   fit in main.** 
0250: 6d 65 6d 6f 72 79 29 2e 0a 2a 2f 0a 0a 23 69 6e  memory)..*/..#in
0260: 63 6c 75 64 65 20 22 73 71 6c 69 74 65 49 6e 74  clude "sqliteInt
0270: 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 76 64  .h".#include "vd
0280: 62 65 49 6e 74 2e 68 22 0a 0a 0a 74 79 70 65 64  beInt.h"...typed
0290: 65 66 20 73 74 72 75 63 74 20 56 64 62 65 53 6f  ef struct VdbeSo
02a0: 72 74 65 72 49 74 65 72 20 56 64 62 65 53 6f 72  rterIter VdbeSor
02b0: 74 65 72 49 74 65 72 3b 0a 74 79 70 65 64 65 66  terIter;.typedef
02c0: 20 73 74 72 75 63 74 20 53 6f 72 74 65 72 52 65   struct SorterRe
02d0: 63 6f 72 64 20 53 6f 72 74 65 72 52 65 63 6f 72  cord SorterRecor
02e0: 64 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  d;.typedef struc
02f0: 74 20 46 69 6c 65 57 72 69 74 65 72 20 46 69 6c  t FileWriter Fil
0300: 65 57 72 69 74 65 72 3b 0a 0a 2f 2a 0a 2a 2a 20  eWriter;../*.** 
0310: 4e 4f 54 45 53 20 4f 4e 20 44 41 54 41 20 53 54  NOTES ON DATA ST
0320: 52 55 43 54 55 52 45 20 55 53 45 44 20 46 4f 52  RUCTURE USED FOR
0330: 20 4e 2d 57 41 59 20 4d 45 52 47 45 53 3a 0a 2a   N-WAY MERGES:.*
0340: 2a 0a 2a 2a 20 41 73 20 6b 65 79 73 20 61 72 65  *.** As keys are
0350: 20 61 64 64 65 64 20 74 6f 20 74 68 65 20 73 6f   added to the so
0360: 72 74 65 72 2c 20 74 68 65 79 20 61 72 65 20 77  rter, they are w
0370: 72 69 74 74 65 6e 20 74 6f 20 64 69 73 6b 20 69  ritten to disk i
0380: 6e 20 61 20 73 65 72 69 65 73 0a 2a 2a 20 6f 66  n a series.** of
0390: 20 73 6f 72 74 65 64 20 70 61 63 6b 65 64 2d 6d   sorted packed-m
03a0: 65 6d 6f 72 79 2d 61 72 72 61 79 73 20 28 50 4d  emory-arrays (PM
03b0: 41 73 29 2e 20 54 68 65 20 73 69 7a 65 20 6f 66  As). The size of
03c0: 20 65 61 63 68 20 50 4d 41 20 69 73 20 72 6f 75   each PMA is rou
03d0: 67 68 6c 79 0a 2a 2a 20 74 68 65 20 73 61 6d 65  ghly.** the same
03e0: 20 61 73 20 74 68 65 20 63 61 63 68 65 2d 73 69   as the cache-si
03f0: 7a 65 20 61 6c 6c 6f 77 65 64 20 66 6f 72 20 74  ze allowed for t
0400: 65 6d 70 6f 72 61 72 79 20 64 61 74 61 62 61 73  emporary databas
0410: 65 73 2e 20 49 6e 20 6f 72 64 65 72 0a 2a 2a 20  es. In order.** 
0420: 74 6f 20 61 6c 6c 6f 77 20 74 68 65 20 63 61 6c  to allow the cal
0430: 6c 65 72 20 74 6f 20 65 78 74 72 61 63 74 20 6b  ler to extract k
0440: 65 79 73 20 66 72 6f 6d 20 74 68 65 20 73 6f 72  eys from the sor
0450: 74 65 72 20 69 6e 20 73 6f 72 74 65 64 20 6f 72  ter in sorted or
0460: 64 65 72 2c 0a 2a 2a 20 61 6c 6c 20 50 4d 41 73  der,.** all PMAs
0470: 20 63 75 72 72 65 6e 74 6c 79 20 73 74 6f 72 65   currently store
0480: 64 20 6f 6e 20 64 69 73 6b 20 6d 75 73 74 20 62  d on disk must b
0490: 65 20 6d 65 72 67 65 64 20 74 6f 67 65 74 68 65  e merged togethe
04a0: 72 2e 20 54 68 69 73 20 63 6f 6d 6d 65 6e 74 0a  r. This comment.
04b0: 2a 2a 20 64 65 73 63 72 69 62 65 73 20 74 68 65  ** describes the
04c0: 20 64 61 74 61 20 73 74 72 75 63 74 75 72 65 20   data structure 
04d0: 75 73 65 64 20 74 6f 20 64 6f 20 73 6f 2e 20 54  used to do so. T
04e0: 68 65 20 73 74 72 75 63 74 75 72 65 20 73 75 70  he structure sup
04f0: 70 6f 72 74 73 20 0a 2a 2a 20 6d 65 72 67 69 6e  ports .** mergin
0500: 67 20 61 6e 79 20 6e 75 6d 62 65 72 20 6f 66 20  g any number of 
0510: 61 72 72 61 79 73 20 69 6e 20 61 20 73 69 6e 67  arrays in a sing
0520: 6c 65 20 70 61 73 73 20 77 69 74 68 20 6e 6f 20  le pass with no 
0530: 72 65 64 75 6e 64 61 6e 74 20 63 6f 6d 70 61 72  redundant compar
0540: 69 73 6f 6e 20 0a 2a 2a 20 6f 70 65 72 61 74 69  ison .** operati
0550: 6f 6e 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61  ons..**.** The a
0560: 49 74 65 72 5b 5d 20 61 72 72 61 79 20 63 6f 6e  Iter[] array con
0570: 74 61 69 6e 73 20 61 6e 20 69 74 65 72 61 74 6f  tains an iterato
0580: 72 20 66 6f 72 20 65 61 63 68 20 6f 66 20 74 68  r for each of th
0590: 65 20 50 4d 41 73 20 62 65 69 6e 67 20 6d 65 72  e PMAs being mer
05a0: 67 65 64 2e 0a 2a 2a 20 41 6e 20 61 49 74 65 72  ged..** An aIter
05b0: 5b 5d 20 69 74 65 72 61 74 6f 72 20 65 69 74 68  [] iterator eith
05c0: 65 72 20 70 6f 69 6e 74 73 20 74 6f 20 61 20 76  er points to a v
05d0: 61 6c 69 64 20 6b 65 79 20 6f 72 20 65 6c 73 65  alid key or else
05e0: 20 69 73 20 61 74 20 45 4f 46 2e 20 46 6f 72 20   is at EOF. For 
05f0: 0a 2a 2a 20 74 68 65 20 70 75 72 70 6f 73 65 73  .** the purposes
0600: 20 6f 66 20 74 68 65 20 70 61 72 61 67 72 61 70   of the paragrap
0610: 68 73 20 62 65 6c 6f 77 2c 20 77 65 20 61 73 73  hs below, we ass
0620: 75 6d 65 20 74 68 61 74 20 74 68 65 20 61 72 72  ume that the arr
0630: 61 79 20 69 73 20 61 63 74 75 61 6c 6c 79 20 0a  ay is actually .
0640: 2a 2a 20 4e 20 65 6c 65 6d 65 6e 74 73 20 69 6e  ** N elements in
0650: 20 73 69 7a 65 2c 20 77 68 65 72 65 20 4e 20 69   size, where N i
0660: 73 20 74 68 65 20 73 6d 61 6c 6c 65 73 74 20 70  s the smallest p
0670: 6f 77 65 72 20 6f 66 20 32 20 67 72 65 61 74 65  ower of 2 greate
0680: 72 20 74 6f 20 6f 72 20 65 71 75 61 6c 20 0a 2a  r to or equal .*
0690: 2a 20 74 6f 20 74 68 65 20 6e 75 6d 62 65 72 20  * to the number 
06a0: 6f 66 20 69 74 65 72 61 74 6f 72 73 20 62 65 69  of iterators bei
06b0: 6e 67 20 6d 65 72 67 65 64 2e 20 54 68 65 20 65  ng merged. The e
06c0: 78 74 72 61 20 61 49 74 65 72 5b 5d 20 65 6c 65  xtra aIter[] ele
06d0: 6d 65 6e 74 73 20 61 72 65 20 0a 2a 2a 20 74 72  ments are .** tr
06e0: 65 61 74 65 64 20 61 73 20 69 66 20 74 68 65 79  eated as if they
06f0: 20 61 72 65 20 65 6d 70 74 79 20 28 61 6c 77 61   are empty (alwa
0700: 79 73 20 61 74 20 45 4f 46 29 2e 0a 2a 2a 0a 2a  ys at EOF)..**.*
0710: 2a 20 54 68 65 20 61 54 72 65 65 5b 5d 20 61 72  * The aTree[] ar
0720: 72 61 79 20 69 73 20 61 6c 73 6f 20 4e 20 65 6c  ray is also N el
0730: 65 6d 65 6e 74 73 20 69 6e 20 73 69 7a 65 2e 20  ements in size. 
0740: 54 68 65 20 76 61 6c 75 65 20 6f 66 20 4e 20 69  The value of N i
0750: 73 20 73 74 6f 72 65 64 20 69 6e 0a 2a 2a 20 74  s stored in.** t
0760: 68 65 20 56 64 62 65 53 6f 72 74 65 72 2e 6e 54  he VdbeSorter.nT
0770: 72 65 65 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2a  ree variable..**
0780: 0a 2a 2a 20 54 68 65 20 66 69 6e 61 6c 20 28 4e  .** The final (N
0790: 2f 32 29 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20  /2) elements of 
07a0: 61 54 72 65 65 5b 5d 20 63 6f 6e 74 61 69 6e 20  aTree[] contain 
07b0: 74 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20 63  the results of c
07c0: 6f 6d 70 61 72 69 6e 67 0a 2a 2a 20 70 61 69 72  omparing.** pair
07d0: 73 20 6f 66 20 69 74 65 72 61 74 6f 72 20 6b 65  s of iterator ke
07e0: 79 73 20 74 6f 67 65 74 68 65 72 2e 20 45 6c 65  ys together. Ele
07f0: 6d 65 6e 74 20 69 20 63 6f 6e 74 61 69 6e 73 20  ment i contains 
0800: 74 68 65 20 72 65 73 75 6c 74 20 6f 66 20 0a 2a  the result of .*
0810: 2a 20 63 6f 6d 70 61 72 69 6e 67 20 61 49 74 65  * comparing aIte
0820: 72 5b 32 2a 69 2d 4e 5d 20 61 6e 64 20 61 49 74  r[2*i-N] and aIt
0830: 65 72 5b 32 2a 69 2d 4e 2b 31 5d 2e 20 57 68 69  er[2*i-N+1]. Whi
0840: 63 68 65 76 65 72 20 6b 65 79 20 69 73 20 73 6d  chever key is sm
0850: 61 6c 6c 65 72 2c 20 74 68 65 0a 2a 2a 20 61 54  aller, the.** aT
0860: 72 65 65 20 65 6c 65 6d 65 6e 74 20 69 73 20 73  ree element is s
0870: 65 74 20 74 6f 20 74 68 65 20 69 6e 64 65 78 20  et to the index 
0880: 6f 66 20 69 74 2e 20 0a 2a 2a 0a 2a 2a 20 46 6f  of it. .**.** Fo
0890: 72 20 74 68 65 20 70 75 72 70 6f 73 65 73 20 6f  r the purposes o
08a0: 66 20 74 68 69 73 20 63 6f 6d 70 61 72 69 73 6f  f this compariso
08b0: 6e 2c 20 45 4f 46 20 69 73 20 63 6f 6e 73 69 64  n, EOF is consid
08c0: 65 72 65 64 20 67 72 65 61 74 65 72 20 74 68 61  ered greater tha
08d0: 6e 20 61 6e 79 0a 2a 2a 20 6f 74 68 65 72 20 6b  n any.** other k
08e0: 65 79 20 76 61 6c 75 65 2e 20 49 66 20 74 68 65  ey value. If the
08f0: 20 6b 65 79 73 20 61 72 65 20 65 71 75 61 6c 20   keys are equal 
0900: 28 6f 6e 6c 79 20 70 6f 73 73 69 62 6c 65 20 77  (only possible w
0910: 69 74 68 20 74 77 6f 20 45 4f 46 0a 2a 2a 20 76  ith two EOF.** v
0920: 61 6c 75 65 73 29 2c 20 69 74 20 64 6f 65 73 6e  alues), it doesn
0930: 27 74 20 6d 61 74 74 65 72 20 77 68 69 63 68 20  't matter which 
0940: 69 6e 64 65 78 20 69 73 20 73 74 6f 72 65 64 2e  index is stored.
0950: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 28 4e 2f 34 29  .**.** The (N/4)
0960: 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20 61 54 72   elements of aTr
0970: 65 65 5b 5d 20 74 68 61 74 20 70 72 65 63 65 64  ee[] that preced
0980: 65 20 74 68 65 20 66 69 6e 61 6c 20 28 4e 2f 32  e the final (N/2
0990: 29 20 64 65 73 63 72 69 62 65 64 20 0a 2a 2a 20  ) described .** 
09a0: 61 62 6f 76 65 20 63 6f 6e 74 61 69 6e 73 20 74  above contains t
09b0: 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20  he index of the 
09c0: 73 6d 61 6c 6c 65 73 74 20 6f 66 20 65 61 63 68  smallest of each
09d0: 20 62 6c 6f 63 6b 20 6f 66 20 34 20 69 74 65 72   block of 4 iter
09e0: 61 74 6f 72 73 2e 0a 2a 2a 20 41 6e 64 20 73 6f  ators..** And so
09f0: 20 6f 6e 2e 20 53 6f 20 74 68 61 74 20 61 54 72   on. So that aTr
0a00: 65 65 5b 31 5d 20 63 6f 6e 74 61 69 6e 73 20 74  ee[1] contains t
0a10: 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20  he index of the 
0a20: 69 74 65 72 61 74 6f 72 20 74 68 61 74 20 0a 2a  iterator that .*
0a30: 2a 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e  * currently poin
0a40: 74 73 20 74 6f 20 74 68 65 20 73 6d 61 6c 6c 65  ts to the smalle
0a50: 73 74 20 6b 65 79 20 76 61 6c 75 65 2e 20 61 54  st key value. aT
0a60: 72 65 65 5b 30 5d 20 69 73 20 75 6e 75 73 65 64  ree[0] is unused
0a70: 2e 0a 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65 3a  ..**.** Example:
0a80: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 49 74 65 72  .**.**     aIter
0a90: 5b 30 5d 20 2d 3e 20 42 61 6e 61 6e 61 0a 2a 2a  [0] -> Banana.**
0aa0: 20 20 20 20 20 61 49 74 65 72 5b 31 5d 20 2d 3e       aIter[1] ->
0ab0: 20 46 65 69 6a 6f 61 0a 2a 2a 20 20 20 20 20 61   Feijoa.**     a
0ac0: 49 74 65 72 5b 32 5d 20 2d 3e 20 45 6c 64 65 72  Iter[2] -> Elder
0ad0: 62 65 72 72 79 0a 2a 2a 20 20 20 20 20 61 49 74  berry.**     aIt
0ae0: 65 72 5b 33 5d 20 2d 3e 20 43 75 72 72 61 6e 74  er[3] -> Currant
0af0: 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 34 5d  .**     aIter[4]
0b00: 20 2d 3e 20 47 72 61 70 65 66 72 75 69 74 0a 2a   -> Grapefruit.*
0b10: 2a 20 20 20 20 20 61 49 74 65 72 5b 35 5d 20 2d  *     aIter[5] -
0b20: 3e 20 41 70 70 6c 65 0a 2a 2a 20 20 20 20 20 61  > Apple.**     a
0b30: 49 74 65 72 5b 36 5d 20 2d 3e 20 44 75 72 69 61  Iter[6] -> Duria
0b40: 6e 0a 2a 2a 20 20 20 20 20 61 49 74 65 72 5b 37  n.**     aIter[7
0b50: 5d 20 2d 3e 20 45 4f 46 0a 2a 2a 0a 2a 2a 20 20  ] -> EOF.**.**  
0b60: 20 20 20 61 54 72 65 65 5b 5d 20 3d 20 7b 20 58     aTree[] = { X
0b70: 2c 20 35 20 20 20 30 2c 20 35 20 20 20 20 30 2c  , 5   0, 5    0,
0b80: 20 33 2c 20 35 2c 20 36 20 7d 0a 2a 2a 0a 2a 2a   3, 5, 6 }.**.**
0b90: 20 54 68 65 20 63 75 72 72 65 6e 74 20 65 6c 65   The current ele
0ba0: 6d 65 6e 74 20 69 73 20 22 41 70 70 6c 65 22 20  ment is "Apple" 
0bb0: 28 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68  (the value of th
0bc0: 65 20 6b 65 79 20 69 6e 64 69 63 61 74 65 64 20  e key indicated 
0bd0: 62 79 20 0a 2a 2a 20 69 74 65 72 61 74 6f 72 20  by .** iterator 
0be0: 35 29 2e 20 57 68 65 6e 20 74 68 65 20 4e 65 78  5). When the Nex
0bf0: 74 28 29 20 6f 70 65 72 61 74 69 6f 6e 20 69 73  t() operation is
0c00: 20 69 6e 76 6f 6b 65 64 2c 20 69 74 65 72 61 74   invoked, iterat
0c10: 6f 72 20 35 20 77 69 6c 6c 0a 2a 2a 20 62 65 20  or 5 will.** be 
0c20: 61 64 76 61 6e 63 65 64 20 74 6f 20 74 68 65 20  advanced to the 
0c30: 6e 65 78 74 20 6b 65 79 20 69 6e 20 69 74 73 20  next key in its 
0c40: 73 65 67 6d 65 6e 74 2e 20 53 61 79 20 74 68 65  segment. Say the
0c50: 20 6e 65 78 74 20 6b 65 79 20 69 73 0a 2a 2a 20   next key is.** 
0c60: 22 45 67 67 70 6c 61 6e 74 22 3a 0a 2a 2a 0a 2a  "Eggplant":.**.*
0c70: 2a 20 20 20 20 20 61 49 74 65 72 5b 35 5d 20 2d  *     aIter[5] -
0c80: 3e 20 45 67 67 70 6c 61 6e 74 0a 2a 2a 0a 2a 2a  > Eggplant.**.**
0c90: 20 54 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   The contents of
0ca0: 20 61 54 72 65 65 5b 5d 20 61 72 65 20 75 70 64   aTree[] are upd
0cb0: 61 74 65 64 20 66 69 72 73 74 20 62 79 20 63 6f  ated first by co
0cc0: 6d 70 61 72 69 6e 67 20 74 68 65 20 6e 65 77 20  mparing the new 
0cd0: 69 74 65 72 61 74 6f 72 0a 2a 2a 20 35 20 6b 65  iterator.** 5 ke
0ce0: 79 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e 74  y to the current
0cf0: 20 6b 65 79 20 6f 66 20 69 74 65 72 61 74 6f 72   key of iterator
0d00: 20 34 20 28 73 74 69 6c 6c 20 22 47 72 61 70 65   4 (still "Grape
0d10: 66 72 75 69 74 22 29 2e 20 54 68 65 20 69 74 65  fruit"). The ite
0d20: 72 61 74 6f 72 0a 2a 2a 20 35 20 76 61 6c 75 65  rator.** 5 value
0d30: 20 69 73 20 73 74 69 6c 6c 20 73 6d 61 6c 6c 65   is still smalle
0d40: 72 2c 20 73 6f 20 61 54 72 65 65 5b 36 5d 20 69  r, so aTree[6] i
0d50: 73 20 73 65 74 20 74 6f 20 35 2e 20 41 6e 64 20  s set to 5. And 
0d60: 73 6f 20 6f 6e 20 75 70 20 74 68 65 20 74 72 65  so on up the tre
0d70: 65 2e 0a 2a 2a 20 54 68 65 20 76 61 6c 75 65 20  e..** The value 
0d80: 6f 66 20 69 74 65 72 61 74 6f 72 20 36 20 2d 20  of iterator 6 - 
0d90: 22 44 75 72 69 61 6e 22 20 2d 20 69 73 20 6e 6f  "Durian" - is no
0da0: 77 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 74  w smaller than t
0db0: 68 61 74 20 6f 66 20 69 74 65 72 61 74 6f 72 0a  hat of iterator.
0dc0: 2a 2a 20 35 2c 20 73 6f 20 61 54 72 65 65 5b 33  ** 5, so aTree[3
0dd0: 5d 20 69 73 20 73 65 74 20 74 6f 20 36 2e 20 4b  ] is set to 6. K
0de0: 65 79 20 30 20 69 73 20 73 6d 61 6c 6c 65 72 20  ey 0 is smaller 
0df0: 74 68 61 6e 20 6b 65 79 20 36 20 28 42 61 6e 61  than key 6 (Bana
0e00: 6e 61 3c 44 75 72 69 61 6e 29 2c 0a 2a 2a 20 73  na<Durian),.** s
0e10: 6f 20 74 68 65 20 76 61 6c 75 65 20 77 72 69 74  o the value writ
0e20: 74 65 6e 20 69 6e 74 6f 20 65 6c 65 6d 65 6e 74  ten into element
0e30: 20 31 20 6f 66 20 74 68 65 20 61 72 72 61 79 20   1 of the array 
0e40: 69 73 20 30 2e 20 41 73 20 66 6f 6c 6c 6f 77 73  is 0. As follows
0e50: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 61 54 72 65  :.**.**     aTre
0e60: 65 5b 5d 20 3d 20 7b 20 58 2c 20 30 20 20 20 30  e[] = { X, 0   0
0e70: 2c 20 36 20 20 20 20 30 2c 20 33 2c 20 35 2c 20  , 6    0, 3, 5, 
0e80: 36 20 7d 0a 2a 2a 0a 2a 2a 20 49 6e 20 6f 74 68  6 }.**.** In oth
0e90: 65 72 20 77 6f 72 64 73 2c 20 65 61 63 68 20 74  er words, each t
0ea0: 69 6d 65 20 77 65 20 61 64 76 61 6e 63 65 20 74  ime we advance t
0eb0: 6f 20 74 68 65 20 6e 65 78 74 20 73 6f 72 74 65  o the next sorte
0ec0: 72 20 65 6c 65 6d 65 6e 74 2c 20 6c 6f 67 32 28  r element, log2(
0ed0: 4e 29 0a 2a 2a 20 6b 65 79 20 63 6f 6d 70 61 72  N).** key compar
0ee0: 69 73 6f 6e 20 6f 70 65 72 61 74 69 6f 6e 73 20  ison operations 
0ef0: 61 72 65 20 72 65 71 75 69 72 65 64 2c 20 77 68  are required, wh
0f00: 65 72 65 20 4e 20 69 73 20 74 68 65 20 6e 75 6d  ere N is the num
0f10: 62 65 72 20 6f 66 20 73 65 67 6d 65 6e 74 73 0a  ber of segments.
0f20: 2a 2a 20 62 65 69 6e 67 20 6d 65 72 67 65 64 20  ** being merged 
0f30: 28 72 6f 75 6e 64 65 64 20 75 70 20 74 6f 20 74  (rounded up to t
0f40: 68 65 20 6e 65 78 74 20 70 6f 77 65 72 20 6f 66  he next power of
0f50: 20 32 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 56   2)..*/.struct V
0f60: 64 62 65 53 6f 72 74 65 72 20 7b 0a 20 20 69 36  dbeSorter {.  i6
0f70: 34 20 69 57 72 69 74 65 4f 66 66 3b 20 20 20 20  4 iWriteOff;    
0f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0f90: 20 43 75 72 72 65 6e 74 20 77 72 69 74 65 20 6f   Current write o
0fa0: 66 66 73 65 74 20 77 69 74 68 69 6e 20 66 69 6c  ffset within fil
0fb0: 65 20 70 54 65 6d 70 31 20 2a 2f 0a 20 20 69 36  e pTemp1 */.  i6
0fc0: 34 20 69 52 65 61 64 4f 66 66 3b 20 20 20 20 20  4 iReadOff;     
0fd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0fe0: 20 43 75 72 72 65 6e 74 20 72 65 61 64 20 6f 66   Current read of
0ff0: 66 73 65 74 20 77 69 74 68 69 6e 20 66 69 6c 65  fset within file
1000: 20 70 54 65 6d 70 31 20 2a 2f 0a 20 20 69 6e 74   pTemp1 */.  int
1010: 20 6e 49 6e 4d 65 6d 6f 72 79 3b 20 20 20 20 20   nInMemory;     
1020: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1030: 43 75 72 72 65 6e 74 20 73 69 7a 65 20 6f 66 20  Current size of 
1040: 70 52 65 63 6f 72 64 20 6c 69 73 74 20 61 73 20  pRecord list as 
1050: 50 4d 41 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 72  PMA */.  int nTr
1060: 65 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ee;             
1070: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64           /* Used
1080: 20 73 69 7a 65 20 6f 66 20 61 54 72 65 65 2f 61   size of aTree/a
1090: 49 74 65 72 20 28 70 6f 77 65 72 20 6f 66 20 32  Iter (power of 2
10a0: 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 4d 41 3b  ) */.  int nPMA;
10b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10c0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
10d0: 20 6f 66 20 50 4d 41 73 20 73 74 6f 72 65 64 20   of PMAs stored 
10e0: 69 6e 20 70 54 65 6d 70 31 20 2a 2f 0a 20 20 69  in pTemp1 */.  i
10f0: 6e 74 20 6d 6e 50 6d 61 53 69 7a 65 3b 20 20 20  nt mnPmaSize;   
1100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1110: 2a 20 4d 69 6e 69 6d 75 6d 20 50 4d 41 20 73 69  * Minimum PMA si
1120: 7a 65 2c 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  ze, in bytes */.
1130: 20 20 69 6e 74 20 6d 78 50 6d 61 53 69 7a 65 3b    int mxPmaSize;
1140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1150: 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 50 4d 41    /* Maximum PMA
1160: 20 73 69 7a 65 2c 20 69 6e 20 62 79 74 65 73 2e   size, in bytes.
1170: 20 20 30 3d 3d 6e 6f 20 6c 69 6d 69 74 20 2a 2f    0==no limit */
1180: 0a 20 20 56 64 62 65 53 6f 72 74 65 72 49 74 65  .  VdbeSorterIte
1190: 72 20 2a 61 49 74 65 72 3b 20 20 20 20 20 20 20  r *aIter;       
11a0: 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 69     /* Array of i
11b0: 74 65 72 61 74 6f 72 73 20 74 6f 20 6d 65 72 67  terators to merg
11c0: 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 54 72 65  e */.  int *aTre
11d0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
11e0: 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e         /* Curren
11f0: 74 20 73 74 61 74 65 20 6f 66 20 69 6e 63 72 65  t state of incre
1200: 6d 65 6e 74 61 6c 20 6d 65 72 67 65 20 2a 2f 0a  mental merge */.
1210: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
1220: 70 54 65 6d 70 31 3b 20 20 20 20 20 20 20 20 20  pTemp1;         
1230: 20 20 2f 2a 20 50 4d 41 20 66 69 6c 65 20 31 20    /* PMA file 1 
1240: 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72  */.  SorterRecor
1250: 64 20 2a 70 52 65 63 6f 72 64 3b 20 20 20 20 20  d *pRecord;     
1260: 20 20 20 20 20 2f 2a 20 48 65 61 64 20 6f 66 20       /* Head of 
1270: 69 6e 2d 6d 65 6d 6f 72 79 20 72 65 63 6f 72 64  in-memory record
1280: 20 6c 69 73 74 20 2a 2f 0a 20 20 55 6e 70 61 63   list */.  Unpac
1290: 6b 65 64 52 65 63 6f 72 64 20 2a 70 55 6e 70 61  kedRecord *pUnpa
12a0: 63 6b 65 64 3b 20 20 20 20 20 20 2f 2a 20 55 73  cked;      /* Us
12b0: 65 64 20 74 6f 20 75 6e 70 61 63 6b 20 6b 65 79  ed to unpack key
12c0: 73 20 2a 2f 0a 20 20 75 38 2a 20 61 4d 65 6d 6f  s */.  u8* aMemo
12d0: 72 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ry;             
12e0: 20 20 20 20 20 20 20 2f 2a 20 42 6c 6f 63 6b 20         /* Block 
12f0: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 72 65 63 6f  to allocate reco
1300: 72 64 73 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 6e  rds from */.  in
1310: 74 20 69 4d 65 6d 6f 72 79 3b 20 20 20 20 20 20  t iMemory;      
1320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1330: 20 4f 66 66 73 65 74 20 6f 66 20 66 72 65 65 20   Offset of free 
1340: 73 70 61 63 65 20 69 6e 20 61 4d 65 6d 6f 72 79  space in aMemory
1350: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68   */.};../*.** Th
1360: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 79 70 65  e following type
1370: 20 69 73 20 61 6e 20 69 74 65 72 61 74 6f 72 20   is an iterator 
1380: 66 6f 72 20 61 20 50 4d 41 2e 20 49 74 20 63 61  for a PMA. It ca
1390: 63 68 65 73 20 74 68 65 20 63 75 72 72 65 6e 74  ches the current
13a0: 20 6b 65 79 20 69 6e 20 0a 2a 2a 20 76 61 72 69   key in .** vari
13b0: 61 62 6c 65 73 20 6e 4b 65 79 2f 61 4b 65 79 2e  ables nKey/aKey.
13c0: 20 49 66 20 74 68 65 20 69 74 65 72 61 74 6f 72   If the iterator
13d0: 20 69 73 20 61 74 20 45 4f 46 2c 20 70 46 69 6c   is at EOF, pFil
13e0: 65 3d 3d 30 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  e==0..*/.struct 
13f0: 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 7b  VdbeSorterIter {
1400: 0a 20 20 69 36 34 20 69 52 65 61 64 4f 66 66 3b  .  i64 iReadOff;
1410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1420: 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 72 65     /* Current re
1430: 61 64 20 6f 66 66 73 65 74 20 2a 2f 0a 20 20 69  ad offset */.  i
1440: 36 34 20 69 45 6f 66 3b 20 20 20 20 20 20 20 20  64 iEof;        
1450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1460: 2a 20 31 20 62 79 74 65 20 70 61 73 74 20 45 4f  * 1 byte past EO
1470: 46 20 66 6f 72 20 74 68 69 73 20 69 74 65 72 61  F for this itera
1480: 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 6c  tor */.  int nAl
1490: 6c 6f 63 3b 20 20 20 20 20 20 20 20 20 20 20 20  loc;            
14a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65           /* Byte
14b0: 73 20 6f 66 20 73 70 61 63 65 20 61 74 20 61 41  s of space at aA
14c0: 6c 6c 6f 63 20 2a 2f 0a 20 20 69 6e 74 20 6e 4b  lloc */.  int nK
14d0: 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ey;             
14e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
14f0: 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
1500: 6b 65 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  key */.  sqlite3
1510: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20  _file *pFile;   
1520: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65           /* File
1530: 20 69 74 65 72 61 74 6f 72 20 69 73 20 72 65 61   iterator is rea
1540: 64 69 6e 67 20 66 72 6f 6d 20 2a 2f 0a 20 20 75  ding from */.  u
1550: 38 20 2a 61 41 6c 6c 6f 63 3b 20 20 20 20 20 20  8 *aAlloc;      
1560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1570: 2a 20 41 6c 6c 6f 63 61 74 65 64 20 73 70 61 63  * Allocated spac
1580: 65 20 2a 2f 0a 20 20 75 38 20 2a 61 4b 65 79 3b  e */.  u8 *aKey;
1590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15a0: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
15b0: 72 20 74 6f 20 63 75 72 72 65 6e 74 20 6b 65 79  r to current key
15c0: 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75 66 66 65   */.  u8 *aBuffe
15d0: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
15e0: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
15f0: 20 72 65 61 64 20 62 75 66 66 65 72 20 2a 2f 0a   read buffer */.
1600: 20 20 69 6e 74 20 6e 42 75 66 66 65 72 3b 20 20    int nBuffer;  
1610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1620: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 72 65 61    /* Size of rea
1630: 64 20 62 75 66 66 65 72 20 69 6e 20 62 79 74 65  d buffer in byte
1640: 73 20 2a 2f 0a 20 20 75 38 20 2a 61 4d 61 70 3b  s */.  u8 *aMap;
1650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1660: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
1670: 72 20 74 6f 20 6d 61 70 70 69 6e 67 20 6f 66 20  r to mapping of 
1680: 70 46 69 6c 65 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  pFile */.};../*.
1690: 2a 2a 20 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f  ** An instance o
16a0: 66 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65  f this structure
16b0: 20 69 73 20 75 73 65 64 20 74 6f 20 6f 72 67 61   is used to orga
16c0: 6e 69 7a 65 20 74 68 65 20 73 74 72 65 61 6d 20  nize the stream 
16d0: 6f 66 20 72 65 63 6f 72 64 73 0a 2a 2a 20 62 65  of records.** be
16e0: 69 6e 67 20 77 72 69 74 74 65 6e 20 74 6f 20 66  ing written to f
16f0: 69 6c 65 73 20 62 79 20 74 68 65 20 6d 65 72 67  iles by the merg
1700: 65 2d 73 6f 72 74 20 63 6f 64 65 20 69 6e 74 6f  e-sort code into
1710: 20 61 6c 69 67 6e 65 64 2c 20 70 61 67 65 2d 73   aligned, page-s
1720: 69 7a 65 64 0a 2a 2a 20 62 6c 6f 63 6b 73 2e 20  ized.** blocks. 
1730: 20 44 6f 69 6e 67 20 61 6c 6c 20 49 2f 4f 20 69   Doing all I/O i
1740: 6e 20 61 6c 69 67 6e 65 64 20 70 61 67 65 2d 73  n aligned page-s
1750: 69 7a 65 64 20 62 6c 6f 63 6b 73 20 68 65 6c 70  ized blocks help
1760: 73 20 49 2f 4f 20 74 6f 20 67 6f 0a 2a 2a 20 66  s I/O to go.** f
1770: 61 73 74 65 72 20 6f 6e 20 6d 61 6e 79 20 6f 70  aster on many op
1780: 65 72 61 74 69 6e 67 20 73 79 73 74 65 6d 73 2e  erating systems.
1790: 0a 2a 2f 0a 73 74 72 75 63 74 20 46 69 6c 65 57  .*/.struct FileW
17a0: 72 69 74 65 72 20 7b 0a 20 20 69 6e 74 20 65 46  riter {.  int eF
17b0: 57 45 72 72 3b 20 20 20 20 20 20 20 20 20 20 20  WErr;           
17c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 6f 6e            /* Non
17d0: 2d 7a 65 72 6f 20 69 66 20 69 6e 20 61 6e 20 65  -zero if in an e
17e0: 72 72 6f 72 20 73 74 61 74 65 20 2a 2f 0a 20 20  rror state */.  
17f0: 75 38 20 2a 61 42 75 66 66 65 72 3b 20 20 20 20  u8 *aBuffer;    
1800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1810: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 77 72  /* Pointer to wr
1820: 69 74 65 20 62 75 66 66 65 72 20 2a 2f 0a 20 20  ite buffer */.  
1830: 69 6e 74 20 6e 42 75 66 66 65 72 3b 20 20 20 20  int nBuffer;    
1840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1850: 2f 2a 20 53 69 7a 65 20 6f 66 20 77 72 69 74 65  /* Size of write
1860: 20 62 75 66 66 65 72 20 69 6e 20 62 79 74 65 73   buffer in bytes
1870: 20 2a 2f 0a 20 20 69 6e 74 20 69 42 75 66 53 74   */.  int iBufSt
1880: 61 72 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  art;            
1890: 20 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 62        /* First b
18a0: 79 74 65 20 6f 66 20 62 75 66 66 65 72 20 74 6f  yte of buffer to
18b0: 20 77 72 69 74 65 20 2a 2f 0a 20 20 69 6e 74 20   write */.  int 
18c0: 69 42 75 66 45 6e 64 3b 20 20 20 20 20 20 20 20  iBufEnd;        
18d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
18e0: 61 73 74 20 62 79 74 65 20 6f 66 20 62 75 66 66  ast byte of buff
18f0: 65 72 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20  er to write */. 
1900: 20 69 36 34 20 69 57 72 69 74 65 4f 66 66 3b 20   i64 iWriteOff; 
1910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1920: 20 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20 73 74   /* Offset of st
1930: 61 72 74 20 6f 66 20 62 75 66 66 65 72 20 69 6e  art of buffer in
1940: 20 66 69 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74   file */.  sqlit
1950: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 3b 20  e3_file *pFile; 
1960: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69             /* Fi
1970: 6c 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20 2a  le to write to *
1980: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 74  /.};../*.** A st
1990: 72 75 63 74 75 72 65 20 74 6f 20 73 74 6f 72 65  ructure to store
19a0: 20 61 20 73 69 6e 67 6c 65 20 72 65 63 6f 72 64   a single record
19b0: 2e 20 41 6c 6c 20 69 6e 2d 6d 65 6d 6f 72 79 20  . All in-memory 
19c0: 72 65 63 6f 72 64 73 20 61 72 65 20 63 6f 6e 6e  records are conn
19d0: 65 63 74 65 64 0a 2a 2a 20 74 6f 67 65 74 68 65  ected.** togethe
19e0: 72 20 69 6e 74 6f 20 61 20 6c 69 6e 6b 65 64 20  r into a linked 
19f0: 6c 69 73 74 20 68 65 61 64 65 64 20 61 74 20 56  list headed at V
1a00: 64 62 65 53 6f 72 74 65 72 2e 70 52 65 63 6f 72  dbeSorter.pRecor
1a10: 64 20 75 73 69 6e 67 20 74 68 65 20 0a 2a 2a 20  d using the .** 
1a20: 53 6f 72 74 65 72 52 65 63 6f 72 64 2e 70 4e 65  SorterRecord.pNe
1a30: 78 74 20 70 6f 69 6e 74 65 72 2e 0a 2a 2f 0a 73  xt pointer..*/.s
1a40: 74 72 75 63 74 20 53 6f 72 74 65 72 52 65 63 6f  truct SorterReco
1a50: 72 64 20 7b 0a 20 20 76 6f 69 64 20 2a 70 56 61  rd {.  void *pVa
1a60: 6c 3b 0a 20 20 69 6e 74 20 6e 56 61 6c 3b 0a 20  l;.  int nVal;. 
1a70: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
1a80: 4e 65 78 74 3b 0a 7d 3b 0a 0a 2f 2a 20 4d 69 6e  Next;.};../* Min
1a90: 69 6d 75 6d 20 61 6c 6c 6f 77 61 62 6c 65 20 76  imum allowable v
1aa0: 61 6c 75 65 20 66 6f 72 20 74 68 65 20 56 64 62  alue for the Vdb
1ab0: 65 53 6f 72 74 65 72 2e 6e 57 6f 72 6b 69 6e 67  eSorter.nWorking
1ac0: 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a 23 64 65   variable */.#de
1ad0: 66 69 6e 65 20 53 4f 52 54 45 52 5f 4d 49 4e 5f  fine SORTER_MIN_
1ae0: 57 4f 52 4b 49 4e 47 20 31 30 0a 0a 2f 2a 20 4d  WORKING 10../* M
1af0: 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66  aximum number of
1b00: 20 73 65 67 6d 65 6e 74 73 20 74 6f 20 6d 65 72   segments to mer
1b10: 67 65 20 69 6e 20 61 20 73 69 6e 67 6c 65 20 70  ge in a single p
1b20: 61 73 73 2e 20 2a 2f 0a 23 64 65 66 69 6e 65 20  ass. */.#define 
1b30: 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45  SORTER_MAX_MERGE
1b40: 5f 43 4f 55 4e 54 20 31 36 0a 0a 2f 2a 0a 2a 2a  _COUNT 16../*.**
1b50: 20 46 72 65 65 20 61 6c 6c 20 6d 65 6d 6f 72 79   Free all memory
1b60: 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 74 68   belonging to th
1b70: 65 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72  e VdbeSorterIter
1b80: 20 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20 61   object passed a
1b90: 73 20 74 68 65 20 73 65 63 6f 6e 64 0a 2a 2a 20  s the second.** 
1ba0: 61 72 67 75 6d 65 6e 74 2e 20 41 6c 6c 20 73 74  argument. All st
1bb0: 72 75 63 74 75 72 65 20 66 69 65 6c 64 73 20 61  ructure fields a
1bc0: 72 65 20 73 65 74 20 74 6f 20 7a 65 72 6f 20 62  re set to zero b
1bd0: 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
1be0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
1bf0: 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 5a 65  vdbeSorterIterZe
1c00: 72 6f 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  ro(sqlite3 *db, 
1c10: 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a  VdbeSorterIter *
1c20: 70 49 74 65 72 29 7b 0a 20 20 73 71 6c 69 74 65  pIter){.  sqlite
1c30: 33 44 62 46 72 65 65 28 64 62 2c 20 70 49 74 65  3DbFree(db, pIte
1c40: 72 2d 3e 61 41 6c 6c 6f 63 29 3b 0a 20 20 73 71  r->aAlloc);.  sq
1c50: 6c 69 74 65 33 44 62 46 72 65 65 28 64 62 2c 20  lite3DbFree(db, 
1c60: 70 49 74 65 72 2d 3e 61 42 75 66 66 65 72 29 3b  pIter->aBuffer);
1c70: 0a 20 20 69 66 28 20 70 49 74 65 72 2d 3e 61 4d  .  if( pIter->aM
1c80: 61 70 20 29 20 73 71 6c 69 74 65 33 4f 73 55 6e  ap ) sqlite3OsUn
1c90: 66 65 74 63 68 28 70 49 74 65 72 2d 3e 70 46 69  fetch(pIter->pFi
1ca0: 6c 65 2c 20 30 2c 20 70 49 74 65 72 2d 3e 61 4d  le, 0, pIter->aM
1cb0: 61 70 29 3b 0a 20 20 6d 65 6d 73 65 74 28 70 49  ap);.  memset(pI
1cc0: 74 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 56  ter, 0, sizeof(V
1cd0: 64 62 65 53 6f 72 74 65 72 49 74 65 72 29 29 3b  dbeSorterIter));
1ce0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 6e  .}../*.** Read n
1cf0: 42 79 74 65 20 62 79 74 65 73 20 6f 66 20 64 61  Byte bytes of da
1d00: 74 61 20 66 72 6f 6d 20 74 68 65 20 73 74 72 65  ta from the stre
1d10: 61 6d 20 6f 66 20 64 61 74 61 20 69 74 65 72 61  am of data itera
1d20: 74 65 64 20 62 79 20 6f 62 6a 65 63 74 20 70 2e  ted by object p.
1d30: 0a 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75  .** If successfu
1d40: 6c 2c 20 73 65 74 20 2a 70 70 4f 75 74 20 74 6f  l, set *ppOut to
1d50: 20 70 6f 69 6e 74 20 74 6f 20 61 20 62 75 66 66   point to a buff
1d60: 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68  er containing th
1d70: 65 20 64 61 74 61 0a 2a 2a 20 61 6e 64 20 72 65  e data.** and re
1d80: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20  turn SQLITE_OK. 
1d90: 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20 61 6e  Otherwise, if an
1da0: 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 72   error occurs, r
1db0: 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 0a  eturn an SQLite.
1dc0: 2a 2a 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a  ** error code..*
1dd0: 2a 0a 2a 2a 20 54 68 65 20 62 75 66 66 65 72 20  *.** The buffer 
1de0: 69 6e 64 69 63 61 74 65 64 20 62 79 20 2a 70 70  indicated by *pp
1df0: 4f 75 74 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20  Out may only be 
1e00: 63 6f 6e 73 69 64 65 72 65 64 20 76 61 6c 69 64  considered valid
1e10: 20 75 6e 74 69 6c 20 74 68 65 0a 2a 2a 20 6e 65   until the.** ne
1e20: 78 74 20 63 61 6c 6c 20 74 6f 20 74 68 69 73 20  xt call to this 
1e30: 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61  function..*/.sta
1e40: 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74  tic int vdbeSort
1e50: 65 72 49 74 65 72 52 65 61 64 28 0a 20 20 73 71  erIterRead(.  sq
1e60: 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20  lite3 *db,      
1e70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1e80: 20 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65   Database handle
1e90: 20 28 66 6f 72 20 6d 61 6c 6c 6f 63 29 20 2a 2f   (for malloc) */
1ea0: 0a 20 20 56 64 62 65 53 6f 72 74 65 72 49 74 65  .  VdbeSorterIte
1eb0: 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20  r *p,           
1ec0: 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 2a     /* Iterator *
1ed0: 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65 2c 20 20  /.  int nByte,  
1ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ef0: 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20      /* Bytes of 
1f00: 64 61 74 61 20 74 6f 20 72 65 61 64 20 2a 2f 0a  data to read */.
1f10: 20 20 75 38 20 2a 2a 70 70 4f 75 74 20 20 20 20    u8 **ppOut    
1f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f30: 20 20 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65    /* OUT: Pointe
1f40: 72 20 74 6f 20 62 75 66 66 65 72 20 63 6f 6e 74  r to buffer cont
1f50: 61 69 6e 69 6e 67 20 64 61 74 61 20 2a 2f 0a 29  aining data */.)
1f60: 7b 0a 20 20 69 6e 74 20 69 42 75 66 3b 20 20 20  {.  int iBuf;   
1f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f80: 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 77 69      /* Offset wi
1f90: 74 68 69 6e 20 62 75 66 66 65 72 20 74 6f 20 72  thin buffer to r
1fa0: 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 6e  ead from */.  in
1fb0: 74 20 6e 41 76 61 69 6c 3b 20 20 20 20 20 20 20  t nAvail;       
1fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1fd0: 20 42 79 74 65 73 20 6f 66 20 64 61 74 61 20 61   Bytes of data a
1fe0: 76 61 69 6c 61 62 6c 65 20 69 6e 20 62 75 66 66  vailable in buff
1ff0: 65 72 20 2a 2f 0a 0a 20 20 69 66 28 20 70 2d 3e  er */..  if( p->
2000: 61 4d 61 70 20 29 7b 0a 20 20 20 20 2a 70 70 4f  aMap ){.    *ppO
2010: 75 74 20 3d 20 26 70 2d 3e 61 4d 61 70 5b 70 2d  ut = &p->aMap[p-
2020: 3e 69 52 65 61 64 4f 66 66 5d 3b 0a 20 20 20 20  >iReadOff];.    
2030: 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e  p->iReadOff += n
2040: 42 79 74 65 3b 0a 20 20 20 20 72 65 74 75 72 6e  Byte;.    return
2050: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a   SQLITE_OK;.  }.
2060: 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61 42  .  assert( p->aB
2070: 75 66 66 65 72 20 29 3b 0a 0a 20 20 2f 2a 20 49  uffer );..  /* I
2080: 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20 6d 6f  f there is no mo
2090: 72 65 20 64 61 74 61 20 74 6f 20 62 65 20 72 65  re data to be re
20a0: 61 64 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66  ad from the buff
20b0: 65 72 2c 20 72 65 61 64 20 74 68 65 20 6e 65 78  er, read the nex
20c0: 74 20 0a 20 20 2a 2a 20 70 2d 3e 6e 42 75 66 66  t .  ** p->nBuff
20d0: 65 72 20 62 79 74 65 73 20 6f 66 20 64 61 74 61  er bytes of data
20e0: 20 66 72 6f 6d 20 74 68 65 20 66 69 6c 65 20 69   from the file i
20f0: 6e 74 6f 20 69 74 2e 20 4f 72 2c 20 69 66 20 74  nto it. Or, if t
2100: 68 65 72 65 20 61 72 65 20 6c 65 73 73 0a 20 20  here are less.  
2110: 2a 2a 20 74 68 61 6e 20 70 2d 3e 6e 42 75 66 66  ** than p->nBuff
2120: 65 72 20 62 79 74 65 73 20 72 65 6d 61 69 6e 69  er bytes remaini
2130: 6e 67 20 69 6e 20 74 68 65 20 50 4d 41 2c 20 72  ng in the PMA, r
2140: 65 61 64 20 61 6c 6c 20 72 65 6d 61 69 6e 69 6e  ead all remainin
2150: 67 20 64 61 74 61 2e 20 20 2a 2f 0a 20 20 69 42  g data.  */.  iB
2160: 75 66 20 3d 20 70 2d 3e 69 52 65 61 64 4f 66 66  uf = p->iReadOff
2170: 20 25 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20   % p->nBuffer;. 
2180: 20 69 66 28 20 69 42 75 66 3d 3d 30 20 29 7b 0a   if( iBuf==0 ){.
2190: 20 20 20 20 69 6e 74 20 6e 52 65 61 64 3b 20 20      int nRead;  
21a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21b0: 20 20 2f 2a 20 42 79 74 65 73 20 74 6f 20 72 65    /* Bytes to re
21c0: 61 64 20 66 72 6f 6d 20 64 69 73 6b 20 2a 2f 0a  ad from disk */.
21d0: 20 20 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20      int rc;     
21e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21f0: 20 20 2f 2a 20 73 71 6c 69 74 65 33 4f 73 52 65    /* sqlite3OsRe
2200: 61 64 28 29 20 72 65 74 75 72 6e 20 63 6f 64 65  ad() return code
2210: 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 44 65 74 65   */..    /* Dete
2220: 72 6d 69 6e 65 20 68 6f 77 20 6d 61 6e 79 20 62  rmine how many b
2230: 79 74 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20  ytes of data to 
2240: 72 65 61 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28  read. */.    if(
2250: 20 28 70 2d 3e 69 45 6f 66 20 2d 20 70 2d 3e 69   (p->iEof - p->i
2260: 52 65 61 64 4f 66 66 29 20 3e 20 28 69 36 34 29  ReadOff) > (i64)
2270: 70 2d 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20  p->nBuffer ){.  
2280: 20 20 20 20 6e 52 65 61 64 20 3d 20 70 2d 3e 6e      nRead = p->n
2290: 42 75 66 66 65 72 3b 0a 20 20 20 20 7d 65 6c 73  Buffer;.    }els
22a0: 65 7b 0a 20 20 20 20 20 20 6e 52 65 61 64 20 3d  e{.      nRead =
22b0: 20 28 69 6e 74 29 28 70 2d 3e 69 45 6f 66 20 2d   (int)(p->iEof -
22c0: 20 70 2d 3e 69 52 65 61 64 4f 66 66 29 3b 0a 20   p->iReadOff);. 
22d0: 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28     }.    assert(
22e0: 20 6e 52 65 61 64 3e 30 20 29 3b 0a 0a 20 20 20   nRead>0 );..   
22f0: 20 2f 2a 20 52 65 61 64 20 64 61 74 61 20 66 72   /* Read data fr
2300: 6f 6d 20 74 68 65 20 66 69 6c 65 2e 20 52 65 74  om the file. Ret
2310: 75 72 6e 20 65 61 72 6c 79 20 69 66 20 61 6e 20  urn early if an 
2320: 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 20 2a 2f  error occurs. */
2330: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
2340: 33 4f 73 52 65 61 64 28 70 2d 3e 70 46 69 6c 65  3OsRead(p->pFile
2350: 2c 20 70 2d 3e 61 42 75 66 66 65 72 2c 20 6e 52  , p->aBuffer, nR
2360: 65 61 64 2c 20 70 2d 3e 69 52 65 61 64 4f 66 66  ead, p->iReadOff
2370: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 72  );.    assert( r
2380: 63 21 3d 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f  c!=SQLITE_IOERR_
2390: 53 48 4f 52 54 5f 52 45 41 44 20 29 3b 0a 20 20  SHORT_READ );.  
23a0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
23b0: 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
23c0: 0a 20 20 7d 0a 20 20 6e 41 76 61 69 6c 20 3d 20  .  }.  nAvail = 
23d0: 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 69 42 75  p->nBuffer - iBu
23e0: 66 3b 20 0a 0a 20 20 69 66 28 20 6e 42 79 74 65  f; ..  if( nByte
23f0: 3c 3d 6e 41 76 61 69 6c 20 29 7b 0a 20 20 20 20  <=nAvail ){.    
2400: 2f 2a 20 54 68 65 20 72 65 71 75 65 73 74 65 64  /* The requested
2410: 20 64 61 74 61 20 69 73 20 61 76 61 69 6c 61 62   data is availab
2420: 6c 65 20 69 6e 20 74 68 65 20 69 6e 2d 6d 65 6d  le in the in-mem
2430: 6f 72 79 20 62 75 66 66 65 72 2e 20 49 6e 20 74  ory buffer. In t
2440: 68 69 73 0a 20 20 20 20 2a 2a 20 63 61 73 65 20  his.    ** case 
2450: 74 68 65 72 65 20 69 73 20 6e 6f 20 6e 65 65 64  there is no need
2460: 20 74 6f 20 6d 61 6b 65 20 61 20 63 6f 70 79 20   to make a copy 
2470: 6f 66 20 74 68 65 20 64 61 74 61 2c 20 6a 75 73  of the data, jus
2480: 74 20 72 65 74 75 72 6e 20 61 20 0a 20 20 20 20  t return a .    
2490: 2a 2a 20 70 6f 69 6e 74 65 72 20 69 6e 74 6f 20  ** pointer into 
24a0: 74 68 65 20 62 75 66 66 65 72 20 74 6f 20 74 68  the buffer to th
24b0: 65 20 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a 20 20  e caller.  */.  
24c0: 20 20 2a 70 70 4f 75 74 20 3d 20 26 70 2d 3e 61    *ppOut = &p->a
24d0: 42 75 66 66 65 72 5b 69 42 75 66 5d 3b 0a 20 20  Buffer[iBuf];.  
24e0: 20 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d    p->iReadOff +=
24f0: 20 6e 42 79 74 65 3b 0a 20 20 7d 65 6c 73 65 7b   nByte;.  }else{
2500: 0a 20 20 20 20 2f 2a 20 54 68 65 20 72 65 71 75  .    /* The requ
2510: 65 73 74 65 64 20 64 61 74 61 20 69 73 20 6e 6f  ested data is no
2520: 74 20 61 6c 6c 20 61 76 61 69 6c 61 62 6c 65 20  t all available 
2530: 69 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79  in the in-memory
2540: 20 62 75 66 66 65 72 2e 0a 20 20 20 20 2a 2a 20   buffer..    ** 
2550: 49 6e 20 74 68 69 73 20 63 61 73 65 2c 20 61 6c  In this case, al
2560: 6c 6f 63 61 74 65 20 73 70 61 63 65 20 61 74 20  locate space at 
2570: 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 74 6f 20 63  p->aAlloc[] to c
2580: 6f 70 79 20 74 68 65 20 72 65 71 75 65 73 74 65  opy the requeste
2590: 64 0a 20 20 20 20 2a 2a 20 72 61 6e 67 65 20 69  d.    ** range i
25a0: 6e 74 6f 2e 20 54 68 65 6e 20 72 65 74 75 72 6e  nto. Then return
25b0: 20 61 20 63 6f 70 79 20 6f 66 20 70 6f 69 6e 74   a copy of point
25c0: 65 72 20 70 2d 3e 61 41 6c 6c 6f 63 20 74 6f 20  er p->aAlloc to 
25d0: 74 68 65 20 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a  the caller.  */.
25e0: 20 20 20 20 69 6e 74 20 6e 52 65 6d 3b 20 20 20      int nRem;   
25f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2600: 20 20 2f 2a 20 42 79 74 65 73 20 72 65 6d 61 69    /* Bytes remai
2610: 6e 69 6e 67 20 74 6f 20 63 6f 70 79 20 2a 2f 0a  ning to copy */.
2620: 0a 20 20 20 20 2f 2a 20 45 78 74 65 6e 64 20 74  .    /* Extend t
2630: 68 65 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 61  he p->aAlloc[] a
2640: 6c 6c 6f 63 61 74 69 6f 6e 20 69 66 20 72 65 71  llocation if req
2650: 75 69 72 65 64 2e 20 2a 2f 0a 20 20 20 20 69 66  uired. */.    if
2660: 28 20 70 2d 3e 6e 41 6c 6c 6f 63 3c 6e 42 79 74  ( p->nAlloc<nByt
2670: 65 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e  e ){.      int n
2680: 4e 65 77 20 3d 20 70 2d 3e 6e 41 6c 6c 6f 63 2a  New = p->nAlloc*
2690: 32 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20  2;.      while( 
26a0: 6e 42 79 74 65 3e 6e 4e 65 77 20 29 20 6e 4e 65  nByte>nNew ) nNe
26b0: 77 20 3d 20 6e 4e 65 77 2a 32 3b 0a 20 20 20 20  w = nNew*2;.    
26c0: 20 20 70 2d 3e 61 41 6c 6c 6f 63 20 3d 20 73 71    p->aAlloc = sq
26d0: 6c 69 74 65 33 44 62 52 65 61 6c 6c 6f 63 4f 72  lite3DbReallocOr
26e0: 46 72 65 65 28 64 62 2c 20 70 2d 3e 61 41 6c 6c  Free(db, p->aAll
26f0: 6f 63 2c 20 6e 4e 65 77 29 3b 0a 20 20 20 20 20  oc, nNew);.     
2700: 20 69 66 28 20 21 70 2d 3e 61 41 6c 6c 6f 63 20   if( !p->aAlloc 
2710: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
2720: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 70 2d 3e  NOMEM;.      p->
2730: 6e 41 6c 6c 6f 63 20 3d 20 6e 4e 65 77 3b 0a 20  nAlloc = nNew;. 
2740: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 43 6f 70     }..    /* Cop
2750: 79 20 61 73 20 6d 75 63 68 20 64 61 74 61 20 61  y as much data a
2760: 73 20 69 73 20 61 76 61 69 6c 61 62 6c 65 20 69  s is available i
2770: 6e 20 74 68 65 20 62 75 66 66 65 72 20 69 6e 74  n the buffer int
2780: 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 0a 20  o the start of. 
2790: 20 20 20 2a 2a 20 70 2d 3e 61 41 6c 6c 6f 63 5b     ** p->aAlloc[
27a0: 5d 2e 20 20 2a 2f 0a 20 20 20 20 6d 65 6d 63 70  ].  */.    memcp
27b0: 79 28 70 2d 3e 61 41 6c 6c 6f 63 2c 20 26 70 2d  y(p->aAlloc, &p-
27c0: 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d 2c 20  >aBuffer[iBuf], 
27d0: 6e 41 76 61 69 6c 29 3b 0a 20 20 20 20 70 2d 3e  nAvail);.    p->
27e0: 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e 41 76 61  iReadOff += nAva
27f0: 69 6c 3b 0a 20 20 20 20 6e 52 65 6d 20 3d 20 6e  il;.    nRem = n
2800: 42 79 74 65 20 2d 20 6e 41 76 61 69 6c 3b 0a 0a  Byte - nAvail;..
2810: 20 20 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f      /* The follo
2820: 77 69 6e 67 20 6c 6f 6f 70 20 63 6f 70 69 65 73  wing loop copies
2830: 20 75 70 20 74 6f 20 70 2d 3e 6e 42 75 66 66 65   up to p->nBuffe
2840: 72 20 62 79 74 65 73 20 70 65 72 20 69 74 65 72  r bytes per iter
2850: 61 74 69 6f 6e 20 69 6e 74 6f 0a 20 20 20 20 2a  ation into.    *
2860: 2a 20 74 68 65 20 70 2d 3e 61 41 6c 6c 6f 63 5b  * the p->aAlloc[
2870: 5d 20 62 75 66 66 65 72 2e 20 20 2a 2f 0a 20 20  ] buffer.  */.  
2880: 20 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30 20    while( nRem>0 
2890: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72 63 3b  ){.      int rc;
28a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
28b0: 20 20 20 20 20 2f 2a 20 76 64 62 65 53 6f 72 74       /* vdbeSort
28c0: 65 72 49 74 65 72 52 65 61 64 28 29 20 72 65 74  erIterRead() ret
28d0: 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 20 20  urn code */.    
28e0: 20 20 69 6e 74 20 6e 43 6f 70 79 3b 20 20 20 20    int nCopy;    
28f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2900: 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   Number of bytes
2910: 20 74 6f 20 63 6f 70 79 20 2a 2f 0a 20 20 20 20   to copy */.    
2920: 20 20 75 38 20 2a 61 4e 65 78 74 3b 20 20 20 20    u8 *aNext;    
2930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2940: 20 50 6f 69 6e 74 65 72 20 74 6f 20 62 75 66 66   Pointer to buff
2950: 65 72 20 74 6f 20 63 6f 70 79 20 64 61 74 61 20  er to copy data 
2960: 66 72 6f 6d 20 2a 2f 0a 0a 20 20 20 20 20 20 6e  from */..      n
2970: 43 6f 70 79 20 3d 20 6e 52 65 6d 3b 0a 20 20 20  Copy = nRem;.   
2980: 20 20 20 69 66 28 20 6e 52 65 6d 3e 70 2d 3e 6e     if( nRem>p->n
2990: 42 75 66 66 65 72 20 29 20 6e 43 6f 70 79 20 3d  Buffer ) nCopy =
29a0: 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20   p->nBuffer;.   
29b0: 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74     rc = vdbeSort
29c0: 65 72 49 74 65 72 52 65 61 64 28 64 62 2c 20 70  erIterRead(db, p
29d0: 2c 20 6e 43 6f 70 79 2c 20 26 61 4e 65 78 74 29  , nCopy, &aNext)
29e0: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  ;.      if( rc!=
29f0: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
2a00: 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 61 73 73  rn rc;.      ass
2a10: 65 72 74 28 20 61 4e 65 78 74 21 3d 70 2d 3e 61  ert( aNext!=p->a
2a20: 41 6c 6c 6f 63 20 29 3b 0a 20 20 20 20 20 20 6d  Alloc );.      m
2a30: 65 6d 63 70 79 28 26 70 2d 3e 61 41 6c 6c 6f 63  emcpy(&p->aAlloc
2a40: 5b 6e 42 79 74 65 20 2d 20 6e 52 65 6d 5d 2c 20  [nByte - nRem], 
2a50: 61 4e 65 78 74 2c 20 6e 43 6f 70 79 29 3b 0a 20  aNext, nCopy);. 
2a60: 20 20 20 20 20 6e 52 65 6d 20 2d 3d 20 6e 43 6f       nRem -= nCo
2a70: 70 79 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2a  py;.    }..    *
2a80: 70 70 4f 75 74 20 3d 20 70 2d 3e 61 41 6c 6c 6f  ppOut = p->aAllo
2a90: 63 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  c;.  }..  return
2aa0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
2ab0: 2a 0a 2a 2a 20 52 65 61 64 20 61 20 76 61 72 69  *.** Read a vari
2ac0: 6e 74 20 66 72 6f 6d 20 74 68 65 20 73 74 72 65  nt from the stre
2ad0: 61 6d 20 6f 66 20 64 61 74 61 20 61 63 63 65 73  am of data acces
2ae0: 73 65 64 20 62 79 20 70 2e 20 53 65 74 20 2a 70  sed by p. Set *p
2af0: 6e 4f 75 74 20 74 6f 0a 2a 2a 20 74 68 65 20 76  nOut to.** the v
2b00: 61 6c 75 65 20 72 65 61 64 2e 0a 2a 2f 0a 73 74  alue read..*/.st
2b10: 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72  atic int vdbeSor
2b20: 74 65 72 49 74 65 72 56 61 72 69 6e 74 28 73 71  terIterVarint(sq
2b30: 6c 69 74 65 33 20 2a 64 62 2c 20 56 64 62 65 53  lite3 *db, VdbeS
2b40: 6f 72 74 65 72 49 74 65 72 20 2a 70 2c 20 75 36  orterIter *p, u6
2b50: 34 20 2a 70 6e 4f 75 74 29 7b 0a 20 20 69 6e 74  4 *pnOut){.  int
2b60: 20 69 42 75 66 3b 0a 0a 20 20 69 66 28 20 70 2d   iBuf;..  if( p-
2b70: 3e 61 4d 61 70 20 29 7b 0a 20 20 20 20 70 2d 3e  >aMap ){.    p->
2b80: 69 52 65 61 64 4f 66 66 20 2b 3d 20 73 71 6c 69  iReadOff += sqli
2b90: 74 65 33 47 65 74 56 61 72 69 6e 74 28 26 70 2d  te3GetVarint(&p-
2ba0: 3e 61 4d 61 70 5b 70 2d 3e 69 52 65 61 64 4f 66  >aMap[p->iReadOf
2bb0: 66 5d 2c 20 70 6e 4f 75 74 29 3b 0a 20 20 7d 65  f], pnOut);.  }e
2bc0: 6c 73 65 7b 0a 20 20 20 20 69 42 75 66 20 3d 20  lse{.    iBuf = 
2bd0: 70 2d 3e 69 52 65 61 64 4f 66 66 20 25 20 70 2d  p->iReadOff % p-
2be0: 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20 20 69 66  >nBuffer;.    if
2bf0: 28 20 69 42 75 66 20 26 26 20 28 70 2d 3e 6e 42  ( iBuf && (p->nB
2c00: 75 66 66 65 72 2d 69 42 75 66 29 3e 3d 39 20 29  uffer-iBuf)>=9 )
2c10: 7b 0a 20 20 20 20 20 20 70 2d 3e 69 52 65 61 64  {.      p->iRead
2c20: 4f 66 66 20 2b 3d 20 73 71 6c 69 74 65 33 47 65  Off += sqlite3Ge
2c30: 74 56 61 72 69 6e 74 28 26 70 2d 3e 61 42 75 66  tVarint(&p->aBuf
2c40: 66 65 72 5b 69 42 75 66 5d 2c 20 70 6e 4f 75 74  fer[iBuf], pnOut
2c50: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
2c60: 20 20 20 20 75 38 20 61 56 61 72 69 6e 74 5b 31      u8 aVarint[1
2c70: 36 5d 2c 20 2a 61 3b 0a 20 20 20 20 20 20 69 6e  6], *a;.      in
2c80: 74 20 69 20 3d 20 30 2c 20 72 63 3b 0a 20 20 20  t i = 0, rc;.   
2c90: 20 20 20 64 6f 7b 0a 20 20 20 20 20 20 20 20 72     do{.        r
2ca0: 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 49 74  c = vdbeSorterIt
2cb0: 65 72 52 65 61 64 28 64 62 2c 20 70 2c 20 31 2c  erRead(db, p, 1,
2cc0: 20 26 61 29 3b 0a 20 20 20 20 20 20 20 20 69 66   &a);.        if
2cd0: 28 20 72 63 20 29 20 72 65 74 75 72 6e 20 72 63  ( rc ) return rc
2ce0: 3b 0a 20 20 20 20 20 20 20 20 61 56 61 72 69 6e  ;.        aVarin
2cf0: 74 5b 28 69 2b 2b 29 26 30 78 66 5d 20 3d 20 61  t[(i++)&0xf] = a
2d00: 5b 30 5d 3b 0a 20 20 20 20 20 20 7d 77 68 69 6c  [0];.      }whil
2d10: 65 28 20 28 61 5b 30 5d 26 30 78 38 30 29 21 3d  e( (a[0]&0x80)!=
2d20: 30 20 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  0 );.      sqlit
2d30: 65 33 47 65 74 56 61 72 69 6e 74 28 61 56 61 72  e3GetVarint(aVar
2d40: 69 6e 74 2c 20 70 6e 4f 75 74 29 3b 0a 20 20 20  int, pnOut);.   
2d50: 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
2d60: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a   SQLITE_OK;.}...
2d70: 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 69 74  /*.** Advance it
2d80: 65 72 61 74 6f 72 20 70 49 74 65 72 20 74 6f 20  erator pIter to 
2d90: 74 68 65 20 6e 65 78 74 20 6b 65 79 20 69 6e 20  the next key in 
2da0: 69 74 73 20 50 4d 41 2e 20 52 65 74 75 72 6e 20  its PMA. Return 
2db0: 53 51 4c 49 54 45 5f 4f 4b 20 69 66 0a 2a 2a 20  SQLITE_OK if.** 
2dc0: 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c  no error occurs,
2dd0: 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72   or an SQLite er
2de0: 72 6f 72 20 63 6f 64 65 20 69 66 20 6f 6e 65 20  ror code if one 
2df0: 64 6f 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  does..*/.static 
2e00: 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72 49 74  int vdbeSorterIt
2e10: 65 72 4e 65 78 74 28 0a 20 20 73 71 6c 69 74 65  erNext(.  sqlite
2e20: 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20  3 *db,          
2e30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
2e40: 61 62 61 73 65 20 68 61 6e 64 6c 65 20 28 66 6f  abase handle (fo
2e50: 72 20 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f  r sqlite3DbMallo
2e60: 63 28 29 20 29 20 2a 2f 0a 20 20 56 64 62 65 53  c() ) */.  VdbeS
2e70: 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74 65 72  orterIter *pIter
2e80: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 74             /* It
2e90: 65 72 61 74 6f 72 20 74 6f 20 61 64 76 61 6e 63  erator to advanc
2ea0: 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63  e */.){.  int rc
2eb0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
2ec0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
2ed0: 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 75 36  urn Code */.  u6
2ee0: 34 20 6e 52 65 63 20 3d 20 30 3b 20 20 20 20 20  4 nRec = 0;     
2ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2f00: 20 53 69 7a 65 20 6f 66 20 72 65 63 6f 72 64 20   Size of record 
2f10: 69 6e 20 62 79 74 65 73 20 2a 2f 0a 0a 20 20 69  in bytes */..  i
2f20: 66 28 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f  f( pIter->iReadO
2f30: 66 66 3e 3d 70 49 74 65 72 2d 3e 69 45 6f 66 20  ff>=pIter->iEof 
2f40: 29 7b 0a 20 20 20 20 2f 2a 20 54 68 69 73 20 69  ){.    /* This i
2f50: 73 20 61 6e 20 45 4f 46 20 63 6f 6e 64 69 74 69  s an EOF conditi
2f60: 6f 6e 20 2a 2f 0a 20 20 20 20 76 64 62 65 53 6f  on */.    vdbeSo
2f70: 72 74 65 72 49 74 65 72 5a 65 72 6f 28 64 62 2c  rterIterZero(db,
2f80: 20 70 49 74 65 72 29 3b 0a 20 20 20 20 72 65 74   pIter);.    ret
2f90: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  urn SQLITE_OK;. 
2fa0: 20 7d 0a 0a 20 20 72 63 20 3d 20 76 64 62 65 53   }..  rc = vdbeS
2fb0: 6f 72 74 65 72 49 74 65 72 56 61 72 69 6e 74 28  orterIterVarint(
2fc0: 64 62 2c 20 70 49 74 65 72 2c 20 26 6e 52 65 63  db, pIter, &nRec
2fd0: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  );.  if( rc==SQL
2fe0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 49  ITE_OK ){.    pI
2ff0: 74 65 72 2d 3e 6e 4b 65 79 20 3d 20 28 69 6e 74  ter->nKey = (int
3000: 29 6e 52 65 63 3b 0a 20 20 20 20 72 63 20 3d 20  )nRec;.    rc = 
3010: 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 52 65  vdbeSorterIterRe
3020: 61 64 28 64 62 2c 20 70 49 74 65 72 2c 20 28 69  ad(db, pIter, (i
3030: 6e 74 29 6e 52 65 63 2c 20 26 70 49 74 65 72 2d  nt)nRec, &pIter-
3040: 3e 61 4b 65 79 29 3b 0a 20 20 7d 0a 0a 20 20 72  >aKey);.  }..  r
3050: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
3060: 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 69 74  ** Initialize it
3070: 65 72 61 74 6f 72 20 70 49 74 65 72 20 74 6f 20  erator pIter to 
3080: 73 63 61 6e 20 74 68 72 6f 75 67 68 20 74 68 65  scan through the
3090: 20 50 4d 41 20 73 74 6f 72 65 64 20 69 6e 20 66   PMA stored in f
30a0: 69 6c 65 20 70 46 69 6c 65 0a 2a 2a 20 73 74 61  ile pFile.** sta
30b0: 72 74 69 6e 67 20 61 74 20 6f 66 66 73 65 74 20  rting at offset 
30c0: 69 53 74 61 72 74 20 61 6e 64 20 65 6e 64 69 6e  iStart and endin
30d0: 67 20 61 74 20 6f 66 66 73 65 74 20 69 45 6f 66  g at offset iEof
30e0: 2d 31 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f  -1. This functio
30f0: 6e 20 0a 2a 2a 20 6c 65 61 76 65 73 20 74 68 65  n .** leaves the
3100: 20 69 74 65 72 61 74 6f 72 20 70 6f 69 6e 74 69   iterator pointi
3110: 6e 67 20 74 6f 20 74 68 65 20 66 69 72 73 74 20  ng to the first 
3120: 6b 65 79 20 69 6e 20 74 68 65 20 50 4d 41 20 28  key in the PMA (
3130: 6f 72 20 45 4f 46 20 69 66 20 74 68 65 20 0a 2a  or EOF if the .*
3140: 2a 20 50 4d 41 20 69 73 20 65 6d 70 74 79 29 2e  * PMA is empty).
3150: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 76  .*/.static int v
3160: 64 62 65 53 6f 72 74 65 72 49 74 65 72 49 6e 69  dbeSorterIterIni
3170: 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  t(.  sqlite3 *db
3180: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
3190: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
31a0: 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e   handle */.  con
31b0: 73 74 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70  st VdbeSorter *p
31c0: 53 6f 72 74 65 72 2c 20 20 20 20 20 20 2f 2a 20  Sorter,      /* 
31d0: 53 6f 72 74 65 72 20 6f 62 6a 65 63 74 20 2a 2f  Sorter object */
31e0: 0a 20 20 69 36 34 20 69 53 74 61 72 74 2c 20 20  .  i64 iStart,  
31f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3200: 20 20 20 2f 2a 20 53 74 61 72 74 20 6f 66 66 73     /* Start offs
3210: 65 74 20 69 6e 20 70 46 69 6c 65 20 2a 2f 0a 20  et in pFile */. 
3220: 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20   VdbeSorterIter 
3230: 2a 70 49 74 65 72 2c 20 20 20 20 20 20 20 20 20  *pIter,         
3240: 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 74 6f 20   /* Iterator to 
3250: 70 6f 70 75 6c 61 74 65 20 2a 2f 0a 20 20 69 36  populate */.  i6
3260: 34 20 2a 70 6e 42 79 74 65 20 20 20 20 20 20 20  4 *pnByte       
3270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3280: 20 49 4e 2f 4f 55 54 3a 20 49 6e 63 72 65 6d 65   IN/OUT: Increme
3290: 6e 74 20 74 68 69 73 20 76 61 6c 75 65 20 62 79  nt this value by
32a0: 20 50 4d 41 20 73 69 7a 65 20 2a 2f 0a 29 7b 0a   PMA size */.){.
32b0: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
32c0: 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 42 75 66  E_OK;.  int nBuf
32d0: 3b 0a 20 20 76 6f 69 64 20 2a 70 4d 61 70 3b 0a  ;.  void *pMap;.
32e0: 0a 20 20 6e 42 75 66 20 3d 20 73 71 6c 69 74 65  .  nBuf = sqlite
32f0: 33 42 74 72 65 65 47 65 74 50 61 67 65 53 69 7a  3BtreeGetPageSiz
3300: 65 28 64 62 2d 3e 61 44 62 5b 30 5d 2e 70 42 74  e(db->aDb[0].pBt
3310: 29 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 53  );..  assert( pS
3320: 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f 66 66  orter->iWriteOff
3330: 3e 69 53 74 61 72 74 20 29 3b 0a 20 20 61 73 73  >iStart );.  ass
3340: 65 72 74 28 20 70 49 74 65 72 2d 3e 61 41 6c 6c  ert( pIter->aAll
3350: 6f 63 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  oc==0 );.  asser
3360: 74 28 20 70 49 74 65 72 2d 3e 61 42 75 66 66 65  t( pIter->aBuffe
3370: 72 3d 3d 30 20 29 3b 0a 20 20 70 49 74 65 72 2d  r==0 );.  pIter-
3380: 3e 70 46 69 6c 65 20 3d 20 70 53 6f 72 74 65 72  >pFile = pSorter
3390: 2d 3e 70 54 65 6d 70 31 3b 0a 20 20 70 49 74 65  ->pTemp1;.  pIte
33a0: 72 2d 3e 69 52 65 61 64 4f 66 66 20 3d 20 69 53  r->iReadOff = iS
33b0: 74 61 72 74 3b 0a 20 20 70 49 74 65 72 2d 3e 6e  tart;.  pIter->n
33c0: 41 6c 6c 6f 63 20 3d 20 31 32 38 3b 0a 20 20 70  Alloc = 128;.  p
33d0: 49 74 65 72 2d 3e 61 41 6c 6c 6f 63 20 3d 20 28  Iter->aAlloc = (
33e0: 75 38 20 2a 29 73 71 6c 69 74 65 33 44 62 4d 61  u8 *)sqlite3DbMa
33f0: 6c 6c 6f 63 52 61 77 28 64 62 2c 20 70 49 74 65  llocRaw(db, pIte
3400: 72 2d 3e 6e 41 6c 6c 6f 63 29 3b 0a 0a 20 20 2f  r->nAlloc);..  /
3410: 2a 20 53 65 65 20 69 66 20 74 68 69 73 20 50 4d  * See if this PM
3420: 41 20 63 61 6e 20 62 65 20 72 65 61 64 20 75 73  A can be read us
3430: 69 6e 67 20 78 46 65 74 63 68 2e 20 2a 2f 0a 20  ing xFetch. */. 
3440: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 46   rc = sqlite3OsF
3450: 65 74 63 68 28 70 49 74 65 72 2d 3e 70 46 69 6c  etch(pIter->pFil
3460: 65 2c 20 30 2c 20 70 53 6f 72 74 65 72 2d 3e 69  e, 0, pSorter->i
3470: 57 72 69 74 65 4f 66 66 2c 20 26 70 4d 61 70 29  WriteOff, &pMap)
3480: 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
3490: 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
34a0: 63 3b 0a 20 20 69 66 28 20 70 4d 61 70 20 29 7b  c;.  if( pMap ){
34b0: 0a 20 20 20 20 70 49 74 65 72 2d 3e 61 4d 61 70  .    pIter->aMap
34c0: 20 3d 20 28 75 38 2a 29 70 4d 61 70 3b 0a 20 20   = (u8*)pMap;.  
34d0: 7d 65 6c 73 65 7b 0a 20 20 20 20 70 49 74 65 72  }else{.    pIter
34e0: 2d 3e 6e 42 75 66 66 65 72 20 3d 20 6e 42 75 66  ->nBuffer = nBuf
34f0: 3b 0a 20 20 20 20 70 49 74 65 72 2d 3e 61 42 75  ;.    pIter->aBu
3500: 66 66 65 72 20 3d 20 28 75 38 20 2a 29 73 71 6c  ffer = (u8 *)sql
3510: 69 74 65 33 44 62 4d 61 6c 6c 6f 63 52 61 77 28  ite3DbMallocRaw(
3520: 64 62 2c 20 6e 42 75 66 29 3b 0a 0a 20 20 20 20  db, nBuf);..    
3530: 69 66 28 20 21 70 49 74 65 72 2d 3e 61 42 75 66  if( !pIter->aBuf
3540: 66 65 72 20 29 7b 0a 20 20 20 20 20 20 72 63 20  fer ){.      rc 
3550: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
3560: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
3570: 20 69 6e 74 20 69 42 75 66 3b 0a 0a 20 20 20 20   int iBuf;..    
3580: 20 20 69 42 75 66 20 3d 20 69 53 74 61 72 74 20    iBuf = iStart 
3590: 25 20 6e 42 75 66 3b 0a 20 20 20 20 20 20 69 66  % nBuf;.      if
35a0: 28 20 69 42 75 66 20 29 7b 0a 20 20 20 20 20 20  ( iBuf ){.      
35b0: 20 20 69 6e 74 20 6e 52 65 61 64 20 3d 20 6e 42    int nRead = nB
35c0: 75 66 20 2d 20 69 42 75 66 3b 0a 20 20 20 20 20  uf - iBuf;.     
35d0: 20 20 20 69 66 28 20 28 69 53 74 61 72 74 20 2b     if( (iStart +
35e0: 20 6e 52 65 61 64 29 20 3e 20 70 53 6f 72 74 65   nRead) > pSorte
35f0: 72 2d 3e 69 57 72 69 74 65 4f 66 66 20 29 7b 0a  r->iWriteOff ){.
3600: 20 20 20 20 20 20 20 20 20 20 6e 52 65 61 64 20            nRead 
3610: 3d 20 28 69 6e 74 29 28 70 53 6f 72 74 65 72 2d  = (int)(pSorter-
3620: 3e 69 57 72 69 74 65 4f 66 66 20 2d 20 69 53 74  >iWriteOff - iSt
3630: 61 72 74 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  art);.        }.
3640: 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c          rc = sql
3650: 69 74 65 33 4f 73 52 65 61 64 28 0a 20 20 20 20  ite3OsRead(.    
3660: 20 20 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d          pSorter-
3670: 3e 70 54 65 6d 70 31 2c 20 26 70 49 74 65 72 2d  >pTemp1, &pIter-
3680: 3e 61 42 75 66 66 65 72 5b 69 42 75 66 5d 2c 20  >aBuffer[iBuf], 
3690: 6e 52 65 61 64 2c 20 69 53 74 61 72 74 0a 20 20  nRead, iStart.  
36a0: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20        );.       
36b0: 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c   assert( rc!=SQL
36c0: 49 54 45 5f 49 4f 45 52 52 5f 53 48 4f 52 54 5f  ITE_IOERR_SHORT_
36d0: 52 45 41 44 20 29 3b 0a 20 20 20 20 20 20 7d 0a  READ );.      }.
36e0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28      }.  }..  if(
36f0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
3700: 7b 0a 20 20 20 20 75 36 34 20 6e 42 79 74 65 3b  {.    u64 nByte;
3710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3720: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
3730: 66 20 50 4d 41 20 69 6e 20 62 79 74 65 73 20 2a  f PMA in bytes *
3740: 2f 0a 20 20 20 20 70 49 74 65 72 2d 3e 69 45 6f  /.    pIter->iEo
3750: 66 20 3d 20 70 53 6f 72 74 65 72 2d 3e 69 57 72  f = pSorter->iWr
3760: 69 74 65 4f 66 66 3b 0a 20 20 20 20 72 63 20 3d  iteOff;.    rc =
3770: 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 56   vdbeSorterIterV
3780: 61 72 69 6e 74 28 64 62 2c 20 70 49 74 65 72 2c  arint(db, pIter,
3790: 20 26 6e 42 79 74 65 29 3b 0a 20 20 20 20 70 49   &nByte);.    pI
37a0: 74 65 72 2d 3e 69 45 6f 66 20 3d 20 70 49 74 65  ter->iEof = pIte
37b0: 72 2d 3e 69 52 65 61 64 4f 66 66 20 2b 20 6e 42  r->iReadOff + nB
37c0: 79 74 65 3b 0a 20 20 20 20 2a 70 6e 42 79 74 65  yte;.    *pnByte
37d0: 20 2b 3d 20 6e 42 79 74 65 3b 0a 20 20 7d 0a 0a   += nByte;.  }..
37e0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
37f0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
3800: 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 4e 65  vdbeSorterIterNe
3810: 78 74 28 64 62 2c 20 70 49 74 65 72 29 3b 0a 20  xt(db, pIter);. 
3820: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
3830: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 61 72  }.../*.** Compar
3840: 65 20 6b 65 79 31 20 28 62 75 66 66 65 72 20 70  e key1 (buffer p
3850: 4b 65 79 31 2c 20 73 69 7a 65 20 6e 4b 65 79 31  Key1, size nKey1
3860: 20 62 79 74 65 73 29 20 77 69 74 68 20 6b 65 79   bytes) with key
3870: 32 20 28 62 75 66 66 65 72 20 70 4b 65 79 32 2c  2 (buffer pKey2,
3880: 20 0a 2a 2a 20 73 69 7a 65 20 6e 4b 65 79 32 20   .** size nKey2 
3890: 62 79 74 65 73 29 2e 20 20 41 72 67 75 6d 65 6e  bytes).  Argumen
38a0: 74 20 70 4b 65 79 49 6e 66 6f 20 73 75 70 70 6c  t pKeyInfo suppl
38b0: 69 65 73 20 74 68 65 20 63 6f 6c 6c 61 74 69 6f  ies the collatio
38c0: 6e 20 66 75 6e 63 74 69 6f 6e 73 0a 2a 2a 20 75  n functions.** u
38d0: 73 65 64 20 62 79 20 74 68 65 20 63 6f 6d 70 61  sed by the compa
38e0: 72 69 73 6f 6e 2e 20 49 66 20 61 6e 20 65 72 72  rison. If an err
38f0: 6f 72 20 6f 63 63 75 72 73 2c 20 72 65 74 75 72  or occurs, retur
3900: 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  n an SQLite erro
3910: 72 20 63 6f 64 65 2e 0a 2a 2a 20 4f 74 68 65 72  r code..** Other
3920: 77 69 73 65 2c 20 72 65 74 75 72 6e 20 53 51 4c  wise, return SQL
3930: 49 54 45 5f 4f 4b 20 61 6e 64 20 73 65 74 20 2a  ITE_OK and set *
3940: 70 52 65 73 20 74 6f 20 61 20 6e 65 67 61 74 69  pRes to a negati
3950: 76 65 2c 20 7a 65 72 6f 20 6f 72 20 70 6f 73 69  ve, zero or posi
3960: 74 69 76 65 0a 2a 2a 20 76 61 6c 75 65 2c 20 64  tive.** value, d
3970: 65 70 65 6e 64 69 6e 67 20 6f 6e 20 77 68 65 74  epending on whet
3980: 68 65 72 20 6b 65 79 31 20 69 73 20 73 6d 61 6c  her key1 is smal
3990: 6c 65 72 2c 20 65 71 75 61 6c 20 74 6f 20 6f 72  ler, equal to or
39a0: 20 6c 61 72 67 65 72 20 74 68 61 6e 20 6b 65 79   larger than key
39b0: 32 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20  2..**.** If the 
39c0: 62 4f 6d 69 74 52 6f 77 69 64 20 61 72 67 75 6d  bOmitRowid argum
39d0: 65 6e 74 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c  ent is non-zero,
39e0: 20 61 73 73 75 6d 65 20 62 6f 74 68 20 6b 65 79   assume both key
39f0: 73 20 65 6e 64 20 69 6e 20 61 20 72 6f 77 69 64  s end in a rowid
3a00: 0a 2a 2a 20 66 69 65 6c 64 2e 20 46 6f 72 20 74  .** field. For t
3a10: 68 65 20 70 75 72 70 6f 73 65 73 20 6f 66 20 74  he purposes of t
3a20: 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2c 20 69  he comparison, i
3a30: 67 6e 6f 72 65 20 69 74 2e 20 41 6c 73 6f 2c 20  gnore it. Also, 
3a40: 69 66 20 62 4f 6d 69 74 52 6f 77 69 64 0a 2a 2a  if bOmitRowid.**
3a50: 20 69 73 20 74 72 75 65 20 61 6e 64 20 6b 65 79   is true and key
3a60: 31 20 63 6f 6e 74 61 69 6e 73 20 65 76 65 6e 20  1 contains even 
3a70: 61 20 73 69 6e 67 6c 65 20 4e 55 4c 4c 20 76 61  a single NULL va
3a80: 6c 75 65 2c 20 69 74 20 69 73 20 63 6f 6e 73 69  lue, it is consi
3a90: 64 65 72 65 64 20 74 6f 0a 2a 2a 20 62 65 20 6c  dered to.** be l
3aa0: 65 73 73 20 74 68 61 6e 20 6b 65 79 32 2e 20 45  ess than key2. E
3ab0: 76 65 6e 20 69 66 20 6b 65 79 32 20 61 6c 73 6f  ven if key2 also
3ac0: 20 63 6f 6e 74 61 69 6e 73 20 4e 55 4c 4c 20 76   contains NULL v
3ad0: 61 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  alues..**.** If 
3ae0: 70 4b 65 79 32 20 69 73 20 70 61 73 73 65 64 20  pKey2 is passed 
3af0: 61 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2c 20  a NULL pointer, 
3b00: 74 68 65 6e 20 69 74 20 69 73 20 61 73 73 75 6d  then it is assum
3b10: 65 64 20 74 68 61 74 20 74 68 65 20 70 43 73 72  ed that the pCsr
3b20: 2d 3e 61 53 70 61 63 65 0a 2a 2a 20 68 61 73 20  ->aSpace.** has 
3b30: 62 65 65 6e 20 61 6c 6c 6f 63 61 74 65 64 20 61  been allocated a
3b40: 6e 64 20 63 6f 6e 74 61 69 6e 73 20 61 6e 20 75  nd contains an u
3b50: 6e 70 61 63 6b 65 64 20 72 65 63 6f 72 64 20 74  npacked record t
3b60: 68 61 74 20 69 73 20 75 73 65 64 20 61 73 20 6b  hat is used as k
3b70: 65 79 32 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ey2..*/.static v
3b80: 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72 43 6f  oid vdbeSorterCo
3b90: 6d 70 61 72 65 28 0a 20 20 63 6f 6e 73 74 20 56  mpare(.  const V
3ba0: 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c  dbeCursor *pCsr,
3bb0: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 73           /* Curs
3bc0: 6f 72 20 6f 62 6a 65 63 74 20 28 66 6f 72 20 70  or object (for p
3bd0: 4b 65 79 49 6e 66 6f 29 20 2a 2f 0a 20 20 69 6e  KeyInfo) */.  in
3be0: 74 20 6e 49 67 6e 6f 72 65 2c 20 20 20 20 20 20  t nIgnore,      
3bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3c00: 20 49 67 6e 6f 72 65 20 74 68 65 20 6c 61 73 74   Ignore the last
3c10: 20 6e 49 67 6e 6f 72 65 20 66 69 65 6c 64 73 20   nIgnore fields 
3c20: 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20  */.  const void 
3c30: 2a 70 4b 65 79 31 2c 20 69 6e 74 20 6e 4b 65 79  *pKey1, int nKey
3c40: 31 2c 20 20 20 2f 2a 20 4c 65 66 74 20 73 69 64  1,   /* Left sid
3c50: 65 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20  e of comparison 
3c60: 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20  */.  const void 
3c70: 2a 70 4b 65 79 32 2c 20 69 6e 74 20 6e 4b 65 79  *pKey2, int nKey
3c80: 32 2c 20 20 20 2f 2a 20 52 69 67 68 74 20 73 69  2,   /* Right si
3c90: 64 65 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e  de of comparison
3ca0: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 52 65 73 20   */.  int *pRes 
3cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3cc0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 52 65        /* OUT: Re
3cd0: 73 75 6c 74 20 6f 66 20 63 6f 6d 70 61 72 69 73  sult of comparis
3ce0: 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 4b 65 79 49 6e  on */.){.  KeyIn
3cf0: 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 20 3d 20 70  fo *pKeyInfo = p
3d00: 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 3b 0a 20  Csr->pKeyInfo;. 
3d10: 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f   VdbeSorter *pSo
3d20: 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f  rter = pCsr->pSo
3d30: 72 74 65 72 3b 0a 20 20 55 6e 70 61 63 6b 65 64  rter;.  Unpacked
3d40: 52 65 63 6f 72 64 20 2a 72 32 20 3d 20 70 53 6f  Record *r2 = pSo
3d50: 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64 3b  rter->pUnpacked;
3d60: 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 69 66 28  .  int i;..  if(
3d70: 20 70 4b 65 79 32 20 29 7b 0a 20 20 20 20 73 71   pKey2 ){.    sq
3d80: 6c 69 74 65 33 56 64 62 65 52 65 63 6f 72 64 55  lite3VdbeRecordU
3d90: 6e 70 61 63 6b 28 70 4b 65 79 49 6e 66 6f 2c 20  npack(pKeyInfo, 
3da0: 6e 4b 65 79 32 2c 20 70 4b 65 79 32 2c 20 72 32  nKey2, pKey2, r2
3db0: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6e 49  );.  }..  if( nI
3dc0: 67 6e 6f 72 65 20 29 7b 0a 20 20 20 20 72 32 2d  gnore ){.    r2-
3dd0: 3e 6e 46 69 65 6c 64 20 3d 20 70 4b 65 79 49 6e  >nField = pKeyIn
3de0: 66 6f 2d 3e 6e 46 69 65 6c 64 20 2d 20 6e 49 67  fo->nField - nIg
3df0: 6e 6f 72 65 3b 0a 20 20 20 20 61 73 73 65 72 74  nore;.    assert
3e00: 28 20 72 32 2d 3e 6e 46 69 65 6c 64 3e 30 20 29  ( r2->nField>0 )
3e10: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69  ;.    for(i=0; i
3e20: 3c 72 32 2d 3e 6e 46 69 65 6c 64 3b 20 69 2b 2b  <r2->nField; i++
3e30: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 72 32 2d  ){.      if( r2-
3e40: 3e 61 4d 65 6d 5b 69 5d 2e 66 6c 61 67 73 20 26  >aMem[i].flags &
3e50: 20 4d 45 4d 5f 4e 75 6c 6c 20 29 7b 0a 20 20 20   MEM_Null ){.   
3e60: 20 20 20 20 20 2a 70 52 65 73 20 3d 20 2d 31 3b       *pRes = -1;
3e70: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 3b  .        return;
3e80: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
3e90: 20 20 20 61 73 73 65 72 74 28 20 72 32 2d 3e 64     assert( r2->d
3ea0: 65 66 61 75 6c 74 5f 72 63 3d 3d 30 20 29 3b 0a  efault_rc==0 );.
3eb0: 20 20 7d 0a 0a 20 20 2a 70 52 65 73 20 3d 20 73    }..  *pRes = s
3ec0: 71 6c 69 74 65 33 56 64 62 65 52 65 63 6f 72 64  qlite3VdbeRecord
3ed0: 43 6f 6d 70 61 72 65 28 6e 4b 65 79 31 2c 20 70  Compare(nKey1, p
3ee0: 4b 65 79 31 2c 20 72 32 2c 20 30 29 3b 0a 7d 0a  Key1, r2, 0);.}.
3ef0: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
3f00: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74  tion is called t
3f10: 6f 20 63 6f 6d 70 61 72 65 20 74 77 6f 20 69 74  o compare two it
3f20: 65 72 61 74 6f 72 20 6b 65 79 73 20 77 68 65 6e  erator keys when
3f30: 20 6d 65 72 67 69 6e 67 20 0a 2a 2a 20 6d 75 6c   merging .** mul
3f40: 74 69 70 6c 65 20 62 2d 74 72 65 65 20 73 65 67  tiple b-tree seg
3f50: 6d 65 6e 74 73 2e 20 50 61 72 61 6d 65 74 65 72  ments. Parameter
3f60: 20 69 4f 75 74 20 69 73 20 74 68 65 20 69 6e 64   iOut is the ind
3f70: 65 78 20 6f 66 20 74 68 65 20 61 54 72 65 65 5b  ex of the aTree[
3f80: 5d 20 0a 2a 2a 20 76 61 6c 75 65 20 74 6f 20 72  ] .** value to r
3f90: 65 63 61 6c 63 75 6c 61 74 65 2e 0a 2a 2f 0a 73  ecalculate..*/.s
3fa0: 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53 6f  tatic int vdbeSo
3fb0: 72 74 65 72 44 6f 43 6f 6d 70 61 72 65 28 63 6f  rterDoCompare(co
3fc0: 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a  nst VdbeCursor *
3fd0: 70 43 73 72 2c 20 69 6e 74 20 69 4f 75 74 29 7b  pCsr, int iOut){
3fe0: 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70  .  VdbeSorter *p
3ff0: 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70  Sorter = pCsr->p
4000: 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 69 31  Sorter;.  int i1
4010: 3b 0a 20 20 69 6e 74 20 69 32 3b 0a 20 20 69 6e  ;.  int i2;.  in
4020: 74 20 69 52 65 73 3b 0a 20 20 56 64 62 65 53 6f  t iRes;.  VdbeSo
4030: 72 74 65 72 49 74 65 72 20 2a 70 31 3b 0a 20 20  rterIter *p1;.  
4040: 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a  VdbeSorterIter *
4050: 70 32 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 69  p2;..  assert( i
4060: 4f 75 74 3c 70 53 6f 72 74 65 72 2d 3e 6e 54 72  Out<pSorter->nTr
4070: 65 65 20 26 26 20 69 4f 75 74 3e 30 20 29 3b 0a  ee && iOut>0 );.
4080: 0a 20 20 69 66 28 20 69 4f 75 74 3e 3d 28 70 53  .  if( iOut>=(pS
4090: 6f 72 74 65 72 2d 3e 6e 54 72 65 65 2f 32 29 20  orter->nTree/2) 
40a0: 29 7b 0a 20 20 20 20 69 31 20 3d 20 28 69 4f 75  ){.    i1 = (iOu
40b0: 74 20 2d 20 70 53 6f 72 74 65 72 2d 3e 6e 54 72  t - pSorter->nTr
40c0: 65 65 2f 32 29 20 2a 20 32 3b 0a 20 20 20 20 69  ee/2) * 2;.    i
40d0: 32 20 3d 20 69 31 20 2b 20 31 3b 0a 20 20 7d 65  2 = i1 + 1;.  }e
40e0: 6c 73 65 7b 0a 20 20 20 20 69 31 20 3d 20 70 53  lse{.    i1 = pS
40f0: 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 69 4f 75  orter->aTree[iOu
4100: 74 2a 32 5d 3b 0a 20 20 20 20 69 32 20 3d 20 70  t*2];.    i2 = p
4110: 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 69 4f  Sorter->aTree[iO
4120: 75 74 2a 32 2b 31 5d 3b 0a 20 20 7d 0a 0a 20 20  ut*2+1];.  }..  
4130: 70 31 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61  p1 = &pSorter->a
4140: 49 74 65 72 5b 69 31 5d 3b 0a 20 20 70 32 20 3d  Iter[i1];.  p2 =
4150: 20 26 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72   &pSorter->aIter
4160: 5b 69 32 5d 3b 0a 0a 20 20 69 66 28 20 70 31 2d  [i2];..  if( p1-
4170: 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20  >pFile==0 ){.   
4180: 20 69 52 65 73 20 3d 20 69 32 3b 0a 20 20 7d 65   iRes = i2;.  }e
4190: 6c 73 65 20 69 66 28 20 70 32 2d 3e 70 46 69 6c  lse if( p2->pFil
41a0: 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 73  e==0 ){.    iRes
41b0: 20 3d 20 69 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a   = i1;.  }else{.
41c0: 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 20 20 20      int res;.   
41d0: 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e 70   assert( pCsr->p
41e0: 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65  Sorter->pUnpacke
41f0: 64 21 3d 30 20 29 3b 20 20 2f 2a 20 61 6c 6c 6f  d!=0 );  /* allo
4200: 63 61 74 65 64 20 69 6e 20 76 64 62 65 53 6f 72  cated in vdbeSor
4210: 74 65 72 4d 65 72 67 65 28 29 20 2a 2f 0a 20 20  terMerge() */.  
4220: 20 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70    vdbeSorterComp
4230: 61 72 65 28 0a 20 20 20 20 20 20 20 20 70 43 73  are(.        pCs
4240: 72 2c 20 30 2c 20 70 31 2d 3e 61 4b 65 79 2c 20  r, 0, p1->aKey, 
4250: 70 31 2d 3e 6e 4b 65 79 2c 20 70 32 2d 3e 61 4b  p1->nKey, p2->aK
4260: 65 79 2c 20 70 32 2d 3e 6e 4b 65 79 2c 20 26 72  ey, p2->nKey, &r
4270: 65 73 0a 20 20 20 20 29 3b 0a 20 20 20 20 69 66  es.    );.    if
4280: 28 20 72 65 73 3c 3d 30 20 29 7b 0a 20 20 20 20  ( res<=0 ){.    
4290: 20 20 69 52 65 73 20 3d 20 69 31 3b 0a 20 20 20    iRes = i1;.   
42a0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 52   }else{.      iR
42b0: 65 73 20 3d 20 69 32 3b 0a 20 20 20 20 7d 0a 20  es = i2;.    }. 
42c0: 20 7d 0a 0a 20 20 70 53 6f 72 74 65 72 2d 3e 61   }..  pSorter->a
42d0: 54 72 65 65 5b 69 4f 75 74 5d 20 3d 20 69 52 65  Tree[iOut] = iRe
42e0: 73 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  s;.  return SQLI
42f0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
4300: 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 74  Initialize the t
4310: 65 6d 70 6f 72 61 72 79 20 69 6e 64 65 78 20 63  emporary index c
4320: 75 72 73 6f 72 20 6a 75 73 74 20 6f 70 65 6e 65  ursor just opene
4330: 64 20 61 73 20 61 20 73 6f 72 74 65 72 20 63 75  d as a sorter cu
4340: 72 73 6f 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  rsor..*/.int sql
4350: 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 49 6e  ite3VdbeSorterIn
4360: 69 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  it(sqlite3 *db, 
4370: 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72  VdbeCursor *pCsr
4380: 29 7b 0a 20 20 69 6e 74 20 70 67 73 7a 3b 20 20  ){.  int pgsz;  
4390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
43a0: 20 20 20 20 20 2f 2a 20 50 61 67 65 20 73 69 7a       /* Page siz
43b0: 65 20 6f 66 20 6d 61 69 6e 20 64 61 74 61 62 61  e of main databa
43c0: 73 65 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 43 61  se */.  int mxCa
43d0: 63 68 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  che;            
43e0: 20 20 20 20 20 20 20 20 2f 2a 20 43 61 63 68 65          /* Cache
43f0: 20 73 69 7a 65 20 2a 2f 0a 20 20 56 64 62 65 53   size */.  VdbeS
4400: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 3b 20  orter *pSorter; 
4410: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
4420: 65 20 6e 65 77 20 73 6f 72 74 65 72 20 2a 2f 0a  e new sorter */.
4430: 20 20 63 68 61 72 20 2a 64 3b 20 20 20 20 20 20    char *d;      
4440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4450: 20 20 2f 2a 20 44 75 6d 6d 79 20 2a 2f 0a 0a 20    /* Dummy */.. 
4460: 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e 70   assert( pCsr->p
4470: 4b 65 79 49 6e 66 6f 20 26 26 20 70 43 73 72 2d  KeyInfo && pCsr-
4480: 3e 70 42 74 3d 3d 30 20 29 3b 0a 20 20 70 43 73  >pBt==0 );.  pCs
4490: 72 2d 3e 70 53 6f 72 74 65 72 20 3d 20 70 53 6f  r->pSorter = pSo
44a0: 72 74 65 72 20 3d 20 73 71 6c 69 74 65 33 44 62  rter = sqlite3Db
44b0: 4d 61 6c 6c 6f 63 5a 65 72 6f 28 64 62 2c 20 73  MallocZero(db, s
44c0: 69 7a 65 6f 66 28 56 64 62 65 53 6f 72 74 65 72  izeof(VdbeSorter
44d0: 29 29 3b 0a 20 20 69 66 28 20 70 53 6f 72 74 65  ));.  if( pSorte
44e0: 72 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  r==0 ){.    retu
44f0: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
4500: 0a 20 20 7d 0a 20 20 0a 20 20 70 53 6f 72 74 65  .  }.  .  pSorte
4510: 72 2d 3e 70 55 6e 70 61 63 6b 65 64 20 3d 20 73  r->pUnpacked = s
4520: 71 6c 69 74 65 33 56 64 62 65 41 6c 6c 6f 63 55  qlite3VdbeAllocU
4530: 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 28 70 43  npackedRecord(pC
4540: 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20 30 2c  sr->pKeyInfo, 0,
4550: 20 30 2c 20 26 64 29 3b 0a 20 20 69 66 28 20 70   0, &d);.  if( p
4560: 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65  Sorter->pUnpacke
4570: 64 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  d==0 ) return SQ
4580: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 61 73  LITE_NOMEM;.  as
4590: 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 70  sert( pSorter->p
45a0: 55 6e 70 61 63 6b 65 64 3d 3d 28 55 6e 70 61 63  Unpacked==(Unpac
45b0: 6b 65 64 52 65 63 6f 72 64 20 2a 29 64 20 29 3b  kedRecord *)d );
45c0: 0a 20 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70  .  pSorter->pUnp
45d0: 61 63 6b 65 64 2d 3e 6e 46 69 65 6c 64 20 3d 20  acked->nField = 
45e0: 70 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2d 3e  pCsr->pKeyInfo->
45f0: 6e 46 69 65 6c 64 3b 0a 0a 20 20 69 66 28 20 21  nField;..  if( !
4600: 73 71 6c 69 74 65 33 54 65 6d 70 49 6e 4d 65 6d  sqlite3TempInMem
4610: 6f 72 79 28 64 62 29 20 29 7b 0a 20 20 20 20 70  ory(db) ){.    p
4620: 67 73 7a 20 3d 20 73 71 6c 69 74 65 33 42 74 72  gsz = sqlite3Btr
4630: 65 65 47 65 74 50 61 67 65 53 69 7a 65 28 64 62  eeGetPageSize(db
4640: 2d 3e 61 44 62 5b 30 5d 2e 70 42 74 29 3b 0a 20  ->aDb[0].pBt);. 
4650: 20 20 20 70 53 6f 72 74 65 72 2d 3e 6d 6e 50 6d     pSorter->mnPm
4660: 61 53 69 7a 65 20 3d 20 53 4f 52 54 45 52 5f 4d  aSize = SORTER_M
4670: 49 4e 5f 57 4f 52 4b 49 4e 47 20 2a 20 70 67 73  IN_WORKING * pgs
4680: 7a 3b 0a 20 20 20 20 6d 78 43 61 63 68 65 20 3d  z;.    mxCache =
4690: 20 64 62 2d 3e 61 44 62 5b 30 5d 2e 70 53 63 68   db->aDb[0].pSch
46a0: 65 6d 61 2d 3e 63 61 63 68 65 5f 73 69 7a 65 3b  ema->cache_size;
46b0: 0a 20 20 20 20 69 66 28 20 6d 78 43 61 63 68 65  .    if( mxCache
46c0: 3c 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b  <SORTER_MIN_WORK
46d0: 49 4e 47 20 29 20 6d 78 43 61 63 68 65 20 3d 20  ING ) mxCache = 
46e0: 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52 4b 49  SORTER_MIN_WORKI
46f0: 4e 47 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d  NG;.    pSorter-
4700: 3e 6d 78 50 6d 61 53 69 7a 65 20 3d 20 6d 78 43  >mxPmaSize = mxC
4710: 61 63 68 65 20 2a 20 70 67 73 7a 3b 0a 0a 20 20  ache * pgsz;..  
4720: 20 20 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f    pSorter->aMemo
4730: 72 79 20 3d 20 28 75 38 2a 29 73 71 6c 69 74 65  ry = (u8*)sqlite
4740: 33 44 62 4d 61 6c 6c 6f 63 52 61 77 28 64 62 2c  3DbMallocRaw(db,
4750: 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53   pSorter->mxPmaS
4760: 69 7a 65 29 3b 0a 20 20 20 20 61 73 73 65 72 74  ize);.    assert
4770: 28 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f  ( pSorter->iMemo
4780: 72 79 3d 3d 30 20 29 3b 0a 20 20 20 20 69 66 28  ry==0 );.    if(
4790: 20 21 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f   !pSorter->aMemo
47a0: 72 79 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  ry ) return SQLI
47b0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20  TE_NOMEM;.  }.. 
47c0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
47d0: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65  K;.}../*.** Free
47e0: 20 74 68 65 20 6c 69 73 74 20 6f 66 20 73 6f 72   the list of sor
47f0: 74 65 64 20 72 65 63 6f 72 64 73 20 73 74 61 72  ted records star
4800: 74 69 6e 67 20 61 74 20 70 52 65 63 6f 72 64 2e  ting at pRecord.
4810: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
4820: 76 64 62 65 53 6f 72 74 65 72 52 65 63 6f 72 64  vdbeSorterRecord
4830: 46 72 65 65 28 73 71 6c 69 74 65 33 20 2a 64 62  Free(sqlite3 *db
4840: 2c 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a  , SorterRecord *
4850: 70 52 65 63 6f 72 64 29 7b 0a 20 20 53 6f 72 74  pRecord){.  Sort
4860: 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a 20 20 53  erRecord *p;.  S
4870: 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65  orterRecord *pNe
4880: 78 74 3b 0a 20 20 66 6f 72 28 70 3d 70 52 65 63  xt;.  for(p=pRec
4890: 6f 72 64 3b 20 70 3b 20 70 3d 70 4e 65 78 74 29  ord; p; p=pNext)
48a0: 7b 0a 20 20 20 20 70 4e 65 78 74 20 3d 20 70 2d  {.    pNext = p-
48b0: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 73 71 6c 69  >pNext;.    sqli
48c0: 74 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 29  te3DbFree(db, p)
48d0: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  ;.  }.}../*.** R
48e0: 65 73 65 74 20 61 20 73 6f 72 74 69 6e 67 20 63  eset a sorting c
48f0: 75 72 73 6f 72 20 62 61 63 6b 20 74 6f 20 69 74  ursor back to it
4900: 73 20 6f 72 69 67 69 6e 61 6c 20 65 6d 70 74 79  s original empty
4910: 20 73 74 61 74 65 2e 0a 2a 2f 0a 76 6f 69 64 20   state..*/.void 
4920: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
4930: 72 52 65 73 65 74 28 73 71 6c 69 74 65 33 20 2a  rReset(sqlite3 *
4940: 64 62 2c 20 56 64 62 65 53 6f 72 74 65 72 20 2a  db, VdbeSorter *
4950: 70 53 6f 72 74 65 72 29 7b 0a 20 20 69 66 28 20  pSorter){.  if( 
4960: 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 20 29  pSorter->aIter )
4970: 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20  {.    int i;.   
4980: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 53 6f 72   for(i=0; i<pSor
4990: 74 65 72 2d 3e 6e 54 72 65 65 3b 20 69 2b 2b 29  ter->nTree; i++)
49a0: 7b 0a 20 20 20 20 20 20 76 64 62 65 53 6f 72 74  {.      vdbeSort
49b0: 65 72 49 74 65 72 5a 65 72 6f 28 64 62 2c 20 26  erIterZero(db, &
49c0: 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b 69  pSorter->aIter[i
49d0: 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71  ]);.    }.    sq
49e0: 6c 69 74 65 33 44 62 46 72 65 65 28 64 62 2c 20  lite3DbFree(db, 
49f0: 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 29 3b  pSorter->aIter);
4a00: 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 61 49  .    pSorter->aI
4a10: 74 65 72 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 69  ter = 0;.  }.  i
4a20: 66 28 20 70 53 6f 72 74 65 72 2d 3e 70 54 65 6d  f( pSorter->pTem
4a30: 70 31 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  p1 ){.    sqlite
4a40: 33 4f 73 43 6c 6f 73 65 46 72 65 65 28 70 53 6f  3OsCloseFree(pSo
4a50: 72 74 65 72 2d 3e 70 54 65 6d 70 31 29 3b 0a 20  rter->pTemp1);. 
4a60: 20 20 20 70 53 6f 72 74 65 72 2d 3e 70 54 65 6d     pSorter->pTem
4a70: 70 31 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 69 66  p1 = 0;.  }.  if
4a80: 28 20 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f  ( pSorter->aMemo
4a90: 72 79 3d 3d 30 20 29 7b 0a 20 20 20 20 76 64 62  ry==0 ){.    vdb
4aa0: 65 53 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65  eSorterRecordFre
4ab0: 65 28 64 62 2c 20 70 53 6f 72 74 65 72 2d 3e 70  e(db, pSorter->p
4ac0: 52 65 63 6f 72 64 29 3b 0a 20 20 7d 0a 20 20 70  Record);.  }.  p
4ad0: 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 20  Sorter->pRecord 
4ae0: 3d 20 30 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e  = 0;.  pSorter->
4af0: 69 57 72 69 74 65 4f 66 66 20 3d 20 30 3b 0a 20  iWriteOff = 0;. 
4b00: 20 70 53 6f 72 74 65 72 2d 3e 69 52 65 61 64 4f   pSorter->iReadO
4b10: 66 66 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74 65  ff = 0;.  pSorte
4b20: 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20 3d 20 30  r->nInMemory = 0
4b30: 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6e 54 72  ;.  pSorter->nTr
4b40: 65 65 20 3d 20 30 3b 0a 20 20 70 53 6f 72 74 65  ee = 0;.  pSorte
4b50: 72 2d 3e 6e 50 4d 41 20 3d 20 30 3b 0a 20 20 70  r->nPMA = 0;.  p
4b60: 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 20 3d 20  Sorter->aTree = 
4b70: 30 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 69 4d  0;.  pSorter->iM
4b80: 65 6d 6f 72 79 20 3d 20 30 3b 0a 7d 0a 0a 0a 2f  emory = 0;.}.../
4b90: 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 79 20 63 75  *.** Free any cu
4ba0: 72 73 6f 72 20 63 6f 6d 70 6f 6e 65 6e 74 73 20  rsor components 
4bb0: 61 6c 6c 6f 63 61 74 65 64 20 62 79 20 73 71 6c  allocated by sql
4bc0: 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 58 58  ite3VdbeSorterXX
4bd0: 58 20 72 6f 75 74 69 6e 65 73 2e 0a 2a 2f 0a 76  X routines..*/.v
4be0: 6f 69 64 20 73 71 6c 69 74 65 33 56 64 62 65 53  oid sqlite3VdbeS
4bf0: 6f 72 74 65 72 43 6c 6f 73 65 28 73 71 6c 69 74  orterClose(sqlit
4c00: 65 33 20 2a 64 62 2c 20 56 64 62 65 43 75 72 73  e3 *db, VdbeCurs
4c10: 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 56 64 62  or *pCsr){.  Vdb
4c20: 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72  eSorter *pSorter
4c30: 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72   = pCsr->pSorter
4c40: 3b 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72 20  ;.  if( pSorter 
4c50: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 56 64  ){.    sqlite3Vd
4c60: 62 65 53 6f 72 74 65 72 52 65 73 65 74 28 64 62  beSorterReset(db
4c70: 2c 20 70 53 6f 72 74 65 72 29 3b 0a 20 20 20 20  , pSorter);.    
4c80: 73 71 6c 69 74 65 33 44 62 46 72 65 65 28 64 62  sqlite3DbFree(db
4c90: 2c 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61  , pSorter->pUnpa
4ca0: 63 6b 65 64 29 3b 0a 20 20 20 20 73 71 6c 69 74  cked);.    sqlit
4cb0: 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 53 6f  e3DbFree(db, pSo
4cc0: 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 29 3b 0a  rter->aMemory);.
4cd0: 20 20 20 20 73 71 6c 69 74 65 33 44 62 46 72 65      sqlite3DbFre
4ce0: 65 28 64 62 2c 20 70 53 6f 72 74 65 72 29 3b 0a  e(db, pSorter);.
4cf0: 20 20 20 20 70 43 73 72 2d 3e 70 53 6f 72 74 65      pCsr->pSorte
4d00: 72 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  r = 0;.  }.}../*
4d10: 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 73 70 61  .** Allocate spa
4d20: 63 65 20 66 6f 72 20 61 20 66 69 6c 65 2d 68 61  ce for a file-ha
4d30: 6e 64 6c 65 20 61 6e 64 20 6f 70 65 6e 20 61 20  ndle and open a 
4d40: 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 2e 20  temporary file. 
4d50: 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 0a 2a  If successful,.*
4d60: 2a 20 73 65 74 20 2a 70 70 46 69 6c 65 20 74 6f  * set *ppFile to
4d70: 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 6d 61   point to the ma
4d80: 6c 6c 6f 63 27 64 20 66 69 6c 65 2d 68 61 6e 64  lloc'd file-hand
4d90: 6c 65 20 61 6e 64 20 72 65 74 75 72 6e 20 53 51  le and return SQ
4da0: 4c 49 54 45 5f 4f 4b 2e 0a 2a 2a 20 4f 74 68 65  LITE_OK..** Othe
4db0: 72 77 69 73 65 2c 20 73 65 74 20 2a 70 70 46 69  rwise, set *ppFi
4dc0: 6c 65 20 74 6f 20 30 20 61 6e 64 20 72 65 74 75  le to 0 and retu
4dd0: 72 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  rn an SQLite err
4de0: 6f 72 20 63 6f 64 65 2e 0a 2a 2f 0a 73 74 61 74  or code..*/.stat
4df0: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
4e00: 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65 28 73 71  rOpenTempFile(sq
4e10: 6c 69 74 65 33 20 2a 64 62 2c 20 73 71 6c 69 74  lite3 *db, sqlit
4e20: 65 33 5f 66 69 6c 65 20 2a 2a 70 70 46 69 6c 65  e3_file **ppFile
4e30: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 72  ){.  int rc;.  r
4e40: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 4f 70 65  c = sqlite3OsOpe
4e50: 6e 4d 61 6c 6c 6f 63 28 64 62 2d 3e 70 56 66 73  nMalloc(db->pVfs
4e60: 2c 20 30 2c 20 70 70 46 69 6c 65 2c 0a 20 20 20  , 0, ppFile,.   
4e70: 20 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 54     SQLITE_OPEN_T
4e80: 45 4d 50 5f 4a 4f 55 52 4e 41 4c 20 7c 0a 20 20  EMP_JOURNAL |.  
4e90: 20 20 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f      SQLITE_OPEN_
4ea0: 52 45 41 44 57 52 49 54 45 20 20 20 20 7c 20 53  READWRITE    | S
4eb0: 51 4c 49 54 45 5f 4f 50 45 4e 5f 43 52 45 41 54  QLITE_OPEN_CREAT
4ec0: 45 20 7c 0a 20 20 20 20 20 20 53 51 4c 49 54 45  E |.      SQLITE
4ed0: 5f 4f 50 45 4e 5f 45 58 43 4c 55 53 49 56 45 20  _OPEN_EXCLUSIVE 
4ee0: 20 20 20 7c 20 53 51 4c 49 54 45 5f 4f 50 45 4e     | SQLITE_OPEN
4ef0: 5f 44 45 4c 45 54 45 4f 4e 43 4c 4f 53 45 2c 20  _DELETEONCLOSE, 
4f00: 26 72 63 0a 20 20 29 3b 0a 20 20 69 66 28 20 72  &rc.  );.  if( r
4f10: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
4f20: 20 20 20 20 69 36 34 20 6d 61 78 20 3d 20 53 51      i64 max = SQ
4f30: 4c 49 54 45 5f 4d 41 58 5f 4d 4d 41 50 5f 53 49  LITE_MAX_MMAP_SI
4f40: 5a 45 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f  ZE;.    sqlite3O
4f50: 73 46 69 6c 65 43 6f 6e 74 72 6f 6c 48 69 6e 74  sFileControlHint
4f60: 28 20 2a 70 70 46 69 6c 65 2c 20 53 51 4c 49 54  ( *ppFile, SQLIT
4f70: 45 5f 46 43 4e 54 4c 5f 4d 4d 41 50 5f 53 49 5a  E_FCNTL_MMAP_SIZ
4f80: 45 2c 20 28 76 6f 69 64 2a 29 26 6d 61 78 29 3b  E, (void*)&max);
4f90: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
4fa0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 65 72 67 65  ;.}../*.** Merge
4fb0: 20 74 68 65 20 74 77 6f 20 73 6f 72 74 65 64 20   the two sorted 
4fc0: 6c 69 73 74 73 20 70 31 20 61 6e 64 20 70 32 20  lists p1 and p2 
4fd0: 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65 20 6c 69  into a single li
4fe0: 73 74 2e 0a 2a 2a 20 53 65 74 20 2a 70 70 4f 75  st..** Set *ppOu
4ff0: 74 20 74 6f 20 74 68 65 20 68 65 61 64 20 6f 66  t to the head of
5000: 20 74 68 65 20 6e 65 77 20 6c 69 73 74 2e 0a 2a   the new list..*
5010: 2a 0a 2a 2a 20 49 6e 20 63 61 73 65 73 20 77 68  *.** In cases wh
5020: 65 72 65 20 6b 65 79 20 76 61 6c 75 65 73 20 61  ere key values a
5030: 72 65 20 65 71 75 61 6c 2c 20 6b 65 79 73 20 66  re equal, keys f
5040: 72 6f 6d 20 6c 69 73 74 20 70 31 20 61 72 65 20  rom list p1 are 
5050: 63 6f 6e 73 69 64 65 72 65 64 0a 2a 2a 20 74 6f  considered.** to
5060: 20 62 65 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e   be smaller than
5070: 20 6c 69 73 74 20 70 32 2e 0a 2a 2f 0a 73 74 61   list p2..*/.sta
5080: 74 69 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72  tic void vdbeSor
5090: 74 65 72 4d 65 72 67 65 28 0a 20 20 63 6f 6e 73  terMerge(.  cons
50a0: 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43  t VdbeCursor *pC
50b0: 73 72 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 46  sr,         /* F
50c0: 6f 72 20 70 4b 65 79 49 6e 66 6f 20 2a 2f 0a 20  or pKeyInfo */. 
50d0: 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70   SorterRecord *p
50e0: 31 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  1,              
50f0: 20 2f 2a 20 46 69 72 73 74 20 6c 69 73 74 20 74   /* First list t
5100: 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20 53 6f 72  o merge */.  Sor
5110: 74 65 72 52 65 63 6f 72 64 20 2a 70 32 2c 20 20  terRecord *p2,  
5120: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5130: 53 65 63 6f 6e 64 20 6c 69 73 74 20 74 6f 20 6d  Second list to m
5140: 65 72 67 65 20 2a 2f 0a 20 20 53 6f 72 74 65 72  erge */.  Sorter
5150: 52 65 63 6f 72 64 20 2a 2a 70 70 4f 75 74 20 20  Record **ppOut  
5160: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
5170: 3a 20 48 65 61 64 20 6f 66 20 6d 65 72 67 65 64  : Head of merged
5180: 20 6c 69 73 74 20 2a 2f 0a 29 7b 0a 20 20 53 6f   list */.){.  So
5190: 72 74 65 72 52 65 63 6f 72 64 20 2a 70 46 69 6e  rterRecord *pFin
51a0: 61 6c 20 3d 20 30 3b 0a 20 20 53 6f 72 74 65 72  al = 0;.  Sorter
51b0: 52 65 63 6f 72 64 20 2a 2a 70 70 20 3d 20 26 70  Record **pp = &p
51c0: 46 69 6e 61 6c 3b 0a 20 20 76 6f 69 64 20 2a 70  Final;.  void *p
51d0: 56 61 6c 32 20 3d 20 70 32 20 3f 20 70 32 2d 3e  Val2 = p2 ? p2->
51e0: 70 56 61 6c 20 3a 20 30 3b 0a 0a 20 20 77 68 69  pVal : 0;..  whi
51f0: 6c 65 28 20 70 31 20 26 26 20 70 32 20 29 7b 0a  le( p1 && p2 ){.
5200: 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 20 20 20      int res;.   
5210: 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61   vdbeSorterCompa
5220: 72 65 28 70 43 73 72 2c 20 30 2c 20 70 31 2d 3e  re(pCsr, 0, p1->
5230: 70 56 61 6c 2c 20 70 31 2d 3e 6e 56 61 6c 2c 20  pVal, p1->nVal, 
5240: 70 56 61 6c 32 2c 20 70 32 2d 3e 6e 56 61 6c 2c  pVal2, p2->nVal,
5250: 20 26 72 65 73 29 3b 0a 20 20 20 20 69 66 28 20   &res);.    if( 
5260: 72 65 73 3c 3d 30 20 29 7b 0a 20 20 20 20 20 20  res<=0 ){.      
5270: 2a 70 70 20 3d 20 70 31 3b 0a 20 20 20 20 20 20  *pp = p1;.      
5280: 70 70 20 3d 20 26 70 31 2d 3e 70 4e 65 78 74 3b  pp = &p1->pNext;
5290: 0a 20 20 20 20 20 20 70 31 20 3d 20 70 31 2d 3e  .      p1 = p1->
52a0: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 56 61  pNext;.      pVa
52b0: 6c 32 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73  l2 = 0;.    }els
52c0: 65 7b 0a 20 20 20 20 20 20 2a 70 70 20 3d 20 70  e{.      *pp = p
52d0: 32 3b 0a 20 20 20 20 20 20 20 70 70 20 3d 20 26  2;.       pp = &
52e0: 70 32 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20  p2->pNext;.     
52f0: 20 70 32 20 3d 20 70 32 2d 3e 70 4e 65 78 74 3b   p2 = p2->pNext;
5300: 0a 20 20 20 20 20 20 69 66 28 20 70 32 3d 3d 30  .      if( p2==0
5310: 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20   ) break;.      
5320: 70 56 61 6c 32 20 3d 20 70 32 2d 3e 70 56 61 6c  pVal2 = p2->pVal
5330: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70  ;.    }.  }.  *p
5340: 70 20 3d 20 70 31 20 3f 20 70 31 20 3a 20 70 32  p = p1 ? p1 : p2
5350: 3b 0a 20 20 2a 70 70 4f 75 74 20 3d 20 70 46 69  ;.  *ppOut = pFi
5360: 6e 61 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f  nal;.}../*.** So
5370: 72 74 20 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69  rt the linked li
5380: 73 74 20 6f 66 20 72 65 63 6f 72 64 73 20 68 65  st of records he
5390: 61 64 65 64 20 61 74 20 70 43 73 72 2d 3e 70 52  aded at pCsr->pR
53a0: 65 63 6f 72 64 2e 20 52 65 74 75 72 6e 20 53 51  ecord. Return SQ
53b0: 4c 49 54 45 5f 4f 4b 0a 2a 2a 20 69 66 20 73 75  LITE_OK.** if su
53c0: 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20  ccessful, or an 
53d0: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
53e0: 65 20 28 69 2e 65 2e 20 53 51 4c 49 54 45 5f 4e  e (i.e. SQLITE_N
53f0: 4f 4d 45 4d 29 20 69 66 20 61 6e 20 65 72 72 6f  OMEM) if an erro
5400: 72 0a 2a 2a 20 6f 63 63 75 72 73 2e 0a 2a 2a 0a  r.** occurs..**.
5410: 2a 2a 20 54 68 65 20 73 6f 72 74 20 69 73 20 72  ** The sort is r
5420: 65 71 75 69 72 65 64 20 74 6f 20 62 65 20 73 74  equired to be st
5430: 61 62 6c 65 20 2d 20 69 66 20 74 77 6f 20 65 6c  able - if two el
5440: 65 6d 65 6e 74 73 20 63 6f 6d 70 61 72 65 20 61  ements compare a
5450: 73 20 65 71 75 61 6c 0a 2a 2a 20 74 68 65 6e 20  s equal.** then 
5460: 74 68 65 20 6f 6e 65 20 61 64 64 65 64 20 74 6f  the one added to
5470: 20 74 68 65 20 73 6f 72 74 65 72 20 66 69 72 73   the sorter firs
5480: 74 20 69 73 20 63 6f 6e 73 69 64 65 72 65 64 20  t is considered 
5490: 74 68 65 20 73 6d 61 6c 6c 65 72 2e 0a 2a 2a 20  the smaller..** 
54a0: 43 75 72 72 65 6e 74 6c 79 2c 20 74 68 65 20 6c  Currently, the l
54b0: 69 73 74 20 69 73 20 73 6f 72 74 65 64 20 66 72  ist is sorted fr
54c0: 6f 6d 20 6e 65 77 65 73 74 20 74 6f 20 6f 6c 64  om newest to old
54d0: 65 73 74 20 2d 20 70 53 6f 72 74 65 72 2d 3e 70  est - pSorter->p
54e0: 52 65 63 6f 72 64 0a 2a 2a 20 70 6f 69 6e 74 73  Record.** points
54f0: 20 74 6f 20 74 68 65 20 6d 6f 73 74 20 72 65 63   to the most rec
5500: 65 6e 74 6c 79 20 61 64 64 65 64 20 73 6f 72 74  ently added sort
5510: 20 6b 65 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20   key..*/.static 
5520: 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72 53 6f  int vdbeSorterSo
5530: 72 74 28 63 6f 6e 73 74 20 56 64 62 65 43 75 72  rt(const VdbeCur
5540: 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 69 6e  sor *pCsr){.  in
5550: 74 20 69 3b 0a 20 20 53 6f 72 74 65 72 52 65 63  t i;.  SorterRec
5560: 6f 72 64 20 2a 2a 61 53 6c 6f 74 3b 0a 20 20 53  ord **aSlot;.  S
5570: 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a  orterRecord *p;.
5580: 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
5590: 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53  orter = pCsr->pS
55a0: 6f 72 74 65 72 3b 0a 0a 20 20 61 53 6c 6f 74 20  orter;..  aSlot 
55b0: 3d 20 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20  = (SorterRecord 
55c0: 2a 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  **)sqlite3Malloc
55d0: 5a 65 72 6f 28 36 34 20 2a 20 73 69 7a 65 6f 66  Zero(64 * sizeof
55e0: 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 29  (SorterRecord *)
55f0: 29 3b 0a 20 20 69 66 28 20 21 61 53 6c 6f 74 20  );.  if( !aSlot 
5600: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
5610: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a  LITE_NOMEM;.  }.
5620: 0a 20 20 70 20 3d 20 70 53 6f 72 74 65 72 2d 3e  .  p = pSorter->
5630: 70 52 65 63 6f 72 64 3b 0a 20 20 77 68 69 6c 65  pRecord;.  while
5640: 28 20 70 20 29 7b 0a 20 20 20 20 53 6f 72 74 65  ( p ){.    Sorte
5650: 72 52 65 63 6f 72 64 20 2a 70 4e 65 78 74 20 3d  rRecord *pNext =
5660: 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 70   p->pNext;.    p
5670: 2d 3e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20  ->pNext = 0;.   
5680: 20 66 6f 72 28 69 3d 30 3b 20 61 53 6c 6f 74 5b   for(i=0; aSlot[
5690: 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  i]; i++){.      
56a0: 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28  vdbeSorterMerge(
56b0: 70 43 73 72 2c 20 70 2c 20 61 53 6c 6f 74 5b 69  pCsr, p, aSlot[i
56c0: 5d 2c 20 26 70 29 3b 0a 20 20 20 20 20 20 61 53  ], &p);.      aS
56d0: 6c 6f 74 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20  lot[i] = 0;.    
56e0: 7d 0a 20 20 20 20 61 53 6c 6f 74 5b 69 5d 20 3d  }.    aSlot[i] =
56f0: 20 70 3b 0a 20 20 20 20 70 20 3d 20 70 4e 65 78   p;.    p = pNex
5700: 74 3b 0a 20 20 7d 0a 0a 20 20 70 20 3d 20 30 3b  t;.  }..  p = 0;
5710: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 36 34  .  for(i=0; i<64
5720: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 76 64 62 65  ; i++){.    vdbe
5730: 53 6f 72 74 65 72 4d 65 72 67 65 28 70 43 73 72  SorterMerge(pCsr
5740: 2c 20 70 2c 20 61 53 6c 6f 74 5b 69 5d 2c 20 26  , p, aSlot[i], &
5750: 70 29 3b 0a 20 20 7d 0a 20 20 70 53 6f 72 74 65  p);.  }.  pSorte
5760: 72 2d 3e 70 52 65 63 6f 72 64 20 3d 20 70 3b 0a  r->pRecord = p;.
5770: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
5780: 61 53 6c 6f 74 29 3b 0a 20 20 72 65 74 75 72 6e  aSlot);.  return
5790: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
57a0: 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20  *.** Initialize 
57b0: 61 20 66 69 6c 65 2d 77 72 69 74 65 72 20 6f 62  a file-writer ob
57c0: 6a 65 63 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ject..*/.static 
57d0: 76 6f 69 64 20 66 69 6c 65 57 72 69 74 65 72 49  void fileWriterI
57e0: 6e 69 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a  nit(.  sqlite3 *
57f0: 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  db,             
5800: 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61         /* Databa
5810: 73 65 20 28 66 6f 72 20 6d 61 6c 6c 6f 63 29 20  se (for malloc) 
5820: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  */.  sqlite3_fil
5830: 65 20 2a 70 46 69 6c 65 2c 20 20 20 20 20 20 20  e *pFile,       
5840: 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 74 6f 20       /* File to 
5850: 77 72 69 74 65 20 74 6f 20 2a 2f 0a 20 20 46 69  write to */.  Fi
5860: 6c 65 57 72 69 74 65 72 20 2a 70 2c 20 20 20 20  leWriter *p,    
5870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5880: 20 4f 62 6a 65 63 74 20 74 6f 20 70 6f 70 75 6c   Object to popul
5890: 61 74 65 20 2a 2f 0a 20 20 69 36 34 20 69 53 74  ate */.  i64 iSt
58a0: 61 72 74 20 20 20 20 20 20 20 20 20 20 20 20 20  art             
58b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73           /* Offs
58c0: 65 74 20 6f 66 20 70 46 69 6c 65 20 74 6f 20 62  et of pFile to b
58d0: 65 67 69 6e 20 77 72 69 74 69 6e 67 20 61 74 20  egin writing at 
58e0: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e 42 75 66  */.){.  int nBuf
58f0: 20 3d 20 73 71 6c 69 74 65 33 42 74 72 65 65 47   = sqlite3BtreeG
5900: 65 74 50 61 67 65 53 69 7a 65 28 64 62 2d 3e 61  etPageSize(db->a
5910: 44 62 5b 30 5d 2e 70 42 74 29 3b 0a 0a 20 20 6d  Db[0].pBt);..  m
5920: 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65  emset(p, 0, size
5930: 6f 66 28 46 69 6c 65 57 72 69 74 65 72 29 29 3b  of(FileWriter));
5940: 0a 20 20 70 2d 3e 61 42 75 66 66 65 72 20 3d 20  .  p->aBuffer = 
5950: 28 75 38 20 2a 29 73 71 6c 69 74 65 33 44 62 4d  (u8 *)sqlite3DbM
5960: 61 6c 6c 6f 63 52 61 77 28 64 62 2c 20 6e 42 75  allocRaw(db, nBu
5970: 66 29 3b 0a 20 20 69 66 28 20 21 70 2d 3e 61 42  f);.  if( !p->aB
5980: 75 66 66 65 72 20 29 7b 0a 20 20 20 20 70 2d 3e  uffer ){.    p->
5990: 65 46 57 45 72 72 20 3d 20 53 51 4c 49 54 45 5f  eFWErr = SQLITE_
59a0: 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a  NOMEM;.  }else{.
59b0: 20 20 20 20 70 2d 3e 69 42 75 66 45 6e 64 20 3d      p->iBufEnd =
59c0: 20 70 2d 3e 69 42 75 66 53 74 61 72 74 20 3d 20   p->iBufStart = 
59d0: 28 69 53 74 61 72 74 20 25 20 6e 42 75 66 29 3b  (iStart % nBuf);
59e0: 0a 20 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66  .    p->iWriteOf
59f0: 66 20 3d 20 69 53 74 61 72 74 20 2d 20 70 2d 3e  f = iStart - p->
5a00: 69 42 75 66 53 74 61 72 74 3b 0a 20 20 20 20 70  iBufStart;.    p
5a10: 2d 3e 6e 42 75 66 66 65 72 20 3d 20 6e 42 75 66  ->nBuffer = nBuf
5a20: 3b 0a 20 20 20 20 70 2d 3e 70 46 69 6c 65 20 3d  ;.    p->pFile =
5a30: 20 70 46 69 6c 65 3b 0a 20 20 7d 0a 7d 0a 0a 2f   pFile;.  }.}../
5a40: 2a 0a 2a 2a 20 57 72 69 74 65 20 6e 44 61 74 61  *.** Write nData
5a50: 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 74   bytes of data t
5a60: 6f 20 74 68 65 20 66 69 6c 65 2d 77 72 69 74 65  o the file-write
5a70: 20 6f 62 6a 65 63 74 2e 20 52 65 74 75 72 6e 20   object. Return 
5a80: 53 51 4c 49 54 45 5f 4f 4b 0a 2a 2a 20 69 66 20  SQLITE_OK.** if 
5a90: 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61  successful, or a
5aa0: 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  n SQLite error c
5ab0: 6f 64 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20  ode if an error 
5ac0: 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69  occurs..*/.stati
5ad0: 63 20 76 6f 69 64 20 66 69 6c 65 57 72 69 74 65  c void fileWrite
5ae0: 72 57 72 69 74 65 28 46 69 6c 65 57 72 69 74 65  rWrite(FileWrite
5af0: 72 20 2a 70 2c 20 75 38 20 2a 70 44 61 74 61 2c  r *p, u8 *pData,
5b00: 20 69 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20 69   int nData){.  i
5b10: 6e 74 20 6e 52 65 6d 20 3d 20 6e 44 61 74 61 3b  nt nRem = nData;
5b20: 0a 20 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30  .  while( nRem>0
5b30: 20 26 26 20 70 2d 3e 65 46 57 45 72 72 3d 3d 30   && p->eFWErr==0
5b40: 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 43 6f 70   ){.    int nCop
5b50: 79 20 3d 20 6e 52 65 6d 3b 0a 20 20 20 20 69 66  y = nRem;.    if
5b60: 28 20 6e 43 6f 70 79 3e 28 70 2d 3e 6e 42 75 66  ( nCopy>(p->nBuf
5b70: 66 65 72 20 2d 20 70 2d 3e 69 42 75 66 45 6e 64  fer - p->iBufEnd
5b80: 29 20 29 7b 0a 20 20 20 20 20 20 6e 43 6f 70 79  ) ){.      nCopy
5b90: 20 3d 20 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20   = p->nBuffer - 
5ba0: 70 2d 3e 69 42 75 66 45 6e 64 3b 0a 20 20 20 20  p->iBufEnd;.    
5bb0: 7d 0a 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70  }..    memcpy(&p
5bc0: 2d 3e 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75  ->aBuffer[p->iBu
5bd0: 66 45 6e 64 5d 2c 20 26 70 44 61 74 61 5b 6e 44  fEnd], &pData[nD
5be0: 61 74 61 2d 6e 52 65 6d 5d 2c 20 6e 43 6f 70 79  ata-nRem], nCopy
5bf0: 29 3b 0a 20 20 20 20 70 2d 3e 69 42 75 66 45 6e  );.    p->iBufEn
5c00: 64 20 2b 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20  d += nCopy;.    
5c10: 69 66 28 20 70 2d 3e 69 42 75 66 45 6e 64 3d 3d  if( p->iBufEnd==
5c20: 70 2d 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20  p->nBuffer ){.  
5c30: 20 20 20 20 70 2d 3e 65 46 57 45 72 72 20 3d 20      p->eFWErr = 
5c40: 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70  sqlite3OsWrite(p
5c50: 2d 3e 70 46 69 6c 65 2c 20 0a 20 20 20 20 20 20  ->pFile, .      
5c60: 20 20 20 20 26 70 2d 3e 61 42 75 66 66 65 72 5b      &p->aBuffer[
5c70: 70 2d 3e 69 42 75 66 53 74 61 72 74 5d 2c 20 70  p->iBufStart], p
5c80: 2d 3e 69 42 75 66 45 6e 64 20 2d 20 70 2d 3e 69  ->iBufEnd - p->i
5c90: 42 75 66 53 74 61 72 74 2c 20 0a 20 20 20 20 20  BufStart, .     
5ca0: 20 20 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66       p->iWriteOf
5cb0: 66 20 2b 20 70 2d 3e 69 42 75 66 53 74 61 72 74  f + p->iBufStart
5cc0: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20  .      );.      
5cd0: 70 2d 3e 69 42 75 66 53 74 61 72 74 20 3d 20 70  p->iBufStart = p
5ce0: 2d 3e 69 42 75 66 45 6e 64 20 3d 20 30 3b 0a 20  ->iBufEnd = 0;. 
5cf0: 20 20 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66       p->iWriteOf
5d00: 66 20 2b 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b  f += p->nBuffer;
5d10: 0a 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72  .    }.    asser
5d20: 74 28 20 70 2d 3e 69 42 75 66 45 6e 64 3c 70 2d  t( p->iBufEnd<p-
5d30: 3e 6e 42 75 66 66 65 72 20 29 3b 0a 0a 20 20 20  >nBuffer );..   
5d40: 20 6e 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a   nRem -= nCopy;.
5d50: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75    }.}../*.** Flu
5d60: 73 68 20 61 6e 79 20 62 75 66 66 65 72 65 64 20  sh any buffered 
5d70: 64 61 74 61 20 74 6f 20 64 69 73 6b 20 61 6e 64  data to disk and
5d80: 20 63 6c 65 61 6e 20 75 70 20 74 68 65 20 66 69   clean up the fi
5d90: 6c 65 2d 77 72 69 74 65 72 20 6f 62 6a 65 63 74  le-writer object
5da0: 2e 0a 2a 2a 20 54 68 65 20 72 65 73 75 6c 74 73  ..** The results
5db0: 20 6f 66 20 75 73 69 6e 67 20 74 68 65 20 66 69   of using the fi
5dc0: 6c 65 2d 77 72 69 74 65 72 20 61 66 74 65 72 20  le-writer after 
5dd0: 74 68 69 73 20 63 61 6c 6c 20 61 72 65 20 75 6e  this call are un
5de0: 64 65 66 69 6e 65 64 2e 0a 2a 2a 20 52 65 74 75  defined..** Retu
5df0: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20  rn SQLITE_OK if 
5e00: 66 6c 75 73 68 69 6e 67 20 74 68 65 20 62 75 66  flushing the buf
5e10: 66 65 72 65 64 20 64 61 74 61 20 73 75 63 63 65  fered data succe
5e20: 65 64 73 20 6f 72 20 69 73 20 6e 6f 74 20 0a 2a  eds or is not .*
5e30: 2a 20 72 65 71 75 69 72 65 64 2e 20 4f 74 68 65  * required. Othe
5e40: 72 77 69 73 65 2c 20 72 65 74 75 72 6e 20 61 6e  rwise, return an
5e50: 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
5e60: 64 65 2e 0a 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65  de..**.** Before
5e70: 20 72 65 74 75 72 6e 69 6e 67 2c 20 73 65 74 20   returning, set 
5e80: 2a 70 69 45 6f 66 20 74 6f 20 74 68 65 20 6f 66  *piEof to the of
5e90: 66 73 65 74 20 69 6d 6d 65 64 69 61 74 65 6c 79  fset immediately
5ea0: 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68 65 0a 2a   following the.*
5eb0: 2a 20 6c 61 73 74 20 62 79 74 65 20 77 72 69 74  * last byte writ
5ec0: 74 65 6e 20 74 6f 20 74 68 65 20 66 69 6c 65 2e  ten to the file.
5ed0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
5ee0: 69 6c 65 57 72 69 74 65 72 46 69 6e 69 73 68 28  ileWriterFinish(
5ef0: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 46 69 6c  sqlite3 *db, Fil
5f00: 65 57 72 69 74 65 72 20 2a 70 2c 20 69 36 34 20  eWriter *p, i64 
5f10: 2a 70 69 45 6f 66 29 7b 0a 20 20 69 6e 74 20 72  *piEof){.  int r
5f20: 63 3b 0a 20 20 69 66 28 20 70 2d 3e 65 46 57 45  c;.  if( p->eFWE
5f30: 72 72 3d 3d 30 20 26 26 20 41 4c 57 41 59 53 28  rr==0 && ALWAYS(
5f40: 70 2d 3e 61 42 75 66 66 65 72 29 20 26 26 20 70  p->aBuffer) && p
5f50: 2d 3e 69 42 75 66 45 6e 64 3e 70 2d 3e 69 42 75  ->iBufEnd>p->iBu
5f60: 66 53 74 61 72 74 20 29 7b 0a 20 20 20 20 70 2d  fStart ){.    p-
5f70: 3e 65 46 57 45 72 72 20 3d 20 73 71 6c 69 74 65  >eFWErr = sqlite
5f80: 33 4f 73 57 72 69 74 65 28 70 2d 3e 70 46 69 6c  3OsWrite(p->pFil
5f90: 65 2c 20 0a 20 20 20 20 20 20 20 20 26 70 2d 3e  e, .        &p->
5fa0: 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 53  aBuffer[p->iBufS
5fb0: 74 61 72 74 5d 2c 20 70 2d 3e 69 42 75 66 45 6e  tart], p->iBufEn
5fc0: 64 20 2d 20 70 2d 3e 69 42 75 66 53 74 61 72 74  d - p->iBufStart
5fd0: 2c 20 0a 20 20 20 20 20 20 20 20 70 2d 3e 69 57  , .        p->iW
5fe0: 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42 75  riteOff + p->iBu
5ff0: 66 53 74 61 72 74 0a 20 20 20 20 29 3b 0a 20 20  fStart.    );.  
6000: 7d 0a 20 20 2a 70 69 45 6f 66 20 3d 20 28 70 2d  }.  *piEof = (p-
6010: 3e 69 57 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e  >iWriteOff + p->
6020: 69 42 75 66 45 6e 64 29 3b 0a 20 20 73 71 6c 69  iBufEnd);.  sqli
6030: 74 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 2d  te3DbFree(db, p-
6040: 3e 61 42 75 66 66 65 72 29 3b 0a 20 20 72 63 20  >aBuffer);.  rc 
6050: 3d 20 70 2d 3e 65 46 57 45 72 72 3b 0a 20 20 6d  = p->eFWErr;.  m
6060: 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65  emset(p, 0, size
6070: 6f 66 28 46 69 6c 65 57 72 69 74 65 72 29 29 3b  of(FileWriter));
6080: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
6090: 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 76 61 6c  ./*.** Write val
60a0: 75 65 20 69 56 61 6c 20 65 6e 63 6f 64 65 64 20  ue iVal encoded 
60b0: 61 73 20 61 20 76 61 72 69 6e 74 20 74 6f 20 74  as a varint to t
60c0: 68 65 20 66 69 6c 65 2d 77 72 69 74 65 20 6f 62  he file-write ob
60d0: 6a 65 63 74 2e 20 52 65 74 75 72 6e 20 0a 2a 2a  ject. Return .**
60e0: 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75   SQLITE_OK if su
60f0: 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20  ccessful, or an 
6100: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
6110: 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  e if an error oc
6120: 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  curs..*/.static 
6130: 76 6f 69 64 20 66 69 6c 65 57 72 69 74 65 72 57  void fileWriterW
6140: 72 69 74 65 56 61 72 69 6e 74 28 46 69 6c 65 57  riteVarint(FileW
6150: 72 69 74 65 72 20 2a 70 2c 20 75 36 34 20 69 56  riter *p, u64 iV
6160: 61 6c 29 7b 0a 20 20 69 6e 74 20 6e 42 79 74 65  al){.  int nByte
6170: 3b 20 0a 20 20 75 38 20 61 42 79 74 65 5b 31 30  ; .  u8 aByte[10
6180: 5d 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 71 6c  ];.  nByte = sql
6190: 69 74 65 33 50 75 74 56 61 72 69 6e 74 28 61 42  ite3PutVarint(aB
61a0: 79 74 65 2c 20 69 56 61 6c 29 3b 0a 20 20 66 69  yte, iVal);.  fi
61b0: 6c 65 57 72 69 74 65 72 57 72 69 74 65 28 70 2c  leWriterWrite(p,
61c0: 20 61 42 79 74 65 2c 20 6e 42 79 74 65 29 3b 0a   aByte, nByte);.
61d0: 7d 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 4d 41  }..#if SQLITE_MA
61e0: 58 5f 4d 4d 41 50 5f 53 49 5a 45 3e 30 0a 2f 2a  X_MMAP_SIZE>0./*
61f0: 0a 2a 2a 20 54 68 65 20 66 69 72 73 74 20 61 72  .** The first ar
6200: 67 75 6d 65 6e 74 20 69 73 20 61 20 66 69 6c 65  gument is a file
6210: 2d 68 61 6e 64 6c 65 20 6f 70 65 6e 20 6f 6e 20  -handle open on 
6220: 61 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65  a temporary file
6230: 2e 20 54 68 65 20 66 69 6c 65 0a 2a 2a 20 69 73  . The file.** is
6240: 20 67 75 61 72 61 6e 74 65 65 64 20 74 6f 20 62   guaranteed to b
6250: 65 20 6e 42 79 74 65 20 62 79 74 65 73 20 6f 72  e nByte bytes or
6260: 20 73 6d 61 6c 6c 65 72 20 69 6e 20 73 69 7a 65   smaller in size
6270: 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
6280: 0a 2a 2a 20 61 74 74 65 6d 70 74 73 20 74 6f 20  .** attempts to 
6290: 65 78 74 65 6e 64 20 74 68 65 20 66 69 6c 65 20  extend the file 
62a0: 74 6f 20 6e 42 79 74 65 20 62 79 74 65 73 20 69  to nByte bytes i
62b0: 6e 20 73 69 7a 65 20 61 6e 64 20 74 6f 20 65 6e  n size and to en
62c0: 73 75 72 65 20 74 68 61 74 0a 2a 2a 20 74 68 65  sure that.** the
62d0: 20 56 46 53 20 68 61 73 20 6d 65 6d 6f 72 79 20   VFS has memory 
62e0: 6d 61 70 70 65 64 20 69 74 2e 0a 2a 2a 0a 2a 2a  mapped it..**.**
62f0: 20 57 68 65 74 68 65 72 20 6f 72 20 6e 6f 74 20   Whether or not 
6300: 74 68 65 20 66 69 6c 65 20 64 6f 65 73 20 65 6e  the file does en
6310: 64 20 75 70 20 6d 65 6d 6f 72 79 20 6d 61 70 70  d up memory mapp
6320: 65 64 20 6f 66 20 63 6f 75 72 73 65 20 64 65 70  ed of course dep
6330: 65 6e 64 73 20 6f 6e 20 0a 2a 2a 20 74 68 65 20  ends on .** the 
6340: 73 70 65 63 69 66 69 63 20 56 46 53 20 69 6d 70  specific VFS imp
6350: 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a  lementation..*/.
6360: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53  static int vdbeS
6370: 6f 72 74 65 72 45 78 74 65 6e 64 46 69 6c 65 28  orterExtendFile(
6380: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
6390: 69 6c 65 2c 20 69 36 34 20 6e 42 79 74 65 29 7b  ile, i64 nByte){
63a0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 69  .  int rc = sqli
63b0: 74 65 33 4f 73 54 72 75 6e 63 61 74 65 28 70 46  te3OsTruncate(pF
63c0: 69 6c 65 2c 20 6e 42 79 74 65 29 3b 0a 20 20 69  ile, nByte);.  i
63d0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
63e0: 20 29 7b 0a 20 20 20 20 76 6f 69 64 20 2a 70 20   ){.    void *p 
63f0: 3d 20 30 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  = 0;.    sqlite3
6400: 4f 73 46 65 74 63 68 28 70 46 69 6c 65 2c 20 30  OsFetch(pFile, 0
6410: 2c 20 6e 42 79 74 65 2c 20 26 70 29 3b 0a 20 20  , nByte, &p);.  
6420: 20 20 73 71 6c 69 74 65 33 4f 73 55 6e 66 65 74    sqlite3OsUnfet
6430: 63 68 28 70 46 69 6c 65 2c 20 30 2c 20 70 29 3b  ch(pFile, 0, p);
6440: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
6450: 3b 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65 66 69  ;.}.#else.# defi
6460: 6e 65 20 76 64 62 65 53 6f 72 74 65 72 45 78 74  ne vdbeSorterExt
6470: 65 6e 64 46 69 6c 65 28 78 2c 79 29 20 53 51 4c  endFile(x,y) SQL
6480: 49 54 45 5f 4f 4b 0a 23 65 6e 64 69 66 0a 0a 2f  ITE_OK.#endif../
6490: 2a 0a 2a 2a 20 57 72 69 74 65 20 74 68 65 20 63  *.** Write the c
64a0: 75 72 72 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20  urrent contents 
64b0: 6f 66 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79  of the in-memory
64c0: 20 6c 69 6e 6b 65 64 2d 6c 69 73 74 20 74 6f 20   linked-list to 
64d0: 61 20 50 4d 41 2e 20 52 65 74 75 72 6e 0a 2a 2a  a PMA. Return.**
64e0: 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75   SQLITE_OK if su
64f0: 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20  ccessful, or an 
6500: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
6510: 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2a 0a  e otherwise..**.
6520: 2a 2a 20 54 68 65 20 66 6f 72 6d 61 74 20 6f 66  ** The format of
6530: 20 61 20 50 4d 41 20 69 73 3a 0a 2a 2a 0a 2a 2a   a PMA is:.**.**
6540: 20 20 20 20 20 2a 20 41 20 76 61 72 69 6e 74 2e       * A varint.
6550: 20 54 68 69 73 20 76 61 72 69 6e 74 20 63 6f 6e   This varint con
6560: 74 61 69 6e 73 20 74 68 65 20 74 6f 74 61 6c 20  tains the total 
6570: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
6580: 6f 66 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20 20 20  of content.**   
6590: 20 20 20 20 69 6e 20 74 68 65 20 50 4d 41 20 28      in the PMA (
65a0: 6e 6f 74 20 69 6e 63 6c 75 64 69 6e 67 20 74 68  not including th
65b0: 65 20 76 61 72 69 6e 74 20 69 74 73 65 6c 66 29  e varint itself)
65c0: 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 4f 6e  ..**.**     * On
65d0: 65 20 6f 72 20 6d 6f 72 65 20 72 65 63 6f 72 64  e or more record
65e0: 73 20 70 61 63 6b 65 64 20 65 6e 64 2d 74 6f 2d  s packed end-to-
65f0: 65 6e 64 20 69 6e 20 6f 72 64 65 72 20 6f 66 20  end in order of 
6600: 61 73 63 65 6e 64 69 6e 67 20 6b 65 79 73 2e 20  ascending keys. 
6610: 0a 2a 2a 20 20 20 20 20 20 20 45 61 63 68 20 72  .**       Each r
6620: 65 63 6f 72 64 20 63 6f 6e 73 69 73 74 73 20 6f  ecord consists o
6630: 66 20 61 20 76 61 72 69 6e 74 20 66 6f 6c 6c 6f  f a varint follo
6640: 77 65 64 20 62 79 20 61 20 62 6c 6f 62 20 6f 66  wed by a blob of
6650: 20 64 61 74 61 20 28 74 68 65 20 0a 2a 2a 20 20   data (the .**  
6660: 20 20 20 20 20 6b 65 79 29 2e 20 54 68 65 20 76       key). The v
6670: 61 72 69 6e 74 20 69 73 20 74 68 65 20 6e 75 6d  arint is the num
6680: 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
6690: 74 68 65 20 62 6c 6f 62 20 6f 66 20 64 61 74 61  the blob of data
66a0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
66b0: 76 64 62 65 53 6f 72 74 65 72 4c 69 73 74 54 6f  vdbeSorterListTo
66c0: 50 4d 41 28 73 71 6c 69 74 65 33 20 2a 64 62 2c  PMA(sqlite3 *db,
66d0: 20 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f   const VdbeCurso
66e0: 72 20 2a 70 43 73 72 29 7b 0a 20 20 69 6e 74 20  r *pCsr){.  int 
66f0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20  rc = SQLITE_OK; 
6700: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
6710: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
6720: 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72  VdbeSorter *pSor
6730: 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72  ter = pCsr->pSor
6740: 74 65 72 3b 0a 20 20 46 69 6c 65 57 72 69 74 65  ter;.  FileWrite
6750: 72 20 77 72 69 74 65 72 3b 0a 0a 20 20 6d 65 6d  r writer;..  mem
6760: 73 65 74 28 26 77 72 69 74 65 72 2c 20 30 2c 20  set(&writer, 0, 
6770: 73 69 7a 65 6f 66 28 46 69 6c 65 57 72 69 74 65  sizeof(FileWrite
6780: 72 29 29 3b 0a 0a 20 20 69 66 28 20 70 53 6f 72  r));..  if( pSor
6790: 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 3d 3d  ter->nInMemory==
67a0: 30 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  0 ){.    assert(
67b0: 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72   pSorter->pRecor
67c0: 64 3d 3d 30 20 29 3b 0a 20 20 20 20 72 65 74 75  d==0 );.    retu
67d0: 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 72 63  rn rc;.  }..  rc
67e0: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 53 6f 72   = vdbeSorterSor
67f0: 74 28 70 43 73 72 29 3b 0a 0a 20 20 2f 2a 20 49  t(pCsr);..  /* I
6800: 66 20 74 68 65 20 66 69 72 73 74 20 74 65 6d 70  f the first temp
6810: 6f 72 61 72 79 20 50 4d 41 20 66 69 6c 65 20 68  orary PMA file h
6820: 61 73 20 6e 6f 74 20 62 65 65 6e 20 6f 70 65 6e  as not been open
6830: 65 64 2c 20 6f 70 65 6e 20 69 74 20 6e 6f 77 2e  ed, open it now.
6840: 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   */.  if( rc==SQ
6850: 4c 49 54 45 5f 4f 4b 20 26 26 20 70 53 6f 72 74  LITE_OK && pSort
6860: 65 72 2d 3e 70 54 65 6d 70 31 3d 3d 30 20 29 7b  er->pTemp1==0 ){
6870: 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65 53 6f  .    rc = vdbeSo
6880: 72 74 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c 65  rterOpenTempFile
6890: 28 64 62 2c 20 26 70 53 6f 72 74 65 72 2d 3e 70  (db, &pSorter->p
68a0: 54 65 6d 70 31 29 3b 0a 20 20 20 20 61 73 73 65  Temp1);.    asse
68b0: 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  rt( rc!=SQLITE_O
68c0: 4b 20 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 70 54  K || pSorter->pT
68d0: 65 6d 70 31 20 29 3b 0a 20 20 20 20 61 73 73 65  emp1 );.    asse
68e0: 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 69 57 72  rt( pSorter->iWr
68f0: 69 74 65 4f 66 66 3d 3d 30 20 29 3b 0a 20 20 20  iteOff==0 );.   
6900: 20 61 73 73 65 72 74 28 20 70 53 6f 72 74 65 72   assert( pSorter
6910: 2d 3e 6e 50 4d 41 3d 3d 30 20 29 3b 0a 20 20 7d  ->nPMA==0 );.  }
6920: 0a 0a 20 20 2f 2a 20 54 72 79 20 74 6f 20 67 65  ..  /* Try to ge
6930: 74 20 74 68 65 20 66 69 6c 65 20 74 6f 20 6d 65  t the file to me
6940: 6d 6f 72 79 20 6d 61 70 20 2a 2f 0a 20 20 69 66  mory map */.  if
6950: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
6960: 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62 65  ){.    rc = vdbe
6970: 53 6f 72 74 65 72 45 78 74 65 6e 64 46 69 6c 65  SorterExtendFile
6980: 28 0a 20 20 20 20 20 20 20 20 70 53 6f 72 74 65  (.        pSorte
6990: 72 2d 3e 70 54 65 6d 70 31 2c 20 70 53 6f 72 74  r->pTemp1, pSort
69a0: 65 72 2d 3e 69 57 72 69 74 65 4f 66 66 20 2b 20  er->iWriteOff + 
69b0: 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f  pSorter->nInMemo
69c0: 72 79 20 2b 20 39 0a 20 20 20 20 29 3b 0a 20 20  ry + 9.    );.  
69d0: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
69e0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 53 6f  ITE_OK ){.    So
69f0: 72 74 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a 20  rterRecord *p;. 
6a00: 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20     SorterRecord 
6a10: 2a 70 4e 65 78 74 20 3d 20 30 3b 0a 0a 20 20 20  *pNext = 0;..   
6a20: 20 66 69 6c 65 57 72 69 74 65 72 49 6e 69 74 28   fileWriterInit(
6a30: 64 62 2c 20 70 53 6f 72 74 65 72 2d 3e 70 54 65  db, pSorter->pTe
6a40: 6d 70 31 2c 20 26 77 72 69 74 65 72 2c 20 70 53  mp1, &writer, pS
6a50: 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f 66 66  orter->iWriteOff
6a60: 29 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  );.    pSorter->
6a70: 6e 50 4d 41 2b 2b 3b 0a 20 20 20 20 66 69 6c 65  nPMA++;.    file
6a80: 57 72 69 74 65 72 57 72 69 74 65 56 61 72 69 6e  WriterWriteVarin
6a90: 74 28 26 77 72 69 74 65 72 2c 20 70 53 6f 72 74  t(&writer, pSort
6aa0: 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 29 3b 0a  er->nInMemory);.
6ab0: 20 20 20 20 66 6f 72 28 70 3d 70 53 6f 72 74 65      for(p=pSorte
6ac0: 72 2d 3e 70 52 65 63 6f 72 64 3b 20 70 3b 20 70  r->pRecord; p; p
6ad0: 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 70  =pNext){.      p
6ae0: 4e 65 78 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b  Next = p->pNext;
6af0: 0a 20 20 20 20 20 20 66 69 6c 65 57 72 69 74 65  .      fileWrite
6b00: 72 57 72 69 74 65 56 61 72 69 6e 74 28 26 77 72  rWriteVarint(&wr
6b10: 69 74 65 72 2c 20 70 2d 3e 6e 56 61 6c 29 3b 0a  iter, p->nVal);.
6b20: 20 20 20 20 20 20 66 69 6c 65 57 72 69 74 65 72        fileWriter
6b30: 57 72 69 74 65 28 26 77 72 69 74 65 72 2c 20 70  Write(&writer, p
6b40: 2d 3e 70 56 61 6c 2c 20 70 2d 3e 6e 56 61 6c 29  ->pVal, p->nVal)
6b50: 3b 0a 20 20 20 20 20 20 69 66 28 20 70 53 6f 72  ;.      if( pSor
6b60: 74 65 72 2d 3e 61 4d 65 6d 6f 72 79 3d 3d 30 20  ter->aMemory==0 
6b70: 29 20 73 71 6c 69 74 65 33 44 62 46 72 65 65 28  ) sqlite3DbFree(
6b80: 64 62 2c 20 70 29 3b 0a 20 20 20 20 7d 0a 20 20  db, p);.    }.  
6b90: 20 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f    pSorter->pReco
6ba0: 72 64 20 3d 20 70 3b 0a 20 20 20 20 72 63 20 3d  rd = p;.    rc =
6bb0: 20 66 69 6c 65 57 72 69 74 65 72 46 69 6e 69 73   fileWriterFinis
6bc0: 68 28 64 62 2c 20 26 77 72 69 74 65 72 2c 20 26  h(db, &writer, &
6bd0: 70 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f  pSorter->iWriteO
6be0: 66 66 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  ff);.  }..  if( 
6bf0: 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79  pSorter->aMemory
6c00: 20 29 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63   ) pSorter->pRec
6c10: 6f 72 64 20 3d 20 30 3b 0a 20 20 61 73 73 65 72  ord = 0;.  asser
6c20: 74 28 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63  t( pSorter->pRec
6c30: 6f 72 64 3d 3d 30 20 7c 7c 20 72 63 21 3d 53 51  ord==0 || rc!=SQ
6c40: 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72 65 74  LITE_OK );.  ret
6c50: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
6c60: 20 41 64 64 20 61 20 72 65 63 6f 72 64 20 74 6f   Add a record to
6c70: 20 74 68 65 20 73 6f 72 74 65 72 2e 0a 2a 2f 0a   the sorter..*/.
6c80: 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62 65 53  int sqlite3VdbeS
6c90: 6f 72 74 65 72 57 72 69 74 65 28 0a 20 20 73 71  orterWrite(.  sq
6ca0: 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20  lite3 *db,      
6cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6cc0: 20 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65   Database handle
6cd0: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 56 64 62 65   */.  const Vdbe
6ce0: 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 20 20  Cursor *pCsr,   
6cf0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
6d00: 6f 72 74 65 72 20 63 75 72 73 6f 72 20 2a 2f 0a  orter cursor */.
6d10: 20 20 4d 65 6d 20 2a 70 56 61 6c 20 20 20 20 20    Mem *pVal     
6d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d30: 20 20 2f 2a 20 4d 65 6d 6f 72 79 20 63 65 6c 6c    /* Memory cell
6d40: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 72 65 63 6f   containing reco
6d50: 72 64 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65 53  rd */.){.  VdbeS
6d60: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d  orter *pSorter =
6d70: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a   pCsr->pSorter;.
6d80: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 73    SorterRecord s
6d90: 52 65 63 6f 72 64 3b 20 20 20 20 20 20 20 20 20  Record;         
6da0: 20 20 2f 2a 20 55 73 65 64 20 66 6f 72 20 61 4d    /* Used for aM
6db0: 65 6d 6f 72 79 20 6f 76 65 72 66 6c 6f 77 20 72  emory overflow r
6dc0: 65 63 6f 72 64 20 2a 2f 0a 20 20 69 6e 74 20 72  ecord */.  int r
6dd0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20  c = SQLITE_OK;  
6de0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
6df0: 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 53  turn Code */.  S
6e00: 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65  orterRecord *pNe
6e10: 77 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  w;             /
6e20: 2a 20 4e 65 77 20 6c 69 73 74 20 65 6c 65 6d 65  * New list eleme
6e30: 6e 74 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28  nt */..  assert(
6e40: 20 70 53 6f 72 74 65 72 20 29 3b 0a 20 20 70 53   pSorter );.  pS
6e50: 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79  orter->nInMemory
6e60: 20 2b 3d 20 73 71 6c 69 74 65 33 56 61 72 69 6e   += sqlite3Varin
6e70: 74 4c 65 6e 28 70 56 61 6c 2d 3e 6e 29 20 2b 20  tLen(pVal->n) + 
6e80: 70 56 61 6c 2d 3e 6e 3b 0a 0a 20 20 69 66 28 20  pVal->n;..  if( 
6e90: 70 53 6f 72 74 65 72 2d 3e 61 4d 65 6d 6f 72 79  pSorter->aMemory
6ea0: 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 52 65 71   ){.    int nReq
6eb0: 20 3d 20 73 69 7a 65 6f 66 28 53 6f 72 74 65 72   = sizeof(Sorter
6ec0: 52 65 63 6f 72 64 29 20 2b 20 70 56 61 6c 2d 3e  Record) + pVal->
6ed0: 6e 3b 0a 20 20 20 20 69 66 28 20 28 70 53 6f 72  n;.    if( (pSor
6ee0: 74 65 72 2d 3e 69 4d 65 6d 6f 72 79 2b 6e 52 65  ter->iMemory+nRe
6ef0: 71 29 20 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 78  q) > pSorter->mx
6f00: 50 6d 61 53 69 7a 65 20 29 7b 0a 20 20 20 20 20  PmaSize ){.     
6f10: 20 70 4e 65 77 20 3d 20 26 73 52 65 63 6f 72 64   pNew = &sRecord
6f20: 3b 0a 20 20 20 20 20 20 70 4e 65 77 2d 3e 70 56  ;.      pNew->pV
6f30: 61 6c 20 3d 20 70 56 61 6c 2d 3e 7a 3b 0a 20 20  al = pVal->z;.  
6f40: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70    }else{.      p
6f50: 4e 65 77 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e  New = &pSorter->
6f60: 61 4d 65 6d 6f 72 79 5b 70 53 6f 72 74 65 72 2d  aMemory[pSorter-
6f70: 3e 69 4d 65 6d 6f 72 79 5d 3b 0a 20 20 20 20 20  >iMemory];.     
6f80: 20 70 53 6f 72 74 65 72 2d 3e 69 4d 65 6d 6f 72   pSorter->iMemor
6f90: 79 20 2b 3d 20 52 4f 55 4e 44 38 28 6e 52 65 71  y += ROUND8(nReq
6fa0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65  );.    }.  }else
6fb0: 7b 0a 20 20 20 20 70 4e 65 77 20 3d 20 28 53 6f  {.    pNew = (So
6fc0: 72 74 65 72 52 65 63 6f 72 64 20 2a 29 73 71 6c  rterRecord *)sql
6fd0: 69 74 65 33 44 62 4d 61 6c 6c 6f 63 52 61 77 28  ite3DbMallocRaw(
6fe0: 64 62 2c 20 70 56 61 6c 2d 3e 6e 2b 73 69 7a 65  db, pVal->n+size
6ff0: 6f 66 28 53 6f 72 74 65 72 52 65 63 6f 72 64 29  of(SorterRecord)
7000: 29 3b 0a 20 20 20 20 69 66 28 20 70 4e 65 77 3d  );.    if( pNew=
7010: 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75  =0 ){.      retu
7020: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
7030: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
7040: 28 20 70 4e 65 77 21 3d 26 73 52 65 63 6f 72 64  ( pNew!=&sRecord
7050: 20 29 7b 0a 20 20 20 20 70 4e 65 77 2d 3e 70 56   ){.    pNew->pV
7060: 61 6c 20 3d 20 28 76 6f 69 64 2a 29 26 70 4e 65  al = (void*)&pNe
7070: 77 5b 31 5d 3b 0a 20 20 20 20 6d 65 6d 63 70 79  w[1];.    memcpy
7080: 28 70 4e 65 77 2d 3e 70 56 61 6c 2c 20 70 56 61  (pNew->pVal, pVa
7090: 6c 2d 3e 7a 2c 20 70 56 61 6c 2d 3e 6e 29 3b 0a  l->z, pVal->n);.
70a0: 20 20 7d 0a 20 20 70 4e 65 77 2d 3e 6e 56 61 6c    }.  pNew->nVal
70b0: 20 3d 20 70 56 61 6c 2d 3e 6e 3b 0a 20 20 70 4e   = pVal->n;.  pN
70c0: 65 77 2d 3e 70 4e 65 78 74 20 3d 20 70 53 6f 72  ew->pNext = pSor
70d0: 74 65 72 2d 3e 70 52 65 63 6f 72 64 3b 0a 20 20  ter->pRecord;.  
70e0: 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64  pSorter->pRecord
70f0: 20 3d 20 70 4e 65 77 3b 0a 0a 20 20 2f 2a 20 53   = pNew;..  /* S
7100: 65 65 20 69 66 20 74 68 65 20 63 6f 6e 74 65 6e  ee if the conten
7110: 74 73 20 6f 66 20 74 68 65 20 73 6f 72 74 65 72  ts of the sorter
7120: 20 73 68 6f 75 6c 64 20 6e 6f 77 20 62 65 20 77   should now be w
7130: 72 69 74 74 65 6e 20 6f 75 74 2e 20 54 68 65 79  ritten out. They
7140: 0a 20 20 2a 2a 20 61 72 65 20 77 72 69 74 74 65  .  ** are writte
7150: 6e 20 6f 75 74 20 77 68 65 6e 20 65 69 74 68 65  n out when eithe
7160: 72 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69  r of the followi
7170: 6e 67 20 61 72 65 20 74 72 75 65 3a 0a 20 20 2a  ng are true:.  *
7180: 2a 0a 20 20 2a 2a 20 20 20 2a 20 54 68 65 20 74  *.  **   * The t
7190: 6f 74 61 6c 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f  otal memory allo
71a0: 63 61 74 65 64 20 66 6f 72 20 74 68 65 20 69 6e  cated for the in
71b0: 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20 69 73 20  -memory list is 
71c0: 67 72 65 61 74 65 72 20 0a 20 20 2a 2a 20 20 20  greater .  **   
71d0: 20 20 74 68 61 6e 20 28 70 61 67 65 2d 73 69 7a    than (page-siz
71e0: 65 20 2a 20 63 61 63 68 65 2d 73 69 7a 65 29 2c  e * cache-size),
71f0: 20 6f 72 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20   or.  **.  **   
7200: 2a 20 54 68 65 20 74 6f 74 61 6c 20 6d 65 6d 6f  * The total memo
7210: 72 79 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72  ry allocated for
7220: 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c   the in-memory l
7230: 69 73 74 20 69 73 20 67 72 65 61 74 65 72 20 0a  ist is greater .
7240: 20 20 2a 2a 20 20 20 20 20 74 68 61 6e 20 28 70    **     than (p
7250: 61 67 65 2d 73 69 7a 65 20 2a 20 31 30 29 20 61  age-size * 10) a
7260: 6e 64 20 73 71 6c 69 74 65 33 48 65 61 70 4e 65  nd sqlite3HeapNe
7270: 61 72 6c 79 46 75 6c 6c 28 29 20 72 65 74 75 72  arlyFull() retur
7280: 6e 73 20 74 72 75 65 2e 0a 20 20 2a 2f 0a 20 20  ns true..  */.  
7290: 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50  if( pSorter->mxP
72a0: 6d 61 53 69 7a 65 3e 30 20 29 7b 0a 20 20 20 20  maSize>0 ){.    
72b0: 69 66 28 20 28 70 4e 65 77 3d 3d 26 73 52 65 63  if( (pNew==&sRec
72c0: 6f 72 64 29 20 7c 7c 20 28 70 53 6f 72 74 65 72  ord) || (pSorter
72d0: 2d 3e 61 4d 65 6d 6f 72 79 3d 3d 30 20 26 26 20  ->aMemory==0 && 
72e0: 28 0a 20 20 20 20 20 20 20 20 28 70 53 6f 72 74  (.        (pSort
72f0: 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20 3e 20  er->nInMemory > 
7300: 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61 53 69  pSorter->mxPmaSi
7310: 7a 65 29 0a 20 20 20 20 20 7c 7c 20 28 70 53 6f  ze).     || (pSo
7320: 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20  rter->nInMemory 
7330: 3e 20 70 53 6f 72 74 65 72 2d 3e 6d 6e 50 6d 61  > pSorter->mnPma
7340: 53 69 7a 65 20 26 26 20 73 71 6c 69 74 65 33 48  Size && sqlite3H
7350: 65 61 70 4e 65 61 72 6c 79 46 75 6c 6c 28 29 29  eapNearlyFull())
7360: 0a 20 20 20 20 29 29 29 7b 0a 23 69 66 64 65 66  .    ))){.#ifdef
7370: 20 53 51 4c 49 54 45 5f 44 45 42 55 47 0a 20 20   SQLITE_DEBUG.  
7380: 20 20 20 20 69 36 34 20 6e 45 78 70 65 63 74 20      i64 nExpect 
7390: 3d 20 70 53 6f 72 74 65 72 2d 3e 69 57 72 69 74  = pSorter->iWrit
73a0: 65 4f 66 66 0a 20 20 20 20 20 20 20 20 2b 20 73  eOff.        + s
73b0: 71 6c 69 74 65 33 56 61 72 69 6e 74 4c 65 6e 28  qlite3VarintLen(
73c0: 70 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f  pSorter->nInMemo
73d0: 72 79 29 0a 20 20 20 20 20 20 20 20 2b 20 70 53  ry).        + pS
73e0: 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79  orter->nInMemory
73f0: 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20 72  ;.#endif.      r
7400: 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4c 69  c = vdbeSorterLi
7410: 73 74 54 6f 50 4d 41 28 64 62 2c 20 70 43 73 72  stToPMA(db, pCsr
7420: 29 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72  );.      pSorter
7430: 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20 3d 20 30 3b  ->nInMemory = 0;
7440: 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  .      pSorter->
7450: 69 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a 20 20 20  iMemory = 0;.   
7460: 20 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 53     assert( rc!=S
7470: 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 28 6e 45 78  QLITE_OK || (nEx
7480: 70 65 63 74 3d 3d 70 53 6f 72 74 65 72 2d 3e 69  pect==pSorter->i
7490: 57 72 69 74 65 4f 66 66 29 20 29 3b 0a 20 20 20  WriteOff) );.   
74a0: 20 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 53     assert( rc!=S
74b0: 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53 6f 72  QLITE_OK || pSor
74c0: 74 65 72 2d 3e 70 52 65 63 6f 72 64 3d 3d 30 20  ter->pRecord==0 
74d0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
74e0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
74f0: 0a 2a 2a 20 48 65 6c 70 65 72 20 66 75 6e 63 74  .** Helper funct
7500: 69 6f 6e 20 66 6f 72 20 73 71 6c 69 74 65 33 56  ion for sqlite3V
7510: 64 62 65 53 6f 72 74 65 72 52 65 77 69 6e 64 28  dbeSorterRewind(
7520: 29 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ). .*/.static in
7530: 74 20 76 64 62 65 53 6f 72 74 65 72 49 6e 69 74  t vdbeSorterInit
7540: 4d 65 72 67 65 28 0a 20 20 73 71 6c 69 74 65 33  Merge(.  sqlite3
7550: 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20 20   *db,           
7560: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
7570: 62 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20  base handle */. 
7580: 20 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f   const VdbeCurso
7590: 72 20 2a 70 43 73 72 2c 20 20 20 20 20 20 20 20  r *pCsr,        
75a0: 20 2f 2a 20 43 75 72 73 6f 72 20 68 61 6e 64 6c   /* Cursor handl
75b0: 65 20 66 6f 72 20 74 68 69 73 20 73 6f 72 74 65  e for this sorte
75c0: 72 20 2a 2f 0a 20 20 69 36 34 20 2a 70 6e 42 79  r */.  i64 *pnBy
75d0: 74 65 20 20 20 20 20 20 20 20 20 20 20 20 20 20  te              
75e0: 20 20 20 20 20 20 20 2f 2a 20 53 75 6d 20 6f 66         /* Sum of
75f0: 20 62 79 74 65 73 20 69 6e 20 61 6c 6c 20 6f 70   bytes in all op
7600: 65 6e 65 64 20 50 4d 41 73 20 2a 2f 0a 29 7b 0a  ened PMAs */.){.
7610: 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
7620: 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53  orter = pCsr->pS
7630: 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 72 63 20  orter;.  int rc 
7640: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20  = SQLITE_OK;    
7650: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
7660: 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74  rn code */.  int
7670: 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
7680: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7690: 55 73 65 64 20 74 6f 20 69 74 65 72 61 74 6f 72  Used to iterator
76a0: 20 74 68 72 6f 75 67 68 20 61 49 74 65 72 5b 5d   through aIter[]
76b0: 20 2a 2f 0a 20 20 69 36 34 20 6e 42 79 74 65 20   */.  i64 nByte 
76c0: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
76d0: 20 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 62        /* Total b
76e0: 79 74 65 73 20 69 6e 20 61 6c 6c 20 6f 70 65 6e  ytes in all open
76f0: 65 64 20 50 4d 41 73 20 2a 2f 0a 0a 20 20 2f 2a  ed PMAs */..  /*
7700: 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20   Initialize the 
7710: 69 74 65 72 61 74 6f 72 73 2e 20 49 74 65 72 61  iterators. Itera
7720: 74 6f 72 20 30 20 63 6f 6e 74 61 69 6e 73 20 74  tor 0 contains t
7730: 68 65 20 6f 6c 64 65 73 74 20 64 61 74 61 2e 20  he oldest data. 
7740: 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  */.  for(i=0; i<
7750: 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45  SORTER_MAX_MERGE
7760: 5f 43 4f 55 4e 54 3b 20 69 2b 2b 29 7b 0a 20 20  _COUNT; i++){.  
7770: 20 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72    VdbeSorterIter
7780: 20 2a 70 49 74 65 72 20 3d 20 26 70 53 6f 72 74   *pIter = &pSort
7790: 65 72 2d 3e 61 49 74 65 72 5b 69 5d 3b 0a 20 20  er->aIter[i];.  
77a0: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
77b0: 72 49 74 65 72 49 6e 69 74 28 64 62 2c 20 70 53  rIterInit(db, pS
77c0: 6f 72 74 65 72 2c 20 70 53 6f 72 74 65 72 2d 3e  orter, pSorter->
77d0: 69 52 65 61 64 4f 66 66 2c 20 70 49 74 65 72 2c  iReadOff, pIter,
77e0: 20 26 6e 42 79 74 65 29 3b 0a 20 20 20 20 70 53   &nByte);.    pS
77f0: 6f 72 74 65 72 2d 3e 69 52 65 61 64 4f 66 66 20  orter->iReadOff 
7800: 3d 20 70 49 74 65 72 2d 3e 69 45 6f 66 3b 0a 20  = pIter->iEof;. 
7810: 20 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 53     assert( rc!=S
7820: 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53 6f 72  QLITE_OK || pSor
7830: 74 65 72 2d 3e 69 52 65 61 64 4f 66 66 3c 3d 70  ter->iReadOff<=p
7840: 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f 66  Sorter->iWriteOf
7850: 66 20 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21  f );.    if( rc!
7860: 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53  =SQLITE_OK || pS
7870: 6f 72 74 65 72 2d 3e 69 52 65 61 64 4f 66 66 3e  orter->iReadOff>
7880: 3d 70 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65  =pSorter->iWrite
7890: 4f 66 66 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d  Off ) break;.  }
78a0: 0a 0a 20 20 2f 2a 20 49 6e 69 74 69 61 6c 69 7a  ..  /* Initializ
78b0: 65 20 74 68 65 20 61 54 72 65 65 5b 5d 20 61 72  e the aTree[] ar
78c0: 72 61 79 2e 20 2a 2f 0a 20 20 66 6f 72 28 69 3d  ray. */.  for(i=
78d0: 70 53 6f 72 74 65 72 2d 3e 6e 54 72 65 65 2d 31  pSorter->nTree-1
78e0: 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ; rc==SQLITE_OK 
78f0: 26 26 20 69 3e 30 3b 20 69 2d 2d 29 7b 0a 20 20  && i>0; i--){.  
7900: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
7910: 72 44 6f 43 6f 6d 70 61 72 65 28 70 43 73 72 2c  rDoCompare(pCsr,
7920: 20 69 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 6e 42   i);.  }..  *pnB
7930: 79 74 65 20 3d 20 6e 42 79 74 65 3b 0a 20 20 72  yte = nByte;.  r
7940: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
7950: 2a 2a 20 4f 6e 63 65 20 74 68 65 20 73 6f 72 74  ** Once the sort
7960: 65 72 20 68 61 73 20 62 65 65 6e 20 70 6f 70 75  er has been popu
7970: 6c 61 74 65 64 2c 20 74 68 69 73 20 66 75 6e 63  lated, this func
7980: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74  tion is called t
7990: 6f 20 70 72 65 70 61 72 65 0a 2a 2a 20 66 6f 72  o prepare.** for
79a0: 20 69 74 65 72 61 74 69 6e 67 20 74 68 72 6f 75   iterating throu
79b0: 67 68 20 69 74 73 20 63 6f 6e 74 65 6e 74 73 20  gh its contents 
79c0: 69 6e 20 73 6f 72 74 65 64 20 6f 72 64 65 72 2e  in sorted order.
79d0: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56  .*/.int sqlite3V
79e0: 64 62 65 53 6f 72 74 65 72 52 65 77 69 6e 64 28  dbeSorterRewind(
79f0: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 63 6f 6e  sqlite3 *db, con
7a00: 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70  st VdbeCursor *p
7a10: 43 73 72 2c 20 69 6e 74 20 2a 70 62 45 6f 66 29  Csr, int *pbEof)
7a20: 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a  {.  VdbeSorter *
7a30: 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e  pSorter = pCsr->
7a40: 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 72  pSorter;.  int r
7a50: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
7a60: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
7a70: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 73  turn code */.  s
7a80: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 54 65  qlite3_file *pTe
7a90: 6d 70 32 20 3d 20 30 3b 20 20 20 20 20 20 20 2f  mp2 = 0;       /
7aa0: 2a 20 53 65 63 6f 6e 64 20 74 65 6d 70 20 66 69  * Second temp fi
7ab0: 6c 65 20 74 6f 20 75 73 65 20 2a 2f 0a 20 20 69  le to use */.  i
7ac0: 36 34 20 69 57 72 69 74 65 32 20 3d 20 30 3b 20  64 iWrite2 = 0; 
7ad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7ae0: 2a 20 57 72 69 74 65 20 6f 66 66 73 65 74 20 66  * Write offset f
7af0: 6f 72 20 70 54 65 6d 70 32 20 2a 2f 0a 20 20 69  or pTemp2 */.  i
7b00: 6e 74 20 6e 49 74 65 72 3b 20 20 20 20 20 20 20  nt nIter;       
7b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7b20: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 69 74 65 72  * Number of iter
7b30: 61 74 6f 72 73 20 75 73 65 64 20 2a 2f 0a 20 20  ators used */.  
7b40: 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20  int nByte;      
7b50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7b60: 2f 2a 20 42 79 74 65 73 20 6f 66 20 73 70 61 63  /* Bytes of spac
7b70: 65 20 72 65 71 75 69 72 65 64 20 66 6f 72 20 61  e required for a
7b80: 49 74 65 72 2f 61 54 72 65 65 20 2a 2f 0a 20 20  Iter/aTree */.  
7b90: 69 6e 74 20 4e 20 3d 20 32 3b 20 20 20 20 20 20  int N = 2;      
7ba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7bb0: 2f 2a 20 50 6f 77 65 72 20 6f 66 20 32 20 3e 3d  /* Power of 2 >=
7bc0: 20 6e 49 74 65 72 20 2a 2f 0a 0a 20 20 61 73 73   nIter */..  ass
7bd0: 65 72 74 28 20 70 53 6f 72 74 65 72 20 29 3b 0a  ert( pSorter );.
7be0: 0a 20 20 2f 2a 20 49 66 20 6e 6f 20 64 61 74 61  .  /* If no data
7bf0: 20 68 61 73 20 62 65 65 6e 20 77 72 69 74 74 65   has been writte
7c00: 6e 20 74 6f 20 64 69 73 6b 2c 20 74 68 65 6e 20  n to disk, then 
7c10: 64 6f 20 6e 6f 74 20 64 6f 20 73 6f 20 6e 6f 77  do not do so now
7c20: 2e 20 49 6e 73 74 65 61 64 2c 0a 20 20 2a 2a 20  . Instead,.  ** 
7c30: 73 6f 72 74 20 74 68 65 20 56 64 62 65 53 6f 72  sort the VdbeSor
7c40: 74 65 72 2e 70 52 65 63 6f 72 64 20 6c 69 73 74  ter.pRecord list
7c50: 2e 20 54 68 65 20 76 64 62 65 20 6c 61 79 65 72  . The vdbe layer
7c60: 20 77 69 6c 6c 20 72 65 61 64 20 64 61 74 61 20   will read data 
7c70: 64 69 72 65 63 74 6c 79 0a 20 20 2a 2a 20 66 72  directly.  ** fr
7c80: 6f 6d 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79  om the in-memory
7c90: 20 6c 69 73 74 2e 20 20 2a 2f 0a 20 20 69 66 28   list.  */.  if(
7ca0: 20 70 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 3d 3d   pSorter->nPMA==
7cb0: 30 20 29 7b 0a 20 20 20 20 2a 70 62 45 6f 66 20  0 ){.    *pbEof 
7cc0: 3d 20 21 70 53 6f 72 74 65 72 2d 3e 70 52 65 63  = !pSorter->pRec
7cd0: 6f 72 64 3b 0a 20 20 20 20 61 73 73 65 72 74 28  ord;.    assert(
7ce0: 20 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 3d   pSorter->aTree=
7cf0: 3d 30 20 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  =0 );.    return
7d00: 20 76 64 62 65 53 6f 72 74 65 72 53 6f 72 74 28   vdbeSorterSort(
7d10: 70 43 73 72 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  pCsr);.  }..  /*
7d20: 20 57 72 69 74 65 20 74 68 65 20 63 75 72 72 65   Write the curre
7d30: 6e 74 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73  nt in-memory lis
7d40: 74 20 74 6f 20 61 20 50 4d 41 2e 20 2a 2f 0a 20  t to a PMA. */. 
7d50: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
7d60: 4c 69 73 74 54 6f 50 4d 41 28 64 62 2c 20 70 43  ListToPMA(db, pC
7d70: 73 72 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  sr);.  if( rc!=S
7d80: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
7d90: 6e 20 72 63 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f  n rc;..  /* Allo
7da0: 63 61 74 65 20 73 70 61 63 65 20 66 6f 72 20 61  cate space for a
7db0: 49 74 65 72 5b 5d 20 61 6e 64 20 61 54 72 65 65  Iter[] and aTree
7dc0: 5b 5d 2e 20 2a 2f 0a 20 20 6e 49 74 65 72 20 3d  []. */.  nIter =
7dd0: 20 70 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 3b 0a   pSorter->nPMA;.
7de0: 20 20 69 66 28 20 6e 49 74 65 72 3e 53 4f 52 54    if( nIter>SORT
7df0: 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55  ER_MAX_MERGE_COU
7e00: 4e 54 20 29 20 6e 49 74 65 72 20 3d 20 53 4f 52  NT ) nIter = SOR
7e10: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
7e20: 55 4e 54 3b 0a 20 20 61 73 73 65 72 74 28 20 6e  UNT;.  assert( n
7e30: 49 74 65 72 3e 30 20 29 3b 0a 20 20 77 68 69 6c  Iter>0 );.  whil
7e40: 65 28 20 4e 3c 6e 49 74 65 72 20 29 20 4e 20 2b  e( N<nIter ) N +
7e50: 3d 20 4e 3b 0a 20 20 6e 42 79 74 65 20 3d 20 4e  = N;.  nByte = N
7e60: 20 2a 20 28 73 69 7a 65 6f 66 28 69 6e 74 29 20   * (sizeof(int) 
7e70: 2b 20 73 69 7a 65 6f 66 28 56 64 62 65 53 6f 72  + sizeof(VdbeSor
7e80: 74 65 72 49 74 65 72 29 29 3b 0a 20 20 70 53 6f  terIter));.  pSo
7e90: 72 74 65 72 2d 3e 61 49 74 65 72 20 3d 20 28 56  rter->aIter = (V
7ea0: 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a 29  dbeSorterIter *)
7eb0: 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f 63 5a  sqlite3DbMallocZ
7ec0: 65 72 6f 28 64 62 2c 20 6e 42 79 74 65 29 3b 0a  ero(db, nByte);.
7ed0: 20 20 69 66 28 20 21 70 53 6f 72 74 65 72 2d 3e    if( !pSorter->
7ee0: 61 49 74 65 72 20 29 20 72 65 74 75 72 6e 20 53  aIter ) return S
7ef0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 70  QLITE_NOMEM;.  p
7f00: 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 20 3d 20  Sorter->aTree = 
7f10: 28 69 6e 74 20 2a 29 26 70 53 6f 72 74 65 72 2d  (int *)&pSorter-
7f20: 3e 61 49 74 65 72 5b 4e 5d 3b 0a 20 20 70 53 6f  >aIter[N];.  pSo
7f30: 72 74 65 72 2d 3e 6e 54 72 65 65 20 3d 20 4e 3b  rter->nTree = N;
7f40: 0a 0a 20 20 64 6f 20 7b 0a 20 20 20 20 69 6e 74  ..  do {.    int
7f50: 20 69 4e 65 77 3b 20 20 20 20 20 20 20 20 20 20   iNew;          
7f60: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
7f70: 64 65 78 20 6f 66 20 6e 65 77 2c 20 6d 65 72 67  dex of new, merg
7f80: 65 64 2c 20 50 4d 41 20 2a 2f 0a 0a 20 20 20 20  ed, PMA */..    
7f90: 66 6f 72 28 69 4e 65 77 3d 30 3b 20 0a 20 20 20  for(iNew=0; .   
7fa0: 20 20 20 20 20 72 63 3d 3d 53 51 4c 49 54 45 5f       rc==SQLITE_
7fb0: 4f 4b 20 26 26 20 69 4e 65 77 2a 53 4f 52 54 45  OK && iNew*SORTE
7fc0: 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
7fd0: 54 3c 70 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 3b  T<pSorter->nPMA;
7fe0: 20 0a 20 20 20 20 20 20 20 20 69 4e 65 77 2b 2b   .        iNew++
7ff0: 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 69 6e  .    ){.      in
8000: 74 20 72 63 32 3b 20 20 20 20 20 20 20 20 20 20  t rc2;          
8010: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
8020: 75 72 6e 20 63 6f 64 65 20 66 72 6f 6d 20 66 69  urn code from fi
8030: 6c 65 57 72 69 74 65 72 46 69 6e 69 73 68 28 29  leWriterFinish()
8040: 20 2a 2f 0a 20 20 20 20 20 20 46 69 6c 65 57 72   */.      FileWr
8050: 69 74 65 72 20 77 72 69 74 65 72 3b 20 20 20 20  iter writer;    
8060: 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63 74 20        /* Object 
8070: 75 73 65 64 20 74 6f 20 77 72 69 74 65 20 74 6f  used to write to
8080: 20 64 69 73 6b 20 2a 2f 0a 20 20 20 20 20 20 69   disk */.      i
8090: 36 34 20 6e 57 72 69 74 65 3b 20 20 20 20 20 20  64 nWrite;      
80a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
80b0: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e  mber of bytes in
80c0: 20 6e 65 77 20 50 4d 41 20 2a 2f 0a 0a 20 20 20   new PMA */..   
80d0: 20 20 20 6d 65 6d 73 65 74 28 26 77 72 69 74 65     memset(&write
80e0: 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 46 69 6c  r, 0, sizeof(Fil
80f0: 65 57 72 69 74 65 72 29 29 3b 0a 0a 20 20 20 20  eWriter));..    
8100: 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20 61 72    /* If there ar
8110: 65 20 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52  e SORTER_MAX_MER
8120: 47 45 5f 43 4f 55 4e 54 20 6f 72 20 6c 65 73 73  GE_COUNT or less
8130: 20 50 4d 41 73 20 69 6e 20 66 69 6c 65 20 70 54   PMAs in file pT
8140: 65 6d 70 31 2c 0a 20 20 20 20 20 20 2a 2a 20 69  emp1,.      ** i
8150: 6e 69 74 69 61 6c 69 7a 65 20 61 6e 20 69 74 65  nitialize an ite
8160: 72 61 74 6f 72 20 66 6f 72 20 65 61 63 68 20 6f  rator for each o
8170: 66 20 74 68 65 6d 20 61 6e 64 20 62 72 65 61 6b  f them and break
8180: 20 6f 75 74 20 6f 66 20 74 68 65 20 6c 6f 6f 70   out of the loop
8190: 2e 0a 20 20 20 20 20 20 2a 2a 20 54 68 65 73 65  ..      ** These
81a0: 20 69 74 65 72 61 74 6f 72 73 20 77 69 6c 6c 20   iterators will 
81b0: 62 65 20 69 6e 63 72 65 6d 65 6e 74 61 6c 6c 79  be incrementally
81c0: 20 6d 65 72 67 65 64 20 61 73 20 74 68 65 20 56   merged as the V
81d0: 44 42 45 20 6c 61 79 65 72 20 63 61 6c 6c 73 0a  DBE layer calls.
81e0: 20 20 20 20 20 20 2a 2a 20 73 71 6c 69 74 65 33        ** sqlite3
81f0: 56 64 62 65 53 6f 72 74 65 72 4e 65 78 74 28 29  VdbeSorterNext()
8200: 2e 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20  ..      **.     
8210: 20 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 69   ** Otherwise, i
8220: 66 20 70 54 65 6d 70 31 20 63 6f 6e 74 61 69 6e  f pTemp1 contain
8230: 73 20 6d 6f 72 65 20 74 68 61 6e 20 53 4f 52 54  s more than SORT
8240: 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55  ER_MAX_MERGE_COU
8250: 4e 54 20 50 4d 41 73 2c 0a 20 20 20 20 20 20 2a  NT PMAs,.      *
8260: 2a 20 69 6e 69 74 69 61 6c 69 7a 65 20 69 6e 74  * initialize int
8270: 65 72 61 74 6f 72 73 20 66 6f 72 20 53 4f 52 54  erators for SORT
8280: 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55  ER_MAX_MERGE_COU
8290: 4e 54 20 6f 66 20 74 68 65 6d 2e 20 54 68 65 73  NT of them. Thes
82a0: 65 20 50 4d 41 73 0a 20 20 20 20 20 20 2a 2a 20  e PMAs.      ** 
82b0: 61 72 65 20 6d 65 72 67 65 64 20 69 6e 74 6f 20  are merged into 
82c0: 61 20 73 69 6e 67 6c 65 20 50 4d 41 20 74 68 61  a single PMA tha
82d0: 74 20 69 73 20 77 72 69 74 74 65 6e 20 74 6f 20  t is written to 
82e0: 66 69 6c 65 20 70 54 65 6d 70 32 2e 0a 20 20 20  file pTemp2..   
82f0: 20 20 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d     */.      rc =
8300: 20 76 64 62 65 53 6f 72 74 65 72 49 6e 69 74 4d   vdbeSorterInitM
8310: 65 72 67 65 28 64 62 2c 20 70 43 73 72 2c 20 26  erge(db, pCsr, &
8320: 6e 57 72 69 74 65 29 3b 0a 20 20 20 20 20 20 61  nWrite);.      a
8330: 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54  ssert( rc!=SQLIT
8340: 45 5f 4f 4b 20 7c 7c 20 70 53 6f 72 74 65 72 2d  E_OK || pSorter-
8350: 3e 61 49 74 65 72 5b 20 70 53 6f 72 74 65 72 2d  >aIter[ pSorter-
8360: 3e 61 54 72 65 65 5b 31 5d 20 5d 2e 70 46 69 6c  >aTree[1] ].pFil
8370: 65 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  e );.      if( r
8380: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20  c!=SQLITE_OK || 
8390: 70 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 3c 3d 53  pSorter->nPMA<=S
83a0: 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f  ORTER_MAX_MERGE_
83b0: 43 4f 55 4e 54 20 29 7b 0a 20 20 20 20 20 20 20  COUNT ){.       
83c0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
83d0: 0a 20 20 20 20 20 20 2f 2a 20 4f 70 65 6e 20 74  .      /* Open t
83e0: 68 65 20 73 65 63 6f 6e 64 20 74 65 6d 70 20 66  he second temp f
83f0: 69 6c 65 2c 20 69 66 20 69 74 20 69 73 20 6e 6f  ile, if it is no
8400: 74 20 61 6c 72 65 61 64 79 20 6f 70 65 6e 2e 20  t already open. 
8410: 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 70 54 65  */.      if( pTe
8420: 6d 70 32 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  mp2==0 ){.      
8430: 20 20 61 73 73 65 72 74 28 20 69 57 72 69 74 65    assert( iWrite
8440: 32 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 20 20  2==0 );.        
8450: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4f  rc = vdbeSorterO
8460: 70 65 6e 54 65 6d 70 46 69 6c 65 28 64 62 2c 20  penTempFile(db, 
8470: 26 70 54 65 6d 70 32 29 3b 0a 20 20 20 20 20 20  &pTemp2);.      
8480: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
8490: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20  _OK ){.         
84a0: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
84b0: 45 78 74 65 6e 64 46 69 6c 65 28 70 54 65 6d 70  ExtendFile(pTemp
84c0: 32 2c 20 70 53 6f 72 74 65 72 2d 3e 69 57 72 69  2, pSorter->iWri
84d0: 74 65 4f 66 66 29 3b 0a 20 20 20 20 20 20 20 20  teOff);.        
84e0: 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  }.      }..     
84f0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
8500: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e  OK ){.        in
8510: 74 20 62 45 6f 66 20 3d 20 30 3b 0a 20 20 20 20  t bEof = 0;.    
8520: 20 20 20 20 66 69 6c 65 57 72 69 74 65 72 49 6e      fileWriterIn
8530: 69 74 28 64 62 2c 20 70 54 65 6d 70 32 2c 20 26  it(db, pTemp2, &
8540: 77 72 69 74 65 72 2c 20 69 57 72 69 74 65 32 29  writer, iWrite2)
8550: 3b 0a 20 20 20 20 20 20 20 20 66 69 6c 65 57 72  ;.        fileWr
8560: 69 74 65 72 57 72 69 74 65 56 61 72 69 6e 74 28  iterWriteVarint(
8570: 26 77 72 69 74 65 72 2c 20 6e 57 72 69 74 65 29  &writer, nWrite)
8580: 3b 0a 20 20 20 20 20 20 20 20 77 68 69 6c 65 28  ;.        while(
8590: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
85a0: 26 20 62 45 6f 66 3d 3d 30 20 29 7b 0a 20 20 20  & bEof==0 ){.   
85b0: 20 20 20 20 20 20 20 56 64 62 65 53 6f 72 74 65         VdbeSorte
85c0: 72 49 74 65 72 20 2a 70 49 74 65 72 20 3d 20 26  rIter *pIter = &
85d0: 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b 20  pSorter->aIter[ 
85e0: 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 31  pSorter->aTree[1
85f0: 5d 20 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 61  ] ];.          a
8600: 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e 70 46  ssert( pIter->pF
8610: 69 6c 65 20 29 3b 0a 0a 20 20 20 20 20 20 20 20  ile );..        
8620: 20 20 66 69 6c 65 57 72 69 74 65 72 57 72 69 74    fileWriterWrit
8630: 65 56 61 72 69 6e 74 28 26 77 72 69 74 65 72 2c  eVarint(&writer,
8640: 20 70 49 74 65 72 2d 3e 6e 4b 65 79 29 3b 0a 20   pIter->nKey);. 
8650: 20 20 20 20 20 20 20 20 20 66 69 6c 65 57 72 69           fileWri
8660: 74 65 72 57 72 69 74 65 28 26 77 72 69 74 65 72  terWrite(&writer
8670: 2c 20 70 49 74 65 72 2d 3e 61 4b 65 79 2c 20 70  , pIter->aKey, p
8680: 49 74 65 72 2d 3e 6e 4b 65 79 29 3b 0a 20 20 20  Iter->nKey);.   
8690: 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69         rc = sqli
86a0: 74 65 33 56 64 62 65 53 6f 72 74 65 72 4e 65 78  te3VdbeSorterNex
86b0: 74 28 64 62 2c 20 70 43 73 72 2c 20 26 62 45 6f  t(db, pCsr, &bEo
86c0: 66 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  f);.        }.  
86d0: 20 20 20 20 20 20 72 63 32 20 3d 20 66 69 6c 65        rc2 = file
86e0: 57 72 69 74 65 72 46 69 6e 69 73 68 28 64 62 2c  WriterFinish(db,
86f0: 20 26 77 72 69 74 65 72 2c 20 26 69 57 72 69 74   &writer, &iWrit
8700: 65 32 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  e2);.        if(
8710: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
8720: 20 72 63 20 3d 20 72 63 32 3b 0a 20 20 20 20 20   rc = rc2;.     
8730: 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66   }.    }..    if
8740: 28 20 70 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 3c  ( pSorter->nPMA<
8750: 3d 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47  =SORTER_MAX_MERG
8760: 45 5f 43 4f 55 4e 54 20 29 7b 0a 20 20 20 20 20  E_COUNT ){.     
8770: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 65 6c 73   break;.    }els
8780: 65 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  e{.      sqlite3
8790: 5f 66 69 6c 65 20 2a 70 54 6d 70 20 3d 20 70 53  _file *pTmp = pS
87a0: 6f 72 74 65 72 2d 3e 70 54 65 6d 70 31 3b 0a 20  orter->pTemp1;. 
87b0: 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6e 50       pSorter->nP
87c0: 4d 41 20 3d 20 69 4e 65 77 3b 0a 20 20 20 20 20  MA = iNew;.     
87d0: 20 70 53 6f 72 74 65 72 2d 3e 70 54 65 6d 70 31   pSorter->pTemp1
87e0: 20 3d 20 70 54 65 6d 70 32 3b 0a 20 20 20 20 20   = pTemp2;.     
87f0: 20 70 54 65 6d 70 32 20 3d 20 70 54 6d 70 3b 0a   pTemp2 = pTmp;.
8800: 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 69        pSorter->i
8810: 57 72 69 74 65 4f 66 66 20 3d 20 69 57 72 69 74  WriteOff = iWrit
8820: 65 32 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65  e2;.      pSorte
8830: 72 2d 3e 69 52 65 61 64 4f 66 66 20 3d 20 30 3b  r->iReadOff = 0;
8840: 0a 20 20 20 20 20 20 69 57 72 69 74 65 32 20 3d  .      iWrite2 =
8850: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 77 68 69   0;.    }.  }whi
8860: 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  le( rc==SQLITE_O
8870: 4b 20 29 3b 0a 0a 20 20 69 66 28 20 70 54 65 6d  K );..  if( pTem
8880: 70 32 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  p2 ){.    sqlite
8890: 33 4f 73 43 6c 6f 73 65 46 72 65 65 28 70 54 65  3OsCloseFree(pTe
88a0: 6d 70 32 29 3b 0a 20 20 7d 0a 20 20 2a 70 62 45  mp2);.  }.  *pbE
88b0: 6f 66 20 3d 20 28 70 53 6f 72 74 65 72 2d 3e 61  of = (pSorter->a
88c0: 49 74 65 72 5b 70 53 6f 72 74 65 72 2d 3e 61 54  Iter[pSorter->aT
88d0: 72 65 65 5b 31 5d 5d 2e 70 46 69 6c 65 3d 3d 30  ree[1]].pFile==0
88e0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
88f0: 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65  }../*.** Advance
8900: 20 74 6f 20 74 68 65 20 6e 65 78 74 20 65 6c 65   to the next ele
8910: 6d 65 6e 74 20 69 6e 20 74 68 65 20 73 6f 72 74  ment in the sort
8920: 65 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  er..*/.int sqlit
8930: 65 33 56 64 62 65 53 6f 72 74 65 72 4e 65 78 74  e3VdbeSorterNext
8940: 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 63 6f  (sqlite3 *db, co
8950: 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a  nst VdbeCursor *
8960: 70 43 73 72 2c 20 69 6e 74 20 2a 70 62 45 6f 66  pCsr, int *pbEof
8970: 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20  ){.  VdbeSorter 
8980: 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d  *pSorter = pCsr-
8990: 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20  >pSorter;.  int 
89a0: 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rc;             
89b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
89c0: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20  eturn code */.. 
89d0: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 61 54   if( pSorter->aT
89e0: 72 65 65 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  ree ){.    int i
89f0: 50 72 65 76 20 3d 20 70 53 6f 72 74 65 72 2d 3e  Prev = pSorter->
8a00: 61 54 72 65 65 5b 31 5d 3b 2f 2a 20 49 6e 64 65  aTree[1];/* Inde
8a10: 78 20 6f 66 20 69 74 65 72 61 74 6f 72 20 74 6f  x of iterator to
8a20: 20 61 64 76 61 6e 63 65 20 2a 2f 0a 20 20 20 20   advance */.    
8a30: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 49  rc = vdbeSorterI
8a40: 74 65 72 4e 65 78 74 28 64 62 2c 20 26 70 53 6f  terNext(db, &pSo
8a50: 72 74 65 72 2d 3e 61 49 74 65 72 5b 69 50 72 65  rter->aIter[iPre
8a60: 76 5d 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d  v]);.    if( rc=
8a70: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
8a80: 20 20 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20      int i;      
8a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8aa0: 2f 2a 20 49 6e 64 65 78 20 6f 66 20 61 54 72 65  /* Index of aTre
8ab0: 65 5b 5d 20 74 6f 20 72 65 63 61 6c 63 75 6c 61  e[] to recalcula
8ac0: 74 65 20 2a 2f 0a 20 20 20 20 20 20 56 64 62 65  te */.      Vdbe
8ad0: 53 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74 65  SorterIter *pIte
8ae0: 72 31 3b 20 20 20 20 20 2f 2a 20 46 69 72 73 74  r1;     /* First
8af0: 20 69 74 65 72 61 74 6f 72 20 74 6f 20 63 6f 6d   iterator to com
8b00: 70 61 72 65 20 2a 2f 0a 20 20 20 20 20 20 56 64  pare */.      Vd
8b10: 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70 49  beSorterIter *pI
8b20: 74 65 72 32 3b 20 20 20 20 20 2f 2a 20 53 65 63  ter2;     /* Sec
8b30: 6f 6e 64 20 69 74 65 72 61 74 6f 72 20 74 6f 20  ond iterator to 
8b40: 63 6f 6d 70 61 72 65 20 2a 2f 0a 20 20 20 20 20  compare */.     
8b50: 20 75 38 20 2a 70 4b 65 79 32 3b 20 20 20 20 20   u8 *pKey2;     
8b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8b70: 54 6f 20 70 49 74 65 72 32 2d 3e 61 4b 65 79 2c  To pIter2->aKey,
8b80: 20 6f 72 20 30 20 69 66 20 72 65 63 6f 72 64 20   or 0 if record 
8b90: 63 61 63 68 65 64 20 2a 2f 0a 0a 20 20 20 20 20  cached */..     
8ba0: 20 2f 2a 20 46 69 6e 64 20 74 68 65 20 66 69 72   /* Find the fir
8bb0: 73 74 20 74 77 6f 20 69 74 65 72 61 74 6f 72 73  st two iterators
8bc0: 20 74 6f 20 63 6f 6d 70 61 72 65 2e 20 54 68 65   to compare. The
8bd0: 20 6f 6e 65 20 74 68 61 74 20 77 61 73 20 6a 75   one that was ju
8be0: 73 74 0a 20 20 20 20 20 20 2a 2a 20 61 64 76 61  st.      ** adva
8bf0: 6e 63 65 64 20 28 69 50 72 65 76 29 20 61 6e 64  nced (iPrev) and
8c00: 20 74 68 65 20 6f 6e 65 20 6e 65 78 74 20 74 6f   the one next to
8c10: 20 69 74 20 69 6e 20 74 68 65 20 61 72 72 61 79   it in the array
8c20: 2e 20 20 2a 2f 0a 20 20 20 20 20 20 70 49 74 65  .  */.      pIte
8c30: 72 31 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61  r1 = &pSorter->a
8c40: 49 74 65 72 5b 28 69 50 72 65 76 20 26 20 30 78  Iter[(iPrev & 0x
8c50: 46 46 46 45 29 5d 3b 0a 20 20 20 20 20 20 70 49  FFFE)];.      pI
8c60: 74 65 72 32 20 3d 20 26 70 53 6f 72 74 65 72 2d  ter2 = &pSorter-
8c70: 3e 61 49 74 65 72 5b 28 69 50 72 65 76 20 7c 20  >aIter[(iPrev | 
8c80: 30 78 30 30 30 31 29 5d 3b 0a 20 20 20 20 20 20  0x0001)];.      
8c90: 70 4b 65 79 32 20 3d 20 70 49 74 65 72 32 2d 3e  pKey2 = pIter2->
8ca0: 61 4b 65 79 3b 0a 0a 20 20 20 20 20 20 66 6f 72  aKey;..      for
8cb0: 28 69 3d 28 70 53 6f 72 74 65 72 2d 3e 6e 54 72  (i=(pSorter->nTr
8cc0: 65 65 2b 69 50 72 65 76 29 2f 32 3b 20 69 3e 30  ee+iPrev)/2; i>0
8cd0: 3b 20 69 3d 69 2f 32 29 7b 0a 20 20 20 20 20 20  ; i=i/2){.      
8ce0: 20 20 2f 2a 20 43 6f 6d 70 61 72 65 20 70 49 74    /* Compare pIt
8cf0: 65 72 31 20 61 6e 64 20 70 49 74 65 72 32 2e 20  er1 and pIter2. 
8d00: 53 74 6f 72 65 20 74 68 65 20 72 65 73 75 6c 74  Store the result
8d10: 20 69 6e 20 76 61 72 69 61 62 6c 65 20 69 52 65   in variable iRe
8d20: 73 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20 69 6e  s. */.        in
8d30: 74 20 69 52 65 73 3b 0a 20 20 20 20 20 20 20 20  t iRes;.        
8d40: 69 66 28 20 70 49 74 65 72 31 2d 3e 70 46 69 6c  if( pIter1->pFil
8d50: 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  e==0 ){.        
8d60: 20 20 69 52 65 73 20 3d 20 2b 31 3b 0a 20 20 20    iRes = +1;.   
8d70: 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70       }else if( p
8d80: 49 74 65 72 32 2d 3e 70 46 69 6c 65 3d 3d 30 20  Iter2->pFile==0 
8d90: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 52 65  ){.          iRe
8da0: 73 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20 20 20  s = -1;.        
8db0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20  }else{.         
8dc0: 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61   vdbeSorterCompa
8dd0: 72 65 28 70 43 73 72 2c 20 30 2c 20 0a 20 20 20  re(pCsr, 0, .   
8de0: 20 20 20 20 20 20 20 20 20 20 20 70 49 74 65 72             pIter
8df0: 31 2d 3e 61 4b 65 79 2c 20 70 49 74 65 72 31 2d  1->aKey, pIter1-
8e00: 3e 6e 4b 65 79 2c 20 70 4b 65 79 32 2c 20 70 49  >nKey, pKey2, pI
8e10: 74 65 72 32 2d 3e 6e 4b 65 79 2c 20 26 69 52 65  ter2->nKey, &iRe
8e20: 73 0a 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20  s.          );. 
8e30: 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20         }..      
8e40: 20 20 2f 2a 20 49 66 20 70 49 74 65 72 31 20 63    /* If pIter1 c
8e50: 6f 6e 74 61 69 6e 65 64 20 74 68 65 20 73 6d 61  ontained the sma
8e60: 6c 6c 65 72 20 76 61 6c 75 65 2c 20 73 65 74 20  ller value, set 
8e70: 61 54 72 65 65 5b 69 5d 20 74 6f 20 69 74 73 20  aTree[i] to its 
8e80: 69 6e 64 65 78 2e 0a 20 20 20 20 20 20 20 20 2a  index..        *
8e90: 2a 20 54 68 65 6e 20 73 65 74 20 70 49 74 65 72  * Then set pIter
8ea0: 32 20 74 6f 20 74 68 65 20 6e 65 78 74 20 69 74  2 to the next it
8eb0: 65 72 61 74 6f 72 20 74 6f 20 63 6f 6d 70 61 72  erator to compar
8ec0: 65 20 74 6f 20 70 49 74 65 72 31 2e 20 49 6e 20  e to pIter1. In 
8ed0: 74 68 69 73 0a 20 20 20 20 20 20 20 20 2a 2a 20  this.        ** 
8ee0: 63 61 73 65 20 74 68 65 72 65 20 69 73 20 6e 6f  case there is no
8ef0: 20 63 61 63 68 65 20 6f 66 20 70 49 74 65 72 32   cache of pIter2
8f00: 20 69 6e 20 70 53 6f 72 74 65 72 2d 3e 70 55 6e   in pSorter->pUn
8f10: 70 61 63 6b 65 64 2c 20 73 6f 20 73 65 74 0a 20  packed, so set. 
8f20: 20 20 20 20 20 20 20 2a 2a 20 70 4b 65 79 32 20         ** pKey2 
8f30: 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20  to point to the 
8f40: 72 65 63 6f 72 64 20 62 65 6c 6f 6e 67 69 6e 67  record belonging
8f50: 20 74 6f 20 70 49 74 65 72 32 2e 0a 20 20 20 20   to pIter2..    
8f60: 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20 2a      **.        *
8f70: 2a 20 41 6c 74 65 72 6e 61 74 69 76 65 6c 79 2c  * Alternatively,
8f80: 20 69 66 20 70 49 74 65 72 32 20 63 6f 6e 74 61   if pIter2 conta
8f90: 69 6e 73 20 74 68 65 20 73 6d 61 6c 6c 65 72 20  ins the smaller 
8fa0: 6f 66 20 74 68 65 20 74 77 6f 20 76 61 6c 75 65  of the two value
8fb0: 73 2c 0a 20 20 20 20 20 20 20 20 2a 2a 20 73 65  s,.        ** se
8fc0: 74 20 61 54 72 65 65 5b 69 5d 20 74 6f 20 69 74  t aTree[i] to it
8fd0: 73 20 69 6e 64 65 78 20 61 6e 64 20 75 70 64 61  s index and upda
8fe0: 74 65 20 70 49 74 65 72 31 2e 20 49 66 20 76 64  te pIter1. If vd
8ff0: 62 65 53 6f 72 74 65 72 43 6f 6d 70 61 72 65 28  beSorterCompare(
9000: 29 0a 20 20 20 20 20 20 20 20 2a 2a 20 77 61 73  ).        ** was
9010: 20 61 63 74 75 61 6c 6c 79 20 63 61 6c 6c 65 64   actually called
9020: 20 61 62 6f 76 65 2c 20 74 68 65 6e 20 70 53 6f   above, then pSo
9030: 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64 20  rter->pUnpacked 
9040: 6e 6f 77 20 63 6f 6e 74 61 69 6e 73 0a 20 20 20  now contains.   
9050: 20 20 20 20 20 2a 2a 20 61 20 76 61 6c 75 65 20       ** a value 
9060: 65 71 75 69 76 61 6c 65 6e 74 20 74 6f 20 70 49  equivalent to pI
9070: 74 65 72 32 2e 20 53 6f 20 73 65 74 20 70 4b 65  ter2. So set pKe
9080: 79 32 20 74 6f 20 4e 55 4c 4c 20 74 6f 20 70 72  y2 to NULL to pr
9090: 65 76 65 6e 74 0a 20 20 20 20 20 20 20 20 2a 2a  event.        **
90a0: 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61   vdbeSorterCompa
90b0: 72 65 28 29 20 66 72 6f 6d 20 64 65 63 6f 64 69  re() from decodi
90c0: 6e 67 20 70 49 74 65 72 32 20 61 67 61 69 6e 2e  ng pIter2 again.
90d0: 20 20 0a 20 20 20 20 20 20 20 20 2a 2a 0a 20 20    .        **.  
90e0: 20 20 20 20 20 20 2a 2a 20 49 66 20 74 68 65 20        ** If the 
90f0: 74 77 6f 20 76 61 6c 75 65 73 20 77 65 72 65 20  two values were 
9100: 65 71 75 61 6c 2c 20 74 68 65 6e 20 74 68 65 20  equal, then the 
9110: 76 61 6c 75 65 20 66 72 6f 6d 20 74 68 65 20 6f  value from the o
9120: 6c 64 65 73 74 0a 20 20 20 20 20 20 20 20 2a 2a  ldest.        **
9130: 20 50 4d 41 20 73 68 6f 75 6c 64 20 62 65 20 63   PMA should be c
9140: 6f 6e 73 69 64 65 72 65 64 20 73 6d 61 6c 6c 65  onsidered smalle
9150: 72 2e 20 54 68 65 20 56 64 62 65 53 6f 72 74 65  r. The VdbeSorte
9160: 72 2e 61 49 74 65 72 5b 5d 20 61 72 72 61 79 0a  r.aIter[] array.
9170: 20 20 20 20 20 20 20 20 2a 2a 20 69 73 20 73 6f          ** is so
9180: 72 74 65 64 20 66 72 6f 6d 20 6f 6c 64 65 73 74  rted from oldest
9190: 20 74 6f 20 6e 65 77 65 73 74 2c 20 73 6f 20 70   to newest, so p
91a0: 49 74 65 72 31 20 63 6f 6e 74 61 69 6e 73 20 6f  Iter1 contains o
91b0: 6c 64 65 72 20 76 61 6c 75 65 73 0a 20 20 20 20  lder values.    
91c0: 20 20 20 20 2a 2a 20 74 68 61 6e 20 70 49 74 65      ** than pIte
91d0: 72 32 20 69 66 66 20 28 70 49 74 65 72 31 3c 70  r2 iff (pIter1<p
91e0: 49 74 65 72 32 29 2e 20 20 2a 2f 0a 20 20 20 20  Iter2).  */.    
91f0: 20 20 20 20 69 66 28 20 69 52 65 73 3c 30 20 7c      if( iRes<0 |
9200: 7c 20 28 69 52 65 73 3d 3d 30 20 26 26 20 70 49  | (iRes==0 && pI
9210: 74 65 72 31 3c 70 49 74 65 72 32 29 20 29 7b 0a  ter1<pIter2) ){.
9220: 20 20 20 20 20 20 20 20 20 20 70 53 6f 72 74 65            pSorte
9230: 72 2d 3e 61 54 72 65 65 5b 69 5d 20 3d 20 28 69  r->aTree[i] = (i
9240: 6e 74 29 28 70 49 74 65 72 31 20 2d 20 70 53 6f  nt)(pIter1 - pSo
9250: 72 74 65 72 2d 3e 61 49 74 65 72 29 3b 0a 20 20  rter->aIter);.  
9260: 20 20 20 20 20 20 20 20 70 49 74 65 72 32 20 3d          pIter2 =
9270: 20 26 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72   &pSorter->aIter
9280: 5b 20 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65  [ pSorter->aTree
9290: 5b 69 20 5e 20 30 78 30 30 30 31 5d 20 5d 3b 0a  [i ^ 0x0001] ];.
92a0: 20 20 20 20 20 20 20 20 20 20 70 4b 65 79 32 20            pKey2 
92b0: 3d 20 70 49 74 65 72 32 2d 3e 61 4b 65 79 3b 0a  = pIter2->aKey;.
92c0: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
92d0: 20 20 20 20 20 20 20 20 20 69 66 28 20 70 49 74           if( pIt
92e0: 65 72 31 2d 3e 70 46 69 6c 65 20 29 20 70 4b 65  er1->pFile ) pKe
92f0: 79 32 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  y2 = 0;.        
9300: 20 20 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65    pSorter->aTree
9310: 5b 69 5d 20 3d 20 28 69 6e 74 29 28 70 49 74 65  [i] = (int)(pIte
9320: 72 32 20 2d 20 70 53 6f 72 74 65 72 2d 3e 61 49  r2 - pSorter->aI
9330: 74 65 72 29 3b 0a 20 20 20 20 20 20 20 20 20 20  ter);.          
9340: 70 49 74 65 72 31 20 3d 20 26 70 53 6f 72 74 65  pIter1 = &pSorte
9350: 72 2d 3e 61 49 74 65 72 5b 20 70 53 6f 72 74 65  r->aIter[ pSorte
9360: 72 2d 3e 61 54 72 65 65 5b 69 20 5e 20 30 78 30  r->aTree[i ^ 0x0
9370: 30 30 31 5d 20 5d 3b 0a 20 20 20 20 20 20 20 20  001] ];.        
9380: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
9390: 2a 70 62 45 6f 66 20 3d 20 28 70 53 6f 72 74 65  *pbEof = (pSorte
93a0: 72 2d 3e 61 49 74 65 72 5b 70 53 6f 72 74 65 72  r->aIter[pSorter
93b0: 2d 3e 61 54 72 65 65 5b 31 5d 5d 2e 70 46 69 6c  ->aTree[1]].pFil
93c0: 65 3d 3d 30 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  e==0);.    }.  }
93d0: 65 6c 73 65 7b 0a 20 20 20 20 53 6f 72 74 65 72  else{.    Sorter
93e0: 52 65 63 6f 72 64 20 2a 70 46 72 65 65 20 3d 20  Record *pFree = 
93f0: 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64  pSorter->pRecord
9400: 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70  ;.    pSorter->p
9410: 52 65 63 6f 72 64 20 3d 20 70 46 72 65 65 2d 3e  Record = pFree->
9420: 70 4e 65 78 74 3b 0a 20 20 20 20 70 46 72 65 65  pNext;.    pFree
9430: 2d 3e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20  ->pNext = 0;.   
9440: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 61 4d   if( pSorter->aM
9450: 65 6d 6f 72 79 3d 3d 30 20 29 7b 0a 20 20 20 20  emory==0 ){.    
9460: 20 20 76 64 62 65 53 6f 72 74 65 72 52 65 63 6f    vdbeSorterReco
9470: 72 64 46 72 65 65 28 64 62 2c 20 70 46 72 65 65  rdFree(db, pFree
9480: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 2a 70 62  );.    }.    *pb
9490: 45 6f 66 20 3d 20 21 70 53 6f 72 74 65 72 2d 3e  Eof = !pSorter->
94a0: 70 52 65 63 6f 72 64 3b 0a 20 20 20 20 72 63 20  pRecord;.    rc 
94b0: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d  = SQLITE_OK;.  }
94c0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
94d0: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20  ./*.** Return a 
94e0: 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 62 75 66  pointer to a buf
94f0: 66 65 72 20 6f 77 6e 65 64 20 62 79 20 74 68 65  fer owned by the
9500: 20 73 6f 72 74 65 72 20 74 68 61 74 20 63 6f 6e   sorter that con
9510: 74 61 69 6e 73 20 74 68 65 20 0a 2a 2a 20 63 75  tains the .** cu
9520: 72 72 65 6e 74 20 6b 65 79 2e 0a 2a 2f 0a 73 74  rrent key..*/.st
9530: 61 74 69 63 20 76 6f 69 64 20 2a 76 64 62 65 53  atic void *vdbeS
9540: 6f 72 74 65 72 52 6f 77 6b 65 79 28 0a 20 20 63  orterRowkey(.  c
9550: 6f 6e 73 74 20 56 64 62 65 53 6f 72 74 65 72 20  onst VdbeSorter 
9560: 2a 70 53 6f 72 74 65 72 2c 20 20 20 20 20 20 2f  *pSorter,      /
9570: 2a 20 53 6f 72 74 65 72 20 6f 62 6a 65 63 74 20  * Sorter object 
9580: 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4b 65 79 20  */.  int *pnKey 
9590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
95a0: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 53 69 7a       /* OUT: Siz
95b0: 65 20 6f 66 20 63 75 72 72 65 6e 74 20 6b 65 79  e of current key
95c0: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 29 7b 0a   in bytes */.){.
95d0: 20 20 76 6f 69 64 20 2a 70 4b 65 79 3b 0a 20 20    void *pKey;.  
95e0: 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 61 54 72  if( pSorter->aTr
95f0: 65 65 20 29 7b 0a 20 20 20 20 56 64 62 65 53 6f  ee ){.    VdbeSo
9600: 72 74 65 72 49 74 65 72 20 2a 70 49 74 65 72 3b  rterIter *pIter;
9610: 0a 20 20 20 20 70 49 74 65 72 20 3d 20 26 70 53  .    pIter = &pS
9620: 6f 72 74 65 72 2d 3e 61 49 74 65 72 5b 20 70 53  orter->aIter[ pS
9630: 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 31 5d 20  orter->aTree[1] 
9640: 5d 3b 0a 20 20 20 20 2a 70 6e 4b 65 79 20 3d 20  ];.    *pnKey = 
9650: 70 49 74 65 72 2d 3e 6e 4b 65 79 3b 0a 20 20 20  pIter->nKey;.   
9660: 20 70 4b 65 79 20 3d 20 70 49 74 65 72 2d 3e 61   pKey = pIter->a
9670: 4b 65 79 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  Key;.  }else{.  
9680: 20 20 2a 70 6e 4b 65 79 20 3d 20 70 53 6f 72 74    *pnKey = pSort
9690: 65 72 2d 3e 70 52 65 63 6f 72 64 2d 3e 6e 56 61  er->pRecord->nVa
96a0: 6c 3b 0a 20 20 20 20 70 4b 65 79 20 3d 20 70 53  l;.    pKey = pS
96b0: 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72 64 2d 3e  orter->pRecord->
96c0: 70 56 61 6c 3b 0a 20 20 7d 0a 20 20 72 65 74 75  pVal;.  }.  retu
96d0: 72 6e 20 70 4b 65 79 3b 0a 7d 0a 0a 2f 2a 0a 2a  rn pKey;.}../*.*
96e0: 2a 20 43 6f 70 79 20 74 68 65 20 63 75 72 72 65  * Copy the curre
96f0: 6e 74 20 73 6f 72 74 65 72 20 6b 65 79 20 69 6e  nt sorter key in
9700: 74 6f 20 74 68 65 20 6d 65 6d 6f 72 79 20 63 65  to the memory ce
9710: 6c 6c 20 70 4f 75 74 2e 0a 2a 2f 0a 69 6e 74 20  ll pOut..*/.int 
9720: 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65  sqlite3VdbeSorte
9730: 72 52 6f 77 6b 65 79 28 63 6f 6e 73 74 20 56 64  rRowkey(const Vd
9740: 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  beCursor *pCsr, 
9750: 4d 65 6d 20 2a 70 4f 75 74 29 7b 0a 20 20 56 64  Mem *pOut){.  Vd
9760: 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
9770: 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65  r = pCsr->pSorte
9780: 72 3b 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 3b  r;.  void *pKey;
9790: 20 69 6e 74 20 6e 4b 65 79 3b 20 20 20 20 20 20   int nKey;      
97a0: 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 6b       /* Sorter k
97b0: 65 79 20 74 6f 20 63 6f 70 79 20 69 6e 74 6f 20  ey to copy into 
97c0: 70 4f 75 74 20 2a 2f 0a 0a 20 20 70 4b 65 79 20  pOut */..  pKey 
97d0: 3d 20 76 64 62 65 53 6f 72 74 65 72 52 6f 77 6b  = vdbeSorterRowk
97e0: 65 79 28 70 53 6f 72 74 65 72 2c 20 26 6e 4b 65  ey(pSorter, &nKe
97f0: 79 29 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65  y);.  if( sqlite
9800: 33 56 64 62 65 4d 65 6d 47 72 6f 77 28 70 4f 75  3VdbeMemGrow(pOu
9810: 74 2c 20 6e 4b 65 79 2c 20 30 29 20 29 7b 0a 20  t, nKey, 0) ){. 
9820: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
9830: 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 70 4f  _NOMEM;.  }.  pO
9840: 75 74 2d 3e 6e 20 3d 20 6e 4b 65 79 3b 0a 20 20  ut->n = nKey;.  
9850: 4d 65 6d 53 65 74 54 79 70 65 46 6c 61 67 28 70  MemSetTypeFlag(p
9860: 4f 75 74 2c 20 4d 45 4d 5f 42 6c 6f 62 29 3b 0a  Out, MEM_Blob);.
9870: 20 20 6d 65 6d 63 70 79 28 70 4f 75 74 2d 3e 7a    memcpy(pOut->z
9880: 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 0a  , pKey, nKey);..
9890: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
98a0: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d  OK;.}../*.** Com
98b0: 70 61 72 65 20 74 68 65 20 6b 65 79 20 69 6e 20  pare the key in 
98c0: 6d 65 6d 6f 72 79 20 63 65 6c 6c 20 70 56 61 6c  memory cell pVal
98d0: 20 77 69 74 68 20 74 68 65 20 6b 65 79 20 74 68   with the key th
98e0: 61 74 20 74 68 65 20 73 6f 72 74 65 72 20 63 75  at the sorter cu
98f0: 72 73 6f 72 0a 2a 2a 20 70 61 73 73 65 64 20 61  rsor.** passed a
9900: 73 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75  s the first argu
9910: 6d 65 6e 74 20 63 75 72 72 65 6e 74 6c 79 20 70  ment currently p
9920: 6f 69 6e 74 73 20 74 6f 2e 20 46 6f 72 20 74 68  oints to. For th
9930: 65 20 70 75 72 70 6f 73 65 73 20 6f 66 0a 2a 2a  e purposes of.**
9940: 20 74 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2c   the comparison,
9950: 20 69 67 6e 6f 72 65 20 74 68 65 20 72 6f 77 69   ignore the rowi
9960: 64 20 66 69 65 6c 64 20 61 74 20 74 68 65 20 65  d field at the e
9970: 6e 64 20 6f 66 20 65 61 63 68 20 72 65 63 6f 72  nd of each recor
9980: 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 65  d..**.** If an e
9990: 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 72 65 74  rror occurs, ret
99a0: 75 72 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72  urn an SQLite er
99b0: 72 6f 72 20 63 6f 64 65 20 28 69 2e 65 2e 20 53  ror code (i.e. S
99c0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 2e 0a 2a 2a  QLITE_NOMEM)..**
99d0: 20 4f 74 68 65 72 77 69 73 65 2c 20 73 65 74 20   Otherwise, set 
99e0: 2a 70 52 65 73 20 74 6f 20 61 20 6e 65 67 61 74  *pRes to a negat
99f0: 69 76 65 2c 20 7a 65 72 6f 20 6f 72 20 70 6f 73  ive, zero or pos
9a00: 69 74 69 76 65 20 76 61 6c 75 65 20 69 66 20 74  itive value if t
9a10: 68 65 0a 2a 2a 20 6b 65 79 20 69 6e 20 70 56 61  he.** key in pVa
9a20: 6c 20 69 73 20 73 6d 61 6c 6c 65 72 20 74 68 61  l is smaller tha
9a30: 6e 2c 20 65 71 75 61 6c 20 74 6f 20 6f 72 20 6c  n, equal to or l
9a40: 61 72 67 65 72 20 74 68 61 6e 20 74 68 65 20 63  arger than the c
9a50: 75 72 72 65 6e 74 20 73 6f 72 74 65 72 0a 2a 2a  urrent sorter.**
9a60: 20 6b 65 79 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c   key..*/.int sql
9a70: 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 43 6f  ite3VdbeSorterCo
9a80: 6d 70 61 72 65 28 0a 20 20 63 6f 6e 73 74 20 56  mpare(.  const V
9a90: 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c  dbeCursor *pCsr,
9aa0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74           /* Sort
9ab0: 65 72 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 4d  er cursor */.  M
9ac0: 65 6d 20 2a 70 56 61 6c 2c 20 20 20 20 20 20 20  em *pVal,       
9ad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9ae0: 2a 20 56 61 6c 75 65 20 74 6f 20 63 6f 6d 70 61  * Value to compa
9af0: 72 65 20 74 6f 20 63 75 72 72 65 6e 74 20 73 6f  re to current so
9b00: 72 74 65 72 20 6b 65 79 20 2a 2f 0a 20 20 69 6e  rter key */.  in
9b10: 74 20 6e 49 67 6e 6f 72 65 2c 20 20 20 20 20 20  t nIgnore,      
9b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9b30: 20 49 67 6e 6f 72 65 20 74 68 69 73 20 6d 61 6e   Ignore this man
9b40: 79 20 66 69 65 6c 64 73 20 61 74 20 74 68 65 20  y fields at the 
9b50: 65 6e 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 52  end */.  int *pR
9b60: 65 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20  es              
9b70: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
9b80: 20 52 65 73 75 6c 74 20 6f 66 20 63 6f 6d 70 61   Result of compa
9b90: 72 69 73 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 56 64  rison */.){.  Vd
9ba0: 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
9bb0: 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65  r = pCsr->pSorte
9bc0: 72 3b 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 3b  r;.  void *pKey;
9bd0: 20 69 6e 74 20 6e 4b 65 79 3b 20 20 20 20 20 20   int nKey;      
9be0: 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 6b       /* Sorter k
9bf0: 65 79 20 74 6f 20 63 6f 6d 70 61 72 65 20 70 56  ey to compare pV
9c00: 61 6c 20 77 69 74 68 20 2a 2f 0a 0a 20 20 70 4b  al with */..  pK
9c10: 65 79 20 3d 20 76 64 62 65 53 6f 72 74 65 72 52  ey = vdbeSorterR
9c20: 6f 77 6b 65 79 28 70 53 6f 72 74 65 72 2c 20 26  owkey(pSorter, &
9c30: 6e 4b 65 79 29 3b 0a 20 20 76 64 62 65 53 6f 72  nKey);.  vdbeSor
9c40: 74 65 72 43 6f 6d 70 61 72 65 28 70 43 73 72 2c  terCompare(pCsr,
9c50: 20 6e 49 67 6e 6f 72 65 2c 20 70 56 61 6c 2d 3e   nIgnore, pVal->
9c60: 7a 2c 20 70 56 61 6c 2d 3e 6e 2c 20 70 4b 65 79  z, pVal->n, pKey
9c70: 2c 20 6e 4b 65 79 2c 20 70 52 65 73 29 3b 0a 20  , nKey, pRes);. 
9c80: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
9c90: 4b 3b 0a 7d 0a                                   K;.}.