/ Hex Artifact Content
Login

Artifact b8fb7befd85b3a9b4a10e701b30b2b79ca92b6d4:


0000: 2f 2a 0a 2a 2a 20 32 30 31 35 2d 30 38 2d 31 38  /*.** 2015-08-18
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
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 0a  ***************.
0170: 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65 20  **.** This file 
0180: 64 65 6d 6f 6e 73 74 72 61 74 65 73 20 68 6f 77  demonstrates how
0190: 20 74 6f 20 63 72 65 61 74 65 20 61 20 74 61 62   to create a tab
01a0: 6c 65 2d 76 61 6c 75 65 64 2d 66 75 6e 63 74 69  le-valued-functi
01b0: 6f 6e 20 75 73 69 6e 67 0a 2a 2a 20 61 20 76 69  on using.** a vi
01c0: 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 20 54 68  rtual table.  Th
01d0: 69 73 20 64 65 6d 6f 20 69 6d 70 6c 65 6d 65 6e  is demo implemen
01e0: 74 73 20 74 68 65 20 67 65 6e 65 72 61 74 65 5f  ts the generate_
01f0: 73 65 72 69 65 73 28 29 20 66 75 6e 63 74 69 6f  series() functio
0200: 6e 0a 2a 2a 20 77 68 69 63 68 20 67 69 76 65 73  n.** which gives
0210: 20 73 69 6d 69 6c 61 72 20 72 65 73 75 6c 74 73   similar results
0220: 20 74 6f 20 74 68 65 20 65 70 6f 6e 79 6d 6f 75   to the eponymou
0230: 73 20 66 75 6e 63 74 69 6f 6e 20 69 6e 20 50 6f  s function in Po
0240: 73 74 67 72 65 53 51 4c 2e 0a 2a 2a 20 45 78 61  stgreSQL..** Exa
0250: 6d 70 6c 65 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20  mples:.**.**    
0260: 20 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20    SELECT * FROM 
0270: 67 65 6e 65 72 61 74 65 5f 73 65 72 69 65 73 28  generate_series(
0280: 30 2c 31 30 30 2c 35 29 3b 0a 2a 2a 0a 2a 2a 20  0,100,5);.**.** 
0290: 54 68 65 20 71 75 65 72 79 20 61 62 6f 76 65 20  The query above 
02a0: 72 65 74 75 72 6e 73 20 69 6e 74 65 67 65 72 73  returns integers
02b0: 20 66 72 6f 6d 20 30 20 74 68 72 6f 75 67 68 20   from 0 through 
02c0: 31 30 30 20 63 6f 75 6e 74 69 6e 67 20 62 79 20  100 counting by 
02d0: 73 74 65 70 73 0a 2a 2a 20 6f 66 20 35 2e 0a 2a  steps.** of 5..*
02e0: 2a 0a 2a 2a 20 20 20 20 20 20 53 45 4c 45 43 54  *.**      SELECT
02f0: 20 2a 20 46 52 4f 4d 20 67 65 6e 65 72 61 74 65   * FROM generate
0300: 5f 73 65 72 69 65 73 28 30 2c 31 30 30 29 3b 0a  _series(0,100);.
0310: 2a 2a 0a 2a 2a 20 49 6e 74 65 67 65 72 73 20 66  **.** Integers f
0320: 72 6f 6d 20 30 20 74 68 72 6f 75 67 68 20 31 30  rom 0 through 10
0330: 30 20 77 69 74 68 20 61 20 73 74 65 70 20 73 69  0 with a step si
0340: 7a 65 20 6f 66 20 31 2e 0a 2a 2a 0a 2a 2a 20 20  ze of 1..**.**  
0350: 20 20 20 20 53 45 4c 45 43 54 20 2a 20 46 52 4f      SELECT * FRO
0360: 4d 20 67 65 6e 65 72 61 74 65 5f 73 65 72 69 65  M generate_serie
0370: 73 28 32 30 29 20 4c 49 4d 49 54 20 31 30 3b 0a  s(20) LIMIT 10;.
0380: 2a 2a 0a 2a 2a 20 49 6e 74 65 67 65 72 73 20 32  **.** Integers 2
0390: 30 20 74 68 72 6f 75 67 68 20 32 39 2e 0a 2a 2a  0 through 29..**
03a0: 0a 2a 2a 20 48 4f 57 20 49 54 20 57 4f 52 4b 53  .** HOW IT WORKS
03b0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 67 65 6e 65 72  .**.** The gener
03c0: 61 74 65 5f 73 65 72 69 65 73 20 22 66 75 6e 63  ate_series "func
03d0: 74 69 6f 6e 22 20 69 73 20 72 65 61 6c 6c 79 20  tion" is really 
03e0: 61 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  a virtual table 
03f0: 77 69 74 68 20 74 68 65 0a 2a 2a 20 66 6f 6c 6c  with the.** foll
0400: 6f 77 69 6e 67 20 73 63 68 65 6d 61 3a 0a 2a 2a  owing schema:.**
0410: 0a 2a 2a 20 20 20 20 20 43 52 45 41 54 45 20 46  .**     CREATE F
0420: 55 4e 43 54 49 4f 4e 20 67 65 6e 65 72 61 74 65  UNCTION generate
0430: 5f 73 65 72 69 65 73 28 0a 2a 2a 20 20 20 20 20  _series(.**     
0440: 20 20 76 61 6c 75 65 2c 0a 2a 2a 20 20 20 20 20    value,.**     
0450: 20 20 73 74 61 72 74 20 48 49 44 44 45 4e 2c 0a    start HIDDEN,.
0460: 2a 2a 20 20 20 20 20 20 20 73 74 6f 70 20 48 49  **       stop HI
0470: 44 44 45 4e 2c 0a 2a 2a 20 20 20 20 20 20 20 73  DDEN,.**       s
0480: 74 65 70 20 48 49 44 44 45 4e 0a 2a 2a 20 20 20  tep HIDDEN.**   
0490: 20 20 29 3b 0a 2a 2a 0a 2a 2a 20 46 75 6e 63 74    );.**.** Funct
04a0: 69 6f 6e 20 61 72 67 75 6d 65 6e 74 73 20 69 6e  ion arguments in
04b0: 20 71 75 65 72 69 65 73 20 61 67 61 69 6e 73 74   queries against
04c0: 20 74 68 69 73 20 76 69 72 74 75 61 6c 20 74 61   this virtual ta
04d0: 62 6c 65 20 61 72 65 20 74 72 61 6e 73 6c 61 74  ble are translat
04e0: 65 64 0a 2a 2a 20 69 6e 74 6f 20 65 71 75 61 6c  ed.** into equal
04f0: 69 74 79 20 63 6f 6e 73 74 72 61 69 6e 74 73 20  ity constraints 
0500: 61 67 61 69 6e 73 74 20 73 75 63 63 65 73 73 69  against successi
0510: 76 65 20 68 69 64 64 65 6e 20 63 6f 6c 75 6d 6e  ve hidden column
0520: 73 2e 20 20 49 6e 20 6f 74 68 65 72 0a 2a 2a 20  s.  In other.** 
0530: 77 6f 72 64 73 2c 20 74 68 65 20 66 6f 6c 6c 6f  words, the follo
0540: 77 69 6e 67 20 70 61 69 72 73 20 6f 66 20 71 75  wing pairs of qu
0550: 65 72 69 65 73 20 61 72 65 20 65 71 75 69 76 61  eries are equiva
0560: 6c 65 6e 74 20 74 6f 20 65 61 63 68 20 6f 74 68  lent to each oth
0570: 65 72 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 53 45 4c  er:.**.**    SEL
0580: 45 43 54 20 2a 20 46 52 4f 4d 20 67 65 6e 65 72  ECT * FROM gener
0590: 61 74 65 5f 73 65 72 69 65 73 28 30 2c 31 30 30  ate_series(0,100
05a0: 2c 35 29 3b 0a 2a 2a 20 20 20 20 53 45 4c 45 43  ,5);.**    SELEC
05b0: 54 20 2a 20 46 52 4f 4d 20 67 65 6e 65 72 61 74  T * FROM generat
05c0: 65 5f 73 65 72 69 65 73 20 57 48 45 52 45 20 73  e_series WHERE s
05d0: 74 61 72 74 3d 30 20 41 4e 44 20 73 74 6f 70 3d  tart=0 AND stop=
05e0: 31 30 30 20 41 4e 44 20 73 74 65 70 3d 35 3b 0a  100 AND step=5;.
05f0: 2a 2a 0a 2a 2a 20 20 20 20 53 45 4c 45 43 54 20  **.**    SELECT 
0600: 2a 20 46 52 4f 4d 20 67 65 6e 65 72 61 74 65 5f  * FROM generate_
0610: 73 65 72 69 65 73 28 30 2c 31 30 30 29 3b 0a 2a  series(0,100);.*
0620: 2a 20 20 20 20 53 45 4c 45 43 54 20 2a 20 46 52  *    SELECT * FR
0630: 4f 4d 20 67 65 6e 65 72 61 74 65 5f 73 65 72 69  OM generate_seri
0640: 65 73 20 57 48 45 52 45 20 73 74 61 72 74 3d 30  es WHERE start=0
0650: 20 41 4e 44 20 73 74 6f 70 3d 31 30 30 3b 0a 2a   AND stop=100;.*
0660: 2a 0a 2a 2a 20 20 20 20 53 45 4c 45 43 54 20 2a  *.**    SELECT *
0670: 20 46 52 4f 4d 20 67 65 6e 65 72 61 74 65 5f 73   FROM generate_s
0680: 65 72 69 65 73 28 32 30 29 20 4c 49 4d 49 54 20  eries(20) LIMIT 
0690: 31 30 3b 0a 2a 2a 20 20 20 20 53 45 4c 45 43 54  10;.**    SELECT
06a0: 20 2a 20 46 52 4f 4d 20 67 65 6e 65 72 61 74 65   * FROM generate
06b0: 5f 73 65 72 69 65 73 20 57 48 45 52 45 20 73 74  _series WHERE st
06c0: 61 72 74 3d 32 30 20 4c 49 4d 49 54 20 31 30 3b  art=20 LIMIT 10;
06d0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 67 65 6e 65 72  .**.** The gener
06e0: 61 74 65 5f 73 65 72 69 65 73 20 76 69 72 74 75  ate_series virtu
06f0: 61 6c 20 74 61 62 6c 65 20 69 6d 70 6c 65 6d 65  al table impleme
0700: 6e 74 61 74 69 6f 6e 20 6c 65 61 76 65 73 20 74  ntation leaves t
0710: 68 65 20 78 43 72 65 61 74 65 20 6d 65 74 68 6f  he xCreate metho
0720: 64 0a 2a 2a 20 73 65 74 20 74 6f 20 4e 55 4c 4c  d.** set to NULL
0730: 2e 20 20 54 68 69 73 20 6d 65 61 6e 73 20 74 68  .  This means th
0740: 61 74 20 69 74 20 69 73 20 6e 6f 74 20 70 6f 73  at it is not pos
0750: 73 69 62 6c 65 20 74 6f 20 64 6f 20 61 20 43 52  sible to do a CR
0760: 45 41 54 45 20 56 49 52 54 55 41 4c 0a 2a 2a 20  EATE VIRTUAL.** 
0770: 54 41 42 4c 45 20 63 6f 6d 6d 61 6e 64 20 77 69  TABLE command wi
0780: 74 68 20 22 67 65 6e 65 72 61 74 65 5f 73 65 72  th "generate_ser
0790: 69 65 73 22 20 61 73 20 74 68 65 20 55 53 49 4e  ies" as the USIN
07a0: 47 20 61 72 67 75 6d 65 6e 74 2e 20 20 49 6e 73  G argument.  Ins
07b0: 74 65 61 64 2c 20 74 68 65 72 65 0a 2a 2a 20 69  tead, there.** i
07c0: 73 20 61 20 73 69 6e 67 6c 65 20 67 65 6e 65 72  s a single gener
07d0: 61 74 65 5f 73 65 72 69 65 73 20 76 69 72 74 75  ate_series virtu
07e0: 61 6c 20 74 61 62 6c 65 20 74 68 61 74 20 69 73  al table that is
07f0: 20 61 6c 77 61 79 73 20 61 76 61 69 6c 61 62 6c   always availabl
0800: 65 20 77 69 74 68 6f 75 74 0a 2a 2a 20 68 61 76  e without.** hav
0810: 69 6e 67 20 74 6f 20 62 65 20 63 72 65 61 74 65  ing to be create
0820: 64 20 66 69 72 73 74 2e 0a 2a 2a 0a 2a 2a 20 54  d first..**.** T
0830: 68 65 20 78 42 65 73 74 49 6e 64 65 78 20 6d 65  he xBestIndex me
0840: 74 68 6f 64 20 6c 6f 6f 6b 73 20 66 6f 72 20 65  thod looks for e
0850: 71 75 61 6c 69 74 79 20 63 6f 6e 73 74 72 61 69  quality constrai
0860: 6e 74 73 20 61 67 61 69 6e 73 74 20 74 68 65 20  nts against the 
0870: 68 69 64 64 65 6e 0a 2a 2a 20 73 74 61 72 74 2c  hidden.** start,
0880: 20 73 74 6f 70 2c 20 61 6e 64 20 73 74 65 70 20   stop, and step 
0890: 63 6f 6c 75 6d 6e 73 2c 20 61 6e 64 20 69 66 20  columns, and if 
08a0: 70 72 65 73 65 6e 74 2c 20 69 74 20 75 73 65 73  present, it uses
08b0: 20 74 68 6f 73 65 20 63 6f 6e 73 74 72 61 69 6e   those constrain
08c0: 74 73 0a 2a 2a 20 74 6f 20 62 6f 75 6e 64 20 74  ts.** to bound t
08d0: 68 65 20 73 65 71 75 65 6e 63 65 20 6f 66 20 67  he sequence of g
08e0: 65 6e 65 72 61 74 65 64 20 76 61 6c 75 65 73 2e  enerated values.
08f0: 20 20 49 66 20 74 68 65 20 65 71 75 61 6c 69 74    If the equalit
0900: 79 20 63 6f 6e 73 74 72 61 69 6e 74 73 0a 2a 2a  y constraints.**
0910: 20 61 72 65 20 6d 69 73 73 69 6e 67 2c 20 69 74   are missing, it
0920: 20 75 73 65 73 20 30 20 66 6f 72 20 73 74 61 72   uses 0 for star
0930: 74 2c 20 34 32 39 34 39 36 37 32 39 35 20 66 6f  t, 4294967295 fo
0940: 72 20 73 74 6f 70 2c 20 61 6e 64 20 31 20 66 6f  r stop, and 1 fo
0950: 72 20 73 74 65 70 2e 0a 2a 2a 20 78 42 65 73 74  r step..** xBest
0960: 49 6e 64 65 78 20 72 65 74 75 72 6e 73 20 61 20  Index returns a 
0970: 73 6d 61 6c 6c 20 63 6f 73 74 20 77 68 65 6e 20  small cost when 
0980: 62 6f 74 68 20 73 74 61 72 74 20 61 6e 64 20 73  both start and s
0990: 74 6f 70 20 61 72 65 20 61 76 61 69 6c 61 62 6c  top are availabl
09a0: 65 2c 0a 2a 2a 20 61 6e 64 20 61 20 76 65 72 79  e,.** and a very
09b0: 20 6c 61 72 67 65 20 63 6f 73 74 20 69 66 20 65   large cost if e
09c0: 69 74 68 65 72 20 73 74 61 72 74 20 6f 72 20 73  ither start or s
09d0: 74 6f 70 20 61 72 65 20 75 6e 61 76 61 69 6c 61  top are unavaila
09e0: 62 6c 65 2e 20 20 54 68 69 73 0a 2a 2a 20 65 6e  ble.  This.** en
09f0: 63 6f 75 72 61 67 65 73 20 74 68 65 20 71 75 65  courages the que
0a00: 72 79 20 70 6c 61 6e 6e 65 72 20 74 6f 20 6f 72  ry planner to or
0a10: 64 65 72 20 6a 6f 69 6e 73 20 73 75 63 68 20 74  der joins such t
0a20: 68 61 74 20 74 68 65 20 62 6f 75 6e 64 73 20 6f  hat the bounds o
0a30: 66 20 74 68 65 0a 2a 2a 20 73 65 72 69 65 73 20  f the.** series 
0a40: 61 72 65 20 77 65 6c 6c 2d 64 65 66 69 6e 65 64  are well-defined
0a50: 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22 73  ..*/.#include "s
0a60: 71 6c 69 74 65 33 65 78 74 2e 68 22 0a 53 51 4c  qlite3ext.h".SQL
0a70: 49 54 45 5f 45 58 54 45 4e 53 49 4f 4e 5f 49 4e  ITE_EXTENSION_IN
0a80: 49 54 31 0a 23 69 6e 63 6c 75 64 65 20 3c 61 73  IT1.#include <as
0a90: 73 65 72 74 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  sert.h>.#include
0aa0: 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 0a 23 69 66   <string.h>..#if
0ab0: 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
0ac0: 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 0a 0a 0a  _VIRTUALTABLE...
0ad0: 2f 2a 20 73 65 72 69 65 73 5f 63 75 72 73 6f 72  /* series_cursor
0ae0: 20 69 73 20 61 20 73 75 62 63 6c 61 73 73 20 6f   is a subclass o
0af0: 66 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  f sqlite3_vtab_c
0b00: 75 72 73 6f 72 20 77 68 69 63 68 20 77 69 6c 6c  ursor which will
0b10: 0a 2a 2a 20 73 65 72 76 65 20 61 73 20 74 68 65  .** serve as the
0b20: 20 75 6e 64 65 72 6c 79 69 6e 67 20 72 65 70 72   underlying repr
0b30: 65 73 65 6e 74 61 74 69 6f 6e 20 6f 66 20 61 20  esentation of a 
0b40: 63 75 72 73 6f 72 20 74 68 61 74 20 73 63 61 6e  cursor that scan
0b50: 73 0a 2a 2a 20 6f 76 65 72 20 72 6f 77 73 20 6f  s.** over rows o
0b60: 66 20 74 68 65 20 72 65 73 75 6c 74 0a 2a 2f 0a  f the result.*/.
0b70: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 73  typedef struct s
0b80: 65 72 69 65 73 5f 63 75 72 73 6f 72 20 73 65 72  eries_cursor ser
0b90: 69 65 73 5f 63 75 72 73 6f 72 3b 0a 73 74 72 75  ies_cursor;.stru
0ba0: 63 74 20 73 65 72 69 65 73 5f 63 75 72 73 6f 72  ct series_cursor
0bb0: 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61   {.  sqlite3_vta
0bc0: 62 5f 63 75 72 73 6f 72 20 62 61 73 65 3b 20 20  b_cursor base;  
0bd0: 2f 2a 20 42 61 73 65 20 63 6c 61 73 73 20 2d 20  /* Base class - 
0be0: 6d 75 73 74 20 62 65 20 66 69 72 73 74 20 2a 2f  must be first */
0bf0: 0a 20 20 69 6e 74 20 69 73 44 65 73 63 3b 20 20  .  int isDesc;  
0c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0c10: 20 54 72 75 65 20 74 6f 20 63 6f 75 6e 74 20 64   True to count d
0c20: 6f 77 6e 20 72 61 74 68 65 72 20 74 68 61 6e 20  own rather than 
0c30: 75 70 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  up */.  sqlite3_
0c40: 69 6e 74 36 34 20 69 52 6f 77 69 64 3b 20 20 20  int64 iRowid;   
0c50: 20 20 20 2f 2a 20 54 68 65 20 72 6f 77 69 64 20     /* The rowid 
0c60: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74  */.  sqlite3_int
0c70: 36 34 20 69 56 61 6c 75 65 3b 20 20 20 20 20 20  64 iValue;      
0c80: 2f 2a 20 43 75 72 72 65 6e 74 20 76 61 6c 75 65  /* Current value
0c90: 20 28 22 76 61 6c 75 65 22 29 20 2a 2f 0a 20 20   ("value") */.  
0ca0: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 6d 6e  sqlite3_int64 mn
0cb0: 56 61 6c 75 65 3b 20 20 20 20 20 2f 2a 20 4d 69  Value;     /* Mi
0cc0: 6d 69 6d 75 6d 20 76 61 6c 75 65 20 28 22 73 74  mimum value ("st
0cd0: 61 72 74 22 29 20 2a 2f 0a 20 20 73 71 6c 69 74  art") */.  sqlit
0ce0: 65 33 5f 69 6e 74 36 34 20 6d 78 56 61 6c 75 65  e3_int64 mxValue
0cf0: 3b 20 20 20 20 20 2f 2a 20 4d 61 78 69 6d 75 6d  ;     /* Maximum
0d00: 20 76 61 6c 75 65 20 28 22 73 74 6f 70 22 29 20   value ("stop") 
0d10: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74  */.  sqlite3_int
0d20: 36 34 20 69 53 74 65 70 3b 20 20 20 20 20 20 20  64 iStep;       
0d30: 2f 2a 20 49 6e 63 72 65 6d 65 6e 74 20 28 22 73  /* Increment ("s
0d40: 74 65 70 22 29 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  tep") */.};../*.
0d50: 2a 2a 20 54 68 65 20 73 65 72 69 65 73 43 6f 6e  ** The seriesCon
0d60: 6e 65 63 74 28 29 20 6d 65 74 68 6f 64 20 69 73  nect() method is
0d70: 20 69 6e 76 6f 6b 65 64 20 74 6f 20 63 72 65 61   invoked to crea
0d80: 74 65 20 61 20 6e 65 77 0a 2a 2a 20 73 65 72 69  te a new.** seri
0d90: 65 73 5f 76 74 61 62 20 74 68 61 74 20 64 65 73  es_vtab that des
0da0: 63 72 69 62 65 73 20 74 68 65 20 67 65 6e 65 72  cribes the gener
0db0: 61 74 65 5f 73 65 72 69 65 73 20 76 69 72 74 75  ate_series virtu
0dc0: 61 6c 20 74 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20  al table..**.** 
0dd0: 54 68 69 6e 6b 20 6f 66 20 74 68 69 73 20 72 6f  Think of this ro
0de0: 75 74 69 6e 65 20 61 73 20 74 68 65 20 63 6f 6e  utine as the con
0df0: 73 74 72 75 63 74 6f 72 20 66 6f 72 20 73 65 72  structor for ser
0e00: 69 65 73 5f 76 74 61 62 20 6f 62 6a 65 63 74 73  ies_vtab objects
0e10: 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c 20 74 68 69 73  ..**.** All this
0e20: 20 72 6f 75 74 69 6e 65 20 6e 65 65 64 73 20 74   routine needs t
0e30: 6f 20 64 6f 20 69 73 3a 0a 2a 2a 0a 2a 2a 20 20  o do is:.**.**  
0e40: 20 20 28 31 29 20 41 6c 6c 6f 63 61 74 65 20 74    (1) Allocate t
0e50: 68 65 20 73 65 72 69 65 73 5f 76 74 61 62 20 6f  he series_vtab o
0e60: 62 6a 65 63 74 20 61 6e 64 20 69 6e 69 74 69 61  bject and initia
0e70: 6c 69 7a 65 20 61 6c 6c 20 66 69 65 6c 64 73 2e  lize all fields.
0e80: 0a 2a 2a 0a 2a 2a 20 20 20 20 28 32 29 20 54 65  .**.**    (2) Te
0e90: 6c 6c 20 53 51 4c 69 74 65 20 28 76 69 61 20 74  ll SQLite (via t
0ea0: 68 65 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61  he sqlite3_decla
0eb0: 72 65 5f 76 74 61 62 28 29 20 69 6e 74 65 72 66  re_vtab() interf
0ec0: 61 63 65 29 20 77 68 61 74 20 74 68 65 0a 2a 2a  ace) what the.**
0ed0: 20 20 20 20 20 20 20 20 72 65 73 75 6c 74 20 73          result s
0ee0: 65 74 20 6f 66 20 71 75 65 72 69 65 73 20 61 67  et of queries ag
0ef0: 61 69 6e 73 74 20 67 65 6e 65 72 61 74 65 5f 73  ainst generate_s
0f00: 65 72 69 65 73 20 77 69 6c 6c 20 6c 6f 6f 6b 20  eries will look 
0f10: 6c 69 6b 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  like..*/.static 
0f20: 69 6e 74 20 73 65 72 69 65 73 43 6f 6e 6e 65 63  int seriesConnec
0f30: 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  t(.  sqlite3 *db
0f40: 2c 0a 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a  ,.  void *pAux,.
0f50: 20 20 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73    int argc, cons
0f60: 74 20 63 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72  t char *const*ar
0f70: 67 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  gv,.  sqlite3_vt
0f80: 61 62 20 2a 2a 70 70 56 74 61 62 2c 0a 20 20 63  ab **ppVtab,.  c
0f90: 68 61 72 20 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20  har **pzErr.){. 
0fa0: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70   sqlite3_vtab *p
0fb0: 4e 65 77 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a  New;.  int rc;..
0fc0: 2f 2a 20 43 6f 6c 75 6d 6e 20 6e 75 6d 62 65 72  /* Column number
0fd0: 73 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53 45 52  s */.#define SER
0fe0: 49 45 53 5f 43 4f 4c 55 4d 4e 5f 56 41 4c 55 45  IES_COLUMN_VALUE
0ff0: 20 30 0a 23 64 65 66 69 6e 65 20 53 45 52 49 45   0.#define SERIE
1000: 53 5f 43 4f 4c 55 4d 4e 5f 53 54 41 52 54 20 31  S_COLUMN_START 1
1010: 0a 23 64 65 66 69 6e 65 20 53 45 52 49 45 53 5f  .#define SERIES_
1020: 43 4f 4c 55 4d 4e 5f 53 54 4f 50 20 20 32 0a 23  COLUMN_STOP  2.#
1030: 64 65 66 69 6e 65 20 53 45 52 49 45 53 5f 43 4f  define SERIES_CO
1040: 4c 55 4d 4e 5f 53 54 45 50 20 20 33 0a 0a 20 20  LUMN_STEP  3..  
1050: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 64 65 63  rc = sqlite3_dec
1060: 6c 61 72 65 5f 76 74 61 62 28 64 62 2c 0a 20 20  lare_vtab(db,.  
1070: 20 20 20 22 43 52 45 41 54 45 20 54 41 42 4c 45     "CREATE TABLE
1080: 20 78 28 76 61 6c 75 65 2c 73 74 61 72 74 20 68   x(value,start h
1090: 69 64 64 65 6e 2c 73 74 6f 70 20 68 69 64 64 65  idden,stop hidde
10a0: 6e 2c 73 74 65 70 20 68 69 64 64 65 6e 29 22 29  n,step hidden)")
10b0: 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
10c0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 4e 65  TE_OK ){.    pNe
10d0: 77 20 3d 20 2a 70 70 56 74 61 62 20 3d 20 73 71  w = *ppVtab = sq
10e0: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 73 69  lite3_malloc( si
10f0: 7a 65 6f 66 28 2a 70 4e 65 77 29 20 29 3b 0a 20  zeof(*pNew) );. 
1100: 20 20 20 69 66 28 20 70 4e 65 77 3d 3d 30 20 29     if( pNew==0 )
1110: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
1120: 4f 4d 45 4d 3b 0a 20 20 20 20 6d 65 6d 73 65 74  OMEM;.    memset
1130: 28 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65 6f 66  (pNew, 0, sizeof
1140: 28 2a 70 4e 65 77 29 29 3b 0a 20 20 7d 0a 20 20  (*pNew));.  }.  
1150: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
1160: 0a 2a 2a 20 54 68 69 73 20 6d 65 74 68 6f 64 20  .** This method 
1170: 69 73 20 74 68 65 20 64 65 73 74 72 75 63 74 6f  is the destructo
1180: 72 20 66 6f 72 20 73 65 72 69 65 73 5f 63 75 72  r for series_cur
1190: 73 6f 72 20 6f 62 6a 65 63 74 73 2e 0a 2a 2f 0a  sor objects..*/.
11a0: 73 74 61 74 69 63 20 69 6e 74 20 73 65 72 69 65  static int serie
11b0: 73 44 69 73 63 6f 6e 6e 65 63 74 28 73 71 6c 69  sDisconnect(sqli
11c0: 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29  te3_vtab *pVtab)
11d0: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  {.  sqlite3_free
11e0: 28 70 56 74 61 62 29 3b 0a 20 20 72 65 74 75 72  (pVtab);.  retur
11f0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
1200: 2f 2a 0a 2a 2a 20 43 6f 6e 73 74 72 75 63 74 6f  /*.** Constructo
1210: 72 20 66 6f 72 20 61 20 6e 65 77 20 73 65 72 69  r for a new seri
1220: 65 73 5f 63 75 72 73 6f 72 20 6f 62 6a 65 63 74  es_cursor object
1230: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
1240: 73 65 72 69 65 73 4f 70 65 6e 28 73 71 6c 69 74  seriesOpen(sqlit
1250: 65 33 5f 76 74 61 62 20 2a 70 2c 20 73 71 6c 69  e3_vtab *p, sqli
1260: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
1270: 2a 2a 70 70 43 75 72 73 6f 72 29 7b 0a 20 20 73  **ppCursor){.  s
1280: 65 72 69 65 73 5f 63 75 72 73 6f 72 20 2a 70 43  eries_cursor *pC
1290: 75 72 3b 0a 20 20 70 43 75 72 20 3d 20 73 71 6c  ur;.  pCur = sql
12a0: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 73 69 7a  ite3_malloc( siz
12b0: 65 6f 66 28 2a 70 43 75 72 29 20 29 3b 0a 20 20  eof(*pCur) );.  
12c0: 69 66 28 20 70 43 75 72 3d 3d 30 20 29 20 72 65  if( pCur==0 ) re
12d0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
12e0: 4d 3b 0a 20 20 6d 65 6d 73 65 74 28 70 43 75 72  M;.  memset(pCur
12f0: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 2a 70 43 75  , 0, sizeof(*pCu
1300: 72 29 29 3b 0a 20 20 2a 70 70 43 75 72 73 6f 72  r));.  *ppCursor
1310: 20 3d 20 26 70 43 75 72 2d 3e 62 61 73 65 3b 0a   = &pCur->base;.
1320: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
1330: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 73  OK;.}../*.** Des
1340: 74 72 75 63 74 6f 72 20 66 6f 72 20 61 20 73 65  tructor for a se
1350: 72 69 65 73 5f 63 75 72 73 6f 72 2e 0a 2a 2f 0a  ries_cursor..*/.
1360: 73 74 61 74 69 63 20 69 6e 74 20 73 65 72 69 65  static int serie
1370: 73 43 6c 6f 73 65 28 73 71 6c 69 74 65 33 5f 76  sClose(sqlite3_v
1380: 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 29  tab_cursor *cur)
1390: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  {.  sqlite3_free
13a0: 28 63 75 72 29 3b 0a 20 20 72 65 74 75 72 6e 20  (cur);.  return 
13b0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f  SQLITE_OK;.}.../
13c0: 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 61 20 73  *.** Advance a s
13d0: 65 72 69 65 73 5f 63 75 72 73 6f 72 20 74 6f 20  eries_cursor to 
13e0: 69 74 73 20 6e 65 78 74 20 72 6f 77 20 6f 66 20  its next row of 
13f0: 6f 75 74 70 75 74 2e 0a 2a 2f 0a 73 74 61 74 69  output..*/.stati
1400: 63 20 69 6e 74 20 73 65 72 69 65 73 4e 65 78 74  c int seriesNext
1410: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
1420: 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 73 65  rsor *cur){.  se
1430: 72 69 65 73 5f 63 75 72 73 6f 72 20 2a 70 43 75  ries_cursor *pCu
1440: 72 20 3d 20 28 73 65 72 69 65 73 5f 63 75 72 73  r = (series_curs
1450: 6f 72 2a 29 63 75 72 3b 0a 20 20 69 66 28 20 70  or*)cur;.  if( p
1460: 43 75 72 2d 3e 69 73 44 65 73 63 20 29 7b 0a 20  Cur->isDesc ){. 
1470: 20 20 20 70 43 75 72 2d 3e 69 56 61 6c 75 65 20     pCur->iValue 
1480: 2d 3d 20 70 43 75 72 2d 3e 69 53 74 65 70 3b 0a  -= pCur->iStep;.
1490: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 43 75    }else{.    pCu
14a0: 72 2d 3e 69 56 61 6c 75 65 20 2b 3d 20 70 43 75  r->iValue += pCu
14b0: 72 2d 3e 69 53 74 65 70 3b 0a 20 20 7d 0a 20 20  r->iStep;.  }.  
14c0: 70 43 75 72 2d 3e 69 52 6f 77 69 64 2b 2b 3b 0a  pCur->iRowid++;.
14d0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
14e0: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  OK;.}../*.** Ret
14f0: 75 72 6e 20 76 61 6c 75 65 73 20 6f 66 20 63 6f  urn values of co
1500: 6c 75 6d 6e 73 20 66 6f 72 20 74 68 65 20 72 6f  lumns for the ro
1510: 77 20 61 74 20 77 68 69 63 68 20 74 68 65 20 73  w at which the s
1520: 65 72 69 65 73 5f 63 75 72 73 6f 72 0a 2a 2a 20  eries_cursor.** 
1530: 69 73 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69  is currently poi
1540: 6e 74 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63  nting..*/.static
1550: 20 69 6e 74 20 73 65 72 69 65 73 43 6f 6c 75 6d   int seriesColum
1560: 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  n(.  sqlite3_vta
1570: 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 20  b_cursor *cur,  
1580: 20 2f 2a 20 54 68 65 20 63 75 72 73 6f 72 20 2a   /* The cursor *
1590: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74  /.  sqlite3_cont
15a0: 65 78 74 20 2a 63 74 78 2c 20 20 20 20 20 20 20  ext *ctx,       
15b0: 2f 2a 20 46 69 72 73 74 20 61 72 67 75 6d 65 6e  /* First argumen
15c0: 74 20 74 6f 20 73 71 6c 69 74 65 33 5f 72 65 73  t to sqlite3_res
15d0: 75 6c 74 5f 2e 2e 2e 28 29 20 2a 2f 0a 20 20 69  ult_...() */.  i
15e0: 6e 74 20 69 20 20 20 20 20 20 20 20 20 20 20 20  nt i            
15f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 68             /* Wh
1600: 69 63 68 20 63 6f 6c 75 6d 6e 20 74 6f 20 72 65  ich column to re
1610: 74 75 72 6e 20 2a 2f 0a 29 7b 0a 20 20 73 65 72  turn */.){.  ser
1620: 69 65 73 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  ies_cursor *pCur
1630: 20 3d 20 28 73 65 72 69 65 73 5f 63 75 72 73 6f   = (series_curso
1640: 72 2a 29 63 75 72 3b 0a 20 20 73 71 6c 69 74 65  r*)cur;.  sqlite
1650: 33 5f 69 6e 74 36 34 20 78 20 3d 20 30 3b 0a 20  3_int64 x = 0;. 
1660: 20 73 77 69 74 63 68 28 20 69 20 29 7b 0a 20 20   switch( i ){.  
1670: 20 20 63 61 73 65 20 53 45 52 49 45 53 5f 43 4f    case SERIES_CO
1680: 4c 55 4d 4e 5f 53 54 41 52 54 3a 20 20 78 20 3d  LUMN_START:  x =
1690: 20 70 43 75 72 2d 3e 6d 6e 56 61 6c 75 65 3b 20   pCur->mnValue; 
16a0: 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20  break;.    case 
16b0: 53 45 52 49 45 53 5f 43 4f 4c 55 4d 4e 5f 53 54  SERIES_COLUMN_ST
16c0: 4f 50 3a 20 20 20 78 20 3d 20 70 43 75 72 2d 3e  OP:   x = pCur->
16d0: 6d 78 56 61 6c 75 65 3b 20 62 72 65 61 6b 3b 0a  mxValue; break;.
16e0: 20 20 20 20 63 61 73 65 20 53 45 52 49 45 53 5f      case SERIES_
16f0: 43 4f 4c 55 4d 4e 5f 53 54 45 50 3a 20 20 20 78  COLUMN_STEP:   x
1700: 20 3d 20 70 43 75 72 2d 3e 69 53 74 65 70 3b 20   = pCur->iStep; 
1710: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 64 65 66    break;.    def
1720: 61 75 6c 74 3a 20 20 20 20 20 20 20 20 20 20 20  ault:           
1730: 20 20 20 20 20 20 20 20 78 20 3d 20 70 43 75 72          x = pCur
1740: 2d 3e 69 56 61 6c 75 65 3b 20 20 62 72 65 61 6b  ->iValue;  break
1750: 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  ;.  }.  sqlite3_
1760: 72 65 73 75 6c 74 5f 69 6e 74 36 34 28 63 74 78  result_int64(ctx
1770: 2c 20 78 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  , x);.  return S
1780: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
1790: 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 72 6f  ** Return the ro
17a0: 77 69 64 20 66 6f 72 20 74 68 65 20 63 75 72 72  wid for the curr
17b0: 65 6e 74 20 72 6f 77 2e 20 20 49 6e 20 74 68 69  ent row.  In thi
17c0: 73 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  s implementation
17d0: 2c 20 74 68 65 0a 2a 2a 20 72 6f 77 69 64 20 69  , the.** rowid i
17e0: 73 20 74 68 65 20 73 61 6d 65 20 61 73 20 74 68  s the same as th
17f0: 65 20 6f 75 74 70 75 74 20 76 61 6c 75 65 2e 0a  e output value..
1800: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
1810: 72 69 65 73 52 6f 77 69 64 28 73 71 6c 69 74 65  riesRowid(sqlite
1820: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63  3_vtab_cursor *c
1830: 75 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  ur, sqlite_int64
1840: 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20 73 65 72   *pRowid){.  ser
1850: 69 65 73 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  ies_cursor *pCur
1860: 20 3d 20 28 73 65 72 69 65 73 5f 63 75 72 73 6f   = (series_curso
1870: 72 2a 29 63 75 72 3b 0a 20 20 2a 70 52 6f 77 69  r*)cur;.  *pRowi
1880: 64 20 3d 20 70 43 75 72 2d 3e 69 52 6f 77 69 64  d = pCur->iRowid
1890: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
18a0: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  E_OK;.}../*.** R
18b0: 65 74 75 72 6e 20 54 52 55 45 20 69 66 20 74 68  eturn TRUE if th
18c0: 65 20 63 75 72 73 6f 72 20 68 61 73 20 62 65 65  e cursor has bee
18d0: 6e 20 6d 6f 76 65 64 20 6f 66 66 20 6f 66 20 74  n moved off of t
18e0: 68 65 20 6c 61 73 74 0a 2a 2a 20 72 6f 77 20 6f  he last.** row o
18f0: 66 20 6f 75 74 70 75 74 2e 0a 2a 2f 0a 73 74 61  f output..*/.sta
1900: 74 69 63 20 69 6e 74 20 73 65 72 69 65 73 45 6f  tic int seriesEo
1910: 66 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  f(sqlite3_vtab_c
1920: 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 73  ursor *cur){.  s
1930: 65 72 69 65 73 5f 63 75 72 73 6f 72 20 2a 70 43  eries_cursor *pC
1940: 75 72 20 3d 20 28 73 65 72 69 65 73 5f 63 75 72  ur = (series_cur
1950: 73 6f 72 2a 29 63 75 72 3b 0a 20 20 69 66 28 20  sor*)cur;.  if( 
1960: 70 43 75 72 2d 3e 69 73 44 65 73 63 20 29 7b 0a  pCur->isDesc ){.
1970: 20 20 20 20 72 65 74 75 72 6e 20 70 43 75 72 2d      return pCur-
1980: 3e 69 56 61 6c 75 65 20 3c 20 70 43 75 72 2d 3e  >iValue < pCur->
1990: 6d 6e 56 61 6c 75 65 3b 0a 20 20 7d 65 6c 73 65  mnValue;.  }else
19a0: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70 43 75  {.    return pCu
19b0: 72 2d 3e 69 56 61 6c 75 65 20 3e 20 70 43 75 72  r->iValue > pCur
19c0: 2d 3e 6d 78 56 61 6c 75 65 3b 0a 20 20 7d 0a 7d  ->mxValue;.  }.}
19d0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 6d 65 74  ../*.** This met
19e0: 68 6f 64 20 69 73 20 63 61 6c 6c 65 64 20 74 6f  hod is called to
19f0: 20 22 72 65 77 69 6e 64 22 20 74 68 65 20 73 65   "rewind" the se
1a00: 72 69 65 73 5f 63 75 72 73 6f 72 20 6f 62 6a 65  ries_cursor obje
1a10: 63 74 20 62 61 63 6b 0a 2a 2a 20 74 6f 20 74 68  ct back.** to th
1a20: 65 20 66 69 72 73 74 20 72 6f 77 20 6f 66 20 6f  e first row of o
1a30: 75 74 70 75 74 2e 20 20 54 68 69 73 20 6d 65 74  utput.  This met
1a40: 68 6f 64 20 69 73 20 61 6c 77 61 79 73 20 63 61  hod is always ca
1a50: 6c 6c 65 64 20 61 74 20 6c 65 61 73 74 0a 2a 2a  lled at least.**
1a60: 20 6f 6e 63 65 20 70 72 69 6f 72 20 74 6f 20 61   once prior to a
1a70: 6e 79 20 63 61 6c 6c 20 74 6f 20 73 65 72 69 65  ny call to serie
1a80: 73 43 6f 6c 75 6d 6e 28 29 20 6f 72 20 73 65 72  sColumn() or ser
1a90: 69 65 73 52 6f 77 69 64 28 29 20 6f 72 20 0a 2a  iesRowid() or .*
1aa0: 2a 20 73 65 72 69 65 73 45 6f 66 28 29 2e 0a 2a  * seriesEof()..*
1ab0: 2a 0a 2a 2a 20 54 68 65 20 71 75 65 72 79 20 70  *.** The query p
1ac0: 6c 61 6e 20 73 65 6c 65 63 74 65 64 20 62 79 20  lan selected by 
1ad0: 73 65 72 69 65 73 42 65 73 74 49 6e 64 65 78 20  seriesBestIndex 
1ae0: 69 73 20 70 61 73 73 65 64 20 69 6e 20 74 68 65  is passed in the
1af0: 20 69 64 78 4e 75 6d 0a 2a 2a 20 70 61 72 61 6d   idxNum.** param
1b00: 65 74 65 72 2e 20 20 28 69 64 78 53 74 72 20 69  eter.  (idxStr i
1b10: 73 20 6e 6f 74 20 75 73 65 64 20 69 6e 20 74 68  s not used in th
1b20: 69 73 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  is implementatio
1b30: 6e 2e 29 20 20 69 64 78 4e 75 6d 0a 2a 2a 20 69  n.)  idxNum.** i
1b40: 73 20 61 20 62 69 74 6d 61 73 6b 20 73 68 6f 77  s a bitmask show
1b50: 69 6e 67 20 77 68 69 63 68 20 63 6f 6e 73 74 72  ing which constr
1b60: 61 69 6e 74 73 20 61 72 65 20 61 76 61 69 6c 61  aints are availa
1b70: 62 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 31 3a  ble:.**.**    1:
1b80: 20 20 20 20 73 74 61 72 74 3d 56 41 4c 55 45 0a      start=VALUE.
1b90: 2a 2a 20 20 20 20 32 3a 20 20 20 20 73 74 6f 70  **    2:    stop
1ba0: 3d 56 41 4c 55 45 0a 2a 2a 20 20 20 20 34 3a 20  =VALUE.**    4: 
1bb0: 20 20 20 73 74 65 70 3d 56 41 4c 55 45 0a 2a 2a     step=VALUE.**
1bc0: 0a 2a 2a 20 41 6c 73 6f 2c 20 69 66 20 62 69 74  .** Also, if bit
1bd0: 20 38 20 69 73 20 73 65 74 2c 20 74 68 61 74 20   8 is set, that 
1be0: 6d 65 61 6e 73 20 74 68 61 74 20 74 68 65 20 73  means that the s
1bf0: 65 72 69 65 73 20 73 68 6f 75 6c 64 20 62 65 20  eries should be 
1c00: 6f 75 74 70 75 74 0a 2a 2a 20 69 6e 20 64 65 73  output.** in des
1c10: 63 65 6e 64 69 6e 67 20 6f 72 64 65 72 20 72 61  cending order ra
1c20: 74 68 65 72 20 74 68 61 6e 20 69 6e 20 61 73 63  ther than in asc
1c30: 65 6e 64 69 6e 67 20 6f 72 64 65 72 2e 0a 2a 2a  ending order..**
1c40: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
1c50: 20 73 68 6f 75 6c 64 20 69 6e 69 74 69 61 6c 69   should initiali
1c60: 7a 65 20 74 68 65 20 63 75 72 73 6f 72 20 61 6e  ze the cursor an
1c70: 64 20 70 6f 73 69 74 69 6f 6e 20 69 74 20 73 6f  d position it so
1c80: 20 74 68 61 74 20 69 74 0a 2a 2a 20 69 73 20 70   that it.** is p
1c90: 6f 69 6e 74 69 6e 67 20 61 74 20 74 68 65 20 66  ointing at the f
1ca0: 69 72 73 74 20 72 6f 77 2c 20 6f 72 20 70 6f 69  irst row, or poi
1cb0: 6e 74 69 6e 67 20 6f 66 66 20 74 68 65 20 65 6e  nting off the en
1cc0: 64 20 6f 66 20 74 68 65 20 74 61 62 6c 65 0a 2a  d of the table.*
1cd0: 2a 20 28 73 6f 20 74 68 61 74 20 73 65 72 69 65  * (so that serie
1ce0: 73 45 6f 66 28 29 20 77 69 6c 6c 20 72 65 74 75  sEof() will retu
1cf0: 72 6e 20 74 72 75 65 29 20 69 66 20 74 68 65 20  rn true) if the 
1d00: 74 61 62 6c 65 20 69 73 20 65 6d 70 74 79 2e 0a  table is empty..
1d10: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
1d20: 72 69 65 73 46 69 6c 74 65 72 28 0a 20 20 73 71  riesFilter(.  sq
1d30: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
1d40: 72 20 2a 70 56 74 61 62 43 75 72 73 6f 72 2c 20  r *pVtabCursor, 
1d50: 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c 20 63  .  int idxNum, c
1d60: 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78 53 74  onst char *idxSt
1d70: 72 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 73  r,.  int argc, s
1d80: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61  qlite3_value **a
1d90: 72 67 76 0a 29 7b 0a 20 20 73 65 72 69 65 73 5f  rgv.){.  series_
1da0: 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28  cursor *pCur = (
1db0: 73 65 72 69 65 73 5f 63 75 72 73 6f 72 20 2a 29  series_cursor *)
1dc0: 70 56 74 61 62 43 75 72 73 6f 72 3b 0a 20 20 69  pVtabCursor;.  i
1dd0: 6e 74 20 69 20 3d 20 30 3b 0a 20 20 69 66 28 20  nt i = 0;.  if( 
1de0: 69 64 78 4e 75 6d 20 26 20 31 20 29 7b 0a 20 20  idxNum & 1 ){.  
1df0: 20 20 70 43 75 72 2d 3e 6d 6e 56 61 6c 75 65 20    pCur->mnValue 
1e00: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
1e10: 69 6e 74 36 34 28 61 72 67 76 5b 69 2b 2b 5d 29  int64(argv[i++])
1e20: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70  ;.  }else{.    p
1e30: 43 75 72 2d 3e 6d 6e 56 61 6c 75 65 20 3d 20 30  Cur->mnValue = 0
1e40: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 69 64 78 4e  ;.  }.  if( idxN
1e50: 75 6d 20 26 20 32 20 29 7b 0a 20 20 20 20 70 43  um & 2 ){.    pC
1e60: 75 72 2d 3e 6d 78 56 61 6c 75 65 20 3d 20 73 71  ur->mxValue = sq
1e70: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74 36  lite3_value_int6
1e80: 34 28 61 72 67 76 5b 69 2b 2b 5d 29 3b 0a 20 20  4(argv[i++]);.  
1e90: 7d 65 6c 73 65 7b 0a 20 20 20 20 70 43 75 72 2d  }else{.    pCur-
1ea0: 3e 6d 78 56 61 6c 75 65 20 3d 20 30 78 66 66 66  >mxValue = 0xfff
1eb0: 66 66 66 66 66 3b 0a 20 20 7d 0a 20 20 69 66 28  fffff;.  }.  if(
1ec0: 20 69 64 78 4e 75 6d 20 26 20 34 20 29 7b 0a 20   idxNum & 4 ){. 
1ed0: 20 20 20 70 43 75 72 2d 3e 69 53 74 65 70 20 3d     pCur->iStep =
1ee0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69   sqlite3_value_i
1ef0: 6e 74 36 34 28 61 72 67 76 5b 69 2b 2b 5d 29 3b  nt64(argv[i++]);
1f00: 0a 20 20 20 20 69 66 28 20 70 43 75 72 2d 3e 69  .    if( pCur->i
1f10: 53 74 65 70 3c 31 20 29 20 70 43 75 72 2d 3e 69  Step<1 ) pCur->i
1f20: 53 74 65 70 20 3d 20 31 3b 0a 20 20 7d 65 6c 73  Step = 1;.  }els
1f30: 65 7b 0a 20 20 20 20 70 43 75 72 2d 3e 69 53 74  e{.    pCur->iSt
1f40: 65 70 20 3d 20 31 3b 0a 20 20 7d 0a 20 20 69 66  ep = 1;.  }.  if
1f50: 28 20 69 64 78 4e 75 6d 20 26 20 38 20 29 7b 0a  ( idxNum & 8 ){.
1f60: 20 20 20 20 70 43 75 72 2d 3e 69 73 44 65 73 63      pCur->isDesc
1f70: 20 3d 20 31 3b 0a 20 20 20 20 70 43 75 72 2d 3e   = 1;.    pCur->
1f80: 69 56 61 6c 75 65 20 3d 20 70 43 75 72 2d 3e 6d  iValue = pCur->m
1f90: 78 56 61 6c 75 65 3b 0a 20 20 20 20 69 66 28 20  xValue;.    if( 
1fa0: 70 43 75 72 2d 3e 69 53 74 65 70 3e 30 20 29 7b  pCur->iStep>0 ){
1fb0: 0a 20 20 20 20 20 20 70 43 75 72 2d 3e 69 56 61  .      pCur->iVa
1fc0: 6c 75 65 20 2d 3d 20 28 70 43 75 72 2d 3e 6d 78  lue -= (pCur->mx
1fd0: 56 61 6c 75 65 20 2d 20 70 43 75 72 2d 3e 6d 6e  Value - pCur->mn
1fe0: 56 61 6c 75 65 29 25 70 43 75 72 2d 3e 69 53 74  Value)%pCur->iSt
1ff0: 65 70 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73  ep;.    }.  }els
2000: 65 7b 0a 20 20 20 20 70 43 75 72 2d 3e 69 73 44  e{.    pCur->isD
2010: 65 73 63 20 3d 20 30 3b 0a 20 20 20 20 70 43 75  esc = 0;.    pCu
2020: 72 2d 3e 69 56 61 6c 75 65 20 3d 20 70 43 75 72  r->iValue = pCur
2030: 2d 3e 6d 6e 56 61 6c 75 65 3b 0a 20 20 7d 0a 20  ->mnValue;.  }. 
2040: 20 70 43 75 72 2d 3e 69 52 6f 77 69 64 20 3d 20   pCur->iRowid = 
2050: 31 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  1;.  return SQLI
2060: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
2070: 53 51 4c 69 74 65 20 77 69 6c 6c 20 69 6e 76 6f  SQLite will invo
2080: 6b 65 20 74 68 69 73 20 6d 65 74 68 6f 64 20 6f  ke this method o
2090: 6e 65 20 6f 72 20 6d 6f 72 65 20 74 69 6d 65 73  ne or more times
20a0: 20 77 68 69 6c 65 20 70 6c 61 6e 6e 69 6e 67 20   while planning 
20b0: 61 20 71 75 65 72 79 0a 2a 2a 20 74 68 61 74 20  a query.** that 
20c0: 75 73 65 73 20 74 68 65 20 67 65 6e 65 72 61 74  uses the generat
20d0: 65 5f 73 65 72 69 65 73 20 76 69 72 74 75 61 6c  e_series virtual
20e0: 20 74 61 62 6c 65 2e 20 20 54 68 69 73 20 72 6f   table.  This ro
20f0: 75 74 69 6e 65 20 6e 65 65 64 73 20 74 6f 20 63  utine needs to c
2100: 72 65 61 74 65 0a 2a 2a 20 61 20 71 75 65 72 79  reate.** a query
2110: 20 70 6c 61 6e 20 66 6f 72 20 65 61 63 68 20 69   plan for each i
2120: 6e 76 6f 63 61 74 69 6f 6e 20 61 6e 64 20 63 6f  nvocation and co
2130: 6d 70 75 74 65 20 61 6e 20 65 73 74 69 6d 61 74  mpute an estimat
2140: 65 64 20 63 6f 73 74 20 66 6f 72 20 74 68 61 74  ed cost for that
2150: 0a 2a 2a 20 70 6c 61 6e 2e 0a 2a 2a 0a 2a 2a 20  .** plan..**.** 
2160: 49 6e 20 74 68 69 73 20 69 6d 70 6c 65 6d 65 6e  In this implemen
2170: 74 61 74 69 6f 6e 20 69 64 78 4e 75 6d 20 69 73  tation idxNum is
2180: 20 75 73 65 64 20 74 6f 20 72 65 70 72 65 73 65   used to represe
2190: 6e 74 20 74 68 65 0a 2a 2a 20 71 75 65 72 79 20  nt the.** query 
21a0: 70 6c 61 6e 2e 20 20 69 64 78 53 74 72 20 69 73  plan.  idxStr is
21b0: 20 75 6e 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 54   unused..**.** T
21c0: 68 65 20 71 75 65 72 79 20 70 6c 61 6e 20 69 73  he query plan is
21d0: 20 72 65 70 72 65 73 65 6e 74 65 64 20 62 79 20   represented by 
21e0: 62 69 74 73 20 69 6e 20 69 64 78 4e 75 6d 3a 0a  bits in idxNum:.
21f0: 2a 2a 0a 2a 2a 20 20 28 31 29 20 20 73 74 61 72  **.**  (1)  star
2200: 74 20 3d 20 24 76 61 6c 75 65 20 20 2d 2d 20 63  t = $value  -- c
2210: 6f 6e 73 74 72 61 69 6e 74 20 65 78 69 73 74 73  onstraint exists
2220: 0a 2a 2a 20 20 28 32 29 20 20 73 74 6f 70 20 3d  .**  (2)  stop =
2230: 20 24 76 61 6c 75 65 20 20 20 2d 2d 20 63 6f 6e   $value   -- con
2240: 73 74 72 61 69 6e 74 20 65 78 69 73 74 73 0a 2a  straint exists.*
2250: 2a 20 20 28 34 29 20 20 73 74 65 70 20 3d 20 24  *  (4)  step = $
2260: 76 61 6c 75 65 20 20 20 2d 2d 20 63 6f 6e 73 74  value   -- const
2270: 72 61 69 6e 74 20 65 78 69 73 74 73 0a 2a 2a 20  raint exists.** 
2280: 20 28 38 29 20 20 6f 75 74 70 75 74 20 69 6e 20   (8)  output in 
2290: 64 65 73 63 65 6e 64 69 6e 67 20 6f 72 64 65 72  descending order
22a0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73  .*/.static int s
22b0: 65 72 69 65 73 42 65 73 74 49 6e 64 65 78 28 0a  eriesBestIndex(.
22c0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
22d0: 74 61 62 2c 0a 20 20 73 71 6c 69 74 65 33 5f 69  tab,.  sqlite3_i
22e0: 6e 64 65 78 5f 69 6e 66 6f 20 2a 70 49 64 78 49  ndex_info *pIdxI
22f0: 6e 66 6f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 20  nfo.){.  int i; 
2300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2310: 2f 2a 20 4c 6f 6f 70 20 6f 76 65 72 20 63 6f 6e  /* Loop over con
2320: 73 74 72 61 69 6e 74 73 20 2a 2f 0a 20 20 69 6e  straints */.  in
2330: 74 20 69 64 78 4e 75 6d 20 3d 20 30 3b 20 20 20  t idxNum = 0;   
2340: 20 20 20 20 20 2f 2a 20 54 68 65 20 71 75 65 72       /* The quer
2350: 79 20 70 6c 61 6e 20 62 69 74 6d 61 73 6b 20 2a  y plan bitmask *
2360: 2f 0a 20 20 69 6e 74 20 73 74 61 72 74 49 64 78  /.  int startIdx
2370: 20 3d 20 2d 31 3b 20 20 20 20 20 2f 2a 20 49 6e   = -1;     /* In
2380: 64 65 78 20 6f 66 20 74 68 65 20 73 74 61 72 74  dex of the start
2390: 3d 20 63 6f 6e 73 74 72 61 69 6e 74 2c 20 6f 72  = constraint, or
23a0: 20 2d 31 20 69 66 20 6e 6f 6e 65 20 2a 2f 0a 20   -1 if none */. 
23b0: 20 69 6e 74 20 73 74 6f 70 49 64 78 20 3d 20 2d   int stopIdx = -
23c0: 31 3b 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78  1;      /* Index
23d0: 20 6f 66 20 74 68 65 20 73 74 6f 70 3d 20 63 6f   of the stop= co
23e0: 6e 73 74 72 61 69 6e 74 2c 20 6f 72 20 2d 31 20  nstraint, or -1 
23f0: 69 66 20 6e 6f 6e 65 20 2a 2f 0a 20 20 69 6e 74  if none */.  int
2400: 20 73 74 65 70 49 64 78 20 3d 20 2d 31 3b 20 20   stepIdx = -1;  
2410: 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20      /* Index of 
2420: 74 68 65 20 73 74 65 70 3d 20 63 6f 6e 73 74 72  the step= constr
2430: 61 69 6e 74 2c 20 6f 72 20 2d 31 20 69 66 20 6e  aint, or -1 if n
2440: 6f 6e 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 72  one */.  int nAr
2450: 67 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  g = 0;          
2460: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67  /* Number of arg
2470: 75 6d 65 6e 74 73 20 74 68 61 74 20 73 65 72 69  uments that seri
2480: 65 73 46 69 6c 74 65 72 28 29 20 65 78 70 65 63  esFilter() expec
2490: 74 73 20 2a 2f 0a 0a 20 20 63 6f 6e 73 74 20 73  ts */..  const s
24a0: 74 72 75 63 74 20 73 71 6c 69 74 65 33 5f 69 6e  truct sqlite3_in
24b0: 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e 74 20 2a  dex_constraint *
24c0: 70 43 6f 6e 73 74 72 61 69 6e 74 3b 0a 20 20 70  pConstraint;.  p
24d0: 43 6f 6e 73 74 72 61 69 6e 74 20 3d 20 70 49 64  Constraint = pId
24e0: 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69  xInfo->aConstrai
24f0: 6e 74 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  nt;.  for(i=0; i
2500: 3c 70 49 64 78 49 6e 66 6f 2d 3e 6e 43 6f 6e 73  <pIdxInfo->nCons
2510: 74 72 61 69 6e 74 3b 20 69 2b 2b 2c 20 70 43 6f  traint; i++, pCo
2520: 6e 73 74 72 61 69 6e 74 2b 2b 29 7b 0a 20 20 20  nstraint++){.   
2530: 20 69 66 28 20 70 43 6f 6e 73 74 72 61 69 6e 74   if( pConstraint
2540: 2d 3e 75 73 61 62 6c 65 3d 3d 30 20 29 20 63 6f  ->usable==0 ) co
2550: 6e 74 69 6e 75 65 3b 0a 20 20 20 20 69 66 28 20  ntinue;.    if( 
2560: 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 21  pConstraint->op!
2570: 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f  =SQLITE_INDEX_CO
2580: 4e 53 54 52 41 49 4e 54 5f 45 51 20 29 20 63 6f  NSTRAINT_EQ ) co
2590: 6e 74 69 6e 75 65 3b 0a 20 20 20 20 73 77 69 74  ntinue;.    swit
25a0: 63 68 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d  ch( pConstraint-
25b0: 3e 69 43 6f 6c 75 6d 6e 20 29 7b 0a 20 20 20 20  >iColumn ){.    
25c0: 20 20 63 61 73 65 20 53 45 52 49 45 53 5f 43 4f    case SERIES_CO
25d0: 4c 55 4d 4e 5f 53 54 41 52 54 3a 0a 20 20 20 20  LUMN_START:.    
25e0: 20 20 20 20 73 74 61 72 74 49 64 78 20 3d 20 69      startIdx = i
25f0: 3b 0a 20 20 20 20 20 20 20 20 69 64 78 4e 75 6d  ;.        idxNum
2600: 20 7c 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 62   |= 1;.        b
2610: 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65  reak;.      case
2620: 20 53 45 52 49 45 53 5f 43 4f 4c 55 4d 4e 5f 53   SERIES_COLUMN_S
2630: 54 4f 50 3a 0a 20 20 20 20 20 20 20 20 73 74 6f  TOP:.        sto
2640: 70 49 64 78 20 3d 20 69 3b 0a 20 20 20 20 20 20  pIdx = i;.      
2650: 20 20 69 64 78 4e 75 6d 20 7c 3d 20 32 3b 0a 20    idxNum |= 2;. 
2660: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
2670: 20 20 20 20 63 61 73 65 20 53 45 52 49 45 53 5f      case SERIES_
2680: 43 4f 4c 55 4d 4e 5f 53 54 45 50 3a 0a 20 20 20  COLUMN_STEP:.   
2690: 20 20 20 20 20 73 74 65 70 49 64 78 20 3d 20 69       stepIdx = i
26a0: 3b 0a 20 20 20 20 20 20 20 20 69 64 78 4e 75 6d  ;.        idxNum
26b0: 20 7c 3d 20 34 3b 0a 20 20 20 20 20 20 20 20 62   |= 4;.        b
26c0: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  reak;.    }.  }.
26d0: 20 20 69 66 28 20 73 74 61 72 74 49 64 78 3e 3d    if( startIdx>=
26e0: 30 20 29 7b 0a 20 20 20 20 70 49 64 78 49 6e 66  0 ){.    pIdxInf
26f0: 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73  o->aConstraintUs
2700: 61 67 65 5b 73 74 61 72 74 49 64 78 5d 2e 61 72  age[startIdx].ar
2710: 67 76 49 6e 64 65 78 20 3d 20 2b 2b 6e 41 72 67  gvIndex = ++nArg
2720: 3b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e  ;.    pIdxInfo->
2730: 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65  aConstraintUsage
2740: 5b 73 74 61 72 74 49 64 78 5d 2e 6f 6d 69 74 20  [startIdx].omit 
2750: 3d 20 31 3b 0a 20 20 7d 0a 20 20 69 66 28 20 73  = 1;.  }.  if( s
2760: 74 6f 70 49 64 78 3e 3d 30 20 29 7b 0a 20 20 20  topIdx>=0 ){.   
2770: 20 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73   pIdxInfo->aCons
2780: 74 72 61 69 6e 74 55 73 61 67 65 5b 73 74 6f 70  traintUsage[stop
2790: 49 64 78 5d 2e 61 72 67 76 49 6e 64 65 78 20 3d  Idx].argvIndex =
27a0: 20 2b 2b 6e 41 72 67 3b 0a 20 20 20 20 70 49 64   ++nArg;.    pId
27b0: 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69  xInfo->aConstrai
27c0: 6e 74 55 73 61 67 65 5b 73 74 6f 70 49 64 78 5d  ntUsage[stopIdx]
27d0: 2e 6f 6d 69 74 20 3d 20 31 3b 0a 20 20 7d 0a 20  .omit = 1;.  }. 
27e0: 20 69 66 28 20 73 74 65 70 49 64 78 3e 3d 30 20   if( stepIdx>=0 
27f0: 29 7b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d  ){.    pIdxInfo-
2800: 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67  >aConstraintUsag
2810: 65 5b 73 74 65 70 49 64 78 5d 2e 61 72 67 76 49  e[stepIdx].argvI
2820: 6e 64 65 78 20 3d 20 2b 2b 6e 41 72 67 3b 0a 20  ndex = ++nArg;. 
2830: 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f     pIdxInfo->aCo
2840: 6e 73 74 72 61 69 6e 74 55 73 61 67 65 5b 73 74  nstraintUsage[st
2850: 65 70 49 64 78 5d 2e 6f 6d 69 74 20 3d 20 31 3b  epIdx].omit = 1;
2860: 0a 20 20 7d 0a 20 20 69 66 28 20 28 69 64 78 4e  .  }.  if( (idxN
2870: 75 6d 20 26 20 33 29 3d 3d 33 20 29 7b 0a 20 20  um & 3)==3 ){.  
2880: 20 20 2f 2a 20 42 6f 74 68 20 73 74 61 72 74 3d    /* Both start=
2890: 20 61 6e 64 20 73 74 6f 70 3d 20 62 6f 75 6e 64   and stop= bound
28a0: 61 72 69 65 73 20 61 72 65 20 61 76 61 69 6c 61  aries are availa
28b0: 62 6c 65 2e 20 20 54 68 69 73 20 69 73 20 74 68  ble.  This is th
28c0: 65 20 0a 20 20 20 20 2a 2a 20 74 68 65 20 70 72  e .    ** the pr
28d0: 65 66 65 72 72 65 64 20 63 61 73 65 20 2a 2f 0a  eferred case */.
28e0: 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73      pIdxInfo->es
28f0: 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 28 64  timatedCost = (d
2900: 6f 75 62 6c 65 29 31 3b 0a 20 20 20 20 70 49 64  ouble)1;.    pId
2910: 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64  xInfo->estimated
2920: 52 6f 77 73 20 3d 20 31 30 30 30 3b 0a 20 20 20  Rows = 1000;.   
2930: 20 69 66 28 20 70 49 64 78 49 6e 66 6f 2d 3e 6e   if( pIdxInfo->n
2940: 4f 72 64 65 72 42 79 3d 3d 31 20 29 7b 0a 20 20  OrderBy==1 ){.  
2950: 20 20 20 20 69 66 28 20 70 49 64 78 49 6e 66 6f      if( pIdxInfo
2960: 2d 3e 61 4f 72 64 65 72 42 79 5b 30 5d 2e 64 65  ->aOrderBy[0].de
2970: 73 63 20 29 20 69 64 78 4e 75 6d 20 7c 3d 20 38  sc ) idxNum |= 8
2980: 3b 0a 20 20 20 20 20 20 70 49 64 78 49 6e 66 6f  ;.      pIdxInfo
2990: 2d 3e 6f 72 64 65 72 42 79 43 6f 6e 73 75 6d 65  ->orderByConsume
29a0: 64 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d  d = 1;.    }.  }
29b0: 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 49 66 20  else{.    /* If 
29c0: 65 69 74 68 65 72 20 62 6f 75 6e 64 61 72 79 20  either boundary 
29d0: 69 73 20 6d 69 73 73 69 6e 67 2c 20 77 65 20 68  is missing, we h
29e0: 61 76 65 20 74 6f 20 67 65 6e 65 72 61 74 65 20  ave to generate 
29f0: 61 20 68 75 67 65 20 73 70 61 6e 0a 20 20 20 20  a huge span.    
2a00: 2a 2a 20 6f 66 20 6e 75 6d 62 65 72 73 2e 20 20  ** of numbers.  
2a10: 4d 61 6b 65 20 74 68 69 73 20 63 61 73 65 20 76  Make this case v
2a20: 65 72 79 20 65 78 70 65 6e 73 69 76 65 20 73 6f  ery expensive so
2a30: 20 74 68 61 74 20 74 68 65 20 71 75 65 72 79 0a   that the query.
2a40: 20 20 20 20 2a 2a 20 70 6c 61 6e 6e 65 72 20 77      ** planner w
2a50: 69 6c 6c 20 77 6f 72 6b 20 68 61 72 64 20 74 6f  ill work hard to
2a60: 20 61 76 6f 69 64 20 69 74 2e 20 2a 2f 0a 20 20   avoid it. */.  
2a70: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69    pIdxInfo->esti
2a80: 6d 61 74 65 64 43 6f 73 74 20 3d 20 28 64 6f 75  matedCost = (dou
2a90: 62 6c 65 29 32 31 34 37 34 38 33 36 34 37 3b 0a  ble)2147483647;.
2aa0: 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73      pIdxInfo->es
2ab0: 74 69 6d 61 74 65 64 52 6f 77 73 20 3d 20 32 31  timatedRows = 21
2ac0: 34 37 34 38 33 36 34 37 3b 0a 20 20 7d 0a 20 20  47483647;.  }.  
2ad0: 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d  pIdxInfo->idxNum
2ae0: 20 3d 20 69 64 78 4e 75 6d 3b 0a 20 20 72 65 74   = idxNum;.  ret
2af0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
2b00: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 6f 6c  ../*.** This fol
2b10: 6c 6f 77 69 6e 67 20 73 74 72 75 63 74 75 72 65  lowing structure
2b20: 20 64 65 66 69 6e 65 73 20 61 6c 6c 20 74 68 65   defines all the
2b30: 20 6d 65 74 68 6f 64 73 20 66 6f 72 20 74 68 65   methods for the
2b40: 20 0a 2a 2a 20 67 65 6e 65 72 61 74 65 5f 73 65   .** generate_se
2b50: 72 69 65 73 20 76 69 72 74 75 61 6c 20 74 61 62  ries virtual tab
2b60: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71  le..*/.static sq
2b70: 6c 69 74 65 33 5f 6d 6f 64 75 6c 65 20 73 65 72  lite3_module ser
2b80: 69 65 73 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20 20  iesModule = {.  
2b90: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
2ba0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56             /* iV
2bb0: 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 30 2c 20 20  ersion */.  0,  
2bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2bd0: 20 20 20 20 20 20 20 2f 2a 20 78 43 72 65 61 74         /* xCreat
2be0: 65 20 2a 2f 0a 20 20 73 65 72 69 65 73 43 6f 6e  e */.  seriesCon
2bf0: 6e 65 63 74 2c 20 20 20 20 20 20 20 20 20 20 20  nect,           
2c00: 20 20 2f 2a 20 78 43 6f 6e 6e 65 63 74 20 2a 2f    /* xConnect */
2c10: 0a 20 20 73 65 72 69 65 73 42 65 73 74 49 6e 64  .  seriesBestInd
2c20: 65 78 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ex,           /*
2c30: 20 78 42 65 73 74 49 6e 64 65 78 20 2a 2f 0a 20   xBestIndex */. 
2c40: 20 73 65 72 69 65 73 44 69 73 63 6f 6e 6e 65 63   seriesDisconnec
2c50: 74 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78  t,          /* x
2c60: 44 69 73 63 6f 6e 6e 65 63 74 20 2a 2f 0a 20 20  Disconnect */.  
2c70: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
2c80: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44             /* xD
2c90: 65 73 74 72 6f 79 20 2a 2f 0a 20 20 73 65 72 69  estroy */.  seri
2ca0: 65 73 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20  esOpen,         
2cb0: 20 20 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e 20         /* xOpen 
2cc0: 2d 20 6f 70 65 6e 20 61 20 63 75 72 73 6f 72 20  - open a cursor 
2cd0: 2a 2f 0a 20 20 73 65 72 69 65 73 43 6c 6f 73 65  */.  seriesClose
2ce0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
2cf0: 2f 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f 73  /* xClose - clos
2d00: 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20  e a cursor */.  
2d10: 73 65 72 69 65 73 46 69 6c 74 65 72 2c 20 20 20  seriesFilter,   
2d20: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46             /* xF
2d30: 69 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67 75 72  ilter - configur
2d40: 65 20 73 63 61 6e 20 63 6f 6e 73 74 72 61 69 6e  e scan constrain
2d50: 74 73 20 2a 2f 0a 20 20 73 65 72 69 65 73 4e 65  ts */.  seriesNe
2d60: 78 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  xt,             
2d70: 20 20 20 2f 2a 20 78 4e 65 78 74 20 2d 20 61 64     /* xNext - ad
2d80: 76 61 6e 63 65 20 61 20 63 75 72 73 6f 72 20 2a  vance a cursor *
2d90: 2f 0a 20 20 73 65 72 69 65 73 45 6f 66 2c 20 20  /.  seriesEof,  
2da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2db0: 2a 20 78 45 6f 66 20 2d 20 63 68 65 63 6b 20 66  * xEof - check f
2dc0: 6f 72 20 65 6e 64 20 6f 66 20 73 63 61 6e 20 2a  or end of scan *
2dd0: 2f 0a 20 20 73 65 72 69 65 73 43 6f 6c 75 6d 6e  /.  seriesColumn
2de0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
2df0: 2a 20 78 43 6f 6c 75 6d 6e 20 2d 20 72 65 61 64  * xColumn - read
2e00: 20 64 61 74 61 20 2a 2f 0a 20 20 73 65 72 69 65   data */.  serie
2e10: 73 52 6f 77 69 64 2c 20 20 20 20 20 20 20 20 20  sRowid,         
2e20: 20 20 20 20 20 20 2f 2a 20 78 52 6f 77 69 64 20        /* xRowid 
2e30: 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a 20  - read data */. 
2e40: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
2e50: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
2e60: 55 70 64 61 74 65 20 2a 2f 0a 20 20 30 2c 20 20  Update */.  0,  
2e70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2e80: 20 20 20 20 20 20 20 2f 2a 20 78 42 65 67 69 6e         /* xBegin
2e90: 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20   */.  0,        
2ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2eb0: 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20 20 30   /* xSync */.  0
2ec0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
2ed0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f            /* xCo
2ee0: 6d 6d 69 74 20 2a 2f 0a 20 20 30 2c 20 20 20 20  mmit */.  0,    
2ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2f00: 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63       /* xRollbac
2f10: 6b 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20  k */.  0,       
2f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2f30: 20 20 2f 2a 20 78 46 69 6e 64 4d 65 74 68 6f 64    /* xFindMethod
2f40: 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20   */.  0,        
2f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2f60: 20 2f 2a 20 78 52 65 6e 61 6d 65 20 2a 2f 0a 7d   /* xRename */.}
2f70: 3b 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c  ;..#endif /* SQL
2f80: 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c  ITE_OMIT_VIRTUAL
2f90: 54 41 42 4c 45 20 2a 2f 0a 0a 23 69 66 64 65 66  TABLE */..#ifdef
2fa0: 20 5f 57 49 4e 33 32 0a 5f 5f 64 65 63 6c 73 70   _WIN32.__declsp
2fb0: 65 63 28 64 6c 6c 65 78 70 6f 72 74 29 0a 23 65  ec(dllexport).#e
2fc0: 6e 64 69 66 0a 69 6e 74 20 73 71 6c 69 74 65 33  ndif.int sqlite3
2fd0: 5f 73 65 72 69 65 73 5f 69 6e 69 74 28 0a 20 20  _series_init(.  
2fe0: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 0a 20 20  sqlite3 *db, .  
2ff0: 63 68 61 72 20 2a 2a 70 7a 45 72 72 4d 73 67 2c  char **pzErrMsg,
3000: 20 0a 20 20 63 6f 6e 73 74 20 73 71 6c 69 74 65   .  const sqlite
3010: 33 5f 61 70 69 5f 72 6f 75 74 69 6e 65 73 20 2a  3_api_routines *
3020: 70 41 70 69 0a 29 7b 0a 20 20 69 6e 74 20 72 63  pApi.){.  int rc
3030: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
3040: 53 51 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f 4e  SQLITE_EXTENSION
3050: 5f 49 4e 49 54 32 28 70 41 70 69 29 3b 0a 23 69  _INIT2(pApi);.#i
3060: 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49  fndef SQLITE_OMI
3070: 54 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 0a 20  T_VIRTUALTABLE. 
3080: 20 69 66 28 20 73 71 6c 69 74 65 33 5f 6c 69 62   if( sqlite3_lib
3090: 76 65 72 73 69 6f 6e 5f 6e 75 6d 62 65 72 28 29  version_number()
30a0: 3c 33 30 30 38 30 31 32 20 29 7b 0a 20 20 20 20  <3008012 ){.    
30b0: 2a 70 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c 69  *pzErrMsg = sqli
30c0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20 20 20  te3_mprintf(.   
30d0: 20 20 20 20 20 22 67 65 6e 65 72 61 74 65 5f 73       "generate_s
30e0: 65 72 69 65 73 28 29 20 72 65 71 75 69 72 65 73  eries() requires
30f0: 20 53 51 4c 69 74 65 20 33 2e 38 2e 31 32 20 6f   SQLite 3.8.12 o
3100: 72 20 6c 61 74 65 72 22 29 3b 0a 20 20 20 20 72  r later");.    r
3110: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52  eturn SQLITE_ERR
3120: 4f 52 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73  OR;.  }.  rc = s
3130: 71 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f  qlite3_create_mo
3140: 64 75 6c 65 28 64 62 2c 20 22 67 65 6e 65 72 61  dule(db, "genera
3150: 74 65 5f 73 65 72 69 65 73 22 2c 20 26 73 65 72  te_series", &ser
3160: 69 65 73 4d 6f 64 75 6c 65 2c 20 30 29 3b 0a 23  iesModule, 0);.#
3170: 65 6e 64 69 66 0a 20 20 72 65 74 75 72 6e 20 72  endif.  return r
3180: 63 3b 0a 7d 0a                                   c;.}.