/ Hex Artifact Content
Login

Artifact 72290f12428973c2c6b9d4f95ad0a7c8181e1280:


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 52 65 63 6f 72 64 43 6f 6d  s */.  RecordCom
12d0: 70 61 72 65 20 78 52 65 63 6f 72 64 43 6f 6d 70  pare xRecordComp
12e0: 61 72 65 3b 20 20 20 2f 2a 20 52 65 63 6f 72 64  are;   /* Record
12f0: 20 63 6f 6d 70 61 72 65 20 66 75 6e 63 74 69 6f   compare functio
1300: 6e 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54  n */.};../*.** T
1310: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 79 70  he following typ
1320: 65 20 69 73 20 61 6e 20 69 74 65 72 61 74 6f 72  e is an iterator
1330: 20 66 6f 72 20 61 20 50 4d 41 2e 20 49 74 20 63   for a PMA. It c
1340: 61 63 68 65 73 20 74 68 65 20 63 75 72 72 65 6e  aches the curren
1350: 74 20 6b 65 79 20 69 6e 20 0a 2a 2a 20 76 61 72  t key in .** var
1360: 69 61 62 6c 65 73 20 6e 4b 65 79 2f 61 4b 65 79  iables nKey/aKey
1370: 2e 20 49 66 20 74 68 65 20 69 74 65 72 61 74 6f  . If the iterato
1380: 72 20 69 73 20 61 74 20 45 4f 46 2c 20 70 46 69  r is at EOF, pFi
1390: 6c 65 3d 3d 30 2e 0a 2a 2f 0a 73 74 72 75 63 74  le==0..*/.struct
13a0: 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20   VdbeSorterIter 
13b0: 7b 0a 20 20 69 36 34 20 69 52 65 61 64 4f 66 66  {.  i64 iReadOff
13c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
13d0: 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 72      /* Current r
13e0: 65 61 64 20 6f 66 66 73 65 74 20 2a 2f 0a 20 20  ead offset */.  
13f0: 69 36 34 20 69 45 6f 66 3b 20 20 20 20 20 20 20  i64 iEof;       
1400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1410: 2f 2a 20 31 20 62 79 74 65 20 70 61 73 74 20 45  /* 1 byte past E
1420: 4f 46 20 66 6f 72 20 74 68 69 73 20 69 74 65 72  OF for this iter
1430: 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 41  ator */.  int nA
1440: 6c 6c 6f 63 3b 20 20 20 20 20 20 20 20 20 20 20  lloc;           
1450: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74            /* Byt
1460: 65 73 20 6f 66 20 73 70 61 63 65 20 61 74 20 61  es of space at a
1470: 41 6c 6c 6f 63 20 2a 2f 0a 20 20 69 6e 74 20 6e  Alloc */.  int n
1480: 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  Key;            
1490: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
14a0: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e  mber of bytes in
14b0: 20 6b 65 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65   key */.  sqlite
14c0: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20  3_file *pFile;  
14d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c            /* Fil
14e0: 65 20 69 74 65 72 61 74 6f 72 20 69 73 20 72 65  e iterator is re
14f0: 61 64 69 6e 67 20 66 72 6f 6d 20 2a 2f 0a 20 20  ading from */.  
1500: 75 38 20 2a 61 41 6c 6c 6f 63 3b 20 20 20 20 20  u8 *aAlloc;     
1510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1520: 2f 2a 20 41 6c 6c 6f 63 61 74 65 64 20 73 70 61  /* Allocated spa
1530: 63 65 20 2a 2f 0a 20 20 75 38 20 2a 61 4b 65 79  ce */.  u8 *aKey
1540: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1550: 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74          /* Point
1560: 65 72 20 74 6f 20 63 75 72 72 65 6e 74 20 6b 65  er to current ke
1570: 79 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75 66 66  y */.  u8 *aBuff
1580: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  er;             
1590: 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e         /* Curren
15a0: 74 20 72 65 61 64 20 62 75 66 66 65 72 20 2a 2f  t read buffer */
15b0: 0a 20 20 69 6e 74 20 6e 42 75 66 66 65 72 3b 20  .  int nBuffer; 
15c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15d0: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 72 65     /* Size of re
15e0: 61 64 20 62 75 66 66 65 72 20 69 6e 20 62 79 74  ad buffer in byt
15f0: 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  es */.};../*.** 
1600: 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74  An instance of t
1610: 68 69 73 20 73 74 72 75 63 74 75 72 65 20 69 73  his structure is
1620: 20 75 73 65 64 20 74 6f 20 6f 72 67 61 6e 69 7a   used to organiz
1630: 65 20 74 68 65 20 73 74 72 65 61 6d 20 6f 66 20  e the stream of 
1640: 72 65 63 6f 72 64 73 0a 2a 2a 20 62 65 69 6e 67  records.** being
1650: 20 77 72 69 74 74 65 6e 20 74 6f 20 66 69 6c 65   written to file
1660: 73 20 62 79 20 74 68 65 20 6d 65 72 67 65 2d 73  s by the merge-s
1670: 6f 72 74 20 63 6f 64 65 20 69 6e 74 6f 20 61 6c  ort code into al
1680: 69 67 6e 65 64 2c 20 70 61 67 65 2d 73 69 7a 65  igned, page-size
1690: 64 0a 2a 2a 20 62 6c 6f 63 6b 73 2e 20 20 44 6f  d.** blocks.  Do
16a0: 69 6e 67 20 61 6c 6c 20 49 2f 4f 20 69 6e 20 61  ing all I/O in a
16b0: 6c 69 67 6e 65 64 20 70 61 67 65 2d 73 69 7a 65  ligned page-size
16c0: 64 20 62 6c 6f 63 6b 73 20 68 65 6c 70 73 20 49  d blocks helps I
16d0: 2f 4f 20 74 6f 20 67 6f 0a 2a 2a 20 66 61 73 74  /O to go.** fast
16e0: 65 72 20 6f 6e 20 6d 61 6e 79 20 6f 70 65 72 61  er on many opera
16f0: 74 69 6e 67 20 73 79 73 74 65 6d 73 2e 0a 2a 2f  ting systems..*/
1700: 0a 73 74 72 75 63 74 20 46 69 6c 65 57 72 69 74  .struct FileWrit
1710: 65 72 20 7b 0a 20 20 69 6e 74 20 65 46 57 45 72  er {.  int eFWEr
1720: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
1730: 20 20 20 20 20 20 20 2f 2a 20 4e 6f 6e 2d 7a 65         /* Non-ze
1740: 72 6f 20 69 66 20 69 6e 20 61 6e 20 65 72 72 6f  ro if in an erro
1750: 72 20 73 74 61 74 65 20 2a 2f 0a 20 20 75 38 20  r state */.  u8 
1760: 2a 61 42 75 66 66 65 72 3b 20 20 20 20 20 20 20  *aBuffer;       
1770: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1780: 50 6f 69 6e 74 65 72 20 74 6f 20 77 72 69 74 65  Pointer to write
1790: 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74   buffer */.  int
17a0: 20 6e 42 75 66 66 65 72 3b 20 20 20 20 20 20 20   nBuffer;       
17b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
17c0: 53 69 7a 65 20 6f 66 20 77 72 69 74 65 20 62 75  Size of write bu
17d0: 66 66 65 72 20 69 6e 20 62 79 74 65 73 20 2a 2f  ffer in bytes */
17e0: 0a 20 20 69 6e 74 20 69 42 75 66 53 74 61 72 74  .  int iBufStart
17f0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1800: 20 20 20 2f 2a 20 46 69 72 73 74 20 62 79 74 65     /* First byte
1810: 20 6f 66 20 62 75 66 66 65 72 20 74 6f 20 77 72   of buffer to wr
1820: 69 74 65 20 2a 2f 0a 20 20 69 6e 74 20 69 42 75  ite */.  int iBu
1830: 66 45 6e 64 3b 20 20 20 20 20 20 20 20 20 20 20  fEnd;           
1840: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 73 74           /* Last
1850: 20 62 79 74 65 20 6f 66 20 62 75 66 66 65 72 20   byte of buffer 
1860: 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 69 36  to write */.  i6
1870: 34 20 69 57 72 69 74 65 4f 66 66 3b 20 20 20 20  4 iWriteOff;    
1880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1890: 20 4f 66 66 73 65 74 20 6f 66 20 73 74 61 72 74   Offset of start
18a0: 20 6f 66 20 62 75 66 66 65 72 20 69 6e 20 66 69   of buffer in fi
18b0: 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  le */.  sqlite3_
18c0: 66 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20 20  file *pFile;    
18d0: 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20          /* File 
18e0: 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a 7d  to write to */.}
18f0: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 74 72 75 63  ;../*.** A struc
1900: 74 75 72 65 20 74 6f 20 73 74 6f 72 65 20 61 20  ture to store a 
1910: 73 69 6e 67 6c 65 20 72 65 63 6f 72 64 2e 20 41  single record. A
1920: 6c 6c 20 69 6e 2d 6d 65 6d 6f 72 79 20 72 65 63  ll in-memory rec
1930: 6f 72 64 73 20 61 72 65 20 63 6f 6e 6e 65 63 74  ords are connect
1940: 65 64 0a 2a 2a 20 74 6f 67 65 74 68 65 72 20 69  ed.** together i
1950: 6e 74 6f 20 61 20 6c 69 6e 6b 65 64 20 6c 69 73  nto a linked lis
1960: 74 20 68 65 61 64 65 64 20 61 74 20 56 64 62 65  t headed at Vdbe
1970: 53 6f 72 74 65 72 2e 70 52 65 63 6f 72 64 20 75  Sorter.pRecord u
1980: 73 69 6e 67 20 74 68 65 20 0a 2a 2a 20 53 6f 72  sing the .** Sor
1990: 74 65 72 52 65 63 6f 72 64 2e 70 4e 65 78 74 20  terRecord.pNext 
19a0: 70 6f 69 6e 74 65 72 2e 0a 2a 2f 0a 73 74 72 75  pointer..*/.stru
19b0: 63 74 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20  ct SorterRecord 
19c0: 7b 0a 20 20 76 6f 69 64 20 2a 70 56 61 6c 3b 0a  {.  void *pVal;.
19d0: 20 20 69 6e 74 20 6e 56 61 6c 3b 0a 20 20 53 6f    int nVal;.  So
19e0: 72 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65 78  rterRecord *pNex
19f0: 74 3b 0a 7d 3b 0a 0a 2f 2a 20 4d 69 6e 69 6d 75  t;.};../* Minimu
1a00: 6d 20 61 6c 6c 6f 77 61 62 6c 65 20 76 61 6c 75  m allowable valu
1a10: 65 20 66 6f 72 20 74 68 65 20 56 64 62 65 53 6f  e for the VdbeSo
1a20: 72 74 65 72 2e 6e 57 6f 72 6b 69 6e 67 20 76 61  rter.nWorking va
1a30: 72 69 61 62 6c 65 20 2a 2f 0a 23 64 65 66 69 6e  riable */.#defin
1a40: 65 20 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52  e SORTER_MIN_WOR
1a50: 4b 49 4e 47 20 31 30 0a 0a 2f 2a 20 4d 61 78 69  KING 10../* Maxi
1a60: 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20 73 65  mum number of se
1a70: 67 6d 65 6e 74 73 20 74 6f 20 6d 65 72 67 65 20  gments to merge 
1a80: 69 6e 20 61 20 73 69 6e 67 6c 65 20 70 61 73 73  in a single pass
1a90: 2e 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53 4f 52  . */.#define SOR
1aa0: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
1ab0: 55 4e 54 20 31 36 0a 0a 2f 2a 0a 2a 2a 20 46 72  UNT 16../*.** Fr
1ac0: 65 65 20 61 6c 6c 20 6d 65 6d 6f 72 79 20 62 65  ee all memory be
1ad0: 6c 6f 6e 67 69 6e 67 20 74 6f 20 74 68 65 20 56  longing to the V
1ae0: 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 6f 62  dbeSorterIter ob
1af0: 6a 65 63 74 20 70 61 73 73 65 64 20 61 73 20 74  ject passed as t
1b00: 68 65 20 73 65 63 6f 6e 64 0a 2a 2a 20 61 72 67  he second.** arg
1b10: 75 6d 65 6e 74 2e 20 41 6c 6c 20 73 74 72 75 63  ument. All struc
1b20: 74 75 72 65 20 66 69 65 6c 64 73 20 61 72 65 20  ture fields are 
1b30: 73 65 74 20 74 6f 20 7a 65 72 6f 20 62 65 66 6f  set to zero befo
1b40: 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2f  re returning..*/
1b50: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 76 64 62  .static void vdb
1b60: 65 53 6f 72 74 65 72 49 74 65 72 5a 65 72 6f 28  eSorterIterZero(
1b70: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 56 64 62  sqlite3 *db, Vdb
1b80: 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74  eSorterIter *pIt
1b90: 65 72 29 7b 0a 20 20 73 71 6c 69 74 65 33 44 62  er){.  sqlite3Db
1ba0: 46 72 65 65 28 64 62 2c 20 70 49 74 65 72 2d 3e  Free(db, pIter->
1bb0: 61 41 6c 6c 6f 63 29 3b 0a 20 20 73 71 6c 69 74  aAlloc);.  sqlit
1bc0: 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 49 74  e3DbFree(db, pIt
1bd0: 65 72 2d 3e 61 42 75 66 66 65 72 29 3b 0a 20 20  er->aBuffer);.  
1be0: 6d 65 6d 73 65 74 28 70 49 74 65 72 2c 20 30 2c  memset(pIter, 0,
1bf0: 20 73 69 7a 65 6f 66 28 56 64 62 65 53 6f 72 74   sizeof(VdbeSort
1c00: 65 72 49 74 65 72 29 29 3b 0a 7d 0a 0a 2f 2a 0a  erIter));.}../*.
1c10: 2a 2a 20 52 65 61 64 20 6e 42 79 74 65 20 62 79  ** Read nByte by
1c20: 74 65 73 20 6f 66 20 64 61 74 61 20 66 72 6f 6d  tes of data from
1c30: 20 74 68 65 20 73 74 72 65 61 6d 20 6f 66 20 64   the stream of d
1c40: 61 74 61 20 69 74 65 72 61 74 65 64 20 62 79 20  ata iterated by 
1c50: 6f 62 6a 65 63 74 20 70 2e 0a 2a 2a 20 49 66 20  object p..** If 
1c60: 73 75 63 63 65 73 73 66 75 6c 2c 20 73 65 74 20  successful, set 
1c70: 2a 70 70 4f 75 74 20 74 6f 20 70 6f 69 6e 74 20  *ppOut to point 
1c80: 74 6f 20 61 20 62 75 66 66 65 72 20 63 6f 6e 74  to a buffer cont
1c90: 61 69 6e 69 6e 67 20 74 68 65 20 64 61 74 61 0a  aining the data.
1ca0: 2a 2a 20 61 6e 64 20 72 65 74 75 72 6e 20 53 51  ** and return SQ
1cb0: 4c 49 54 45 5f 4f 4b 2e 20 4f 74 68 65 72 77 69  LITE_OK. Otherwi
1cc0: 73 65 2c 20 69 66 20 61 6e 20 65 72 72 6f 72 20  se, if an error 
1cd0: 6f 63 63 75 72 73 2c 20 72 65 74 75 72 6e 20 61  occurs, return a
1ce0: 6e 20 53 51 4c 69 74 65 0a 2a 2a 20 65 72 72 6f  n SQLite.** erro
1cf0: 72 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 54 68  r code..**.** Th
1d00: 65 20 62 75 66 66 65 72 20 69 6e 64 69 63 61 74  e buffer indicat
1d10: 65 64 20 62 79 20 2a 70 70 4f 75 74 20 6d 61 79  ed by *ppOut may
1d20: 20 6f 6e 6c 79 20 62 65 20 63 6f 6e 73 69 64 65   only be conside
1d30: 72 65 64 20 76 61 6c 69 64 20 75 6e 74 69 6c 20  red valid until 
1d40: 74 68 65 0a 2a 2a 20 6e 65 78 74 20 63 61 6c 6c  the.** next call
1d50: 20 74 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f   to this functio
1d60: 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  n..*/.static int
1d70: 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 52   vdbeSorterIterR
1d80: 65 61 64 28 0a 20 20 73 71 6c 69 74 65 33 20 2a  ead(.  sqlite3 *
1d90: 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  db,             
1da0: 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61         /* Databa
1db0: 73 65 20 68 61 6e 64 6c 65 20 28 66 6f 72 20 6d  se handle (for m
1dc0: 61 6c 6c 6f 63 29 20 2a 2f 0a 20 20 56 64 62 65  alloc) */.  Vdbe
1dd0: 53 6f 72 74 65 72 49 74 65 72 20 2a 70 2c 20 20  SorterIter *p,  
1de0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
1df0: 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74  terator */.  int
1e00: 20 6e 42 79 74 65 2c 20 20 20 20 20 20 20 20 20   nByte,         
1e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1e20: 42 79 74 65 73 20 6f 66 20 64 61 74 61 20 74 6f  Bytes of data to
1e30: 20 72 65 61 64 20 2a 2f 0a 20 20 75 38 20 2a 2a   read */.  u8 **
1e40: 70 70 4f 75 74 20 20 20 20 20 20 20 20 20 20 20  ppOut           
1e50: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
1e60: 54 3a 20 50 6f 69 6e 74 65 72 20 74 6f 20 62 75  T: Pointer to bu
1e70: 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ffer containing 
1e80: 64 61 74 61 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  data */.){.  int
1e90: 20 69 42 75 66 3b 20 20 20 20 20 20 20 20 20 20   iBuf;          
1ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1eb0: 4f 66 66 73 65 74 20 77 69 74 68 69 6e 20 62 75  Offset within bu
1ec0: 66 66 65 72 20 74 6f 20 72 65 61 64 20 66 72 6f  ffer to read fro
1ed0: 6d 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 76 61 69  m */.  int nAvai
1ee0: 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l;              
1ef0: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
1f00: 6f 66 20 64 61 74 61 20 61 76 61 69 6c 61 62 6c  of data availabl
1f10: 65 20 69 6e 20 62 75 66 66 65 72 20 2a 2f 0a 20  e in buffer */. 
1f20: 20 61 73 73 65 72 74 28 20 70 2d 3e 61 42 75 66   assert( p->aBuf
1f30: 66 65 72 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20  fer );..  /* If 
1f40: 74 68 65 72 65 20 69 73 20 6e 6f 20 6d 6f 72 65  there is no more
1f50: 20 64 61 74 61 20 74 6f 20 62 65 20 72 65 61 64   data to be read
1f60: 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66 65 72   from the buffer
1f70: 2c 20 72 65 61 64 20 74 68 65 20 6e 65 78 74 20  , read the next 
1f80: 0a 20 20 2a 2a 20 70 2d 3e 6e 42 75 66 66 65 72  .  ** p->nBuffer
1f90: 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 66   bytes of data f
1fa0: 72 6f 6d 20 74 68 65 20 66 69 6c 65 20 69 6e 74  rom the file int
1fb0: 6f 20 69 74 2e 20 4f 72 2c 20 69 66 20 74 68 65  o it. Or, if the
1fc0: 72 65 20 61 72 65 20 6c 65 73 73 0a 20 20 2a 2a  re are less.  **
1fd0: 20 74 68 61 6e 20 70 2d 3e 6e 42 75 66 66 65 72   than p->nBuffer
1fe0: 20 62 79 74 65 73 20 72 65 6d 61 69 6e 69 6e 67   bytes remaining
1ff0: 20 69 6e 20 74 68 65 20 50 4d 41 2c 20 72 65 61   in the PMA, rea
2000: 64 20 61 6c 6c 20 72 65 6d 61 69 6e 69 6e 67 20  d all remaining 
2010: 64 61 74 61 2e 20 20 2a 2f 0a 20 20 69 42 75 66  data.  */.  iBuf
2020: 20 3d 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 25   = p->iReadOff %
2030: 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 69   p->nBuffer;.  i
2040: 66 28 20 69 42 75 66 3d 3d 30 20 29 7b 0a 20 20  f( iBuf==0 ){.  
2050: 20 20 69 6e 74 20 6e 52 65 61 64 3b 20 20 20 20    int nRead;    
2060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2070: 2f 2a 20 42 79 74 65 73 20 74 6f 20 72 65 61 64  /* Bytes to read
2080: 20 66 72 6f 6d 20 64 69 73 6b 20 2a 2f 0a 20 20   from disk */.  
2090: 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
20a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20b0: 2f 2a 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64  /* sqlite3OsRead
20c0: 28 29 20 72 65 74 75 72 6e 20 63 6f 64 65 20 2a  () return code *
20d0: 2f 0a 0a 20 20 20 20 2f 2a 20 44 65 74 65 72 6d  /..    /* Determ
20e0: 69 6e 65 20 68 6f 77 20 6d 61 6e 79 20 62 79 74  ine how many byt
20f0: 65 73 20 6f 66 20 64 61 74 61 20 74 6f 20 72 65  es of data to re
2100: 61 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 28  ad. */.    if( (
2110: 70 2d 3e 69 45 6f 66 20 2d 20 70 2d 3e 69 52 65  p->iEof - p->iRe
2120: 61 64 4f 66 66 29 20 3e 20 28 69 36 34 29 70 2d  adOff) > (i64)p-
2130: 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20  >nBuffer ){.    
2140: 20 20 6e 52 65 61 64 20 3d 20 70 2d 3e 6e 42 75    nRead = p->nBu
2150: 66 66 65 72 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  ffer;.    }else{
2160: 0a 20 20 20 20 20 20 6e 52 65 61 64 20 3d 20 28  .      nRead = (
2170: 69 6e 74 29 28 70 2d 3e 69 45 6f 66 20 2d 20 70  int)(p->iEof - p
2180: 2d 3e 69 52 65 61 64 4f 66 66 29 3b 0a 20 20 20  ->iReadOff);.   
2190: 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 6e   }.    assert( n
21a0: 52 65 61 64 3e 30 20 29 3b 0a 0a 20 20 20 20 2f  Read>0 );..    /
21b0: 2a 20 52 65 61 64 20 64 61 74 61 20 66 72 6f 6d  * Read data from
21c0: 20 74 68 65 20 66 69 6c 65 2e 20 52 65 74 75 72   the file. Retur
21d0: 6e 20 65 61 72 6c 79 20 69 66 20 61 6e 20 65 72  n early if an er
21e0: 72 6f 72 20 6f 63 63 75 72 73 2e 20 2a 2f 0a 20  ror occurs. */. 
21f0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
2200: 73 52 65 61 64 28 70 2d 3e 70 46 69 6c 65 2c 20  sRead(p->pFile, 
2210: 70 2d 3e 61 42 75 66 66 65 72 2c 20 6e 52 65 61  p->aBuffer, nRea
2220: 64 2c 20 70 2d 3e 69 52 65 61 64 4f 66 66 29 3b  d, p->iReadOff);
2230: 0a 20 20 20 20 61 73 73 65 72 74 28 20 72 63 21  .    assert( rc!
2240: 3d 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f 53 48  =SQLITE_IOERR_SH
2250: 4f 52 54 5f 52 45 41 44 20 29 3b 0a 20 20 20 20  ORT_READ );.    
2260: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
2270: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  K ) return rc;. 
2280: 20 7d 0a 20 20 6e 41 76 61 69 6c 20 3d 20 70 2d   }.  nAvail = p-
2290: 3e 6e 42 75 66 66 65 72 20 2d 20 69 42 75 66 3b  >nBuffer - iBuf;
22a0: 20 0a 0a 20 20 69 66 28 20 6e 42 79 74 65 3c 3d   ..  if( nByte<=
22b0: 6e 41 76 61 69 6c 20 29 7b 0a 20 20 20 20 2f 2a  nAvail ){.    /*
22c0: 20 54 68 65 20 72 65 71 75 65 73 74 65 64 20 64   The requested d
22d0: 61 74 61 20 69 73 20 61 76 61 69 6c 61 62 6c 65  ata is available
22e0: 20 69 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72   in the in-memor
22f0: 79 20 62 75 66 66 65 72 2e 20 49 6e 20 74 68 69  y buffer. In thi
2300: 73 0a 20 20 20 20 2a 2a 20 63 61 73 65 20 74 68  s.    ** case th
2310: 65 72 65 20 69 73 20 6e 6f 20 6e 65 65 64 20 74  ere is no need t
2320: 6f 20 6d 61 6b 65 20 61 20 63 6f 70 79 20 6f 66  o make a copy of
2330: 20 74 68 65 20 64 61 74 61 2c 20 6a 75 73 74 20   the data, just 
2340: 72 65 74 75 72 6e 20 61 20 0a 20 20 20 20 2a 2a  return a .    **
2350: 20 70 6f 69 6e 74 65 72 20 69 6e 74 6f 20 74 68   pointer into th
2360: 65 20 62 75 66 66 65 72 20 74 6f 20 74 68 65 20  e buffer to the 
2370: 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a 20 20 20 20  caller.  */.    
2380: 2a 70 70 4f 75 74 20 3d 20 26 70 2d 3e 61 42 75  *ppOut = &p->aBu
2390: 66 66 65 72 5b 69 42 75 66 5d 3b 0a 20 20 20 20  ffer[iBuf];.    
23a0: 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b 3d 20 6e  p->iReadOff += n
23b0: 42 79 74 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  Byte;.  }else{. 
23c0: 20 20 20 2f 2a 20 54 68 65 20 72 65 71 75 65 73     /* The reques
23d0: 74 65 64 20 64 61 74 61 20 69 73 20 6e 6f 74 20  ted data is not 
23e0: 61 6c 6c 20 61 76 61 69 6c 61 62 6c 65 20 69 6e  all available in
23f0: 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 62   the in-memory b
2400: 75 66 66 65 72 2e 0a 20 20 20 20 2a 2a 20 49 6e  uffer..    ** In
2410: 20 74 68 69 73 20 63 61 73 65 2c 20 61 6c 6c 6f   this case, allo
2420: 63 61 74 65 20 73 70 61 63 65 20 61 74 20 70 2d  cate space at p-
2430: 3e 61 41 6c 6c 6f 63 5b 5d 20 74 6f 20 63 6f 70  >aAlloc[] to cop
2440: 79 20 74 68 65 20 72 65 71 75 65 73 74 65 64 0a  y the requested.
2450: 20 20 20 20 2a 2a 20 72 61 6e 67 65 20 69 6e 74      ** range int
2460: 6f 2e 20 54 68 65 6e 20 72 65 74 75 72 6e 20 61  o. Then return a
2470: 20 63 6f 70 79 20 6f 66 20 70 6f 69 6e 74 65 72   copy of pointer
2480: 20 70 2d 3e 61 41 6c 6c 6f 63 20 74 6f 20 74 68   p->aAlloc to th
2490: 65 20 63 61 6c 6c 65 72 2e 20 20 2a 2f 0a 20 20  e caller.  */.  
24a0: 20 20 69 6e 74 20 6e 52 65 6d 3b 20 20 20 20 20    int nRem;     
24b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24c0: 2f 2a 20 42 79 74 65 73 20 72 65 6d 61 69 6e 69  /* Bytes remaini
24d0: 6e 67 20 74 6f 20 63 6f 70 79 20 2a 2f 0a 0a 20  ng to copy */.. 
24e0: 20 20 20 2f 2a 20 45 78 74 65 6e 64 20 74 68 65     /* Extend the
24f0: 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20 61 6c 6c   p->aAlloc[] all
2500: 6f 63 61 74 69 6f 6e 20 69 66 20 72 65 71 75 69  ocation if requi
2510: 72 65 64 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20  red. */.    if( 
2520: 70 2d 3e 6e 41 6c 6c 6f 63 3c 6e 42 79 74 65 20  p->nAlloc<nByte 
2530: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e 65  ){.      int nNe
2540: 77 20 3d 20 70 2d 3e 6e 41 6c 6c 6f 63 2a 32 3b  w = p->nAlloc*2;
2550: 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 6e 42  .      while( nB
2560: 79 74 65 3e 6e 4e 65 77 20 29 20 6e 4e 65 77 20  yte>nNew ) nNew 
2570: 3d 20 6e 4e 65 77 2a 32 3b 0a 20 20 20 20 20 20  = nNew*2;.      
2580: 70 2d 3e 61 41 6c 6c 6f 63 20 3d 20 73 71 6c 69  p->aAlloc = sqli
2590: 74 65 33 44 62 52 65 61 6c 6c 6f 63 4f 72 46 72  te3DbReallocOrFr
25a0: 65 65 28 64 62 2c 20 70 2d 3e 61 41 6c 6c 6f 63  ee(db, p->aAlloc
25b0: 2c 20 6e 4e 65 77 29 3b 0a 20 20 20 20 20 20 69  , nNew);.      i
25c0: 66 28 20 21 70 2d 3e 61 41 6c 6c 6f 63 20 29 20  f( !p->aAlloc ) 
25d0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
25e0: 4d 45 4d 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 41  MEM;.      p->nA
25f0: 6c 6c 6f 63 20 3d 20 6e 4e 65 77 3b 0a 20 20 20  lloc = nNew;.   
2600: 20 7d 0a 0a 20 20 20 20 2f 2a 20 43 6f 70 79 20   }..    /* Copy 
2610: 61 73 20 6d 75 63 68 20 64 61 74 61 20 61 73 20  as much data as 
2620: 69 73 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20  is available in 
2630: 74 68 65 20 62 75 66 66 65 72 20 69 6e 74 6f 20  the buffer into 
2640: 74 68 65 20 73 74 61 72 74 20 6f 66 0a 20 20 20  the start of.   
2650: 20 2a 2a 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 2e   ** p->aAlloc[].
2660: 20 20 2a 2f 0a 20 20 20 20 6d 65 6d 63 70 79 28    */.    memcpy(
2670: 70 2d 3e 61 41 6c 6c 6f 63 2c 20 26 70 2d 3e 61  p->aAlloc, &p->a
2680: 42 75 66 66 65 72 5b 69 42 75 66 5d 2c 20 6e 41  Buffer[iBuf], nA
2690: 76 61 69 6c 29 3b 0a 20 20 20 20 70 2d 3e 69 52  vail);.    p->iR
26a0: 65 61 64 4f 66 66 20 2b 3d 20 6e 41 76 61 69 6c  eadOff += nAvail
26b0: 3b 0a 20 20 20 20 6e 52 65 6d 20 3d 20 6e 42 79  ;.    nRem = nBy
26c0: 74 65 20 2d 20 6e 41 76 61 69 6c 3b 0a 0a 20 20  te - nAvail;..  
26d0: 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69    /* The followi
26e0: 6e 67 20 6c 6f 6f 70 20 63 6f 70 69 65 73 20 75  ng loop copies u
26f0: 70 20 74 6f 20 70 2d 3e 6e 42 75 66 66 65 72 20  p to p->nBuffer 
2700: 62 79 74 65 73 20 70 65 72 20 69 74 65 72 61 74  bytes per iterat
2710: 69 6f 6e 20 69 6e 74 6f 0a 20 20 20 20 2a 2a 20  ion into.    ** 
2720: 74 68 65 20 70 2d 3e 61 41 6c 6c 6f 63 5b 5d 20  the p->aAlloc[] 
2730: 62 75 66 66 65 72 2e 20 20 2a 2f 0a 20 20 20 20  buffer.  */.    
2740: 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30 20 29 7b  while( nRem>0 ){
2750: 0a 20 20 20 20 20 20 69 6e 74 20 72 63 3b 20 20  .      int rc;  
2760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2770: 20 20 20 2f 2a 20 76 64 62 65 53 6f 72 74 65 72     /* vdbeSorter
2780: 49 74 65 72 52 65 61 64 28 29 20 72 65 74 75 72  IterRead() retur
2790: 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 20 20 20 20  n code */.      
27a0: 69 6e 74 20 6e 43 6f 70 79 3b 20 20 20 20 20 20  int nCopy;      
27b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
27c0: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 74  umber of bytes t
27d0: 6f 20 63 6f 70 79 20 2a 2f 0a 20 20 20 20 20 20  o copy */.      
27e0: 75 38 20 2a 61 4e 65 78 74 3b 20 20 20 20 20 20  u8 *aNext;      
27f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
2800: 6f 69 6e 74 65 72 20 74 6f 20 62 75 66 66 65 72  ointer to buffer
2810: 20 74 6f 20 63 6f 70 79 20 64 61 74 61 20 66 72   to copy data fr
2820: 6f 6d 20 2a 2f 0a 0a 20 20 20 20 20 20 6e 43 6f  om */..      nCo
2830: 70 79 20 3d 20 6e 52 65 6d 3b 0a 20 20 20 20 20  py = nRem;.     
2840: 20 69 66 28 20 6e 52 65 6d 3e 70 2d 3e 6e 42 75   if( nRem>p->nBu
2850: 66 66 65 72 20 29 20 6e 43 6f 70 79 20 3d 20 70  ffer ) nCopy = p
2860: 2d 3e 6e 42 75 66 66 65 72 3b 0a 20 20 20 20 20  ->nBuffer;.     
2870: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
2880: 49 74 65 72 52 65 61 64 28 64 62 2c 20 70 2c 20  IterRead(db, p, 
2890: 6e 43 6f 70 79 2c 20 26 61 4e 65 78 74 29 3b 0a  nCopy, &aNext);.
28a0: 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
28b0: 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
28c0: 20 72 63 3b 0a 20 20 20 20 20 20 61 73 73 65 72   rc;.      asser
28d0: 74 28 20 61 4e 65 78 74 21 3d 70 2d 3e 61 41 6c  t( aNext!=p->aAl
28e0: 6c 6f 63 20 29 3b 0a 20 20 20 20 20 20 6d 65 6d  loc );.      mem
28f0: 63 70 79 28 26 70 2d 3e 61 41 6c 6c 6f 63 5b 6e  cpy(&p->aAlloc[n
2900: 42 79 74 65 20 2d 20 6e 52 65 6d 5d 2c 20 61 4e  Byte - nRem], aN
2910: 65 78 74 2c 20 6e 43 6f 70 79 29 3b 0a 20 20 20  ext, nCopy);.   
2920: 20 20 20 6e 52 65 6d 20 2d 3d 20 6e 43 6f 70 79     nRem -= nCopy
2930: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2a 70 70  ;.    }..    *pp
2940: 4f 75 74 20 3d 20 70 2d 3e 61 41 6c 6c 6f 63 3b  Out = p->aAlloc;
2950: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53  .  }..  return S
2960: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
2970: 2a 2a 20 52 65 61 64 20 61 20 76 61 72 69 6e 74  ** Read a varint
2980: 20 66 72 6f 6d 20 74 68 65 20 73 74 72 65 61 6d   from the stream
2990: 20 6f 66 20 64 61 74 61 20 61 63 63 65 73 73 65   of data accesse
29a0: 64 20 62 79 20 70 2e 20 53 65 74 20 2a 70 6e 4f  d by p. Set *pnO
29b0: 75 74 20 74 6f 0a 2a 2a 20 74 68 65 20 76 61 6c  ut to.** the val
29c0: 75 65 20 72 65 61 64 2e 0a 2a 2f 0a 73 74 61 74  ue read..*/.stat
29d0: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
29e0: 72 49 74 65 72 56 61 72 69 6e 74 28 73 71 6c 69  rIterVarint(sqli
29f0: 74 65 33 20 2a 64 62 2c 20 56 64 62 65 53 6f 72  te3 *db, VdbeSor
2a00: 74 65 72 49 74 65 72 20 2a 70 2c 20 75 36 34 20  terIter *p, u64 
2a10: 2a 70 6e 4f 75 74 29 7b 0a 20 20 69 6e 74 20 69  *pnOut){.  int i
2a20: 42 75 66 3b 0a 0a 20 20 69 42 75 66 20 3d 20 70  Buf;..  iBuf = p
2a30: 2d 3e 69 52 65 61 64 4f 66 66 20 25 20 70 2d 3e  ->iReadOff % p->
2a40: 6e 42 75 66 66 65 72 3b 0a 20 20 69 66 28 20 69  nBuffer;.  if( i
2a50: 42 75 66 20 26 26 20 28 70 2d 3e 6e 42 75 66 66  Buf && (p->nBuff
2a60: 65 72 2d 69 42 75 66 29 3e 3d 39 20 29 7b 0a 20  er-iBuf)>=9 ){. 
2a70: 20 20 20 70 2d 3e 69 52 65 61 64 4f 66 66 20 2b     p->iReadOff +
2a80: 3d 20 73 71 6c 69 74 65 33 47 65 74 56 61 72 69  = sqlite3GetVari
2a90: 6e 74 28 26 70 2d 3e 61 42 75 66 66 65 72 5b 69  nt(&p->aBuffer[i
2aa0: 42 75 66 5d 2c 20 70 6e 4f 75 74 29 3b 0a 20 20  Buf], pnOut);.  
2ab0: 7d 65 6c 73 65 7b 0a 20 20 20 20 75 38 20 61 56  }else{.    u8 aV
2ac0: 61 72 69 6e 74 5b 31 36 5d 2c 20 2a 61 3b 0a 20  arint[16], *a;. 
2ad0: 20 20 20 69 6e 74 20 69 20 3d 20 30 2c 20 72 63     int i = 0, rc
2ae0: 3b 0a 20 20 20 20 64 6f 7b 0a 20 20 20 20 20 20  ;.    do{.      
2af0: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 49  rc = vdbeSorterI
2b00: 74 65 72 52 65 61 64 28 64 62 2c 20 70 2c 20 31  terRead(db, p, 1
2b10: 2c 20 26 61 29 3b 0a 20 20 20 20 20 20 69 66 28  , &a);.      if(
2b20: 20 72 63 20 29 20 72 65 74 75 72 6e 20 72 63 3b   rc ) return rc;
2b30: 0a 20 20 20 20 20 20 61 56 61 72 69 6e 74 5b 28  .      aVarint[(
2b40: 69 2b 2b 29 26 30 78 66 5d 20 3d 20 61 5b 30 5d  i++)&0xf] = a[0]
2b50: 3b 0a 20 20 20 20 7d 77 68 69 6c 65 28 20 28 61  ;.    }while( (a
2b60: 5b 30 5d 26 30 78 38 30 29 21 3d 30 20 29 3b 0a  [0]&0x80)!=0 );.
2b70: 20 20 20 20 73 71 6c 69 74 65 33 47 65 74 56 61      sqlite3GetVa
2b80: 72 69 6e 74 28 61 56 61 72 69 6e 74 2c 20 70 6e  rint(aVarint, pn
2b90: 4f 75 74 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  Out);.  }..  ret
2ba0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
2bb0: 0a 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65  .../*.** Advance
2bc0: 20 69 74 65 72 61 74 6f 72 20 70 49 74 65 72 20   iterator pIter 
2bd0: 74 6f 20 74 68 65 20 6e 65 78 74 20 6b 65 79 20  to the next key 
2be0: 69 6e 20 69 74 73 20 50 4d 41 2e 20 52 65 74 75  in its PMA. Retu
2bf0: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 0a  rn SQLITE_OK if.
2c00: 2a 2a 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75  ** no error occu
2c10: 72 73 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65  rs, or an SQLite
2c20: 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20 6f   error code if o
2c30: 6e 65 20 64 6f 65 73 2e 0a 2a 2f 0a 73 74 61 74  ne does..*/.stat
2c40: 69 63 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65  ic int vdbeSorte
2c50: 72 49 74 65 72 4e 65 78 74 28 0a 20 20 73 71 6c  rIterNext(.  sql
2c60: 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20  ite3 *db,       
2c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2c80: 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20  Database handle 
2c90: 28 66 6f 72 20 73 71 6c 69 74 65 33 44 62 4d 61  (for sqlite3DbMa
2ca0: 6c 6c 6f 63 28 29 20 29 20 2a 2f 0a 20 20 56 64  lloc() ) */.  Vd
2cb0: 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70 49  beSorterIter *pI
2cc0: 74 65 72 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ter           /*
2cd0: 20 49 74 65 72 61 74 6f 72 20 74 6f 20 61 64 76   Iterator to adv
2ce0: 61 6e 63 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  ance */.){.  int
2cf0: 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
2d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2d10: 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20  Return Code */. 
2d20: 20 75 36 34 20 6e 52 65 63 20 3d 20 30 3b 20 20   u64 nRec = 0;  
2d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2d40: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 72 65 63 6f   /* Size of reco
2d50: 72 64 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 0a  rd in bytes */..
2d60: 20 20 69 66 28 20 70 49 74 65 72 2d 3e 69 52 65    if( pIter->iRe
2d70: 61 64 4f 66 66 3e 3d 70 49 74 65 72 2d 3e 69 45  adOff>=pIter->iE
2d80: 6f 66 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 69  of ){.    /* Thi
2d90: 73 20 69 73 20 61 6e 20 45 4f 46 20 63 6f 6e 64  s is an EOF cond
2da0: 69 74 69 6f 6e 20 2a 2f 0a 20 20 20 20 76 64 62  ition */.    vdb
2db0: 65 53 6f 72 74 65 72 49 74 65 72 5a 65 72 6f 28  eSorterIterZero(
2dc0: 64 62 2c 20 70 49 74 65 72 29 3b 0a 20 20 20 20  db, pIter);.    
2dd0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
2de0: 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20 76 64  ;.  }..  rc = vd
2df0: 62 65 53 6f 72 74 65 72 49 74 65 72 56 61 72 69  beSorterIterVari
2e00: 6e 74 28 64 62 2c 20 70 49 74 65 72 2c 20 26 6e  nt(db, pIter, &n
2e10: 52 65 63 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d  Rec);.  if( rc==
2e20: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
2e30: 20 70 49 74 65 72 2d 3e 6e 4b 65 79 20 3d 20 28   pIter->nKey = (
2e40: 69 6e 74 29 6e 52 65 63 3b 0a 20 20 20 20 72 63  int)nRec;.    rc
2e50: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 49 74 65   = vdbeSorterIte
2e60: 72 52 65 61 64 28 64 62 2c 20 70 49 74 65 72 2c  rRead(db, pIter,
2e70: 20 28 69 6e 74 29 6e 52 65 63 2c 20 26 70 49 74   (int)nRec, &pIt
2e80: 65 72 2d 3e 61 4b 65 79 29 3b 0a 20 20 7d 0a 0a  er->aKey);.  }..
2e90: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
2ea0: 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65  /*.** Initialize
2eb0: 20 69 74 65 72 61 74 6f 72 20 70 49 74 65 72 20   iterator pIter 
2ec0: 74 6f 20 73 63 61 6e 20 74 68 72 6f 75 67 68 20  to scan through 
2ed0: 74 68 65 20 50 4d 41 20 73 74 6f 72 65 64 20 69  the PMA stored i
2ee0: 6e 20 66 69 6c 65 20 70 46 69 6c 65 0a 2a 2a 20  n file pFile.** 
2ef0: 73 74 61 72 74 69 6e 67 20 61 74 20 6f 66 66 73  starting at offs
2f00: 65 74 20 69 53 74 61 72 74 20 61 6e 64 20 65 6e  et iStart and en
2f10: 64 69 6e 67 20 61 74 20 6f 66 66 73 65 74 20 69  ding at offset i
2f20: 45 6f 66 2d 31 2e 20 54 68 69 73 20 66 75 6e 63  Eof-1. This func
2f30: 74 69 6f 6e 20 0a 2a 2a 20 6c 65 61 76 65 73 20  tion .** leaves 
2f40: 74 68 65 20 69 74 65 72 61 74 6f 72 20 70 6f 69  the iterator poi
2f50: 6e 74 69 6e 67 20 74 6f 20 74 68 65 20 66 69 72  nting to the fir
2f60: 73 74 20 6b 65 79 20 69 6e 20 74 68 65 20 50 4d  st key in the PM
2f70: 41 20 28 6f 72 20 45 4f 46 20 69 66 20 74 68 65  A (or EOF if the
2f80: 20 0a 2a 2a 20 50 4d 41 20 69 73 20 65 6d 70 74   .** PMA is empt
2f90: 79 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  y)..*/.static in
2fa0: 74 20 76 64 62 65 53 6f 72 74 65 72 49 74 65 72  t vdbeSorterIter
2fb0: 49 6e 69 74 28 0a 20 20 73 71 6c 69 74 65 33 20  Init(.  sqlite3 
2fc0: 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20  *db,            
2fd0: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
2fe0: 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20  ase handle */.  
2ff0: 63 6f 6e 73 74 20 56 64 62 65 53 6f 72 74 65 72  const VdbeSorter
3000: 20 2a 70 53 6f 72 74 65 72 2c 20 20 20 20 20 20   *pSorter,      
3010: 2f 2a 20 53 6f 72 74 65 72 20 6f 62 6a 65 63 74  /* Sorter object
3020: 20 2a 2f 0a 20 20 69 36 34 20 69 53 74 61 72 74   */.  i64 iStart
3030: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
3040: 20 20 20 20 20 20 2f 2a 20 53 74 61 72 74 20 6f        /* Start o
3050: 66 66 73 65 74 20 69 6e 20 70 46 69 6c 65 20 2a  ffset in pFile *
3060: 2f 0a 20 20 56 64 62 65 53 6f 72 74 65 72 49 74  /.  VdbeSorterIt
3070: 65 72 20 2a 70 49 74 65 72 2c 20 20 20 20 20 20  er *pIter,      
3080: 20 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20      /* Iterator 
3090: 74 6f 20 70 6f 70 75 6c 61 74 65 20 2a 2f 0a 20  to populate */. 
30a0: 20 69 36 34 20 2a 70 6e 42 79 74 65 20 20 20 20   i64 *pnByte    
30b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
30c0: 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 49 6e 63 72   /* IN/OUT: Incr
30d0: 65 6d 65 6e 74 20 74 68 69 73 20 76 61 6c 75 65  ement this value
30e0: 20 62 79 20 50 4d 41 20 73 69 7a 65 20 2a 2f 0a   by PMA size */.
30f0: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
3100: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e  LITE_OK;.  int n
3110: 42 75 66 3b 0a 0a 20 20 6e 42 75 66 20 3d 20 73  Buf;..  nBuf = s
3120: 71 6c 69 74 65 33 42 74 72 65 65 47 65 74 50 61  qlite3BtreeGetPa
3130: 67 65 53 69 7a 65 28 64 62 2d 3e 61 44 62 5b 30  geSize(db->aDb[0
3140: 5d 2e 70 42 74 29 3b 0a 0a 20 20 61 73 73 65 72  ].pBt);..  asser
3150: 74 28 20 70 53 6f 72 74 65 72 2d 3e 69 57 72 69  t( pSorter->iWri
3160: 74 65 4f 66 66 3e 69 53 74 61 72 74 20 29 3b 0a  teOff>iStart );.
3170: 20 20 61 73 73 65 72 74 28 20 70 49 74 65 72 2d    assert( pIter-
3180: 3e 61 41 6c 6c 6f 63 3d 3d 30 20 29 3b 0a 20 20  >aAlloc==0 );.  
3190: 61 73 73 65 72 74 28 20 70 49 74 65 72 2d 3e 61  assert( pIter->a
31a0: 42 75 66 66 65 72 3d 3d 30 20 29 3b 0a 20 20 70  Buffer==0 );.  p
31b0: 49 74 65 72 2d 3e 70 46 69 6c 65 20 3d 20 70 53  Iter->pFile = pS
31c0: 6f 72 74 65 72 2d 3e 70 54 65 6d 70 31 3b 0a 20  orter->pTemp1;. 
31d0: 20 70 49 74 65 72 2d 3e 69 52 65 61 64 4f 66 66   pIter->iReadOff
31e0: 20 3d 20 69 53 74 61 72 74 3b 0a 20 20 70 49 74   = iStart;.  pIt
31f0: 65 72 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 31 32 38  er->nAlloc = 128
3200: 3b 0a 20 20 70 49 74 65 72 2d 3e 61 41 6c 6c 6f  ;.  pIter->aAllo
3210: 63 20 3d 20 28 75 38 20 2a 29 73 71 6c 69 74 65  c = (u8 *)sqlite
3220: 33 44 62 4d 61 6c 6c 6f 63 52 61 77 28 64 62 2c  3DbMallocRaw(db,
3230: 20 70 49 74 65 72 2d 3e 6e 41 6c 6c 6f 63 29 3b   pIter->nAlloc);
3240: 0a 20 20 70 49 74 65 72 2d 3e 6e 42 75 66 66 65  .  pIter->nBuffe
3250: 72 20 3d 20 6e 42 75 66 3b 0a 20 20 70 49 74 65  r = nBuf;.  pIte
3260: 72 2d 3e 61 42 75 66 66 65 72 20 3d 20 28 75 38  r->aBuffer = (u8
3270: 20 2a 29 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c   *)sqlite3DbMall
3280: 6f 63 52 61 77 28 64 62 2c 20 6e 42 75 66 29 3b  ocRaw(db, nBuf);
3290: 0a 0a 20 20 69 66 28 20 21 70 49 74 65 72 2d 3e  ..  if( !pIter->
32a0: 61 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20 72  aBuffer ){.    r
32b0: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
32c0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69  ;.  }else{.    i
32d0: 6e 74 20 69 42 75 66 3b 0a 0a 20 20 20 20 69 42  nt iBuf;..    iB
32e0: 75 66 20 3d 20 69 53 74 61 72 74 20 25 20 6e 42  uf = iStart % nB
32f0: 75 66 3b 0a 20 20 20 20 69 66 28 20 69 42 75 66  uf;.    if( iBuf
3300: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 52   ){.      int nR
3310: 65 61 64 20 3d 20 6e 42 75 66 20 2d 20 69 42 75  ead = nBuf - iBu
3320: 66 3b 0a 20 20 20 20 20 20 69 66 28 20 28 69 53  f;.      if( (iS
3330: 74 61 72 74 20 2b 20 6e 52 65 61 64 29 20 3e 20  tart + nRead) > 
3340: 70 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f  pSorter->iWriteO
3350: 66 66 20 29 7b 0a 20 20 20 20 20 20 20 20 6e 52  ff ){.        nR
3360: 65 61 64 20 3d 20 28 69 6e 74 29 28 70 53 6f 72  ead = (int)(pSor
3370: 74 65 72 2d 3e 69 57 72 69 74 65 4f 66 66 20 2d  ter->iWriteOff -
3380: 20 69 53 74 61 72 74 29 3b 0a 20 20 20 20 20 20   iStart);.      
3390: 7d 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  }.      rc = sql
33a0: 69 74 65 33 4f 73 52 65 61 64 28 0a 20 20 20 20  ite3OsRead(.    
33b0: 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 70        pSorter->p
33c0: 54 65 6d 70 31 2c 20 26 70 49 74 65 72 2d 3e 61  Temp1, &pIter->a
33d0: 42 75 66 66 65 72 5b 69 42 75 66 5d 2c 20 6e 52  Buffer[iBuf], nR
33e0: 65 61 64 2c 20 69 53 74 61 72 74 0a 20 20 20 20  ead, iStart.    
33f0: 20 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72    );.      asser
3400: 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 49 4f  t( rc!=SQLITE_IO
3410: 45 52 52 5f 53 48 4f 52 54 5f 52 45 41 44 20 29  ERR_SHORT_READ )
3420: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  ;.    }..    if(
3430: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
3440: 7b 0a 20 20 20 20 20 20 75 36 34 20 6e 42 79 74  {.      u64 nByt
3450: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
3460: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
3470: 20 6f 66 20 50 4d 41 20 69 6e 20 62 79 74 65 73   of PMA in bytes
3480: 20 2a 2f 0a 20 20 20 20 20 20 70 49 74 65 72 2d   */.      pIter-
3490: 3e 69 45 6f 66 20 3d 20 70 53 6f 72 74 65 72 2d  >iEof = pSorter-
34a0: 3e 69 57 72 69 74 65 4f 66 66 3b 0a 20 20 20 20  >iWriteOff;.    
34b0: 20 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65    rc = vdbeSorte
34c0: 72 49 74 65 72 56 61 72 69 6e 74 28 64 62 2c 20  rIterVarint(db, 
34d0: 70 49 74 65 72 2c 20 26 6e 42 79 74 65 29 3b 0a  pIter, &nByte);.
34e0: 20 20 20 20 20 20 70 49 74 65 72 2d 3e 69 45 6f        pIter->iEo
34f0: 66 20 3d 20 70 49 74 65 72 2d 3e 69 52 65 61 64  f = pIter->iRead
3500: 4f 66 66 20 2b 20 6e 42 79 74 65 3b 0a 20 20 20  Off + nByte;.   
3510: 20 20 20 2a 70 6e 42 79 74 65 20 2b 3d 20 6e 42     *pnByte += nB
3520: 79 74 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  yte;.    }.  }..
3530: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
3540: 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
3550: 76 64 62 65 53 6f 72 74 65 72 49 74 65 72 4e 65  vdbeSorterIterNe
3560: 78 74 28 64 62 2c 20 70 49 74 65 72 29 3b 0a 20  xt(db, pIter);. 
3570: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
3580: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 61 72  }.../*.** Compar
3590: 65 20 6b 65 79 31 20 28 62 75 66 66 65 72 20 70  e key1 (buffer p
35a0: 4b 65 79 31 2c 20 73 69 7a 65 20 6e 4b 65 79 31  Key1, size nKey1
35b0: 20 62 79 74 65 73 29 20 77 69 74 68 20 6b 65 79   bytes) with key
35c0: 32 20 28 62 75 66 66 65 72 20 70 4b 65 79 32 2c  2 (buffer pKey2,
35d0: 20 0a 2a 2a 20 73 69 7a 65 20 6e 4b 65 79 32 20   .** size nKey2 
35e0: 62 79 74 65 73 29 2e 20 20 41 72 67 75 6d 65 6e  bytes).  Argumen
35f0: 74 20 70 4b 65 79 49 6e 66 6f 20 73 75 70 70 6c  t pKeyInfo suppl
3600: 69 65 73 20 74 68 65 20 63 6f 6c 6c 61 74 69 6f  ies the collatio
3610: 6e 20 66 75 6e 63 74 69 6f 6e 73 0a 2a 2a 20 75  n functions.** u
3620: 73 65 64 20 62 79 20 74 68 65 20 63 6f 6d 70 61  sed by the compa
3630: 72 69 73 6f 6e 2e 20 49 66 20 61 6e 20 65 72 72  rison. If an err
3640: 6f 72 20 6f 63 63 75 72 73 2c 20 72 65 74 75 72  or occurs, retur
3650: 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  n an SQLite erro
3660: 72 20 63 6f 64 65 2e 0a 2a 2a 20 4f 74 68 65 72  r code..** Other
3670: 77 69 73 65 2c 20 72 65 74 75 72 6e 20 53 51 4c  wise, return SQL
3680: 49 54 45 5f 4f 4b 20 61 6e 64 20 73 65 74 20 2a  ITE_OK and set *
3690: 70 52 65 73 20 74 6f 20 61 20 6e 65 67 61 74 69  pRes to a negati
36a0: 76 65 2c 20 7a 65 72 6f 20 6f 72 20 70 6f 73 69  ve, zero or posi
36b0: 74 69 76 65 0a 2a 2a 20 76 61 6c 75 65 2c 20 64  tive.** value, d
36c0: 65 70 65 6e 64 69 6e 67 20 6f 6e 20 77 68 65 74  epending on whet
36d0: 68 65 72 20 6b 65 79 31 20 69 73 20 73 6d 61 6c  her key1 is smal
36e0: 6c 65 72 2c 20 65 71 75 61 6c 20 74 6f 20 6f 72  ler, equal to or
36f0: 20 6c 61 72 67 65 72 20 74 68 61 6e 20 6b 65 79   larger than key
3700: 32 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20  2..**.** If the 
3710: 62 4f 6d 69 74 52 6f 77 69 64 20 61 72 67 75 6d  bOmitRowid argum
3720: 65 6e 74 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c  ent is non-zero,
3730: 20 61 73 73 75 6d 65 20 62 6f 74 68 20 6b 65 79   assume both key
3740: 73 20 65 6e 64 20 69 6e 20 61 20 72 6f 77 69 64  s end in a rowid
3750: 0a 2a 2a 20 66 69 65 6c 64 2e 20 46 6f 72 20 74  .** field. For t
3760: 68 65 20 70 75 72 70 6f 73 65 73 20 6f 66 20 74  he purposes of t
3770: 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2c 20 69  he comparison, i
3780: 67 6e 6f 72 65 20 69 74 2e 20 41 6c 73 6f 2c 20  gnore it. Also, 
3790: 69 66 20 62 4f 6d 69 74 52 6f 77 69 64 0a 2a 2a  if bOmitRowid.**
37a0: 20 69 73 20 74 72 75 65 20 61 6e 64 20 6b 65 79   is true and key
37b0: 31 20 63 6f 6e 74 61 69 6e 73 20 65 76 65 6e 20  1 contains even 
37c0: 61 20 73 69 6e 67 6c 65 20 4e 55 4c 4c 20 76 61  a single NULL va
37d0: 6c 75 65 2c 20 69 74 20 69 73 20 63 6f 6e 73 69  lue, it is consi
37e0: 64 65 72 65 64 20 74 6f 0a 2a 2a 20 62 65 20 6c  dered to.** be l
37f0: 65 73 73 20 74 68 61 6e 20 6b 65 79 32 2e 20 45  ess than key2. E
3800: 76 65 6e 20 69 66 20 6b 65 79 32 20 61 6c 73 6f  ven if key2 also
3810: 20 63 6f 6e 74 61 69 6e 73 20 4e 55 4c 4c 20 76   contains NULL v
3820: 61 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  alues..**.** If 
3830: 70 4b 65 79 32 20 69 73 20 70 61 73 73 65 64 20  pKey2 is passed 
3840: 61 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2c 20  a NULL pointer, 
3850: 74 68 65 6e 20 69 74 20 69 73 20 61 73 73 75 6d  then it is assum
3860: 65 64 20 74 68 61 74 20 74 68 65 20 70 43 73 72  ed that the pCsr
3870: 2d 3e 61 53 70 61 63 65 0a 2a 2a 20 68 61 73 20  ->aSpace.** has 
3880: 62 65 65 6e 20 61 6c 6c 6f 63 61 74 65 64 20 61  been allocated a
3890: 6e 64 20 63 6f 6e 74 61 69 6e 73 20 61 6e 20 75  nd contains an u
38a0: 6e 70 61 63 6b 65 64 20 72 65 63 6f 72 64 20 74  npacked record t
38b0: 68 61 74 20 69 73 20 75 73 65 64 20 61 73 20 6b  hat is used as k
38c0: 65 79 32 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ey2..*/.static v
38d0: 6f 69 64 20 76 64 62 65 53 6f 72 74 65 72 43 6f  oid vdbeSorterCo
38e0: 6d 70 61 72 65 28 0a 20 20 63 6f 6e 73 74 20 56  mpare(.  const V
38f0: 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c  dbeCursor *pCsr,
3900: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 73           /* Curs
3910: 6f 72 20 6f 62 6a 65 63 74 20 28 66 6f 72 20 70  or object (for p
3920: 4b 65 79 49 6e 66 6f 29 20 2a 2f 0a 20 20 69 6e  KeyInfo) */.  in
3930: 74 20 6e 49 67 6e 6f 72 65 2c 20 20 20 20 20 20  t nIgnore,      
3940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3950: 20 49 67 6e 6f 72 65 20 74 68 65 20 6c 61 73 74   Ignore the last
3960: 20 6e 49 67 6e 6f 72 65 20 66 69 65 6c 64 73 20   nIgnore fields 
3970: 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20  */.  const void 
3980: 2a 70 4b 65 79 31 2c 20 69 6e 74 20 6e 4b 65 79  *pKey1, int nKey
3990: 31 2c 20 20 20 2f 2a 20 4c 65 66 74 20 73 69 64  1,   /* Left sid
39a0: 65 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20  e of comparison 
39b0: 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20  */.  const void 
39c0: 2a 70 4b 65 79 32 2c 20 69 6e 74 20 6e 4b 65 79  *pKey2, int nKey
39d0: 32 2c 20 20 20 2f 2a 20 52 69 67 68 74 20 73 69  2,   /* Right si
39e0: 64 65 20 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e  de of comparison
39f0: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 52 65 73 20   */.  int *pRes 
3a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a10: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 52 65        /* OUT: Re
3a20: 73 75 6c 74 20 6f 66 20 63 6f 6d 70 61 72 69 73  sult of comparis
3a30: 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 4b 65 79 49 6e  on */.){.  KeyIn
3a40: 66 6f 20 2a 70 4b 65 79 49 6e 66 6f 20 3d 20 70  fo *pKeyInfo = p
3a50: 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 3b 0a 20  Csr->pKeyInfo;. 
3a60: 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f   VdbeSorter *pSo
3a70: 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f  rter = pCsr->pSo
3a80: 72 74 65 72 3b 0a 20 20 55 6e 70 61 63 6b 65 64  rter;.  Unpacked
3a90: 52 65 63 6f 72 64 20 2a 72 32 20 3d 20 70 53 6f  Record *r2 = pSo
3aa0: 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64 3b  rter->pUnpacked;
3ab0: 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 69 66 28  .  int i;..  if(
3ac0: 20 70 4b 65 79 32 20 29 7b 0a 20 20 20 20 73 71   pKey2 ){.    sq
3ad0: 6c 69 74 65 33 56 64 62 65 52 65 63 6f 72 64 55  lite3VdbeRecordU
3ae0: 6e 70 61 63 6b 28 70 4b 65 79 49 6e 66 6f 2c 20  npack(pKeyInfo, 
3af0: 6e 4b 65 79 32 2c 20 70 4b 65 79 32 2c 20 72 32  nKey2, pKey2, r2
3b00: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6e 49  );.  }..  if( nI
3b10: 67 6e 6f 72 65 20 29 7b 0a 20 20 20 20 72 32 2d  gnore ){.    r2-
3b20: 3e 6e 46 69 65 6c 64 20 3d 20 70 4b 65 79 49 6e  >nField = pKeyIn
3b30: 66 6f 2d 3e 6e 46 69 65 6c 64 20 2d 20 6e 49 67  fo->nField - nIg
3b40: 6e 6f 72 65 3b 0a 20 20 20 20 61 73 73 65 72 74  nore;.    assert
3b50: 28 20 72 32 2d 3e 6e 46 69 65 6c 64 3e 30 20 29  ( r2->nField>0 )
3b60: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69  ;.    for(i=0; i
3b70: 3c 72 32 2d 3e 6e 46 69 65 6c 64 3b 20 69 2b 2b  <r2->nField; i++
3b80: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 72 32 2d  ){.      if( r2-
3b90: 3e 61 4d 65 6d 5b 69 5d 2e 66 6c 61 67 73 20 26  >aMem[i].flags &
3ba0: 20 4d 45 4d 5f 4e 75 6c 6c 20 29 7b 0a 20 20 20   MEM_Null ){.   
3bb0: 20 20 20 20 20 2a 70 52 65 73 20 3d 20 2d 31 3b       *pRes = -1;
3bc0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 3b  .        return;
3bd0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
3be0: 20 20 20 61 73 73 65 72 74 28 20 72 32 2d 3e 64     assert( r2->d
3bf0: 65 66 61 75 6c 74 5f 72 63 3d 3d 30 20 29 3b 0a  efault_rc==0 );.
3c00: 20 20 7d 0a 0a 23 69 66 20 30 0a 20 20 2a 70 52    }..#if 0.  *pR
3c10: 65 73 20 3d 20 73 71 6c 69 74 65 33 56 64 62 65  es = sqlite3Vdbe
3c20: 52 65 63 6f 72 64 43 6f 6d 70 61 72 65 28 6e 4b  RecordCompare(nK
3c30: 65 79 31 2c 20 70 4b 65 79 31 2c 20 72 32 29 3b  ey1, pKey1, r2);
3c40: 0a 23 65 6e 64 69 66 0a 20 20 2a 70 52 65 73 20  .#endif.  *pRes 
3c50: 3d 20 70 53 6f 72 74 65 72 2d 3e 78 52 65 63 6f  = pSorter->xReco
3c60: 72 64 43 6f 6d 70 61 72 65 28 6e 4b 65 79 31 2c  rdCompare(nKey1,
3c70: 20 70 4b 65 79 31 2c 20 2a 28 28 75 38 2a 29 70   pKey1, *((u8*)p
3c80: 4b 65 79 31 29 2c 20 31 2c 20 72 32 29 3b 0a 7d  Key1), 1, r2);.}
3c90: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
3ca0: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20  ction is called 
3cb0: 74 6f 20 63 6f 6d 70 61 72 65 20 74 77 6f 20 69  to compare two i
3cc0: 74 65 72 61 74 6f 72 20 6b 65 79 73 20 77 68 65  terator keys whe
3cd0: 6e 20 6d 65 72 67 69 6e 67 20 0a 2a 2a 20 6d 75  n merging .** mu
3ce0: 6c 74 69 70 6c 65 20 62 2d 74 72 65 65 20 73 65  ltiple b-tree se
3cf0: 67 6d 65 6e 74 73 2e 20 50 61 72 61 6d 65 74 65  gments. Paramete
3d00: 72 20 69 4f 75 74 20 69 73 20 74 68 65 20 69 6e  r iOut is the in
3d10: 64 65 78 20 6f 66 20 74 68 65 20 61 54 72 65 65  dex of the aTree
3d20: 5b 5d 20 0a 2a 2a 20 76 61 6c 75 65 20 74 6f 20  [] .** value to 
3d30: 72 65 63 61 6c 63 75 6c 61 74 65 2e 0a 2a 2f 0a  recalculate..*/.
3d40: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53  static int vdbeS
3d50: 6f 72 74 65 72 44 6f 43 6f 6d 70 61 72 65 28 63  orterDoCompare(c
3d60: 6f 6e 73 74 20 56 64 62 65 43 75 72 73 6f 72 20  onst VdbeCursor 
3d70: 2a 70 43 73 72 2c 20 69 6e 74 20 69 4f 75 74 29  *pCsr, int iOut)
3d80: 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a  {.  VdbeSorter *
3d90: 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e  pSorter = pCsr->
3da0: 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 69  pSorter;.  int i
3db0: 31 3b 0a 20 20 69 6e 74 20 69 32 3b 0a 20 20 69  1;.  int i2;.  i
3dc0: 6e 74 20 69 52 65 73 3b 0a 20 20 56 64 62 65 53  nt iRes;.  VdbeS
3dd0: 6f 72 74 65 72 49 74 65 72 20 2a 70 31 3b 0a 20  orterIter *p1;. 
3de0: 20 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20   VdbeSorterIter 
3df0: 2a 70 32 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  *p2;..  assert( 
3e00: 69 4f 75 74 3c 70 53 6f 72 74 65 72 2d 3e 6e 54  iOut<pSorter->nT
3e10: 72 65 65 20 26 26 20 69 4f 75 74 3e 30 20 29 3b  ree && iOut>0 );
3e20: 0a 0a 20 20 69 66 28 20 69 4f 75 74 3e 3d 28 70  ..  if( iOut>=(p
3e30: 53 6f 72 74 65 72 2d 3e 6e 54 72 65 65 2f 32 29  Sorter->nTree/2)
3e40: 20 29 7b 0a 20 20 20 20 69 31 20 3d 20 28 69 4f   ){.    i1 = (iO
3e50: 75 74 20 2d 20 70 53 6f 72 74 65 72 2d 3e 6e 54  ut - pSorter->nT
3e60: 72 65 65 2f 32 29 20 2a 20 32 3b 0a 20 20 20 20  ree/2) * 2;.    
3e70: 69 32 20 3d 20 69 31 20 2b 20 31 3b 0a 20 20 7d  i2 = i1 + 1;.  }
3e80: 65 6c 73 65 7b 0a 20 20 20 20 69 31 20 3d 20 70  else{.    i1 = p
3e90: 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 69 4f  Sorter->aTree[iO
3ea0: 75 74 2a 32 5d 3b 0a 20 20 20 20 69 32 20 3d 20  ut*2];.    i2 = 
3eb0: 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 5b 69  pSorter->aTree[i
3ec0: 4f 75 74 2a 32 2b 31 5d 3b 0a 20 20 7d 0a 0a 20  Out*2+1];.  }.. 
3ed0: 20 70 31 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e   p1 = &pSorter->
3ee0: 61 49 74 65 72 5b 69 31 5d 3b 0a 20 20 70 32 20  aIter[i1];.  p2 
3ef0: 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 49 74 65  = &pSorter->aIte
3f00: 72 5b 69 32 5d 3b 0a 0a 20 20 69 66 28 20 70 31  r[i2];..  if( p1
3f10: 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20  ->pFile==0 ){.  
3f20: 20 20 69 52 65 73 20 3d 20 69 32 3b 0a 20 20 7d    iRes = i2;.  }
3f30: 65 6c 73 65 20 69 66 28 20 70 32 2d 3e 70 46 69  else if( p2->pFi
3f40: 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69 52 65  le==0 ){.    iRe
3f50: 73 20 3d 20 69 31 3b 0a 20 20 7d 65 6c 73 65 7b  s = i1;.  }else{
3f60: 0a 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 20 20  .    int res;.  
3f70: 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
3f80: 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b  pSorter->pUnpack
3f90: 65 64 21 3d 30 20 29 3b 20 20 2f 2a 20 61 6c 6c  ed!=0 );  /* all
3fa0: 6f 63 61 74 65 64 20 69 6e 20 76 64 62 65 53 6f  ocated in vdbeSo
3fb0: 72 74 65 72 4d 65 72 67 65 28 29 20 2a 2f 0a 20  rterMerge() */. 
3fc0: 20 20 20 76 64 62 65 53 6f 72 74 65 72 43 6f 6d     vdbeSorterCom
3fd0: 70 61 72 65 28 0a 20 20 20 20 20 20 20 20 70 43  pare(.        pC
3fe0: 73 72 2c 20 30 2c 20 70 31 2d 3e 61 4b 65 79 2c  sr, 0, p1->aKey,
3ff0: 20 70 31 2d 3e 6e 4b 65 79 2c 20 70 32 2d 3e 61   p1->nKey, p2->a
4000: 4b 65 79 2c 20 70 32 2d 3e 6e 4b 65 79 2c 20 26  Key, p2->nKey, &
4010: 72 65 73 0a 20 20 20 20 29 3b 0a 20 20 20 20 69  res.    );.    i
4020: 66 28 20 72 65 73 3c 3d 30 20 29 7b 0a 20 20 20  f( res<=0 ){.   
4030: 20 20 20 69 52 65 73 20 3d 20 69 31 3b 0a 20 20     iRes = i1;.  
4040: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69    }else{.      i
4050: 52 65 73 20 3d 20 69 32 3b 0a 20 20 20 20 7d 0a  Res = i2;.    }.
4060: 20 20 7d 0a 0a 20 20 70 53 6f 72 74 65 72 2d 3e    }..  pSorter->
4070: 61 54 72 65 65 5b 69 4f 75 74 5d 20 3d 20 69 52  aTree[iOut] = iR
4080: 65 73 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  es;.  return SQL
4090: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
40a0: 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20   Initialize the 
40b0: 74 65 6d 70 6f 72 61 72 79 20 69 6e 64 65 78 20  temporary index 
40c0: 63 75 72 73 6f 72 20 6a 75 73 74 20 6f 70 65 6e  cursor just open
40d0: 65 64 20 61 73 20 61 20 73 6f 72 74 65 72 20 63  ed as a sorter c
40e0: 75 72 73 6f 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71  ursor..*/.int sq
40f0: 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 49  lite3VdbeSorterI
4100: 6e 69 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c  nit(sqlite3 *db,
4110: 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73   VdbeCursor *pCs
4120: 72 29 7b 0a 20 20 69 6e 74 20 70 67 73 7a 3b 20  r){.  int pgsz; 
4130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4140: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 73 69        /* Page si
4150: 7a 65 20 6f 66 20 6d 61 69 6e 20 64 61 74 61 62  ze of main datab
4160: 61 73 65 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 43  ase */.  int mxC
4170: 61 63 68 65 3b 20 20 20 20 20 20 20 20 20 20 20  ache;           
4180: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61 63 68           /* Cach
4190: 65 20 73 69 7a 65 20 2a 2f 0a 20 20 56 64 62 65  e size */.  Vdbe
41a0: 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 3b  Sorter *pSorter;
41b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
41c0: 68 65 20 6e 65 77 20 73 6f 72 74 65 72 20 2a 2f  he new sorter */
41d0: 0a 20 20 63 68 61 72 20 2a 64 3b 20 20 20 20 20  .  char *d;     
41e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
41f0: 20 20 20 2f 2a 20 44 75 6d 6d 79 20 2a 2f 0a 0a     /* Dummy */..
4200: 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
4210: 70 4b 65 79 49 6e 66 6f 20 26 26 20 70 43 73 72  pKeyInfo && pCsr
4220: 2d 3e 70 42 74 3d 3d 30 20 29 3b 0a 20 20 70 43  ->pBt==0 );.  pC
4230: 73 72 2d 3e 70 53 6f 72 74 65 72 20 3d 20 70 53  sr->pSorter = pS
4240: 6f 72 74 65 72 20 3d 20 73 71 6c 69 74 65 33 44  orter = sqlite3D
4250: 62 4d 61 6c 6c 6f 63 5a 65 72 6f 28 64 62 2c 20  bMallocZero(db, 
4260: 73 69 7a 65 6f 66 28 56 64 62 65 53 6f 72 74 65  sizeof(VdbeSorte
4270: 72 29 29 3b 0a 20 20 69 66 28 20 70 53 6f 72 74  r));.  if( pSort
4280: 65 72 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74  er==0 ){.    ret
4290: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
42a0: 3b 0a 20 20 7d 0a 20 20 0a 20 20 70 53 6f 72 74  ;.  }.  .  pSort
42b0: 65 72 2d 3e 70 55 6e 70 61 63 6b 65 64 20 3d 20  er->pUnpacked = 
42c0: 73 71 6c 69 74 65 33 56 64 62 65 41 6c 6c 6f 63  sqlite3VdbeAlloc
42d0: 55 6e 70 61 63 6b 65 64 52 65 63 6f 72 64 28 70  UnpackedRecord(p
42e0: 43 73 72 2d 3e 70 4b 65 79 49 6e 66 6f 2c 20 30  Csr->pKeyInfo, 0
42f0: 2c 20 30 2c 20 26 64 29 3b 0a 20 20 69 66 28 20  , 0, &d);.  if( 
4300: 70 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b  pSorter->pUnpack
4310: 65 64 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53  ed==0 ) return S
4320: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 61  QLITE_NOMEM;.  a
4330: 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e  ssert( pSorter->
4340: 70 55 6e 70 61 63 6b 65 64 3d 3d 28 55 6e 70 61  pUnpacked==(Unpa
4350: 63 6b 65 64 52 65 63 6f 72 64 20 2a 29 64 20 29  ckedRecord *)d )
4360: 3b 0a 0a 20 20 69 66 28 20 21 73 71 6c 69 74 65  ;..  if( !sqlite
4370: 33 54 65 6d 70 49 6e 4d 65 6d 6f 72 79 28 64 62  3TempInMemory(db
4380: 29 20 29 7b 0a 20 20 20 20 70 67 73 7a 20 3d 20  ) ){.    pgsz = 
4390: 73 71 6c 69 74 65 33 42 74 72 65 65 47 65 74 50  sqlite3BtreeGetP
43a0: 61 67 65 53 69 7a 65 28 64 62 2d 3e 61 44 62 5b  ageSize(db->aDb[
43b0: 30 5d 2e 70 42 74 29 3b 0a 20 20 20 20 70 53 6f  0].pBt);.    pSo
43c0: 72 74 65 72 2d 3e 6d 6e 50 6d 61 53 69 7a 65 20  rter->mnPmaSize 
43d0: 3d 20 53 4f 52 54 45 52 5f 4d 49 4e 5f 57 4f 52  = SORTER_MIN_WOR
43e0: 4b 49 4e 47 20 2a 20 70 67 73 7a 3b 0a 20 20 20  KING * pgsz;.   
43f0: 20 6d 78 43 61 63 68 65 20 3d 20 64 62 2d 3e 61   mxCache = db->a
4400: 44 62 5b 30 5d 2e 70 53 63 68 65 6d 61 2d 3e 63  Db[0].pSchema->c
4410: 61 63 68 65 5f 73 69 7a 65 3b 0a 20 20 20 20 69  ache_size;.    i
4420: 66 28 20 6d 78 43 61 63 68 65 3c 53 4f 52 54 45  f( mxCache<SORTE
4430: 52 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 20 29 20  R_MIN_WORKING ) 
4440: 6d 78 43 61 63 68 65 20 3d 20 53 4f 52 54 45 52  mxCache = SORTER
4450: 5f 4d 49 4e 5f 57 4f 52 4b 49 4e 47 3b 0a 20 20  _MIN_WORKING;.  
4460: 20 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61    pSorter->mxPma
4470: 53 69 7a 65 20 3d 20 6d 78 43 61 63 68 65 20 2a  Size = mxCache *
4480: 20 70 67 73 7a 3b 0a 20 20 7d 0a 20 20 70 53 6f   pgsz;.  }.  pSo
4490: 72 74 65 72 2d 3e 78 52 65 63 6f 72 64 43 6f 6d  rter->xRecordCom
44a0: 70 61 72 65 20 3d 20 73 71 6c 69 74 65 33 56 64  pare = sqlite3Vd
44b0: 62 65 46 69 6e 64 53 6f 72 74 65 72 43 6f 6d 70  beFindSorterComp
44c0: 61 72 65 28 70 43 73 72 2d 3e 70 4b 65 79 49 6e  are(pCsr->pKeyIn
44d0: 66 6f 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 53  fo);..  return S
44e0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
44f0: 2a 2a 20 46 72 65 65 20 74 68 65 20 6c 69 73 74  ** Free the list
4500: 20 6f 66 20 73 6f 72 74 65 64 20 72 65 63 6f 72   of sorted recor
4510: 64 73 20 73 74 61 72 74 69 6e 67 20 61 74 20 70  ds starting at p
4520: 52 65 63 6f 72 64 2e 0a 2a 2f 0a 73 74 61 74 69  Record..*/.stati
4530: 63 20 76 6f 69 64 20 76 64 62 65 53 6f 72 74 65  c void vdbeSorte
4540: 72 52 65 63 6f 72 64 46 72 65 65 28 73 71 6c 69  rRecordFree(sqli
4550: 74 65 33 20 2a 64 62 2c 20 53 6f 72 74 65 72 52  te3 *db, SorterR
4560: 65 63 6f 72 64 20 2a 70 52 65 63 6f 72 64 29 7b  ecord *pRecord){
4570: 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20  .  SorterRecord 
4580: 2a 70 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f  *p;.  SorterReco
4590: 72 64 20 2a 70 4e 65 78 74 3b 0a 20 20 66 6f 72  rd *pNext;.  for
45a0: 28 70 3d 70 52 65 63 6f 72 64 3b 20 70 3b 20 70  (p=pRecord; p; p
45b0: 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 4e 65  =pNext){.    pNe
45c0: 78 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20  xt = p->pNext;. 
45d0: 20 20 20 73 71 6c 69 74 65 33 44 62 46 72 65 65     sqlite3DbFree
45e0: 28 64 62 2c 20 70 29 3b 0a 20 20 7d 0a 7d 0a 0a  (db, p);.  }.}..
45f0: 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 79 20 63  /*.** Free any c
4600: 75 72 73 6f 72 20 63 6f 6d 70 6f 6e 65 6e 74 73  ursor components
4610: 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20 73 71   allocated by sq
4620: 6c 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 58  lite3VdbeSorterX
4630: 58 58 20 72 6f 75 74 69 6e 65 73 2e 0a 2a 2f 0a  XX routines..*/.
4640: 76 6f 69 64 20 73 71 6c 69 74 65 33 56 64 62 65  void sqlite3Vdbe
4650: 53 6f 72 74 65 72 43 6c 6f 73 65 28 73 71 6c 69  SorterClose(sqli
4660: 74 65 33 20 2a 64 62 2c 20 56 64 62 65 43 75 72  te3 *db, VdbeCur
4670: 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 56 64  sor *pCsr){.  Vd
4680: 62 65 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65  beSorter *pSorte
4690: 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65  r = pCsr->pSorte
46a0: 72 3b 0a 20 20 69 66 28 20 70 53 6f 72 74 65 72  r;.  if( pSorter
46b0: 20 29 7b 0a 20 20 20 20 69 66 28 20 70 53 6f 72   ){.    if( pSor
46c0: 74 65 72 2d 3e 61 49 74 65 72 20 29 7b 0a 20 20  ter->aIter ){.  
46d0: 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20      int i;.     
46e0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 53 6f 72   for(i=0; i<pSor
46f0: 74 65 72 2d 3e 6e 54 72 65 65 3b 20 69 2b 2b 29  ter->nTree; i++)
4700: 7b 0a 20 20 20 20 20 20 20 20 76 64 62 65 53 6f  {.        vdbeSo
4710: 72 74 65 72 49 74 65 72 5a 65 72 6f 28 64 62 2c  rterIterZero(db,
4720: 20 26 70 53 6f 72 74 65 72 2d 3e 61 49 74 65 72   &pSorter->aIter
4730: 5b 69 5d 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  [i]);.      }.  
4740: 20 20 20 20 73 71 6c 69 74 65 33 44 62 46 72 65      sqlite3DbFre
4750: 65 28 64 62 2c 20 70 53 6f 72 74 65 72 2d 3e 61  e(db, pSorter->a
4760: 49 74 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20 20  Iter);.    }.   
4770: 20 69 66 28 20 70 53 6f 72 74 65 72 2d 3e 70 54   if( pSorter->pT
4780: 65 6d 70 31 20 29 7b 0a 20 20 20 20 20 20 73 71  emp1 ){.      sq
4790: 6c 69 74 65 33 4f 73 43 6c 6f 73 65 46 72 65 65  lite3OsCloseFree
47a0: 28 70 53 6f 72 74 65 72 2d 3e 70 54 65 6d 70 31  (pSorter->pTemp1
47b0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 76 64 62  );.    }.    vdb
47c0: 65 53 6f 72 74 65 72 52 65 63 6f 72 64 46 72 65  eSorterRecordFre
47d0: 65 28 64 62 2c 20 70 53 6f 72 74 65 72 2d 3e 70  e(db, pSorter->p
47e0: 52 65 63 6f 72 64 29 3b 0a 20 20 20 20 73 71 6c  Record);.    sql
47f0: 69 74 65 33 44 62 46 72 65 65 28 64 62 2c 20 70  ite3DbFree(db, p
4800: 53 6f 72 74 65 72 2d 3e 70 55 6e 70 61 63 6b 65  Sorter->pUnpacke
4810: 64 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 44  d);.    sqlite3D
4820: 62 46 72 65 65 28 64 62 2c 20 70 53 6f 72 74 65  bFree(db, pSorte
4830: 72 29 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70 53  r);.    pCsr->pS
4840: 6f 72 74 65 72 20 3d 20 30 3b 0a 20 20 7d 0a 7d  orter = 0;.  }.}
4850: 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65  ../*.** Allocate
4860: 20 73 70 61 63 65 20 66 6f 72 20 61 20 66 69 6c   space for a fil
4870: 65 2d 68 61 6e 64 6c 65 20 61 6e 64 20 6f 70 65  e-handle and ope
4880: 6e 20 61 20 74 65 6d 70 6f 72 61 72 79 20 66 69  n a temporary fi
4890: 6c 65 2e 20 49 66 20 73 75 63 63 65 73 73 66 75  le. If successfu
48a0: 6c 2c 0a 2a 2a 20 73 65 74 20 2a 70 70 46 69 6c  l,.** set *ppFil
48b0: 65 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68  e to point to th
48c0: 65 20 6d 61 6c 6c 6f 63 27 64 20 66 69 6c 65 2d  e malloc'd file-
48d0: 68 61 6e 64 6c 65 20 61 6e 64 20 72 65 74 75 72  handle and retur
48e0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2a 20  n SQLITE_OK..** 
48f0: 4f 74 68 65 72 77 69 73 65 2c 20 73 65 74 20 2a  Otherwise, set *
4900: 70 70 46 69 6c 65 20 74 6f 20 30 20 61 6e 64 20  ppFile to 0 and 
4910: 72 65 74 75 72 6e 20 61 6e 20 53 51 4c 69 74 65  return an SQLite
4920: 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2f 0a   error code..*/.
4930: 73 74 61 74 69 63 20 69 6e 74 20 76 64 62 65 53  static int vdbeS
4940: 6f 72 74 65 72 4f 70 65 6e 54 65 6d 70 46 69 6c  orterOpenTempFil
4950: 65 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 73  e(sqlite3 *db, s
4960: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 2a 70 70  qlite3_file **pp
4970: 46 69 6c 65 29 7b 0a 20 20 69 6e 74 20 64 75 6d  File){.  int dum
4980: 6d 79 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c  my;.  return sql
4990: 69 74 65 33 4f 73 4f 70 65 6e 4d 61 6c 6c 6f 63  ite3OsOpenMalloc
49a0: 28 64 62 2d 3e 70 56 66 73 2c 20 30 2c 20 70 70  (db->pVfs, 0, pp
49b0: 46 69 6c 65 2c 0a 20 20 20 20 20 20 53 51 4c 49  File,.      SQLI
49c0: 54 45 5f 4f 50 45 4e 5f 54 45 4d 50 5f 4a 4f 55  TE_OPEN_TEMP_JOU
49d0: 52 4e 41 4c 20 7c 0a 20 20 20 20 20 20 53 51 4c  RNAL |.      SQL
49e0: 49 54 45 5f 4f 50 45 4e 5f 52 45 41 44 57 52 49  ITE_OPEN_READWRI
49f0: 54 45 20 20 20 20 7c 20 53 51 4c 49 54 45 5f 4f  TE    | SQLITE_O
4a00: 50 45 4e 5f 43 52 45 41 54 45 20 7c 0a 20 20 20  PEN_CREATE |.   
4a10: 20 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 45     SQLITE_OPEN_E
4a20: 58 43 4c 55 53 49 56 45 20 20 20 20 7c 20 53 51  XCLUSIVE    | SQ
4a30: 4c 49 54 45 5f 4f 50 45 4e 5f 44 45 4c 45 54 45  LITE_OPEN_DELETE
4a40: 4f 4e 43 4c 4f 53 45 2c 20 26 64 75 6d 6d 79 0a  ONCLOSE, &dummy.
4a50: 20 20 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 65    );.}../*.** Me
4a60: 72 67 65 20 74 68 65 20 74 77 6f 20 73 6f 72 74  rge the two sort
4a70: 65 64 20 6c 69 73 74 73 20 70 31 20 61 6e 64 20  ed lists p1 and 
4a80: 70 32 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65  p2 into a single
4a90: 20 6c 69 73 74 2e 0a 2a 2a 20 53 65 74 20 2a 70   list..** Set *p
4aa0: 70 4f 75 74 20 74 6f 20 74 68 65 20 68 65 61 64  pOut to the head
4ab0: 20 6f 66 20 74 68 65 20 6e 65 77 20 6c 69 73 74   of the new list
4ac0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
4ad0: 20 76 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65   vdbeSorterMerge
4ae0: 28 0a 20 20 63 6f 6e 73 74 20 56 64 62 65 43 75  (.  const VdbeCu
4af0: 72 73 6f 72 20 2a 70 43 73 72 2c 20 20 20 20 20  rsor *pCsr,     
4b00: 20 20 20 20 2f 2a 20 46 6f 72 20 70 4b 65 79 49      /* For pKeyI
4b10: 6e 66 6f 20 2a 2f 0a 20 20 53 6f 72 74 65 72 52  nfo */.  SorterR
4b20: 65 63 6f 72 64 20 2a 70 31 2c 20 20 20 20 20 20  ecord *p1,      
4b30: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73           /* Firs
4b40: 74 20 6c 69 73 74 20 74 6f 20 6d 65 72 67 65 20  t list to merge 
4b50: 2a 2f 0a 20 20 53 6f 72 74 65 72 52 65 63 6f 72  */.  SorterRecor
4b60: 64 20 2a 70 32 2c 20 20 20 20 20 20 20 20 20 20  d *p2,          
4b70: 20 20 20 20 20 2f 2a 20 53 65 63 6f 6e 64 20 6c       /* Second l
4b80: 69 73 74 20 74 6f 20 6d 65 72 67 65 20 2a 2f 0a  ist to merge */.
4b90: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
4ba0: 2a 70 70 4f 75 74 20 20 20 20 20 20 20 20 20 20  *ppOut          
4bb0: 20 20 2f 2a 20 4f 55 54 3a 20 48 65 61 64 20 6f    /* OUT: Head o
4bc0: 66 20 6d 65 72 67 65 64 20 6c 69 73 74 20 2a 2f  f merged list */
4bd0: 0a 29 7b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f  .){.  SorterReco
4be0: 72 64 20 2a 70 46 69 6e 61 6c 20 3d 20 30 3b 0a  rd *pFinal = 0;.
4bf0: 20 20 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a    SorterRecord *
4c00: 2a 70 70 20 3d 20 26 70 46 69 6e 61 6c 3b 0a 20  *pp = &pFinal;. 
4c10: 20 76 6f 69 64 20 2a 70 56 61 6c 32 20 3d 20 70   void *pVal2 = p
4c20: 32 20 3f 20 70 32 2d 3e 70 56 61 6c 20 3a 20 30  2 ? p2->pVal : 0
4c30: 3b 0a 0a 20 20 77 68 69 6c 65 28 20 70 31 20 26  ;..  while( p1 &
4c40: 26 20 70 32 20 29 7b 0a 20 20 20 20 69 6e 74 20  & p2 ){.    int 
4c50: 72 65 73 3b 0a 20 20 20 20 76 64 62 65 53 6f 72  res;.    vdbeSor
4c60: 74 65 72 43 6f 6d 70 61 72 65 28 70 43 73 72 2c  terCompare(pCsr,
4c70: 20 30 2c 20 70 31 2d 3e 70 56 61 6c 2c 20 70 31   0, p1->pVal, p1
4c80: 2d 3e 6e 56 61 6c 2c 20 70 56 61 6c 32 2c 20 70  ->nVal, pVal2, p
4c90: 32 2d 3e 6e 56 61 6c 2c 20 26 72 65 73 29 3b 0a  2->nVal, &res);.
4ca0: 20 20 20 20 69 66 28 20 72 65 73 3c 3d 30 20 29      if( res<=0 )
4cb0: 7b 0a 20 20 20 20 20 20 2a 70 70 20 3d 20 70 31  {.      *pp = p1
4cc0: 3b 0a 20 20 20 20 20 20 70 70 20 3d 20 26 70 31  ;.      pp = &p1
4cd0: 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70  ->pNext;.      p
4ce0: 31 20 3d 20 70 31 2d 3e 70 4e 65 78 74 3b 0a 20  1 = p1->pNext;. 
4cf0: 20 20 20 20 20 70 56 61 6c 32 20 3d 20 30 3b 0a       pVal2 = 0;.
4d00: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
4d10: 20 2a 70 70 20 3d 20 70 32 3b 0a 20 20 20 20 20   *pp = p2;.     
4d20: 20 20 70 70 20 3d 20 26 70 32 2d 3e 70 4e 65 78    pp = &p2->pNex
4d30: 74 3b 0a 20 20 20 20 20 20 70 32 20 3d 20 70 32  t;.      p2 = p2
4d40: 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 69  ->pNext;.      i
4d50: 66 28 20 70 32 3d 3d 30 20 29 20 62 72 65 61 6b  f( p2==0 ) break
4d60: 3b 0a 20 20 20 20 20 20 70 56 61 6c 32 20 3d 20  ;.      pVal2 = 
4d70: 70 32 2d 3e 70 56 61 6c 3b 0a 20 20 20 20 7d 0a  p2->pVal;.    }.
4d80: 20 20 7d 0a 20 20 2a 70 70 20 3d 20 70 31 20 3f    }.  *pp = p1 ?
4d90: 20 70 31 20 3a 20 70 32 3b 0a 20 20 2a 70 70 4f   p1 : p2;.  *ppO
4da0: 75 74 20 3d 20 70 46 69 6e 61 6c 3b 0a 7d 0a 0a  ut = pFinal;.}..
4db0: 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74 68 65 20 6c  /*.** Sort the l
4dc0: 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20 72 65  inked list of re
4dd0: 63 6f 72 64 73 20 68 65 61 64 65 64 20 61 74 20  cords headed at 
4de0: 70 43 73 72 2d 3e 70 52 65 63 6f 72 64 2e 20 52  pCsr->pRecord. R
4df0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 0a  eturn SQLITE_OK.
4e00: 2a 2a 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  ** if successful
4e10: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65  , or an SQLite e
4e20: 72 72 6f 72 20 63 6f 64 65 20 28 69 2e 65 2e 20  rror code (i.e. 
4e30: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 20 69 66  SQLITE_NOMEM) if
4e40: 20 61 6e 20 65 72 72 6f 72 0a 2a 2a 20 6f 63 63   an error.** occ
4e50: 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  urs..*/.static i
4e60: 6e 74 20 76 64 62 65 53 6f 72 74 65 72 53 6f 72  nt vdbeSorterSor
4e70: 74 28 63 6f 6e 73 74 20 56 64 62 65 43 75 72 73  t(const VdbeCurs
4e80: 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 69 6e 74  or *pCsr){.  int
4e90: 20 69 3b 0a 20 20 53 6f 72 74 65 72 52 65 63 6f   i;.  SorterReco
4ea0: 72 64 20 2a 2a 61 53 6c 6f 74 3b 0a 20 20 53 6f  rd **aSlot;.  So
4eb0: 72 74 65 72 52 65 63 6f 72 64 20 2a 70 3b 0a 20  rterRecord *p;. 
4ec0: 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53 6f   VdbeSorter *pSo
4ed0: 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f  rter = pCsr->pSo
4ee0: 72 74 65 72 3b 0a 0a 20 20 61 53 6c 6f 74 20 3d  rter;..  aSlot =
4ef0: 20 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a   (SorterRecord *
4f00: 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a  *)sqlite3MallocZ
4f10: 65 72 6f 28 36 34 20 2a 20 73 69 7a 65 6f 66 28  ero(64 * sizeof(
4f20: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 29 29  SorterRecord *))
4f30: 3b 0a 20 20 69 66 28 20 21 61 53 6c 6f 74 20 29  ;.  if( !aSlot )
4f40: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  {.    return SQL
4f50: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a  ITE_NOMEM;.  }..
4f60: 20 20 70 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70    p = pSorter->p
4f70: 52 65 63 6f 72 64 3b 0a 20 20 77 68 69 6c 65 28  Record;.  while(
4f80: 20 70 20 29 7b 0a 20 20 20 20 53 6f 72 74 65 72   p ){.    Sorter
4f90: 52 65 63 6f 72 64 20 2a 70 4e 65 78 74 20 3d 20  Record *pNext = 
4fa0: 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 70 2d  p->pNext;.    p-
4fb0: 3e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20  >pNext = 0;.    
4fc0: 66 6f 72 28 69 3d 30 3b 20 61 53 6c 6f 74 5b 69  for(i=0; aSlot[i
4fd0: 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 76  ]; i++){.      v
4fe0: 64 62 65 53 6f 72 74 65 72 4d 65 72 67 65 28 70  dbeSorterMerge(p
4ff0: 43 73 72 2c 20 70 2c 20 61 53 6c 6f 74 5b 69 5d  Csr, p, aSlot[i]
5000: 2c 20 26 70 29 3b 0a 20 20 20 20 20 20 61 53 6c  , &p);.      aSl
5010: 6f 74 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 7d  ot[i] = 0;.    }
5020: 0a 20 20 20 20 61 53 6c 6f 74 5b 69 5d 20 3d 20  .    aSlot[i] = 
5030: 70 3b 0a 20 20 20 20 70 20 3d 20 70 4e 65 78 74  p;.    p = pNext
5040: 3b 0a 20 20 7d 0a 0a 20 20 70 20 3d 20 30 3b 0a  ;.  }..  p = 0;.
5050: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 36 34 3b    for(i=0; i<64;
5060: 20 69 2b 2b 29 7b 0a 20 20 20 20 76 64 62 65 53   i++){.    vdbeS
5070: 6f 72 74 65 72 4d 65 72 67 65 28 70 43 73 72 2c  orterMerge(pCsr,
5080: 20 70 2c 20 61 53 6c 6f 74 5b 69 5d 2c 20 26 70   p, aSlot[i], &p
5090: 29 3b 0a 20 20 7d 0a 20 20 70 53 6f 72 74 65 72  );.  }.  pSorter
50a0: 2d 3e 70 52 65 63 6f 72 64 20 3d 20 70 3b 0a 0a  ->pRecord = p;..
50b0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61    sqlite3_free(a
50c0: 53 6c 6f 74 29 3b 0a 20 20 72 65 74 75 72 6e 20  Slot);.  return 
50d0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
50e0: 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61  .** Initialize a
50f0: 20 66 69 6c 65 2d 77 72 69 74 65 72 20 6f 62 6a   file-writer obj
5100: 65 63 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ect..*/.static v
5110: 6f 69 64 20 66 69 6c 65 57 72 69 74 65 72 49 6e  oid fileWriterIn
5120: 69 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  it(.  sqlite3 *d
5130: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b,              
5140: 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
5150: 65 20 28 66 6f 72 20 6d 61 6c 6c 6f 63 29 20 2a  e (for malloc) *
5160: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  /.  sqlite3_file
5170: 20 2a 70 46 69 6c 65 2c 20 20 20 20 20 20 20 20   *pFile,        
5180: 20 20 20 20 2f 2a 20 46 69 6c 65 20 74 6f 20 77      /* File to w
5190: 72 69 74 65 20 74 6f 20 2a 2f 0a 20 20 46 69 6c  rite to */.  Fil
51a0: 65 57 72 69 74 65 72 20 2a 70 2c 20 20 20 20 20  eWriter *p,     
51b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
51c0: 4f 62 6a 65 63 74 20 74 6f 20 70 6f 70 75 6c 61  Object to popula
51d0: 74 65 20 2a 2f 0a 20 20 69 36 34 20 69 53 74 61  te */.  i64 iSta
51e0: 72 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20  rt              
51f0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65          /* Offse
5200: 74 20 6f 66 20 70 46 69 6c 65 20 74 6f 20 62 65  t of pFile to be
5210: 67 69 6e 20 77 72 69 74 69 6e 67 20 61 74 20 2a  gin writing at *
5220: 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e 42 75 66 20  /.){.  int nBuf 
5230: 3d 20 73 71 6c 69 74 65 33 42 74 72 65 65 47 65  = sqlite3BtreeGe
5240: 74 50 61 67 65 53 69 7a 65 28 64 62 2d 3e 61 44  tPageSize(db->aD
5250: 62 5b 30 5d 2e 70 42 74 29 3b 0a 0a 20 20 6d 65  b[0].pBt);..  me
5260: 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f  mset(p, 0, sizeo
5270: 66 28 46 69 6c 65 57 72 69 74 65 72 29 29 3b 0a  f(FileWriter));.
5280: 20 20 70 2d 3e 61 42 75 66 66 65 72 20 3d 20 28    p->aBuffer = (
5290: 75 38 20 2a 29 73 71 6c 69 74 65 33 44 62 4d 61  u8 *)sqlite3DbMa
52a0: 6c 6c 6f 63 52 61 77 28 64 62 2c 20 6e 42 75 66  llocRaw(db, nBuf
52b0: 29 3b 0a 20 20 69 66 28 20 21 70 2d 3e 61 42 75  );.  if( !p->aBu
52c0: 66 66 65 72 20 29 7b 0a 20 20 20 20 70 2d 3e 65  ffer ){.    p->e
52d0: 46 57 45 72 72 20 3d 20 53 51 4c 49 54 45 5f 4e  FWErr = SQLITE_N
52e0: 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  OMEM;.  }else{. 
52f0: 20 20 20 70 2d 3e 69 42 75 66 45 6e 64 20 3d 20     p->iBufEnd = 
5300: 70 2d 3e 69 42 75 66 53 74 61 72 74 20 3d 20 28  p->iBufStart = (
5310: 69 53 74 61 72 74 20 25 20 6e 42 75 66 29 3b 0a  iStart % nBuf);.
5320: 20 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66      p->iWriteOff
5330: 20 3d 20 69 53 74 61 72 74 20 2d 20 70 2d 3e 69   = iStart - p->i
5340: 42 75 66 53 74 61 72 74 3b 0a 20 20 20 20 70 2d  BufStart;.    p-
5350: 3e 6e 42 75 66 66 65 72 20 3d 20 6e 42 75 66 3b  >nBuffer = nBuf;
5360: 0a 20 20 20 20 70 2d 3e 70 46 69 6c 65 20 3d 20  .    p->pFile = 
5370: 70 46 69 6c 65 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  pFile;.  }.}../*
5380: 0a 2a 2a 20 57 72 69 74 65 20 6e 44 61 74 61 20  .** Write nData 
5390: 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 74 6f  bytes of data to
53a0: 20 74 68 65 20 66 69 6c 65 2d 77 72 69 74 65 20   the file-write 
53b0: 6f 62 6a 65 63 74 2e 20 52 65 74 75 72 6e 20 53  object. Return S
53c0: 51 4c 49 54 45 5f 4f 4b 0a 2a 2a 20 69 66 20 73  QLITE_OK.** if s
53d0: 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e  uccessful, or an
53e0: 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
53f0: 64 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f  de if an error o
5400: 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  ccurs..*/.static
5410: 20 76 6f 69 64 20 66 69 6c 65 57 72 69 74 65 72   void fileWriter
5420: 57 72 69 74 65 28 46 69 6c 65 57 72 69 74 65 72  Write(FileWriter
5430: 20 2a 70 2c 20 75 38 20 2a 70 44 61 74 61 2c 20   *p, u8 *pData, 
5440: 69 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20 69 6e  int nData){.  in
5450: 74 20 6e 52 65 6d 20 3d 20 6e 44 61 74 61 3b 0a  t nRem = nData;.
5460: 20 20 77 68 69 6c 65 28 20 6e 52 65 6d 3e 30 20    while( nRem>0 
5470: 26 26 20 70 2d 3e 65 46 57 45 72 72 3d 3d 30 20  && p->eFWErr==0 
5480: 29 7b 0a 20 20 20 20 69 6e 74 20 6e 43 6f 70 79  ){.    int nCopy
5490: 20 3d 20 6e 52 65 6d 3b 0a 20 20 20 20 69 66 28   = nRem;.    if(
54a0: 20 6e 43 6f 70 79 3e 28 70 2d 3e 6e 42 75 66 66   nCopy>(p->nBuff
54b0: 65 72 20 2d 20 70 2d 3e 69 42 75 66 45 6e 64 29  er - p->iBufEnd)
54c0: 20 29 7b 0a 20 20 20 20 20 20 6e 43 6f 70 79 20   ){.      nCopy 
54d0: 3d 20 70 2d 3e 6e 42 75 66 66 65 72 20 2d 20 70  = p->nBuffer - p
54e0: 2d 3e 69 42 75 66 45 6e 64 3b 0a 20 20 20 20 7d  ->iBufEnd;.    }
54f0: 0a 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 2d  ..    memcpy(&p-
5500: 3e 61 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66  >aBuffer[p->iBuf
5510: 45 6e 64 5d 2c 20 26 70 44 61 74 61 5b 6e 44 61  End], &pData[nDa
5520: 74 61 2d 6e 52 65 6d 5d 2c 20 6e 43 6f 70 79 29  ta-nRem], nCopy)
5530: 3b 0a 20 20 20 20 70 2d 3e 69 42 75 66 45 6e 64  ;.    p->iBufEnd
5540: 20 2b 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 69   += nCopy;.    i
5550: 66 28 20 70 2d 3e 69 42 75 66 45 6e 64 3d 3d 70  f( p->iBufEnd==p
5560: 2d 3e 6e 42 75 66 66 65 72 20 29 7b 0a 20 20 20  ->nBuffer ){.   
5570: 20 20 20 70 2d 3e 65 46 57 45 72 72 20 3d 20 73     p->eFWErr = s
5580: 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d  qlite3OsWrite(p-
5590: 3e 70 46 69 6c 65 2c 20 0a 20 20 20 20 20 20 20  >pFile, .       
55a0: 20 20 20 26 70 2d 3e 61 42 75 66 66 65 72 5b 70     &p->aBuffer[p
55b0: 2d 3e 69 42 75 66 53 74 61 72 74 5d 2c 20 70 2d  ->iBufStart], p-
55c0: 3e 69 42 75 66 45 6e 64 20 2d 20 70 2d 3e 69 42  >iBufEnd - p->iB
55d0: 75 66 53 74 61 72 74 2c 20 0a 20 20 20 20 20 20  ufStart, .      
55e0: 20 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66      p->iWriteOff
55f0: 20 2b 20 70 2d 3e 69 42 75 66 53 74 61 72 74 0a   + p->iBufStart.
5600: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 70        );.      p
5610: 2d 3e 69 42 75 66 53 74 61 72 74 20 3d 20 70 2d  ->iBufStart = p-
5620: 3e 69 42 75 66 45 6e 64 20 3d 20 30 3b 0a 20 20  >iBufEnd = 0;.  
5630: 20 20 20 20 70 2d 3e 69 57 72 69 74 65 4f 66 66      p->iWriteOff
5640: 20 2b 3d 20 70 2d 3e 6e 42 75 66 66 65 72 3b 0a   += p->nBuffer;.
5650: 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74      }.    assert
5660: 28 20 70 2d 3e 69 42 75 66 45 6e 64 3c 70 2d 3e  ( p->iBufEnd<p->
5670: 6e 42 75 66 66 65 72 20 29 3b 0a 0a 20 20 20 20  nBuffer );..    
5680: 6e 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20  nRem -= nCopy;. 
5690: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73   }.}../*.** Flus
56a0: 68 20 61 6e 79 20 62 75 66 66 65 72 65 64 20 64  h any buffered d
56b0: 61 74 61 20 74 6f 20 64 69 73 6b 20 61 6e 64 20  ata to disk and 
56c0: 63 6c 65 61 6e 20 75 70 20 74 68 65 20 66 69 6c  clean up the fil
56d0: 65 2d 77 72 69 74 65 72 20 6f 62 6a 65 63 74 2e  e-writer object.
56e0: 0a 2a 2a 20 54 68 65 20 72 65 73 75 6c 74 73 20  .** The results 
56f0: 6f 66 20 75 73 69 6e 67 20 74 68 65 20 66 69 6c  of using the fil
5700: 65 2d 77 72 69 74 65 72 20 61 66 74 65 72 20 74  e-writer after t
5710: 68 69 73 20 63 61 6c 6c 20 61 72 65 20 75 6e 64  his call are und
5720: 65 66 69 6e 65 64 2e 0a 2a 2a 20 52 65 74 75 72  efined..** Retur
5730: 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 66  n SQLITE_OK if f
5740: 6c 75 73 68 69 6e 67 20 74 68 65 20 62 75 66 66  lushing the buff
5750: 65 72 65 64 20 64 61 74 61 20 73 75 63 63 65 65  ered data succee
5760: 64 73 20 6f 72 20 69 73 20 6e 6f 74 20 0a 2a 2a  ds or is not .**
5770: 20 72 65 71 75 69 72 65 64 2e 20 4f 74 68 65 72   required. Other
5780: 77 69 73 65 2c 20 72 65 74 75 72 6e 20 61 6e 20  wise, return an 
5790: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
57a0: 65 2e 0a 2a 2a 0a 2a 2a 20 42 65 66 6f 72 65 20  e..**.** Before 
57b0: 72 65 74 75 72 6e 69 6e 67 2c 20 73 65 74 20 2a  returning, set *
57c0: 70 69 45 6f 66 20 74 6f 20 74 68 65 20 6f 66 66  piEof to the off
57d0: 73 65 74 20 69 6d 6d 65 64 69 61 74 65 6c 79 20  set immediately 
57e0: 66 6f 6c 6c 6f 77 69 6e 67 20 74 68 65 0a 2a 2a  following the.**
57f0: 20 6c 61 73 74 20 62 79 74 65 20 77 72 69 74 74   last byte writt
5800: 65 6e 20 74 6f 20 74 68 65 20 66 69 6c 65 2e 0a  en to the file..
5810: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69  */.static int fi
5820: 6c 65 57 72 69 74 65 72 46 69 6e 69 73 68 28 73  leWriterFinish(s
5830: 71 6c 69 74 65 33 20 2a 64 62 2c 20 46 69 6c 65  qlite3 *db, File
5840: 57 72 69 74 65 72 20 2a 70 2c 20 69 36 34 20 2a  Writer *p, i64 *
5850: 70 69 45 6f 66 29 7b 0a 20 20 69 6e 74 20 72 63  piEof){.  int rc
5860: 3b 0a 20 20 69 66 28 20 70 2d 3e 65 46 57 45 72  ;.  if( p->eFWEr
5870: 72 3d 3d 30 20 26 26 20 41 4c 57 41 59 53 28 70  r==0 && ALWAYS(p
5880: 2d 3e 61 42 75 66 66 65 72 29 20 26 26 20 70 2d  ->aBuffer) && p-
5890: 3e 69 42 75 66 45 6e 64 3e 70 2d 3e 69 42 75 66  >iBufEnd>p->iBuf
58a0: 53 74 61 72 74 20 29 7b 0a 20 20 20 20 70 2d 3e  Start ){.    p->
58b0: 65 46 57 45 72 72 20 3d 20 73 71 6c 69 74 65 33  eFWErr = sqlite3
58c0: 4f 73 57 72 69 74 65 28 70 2d 3e 70 46 69 6c 65  OsWrite(p->pFile
58d0: 2c 20 0a 20 20 20 20 20 20 20 20 26 70 2d 3e 61  , .        &p->a
58e0: 42 75 66 66 65 72 5b 70 2d 3e 69 42 75 66 53 74  Buffer[p->iBufSt
58f0: 61 72 74 5d 2c 20 70 2d 3e 69 42 75 66 45 6e 64  art], p->iBufEnd
5900: 20 2d 20 70 2d 3e 69 42 75 66 53 74 61 72 74 2c   - p->iBufStart,
5910: 20 0a 20 20 20 20 20 20 20 20 70 2d 3e 69 57 72   .        p->iWr
5920: 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69 42 75 66  iteOff + p->iBuf
5930: 53 74 61 72 74 0a 20 20 20 20 29 3b 0a 20 20 7d  Start.    );.  }
5940: 0a 20 20 2a 70 69 45 6f 66 20 3d 20 28 70 2d 3e  .  *piEof = (p->
5950: 69 57 72 69 74 65 4f 66 66 20 2b 20 70 2d 3e 69  iWriteOff + p->i
5960: 42 75 66 45 6e 64 29 3b 0a 20 20 73 71 6c 69 74  BufEnd);.  sqlit
5970: 65 33 44 62 46 72 65 65 28 64 62 2c 20 70 2d 3e  e3DbFree(db, p->
5980: 61 42 75 66 66 65 72 29 3b 0a 20 20 72 63 20 3d  aBuffer);.  rc =
5990: 20 70 2d 3e 65 46 57 45 72 72 3b 0a 20 20 6d 65   p->eFWErr;.  me
59a0: 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f  mset(p, 0, sizeo
59b0: 66 28 46 69 6c 65 57 72 69 74 65 72 29 29 3b 0a  f(FileWriter));.
59c0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
59d0: 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 76 61 6c 75  /*.** Write valu
59e0: 65 20 69 56 61 6c 20 65 6e 63 6f 64 65 64 20 61  e iVal encoded a
59f0: 73 20 61 20 76 61 72 69 6e 74 20 74 6f 20 74 68  s a varint to th
5a00: 65 20 66 69 6c 65 2d 77 72 69 74 65 20 6f 62 6a  e file-write obj
5a10: 65 63 74 2e 20 52 65 74 75 72 6e 20 0a 2a 2a 20  ect. Return .** 
5a20: 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63  SQLITE_OK if suc
5a30: 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53  cessful, or an S
5a40: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
5a50: 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   if an error occ
5a60: 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  urs..*/.static v
5a70: 6f 69 64 20 66 69 6c 65 57 72 69 74 65 72 57 72  oid fileWriterWr
5a80: 69 74 65 56 61 72 69 6e 74 28 46 69 6c 65 57 72  iteVarint(FileWr
5a90: 69 74 65 72 20 2a 70 2c 20 75 36 34 20 69 56 61  iter *p, u64 iVa
5aa0: 6c 29 7b 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b  l){.  int nByte;
5ab0: 20 0a 20 20 75 38 20 61 42 79 74 65 5b 31 30 5d   .  u8 aByte[10]
5ac0: 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 71 6c 69  ;.  nByte = sqli
5ad0: 74 65 33 50 75 74 56 61 72 69 6e 74 28 61 42 79  te3PutVarint(aBy
5ae0: 74 65 2c 20 69 56 61 6c 29 3b 0a 20 20 66 69 6c  te, iVal);.  fil
5af0: 65 57 72 69 74 65 72 57 72 69 74 65 28 70 2c 20  eWriterWrite(p, 
5b00: 61 42 79 74 65 2c 20 6e 42 79 74 65 29 3b 0a 7d  aByte, nByte);.}
5b10: 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 74 68  ../*.** Write th
5b20: 65 20 63 75 72 72 65 6e 74 20 63 6f 6e 74 65 6e  e current conten
5b30: 74 73 20 6f 66 20 74 68 65 20 69 6e 2d 6d 65 6d  ts of the in-mem
5b40: 6f 72 79 20 6c 69 6e 6b 65 64 2d 6c 69 73 74 20  ory linked-list 
5b50: 74 6f 20 61 20 50 4d 41 2e 20 52 65 74 75 72 6e  to a PMA. Return
5b60: 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66  .** SQLITE_OK if
5b70: 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20   successful, or 
5b80: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
5b90: 63 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a  code otherwise..
5ba0: 2a 2a 0a 2a 2a 20 54 68 65 20 66 6f 72 6d 61 74  **.** The format
5bb0: 20 6f 66 20 61 20 50 4d 41 20 69 73 3a 0a 2a 2a   of a PMA is:.**
5bc0: 0a 2a 2a 20 20 20 20 20 2a 20 41 20 76 61 72 69  .**     * A vari
5bd0: 6e 74 2e 20 54 68 69 73 20 76 61 72 69 6e 74 20  nt. This varint 
5be0: 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 74 6f 74  contains the tot
5bf0: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  al number of byt
5c00: 65 73 20 6f 66 20 63 6f 6e 74 65 6e 74 0a 2a 2a  es of content.**
5c10: 20 20 20 20 20 20 20 69 6e 20 74 68 65 20 50 4d         in the PM
5c20: 41 20 28 6e 6f 74 20 69 6e 63 6c 75 64 69 6e 67  A (not including
5c30: 20 74 68 65 20 76 61 72 69 6e 74 20 69 74 73 65   the varint itse
5c40: 6c 66 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a  lf)..**.**     *
5c50: 20 4f 6e 65 20 6f 72 20 6d 6f 72 65 20 72 65 63   One or more rec
5c60: 6f 72 64 73 20 70 61 63 6b 65 64 20 65 6e 64 2d  ords packed end-
5c70: 74 6f 2d 65 6e 64 20 69 6e 20 6f 72 64 65 72 20  to-end in order 
5c80: 6f 66 20 61 73 63 65 6e 64 69 6e 67 20 6b 65 79  of ascending key
5c90: 73 2e 20 0a 2a 2a 20 20 20 20 20 20 20 45 61 63  s. .**       Eac
5ca0: 68 20 72 65 63 6f 72 64 20 63 6f 6e 73 69 73 74  h record consist
5cb0: 73 20 6f 66 20 61 20 76 61 72 69 6e 74 20 66 6f  s of a varint fo
5cc0: 6c 6c 6f 77 65 64 20 62 79 20 61 20 62 6c 6f 62  llowed by a blob
5cd0: 20 6f 66 20 64 61 74 61 20 28 74 68 65 20 0a 2a   of data (the .*
5ce0: 2a 20 20 20 20 20 20 20 6b 65 79 29 2e 20 54 68  *       key). Th
5cf0: 65 20 76 61 72 69 6e 74 20 69 73 20 74 68 65 20  e varint is the 
5d00: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
5d10: 69 6e 20 74 68 65 20 62 6c 6f 62 20 6f 66 20 64  in the blob of d
5d20: 61 74 61 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ata..*/.static i
5d30: 6e 74 20 76 64 62 65 53 6f 72 74 65 72 4c 69 73  nt vdbeSorterLis
5d40: 74 54 6f 50 4d 41 28 73 71 6c 69 74 65 33 20 2a  tToPMA(sqlite3 *
5d50: 64 62 2c 20 63 6f 6e 73 74 20 56 64 62 65 43 75  db, const VdbeCu
5d60: 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 69  rsor *pCsr){.  i
5d70: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
5d80: 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  K;             /
5d90: 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
5da0: 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70  .  VdbeSorter *p
5db0: 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70  Sorter = pCsr->p
5dc0: 53 6f 72 74 65 72 3b 0a 20 20 46 69 6c 65 57 72  Sorter;.  FileWr
5dd0: 69 74 65 72 20 77 72 69 74 65 72 3b 0a 0a 20 20  iter writer;..  
5de0: 6d 65 6d 73 65 74 28 26 77 72 69 74 65 72 2c 20  memset(&writer, 
5df0: 30 2c 20 73 69 7a 65 6f 66 28 46 69 6c 65 57 72  0, sizeof(FileWr
5e00: 69 74 65 72 29 29 3b 0a 0a 20 20 69 66 28 20 70  iter));..  if( p
5e10: 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72  Sorter->nInMemor
5e20: 79 3d 3d 30 20 29 7b 0a 20 20 20 20 61 73 73 65  y==0 ){.    asse
5e30: 72 74 28 20 70 53 6f 72 74 65 72 2d 3e 70 52 65  rt( pSorter->pRe
5e40: 63 6f 72 64 3d 3d 30 20 29 3b 0a 20 20 20 20 72  cord==0 );.    r
5e50: 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20  eturn rc;.  }.. 
5e60: 20 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72   rc = vdbeSorter
5e70: 53 6f 72 74 28 70 43 73 72 29 3b 0a 0a 20 20 2f  Sort(pCsr);..  /
5e80: 2a 20 49 66 20 74 68 65 20 66 69 72 73 74 20 74  * If the first t
5e90: 65 6d 70 6f 72 61 72 79 20 50 4d 41 20 66 69 6c  emporary PMA fil
5ea0: 65 20 68 61 73 20 6e 6f 74 20 62 65 65 6e 20 6f  e has not been o
5eb0: 70 65 6e 65 64 2c 20 6f 70 65 6e 20 69 74 20 6e  pened, open it n
5ec0: 6f 77 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d  ow. */.  if( rc=
5ed0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 53  =SQLITE_OK && pS
5ee0: 6f 72 74 65 72 2d 3e 70 54 65 6d 70 31 3d 3d 30  orter->pTemp1==0
5ef0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 76 64 62   ){.    rc = vdb
5f00: 65 53 6f 72 74 65 72 4f 70 65 6e 54 65 6d 70 46  eSorterOpenTempF
5f10: 69 6c 65 28 64 62 2c 20 26 70 53 6f 72 74 65 72  ile(db, &pSorter
5f20: 2d 3e 70 54 65 6d 70 31 29 3b 0a 20 20 20 20 61  ->pTemp1);.    a
5f30: 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54  ssert( rc!=SQLIT
5f40: 45 5f 4f 4b 20 7c 7c 20 70 53 6f 72 74 65 72 2d  E_OK || pSorter-
5f50: 3e 70 54 65 6d 70 31 20 29 3b 0a 20 20 20 20 61  >pTemp1 );.    a
5f60: 73 73 65 72 74 28 20 70 53 6f 72 74 65 72 2d 3e  ssert( pSorter->
5f70: 69 57 72 69 74 65 4f 66 66 3d 3d 30 20 29 3b 0a  iWriteOff==0 );.
5f80: 20 20 20 20 61 73 73 65 72 74 28 20 70 53 6f 72      assert( pSor
5f90: 74 65 72 2d 3e 6e 50 4d 41 3d 3d 30 20 29 3b 0a  ter->nPMA==0 );.
5fa0: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53    }..  if( rc==S
5fb0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
5fc0: 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a 70 3b  SorterRecord *p;
5fd0: 0a 20 20 20 20 53 6f 72 74 65 72 52 65 63 6f 72  .    SorterRecor
5fe0: 64 20 2a 70 4e 65 78 74 20 3d 20 30 3b 0a 0a 20  d *pNext = 0;.. 
5ff0: 20 20 20 66 69 6c 65 57 72 69 74 65 72 49 6e 69     fileWriterIni
6000: 74 28 64 62 2c 20 70 53 6f 72 74 65 72 2d 3e 70  t(db, pSorter->p
6010: 54 65 6d 70 31 2c 20 26 77 72 69 74 65 72 2c 20  Temp1, &writer, 
6020: 70 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f  pSorter->iWriteO
6030: 66 66 29 3b 0a 20 20 20 20 70 53 6f 72 74 65 72  ff);.    pSorter
6040: 2d 3e 6e 50 4d 41 2b 2b 3b 0a 20 20 20 20 66 69  ->nPMA++;.    fi
6050: 6c 65 57 72 69 74 65 72 57 72 69 74 65 56 61 72  leWriterWriteVar
6060: 69 6e 74 28 26 77 72 69 74 65 72 2c 20 70 53 6f  int(&writer, pSo
6070: 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 29  rter->nInMemory)
6080: 3b 0a 20 20 20 20 66 6f 72 28 70 3d 70 53 6f 72  ;.    for(p=pSor
6090: 74 65 72 2d 3e 70 52 65 63 6f 72 64 3b 20 70 3b  ter->pRecord; p;
60a0: 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 20   p=pNext){.     
60b0: 20 70 4e 65 78 74 20 3d 20 70 2d 3e 70 4e 65 78   pNext = p->pNex
60c0: 74 3b 0a 20 20 20 20 20 20 66 69 6c 65 57 72 69  t;.      fileWri
60d0: 74 65 72 57 72 69 74 65 56 61 72 69 6e 74 28 26  terWriteVarint(&
60e0: 77 72 69 74 65 72 2c 20 70 2d 3e 6e 56 61 6c 29  writer, p->nVal)
60f0: 3b 0a 20 20 20 20 20 20 66 69 6c 65 57 72 69 74  ;.      fileWrit
6100: 65 72 57 72 69 74 65 28 26 77 72 69 74 65 72 2c  erWrite(&writer,
6110: 20 70 2d 3e 70 56 61 6c 2c 20 70 2d 3e 6e 56 61   p->pVal, p->nVa
6120: 6c 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  l);.      sqlite
6130: 33 44 62 46 72 65 65 28 64 62 2c 20 70 29 3b 0a  3DbFree(db, p);.
6140: 20 20 20 20 7d 0a 20 20 20 20 70 53 6f 72 74 65      }.    pSorte
6150: 72 2d 3e 70 52 65 63 6f 72 64 20 3d 20 70 3b 0a  r->pRecord = p;.
6160: 20 20 20 20 72 63 20 3d 20 66 69 6c 65 57 72 69      rc = fileWri
6170: 74 65 72 46 69 6e 69 73 68 28 64 62 2c 20 26 77  terFinish(db, &w
6180: 72 69 74 65 72 2c 20 26 70 53 6f 72 74 65 72 2d  riter, &pSorter-
6190: 3e 69 57 72 69 74 65 4f 66 66 29 3b 0a 20 20 7d  >iWriteOff);.  }
61a0: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
61b0: 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 72 65  ../*.** Add a re
61c0: 63 6f 72 64 20 74 6f 20 74 68 65 20 73 6f 72 74  cord to the sort
61d0: 65 72 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  er..*/.int sqlit
61e0: 65 33 56 64 62 65 53 6f 72 74 65 72 57 72 69 74  e3VdbeSorterWrit
61f0: 65 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  e(.  sqlite3 *db
6200: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
6210: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
6220: 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e   handle */.  con
6230: 73 74 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70  st VdbeCursor *p
6240: 43 73 72 2c 20 20 20 20 20 20 20 20 20 20 20 20  Csr,            
6250: 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 63 75 72     /* Sorter cur
6260: 73 6f 72 20 2a 2f 0a 20 20 4d 65 6d 20 2a 70 56  sor */.  Mem *pV
6270: 61 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  al              
6280: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 65 6d 6f           /* Memo
6290: 72 79 20 63 65 6c 6c 20 63 6f 6e 74 61 69 6e 69  ry cell containi
62a0: 6e 67 20 72 65 63 6f 72 64 20 2a 2f 0a 29 7b 0a  ng record */.){.
62b0: 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
62c0: 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53  orter = pCsr->pS
62d0: 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 72 63 20  orter;.  int rc 
62e0: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20  = SQLITE_OK;    
62f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
6300: 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 53 6f 72  rn Code */.  Sor
6310: 74 65 72 52 65 63 6f 72 64 20 2a 70 4e 65 77 3b  terRecord *pNew;
6320: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6330: 4e 65 77 20 6c 69 73 74 20 65 6c 65 6d 65 6e 74  New list element
6340: 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70   */..  assert( p
6350: 53 6f 72 74 65 72 20 29 3b 0a 20 20 70 53 6f 72  Sorter );.  pSor
6360: 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 20 2b  ter->nInMemory +
6370: 3d 20 73 71 6c 69 74 65 33 56 61 72 69 6e 74 4c  = sqlite3VarintL
6380: 65 6e 28 70 56 61 6c 2d 3e 6e 29 20 2b 20 70 56  en(pVal->n) + pV
6390: 61 6c 2d 3e 6e 3b 0a 0a 20 20 70 4e 65 77 20 3d  al->n;..  pNew =
63a0: 20 28 53 6f 72 74 65 72 52 65 63 6f 72 64 20 2a   (SorterRecord *
63b0: 29 73 71 6c 69 74 65 33 44 62 4d 61 6c 6c 6f 63  )sqlite3DbMalloc
63c0: 52 61 77 28 64 62 2c 20 70 56 61 6c 2d 3e 6e 20  Raw(db, pVal->n 
63d0: 2b 20 73 69 7a 65 6f 66 28 53 6f 72 74 65 72 52  + sizeof(SorterR
63e0: 65 63 6f 72 64 29 29 3b 0a 20 20 69 66 28 20 70  ecord));.  if( p
63f0: 4e 65 77 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63  New==0 ){.    rc
6400: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
6410: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 4e  .  }else{.    pN
6420: 65 77 2d 3e 70 56 61 6c 20 3d 20 28 76 6f 69 64  ew->pVal = (void
6430: 20 2a 29 26 70 4e 65 77 5b 31 5d 3b 0a 20 20 20   *)&pNew[1];.   
6440: 20 6d 65 6d 63 70 79 28 70 4e 65 77 2d 3e 70 56   memcpy(pNew->pV
6450: 61 6c 2c 20 70 56 61 6c 2d 3e 7a 2c 20 70 56 61  al, pVal->z, pVa
6460: 6c 2d 3e 6e 29 3b 0a 20 20 20 20 70 4e 65 77 2d  l->n);.    pNew-
6470: 3e 6e 56 61 6c 20 3d 20 70 56 61 6c 2d 3e 6e 3b  >nVal = pVal->n;
6480: 0a 20 20 20 20 70 4e 65 77 2d 3e 70 4e 65 78 74  .    pNew->pNext
6490: 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 52 65 63   = pSorter->pRec
64a0: 6f 72 64 3b 0a 20 20 20 20 70 53 6f 72 74 65 72  ord;.    pSorter
64b0: 2d 3e 70 52 65 63 6f 72 64 20 3d 20 70 4e 65 77  ->pRecord = pNew
64c0: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 65 65 20  ;.  }..  /* See 
64d0: 69 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  if the contents 
64e0: 6f 66 20 74 68 65 20 73 6f 72 74 65 72 20 73 68  of the sorter sh
64f0: 6f 75 6c 64 20 6e 6f 77 20 62 65 20 77 72 69 74  ould now be writ
6500: 74 65 6e 20 6f 75 74 2e 20 54 68 65 79 0a 20 20  ten out. They.  
6510: 2a 2a 20 61 72 65 20 77 72 69 74 74 65 6e 20 6f  ** are written o
6520: 75 74 20 77 68 65 6e 20 65 69 74 68 65 72 20 6f  ut when either o
6530: 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  f the following 
6540: 61 72 65 20 74 72 75 65 3a 0a 20 20 2a 2a 0a 20  are true:.  **. 
6550: 20 2a 2a 20 20 20 2a 20 54 68 65 20 74 6f 74 61   **   * The tota
6560: 6c 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74  l memory allocat
6570: 65 64 20 66 6f 72 20 74 68 65 20 69 6e 2d 6d 65  ed for the in-me
6580: 6d 6f 72 79 20 6c 69 73 74 20 69 73 20 67 72 65  mory list is gre
6590: 61 74 65 72 20 0a 20 20 2a 2a 20 20 20 20 20 74  ater .  **     t
65a0: 68 61 6e 20 28 70 61 67 65 2d 73 69 7a 65 20 2a  han (page-size *
65b0: 20 63 61 63 68 65 2d 73 69 7a 65 29 2c 20 6f 72   cache-size), or
65c0: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 54  .  **.  **   * T
65d0: 68 65 20 74 6f 74 61 6c 20 6d 65 6d 6f 72 79 20  he total memory 
65e0: 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 74 68  allocated for th
65f0: 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74  e in-memory list
6600: 20 69 73 20 67 72 65 61 74 65 72 20 0a 20 20 2a   is greater .  *
6610: 2a 20 20 20 20 20 74 68 61 6e 20 28 70 61 67 65  *     than (page
6620: 2d 73 69 7a 65 20 2a 20 31 30 29 20 61 6e 64 20  -size * 10) and 
6630: 73 71 6c 69 74 65 33 48 65 61 70 4e 65 61 72 6c  sqlite3HeapNearl
6640: 79 46 75 6c 6c 28 29 20 72 65 74 75 72 6e 73 20  yFull() returns 
6650: 74 72 75 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  true..  */.  if(
6660: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
6670: 26 20 70 53 6f 72 74 65 72 2d 3e 6d 78 50 6d 61  & pSorter->mxPma
6680: 53 69 7a 65 3e 30 20 26 26 20 28 0a 20 20 20 20  Size>0 && (.    
6690: 20 20 20 20 28 70 53 6f 72 74 65 72 2d 3e 6e 49      (pSorter->nI
66a0: 6e 4d 65 6d 6f 72 79 3e 70 53 6f 72 74 65 72 2d  nMemory>pSorter-
66b0: 3e 6d 78 50 6d 61 53 69 7a 65 29 0a 20 20 20 20  >mxPmaSize).    
66c0: 20 7c 7c 20 28 70 53 6f 72 74 65 72 2d 3e 6e 49   || (pSorter->nI
66d0: 6e 4d 65 6d 6f 72 79 3e 70 53 6f 72 74 65 72 2d  nMemory>pSorter-
66e0: 3e 6d 6e 50 6d 61 53 69 7a 65 20 26 26 20 73 71  >mnPmaSize && sq
66f0: 6c 69 74 65 33 48 65 61 70 4e 65 61 72 6c 79 46  lite3HeapNearlyF
6700: 75 6c 6c 28 29 29 0a 20 20 29 29 7b 0a 23 69 66  ull()).  )){.#if
6710: 64 65 66 20 53 51 4c 49 54 45 5f 44 45 42 55 47  def SQLITE_DEBUG
6720: 0a 20 20 20 20 69 36 34 20 6e 45 78 70 65 63 74  .    i64 nExpect
6730: 20 3d 20 70 53 6f 72 74 65 72 2d 3e 69 57 72 69   = pSorter->iWri
6740: 74 65 4f 66 66 0a 20 20 20 20 20 20 20 20 20 20  teOff.          
6750: 20 20 20 20 20 20 2b 20 73 71 6c 69 74 65 33 56        + sqlite3V
6760: 61 72 69 6e 74 4c 65 6e 28 70 53 6f 72 74 65 72  arintLen(pSorter
6770: 2d 3e 6e 49 6e 4d 65 6d 6f 72 79 29 0a 20 20 20  ->nInMemory).   
6780: 20 20 20 20 20 20 20 20 20 20 20 20 20 2b 20 70               + p
6790: 53 6f 72 74 65 72 2d 3e 6e 49 6e 4d 65 6d 6f 72  Sorter->nInMemor
67a0: 79 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 72 63  y;.#endif.    rc
67b0: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4c 69 73   = vdbeSorterLis
67c0: 74 54 6f 50 4d 41 28 64 62 2c 20 70 43 73 72 29  tToPMA(db, pCsr)
67d0: 3b 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 6e  ;.    pSorter->n
67e0: 49 6e 4d 65 6d 6f 72 79 20 3d 20 30 3b 0a 20 20  InMemory = 0;.  
67f0: 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51    assert( rc!=SQ
6800: 4c 49 54 45 5f 4f 4b 20 7c 7c 20 28 6e 45 78 70  LITE_OK || (nExp
6810: 65 63 74 3d 3d 70 53 6f 72 74 65 72 2d 3e 69 57  ect==pSorter->iW
6820: 72 69 74 65 4f 66 66 29 20 29 3b 0a 20 20 7d 0a  riteOff) );.  }.
6830: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
6840: 0a 2f 2a 0a 2a 2a 20 48 65 6c 70 65 72 20 66 75  ./*.** Helper fu
6850: 6e 63 74 69 6f 6e 20 66 6f 72 20 73 71 6c 69 74  nction for sqlit
6860: 65 33 56 64 62 65 53 6f 72 74 65 72 52 65 77 69  e3VdbeSorterRewi
6870: 6e 64 28 29 2e 20 0a 2a 2f 0a 73 74 61 74 69 63  nd(). .*/.static
6880: 20 69 6e 74 20 76 64 62 65 53 6f 72 74 65 72 49   int vdbeSorterI
6890: 6e 69 74 4d 65 72 67 65 28 0a 20 20 73 71 6c 69  nitMerge(.  sqli
68a0: 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20  te3 *db,        
68b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
68c0: 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a  atabase handle *
68d0: 2f 0a 20 20 63 6f 6e 73 74 20 56 64 62 65 43 75  /.  const VdbeCu
68e0: 72 73 6f 72 20 2a 70 43 73 72 2c 20 20 20 20 20  rsor *pCsr,     
68f0: 20 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 68 61      /* Cursor ha
6900: 6e 64 6c 65 20 66 6f 72 20 74 68 69 73 20 73 6f  ndle for this so
6910: 72 74 65 72 20 2a 2f 0a 20 20 69 36 34 20 2a 70  rter */.  i64 *p
6920: 6e 42 79 74 65 20 20 20 20 20 20 20 20 20 20 20  nByte           
6930: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 75 6d            /* Sum
6940: 20 6f 66 20 62 79 74 65 73 20 69 6e 20 61 6c 6c   of bytes in all
6950: 20 6f 70 65 6e 65 64 20 50 4d 41 73 20 2a 2f 0a   opened PMAs */.
6960: 29 7b 0a 20 20 56 64 62 65 53 6f 72 74 65 72 20  ){.  VdbeSorter 
6970: 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d  *pSorter = pCsr-
6980: 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20  >pSorter;.  int 
6990: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20  rc = SQLITE_OK; 
69a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
69b0: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
69c0: 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20  int i;          
69d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
69e0: 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72 61  /* Used to itera
69f0: 74 6f 72 20 74 68 72 6f 75 67 68 20 61 49 74 65  tor through aIte
6a00: 72 5b 5d 20 2a 2f 0a 20 20 69 36 34 20 6e 42 79  r[] */.  i64 nBy
6a10: 74 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  te = 0;         
6a20: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 74 61           /* Tota
6a30: 6c 20 62 79 74 65 73 20 69 6e 20 61 6c 6c 20 6f  l bytes in all o
6a40: 70 65 6e 65 64 20 50 4d 41 73 20 2a 2f 0a 0a 20  pened PMAs */.. 
6a50: 20 2f 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 74   /* Initialize t
6a60: 68 65 20 69 74 65 72 61 74 6f 72 73 2e 20 2a 2f  he iterators. */
6a70: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 53 4f  .  for(i=0; i<SO
6a80: 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43  RTER_MAX_MERGE_C
6a90: 4f 55 4e 54 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  OUNT; i++){.    
6aa0: 56 64 62 65 53 6f 72 74 65 72 49 74 65 72 20 2a  VdbeSorterIter *
6ab0: 70 49 74 65 72 20 3d 20 26 70 53 6f 72 74 65 72  pIter = &pSorter
6ac0: 2d 3e 61 49 74 65 72 5b 69 5d 3b 0a 20 20 20 20  ->aIter[i];.    
6ad0: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 49  rc = vdbeSorterI
6ae0: 74 65 72 49 6e 69 74 28 64 62 2c 20 70 53 6f 72  terInit(db, pSor
6af0: 74 65 72 2c 20 70 53 6f 72 74 65 72 2d 3e 69 52  ter, pSorter->iR
6b00: 65 61 64 4f 66 66 2c 20 70 49 74 65 72 2c 20 26  eadOff, pIter, &
6b10: 6e 42 79 74 65 29 3b 0a 20 20 20 20 70 53 6f 72  nByte);.    pSor
6b20: 74 65 72 2d 3e 69 52 65 61 64 4f 66 66 20 3d 20  ter->iReadOff = 
6b30: 70 49 74 65 72 2d 3e 69 45 6f 66 3b 0a 20 20 20  pIter->iEof;.   
6b40: 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c   assert( rc!=SQL
6b50: 49 54 45 5f 4f 4b 20 7c 7c 20 70 53 6f 72 74 65  ITE_OK || pSorte
6b60: 72 2d 3e 69 52 65 61 64 4f 66 66 3c 3d 70 53 6f  r->iReadOff<=pSo
6b70: 72 74 65 72 2d 3e 69 57 72 69 74 65 4f 66 66 20  rter->iWriteOff 
6b80: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53  );.    if( rc!=S
6b90: 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53 6f 72  QLITE_OK || pSor
6ba0: 74 65 72 2d 3e 69 52 65 61 64 4f 66 66 3e 3d 70  ter->iReadOff>=p
6bb0: 53 6f 72 74 65 72 2d 3e 69 57 72 69 74 65 4f 66  Sorter->iWriteOf
6bc0: 66 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a  f ) break;.  }..
6bd0: 20 20 2f 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20    /* Initialize 
6be0: 74 68 65 20 61 54 72 65 65 5b 5d 20 61 72 72 61  the aTree[] arra
6bf0: 79 2e 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 70 53  y. */.  for(i=pS
6c00: 6f 72 74 65 72 2d 3e 6e 54 72 65 65 2d 31 3b 20  orter->nTree-1; 
6c10: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
6c20: 20 69 3e 30 3b 20 69 2d 2d 29 7b 0a 20 20 20 20   i>0; i--){.    
6c30: 72 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 44  rc = vdbeSorterD
6c40: 6f 43 6f 6d 70 61 72 65 28 70 43 73 72 2c 20 69  oCompare(pCsr, i
6c50: 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 6e 42 79 74  );.  }..  *pnByt
6c60: 65 20 3d 20 6e 42 79 74 65 3b 0a 20 20 72 65 74  e = nByte;.  ret
6c70: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
6c80: 20 4f 6e 63 65 20 74 68 65 20 73 6f 72 74 65 72   Once the sorter
6c90: 20 68 61 73 20 62 65 65 6e 20 70 6f 70 75 6c 61   has been popula
6ca0: 74 65 64 2c 20 74 68 69 73 20 66 75 6e 63 74 69  ted, this functi
6cb0: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20  on is called to 
6cc0: 70 72 65 70 61 72 65 0a 2a 2a 20 66 6f 72 20 69  prepare.** for i
6cd0: 74 65 72 61 74 69 6e 67 20 74 68 72 6f 75 67 68  terating through
6ce0: 20 69 74 73 20 63 6f 6e 74 65 6e 74 73 20 69 6e   its contents in
6cf0: 20 73 6f 72 74 65 64 20 6f 72 64 65 72 2e 0a 2a   sorted order..*
6d00: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 56 64 62  /.int sqlite3Vdb
6d10: 65 53 6f 72 74 65 72 52 65 77 69 6e 64 28 73 71  eSorterRewind(sq
6d20: 6c 69 74 65 33 20 2a 64 62 2c 20 63 6f 6e 73 74  lite3 *db, const
6d30: 20 56 64 62 65 43 75 72 73 6f 72 20 2a 70 43 73   VdbeCursor *pCs
6d40: 72 2c 20 69 6e 74 20 2a 70 62 45 6f 66 29 7b 0a  r, int *pbEof){.
6d50: 20 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53    VdbeSorter *pS
6d60: 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53  orter = pCsr->pS
6d70: 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 72 63 3b  orter;.  int rc;
6d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d90: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
6da0: 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 73 71 6c  rn code */.  sql
6db0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 54 65 6d 70  ite3_file *pTemp
6dc0: 32 20 3d 20 30 3b 20 20 20 20 20 20 20 2f 2a 20  2 = 0;       /* 
6dd0: 53 65 63 6f 6e 64 20 74 65 6d 70 20 66 69 6c 65  Second temp file
6de0: 20 74 6f 20 75 73 65 20 2a 2f 0a 20 20 69 36 34   to use */.  i64
6df0: 20 69 57 72 69 74 65 32 20 3d 20 30 3b 20 20 20   iWrite2 = 0;   
6e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6e10: 57 72 69 74 65 20 6f 66 66 73 65 74 20 66 6f 72  Write offset for
6e20: 20 70 54 65 6d 70 32 20 2a 2f 0a 20 20 69 6e 74   pTemp2 */.  int
6e30: 20 6e 49 74 65 72 3b 20 20 20 20 20 20 20 20 20   nIter;         
6e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6e50: 4e 75 6d 62 65 72 20 6f 66 20 69 74 65 72 61 74  Number of iterat
6e60: 6f 72 73 20 75 73 65 64 20 2a 2f 0a 20 20 69 6e  ors used */.  in
6e70: 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20  t nByte;        
6e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6e90: 20 42 79 74 65 73 20 6f 66 20 73 70 61 63 65 20   Bytes of space 
6ea0: 72 65 71 75 69 72 65 64 20 66 6f 72 20 61 49 74  required for aIt
6eb0: 65 72 2f 61 54 72 65 65 20 2a 2f 0a 20 20 69 6e  er/aTree */.  in
6ec0: 74 20 4e 20 3d 20 32 3b 20 20 20 20 20 20 20 20  t N = 2;        
6ed0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6ee0: 20 50 6f 77 65 72 20 6f 66 20 32 20 3e 3d 20 6e   Power of 2 >= n
6ef0: 49 74 65 72 20 2a 2f 0a 0a 20 20 61 73 73 65 72  Iter */..  asser
6f00: 74 28 20 70 53 6f 72 74 65 72 20 29 3b 0a 0a 20  t( pSorter );.. 
6f10: 20 2f 2a 20 49 66 20 6e 6f 20 64 61 74 61 20 68   /* If no data h
6f20: 61 73 20 62 65 65 6e 20 77 72 69 74 74 65 6e 20  as been written 
6f30: 74 6f 20 64 69 73 6b 2c 20 74 68 65 6e 20 64 6f  to disk, then do
6f40: 20 6e 6f 74 20 64 6f 20 73 6f 20 6e 6f 77 2e 20   not do so now. 
6f50: 49 6e 73 74 65 61 64 2c 0a 20 20 2a 2a 20 73 6f  Instead,.  ** so
6f60: 72 74 20 74 68 65 20 56 64 62 65 53 6f 72 74 65  rt the VdbeSorte
6f70: 72 2e 70 52 65 63 6f 72 64 20 6c 69 73 74 2e 20  r.pRecord list. 
6f80: 54 68 65 20 76 64 62 65 20 6c 61 79 65 72 20 77  The vdbe layer w
6f90: 69 6c 6c 20 72 65 61 64 20 64 61 74 61 20 64 69  ill read data di
6fa0: 72 65 63 74 6c 79 0a 20 20 2a 2a 20 66 72 6f 6d  rectly.  ** from
6fb0: 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c   the in-memory l
6fc0: 69 73 74 2e 20 20 2a 2f 0a 20 20 69 66 28 20 70  ist.  */.  if( p
6fd0: 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 3d 3d 30 20  Sorter->nPMA==0 
6fe0: 29 7b 0a 20 20 20 20 2a 70 62 45 6f 66 20 3d 20  ){.    *pbEof = 
6ff0: 21 70 53 6f 72 74 65 72 2d 3e 70 52 65 63 6f 72  !pSorter->pRecor
7000: 64 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  d;.    assert( p
7010: 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 3d 3d 30  Sorter->aTree==0
7020: 20 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 76   );.    return v
7030: 64 62 65 53 6f 72 74 65 72 53 6f 72 74 28 70 43  dbeSorterSort(pC
7040: 73 72 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 57  sr);.  }..  /* W
7050: 72 69 74 65 20 74 68 65 20 63 75 72 72 65 6e 74  rite the current
7060: 20 69 6e 2d 6d 65 6d 6f 72 79 20 6c 69 73 74 20   in-memory list 
7070: 74 6f 20 61 20 50 4d 41 2e 20 2a 2f 0a 20 20 72  to a PMA. */.  r
7080: 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4c 69  c = vdbeSorterLi
7090: 73 74 54 6f 50 4d 41 28 64 62 2c 20 70 43 73 72  stToPMA(db, pCsr
70a0: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
70b0: 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
70c0: 72 63 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61  rc;..  /* Alloca
70d0: 74 65 20 73 70 61 63 65 20 66 6f 72 20 61 49 74  te space for aIt
70e0: 65 72 5b 5d 20 61 6e 64 20 61 54 72 65 65 5b 5d  er[] and aTree[]
70f0: 2e 20 2a 2f 0a 20 20 6e 49 74 65 72 20 3d 20 70  . */.  nIter = p
7100: 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 3b 0a 20 20  Sorter->nPMA;.  
7110: 69 66 28 20 6e 49 74 65 72 3e 53 4f 52 54 45 52  if( nIter>SORTER
7120: 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
7130: 20 29 20 6e 49 74 65 72 20 3d 20 53 4f 52 54 45   ) nIter = SORTE
7140: 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e  R_MAX_MERGE_COUN
7150: 54 3b 0a 20 20 61 73 73 65 72 74 28 20 6e 49 74  T;.  assert( nIt
7160: 65 72 3e 30 20 29 3b 0a 20 20 77 68 69 6c 65 28  er>0 );.  while(
7170: 20 4e 3c 6e 49 74 65 72 20 29 20 4e 20 2b 3d 20   N<nIter ) N += 
7180: 4e 3b 0a 20 20 6e 42 79 74 65 20 3d 20 4e 20 2a  N;.  nByte = N *
7190: 20 28 73 69 7a 65 6f 66 28 69 6e 74 29 20 2b 20   (sizeof(int) + 
71a0: 73 69 7a 65 6f 66 28 56 64 62 65 53 6f 72 74 65  sizeof(VdbeSorte
71b0: 72 49 74 65 72 29 29 3b 0a 20 20 70 53 6f 72 74  rIter));.  pSort
71c0: 65 72 2d 3e 61 49 74 65 72 20 3d 20 28 56 64 62  er->aIter = (Vdb
71d0: 65 53 6f 72 74 65 72 49 74 65 72 20 2a 29 73 71  eSorterIter *)sq
71e0: 6c 69 74 65 33 44 62 4d 61 6c 6c 6f 63 5a 65 72  lite3DbMallocZer
71f0: 6f 28 64 62 2c 20 6e 42 79 74 65 29 3b 0a 20 20  o(db, nByte);.  
7200: 69 66 28 20 21 70 53 6f 72 74 65 72 2d 3e 61 49  if( !pSorter->aI
7210: 74 65 72 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ter ) return SQL
7220: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 70 53 6f  ITE_NOMEM;.  pSo
7230: 72 74 65 72 2d 3e 61 54 72 65 65 20 3d 20 28 69  rter->aTree = (i
7240: 6e 74 20 2a 29 26 70 53 6f 72 74 65 72 2d 3e 61  nt *)&pSorter->a
7250: 49 74 65 72 5b 4e 5d 3b 0a 20 20 70 53 6f 72 74  Iter[N];.  pSort
7260: 65 72 2d 3e 6e 54 72 65 65 20 3d 20 4e 3b 0a 0a  er->nTree = N;..
7270: 20 20 64 6f 20 7b 0a 20 20 20 20 69 6e 74 20 69    do {.    int i
7280: 4e 65 77 3b 20 20 20 20 20 20 20 20 20 20 20 20  New;            
7290: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65           /* Inde
72a0: 78 20 6f 66 20 6e 65 77 2c 20 6d 65 72 67 65 64  x of new, merged
72b0: 2c 20 50 4d 41 20 2a 2f 0a 0a 20 20 20 20 66 6f  , PMA */..    fo
72c0: 72 28 69 4e 65 77 3d 30 3b 20 0a 20 20 20 20 20  r(iNew=0; .     
72d0: 20 20 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b     rc==SQLITE_OK
72e0: 20 26 26 20 69 4e 65 77 2a 53 4f 52 54 45 52 5f   && iNew*SORTER_
72f0: 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 3c  MAX_MERGE_COUNT<
7300: 70 53 6f 72 74 65 72 2d 3e 6e 50 4d 41 3b 20 0a  pSorter->nPMA; .
7310: 20 20 20 20 20 20 20 20 69 4e 65 77 2b 2b 0a 20          iNew++. 
7320: 20 20 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20     ){.      int 
7330: 72 63 32 3b 20 20 20 20 20 20 20 20 20 20 20 20  rc2;            
7340: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
7350: 6e 20 63 6f 64 65 20 66 72 6f 6d 20 66 69 6c 65  n code from file
7360: 57 72 69 74 65 72 46 69 6e 69 73 68 28 29 20 2a  WriterFinish() *
7370: 2f 0a 20 20 20 20 20 20 46 69 6c 65 57 72 69 74  /.      FileWrit
7380: 65 72 20 77 72 69 74 65 72 3b 20 20 20 20 20 20  er writer;      
7390: 20 20 20 20 2f 2a 20 4f 62 6a 65 63 74 20 75 73      /* Object us
73a0: 65 64 20 74 6f 20 77 72 69 74 65 20 74 6f 20 64  ed to write to d
73b0: 69 73 6b 20 2a 2f 0a 20 20 20 20 20 20 69 36 34  isk */.      i64
73c0: 20 6e 57 72 69 74 65 3b 20 20 20 20 20 20 20 20   nWrite;        
73d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
73e0: 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 6e  er of bytes in n
73f0: 65 77 20 50 4d 41 20 2a 2f 0a 0a 20 20 20 20 20  ew PMA */..     
7400: 20 6d 65 6d 73 65 74 28 26 77 72 69 74 65 72 2c   memset(&writer,
7410: 20 30 2c 20 73 69 7a 65 6f 66 28 46 69 6c 65 57   0, sizeof(FileW
7420: 72 69 74 65 72 29 29 3b 0a 0a 20 20 20 20 20 20  riter));..      
7430: 2f 2a 20 49 66 20 74 68 65 72 65 20 61 72 65 20  /* If there are 
7440: 53 4f 52 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45  SORTER_MAX_MERGE
7450: 5f 43 4f 55 4e 54 20 6f 72 20 6c 65 73 73 20 50  _COUNT or less P
7460: 4d 41 73 20 69 6e 20 66 69 6c 65 20 70 54 65 6d  MAs in file pTem
7470: 70 31 2c 0a 20 20 20 20 20 20 2a 2a 20 69 6e 69  p1,.      ** ini
7480: 74 69 61 6c 69 7a 65 20 61 6e 20 69 74 65 72 61  tialize an itera
7490: 74 6f 72 20 66 6f 72 20 65 61 63 68 20 6f 66 20  tor for each of 
74a0: 74 68 65 6d 20 61 6e 64 20 62 72 65 61 6b 20 6f  them and break o
74b0: 75 74 20 6f 66 20 74 68 65 20 6c 6f 6f 70 2e 0a  ut of the loop..
74c0: 20 20 20 20 20 20 2a 2a 20 54 68 65 73 65 20 69        ** These i
74d0: 74 65 72 61 74 6f 72 73 20 77 69 6c 6c 20 62 65  terators will be
74e0: 20 69 6e 63 72 65 6d 65 6e 74 61 6c 6c 79 20 6d   incrementally m
74f0: 65 72 67 65 64 20 61 73 20 74 68 65 20 56 44 42  erged as the VDB
7500: 45 20 6c 61 79 65 72 20 63 61 6c 6c 73 0a 20 20  E layer calls.  
7510: 20 20 20 20 2a 2a 20 73 71 6c 69 74 65 33 56 64      ** sqlite3Vd
7520: 62 65 53 6f 72 74 65 72 4e 65 78 74 28 29 2e 0a  beSorterNext()..
7530: 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a        **.      *
7540: 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20  * Otherwise, if 
7550: 70 54 65 6d 70 31 20 63 6f 6e 74 61 69 6e 73 20  pTemp1 contains 
7560: 6d 6f 72 65 20 74 68 61 6e 20 53 4f 52 54 45 52  more than SORTER
7570: 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
7580: 20 50 4d 41 73 2c 0a 20 20 20 20 20 20 2a 2a 20   PMAs,.      ** 
7590: 69 6e 69 74 69 61 6c 69 7a 65 20 69 6e 74 65 72  initialize inter
75a0: 61 74 6f 72 73 20 66 6f 72 20 53 4f 52 54 45 52  ators for SORTER
75b0: 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54  _MAX_MERGE_COUNT
75c0: 20 6f 66 20 74 68 65 6d 2e 20 54 68 65 73 65 20   of them. These 
75d0: 50 4d 41 73 0a 20 20 20 20 20 20 2a 2a 20 61 72  PMAs.      ** ar
75e0: 65 20 6d 65 72 67 65 64 20 69 6e 74 6f 20 61 20  e merged into a 
75f0: 73 69 6e 67 6c 65 20 50 4d 41 20 74 68 61 74 20  single PMA that 
7600: 69 73 20 77 72 69 74 74 65 6e 20 74 6f 20 66 69  is written to fi
7610: 6c 65 20 70 54 65 6d 70 32 2e 0a 20 20 20 20 20  le pTemp2..     
7620: 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 76   */.      rc = v
7630: 64 62 65 53 6f 72 74 65 72 49 6e 69 74 4d 65 72  dbeSorterInitMer
7640: 67 65 28 64 62 2c 20 70 43 73 72 2c 20 26 6e 57  ge(db, pCsr, &nW
7650: 72 69 74 65 29 3b 0a 20 20 20 20 20 20 61 73 73  rite);.      ass
7660: 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f  ert( rc!=SQLITE_
7670: 4f 4b 20 7c 7c 20 70 53 6f 72 74 65 72 2d 3e 61  OK || pSorter->a
7680: 49 74 65 72 5b 20 70 53 6f 72 74 65 72 2d 3e 61  Iter[ pSorter->a
7690: 54 72 65 65 5b 31 5d 20 5d 2e 70 46 69 6c 65 20  Tree[1] ].pFile 
76a0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  );.      if( rc!
76b0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53  =SQLITE_OK || pS
76c0: 6f 72 74 65 72 2d 3e 6e 50 4d 41 3c 3d 53 4f 52  orter->nPMA<=SOR
76d0: 54 45 52 5f 4d 41 58 5f 4d 45 52 47 45 5f 43 4f  TER_MAX_MERGE_CO
76e0: 55 4e 54 20 29 7b 0a 20 20 20 20 20 20 20 20 62  UNT ){.        b
76f0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20  reak;.      }.. 
7700: 20 20 20 20 20 2f 2a 20 4f 70 65 6e 20 74 68 65       /* Open the
7710: 20 73 65 63 6f 6e 64 20 74 65 6d 70 20 66 69 6c   second temp fil
7720: 65 2c 20 69 66 20 69 74 20 69 73 20 6e 6f 74 20  e, if it is not 
7730: 61 6c 72 65 61 64 79 20 6f 70 65 6e 2e 20 2a 2f  already open. */
7740: 0a 20 20 20 20 20 20 69 66 28 20 70 54 65 6d 70  .      if( pTemp
7750: 32 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  2==0 ){.        
7760: 61 73 73 65 72 74 28 20 69 57 72 69 74 65 32 3d  assert( iWrite2=
7770: 3d 30 20 29 3b 0a 20 20 20 20 20 20 20 20 72 63  =0 );.        rc
7780: 20 3d 20 76 64 62 65 53 6f 72 74 65 72 4f 70 65   = vdbeSorterOpe
7790: 6e 54 65 6d 70 46 69 6c 65 28 64 62 2c 20 26 70  nTempFile(db, &p
77a0: 54 65 6d 70 32 29 3b 0a 20 20 20 20 20 20 7d 0a  Temp2);.      }.
77b0: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
77c0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
77d0: 20 20 20 20 69 6e 74 20 62 45 6f 66 20 3d 20 30      int bEof = 0
77e0: 3b 0a 20 20 20 20 20 20 20 20 66 69 6c 65 57 72  ;.        fileWr
77f0: 69 74 65 72 49 6e 69 74 28 64 62 2c 20 70 54 65  iterInit(db, pTe
7800: 6d 70 32 2c 20 26 77 72 69 74 65 72 2c 20 69 57  mp2, &writer, iW
7810: 72 69 74 65 32 29 3b 0a 20 20 20 20 20 20 20 20  rite2);.        
7820: 66 69 6c 65 57 72 69 74 65 72 57 72 69 74 65 56  fileWriterWriteV
7830: 61 72 69 6e 74 28 26 77 72 69 74 65 72 2c 20 6e  arint(&writer, n
7840: 57 72 69 74 65 29 3b 0a 20 20 20 20 20 20 20 20  Write);.        
7850: 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54  while( rc==SQLIT
7860: 45 5f 4f 4b 20 26 26 20 62 45 6f 66 3d 3d 30 20  E_OK && bEof==0 
7870: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 56 64 62  ){.          Vdb
7880: 65 53 6f 72 74 65 72 49 74 65 72 20 2a 70 49 74  eSorterIter *pIt
7890: 65 72 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61  er = &pSorter->a
78a0: 49 74 65 72 5b 20 70 53 6f 72 74 65 72 2d 3e 61  Iter[ pSorter->a
78b0: 54 72 65 65 5b 31 5d 20 5d 3b 0a 20 20 20 20 20  Tree[1] ];.     
78c0: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 49 74       assert( pIt
78d0: 65 72 2d 3e 70 46 69 6c 65 20 29 3b 0a 0a 20 20  er->pFile );..  
78e0: 20 20 20 20 20 20 20 20 66 69 6c 65 57 72 69 74          fileWrit
78f0: 65 72 57 72 69 74 65 56 61 72 69 6e 74 28 26 77  erWriteVarint(&w
7900: 72 69 74 65 72 2c 20 70 49 74 65 72 2d 3e 6e 4b  riter, pIter->nK
7910: 65 79 29 3b 0a 20 20 20 20 20 20 20 20 20 20 66  ey);.          f
7920: 69 6c 65 57 72 69 74 65 72 57 72 69 74 65 28 26  ileWriterWrite(&
7930: 77 72 69 74 65 72 2c 20 70 49 74 65 72 2d 3e 61  writer, pIter->a
7940: 4b 65 79 2c 20 70 49 74 65 72 2d 3e 6e 4b 65 79  Key, pIter->nKey
7950: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  );.          rc 
7960: 3d 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72  = sqlite3VdbeSor
7970: 74 65 72 4e 65 78 74 28 64 62 2c 20 70 43 73 72  terNext(db, pCsr
7980: 2c 20 26 62 45 6f 66 29 3b 0a 20 20 20 20 20 20  , &bEof);.      
7990: 20 20 7d 0a 20 20 20 20 20 20 20 20 72 63 32 20    }.        rc2 
79a0: 3d 20 66 69 6c 65 57 72 69 74 65 72 46 69 6e 69  = fileWriterFini
79b0: 73 68 28 64 62 2c 20 26 77 72 69 74 65 72 2c 20  sh(db, &writer, 
79c0: 26 69 57 72 69 74 65 32 29 3b 0a 20 20 20 20 20  &iWrite2);.     
79d0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
79e0: 45 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63 32 3b  E_OK ) rc = rc2;
79f0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
7a00: 20 20 20 20 69 66 28 20 70 53 6f 72 74 65 72 2d      if( pSorter-
7a10: 3e 6e 50 4d 41 3c 3d 53 4f 52 54 45 52 5f 4d 41  >nPMA<=SORTER_MA
7a20: 58 5f 4d 45 52 47 45 5f 43 4f 55 4e 54 20 29 7b  X_MERGE_COUNT ){
7a30: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
7a40: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 73    }else{.      s
7a50: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 54 6d  qlite3_file *pTm
7a60: 70 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 54 65  p = pSorter->pTe
7a70: 6d 70 31 3b 0a 20 20 20 20 20 20 70 53 6f 72 74  mp1;.      pSort
7a80: 65 72 2d 3e 6e 50 4d 41 20 3d 20 69 4e 65 77 3b  er->nPMA = iNew;
7a90: 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d 3e  .      pSorter->
7aa0: 70 54 65 6d 70 31 20 3d 20 70 54 65 6d 70 32 3b  pTemp1 = pTemp2;
7ab0: 0a 20 20 20 20 20 20 70 54 65 6d 70 32 20 3d 20  .      pTemp2 = 
7ac0: 70 54 6d 70 3b 0a 20 20 20 20 20 20 70 53 6f 72  pTmp;.      pSor
7ad0: 74 65 72 2d 3e 69 57 72 69 74 65 4f 66 66 20 3d  ter->iWriteOff =
7ae0: 20 69 57 72 69 74 65 32 3b 0a 20 20 20 20 20 20   iWrite2;.      
7af0: 70 53 6f 72 74 65 72 2d 3e 69 52 65 61 64 4f 66  pSorter->iReadOf
7b00: 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 57 72  f = 0;.      iWr
7b10: 69 74 65 32 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  ite2 = 0;.    }.
7b20: 20 20 7d 77 68 69 6c 65 28 20 72 63 3d 3d 53 51    }while( rc==SQ
7b30: 4c 49 54 45 5f 4f 4b 20 29 3b 0a 0a 20 20 69 66  LITE_OK );..  if
7b40: 28 20 70 54 65 6d 70 32 20 29 7b 0a 20 20 20 20  ( pTemp2 ){.    
7b50: 73 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 46 72  sqlite3OsCloseFr
7b60: 65 65 28 70 54 65 6d 70 32 29 3b 0a 20 20 7d 0a  ee(pTemp2);.  }.
7b70: 20 20 2a 70 62 45 6f 66 20 3d 20 28 70 53 6f 72    *pbEof = (pSor
7b80: 74 65 72 2d 3e 61 49 74 65 72 5b 70 53 6f 72 74  ter->aIter[pSort
7b90: 65 72 2d 3e 61 54 72 65 65 5b 31 5d 5d 2e 70 46  er->aTree[1]].pF
7ba0: 69 6c 65 3d 3d 30 29 3b 0a 20 20 72 65 74 75 72  ile==0);.  retur
7bb0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  n rc;.}../*.** A
7bc0: 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20 6e 65  dvance to the ne
7bd0: 78 74 20 65 6c 65 6d 65 6e 74 20 69 6e 20 74 68  xt element in th
7be0: 65 20 73 6f 72 74 65 72 2e 0a 2a 2f 0a 69 6e 74  e sorter..*/.int
7bf0: 20 73 71 6c 69 74 65 33 56 64 62 65 53 6f 72 74   sqlite3VdbeSort
7c00: 65 72 4e 65 78 74 28 73 71 6c 69 74 65 33 20 2a  erNext(sqlite3 *
7c10: 64 62 2c 20 63 6f 6e 73 74 20 56 64 62 65 43 75  db, const VdbeCu
7c20: 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74 20  rsor *pCsr, int 
7c30: 2a 70 62 45 6f 66 29 7b 0a 20 20 56 64 62 65 53  *pbEof){.  VdbeS
7c40: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d  orter *pSorter =
7c50: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a   pCsr->pSorter;.
7c60: 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
7c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7c80: 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
7c90: 20 2a 2f 0a 0a 20 20 69 66 28 20 70 53 6f 72 74   */..  if( pSort
7ca0: 65 72 2d 3e 61 54 72 65 65 20 29 7b 0a 20 20 20  er->aTree ){.   
7cb0: 20 69 6e 74 20 69 50 72 65 76 20 3d 20 70 53 6f   int iPrev = pSo
7cc0: 72 74 65 72 2d 3e 61 54 72 65 65 5b 31 5d 3b 2f  rter->aTree[1];/
7cd0: 2a 20 49 6e 64 65 78 20 6f 66 20 69 74 65 72 61  * Index of itera
7ce0: 74 6f 72 20 74 6f 20 61 64 76 61 6e 63 65 20 2a  tor to advance *
7cf0: 2f 0a 20 20 20 20 69 6e 74 20 69 3b 20 20 20 20  /.    int i;    
7d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7d10: 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20      /* Index of 
7d20: 61 54 72 65 65 5b 5d 20 74 6f 20 72 65 63 61 6c  aTree[] to recal
7d30: 63 75 6c 61 74 65 20 2a 2f 0a 0a 20 20 20 20 72  culate */..    r
7d40: 63 20 3d 20 76 64 62 65 53 6f 72 74 65 72 49 74  c = vdbeSorterIt
7d50: 65 72 4e 65 78 74 28 64 62 2c 20 26 70 53 6f 72  erNext(db, &pSor
7d60: 74 65 72 2d 3e 61 49 74 65 72 5b 69 50 72 65 76  ter->aIter[iPrev
7d70: 5d 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 28 70  ]);.    for(i=(p
7d80: 53 6f 72 74 65 72 2d 3e 6e 54 72 65 65 2b 69 50  Sorter->nTree+iP
7d90: 72 65 76 29 2f 32 3b 20 72 63 3d 3d 53 51 4c 49  rev)/2; rc==SQLI
7da0: 54 45 5f 4f 4b 20 26 26 20 69 3e 30 3b 20 69 3d  TE_OK && i>0; i=
7db0: 69 2f 32 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  i/2){.      rc =
7dc0: 20 76 64 62 65 53 6f 72 74 65 72 44 6f 43 6f 6d   vdbeSorterDoCom
7dd0: 70 61 72 65 28 70 43 73 72 2c 20 69 29 3b 0a 20  pare(pCsr, i);. 
7de0: 20 20 20 7d 0a 0a 20 20 20 20 2a 70 62 45 6f 66     }..    *pbEof
7df0: 20 3d 20 28 70 53 6f 72 74 65 72 2d 3e 61 49 74   = (pSorter->aIt
7e00: 65 72 5b 70 53 6f 72 74 65 72 2d 3e 61 54 72 65  er[pSorter->aTre
7e10: 65 5b 31 5d 5d 2e 70 46 69 6c 65 3d 3d 30 29 3b  e[1]].pFile==0);
7e20: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 53 6f  .  }else{.    So
7e30: 72 74 65 72 52 65 63 6f 72 64 20 2a 70 46 72 65  rterRecord *pFre
7e40: 65 20 3d 20 70 53 6f 72 74 65 72 2d 3e 70 52 65  e = pSorter->pRe
7e50: 63 6f 72 64 3b 0a 20 20 20 20 70 53 6f 72 74 65  cord;.    pSorte
7e60: 72 2d 3e 70 52 65 63 6f 72 64 20 3d 20 70 46 72  r->pRecord = pFr
7e70: 65 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 70  ee->pNext;.    p
7e80: 46 72 65 65 2d 3e 70 4e 65 78 74 20 3d 20 30 3b  Free->pNext = 0;
7e90: 0a 20 20 20 20 76 64 62 65 53 6f 72 74 65 72 52  .    vdbeSorterR
7ea0: 65 63 6f 72 64 46 72 65 65 28 64 62 2c 20 70 46  ecordFree(db, pF
7eb0: 72 65 65 29 3b 0a 20 20 20 20 2a 70 62 45 6f 66  ree);.    *pbEof
7ec0: 20 3d 20 21 70 53 6f 72 74 65 72 2d 3e 70 52 65   = !pSorter->pRe
7ed0: 63 6f 72 64 3b 0a 20 20 20 20 72 63 20 3d 20 53  cord;.    rc = S
7ee0: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 20 20  QLITE_OK;.  }.  
7ef0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
7f00: 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69  .** Return a poi
7f10: 6e 74 65 72 20 74 6f 20 61 20 62 75 66 66 65 72  nter to a buffer
7f20: 20 6f 77 6e 65 64 20 62 79 20 74 68 65 20 73 6f   owned by the so
7f30: 72 74 65 72 20 74 68 61 74 20 63 6f 6e 74 61 69  rter that contai
7f40: 6e 73 20 74 68 65 20 0a 2a 2a 20 63 75 72 72 65  ns the .** curre
7f50: 6e 74 20 6b 65 79 2e 0a 2a 2f 0a 73 74 61 74 69  nt key..*/.stati
7f60: 63 20 76 6f 69 64 20 2a 76 64 62 65 53 6f 72 74  c void *vdbeSort
7f70: 65 72 52 6f 77 6b 65 79 28 0a 20 20 63 6f 6e 73  erRowkey(.  cons
7f80: 74 20 56 64 62 65 53 6f 72 74 65 72 20 2a 70 53  t VdbeSorter *pS
7f90: 6f 72 74 65 72 2c 20 20 20 20 20 20 2f 2a 20 53  orter,      /* S
7fa0: 6f 72 74 65 72 20 6f 62 6a 65 63 74 20 2a 2f 0a  orter object */.
7fb0: 20 20 69 6e 74 20 2a 70 6e 4b 65 79 20 20 20 20    int *pnKey    
7fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7fd0: 20 20 2f 2a 20 4f 55 54 3a 20 53 69 7a 65 20 6f    /* OUT: Size o
7fe0: 66 20 63 75 72 72 65 6e 74 20 6b 65 79 20 69 6e  f current key in
7ff0: 20 62 79 74 65 73 20 2a 2f 0a 29 7b 0a 20 20 76   bytes */.){.  v
8000: 6f 69 64 20 2a 70 4b 65 79 3b 0a 20 20 69 66 28  oid *pKey;.  if(
8010: 20 70 53 6f 72 74 65 72 2d 3e 61 54 72 65 65 20   pSorter->aTree 
8020: 29 7b 0a 20 20 20 20 56 64 62 65 53 6f 72 74 65  ){.    VdbeSorte
8030: 72 49 74 65 72 20 2a 70 49 74 65 72 3b 0a 20 20  rIter *pIter;.  
8040: 20 20 70 49 74 65 72 20 3d 20 26 70 53 6f 72 74    pIter = &pSort
8050: 65 72 2d 3e 61 49 74 65 72 5b 20 70 53 6f 72 74  er->aIter[ pSort
8060: 65 72 2d 3e 61 54 72 65 65 5b 31 5d 20 5d 3b 0a  er->aTree[1] ];.
8070: 20 20 20 20 2a 70 6e 4b 65 79 20 3d 20 70 49 74      *pnKey = pIt
8080: 65 72 2d 3e 6e 4b 65 79 3b 0a 20 20 20 20 70 4b  er->nKey;.    pK
8090: 65 79 20 3d 20 70 49 74 65 72 2d 3e 61 4b 65 79  ey = pIter->aKey
80a0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2a  ;.  }else{.    *
80b0: 70 6e 4b 65 79 20 3d 20 70 53 6f 72 74 65 72 2d  pnKey = pSorter-
80c0: 3e 70 52 65 63 6f 72 64 2d 3e 6e 56 61 6c 3b 0a  >pRecord->nVal;.
80d0: 20 20 20 20 70 4b 65 79 20 3d 20 70 53 6f 72 74      pKey = pSort
80e0: 65 72 2d 3e 70 52 65 63 6f 72 64 2d 3e 70 56 61  er->pRecord->pVa
80f0: 6c 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  l;.  }.  return 
8100: 70 4b 65 79 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  pKey;.}../*.** C
8110: 6f 70 79 20 74 68 65 20 63 75 72 72 65 6e 74 20  opy the current 
8120: 73 6f 72 74 65 72 20 6b 65 79 20 69 6e 74 6f 20  sorter key into 
8130: 74 68 65 20 6d 65 6d 6f 72 79 20 63 65 6c 6c 20  the memory cell 
8140: 70 4f 75 74 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  pOut..*/.int sql
8150: 69 74 65 33 56 64 62 65 53 6f 72 74 65 72 52 6f  ite3VdbeSorterRo
8160: 77 6b 65 79 28 63 6f 6e 73 74 20 56 64 62 65 43  wkey(const VdbeC
8170: 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 4d 65 6d  ursor *pCsr, Mem
8180: 20 2a 70 4f 75 74 29 7b 0a 20 20 56 64 62 65 53   *pOut){.  VdbeS
8190: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d  orter *pSorter =
81a0: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a   pCsr->pSorter;.
81b0: 20 20 76 6f 69 64 20 2a 70 4b 65 79 3b 20 69 6e    void *pKey; in
81c0: 74 20 6e 4b 65 79 3b 20 20 20 20 20 20 20 20 20  t nKey;         
81d0: 20 20 2f 2a 20 53 6f 72 74 65 72 20 6b 65 79 20    /* Sorter key 
81e0: 74 6f 20 63 6f 70 79 20 69 6e 74 6f 20 70 4f 75  to copy into pOu
81f0: 74 20 2a 2f 0a 0a 20 20 70 4b 65 79 20 3d 20 76  t */..  pKey = v
8200: 64 62 65 53 6f 72 74 65 72 52 6f 77 6b 65 79 28  dbeSorterRowkey(
8210: 70 53 6f 72 74 65 72 2c 20 26 6e 4b 65 79 29 3b  pSorter, &nKey);
8220: 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33 56 64  .  if( sqlite3Vd
8230: 62 65 4d 65 6d 47 72 6f 77 28 70 4f 75 74 2c 20  beMemGrow(pOut, 
8240: 6e 4b 65 79 2c 20 30 29 20 29 7b 0a 20 20 20 20  nKey, 0) ){.    
8250: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
8260: 4d 45 4d 3b 0a 20 20 7d 0a 20 20 70 4f 75 74 2d  MEM;.  }.  pOut-
8270: 3e 6e 20 3d 20 6e 4b 65 79 3b 0a 20 20 4d 65 6d  >n = nKey;.  Mem
8280: 53 65 74 54 79 70 65 46 6c 61 67 28 70 4f 75 74  SetTypeFlag(pOut
8290: 2c 20 4d 45 4d 5f 42 6c 6f 62 29 3b 0a 20 20 6d  , MEM_Blob);.  m
82a0: 65 6d 63 70 79 28 70 4f 75 74 2d 3e 7a 2c 20 70  emcpy(pOut->z, p
82b0: 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 0a 20 20 72  Key, nKey);..  r
82c0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
82d0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 61 72  .}../*.** Compar
82e0: 65 20 74 68 65 20 6b 65 79 20 69 6e 20 6d 65 6d  e the key in mem
82f0: 6f 72 79 20 63 65 6c 6c 20 70 56 61 6c 20 77 69  ory cell pVal wi
8300: 74 68 20 74 68 65 20 6b 65 79 20 74 68 61 74 20  th the key that 
8310: 74 68 65 20 73 6f 72 74 65 72 20 63 75 72 73 6f  the sorter curso
8320: 72 0a 2a 2a 20 70 61 73 73 65 64 20 61 73 20 74  r.** passed as t
8330: 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e  he first argumen
8340: 74 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e  t currently poin
8350: 74 73 20 74 6f 2e 20 46 6f 72 20 74 68 65 20 70  ts to. For the p
8360: 75 72 70 6f 73 65 73 20 6f 66 0a 2a 2a 20 74 68  urposes of.** th
8370: 65 20 63 6f 6d 70 61 72 69 73 6f 6e 2c 20 69 67  e comparison, ig
8380: 6e 6f 72 65 20 74 68 65 20 72 6f 77 69 64 20 66  nore the rowid f
8390: 69 65 6c 64 20 61 74 20 74 68 65 20 65 6e 64 20  ield at the end 
83a0: 6f 66 20 65 61 63 68 20 72 65 63 6f 72 64 2e 0a  of each record..
83b0: 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 65 72 72 6f  **.** If an erro
83c0: 72 20 6f 63 63 75 72 73 2c 20 72 65 74 75 72 6e  r occurs, return
83d0: 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
83e0: 20 63 6f 64 65 20 28 69 2e 65 2e 20 53 51 4c 49   code (i.e. SQLI
83f0: 54 45 5f 4e 4f 4d 45 4d 29 2e 0a 2a 2a 20 4f 74  TE_NOMEM)..** Ot
8400: 68 65 72 77 69 73 65 2c 20 73 65 74 20 2a 70 52  herwise, set *pR
8410: 65 73 20 74 6f 20 61 20 6e 65 67 61 74 69 76 65  es to a negative
8420: 2c 20 7a 65 72 6f 20 6f 72 20 70 6f 73 69 74 69  , zero or positi
8430: 76 65 20 76 61 6c 75 65 20 69 66 20 74 68 65 0a  ve value if the.
8440: 2a 2a 20 6b 65 79 20 69 6e 20 70 56 61 6c 20 69  ** key in pVal i
8450: 73 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 2c 20  s smaller than, 
8460: 65 71 75 61 6c 20 74 6f 20 6f 72 20 6c 61 72 67  equal to or larg
8470: 65 72 20 74 68 61 6e 20 74 68 65 20 63 75 72 72  er than the curr
8480: 65 6e 74 20 73 6f 72 74 65 72 0a 2a 2a 20 6b 65  ent sorter.** ke
8490: 79 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  y..*/.int sqlite
84a0: 33 56 64 62 65 53 6f 72 74 65 72 43 6f 6d 70 61  3VdbeSorterCompa
84b0: 72 65 28 0a 20 20 63 6f 6e 73 74 20 56 64 62 65  re(.  const Vdbe
84c0: 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 20 20  Cursor *pCsr,   
84d0: 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20        /* Sorter 
84e0: 63 75 72 73 6f 72 20 2a 2f 0a 20 20 4d 65 6d 20  cursor */.  Mem 
84f0: 2a 70 56 61 6c 2c 20 20 20 20 20 20 20 20 20 20  *pVal,          
8500: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56              /* V
8510: 61 6c 75 65 20 74 6f 20 63 6f 6d 70 61 72 65 20  alue to compare 
8520: 74 6f 20 63 75 72 72 65 6e 74 20 73 6f 72 74 65  to current sorte
8530: 72 20 6b 65 79 20 2a 2f 0a 20 20 69 6e 74 20 6e  r key */.  int n
8540: 49 67 6e 6f 72 65 2c 20 20 20 20 20 20 20 20 20  Ignore,         
8550: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 67             /* Ig
8560: 6e 6f 72 65 20 74 68 69 73 20 6d 61 6e 79 20 66  nore this many f
8570: 69 65 6c 64 73 20 61 74 20 74 68 65 20 65 6e 64  ields at the end
8580: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 52 65 73 20   */.  int *pRes 
8590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
85a0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 52 65        /* OUT: Re
85b0: 73 75 6c 74 20 6f 66 20 63 6f 6d 70 61 72 69 73  sult of comparis
85c0: 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 56 64 62 65 53  on */.){.  VdbeS
85d0: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d  orter *pSorter =
85e0: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a   pCsr->pSorter;.
85f0: 20 20 76 6f 69 64 20 2a 70 4b 65 79 3b 20 69 6e    void *pKey; in
8600: 74 20 6e 4b 65 79 3b 20 20 20 20 20 20 20 20 20  t nKey;         
8610: 20 20 2f 2a 20 53 6f 72 74 65 72 20 6b 65 79 20    /* Sorter key 
8620: 74 6f 20 63 6f 6d 70 61 72 65 20 70 56 61 6c 20  to compare pVal 
8630: 77 69 74 68 20 2a 2f 0a 0a 20 20 70 4b 65 79 20  with */..  pKey 
8640: 3d 20 76 64 62 65 53 6f 72 74 65 72 52 6f 77 6b  = vdbeSorterRowk
8650: 65 79 28 70 53 6f 72 74 65 72 2c 20 26 6e 4b 65  ey(pSorter, &nKe
8660: 79 29 3b 0a 20 20 76 64 62 65 53 6f 72 74 65 72  y);.  vdbeSorter
8670: 43 6f 6d 70 61 72 65 28 70 43 73 72 2c 20 6e 49  Compare(pCsr, nI
8680: 67 6e 6f 72 65 2c 20 70 56 61 6c 2d 3e 7a 2c 20  gnore, pVal->z, 
8690: 70 56 61 6c 2d 3e 6e 2c 20 70 4b 65 79 2c 20 6e  pVal->n, pKey, n
86a0: 4b 65 79 2c 20 70 52 65 73 29 3b 0a 20 20 72 65  Key, pRes);.  re
86b0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
86c0: 7d 0a                                            }.