db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r1131002 - in /db/derby/code/branches/10.8: ./ java/engine/org/apache/derby/iapi/services/io/ java/engine/org/apache/derby/iapi/types/ java/engine/org/apache/derby/impl/sql/compile/ java/engine/org/apache/derby/impl/sql/execute/ java/testin...
Date Fri, 03 Jun 2011 11:49:40 GMT
Author: kahatlen
Date: Fri Jun  3 11:49:40 2011
New Revision: 1131002

URL: http://svn.apache.org/viewvc?rev=1131002&view=rev
Log:
DERBY-3870: Concurrent Inserts of rows with XML data results in an exception

Back out fix while upgrade issues are worked out.

Added:
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/execute/SqlXmlExecutor.java
      - copied unchanged from r1130982, db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/execute/SqlXmlExecutor.java
Removed:
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/OperatorNode.java
    db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/XMLConcurrencyTest.java
Modified:
    db/derby/code/branches/10.8/   (props changed)
    db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/SqlXmlUtil.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/XML.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/XMLDataValue.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/BinaryOperatorNode.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/UnaryOperatorNode.java
    db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/suites/XMLSuite.java
    db/derby/code/branches/10.8/tools/jar/extraDBMSclasses.properties

Propchange: db/derby/code/branches/10.8/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jun  3 11:49:40 2011
@@ -1,2 +1,2 @@
 /db/derby/code/branches/10.7:1061570,1061578,1082235
