aboutsummaryrefslogtreecommitdiff
path: root/src/fkey.c
diff options
context:
space:
mode:
authordan <dan@noemail.net>2009-09-22 16:55:38 +0000
committerdan <dan@noemail.net>2009-09-22 16:55:38 +0000
commitf59c5cacb8bf8227e3b1ebd7e33055deebbf23cd (patch)
tree77bcc1799fc0effd7156c5fdb64214387801c9f4 /src/fkey.c
parent934ce300a0fbeceb739434a37caa231655aabec5 (diff)
downloadsqlite-f59c5cacb8bf8227e3b1ebd7e33055deebbf23cd.tar.gz
sqlite-f59c5cacb8bf8227e3b1ebd7e33055deebbf23cd.zip
Fix another OOM related problem in fkey.c.
FossilOrigin-Name: e2bc51bc61d54d103ccffd12106c27a574e4e997
Diffstat (limited to 'src/fkey.c')
-rw-r--r--src/fkey.c87
1 files changed, 45 insertions, 42 deletions
diff --git a/src/fkey.c b/src/fkey.c
index ceb5bedce..32aef9bbe 100644
--- a/src/fkey.c
+++ b/src/fkey.c
@@ -364,7 +364,9 @@ static void fkScanReferences(
pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
);
}
- sqlite3WhereEnd(pWInfo);
+ if( pWInfo ){
+ sqlite3WhereEnd(pWInfo);
+ }
/* Clean up the WHERE clause constructed above. */
sqlite3ExprDelete(db, pWhere);
@@ -510,49 +512,50 @@ void sqlite3FkCheck(
** the foreign key that refers to this table is attached to). This
** is required for the sqlite3WhereXXX() interface. */
pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
- if( !pSrc ) return;
- pSrc->a->pTab = pFKey->pFrom;
- pSrc->a->pTab->nRef++;
- pSrc->a->iCursor = pParse->nTab++;
-
- /* If this is an UPDATE, and none of the columns associated with this
- ** FK have been modified, do not scan the referencing table. Unlike
- ** the compile-time test implemented above, this is not just an
- ** optimization. It is required so that immediate foreign keys do not
- ** throw exceptions when the user executes a statement like:
- **
- ** UPDATE refd_table SET refd_column = refd_column
- */
- if( pChanges ){
- int i;
- int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1;
- for(i=0; i<pFKey->nCol; i++){
- int iOff = (pIdx ? pIdx->aiColumn[i] : -1) + 1;
- sqlite3VdbeAddOp3(v, OP_Ne, regOld+iOff, iJump, regNew+iOff);
+ if( pSrc ){
+ pSrc->a->pTab = pFKey->pFrom;
+ pSrc->a->pTab->nRef++;
+ pSrc->a->iCursor = pParse->nTab++;
+
+ /* If this is an UPDATE, and none of the columns associated with this
+ ** FK have been modified, do not scan the referencing table. Unlike
+ ** the compile-time test implemented above, this is not just an
+ ** optimization. It is required so that immediate foreign keys do not
+ ** throw exceptions when the user executes a statement like:
+ **
+ ** UPDATE refd_table SET refd_column = refd_column
+ */
+ if( pChanges ){
+ int i;
+ int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1;
+ for(i=0; i<pFKey->nCol; i++){
+ int iOff = (pIdx ? pIdx->aiColumn[i] : -1) + 1;
+ sqlite3VdbeAddOp3(v, OP_Ne, regOld+iOff, iJump, regNew+iOff);
+ }
+ iGoto = sqlite3VdbeAddOp0(v, OP_Goto);
}
- iGoto = sqlite3VdbeAddOp0(v, OP_Goto);
- }
-
- if( regNew!=0 && pFKey->isDeferred ){
- fkScanReferences(pParse, pSrc, pIdx, pFKey, aiCol, regNew, -1);
- }
- if( regOld!=0 ){
- /* If there is a RESTRICT action configured for the current operation
- ** on the referenced table of this FK, then throw an exception
- ** immediately if the FK constraint is violated, even if this is a
- ** deferred trigger. That's what RESTRICT means. To defer checking
- ** the constraint, the FK should specify NO ACTION (represented
- ** using OE_None). NO ACTION is the default. */
- fkScanReferences(pParse, pSrc, pIdx, pFKey, aiCol, regOld,
- (pChanges!=0 && pFKey->updateConf!=OE_Restrict)
- || (pChanges==0 && pFKey->deleteConf!=OE_Restrict)
- );
- }
-
- if( pChanges ){
- sqlite3VdbeJumpHere(v, iGoto);
+
+ if( regNew!=0 && pFKey->isDeferred ){
+ fkScanReferences(pParse, pSrc, pIdx, pFKey, aiCol, regNew, -1);
+ }
+ if( regOld!=0 ){
+ /* If there is a RESTRICT action configured for the current operation
+ ** on the referenced table of this FK, then throw an exception
+ ** immediately if the FK constraint is violated, even if this is a
+ ** deferred trigger. That's what RESTRICT means. To defer checking
+ ** the constraint, the FK should specify NO ACTION (represented
+ ** using OE_None). NO ACTION is the default. */
+ fkScanReferences(pParse, pSrc, pIdx, pFKey, aiCol, regOld,
+ (pChanges!=0 && pFKey->updateConf!=OE_Restrict)
+ || (pChanges==0 && pFKey->deleteConf!=OE_Restrict)
+ );
+ }
+
+ if( pChanges ){
+ sqlite3VdbeJumpHere(v, iGoto);
+ }
+ sqlite3SrcListDelete(db, pSrc);
}
- sqlite3SrcListDelete(db, pSrc);
sqlite3DbFree(db, aiCol);
}
}