Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Improvements to comments. No code changes. (CVS 618) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
7e10e60bb78b680bb822908a0b7763f8 |
User & Date: | drh 2002-06-14 20:58:45.000 |
Context
2002-06-14
| ||
22:38 | Make the LIMIT clause work even if the destination of the SELECT is something other than a callback. (Ticket #66) (CVS 619) (check-in: 699cf36208 user: drh tags: trunk) | |
20:58 | Improvements to comments. No code changes. (CVS 618) (check-in: 7e10e60bb7 user: drh tags: trunk) | |
20:54 | Fix for bug #72: Make sure the file descriptors are properly closed if sqliteInit() fails for any reason. (CVS 617) (check-in: e67ac0fec5 user: drh tags: trunk) | |
Changes
Changes to src/util.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** ** $Id: util.c,v 1.46 2002/06/14 20:58:45 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* ** If malloc() ever fails, this global variable gets set to 1. |
︙ | ︙ | |||
1080 1081 1082 1083 1084 1085 1086 | ** Return an error (non-zero) if the magic was not SQLITE_MAGIC_OPEN ** when this routine is called. ** ** This routine is a attempt to detect if two threads use the ** same sqlite* pointer at the same time. There is a race ** condition so it is possible that the error is not detected. ** But usually the problem will be seen. The result will be an | | | 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 | ** Return an error (non-zero) if the magic was not SQLITE_MAGIC_OPEN ** when this routine is called. ** ** This routine is a attempt to detect if two threads use the ** same sqlite* pointer at the same time. There is a race ** condition so it is possible that the error is not detected. ** But usually the problem will be seen. The result will be an ** error which can be used to debug the application that is ** using SQLite incorrectly. */ int sqliteSafetyOn(sqlite *db){ if( db->magic==SQLITE_MAGIC_OPEN ){ db->magic = SQLITE_MAGIC_BUSY; return 0; }else{ |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** 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. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** 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.51 2002/06/14 20:58:45 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. |
︙ | ︙ | |||
99 100 101 102 103 104 105 | } return mask; } /* ** Return TRUE if the given operator is one of the operators that is ** allowed for an indexable WHERE clause. The allowed operators are | | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | } return mask; } /* ** Return TRUE if the given operator is one of the operators that is ** allowed for an indexable WHERE clause. The allowed operators are ** "=", "<", ">", "<=", ">=", and "IN". */ static int allowedOp(int op){ switch( op ){ case TK_LT: case TK_LE: case TK_GT: case TK_GE: |
︙ | ︙ | |||
152 153 154 155 156 157 158 159 160 161 162 163 164 165 | ** Generating the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an (opaque) structure that contains ** information needed to terminate the loop. Later, the calling routine ** should invoke sqliteWhereEnd() with the return value of this function ** in order to complete the WHERE clause processing. ** ** If an error occurs, this routine returns NULL. */ WhereInfo *sqliteWhereBegin( Parse *pParse, /* The parser context */ int base, /* VDBE cursor index for left-most table in pTabList */ SrcList *pTabList, /* A list of all tables to be scanned */ Expr *pWhere, /* The WHERE clause */ int pushKey /* If TRUE, leave the table key on the stack */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 207 208 209 210 211 212 213 214 215 216 217 | ** Generating the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an (opaque) structure that contains ** information needed to terminate the loop. Later, the calling routine ** should invoke sqliteWhereEnd() with the return value of this function ** in order to complete the WHERE clause processing. ** ** If an error occurs, this routine returns NULL. ** ** The basic idea is to do a nested loop, one loop for each table in ** the FROM clause of a select. (INSERT and UPDATE statements are the ** same as a SELECT with only a single table in the FROM clause.) For ** example, if the SQL is this: ** ** SELECT * FROM t1, t2, t3 WHERE ...; ** ** Then the code generated is conceptually like the following: ** ** foreach row1 in t1 do \ Code generated ** foreach row2 in t2 do |-- by sqliteWhereBegin() ** foreach row3 in t3 do / ** ... ** end \ Code generated ** end |-- by sqliteWhereEnd() ** end / ** ** There are Btree cursors associated with each table. t1 uses cursor ** "base". t2 uses cursor "base+1". And so forth. This routine generates ** the code to open those cursors. sqliteWhereEnd() generates the code ** to close them. ** ** If the WHERE clause is empty, the foreach loops must each scan their ** entire tables. Thus a three-way join is an O(N^3) operation. But if ** the tables have indices and there are terms in the WHERE clause that ** refer to those indices, a complete table scan can be avoided and the ** code will run much faster. Most of the work of this routine is checking ** to see if there are indices that can be used to speed up the loop. ** ** Terms of the WHERE clause are also used to limit which rows actually ** make it to the "..." in the middle of the loop. After each "foreach", ** terms of the WHERE clause that use only terms in that loop and outer ** loops are evaluated and if false a jump is made around all subsequent ** inner loops (or around the "..." if the test occurs within the inner- ** most loop) ** ** OUTER JOINS ** ** An outer join of tables t1 and t2 is conceptally coded as follows: ** ** foreach row1 in t1 do ** flag = 0 ** foreach row2 in t2 do ** start: ** ... ** flag = 1 ** end ** if flag==0 goto start ** end ** ** In words, if the right */ WhereInfo *sqliteWhereBegin( Parse *pParse, /* The parser context */ int base, /* VDBE cursor index for left-most table in pTabList */ SrcList *pTabList, /* A list of all tables to be scanned */ Expr *pWhere, /* The WHERE clause */ int pushKey /* If TRUE, leave the table key on the stack */ |
︙ | ︙ | |||
174 175 176 177 178 179 180 181 182 183 184 185 186 187 | int haveKey; /* True if KEY is on the stack */ int aDirect[32]; /* If TRUE, then index this table using ROWID */ int iDirectEq[32]; /* Term of the form ROWID==X for the N-th table */ int iDirectLt[32]; /* Term of the form ROWID<X or ROWID<=X */ int iDirectGt[32]; /* Term of the form ROWID>X or ROWID>=X */ ExprInfo aExpr[50]; /* The WHERE clause is divided into these expressions */ /* Allocate space for aOrder[] and aiMem[]. */ aOrder = sqliteMalloc( sizeof(int) * pTabList->nSrc ); /* Allocate and initialize the WhereInfo structure that will become the ** return value. */ pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel)); | > > > > > | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | int haveKey; /* True if KEY is on the stack */ int aDirect[32]; /* If TRUE, then index this table using ROWID */ int iDirectEq[32]; /* Term of the form ROWID==X for the N-th table */ int iDirectLt[32]; /* Term of the form ROWID<X or ROWID<=X */ int iDirectGt[32]; /* Term of the form ROWID>X or ROWID>=X */ ExprInfo aExpr[50]; /* The WHERE clause is divided into these expressions */ /* pushKey is only allowed if there is a single table (as in an INSERT or ** UPDATE statement) */ assert( pushKey==0 || pTabList->nSrc==1 ); /* Allocate space for aOrder[] and aiMem[]. */ aOrder = sqliteMalloc( sizeof(int) * pTabList->nSrc ); /* Allocate and initialize the WhereInfo structure that will become the ** return value. */ pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel)); |
︙ | ︙ | |||
328 329 330 331 332 333 334 | ** This scoring system is designed so that the score can later be ** used to determine how the index is used. If the score&3 is 0 ** then all constraints are equalities. If score&1 is not 0 then ** there is an inequality used as a termination key. (ex: "x<...") ** If score&2 is not 0 then there is an inequality used as the ** start key. (ex: "x>..."); ** | | | > > > | | | | | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | ** This scoring system is designed so that the score can later be ** used to determine how the index is used. If the score&3 is 0 ** then all constraints are equalities. If score&1 is not 0 then ** there is an inequality used as a termination key. (ex: "x<...") ** If score&2 is not 0 then there is an inequality used as the ** start key. (ex: "x>..."); ** ** The IN operator (as in "<expr> IN (...)") is treated the same as ** an equality comparison except that it can only be used on the ** left-most column of an index and other terms of the WHERE clause ** cannot be used in conjunction with the IN operator to help satisfy ** other columns of the index. */ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int eqMask = 0; /* Index columns covered by an x=... term */ int ltMask = 0; /* Index columns covered by an x<... term */ int gtMask = 0; /* Index columns covered by an x>... term */ int inMask = 0; /* Index columns covered by an x IN .. term */ int nEq, m, score; if( pIdx->isDropped ) continue; /* Ignore dropped indices */ if( pIdx->nColumn>32 ) continue; /* Ignore indices too many columns */ for(j=0; j<nExpr; j++){ if( aExpr[j].idxLeft==idx && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ){ |
︙ | ︙ | |||
464 465 466 467 468 469 470 | int j, k; int idx = aOrder[i]; Index *pIdx; WhereLevel *pLevel = &pWInfo->a[i]; /* If this is the right table of a LEFT OUTER JOIN, allocate and ** initialize a memory cell that record if this table matches any | | | > > | 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 | int j, k; int idx = aOrder[i]; Index *pIdx; WhereLevel *pLevel = &pWInfo->a[i]; /* If this is the right table of a LEFT OUTER JOIN, allocate and ** initialize a memory cell that record if this table matches any ** row of the left table of the join. */ if( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ){ if( !pParse->nMem ) pParse->nMem++; pLevel->iLeftJoin = pParse->nMem++; sqliteVdbeAddOp(v, OP_String, 0, 0); sqliteVdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1); } pIdx = pLevel->pIdx; pLevel->inOp = OP_Noop; if( i<ARRAYSIZE(iDirectEq) && iDirectEq[i]>=0 ){ /* Case 1: We can directly reference a single row using an ** equality comparison against the ROWID field. Or ** we reference multiple rows using a "rowid IN (...)" ** construct. */ k = iDirectEq[i]; assert( k<nExpr ); assert( aExpr[k].p!=0 ); assert( aExpr[k].idxLeft==idx || aExpr[k].idxRight==idx ); brk = pLevel->brk = sqliteVdbeMakeLabel(v); if( aExpr[k].idxLeft==idx ){ |
︙ | ︙ | |||
511 512 513 514 515 516 517 | aExpr[k].p = 0; cont = pLevel->cont = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_MustBeInt, 0, brk); haveKey = 0; sqliteVdbeAddOp(v, OP_NotExists, base+idx, brk); pLevel->op = OP_Noop; }else if( pIdx!=0 && pLevel->score%4==0 ){ | | > | 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 | aExpr[k].p = 0; cont = pLevel->cont = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_MustBeInt, 0, brk); haveKey = 0; sqliteVdbeAddOp(v, OP_NotExists, base+idx, brk); pLevel->op = OP_Noop; }else if( pIdx!=0 && pLevel->score%4==0 ){ /* Case 2: There is an index and all terms of the WHERE clause that ** refer to the index use the "==" or "IN" operators. */ int start; int testOp; int nColumn = pLevel->score/4; brk = pLevel->brk = sqliteVdbeMakeLabel(v); for(j=0; j<nColumn; j++){ for(k=0; k<nExpr; k++){ |
︙ | ︙ | |||
642 643 644 645 646 647 648 | if( testOp!=OP_Noop ){ sqliteVdbeAddOp(v, OP_Recno, base+idx, 0); sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); sqliteVdbeAddOp(v, testOp, 0, brk); } haveKey = 0; }else if( pIdx==0 ){ | | | > > > > | | 705 706 707 708 709 710 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 738 | if( testOp!=OP_Noop ){ sqliteVdbeAddOp(v, OP_Recno, base+idx, 0); sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); sqliteVdbeAddOp(v, testOp, 0, brk); } haveKey = 0; }else if( pIdx==0 ){ /* Case 4: There is no usable index. We must do a complete ** scan of the entire database table. */ int start; brk = pLevel->brk = sqliteVdbeMakeLabel(v); cont = pLevel->cont = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_Rewind, base+idx, brk); start = sqliteVdbeCurrentAddr(v); pLevel->op = OP_Next; pLevel->p1 = base+idx; pLevel->p2 = start; haveKey = 0; }else{ /* Case 5: The WHERE clause term that refers to the right-most ** column of the index is an inequality. For example, if ** the index is on (x,y,z) and the WHERE clause is of the ** form "x=5 AND y<10" then this case is used. Only the ** right-most column can be an inequality - the rest must ** use the "==" operator. */ int score = pLevel->score; int nEqColumn = score/4; int start; int leFlag, geFlag; int testOp; |
︙ | ︙ | |||
691 692 693 694 695 696 697 | sqliteExprCode(pParse, aExpr[k].p->pLeft); aExpr[k].p = 0; break; } } } | | | | 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 | sqliteExprCode(pParse, aExpr[k].p->pLeft); aExpr[k].p = 0; break; } } } /* Duplicate the equality term values because they will all be ** used twice: once to make the termination key and once to make the ** start key. */ for(j=0; j<nEqColumn; j++){ sqliteVdbeAddOp(v, OP_Dup, nEqColumn-1, 0); } /* Generate the termination key. This is the key value that ** will end the search. There is no termination key if there ** are no equality terms and no "X<..." term. */ if( (score & 1)!=0 ){ for(k=0; k<nExpr; k++){ Expr *pExpr = aExpr[k].p; if( pExpr==0 ) continue; if( aExpr[k].idxLeft==idx && (pExpr->op==TK_LT || pExpr->op==TK_LE) |
︙ | ︙ | |||
743 744 745 746 747 748 749 | if( leFlag ){ sqliteVdbeAddOp(v, OP_IncrKey, 0, 0); } sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1); } /* Generate the start key. This is the key that defines the lower | | | | 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 | if( leFlag ){ sqliteVdbeAddOp(v, OP_IncrKey, 0, 0); } sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1); } /* Generate the start key. This is the key that defines the lower ** bound on the search. There is no start key if there are no ** equality terms and if there is no "X>..." term. In ** that case, generate a "Rewind" instruction in place of the ** start key search. */ if( (score & 2)!=0 ){ for(k=0; k<nExpr; k++){ Expr *pExpr = aExpr[k].p; if( pExpr==0 ) continue; |
︙ | ︙ | |||
846 847 848 849 850 851 852 | sqliteVdbeAddOp(v, OP_Recno, base, 0); } sqliteFree(aOrder); return pWInfo; } /* | | > | 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 | sqliteVdbeAddOp(v, OP_Recno, base, 0); } sqliteFree(aOrder); return pWInfo; } /* ** Generate the end of the WHERE loop. See comments on ** sqliteWhereBegin() for additional information. */ void sqliteWhereEnd(WhereInfo *pWInfo){ Vdbe *v = pWInfo->pParse->pVdbe; int i; int base = pWInfo->base; WhereLevel *pLevel; SrcList *pTabList = pWInfo->pTabList; |
︙ | ︙ |