-/db/derby/code/trunk:1063809,1088633,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1096741,1096890,1097247,1097249,1097460,1097469,1097471,1101839,1102826,1103681,1103718,1125305,1126358,1127825,1127883,1129136,1129764,1129797
+/db/derby/code/trunk:1063809,1088633,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1096741,1096890,1097247,1097249,1097460,1097469,1097471,1102826,1103681,1103718,1127825,1129136,1129764,1129797

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java?rev=1131002&r1=1131001&r2=1131002&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java
(original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java
Fri Jun  3 11:49:40 2011
@@ -525,7 +525,7 @@ String[] TwoByte = {
         /* 461 */   "org.apache.derby.impl.sql.catalog.CoreDDFinderClassInfo",
         /* 462 */   "org.apache.derby.impl.sql.catalog.CoreDDFinderClassInfo",
         /* 463 */   "org.apache.derby.impl.sql.catalog.CoreDDFinderClassInfo",
-        /* 464 */   null,
+        /* 464 */   "org.apache.derby.iapi.types.SqlXmlUtil",        
 		/* 465 */   "org.apache.derby.impl.store.raw.data.CompressSpacePageOperation",
         /* 466 */   "org.apache.derby.impl.store.access.btree.index.B2I_10_3",
         /* 467 */   "org.apache.derby.impl.store.access.heap.Heap",

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java?rev=1131002&r1=1131001&r2=1131002&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java
(original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java
Fri Jun  3 11:49:40 2011
@@ -506,6 +506,12 @@ public interface StoredFormatIds {
             (MIN_ID_2 + 456);
     
     /**
+        class org.apache.derby.iapi.types.SqlXmlUtil
+    */
+    static public final int SQL_XML_UTIL_V01_ID =
+            (MIN_ID_2 + 464);
+    
+    /**
         class org.apache.derby.iapi.types.JSQLType
      */
     static public final int JSQLTYPEIMPL_ID =

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/SqlXmlUtil.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/SqlXmlUtil.java?rev=1131002&r1=1131001&r2=1131002&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/SqlXmlUtil.java (original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/SqlXmlUtil.java Fri
Jun  3 11:49:40 2011
@@ -23,6 +23,8 @@ package org.apache.derby.iapi.types;
 
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.reference.SQLState;
+import org.apache.derby.iapi.services.io.Formatable;
+import org.apache.derby.iapi.services.io.StoredFormatIds;
 import org.apache.derby.iapi.services.sanity.SanityManager;
 
 import java.util.Properties;
@@ -31,6 +33,8 @@ import java.util.Collections;
 import java.util.List;
 
 import java.io.IOException;
+import java.io.ObjectOutput;
+import java.io.ObjectInput;
 import java.io.StringReader;
 
 import java.lang.reflect.InvocationTargetException;
@@ -80,8 +84,10 @@ import javax.xml.transform.stream.Stream
  *       query expression a single time per statement, instead of
  *       having to do it for every row against which the query
  *       is evaluated.  An instance of this class is created at
- *       compile time and then passed to the appropriate operator
- *       implementation method in XML.java.
+ *       compile time and then passed (using "saved objects")
+ *       to the appropriate operator implementation method in
+ *       XML.java; see SqlXmlExecutor.java for more about the
+ *       role this class plays in "saved object" processing.
  *
  *    2. By keeping all XML-specific references in this one class, 
  *       we have a single "point of entry" to the XML objects--namely,
@@ -107,7 +113,7 @@ import javax.xml.transform.stream.Stream
  *       _if_ s/he is trying to access or operate on XML values.
  */
 
-public class SqlXmlUtil
+public class SqlXmlUtil implements Formatable
 {
     // Used to parse a string into an XML value (DOM); checks
     // the well-formedness of the string while parsing.
@@ -797,6 +803,58 @@ public class SqlXmlUtil
         }
     }
 
+    /* ****
+     * Formatable interface implementation
+     * */
+
+    /** 
+     * @see java.io.Externalizable#writeExternal 
+     * 
+     * @exception IOException on error
+     */
+    public void writeExternal(ObjectOutput out) 
+        throws IOException
+    {
+        // query may be null
+        if (query == null)
+        {
+            out.writeBoolean(false);
+        }
+        else
+        {
+            out.writeBoolean(true);
+            out.writeObject(queryExpr);
+            out.writeObject(opName);
+        }
+    }
+
+    /** 
+     * @see java.io.Externalizable#readExternal 
+     *
+     * @exception IOException on error
+     * @exception ClassNotFoundException on error
+     */
+    public void readExternal(ObjectInput in) 
+        throws IOException, ClassNotFoundException
+    {
+        if (in.readBoolean())
+        {
+            queryExpr = (String)in.readObject();
+            opName = (String)in.readObject();
+            recompileQuery = true;
+	    }
+    }
+
+    /**
+     * Get the formatID which corresponds to this class.
+     *
+     * @return	the formatID of this class
+     */
+    public int getTypeFormatId()
+    { 
+        return StoredFormatIds.SQL_XML_UTIL_V01_ID;
+    }
+
     /*
      ** The XMLErrorHandler class is just a generic implementation
      ** of the ErrorHandler interface.  It allows us to catch

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/XML.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/XML.java?rev=1131002&r1=1131001&r2=1131002&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/XML.java (original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/XML.java Fri Jun 
3 11:49:40 2011
@@ -598,7 +598,7 @@ public class XML
      * store the _serialized_ version locally and then return
      * this XMLDataValue.
      *
-     * @param stringValue The string value to check.
+     * @param text The string value to check.
      * @param preserveWS Whether or not to preserve
      *  ignorable whitespace.
      * @param sqlxUtil Contains SQL/XML objects and util
@@ -609,18 +609,9 @@ public class XML
      *  value is returned; otherwise, an exception is thrown. 
      * @exception StandardException Thrown on error.
      */
-    public XMLDataValue XMLParse(
-            StringDataValue stringValue,
-            boolean preserveWS,
-            SqlXmlUtil sqlxUtil)
-        throws StandardException
+    public XMLDataValue XMLParse(String text, boolean preserveWS,
+        SqlXmlUtil sqlxUtil) throws StandardException
     {
-        if (stringValue.isNull()) {
-            setToNull();
-            return this;
-        }
-
-        String text = stringValue.getString();
         try {
 
             if (preserveWS) {
@@ -843,10 +834,10 @@ public class XML
      * the received XMLDataValue "result" param (assuming "result" is
      * non-null; else create a new XMLDataValue).
      *
-     * @param sqlxUtil Contains SQL/XML objects and util methods that
-     *  facilitate execution of XML-related operations
      * @param result The result of a previous call to this method; null
      *  if not called yet.
+     * @param sqlxUtil Contains SQL/XML objects and util methods that
+     *  facilitate execution of XML-related operations
      * @return An XMLDataValue whose content corresponds to the serialized
      *  version of the results from evaluation of the query expression.
      *  Note: this XMLDataValue may not be storable into Derby XML
@@ -854,8 +845,8 @@ public class XML
      * @exception Exception thrown on error (and turned into a
      *  StandardException by the caller).
      */
-    public XMLDataValue XMLQuery(SqlXmlUtil sqlxUtil, XMLDataValue result)
-            throws StandardException
+    public XMLDataValue XMLQuery(XMLDataValue result,
+        SqlXmlUtil sqlxUtil) throws StandardException
     {
         if (this.isNull()) {
         // if the context is null, we return null,

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/XMLDataValue.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/XMLDataValue.java?rev=1131002&r1=1131001&r2=1131002&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/XMLDataValue.java
(original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/iapi/types/XMLDataValue.java
Fri Jun  3 11:49:40 2011
@@ -30,7 +30,7 @@ public interface XMLDataValue extends Da
      * store the _serialized_ version locally and then return
      * this XMLDataValue.
      *
-     * @param stringValue The string value to check.
+     * @param text The string value to check.
      * @param preserveWS Whether or not to preserve
      *  ignorable whitespace.
      * @param sqlxUtil Contains SQL/XML objects and util
@@ -41,11 +41,8 @@ public interface XMLDataValue extends Da
      *  value returned; otherwise, an exception is thrown. 
      * @exception StandardException Thrown on error.
      */
-    public XMLDataValue XMLParse(
-            StringDataValue stringValue,
-            boolean preserveWS,
-            SqlXmlUtil sqlxUtil)
-        throws StandardException;
+	public XMLDataValue XMLParse(String text, boolean preserveWS,
+		SqlXmlUtil sqlxUtil) throws StandardException;
 
     /**
      * The SQL/XML XMLSerialize operator.
@@ -93,10 +90,10 @@ public interface XMLDataValue extends Da
      * the received XMLDataValue "result" param (assuming "result" is
      * non-null; else create a new XMLDataValue).
      *
-     * @param sqlxUtil Contains SQL/XML objects and util methods that
-     *  facilitate execution of XML-related operations
      * @param result The result of a previous call to this method; null
      *  if not called yet.
+     * @param sqlxUtil Contains SQL/XML objects and util methods that
+     *  facilitate execution of XML-related operations
      * @return An XMLDataValue whose content corresponds to the serialized
      *  version of the results from evaluation of the query expression.
      *  Note: this XMLDataValue may not be storable into Derby XML
@@ -104,7 +101,7 @@ public interface XMLDataValue extends Da
      * @exception Exception thrown on error (and turned into a
      *  StandardException by the caller).
      */
-    public XMLDataValue XMLQuery(SqlXmlUtil sqlxUtil, XMLDataValue result)
+    public XMLDataValue XMLQuery(XMLDataValue result, SqlXmlUtil sqlxUtil)
 		throws StandardException;
 
     /* ****

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/BinaryOperatorNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/BinaryOperatorNode.java?rev=1131002&r1=1131001&r2=1131002&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/BinaryOperatorNode.java
(original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/BinaryOperatorNode.java
Fri Jun  3 11:49:40 2011
@@ -21,16 +21,25 @@
 
 package	org.apache.derby.impl.sql.compile;
 
+import org.apache.derby.iapi.sql.compile.Visitable;
 import org.apache.derby.iapi.sql.compile.Visitor;
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;
 import org.apache.derby.iapi.error.StandardException;
 
 import org.apache.derby.iapi.services.sanity.SanityManager;
 import org.apache.derby.iapi.services.compiler.MethodBuilder;
 import org.apache.derby.iapi.services.compiler.LocalField;
+import org.apache.derby.iapi.services.io.StoredFormatIds;
 
 import java.lang.reflect.Modifier;
+import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
+import org.apache.derby.impl.sql.compile.ActivationClassBuilder;
+import org.apache.derby.iapi.types.StringDataValue;
 import org.apache.derby.iapi.types.TypeId;
 import org.apache.derby.iapi.types.DataTypeDescriptor;
+import org.apache.derby.iapi.types.SqlXmlUtil;
+
+import org.apache.derby.iapi.store.access.Qualifier;
 
 import org.apache.derby.iapi.reference.ClassName;
 import org.apache.derby.iapi.reference.JDBC40Translation;
@@ -39,6 +48,7 @@ import org.apache.derby.iapi.reference.S
 import org.apache.derby.iapi.util.JBitSet;
 import org.apache.derby.iapi.services.classfile.VMOpcode;
 
+import java.sql.Types;
 import java.util.Vector;
 
 /**
@@ -49,7 +59,7 @@ import java.util.Vector;
  *
  */
 
-public class BinaryOperatorNode extends OperatorNode
+public class BinaryOperatorNode extends ValueNode
 {
 	String	operator;
 	String	methodName;
@@ -115,8 +125,9 @@ public class BinaryOperatorNode extends 
 		{ClassName.StringDataValue, ClassName.XMLDataValue}		// XMLQuery
 	};
 
-    /** The query expression if the operator is XMLEXISTS or XMLQUERY. */
-    private String xmlQuery;
+	// Class used to compile an XML query expression and/or load/process
+	// XML-specific objects.
+	private SqlXmlUtil sqlxUtil;
 
 	/**
 	 * Initializer for a BinaryOperatorNode
@@ -341,7 +352,11 @@ public class BinaryOperatorNode extends 
                 SQLState.LANG_INVALID_XML_QUERY_EXPRESSION);
         }
         else {
-            xmlQuery = ((CharConstantNode)leftOperand).getString();
+        // compile the query expression.
+            sqlxUtil = new SqlXmlUtil();
+            sqlxUtil.compileXQExpr(
+                ((CharConstantNode)leftOperand).getString(),
+                (operatorType == XMLEXISTS_OP ? "XMLEXISTS" : "XMLQUERY"));
         }
 
         // Right operand must be an XML data value.  NOTE: This
@@ -483,15 +498,29 @@ public class BinaryOperatorNode extends 
 ** but how?
 */
 
-        // The number of arguments to pass to the method that implements the
-        // operator, depends on the type of the operator.
-        int numArgs;
-
 		// If we're dealing with XMLEXISTS or XMLQUERY, there is some
 		// additional work to be done.
 		boolean xmlGen =
 			(operatorType == XMLQUERY_OP) || (operatorType == XMLEXISTS_OP);
 
+		if (xmlGen) {
+		// We create an execution-time object so that we can retrieve
+		// saved objects (esp. our compiled query expression) from
+		// the activation.  We do this for two reasons: 1) this level
+		// of indirection allows us to separate the XML data type
+		// from the required XML implementation classes (esp. JAXP
+		// and Xalan classes)--for more on how this works, see the
+		// comments in SqlXmlUtil.java; and 2) we can take
+		// the XML query expression, which we've already compiled,
+		// and pass it to the execution-time object for each row,
+		// which means that we only have to compile the query
+		// expression once per SQL statement (instead of once per
+		// row); see SqlXmlExecutor.java for more.
+			mb.pushNewStart(
+				"org.apache.derby.impl.sql.execute.SqlXmlExecutor");
+			mb.pushNewComplete(addXmlOpMethodParams(acb, mb));
+		}
+
 		/*
 		** The receiver is the operand with the higher type precedence.
 		** Like always makes the left the receiver.
@@ -529,9 +558,6 @@ public class BinaryOperatorNode extends 
 			rightOperand.generateExpression(acb, mb);
 			mb.cast(rightInterfaceType); // second arg with cast
 			// stack: left, left, right
-
-            // We've pushed two arguments
-            numArgs = 2;
 		}
 		else
 		{
@@ -555,33 +581,28 @@ public class BinaryOperatorNode extends 
 			** UNLESS we're generating an XML operator such as XMLEXISTS.
 			** In that case we want to generate
 			** 
-			**  <right expression>.method(sqlXmlUtil)
+			**  SqlXmlExecutor.method(left, right)"
+			**
+			** and we've already pushed the SqlXmlExecutor object to
+			** the stack.
 			*/
 
 			rightOperand.generateExpression(acb, mb);			
 			mb.cast(receiverType); // cast the method instance
 			// stack: right
 			
-            if (xmlGen) {
-                // Push one argument (the SqlXmlUtil instance)
-                numArgs = 1;
-                pushSqlXmlUtil(acb, mb, xmlQuery, operator);
-                // stack: right,sqlXmlUtil
-            } else {
-                // Push two arguments (left, right)
-                numArgs = 2;
-
+			if (!xmlGen) {
 				mb.dup();
 				mb.cast(rightInterfaceType);
 				// stack: right,right
+			}
 			
-                leftOperand.generateExpression(acb, mb);
-                mb.cast(leftInterfaceType); // second arg with cast
-                // stack: right,right,left
-
-                mb.swap();
-                // stack: right,left,right
-            }
+			leftOperand.generateExpression(acb, mb);
+			mb.cast(leftInterfaceType); // second arg with cast
+			// stack: right,right,left
+			
+			mb.swap();
+			// stack: right,left,right			
 		}
 
 		/* Figure out the result type name */
@@ -589,13 +610,15 @@ public class BinaryOperatorNode extends 
 			? getTypeCompiler().interfaceName()
 			: resultInterfaceType;
 
-        // Boolean return types don't need a result field. For other types,
-        // allocate an object for re-use to hold the result of the operator.
-        LocalField resultField = getTypeId().isBooleanTypeId() ?
-            null : acb.newFieldDeclaration(Modifier.PRIVATE, resultTypeName);
+		// Boolean return types don't need a result field
+		boolean needField = !getTypeId().isBooleanTypeId();
+
+		if (needField) {
+
+			/* Allocate an object for re-use to hold the result of the operator */
+			LocalField resultField =
+				acb.newFieldDeclaration(Modifier.PRIVATE, resultTypeName);
 
-        // Push the result field onto the stack, if there is a result field.
-		if (resultField != null) {
 			/*
 			** Call the method for this operator.
 			*/
@@ -604,9 +627,6 @@ public class BinaryOperatorNode extends 
 			//before generating code "field = method(p1, p2, field);"
 			initializeResultField(acb, mb, resultField);
 
-            // Adjust number of arguments for the result field
-            numArgs++;
-
 			/* pass statically calculated scale to decimal divide method to make
 			 * result set scale consistent, beetle 3901
 			 */
@@ -617,15 +637,17 @@ public class BinaryOperatorNode extends 
 				operator.equals("/"))
 			{
 				mb.push(getTypeServices().getScale());		// 4th arg
-                numArgs++;
+				mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType, methodName, resultTypeName, 4);
 			}
-        }
-
-        mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType,
-                      methodName, resultTypeName, numArgs);
+			else if (xmlGen) {
+			// This is for an XMLQUERY operation, so invoke the method
+			// on our execution-time object.
+				mb.callMethod(VMOpcode.INVOKEVIRTUAL, null,
+					methodName, resultTypeName, 3);
+			}
+			else
+				mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType, methodName, resultTypeName, 3);
 
-        // Store the result of the method call, if there is a result field.
-        if (resultField != null) {
 			//the need for following if was realized while fixing bug 5704 where decimal*decimal was
resulting an overflow value but we were not detecting it
 			if (getTypeId().variableLength())//since result type is numeric variable length, generate
setWidth code.
 			{
@@ -648,6 +670,17 @@ public class BinaryOperatorNode extends 
 			*/
 
 			mb.putField(resultField);
+		} else {
+			if (xmlGen) {
+			// This is for an XMLEXISTS operation, so invoke the method
+			// on our execution-time object.
+				mb.callMethod(VMOpcode.INVOKEVIRTUAL, null,
+					methodName, resultTypeName, 2);
+			}
+			else {
+				mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType,
+					methodName, resultTypeName, 2);
+			}
 		}
 	}
 
@@ -842,4 +875,32 @@ public class BinaryOperatorNode extends 
         	       && leftOperand.isEquivalent(other.leftOperand)
         	       && rightOperand.isEquivalent(other.rightOperand);
         }
+
+	/**
+	 * Push the fields necessary to generate an instance of
+	 * SqlXmlExecutor, which will then be used at execution
+	 * time to retrieve the compiled XML query expression,
+	 * along with any other XML-specific objects.
+	 *
+	 * @param acb The ExpressionClassBuilder for the class we're generating
+	 * @param mb  The method the code to place the code
+	 *
+	 * @return The number of items that this method pushed onto
+	 *  the mb's stack.
+	 */
+	private int addXmlOpMethodParams(ExpressionClassBuilder acb,
+		MethodBuilder mb) throws StandardException
+	{
+		// Push activation so that we can get our saved object
+		// (which will hold the compiled XML query expression)
+		// back at execute time.
+		acb.pushThisAsActivation(mb);
+
+		// Push our saved object (the compiled query and XML-specific
+		// objects).
+		mb.push(getCompilerContext().addSavedObject(sqlxUtil));
+
+		// We pushed 2 items to the stack.
+		return 2;
+	}
 }

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java?rev=1131002&r1=1131001&r2=1131002&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java
(original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java
Fri Jun  3 11:49:40 2011
@@ -54,7 +54,7 @@ import java.util.Vector;
  *
  */
 
-public class TernaryOperatorNode extends OperatorNode
+public class TernaryOperatorNode extends ValueNode
 {
 	String		operator;
 	String		methodName;

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/UnaryOperatorNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/UnaryOperatorNode.java?rev=1131002&r1=1131001&r2=1131002&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/UnaryOperatorNode.java
(original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/UnaryOperatorNode.java
Fri Jun  3 11:49:40 2011
@@ -23,8 +23,11 @@ package	org.apache.derby.impl.sql.compil
 
 import org.apache.derby.iapi.store.access.Qualifier;
 
+import org.apache.derby.iapi.sql.compile.Visitable;
 import org.apache.derby.iapi.sql.compile.Visitor;
 
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;
+
 import org.apache.derby.iapi.reference.JDBC40Translation;
 import org.apache.derby.iapi.reference.SQLState;
 import org.apache.derby.iapi.reference.ClassName;
@@ -32,11 +35,15 @@ import org.apache.derby.iapi.error.Stand
 import org.apache.derby.iapi.services.sanity.SanityManager;
 import org.apache.derby.iapi.services.compiler.MethodBuilder;
 import org.apache.derby.iapi.services.compiler.LocalField;
+import org.apache.derby.iapi.services.io.StoredFormatIds;
 
+import org.apache.derby.iapi.types.StringDataValue;
 import org.apache.derby.iapi.types.TypeId;
 import org.apache.derby.iapi.types.DataTypeDescriptor;
+import org.apache.derby.iapi.types.SqlXmlUtil;
 
 import java.lang.reflect.Modifier;
+import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
 
 import org.apache.derby.iapi.util.JBitSet;
 import org.apache.derby.iapi.services.classfile.VMOpcode;
@@ -52,7 +59,7 @@ import java.util.Vector;
  *
  */
 
-public class UnaryOperatorNode extends OperatorNode
+public class UnaryOperatorNode extends ValueNode
 {
 	String	operator;
 	String	methodName;
@@ -114,6 +121,10 @@ public class UnaryOperatorNode extends O
 	// args required by the operator method call.
 	private Object [] additionalArgs;
 
+	// Class used to hold XML-specific objects required for
+	// parsing/serializing XML data.
+	private SqlXmlUtil sqlxUtil;
+
 	/**
 	 * Initializer for a UnaryOperatorNode.
 	 *
@@ -372,6 +383,12 @@ public class UnaryOperatorNode extends O
             }
         }
 
+        // Create a new XML compiler object; the constructor
+        // here automatically creates the XML-specific objects 
+        // required for parsing/serializing XML, so all we
+        // have to do is create an instance.
+        sqlxUtil = new SqlXmlUtil();
+
         // The result type of XMLParse() is always an XML type.
         setType(DataTypeDescriptor.getBuiltInDataTypeDescriptor(
                 JDBC40Translation.SQLXML));
@@ -607,6 +624,26 @@ public class UnaryOperatorNode extends O
 											MethodBuilder mb)
 									throws StandardException
 	{
+		// For XML operator we do some extra work.
+		boolean xmlGen = (operatorType == XMLPARSE_OP) ||
+			(operatorType == XMLSERIALIZE_OP);
+
+		if (xmlGen) {
+		// We create an execution-time object from which we call
+		// the necessary methods.  We do this for two reasons: 1) this
+		// level of indirection allows us to separate the XML data type
+		// from the required XML implementation classes (esp. JAXP and
+		// Xalan classes)--for more on how this works, see the comments
+		// in SqlXmlUtil.java; and 2) this allows us to create the
+		// required XML objects a single time (which we did at bind time
+		// when we created a new SqlXmlUtil) and then reuse those objects
+		// for each row in the target result set, instead of creating
+		// new objects every time; see SqlXmlUtil.java for more.
+			mb.pushNewStart(
+				"org.apache.derby.impl.sql.execute.SqlXmlExecutor");
+			mb.pushNewComplete(addXmlOpMethodParams(acb, mb));
+		}
+
 		String resultTypeName = 
 			(operatorType == -1)
 				? getTypeCompiler().interfaceName()
@@ -627,13 +664,25 @@ public class UnaryOperatorNode extends O
 			LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, resultTypeName);
 			mb.getField(field);
 
-            int numArgs = 1;
-
-            // XML operators take extra arguments.
-            numArgs += addXmlOpMethodParams(acb, mb, field);
-
-            mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
-                          methodName, resultTypeName, numArgs);
+			/* If we're calling a method on a class (SqlXmlExecutor) instead
+			 * of calling a method on the operand interface, then we invoke
+			 * VIRTUAL; we then have 2 args (the operand and the local field)
+			 * instead of one, i.e:
+			 *
+			 *  SqlXmlExecutor.method(operand, field)
+			 *
+			 * instead of
+			 *
+			 *  <operand>.method(field).
+			 */
+			if (xmlGen) {
+				mb.callMethod(VMOpcode.INVOKEVIRTUAL, null,
+					methodName, resultTypeName, 2);
+			}
+			else {
+				mb.callMethod(VMOpcode.INVOKEINTERFACE,
+					(String) null, methodName, resultTypeName, 1);
+			}
 
 			/*
 			** Store the result of the method call in the field, so we can re-use
@@ -714,14 +763,11 @@ public class UnaryOperatorNode extends O
     /**
      * Add some additional arguments to our method call for
      * XML related operations like XMLPARSE and XMLSERIALIZE.
-     *
-     * @param acb the builder for the class in which the method lives
      * @param mb The MethodBuilder that will make the call.
-     * @param resultField the field that contains the previous result
      * @return Number of parameters added.
      */
     protected int addXmlOpMethodParams(ExpressionClassBuilder acb,
-		MethodBuilder mb, LocalField resultField) throws StandardException
+		MethodBuilder mb) throws StandardException
     {
         if ((operatorType != XMLPARSE_OP) && (operatorType != XMLSERIALIZE_OP))
         // nothing to do.
@@ -752,26 +798,20 @@ public class UnaryOperatorNode extends O
 
         /* Else we're here for XMLPARSE. */
 
-        // XMLPARSE is different from other unary operators in that the method
-        // must be called on the result object (the XML value) and not on the
-        // operand (the string value). We must therefore make sure the result
-        // object is not null.
-        MethodBuilder constructor = acb.getConstructor();
-        acb.generateNull(constructor, getTypeCompiler(),
-                         getTypeServices().getCollationType());
-        constructor.setField(resultField);
-
-        // Swap operand and result object so that the method will be called
-        // on the result object.
-        mb.swap();
+        // Push activation, which we use at execution time to
+        // get our saved object (which will hold objects used
+        // for parsing/serializing) back.
+        acb.pushThisAsActivation(mb);
+
+        // Push our XML object (used for parsing/serializing) as
+        // a saved object, so that we can retrieve it at execution
+        // time.  This allows us to avoid having to re-create the
+        // objects for every row in a given result set.
+        mb.push(getCompilerContext().addSavedObject(sqlxUtil));
 
         // Push whether or not we want to preserve whitespace.
         mb.push(((Boolean)additionalArgs[0]).booleanValue());
-
-        // Push the SqlXmlUtil instance as the next argument.
-        pushSqlXmlUtil(acb, mb, null, null);
-
-        return 2;
+        return 3;
     }
     
     /**

Modified: db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/suites/XMLSuite.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/suites/XMLSuite.java?rev=1131002&r1=1131001&r2=1131002&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/suites/XMLSuite.java
(original)
+++ db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/suites/XMLSuite.java
Fri Jun  3 11:49:40 2011
@@ -50,7 +50,6 @@ public final class XMLSuite extends Base
         suite.addTest(org.apache.derbyTesting.functionTests.tests.lang.XMLTypeAndOpsTest.suite());
         suite.addTest(org.apache.derbyTesting.functionTests.tests.lang.XMLBindingTest.suite());
         suite.addTest(org.apache.derbyTesting.functionTests.tests.lang.XMLMissingClassesTest.suite());
-        suite.addTest(org.apache.derbyTesting.functionTests.tests.lang.XMLConcurrencyTest.suite());
         
         return suite;
     }

Modified: db/derby/code/branches/10.8/tools/jar/extraDBMSclasses.properties
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/tools/jar/extraDBMSclasses.properties?rev=1131002&r1=1131001&r2=1131002&view=diff
==============================================================================
--- db/derby/code/branches/10.8/tools/jar/extraDBMSclasses.properties (original)
+++ db/derby/code/branches/10.8/tools/jar/extraDBMSclasses.properties Fri Jun  3 11:49:40
2011
@@ -99,5 +99,7 @@ derby.module.store.jardbf=org.apache.der
 derby.module.store.urlf=org.apache.derby.impl.io.URLFile
 derby.module.store.cpf=org.apache.derby.impl.io.CPFile
 
+derby.module.xml.sqlxmle=org.apache.derby.impl.sql.execute.SqlXmlExecutor
+
 derby.module.shared.threaddump=org.apache.derby.shared.common.sanity.ThreadDump
 derby.module.engine.threaddump=org.apache.derby.iapi.error.ThreadDump



Mime
View raw message