db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d..@apache.org
Subject svn commit: r521882 - in /db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile: ActivationClassBuilder.java ExpressionClassBuilder.java StatementNode.java SubqueryNode.java
Date Fri, 23 Mar 2007 19:48:36 GMT
Author: djd
Date: Fri Mar 23 12:48:35 2007
New Revision: 521882

URL: http://svn.apache.org/viewvc?view=rev&rev=521882
Log:
DERBY-827 (partial) Clean up generation of execute() method of activation to ensure
that if the ResultSet is re-used then the execute actions are still called per-execute
instead of once when the result set is created.

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/ExpressionClassBuilder.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/SubqueryNode.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?view=diff&rev=521882&r1=521881&r2=521882
==============================================================================
--- 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 Mar 23 12:48:35 2007
@@ -201,7 +201,7 @@
 	 *
 	 * @exception StandardException thrown on failure
 	 */
-	public	MethodBuilder	beginExecuteMethod()
+	private	MethodBuilder	beginExecuteMethod()
 		throws StandardException
 	{
 		// create a reset method that does nothing.
@@ -265,9 +265,6 @@
 	   Upon entry the only word on the stack is the result set expression
 	 */
 	void finishExecuteMethod(boolean genMarkAsTopNode) {
-
-		executeMethod.pushThis();
-		executeMethod.getField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet);
 
 		/* We only call markAsTopResultSet() for selects.
 		 * Non-select DML marks the top NoPutResultSet in the constructor.

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?view=diff&rev=521882&r1=521881&r2=521882
==============================================================================
--- 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 Mar 23 12:48:35 2007
@@ -178,28 +178,6 @@
 	abstract	void 	setNumSubqueries()
 		 throws StandardException;
 
-	/**
-	 * Build boiler plate for the Execute method
-	 *
-	 *
-	 *	@return	a method builder containing boiler plate for the Execute method
-	 *
-	 * 	@exception StandardException thrown on failure
-	 */
-	abstract	MethodBuilder	beginExecuteMethod()
-		throws StandardException;
-
-
-	/**
-	 * Finish up the Execute method.
-	 *
-	 *
-	 * 	@exception StandardException thrown on failure
-	 */
-	abstract		void 			finishExecuteMethod(boolean		genMarkAsTopNode )
-		throws StandardException;
-
-
 	///////////////////////////////////////////////////////////////////////
 	//
 	// ACCESSORS
@@ -225,10 +203,12 @@
 	}
 
 	/**
-	 * The execute method returns a result set that will evaluate the
-	 * statement this activation class is the compiled form of.
-	 * REVISIT: do we need to give the caller the ability to touch it
-	 * directly, or could we wrap the alterations to it in this class?
+     * 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. 
 	 */
 	MethodBuilder getExecuteMethod() {
 		return executeMethod;

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?view=diff&rev=521882&r1=521881&r2=521882
==============================================================================
--- 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
Mar 23 12:48:35 2007
@@ -300,53 +300,75 @@
 		ActivationClassBuilder generatingClass = new ActivationClassBuilder(
 										superClass, 
 										getCompilerContext());
-		MethodBuilder executeMethod = generatingClass.getExecuteMethod();
 
-
-		/*
-		** the resultSet variable is cached.
-		**
-		** 	resultSet = (resultSet == null) ? ... : resultSet
-		*/
+        /*
+         * Generate the code to execute this statement.
+         * Two methods are generated here: execute() and
+         * fillResultSet().
+         * <BR>
+         * execute 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>
+         * public ResultSet execute() {
+         * 
+         *    // these two added by ActivationClassBuilder
+         *    throwIfClosed("execute");
+         *    startExecution();
+         *    
+         *    [per-execution code added by nodes]
+         *    
+         *    if (resultSet == null)
+         *        resultSet = fillResultSet();
+         *    
+         *    return resultSet;
+         * }
+         * </code>
+         */
+
+        MethodBuilder executeMethod = generatingClass.getExecuteMethod();
+
+        MethodBuilder mbWorker = generatingClass.getClassBuilder().newMethodBuilder(
+                Modifier.PRIVATE,
+                ClassName.ResultSet,
+                "fillResultSet");
+        mbWorker.addThrownException(ClassName.StandardException);
+        
+        // Generate the complete ResultSet tree for this statement.
+        // This step may add statements into the execute method
+        // for per-execution actions.
+        generate(generatingClass, mbWorker);
+        mbWorker.methodReturn();
+        mbWorker.complete();
 
 		executeMethod.pushThis();
-		executeMethod.getField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet);
+		executeMethod.getField(ClassName.BaseActivation, "resultSet",
+                ClassName.ResultSet);
+        
 		executeMethod.conditionalIfNull();
-
-			/* We should generate the result set here.  However, the generated
-			 * code size may be too big to fit in a conditional statement for
-			 * Java compiler to handle (it has a jump/branch step limit).  For
-			 * example, a extremely huge insert is issued with many many rows
-			 * (beetle 4293).  We fork a worker method here to get the
-			 * generated result set, pass our parameter to it and call it.
-			 */
-			MethodBuilder mbWorker = generatingClass.getClassBuilder().newMethodBuilder(
-														Modifier.PROTECTED,
-														ClassName.ResultSet,
-														"fillResultSet");
-			mbWorker.addThrownException(ClassName.StandardException);
-
-			// we expect to get back an expression that will give a resultSet
-			// the nodes use the generatingClass: they add expression functions
-			// to it, and then use those functions in their expressions.
-			generate(generatingClass, mbWorker);
-
-			mbWorker.methodReturn();
-			mbWorker.complete();
+        
+            // 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.
+			
 			executeMethod.pushThis();
 			executeMethod.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null,
 									 "fillResultSet", ClassName.ResultSet, 0);
-
+            executeMethod.pushThis();
+            executeMethod.swap();
+            executeMethod.putField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet);
+            
 		executeMethod.startElseCode(); // this is here as the compiler only supports ? :
 			executeMethod.pushThis();
 			executeMethod.getField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet);
 		executeMethod.completeConditional();
-
-		executeMethod.pushThis();
-		executeMethod.swap();
-		executeMethod.putField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet);
-
-		executeMethod.endStatement();
 
    		// wrap up the activation class definition
 		// generate on the tree gave us back the newExpr

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SubqueryNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SubqueryNode.java?view=diff&rev=521882&r1=521881&r2=521882
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SubqueryNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SubqueryNode.java Fri
Mar 23 12:48:35 2007
@@ -2075,7 +2075,7 @@
 			MethodBuilder mbsq,
 			String 			type)
 	{
-		MethodBuilder mb = acb.executeMethod;
+		MethodBuilder mb = acb.getExecuteMethod();
 
 		// declare field
 		LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, type);



Mime
View raw message