1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.loader.ClassFactory; 25 26 import org.apache.derby.iapi.store.access.TransactionController; 27 28 import org.apache.derby.iapi.sql.execute.ConstantAction; 29 30 import org.apache.derby.iapi.sql.dictionary.TableDescriptor; 31 import org.apache.derby.iapi.sql.dictionary.AliasDescriptor; 32 import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator; 33 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 34 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor; 35 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor; 36 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 37 38 import org.apache.derby.iapi.types.DataValueFactory; 39 40 import org.apache.derby.iapi.reference.SQLState; 41 42 import org.apache.derby.iapi.sql.Activation; 43 44 import org.apache.derby.iapi.error.StandardException; 45 46 import org.apache.derby.iapi.services.context.ContextService; 47 48 import org.apache.derby.catalog.UUID; 49 50 import org.apache.derby.iapi.services.sanity.SanityManager; 51 52 import org.apache.derby.catalog.AliasInfo; 53 import org.apache.derby.catalog.types.RoutineAliasInfo; 54 import org.apache.derby.catalog.types.SynonymAliasInfo; 55 56 import java.lang.reflect.Method ; 57 import java.lang.reflect.Modifier ; 58 59 65 class CreateAliasConstantAction extends DDLConstantAction 66 { 67 68 private final String aliasName; 69 private final String schemaName; 70 private final String javaClassName; 71 private final char aliasType; 72 private final char nameSpace; 73 private final AliasInfo aliasInfo; 74 75 77 86 CreateAliasConstantAction( 87 String aliasName, 88 String schemaName, 89 String javaClassName, 90 AliasInfo aliasInfo, 91 char aliasType) 92 { 93 this.aliasName = aliasName; 94 this.schemaName = schemaName; 95 this.javaClassName = javaClassName; 96 this.aliasInfo = aliasInfo; 97 this.aliasType = aliasType; 98 switch (aliasType) 99 { 100 case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR: 101 nameSpace = AliasInfo.ALIAS_NAME_SPACE_PROCEDURE_AS_CHAR; 102 break; 103 104 case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR: 105 nameSpace = AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR; 106 break; 107 108 case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR: 109 nameSpace = AliasInfo.ALIAS_NAME_SPACE_SYNONYM_AS_CHAR; 110 break; 111 112 default: 113 if (SanityManager.DEBUG) 114 { 115 SanityManager.THROWASSERT( 116 "Unexpected value for aliasType (" + aliasType + ")"); 117 } 118 nameSpace = '\0'; 119 break; 120 } 121 } 122 123 125 public String toString() 126 { 127 String type = null; 130 131 switch (aliasType) 132 { 133 case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR: 134 type = "CREATE PROCEDURE "; 135 break; 136 137 case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR: 138 type = "CREATE FUNCTION "; 139 break; 140 141 case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR: 142 type = "CREATE SYNONYM "; 143 break; 144 145 default: 146 if (SanityManager.DEBUG) 147 { 148 SanityManager.THROWASSERT( 149 "Unexpected value for aliasType (" + aliasType + ")"); 150 } 151 } 152 153 return type + aliasName; 154 } 155 156 158 159 166 public void executeConstantAction( Activation activation ) 167 throws StandardException 168 { 169 LanguageConnectionContext lcc; 170 if (activation != null) 171 { 172 lcc = activation.getLanguageConnectionContext(); 173 } 174 else { 176 lcc = (LanguageConnectionContext) ContextService.getContext 177 (LanguageConnectionContext.CONTEXT_ID); 178 } 179 DataDictionary dd = lcc.getDataDictionary(); 180 TransactionController tc = lcc.getTransactionExecute(); 181 182 188 String checkMethodName = null; 189 190 String checkClassName = javaClassName; 191 192 if (aliasInfo != null) 193 checkMethodName = aliasInfo.getMethodName(); 194 195 switch (aliasType) 198 { 199 case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR: 200 case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR: 201 case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR: 202 break; 203 204 default: 205 { 206 207 ClassFactory cf = lcc.getLanguageConnectionFactory().getClassFactory(); 208 209 Class realClass = null; 210 try 211 { 212 realClass = cf.loadApplicationClass(checkClassName); 214 } 215 catch (ClassNotFoundException t) 216 { 217 throw StandardException.newException(SQLState.LANG_TYPE_DOESNT_EXIST2, t, checkClassName); 218 } 219 220 if (! Modifier.isPublic(realClass.getModifiers())) 221 { 222 throw StandardException.newException(SQLState.LANG_TYPE_DOESNT_EXIST2, checkClassName); 223 } 224 225 if (checkMethodName != null) 226 { 227 Method [] methods = realClass.getMethods(); 229 230 int index = 0; 231 for ( ; index < methods.length; index++) 232 { 233 if (!Modifier.isStatic(methods[index].getModifiers())) 234 { 235 continue; 236 } 237 238 if (checkMethodName.equals(methods[index].getName())) 239 { 240 break; 241 } 242 } 243 244 if (index == methods.length) 245 { 246 throw StandardException.newException(SQLState.LANG_NO_METHOD_MATCHING_ALIAS, 247 checkMethodName, checkClassName); 248 } 249 } 250 } 251 } 252 253 254 263 dd.startWriting(lcc); 264 265 266 SchemaDescriptor sd = null; 267 if (activation == null) 268 sd = dd.getSysIBMSchemaDescriptor(); 269 else if (schemaName != null) 270 sd = DDLConstantAction.getSchemaDescriptorForCreate(dd, activation, schemaName); 271 272 UUID aliasID = dd.getUUIDFactory().createUUID(); 276 277 AliasDescriptor ads = new AliasDescriptor(dd, aliasID, 278 aliasName, 279 sd != null ? sd.getUUID() : null, 280 javaClassName, 281 aliasType, 282 nameSpace, 283 false, 284 aliasInfo, null); 285 286 switch (aliasType) { 288 case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR: 289 case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR: 290 { 291 292 java.util.List list = dd.getRoutineList( 293 sd.getUUID().toString(), aliasName, aliasType); 294 for (int i = list.size() - 1; i >= 0; i--) { 295 296 AliasDescriptor proc = (AliasDescriptor) list.get(i); 297 298 RoutineAliasInfo procedureInfo = (RoutineAliasInfo) proc.getAliasInfo(); 299 int parameterCount = procedureInfo.getParameterCount(); 300 if (parameterCount != ((RoutineAliasInfo) aliasInfo).getParameterCount()) 301 continue; 302 303 throw StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS, 306 ads.getDescriptorType(), 307 aliasName); 308 } 309 } 310 break; 311 case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR: 312 TableDescriptor targetTD = dd.getTableDescriptor(aliasName, sd); 314 if (targetTD != null) 315 { 316 throw StandardException.newException( 317 SQLState.LANG_OBJECT_ALREADY_EXISTS, 318 targetTD.getDescriptorType(), 319 targetTD.getDescriptorName()); 320 } 321 322 String nextSynTable = ((SynonymAliasInfo)aliasInfo).getSynonymTable(); 324 String nextSynSchema = ((SynonymAliasInfo)aliasInfo).getSynonymSchema(); 325 SchemaDescriptor nextSD; 326 for (;;) 327 { 328 nextSD = dd.getSchemaDescriptor(nextSynSchema, tc, false); 329 if (nextSD == null) 330 break; 331 332 AliasDescriptor nextAD = dd.getAliasDescriptor(nextSD.getUUID().toString(), 333 nextSynTable, nameSpace); 334 if (nextAD == null) 335 break; 336 337 SynonymAliasInfo info = (SynonymAliasInfo) nextAD.getAliasInfo(); 338 nextSynTable = info.getSynonymTable(); 339 nextSynSchema = info.getSynonymSchema(); 340 341 if (aliasName.equals(nextSynTable) && schemaName.equals(nextSynSchema)) 342 throw StandardException.newException(SQLState.LANG_SYNONYM_CIRCULAR, 343 aliasName, ((SynonymAliasInfo)aliasInfo).getSynonymTable()); 344 } 345 346 if (nextSD != null) 348 targetTD = dd.getTableDescriptor(nextSynTable, nextSD); 349 if (nextSD == null || targetTD == null) 350 activation.addWarning( 351 StandardException.newWarning(SQLState.LANG_SYNONYM_UNDEFINED, 352 aliasName, nextSynSchema+"."+nextSynTable)); 353 354 TableDescriptor td; 358 DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator(); 359 td = ddg.newTableDescriptor(aliasName, sd, TableDescriptor.SYNONYM_TYPE, 360 TableDescriptor.DEFAULT_LOCK_GRANULARITY); 361 dd.addDescriptor(td, sd, DataDictionary.SYSTABLES_CATALOG_NUM, false, tc); 362 363 default: 364 break; 365 } 366 367 dd.addDescriptor(ads, null, DataDictionary.SYSALIASES_CATALOG_NUM, 368 false, lcc.getTransactionExecute()); 369 } 370 } 371 | Popular Tags |