]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
"PRAGMA foreign_key_check" with no argument checks the foreign keys on all
authordrh <drh@noemail.net>
Mon, 17 Dec 2012 18:43:02 +0000 (18:43 +0000)
committerdrh <drh@noemail.net>
Mon, 17 Dec 2012 18:43:02 +0000 (18:43 +0000)
tables.

FossilOrigin-Name: 57d47423a65d183cb1efcb95b28cb143e788b953

manifest
manifest.uuid
src/pragma.c

index 239a8f55d8657c4b9162dade37cb5479fa14459f..40430b8c8a9089f6c79d6a5e27f65908c51bb4da 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\san\sissue\swith\schild\skeys\sthat\sare\snot\sINTEGER\sPRIMARY\sKEY\nreferencing\sINTEGER\sPRIMARY\sKEY\sin\sthe\sparent.
-D 2012-12-17T18:05:54.523
+C "PRAGMA\sforeign_key_check"\swith\sno\sargument\schecks\sthe\sforeign\skeys\son\sall\ntables.
+D 2012-12-17T18:43:02.925
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 690d441a758cbffd13e814dc2724a721a6ebd400
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -168,7 +168,7 @@ F src/parse.y c2b4a6454ad77299b1443e2c483a560a9f16e724
 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
 F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c
 F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9
-F src/pragma.c 599af02bcc13c8f41a6670a19185119ffae18e6d
+F src/pragma.c b98dfe89b961d41be6d502d23adf18ed02dbb410
 F src/prepare.c 931ad0d852a0df48f79adcba6ce79ca5f475625c
 F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f
 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
@@ -1025,7 +1025,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P 01c980e9bbdf82e0b37667b6403c19ed8c73ee62
-R abb2e93db46b538d88f02500430c7bfd
+P 603b695bf094b9da905f877a13dcb134463db92a
+R 838d64421c46ea50daf2c57db5adcb2d
 U drh
