You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2011/06/03 13:00:49 UTC
svn commit: r1130983 - 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...
Author: kahatlen
Date: Fri Jun 3 11:00:48 2011
New Revision: 1130983
URL: http://svn.apache.org/viewvc?rev=1130983&view=rev
Log:
DERBY-3870: Concurrent Inserts of rows with XML data results in an exception
Merged from trunk (revisions 1101839, 1125305, 1126358 and 1127883).
Added:
db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/OperatorNode.java
- copied, changed from r1125305, db/derby/code/trunk/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
- copied unchanged from r1101839, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/XMLConcurrencyTest.java
Removed:
db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/execute/SqlXmlExecutor.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:00:48 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,1102826,1103681,1103718,1127825,1129136,1129764,1129797
+/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
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=1130983&r1=1130982&r2=1130983&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:00:48 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 */ "org.apache.derby.iapi.types.SqlXmlUtil",
+ /* 464 */ null,
/* 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=1130983&r1=1130982&r2=1130983&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:00:48 2011
@@ -506,12 +506,6 @@ 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=1130983&r1=1130982&r2=1130983&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:00:48 2011
@@ -23,8 +23,6 @@ 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;
@@ -33,8 +31,6 @@ 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;
@@ -84,10 +80,8 @@ 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 (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.
+ * compile time and then passed to the appropriate operator
+ * implementation method in XML.java.
*
* 2. By keeping all XML-specific references in this one class,
* we have a single "point of entry" to the XML objects--namely,
@@ -113,7 +107,7 @@ import javax.xml.transform.stream.Stream
* _if_ s/he is trying to access or operate on XML values.
*/
-public class SqlXmlUtil implements Formatable
+public class SqlXmlUtil
{
// Used to parse a string into an XML value (DOM); checks
// the well-formedness of the string while parsing.
@@ -803,58 +797,6 @@ public class SqlXmlUtil implements Forma
}
}
- /* ****
- * 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=1130983&r1=1130982&r2=1130983&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:00:48 2011
@@ -598,7 +598,7 @@ public class XML
* store the _serialized_ version locally and then return
* this XMLDataValue.
*
- * @param text The string value to check.
+ * @param stringValue The string value to check.
* @param preserveWS Whether or not to preserve
* ignorable whitespace.
* @param sqlxUtil Contains SQL/XML objects and util
@@ -609,9 +609,18 @@ public class XML
* value is returned; otherwise, an exception is thrown.
* @exception StandardException Thrown on error.
*/
- public XMLDataValue XMLParse(String text, boolean preserveWS,
- SqlXmlUtil sqlxUtil) throws StandardException
+ public XMLDataValue XMLParse(
+ StringDataValue stringValue,
+ boolean preserveWS,
+ SqlXmlUtil sqlxUtil)
+ throws StandardException
{
+ if (stringValue.isNull()) {
+ setToNull();
+ return this;
+ }
+
+ String text = stringValue.getString();
try {
if (preserveWS) {
@@ -834,10 +843,10 @@ public class XML
* the received XMLDataValue "result" param (assuming "result" is
* non-null; else create a new XMLDataValue).
*
- * @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
+ * @param result The result of a previous call to this method; null
+ * if not called yet.
* @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
@@ -845,8 +854,8 @@ public class XML
* @exception Exception thrown on error (and turned into a
* StandardException by the caller).
*/
- public XMLDataValue XMLQuery(XMLDataValue result,
- SqlXmlUtil sqlxUtil) throws StandardException
+ public XMLDataValue XMLQuery(SqlXmlUtil sqlxUtil, XMLDataValue result)
+ 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=1130983&r1=1130982&r2=1130983&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:00:48 2011
@@ -30,7 +30,7 @@ public interface XMLDataValue extends Da
* store the _serialized_ version locally and then return
* this XMLDataValue.
*
- * @param text The string value to check.
+ * @param stringValue The string value to check.
* @param preserveWS Whether or not to preserve
* ignorable whitespace.
* @param sqlxUtil Contains SQL/XML objects and util
@@ -41,8 +41,11 @@ public interface XMLDataValue extends Da
* value returned; otherwise, an exception is thrown.
* @exception StandardException Thrown on error.
*/
- public XMLDataValue XMLParse(String text, boolean preserveWS,
- SqlXmlUtil sqlxUtil) throws StandardException;
+ public XMLDataValue XMLParse(
+ StringDataValue stringValue,
+ boolean preserveWS,
+ SqlXmlUtil sqlxUtil)
+ throws StandardException;
/**
* The SQL/XML XMLSerialize operator.
@@ -90,10 +93,10 @@ public interface XMLDataValue extends Da
* the received XMLDataValue "result" param (assuming "result" is
* non-null; else create a new XMLDataValue).
*
- * @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
+ * @param result The result of a previous call to this method; null
+ * if not called yet.
* @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
@@ -101,7 +104,7 @@ public interface XMLDataValue extends Da
* @exception Exception thrown on error (and turned into a
* StandardException by the caller).
*/
- public XMLDataValue XMLQuery(XMLDataValue result, SqlXmlUtil sqlxUtil)
+ public XMLDataValue XMLQuery(SqlXmlUtil sqlxUtil, XMLDataValue result)
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=1130983&r1=1130982&r2=1130983&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:00:48 2011
@@ -21,25 +21,16 @@
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;
@@ -48,7 +39,6 @@ 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;
/**
@@ -59,7 +49,7 @@ import java.util.Vector;
*
*/
-public class BinaryOperatorNode extends ValueNode
+public class BinaryOperatorNode extends OperatorNode
{
String operator;
String methodName;
@@ -125,9 +115,8 @@ public class BinaryOperatorNode extends
{ClassName.StringDataValue, ClassName.XMLDataValue} // XMLQuery
};
- // Class used to compile an XML query expression and/or load/process
- // XML-specific objects.
- private SqlXmlUtil sqlxUtil;
+ /** The query expression if the operator is XMLEXISTS or XMLQUERY. */
+ private String xmlQuery;
/**
* Initializer for a BinaryOperatorNode
@@ -352,11 +341,7 @@ public class BinaryOperatorNode extends
SQLState.LANG_INVALID_XML_QUERY_EXPRESSION);
}
else {
- // compile the query expression.
- sqlxUtil = new SqlXmlUtil();
- sqlxUtil.compileXQExpr(
- ((CharConstantNode)leftOperand).getString(),
- (operatorType == XMLEXISTS_OP ? "XMLEXISTS" : "XMLQUERY"));
+ xmlQuery = ((CharConstantNode)leftOperand).getString();
}
// Right operand must be an XML data value. NOTE: This
@@ -498,29 +483,15 @@ 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.
@@ -558,6 +529,9 @@ 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
{
@@ -581,28 +555,33 @@ public class BinaryOperatorNode extends
** UNLESS we're generating an XML operator such as XMLEXISTS.
** In that case we want to generate
**
- ** SqlXmlExecutor.method(left, right)"
- **
- ** and we've already pushed the SqlXmlExecutor object to
- ** the stack.
+ ** <right expression>.method(sqlXmlUtil)
*/
rightOperand.generateExpression(acb, mb);
mb.cast(receiverType); // cast the method instance
// stack: right
- if (!xmlGen) {
+ 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;
+
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 */
@@ -610,15 +589,13 @@ public class BinaryOperatorNode extends
? getTypeCompiler().interfaceName()
: resultInterfaceType;
- // 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);
+ // 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);
+ // Push the result field onto the stack, if there is a result field.
+ if (resultField != null) {
/*
** Call the method for this operator.
*/
@@ -627,6 +604,9 @@ 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
*/
@@ -637,17 +617,15 @@ public class BinaryOperatorNode extends
operator.equals("/"))
{
mb.push(getTypeServices().getScale()); // 4th arg
- mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType, methodName, resultTypeName, 4);
- }
- 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);
+ numArgs++;
}
- else
- mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType, methodName, resultTypeName, 3);
+ }
+
+ mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType,
+ methodName, resultTypeName, numArgs);
+ // 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.
{
@@ -670,17 +648,6 @@ 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);
- }
}
}
@@ -875,32 +842,4 @@ 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;
- }
}
Copied: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/OperatorNode.java (from r1125305, db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OperatorNode.java)
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/OperatorNode.java?p2=db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/OperatorNode.java&p1=db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OperatorNode.java&r1=1125305&r2=1130983&rev=1130983&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OperatorNode.java (original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/compile/OperatorNode.java Fri Jun 3 11:00:48 2011
@@ -36,9 +36,8 @@ abstract class OperatorNode extends Valu
/**
* <p>
* Generate code that pushes an SqlXmlUtil instance onto the stack. The
- * instance will be created and cached in the activation the first time
- * the code is executed, so that we don't need to create a new instance
- * for every row.
+ * instance will be created and cached in the activation's constructor, so
+ * that we don't need to create a new instance for every row.
* </p>
*
* <p>
@@ -59,37 +58,31 @@ abstract class OperatorNode extends Valu
// Create a field in which the instance can be cached.
LocalField sqlXmlUtil = acb.newFieldDeclaration(
- Modifier.PRIVATE, SqlXmlUtil.class.getName());
+ Modifier.PRIVATE | Modifier.FINAL, SqlXmlUtil.class.getName());
- // Read the cached value.
- mb.getField(sqlXmlUtil);
-
- // Check if the cached value is null. If it is, create a new instance.
- // Otherwise, we're happy with the stack as it is (the cached instance
- // will be on top of it), and nothing more is needed.
- mb.dup();
- mb.conditionalIfNull();
-
- // The cached value is null. Pop it from the stack so that we can put
- // a fresh instance there in its place.
- mb.pop();
-
- // Create a new instance and cache it in the field. Its value will be
- // on the top of the stack after this sequence.
- mb.pushNewStart(SqlXmlUtil.class.getName());
- mb.pushNewComplete(0);
- mb.putField(sqlXmlUtil);
-
- // If a query is specified, compile it.
- if (xmlQuery != null) {
- mb.dup();
- mb.push(xmlQuery);
- mb.push(xmlOpName);
- mb.callMethod(
+ // Add code that creates the SqlXmlUtil instance in the constructor.
+ MethodBuilder constructor = acb.getConstructor();
+ constructor.pushNewStart(SqlXmlUtil.class.getName());
+ constructor.pushNewComplete(0);
+ constructor.putField(sqlXmlUtil);
+
+ // Compile the query, if one is specified.
+ if (xmlQuery == null) {
+ // No query. The SqlXmlUtil instance is still on the stack. Pop it
+ // to restore the initial state of the stack.
+ constructor.pop();
+ } else {
+ // Compile the query. This will consume the SqlXmlUtil instance
+ // and leave the stack in its initial state.
+ constructor.push(xmlQuery);
+ constructor.push(xmlOpName);
+ constructor.callMethod(
VMOpcode.INVOKEVIRTUAL, SqlXmlUtil.class.getName(),
"compileXQExpr", "void", 2);
}
- mb.completeConditional();
+ // Read the cached value and push it onto the stack in the method
+ // generated for the operator.
+ mb.getField(sqlXmlUtil);
}
}
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=1130983&r1=1130982&r2=1130983&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:00:48 2011
@@ -54,7 +54,7 @@ import java.util.Vector;
*
*/
-public class TernaryOperatorNode extends ValueNode
+public class TernaryOperatorNode extends OperatorNode
{
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=1130983&r1=1130982&r2=1130983&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:00:48 2011
@@ -23,11 +23,8 @@ 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;
@@ -35,15 +32,11 @@ 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;
@@ -59,7 +52,7 @@ import java.util.Vector;
*
*/
-public class UnaryOperatorNode extends ValueNode
+public class UnaryOperatorNode extends OperatorNode
{
String operator;
String methodName;
@@ -121,10 +114,6 @@ public class UnaryOperatorNode extends V
// 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.
*
@@ -383,12 +372,6 @@ public class UnaryOperatorNode extends V
}
}
- // 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));
@@ -624,26 +607,6 @@ public class UnaryOperatorNode extends V
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()
@@ -664,25 +627,13 @@ public class UnaryOperatorNode extends V
LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, resultTypeName);
mb.getField(field);
- /* 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);
- }
+ int numArgs = 1;
+
+ // XML operators take extra arguments.
+ numArgs += addXmlOpMethodParams(acb, mb, field);
+
+ mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
+ methodName, resultTypeName, numArgs);
/*
** Store the result of the method call in the field, so we can re-use
@@ -763,11 +714,14 @@ public class UnaryOperatorNode extends V
/**
* 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) throws StandardException
+ MethodBuilder mb, LocalField resultField) throws StandardException
{
if ((operatorType != XMLPARSE_OP) && (operatorType != XMLSERIALIZE_OP))
// nothing to do.
@@ -798,20 +752,26 @@ public class UnaryOperatorNode extends V
/* Else we're here for XMLPARSE. */
- // 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));
+ // 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 whether or not we want to preserve whitespace.
mb.push(((Boolean)additionalArgs[0]).booleanValue());
- return 3;
+
+ // Push the SqlXmlUtil instance as the next argument.
+ pushSqlXmlUtil(acb, mb, null, null);
+
+ return 2;
}
/**
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=1130983&r1=1130982&r2=1130983&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:00:48 2011
@@ -50,6 +50,7 @@ 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=1130983&r1=1130982&r2=1130983&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:00:48 2011
@@ -99,7 +99,5 @@ 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