SQLite

Check-in [4fb52b4824]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Repairs to the previous fix (CVS 186)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4fb52b4824cbc6d5fa23449bfb998ec9985f1336
User & Date: drh 2001-02-19 23:23:38.000
Context
2001-02-19
23:28
Repairs to the previous fix (CVS 187) (check-in: b91854a67f user: drh tags: trunk)
23:23
Repairs to the previous fix (CVS 186) (check-in: 4fb52b4824 user: drh tags: trunk)
18:30
Version 1.0.21 (CVS 482) (check-in: 7a1147ff52 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to VERSION.
1
1.0.21
|
1
1.0.22
Changes to src/select.c.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements.
**
** $Id: select.c,v 1.28 2001/01/15 22:51:11 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/







|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements.
**
** $Id: select.c,v 1.29 2001/02/19 23:23:38 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
      assert( p->pEList );
      generateColumnNames(pParse, 0, p->pEList);
      if( p->pOrderBy ){
        sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
      }
      iBreak = sqliteVdbeMakeLabel(v);
      iCont = sqliteVdbeAddOp(v, OP_Next, tab1, iBreak, 0, 0);
      sqliteVdbeAddOp(v, OP_Key, tab1, 0, 0, 0);
      sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont, 0, 0);
      rc = selectInnerLoop(pParse, 0, tab1, p->pEList->nExpr,
                             p->pOrderBy, -1, eDest, iParm, 
                             iCont, iBreak);
      if( rc ) return 1;
      sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0);
      sqliteVdbeAddOp(v, OP_Close, tab2, 0, 0, iBreak);







|







574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
      assert( p->pEList );
      generateColumnNames(pParse, 0, p->pEList);
      if( p->pOrderBy ){
        sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
      }
      iBreak = sqliteVdbeMakeLabel(v);
      iCont = sqliteVdbeAddOp(v, OP_Next, tab1, iBreak, 0, 0);
      sqliteVdbeAddOp(v, OP_FullKey, tab1, 0, 0, 0);
      sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont, 0, 0);
      rc = selectInnerLoop(pParse, 0, tab1, p->pEList->nExpr,
                             p->pOrderBy, -1, eDest, iParm, 
                             iCont, iBreak);
      if( rc ) return 1;
      sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0);
      sqliteVdbeAddOp(v, OP_Close, tab2, 0, 0, iBreak);
Changes to src/vdbe.c.
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
** inplicit conversion from one type to the other occurs as necessary.
** 
** Most of the code in this file is taken up by the sqliteVdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** $Id: vdbe.c,v 1.51 2001/01/15 22:51:12 drh Exp $
*/
#include "sqliteInt.h"
#include <unistd.h>
#include <ctype.h>

/*
** SQL is translated into a sequence of instructions to be







|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
** inplicit conversion from one type to the other occurs as necessary.
** 
** Most of the code in this file is taken up by the sqliteVdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** $Id: vdbe.c,v 1.52 2001/02/19 23:23:39 drh Exp $
*/
#include "sqliteInt.h"
#include <unistd.h>
#include <ctype.h>

/*
** SQL is translated into a sequence of instructions to be
63
64
65
66
67
68
69


70
71
72
73
74
75
76
** 
** Every cursor that the virtual machine has open is represented by an
** instance of the following structure.
*/
struct Cursor {
  DbbeCursor *pCursor;  /* The cursor structure of the backend */
  int index;            /* The next index to extract */


  int keyAsData;        /* The OP_Field command works on key instead of data */
};
typedef struct Cursor Cursor;

/*
** A sorter builds a list of elements to be sorted.  Each element of
** the list is an instance of the following structure.







>
>







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
** 
** Every cursor that the virtual machine has open is represented by an
** instance of the following structure.
*/
struct Cursor {
  DbbeCursor *pCursor;  /* The cursor structure of the backend */
  int index;            /* The next index to extract */
  int lastKey;          /* Last key from a Next or NextIdx operation */
  int keyIsValid;       /* True if lastKey is valid */
  int keyAsData;        /* The OP_Field command works on key instead of data */
};
typedef struct Cursor Cursor;

