Index: src/pragma.c ================================================================== --- src/pragma.c +++ src/pragma.c @@ -1608,12 +1608,12 @@ if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow; sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead); sqlite3VdbeAddOp4(v, OP_String8, 0, regResult, 0, pTab->zName, P4_TRANSIENT); for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ - pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb); - if( pParent==0 ) break; + pParent = sqlite3FindTable(db, pFK->zTo, zDb); + if( pParent==0 ) continue; pIdx = 0; sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName); x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0); if( x==0 ){ if( pIdx==0 ){ @@ -1626,22 +1626,24 @@ }else{ k = 0; break; } } + assert( pParse->nErr>0 || pFK==0 ); if( pFK ) break; if( pParse->nTabnTab = i; addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ - pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb); - assert( pParent!=0 ); + pParent = sqlite3FindTable(db, pFK->zTo, zDb); pIdx = 0; aiCols = 0; - x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); - assert( x==0 ); + if( pParent ){ + x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); + assert( x==0 ); + } addrOk = sqlite3VdbeMakeLabel(v); - if( pIdx==0 ){ + if( pParent && pIdx==0 ){ int iKey = pFK->aCol[0].iFrom; assert( iKey>=0 && iKeynCol ); if( iKey!=pTab->iPKey ){ sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow); sqlite3ColumnDefault(v, pTab, iKey, regRow); @@ -1655,17 +1657,19 @@ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk); sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); }else{ for(j=0; jnCol; j++){ sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, - aiCols ? aiCols[j] : pFK->aCol[0].iFrom, regRow+j); + aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j); sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); } - sqlite3VdbeAddOp3(v, OP_MakeRecord, regRow, pFK->nCol, regKey); - sqlite3VdbeChangeP4(v, -1, - sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT); - sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); + if( pParent ){ + sqlite3VdbeAddOp3(v, OP_MakeRecord, regRow, pFK->nCol, regKey); + sqlite3VdbeChangeP4(v, -1, + sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT); + sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); + } } sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1); sqlite3VdbeAddOp4(v, OP_String8, 0, regResult+2, 0, pFK->zTo, P4_TRANSIENT); sqlite3VdbeAddOp2(v, OP_Integer, i-1, regResult+3); Index: test/fkey5.test ================================================================== --- test/fkey5.test +++ test/fkey5.test @@ -15,10 +15,11 @@ # EVIDENCE-OF: R-05426-18119 PRAGMA foreign_key_check; PRAGMA # foreign_key_check(table-name); set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix fkey5 ifcapable {!foreignkey} { finish_test return } @@ -322,8 +323,41 @@ INSERT INTO c22 VALUES('abc ','ALPHA'); PRAGMA foreign_key_check(c22); } } {} + +#------------------------------------------------------------------------- +# Tests 9.* verify that missing parent tables are handled correctly. +# +do_execsql_test 9.1.1 { + CREATE TABLE k1(x REFERENCES s1); + PRAGMA foreign_key_check(k1); +} {} +do_execsql_test 9.1.2 { + INSERT INTO k1 VALUES(NULL); + PRAGMA foreign_key_check(k1); +} {} +do_execsql_test 9.1.3 { + INSERT INTO k1 VALUES(1); + PRAGMA foreign_key_check(k1); +} {k1 2 s1 0} + +do_execsql_test 9.2.1 { + CREATE TABLE k2(x, y, FOREIGN KEY(x, y) REFERENCES s1(a, b)); + PRAGMA foreign_key_check(k2); +} {} +do_execsql_test 9.2 { + INSERT INTO k2 VALUES(NULL, 'five'); + PRAGMA foreign_key_check(k2); +} {} +do_execsql_test 9.3 { + INSERT INTO k2 VALUES('one', NULL); + PRAGMA foreign_key_check(k2); +} {} +do_execsql_test 9.4 { + INSERT INTO k2 VALUES('six', 'seven'); + PRAGMA foreign_key_check(k2); +} {k2 3 s1 0} finish_test