db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r1400023 - in /db/derby/code/trunk/java/engine/org/apache/derby/impl/sql: compile/ execute/
Date Fri, 19 Oct 2012 10:18:55 GMT
Author: kahatlen
Date: Fri Oct 19 10:18:55 2012
New Revision: 1400023

URL: http://svn.apache.org/viewvc?rev=1400023&view=rev
Log:
DERBY-5947: Factor out common code from generated classes

Moved more code to BaseActivation.execute(). Specifically, code to
initialize BaseActivation's resultSet field and marking the root of
the result set tree as the top-level result set.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ActivationClassBuilder.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ExpressionClassBuilder.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/InsertNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StatementNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstantActionActivation.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ActivationClassBuilder.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ActivationClassBuilder.java?rev=1400023&r1=1400022&r2=1400023&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ActivationClassBuilder.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ActivationClassBuilder.java
Fri Oct 19 10:18:55 2012
@@ -94,7 +94,6 @@ class ActivationClassBuilder	extends	Exp
 	ActivationClassBuilder (String superClass, CompilerContext cc) throws StandardException
 	{
 		super( superClass, (String) null, cc );
-		executeMethod = beginExecuteMethod();
 	}
 
 	///////////////////////////////////////////////////////////////////////
@@ -162,49 +161,6 @@ class ActivationClassBuilder	extends	Exp
 	//
 	///////////////////////////////////////////////////////////////////////
 
