]> source.dussan.org Git - jackcess.git/commitdiff
Allow null values in foreign key fields when enforcing referential integrity. Fixes...
authorJames Ahlborn <jtahlborn@yahoo.com>
Mon, 21 Mar 2016 02:15:47 +0000 (02:15 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Mon, 21 Mar 2016 02:15:47 +0000 (02:15 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@980 f203690c-595d-4dc9-a70b-905162fa7fd2

src/changes/changes.xml
src/main/java/com/healthmarketscience/jackcess/impl/FKEnforcer.java
src/test/java/com/healthmarketscience/jackcess/impl/FKEnforcerTest.java

index c683ad9a900b999ada678b6931e422895e065304..a887ec3e3a9370c573a3d8da300918c737665782 100644 (file)
         Add Database.getTableMetaData method to enable getting basic info
         about a Table (by name) without actually loading it.
       </action>
+      <action dev="jahlborn" type="fix" system="SourceForge2" issue="136">
+        Allow null values in foreign key fields when enforcing referential
+        integrity.
+      </action>
     </release>
     <release version="2.1.3" date="2015-12-04">
       <action dev="jahlborn" type="fix" system="SourceForge2" issue="127">
index bf5138c4f2bd795fbc04fb6556feb709d7db6f3b..470035d026ee0edaa9a0165dc385e24989cf1c88 100644 (file)
@@ -219,8 +219,8 @@ final class FKEnforcer
     throws IOException 
   {
     // ensure that the relevant rows exist in the primary tables for which
-    // this table is a secondary table.
-    if(!joiner.hasRows(row)) {
+    // this table is a secondary table.  however, null values are allowed
+    if(!areNull(joiner, row) && !joiner.hasRows(row)) {
       throw new ConstraintViolationException(
           "Adding new row " + Arrays.asList(row) + " violates constraint " +
           joiner.toFKString());
@@ -288,6 +288,15 @@ final class FKEnforcer
     return false;
   }
 
+  private static boolean areNull(Joiner joiner, Object[] row) {
+    for(Index.Column col : joiner.getColumns()) {
+      if(col.getColumn().getRowValue(row) != null) {
+        return false;
+      }
+    } 
+    return true;
+  }
+
   private boolean enforcing() {
     return _table.getDatabase().isEnforceForeignKeys();
   }
index c3150ea64df415cddd6ca543bc3bea1db2d9c0f7..2567f124121f877711fdc99194cee081b06245b8 100644 (file)
@@ -102,6 +102,8 @@ public class FKEnforcerTest extends TestCase
         assertTrue(ignored.getMessage().contains("Table3[id]"));
       }
 
+      t1.addRow(21, null, null, "null fks", null);
+
       Cursor c = CursorBuilder.createCursor(t3);
       Column col = t3.getColumn("id");
       for(Row row : c) {
@@ -115,7 +117,8 @@ public class FKEnforcerTest extends TestCase
             createT1Row(0, 0, 30, "baz0", 0),
             createT1Row(1, 1, 31, "baz11", 0),
             createT1Row(2, 1, 31, "baz11-2", 0),
-            createT1Row(3, 2, 33, "baz13", 0));
+            createT1Row(3, 2, 33, "baz13", 0),
+            createT1Row(21, null, null, "null fks", null));
 
       assertTable(expectedRows, t1);
 
@@ -125,7 +128,7 @@ public class FKEnforcerTest extends TestCase
         iter.remove();
       }
 
-      assertEquals(0, t1.getRowCount());
+      assertEquals(1, t1.getRowCount());
 
       db.close();
     }
@@ -133,7 +136,7 @@ public class FKEnforcerTest extends TestCase
   }
 
   private static Row createT1Row(
-      int id1, int fk1, int fk2, String data, int fk3)
+      int id1, Integer fk1, Integer fk2, String data, Integer fk3)
   {
     return createExpectedRow("id", id1, "otherfk1", fk1, "otherfk2", fk2,
                              "data", data, "otherfk3", fk3);