Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Implement the out2-prerelease opcode design pattern. (CVS 4681) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
fe057a88d0038ac349ea41883b979ceb |
User & Date: | drh 2008-01-04 22:01:03.000 |
Context
2008-01-05
| ||
04:06 | Get rid of OP_Dup, OP_MemStore, OP_MemLoad, and OP_MemMove. Replace with OP_Copy, OP_SCopy, and OP_Move. Add the infrastructure for operation properties in1, in2, in3, out2, and out3 but do not yet use any of these. (CVS 4682) (check-in: cc149eb9ca user: drh tags: trunk) | |
2008-01-04
| ||
22:01 | Implement the out2-prerelease opcode design pattern. (CVS 4681) (check-in: fe057a88d0 user: drh tags: trunk) | |
19:33 | Allow the P2 operand to be negative on opcodes that are not jumps. (CVS 4680) (check-in: 717bcd11a2 user: drh tags: trunk) | |
Changes
Changes to mkopcodeh.awk.
︙ | ︙ | |||
46 47 48 49 50 51 52 | # Scan for "case OP_aaaa:" lines in the vdbe.c file /^case OP_/ { name = $2 sub(/:/,"",name) sub("\r","",name) op[name] = -1 | < < < | | < < | | | < < < < | < < < < < < | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | # Scan for "case OP_aaaa:" lines in the vdbe.c file /^case OP_/ { name = $2 sub(/:/,"",name) sub("\r","",name) op[name] = -1 jump[name] = 0 nopush[name] = 0 out2_prerelease[name] = 0 for(i=3; i<NF; i++){ if($i=="same" && $(i+1)=="as"){ sym = $(i+2) sub(/,/,"",sym) op[name] = tk[sym] used[op[name]] = 1 sameas[op[name]] = sym } x = $i sub(",","",x) if(x=="no-push"){ nopush[name] = 1 }else if(x=="jump"){ jump[name] = 1 }else if(x=="out2-prerelease"){ out2_prerelease[name] = 1 } } } # Assign numbers to all opcodes and output the result. END { cnt = 0 |
︙ | ︙ | |||
119 120 121 122 123 124 125 | printf "#define %-25s %15d\n", sprintf( "OP_NotUsed_%-3d", i ), i } } # Generate the bitvectors: # # bit 0: jump | | | < < < < < < < < < < < | > | | | < < < < < | | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | printf "#define %-25s %15d\n", sprintf( "OP_NotUsed_%-3d", i ), i } } # Generate the bitvectors: # # bit 0: jump # bit 1: pushes a result onto stack # bit 2: output to p1. release p1 before opcode runs # for(i=0; i<=max; i++) bv[i] = 0; for(name in op){ x = op[name] a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0 if( jump[name] ) a0 = 1; if( nopush[name]==0 ) a1 = 2; if( out2_prerelease[name] ) a2 = 4; bv[x] = a0+a1+a2+a3+a4+a5+a6+a7; } print "\n" print "/* Properties such as \"out2\" or \"jump\" that are specified in" print "** comments following the "case" for each opcode in the vdbe.c" print "** are encoded into bitvectors as follows:" print "*/" print "#define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */" print "#define OPFLG_PUSH 0x02 /* ~no-push: Does not push */" print "#define OPFLG_OUT2_PRERELEASE 0x04 /* out2-prerelease: */" print "#define OPFLG_INITIALIZER {\\" for(i=0; i<=max; i++){ printf " 0x%02x,", bv[i] if( i%8==7 ) printf("\\\n"); } print "}" } |
Changes to src/alter.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 used to generate VDBE code ** that implements the ALTER TABLE command. ** | | | 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 used to generate VDBE code ** that implements the ALTER TABLE command. ** ** $Id: alter.c,v 1.39 2008/01/04 22:01:03 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** The code in this file only exists if we are not omitting the ** ALTER TABLE logic from the build. |
︙ | ︙ | |||
359 360 361 362 363 364 365 | ** one is defined. The xRename() callback will modify the names ** of any resources used by the v-table implementation (including other ** SQLite tables) that are identified by the name of the virtual table. */ #ifndef SQLITE_OMIT_VIRTUALTABLE if( isVirtualRename ){ int i = ++pParse->nMem; | < < | | 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 | ** one is defined. The xRename() callback will modify the names ** of any resources used by the v-table implementation (including other ** SQLite tables) that are identified by the name of the virtual table. */ #ifndef SQLITE_OMIT_VIRTUALTABLE if( isVirtualRename ){ int i = ++pParse->nMem; sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0); sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pTab->pVtab, P4_VTAB); } #endif /* figure out how many UTF-8 characters are in zName */ zTabName = pTab->zName; nTabName = sqlite3Utf8CharLen(zTabName, -1); |
︙ | ︙ |
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.31 2008/01/04 22:01:03 drh Exp $ */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" /* ** This routine generates code that opens the sqlite_stat1 table on cursor ** iStatCur. |
︙ | ︙ | |||
140 141 142 143 144 145 146 | ** ... ** mem[iMem+nCol+nCol]: Last observed value of column N ** ** Cells iMem through iMem+nCol are initialized to 0. The others ** are initialized to NULL. */ for(i=0; i<=nCol; i++){ | | | | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | ** ... ** mem[iMem+nCol+nCol]: Last observed value of column N ** ** Cells iMem through iMem+nCol are initialized to 0. The others ** are initialized to NULL. */ for(i=0; i<=nCol; i++){ sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem+i); } for(i=0; i<nCol; i++){ sqlite3VdbeAddOp2(v, OP_Null, 0, iMem+nCol+i+1); } /* Do the analysis. */ endOfLoop = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop); topOfLoop = sqlite3VdbeCurrentAddr(v); |
︙ | ︙ |
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.457 2008/01/04 22:01:03 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. |
︙ | ︙ | |||
847 848 849 850 851 852 853 | sqlite3VdbeAddOp0(v, OP_VBegin); } #endif /* If the file format and encoding in the database have not been set, ** set them now. */ | | | 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 | sqlite3VdbeAddOp0(v, OP_VBegin); } #endif /* If the file format and encoding in the database have not been set, ** set them now. */ sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 0, 1); /* file_format */ sqlite3VdbeUsesBtree(v, iDb); lbl = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp2(v, OP_If, 0, lbl); fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? 1 : SQLITE_MAX_FILE_FORMAT; sqlite3VdbeAddOp1(v, OP_Integer, fileFormat); sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 1); |
︙ | ︙ | |||
2715 2716 2717 2718 2719 2720 2721 | ** Generate code to make sure the file format number is at least minFormat. ** The generated code will increase the file format number if necessary. */ void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){ Vdbe *v; v = sqlite3GetVdbe(pParse); if( v ){ | | | 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 | ** Generate code to make sure the file format number is at least minFormat. ** The generated code will increase the file format number if necessary. */ void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){ Vdbe *v; v = sqlite3GetVdbe(pParse); if( v ){ sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 0, 1); sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeAddOp1(v, OP_Integer, minFormat); sqlite3VdbeAddOp2(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp1(v, OP_Integer, minFormat); sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 1); } } |
︙ | ︙ |
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.148 2008/01/04 22:01:03 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. |
︙ | ︙ | |||
270 271 272 273 274 275 276 | } /* Initialize the counter of the number of rows deleted, if ** we are counting rows. */ if( db->flags & SQLITE_CountRows ){ memCnt = ++pParse->nMem; | | | 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | } /* 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_Integer, 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. */ if( pWhere==0 && !triggers_exist && !IsVirtual(pTab) ){ |
︙ | ︙ | |||
365 366 367 368 369 370 371 | */ sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, iRowid); /* Populate the OLD.* pseudo-table */ if( old_col_mask ){ sqlite3VdbeAddOp3(v, OP_RowData, iCur, 0, iData); }else{ | | | 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | */ sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, iRowid); /* Populate the OLD.* pseudo-table */ if( old_col_mask ){ sqlite3VdbeAddOp3(v, OP_RowData, iCur, 0, iData); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, iData); } sqlite3VdbeAddOp3(v, OP_Insert, oldIdx, iData, iRowid); /* Jump back and run the BEFORE triggers */ sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger); sqlite3VdbeJumpHere(v, iEndBeforeTrigger); } |
︙ | ︙ |
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.330 2008/01/04 22:01:03 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
1604 1605 1606 1607 1608 1609 1610 | 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); | | | 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 | 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); sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem); sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); eType = IN_INDEX_ROWID; sqlite3VdbeJumpHere(v, iAddr); }else{ /* The collation sequence used by the comparison. If an index is to |
︙ | ︙ | |||
1641 1642 1643 1644 1645 1646 1647 | pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx); iDb = sqlite3SchemaToIndex(db, pIdx->pSchema); sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeAddOp1(v, OP_MemLoad, iMem); iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem); | | | 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 | pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx); iDb = sqlite3SchemaToIndex(db, pIdx->pSchema); sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeAddOp1(v, OP_MemLoad, iMem); iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem); sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem); sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb, pKey,P4_KEYINFO_HANDOFF); VdbeComment((v, "%s", pIdx->zName)); eType = IN_INDEX_INDEX; sqlite3VdbeAddOp2(v, OP_SetNumColumns, iTab, pIdx->nColumn); |
︙ | ︙ | |||
1699 1700 1701 1702 1703 1704 1705 | ** 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 ); | | | 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 | ** 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_Integer, 1, mem); } switch( pExpr->op ){ case TK_IN: { char affinity; KeyInfo keyInfo; int addr; /* Address of OP_OpenEphemeral instruction */ |
︙ | ︙ | |||
1803 1804 1805 1806 1807 1808 1809 | Select *pSel; SelectDest dest; pSel = pExpr->pSelect; dest.iParm = ++pParse->nMem; if( pExpr->op==TK_SELECT ){ dest.eDest = SRT_Mem; | | | | 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 | Select *pSel; SelectDest dest; pSel = pExpr->pSelect; dest.iParm = ++pParse->nMem; if( pExpr->op==TK_SELECT ){ dest.eDest = SRT_Mem; sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iParm); VdbeComment((v, "Init subquery result")); }else{ dest.eDest = SRT_Exists; sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iParm); VdbeComment((v, "Init EXISTS result")); } sqlite3ExprDelete(pSel->pLimit); pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &one); if( sqlite3Select(pParse, pSel, &dest, 0, 0, 0, 0) ){ return; } |
︙ | ︙ |
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.211 2008/01/04 22:01:03 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: |
︙ | ︙ | |||
213 214 215 216 217 218 219 | int addr; assert( v ); addr = sqlite3VdbeCurrentAddr(v); sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); sqlite3VdbeAddOp2(v, OP_MemLoad, memId-1, 0); sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+6); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); | | | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | int addr; assert( v ); addr = sqlite3VdbeCurrentAddr(v); sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); sqlite3VdbeAddOp2(v, OP_MemLoad, memId-1, 0); sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+6); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); sqlite3VdbeAddOp1(v, OP_NewRowid, iCur); sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0); sqlite3VdbeAddOp2(v, OP_MemLoad, memId, 0); sqlite3VdbeAddOp2(v, OP_MakeRecord, 2, 0); sqlite3CodeInsert(pParse, iCur, OPFLAG_APPEND); sqlite3VdbeAddOp2(v, OP_Close, iCur, 0); } } |
︙ | ︙ | |||
505 506 507 508 509 510 511 | /* Generate the subroutine that SELECT calls to process each row of ** the result. Store the result in a temporary table */ srcTab = pParse->nTab++; sqlite3VdbeResolveLabel(v, iInsertBlock); sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0); sqlite3VdbeAddOp2(v, OP_MakeRecord, nColumn, 0); | | | 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 | /* Generate the subroutine that SELECT calls to process each row of ** the result. Store the result in a temporary table */ srcTab = pParse->nTab++; sqlite3VdbeResolveLabel(v, iInsertBlock); sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0); sqlite3VdbeAddOp2(v, OP_MakeRecord, nColumn, 0); sqlite3VdbeAddOp1(v, OP_NewRowid, srcTab); sqlite3VdbeAddOp2(v, OP_Pull, 1, 0); sqlite3CodeInsert(pParse, srcTab, OPFLAG_APPEND); sqlite3VdbeAddOp2(v, OP_Return, 0, 0); /* The following code runs first because the GOTO at the very top ** of the program jumps to it. Create the temporary table, then jump ** back up and execute the SELECT code above. |
︙ | ︙ | |||
615 616 617 618 619 620 621 | sqlite3VdbeAddOp2(v, OP_SetNumColumns, newIdx, pTab->nCol); } /* Initialize the count of rows to be inserted */ if( db->flags & SQLITE_CountRows ){ iCntMem = ++pParse->nMem; | | | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 | 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_Integer, 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); } |
︙ | ︙ | |||
718 719 720 721 722 723 724 | if( !isView ){ int iReg = pParse->nMem+1; int iRowid = iReg+(IsVirtual(pTab)?1:0); pParse->nMem += pTab->nCol + (IsVirtual(pTab)?2:1); if( IsVirtual(pTab) ){ /* The row that the VUpdate opcode will delete: none */ | | | | | | | | | 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 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 783 784 785 | if( !isView ){ int iReg = pParse->nMem+1; int iRowid = iReg+(IsVirtual(pTab)?1:0); pParse->nMem += pTab->nCol + (IsVirtual(pTab)?2:1); if( IsVirtual(pTab) ){ /* The row that the VUpdate opcode will delete: none */ sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); } if( keyColumn>=0 ){ if( useTempTable ){ sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, iRowid); }else if( pSelect ){ sqlite3VdbeAddOp3(v, OP_Dup, nColumn - keyColumn - 1, 1, iRowid); /* TODO: Avoid this use of the stack. */ sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1); }else{ VdbeOp *pOp; sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, 0); pOp = sqlite3VdbeGetOp(v, sqlite3VdbeCurrentAddr(v) - 1); if( pOp && pOp->opcode==OP_Null ){ appendFlag = 1; pOp->opcode = OP_NewRowid; pOp->p1 = base; pOp->p2 = iRowid; pOp->p3 = counterMem; }else{ /* TODO: Avoid this use of the stack. */ sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1); } } /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid ** to generate a unique primary key value. */ if( !appendFlag ){ sqlite3VdbeAddOp2(v, OP_IfMemNull, iRowid, sqlite3VdbeCurrentAddr(v)+2); sqlite3VdbeAddOp2(v, OP_Goto, -1, sqlite3VdbeCurrentAddr(v)+2); sqlite3VdbeAddOp3(v, OP_NewRowid, base, iRowid, counterMem); sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, 0, iRowid); } }else if( IsVirtual(pTab) ){ sqlite3VdbeAddOp2(v, OP_Null, 0, iRowid); }else{ sqlite3VdbeAddOp3(v, OP_NewRowid, base, 0, counterMem); sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1); appendFlag = 1; } autoIncStep(pParse, counterMem, iRowid); /* Push onto the stack, data for all columns of the new entry, beginning ** with the first column. */ nHidden = 0; for(i=0; i<pTab->nCol; i++){ int iRegStore = iRowid+1+i; if( i==pTab->iPKey ){ /* The value of the INTEGER PRIMARY KEY column is always a NULL. ** Whenever this column is read, the record number will be substituted ** in its place. So will fill this column with a NULL to avoid ** taking up data space with information that will never be used. */ sqlite3VdbeAddOp2(v, OP_Null, 0, iRegStore); continue; } if( pColumn==0 ){ if( IsHiddenColumn(&pTab->aCol[i]) ){ assert( IsVirtual(pTab) ); j = -1; nHidden++; |
︙ | ︙ | |||
1569 1570 1571 1572 1573 1574 1575 | sqlite3VdbeAddOp2(v, OP_Dup, 0, 0); addr2 = sqlite3VdbeAddOp2(v, OP_NotExists, iDest, 0); sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, "PRIMARY KEY must be unique", P4_STATIC); sqlite3VdbeJumpHere(v, addr2); autoIncStep(pParse, counterMem, 0); }else if( pDest->pIndex==0 ){ | | | 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 | sqlite3VdbeAddOp2(v, OP_Dup, 0, 0); addr2 = sqlite3VdbeAddOp2(v, OP_NotExists, iDest, 0); sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, "PRIMARY KEY must be unique", P4_STATIC); sqlite3VdbeJumpHere(v, addr2); autoIncStep(pParse, counterMem, 0); }else if( pDest->pIndex==0 ){ addr1 = sqlite3VdbeAddOp1(v, OP_NewRowid, iDest); }else{ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, 0); assert( pDest->autoInc==0 ); } sqlite3VdbeAddOp2(v, OP_RowData, iSrc, 0); sqlite3CodeInsert(pParse,iDest,OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND); sqlite3VdbeChangeP4(v, -1, pDest->zName, 0); |
︙ | ︙ |
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.158 2008/01/04 22:01:03 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) |
︙ | ︙ | |||
144 145 146 147 148 149 150 | /* ** 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; | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | /* ** 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_Integer, value, mem); if( pParse->explain==0 ){ sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, P4_STATIC); } sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); } |
︙ | ︙ | |||
294 295 296 297 298 299 300 | ** database file. The cache size is actually the absolute value of ** this memory location. The sign of meta-value 2 determines the ** synchronous setting. A negative value means synchronous is off ** and a positive value means synchronous is on. */ if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ static const VdbeOpList getCacheSize[] = { | | | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | ** database file. The cache size is actually the absolute value of ** this memory location. The sign of meta-value 2 determines the ** synchronous setting. A negative value means synchronous is off ** and a positive value means synchronous is on. */ if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ static const VdbeOpList getCacheSize[] = { { OP_ReadCookie, 0, 0, 2}, /* 0 */ { OP_AbsValue, 0, 0, 0}, { OP_Dup, 0, 0, 0}, { OP_Integer, 0, 0, 0}, { OP_Ne, 0, 6, 0}, { OP_Integer, 0, 0, 0}, /* 5 */ { OP_Callback, 1, 0, 0}, }; |
︙ | ︙ | |||
316 317 318 319 320 321 322 | sqlite3VdbeChangeP1(v, addr, iDb); sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE); }else{ int size = atoi(zRight); if( size<0 ) size = -size; sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp2(v, OP_Integer, size, 0); | | | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | sqlite3VdbeChangeP1(v, addr, iDb); sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE); }else{ int size = atoi(zRight); if( size<0 ) size = -size; sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp2(v, OP_Integer, size, 0); sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 0, 2); addr = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); sqlite3VdbeAddOp2(v, OP_Ge, 0, addr+3); sqlite3VdbeAddOp2(v, OP_Negative, 0, 0); sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 2); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } |
︙ | ︙ | |||
453 454 455 456 457 458 459 | /* When setting the auto_vacuum mode to either "full" or ** "incremental", write the value of meta[6] in the database ** file. Before writing to meta[6], check that meta[3] indicates ** that this really is an auto-vacuum capable database. */ static const VdbeOpList setMeta6[] = { { OP_Transaction, 0, 1, 0}, /* 0 */ | | | 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 | /* When setting the auto_vacuum mode to either "full" or ** "incremental", write the value of meta[6] in the database ** file. Before writing to meta[6], check that meta[3] indicates ** that this really is an auto-vacuum capable database. */ static const VdbeOpList setMeta6[] = { { OP_Transaction, 0, 1, 0}, /* 0 */ { OP_ReadCookie, 0, 0, 3}, /* 1 */ { OP_If, 0, 0, 0}, /* 2 */ { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ { OP_Integer, 0, 0, 0}, /* 4 */ { OP_SetCookie, 0, 6, 0}, /* 5 */ }; int iAddr; iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6); |
︙ | ︙ | |||
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 | if( sqlite3ReadSchema(pParse) ){ goto pragma_out; } if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ iLimit = 0x7fffffff; } sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp2(v, OP_Integer, 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 |
︙ | ︙ | |||
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 | mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; if( zRight ){ mxErr = atoi(zRight); if( mxErr<=0 ){ mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; } } sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* Do an integrity check on each database file */ for(i=0; i<db->nDb; i++){ HashElem *x; Hash *pTbls; int cnt = 0; |
︙ | ︙ | |||
899 900 901 902 903 904 905 | 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); | | | 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 | 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_Integer, 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 */ |
︙ | ︙ | |||
925 926 927 928 929 930 931 | 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[] = { | | | 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 | 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_Integer, 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}, |
︙ | ︙ | |||
1103 1104 1105 1106 1107 1108 1109 | /* Read the specified cookie value */ static const VdbeOpList readCookie[] = { { OP_ReadCookie, 0, 0, 0}, /* 0 */ { OP_Callback, 1, 0, 0} }; int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie); sqlite3VdbeChangeP1(v, addr, iDb); | | | 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 | /* Read the specified cookie value */ static const VdbeOpList readCookie[] = { { OP_ReadCookie, 0, 0, 0}, /* 0 */ { OP_Callback, 1, 0, 0} }; int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie); sqlite3VdbeChangeP1(v, addr, iDb); sqlite3VdbeChangeP3(v, addr, iCookie); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, P4_TRANSIENT); } }else #endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
︙ | ︙ |
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.384 2008/01/04 22:01:03 drh Exp $ */ #include "sqliteInt.h" /* ** Delete all the content of a Select structure but do not deallocate ** the select structure itself. |
︙ | ︙ | |||
539 540 541 542 543 544 545 | if( nColumn>0 ){ n = nColumn; }else{ n = pEList->nExpr; } iMem = ++pParse->nMem; pParse->nMem += n+1; | | | 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 | if( nColumn>0 ){ n = nColumn; }else{ n = pEList->nExpr; } iMem = ++pParse->nMem; pParse->nMem += n+1; sqlite3VdbeAddOp2(v, OP_Integer, 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 ){ /* If the destination is an EXISTS(...) expression, the actual ** values returned by the SELECT are not required. |
︙ | ︙ | |||
607 608 609 610 611 612 613 | */ case SRT_Table: case SRT_EphemTab: { sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0); if( pOrderBy ){ pushOntoSorter(pParse, pOrderBy, p); }else{ | | | 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 | */ case SRT_Table: case SRT_EphemTab: { sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0); if( pOrderBy ){ pushOntoSorter(pParse, pOrderBy, p); }else{ sqlite3VdbeAddOp1(v, OP_NewRowid, iParm); sqlite3VdbeAddOp2(v, OP_Pull, 1, 0); sqlite3CodeInsert(pParse, iParm, OPFLAG_APPEND); } break; } #ifndef SQLITE_OMIT_SUBQUERY |
︙ | ︙ | |||
643 644 645 646 647 648 649 | sqlite3VdbeJumpHere(v, addr2); break; } /* If any row exist in the result set, record that fact and abort. */ case SRT_Exists: { | | | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 | sqlite3VdbeJumpHere(v, addr2); break; } /* If any row exist in the result set, record that fact and abort. */ case SRT_Exists: { sqlite3VdbeAddOp2(v, OP_Integer, 1, iParm); /* The LIMIT clause will terminate the loop for us */ break; } /* If this is a scalar select that is part of an expression, then ** store the results in the appropriate memory cell and break out ** of the scan loop. |
︙ | ︙ | |||
785 786 787 788 789 790 791 | if( eDest==SRT_Callback || eDest==SRT_Subroutine ){ sqlite3VdbeAddOp2(v, OP_Integer, 1, 0); } sqlite3VdbeAddOp2(v, OP_Column, iTab, pOrderBy->nExpr + 1); switch( eDest ){ case SRT_Table: case SRT_EphemTab: { | | | 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 | if( eDest==SRT_Callback || eDest==SRT_Subroutine ){ sqlite3VdbeAddOp2(v, OP_Integer, 1, 0); } sqlite3VdbeAddOp2(v, OP_Column, iTab, pOrderBy->nExpr + 1); switch( eDest ){ case SRT_Table: case SRT_EphemTab: { sqlite3VdbeAddOp1(v, OP_NewRowid, iParm); sqlite3VdbeAddOp2(v, OP_Pull, 1, 0); sqlite3CodeInsert(pParse, iParm, OPFLAG_APPEND); break; } #ifndef SQLITE_OMIT_SUBQUERY case SRT_Set: { assert( nColumn==1 ); |
︙ | ︙ | |||
1772 1773 1774 1775 1776 1777 1778 | if( p->pLimit ){ sqlite3VdbeAddOp2(v, OP_Add, 0, 0); } } if( p->pLimit ){ addr1 = sqlite3VdbeAddOp2(v, OP_IfMemPos, iLimit, 0); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); | | | 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 | if( p->pLimit ){ sqlite3VdbeAddOp2(v, OP_Add, 0, 0); } } if( p->pLimit ){ addr1 = sqlite3VdbeAddOp2(v, OP_IfMemPos, iLimit, 0); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); sqlite3VdbeAddOp2(v, OP_Integer, -1, iLimit+1); addr2 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp2(v, OP_MemStore, iLimit+1, 1); VdbeComment((v, "LIMIT+OFFSET")); sqlite3VdbeJumpHere(v, addr2); } } |
︙ | ︙ | |||
2923 2924 2925 2926 2927 2928 2929 | Vdbe *v = pParse->pVdbe; int i; struct AggInfo_func *pFunc; if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){ return; } for(i=0; i<pAggInfo->nColumn; i++){ | | | | 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 | Vdbe *v = pParse->pVdbe; int i; struct AggInfo_func *pFunc; if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){ return; } for(i=0; i<pAggInfo->nColumn; i++){ sqlite3VdbeAddOp2(v, OP_Null, 0, pAggInfo->aCol[i].iMem); } for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){ sqlite3VdbeAddOp2(v, OP_Null, 0, pFunc->iMem); if( pFunc->iDistinct>=0 ){ Expr *pE = pFunc->pExpr; if( pE->pList==0 || pE->pList->nExpr!=1 ){ sqlite3ErrorMsg(pParse, "DISTINCT in aggregate must be followed " "by an expression"); pFunc->iDistinct = -1; }else{ |
︙ | ︙ | |||
3450 3451 3452 3453 3454 3455 3456 | */ iUseFlag = ++pParse->nMem; iAbortFlag = ++pParse->nMem; iAMem = pParse->nMem + 1; pParse->nMem += pGroupBy->nExpr; iBMem = pParse->nMem + 1; pParse->nMem += pGroupBy->nExpr; | | | | | 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 | */ 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_Integer, 0, iAbortFlag); VdbeComment((v, "clear abort flag")); sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); VdbeComment((v, "indicate accumulator empty")); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrInitializeLoop); /* Generate a subroutine that outputs a single row of the result ** set. This subroutine first looks at the iUseFlag. If iUseFlag ** is less than or equal to zero, the subroutine is a no-op. If ** the processing calls for the query to abort, this subroutine ** increments the iAbortFlag memory location before returning in ** order to signal the caller to abort. */ addrSetAbort = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag); VdbeComment((v, "set abort flag")); sqlite3VdbeAddOp2(v, OP_Return, 0, 0); addrOutputRow = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_IfMemPos, iUseFlag, addrOutputRow+2); VdbeComment((v, "Groupby result generator entry point")); sqlite3VdbeAddOp2(v, OP_Return, 0, 0); finalizeAggFunctions(pParse, &sAggInfo); |
︙ | ︙ | |||
3583 3584 3585 3586 3587 3588 3589 | VdbeComment((v, "reset accumulator")); /* Update the aggregate accumulators based on the content of ** the current row */ sqlite3VdbeResolveLabel(v, addrProcessRow); updateAccumulator(pParse, &sAggInfo); | | | 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 | VdbeComment((v, "reset accumulator")); /* Update the aggregate accumulators based on the content of ** the current row */ sqlite3VdbeResolveLabel(v, addrProcessRow); updateAccumulator(pParse, &sAggInfo); sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); VdbeComment((v, "indicate data in accumulator")); /* End of the loop */ if( groupBySort ){ sqlite3VdbeAddOp2(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop); }else{ |
︙ | ︙ |
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.158 2008/01/04 22:01:03 drh Exp $ */ #include "sqliteInt.h" #ifndef SQLITE_OMIT_VIRTUALTABLE /* Forward declaration */ static void updateVirtualTable( Parse *pParse, /* The parsing context */ |
︙ | ︙ | |||
352 353 354 355 356 357 358 | */ sqlite3WhereEnd(pWInfo); /* Initialize the count of updated rows */ if( db->flags & SQLITE_CountRows && !pParse->trigStack ){ memCnt = ++pParse->nMem; | | | 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | */ sqlite3WhereEnd(pWInfo); /* Initialize the count of updated rows */ if( db->flags & SQLITE_CountRows && !pParse->trigStack ){ memCnt = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); } if( !isView && !IsVirtual(pTab) ){ /* ** Open every index that needs updating. Note that if any ** index could potentially invoke a REPLACE conflict resolution ** action, then we need to open all indices because we might need |
︙ | ︙ |
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.679 2008/01/04 22:01:03 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
173 174 175 176 177 178 179 | } /* ** Properties of opcodes. The OPFLG_INITIALIZER macro is ** created by mkopcodeh.awk during compilation. Data is obtained ** from the comments following the "case OP_xxxx:" statements in ** this file. | < < < < < < < < | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | } /* ** Properties of opcodes. The OPFLG_INITIALIZER macro is ** created by mkopcodeh.awk during compilation. Data is obtained ** from the comments following the "case OP_xxxx:" statements in ** this file. */ static unsigned char opcodeProperty[] = OPFLG_INITIALIZER; /* ** Return true if an opcode has any of the OPFLG_xxx properties ** specified by mask. */ |
︙ | ︙ | |||
471 472 473 474 475 476 477 478 479 480 481 482 483 484 | ){ int pc; /* The program counter */ Op *pOp; /* Current operation */ int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 encoding = ENC(db); /* The database encoding */ Mem *pTos; /* Top entry in the operand stack */ #ifdef VDBE_PROFILE unsigned long long start; /* CPU clock count at start of opcode */ int origPc; /* Program counter at start of opcode */ #endif #ifndef SQLITE_OMIT_PROGRESS_CALLBACK int nProgressOps = 0; /* Opcodes executed since progress callback. */ #endif | > > > | 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 | ){ int pc; /* The program counter */ Op *pOp; /* Current operation */ int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 encoding = ENC(db); /* The database encoding */ Mem *pTos; /* Top entry in the operand stack */ Mem *pIn1, *pIn2; /* Input operands */ Mem *pOut; /* Output operand */ int nPop = 0; /* Number of times to pop the stack */ #ifdef VDBE_PROFILE unsigned long long start; /* CPU clock count at start of opcode */ int origPc; /* Program counter at start of opcode */ #endif #ifndef SQLITE_OMIT_PROGRESS_CALLBACK int nProgressOps = 0; /* Opcodes executed since progress callback. */ #endif |
︙ | ︙ | |||
589 590 591 592 593 594 595 596 597 598 599 600 601 602 | */ pStackLimit = pTos; if( sqlite3VdbeOpcodeHasProperty(pOp->opcode, OPFLG_PUSH) ){ pStackLimit++; } assert( pTos>=&p->aStack[-1] && pTos<=pStackLimit ); #endif switch( pOp->opcode ){ /***************************************************************************** ** What follows is a massive switch statement where each case implements a ** separate instruction in the virtual machine. If we follow the usual ** indentation conventions, each case should be indented by 6 spaces. But | > > > > > > > > > > > > > > > > > > > | 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 | */ pStackLimit = pTos; if( sqlite3VdbeOpcodeHasProperty(pOp->opcode, OPFLG_PUSH) ){ pStackLimit++; } assert( pTos>=&p->aStack[-1] && pTos<=pStackLimit ); #endif /* Do common setup processing for any opcode that is marked ** with the "out2-prerelease" tag. Such opcodes have a single ** output which is specified by the P2 parameter. The output ** is normally written into the P2-th register. But if P2==0 ** then the output is pushed onto the stack. The P2 operand ** is initialized to a NULL. */ if( (opcodeProperty[pOp->opcode]&OPFLG_OUT2_PRERELEASE)!=0 ){ assert( pOp->p2>=0 ); if( pOp->p2==0 ){ pOut = ++pTos; }else{ assert( pOp->p2<=p->nMem ); pOut = &p->aMem[pOp->p2]; sqlite3VdbeMemRelease(pOut); } pOut->flags = MEM_Null; } switch( pOp->opcode ){ /***************************************************************************** ** What follows is a massive switch statement where each case implements a ** separate instruction in the virtual machine. If we follow the usual ** indentation conventions, each case should be indented by 6 spaces. But |
︙ | ︙ | |||
730 731 732 733 734 735 736 | p->errorAction = OE_Rollback; sqlite3SetString(&p->zErrMsg, "internal error: VDBE stack leak", (char*)0); goto vdbe_return; } break; } | | | > | < | | | | | < | | | | | | < | | | < | | | | | | | | | > | < | | | | | | > | < < < | | | | | 744 745 746 747 748 749 750 751 752 753 754 755 756 757 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 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 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 848 849 850 851 852 853 854 855 856 857 858 859 860 | p->errorAction = OE_Rollback; sqlite3SetString(&p->zErrMsg, "internal error: VDBE stack leak", (char*)0); goto vdbe_return; } break; } /* Opcode: Integer P1 P2 * * * ** ** The 32-bit integer value P1 is written into register P2, or ** pushed onto the stack if P2==0. */ case OP_Integer: { /* out2-prerelease */ pOut->flags = MEM_Int; pOut->u.i = pOp->p1; break; } /* Opcode: Int64 * P2 * P4 * ** ** P4 is a pointer to a 64-bit integer value. ** Write that value into register P2 or push onto the stack if P2 is 0. */ case OP_Int64: { /* out2-prerelease */ assert( pOp->p4.pI64!=0 ); pOut->flags = MEM_Int; pOut->u.i = *pOp->p4.pI64; break; } /* Opcode: Real * P2 * P4 * ** ** P4 is a pointer to a 64-bit floating point value. ** Write that value into register P2 or push onto the stack if P2 is 0. */ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */ pOut->flags = MEM_Real; pOut->r = *pOp->p4.pReal; break; } /* Opcode: String8 * * P4 ** ** P4 points to a nul terminated UTF-8 string. This opcode is transformed ** into an OP_String before it is executed for the first time. */ case OP_String8: { /* same as TK_STRING, out2-prerelease */ assert( pOp->p4.z!=0 ); pOp->opcode = OP_String; pOp->p1 = strlen(pOp->p4.z); #ifndef SQLITE_OMIT_UTF16 if( encoding!=SQLITE_UTF8 ){ sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pOut) ) goto no_mem; pOut->flags &= ~(MEM_Dyn); pOut->flags |= MEM_Static; if( pOp->p4type==P4_DYNAMIC ){ sqlite3_free(pOp->p4.z); } pOp->p4type = P4_DYNAMIC; pOp->p4.z = pOut->z; pOp->p1 = pOut->n; if( pOp->p1>SQLITE_MAX_LENGTH ){ goto too_big; } break; } #endif if( pOp->p1>SQLITE_MAX_LENGTH ){ goto too_big; } /* Fall through to the next case, OP_String */ } /* Opcode: String P1 P2 * P4 * ** ** The string value P4 of length P1 (bytes) is stored in register P2 ** or is pushed onto the stack if P2==0. */ case OP_String: { /* out2-prerelease */ assert( pOp->p4.z!=0 ); pOut->flags = MEM_Str|MEM_Static|MEM_Term; pOut->z = pOp->p4.z; pOut->n = pOp->p1; pOut->enc = encoding; break; } /* Opcode: Null * P2 * * * ** ** Write a NULL into register P2 or push a NULL onto the stack ** if P2==0. */ case OP_Null: { /* out2-prerelease */ break; } #ifndef SQLITE_OMIT_BLOB_LITERAL /* Opcode: HexBlob * P2 * P4 * ** ** P4 is an UTF-8 SQL hex encoding of a blob. The blob is stored in ** register P2 or pushed onto the stack if P2 is zero. ** ** The first time this instruction executes, in transforms itself into a ** 'Blob' opcode with a binary blob as P4. */ case OP_HexBlob: { /* same as TK_BLOB, out2-prerelease */ pOp->opcode = OP_Blob; pOp->p1 = strlen(pOp->p4.z)/2; if( pOp->p1>SQLITE_MAX_LENGTH ){ goto too_big; } if( pOp->p1 ){ char *zBlob = sqlite3HexToBlob(db, pOp->p4.z); |
︙ | ︙ | |||
871 872 873 874 875 876 877 | ** P4 points to a blob of data P1 bytes long. Push this ** value onto the stack. This instruction is not coded directly ** by the compiler. Instead, the compiler layer specifies ** an OP_HexBlob opcode, with the hex string representation of ** the blob as P4. This opcode is transformed to an OP_Blob ** the first time it is executed. */ | | < | | > | < | | 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 | ** P4 points to a blob of data P1 bytes long. Push this ** value onto the stack. This instruction is not coded directly ** by the compiler. Instead, the compiler layer specifies ** an OP_HexBlob opcode, with the hex string representation of ** the blob as P4. This opcode is transformed to an OP_Blob ** the first time it is executed. */ case OP_Blob: { /* out2-prerelease */ assert( pOp->p1 <= SQLITE_MAX_LENGTH ); sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); pTos->enc = encoding; break; } #endif /* SQLITE_OMIT_BLOB_LITERAL */ /* Opcode: Variable P1 * * ** ** The value of variable P1 is written into register P2 or pushed ** onto the stack if P2 is zero. A variable is ** an unknown in the original SQL string as handed to sqlite3_compile(). ** Any occurance of the '?' character in the original SQL is considered ** a variable. Variables in the SQL string are number from left to ** right beginning with 1. The values of variables are set using the ** sqlite3_bind() API. */ case OP_Variable: { /* out2-prerelease */ int j = pOp->p1 - 1; Mem *pVar; assert( j>=0 && j<p->nVar ); pVar = &p->aVar[j]; if( sqlite3VdbeMemTooBig(pVar) ){ goto too_big; } sqlite3VdbeMemShallowCopy(pOut, &p->aVar[j], MEM_Static); break; } /* Opcode: Pop P1 * * ** ** P1 elements are popped off of the top of stack and discarded. */ |
︙ | ︙ | |||
2669 2670 2671 2672 2673 2674 2675 | if( rc!=SQLITE_OK && rc!=SQLITE_READONLY /* && rc!=SQLITE_BUSY */ ){ goto abort_due_to_error; } } break; } | | > | | | | | | < | | | 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 | if( rc!=SQLITE_OK && rc!=SQLITE_READONLY /* && rc!=SQLITE_BUSY */ ){ goto abort_due_to_error; } } break; } /* Opcode: ReadCookie P1 P2 P3 ** ** Read cookie number P3 from database P1 and write it into register ** P2 or push it onto the stack if P2==0. ** P3==0 is the schema version. P3==1 is the database format. ** P3==2 is the recommended pager cache size, and so forth. P1==0 is ** the main database file and P1==1 is the database file used to store ** temporary tables. ** ** If P1 is negative, then this is a request to read the size of a ** databases free-list. P3 must be set to 1 in this case. The actual ** database accessed is ((P1+1)*-1). For example, a P1 parameter of -1 ** corresponds to database 0 ("main"), a P1 of -2 is database 1 ("temp"). ** ** There must be a read-lock on the database (either a transaction ** must be started or there must be an open cursor) before ** executing this instruction. */ case OP_ReadCookie: { /* out2-prerelease */ int iMeta; int iDb = pOp->p1; int iCookie = pOp->p3; assert( pOp->p2<SQLITE_N_BTREE_META ); if( iDb<0 ){ iDb = (-1*(iDb+1)); iCookie *= -1; } assert( iDb>=0 && iDb<db->nDb ); assert( db->aDb[iDb].pBt!=0 ); assert( (p->btreeMask & (1<<iDb))!=0 ); /* The indexing of meta values at the schema layer is off by one from ** the indexing in the btree layer. The btree considers meta[0] to ** be the number of free pages in the database (a read-only value) ** and meta[1] to be the schema cookie. The schema layer considers ** meta[1] to be the schema cookie. So we have to shift the index ** by one in the following statement. */ rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, 1 + iCookie, (u32 *)&iMeta); pOut->u.i = iMeta; pOut->flags = MEM_Int; break; } /* Opcode: SetCookie P1 P2 * ** ** Write the top of the stack into cookie number P2 of database P1. ** P2==0 is the schema version. P2==1 is the database format. |
︙ | ︙ | |||
3422 3423 3424 3425 3426 3427 3428 | if( pOp->p3==0 ){ Release(pTos); pTos--; } break; } | | | | > | > | < | | | | | | | | 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 | if( pOp->p3==0 ){ Release(pTos); pTos--; } break; } /* Opcode: Sequence P1 P2 * * * ** ** Find the next available sequence number for cursor P1. ** Write the sequence number into register P2, or push it onto ** the stack if P2==0. ** The sequence number on the cursor is incremented after this ** instruction. */ case OP_Sequence: { /* out2-prerelease */ int i = pOp->p1; assert( pTos>=p->aStack ); assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); pOut->u.i = p->apCsr[i]->seqCount++; pOut->flags = MEM_Int; break; } /* Opcode: NewRowid P1 P2 P3 ** ** Get a new integer record number (a.k.a "rowid") used as the key to a table. ** The record number is not previously used as a key in the database ** table that cursor P1 points to. The new record number is pushed ** onto the stack if P2 is 0 or written to memory cell P2 otherwise. ** ** If P3>0 then P3 is a memory cell that holds the largest previously ** generated record number. No new record numbers are allowed to be less ** than this value. When this value reaches its maximum, a SQLITE_FULL ** error is generated. The P3 memory cell is updated with the generated ** record number. This P3 mechanism is used to help implement the ** AUTOINCREMENT feature. */ case OP_NewRowid: { /* out2-prerelease */ int i = pOp->p1; i64 v = 0; Cursor *pC; assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( (pC = p->apCsr[i])->pCursor==0 ){ /* The zero initialization above is all that is needed */ |
︙ | ︙ | |||
3537 3538 3539 3540 3541 3542 3543 | }else{ v++; } } } #ifndef SQLITE_OMIT_AUTOINCREMENT | | | | | | | 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 | }else{ v++; } } } #ifndef SQLITE_OMIT_AUTOINCREMENT if( pOp->p3 ){ Mem *pMem; assert( pOp->p3>0 && pOp->p3<=p->nMem ); /* P3 is a valid memory cell */ pMem = &p->aMem[pOp->p3]; sqlite3VdbeMemIntegerify(pMem); assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ rc = SQLITE_FULL; goto abort_due_to_error; } if( v<pMem->u.i+1 ){ v = pMem->u.i + 1; } pMem->u.i = v; } #endif if( v<MAX_ROWID ){ pC->nextRowidValid = 1; pC->nextRowid = v+1; }else{ pC->nextRowidValid = 0; } } if( pC->useRandomRowid ){ assert( pOp->p3==0 ); /* SQLITE_FULL must have occurred prior to this */ v = db->priorNewRowid; cnt = 0; do{ if( v==0 || cnt>2 ){ sqlite3Randomness(sizeof(v), &v); if( cnt<5 ) v &= 0xffffff; }else{ |
︙ | ︙ | |||
3589 3590 3591 3592 3593 3594 3595 | goto abort_due_to_error; } } pC->rowidIsValid = 0; pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; } | | < < < | < < | 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 | goto abort_due_to_error; } } pC->rowidIsValid = 0; pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; } pOut->flags = MEM_Int; pOut->u.i = v; break; } /* Opcode: Insert P1 P2 P3 P4 P5 ** ** Write an entry into the table of cursor P1. A new entry is ** created if it doesn't already exist or the data for an existing |
︙ | ︙ | |||
3856 3857 3858 3859 3860 3861 3862 | pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ break; } /* Opcode: Rowid P1 P2 * * * ** ** Store in register P2 an integer which is the key of the table entry that | | | < < < < < < < < | | | | 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 | pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ break; } /* Opcode: Rowid P1 P2 * * * ** ** Store in register P2 an integer which is the key of the table entry that ** P1 is currently point to. If p2==0 then push the integer. */ case OP_Rowid: { /* out2-prerelease */ int i = pOp->p1; Cursor *pC; i64 v; assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); rc = sqlite3VdbeCursorMoveto(pC); if( rc ) goto abort_due_to_error; if( pC->rowidIsValid ){ v = pC->lastRowid; }else if( pC->pseudoTable ){ v = keyToInt(pC->iKey); }else if( pC->nullRow || pC->pCursor==0 ){ /* Leave the rowid set to a NULL */ break; }else{ assert( pC->pCursor!=0 ); sqlite3BtreeKeySize(pC->pCursor, &v); v = keyToInt(v); } pOut->u.i = v; pOut->flags = MEM_Int; break; } /* Opcode: NullRow P1 * * ** ** Move the cursor P1 to a null row. Any OP_Column operations ** that occur while the cursor is on the null row will always push |
︙ | ︙ | |||
4117 4118 4119 4120 4121 4122 4123 | ** ** Write into register P2 an integer which is the last entry in the record at ** the end of the index key pointed to by cursor P1. This integer should be ** the rowid of the table entry to which this index entry points. ** ** See also: Rowid, MakeIdxRec. */ | | < < < < < < < < < | < < | | | 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 | ** ** Write into register P2 an integer which is the last entry in the record at ** the end of the index key pointed to by cursor P1. This integer should be ** the rowid of the table entry to which this index entry points. ** ** See also: Rowid, MakeIdxRec. */ case OP_IdxRowid: { /* out2-prerelease */ int i = pOp->p1; BtCursor *pCrsr; Cursor *pC; assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ i64 rowid; assert( pC->deferredMoveto==0 ); assert( pC->isTable==0 ); if( !pC->nullRow ){ rc = sqlite3VdbeIdxRowid(pCrsr, &rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } pOut->flags = MEM_Int; pOut->u.i = rowid; } } break; } /* Opcode: IdxGT P1 P2 * ** |
︙ | ︙ | |||
4338 4339 4340 4341 4342 4343 4344 | } #endif assert( (p->btreeMask & (1<<pOp->p2))!=0 ); rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1); break; } | | | | | > | | | > | | | < < < | 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 | } #endif assert( (p->btreeMask & (1<<pOp->p2))!=0 ); rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1); break; } /* Opcode: CreateTable P1 P2 * * * ** ** Allocate a new table in the main database file if P1==0 or in the ** auxiliary database file if P1==1 or in an attached database if ** P1>1. Write the root page number of the new table into ** register P2 or push it onto the stack if P2==0. ** ** The difference between a table and an index is this: A table must ** have a 4-byte integer key and can have arbitrary data. An index ** has an arbitrary key but no data. ** ** See also: CreateIndex */ /* Opcode: CreateIndex P1 P2 * * * ** ** Allocate a new index in the main database file if P1==0 or in the ** auxiliary database file if P1==1 or in an attached database if ** P1>1. Write the root page number of the new table into ** register P2 or push it onto the stack if P2==0. ** ** See documentation on OP_CreateTable for additional information. */ case OP_CreateIndex: /* out2-prerelease */ case OP_CreateTable: { /* out2-prerelease */ int pgno; int flags; Db *pDb; assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( (p->btreeMask & (1<<pOp->p1))!=0 ); pDb = &db->aDb[pOp->p1]; assert( pDb->pBt!=0 ); if( pOp->opcode==OP_CreateTable ){ /* flags = BTREE_INTKEY; */ flags = BTREE_LEAFDATA|BTREE_INTKEY; }else{ flags = BTREE_ZERODATA; } rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags); if( rc==SQLITE_OK ){ pTos->u.i = pgno; pTos->flags = MEM_Int; } break; } /* Opcode: ParseSchema P1 P2 P4 ** ** Read and parse all entries from the SQLITE_MASTER table of database P1 |
︙ | ︙ | |||
4780 4781 4782 4783 4784 4785 4786 | assert( i>0 && i<=p->nMem ); if( p->aMem[i].flags & MEM_Null ){ pc = pOp->p2 - 1; } break; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 | assert( i>0 && i<=p->nMem ); if( p->aMem[i].flags & MEM_Null ){ pc = pOp->p2 - 1; } 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 ** function has P2 arguments. P4 is a pointer to the FuncDef ** structure that specifies the function. Use memory location ** P1 as the accumulator. ** |
︙ | ︙ | |||
5137 5138 5139 5140 5141 5142 5143 | #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VRowid P1 P2 * ** ** Store into register P2 the rowid of ** the virtual-table that the P1 cursor is pointing to. ** If P2==0, push the value onto the stack. */ | | < < < < < < < < < | | | 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 | #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VRowid P1 P2 * ** ** Store into register P2 the rowid of ** the virtual-table that the P1 cursor is pointing to. ** If P2==0, push the value onto the stack. */ case OP_VRowid: { /* out2-prerelease */ const sqlite3_module *pModule; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); pModule = pCur->pVtabCursor->pVtab->pModule; if( pModule->xRowid==0 ){ sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xRowid", 0); rc = SQLITE_ERROR; } else { sqlite_int64 iRow; if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = pModule->xRowid(pCur->pVtabCursor, &iRow); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; pOut->flags = MEM_Int; pOut->u.i = iRow; } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
287 288 289 290 291 292 293 | doesStatementRollback = 1; #ifndef SQLITE_OMIT_VIRTUALTABLE }else if( opcode==OP_VUpdate || opcode==OP_VRename ){ doesStatementRollback = 1; }else if( opcode==OP_VFilter ){ int n; assert( p->nOp - i >= 3 ); | | | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | doesStatementRollback = 1; #ifndef SQLITE_OMIT_VIRTUALTABLE }else if( opcode==OP_VUpdate || opcode==OP_VRename ){ doesStatementRollback = 1; }else if( opcode==OP_VFilter ){ int n; assert( p->nOp - i >= 3 ); assert( pOp[-1].opcode==OP_Integer ); n = pOp[-1].p1; if( n>nMaxArgs ) nMaxArgs = n; #endif } if( !sqlite3VdbeOpcodeHasProperty(opcode, OPFLG_PUSH) ){ nMaxStack--; } |
︙ | ︙ |
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.273 2008/01/04 22:01:03 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
2257 2258 2259 2260 2261 2262 2263 | /* 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; | | | 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 | /* 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_Integer, 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 ** to access the data. |
︙ | ︙ | |||
2289 2290 2291 2292 2293 2294 2295 | } } if( k==nConstraint ) break; } iReg = ++pParse->nMem; pParse->nMem++; sqlite3StackToReg(pParse, j-1); | | | | 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 | } } if( k==nConstraint ) break; } iReg = ++pParse->nMem; pParse->nMem++; sqlite3StackToReg(pParse, j-1); sqlite3VdbeAddOp2(v, OP_Integer, pBestIdx->idxNum, iReg); sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1); sqlite3VdbeAddOp4(v, OP_VFilter, iCur, brk, iReg, pBestIdx->idxStr, pBestIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC); pBestIdx->needToFreeIdxStr = 0; for(j=0; j<pBestIdx->nConstraint; j++){ if( aUsage[j].omit ){ int iTerm = aConstraint[j].iTermOffset; disableTerm(pLevel, &wc.a[iTerm]); |
︙ | ︙ | |||
2604 2605 2606 2607 2608 2609 2610 | } /* For a LEFT OUTER JOIN, generate code that will record the fact that ** at least one row of the right table has matched the left table. */ if( pLevel->iLeftJoin ){ pLevel->top = sqlite3VdbeCurrentAddr(v); | | | 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 | } /* For a LEFT OUTER JOIN, generate code that will record the fact that ** at least one row of the right table has matched the left table. */ if( pLevel->iLeftJoin ){ pLevel->top = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); VdbeComment((v, "record LEFT JOIN hit")); for(pTerm=wc.a, j=0; j<wc.nTerm; j++, pTerm++){ if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( (pTerm->prereqAll & notReady)!=0 ) continue; assert( pTerm->pExpr ); sqlite3ExprIfFalse(pParse, pTerm->pExpr, cont, 1); pTerm->flags |= TERM_CODED; |
︙ | ︙ |