-	/**
-	 * By the time this is done, it has generated the following code
-	 * <pre>
-	 *		protected ResultSet doExecute() throws StandardException {
-	 *			// statements must be added here
-	 *		}
-	 *    }
-	 * </pre>
-	 *
-	 * @exception StandardException thrown on failure
-	 */
-	private	MethodBuilder	beginExecuteMethod()
-		throws StandardException
-	{
-		// create a reset method that does nothing.
-		// REVISIT: this might better belong in the Activation
-		// superclasses ?? not clear yet what it needs to do.
-
-		// don't yet need a reset method here. when we do,
-		// it will need to call super.reset() as well as
-		// whatever it does.
-		// mb = cb.newMethodBuilder(
-		// 	Modifier.PUBLIC, "void", "reset");
-		// mb.addStatement(javaFac.newStatement(
-		//		javaFac.newSpecialMethodCall(
-		//			thisExpression(),
-		//			BaseActivation.CLASS_NAME,
-		//			"reset", "void")));
-		// mb.addStatement(javaFac.newReturnStatement());
-		// mb.complete(); // there is nothing else.
-
-
-		// This method is an implementation of the abstract method
-		// BaseActivation - ResultSet doExecute()
-
-		// create an empty execute method
-		MethodBuilder mb = cb.newMethodBuilder(Modifier.PROTECTED,
-			ClassName.ResultSet, "doExecute");
-		mb.addThrownException(ClassName.StandardException);
-
-		return	mb;
-	}
-
 	MethodBuilder startResetMethod() {
 		MethodBuilder mb = cb.newMethodBuilder(Modifier.PUBLIC,
 			"void", "reset");
@@ -225,23 +181,12 @@ class ActivationClassBuilder	extends	Exp
 
 	   Upon entry the only word on the stack is the result set expression
 	 */
-	void finishExecuteMethod(boolean genMarkAsTopNode) {
-
-		/* We only call markAsTopResultSet() for selects.
-		 * Non-select DML marks the top NoPutResultSet in the constructor.
-		 * Needed for closing down resultSet on an error.
-		 */
-		if (genMarkAsTopNode)
-		{
-			// dup the result set to leave one for the return and one for this call
-			executeMethod.dup();
-			executeMethod.cast(ClassName.NoPutResultSet);
-			executeMethod.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "markAsTopResultSet",
"void", 0);
-		}
+	void finishExecuteMethod() {
 
-		/* return resultSet */
-		executeMethod.methodReturn();
-		executeMethod.complete();
+        if (executeMethod != null) {
+            executeMethod.methodReturn();
+            executeMethod.complete();
+        }
 
         // Create and initialize a static field that holds row count statistics.
         LocalField rowCountField = newFieldDeclaration(
@@ -397,8 +342,10 @@ class ActivationClassBuilder	extends	Exp
 		//    to tell cdt to restart:
 		//	  cdt.forget();
 
-		executeMethod.getField(lf);
-		executeMethod.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, "forget", "void", 0);
+        MethodBuilder execute = getExecuteMethod();
+        execute.getField(lf);
+        execute.callMethod(
+                VMOpcode.INVOKEVIRTUAL, (String) null, "forget", "void", 0);
 
 		return lf;
 	}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java?rev=1400023&r1=1400022&r2=1400023&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java
Fri Oct 19 10:18:55 2012
@@ -161,16 +161,16 @@ abstract class DMLModStatementNode exten
 	 * If yes, we will remove all the data from the temporary table
 	 *
 	 * @param acb	The ActivationClassBuilder for the class being built
-	 * @param mb	The execute() method to be built
 	 *
 	 * @exception StandardException		Thrown on error
 	 */
-	protected void generateCodeForTemporaryTable(ActivationClassBuilder acb, MethodBuilder mb)
+	protected void generateCodeForTemporaryTable(ActivationClassBuilder acb)
 		throws StandardException
 	{
 		if (targetTableDescriptor != null && targetTableDescriptor.getTableType() == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE
&&
 			targetTableDescriptor.isOnRollbackDeleteRows() == true)
 		{
+            MethodBuilder mb = acb.getExecuteMethod();
 			mb.pushThis();
 			mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Activation,
 									"getLanguageConnectionContext", ClassName.LanguageConnectionContext, 0);

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java?rev=1400023&r1=1400022&r2=1400023&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java Fri
Oct 19 10:18:55 2012
@@ -531,8 +531,8 @@ public class DeleteNode extends DMLModSt
 		// If the DML is on the temporary table, generate the code to
 		// mark temporary table as modified in the current UOW. After
 		// DERBY-827 this must be done in execute() since
-		// fillResultSet() will only be called once.
-		generateCodeForTemporaryTable(acb, acb.getExecuteMethod());
+		// createResultSet() will only be called once.
+		generateCodeForTemporaryTable(acb);
 
 		/* generate the parameters */
 		if(!isDependentTable)

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ExpressionClassBuilder.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ExpressionClassBuilder.java?rev=1400023&r1=1400022&r2=1400023&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ExpressionClassBuilder.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ExpressionClassBuilder.java
Fri Oct 19 10:18:55 2012
@@ -22,55 +22,25 @@
 package org.apache.derby.impl.sql.compile;
 
 
+import java.io.Serializable;
+import java.lang.reflect.Modifier;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.reference.ClassName;
+import org.apache.derby.iapi.services.classfile.VMOpcode;
 import org.apache.derby.iapi.services.compiler.ClassBuilder;
-import org.apache.derby.iapi.services.compiler.MethodBuilder;
 import org.apache.derby.iapi.services.compiler.JavaFactory;
 import org.apache.derby.iapi.services.compiler.LocalField;
-import org.apache.derby.iapi.reference.ClassName;
-
+import org.apache.derby.iapi.services.compiler.MethodBuilder;
+import org.apache.derby.iapi.services.io.FormatableArrayHolder;
+import org.apache.derby.iapi.services.loader.GeneratedClass;
 import org.apache.derby.iapi.services.sanity.SanityManager;
-
 import org.apache.derby.iapi.sql.compile.CompilerContext;
 import org.apache.derby.iapi.sql.compile.ExpressionClassBuilderInterface;
-
-import org.apache.derby.iapi.sql.execute.ResultSetFactory;
-import org.apache.derby.iapi.sql.execute.ExecutionFactory;
-import org.apache.derby.iapi.sql.execute.ExecIndexRow;
-
-import org.apache.derby.iapi.sql.Activation;
-import org.apache.derby.iapi.sql.ParameterValueSet;
-import org.apache.derby.iapi.sql.Row;
-
-import org.apache.derby.iapi.sql.execute.ExecRow;
-
-import org.apache.derby.impl.sql.compile.OrderedColumnList;
-import org.apache.derby.impl.sql.compile.ResultColumnList;
-import org.apache.derby.impl.sql.execute.IndexColumnOrder;
+import org.apache.derby.iapi.sql.compile.TypeCompiler;
 import org.apache.derby.iapi.store.access.ColumnOrdering;
-
-import org.apache.derby.iapi.types.DataValueDescriptor;
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-import org.apache.derby.iapi.types.DataValueFactory;
 import org.apache.derby.iapi.types.TypeId;
-
-import org.apache.derby.iapi.sql.compile.TypeCompiler;
-
-import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.util.ByteArray;
-
-import org.apache.derby.iapi.services.loader.ClassFactory;
-import org.apache.derby.iapi.services.loader.GeneratedClass;
-import org.apache.derby.iapi.services.loader.GeneratedByteCode;
-import org.apache.derby.iapi.services.loader.GeneratedMethod;
-
-import java.lang.reflect.Modifier;
-import org.apache.derby.iapi.services.classfile.VMOpcode;
-
-import org.apache.derby.iapi.services.monitor.Monitor;
-
-import org.apache.derby.iapi.services.io.FormatableArrayHolder;
-
-import java.io.Serializable;
+import org.apache.derby.impl.sql.execute.IndexColumnOrder;
 
 /**
  * ExpressionClassBuilder
@@ -211,14 +181,18 @@ abstract	class ExpressionClassBuilder im
 	}
 
 	/**
-     * Get the execute method in order to add code to it.
-     * Added code will be executed for each execution
-     * of the activation. StatementNode completes the
-     * execute method so that code added by other nodes
-     * will be executed before the ResultSet is created
-     * using fillResultSet. 
+     * Get a method builder for adding code to the execute() method.
+     * The method builder does not actually build a method called execute.
+     * Instead, it creates a method that overrides the reinit() method,
+     * which is called from execute() on every execution in order to
+     * reinitialize the data structures.
 	 */
 	MethodBuilder getExecuteMethod() {
+        if (executeMethod == null) {
+            executeMethod =
+                    cb.newMethodBuilder(Modifier.PROTECTED, "void", "reinit");
+            executeMethod.addThrownException(ClassName.StandardException);
+        }
 		return executeMethod;
 	}
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/InsertNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/InsertNode.java?rev=1400023&r1=1400022&r2=1400023&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/InsertNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/InsertNode.java Fri
Oct 19 10:18:55 2012
@@ -908,8 +908,8 @@ public final class InsertNode extends DM
 		// If the DML is on the temporary table, generate the code to
 		// mark temporary table as modified in the current UOW. After
 		// DERBY-827 this must be done in execute() since
-		// fillResultSet() will only be called once.
-		generateCodeForTemporaryTable(acb, acb.getExecuteMethod());
+		// createResultSet() will only be called once.
+		generateCodeForTemporaryTable(acb);
 
 		/* generate the parameters */
 		generateParameterValueSet(acb);

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StatementNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StatementNode.java?rev=1400023&r1=1400022&r2=1400023&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StatementNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StatementNode.java Fri
Oct 19 10:18:55 2012
@@ -299,40 +299,13 @@ public abstract class StatementNode exte
 										superClass, 
 										getCompilerContext());
 
-        /*
-         * Generate the code to execute this statement.
-         * Two methods are generated here: doExecute() and
-         * fillResultSet().
-         * <BR>
-         * doExecute() is called for every execution of the
-         * Activation. Nodes may add code to this using
-         * ActivationClassBuilder.getExecuteMethod().
-         * This code will be executed every execution.
-         * <BR>
-         * fillResultSet is called by execute if the BaseActivation's
-         * resultSet field is null and the returned ResultSet is
-         * set into the the resultSet field.
-         * <P>
-         * The generated code is equivalent to:
-         * <code>
-         * protected ResultSet doExecute() {
-         * 
-         *    [per-execution code added by nodes]
-         *    
-         *    if (resultSet == null)
-         *        resultSet = fillResultSet();
-         *    
-         *    return resultSet;
-         * }
-         * </code>
-         */
-
-        MethodBuilder executeMethod = generatingClass.getExecuteMethod();
-
+        // Create the method that generates the ResultSet tree used when
+        // executing this statement. Implements the abstract method
+        // BaseActivation.createResultSet().
         MethodBuilder mbWorker = generatingClass.getClassBuilder().newMethodBuilder(
-                Modifier.PRIVATE,
+                Modifier.PROTECTED,
                 ClassName.ResultSet,
-                "fillResultSet");
+                "createResultSet");
         mbWorker.addThrownException(ClassName.StandardException);
         
         // Generate the complete ResultSet tree for this statement.
