aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <dan@noemail.net>2018-12-20 17:32:33 +0000
committerdan <dan@noemail.net>2018-12-20 17:32:33 +0000
commite46201e264082d02490e20f778b3f0fc00ba136f (patch)
treefc0fed1bd8b458816f6cacc0808924625f346be1 /src
parent16dd3985f0c78b77f0fd753ff151363d663d7413 (diff)
downloadsqlite-e46201e264082d02490e20f778b3f0fc00ba136f.tar.gz
sqlite-e46201e264082d02490e20f778b3f0fc00ba136f.zip
Fix a bug in the code that detects self-referencing rows as part of foreign
key processing. Fix for [50d2a6c2]. FossilOrigin-Name: 16fff05347f42fe9fa0f3150290b98b59a9bb921e49dc07ca397aa1de7a7e17d
Diffstat (limited to 'src')
-rw-r--r--src/fkey.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/src/fkey.c b/src/fkey.c
index 6777d71ea..8f465bb7b 100644
--- a/src/fkey.c
+++ b/src/fkey.c
@@ -602,8 +602,11 @@ static void fkScanChildren(
** NOT( $current_a==a AND $current_b==b AND ... )
**
** The first form is used for rowid tables. The second form is used
- ** for WITHOUT ROWID tables. In the second form, the primary key is
- ** (a,b,...)
+ ** for WITHOUT ROWID tables. In the second form, the *parent* key is
+ ** (a,b,...). Either the parent or primary key could be used to
+ ** uniquely identify the current row, but the parent key is more convenient
+ ** as the required values have already been loaded into registers
+ ** by the caller.
*/
if( pTab==pFKey->pFrom && nIncr>0 ){
Expr *pNe; /* Expression (pLeft != pRight) */
@@ -615,14 +618,13 @@ static void fkScanChildren(
pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight);
}else{
Expr *pEq, *pAll = 0;
- Index *pPk = sqlite3PrimaryKeyIndex(pTab);
assert( pIdx!=0 );
- for(i=0; i<pPk->nKeyCol; i++){
+ for(i=0; i<pIdx->nKeyCol; i++){
i16 iCol = pIdx->aiColumn[i];
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);
+ pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName);
+ pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight);
pAll = sqlite3ExprAnd(db, pAll, pEq);
}
pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);