aboutsummaryrefslogtreecommitdiff
path: root/src/update.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/update.c')
-rw-r--r--src/update.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/src/update.c b/src/update.c
index 94e169fd0..c9ec95bb6 100644
--- a/src/update.c
+++ b/src/update.c
@@ -80,6 +80,29 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
}
/*
+** Check to see if column iCol of index pIdx references any of the
+** columns defined by aXRef and chngRowid. Return true if it does
+** and false if not.
+**
+** The iCol-th column of pIdx will be an expression.
+**
+** aXRef[j] will be non-negative if column j of the original table is
+** being updated. chngRowid will be true if the rowid of the table is
+** being updated.
+*/
+static int indexExprRefsUpdatedColumn(
+ Index *pIdx, /* The index containing the expression to analyze */
+ int iCol, /* Which column of the index is the expression */
+ int *aXRef, /* aXRef[j]>=0 if column j is being updated */
+ int chngRowid /* true if the rowid is being updated */
+){
+ assert( pIdx->aColExpr!=0 );
+ assert( pIdx->aColExpr->a[iCol].pExpr!=0 );
+ return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr,
+ aXRef,chngRowid);
+}
+
+/*
** Process an UPDATE statement.
**
** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
@@ -302,8 +325,6 @@ void sqlite3Update(
/* There is one entry in the aRegIdx[] array for each index on the table
** being updated. Fill in aRegIdx[] with a register number that will hold
** the key for accessing each index.
- **
- ** FIXME: Be smarter about omitting indexes that use expressions.
*/
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int reg;
@@ -314,7 +335,11 @@ void sqlite3Update(
reg = 0;
for(i=0; i<pIdx->nKeyCol; i++){
i16 iIdxCol = pIdx->aiColumn[i];
- if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
+ if( (iIdxCol>=0 && aXRef[iIdxCol]>=0)
+ || iIdxCol==XN_ROWID
+ || (iIdxCol==XN_EXPR
+ && indexExprRefsUpdatedColumn(pIdx,i,aXRef,chngRowid))
+ ){
reg = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
if( (onError==OE_Replace)