Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Update OP_Rowid, OP_Column and related opcodes to use registers. (CVS 4671) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4f3967073d2df9eae5a61b9770d5de2e |
User & Date: | drh 2008-01-03 18:44:59.000 |
Context
2008-01-03
| ||
18:56 | Fix typo in comment. Ticket #2870. (CVS 4672) (check-in: e97e457867 user: danielk1977 tags: trunk) | |
18:44 | Update OP_Rowid, OP_Column and related opcodes to use registers. (CVS 4671) (check-in: 4f3967073d user: drh tags: trunk) | |
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) | |
Changes
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.328 2008/01/03 18:44:59 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
1893 1894 1895 1896 1897 1898 1899 | } } } /* ** Generate code that will extract the iColumn-th column from | | | | | > > > > > > | | | | | 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 | } } } /* ** Generate code that will extract the iColumn-th column from ** table pTab and store the column value in register iMem, or on ** the stack if iMem==0. There is an open cursor to pTab in ** iTable. If iColumn<0 then code is generated that extracts the rowid. */ void sqlite3ExprCodeGetColumn( Vdbe *v, /* The VM being created */ Table *pTab, /* Description of the table we are reading from */ int iColumn, /* Index of the table column */ int iTable, /* The cursor pointing to the table */ int iReg /* Store results here */ ){ if( iColumn<0 ){ int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid; sqlite3VdbeAddOp2(v, op, iTable, iReg); }else if( pTab==0 ){ sqlite3VdbeAddOp3(v, OP_Column, iTable, iColumn, iReg); }else{ int op = IsVirtual(pTab) ? OP_VColumn : OP_Column; sqlite3VdbeAddOp3(v, op, iTable, iColumn, iReg); sqlite3ColumnDefault(v, pTab, iColumn); #ifndef SQLITE_OMIT_FLOATING_POINT if( pTab->aCol[iColumn].affinity==SQLITE_AFF_REAL ){ sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); } #endif } } /* ** Generate code into the current Vdbe to evaluate the given |
︙ | ︙ | |||
1956 1957 1958 1959 1960 1961 1962 | } case TK_COLUMN: { if( pExpr->iTable<0 ){ /* This only happens when coding check constraints */ assert( pParse->ckOffset>0 ); sqlite3VdbeAddOp2(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1); }else{ | | > | 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 | } case TK_COLUMN: { if( pExpr->iTable<0 ){ /* This only happens when coding check constraints */ assert( pParse->ckOffset>0 ); sqlite3VdbeAddOp2(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1); }else{ sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable, 0); } break; } case TK_INTEGER: { codeInteger(v, (char*)pExpr->token.z, pExpr->token.n, 0); break; } |
︙ | ︙ | |||
2357 2358 2359 2360 2361 2362 2363 | ** 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; | > > | < | > > > > > | > | 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 | ** 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; assert( v!=0 || pParse->db->mallocFailed ); assert( pExpr!=0 || pParse->db->mallocFailed ); if( v==0 || pExpr==0 ) return -1; if( target<=0 ){ target = ++pParse->nMem; } if( pExpr->op==TK_COLUMN && pExpr->iTable>=0 ){ sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable, target); }else{ sqlite3ExprCode(pParse, pExpr); sqlite3VdbeAddOp2(v, OP_MemStore, target, 1); } return target; } /* ** Generate code that pushes the value of every element of the given ** expression list onto the stack. ** |
︙ | ︙ |
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.382 2008/01/03 18:44:59 drh Exp $ */ #include "sqliteInt.h" /* ** Delete all the content of a Select structure but do not deallocate ** the select structure itself. |
︙ | ︙ | |||
3520 3521 3522 3523 3524 3525 3526 | groupBySort = 1; sqlite3ExprCodeExprList(pParse, pGroupBy); sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx, 0); j = pGroupBy->nExpr+1; for(i=0; i<sAggInfo.nColumn; i++){ struct AggInfo_col *pCol = &sAggInfo.aCol[i]; if( pCol->iSorterColumn<j ) continue; | | | 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 | groupBySort = 1; sqlite3ExprCodeExprList(pParse, pGroupBy); sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx, 0); j = pGroupBy->nExpr+1; for(i=0; i<sAggInfo.nColumn; i++){ struct AggInfo_col *pCol = &sAggInfo.aCol[i]; if( pCol->iSorterColumn<j ) continue; sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn,pCol->iTable,0); j++; } sqlite3VdbeAddOp2(v, OP_MakeRecord, j, 0); sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, 0); sqlite3WhereEnd(pWInfo); sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd); VdbeComment((v, "GROUP BY sort")); |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.635 2008/01/03 18:44:59 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** The macro unlikely() is a hint that surrounds a boolean ** expression that is usually false. Macro likely() surrounds |
︙ | ︙ | |||
1733 1734 1735 1736 1737 1738 1739 | Table *sqlite3SrcListLookup(Parse*, SrcList*); int sqlite3IsReadOnly(Parse*, Table*, int); void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**); void sqlite3WhereEnd(WhereInfo*); | | | 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 | Table *sqlite3SrcListLookup(Parse*, SrcList*); int sqlite3IsReadOnly(Parse*, Table*, int); void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**); void sqlite3WhereEnd(WhereInfo*); void sqlite3ExprCodeGetColumn(Vdbe*, Table*, int, int, int); void sqlite3ExprCode(Parse*, Expr*); void sqlite3ExprCodeAndCache(Parse*, Expr*); int sqlite3ExprIntoReg(Parse*,Expr*,int); int sqlite3ExprCodeExprList(Parse*, ExprList*); void sqlite3ExprIfTrue(Parse*, Expr*, int, int); void sqlite3ExprIfFalse(Parse*, Expr*, int, int); Table *sqlite3FindTable(sqlite3*,const char*, const char*); |
︙ | ︙ |
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.673 2008/01/03 18:44:59 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
1533 1534 1535 1536 1537 1538 1539 | }else{ Release(pTos); pTos->flags = MEM_Int; } break; } | | | | > | | > > > > > > | 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 | }else{ Release(pTos); pTos->flags = MEM_Int; } break; } /* Opcode: RealAffinity P1 * * ** ** If register P1 holds an integer convert it to a real value. ** ** This opcode is used when extracting information from a column that ** has REAL affinity. Such column values may still be stored as ** integers, for space efficiency, but after extraction we want them ** to have only a real value. */ case OP_RealAffinity: { /* no-push */ assert( pOp->p1>=0 && pOp->p1<=p->nMem ); if( pOp->p1==0 ){ if( pTos->flags & MEM_Int ){ sqlite3VdbeMemRealify(pTos); } }else{ Mem *pX = &p->aMem[pOp->p1]; if( pX->flags & MEM_Int ){ sqlite3VdbeMemRealify(pX); } } break; } #ifndef SQLITE_OMIT_CAST /* Opcode: ToText * * * ** |
︙ | ︙ | |||
3798 3799 3800 3801 3802 3803 3804 | }else{ pTos->flags = MEM_Null; } pTos->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ break; } | | | | > > > > > > | > | | | | 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 | }else{ pTos->flags = MEM_Null; } pTos->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 pust the integer. */ case OP_Rowid: { int i = pOp->p1; Cursor *pC; i64 v; Mem *pDest; assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); rc = sqlite3VdbeCursorMoveto(pC); if( rc ) goto abort_due_to_error; if( pOp->p2>0 ){ assert( pOp->p2<=p->nMem ); pDest = &p->aMem[pOp->p2]; sqlite3VdbeMemRelease(pDest); }else{ pDest = ++pTos; } if( pC->rowidIsValid ){ v = pC->lastRowid; }else if( pC->pseudoTable ){ v = keyToInt(pC->iKey); }else if( pC->nullRow || pC->pCursor==0 ){ pDest->flags = MEM_Null; break; }else{ assert( pC->pCursor!=0 ); sqlite3BtreeKeySize(pC->pCursor, &v); v = keyToInt(v); } pDest->u.i = v; pDest->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 |
︙ | ︙ | |||
4047 4048 4049 4050 4051 4052 4053 | pC->cacheStatus = CACHE_STALE; } Release(pTos); pTos--; break; } | | | > > > > > > | > | | | | | 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 | pC->cacheStatus = CACHE_STALE; } Release(pTos); pTos--; break; } /* Opcode: IdxRowid P1 P2 * * * ** ** 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: { int i = pOp->p1; BtCursor *pCrsr; Cursor *pC; Mem *pDest; assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( pOp->p2>0 ){ assert( pOp->p2<=p->nMem ); pDest = &p->aMem[pOp->p2]; sqlite3VdbeMemRelease(pDest); }else{ pDest = ++pTos; } pDest->flags = MEM_Null; if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ i64 rowid; assert( pC->deferredMoveto==0 ); assert( pC->isTable==0 ); if( pC->nullRow ){ pDest->flags = MEM_Null; }else{ rc = sqlite3VdbeIdxRowid(pCrsr, &rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } pDest->flags = MEM_Int; pDest->u.i = rowid; } } break; } /* Opcode: IdxGT P1 P2 * ** |
︙ | ︙ | |||
5047 5048 5049 5050 5051 5052 5053 | } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE | | | > > > > > > > | > | | | | | > > > > > > > | | > | | | 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 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 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 | } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #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: { 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; Mem *pDest; if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = pModule->xRowid(pCur->pVtabCursor, &iRow); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; if( pOp->p2>0 ){ assert( pOp->p2<=p->nMem ); pDest = &p->aMem[pOp->p2]; sqlite3VdbeMemRelease(pDest); }else{ pDest = ++pTos; } pDest->flags = MEM_Int; pDest->u.i = iRow; } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VColumn P1 P2 P3 ** ** Store the value of the P2-th column of ** the row of the virtual-table that the ** P1 cursor is pointing to into register P3. ** Or if P3==0 push the value onto the stack. */ case OP_VColumn: { const sqlite3_module *pModule; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); pModule = pCur->pVtabCursor->pVtab->pModule; if( pModule->xColumn==0 ){ sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xColumn", 0); rc = SQLITE_ERROR; } else { Mem *pDest; sqlite3_context sContext; memset(&sContext, 0, sizeof(sContext)); sContext.s.flags = MEM_Null; sContext.s.db = db; if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2); /* Copy the result of the function to the top of the stack. We ** do this regardless of whether or not an error occured to ensure any ** dynamic allocation in sContext.s (a Mem struct) is released. */ sqlite3VdbeChangeEncoding(&sContext.s, encoding); if( pOp->p3>0 ){ assert( pOp->p3<=p->nMem ); pDest = &p->aMem[pOp->p3]; }else{ pDest = ++pTos; pDest->flags = 0; } sqlite3VdbeMemMove(pDest, &sContext.s); if( sqlite3SafetyOn(db) ){ goto abort_due_to_misuse; } if( sqlite3VdbeMemTooBig(pDest) ){ goto too_big; } } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
︙ | ︙ |