Index: third_party/sqlite/src/src/fkey.c |
diff --git a/third_party/sqlite/src/src/fkey.c b/third_party/sqlite/src/src/fkey.c |
index 2abd06c693b7614977c4bc8c221b0a889ed80b69..cb78764f513a8fe0c29fdd2484783e2a487e99b4 100644 |
--- a/third_party/sqlite/src/src/fkey.c |
+++ b/third_party/sqlite/src/src/fkey.c |
@@ -219,13 +219,13 @@ int sqlite3FkLocateIndex( |
} |
}else if( paiCol ){ |
assert( nCol>1 ); |
- aiCol = (int *)sqlite3DbMallocRaw(pParse->db, nCol*sizeof(int)); |
+ aiCol = (int *)sqlite3DbMallocRawNN(pParse->db, nCol*sizeof(int)); |
if( !aiCol ) return 1; |
*paiCol = aiCol; |
} |
for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ |
- if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) ){ |
+ if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) && pIdx->pPartIdxWhere==0 ){ |
/* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number |
** of columns. If each indexed column corresponds to a foreign key |
** column of pFKey, then this index is a winner. */ |
@@ -584,7 +584,7 @@ static void fkScanChildren( |
assert( iCol>=0 ); |
zCol = pFKey->pFrom->aCol[iCol].zName; |
pRight = sqlite3Expr(db, TK_ID, zCol); |
- pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0); |
+ pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight); |
pWhere = sqlite3ExprAnd(db, pWhere, pEq); |
} |
@@ -606,7 +606,7 @@ static void fkScanChildren( |
if( HasRowid(pTab) ){ |
pLeft = exprTableRegister(pParse, pTab, regData, -1); |
pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1); |
- pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0); |
+ pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight); |
}else{ |
Expr *pEq, *pAll = 0; |
Index *pPk = sqlite3PrimaryKeyIndex(pTab); |
@@ -616,10 +616,10 @@ static void fkScanChildren( |
assert( iCol>=0 ); |
pLeft = exprTableRegister(pParse, pTab, regData, iCol); |
pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol); |
- pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0); |
+ pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight); |
pAll = sqlite3ExprAnd(db, pAll, pEq); |
} |
- pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0, 0); |
+ pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0); |
} |
pWhere = sqlite3ExprAnd(db, pWhere, pNe); |
} |
@@ -871,7 +871,7 @@ void sqlite3FkCheck( |
if( (db->flags&SQLITE_ForeignKeys)==0 ) return; |
iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
- zDb = db->aDb[iDb].zName; |
+ zDb = db->aDb[iDb].zDbSName; |
/* Loop through all the foreign key constraints for which pTab is the |
** child table (the table that the foreign key definition is part of). */ |
@@ -1007,7 +1007,7 @@ void sqlite3FkCheck( |
struct SrcList_item *pItem = pSrc->a; |
pItem->pTab = pFKey->pFrom; |
pItem->zName = pFKey->pFrom->zName; |
- pItem->pTab->nRef++; |
+ pItem->pTab->nTabRef++; |
pItem->iCursor = pParse->nTab++; |
if( regNew!=0 ){ |
@@ -1162,10 +1162,12 @@ static Trigger *fkActionTrigger( |
int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ |
action = pFKey->aAction[iAction]; |
+ if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){ |
+ return 0; |
+ } |
pTrigger = pFKey->apTrigger[iAction]; |
if( action!=OE_None && !pTrigger ){ |
- u8 enableLookaside; /* Copy of db->lookaside.bEnabled */ |
char const *zFrom; /* Name of child table */ |
int nFrom; /* Length in bytes of zFrom */ |
Index *pIdx = 0; /* Parent key index for this FK */ |
@@ -1192,11 +1194,9 @@ static Trigger *fkActionTrigger( |
assert( iFromCol>=0 ); |
assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) ); |
assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); |
- tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName; |
- tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName; |
- |
- tToCol.n = sqlite3Strlen30(tToCol.z); |
- tFromCol.n = sqlite3Strlen30(tFromCol.z); |
+ sqlite3TokenInit(&tToCol, |
+ pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName); |
+ sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zName); |
/* Create the expression "OLD.zToCol = zFromCol". It is important |
** that the "OLD.zToCol" term is on the LHS of the = operator, so |
@@ -1205,10 +1205,9 @@ static Trigger *fkActionTrigger( |
pEq = sqlite3PExpr(pParse, TK_EQ, |
sqlite3PExpr(pParse, TK_DOT, |
sqlite3ExprAlloc(db, TK_ID, &tOld, 0), |
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0) |
- , 0), |
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), |
sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0) |
- , 0); |
+ ); |
pWhere = sqlite3ExprAnd(db, pWhere, pEq); |
/* For ON UPDATE, construct the next term of the WHEN clause. |
@@ -1220,13 +1219,11 @@ static Trigger *fkActionTrigger( |
pEq = sqlite3PExpr(pParse, TK_IS, |
sqlite3PExpr(pParse, TK_DOT, |
sqlite3ExprAlloc(db, TK_ID, &tOld, 0), |
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0), |
- 0), |
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), |
sqlite3PExpr(pParse, TK_DOT, |
sqlite3ExprAlloc(db, TK_ID, &tNew, 0), |
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0), |
- 0), |
- 0); |
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)) |
+ ); |
pWhen = sqlite3ExprAnd(db, pWhen, pEq); |
} |
@@ -1235,17 +1232,16 @@ static Trigger *fkActionTrigger( |
if( action==OE_Cascade ){ |
pNew = sqlite3PExpr(pParse, TK_DOT, |
sqlite3ExprAlloc(db, TK_ID, &tNew, 0), |
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0) |
- , 0); |
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)); |
}else if( action==OE_SetDflt ){ |
Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt; |
if( pDflt ){ |
pNew = sqlite3ExprDup(db, pDflt, 0); |
}else{ |
- pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); |
+ pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0); |
} |
}else{ |
- pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); |
+ pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0); |
} |
pList = sqlite3ExprListAppend(pParse, pList, pNew); |
sqlite3ExprListSetName(pParse, pList, &tFromCol, 0); |
@@ -1276,8 +1272,7 @@ static Trigger *fkActionTrigger( |
} |
/* Disable lookaside memory allocation */ |
- enableLookaside = db->lookaside.bEnabled; |
- db->lookaside.bEnabled = 0; |
+ db->lookaside.bDisable++; |
pTrigger = (Trigger *)sqlite3DbMallocZero(db, |
sizeof(Trigger) + /* struct Trigger */ |
@@ -1293,13 +1288,13 @@ static Trigger *fkActionTrigger( |
pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); |
pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); |
if( pWhen ){ |
- pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0); |
+ pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0); |
pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); |
} |
} |
/* Re-enable the lookaside buffer, if it was disabled earlier. */ |
- db->lookaside.bEnabled = enableLookaside; |
+ db->lookaside.bDisable--; |
sqlite3ExprDelete(db, pWhere); |
sqlite3ExprDelete(db, pWhen); |
@@ -1373,7 +1368,8 @@ void sqlite3FkDelete(sqlite3 *db, Table *pTab){ |
FKey *pFKey; /* Iterator variable */ |
FKey *pNext; /* Copy of pFKey->pNextFrom */ |
- assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); |
+ assert( db==0 || IsVirtual(pTab) |
+ || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); |
for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){ |
/* Remove the FK from the fkeyHash hash table. */ |