1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.services.context.ContextManager; 25 26 import org.apache.derby.iapi.error.StandardException; 27 28 import org.apache.derby.iapi.sql.compile.CompilerContext; 29 30 import org.apache.derby.impl.sql.compile.ActivationClassBuilder; 31 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 32 import org.apache.derby.iapi.sql.dictionary.TableDescriptor; 33 import org.apache.derby.iapi.store.access.ConglomerateController; 34 import org.apache.derby.iapi.store.access.TransactionController; 35 36 import org.apache.derby.iapi.services.compiler.MethodBuilder; 37 38 import org.apache.derby.iapi.reference.SQLState; 39 import org.apache.derby.iapi.reference.ClassName; 40 import org.apache.derby.iapi.services.loader.GeneratedClass; 41 42 import org.apache.derby.iapi.util.ByteArray; 43 import org.apache.derby.iapi.services.classfile.VMOpcode; 44 45 import org.apache.derby.iapi.services.sanity.SanityManager; 46 47 import java.lang.reflect.Modifier ; 48 49 57 58 62 63 abstract class StatementNode extends QueryTreeNode 64 { 65 66 75 public boolean isAtomic() throws StandardException 76 { 77 return true; 78 } 79 80 86 87 public String toString() 88 { 89 if (SanityManager.DEBUG) 90 { 91 return "statementType: " + statementToString() + "\n" + 92 super.toString(); 93 } 94 else 95 { 96 return ""; 97 } 98 } 99 100 public abstract String statementToString(); 101 102 107 static final int NEED_DDL_ACTIVATION = 5; 108 static final int NEED_CURSOR_ACTIVATION = 4; 109 static final int NEED_PARAM_ACTIVATION = 2; 110 static final int NEED_ROW_ACTIVATION = 1; 111 static final int NEED_NOTHING_ACTIVATION = 0; 112 113 abstract int activationKind(); 114 115 120 protected TableDescriptor lockTableForCompilation(TableDescriptor td) 121 throws StandardException 122 { 123 DataDictionary dd = getDataDictionary(); 124 125 127 if (dd.getCacheMode() == DataDictionary.DDL_MODE) 128 { 129 ConglomerateController heapCC; 130 TransactionController tc = 131 getLanguageConnectionContext().getTransactionCompile(); 132 133 heapCC = tc.openConglomerate(td.getHeapConglomerateId(), 134 false, 135 TransactionController.OPENMODE_FORUPDATE | 136 TransactionController.OPENMODE_FOR_LOCK_ONLY, 137 TransactionController.MODE_RECORD, 138 TransactionController.ISOLATION_SERIALIZABLE); 139 heapCC.close(); 140 145 String tableName = td.getName(); 146 td = getTableDescriptor(td.getName(), getSchemaDescriptor(td.getSchemaName())); 147 if (td == null) 148 { 149 throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, tableName); 150 } 151 } 152 return td; 153 } 154 155 156 167 public GeneratedClass generate(ByteArray byteCode) throws StandardException 168 { 169 174 int nodeChoice = activationKind(); 175 176 181 String superClass; 182 switch (nodeChoice) 183 { 184 case NEED_CURSOR_ACTIVATION: 185 superClass = ClassName.CursorActivation; 186 break; 187 case NEED_DDL_ACTIVATION: 188 return getClassFactory().loadGeneratedClass( 189 "org.apache.derby.impl.sql.execute.ConstantActionActivation", null); 190 191 case NEED_NOTHING_ACTIVATION : 192 case NEED_ROW_ACTIVATION : 193 case NEED_PARAM_ACTIVATION : 194 superClass = ClassName.BaseActivation; 195 break; 196 default : 197 throw StandardException.newException(SQLState.LANG_UNAVAILABLE_ACTIVATION_NEED, 198 String.valueOf(nodeChoice)); 199 } 200 201 ActivationClassBuilder generatingClass = new ActivationClassBuilder( 202 superClass, 203 getCompilerContext()); 204 MethodBuilder executeMethod = generatingClass.getExecuteMethod(); 205 206 207 212 213 executeMethod.pushThis(); 214 executeMethod.getField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet); 215 executeMethod.conditionalIfNull(); 216 217 224 MethodBuilder mbWorker = generatingClass.getClassBuilder().newMethodBuilder( 225 Modifier.PROTECTED, 226 ClassName.ResultSet, 227 "fillResultSet"); 228 mbWorker.addThrownException(ClassName.StandardException); 229 230 generate(generatingClass, mbWorker); 234 235 mbWorker.methodReturn(); 236 mbWorker.complete(); 237 executeMethod.pushThis(); 238 executeMethod.callMethod(VMOpcode.INVOKEVIRTUAL, (String ) null, 239 "fillResultSet", ClassName.ResultSet, 0); 240 241 executeMethod.startElseCode(); executeMethod.pushThis(); 243 executeMethod.getField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet); 244 executeMethod.completeConditional(); 245 246 executeMethod.pushThis(); 247 executeMethod.swap(); 248 executeMethod.putField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet); 249 250 executeMethod.endStatement(); 251 252 generatingClass.finishExecuteMethod(this instanceof CursorNode); 262 263 generatingClass.finishConstructor(); 265 266 try { 267 GeneratedClass activationClass = generatingClass.getGeneratedClass(byteCode); 270 271 return activationClass; 272 } catch (StandardException e) { 273 274 String msgId = e.getMessageId(); 275 276 if (SQLState.GENERATED_CLASS_LIMIT_EXCEEDED.equals(msgId) 277 || SQLState.GENERATED_CLASS_LINKAGE_ERROR.equals(msgId)) 278 { 279 throw StandardException.newException( 280 SQLState.LANG_QUERY_TOO_COMPLEX, e); 281 } 282 283 throw e; 284 } 285 } 286 } 287 | Popular Tags |