/ Hex Artifact Content
Login

Artifact de73c00aefc4747ad59b5105cf38bbff0667922e:


0000: 2f 2a 0a 2a 2a 20 32 30 30 34 20 4e 6f 76 65 6d  /*.** 2004 Novem
0010: 62 65 72 20 32 31 0a 2a 2a 0a 2a 2a 20 54 68 65  ber 21.**.** The
0020: 20 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d   author disclaim
0030: 73 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74  s copyright to t
0040: 68 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e  his source code.
0050: 20 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a    In place of.**
0060: 20 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c   a legal notice,
0070: 20 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73   here is a bless
0080: 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61  ing:.**.**    Ma
0090: 79 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e  y you do good an
00a0: 64 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20  d not evil..**  
00b0: 20 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66    May you find f
00c0: 6f 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79  orgiveness for y
00d0: 6f 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67  ourself and forg
00e0: 69 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20  ive others..**  
00f0: 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20    May you share 
0100: 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61  freely, never ta
0110: 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79  king more than y
0120: 6f 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a  ou give..**.****
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: 2a 2a 2a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69  *****.** This fi
0180: 6c 65 20 63 6f 6e 74 61 69 6e 73 20 63 6f 64 65  le contains code
0190: 20 75 73 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65   used to impleme
01a0: 6e 74 20 74 68 65 20 44 45 43 4c 41 52 45 2e 2e  nt the DECLARE..
01b0: 2e 43 55 52 53 4f 52 20 73 79 6e 74 61 78 0a 2a  .CURSOR syntax.*
01c0: 2a 20 6f 66 20 53 51 4c 20 61 6e 64 20 72 65 6c  * of SQL and rel
01d0: 61 74 65 64 20 70 72 6f 63 65 73 73 69 6e 67 2e  ated processing.
01e0: 0a 2a 2a 0a 2a 2a 20 44 6f 20 6e 6f 74 20 63 6f  .**.** Do not co
01f0: 6e 66 75 73 65 20 53 51 4c 20 63 75 72 73 6f 72  nfuse SQL cursor
0200: 73 20 61 6e 64 20 42 2d 74 72 65 65 20 63 75 72  s and B-tree cur
0210: 73 6f 72 73 2e 20 20 41 6e 20 53 51 4c 20 63 75  sors.  An SQL cu
0220: 72 73 6f 72 20 28 61 73 0a 2a 2a 20 69 6d 70 6c  rsor (as.** impl
0230: 65 6d 65 6e 74 65 64 20 62 79 20 74 68 69 73 20  emented by this 
0240: 66 69 6c 65 29 20 69 73 20 61 20 75 73 65 72 2d  file) is a user-
0250: 76 69 73 69 62 6c 65 20 63 75 72 73 6f 72 20 74  visible cursor t
0260: 68 61 74 20 69 73 20 63 72 65 61 74 65 64 0a 2a  hat is created.*
0270: 2a 20 75 73 69 6e 67 20 74 68 65 20 44 45 43 4c  * using the DECL
0280: 41 52 45 2e 2e 2e 43 55 52 53 4f 52 20 63 6f 6d  ARE...CURSOR com
0290: 6d 61 6e 64 20 61 6e 64 20 64 65 6c 65 74 65 64  mand and deleted
02a0: 20 75 73 69 6e 67 20 43 4c 4f 53 45 2e 20 20 41   using CLOSE.  A
02b0: 0a 2a 2a 20 42 2d 74 72 65 65 20 63 75 72 73 6f  .** B-tree curso
02c0: 72 20 69 73 20 61 6e 20 61 62 73 74 72 61 63 74  r is an abstract
02d0: 69 6f 6e 20 6f 66 20 74 68 65 20 62 2d 74 72 65  ion of the b-tre
02e0: 65 20 6c 61 79 65 72 2e 20 20 53 65 65 20 74 68  e layer.  See th
02f0: 65 20 62 74 72 65 65 2e 63 0a 2a 2a 20 6d 6f 64  e btree.c.** mod
0300: 75 6c 65 20 66 6f 72 20 61 64 64 69 74 69 6f 6e  ule for addition
0310: 61 6c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e 20  al information. 
0320: 20 54 68 65 72 65 20 69 73 20 61 6c 73 6f 20 61   There is also a
0330: 20 56 44 42 45 2d 63 75 72 73 6f 72 20 74 68 61   VDBE-cursor tha
0340: 74 0a 2a 2a 20 69 73 20 75 73 65 64 20 62 79 20  t.** is used by 
0350: 74 68 65 20 56 44 42 45 20 6d 6f 64 75 6c 65 2e  the VDBE module.
0360: 20 20 45 76 65 6e 20 74 68 6f 75 67 68 20 61 6c    Even though al
0370: 6c 20 74 68 65 73 65 20 6f 62 6a 65 63 74 73 20  l these objects 
0380: 61 72 65 20 63 61 6c 6c 65 64 0a 2a 2a 20 63 75  are called.** cu
0390: 72 73 6f 72 73 2c 20 74 68 65 79 20 61 72 65 20  rsors, they are 
03a0: 72 65 61 6c 6c 79 20 76 65 72 79 20 64 69 66 66  really very diff
03b0: 65 72 65 6e 74 20 74 68 69 6e 67 73 2e 20 20 49  erent things.  I
03c0: 74 20 69 73 20 77 6f 72 74 68 20 79 6f 75 72 20  t is worth your 
03d0: 77 68 69 6c 65 0a 2a 2a 20 74 6f 20 66 75 6c 6c  while.** to full
03e0: 79 20 75 6e 64 65 72 73 74 61 6e 64 20 74 68 65  y understand the
03f0: 20 64 69 66 66 65 72 65 6e 63 65 2e 0a 2a 2a 0a   difference..**.
0400: 2a 2a 20 40 28 23 29 20 24 49 64 3a 20 63 75 72  ** @(#) $Id: cur
0410: 73 6f 72 2e 63 2c 76 20 31 2e 33 20 32 30 30 35  sor.c,v 1.3 2005
0420: 2f 30 31 2f 32 30 20 30 32 3a 31 34 3a 33 31 20  /01/20 02:14:31 
0430: 64 72 68 20 45 78 70 20 24 0a 2a 2f 0a 23 69 6e  drh Exp $.*/.#in
0440: 63 6c 75 64 65 20 22 73 71 6c 69 74 65 49 6e 74  clude "sqliteInt
0450: 2e 68 22 0a 23 69 66 6e 64 65 66 20 53 51 4c 49  .h".#ifndef SQLI
0460: 54 45 5f 4f 4d 49 54 5f 43 55 52 53 4f 52 0a 23  TE_OMIT_CURSOR.#
0470: 69 6e 63 6c 75 64 65 20 22 76 64 62 65 49 6e 74  include "vdbeInt
0480: 2e 68 22 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c 65 74  .h"../*.** Delet
0490: 65 20 61 20 63 75 72 73 6f 72 20 6f 62 6a 65 63  e a cursor objec
04a0: 74 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  t..*/.void sqlit
04b0: 65 33 43 75 72 73 6f 72 44 65 6c 65 74 65 28 53  e3CursorDelete(S
04c0: 71 6c 43 75 72 73 6f 72 20 2a 70 29 7b 0a 20 20  qlCursor *p){.  
04d0: 69 66 28 20 70 20 29 7b 0a 20 20 20 20 69 6e 74  if( p ){.    int
04e0: 20 69 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 53   i;.    sqlite3S
04f0: 65 6c 65 63 74 44 65 6c 65 74 65 28 70 2d 3e 70  electDelete(p->p
0500: 53 65 6c 65 63 74 29 3b 0a 20 20 20 20 66 6f 72  Select);.    for
0510: 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 50 74 72 3b  (i=0; i<p->nPtr;
0520: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73 71 6c   i++){.      sql
0530: 69 74 65 33 56 64 62 65 4d 65 6d 52 65 6c 65 61  ite3VdbeMemRelea
0540: 73 65 28 26 70 2d 3e 61 50 74 72 5b 69 5d 29 3b  se(&p->aPtr[i]);
0550: 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74  .    }.    sqlit
0560: 65 46 72 65 65 28 70 2d 3e 61 50 74 72 29 3b 0a  eFree(p->aPtr);.
0570: 20 20 20 20 73 71 6c 69 74 65 46 72 65 65 28 70      sqliteFree(p
0580: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  );.  }.}../*.** 
0590: 4c 6f 6f 6b 20 75 70 20 61 20 63 75 72 73 6f 72  Look up a cursor
05a0: 20 62 79 20 6e 61 6d 65 2e 20 20 52 65 74 75 72   by name.  Retur
05b0: 6e 20 4e 55 4c 4c 20 69 66 20 6e 6f 74 20 66 6f  n NULL if not fo
05c0: 75 6e 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 53  und..*/.static S
05d0: 71 6c 43 75 72 73 6f 72 20 2a 66 69 6e 64 43 75  qlCursor *findCu
05e0: 72 73 6f 72 28 73 71 6c 69 74 65 33 20 2a 64 62  rsor(sqlite3 *db
05f0: 2c 20 54 6f 6b 65 6e 20 2a 70 4e 61 6d 65 29 7b  , Token *pName){
0600: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 53 71 6c 43  .  int i;.  SqlC
0610: 75 72 73 6f 72 20 2a 70 3b 0a 20 20 66 6f 72 28  ursor *p;.  for(
0620: 69 3d 30 3b 20 69 3c 64 62 2d 3e 6e 53 71 6c 43  i=0; i<db->nSqlC
0630: 75 72 73 6f 72 3b 20 69 2b 2b 29 7b 0a 20 20 20  ursor; i++){.   
0640: 20 70 20 3d 20 64 62 2d 3e 61 70 53 71 6c 43 75   p = db->apSqlCu
0650: 72 73 6f 72 5b 69 5d 3b 0a 20 20 20 20 69 66 28  rsor[i];.    if(
0660: 20 70 20 26 26 20 73 71 6c 69 74 65 33 53 74 72   p && sqlite3Str
0670: 4e 49 43 6d 70 28 70 2d 3e 7a 4e 61 6d 65 2c 20  NICmp(p->zName, 
0680: 70 4e 61 6d 65 2d 3e 7a 2c 20 70 4e 61 6d 65 2d  pName->z, pName-
0690: 3e 6e 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  >n)==0 ){.      
06a0: 72 65 74 75 72 6e 20 70 3b 0a 20 20 20 20 7d 0a  return p;.    }.
06b0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a    }.  return 0;.
06c0: 7d 20 20 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 70  }  ../*.** The p
06d0: 61 72 73 65 72 20 63 61 6c 6c 73 20 74 68 69 73  arser calls this
06e0: 20 72 6f 75 74 69 6e 65 20 69 6e 20 6f 72 64 65   routine in orde
06f0: 72 20 74 6f 20 63 72 65 61 74 65 20 61 20 6e 65  r to create a ne
0700: 77 20 63 75 72 73 6f 72 2e 0a 2a 2a 20 54 68 65  w cursor..** The
0710: 20 61 72 67 75 6d 65 6e 74 73 20 61 72 65 20 74   arguments are t
0720: 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 6e  he name of the n
0730: 65 77 20 63 75 72 73 6f 72 20 61 6e 64 20 74 68  ew cursor and th
0740: 65 20 53 45 4c 45 43 54 20 73 74 61 74 65 6d 65  e SELECT stateme
0750: 6e 74 0a 2a 2a 20 74 68 61 74 20 74 68 65 20 6e  nt.** that the n
0760: 65 77 20 63 75 72 73 6f 72 20 77 69 6c 6c 20 61  ew cursor will a
0770: 63 63 65 73 73 2e 0a 2a 2f 0a 76 6f 69 64 20 73  ccess..*/.void s
0780: 71 6c 69 74 65 33 43 75 72 73 6f 72 43 72 65 61  qlite3CursorCrea
0790: 74 65 28 50 61 72 73 65 20 2a 70 50 61 72 73 65  te(Parse *pParse
07a0: 2c 20 54 6f 6b 65 6e 20 2a 70 4e 61 6d 65 2c 20  , Token *pName, 
07b0: 53 65 6c 65 63 74 20 2a 70 53 65 6c 65 63 74 29  Select *pSelect)
07c0: 7b 0a 20 20 53 71 6c 43 75 72 73 6f 72 20 2a 70  {.  SqlCursor *p
07d0: 4e 65 77 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a  New;.  sqlite3 *
07e0: 64 62 20 3d 20 70 50 61 72 73 65 2d 3e 64 62 3b  db = pParse->db;
07f0: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 0a 0a 20 20  .  int i;.  ..  
0800: 70 4e 65 77 20 3d 20 66 69 6e 64 43 75 72 73 6f  pNew = findCurso
0810: 72 28 64 62 2c 20 70 4e 61 6d 65 29 3b 0a 20 20  r(db, pName);.  
0820: 69 66 28 20 70 4e 65 77 20 29 7b 0a 20 20 20 20  if( pNew ){.    
0830: 73 71 6c 69 74 65 33 45 72 72 6f 72 4d 73 67 28  sqlite3ErrorMsg(
0840: 70 50 61 72 73 65 2c 20 22 61 6e 6f 74 68 65 72  pParse, "another
0850: 20 63 75 72 73 6f 72 20 6e 61 6d 65 64 20 25 54   cursor named %T
0860: 20 61 6c 72 65 61 64 79 20 65 78 69 73 74 73 22   already exists"
0870: 2c 20 70 4e 61 6d 65 29 3b 0a 20 20 20 20 67 6f  , pName);.    go
0880: 74 6f 20 65 6e 64 5f 63 72 65 61 74 65 5f 63 75  to end_create_cu
0890: 72 73 6f 72 3b 0a 20 20 7d 0a 20 20 69 66 28 20  rsor;.  }.  if( 
08a0: 70 53 65 6c 65 63 74 3d 3d 30 20 29 7b 0a 20 20  pSelect==0 ){.  
08b0: 20 20 2f 2a 20 54 68 69 73 20 63 61 6e 20 6f 6e    /* This can on
08c0: 6c 79 20 68 61 70 70 65 6e 20 64 75 65 20 74 6f  ly happen due to
08d0: 20 61 20 70 72 69 6f 72 20 6d 61 6c 6c 6f 63 20   a prior malloc 
08e0: 66 61 69 6c 75 72 65 20 2a 2f 0a 20 20 20 20 67  failure */.    g
08f0: 6f 74 6f 20 65 6e 64 5f 63 72 65 61 74 65 5f 63  oto end_create_c
0900: 75 72 73 6f 72 3b 0a 20 20 7d 0a 20 20 66 6f 72  ursor;.  }.  for
0910: 28 69 3d 30 3b 20 69 3c 64 62 2d 3e 6e 53 71 6c  (i=0; i<db->nSql
0920: 43 75 72 73 6f 72 3b 20 69 2b 2b 29 7b 0a 20 20  Cursor; i++){.  
0930: 20 20 69 66 28 20 64 62 2d 3e 61 70 53 71 6c 43    if( db->apSqlC
0940: 75 72 73 6f 72 5b 69 5d 3d 3d 30 20 29 20 62 72  ursor[i]==0 ) br
0950: 65 61 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 69  eak;.  }.  if( i
0960: 3e 3d 64 62 2d 3e 6e 53 71 6c 43 75 72 73 6f 72  >=db->nSqlCursor
0970: 20 29 7b 0a 20 20 20 20 64 62 2d 3e 61 70 53 71   ){.    db->apSq
0980: 6c 43 75 72 73 6f 72 20 3d 20 73 71 6c 69 74 65  lCursor = sqlite
0990: 52 65 61 6c 6c 6f 63 28 64 62 2d 3e 61 70 53 71  Realloc(db->apSq
09a0: 6c 43 75 72 73 6f 72 2c 20 28 69 2b 31 29 2a 73  lCursor, (i+1)*s
09b0: 69 7a 65 6f 66 28 70 4e 65 77 29 29 3b 0a 20 20  izeof(pNew));.  
09c0: 20 20 64 62 2d 3e 6e 53 71 6c 43 75 72 73 6f 72    db->nSqlCursor
09d0: 20 3d 20 69 2b 31 3b 0a 20 20 7d 0a 20 20 64 62   = i+1;.  }.  db
09e0: 2d 3e 61 70 53 71 6c 43 75 72 73 6f 72 5b 69 5d  ->apSqlCursor[i]
09f0: 20 3d 20 70 4e 65 77 20 3d 20 73 71 6c 69 74 65   = pNew = sqlite
0a00: 4d 61 6c 6c 6f 63 52 61 77 28 20 73 69 7a 65 6f  MallocRaw( sizeo
0a10: 66 28 2a 70 4e 65 77 29 20 2b 20 70 4e 61 6d 65  f(*pNew) + pName
0a20: 2d 3e 6e 20 2b 20 31 20 29 3b 0a 20 20 69 66 28  ->n + 1 );.  if(
0a30: 20 70 4e 65 77 3d 3d 30 20 29 20 67 6f 74 6f 20   pNew==0 ) goto 
0a40: 65 6e 64 5f 63 72 65 61 74 65 5f 63 75 72 73 6f  end_create_curso
0a50: 72 3b 0a 20 20 70 4e 65 77 2d 3e 69 64 78 20 3d  r;.  pNew->idx =
0a60: 20 69 3b 0a 20 20 70 4e 65 77 2d 3e 7a 4e 61 6d   i;.  pNew->zNam
0a70: 65 20 3d 20 28 63 68 61 72 2a 29 26 70 4e 65 77  e = (char*)&pNew
0a80: 5b 31 5d 3b 0a 20 20 6d 65 6d 63 70 79 28 70 4e  [1];.  memcpy(pN
0a90: 65 77 2d 3e 7a 4e 61 6d 65 2c 20 70 4e 61 6d 65  ew->zName, pName
0aa0: 2d 3e 7a 2c 20 70 4e 61 6d 65 2d 3e 6e 29 3b 0a  ->z, pName->n);.
0ab0: 20 20 70 4e 65 77 2d 3e 7a 4e 61 6d 65 5b 70 4e    pNew->zName[pN
0ac0: 61 6d 65 2d 3e 6e 5d 20 3d 20 30 3b 0a 20 20 70  ame->n] = 0;.  p
0ad0: 4e 65 77 2d 3e 70 53 65 6c 65 63 74 20 3d 20 73  New->pSelect = s
0ae0: 71 6c 69 74 65 33 53 65 6c 65 63 74 44 75 70 28  qlite3SelectDup(
0af0: 70 53 65 6c 65 63 74 29 3b 0a 20 20 70 4e 65 77  pSelect);.  pNew
0b00: 2d 3e 6e 50 74 72 20 3d 20 32 3b 0a 20 20 70 4e  ->nPtr = 2;.  pN
0b10: 65 77 2d 3e 61 50 74 72 20 3d 20 73 71 6c 69 74  ew->aPtr = sqlit
0b20: 65 4d 61 6c 6c 6f 63 28 20 73 69 7a 65 6f 66 28  eMalloc( sizeof(
0b30: 4d 65 6d 29 2a 32 20 29 3b 0a 20 20 66 6f 72 28  Mem)*2 );.  for(
0b40: 69 3d 30 3b 20 69 3c 32 3b 20 69 2b 2b 29 7b 0a  i=0; i<2; i++){.
0b50: 20 20 20 20 70 4e 65 77 2d 3e 61 50 74 72 5b 69      pNew->aPtr[i
0b60: 5d 2e 66 6c 61 67 73 20 3d 20 4d 45 4d 5f 4e 75  ].flags = MEM_Nu
0b70: 6c 6c 3b 0a 20 20 7d 0a 0a 65 6e 64 5f 63 72 65  ll;.  }..end_cre
0b80: 61 74 65 5f 63 75 72 73 6f 72 3a 0a 20 20 73 71  ate_cursor:.  sq
0b90: 6c 69 74 65 33 53 65 6c 65 63 74 44 65 6c 65 74  lite3SelectDelet
0ba0: 65 28 70 53 65 6c 65 63 74 29 3b 0a 7d 0a 0a 2f  e(pSelect);.}../
0bb0: 2a 0a 2a 2a 20 54 68 65 20 70 61 72 73 65 72 20  *.** The parser 
0bc0: 63 61 6c 6c 73 20 74 68 69 73 20 72 6f 75 74 69  calls this routi
0bd0: 6e 65 20 69 6e 20 72 65 73 70 6f 6e 73 65 20 74  ne in response t
0be0: 6f 20 61 20 43 4c 4f 53 45 20 63 6f 6d 6d 61 6e  o a CLOSE comman
0bf0: 64 2e 20 20 44 65 6c 65 74 65 0a 2a 2a 20 74 68  d.  Delete.** th
0c00: 65 20 63 75 72 73 6f 72 20 6e 61 6d 65 64 20 69  e cursor named i
0c10: 6e 20 74 68 65 20 61 72 67 75 6d 65 6e 74 2e 0a  n the argument..
0c20: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 43  */.void sqlite3C
0c30: 75 72 73 6f 72 43 6c 6f 73 65 28 50 61 72 73 65  ursorClose(Parse
0c40: 20 2a 70 50 61 72 73 65 2c 20 54 6f 6b 65 6e 20   *pParse, Token 
0c50: 2a 70 4e 61 6d 65 29 7b 0a 20 20 53 71 6c 43 75  *pName){.  SqlCu
0c60: 72 73 6f 72 20 2a 70 3b 0a 20 20 73 71 6c 69 74  rsor *p;.  sqlit
0c70: 65 33 20 2a 64 62 20 3d 20 70 50 61 72 73 65 2d  e3 *db = pParse-
0c80: 3e 64 62 3b 0a 0a 20 20 70 20 3d 20 66 69 6e 64  >db;..  p = find
0c90: 43 75 72 73 6f 72 28 64 62 2c 20 70 4e 61 6d 65  Cursor(db, pName
0ca0: 29 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20 29 7b  );.  if( p==0 ){
0cb0: 0a 20 20 20 20 73 71 6c 69 74 65 33 45 72 72 6f  .    sqlite3Erro
0cc0: 72 4d 73 67 28 70 50 61 72 73 65 2c 20 22 6e 6f  rMsg(pParse, "no
0cd0: 20 73 75 63 68 20 63 75 72 73 6f 72 3a 20 25 54   such cursor: %T
0ce0: 22 2c 20 70 4e 61 6d 65 29 3b 0a 20 20 20 20 72  ", pName);.    r
0cf0: 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 61 73 73  eturn;.  }.  ass
0d00: 65 72 74 28 20 70 2d 3e 69 64 78 3e 3d 30 20 26  ert( p->idx>=0 &
0d10: 26 20 70 2d 3e 69 64 78 3c 64 62 2d 3e 6e 53 71  & p->idx<db->nSq
0d20: 6c 43 75 72 73 6f 72 20 29 3b 0a 20 20 61 73 73  lCursor );.  ass
0d30: 65 72 74 28 20 64 62 2d 3e 61 70 53 71 6c 43 75  ert( db->apSqlCu
0d40: 72 73 6f 72 5b 70 2d 3e 69 64 78 5d 3d 3d 70 20  rsor[p->idx]==p 
0d50: 29 3b 0a 20 20 64 62 2d 3e 61 70 53 71 6c 43 75  );.  db->apSqlCu
0d60: 72 73 6f 72 5b 70 2d 3e 69 64 78 5d 20 3d 20 30  rsor[p->idx] = 0
0d70: 3b 0a 20 20 73 71 6c 69 74 65 33 43 75 72 73 6f  ;.  sqlite3Curso
0d80: 72 44 65 6c 65 74 65 28 70 29 3b 0a 7d 0a 0a 2f  rDelete(p);.}../
0d90: 2a 0a 2a 2a 20 52 65 76 65 72 73 65 20 74 68 65  *.** Reverse the
0da0: 20 64 69 72 65 63 74 69 6f 6e 20 74 68 65 20 4f   direction the O
0db0: 52 44 45 52 20 42 59 20 63 6c 61 75 73 65 20 6f  RDER BY clause o
0dc0: 6e 20 74 68 65 20 53 45 4c 45 43 54 20 73 74 61  n the SELECT sta
0dd0: 74 65 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69  tement..*/.stati
0de0: 63 20 76 6f 69 64 20 72 65 76 65 72 73 65 53 6f  c void reverseSo
0df0: 72 74 4f 72 64 65 72 28 53 65 6c 65 63 74 20 2a  rtOrder(Select *
0e00: 70 29 7b 0a 20 20 69 66 28 20 70 2d 3e 70 4f 72  p){.  if( p->pOr
0e10: 64 65 72 42 79 3d 3d 30 20 29 7b 0a 20 20 20 20  derBy==0 ){.    
0e20: 2f 2a 20 49 66 20 74 68 65 72 65 20 6e 6f 20 4f  /* If there no O
0e30: 52 44 45 52 20 42 59 20 63 6c 61 75 73 65 2c 20  RDER BY clause, 
0e40: 61 64 64 20 61 20 6e 65 77 20 6f 6e 65 20 74 68  add a new one th
0e50: 61 74 20 69 73 20 22 72 6f 77 69 64 20 44 45 53  at is "rowid DES
0e60: 43 22 20 2a 2f 0a 20 20 20 20 73 74 61 74 69 63  C" */.    static
0e70: 20 63 6f 6e 73 74 20 54 6f 6b 65 6e 20 72 6f 77   const Token row
0e80: 69 64 20 3d 20 7b 20 22 52 4f 57 49 44 22 2c 20  id = { "ROWID", 
0e90: 30 2c 20 35 20 7d 3b 0a 20 20 20 20 45 78 70 72  0, 5 };.    Expr
0ea0: 20 2a 70 45 78 70 72 20 3d 20 73 71 6c 69 74 65   *pExpr = sqlite
0eb0: 33 45 78 70 72 28 54 4b 5f 49 44 2c 20 30 2c 20  3Expr(TK_ID, 0, 
0ec0: 30 2c 20 26 72 6f 77 69 64 29 3b 0a 20 20 20 20  0, &rowid);.    
0ed0: 45 78 70 72 4c 69 73 74 20 2a 70 4c 69 73 74 20  ExprList *pList 
0ee0: 3d 20 73 71 6c 69 74 65 33 45 78 70 72 4c 69 73  = sqlite3ExprLis
0ef0: 74 41 70 70 65 6e 64 28 30 2c 20 70 45 78 70 72  tAppend(0, pExpr
0f00: 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 70 4c  , 0);.    if( pL
0f10: 69 73 74 20 29 20 20 70 4c 69 73 74 2d 3e 61 5b  ist )  pList->a[
0f20: 30 5d 2e 73 6f 72 74 4f 72 64 65 72 20 3d 20 53  0].sortOrder = S
0f30: 51 4c 49 54 45 5f 53 4f 5f 44 45 53 43 3b 0a 20  QLITE_SO_DESC;. 
0f40: 20 20 20 70 2d 3e 70 4f 72 64 65 72 42 79 20 3d     p->pOrderBy =
0f50: 20 70 4c 69 73 74 3b 0a 20 20 7d 65 6c 73 65 7b   pList;.  }else{
0f60: 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20  .    int i;.    
0f70: 45 78 70 72 4c 69 73 74 20 2a 70 4c 69 73 74 20  ExprList *pList 
0f80: 3d 20 70 2d 3e 70 4f 72 64 65 72 42 79 3b 0a 20  = p->pOrderBy;. 
0f90: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 4c     for(i=0; i<pL
0fa0: 69 73 74 2d 3e 6e 45 78 70 72 3b 20 69 2b 2b 29  ist->nExpr; i++)
0fb0: 7b 0a 20 20 20 20 20 20 70 4c 69 73 74 2d 3e 61  {.      pList->a
0fc0: 5b 69 5d 2e 73 6f 72 74 4f 72 64 65 72 20 3d 20  [i].sortOrder = 
0fd0: 21 70 4c 69 73 74 2d 3e 61 5b 69 5d 2e 73 6f 72  !pList->a[i].sor
0fe0: 74 4f 72 64 65 72 3b 0a 20 20 20 20 7d 0a 20 20  tOrder;.    }.  
0ff0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 70  }.}../*.** The p
1000: 61 72 73 65 72 20 63 61 6c 6c 73 20 74 68 69 73  arser calls this
1010: 20 72 6f 75 74 69 6e 65 20 77 68 65 6e 20 69 74   routine when it
1020: 20 73 65 65 73 20 61 20 63 6f 6d 70 6c 65 74 65   sees a complete
1030: 20 46 45 54 43 48 20 73 74 61 74 65 6d 65 6e 74   FETCH statement
1040: 2e 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e  ..** This routin
1050: 65 20 67 65 6e 65 72 61 74 65 73 20 63 6f 64 65  e generates code
1060: 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 74 68   to implement th
1070: 65 20 46 45 54 43 48 2e 0a 2a 2a 0a 2a 2a 20 49  e FETCH..**.** I
1080: 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74  nformation about
1090: 20 74 68 65 20 64 69 72 65 63 74 69 6f 6e 20 6f   the direction o
10a0: 66 20 74 68 65 20 46 45 54 43 48 20 68 61 73 20  f the FETCH has 
10b0: 61 6c 72 65 61 64 79 20 62 65 65 6e 20 69 6e 73  already been ins
10c0: 65 72 74 65 64 0a 2a 2a 20 69 6e 74 6f 20 74 68  erted.** into th
10d0: 65 20 70 50 61 72 73 65 20 73 74 72 75 63 74 75  e pParse structu
10e0: 72 65 20 62 79 20 70 61 72 73 65 72 20 72 75 6c  re by parser rul
10f0: 65 73 2e 20 20 54 68 65 20 61 72 67 75 6d 65 6e  es.  The argumen
1100: 74 73 20 73 70 65 63 69 66 79 20 74 68 65 0a 2a  ts specify the.*
1110: 2a 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 63 75  * name of the cu
1120: 72 73 6f 72 20 66 72 6f 6d 20 77 68 69 63 68 20  rsor from which 
1130: 77 65 20 61 72 65 20 66 65 74 63 68 69 6e 67 20  we are fetching 
1140: 61 6e 64 20 74 68 65 20 6f 70 74 69 6f 6e 61 6c  and the optional
1150: 20 49 4e 54 4f 0a 2a 2a 20 63 6c 61 75 73 65 2e   INTO.** clause.
1160: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
1170: 46 65 74 63 68 28 50 61 72 73 65 20 2a 70 50 61  Fetch(Parse *pPa
1180: 72 73 65 2c 20 54 6f 6b 65 6e 20 2a 70 4e 61 6d  rse, Token *pNam
1190: 65 2c 20 49 64 4c 69 73 74 20 2a 70 49 6e 74 6f  e, IdList *pInto
11a0: 29 7b 0a 20 20 53 71 6c 43 75 72 73 6f 72 20 2a  ){.  SqlCursor *
11b0: 70 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  p;.  sqlite3 *db
11c0: 20 3d 20 70 50 61 72 73 65 2d 3e 64 62 3b 0a 20   = pParse->db;. 
11d0: 20 53 65 6c 65 63 74 20 2a 70 43 6f 70 79 3b 0a   Select *pCopy;.
11e0: 20 20 46 65 74 63 68 20 73 46 65 74 63 68 3b 0a    Fetch sFetch;.
11f0: 0a 20 20 70 20 3d 20 66 69 6e 64 43 75 72 73 6f  .  p = findCurso
1200: 72 28 64 62 2c 20 70 4e 61 6d 65 29 3b 0a 20 20  r(db, pName);.  
1210: 69 66 28 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20  if( p==0 ){.    
1220: 73 71 6c 69 74 65 33 45 72 72 6f 72 4d 73 67 28  sqlite3ErrorMsg(
1230: 70 50 61 72 73 65 2c 20 22 6e 6f 20 73 75 63 68  pParse, "no such
1240: 20 63 75 72 73 6f 72 3a 20 25 54 22 2c 20 70 4e   cursor: %T", pN
1250: 61 6d 65 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  ame);.    return
1260: 3b 0a 20 20 7d 0a 20 20 73 46 65 74 63 68 2e 70  ;.  }.  sFetch.p
1270: 43 75 72 73 6f 72 20 3d 20 70 3b 0a 20 20 70 43  Cursor = p;.  pC
1280: 6f 70 79 20 3d 20 73 71 6c 69 74 65 33 53 65 6c  opy = sqlite3Sel
1290: 65 63 74 44 75 70 28 70 2d 3e 70 53 65 6c 65 63  ectDup(p->pSelec
12a0: 74 29 3b 0a 20 20 70 43 6f 70 79 2d 3e 70 46 65  t);.  pCopy->pFe
12b0: 74 63 68 20 3d 20 26 73 46 65 74 63 68 3b 0a 20  tch = &sFetch;. 
12c0: 20 73 77 69 74 63 68 28 20 70 50 61 72 73 65 2d   switch( pParse-
12d0: 3e 66 65 74 63 68 44 69 72 20 29 7b 0a 20 20 20  >fetchDir ){.   
12e0: 20 63 61 73 65 20 54 4b 5f 46 49 52 53 54 3a 20   case TK_FIRST: 
12f0: 7b 0a 20 20 20 20 20 20 73 46 65 74 63 68 2e 69  {.      sFetch.i
1300: 73 42 61 63 6b 77 61 72 64 73 20 3d 20 30 3b 0a  sBackwards = 0;.
1310: 20 20 20 20 20 20 73 46 65 74 63 68 2e 64 6f 52        sFetch.doR
1320: 65 77 69 6e 64 20 3d 20 31 3b 0a 20 20 20 20 20  ewind = 1;.     
1330: 20 70 43 6f 70 79 2d 3e 6e 4c 69 6d 69 74 20 3d   pCopy->nLimit =
1340: 20 70 50 61 72 73 65 2d 3e 64 69 72 41 72 67 31   pParse->dirArg1
1350: 3b 0a 20 20 20 20 20 20 70 43 6f 70 79 2d 3e 6e  ;.      pCopy->n
1360: 4f 66 66 73 65 74 20 3d 20 30 3b 0a 20 20 20 20  Offset = 0;.    
1370: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20    break;.    }. 
1380: 20 20 20 63 61 73 65 20 54 4b 5f 4c 41 53 54 3a     case TK_LAST:
1390: 20 7b 0a 20 20 20 20 20 20 72 65 76 65 72 73 65   {.      reverse
13a0: 53 6f 72 74 4f 72 64 65 72 28 70 43 6f 70 79 29  SortOrder(pCopy)
13b0: 3b 0a 20 20 20 20 20 20 73 46 65 74 63 68 2e 69  ;.      sFetch.i
13c0: 73 42 61 63 6b 77 61 72 64 73 20 3d 20 31 3b 0a  sBackwards = 1;.
13d0: 20 20 20 20 20 20 73 46 65 74 63 68 2e 64 6f 52        sFetch.doR
13e0: 65 77 69 6e 64 20 3d 20 31 3b 0a 20 20 20 20 20  ewind = 1;.     
13f0: 20 70 43 6f 70 79 2d 3e 6e 4c 69 6d 69 74 20 3d   pCopy->nLimit =
1400: 20 70 50 61 72 73 65 2d 3e 64 69 72 41 72 67 31   pParse->dirArg1
1410: 3b 0a 20 20 20 20 20 20 70 43 6f 70 79 2d 3e 6e  ;.      pCopy->n
1420: 4f 66 66 73 65 74 20 3d 20 30 3b 0a 20 20 20 20  Offset = 0;.    
1430: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20    break;.    }. 
1440: 20 20 20 63 61 73 65 20 54 4b 5f 4e 45 58 54 3a     case TK_NEXT:
1450: 20 7b 0a 20 20 20 20 20 20 73 46 65 74 63 68 2e   {.      sFetch.
1460: 69 73 42 61 63 6b 77 61 72 64 73 20 3d 20 30 3b  isBackwards = 0;
1470: 0a 20 20 20 20 20 20 73 46 65 74 63 68 2e 64 6f  .      sFetch.do
1480: 52 65 77 69 6e 64 20 3d 20 30 3b 0a 20 20 20 20  Rewind = 0;.    
1490: 20 20 70 43 6f 70 79 2d 3e 6e 4c 69 6d 69 74 20    pCopy->nLimit 
14a0: 3d 20 70 50 61 72 73 65 2d 3e 64 69 72 41 72 67  = pParse->dirArg
14b0: 31 3b 0a 20 20 20 20 20 20 70 43 6f 70 79 2d 3e  1;.      pCopy->
14c0: 6e 4f 66 66 73 65 74 20 3d 20 30 3b 0a 20 20 20  nOffset = 0;.   
14d0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
14e0: 20 20 20 20 63 61 73 65 20 54 4b 5f 50 52 49 4f      case TK_PRIO
14f0: 52 3a 20 7b 0a 20 20 20 20 20 20 72 65 76 65 72  R: {.      rever
1500: 73 65 53 6f 72 74 4f 72 64 65 72 28 70 43 6f 70  seSortOrder(pCop
1510: 79 29 3b 0a 20 20 20 20 20 20 73 46 65 74 63 68  y);.      sFetch
1520: 2e 69 73 42 61 63 6b 77 61 72 64 73 20 3d 20 31  .isBackwards = 1
1530: 3b 0a 20 20 20 20 20 20 73 46 65 74 63 68 2e 64  ;.      sFetch.d
1540: 6f 52 65 77 69 6e 64 20 3d 20 30 3b 0a 20 20 20  oRewind = 0;.   
1550: 20 20 20 70 43 6f 70 79 2d 3e 6e 4c 69 6d 69 74     pCopy->nLimit
1560: 20 3d 20 70 50 61 72 73 65 2d 3e 64 69 72 41 72   = pParse->dirAr
1570: 67 31 3b 0a 20 20 20 20 20 20 70 43 6f 70 79 2d  g1;.      pCopy-
1580: 3e 6e 4f 66 66 73 65 74 20 3d 20 30 3b 0a 20 20  >nOffset = 0;.  
1590: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d      break;.    }
15a0: 0a 20 20 20 20 63 61 73 65 20 54 4b 5f 41 42 53  .    case TK_ABS
15b0: 4f 4c 55 54 45 3a 20 7b 0a 20 20 20 20 20 20 73  OLUTE: {.      s
15c0: 46 65 74 63 68 2e 69 73 42 61 63 6b 77 61 72 64  Fetch.isBackward
15d0: 73 20 3d 20 30 3b 0a 20 20 20 20 20 20 73 46 65  s = 0;.      sFe
15e0: 74 63 68 2e 64 6f 52 65 77 69 6e 64 20 3d 20 31  tch.doRewind = 1
15f0: 3b 0a 20 20 20 20 20 20 70 43 6f 70 79 2d 3e 6e  ;.      pCopy->n
1600: 4c 69 6d 69 74 20 3d 20 70 50 61 72 73 65 2d 3e  Limit = pParse->
1610: 64 69 72 41 72 67 31 3b 0a 20 20 20 20 20 20 70  dirArg1;.      p
1620: 43 6f 70 79 2d 3e 6e 4f 66 66 73 65 74 20 3d 20  Copy->nOffset = 
1630: 70 50 61 72 73 65 2d 3e 64 69 72 41 72 67 32 3b  pParse->dirArg2;
1640: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
1650: 20 20 7d 0a 20 20 20 20 64 65 66 61 75 6c 74 3a    }.    default:
1660: 20 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28   {.      assert(
1670: 20 70 50 61 72 73 65 2d 3e 66 65 74 63 68 44 69   pParse->fetchDi
1680: 72 3d 3d 54 4b 5f 52 45 4c 41 54 49 56 45 20 29  r==TK_RELATIVE )
1690: 3b 0a 20 20 20 20 20 20 69 66 28 20 70 50 61 72  ;.      if( pPar
16a0: 73 65 2d 3e 64 69 72 41 72 67 32 3e 3d 30 20 29  se->dirArg2>=0 )
16b0: 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65  {.        /* The
16c0: 20 69 6e 64 65 78 20 70 61 72 61 6d 65 74 65 72   index parameter
16d0: 20 69 73 20 70 6f 73 69 74 69 76 65 2e 20 20 4d   is positive.  M
16e0: 6f 76 65 20 66 6f 72 77 61 72 64 20 66 72 6f 6d  ove forward from
16f0: 20 74 68 65 20 63 75 72 72 65 6e 74 0a 20 20 20   the current.   
1700: 20 20 20 20 20 2a 2a 20 6c 6f 63 61 74 69 6f 6e       ** location
1710: 20 2a 2f 0a 20 20 20 20 20 20 20 20 73 46 65 74   */.        sFet
1720: 63 68 2e 69 73 42 61 63 6b 77 61 72 64 73 20 3d  ch.isBackwards =
1730: 20 30 3b 0a 20 20 20 20 20 20 20 20 73 46 65 74   0;.        sFet
1740: 63 68 2e 64 6f 52 65 77 69 6e 64 20 3d 20 30 3b  ch.doRewind = 0;
1750: 0a 20 20 20 20 20 20 20 20 70 43 6f 70 79 2d 3e  .        pCopy->
1760: 6e 4c 69 6d 69 74 20 3d 20 70 50 61 72 73 65 2d  nLimit = pParse-
1770: 3e 64 69 72 41 72 67 31 3b 0a 20 20 20 20 20 20  >dirArg1;.      
1780: 20 20 70 43 6f 70 79 2d 3e 6e 4f 66 66 73 65 74    pCopy->nOffset
1790: 20 3d 20 70 50 61 72 73 65 2d 3e 64 69 72 41 72   = pParse->dirAr
17a0: 67 32 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  g2;.      }else{
17b0: 0a 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20  .        /* The 
17c0: 69 6e 64 65 78 20 69 73 20 6e 65 67 61 74 69 76  index is negativ
17d0: 65 2e 20 20 57 65 20 68 61 76 65 20 74 6f 20 63  e.  We have to c
17e0: 6f 64 65 20 74 77 6f 20 73 65 70 61 72 61 74 65  ode two separate
17f0: 20 53 45 4c 45 43 54 73 2e 0a 20 20 20 20 20 20   SELECTs..      
1800: 20 20 2a 2a 20 54 68 65 20 66 69 72 73 74 20 6f    ** The first o
1810: 6e 65 20 73 65 65 6b 73 20 74 6f 20 74 68 65 20  ne seeks to the 
1820: 6e 6f 20 70 6f 73 69 74 69 6f 6e 20 61 6e 64 20  no position and 
1830: 74 68 65 20 73 65 63 6f 6e 64 20 6f 6e 65 20 64  the second one d
1840: 6f 65 73 0a 20 20 20 20 20 20 20 20 2a 2a 20 74  oes.        ** t
1850: 68 65 20 71 75 65 72 79 2e 0a 20 20 20 20 20 20  he query..      
1860: 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 53 65 6c    */.        Sel
1870: 65 63 74 20 2a 70 53 65 65 6b 20 3d 20 73 71 6c  ect *pSeek = sql
1880: 69 74 65 33 53 65 6c 65 63 74 44 75 70 28 70 43  ite3SelectDup(pC
1890: 6f 70 79 29 3b 0a 20 20 20 20 20 20 20 20 72 65  opy);.        re
18a0: 76 65 72 73 65 53 6f 72 74 4f 72 64 65 72 28 70  verseSortOrder(p
18b0: 53 65 65 6b 29 3b 0a 20 20 20 20 20 20 20 20 73  Seek);.        s
18c0: 46 65 74 63 68 2e 69 73 42 61 63 6b 77 61 72 64  Fetch.isBackward
18d0: 73 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 73  s = 1;.        s
18e0: 46 65 74 63 68 2e 64 6f 52 65 77 69 6e 64 20 3d  Fetch.doRewind =
18f0: 20 30 3b 0a 20 20 20 20 20 20 20 20 70 53 65 65   0;.        pSee
1900: 6b 2d 3e 6e 4c 69 6d 69 74 20 3d 20 70 50 61 72  k->nLimit = pPar
1910: 73 65 2d 3e 64 69 72 41 72 67 32 3b 0a 20 20 20  se->dirArg2;.   
1920: 20 20 20 20 20 70 53 65 65 6b 2d 3e 70 46 65 74       pSeek->pFet
1930: 63 68 20 3d 20 26 73 46 65 74 63 68 3b 0a 20 20  ch = &sFetch;.  
1940: 20 20 20 20 20 20 73 71 6c 69 74 65 33 53 65 6c        sqlite3Sel
1950: 65 63 74 28 70 50 61 72 73 65 2c 20 70 53 65 65  ect(pParse, pSee
1960: 6b 2c 20 53 52 54 5f 44 69 73 63 61 72 64 2c 20  k, SRT_Discard, 
1970: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 29 3b 0a  0, 0, 0, 0, 0);.
1980: 20 20 20 20 20 20 20 20 73 46 65 74 63 68 2e 69          sFetch.i
1990: 73 42 61 63 6b 77 61 72 64 73 20 3d 20 30 3b 0a  sBackwards = 0;.
19a0: 20 20 20 20 20 20 20 20 73 46 65 74 63 68 2e 64          sFetch.d
19b0: 6f 52 65 77 69 6e 64 20 3d 20 30 3b 0a 20 20 20  oRewind = 0;.   
19c0: 20 20 20 20 20 70 43 6f 70 79 2d 3e 6e 4c 69 6d       pCopy->nLim
19d0: 69 74 20 3d 20 70 50 61 72 73 65 2d 3e 64 69 72  it = pParse->dir
19e0: 41 72 67 31 3b 0a 20 20 20 20 20 20 20 20 70 43  Arg1;.        pC
19f0: 6f 70 79 2d 3e 6e 4f 66 66 73 65 74 20 3d 20 30  opy->nOffset = 0
1a00: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
1a10: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d  break;.    }.  }
1a20: 0a 20 20 73 71 6c 69 74 65 33 53 65 6c 65 63 74  .  sqlite3Select
1a30: 28 70 50 61 72 73 65 2c 20 70 43 6f 70 79 2c 20  (pParse, pCopy, 
1a40: 53 52 54 5f 43 61 6c 6c 62 61 63 6b 2c 20 30 2c  SRT_Callback, 0,
1a50: 20 30 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 0a 65   0, 0, 0, 0);..e
1a60: 6e 64 5f 66 65 74 63 68 3a 0a 20 20 73 71 6c 69  nd_fetch:.  sqli
1a70: 74 65 33 49 64 4c 69 73 74 44 65 6c 65 74 65 28  te3IdListDelete(
1a80: 70 49 6e 74 6f 29 3b 0a 7d 0a 0a 23 65 6e 64 69  pInto);.}..#endi
1a90: 66 20 2f 2a 20 53 51 4c 49 54 45 5f 4f 4d 49 54  f /* SQLITE_OMIT
1aa0: 5f 43 55 52 53 4f 52 20 2a 2f 0a                 _CURSOR */.