/*
** A sorter builds a list of elements to be sorted.  Each element of
** the list is an instance of the following structure.
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
** "opNames.awk" awk script which is part of the source tree to regenerate
** this array, then copy and paste it into this file, if you want.
*/
static char *zOpName[] = { 0,
  "OpenIdx",        "OpenTbl",        "Close",          "Fetch",
  "Fcnt",           "New",            "Put",            "Distinct",
  "Found",          "NotFound",       "Delete",         "Field",
  "KeyAsData",      "Key",            "Rewind",         "Next",
  "Destroy",        "Reorganize",     "ResetIdx",       "NextIdx",
  "PutIdx",         "DeleteIdx",      "MemLoad",        "MemStore",
  "ListOpen",       "ListWrite",      "ListRewind",     "ListRead",
  "ListClose",      "SortOpen",       "SortPut",        "SortMakeRec",
  "SortMakeKey",    "Sort",           "SortNext",       "SortKey",
  "SortCallback",   "SortClose",      "FileOpen",       "FileRead",
  "FileField",      "FileClose",      "AggReset",       "AggFocus",
  "AggIncr",        "AggNext",        "AggSet",         "AggGet",
  "SetInsert",      "SetFound",       "SetNotFound",    "SetClear",
  "MakeRecord",     "MakeKey",        "Goto",           "If",
  "Halt",           "ColumnCount",    "ColumnName",     "Callback",
  "Integer",        "String",         "Null",           "Pop",
  "Dup",            "Pull",           "Add",            "AddImm",
  "Subtract",       "Multiply",       "Divide",         "Min",
  "Max",            "Like",           "Glob",           "Eq",
  "Ne",             "Lt",             "Le",             "Gt",
  "Ge",             "IsNull",         "NotNull",        "Negative",
  "And",            "Or",             "Not",            "Concat",
  "Noop",           "Strlen",         "Substr",       
};

/*
** Given the name of an opcode, return its number.  Return 0 if
** there is no match.
**
** This routine is used for testing and debugging.







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
** "opNames.awk" awk script which is part of the source tree to regenerate
** this array, then copy and paste it into this file, if you want.
*/
static char *zOpName[] = { 0,
  "OpenIdx",        "OpenTbl",        "Close",          "Fetch",
  "Fcnt",           "New",            "Put",            "Distinct",
  "Found",          "NotFound",       "Delete",         "Field",
  "KeyAsData",      "Key",            "FullKey",        "Rewind",
  "Next",           "Destroy",        "Reorganize",     "ResetIdx",
  "NextIdx",        "PutIdx",         "DeleteIdx",      "MemLoad",
  "MemStore",       "ListOpen",       "ListWrite",      "ListRewind",
  "ListRead",       "ListClose",      "SortOpen",       "SortPut",
  "SortMakeRec",    "SortMakeKey",    "Sort",           "SortNext",
  "SortKey",        "SortCallback",   "SortClose",      "FileOpen",
  "FileRead",       "FileField",      "FileClose",      "AggReset",
  "AggFocus",       "AggIncr",        "AggNext",        "AggSet",
  "AggGet",         "SetInsert",      "SetFound",       "SetNotFound",
  "SetClear",       "MakeRecord",     "MakeKey",        "Goto",
  "If",             "Halt",           "ColumnCount",    "ColumnName",
  "Callback",       "Integer",        "String",         "Null",
  "Pop",            "Dup",            "Pull",           "Add",
  "AddImm",         "Subtract",       "Multiply",       "Divide",
  "Min",            "Max",            "Like",           "Glob",
  "Eq",             "Ne",             "Lt",             "Le",
  "Gt",             "Ge",             "IsNull",         "NotNull",
  "Negative",       "And",            "Or",             "Not",
  "Concat",         "Noop",           "Strlen",         "Substr",
};

/*
** Given the name of an opcode, return its number.  Return 0 if
** there is no match.
**
** This routine is used for testing and debugging.
1891
1892
1893
1894
1895
1896
1897


1898
1899
1900
1901

1902
1903
1904
1905
1906
1907
1908
        int i = pOp->p1;
        int tos = p->tos;
        VERIFY( if( tos<0 ) goto not_enough_stack; )
        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor ){
          if( aStack[tos].flags & STK_Int ){
            pBex->Fetch(p->aCsr[i].pCursor, sizeof(int), 
                           (char*)&aStack[tos].i);


          }else{
            if( Stringify(p, tos) ) goto no_mem;
            pBex->Fetch(p->aCsr[i].pCursor, aStack[tos].n, 
                           zStack[tos]);

          }
          p->nFetch++;
        }
        POPSTACK;
        break;
      }








>
>




>







1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
        int i = pOp->p1;
        int tos = p->tos;
        VERIFY( if( tos<0 ) goto not_enough_stack; )
        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor ){
          if( aStack[tos].flags & STK_Int ){
            pBex->Fetch(p->aCsr[i].pCursor, sizeof(int), 
                           (char*)&aStack[tos].i);
            p->aCsr[i].lastKey = aStack[tos].i;
            p->aCsr[i].keyIsValid = 1;
          }else{
            if( Stringify(p, tos) ) goto no_mem;
            pBex->Fetch(p->aCsr[i].pCursor, aStack[tos].n, 
                           zStack[tos]);
            p->aCsr[i].keyIsValid = 0;
          }
          p->nFetch++;
        }
        POPSTACK;
        break;
      }

2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157


2158
2159
2160





















2161
2162
2163
2164
2165
2166
2167
      case OP_Key: {
        int i = pOp->p1;
        int tos = ++p->tos;
        DbbeCursor *pCrsr;

        VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
        if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
          char *z = pBex->ReadKey(pCrsr, 0);
          if( p->aCsr[i].keyAsData ){
            zStack[tos] = z;
            aStack[tos].flags = STK_Str;
            aStack[tos].n = pBex->KeyLength(pCrsr);
          }else{


            memcpy(&aStack[tos].i, z, sizeof(int));
            aStack[tos].flags = STK_Int;
          }





















        }
        break;
      }

      /* Opcode: Rewind P1 * *
      **
      ** The next use of the Key or Field or Next instruction for P1 







|
|
|
<
<

>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2150
2151
2152
2153
2154
2155
2156
2157
2158
2159


2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
      case OP_Key: {
        int i = pOp->p1;
        int tos = ++p->tos;
        DbbeCursor *pCrsr;

        VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
        if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
          int v;
          if( p->aCsr[i].keyIsValid ){
            v = p->aCsr[i].lastKey;


          }else{
            memcpy(&v, pBex->ReadKey(pCrsr,0), sizeof(int));
          }
          aStack[tos].i = v;
          aStack[tos].flags = STK_Int;
        }
        break;
      }

      /* Opcode: FullKey P1 * *
      **
      ** Push a string onto the stack which is the full text key associated
      ** with the last Next operation on file P1.  Compare this with the
      ** Key operator which pushs an integer key.
      */
      case OP_FullKey: {
        int i = pOp->p1;
        int tos = ++p->tos;
        DbbeCursor *pCrsr;

        VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
        VERIFY( if( !p->aCsr[i].keyAsData ) goto bad_instruction; )
        if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
          char *z = pBex->ReadKey(pCrsr, 0);
          zStack[tos] = z;
          aStack[tos].flags = STK_Str;
          aStack[tos].n = pBex->KeyLength(pCrsr);
        }
        break;
      }

      /* Opcode: Rewind P1 * *
      **
      ** The next use of the Key or Field or Next instruction for P1 
2185
2186
2187
2188
2189
2190
2191

2192
2193
2194
2195
2196
2197
2198
        if( VERIFY( i>=0 && i<p->nCursor && ) p->aCsr[i].pCursor!=0 ){
          if( pBex->NextKey(p->aCsr[i].pCursor)==0 ){
            pc = pOp->p2 - 1;
          }else{
            p->nFetch++;
          }
        }

        break;
      }

      /* Opcode: ResetIdx P1 * *
      **
      ** Begin treating the current data in cursor P1 as a bunch of integer
      ** keys to records of a (separate) SQL table file.  This instruction







>







2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
        if( VERIFY( i>=0 && i<p->nCursor && ) p->aCsr[i].pCursor!=0 ){
          if( pBex->NextKey(p->aCsr[i].pCursor)==0 ){
            pc = pOp->p2 - 1;
          }else{
            p->nFetch++;
          }
        }
        p->aCsr[i].keyIsValid = 0;
        break;
      }

      /* Opcode: ResetIdx P1 * *
      **
      ** Begin treating the current data in cursor P1 as a bunch of integer
      ** keys to records of a (separate) SQL table file.  This instruction
2237
2238
2239
2240
2241
2242
2243

2244
2245
2246

2247
2248
2249
2250
2251
2252
2253
          aIdx = (int*)pBex->ReadData(pCrsr, 0);
          if( nIdx>1 ){
            k = *(aIdx++);
            if( k>nIdx-1 ) k = nIdx-1;
          }else{
            k = nIdx;
          }

          for(j=p->aCsr[i].index; j<k; j++){
            if( aIdx[j]!=0 ){
              aStack[tos].i = aIdx[j];

              aStack[tos].flags = STK_Int;
              break;
            }
          }
          if( j>=k ){
            j = -1;
            pc = pOp->p2 - 1;







>


|
>







2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
          aIdx = (int*)pBex->ReadData(pCrsr, 0);
          if( nIdx>1 ){
            k = *(aIdx++);
            if( k>nIdx-1 ) k = nIdx-1;
          }else{
            k = nIdx;
          }
          p->aCsr[i].keyIsValid = 0;
          for(j=p->aCsr[i].index; j<k; j++){
            if( aIdx[j]!=0 ){
              aStack[tos].i = p->aCsr[i].lastKey = aIdx[j];
              p->aCsr[i].keyIsValid = 1;
              aStack[tos].flags = STK_Int;
              break;
            }
          }
          if( j>=k ){
            j = -1;
            pc = pOp->p2 - 1;
Changes to src/vdbe.h.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.15 2001/01/15 22:51:12 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.16 2001/02/19 23:23:39 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#define OP_Distinct            8
#define OP_Found               9
#define OP_NotFound           10
#define OP_Delete             11
#define OP_Field              12
#define OP_KeyAsData          13
#define OP_Key                14

#define OP_Rewind             15
#define OP_Next               16

#define OP_Destroy            17
#define OP_Reorganize         18

#define OP_ResetIdx           19
#define OP_NextIdx            20
#define OP_PutIdx             21
#define OP_DeleteIdx          22

#define OP_MemLoad            23
#define OP_MemStore           24

#define OP_ListOpen           25
#define OP_ListWrite          26
#define OP_ListRewind         27
#define OP_ListRead           28
#define OP_ListClose          29

#define OP_SortOpen           30
#define OP_SortPut            31
#define OP_SortMakeRec        32
#define OP_SortMakeKey        33
#define OP_Sort               34
#define OP_SortNext           35
#define OP_SortKey            36
#define OP_SortCallback       37
#define OP_SortClose          38

#define OP_FileOpen           39
#define OP_FileRead           40
#define OP_FileField          41
#define OP_FileClose          42

#define OP_AggReset           43
#define OP_AggFocus           44
#define OP_AggIncr            45
#define OP_AggNext            46
#define OP_AggSet             47
#define OP_AggGet             48

#define OP_SetInsert          49
#define OP_SetFound           50
#define OP_SetNotFound        51
#define OP_SetClear           52

#define OP_MakeRecord         53
#define OP_MakeKey            54

#define OP_Goto               55
#define OP_If                 56
#define OP_Halt               57

#define OP_ColumnCount        58
#define OP_ColumnName         59
#define OP_Callback           60

#define OP_Integer            61
#define OP_String             62
#define OP_Null               63
#define OP_Pop                64
#define OP_Dup                65
#define OP_Pull               66

#define OP_Add                67
#define OP_AddImm             68
#define OP_Subtract           69
#define OP_Multiply           70
#define OP_Divide             71
#define OP_Min                72
#define OP_Max                73
#define OP_Like               74
#define OP_Glob               75
#define OP_Eq                 76
#define OP_Ne                 77
#define OP_Lt                 78
#define OP_Le                 79
#define OP_Gt                 80
#define OP_Ge                 81
#define OP_IsNull             82
#define OP_NotNull            83
#define OP_Negative           84
#define OP_And                85
#define OP_Or                 86
#define OP_Not                87
#define OP_Concat             88
#define OP_Noop               89

#define OP_Strlen             90
#define OP_Substr             91

#define OP_MAX                91

/*
** Prototypes for the VDBE interface.  See comments on the implementation
** for a description of what each of these routines does.
*/
Vdbe *sqliteVdbeCreate(sqlite*);
int sqliteVdbeAddOp(Vdbe*,int,int,int,const char*,int);







>
|
|

|
|

|
|
|
|

|
|

|
|
|
|
|

|
|
|
|
|
|
|
|
|

|
|
|
|

|
|
|
|
|
|

|
|
|
|

|
|

|
|
|

|
|
|

|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|

|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#define OP_Distinct            8
#define OP_Found               9
#define OP_NotFound           10
#define OP_Delete             11
#define OP_Field              12
#define OP_KeyAsData          13
#define OP_Key                14
#define OP_FullKey            15
#define OP_Rewind             16
#define OP_Next               17

#define OP_Destroy            18
#define OP_Reorganize         19

#define OP_ResetIdx           20
#define OP_NextIdx            21
#define OP_PutIdx             22
#define OP_DeleteIdx          23

#define OP_MemLoad            24
#define OP_MemStore           25

#define OP_ListOpen           26
#define OP_ListWrite          27
#define OP_ListRewind         28
#define OP_ListRead           29
#define OP_ListClose          30

#define OP_SortOpen           31
#define OP_SortPut            32
#define OP_SortMakeRec        33
#define OP_SortMakeKey        34
#define OP_Sort               35
#define OP_SortNext           36
#define OP_SortKey            37
#define OP_SortCallback       38
#define OP_SortClose          39

#define OP_FileOpen           40
#define OP_FileRead           41
#define OP_FileField          42
#define OP_FileClose          43

