Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a problem in "PRAGMA foreign_key_check" in handling a WITHOUT ROWID child table with an INTEGER PRIMARY KEY parent key. Also, if an FK violation is detected in a WITHOUT ROWID child table, do not try to read and return the rowid. The second column returned by "PRAGMA foreign_key_check" in this case (WITHOUT ROWID child table) is now always set to NULL. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
690870bd7b2e607b7992c4496c9f08c2 |
User & Date: | dan 2017-04-17 18:02:41 |
Original Comment: | Fix a problem in "PRAGMA foreign_key_check" in handling a WITHOUT ROWID child table with an INTEGER PRIMARY KEY parent key. Also, if an FK violation is detected in a WITHOUT ROWID child table, do not try to read and return the rowid. The third column returned by "PRAGMA foreign_key_check" in this case (WITHOUT ROWID child table) is now always set to NULL. |
Context
2017-04-17
| ||
18:42 | Consolidate two branches of code in the "PRAGMA foreign_key_check" implementation. (check-in: 69f51f83 user: dan tags: trunk) | |
18:02 | Fix a problem in "PRAGMA foreign_key_check" in handling a WITHOUT ROWID child table with an INTEGER PRIMARY KEY parent key. Also, if an FK violation is detected in a WITHOUT ROWID child table, do not try to read and return the rowid. The second column returned by "PRAGMA foreign_key_check" in this case (WITHOUT ROWID child table) is now always set to NULL. (check-in: 690870bd user: dan tags: trunk) | |
16:07 | Further improvements to test coverage in fts3. (check-in: 352413ee user: dan tags: trunk) | |
Changes
Changes to src/pragma.c.
︙ | ︙ | |||
1329 1330 1331 1332 1333 1334 1335 | assert( x==0 ); } addrOk = sqlite3VdbeMakeLabel(v); if( pParent && pIdx==0 ){ int iKey = pFK->aCol[0].iFrom; assert( iKey>=0 && iKey<pTab->nCol ); if( iKey!=pTab->iPKey ){ | | | > | > > > | 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 | assert( x==0 ); } addrOk = sqlite3VdbeMakeLabel(v); if( pParent && pIdx==0 ){ int iKey = pFK->aCol[0].iFrom; assert( iKey>=0 && iKey<pTab->nCol ); if( iKey!=pTab->iPKey ){ sqlite3ExprCodeGetColumnOfTable( v, pTab, 0, pFK->aCol[0].iFrom, regRow); sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v); }else{ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow); } sqlite3VdbeAddOp3(v, OP_SeekRowid, i, 0, regRow); VdbeCoverage(v); sqlite3VdbeGoto(v, addrOk); sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); }else{ for(j=0; j<pFK->nCol; j++){ sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j); sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v); } if( pParent ){ sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey, sqlite3IndexAffinityStr(db,pIdx), pFK->nCol); sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); VdbeCoverage(v); } } if( HasRowid(pTab) ){ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, regResult+1); } sqlite3VdbeMultiLoad(v, regResult+2, "si", pFK->zTo, i-1); sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4); sqlite3VdbeResolveLabel(v, addrOk); sqlite3DbFree(db, aiCols); } sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addrTop); |
︙ | ︙ |
Changes to test/fkey5.test.
︙ | ︙ | |||
384 385 386 387 388 389 390 391 392 | 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 | > > > > > > > > > > > > > > > > > > > > > > > | 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 | 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} #------------------------------------------------------------------------- # Test using a WITHOUT ROWID table as the child table with an INTEGER # PRIMARY KEY as the parent key. # reset_db do_execsql_test 10.1 { CREATE TABLE p30 (id INTEGER PRIMARY KEY); CREATE TABLE IF NOT EXISTS c30 ( line INTEGER, master REFERENCES p30(id), PRIMARY KEY(master) ) WITHOUT ROWID; INSERT INTO p30 (id) VALUES (1); INSERT INTO c30 (master, line) VALUES (1, 999); } do_execsql_test 10.2 { PRAGMA foreign_key_check; } do_execsql_test 10.3 { INSERT INTO c30 VALUES(45, 45); PRAGMA foreign_key_check; } {c30 {} p30 0} finish_test |