Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Refactor names of column index transformation functions, for clarity. Get generated columns working with ALTER TABLE RENAME COLUMN. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | generated-columns |
Files: | files | file ages | folders |
SHA3-256: |
27ab41c9102e7801ff829488fc123a80 |
User & Date: | drh 2019-10-19 13:29:10.933 |
Context
2019-10-19
| ||
15:01 | Add testcase macros. (check-in: fb9c9bb284 user: drh tags: generated-columns) | |
13:29 | Refactor names of column index transformation functions, for clarity. Get generated columns working with ALTER TABLE RENAME COLUMN. (check-in: 27ab41c910 user: drh tags: generated-columns) | |
2019-10-18
| ||
18:33 | Fixes for WITHOUT ROWID tables with VIRTUAL columns and an INTEGER PRIMARY KEY. (check-in: 86074da0fd user: drh tags: generated-columns) | |
Changes
Changes to src/alter.c.
︙ | ︙ | |||
1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 | for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){ sqlite3WalkExprList(&sWalker, pIdx->aColExpr); } for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){ sqlite3WalkExprList(&sWalker, pIdx->aColExpr); } } for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ for(i=0; i<pFKey->nCol; i++){ if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){ renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]); } if( 0==sqlite3_stricmp(pFKey->zTo, zTable) | > > > > > | 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 | for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){ sqlite3WalkExprList(&sWalker, pIdx->aColExpr); } for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){ sqlite3WalkExprList(&sWalker, pIdx->aColExpr); } } #ifndef SQLITE_OMIT_GENERATED_COLUMNS for(i=0; i<sParse.pNewTable->nCol; i++){ sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); } #endif for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ for(i=0; i<pFKey->nCol; i++){ if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){ renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]); } if( 0==sqlite3_stricmp(pFKey->zTo, zTable) |
︙ | ︙ |
Changes to src/analyze.c.
︙ | ︙ | |||
1178 1179 1180 1181 1182 1183 1184 | if( HasRowid(pTab) ){ sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); }else{ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); int j, k, regKey; regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol); for(j=0; j<pPk->nKeyCol; j++){ | | | 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 | if( HasRowid(pTab) ){ sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); }else{ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); int j, k, regKey; regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol); for(j=0; j<pPk->nKeyCol; j++){ k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]); assert( k>=0 && k<pIdx->nColumn ); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName)); } sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid); sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol); } |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
873 874 875 876 877 878 879 | Index *sqlite3PrimaryKeyIndex(Table *pTab){ Index *p; for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){} return p; } /* | | > > | | | | | | | | | | | 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 | Index *sqlite3PrimaryKeyIndex(Table *pTab){ Index *p; for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){} return p; } /* ** Convert an table column number into a index column number. That is, ** for the column iCol in the table (as defined by the CREATE TABLE statement) ** find the (first) offset of that column in index pIdx. Or return -1 ** if column iCol is not used in index pIdx. */ i16 sqlite3TableColumnToIndex(Index *pIdx, i16 iCol){ int i; for(i=0; i<pIdx->nColumn; i++){ if( iCol==pIdx->aiColumn[i] ) return i; } return -1; } #ifndef SQLITE_OMIT_GENERATED_COLUMNS /* Convert a storage column number into a table column number. ** ** The storage column number (0,1,2,....) is the index of the value ** as it appears in the record on disk. The true column number ** is the index (0,1,2,...) of the column in the CREATE TABLE statement. ** ** The storage column number is less than the table column number if ** and only there are VIRTUAL columns to the left. ** ** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro. ** ** This function is the inverse of sqlite3TableColumnToStorage(). */ i16 sqlite3StorageColumnToTable(Table *pTab, i16 iCol){ if( pTab->tabFlags & TF_HasVirtual ){ int i; for(i=0; i<=iCol; i++){ if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) iCol++; } } return iCol; } #endif #ifndef SQLITE_OMIT_GENERATED_COLUMNS /* Convert a table column number into a storage column number. ** ** The storage column number (0,1,2,....) is the index of the value ** as it appears in the record on disk. The true column number ** is the index (0,1,2,...) of the column in the CREATE TABLE statement. ** ** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro. ** ** This function is the inverse of sqlite3StorageColumnToTable(). */ i16 sqlite3TableColumnToStorage(Table *pTab, i16 iCol){ int i; i16 n; assert( iCol<pTab->nCol ); if( (pTab->tabFlags & TF_HasVirtual)==0 ) return iCol; for(i=0, n=0; i<iCol; i++){ if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) n++; } |
︙ | ︙ | |||
1573 1574 1575 1576 1577 1578 1579 | ** column. */ void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){ #ifndef SQLITE_OMIT_GENERATED_COLUMNS u8 eType = COLFLAG_VIRTUAL; Table *pTab = pParse->pNewTable; Column *pCol; | < < < > > > > | > | 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 | ** column. */ void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){ #ifndef SQLITE_OMIT_GENERATED_COLUMNS u8 eType = COLFLAG_VIRTUAL; Table *pTab = pParse->pNewTable; Column *pCol; if( pTab==0 ) goto generated_done; pCol = &(pTab->aCol[pTab->nCol-1]); if( IN_DECLARE_VTAB ){ sqlite3ErrorMsg(pParse, "virtual tables cannot use computed columns"); goto generated_done; } if( pCol->pDflt ) goto generated_error; if( pType ){ if( pType->n==7 && sqlite3StrNICmp("virtual",pType->z,7)==0 ){ /* no-op */ }else if( pType->n==6 && sqlite3StrNICmp("stored",pType->z,6)==0 ){ eType = COLFLAG_STORED; }else{ goto generated_error; } } if( eType==COLFLAG_VIRTUAL ) pTab->nNVCol--; pCol->colFlags |= eType; assert( TF_HasVirtual==COLFLAG_VIRTUAL ); assert( TF_HasStored==COLFLAG_STORED ); pTab->tabFlags |= eType; pCol->pDflt = pExpr; pExpr = 0; goto generated_done; generated_error: sqlite3ErrorMsg(pParse, "incorrect GENERATED ALWAYS AS on column \"%s\"", pCol->zName); generated_done: sqlite3ExprDelete(pParse->db, pExpr); |
︙ | ︙ | |||
3647 3648 3649 3650 3651 3652 3653 | } sqlite3DefaultRowEst(pIndex); if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex); /* If this index contains every column of its table, then mark ** it as a covering index */ assert( HasRowid(pTab) | | | | 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 | } sqlite3DefaultRowEst(pIndex); if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex); /* If this index contains every column of its table, then mark ** it as a covering index */ assert( HasRowid(pTab) || pTab->iPKey<0 || sqlite3TableColumnToIndex(pIndex, pTab->iPKey)>=0 ); recomputeColumnsNotIndexed(pIndex); if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){ pIndex->isCovering = 1; for(j=0; j<pTab->nCol; j++){ if( j==pTab->iPKey ) continue; if( sqlite3TableColumnToIndex(pIndex,j)>=0 ) continue; pIndex->isCovering = 0; break; } } if( pTab==pParse->pNewTable ){ /* This routine has been called to create an automatic index as a |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
3406 3407 3408 3409 3410 3411 3412 | sqlite3ExprCode(pParse, pTab->aCol[iCol].pDflt, regOut); pParse->iSelfTab = savedSelfTab; pCol->colFlags &= ~COLFLAG_BUSY; } return; #endif }else if( !HasRowid(pTab) ){ | | | | 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 | sqlite3ExprCode(pParse, pTab->aCol[iCol].pDflt, regOut); pParse->iSelfTab = savedSelfTab; pCol->colFlags &= ~COLFLAG_BUSY; } return; #endif }else if( !HasRowid(pTab) ){ x = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), iCol); op = OP_Column; }else{ x = sqlite3TableColumnToStorage(pTab,iCol); op = OP_Column; } sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut); sqlite3ColumnDefault(v, pTab, iCol, regOut); } } |
︙ | ︙ | |||
3587 3588 3589 3590 3591 3592 3593 | assert( pTab!=0 ); assert( pExpr->iColumn>=XN_ROWID ); assert( pExpr->iColumn<pExpr->y.pTab->nCol ); if( pExpr->iColumn<0 ){ return -1-pParse->iSelfTab; } pCol = pTab->aCol + pExpr->iColumn; | > | | 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 | assert( pTab!=0 ); assert( pExpr->iColumn>=XN_ROWID ); assert( pExpr->iColumn<pExpr->y.pTab->nCol ); if( pExpr->iColumn<0 ){ return -1-pParse->iSelfTab; } pCol = pTab->aCol + pExpr->iColumn; iSrc = sqlite3TableColumnToStorage(pTab, pExpr->iColumn) - pParse->iSelfTab; #ifndef SQLITE_OMIT_GENERATED_COLUMNS if( pCol->colFlags & COLFLAG_GENERATED ){ if( pCol->colFlags & COLFLAG_BUSY ){ sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pCol->zName); return 0; } |
︙ | ︙ | |||
5316 5317 5318 5319 5320 5321 5322 | ** Check to see if there are references to columns in table ** pWalker->u.pIdxCover->iCur can be satisfied using the index ** pWalker->u.pIdxCover->pIdx. */ static int exprIdxCover(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_COLUMN && pExpr->iTable==pWalker->u.pIdxCover->iCur | | | 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 | ** Check to see if there are references to columns in table ** pWalker->u.pIdxCover->iCur can be satisfied using the index ** pWalker->u.pIdxCover->pIdx. */ static int exprIdxCover(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_COLUMN && pExpr->iTable==pWalker->u.pIdxCover->iCur && sqlite3TableColumnToIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0 ){ pWalker->eCode = 1; return WRC_Abort; } return WRC_Continue; } |
︙ | ︙ |
Changes to src/insert.c.
︙ | ︙ | |||
1051 1052 1053 1054 1055 1056 1057 | */ nHidden = 0; iRegStore = regRowid+1; for(i=0; i<pTab->nCol; i++, iRegStore++){ int k; u32 colFlags; assert( i>=nHidden ); | | | 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 | */ nHidden = 0; iRegStore = regRowid+1; for(i=0; i<pTab->nCol; i++, iRegStore++){ int k; u32 colFlags; assert( i>=nHidden ); assert( iRegStore==sqlite3TableColumnToStorage(pTab,i)+regRowid+1 ); if( i==pTab->iPKey ){ /* The value of the INTEGER PRIMARY KEY column is always a NULL. ** Whenever this column is read, the rowid will be substituted ** in its place. Hence, fill this column with a NULL to avoid ** taking up data space with information that will never be used. ** As there may be shallow copies of this value, make it a soft-NULL */ sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); |
︙ | ︙ | |||
1460 1461 1462 1463 1464 1465 1466 | iReg = ++pParse->nMem; assert( pParse->iSelfTab==0 ); pParse->iSelfTab = -regNewData; sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iReg); pParse->iSelfTab = 0; if( onError==OE_Replace ) onError = OE_Abort; }else{ | | | 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 | iReg = ++pParse->nMem; assert( pParse->iSelfTab==0 ); pParse->iSelfTab = -regNewData; sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iReg); pParse->iSelfTab = 0; if( onError==OE_Replace ) onError = OE_Abort; }else{ iReg = sqlite3TableColumnToStorage(pTab, i) + regNewData + 1; } switch( onError ){ case OE_Replace: { assert( onError==OE_Replace ); addr1 = sqlite3VdbeMakeLabel(pParse); sqlite3VdbeAddOp2(v, OP_NotNull, iReg, addr1); VdbeCoverage(v); |
︙ | ︙ | |||
1778 1779 1780 1781 1782 1783 1784 | }else if( pTab->aCol[iField].colFlags & COLFLAG_VIRTUAL ){ pParse->iSelfTab = -(regNewData+1); sqlite3ExprCodeCopy(pParse, pTab->aCol[iField].pDflt, regIdx+i); pParse->iSelfTab = 0; VdbeComment((v, "%s column %d", pIdx->zName, i)); #endif }else{ | | | 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 | }else if( pTab->aCol[iField].colFlags & COLFLAG_VIRTUAL ){ pParse->iSelfTab = -(regNewData+1); sqlite3ExprCodeCopy(pParse, pTab->aCol[iField].pDflt, regIdx+i); pParse->iSelfTab = 0; VdbeComment((v, "%s column %d", pIdx->zName, i)); #endif }else{ x = sqlite3TableColumnToStorage(pTab, iField) + regNewData + 1; sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i); VdbeComment((v, "%s", pTab->aCol[iField].zName)); } } sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]); VdbeComment((v, "for %s", pIdx->zName)); #ifdef SQLITE_ENABLE_NULL_TRIM |
︙ | ︙ | |||
1869 1870 1871 1872 1873 1874 1875 | }else{ int x; /* Extract the PRIMARY KEY from the end of the index entry and ** store it in registers regR..regR+nPk-1 */ if( pIdx!=pPk ){ for(i=0; i<pPk->nKeyCol; i++){ assert( pPk->aiColumn[i]>=0 ); | | | 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 | }else{ int x; /* Extract the PRIMARY KEY from the end of the index entry and ** store it in registers regR..regR+nPk-1 */ if( pIdx!=pPk ){ for(i=0; i<pPk->nKeyCol; i++){ assert( pPk->aiColumn[i]>=0 ); x = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i); VdbeComment((v, "%s.%s", pTab->zName, pTab->aCol[pPk->aiColumn[i]].zName)); } } if( isUpdate ){ /* If currently processing the PRIMARY KEY of a WITHOUT ROWID |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
1814 1815 1816 1817 1818 1819 1820 | int nRefModule; /* Number of pointers to this object */ void *pAux; /* pAux passed to create_module() */ void (*xDestroy)(void *); /* Module destructor function */ Table *pEpoTab; /* Eponymous table for this module */ }; /* | | | > > > > > > > > > > > > > | 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 | int nRefModule; /* Number of pointers to this object */ void *pAux; /* pAux passed to create_module() */ void (*xDestroy)(void *); /* Module destructor function */ Table *pEpoTab; /* Eponymous table for this module */ }; /* ** Information about each column of an SQL table is held in an instance ** of the Column structure, in the Table.aCol[] array. ** ** Definitions: ** ** "table column index" This is the index of the column in the ** Table.aCol[] array, and also the index of ** the column in the original CREATE TABLE stmt. ** ** "storage column index" This is the index of the column in the ** record BLOB generated by the OP_MakeRecord ** opcode. The storage column index is less than ** or equal to the table column index. It is ** equal if and only if there are no VIRTUAL ** columns to the left. */ struct Column { char *zName; /* Name of this column, \000, then the type */ Expr *pDflt; /* Default value or GENERATED ALWAYS AS value */ char *zColl; /* Collating sequence. If NULL, use the default */ u8 notNull; /* An OE_ code for handling a NOT NULL constraint */ char affinity; /* One of the SQLITE_AFF_... values */ |
︙ | ︙ | |||
3948 3949 3950 3951 3952 3953 3954 | void sqlite3CommitInternalChanges(sqlite3*); void sqlite3DeleteColumnNames(sqlite3*,Table*); int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char); Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); void sqlite3OpenMasterTable(Parse *, int); Index *sqlite3PrimaryKeyIndex(Table*); | | | | | | | 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 | void sqlite3CommitInternalChanges(sqlite3*); void sqlite3DeleteColumnNames(sqlite3*,Table*); int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char); Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); void sqlite3OpenMasterTable(Parse *, int); Index *sqlite3PrimaryKeyIndex(Table*); i16 sqlite3TableColumnToIndex(Index*, i16); #ifdef SQLITE_OMIT_GENERATED_COLUMNS # define sqlite3TableColumnToStorage(T,X) (X) /* No-op pass-through */ # define sqlite3StorageColumnToTable(T,X) (X) /* No-op pass-through */ #else i16 sqlite3TableColumnToStorage(Table*, i16); i16 sqlite3StorageColumnToTable(Table*, i16); #endif void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); #if SQLITE_ENABLE_HIDDEN_COLUMNS void sqlite3ColumnPropertiesFromName(Table*, Column*); #else # define sqlite3ColumnPropertiesFromName(T,C) /* no-op */ #endif |
︙ | ︙ |
Changes to src/upsert.c.
︙ | ︙ | |||
222 223 224 225 226 227 228 | Index *pPk = sqlite3PrimaryKeyIndex(pTab); int nPk = pPk->nKeyCol; int iPk = pParse->nMem+1; pParse->nMem += nPk; for(i=0; i<nPk; i++){ int k; assert( pPk->aiColumn[i]>=0 ); | | | 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | Index *pPk = sqlite3PrimaryKeyIndex(pTab); int nPk = pPk->nKeyCol; int iPk = pParse->nMem+1; pParse->nMem += nPk; for(i=0; i<nPk; i++){ int k; assert( pPk->aiColumn[i]>=0 ); k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i); VdbeComment((v, "%s.%s", pIdx->zName, pTab->aCol[pPk->aiColumn[i]].zName)); } sqlite3VdbeVerifyAbortable(v, OE_Abort); i = sqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk); VdbeCoverage(v); |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
1827 1828 1829 1830 1831 1832 1833 | /* Test that this call is being made from within an SQLITE_DELETE or ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */ if( !p || p->op==SQLITE_INSERT ){ rc = SQLITE_MISUSE_BKPT; goto preupdate_old_out; } if( p->pPk ){ | | | 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 | /* Test that this call is being made from within an SQLITE_DELETE or ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */ if( !p || p->op==SQLITE_INSERT ){ rc = SQLITE_MISUSE_BKPT; goto preupdate_old_out; } if( p->pPk ){ iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx); } if( iIdx>=p->pCsr->nField || iIdx<0 ){ rc = SQLITE_RANGE; goto preupdate_old_out; } /* If the old.* record has not yet been loaded into memory, do so now. */ |
︙ | ︙ | |||
1917 1918 1919 1920 1921 1922 1923 | Mem *pMem; if( !p || p->op==SQLITE_DELETE ){ rc = SQLITE_MISUSE_BKPT; goto preupdate_new_out; } if( p->pPk && p->op!=SQLITE_UPDATE ){ | | | 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 | Mem *pMem; if( !p || p->op==SQLITE_DELETE ){ rc = SQLITE_MISUSE_BKPT; goto preupdate_new_out; } if( p->pPk && p->op!=SQLITE_UPDATE ){ iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx); } if( iIdx>=p->pCsr->nField || iIdx<0 ){ rc = SQLITE_RANGE; goto preupdate_new_out; } if( p->op==SQLITE_INSERT ){ |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
5375 5376 5377 5378 5379 5380 5381 | int x = pOp->p2; assert( pIdx->pTable==pTab ); if( !HasRowid(pTab) ){ Index *pPk = sqlite3PrimaryKeyIndex(pTab); x = pPk->aiColumn[x]; assert( x>=0 ); }else{ | | | | 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 | int x = pOp->p2; assert( pIdx->pTable==pTab ); if( !HasRowid(pTab) ){ Index *pPk = sqlite3PrimaryKeyIndex(pTab); x = pPk->aiColumn[x]; assert( x>=0 ); }else{ x = sqlite3StorageColumnToTable(pTab,x); } x = sqlite3TableColumnToIndex(pIdx, x); if( x>=0 ){ pOp->p2 = x; pOp->p1 = pLevel->iIdxCur; OpcodeRewriteTrace(db, k, pOp); } assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 || pWInfo->eOnePass ); |
︙ | ︙ |
Changes to src/wherecode.c.
︙ | ︙ | |||
819 820 821 822 823 824 825 | ** accessed through the index. If it cannot, then set pWalker->eCode to 1. */ static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){ struct CCurHint *pHint = pWalker->u.pCCurHint; assert( pHint->pIdx!=0 ); if( pExpr->op==TK_COLUMN && pExpr->iTable==pHint->iTabCur | | | 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 | ** accessed through the index. If it cannot, then set pWalker->eCode to 1. */ static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){ struct CCurHint *pHint = pWalker->u.pCCurHint; assert( pHint->pIdx!=0 ); if( pExpr->op==TK_COLUMN && pExpr->iTable==pHint->iTabCur && sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn)<0 ){ pWalker->eCode = 1; } return WRC_Continue; } /* |
︙ | ︙ | |||
887 888 889 890 891 892 893 | if( pExpr->iTable!=pHint->iTabCur ){ int reg = ++pWalker->pParse->nMem; /* Register for column value */ sqlite3ExprCode(pWalker->pParse, pExpr, reg); pExpr->op = TK_REGISTER; pExpr->iTable = reg; }else if( pHint->pIdx!=0 ){ pExpr->iTable = pHint->iIdxCur; | | | 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 | if( pExpr->iTable!=pHint->iTabCur ){ int reg = ++pWalker->pParse->nMem; /* Register for column value */ sqlite3ExprCode(pWalker->pParse, pExpr, reg); pExpr->op = TK_REGISTER; pExpr->iTable = reg; }else if( pHint->pIdx!=0 ){ pExpr->iTable = pHint->iIdxCur; pExpr->iColumn = sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn); assert( pExpr->iColumn>=0 ); } }else if( pExpr->op==TK_AGG_FUNCTION ){ /* An aggregate function in the WHERE clause of a query means this must ** be a correlated sub-query, and expression pExpr is an aggregate from ** the parent context. Do not walk the function arguments in this case. ** |
︙ | ︙ | |||
1822 1823 1824 1825 1826 1827 1828 | }else{ codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur); } }else if( iCur!=iIdxCur ){ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol); for(j=0; j<pPk->nKeyCol; j++){ | | | 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 | }else{ codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur); } }else if( iCur!=iIdxCur ){ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol); for(j=0; j<pPk->nKeyCol; j++){ k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j); } sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont, iRowidReg, pPk->nKeyCol); VdbeCoverage(v); } /* If pIdx is an index on one or more expressions, then look through |
︙ | ︙ |