db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From banda...@apache.org
Subject svn commit: r189721 [2/5] - in /incubator/derby/code/trunk: java/engine/org/apache/derby/catalog/types/ java/engine/org/apache/derby/iapi/ java/engine/org/apache/derby/iapi/reference/ java/engine/org/apache/derby/iapi/services/io/ java/engine/org/apache/derby/iapi/sql/compile/ java/engine/org/apache/derby/iapi/types/ java/engine/org/apache/derby/impl/jdbc/ java/engine/org/apache/derby/impl/sql/compile/ java/engine/org/apache/derby/loc/ java/testing/org/apache/derbyTesting/functionTests/master/ java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/ java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/ java/testing/org/apache/derbyTesting/functionTests/tests/lang/ java/testing/org/apache/derbyTesting/functionTests/tests/lang/xmlTestFiles/ tools/jar/
Date Thu, 09 Jun 2005 06:48:36 GMT
Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ParameterNode.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ParameterNode.java?rev=189721&r1=189720&r2=189721&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ParameterNode.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ParameterNode.java Wed Jun  8 23:48:34 2005
@@ -41,6 +41,7 @@
 import org.apache.derby.iapi.sql.ParameterValueSet;
 import org.apache.derby.iapi.sql.Activation;
 import org.apache.derby.iapi.reference.ClassName;
+import org.apache.derby.iapi.reference.SQLState;
 
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 
@@ -379,6 +380,18 @@
 											MethodBuilder mb)
 									throws StandardException
 	{
+		DataTypeDescriptor dtd = getTypeServices();
+		if ((dtd != null) && dtd.getTypeId().isXMLTypeId()) {
+		// We're a parameter that corresponds to an XML column/target,
+		// which we don't allow.  We throw the error here instead of
+		// in "bindExpression" because at the time of bindExpression,
+		// we don't know yet what the type is going to be (only when
+		// the node that points to this parameter calls
+		// "setDescriptor" do we figure out the type).
+			throw StandardException.newException(
+				SQLState.LANG_ATTEMPT_TO_BIND_XML);
+		}
+
 		// PUSHCOMPILE
 		/* Reuse code if possible */
 		//if (genRetval != null)
@@ -402,7 +415,6 @@
 		// For some types perform host variable checking
 		// to match DB2/JCC where if a host variable is too
 		// big it is not accepted, regardless of any trailing padding.
-		DataTypeDescriptor dtd = getTypeServices();
 
 		switch (dtd.getJDBCTypeId()) {
 		case Types.BINARY:

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java?rev=189721&r1=189720&r2=189721&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java Wed Jun  8 23:48:34 2005
@@ -33,6 +33,7 @@
 import org.apache.derby.iapi.services.compiler.MethodBuilder;
 import org.apache.derby.iapi.services.monitor.Monitor;
 import org.apache.derby.iapi.services.sanity.SanityManager;
+import org.apache.derby.iapi.services.io.StoredFormatIds;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.sql.compile.CompilerContext;
 import org.apache.derby.iapi.sql.compile.NodeFactory;
@@ -976,6 +977,13 @@
 		  case Types.BLOB:
 			constantNode = nf.getNode(
 										C_NodeTypes.BLOB_CONSTANT_NODE,
+										typeId,
+										cm);
+			break;
+
+		  case StoredFormatIds.XML_TYPE_ID:
+			constantNode = nf.getNode(
+										C_NodeTypes.XML_CONSTANT_NODE,
 										typeId,
 										cm);
 			break;

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ReadCursorNode.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ReadCursorNode.java?rev=189721&r1=189720&r2=189721&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ReadCursorNode.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ReadCursorNode.java Wed Jun  8 23:48:34 2005
@@ -81,6 +81,10 @@
 		// types for this node
 		resultSet.bindUntypedNullsToResultColumns(null);
 
+		// Reject any XML values in the select list; JDBC doesn't
+		// define how we bind these out, so we don't allow it.
+		resultSet.rejectXMLValues();
+
 		/* Verify that all underlying ResultSets reclaimed their FromList */
 		if (SanityManager.DEBUG)
 		{

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java?rev=189721&r1=189720&r2=189721&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java Wed Jun  8 23:48:34 2005
@@ -120,6 +120,10 @@
 	// Is a count mismatch allowed - see set/get methods for details.
 	private boolean countMismatchAllowed;
 
+	// Number of RCs in this RCL at "init" time, before additional
+	// ones were added internally.
+	private int initialListSize = 0;
+
 	public ResultColumnList()
 	{
 	}
@@ -1472,6 +1476,11 @@
 				{
 					insertElementAt(allExpansion.elementAt(inner), index + inner);
 				}
+
+				// If the rc was a "*", we need to set the initial list size
+				// to the number of columns that are actually returned to
+				// the user.
+				markInitialSize();
 			}
 			else
 			{
@@ -1953,6 +1962,71 @@
 	}
 
 	/**
+	 * Check for (and reject) XML values directly under the ResultColumns.
+	 * This is done for SELECT/VALUES statements.  We reject values
+	 * in this case because JDBC does not define an XML type/binding
+	 * and thus there's no standard way to pass such a type back
+	 * to a JDBC application.
+	 *
+	 * Note that we DO allow an XML column in a top-level RCL
+	 * IF that column was added to the RCL by _us_ instead of
+	 * by the user.  For example, if we have a table:
+	 *
+	 * create table t1 (i int, x xml)
+	 *
+	 * and the user query is:
+	 *
+	 * select i from t1 order by x
+	 *
+	 * the "x" column will be added (internally) to the RCL
+	 * as part of ORDER BY processing--and so we need to
+	 * allow that XML column to be bound without throwing
+	 * an error.  If, as in this case, the XML column reference
+	 * is invalid (we can't use ORDER BY on an XML column because
+	 * XML values aren't ordered), a more appropriate error
+	 * message should be returned to the user in later processing.
+	 * If we didn't allow for this, the user would get an
+	 * error saying that XML columns are not valid as part
+	 * of the result set--but as far as s/he knows, there
+	 * isn't such a column: only "i" is supposed to be returned
+	 * (the RC for "x" was added to the RCL by _us_ as part of
+	 * ORDER BY processing).
+	 *
+	 * ASSUMPTION: Any RCs that are generated internally and
+	 * added to this RCL (before this RCL is bound) are added
+	 * at the _end_ of the list.  If that's true, then any
+	 * RC with an index greater than the size of the initial
+	 * (user-specified) list must have been added internally
+	 * and will not be returned to the user.
+	 *
+	 * @return	Nothing
+	 *
+	 * @exception StandardException		Thrown if an XML value found
+	 *									directly under a ResultColumn
+	 */
+	void rejectXMLValues() throws StandardException
+	{
+		int sz = size();
+		ResultColumn rc = null;
+		for (int i = 1; i <= sz; i++) {
+
+			if (i > initialListSize)
+			// this RC was generated internally and will not
+			// be returned to the user, so don't throw error.
+				continue;
+
+			rc = getResultColumn(i);
+			if ((rc != null) && (rc.getType() != null) &&
+				rc.getType().getTypeId().isXMLTypeId())
+			{ // Disallow it.
+				throw StandardException.newException(
+					SQLState.LANG_ATTEMPT_TO_SELECT_XML);
+			}
+
+		}
+	}
+
+	/**
 	 * Set the resultSetNumber in all of the ResultColumns.
 	 *
 	 * @param resultSetNumber	The resultSetNumber
@@ -3947,4 +4021,15 @@
     {
         orderBySelect = src.orderBySelect;
     }
+
+	/* ****
+	 * Take note of the size of this RCL _before_ we start
+	 * processing/binding it.  This is so that, at bind time,
+	 * we can tell if any columns in the RCL were added
+	 * internally by us (i.e. they were not specified by the
+	 * user and thus will not be returned to the user).
+	 */
+	protected void markInitialSize() {
+		initialListSize = size();
+	}
 }

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultSetNode.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultSetNode.java?rev=189721&r1=189720&r2=189721&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultSetNode.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultSetNode.java Wed Jun  8 23:48:34 2005
@@ -991,6 +991,26 @@
 	}
 
 	/**
+	 * Check for (and reject) XML values directly under the ResultColumns.
+	 * This is done for SELECT/VALUES statements.  We reject values
+	 * in this case because JDBC does not define an XML type/binding
+	 * and thus there's no standard way to pass such a type back
+	 * to a JDBC application.
+	 *
+	 * @return	Nothing
+	 *
+	 * @exception StandardException		Thrown if an XML value found
+	 *									directly under a ResultColumn
+	 */
+	public void rejectXMLValues() throws StandardException
+	{
+		if (resultColumns != null)
+		{
+			resultColumns.rejectXMLValues();
+		}
+	}
+
+	/**
 	 * Rename generated result column names as '1', '2' etc... These will be the result
 	 * column names seen by JDBC clients.
 	 */

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/RowResultSetNode.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/RowResultSetNode.java?rev=189721&r1=189720&r2=189721&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/RowResultSetNode.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/RowResultSetNode.java Wed Jun  8 23:48:34 2005
@@ -80,6 +80,8 @@
 	{
 		super.init(null, tableProperties);
 		resultColumns = (ResultColumnList) valuesClause;
+		if (resultColumns != null)
+			resultColumns.markInitialSize();
 	}
 
 	/**

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java?rev=189721&r1=189720&r2=189721&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java Wed Jun  8 23:48:34 2005
@@ -132,6 +132,8 @@
 		 * Consider adding selectAggregates and whereAggregates 
 		 */
 		resultColumns = (ResultColumnList) selectList;
+		if (resultColumns != null)
+			resultColumns.markInitialSize();
 		this.fromList = (FromList) fromList;
 		this.whereClause = (ValueNode) whereClause;
 		this.originalWhereClause = (ValueNode) whereClause;

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TypeCompilerFactoryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TypeCompilerFactoryImpl.java?rev=189721&r1=189720&r2=189721&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TypeCompilerFactoryImpl.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TypeCompilerFactoryImpl.java Wed Jun  8 23:48:34 2005
@@ -29,6 +29,7 @@
 import org.apache.derby.iapi.reference.JDBC20Translation;
 import org.apache.derby.iapi.reference.JDBC30Translation;
 
+import org.apache.derby.iapi.services.io.StoredFormatIds;
 import java.util.Properties;
 
 import java.sql.Types;
@@ -65,6 +66,7 @@
         static TypeCompiler blobTypeCompiler ;
         static TypeCompiler clobTypeCompiler ;
         static TypeCompiler nclobTypeCompiler ;
+        static TypeCompiler xmlTypeCompiler ;
 
         /**
          * Get a TypeCompiler corresponding to the given TypeId
@@ -256,6 +258,13 @@
                                 btc.setTypeId(typeId);
                                 return btc;
                         }
+
+                  case StoredFormatIds.XML_TYPE_ID:
+                        return xmlTypeCompiler =
+                                getAnInstance(PACKAGE_NAME + "XMLTypeCompiler",
+                                                                xmlTypeCompiler,
+                                                                typeId);
+
                 }
 
                 if (SanityManager.DEBUG)

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnaryOperatorNode.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnaryOperatorNode.java?rev=189721&r1=189720&r2=189721&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnaryOperatorNode.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnaryOperatorNode.java Wed Jun  8 23:48:34 2005
@@ -28,10 +28,15 @@
 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
 
 import org.apache.derby.iapi.reference.SQLState;
+import org.apache.derby.iapi.reference.ClassName;
 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 org.apache.derby.iapi.types.TypeId;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
 
 import java.lang.reflect.Modifier;
 import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
@@ -39,6 +44,7 @@
 import org.apache.derby.iapi.util.JBitSet;
 import org.apache.derby.iapi.services.classfile.VMOpcode;
 
+import java.sql.Types;
 import java.util.Vector;
 
 /**
@@ -50,10 +56,14 @@
  * @author Jeff Lichtman
  */
 
-public abstract class UnaryOperatorNode extends ValueNode
+public class UnaryOperatorNode extends ValueNode
 {
 	String	operator;
 	String	methodName;
+	int operatorType;
+
+	String		resultInterfaceType;
+	String		receiverInterfaceType;
 
 	/**
 	 * WARNING: operand may be NULL for COUNT(*).  
@@ -65,22 +75,87 @@
 	public final static int NOT		= 3;
 	public final static int IS_NULL		= 4;
 
+	// At the time of adding XML support, it was decided that
+	// we should avoid creating new OperatorNodes where possible.
+	// So for the XML-related unary operators we just add the
+	// necessary code to _this_ class, similar to what is done in
+	// TernarnyOperatorNode. Subsequent unary operators (whether
+	// XML-related or not) should follow this example when
+	// possible.
+
+	public final static int XMLPARSE_OP = 0;
+	public final static int XMLSERIALIZE_OP = 1;
+
+	// NOTE: in the following 4 arrays, order
+	// IS important.
+
+	static final String[] UnaryOperators = {
+		"xmlparse",
+		"xmlserialize"
+	};
+
+	static final String[] UnaryMethodNames = {
+		"XMLParse",
+		"XMLSerialize"
+	};
+
+	static final String[] UnaryResultTypes = {
+		ClassName.XMLDataValue, 		// XMLParse
+		ClassName.StringDataValue		// XMLSerialize
+	};
+
+	static final String[] UnaryArgTypes = {
+		ClassName.StringDataValue,		// XMLParse
+		ClassName.XMLDataValue			// XMLSerialize
+	};
+
+	// Array to hold Objects that contain primitive
+	// args required by the operator method call.
+	private Object [] additionalArgs;
+
 	/**
 	 * Initializer for a UnaryOperatorNode
 	 *
 	 * @param operand	The operand of the node
-	 * @param operator	The name of the operator
-	 * @param methodName	The name of the method to call for this operator
+	 * @param operatorOrOpType	Either 1) the name of the operator,
+	 *  OR 2) an Integer holding the operatorType for this operator.
+	 * @param methodNameOrParams	Either 1) name of the method
+	 *  to call for this operator, or 2) an array of Objects
+	 *  from which primitive method parameters can be
+	 *  retrieved.
 	 */
 
 	public void init(
 					Object	operand,
-					Object		operator,
-					Object		methodName)
+					Object		operatorOrOpType,
+					Object		methodNameOrAddedArgs)
 	{
 		this.operand = (ValueNode) operand;
-		this.operator = (String) operator;
-		this.methodName = (String) methodName;
+		if (operatorOrOpType instanceof String) {
+		// then 2nd and 3rd params are operator and methodName,
+		// respectively.
+			this.operator = (String) operatorOrOpType;
+			this.methodName = (String) methodNameOrAddedArgs;
+			this.operatorType = -1;
+		}
+		else {
+		// 2nd and 3rd params are operatorType and additional args,
+		// respectively.
+			if (SanityManager.DEBUG) {
+				SanityManager.ASSERT(
+					((operatorOrOpType instanceof Integer) &&
+						((methodNameOrAddedArgs == null) ||
+						(methodNameOrAddedArgs instanceof Object[]))),
+					"Init params in UnaryOperator node have the " +
+					"wrong type.");
+			}
+			this.operatorType = ((Integer) operatorOrOpType).intValue();
+			this.operator = UnaryOperators[this.operatorType];
+			this.methodName = UnaryMethodNames[this.operatorType];
+			this.resultInterfaceType = UnaryResultTypes[this.operatorType];
+			this.receiverInterfaceType = UnaryArgTypes[this.operatorType];
+			this.additionalArgs = (Object[])methodNameOrAddedArgs;
+		}
 	}
 
 	/**
@@ -91,6 +166,7 @@
 	public void init(Object	operand)
 	{
 		this.operand = (ValueNode) operand;
+		this.operatorType = -1;
 	}
 
 	/**
@@ -103,6 +179,7 @@
 	void setOperator(String operator)
 	{
 		this.operator = operator;
+		this.operatorType = -1;
 	}
 
 	/**
@@ -125,6 +202,7 @@
 	void setMethodName(String methodName)
 	{
 		this.methodName = methodName;
+		this.operatorType = -1;
 	}
 
 	/**
@@ -257,9 +335,103 @@
 			operand = operand.genSQLJavaSQLTree();
 		}
 
+		if (operatorType == XMLPARSE_OP)
+			bindXMLParse();
+		else if (operatorType == XMLSERIALIZE_OP)
+			bindXMLSerialize();
+
 		return this;
 	}
 
+    /**
+     * Bind an XMLPARSE operator.  Makes sure the operand type
+     * is correct, and sets the result type.
+     *
+     * @exception StandardException Thrown on error
+     */
+    public void bindXMLParse() throws StandardException
+    {
+        // Check the type of the operand - this function is allowed only on
+        // string value (char) types.
+        TypeId operandType = operand.getTypeId();
+        if (operandType != null) {
+            switch (operandType.getJDBCTypeId())
+            {
+                case Types.CHAR:
+                case Types.VARCHAR:
+                case Types.LONGVARCHAR:
+                case Types.CLOB:
+                    break;
+                default:
+                {
+                    throw StandardException.newException(
+                        SQLState.LANG_UNARY_FUNCTION_BAD_TYPE, 
+                        methodName,
+                        operandType.getSQLTypeName());
+                }
+            }
+        }
+
+        // The result type of XMLParse() is always an XML type.
+        setType(DataTypeDescriptor.getBuiltInDataTypeDescriptor(
+            StoredFormatIds.XML_TYPE_ID));
+    }
+
+    /**
+     * Bind an XMLSERIALIZE operator.  Makes sure the operand type
+     * and target type are both correct, and sets the result type.
+     *
+     * @exception StandardException Thrown on error
+     */
+    public void bindXMLSerialize() throws StandardException
+    {
+        TypeId operandType;
+
+        // Check the type of the operand - this function is allowed only on
+        // the XML type.
+        operandType = operand.getTypeId();
+        if ((operandType != null) && !operandType.isXMLTypeId())
+        {
+            throw StandardException.newException(
+                SQLState.LANG_UNARY_FUNCTION_BAD_TYPE, 
+                methodName,
+                operandType.getSQLTypeName());
+        }
+
+        // Check the target type.  We only allow string types to be used as
+        // the target type.  The targetType is stored as the first Object
+        // in our list of additional parameters, so we have to retrieve
+        // it from there.
+        if (SanityManager.DEBUG) {
+            SanityManager.ASSERT(
+                ((additionalArgs != null) && (additionalArgs.length > 0)),
+                "Failed to locate target type for XMLSERIALIZE operator");
+        }
+
+        DataTypeDescriptor targetType =
+            (DataTypeDescriptor)additionalArgs[0];
+
+        TypeId targetTypeId = targetType.getTypeId();
+        switch (targetTypeId.getJDBCTypeId())
+        {
+            case Types.CHAR:
+            case Types.VARCHAR:
+            case Types.LONGVARCHAR:
+            case Types.CLOB:
+                break;
+            default:
+            {
+                throw StandardException.newException(
+                    SQLState.LANG_INVALID_XMLSERIALIZE_TYPE,
+                    targetTypeId.getSQLTypeName());
+            }
+        }
+
+        // The result type of XMLSerialize() is always a string; which
+        // kind of string is determined by the targetType field.
+        setType(targetType);
+    }
+
 	/**
 	 * Preprocess an expression tree.  We do a number of transformations
 	 * here (including subqueries, IN lists, LIKE and BETWEEN) plus
@@ -376,7 +548,22 @@
 
 	void bindParameter() throws StandardException
 	{
-		if (operand.getTypeServices() == null)
+		if (operatorType == XMLPARSE_OP) {
+        // According to the SQL/XML standard, the XMLParse parameter
+        // takes a string operand.  RESOLVE: We use CLOB here because
+        // an XML string can be arbitrarily long...is this okay?
+        // The SQL/XML spec doesn't state what the type of the param
+        // should be; only that it "shall be a character type".
+	        ((ParameterNode) operand).setDescriptor(
+ 	           DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.CLOB));
+		}
+		else if (operatorType == XMLSERIALIZE_OP) {
+        // For now, since JDBC has no type defined for XML, we
+        // don't allow binding to an XML parameter.
+	        throw StandardException.newException(
+ 	           SQLState.LANG_ATTEMPT_TO_BIND_XML);
+		}
+		else if (operand.getTypeServices() == null)
 		{
 			throw StandardException.newException(SQLState.LANG_UNARY_OPERAND_PARM, operator);
 		}
@@ -399,7 +586,11 @@
 		if (operand == null)
 			return;
 
-		String resultTypeName = getTypeCompiler().interfaceName();
+		String resultTypeName = 
+			(operatorType == -1)
+				? getTypeCompiler().interfaceName()
+				: resultInterfaceType;
+			
 		// System.out.println("resultTypeName " + resultTypeName + " method " + methodName);
 		// System.out.println("isBooleanTypeId() " + getTypeId().isBooleanTypeId());
 
@@ -414,7 +605,8 @@
 			/* Allocate an object for re-use to hold the result of the operator */
 			LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, resultTypeName);
 			mb.getField(field);
-			mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, methodName, resultTypeName, 1);
+			int numParams = 1 + addMethodParams(mb);
+			mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, methodName, resultTypeName, numParams);
 
 			/*
 			** Store the result of the method call in the field, so we can re-use
@@ -422,7 +614,8 @@
 			*/
 			mb.putField(field);
 		} else {
-			mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, methodName, resultTypeName, 0);
+			int numParams = addMethodParams(mb);
+			mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, methodName, resultTypeName, numParams);
 		}
 	}
 
@@ -442,6 +635,9 @@
 								"cannot get interface without operand");
 		}
 
+		if (operatorType != -1)
+			return receiverInterfaceType;
+		
 		return operand.getTypeCompiler().interfaceName();
 	}
 
@@ -495,4 +691,35 @@
 
 		return returnNode;
 	}
+
+    /**
+     * This method allows different operators to add
+     * primitive arguments to the generated method call,
+     * if needed.
+     * @param mb The MethodBuilder that will make the call.
+     * @return Number of parameters added.
+     */
+    protected int addMethodParams(MethodBuilder mb)
+    {
+        if (operatorType == XMLPARSE_OP) {
+        // We push whether or not we want to preserve whitespace.
+            mb.push(((Boolean)additionalArgs[0]).booleanValue());
+            return 1;
+        }
+
+        if (operatorType == XMLSERIALIZE_OP) {
+        // We push the target type's JDBC type id as well as
+        // the maximum width, since both are required when
+        // we actually perform the operation, and both are
+        // primitive types.
+            DataTypeDescriptor targetType =
+                (DataTypeDescriptor)additionalArgs[0];
+            mb.push(targetType.getJDBCTypeId());
+            mb.push(targetType.getMaximumWidth());
+            return 2;
+        }
+
+        // Default is to add zero params.
+        return 0;
+    }
 }

Added: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLConstantNode.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLConstantNode.java?rev=189721&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLConstantNode.java (added)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLConstantNode.java Wed Jun  8 23:48:34 2005
@@ -0,0 +1,99 @@
+/*
+
+   Derby - Class org.apache.derby.impl.sql.compile.XMLConstantNode
+
+   Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package    org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.services.compiler.MethodBuilder;
+import org.apache.derby.iapi.services.io.StoredFormatIds;
+import org.apache.derby.iapi.services.sanity.SanityManager;
+import org.apache.derby.iapi.types.TypeId;
+
+import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
+
+import org.apache.derby.iapi.util.ReuseFactory;
+
+public final class XMLConstantNode extends ConstantNode
+{
+    /**
+     * Initializer for an XMLConstantNode.
+     *
+     * @param arg1 The TypeId for the type of the node
+     *
+     * @exception StandardException
+     */
+    public void init(
+                    Object arg1)
+        throws StandardException
+    {
+        super.init(
+                    arg1,
+                    Boolean.TRUE,
+                    ReuseFactory.getInteger(0));
+    }
+
+    /**
+     * Return the value from this XMLConstantNode as a string.
+     *
+     * @return The value of this XMLConstantNode as a string.
+     *
+     * @exception StandardException Thrown on error
+     */
+    public String getString() throws StandardException
+    {
+        return value.getString();
+    }
+
+    /**
+     * Return an Object representing the bind time value of this
+     * expression tree.  If the expression tree does not evaluate to
+     * a constant at bind time then we return null.
+     *
+     * @return An Object representing the bind time value of this
+     *  expression tree (null if not a bind time constant).
+     *
+     * @exception StandardException        Thrown on error
+     */
+    Object getConstantValueAsObject() throws StandardException 
+    {
+        return value.getObject();
+    }
+
+    /**
+     * This generates the proper constant.  For an XML value,
+     * this constant value is simply the XML string (which is
+     * just null because null values are the only types of
+     * XML constants we can have).
+     *
+     * @param acb The ExpressionClassBuilder for the class being built
+     * @param mb The method the code to place the code
+     *
+     * @return The compiled Expression, 
+     *
+     * @exception StandardException        Thrown on error
+     */
+    void generateConstant(ExpressionClassBuilder acb, MethodBuilder mb)
+        throws StandardException
+    {
+        // The generated java is the expression:
+        // "#getString()"
+        mb.push(getString());
+    }
+}

Propchange: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLConstantNode.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLTypeCompiler.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLTypeCompiler.java?rev=189721&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLTypeCompiler.java (added)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLTypeCompiler.java Wed Jun  8 23:48:34 2005
@@ -0,0 +1,179 @@
+/*
+
+   Derby - Class org.apache.derby.impl.sql.compile.XMLTypeCompiler
+
+   Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.services.loader.ClassFactory;
+import org.apache.derby.iapi.services.sanity.SanityManager;
+import org.apache.derby.iapi.services.io.StoredFormatIds;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.types.TypeId;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+
+import org.apache.derby.iapi.reference.ClassName;
+
+/**
+ * This class implements TypeCompiler for the XML type.
+ */
+
+public class XMLTypeCompiler extends BaseTypeCompiler
+{
+    /**
+     * Tell whether this type (XML) can be compared to the given type.
+     * Says SQL/XML[2003] spec:
+     *
+     * 4.2.2 XML comparison and assignment
+     * "XML values are not comparable."
+     *
+     * @param otherType The TypeId of the other type.
+     */
+    public boolean comparable(TypeId otherType,
+                            boolean forEquals,
+                            ClassFactory cs)
+    {
+        // An XML value cannot be compared to any type--
+        // not even to other XML values.
+        return false;
+    }
+
+    /**
+     * Tell whether this type (XML) can be converted to the given type.
+     *
+     * An XML value can't be converted to any other type, per
+     * SQL/XML[2003] 6.3 <cast specification>
+     *
+     * @see TypeCompiler#convertible
+     */
+    public boolean convertible(TypeId otherType, 
+                            boolean forDataTypeFunction)
+    {
+        // An XML value cannot be converted to any non-XML type.  If
+        // user wants to convert an XML value to a string, then
+        // s/he must use the provided SQL/XML serialization operator
+        // (namely, XMLSERIALIZE).
+        return otherType.isXMLTypeId();
+    }
+
+    /**
+     * Tell whether this type (XML) is compatible with the given type.
+     *
+     * @param otherType The TypeId of the other type.
+     */
+    public boolean compatible(TypeId otherType)
+    {
+        // An XML value is not compatible (i.e. cannot be "coalesced")
+        // into any non-XML type.
+        return otherType.isXMLTypeId();
+    }
+
+    /**
+     * Tell whether this type (XML) can be stored into from the given type.
+     * Only XML values can be stored into an XML type, per SQL/XML spec:
+     *
+     * 4.2.2 XML comparison and assignment
+     * Values of XML type are assignable to sites of XML type.
+     *
+     * @param otherType The TypeId of the other type.
+     * @param cf A ClassFactory
+     */
+    public boolean storable(TypeId otherType, ClassFactory cf)
+    {
+        // The only type of value that can be stored as XML
+        // is an XML value.  Strings are not allowed.  If
+        // the user wants to store a string value as XML,
+        // s/he must use the provided XML parse operator
+        // (namely, XMLPARSE) to parse the string into
+        // XML.
+        return otherType.isXMLTypeId();
+    }
+
+    /**
+     * @see TypeCompiler#interfaceName
+     */
+    public String interfaceName() {
+        return ClassName.XMLDataValue;
+    }
+
+    /**
+     * @see TypeCompiler#getCorrespondingPrimitiveTypeName
+     */
+    public String getCorrespondingPrimitiveTypeName()
+    {
+        int formatId = getStoredFormatIdFromTypeId();
+        if (formatId == StoredFormatIds.XML_TYPE_ID)
+            return "org.apache.derby.iapi.types.XML";
+
+        if (SanityManager.DEBUG) {
+            SanityManager.THROWASSERT(
+                "unexpected formatId in getCorrespondingPrimitiveTypeName(): "
+                + formatId);
+        }
+
+        return null;
+    }
+
+    /**
+     * @see TypeCompiler#getCastToCharWidth
+     *
+     * While it is true XML values can't be cast to char, this method
+     * can get called before we finish type checking--so we return a dummy
+     * value here and let the type check throw the appropriate error.
+     */
+    public int getCastToCharWidth(DataTypeDescriptor dts)
+    {
+        return -1;
+    }
+
+    /**
+     * @see TypeCompiler#nullMethodName
+     */
+    protected String nullMethodName()
+    {
+        int formatId = getStoredFormatIdFromTypeId();
+        if (formatId == StoredFormatIds.XML_TYPE_ID)
+            return "getNullXML";
+
+        if (SanityManager.DEBUG) {
+            SanityManager.THROWASSERT(
+                "unexpected formatId in nullMethodName(): " + formatId);
+        }
+
+        return null;
+    }
+
+    /**
+     * @see TypeCompiler#dataValueMethodName
+     */
+    protected String dataValueMethodName()
+    {
+        int formatId = getStoredFormatIdFromTypeId();
+        if (formatId == StoredFormatIds.XML_TYPE_ID)
+            return "getXMLDataValue";
+
+        if (SanityManager.DEBUG) {
+            SanityManager.THROWASSERT(
+                "unexpected formatId in dataValueMethodName() - " + formatId);
+        }
+
+        return null;
+    }
+}

Propchange: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLTypeCompiler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj?rev=189721&r1=189720&r2=189721&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj Wed Jun  8 23:48:34 2005
@@ -86,6 +86,7 @@
 import org.apache.derby.impl.sql.compile.TriggerReferencingStruct;
 import org.apache.derby.impl.sql.compile.UnionNode;
 import org.apache.derby.impl.sql.compile.IntersectOrExceptNode;
+import org.apache.derby.impl.sql.compile.UnaryOperatorNode;
 import org.apache.derby.impl.sql.compile.UntypedNullConstantNode;
 import org.apache.derby.impl.sql.compile.UpdateNode;
 import org.apache.derby.impl.sql.compile.UserTypeConstantNode;
@@ -141,6 +142,7 @@
 import org.apache.derby.catalog.types.RoutineAliasInfo;
 
 import org.apache.derby.iapi.services.io.FormatableProperties;
+import org.apache.derby.iapi.services.io.StoredFormatIds;
 import org.apache.derby.iapi.util.ReuseFactory;
 import org.apache.derby.iapi.services.io.FormatableBitSet;
 import org.apache.derby.iapi.util.StringUtil;
@@ -683,6 +685,7 @@
 		  case CLOB:
 		  case NCLOB:
 		  case BINARY: // LARGE OBJECT
+		  case XML:
 			retval = true;
 			break;
 
@@ -1885,6 +1888,9 @@
 	The next lists should contain non-SQL92 keywords, and should
 	specify whether their keywords are reserved or non-reserved.
 	If they are non-reserved, they need to be added to the identifier() rule.
+
+	NOTE: XML, XMLPARSE, XMLSERIALIZE, and XMLEXISTS are considered reserved
+	words to comply with the SQL/XML (2003) standard, section 5.1.
  */
 
 /* NOTE - If you add a keyword, then you must add it to reservedKeyword()
@@ -1904,10 +1910,19 @@
 |	<LTRIM: "ltrim">
 |	<RTRIM: "rtrim">
 |	<SUBSTR:	"substr">
+|	<XML:	"xml">
+|	<XMLPARSE:	"xmlparse">
+|	<XMLSERIALIZE:	"xmlserialize">
+|	<XMLEXISTS:	"xmlexists">
 }
 
 /* NOTE - If you add a keyword, then you must add it to reservedKeyword()
  *	      or nonReservedKeyword() as well!
+ *
+ * NOTE: CONTENT, DOCUMENT, STRIP, WHITESPACE and PASSING are considered NON-
+ * reserved words to comply with the SQL/XML (2003) standard, section 5.1.
+ * PRESERVE is also listed as non-reserved in the SQL/XML spec, but
+ * since that word is already reserved, we leave it alone.
  */
 TOKEN [IGNORE_CASE] :
 {	/* Additional JSQL keywords -- non-SQL92 non-reserved Keywords */
@@ -1915,10 +1930,12 @@
 |	<BEFORE: "before">
 |	<CLASS: "class">
 |	<COMPRESS: "compress">
+|	<CONTENT: "content">
 |   <CS: "cs">
 |	<CURSORS: "cursors">
 |	<DB2SQL: "db2sql">
 |       <DIRTY: "dirty">
+|	<DOCUMENT: "document">
 |	<EACH: "each">
 |	<EXCLUSIVE: "exclusive">
 |	<FN: "fn">
@@ -1939,8 +1956,10 @@
 |   <OLD_TABLE: "old_table">
 |   <OUT: "out">
 |	<PARAMETER: "parameter">
+|	<PASSING: "passing">
 |	<PROPERTIES: "properties">
 |	<READS: "reads">
+|	<REF: "ref">
 |	<REFERENCING: "referencing">
 |	<RENAME: "rename">
 |       <RESET: "reset">
@@ -1955,10 +1974,12 @@
 |	<SPECIFIC: "specific">
 |   <SQRT: "sqrt">
 |       <STABILITY: "stability">
+|   <STRIP: "strip">
 |   <STYLE: "style">
 |	<TRIGGER: "trigger">
 |   <UCASE: "ucase">
 |   <UR: "ur">
+|   <WHITESPACE: "whitespace">
 }
 
 TOKEN :
@@ -3377,6 +3398,8 @@
 	typeDescriptor = longType()
 |
 	typeDescriptor = LOBType()
+|
+	typeDescriptor = XMLType()
 	)
 	{
 		return typeDescriptor;
@@ -3790,6 +3813,55 @@
 }
 
 /*
+ * <A NAME="XMLType">XMLType</A>
+ */
+DataTypeDescriptor
+XMLType() throws StandardException :
+{
+	DataTypeDescriptor value;
+}
+{
+	<XML>
+	{
+		checkVersion(DataDictionary.DD_VERSION_DERBY_10_1, "XML");
+		return DataTypeDescriptor.getBuiltInDataTypeDescriptor(
+			StoredFormatIds.XML_TYPE_ID);
+	}
+}
+
+/*
+ * <A NAME="xmlDocOrContent">xmlDocOrContent</A>
+ *
+ * Parse the XML keywords DOCUMENT and CONTENT.  We don't
+ * support CONTENT yet, so we throw an appropriate error
+ * if we see it.
+ *
+ */
+void
+xmlDocOrContent() throws StandardException :
+{
+}
+{
+	LOOKAHEAD({ (getToken(1).kind != DOCUMENT) &&
+		(getToken(1).kind != CONTENT) })
+	{
+		throw StandardException.newException(
+			SQLState.LANG_XML_KEYWORD_MISSING, "DOCUMENT");
+	}
+|
+	LOOKAHEAD({ getToken(1).kind == CONTENT }) <CONTENT>
+	{
+		throw StandardException.newException(
+			SQLState.LANG_UNSUPPORTED_XML_FEATURE, "CONTENT");
+	}
+|
+	LOOKAHEAD({ getToken(1).kind == DOCUMENT }) <DOCUMENT>
+	{
+		return;
+	}
+}
+
+/*
  * <A NAME="javaType">javaType</A>
  */
 DataTypeDescriptor
@@ -5995,7 +6067,10 @@
                 getToken(1).kind == MINUTE ||
                 getToken(1).kind == SECOND ||
                 getToken(1).kind == LENGTH ||
-                getToken(1).kind == LOCATE ) &&
+                getToken(1).kind == LOCATE ||
+                getToken(1).kind == XMLPARSE ||
+                getToken(1).kind == XMLSERIALIZE ||
+                getToken(1).kind == XMLEXISTS ) &&
               getToken(2).kind == LEFT_PAREN
               )
     } )
@@ -6094,6 +6169,11 @@
                                                         value,
                                                         localCM);
 	}
+|
+	value = xmlFunction()
+	{
+		return value;
+	}
 }
 
 
@@ -6144,6 +6224,237 @@
 	}
 }
 	 
