1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.sanity.SanityManager; 25 26 import org.apache.derby.iapi.error.StandardException; 27 import org.apache.derby.iapi.sql.ResultSet; 28 29 import org.apache.derby.iapi.types.BooleanDataValue; 30 import org.apache.derby.iapi.types.DataValueDescriptor; 31 import org.apache.derby.iapi.types.RowLocation; 32 import org.apache.derby.iapi.sql.execute.ExecRow; 33 import org.apache.derby.iapi.sql.LanguageProperties; 34 35 import org.apache.derby.iapi.store.access.ConglomerateController; 36 import org.apache.derby.iapi.store.access.GenericScanController; 37 import org.apache.derby.iapi.store.access.GroupFetchScanController; 38 import org.apache.derby.iapi.store.access.ScanController; 39 import org.apache.derby.iapi.store.access.TransactionController; 40 import org.apache.derby.iapi.types.DataValueDescriptor; 41 42 import org.apache.derby.iapi.services.io.FormatableBitSet; 43 44 63 public class RIBulkChecker 64 { 65 private static final int EQUAL = 0; 66 private static final int GREATER_THAN = 1; 67 private static final int LESS_THAN = -1; 68 69 private FKInfo fkInfo; 70 private GroupFetchScanController referencedKeyScan; 71 private DataValueDescriptor[][] referencedKeyRowArray; 72 private GroupFetchScanController foreignKeyScan; 73 private DataValueDescriptor[][] foreignKeyRowArray; 74 private ConglomerateController unreferencedCC; 75 private int failedCounter; 76 private boolean quitOnFirstFailure; 77 private int numColumns; 78 private int currRefRowIndex; 79 private int currFKRowIndex; 80 private int lastRefRowIndex; 81 private int lastFKRowIndex; 82 private ExecRow firstRowToFail; 83 84 99 public RIBulkChecker 100 ( 101 GroupFetchScanController referencedKeyScan, 102 GroupFetchScanController foreignKeyScan, 103 ExecRow templateRow, 104 boolean quitOnFirstFailure, 105 ConglomerateController unreferencedCC, 106 ExecRow firstRowToFail 107 ) 108 { 109 this.referencedKeyScan = referencedKeyScan; 110 this.foreignKeyScan = foreignKeyScan; 111 this.quitOnFirstFailure = quitOnFirstFailure; 112 this.unreferencedCC = unreferencedCC; 113 this.firstRowToFail = firstRowToFail; 114 115 foreignKeyRowArray = new DataValueDescriptor[LanguageProperties.BULK_FETCH_DEFAULT_INT][]; 116 foreignKeyRowArray[0] = templateRow.getRowArrayClone(); 117 referencedKeyRowArray = new DataValueDescriptor[LanguageProperties.BULK_FETCH_DEFAULT_INT][]; 118 referencedKeyRowArray[0]= templateRow.getRowArrayClone(); 119 failedCounter = 0; 120 numColumns = templateRow.getRowArray().length - 1; 121 currFKRowIndex = -1; 122 currRefRowIndex = -1; 123 } 124 125 132 public int doCheck() 133 throws StandardException 134 { 135 DataValueDescriptor[] foreignKey; 136 DataValueDescriptor[] referencedKey; 137 138 int compareResult; 139 140 referencedKey = getNextRef(); 141 142 153 while ((foreignKey = getNextFK()) != null) 154 { 155 164 if (!anyNull(foreignKey) && referencedKey == null) 165 { 166 do 167 { 168 failure(foreignKey); 169 if (quitOnFirstFailure) 170 { 171 return 1; 172 } 173 } while ((foreignKey = getNextFK()) != null); 174 return failedCounter; 175 } 176 177 while ((compareResult = greaterThan(foreignKey, referencedKey)) == GREATER_THAN) 178 { 179 if ((referencedKey = getNextRef()) == null) 180 { 181 do 182 { 183 failure(foreignKey); 184 if (quitOnFirstFailure) 185 { 186 return 1; 187 } 188 } while ((foreignKey = getNextFK()) != null); 189 return failedCounter; 190 } 191 } 192 193 if (compareResult != EQUAL) 194 { 195 failure(foreignKey); 196 if (quitOnFirstFailure) 197 { 198 return 1; 199 } 200 } 201 } 202 return failedCounter; 203 } 204 205 206 210 private DataValueDescriptor[] getNextFK() 211 throws StandardException 212 { 213 if ((currFKRowIndex > lastFKRowIndex) || 214 (currFKRowIndex == -1)) 215 { 216 int rowCount = 217 foreignKeyScan.fetchNextGroup(foreignKeyRowArray, (RowLocation[]) null); 218 219 if (rowCount == 0) 220 { 221 currFKRowIndex = -1; 222 return null; 223 } 224 225 lastFKRowIndex = rowCount - 1; 226 currFKRowIndex = 0; 227 } 228 229 return foreignKeyRowArray[currFKRowIndex++]; 230 } 231 232 236 private DataValueDescriptor[] getNextRef() 237 throws StandardException 238 { 239 if ((currRefRowIndex > lastRefRowIndex) || 240 (currRefRowIndex == -1)) 241 { 242 int rowCount = 243 referencedKeyScan.fetchNextGroup(referencedKeyRowArray, (RowLocation[]) null); 244 245 if (rowCount == 0) 246 { 247 currRefRowIndex = -1; 248 return null; 249 } 250 251 lastRefRowIndex = rowCount - 1; 252 currRefRowIndex = 0; 253 } 254 255 return referencedKeyRowArray[currRefRowIndex++]; 256 } 257 258 private void failure(DataValueDescriptor[] foreignKeyRow) 259 throws StandardException 260 { 261 if (failedCounter == 0) 262 { 263 if (firstRowToFail != null) 264 { 265 firstRowToFail.setRowArray(foreignKeyRow); 266 firstRowToFail.setRowArray(firstRowToFail.getRowArrayClone()); 268 } 269 } 270 271 failedCounter++; 272 if (unreferencedCC != null) 273 { 274 unreferencedCC.insert(foreignKeyRow); 275 } 276 } 277 281 private boolean anyNull(DataValueDescriptor[] fkRowArray) 282 throws StandardException 283 { 284 DataValueDescriptor fkCol; 285 286 289 for (int i = 0; i < numColumns; i++) 290 { 291 fkCol = (DataValueDescriptor)fkRowArray[i]; 292 293 297 if (fkCol.isNull()) 298 { 299 return true; 300 } 301 } 302 return false; 303 304 } 305 306 private int greaterThan(DataValueDescriptor[] fkRowArray, DataValueDescriptor[] refRowArray) 307 throws StandardException 308 { 309 DataValueDescriptor fkCol; 310 DataValueDescriptor refCol; 311 int result; 312 313 317 if (anyNull(fkRowArray)) 318 return EQUAL; 319 320 for (int i = 0; i < numColumns; i++) 321 { 322 fkCol = (DataValueDescriptor)fkRowArray[i]; 323 refCol = (DataValueDescriptor)refRowArray[i]; 324 325 result = fkCol.compare(refCol); 326 327 if (result == 1) 328 { 329 return GREATER_THAN; 330 } 331 else if (result == -1) 332 { 333 return LESS_THAN; 334 } 335 336 340 } 341 342 345 return EQUAL; 346 } 347 } 348 | Popular Tags |