Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Remove cruft: restrict the number of sorters and lists in the VDBE to one since no more than one was ever used anyway. This eliminates several op-codes and simplifies the implementation of several others. (CVS 297) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
e1370276c2a0d045b29c981ddcb59f73 |
User & Date: | drh 2001-11-01 14:41:34.000 |
Context
2001-11-03
| ||
23:57 | Added "const" to lots of "char*" parameters in the API. (CVS 298) (check-in: 1c448f1fd2 user: drh tags: trunk) | |
2001-11-01
| ||
14:41 | Remove cruft: restrict the number of sorters and lists in the VDBE to one since no more than one was ever used anyway. This eliminates several op-codes and simplifies the implementation of several others. (CVS 297) (check-in: e1370276c2 user: drh tags: trunk) | |
13:52 | Comment changes only. (CVS 296) (check-in: b2cb118fb7 user: drh tags: trunk) | |
Changes
Changes to README.
︙ | ︙ | |||
17 18 19 20 21 22 23 | make ;# Run the makefile. The configure script uses autoconf 2.50 and libtool. If the configure script does not work out for you, there is a generic makefile named "Makefile.template" in the top directory of the source tree that you can copy and edit to suite your needs. Comments on the generic makefile show what changes are needed. | > > > > > > > > > > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | make ;# Run the makefile. The configure script uses autoconf 2.50 and libtool. If the configure script does not work out for you, there is a generic makefile named "Makefile.template" in the top directory of the source tree that you can copy and edit to suite your needs. Comments on the generic makefile show what changes are needed. The windows binaries on the website are created using MinGW32 configured as a cross-compiler running under Linux. For details, see the ./publish.sh script at the top-level of the source tree. Contacts: http://www.hwaci.com/sw/sqlite/ http://groups.yahoo.com/group/sqlite/ drh@hwaci.com |
Changes to publish.sh.
︙ | ︙ | |||
86 87 88 89 90 91 92 | zip sqlite.zip sqlite.exe # Construct a tarball of the source tree # ORIGIN=`pwd` cd $srcdir cd .. | > | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | zip sqlite.zip sqlite.exe # Construct a tarball of the source tree # ORIGIN=`pwd` cd $srcdir cd .. EXCLUDE=`find sqlite -print | grep CVS | sed 's,sqlite/, --exclude sqlite/,'` tar czf $ORIGIN/sqlite.tar.gz $EXCLUDE sqlite cd $ORIGIN vers=`cat $srcdir/VERSION` rm -f sqlite-$vers.tar.gz ln sqlite.tar.gz sqlite-$vers.tar.gz # Build the website # |
︙ | ︙ |
Changes to src/delete.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** ** $Id: delete.c,v 1.19 2001/11/01 14:41:34 drh Exp $ */ #include "sqliteInt.h" /* ** Process a DELETE FROM statement. */ void sqliteDeleteFrom( |
︙ | ︙ | |||
121 122 123 124 125 126 127 | /* The usual case: There is a WHERE clause so we have to scan through ** the table an pick which records to delete. */ else{ /* Begin the database scan */ | < | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | /* The usual case: There is a WHERE clause so we have to scan through ** the table an pick which records to delete. */ else{ /* Begin the database scan */ pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1); if( pWInfo==0 ) goto delete_from_cleanup; /* Remember the key of every item to be deleted. */ sqliteVdbeAddOp(v, OP_ListWrite, 0, 0); if( db->flags & SQLITE_CountRows ){ |
︙ | ︙ | |||
164 165 166 167 168 169 170 | sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0); sqliteVdbeAddOp(v, OP_DeleteIdx, base+i, 0); } } sqliteVdbeAddOp(v, OP_Delete, base, 0); sqliteVdbeAddOp(v, OP_Goto, 0, addr); sqliteVdbeResolveLabel(v, end); | | | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0); sqliteVdbeAddOp(v, OP_DeleteIdx, base+i, 0); } } sqliteVdbeAddOp(v, OP_Delete, base, 0); sqliteVdbeAddOp(v, OP_Goto, 0, addr); sqliteVdbeResolveLabel(v, end); sqliteVdbeAddOp(v, OP_ListReset, 0, 0); } if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0); } /* ** Return the number of rows that were deleted. |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** ** $Id: select.c,v 1.45 2001/11/01 14:41:34 drh Exp $ */ #include "sqliteInt.h" /* ** Allocate a new Select structure and return a pointer to that ** structure. */ |
︙ | ︙ | |||
218 219 220 221 222 223 224 | int end = sqliteVdbeMakeLabel(v); int addr; sqliteVdbeAddOp(v, OP_Sort, 0, 0); addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end); sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0); sqliteVdbeAddOp(v, OP_Goto, 0, addr); sqliteVdbeResolveLabel(v, end); | | | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | int end = sqliteVdbeMakeLabel(v); int addr; sqliteVdbeAddOp(v, OP_Sort, 0, 0); addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end); sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0); sqliteVdbeAddOp(v, OP_Goto, 0, addr); sqliteVdbeResolveLabel(v, end); sqliteVdbeAddOp(v, OP_SortReset, 0, 0); } /* ** Generate code that will tell the VDBE how many columns there ** are in the result and the name for each column. This information ** is used to provide "argc" and "azCol[]" values in the callback. */ |
︙ | ︙ | |||
547 548 549 550 551 552 553 | /* Convert the data in the temporary table into whatever form ** it is that we currently need. */ if( eDest!=priorOp ){ int iCont, iBreak; assert( p->pEList ); generateColumnNames(pParse, 0, p->pEList); | < < < | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 | /* Convert the data in the temporary table into whatever form ** it is that we currently need. */ if( eDest!=priorOp ){ int iCont, iBreak; assert( p->pEList ); generateColumnNames(pParse, 0, p->pEList); sqliteVdbeAddOp(v, OP_Rewind, unionTab, 0); iBreak = sqliteVdbeMakeLabel(v); iCont = sqliteVdbeAddOp(v, OP_Next, unionTab, iBreak); rc = selectInnerLoop(pParse, 0, unionTab, p->pEList->nExpr, p->pOrderBy, -1, eDest, iParm, iCont, iBreak); if( rc ) return 1; |
︙ | ︙ | |||
601 602 603 604 605 606 607 | if( rc ) return rc; /* Generate code to take the intersection of the two temporary ** tables. */ assert( p->pEList ); generateColumnNames(pParse, 0, p->pEList); | < < < | 598 599 600 601 602 603 604 605 606 607 608 609 610 611 | if( rc ) return rc; /* Generate code to take the intersection of the two temporary ** tables. */ assert( p->pEList ); generateColumnNames(pParse, 0, p->pEList); sqliteVdbeAddOp(v, OP_Rewind, tab1, 0); iBreak = sqliteVdbeMakeLabel(v); iCont = sqliteVdbeAddOp(v, OP_Next, tab1, iBreak); sqliteVdbeAddOp(v, OP_FullKey, tab1, 0); sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont); rc = selectInnerLoop(pParse, 0, tab1, p->pEList->nExpr, p->pOrderBy, -1, eDest, iParm, |
︙ | ︙ | |||
855 856 857 858 859 860 861 | } } /* Begin generating code. */ v = sqliteGetVdbe(pParse); if( v==0 ) return 1; | < < < | 849 850 851 852 853 854 855 856 857 858 859 860 861 862 | } } /* Begin generating code. */ v = sqliteGetVdbe(pParse); if( v==0 ) return 1; /* Identify column names if we will be using in the callback. This ** step is skipped if the output is going to a table or a memory cell. */ if( eDest==SRT_Callback ){ generateColumnNames(pParse, pTabList, pEList); } |
︙ | ︙ |
Changes to src/update.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** ** $Id: update.c,v 1.20 2001/11/01 14:41:34 drh Exp $ */ #include "sqliteInt.h" /* ** Process an UPDATE statement. */ void sqliteUpdate( |
︙ | ︙ | |||
139 140 141 142 143 144 145 | sqliteVdbeAddOp(v, OP_Transaction, 0, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0); pParse->schemaVerified = 1; } /* Begin the database scan */ | < | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | sqliteVdbeAddOp(v, OP_Transaction, 0, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0); pParse->schemaVerified = 1; } /* Begin the database scan */ pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1); if( pWInfo==0 ) goto update_cleanup; /* Remember the index of every item to be updated. */ sqliteVdbeAddOp(v, OP_ListWrite, 0, 0); |
︙ | ︙ | |||
229 230 231 232 233 234 235 | } /* Repeat the above with the next record to be updated, until ** all record selected by the WHERE clause have been updated. */ sqliteVdbeAddOp(v, OP_Goto, 0, addr); sqliteVdbeResolveLabel(v, end); | | | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | } /* Repeat the above with the next record to be updated, until ** all record selected by the WHERE clause have been updated. */ sqliteVdbeAddOp(v, OP_Goto, 0, addr); sqliteVdbeResolveLabel(v, end); sqliteVdbeAddOp(v, OP_ListReset, 0, 0); if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0); } /* ** Return the number of rows that were changed. */ |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
26 27 28 29 30 31 32 | ** 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. ** | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** 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.91 2001/11/01 14:41:34 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** SQL is translated into a sequence of instructions to be ** executed by a virtual machine. Each instruction is an instance |
︙ | ︙ | |||
183 184 185 186 187 188 189 | int tos; /* Index of top of stack */ int nStackAlloc; /* Size of the stack */ Stack *aStack; /* The operand stack, except string values */ char **zStack; /* Text or binary values of the stack */ char **azColName; /* Becomes the 4th parameter to callbacks */ int nCursor; /* Number of slots in aCsr[] */ Cursor *aCsr; /* On element of this array for each open cursor */ | | < | < | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | int tos; /* Index of top of stack */ int nStackAlloc; /* Size of the stack */ Stack *aStack; /* The operand stack, except string values */ char **zStack; /* Text or binary values of the stack */ char **azColName; /* Becomes the 4th parameter to callbacks */ int nCursor; /* Number of slots in aCsr[] */ Cursor *aCsr; /* On element of this array for each open cursor */ Keylist *pList; /* A list of ROWIDs */ Sorter *pSort; /* A linked list of objects to be sorted */ FILE *pFile; /* At most one open file handler */ int nField; /* Number of file fields */ char **azField; /* Data for each file field */ char *zLine; /* A single line from the input file */ int nLineAlloc; /* Number of spaces allocated for zLine */ int nMem; /* Number of memory locations currently allocated */ Mem *aMem; /* The memory locations */ |
︙ | ︙ | |||
713 714 715 716 717 718 719 720 721 722 723 724 725 726 | for(i=0; i<p->nCursor; i++){ cleanupCursor(&p->aCsr[i]); } sqliteFree(p->aCsr); p->aCsr = 0; p->nCursor = 0; } /* ** Clean up the VM after execution. ** ** This routine will automatically close any cursors, lists, and/or ** sorters that were left open. */ | > > > > > > > > > > > > > | 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 | for(i=0; i<p->nCursor; i++){ cleanupCursor(&p->aCsr[i]); } sqliteFree(p->aCsr); p->aCsr = 0; p->nCursor = 0; } /* ** Remove any elements that remain on the sorter for the VDBE given. */ static void SorterReset(Vdbe *p){ while( p->pSort ){ Sorter *pSorter = p->pSort; p->pSort = pSorter->pNext; sqliteFree(pSorter->zKey); sqliteFree(pSorter->pData); sqliteFree(pSorter); } } /* ** Clean up the VM after execution. ** ** This routine will automatically close any cursors, lists, and/or ** sorters that were left open. */ |
︙ | ︙ | |||
734 735 736 737 738 739 740 | if( p->aMem[i].s.flags & STK_Dyn ){ sqliteFree(p->aMem[i].z); } } sqliteFree(p->aMem); p->aMem = 0; p->nMem = 0; | | | < < < | < < < < < < < < | < < | < | 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 | if( p->aMem[i].s.flags & STK_Dyn ){ sqliteFree(p->aMem[i].z); } } sqliteFree(p->aMem); p->aMem = 0; p->nMem = 0; if( p->pList ){ KeylistFree(p->pList); p->pList = 0; } SorterReset(p); if( p->pFile ){ if( p->pFile!=stdin ) fclose(p->pFile); p->pFile = 0; } if( p->azField ){ sqliteFree(p->azField); p->azField = 0; |
︙ | ︙ | |||
818 819 820 821 822 823 824 | "OpenWrite", "OpenAux", "OpenWrAux", "Close", "MoveTo", "Fcnt", "NewRecno", "Put", "Distinct", "Found", "NotFound", "Delete", "Column", "KeyAsData", "Recno", "FullKey", "Rewind", "Next", "Destroy", "Clear", "CreateIndex", "CreateTable", "Reorganize", "BeginIdx", "NextIdx", "PutIdx", "DeleteIdx", "MemLoad", | | | | < | | | | | | | | | | | | | | | | | 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 | "OpenWrite", "OpenAux", "OpenWrAux", "Close", "MoveTo", "Fcnt", "NewRecno", "Put", "Distinct", "Found", "NotFound", "Delete", "Column", "KeyAsData", "Recno", "FullKey", "Rewind", "Next", "Destroy", "Clear", "CreateIndex", "CreateTable", "Reorganize", "BeginIdx", "NextIdx", "PutIdx", "DeleteIdx", "MemLoad", "MemStore", "ListWrite", "ListRewind", "ListRead", "ListReset", "SortPut", "SortMakeRec", "SortMakeKey", "Sort", "SortNext", "SortCallback", "SortReset", "FileOpen", "FileRead", "FileColumn", "FileClose", "AggReset", "AggFocus", "AggIncr", "AggNext", "AggSet", "AggGet", "SetInsert", "SetFound", "SetNotFound", "SetClear", "MakeRecord", "MakeKey", "MakeIdxKey", "Goto", "If", "Halt", "ColumnCount", "ColumnName", "Callback", "NullCallback", "Integer", "String", "Null", "Pop", "Dup", "Pull", "Add", "AddImm", "Subtract", "Multiply", "Divide", "Remainder", "BitAnd", "BitOr", "BitNot", "ShiftLeft", "ShiftRight", "AbsValue", "Precision", "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. |
︙ | ︙ | |||
3081 3082 3083 3084 3085 3086 3087 | ** In the current implementation, this is a no-op. */ case OP_Reorganize: { /* This is currently a no-op */ break; } | < < < < < < < < < < < < < < < < < < < < < < < < < | | < < | | | | | < < | | < < | | | | | | < < | < < < | < < < < < < < < < < < < < < | < < | | | 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 | ** In the current implementation, this is a no-op. */ case OP_Reorganize: { /* This is currently a no-op */ break; } /* Opcode: ListWrite * * * ** ** Write the integer on the top of the stack ** into the temporary storage list. */ case OP_ListWrite: { Keylist *pKeylist; VERIFY( if( p->tos<0 ) goto not_enough_stack; ) pKeylist = p->pList; if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){ pKeylist = sqliteMalloc( sizeof(Keylist)+999*sizeof(pKeylist->aKey[0]) ); if( pKeylist==0 ) goto no_mem; pKeylist->nKey = 1000; pKeylist->nRead = 0; pKeylist->nUsed = 0; pKeylist->pNext = p->pList; p->pList = pKeylist; } Integerify(p, p->tos); pKeylist->aKey[pKeylist->nUsed++] = aStack[p->tos].i; POPSTACK; break; } /* Opcode: ListRewind * * * ** ** Rewind the temporary buffer back to the beginning. */ case OP_ListRewind: { /* This is now a no-op */ break; } /* Opcode: ListRead * P2 * ** ** Attempt to read an integer from the temporary storage buffer ** and push it onto the stack. If the storage buffer is empty, ** push nothing but instead jump to P2. */ case OP_ListRead: { Keylist *pKeylist; pKeylist = p->pList; if( pKeylist!=0 ){ VERIFY( if( pKeylist->nRead<0 || pKeylist->nRead>=pKeylist->nUsed || pKeylist->nRead>=pKeylist->nKey ) goto bad_instruction; ) p->tos++; if( NeedStack(p, p->tos) ) goto no_mem; aStack[p->tos].i = pKeylist->aKey[pKeylist->nRead++]; aStack[p->tos].flags = STK_Int; zStack[p->tos] = 0; if( pKeylist->nRead>=pKeylist->nUsed ){ p->pList = pKeylist->pNext; sqliteFree(pKeylist); } }else{ pc = pOp->p2 - 1; } break; } /* Opcode: ListReset * * * ** ** Reset the temporary storage buffer so that it holds nothing. */ case OP_ListReset: { if( p->pList ){ KeylistFree(p->pList); p->pList = 0; } break; } /* Opcode: SortPut * * * ** ** The TOS is the key and the NOS is the data. Pop both from the stack ** and put them on the sorter. */ case OP_SortPut: { int tos = p->tos; int nos = tos - 1; Sorter *pSorter; VERIFY( if( tos<1 ) goto not_enough_stack; ) if( Stringify(p, tos) || Stringify(p, nos) ) goto no_mem; pSorter = sqliteMalloc( sizeof(Sorter) ); if( pSorter==0 ) goto no_mem; pSorter->pNext = p->pSort; p->pSort = pSorter; pSorter->nKey = aStack[tos].n; pSorter->zKey = zStack[tos]; pSorter->nData = aStack[nos].n; pSorter->pData = zStack[nos]; aStack[tos].flags = 0; aStack[nos].flags = 0; zStack[tos] = 0; |
︙ | ︙ | |||
3279 3280 3281 3282 3283 3284 3285 | p->tos++; aStack[p->tos].n = nByte; zStack[p->tos] = (char*)azArg; aStack[p->tos].flags = STK_Str|STK_Dyn; break; } | | | 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 | p->tos++; aStack[p->tos].n = nByte; zStack[p->tos] = (char*)azArg; aStack[p->tos].flags = STK_Str|STK_Dyn; break; } /* Opcode: SortMakeKey * * P3 ** ** Convert the top few entries of the stack into a sort key. The ** number of stack entries consumed is the number of characters in ** the string P3. One character from P3 is prepended to each entry. ** The first character of P3 is prepended to the element lowest in ** the stack and the last character of P3 is appended to the top of ** the stack. All stack entries are separated by a \000 character |
︙ | ︙ | |||
3326 3327 3328 3329 3330 3331 3332 | p->tos++; aStack[p->tos].n = nByte; aStack[p->tos].flags = STK_Str|STK_Dyn; zStack[p->tos] = zNewKey; break; } | | | < < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | > > < < < | > | < < < < < < < < < < < < < < < < < < < < < | | | | | < < < < < < < < < < | 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 | p->tos++; aStack[p->tos].n = nByte; aStack[p->tos].flags = STK_Str|STK_Dyn; zStack[p->tos] = zNewKey; break; } /* Opcode: Sort * * * ** ** Sort all elements on the sorter. The algorithm is a ** mergesort. */ case OP_Sort: { int i; Sorter *pElem; Sorter *apSorter[NSORT]; for(i=0; i<NSORT; i++){ apSorter[i] = 0; } while( p->pSort ){ pElem = p->pSort; p->pSort = pElem->pNext; pElem->pNext = 0; for(i=0; i<NSORT-1; i++){ if( apSorter[i]==0 ){ apSorter[i] = pElem; break; }else{ pElem = Merge(apSorter[i], pElem); apSorter[i] = 0; } } if( i>=NSORT-1 ){ apSorter[NSORT-1] = Merge(apSorter[NSORT-1],pElem); } } pElem = 0; for(i=0; i<NSORT; i++){ pElem = Merge(apSorter[i], pElem); } p->pSort = pElem; break; } /* Opcode: SortNext * P2 * ** ** Push the data for the topmost element in the sorter onto the ** stack, then remove the element from the sorter. If the sorter ** is empty, push nothing on the stack and instead jump immediately ** to instruction P2. */ case OP_SortNext: { Sorter *pSorter = p->pSort; if( pSorter!=0 ){ p->pSort = pSorter->pNext; p->tos++; VERIFY( NeedStack(p, p->tos); ) zStack[p->tos] = pSorter->pData; aStack[p->tos].n = pSorter->nData; aStack[p->tos].flags = STK_Str|STK_Dyn; sqliteFree(pSorter->zKey); sqliteFree(pSorter); }else{ pc = pOp->p2 - 1; } break; } /* Opcode: SortCallback * P2 * ** ** The top of the stack contains a callback record built using ** the SortMakeRec operation with the same P1 value as this ** instruction. Pop this record from the stack and invoke the ** callback on it. */ case OP_SortCallback: { int i = p->tos; VERIFY( if( i<0 ) goto not_enough_stack; ) if( xCallback!=0 ){ if( xCallback(pArg, pOp->p1, (char**)zStack[i], p->azColName) ){ rc = SQLITE_ABORT; } p->nCallback++; } POPSTACK; if( sqlite_malloc_failed ) goto no_mem; break; } /* Opcode: SortReset * * * ** ** Remove any elements that remain on the sorter. */ case OP_SortReset: { SorterReset(p); break; } /* Opcode: FileOpen * * P3 ** ** Open the file named by P3 for reading using the FileRead opcode. ** If P3 is "stdin" then open standard input for reading. |
︙ | ︙ |
Changes to src/vdbe.h.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** 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. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** 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.31 2001/11/01 14:41:34 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines |
︙ | ︙ | |||
107 108 109 110 111 112 113 | #define OP_NextIdx 33 #define OP_PutIdx 34 #define OP_DeleteIdx 35 #define OP_MemLoad 36 #define OP_MemStore 37 | < | | | | < | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | #define OP_NextIdx 33 #define OP_PutIdx 34 #define OP_DeleteIdx 35 #define OP_MemLoad 36 #define OP_MemStore 37 #define OP_ListWrite 38 #define OP_ListRewind 39 #define OP_ListRead 40 #define OP_ListReset 41 #define OP_SortPut 42 #define OP_SortMakeRec 43 #define OP_SortMakeKey 44 #define OP_Sort 45 #define OP_SortNext 46 #define OP_SortCallback 47 #define OP_SortReset 48 #define OP_FileOpen 49 #define OP_FileRead 50 #define OP_FileColumn 51 #define OP_FileClose 52 #define OP_AggReset 53 #define OP_AggFocus 54 #define OP_AggIncr 55 #define OP_AggNext 56 #define OP_AggSet 57 #define OP_AggGet 58 #define OP_SetInsert 59 #define OP_SetFound 60 #define OP_SetNotFound 61 #define OP_SetClear 62 #define OP_MakeRecord 63 #define OP_MakeKey 64 #define OP_MakeIdxKey 65 #define OP_Goto 66 #define OP_If 67 #define OP_Halt 68 #define OP_ColumnCount 69 #define OP_ColumnName 70 #define OP_Callback 71 #define OP_NullCallback 72 #define OP_Integer 73 #define OP_String 74 #define OP_Null 75 #define OP_Pop 76 #define OP_Dup 77 #define OP_Pull 78 #define OP_Add 79 #define OP_AddImm 80 #define OP_Subtract 81 #define OP_Multiply 82 #define OP_Divide 83 #define OP_Remainder 84 #define OP_BitAnd 85 #define OP_BitOr 86 #define OP_BitNot 87 #define OP_ShiftLeft 88 #define OP_ShiftRight 89 #define OP_AbsValue 90 #define OP_Precision 91 #define OP_Min 92 #define OP_Max 93 #define OP_Like 94 #define OP_Glob 95 #define OP_Eq 96 #define OP_Ne 97 #define OP_Lt 98 #define OP_Le 99 #define OP_Gt 100 #define OP_Ge 101 #define OP_IsNull 102 #define OP_NotNull 103 #define OP_Negative 104 #define OP_And 105 #define OP_Or 106 #define OP_Not 107 #define OP_Concat 108 #define OP_Noop 109 #define OP_Strlen 110 #define OP_Substr 111 #define OP_MAX 111 /* ** Prototypes for the VDBE interface. See comments on the implementation ** for a description of what each of these routines does. */ Vdbe *sqliteVdbeCreate(sqlite*); void sqliteVdbeCreateCallback(Vdbe*, int*); |
︙ | ︙ |
Changes to www/changes.tcl.
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 | proc chng {date desc} { puts "<DT><B>$date</B></DT>" puts "<DD><P><UL>$desc</UL></P></DD>" } chng {2001 Oct ?? (2.0.8)} { <li>Documentation updates</li> } chng {2001 Oct 21 (2.0.7)} { <li>Any UTF-8 character or ISO8859 character can be used as part of an identifier.</li> <li>Patches from Christian Werner to improve ODBC compatibility and to fix a bug in the round() function.</li> | > > > > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | proc chng {date desc} { puts "<DT><B>$date</B></DT>" puts "<DD><P><UL>$desc</UL></P></DD>" } chng {2001 Oct ?? (2.0.8)} { <li>Documentation updates</li> <li>Simplify the design of the VDBE by restricting the number of sorters and lists to 1. In practice, no more than one sorter and one list was every used anyhow. </li> } chng {2001 Oct 21 (2.0.7)} { <li>Any UTF-8 character or ISO8859 character can be used as part of an identifier.</li> <li>Patches from Christian Werner to improve ODBC compatibility and to fix a bug in the round() function.</li> |
︙ | ︙ |
Changes to www/index.tcl.
1 2 3 | # # Run this TCL script to generate HTML for the index.html file. # | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # # Run this TCL script to generate HTML for the index.html file. # set rcsid {$Id: index.tcl,v 1.46 2001/11/01 14:41:34 drh Exp $} puts {<html> <head><title>SQLite: An SQL Database Engine In A C Library</title></head> <body bgcolor=white> <h1 align=center>SQLite: An SQL Database Engine In A C Library</h1> <p align=center>} puts "This page was last modified on [lrange $rcsid 3 4] GMT<br>" set vers [lindex $argv 0] puts "The latest SQLite version is <b>$vers</b>" puts " created on [exec cat last_change] GMT" puts {</p>} puts {<h2>Introduction</h2> <p>SQLite is a C library that implements an embeddable SQL database engine. Programs that link with the SQLite library can have SQL database access without running a separate RDBMS process. The distribution comes with a standalone command-line access program (<a href="sqlite.html">sqlite</a>) that can be used to administer an SQLite database and which serves as an example of how to use the SQLite library.</p> |
︙ | ︙ | |||
60 61 62 63 64 65 66 | } puts {<h2>Current Status</h2> <p>A <a href="changes.html">change history</a> is available online. The latest source code is <a href="download.html">available for download</a>. | | > > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | } puts {<h2>Current Status</h2> <p>A <a href="changes.html">change history</a> is available online. The latest source code is <a href="download.html">available for download</a>. There are currently no known memory leaks or bugs in the library. SQLite is currently being used in several mission-critical applications. </p> <p> The file format used changed beginning with version 2.0.0. Version 1.0.X of SQLite used GDBM as its database backend. Version 2.0.0 and later use a built-in implementation of B-trees. If you have older 1.0 databases you will need to convert them before they can be read using a 2.0 |
︙ | ︙ | |||
154 155 156 157 158 159 160 | $ cd bld $ ../sqlite/configure $ make <i> Builds "sqlite" and "libsqlite.a" </i> $ make test <i> Optional: run regression tests </i> </pre></blockquote> } | < < < < < < < < < < < < < < < < < < < < < < < < < < | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | $ cd bld $ ../sqlite/configure $ make <i> Builds "sqlite" and "libsqlite.a" </i> $ make test <i> Optional: run regression tests </i> </pre></blockquote> } puts {<h2>Related Sites</h2> <ul> <li><p>An ODBC driver for SQLite can be found at <a href="http://www.ch-werner.de/sqliteodbc/"> http://www.ch-werner.de/sqliteodbc/</a>.</p></li> |
︙ | ︙ |
Changes to www/opcode.tcl.
1 2 3 | # # Run this Tcl script to generate the sqlite.html file. # | | | 1 2 3 4 5 6 7 8 9 10 11 | # # Run this Tcl script to generate the sqlite.html file. # set rcsid {$Id: opcode.tcl,v 1.7 2001/11/01 14:41:34 drh Exp $} puts {<html> <head> <title>SQLite Virtual Machine Opcodes</title> </head> <body bgcolor=white> <h1 align=center> |
︙ | ︙ | |||
113 114 115 116 117 118 119 | <p>The virtual machine contains an arbitrary number of fixed memory locations with addresses beginning at zero and growing upward. Each memory location can hold an arbitrary string. The memory cells are typically used to hold the result of a scalar SELECT that is part of a larger expression.</p> | | | | | < < < | | | | < | 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 | <p>The virtual machine contains an arbitrary number of fixed memory locations with addresses beginning at zero and growing upward. Each memory location can hold an arbitrary string. The memory cells are typically used to hold the result of a scalar SELECT that is part of a larger expression.</p> <p>The virtual machine contains a single sorter. The sorter is able to accumulate records, sort those records, then play the records back in sorted order. The sorter is used to implement the ORDER BY clause of a SELECT statement.</p> <p>The virtual machine contains a single "Lists". The list stores a list of integers. Lists are used to hold the rowids for records of a database table that needs to be modified. The WHERE clause of an UPDATE or DELETE statement scans through the table and writes the rowid of every record to be modified into the list. Then the list is played back and the table is modified in a separate step.</p> <p>The virtual machine can contain an arbitrary number of "Sets". Each set holds an arbitrary number of strings. Sets are used to implement the IN operator with a constant right-hand side.</p> <p>The virtual machine can open a single external file for reading. This external read file is used to implement the COPY command.</p> |
︙ | ︙ |