1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.sql.compile.C_NodeTypes; 25 26 import org.apache.derby.iapi.services.sanity.SanityManager; 27 28 import org.apache.derby.iapi.error.StandardException; 29 30 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor; 31 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 32 import org.apache.derby.iapi.sql.dictionary.DefaultDescriptor; 33 import org.apache.derby.iapi.sql.dictionary.TableDescriptor; 34 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList; 35 import org.apache.derby.iapi.sql.dictionary.KeyConstraintDescriptor; 36 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor; 37 38 import org.apache.derby.iapi.types.TypeId; 39 import org.apache.derby.iapi.types.DataTypeDescriptor; 40 41 import org.apache.derby.iapi.reference.SQLState; 42 43 import org.apache.derby.impl.sql.execute.ColumnInfo; 44 import org.apache.derby.catalog.TypeDescriptor; 45 import org.apache.derby.catalog.UUID; 46 import org.apache.derby.catalog.types.DefaultInfoImpl; 47 48 53 54 public class ModifyColumnNode extends ColumnDefinitionNode 55 { 56 int columnPosition = -1; 57 UUID oldDefaultUUID; 58 59 64 UUID getOldDefaultUUID() 65 { 66 return oldDefaultUUID; 67 } 68 69 74 public int getColumnPosition() 75 { 76 if (SanityManager.DEBUG) 77 { 78 SanityManager.ASSERT(columnPosition > 0, 79 "columnPosition expected to be > 0"); 80 } 81 return columnPosition; 82 } 83 84 92 93 public void checkUserType(TableDescriptor td) 94 throws StandardException 95 { 96 ColumnDescriptor cd; 97 TypeDescriptor oldType; 98 DataTypeDescriptor newType = dataTypeServices; 99 TypeId oldTypeId; 100 TypeId newTypeId; 101 102 if (getNodeType() != C_NodeTypes.MODIFY_COLUMN_TYPE_NODE) 103 return; 105 cd = td.getColumnDescriptor(name); 106 if (cd == null) 107 { 108 throw StandardException.newException( 109 SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, name, td.getName()); 110 } 111 112 oldType = cd.getType(); 113 oldTypeId = cd.getType().getTypeId(); 114 newTypeId = dataTypeServices.getTypeId(); 115 newType.setNullability(oldType.isNullable()); 116 117 if (!(oldTypeId.equals(newTypeId))) 119 { 120 throw StandardException.newException( 121 SQLState.LANG_MODIFY_COLUMN_CHANGE_TYPE, name); 122 } 123 124 String typeName = dataTypeServices.getTypeName(); 126 if (!(typeName.equals(TypeId.NATIONAL_VARCHAR_NAME)) && 127 !(typeName.equals(TypeId.VARCHAR_NAME)) && 128 !(typeName.equals(TypeId.VARBIT_NAME))) 129 { 130 throw StandardException.newException( 131 SQLState.LANG_MODIFY_COLUMN_INVALID_TYPE); 132 } 133 134 if (newType.getMaximumWidth() < oldType.getMaximumWidth()) 136 { 137 throw StandardException.newException( 138 SQLState.LANG_MODIFY_COLUMN_INVALID_LENGTH, name); 139 } 140 } 141 142 159 public void checkExistingConstraints(TableDescriptor td) 160 throws StandardException 161 { 162 if ((getNodeType() != C_NodeTypes.MODIFY_COLUMN_TYPE_NODE) && 163 (getNodeType() != C_NodeTypes.MODIFY_COLUMN_CONSTRAINT_NODE) && 164 (getNodeType() != C_NodeTypes.MODIFY_COLUMN_CONSTRAINT_NOT_NULL_NODE)) 165 return; 166 167 DataDictionary dd = getDataDictionary(); 168 ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td); 169 int intArray[] = new int[1]; 170 intArray[0] = columnPosition; 171 172 for (int index = 0; index < cdl.size(); index++) 173 { 174 ConstraintDescriptor existingConstraint = 175 cdl.elementAt(index); 176 if (!(existingConstraint instanceof KeyConstraintDescriptor)) 177 continue; 178 179 if (!existingConstraint.columnIntersects(intArray)) 180 continue; 181 182 int constraintType = existingConstraint.getConstraintType(); 183 184 if ((constraintType == DataDictionary.FOREIGNKEY_CONSTRAINT) 188 && 189 (getNodeType() == C_NodeTypes.MODIFY_COLUMN_TYPE_NODE)) 190 { 191 throw StandardException.newException( 192 SQLState.LANG_MODIFY_COLUMN_FKEY_CONSTRAINT, name, existingConstraint.getConstraintName()); 193 } 194 195 else 196 { 197 if ((getNodeType() == 200 C_NodeTypes.MODIFY_COLUMN_CONSTRAINT_NODE) && 201 ((existingConstraint.getConstraintType() == 202 DataDictionary.PRIMARYKEY_CONSTRAINT) || 203 (existingConstraint.getConstraintType() == 204 DataDictionary.UNIQUE_CONSTRAINT))) 205 { 206 throw StandardException.newException( 207 SQLState.LANG_MODIFY_COLUMN_EXISTING_CONSTRAINT, name); 208 } 209 ConstraintDescriptorList 211 refcdl = dd.getForeignKeys(existingConstraint.getUUID()); 212 213 if (refcdl.size() > 0) 214 { 215 throw StandardException.newException( 216 SQLState.LANG_MODIFY_COLUMN_REFERENCED, name, refcdl.elementAt(0).getConstraintName()); 217 } 218 219 getCompilerContext().createDependency(existingConstraint); 221 } 222 } 223 224 } 225 230 int getAction() 231 { 232 switch (getNodeType()) 233 { 234 case C_NodeTypes.MODIFY_COLUMN_DEFAULT_NODE: 235 if (autoinc_create_or_modify_Start_Increment == ColumnDefinitionNode.MODIFY_AUTOINCREMENT_RESTART_VALUE) 236 return ColumnInfo.MODIFY_COLUMN_DEFAULT_RESTART; 237 else 238 return ColumnInfo.MODIFY_COLUMN_DEFAULT_INCREMENT; 239 case C_NodeTypes.MODIFY_COLUMN_TYPE_NODE: 240 return ColumnInfo.MODIFY_COLUMN_TYPE; 241 case C_NodeTypes.MODIFY_COLUMN_CONSTRAINT_NODE: 242 return ColumnInfo.MODIFY_COLUMN_CONSTRAINT; 243 case C_NodeTypes.MODIFY_COLUMN_CONSTRAINT_NOT_NULL_NODE: 244 return ColumnInfo.MODIFY_COLUMN_CONSTRAINT_NOT_NULL; 245 default: 246 if (SanityManager.DEBUG) 247 { 248 SanityManager.THROWASSERT("Unexpected nodeType = " + 249 getNodeType()); 250 } 251 return 0; 252 } 253 } 254 255 263 void bindAndValidateDefault(DataDictionary dd, TableDescriptor td) 264 throws StandardException 265 { 266 ColumnDescriptor cd; 267 268 cd = td.getColumnDescriptor(name); 270 if (cd == null) 271 { 272 throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, name, td.getName()); 273 } 274 275 276 DefaultDescriptor defaultDescriptor = cd.getDefaultDescriptor(dd); 278 279 oldDefaultUUID = (defaultDescriptor == null) ? null : defaultDescriptor.getUUID(); 280 281 columnPosition = cd.getPosition(); 283 284 if (getNodeType() != C_NodeTypes.MODIFY_COLUMN_DEFAULT_NODE) 286 { 287 return; 288 } 289 290 if (defaultNode == null) 299 defaultInfo = (DefaultInfoImpl)cd.getDefaultInfo(); 300 if (autoinc_create_or_modify_Start_Increment == 301 ColumnDefinitionNode.MODIFY_AUTOINCREMENT_RESTART_VALUE) 302 autoincrementIncrement = cd.getAutoincInc(); 303 if (autoinc_create_or_modify_Start_Increment == 304 ColumnDefinitionNode.MODIFY_AUTOINCREMENT_INC_VALUE) 305 autoincrementStart = cd.getAutoincStart(); 306 307 308 dataTypeServices = cd.getType(); 309 310 validateDefault(dd, td); 312 } 313 314 private ColumnDescriptor getLocalColumnDescriptor(String name, TableDescriptor td) 315 throws StandardException 316 { 317 ColumnDescriptor cd; 318 319 cd = td.getColumnDescriptor(name); 321 if (cd == null) 322 { 323 throw StandardException.newException( 324 SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, name, td.getName()); 325 } 326 327 return cd; 328 } 329 334 public void validateAutoincrement(DataDictionary dd, TableDescriptor td, int tableType) 335 throws StandardException 336 { 337 ColumnDescriptor cd; 338 339 if (getNodeType() == C_NodeTypes.MODIFY_COLUMN_CONSTRAINT_NODE) 341 { 342 cd = getLocalColumnDescriptor(name, td); 343 if (cd.isAutoincrement()) 344 { 345 throw StandardException.newException(SQLState.LANG_AI_CANNOT_NULL_AI, 346 getColumnName()); 347 } 348 } 349 350 if (autoincrementVerify) 351 { 352 cd = getLocalColumnDescriptor(name, td); 353 if (!cd.isAutoincrement()) 354 throw StandardException.newException(SQLState.LANG_INVALID_ALTER_TABLE_ATTRIBUTES, 355 td.getQualifiedName(), name); 356 } 357 if (isAutoincrement == false) 358 return; 359 360 super.validateAutoincrement(dd, td, tableType); 361 if (dataTypeServices.isNullable()) 362 throw StandardException.newException(SQLState.LANG_AI_CANNOT_ADD_AI_TO_NULLABLE, 363 getColumnName()); 364 } 365 } 366 | Popular Tags |