-Z 4013a6f2f3fe7fcef30b92f6b8b3c386
+Z f327b298aa59d7b1bf00c17e68686c2c
index f929e33227c7e7f69630d41897344b4d002e84d5..a607adedca33158d74599689731802dbb2851c02 100644 (file)
@@ -1 +1 @@
-603b695bf094b9da905f877a13dcb134463db92a
\ No newline at end of file
+57d47423a65d183cb1efcb95b28cb143e788b953
\ No newline at end of file
index fbd556526a801bd963b98207d706473891352afa..d65f4cd10119db43d4b586b2f7630b222f49fbc9 100644 (file)
@@ -1115,33 +1115,51 @@ void sqlite3Pragma(
 #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
 
 #ifndef SQLITE_OMIT_FOREIGN_KEY
-  if( sqlite3StrICmp(zLeft, "foreign_key_check")==0 && zRight ){
-    FKey *pFK;
-    Table *pTab;
-    Table *pParent;
-    Index *pIdx;
-    int i, j;
-    int x;
-    int *aiCols;
+  if( sqlite3StrICmp(zLeft, "foreign_key_check")==0 ){
+    FKey *pFK;             /* A foreign key constraint */
+    Table *pTab;           /* Child table contain "REFERENCES" keyword */
+    Table *pParent;        /* Parent table that child points to */
+    Index *pIdx;           /* Index in the parent table */
+    int i;                 /* Loop counter:  Foreign key number for pTab */
+    int j;                 /* Loop counter:  Field of the foreign key */
+    HashElem *k;           /* Loop counter:  Next table in schema */
+    int x;                 /* result variable */
+    int regResult;         /* 3 registers to hold a result row */
+    int regKey;            /* Register to hold key for checking the FK */
+    int regRow;            /* Registers to hold a row from pTab */
+    int addrTop;           /* Top of a loop checking foreign keys */
+    int addrOk;            /* Jump here if the key is OK */
 
     if( sqlite3ReadSchema(pParse) ) goto pragma_out;
-    pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
-    if( pTab && pTab->pFKey ){
-      int regResult;
-      int regRow;
-      int regKey;
-      v = sqlite3GetVdbe(pParse);
-      sqlite3VdbeSetNumCols(v, 2);
-      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "fkid", SQLITE_STATIC);
-      sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "rowid", SQLITE_STATIC);
-      sqlite3CodeVerifySchema(pParse, iDb);
+    regResult = pParse->nMem+1;
+    pParse->nMem += 3;
+    regKey = ++pParse->nMem;
+    regRow = ++pParse->nMem;
+    v = sqlite3GetVdbe(pParse);
+    sqlite3VdbeSetNumCols(v, 3);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC);
+    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "rowid", SQLITE_STATIC);
+    sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "fkid", SQLITE_STATIC);
+    sqlite3CodeVerifySchema(pParse, iDb);
+    k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
+    while( k ){
+      if( zRight ){
+        pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
+        k = 0;
+      }else{
+        pTab = (Table*)sqliteHashData(k);
+        k = sqliteHashNext(k);
+      }
+      if( pTab->pFKey==0 ) continue;
+      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;
         pIdx = 0;
-        aiCols = 0;
-        x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
+        x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
         if( x==0 ){
           if( pIdx==0 ){
             sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
@@ -1151,62 +1169,52 @@ void sqlite3Pragma(
             sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
           }
         }else{
+          k = 0;
           break;
         }
-        sqlite3DbFree(db, aiCols);
       }
-      pParse->nTab = i;
-      if( pFK==0 ){
-        int addrTop;
-        int addrOk;
-        addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0);
-        regResult = pParse->nMem+1;
-        pParse->nMem += 2;
-        regRow = pParse->nMem+1;
-        pParse->nMem += pTab->nCol;
-        regKey = ++pParse->nMem;
-        for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
-          pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb);
-          assert( pParent!=0 );
-          pIdx = 0;
-          aiCols = 0;
-          x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
-          assert( x==0 );
-          addrOk = sqlite3VdbeMakeLabel(v);
-          if( pIdx==0 ){
-            int iKey = pFK->aCol[0].iFrom;
-            if( iKey>=0 && iKey!=pTab->iPKey ){
-              sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
-              sqlite3ColumnDefault(v, pTab, iKey, regRow);
-              sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk);
-              sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow,
-                 sqlite3VdbeCurrentAddr(v)+3);
-            }else{
-              sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
-            }
-            sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow);
-            sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk);
-            sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
+      if( pFK ) break;
+      if( pParse->nTab<i ) pParse->nTab = 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 );
+        pIdx = 0;
+        x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
+        assert( x==0 );
+        addrOk = sqlite3VdbeMakeLabel(v);
+        if( pIdx==0 ){
+          int iKey = pFK->aCol[0].iFrom;
+          if( iKey>=0 && iKey!=pTab->iPKey ){
+            sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
+            sqlite3ColumnDefault(v, pTab, iKey, regRow);
+            sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk);
+            sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow,
+               sqlite3VdbeCurrentAddr(v)+3);
           }else{
-            for(j=0; j<pFK->nCol; j++){
-              sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, 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);
+            sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
+          }
+          sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow);
+          sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk);
+          sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
+        }else{
+          for(j=0; j<pFK->nCol; j++){
+            sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, pFK->aCol[j].iFrom,
+                                            regRow+j);
+            sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk);
           }
-          sqlite3DbFree(db, aiCols);
-          sqlite3VdbeAddOp2(v, OP_Integer, i-1, regResult);
-          sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
-          sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 2);
-          sqlite3VdbeResolveLabel(v, 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);
         }
-        sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1);
-        sqlite3VdbeJumpHere(v, addrTop);
+        sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
+        sqlite3VdbeAddOp2(v, OP_Integer, i-1, regResult+2);
+        sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 3);
+        sqlite3VdbeResolveLabel(v, addrOk);
       }
+      sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1);
+      sqlite3VdbeJumpHere(v, addrTop);
     }
   }else
 #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */