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: |
4fb52b4824cbc6d5fa23449bfb998ec9 |
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
Changes to VERSION.
|
| | | 1 | 1.0.22 |
Changes to src/select.c.
︙ | ︙ | |||
20 21 22 23 24 25 26 | ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements. ** | | | 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 | 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); | | | 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 | ** 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. ** | | | 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 | ** "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", | | | | | | | | | | | | | | | | | | | | | | 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 | 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 ){ | | | | < < > > | | | > > > > > > > > > > > > > > > > > > > > > | 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 | 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 ){ | > | > | 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 | ************************************************************************* ** 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. ** | | | 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 | #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 | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | ** 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. ** | | | 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 | ** 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 ){ | < < < | < | 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> } |
︙ | ︙ |