#define OP_AggReset           44
#define OP_AggFocus           45
#define OP_AggIncr            46
#define OP_AggNext            47
#define OP_AggSet             48
#define OP_AggGet             49

#define OP_SetInsert          50
#define OP_SetFound           51
#define OP_SetNotFound        52
#define OP_SetClear           53

#define OP_MakeRecord         54
#define OP_MakeKey            55

#define OP_Goto               56
#define OP_If                 57
#define OP_Halt               58

#define OP_ColumnCount        59
#define OP_ColumnName         60
#define OP_Callback           61

#define OP_Integer            62
#define OP_String             63
#define OP_Null               64
#define OP_Pop                65
#define OP_Dup                66
#define OP_Pull               67

#define OP_Add                68
#define OP_AddImm             69
#define OP_Subtract           70
#define OP_Multiply           71
#define OP_Divide             72
#define OP_Min                73
#define OP_Max                74
#define OP_Like               75
#define OP_Glob               76
#define OP_Eq                 77
#define OP_Ne                 78
#define OP_Lt                 79
#define OP_Le                 80
#define OP_Gt                 81
#define OP_Ge                 82
#define OP_IsNull             83
#define OP_NotNull            84
#define OP_Negative           85
#define OP_And                86
#define OP_Or                 87
#define OP_Not                88
#define OP_Concat             89
#define OP_Noop               90