+/*
+ * <A NAME="xmlFunction">xmlFunction</A>
+ *
+ * This method parses the built-in functions used with
+ * the XML datatype.
+ *
+ */
+ValueNode
+	xmlFunction() throws StandardException :
+{
+	ValueNode value;
+	checkVersion(DataDictionary.DD_VERSION_DERBY_10_1, "XML");
+}
+{
+	<XMLPARSE> <LEFT_PAREN>
+		xmlDocOrContent() value = xmlParseValue() <RIGHT_PAREN>
+	{
+		return value;
+	}
+|
+	<XMLSERIALIZE> <LEFT_PAREN> value = xmlSerializeValue() <RIGHT_PAREN>
+	{
+		return value;
+	}
+|
+	<XMLEXISTS> <LEFT_PAREN> value = xmlExistsValue() <RIGHT_PAREN>
+	{
+		return value;
+	}
+}
+
+/*
+ * <A NAME="xmlParseValue">xmlParseValue</A>
+ *
+ * Syntax is as follows:
+ *
+ *     XMLPARSE( DOCUMENT <string-value-expression> PRESERVE WHITESPACE )
+ *
+ * The result of this operation will be an XML value, which can either
+ * be used transiently or else can be stored persistently in a table that
+ * has an XML column.  For example:
+ *
+ * ij> CREATE TABLE x_table (id INT, xdoc XML);
+ * 0 rows inserted/updated/deleted
+ * ij> INSERT INTO x_table VALUES (1, XMLPARSE(DOCUMENT '<simp> doc </simp>'
+ * PRESERVE WHITESPACE));
+ * 1 row inserted/updated/deleted
+ *
+ * We only allow XML documents (as opposed to XML content) to be
+ * parsed into XML values.  Note that we require the "PRESERVE WHITESPACE"
+ * keyword to be explicit; this is because the SQL/XML (2003) spec says that
+ * if no whitespace option is given, the default is "STRIP WHITESPACE", which
+ * we don't support (yet).
+ *
+ * By the time we get to this method, the "DOCUMENT" keyword has already
+ * been parsed.
+ *
+ */
+ValueNode
+	xmlParseValue() throws StandardException :
+{
+	ValueNode value;
+	boolean wsOption;
+}
+{
+	value = additiveExpression(null,0,false) wsOption = xmlPreserveWhitespace() {
+		return (ValueNode) nodeFactory.getNode(
+					C_NodeTypes.XML_PARSE_OPERATOR_NODE,
+					value,
+					ReuseFactory.getInteger(UnaryOperatorNode.XMLPARSE_OP),
+					new Object[] {(wsOption ? Boolean.TRUE : Boolean.FALSE)},
+					getContextManager());
+	}
+}
+
+/*
+ * <A NAME="xmlPreserveWhitespace">xmlPreserveWhitespace</A>
+ *
+ * For now, we only support the PRESERVE WHITESPACE option.
+ *
+ */
+boolean
+	xmlPreserveWhitespace() throws StandardException :
+{
+}
+{
+	LOOKAHEAD({ (getToken(1).kind != STRIP) &&
+		(getToken(1).kind != PRESERVE) })
+	{
+		throw StandardException.newException(
+			SQLState.LANG_XML_KEYWORD_MISSING, "PRESERVE WHITESPACE");
+	}
+|
+	<STRIP> <WHITESPACE>
+	{ // don't preserve whitespace.
+		throw StandardException.newException(
+			SQLState.LANG_UNSUPPORTED_XML_FEATURE, "STRIP WHITESPACE");
+	}
+|
+	<PRESERVE> <WHITESPACE>
+	{ // must preserve whitespace.
+		return true;
+	}
+}
+
+/*
+ * <A NAME="xmlSerializeValue">xmlSerializeValue</A>
+ *
+ * Syntax is as follows:
+ *
+ *   XMLSERIALIZE( <xml-value-expression> AS <string-data-type> )
+ *
+ * The result of this operation will be a string value with the type specified
+ * by the user.  For example:
+ *
+ * ij> SELECT id, XMLSERIALIZE(xdoc AS varchar(30)) FROM x_table;
+ * ID         |2
+ * ------------------------------------------
+ * 1          |<simp> doc </simp>
+ *
+ */
+ValueNode
+	xmlSerializeValue() throws StandardException :
+{
+	ValueNode value;
+	DataTypeDescriptor targetType;
+}
+{
+	value = additiveExpression(null,0,false)
+		targetType = xmlSerializeTargetType()
+	{
+		return (ValueNode) nodeFactory.getNode(
+					C_NodeTypes.XML_SERIALIZE_OPERATOR_NODE,
+					value,
+					ReuseFactory.getInteger(UnaryOperatorNode.XMLSERIALIZE_OP),
+					new Object[] {targetType},
+					getContextManager());
+	}
+}
+
+/*
+ * <A NAME="xmlSerializeTargetType">xmlSerializeTargetType</A>
+ *
+ * Parse the target type of an XMLSERIALIZE operation.
+ *
+ */
+DataTypeDescriptor xmlSerializeTargetType() throws StandardException :
+{
+	DataTypeDescriptor targetType;
+}
+{
+	LOOKAHEAD({ (getToken(1).kind != AS) || (getToken(2).kind == RIGHT_PAREN) })
+	{
+		throw StandardException.newException(
+			SQLState.LANG_XML_KEYWORD_MISSING, "AS <string-type>");
+	}
+|
+	<AS> targetType = dataTypeDDL()
+	{
+		return targetType;
+	}
+}
+
+/*
+ * <A NAME="xmlExistsValue">xmlExistsValue</A>
+ *
+ * Syntax is as follows:
+ *
+ *   XMLEXISTS( <xpath-expression> PASSING BY VALUE <xml-value-expression> )
+ *
+ * The result of this operation will be a boolean true/false/unknown value:
+ *   -- Unknown if either <xpath-expression> or <xml-value-expression> is null;
+ *   -- True if at least one node in the given xml-value matches the given
+ *      XPath expression;
+ *   -- False otherwise.
+ *
+ * For example:
+ *
+ * ij> SELECT id FROM x_table WHERE XMLEXISTS('/simple' PASSING BY VALUE xdoc);
+ * ID
+ * -----------
+ * 1
+ *
+ */
+ValueNode
+	xmlExistsValue() throws StandardException :
+{
+	ValueNode xpathExpr;
+	ValueNode xmlValue;
+}
+{
+	xpathExpr = additiveExpression(null,0,false)
+		xmlPassingMechanism() xmlValue = additiveExpression(null, 0, false)
+	{
+		return (ValueNode) nodeFactory.getNode(
+					C_NodeTypes.XML_EXISTS_OPERATOR_NODE,
+					xpathExpr,
+					xmlValue,
+					ReuseFactory.getInteger(BinaryOperatorNode.XMLEXISTS_OP),
+					getContextManager());
+	}
+}
+
+/*
+ * <A NAME="xmlPassingMechanism">xmlPassingMechanism</A>
+ *
+ * For now, we only support the BY VALUE option because,
+ * at query time, we take the XML string value from disk and
+ * pass it into Xalan, which creates a "copy" of the XML
+ * value internally (as DOM/DTM) and then executes against
+ * that.  Because Xalan creates this copy, this impl
+ * is BY VALUE.
+ *
+ */
+void
+	xmlPassingMechanism() throws StandardException :
+{
+}
+{
+	LOOKAHEAD( { getToken(3).kind == REF })
+	<PASSING> <BY> <REF>
+	{ // pass the XML value by reference
+		throw StandardException.newException(
+			SQLState.LANG_UNSUPPORTED_XML_FEATURE, "BY REF");
+	}
+|
+	<PASSING> <BY> <VALUE>
+	{ // pass a 'copy' of the XML value.
+		return;
+	}
+}
 
 /*
  * <A NAME="numericFunctionType">numericFunctionType</A>
@@ -11432,6 +11743,10 @@
 |	tok = <LTRIM>
 |	tok = <RTRIM>
 |	tok = <SUBSTR>
+|	tok = <XML>
+|	tok = <XMLPARSE>
+|	tok = <XMLSERIALIZE>
+|	tok = <XMLEXISTS>
 )
 	{
 		// Remember whether last token was a delimited identifier
@@ -11476,6 +11791,7 @@
 	|	tok = <COMPRESS>
 	|	tok = <CONCAT>
 	|	tok = <CONTAINS>
+	|	tok = <CONTENT>
 	|   tok = <CS>
 	|	tok = <CURDATE>
 	|	tok = <CURTIME>
@@ -11487,6 +11803,7 @@
 	|	tok = <DYNAMIC>
     |   tok = <DATABASE>
 	|	tok = <DB2SQL>
+	|	tok = <DOCUMENT>
 	|	tok = <EACH>
 	|	tok = <EXCLUSIVE>
 	|	tok = <FN>
@@ -11533,10 +11850,12 @@
 	|	tok = <OLD_TABLE>
 	|	tok = <OJ>
 	|	tok = <PASCAL>
+	|	tok = <PASSING>
 	|	tok = <PLI>
 	|	tok = <PRECISION>
 	|	tok = <PROPERTIES>
 	|	tok = <READS>
+	|	tok = <REF>
 // SQL92 says it is reserved, but we want it to be non-reserved.
 	|	tok = <RELEASE>
 	|	tok = <RENAME>
@@ -11571,6 +11890,7 @@
     |       tok = <STABILITY>
 	|	tok = <START>
 	|	tok = <STATEMENT>
+	|	tok = <STRIP>
 	|	tok = <SYNONYM>
 	|	tok = <STYLE>
 	|	tok = <T>
@@ -11592,6 +11912,7 @@
 	|	tok = <VARBINARY>
 	|	tok = <PARAMETER>
 	|	tok = <WHEN>
+	|	tok = <WHITESPACE>
 	)
 	{
 		// Remember whether last token was a delimited identifier

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties?rev=189721&r1=189720&r2=189721&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties Wed Jun  8 23:48:34 2005
@@ -373,6 +373,7 @@
 22025=Escape character must be followed by escape character, '_', or '%'. It cannot be followed by any other character or be at the end of the pattern.
 22027=The built-in TRIM() function only supports a single trim character.  The LTRIM() and RTRIM() built-in functions support multiple trim characters.
 22501=An ESCAPE clause of NULL returns undefined results and is not allowed.
+2200L=XMLPARSE operand is not an XML document; see next exception for details.
 23502=Column ''{0}''  cannot accept a NULL value.
 23505=The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by ''{0}'' defined on ''{1}''.
 23503={2} on table ''{1}'' caused a violation of foreign key constraint ''{0}'' for key {3}.  The statement has been rolled back.
@@ -927,6 +928,15 @@
 X0X87.S=ResultSet.relative(int row) cannot be called when the cursor is not positioned on a row.
 X0X95.S=Operation ''{0}'' cannot be performed on object ''{1}'' because there is an open ResultSet dependent on that object.
 X0X99.S=Index ''{0}'' does not exist.
+
+# Derby-specific XML errors.
+X0X14.S=Binding directly to an XML value is not allowed; try using XMLPARSE.
+X0X15.S=XML values are not allowed in top-level result sets; try using XMLSERIALIZE.
+X0X16.S=XML syntax error; missing keyword(s): ''{0}''.
+X0X17.S=Invalid target type for XMLSERIALIZE: ''{0}''.
+X0X18.S=XML feature not supported: ''{0}''.
+X0XML.S=Encountered unexpected error while processing XML; see next exception for details.
+
 X0Y16.S=''{0}'' is not a view.  If it is a table, then use DROP TABLE instead.
 X0Y23.S=Operation ''{0}'' cannot be performed on object ''{1}'' because VIEW ''{2}'' is dependent on that object.
 X0Y24.S=Operation ''{0}'' cannot be performed on object ''{1}'' because STATEMENT ''{2}'' is dependent on that object.

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/xmlBinding.out
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/xmlBinding.out?rev=189721&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/xmlBinding.out (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/xmlBinding.out Wed Jun  8 23:48:34 2005
@@ -0,0 +1,51 @@
+[ Beginning XML binding tests. ]
+XML column -- bind String to XML: PASS -- caught expected error X0X14.
+XML column -- bind Java null to XML: PASS -- caught expected error X0X14.
+XML column -- bind SQL NULL to XML: PASS -- caught expected error X0X14.
+XML column -- bind integer to XML: PASS -- caught expected error X0X14.
+Trying to bind to XML in XMLSERIALIZE: PASS -- caught expected error X0X14.
+Trying to bind to XML in XMLEXISTS: PASS -- caught expected error X0X14.
+XML value in result set: PASS -- caught expected error X0X15.
+[ End XML binding tests. ]
+[ Beginning XMLPARSE tests. ]
+Test insertions from file: 
+Inserted roughly 40k of data.
+Inserted roughly 40k of data.
+Inserted roughly 1k of data.
+Inserted roughly 1k of data.
+Inserted roughly 1k of data.
+Inserted roughly 1k of data.
+-----> Insertions all PASS.
+Binding string in XMLPARSE: PASS -- Completed without exception, as expected.
+Binding Java null string in XMLPARSE: PASS -- Completed without exception, as expected.
+Binding SQL NULL string in XMLPARSE: PASS -- Completed without exception, as expected.
+[ End XMLPARSE tests. ]
+[ Beginning XMLSERIALIZE tests. ]
+1, [ roughly 40k ]
+2, [ roughly 40k ]
+3, [ roughly 1k ]
+4, [ roughly 1k ]
+5, [ roughly 1k ]
+6, [ roughly 1k ]
+7, [ roughly 0k ]
+8, NULL
+9, NULL
+[ End XMLSERIALIZE tests. ]
+[ Begin XMLEXISTS tests. ]
+Running XMLEXISTS with: //abb
+-----> Matching rows: 1
+Running XMLEXISTS with: //d50
+-----> Matching rows: 1
+Running XMLEXISTS with: //person/email
+-----> Matching rows: 4
+Running XMLEXISTS with: /personnel
+-----> Matching rows: 5
+Running XMLEXISTS with: //person/@id
+-----> Matching rows: 4
+Running XMLEXISTS with: //person/@noteTwo
+-----> Matching rows: 1
+Binding string in XMLEXISTS: PASS -- Completed without exception, as expected.
+Binding Java null string in XMLEXISTS: PASS -- Completed without exception, as expected.
+Binding SQL NULL string in XMLEXISTS: PASS -- Completed without exception, as expected.
+[ End XMLEXISTS tests. ]
+[ Done. ]

Propchange: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/xmlBinding.out
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/xml_general.out
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/xml_general.out?rev=189721&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/xml_general.out (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/xml_general.out Wed Jun  8 23:48:34 2005
@@ -0,0 +1,582 @@
+ij> create table t0 (si smallint, i int, bi bigint, vcb varchar (32) for bit data, nu numeric(10,2), f float, d double, vc varchar(20), da date, ti time, ts timestamp, cl clob, bl blob);
+0 rows inserted/updated/deleted
+ij> -- XML column declarations should work like other built-in types.
+create table t1 (i int, x xml);
+0 rows inserted/updated/deleted
+ij> create table t2 (i int, x xml not null);
+0 rows inserted/updated/deleted
+ij> create table t3 (i int, x xml default null);
+0 rows inserted/updated/deleted
+ij> create table t4 (vc varchar(100));
+0 rows inserted/updated/deleted
+ij> create table t5 (x2 xml not null);
+0 rows inserted/updated/deleted
+ij> alter table t5 add column x1 xml;
+0 rows inserted/updated/deleted
+ij> -- Check insertion of null XML values.
+----- Next four should work.
+insert into t1 values (1, null);
+1 row inserted/updated/deleted
+ij> insert into t1 values (2, cast (null as xml));
+1 row inserted/updated/deleted
+ij> insert into t1 (i) values (4);
+1 row inserted/updated/deleted
+ij> insert into t1 values (3, default);
+1 row inserted/updated/deleted
+ij> -- Next two should fail.
+insert into t2 values (1, null);
+ERROR 23502: Column 'X'  cannot accept a NULL value.
+ij> insert into t2 values (2, cast (null as xml));
+ERROR 23502: Column 'X'  cannot accept a NULL value.
+ij> -- XML cols can't hold non-XML types.
+insert into t1 values (3, 'hmm');
+ERROR 42821: Columns of type 'XML' cannot hold values of type 'CHAR'. 
+ij> insert into t1 values (1, 2);
+ERROR 42821: Columns of type 'XML' cannot hold values of type 'INTEGER'. 
+ij> insert into t1 values (1, 123.456);
+ERROR 42821: Columns of type 'XML' cannot hold values of type 'DECIMAL'. 
+ij> insert into t1 values (1, x'01');
+ERROR 42821: Columns of type 'XML' cannot hold values of type 'CHAR () FOR BIT DATA'. 
+ij> insert into t1 values (1, x'ab');
+ERROR 42821: Columns of type 'XML' cannot hold values of type 'CHAR () FOR BIT DATA'. 
+ij> insert into t1 values (1, current date);
+ERROR 42821: Columns of type 'XML' cannot hold values of type 'DATE'. 
+ij> insert into t1 values (1, current time);
+ERROR 42821: Columns of type 'XML' cannot hold values of type 'TIME'. 
+ij> insert into t1 values (1, current timestamp);
+ERROR 42821: Columns of type 'XML' cannot hold values of type 'TIMESTAMP'. 
+ij> insert into t1 values (1, ('hmm' | | 'andstuff'));
+ERROR 42821: Columns of type 'XML' cannot hold values of type 'CHAR'. 
+ij> -- XML can't be stored in non-XML cols.
+insert into t0 (si) values (cast (null as xml));
+ERROR 42821: Columns of type 'SMALLINT' cannot hold values of type 'XML'. 
+ij> insert into t0 (i) values (cast (null as xml));
+ERROR 42821: Columns of type 'INTEGER' cannot hold values of type 'XML'. 
+ij> insert into t0 (bi) values (cast (null as xml));
+ERROR 42821: Columns of type 'BIGINT' cannot hold values of type 'XML'. 
+ij> insert into t0 (vcb) values (cast (null as xml));
+ERROR 42821: Columns of type 'VARCHAR () FOR BIT DATA' cannot hold values of type 'XML'. 
+ij> insert into t0 (nu) values (cast (null as xml));
+ERROR 42821: Columns of type 'NUMERIC' cannot hold values of type 'XML'. 
+ij> insert into t0 (f) values (cast (null as xml));
+ERROR 42821: Columns of type 'DOUBLE' cannot hold values of type 'XML'. 
+ij> insert into t0 (d) values (cast (null as xml));
+ERROR 42821: Columns of type 'DOUBLE' cannot hold values of type 'XML'. 
+ij> insert into t0 (vc) values (cast (null as xml));
+ERROR 42821: Columns of type 'VARCHAR' cannot hold values of type 'XML'. 
+ij> insert into t0 (da) values (cast (null as xml));
+ERROR 42821: Columns of type 'DATE' cannot hold values of type 'XML'. 
+ij> insert into t0 (ti) values (cast (null as xml));
+ERROR 42821: Columns of type 'TIME' cannot hold values of type 'XML'. 
+ij> insert into t0 (ts) values (cast (null as xml));
+ERROR 42821: Columns of type 'TIMESTAMP' cannot hold values of type 'XML'. 
+ij> insert into t0 (cl) values (cast (null as xml));
+ERROR 42821: Columns of type 'CLOB' cannot hold values of type 'XML'. 
+ij> insert into t0 (bl) values (cast (null as xml));
+ERROR 42821: Columns of type 'BLOB' cannot hold values of type 'XML'. 
+ij> -- No casting is allowed.
+insert into t1 values (1, cast ('hmm' as xml));
+ERROR 42846: Cannot convert types 'CHAR' to 'XML'.
+ij> insert into t1 values (1, cast (2 as xml));
+ERROR 42846: Cannot convert types 'INTEGER' to 'XML'.
+ij> insert into t1 values (1, cast (123.456 as xml));
+ERROR 42846: Cannot convert types 'DECIMAL' to 'XML'.
+ij> insert into t1 values (1, cast (x'01' as xml));
+ERROR 42846: Cannot convert types 'CHAR () FOR BIT DATA' to 'XML'.
+ij> insert into t1 values (1, cast (x'ab' as xml));
+ERROR 42846: Cannot convert types 'CHAR () FOR BIT DATA' to 'XML'.
+ij> insert into t1 values (1, cast (current date as xml));
+ERROR 42846: Cannot convert types 'DATE' to 'XML'.
+ij> insert into t1 values (1, cast (current time as xml));
+ERROR 42846: Cannot convert types 'TIME' to 'XML'.
+ij> insert into t1 values (1, cast (current timestamp as xml));
+ERROR 42846: Cannot convert types 'TIMESTAMP' to 'XML'.
+ij> insert into t1 values (1, cast (('hmm' | | 'andstuff') as xml));
+ERROR 42846: Cannot convert types 'CHAR' to 'XML'.
+ij> -- XML can't be used in non-XML operations.
+select i + x from t1;
+ERROR 42Y95: The '+' operator with a left operand type of 'INTEGER' and a right operand type of 'XML' is not supported.
+ij> select i * x from t1;
+ERROR 42Y95: The '*' operator with a left operand type of 'INTEGER' and a right operand type of 'XML' is not supported.
+ij> select i / x from t1;
+ERROR 42Y95: The '/' operator with a left operand type of 'INTEGER' and a right operand type of 'XML' is not supported.
+ij> select i - x from t1;
+ERROR 42Y95: The '-' operator with a left operand type of 'INTEGER' and a right operand type of 'XML' is not supported.
+ij> select -x from t1;
+ERROR 42X37: The unary '-' operator is not allowed on the 'XML' type.
+ij> select 'hi' | | x from t1;
+ERROR 42846: Cannot convert types 'XML' to 'VARCHAR'.
+ij> select substr(x, 0) from t1;
+ERROR 42X25: The 'SUBSTR' function is not allowed on the 'XML' type.
+ij> select i from t1 where x like 'hmm';
+ERROR 42884: No authorized routine named 'LIKE' of type 'FUNCTION' having compatible arguments was found.
+ij> select max(x) from t1;
+ERROR 42Y22: Aggregate MAX cannot operate on type XML.
+ij> select min(x) from t1;
+ERROR 42Y22: Aggregate MIN cannot operate on type XML.
+ij> select length(x) from t1;
+ERROR 42X25: The 'length' function is not allowed on the 'XML' type.
+ij> -- Comparsions against XML don't work.
+select i from t1 where x = 'hmm';
+ERROR 42818: Comparisons between 'XML' and 'CHAR' are not supported.
+ij> select i from t1 where x > 0;
+ERROR 42818: Comparisons between 'XML' and 'INTEGER' are not supported.
+ij> select i from t1 where x > x;
+ERROR 42818: Comparisons between 'XML' and 'XML' are not supported.
+ij> select i from t1 where x > 'some char';
+ERROR 42818: Comparisons between 'XML' and 'CHAR' are not supported.
+ij> -- Indexing/ordering on XML cols is not allowed.
+create index oops_ix on t1(x);
+ERROR X0X67: Columns of type 'XML' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, INTERSECT, EXCEPT or DISTINCT statements because comparisons are not supported for that type.
+ij> select i from t1 where x is null order by x;
+ERROR X0X67: Columns of type 'XML' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, INTERSECT, EXCEPT or DISTINCT statements because comparisons are not supported for that type.
+ij> -- XML cols can be used in a SET clause, if target value is XML.
+create trigger tr2 after insert on t1 for each row mode db2sql update t1 set x = 'hmm';
+ERROR 42821: Columns of type 'XML' cannot hold values of type 'CHAR'. 
+ij> create trigger tr1 after insert on t1 for each row mode db2sql update t1 set x = null;
+0 rows inserted/updated/deleted
+ij> drop trigger tr1;
+0 rows inserted/updated/deleted
+ij> -- Test XMLPARSE operator.
+----- These should fail.
+insert into t1 values (1, xmlparse(document '<hmm/>' strip whitespace));
+ERROR X0X18: XML feature not supported: 'STRIP WHITESPACE'.
+ij> insert into t1 values (1, xmlparse(document '<hmm/>'));
+ERROR X0X16: XML syntax error; missing keyword(s): 'PRESERVE WHITESPACE'.
+ij> insert into t1 values (1, xmlparse('<hmm/>' preserve whitespace));
+ERROR X0X16: XML syntax error; missing keyword(s): 'DOCUMENT'.
+ij> insert into t1 values (1, xmlparse(content '<hmm/>' preserve whitespace));
+ERROR X0X18: XML feature not supported: 'CONTENT'.
+ij> select xmlparse(document xmlparse(document '<hein/>' preserve whitespace) preserve whitespace) from t1;
+ERROR 42X25: The 'XMLParse' function is not allowed on the 'XML' type.
+ij> select i from t1 where xmlparse(document '<hein/>' preserve whitespace);
+ERROR 42X19: The WHERE or HAVING clause or CHECK CONSTRAINT definition is a 'XML' expression.  It must be a BOOLEAN expression.
+ij> insert into t1 values (1, xmlparse(document '<oops>' preserve whitespace));
+ERROR 2200L: XMLPARSE operand is not an XML document; see next exception for details. SQLSTATE: XJ001: Java exception: 'XML document structures must start and end within the same entity.: org.xml.sax.SAXParseException'.
+ij> -- These should work.
+insert into t1 values (5, xmlparse(document '<hmm/>' preserve whitespace));
+1 row inserted/updated/deleted
+ij> insert into t1 values (6, xmlparse(document '<half> <masted> bass </masted> boosted. </half>' preserve whitespace));
+1 row inserted/updated/deleted
+ij> insert into t2 values (1, xmlparse(document '<should> work as planned </should>' preserve whitespace));
+1 row inserted/updated/deleted
+ij> insert into t5 (x1, x2) values (null, xmlparse(document '<notnull/>' preserve whitespace));
+1 row inserted/updated/deleted
+ij> update t1 set x = xmlparse(document '<update> document was inserted as part of an UPDATE </update>' preserve whitespace) where i = 1;
+1 row inserted/updated/deleted
+ij> update t1 set x = xmlparse(document '<update2> document was inserted as part of an UPDATE </update2>' preserve whitespace) where xmlexists('/update' passing by value x);
+1 row inserted/updated/deleted
+ij> select i from t1 where xmlparse(document '<hein/>' preserve whitespace) is not null;
+I          
+-----
+1          
+2          
+4          
+3          
+5          
+6          
+ij> select i from t1 where xmlparse(document '<hein/>' preserve whitespace) is not null order by i;
+I          
+-----
+1          
+2          
+3          
+4          
+5          
+6          
+ij> -- "is [not] null" should work with XML.
+select i from t1 where x is not null;
+I          
+-----
+1          
+5          
+6          
+ij> select i from t1 where x is null;
+I          
+-----
+2          
+4          
+3          
+ij> -- XML columns can't be returned in a top-level result set.
+select x from t1;
+ERROR X0X15: XML values are not allowed in top-level result sets; try using XMLSERIALIZE.
+ij> select * from t1;
+ERROR X0X15: XML values are not allowed in top-level result sets; try using XMLSERIALIZE.
+ij> select xmlparse(document vc preserve whitespace) from t4;
+ERROR X0X15: XML values are not allowed in top-level result sets; try using XMLSERIALIZE.
+ij> values xmlparse(document '<bye/>' preserve whitespace);
+ERROR X0X15: XML values are not allowed in top-level result sets; try using XMLSERIALIZE.
+ij> values xmlparse(document '<hel' | | 'lo/>' preserve whitespace);
+ERROR X0X15: XML values are not allowed in top-level result sets; try using XMLSERIALIZE.
+ij> -- Test XMLSERIALIZE operator.
+insert into t4 values ('<hmm/>');
+1 row inserted/updated/deleted
+ij> insert into t4 values 'no good';
+1 row inserted/updated/deleted
+ij> -- These should fail.
+select xmlserialize(x) from t1;
+ERROR X0X16: XML syntax error; missing keyword(s): 'AS <string-type>'.
+ij> select xmlserialize(x as) from t1;
+ERROR X0X16: XML syntax error; missing keyword(s): 'AS <string-type>'.
+ij> select xmlserialize(x as int) from t1;
+ERROR X0X17: Invalid target type for XMLSERIALIZE: 'INTEGER'.
+ij> select xmlserialize(x as varchar(20) for bit data) from t1;
+ERROR X0X17: Invalid target type for XMLSERIALIZE: 'VARCHAR () FOR BIT DATA'.
+ij> select xmlserialize(y as char(10)) from t1;
+ERROR 42X04: Column 'Y' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE  statement then 'Y' is not a column in the target table.
+ij> select xmlserialize(xmlserialize(x as clob) as clob) from t1;
+ERROR 42X25: The 'XMLSerialize' function is not allowed on the 'CLOB' type.
+ij> values xmlserialize('<okay> dokie </okay>' as clob);
+ERROR 42X25: The 'XMLSerialize' function is not allowed on the 'CHAR' type.
+ij> -- These should succeed.
+select xmlserialize(x as clob) from t1;
+1                                                                                                                               
+-----
+<update2> document was inserted as part of an UPDATE </update2>                                                                 
+NULL                                                                                                                            
+NULL                                                                                                                            
+NULL                                                                                                                            
+<hmm/>                                                                                                                          
+<half> <masted> bass </masted> boosted. </half>                                                                                 
+ij> select xmlserialize(x1 as clob), xmlserialize(x2 as clob) from t5;
+1 |2                                                                                                                               
+-----
+NULL |<notnull/>                                                                                                                      
+ij> select xmlserialize(x as char(100)) from t1;
+1                                                                                                   
+-----
+<update2> document was inserted as part of an UPDATE </update2>                                     
+NULL                                                                                                
+NULL                                                                                                
+NULL                                                                                                
+<hmm/>                                                                                              
+<half> <masted> bass </masted> boosted. </half>                                                     
+ij> select xmlserialize(x as varchar(300)) from t1;
+1                                                                                                                               
+-----
+<update2> document was inserted as part of an UPDATE </update2>                                                                 
+NULL                                                                                                                            
+NULL                                                                                                                            
+NULL                                                                                                                            
+<hmm/>                                                                                                                          
+<half> <masted> bass </masted> boosted. </half>                                                                                 
+ij> -- These should succeed at the XMLEXISTS level, but fail with
+----- parse/truncation errors.
+select xmlserialize(xmlparse(document vc preserve whitespace) as char(10)) from t4;
+1         
+-----
+ERROR 2200L: XMLPARSE operand is not an XML document; see next exception for details. SQLSTATE: XJ001: Java exception: 'Content is not allowed in prolog.: org.xml.sax.SAXParseException'.
+ij> select xmlserialize(x as char) from t1;
+1   
+-----
+ERROR 22001: A truncation error was encountered trying to shrink CHAR '<update2> document was inserted as part of an UPDATE </updat&' to length 1.
+ij> select xmlserialize(x as clob(10)) from t1;
+1         
+-----
+ERROR 22001: A truncation error was encountered trying to shrink CLOB '<update2> document was inserted as part of an UPDATE </updat&' to length 10.
+ij> select xmlserialize(x as char(1)) from t1;
+1   
+-----
+ERROR 22001: A truncation error was encountered trying to shrink CHAR '<update2> document was inserted as part of an UPDATE </updat&' to length 1.
+ij> select length(xmlserialize(x as char(1))) from t1;
+1          
+-----
+ERROR 22001: A truncation error was encountered trying to shrink CHAR '<update2> document was inserted as part of an UPDATE </updat&' to length 1.
+ij> select xmlserialize(x as varchar(1)) from t1;
+1   
+-----
+ERROR 22001: A truncation error was encountered trying to shrink VARCHAR '<update2> document was inserted as part of an UPDATE </updat&' to length 1.
+ij> select length(xmlserialize(x as varchar(1))) from t1;
+1          
+-----
+ERROR 22001: A truncation error was encountered trying to shrink VARCHAR '<update2> document was inserted as part of an UPDATE </updat&' to length 1.
+ij> -- These checks verify that the XMLSERIALIZE result is the correct
+----- type (the type is indicated as part of the error message).
+create table it (i int);
+0 rows inserted/updated/deleted
+ij> insert into it values (select xmlserialize(x as varchar(10)) from t1);
+ERROR 42821: Columns of type 'INTEGER' cannot hold values of type 'VARCHAR'. 
+ij> insert into it values (select xmlserialize(x as char(10)) from t1);
+ERROR 42821: Columns of type 'INTEGER' cannot hold values of type 'CHAR'. 
+ij> insert into it values (select xmlserialize(x as clob(10)) from t1);
+ERROR 42821: Columns of type 'INTEGER' cannot hold values of type 'CLOB'. 
+ij> -- Test XMLPARSE/XMLSERIALIZE combinations.
+----- These should fail.
+select xmlserialize(xmlparse(document '<hmm>' preserve whitespace) as clob) from t2;
+1                                                                                                                               
+-----
+ERROR 2200L: XMLPARSE operand is not an XML document; see next exception for details. SQLSTATE: XJ001: Java exception: 'XML document structures must start and end within the same entity.: org.xml.sax.SAXParseException'.
+ij> select xmlserialize(xmlparse(document x preserve whitespace) as char(100)) from t1;
+ERROR 42X25: The 'XMLParse' function is not allowed on the 'XML' type.
+ij> -- These should succeed.
+select xmlserialize(xmlparse(document '<hmm/>' preserve whitespace) as clob) from t2;
+1                                                                                                                               
+-----
+<hmm/>                                                                                                                          
+ij> select xmlserialize(xmlparse(document xmlserialize(x as clob) preserve whitespace) as clob) from t1;
+1                                                                                                                               
+-----
+<update2> document was inserted as part of an UPDATE </update2>                                                                 
+NULL                                                                                                                            
+NULL                                                                                                                            
+NULL                                                                                                                            
+<hmm/>                                                                                                                          
+<half> <masted> bass </masted> boosted. </half>                                                                                 
+ij> values xmlserialize(xmlparse(document '<okay> dokie </okay>' preserve whitespace) as clob);
+1                                                                                                                               
+-----
+<okay> dokie </okay>                                                                                                            
+ij> select i from t1 where xmlparse(document xmlserialize(x as clob) preserve whitespace) is not null order by i;
+I          
+-----
+1          
+5          
+6          
+ij> -- Test XMLEXISTS operator.
+insert into t1 values (7, xmlparse(document '<lets> <try> this out </try> </lets>' preserve whitespace));
+1 row inserted/updated/deleted
+ij> create table t7 (i int, x1 xml, x2 xml not null);
+0 rows inserted/updated/deleted
+ij> insert into t7 values (1, null, xmlparse(document '<ok/>' preserve whitespace));
+1 row inserted/updated/deleted
+ij> -- These should fail.
+select i from t1 where xmlexists(x);
+ERROR 42X01: Syntax error: Encountered ")" at line 1, column 35.
+ij> select i from t1 where xmlexists(i);
+ERROR 42X01: Syntax error: Encountered ")" at line 1, column 35.
+ij> select i from t1 where xmlexists('//*');
+ERROR 42X01: Syntax error: Encountered ")" at line 1, column 39.
+ij> select i from t1 where xmlexists('//*' x);
+ERROR 42X01: Syntax error: Encountered "x" at line 1, column 40.
+ij> select i from t1 where xmlexists('//*' passing x);
+ERROR 42X01: Syntax error: Encountered "x" at line 1, column 48.
+ij> select i from t1 where xmlexists('//*' passing by ref x);
+ERROR X0X18: XML feature not supported: 'BY REF'.
+ij> select i from t1 where xmlexists('//*' passing by value i);
+ERROR 42Y95: The 'XMLExists' operator with a left operand type of 'CHAR' and a right operand type of 'INTEGER' is not supported.
+ij> -- These should succeed.
+select i from t1 where xmlexists('//*' passing by value x);
+I          
+-----
+1          
+5          
+6          
+7          
+ij> select i from t1 where xmlexists('//person' passing by value x);
+I          
+-----
+ij> select i from t1 where xmlexists('//lets' passing by value x);
+I          
+-----
+7          
+ij> select xmlexists('//lets' passing by value x) from t1;
+1     
+-----
+0     
+NULL  
+NULL  
+NULL  
+0     
+0     
+1     
+ij> select xmlexists('//try[text()='' this out '']' passing by value x) from t1;
+1     
+-----
+0     
+NULL  
+NULL  
+NULL  
+0     
+0     
+1     
+ij> select xmlexists('//let' passing by value x) from t1;
+1     
+-----
+0     
+NULL  
+NULL  
+NULL  
+0     
+0     
+0     
+ij> select xmlexists('//try[text()='' this in '']' passing by value x) from t1;
+1     
+-----
+0     
+NULL  
+NULL  
+NULL  
+0     
+0     
+0     
+ij> select i, xmlexists('//let' passing by value x) from t1;
+I |2     
+-----
+1 |0     
+2 |NULL  
+4 |NULL  
+3 |NULL  
+5 |0     
+6 |0     
+7 |0     
+ij> select i, xmlexists('//lets' passing by value x) from t1;
+I |2     
+-----
+1 |0     
+2 |NULL  
+4 |NULL  
+3 |NULL  
+5 |0     
+6 |0     
+7 |1     
+ij> values xmlexists('//let' passing by value xmlparse(document '<lets> try this </lets>' preserve whitespace));
+1     
+-----
+0     
+ij> values xmlexists('//lets' passing by value xmlparse(document '<lets> try this </lets>' preserve whitespace));
+1     
+-----
+1     
+ij> select xmlserialize(x1 as clob) from t5 where xmlexists('//*' passing by value x1);
+1                                                                                                                               
+-----
+ij> select xmlserialize(x2 as clob) from t5 where xmlexists('//*' passing by value x2);
+1                                                                                                                               
+-----
+<notnull/>                                                                                                                      
+ij> select xmlserialize(x1 as clob), xmlexists('//*' passing by value xmlparse(document '<badboy/>' preserve whitespace)) from t5;
+1 |2     
+-----
+NULL |1     
+ij> select xmlserialize(x1 as clob), xmlexists('//goodboy' passing by value xmlparse(document '<badboy/>' preserve whitespace)) from t5;
+1 |2     
+-----
+NULL |0     
+ij> select i, xmlserialize(x1 as char(10)), xmlserialize (x2 as char(10)) from t7;
+I |2 |3         
+-----
+1 |NULL |<ok/>     
+ij> select i from t7 where xmlexists('/ok' passing by value x1) and xmlexists('/ok' passing by value x2);
+I          
+-----
+ij> select i from t7 where xmlexists('/ok' passing by value x1) or xmlexists('/ok' passing by value x2);
+I          
+-----
+1          
+ij> -- XMLEXISTS can be used wherever a boolean function is allowed,
+----- for ex, a check constraint...
+create table t6 (i int, x xml check (xmlexists('//should' passing by value x)));
+0 rows inserted/updated/deleted
+ij> insert into t6 values (1, xmlparse(document '<should/>' preserve whitespace));
+1 row inserted/updated/deleted
+ij> insert into t6 values (1, xmlparse(document '<shouldnt/>' preserve whitespace));
+ERROR 23513: The check constraint 'xxxxGENERATED-IDxxxx' was violated while performing an INSERT or UPDATE on table 'APP.T6'.
+ij> select xmlserialize(x as char(20)) from t6;
+1                   
+-----
+<should/>           
+ij> -- Do some namespace queries/examples.
+create table t8 (i int, x xml);
+0 rows inserted/updated/deleted
+ij> insert into t8 values (1, xmlparse(document '<a:hi xmlns:a="http://www.hi.there"/>' preserve whitespace));
+1 row inserted/updated/deleted
+ij> insert into t8 values (2, xmlparse(document '<b:hi xmlns:b="http://www.hi.there"/>' preserve whitespace));
+1 row inserted/updated/deleted
+ij> insert into t8 values (3, xmlparse(document '<a:bye xmlns:a="http://www.good.bye"/>' preserve whitespace));
+1 row inserted/updated/deleted
+ij> insert into t8 values (4, xmlparse(document '<b:bye xmlns:b="http://www.hi.there"/>' preserve whitespace));
+1 row inserted/updated/deleted
+ij> insert into t8 values (5, xmlparse(document '<hi/>' preserve whitespace));
+1 row inserted/updated/deleted
+ij> select xmlexists('//child::*[name()="none"]' passing by value x) from t8;
+1     
+-----
+0     
+0     
+0     
+0     
+0     
+ij> select xmlexists('//child::*[name()=''hi'']' passing by value x) from t8;
+1     
+-----
+0     
+0     
+0     
+0     
+1     
+ij> select xmlexists('//child::*[local-name()=''hi'']' passing by value x) from t8;
+1     
+-----
+1     
+1     
+0     
+0     
+1     
+ij> select xmlexists('//child::*[local-name()=''bye'']' passing by value x) from t8;
+1     
+-----
+0     
+0     
+1     
+1     
+0     
+ij> select xmlexists('//*[namespace::*[string()=''http://www.hi.there'']]' passing by value x) from t8;
+1     
+-----
+1     
+1     
+0     
+1     
+0     
+ij> select xmlexists('//*[namespace::*[string()=''http://www.good.bye'']]' passing by value x) from t8;
+1     
+-----
+0     
+0     
+1     
+0     
+0     
+ij> select xmlexists('//child::*[local-name()=''hi'' and namespace::*[string()=''http://www.hi.there'']]' passing by value x) from t8;
+1     
+-----
+1     
+1     
+0     
+0     
+0     
+ij> select xmlexists('//child::*[local-name()=''bye'' and namespace::*[string()=''http://www.good.bye'']]' passing by value x) from t8;
+1     
+-----
+0     
+0     
+1     
+0     
+0     
+ij> select xmlexists('//child::*[local-name()=''bye'' and namespace::*[string()=''http://www.hi.there'']]' passing by value x) from t8;
+1     
+-----
+0     
+0     
+0     
+1     
+0     
+ij> -- clean up.
+drop table t0;
+0 rows inserted/updated/deleted
+ij> drop table t1;
+0 rows inserted/updated/deleted
+ij> drop table t2;
+0 rows inserted/updated/deleted
+ij> drop table t3;
+0 rows inserted/updated/deleted
+ij> drop table t4;
+0 rows inserted/updated/deleted
+ij> drop table t5;
+0 rows inserted/updated/deleted
+ij> drop table t6;
+0 rows inserted/updated/deleted
+ij> drop table t7;
+0 rows inserted/updated/deleted
+ij> drop table t8;
+0 rows inserted/updated/deleted
+ij> 

Propchange: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/xml_general.out
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message