]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Consolidate two branches of code in the "PRAGMA foreign_key_check"
authordan <dan@noemail.net>
Mon, 17 Apr 2017 18:42:33 +0000 (18:42 +0000)
committerdan <dan@noemail.net>
Mon, 17 Apr 2017 18:42:33 +0000 (18:42 +0000)
implementation.

FossilOrigin-Name: 69f51f838abcf57b35e41f7a10fbb45f56536f93825aac865debc3c8315930be

manifest
manifest.uuid
src/pragma.c
test/fkey5.test

index b80db914a6c873c98e965eb6f29e414edf227664..626df9e1b2b08429711299f75a0fdf3bc61f5218 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sproblem\sin\s"PRAGMA\sforeign_key_check"\sin\shandling\sa\sWITHOUT\sROWID\schild\ntable\swith\san\sINTEGER\sPRIMARY\sKEY\sparent\skey.\sAlso,\sif\san\sFK\sviolation\sis\ndetected\sin\sa\sWITHOUT\sROWID\schild\stable,\sdo\snot\stry\sto\sread\sand\sreturn\sthe\nrowid.\sThe\sthird\scolumn\sreturned\sby\s"PRAGMA\sforeign_key_check"\sin\sthis\scase\n(WITHOUT\sROWID\schild\stable)\sis\snow\salways\sset\sto\sNULL.
-D 2017-04-17T18:02:41.447
+C Consolidate\stwo\sbranches\sof\scode\sin\sthe\s"PRAGMA\sforeign_key_check"\nimplementation.
+D 2017-04-17T18:42:33.368
 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 6a8c838220f7c00820e1fc0ac1bccaaa8e5676067e1dbfa1bafa7a4ffecf8ae6
@@ -395,7 +395,7 @@ F src/parse.y 48b03113704ee8bd78ee6996d81de7fbee22e105
 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
 F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc
-F src/pragma.c 943f71f762d8c7ab5a7b00641308cb9cd5effeddc3c709f0303e394ca8c21228
+F src/pragma.c 2362670a9d28b71708aecb2b9b10b3f7be71f4c950961c07e81dc400e3ce6371
 F src/pragma.h 37a1311d0388db480388d7ec09054f7103045eff20d4971f8a433b77f40b9921
 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a
 F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2
@@ -708,7 +708,7 @@ F test/fkey1.test ba64806ff9a04eecab2679caad377ae99a5e94e4
 F test/fkey2.test 155809016fad6b2a1491facf2ac53a551bc57c2c
 F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
 F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
-F test/fkey5.test 67eac5be27ab6c80b1131ed7a060d0df5df748a0cb51600db495221a0e70b732
+F test/fkey5.test 19a9b73bafd78323c37fc883dba060191541503d6094f8aea67fe94d33118e20
 F test/fkey6.test d078a1e323a740062bed38df32b8a736fd320dc0
 F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13
 F test/fkey8.test e5372e32cdb4481f121ec3550703eeb7b4e0762c
@@ -1575,7 +1575,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 352413eed469802665e7d2c17b7fe6e3a0b0b2209ce45bdc85fd4243cec50ea6
-R 46f0a9ecba377acfe7b4e03c3b9e97dc
+P 690870bd7b2e607b7992c4496c9f08c29eb72a36af002c606fd7aa3dcf94a2a4
+R 19c8be4cdee10493f553df8030d2fc52
 U dan
-Z a6a806ccfe0a8fddda7afe6e73d07801
+Z 1848b8fa31243e1c51d1bf2e158fcffc
index fa5e7a216cd83bd44c3bf6cd6b3cbc4bcbda69fa..7995338c75dd0ca3d316847ecf52d1b4e6c74677 100644 (file)
@@ -1 +1 @@
-690870bd7b2e607b7992c4496c9f08c29eb72a36af002c606fd7aa3dcf94a2a4
\ No newline at end of file
+69f51f838abcf57b35e41f7a10fbb45f56536f93825aac865debc3c8315930be
\ No newline at end of file
index 45b190fbd8f019c48f38c9ac5f831dcb7105df04..945fd2d4a7447764ad6c40441df9caf57f2ba3a3 100644 (file)
@@ -1329,32 +1329,32 @@ void sqlite3Pragma(
           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);
+
+        /* Generate code to read the child key values into registers
+        ** regRow..regRow+n. If any of the child key values are NULL, this 
+        ** row cannot cause an FK violation. Jump directly to addrOk in 
+        ** this case. */
+        for(j=0; j<pFK->nCol; j++){
+          int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom;
+          sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j);
+          sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
+        }
+
+        /* Generate code to query the parent index for a matching parent
+        ** key. If a match is found, jump to addrOk. */
+        if( pIdx ){
+          sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
+              sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
+          sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
+          VdbeCoverage(v);
+        }else if( pParent ){
+          int jmp = sqlite3VdbeCurrentAddr(v)+2;
+          sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, 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);
-          }
+          assert( pFK->nCol==1 );
         }
+
+        /* Generate code to report an FK violation to the caller. */
         if( HasRowid(pTab) ){
           sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
         }else{
index 690983460d36b057b74b1acf582f27ad85e2de8a..e9bb47f895877a2f2d8558d991fc53f454469cdd 100644 (file)
@@ -412,4 +412,16 @@ do_execsql_test 10.3 {
   PRAGMA foreign_key_check;
 } {c30 {} p30 0}
 
+#-------------------------------------------------------------------------
+# Test "foreign key mismatch" errors.
+#
+reset_db
+do_execsql_test 11.0 {
+  CREATE TABLE tt(y);
+  CREATE TABLE c11(x REFERENCES tt(y));
+}
+do_catchsql_test 11.1 {
+  PRAGMA foreign_key_check;
+} {1 {foreign key mismatch - "c11" referencing "tt"}}
+
 finish_test