| 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. */
|
|
|