@@ -342,35 +315,6 @@ public abstract class StatementNode exte
         mbWorker.methodReturn();
         mbWorker.complete();
 
-        // Get the value of the resultSet field.
-		executeMethod.pushThis();
-		executeMethod.getField(ClassName.BaseActivation, "resultSet",
-                ClassName.ResultSet);
-
-        // Keep a copy of the field value on the stack so we don't need
-        // to look it up again if it's non-null.
-        executeMethod.dup();
-		executeMethod.conditionalIfNull();
-
-            // The field was null, so we won't use the value that's on the
-            // stack. Forget about it.
-            executeMethod.pop();
-
-            // Generate the result set tree and store the
-            // resulting top-level result set into the resultSet
-            // field, as well as returning it from the execute method.
-
-            // Push this onto the stack twice, as both callMethod() and
-            // putField() take the instance as first operand.
-			executeMethod.pushThis();
-            executeMethod.dup();
-			executeMethod.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null,
-									 "fillResultSet", ClassName.ResultSet, 0);
-            executeMethod.putField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet);
-            
-		executeMethod.startElseCode(); // this is here as the compiler only supports ? :
-		executeMethod.completeConditional();
-
    		// wrap up the activation class definition
 		// generate on the tree gave us back the newExpr
 		// for getting a result set on the tree.