#define OP_Strlen             91
#define OP_Substr             92

#define OP_MAX                92

/*
** Prototypes for the VDBE interface.  See comments on the implementation
** for a description of what each of these routines does.
*/
Vdbe *sqliteVdbeCreate(sqlite*);
int sqliteVdbeAddOp(Vdbe*,int,int,int,const char*,int);
Changes to src/where.c.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  Also found here are subroutines
** to generate VDBE code to evaluate expressions.
**
** $Id: where.c,v 1.11 2001/02/19 18:24:22 drh Exp $
*/
#include "sqliteInt.h"

/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by an AND operator.







|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  Also found here are subroutines
** to generate VDBE code to evaluate expressions.
**
** $Id: where.c,v 1.12 2001/02/19 23:23:39 drh Exp $
*/
#include "sqliteInt.h"

/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by an AND operator.
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
    ** computed using the current set of tables.
    */
    for(j=0; j<nExpr; j++){
      if( aExpr[j].p==0 ) continue;
      if( (aExpr[j].prereqRight & loopMask)!=aExpr[j].prereqRight ) continue;
      if( (aExpr[j].prereqLeft & loopMask)!=aExpr[j].prereqLeft ) continue;
      if( haveKey ){
        if( pushKey && i==pTabList->nId-1 ){
          sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
        }else{
          haveKey = 0;
        }
        sqliteVdbeAddOp(v, OP_Fetch, base+idx, 0, 0, 0);
      }
      sqliteExprIfFalse(pParse, aExpr[j].p, cont);
      aExpr[j].p = 0;
    }
    brk = cont;
  }







<
<
<
|
<







334
335
336
337
338
339
340



341

342
343
344
345
346
347
348
    ** computed using the current set of tables.
    */
    for(j=0; j<nExpr; j++){
      if( aExpr[j].p==0 ) continue;
      if( (aExpr[j].prereqRight & loopMask)!=aExpr[j].prereqRight ) continue;
      if( (aExpr[j].prereqLeft & loopMask)!=aExpr[j].prereqLeft ) continue;
      if( haveKey ){



        haveKey = 0;

        sqliteVdbeAddOp(v, OP_Fetch, base+idx, 0, 0, 0);
      }
      sqliteExprIfFalse(pParse, aExpr[j].p, cont);
      aExpr[j].p = 0;
    }
    brk = cont;
  }
Changes to www/changes.tcl.
12
13
14
15
16
17
18





19
20
21
22
23
24
25
}


proc chng {date desc} {
  puts "<DT><B>$date</B></DT>"
  puts "<DD><P><UL>$desc</UL></P></DD>"
}






chng {2001 Feb 19 (1.0.21)} {
<li>The UPDATE statement was not working when the WHERE clause contained
    some terms that could be satisfied using indices and other terms that
    could not.  Fixed.</li>
}








>
>
>
>
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
}


proc chng {date desc} {
  puts "<DT><B>$date</B></DT>"
  puts "<DD><P><UL>$desc</UL></P></DD>"
}

chng {2001 Feb 19 (1.0.22)} {
<li>The previous fix was not quite right.  This one seems to work better.
    </li>
}

chng {2001 Feb 19 (1.0.21)} {
<li>The UPDATE statement was not working when the WHERE clause contained
    some terms that could be satisfied using indices and other terms that
    could not.  Fixed.</li>
}