1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.sanity.SanityManager; 25 26 27 import org.apache.derby.catalog.UUID; 28 import org.apache.derby.iapi.services.uuid.UUIDFactory; 29 import org.apache.derby.catalog.types.ReferencedColumnsDescriptorImpl; 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.dictionary.DDUtils; 36 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor; 37 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor; 38 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor; 39 import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator; 40 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 41 import org.apache.derby.iapi.sql.dictionary.ForeignKeyConstraintDescriptor; 42 import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor; 43 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor; 44 import org.apache.derby.iapi.sql.dictionary.TableDescriptor; 45 46 import org.apache.derby.iapi.reference.SQLState; 47 48 import org.apache.derby.iapi.sql.depend.DependencyManager; 49 import org.apache.derby.iapi.sql.depend.Provider; 50 import org.apache.derby.iapi.sql.depend.ProviderInfo; 51 52 import org.apache.derby.iapi.sql.execute.ConstantAction; 53 54 import org.apache.derby.iapi.sql.Activation; 55 56 import org.apache.derby.iapi.store.access.TransactionController; 57 import org.apache.derby.iapi.services.loader.ClassFactory; 58 59 66 67 public class CreateConstraintConstantAction extends ConstraintConstantAction 68 { 69 String [] columnNames; 70 private String constraintText; 71 72 private ConstraintInfo otherConstraintInfo; 73 private ClassFactory cf; 74 75 80 private boolean enabled; 81 82 private ProviderInfo[] providerInfo; 83 84 86 104 CreateConstraintConstantAction( 105 String constraintName, 106 int constraintType, 107 String tableName, 108 UUID tableId, 109 String schemaName, 110 String [] columnNames, 111 IndexConstantAction indexAction, 112 String constraintText, 113 boolean enabled, 114 ConstraintInfo otherConstraint, 115 ProviderInfo[] providerInfo) 116 { 117 super(constraintName, constraintType, tableName, 118 tableId, schemaName, indexAction); 119 this.columnNames = columnNames; 120 this.constraintText = constraintText; 121 this.enabled = enabled; 122 this.otherConstraintInfo = otherConstraint; 123 this.providerInfo = providerInfo; 124 } 125 126 128 129 136 public void executeConstantAction( Activation activation ) 137 throws StandardException 138 { 139 boolean forCreateTable; 140 ConglomerateDescriptor conglomDesc = null; 141 ConglomerateDescriptor[] conglomDescs = null; 142 ConstraintDescriptor conDesc = null; 143 TableDescriptor td = null; 144 UUID indexId = null; 145 String uniqueName; 146 String backingIndexName; 147 148 149 if (constraintType == DataDictionary.NOTNULL_CONSTRAINT) 150 { 151 return; 152 } 153 154 LanguageConnectionContext lcc = activation.getLanguageConnectionContext(); 155 DataDictionary dd = lcc.getDataDictionary(); 156 DependencyManager dm = dd.getDependencyManager(); 157 TransactionController tc = lcc.getTransactionExecute(); 158 159 cf = lcc.getLanguageConnectionFactory().getClassFactory(); 160 161 162 forCreateTable = activation.getForCreateTable(); 163 164 173 dd.startWriting(lcc); 174 175 176 177 183 184 SchemaDescriptor sd = dd.getSchemaDescriptor(schemaName, tc, true); 185 186 191 td = activation.getDDLTableDescriptor(); 192 193 if (td == null) 194 { 195 198 if (tableId != null) 199 { 200 td = dd.getTableDescriptor(tableId); 201 } 202 else 203 { 204 td = dd.getTableDescriptor(tableName, sd); 205 } 206 207 if (td == null) 208 { 209 throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, tableName); 210 } 211 activation.setDDLTableDescriptor(td); 212 } 213 214 217 UUIDFactory uuidFactory = dd.getUUIDFactory(); 218 219 220 if (indexAction != null) 221 { 222 if ( indexAction.getIndexName() == null ) 223 { 224 225 backingIndexName = uuidFactory.createUUID().toString(); 226 indexAction.setIndexName(backingIndexName); 227 } 228 else { backingIndexName = indexAction.getIndexName(); } 229 230 231 indexAction.executeConstantAction(activation); 232 233 234 conglomDescs = td.getConglomerateDescriptors(); 235 236 for (int index = 0; index < conglomDescs.length; index++) 237 { 238 conglomDesc = conglomDescs[index]; 239 240 243 if (conglomDesc.isIndex() && 244 backingIndexName.equals(conglomDesc.getConglomerateName())) 245 { 246 break; 247 } 248 } 249 250 if (SanityManager.DEBUG) 251 { 252 SanityManager.ASSERT(conglomDesc != null, 253 "conglomDesc is expected to be non-null after search for backing index"); 254 SanityManager.ASSERT(conglomDesc.isIndex(), 255 "conglomDesc is expected to be indexable after search for backing index"); 256 SanityManager.ASSERT(conglomDesc.getConglomerateName().equals(backingIndexName), 257 "conglomDesc name expected to be the same as backing index name after search for backing index"); 258 } 259 260 indexId = conglomDesc.getUUID(); 261 } 262 263 UUID constraintId = uuidFactory.createUUID(); 268 269 270 DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator(); 271 switch (constraintType) 272 { 273 case DataDictionary.PRIMARYKEY_CONSTRAINT: 274 conDesc = ddg.newPrimaryKeyConstraintDescriptor( 275 td, constraintName, 276 false, false, genColumnPositions(td, false), constraintId, 280 indexId, 281 sd, 282 enabled, 283 0 ); 285 dd.addConstraintDescriptor(conDesc, tc); 286 break; 287 288 case DataDictionary.UNIQUE_CONSTRAINT: 289 conDesc = ddg.newUniqueConstraintDescriptor( 290 td, constraintName, 291 false, false, genColumnPositions(td, false), constraintId, 295 indexId, 296 sd, 297 enabled, 298 0 ); 300 dd.addConstraintDescriptor(conDesc, tc); 301 break; 302 303 case DataDictionary.CHECK_CONSTRAINT: 304 conDesc = ddg.newCheckConstraintDescriptor( 305 td, constraintName, 306 false, false, constraintId, 309 constraintText, 310 new ReferencedColumnsDescriptorImpl(genColumnPositions(td, false)), sd, 312 enabled 313 ); 314 dd.addConstraintDescriptor(conDesc, tc); 315 break; 316 317 case DataDictionary.FOREIGNKEY_CONSTRAINT: 318 ReferencedKeyConstraintDescriptor referencedConstraint = DDUtils.locateReferencedConstraint 319 ( dd, td, constraintName, columnNames, otherConstraintInfo ); 320 DDUtils.validateReferentialActions(dd, td, constraintName, otherConstraintInfo,columnNames); 321 322 conDesc = ddg.newForeignKeyConstraintDescriptor( 323 td, constraintName, 324 false, false, genColumnPositions(td, false), constraintId, 328 indexId, 329 sd, 330 referencedConstraint, 331 enabled, 332 otherConstraintInfo.getReferentialActionDeleteRule(), 333 otherConstraintInfo.getReferentialActionUpdateRule() 334 ); 335 336 dd.addConstraintDescriptor(conDesc, tc); 340 341 344 if ( (! forCreateTable) && 345 dd.activeConstraint( conDesc ) ) 346 { 347 validateFKConstraint(tc, 348 dd, 349 (ForeignKeyConstraintDescriptor)conDesc, 350 referencedConstraint, 351 ((CreateIndexConstantAction)indexAction).getIndexTemplateRow()); 352 } 353 354 355 dm.addDependency(conDesc, referencedConstraint, lcc.getContextManager()); 356 storeConstraintDependenciesOnPrivileges(activation, conDesc, referencedConstraint.getTableId()); 358 break; 359 360 default: 361 if (SanityManager.DEBUG) 362 { 363 SanityManager.THROWASSERT("contraintType (" + constraintType + 364 ") has unexpected value"); 365 } 366 break; 367 } 368 369 370 if (providerInfo != null) 371 { 372 for (int ix = 0; ix < providerInfo.length; ix++) 373 { 374 Provider provider = null; 375 376 377 try 378 { 379 provider = (Provider) providerInfo[ix]. 380 getDependableFinder(). 381 getDependable( 382 providerInfo[ix].getObjectId()); 383 } 384 catch(java.sql.SQLException te) 385 { 386 if (SanityManager.DEBUG) 387 { 388 SanityManager.THROWASSERT("unexpected java.sql.SQLException - " + te); 389 } 390 } 391 dm.addDependency(conDesc, provider, lcc.getContextManager()); 392 } 393 } 394 395 399 if (! forCreateTable) 400 { 401 dm.invalidateFor(td, DependencyManager.CREATE_CONSTRAINT, lcc); 402 } 403 if (constraintType == DataDictionary.FOREIGNKEY_CONSTRAINT) 404 { 405 if (SanityManager.DEBUG) 406 { 407 SanityManager.ASSERT(conDesc != null, 408 "conDesc expected to be non-null"); 409 410 if (! (conDesc instanceof ForeignKeyConstraintDescriptor)) 411 { 412 SanityManager.THROWASSERT( 413 "conDesc expected to be instance of ForeignKeyConstraintDescriptor, not " + 414 conDesc.getClass().getName()); 415 } 416 } 417 dm.invalidateFor( 418 ((ForeignKeyConstraintDescriptor)conDesc). 419 getReferencedConstraint(). 420 getTableDescriptor(), 421 DependencyManager.CREATE_CONSTRAINT, lcc); 422 } 423 } 424 425 430 public boolean isForeignKeyConstraint() 431 { 432 return (constraintType == DataDictionary.FOREIGNKEY_CONSTRAINT); 433 } 434 435 444 private int[] genColumnPositions(TableDescriptor td, 445 boolean columnsMustBeOrderable) 446 throws StandardException 447 { 448 int[] baseColumnPositions; 449 450 baseColumnPositions = new int[columnNames.length]; 452 for (int i = 0; i < columnNames.length; i++) 453 { 454 ColumnDescriptor columnDescriptor; 455 456 columnDescriptor = td.getColumnDescriptor(columnNames[i]); 458 if (columnDescriptor == null) 459 { 460 throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, 461 columnNames[i], 462 tableName); 463 } 464 465 if ( columnsMustBeOrderable && 468 ( ! columnDescriptor.getType().getTypeId().orderable( 469 cf)) 470 ) 471 { 472 throw StandardException.newException(SQLState.LANG_COLUMN_NOT_ORDERABLE_DURING_EXECUTION, 473 columnDescriptor.getType().getTypeId().getSQLTypeName()); 474 } 475 476 baseColumnPositions[i] = columnDescriptor.getPosition(); 478 } 479 480 return baseColumnPositions; 481 } 482 488 493 public String [] getColumnNames() { return columnNames; } 494 495 496 501 public String getConstraintText() { return constraintText; } 502 503 public String toString() 504 { 505 StringBuffer strbuf = new StringBuffer (); 508 strbuf.append( "CREATE CONSTRAINT " + constraintName ); 509 strbuf.append("\n=========================\n"); 510 511 if (columnNames == null) 512 { 513 strbuf.append("columnNames == null\n"); 514 } 515 else 516 { 517 for (int ix=0; ix < columnNames.length; ix++) 518 { 519 strbuf.append("\n\tcol["+ix+"]"+columnNames[ix].toString()); 520 } 521 } 522 523 strbuf.append("\n"); 524 strbuf.append(constraintText); 525 strbuf.append("\n"); 526 if (otherConstraintInfo != null) 527 { 528 strbuf.append(otherConstraintInfo.toString()); 529 } 530 strbuf.append("\n"); 531 return strbuf.toString(); 532 } 533 } 534 | Popular Tags |