@@ -380,7 +324,7 @@ public abstract class StatementNode exte
 		// the activation class builder takes care of constructing it
 		// for us, given the resultSetExpr to use.
 		//   return (this.resultSet = #resultSetExpr);
-		generatingClass.finishExecuteMethod(this instanceof CursorNode);
+		generatingClass.finishExecuteMethod();
 
 		// wrap up the constructor by putting a return at the end of it
 		generatingClass.finishConstructor();

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java?rev=1400023&r1=1400022&r2=1400023&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java Fri
Oct 19 10:18:55 2012
@@ -799,8 +799,8 @@ public final class UpdateNode extends DM
 		// If the DML is on the temporary table, generate the code to
 		// mark temporary table as modified in the current UOW. After
 		// DERBY-827 this must be done in execute() since
-		// fillResultSet() will only be called once.
-		generateCodeForTemporaryTable(acb, acb.getExecuteMethod());
+		// createResultSet() will only be called once.
+		generateCodeForTemporaryTable(acb);
 
 		/* generate the parameters */
 		if(!isDependentTable)

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java?rev=1400023&r1=1400022&r2=1400023&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java
Fri Oct 19 10:18:55 2012
@@ -270,14 +270,36 @@ public abstract class BaseActivation imp
             rowCountsCheckedThisExecution.clear();
         }
 
-        return doExecute();
+        // Reinitialize data structures in the generated class before
+        // each execution.
+        reinit();
+
+        // Create the result set tree on the first execution.
+        if (resultSet == null) {
+             resultSet = createResultSet();
+             if (isCursorActivation()) {
+                 ((NoPutResultSet) resultSet).markAsTopResultSet();
+             }
+        }
+
+        return resultSet;
     }
 
     /**
-     * Abstract method overridden by generated classes, containing the
-     * body of the {@link #execute()} method.
+     * Create the ResultSet tree for this statement.
+     * @return the root of the ResultSet tree for this statement
+     */
+    protected abstract ResultSet createResultSet() throws StandardException;
+
+    /**
+     * Reinitialize data structures added by the sub-classes before each
+     * execution of the statement. The default implementation does nothing.
+     * Sub-classes should override this method if they need to perform
+     * operations before each execution.
      */
-    protected abstract ResultSet doExecute() throws StandardException;
+    protected void reinit() throws StandardException {
+        // Do nothing by default. Overridden by sub-classes that need it.
+    }
 
 	public final ExecPreparedStatement getPreparedStatement() {
 		return preStmt;

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstantActionActivation.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstantActionActivation.java?rev=1400023&r1=1400022&r2=1400023&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstantActionActivation.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstantActionActivation.java
Fri Oct 19 10:18:55 2012
@@ -22,11 +22,8 @@
 package org.apache.derby.impl.sql.execute;
 
 import org.apache.derby.iapi.error.StandardException;
-
 import org.apache.derby.iapi.sql.ResultSet;
 
-import java.util.Vector;
-
 /**
 	A pre-compiled activation that supports a single ResultSet with
 	a single constant action. All the execution logic is contained
@@ -57,11 +54,9 @@ public final class ConstantActionActivat
         return null;
     }
 
-	protected ResultSet doExecute() throws StandardException {
-		if (resultSet == null)
-			resultSet = getResultSetFactory().getDDLResultSet(this);
-		return resultSet;
-	}
+    protected ResultSet createResultSet() throws StandardException {
+        return getResultSetFactory().getDDLResultSet(this);
+    }
 
 	public void postConstructor(){}
 }



Mime
View raw message