Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Registers (aka memory cells) in the VM are now numbered starting with 1 instead of 0. A register number of 0 means "no such register". (CVS 4669) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
0b849805c3a0f562d50623f406279b40 |
User & Date: | drh 2008-01-03 18:03:09.000 |
Context
2008-01-03
| ||
18:39 | Modify VFilter and VRename to use registers instead of the vdbe stack for inputs. (CVS 4670) (check-in: 253ed40aa3 user: danielk1977 tags: trunk) | |
18:03 | Registers (aka memory cells) in the VM are now numbered starting with 1 instead of 0. A register number of 0 means "no such register". (CVS 4669) (check-in: 0b849805c3 user: drh tags: trunk) | |
17:31 | Modify OP_VUpdate to read arguments from a range of memory cells instead of from the stack. (CVS 4668) (check-in: 955b15a020 user: danielk1977 tags: trunk) | |
Changes
Changes to src/analyze.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2005 July 8 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code associated with the ANALYZE command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2005 July 8 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code associated with the ANALYZE command. ** ** @(#) $Id: analyze.c,v 1.30 2008/01/03 18:03:09 drh Exp $ */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" /* ** This routine generates code that opens the sqlite_stat1 table on cursor ** iStatCur. |
︙ | ︙ | |||
237 238 239 240 241 242 243 | HashElem *k; int iStatCur; int iMem; sqlite3BeginWriteOperation(pParse, 0, iDb); iStatCur = pParse->nTab++; openStatTable(pParse, iDb, iStatCur, 0); | | | 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | HashElem *k; int iStatCur; int iMem; sqlite3BeginWriteOperation(pParse, 0, iDb); iStatCur = pParse->nTab++; openStatTable(pParse, iDb, iStatCur, 0); iMem = pParse->nMem+1; for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ Table *pTab = (Table*)sqliteHashData(k); analyzeOneTable(pParse, pTab, iStatCur, iMem); } loadAnalysis(pParse, iDb); } |
︙ | ︙ | |||
259 260 261 262 263 264 265 | assert( pTab!=0 ); assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); sqlite3BeginWriteOperation(pParse, 0, iDb); iStatCur = pParse->nTab++; openStatTable(pParse, iDb, iStatCur, pTab->zName); | | | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | assert( pTab!=0 ); assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); sqlite3BeginWriteOperation(pParse, 0, iDb); iStatCur = pParse->nTab++; openStatTable(pParse, iDb, iStatCur, pTab->zName); analyzeOneTable(pParse, pTab, iStatCur, pParse->nMem+1); loadAnalysis(pParse, iDb); } /* ** Generate code for the ANALYZE command. The parser calls this routine ** when it recognizes an ANALYZE command. ** |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** ** $Id: build.c,v 1.456 2008/01/03 18:03:09 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. |
︙ | ︙ | |||
2624 2625 2626 2627 2628 2629 2630 | ** or UNIQUE constraint of a CREATE TABLE statement. Since the table ** has just been created, it contains no data and the index initialization ** step can be skipped. */ else if( db->init.busy==0 ){ Vdbe *v; char *zStmt; | | | 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 | ** or UNIQUE constraint of a CREATE TABLE statement. Since the table ** has just been created, it contains no data and the index initialization ** step can be skipped. */ else if( db->init.busy==0 ){ Vdbe *v; char *zStmt; int iMem = ++pParse->nMem; v = sqlite3GetVdbe(pParse); if( v==0 ) goto exit_create_index; /* Create the rootpage for the index */ |
︙ | ︙ |
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 ** in order to generate code for 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 ** in order to generate code for DELETE FROM statements. ** ** $Id: delete.c,v 1.144 2008/01/03 18:03:09 drh Exp $ */ #include "sqliteInt.h" /* ** Look up every table that is named in pSrc. If any table is not found, ** add an error message to pParse->zErrMsg and return NULL. If all tables ** are found, return a pointer to the last table. |
︙ | ︙ | |||
61 62 63 64 65 66 67 | } /* ** This function is a temporary measure required because OP_Insert now ** reads the key and data to insert from memory cells. */ void sqlite3CodeInsert(Parse *p, int iCur, u8 flags){ | | | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | } /* ** This function is a temporary measure required because OP_Insert now ** reads the key and data to insert from memory cells. */ void sqlite3CodeInsert(Parse *p, int iCur, u8 flags){ int iData = ++p->nMem; int iKey = ++p->nMem; Vdbe *v = sqlite3GetVdbe(p); sqlite3VdbeAddOp2(v, OP_MemStore, iData, 1); sqlite3VdbeAddOp2(v, OP_MemStore, iKey, 1); sqlite3VdbeAddOp3(v, OP_Insert, iCur, iData, iKey); sqlite3VdbeChangeP5(v, sqlite3VdbeCurrentAddr(v)-1, flags); } /* ** Allocate nVal contiguous memory cells and return the index of the ** first. Also pop nVal elements from the stack and store them in the ** registers. The element on the top of the stack is stored in the ** register with the largest index. */ int sqlite3StackToReg(Parse *p, int nVal){ int i; int iRet = p->nMem+1; Vdbe *v = sqlite3GetVdbe(p); assert(v); p->nMem += nVal; for(i=nVal-1; i>=0; i--){ sqlite3VdbeAddOp2(v, OP_MemStore, iRet+i, 1); } return iRet; |
︙ | ︙ | |||
259 260 261 262 263 264 265 | sqlite3SelectDelete(pView); } /* Initialize the counter of the number of rows deleted, if ** we are counting rows. */ if( db->flags & SQLITE_CountRows ){ | | | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | sqlite3SelectDelete(pView); } /* Initialize the counter of the number of rows deleted, if ** we are counting rows. */ if( db->flags & SQLITE_CountRows ){ memCnt = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_MemInt, 0, memCnt); } /* Special case: A DELETE without a WHERE clause deletes everything. ** It is easier just to erase the whole table. Note, however, that ** this means that the row change count will be incorrect. */ |
︙ | ︙ | |||
342 343 344 345 346 347 348 | if( triggers_exist ){ sqlite3VdbeResolveLabel(v, addr); } addr = sqlite3VdbeAddOp2(v, OP_FifoRead, 0, end); sqlite3VdbeAddOp1(v, OP_StackDepth, -1); if( triggers_exist ){ | | | 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | if( triggers_exist ){ sqlite3VdbeResolveLabel(v, addr); } addr = sqlite3VdbeAddOp2(v, OP_FifoRead, 0, end); sqlite3VdbeAddOp1(v, OP_StackDepth, -1); if( triggers_exist ){ int mem1 = ++pParse->nMem; if( !isView ){ sqlite3VdbeAddOp1(v, OP_MemStore, mem1); } sqlite3VdbeAddOp2(v, OP_NotExists, iCur, addr); sqlite3VdbeAddOp1(v, OP_Rowid, iCur); if( old_col_mask ){ sqlite3VdbeAddOp1(v, OP_RowData, iCur); |
︙ | ︙ |
Changes to src/expr.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 routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions 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 routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.327 2008/01/03 18:03:09 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
303 304 305 306 307 308 309 | } if( v==0 ) return 0; p = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, pToken); if( p==0 ){ return 0; /* Malloc failed */ } depth = atoi((char*)&pToken->z[1]); | | | 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 | } if( v==0 ) return 0; p = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, pToken); if( p==0 ){ return 0; /* Malloc failed */ } depth = atoi((char*)&pToken->z[1]); p->iTable = ++pParse->nMem; sqlite3VdbeAddOp1(v, OP_Dup, depth); sqlite3VdbeAddOp2(v, OP_MemStore, p->iTable, 1); return p; } /* ** Join two expressions using an AND operator. If either expression is |
︙ | ︙ | |||
1596 1597 1598 1599 1600 1601 1602 | /* This function is only called from two places. In both cases the vdbe ** has already been allocated. So assume sqlite3GetVdbe() is always ** successful here. */ assert(v); if( iCol<0 ){ | | | 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 | /* This function is only called from two places. In both cases the vdbe ** has already been allocated. So assume sqlite3GetVdbe() is always ** successful here. */ assert(v); if( iCol<0 ){ int iMem = ++pParse->nMem; int iAddr; Table *pTab = p->pSrc->a[0].pTab; int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeAddOp1(v, OP_MemLoad, iMem); iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem); |
︙ | ︙ | |||
1631 1632 1633 1634 1635 1636 1637 | for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){ if( (pIdx->aiColumn[0]==iCol) && (pReq==sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], -1, 0)) && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None)) ){ int iDb; | | | 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 | for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){ if( (pIdx->aiColumn[0]==iCol) && (pReq==sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], -1, 0)) && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None)) ){ int iDb; int iMem = ++pParse->nMem; int iAddr; char *pKey; pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx); iDb = sqlite3SchemaToIndex(db, pIdx->pSchema); sqlite3VdbeUsesBtree(v, iDb); |
︙ | ︙ | |||
1695 1696 1697 1698 1699 1700 1701 | ** * The right-hand side is an expression list containing variables ** * We are inside a trigger ** ** If all of the above are false, then we can run this code just once ** save the results, and reuse the same result on subsequent invocations. */ if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){ | | | 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 | ** * The right-hand side is an expression list containing variables ** * We are inside a trigger ** ** If all of the above are false, then we can run this code just once ** save the results, and reuse the same result on subsequent invocations. */ if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){ int mem = ++pParse->nMem; sqlite3VdbeAddOp1(v, OP_MemLoad, mem); testAddr = sqlite3VdbeAddOp0(v, OP_If); assert( testAddr>0 || pParse->db->mallocFailed ); sqlite3VdbeAddOp2(v, OP_MemInt, 1, mem); } switch( pExpr->op ){ |
︙ | ︙ | |||
1800 1801 1802 1803 1804 1805 1806 | ** of the memory cell in iColumn. */ static const Token one = { (u8*)"1", 0, 1 }; Select *pSel; SelectDest dest; pSel = pExpr->pSelect; | | | 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 | ** of the memory cell in iColumn. */ static const Token one = { (u8*)"1", 0, 1 }; Select *pSel; SelectDest dest; pSel = pExpr->pSelect; dest.iParm = ++pParse->nMem; if( pExpr->op==TK_SELECT ){ dest.eDest = SRT_Mem; sqlite3VdbeAddOp2(v, OP_MemNull, 0, dest.iParm); VdbeComment((v, "Init subquery result")); }else{ dest.eDest = SRT_Exists; sqlite3VdbeAddOp2(v, OP_MemInt, 0, dest.iParm); |
︙ | ︙ | |||
2339 2340 2341 2342 2343 2344 2345 | int addr1, addr2; if( v==0 ) return; addr1 = sqlite3VdbeCurrentAddr(v); sqlite3ExprCode(pParse, pExpr); addr2 = sqlite3VdbeCurrentAddr(v); if( addr2>addr1+1 || ((pOp = sqlite3VdbeGetOp(v, addr1))!=0 && pOp->opcode==OP_Function) ){ | | | | 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 | int addr1, addr2; if( v==0 ) return; addr1 = sqlite3VdbeCurrentAddr(v); sqlite3ExprCode(pParse, pExpr); addr2 = sqlite3VdbeCurrentAddr(v); if( addr2>addr1+1 || ((pOp = sqlite3VdbeGetOp(v, addr1))!=0 && pOp->opcode==OP_Function) ){ iMem = pExpr->iTable = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_MemStore, iMem, 0); pExpr->op = TK_REGISTER; } } #endif /* ** Generate code to evaluate an expression and store the result in ** a designated register. If the target register number is negative, ** allocate a new register to store the result. Return the target ** register number regardless. ** ** The current implementation is a rough prototype for experimental ** purposes. There are many optimization opportunities here. */ int sqlite3ExprIntoReg(Parse *pParse, Expr *pExpr, int target){ Vdbe *v = pParse->pVdbe; if( v==0 ) return -1; sqlite3ExprCode(pParse, pExpr); if( target<0 ){ target = ++pParse->nMem; } sqlite3VdbeAddOp2(v, OP_MemStore, target, 1); return target; } /* ** Generate code that pushes the value of every element of the given |
︙ | ︙ | |||
2720 2721 2722 2723 2724 2725 2726 | if( (k>=pAggInfo->nColumn) && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 ){ pCol = &pAggInfo->aCol[k]; pCol->pTab = pExpr->pTab; pCol->iTable = pExpr->iTable; pCol->iColumn = pExpr->iColumn; | | | 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 | if( (k>=pAggInfo->nColumn) && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 ){ pCol = &pAggInfo->aCol[k]; pCol->pTab = pExpr->pTab; pCol->iTable = pExpr->iTable; pCol->iColumn = pExpr->iColumn; pCol->iMem = ++pParse->nMem; pCol->iSorterColumn = -1; pCol->pExpr = pExpr; if( pAggInfo->pGroupBy ){ int j, n; ExprList *pGB = pAggInfo->pGroupBy; struct ExprList_item *pTerm = pGB->a; n = pGB->nExpr; |
︙ | ︙ | |||
2776 2777 2778 2779 2780 2781 2782 | /* pExpr is original. Make a new entry in pAggInfo->aFunc[] */ u8 enc = ENC(pParse->db); i = addAggInfoFunc(pParse->db, pAggInfo); if( i>=0 ){ pItem = &pAggInfo->aFunc[i]; pItem->pExpr = pExpr; | | | 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 | /* pExpr is original. Make a new entry in pAggInfo->aFunc[] */ u8 enc = ENC(pParse->db); i = addAggInfoFunc(pParse->db, pAggInfo); if( i>=0 ){ pItem = &pAggInfo->aFunc[i]; pItem->pExpr = pExpr; pItem->iMem = ++pParse->nMem; pItem->pFunc = sqlite3FindFunction(pParse->db, (char*)pExpr->token.z, pExpr->token.n, pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0); if( pExpr->flags & EP_Distinct ){ pItem->iDistinct = pParse->nTab++; }else{ pItem->iDistinct = -1; |
︙ | ︙ |
Changes to src/insert.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 INSERT 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 INSERT statements in SQLite. ** ** $Id: insert.c,v 1.207 2008/01/03 18:03:09 drh Exp $ */ #include "sqliteInt.h" /* ** Set P4 of the most recently inserted opcode to a column affinity ** string for index pIdx. A column affinity string has one character ** for each column in the table, according to the affinity of the column: |
︙ | ︙ | |||
142 143 144 145 146 147 148 | ** autoIncStep() will keep that memory cell holding the largest ** rowid value. Code generated by autoIncEnd() will write the new ** largest value of the counter back into the sqlite_sequence table. ** ** This routine returns the index of the mem[] cell that contains ** the maximum rowid counter. ** | | | | | 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 | ** autoIncStep() will keep that memory cell holding the largest ** rowid value. Code generated by autoIncEnd() will write the new ** largest value of the counter back into the sqlite_sequence table. ** ** This routine returns the index of the mem[] cell that contains ** the maximum rowid counter. ** ** Two memory cells are allocated. The next memory cell befor the ** one returned holds the rowid in sqlite_sequence where we will ** write back the revised maximum rowid. */ static int autoIncBegin( Parse *pParse, /* Parsing context */ int iDb, /* Index of the database holding pTab */ Table *pTab /* The table we are writing to */ ){ int memId = 0; if( pTab->autoInc ){ Vdbe *v = pParse->pVdbe; Db *pDb = &pParse->db->aDb[iDb]; int iCur = pParse->nTab; int addr; assert( v ); addr = sqlite3VdbeCurrentAddr(v); pParse->nMem += 2; memId = pParse->nMem; sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenRead); sqlite3VdbeAddOp2(v, OP_Rewind, iCur, addr+12); sqlite3VdbeAddOp2(v, OP_Column, iCur, 0); sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0); sqlite3VdbeAddOp2(v, OP_Ne, 0x100, addr+11); sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0); sqlite3VdbeAddOp2(v, OP_MemStore, memId-1, 1); |
︙ | ︙ | |||
614 615 616 617 618 619 620 | sqlite3VdbeAddOp2(v, OP_OpenPseudo, newIdx, 0); sqlite3VdbeAddOp2(v, OP_SetNumColumns, newIdx, pTab->nCol); } /* Initialize the count of rows to be inserted */ if( db->flags & SQLITE_CountRows ){ | | | 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 | sqlite3VdbeAddOp2(v, OP_OpenPseudo, newIdx, 0); sqlite3VdbeAddOp2(v, OP_SetNumColumns, newIdx, pTab->nCol); } /* Initialize the count of rows to be inserted */ if( db->flags & SQLITE_CountRows ){ iCntMem = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_MemInt, 0, iCntMem); } /* If this is not a view, open the table and and all indices */ if( !isView ){ base = pParse->nTab; sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite); |
︙ | ︙ |
Changes to src/pragma.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** ** $Id: pragma.c,v 1.157 2008/01/03 18:03:09 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* Ignore this whole file if pragmas are disabled */ #if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER) |
︙ | ︙ | |||
143 144 145 146 147 148 149 | #endif /* SQLITE_PAGER_PRAGMAS */ /* ** Generate code to return a single integer value. */ static void returnSingleInt(Parse *pParse, const char *zLabel, int value){ Vdbe *v = sqlite3GetVdbe(pParse); | | | 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | #endif /* SQLITE_PAGER_PRAGMAS */ /* ** Generate code to return a single integer value. */ static void returnSingleInt(Parse *pParse, const char *zLabel, int value){ Vdbe *v = sqlite3GetVdbe(pParse); int mem = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_MemInt, value, mem); if( pParse->explain==0 ){ sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, P4_STATIC); } sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); } |
︙ | ︙ | |||
488 489 490 491 492 493 494 | if( sqlite3ReadSchema(pParse) ){ goto pragma_out; } if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ iLimit = 0x7fffffff; } sqlite3BeginWriteOperation(pParse, 0, iDb); | | | | | 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 | if( sqlite3ReadSchema(pParse) ){ goto pragma_out; } if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ iLimit = 0x7fffffff; } sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp2(v, OP_MemInt, iLimit, 1); addr = sqlite3VdbeAddOp2(v, OP_IncrVacuum, iDb, 0); sqlite3VdbeAddOp2(v, OP_Callback, 0, 0); sqlite3VdbeAddOp2(v, OP_MemIncr, -1, 1); sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, addr); sqlite3VdbeJumpHere(v, addr); }else #endif #ifndef SQLITE_OMIT_PAGER_PRAGMAS /* ** PRAGMA [database.]cache_size |
︙ | ︙ | |||
826 827 828 829 830 831 832 | int i, j, addr, mxErr; /* Code that appears at the end of the integrity check. If no error ** messages have been generated, output OK. Otherwise output the ** error message */ static const VdbeOpList endCode[] = { | | | 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 | int i, j, addr, mxErr; /* Code that appears at the end of the integrity check. If no error ** messages have been generated, output OK. Otherwise output the ** error message */ static const VdbeOpList endCode[] = { { OP_MemLoad, 1, 0, 0}, { OP_Integer, 0, 0, 0}, { OP_Ne, 0, 0, 0}, /* 2 */ { OP_String8, 0, 0, 0}, /* 3 */ { OP_Callback, 1, 0, 0}, }; int isQuick = (zLeft[0]=='q'); |
︙ | ︙ | |||
848 849 850 851 852 853 854 | mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; if( zRight ){ mxErr = atoi(zRight); if( mxErr<=0 ){ mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; } } | | | | | | | | | | | | | | | 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 | mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; if( zRight ){ mxErr = atoi(zRight); if( mxErr<=0 ){ mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; } } sqlite3VdbeAddOp2(v, OP_MemInt, mxErr, 1); /* Do an integrity check on each database file */ for(i=0; i<db->nDb; i++){ HashElem *x; Hash *pTbls; int cnt = 0; if( OMIT_TEMPDB && i==1 ) continue; sqlite3CodeVerifySchema(pParse, i); addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, 0); sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); /* Do an integrity check of the B-Tree */ pTbls = &db->aDb[i].pSchema->tblHash; for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 0); cnt++; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 0); cnt++; } } if( cnt==0 ) continue; sqlite3VdbeAddOp2(v, OP_IntegrityCk, 1, i); addr = sqlite3VdbeAddOp2(v, OP_IsNull, -1, 0); sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), P4_DYNAMIC); sqlite3VdbeAddOp2(v, OP_Pull, 1, 0); sqlite3VdbeAddOp2(v, OP_Concat, 0, 0); sqlite3VdbeAddOp2(v, OP_Callback, 1, 0); sqlite3VdbeJumpHere(v, addr); /* Make sure all the indices are constructed correctly. */ for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; int loopTop; if( pTab->pIndex==0 ) continue; addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, 0); sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead); sqlite3VdbeAddOp2(v, OP_MemInt, 0, 2); loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0); sqlite3VdbeAddOp2(v, OP_MemIncr, 1, 2); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int jmp2; static const VdbeOpList idxErr[] = { { OP_MemIncr, -1, 1, 0}, { OP_String8, 0, 0, 0}, /* 1 */ { OP_Rowid, 1, 0, 0}, { OP_String8, 0, 0, 0}, /* 3 */ { OP_String8, 0, 0, 0}, /* 4 */ { OP_Concat, 2, 0, 0}, { OP_Callback, 1, 0, 0}, }; sqlite3GenerateIndexKey(v, pIdx, 1); jmp2 = sqlite3VdbeAddOp2(v, OP_Found, j+2, 0); addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr); sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC); sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC); sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_STATIC); sqlite3VdbeJumpHere(v, jmp2); } sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1); sqlite3VdbeJumpHere(v, loopTop); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ static const VdbeOpList cntIdx[] = { { OP_MemInt, 0, 3, 0}, { OP_Rewind, 0, 0, 0}, /* 1 */ { OP_MemIncr, 1, 3, 0}, { OP_Next, 0, 0, 0}, /* 3 */ { OP_MemLoad, 2, 0, 0}, { OP_MemLoad, 3, 0, 0}, { OP_Eq, 0, 0, 0}, /* 6 */ { OP_MemIncr, -1, 1, 0}, { OP_String8, 0, 0, 0}, /* 8 */ { OP_String8, 0, 0, 0}, /* 9 */ { OP_Concat, 0, 0, 0}, { OP_Callback, 1, 0, 0}, }; if( pIdx->tnum==0 ) continue; addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, 0); sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx); sqlite3VdbeChangeP1(v, addr+1, j+2); sqlite3VdbeChangeP2(v, addr+1, addr+4); sqlite3VdbeChangeP1(v, addr+3, j+2); sqlite3VdbeChangeP2(v, addr+3, addr+2); |
︙ | ︙ |
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.381 2008/01/03 18:03:09 drh Exp $ */ #include "sqliteInt.h" /* ** Delete all the content of a Select structure but do not deallocate ** the select structure itself. |
︙ | ︙ | |||
537 538 539 540 541 542 543 | /* Pull the requested columns. */ if( nColumn>0 ){ n = nColumn; }else{ n = pEList->nExpr; } | | | 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 | /* Pull the requested columns. */ if( nColumn>0 ){ n = nColumn; }else{ n = pEList->nExpr; } iMem = ++pParse->nMem; pParse->nMem += n+1; sqlite3VdbeAddOp2(v, OP_MemInt, n, iMem); if( nColumn>0 ){ for(i=0; i<nColumn; i++){ sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, iMem+i+1); } }else if( eDest!=SRT_Exists ){ |
︙ | ︙ | |||
1742 1743 1744 1745 1746 1747 1748 | /* ** "LIMIT -1" always shows all rows. There is some ** contraversy about what the correct behavior should be. ** The current implementation interprets "LIMIT 0" to mean ** no rows. */ if( p->pLimit ){ | | | | | 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 | /* ** "LIMIT -1" always shows all rows. There is some ** contraversy about what the correct behavior should be. ** The current implementation interprets "LIMIT 0" to mean ** no rows. */ if( p->pLimit ){ p->iLimit = iLimit = ++pParse->nMem; pParse->nMem++; v = sqlite3GetVdbe(pParse); if( v==0 ) return; sqlite3ExprCode(pParse, p->pLimit); sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0); sqlite3VdbeAddOp2(v, OP_MemStore, iLimit, 1); VdbeComment((v, "LIMIT counter")); sqlite3VdbeAddOp2(v, OP_IfMemZero, iLimit, iBreak); sqlite3VdbeAddOp2(v, OP_MemLoad, iLimit, 0); } if( p->pOffset ){ p->iOffset = iOffset = ++pParse->nMem; v = sqlite3GetVdbe(pParse); if( v==0 ) return; sqlite3ExprCode(pParse, p->pOffset); sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0); sqlite3VdbeAddOp2(v, OP_MemStore, iOffset, p->pLimit==0); VdbeComment((v, "OFFSET counter")); addr1 = sqlite3VdbeAddOp2(v, OP_IfMemPos, iOffset, 0); |
︙ | ︙ | |||
3445 3446 3447 3448 3449 3450 3451 | addrSortingIdx = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF); /* Initialize memory locations used by GROUP BY aggregate processing */ | | | | | | 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 | addrSortingIdx = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF); /* Initialize memory locations used by GROUP BY aggregate processing */ iUseFlag = ++pParse->nMem; iAbortFlag = ++pParse->nMem; iAMem = pParse->nMem + 1; pParse->nMem += pGroupBy->nExpr; iBMem = pParse->nMem + 1; pParse->nMem += pGroupBy->nExpr; sqlite3VdbeAddOp2(v, OP_MemInt, 0, iAbortFlag); VdbeComment((v, "clear abort flag")); sqlite3VdbeAddOp2(v, OP_MemInt, 0, iUseFlag); VdbeComment((v, "indicate accumulator empty")); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrInitializeLoop); |
︙ | ︙ |
Changes to src/trigger.c.
︙ | ︙ | |||
239 240 241 242 243 244 245 | { OP_MakeRecord, 5, 0, 0 }, /* 8: "aaada" */ { OP_MemStore, 0, 1, 0 }, /* 9: Store data */ { OP_MemStore, 0, 1, 0 }, /* 10: Store key */ { OP_Insert, 0, 0, 0 }, }; int addr; Vdbe *v; | | | | 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | { OP_MakeRecord, 5, 0, 0 }, /* 8: "aaada" */ { OP_MemStore, 0, 1, 0 }, /* 9: Store data */ { OP_MemStore, 0, 1, 0 }, /* 10: Store key */ { OP_Insert, 0, 0, 0 }, }; int addr; Vdbe *v; int iKey = ++pParse->nMem; int iData = ++pParse->nMem; /* Make an entry in the sqlite_master table */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto triggerfinish_cleanup; sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3OpenMasterTable(pParse, iDb); addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig); |
︙ | ︙ |
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.154 2008/01/03 18:03:09 drh Exp $ */ #include "sqliteInt.h" #ifndef SQLITE_OMIT_VIRTUALTABLE /* Forward declaration */ static void updateVirtualTable( Parse *pParse, /* The parsing context */ |
︙ | ︙ | |||
264 265 266 267 268 269 270 | /* Begin generating code. */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto update_cleanup; if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); sqlite3BeginWriteOperation(pParse, 1, iDb); | | | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | /* Begin generating code. */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto update_cleanup; if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); sqlite3BeginWriteOperation(pParse, 1, iDb); mem1 = ++pParse->nMem; #ifndef SQLITE_OMIT_VIRTUALTABLE /* Virtual tables must be handled separately */ if( IsVirtual(pTab) ){ updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef, pWhere); pWhere = 0; |
︙ | ︙ | |||
349 350 351 352 353 354 355 | /* End the database scan loop. */ sqlite3WhereEnd(pWInfo); /* Initialize the count of updated rows */ if( db->flags & SQLITE_CountRows && !pParse->trigStack ){ | | | 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | /* End the database scan loop. */ sqlite3WhereEnd(pWInfo); /* Initialize the count of updated rows */ if( db->flags & SQLITE_CountRows && !pParse->trigStack ){ memCnt = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_MemInt, 0, memCnt); } if( !isView && !IsVirtual(pTab) ){ /* ** Open every index that needs updating. Note that if any ** index could potentially invoke a REPLACE conflict resolution |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.671 2008/01/03 18:03:09 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
1036 1037 1038 1039 1040 1041 1042 | ** values will be automatically popped from the stack before the next ** instruction executes. */ case OP_ResultRow: { /* no-push */ Mem *pMem; int i; assert( p->nResColumn==pOp->p2 ); | | | | 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 | ** values will be automatically popped from the stack before the next ** instruction executes. */ case OP_ResultRow: { /* no-push */ Mem *pMem; int i; assert( p->nResColumn==pOp->p2 ); assert( pOp->p1>0 ); assert( pOp->p1+pOp->p2<=p->nMem ); /* Data in the pager might be moved or changed out from under us ** in between the return from this sqlite3_step() call and the ** next call to sqlite3_step(). So deephermeralize everything on ** the stack. Note that ephemeral data is never stored in memory ** cells so we do not have to worry about them. */ |
︙ | ︙ | |||
2387 2388 2389 2390 2391 2392 2393 | } jumpIfNull = pOp->p2; addRowid = pOp->opcode==OP_MakeIdxRec || pOp->opcode==OP_RegMakeIRec; zAffinity = pOp->p4.z; if( pOp->opcode==OP_RegMakeRec || pOp->opcode==OP_RegMakeIRec ){ Mem *pCount; | | | | 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 | } jumpIfNull = pOp->p2; addRowid = pOp->opcode==OP_MakeIdxRec || pOp->opcode==OP_RegMakeIRec; zAffinity = pOp->p4.z; if( pOp->opcode==OP_RegMakeRec || pOp->opcode==OP_RegMakeIRec ){ Mem *pCount; assert( nField>0 && nField<=p->nMem ); pCount = &p->aMem[nField]; assert( pCount->flags & MEM_Int ); assert( pCount->u.i>0 && pCount->u.i+nField<=p->nMem ); leaveOnStack = 1; nField = pCount->u.i; pData0 = &pCount[1]; pLast = &pData0[nField-1]; }else{ pData0 = &pTos[1-nField]; pLast = pTos; |
︙ | ︙ | |||
3497 3498 3499 3500 3501 3502 3503 | } } } #ifndef SQLITE_OMIT_AUTOINCREMENT if( pOp->p2 ){ Mem *pMem; | | | 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 | } } } #ifndef SQLITE_OMIT_AUTOINCREMENT if( pOp->p2 ){ Mem *pMem; assert( pOp->p2>0 && pOp->p2<=p->nMem ); /* P2 is a valid memory cell */ pMem = &p->aMem[pOp->p2]; sqlite3VdbeMemIntegerify(pMem); assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P2) holds an integer */ if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ rc = SQLITE_FULL; goto abort_due_to_error; } |
︙ | ︙ | |||
4448 4449 4450 4451 4452 4453 4454 | for(nRoot=0; &pTos[-nRoot]>=p->aStack; nRoot++){ if( (pTos[-nRoot].flags & MEM_Int)==0 ) break; } assert( nRoot>0 ); aRoot = sqlite3_malloc( sizeof(int)*(nRoot+1) ); if( aRoot==0 ) goto no_mem; j = pOp->p1; | | | 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 | for(nRoot=0; &pTos[-nRoot]>=p->aStack; nRoot++){ if( (pTos[-nRoot].flags & MEM_Int)==0 ) break; } assert( nRoot>0 ); aRoot = sqlite3_malloc( sizeof(int)*(nRoot+1) ); if( aRoot==0 ) goto no_mem; j = pOp->p1; assert( j>0 && j<=p->nMem ); pnErr = &p->aMem[j]; assert( (pnErr->flags & MEM_Int)!=0 ); for(j=0; j<nRoot; j++){ aRoot[j] = (pTos-j)->u.i; } aRoot[j] = 0; popStack(&pTos, nRoot); |
︙ | ︙ | |||
4569 4570 4571 4572 4573 4574 4575 | ** ** After the data is stored in the memory location, the ** stack is popped once if P2 is 1. If P2 is zero, then ** the original data remains on the stack. */ case OP_MemStore: { /* no-push */ assert( pTos>=p->aStack ); | | | 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 | ** ** After the data is stored in the memory location, the ** stack is popped once if P2 is 1. If P2 is zero, then ** the original data remains on the stack. */ case OP_MemStore: { /* no-push */ assert( pTos>=p->aStack ); assert( pOp->p1>0 && pOp->p1<=p->nMem ); rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], pTos); pTos--; /* If P2 is 0 then fall thru to the next opcode, OP_MemLoad, that will ** restore the top of the stack to its original value. */ if( pOp->p2 ){ |
︙ | ︙ | |||
4591 4592 4593 4594 4595 4596 4597 | ** If the value is a string, then the value pushed is a pointer to ** the string that is stored in the memory location. If the memory ** location is subsequently changed (using OP_MemStore) then the ** value pushed onto the stack will change too. */ case OP_MemLoad: { int i = pOp->p1; | | | | | | | | | | | | | 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 | ** If the value is a string, then the value pushed is a pointer to ** the string that is stored in the memory location. If the memory ** location is subsequently changed (using OP_MemStore) then the ** value pushed onto the stack will change too. */ case OP_MemLoad: { int i = pOp->p1; assert( i>0 && i<=p->nMem ); pTos++; sqlite3VdbeMemShallowCopy(pTos, &p->aMem[i], MEM_Ephem); break; } #ifndef SQLITE_OMIT_AUTOINCREMENT /* Opcode: MemMax P1 * * ** ** Set the value of memory cell P1 to the maximum of its current value ** and the value on the top of the stack. The stack is unchanged. ** ** This instruction throws an error if the memory cell is not initially ** an integer. */ case OP_MemMax: { /* no-push */ int i = pOp->p1; Mem *pMem; assert( pTos>=p->aStack ); assert( i>0 && i<=p->nMem ); pMem = &p->aMem[i]; sqlite3VdbeMemIntegerify(pMem); sqlite3VdbeMemIntegerify(pTos); if( pMem->u.i<pTos->u.i){ pMem->u.i = pTos->u.i; } break; } #endif /* SQLITE_OMIT_AUTOINCREMENT */ /* Opcode: MemIncr P1 P2 * ** ** Increment the integer valued memory cell P2 by the value in P1. ** ** It is illegal to use this instruction on a memory cell that does ** not contain an integer. An assertion fault will result if you try. */ case OP_MemIncr: { /* no-push */ int i = pOp->p2; Mem *pMem; assert( i>0 && i<=p->nMem ); pMem = &p->aMem[i]; assert( pMem->flags==MEM_Int ); pMem->u.i += pOp->p1; break; } /* Opcode: IfMemPos P1 P2 * ** ** If the value of memory cell P1 is 1 or greater, jump to P2. ** ** It is illegal to use this instruction on a memory cell that does ** not contain an integer. An assertion fault will result if you try. */ case OP_IfMemPos: { /* no-push */ int i = pOp->p1; Mem *pMem; assert( i>0 && i<=p->nMem ); pMem = &p->aMem[i]; assert( pMem->flags==MEM_Int ); if( pMem->u.i>0 ){ pc = pOp->p2 - 1; } break; } /* Opcode: IfMemNeg P1 P2 * ** ** If the value of memory cell P1 is less than zero, jump to P2. ** ** It is illegal to use this instruction on a memory cell that does ** not contain an integer. An assertion fault will result if you try. */ case OP_IfMemNeg: { /* no-push */ int i = pOp->p1; Mem *pMem; assert( i>0 && i<=p->nMem ); pMem = &p->aMem[i]; assert( pMem->flags==MEM_Int ); if( pMem->u.i<0 ){ pc = pOp->p2 - 1; } break; } /* Opcode: IfMemZero P1 P2 * ** ** If the value of memory cell P1 is exactly 0, jump to P2. ** ** It is illegal to use this instruction on a memory cell that does ** not contain an integer. An assertion fault will result if you try. */ case OP_IfMemZero: { /* no-push */ int i = pOp->p1; Mem *pMem; assert( i>0 && i<=p->nMem ); pMem = &p->aMem[i]; assert( pMem->flags==MEM_Int ); if( pMem->u.i==0 ){ pc = pOp->p2 - 1; } break; } /* Opcode: IfMemNull P1 P2 * ** ** If the value of memory cell P1 is NULL, jump to P2. */ case OP_IfMemNull: { /* no-push */ int i = pOp->p1; assert( i>0 && i<=p->nMem ); if( p->aMem[i].flags & MEM_Null ){ pc = pOp->p2 - 1; } break; } /* Opcode: MemNull * P2 * ** ** Store a NULL in memory cell P2 */ case OP_MemNull: { assert( pOp->p2>0 && pOp->p2<=p->nMem ); sqlite3VdbeMemSetNull(&p->aMem[pOp->p2]); break; } /* Opcode: MemInt P1 P2 * ** ** Store the integer value P1 in memory cell P2. */ case OP_MemInt: { assert( pOp->p2>0 && pOp->p2<=p->nMem ); sqlite3VdbeMemSetInt64(&p->aMem[pOp->p2], pOp->p1); break; } /* Opcode: MemMove P1 P2 * ** ** Move the content of memory cell P2 over to memory cell P1. ** Any prior content of P1 is erased. Memory cell P2 is left ** containing a NULL. */ case OP_MemMove: { assert( pOp->p1>0 && pOp->p1<=p->nMem ); assert( pOp->p2>0 && pOp->p2<=p->nMem ); rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], &p->aMem[pOp->p2]); break; } /* Opcode: AggStep P1 P2 P4 ** ** Execute the step function for an aggregate. The |
︙ | ︙ | |||
4767 4768 4769 4770 4771 4772 4773 | apVal = p->apArg; assert( apVal || n==0 ); for(i=0; i<n; i++, pRec++){ apVal[i] = pRec; storeTypeInfo(pRec, encoding); } ctx.pFunc = pOp->p4.pFunc; | | | 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 | apVal = p->apArg; assert( apVal || n==0 ); for(i=0; i<n; i++, pRec++){ apVal[i] = pRec; storeTypeInfo(pRec, encoding); } ctx.pFunc = pOp->p4.pFunc; assert( pOp->p1>0 && pOp->p1<=p->nMem ); ctx.pMem = pMem = &p->aMem[pOp->p1]; pMem->n++; ctx.s.flags = MEM_Null; ctx.s.z = 0; ctx.s.xDel = 0; ctx.s.db = db; ctx.isError = 0; |
︙ | ︙ | |||
4806 4807 4808 4809 4810 4811 4812 | ** argument is not used by this opcode. It is only there to disambiguate ** functions that can take varying numbers of arguments. The ** P4 argument is only needed for the degenerate case where ** the step function was not previously called. */ case OP_AggFinal: { /* no-push */ Mem *pMem; | | | 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 | ** argument is not used by this opcode. It is only there to disambiguate ** functions that can take varying numbers of arguments. The ** P4 argument is only needed for the degenerate case where ** the step function was not previously called. */ case OP_AggFinal: { /* no-push */ Mem *pMem; assert( pOp->p1>0 && pOp->p1<=p->nMem ); pMem = &p->aMem[pOp->p1]; assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); if( rc==SQLITE_ERROR ){ sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pMem), (char*)0); } if( sqlite3VdbeMemTooBig(pMem) ){ |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
967 968 969 970 971 972 973 | int nArg; /* Maximum number of args passed to a user function. */ int nStack; /* Maximum number of stack entries required */ resolveP2Values(p, &nArg, &nStack); resizeOpArray(p, p->nOp); assert( nVar>=0 ); assert( nStack<p->nOp ); if( isExplain ){ | | | | | | | | 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 | int nArg; /* Maximum number of args passed to a user function. */ int nStack; /* Maximum number of stack entries required */ resolveP2Values(p, &nArg, &nStack); resizeOpArray(p, p->nOp); assert( nVar>=0 ); assert( nStack<p->nOp ); if( isExplain ){ nStack = 16; } p->aStack = sqlite3DbMallocZero(db, nStack*sizeof(p->aStack[0]) /* aStack */ + nArg*sizeof(Mem*) /* apArg */ + nVar*sizeof(Mem) /* aVar */ + nVar*sizeof(char*) /* azVar */ + nMem*sizeof(Mem) /* aMem */ + nCursor*sizeof(Cursor*) + 1 /* apCsr */ ); if( !db->mallocFailed ){ p->aMem = &p->aStack[nStack-1]; /* aMem[] goes from 1..nMem */ p->nMem = nMem; /* not from 0..nMem-1 */ p->aVar = &p->aMem[nMem+1]; p->nVar = nVar; p->okVar = 0; p->apArg = (Mem**)&p->aVar[nVar]; p->azVar = (char**)&p->apArg[nArg]; p->apCsr = (Cursor**)&p->azVar[nVar]; p->nCursor = nCursor; for(n=0; n<nVar; n++){ p->aVar[n].flags = MEM_Null; p->aVar[n].db = db; } for(n=0; n<nStack; n++){ p->aStack[n].db = db; } } } for(n=1; n<=p->nMem; n++){ p->aMem[n].flags = MEM_Null; p->aMem[n].db = db; } p->pTos = &p->aStack[-1]; p->pc = -1; p->rc = SQLITE_OK; |
︙ | ︙ | |||
1085 1086 1087 1088 1089 1090 1091 | static void Cleanup(Vdbe *p){ int i; if( p->aStack ){ releaseMemArray(p->aStack, 1 + (p->pTos - p->aStack)); p->pTos = &p->aStack[-1]; } closeAllCursorsExceptActiveVtabs(p); | | | 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 | static void Cleanup(Vdbe *p){ int i; if( p->aStack ){ releaseMemArray(p->aStack, 1 + (p->pTos - p->aStack)); p->pTos = &p->aStack[-1]; } closeAllCursorsExceptActiveVtabs(p); releaseMemArray(&p->aMem[1], p->nMem); sqlite3VdbeFifoClear(&p->sFifo); if( p->contextStack ){ for(i=0; i<p->contextStackTop; i++){ sqlite3VdbeFifoClear(&p->contextStack[i].sFifo); } sqlite3_free(p->contextStack); } |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** ** $Id: where.c,v 1.270 2008/01/03 18:03:09 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
1804 1805 1806 1807 1808 1809 1810 | int j; /* Loop counter */ /* Figure out how many memory cells we will need then allocate them. ** We always need at least one used to store the loop terminator ** value. If there are IN operators we'll need one for each == or ** IN constraint. */ | | | 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 | int j; /* Loop counter */ /* Figure out how many memory cells we will need then allocate them. ** We always need at least one used to store the loop terminator ** value. If there are IN operators we'll need one for each == or ** IN constraint. */ pLevel->iMem = ++pParse->nMem; if( pLevel->flags & WHERE_COLUMN_IN ){ pParse->nMem += pLevel->nEq; termsInMem = 1; } /* Evaluate the equality constraints */ |
︙ | ︙ | |||
2256 2257 2258 2259 2260 2261 2262 | cont = pLevel->cont = sqlite3VdbeMakeLabel(v); /* If this is the right table of a LEFT OUTER JOIN, allocate and ** initialize a memory cell that records if this table matches any ** row of the left table of the join. */ if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){ | < | | 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 | cont = pLevel->cont = sqlite3VdbeMakeLabel(v); /* If this is the right table of a LEFT OUTER JOIN, allocate and ** initialize a memory cell that records if this table matches any ** row of the left table of the join. */ if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){ pLevel->iLeftJoin = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_MemInt, 0, pLevel->iLeftJoin); VdbeComment((v, "init LEFT JOIN no-match flag")); } #ifndef SQLITE_OMIT_VIRTUALTABLE if( pLevel->pBestIdx ){ /* Case 0: The table is a virtual-table. Use the VFilter and VNext |
︙ | ︙ | |||
2354 2355 2356 2357 2358 2359 2360 | } if( pEnd ){ Expr *pX; pX = pEnd->pExpr; assert( pX!=0 ); assert( pEnd->leftCursor==iCur ); sqlite3ExprCode(pParse, pX->pRight); | | | 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 | } if( pEnd ){ Expr *pX; pX = pEnd->pExpr; assert( pX!=0 ); assert( pEnd->leftCursor==iCur ); sqlite3ExprCode(pParse, pX->pRight); pLevel->iMem = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 1); if( pX->op==TK_LT || pX->op==TK_GT ){ testOp = bRev ? OP_Le : OP_Ge; }else{ testOp = bRev ? OP_Lt : OP_Gt; } disableTerm(pLevel, pEnd); |
︙ | ︙ | |||
2446 2447 2448 2449 2450 2451 2452 | testOp = OP_IdxGE; }else{ testOp = nEq>0 ? OP_IdxGE : OP_Noop; topEq = 1; } if( testOp!=OP_Noop ){ int nCol = nEq + topLimit; | | | 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 | testOp = OP_IdxGE; }else{ testOp = nEq>0 ? OP_IdxGE : OP_Noop; topEq = 1; } if( testOp!=OP_Noop ){ int nCol = nEq + topLimit; pLevel->iMem = ++pParse->nMem; buildIndexProbe(v, nCol, pIdx); if( bRev ){ int op = topEq ? OP_MoveLe : OP_MoveLt; sqlite3VdbeAddOp2(v, op, iIdxCur, nxt); }else{ sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 1); } |
︙ | ︙ | |||
2485 2486 2487 2488 2489 2490 2491 | }else{ btmEq = 1; } if( nEq>0 || btmLimit ){ int nCol = nEq + btmLimit; buildIndexProbe(v, nCol, pIdx); if( bRev ){ | | | 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 | }else{ btmEq = 1; } if( nEq>0 || btmLimit ){ int nCol = nEq + btmLimit; buildIndexProbe(v, nCol, pIdx); if( bRev ){ pLevel->iMem = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 1); testOp = OP_IdxLT; }else{ int op = btmEq ? OP_MoveGe : OP_MoveGt; sqlite3VdbeAddOp2(v, op, iIdxCur, nxt); } }else if( bRev ){ |
︙ | ︙ |