1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.context.ContextManager; 25 26 import org.apache.derby.iapi.services.sanity.SanityManager; 27 28 import org.apache.derby.catalog.UUID; 29 import org.apache.derby.iapi.services.uuid.UUIDFactory; 30 31 import org.apache.derby.iapi.error.StandardException; 32 33 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 34 35 import org.apache.derby.iapi.sql.StatementType; 36 37 import org.apache.derby.iapi.sql.dictionary.CheckConstraintDescriptor; 38 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor; 39 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor; 40 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList; 41 import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator; 42 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 43 import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext; 44 import org.apache.derby.iapi.sql.dictionary.ForeignKeyConstraintDescriptor; 45 import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator; 46 import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor; 47 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor; 48 import org.apache.derby.iapi.sql.dictionary.TableDescriptor; 49 50 51 import org.apache.derby.iapi.types.DataValueFactory; 52 import org.apache.derby.iapi.types.RowLocation; 53 54 import org.apache.derby.iapi.sql.depend.DependencyManager; 55 56 import org.apache.derby.iapi.sql.execute.ConstantAction; 57 import org.apache.derby.iapi.sql.execute.ExecIndexRow; 58 import org.apache.derby.iapi.sql.execute.ExecRow; 59 60 import org.apache.derby.iapi.sql.Activation; 61 62 import org.apache.derby.iapi.store.access.ConglomerateController; 63 import org.apache.derby.iapi.store.access.TransactionController; 64 65 import org.apache.derby.iapi.services.io.FormatableBitSet; 66 67 import java.util.Hashtable ; 68 import java.util.Enumeration ; 69 70 81 class SetConstraintsConstantAction extends DDLConstantAction 82 { 83 84 private boolean enable; 85 private boolean unconditionallyEnforce; 86 87 92 private ConstraintDescriptorList cdl; 93 private UUID[] cuuids; 94 private UUID[] tuuids; 95 96 107 SetConstraintsConstantAction 108 ( 109 ConstraintDescriptorList cdl, 110 boolean enable, 111 boolean unconditionallyEnforce 112 ) 113 { 114 this.cdl = cdl; 115 this.enable = enable; 116 this.unconditionallyEnforce = unconditionallyEnforce; 117 } 118 119 125 public String toString() 126 { 127 return "SET CONSTRAINTS"; 130 } 131 132 134 135 142 public void executeConstantAction( Activation activation ) 143 throws StandardException 144 { 145 ConstraintDescriptor cd; 146 TableDescriptor td; 147 ConstraintDescriptorList tmpCdl; 148 boolean enforceThisConstraint; 149 150 LanguageConnectionContext lcc = activation.getLanguageConnectionContext(); 151 DataDictionary dd = lcc.getDataDictionary(); 152 DependencyManager dm = dd.getDependencyManager(); 153 TransactionController tc = lcc.getTransactionExecute(); 154 155 tmpCdl = getConstraintDescriptorList(dd); 156 157 int[] enabledCol = new int[1]; 158 enabledCol[0] = ConstraintDescriptor.SYSCONSTRAINTS_STATE_FIELD; 159 168 dd.startWriting(lcc); 169 170 173 publishToTargets(activation); 174 175 boolean skipFKs = false; 176 177 184 if (tmpCdl == null) 185 { 186 skipFKs = true; 187 tmpCdl = dd.getConstraintDescriptors((TableDescriptor)null); 188 } 189 190 Hashtable checkConstraintTables = null; 191 int cdlSize = tmpCdl.size(); 192 for (int index = 0; index < cdlSize; index++) 193 { 194 cd = tmpCdl.elementAt(index); 195 196 202 if (unconditionallyEnforce) 203 { 204 enforceThisConstraint = true; 205 } 206 else 207 { 208 enforceThisConstraint = (enable && !cd.isEnabled()); 209 } 210 211 if (enforceThisConstraint) 212 { 213 if (cd instanceof ForeignKeyConstraintDescriptor) 214 { 215 validateFKConstraint((ForeignKeyConstraintDescriptor)cd, dd, tc, lcc.getContextManager()); 216 } 217 222 else if (cd instanceof CheckConstraintDescriptor) 223 { 224 td = cd.getTableDescriptor(); 225 226 if (checkConstraintTables == null) 227 { 228 checkConstraintTables = new Hashtable (10); 229 } 230 231 ConstraintDescriptorList tabCdl = (ConstraintDescriptorList) 232 checkConstraintTables.get(td.getUUID()); 233 if (tabCdl == null) 234 { 235 tabCdl = new ConstraintDescriptorList(); 236 checkConstraintTables.put(td.getUUID(), tabCdl); 237 } 238 tabCdl.add(cd); 239 } 240 247 dm.invalidateFor(cd.getTableDescriptor(), 248 DependencyManager.SET_CONSTRAINTS_ENABLE, lcc); 249 cd.setEnabled(); 250 dd.updateConstraintDescriptor(cd, 251 cd.getUUID(), 252 enabledCol, 253 tc); 254 } 255 256 262 if (!skipFKs && 263 (cd instanceof ReferencedKeyConstraintDescriptor)) 264 { 265 ForeignKeyConstraintDescriptor fkcd; 266 ReferencedKeyConstraintDescriptor refcd; 267 ConstraintDescriptorList fkcdl; 268 269 refcd = (ReferencedKeyConstraintDescriptor)cd; 270 fkcdl = refcd.getForeignKeyConstraints(ReferencedKeyConstraintDescriptor.ALL); 271 272 int fkcdlSize = fkcdl.size(); 273 for (int inner = 0; inner < fkcdlSize; inner++) 274 { 275 fkcd = (ForeignKeyConstraintDescriptor) fkcdl.elementAt(inner); 276 if (enable && !fkcd.isEnabled()) 277 { 278 dm.invalidateFor(fkcd.getTableDescriptor(), 279 DependencyManager.SET_CONSTRAINTS_ENABLE, lcc); 280 validateFKConstraint(fkcd, dd, tc, lcc.getContextManager()); 281 fkcd.setEnabled(); 282 dd.updateConstraintDescriptor(fkcd, 283 fkcd.getUUID(), 284 enabledCol, 285 tc); 286 } 287 else if (!enable && fkcd.isEnabled()) 288 { 289 dm.invalidateFor(fkcd, DependencyManager.SET_CONSTRAINTS_DISABLE, 290 lcc); 291 fkcd.setDisabled(); 292 dd.updateConstraintDescriptor(fkcd, 293 fkcd.getUUID(), 294 enabledCol, 295 tc); 296 } 297 } 298 } 299 300 if (!enable && cd.isEnabled()) 301 { 302 dm.invalidateFor(cd, DependencyManager.SET_CONSTRAINTS_DISABLE, 303 lcc); 304 cd.setDisabled(); 305 dd.updateConstraintDescriptor(cd, 306 cd.getUUID(), 307 enabledCol, 308 tc); 309 } 310 } 311 312 validateAllCheckConstraints(lcc, checkConstraintTables); 313 } 314 315 private void validateAllCheckConstraints(LanguageConnectionContext lcc, Hashtable ht) 316 throws StandardException 317 { 318 ConstraintDescriptorList cdl; 319 ConstraintDescriptor cd = null; 320 TableDescriptor td; 321 StringBuffer text; 322 StringBuffer constraintNames; 323 324 if (ht == null) 325 { 326 return; 327 } 328 329 for (Enumeration e = ht.elements(); e.hasMoreElements(); ) 330 { 331 332 cdl = (ConstraintDescriptorList) e.nextElement(); 333 text = null; 334 constraintNames = null; 335 336 343 int cdlSize = cdl.size(); 344 for (int index = 0; index < cdlSize; index++) 345 { 346 cd = (CheckConstraintDescriptor) cdl.elementAt(index); 347 if (text == null) 348 { 349 text = new StringBuffer ("(").append(cd.getConstraintText()).append(") "); 350 constraintNames = new StringBuffer (cd.getConstraintName()); 351 } 352 else 353 { 354 text.append(" AND (").append(cd.getConstraintText()).append(") "); 355 constraintNames.append(", ").append(cd.getConstraintName()); 356 } 357 } 358 359 if (SanityManager.DEBUG) 360 { 361 SanityManager.ASSERT(text != null, "internal error, badly built hastable"); 362 } 363 364 ConstraintConstantAction.validateConstraint( 365 constraintNames.toString(), 366 text.toString(), 367 cd.getTableDescriptor(), 368 lcc, true); 369 } 370 } 371 372 375 private void validateFKConstraint 376 ( 377 ForeignKeyConstraintDescriptor fk, 378 DataDictionary dd, 379 TransactionController tc, 380 ContextManager cm 381 ) 382 throws StandardException 383 { 384 387 IndexRowGenerator irg = fk.getIndexConglomerateDescriptor(dd).getIndexDescriptor(); 388 ExecIndexRow indexTemplateRow = irg.getIndexRowTemplate(); 389 TableDescriptor td = fk.getTableDescriptor(); 390 ExecRow baseRow = td.getEmptyExecRow(cm); 391 irg.getIndexRow(baseRow, getRowLocation(dd, td, tc), 392 indexTemplateRow, (FormatableBitSet)null); 393 394 397 ConstraintConstantAction.validateFKConstraint(tc, dd, fk, 398 fk.getReferencedConstraint(), indexTemplateRow); 399 } 400 401 409 private RowLocation getRowLocation 410 ( 411 DataDictionary dd, 412 TableDescriptor td, 413 TransactionController tc 414 ) 415 throws StandardException 416 { 417 RowLocation rl; 418 ConglomerateController heapCC = null; 419 420 long tableId = td.getHeapConglomerateId(); 421 heapCC = 422 tc.openConglomerate( 423 tableId, false, 0, tc.MODE_RECORD, tc.ISOLATION_READ_COMMITTED); 424 try 425 { 426 rl = heapCC.newRowLocationTemplate(); 427 } 428 finally 429 { 430 heapCC.close(); 431 } 432 433 return rl; 434 } 435 436 441 private ConstraintDescriptorList getConstraintDescriptorList(DataDictionary dd) 442 throws StandardException 443 { 444 if (cdl != null) 445 { 446 return cdl; 447 } 448 if (tuuids == null) 449 { 450 return null; 451 } 452 453 456 cdl = new ConstraintDescriptorList(); 457 458 for (int i = 0; i < tuuids.length; i++) 459 { 460 TableDescriptor td = dd.getTableDescriptor(tuuids[i]); 461 if (SanityManager.DEBUG) 462 { 463 if (td == null) 464 { 465 SanityManager.THROWASSERT("couldn't locate table descriptor "+ 466 "in SET CONSTRAINTS for uuid "+tuuids[i]); 467 } 468 } 469 470 ConstraintDescriptor cd = dd.getConstraintDescriptorById(td, cuuids[i]); 471 472 if (SanityManager.DEBUG) 473 { 474 if (cd == null) 475 { 476 SanityManager.THROWASSERT("couldn't locate constraint descriptor "+ 477 " in SET CONSTRAINTS for uuid "+cuuids[i]); 478 } 479 } 480 481 cdl.add(cd); 482 } 483 return cdl; 484 } 485 486 492 501 protected void publishToTargets(Activation activation) 502 throws StandardException 503 { 504 } 505 } 506 | Popular Tags |