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 dj...@apache.org on 2004/09/24 19:33:21 UTC

svn commit: rev 47170 - in incubator/derby/code/trunk: . java/engine/org/apache/derby/iapi/services/cache java/engine/org/apache/derby/iapi/services/classfile java/engine/org/apache/derby/iapi/services/stream java/engine/org/apache/derby/iapi/services/uuid java/engine/org/apache/derby/iapi/sql java/engine/org/apache/derby/iapi/sql/compile java/engine/org/apache/derby/impl/sql/compile java/tools/org/apache/derby/impl/tools/ij java/tools/org/apache/derby/impl/tools/sysinfo java/tools/org/apache/derby/tools

Author: djd
Date: Fri Sep 24 10:33:20 2004
New Revision: 47170

Modified:
   incubator/derby/code/trunk/BUILDING.txt   (props changed)
   incubator/derby/code/trunk/build.xml   (props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/cache/SizedCacheable.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/AttributeEntry.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/Attributes.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Double_info.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Float_info.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Index_info.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Integer_info.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassEnumeration.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassFormatOutput.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassHolder.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassInput.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassInvestigator.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassMember.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ConstantPoolEntry.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/stream/HeaderPrintWriter.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/stream/InfoStreams.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/stream/PrintWriterGetHeader.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/uuid/UUIDFactory.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/Activation.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/LanguageFactory.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/LanguageProperties.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ParameterValueSet.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/PreparedStatement.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ResultColumnDescriptor.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ResultDescription.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ResultSet.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/Row.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/Statement.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StatementType.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StatementUtil.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StorablePreparedStatement.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/AccessPath.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SQLToJavaValueNode.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StatementNode.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticClassFieldReferenceNode.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StringSlicer.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SubqueryList.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SubqueryNode.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SumAvgAggregateDefinition.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableElementList.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableElementNode.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableName.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableOperatorNode.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TestConstraintNode.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TimeTypeCompiler.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TimestampOperatorNode.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TimestampTypeCompiler.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/Token.java   (contents, props changed)
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TransactionStatementNode.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ConnectionEnv.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/Main.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/Main14.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ParseException.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/Session.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/StatementFinder.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/UCode_CharStream.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijConnectionResult.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijException.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijExceptionResult.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijFatalException.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijMultiResult.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijResult.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijVectorResult.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijWarningResult.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTestCase.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTestSuite.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTester.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTime.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/util.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/utilMain.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/utilMain14.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/xaAbstractHelper.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/xaHelper.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/sysinfo/Main.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/sysinfo/ZipInfoProperties.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/tools/JDBCDisplayUtil.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/tools/URLCheck.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/tools/dblook.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/tools/ij.java   (contents, props changed)
   incubator/derby/code/trunk/java/tools/org/apache/derby/tools/sysinfo.java   (contents, props changed)
Log:
Set svn:eol-style to native on remaining text files.


Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/cache/SizedCacheable.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/cache/SizedCacheable.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/cache/SizedCacheable.java	Fri Sep 24 10:33:20 2004
@@ -1,40 +1,40 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.cache
-   (C) Copyright IBM Corp. 2002, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.cache;
-
-/**
- * This interface extends the Cacheable interface (@see Cacheable) with a method that
- * estimates the size of the Cacheable object, in bytes. CacheManagers constructed with the SizedCacheFactory
- * interface regulate the total estimated cache size, in bytes.
- * CacheManagers constructed with the CacheFactory use regulate the total number of cache entries.
- *
- * @see Cacheable
- * @see SizedCacheableFactory
- * @see CacheFactory
- *
- * @author Jack Klebanoff
- */
-
-public interface SizedCacheable extends Cacheable
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-
-    public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2002_2004;
-
-    /**
-     * Get the estimated size of the cacheable object.
-     *
-     * @return the estimated size, in bytes
-     */
-    public int getSize();
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.cache
+   (C) Copyright IBM Corp. 2002, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.cache;
+
+/**
+ * This interface extends the Cacheable interface (@see Cacheable) with a method that
+ * estimates the size of the Cacheable object, in bytes. CacheManagers constructed with the SizedCacheFactory
+ * interface regulate the total estimated cache size, in bytes.
+ * CacheManagers constructed with the CacheFactory use regulate the total number of cache entries.
+ *
+ * @see Cacheable
+ * @see SizedCacheableFactory
+ * @see CacheFactory
+ *
+ * @author Jack Klebanoff
+ */
+
+public interface SizedCacheable extends Cacheable
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+
+    public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2002_2004;
+
+    /**
+     * Get the estimated size of the cacheable object.
+     *
+     * @return the estimated size, in bytes
+     */
+    public int getSize();
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/AttributeEntry.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/AttributeEntry.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/AttributeEntry.java	Fri Sep 24 10:33:20 2004
@@ -1,58 +1,58 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.classfile
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.classfile;
-
-import java.io.IOException;
-
-class AttributeEntry {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-
-	private int attribute_name_index;
-	private ClassFormatOutput infoOut;
-	byte[] infoIn;
-
-	AttributeEntry(int name_index, ClassFormatOutput info) {
-		super();
-
-		attribute_name_index = name_index;
-		this.infoOut = info;
-	}
-
-
-	AttributeEntry(ClassInput in) throws IOException {
-		attribute_name_index = in.getU2();
-		infoIn = in.getU1Array(in.getU4());
-	}
-
-	int getNameIndex() { return attribute_name_index; }
-
-	void put(ClassFormatOutput out) throws IOException {
-		out.putU2(attribute_name_index);
-		if (infoOut != null) {
-			out.putU4(infoOut.size());
-			infoOut.writeTo(out);
-		} else {
-			out.putU4(infoIn.length);
-			out.write(infoIn);
-		}
-	}
-
-	/**
-		This is exact.
-	*/
-	int classFileSize() {
-		return 2 + 4 + 
-			((infoOut != null) ? infoOut.size() : infoIn.length);
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.classfile
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.classfile;
+
+import java.io.IOException;
+
+class AttributeEntry {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+
+	private int attribute_name_index;
+	private ClassFormatOutput infoOut;
+	byte[] infoIn;
+
+	AttributeEntry(int name_index, ClassFormatOutput info) {
+		super();
+
+		attribute_name_index = name_index;
+		this.infoOut = info;
+	}
+
+
+	AttributeEntry(ClassInput in) throws IOException {
+		attribute_name_index = in.getU2();
+		infoIn = in.getU1Array(in.getU4());
+	}
+
+	int getNameIndex() { return attribute_name_index; }
+
+	void put(ClassFormatOutput out) throws IOException {
+		out.putU2(attribute_name_index);
+		if (infoOut != null) {
+			out.putU4(infoOut.size());
+			infoOut.writeTo(out);
+		} else {
+			out.putU4(infoIn.length);
+			out.write(infoIn);
+		}
+	}
+
+	/**
+		This is exact.
+	*/
+	int classFileSize() {
+		return 2 + 4 + 
+			((infoOut != null) ? infoOut.size() : infoIn.length);
+	}
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/Attributes.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/Attributes.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/Attributes.java	Fri Sep 24 10:33:20 2004
@@ -1,47 +1,47 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.classfile
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.classfile;
-
-import java.util.Vector;
-
-import java.io.IOException;
-
-class Attributes extends Vector {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-	private int classFileSize;
-
-	Attributes(int count) {
-		super(count);
-	}
-
-	void put(ClassFormatOutput out) throws IOException {
-		int size = size();
-		for (int i = 0; i < size; i++) {
-			((AttributeEntry) elementAt(i)).put(out);
-		}
-	}
-
-	int classFileSize() {
-		return classFileSize;
-	}
-
-	/**
-	*/
-
-	void addEntry(AttributeEntry item) {
-		addElement(item);
-		classFileSize += item.classFileSize();
-	}
-}
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.classfile
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.classfile;
+
+import java.util.Vector;
+
+import java.io.IOException;
+
+class Attributes extends Vector {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+	private int classFileSize;
+
+	Attributes(int count) {
+		super(count);
+	}
+
+	void put(ClassFormatOutput out) throws IOException {
+		int size = size();
+		for (int i = 0; i < size; i++) {
+			((AttributeEntry) elementAt(i)).put(out);
+		}
+	}
+
+	int classFileSize() {
+		return classFileSize;
+	}
+
+	/**
+	*/
+
+	void addEntry(AttributeEntry item) {
+		addElement(item);
+		classFileSize += item.classFileSize();
+	}
+}
+

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Double_info.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Double_info.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Double_info.java	Fri Sep 24 10:33:20 2004
@@ -1,56 +1,56 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.classfile
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.classfile;
-
-import org.apache.derby.iapi.services.classfile.VMDescriptor;
-
-import java.io.IOException;
-
-/** Double Constant - page 97 - Section 4.4.5 */
-final class CONSTANT_Double_info extends ConstantPoolEntry {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-	private final double value;
-
-	CONSTANT_Double_info(double value) {
-		super(VMDescriptor.CONSTANT_Double);
-		doubleSlot = true; //See page 98.
-		this.value = value;
-	}
-
-	public int hashCode() {
-		return (int) value;
-	}
-
-	int classFileSize() {
-		// 1 (tag) + 8 (double length)
-		return 1 + 8;
-	}
-	void put(ClassFormatOutput out) throws IOException {
-		super.put(out);
-		out.writeDouble(value);
-	}
-
-	public boolean equals(Object other) {
-
-		// check it is the right type
-		if (other instanceof CONSTANT_Double_info) {
-		
-			return value == ((CONSTANT_Double_info) other).value;
-		}
-
-		return false;
-	}
-}
-
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.classfile
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.classfile;
+
+import org.apache.derby.iapi.services.classfile.VMDescriptor;
+
+import java.io.IOException;
+
+/** Double Constant - page 97 - Section 4.4.5 */
+final class CONSTANT_Double_info extends ConstantPoolEntry {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+	private final double value;
+
+	CONSTANT_Double_info(double value) {
+		super(VMDescriptor.CONSTANT_Double);
+		doubleSlot = true; //See page 98.
+		this.value = value;
+	}
+
+	public int hashCode() {
+		return (int) value;
+	}
+
+	int classFileSize() {
+		// 1 (tag) + 8 (double length)
+		return 1 + 8;
+	}
+	void put(ClassFormatOutput out) throws IOException {
+		super.put(out);
+		out.writeDouble(value);
+	}
+
+	public boolean equals(Object other) {
+
+		// check it is the right type
+		if (other instanceof CONSTANT_Double_info) {
+		
+			return value == ((CONSTANT_Double_info) other).value;
+		}
+
+		return false;
+	}
+}
+
+

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Float_info.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Float_info.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Float_info.java	Fri Sep 24 10:33:20 2004
@@ -1,55 +1,55 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.classfile
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.classfile;
-
-import org.apache.derby.iapi.services.classfile.VMDescriptor;
-import java.io.IOException;
-
-
-/** Float Constant - page 96 */
-final class CONSTANT_Float_info extends ConstantPoolEntry {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-	private final float value;
-
-	CONSTANT_Float_info(float value) {
-		super(VMDescriptor.CONSTANT_Float);
-		this.value = value;
-	}
-
-	public int hashCode() {
-		return (int) value;
-	}
-
-	public boolean equals(Object other) {
-
-		// check it is the right type
-		if (other instanceof CONSTANT_Float_info) {
-		
-			return value == ((CONSTANT_Float_info) other).value;
-		}
-
-		return false;
-	}
-
-	int classFileSize() {
-		// 1 (tag) + 4 (float length)
-		return 1 + 4;
-	}
-
-	void put(ClassFormatOutput out) throws IOException {
-		super.put(out);
-		out.writeFloat(value);
-	}
-}
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.classfile
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.classfile;
+
+import org.apache.derby.iapi.services.classfile.VMDescriptor;
+import java.io.IOException;
+
+
+/** Float Constant - page 96 */
+final class CONSTANT_Float_info extends ConstantPoolEntry {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+	private final float value;
+
+	CONSTANT_Float_info(float value) {
+		super(VMDescriptor.CONSTANT_Float);
+		this.value = value;
+	}
+
+	public int hashCode() {
+		return (int) value;
+	}
+
+	public boolean equals(Object other) {
+
+		// check it is the right type
+		if (other instanceof CONSTANT_Float_info) {
+		
+			return value == ((CONSTANT_Float_info) other).value;
+		}
+
+		return false;
+	}
+
+	int classFileSize() {
+		// 1 (tag) + 4 (float length)
+		return 1 + 4;
+	}
+
+	void put(ClassFormatOutput out) throws IOException {
+		super.put(out);
+		out.writeFloat(value);
+	}
+}
+

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Index_info.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Index_info.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Index_info.java	Fri Sep 24 10:33:20 2004
@@ -1,85 +1,85 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.classfile
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.classfile;
-
-import org.apache.derby.iapi.services.classfile.VMDescriptor;
-
-import java.io.IOException;
-
- /**
-
-  A generic constant pool entry for entries that simply hold indexes
-  into other entries.
-
-  <BR>
-  Ref Constant Pool Entry  - page 94 - Section 4.4.2	- Two indexes
-  <BR>
-  NameAndType Constant Pool Entry  - page 99 - Section 4.4.6 - Two indexes
-  <BR>
-  String Constant Pool Entry - page 96 - Section 4.4.3 - One index
-  <BR>
-  Class Reference Constant Pool Entry - page 93 - Section 4.4.1 - One index
-
-*/
-final class CONSTANT_Index_info extends ConstantPoolEntry {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-
-	private int i1;
-	private int i2;
-
-	CONSTANT_Index_info(int tag, int i1, int i2) {
-		super(tag);
-		this.i1 = i1;
-		this.i2 = i2;
-	}
-
-	public int hashCode() {
-		return (tag << 16) | ((i1 << 8) ^ i2);
-	}
-
-	public boolean equals(Object other) {
-		if (other instanceof CONSTANT_Index_info) {
-			CONSTANT_Index_info o = (CONSTANT_Index_info) other;
-
-			return (tag == o.tag) && (i1 == o.i1) && (i2 == o.i2);			
-		}
-		return false;
-	}
-
-
-	/**
-		Used when searching 
-	*/
-	void set(int tag, int i1, int i2) {
-		this.tag = tag;
-		this.i1 = i1;
-		this.i2 = i2;
-	}
-
-	int classFileSize() {
-		// 1 (tag) + 2 (index length) [ + 2 (index length) ]
-		return 1 + 2 + ((i2 != 0) ? 2 : 0);
-	}
-
-	void put(ClassFormatOutput out) throws IOException {
-		super.put(out);
-		out.putU2(i1);
-		if (i2 != 0)
-			out.putU2(i2);
-	}
-
-	public int getI1() { return i1; }
-
-	public int getI2() { return i2; }
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.classfile
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.classfile;
+
+import org.apache.derby.iapi.services.classfile.VMDescriptor;
+
+import java.io.IOException;
+
+ /**
+
+  A generic constant pool entry for entries that simply hold indexes
+  into other entries.
+
+  <BR>
+  Ref Constant Pool Entry  - page 94 - Section 4.4.2	- Two indexes
+  <BR>
+  NameAndType Constant Pool Entry  - page 99 - Section 4.4.6 - Two indexes
+  <BR>
+  String Constant Pool Entry - page 96 - Section 4.4.3 - One index
+  <BR>
+  Class Reference Constant Pool Entry - page 93 - Section 4.4.1 - One index
+
+*/
+final class CONSTANT_Index_info extends ConstantPoolEntry {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+
+	private int i1;
+	private int i2;
+
+	CONSTANT_Index_info(int tag, int i1, int i2) {
+		super(tag);
+		this.i1 = i1;
+		this.i2 = i2;
+	}
+
+	public int hashCode() {
+		return (tag << 16) | ((i1 << 8) ^ i2);
+	}
+
+	public boolean equals(Object other) {
+		if (other instanceof CONSTANT_Index_info) {
+			CONSTANT_Index_info o = (CONSTANT_Index_info) other;
+
+			return (tag == o.tag) && (i1 == o.i1) && (i2 == o.i2);			
+		}
+		return false;
+	}
+
+
+	/**
+		Used when searching 
+	*/
+	void set(int tag, int i1, int i2) {
+		this.tag = tag;
+		this.i1 = i1;
+		this.i2 = i2;
+	}
+
+	int classFileSize() {
+		// 1 (tag) + 2 (index length) [ + 2 (index length) ]
+		return 1 + 2 + ((i2 != 0) ? 2 : 0);
+	}
+
+	void put(ClassFormatOutput out) throws IOException {
+		super.put(out);
+		out.putU2(i1);
+		if (i2 != 0)
+			out.putU2(i2);
+	}
+
+	public int getI1() { return i1; }
+
+	public int getI2() { return i2; }
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Integer_info.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Integer_info.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/CONSTANT_Integer_info.java	Fri Sep 24 10:33:20 2004
@@ -1,54 +1,54 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.classfile
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.classfile;
-
-import org.apache.derby.iapi.services.classfile.VMDescriptor;
-import java.io.IOException;
-
-/** Integer Constant - page 96 */
-class CONSTANT_Integer_info extends ConstantPoolEntry {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-	private final int value;
-
-	CONSTANT_Integer_info(int value) {
-		super(VMDescriptor.CONSTANT_Integer);
-		this.value = value;
-	}
-
-	public int hashCode() {
-		return value;
-	}
-
-	void put(ClassFormatOutput out) throws IOException {
-		super.put(out);
-		out.putU4(value);
-	}
-
-	public boolean equals(Object other) {
-
-		// check it is the right type
-		if (other instanceof CONSTANT_Integer_info) {
-		
-			return value == ((CONSTANT_Integer_info) other).value;
-		}
-
-		return false;
-	}
-
-	int classFileSize() {
-		// 1 (tag) + 4 (int length)
-		return 1 + 4;
-	}
-}
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.classfile
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.classfile;
+
+import org.apache.derby.iapi.services.classfile.VMDescriptor;
+import java.io.IOException;
+
+/** Integer Constant - page 96 */
+class CONSTANT_Integer_info extends ConstantPoolEntry {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+	private final int value;
+
+	CONSTANT_Integer_info(int value) {
+		super(VMDescriptor.CONSTANT_Integer);
+		this.value = value;
+	}
+
+	public int hashCode() {
+		return value;
+	}
+
+	void put(ClassFormatOutput out) throws IOException {
+		super.put(out);
+		out.putU4(value);
+	}
+
+	public boolean equals(Object other) {
+
+		// check it is the right type
+		if (other instanceof CONSTANT_Integer_info) {
+		
+			return value == ((CONSTANT_Integer_info) other).value;
+		}
+
+		return false;
+	}
+
+	int classFileSize() {
+		// 1 (tag) + 4 (int length)
+		return 1 + 4;
+	}
+}
+

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassEnumeration.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassEnumeration.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassEnumeration.java	Fri Sep 24 10:33:20 2004
@@ -1,194 +1,194 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.classfile
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.classfile;
-
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.StringTokenizer;
-import org.apache.derby.iapi.services.classfile.VMDescriptor;
-
-/**
-	An enumeration that filters only classes
-	from the enumeration of the class pool.
-
-	Code has been added to also include classes referenced in method and
-	field signatures.
-*/
-
-
-class ClassEnumeration implements Enumeration {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-	ClassHolder	cpt;
-	Enumeration			inner;
-	CONSTANT_Index_info	position;
-	HashSet           foundClasses;
-    Enumeration         classList;
-
-    ClassEnumeration(   ClassHolder cpt,
-                        Enumeration e,
-                        Enumeration methods,
-                        Enumeration fields)
-    {
-		this.cpt = cpt;
-		inner = e;
-		foundClasses = new HashSet(30, 0.8f);
-		findMethodReferences(methods, foundClasses);
-		findFieldReferences(fields, foundClasses);
-		findClassReferences(foundClasses);
-		classList = java.util.Collections.enumeration(foundClasses);
-
-	}
-
-	public boolean hasMoreElements() {
-	    return classList.hasMoreElements();
-	}
-
-	// uses cpt and inner
-	private void findClassReferences(HashSet foundClasses)
-	{
-
-		ConstantPoolEntry	item;
-		CONSTANT_Index_info	ref;
-
-
-		while (inner.hasMoreElements())
-		{
-			item = (ConstantPoolEntry) inner.nextElement();
-			if (item == null)
-				continue;
-			if (item.getTag() == VMDescriptor.CONSTANT_Class)
-			{
-				ref = (CONSTANT_Index_info) item;
-
-				String className = cpt.className(ref.getIndex());
-
-				// if this is an array type, distillClasses can
-				// handle it
-                if (className.startsWith("["))
-                {
-                   distillClasses(className, foundClasses);
-                   continue;
-                }
-
-                // now we've got either a primitive type or a classname
-                // primitive types are all a single char
-
-                if (className.length() > 1)
-                {
-                    //we've got a class
-                    if (className.startsWith("java"))
-                    {
-                        //skip it
-                        continue;
-                    }
-
-                    foundClasses.add(className);
-                }
-			}
-		}
-
-	}
-
-	private void findMethodReferences(  Enumeration methods,
-	                                    HashSet foundClasses)
-	{
-	    while (methods.hasMoreElements())
-	    {
-	        ClassMember member = (ClassMember) methods.nextElement();
-	        String description = member.getDescriptor();
-	        distillClasses(description, foundClasses);
-	    }
-	}
-
-	private void findFieldReferences(   Enumeration fields,
-	                                    HashSet foundClasses)
-	{
-	    while (fields.hasMoreElements())
-	    {
-	        ClassMember member = (ClassMember) fields.nextElement();
-	        String description = member.getDescriptor();
-	        distillClasses(description, foundClasses);
-	    }
-	}
-
-	void distillClasses(String fieldOrMethodSig, HashSet foundClasses)
-	{
-	    if (fieldOrMethodSig == null || fieldOrMethodSig.length() < 1)
-	    {
-	        //empty string
-	        return;
-	    }
-
-	    if (fieldOrMethodSig.charAt(0) != '(')
-	    {
-    	    // first time through, we're dealing with a field here
-    	    // otherwise, it is a token from a method signature
-
-            int classNameStart = fieldOrMethodSig.indexOf('L');
-
-            if (classNameStart == -1)
-            {
-                // no class in the type, so stop
-                return;
-            }
-
-            // chop off any leading ['s or other Java-primitive type
-            // signifiers (like I or L) *AND* substitute the dots
-	        String fieldType =
-	            fieldOrMethodSig.substring(classNameStart + 1).replace('/', '.');
-
-            // we have to check for the semi-colon in case we are
-            // actually looking at a token from a method signature
-	        if (fieldType.endsWith(";"))
-	        {
-    	        fieldType = fieldType.substring(0,fieldType.length()-1);
-            }
-
-	        if (fieldType.startsWith("java"))
-	        {
-	            return;     // it's a java base class and we don't care about
-	                        // that either
-	        }
-
-            foundClasses.add(fieldType);
-            return;
-         }
-         else
-         {
-            // it's a method signature
-            StringTokenizer tokens = new StringTokenizer(fieldOrMethodSig, "();[");
-            while (tokens.hasMoreElements())
-            {
-                String aToken = (String) tokens.nextToken();
-                // because of the semi-colon delimiter in the tokenizer, we
-                // can have only one class name per token and it must be the
-                // last item in the token
-                int classNameStart = aToken.indexOf('L');
-                if (classNameStart != -1)
-                {
-                    distillClasses(aToken, foundClasses);
-                }
-                else
-                {
-                    continue;
-                }
-            }
-         }
-     }
-
-	public Object nextElement() {
-        return classList.nextElement();
-	}
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.classfile
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.classfile;
+
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.StringTokenizer;
+import org.apache.derby.iapi.services.classfile.VMDescriptor;
+
+/**
+	An enumeration that filters only classes
+	from the enumeration of the class pool.
+
+	Code has been added to also include classes referenced in method and
+	field signatures.
+*/
+
+
+class ClassEnumeration implements Enumeration {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+	ClassHolder	cpt;
+	Enumeration			inner;
+	CONSTANT_Index_info	position;
+	HashSet           foundClasses;
+    Enumeration         classList;
+
+    ClassEnumeration(   ClassHolder cpt,
+                        Enumeration e,
+                        Enumeration methods,
+                        Enumeration fields)
+    {
+		this.cpt = cpt;
+		inner = e;
+		foundClasses = new HashSet(30, 0.8f);
+		findMethodReferences(methods, foundClasses);
+		findFieldReferences(fields, foundClasses);
+		findClassReferences(foundClasses);
+		classList = java.util.Collections.enumeration(foundClasses);
+
+	}
+
+	public boolean hasMoreElements() {
+	    return classList.hasMoreElements();
+	}
+
+	// uses cpt and inner
+	private void findClassReferences(HashSet foundClasses)
+	{
+
+		ConstantPoolEntry	item;
+		CONSTANT_Index_info	ref;
+
+
+		while (inner.hasMoreElements())
+		{
+			item = (ConstantPoolEntry) inner.nextElement();
+			if (item == null)
+				continue;
+			if (item.getTag() == VMDescriptor.CONSTANT_Class)
+			{
+				ref = (CONSTANT_Index_info) item;
+
+				String className = cpt.className(ref.getIndex());
+
+				// if this is an array type, distillClasses can
+				// handle it
+                if (className.startsWith("["))
+                {
+                   distillClasses(className, foundClasses);
+                   continue;
+                }
+
+                // now we've got either a primitive type or a classname
+                // primitive types are all a single char
+
+                if (className.length() > 1)
+                {
+                    //we've got a class
+                    if (className.startsWith("java"))
+                    {
+                        //skip it
+                        continue;
+                    }
+
+                    foundClasses.add(className);
+                }
+			}
+		}
+
+	}
+
+	private void findMethodReferences(  Enumeration methods,
+	                                    HashSet foundClasses)
+	{
+	    while (methods.hasMoreElements())
+	    {
+	        ClassMember member = (ClassMember) methods.nextElement();
+	        String description = member.getDescriptor();
+	        distillClasses(description, foundClasses);
+	    }
+	}
+
+	private void findFieldReferences(   Enumeration fields,
+	                                    HashSet foundClasses)
+	{
+	    while (fields.hasMoreElements())
+	    {
+	        ClassMember member = (ClassMember) fields.nextElement();
+	        String description = member.getDescriptor();
+	        distillClasses(description, foundClasses);
+	    }
+	}
+
+	void distillClasses(String fieldOrMethodSig, HashSet foundClasses)
+	{
+	    if (fieldOrMethodSig == null || fieldOrMethodSig.length() < 1)
+	    {
+	        //empty string
+	        return;
+	    }
+
+	    if (fieldOrMethodSig.charAt(0) != '(')
+	    {
+    	    // first time through, we're dealing with a field here
+    	    // otherwise, it is a token from a method signature
+
+            int classNameStart = fieldOrMethodSig.indexOf('L');
+
+            if (classNameStart == -1)
+            {
+                // no class in the type, so stop
+                return;
+            }
+
+            // chop off any leading ['s or other Java-primitive type
+            // signifiers (like I or L) *AND* substitute the dots
+	        String fieldType =
+	            fieldOrMethodSig.substring(classNameStart + 1).replace('/', '.');
+
+            // we have to check for the semi-colon in case we are
+            // actually looking at a token from a method signature
+	        if (fieldType.endsWith(";"))
+	        {
+    	        fieldType = fieldType.substring(0,fieldType.length()-1);
+            }
+
+	        if (fieldType.startsWith("java"))
+	        {
+	            return;     // it's a java base class and we don't care about
+	                        // that either
+	        }
+
+            foundClasses.add(fieldType);
+            return;
+         }
+         else
+         {
+            // it's a method signature
+            StringTokenizer tokens = new StringTokenizer(fieldOrMethodSig, "();[");
+            while (tokens.hasMoreElements())
+            {
+                String aToken = (String) tokens.nextToken();
+                // because of the semi-colon delimiter in the tokenizer, we
+                // can have only one class name per token and it must be the
+                // last item in the token
+                int classNameStart = aToken.indexOf('L');
+                if (classNameStart != -1)
+                {
+                    distillClasses(aToken, foundClasses);
+                }
+                else
+                {
+                    continue;
+                }
+            }
+         }
+     }
+
+	public Object nextElement() {
+        return classList.nextElement();
+	}
+
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassFormatOutput.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassFormatOutput.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassFormatOutput.java	Fri Sep 24 10:33:20 2004
@@ -1,68 +1,68 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.classfile
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.classfile;
-
-import org.apache.derby.iapi.services.io.AccessibleByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-
-/** A wrapper around DataOutputStream to provide input functions in terms
-    of the types defined on pages 83.
-
-	For this types use these methods of DataOutputStream
-	<UL>
-	<LI>float - writeFloat
-	<LI>long - writeLong
-	<LI>double - writeDouble
-	<LI>UTF/String - writeUTF
-	<LI>U1Array - write(byte[])
-	</UL>
- */
-
-public final class ClassFormatOutput extends DataOutputStream {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-
-	public ClassFormatOutput() {
-		this(512);
-	}
-
-	public ClassFormatOutput(int size) {
-		super(new AccessibleByteArrayOutputStream(size));
-	}
-
-	public void putU1(int i) throws IOException {
-		write(i);
-	}
-	public void putU2(int i) throws IOException {
-		write(i >> 8);
-		write(i);
-	}
-	public void putU4(int i) throws IOException {
-		writeInt(i);
-	}
-
-	public void writeTo(OutputStream outTo) throws IOException {
-		((AccessibleByteArrayOutputStream) out).writeTo(outTo);
-	}
-
-	/**
-		Get a reference to the data array the class data is being built
-		in. No copy is made.
-	*/
-	public byte[] getData() {
-		return ((AccessibleByteArrayOutputStream) out).getInternalByteArray();
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.classfile
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.classfile;
+
+import org.apache.derby.iapi.services.io.AccessibleByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+
+/** A wrapper around DataOutputStream to provide input functions in terms
+    of the types defined on pages 83.
+
+	For this types use these methods of DataOutputStream
+	<UL>
+	<LI>float - writeFloat
+	<LI>long - writeLong
+	<LI>double - writeDouble
+	<LI>UTF/String - writeUTF
+	<LI>U1Array - write(byte[])
+	</UL>
+ */
+
+public final class ClassFormatOutput extends DataOutputStream {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+
+	public ClassFormatOutput() {
+		this(512);
+	}
+
+	public ClassFormatOutput(int size) {
+		super(new AccessibleByteArrayOutputStream(size));
+	}
+
+	public void putU1(int i) throws IOException {
+		write(i);
+	}
+	public void putU2(int i) throws IOException {
+		write(i >> 8);
+		write(i);
+	}
+	public void putU4(int i) throws IOException {
+		writeInt(i);
+	}
+
+	public void writeTo(OutputStream outTo) throws IOException {
+		((AccessibleByteArrayOutputStream) out).writeTo(outTo);
+	}
+
+	/**
+		Get a reference to the data array the class data is being built
+		in. No copy is made.
+	*/
+	public byte[] getData() {
+		return ((AccessibleByteArrayOutputStream) out).getInternalByteArray();
+	}
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassHolder.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassHolder.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassHolder.java	Fri Sep 24 10:33:20 2004
@@ -1,894 +1,894 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.classfile
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.classfile;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Enumeration;
-
-import java.io.IOException;
-import java.util.Vector;
-
-import org.apache.derby.iapi.util.ByteArray;
-import org.apache.derby.iapi.services.classfile.VMDescriptor;
-import org.apache.derby.iapi.services.classfile.VMDescriptor;
-
-import java.util.Hashtable;
-import java.util.Vector;
-import java.util.Enumeration;
-
-
-/** Based upon "THE class FILE FORMAT" chapter of "The Java Virtual Machine Specification"
-    corresponding to version 1.0.2 of the Java Virtual Machine and 1.0.2 of the
-	Java Language Specification.
-
-    ISBN  0-201-63452-X, September 1996.
-	*/
-
-public class ClassHolder {
-	/**
-		IBM Copyright &copy notice.
-	*/
-
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-
-
-	/*
-	** Constants.
-	*/
-
-	/*
-	** Fields
-	*/
-
-	protected int access_flags;
-	protected int this_class;
-	protected int super_class;
-
-	// protected InterfacesArray interfaces; // can be null
-	protected int[] interfaces; //can be null
-
-	protected MemberTable field_info; // can be null
-	protected MemberTable method_info;	// can be null
-	protected Attributes attribute_info; // can be null
-
-	/*
-	** Fields for Constant Pool Table
-	*/
-	protected Hashtable cptHashTable;
-	protected Vector cptEntries;
-	private int cptEstimatedSize;
-
-	/**
-		Used to search for index entries to avoid object allocation
-		in the case a referecne already exists.
-	*/
-	private final CONSTANT_Index_info	searchIndex = new CONSTANT_Index_info(0, 0, 0);
-
-	/*
-	**	Constructors.
-	*/
-
-	protected ClassHolder(int estimatedConstantPoolCount) {
-		// Constant Pool Information
-		// 100 is the estimate of the number of entries that will be generated
-		cptEntries = new Vector(estimatedConstantPoolCount);
-		cptHashTable = new Hashtable(estimatedConstantPoolCount, (float)0.75);
-
-		// reserve the 0'th constant pool entry
-		cptEntries.setSize(1);
-	}
-
-
-	/**
-		This will not define a constructor -- it is up
-		to the caller to add at least one.
-	*/
-
-	public ClassHolder(String fullyQualifiedName, String superClassName,
-		int modifiers) {
-
-		this(100);
-
-		access_flags = modifiers | /* Modifier.SUPER */ 0x0020;
-
-		this_class = addClassReference(fullyQualifiedName);
-		super_class = addClassReference(superClassName);
-		method_info = new MemberTable(0);
-	}
-
-	public void put(ClassFormatOutput out) throws IOException {
-
-		/* Write out the header */
-		out.putU4(VMDescriptor.JAVA_CLASS_FORMAT_MAGIC);
-		out.putU2(VMDescriptor.JAVA_CLASS_FORMAT_MINOR_VERSION);
-		out.putU2(VMDescriptor.JAVA_CLASS_FORMAT_MAJOR_VERSION);
-
-		out.putU2(cptEntries.size());
-		cptPut(out);
-
-		out.putU2(access_flags);
-		out.putU2(this_class);
-		out.putU2(super_class);
-
-		if (interfaces != null) {
-			int ilen = interfaces.length;
-			out.putU2(ilen);
-			for (int i = 0; i < ilen; i++) {
-				out.putU2(interfaces[i]);
-			}
-		} else {
-			out.putU2(0);
-		}
-
-		if (field_info != null) {
-			out.putU2(field_info.size());
-			field_info.put(out);
-		} else {
-			out.putU2(0);
-		}
-
-		if (method_info != null) {
-			out.putU2(method_info.size());
-			method_info.put(out);
-		} else {
-			out.putU2(0);
-		}
-
-		if (attribute_info != null) {
-			out.putU2(attribute_info.size());
-			attribute_info.put(out);
-		} else {
-			out.putU2(0);
-		}
-
-	}
-
-
-	/*
-	**	Public methods from ClassHolder.
-	*/
-
-
-	public ByteArray getFileFormat() {
-
-		int classFileSize = 4 + (10 * 2);
-		classFileSize += cptEstimatedSize;
-
-		if (interfaces != null)
-			classFileSize += (interfaces.length * 2);
-
-		if (field_info != null)
-			classFileSize += field_info.classFileSize();
-
-		if (method_info != null)
-			classFileSize += method_info.classFileSize();
-
-		if (attribute_info != null)
-			classFileSize += attribute_info.classFileSize();
-
-		try {
-			ClassFormatOutput cfo = new ClassFormatOutput(classFileSize + 200);
-
-			put(cfo);
-
-			return new ByteArray(cfo.getData(), 0, cfo.size());
-
-		} catch (IOException e) {
-			return null;
-		}
-
-	}
-
-	/*
-	** Public methods from ClassMember
-	*/
-
-	/** @see ClassMember
-	*/
-	public int getModifier() { return access_flags; }
-
-	/** @see ClassMember
-	*/
-	public String getName() {
-		return className(this_class).replace('/', '.');
-	}
-	/*
-	**	Public methods from ClassHolder
-	*/
-
-	/** @see ClassHolder#addMember */
- 	public ClassMember addMember(String simpleName, String descriptor, int modifier)
-	{
-		if (SanityManager.DEBUG)
-		{
-			if (descriptor.startsWith("(")) {
-				if (method_info != null) {
-					if (method_info.find(simpleName, descriptor) != null) {
-						SanityManager.THROWASSERT("Method already exists " + simpleName + " " + descriptor);
-					}
-				}
-
-			} else {
-				if (field_info != null) {
-					if (field_info.find(simpleName, descriptor) != null) {
-						SanityManager.THROWASSERT("Field already exists " + simpleName + " " + descriptor);
-					}
-				}
-			}
-		}
-
-		CONSTANT_Utf8_info utf = addUtf8Entry(simpleName);
-
-		int nameIndex = utf.getIndex();
-		int descriptorIndex = addUtf8Entry(descriptor).getIndex();
-
-		ClassMember item = new ClassMember(this, modifier, nameIndex, descriptorIndex);
-		MemberTable mt;
-		if (descriptor.startsWith("(")) {
-			mt = method_info;
-			if (mt == null)
-				mt = method_info = new MemberTable(0);
-
-		}
-		else {
-			mt = field_info;
-			if (mt == null)
-				mt = field_info = new MemberTable(0);
-		}
-
-		mt.addEntry(item);
-		return item;
-	}
-
-	/** @see ClassHolder#addFieldReference */
-	public int addFieldReference(String className, String simpleName, String descriptor) {
-		return addReference(VMDescriptor.CONSTANT_Fieldref, className, simpleName, descriptor);
-	}
-
-	public int addFieldReference(ClassMember field) {
-		return addReference(VMDescriptor.CONSTANT_Fieldref, (ClassMember) field);
-	}
-
-	/** @see ClassHolder#addMethodReference */
-	public int addMethodReference(String className, String simpleName, String descriptor, boolean isInterface) {
-
-		int tag = isInterface ?	VMDescriptor.CONSTANT_InterfaceMethodref :
-								VMDescriptor.CONSTANT_Methodref;
-
-		return addReference(tag, className, simpleName, descriptor); 
-	}
-
-	private int addReference(int tag, String className, String simpleName, String descriptor) {
-
-		int classIndex = addClassReference(className);
-		int nameTypeIndex = addNameAndType(simpleName, descriptor);
-
-		return addIndexReference(tag, classIndex, nameTypeIndex);
-	}
-
-	private int addReference(int tag, ClassMember member) {
-
-		int nameTypeIndex = addIndexReference(VMDescriptor.CONSTANT_NameAndType,
-							member.name_index, member.descriptor_index);
-
-		return addIndexReference(tag, this_class, nameTypeIndex);
-	}
-
-	/** @see ClassHolder#addConstant */
-	public int addConstant(String value) {
-
-		return addString(value);
-	}
-
-	/** @see ClassHolder#addUtf8 */
-	public int addUtf8(String value) {
-
-		return addUtf8Entry(value).getIndex();
-	}
-
-
-	/** @see ClassHolder#addInteger */
-	public int addConstant(int value) {
-		return addDirectEntry(new CONSTANT_Integer_info(value));
-	}
-
-	/** @see ClassHolder#addFloat */
-	public int addConstant(float value) {
-		return addDirectEntry(new CONSTANT_Float_info(value));
-	}
-
-	/** @see ClassHolder#addLong */
-	public int addConstant(long value) {
-		return addDirectEntry(new CONSTANT_Long_info(value));
-	}
-
-	/** @see ClassHolder#addDouble */
-	public int addConstant(double value) {
-		return addDirectEntry(new CONSTANT_Double_info(value));
-	}
-
-
-	/** @see ClassMember
-	*/
-	public int getConstantPoolIndex() { return this_class; }
-
-	public void addAttribute(String attributeName, ClassFormatOutput info) {
-
-		if (attribute_info == null)
-			attribute_info = new Attributes(1);
-
-
-		CONSTANT_Utf8_info autf = addUtf8Entry(attributeName);
-
-		int index = autf.getIndex();
-
-		attribute_info.addEntry(new AttributeEntry(index, info));
-	}
-
-
-	public String getSuperClassName() {
-		if (super_class == 0)
-			return null;
-		else
-			return className(super_class).replace('/', '.');
-	}
-
-
-/*
-    public ClassMember getMemberReference(String fullyQualifiedClassName, String simpleName, String descriptor) {
-
-		int classIndex;
-
-		if (fullyQualifiedClassName == null)
-			 classIndex = this_class;
-		else
-			classIndex = constantPool.findClass(fullyQualifiedClassName);
-
-		if (classIndex < 0)
-			return null;
-
-		int nameAndTypeIndex = constantPool.findNameAndType(simpleName, descriptor);
-		if (nameAndTypeIndex < 0)
-			return null;
-
-        return constantPool.findReference(classIndex, nameAndTypeIndex);
-	}
-*/
-	/*
-	** Public methods from ClassRead
-	*/
-
-
-
-	/*
-	** Implementation specific methods.
-	*/
-
-	/*
-	** Methods related to Constant Pool Table
-	*/
-	/**
-		Generic add entry to constant pool. Includes the logic
-		for an entry to occupy more than one slot (e.g. long).
-
-		@return The number of slots occupied by the entry.
-.
-	*/
-	protected int addEntry(Object key, ConstantPoolEntry item) {
-
-		item.setIndex(cptEntries.size());
-		if (key != null)
-			cptHashTable.put(key, item);
-		cptEntries.addElement(item);
-
-		cptEstimatedSize += item.classFileSize();
-
-		if (item.doubleSlot()) {
-			cptEntries.addElement(null);
-			return 2;
-		} else {
-			return 1;
-		}
-	}
-	
-	/**
-		Add an entry, but only if it doesn't exist.
-
-		@return the constant pool index of the added
-		or existing item.
-	*/
-	private int addDirectEntry(ConstantPoolEntry item) {
-		ConstantPoolEntry existingItem = findMatchingEntry(item);
-		if (existingItem != null) {
-			item = existingItem;
-			//foundCount++;
-		}
-		else {
-			addEntry(item.getKey(), item);
-		}
-		return item.getIndex();
-	}
-
-	/**
-		Add an index reference.
-	*/
-	private int addIndexReference(int tag, int i1, int i2) {
-
-		// search for the item using the pre-allocated object 
-		searchIndex.set(tag, i1, i2);
-
-		ConstantPoolEntry item = findMatchingEntry(searchIndex);
-
-		if (item == null) {
-			item = new CONSTANT_Index_info(tag, i1, i2);
-			addEntry(item.getKey(), item);
-		}
-
-		return item.getIndex();
-	}
-
-	/**
-		Add a class entry to the pool.
-	*/
-	public int addClassReference(String fullyQualifiedName) {
-		if (ClassHolder.isExternalClassName(fullyQualifiedName)) {
-			fullyQualifiedName = ClassHolder.convertToInternalClassName(fullyQualifiedName);
-			// System.out.println("addClassReference " + fullyQualifiedName);
-		}
-
-		int name_index = addUtf8Entry(fullyQualifiedName).getIndex();
-
-		return addIndexReference(VMDescriptor.CONSTANT_Class, name_index, 0);
-	}
-
-	/**
-		Add a name and type entry
-	*/
-	private int addNameAndType(String name, String descriptor) {
-		int nameIndex = addUtf8Entry(name).getIndex();
-
-		int descriptorIndex = addUtf8Entry(descriptor).getIndex();
-
-		return addIndexReference(VMDescriptor.CONSTANT_NameAndType, nameIndex, descriptorIndex);
-	}
-
-	/**
-		Add a UTF8 into the pool and return the index to it.
-	*/
-	private CONSTANT_Utf8_info addUtf8Entry(String value) {
-
-		CONSTANT_Utf8_info item = (CONSTANT_Utf8_info) findMatchingEntry(value);
-
-		if (item == null) {
-
-			item = new CONSTANT_Utf8_info(value);
-			addEntry(value, item);
-		}
-		return item;
-	}
-	/**
-		Add an extra UTF8 into the pool 
-	*/
-	private CONSTANT_Utf8_info addExtraUtf8(String value) {
-
-		CONSTANT_Utf8_info item = new CONSTANT_Utf8_info(value);
-		addEntry(null, item);
-
-		return item;
-	}
-
-	/**
-		Add a string entry
-	*/
-	private int addString(String value) {
-		CONSTANT_Utf8_info sutf = addUtf8Entry(value);
-		int valueIndex = sutf.setAsString();
-		if (valueIndex == 0) {
-			// string is already being used as code
-			valueIndex = addExtraUtf8(value).getIndex();
-			sutf.setAlternative(valueIndex);
-		}
-
-		return addIndexReference(VMDescriptor.CONSTANT_String, valueIndex, 0);
-	}
-
-	/**
-		Add a string entry
-	*/
-	private int addCodeUtf8(String value) {
-		CONSTANT_Utf8_info sutf = addUtf8Entry(value);
-		int index = sutf.setAsCode();
-		if (index == 0) {
-			// code string is already being used as string
-			CONSTANT_Utf8_info eutf = addExtraUtf8(value);
-			eutf.setAsCode(); // ensure the replace will happen
-			index = eutf.getIndex();
-			sutf.setAlternative(index);
-		}
-
-		return index;
-	}
- 	protected void cptPut(ClassFormatOutput out) throws IOException {
-
-		for (Enumeration e = cptEntries.elements(); e.hasMoreElements(); ) {
-			ConstantPoolEntry item = (ConstantPoolEntry) e.nextElement();
-			if (item == null) {
-				continue;
-			}
-
-			item.put(out);
-		}
-	}
-
-	/*
-	** Methods to convert indexes to constant pool entries and vice-versa.
-	*/
-
-	ConstantPoolEntry getEntry(int index) {
-		return (ConstantPoolEntry) cptEntries.elementAt(index);
-	}
-
-	/**
-		Return the class name for an index to a CONSTANT_Class_info.
-	*/
-
-	protected String className(int classIndex) {
-		CONSTANT_Index_info ci = (CONSTANT_Index_info) getEntry(classIndex);
-
-		return nameIndexToString(ci.getI1()).replace('/', '.');
-
-	}
-
-	/*
-	** Methods to find specific types of constant pool entries.
-	   In these methods we try to avoid using the ConstantPoolEntry.matchValue()
-	   as that requires creating a new object for the search. The matchValue()
-	   call is really intended for when objects are being added to the constant pool.
-	*/
-
-	/**
-		Return the index of a UTF entry or -1 if it doesn't exist.
-	*/
-	int findUtf8(String value) {
-
-		ConstantPoolEntry item = findMatchingEntry(value);
-		if (item == null)
-			return -1;
-
-		return item.getIndex();
-	}
-
-	/**
-		Find a class descriptor (section 4.4.1) and return its
-		index, returns -1 if not found.
-	*/
-	public int findClass(String fullyQualifiedName) {
-		String internalName = ClassHolder.convertToInternalClassName(fullyQualifiedName);
-		int utf_index = findUtf8(internalName);
-		if (utf_index < 0)
-			return -1;
-
-		return findIndexIndex(VMDescriptor.CONSTANT_Class,
-			utf_index, 0);
-	}
-
-
-	/**
-		Find a name and type descriptor (section 4.4.6) and
-		return ita index. returns -1 if not found.
-	*/
-	public int findNameAndType(String name, String descriptor) {
-
-		int name_index = findUtf8(name);
-		if (name_index < 0)
-			return -1;
-		int descriptor_index = findUtf8(descriptor);
-		if (descriptor_index < 0)
-			return -1;
-
-		return findIndexIndex(VMDescriptor.CONSTANT_NameAndType,
-			name_index, descriptor_index);
-	}
-/*
-	public ClassMember findReference(int classIndex, int nameAndTypeIndex) {
-
-		CONSTANT_Index_info item = findIndexEntry(VMDescriptor.CONSTANT_Methodref,
-				classIndex, nameAndTypeIndex);
-
-		if (item == null) {
-
-			item = findIndexEntry(VMDescriptor.CONSTANT_InterfaceMethodref,
-				classIndex, nameAndTypeIndex);
-
-			if (item == null) {
-				item = findIndexEntry(VMDescriptor.CONSTANT_Fieldref,
-					classIndex, nameAndTypeIndex);
-
-				if (item == null)
-					return null;
-
-			}
-		}
-
-		return new ReferenceMember(this, item);
-	}
-*/
-	protected CONSTANT_Index_info findIndexEntry(int tag, int i1, int i2) {
-		// search for the item using the pre-allocated object 
-		searchIndex.set(tag, i1, i2);
-
-		return (CONSTANT_Index_info) findMatchingEntry(searchIndex);
-	}
-
-	protected int findIndexIndex(int tag, int i1, int i2) {
-		CONSTANT_Index_info item = findIndexEntry(tag, i1, i2);
-		if (item == null)
-			return -1;
-
-		return item.getIndex();
-	}
-
-	protected ConstantPoolEntry findMatchingEntry(Object key) {
-		return (ConstantPoolEntry) cptHashTable.get(key);
-	}
-
-	/** get a string (UTF) given a name_index into the constant pool
-	   */
-	String nameIndexToString(int index) {
-
-		return getEntry(index).toString();
-	}
-
-	/** get the class name of a Class given the index of its CONSTANT_Class_info
-	    entry in the Constant Pool.
-		*/
-
-	protected String getClassName(int index) {
-
-		if (index == 0)
-			return ""; // must be the super class of java.lang.Object, ie. nothing.
-
-		return 	nameIndexToString(getEntry(index).getI1());
-	}
-
-	/*
-	 * Determine whether the class descriptor string is 
-	 * in external format or not.  Assumes that to be in external
-	 * format means it must have a '.' or end in an ']'.
-	 * 
-	 * @param className	the name of the class to check
-	 *
-	 * @return true/false
-	 */
-	public static boolean isExternalClassName(String className)
-	{
-		int len;
-		if (className.indexOf('.') != -1)
-		{
-			return true;
-		}
-		else if ((len = className.length()) == 0)
-		{ 
-			return false;
-		}
-		return (className.charAt(len - 1) == ']');
-	}
-
-	/*
-	 * Convert a class name to the internal VM class name format.
-	   See sections 4.3.2, 4.4.1 of the vm spec.
-	 * The normal leading 'L' and trailing ';' are left
-	 * off of objects.  This is intended primarily for
-	 * the class manager.
-	 * <p>
-	 * An example of a conversion would be java.lang.Double[]
-	 * to "[Ljava/lang/Double;".
-	 <BR>
-	   java.lang.Double would be converted to "java/lang/Double"
-
-	<BR>
-	Note that for array types the result of convertToInternalClassName()
-	and convertToInternalDescriptor() are identical.
-
-	 *
-	 * @param the external name (cannot be null)
-	 *
-	 * @return the internal string
-	 */
-	public static String convertToInternalClassName(String externalName)
-	{
-		return convertToInternal(externalName, false);
-	}
-
-	/*
-	 * Convert a class name to internal JVM descriptor format.
-	   See sections 4.3.2 of the vm spec.
-	 * <p>
-	 * An example of a conversion would be "java.lang.Double[]"
-	 * to "[Ljava/lang/Double;".
-	 *
-	 <BR>
-	   java.lang.Double would be converted to "Ljava/lang/Double;"
-
-	<BR>
-	Note that for array types the result of convertToInternalClassName()
-	and convertToInternalDescriptor() are identical.
-
-	 * @param the external name (cannot be null)
-	 *
-	 * @return the internal string
-	 */
-	public static String convertToInternalDescriptor(String externalName)
-	{
-		return convertToInternal(externalName, true);
-	}
-
-	/*
-	** Workhorse method.  Convert to internal format.
-
-		@param descriptor True if converting to descriptor format, false if
-		converting to class name format.
-	**
-	** Lifted from BCClass.java. 
-	**
-	** Returns the result string.
-	*/
-	private static String convertToInternal(String externalName, boolean descriptor)
-	{
-		if (SanityManager.DEBUG)
-		{
-			SanityManager.ASSERT(externalName != null, "unexpected null");
-		}
-
-		int len = externalName.length();
-
-		String internalName;	
-		String retVal = null;	
-		int origLen = len;
-		int arity = 0;
-
-		// first walk through all array-ness
-		if (externalName.charAt(len-1) == ']')
-		{
-			while (len > 0
-				&& externalName.charAt(len-1) == ']'
-				&& externalName.charAt(len-2) == '[') 
-			{
-				len -= 2;
-				arity++;
-			}
-		}
-		if (SanityManager.DEBUG) {
-			SanityManager.ASSERT(len > 0);
-		}
-
-		internalName = (origLen == len)? 
-						  externalName 
-						: externalName.substring(0,len);
-
-	    // then check for primitive types ... 
-		// in length by expected frequency order
-
-		switch (len) {
-			case 7 :
-		        if ("boolean".equals(internalName)) {
-					retVal = makeDesc(VMDescriptor.C_BOOLEAN, arity);
-				}
-				break;
-			case 4 :
-		        if ("void".equals(internalName)) {
-					retVal = makeDesc(VMDescriptor.C_VOID, arity);
-				}
-		        else if ("long".equals(internalName)) {
-					retVal = makeDesc(VMDescriptor.C_LONG, arity);
-				}
-		        else if ("byte".equals(internalName)) {
-					retVal = makeDesc(VMDescriptor.C_BYTE, arity);
-				}
-		        else if ("char".equals(internalName)) {
-					retVal = makeDesc(VMDescriptor.C_CHAR, arity);
-				}
-				break;
-			case 3 :
-		        if ("int".equals(internalName)) {
-					retVal = makeDesc(VMDescriptor.C_INT, arity);
-				}
-				break;
-			case 6 :
-		        if ("double".equals(internalName)) {
-					retVal = makeDesc(VMDescriptor.C_DOUBLE, arity);
-				}
-				break;
-			case 5 :
-		        if ("short".equals(internalName)) {
-					retVal = makeDesc(VMDescriptor.C_SHORT, arity);
-				}
-		        else if ("float".equals(internalName)) {
-					retVal = makeDesc(VMDescriptor.C_FLOAT, arity);
-				}
-				break;
-		}
-
-		// then it must be a Java class
-		if (retVal == null)
-			retVal = makeDesc(internalName, arity, descriptor);
-
-		return retVal;
-	}
-
-	/**
-		A helper to build a type description based on a built-in type
-		and an array arity.
-	 */
-	static private String makeDesc (char builtin, int arity) {
-		if (arity == 0)
-			switch (builtin) {
-				case VMDescriptor.C_BYTE : return VMDescriptor.BYTE;
-				case VMDescriptor.C_CHAR : return VMDescriptor.CHAR;
-				case VMDescriptor.C_DOUBLE : return VMDescriptor.DOUBLE;
-				case VMDescriptor.C_FLOAT : return VMDescriptor.FLOAT;
-				case VMDescriptor.C_INT : return VMDescriptor.INT;
-				case VMDescriptor.C_LONG : return VMDescriptor.LONG;
-				case VMDescriptor.C_SHORT : return VMDescriptor.SHORT;
-				case VMDescriptor.C_BOOLEAN : return VMDescriptor.BOOLEAN;
-				case VMDescriptor.C_VOID : return VMDescriptor.VOID;
-				default: 
-					if (SanityManager.DEBUG)
-						SanityManager.THROWASSERT("No type match");
-					return null;
-			}
-		else {
-			StringBuffer desc = new StringBuffer(arity+3);
-
-			for (int i=0;i<arity;i++)
-				desc.append(VMDescriptor.C_ARRAY);
-
-			desc.append(ClassHolder.makeDesc(builtin, 0));
-
-			return desc.toString();
-		}
-	}
-
-	/**
-		A helper to build a type description based on a Java class
-		and an array arity.
-
-		If descriptor is true create a descriptor according to
-		section 4.3.2 of the vm spec. If false create a class name
-		according to sections 4.3.2 and 4.4.1 of the vm spec.
-	
-	 */
-	static private String makeDesc (String className, int arity, boolean descriptor) {
-
-		if (!descriptor && (arity == 0)) {
-			return className.replace('.','/');
-		}
-
-		StringBuffer desc = new StringBuffer(arity+2+className.length());
-
-		for (int i=0;i<arity;i++)
-			desc.append(VMDescriptor.C_ARRAY);
-
-		desc.append(VMDescriptor.C_CLASS);
-
-		desc.append(className.replace('.','/'));
-
-		desc.append(VMDescriptor.C_ENDCLASS);
-
-		return desc.toString();
-	}
-
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.classfile
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.classfile;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+
+import java.io.IOException;
+import java.util.Vector;
+
+import org.apache.derby.iapi.util.ByteArray;
+import org.apache.derby.iapi.services.classfile.VMDescriptor;
+import org.apache.derby.iapi.services.classfile.VMDescriptor;
+
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+
+
+/** Based upon "THE class FILE FORMAT" chapter of "The Java Virtual Machine Specification"
+    corresponding to version 1.0.2 of the Java Virtual Machine and 1.0.2 of the
+	Java Language Specification.
+
+    ISBN  0-201-63452-X, September 1996.
+	*/
+
+public class ClassHolder {
+	/**
+		IBM Copyright &copy notice.
+	*/
+
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+
+
+	/*
+	** Constants.
+	*/
+
+	/*
+	** Fields
+	*/
+
+	protected int access_flags;
+	protected int this_class;
+	protected int super_class;
+
+	// protected InterfacesArray interfaces; // can be null
+	protected int[] interfaces; //can be null
+
+	protected MemberTable field_info; // can be null
+	protected MemberTable method_info;	// can be null
+	protected Attributes attribute_info; // can be null
+
+	/*
+	** Fields for Constant Pool Table
+	*/
+	protected Hashtable cptHashTable;
+	protected Vector cptEntries;
+	private int cptEstimatedSize;
+
+	/**
+		Used to search for index entries to avoid object allocation
+		in the case a referecne already exists.
+	*/
+	private final CONSTANT_Index_info	searchIndex = new CONSTANT_Index_info(0, 0, 0);
+
+	/*
+	**	Constructors.
+	*/
+
+	protected ClassHolder(int estimatedConstantPoolCount) {
+		// Constant Pool Information
+		// 100 is the estimate of the number of entries that will be generated
+		cptEntries = new Vector(estimatedConstantPoolCount);
+		cptHashTable = new Hashtable(estimatedConstantPoolCount, (float)0.75);
+
+		// reserve the 0'th constant pool entry
+		cptEntries.setSize(1);
+	}
+
+
+	/**
+		This will not define a constructor -- it is up
+		to the caller to add at least one.
+	*/
+
+	public ClassHolder(String fullyQualifiedName, String superClassName,
+		int modifiers) {
+
+		this(100);
+
+		access_flags = modifiers | /* Modifier.SUPER */ 0x0020;
+
+		this_class = addClassReference(fullyQualifiedName);
+		super_class = addClassReference(superClassName);
+		method_info = new MemberTable(0);
+	}
+
+	public void put(ClassFormatOutput out) throws IOException {
+
+		/* Write out the header */
+		out.putU4(VMDescriptor.JAVA_CLASS_FORMAT_MAGIC);
+		out.putU2(VMDescriptor.JAVA_CLASS_FORMAT_MINOR_VERSION);
+		out.putU2(VMDescriptor.JAVA_CLASS_FORMAT_MAJOR_VERSION);
+
+		out.putU2(cptEntries.size());
+		cptPut(out);
+
+		out.putU2(access_flags);
+		out.putU2(this_class);
+		out.putU2(super_class);
+
+		if (interfaces != null) {
+			int ilen = interfaces.length;
+			out.putU2(ilen);
+			for (int i = 0; i < ilen; i++) {
+				out.putU2(interfaces[i]);
+			}
+		} else {
+			out.putU2(0);
+		}
+
+		if (field_info != null) {
+			out.putU2(field_info.size());
+			field_info.put(out);
+		} else {
+			out.putU2(0);
+		}
+
+		if (method_info != null) {
+			out.putU2(method_info.size());
+			method_info.put(out);
+		} else {
+			out.putU2(0);
+		}
+
+		if (attribute_info != null) {
+			out.putU2(attribute_info.size());
+			attribute_info.put(out);
+		} else {
+			out.putU2(0);
+		}
+
+	}
+
+
+	/*
+	**	Public methods from ClassHolder.
+	*/
+
+
+	public ByteArray getFileFormat() {
+
+		int classFileSize = 4 + (10 * 2);
+		classFileSize += cptEstimatedSize;
+
+		if (interfaces != null)
+			classFileSize += (interfaces.length * 2);
+
+		if (field_info != null)
+			classFileSize += field_info.classFileSize();
+
+		if (method_info != null)
+			classFileSize += method_info.classFileSize();
+
+		if (attribute_info != null)
+			classFileSize += attribute_info.classFileSize();
+
+		try {
+			ClassFormatOutput cfo = new ClassFormatOutput(classFileSize + 200);
+
+			put(cfo);
+
+			return new ByteArray(cfo.getData(), 0, cfo.size());
+
+		} catch (IOException e) {
+			return null;
+		}
+
+	}
+
+	/*
+	** Public methods from ClassMember
+	*/
+
+	/** @see ClassMember
+	*/
+	public int getModifier() { return access_flags; }
+
+	/** @see ClassMember
+	*/
+	public String getName() {
+		return className(this_class).replace('/', '.');
+	}
+	/*
+	**	Public methods from ClassHolder
+	*/
+
+	/** @see ClassHolder#addMember */
+ 	public ClassMember addMember(String simpleName, String descriptor, int modifier)
+	{
+		if (SanityManager.DEBUG)
+		{
+			if (descriptor.startsWith("(")) {
+				if (method_info != null) {
+					if (method_info.find(simpleName, descriptor) != null) {
+						SanityManager.THROWASSERT("Method already exists " + simpleName + " " + descriptor);
+					}
+				}
+
+			} else {
+				if (field_info != null) {
+					if (field_info.find(simpleName, descriptor) != null) {
+						SanityManager.THROWASSERT("Field already exists " + simpleName + " " + descriptor);
+					}
+				}
+			}
+		}
+
+		CONSTANT_Utf8_info utf = addUtf8Entry(simpleName);
+
+		int nameIndex = utf.getIndex();
+		int descriptorIndex = addUtf8Entry(descriptor).getIndex();
+
+		ClassMember item = new ClassMember(this, modifier, nameIndex, descriptorIndex);
+		MemberTable mt;
+		if (descriptor.startsWith("(")) {
+			mt = method_info;
+			if (mt == null)
+				mt = method_info = new MemberTable(0);
+
+		}
+		else {
+			mt = field_info;
+			if (mt == null)
+				mt = field_info = new MemberTable(0);
+		}
+
+		mt.addEntry(item);
+		return item;
+	}
+
+	/** @see ClassHolder#addFieldReference */
+	public int addFieldReference(String className, String simpleName, String descriptor) {
+		return addReference(VMDescriptor.CONSTANT_Fieldref, className, simpleName, descriptor);
+	}
+
+	public int addFieldReference(ClassMember field) {
+		return addReference(VMDescriptor.CONSTANT_Fieldref, (ClassMember) field);
+	}
+
+	/** @see ClassHolder#addMethodReference */
+	public int addMethodReference(String className, String simpleName, String descriptor, boolean isInterface) {
+
+		int tag = isInterface ?	VMDescriptor.CONSTANT_InterfaceMethodref :
+								VMDescriptor.CONSTANT_Methodref;
+
+		return addReference(tag, className, simpleName, descriptor); 
+	}
+
+	private int addReference(int tag, String className, String simpleName, String descriptor) {
+
+		int classIndex = addClassReference(className);
+		int nameTypeIndex = addNameAndType(simpleName, descriptor);
+
+		return addIndexReference(tag, classIndex, nameTypeIndex);
+	}
+
+	private int addReference(int tag, ClassMember member) {
+
+		int nameTypeIndex = addIndexReference(VMDescriptor.CONSTANT_NameAndType,
+							member.name_index, member.descriptor_index);
+
+		return addIndexReference(tag, this_class, nameTypeIndex);
+	}
+
+	/** @see ClassHolder#addConstant */
+	public int addConstant(String value) {
+
+		return addString(value);
+	}
+
+	/** @see ClassHolder#addUtf8 */
+	public int addUtf8(String value) {
+
+		return addUtf8Entry(value).getIndex();
+	}
+
+
+	/** @see ClassHolder#addInteger */
+	public int addConstant(int value) {
+		return addDirectEntry(new CONSTANT_Integer_info(value));
+	}
+
+	/** @see ClassHolder#addFloat */
+	public int addConstant(float value) {
+		return addDirectEntry(new CONSTANT_Float_info(value));
+	}
+
+	/** @see ClassHolder#addLong */
+	public int addConstant(long value) {
+		return addDirectEntry(new CONSTANT_Long_info(value));
+	}
+
+	/** @see ClassHolder#addDouble */
+	public int addConstant(double value) {
+		return addDirectEntry(new CONSTANT_Double_info(value));
+	}
+
+
+	/** @see ClassMember
+	*/
+	public int getConstantPoolIndex() { return this_class; }
+
+	public void addAttribute(String attributeName, ClassFormatOutput info) {
+
+		if (attribute_info == null)
+			attribute_info = new Attributes(1);
+
+
+		CONSTANT_Utf8_info autf = addUtf8Entry(attributeName);
+
+		int index = autf.getIndex();
+
+		attribute_info.addEntry(new AttributeEntry(index, info));
+	}
+
+
+	public String getSuperClassName() {
+		if (super_class == 0)
+			return null;
+		else
+			return className(super_class).replace('/', '.');
+	}
+
+
+/*
+    public ClassMember getMemberReference(String fullyQualifiedClassName, String simpleName, String descriptor) {
+
+		int classIndex;
+
+		if (fullyQualifiedClassName == null)
+			 classIndex = this_class;
+		else
+			classIndex = constantPool.findClass(fullyQualifiedClassName);
+
+		if (classIndex < 0)
+			return null;
+
+		int nameAndTypeIndex = constantPool.findNameAndType(simpleName, descriptor);
+		if (nameAndTypeIndex < 0)
+			return null;
+
+        return constantPool.findReference(classIndex, nameAndTypeIndex);
+	}
+*/
+	/*
+	** Public methods from ClassRead
+	*/
+
+
+
+	/*
+	** Implementation specific methods.
+	*/
+
+	/*
+	** Methods related to Constant Pool Table
+	*/
+	/**
+		Generic add entry to constant pool. Includes the logic
+		for an entry to occupy more than one slot (e.g. long).
+
+		@return The number of slots occupied by the entry.
+.
+	*/
+	protected int addEntry(Object key, ConstantPoolEntry item) {
+
+		item.setIndex(cptEntries.size());
+		if (key != null)
+			cptHashTable.put(key, item);
+		cptEntries.addElement(item);
+
+		cptEstimatedSize += item.classFileSize();
+
+		if (item.doubleSlot()) {
+			cptEntries.addElement(null);
+			return 2;
+		} else {
+			return 1;
+		}
+	}
+	
+	/**
+		Add an entry, but only if it doesn't exist.
+
+		@return the constant pool index of the added
+		or existing item.
+	*/
+	private int addDirectEntry(ConstantPoolEntry item) {
+		ConstantPoolEntry existingItem = findMatchingEntry(item);
+		if (existingItem != null) {
+			item = existingItem;
+			//foundCount++;
+		}
+		else {
+			addEntry(item.getKey(), item);
+		}
+		return item.getIndex();
+	}
+
+	/**
+		Add an index reference.
+	*/
+	private int addIndexReference(int tag, int i1, int i2) {
+
+		// search for the item using the pre-allocated object 
+		searchIndex.set(tag, i1, i2);
+
+		ConstantPoolEntry item = findMatchingEntry(searchIndex);
+
+		if (item == null) {
+			item = new CONSTANT_Index_info(tag, i1, i2);
+			addEntry(item.getKey(), item);
+		}
+
+		return item.getIndex();
+	}
+
+	/**
+		Add a class entry to the pool.
+	*/
+	public int addClassReference(String fullyQualifiedName) {
+		if (ClassHolder.isExternalClassName(fullyQualifiedName)) {
+			fullyQualifiedName = ClassHolder.convertToInternalClassName(fullyQualifiedName);
+			// System.out.println("addClassReference " + fullyQualifiedName);
+		}
+
+		int name_index = addUtf8Entry(fullyQualifiedName).getIndex();
+
+		return addIndexReference(VMDescriptor.CONSTANT_Class, name_index, 0);
+	}
+
+	/**
+		Add a name and type entry
+	*/
+	private int addNameAndType(String name, String descriptor) {
+		int nameIndex = addUtf8Entry(name).getIndex();
+
+		int descriptorIndex = addUtf8Entry(descriptor).getIndex();
+
+		return addIndexReference(VMDescriptor.CONSTANT_NameAndType, nameIndex, descriptorIndex);
+	}
+
+	/**
+		Add a UTF8 into the pool and return the index to it.
+	*/
+	private CONSTANT_Utf8_info addUtf8Entry(String value) {
+
+		CONSTANT_Utf8_info item = (CONSTANT_Utf8_info) findMatchingEntry(value);
+
+		if (item == null) {
+
+			item = new CONSTANT_Utf8_info(value);
+			addEntry(value, item);
+		}
+		return item;
+	}
+	/**
+		Add an extra UTF8 into the pool 
+	*/
+	private CONSTANT_Utf8_info addExtraUtf8(String value) {
+
+		CONSTANT_Utf8_info item = new CONSTANT_Utf8_info(value);
+		addEntry(null, item);
+
+		return item;
+	}
+
+	/**
+		Add a string entry
+	*/
+	private int addString(String value) {
+		CONSTANT_Utf8_info sutf = addUtf8Entry(value);
+		int valueIndex = sutf.setAsString();
+		if (valueIndex == 0) {
+			// string is already being used as code
+			valueIndex = addExtraUtf8(value).getIndex();
+			sutf.setAlternative(valueIndex);
+		}
+
+		return addIndexReference(VMDescriptor.CONSTANT_String, valueIndex, 0);
+	}
+
+	/**
+		Add a string entry
+	*/
+	private int addCodeUtf8(String value) {
+		CONSTANT_Utf8_info sutf = addUtf8Entry(value);
+		int index = sutf.setAsCode();
+		if (index == 0) {
+			// code string is already being used as string
+			CONSTANT_Utf8_info eutf = addExtraUtf8(value);
+			eutf.setAsCode(); // ensure the replace will happen
+			index = eutf.getIndex();
+			sutf.setAlternative(index);
+		}
+
+		return index;
+	}
+ 	protected void cptPut(ClassFormatOutput out) throws IOException {
+
+		for (Enumeration e = cptEntries.elements(); e.hasMoreElements(); ) {
+			ConstantPoolEntry item = (ConstantPoolEntry) e.nextElement();
+			if (item == null) {
+				continue;
+			}
+
+			item.put(out);
+		}
+	}
+
+	/*
+	** Methods to convert indexes to constant pool entries and vice-versa.
+	*/
+
+	ConstantPoolEntry getEntry(int index) {
+		return (ConstantPoolEntry) cptEntries.elementAt(index);
+	}
+
+	/**
+		Return the class name for an index to a CONSTANT_Class_info.
+	*/
+
+	protected String className(int classIndex) {
+		CONSTANT_Index_info ci = (CONSTANT_Index_info) getEntry(classIndex);
+
+		return nameIndexToString(ci.getI1()).replace('/', '.');
+
+	}
+
+	/*
+	** Methods to find specific types of constant pool entries.
+	   In these methods we try to avoid using the ConstantPoolEntry.matchValue()
+	   as that requires creating a new object for the search. The matchValue()
+	   call is really intended for when objects are being added to the constant pool.
+	*/
+
+	/**
+		Return the index of a UTF entry or -1 if it doesn't exist.
+	*/
+	int findUtf8(String value) {
+
+		ConstantPoolEntry item = findMatchingEntry(value);
+		if (item == null)
+			return -1;
+
+		return item.getIndex();
+	}
+
+	/**
+		Find a class descriptor (section 4.4.1) and return its
+		index, returns -1 if not found.
+	*/
+	public int findClass(String fullyQualifiedName) {
+		String internalName = ClassHolder.convertToInternalClassName(fullyQualifiedName);
+		int utf_index = findUtf8(internalName);
+		if (utf_index < 0)
+			return -1;
+
+		return findIndexIndex(VMDescriptor.CONSTANT_Class,
+			utf_index, 0);
+	}
+
+
+	/**
+		Find a name and type descriptor (section 4.4.6) and
+		return ita index. returns -1 if not found.
+	*/
+	public int findNameAndType(String name, String descriptor) {
+
+		int name_index = findUtf8(name);
+		if (name_index < 0)
+			return -1;
+		int descriptor_index = findUtf8(descriptor);
+		if (descriptor_index < 0)
+			return -1;
+
+		return findIndexIndex(VMDescriptor.CONSTANT_NameAndType,
+			name_index, descriptor_index);
+	}
+/*
+	public ClassMember findReference(int classIndex, int nameAndTypeIndex) {
+
+		CONSTANT_Index_info item = findIndexEntry(VMDescriptor.CONSTANT_Methodref,
+				classIndex, nameAndTypeIndex);
+
+		if (item == null) {
+
+			item = findIndexEntry(VMDescriptor.CONSTANT_InterfaceMethodref,
+				classIndex, nameAndTypeIndex);
+
+			if (item == null) {
+				item = findIndexEntry(VMDescriptor.CONSTANT_Fieldref,
+					classIndex, nameAndTypeIndex);
+
+				if (item == null)
+					return null;
+
+			}
+		}
+
+		return new ReferenceMember(this, item);
+	}
+*/
+	protected CONSTANT_Index_info findIndexEntry(int tag, int i1, int i2) {
+		// search for the item using the pre-allocated object 
+		searchIndex.set(tag, i1, i2);
+
+		return (CONSTANT_Index_info) findMatchingEntry(searchIndex);
+	}
+
+	protected int findIndexIndex(int tag, int i1, int i2) {
+		CONSTANT_Index_info item = findIndexEntry(tag, i1, i2);
+		if (item == null)
+			return -1;
+
+		return item.getIndex();
+	}
+
+	protected ConstantPoolEntry findMatchingEntry(Object key) {
+		return (ConstantPoolEntry) cptHashTable.get(key);
+	}
+
+	/** get a string (UTF) given a name_index into the constant pool
+	   */
+	String nameIndexToString(int index) {
+
+		return getEntry(index).toString();
+	}
+
+	/** get the class name of a Class given the index of its CONSTANT_Class_info
+	    entry in the Constant Pool.
+		*/
+
+	protected String getClassName(int index) {
+
+		if (index == 0)
+			return ""; // must be the super class of java.lang.Object, ie. nothing.
+
+		return 	nameIndexToString(getEntry(index).getI1());
+	}
+
+	/*
+	 * Determine whether the class descriptor string is 
+	 * in external format or not.  Assumes that to be in external
+	 * format means it must have a '.' or end in an ']'.
+	 * 
+	 * @param className	the name of the class to check
+	 *
+	 * @return true/false
+	 */
+	public static boolean isExternalClassName(String className)
+	{
+		int len;
+		if (className.indexOf('.') != -1)
+		{
+			return true;
+		}
+		else if ((len = className.length()) == 0)
+		{ 
+			return false;
+		}
+		return (className.charAt(len - 1) == ']');
+	}
+
+	/*
+	 * Convert a class name to the internal VM class name format.
+	   See sections 4.3.2, 4.4.1 of the vm spec.
+	 * The normal leading 'L' and trailing ';' are left
+	 * off of objects.  This is intended primarily for
+	 * the class manager.
+	 * <p>
+	 * An example of a conversion would be java.lang.Double[]
+	 * to "[Ljava/lang/Double;".
+	 <BR>
+	   java.lang.Double would be converted to "java/lang/Double"
+
+	<BR>
+	Note that for array types the result of convertToInternalClassName()
+	and convertToInternalDescriptor() are identical.
+
+	 *
+	 * @param the external name (cannot be null)
+	 *
+	 * @return the internal string
+	 */
+	public static String convertToInternalClassName(String externalName)
+	{
+		return convertToInternal(externalName, false);
+	}
+
+	/*
+	 * Convert a class name to internal JVM descriptor format.
+	   See sections 4.3.2 of the vm spec.
+	 * <p>
+	 * An example of a conversion would be "java.lang.Double[]"
+	 * to "[Ljava/lang/Double;".
+	 *
+	 <BR>
+	   java.lang.Double would be converted to "Ljava/lang/Double;"
+
+	<BR>
+	Note that for array types the result of convertToInternalClassName()
+	and convertToInternalDescriptor() are identical.
+
+	 * @param the external name (cannot be null)
+	 *
+	 * @return the internal string
+	 */
+	public static String convertToInternalDescriptor(String externalName)
+	{
+		return convertToInternal(externalName, true);
+	}
+
+	/*
+	** Workhorse method.  Convert to internal format.
+
+		@param descriptor True if converting to descriptor format, false if
+		converting to class name format.
+	**
+	** Lifted from BCClass.java. 
+	**
+	** Returns the result string.
+	*/
+	private static String convertToInternal(String externalName, boolean descriptor)
+	{
+		if (SanityManager.DEBUG)
+		{
+			SanityManager.ASSERT(externalName != null, "unexpected null");
+		}
+
+		int len = externalName.length();
+
+		String internalName;	
+		String retVal = null;	
+		int origLen = len;
+		int arity = 0;
+
+		// first walk through all array-ness
+		if (externalName.charAt(len-1) == ']')
+		{
+			while (len > 0
+				&& externalName.charAt(len-1) == ']'
+				&& externalName.charAt(len-2) == '[') 
+			{
+				len -= 2;
+				arity++;
+			}
+		}
+		if (SanityManager.DEBUG) {
+			SanityManager.ASSERT(len > 0);
+		}
+
+		internalName = (origLen == len)? 
+						  externalName 
+						: externalName.substring(0,len);
+
+	    // then check for primitive types ... 
+		// in length by expected frequency order
+
+		switch (len) {
+			case 7 :
+		        if ("boolean".equals(internalName)) {
+					retVal = makeDesc(VMDescriptor.C_BOOLEAN, arity);
+				}
+				break;
+			case 4 :
+		        if ("void".equals(internalName)) {
+					retVal = makeDesc(VMDescriptor.C_VOID, arity);
+				}
+		        else if ("long".equals(internalName)) {
+					retVal = makeDesc(VMDescriptor.C_LONG, arity);
+				}
+		        else if ("byte".equals(internalName)) {
+					retVal = makeDesc(VMDescriptor.C_BYTE, arity);
+				}
+		        else if ("char".equals(internalName)) {
+					retVal = makeDesc(VMDescriptor.C_CHAR, arity);
+				}
+				break;
+			case 3 :
+		        if ("int".equals(internalName)) {
+					retVal = makeDesc(VMDescriptor.C_INT, arity);
+				}
+				break;
+			case 6 :
+		        if ("double".equals(internalName)) {
+					retVal = makeDesc(VMDescriptor.C_DOUBLE, arity);
+				}
+				break;
+			case 5 :
+		        if ("short".equals(internalName)) {
+					retVal = makeDesc(VMDescriptor.C_SHORT, arity);
+				}
+		        else if ("float".equals(internalName)) {
+					retVal = makeDesc(VMDescriptor.C_FLOAT, arity);
+				}
+				break;
+		}
+
+		// then it must be a Java class
+		if (retVal == null)
+			retVal = makeDesc(internalName, arity, descriptor);
+
+		return retVal;
+	}
+
+	/**
+		A helper to build a type description based on a built-in type
+		and an array arity.
+	 */
+	static private String makeDesc (char builtin, int arity) {
+		if (arity == 0)
+			switch (builtin) {
+				case VMDescriptor.C_BYTE : return VMDescriptor.BYTE;
+				case VMDescriptor.C_CHAR : return VMDescriptor.CHAR;
+				case VMDescriptor.C_DOUBLE : return VMDescriptor.DOUBLE;
+				case VMDescriptor.C_FLOAT : return VMDescriptor.FLOAT;
+				case VMDescriptor.C_INT : return VMDescriptor.INT;
+				case VMDescriptor.C_LONG : return VMDescriptor.LONG;
+				case VMDescriptor.C_SHORT : return VMDescriptor.SHORT;
+				case VMDescriptor.C_BOOLEAN : return VMDescriptor.BOOLEAN;
+				case VMDescriptor.C_VOID : return VMDescriptor.VOID;
+				default: 
+					if (SanityManager.DEBUG)
+						SanityManager.THROWASSERT("No type match");
+					return null;
+			}
+		else {
+			StringBuffer desc = new StringBuffer(arity+3);
+
+			for (int i=0;i<arity;i++)
+				desc.append(VMDescriptor.C_ARRAY);
+
+			desc.append(ClassHolder.makeDesc(builtin, 0));
+
+			return desc.toString();
+		}
+	}
+
+	/**
+		A helper to build a type description based on a Java class
+		and an array arity.
+
+		If descriptor is true create a descriptor according to
+		section 4.3.2 of the vm spec. If false create a class name
+		according to sections 4.3.2 and 4.4.1 of the vm spec.
+	
+	 */
+	static private String makeDesc (String className, int arity, boolean descriptor) {
+
+		if (!descriptor && (arity == 0)) {
+			return className.replace('.','/');
+		}
+
+		StringBuffer desc = new StringBuffer(arity+2+className.length());
+
+		for (int i=0;i<arity;i++)
+			desc.append(VMDescriptor.C_ARRAY);
+
+		desc.append(VMDescriptor.C_CLASS);
+
+		desc.append(className.replace('.','/'));
+
+		desc.append(VMDescriptor.C_ENDCLASS);
+
+		return desc.toString();
+	}
+
+
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassInput.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassInput.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassInput.java	Fri Sep 24 10:33:20 2004
@@ -1,43 +1,43 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.classfile
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.classfile;
-
-import java.io.InputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-
-
-/**	A wrapper around DataInputStream to provide input functions in terms
-    of the types defined on pages 83.
- */
-
-class ClassInput extends DataInputStream {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-
-	ClassInput(InputStream in) {
-		super(in);
-	}
-
-	int getU2() throws IOException {
-		return readUnsignedShort();
-	}
-	int getU4() throws IOException {
-		return readInt();
-	}
-	byte[] getU1Array(int count) throws IOException {
-		byte[] b = new byte[count];
-		readFully(b);
-		return b;
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.classfile
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.classfile;
+
+import java.io.InputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+
+
+/**	A wrapper around DataInputStream to provide input functions in terms
+    of the types defined on pages 83.
+ */
+
+class ClassInput extends DataInputStream {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+
+	ClassInput(InputStream in) {
+		super(in);
+	}
+
+	int getU2() throws IOException {
+		return readUnsignedShort();
+	}
+	int getU4() throws IOException {
+		return readInt();
+	}
+	byte[] getU1Array(int count) throws IOException {
+		byte[] b = new byte[count];
+		readFully(b);
+		return b;
+	}
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassInvestigator.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassInvestigator.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassInvestigator.java	Fri Sep 24 10:33:20 2004
@@ -1,582 +1,582 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.classfile
-   (C) Copyright IBM Corp. 2001, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.classfile;
-
-
-import java.io.InputStream;
-import java.util.Enumeration;
-
-import java.io.IOException;
-import java.util.Vector;
-
-import org.apache.derby.iapi.services.classfile.VMDescriptor;
-import org.apache.derby.iapi.services.classfile.VMDescriptor;
-import java.util.HashSet;
-
-import java.util.Hashtable;
-import java.util.Vector;
-import java.util.Enumeration;
-import java.util.Collections;
-
-
-/** 
-*/
-
-public class ClassInvestigator extends ClassHolder {
-	/**
-		IBM Copyright &copy notice.
-	*/
-
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2001_2004;
-
-	public static ClassInvestigator load(InputStream is)
-		throws IOException {
-
-		ClassInput classInput = new ClassInput(is);
-
-		// Check the header
-		checkHeader(classInput);
-
-		//	Read in the Constant Pool
-		int constantPoolCount = classInput.getU2();
-
-		ClassInvestigator ci = new ClassInvestigator(constantPoolCount);
-		// Yes, index starts at 1, The '0'th constant pool entry
-		// is reserved for the JVM and is not present in the class file.
-		for (int i = 1; i < constantPoolCount; ) {
-			ConstantPoolEntry item = ClassInvestigator.getConstant(classInput);
-			i += ci.addEntry(item.getKey(), item);
-		}
-
-		// Read in access_flags and class indexes
-		ci.access_flags = classInput.getU2();
-		ci.this_class = classInput.getU2();
-		ci.super_class = classInput.getU2();
-
-		// interfaces is a simple int array
-		int interfaceCount = classInput.getU2();
-		if (interfaceCount != 0) {
-			ci.interfaces = new int[interfaceCount];
-			for (int i = 0; i < interfaceCount; i++)
-				ci.interfaces[i] = classInput.getU2();
-		}
-
-		int fieldCount = classInput.getU2();
-		if (fieldCount != 0) {
-			ci.field_info = new MemberTable(fieldCount);
-			for (int i = 0; i < fieldCount; i++)
-			{
-				ci.field_info.addEntry(readClassMember(ci, classInput));
-			}
-		}
-
-		int methodCount = classInput.getU2();
-		if (methodCount != 0) {
- 			ci.method_info = new MemberTable(methodCount);
-			for (int i = 0; i < methodCount; i++)
-			{
-				ci.method_info.addEntry(readClassMember(ci, classInput));
-			}
-		}
-
-		int attributeCount = classInput.getU2();
-		if (attributeCount != 0) {
-			ci.attribute_info = new Attributes(attributeCount);
-
-			for (int i = 0; i < attributeCount; i++)
-				ci.attribute_info.addEntry(new AttributeEntry(classInput));
-		}
-		return ci;
-
-	}
-
-	private static ClassMember readClassMember(ClassInvestigator ci, ClassInput in)
-		throws IOException {
-
-		ClassMember member = new ClassMember(ci, in.getU2(),  in.getU2(), in.getU2());
-
-		int attributeCount = in.getU2();
-		if (attributeCount != 0) {
-			member.attribute_info = new Attributes(attributeCount);
-			for (int i = 0; i < attributeCount; i++)
-				member.attribute_info.addEntry(new AttributeEntry(in));
-		}
-			
-		return member;
-	}
-
-	/*
-	**	Constructors.
-	*/
-
-	private ClassInvestigator(int constantPoolCount) {
-		super(constantPoolCount);
-	}
-
-	/*
-	** Methods to investigate this class
-	*/
-
-
-	public Enumeration implementedInterfaces()
-	{
-		int interfaceCount = interfaces == null ? 0 : interfaces.length;
-		Vector implemented = new Vector(interfaceCount);
-
-        for (int i = 0; i < interfaceCount; i++)
-        {
-            implemented.addElement(className(interfaces[i]));
-        }
-        return implemented.elements();
-	}
-    public Enumeration getFields() {
-		if (field_info == null)
-			return Collections.enumeration(Collections.EMPTY_LIST);
-
-		return field_info.entries.elements();
-	}
-
-    public Enumeration getMethods() {
-		if (method_info == null)
-			return Collections.enumeration(Collections.EMPTY_LIST);
-		return method_info.entries.elements();
-	}
-
-    public Enumeration referencedClasses() {
-        return getClasses(getMethods(), getFields() );
-    }
-
-	/**
-		Return an Enumeration of all referenced classes
-	*/
-
-	private Enumeration getClasses(Enumeration methods, Enumeration fields)
-	{
-		return new ClassEnumeration(this, cptEntries.elements(), methods, fields);
-	}
-
-	public Enumeration getStrings() {
-		HashSet strings = new HashSet(30, 0.8f);
-		
-		int size = cptEntries.size();
-		for (int i = 1; i < size; i++) {
-			ConstantPoolEntry cpe = getEntry(i);
-
-			if ((cpe == null) || (cpe.getTag() != VMDescriptor.CONSTANT_String))
-				continue;
-
-			CONSTANT_Index_info cii = (CONSTANT_Index_info) cpe;
-
-			strings.add(nameIndexToString(cii.getI1()));
-		}
-
-		return java.util.Collections.enumeration(strings);
-	}
-
-    public ClassMember getMember(String simpleName, String descriptor) {
-
-		if (descriptor.startsWith("(")) {
-			if (method_info == null)
-				return null;
-			return method_info.find(simpleName, descriptor);
-		}
-		else {
-			if (field_info == null)
-				return null;
-			return  field_info.find(simpleName, descriptor);
-		}
-	}
-
-	/**
-		Return an Enumeration of all Member References
-	*/
-/*
-	Enumeration getMemberReferences() {
-		return new ReferenceEnumeration(this, elements());
-	}
-*/
-
-	/*
-	** Methods to modify the class.
-	*/
-	// remove all atttributes that are not essential
-	public void removeAttributes() throws IOException {
-
-		// Class level attributes
-		if (attribute_info != null) {
-			for (int i = attribute_info.size() - 1; i >= 0 ; i--) {
-
-				AttributeEntry ae = (AttributeEntry) attribute_info.elementAt(i);
-				String name = nameIndexToString(ae.getNameIndex());
-				if (name.equals("SourceFile"))
-					attribute_info.removeElementAt(i);
-				else if (name.equals("InnerClasses"))
-					; // leave in
-				else
-					System.err.println("WARNING - Unknown Class File attribute " + name);
-			}
-
-			if (attribute_info.size() == 0)
-				attribute_info = null;
-		}
-		attribute_info = null;
-
-		// fields
-		for (Enumeration e = getFields(); e.hasMoreElements(); ) {
-			ClassMember member = (ClassMember) e.nextElement();
-
-			Attributes attrs = member.attribute_info;
-
-			if (attrs != null) {
-
-				for (int i = attrs.size() - 1; i >= 0 ; i--) {
-
-					AttributeEntry ae = (AttributeEntry) attrs.elementAt(i);
-					String name = nameIndexToString(ae.getNameIndex());
-					if (name.equals("ConstantValue"))
-						; // leave in
-					else if (name.equals("Synthetic"))
-						; // leave in
-					else
-						System.err.println("WARNING - Unknown Field attribute " + name);
-				}
-
-				if (attrs.size() == 0)
-					member.attribute_info = null;
-			}
-
-		}
-
-		// methods
-		for (Enumeration e = getMethods(); e.hasMoreElements(); ) {
-			ClassMember member = (ClassMember) e.nextElement();
-
-			Attributes attrs = member.attribute_info;
-
-			if (attrs != null) {
-
-				for (int i = attrs.size() - 1; i >= 0 ; i--) {
-
-					AttributeEntry ae = (AttributeEntry) attrs.elementAt(i);
-					String name = nameIndexToString(ae.getNameIndex());
-					if (name.equals("Code"))
-						processCodeAttribute(member, ae);
-					else if (name.equals("Exceptions"))
-						; // leave in
-					else if (name.equals("Deprecated"))
-						; // leave in
-					else if (name.equals("Synthetic"))
-						; // leave in
-					else
-						System.err.println("WARNING - Unknown method attribute " + name);
-				}
-
-				if (attrs.size() == 0)
-					member.attribute_info = null;
-			}
-
-		}
-	}
-
-	private void processCodeAttribute(ClassMember member, AttributeEntry ae) throws IOException {
-
-		ClassInput ci = new ClassInput(new java.io.ByteArrayInputStream(ae.infoIn));
-
-
-		ci.skipBytes(4); // puts us at code_length
-		int len = ci.getU4();
-		ci.skipBytes(len); // puts us at exception_table_length
-		int count = ci.getU2();
-		if (count != 0)
-			ci.skipBytes(8 * count);
-
-		int nonAttrLength = 4 + 4 + len + 2 + (8 * count);
-
-		// now at attributes
-
-		count = ci.getU2();
-		if (count == 0)
-			return;
-
-		int newCount = count;
-		for (int i = 0; i < count; i++) {
-
-			int nameIndex = ci.getU2();
-			String name = nameIndexToString(nameIndex);
-			if (name.equals("LineNumberTable") || name.equals("LocalVariableTable"))
-				newCount--;
-			else
-				System.err.println("ERROR - Unknown code attribute " + name);
-
-			len = ci.getU4();
-			ci.skipBytes(len);
-		}
-
-		if (newCount != 0) {
-			System.err.println("ERROR - expecting all code attributes to be removed");
-			System.exit(1);
-		}
-
-		// this is only coded for all attributes within a Code attribute being removed.
-
-		byte[] newInfo = new byte[nonAttrLength + 2];
-		System.arraycopy(ae.infoIn, 0, newInfo, 0, nonAttrLength);
-		// last two bytes are left at 0 which means 0 attributes
-		ae.infoIn = newInfo;
-	}
-
-	public void renameClassElements(Hashtable classNameMap, Hashtable memberNameMap) {
-
-		// this & super class
-		renameString(classNameMap, (CONSTANT_Index_info) getEntry(this_class));
-		renameString(classNameMap, (CONSTANT_Index_info) getEntry(super_class));
-
-		// implemented interfaces
-		// handled by Class entries below
-
-		// classes & Strings
-		// descriptors
-		int size = cptEntries.size();
-		for (int i = 1; i < size; i++) {
-			ConstantPoolEntry cpe = getEntry(i);
-
-			if (cpe == null)
-				continue;
-
-			switch (cpe.getTag()) {
-			case VMDescriptor.CONSTANT_String:
-			case VMDescriptor.CONSTANT_Class:
-				{
-				CONSTANT_Index_info cii = (CONSTANT_Index_info) cpe;
-				renameString(classNameMap, cii);
-				break;
-				}
-			case VMDescriptor.CONSTANT_NameAndType:
-				{
-				CONSTANT_Index_info cii = (CONSTANT_Index_info) cpe;
-				String newDescriptor = newDescriptor(classNameMap, nameIndexToString(cii.getI2()));
-				if (newDescriptor != null) {
-					doRenameString(cii.getI2(), newDescriptor);
-				}
-				break;
-				}
-
-			default:
-				continue;
-			}
-
-		}
-
-		//System.out.println("Starting Fields");
-
-		// now the methods & fields, only descriptors at this time
-		renameMembers(getFields(), classNameMap, memberNameMap);
-
-		renameMembers(getMethods(), classNameMap, memberNameMap);
-	}
-
-	private void renameMembers(Enumeration e, Hashtable classNameMap, Hashtable memberNameMap) {
-
-		for (; e.hasMoreElements(); ) {
-			ClassMember member = (ClassMember) e.nextElement();
-
-			String oldMemberName = nameIndexToString(member.name_index);
-			String newMemberName = (String) memberNameMap.get(oldMemberName);
-			if (newMemberName != null)
-				doRenameString(member.name_index, newMemberName);
-
-			String newDescriptor = newDescriptor(classNameMap, nameIndexToString(member.descriptor_index));
-			if (newDescriptor != null) {
-				doRenameString(member.descriptor_index, newDescriptor);
-			}
-		}
-
-	}
-
-	private void renameString(Hashtable classNameMap, CONSTANT_Index_info cii) {
-
-		int index = cii.getI1();
-
-		String name = nameIndexToString(index);
-		String newName = (String) classNameMap.get(name);
-		if (newName != null) {
-
-			doRenameString(index, newName);
-
-			return;
-		}
-
-		// have to look for arrays
-		if (cii.getTag() == VMDescriptor.CONSTANT_Class) {
-
-			if (name.charAt(0) == '[') {
-				int classOffset = name.indexOf('L') + 1;
-
-				String baseClassName = name.substring(classOffset, name.length() - 1);
-
-
-				newName = (String) classNameMap.get(baseClassName);
-
-				if (newName != null) {
-
-					String newArrayClassName = name.substring(0, classOffset) + newName + ";";
-
-					doRenameString(index, newArrayClassName);
-
-				}
-
-			}
-		}
-	}
-
-	private void doRenameString(int index, String newName) {
-		ConstantPoolEntry cpe = getEntry(index);
-		if (cpe.getTag() != VMDescriptor.CONSTANT_Utf8)
-			throw new RuntimeException("unexpected type " + cpe);
-
-		CONSTANT_Utf8_info newCpe = new CONSTANT_Utf8_info(newName);
-
-		cptHashTable.remove(cpe.getKey());
-		cptHashTable.put(cpe.getKey(), cpe);
-
-		newCpe.index = index;
-
-		cptEntries.setElementAt(newCpe, index);
-	}
-
-	/*
-	**
-	*/
-	static private void checkHeader(ClassInput in) throws IOException {
-		int magic = in.getU4();
-		int minor_version = in.getU2();
-		int major_version = in.getU2();
-
-
-		if (magic != VMDescriptor.JAVA_CLASS_FORMAT_MAGIC)
-			   throw new ClassFormatError();
-   	}
-	private static ConstantPoolEntry getConstant(ClassInput in)
-		throws IOException {
-
-		ConstantPoolEntry item;
-		int tag;		
-		tag = in.readUnsignedByte();
-
-		switch (tag) {
-		case VMDescriptor.CONSTANT_Class:
-		case VMDescriptor.CONSTANT_String:
-			item = new CONSTANT_Index_info(tag, in.getU2(), 0);
-			break;
-
-		case VMDescriptor.CONSTANT_NameAndType:
-		case VMDescriptor.CONSTANT_Fieldref:
-		case VMDescriptor.CONSTANT_Methodref:
-		case VMDescriptor.CONSTANT_InterfaceMethodref:
-			item = new CONSTANT_Index_info(tag, in.getU2(), in.getU2());
-			break;
-
-		case VMDescriptor.CONSTANT_Integer:
-			item = new CONSTANT_Integer_info(in.getU4());
-			break;
-
-		case VMDescriptor.CONSTANT_Float:
-			item = new CONSTANT_Float_info(in.readFloat());
-			break;
-
-		case VMDescriptor.CONSTANT_Long:
-			item = new CONSTANT_Long_info(in.readLong());
-			break;
-
-		case VMDescriptor.CONSTANT_Double:
-			item = new CONSTANT_Double_info(in.readDouble());
-			break;
-
-		case VMDescriptor.CONSTANT_Utf8:
-			item = new CONSTANT_Utf8_info(in.readUTF());
-			break;
-		default:
-			throw new ClassFormatError();
-		}
-
-		return item;
-	}
-	public static String newDescriptor(Hashtable classNameMap, String descriptor) {
-
-		String newDescriptor = null;
-
-		int dlen = descriptor.length();
-		for (int offset = 0; offset < dlen; ) {
-			char c = descriptor.charAt(offset);
-			switch (c) {
-			case VMDescriptor.C_VOID :
-			case VMDescriptor.C_BOOLEAN:
-			case VMDescriptor.C_BYTE:
-			case VMDescriptor.C_CHAR:
-			case VMDescriptor.C_SHORT:
-			case VMDescriptor.C_INT:
-			case VMDescriptor.C_LONG:
-			case VMDescriptor.C_FLOAT:
-			case VMDescriptor.C_DOUBLE:
-			case VMDescriptor.C_ARRAY:
-			case VMDescriptor.C_METHOD:
-			case VMDescriptor.C_ENDMETHOD:
-			default:
-				offset++;
-				continue;
-
-			case VMDescriptor.C_CLASS:
-				{
-				int startOffset = offset;
-				while (descriptor.charAt(offset++) != VMDescriptor.C_ENDCLASS)
-					;
-				int endOffset = offset;
-
-				// name includes L and ;
-				String name = descriptor.substring(startOffset, endOffset);
-				String newName = (String) classNameMap.get(name);
-				if (newName != null) {
-					if (newDescriptor == null)
-						newDescriptor = descriptor;
-
-					// we just replace the first occurance of it,
-					// the loop will hit any next occurance.
-					int startPos = newDescriptor.indexOf(name);
-
-					String tmp;
-					if (startPos == 0)
-						tmp = newName;
-					else
-						tmp = newDescriptor.substring(0, startPos) +
-								newName;
-
-					int endPos = startPos + name.length();
-
-					if (endPos < newDescriptor.length()) {
-
-						tmp += newDescriptor.substring(endPos , newDescriptor.length());
-					}
-
-
-					newDescriptor = tmp;
-				}
-				}
-			}
-
-
-		}
-		//if (newDescriptor != null) {
-		//	System.out.println("O - " + descriptor);
-		//	System.out.println("N - " + newDescriptor);
-		//}
-		return newDescriptor;
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.classfile
+   (C) Copyright IBM Corp. 2001, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.classfile;
+
+
+import java.io.InputStream;
+import java.util.Enumeration;
+
+import java.io.IOException;
+import java.util.Vector;
+
+import org.apache.derby.iapi.services.classfile.VMDescriptor;
+import org.apache.derby.iapi.services.classfile.VMDescriptor;
+import java.util.HashSet;
+
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Collections;
+
+
+/** 
+*/
+
+public class ClassInvestigator extends ClassHolder {
+	/**
+		IBM Copyright &copy notice.
+	*/
+
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2001_2004;
+
+	public static ClassInvestigator load(InputStream is)
+		throws IOException {
+
+		ClassInput classInput = new ClassInput(is);
+
+		// Check the header
+		checkHeader(classInput);
+
+		//	Read in the Constant Pool
+		int constantPoolCount = classInput.getU2();
+
+		ClassInvestigator ci = new ClassInvestigator(constantPoolCount);
+		// Yes, index starts at 1, The '0'th constant pool entry
+		// is reserved for the JVM and is not present in the class file.
+		for (int i = 1; i < constantPoolCount; ) {
+			ConstantPoolEntry item = ClassInvestigator.getConstant(classInput);
+			i += ci.addEntry(item.getKey(), item);
+		}
+
+		// Read in access_flags and class indexes
+		ci.access_flags = classInput.getU2();
+		ci.this_class = classInput.getU2();
+		ci.super_class = classInput.getU2();
+
+		// interfaces is a simple int array
+		int interfaceCount = classInput.getU2();
+		if (interfaceCount != 0) {
+			ci.interfaces = new int[interfaceCount];
+			for (int i = 0; i < interfaceCount; i++)
+				ci.interfaces[i] = classInput.getU2();
+		}
+
+		int fieldCount = classInput.getU2();
+		if (fieldCount != 0) {
+			ci.field_info = new MemberTable(fieldCount);
+			for (int i = 0; i < fieldCount; i++)
+			{
+				ci.field_info.addEntry(readClassMember(ci, classInput));
+			}
+		}
+
+		int methodCount = classInput.getU2();
+		if (methodCount != 0) {
+ 			ci.method_info = new MemberTable(methodCount);
+			for (int i = 0; i < methodCount; i++)
+			{
+				ci.method_info.addEntry(readClassMember(ci, classInput));
+			}
+		}
+
+		int attributeCount = classInput.getU2();
+		if (attributeCount != 0) {
+			ci.attribute_info = new Attributes(attributeCount);
+
+			for (int i = 0; i < attributeCount; i++)
+				ci.attribute_info.addEntry(new AttributeEntry(classInput));
+		}
+		return ci;
+
+	}
+
+	private static ClassMember readClassMember(ClassInvestigator ci, ClassInput in)
+		throws IOException {
+
+		ClassMember member = new ClassMember(ci, in.getU2(),  in.getU2(), in.getU2());
+
+		int attributeCount = in.getU2();
+		if (attributeCount != 0) {
+			member.attribute_info = new Attributes(attributeCount);
+			for (int i = 0; i < attributeCount; i++)
+				member.attribute_info.addEntry(new AttributeEntry(in));
+		}
+			
+		return member;
+	}
+
+	/*
+	**	Constructors.
+	*/
+
+	private ClassInvestigator(int constantPoolCount) {
+		super(constantPoolCount);
+	}
+
+	/*
+	** Methods to investigate this class
+	*/
+
+
+	public Enumeration implementedInterfaces()
+	{
+		int interfaceCount = interfaces == null ? 0 : interfaces.length;
+		Vector implemented = new Vector(interfaceCount);
+
+        for (int i = 0; i < interfaceCount; i++)
+        {
+            implemented.addElement(className(interfaces[i]));
+        }
+        return implemented.elements();
+	}
+    public Enumeration getFields() {
+		if (field_info == null)
+			return Collections.enumeration(Collections.EMPTY_LIST);
+
+		return field_info.entries.elements();
+	}
+
+    public Enumeration getMethods() {
+		if (method_info == null)
+			return Collections.enumeration(Collections.EMPTY_LIST);
+		return method_info.entries.elements();
+	}
+
+    public Enumeration referencedClasses() {
+        return getClasses(getMethods(), getFields() );
+    }
+
+	/**
+		Return an Enumeration of all referenced classes
+	*/
+
+	private Enumeration getClasses(Enumeration methods, Enumeration fields)
+	{
+		return new ClassEnumeration(this, cptEntries.elements(), methods, fields);
+	}
+
+	public Enumeration getStrings() {
+		HashSet strings = new HashSet(30, 0.8f);
+		
+		int size = cptEntries.size();
+		for (int i = 1; i < size; i++) {
+			ConstantPoolEntry cpe = getEntry(i);
+
+			if ((cpe == null) || (cpe.getTag() != VMDescriptor.CONSTANT_String))
+				continue;
+
+			CONSTANT_Index_info cii = (CONSTANT_Index_info) cpe;
+
+			strings.add(nameIndexToString(cii.getI1()));
+		}
+
+		return java.util.Collections.enumeration(strings);
+	}
+
+    public ClassMember getMember(String simpleName, String descriptor) {
+
+		if (descriptor.startsWith("(")) {
+			if (method_info == null)
+				return null;
+			return method_info.find(simpleName, descriptor);
+		}
+		else {
+			if (field_info == null)
+				return null;
+			return  field_info.find(simpleName, descriptor);
+		}
+	}
+
+	/**
+		Return an Enumeration of all Member References
+	*/
+/*
+	Enumeration getMemberReferences() {
+		return new ReferenceEnumeration(this, elements());
+	}
+*/
+
+	/*
+	** Methods to modify the class.
+	*/
+	// remove all atttributes that are not essential
+	public void removeAttributes() throws IOException {
+
+		// Class level attributes
+		if (attribute_info != null) {
+			for (int i = attribute_info.size() - 1; i >= 0 ; i--) {
+
+				AttributeEntry ae = (AttributeEntry) attribute_info.elementAt(i);
+				String name = nameIndexToString(ae.getNameIndex());
+				if (name.equals("SourceFile"))
+					attribute_info.removeElementAt(i);
+				else if (name.equals("InnerClasses"))
+					; // leave in
+				else
+					System.err.println("WARNING - Unknown Class File attribute " + name);
+			}
+
+			if (attribute_info.size() == 0)
+				attribute_info = null;
+		}
+		attribute_info = null;
+
+		// fields
+		for (Enumeration e = getFields(); e.hasMoreElements(); ) {
+			ClassMember member = (ClassMember) e.nextElement();
+
+			Attributes attrs = member.attribute_info;
+
+			if (attrs != null) {
+
+				for (int i = attrs.size() - 1; i >= 0 ; i--) {
+
+					AttributeEntry ae = (AttributeEntry) attrs.elementAt(i);
+					String name = nameIndexToString(ae.getNameIndex());
+					if (name.equals("ConstantValue"))
+						; // leave in
+					else if (name.equals("Synthetic"))
+						; // leave in
+					else
+						System.err.println("WARNING - Unknown Field attribute " + name);
+				}
+
+				if (attrs.size() == 0)
+					member.attribute_info = null;
+			}
+
+		}
+
+		// methods
+		for (Enumeration e = getMethods(); e.hasMoreElements(); ) {
+			ClassMember member = (ClassMember) e.nextElement();
+
+			Attributes attrs = member.attribute_info;
+
+			if (attrs != null) {
+
+				for (int i = attrs.size() - 1; i >= 0 ; i--) {
+
+					AttributeEntry ae = (AttributeEntry) attrs.elementAt(i);
+					String name = nameIndexToString(ae.getNameIndex());
+					if (name.equals("Code"))
+						processCodeAttribute(member, ae);
+					else if (name.equals("Exceptions"))
+						; // leave in
+					else if (name.equals("Deprecated"))
+						; // leave in
+					else if (name.equals("Synthetic"))
+						; // leave in
+					else
+						System.err.println("WARNING - Unknown method attribute " + name);
+				}
+
+				if (attrs.size() == 0)
+					member.attribute_info = null;
+			}
+
+		}
+	}
+
+	private void processCodeAttribute(ClassMember member, AttributeEntry ae) throws IOException {
+
+		ClassInput ci = new ClassInput(new java.io.ByteArrayInputStream(ae.infoIn));
+
+
+		ci.skipBytes(4); // puts us at code_length
+		int len = ci.getU4();
+		ci.skipBytes(len); // puts us at exception_table_length
+		int count = ci.getU2();
+		if (count != 0)
+			ci.skipBytes(8 * count);
+
+		int nonAttrLength = 4 + 4 + len + 2 + (8 * count);
+
+		// now at attributes
+
+		count = ci.getU2();
+		if (count == 0)
+			return;
+
+		int newCount = count;
+		for (int i = 0; i < count; i++) {
+
+			int nameIndex = ci.getU2();
+			String name = nameIndexToString(nameIndex);
+			if (name.equals("LineNumberTable") || name.equals("LocalVariableTable"))
+				newCount--;
+			else
+				System.err.println("ERROR - Unknown code attribute " + name);
+
+			len = ci.getU4();
+			ci.skipBytes(len);
+		}
+
+		if (newCount != 0) {
+			System.err.println("ERROR - expecting all code attributes to be removed");
+			System.exit(1);
+		}
+
+		// this is only coded for all attributes within a Code attribute being removed.
+
+		byte[] newInfo = new byte[nonAttrLength + 2];
+		System.arraycopy(ae.infoIn, 0, newInfo, 0, nonAttrLength);
+		// last two bytes are left at 0 which means 0 attributes
+		ae.infoIn = newInfo;
+	}
+
+	public void renameClassElements(Hashtable classNameMap, Hashtable memberNameMap) {
+
+		// this & super class
+		renameString(classNameMap, (CONSTANT_Index_info) getEntry(this_class));
+		renameString(classNameMap, (CONSTANT_Index_info) getEntry(super_class));
+
+		// implemented interfaces
+		// handled by Class entries below
+
+		// classes & Strings
+		// descriptors
+		int size = cptEntries.size();
+		for (int i = 1; i < size; i++) {
+			ConstantPoolEntry cpe = getEntry(i);
+
+			if (cpe == null)
+				continue;
+
+			switch (cpe.getTag()) {
+			case VMDescriptor.CONSTANT_String:
+			case VMDescriptor.CONSTANT_Class:
+				{
+				CONSTANT_Index_info cii = (CONSTANT_Index_info) cpe;
+				renameString(classNameMap, cii);
+				break;
+				}
+			case VMDescriptor.CONSTANT_NameAndType:
+				{
+				CONSTANT_Index_info cii = (CONSTANT_Index_info) cpe;
+				String newDescriptor = newDescriptor(classNameMap, nameIndexToString(cii.getI2()));
+				if (newDescriptor != null) {
+					doRenameString(cii.getI2(), newDescriptor);
+				}
+				break;
+				}
+
+			default:
+				continue;
+			}
+
+		}
+
+		//System.out.println("Starting Fields");
+
+		// now the methods & fields, only descriptors at this time
+		renameMembers(getFields(), classNameMap, memberNameMap);
+
+		renameMembers(getMethods(), classNameMap, memberNameMap);
+	}
+
+	private void renameMembers(Enumeration e, Hashtable classNameMap, Hashtable memberNameMap) {
+
+		for (; e.hasMoreElements(); ) {
+			ClassMember member = (ClassMember) e.nextElement();
+
+			String oldMemberName = nameIndexToString(member.name_index);
+			String newMemberName = (String) memberNameMap.get(oldMemberName);
+			if (newMemberName != null)
+				doRenameString(member.name_index, newMemberName);
+
+			String newDescriptor = newDescriptor(classNameMap, nameIndexToString(member.descriptor_index));
+			if (newDescriptor != null) {
+				doRenameString(member.descriptor_index, newDescriptor);
+			}
+		}
+
+	}
+
+	private void renameString(Hashtable classNameMap, CONSTANT_Index_info cii) {
+
+		int index = cii.getI1();
+
+		String name = nameIndexToString(index);
+		String newName = (String) classNameMap.get(name);
+		if (newName != null) {
+
+			doRenameString(index, newName);
+
+			return;
+		}
+
+		// have to look for arrays
+		if (cii.getTag() == VMDescriptor.CONSTANT_Class) {
+
+			if (name.charAt(0) == '[') {
+				int classOffset = name.indexOf('L') + 1;
+
+				String baseClassName = name.substring(classOffset, name.length() - 1);
+
+
+				newName = (String) classNameMap.get(baseClassName);
+
+				if (newName != null) {
+
+					String newArrayClassName = name.substring(0, classOffset) + newName + ";";
+
+					doRenameString(index, newArrayClassName);
+
+				}
+
+			}
+		}
+	}
+
+	private void doRenameString(int index, String newName) {
+		ConstantPoolEntry cpe = getEntry(index);
+		if (cpe.getTag() != VMDescriptor.CONSTANT_Utf8)
+			throw new RuntimeException("unexpected type " + cpe);
+
+		CONSTANT_Utf8_info newCpe = new CONSTANT_Utf8_info(newName);
+
+		cptHashTable.remove(cpe.getKey());
+		cptHashTable.put(cpe.getKey(), cpe);
+
+		newCpe.index = index;
+
+		cptEntries.setElementAt(newCpe, index);
+	}
+
+	/*
+	**
+	*/
+	static private void checkHeader(ClassInput in) throws IOException {
+		int magic = in.getU4();
+		int minor_version = in.getU2();
+		int major_version = in.getU2();
+
+
+		if (magic != VMDescriptor.JAVA_CLASS_FORMAT_MAGIC)
+			   throw new ClassFormatError();
+   	}
+	private static ConstantPoolEntry getConstant(ClassInput in)
+		throws IOException {
+
+		ConstantPoolEntry item;
+		int tag;		
+		tag = in.readUnsignedByte();
+
+		switch (tag) {
+		case VMDescriptor.CONSTANT_Class:
+		case VMDescriptor.CONSTANT_String:
+			item = new CONSTANT_Index_info(tag, in.getU2(), 0);
+			break;
+
+		case VMDescriptor.CONSTANT_NameAndType:
+		case VMDescriptor.CONSTANT_Fieldref:
+		case VMDescriptor.CONSTANT_Methodref:
+		case VMDescriptor.CONSTANT_InterfaceMethodref:
+			item = new CONSTANT_Index_info(tag, in.getU2(), in.getU2());
+			break;
+
+		case VMDescriptor.CONSTANT_Integer:
+			item = new CONSTANT_Integer_info(in.getU4());
+			break;
+
+		case VMDescriptor.CONSTANT_Float:
+			item = new CONSTANT_Float_info(in.readFloat());
+			break;
+
+		case VMDescriptor.CONSTANT_Long:
+			item = new CONSTANT_Long_info(in.readLong());
+			break;
+
+		case VMDescriptor.CONSTANT_Double:
+			item = new CONSTANT_Double_info(in.readDouble());
+			break;
+
+		case VMDescriptor.CONSTANT_Utf8:
+			item = new CONSTANT_Utf8_info(in.readUTF());
+			break;
+		default:
+			throw new ClassFormatError();
+		}
+
+		return item;
+	}
+	public static String newDescriptor(Hashtable classNameMap, String descriptor) {
+
+		String newDescriptor = null;
+
+		int dlen = descriptor.length();
+		for (int offset = 0; offset < dlen; ) {
+			char c = descriptor.charAt(offset);
+			switch (c) {
+			case VMDescriptor.C_VOID :
+			case VMDescriptor.C_BOOLEAN:
+			case VMDescriptor.C_BYTE:
+			case VMDescriptor.C_CHAR:
+			case VMDescriptor.C_SHORT:
+			case VMDescriptor.C_INT:
+			case VMDescriptor.C_LONG:
+			case VMDescriptor.C_FLOAT:
+			case VMDescriptor.C_DOUBLE:
+			case VMDescriptor.C_ARRAY:
+			case VMDescriptor.C_METHOD:
+			case VMDescriptor.C_ENDMETHOD:
+			default:
+				offset++;
+				continue;
+
+			case VMDescriptor.C_CLASS:
+				{
+				int startOffset = offset;
+				while (descriptor.charAt(offset++) != VMDescriptor.C_ENDCLASS)
+					;
+				int endOffset = offset;
+
+				// name includes L and ;
+				String name = descriptor.substring(startOffset, endOffset);
+				String newName = (String) classNameMap.get(name);
+				if (newName != null) {
+					if (newDescriptor == null)
+						newDescriptor = descriptor;
+
+					// we just replace the first occurance of it,
+					// the loop will hit any next occurance.
+					int startPos = newDescriptor.indexOf(name);
+
+					String tmp;
+					if (startPos == 0)
+						tmp = newName;
+					else
+						tmp = newDescriptor.substring(0, startPos) +
+								newName;
+
+					int endPos = startPos + name.length();
+
+					if (endPos < newDescriptor.length()) {
+
+						tmp += newDescriptor.substring(endPos , newDescriptor.length());
+					}
+
+
+					newDescriptor = tmp;
+				}
+				}
+			}
+
+
+		}
+		//if (newDescriptor != null) {
+		//	System.out.println("O - " + descriptor);
+		//	System.out.println("N - " + newDescriptor);
+		//}
+		return newDescriptor;
+	}
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassMember.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassMember.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassMember.java	Fri Sep 24 10:33:20 2004
@@ -1,85 +1,85 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.classfile
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.classfile;
-
-import java.lang.reflect.Modifier;
-
-import java.io.IOException;
-
-
-
-public class ClassMember {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-	protected ClassHolder cpt;
-	protected int access_flags;
-	protected int name_index;
-	protected int descriptor_index;
-	protected Attributes attribute_info; // can be null
-
-	ClassMember(ClassHolder cpt, int modifier, int name, int descriptor) {
-		this.cpt = cpt;
-		name_index = name;
-		descriptor_index = descriptor;
-		access_flags = modifier;
-	}
-
-	/*
-	** Public methods from ClassMember
-	*/
-
-    public int getModifier() {
-			return access_flags;
-	}
-
-    public String getDescriptor() {
-		return cpt.nameIndexToString(descriptor_index);
-	}
-	
-	public String getName() {
-		return cpt.nameIndexToString(name_index);
-	}
-
-	public void addAttribute(String attributeName, ClassFormatOutput info) {
-
-		if (attribute_info == null)
-			attribute_info = new Attributes(1);
-
-		attribute_info.addEntry(new AttributeEntry(cpt.addUtf8(attributeName), info));
-	}
-
-
-	/*
-	**	 ----
-	*/
-
-	void put(ClassFormatOutput out) throws IOException {
-		out.putU2(access_flags);
-		out.putU2(name_index);
-		out.putU2(descriptor_index);
-
-		if (attribute_info != null) {
-			out.putU2(attribute_info.size());
-			attribute_info.put(out);
-		} else {
-			out.putU2(0);
-		}
-	}
-
-	int classFileSize() {
-		int size = 2 + 2 + 2 + 2;
-		if (attribute_info != null)
-			size += attribute_info.classFileSize();
-		return size;
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.classfile
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.classfile;
+
+import java.lang.reflect.Modifier;
+
+import java.io.IOException;
+
+
+
+public class ClassMember {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+	protected ClassHolder cpt;
+	protected int access_flags;
+	protected int name_index;
+	protected int descriptor_index;
+	protected Attributes attribute_info; // can be null
+
+	ClassMember(ClassHolder cpt, int modifier, int name, int descriptor) {
+		this.cpt = cpt;
+		name_index = name;
+		descriptor_index = descriptor;
+		access_flags = modifier;
+	}
+
+	/*
+	** Public methods from ClassMember
+	*/
+
+    public int getModifier() {
+			return access_flags;
+	}
+
+    public String getDescriptor() {
+		return cpt.nameIndexToString(descriptor_index);
+	}
+	
+	public String getName() {
+		return cpt.nameIndexToString(name_index);
+	}
+
+	public void addAttribute(String attributeName, ClassFormatOutput info) {
+
+		if (attribute_info == null)
+			attribute_info = new Attributes(1);
+
+		attribute_info.addEntry(new AttributeEntry(cpt.addUtf8(attributeName), info));
+	}
+
+
+	/*
+	**	 ----
+	*/
+
+	void put(ClassFormatOutput out) throws IOException {
+		out.putU2(access_flags);
+		out.putU2(name_index);
+		out.putU2(descriptor_index);
+
+		if (attribute_info != null) {
+			out.putU2(attribute_info.size());
+			attribute_info.put(out);
+		} else {
+			out.putU2(0);
+		}
+	}
+
+	int classFileSize() {
+		int size = 2 + 2 + 2 + 2;
+		if (attribute_info != null)
+			size += attribute_info.classFileSize();
+		return size;
+	}
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ConstantPoolEntry.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ConstantPoolEntry.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ConstantPoolEntry.java	Fri Sep 24 10:33:20 2004
@@ -1,109 +1,109 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.classfile
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.classfile;
-
-import org.apache.derby.iapi.services.classfile.VMDescriptor;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-import java.io.IOException;
-
-/** Constant Pool class - pages 92-99 */
-public abstract class ConstantPoolEntry /*implements PoolEntry*/
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-	
-	protected int tag; // u1 (page 83)
-	protected boolean doubleSlot; // Some entries take up two slots! (see footnote page 98) 
-
-	/* Index within Vector */
-	protected int index;
-
-	protected ConstantPoolEntry(int tag) {
-		this.tag = tag;
-	}
-
-	int getIndex() {
-		if (SanityManager.DEBUG) {
-			if (index <= 0)
-			{
-				SanityManager.THROWASSERT("index is expected to be > 0, is " + index);
-			}
-		}
-		return index;
-	}
-
-	void setIndex(int index) {
-		this.index = index;
-	}
-
-	boolean doubleSlot() {
-		return doubleSlot;
-	}
-
-	/**
-		Return the key used to key this object in a hashtable
-	*/
-	Object getKey() {
-		return this;
-	}
-
-	/**
-		Return an estimate of the size of the constant pool entry.
-	*/
-	abstract int classFileSize();
-
-	void put(ClassFormatOutput out) throws IOException {
-		out.putU1(tag);
-	}
-
-	/*
-	** Public API methods
-	*/
-
-	/**
-		Return the tag or type of the entry. Will be equal to one of the
-		constants above, e.g. CONSTANT_Class.
-	*/
-	final int getTag() {
-		return tag;
-	}
-
-	/**	
-		Get the first index in a index type pool entry.
-		This call is valid when getTag() returns one of
-		<UL> 
-		<LI> CONSTANT_Class
-		<LI> CONSTANT_Fieldref
-		<LI> CONSTANT_Methodref
-		<LI> CONSTANT_InterfaceMethodref
-		<LI> CONSTANT_String
-		<LI> CONSTANT_NameAndType
-		</UL>
-	*/
-	int getI1() { return 0; }
-
-	/**	
-		Get the second index in a index type pool entry.
-		This call is valid when getTag() returns one of
-		<UL> 
-		<LI> CONSTANT_Fieldref
-		<LI> CONSTANT_Methodref
-		<LI> CONSTANT_InterfaceMethodref
-		<LI> CONSTANT_NameAndType
-		</UL>
-	*/	
-	int getI2() { return 0; };
-}
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.classfile
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.classfile;
+
+import org.apache.derby.iapi.services.classfile.VMDescriptor;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+import java.io.IOException;
+
+/** Constant Pool class - pages 92-99 */
+public abstract class ConstantPoolEntry /*implements PoolEntry*/
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+	
+	protected int tag; // u1 (page 83)
+	protected boolean doubleSlot; // Some entries take up two slots! (see footnote page 98) 
+
+	/* Index within Vector */
+	protected int index;
+
+	protected ConstantPoolEntry(int tag) {
+		this.tag = tag;
+	}
+
+	int getIndex() {
+		if (SanityManager.DEBUG) {
+			if (index <= 0)
+			{
+				SanityManager.THROWASSERT("index is expected to be > 0, is " + index);
+			}
+		}
+		return index;
+	}
+
+	void setIndex(int index) {
+		this.index = index;
+	}
+
+	boolean doubleSlot() {
+		return doubleSlot;
+	}
+
+	/**
+		Return the key used to key this object in a hashtable
+	*/
+	Object getKey() {
+		return this;
+	}
+
+	/**
+		Return an estimate of the size of the constant pool entry.
+	*/
+	abstract int classFileSize();
+
+	void put(ClassFormatOutput out) throws IOException {
+		out.putU1(tag);
+	}
+
+	/*
+	** Public API methods
+	*/
+
+	/**
+		Return the tag or type of the entry. Will be equal to one of the
+		constants above, e.g. CONSTANT_Class.
+	*/
+	final int getTag() {
+		return tag;
+	}
+
+	/**	
+		Get the first index in a index type pool entry.
+		This call is valid when getTag() returns one of
+		<UL> 
+		<LI> CONSTANT_Class
+		<LI> CONSTANT_Fieldref
+		<LI> CONSTANT_Methodref
+		<LI> CONSTANT_InterfaceMethodref
+		<LI> CONSTANT_String
+		<LI> CONSTANT_NameAndType
+		</UL>
+	*/
+	int getI1() { return 0; }
+
+	/**	
+		Get the second index in a index type pool entry.
+		This call is valid when getTag() returns one of
+		<UL> 
+		<LI> CONSTANT_Fieldref
+		<LI> CONSTANT_Methodref
+		<LI> CONSTANT_InterfaceMethodref
+		<LI> CONSTANT_NameAndType
+		</UL>
+	*/	
+	int getI2() { return 0; };
+}
+

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/stream/HeaderPrintWriter.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/stream/HeaderPrintWriter.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/stream/HeaderPrintWriter.java	Fri Sep 24 10:33:20 2004
@@ -1,78 +1,78 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.stream
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.stream;
-
-import java.io.PrintWriter;
-
-/**
- * A HeaderPrintWriter is like a PrintWriter with support for
- * including a header in the output. It is expected users
- * will use HeaderPrintWriters to prepend headings to trace
- * and log messages.
- * 
- */
-public interface HeaderPrintWriter
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	/**
-	 * Puts out some setup info for
-	 * the current write and the write(s) that will be put out next.
-	 * It ends with a \n\r.
-	 * <p>
-	 * All other writes to the stream use the
-	 * PrintStream interface.
-	 */
-	public void printlnWithHeader(String message);
-
-	/**
-	 * Return the header for the stream.
-	 */
-	public PrintWriterGetHeader getHeader();
-	
-	/**
-	 * Gets a PrintWriter object for writing to this HeaderPrintWriter.
-	 * Users may use the HeaderPrintWriter to access methods not included
-	 * in this interface or to invoke methods or constructors which require
-	 * a PrintWriter. 
-	 *
-	 * Interleaving calls to a printWriter and its associated HeaderPrintWriter
-	 * is not supported.
-	 * 
-	 */
-	public PrintWriter getPrintWriter();
-
-	/*
-	 * The routines that mimic java.io.PrintWriter...
-	 */
-	/**
-	 * @see java.io.PrintWriter#print
-	 */
-	public void print(String message);
-
-	/**
-	 * @see java.io.PrintWriter#println
-	 */
-	public void println(String message);
-
-	/**
-	 * @see java.io.PrintWriter#println
-	 */
-	public void println(Object message);
-
-	/**
-	* @see java.io.PrintWriter#flush
-	 */
-	public void flush();
-}
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.stream
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.stream;
+
+import java.io.PrintWriter;
+
+/**
+ * A HeaderPrintWriter is like a PrintWriter with support for
+ * including a header in the output. It is expected users
+ * will use HeaderPrintWriters to prepend headings to trace
+ * and log messages.
+ * 
+ */
+public interface HeaderPrintWriter
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	/**
+	 * Puts out some setup info for
+	 * the current write and the write(s) that will be put out next.
+	 * It ends with a \n\r.
+	 * <p>
+	 * All other writes to the stream use the
+	 * PrintStream interface.
+	 */
+	public void printlnWithHeader(String message);
+
+	/**
+	 * Return the header for the stream.
+	 */
+	public PrintWriterGetHeader getHeader();
+	
+	/**
+	 * Gets a PrintWriter object for writing to this HeaderPrintWriter.
+	 * Users may use the HeaderPrintWriter to access methods not included
+	 * in this interface or to invoke methods or constructors which require
+	 * a PrintWriter. 
+	 *
+	 * Interleaving calls to a printWriter and its associated HeaderPrintWriter
+	 * is not supported.
+	 * 
+	 */
+	public PrintWriter getPrintWriter();
+
+	/*
+	 * The routines that mimic java.io.PrintWriter...
+	 */
+	/**
+	 * @see java.io.PrintWriter#print
+	 */
+	public void print(String message);
+
+	/**
+	 * @see java.io.PrintWriter#println
+	 */
+	public void println(String message);
+
+	/**
+	 * @see java.io.PrintWriter#println
+	 */
+	public void println(Object message);
+
+	/**
+	* @see java.io.PrintWriter#flush
+	 */
+	public void flush();
+}
+

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/stream/InfoStreams.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/stream/InfoStreams.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/stream/InfoStreams.java	Fri Sep 24 10:33:20 2004
@@ -1,40 +1,40 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.stream
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.stream;
-
-/**
- *
- * The Basic Services provide InfoStreams for reporting
- * information.
- * <p>
- * When creating a message for a stream,
- * you can create an initial entry with header information
- * and then append to it as many times as desired.
- * <p>
- * 
- * @see HeaderPrintWriter
- * @author ames
- */
-public interface InfoStreams { 
-
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-
-	/**
-	 Return the default stream. If the default stream could not be set up as requested then
-	 it points indirectly to System.err.
-	 * 
-	 * @return the default stream.
-	 */
-	HeaderPrintWriter stream();
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.stream
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.stream;
+
+/**
+ *
+ * The Basic Services provide InfoStreams for reporting
+ * information.
+ * <p>
+ * When creating a message for a stream,
+ * you can create an initial entry with header information
+ * and then append to it as many times as desired.
+ * <p>
+ * 
+ * @see HeaderPrintWriter
+ * @author ames
+ */
+public interface InfoStreams { 
+
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+
+	/**
+	 Return the default stream. If the default stream could not be set up as requested then
+	 it points indirectly to System.err.
+	 * 
+	 * @return the default stream.
+	 */
+	HeaderPrintWriter stream();
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/stream/PrintWriterGetHeader.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/stream/PrintWriterGetHeader.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/stream/PrintWriterGetHeader.java	Fri Sep 24 10:33:20 2004
@@ -1,37 +1,37 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.stream
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.stream;
-
-/**
- * Get a header to prepend to a line of output. 
- * A HeaderPrintWriter requires an object which implements
- * this interface to construct headers for output lines.
- *
- * @see org.apache.derby.iapi.services.stream.HeaderPrintWriter
- */
-
-public interface PrintWriterGetHeader
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	/**
-	 *	getHeader
-	 *
-	 *  @return	The header for an output line. 
-	 *
-	 *  @see org.apache.derby.iapi.services.stream.HeaderPrintWriter
-	 **/
-
-	public String getHeader();
-}
-	
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.stream
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.stream;
+
+/**
+ * Get a header to prepend to a line of output. 
+ * A HeaderPrintWriter requires an object which implements
+ * this interface to construct headers for output lines.
+ *
+ * @see org.apache.derby.iapi.services.stream.HeaderPrintWriter
+ */
+
+public interface PrintWriterGetHeader
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	/**
+	 *	getHeader
+	 *
+	 *  @return	The header for an output line. 
+	 *
+	 *  @see org.apache.derby.iapi.services.stream.HeaderPrintWriter
+	 **/
+
+	public String getHeader();
+}
+	

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/uuid/UUIDFactory.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/uuid/UUIDFactory.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/uuid/UUIDFactory.java	Fri Sep 24 10:33:20 2004
@@ -1,69 +1,69 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.services.uuid
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.services.uuid;
-
-import org.apache.derby.catalog.UUID;
-
-/*
-	Internal comment (not for user documentation):
-  Although this is an abstract interface, I believe that the
-  underlying implementation of UUID will have to be DCE UUID.
-  This is because the string versions of UUIDs get stored in
-  the source code.  In other words, no matter what implementation
-  is used for UUIDs, strings that look like this
-  <blockquote><pre>
-	E4900B90-DA0E-11d0-BAFE-0060973F0942
-  </blockquote></pre>
-  will always have to be turned into universally unique objects
-  by the recreateUUID method
- */
-/**
-	
-  Generates and recreates unique identifiers.
-  
-  An example of such an identifier is:
-  <blockquote><pre>
-	E4900B90-DA0E-11d0-BAFE-0060973F0942
-  </blockquote></pre>
-  These resemble DCE UUIDs, but use a different implementation.
-  <P>
-  The string format is designed to be the same as the string
-  format produced by Microsoft's UUIDGEN program, although at
-  present the bit fields are probably not the same.
-  
- **/
-public interface UUIDFactory 
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-	/**
-	  Create a new UUID.  The resulting object is guaranteed
-	  to be unique "across space and time".
-	  @return		The UUID.
-	**/
- 	public UUID createUUID();
-
-	/**
-	  Recreate a UUID from a string produced by UUID.toString.
-	  @return		The UUID.
-	**/
-	public UUID recreateUUID(String uuidstring);
-
-	/**
-	  Recreate a UUID from a byte array produced by UUID.toByteArray.
-	  @return		The UUID.
-	  @see UUID#toByteArray
-	**/
-	public UUID recreateUUID(byte[] b);
-}
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.services.uuid
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.services.uuid;
+
+import org.apache.derby.catalog.UUID;
+
+/*
+	Internal comment (not for user documentation):
+  Although this is an abstract interface, I believe that the
+  underlying implementation of UUID will have to be DCE UUID.
+  This is because the string versions of UUIDs get stored in
+  the source code.  In other words, no matter what implementation
+  is used for UUIDs, strings that look like this
+  <blockquote><pre>
+	E4900B90-DA0E-11d0-BAFE-0060973F0942
+  </blockquote></pre>
+  will always have to be turned into universally unique objects
+  by the recreateUUID method
+ */
+/**
+	
+  Generates and recreates unique identifiers.
+  
+  An example of such an identifier is:
+  <blockquote><pre>
+	E4900B90-DA0E-11d0-BAFE-0060973F0942
+  </blockquote></pre>
+  These resemble DCE UUIDs, but use a different implementation.
+  <P>
+  The string format is designed to be the same as the string
+  format produced by Microsoft's UUIDGEN program, although at
+  present the bit fields are probably not the same.
+  
+ **/
+public interface UUIDFactory 
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+	/**
+	  Create a new UUID.  The resulting object is guaranteed
+	  to be unique "across space and time".
+	  @return		The UUID.
+	**/
+ 	public UUID createUUID();
+
+	/**
+	  Recreate a UUID from a string produced by UUID.toString.
+	  @return		The UUID.
+	**/
+	public UUID recreateUUID(String uuidstring);
+
+	/**
+	  Recreate a UUID from a byte array produced by UUID.toByteArray.
+	  @return		The UUID.
+	  @see UUID#toByteArray
+	**/
+	public UUID recreateUUID(byte[] b);
+}
+

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/Activation.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/Activation.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/Activation.java	Fri Sep 24 10:33:20 2004
@@ -1,617 +1,617 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.sql
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.sql;
-
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
-
-import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
-import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
-
-import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
-import org.apache.derby.iapi.sql.execute.ExecRow;
-import org.apache.derby.iapi.sql.execute.ExecutionFactory;
-import org.apache.derby.iapi.sql.execute.NoPutResultSet;
-import org.apache.derby.iapi.sql.execute.ConstantAction;
-import org.apache.derby.iapi.sql.execute.CursorResultSet;
-import org.apache.derby.iapi.sql.execute.TemporaryRowHolder;
-
-import org.apache.derby.iapi.store.access.ConglomerateController;
-import org.apache.derby.iapi.store.access.ScanController;
-import org.apache.derby.iapi.store.access.TransactionController;
-
-import org.apache.derby.iapi.types.DataValueFactory;
-
-import org.apache.derby.iapi.types.RowLocation;
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-
-import java.sql.SQLWarning;
-import java.util.Enumeration;
-import java.util.Vector;
-import java.util.Hashtable;
-
-
-/**
- * An activation contains all the local state information necessary
- * to execute a re-entrant PreparedStatement. The way it will actually work
- * is that a PreparedStatement will have an executable plan, which will be
- * a generated class. All of the local state will be variables in the class.
- * Creating a new instance of the executable plan will create the local state
- * variables. This means that an executable plan must implement this interface,
- * and that the PreparedStatement.getActivation() method will do a
- * "new" operation on the executable plan.
- * <p>
- * The fixed implementations of Activation in the Execution impl
- * package are used as skeletons for the classes generated for statements
- * when they are compiled.
- * <p>
- * There are no fixed implementations of Activation for statements;
- * a statement has an activation generated for it when it is compiled.
- *
- * @author Jeff Lichtman
- */
-
-public interface Activation
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	/**
-	 * Resets the activation to the "pre-execution" state -
-	 * that is, the state where it can be used to begin a new execution.
-	 * Frees local buffers, stops scans, resets counters to zero, sets
-	 * current date and time to an unitialized state, etc.
-	 *
-	 * @return	Nothing
-	 * @exception StandardException thrown on failure
-	 */
-	void	reset() throws StandardException;
-
-	/**
-	 * JDBC requires that all select statements be converted into cursors,
-	 * and that the cursor name be settable for each execution of a select
-	 * statement. The Language Module will support this, so that the JDBC
-	 * driver will not have to parse JSQL text. This method will have no
-	 * effect when called on non-select statements.
-	 * <p>
-	 * There will be a JSQL statement to disable the "cursorization" of
-	 * all select statements. For non-cursorized select statements, this
-	 * method will have no effect.
-	 * <p>
-	 * This has no effect if the activation has been closed.
-	 * <p>
-	 * @param cursorName  The cursor name to use.
-	 */
-	void	setCursorName(String cursorName);
-
-	/**
-	 * Temporary tables can be declared with ON COMMIT DELETE ROWS. But if the table has a held curosr open at
-	 * commit time, data should not be deleted from the table. This method, (gets called at commit time) checks if this
-	 * activation held cursor and if so, does that cursor reference the passed temp table name.
-	 *
-	 * @return	true if this activation has held cursor and if it references the passed temp table name
-	 */
-	public boolean checkIfThisActivationHasHoldCursor(String tableName);
-
-	/**
-	 * Gets the ParameterValueSet for this execution of the statement.
-	 *
-	 * @return	The ParameterValueSet for this execution of the
-	 *		statement. Returns NULL if there are no parameters.
-	 */
-	ParameterValueSet	getParameterValueSet();
-
-	/**
-	 * Sets the parameter values for this execution of the statement.
-	 * <p>
-	 * Has no effect if the activation has been closed.
-	 *
-	 * <p>
-	 * NOTE: The setParameters() method is currently unimplemented. 
-	 * A statement with parameters will generate its own ParameterValueSet,
-	 * which can be gotten with the getParameterValueSet() method (above).
-	 * The idea behind setParameters() is to improve performance when
-	 * operating across a network by allowing all the parameters to be set
-	 * in one call, as opposed to one call per parameter.
-	 *
-	 * @param parameterValues	The values of the parameters.
-	 *
-	 * @return	Nothing
-	 */
-	void	setParameters(ParameterValueSet parameterValues, DataTypeDescriptor[] parameterTypes) throws StandardException;
-
-	/**
-	 * When the prepared statement is executed, it passes
-	 * execution on to the activation execution was requested for.
-	 *
-	 * @return the ResultSet for further manipulation, if any.
-	 *
-	 * @exception StandardException		Thrown on failure
-	 */
-	ResultSet execute() throws StandardException;
-
-	/**
-		Closing an activation statement marks it as unusable. Any other
-		requests made on it will fail.  An activation should be
-		marked closed when it is expected to not be used any longer,
-		i.e. when the connection for it is closed, or it has suffered some
-		sort of severe error. This will also close its result set and
-		release any resources it holds e.g. for parameters.
-		<P>
-		Any class that implements this must be prepared to be executed
-		from garbage collection, ie. there is no matching context stack.
-
-		@exception StandardException		Thrown on failure
-	 */
-	void close() throws StandardException;
-
-	/**
-		Find out if the activation is closed or not.
-
-		@return true if the Activation has been closed.
-	 */
-	boolean isClosed();
-
-	/**
-		Set this Activation for a single execution.
-		E.g. a java.sql.Statement execution.
-	*/
-	void setSingleExecution();
-
-	/**
-		Returns true if this Activation is only going to be used for
-		one execution.
-	*/
-	boolean isSingleExecution();
-
-	/**
-	  Returns the chained list of warnings. Returns null
-	  if there are no warnings.
-	  */
-	SQLWarning getWarnings();
-
-	/**
-	  Add a warning to the activation
-	  */
-	void addWarning(SQLWarning w);
-
-	/**
-	  Clear the activation's warnings.
-	  */
-	void clearWarnings();
-
-	/**
-	 * Get the language connection context associated with this activation
-     */
-	public	LanguageConnectionContext	getLanguageConnectionContext();
-
-	/**
-	 * Get the Execution TransactionController associated with this 
-	 * activation/lcc.
-	 */
-	TransactionController getTransactionController();
-
-	/**
-	 * Returns the current result set for this activation, i.e.
-	 * the one returned by the last execute() call.  If there has
-	 * been no execute call or the activation has been reset or closed,
-	 * a null is returned.
-	 *
-	 * @return the current ResultSet of this activation.
-	 */
-	ResultSet getResultSet();
-
-	/**
-	 * Sets the ResultSet to be returned by getResultSet() to null.
-	 */
-	void clearResultSet();
-
-	/**
-	 * Generated plans have a current row field for ease in defining
-	 * the methods and finding them dynamically. The interface is
-	 * used to set the row before a dynamic method that uses it is
-	 * invoked.
-	 * <p>
-	 * When all processing on the currentRow has been completed,
-	 * callers should call activation.clearCurrentRow(resultSetNumber)
-	 * to ensure that no unnecessary references are retained to rows.
-	 * This will allow the rows no longer in use to be collected by
-	 * the garbage collecter.
-	 *
-	 * @param currentRow		The row to be operated upon.
-	 * @param resultSetNumber	The resultSetNumber for the current ResultSet
-	 *
-	 * @return Nothing
-	 *
-	 */
-	void setCurrentRow(ExecRow currentRow, int resultSetNumber);
-
-	/**
-	 * Generated plans have a current row field for ease in defining
-	 * the methods and finding them dynamically. The interface is
-	 * used to set the row before a dynamic method that uses it is
-	 * invoked.
-	 * <p>
-	 * When all processing on the currentRow has been completed,
-	 * callers should call activation.clearCurrentRow(resultSetNumber)
-	 * to ensure that no unnecessary references are retained to rows.
-	 * This will allow the rows no longer in use to be collected by
-	 * the garbage collecter.
-	 *
-	 * @param resultSetNumber	The resultSetNumber for the current ResultSet
-	 *
-	 * @return Nothing
-	 */
-	/* RESOLVE - this method belongs on an internal, not external, interface */
-	void clearCurrentRow(int resultSetNumber);
-
-	/**
-	 * Get the prepared statement that this activation is for.
-	 *
-	 * @return the prepared statement this activation is for.
-	 *
-	 */
-	ExecPreparedStatement getPreparedStatement();
-
-	/**
-		Check the validity of the current executing statement. Needs to be
-		called after a statement has obtained the relevant table locks on
-		the 
-	*/
-	public void checkStatementValidity() throws StandardException;
-
-	/**
-	 * Get the result description for this activation, if it has one.
-	 *
-	 * @return result description for this activation, if it has one;
-	 * otherwise, null.
-	 */
-	ResultDescription getResultDescription();
-
-	/**
-	 * Get the DataValueFactory
-	 *
-	 * @return DataValueFactory
-	 */
-	DataValueFactory getDataValueFactory();
-
-	/**
-	 * Get the ExecutionFactory
-	 *
-	 * @return ExecutionFactory
-	 */
-	ExecutionFactory getExecutionFactory();
-
-	/**
-		Get the saved RowLocation.
-
-		@param itemNumber	The saved item number.
-
-		@return	A RowLocation template for the conglomerate
-	 */
-	public RowLocation getRowLocationTemplate(int itemNumber);
-
-	/**
-		Get the number of subqueries in the entire query.
-		@return int	 The number of subqueries in the entire query.
-	 */
-	public int getNumSubqueries();
-
-	/**
-	 * Return the cursor name of this activation. This will differ
-	 * from its ResultSet's cursor name if it has been
-	 * altered with setCursorName. Thus this always returns the cursor
-	 * name of the next execution of this activation. The cursor name
-	 * of the current execution must be obtained from the ResultSet.
-	 * or this.getResultSet.getCursorName() [with null checking].
-	 * <p>
-	 * Statements that do not support cursors will return a null.
-	 * <p>
-	 * @return The cursor name.
-	 */
-	public String	getCursorName();
-
-	/**
-	 * Return the holdability of this activation.
-	 * <p>
-	 * @return The holdability of this activation.
-	 */
-	public boolean	getResultSetHoldability();
-
-	/**
-	 * Set current resultset holdability.
-	 *
-	 * @param resultSetHoldability	The new resultset holdability.
-	 *
-	 * @return Nothing.
-	 */
-	public void setResultSetHoldability(boolean resultSetHoldability);
-
-	/**
-	 * Set the auto-generated keys resultset mode to true for this activation.
-	 *
-	 * The specific columns for auto-generated keys resultset can be requested by
-	 * passing column positions array
-	 *
-	 * The specific columns for auto-generated keys resultset can be requested by
-	 * passing column names array
-	 *
-	 * Both the parameters would be null if user didn't request specific keys.
-	 * Otherwise, the user could request specific columns by passing column positions
-	 * or names array but not both.
-	 *
-	 * @param columnIndexes Request specific columns in auto-generated keys
-	 * resultset by passing column positions. null means no specific columns
-	 * requested by position
-	 *
-	 * @param columnNames Request specific columns in auto-generated keys
-	 * resultset by passing column names.  null means no specific columns
-	 * requested by position
-	 *
-	 * @return Nothing.
-	 */
-	public void setAutoGeneratedKeysResultsetInfo(int[] columnIndexes, String[] columnNames);
-
-	/**
-	 * Returns true if auto-generated keys resultset request was made for this
-	 * avtivation.
-	 * <p>
-	 * @return auto-generated keys resultset mode for this activation.
-	 */
-	public boolean	getAutoGeneratedKeysResultsetMode();
-
-	/**
-	 * Returns the column positions array of columns requested in auto-generated
-	 * keys resultset for this avtivation. Returns null if no specific column
-	 * requested by positions
-	 * <p>
-	 * @return column positions array of columns requested.
-	 */
-	public int[] getAutoGeneratedKeysColumnIndexes();
-
-	/**
-	 * Returns the column names array of columns requested in auto-generated
-	 * keys resultset for this avtivation. Returns null if no specific column
-	 * requested by names
-	 * <p>
-	 * @return column names array of columns requested.
-	 */
-	public String[] getAutoGeneratedKeysColumnNames();
-
-	/**
-	 * Mark the activation as unused.  
-	 */
-	public void markUnused();
-
-	/**
-	 * Is the activation in use?
-	 *
-	 * @return true/false
-	 */
-	public boolean isInUse();
-
-	/**
-	 * Tell this activation that the given ResultSet was found to have
-	 * the given number of rows.  This is used during execution to determine
-	 * whether a table has grown or shrunk.  If a table's size changes
-	 * significantly, the activation may invalidate its PreparedStatement
-	 * to force recompilation.
-	 *
-	 * Note that the association of row counts with ResultSets is kept
-	 * in the activation class, not in the activation itself.  This
-	 * means that this method must be synchronized.
-	 *
-	 * This method is not required to check the number of rows on each
-	 * call.  Because of synchronization, this check is likely to be
-	 * expensive, so it may only check every hundred calls or so.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public void informOfRowCount(NoPutResultSet resultSet, long rowCount)
-					throws StandardException;
-
-	/**
-	 * Get the ConglomerateController, if any, that has already
-	 * been opened for the heap when scaning for an update or delete.
-	 * (Saves opening the ConglomerateController twice.)
-	 *
-	 * @return The ConglomerateController, if available, to use for the update.
-	 */
-	public ConglomerateController getHeapConglomerateController();
-
-	/**
-	 * Set the ConglomerateController to be used for an update or delete.
-	 * (Saves opening the ConglomerateController twice.)
-	 *
-	 * @param updateHeapCC	The ConglomerateController to reuse for the update or delete.
-	 *
-	 * @return Nothing.
-	 */
-	public void setHeapConglomerateController(ConglomerateController updateHeapCC);
-
-	/**
-	 * Clear the ConglomerateController to be used for an update or delete.
-	 * (Saves opening the ConglomerateController twice.)
-	 *
-	 * @return Nothing.
-	 */
-	public void clearHeapConglomerateController();
-
-	/**
-	 * Get the ScanController, if any, that has already
-	 * been opened for the index when scaning for an update or delete.
-	 * (Saves opening the ScanController twice.)
-	 *
-	 * @return The ScanController, if available, to use for the update.
-	 */
-	public ScanController getIndexScanController();
-
-	/**
-	 * Set the ScanController to be used for an update or delete,
-	 * when scanning an index that will also be updated
-	 * (Saves opening the ScanController twice.)
-	 *
-	 * @param indexSC	The ScanController to reuse for the update or delete.
-	 *
-	 * @return Nothing.
-	 */
-	public void setIndexScanController(ScanController indexSC);
-
-	/**
-	 * Get the conglomerate number of the index, if any, that has already
-	 * been opened for scaning for an update or delete.
-	 * (Saves opening the ScanController twice.)
-	 *
-	 * @return The conglomerate number, if available, to use for the update.
-	 */
-	public long getIndexConglomerateNumber();
-
-	/**
-	 * Set the conglomerate number of the index to be used for an update or delete,
-	 * when scanning an index that will also be updated
-	 * (Saves opening the ScanController twice.)
-	 *
-	 * @param indexConglomerateNumber The conglomerate number of the index to reuse for the update or delete.
-	 *
-	 * @return Nothing.
-	 */
-	public void setIndexConglomerateNumber(long indexConglomerateNumber);
-
-	/**
-	 * Clear the info for the index to be re-used for update/delete.
-	 * (ScanController and conglomerate number.)
-	 *
-	 * @return Nothing.
-	 */
-	public void clearIndexScanInfo();
-
-	/**
-	 * Mark the Activation as being for create table.
-	 * (NOTE: We can do certain optimizations for
-	 * create table that we can't do for other DDL.)
-	 *
-	 * @return Nothing.
-	 */
-	public void setForCreateTable();
-
-	/**
-	 * Get whether or not this activation is for
-	 * create table.
-	 * (NOTE: We can do certain optimizations for
-	 * create table that we can't do for other DDL.)
-	 *
-	 * @return Whether or not this activation is for
-	 *		   create table.
-	 */
-	public boolean getForCreateTable();
-
-	/**
-	 * Save the TableDescriptor for the target of 
-	 * DDL so that it can be passed between the
-	 * various ConstantActions during execution.
-	 *
-	 * @return Nothing.
-	 */
-	public void setDDLTableDescriptor(TableDescriptor td);
-
-	/**
-	 * Get the TableDescriptor for the target of
-	 * DDL.
-	 *
-	 * @return The TableDescriptor for the target of
-	 * DDL.
-	 */
-	public TableDescriptor getDDLTableDescriptor();
-
-	/**
-	 * Set the maximum # of rows.  (# of rows that can
-	 * be returned by a ResultSet.  0 means no limit.)
-	 *
-	 * @param maxRows Maximum # of rows. (0 means no limit.)
-	 *
-	 * @return Nothing.
-	 */
-	public void setMaxRows(int maxRows);
-
-	/**
-	 * Get the maximum # of rows.  (# of rows that can
-	 * be returned by a ResultSet.  0 means no limit.)
-	 *
-	 * @return Maximum # of rows.  (0 means no limit.)
-	 */
-	public int getMaxRows();
-
-	/**
-	 * Is this Activation for a cursor?
-	 *
-	 * @return Whether or not this Activation is for a cursor.
-	 */
-	public boolean isCursorActivation();
-
-	/**
-	 * Save the ResultSet for the target
-	 * of an update/delete to a VTI.
-	 *
-	 * @return Nothing.
-	 */
-	public void setTargetVTI(java.sql.ResultSet targetVTI);
-
-	/**
-	 * Get the ResultSet for the target
-	 * of an update/delete to a VTI.
-	 *
-	 * @return The ResultSet for the target
-	 * of an update/delete to a VTI.
-	 */
-	public java.sql.ResultSet getTargetVTI();
-
-	public ConstantAction	getConstantAction();
-
-	//store a reference to the parent table result sets
-	public void setParentResultSet(TemporaryRowHolder rs, String resultSetId);
-
-	/**
-	 * get the reference to parent table ResultSets, that will be needed by the 
-	 * referential action dependent table scans.
-	 */
-	public Vector getParentResultSet(String resultSetId);
-	
-	//clear the parent resultset hash table;
-	public void clearParentResultSets();
-
-	public Hashtable getParentResultSets();
-
-	/**
-	 * beetle 3865: updateable cursor using index.  A way of communication
-	 * between cursor activation and update activation.
-	 */
-	public void setForUpdateIndexScan(CursorResultSet forUpdateResultSet);
-
-	public CursorResultSet getForUpdateIndexScan();
-
-	/**
-		Return the set of dynamical created result sets, for procedures.
-		Base implementation returns null, a generated class for a procedure overwrites
-		this with a real implementation.
-		@return null if no dynamic results exists. Otherwise an array of ResultSet
-		arrays, each of length one containing null or a reference to a ResultSet.
-	*/
-	public java.sql.ResultSet[][] getDynamicResults();
-
-	/**
-		Return the maximum number of dynamical created result sets from the procedure definition.
-		Base implementation returns 0, a generated class for a procedure overwrites
-		this with a real implementation.
-	*/
-	public int getMaxDynamicResults();
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.sql
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.sql;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
+
+import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
+
+import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
+import org.apache.derby.iapi.sql.execute.ExecRow;
+import org.apache.derby.iapi.sql.execute.ExecutionFactory;
+import org.apache.derby.iapi.sql.execute.NoPutResultSet;
+import org.apache.derby.iapi.sql.execute.ConstantAction;
+import org.apache.derby.iapi.sql.execute.CursorResultSet;
+import org.apache.derby.iapi.sql.execute.TemporaryRowHolder;
+
+import org.apache.derby.iapi.store.access.ConglomerateController;
+import org.apache.derby.iapi.store.access.ScanController;
+import org.apache.derby.iapi.store.access.TransactionController;
+
+import org.apache.derby.iapi.types.DataValueFactory;
+
+import org.apache.derby.iapi.types.RowLocation;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+
+import java.sql.SQLWarning;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.Hashtable;
+
+
+/**
+ * An activation contains all the local state information necessary
+ * to execute a re-entrant PreparedStatement. The way it will actually work
+ * is that a PreparedStatement will have an executable plan, which will be
+ * a generated class. All of the local state will be variables in the class.
+ * Creating a new instance of the executable plan will create the local state
+ * variables. This means that an executable plan must implement this interface,
+ * and that the PreparedStatement.getActivation() method will do a
+ * "new" operation on the executable plan.
+ * <p>
+ * The fixed implementations of Activation in the Execution impl
+ * package are used as skeletons for the classes generated for statements
+ * when they are compiled.
+ * <p>
+ * There are no fixed implementations of Activation for statements;
+ * a statement has an activation generated for it when it is compiled.
+ *
+ * @author Jeff Lichtman
+ */
+
+public interface Activation
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	/**
+	 * Resets the activation to the "pre-execution" state -
+	 * that is, the state where it can be used to begin a new execution.
+	 * Frees local buffers, stops scans, resets counters to zero, sets
+	 * current date and time to an unitialized state, etc.
+	 *
+	 * @return	Nothing
+	 * @exception StandardException thrown on failure
+	 */
+	void	reset() throws StandardException;
+
+	/**
+	 * JDBC requires that all select statements be converted into cursors,
+	 * and that the cursor name be settable for each execution of a select
+	 * statement. The Language Module will support this, so that the JDBC
+	 * driver will not have to parse JSQL text. This method will have no
+	 * effect when called on non-select statements.
+	 * <p>
+	 * There will be a JSQL statement to disable the "cursorization" of
+	 * all select statements. For non-cursorized select statements, this
+	 * method will have no effect.
+	 * <p>
+	 * This has no effect if the activation has been closed.
+	 * <p>
+	 * @param cursorName  The cursor name to use.
+	 */
+	void	setCursorName(String cursorName);
+
+	/**
+	 * Temporary tables can be declared with ON COMMIT DELETE ROWS. But if the table has a held curosr open at
+	 * commit time, data should not be deleted from the table. This method, (gets called at commit time) checks if this
+	 * activation held cursor and if so, does that cursor reference the passed temp table name.
+	 *
+	 * @return	true if this activation has held cursor and if it references the passed temp table name
+	 */
+	public boolean checkIfThisActivationHasHoldCursor(String tableName);
+
+	/**
+	 * Gets the ParameterValueSet for this execution of the statement.
+	 *
+	 * @return	The ParameterValueSet for this execution of the
+	 *		statement. Returns NULL if there are no parameters.
+	 */
+	ParameterValueSet	getParameterValueSet();
+
+	/**
+	 * Sets the parameter values for this execution of the statement.
+	 * <p>
+	 * Has no effect if the activation has been closed.
+	 *
+	 * <p>
+	 * NOTE: The setParameters() method is currently unimplemented. 
+	 * A statement with parameters will generate its own ParameterValueSet,
+	 * which can be gotten with the getParameterValueSet() method (above).
+	 * The idea behind setParameters() is to improve performance when
+	 * operating across a network by allowing all the parameters to be set
+	 * in one call, as opposed to one call per parameter.
+	 *
+	 * @param parameterValues	The values of the parameters.
+	 *
+	 * @return	Nothing
+	 */
+	void	setParameters(ParameterValueSet parameterValues, DataTypeDescriptor[] parameterTypes) throws StandardException;
+
+	/**
+	 * When the prepared statement is executed, it passes
+	 * execution on to the activation execution was requested for.
+	 *
+	 * @return the ResultSet for further manipulation, if any.
+	 *
+	 * @exception StandardException		Thrown on failure
+	 */
+	ResultSet execute() throws StandardException;
+
+	/**
+		Closing an activation statement marks it as unusable. Any other
+		requests made on it will fail.  An activation should be
+		marked closed when it is expected to not be used any longer,
+		i.e. when the connection for it is closed, or it has suffered some
+		sort of severe error. This will also close its result set and
+		release any resources it holds e.g. for parameters.
+		<P>
+		Any class that implements this must be prepared to be executed
+		from garbage collection, ie. there is no matching context stack.
+
+		@exception StandardException		Thrown on failure
+	 */
+	void close() throws StandardException;
+
+	/**
+		Find out if the activation is closed or not.
+
+		@return true if the Activation has been closed.
+	 */
+	boolean isClosed();
+
+	/**
+		Set this Activation for a single execution.
+		E.g. a java.sql.Statement execution.
+	*/
+	void setSingleExecution();
+
+	/**
+		Returns true if this Activation is only going to be used for
+		one execution.
+	*/
+	boolean isSingleExecution();
+
+	/**
+	  Returns the chained list of warnings. Returns null
+	  if there are no warnings.
+	  */
+	SQLWarning getWarnings();
+
+	/**
+	  Add a warning to the activation
+	  */
+	void addWarning(SQLWarning w);
+
+	/**
+	  Clear the activation's warnings.
+	  */
+	void clearWarnings();
+
+	/**
+	 * Get the language connection context associated with this activation
+     */
+	public	LanguageConnectionContext	getLanguageConnectionContext();
+
+	/**
+	 * Get the Execution TransactionController associated with this 
+	 * activation/lcc.
+	 */
+	TransactionController getTransactionController();
+
+	/**
+	 * Returns the current result set for this activation, i.e.
+	 * the one returned by the last execute() call.  If there has
+	 * been no execute call or the activation has been reset or closed,
+	 * a null is returned.
+	 *
+	 * @return the current ResultSet of this activation.
+	 */
+	ResultSet getResultSet();
+
+	/**
+	 * Sets the ResultSet to be returned by getResultSet() to null.
+	 */
+	void clearResultSet();
+
+	/**
+	 * Generated plans have a current row field for ease in defining
+	 * the methods and finding them dynamically. The interface is
+	 * used to set the row before a dynamic method that uses it is
+	 * invoked.
+	 * <p>
+	 * When all processing on the currentRow has been completed,
+	 * callers should call activation.clearCurrentRow(resultSetNumber)
+	 * to ensure that no unnecessary references are retained to rows.
+	 * This will allow the rows no longer in use to be collected by
+	 * the garbage collecter.
+	 *
+	 * @param currentRow		The row to be operated upon.
+	 * @param resultSetNumber	The resultSetNumber for the current ResultSet
+	 *
+	 * @return Nothing
+	 *
+	 */
+	void setCurrentRow(ExecRow currentRow, int resultSetNumber);
+
+	/**
+	 * Generated plans have a current row field for ease in defining
+	 * the methods and finding them dynamically. The interface is
+	 * used to set the row before a dynamic method that uses it is
+	 * invoked.
+	 * <p>
+	 * When all processing on the currentRow has been completed,
+	 * callers should call activation.clearCurrentRow(resultSetNumber)
+	 * to ensure that no unnecessary references are retained to rows.
+	 * This will allow the rows no longer in use to be collected by
+	 * the garbage collecter.
+	 *
+	 * @param resultSetNumber	The resultSetNumber for the current ResultSet
+	 *
+	 * @return Nothing
+	 */
+	/* RESOLVE - this method belongs on an internal, not external, interface */
+	void clearCurrentRow(int resultSetNumber);
+
+	/**
+	 * Get the prepared statement that this activation is for.
+	 *
+	 * @return the prepared statement this activation is for.
+	 *
+	 */
+	ExecPreparedStatement getPreparedStatement();
+
+	/**
+		Check the validity of the current executing statement. Needs to be
+		called after a statement has obtained the relevant table locks on
+		the 
+	*/
+	public void checkStatementValidity() throws StandardException;
+
+	/**
+	 * Get the result description for this activation, if it has one.
+	 *
+	 * @return result description for this activation, if it has one;
+	 * otherwise, null.
+	 */
+	ResultDescription getResultDescription();
+
+	/**
+	 * Get the DataValueFactory
+	 *
+	 * @return DataValueFactory
+	 */
+	DataValueFactory getDataValueFactory();
+
+	/**
+	 * Get the ExecutionFactory
+	 *
+	 * @return ExecutionFactory
+	 */
+	ExecutionFactory getExecutionFactory();
+
+	/**
+		Get the saved RowLocation.
+
+		@param itemNumber	The saved item number.
+
+		@return	A RowLocation template for the conglomerate
+	 */
+	public RowLocation getRowLocationTemplate(int itemNumber);
+
+	/**
+		Get the number of subqueries in the entire query.
+		@return int	 The number of subqueries in the entire query.
+	 */
+	public int getNumSubqueries();
+
+	/**
+	 * Return the cursor name of this activation. This will differ
+	 * from its ResultSet's cursor name if it has been
+	 * altered with setCursorName. Thus this always returns the cursor
+	 * name of the next execution of this activation. The cursor name
+	 * of the current execution must be obtained from the ResultSet.
+	 * or this.getResultSet.getCursorName() [with null checking].
+	 * <p>
+	 * Statements that do not support cursors will return a null.
+	 * <p>
+	 * @return The cursor name.
+	 */
+	public String	getCursorName();
+
+	/**
+	 * Return the holdability of this activation.
+	 * <p>
+	 * @return The holdability of this activation.
+	 */
+	public boolean	getResultSetHoldability();
+
+	/**
+	 * Set current resultset holdability.
+	 *
+	 * @param resultSetHoldability	The new resultset holdability.
+	 *
+	 * @return Nothing.
+	 */
+	public void setResultSetHoldability(boolean resultSetHoldability);
+
+	/**
+	 * Set the auto-generated keys resultset mode to true for this activation.
+	 *
+	 * The specific columns for auto-generated keys resultset can be requested by
+	 * passing column positions array
+	 *
+	 * The specific columns for auto-generated keys resultset can be requested by
+	 * passing column names array
+	 *
+	 * Both the parameters would be null if user didn't request specific keys.
+	 * Otherwise, the user could request specific columns by passing column positions
+	 * or names array but not both.
+	 *
+	 * @param columnIndexes Request specific columns in auto-generated keys
+	 * resultset by passing column positions. null means no specific columns
+	 * requested by position
+	 *
+	 * @param columnNames Request specific columns in auto-generated keys
+	 * resultset by passing column names.  null means no specific columns
+	 * requested by position
+	 *
+	 * @return Nothing.
+	 */
+	public void setAutoGeneratedKeysResultsetInfo(int[] columnIndexes, String[] columnNames);
+
+	/**
+	 * Returns true if auto-generated keys resultset request was made for this
+	 * avtivation.
+	 * <p>
+	 * @return auto-generated keys resultset mode for this activation.
+	 */
+	public boolean	getAutoGeneratedKeysResultsetMode();
+
+	/**
+	 * Returns the column positions array of columns requested in auto-generated
+	 * keys resultset for this avtivation. Returns null if no specific column
+	 * requested by positions
+	 * <p>
+	 * @return column positions array of columns requested.
+	 */
+	public int[] getAutoGeneratedKeysColumnIndexes();
+
+	/**
+	 * Returns the column names array of columns requested in auto-generated
+	 * keys resultset for this avtivation. Returns null if no specific column
+	 * requested by names
+	 * <p>
+	 * @return column names array of columns requested.
+	 */
+	public String[] getAutoGeneratedKeysColumnNames();
+
+	/**
+	 * Mark the activation as unused.  
+	 */
+	public void markUnused();
+
+	/**
+	 * Is the activation in use?
+	 *
+	 * @return true/false
+	 */
+	public boolean isInUse();
+
+	/**
+	 * Tell this activation that the given ResultSet was found to have
+	 * the given number of rows.  This is used during execution to determine
+	 * whether a table has grown or shrunk.  If a table's size changes
+	 * significantly, the activation may invalidate its PreparedStatement
+	 * to force recompilation.
+	 *
+	 * Note that the association of row counts with ResultSets is kept
+	 * in the activation class, not in the activation itself.  This
+	 * means that this method must be synchronized.
+	 *
+	 * This method is not required to check the number of rows on each
+	 * call.  Because of synchronization, this check is likely to be
+	 * expensive, so it may only check every hundred calls or so.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public void informOfRowCount(NoPutResultSet resultSet, long rowCount)
+					throws StandardException;
+
+	/**
+	 * Get the ConglomerateController, if any, that has already
+	 * been opened for the heap when scaning for an update or delete.
+	 * (Saves opening the ConglomerateController twice.)
+	 *
+	 * @return The ConglomerateController, if available, to use for the update.
+	 */
+	public ConglomerateController getHeapConglomerateController();
+
+	/**
+	 * Set the ConglomerateController to be used for an update or delete.
+	 * (Saves opening the ConglomerateController twice.)
+	 *
+	 * @param updateHeapCC	The ConglomerateController to reuse for the update or delete.
+	 *
+	 * @return Nothing.
+	 */
+	public void setHeapConglomerateController(ConglomerateController updateHeapCC);
+
+	/**
+	 * Clear the ConglomerateController to be used for an update or delete.
+	 * (Saves opening the ConglomerateController twice.)
+	 *
+	 * @return Nothing.
+	 */
+	public void clearHeapConglomerateController();
+
+	/**
+	 * Get the ScanController, if any, that has already
+	 * been opened for the index when scaning for an update or delete.
+	 * (Saves opening the ScanController twice.)
+	 *
+	 * @return The ScanController, if available, to use for the update.
+	 */
+	public ScanController getIndexScanController();
+
+	/**
+	 * Set the ScanController to be used for an update or delete,
+	 * when scanning an index that will also be updated
+	 * (Saves opening the ScanController twice.)
+	 *
+	 * @param indexSC	The ScanController to reuse for the update or delete.
+	 *
+	 * @return Nothing.
+	 */
+	public void setIndexScanController(ScanController indexSC);
+
+	/**
+	 * Get the conglomerate number of the index, if any, that has already
+	 * been opened for scaning for an update or delete.
+	 * (Saves opening the ScanController twice.)
+	 *
+	 * @return The conglomerate number, if available, to use for the update.
+	 */
+	public long getIndexConglomerateNumber();
+
+	/**
+	 * Set the conglomerate number of the index to be used for an update or delete,
+	 * when scanning an index that will also be updated
+	 * (Saves opening the ScanController twice.)
+	 *
+	 * @param indexConglomerateNumber The conglomerate number of the index to reuse for the update or delete.
+	 *
+	 * @return Nothing.
+	 */
+	public void setIndexConglomerateNumber(long indexConglomerateNumber);
+
+	/**
+	 * Clear the info for the index to be re-used for update/delete.
+	 * (ScanController and conglomerate number.)
+	 *
+	 * @return Nothing.
+	 */
+	public void clearIndexScanInfo();
+
+	/**
+	 * Mark the Activation as being for create table.
+	 * (NOTE: We can do certain optimizations for
+	 * create table that we can't do for other DDL.)
+	 *
+	 * @return Nothing.
+	 */
+	public void setForCreateTable();
+
+	/**
+	 * Get whether or not this activation is for
+	 * create table.
+	 * (NOTE: We can do certain optimizations for
+	 * create table that we can't do for other DDL.)
+	 *
+	 * @return Whether or not this activation is for
+	 *		   create table.
+	 */
+	public boolean getForCreateTable();
+
+	/**
+	 * Save the TableDescriptor for the target of 
+	 * DDL so that it can be passed between the
+	 * various ConstantActions during execution.
+	 *
+	 * @return Nothing.
+	 */
+	public void setDDLTableDescriptor(TableDescriptor td);
+
+	/**
+	 * Get the TableDescriptor for the target of
+	 * DDL.
+	 *
+	 * @return The TableDescriptor for the target of
+	 * DDL.
+	 */
+	public TableDescriptor getDDLTableDescriptor();
+
+	/**
+	 * Set the maximum # of rows.  (# of rows that can
+	 * be returned by a ResultSet.  0 means no limit.)
+	 *
+	 * @param maxRows Maximum # of rows. (0 means no limit.)
+	 *
+	 * @return Nothing.
+	 */
+	public void setMaxRows(int maxRows);
+
+	/**
+	 * Get the maximum # of rows.  (# of rows that can
+	 * be returned by a ResultSet.  0 means no limit.)
+	 *
+	 * @return Maximum # of rows.  (0 means no limit.)
+	 */
+	public int getMaxRows();
+
+	/**
+	 * Is this Activation for a cursor?
+	 *
+	 * @return Whether or not this Activation is for a cursor.
+	 */
+	public boolean isCursorActivation();
+
+	/**
+	 * Save the ResultSet for the target
+	 * of an update/delete to a VTI.
+	 *
+	 * @return Nothing.
+	 */
+	public void setTargetVTI(java.sql.ResultSet targetVTI);
+
+	/**
+	 * Get the ResultSet for the target
+	 * of an update/delete to a VTI.
+	 *
+	 * @return The ResultSet for the target
+	 * of an update/delete to a VTI.
+	 */
+	public java.sql.ResultSet getTargetVTI();
+
+	public ConstantAction	getConstantAction();
+
+	//store a reference to the parent table result sets
+	public void setParentResultSet(TemporaryRowHolder rs, String resultSetId);
+
+	/**
+	 * get the reference to parent table ResultSets, that will be needed by the 
+	 * referential action dependent table scans.
+	 */
+	public Vector getParentResultSet(String resultSetId);
+	
+	//clear the parent resultset hash table;
+	public void clearParentResultSets();
+
+	public Hashtable getParentResultSets();
+
+	/**
+	 * beetle 3865: updateable cursor using index.  A way of communication
+	 * between cursor activation and update activation.
+	 */
+	public void setForUpdateIndexScan(CursorResultSet forUpdateResultSet);
+
+	public CursorResultSet getForUpdateIndexScan();
+
+	/**
+		Return the set of dynamical created result sets, for procedures.
+		Base implementation returns null, a generated class for a procedure overwrites
+		this with a real implementation.
+		@return null if no dynamic results exists. Otherwise an array of ResultSet
+		arrays, each of length one containing null or a reference to a ResultSet.
+	*/
+	public java.sql.ResultSet[][] getDynamicResults();
+
+	/**
+		Return the maximum number of dynamical created result sets from the procedure definition.
+		Base implementation returns 0, a generated class for a procedure overwrites
+		this with a real implementation.
+	*/
+	public int getMaxDynamicResults();
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/LanguageFactory.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/LanguageFactory.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/LanguageFactory.java	Fri Sep 24 10:33:20 2004
@@ -1,80 +1,80 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.sql
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.sql;
-
-import org.apache.derby.iapi.error.StandardException;
-import org.apache.derby.iapi.services.loader.ClassInspector;
-
-/**
- * Factory interface for the Language.Interface protocol.
- * This is used via the Database API by users, and is presented
- * as a System Module (not a service module).  That could change,
- * but for now this is valid for any database. 
- *
- * @author Jeff Lichtman
- */
-public interface LanguageFactory
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	/**
-		Used to locate this factory by the Monitor basic service.
-		There needs to be a language factory per database.
-	 */
-	String MODULE = "org.apache.derby.iapi.sql.LanguageFactory";
-
-	/**
-	 * Get a ParameterValueSet
-	 *
-	 * @param numParms	The number of parameters in the
-	 *			ParameterValueSet
-	 * @param hasReturnParam	true if this parameter set
-	 *			has a return parameter.  The return parameter
-	 *			is always the 1st parameter in the list.  It
-	 *			is due to a callableStatement like this: <i>
-	 *			? = CALL myMethod()</i>
-	 *
-	 * @return	A new ParameterValueSet with the given number of parms
-	 */
-	ParameterValueSet newParameterValueSet(ClassInspector ci, int numParms, boolean hasReturnParam);
-
-	/**
-	 * Get a new result description from the input result
-	 * description.  Picks only the columns in the column
-	 * array from the inputResultDescription.
-	 *
- 	 * @param inputResultDescription the input rd
-	 * @param theCols non null array of ints
-	 *
-	 * @return ResultDescription the rd
-	 */
-	public ResultDescription getResultDescription
-	(
-		ResultDescription	inputResultDescription,
-		int[]				theCols
-	);
-
-	/**
-	 * Get a new result description
-	 *
- 	 * @param cols an array of col descriptors
-	 * @param type the statement type
-	 *
-	 * @return ResultDescription the rd
-	 */
-	public ResultDescription getResultDescription
-	(
-		ResultColumnDescriptor[]	cols,
-		String						type
-	);
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.sql
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.sql;
+
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.services.loader.ClassInspector;
+
+/**
+ * Factory interface for the Language.Interface protocol.
+ * This is used via the Database API by users, and is presented
+ * as a System Module (not a service module).  That could change,
+ * but for now this is valid for any database. 
+ *
+ * @author Jeff Lichtman
+ */
+public interface LanguageFactory
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	/**
+		Used to locate this factory by the Monitor basic service.
+		There needs to be a language factory per database.
+	 */
+	String MODULE = "org.apache.derby.iapi.sql.LanguageFactory";
+
+	/**
+	 * Get a ParameterValueSet
+	 *
+	 * @param numParms	The number of parameters in the
+	 *			ParameterValueSet
+	 * @param hasReturnParam	true if this parameter set
+	 *			has a return parameter.  The return parameter
+	 *			is always the 1st parameter in the list.  It
+	 *			is due to a callableStatement like this: <i>
+	 *			? = CALL myMethod()</i>
+	 *
+	 * @return	A new ParameterValueSet with the given number of parms
+	 */
+	ParameterValueSet newParameterValueSet(ClassInspector ci, int numParms, boolean hasReturnParam);
+
+	/**
+	 * Get a new result description from the input result
+	 * description.  Picks only the columns in the column
+	 * array from the inputResultDescription.
+	 *
+ 	 * @param inputResultDescription the input rd
+	 * @param theCols non null array of ints
+	 *
+	 * @return ResultDescription the rd
+	 */
+	public ResultDescription getResultDescription
+	(
+		ResultDescription	inputResultDescription,
+		int[]				theCols
+	);
+
+	/**
+	 * Get a new result description
+	 *
+ 	 * @param cols an array of col descriptors
+	 * @param type the statement type
+	 *
+	 * @return ResultDescription the rd
+	 */
+	public ResultDescription getResultDescription
+	(
+		ResultColumnDescriptor[]	cols,
+		String						type
+	);
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/LanguageProperties.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/LanguageProperties.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/LanguageProperties.java	Fri Sep 24 10:33:20 2004
@@ -1,42 +1,42 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.sql
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.sql;
-
-/**
- * This is a holder of language properties that are
- * exposed users.  Consolodate all properties here.
- */
-public interface LanguageProperties
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-	/*
-	** BulkFetch
-	**
-	** The default size needs some explaining.  As
-	** of 7/14/98, the most efficient way for access
-	** to return rows from a table is basically by
-	** reading/qualifying/returning all the rows in
-	** one page.  If you are read in many many rows
-	** at a time the performance gain is only marginally
-	** better.  Anyway, since even a small number of
-	** rows per read helps, and since there is no good
-	** way to get access to retrieve the rows page
-	** by page, we use 16 totally arbitrarily.  Ultimately,
-	** this should be dynamically sized -- in which
-	** case we wouldn't need this default.
-	*/
-    static final String BULK_FETCH_PROP = "derby.language.bulkFetchDefault";
-    static final String BULK_FETCH_DEFAULT = "16";
-    static final int BULK_FETCH_DEFAULT_INT = 16;
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.sql
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.sql;
+
+/**
+ * This is a holder of language properties that are
+ * exposed users.  Consolodate all properties here.
+ */
+public interface LanguageProperties
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+	/*
+	** BulkFetch
+	**
+	** The default size needs some explaining.  As
+	** of 7/14/98, the most efficient way for access
+	** to return rows from a table is basically by
+	** reading/qualifying/returning all the rows in
+	** one page.  If you are read in many many rows
+	** at a time the performance gain is only marginally
+	** better.  Anyway, since even a small number of
+	** rows per read helps, and since there is no good
+	** way to get access to retrieve the rows page
+	** by page, we use 16 totally arbitrarily.  Ultimately,
+	** this should be dynamically sized -- in which
+	** case we wouldn't need this default.
+	*/
+    static final String BULK_FETCH_PROP = "derby.language.bulkFetchDefault";
+    static final String BULK_FETCH_DEFAULT = "16";
+    static final int BULK_FETCH_DEFAULT_INT = 16;
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ParameterValueSet.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ParameterValueSet.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ParameterValueSet.java	Fri Sep 24 10:33:20 2004
@@ -1,270 +1,270 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.sql
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.sql;
-
-import java.sql.Date;
-import java.sql.Time;
-import java.sql.Timestamp;
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.types.DataValueDescriptor;
-
-/**
- * A ParameterValueSet is a set of parameter values that can be assembled by a
- * JDBC driver and passed to a PreparedStatement all at once. The fact that
- * they are all passed at once can reduce the communication overhead between
- * client and server.
- *
- * @author Jeff Lichtman
- */
-public interface ParameterValueSet
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-
-
-	/**
-		Set the mode of the parameter, called when setting up static method calls and stored procedures.
-		Otherwise the parameter type will default to an IN parameter.
-	*/
-    void setParameterMode(int position, int mode);
-
-	/**
-	 * Set a parameter position to a DataValueDescriptor.
-	 *
-	 * NOTE: This method assumes the caller will not pass a position that's
-	 * out of range.  The implementation may have an assertion that the position
-	 * is in range.
-	 *
-	 * @param sdv		The DataValueDescriptor to set
-	 * @param position	The parameter position to set it at
-	 * @param jdbcTypeId    The corresponding JDBC types from java.sql.Types
-	 * @param className  The declared class name for the type.
-	 */
-
-	void setStorableDataValue(DataValueDescriptor sdv, int position, int jdbcTypeId, String className);
-
-
-	//////////////////////////////////////////////////////////////////
-	//
-	// CALLABLE STATEMENT
-	//
-	//////////////////////////////////////////////////////////////////
-
-	/**
-	 * Mark the parameter as an output parameter.
-	 *
-	 * @param parameterIndex	The ordinal position of a parameter to set
-	 *			to the given value.
-	 * @param sqlType	A type from java.sql.Types
-	 * @param scale		the scale to use.  -1 means ignore scale
-	 *
-	 * @exception StandardException on error
-	 */
-	void registerOutParameter(int parameterIndex, int sqlType, int scale)
-		throws StandardException;
-
-
-    /**
-     * Get the value of a parameter as a Java object.
-     *
-     * <p>This method returns a Java object whose type coresponds to the SQL
-     * type that was registered for this parameter using registerOutParameter.
-     *
-     * <p>Note that this method may be used to read
-     * datatabase-specific, abstract data types. This is done by
-     * specifying a targetSqlType of java.sql.types.OTHER, which
-     * allows the driver to return a database-specific Java type.
-     *
-     * @param parameterIndex The first parameter is 1, the second is 2, ...
-     * @return A java.lang.Object holding the OUT parameter value.
-     * @exception StandardException if a database-access error occurs.
-     * @see java.sql.Types 
-     */
-    Object getObject(int parameterIndex) throws StandardException;
-
-	//////////////////////////////////////////////////////////////////
-	//
-	// MISC STATEMENT
-	//
-	//////////////////////////////////////////////////////////////////
-
-	/**
-	 * Sets all parameters to an uninitialized state. An exception will be
-	 * thrown if the caller tries to execute a PreparedStatement when one
-	 * or more parameters is uninitialized (i.e. has not had
-	 * setParameterValue() called on it.
-	 *
-	 * @return	Nothing
-	 */
-	void	clearParameters();
-
-	/**
-	 * Returns the number of parameters in this set.
-	 *
-	 * @return	The number of parameters in this set.
-	 */
-	public	int	getParameterCount();
-
-	/**
-	 * Returns the parameter at the given position.
-	 *
-	 * @return	The parameter at the given position.
-	 * @exception StandardException		Thrown on error
-	 */
-	public DataValueDescriptor getParameter( int position ) throws StandardException;
-
-
-	/**
-	 * Returns the parameter at the given position in order to set it.
-	   Setting via an unknown object type must use setParameterAsObject()
-	   to ensure correct typing.
-
-	 *
-	 * @return	The parameter at the given position.
-	 * @exception StandardException		Thrown on error
-	 */
-	public DataValueDescriptor getParameterForSet( int position ) throws StandardException;
-
-	/**
-		Set the value of this parameter to the passed in Object.
-		
-		  @return	The parameter at the given position.
-		  @exception StandardException		Thrown on error
-	*/
-	void setParameterAsObject(int parameterIndex, Object value) throws StandardException;
-	
-	
-	public DataValueDescriptor getParameterForGet( int position ) throws StandardException;
-
-	/**
-	 * Tells whether all the parameters are set and ready for execution.
-	   OUT and Cloudscape static method INOUT parameters are not required to be set.
-	 *
-	 * @return	true if all parameters are set, false if at least one
-	 *			parameter is not set.
-	 */
-	boolean	allAreSet();
-
-	/**
-	 * Clone the ParameterValueSet and its contents.
-	 *
-	 * @return ParameterValueSet	A clone of the ParameterValueSet and its contents.
-	 */
-	ParameterValueSet getClone();
-
-	/**
-	 * Validate the parameters.  This is done for situations where
-	 * we cannot validate everything in the setXXX() calls.  In
-	 * particular, before we do an execute() on a CallableStatement,
-	 * we need to go through the parameters and make sure that
-	 * all parameters are set up properly.  The motivator for this
-	 * is that setXXX() can be called either before or after 
-	 * registerOutputParamter(), we cannot be sure we have the types
-	 * correct until we get to execute().
-	 *
-	 * @exception StandardException if the parameters aren't valid
-	 */
-	void validate() throws StandardException;
-
-	/**
-	 * Is there a return output parameter in this pvs.  A return
-	 * parameter is from a CALL statement of the following
-	 * syntax: ? = CALL myMethod().  Note that a return
-	 * output parameter is NOT the same thing as an output
-	 * parameter; it is a special type of output parameter.
-	 *
-	 * @return true if it has a return parameter
-	 *
-	 */
-	public boolean hasReturnOutputParameter();
-
-	/**
-		Check that there are not output parameters defined
-		by the parameter set. If there are unknown parameter
-		types they are forced to input types. i.e. Cloudscape static method
-		calls with parameters that are array.
-
-		@return true if a declared Java Procedure INOUT or OUT parameter is in the set, false otherwise.
-	*/
-	public boolean checkNoDeclaredOutputParameters();
-
-
-	// bug 4552 - "exec statement using" will return no parameters through parametermetadata
-	/**
-	 * Is this pvs for using clause.
-	 *
-	 * @return true if it has a output parameter
-	 *
-	 */
-	public boolean isUsingParameterValueSet();
-
-	// bug 4552 - "exec statement using" will return no parameters through parametermetadata
-	/**
-	 * Setthis pvs for using clause.
-	 */
-	public void setUsingParameterValueSet();
-
-	/**
-	 * Set the parameter values of the pvstarget to equal those 
-	 * set in this PVS.
-	 * Used to transfer saved SPS parameters to the actual
-	 * prepared statement parameters  once associated parameters 
-	 * have been established.  Assumes pvstarget is the same 
-	 * length as this.
-	 * @param pvstarget ParameterValueSet which will recieve the values
-
-		@exception StandardException values not compatible
-	 **/
-	public void transferDataValues(ParameterValueSet pvstarget) throws StandardException;
-
-	/**
-		Return the mode of the parameter according to JDBC 3.0 ParameterMetaData
-		
-	 *
-	 * @param parameterIndex the first parameter is 1, the second is 2, ...
-	 *
-	 */
-	public short getParameterMode(int parameterIndex);
-
-
-    /**
-     * Set the value of the return parameter as a Java object.
-     *
-     * @param value the return value
-     *
-     * @exception StandardException if a database-access error occurs.
-     */
-	void setReturnValue(Object value) throws StandardException;
-
-	/**
-	 * Return the scale of the given parameter index in this pvs.
-	 *
-	 * @param parameterIndex the first parameter is 1, the second is 2, ...
-	 *
-	 * @return scale
-	 */
-	public int getScale(int parameterIndex);
-
-	/**
-	 * Return the precision of the given parameter index in this pvs.
-	 *
-	 * @param parameterIndex the first parameter is 1, the second is 2, ...
-	 *
-	 * @return precision
-	 */
-	public int getPrecision(int parameterIndex);
-
-
-}
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.sql
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.sql;
+
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.types.DataValueDescriptor;
+
+/**
+ * A ParameterValueSet is a set of parameter values that can be assembled by a
+ * JDBC driver and passed to a PreparedStatement all at once. The fact that
+ * they are all passed at once can reduce the communication overhead between
+ * client and server.
+ *
+ * @author Jeff Lichtman
+ */
+public interface ParameterValueSet
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+
+
+	/**
+		Set the mode of the parameter, called when setting up static method calls and stored procedures.
+		Otherwise the parameter type will default to an IN parameter.
+	*/
+    void setParameterMode(int position, int mode);
+
+	/**
+	 * Set a parameter position to a DataValueDescriptor.
+	 *
+	 * NOTE: This method assumes the caller will not pass a position that's
+	 * out of range.  The implementation may have an assertion that the position
+	 * is in range.
+	 *
+	 * @param sdv		The DataValueDescriptor to set
+	 * @param position	The parameter position to set it at
+	 * @param jdbcTypeId    The corresponding JDBC types from java.sql.Types
+	 * @param className  The declared class name for the type.
+	 */
+
+	void setStorableDataValue(DataValueDescriptor sdv, int position, int jdbcTypeId, String className);
+
+
+	//////////////////////////////////////////////////////////////////
+	//
+	// CALLABLE STATEMENT
+	//
+	//////////////////////////////////////////////////////////////////
+
+	/**
+	 * Mark the parameter as an output parameter.
+	 *
+	 * @param parameterIndex	The ordinal position of a parameter to set
+	 *			to the given value.
+	 * @param sqlType	A type from java.sql.Types
+	 * @param scale		the scale to use.  -1 means ignore scale
+	 *
+	 * @exception StandardException on error
+	 */
+	void registerOutParameter(int parameterIndex, int sqlType, int scale)
+		throws StandardException;
+
+
+    /**
+     * Get the value of a parameter as a Java object.
+     *
+     * <p>This method returns a Java object whose type coresponds to the SQL
+     * type that was registered for this parameter using registerOutParameter.
+     *
+     * <p>Note that this method may be used to read
+     * datatabase-specific, abstract data types. This is done by
+     * specifying a targetSqlType of java.sql.types.OTHER, which
+     * allows the driver to return a database-specific Java type.
+     *
+     * @param parameterIndex The first parameter is 1, the second is 2, ...
+     * @return A java.lang.Object holding the OUT parameter value.
+     * @exception StandardException if a database-access error occurs.
+     * @see java.sql.Types 
+     */
+    Object getObject(int parameterIndex) throws StandardException;
+
+	//////////////////////////////////////////////////////////////////
+	//
+	// MISC STATEMENT
+	//
+	//////////////////////////////////////////////////////////////////
+
+	/**
+	 * Sets all parameters to an uninitialized state. An exception will be
+	 * thrown if the caller tries to execute a PreparedStatement when one
+	 * or more parameters is uninitialized (i.e. has not had
+	 * setParameterValue() called on it.
+	 *
+	 * @return	Nothing
+	 */
+	void	clearParameters();
+
+	/**
+	 * Returns the number of parameters in this set.
+	 *
+	 * @return	The number of parameters in this set.
+	 */
+	public	int	getParameterCount();
+
+	/**
+	 * Returns the parameter at the given position.
+	 *
+	 * @return	The parameter at the given position.
+	 * @exception StandardException		Thrown on error
+	 */
+	public DataValueDescriptor getParameter( int position ) throws StandardException;
+
+
+	/**
+	 * Returns the parameter at the given position in order to set it.
+	   Setting via an unknown object type must use setParameterAsObject()
+	   to ensure correct typing.
+
+	 *
+	 * @return	The parameter at the given position.
+	 * @exception StandardException		Thrown on error
+	 */
+	public DataValueDescriptor getParameterForSet( int position ) throws StandardException;
+
+	/**
+		Set the value of this parameter to the passed in Object.
+		
+		  @return	The parameter at the given position.
+		  @exception StandardException		Thrown on error
+	*/
+	void setParameterAsObject(int parameterIndex, Object value) throws StandardException;
+	
+	
+	public DataValueDescriptor getParameterForGet( int position ) throws StandardException;
+
+	/**
+	 * Tells whether all the parameters are set and ready for execution.
+	   OUT and Cloudscape static method INOUT parameters are not required to be set.
+	 *
+	 * @return	true if all parameters are set, false if at least one
+	 *			parameter is not set.
+	 */
+	boolean	allAreSet();
+
+	/**
+	 * Clone the ParameterValueSet and its contents.
+	 *
+	 * @return ParameterValueSet	A clone of the ParameterValueSet and its contents.
+	 */
+	ParameterValueSet getClone();
+
+	/**
+	 * Validate the parameters.  This is done for situations where
+	 * we cannot validate everything in the setXXX() calls.  In
+	 * particular, before we do an execute() on a CallableStatement,
+	 * we need to go through the parameters and make sure that
+	 * all parameters are set up properly.  The motivator for this
+	 * is that setXXX() can be called either before or after 
+	 * registerOutputParamter(), we cannot be sure we have the types
+	 * correct until we get to execute().
+	 *
+	 * @exception StandardException if the parameters aren't valid
+	 */
+	void validate() throws StandardException;
+
+	/**
+	 * Is there a return output parameter in this pvs.  A return
+	 * parameter is from a CALL statement of the following
+	 * syntax: ? = CALL myMethod().  Note that a return
+	 * output parameter is NOT the same thing as an output
+	 * parameter; it is a special type of output parameter.
+	 *
+	 * @return true if it has a return parameter
+	 *
+	 */
+	public boolean hasReturnOutputParameter();
+
+	/**
+		Check that there are not output parameters defined
+		by the parameter set. If there are unknown parameter
+		types they are forced to input types. i.e. Cloudscape static method
+		calls with parameters that are array.
+
+		@return true if a declared Java Procedure INOUT or OUT parameter is in the set, false otherwise.
+	*/
+	public boolean checkNoDeclaredOutputParameters();
+
+
+	// bug 4552 - "exec statement using" will return no parameters through parametermetadata
+	/**
+	 * Is this pvs for using clause.
+	 *
+	 * @return true if it has a output parameter
+	 *
+	 */
+	public boolean isUsingParameterValueSet();
+
+	// bug 4552 - "exec statement using" will return no parameters through parametermetadata
+	/**
+	 * Setthis pvs for using clause.
+	 */
+	public void setUsingParameterValueSet();
+
+	/**
+	 * Set the parameter values of the pvstarget to equal those 
+	 * set in this PVS.
+	 * Used to transfer saved SPS parameters to the actual
+	 * prepared statement parameters  once associated parameters 
+	 * have been established.  Assumes pvstarget is the same 
+	 * length as this.
+	 * @param pvstarget ParameterValueSet which will recieve the values
+
+		@exception StandardException values not compatible
+	 **/
+	public void transferDataValues(ParameterValueSet pvstarget) throws StandardException;
+
+	/**
+		Return the mode of the parameter according to JDBC 3.0 ParameterMetaData
+		
+	 *
+	 * @param parameterIndex the first parameter is 1, the second is 2, ...
+	 *
+	 */
+	public short getParameterMode(int parameterIndex);
+
+
+    /**
+     * Set the value of the return parameter as a Java object.
+     *
+     * @param value the return value
+     *
+     * @exception StandardException if a database-access error occurs.
+     */
+	void setReturnValue(Object value) throws StandardException;
+
+	/**
+	 * Return the scale of the given parameter index in this pvs.
+	 *
+	 * @param parameterIndex the first parameter is 1, the second is 2, ...
+	 *
+	 * @return scale
+	 */
+	public int getScale(int parameterIndex);
+
+	/**
+	 * Return the precision of the given parameter index in this pvs.
+	 *
+	 * @param parameterIndex the first parameter is 1, the second is 2, ...
+	 *
+	 * @return precision
+	 */
+	public int getPrecision(int parameterIndex);
+
+
+}
+

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/PreparedStatement.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/PreparedStatement.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/PreparedStatement.java	Fri Sep 24 10:33:20 2004
@@ -1,230 +1,230 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.sql
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.sql;
-
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
-
-import org.apache.derby.iapi.sql.depend.Dependent;
-import org.apache.derby.iapi.sql.depend.Provider;
-
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-import java.sql.Timestamp;
-import java.sql.SQLWarning;
-
-/**
- * The PreparedStatement interface provides methods to execute prepared
- * statements, store them, and get metadata about them.
- *
- *	@author Jeff Lichtman
- */
-public interface PreparedStatement
-	extends Dependent, Provider
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-
-	/**
-	 * Checks whether this PreparedStatement is up to date.
-	 * A PreparedStatement can become out of date if any of several
-	 * things happen:
-	 *
-	 *	A schema used by the statement is dropped
-	 *	A table used by the statement is dropped
-	 *	A table used by the statement, or a column in such a table,
-	 *		is altered in one of several ways: a column is dropped,
-	 *		a privilege is dropped, a constraint is added or
-	 *		dropped, an index is dropped.
-	 *	A view used by the statement is dropped.
-	 *
-	 * In general, anything that happened since the plan was generated
-	 * that might cause the plan to fail, or to generate incorrect results,
-	 * will cause this method to return FALSE.
-	 *
-	 * @return	TRUE if the PreparedStatement is up to date,
-	 *		FALSE if it is not up to date
-	 */
-	boolean	upToDate() throws StandardException;
-
-	/**
-	 * Re-prepare the statement if it is not up to date or,
-	 * if requested, simply not optimal.
-	 * If there are open cursors using this prepared statement,
-	 * then we will not be able to recompile the statement.
-	 *
-	 * @param lcc			The LanguageConnectionContext.
-	 *
-	 * @exception StandardException thrown if unable to perform
-	 */
-	void rePrepare(LanguageConnectionContext lcc) 
-		throws StandardException;
-
-	/**
-	 * PreparedStatements are re-entrant - that is, more than one
-	 * execution can be active at a time for a single prepared statement.
-	 * An Activation contains all the local state information to
-	 * execute a prepared statement (as opposed to the constant
-	 * information, such as literal values and code). Each Activation
-	 * class contains the code specific to the prepared statement
-	 * represented by an instance of this class (PreparedStatement).
-	 *
-	 * @param lcc			The LanguageConnectionContext.
-	 * @return	The new activation.
-	 *
-	 * @exception StandardException		Thrown on failure
-	 */
-	Activation	getActivation(LanguageConnectionContext lcc, boolean scrollable) throws StandardException;
-
-	/**
-	 * Execute the PreparedStatement and return results.
-	 *<p>
-	 * There is no executeQuery() or
-	 * executeUpdate(); a method is provided in
-	 * ResultSet to tell whether to expect rows to be returned.
-	 *
-	 * @param activation The activation containing all the local state
-	 *		to execute the plan.
-	 * @param executeQuery		Whether or not called from a Statement.executeQuery()
-	 * @param executeUpdate	Whether or not called from a Statement.executeUpdate()
- 	 * @param rollbackParentContext True if 1) the statement context is
-	 *  NOT a top-level context, AND 2) in the event of a statement-level
-	 *	 exception, the parent context needs to be rolled back, too.
-	 *
-	 * @return	A ResultSet for a statement. A ResultSet represents
-	 *		the results returned from the statement, if any.
-	 *		Will return NULL if the plan for the PreparedStatement
-	 *		has aged out of cache, or the plan is out of date.
-	 *
-	 * @exception StandardException		Thrown on failure
-	 */
-	ResultSet	execute(Activation activation, boolean executeQuery, boolean executeUpdate,
-		boolean rollbackParentContext) throws StandardException;
-
-	/**
-		Simple form of execute(). Creates a new single use activation and executes it,
-		but also passes rollbackParentContext parameter (see above).
-	*/
-	ResultSet	execute(LanguageConnectionContext lcc, boolean rollbackParentContext)
-		throws StandardException;
-
-	/**
-	 * Get the ResultDescription for the statement.  The ResultDescription
-	 * describes what the results look like: what are the rows and columns?
-	 * <p>
-	 * This is available here and on the ResultSet so that users can
-	 * see the shape of the result before they execute.
-	 *
-	 * @return	A ResultDescription describing the results.
-	 *
-	 */
-	ResultDescription	getResultDescription();
-
-	/**
-	 * Return true if the query node for this statement references SESSION schema tables.
-	 *
-	 * @return	true if references SESSION schema tables, else false
-	 */
-	boolean referencesSessionSchema();
-
-	/**
-	 * Get an array of DataTypeDescriptors describing the types of the
-	 * parameters of this PreparedStatement. The Nth element of the array
-	 * describes the Nth parameter.
-	 *
-	 * @return		An array of DataTypeDescriptors telling the
-	 *			type, length, precision, scale, etc. of each
-	 *			parameter of this PreparedStatement.
-	 */
-	DataTypeDescriptor[]	getParameterTypes();
-
-	/**
-	 *	Return the SQL string that this statement is for.
-	 *
-	 *	@return the SQL string this statement is for.
-	 */
-	String getSource();
-
-	/**
-	 *	Return the SPS Name for this statement.
-	 *
-	 *	@return the SPS Name for this statement
-	 */
-	String getSPSName();
-
-	/**
-	 * Get the total compile time for the associated query in milliseconds.
-	 * Compile time can be divided into parse, bind, optimize and generate times.
-	 * 
-	 * @return long		The total compile time for the associated query in milliseconds.
-	 */
-	public long getCompileTimeInMillis();
-
-	/**
-	 * Get the parse time for the associated query in milliseconds.
-	 * 
-	 * @return long		The parse time for the associated query in milliseconds.
-	 */
-	public long getParseTimeInMillis();
-
-	/**
-	 * Get the bind time for the associated query in milliseconds.
-	 * 
-	 * @return long		The bind time for the associated query in milliseconds.
-	 */
-	public long getBindTimeInMillis();
-
-	/**
-	 * Get the optimize time for the associated query in milliseconds.
-	 * 
-	 * @return long		The optimize time for the associated query in milliseconds.
-	 */
-	public long getOptimizeTimeInMillis();
-
-	/**
-	 * Get the generate time for the associated query in milliseconds.
-	 * 
-	 * @return long		The generate time for the associated query in milliseconds.
-	 */
-	public long getGenerateTimeInMillis();
-
-	/**
-	 * Get the timestamp for the beginning of compilation
-	 *
-	 * @return Timestamp	The timestamp for the beginning of compilation.
-	 */
-	public Timestamp getBeginCompileTimestamp();
-
-	/**
-	 * Get the timestamp for the end of compilation
-	 *
-	 * @return Timestamp	The timestamp for the end of compilation.
-	 */
-	public Timestamp getEndCompileTimestamp();
-
-	/**
-	 * Returns whether or not this Statement requires should
-	 * behave atomically -- i.e. whether a user is permitted
-	 * to do a commit/rollback during the execution of this
-	 * statement.
-	 *
-	 * @return boolean	Whether or not this Statement is atomic
-	 */
-	boolean isAtomic();
-
-	/**
-		Return any compile time warnings. Null if no warnings exist.
-	*/
-	public SQLWarning getCompileTimeWarnings();
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.sql
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.sql;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
+
+import org.apache.derby.iapi.sql.depend.Dependent;
+import org.apache.derby.iapi.sql.depend.Provider;
+
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+import java.sql.Timestamp;
+import java.sql.SQLWarning;
+
+/**
+ * The PreparedStatement interface provides methods to execute prepared
+ * statements, store them, and get metadata about them.
+ *
+ *	@author Jeff Lichtman
+ */
+public interface PreparedStatement
+	extends Dependent, Provider
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+
+	/**
+	 * Checks whether this PreparedStatement is up to date.
+	 * A PreparedStatement can become out of date if any of several
+	 * things happen:
+	 *
+	 *	A schema used by the statement is dropped
+	 *	A table used by the statement is dropped
+	 *	A table used by the statement, or a column in such a table,
+	 *		is altered in one of several ways: a column is dropped,
+	 *		a privilege is dropped, a constraint is added or
+	 *		dropped, an index is dropped.
+	 *	A view used by the statement is dropped.
+	 *
+	 * In general, anything that happened since the plan was generated
+	 * that might cause the plan to fail, or to generate incorrect results,
+	 * will cause this method to return FALSE.
+	 *
+	 * @return	TRUE if the PreparedStatement is up to date,
+	 *		FALSE if it is not up to date
+	 */
+	boolean	upToDate() throws StandardException;
+
+	/**
+	 * Re-prepare the statement if it is not up to date or,
+	 * if requested, simply not optimal.
+	 * If there are open cursors using this prepared statement,
+	 * then we will not be able to recompile the statement.
+	 *
+	 * @param lcc			The LanguageConnectionContext.
+	 *
+	 * @exception StandardException thrown if unable to perform
+	 */
+	void rePrepare(LanguageConnectionContext lcc) 
+		throws StandardException;
+
+	/**
+	 * PreparedStatements are re-entrant - that is, more than one
+	 * execution can be active at a time for a single prepared statement.
+	 * An Activation contains all the local state information to
+	 * execute a prepared statement (as opposed to the constant
+	 * information, such as literal values and code). Each Activation
+	 * class contains the code specific to the prepared statement
+	 * represented by an instance of this class (PreparedStatement).
+	 *
+	 * @param lcc			The LanguageConnectionContext.
+	 * @return	The new activation.
+	 *
+	 * @exception StandardException		Thrown on failure
+	 */
+	Activation	getActivation(LanguageConnectionContext lcc, boolean scrollable) throws StandardException;
+
+	/**
+	 * Execute the PreparedStatement and return results.
+	 *<p>
+	 * There is no executeQuery() or
+	 * executeUpdate(); a method is provided in
+	 * ResultSet to tell whether to expect rows to be returned.
+	 *
+	 * @param activation The activation containing all the local state
+	 *		to execute the plan.
+	 * @param executeQuery		Whether or not called from a Statement.executeQuery()
+	 * @param executeUpdate	Whether or not called from a Statement.executeUpdate()
+ 	 * @param rollbackParentContext True if 1) the statement context is
+	 *  NOT a top-level context, AND 2) in the event of a statement-level
+	 *	 exception, the parent context needs to be rolled back, too.
+	 *
+	 * @return	A ResultSet for a statement. A ResultSet represents
+	 *		the results returned from the statement, if any.
+	 *		Will return NULL if the plan for the PreparedStatement
+	 *		has aged out of cache, or the plan is out of date.
+	 *
+	 * @exception StandardException		Thrown on failure
+	 */
+	ResultSet	execute(Activation activation, boolean executeQuery, boolean executeUpdate,
+		boolean rollbackParentContext) throws StandardException;
+
+	/**
+		Simple form of execute(). Creates a new single use activation and executes it,
+		but also passes rollbackParentContext parameter (see above).
+	*/
+	ResultSet	execute(LanguageConnectionContext lcc, boolean rollbackParentContext)
+		throws StandardException;
+
+	/**
+	 * Get the ResultDescription for the statement.  The ResultDescription
+	 * describes what the results look like: what are the rows and columns?
+	 * <p>
+	 * This is available here and on the ResultSet so that users can
+	 * see the shape of the result before they execute.
+	 *
+	 * @return	A ResultDescription describing the results.
+	 *
+	 */
+	ResultDescription	getResultDescription();
+
+	/**
+	 * Return true if the query node for this statement references SESSION schema tables.
+	 *
+	 * @return	true if references SESSION schema tables, else false
+	 */
+	boolean referencesSessionSchema();
+
+	/**
+	 * Get an array of DataTypeDescriptors describing the types of the
+	 * parameters of this PreparedStatement. The Nth element of the array
+	 * describes the Nth parameter.
+	 *
+	 * @return		An array of DataTypeDescriptors telling the
+	 *			type, length, precision, scale, etc. of each
+	 *			parameter of this PreparedStatement.
+	 */
+	DataTypeDescriptor[]	getParameterTypes();
+
+	/**
+	 *	Return the SQL string that this statement is for.
+	 *
+	 *	@return the SQL string this statement is for.
+	 */
+	String getSource();
+
+	/**
+	 *	Return the SPS Name for this statement.
+	 *
+	 *	@return the SPS Name for this statement
+	 */
+	String getSPSName();
+
+	/**
+	 * Get the total compile time for the associated query in milliseconds.
+	 * Compile time can be divided into parse, bind, optimize and generate times.
+	 * 
+	 * @return long		The total compile time for the associated query in milliseconds.
+	 */
+	public long getCompileTimeInMillis();
+
+	/**
+	 * Get the parse time for the associated query in milliseconds.
+	 * 
+	 * @return long		The parse time for the associated query in milliseconds.
+	 */
+	public long getParseTimeInMillis();
+
+	/**
+	 * Get the bind time for the associated query in milliseconds.
+	 * 
+	 * @return long		The bind time for the associated query in milliseconds.
+	 */
+	public long getBindTimeInMillis();
+
+	/**
+	 * Get the optimize time for the associated query in milliseconds.
+	 * 
+	 * @return long		The optimize time for the associated query in milliseconds.
+	 */
+	public long getOptimizeTimeInMillis();
+
+	/**
+	 * Get the generate time for the associated query in milliseconds.
+	 * 
+	 * @return long		The generate time for the associated query in milliseconds.
+	 */
+	public long getGenerateTimeInMillis();
+
+	/**
+	 * Get the timestamp for the beginning of compilation
+	 *
+	 * @return Timestamp	The timestamp for the beginning of compilation.
+	 */
+	public Timestamp getBeginCompileTimestamp();
+
+	/**
+	 * Get the timestamp for the end of compilation
+	 *
+	 * @return Timestamp	The timestamp for the end of compilation.
+	 */
+	public Timestamp getEndCompileTimestamp();
+
+	/**
+	 * Returns whether or not this Statement requires should
+	 * behave atomically -- i.e. whether a user is permitted
+	 * to do a commit/rollback during the execution of this
+	 * statement.
+	 *
+	 * @return boolean	Whether or not this Statement is atomic
+	 */
+	boolean isAtomic();
+
+	/**
+		Return any compile time warnings. Null if no warnings exist.
+	*/
+	public SQLWarning getCompileTimeWarnings();
+
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ResultColumnDescriptor.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ResultColumnDescriptor.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ResultColumnDescriptor.java	Fri Sep 24 10:33:20 2004
@@ -1,88 +1,88 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.sql
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.sql;
-
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-
-/**
- * A ResultColumnDescriptor describes a result column in a ResultSet.
- *
- * @author Jeff Lichtman
- */
-
-public interface ResultColumnDescriptor
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	/**
-	 * Returns a DataTypeDescriptor for the column. This DataTypeDescriptor
-	 * will not represent an actual value, it will only represent the type
-	 * that all values in the column will have.
-	 *
-	 * @return	A DataTypeDescriptor describing the type of the column.
-	 */
-	DataTypeDescriptor	getType();
-
-	/**
-	 * Returns the name of the Column.
-	 *
-	 * @return	A String containing the name of the column.
-	 */
-	String	getName();
-
-	/**
-	 * Get the name of the schema the Column is in, if any.
-	 *
-	 * @return	A String containing the name of the schema the Column
-	 *		is in.  If the column is not in a schema (i.e. is a
-	 * 		derived column), it returns NULL.
-	 */
-	String	getSchemaName();
-
-	/**
-	 * Get the name of the table the Column is in, if any.
-	 *
-	 * @return	A String containing the name of the table the Column
-	 *		is in. If the column is not in a table (i.e. is a
-	 * 		derived column), it returns NULL.
-	 */
-	String	getSourceTableName();
-
-	/**
-	 * Get the position of the Column.
-	 * NOTE - position is 1-based.
-	 *
-	 * @return	An int containing the position of the Column
-	 *		within the table.
-	 */
-	int	getColumnPosition();
-
-	/**
-	 * Tell us if the column is an autoincrement column or not.
-	 * 
-	 * @return TRUE, if the column is a base column of a table and is an
-	 * autoincrement column.
-	 */
-	boolean isAutoincrement();
-
-	/*
-	 * NOTE: These interfaces are intended to support JDBC. There are some
-	 * JDBC methods on java.sql.ResultSetMetaData that have no equivalent
-	 * here, mainly because they are of questionable use to us.  They are:
-	 * getCatalogName() (will we support catalogs?), getColumnLabel(),
-	 * isCaseSensitive(), isCurrency(),
-	 * isDefinitelyWritable(), isReadOnly(), isSearchable(), isSigned(),
-	 * isWritable()). The JDBC driver implements these itself, using
-	 * the data type information and knowing data type characteristics.
-	 */
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.sql
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.sql;
+
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+
+/**
+ * A ResultColumnDescriptor describes a result column in a ResultSet.
+ *
+ * @author Jeff Lichtman
+ */
+
+public interface ResultColumnDescriptor
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	/**
+	 * Returns a DataTypeDescriptor for the column. This DataTypeDescriptor
+	 * will not represent an actual value, it will only represent the type
+	 * that all values in the column will have.
+	 *
+	 * @return	A DataTypeDescriptor describing the type of the column.
+	 */
+	DataTypeDescriptor	getType();
+
+	/**
+	 * Returns the name of the Column.
+	 *
+	 * @return	A String containing the name of the column.
+	 */
+	String	getName();
+
+	/**
+	 * Get the name of the schema the Column is in, if any.
+	 *
+	 * @return	A String containing the name of the schema the Column
+	 *		is in.  If the column is not in a schema (i.e. is a
+	 * 		derived column), it returns NULL.
+	 */
+	String	getSchemaName();
+
+	/**
+	 * Get the name of the table the Column is in, if any.
+	 *
+	 * @return	A String containing the name of the table the Column
+	 *		is in. If the column is not in a table (i.e. is a
+	 * 		derived column), it returns NULL.
+	 */
+	String	getSourceTableName();
+
+	/**
+	 * Get the position of the Column.
+	 * NOTE - position is 1-based.
+	 *
+	 * @return	An int containing the position of the Column
+	 *		within the table.
+	 */
+	int	getColumnPosition();
+
+	/**
+	 * Tell us if the column is an autoincrement column or not.
+	 * 
+	 * @return TRUE, if the column is a base column of a table and is an
+	 * autoincrement column.
+	 */
+	boolean isAutoincrement();
+
+	/*
+	 * NOTE: These interfaces are intended to support JDBC. There are some
+	 * JDBC methods on java.sql.ResultSetMetaData that have no equivalent
+	 * here, mainly because they are of questionable use to us.  They are:
+	 * getCatalogName() (will we support catalogs?), getColumnLabel(),
+	 * isCaseSensitive(), isCurrency(),
+	 * isDefinitelyWritable(), isReadOnly(), isSearchable(), isSigned(),
+	 * isWritable()). The JDBC driver implements these itself, using
+	 * the data type information and knowing data type characteristics.
+	 */
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ResultDescription.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ResultDescription.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ResultDescription.java	Fri Sep 24 10:33:20 2004
@@ -1,78 +1,78 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.sql
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.sql;
-
-/**
- * The ResultDescription interface provides methods to get metadata on the
- * results returned by a statement.
- *
- * @author Jeff Lichtman
- */
-
-public interface ResultDescription
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	/**
-	 * Returns an identifier that tells what type of statement has been
-	 * executed. This can be used to determine what other methods to call
-	 * to get the results back from a statement. For example, a SELECT
-	 * statement returns rows and columns, while other statements don't,
-	 * so you would only call getColumnCount() or getColumnType() for
-	 * SELECT statements.
-	 *
-	 * @return	A String identifier telling what type of statement this
-	 *		is.
-	 */
-	String	getStatementType();	
-
-	/**
-	 * Returns the number of columns in the result set.
-	 *
-	 * @return	The number of columns in the result set.
-	 */
-	int	getColumnCount();
-
-	/**
-		Return information about all the columns.
-	*/
-	public ResultColumnDescriptor[] getColumnInfo();
-
-	/**
-	 * Returns a ResultColumnDescriptor for the column, given the oridinal
-	 * position of the column.
-	 * NOTE - position is 1-based.
-	 *
-	 * @param position	The oridinal position of a column in the
-	 *			ResultSet.
-	 *
-	 * @return		A ResultColumnDescriptor describing the
-	 *			column in the ResultSet.
-	 */
-	ResultColumnDescriptor	getColumnDescriptor(int position);
-
-	/**
-	 * Get a new result description that has been truncated
-	 * from input column number.   If the input column is
-	 * 5, then columns 5 to getColumnCount() are removed.
-	 * The new ResultDescription points to the same
-	 * ColumnDescriptors (this method performs a shallow
-	 * copy.
-	 *
-	 * @param truncateFrom the starting column to remove,
-	 * 1-based.
-	 *
-	 * @return a new ResultDescription
-	 */
-	public ResultDescription truncateColumns(int truncateFrom);
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.sql
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.sql;
+
+/**
+ * The ResultDescription interface provides methods to get metadata on the
+ * results returned by a statement.
+ *
+ * @author Jeff Lichtman
+ */
+
+public interface ResultDescription
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	/**
+	 * Returns an identifier that tells what type of statement has been
+	 * executed. This can be used to determine what other methods to call
+	 * to get the results back from a statement. For example, a SELECT
+	 * statement returns rows and columns, while other statements don't,
+	 * so you would only call getColumnCount() or getColumnType() for
+	 * SELECT statements.
+	 *
+	 * @return	A String identifier telling what type of statement this
+	 *		is.
+	 */
+	String	getStatementType();	
+
+	/**
+	 * Returns the number of columns in the result set.
+	 *
+	 * @return	The number of columns in the result set.
+	 */
+	int	getColumnCount();
+
+	/**
+		Return information about all the columns.
+	*/
+	public ResultColumnDescriptor[] getColumnInfo();
+
+	/**
+	 * Returns a ResultColumnDescriptor for the column, given the oridinal
+	 * position of the column.
+	 * NOTE - position is 1-based.
+	 *
+	 * @param position	The oridinal position of a column in the
+	 *			ResultSet.
+	 *
+	 * @return		A ResultColumnDescriptor describing the
+	 *			column in the ResultSet.
+	 */
+	ResultColumnDescriptor	getColumnDescriptor(int position);
+
+	/**
+	 * Get a new result description that has been truncated
+	 * from input column number.   If the input column is
+	 * 5, then columns 5 to getColumnCount() are removed.
+	 * The new ResultDescription points to the same
+	 * ColumnDescriptors (this method performs a shallow
+	 * copy.
+	 *
+	 * @param truncateFrom the starting column to remove,
+	 * 1-based.
+	 *
+	 * @return a new ResultDescription
+	 */
+	public ResultDescription truncateColumns(int truncateFrom);
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ResultSet.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ResultSet.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/ResultSet.java	Fri Sep 24 10:33:20 2004
@@ -1,330 +1,330 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.sql
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.sql;
-
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.sql.execute.ExecRow;
-import org.apache.derby.iapi.sql.execute.NoPutResultSet;
-import org.apache.derby.iapi.sql.Row;
-
-import java.sql.Timestamp;
-import java.sql.SQLWarning;
-
-/**
- * The ResultSet interface provides a method to tell whether a statement
- * returns rows, and if so, a method to get the rows. It also provides a
- * method to get metadata about the contents of the rows. It also provide
- * a method to accept rows as input.
- * <p>
- * There is no single implementation of the ResultSet interface. Instead,
- * the various support operations involved in executing statements
- * implement this interface.
- * <p>
- * Although ExecRow is used on the interface, it is not available to
- * users of the API. They should use Row, the exposed super-interface
- * of ExecRow.  <<I couldn't find another way to perform this mapping...>>
- * <p>
- * Valid transitions: <ul>
- * <li> open->close</li>
- * <li> close->open</li>
- * <li> close->finished</li>
- * <li> finished->open</li>
- * </ul>
- *
- * @author Jeff Lichtman
- */
-
-public interface ResultSet
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	/* Get time only spent in this ResultSet */
-	public static final int CURRENT_RESULTSET_ONLY = 0;
-	/* Get time spent in this ResultSet and below */
-	public static final int ENTIRE_RESULTSET_TREE = 1;
-
-	// cursor check positioning
-	public static final int ISBEFOREFIRST = 101;
-	public static final int ISFIRST = 102;
-	public static final int ISLAST = 103;
-	public static final int ISAFTERLAST = 104;
-
-	/**
-	 * Returns TRUE if the statement returns rows (i.e. is a SELECT
-	 * or FETCH statement), FALSE if it returns no rows.
-	 *
-	 * @return	TRUE if the statement returns rows, FALSE if not.
-	 */
-	 boolean	returnsRows();
-
-	/**
-	 * Returns the number of rows affected by the statement.
-	   Only valid of returnsRows() returns false.
-	 * For other DML statements, it returns the number of rows
-	 * modified by the statement. For statements that do not affect rows
-	 * (like DDL statements), it returns zero.
-	 *
-	 * @return	The number of rows affect by the statement, so far.
-	 */
-	int	modifiedRowCount();
-
-	/**
-	 * Returns a ResultDescription object, which describes the results
-	 * of the statement this ResultSet is in. This will *not* be a
-	 * description of this particular ResultSet, if this is not the
-	 * outermost ResultSet.
-	 *
-	 * @return	A ResultDescription describing the results of the
-	 *		statement.
-	 */
-	ResultDescription	getResultDescription();
-
-	/**
-	 * Needs to be called before the result set will do anything.
-	 * Need to call before getNextRow(), or for a result set
-	 * that doesn't return rows, this is the call that will
-	 * cause all the work to be done.
-	 *
-	 * @return	Nothing
-	 *
-	 * @exception StandardException		Thrown on failure
-	 */
-	void	open() throws StandardException;
-
-	/**
-	 * Returns the row at the absolute position from the query, 
-	 * and returns NULL when there is no such position.
-	 * (Negative position means from the end of the result set.)
-	 * Moving the cursor to an invalid position leaves the cursor
-	 * positioned either before the first row (negative position)
-	 * or after the last row (positive position).
-	 * NOTE: An exception will be thrown on 0.
-	 *
-	 * @param row	The position.
-	 * @return	The row at the absolute position, or NULL if no such position.
-	 *
-	 * @exception StandardException		Thrown on failure
-	 * @see Row
-	 */
-	ExecRow	getAbsoluteRow(int row) throws StandardException;
-
-	/**
-	 * Returns the row at the relative position from the current
-	 * cursor position, and returns NULL when there is no such position.
-	 * (Negative position means toward the beginning of the result set.)
-	 * Moving the cursor to an invalid position leaves the cursor
-	 * positioned either before the first row (negative position)
-	 * or after the last row (positive position).
-	 * NOTE: 0 is valid.
-	 * NOTE: An exception is thrown if the cursor is not currently
-	 * positioned on a row.
-	 *
-	 * @param row	The position.
-	 * @return	The row at the relative position, or NULL if no such position.
-	 *
-	 * @exception StandardException		Thrown on failure
-	 * @see Row
-	 */
-	ExecRow	getRelativeRow(int row) throws StandardException;
-
-	/**
-	 * Sets the current position to before the first row and returns NULL
-	 * because there is no current row.
-	 *
-	 * @return	NULL.
-	 *
-	 * @exception StandardException		Thrown on failure
-	 * @see Row
-	 */
-	ExecRow	setBeforeFirstRow() throws StandardException;
-
-	/**
-	 * Returns the first row from the query, and returns NULL when there
-	 * are no rows.
-	 *
-	 * @return	The first row, or NULL if no rows.
-	 *
-	 * @exception StandardException		Thrown on failure
-	 * @see Row
-	 */
-	ExecRow	getFirstRow() throws StandardException;
-
-	/**
-	 * Returns the next row from the query, and returns NULL when there
-	 * are no more rows.
-	 *
-	 * @return	The next row, or NULL if no more rows.
-	 *
-	 * @exception StandardException		Thrown on failure
-	 * @see Row
-	 */
-	ExecRow	getNextRow() throws StandardException;
-
-	/**
-	 * Returns the previous row from the query, and returns NULL when there
-	 * are no more previous rows.
-	 *
-	 * @return	The previous row, or NULL if no more previous rows.
-	 *
-	 * @exception StandardException		Thrown on failure
-	 * @see Row
-	 */
-	ExecRow	getPreviousRow() throws StandardException;
-
-	/**
-	 * Returns the last row from the query, and returns NULL when there
-	 * are no rows.
-	 *
-	 * @return	The last row, or NULL if no rows.
-	 *
-	 * @exception StandardException		Thrown on failure
-	 * @see Row
-	 */
-	ExecRow	getLastRow() throws StandardException;
-
-	/**
-	 * Sets the current position to after the last row and returns NULL
-	 * because there is no current row.
-	 *
-	 * @return	NULL.
-	 *
-	 * @exception StandardException		Thrown on failure
-	 * @see Row
-	 */
-	ExecRow	setAfterLastRow() throws StandardException;
-
-    /**
-		Determine if the result set is at one of the positions
-		according to the constants above (ISBEFOREFIRST etc).
-		Only valid and called for scrollable cursors.
-     * @return true if at the requested position.
-	 * @exception StandardException Thrown on error.
-     */
-    public boolean checkRowPosition(int isType) throws StandardException;
-
-	/**
-	 * Returns the row number of the current row.  Row
-	 * numbers start from 1 and go to 'n'.  Corresponds
-	 * to row numbering used to position current row
-	 * in the result set (as per JDBC).
-
-		Only valid and called for scrollable cursors.
-	 * @return	the row number, or 0 if not on a row
-	 *
-	 */
-	int	getRowNumber();
-
-	/**
-	 * Tells the system that there will be no more calls to getNextRow()
-	 * (until the next open() call), so it can free up the resources
-	 * associated with the ResultSet.
-	 *
-	 * @return	Nothing
-	 *
-	 * @exception StandardException		Thrown on error.
-	 */
-	void	close() throws StandardException;
-
-	/**
-	 * Tells the system to clean up on an error.
-	 *
-	 * @return	Nothing
-	 *
-	 * @exception StandardException		Thrown on error.
-	 */
-	void	cleanUp() throws StandardException;
-
-	/**
-		Find out if the ResultSet is closed or not.
-		Will report true for result sets that do not return rows.
-
-		@return true if the ResultSet has been closed.
-	 */
-	boolean isClosed();
-
-	/**
-	 * Tells the system that there will be no more access
-	 * to any database information via this result set;
-	 * in particular, no more calls to open().
-	 * Will close the result set if it is not already closed.
-	 *
-	 * @return	Nothing
-	 * @exception StandardException	on error
-	 */
-	void	finish() throws StandardException;
-
-	/**
-	 * Get the execution time in milliseconds.
-	 *
-	 * @return long		The execution time in milliseconds.
-	 */
-	public long getExecuteTime();
-
-	/**
-	 * Get the Timestamp for the beginning of execution.
-	 *
-	 * @return Timestamp		The Timestamp for the beginning of execution.
-	 */
-	public Timestamp getBeginExecutionTimestamp();
-
-	/**
-	 * Get the Timestamp for the end of execution.
-	 *
-	 * @return Timestamp		The Timestamp for the end of execution.
-	 */
-	public Timestamp getEndExecutionTimestamp();
-
-	/**
-	 * Return the total amount of time spent in this ResultSet
-	 *
-	 * @param type	CURRENT_RESULTSET_ONLY - time spent only in this ResultSet
-	 *				ENTIRE_RESULTSET_TREE  - time spent in this ResultSet and below.
-	 *
-	 * @return long		The total amount of time spent (in milliseconds).
-	 */
-	public long getTimeSpent(int type);	
-
-	/**
-	 * Get the subquery ResultSet tracking array from the top ResultSet.
-	 * (Used for tracking open subqueries when closing down on an error.)
-	 *
-	 * @param numSubqueries		The size of the array (For allocation on demand.)
-	 *
-	 * @return NoPutResultSet[]	Array of NoPutResultSets for subqueries.
-	 */
-	public NoPutResultSet[] getSubqueryTrackingArray(int numSubqueries);
-
-	/**
-	 * ResultSet for rowss inserted into the table (contains auto-generated keys columns only)
-	 *
-	 * @return NoPutResultSet	NoPutResultSets for rows inserted into the table.
-	 */
-	public ResultSet getAutoGeneratedKeysResultset();
-
-	/**
-	 * Returns the name of the cursor, if this is cursor statement of some
-	 * type (declare, open, fetch, positioned update, positioned delete,
-	 * close).
-	 *
-	 * @return	A String with the name of the cursor, if any. Returns
-	 *		NULL if this is not a cursor statement.
-	 */
-	public String	getCursorName();
-
-	/**
-		Return the set of warnings generated during the execution of
-		this result set. The warnings are cleared once this call returns.
-	*/
-	public SQLWarning getWarnings();
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.sql
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.sql;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.sql.execute.ExecRow;
+import org.apache.derby.iapi.sql.execute.NoPutResultSet;
+import org.apache.derby.iapi.sql.Row;
+
+import java.sql.Timestamp;
+import java.sql.SQLWarning;
+
+/**
+ * The ResultSet interface provides a method to tell whether a statement
+ * returns rows, and if so, a method to get the rows. It also provides a
+ * method to get metadata about the contents of the rows. It also provide
+ * a method to accept rows as input.
+ * <p>
+ * There is no single implementation of the ResultSet interface. Instead,
+ * the various support operations involved in executing statements
+ * implement this interface.
+ * <p>
+ * Although ExecRow is used on the interface, it is not available to
+ * users of the API. They should use Row, the exposed super-interface
+ * of ExecRow.  <<I couldn't find another way to perform this mapping...>>
+ * <p>
+ * Valid transitions: <ul>
+ * <li> open->close</li>
+ * <li> close->open</li>
+ * <li> close->finished</li>
+ * <li> finished->open</li>
+ * </ul>
+ *
+ * @author Jeff Lichtman
+ */
+
+public interface ResultSet
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	/* Get time only spent in this ResultSet */
+	public static final int CURRENT_RESULTSET_ONLY = 0;
+	/* Get time spent in this ResultSet and below */
+	public static final int ENTIRE_RESULTSET_TREE = 1;
+
+	// cursor check positioning
+	public static final int ISBEFOREFIRST = 101;
+	public static final int ISFIRST = 102;
+	public static final int ISLAST = 103;
+	public static final int ISAFTERLAST = 104;
+
+	/**
+	 * Returns TRUE if the statement returns rows (i.e. is a SELECT
+	 * or FETCH statement), FALSE if it returns no rows.
+	 *
+	 * @return	TRUE if the statement returns rows, FALSE if not.
+	 */
+	 boolean	returnsRows();
+
+	/**
+	 * Returns the number of rows affected by the statement.
+	   Only valid of returnsRows() returns false.
+	 * For other DML statements, it returns the number of rows
+	 * modified by the statement. For statements that do not affect rows
+	 * (like DDL statements), it returns zero.
+	 *
+	 * @return	The number of rows affect by the statement, so far.
+	 */
+	int	modifiedRowCount();
+
+	/**
+	 * Returns a ResultDescription object, which describes the results
+	 * of the statement this ResultSet is in. This will *not* be a
+	 * description of this particular ResultSet, if this is not the
+	 * outermost ResultSet.
+	 *
+	 * @return	A ResultDescription describing the results of the
+	 *		statement.
+	 */
+	ResultDescription	getResultDescription();
+
+	/**
+	 * Needs to be called before the result set will do anything.
+	 * Need to call before getNextRow(), or for a result set
+	 * that doesn't return rows, this is the call that will
+	 * cause all the work to be done.
+	 *
+	 * @return	Nothing
+	 *
+	 * @exception StandardException		Thrown on failure
+	 */
+	void	open() throws StandardException;
+
+	/**
+	 * Returns the row at the absolute position from the query, 
+	 * and returns NULL when there is no such position.
+	 * (Negative position means from the end of the result set.)
+	 * Moving the cursor to an invalid position leaves the cursor
+	 * positioned either before the first row (negative position)
+	 * or after the last row (positive position).
+	 * NOTE: An exception will be thrown on 0.
+	 *
+	 * @param row	The position.
+	 * @return	The row at the absolute position, or NULL if no such position.
+	 *
+	 * @exception StandardException		Thrown on failure
+	 * @see Row
+	 */
+	ExecRow	getAbsoluteRow(int row) throws StandardException;
+
+	/**
+	 * Returns the row at the relative position from the current
+	 * cursor position, and returns NULL when there is no such position.
+	 * (Negative position means toward the beginning of the result set.)
+	 * Moving the cursor to an invalid position leaves the cursor
+	 * positioned either before the first row (negative position)
+	 * or after the last row (positive position).
+	 * NOTE: 0 is valid.
+	 * NOTE: An exception is thrown if the cursor is not currently
+	 * positioned on a row.
+	 *
+	 * @param row	The position.
+	 * @return	The row at the relative position, or NULL if no such position.
+	 *
+	 * @exception StandardException		Thrown on failure
+	 * @see Row
+	 */
+	ExecRow	getRelativeRow(int row) throws StandardException;
+
+	/**
+	 * Sets the current position to before the first row and returns NULL
+	 * because there is no current row.
+	 *
+	 * @return	NULL.
+	 *
+	 * @exception StandardException		Thrown on failure
+	 * @see Row
+	 */
+	ExecRow	setBeforeFirstRow() throws StandardException;
+
+	/**
+	 * Returns the first row from the query, and returns NULL when there
+	 * are no rows.
+	 *
+	 * @return	The first row, or NULL if no rows.
+	 *
+	 * @exception StandardException		Thrown on failure
+	 * @see Row
+	 */
+	ExecRow	getFirstRow() throws StandardException;
+
+	/**
+	 * Returns the next row from the query, and returns NULL when there
+	 * are no more rows.
+	 *
+	 * @return	The next row, or NULL if no more rows.
+	 *
+	 * @exception StandardException		Thrown on failure
+	 * @see Row
+	 */
+	ExecRow	getNextRow() throws StandardException;
+
+	/**
+	 * Returns the previous row from the query, and returns NULL when there
+	 * are no more previous rows.
+	 *
+	 * @return	The previous row, or NULL if no more previous rows.
+	 *
+	 * @exception StandardException		Thrown on failure
+	 * @see Row
+	 */
+	ExecRow	getPreviousRow() throws StandardException;
+
+	/**
+	 * Returns the last row from the query, and returns NULL when there
+	 * are no rows.
+	 *
+	 * @return	The last row, or NULL if no rows.
+	 *
+	 * @exception StandardException		Thrown on failure
+	 * @see Row
+	 */
+	ExecRow	getLastRow() throws StandardException;
+
+	/**
+	 * Sets the current position to after the last row and returns NULL
+	 * because there is no current row.
+	 *
+	 * @return	NULL.
+	 *
+	 * @exception StandardException		Thrown on failure
+	 * @see Row
+	 */
+	ExecRow	setAfterLastRow() throws StandardException;
+
+    /**
+		Determine if the result set is at one of the positions
+		according to the constants above (ISBEFOREFIRST etc).
+		Only valid and called for scrollable cursors.
+     * @return true if at the requested position.
+	 * @exception StandardException Thrown on error.
+     */
+    public boolean checkRowPosition(int isType) throws StandardException;
+
+	/**
+	 * Returns the row number of the current row.  Row
+	 * numbers start from 1 and go to 'n'.  Corresponds
+	 * to row numbering used to position current row
+	 * in the result set (as per JDBC).
+
+		Only valid and called for scrollable cursors.
+	 * @return	the row number, or 0 if not on a row
+	 *
+	 */
+	int	getRowNumber();
+
+	/**
+	 * Tells the system that there will be no more calls to getNextRow()
+	 * (until the next open() call), so it can free up the resources
+	 * associated with the ResultSet.
+	 *
+	 * @return	Nothing
+	 *
+	 * @exception StandardException		Thrown on error.
+	 */
+	void	close() throws StandardException;
+
+	/**
+	 * Tells the system to clean up on an error.
+	 *
+	 * @return	Nothing
+	 *
+	 * @exception StandardException		Thrown on error.
+	 */
+	void	cleanUp() throws StandardException;
+
+	/**
+		Find out if the ResultSet is closed or not.
+		Will report true for result sets that do not return rows.
+
+		@return true if the ResultSet has been closed.
+	 */
+	boolean isClosed();
+
+	/**
+	 * Tells the system that there will be no more access
+	 * to any database information via this result set;
+	 * in particular, no more calls to open().
+	 * Will close the result set if it is not already closed.
+	 *
+	 * @return	Nothing
+	 * @exception StandardException	on error
+	 */
+	void	finish() throws StandardException;
+
+	/**
+	 * Get the execution time in milliseconds.
+	 *
+	 * @return long		The execution time in milliseconds.
+	 */
+	public long getExecuteTime();
+
+	/**
+	 * Get the Timestamp for the beginning of execution.
+	 *
+	 * @return Timestamp		The Timestamp for the beginning of execution.
+	 */
+	public Timestamp getBeginExecutionTimestamp();
+
+	/**
+	 * Get the Timestamp for the end of execution.
+	 *
+	 * @return Timestamp		The Timestamp for the end of execution.
+	 */
+	public Timestamp getEndExecutionTimestamp();
+
+	/**
+	 * Return the total amount of time spent in this ResultSet
+	 *
+	 * @param type	CURRENT_RESULTSET_ONLY - time spent only in this ResultSet
+	 *				ENTIRE_RESULTSET_TREE  - time spent in this ResultSet and below.
+	 *
+	 * @return long		The total amount of time spent (in milliseconds).
+	 */
+	public long getTimeSpent(int type);	
+
+	/**
+	 * Get the subquery ResultSet tracking array from the top ResultSet.
+	 * (Used for tracking open subqueries when closing down on an error.)
+	 *
+	 * @param numSubqueries		The size of the array (For allocation on demand.)
+	 *
+	 * @return NoPutResultSet[]	Array of NoPutResultSets for subqueries.
+	 */
+	public NoPutResultSet[] getSubqueryTrackingArray(int numSubqueries);
+
+	/**
+	 * ResultSet for rowss inserted into the table (contains auto-generated keys columns only)
+	 *
+	 * @return NoPutResultSet	NoPutResultSets for rows inserted into the table.
+	 */
+	public ResultSet getAutoGeneratedKeysResultset();
+
+	/**
+	 * Returns the name of the cursor, if this is cursor statement of some
+	 * type (declare, open, fetch, positioned update, positioned delete,
+	 * close).
+	 *
+	 * @return	A String with the name of the cursor, if any. Returns
+	 *		NULL if this is not a cursor statement.
+	 */
+	public String	getCursorName();
+
+	/**
+		Return the set of warnings generated during the execution of
+		this result set. The warnings are cleared once this call returns.
+	*/
+	public SQLWarning getWarnings();
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/Row.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/Row.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/Row.java	Fri Sep 24 10:33:20 2004
@@ -1,58 +1,58 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.sql
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.sql;
-
-import org.apache.derby.iapi.types.DataValueDescriptor;
-
-import org.apache.derby.iapi.error.StandardException;
-
-/**
- * The Row interface provides methods to get information about the columns
- * in a result row.
- * It uses simple, position (1-based) access to get to columns.
- * Searching for columns by name should be done from the ResultSet
- * interface, where metadata about the rows and columns is available.
- * <p>
- *
- * @see ResultSet
- *
- * @author Jeff Lichtman
- * @see org.apache.derby.iapi.sql.execute.ExecRow
- */
-
-public interface Row
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	public int nColumns();
-
-	/**
-	 * Get a DataValueDescriptor in a Row by ordinal position (1-based).
-	 *
-	 * @param position	The ordinal position of the column.
-	 *
-     * @exception   StandardException Thrown on failure.
-	 * @return		The DataValueDescriptor, null if no such column exists
-	 */
-	DataValueDescriptor	getColumn (int position) throws StandardException;
-
-	/**
-	 * Set a DataValueDescriptor in a Row by ordinal position (1-based).
-	 *
-	 * @param position	The ordinal position of the column.
-	 *
-	 * @return		The DataValueDescriptor, null if no such column exists
-	 */
-	void	setColumn (int position, DataValueDescriptor value);
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.sql
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.sql;
+
+import org.apache.derby.iapi.types.DataValueDescriptor;
+
+import org.apache.derby.iapi.error.StandardException;
+
+/**
+ * The Row interface provides methods to get information about the columns
+ * in a result row.
+ * It uses simple, position (1-based) access to get to columns.
+ * Searching for columns by name should be done from the ResultSet
+ * interface, where metadata about the rows and columns is available.
+ * <p>
+ *
+ * @see ResultSet
+ *
+ * @author Jeff Lichtman
+ * @see org.apache.derby.iapi.sql.execute.ExecRow
+ */
+
+public interface Row
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	public int nColumns();
+
+	/**
+	 * Get a DataValueDescriptor in a Row by ordinal position (1-based).
+	 *
+	 * @param position	The ordinal position of the column.
+	 *
+     * @exception   StandardException Thrown on failure.
+	 * @return		The DataValueDescriptor, null if no such column exists
+	 */
+	DataValueDescriptor	getColumn (int position) throws StandardException;
+
+	/**
+	 * Set a DataValueDescriptor in a Row by ordinal position (1-based).
+	 *
+	 * @param position	The ordinal position of the column.
+	 *
+	 * @return		The DataValueDescriptor, null if no such column exists
+	 */
+	void	setColumn (int position, DataValueDescriptor value);
+
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/Statement.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/Statement.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/Statement.java	Fri Sep 24 10:33:20 2004
@@ -1,88 +1,88 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.sql
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.sql;
-
-import org.apache.derby.iapi.error.StandardException;
-import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
-import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
-
-/**
- * The Statement interface provides a way of giving a statement to the
- * language module, preparing the statement, and executing it. It also
- * provides some support for stored statements. Simple, non-stored,
- * non-parameterized statements can be executed with the execute() method.
- * Parameterized statements must use prepare(). To get the stored query
- * plan for a statement, use get().
- * <p>
- * This interface will have different implementations for the execution-only
- * and compile-and-execute versions of the product. In the execution-only
- * version, some of the methods will do nothing but raise exceptions to
- * indicate that they are not implemented.
- * <p>
- * There is a Statement factory in the Connection interface in the Database
- * module, which uses the one provided in LanguageFactory.
- *
- *	@author Jeff Lichtman
- */
-public interface Statement
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-
-	/**
-	 * Generates an execution plan without executing it.
-	 *
-	 * @return A PreparedStatement that allows execution of the execution
-	 *	   plan.
-	 * @exception StandardException	Thrown if this is an
-	 *	   execution-only version of the module (the prepare() method
-	 *	   relies on compilation).
-	 */
-	PreparedStatement	prepare(LanguageConnectionContext lcc) throws StandardException;
-
-	/**
-	 * Generates an execution plan given a set of named parameters.
-	 * For generating a storable prepared statement (which
-	 * has some extensions over a standard prepared statement).
-	 *
-	 * @param 	compSchema			the compilation schema to use
-	 * @param	paramDefaults		Default parameter values to use for
-	 *								optimization
-	 * @param	spsSchema schema of the stored prepared statement
-	 *
-	 * @return A Storable PreparedStatement that allows execution of the execution
-	 *	   plan.
-	 * @exception StandardException	Thrown if this is an
-	 *	   execution-only version of the module (the prepare() method
-	 *	   relies on compilation).
-	 */
-	public	PreparedStatement	prepareStorable
-	( 
-		LanguageConnectionContext lcc,
-		PreparedStatement ps, 
-		Object[]			paramDefaults,
-		SchemaDescriptor	spsSchema,
-		boolean	internalSQL
-	)
-		throws StandardException;
-
-	/**
-	 *	Return the SQL string that this statement is for.
-	 *
-	 *	@return the SQL string this statement is for.
-	 */
-	String getSource();
-
-	public boolean getUnicode();
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.sql
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.sql;
+
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
+
+/**
+ * The Statement interface provides a way of giving a statement to the
+ * language module, preparing the statement, and executing it. It also
+ * provides some support for stored statements. Simple, non-stored,
+ * non-parameterized statements can be executed with the execute() method.
+ * Parameterized statements must use prepare(). To get the stored query
+ * plan for a statement, use get().
+ * <p>
+ * This interface will have different implementations for the execution-only
+ * and compile-and-execute versions of the product. In the execution-only
+ * version, some of the methods will do nothing but raise exceptions to
+ * indicate that they are not implemented.
+ * <p>
+ * There is a Statement factory in the Connection interface in the Database
+ * module, which uses the one provided in LanguageFactory.
+ *
+ *	@author Jeff Lichtman
+ */
+public interface Statement
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+
+	/**
+	 * Generates an execution plan without executing it.
+	 *
+	 * @return A PreparedStatement that allows execution of the execution
+	 *	   plan.
+	 * @exception StandardException	Thrown if this is an
+	 *	   execution-only version of the module (the prepare() method
+	 *	   relies on compilation).
+	 */
+	PreparedStatement	prepare(LanguageConnectionContext lcc) throws StandardException;
+
+	/**
+	 * Generates an execution plan given a set of named parameters.
+	 * For generating a storable prepared statement (which
+	 * has some extensions over a standard prepared statement).
+	 *
+	 * @param 	compSchema			the compilation schema to use
+	 * @param	paramDefaults		Default parameter values to use for
+	 *								optimization
+	 * @param	spsSchema schema of the stored prepared statement
+	 *
+	 * @return A Storable PreparedStatement that allows execution of the execution
+	 *	   plan.
+	 * @exception StandardException	Thrown if this is an
+	 *	   execution-only version of the module (the prepare() method
+	 *	   relies on compilation).
+	 */
+	public	PreparedStatement	prepareStorable
+	( 
+		LanguageConnectionContext lcc,
+		PreparedStatement ps, 
+		Object[]			paramDefaults,
+		SchemaDescriptor	spsSchema,
+		boolean	internalSQL
+	)
+		throws StandardException;
+
+	/**
+	 *	Return the SQL string that this statement is for.
+	 *
+	 *	@return the SQL string this statement is for.
+	 */
+	String getSource();
+
+	public boolean getUnicode();
+
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StatementType.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StatementType.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StatementType.java	Fri Sep 24 10:33:20 2004
@@ -1,54 +1,54 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.sql
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.sql;
-
-/**
- * Different types of statements
- *
- * @author jamie
- */
-public interface StatementType
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-	public static final int UNKNOWN	= 0;
-	public static final int INSERT	= 1;
-	public static final int BULK_INSERT_REPLACE = 2;
-	public static final int UPDATE	= 3;
-	public static final int DELETE	= 4;
-	public static final int ENABLED = 5;
-	public static final int DISABLED = 6;
-
-	public static final int DROP_CASCADE = 0;
-	public static final int DROP_RESTRICT = 1;
-	public static final int DROP_DEFAULT = 2;
-
-	public static final int RENAME_TABLE = 1;
-	public static final int RENAME_COLUMN = 2;
-	public static final int RENAME_INDEX = 3;
-
-	public static final int RA_CASCADE = 0;
-	public static final int RA_RESTRICT = 1;
-	public static final int RA_NOACTION = 2;  //default value
-	public static final int RA_SETNULL = 3;
-	public static final int RA_SETDEFAULT = 4;
-	
-	public static final int SET_SCHEMA_USER = 1;
-	public static final int SET_SCHEMA_DYNAMIC = 2;
-	
-}
-
-
-
-
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.sql
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.sql;
+
+/**
+ * Different types of statements
+ *
+ * @author jamie
+ */
+public interface StatementType
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+	public static final int UNKNOWN	= 0;
+	public static final int INSERT	= 1;
+	public static final int BULK_INSERT_REPLACE = 2;
+	public static final int UPDATE	= 3;
+	public static final int DELETE	= 4;
+	public static final int ENABLED = 5;
+	public static final int DISABLED = 6;
+
+	public static final int DROP_CASCADE = 0;
+	public static final int DROP_RESTRICT = 1;
+	public static final int DROP_DEFAULT = 2;
+
+	public static final int RENAME_TABLE = 1;
+	public static final int RENAME_COLUMN = 2;
+	public static final int RENAME_INDEX = 3;
+
+	public static final int RA_CASCADE = 0;
+	public static final int RA_RESTRICT = 1;
+	public static final int RA_NOACTION = 2;  //default value
+	public static final int RA_SETNULL = 3;
+	public static final int RA_SETDEFAULT = 4;
+	
+	public static final int SET_SCHEMA_USER = 1;
+	public static final int SET_SCHEMA_DYNAMIC = 2;
+	
+}
+
+
+
+
+

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StatementUtil.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StatementUtil.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StatementUtil.java	Fri Sep 24 10:33:20 2004
@@ -1,63 +1,63 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.sql
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.sql;
-
-import org.apache.derby.iapi.error.StandardException;
-import org.apache.derby.iapi.services.i18n.MessageService;
-import org.apache.derby.iapi.reference.SQLState;
-
-/**
- * Utilities for dealing with statements.
- *
- * @author jeff
- */
-public class StatementUtil
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-	private StatementUtil(){};	// Do not instantiate
-
-	public static String typeName(int typeNumber)
-	{
-		String retval;
-
-		switch (typeNumber)
-		{
-		  case StatementType.INSERT:
-		  case StatementType.BULK_INSERT_REPLACE:
-		  case StatementType.UPDATE:
-		  case StatementType.DELETE:
-		  case StatementType.ENABLED:
-		  case StatementType.DISABLED:
-			retval = TypeNames[typeNumber];
-			break;
-
-		  default:
-			retval = MessageService.getTextMessage(SQLState.LANG_UNKNOWN);
-			break;
-		}
-
-		return retval;
-	}
-
-	private static final String[] TypeNames = 
-				{ 
-					"",
-					"INSERT",
-					"INSERT",
-					"UPDATE",
-					"DELETE",
-					"ENABLED",
-					"DISABLED"
-				};
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.sql
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.sql;
+
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.services.i18n.MessageService;
+import org.apache.derby.iapi.reference.SQLState;
+
+/**
+ * Utilities for dealing with statements.
+ *
+ * @author jeff
+ */
+public class StatementUtil
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+	private StatementUtil(){};	// Do not instantiate
+
+	public static String typeName(int typeNumber)
+	{
+		String retval;
+
+		switch (typeNumber)
+		{
+		  case StatementType.INSERT:
+		  case StatementType.BULK_INSERT_REPLACE:
+		  case StatementType.UPDATE:
+		  case StatementType.DELETE:
+		  case StatementType.ENABLED:
+		  case StatementType.DISABLED:
+			retval = TypeNames[typeNumber];
+			break;
+
+		  default:
+			retval = MessageService.getTextMessage(SQLState.LANG_UNKNOWN);
+			break;
+		}
+
+		return retval;
+	}
+
+	private static final String[] TypeNames = 
+				{ 
+					"",
+					"INSERT",
+					"INSERT",
+					"UPDATE",
+					"DELETE",
+					"ENABLED",
+					"DISABLED"
+				};
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StorablePreparedStatement.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StorablePreparedStatement.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StorablePreparedStatement.java	Fri Sep 24 10:33:20 2004
@@ -1,38 +1,38 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.sql
-   (C) Copyright IBM Corp. 1999, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.sql;
-
-import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
-import org.apache.derby.iapi.error.StandardException;
-import org.apache.derby.iapi.services.loader.GeneratedClass;
-
-/**
- * The Statement interface is an extension of exec prepared statement
- * that has some stored prepared specifics.
- *
- * @author jamie
- */
-public interface StorablePreparedStatement extends ExecPreparedStatement
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1999_2004;
-
-	/**
-	 * Load up the class from the saved bytes.
-	 *
-	 *
-	 * @exception StandardException on error
-	 */
-	public void loadGeneratedClass()
-		throws StandardException;
-}	
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.sql
+   (C) Copyright IBM Corp. 1999, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.sql;
+
+import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.services.loader.GeneratedClass;
+
+/**
+ * The Statement interface is an extension of exec prepared statement
+ * that has some stored prepared specifics.
+ *
+ * @author jamie
+ */
+public interface StorablePreparedStatement extends ExecPreparedStatement
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1999_2004;
+
+	/**
+	 * Load up the class from the saved bytes.
+	 *
+	 *
+	 * @exception StandardException on error
+	 */
+	public void loadGeneratedClass()
+		throws StandardException;
+}	

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/AccessPath.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/AccessPath.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/AccessPath.java	Fri Sep 24 10:33:20 2004
@@ -1,136 +1,136 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.iapi.sql.compile
-   (C) Copyright IBM Corp. 1999, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.iapi.sql.compile;
-
-import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
-import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
-import org.apache.derby.iapi.sql.dictionary.DataDictionary;
-import org.apache.derby.iapi.error.StandardException;
-
-/**
- * AccessPath represents a proposed access path for an Optimizable.
- * An Optimizable may have more than one proposed AccessPath.
- */
-
-public interface AccessPath {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1999_2004;
-	/**
-	 * Set the conglomerate descriptor for this access path.
-	 *
-	 * @param cd	A ConglomerateDescriptor
-	 *
-	 * @return Nothing.
-	 */
-	void setConglomerateDescriptor(ConglomerateDescriptor cd);
-
-	/**
-	 * Get whatever was last set as the conglomerate descriptor.
-	 * Returns null if nothing was set since the last call to startOptimizing()
-	 */
-	ConglomerateDescriptor getConglomerateDescriptor();
-
-	/**
-	 * Set the given cost estimate in this AccessPath.  Generally, this will
-	 * be the CostEstimate for the plan currently under consideration.
-	 */
-	public void setCostEstimate(CostEstimate costEstimate);
-
-	/**
-	 * Get the cost estimate for this AccessPath.  This is the last one
-	 * set by setCostEstimate.
-	 */
-	public CostEstimate getCostEstimate();
-
-	/**
-	 * Set whether or not to consider a covering index scan on the optimizable.
-	 *
-	 * @return Nothing.
-	 */
-	public void setCoveringIndexScan(boolean coveringIndexScan);
-
-	/**
-	 * Return whether or not the optimizer is considering a covering index
-	 * scan on this AccessPath. 
-	 *
-	 * @return boolean		Whether or not the optimizer chose a covering
-	 *						index scan.
-	 */
-	public boolean getCoveringIndexScan();
-
-	/**
-	 * Set whether or not to consider a non-matching index scan on this
-	 * AccessPath. 
-	 *
-	 * @return Nothing.
-	 */
-	public void setNonMatchingIndexScan(boolean nonMatchingIndexScan);
-
-	/**
-	 * Return whether or not the optimizer is considering a non-matching
-	 * index scan on this AccessPath. We expect to call this during
-	 * generation, after access path selection is complete.
-	 *
-	 * @return boolean		Whether or not the optimizer is considering
-	 *						a non-matching index scan.
-	 */
-	public boolean getNonMatchingIndexScan();
-
-	/**
-	 * Remember the given join strategy
-	 *
-	 * @param joinStrategy	The best join strategy
-	 */
-	public void setJoinStrategy(JoinStrategy joinStrategy);
-
-	/**
-	 * Get the join strategy, as set by setJoinStrategy().
-	 */
-	public JoinStrategy getJoinStrategy();
-
-	/**
-	 * Set the lock mode
-	 */
-	public void setLockMode(int lockMode);
-
-	/**
-	 * Get the lock mode, as last set in setLockMode().
-	 */
-	public int getLockMode();
-
-	/**
-	 * Copy all information from the given AccessPath to this one.
-	 */
-	public void copy(AccessPath copyFrom);
-
-	/**
-	 * Get the optimizer associated with this access path.
-	 *
-	 * @return	The optimizer associated with this access path.
-	 */
-	public Optimizer getOptimizer();
-	
-	/**
-	 * Sets the "name" of the access path. if the access path represents an
-	 * index then set the name to the name of the index. if it is an index
-	 * created for a constraint, use the constraint name. This is called only
-	 * for base tables.
-	 * 
-	 * @param 	td		TableDescriptor of the base table.
-	 * @param 	dd		Datadictionary.
-	 *
-	 * @exception StandardException 	on error.
-	 */
-	public void initializeAccessPathName(DataDictionary dd, TableDescriptor td)
-		throws StandardException;
-}	
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.iapi.sql.compile
+   (C) Copyright IBM Corp. 1999, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.iapi.sql.compile;
+
+import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;
+import org.apache.derby.iapi.error.StandardException;
+
+/**
+ * AccessPath represents a proposed access path for an Optimizable.
+ * An Optimizable may have more than one proposed AccessPath.
+ */
+
+public interface AccessPath {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1999_2004;
+	/**
+	 * Set the conglomerate descriptor for this access path.
+	 *
+	 * @param cd	A ConglomerateDescriptor
+	 *
+	 * @return Nothing.
+	 */
+	void setConglomerateDescriptor(ConglomerateDescriptor cd);
+
+	/**
+	 * Get whatever was last set as the conglomerate descriptor.
+	 * Returns null if nothing was set since the last call to startOptimizing()
+	 */
+	ConglomerateDescriptor getConglomerateDescriptor();
+
+	/**
+	 * Set the given cost estimate in this AccessPath.  Generally, this will
+	 * be the CostEstimate for the plan currently under consideration.
+	 */
+	public void setCostEstimate(CostEstimate costEstimate);
+
+	/**
+	 * Get the cost estimate for this AccessPath.  This is the last one
+	 * set by setCostEstimate.
+	 */
+	public CostEstimate getCostEstimate();
+
+	/**
+	 * Set whether or not to consider a covering index scan on the optimizable.
+	 *
+	 * @return Nothing.
+	 */
+	public void setCoveringIndexScan(boolean coveringIndexScan);
+
+	/**
+	 * Return whether or not the optimizer is considering a covering index
+	 * scan on this AccessPath. 
+	 *
+	 * @return boolean		Whether or not the optimizer chose a covering
+	 *						index scan.
+	 */
+	public boolean getCoveringIndexScan();
+
+	/**
+	 * Set whether or not to consider a non-matching index scan on this
+	 * AccessPath. 
+	 *
+	 * @return Nothing.
+	 */
+	public void setNonMatchingIndexScan(boolean nonMatchingIndexScan);
+
+	/**
+	 * Return whether or not the optimizer is considering a non-matching
+	 * index scan on this AccessPath. We expect to call this during
+	 * generation, after access path selection is complete.
+	 *
+	 * @return boolean		Whether or not the optimizer is considering
+	 *						a non-matching index scan.
+	 */
+	public boolean getNonMatchingIndexScan();
+
+	/**
+	 * Remember the given join strategy
+	 *
+	 * @param joinStrategy	The best join strategy
+	 */
+	public void setJoinStrategy(JoinStrategy joinStrategy);
+
+	/**
+	 * Get the join strategy, as set by setJoinStrategy().
+	 */
+	public JoinStrategy getJoinStrategy();
+
+	/**
+	 * Set the lock mode
+	 */
+	public void setLockMode(int lockMode);
+
+	/**
+	 * Get the lock mode, as last set in setLockMode().
+	 */
+	public int getLockMode();
+
+	/**
+	 * Copy all information from the given AccessPath to this one.
+	 */
+	public void copy(AccessPath copyFrom);
+
+	/**
+	 * Get the optimizer associated with this access path.
+	 *
+	 * @return	The optimizer associated with this access path.
+	 */
+	public Optimizer getOptimizer();
+	
+	/**
+	 * Sets the "name" of the access path. if the access path represents an
+	 * index then set the name to the name of the index. if it is an index
+	 * created for a constraint, use the constraint name. This is called only
+	 * for base tables.
+	 * 
+	 * @param 	td		TableDescriptor of the base table.
+	 * @param 	dd		Datadictionary.
+	 *
+	 * @exception StandardException 	on error.
+	 */
+	public void initializeAccessPathName(DataDictionary dd, TableDescriptor td)
+		throws StandardException;
+}	

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SQLToJavaValueNode.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SQLToJavaValueNode.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SQLToJavaValueNode.java	Fri Sep 24 10:33:20 2004
@@ -1,519 +1,519 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package	org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.services.compiler.MethodBuilder;
-import org.apache.derby.iapi.services.compiler.LocalField;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-import org.apache.derby.iapi.types.JSQLType;
-
-import org.apache.derby.iapi.types.DataValueDescriptor;
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-
-import org.apache.derby.iapi.sql.compile.TypeCompiler;
-
-import org.apache.derby.iapi.sql.Activation;
-
-import org.apache.derby.iapi.sql.dictionary.DataDictionary;
-import org.apache.derby.iapi.error.StandardException;
-import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
-import org.apache.derby.iapi.sql.compile.Visitable;
-import org.apache.derby.iapi.sql.compile.Visitor;
-
-import org.apache.derby.iapi.reference.ClassName;
-
-import org.apache.derby.iapi.util.JBitSet;
-import org.apache.derby.iapi.services.classfile.VMOpcode;
-
-import java.lang.reflect.Modifier;
-
-import java.util.Vector;
-
-/**
- * This node type converts a value in the SQL domain to a value in the Java
- * domain.
- */
-
-public class SQLToJavaValueNode extends JavaValueNode
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	ValueNode	value;
-
-	LocalField	returnsNullOnNullState;
-
-	/**
-	 * Constructor for a SQLToJavaValueNode
-	 *
-	 * @param value		A ValueNode representing a SQL value to convert to
-	 *					the Java domain.
-	 */
-
-	public void init(Object value)
-	{
-		this.value = (ValueNode) value;
-	}
-
-	/**
-	 * Prints the sub-nodes of this object.  See QueryTreeNode.java for
-	 * how tree printing is supposed to work.
-	 *
-	 * @param depth		The depth of this node in the tree
-	 *
-	 * @return	Nothing
-	 */
-
-	public void printSubNodes(int depth)
-	{
-		if (SanityManager.DEBUG)
-		{
-			int	parm;
-
-			super.printSubNodes(depth);
-			if (value != null)
-			{
-				printLabel(depth, "value: ");
-				value.treePrint(depth + 1);
-			}
-		}
-	}
-
-	/**
-	  *	Returns the name of the java class type that this node coerces to.
-	  *
-	  *	@return	name of java class type
-	  *
-	  */
-	public String getJavaTypeName()
-	{
-		JSQLType	myType = getJSQLType();
-
-		if ( myType == null ) { return ""; }
-		else { return	mapToTypeID( myType ).getCorrespondingJavaTypeName(); }
-	}
-
-	/**
-	  *	Returns the name of the java primitive type that this node coerces to.
-	  *
-	  *	@return	name of java primitive type
-	  *
-	  * @exception StandardException		Thrown on error
-	  */
-	public String getPrimitiveTypeName()
-		throws StandardException
-	{
-		JSQLType	myType = getJSQLType();
-
-		if ( myType == null )
-		{
-			return "";
-		}
-		else
-		{
-			return
-				getTypeCompiler(mapToTypeID( myType )).
-										getCorrespondingPrimitiveTypeName();
-		}
-	}
-
-	/**
-	  *	Get the JSQLType that corresponds to this node. Could be a SQLTYPE,
-	  *	a Java primitive, or a Java class.
-	  *
-	  *	Overrides method in JavaValueNode.
-	  *
-	  *	@return	the corresponding JSQLType
-	  *
-	  */
-	public	JSQLType	getJSQLType
-	(
-    )
-	{
-		if ( jsqlType == null )
-		{
-			if ( value.isParameterNode() ) 
-			{
-				jsqlType = ((ParameterNode) value).getJSQLType();
-			}
-			else
-			{
-				DataTypeDescriptor dtd = value.getTypeServices();
-				if (dtd != null)
-					jsqlType = new JSQLType( dtd );
-			}
-		}
-
-		return jsqlType;
-	}
-
-
-	/**
-	 * Set the clause that this node appears in.
-	 *
-	 * @param clause	The clause that this node appears in.
-	 *
-	 * @return Nothing.
-	 */
-	public void setClause(int clause)
-	{
-		super.setClause(clause);
-		value.setClause(clause);
-	}
-
-	/**
-	 * Bind this expression.  This means binding the sub-expressions,
-	 * as well as figuring out what the return type is for this expression.
-	 *
-	 * @param fromList		The FROM list for the query this
-	 *				expression is in, for binding columns.
-	 * @param subqueryList		The subquery list being built as we find
-	 *							SubqueryNodes
-	 * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
-	 *
-	 * @return this	
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public JavaValueNode bindExpression(
-		FromList fromList, SubqueryList subqueryList,
-		Vector	aggregateVector) 
-			throws StandardException
-	{
-		/* Bind the expression under us */
-		value = value.bindExpression(fromList, subqueryList,
-							  aggregateVector);
-
-		return this;
-	}
-
-	/**
-	 * Remap all ColumnReferences in this tree to be clones of the
-	 * underlying expression.
-	 *
-	 * @return JavaValueNode			The remapped expression tree.
-	 *
-	 * @exception StandardException			Thrown on error
-	 */
-	public JavaValueNode remapColumnReferencesToExpressions()
-		throws StandardException
-	{
-		value = value.remapColumnReferencesToExpressions();
-		return this;
-	}
-
-	/**
-	 * Categorize this predicate.  Initially, this means
-	 * building a bit map of the referenced tables for each predicate.
-	 * If the source of this ColumnReference (at the next underlying level) 
-	 * is not a ColumnReference or a VirtualColumnNode then this predicate
-	 * will not be pushed down.
-	 *
-	 * For example, in:
-	 *		select * from (select 1 from s) a (x) where x = 1
-	 * we will not push down x = 1.
-	 * NOTE: It would be easy to handle the case of a constant, but if the
-	 * inner SELECT returns an arbitrary expression, then we would have to copy
-	 * that tree into the pushed predicate, and that tree could contain
-	 * subqueries and method calls.
-	 * RESOLVE - revisit this issue once we have views.
-	 *
-	 * @param referencedTabs	JBitSet with bit map of referenced FromTables
-	 * @param simplePredsOnly	Whether or not to consider method
-	 *							calls, field references and conditional nodes
-	 *							when building bit map
-	 *
-	 * @return boolean		Whether or not source.expression is a ColumnReference
-	 *						or a VirtualColumnNode.
-	 *
-	 * @exception StandardException			Thrown on error
-	 */
-	public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly)
-		throws StandardException
-	{
-		return value.categorize(referencedTabs, simplePredsOnly);
-	}
-
-	/**
-	 * Preprocess an expression tree.  We do a number of transformations
-	 * here (including subqueries, IN lists, LIKE and BETWEEN) plus
-	 * subquery flattening.
-	 * NOTE: This is done before the outer ResultSetNode is preprocessed.
-	 *
-	 * @param	numTables			Number of tables in the DML Statement
-	 * @param	outerFromList		FromList from outer query block
-	 * @param	outerSubqueryList	SubqueryList from outer query block
-	 * @param	outerPredicateList	PredicateList from outer query block
-	 *
-	 * @return	Nothing.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public void preprocess(int numTables,
-							FromList outerFromList,
-							SubqueryList outerSubqueryList,
-							PredicateList outerPredicateList) 
-							throws StandardException
-	{
-		value.preprocess(numTables,
-						 outerFromList, outerSubqueryList,
-						 outerPredicateList);
-	}
-
-	/**
-	 * Return the variant type for the underlying expression.
-	 * The variant type can be:
-	 *		VARIANT				- variant within a scan
-	 *							  (method calls and non-static field access)
-	 *		SCAN_INVARIANT		- invariant within a scan
-	 *							  (column references from outer tables)
-	 *		QUERY_INVARIANT		- invariant within the life of a query
-	 *							  (constant expressions)
-	 *
-	 * @return	The variant type for the underlying expression.
-	 * @exception StandardException	thrown on error
-	 */
-	protected int getOrderableVariantType() throws StandardException
-	{
-		return value.getOrderableVariantType();
-	}
-
-	///////////////////////////////////////////////////////////////////////
-	//
-	//	CODE GENERATION METHODS
-	//
-	///////////////////////////////////////////////////////////////////////
-
-
-	/**
-	 * Generate code to get the Java value out of a SQL value.
-	 *
-	 * Every SQL type has a corresponding Java type.  The getObject() method
-	 * on the SQL type gets the right Java type.
-	 *
-	 * The generated code will be:
-	 *
-	 * (<Java type name>) ((DataValueDescriptor)
-	 *								<generated value>.getObject())
-	 *
-	 * where <Java type name> comes from the getCorrespondingJavaTypeName()
-	 * method of the value's TypeId.
-	 *
-	 * @param acb	The ExpressionClassBuilder for the class being built
-	 * @param mb	The method the expression will go into
-	 *
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public void generateExpression(ExpressionClassBuilder acb,
-											MethodBuilder mb)
-									throws StandardException
-	{
-		/* Compile the expression under us */
-		generateSQLValue( acb, mb );
-
-		/* now cast the SQLValue to a Java value */
-		generateJavaValue( acb, mb);
-	}
-
-	/**
-	 * Generate the SQLvalue that this node wraps.
-	 *
-	 * @param acb	The ExpressionClassBuilder for the class being built
-	 * @param mb	The method the expression will go into
-	 *
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public void generateSQLValue(ExpressionClassBuilder acb,
-											MethodBuilder mb)
-									throws StandardException
-	{
-		value.generateExpression(acb, mb);
-	}
-
-	/**
-	 * Generate code to cast the SQLValue to a Java value.
-	 *
-	 *
-	 * @param acb	The ExpressionClassBuilder for the class being built
-	 * @param mb	The method the expression will go into
-	 * @param SQLValue	An Expression holding the SQLValue.
-	 *
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public void generateJavaValue
-	(
-		ExpressionClassBuilder	acb,
-		MethodBuilder mbex
-    )
-		throws StandardException
-	{
-		/* If this is a conversion to a primitive type, then call the
-		 * appropriate method for getting the primitive value and
-		 * cast it to the primitive type. 
-		 * NOTE: We first call Activation.nullToPrimitiveTest(),
-		 * which will throw a StandardException if the value is null
-		 */
-		if ( isPrimitiveType() || mustCastToPrimitive() )
-		{
-			String		primitiveTN = value.getTypeCompiler().getCorrespondingPrimitiveTypeName();
-
-			/* Put the code to check if the object is null and to
-			 * get the primitive value in a method call.  This is
-			 * necessary because we are generating an expression here and
-			 * cannot have multiple statements.
-			 * The method call will take SQLValue as a parameter.
-			 */
-			String[] pd = new String[1];
-			pd[0] = getSQLValueInterfaceName(); // parameter "param1"
-
-			MethodBuilder	mb = acb.newGeneratedFun(primitiveTN, Modifier.PRIVATE, pd);
-
-			mb.getParameter(0);
-
-			if (returnsNullOnNullState != null)
-			{
-				generateReturnsNullOnNullCheck(mb);
-			}
-			else
-			{
-				mb.dup();
-				mb.upCast(ClassName.DataValueDescriptor);
-				mb.push(primitiveTN); 
-				mb.callMethod(VMOpcode.INVOKESTATIC, ClassName.BaseActivation, "nullToPrimitiveTest", "void", 2);
-			}
-
-			// stack is dvd
-
-			/* Generate the code to get the primitive value */
-			mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.DataValueDescriptor,
-								value.getTypeCompiler().getPrimitiveMethodName(), primitiveTN, 0);
-
-			mb.methodReturn();
-			mb.complete();
-
-			/* Generate the call to the new method, with the parameter */
-
-			mbex.pushThis();
-			mbex.swap(); // caller pushed out parameter
-			mbex.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, mb.getName(), primitiveTN, 1);
-		}
-		else
-		{
-			if (returnsNullOnNullState != null)
-				generateReturnsNullOnNullCheck(mbex);
-
-			/* Call getObject() to get the right type of Java value */
-			mbex.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.DataValueDescriptor, "getObject",
-										"java.lang.Object", 0);
-
-			mbex.cast(value.getTypeId().getCorrespondingJavaTypeName());
-		}
-	}
-
-	/**
-		Generate the code for the returns Null on Null input check..
-		Stack must contain the DataDescriptorValue.
-	*/
-
-	private void generateReturnsNullOnNullCheck(MethodBuilder mb)
-	{
-		mb.dup();
-		mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Storable,
-								"isNull", "boolean", 0);
-
-		mb.conditionalIf();
-		  mb.push(true);
-		mb.startElseCode();
-		  mb.getField(returnsNullOnNullState);
-		mb.completeConditional();
-		
-		mb.putField(returnsNullOnNullState);
-		mb.endStatement();
-	}
-
-
-	/**
-	  *	Get the type name of the SQLValue we generate.
-	  *
-	  *	@return	name of interface corresponding to SQLValue
-	  *
-	  *
-	  * @exception StandardException		Thrown on error
-	  */
-	public	String	getSQLValueInterfaceName()
-		throws StandardException
-	{
-		return value.getTypeCompiler().interfaceName();
-	}
-
-	///////////////////////////////////////////////////////////////////////
-	//
-	//	OTHER VALUE NODE METHODS
-	//
-	///////////////////////////////////////////////////////////////////////
-
-
-	/**
-	 * Get the SQL ValueNode that is being converted to a JavaValueNode
-	 *
-	 * @return	The underlying SQL ValueNode
-	 */
-	ValueNode getSQLValueNode()
-	{
-		return value;
-	}
-
-	/** @see ValueNode#getConstantValueAsObject 
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	Object getConstantValueAsObject()
-		throws StandardException
-	{
-		return value.getConstantValueAsObject();
-	}
-
-	/**
-	 * Accept a visitor, and call v.visit()
-	 * on child nodes as necessary.  
-	 * 
-	 * @param v the visitor
-	 *
-	 * @exception StandardException on error
-	 */
-	public Visitable accept(Visitor v) 
-		throws StandardException
-	{
-		Visitable returnNode = v.visit(this);
-	
-		if (v.skipChildren(this))
-		{
-			return returnNode;
-		}
-
-		if (value != null && !v.stopTraversal())
-		{
-			value = (ValueNode)value.accept(v);
-		}
-
-		return returnNode;
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package	org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.services.compiler.MethodBuilder;
+import org.apache.derby.iapi.services.compiler.LocalField;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+import org.apache.derby.iapi.types.JSQLType;
+
+import org.apache.derby.iapi.types.DataValueDescriptor;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+
+import org.apache.derby.iapi.sql.compile.TypeCompiler;
+
+import org.apache.derby.iapi.sql.Activation;
+
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
+import org.apache.derby.iapi.sql.compile.Visitable;
+import org.apache.derby.iapi.sql.compile.Visitor;
+
+import org.apache.derby.iapi.reference.ClassName;
+
+import org.apache.derby.iapi.util.JBitSet;
+import org.apache.derby.iapi.services.classfile.VMOpcode;
+
+import java.lang.reflect.Modifier;
+
+import java.util.Vector;
+
+/**
+ * This node type converts a value in the SQL domain to a value in the Java
+ * domain.
+ */
+
+public class SQLToJavaValueNode extends JavaValueNode
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	ValueNode	value;
+
+	LocalField	returnsNullOnNullState;
+
+	/**
+	 * Constructor for a SQLToJavaValueNode
+	 *
+	 * @param value		A ValueNode representing a SQL value to convert to
+	 *					the Java domain.
+	 */
+
+	public void init(Object value)
+	{
+		this.value = (ValueNode) value;
+	}
+
+	/**
+	 * Prints the sub-nodes of this object.  See QueryTreeNode.java for
+	 * how tree printing is supposed to work.
+	 *
+	 * @param depth		The depth of this node in the tree
+	 *
+	 * @return	Nothing
+	 */
+
+	public void printSubNodes(int depth)
+	{
+		if (SanityManager.DEBUG)
+		{
+			int	parm;
+
+			super.printSubNodes(depth);
+			if (value != null)
+			{
+				printLabel(depth, "value: ");
+				value.treePrint(depth + 1);
+			}
+		}
+	}
+
+	/**
+	  *	Returns the name of the java class type that this node coerces to.
+	  *
+	  *	@return	name of java class type
+	  *
+	  */
+	public String getJavaTypeName()
+	{
+		JSQLType	myType = getJSQLType();
+
+		if ( myType == null ) { return ""; }
+		else { return	mapToTypeID( myType ).getCorrespondingJavaTypeName(); }
+	}
+
+	/**
+	  *	Returns the name of the java primitive type that this node coerces to.
+	  *
+	  *	@return	name of java primitive type
+	  *
+	  * @exception StandardException		Thrown on error
+	  */
+	public String getPrimitiveTypeName()
+		throws StandardException
+	{
+		JSQLType	myType = getJSQLType();
+
+		if ( myType == null )
+		{
+			return "";
+		}
+		else
+		{
+			return
+				getTypeCompiler(mapToTypeID( myType )).
+										getCorrespondingPrimitiveTypeName();
+		}
+	}
+
+	/**
+	  *	Get the JSQLType that corresponds to this node. Could be a SQLTYPE,
+	  *	a Java primitive, or a Java class.
+	  *
+	  *	Overrides method in JavaValueNode.
+	  *
+	  *	@return	the corresponding JSQLType
+	  *
+	  */
+	public	JSQLType	getJSQLType
+	(
+    )
+	{
+		if ( jsqlType == null )
+		{
+			if ( value.isParameterNode() ) 
+			{
+				jsqlType = ((ParameterNode) value).getJSQLType();
+			}
+			else
+			{
+				DataTypeDescriptor dtd = value.getTypeServices();
+				if (dtd != null)
+					jsqlType = new JSQLType( dtd );
+			}
+		}
+
+		return jsqlType;
+	}
+
+
+	/**
+	 * Set the clause that this node appears in.
+	 *
+	 * @param clause	The clause that this node appears in.
+	 *
+	 * @return Nothing.
+	 */
+	public void setClause(int clause)
+	{
+		super.setClause(clause);
+		value.setClause(clause);
+	}
+
+	/**
+	 * Bind this expression.  This means binding the sub-expressions,
+	 * as well as figuring out what the return type is for this expression.
+	 *
+	 * @param fromList		The FROM list for the query this
+	 *				expression is in, for binding columns.
+	 * @param subqueryList		The subquery list being built as we find
+	 *							SubqueryNodes
+	 * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
+	 *
+	 * @return this	
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public JavaValueNode bindExpression(
+		FromList fromList, SubqueryList subqueryList,
+		Vector	aggregateVector) 
+			throws StandardException
+	{
+		/* Bind the expression under us */
+		value = value.bindExpression(fromList, subqueryList,
+							  aggregateVector);
+
+		return this;
+	}
+
+	/**
+	 * Remap all ColumnReferences in this tree to be clones of the
+	 * underlying expression.
+	 *
+	 * @return JavaValueNode			The remapped expression tree.
+	 *
+	 * @exception StandardException			Thrown on error
+	 */
+	public JavaValueNode remapColumnReferencesToExpressions()
+		throws StandardException
+	{
+		value = value.remapColumnReferencesToExpressions();
+		return this;
+	}
+
+	/**
+	 * Categorize this predicate.  Initially, this means
+	 * building a bit map of the referenced tables for each predicate.
+	 * If the source of this ColumnReference (at the next underlying level) 
+	 * is not a ColumnReference or a VirtualColumnNode then this predicate
+	 * will not be pushed down.
+	 *
+	 * For example, in:
+	 *		select * from (select 1 from s) a (x) where x = 1
+	 * we will not push down x = 1.
+	 * NOTE: It would be easy to handle the case of a constant, but if the
+	 * inner SELECT returns an arbitrary expression, then we would have to copy
+	 * that tree into the pushed predicate, and that tree could contain
+	 * subqueries and method calls.
+	 * RESOLVE - revisit this issue once we have views.
+	 *
+	 * @param referencedTabs	JBitSet with bit map of referenced FromTables
+	 * @param simplePredsOnly	Whether or not to consider method
+	 *							calls, field references and conditional nodes
+	 *							when building bit map
+	 *
+	 * @return boolean		Whether or not source.expression is a ColumnReference
+	 *						or a VirtualColumnNode.
+	 *
+	 * @exception StandardException			Thrown on error
+	 */
+	public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly)
+		throws StandardException
+	{
+		return value.categorize(referencedTabs, simplePredsOnly);
+	}
+
+	/**
+	 * Preprocess an expression tree.  We do a number of transformations
+	 * here (including subqueries, IN lists, LIKE and BETWEEN) plus
+	 * subquery flattening.
+	 * NOTE: This is done before the outer ResultSetNode is preprocessed.
+	 *
+	 * @param	numTables			Number of tables in the DML Statement
+	 * @param	outerFromList		FromList from outer query block
+	 * @param	outerSubqueryList	SubqueryList from outer query block
+	 * @param	outerPredicateList	PredicateList from outer query block
+	 *
+	 * @return	Nothing.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public void preprocess(int numTables,
+							FromList outerFromList,
+							SubqueryList outerSubqueryList,
+							PredicateList outerPredicateList) 
+							throws StandardException
+	{
+		value.preprocess(numTables,
+						 outerFromList, outerSubqueryList,
+						 outerPredicateList);
+	}
+
+	/**
+	 * Return the variant type for the underlying expression.
+	 * The variant type can be:
+	 *		VARIANT				- variant within a scan
+	 *							  (method calls and non-static field access)
+	 *		SCAN_INVARIANT		- invariant within a scan
+	 *							  (column references from outer tables)
+	 *		QUERY_INVARIANT		- invariant within the life of a query
+	 *							  (constant expressions)
+	 *
+	 * @return	The variant type for the underlying expression.
+	 * @exception StandardException	thrown on error
+	 */
+	protected int getOrderableVariantType() throws StandardException
+	{
+		return value.getOrderableVariantType();
+	}
+
+	///////////////////////////////////////////////////////////////////////
+	//
+	//	CODE GENERATION METHODS
+	//
+	///////////////////////////////////////////////////////////////////////
+
+
+	/**
+	 * Generate code to get the Java value out of a SQL value.
+	 *
+	 * Every SQL type has a corresponding Java type.  The getObject() method
+	 * on the SQL type gets the right Java type.
+	 *
+	 * The generated code will be:
+	 *
+	 * (<Java type name>) ((DataValueDescriptor)
+	 *								<generated value>.getObject())
+	 *
+	 * where <Java type name> comes from the getCorrespondingJavaTypeName()
+	 * method of the value's TypeId.
+	 *
+	 * @param acb	The ExpressionClassBuilder for the class being built
+	 * @param mb	The method the expression will go into
+	 *
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public void generateExpression(ExpressionClassBuilder acb,
+											MethodBuilder mb)
+									throws StandardException
+	{
+		/* Compile the expression under us */
+		generateSQLValue( acb, mb );
+
+		/* now cast the SQLValue to a Java value */
+		generateJavaValue( acb, mb);
+	}
+
+	/**
+	 * Generate the SQLvalue that this node wraps.
+	 *
+	 * @param acb	The ExpressionClassBuilder for the class being built
+	 * @param mb	The method the expression will go into
+	 *
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public void generateSQLValue(ExpressionClassBuilder acb,
+											MethodBuilder mb)
+									throws StandardException
+	{
+		value.generateExpression(acb, mb);
+	}
+
+	/**
+	 * Generate code to cast the SQLValue to a Java value.
+	 *
+	 *
+	 * @param acb	The ExpressionClassBuilder for the class being built
+	 * @param mb	The method the expression will go into
+	 * @param SQLValue	An Expression holding the SQLValue.
+	 *
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public void generateJavaValue
+	(
+		ExpressionClassBuilder	acb,
+		MethodBuilder mbex
+    )
+		throws StandardException
+	{
+		/* If this is a conversion to a primitive type, then call the
+		 * appropriate method for getting the primitive value and
+		 * cast it to the primitive type. 
+		 * NOTE: We first call Activation.nullToPrimitiveTest(),
+		 * which will throw a StandardException if the value is null
+		 */
+		if ( isPrimitiveType() || mustCastToPrimitive() )
+		{
+			String		primitiveTN = value.getTypeCompiler().getCorrespondingPrimitiveTypeName();
+
+			/* Put the code to check if the object is null and to
+			 * get the primitive value in a method call.  This is
+			 * necessary because we are generating an expression here and
+			 * cannot have multiple statements.
+			 * The method call will take SQLValue as a parameter.
+			 */
+			String[] pd = new String[1];
+			pd[0] = getSQLValueInterfaceName(); // parameter "param1"
+
+			MethodBuilder	mb = acb.newGeneratedFun(primitiveTN, Modifier.PRIVATE, pd);
+
+			mb.getParameter(0);
+
+			if (returnsNullOnNullState != null)
+			{
+				generateReturnsNullOnNullCheck(mb);
+			}
+			else
+			{
+				mb.dup();
+				mb.upCast(ClassName.DataValueDescriptor);
+				mb.push(primitiveTN); 
+				mb.callMethod(VMOpcode.INVOKESTATIC, ClassName.BaseActivation, "nullToPrimitiveTest", "void", 2);
+			}
+
+			// stack is dvd
+
+			/* Generate the code to get the primitive value */
+			mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.DataValueDescriptor,
+								value.getTypeCompiler().getPrimitiveMethodName(), primitiveTN, 0);
+
+			mb.methodReturn();
+			mb.complete();
+
+			/* Generate the call to the new method, with the parameter */
+
+			mbex.pushThis();
+			mbex.swap(); // caller pushed out parameter
+			mbex.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, mb.getName(), primitiveTN, 1);
+		}
+		else
+		{
+			if (returnsNullOnNullState != null)
+				generateReturnsNullOnNullCheck(mbex);
+
+			/* Call getObject() to get the right type of Java value */
+			mbex.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.DataValueDescriptor, "getObject",
+										"java.lang.Object", 0);
+
+			mbex.cast(value.getTypeId().getCorrespondingJavaTypeName());
+		}
+	}
+
+	/**
+		Generate the code for the returns Null on Null input check..
+		Stack must contain the DataDescriptorValue.
+	*/
+
+	private void generateReturnsNullOnNullCheck(MethodBuilder mb)
+	{
+		mb.dup();
+		mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Storable,
+								"isNull", "boolean", 0);
+
+		mb.conditionalIf();
+		  mb.push(true);
+		mb.startElseCode();
+		  mb.getField(returnsNullOnNullState);
+		mb.completeConditional();
+		
+		mb.putField(returnsNullOnNullState);
+		mb.endStatement();
+	}
+
+
+	/**
+	  *	Get the type name of the SQLValue we generate.
+	  *
+	  *	@return	name of interface corresponding to SQLValue
+	  *
+	  *
+	  * @exception StandardException		Thrown on error
+	  */
+	public	String	getSQLValueInterfaceName()
+		throws StandardException
+	{
+		return value.getTypeCompiler().interfaceName();
+	}
+
+	///////////////////////////////////////////////////////////////////////
+	//
+	//	OTHER VALUE NODE METHODS
+	//
+	///////////////////////////////////////////////////////////////////////
+
+
+	/**
+	 * Get the SQL ValueNode that is being converted to a JavaValueNode
+	 *
+	 * @return	The underlying SQL ValueNode
+	 */
+	ValueNode getSQLValueNode()
+	{
+		return value;
+	}
+
+	/** @see ValueNode#getConstantValueAsObject 
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	Object getConstantValueAsObject()
+		throws StandardException
+	{
+		return value.getConstantValueAsObject();
+	}
+
+	/**
+	 * Accept a visitor, and call v.visit()
+	 * on child nodes as necessary.  
+	 * 
+	 * @param v the visitor
+	 *
+	 * @exception StandardException on error
+	 */
+	public Visitable accept(Visitor v) 
+		throws StandardException
+	{
+		Visitable returnNode = v.visit(this);
+	
+		if (v.skipChildren(this))
+		{
+			return returnNode;
+		}
+
+		if (value != null && !v.stopTraversal())
+		{
+			value = (ValueNode)value.accept(v);
+		}
+
+		return returnNode;
+	}
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StatementNode.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StatementNode.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StatementNode.java	Fri Sep 24 10:33:20 2004
@@ -1,265 +1,265 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package	org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.services.context.ContextManager;
-
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.sql.compile.CompilerContext;
-
-import org.apache.derby.impl.sql.compile.ActivationClassBuilder;
-import org.apache.derby.iapi.sql.dictionary.DataDictionary;
-import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
-import org.apache.derby.iapi.store.access.ConglomerateController;
-import org.apache.derby.iapi.store.access.TransactionController;
-
-import org.apache.derby.iapi.services.compiler.MethodBuilder;
-
-import org.apache.derby.iapi.reference.SQLState;
-import org.apache.derby.iapi.reference.ClassName;
-import org.apache.derby.iapi.services.loader.GeneratedClass;
-
-import org.apache.derby.iapi.util.ByteArray;
-import org.apache.derby.iapi.services.classfile.VMOpcode;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-import java.lang.reflect.Modifier;
-
-/**
- * A StatementNode represents a single statement in the language.  It is
- * the top node for any statement.
- * <p>
- * StatementNode controls the class generation for query tree nodes.
- *
- * @author Jeff Lichtman
- */
-
-/*
-* History:
-*	5/8/97	Rick Hilleags	Moved node-name-string to child classes.
-*/
-
-public abstract class StatementNode extends QueryTreeNode
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-
-	/**
-	 * By default, assume StatementNodes are atomic.
-	 * The rare statements that aren't atomic (e.g.
-	 * CALL method()) override this.
-	 *
-	 * @return true if the statement is atomic
-	 *
-	 * @exception StandardException		Thrown on error
-	 */	
-	public boolean isAtomic() throws StandardException
-	{
-		return true;
-	}
-
-	/**
-	 * Convert this object to a String.  See comments in QueryTreeNode.java
-	 * for how this should be done for tree printing.
-	 *
-	 * @return	This object as a String
-	 */
-
-	public String toString()
-	{
-		if (SanityManager.DEBUG)
-		{
-			return "statementType: " + statementToString() + "\n" +
-				super.toString();
-		}
-		else
-		{
-			return "";
-		}
-	}
-
-	public abstract String statementToString();
-
-	/**
-	 * create the outer shell class builder for the class we will
-	 * be generating, generate the expression to stuff in it,
-	 * and turn it into a class.
-	 */
-	static final int NEED_DDL_ACTIVATION = 5;
-	static final int NEED_CURSOR_ACTIVATION = 4;
-	static final int NEED_PARAM_ACTIVATION = 2;
-	static final int NEED_ROW_ACTIVATION = 1;
-	static final int NEED_NOTHING_ACTIVATION = 0;
-
-	abstract int activationKind();
-
-	/* We need to get some kind of table lock (IX here) at the beginning of
-	 * compilation of DMLModStatementNode and DDLStatementNode, to prevent the
-	 * interference of insert/update/delete/DDL compilation and DDL execution,
-	 * see beetle 3976, 4343, and $WS/language/SolutionsToConcurrencyIssues.txt
-	 */
-	protected TableDescriptor lockTableForCompilation(TableDescriptor td)
-		throws StandardException
-	{
-		DataDictionary dd = getDataDictionary();
-
-		/* we need to lock only if the data dictionary is in DDL cache mode
-		 */
-		if (dd.getCacheMode() == DataDictionary.DDL_MODE)
-		{
-			ConglomerateController  heapCC;
-			TransactionController tc =
-				getLanguageConnectionContext().getTransactionCompile();
-
-			heapCC = tc.openConglomerate(td.getHeapConglomerateId(),
-                                    false,
-									TransactionController.OPENMODE_FORUPDATE |
-									TransactionController.OPENMODE_FOR_LOCK_ONLY,
-									TransactionController.MODE_RECORD,
-									TransactionController.ISOLATION_SERIALIZABLE);
-			heapCC.close();
-			/*
-			** Need to get TableDescriptor again after getting the lock, in
-			** case for example, a concurrent add column thread commits
-			** while we are binding.
-			*/
-			String tableName = td.getName();
-			td = getTableDescriptor(td.getName(), getSchemaDescriptor(td.getSchemaName()));
-			if (td == null)
-			{
-				throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, tableName);
-			}
-		}
-		return td;
-	}
-
-
-	/**
-	 * Do code generation for this statement.
-	 *
-	 * @param	the generated byte code for this statement.
-	 *			if non-null, then the byte code is saved
-	 *			here.
-	 *
-	 * @return		A GeneratedClass for this statement
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public GeneratedClass generate(ByteArray byteCode) throws StandardException
-	{
-		// start the new activation class.
-		// it starts with the Execute method
-		// and the appropriate superclass (based on
-		// statement type, from inspecting the queryTree).
-
-		int nodeChoice = activationKind();
-
-		/* RESOLVE: Activation hierarchy was way too complicated
-		 * and added no value.  Simple thing to do was to simply
-		 * leave calling code alone and to handle here and to
-		 * eliminate unnecessary classes.
-		 */
-		String superClass;
-		switch (nodeChoice)
-		{
-		case NEED_CURSOR_ACTIVATION:
-			superClass = ClassName.CursorActivation;
-			break;
-		case NEED_DDL_ACTIVATION:
-			return getClassFactory().loadGeneratedClass(
-				"org.apache.derby.impl.sql.execute.ConstantActionActivation", null);
-
-		case NEED_NOTHING_ACTIVATION :
-		case NEED_ROW_ACTIVATION :
-		case NEED_PARAM_ACTIVATION :
-			superClass = ClassName.BaseActivation;
-			break;
-		default :
-			throw StandardException.newException(SQLState.LANG_UNAVAILABLE_ACTIVATION_NEED,
-					String.valueOf(nodeChoice));
-		}
-
-		ActivationClassBuilder generatingClass = new ActivationClassBuilder(
-										superClass, 
-										getCompilerContext());
-		MethodBuilder executeMethod = generatingClass.getExecuteMethod();
-
-
-		/*
-		** the resultSet variable is cached.
-		**
-		** 	resultSet = (resultSet == null) ? ... : resultSet
-		*/
-
-		executeMethod.pushThis();
-		executeMethod.getField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet);
-		executeMethod.conditionalIfNull();
-
-			/* We should generate the result set here.  However, the generated
-			 * code size may be too big to fit in a conditional statement for
-			 * Java compiler to handle (it has a jump/branch step limit).  For
-			 * example, a extremely huge insert is issued with many many rows
-			 * (beetle 4293).  We fork a worker method here to get the
-			 * generated result set, pass our parameter to it and call it.
-			 */
-			MethodBuilder mbWorker = generatingClass.getClassBuilder().newMethodBuilder(
-														Modifier.PROTECTED,
-														ClassName.ResultSet,
-														"fillResultSet");
-			mbWorker.addThrownException(ClassName.StandardException);
-
-			// we expect to get back an expression that will give a resultSet
-			// the nodes use the generatingClass: they add expression functions
-			// to it, and then use those functions in their expressions.
-			generate(generatingClass, mbWorker);
-
-			mbWorker.methodReturn();
-			mbWorker.complete();
-			executeMethod.pushThis();
-			executeMethod.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null,
-									 "fillResultSet", ClassName.ResultSet, 0);
-
-		executeMethod.startElseCode(); // this is here as the compiler only supports ? :
-			executeMethod.pushThis();
-			executeMethod.getField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet);
-		executeMethod.completeConditional();
-
-		executeMethod.pushThis();
-		executeMethod.swap();
-		executeMethod.putField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet);
-
-		executeMethod.endStatement();
-
-   		// wrap up the activation class definition
-		// generate on the tree gave us back the newExpr
-		// for getting a result set on the tree.
-		// we put it in a return statement and stuff
-		// it in the execute method of the activation.
-		// The generated statement is the expression:
-		// the activation class builder takes care of constructing it
-		// for us, given the resultSetExpr to use.
-		//   return (this.resultSet = #resultSetExpr);
-		generatingClass.finishExecuteMethod(this instanceof CursorNode);
-
-		// wrap up the constructor by putting a return at the end of it
-		generatingClass.finishConstructor();
-
-		// cook the completed class into a real class
-		// and stuff it into activationClass
-		GeneratedClass activationClass = generatingClass.getGeneratedClass(byteCode);
-
-		return activationClass;
-	 }
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package	org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.services.context.ContextManager;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.sql.compile.CompilerContext;
+
+import org.apache.derby.impl.sql.compile.ActivationClassBuilder;
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
+import org.apache.derby.iapi.store.access.ConglomerateController;
+import org.apache.derby.iapi.store.access.TransactionController;
+
+import org.apache.derby.iapi.services.compiler.MethodBuilder;
+
+import org.apache.derby.iapi.reference.SQLState;
+import org.apache.derby.iapi.reference.ClassName;
+import org.apache.derby.iapi.services.loader.GeneratedClass;
+
+import org.apache.derby.iapi.util.ByteArray;
+import org.apache.derby.iapi.services.classfile.VMOpcode;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * A StatementNode represents a single statement in the language.  It is
+ * the top node for any statement.
+ * <p>
+ * StatementNode controls the class generation for query tree nodes.
+ *
+ * @author Jeff Lichtman
+ */
+
+/*
+* History:
+*	5/8/97	Rick Hilleags	Moved node-name-string to child classes.
+*/
+
+public abstract class StatementNode extends QueryTreeNode
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+
+	/**
+	 * By default, assume StatementNodes are atomic.
+	 * The rare statements that aren't atomic (e.g.
+	 * CALL method()) override this.
+	 *
+	 * @return true if the statement is atomic
+	 *
+	 * @exception StandardException		Thrown on error
+	 */	
+	public boolean isAtomic() throws StandardException
+	{
+		return true;
+	}
+
+	/**
+	 * Convert this object to a String.  See comments in QueryTreeNode.java
+	 * for how this should be done for tree printing.
+	 *
+	 * @return	This object as a String
+	 */
+
+	public String toString()
+	{
+		if (SanityManager.DEBUG)
+		{
+			return "statementType: " + statementToString() + "\n" +
+				super.toString();
+		}
+		else
+		{
+			return "";
+		}
+	}
+
+	public abstract String statementToString();
+
+	/**
+	 * create the outer shell class builder for the class we will
+	 * be generating, generate the expression to stuff in it,
+	 * and turn it into a class.
+	 */
+	static final int NEED_DDL_ACTIVATION = 5;
+	static final int NEED_CURSOR_ACTIVATION = 4;
+	static final int NEED_PARAM_ACTIVATION = 2;
+	static final int NEED_ROW_ACTIVATION = 1;
+	static final int NEED_NOTHING_ACTIVATION = 0;
+
+	abstract int activationKind();
+
+	/* We need to get some kind of table lock (IX here) at the beginning of
+	 * compilation of DMLModStatementNode and DDLStatementNode, to prevent the
+	 * interference of insert/update/delete/DDL compilation and DDL execution,
+	 * see beetle 3976, 4343, and $WS/language/SolutionsToConcurrencyIssues.txt
+	 */
+	protected TableDescriptor lockTableForCompilation(TableDescriptor td)
+		throws StandardException
+	{
+		DataDictionary dd = getDataDictionary();
+
+		/* we need to lock only if the data dictionary is in DDL cache mode
+		 */
+		if (dd.getCacheMode() == DataDictionary.DDL_MODE)
+		{
+			ConglomerateController  heapCC;
+			TransactionController tc =
+				getLanguageConnectionContext().getTransactionCompile();
+
+			heapCC = tc.openConglomerate(td.getHeapConglomerateId(),
+                                    false,
+									TransactionController.OPENMODE_FORUPDATE |
+									TransactionController.OPENMODE_FOR_LOCK_ONLY,
+									TransactionController.MODE_RECORD,
+									TransactionController.ISOLATION_SERIALIZABLE);
+			heapCC.close();
+			/*
+			** Need to get TableDescriptor again after getting the lock, in
+			** case for example, a concurrent add column thread commits
+			** while we are binding.
+			*/
+			String tableName = td.getName();
+			td = getTableDescriptor(td.getName(), getSchemaDescriptor(td.getSchemaName()));
+			if (td == null)
+			{
+				throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, tableName);
+			}
+		}
+		return td;
+	}
+
+
+	/**
+	 * Do code generation for this statement.
+	 *
+	 * @param	the generated byte code for this statement.
+	 *			if non-null, then the byte code is saved
+	 *			here.
+	 *
+	 * @return		A GeneratedClass for this statement
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public GeneratedClass generate(ByteArray byteCode) throws StandardException
+	{
+		// start the new activation class.
+		// it starts with the Execute method
+		// and the appropriate superclass (based on
+		// statement type, from inspecting the queryTree).
+
+		int nodeChoice = activationKind();
+
+		/* RESOLVE: Activation hierarchy was way too complicated
+		 * and added no value.  Simple thing to do was to simply
+		 * leave calling code alone and to handle here and to
+		 * eliminate unnecessary classes.
+		 */
+		String superClass;
+		switch (nodeChoice)
+		{
+		case NEED_CURSOR_ACTIVATION:
+			superClass = ClassName.CursorActivation;
+			break;
+		case NEED_DDL_ACTIVATION:
+			return getClassFactory().loadGeneratedClass(
+				"org.apache.derby.impl.sql.execute.ConstantActionActivation", null);
+
+		case NEED_NOTHING_ACTIVATION :
+		case NEED_ROW_ACTIVATION :
+		case NEED_PARAM_ACTIVATION :
+			superClass = ClassName.BaseActivation;
+			break;
+		default :
+			throw StandardException.newException(SQLState.LANG_UNAVAILABLE_ACTIVATION_NEED,
+					String.valueOf(nodeChoice));
+		}
+
+		ActivationClassBuilder generatingClass = new ActivationClassBuilder(
+										superClass, 
+										getCompilerContext());
+		MethodBuilder executeMethod = generatingClass.getExecuteMethod();
+
+
+		/*
+		** the resultSet variable is cached.
+		**
+		** 	resultSet = (resultSet == null) ? ... : resultSet
+		*/
+
+		executeMethod.pushThis();
+		executeMethod.getField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet);
+		executeMethod.conditionalIfNull();
+
+			/* We should generate the result set here.  However, the generated
+			 * code size may be too big to fit in a conditional statement for
+			 * Java compiler to handle (it has a jump/branch step limit).  For
+			 * example, a extremely huge insert is issued with many many rows
+			 * (beetle 4293).  We fork a worker method here to get the
+			 * generated result set, pass our parameter to it and call it.
+			 */
+			MethodBuilder mbWorker = generatingClass.getClassBuilder().newMethodBuilder(
+														Modifier.PROTECTED,
+														ClassName.ResultSet,
+														"fillResultSet");
+			mbWorker.addThrownException(ClassName.StandardException);
+
+			// we expect to get back an expression that will give a resultSet
+			// the nodes use the generatingClass: they add expression functions
+			// to it, and then use those functions in their expressions.
+			generate(generatingClass, mbWorker);
+
+			mbWorker.methodReturn();
+			mbWorker.complete();
+			executeMethod.pushThis();
+			executeMethod.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null,
+									 "fillResultSet", ClassName.ResultSet, 0);
+
+		executeMethod.startElseCode(); // this is here as the compiler only supports ? :
+			executeMethod.pushThis();
+			executeMethod.getField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet);
+		executeMethod.completeConditional();
+
+		executeMethod.pushThis();
+		executeMethod.swap();
+		executeMethod.putField(ClassName.BaseActivation, "resultSet", ClassName.ResultSet);
+
+		executeMethod.endStatement();
+
+   		// wrap up the activation class definition
+		// generate on the tree gave us back the newExpr
+		// for getting a result set on the tree.
+		// we put it in a return statement and stuff
+		// it in the execute method of the activation.
+		// The generated statement is the expression:
+		// the activation class builder takes care of constructing it
+		// for us, given the resultSetExpr to use.
+		//   return (this.resultSet = #resultSetExpr);
+		generatingClass.finishExecuteMethod(this instanceof CursorNode);
+
+		// wrap up the constructor by putting a return at the end of it
+		generatingClass.finishConstructor();
+
+		// cook the completed class into a real class
+		// and stuff it into activationClass
+		GeneratedClass activationClass = generatingClass.getGeneratedClass(byteCode);
+
+		return activationClass;
+	 }
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticClassFieldReferenceNode.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticClassFieldReferenceNode.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticClassFieldReferenceNode.java	Fri Sep 24 10:33:20 2004
@@ -1,238 +1,238 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package	org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.services.monitor.Monitor;
-
-import org.apache.derby.iapi.services.compiler.MethodBuilder;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.sql.dictionary.DataDictionary;
-import org.apache.derby.iapi.reference.SQLState;
-
-import org.apache.derby.iapi.services.loader.ClassInspector;
-
-import org.apache.derby.iapi.store.access.Qualifier;
-
-import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
-import org.apache.derby.iapi.sql.compile.CompilerContext;
-
-import org.apache.derby.iapi.util.JBitSet;
-
-import java.lang.reflect.Member;
-import java.lang.reflect.Modifier;
-
-import java.util.Vector;
-
-/**
- * A StaticClassFieldReferenceNode represents a Java static field reference from 
- * a Class (as opposed to an Object).  Field references can be 
- * made in DML (as expressions).
- *
- * @author Jerry Brenner
- */
-
-public final class StaticClassFieldReferenceNode extends JavaValueNode
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	/*
-	** Name of the field.
-	*/
-	private String	fieldName;
-
-	/* The class name */
-	private String	javaClassName;
-	private boolean classNameDelimitedIdentifier;
-
-	/**
-		The field we are going to access.
-	*/
-	private Member			field;
-
-	/**
-	 * Initializer for a StaticClassFieldReferenceNode
-	 *
-	 * @param	javaClassName	The class name
-	 * @param	fieldName		The field name
-	 */
-	public void init(Object javaClassName, Object fieldName, Object classNameDelimitedIdentifier)
-	{
-		this.fieldName = (String) fieldName;
-		this.javaClassName = (String) javaClassName;
-		this.classNameDelimitedIdentifier = ((Boolean) classNameDelimitedIdentifier).booleanValue();
-	}
-
-	/**
-	 * Bind this expression.  This means binding the sub-expressions,
-	 * as well as figuring out what the return type is for this expression.
-	 *
-	 * @param fromList		The FROM list for the query this
-	 *				expression is in, for binding columns.
-	 * @param subqueryList		The subquery list being built as we find SubqueryNodes
-	 * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
-	 *
-	 * @return	Nothing
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public JavaValueNode bindExpression(FromList fromList, SubqueryList subqueryList,
-		Vector aggregateVector) 
-			throws StandardException
-	{
-		ClassInspector classInspector = getClassFactory().getClassInspector();
-
-
-		if (((getCompilerContext().getReliability() & CompilerContext.INTERNAL_SQL_ILLEGAL) != 0)
-			|| !javaClassName.startsWith("java.sql.")) {
-
-			throw StandardException.newException(SQLState.LANG_SYNTAX_ERROR, javaClassName + "::" + fieldName);
-		}
-
-		javaClassName = verifyClassExist(javaClassName, ! classNameDelimitedIdentifier);
-
-		/*
-		** Find the field that is public.
-		*/
-		field = classInspector.findPublicField(javaClassName,
-										fieldName,
-										true);
-		/* Get the field type */
-	 	setJavaTypeName( classInspector.getType(field) );
-
-		return this;
-
-	}
-
-	/**
-	 * Preprocess an expression tree.  We do a number of transformations
-	 * here (including subqueries, IN lists, LIKE and BETWEEN) plus
-	 * subquery flattening.
-	 * NOTE: This is done before the outer ResultSetNode is preprocessed.
-	 *
-	 * @param	numTables			Number of tables in the DML Statement
-	 * @param	outerFromList		FromList from outer query block
-	 * @param	outerSubqueryList	SubqueryList from outer query block
-	 * @param	outerPredicateList	PredicateList from outer query block
-	 *
-	 * @return	Nothing.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public void preprocess(int numTables,
-							FromList outerFromList,
-							SubqueryList outerSubqueryList,
-							PredicateList outerPredicateList) 
-					throws StandardException
-	{
-	}
-
-	/**
-	 * Categorize this predicate.  Initially, this means
-	 * building a bit map of the referenced tables for each predicate.
-	 * If the source of this ColumnReference (at the next underlying level) 
-	 * is not a ColumnReference or a VirtualColumnNode then this predicate
-	 * will not be pushed down.
-	 *
-	 * For example, in:
-	 *		select * from (select 1 from s) a (x) where x = 1
-	 * we will not push down x = 1.
-	 * NOTE: It would be easy to handle the case of a constant, but if the
-	 * inner SELECT returns an arbitrary expression, then we would have to copy
-	 * that tree into the pushed predicate, and that tree could contain
-	 * subqueries and method calls.
-	 * RESOLVE - revisit this issue once we have views.
-	 *
-	 * @param referencedTabs	JBitSet with bit map of referenced FromTables
-	 * @param simplePredsOnly	Whether or not to consider method
-	 *							calls, field references and conditional nodes
-	 *							when building bit map
-	 *
-	 * @return boolean		Whether or not source.expression is a ColumnReference
-	 *						or a VirtualColumnNode.
-	 */
-	public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly)
-	{
-		return true;
-	}
-
-	/**
-	 * Remap all ColumnReferences in this tree to be clones of the
-	 * underlying expression.
-	 *
-	 * @return JavaValueNode			The remapped expression tree.
-	 *
-	 * @exception StandardException			Thrown on error
-	 */
-	public JavaValueNode remapColumnReferencesToExpressions()
-		throws StandardException
-	{
-		return this;
-	}
-
-	/**
-	 * Return the variant type for the underlying expression.
-	 * The variant type can be:
-	 *		VARIANT				- variant within a scan
-	 *							  (method calls and non-static field access)
-	 *		SCAN_INVARIANT		- invariant within a scan
-	 *							  (column references from outer tables)
-	 *		QUERY_INVARIANT		- invariant within the life of a query
-	 *		CONSTANT			- constant
-	 *
-	 * @return	The variant type for the underlying expression.
-	 */
-	protected int getOrderableVariantType()
-	{
-		if (SanityManager.DEBUG)
-		{
-			SanityManager.ASSERT(field != null,
-					"field is expected to be non-null");
-		}
-		/* Static field references are invariant for the life 
-		 * of the query, non-static are variant.
-		 */
-		if (Modifier.isFinal(field.getModifiers()))
-		{
-			return Qualifier.CONSTANT;
-		}
-		else
-		{
-			return Qualifier.VARIANT;
-		}
-	}
-
-	/**
-	 * @see QueryTreeNode#generate
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public void generateExpression(ExpressionClassBuilder acb,
-											MethodBuilder mb)
-	{
-		/*
-		** Generate the following:
-		**
-		** <javaClassName>.<field name>
-		*/
-
-		mb.getStaticField(field.getDeclaringClass().getName(),
-								 fieldName,
-								 getJavaTypeName());
-	}
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package	org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.services.monitor.Monitor;
+
+import org.apache.derby.iapi.services.compiler.MethodBuilder;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;
+import org.apache.derby.iapi.reference.SQLState;
+
+import org.apache.derby.iapi.services.loader.ClassInspector;
+
+import org.apache.derby.iapi.store.access.Qualifier;
+
+import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
+import org.apache.derby.iapi.sql.compile.CompilerContext;
+
+import org.apache.derby.iapi.util.JBitSet;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Modifier;
+
+import java.util.Vector;
+
+/**
+ * A StaticClassFieldReferenceNode represents a Java static field reference from 
+ * a Class (as opposed to an Object).  Field references can be 
+ * made in DML (as expressions).
+ *
+ * @author Jerry Brenner
+ */
+
+public final class StaticClassFieldReferenceNode extends JavaValueNode
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	/*
+	** Name of the field.
+	*/
+	private String	fieldName;
+
+	/* The class name */
+	private String	javaClassName;
+	private boolean classNameDelimitedIdentifier;
+
+	/**
+		The field we are going to access.
+	*/
+	private Member			field;
+
+	/**
+	 * Initializer for a StaticClassFieldReferenceNode
+	 *
+	 * @param	javaClassName	The class name
+	 * @param	fieldName		The field name
+	 */
+	public void init(Object javaClassName, Object fieldName, Object classNameDelimitedIdentifier)
+	{
+		this.fieldName = (String) fieldName;
+		this.javaClassName = (String) javaClassName;
+		this.classNameDelimitedIdentifier = ((Boolean) classNameDelimitedIdentifier).booleanValue();
+	}
+
+	/**
+	 * Bind this expression.  This means binding the sub-expressions,
+	 * as well as figuring out what the return type is for this expression.
+	 *
+	 * @param fromList		The FROM list for the query this
+	 *				expression is in, for binding columns.
+	 * @param subqueryList		The subquery list being built as we find SubqueryNodes
+	 * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
+	 *
+	 * @return	Nothing
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public JavaValueNode bindExpression(FromList fromList, SubqueryList subqueryList,
+		Vector aggregateVector) 
+			throws StandardException
+	{
+		ClassInspector classInspector = getClassFactory().getClassInspector();
+
+
+		if (((getCompilerContext().getReliability() & CompilerContext.INTERNAL_SQL_ILLEGAL) != 0)
+			|| !javaClassName.startsWith("java.sql.")) {
+
+			throw StandardException.newException(SQLState.LANG_SYNTAX_ERROR, javaClassName + "::" + fieldName);
+		}
+
+		javaClassName = verifyClassExist(javaClassName, ! classNameDelimitedIdentifier);
+
+		/*
+		** Find the field that is public.
+		*/
+		field = classInspector.findPublicField(javaClassName,
+										fieldName,
+										true);
+		/* Get the field type */
+	 	setJavaTypeName( classInspector.getType(field) );
+
+		return this;
+
+	}
+
+	/**
+	 * Preprocess an expression tree.  We do a number of transformations
+	 * here (including subqueries, IN lists, LIKE and BETWEEN) plus
+	 * subquery flattening.
+	 * NOTE: This is done before the outer ResultSetNode is preprocessed.
+	 *
+	 * @param	numTables			Number of tables in the DML Statement
+	 * @param	outerFromList		FromList from outer query block
+	 * @param	outerSubqueryList	SubqueryList from outer query block
+	 * @param	outerPredicateList	PredicateList from outer query block
+	 *
+	 * @return	Nothing.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public void preprocess(int numTables,
+							FromList outerFromList,
+							SubqueryList outerSubqueryList,
+							PredicateList outerPredicateList) 
+					throws StandardException
+	{
+	}
+
+	/**
+	 * Categorize this predicate.  Initially, this means
+	 * building a bit map of the referenced tables for each predicate.
+	 * If the source of this ColumnReference (at the next underlying level) 
+	 * is not a ColumnReference or a VirtualColumnNode then this predicate
+	 * will not be pushed down.
+	 *
+	 * For example, in:
+	 *		select * from (select 1 from s) a (x) where x = 1
+	 * we will not push down x = 1.
+	 * NOTE: It would be easy to handle the case of a constant, but if the
+	 * inner SELECT returns an arbitrary expression, then we would have to copy
+	 * that tree into the pushed predicate, and that tree could contain
+	 * subqueries and method calls.
+	 * RESOLVE - revisit this issue once we have views.
+	 *
+	 * @param referencedTabs	JBitSet with bit map of referenced FromTables
+	 * @param simplePredsOnly	Whether or not to consider method
+	 *							calls, field references and conditional nodes
+	 *							when building bit map
+	 *
+	 * @return boolean		Whether or not source.expression is a ColumnReference
+	 *						or a VirtualColumnNode.
+	 */
+	public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly)
+	{
+		return true;
+	}
+
+	/**
+	 * Remap all ColumnReferences in this tree to be clones of the
+	 * underlying expression.
+	 *
+	 * @return JavaValueNode			The remapped expression tree.
+	 *
+	 * @exception StandardException			Thrown on error
+	 */
+	public JavaValueNode remapColumnReferencesToExpressions()
+		throws StandardException
+	{
+		return this;
+	}
+
+	/**
+	 * Return the variant type for the underlying expression.
+	 * The variant type can be:
+	 *		VARIANT				- variant within a scan
+	 *							  (method calls and non-static field access)
+	 *		SCAN_INVARIANT		- invariant within a scan
+	 *							  (column references from outer tables)
+	 *		QUERY_INVARIANT		- invariant within the life of a query
+	 *		CONSTANT			- constant
+	 *
+	 * @return	The variant type for the underlying expression.
+	 */
+	protected int getOrderableVariantType()
+	{
+		if (SanityManager.DEBUG)
+		{
+			SanityManager.ASSERT(field != null,
+					"field is expected to be non-null");
+		}
+		/* Static field references are invariant for the life 
+		 * of the query, non-static are variant.
+		 */
+		if (Modifier.isFinal(field.getModifiers()))
+		{
+			return Qualifier.CONSTANT;
+		}
+		else
+		{
+			return Qualifier.VARIANT;
+		}
+	}
+
+	/**
+	 * @see QueryTreeNode#generate
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public void generateExpression(ExpressionClassBuilder acb,
+											MethodBuilder mb)
+	{
+		/*
+		** Generate the following:
+		**
+		** <javaClassName>.<field name>
+		*/
+
+		mb.getStaticField(field.getDeclaringClass().getName(),
+								 fieldName,
+								 getJavaTypeName());
+	}
+
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java	Fri Sep 24 10:33:20 2004
@@ -1,1006 +1,1006 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package	org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.services.compiler.MethodBuilder;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-import org.apache.derby.iapi.sql.compile.CompilerContext;
-import org.apache.derby.iapi.sql.compile.TypeCompiler;
-import org.apache.derby.iapi.sql.compile.C_NodeTypes;
-import org.apache.derby.iapi.types.JSQLType;
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-import org.apache.derby.iapi.types.TypeId;
-
-import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
-import org.apache.derby.iapi.sql.dictionary.DataDictionary;
-import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
-
-import org.apache.derby.iapi.reference.ClassName;
-import org.apache.derby.iapi.reference.SQLState;
-import org.apache.derby.iapi.reference.JDBC30Translation;
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
-import org.apache.derby.iapi.services.loader.ClassInspector;
-import org.apache.derby.iapi.services.compiler.LocalField;
-
-import org.apache.derby.iapi.util.JBitSet;
-import org.apache.derby.iapi.services.classfile.VMOpcode;
-
-import org.apache.derby.iapi.sql.conn.Authorizer;
-
-import org.apache.derby.catalog.AliasInfo;
-import org.apache.derby.catalog.TypeDescriptor;
-import org.apache.derby.catalog.types.RoutineAliasInfo;
-import org.apache.derby.impl.sql.compile.ActivationClassBuilder;
-
-import org.apache.derby.catalog.UUID;
-
-import java.util.Vector;
-import java.lang.reflect.Modifier;
-
-/**
- * A StaticMethodCallNode represents a static method call from a Class
- * (as opposed to from an Object).
-
-   For a procedure the call requires that the arguments be ? parameters.
-   The parameter is *logically* passed into the method call a number of different ways.
-
-   <P>
-   For a application call like CALL MYPROC(?) the logically Java method call is
-   (in psuedo Java/SQL code) (examples with CHAR(10) parameter)
-   <BR>
-   Fixed length IN parameters - com.acme.MyProcedureMethod(?)
-   <BR>
-   Variable length IN parameters - com.acme.MyProcedureMethod(CAST (? AS CHAR(10))
-   <BR>
-   Fixed length INOUT parameter -
-		String[] holder = new String[] {?}; com.acme.MyProcedureMethod(holder); ? = holder[0]
-   <BR>
-   Variable length INOUT parameter -
-		String[] holder = new String[] {CAST (? AS CHAR(10)}; com.acme.MyProcedureMethod(holder); ? = CAST (holder[0] AS CHAR(10))
-
-   <BR>
-   Fixed length OUT parameter -
-		String[] holder = new String[1]; com.acme.MyProcedureMethod(holder); ? = holder[0]
-
-   <BR>
-   Variable length INOUT parameter -
-		String[] holder = new String[1]; com.acme.MyProcedureMethod(holder); ? = CAST (holder[0] AS CHAR(10))
-
-
-    <P>
-	For static method calls there is no pre-definition of an IN or INOUT parameter, so a call to CallableStatement.registerOutParameter()
-	makes the parameter an INOUT parameter, provided:
-		- the parameter is passed directly to the method call (no casts or expressions).
-		- the method's parameter type is a Java array type.
-
-    Since this is a dynmaic decision we compile in code to take both paths, based upon a boolean isINOUT which is dervied from the
-	ParameterValueSet. Code is logically (only single parameter String[] shown here). Note, no casts can exist here.
-
-	boolean isINOUT = getParameterValueSet().getParameterMode(0) == PARAMETER_IN_OUT;
-	if (isINOUT) {
-		String[] holder = new String[] {?}; com.acme.MyProcedureMethod(holder); ? = holder[0]
-	   
-	} else {
-		com.acme.MyProcedureMethod(?)
-	}
-
- *
- * @author Jerry Brenner
- */
-public class StaticMethodCallNode extends MethodCallNode
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	private TableName procedureName;
-
-	private LocalField[] outParamArrays;
-	private int[]		 applicationParameterNumbers; 
-
-	private boolean		isSystemCode;
-	private boolean		alreadyBound;
-
-	private LocalField	returnsNullOnNullState;
-
-
-	AliasDescriptor	ad;
-
-
-	/**
-	 * Intializer for a NonStaticMethodCallNode
-	 *
-	 * @param methodName		The name of the method to call
-	 * @param javaClassName		The name of the java class that the static method belongs to.
-	 */
-	public void init(Object methodName, Object javaClassName)
-	{
-		if (methodName instanceof String)
-			init(methodName);
-		else {
-			procedureName = (TableName) methodName;
-			init(procedureName.getTableName());
-		}
-
-		this.javaClassName = (String) javaClassName;
-	}
-
-	/**
-	 * Bind this expression.  This means binding the sub-expressions,
-	 * as well as figuring out what the return type is for this expression.
-	 *
-	 * @param fromList		The FROM list for the query this
-	 *				expression is in, for binding columns.
-	 * @param subqueryList		The subquery list being built as we find SubqueryNodes
-	 * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
-	 *
-	 * @return	this or an AggregateNode
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public JavaValueNode bindExpression(
-		FromList fromList, SubqueryList subqueryList,
-		Vector	aggregateVector) 
-			throws StandardException
-	{
-		// for a function we can get called recursively
-		if (alreadyBound)
-			return this;
-
-
-		bindParameters(fromList, subqueryList, aggregateVector);
-
-		
-		/* If javaClassName is null then we assume that the current methodName
-		 * is an alias and we must go to sysmethods to
-		 * get the real method and java class names for this alias.
-		 */
-		if (javaClassName == null)
-		{
-			CompilerContext cc = getCompilerContext();
-
-			// look for a routine
-			if (ad == null) {
-
-				String schemaName = procedureName != null ?
-									procedureName.getSchemaName() : null;
-
-				SchemaDescriptor sd = getSchemaDescriptor(schemaName, schemaName != null);
-
-
-				if (sd.getUUID() != null) {
-
-				java.util.List list = getDataDictionary().getRoutineList(
-					sd.getUUID().toString(), methodName,
-					forCallStatement ? AliasInfo.ALIAS_NAME_SPACE_PROCEDURE_AS_CHAR : AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR
-					);
-
-				for (int i = list.size() - 1; i >= 0; i--) {
-
-					AliasDescriptor proc = (AliasDescriptor) list.get(i);
-
-					RoutineAliasInfo routineInfo = (RoutineAliasInfo) proc.getAliasInfo();
-					int parameterCount = routineInfo.getParameterCount();
-					if (parameterCount != methodParms.length)
-						continue;
-
-					// pre-form the method signature. If it is a dynamic result set procedure
-					// then we need to add in the ResultSet array
-
-					TypeDescriptor[] parameterTypes = routineInfo.getParameterTypes();
-
-					int sigParameterCount = parameterCount;
-					if (routineInfo.getMaxDynamicResultSets() > 0)
-						sigParameterCount++;
-
-					signature = new JSQLType[sigParameterCount];
-					for (int p = 0; p < parameterCount; p++) {
-
-						// find the declared type.
-
-						TypeDescriptor td = parameterTypes[p];
-
-						TypeId typeId = TypeId.getBuiltInTypeId(td.getJDBCTypeId());
-
-						TypeId parameterTypeId = typeId;
-
-
-						// if it's an OUT or INOUT parameter we need an array.
-						int parameterMode = routineInfo.getParameterModes()[p];
-
-						if (parameterMode != JDBC30Translation.PARAMETER_MODE_IN) {
-
-							String arrayType;
-							switch (typeId.getJDBCTypeId()) {
-								case java.sql.Types.SMALLINT:
-								case java.sql.Types.INTEGER:
-								case java.sql.Types.BIGINT:
-								case java.sql.Types.REAL:
-								case java.sql.Types.DOUBLE:
-									arrayType = getTypeCompiler(typeId).getCorrespondingPrimitiveTypeName().concat("[]");
-									break;
-								default:
-									arrayType = typeId.getCorrespondingJavaTypeName().concat("[]");
-									break;
-							}
-
-							typeId = TypeId.getUserDefinedTypeId(arrayType, false);
-						}
-
-						// this is the type descriptor of the require method parameter
-						DataTypeDescriptor methoddtd = new DataTypeDescriptor(
-								typeId,
-								td.getPrecision(),
-								td.getScale(),
-								td.isNullable(),
-								td.getMaximumWidth()
-							);
-
-						signature[p] = new JSQLType(methoddtd);
-
-						// check parameter is a ? node for INOUT and OUT parameters.
-
-						ValueNode sqlParamNode = null;
-
-						if (methodParms[p] instanceof SQLToJavaValueNode) {
-							SQLToJavaValueNode sql2j = (SQLToJavaValueNode) methodParms[p];
-							sqlParamNode = sql2j.getSQLValueNode();
-						}
-						else
-						{
-						}
-
-						boolean isParameterMarker = true;
-						if ((sqlParamNode == null) || !sqlParamNode.isParameterNode())
-						{
-							if (parameterMode != JDBC30Translation.PARAMETER_MODE_IN) {
-							 
-								throw StandardException.newException(SQLState.LANG_DB2_PARAMETER_NEEDS_MARKER,
-									RoutineAliasInfo.parameterMode(parameterMode),
-									routineInfo.getParameterNames()[p]);
-							}
-							isParameterMarker = false;
-						}
-						else
-						{
-							if (applicationParameterNumbers == null)
-								applicationParameterNumbers = new int[parameterCount];
-							applicationParameterNumbers[p] = ((ParameterNode) sqlParamNode).getParameterNumber();
-						}
-
-						// this is the SQL type of the procedure parameter.
-						DataTypeDescriptor paramdtd = new DataTypeDescriptor(
-							parameterTypeId,
-							td.getPrecision(),
-							td.getScale(),
-							td.isNullable(),
-							td.getMaximumWidth()
-						);
-
-						boolean needCast = false;
-						if (!isParameterMarker)
-						{
-
-							// can only be an IN parameter.
-							// check that the value can be assigned to the
-							// type of the procedure parameter.
-							if (sqlParamNode instanceof UntypedNullConstantNode)
-							{
-								sqlParamNode.setDescriptor(paramdtd);
-							}
-							else
-							{
-
-
-								DataTypeDescriptor dts;
-								TypeId argumentTypeId;
-
-								if (sqlParamNode != null)
-								{
-									// a node from the SQL world
-									argumentTypeId = sqlParamNode.getTypeId();
-									dts = sqlParamNode.getTypeServices();
-								}
-								else
-								{
-									// a node from the Java world
-									dts = DataTypeDescriptor.getSQLDataTypeDescriptor(methodParms[p].getJavaTypeName());
-									if (dts == null)
-									{
-										throw StandardException.newException(SQLState.LANG_NO_CORRESPONDING_S_Q_L_TYPE, 
-											methodParms[p].getJavaTypeName());
-									}
-
-									argumentTypeId = dts.getTypeId();
-								}
-
-								if (! getTypeCompiler(parameterTypeId).storable(argumentTypeId, getClassFactory()))
-										throw StandardException.newException(SQLState.LANG_NOT_STORABLE, 
-											parameterTypeId.getSQLTypeName(),
-											argumentTypeId.getSQLTypeName() );
-
-								// if it's not an exact length match then some cast will be needed.
-								if (!paramdtd.isExactTypeAndLengthMatch(dts))
-									needCast = true;
-							}
-						}
-						else
-						{
-							// any variable length type will need a cast from the
-							// Java world (the ? parameter) to the SQL type. This
-							// ensures values like CHAR(10) are passed into the procedure
-							// correctly as 10 characters long.
-							if (parameterTypeId.variableLength()) {
-
-								if (parameterMode != JDBC30Translation.PARAMETER_MODE_OUT)
-									needCast = true;
-							}
-						}
-						
-
-						if (needCast)
-						{
-							// push a cast node to ensure the
-							// correct type is passed to the method
-							// this gets tacky because before we knew
-							// it was a procedure call we ensured all the
-							// parameter are JavaNodeTypes. Now we need to
-							// push them back to the SQL domain, cast them
-							// and then push them back to the Java domain.
-
-							if (sqlParamNode == null) {
-
-								sqlParamNode = (ValueNode) getNodeFactory().getNode(
-									C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,
-									methodParms[p], 
-									getContextManager());
-							}
-
-							ValueNode castNode = (ValueNode) getNodeFactory().getNode(
-								C_NodeTypes.CAST_NODE,
-								sqlParamNode, 
-								paramdtd,
-								getContextManager());
-
-
-							methodParms[p] = (JavaValueNode) getNodeFactory().getNode(
-									C_NodeTypes.SQL_TO_JAVA_VALUE_NODE,
-									castNode, 
-									getContextManager());
-
-							methodParms[p] = methodParms[p].bindExpression(fromList, subqueryList, aggregateVector);
-						}
-
-						// only force the type for a ? so that the correct type shows up
-						// in parameter meta data
-						if (isParameterMarker)
-							sqlParamNode.setDescriptor(paramdtd);
-					}
-
-					if (sigParameterCount != parameterCount) {
-
-						TypeId typeId = TypeId.getUserDefinedTypeId("java.sql.ResultSet[]", false);
-
-						DataTypeDescriptor dtd = new DataTypeDescriptor(
-								typeId,
-								0,
-								0,
-								false,
-								-1
-							);
-
-						signature[parameterCount] = new JSQLType(dtd);
-
-					}
-
-					this.routineInfo = routineInfo;
-					ad = proc;
-
-					// If a procedure is in the system schema and defined as executing
-					// SQL do we set we are in system code.
-					if (sd.isSystemSchema() && (routineInfo.getReturnType() == null) && routineInfo.getSQLAllowed() != RoutineAliasInfo.NO_SQL)
-						isSystemCode = true;
-
-					break;
-				}
-			}
-	
-			}
-
-			/* Throw exception if no alias found */
-			if (ad == null)
-			{
-				Object errName;
-				if (procedureName == null)
-					errName = methodName;
-				else
-					errName = procedureName;
-
-				throw StandardException.newException(SQLState.LANG_NO_SUCH_METHOD_ALIAS, errName);
-			}
-	
-
-
-			/* Query is dependent on the AliasDescriptor */
-			cc.createDependency(ad);
-
-
-			methodName = ad.getAliasInfo().getMethodName();
-			javaClassName = ad.getJavaClassName();
-		}
-
-
-		javaClassName = verifyClassExist(javaClassName, true);
-
-		/* Resolve the method call */
-		resolveMethodCall(javaClassName, true);
-
-
-		alreadyBound = true;
-
-		// If this is a function call with a variable length
-		// return type, then we need to push a CAST node.
-		if (routineInfo != null)
-		{
-			TypeDescriptor returnType = routineInfo.getReturnType();
-			if (returnType != null)
-			{
-				TypeId returnTypeId = TypeId.getBuiltInTypeId(returnType.getJDBCTypeId());
-
-				if (returnTypeId.variableLength()) {
-					// Cast the return using a cast node, but have to go
-					// into the SQL domain, and back to the Java domain.
-
-					DataTypeDescriptor returnValueDtd = new DataTypeDescriptor(
-								returnTypeId,
-								returnType.getPrecision(),
-								returnType.getScale(),
-								returnType.isNullable(),
-								returnType.getMaximumWidth()
-							);
-
-
-					ValueNode returnValueToSQL = (ValueNode) getNodeFactory().getNode(
-								C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,
-								this, 
-								getContextManager());
-
-					ValueNode returnValueCastNode = (ValueNode) getNodeFactory().getNode(
-									C_NodeTypes.CAST_NODE,
-									returnValueToSQL, 
-									returnValueDtd,
-									getContextManager());
-
-
-					JavaValueNode returnValueToJava = (JavaValueNode) getNodeFactory().getNode(
-										C_NodeTypes.SQL_TO_JAVA_VALUE_NODE,
-										returnValueCastNode, 
-										getContextManager());
-
-					return returnValueToJava.bindExpression(fromList, subqueryList, aggregateVector);
-				}
-
-			}
-		}
-
-		return this;
-	}
-
-	/**
-		Push extra code to generate the casts within the
-		arrays for the parameters passed as arrays.
-	*/
-	public	void generateOneParameter(ExpressionClassBuilder acb,
-											MethodBuilder mb,
-											int parameterNumber )
-			throws StandardException
-	{
-		int parameterMode;
-
-
-		SQLToJavaValueNode sql2j = null;
-		if (methodParms[parameterNumber] instanceof SQLToJavaValueNode)
-			sql2j = (SQLToJavaValueNode) methodParms[parameterNumber];
-		
-		if (routineInfo != null) {
-			parameterMode = routineInfo.getParameterModes()[parameterNumber];
-		} else {
-			// for a static method call the parameter always starts out as a in parameter, but
-			// may be registered as an IN OUT parameter. For a static method argument to be
-			// a dynmaically registered out parameter it must be a simple ? parameter
-
-			parameterMode = JDBC30Translation.PARAMETER_MODE_IN;
-
-			if (sql2j != null) {
-				if (sql2j.getSQLValueNode().isParameterNode()) {
-
-					// applicationParameterNumbers is only set up for a procedure.
-					int applicationParameterNumber = ((ParameterNode) (sql2j.getSQLValueNode())).getParameterNumber();
-
-					String parameterType = methodParameterTypes[parameterNumber];
-
-					if (parameterType.endsWith("[]")) {
-
-						// constructor  - setting up correct paramter type info
-						MethodBuilder constructor = acb.getConstructor();
-						acb.pushThisAsActivation(constructor);
-						constructor.callMethod(VMOpcode.INVOKEINTERFACE, null,
-											"getParameterValueSet", ClassName.ParameterValueSet, 0);
-
-						constructor.push(applicationParameterNumber);
-						constructor.push(JDBC30Translation.PARAMETER_MODE_UNKNOWN);
-						constructor.callMethod(VMOpcode.INVOKEINTERFACE, null,
-											"setParameterMode", "void", 2);
-						constructor.endStatement();
-					}
-				}
-			} 
-		}
-
-		switch (parameterMode) {
-		case JDBC30Translation.PARAMETER_MODE_IN:
-		case JDBC30Translation.PARAMETER_MODE_IN_OUT:
-		case JDBC30Translation.PARAMETER_MODE_UNKNOWN:
-			if (sql2j != null)
-				sql2j.returnsNullOnNullState = returnsNullOnNullState;
-			super.generateOneParameter(acb, mb, parameterNumber);
-			break;
-
-		case JDBC30Translation.PARAMETER_MODE_OUT:
-			// For an OUT parameter we require nothing to be pushed into the
-			// method call from the parameter node.
-			break;
-		}
-
-		switch (parameterMode) {
-		case JDBC30Translation.PARAMETER_MODE_IN:
-		case JDBC30Translation.PARAMETER_MODE_UNKNOWN:
-			break;
-
-		case JDBC30Translation.PARAMETER_MODE_IN_OUT:
-		case JDBC30Translation.PARAMETER_MODE_OUT:
-		{
-			// Create the array used to pass into the method. We create a
-			// new array for each call as there is a small chance the
-			// application could retain a reference to it and corrupt
-			// future calls with the same CallableStatement object.
-
-			String methodParameterType = methodParameterTypes[parameterNumber];
-			String arrayType = methodParameterType.substring(0, methodParameterType.length() - 2);
-			LocalField lf = acb.newFieldDeclaration(Modifier.PRIVATE, methodParameterType);
-
-			if (outParamArrays == null)
-				outParamArrays = new LocalField[methodParms.length];
-
-			outParamArrays[parameterNumber] = lf;
-
-			mb.pushNewArray(arrayType, 1);
-			mb.putField(lf);
-
-			// set the IN part of the parameter into the INOUT parameter.
-			if (parameterMode != JDBC30Translation.PARAMETER_MODE_OUT) {
-				mb.swap();
-				mb.setArrayElement(0);
-				mb.getField(lf);
-			}
-			break;
-			}
-		}
-
-	}
-
-	/**
-	 * Categorize this predicate.  Initially, this means
-	 * building a bit map of the referenced tables for each predicate.
-	 * If the source of this ColumnReference (at the next underlying level) 
-	 * is not a ColumnReference or a VirtualColumnNode then this predicate
-	 * will not be pushed down.
-	 *
-	 * For example, in:
-	 *		select * from (select 1 from s) a (x) where x = 1
-	 * we will not push down x = 1.
-	 * NOTE: It would be easy to handle the case of a constant, but if the
-	 * inner SELECT returns an arbitrary expression, then we would have to copy
-	 * that tree into the pushed predicate, and that tree could contain
-	 * subqueries and method calls.
-	 * RESOLVE - revisit this issue once we have views.
-	 *
-	 * @param referencedTabs	JBitSet with bit map of referenced FromTables
-	 * @param simplePredsOnly	Whether or not to consider method
-	 *							calls, field references and conditional nodes
-	 *							when building bit map
-	 *
-	 * @return boolean		Whether or not source.expression is a ColumnReference
-	 *						or a VirtualColumnNode.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly)
-		throws StandardException
-	{
-		/* We stop here when only considering simple predicates
-		 *  as we don't consider method calls when looking
-		 * for null invariant predicates.
-		 */
-		if (simplePredsOnly)
-		{
-			return false;
-		}
-
-		boolean pushable = true;
-
-		pushable = pushable && super.categorize(referencedTabs, simplePredsOnly);
-
-		return pushable;
-	}
-
-	/**
-	 * Convert this object to a String.  See comments in QueryTreeNode.java
-	 * for how this should be done for tree printing.
-	 *
-	 * @return	This object as a String
-	 */
-
-	public String toString()
-	{
-		if (SanityManager.DEBUG)
-		{
-			return "javaClassName: " +
-				(javaClassName != null ? javaClassName : "null") + "\n" +
-				super.toString();
-		}
-		else
-		{
-			return "";
-		}
-	}
-
-	/**
-	 * Do code generation for this method call
-	 *
-	 * @param acb	The ExpressionClassBuilder for the class we're generating
-	 * @param mb	The method the expression will go into
-	 *
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public void generateExpression(ExpressionClassBuilder acb,
-											MethodBuilder mb)
-									throws StandardException
-	{
-		if (routineInfo != null) {
-
-			if (!routineInfo.calledOnNullInput() && routineInfo.getParameterCount() != 0)
-				returnsNullOnNullState = acb.newFieldDeclaration(Modifier.PRIVATE, "boolean");
-
-		}
-
-		// reset the parameters are null indicator.
-		if (returnsNullOnNullState != null) {
-			mb.push(false);
-			mb.putField(returnsNullOnNullState);
-			mb.endStatement();
-
-			// for the call to the generated method below.
-			mb.pushThis();
-		}
-
-		int nargs = generateParameters(acb, mb);
-
-		LocalField functionEntrySQLAllowed = null;
-
-		if (routineInfo != null) {
-
-			short sqlAllowed = routineInfo.getSQLAllowed();
-
-			// Before we set up our authorization level, add a check to see if this
-			// method can be called. If the routine is NO SQL or CONTAINS SQL 
-			// then there is no need for a check. As follows:
-			//
-			// Current Level = NO_SQL - CALL will be rejected when getting CALL result set
-			// Current Level = anything else - calls to procedures defined as NO_SQL and CONTAINS SQL both allowed.
-
-
-			if (sqlAllowed != RoutineAliasInfo.NO_SQL)
-			{
-				
-				int sqlOperation;
-				
-				if (sqlAllowed == RoutineAliasInfo.READS_SQL_DATA)
-					sqlOperation = Authorizer.SQL_SELECT_OP;
-				else if (sqlAllowed == RoutineAliasInfo.MODIFIES_SQL_DATA)
-					sqlOperation = Authorizer.SQL_WRITE_OP;
-				else
-					sqlOperation = Authorizer.SQL_ARBITARY_OP;
-				
-				generateAuthorizeCheck((ActivationClassBuilder) acb, mb, sqlOperation);
-			}
-
-			int statmentContextReferences = isSystemCode ? 2 : 1;
-			
-			boolean isFunction = routineInfo.getReturnType() != null;
-
-			if (isFunction)
-				statmentContextReferences++;
-
-
-			if (statmentContextReferences != 0) {
-				acb.pushThisAsActivation(mb);
-				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
-									"getLanguageConnectionContext", ClassName.LanguageConnectionContext, 0);
-				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
-									"getStatementContext", "org.apache.derby.iapi.sql.conn.StatementContext", 0);
-
-				for (int scc = 1; scc < statmentContextReferences; scc++)
-					mb.dup();
-			}
-
-			/**
-				Set the statement context to reflect we are running
-				System procedures, so that we can execute non-standard SQL.
-			*/
-			if (isSystemCode) {
-				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
-									"setSystemCode", "void", 0);
-			}
-
-			// for a function we need to fetch the current SQL control
-			// so that we can reset it once the function is complete.
-			// 
-			if (isFunction)
-			{
-				functionEntrySQLAllowed = acb.newFieldDeclaration(Modifier.PRIVATE, "short");
-				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
-									"getSQLAllowed", "short", 0);
-				mb.putField(functionEntrySQLAllowed);
-				mb.endStatement();
-
-			}
-			
-			
-			// Set up the statement context to reflect the
-			// restricted SQL execution allowed by this routine.
-
-			mb.push(sqlAllowed);
-			mb.push(false);
-			mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
-								"setSQLAllowed", "void", 2);
-
-		}
-
-		// add in the ResultSet arrays.
-		if (routineInfo != null) {
-
-			int compiledResultSets = methodParameterTypes.length - methodParms.length;
-
-			if (compiledResultSets != 0) {
-
-				// Add a method that indicates the maxium number of dynamic result sets.
-				int maxDynamicResults = routineInfo.getMaxDynamicResultSets();
-				if (maxDynamicResults > 0) {
-					MethodBuilder gdr = acb.getClassBuilder().newMethodBuilder(Modifier.PUBLIC, "int", "getMaxDynamicResults");
-					gdr.push(maxDynamicResults);
-					gdr.methodReturn();
-					gdr.complete();
-				}
-
-				// add a method to return all the dynamic result sets (unordered)
-				MethodBuilder gdr = acb.getClassBuilder().newMethodBuilder(Modifier.PUBLIC, "java.sql.ResultSet[][]", "getDynamicResults");
-
-				MethodBuilder cons = acb.getConstructor();
-				// if (procDef.getParameterStyle() == RoutineAliasInfo.PS_JAVA)
-				{
-					// PARAMETER STYLE JAVA
-
-					LocalField procedureResultSetsHolder = acb.newFieldDeclaration(Modifier.PRIVATE, "java.sql.ResultSet[][]");
-
-					// getDynamicResults body
-					gdr.getField(procedureResultSetsHolder);
-
-					// create the holder of all the ResultSet arrays, new java.sql.ResultSet[][compiledResultSets]
-					cons.pushNewArray("java.sql.ResultSet[]", compiledResultSets);
-					cons.putField(procedureResultSetsHolder);
-					cons.endStatement();
-
-
-					// arguments for the dynamic result sets
-					for (int i = 0; i < compiledResultSets; i++) {
-
-						mb.pushNewArray("java.sql.ResultSet", 1);
-						mb.dup();
-
-						mb.getField(procedureResultSetsHolder);
-						mb.swap();
-
-						mb.setArrayElement(i);
-					}
-				} 
-
-				// complete the method that returns the ResultSet[][] to the 
-				gdr.methodReturn();
-				gdr.complete();
-
-				nargs += compiledResultSets;
-			}
-
-		}
-
-		String javaReturnType = getJavaTypeName();
-
-		MethodBuilder mbnc = null;
-		MethodBuilder mbcm = mb;
-
-
-		// If any of the parameters are null then
-		// do not call the method, just return null.
-		if (returnsNullOnNullState != null)
-		{
-			mbnc = acb.newGeneratedFun(javaReturnType, Modifier.PRIVATE, methodParameterTypes);
-
-			// add the throws clause for the public static method we are going to call.
-			Class[] throwsSet = ((java.lang.reflect.Method) method).getExceptionTypes();
-			for (int te = 0; te < throwsSet.length; te++)
-			{
-				mbnc.addThrownException(throwsSet[te].getName());
-			}
-
-			mbnc.getField(returnsNullOnNullState);
-			mbnc.conditionalIf();
-
-			// set up for a null!!
-			// for objects is easy.
-			mbnc.pushNull(javaReturnType);
-
-			mbnc.startElseCode();	
-
-			if (!actualMethodReturnType.equals(javaReturnType))
-				mbnc.pushNewStart(javaReturnType);
-
-			// fetch all the arguments
-			for (int pa = 0; pa < nargs; pa++)
-			{
-				mbnc.getParameter(pa);
-			}
-
-			mbcm = mbnc;
-		}
-
-		mbcm.callMethod(VMOpcode.INVOKESTATIC, method.getDeclaringClass().getName(), methodName,
-					actualMethodReturnType, nargs);
-
-
-		if (returnsNullOnNullState != null)
-		{
-			if (!actualMethodReturnType.equals(javaReturnType))
-				mbnc.pushNewComplete(1);
-
-			mbnc.completeConditional();
-
-			mbnc.methodReturn();
-			mbnc.complete();
-
-			// now call the wrapper method
-			mb.callMethod(VMOpcode.INVOKEVIRTUAL, acb.getClassBuilder().getFullName(), mbnc.getName(),
-					javaReturnType, nargs);
-			mbnc = null;
-		}
-
-
-		if (routineInfo != null) {
-
-			// reset the SQL allowed setting that we set upon
-			// entry to the method.
-			if (functionEntrySQLAllowed != null) {
-				acb.pushThisAsActivation(mb);
-				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
-									"getLanguageConnectionContext", ClassName.LanguageConnectionContext, 0);
-				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
-									"getStatementContext", "org.apache.derby.iapi.sql.conn.StatementContext", 0);
-				mb.getField(functionEntrySQLAllowed);
-				mb.push(true); // override as we are ending the control set by this function all.
-				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
-									"setSQLAllowed", "void", 2);
-
-			}
-
-			if (outParamArrays != null) {
-
-				MethodBuilder constructor = acb.getConstructor();
-
-				// constructor  - setting up correct paramter type info
-				acb.pushThisAsActivation(constructor);
-				constructor.callMethod(VMOpcode.INVOKEINTERFACE, null,
-									"getParameterValueSet", ClassName.ParameterValueSet, 0);
-
-				// execute  - passing out parameters back.
-				acb.pushThisAsActivation(mb);
-				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
-									"getParameterValueSet", ClassName.ParameterValueSet, 0);
-
-				int[] parameterModes = routineInfo.getParameterModes();
-				for (int i = 0; i < outParamArrays.length; i++) {
-
-					int parameterMode = parameterModes[i];
-					if (parameterMode != JDBC30Translation.PARAMETER_MODE_IN) {
-
-						// must be a parameter if it is INOUT or OUT.
-						ValueNode sqlParamNode = ((SQLToJavaValueNode) methodParms[i]).getSQLValueNode();
-
-
-						int applicationParameterNumber = applicationParameterNumbers[i];
-
-						// Set the correct parameter nodes in the ParameterValueSet at constructor time.
-						constructor.dup();
-						constructor.push(applicationParameterNumber);
-						constructor.push(parameterMode);
-						constructor.callMethod(VMOpcode.INVOKEINTERFACE, null,
-										"setParameterMode", "void", 2);
-
-						// Pass the value of the outparameters back to the calling code
-						LocalField lf = outParamArrays[i];
-
-						mb.dup(); 
-						mb.push(applicationParameterNumber);
-						mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
-									"getParameter", ClassName.DataValueDescriptor, 1);
-
-						// see if we need to set the desired length/scale/precision of the type
-						DataTypeDescriptor paramdtd = sqlParamNode.getTypeServices();
-
-						boolean isNumericType = paramdtd.getTypeId().isNumericTypeId();
-
-						if (isNumericType) {
-							if (!paramdtd.getTypeId().isDecimalTypeId()) {
-
-								if (!((java.lang.reflect.Method) method).getParameterTypes()[i].getComponentType().isPrimitive())
-									mb.cast(ClassName.NumberDataValue);
-							}
-						}
-						else if (paramdtd.getTypeId().isBooleanTypeId())
-						{
-							if (!((java.lang.reflect.Method) method).getParameterTypes()[i].getComponentType().isPrimitive())
-								mb.cast(ClassName.BooleanDataValue);
-						}
-
-
-
-						if (paramdtd.getTypeId().variableLength()) {
-							// need another DVD reference for the set width below.
-							mb.dup();
-						}
-
-
-						mb.getField(lf); // pvs, dvd, array
-						mb.getArrayElement(0); // pvs, dvd, value
-						mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "setValue", "void", 1);
-
-						if (paramdtd.getTypeId().variableLength()) {
-							mb.push(isNumericType ? paramdtd.getPrecision() : paramdtd.getMaximumWidth());
-							mb.push(paramdtd.getScale());
-							mb.push(isNumericType);
-							mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.VariableSizeDataValue, "setWidth", ClassName.DataValueDescriptor, 3);
-							mb.endStatement();
-						}
-					}
-				}
-				constructor.endStatement();
-				mb.endStatement();
-			}
-
-		}
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package	org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.services.compiler.MethodBuilder;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+import org.apache.derby.iapi.sql.compile.CompilerContext;
+import org.apache.derby.iapi.sql.compile.TypeCompiler;
+import org.apache.derby.iapi.sql.compile.C_NodeTypes;
+import org.apache.derby.iapi.types.JSQLType;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+import org.apache.derby.iapi.types.TypeId;
+
+import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;
+import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
+
+import org.apache.derby.iapi.reference.ClassName;
+import org.apache.derby.iapi.reference.SQLState;
+import org.apache.derby.iapi.reference.JDBC30Translation;
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
+import org.apache.derby.iapi.services.loader.ClassInspector;
+import org.apache.derby.iapi.services.compiler.LocalField;
+
+import org.apache.derby.iapi.util.JBitSet;
+import org.apache.derby.iapi.services.classfile.VMOpcode;
+
+import org.apache.derby.iapi.sql.conn.Authorizer;
+
+import org.apache.derby.catalog.AliasInfo;
+import org.apache.derby.catalog.TypeDescriptor;
+import org.apache.derby.catalog.types.RoutineAliasInfo;
+import org.apache.derby.impl.sql.compile.ActivationClassBuilder;
+
+import org.apache.derby.catalog.UUID;
+
+import java.util.Vector;
+import java.lang.reflect.Modifier;
+
+/**
+ * A StaticMethodCallNode represents a static method call from a Class
+ * (as opposed to from an Object).
+
+   For a procedure the call requires that the arguments be ? parameters.
+   The parameter is *logically* passed into the method call a number of different ways.
+
+   <P>
+   For a application call like CALL MYPROC(?) the logically Java method call is
+   (in psuedo Java/SQL code) (examples with CHAR(10) parameter)
+   <BR>
+   Fixed length IN parameters - com.acme.MyProcedureMethod(?)
+   <BR>
+   Variable length IN parameters - com.acme.MyProcedureMethod(CAST (? AS CHAR(10))
+   <BR>
+   Fixed length INOUT parameter -
+		String[] holder = new String[] {?}; com.acme.MyProcedureMethod(holder); ? = holder[0]
+   <BR>
+   Variable length INOUT parameter -
+		String[] holder = new String[] {CAST (? AS CHAR(10)}; com.acme.MyProcedureMethod(holder); ? = CAST (holder[0] AS CHAR(10))
+
+   <BR>
+   Fixed length OUT parameter -
+		String[] holder = new String[1]; com.acme.MyProcedureMethod(holder); ? = holder[0]
+
+   <BR>
+   Variable length INOUT parameter -
+		String[] holder = new String[1]; com.acme.MyProcedureMethod(holder); ? = CAST (holder[0] AS CHAR(10))
+
+
+    <P>
+	For static method calls there is no pre-definition of an IN or INOUT parameter, so a call to CallableStatement.registerOutParameter()
+	makes the parameter an INOUT parameter, provided:
+		- the parameter is passed directly to the method call (no casts or expressions).
+		- the method's parameter type is a Java array type.
+
+    Since this is a dynmaic decision we compile in code to take both paths, based upon a boolean isINOUT which is dervied from the
+	ParameterValueSet. Code is logically (only single parameter String[] shown here). Note, no casts can exist here.
+
+	boolean isINOUT = getParameterValueSet().getParameterMode(0) == PARAMETER_IN_OUT;
+	if (isINOUT) {
+		String[] holder = new String[] {?}; com.acme.MyProcedureMethod(holder); ? = holder[0]
+	   
+	} else {
+		com.acme.MyProcedureMethod(?)
+	}
+
+ *
+ * @author Jerry Brenner
+ */
+public class StaticMethodCallNode extends MethodCallNode
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	private TableName procedureName;
+
+	private LocalField[] outParamArrays;
+	private int[]		 applicationParameterNumbers; 
+
+	private boolean		isSystemCode;
+	private boolean		alreadyBound;
+
+	private LocalField	returnsNullOnNullState;
+
+
+	AliasDescriptor	ad;
+
+
+	/**
+	 * Intializer for a NonStaticMethodCallNode
+	 *
+	 * @param methodName		The name of the method to call
+	 * @param javaClassName		The name of the java class that the static method belongs to.
+	 */
+	public void init(Object methodName, Object javaClassName)
+	{
+		if (methodName instanceof String)
+			init(methodName);
+		else {
+			procedureName = (TableName) methodName;
+			init(procedureName.getTableName());
+		}
+
+		this.javaClassName = (String) javaClassName;
+	}
+
+	/**
+	 * Bind this expression.  This means binding the sub-expressions,
+	 * as well as figuring out what the return type is for this expression.
+	 *
+	 * @param fromList		The FROM list for the query this
+	 *				expression is in, for binding columns.
+	 * @param subqueryList		The subquery list being built as we find SubqueryNodes
+	 * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
+	 *
+	 * @return	this or an AggregateNode
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public JavaValueNode bindExpression(
+		FromList fromList, SubqueryList subqueryList,
+		Vector	aggregateVector) 
+			throws StandardException
+	{
+		// for a function we can get called recursively
+		if (alreadyBound)
+			return this;
+
+
+		bindParameters(fromList, subqueryList, aggregateVector);
+
+		
+		/* If javaClassName is null then we assume that the current methodName
+		 * is an alias and we must go to sysmethods to
+		 * get the real method and java class names for this alias.
+		 */
+		if (javaClassName == null)
+		{
+			CompilerContext cc = getCompilerContext();
+
+			// look for a routine
+			if (ad == null) {
+
+				String schemaName = procedureName != null ?
+									procedureName.getSchemaName() : null;
+
+				SchemaDescriptor sd = getSchemaDescriptor(schemaName, schemaName != null);
+
+
+				if (sd.getUUID() != null) {
+
+				java.util.List list = getDataDictionary().getRoutineList(
+					sd.getUUID().toString(), methodName,
+					forCallStatement ? AliasInfo.ALIAS_NAME_SPACE_PROCEDURE_AS_CHAR : AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR
+					);
+
+				for (int i = list.size() - 1; i >= 0; i--) {
+
+					AliasDescriptor proc = (AliasDescriptor) list.get(i);
+
+					RoutineAliasInfo routineInfo = (RoutineAliasInfo) proc.getAliasInfo();
+					int parameterCount = routineInfo.getParameterCount();
+					if (parameterCount != methodParms.length)
+						continue;
+
+					// pre-form the method signature. If it is a dynamic result set procedure
+					// then we need to add in the ResultSet array
+
+					TypeDescriptor[] parameterTypes = routineInfo.getParameterTypes();
+
+					int sigParameterCount = parameterCount;
+					if (routineInfo.getMaxDynamicResultSets() > 0)
+						sigParameterCount++;
+
+					signature = new JSQLType[sigParameterCount];
+					for (int p = 0; p < parameterCount; p++) {
+
+						// find the declared type.
+
+						TypeDescriptor td = parameterTypes[p];
+
+						TypeId typeId = TypeId.getBuiltInTypeId(td.getJDBCTypeId());
+
+						TypeId parameterTypeId = typeId;
+
+
+						// if it's an OUT or INOUT parameter we need an array.
+						int parameterMode = routineInfo.getParameterModes()[p];
+
+						if (parameterMode != JDBC30Translation.PARAMETER_MODE_IN) {
+
+							String arrayType;
+							switch (typeId.getJDBCTypeId()) {
+								case java.sql.Types.SMALLINT:
+								case java.sql.Types.INTEGER:
+								case java.sql.Types.BIGINT:
+								case java.sql.Types.REAL:
+								case java.sql.Types.DOUBLE:
+									arrayType = getTypeCompiler(typeId).getCorrespondingPrimitiveTypeName().concat("[]");
+									break;
+								default:
+									arrayType = typeId.getCorrespondingJavaTypeName().concat("[]");
+									break;
+							}
+
+							typeId = TypeId.getUserDefinedTypeId(arrayType, false);
+						}
+
+						// this is the type descriptor of the require method parameter
+						DataTypeDescriptor methoddtd = new DataTypeDescriptor(
+								typeId,
+								td.getPrecision(),
+								td.getScale(),
+								td.isNullable(),
+								td.getMaximumWidth()
+							);
+
+						signature[p] = new JSQLType(methoddtd);
+
+						// check parameter is a ? node for INOUT and OUT parameters.
+
+						ValueNode sqlParamNode = null;
+
+						if (methodParms[p] instanceof SQLToJavaValueNode) {
+							SQLToJavaValueNode sql2j = (SQLToJavaValueNode) methodParms[p];
+							sqlParamNode = sql2j.getSQLValueNode();
+						}
+						else
+						{
+						}
+
+						boolean isParameterMarker = true;
+						if ((sqlParamNode == null) || !sqlParamNode.isParameterNode())
+						{
+							if (parameterMode != JDBC30Translation.PARAMETER_MODE_IN) {
+							 
+								throw StandardException.newException(SQLState.LANG_DB2_PARAMETER_NEEDS_MARKER,
+									RoutineAliasInfo.parameterMode(parameterMode),
+									routineInfo.getParameterNames()[p]);
+							}
+							isParameterMarker = false;
+						}
+						else
+						{
+							if (applicationParameterNumbers == null)
+								applicationParameterNumbers = new int[parameterCount];
+							applicationParameterNumbers[p] = ((ParameterNode) sqlParamNode).getParameterNumber();
+						}
+
+						// this is the SQL type of the procedure parameter.
+						DataTypeDescriptor paramdtd = new DataTypeDescriptor(
+							parameterTypeId,
+							td.getPrecision(),
+							td.getScale(),
+							td.isNullable(),
+							td.getMaximumWidth()
+						);
+
+						boolean needCast = false;
+						if (!isParameterMarker)
+						{
+
+							// can only be an IN parameter.
+							// check that the value can be assigned to the
+							// type of the procedure parameter.
+							if (sqlParamNode instanceof UntypedNullConstantNode)
+							{
+								sqlParamNode.setDescriptor(paramdtd);
+							}
+							else
+							{
+
+
+								DataTypeDescriptor dts;
+								TypeId argumentTypeId;
+
+								if (sqlParamNode != null)
+								{
+									// a node from the SQL world
+									argumentTypeId = sqlParamNode.getTypeId();
+									dts = sqlParamNode.getTypeServices();
+								}
+								else
+								{
+									// a node from the Java world
+									dts = DataTypeDescriptor.getSQLDataTypeDescriptor(methodParms[p].getJavaTypeName());
+									if (dts == null)
+									{
+										throw StandardException.newException(SQLState.LANG_NO_CORRESPONDING_S_Q_L_TYPE, 
+											methodParms[p].getJavaTypeName());
+									}
+
+									argumentTypeId = dts.getTypeId();
+								}
+
+								if (! getTypeCompiler(parameterTypeId).storable(argumentTypeId, getClassFactory()))
+										throw StandardException.newException(SQLState.LANG_NOT_STORABLE, 
+											parameterTypeId.getSQLTypeName(),
+											argumentTypeId.getSQLTypeName() );
+
+								// if it's not an exact length match then some cast will be needed.
+								if (!paramdtd.isExactTypeAndLengthMatch(dts))
+									needCast = true;
+							}
+						}
+						else
+						{
+							// any variable length type will need a cast from the
+							// Java world (the ? parameter) to the SQL type. This
+							// ensures values like CHAR(10) are passed into the procedure
+							// correctly as 10 characters long.
+							if (parameterTypeId.variableLength()) {
+
+								if (parameterMode != JDBC30Translation.PARAMETER_MODE_OUT)
+									needCast = true;
+							}
+						}
+						
+
+						if (needCast)
+						{
+							// push a cast node to ensure the
+							// correct type is passed to the method
+							// this gets tacky because before we knew
+							// it was a procedure call we ensured all the
+							// parameter are JavaNodeTypes. Now we need to
+							// push them back to the SQL domain, cast them
+							// and then push them back to the Java domain.
+
+							if (sqlParamNode == null) {
+
+								sqlParamNode = (ValueNode) getNodeFactory().getNode(
+									C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,
+									methodParms[p], 
+									getContextManager());
+							}
+
+							ValueNode castNode = (ValueNode) getNodeFactory().getNode(
+								C_NodeTypes.CAST_NODE,
+								sqlParamNode, 
+								paramdtd,
+								getContextManager());
+
+
+							methodParms[p] = (JavaValueNode) getNodeFactory().getNode(
+									C_NodeTypes.SQL_TO_JAVA_VALUE_NODE,
+									castNode, 
+									getContextManager());
+
+							methodParms[p] = methodParms[p].bindExpression(fromList, subqueryList, aggregateVector);
+						}
+
+						// only force the type for a ? so that the correct type shows up
+						// in parameter meta data
+						if (isParameterMarker)
+							sqlParamNode.setDescriptor(paramdtd);
+					}
+
+					if (sigParameterCount != parameterCount) {
+
+						TypeId typeId = TypeId.getUserDefinedTypeId("java.sql.ResultSet[]", false);
+
+						DataTypeDescriptor dtd = new DataTypeDescriptor(
+								typeId,
+								0,
+								0,
+								false,
+								-1
+							);
+
+						signature[parameterCount] = new JSQLType(dtd);
+
+					}
+
+					this.routineInfo = routineInfo;
+					ad = proc;
+
+					// If a procedure is in the system schema and defined as executing
+					// SQL do we set we are in system code.
+					if (sd.isSystemSchema() && (routineInfo.getReturnType() == null) && routineInfo.getSQLAllowed() != RoutineAliasInfo.NO_SQL)
+						isSystemCode = true;
+
+					break;
+				}
+			}
+	
+			}
+
+			/* Throw exception if no alias found */
+			if (ad == null)
+			{
+				Object errName;
+				if (procedureName == null)
+					errName = methodName;
+				else
+					errName = procedureName;
+
+				throw StandardException.newException(SQLState.LANG_NO_SUCH_METHOD_ALIAS, errName);
+			}
+	
+
+
+			/* Query is dependent on the AliasDescriptor */
+			cc.createDependency(ad);
+
+
+			methodName = ad.getAliasInfo().getMethodName();
+			javaClassName = ad.getJavaClassName();
+		}
+
+
+		javaClassName = verifyClassExist(javaClassName, true);
+
+		/* Resolve the method call */
+		resolveMethodCall(javaClassName, true);
+
+
+		alreadyBound = true;
+
+		// If this is a function call with a variable length
+		// return type, then we need to push a CAST node.
+		if (routineInfo != null)
+		{
+			TypeDescriptor returnType = routineInfo.getReturnType();
+			if (returnType != null)
+			{
+				TypeId returnTypeId = TypeId.getBuiltInTypeId(returnType.getJDBCTypeId());
+
+				if (returnTypeId.variableLength()) {
+					// Cast the return using a cast node, but have to go
+					// into the SQL domain, and back to the Java domain.
+
+					DataTypeDescriptor returnValueDtd = new DataTypeDescriptor(
+								returnTypeId,
+								returnType.getPrecision(),
+								returnType.getScale(),
+								returnType.isNullable(),
+								returnType.getMaximumWidth()
+							);
+
+
+					ValueNode returnValueToSQL = (ValueNode) getNodeFactory().getNode(
+								C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,
+								this, 
+								getContextManager());
+
+					ValueNode returnValueCastNode = (ValueNode) getNodeFactory().getNode(
+									C_NodeTypes.CAST_NODE,
+									returnValueToSQL, 
+									returnValueDtd,
+									getContextManager());
+
+
+					JavaValueNode returnValueToJava = (JavaValueNode) getNodeFactory().getNode(
+										C_NodeTypes.SQL_TO_JAVA_VALUE_NODE,
+										returnValueCastNode, 
+										getContextManager());
+
+					return returnValueToJava.bindExpression(fromList, subqueryList, aggregateVector);
+				}
+
+			}
+		}
+
+		return this;
+	}
+
+	/**
+		Push extra code to generate the casts within the
+		arrays for the parameters passed as arrays.
+	*/
+	public	void generateOneParameter(ExpressionClassBuilder acb,
+											MethodBuilder mb,
+											int parameterNumber )
+			throws StandardException
+	{
+		int parameterMode;
+
+
+		SQLToJavaValueNode sql2j = null;
+		if (methodParms[parameterNumber] instanceof SQLToJavaValueNode)
+			sql2j = (SQLToJavaValueNode) methodParms[parameterNumber];
+		
+		if (routineInfo != null) {
+			parameterMode = routineInfo.getParameterModes()[parameterNumber];
+		} else {
+			// for a static method call the parameter always starts out as a in parameter, but
+			// may be registered as an IN OUT parameter. For a static method argument to be
+			// a dynmaically registered out parameter it must be a simple ? parameter
+
+			parameterMode = JDBC30Translation.PARAMETER_MODE_IN;
+
+			if (sql2j != null) {
+				if (sql2j.getSQLValueNode().isParameterNode()) {
+
+					// applicationParameterNumbers is only set up for a procedure.
+					int applicationParameterNumber = ((ParameterNode) (sql2j.getSQLValueNode())).getParameterNumber();
+
+					String parameterType = methodParameterTypes[parameterNumber];
+
+					if (parameterType.endsWith("[]")) {
+
+						// constructor  - setting up correct paramter type info
+						MethodBuilder constructor = acb.getConstructor();
+						acb.pushThisAsActivation(constructor);
+						constructor.callMethod(VMOpcode.INVOKEINTERFACE, null,
+											"getParameterValueSet", ClassName.ParameterValueSet, 0);
+
+						constructor.push(applicationParameterNumber);
+						constructor.push(JDBC30Translation.PARAMETER_MODE_UNKNOWN);
+						constructor.callMethod(VMOpcode.INVOKEINTERFACE, null,
+											"setParameterMode", "void", 2);
+						constructor.endStatement();
+					}
+				}
+			} 
+		}
+
+		switch (parameterMode) {
+		case JDBC30Translation.PARAMETER_MODE_IN:
+		case JDBC30Translation.PARAMETER_MODE_IN_OUT:
+		case JDBC30Translation.PARAMETER_MODE_UNKNOWN:
+			if (sql2j != null)
+				sql2j.returnsNullOnNullState = returnsNullOnNullState;
+			super.generateOneParameter(acb, mb, parameterNumber);
+			break;
+
+		case JDBC30Translation.PARAMETER_MODE_OUT:
+			// For an OUT parameter we require nothing to be pushed into the
+			// method call from the parameter node.
+			break;
+		}
+
+		switch (parameterMode) {
+		case JDBC30Translation.PARAMETER_MODE_IN:
+		case JDBC30Translation.PARAMETER_MODE_UNKNOWN:
+			break;
+
+		case JDBC30Translation.PARAMETER_MODE_IN_OUT:
+		case JDBC30Translation.PARAMETER_MODE_OUT:
+		{
+			// Create the array used to pass into the method. We create a
+			// new array for each call as there is a small chance the
+			// application could retain a reference to it and corrupt
+			// future calls with the same CallableStatement object.
+
+			String methodParameterType = methodParameterTypes[parameterNumber];
+			String arrayType = methodParameterType.substring(0, methodParameterType.length() - 2);
+			LocalField lf = acb.newFieldDeclaration(Modifier.PRIVATE, methodParameterType);
+
+			if (outParamArrays == null)
+				outParamArrays = new LocalField[methodParms.length];
+
+			outParamArrays[parameterNumber] = lf;
+
+			mb.pushNewArray(arrayType, 1);
+			mb.putField(lf);
+
+			// set the IN part of the parameter into the INOUT parameter.
+			if (parameterMode != JDBC30Translation.PARAMETER_MODE_OUT) {
+				mb.swap();
+				mb.setArrayElement(0);
+				mb.getField(lf);
+			}
+			break;
+			}
+		}
+
+	}
+
+	/**
+	 * Categorize this predicate.  Initially, this means
+	 * building a bit map of the referenced tables for each predicate.
+	 * If the source of this ColumnReference (at the next underlying level) 
+	 * is not a ColumnReference or a VirtualColumnNode then this predicate
+	 * will not be pushed down.
+	 *
+	 * For example, in:
+	 *		select * from (select 1 from s) a (x) where x = 1
+	 * we will not push down x = 1.
+	 * NOTE: It would be easy to handle the case of a constant, but if the
+	 * inner SELECT returns an arbitrary expression, then we would have to copy
+	 * that tree into the pushed predicate, and that tree could contain
+	 * subqueries and method calls.
+	 * RESOLVE - revisit this issue once we have views.
+	 *
+	 * @param referencedTabs	JBitSet with bit map of referenced FromTables
+	 * @param simplePredsOnly	Whether or not to consider method
+	 *							calls, field references and conditional nodes
+	 *							when building bit map
+	 *
+	 * @return boolean		Whether or not source.expression is a ColumnReference
+	 *						or a VirtualColumnNode.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly)
+		throws StandardException
+	{
+		/* We stop here when only considering simple predicates
+		 *  as we don't consider method calls when looking
+		 * for null invariant predicates.
+		 */
+		if (simplePredsOnly)
+		{
+			return false;
+		}
+
+		boolean pushable = true;
+
+		pushable = pushable && super.categorize(referencedTabs, simplePredsOnly);
+
+		return pushable;
+	}
+
+	/**
+	 * Convert this object to a String.  See comments in QueryTreeNode.java
+	 * for how this should be done for tree printing.
+	 *
+	 * @return	This object as a String
+	 */
+
+	public String toString()
+	{
+		if (SanityManager.DEBUG)
+		{
+			return "javaClassName: " +
+				(javaClassName != null ? javaClassName : "null") + "\n" +
+				super.toString();
+		}
+		else
+		{
+			return "";
+		}
+	}
+
+	/**
+	 * Do code generation for this method call
+	 *
+	 * @param acb	The ExpressionClassBuilder for the class we're generating
+	 * @param mb	The method the expression will go into
+	 *
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public void generateExpression(ExpressionClassBuilder acb,
+											MethodBuilder mb)
+									throws StandardException
+	{
+		if (routineInfo != null) {
+
+			if (!routineInfo.calledOnNullInput() && routineInfo.getParameterCount() != 0)
+				returnsNullOnNullState = acb.newFieldDeclaration(Modifier.PRIVATE, "boolean");
+
+		}
+
+		// reset the parameters are null indicator.
+		if (returnsNullOnNullState != null) {
+			mb.push(false);
+			mb.putField(returnsNullOnNullState);
+			mb.endStatement();
+
+			// for the call to the generated method below.
+			mb.pushThis();
+		}
+
+		int nargs = generateParameters(acb, mb);
+
+		LocalField functionEntrySQLAllowed = null;
+
+		if (routineInfo != null) {
+
+			short sqlAllowed = routineInfo.getSQLAllowed();
+
+			// Before we set up our authorization level, add a check to see if this
+			// method can be called. If the routine is NO SQL or CONTAINS SQL 
+			// then there is no need for a check. As follows:
+			//
+			// Current Level = NO_SQL - CALL will be rejected when getting CALL result set
+			// Current Level = anything else - calls to procedures defined as NO_SQL and CONTAINS SQL both allowed.
+
+
+			if (sqlAllowed != RoutineAliasInfo.NO_SQL)
+			{
+				
+				int sqlOperation;
+				
+				if (sqlAllowed == RoutineAliasInfo.READS_SQL_DATA)
+					sqlOperation = Authorizer.SQL_SELECT_OP;
+				else if (sqlAllowed == RoutineAliasInfo.MODIFIES_SQL_DATA)
+					sqlOperation = Authorizer.SQL_WRITE_OP;
+				else
+					sqlOperation = Authorizer.SQL_ARBITARY_OP;
+				
+				generateAuthorizeCheck((ActivationClassBuilder) acb, mb, sqlOperation);
+			}
+
+			int statmentContextReferences = isSystemCode ? 2 : 1;
+			
+			boolean isFunction = routineInfo.getReturnType() != null;
+
+			if (isFunction)
+				statmentContextReferences++;
+
+
+			if (statmentContextReferences != 0) {
+				acb.pushThisAsActivation(mb);
+				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
+									"getLanguageConnectionContext", ClassName.LanguageConnectionContext, 0);
+				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
+									"getStatementContext", "org.apache.derby.iapi.sql.conn.StatementContext", 0);
+
+				for (int scc = 1; scc < statmentContextReferences; scc++)
+					mb.dup();
+			}
+
+			/**
+				Set the statement context to reflect we are running
+				System procedures, so that we can execute non-standard SQL.
+			*/
+			if (isSystemCode) {
+				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
+									"setSystemCode", "void", 0);
+			}
+
+			// for a function we need to fetch the current SQL control
+			// so that we can reset it once the function is complete.
+			// 
+			if (isFunction)
+			{
+				functionEntrySQLAllowed = acb.newFieldDeclaration(Modifier.PRIVATE, "short");
+				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
+									"getSQLAllowed", "short", 0);
+				mb.putField(functionEntrySQLAllowed);
+				mb.endStatement();
+
+			}
+			
+			
+			// Set up the statement context to reflect the
+			// restricted SQL execution allowed by this routine.
+
+			mb.push(sqlAllowed);
+			mb.push(false);
+			mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
+								"setSQLAllowed", "void", 2);
+
+		}
+
+		// add in the ResultSet arrays.
+		if (routineInfo != null) {
+
+			int compiledResultSets = methodParameterTypes.length - methodParms.length;
+
+			if (compiledResultSets != 0) {
+
+				// Add a method that indicates the maxium number of dynamic result sets.
+				int maxDynamicResults = routineInfo.getMaxDynamicResultSets();
+				if (maxDynamicResults > 0) {
+					MethodBuilder gdr = acb.getClassBuilder().newMethodBuilder(Modifier.PUBLIC, "int", "getMaxDynamicResults");
+					gdr.push(maxDynamicResults);
+					gdr.methodReturn();
+					gdr.complete();
+				}
+
+				// add a method to return all the dynamic result sets (unordered)
+				MethodBuilder gdr = acb.getClassBuilder().newMethodBuilder(Modifier.PUBLIC, "java.sql.ResultSet[][]", "getDynamicResults");
+
+				MethodBuilder cons = acb.getConstructor();
+				// if (procDef.getParameterStyle() == RoutineAliasInfo.PS_JAVA)
+				{
+					// PARAMETER STYLE JAVA
+
+					LocalField procedureResultSetsHolder = acb.newFieldDeclaration(Modifier.PRIVATE, "java.sql.ResultSet[][]");
+
+					// getDynamicResults body
+					gdr.getField(procedureResultSetsHolder);
+
+					// create the holder of all the ResultSet arrays, new java.sql.ResultSet[][compiledResultSets]
+					cons.pushNewArray("java.sql.ResultSet[]", compiledResultSets);
+					cons.putField(procedureResultSetsHolder);
+					cons.endStatement();
+
+
+					// arguments for the dynamic result sets
+					for (int i = 0; i < compiledResultSets; i++) {
+
+						mb.pushNewArray("java.sql.ResultSet", 1);
+						mb.dup();
+
+						mb.getField(procedureResultSetsHolder);
+						mb.swap();
+
+						mb.setArrayElement(i);
+					}
+				} 
+
+				// complete the method that returns the ResultSet[][] to the 
+				gdr.methodReturn();
+				gdr.complete();
+
+				nargs += compiledResultSets;
+			}
+
+		}
+
+		String javaReturnType = getJavaTypeName();
+
+		MethodBuilder mbnc = null;
+		MethodBuilder mbcm = mb;
+
+
+		// If any of the parameters are null then
+		// do not call the method, just return null.
+		if (returnsNullOnNullState != null)
+		{
+			mbnc = acb.newGeneratedFun(javaReturnType, Modifier.PRIVATE, methodParameterTypes);
+
+			// add the throws clause for the public static method we are going to call.
+			Class[] throwsSet = ((java.lang.reflect.Method) method).getExceptionTypes();
+			for (int te = 0; te < throwsSet.length; te++)
+			{
+				mbnc.addThrownException(throwsSet[te].getName());
+			}
+
+			mbnc.getField(returnsNullOnNullState);
+			mbnc.conditionalIf();
+
+			// set up for a null!!
+			// for objects is easy.
+			mbnc.pushNull(javaReturnType);
+
+			mbnc.startElseCode();	
+
+			if (!actualMethodReturnType.equals(javaReturnType))
+				mbnc.pushNewStart(javaReturnType);
+
+			// fetch all the arguments
+			for (int pa = 0; pa < nargs; pa++)
+			{
+				mbnc.getParameter(pa);
+			}
+
+			mbcm = mbnc;
+		}
+
+		mbcm.callMethod(VMOpcode.INVOKESTATIC, method.getDeclaringClass().getName(), methodName,
+					actualMethodReturnType, nargs);
+
+
+		if (returnsNullOnNullState != null)
+		{
+			if (!actualMethodReturnType.equals(javaReturnType))
+				mbnc.pushNewComplete(1);
+
+			mbnc.completeConditional();
+
+			mbnc.methodReturn();
+			mbnc.complete();
+
+			// now call the wrapper method
+			mb.callMethod(VMOpcode.INVOKEVIRTUAL, acb.getClassBuilder().getFullName(), mbnc.getName(),
+					javaReturnType, nargs);
+			mbnc = null;
+		}
+
+
+		if (routineInfo != null) {
+
+			// reset the SQL allowed setting that we set upon
+			// entry to the method.
+			if (functionEntrySQLAllowed != null) {
+				acb.pushThisAsActivation(mb);
+				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
+									"getLanguageConnectionContext", ClassName.LanguageConnectionContext, 0);
+				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
+									"getStatementContext", "org.apache.derby.iapi.sql.conn.StatementContext", 0);
+				mb.getField(functionEntrySQLAllowed);
+				mb.push(true); // override as we are ending the control set by this function all.
+				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
+									"setSQLAllowed", "void", 2);
+
+			}
+
+			if (outParamArrays != null) {
+
+				MethodBuilder constructor = acb.getConstructor();
+
+				// constructor  - setting up correct paramter type info
+				acb.pushThisAsActivation(constructor);
+				constructor.callMethod(VMOpcode.INVOKEINTERFACE, null,
+									"getParameterValueSet", ClassName.ParameterValueSet, 0);
+
+				// execute  - passing out parameters back.
+				acb.pushThisAsActivation(mb);
+				mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
+									"getParameterValueSet", ClassName.ParameterValueSet, 0);
+
+				int[] parameterModes = routineInfo.getParameterModes();
+				for (int i = 0; i < outParamArrays.length; i++) {
+
+					int parameterMode = parameterModes[i];
+					if (parameterMode != JDBC30Translation.PARAMETER_MODE_IN) {
+
+						// must be a parameter if it is INOUT or OUT.
+						ValueNode sqlParamNode = ((SQLToJavaValueNode) methodParms[i]).getSQLValueNode();
+
+
+						int applicationParameterNumber = applicationParameterNumbers[i];
+
+						// Set the correct parameter nodes in the ParameterValueSet at constructor time.
+						constructor.dup();
+						constructor.push(applicationParameterNumber);
+						constructor.push(parameterMode);
+						constructor.callMethod(VMOpcode.INVOKEINTERFACE, null,
+										"setParameterMode", "void", 2);
+
+						// Pass the value of the outparameters back to the calling code
+						LocalField lf = outParamArrays[i];
+
+						mb.dup(); 
+						mb.push(applicationParameterNumber);
+						mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
+									"getParameter", ClassName.DataValueDescriptor, 1);
+
+						// see if we need to set the desired length/scale/precision of the type
+						DataTypeDescriptor paramdtd = sqlParamNode.getTypeServices();
+
+						boolean isNumericType = paramdtd.getTypeId().isNumericTypeId();
+
+						if (isNumericType) {
+							if (!paramdtd.getTypeId().isDecimalTypeId()) {
+
+								if (!((java.lang.reflect.Method) method).getParameterTypes()[i].getComponentType().isPrimitive())
+									mb.cast(ClassName.NumberDataValue);
+							}
+						}
+						else if (paramdtd.getTypeId().isBooleanTypeId())
+						{
+							if (!((java.lang.reflect.Method) method).getParameterTypes()[i].getComponentType().isPrimitive())
+								mb.cast(ClassName.BooleanDataValue);
+						}
+
+
+
+						if (paramdtd.getTypeId().variableLength()) {
+							// need another DVD reference for the set width below.
+							mb.dup();
+						}
+
+
+						mb.getField(lf); // pvs, dvd, array
+						mb.getArrayElement(0); // pvs, dvd, value
+						mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "setValue", "void", 1);
+
+						if (paramdtd.getTypeId().variableLength()) {
+							mb.push(isNumericType ? paramdtd.getPrecision() : paramdtd.getMaximumWidth());
+							mb.push(paramdtd.getScale());
+							mb.push(isNumericType);
+							mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.VariableSizeDataValue, "setWidth", ClassName.DataValueDescriptor, 3);
+							mb.endStatement();
+						}
+					}
+				}
+				constructor.endStatement();
+				mb.endStatement();
+			}
+
+		}
+	}
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StringSlicer.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StringSlicer.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StringSlicer.java	Fri Sep 24 10:33:20 2004
@@ -1,93 +1,93 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.sql.compile;
-
-import	java.lang.Math;
-
-/**
- * This utility class wraps a string, making it possible
- * to extract substrings, given byte offsets into the
- * original string.
- * 
- */
-public class StringSlicer
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	private	char[]		charArray;
-	private	int			charLength;
-
-	/**
-	 * Construct a StringSlicer from a String.
-	 *
-	 * @param	sourceString	Source string to be sliced.
-	 */
-	public StringSlicer( String sourceString)
-	{
-		if ( sourceString == null )
-		{
-			charArray = null;
-			charLength = 0;
-		}
-		else
-		{
-			charArray = sourceString.toCharArray();
-			charLength = charArray.length;
-		}
-	}
-
-	/**
-	 * Get the byte length of the string.
-	 *
-	 * @return	byte length of the string.
-	 */
-    public	int	getCharLength() { return charLength; }
-
-
-	/**
-	 * Get the substring between two byte offsets.
-	 *
-	 * If the beginning offset is past the end of the string,
-	 * returns null. If the ending offset is past the end of
-	 * the string, truncates the substring accordingly.
-	 *
-	 * @param	beginOffset		Start of substring.
-	 * @param	endOffset		End of substring.
-	 * @param   trimflag        true to trim leading and trailing spaces
-	 *
-	 * @return	specified substring
-	 */
-	public	String	slice( int beginOffset, int endOffset, boolean trimflag )
-	{
-		int		length;
-		String	retval;
-
-		if ( charLength == 0 || beginOffset >= charLength || endOffset < beginOffset )
-		{ return null; }
-
-		endOffset = Math.min( endOffset, charLength - 1 );
-		length = (endOffset - beginOffset) + 1;
-
-		retval = new String( charArray, beginOffset, length );
-
-		// Trim leading and trailing spaces if trimflag is 
-		// set (specifically for column defaults Beetle 3913)
-		if (trimflag)
-			retval = retval.trim();
-
-		return retval;
-	}
-
-
-}
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.sql.compile;
+
+import	java.lang.Math;
+
+/**
+ * This utility class wraps a string, making it possible
+ * to extract substrings, given byte offsets into the
+ * original string.
+ * 
+ */
+public class StringSlicer
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	private	char[]		charArray;
+	private	int			charLength;
+
+	/**
+	 * Construct a StringSlicer from a String.
+	 *
+	 * @param	sourceString	Source string to be sliced.
+	 */
+	public StringSlicer( String sourceString)
+	{
+		if ( sourceString == null )
+		{
+			charArray = null;
+			charLength = 0;
+		}
+		else
+		{
+			charArray = sourceString.toCharArray();
+			charLength = charArray.length;
+		}
+	}
+
+	/**
+	 * Get the byte length of the string.
+	 *
+	 * @return	byte length of the string.
+	 */
+    public	int	getCharLength() { return charLength; }
+
+
+	/**
+	 * Get the substring between two byte offsets.
+	 *
+	 * If the beginning offset is past the end of the string,
+	 * returns null. If the ending offset is past the end of
+	 * the string, truncates the substring accordingly.
+	 *
+	 * @param	beginOffset		Start of substring.
+	 * @param	endOffset		End of substring.
+	 * @param   trimflag        true to trim leading and trailing spaces
+	 *
+	 * @return	specified substring
+	 */
+	public	String	slice( int beginOffset, int endOffset, boolean trimflag )
+	{
+		int		length;
+		String	retval;
+
+		if ( charLength == 0 || beginOffset >= charLength || endOffset < beginOffset )
+		{ return null; }
+
+		endOffset = Math.min( endOffset, charLength - 1 );
+		length = (endOffset - beginOffset) + 1;
+
+		retval = new String( charArray, beginOffset, length );
+
+		// Trim leading and trailing spaces if trimflag is 
+		// set (specifically for column defaults Beetle 3913)
+		if (trimflag)
+			retval = retval.trim();
+
+		return retval;
+	}
+
+
+}
+

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SubqueryList.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SubqueryList.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SubqueryList.java	Fri Sep 24 10:33:20 2004
@@ -1,249 +1,249 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package	org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.sql.dictionary.DataDictionary;
-import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
-
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-/**
- * A SubqueryList represents a list of subquerys within a specific clause 
- * (select, where or having) in a DML statement.  It extends QueryTreeNodeVector.
- *
- * @author Jerry Brenner
- */
-
-public class SubqueryList extends QueryTreeNodeVector
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-
-	/**
-	 * Prints the sub-nodes of this object.  See QueryTreeNode.java for
-	 * how tree printing is supposed to work.
-	 *
-	 * @param depth		The depth of this node in the tree
-	 *
-	 * @return	Nothing
-	 */
-
-	public void printSubNodes(int depth)
-	{
-		if (SanityManager.DEBUG)
-		{
-			SubqueryNode	subqueryNode;
-
-			super.printSubNodes(depth);
-
-			for (int index = 0; index < size(); index++)
-			{
-				subqueryNode = (SubqueryNode) elementAt(index);
-				subqueryNode.treePrint(depth + 1);
-			}
-		}
-	}
-
-	/**
-	 * Add a subquery to the list.
-	 *
-	 * @param subqueryNode	A SubqueryNode to add to the list
-	 *
-	 * @return	Nothing
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public void addSubqueryNode(SubqueryNode subqueryNode) throws StandardException
-	{
-		addElement(subqueryNode);
-	}
-
-	/**
-	 * Preprocess a SubqueryList.  For now, we just preprocess each SubqueryNode
-	 * in the list.
-	 *
-	 * @param	numTables			Number of tables in the DML Statement
-	 * @param	outerFromList		FromList from outer query block
-	 * @param	outerSubqueryList	SubqueryList from outer query block
-	 * @param	outerPredicateList	PredicateList from outer query block
-	 *
-	 * @return None.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public void preprocess(int numTables,
-							FromList outerFromList,
-							SubqueryList outerSubqueryList,
-							PredicateList outerPredicateList) 
-				throws StandardException
-	{
-		SubqueryNode	subqueryNode;
-
-		int size = size();
-		for (int index = 0; index < size; index++)
-		{
-			subqueryNode = (SubqueryNode) elementAt(index);
-			subqueryNode.preprocess(numTables, outerFromList,
-									outerSubqueryList,
-									outerPredicateList);
-		}
-	}
-
-	/**
-	 * Optimize the subqueries in this list.  
-	 *
-	 * @param dataDictionary	The data dictionary to use for optimization
-	 * @param outerRows			The optimizer's estimate of the number of
-	 *							times this subquery will be executed.
-	 *
-	 * @return	Nothing
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public void optimize(DataDictionary dataDictionary, double outerRows)
-			throws StandardException
-	{
-		int size = size();
-		for (int index = 0; index < size; index++)
-		{
-			SubqueryNode	subqueryNode;
-			subqueryNode = (SubqueryNode) elementAt(index);
-			subqueryNode.optimize(dataDictionary, outerRows);
-		}
-	}
-
-	/**
-	 * Modify the access paths for all subqueries in this list.
-	 *
-	 * @see ResultSetNode#modifyAccessPaths
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public void modifyAccessPaths()
-			throws StandardException
-	{
-		int size = size();
-		for (int index = 0; index < size; index++)
-		{
-			SubqueryNode	subqueryNode;
-			subqueryNode = (SubqueryNode) elementAt(index);
-			subqueryNode.modifyAccessPaths();
-		}
-	}
-
-	/**
-	 * Search to see if a query references the specifed table name.
-	 *
-	 * @param name		Table name (String) to search for.
-	 * @param baseTable	Whether or not name is for a base table
-	 *
-	 * @return	true if found, else false
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public boolean referencesTarget(String name, boolean baseTable)
-		throws StandardException
-	{
-		int size = size();
-		for (int index = 0; index < size; index++)
-		{
-			SubqueryNode	subqueryNode;
-
-			subqueryNode = (SubqueryNode) elementAt(index);
-			if (subqueryNode.isMaterializable())
-			{
-				continue;
-			}
-
-			if (subqueryNode.getResultSet().referencesTarget(name, baseTable))
-			{
-				return true;
-			}
-		}
-
-		return false;
-	}
-
-	/**
-	 * Return true if the node references SESSION schema tables (temporary or permanent)
-	 *
-	 * @return	true if references SESSION schema tables, else false
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public boolean referencesSessionSchema()
-		throws StandardException
-	{
-		int size = size();
-		for (int index = 0; index < size; index++)
-		{
-			SubqueryNode	subqueryNode;
-
-			subqueryNode = (SubqueryNode) elementAt(index);
-
-			if (subqueryNode.getResultSet().referencesSessionSchema())
-			{
-				return true;
-			}
-		}
-
-		return false;
-	}
-
-	/**
-	 * Set the point of attachment in all subqueries in this list.
-	 *
-	 * @param pointOfAttachment		The point of attachment
-	 *
-	 * @return Nothing.
-	 *
-	 * @exception StandardException			Thrown on error
-	 */
-	public void setPointOfAttachment(int pointOfAttachment)
-		throws StandardException
-	{
-		int size = size();
-
-		for (int index = 0; index < size; index++)
-		{
-			SubqueryNode	subqueryNode;
-
-			subqueryNode = (SubqueryNode) elementAt(index);
-			subqueryNode.setPointOfAttachment(pointOfAttachment);
-		}
-	}
-
-	/**
-	 * Decrement (query block) level (0-based) for 
-	 * all of the tables in this subquery list.
-	 * This is useful when flattening a subquery.
-	 *
-	 * @param decrement	The amount to decrement by.
-	 *
-	 * @return Nothing;
-	 */
-	void decrementLevel(int decrement)
-	{
-		int size = size();
-
-		for (int index = 0; index < size; index++)
-		{
-			((SubqueryNode) elementAt(index)).getResultSet().decrementLevel(decrement);
-		}
-	}
-}
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package	org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;
+import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+/**
+ * A SubqueryList represents a list of subquerys within a specific clause 
+ * (select, where or having) in a DML statement.  It extends QueryTreeNodeVector.
+ *
+ * @author Jerry Brenner
+ */
+
+public class SubqueryList extends QueryTreeNodeVector
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+
+	/**
+	 * Prints the sub-nodes of this object.  See QueryTreeNode.java for
+	 * how tree printing is supposed to work.
+	 *
+	 * @param depth		The depth of this node in the tree
+	 *
+	 * @return	Nothing
+	 */
+
+	public void printSubNodes(int depth)
+	{
+		if (SanityManager.DEBUG)
+		{
+			SubqueryNode	subqueryNode;
+
+			super.printSubNodes(depth);
+
+			for (int index = 0; index < size(); index++)
+			{
+				subqueryNode = (SubqueryNode) elementAt(index);
+				subqueryNode.treePrint(depth + 1);
+			}
+		}
+	}
+
+	/**
+	 * Add a subquery to the list.
+	 *
+	 * @param subqueryNode	A SubqueryNode to add to the list
+	 *
+	 * @return	Nothing
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public void addSubqueryNode(SubqueryNode subqueryNode) throws StandardException
+	{
+		addElement(subqueryNode);
+	}
+
+	/**
+	 * Preprocess a SubqueryList.  For now, we just preprocess each SubqueryNode
+	 * in the list.
+	 *
+	 * @param	numTables			Number of tables in the DML Statement
+	 * @param	outerFromList		FromList from outer query block
+	 * @param	outerSubqueryList	SubqueryList from outer query block
+	 * @param	outerPredicateList	PredicateList from outer query block
+	 *
+	 * @return None.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public void preprocess(int numTables,
+							FromList outerFromList,
+							SubqueryList outerSubqueryList,
+							PredicateList outerPredicateList) 
+				throws StandardException
+	{
+		SubqueryNode	subqueryNode;
+
+		int size = size();
+		for (int index = 0; index < size; index++)
+		{
+			subqueryNode = (SubqueryNode) elementAt(index);
+			subqueryNode.preprocess(numTables, outerFromList,
+									outerSubqueryList,
+									outerPredicateList);
+		}
+	}
+
+	/**
+	 * Optimize the subqueries in this list.  
+	 *
+	 * @param dataDictionary	The data dictionary to use for optimization
+	 * @param outerRows			The optimizer's estimate of the number of
+	 *							times this subquery will be executed.
+	 *
+	 * @return	Nothing
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public void optimize(DataDictionary dataDictionary, double outerRows)
+			throws StandardException
+	{
+		int size = size();
+		for (int index = 0; index < size; index++)
+		{
+			SubqueryNode	subqueryNode;
+			subqueryNode = (SubqueryNode) elementAt(index);
+			subqueryNode.optimize(dataDictionary, outerRows);
+		}
+	}
+
+	/**
+	 * Modify the access paths for all subqueries in this list.
+	 *
+	 * @see ResultSetNode#modifyAccessPaths
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public void modifyAccessPaths()
+			throws StandardException
+	{
+		int size = size();
+		for (int index = 0; index < size; index++)
+		{
+			SubqueryNode	subqueryNode;
+			subqueryNode = (SubqueryNode) elementAt(index);
+			subqueryNode.modifyAccessPaths();
+		}
+	}
+
+	/**
+	 * Search to see if a query references the specifed table name.
+	 *
+	 * @param name		Table name (String) to search for.
+	 * @param baseTable	Whether or not name is for a base table
+	 *
+	 * @return	true if found, else false
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public boolean referencesTarget(String name, boolean baseTable)
+		throws StandardException
+	{
+		int size = size();
+		for (int index = 0; index < size; index++)
+		{
+			SubqueryNode	subqueryNode;
+
+			subqueryNode = (SubqueryNode) elementAt(index);
+			if (subqueryNode.isMaterializable())
+			{
+				continue;
+			}
+
+			if (subqueryNode.getResultSet().referencesTarget(name, baseTable))
+			{
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * Return true if the node references SESSION schema tables (temporary or permanent)
+	 *
+	 * @return	true if references SESSION schema tables, else false
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public boolean referencesSessionSchema()
+		throws StandardException
+	{
+		int size = size();
+		for (int index = 0; index < size; index++)
+		{
+			SubqueryNode	subqueryNode;
+
+			subqueryNode = (SubqueryNode) elementAt(index);
+
+			if (subqueryNode.getResultSet().referencesSessionSchema())
+			{
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * Set the point of attachment in all subqueries in this list.
+	 *
+	 * @param pointOfAttachment		The point of attachment
+	 *
+	 * @return Nothing.
+	 *
+	 * @exception StandardException			Thrown on error
+	 */
+	public void setPointOfAttachment(int pointOfAttachment)
+		throws StandardException
+	{
+		int size = size();
+
+		for (int index = 0; index < size; index++)
+		{
+			SubqueryNode	subqueryNode;
+
+			subqueryNode = (SubqueryNode) elementAt(index);
+			subqueryNode.setPointOfAttachment(pointOfAttachment);
+		}
+	}
+
+	/**
+	 * Decrement (query block) level (0-based) for 
+	 * all of the tables in this subquery list.
+	 * This is useful when flattening a subquery.
+	 *
+	 * @param decrement	The amount to decrement by.
+	 *
+	 * @return Nothing;
+	 */
+	void decrementLevel(int decrement)
+	{
+		int size = size();
+
+		for (int index = 0; index < size; index++)
+		{
+			((SubqueryNode) elementAt(index)).getResultSet().decrementLevel(decrement);
+		}
+	}
+}
+

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SubqueryNode.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SubqueryNode.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SubqueryNode.java	Fri Sep 24 10:33:20 2004
@@ -1,2304 +1,2304 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package	org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.services.context.ContextManager;
-
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.sql.compile.CompilerContext;
-import org.apache.derby.iapi.sql.compile.CostEstimate;
-import org.apache.derby.iapi.sql.compile.Visitable;
-import org.apache.derby.iapi.sql.compile.Visitor;
-import org.apache.derby.iapi.sql.compile.C_NodeTypes;
-
-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.types.DataTypeDescriptor;
-
-import org.apache.derby.iapi.sql.execute.ExecRow;
-
-import org.apache.derby.iapi.sql.Activation;
-import org.apache.derby.iapi.types.DataValueDescriptor;
-import org.apache.derby.iapi.sql.Row;
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-import org.apache.derby.iapi.sql.ResultSet;
-import org.apache.derby.iapi.types.TypeId;
-
-import org.apache.derby.iapi.services.loader.GeneratedMethod;
-
-import org.apache.derby.iapi.services.compiler.MethodBuilder;
-import org.apache.derby.iapi.services.compiler.LocalField;
-
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-import org.apache.derby.iapi.store.access.Qualifier;
-
-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.impl.sql.execute.OnceResultSet;
-
-import org.apache.derby.iapi.util.JBitSet;
-import org.apache.derby.iapi.util.ReuseFactory;
-import org.apache.derby.iapi.services.classfile.VMOpcode;
-
-import java.util.Properties;
-import java.util.Vector;
-
-/**
- * A SubqueryNode represents a subquery.  Subqueries return values to their
- * outer queries. An quantified subquery is one that appears under a quantified
- * operator (like IN or EXISTS) - quantified subqueries can return more than
- * one value per invocation. An expression subquery is one that is not directly
- * under a quantified operator - expression subqueries are allowed to return
- * at most one value per invocation (returning no value is considered to be
- * equivalent to returning NULL).
- *
- * There are a large number of subquery types.  Because of the large number of
- * types, and the large amount of shared code, we have decided to have 1 SubqueryNode
- * without any subclasses.  The subquery type (and operator) is encoded in the
- * subqueryType field.
- *
- * The query optimizer is responsible for optimizing subqueries, and also for
- * transforming them so that code can be generated for them. The optimizer may
- * eliminate some subqueries by transforming them into joins, or it may
- * change the internal form of a subquery (for example, transforming
- * 'where x in (select y from z where ...)' into
- * 'where (select true from z where x = y and ...)').
- *
- * Note that aggregates present some additional issues.  A transformation
- * such as:
- *	<UL> where x in (SELECT <I>expression</I> FROM z) </UL>
- * has to be treated specially if <I>expression</I> has an aggregate.
- * We change it to:
- *	<UL> where x = (SELECT true FROM (SELECT MAX(x) FROM z) WHERE SQLCOL1 = y) </UL>
- *
- * @author Jeff Lichtman
- */
-
-public class SubqueryNode extends ValueNode
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	/*
-	** This must be a single-column result set.  If the subquery is
-	** not quantified, it must also be a single-row result set - that is,
-	** expression subqueries are allowed to return only a single value
-	** per invocation.
-	** NOTE: SubqueryNodes are used as an intermediate step within the parser
-	** for building a derived table.  Derived tables can be multi-column and 
-	** multi-table.
-	*/
-	ResultSetNode	resultSet;
-
-	/* Type of this subquery */
-	int				subqueryType;
-
-	/* Whether or not this subquery is immediately under a top level AndNode.
-	 * (Important for subquery flattening.)
-	 */
-	boolean			underTopAndNode;
-
-	/* Whether or not we've been preprocessed. (Only do the work once.) */
-	boolean			preprocessed;
-
-	/* Whether or not this subquery began life as a distinct expression subquery */
-	boolean			distinctExpression;
-
-	/* Since we do not have separate subquery operator nodes, the
-	 * type of the subquery is stored in the subqueryType field.  Most subquery
-	 * types take a left operand (except for expression and exists).  We could
-	 * either add a leftOperand field here or subclass SubqueryNode for those
-	 * types that take a left operand.  We have decided to add the left operand
-	 * here for now.
-	 */
-	ValueNode		leftOperand;
-	boolean			pushedNewPredicate;
-
-	/* Expression subqueries on the right side of a BinaryComparisonOperatorNode
-	 * will get passed a pointer to that node prior to preprocess().  This
-	 * allows us to replace the entire comparison, if we want to, when
-	 * flattening.
-	 */
-	BinaryComparisonOperatorNode parentComparisonOperator;
-
-	/* Private fields (all references via private methods) - 
-	 * We reuse true BooleanConstantNodes within
-	 * this class, creating them on the first reference.
-	 */
-	private BooleanConstantNode trueNode;
-	/* Reuse generated code where possible */
-	//private Expression genResult;
-
-	/* Subquery # for this subquery */
-	private int subqueryNumber = -1;
-
-	/* ResultSet # for the point of attachment for this subquery */
-	private int pointOfAttachment = -1;
-
-	/* 
-	** Indicate whether we found a correlation or not.
-	** And track whether we have checked yet.
-	*/
-	private boolean foundCorrelation;
-	private boolean doneCorrelationCheck;
-
-	/* 
-	** Indicate whether we found an invariant node
-	** below us or not. And track whether we have 
-	** checked yet.
-	*/
-	private boolean foundVariant;
-	private boolean doneInvariantCheck;
-
-	/* Subquery types.
-	 * NOTE: FROM_SUBQUERY only exists for a brief second in the parser.  It
-	 * should never appear in a query tree.
-	 * NOTE: NOT EXISTS and NOT IN subquery types do not exist prior to NOT 
-	 * elimination during preprocessing.  Prior to that, there is a separate
-	 * NotNode above the SubqueryNode in the tree.
-	 *
-	 */
-	public final static int NOTIMPLEMENTED_SUBQUERY		= -1;
-	public final static int FROM_SUBQUERY	    = 0;
-	public final static int IN_SUBQUERY			= 1;
-	public final static int NOT_IN_SUBQUERY		= 2;
-	public final static int EQ_ANY_SUBQUERY		= 3;
-	public final static int EQ_ALL_SUBQUERY		= 4;
-	public final static int NE_ANY_SUBQUERY		= 5;
-	public final static int NE_ALL_SUBQUERY		= 6;
-	public final static int GT_ANY_SUBQUERY		= 7;
-	public final static int GT_ALL_SUBQUERY		= 8;
-	public final static int GE_ANY_SUBQUERY		= 9;
-	public final static int GE_ALL_SUBQUERY		= 10;
-	public final static int LT_ANY_SUBQUERY		= 11;
-	public final static int LT_ALL_SUBQUERY		= 12;
-	public final static int LE_ANY_SUBQUERY		= 13;
-	public final static int LE_ALL_SUBQUERY		= 14;
-	public final static int EXISTS_SUBQUERY		= 15;
-	public final static int NOT_EXISTS_SUBQUERY	= 16;
-	public final static int EXPRESSION_SUBQUERY = 17;
-
-
-	/**
-	 * Initializer.
-	 *
-	 * @param resultSet		The ResultSetNode for the subquery
-	 * @param subqueryType	The type of the subquery
-	 * @param leftOperand	The left operand, if any, of the subquery
-	 */
-
-	public void init(
-							Object resultSet,
-							Object subqueryType,
-							Object leftOperand)
-	{
-		this.resultSet = (ResultSetNode) resultSet;
-		this.subqueryType = ((Integer) subqueryType).intValue();
-
-		/* Subqueries are presumed not to be under a top level AndNode by
-		 * default.  This is because expression normalization only recurses
-		 * under Ands and Ors, not under comparison operators, method calls,
-		 * built-in functions, etc.
-		 */
-		underTopAndNode = false;
-		this.leftOperand = (ValueNode) leftOperand;
-	}
-
-	/**
-	 * Convert this object to a String.  See comments in QueryTreeNode.java
-	 * for how this should be done for tree printing.
-	 *
-	 * @return	This object as a String
-	 */
-
-	public String toString()
-	{
-		if (SanityManager.DEBUG)
-		{
-			return "subqueryType: " + subqueryType + "\n" +
-			   "underTopAndNode: " + underTopAndNode + "\n" +
-			   "subqueryNumber: " + subqueryNumber + "\n" +
-			   "pointOfAttachment: " + pointOfAttachment + "\n" +
-			   "preprocessed: " + preprocessed + "\n" +
-			   "distinctExpression: " + distinctExpression + "\n" +
-				super.toString();
-		}
-		else
-		{
-			return "";
-		}
-	}
-
-	/**
-	 * Prints the sub-nodes of this object.  See QueryTreeNode.java for
-	 * how tree printing is supposed to work.
-	 *
-	 * @param depth		The depth of this node in the tree
-	 *
-	 * @return	Nothing
-	 */
-
-	public void printSubNodes(int depth)
-	{
-		if (SanityManager.DEBUG)
-		{
-			super.printSubNodes(depth);
-
-			if (resultSet != null)
-			{
-				printLabel(depth, "resultSet: ");
-				resultSet.treePrint(depth + 1);
-			}
-
-			if (leftOperand != null)
-			{
-				printLabel(depth, "leftOperand: ");
-				leftOperand.treePrint(depth + 1);
-			}
-		}
-	}
-
-	/**
-	 * Return the resultSet for this SubqueryNode.
-	 *
-	 * @return ResultSetNode underlying this SubqueryNode.
-	 */
-	public ResultSetNode getResultSet()
-	{
-		return resultSet;
-	}
-
-	/**
-	 * Return the type of this subquery.
-	 *
-	 * @return int	Type of this subquery.
-	 */
-	public int getSubqueryType()
-	{
-		return subqueryType;
-	}
-
-	/**
-	 * Set the type of this subquery.
-	 *
-	 * @param Type of this subquery.
-	 *
-	 * @return None.
-	 */
-	public void setSubqueryType(int subqueryType)
-	{
-		this.subqueryType = subqueryType;
-	}
-
-	/**
-	 * Set the point of attachment of this subquery.
-	 *
-	 * @param pointOfAttachment	The point of attachment of this subquery.
-	 *
-	 * @return None.
-	 *
-	 * @exception StandardException			Thrown on error
-	 */
-	public void setPointOfAttachment(int pointOfAttachment)
-		throws StandardException
-	{
-		/* Materialized subqueries always keep their point of
-		 * attachment as -1.
-		 */
-		if (! isMaterializable())
-		{
-			this.pointOfAttachment = pointOfAttachment;
-		}
-	}
-
-	/**
-	 * Return whether or not this subquery is immediately under a top level
-	 * AndNode.
-	 *
-	 * @return boolean	Whether or not this subquery is immediately under a
-	 *					top level AndNode.
-	 */
-	public boolean getUnderTopAndNode()
-	{
-		return underTopAndNode;
-	}
-
-	/**
-	 * Get the ResultSet # for the point of attachment for this SubqueryNode.
-	 *
-	 * @return int		The ResultSet # for the point of attachment
-	 */
-	public int getPointOfAttachment()
-	{
-		if (SanityManager.DEBUG)
-		{
-			SanityManager.ASSERT(pointOfAttachment >= 0,
-				"pointOfAttachment expected to be >= 0");
-		}
-		return pointOfAttachment;
-	}
-
-	/**
-	 * Get whether or not this SubqueryNode has already been
-	 * preprocessed.
-	 * 
-	 * @return	Whether or not this SubqueryNode has already been
-	 *			preprocessed.
-	 */
-	boolean getPreprocessed()
-	{
-		return preprocessed;
-	}
-
-	/**
-	 * Set the parent BCON.  Useful when considering flattening
-	 * expression subqueries.
-	 *
-	 * @param parent	The parent BCON.
-	 *
-	 * @return Nothing.
-	 */
-  	void setParentComparisonOperator(BinaryComparisonOperatorNode parent)
-  	{
-  		parentComparisonOperator = parent;
-  	}
-
-	/**
-	 * Remap all ColumnReferences in this tree to be clones of the
-	 * underlying expression.
-	 *
-	 * @return ValueNode			The remapped expression tree.
-	 *
-	 * @exception StandardException			Thrown on error
-	 */
-	public ValueNode remapColumnReferencesToExpressions()
-		throws StandardException
-	{
-		/* We need to remap both the SELECT and Predicate lists 
-		 * since there may be correlated columns in either of them.
-		 */
-		if (resultSet instanceof SelectNode)
-		{
-			ResultColumnList selectRCL = resultSet.getResultColumns();
-			SelectNode		 select = (SelectNode) resultSet;
-			PredicateList	 selectPL = select.getWherePredicates();
-
-			if (SanityManager.DEBUG)
-			{
-				SanityManager.ASSERT(selectPL != null,
-					"selectPL expected to be non-null");
-			}
-			selectRCL.remapColumnReferencesToExpressions();
-			selectPL.remapColumnReferencesToExpressions();
-		}
-		return this;
-	}
-
-	/**
-	 * Bind this expression.  This means binding the sub-expressions,
-	 * as well as figuring out what the return type is for this expression.
-	 *
-	 * @param fromList			The FROM list for the query this
-	 *							expression is in, for binding columns.
-	 *							NOTE: fromList will be null if the subquery appears
-	 *							in a VALUES clause.
-	 * @param subqueryList		The subquery list being built as we find SubqueryNodes
-	 * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
-	 *
-	 * @return	The new top of the expression tree.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public ValueNode bindExpression(FromList fromList, SubqueryList subqueryList,
-					Vector	aggregateVector)
-				throws StandardException
-	{
-		ResultColumnList	resultColumns;
-
-		//check if subquery is allowed in expression tree
-		checkReliability( CompilerContext.SUBQUERY_ILLEGAL, SQLState.LANG_SUBQUERY );
-
-		resultColumns = resultSet.getResultColumns();
-
-		/* The parser does not enforce the fact that a subquery can only return
-		 * a single column, so we must check here.
-		 */
-		if (resultColumns.size() != 1)
-		{
-			throw StandardException.newException(SQLState.LANG_NON_SINGLE_COLUMN_SUBQUERY);
-		}
-
-		/* Verify the usage of "*" in the select list:
-		 *	o  Only valid in EXISTS subqueries
-		 *	o  If the AllResultColumn is qualified, then we have to verify
-		 *	   that the qualification is a valid exposed name.
-		 *	   NOTE: The exposed name can come from an outer query block.
-		 */
-		resultSet.verifySelectStarSubquery(fromList, subqueryType);
-
-		/* For an EXISTS subquery:
-		 *	o  If the SELECT list is a "*", then we convert it to a true.
-		 *	   (We need to do the conversion since we don't want the "*" to
-		 *	   get expanded.)
-		 *  o  We then must bind the expression under the SELECT list to
-		 *	   verify that it is a valid expression.  (We must do this as a
-		 *	   separate step because we need to validate the expression and
-		 *	   we need to handle EXISTS (select * ... union all select 1 ...)
-		 *	   without getting a type compatability error.)
-		 *	o  Finally, we convert the expression to a SELECT true.
-		 */
-		if (subqueryType == EXISTS_SUBQUERY)
-		{
-			/* Transform the * into true (EXISTS). */
-			resultSet.setResultToBooleanTrueNode(true);
-		}
-
-		/* We need to bind the tables before we can bind the target list
-		 * (for exists subqueries).  However, we need to wait until after
-		 * any *'s have been replaced, so that they don't get expanded.
-		 */
-		CompilerContext cc = getCompilerContext();
-
-		resultSet = resultSet.bindNonVTITables(getDataDictionary(), fromList);
-		resultSet = resultSet.bindVTITables(fromList);
-
-		/* Set the subquery # for this SubqueryNode */
-		if (subqueryNumber == -1)
-			subqueryNumber = cc.getNextSubqueryNumber();
-
-		/* reject ? parameters in the select list of subqueries */
-		resultSet.rejectParameters();
-
-		if (subqueryType == EXISTS_SUBQUERY)
-		{
-			/* Bind the expression in the SELECT list */
-			resultSet.bindTargetExpressions(fromList);
-
-			/* Transform the ResultColumn into true.
-			 * NOTE: This may be a 2nd instance of the same transformation for
-			 * an EXISTS (select * ...), since we had to transform the 
-			 * AllResultColumn above, but we have to also handle
-			 * EXISTS (select r from s ...)
-			 */
-			resultSet.setResultToBooleanTrueNode(false);
-		}
-
-		/* bind the left operand, if there is one */
-		if (leftOperand != null)
-		{
-			leftOperand = leftOperand.bindExpression(fromList, subqueryList,
-									   aggregateVector);
-		}
-
-		/* bind the expressions in the underlying subquery */
-		resultSet.bindExpressions(fromList);
-
-		resultSet.bindResultColumns(fromList);
-
-		/* We need to reset resultColumns since the underlying resultSet may
-		 * be a UNION (and UnionNode.bindResultColumns() regens a new RCL).
-		 */
-		resultColumns = resultSet.getResultColumns();
-
-		/*
-		 * A ? parameter to the left of this subquery gets type of the
-		 * subquery's sole column.
-		 */
-		if (leftOperand != null && leftOperand.isParameterNode())
-		{
-			((ParameterNode) leftOperand).setDescriptor(
-				((ResultColumn) resultColumns.elementAt(0)).getTypeServices());
-		}
-
-		// Set the DataTypeServices
-		setDataTypeServices(resultColumns);
-
-		/* Add this subquery to the subquery list */
-		subqueryList.addSubqueryNode(this);
-
-		return this;
-	}
-
-	/**
-	 * Preprocess an expression tree.  We do a number of transformations
-	 * here (including subqueries, IN lists, LIKE and BETWEEN) plus
-	 * subquery flattening.
-	 * NOTE: This is done before the outer ResultSetNode is preprocessed.
-	 *
-	 * @param	numTables			Number of tables in the DML Statement
-	 * @param	outerFromList		FromList from outer query block
-	 * @param	outerSubqueryList	SubqueryList from outer query block
-	 * @param	outerPredicateList	PredicateList from outer query block
-	 *
-	 * @return		The modified expression
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public ValueNode preprocess(int numTables,
-								FromList outerFromList,
-								SubqueryList outerSubqueryList,
-								PredicateList outerPredicateList) 
-					throws StandardException
-	{
-		/* Only preprocess this node once.  We may get called multiple times
-		 * due to tree transformations.
-		 */
-		if (preprocessed)
-		{
-			return this;
-		}
-		preprocessed = true;
-
-		boolean		flattenable;
-		ValueNode	topNode = this;
-
-		resultSet = resultSet.preprocess(numTables, null, (FromList) null);
-
-		// Eliminate any unnecessary DISTINCTs
-		if (resultSet instanceof SelectNode)
-		{
-			if (((SelectNode) resultSet).hasDistinct())
-			{
-				((SelectNode) resultSet).clearDistinct();
-				/* We need to remember to check for single unique value
-				 * at execution time for expression subqueries.
-				 */
-				if  (subqueryType == EXPRESSION_SUBQUERY)
-				{
-					distinctExpression = true;
-				}
-			}
-		}
-
-		/* Lame transformation - For IN/ANY subqueries, if
-		 * result set is guaranteed to return at most 1 row
-		 * and it is not correlated
-		 * then convert the subquery into the matching expression
-		 * subquery type.  For example:
-		 *	c1 in (select min(c1) from t2)
-		 * becomes:
-		 *	c1 = (select min(c1) from t2)
-		 * (This actually showed up in an app that a potential customer
-		 * was porting from SQL Server.)
-		 * The transformed query can then be flattened if appropriate.
-		 */
-		if ((isIN() || isANY()) &&
-			resultSet.returnsAtMostOneRow())
-		{
-			if (! hasCorrelatedCRs())
-			{
-				changeToCorrespondingExpressionType();
-			}
-		}
-
-		/* NOTE: Flattening occurs before the pushing of
-		 * the predicate, since the pushing will add a node 
-		 * above the SubqueryNode.
-		 */
-
-		/* Values subquery is flattenable if:
-		 *  o It is not under an OR.
-		 *  o It is an expression subquery on the right side
-		 *	  of a BinaryComparisonOperatorNode.
-		 */
-		flattenable = (resultSet instanceof RowResultSetNode) &&
-					  underTopAndNode &&
-					  parentComparisonOperator instanceof BinaryComparisonOperatorNode;
-		if (flattenable)
-		{
-			/* If we got this far and we are an expression subquery
-			 * then we want to set leftOperand to be the left side
-			 * of the comparison in case we pull the comparison into
-			 * the flattened subquery.
-			 */
-			leftOperand = parentComparisonOperator.getLeftOperand();
-			// Flatten the subquery
-			RowResultSetNode rrsn = (RowResultSetNode) resultSet;
-			FromList   fl = new FromList();
-
-			// Remove ourselves from the outer subquery list
-			outerSubqueryList.removeElement(this);
-
-			/* We only need to add the table from the subquery into 
-			 * the outer from list if the subquery itself contains
-			 * another subquery.  Otherwise, it just becomes a constant.
-			 */
-			if (rrsn.subquerys.size() != 0)
-			{
-				fl.addElement(rrsn);
-				outerFromList.destructiveAppend(fl);
-			}
-
-			/* Append the subquery's subquery list to the 
-			 * outer subquery list.
-			 */
-			outerSubqueryList.destructiveAppend(rrsn.subquerys);
-
-			/* return the new join condition 
-			 * If we are flattening an EXISTS then there is no new join
-			 * condition since there is no leftOperand.  Simply return
-			 * TRUE.
-			 *
-			 * NOTE: The outer where clause, etc. has already been normalized,
-			 * so we simply return the BinaryComparisonOperatorNode above
-			 * the new join condition.
-			 */
-			ValueNode rightOperand;
-			rightOperand = ((ResultColumn) rrsn.getResultColumns().elementAt(0)).
-								getExpression();
-			return getNewJoinCondition(leftOperand, rightOperand);
-		}
-
-		/* Select subquery is flattenable if:
-		 *  o It is not under an OR.
-		 *  o The subquery type is IN, ANY or EXISTS or
-		 *    an expression subquery on the right side
-		 *	  of a BinaryComparisonOperatorNode.
-		 *  o There are no aggregates in the select list
-		 *  o There is no group by clause
-		 *  o There is a uniqueness condition that ensures
-		 *	  that the flattening of the subquery will not
-		 *	  introduce duplicates into the result set.
-		 *
-		 *	OR,
-		 *  o The subquery is NOT EXISTS, NOT IN, ALL (beetle 5173).
-		 */
-		boolean flattenableNotExists = (isNOT_EXISTS() || canAllBeFlattened());
-
-		flattenable = (resultSet instanceof SelectNode) &&
-					  underTopAndNode &&
-					  (isIN() || isANY() || isEXISTS() || flattenableNotExists ||
-                       parentComparisonOperator != null);
-
-		if (flattenable)
-		{
-			SelectNode	select = (SelectNode) resultSet;
-			if ((select.getAggregateVector(IN_SELECT_LIST).size() == 0) &&
-				(! select.getGeneratedForGroupbyClause()))
-			{
-				ValueNode origLeftOperand = leftOperand;
-
-				/* Check for uniqueness condition. */
-				/* Is the column being returned by the subquery
-				 * a candidate for an = condition?
-				 */
-				boolean additionalEQ =
-							(subqueryType == IN_SUBQUERY) ||
-							(subqueryType == EQ_ANY_SUBQUERY);
-
-
-				additionalEQ = additionalEQ &&
-								((leftOperand instanceof ConstantNode) ||
-								 (leftOperand instanceof ColumnReference) ||
-
-								 (leftOperand.isParameterNode()));
-				/* If we got this far and we are an expression subquery
-				 * then we want to set leftOperand to be the left side
-				 * of the comparison in case we pull the comparison into
-				 * the flattened subquery.
-				 */
-				if (parentComparisonOperator instanceof BinaryComparisonOperatorNode)
-				{
-					leftOperand = parentComparisonOperator.getLeftOperand();
-				}
-				/* Never flatten to normal join for NOT EXISTS.
-				 */
-				if ((! flattenableNotExists) && select.uniqueSubquery(additionalEQ))
-				{
-					// Flatten the subquery
-					return flattenToNormalJoin(numTables,
-										   outerFromList, outerSubqueryList,
-										   outerPredicateList);
-				}
-				/* We can flatten into an EXISTS join if all of the above
-				 * conditions except for a uniqueness condition are true
-				 * and:
-				 *	o Subquery only has a single entry in its from list
-				 *	  and that entry is a FromBaseTable
-				 *	o All predicates in the subquery's where clause are
-				 *	  pushable.
-				 *  o The leftOperand, if non-null, is pushable.
-				 * If the subquery meets these conditions then we will flatten
-				 * the FBT into an EXISTS FBT, pushd the subquery's
-				 * predicates down to the PRN above the EBT and
-				 * mark the predicates to say that they cannot be pulled 
-				 * above the PRN. (The only way that we can guarantee correctness
-				 * is if the predicates do not get pulled up.  If they get pulled
-				 * up then the single next logic for an EXISTS join does not work
-				 * because that row may get disqualified at a higher level.)
-				 */
-				else if ( (isIN() || isANY() || isEXISTS() || flattenableNotExists) &&
-						  ((leftOperand == null) ? true :
-							 leftOperand.categorize(new JBitSet(numTables), false)) &&
-						  select.getWherePredicates().allPushable() &&
-						  singleFromBaseTable(select.getFromList()))
-				{
-					return flattenToExistsJoin(numTables,
-										   outerFromList, outerSubqueryList,
-										   outerPredicateList, flattenableNotExists);
-				}
-
-				// restore leftOperand to its original value
-				leftOperand = origLeftOperand;
-			}
-		}
-
-		/* We transform the leftOperand and the select list for quantified 
-		 * predicates that have a leftOperand into a new predicate and push it
-		 * down to the subquery after we preprocess the subquery's resultSet.
-		 * We must do this after preprocessing the underlying subquery so that
-		 * we know where to attach the new predicate.
-		 * NOTE - If we pushed the predicate before preprocessing the underlying
-		 * subquery, then the point of attachment would depend on the form of
-		 * that subquery.  (Where clause?  Having clause?)
-		 */
-		if (leftOperand != null)
-		{
-			topNode = pushNewPredicate(numTables);
-			pushedNewPredicate = true;
-		}
-		/* Since NOT EXISTS subquery is not flattened, now is good time to create
-		 * an IS NULL node on top.  Other cases are taken care of in pushNewPredicate.
-		 */
-		else if (subqueryType == NOT_EXISTS_SUBQUERY)
-		{
-			topNode = genIsNullTree();
-			subqueryType = EXISTS_SUBQUERY;
-		}
-
-		/*
-		** Do inVariant and correlated checks now.  We
-		** aren't going to use the results here, but they
-		** have been stashed away by isInvariant() and hasCorrelatedCRs()
-		*/
-		isInvariant();
-		hasCorrelatedCRs();
-
-		/* If parentComparisonOperator is non-null then we are an
-		 * expression subquery that was considered to be a candidate 
-		 * for flattening, but we didn't get flattened.  In that case
-		 * we are the rightOperand of the parent.  We need to update
-		 * the parent's rightOperand with the new topNode and return
-		 * the parent because the parent is letting us decide whether
-		 * or not to replace the entire comparison, which we can do
-		 * if we flatten.  Otherwise we simply return the new top node.
-		 */
-		if (parentComparisonOperator != null)
-		{
-			parentComparisonOperator.setRightOperand(topNode);
-			return parentComparisonOperator;
-		}
-
-		return topNode;
-	}
-
-	/**
-	 * Does the from list from the subquery contain a
-	 * single entry which is a FBT or a PRN/FBT.
-	 *
-	 * @param fromList	The from list from the subquery
-	 *
-	 * @return Whether or not the from list from the subquery contains a
-	 *			single entry which is a FBT or a PRN/FBT.
-	 */
-	private boolean singleFromBaseTable(FromList fromList)
-	{
-		boolean retCode = (fromList.size() == 1);
-
-		if (retCode)
-		{
-			FromTable ft = (FromTable) fromList.elementAt(0);
-
-			if (((ft instanceof ProjectRestrictNode) &&
-				 ((ProjectRestrictNode) ft).getChildResult() instanceof FromBaseTable) ||
-				ft instanceof FromBaseTable)
-			{
-			}
-			else
-			{
-				retCode = false;
-			}
-		}
-
-		return retCode;
-	}
-
-	/**
-	 * Can NOT IN, ALL be falttened to NOT EXISTS join?  We can't or the flattening doesn't
-	 * easily make sense if either side of the comparison is nullable. (beetle 5173)
-	 *
-	 * @return Whether or not the NOT IN or ALL subquery can be flattened.
-	 */
-	private boolean canAllBeFlattened ()
-	{
-		boolean result = false;
-		if (isNOT_IN() || isALL())
-		{
-			ValueNode rightOperand = ((ResultColumn) resultSet.getResultColumns().elementAt(0)).
-									getExpression();
-			result = (! leftOperand.getTypeServices().isNullable() &&
-						! rightOperand.getTypeServices().isNullable());
-		}
-		return result;
-	}
-
-	/**
-	 * Flatten this subquery into the outer query block.  
-	 * At this point we are only flattening based on a uniqueness
-	 * condition and only flattening non-aggregate subqueries.
-	 * So, we promote the subquery's from list, as is, into 
-	 * the outer from list.  For EXISTS subquerys, we return a 
-	 * TRUE.  Otherwise we return a new comparison between
-	 * the leftOperand and the expression in the subquery's
-	 * SELECT list.
-	 * RESOLVE - we will need to modify this logic to account
-	 * for exists joins and aggregates as we support flattening
-	 * for them.
-	 *
-	 * Anyway, here's what we do:
-	 *	o We remove ourself from the outer subquery list.
-	 *	o We decrement the nesting level for all tables
-	 *	  in the subquery tree.
-	 *	o We append the subquery's from list to the outer
-	 *	  from list.
-	 *	o We add the subquery's predicate list to the outer
-	 *	  predicate list.  (The subquery has already been
-	 *	  preprocessed.)
-	 *  o We add the subquery's subquery list to the outer
-	 *	  subquery list.
-	 *	o For EXISTS, we return a true.
-	 *	o Otherwise, we return a new comparison between the
-	 *	  leftOperand and the expression in the inner select's
-	 *	  RCL.
-	 *
-	 * @param	numTables			Number of tables in the DML Statement
-	 * @param	outerFromList		FromList from outer query block
-	 * @param	outerSubqueryList	SubqueryList from outer query block
-	 * @param	outerPredicateList	PredicateList from outer query block
-	 *
-	 * @return	The modified expression
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	private ValueNode flattenToNormalJoin(int numTables,
-										  FromList outerFromList, 
-										  SubqueryList outerSubqueryList,
-										  PredicateList outerPredicateList)
-		throws StandardException
-	{
-		SelectNode select = (SelectNode) resultSet;
-		FromList   fl = select.getFromList();
-		int[] tableNumbers = fl.getTableNumbers();
-
-		// Remove ourselves from the outer subquery list
-		outerSubqueryList.removeElement(this);
-
-		/* Decrease the nesting level for all
-		 * tables in the subquey tree.
-		 */
-		select.decrementLevel(1);
-
-		/* Add the table(s) from the subquery into the outer from list */
-		outerFromList.destructiveAppend(fl);
-
-		/* Append the subquery's predicate list to the
-		 * outer predicate list.
-		 */
-		outerPredicateList.destructiveAppend(select.getWherePredicates());
-
-		/* Append the subquery's subquery list to the 
-		 * outer subquery list.
-		 * NOTE: We must propagate any subqueries from both the
-		 * SELECT list and WHERE clause of the subquery that's
-		 * getting flattened.
-		 */
-		outerSubqueryList.destructiveAppend(select.getWhereSubquerys());
-		outerSubqueryList.destructiveAppend(select.getSelectSubquerys());
-
-		/* return the new join condition 
-		 * If we are flattening an EXISTS then there is no new join
-		 * condition since there is no leftOperand.  Simply return
-		 * TRUE.
-		 *
-		 * NOTE: The outer where clause, etc. has already been normalized,
-		 * so we simply return the BinaryComparisonOperatorNode above
-		 * the new join condition.
-		 */
-		if (leftOperand == null)
-		{
-			return (ValueNode) getNodeFactory().getNode(
-											C_NodeTypes.BOOLEAN_CONSTANT_NODE,
-											Boolean.TRUE,
-											getContextManager());
-		}
-		else
-		{
-			ValueNode rightOperand;
-			rightOperand = ((ResultColumn) select.getResultColumns().elementAt(0)).
-								getExpression();
-			/* If the right operand is a CR, then we need to decrement
-			 * its source level as part of flattening so that
-			 * transitive closure will work correctly.
-			 */
-			if (rightOperand instanceof ColumnReference)
-			{
-				ColumnReference cr = (ColumnReference) rightOperand;
-				int tableNumber = cr.getTableNumber();
-				for (int index = 0; index < tableNumbers.length; index++)
-				{
-					if (tableNumber == tableNumbers[index])
-					{
-						cr.setSourceLevel(
-							cr.getSourceLevel() - 1);
-						break;
-					}
-				}
-			}
-			return getNewJoinCondition(leftOperand, rightOperand);
-		}
-	}
-
-	/**
-	 * Flatten this subquery into the outer query block
-	 * as an exists join.  
-	 * At this point we are only flattening non-aggregate subqueries
-	 * with a single FBT in the from list.
-	 * So, we transform all FBTs in the from list into ExistBaseTables,
-	 * update the dependency lists for each of the tables and then
-	 * flatten the subquery.
-	 * RESOLVE - we will need to modify this logic to account
-	 * for aggregates as we support flattening
-	 * for them.
-	 *
-	 * @param	numTables			Number of tables in the DML Statement
-	 * @param	outerFromList		FromList from outer query block
-	 * @param	outerSubqueryList	SubqueryList from outer query block
-	 * @param	outerPredicateList	PredicateList from outer query block
-	 * @param	flattenableNotExists Is it a flattening into a NOT EXISTS join
-	 *
-	 * @return	The modified expression
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	private ValueNode flattenToExistsJoin(int numTables,
-										  FromList outerFromList, 
-										  SubqueryList outerSubqueryList,
-										  PredicateList outerPredicateList,
-										  boolean flattenableNotExists)
-		throws StandardException
-	{
-		SelectNode select = (SelectNode) resultSet;
-
-		// Replace the FromBaseTables in the from list with ExistBaseTables
-		select.getFromList().genExistsBaseTables(resultSet.getReferencedTableMap(),
-				outerFromList, flattenableNotExists);
-
-		/* NOTE: Because we are currently only flattening single table subqueries
-		 * whose predicates are all pushable, we simply follow the rest of the
-		 * flattening algorithm for unique subqueries.  Should we decide to 
-		 * loosen these restrictions then we need to do more work such as:
-		 *
-		 * Mark all of the predicates from the subquery as non-pullable. They must
-		 * not be pulled so that we can guarantee correctness.  Otherwise, we could
-		 * add or subtract rows from the result set.
-		 *
-		 * Remap all of the non-correlated CRs in the predicate list so that they
-		 * point to the correct source.  (We've chopped a level out of the RCL/VCN
-		 * chain.)  We then transfer those predicates to the PRN in the subquery's
-		 * from list.
-		 */
-
-		return flattenToNormalJoin(numTables, outerFromList,
-								   outerSubqueryList, outerPredicateList);
-	}
-
-	/**
-	 * Check to see if we have a Variant value below us.
-	 * If so, return true.  Caches the result so multiple
-	 * calls are ok.
-	 *  
-	 * @return boolean whether we have 
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	private boolean isInvariant() throws StandardException
-	{
-		if (doneInvariantCheck)
-		{
-			return !foundVariant;
-		}
-
-		doneInvariantCheck = true;
-		HasVariantValueNodeVisitor visitor = new HasVariantValueNodeVisitor();
-		resultSet.accept(visitor);
-		foundVariant = visitor.hasVariant();
-		return !foundVariant;
-	}
-
-	/**
-	 * Check to see if this subquery has correlated
-	 * column references.  Only useful results if
-	 * called AFTER binding (after CRs have been bound).
-	 *
-	 * @return whether the subquery has correlated column
-	 *	references.
-	 * @exception StandardException		Thrown on error
-	 */
-	public boolean hasCorrelatedCRs() throws StandardException
-	{
-		if (doneCorrelationCheck)
-		{
-			return foundCorrelation;
-		}
-		doneCorrelationCheck = true;
-
-		ResultSetNode realSubquery = resultSet;
-		ResultColumnList oldRCL = null;
-
-		/* If we have pushed the new join predicate on top, we want to disregard it
-		 * to see if anything under the predicate is correlated.  If nothing correlated
-		 * under the new join predicate, we could then materialize the subquery.
-		 * See beetle 4373.
-		 */
-		if (pushedNewPredicate)
-		{
-			if (SanityManager.DEBUG)
-			{
-				SanityManager.ASSERT(resultSet instanceof ProjectRestrictNode,
-					"resultSet expected to be a ProjectRestrictNode!");
-			}
-
-			realSubquery = ((ProjectRestrictNode) resultSet).getChildResult();
-			oldRCL = realSubquery.getResultColumns();
-
-			/* Only first column matters.
-			 */
-			if (oldRCL.size() > 1)
-			{
-				ResultColumnList newRCL = new ResultColumnList();
-				newRCL.addResultColumn(oldRCL.getResultColumn(1));
-				realSubquery.setResultColumns(newRCL);
-			}
-		}
-
-		HasCorrelatedCRsVisitor visitor = new HasCorrelatedCRsVisitor();
-		realSubquery.accept(visitor);
-		foundCorrelation = visitor.hasCorrelatedCRs();
-
-		if (pushedNewPredicate && (oldRCL.size() > 1))
-		{
-			realSubquery.setResultColumns(oldRCL);
-		}
-
-		return foundCorrelation;
-	}
-				
-	/**
-	 * Transform:
-	 *		expresion QuantifiedOperator (select x from ...)
-	 * into
-	 *		(select true from .. where expression <BinaryComparisonOperator> x ...)
-	 *		IS [NOT] NULL
-	 *
-	 * or, if we have an aggregate:
-	 *		(select true from 
-	 *			(select AGG(x) from ...)
-	 *		where expression <BinaryComparisonOperator> x ...)
-	 *		IS [NOT] NULL
-	 *
-	 *
-	 * For ANY and IN subqueries:
-	 *		o  We generate an IS NULL above the SubqueryNode and return the top of
-	 *		   the new tree to the caller.
-	 *		o  The operator in the new predicate that is added to the subquery
-	 *		   will correspond to the operator that modifies the ANY.
-	 *		   (eg, = for = ANY, with = for IN.)
-	 * For ALL and NOT IN subqueries:
-	 *		o  We generate an IS NOT NULL above the SubqueryNode and return the top of
-	 *		   the new tree to the caller.
-	 *		o  The operator in the new predicate that is added to the subquery
-	 *		   will be a BinaryAllOperatorNode whose bcoNodeType corresponds to 
-	 *		   the negation of the operator that modifies the ALL.
-	 *		   (eg, <> for = ALL, with <> for NOT IN.)
-	 *
-	 * NOTE: This method is called after the underlying subquery has been
-	 * preprocessed, so we build a new Predicate, not just a new expression.
-	 *
-	 * @param numTables			Number of tables in DML Statement
-	 *
-	 * @return UnaryComparisonOperatorNode	An IS [NOT] NULL above the 
-	 *										transformed subquery.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	private UnaryComparisonOperatorNode pushNewPredicate(
-				int numTables)
-			throws StandardException
-	{
-		AndNode						andNode;
-		BinaryComparisonOperatorNode bcoNode = null;
-		JBitSet						tableMap;
-		Predicate					predicate;
-		ResultColumn				firstRC;
-		ResultColumnList			resultColumns;
-		UnaryComparisonOperatorNode	ucoNode = null;
-		ValueNode					oldWhereClause;
-		ValueNode					rightOperand;
-
-		/* We have to ensure that the resultSet immediately under us has
-		 * a PredicateList, otherwise we can't push the predicate down.
-		 */
-		resultSet = resultSet.ensurePredicateList(numTables);
-
-		/* RESOLVE - once we understand how correlated columns will work, 
-		 * we probably want to mark leftOperand as a correlated column
-		 */
-		resultColumns = resultSet.getResultColumns();
-
-		/*
-		** Create a new PR node.  Put it over the original subquery.  resulSet
-		** is now the new PR.  We give the chance that things under the PR node
-		** can be materialized.  See beetle 4373.
-		*/
-		ResultColumnList newRCL = resultColumns.copyListAndObjects();
-		newRCL.genVirtualColumnNodes(resultSet, resultColumns);
-		resultSet = (ResultSetNode) getNodeFactory().getNode(
-										C_NodeTypes.PROJECT_RESTRICT_NODE,
-										resultSet,	// child
-										newRCL,			// result columns
-										null,			// restriction
-										null, 			// restriction list
-										null,			// project subqueries
-										null,			// restrict subqueries	
-										null,
-										getContextManager());
-		resultColumns = newRCL;
-	
-		firstRC = (ResultColumn) resultColumns.elementAt(0);
-		rightOperand = firstRC.getExpression();
-
-		bcoNode = getNewJoinCondition(leftOperand, rightOperand);
-
-		ValueNode andLeft = bcoNode;
-
-		/* For NOT IN or ALL, and if either side of the comparison is nullable, and the
-		 * subquery can not be flattened (because of that), we need to add IS NULL node
-		 * on top of the nullables, such that the behavior is (beetle 5173):
-		 *
-		 *    (1) If we have nulls in right operand, no row is returned.
-		 *    (2) If subquery result is empty before applying join predicate, every
-		 *		  left row (including NULLs) is returned.
-		 *	  (3) Otherwise, return {all left row} - {NULLs}
-		 */
-		if (isNOT_IN() || isALL())
-		{
-			boolean leftNullable = leftOperand.getTypeServices().isNullable();
-			boolean rightNullable = rightOperand.getTypeServices().isNullable();
-			if (leftNullable || rightNullable)
-			{
-				/* Create a normalized structure.
-				 */
-				BooleanConstantNode falseNode = (BooleanConstantNode) getNodeFactory().getNode(
-												C_NodeTypes.BOOLEAN_CONSTANT_NODE,
-												Boolean.FALSE,
-												getContextManager());
-				OrNode newOr = (OrNode) getNodeFactory().getNode(
-												C_NodeTypes.OR_NODE,
-												bcoNode,
-												falseNode,
-												getContextManager());
-				newOr.postBindFixup();
-				andLeft = newOr;
-
-				if (leftNullable)
-				{
-					UnaryComparisonOperatorNode leftIsNull = (UnaryComparisonOperatorNode)
-									getNodeFactory().getNode(
-														C_NodeTypes.IS_NULL_NODE,
-														leftOperand,
-														getContextManager());
-					leftIsNull.bindComparisonOperator();
-					newOr = (OrNode) getNodeFactory().getNode(
-													C_NodeTypes.OR_NODE,
-													leftIsNull,
-													andLeft,
-													getContextManager());
-					newOr.postBindFixup();
-					andLeft = newOr;
-				}
-				if (rightNullable)
-				{
-					UnaryComparisonOperatorNode rightIsNull = (UnaryComparisonOperatorNode)
-									getNodeFactory().getNode(
-														C_NodeTypes.IS_NULL_NODE,
-														rightOperand,
-														getContextManager());
-					rightIsNull.bindComparisonOperator();
-					newOr = (OrNode) getNodeFactory().getNode(
-													C_NodeTypes.OR_NODE,
-													rightIsNull,
-													andLeft,
-													getContextManager());
-					newOr.postBindFixup();
-					andLeft = newOr;
-				}
-			}
-		}
-
-		/* Place an AndNode above the <BinaryComparisonOperator> */
-		andNode = (AndNode) getNodeFactory().getNode(
-													C_NodeTypes.AND_NODE,
-													andLeft,
-													getTrueNode(),
-													getContextManager());
-
-		/* Build the referenced table map for the new predicate */
-		tableMap = new JBitSet(numTables);
-		andNode.postBindFixup();
-
-		/* Put the AndNode under a Predicate */
-		predicate = (Predicate) getNodeFactory().getNode(
-										C_NodeTypes.PREDICATE,
-										andNode,
-										tableMap,
-										getContextManager());
-		predicate.categorize();
-
-		/* Push the new Predicate to the subquery's list */
-		resultSet = resultSet.addNewPredicate(predicate);
-
-		/* Clean up the leftOperand and subquery ResultColumn */
-		leftOperand = null;
-		firstRC.setType(getTypeServices());
-		firstRC.setExpression(getTrueNode());
-
-		/* Add the IS [NOT] NULL above the SubqueryNode */
-		switch (subqueryType)
-		{
-			case IN_SUBQUERY:
-			case EQ_ANY_SUBQUERY:
-			case NE_ANY_SUBQUERY:
-			case LE_ANY_SUBQUERY:
-			case LT_ANY_SUBQUERY:
-			case GE_ANY_SUBQUERY:
-			case GT_ANY_SUBQUERY:
-				ucoNode = (UnaryComparisonOperatorNode) 
-									getNodeFactory().getNode(
-												C_NodeTypes.IS_NOT_NULL_NODE,
-												this,
-												getContextManager());
-				break;
-
-			case NOT_IN_SUBQUERY:
-			case EQ_ALL_SUBQUERY:
-			case NE_ALL_SUBQUERY:
-			case LE_ALL_SUBQUERY:
-			case LT_ALL_SUBQUERY:
-			case GE_ALL_SUBQUERY:
-			case GT_ALL_SUBQUERY:
-				ucoNode = (UnaryComparisonOperatorNode) 
-									getNodeFactory().getNode(
-													C_NodeTypes.IS_NULL_NODE,
-													this,
-													getContextManager());
-				break;
-		}
-		ucoNode.bindComparisonOperator();
-		return ucoNode;
-	}
-
-	/**
-	 * Build a new join condition between the leftOperand
-	 * and the rightOperand.  The comparison operator
-	 * is dependent on the subquery type.
-	 *
-	 * @param leftOperand	The left operand for the new condition.
-	 * @param rightOperand	The right operand for the new condition.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	private BinaryComparisonOperatorNode getNewJoinCondition(
-				ValueNode leftOperand, 
-				ValueNode rightOperand)
-		throws StandardException
-	{
-		BinaryComparisonOperatorNode bcoNode = null;
-
-		/* NOTE: If we are an expression subquery that's getting
-		 * flattened then our subqueryType is EXPRESSION_SUBQUERY.
-		 * However, we can get the comparison type from the 
-		 * parentComparisonOperator.  In that case we dovetail on
-		 * the ANY subquery types.
-		 */
-		int operatorType = subqueryType;
-		if (subqueryType == EXPRESSION_SUBQUERY)
-		{
-			if (SanityManager.DEBUG)
-			{
-				SanityManager.ASSERT(parentComparisonOperator != null,
-					"parentComparisonOperator expected to be non-null");
-			}
-
-			int parentOperator = -1;
-
-			if (parentComparisonOperator.isRelationalOperator())
-			{
-				RelationalOperator ro = (RelationalOperator)parentComparisonOperator;
-				parentOperator = ro.getOperator();
-			}
-
-			if (parentOperator == RelationalOperator.EQUALS_RELOP)
-			{
-				operatorType = EQ_ANY_SUBQUERY;
-			}
-			else if (parentOperator == RelationalOperator.NOT_EQUALS_RELOP)
-			{
-				operatorType = NE_ANY_SUBQUERY;
-			}
-			else if (parentOperator == RelationalOperator.LESS_EQUALS_RELOP)
-			{
-				operatorType = LE_ANY_SUBQUERY;
-			}
-			else if (parentOperator == RelationalOperator.LESS_THAN_RELOP)
-			{
-				operatorType = LT_ANY_SUBQUERY;
-			}
-			else if (parentOperator == RelationalOperator.GREATER_EQUALS_RELOP)
-			{
-				operatorType = GE_ANY_SUBQUERY;
-			}
-			else if (parentOperator == RelationalOperator.GREATER_THAN_RELOP)
-			{
-				operatorType = GT_ANY_SUBQUERY;
-			}
-		}
-
-		int bcoType = 0;
-		int nodeType = 0;
-
-		/* Build the <BinaryComparisonOperator> */
-		switch (operatorType)
-		{
-			case IN_SUBQUERY:
-			case EQ_ANY_SUBQUERY:
-			case NOT_IN_SUBQUERY:
-			case NE_ALL_SUBQUERY:
-				nodeType = C_NodeTypes.BINARY_EQUALS_OPERATOR_NODE;
-				break;
-
-			case NE_ANY_SUBQUERY:
-			case EQ_ALL_SUBQUERY:
-				nodeType = C_NodeTypes.BINARY_NOT_EQUALS_OPERATOR_NODE;
-				break;
-
-			case LE_ANY_SUBQUERY:
-			case GT_ALL_SUBQUERY:
-				nodeType = C_NodeTypes.BINARY_LESS_EQUALS_OPERATOR_NODE;
-				break;
-
-			case LT_ANY_SUBQUERY:
-			case GE_ALL_SUBQUERY:
-				nodeType = C_NodeTypes.BINARY_LESS_THAN_OPERATOR_NODE;
-				break;
-
-			case GE_ANY_SUBQUERY:
-			case LT_ALL_SUBQUERY:
-				nodeType = C_NodeTypes.BINARY_GREATER_EQUALS_OPERATOR_NODE;
-				break;
-
-			case GT_ANY_SUBQUERY:
-			case LE_ALL_SUBQUERY:
-				nodeType = C_NodeTypes.BINARY_GREATER_THAN_OPERATOR_NODE;
-				break;
-
-			default:
-				if (SanityManager.DEBUG)
-				SanityManager.ASSERT(false,
-					"subqueryType (" + subqueryType + ") is an unexpected type");
-		}
-
-		bcoNode =  (BinaryComparisonOperatorNode) 
-						getNodeFactory().getNode(
-							nodeType,
-							leftOperand,
-							rightOperand,
-							getContextManager());
-
-		bcoNode.bindComparisonOperator();
-		return bcoNode;
-	}
-
-
-	/**
-	 * Eliminate NotNodes in the current query block.  We traverse the tree, 
-	 * inverting ANDs and ORs and eliminating NOTs as we go.  We stop at 
-	 * ComparisonOperators and boolean expressions.  We invert 
-	 * ComparisonOperators and replace boolean expressions with 
-	 * boolean expression = false.
-	 * NOTE: Since we do not recurse under ComparisonOperators, there
-	 * still could be NotNodes left in the tree.
-	 *
-	 * @param	underNotNode		Whether or not we are under a NotNode.
-	 *							
-	 *
-	 * @return		The modified expression
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	ValueNode eliminateNots(boolean underNotNode) 
-					throws StandardException
-	{
-		ValueNode result = this;
-
-		if (underNotNode)
-		{
-			/* Negate the subqueryType. For expression subqueries
-			 * we simply return subquery = false
-			 */
-			/* RESOLVE - This code needs to get cleaned up once there are
-			 * more subquery types.  (Consider using arrays.)
-			 */
-			switch (subqueryType)
-			{
-				case EXPRESSION_SUBQUERY:
-					result = genEqualsFalseTree();
-					break;
-
-				case EXISTS_SUBQUERY:
-					subqueryType = NOT_EXISTS_SUBQUERY;
-					break;
-
-				/* ANY subqueries */
-				case IN_SUBQUERY:
-				case EQ_ANY_SUBQUERY:
-					subqueryType = NOT_IN_SUBQUERY;
-					break;
-
-				case NE_ANY_SUBQUERY:
-					subqueryType = EQ_ALL_SUBQUERY;
-					break;
-
-				case GE_ANY_SUBQUERY:
-					subqueryType = LT_ALL_SUBQUERY;
-					break;
-
-				case GT_ANY_SUBQUERY:
-					subqueryType = LE_ALL_SUBQUERY;
-					break;
-
-				case LE_ANY_SUBQUERY:
-					subqueryType = GT_ALL_SUBQUERY;
-					break;
-
-				case LT_ANY_SUBQUERY:
-					subqueryType = GE_ALL_SUBQUERY;
-					break;
-
-				/* ALL subqueries - no need for NOT NOT_IN_SUBQUERY, since
-				 * NOT IN only comes into existence here.
-				 */
-				case EQ_ALL_SUBQUERY:
-					subqueryType = NE_ANY_SUBQUERY;
-					break;
-
-				case NE_ALL_SUBQUERY:
-					subqueryType = EQ_ANY_SUBQUERY;
-					break;
-
-				case GE_ALL_SUBQUERY:
-					subqueryType = LT_ANY_SUBQUERY;
-					break;
-
-				case GT_ALL_SUBQUERY:
-					subqueryType = LE_ANY_SUBQUERY;
-					break;
-
-				case LE_ALL_SUBQUERY:
-					subqueryType = GT_ANY_SUBQUERY;
-					break;
-
-				case LT_ALL_SUBQUERY:
-					subqueryType = GE_ANY_SUBQUERY;
-					break;
-
-				default:
-					if (SanityManager.DEBUG)
-					SanityManager.ASSERT(false,
-						"NOT is not supported for this time of subquery");
-			}
-		}
-
-		/* Halt recursion here, as each query block is preprocessed separately */
-		return result;
-	}
-
-	/**
-	 * Finish putting an expression into conjunctive normal
-	 * form.  An expression tree in conjunctive normal form meets
-	 * the following criteria:
-	 *		o  If the expression tree is not null,
-	 *		   the top level will be a chain of AndNodes terminating
-	 *		   in a true BooleanConstantNode.
-	 *		o  The left child of an AndNode will never be an AndNode.
-	 *		o  Any right-linked chain that includes an AndNode will
-	 *		   be entirely composed of AndNodes terminated by a true BooleanConstantNode.
-	 *		o  The left child of an OrNode will never be an OrNode.
-	 *		o  Any right-linked chain that includes an OrNode will
-	 *		   be entirely composed of OrNodes terminated by a false BooleanConstantNode.
-	 *		o  ValueNodes other than AndNodes and OrNodes are considered
-	 *		   leaf nodes for purposes of expression normalization.
-	 *		   In other words, we won't do any normalization under
-	 *		   those nodes.
-	 *
-	 * In addition, we track whether or not we are under a top level AndNode.  
-	 * SubqueryNodes need to know this for subquery flattening.
-	 *
-	 * @param	underTopAndNode		Whether or not we are under a top level AndNode.
-	 *							
-	 *
-	 * @return		The modified expression
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public ValueNode changeToCNF(boolean underTopAndNode) 
-					throws StandardException
-	{
-		/* Remember whether or not we are immediately under a top leve
-		 * AndNode.  This is important for subquery flattening.
-		 * (We can only flatten subqueries under a top level AndNode.)
-		 */
-		 this.underTopAndNode = underTopAndNode;
-
-		/* Halt recursion here, as each query block is preprocessed separately */
-		return this;
-	}
-
-	/**
-	 * Categorize this predicate.  Initially, this means
-	 * building a bit map of the referenced tables for each predicate.
-	 * If the source of this ColumnReference (at the next underlying level) 
-	 * is not a ColumnReference or a VirtualColumnNode then this predicate
-	 * will not be pushed down.
-	 *
-	 * For example, in:
-	 *		select * from (select 1 from s) a (x) where x = 1
-	 * we will not push down x = 1.
-	 * NOTE: It would be easy to handle the case of a constant, but if the
-	 * inner SELECT returns an arbitrary expression, then we would have to copy
-	 * that tree into the pushed predicate, and that tree could contain
-	 * subqueries and method calls.
-	 * RESOLVE - revisit this issue once we have views.
-	 *
-	 * @param referencedTabs	JBitSet with bit map of referenced FromTables
-	 * @return boolean		Whether or not source.expression is a ColumnReference
-	 *						or a VirtualColumnNode.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly)
-		throws StandardException
-	{
-		/* We stop here when only considering simple predicates
-		 *  as we don't consider method calls when looking
-		 * for null invariant predicates.
-		 */
-		if (simplePredsOnly)
-		{
-			return false;
-		}
-
-		/* RESOLVE - We need to or in a bit map when there are correlation columns */
-
-		/* We categorize a query block at a time, so stop the recursion here */
-
-		/* Predicates with subqueries are not pushable for now */
-
-		/*
-		** If we can materialize the subquery, then it is 
-		** both invariant and non-correlated.  And so it
-		** is pushable.
-		*/
-		return isMaterializable();
-
-	}
-
-	/*
-	** Subquery is materializable if
-	** it is an expression subquery that
-	** has no correlations and is invariant.
-	*/
-	boolean isMaterializable() throws StandardException
-	{
-		boolean retval = (subqueryType == EXPRESSION_SUBQUERY) && 
-						  !hasCorrelatedCRs() && 
-						  isInvariant();
-		/* If we can materialize the subquery, then we set
-		 * the level of all of the tables to 0 so that we can
-		 * consider bulk fetch for them.
-		 */
-		if (retval)
-		{
-			if (resultSet instanceof SelectNode)
-			{
-				SelectNode select = (SelectNode) resultSet;
-				FromList fromList = select.getFromList();
-				fromList.setLevel(0);
-			}
-		}
-
-		return retval;
-	}
-
-	/**
-	 * Optimize this SubqueryNode.  
-	 *
-	 * @param dataDictionary	The DataDictionary to use for optimization
-	 * @param outerRows			The optimizer's estimate of the number of
-	 *							times this subquery will be executed.
-	 *
-	 * @return	Nothing
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public void optimize(DataDictionary dataDictionary, double outerRows) 
-					throws StandardException
-	{
-		/* RESOLVE - is there anything else that we need to do for this
-		 * node.
-		 */
-
-		/* Optimize the underlying result set */
-		resultSet = resultSet.optimize(dataDictionary, null, outerRows);
-	}
-
-	/**
-	 * Make any changes to the access paths, as decided by the optimizer.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public void modifyAccessPaths() throws StandardException
-	{
-		resultSet = resultSet.modifyAccessPaths();
-	}
-
-	/**
-	 * Return the variant type for the underlying expression.
-	 * The variant type can be:
-	 *		VARIANT				- variant within a scan
-	 *							  (method calls and non-static field access)
-	 *		SCAN_INVARIANT		- invariant within a scan
-	 *							  (column references from outer tables)
-	 *		QUERY_INVARIANT		- invariant within the life of a query
-	 *							  (constant expressions)
-	 *
-	 * @return	The variant type for the underlying expression.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	protected int getOrderableVariantType() throws StandardException
-	{
-		/* 
-		 * If the subquery is variant, than return
-		 * VARIANT.  Otherwise, if we have an expression
-		 * subquery and no correlated CRs we are going
-		 * to materialize it, so it is QUERY_INVARIANT.
-	  	 * Otherwise, SCAN_INVARIANT.
-		 */
-		if (isInvariant())
-		{
-			if (!hasCorrelatedCRs() && 
-				(subqueryType == EXPRESSION_SUBQUERY))
-			{
-				return Qualifier.QUERY_INVARIANT;
-			}
-			else
-			{
-				return Qualifier.SCAN_INVARIANT;
-			}
-		}
-		else
-		{
-			return Qualifier.VARIANT;
-		}
-	}
-
-	/**
-	 * Do code generation for this subquery.
-	 *
-	 * @param expressionBuilder	The ExpressionClassBuilder for the class being built
-	 * @param mbex	The method the expression will go into
-	 *
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public void generateExpression(
-									ExpressionClassBuilder expressionBuilder,
-									MethodBuilder mbex)
-								throws StandardException
-	{
-		CompilerContext	cc = getCompilerContext();
-		String			resultSetString;
-
-		///////////////////////////////////////////////////////////////////////////
-		//
-		//	Subqueries should not appear in Filter expressions. We should get here
-		//	only if we're compiling a query. That means that our class builder
-		//	is an activation builder. If we ever allow subqueries in filters, we'll
-		//	have to revisit this code.
-		//
-		///////////////////////////////////////////////////////////////////////////
-		
-		if (SanityManager.DEBUG)
-		{
-			SanityManager.ASSERT(expressionBuilder instanceof ActivationClassBuilder,
-				"Expecting an ActivationClassBuilder");
-		}
-
-		ActivationClassBuilder	acb = (ActivationClassBuilder) expressionBuilder;
-		/* Reuse generated code, where possible */
-
-		/* Generate the appropriate (Any or Once) ResultSet */
-		if (subqueryType == EXPRESSION_SUBQUERY)
-		{
-			resultSetString = "getOnceResultSet";
-		}
-		else
-		{
-			resultSetString = "getAnyResultSet";
-		}
-
-		// Get cost estimate for underlying subquery
-		CostEstimate costEstimate = resultSet.getFinalCostEstimate();
-
-		/* Generate a new method.  It's only used within the other
-		 * exprFuns, so it could be private. but since we don't
-		 * generate the right bytecodes to invoke private methods,
-		 * we just make it protected.  This generated class won't
-		 * have any subclasses, certainly! (nat 12/97)
-		 */
-		String subqueryTypeString =
-							getTypeCompiler().interfaceName();
-		MethodBuilder	mb = acb.newGeneratedFun(subqueryTypeString, Modifier.PROTECTED);
-
-		/* Declare the field to hold the suquery's ResultSet tree */
-		LocalField rsFieldLF = acb.newFieldDeclaration(Modifier.PRIVATE, ClassName.NoPutResultSet);
-
-		ResultSetNode subNode = null;
-
-		if (!isMaterializable())
-		{
-            MethodBuilder executeMB = acb.getExecuteMethod();
-			if (pushedNewPredicate && (! hasCorrelatedCRs()))
-			{
-				/* We try to materialize the subquery if it can fit in the memory.  We
-				 * evaluate the subquery first.  If the result set fits in the memory,
-				 * we replace the resultset with in-memory unions of row result sets.
-				 * We do this trick by replacing the child result with a new node --
-				 * MaterializeSubqueryNode, which essentially generates the suitable
-				 * code to materialize the subquery if possible.  This may have big
-				 * performance improvement.  See beetle 4373.
-				 */
-				if (SanityManager.DEBUG)
-				{
-					SanityManager.ASSERT(resultSet instanceof ProjectRestrictNode,
-						"resultSet expected to be a ProjectRestrictNode!");
-				}
-				subNode = ((ProjectRestrictNode) resultSet).getChildResult();
-				LocalField subRS = acb.newFieldDeclaration(Modifier.PRIVATE, ClassName.NoPutResultSet);
-				mb.getField(subRS);
-				mb.conditionalIfNull();
-
-				ResultSetNode materialSubNode = new MaterializeSubqueryNode(subRS);
-				((ProjectRestrictNode) resultSet).setChildResult(materialSubNode);
-
-				/* Evaluate subquery resultset here first.  Next time when we come to
-				 * this subquery it may be replaced by a bunch of unions of rows.
-				 */
-				subNode.generate(acb, mb);
-				mb.startElseCode();
-				mb.getField(subRS);
-				mb.completeConditional();
-		
-				mb.putField(subRS);
-				mb.endStatement();
-
-                executeMB.pushNull( ClassName.NoPutResultSet);
-                executeMB.putField(subRS);
-                executeMB.endStatement();
-			}
-
-            executeMB.pushNull( ClassName.NoPutResultSet);
-            executeMB.putField(rsFieldLF);
-            executeMB.endStatement();
-
-			// now we fill in the body of the conditional
-			mb.getField(rsFieldLF);
-			mb.conditionalIfNull();
-		}
-
-		acb.pushGetResultSetFactoryExpression(mb);
-
-		// start of args
-		int nargs;
-
-		/* Inside here is where subquery could already have been materialized. 4373
-		 */
-		resultSet.generate(acb, mb);
-
-		/* Get the next ResultSet #, so that we can number the subquery's 
-		 * empty row ResultColumnList and Once/Any ResultSet.
-		 */
-		int subqResultSetNumber = cc.getNextResultSetNumber();
-
-		/* We will be reusing the RCL from the subquery's ResultSet for the 
-		 * empty row function.  We need to reset the resultSetNumber in the
-		 * RCL, before we generate that function.  Now that we've called
-		 * generate() on the subquery's ResultSet, we can reset that
-		 * resultSetNumber.
-		 */
-		resultSet.getResultColumns().setResultSetNumber(subqResultSetNumber);
-
-		acb.pushThisAsActivation(mb);
-
-		/* Generate code for empty row */
-		resultSet.getResultColumns().generateNulls(acb, mb);
-
-		/*
-		 *	arg1: suqueryExpress - Expression for subquery's
-		 *		  ResultSet
-		 *  arg2: Activation
-		 *  arg3: Method to generate Row with null(s) if subquery
-		 *		  Result Set is empty
-		 */
-		if (subqueryType == EXPRESSION_SUBQUERY)
-		{
-			int cardinalityCheck;
-
-			/* No need to do sort if subquery began life as a distinct expression subquery.
-			 * (We simply check for a single unique value at execution time.)
-			 * No need for cardinality check if we know that underlying
-			 * ResultSet can contain at most 1 row.
-			 * RESOLVE - Not necessary if we know we
-			 * are getting a single row because of a unique index.
-			 */
-			if (distinctExpression)
-			{
-				cardinalityCheck = OnceResultSet.UNIQUE_CARDINALITY_CHECK;
-			}
-			else if (resultSet.returnsAtMostOneRow())
-			{
-				cardinalityCheck = OnceResultSet.NO_CARDINALITY_CHECK;
-			}
-			else
-			{
-				cardinalityCheck = OnceResultSet.DO_CARDINALITY_CHECK;
-			}
-
-			/*  arg4: int - whether or not cardinality check is required
-			 *				DO_CARDINALITY_CHECK - required
-			 *				NO_CARDINALITY_CHECK - not required
-			 *				UNIQUE_CARDINALITY_CHECK - verify single
-			 *											unique value
-			 */
-			mb.push(cardinalityCheck);
-			nargs = 9;
-
-		} else {
-			nargs = 8;
-		}
-
-		mb.push(subqResultSetNumber);
-		mb.push(subqueryNumber);
-		mb.push(pointOfAttachment);
-		mb.push(costEstimate.rowCount());
-		mb.push(costEstimate.getEstimatedCost());
-
-		mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, resultSetString, ClassName.NoPutResultSet, nargs);
-
-
-
-		/* Fill in the body of the method
-		 * generates the following.
-		 * (NOTE: the close() method only generated for
-		 * materialized subqueries.  All other subqueries
-		 * closed by top result set in the query.):
-		 * 
-		 *	NoPutResultSet	rsFieldX;
-		 *	{
-		 *		<Datatype interface> col;
-		 *		ExecRow r;
-		 *		rsFieldX = (rsFieldX == null) ? outerRSCall() : rsFieldX; // <== NONmaterialized specific
-		 *		rsFieldX.openCore();
-		 *		r = rsFieldX.getNextRowCore();
-		 *		col = (<Datatype interface>) r.getColumn(1);
-		 *		return col;
-		 *	}
-		 *
-		 * MATERIALIZED:
-		 *	NoPutResultSet	rsFieldX;
-		 *	{
-		 *		<Datatype interface> col;
-		 *		ExecRow r;
-		 *		rsFieldX = outerRSCall();
-		 *		rsFieldX.openCore();
-		 *		r = rsFieldX.getNextRowCore();
-		 *		col = (<Datatype interface>) r.getColumn(1);
-		 *		rsFieldX.close();								// <== materialized specific
-		 *		return col;
-		 *	}
-		 * and adds it to exprFun
-		 */
-
-		/* Generate the declarations */ // PUSHCOMPILE
-		//VariableDeclaration colVar = mb.addVariableDeclaration(subqueryTypeString);
-		//VariableDeclaration rVar   = mb.addVariableDeclaration(ClassName.ExecRow);
-
-		if (!isMaterializable())
-		{
-			/* put it back
-			 */
-			if (pushedNewPredicate && (! hasCorrelatedCRs()))
-				((ProjectRestrictNode) resultSet).setChildResult(subNode);
-
-			// now we fill in the body of the conditional
-			mb.startElseCode();
-			  mb.getField(rsFieldLF);
-			mb.completeConditional();
-		}
-		
-		mb.putField(rsFieldLF);
-		mb.endStatement();
-
-		/* rs.openCore() */
-		mb.getField(rsFieldLF);
-		mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "openCore", "void", 0);
-
-		/* r = rs.next() */
-		mb.getField(rsFieldLF);
-		mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getNextRowCore", ClassName.ExecRow, 0);
-		//mb.putVariable(rVar);
-		//mb.endStatement();
-
-		/* col = (<Datatype interface>) r.getColumn(1) */
-		//mb.getVariable(rVar);
-		mb.push(1); // both the Row interface and columnId are 1-based
-		mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Row, "getColumn", ClassName.DataValueDescriptor, 1);
-		mb.cast(subqueryTypeString);
-		//mb.putVariable(colVar);
-		//mb.endStatement();
-
-		/* Only generate the close() method for materialized
-		 * subqueries.  All others will be closed when the
-		 * close() method is called on the top ResultSet.
-		 */
-		if (isMaterializable())
-		{
-			/* rs.close() */
-			mb.getField(rsFieldLF);
-			mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.ResultSet, "close", "void", 0);
-		}
-
-		/* return col */
-		//mb.getVariable(colVar);
-		mb.methodReturn();
-		mb.complete();
-
-		/*
-		** If we have an expression subquery, then we
-		** can materialize it if it has no correlated
-		** column references and is invariant.
-		*/
-		if (isMaterializable())
-		{
-			LocalField lf = generateMaterialization(acb, mb, subqueryTypeString);
-			mbex.getField(lf);
-
-		} else {
-			/* Generate the call to the new method */
-			mbex.pushThis();
-			mbex.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, mb.getName(), subqueryTypeString, 0);
-		}
-	}
-
-	/*
-	** Materialize the subquery in question.  Given the expression
-	** that represents the subquery, this returns fieldX where
-	** fieldX is set up as follows:
-	**
-	** private ... fieldX
-	**
-	** execute()
-	** {
-	**	fieldX = <subqueryExpression>
-	**	...
-	** }
-	**
-	** So we wind up evaluating the subquery when we start
-	** execution.  Obviously, it is absolutely necessary that
-	** the subquery is invariant and has no correlations
-	** for this to work.
-	**
-	** Ideally we wouldn't evaluate the expression subquery
-	** until we know we need to, but because we are marking
-	** this expression subquery as pushable, we must evaluate
-	** it up front because it might wind up as a qualification,
-	** and we cannot execute a subquery in the store as a
-	** qualification because the store executes qualifications
-	** while holding a latch.  
-	**
-	** @param acb
-	** @param type 
-	** @param subqueryExpression
-	*/
-	private LocalField generateMaterialization(
-			ActivationClassBuilder	acb,
-			MethodBuilder mbsq,
-			String 			type)
-	{
-		MethodBuilder mb = acb.executeMethod;
-
-		// declare field
-		LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, type);
-
-		/* Generate the call to the new method */
-		mb.pushThis();
-		mb.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, mbsq.getName(), type, 0);
-
-		// generate: field = value (value is on stack)
-		mb.putField(field);
-		mb.endStatement();
-
-		return field;
-	}
-
-	/* Private methods on private variables */
-	private BooleanConstantNode getTrueNode()
-		throws StandardException
-	{
-		if (trueNode == null)
-		{
-			trueNode = (BooleanConstantNode) getNodeFactory().getNode(
-											C_NodeTypes.BOOLEAN_CONSTANT_NODE,
-											Boolean.TRUE,
-											getContextManager());
-		}
-		return trueNode;
-	}
-
-	/**
-	 * Accept a visitor, and call v.visit()
-	 * on child nodes as necessary.  
-	 * 
-	 * @param v the visitor
-	 *
-	 * @exception StandardException on error
-	 */
-	public Visitable accept(Visitor v)
-		throws StandardException
-	{
-		Visitable returnNode = v.visit(this);
-
-		/* shortcut if we've already done it
-		 */
-		if ((v instanceof HasCorrelatedCRsVisitor) && doneCorrelationCheck) 
-		{
-			((HasCorrelatedCRsVisitor) v).setHasCorrelatedCRs(foundCorrelation);
-			return returnNode;
-		}
-	
-		if (v.skipChildren(this))
-		{
-			return returnNode;
-		}
-
-		if (resultSet != null && !v.stopTraversal())
-		{
-			resultSet = (ResultSetNode)resultSet.accept(v);
-		}
-
-		if (leftOperand != null && !v.stopTraversal())
-		{
-			leftOperand = (ValueNode)leftOperand.accept(v);
-		}
-		return returnNode;
-	}
-
-	private boolean isIN()
-	{
-		return subqueryType == IN_SUBQUERY;
-	}
-
-	private boolean isNOT_IN()
-	{
-		return subqueryType == NOT_IN_SUBQUERY;
-	}
-
-	private boolean isANY()
-	{
-		switch (subqueryType)
-		{
-			case EQ_ANY_SUBQUERY:
-			case NE_ANY_SUBQUERY:
-			case LE_ANY_SUBQUERY:
-			case LT_ANY_SUBQUERY:
-			case GE_ANY_SUBQUERY:
-			case GT_ANY_SUBQUERY:
-				return true;
-
-			default:
-				return false;
-		}
-	}
-
-	private boolean isALL()
-	{
-		switch (subqueryType)
-		{
-			case EQ_ALL_SUBQUERY:
-			case NE_ALL_SUBQUERY:
-			case LE_ALL_SUBQUERY:
-			case LT_ALL_SUBQUERY:
-			case GE_ALL_SUBQUERY:
-			case GT_ALL_SUBQUERY:
-				return true;
-
-			default:
-				return false;
-		}
-	}
-
-	private boolean isEXISTS()
-	{
-		return subqueryType == EXISTS_SUBQUERY;
-	}
-
-	private boolean isNOT_EXISTS()
-	{
-		return subqueryType == NOT_EXISTS_SUBQUERY;
-	}
-
-	/**
-	 * Convert this IN/ANY subquery, which is known to return at most 1 row,
-	 * to an equivalent expression subquery.
-	 *
-	 * @return Nothing
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	private void changeToCorrespondingExpressionType()
-		throws StandardException
-	{
-  		BinaryOperatorNode bcon = null;
-
-  		switch (subqueryType)
-  		{
-  			case EQ_ANY_SUBQUERY:
-  			case IN_SUBQUERY:
-  				bcon = (BinaryOperatorNode) getNodeFactory().getNode(
-  									C_NodeTypes.BINARY_EQUALS_OPERATOR_NODE,
-  									leftOperand,
-  									this,
-  									getContextManager());
-  				break;
-
-  			case NE_ANY_SUBQUERY:
-  				bcon = (BinaryOperatorNode) getNodeFactory().getNode(
-  								C_NodeTypes.BINARY_NOT_EQUALS_OPERATOR_NODE,
-  								leftOperand,
-  								this,
-  								getContextManager());
-  				break;
-
-  			case LE_ANY_SUBQUERY:
-  				bcon = (BinaryOperatorNode) getNodeFactory().getNode(
-  								C_NodeTypes.BINARY_LESS_EQUALS_OPERATOR_NODE,
-  								leftOperand,
-  								this,
-  								getContextManager());
-  				break;
-
-  			case LT_ANY_SUBQUERY:
-  				bcon = (BinaryOperatorNode) getNodeFactory().getNode(
-  							C_NodeTypes.BINARY_LESS_THAN_OPERATOR_NODE,
-  							leftOperand,
-  							this,
-  							getContextManager());
-  				break;
-
-  			case GE_ANY_SUBQUERY:
-  				bcon = (BinaryOperatorNode) getNodeFactory().getNode(
-  							C_NodeTypes.BINARY_GREATER_EQUALS_OPERATOR_NODE,
-  							leftOperand,
-  							this,
-  							getContextManager());
-  				break;
-
-  			case GT_ANY_SUBQUERY:
-  				bcon = (BinaryOperatorNode) getNodeFactory().getNode(
-  								C_NodeTypes.BINARY_GREATER_THAN_OPERATOR_NODE,
-  								leftOperand,
-  								this,
-  								getContextManager());
-  				break;
-  		}
-
-  		// clean up the state of the tree to reflect a bound expression subquery
-  		subqueryType = EXPRESSION_SUBQUERY;
-  		setDataTypeServices(resultSet.getResultColumns());
-
-  		parentComparisonOperator = (BinaryComparisonOperatorNode) bcon;
-  		/* Set type info for the operator node */
-  		parentComparisonOperator.bindComparisonOperator();
-  		leftOperand = null;
-   }
-
-	private void setDataTypeServices(ResultColumnList resultColumns)
-		throws StandardException
-	{
-		DataTypeDescriptor dts;
-
-		/* Set the result type for this subquery (must be nullable).
-		 * Quantified predicates will return boolean.
-		 * However, the return type of the subquery's result list will 
-		 * probably not be boolean at this point, because we do not
-		 * transform the subquery (other than EXISTS) into 
-		 * (select true/false ...) until preprocess().  So, we force 
-		 * the return type to boolean.
-		 */
-		if (subqueryType == EXPRESSION_SUBQUERY)
-		{
-			dts = ((ResultColumn) resultColumns.elementAt(0)).getTypeServices();
-		}
-		else
-		{
-			dts = getTrueNode().getTypeServices();
-		}
-
-		/* If datatype of underlying resultSet is nullable, reuse it, otherwise
-		 * we need to generate a new one.
-		 */
-		if (! dts.isNullable())
-		{
-			dts = new DataTypeDescriptor(dts, true);
-		}
-		setType(dts);
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package	org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.services.context.ContextManager;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.sql.compile.CompilerContext;
+import org.apache.derby.iapi.sql.compile.CostEstimate;
+import org.apache.derby.iapi.sql.compile.Visitable;
+import org.apache.derby.iapi.sql.compile.Visitor;
+import org.apache.derby.iapi.sql.compile.C_NodeTypes;
+
+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.types.DataTypeDescriptor;
+
+import org.apache.derby.iapi.sql.execute.ExecRow;
+
+import org.apache.derby.iapi.sql.Activation;
+import org.apache.derby.iapi.types.DataValueDescriptor;
+import org.apache.derby.iapi.sql.Row;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+import org.apache.derby.iapi.sql.ResultSet;
+import org.apache.derby.iapi.types.TypeId;
+
+import org.apache.derby.iapi.services.loader.GeneratedMethod;
+
+import org.apache.derby.iapi.services.compiler.MethodBuilder;
+import org.apache.derby.iapi.services.compiler.LocalField;
+
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+import org.apache.derby.iapi.store.access.Qualifier;
+
+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.impl.sql.execute.OnceResultSet;
+
+import org.apache.derby.iapi.util.JBitSet;
+import org.apache.derby.iapi.util.ReuseFactory;
+import org.apache.derby.iapi.services.classfile.VMOpcode;
+
+import java.util.Properties;
+import java.util.Vector;
+
+/**
+ * A SubqueryNode represents a subquery.  Subqueries return values to their
+ * outer queries. An quantified subquery is one that appears under a quantified
+ * operator (like IN or EXISTS) - quantified subqueries can return more than
+ * one value per invocation. An expression subquery is one that is not directly
+ * under a quantified operator - expression subqueries are allowed to return
+ * at most one value per invocation (returning no value is considered to be
+ * equivalent to returning NULL).
+ *
+ * There are a large number of subquery types.  Because of the large number of
+ * types, and the large amount of shared code, we have decided to have 1 SubqueryNode
+ * without any subclasses.  The subquery type (and operator) is encoded in the
+ * subqueryType field.
+ *
+ * The query optimizer is responsible for optimizing subqueries, and also for
+ * transforming them so that code can be generated for them. The optimizer may
+ * eliminate some subqueries by transforming them into joins, or it may
+ * change the internal form of a subquery (for example, transforming
+ * 'where x in (select y from z where ...)' into
+ * 'where (select true from z where x = y and ...)').
+ *
+ * Note that aggregates present some additional issues.  A transformation
+ * such as:
+ *	<UL> where x in (SELECT <I>expression</I> FROM z) </UL>
+ * has to be treated specially if <I>expression</I> has an aggregate.
+ * We change it to:
+ *	<UL> where x = (SELECT true FROM (SELECT MAX(x) FROM z) WHERE SQLCOL1 = y) </UL>
+ *
+ * @author Jeff Lichtman
+ */
+
+public class SubqueryNode extends ValueNode
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	/*
+	** This must be a single-column result set.  If the subquery is
+	** not quantified, it must also be a single-row result set - that is,
+	** expression subqueries are allowed to return only a single value
+	** per invocation.
+	** NOTE: SubqueryNodes are used as an intermediate step within the parser
+	** for building a derived table.  Derived tables can be multi-column and 
+	** multi-table.
+	*/
+	ResultSetNode	resultSet;
+
+	/* Type of this subquery */
+	int				subqueryType;
+
+	/* Whether or not this subquery is immediately under a top level AndNode.
+	 * (Important for subquery flattening.)
+	 */
+	boolean			underTopAndNode;
+
+	/* Whether or not we've been preprocessed. (Only do the work once.) */
+	boolean			preprocessed;
+
+	/* Whether or not this subquery began life as a distinct expression subquery */
+	boolean			distinctExpression;
+
+	/* Since we do not have separate subquery operator nodes, the
+	 * type of the subquery is stored in the subqueryType field.  Most subquery
+	 * types take a left operand (except for expression and exists).  We could
+	 * either add a leftOperand field here or subclass SubqueryNode for those
+	 * types that take a left operand.  We have decided to add the left operand
+	 * here for now.
+	 */
+	ValueNode		leftOperand;
+	boolean			pushedNewPredicate;
+
+	/* Expression subqueries on the right side of a BinaryComparisonOperatorNode
+	 * will get passed a pointer to that node prior to preprocess().  This
+	 * allows us to replace the entire comparison, if we want to, when
+	 * flattening.
+	 */
+	BinaryComparisonOperatorNode parentComparisonOperator;
+
+	/* Private fields (all references via private methods) - 
+	 * We reuse true BooleanConstantNodes within
+	 * this class, creating them on the first reference.
+	 */
+	private BooleanConstantNode trueNode;
+	/* Reuse generated code where possible */
+	//private Expression genResult;
+
+	/* Subquery # for this subquery */
+	private int subqueryNumber = -1;
+
+	/* ResultSet # for the point of attachment for this subquery */
+	private int pointOfAttachment = -1;
+
+	/* 
+	** Indicate whether we found a correlation or not.
+	** And track whether we have checked yet.
+	*/
+	private boolean foundCorrelation;
+	private boolean doneCorrelationCheck;
+
+	/* 
+	** Indicate whether we found an invariant node
+	** below us or not. And track whether we have 
+	** checked yet.
+	*/
+	private boolean foundVariant;
+	private boolean doneInvariantCheck;
+
+	/* Subquery types.
+	 * NOTE: FROM_SUBQUERY only exists for a brief second in the parser.  It
+	 * should never appear in a query tree.
+	 * NOTE: NOT EXISTS and NOT IN subquery types do not exist prior to NOT 
+	 * elimination during preprocessing.  Prior to that, there is a separate
+	 * NotNode above the SubqueryNode in the tree.
+	 *
+	 */
+	public final static int NOTIMPLEMENTED_SUBQUERY		= -1;
+	public final static int FROM_SUBQUERY	    = 0;
+	public final static int IN_SUBQUERY			= 1;
+	public final static int NOT_IN_SUBQUERY		= 2;
+	public final static int EQ_ANY_SUBQUERY		= 3;
+	public final static int EQ_ALL_SUBQUERY		= 4;
+	public final static int NE_ANY_SUBQUERY		= 5;
+	public final static int NE_ALL_SUBQUERY		= 6;
+	public final static int GT_ANY_SUBQUERY		= 7;
+	public final static int GT_ALL_SUBQUERY		= 8;
+	public final static int GE_ANY_SUBQUERY		= 9;
+	public final static int GE_ALL_SUBQUERY		= 10;
+	public final static int LT_ANY_SUBQUERY		= 11;
+	public final static int LT_ALL_SUBQUERY		= 12;
+	public final static int LE_ANY_SUBQUERY		= 13;
+	public final static int LE_ALL_SUBQUERY		= 14;
+	public final static int EXISTS_SUBQUERY		= 15;
+	public final static int NOT_EXISTS_SUBQUERY	= 16;
+	public final static int EXPRESSION_SUBQUERY = 17;
+
+
+	/**
+	 * Initializer.
+	 *
+	 * @param resultSet		The ResultSetNode for the subquery
+	 * @param subqueryType	The type of the subquery
+	 * @param leftOperand	The left operand, if any, of the subquery
+	 */
+
+	public void init(
+							Object resultSet,
+							Object subqueryType,
+							Object leftOperand)
+	{
+		this.resultSet = (ResultSetNode) resultSet;
+		this.subqueryType = ((Integer) subqueryType).intValue();
+
+		/* Subqueries are presumed not to be under a top level AndNode by
+		 * default.  This is because expression normalization only recurses
+		 * under Ands and Ors, not under comparison operators, method calls,
+		 * built-in functions, etc.
+		 */
+		underTopAndNode = false;
+		this.leftOperand = (ValueNode) leftOperand;
+	}
+
+	/**
+	 * Convert this object to a String.  See comments in QueryTreeNode.java
+	 * for how this should be done for tree printing.
+	 *
+	 * @return	This object as a String
+	 */
+
+	public String toString()
+	{
+		if (SanityManager.DEBUG)
+		{
+			return "subqueryType: " + subqueryType + "\n" +
+			   "underTopAndNode: " + underTopAndNode + "\n" +
+			   "subqueryNumber: " + subqueryNumber + "\n" +
+			   "pointOfAttachment: " + pointOfAttachment + "\n" +
+			   "preprocessed: " + preprocessed + "\n" +
+			   "distinctExpression: " + distinctExpression + "\n" +
+				super.toString();
+		}
+		else
+		{
+			return "";
+		}
+	}
+
+	/**
+	 * Prints the sub-nodes of this object.  See QueryTreeNode.java for
+	 * how tree printing is supposed to work.
+	 *
+	 * @param depth		The depth of this node in the tree
+	 *
+	 * @return	Nothing
+	 */
+
+	public void printSubNodes(int depth)
+	{
+		if (SanityManager.DEBUG)
+		{
+			super.printSubNodes(depth);
+
+			if (resultSet != null)
+			{
+				printLabel(depth, "resultSet: ");
+				resultSet.treePrint(depth + 1);
+			}
+
+			if (leftOperand != null)
+			{
+				printLabel(depth, "leftOperand: ");
+				leftOperand.treePrint(depth + 1);
+			}
+		}
+	}
+
+	/**
+	 * Return the resultSet for this SubqueryNode.
+	 *
+	 * @return ResultSetNode underlying this SubqueryNode.
+	 */
+	public ResultSetNode getResultSet()
+	{
+		return resultSet;
+	}
+
+	/**
+	 * Return the type of this subquery.
+	 *
+	 * @return int	Type of this subquery.
+	 */
+	public int getSubqueryType()
+	{
+		return subqueryType;
+	}
+
+	/**
+	 * Set the type of this subquery.
+	 *
+	 * @param Type of this subquery.
+	 *
+	 * @return None.
+	 */
+	public void setSubqueryType(int subqueryType)
+	{
+		this.subqueryType = subqueryType;
+	}
+
+	/**
+	 * Set the point of attachment of this subquery.
+	 *
+	 * @param pointOfAttachment	The point of attachment of this subquery.
+	 *
+	 * @return None.
+	 *
+	 * @exception StandardException			Thrown on error
+	 */
+	public void setPointOfAttachment(int pointOfAttachment)
+		throws StandardException
+	{
+		/* Materialized subqueries always keep their point of
+		 * attachment as -1.
+		 */
+		if (! isMaterializable())
+		{
+			this.pointOfAttachment = pointOfAttachment;
+		}
+	}
+
+	/**
+	 * Return whether or not this subquery is immediately under a top level
+	 * AndNode.
+	 *
+	 * @return boolean	Whether or not this subquery is immediately under a
+	 *					top level AndNode.
+	 */
+	public boolean getUnderTopAndNode()
+	{
+		return underTopAndNode;
+	}
+
+	/**
+	 * Get the ResultSet # for the point of attachment for this SubqueryNode.
+	 *
+	 * @return int		The ResultSet # for the point of attachment
+	 */
+	public int getPointOfAttachment()
+	{
+		if (SanityManager.DEBUG)
+		{
+			SanityManager.ASSERT(pointOfAttachment >= 0,
+				"pointOfAttachment expected to be >= 0");
+		}
+		return pointOfAttachment;
+	}
+
+	/**
+	 * Get whether or not this SubqueryNode has already been
+	 * preprocessed.
+	 * 
+	 * @return	Whether or not this SubqueryNode has already been
+	 *			preprocessed.
+	 */
+	boolean getPreprocessed()
+	{
+		return preprocessed;
+	}
+
+	/**
+	 * Set the parent BCON.  Useful when considering flattening
+	 * expression subqueries.
+	 *
+	 * @param parent	The parent BCON.
+	 *
+	 * @return Nothing.
+	 */
+  	void setParentComparisonOperator(BinaryComparisonOperatorNode parent)
+  	{
+  		parentComparisonOperator = parent;
+  	}
+
+	/**
+	 * Remap all ColumnReferences in this tree to be clones of the
+	 * underlying expression.
+	 *
+	 * @return ValueNode			The remapped expression tree.
+	 *
+	 * @exception StandardException			Thrown on error
+	 */
+	public ValueNode remapColumnReferencesToExpressions()
+		throws StandardException
+	{
+		/* We need to remap both the SELECT and Predicate lists 
+		 * since there may be correlated columns in either of them.
+		 */
+		if (resultSet instanceof SelectNode)
+		{
+			ResultColumnList selectRCL = resultSet.getResultColumns();
+			SelectNode		 select = (SelectNode) resultSet;
+			PredicateList	 selectPL = select.getWherePredicates();
+
+			if (SanityManager.DEBUG)
+			{
+				SanityManager.ASSERT(selectPL != null,
+					"selectPL expected to be non-null");
+			}
+			selectRCL.remapColumnReferencesToExpressions();
+			selectPL.remapColumnReferencesToExpressions();
+		}
+		return this;
+	}
+
+	/**
+	 * Bind this expression.  This means binding the sub-expressions,
+	 * as well as figuring out what the return type is for this expression.
+	 *
+	 * @param fromList			The FROM list for the query this
+	 *							expression is in, for binding columns.
+	 *							NOTE: fromList will be null if the subquery appears
+	 *							in a VALUES clause.
+	 * @param subqueryList		The subquery list being built as we find SubqueryNodes
+	 * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
+	 *
+	 * @return	The new top of the expression tree.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public ValueNode bindExpression(FromList fromList, SubqueryList subqueryList,
+					Vector	aggregateVector)
+				throws StandardException
+	{
+		ResultColumnList	resultColumns;
+
+		//check if subquery is allowed in expression tree
+		checkReliability( CompilerContext.SUBQUERY_ILLEGAL, SQLState.LANG_SUBQUERY );
+
+		resultColumns = resultSet.getResultColumns();
+
+		/* The parser does not enforce the fact that a subquery can only return
+		 * a single column, so we must check here.
+		 */
+		if (resultColumns.size() != 1)
+		{
+			throw StandardException.newException(SQLState.LANG_NON_SINGLE_COLUMN_SUBQUERY);
+		}
+
+		/* Verify the usage of "*" in the select list:
+		 *	o  Only valid in EXISTS subqueries
+		 *	o  If the AllResultColumn is qualified, then we have to verify
+		 *	   that the qualification is a valid exposed name.
+		 *	   NOTE: The exposed name can come from an outer query block.
+		 */
+		resultSet.verifySelectStarSubquery(fromList, subqueryType);
+
+		/* For an EXISTS subquery:
+		 *	o  If the SELECT list is a "*", then we convert it to a true.
+		 *	   (We need to do the conversion since we don't want the "*" to
+		 *	   get expanded.)
+		 *  o  We then must bind the expression under the SELECT list to
+		 *	   verify that it is a valid expression.  (We must do this as a
+		 *	   separate step because we need to validate the expression and
+		 *	   we need to handle EXISTS (select * ... union all select 1 ...)
+		 *	   without getting a type compatability error.)
+		 *	o  Finally, we convert the expression to a SELECT true.
+		 */
+		if (subqueryType == EXISTS_SUBQUERY)
+		{
+			/* Transform the * into true (EXISTS). */
+			resultSet.setResultToBooleanTrueNode(true);
+		}
+
+		/* We need to bind the tables before we can bind the target list
+		 * (for exists subqueries).  However, we need to wait until after
+		 * any *'s have been replaced, so that they don't get expanded.
+		 */
+		CompilerContext cc = getCompilerContext();
+
+		resultSet = resultSet.bindNonVTITables(getDataDictionary(), fromList);
+		resultSet = resultSet.bindVTITables(fromList);
+
+		/* Set the subquery # for this SubqueryNode */
+		if (subqueryNumber == -1)
+			subqueryNumber = cc.getNextSubqueryNumber();
+
+		/* reject ? parameters in the select list of subqueries */
+		resultSet.rejectParameters();
+
+		if (subqueryType == EXISTS_SUBQUERY)
+		{
+			/* Bind the expression in the SELECT list */
+			resultSet.bindTargetExpressions(fromList);
+
+			/* Transform the ResultColumn into true.
+			 * NOTE: This may be a 2nd instance of the same transformation for
+			 * an EXISTS (select * ...), since we had to transform the 
+			 * AllResultColumn above, but we have to also handle
+			 * EXISTS (select r from s ...)
+			 */
+			resultSet.setResultToBooleanTrueNode(false);
+		}
+
+		/* bind the left operand, if there is one */
+		if (leftOperand != null)
+		{
+			leftOperand = leftOperand.bindExpression(fromList, subqueryList,
+									   aggregateVector);
+		}
+
+		/* bind the expressions in the underlying subquery */
+		resultSet.bindExpressions(fromList);
+
+		resultSet.bindResultColumns(fromList);
+
+		/* We need to reset resultColumns since the underlying resultSet may
+		 * be a UNION (and UnionNode.bindResultColumns() regens a new RCL).
+		 */
+		resultColumns = resultSet.getResultColumns();
+
+		/*
+		 * A ? parameter to the left of this subquery gets type of the
+		 * subquery's sole column.
+		 */
+		if (leftOperand != null && leftOperand.isParameterNode())
+		{
+			((ParameterNode) leftOperand).setDescriptor(
+				((ResultColumn) resultColumns.elementAt(0)).getTypeServices());
+		}
+
+		// Set the DataTypeServices
+		setDataTypeServices(resultColumns);
+
+		/* Add this subquery to the subquery list */
+		subqueryList.addSubqueryNode(this);
+
+		return this;
+	}
+
+	/**
+	 * Preprocess an expression tree.  We do a number of transformations
+	 * here (including subqueries, IN lists, LIKE and BETWEEN) plus
+	 * subquery flattening.
+	 * NOTE: This is done before the outer ResultSetNode is preprocessed.
+	 *
+	 * @param	numTables			Number of tables in the DML Statement
+	 * @param	outerFromList		FromList from outer query block
+	 * @param	outerSubqueryList	SubqueryList from outer query block
+	 * @param	outerPredicateList	PredicateList from outer query block
+	 *
+	 * @return		The modified expression
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public ValueNode preprocess(int numTables,
+								FromList outerFromList,
+								SubqueryList outerSubqueryList,
+								PredicateList outerPredicateList) 
+					throws StandardException
+	{
+		/* Only preprocess this node once.  We may get called multiple times
+		 * due to tree transformations.
+		 */
+		if (preprocessed)
+		{
+			return this;
+		}
+		preprocessed = true;
+
+		boolean		flattenable;
+		ValueNode	topNode = this;
+
+		resultSet = resultSet.preprocess(numTables, null, (FromList) null);
+
+		// Eliminate any unnecessary DISTINCTs
+		if (resultSet instanceof SelectNode)
+		{
+			if (((SelectNode) resultSet).hasDistinct())
+			{
+				((SelectNode) resultSet).clearDistinct();
+				/* We need to remember to check for single unique value
+				 * at execution time for expression subqueries.
+				 */
+				if  (subqueryType == EXPRESSION_SUBQUERY)
+				{
+					distinctExpression = true;
+				}
+			}
+		}
+
+		/* Lame transformation - For IN/ANY subqueries, if
+		 * result set is guaranteed to return at most 1 row
+		 * and it is not correlated
+		 * then convert the subquery into the matching expression
+		 * subquery type.  For example:
+		 *	c1 in (select min(c1) from t2)
+		 * becomes:
+		 *	c1 = (select min(c1) from t2)
+		 * (This actually showed up in an app that a potential customer
+		 * was porting from SQL Server.)
+		 * The transformed query can then be flattened if appropriate.
+		 */
+		if ((isIN() || isANY()) &&
+			resultSet.returnsAtMostOneRow())
+		{
+			if (! hasCorrelatedCRs())
+			{
+				changeToCorrespondingExpressionType();
+			}
+		}
+
+		/* NOTE: Flattening occurs before the pushing of
+		 * the predicate, since the pushing will add a node 
+		 * above the SubqueryNode.
+		 */
+
+		/* Values subquery is flattenable if:
+		 *  o It is not under an OR.
+		 *  o It is an expression subquery on the right side
+		 *	  of a BinaryComparisonOperatorNode.
+		 */
+		flattenable = (resultSet instanceof RowResultSetNode) &&
+					  underTopAndNode &&
+					  parentComparisonOperator instanceof BinaryComparisonOperatorNode;
+		if (flattenable)
+		{
+			/* If we got this far and we are an expression subquery
+			 * then we want to set leftOperand to be the left side
+			 * of the comparison in case we pull the comparison into
+			 * the flattened subquery.
+			 */
+			leftOperand = parentComparisonOperator.getLeftOperand();
+			// Flatten the subquery
+			RowResultSetNode rrsn = (RowResultSetNode) resultSet;
+			FromList   fl = new FromList();
+
+			// Remove ourselves from the outer subquery list
+			outerSubqueryList.removeElement(this);
+
+			/* We only need to add the table from the subquery into 
+			 * the outer from list if the subquery itself contains
+			 * another subquery.  Otherwise, it just becomes a constant.
+			 */
+			if (rrsn.subquerys.size() != 0)
+			{
+				fl.addElement(rrsn);
+				outerFromList.destructiveAppend(fl);
+			}
+
+			/* Append the subquery's subquery list to the 
+			 * outer subquery list.
+			 */
+			outerSubqueryList.destructiveAppend(rrsn.subquerys);
+
+			/* return the new join condition 
+			 * If we are flattening an EXISTS then there is no new join
+			 * condition since there is no leftOperand.  Simply return
+			 * TRUE.
+			 *
+			 * NOTE: The outer where clause, etc. has already been normalized,
+			 * so we simply return the BinaryComparisonOperatorNode above
+			 * the new join condition.
+			 */
+			ValueNode rightOperand;
+			rightOperand = ((ResultColumn) rrsn.getResultColumns().elementAt(0)).
+								getExpression();
+			return getNewJoinCondition(leftOperand, rightOperand);
+		}
+
+		/* Select subquery is flattenable if:
+		 *  o It is not under an OR.
+		 *  o The subquery type is IN, ANY or EXISTS or
+		 *    an expression subquery on the right side
+		 *	  of a BinaryComparisonOperatorNode.
+		 *  o There are no aggregates in the select list
+		 *  o There is no group by clause
+		 *  o There is a uniqueness condition that ensures
+		 *	  that the flattening of the subquery will not
+		 *	  introduce duplicates into the result set.
+		 *
+		 *	OR,
+		 *  o The subquery is NOT EXISTS, NOT IN, ALL (beetle 5173).
+		 */
+		boolean flattenableNotExists = (isNOT_EXISTS() || canAllBeFlattened());
+
+		flattenable = (resultSet instanceof SelectNode) &&
+					  underTopAndNode &&
+					  (isIN() || isANY() || isEXISTS() || flattenableNotExists ||
+                       parentComparisonOperator != null);
+
+		if (flattenable)
+		{
+			SelectNode	select = (SelectNode) resultSet;
+			if ((select.getAggregateVector(IN_SELECT_LIST).size() == 0) &&
+				(! select.getGeneratedForGroupbyClause()))
+			{
+				ValueNode origLeftOperand = leftOperand;
+
+				/* Check for uniqueness condition. */
+				/* Is the column being returned by the subquery
+				 * a candidate for an = condition?
+				 */
+				boolean additionalEQ =
+							(subqueryType == IN_SUBQUERY) ||
+							(subqueryType == EQ_ANY_SUBQUERY);
+
+
+				additionalEQ = additionalEQ &&
+								((leftOperand instanceof ConstantNode) ||
+								 (leftOperand instanceof ColumnReference) ||
+
+								 (leftOperand.isParameterNode()));
+				/* If we got this far and we are an expression subquery
+				 * then we want to set leftOperand to be the left side
+				 * of the comparison in case we pull the comparison into
+				 * the flattened subquery.
+				 */
+				if (parentComparisonOperator instanceof BinaryComparisonOperatorNode)
+				{
+					leftOperand = parentComparisonOperator.getLeftOperand();
+				}
+				/* Never flatten to normal join for NOT EXISTS.
+				 */
+				if ((! flattenableNotExists) && select.uniqueSubquery(additionalEQ))
+				{
+					// Flatten the subquery
+					return flattenToNormalJoin(numTables,
+										   outerFromList, outerSubqueryList,
+										   outerPredicateList);
+				}
+				/* We can flatten into an EXISTS join if all of the above
+				 * conditions except for a uniqueness condition are true
+				 * and:
+				 *	o Subquery only has a single entry in its from list
+				 *	  and that entry is a FromBaseTable
+				 *	o All predicates in the subquery's where clause are
+				 *	  pushable.
+				 *  o The leftOperand, if non-null, is pushable.
+				 * If the subquery meets these conditions then we will flatten
+				 * the FBT into an EXISTS FBT, pushd the subquery's
+				 * predicates down to the PRN above the EBT and
+				 * mark the predicates to say that they cannot be pulled 
+				 * above the PRN. (The only way that we can guarantee correctness
+				 * is if the predicates do not get pulled up.  If they get pulled
+				 * up then the single next logic for an EXISTS join does not work
+				 * because that row may get disqualified at a higher level.)
+				 */
+				else if ( (isIN() || isANY() || isEXISTS() || flattenableNotExists) &&
+						  ((leftOperand == null) ? true :
+							 leftOperand.categorize(new JBitSet(numTables), false)) &&
+						  select.getWherePredicates().allPushable() &&
+						  singleFromBaseTable(select.getFromList()))
+				{
+					return flattenToExistsJoin(numTables,
+										   outerFromList, outerSubqueryList,
+										   outerPredicateList, flattenableNotExists);
+				}
+
+				// restore leftOperand to its original value
+				leftOperand = origLeftOperand;
+			}
+		}
+
+		/* We transform the leftOperand and the select list for quantified 
+		 * predicates that have a leftOperand into a new predicate and push it
+		 * down to the subquery after we preprocess the subquery's resultSet.
+		 * We must do this after preprocessing the underlying subquery so that
+		 * we know where to attach the new predicate.
+		 * NOTE - If we pushed the predicate before preprocessing the underlying
+		 * subquery, then the point of attachment would depend on the form of
+		 * that subquery.  (Where clause?  Having clause?)
+		 */
+		if (leftOperand != null)
+		{
+			topNode = pushNewPredicate(numTables);
+			pushedNewPredicate = true;
+		}
+		/* Since NOT EXISTS subquery is not flattened, now is good time to create
+		 * an IS NULL node on top.  Other cases are taken care of in pushNewPredicate.
+		 */
+		else if (subqueryType == NOT_EXISTS_SUBQUERY)
+		{
+			topNode = genIsNullTree();
+			subqueryType = EXISTS_SUBQUERY;
+		}
+
+		/*
+		** Do inVariant and correlated checks now.  We
+		** aren't going to use the results here, but they
+		** have been stashed away by isInvariant() and hasCorrelatedCRs()
+		*/
+		isInvariant();
+		hasCorrelatedCRs();
+
+		/* If parentComparisonOperator is non-null then we are an
+		 * expression subquery that was considered to be a candidate 
+		 * for flattening, but we didn't get flattened.  In that case
+		 * we are the rightOperand of the parent.  We need to update
+		 * the parent's rightOperand with the new topNode and return
+		 * the parent because the parent is letting us decide whether
+		 * or not to replace the entire comparison, which we can do
+		 * if we flatten.  Otherwise we simply return the new top node.
+		 */
+		if (parentComparisonOperator != null)
+		{
+			parentComparisonOperator.setRightOperand(topNode);
+			return parentComparisonOperator;
+		}
+
+		return topNode;
+	}
+
+	/**
+	 * Does the from list from the subquery contain a
+	 * single entry which is a FBT or a PRN/FBT.
+	 *
+	 * @param fromList	The from list from the subquery
+	 *
+	 * @return Whether or not the from list from the subquery contains a
+	 *			single entry which is a FBT or a PRN/FBT.
+	 */
+	private boolean singleFromBaseTable(FromList fromList)
+	{
+		boolean retCode = (fromList.size() == 1);
+
+		if (retCode)
+		{
+			FromTable ft = (FromTable) fromList.elementAt(0);
+
+			if (((ft instanceof ProjectRestrictNode) &&
+				 ((ProjectRestrictNode) ft).getChildResult() instanceof FromBaseTable) ||
+				ft instanceof FromBaseTable)
+			{
+			}
+			else
+			{
+				retCode = false;
+			}
+		}
+
+		return retCode;
+	}
+
+	/**
+	 * Can NOT IN, ALL be falttened to NOT EXISTS join?  We can't or the flattening doesn't
+	 * easily make sense if either side of the comparison is nullable. (beetle 5173)
+	 *
+	 * @return Whether or not the NOT IN or ALL subquery can be flattened.
+	 */
+	private boolean canAllBeFlattened ()
+	{
+		boolean result = false;
+		if (isNOT_IN() || isALL())
+		{
+			ValueNode rightOperand = ((ResultColumn) resultSet.getResultColumns().elementAt(0)).
+									getExpression();
+			result = (! leftOperand.getTypeServices().isNullable() &&
+						! rightOperand.getTypeServices().isNullable());
+		}
+		return result;
+	}
+
+	/**
+	 * Flatten this subquery into the outer query block.  
+	 * At this point we are only flattening based on a uniqueness
+	 * condition and only flattening non-aggregate subqueries.
+	 * So, we promote the subquery's from list, as is, into 
+	 * the outer from list.  For EXISTS subquerys, we return a 
+	 * TRUE.  Otherwise we return a new comparison between
+	 * the leftOperand and the expression in the subquery's
+	 * SELECT list.
+	 * RESOLVE - we will need to modify this logic to account
+	 * for exists joins and aggregates as we support flattening
+	 * for them.
+	 *
+	 * Anyway, here's what we do:
+	 *	o We remove ourself from the outer subquery list.
+	 *	o We decrement the nesting level for all tables
+	 *	  in the subquery tree.
+	 *	o We append the subquery's from list to the outer
+	 *	  from list.
+	 *	o We add the subquery's predicate list to the outer
+	 *	  predicate list.  (The subquery has already been
+	 *	  preprocessed.)
+	 *  o We add the subquery's subquery list to the outer
+	 *	  subquery list.
+	 *	o For EXISTS, we return a true.
+	 *	o Otherwise, we return a new comparison between the
+	 *	  leftOperand and the expression in the inner select's
+	 *	  RCL.
+	 *
+	 * @param	numTables			Number of tables in the DML Statement
+	 * @param	outerFromList		FromList from outer query block
+	 * @param	outerSubqueryList	SubqueryList from outer query block
+	 * @param	outerPredicateList	PredicateList from outer query block
+	 *
+	 * @return	The modified expression
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	private ValueNode flattenToNormalJoin(int numTables,
+										  FromList outerFromList, 
+										  SubqueryList outerSubqueryList,
+										  PredicateList outerPredicateList)
+		throws StandardException
+	{
+		SelectNode select = (SelectNode) resultSet;
+		FromList   fl = select.getFromList();
+		int[] tableNumbers = fl.getTableNumbers();
+
+		// Remove ourselves from the outer subquery list
+		outerSubqueryList.removeElement(this);
+
+		/* Decrease the nesting level for all
+		 * tables in the subquey tree.
+		 */
+		select.decrementLevel(1);
+
+		/* Add the table(s) from the subquery into the outer from list */
+		outerFromList.destructiveAppend(fl);
+
+		/* Append the subquery's predicate list to the
+		 * outer predicate list.
+		 */
+		outerPredicateList.destructiveAppend(select.getWherePredicates());
+
+		/* Append the subquery's subquery list to the 
+		 * outer subquery list.
+		 * NOTE: We must propagate any subqueries from both the
+		 * SELECT list and WHERE clause of the subquery that's
+		 * getting flattened.
+		 */
+		outerSubqueryList.destructiveAppend(select.getWhereSubquerys());
+		outerSubqueryList.destructiveAppend(select.getSelectSubquerys());
+
+		/* return the new join condition 
+		 * If we are flattening an EXISTS then there is no new join
+		 * condition since there is no leftOperand.  Simply return
+		 * TRUE.
+		 *
+		 * NOTE: The outer where clause, etc. has already been normalized,
+		 * so we simply return the BinaryComparisonOperatorNode above
+		 * the new join condition.
+		 */
+		if (leftOperand == null)
+		{
+			return (ValueNode) getNodeFactory().getNode(
+											C_NodeTypes.BOOLEAN_CONSTANT_NODE,
+											Boolean.TRUE,
+											getContextManager());
+		}
+		else
+		{
+			ValueNode rightOperand;
+			rightOperand = ((ResultColumn) select.getResultColumns().elementAt(0)).
+								getExpression();
+			/* If the right operand is a CR, then we need to decrement
+			 * its source level as part of flattening so that
+			 * transitive closure will work correctly.
+			 */
+			if (rightOperand instanceof ColumnReference)
+			{
+				ColumnReference cr = (ColumnReference) rightOperand;
+				int tableNumber = cr.getTableNumber();
+				for (int index = 0; index < tableNumbers.length; index++)
+				{
+					if (tableNumber == tableNumbers[index])
+					{
+						cr.setSourceLevel(
+							cr.getSourceLevel() - 1);
+						break;
+					}
+				}
+			}
+			return getNewJoinCondition(leftOperand, rightOperand);
+		}
+	}
+
+	/**
+	 * Flatten this subquery into the outer query block
+	 * as an exists join.  
+	 * At this point we are only flattening non-aggregate subqueries
+	 * with a single FBT in the from list.
+	 * So, we transform all FBTs in the from list into ExistBaseTables,
+	 * update the dependency lists for each of the tables and then
+	 * flatten the subquery.
+	 * RESOLVE - we will need to modify this logic to account
+	 * for aggregates as we support flattening
+	 * for them.
+	 *
+	 * @param	numTables			Number of tables in the DML Statement
+	 * @param	outerFromList		FromList from outer query block
+	 * @param	outerSubqueryList	SubqueryList from outer query block
+	 * @param	outerPredicateList	PredicateList from outer query block
+	 * @param	flattenableNotExists Is it a flattening into a NOT EXISTS join
+	 *
+	 * @return	The modified expression
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	private ValueNode flattenToExistsJoin(int numTables,
+										  FromList outerFromList, 
+										  SubqueryList outerSubqueryList,
+										  PredicateList outerPredicateList,
+										  boolean flattenableNotExists)
+		throws StandardException
+	{
+		SelectNode select = (SelectNode) resultSet;
+
+		// Replace the FromBaseTables in the from list with ExistBaseTables
+		select.getFromList().genExistsBaseTables(resultSet.getReferencedTableMap(),
+				outerFromList, flattenableNotExists);
+
+		/* NOTE: Because we are currently only flattening single table subqueries
+		 * whose predicates are all pushable, we simply follow the rest of the
+		 * flattening algorithm for unique subqueries.  Should we decide to 
+		 * loosen these restrictions then we need to do more work such as:
+		 *
+		 * Mark all of the predicates from the subquery as non-pullable. They must
+		 * not be pulled so that we can guarantee correctness.  Otherwise, we could
+		 * add or subtract rows from the result set.
+		 *
+		 * Remap all of the non-correlated CRs in the predicate list so that they
+		 * point to the correct source.  (We've chopped a level out of the RCL/VCN
+		 * chain.)  We then transfer those predicates to the PRN in the subquery's
+		 * from list.
+		 */
+
+		return flattenToNormalJoin(numTables, outerFromList,
+								   outerSubqueryList, outerPredicateList);
+	}
+
+	/**
+	 * Check to see if we have a Variant value below us.
+	 * If so, return true.  Caches the result so multiple
+	 * calls are ok.
+	 *  
+	 * @return boolean whether we have 
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	private boolean isInvariant() throws StandardException
+	{
+		if (doneInvariantCheck)
+		{
+			return !foundVariant;
+		}
+
+		doneInvariantCheck = true;
+		HasVariantValueNodeVisitor visitor = new HasVariantValueNodeVisitor();
+		resultSet.accept(visitor);
+		foundVariant = visitor.hasVariant();
+		return !foundVariant;
+	}
+
+	/**
+	 * Check to see if this subquery has correlated
+	 * column references.  Only useful results if
+	 * called AFTER binding (after CRs have been bound).
+	 *
+	 * @return whether the subquery has correlated column
+	 *	references.
+	 * @exception StandardException		Thrown on error
+	 */
+	public boolean hasCorrelatedCRs() throws StandardException
+	{
+		if (doneCorrelationCheck)
+		{
+			return foundCorrelation;
+		}
+		doneCorrelationCheck = true;
+
+		ResultSetNode realSubquery = resultSet;
+		ResultColumnList oldRCL = null;
+
+		/* If we have pushed the new join predicate on top, we want to disregard it
+		 * to see if anything under the predicate is correlated.  If nothing correlated
+		 * under the new join predicate, we could then materialize the subquery.
+		 * See beetle 4373.
+		 */
+		if (pushedNewPredicate)
+		{
+			if (SanityManager.DEBUG)
+			{
+				SanityManager.ASSERT(resultSet instanceof ProjectRestrictNode,
+					"resultSet expected to be a ProjectRestrictNode!");
+			}
+
+			realSubquery = ((ProjectRestrictNode) resultSet).getChildResult();
+			oldRCL = realSubquery.getResultColumns();
+
+			/* Only first column matters.
+			 */
+			if (oldRCL.size() > 1)
+			{
+				ResultColumnList newRCL = new ResultColumnList();
+				newRCL.addResultColumn(oldRCL.getResultColumn(1));
+				realSubquery.setResultColumns(newRCL);
+			}
+		}
+
+		HasCorrelatedCRsVisitor visitor = new HasCorrelatedCRsVisitor();
+		realSubquery.accept(visitor);
+		foundCorrelation = visitor.hasCorrelatedCRs();
+
+		if (pushedNewPredicate && (oldRCL.size() > 1))
+		{
+			realSubquery.setResultColumns(oldRCL);
+		}
+
+		return foundCorrelation;
+	}
+				
+	/**
+	 * Transform:
+	 *		expresion QuantifiedOperator (select x from ...)
+	 * into
+	 *		(select true from .. where expression <BinaryComparisonOperator> x ...)
+	 *		IS [NOT] NULL
+	 *
+	 * or, if we have an aggregate:
+	 *		(select true from 
+	 *			(select AGG(x) from ...)
+	 *		where expression <BinaryComparisonOperator> x ...)
+	 *		IS [NOT] NULL
+	 *
+	 *
+	 * For ANY and IN subqueries:
+	 *		o  We generate an IS NULL above the SubqueryNode and return the top of
+	 *		   the new tree to the caller.
+	 *		o  The operator in the new predicate that is added to the subquery
+	 *		   will correspond to the operator that modifies the ANY.
+	 *		   (eg, = for = ANY, with = for IN.)
+	 * For ALL and NOT IN subqueries:
+	 *		o  We generate an IS NOT NULL above the SubqueryNode and return the top of
+	 *		   the new tree to the caller.
+	 *		o  The operator in the new predicate that is added to the subquery
+	 *		   will be a BinaryAllOperatorNode whose bcoNodeType corresponds to 
+	 *		   the negation of the operator that modifies the ALL.
+	 *		   (eg, <> for = ALL, with <> for NOT IN.)
+	 *
+	 * NOTE: This method is called after the underlying subquery has been
+	 * preprocessed, so we build a new Predicate, not just a new expression.
+	 *
+	 * @param numTables			Number of tables in DML Statement
+	 *
+	 * @return UnaryComparisonOperatorNode	An IS [NOT] NULL above the 
+	 *										transformed subquery.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	private UnaryComparisonOperatorNode pushNewPredicate(
+				int numTables)
+			throws StandardException
+	{
+		AndNode						andNode;
+		BinaryComparisonOperatorNode bcoNode = null;
+		JBitSet						tableMap;
+		Predicate					predicate;
+		ResultColumn				firstRC;
+		ResultColumnList			resultColumns;
+		UnaryComparisonOperatorNode	ucoNode = null;
+		ValueNode					oldWhereClause;
+		ValueNode					rightOperand;
+
+		/* We have to ensure that the resultSet immediately under us has
+		 * a PredicateList, otherwise we can't push the predicate down.
+		 */
+		resultSet = resultSet.ensurePredicateList(numTables);
+
+		/* RESOLVE - once we understand how correlated columns will work, 
+		 * we probably want to mark leftOperand as a correlated column
+		 */
+		resultColumns = resultSet.getResultColumns();
+
+		/*
+		** Create a new PR node.  Put it over the original subquery.  resulSet
+		** is now the new PR.  We give the chance that things under the PR node
+		** can be materialized.  See beetle 4373.
+		*/
+		ResultColumnList newRCL = resultColumns.copyListAndObjects();
+		newRCL.genVirtualColumnNodes(resultSet, resultColumns);
+		resultSet = (ResultSetNode) getNodeFactory().getNode(
+										C_NodeTypes.PROJECT_RESTRICT_NODE,
+										resultSet,	// child
+										newRCL,			// result columns
+										null,			// restriction
+										null, 			// restriction list
+										null,			// project subqueries
+										null,			// restrict subqueries	
+										null,
+										getContextManager());
+		resultColumns = newRCL;
+	
+		firstRC = (ResultColumn) resultColumns.elementAt(0);
+		rightOperand = firstRC.getExpression();
+
+		bcoNode = getNewJoinCondition(leftOperand, rightOperand);
+
+		ValueNode andLeft = bcoNode;
+
+		/* For NOT IN or ALL, and if either side of the comparison is nullable, and the
+		 * subquery can not be flattened (because of that), we need to add IS NULL node
+		 * on top of the nullables, such that the behavior is (beetle 5173):
+		 *
+		 *    (1) If we have nulls in right operand, no row is returned.
+		 *    (2) If subquery result is empty before applying join predicate, every
+		 *		  left row (including NULLs) is returned.
+		 *	  (3) Otherwise, return {all left row} - {NULLs}
+		 */
+		if (isNOT_IN() || isALL())
+		{
+			boolean leftNullable = leftOperand.getTypeServices().isNullable();
+			boolean rightNullable = rightOperand.getTypeServices().isNullable();
+			if (leftNullable || rightNullable)
+			{
+				/* Create a normalized structure.
+				 */
+				BooleanConstantNode falseNode = (BooleanConstantNode) getNodeFactory().getNode(
+												C_NodeTypes.BOOLEAN_CONSTANT_NODE,
+												Boolean.FALSE,
+												getContextManager());
+				OrNode newOr = (OrNode) getNodeFactory().getNode(
+												C_NodeTypes.OR_NODE,
+												bcoNode,
+												falseNode,
+												getContextManager());
+				newOr.postBindFixup();
+				andLeft = newOr;
+
+				if (leftNullable)
+				{
+					UnaryComparisonOperatorNode leftIsNull = (UnaryComparisonOperatorNode)
+									getNodeFactory().getNode(
+														C_NodeTypes.IS_NULL_NODE,
+														leftOperand,
+														getContextManager());
+					leftIsNull.bindComparisonOperator();
+					newOr = (OrNode) getNodeFactory().getNode(
+													C_NodeTypes.OR_NODE,
+													leftIsNull,
+													andLeft,
+													getContextManager());
+					newOr.postBindFixup();
+					andLeft = newOr;
+				}
+				if (rightNullable)
+				{
+					UnaryComparisonOperatorNode rightIsNull = (UnaryComparisonOperatorNode)
+									getNodeFactory().getNode(
+														C_NodeTypes.IS_NULL_NODE,
+														rightOperand,
+														getContextManager());
+					rightIsNull.bindComparisonOperator();
+					newOr = (OrNode) getNodeFactory().getNode(
+													C_NodeTypes.OR_NODE,
+													rightIsNull,
+													andLeft,
+													getContextManager());
+					newOr.postBindFixup();
+					andLeft = newOr;
+				}
+			}
+		}
+
+		/* Place an AndNode above the <BinaryComparisonOperator> */
+		andNode = (AndNode) getNodeFactory().getNode(
+													C_NodeTypes.AND_NODE,
+													andLeft,
+													getTrueNode(),
+													getContextManager());
+
+		/* Build the referenced table map for the new predicate */
+		tableMap = new JBitSet(numTables);
+		andNode.postBindFixup();
+
+		/* Put the AndNode under a Predicate */
+		predicate = (Predicate) getNodeFactory().getNode(
+										C_NodeTypes.PREDICATE,
+										andNode,
+										tableMap,
+										getContextManager());
+		predicate.categorize();
+
+		/* Push the new Predicate to the subquery's list */
+		resultSet = resultSet.addNewPredicate(predicate);
+
+		/* Clean up the leftOperand and subquery ResultColumn */
+		leftOperand = null;
+		firstRC.setType(getTypeServices());
+		firstRC.setExpression(getTrueNode());
+
+		/* Add the IS [NOT] NULL above the SubqueryNode */
+		switch (subqueryType)
+		{
+			case IN_SUBQUERY:
+			case EQ_ANY_SUBQUERY:
+			case NE_ANY_SUBQUERY:
+			case LE_ANY_SUBQUERY:
+			case LT_ANY_SUBQUERY:
+			case GE_ANY_SUBQUERY:
+			case GT_ANY_SUBQUERY:
+				ucoNode = (UnaryComparisonOperatorNode) 
+									getNodeFactory().getNode(
+												C_NodeTypes.IS_NOT_NULL_NODE,
+												this,
+												getContextManager());
+				break;
+
+			case NOT_IN_SUBQUERY:
+			case EQ_ALL_SUBQUERY:
+			case NE_ALL_SUBQUERY:
+			case LE_ALL_SUBQUERY:
+			case LT_ALL_SUBQUERY:
+			case GE_ALL_SUBQUERY:
+			case GT_ALL_SUBQUERY:
+				ucoNode = (UnaryComparisonOperatorNode) 
+									getNodeFactory().getNode(
+													C_NodeTypes.IS_NULL_NODE,
+													this,
+													getContextManager());
+				break;
+		}
+		ucoNode.bindComparisonOperator();
+		return ucoNode;
+	}
+
+	/**
+	 * Build a new join condition between the leftOperand
+	 * and the rightOperand.  The comparison operator
+	 * is dependent on the subquery type.
+	 *
+	 * @param leftOperand	The left operand for the new condition.
+	 * @param rightOperand	The right operand for the new condition.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	private BinaryComparisonOperatorNode getNewJoinCondition(
+				ValueNode leftOperand, 
+				ValueNode rightOperand)
+		throws StandardException
+	{
+		BinaryComparisonOperatorNode bcoNode = null;
+
+		/* NOTE: If we are an expression subquery that's getting
+		 * flattened then our subqueryType is EXPRESSION_SUBQUERY.
+		 * However, we can get the comparison type from the 
+		 * parentComparisonOperator.  In that case we dovetail on
+		 * the ANY subquery types.
+		 */
+		int operatorType = subqueryType;
+		if (subqueryType == EXPRESSION_SUBQUERY)
+		{
+			if (SanityManager.DEBUG)
+			{
+				SanityManager.ASSERT(parentComparisonOperator != null,
+					"parentComparisonOperator expected to be non-null");
+			}
+
+			int parentOperator = -1;
+
+			if (parentComparisonOperator.isRelationalOperator())
+			{
+				RelationalOperator ro = (RelationalOperator)parentComparisonOperator;
+				parentOperator = ro.getOperator();
+			}
+
+			if (parentOperator == RelationalOperator.EQUALS_RELOP)
+			{
+				operatorType = EQ_ANY_SUBQUERY;
+			}
+			else if (parentOperator == RelationalOperator.NOT_EQUALS_RELOP)
+			{
+				operatorType = NE_ANY_SUBQUERY;
+			}
+			else if (parentOperator == RelationalOperator.LESS_EQUALS_RELOP)
+			{
+				operatorType = LE_ANY_SUBQUERY;
+			}
+			else if (parentOperator == RelationalOperator.LESS_THAN_RELOP)
+			{
+				operatorType = LT_ANY_SUBQUERY;
+			}
+			else if (parentOperator == RelationalOperator.GREATER_EQUALS_RELOP)
+			{
+				operatorType = GE_ANY_SUBQUERY;
+			}
+			else if (parentOperator == RelationalOperator.GREATER_THAN_RELOP)
+			{
+				operatorType = GT_ANY_SUBQUERY;
+			}
+		}
+
+		int bcoType = 0;
+		int nodeType = 0;
+
+		/* Build the <BinaryComparisonOperator> */
+		switch (operatorType)
+		{
+			case IN_SUBQUERY:
+			case EQ_ANY_SUBQUERY:
+			case NOT_IN_SUBQUERY:
+			case NE_ALL_SUBQUERY:
+				nodeType = C_NodeTypes.BINARY_EQUALS_OPERATOR_NODE;
+				break;
+
+			case NE_ANY_SUBQUERY:
+			case EQ_ALL_SUBQUERY:
+				nodeType = C_NodeTypes.BINARY_NOT_EQUALS_OPERATOR_NODE;
+				break;
+
+			case LE_ANY_SUBQUERY:
+			case GT_ALL_SUBQUERY:
+				nodeType = C_NodeTypes.BINARY_LESS_EQUALS_OPERATOR_NODE;
+				break;
+
+			case LT_ANY_SUBQUERY:
+			case GE_ALL_SUBQUERY:
+				nodeType = C_NodeTypes.BINARY_LESS_THAN_OPERATOR_NODE;
+				break;
+
+			case GE_ANY_SUBQUERY:
+			case LT_ALL_SUBQUERY:
+				nodeType = C_NodeTypes.BINARY_GREATER_EQUALS_OPERATOR_NODE;
+				break;
+
+			case GT_ANY_SUBQUERY:
+			case LE_ALL_SUBQUERY:
+				nodeType = C_NodeTypes.BINARY_GREATER_THAN_OPERATOR_NODE;
+				break;
+
+			default:
+				if (SanityManager.DEBUG)
+				SanityManager.ASSERT(false,
+					"subqueryType (" + subqueryType + ") is an unexpected type");
+		}
+
+		bcoNode =  (BinaryComparisonOperatorNode) 
+						getNodeFactory().getNode(
+							nodeType,
+							leftOperand,
+							rightOperand,
+							getContextManager());
+
+		bcoNode.bindComparisonOperator();
+		return bcoNode;
+	}
+
+
+	/**
+	 * Eliminate NotNodes in the current query block.  We traverse the tree, 
+	 * inverting ANDs and ORs and eliminating NOTs as we go.  We stop at 
+	 * ComparisonOperators and boolean expressions.  We invert 
+	 * ComparisonOperators and replace boolean expressions with 
+	 * boolean expression = false.
+	 * NOTE: Since we do not recurse under ComparisonOperators, there
+	 * still could be NotNodes left in the tree.
+	 *
+	 * @param	underNotNode		Whether or not we are under a NotNode.
+	 *							
+	 *
+	 * @return		The modified expression
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	ValueNode eliminateNots(boolean underNotNode) 
+					throws StandardException
+	{
+		ValueNode result = this;
+
+		if (underNotNode)
+		{
+			/* Negate the subqueryType. For expression subqueries
+			 * we simply return subquery = false
+			 */
+			/* RESOLVE - This code needs to get cleaned up once there are
+			 * more subquery types.  (Consider using arrays.)
+			 */
+			switch (subqueryType)
+			{
+				case EXPRESSION_SUBQUERY:
+					result = genEqualsFalseTree();
+					break;
+
+				case EXISTS_SUBQUERY:
+					subqueryType = NOT_EXISTS_SUBQUERY;
+					break;
+
+				/* ANY subqueries */
+				case IN_SUBQUERY:
+				case EQ_ANY_SUBQUERY:
+					subqueryType = NOT_IN_SUBQUERY;
+					break;
+
+				case NE_ANY_SUBQUERY:
+					subqueryType = EQ_ALL_SUBQUERY;
+					break;
+
+				case GE_ANY_SUBQUERY:
+					subqueryType = LT_ALL_SUBQUERY;
+					break;
+
+				case GT_ANY_SUBQUERY:
+					subqueryType = LE_ALL_SUBQUERY;
+					break;
+
+				case LE_ANY_SUBQUERY:
+					subqueryType = GT_ALL_SUBQUERY;
+					break;
+
+				case LT_ANY_SUBQUERY:
+					subqueryType = GE_ALL_SUBQUERY;
+					break;
+
+				/* ALL subqueries - no need for NOT NOT_IN_SUBQUERY, since
+				 * NOT IN only comes into existence here.
+				 */
+				case EQ_ALL_SUBQUERY:
+					subqueryType = NE_ANY_SUBQUERY;
+					break;
+
+				case NE_ALL_SUBQUERY:
+					subqueryType = EQ_ANY_SUBQUERY;
+					break;
+
+				case GE_ALL_SUBQUERY:
+					subqueryType = LT_ANY_SUBQUERY;
+					break;
+
+				case GT_ALL_SUBQUERY:
+					subqueryType = LE_ANY_SUBQUERY;
+					break;
+
+				case LE_ALL_SUBQUERY:
+					subqueryType = GT_ANY_SUBQUERY;
+					break;
+
+				case LT_ALL_SUBQUERY:
+					subqueryType = GE_ANY_SUBQUERY;
+					break;
+
+				default:
+					if (SanityManager.DEBUG)
+					SanityManager.ASSERT(false,
+						"NOT is not supported for this time of subquery");
+			}
+		}
+
+		/* Halt recursion here, as each query block is preprocessed separately */
+		return result;
+	}
+
+	/**
+	 * Finish putting an expression into conjunctive normal
+	 * form.  An expression tree in conjunctive normal form meets
+	 * the following criteria:
+	 *		o  If the expression tree is not null,
+	 *		   the top level will be a chain of AndNodes terminating
+	 *		   in a true BooleanConstantNode.
+	 *		o  The left child of an AndNode will never be an AndNode.
+	 *		o  Any right-linked chain that includes an AndNode will
+	 *		   be entirely composed of AndNodes terminated by a true BooleanConstantNode.
+	 *		o  The left child of an OrNode will never be an OrNode.
+	 *		o  Any right-linked chain that includes an OrNode will
+	 *		   be entirely composed of OrNodes terminated by a false BooleanConstantNode.
+	 *		o  ValueNodes other than AndNodes and OrNodes are considered
+	 *		   leaf nodes for purposes of expression normalization.
+	 *		   In other words, we won't do any normalization under
+	 *		   those nodes.
+	 *
+	 * In addition, we track whether or not we are under a top level AndNode.  
+	 * SubqueryNodes need to know this for subquery flattening.
+	 *
+	 * @param	underTopAndNode		Whether or not we are under a top level AndNode.
+	 *							
+	 *
+	 * @return		The modified expression
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public ValueNode changeToCNF(boolean underTopAndNode) 
+					throws StandardException
+	{
+		/* Remember whether or not we are immediately under a top leve
+		 * AndNode.  This is important for subquery flattening.
+		 * (We can only flatten subqueries under a top level AndNode.)
+		 */
+		 this.underTopAndNode = underTopAndNode;
+
+		/* Halt recursion here, as each query block is preprocessed separately */
+		return this;
+	}
+
+	/**
+	 * Categorize this predicate.  Initially, this means
+	 * building a bit map of the referenced tables for each predicate.
+	 * If the source of this ColumnReference (at the next underlying level) 
+	 * is not a ColumnReference or a VirtualColumnNode then this predicate
+	 * will not be pushed down.
+	 *
+	 * For example, in:
+	 *		select * from (select 1 from s) a (x) where x = 1
+	 * we will not push down x = 1.
+	 * NOTE: It would be easy to handle the case of a constant, but if the
+	 * inner SELECT returns an arbitrary expression, then we would have to copy
+	 * that tree into the pushed predicate, and that tree could contain
+	 * subqueries and method calls.
+	 * RESOLVE - revisit this issue once we have views.
+	 *
+	 * @param referencedTabs	JBitSet with bit map of referenced FromTables
+	 * @return boolean		Whether or not source.expression is a ColumnReference
+	 *						or a VirtualColumnNode.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly)
+		throws StandardException
+	{
+		/* We stop here when only considering simple predicates
+		 *  as we don't consider method calls when looking
+		 * for null invariant predicates.
+		 */
+		if (simplePredsOnly)
+		{
+			return false;
+		}
+
+		/* RESOLVE - We need to or in a bit map when there are correlation columns */
+
+		/* We categorize a query block at a time, so stop the recursion here */
+
+		/* Predicates with subqueries are not pushable for now */
+
+		/*
+		** If we can materialize the subquery, then it is 
+		** both invariant and non-correlated.  And so it
+		** is pushable.
+		*/
+		return isMaterializable();
+
+	}
+
+	/*
+	** Subquery is materializable if
+	** it is an expression subquery that
+	** has no correlations and is invariant.
+	*/
+	boolean isMaterializable() throws StandardException
+	{
+		boolean retval = (subqueryType == EXPRESSION_SUBQUERY) && 
+						  !hasCorrelatedCRs() && 
+						  isInvariant();
+		/* If we can materialize the subquery, then we set
+		 * the level of all of the tables to 0 so that we can
+		 * consider bulk fetch for them.
+		 */
+		if (retval)
+		{
+			if (resultSet instanceof SelectNode)
+			{
+				SelectNode select = (SelectNode) resultSet;
+				FromList fromList = select.getFromList();
+				fromList.setLevel(0);
+			}
+		}
+
+		return retval;
+	}
+
+	/**
+	 * Optimize this SubqueryNode.  
+	 *
+	 * @param dataDictionary	The DataDictionary to use for optimization
+	 * @param outerRows			The optimizer's estimate of the number of
+	 *							times this subquery will be executed.
+	 *
+	 * @return	Nothing
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public void optimize(DataDictionary dataDictionary, double outerRows) 
+					throws StandardException
+	{
+		/* RESOLVE - is there anything else that we need to do for this
+		 * node.
+		 */
+
+		/* Optimize the underlying result set */
+		resultSet = resultSet.optimize(dataDictionary, null, outerRows);
+	}
+
+	/**
+	 * Make any changes to the access paths, as decided by the optimizer.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public void modifyAccessPaths() throws StandardException
+	{
+		resultSet = resultSet.modifyAccessPaths();
+	}
+
+	/**
+	 * Return the variant type for the underlying expression.
+	 * The variant type can be:
+	 *		VARIANT				- variant within a scan
+	 *							  (method calls and non-static field access)
+	 *		SCAN_INVARIANT		- invariant within a scan
+	 *							  (column references from outer tables)
+	 *		QUERY_INVARIANT		- invariant within the life of a query
+	 *							  (constant expressions)
+	 *
+	 * @return	The variant type for the underlying expression.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	protected int getOrderableVariantType() throws StandardException
+	{
+		/* 
+		 * If the subquery is variant, than return
+		 * VARIANT.  Otherwise, if we have an expression
+		 * subquery and no correlated CRs we are going
+		 * to materialize it, so it is QUERY_INVARIANT.
+	  	 * Otherwise, SCAN_INVARIANT.
+		 */
+		if (isInvariant())
+		{
+			if (!hasCorrelatedCRs() && 
+				(subqueryType == EXPRESSION_SUBQUERY))
+			{
+				return Qualifier.QUERY_INVARIANT;
+			}
+			else
+			{
+				return Qualifier.SCAN_INVARIANT;
+			}
+		}
+		else
+		{
+			return Qualifier.VARIANT;
+		}
+	}
+
+	/**
+	 * Do code generation for this subquery.
+	 *
+	 * @param expressionBuilder	The ExpressionClassBuilder for the class being built
+	 * @param mbex	The method the expression will go into
+	 *
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public void generateExpression(
+									ExpressionClassBuilder expressionBuilder,
+									MethodBuilder mbex)
+								throws StandardException
+	{
+		CompilerContext	cc = getCompilerContext();
+		String			resultSetString;
+
+		///////////////////////////////////////////////////////////////////////////
+		//
+		//	Subqueries should not appear in Filter expressions. We should get here
+		//	only if we're compiling a query. That means that our class builder
+		//	is an activation builder. If we ever allow subqueries in filters, we'll
+		//	have to revisit this code.
+		//
+		///////////////////////////////////////////////////////////////////////////
+		
+		if (SanityManager.DEBUG)
+		{
+			SanityManager.ASSERT(expressionBuilder instanceof ActivationClassBuilder,
+				"Expecting an ActivationClassBuilder");
+		}
+
+		ActivationClassBuilder	acb = (ActivationClassBuilder) expressionBuilder;
+		/* Reuse generated code, where possible */
+
+		/* Generate the appropriate (Any or Once) ResultSet */
+		if (subqueryType == EXPRESSION_SUBQUERY)
+		{
+			resultSetString = "getOnceResultSet";
+		}
+		else
+		{
+			resultSetString = "getAnyResultSet";
+		}
+
+		// Get cost estimate for underlying subquery
+		CostEstimate costEstimate = resultSet.getFinalCostEstimate();
+
+		/* Generate a new method.  It's only used within the other
+		 * exprFuns, so it could be private. but since we don't
+		 * generate the right bytecodes to invoke private methods,
+		 * we just make it protected.  This generated class won't
+		 * have any subclasses, certainly! (nat 12/97)
+		 */
+		String subqueryTypeString =
+							getTypeCompiler().interfaceName();
+		MethodBuilder	mb = acb.newGeneratedFun(subqueryTypeString, Modifier.PROTECTED);
+
+		/* Declare the field to hold the suquery's ResultSet tree */
+		LocalField rsFieldLF = acb.newFieldDeclaration(Modifier.PRIVATE, ClassName.NoPutResultSet);
+
+		ResultSetNode subNode = null;
+
+		if (!isMaterializable())
+		{
+            MethodBuilder executeMB = acb.getExecuteMethod();
+			if (pushedNewPredicate && (! hasCorrelatedCRs()))
+			{
+				/* We try to materialize the subquery if it can fit in the memory.  We
+				 * evaluate the subquery first.  If the result set fits in the memory,
+				 * we replace the resultset with in-memory unions of row result sets.
+				 * We do this trick by replacing the child result with a new node --
+				 * MaterializeSubqueryNode, which essentially generates the suitable
+				 * code to materialize the subquery if possible.  This may have big
+				 * performance improvement.  See beetle 4373.
+				 */
+				if (SanityManager.DEBUG)
+				{
+					SanityManager.ASSERT(resultSet instanceof ProjectRestrictNode,
+						"resultSet expected to be a ProjectRestrictNode!");
+				}
+				subNode = ((ProjectRestrictNode) resultSet).getChildResult();
+				LocalField subRS = acb.newFieldDeclaration(Modifier.PRIVATE, ClassName.NoPutResultSet);
+				mb.getField(subRS);
+				mb.conditionalIfNull();
+
+				ResultSetNode materialSubNode = new MaterializeSubqueryNode(subRS);
+				((ProjectRestrictNode) resultSet).setChildResult(materialSubNode);
+
+				/* Evaluate subquery resultset here first.  Next time when we come to
+				 * this subquery it may be replaced by a bunch of unions of rows.
+				 */
+				subNode.generate(acb, mb);
+				mb.startElseCode();
+				mb.getField(subRS);
+				mb.completeConditional();
+		
+				mb.putField(subRS);
+				mb.endStatement();
+
+                executeMB.pushNull( ClassName.NoPutResultSet);
+                executeMB.putField(subRS);
+                executeMB.endStatement();
+			}
+
+            executeMB.pushNull( ClassName.NoPutResultSet);
+            executeMB.putField(rsFieldLF);
+            executeMB.endStatement();
+
+			// now we fill in the body of the conditional
+			mb.getField(rsFieldLF);
+			mb.conditionalIfNull();
+		}
+
+		acb.pushGetResultSetFactoryExpression(mb);
+
+		// start of args
+		int nargs;
+
+		/* Inside here is where subquery could already have been materialized. 4373
+		 */
+		resultSet.generate(acb, mb);
+
+		/* Get the next ResultSet #, so that we can number the subquery's 
+		 * empty row ResultColumnList and Once/Any ResultSet.
+		 */
+		int subqResultSetNumber = cc.getNextResultSetNumber();
+
+		/* We will be reusing the RCL from the subquery's ResultSet for the 
+		 * empty row function.  We need to reset the resultSetNumber in the
+		 * RCL, before we generate that function.  Now that we've called
+		 * generate() on the subquery's ResultSet, we can reset that
+		 * resultSetNumber.
+		 */
+		resultSet.getResultColumns().setResultSetNumber(subqResultSetNumber);
+
+		acb.pushThisAsActivation(mb);
+
+		/* Generate code for empty row */
+		resultSet.getResultColumns().generateNulls(acb, mb);
+
+		/*
+		 *	arg1: suqueryExpress - Expression for subquery's
+		 *		  ResultSet
+		 *  arg2: Activation
+		 *  arg3: Method to generate Row with null(s) if subquery
+		 *		  Result Set is empty
+		 */
+		if (subqueryType == EXPRESSION_SUBQUERY)
+		{
+			int cardinalityCheck;
+
+			/* No need to do sort if subquery began life as a distinct expression subquery.
+			 * (We simply check for a single unique value at execution time.)
+			 * No need for cardinality check if we know that underlying
+			 * ResultSet can contain at most 1 row.
+			 * RESOLVE - Not necessary if we know we
+			 * are getting a single row because of a unique index.
+			 */
+			if (distinctExpression)
+			{
+				cardinalityCheck = OnceResultSet.UNIQUE_CARDINALITY_CHECK;
+			}
+			else if (resultSet.returnsAtMostOneRow())
+			{
+				cardinalityCheck = OnceResultSet.NO_CARDINALITY_CHECK;
+			}
+			else
+			{
+				cardinalityCheck = OnceResultSet.DO_CARDINALITY_CHECK;
+			}
+
+			/*  arg4: int - whether or not cardinality check is required
+			 *				DO_CARDINALITY_CHECK - required
+			 *				NO_CARDINALITY_CHECK - not required
+			 *				UNIQUE_CARDINALITY_CHECK - verify single
+			 *											unique value
+			 */
+			mb.push(cardinalityCheck);
+			nargs = 9;
+
+		} else {
+			nargs = 8;
+		}
+
+		mb.push(subqResultSetNumber);
+		mb.push(subqueryNumber);
+		mb.push(pointOfAttachment);
+		mb.push(costEstimate.rowCount());
+		mb.push(costEstimate.getEstimatedCost());
+
+		mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, resultSetString, ClassName.NoPutResultSet, nargs);
+
+
+
+		/* Fill in the body of the method
+		 * generates the following.
+		 * (NOTE: the close() method only generated for
+		 * materialized subqueries.  All other subqueries
+		 * closed by top result set in the query.):
+		 * 
+		 *	NoPutResultSet	rsFieldX;
+		 *	{
+		 *		<Datatype interface> col;
+		 *		ExecRow r;
+		 *		rsFieldX = (rsFieldX == null) ? outerRSCall() : rsFieldX; // <== NONmaterialized specific
+		 *		rsFieldX.openCore();
+		 *		r = rsFieldX.getNextRowCore();
+		 *		col = (<Datatype interface>) r.getColumn(1);
+		 *		return col;
+		 *	}
+		 *
+		 * MATERIALIZED:
+		 *	NoPutResultSet	rsFieldX;
+		 *	{
+		 *		<Datatype interface> col;
+		 *		ExecRow r;
+		 *		rsFieldX = outerRSCall();
+		 *		rsFieldX.openCore();
+		 *		r = rsFieldX.getNextRowCore();
+		 *		col = (<Datatype interface>) r.getColumn(1);
+		 *		rsFieldX.close();								// <== materialized specific
+		 *		return col;
+		 *	}
+		 * and adds it to exprFun
+		 */
+
+		/* Generate the declarations */ // PUSHCOMPILE
+		//VariableDeclaration colVar = mb.addVariableDeclaration(subqueryTypeString);
+		//VariableDeclaration rVar   = mb.addVariableDeclaration(ClassName.ExecRow);
+
+		if (!isMaterializable())
+		{
+			/* put it back
+			 */
+			if (pushedNewPredicate && (! hasCorrelatedCRs()))
+				((ProjectRestrictNode) resultSet).setChildResult(subNode);
+
+			// now we fill in the body of the conditional
+			mb.startElseCode();
+			  mb.getField(rsFieldLF);
+			mb.completeConditional();
+		}
+		
+		mb.putField(rsFieldLF);
+		mb.endStatement();
+
+		/* rs.openCore() */
+		mb.getField(rsFieldLF);
+		mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "openCore", "void", 0);
+
+		/* r = rs.next() */
+		mb.getField(rsFieldLF);
+		mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getNextRowCore", ClassName.ExecRow, 0);
+		//mb.putVariable(rVar);
+		//mb.endStatement();
+
+		/* col = (<Datatype interface>) r.getColumn(1) */
+		//mb.getVariable(rVar);
+		mb.push(1); // both the Row interface and columnId are 1-based
+		mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Row, "getColumn", ClassName.DataValueDescriptor, 1);
+		mb.cast(subqueryTypeString);
+		//mb.putVariable(colVar);
+		//mb.endStatement();
+
+		/* Only generate the close() method for materialized
+		 * subqueries.  All others will be closed when the
+		 * close() method is called on the top ResultSet.
+		 */
+		if (isMaterializable())
+		{
+			/* rs.close() */
+			mb.getField(rsFieldLF);
+			mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.ResultSet, "close", "void", 0);
+		}
+
+		/* return col */
+		//mb.getVariable(colVar);
+		mb.methodReturn();
+		mb.complete();
+
+		/*
+		** If we have an expression subquery, then we
+		** can materialize it if it has no correlated
+		** column references and is invariant.
+		*/
+		if (isMaterializable())
+		{
+			LocalField lf = generateMaterialization(acb, mb, subqueryTypeString);
+			mbex.getField(lf);
+
+		} else {
+			/* Generate the call to the new method */
+			mbex.pushThis();
+			mbex.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, mb.getName(), subqueryTypeString, 0);
+		}
+	}
+
+	/*
+	** Materialize the subquery in question.  Given the expression
+	** that represents the subquery, this returns fieldX where
+	** fieldX is set up as follows:
+	**
+	** private ... fieldX
+	**
+	** execute()
+	** {
+	**	fieldX = <subqueryExpression>
+	**	...
+	** }
+	**
+	** So we wind up evaluating the subquery when we start
+	** execution.  Obviously, it is absolutely necessary that
+	** the subquery is invariant and has no correlations
+	** for this to work.
+	**
+	** Ideally we wouldn't evaluate the expression subquery
+	** until we know we need to, but because we are marking
+	** this expression subquery as pushable, we must evaluate
+	** it up front because it might wind up as a qualification,
+	** and we cannot execute a subquery in the store as a
+	** qualification because the store executes qualifications
+	** while holding a latch.  
+	**
+	** @param acb
+	** @param type 
+	** @param subqueryExpression
+	*/
+	private LocalField generateMaterialization(
+			ActivationClassBuilder	acb,
+			MethodBuilder mbsq,
+			String 			type)
+	{
+		MethodBuilder mb = acb.executeMethod;
+
+		// declare field
+		LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, type);
+
+		/* Generate the call to the new method */
+		mb.pushThis();
+		mb.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, mbsq.getName(), type, 0);
+
+		// generate: field = value (value is on stack)
+		mb.putField(field);
+		mb.endStatement();
+
+		return field;
+	}
+
+	/* Private methods on private variables */
+	private BooleanConstantNode getTrueNode()
+		throws StandardException
+	{
+		if (trueNode == null)
+		{
+			trueNode = (BooleanConstantNode) getNodeFactory().getNode(
+											C_NodeTypes.BOOLEAN_CONSTANT_NODE,
+											Boolean.TRUE,
+											getContextManager());
+		}
+		return trueNode;
+	}
+
+	/**
+	 * Accept a visitor, and call v.visit()
+	 * on child nodes as necessary.  
+	 * 
+	 * @param v the visitor
+	 *
+	 * @exception StandardException on error
+	 */
+	public Visitable accept(Visitor v)
+		throws StandardException
+	{
+		Visitable returnNode = v.visit(this);
+
+		/* shortcut if we've already done it
+		 */
+		if ((v instanceof HasCorrelatedCRsVisitor) && doneCorrelationCheck) 
+		{
+			((HasCorrelatedCRsVisitor) v).setHasCorrelatedCRs(foundCorrelation);
+			return returnNode;
+		}
+	
+		if (v.skipChildren(this))
+		{
+			return returnNode;
+		}
+
+		if (resultSet != null && !v.stopTraversal())
+		{
+			resultSet = (ResultSetNode)resultSet.accept(v);
+		}
+
+		if (leftOperand != null && !v.stopTraversal())
+		{
+			leftOperand = (ValueNode)leftOperand.accept(v);
+		}
+		return returnNode;
+	}
+
+	private boolean isIN()
+	{
+		return subqueryType == IN_SUBQUERY;
+	}
+
+	private boolean isNOT_IN()
+	{
+		return subqueryType == NOT_IN_SUBQUERY;
+	}
+
+	private boolean isANY()
+	{
+		switch (subqueryType)
+		{
+			case EQ_ANY_SUBQUERY:
+			case NE_ANY_SUBQUERY:
+			case LE_ANY_SUBQUERY:
+			case LT_ANY_SUBQUERY:
+			case GE_ANY_SUBQUERY:
+			case GT_ANY_SUBQUERY:
+				return true;
+
+			default:
+				return false;
+		}
+	}
+
+	private boolean isALL()
+	{
+		switch (subqueryType)
+		{
+			case EQ_ALL_SUBQUERY:
+			case NE_ALL_SUBQUERY:
+			case LE_ALL_SUBQUERY:
+			case LT_ALL_SUBQUERY:
+			case GE_ALL_SUBQUERY:
+			case GT_ALL_SUBQUERY:
+				return true;
+
+			default:
+				return false;
+		}
+	}
+
+	private boolean isEXISTS()
+	{
+		return subqueryType == EXISTS_SUBQUERY;
+	}
+
+	private boolean isNOT_EXISTS()
+	{
+		return subqueryType == NOT_EXISTS_SUBQUERY;
+	}
+
+	/**
+	 * Convert this IN/ANY subquery, which is known to return at most 1 row,
+	 * to an equivalent expression subquery.
+	 *
+	 * @return Nothing
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	private void changeToCorrespondingExpressionType()
+		throws StandardException
+	{
+  		BinaryOperatorNode bcon = null;
+
+  		switch (subqueryType)
+  		{
+  			case EQ_ANY_SUBQUERY:
+  			case IN_SUBQUERY:
+  				bcon = (BinaryOperatorNode) getNodeFactory().getNode(
+  									C_NodeTypes.BINARY_EQUALS_OPERATOR_NODE,
+  									leftOperand,
+  									this,
+  									getContextManager());
+  				break;
+
+  			case NE_ANY_SUBQUERY:
+  				bcon = (BinaryOperatorNode) getNodeFactory().getNode(
+  								C_NodeTypes.BINARY_NOT_EQUALS_OPERATOR_NODE,
+  								leftOperand,
+  								this,
+  								getContextManager());
+  				break;
+
+  			case LE_ANY_SUBQUERY:
+  				bcon = (BinaryOperatorNode) getNodeFactory().getNode(
+  								C_NodeTypes.BINARY_LESS_EQUALS_OPERATOR_NODE,
+  								leftOperand,
+  								this,
+  								getContextManager());
+  				break;
+
+  			case LT_ANY_SUBQUERY:
+  				bcon = (BinaryOperatorNode) getNodeFactory().getNode(
+  							C_NodeTypes.BINARY_LESS_THAN_OPERATOR_NODE,
+  							leftOperand,
+  							this,
+  							getContextManager());
+  				break;
+
+  			case GE_ANY_SUBQUERY:
+  				bcon = (BinaryOperatorNode) getNodeFactory().getNode(
+  							C_NodeTypes.BINARY_GREATER_EQUALS_OPERATOR_NODE,
+  							leftOperand,
+  							this,
+  							getContextManager());
+  				break;
+
+  			case GT_ANY_SUBQUERY:
+  				bcon = (BinaryOperatorNode) getNodeFactory().getNode(
+  								C_NodeTypes.BINARY_GREATER_THAN_OPERATOR_NODE,
+  								leftOperand,
+  								this,
+  								getContextManager());
+  				break;
+  		}
+
+  		// clean up the state of the tree to reflect a bound expression subquery
+  		subqueryType = EXPRESSION_SUBQUERY;
+  		setDataTypeServices(resultSet.getResultColumns());
+
+  		parentComparisonOperator = (BinaryComparisonOperatorNode) bcon;
+  		/* Set type info for the operator node */
+  		parentComparisonOperator.bindComparisonOperator();
+  		leftOperand = null;
+   }
+
+	private void setDataTypeServices(ResultColumnList resultColumns)
+		throws StandardException
+	{
+		DataTypeDescriptor dts;
+
+		/* Set the result type for this subquery (must be nullable).
+		 * Quantified predicates will return boolean.
+		 * However, the return type of the subquery's result list will 
+		 * probably not be boolean at this point, because we do not
+		 * transform the subquery (other than EXISTS) into 
+		 * (select true/false ...) until preprocess().  So, we force 
+		 * the return type to boolean.
+		 */
+		if (subqueryType == EXPRESSION_SUBQUERY)
+		{
+			dts = ((ResultColumn) resultColumns.elementAt(0)).getTypeServices();
+		}
+		else
+		{
+			dts = getTrueNode().getTypeServices();
+		}
+
+		/* If datatype of underlying resultSet is nullable, reuse it, otherwise
+		 * we need to generate a new one.
+		 */
+		if (! dts.isNullable())
+		{
+			dts = new DataTypeDescriptor(dts, true);
+		}
+		setType(dts);
+	}
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SumAvgAggregateDefinition.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SumAvgAggregateDefinition.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SumAvgAggregateDefinition.java	Fri Sep 24 10:33:20 2004
@@ -1,146 +1,146 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 2001, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
-import org.apache.derby.iapi.services.context.ContextService;
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-import org.apache.derby.impl.sql.execute.SumAggregator;
-import org.apache.derby.impl.sql.execute.AvgAggregator;
-
-import org.apache.derby.catalog.TypeDescriptor;
-import org.apache.derby.iapi.types.TypeId;
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-
-import org.apache.derby.iapi.sql.compile.TypeCompiler;
-import org.apache.derby.iapi.sql.compile.TypeCompilerFactory;
-
-import org.apache.derby.iapi.sql.compile.CompilerContext;
-
-import org.apache.derby.iapi.error.StandardException;
-import org.apache.derby.iapi.reference.ClassName;
-
-/**
- * Defintion for the SUM()/AVG() aggregates.
- *
- * @author jamie
- */
-public class SumAvgAggregateDefinition
-		implements AggregateDefinition 
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2001_2004;
-	private boolean isSum;
-	/**
-	 * Niladic constructor.  Does nothing.  For ease
-	 * Of use, only.
-	 */
-	public SumAvgAggregateDefinition() { super(); }
-
-	/**
-	 * Determines the result datatype.  Accept NumberDataValues
-	 * only.  
-	 * <P>
-	 * <I>Note</I>: In the future you should be able to do
-	 * a sum user data types.  One option would be to run
-	 * sum on anything that implements plus().  In which
-	 * case avg() would need divide().
-	 *
-	 * @param the input type, either a user type or a java.lang object
-	 * @param implementsInterface	the interface it implements
-	 *
-	 * @return the output Class (null if cannot operate on
-	 *	value expression of this type.
-	 */
-	public final TypeDescriptor	getAggregator(TypeDescriptor inputType, 
-				StringBuffer aggregatorClass) 
-	{
-		try
-		{
-			LanguageConnectionContext lcc = (LanguageConnectionContext)
-				ContextService.getContext(LanguageConnectionContext.CONTEXT_ID);
-
-			DataTypeDescriptor dts = new DataTypeDescriptor( (DataTypeDescriptor)inputType, inputType.isNullable());
-			TypeId compType = dts.getTypeId();
-		
-			CompilerContext cc = (CompilerContext)
-				ContextService.getContext(CompilerContext.CONTEXT_ID);
-			TypeCompilerFactory tcf = cc.getTypeCompilerFactory();
-			TypeCompiler tc = tcf.getTypeCompiler(compType);
-		
-			/*
-			** If the class implements NumberDataValue, then we
-			** are in business.  Return type is same as input
-			** type.
-			*/
-			if (compType.isNumericTypeId())
-			{
-				aggregatorClass.append(getAggregatorClassName());
-
-				DataTypeDescriptor outDts = tc.resolveArithmeticOperation( 
-															dts, dts, getOperator());
-				/*
-				** SUM and AVG may return null
-				*/
-				outDts.setNullability(true);
-				return outDts;
-			}
-		}
-		catch (StandardException e)
-		{
-			if (SanityManager.DEBUG)
-			{
-				SanityManager.THROWASSERT("Unexpected exception " + e);
-			}
-		}
-
-		return null;
-	}
-
-	/**
-	 * Return the aggregator class.  
-	 *
-	 * @return SumAggregator.CLASS_NAME/AvgAggregator.CLASS_NAME
-	 */
-	private String getAggregatorClassName()
-	{
-		if ( isSum )
-				return ClassName.SumAggregator;
-		else
-				return ClassName.AvgAggregator;
-	}
-
-	/**
-	 * Return the arithmetic operator corresponding
-	 * to this operation.
-	 *
-	 * @return TypeCompiler.SUM_OP /TypeCompiler.AVG_OP
-	 */
-	protected String getOperator()
-	{
-		if ( isSum )
-				return TypeCompiler.SUM_OP;
-		else
-				return TypeCompiler.AVG_OP;
-	}
-
-	/**
-	 * This is set by the parser.
-	 */
-	public final void setSumOrAvg(boolean isSum)
-	{
-		this.isSum = isSum;
-	}
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 2001, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
+import org.apache.derby.iapi.services.context.ContextService;
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+import org.apache.derby.impl.sql.execute.SumAggregator;
+import org.apache.derby.impl.sql.execute.AvgAggregator;
+
+import org.apache.derby.catalog.TypeDescriptor;
+import org.apache.derby.iapi.types.TypeId;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+
+import org.apache.derby.iapi.sql.compile.TypeCompiler;
+import org.apache.derby.iapi.sql.compile.TypeCompilerFactory;
+
+import org.apache.derby.iapi.sql.compile.CompilerContext;
+
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.reference.ClassName;
+
+/**
+ * Defintion for the SUM()/AVG() aggregates.
+ *
+ * @author jamie
+ */
+public class SumAvgAggregateDefinition
+		implements AggregateDefinition 
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2001_2004;
+	private boolean isSum;
+	/**
+	 * Niladic constructor.  Does nothing.  For ease
+	 * Of use, only.
+	 */
+	public SumAvgAggregateDefinition() { super(); }
+
+	/**
+	 * Determines the result datatype.  Accept NumberDataValues
+	 * only.  
+	 * <P>
+	 * <I>Note</I>: In the future you should be able to do
+	 * a sum user data types.  One option would be to run
+	 * sum on anything that implements plus().  In which
+	 * case avg() would need divide().
+	 *
+	 * @param the input type, either a user type or a java.lang object
+	 * @param implementsInterface	the interface it implements
+	 *
+	 * @return the output Class (null if cannot operate on
+	 *	value expression of this type.
+	 */
+	public final TypeDescriptor	getAggregator(TypeDescriptor inputType, 
+				StringBuffer aggregatorClass) 
+	{
+		try
+		{
+			LanguageConnectionContext lcc = (LanguageConnectionContext)
+				ContextService.getContext(LanguageConnectionContext.CONTEXT_ID);
+
+			DataTypeDescriptor dts = new DataTypeDescriptor( (DataTypeDescriptor)inputType, inputType.isNullable());
+			TypeId compType = dts.getTypeId();
+		
+			CompilerContext cc = (CompilerContext)
+				ContextService.getContext(CompilerContext.CONTEXT_ID);
+			TypeCompilerFactory tcf = cc.getTypeCompilerFactory();
+			TypeCompiler tc = tcf.getTypeCompiler(compType);
+		
+			/*
+			** If the class implements NumberDataValue, then we
+			** are in business.  Return type is same as input
+			** type.
+			*/
+			if (compType.isNumericTypeId())
+			{
+				aggregatorClass.append(getAggregatorClassName());
+
+				DataTypeDescriptor outDts = tc.resolveArithmeticOperation( 
+															dts, dts, getOperator());
+				/*
+				** SUM and AVG may return null
+				*/
+				outDts.setNullability(true);
+				return outDts;
+			}
+		}
+		catch (StandardException e)
+		{
+			if (SanityManager.DEBUG)
+			{
+				SanityManager.THROWASSERT("Unexpected exception " + e);
+			}
+		}
+
+		return null;
+	}
+
+	/**
+	 * Return the aggregator class.  
+	 *
+	 * @return SumAggregator.CLASS_NAME/AvgAggregator.CLASS_NAME
+	 */
+	private String getAggregatorClassName()
+	{
+		if ( isSum )
+				return ClassName.SumAggregator;
+		else
+				return ClassName.AvgAggregator;
+	}
+
+	/**
+	 * Return the arithmetic operator corresponding
+	 * to this operation.
+	 *
+	 * @return TypeCompiler.SUM_OP /TypeCompiler.AVG_OP
+	 */
+	protected String getOperator()
+	{
+		if ( isSum )
+				return TypeCompiler.SUM_OP;
+		else
+				return TypeCompiler.AVG_OP;
+	}
+
+	/**
+	 * This is set by the parser.
+	 */
+	public final void setSumOrAvg(boolean isSum)
+	{
+		this.isSum = isSum;
+	}
+
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableElementList.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableElementList.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableElementList.java	Fri Sep 24 10:33:20 2004
@@ -1,977 +1,977 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package	org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.sql.compile.CompilerContext;
-import org.apache.derby.iapi.sql.compile.C_NodeTypes;
-
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-
-import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
-import org.apache.derby.iapi.sql.dictionary.DataDictionary;
-import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
-import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
-import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
-
-import org.apache.derby.iapi.sql.depend.DependencyManager;
-import org.apache.derby.iapi.sql.depend.ProviderInfo;
-import org.apache.derby.iapi.sql.depend.ProviderList;
-
-import org.apache.derby.iapi.reference.SQLState;
-
-import org.apache.derby.impl.sql.execute.ColumnInfo;
-import org.apache.derby.impl.sql.execute.ConstraintInfo;
-import org.apache.derby.impl.sql.execute.ConstraintConstantAction;
-import org.apache.derby.impl.sql.execute.IndexConstantAction;
-
-import	org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList;
-
-import org.apache.derby.catalog.UUID;
-
-import java.util.Hashtable;
-import java.util.Vector;
-
-/**
- * A TableElementList represents the list of columns and other table elements
- * such as constraints in a CREATE TABLE or ALTER TABLE statement.
- *
- * @author Jeff Lichtman
- */
-
-public class TableElementList extends QueryTreeNodeVector
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	int				numColumns;
-	TableDescriptor td;
-
-	/**
-	 * Add a TableElementNode to this TableElementList
-	 *
-	 * @param tableElement	The TableElementNode to add to this list
-	 *
-	 * @return	Nothing
-	 */
-
-	public void addTableElement(TableElementNode tableElement)
-	{
-		addElement(tableElement);
-		if ((tableElement instanceof ColumnDefinitionNode) ||
-			tableElement.getElementType() == TableElementNode.AT_DROP_COLUMN)
-		{
-			numColumns++;
-		}
-	} 
-
-	/**
-	 * Convert this object to a String.  See comments in QueryTreeNode.java
-	 * for how this should be done for tree printing.
-	 *
-	 * @return	This object as a String
-	 */
-
-	public String toString()
-	{
-		if (SanityManager.DEBUG)
-		{
-			StringBuffer	buffer = new StringBuffer("");
-
-			for (int index = 0; index < size(); index++)
-			{
-				buffer.append(elementAt(index).toString()).append("\n");
-			}
-
-			return buffer.toString();
-		}
-		else
-		{
-			return "";
-		}
-	}
-
-	/**
-	 * Validate this TableElementList.  This includes checking for
-	 * duplicate columns names, and checking that user types really exist.
-	 *
-	 * @param ddlStmt	DDLStatementNode which contains this list
-	 * @param dd		DataDictionary to use
-	 * @param td		TableDescriptor for table, if existing table.
-	 *
-	 * @return	None
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	void validate(DDLStatementNode ddlStmt,
-					     DataDictionary dd,
-						 TableDescriptor td)
-					throws StandardException
-	{
- 		this.td = td;
-		int numAutoCols = 0;
-
-		int			size = size();
-		Hashtable	columnHT = new Hashtable(size + 2, (float) .999);
-		Hashtable	constraintHT = new Hashtable(size + 2, (float) .999);
-		//all the primary key/unique key constraints for this table
-		Vector constraintsVector = new Vector();
-
-		//special case for alter table (td is not null in case of alter table)
-		if (td != null)
-		{
-			//In case of alter table, get the already existing primary key and unique
-			//key constraints for this table. And then we will compare them with  new
-			//primary key/unique key constraint column lists.
-			ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td);
-			ConstraintDescriptor cd;
-
-			if (cdl != null) //table does have some pre-existing constraints defined on it
-			{
-				for (int i=0; i<cdl.size();i++)
-				{
-					cd = cdl.elementAt(i);
-					//if the constraint type is not primary key or unique key, ignore it.
-					if (cd.getConstraintType() == DataDictionary.PRIMARYKEY_CONSTRAINT ||
-					cd.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT)
-						constraintsVector.addElement(cd);
-				}
-			}
-		}
-
-		int tableType = TableDescriptor.BASE_TABLE_TYPE;
-		if (ddlStmt instanceof CreateTableNode)
-			tableType = ((CreateTableNode)ddlStmt).tableType;
-
-		for (int index = 0; index < size; index++)
-		{
-			TableElementNode tableElement = (TableElementNode) elementAt(index);
-
-			if (tableElement instanceof ColumnDefinitionNode)
-			{
-				ColumnDefinitionNode cdn = (ColumnDefinitionNode) elementAt(index);
-				if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE &&
-					(cdn.getDataTypeServices().getTypeId().isLongConcatableTypeId() ||
-					cdn.getDataTypeServices().getTypeId().isUserDefinedTypeId()))
-				{
-					throw StandardException.newException(SQLState.LANG_LONG_DATA_TYPE_NOT_ALLOWED, cdn.getColumnName());
-				}
-				checkForDuplicateColumns(ddlStmt, columnHT, cdn.getColumnName());
-				cdn.checkUserType(td);
-				cdn.bindAndValidateDefault(dd, td);
-				
-				cdn.validateAutoincrement(dd, td, tableType);
-
-				if (tableElement instanceof ModifyColumnNode)
-				{
-					ModifyColumnNode mcdn = (ModifyColumnNode)cdn;
-					mcdn.checkExistingConstraints(td);
-				} else if (cdn.isAutoincrementColumn())
-					numAutoCols ++;
-			}
-			else if (tableElement.getElementType() == TableElementNode.AT_DROP_COLUMN)
-			{
-				String colName = tableElement.getName();
-				if (td.getColumnDescriptor(colName) == null)
-				{
-					throw StandardException.newException(
-												SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE,
-												colName,
-												td.getQualifiedName());
-				}
-				break;
-			}
-
-			/* The rest of this method deals with validating constraints */
-			if (! (tableElement.hasConstraint()))
-			{
-				continue;
-			}
-
-			ConstraintDefinitionNode cdn = (ConstraintDefinitionNode) tableElement;
-
-			cdn.bind(ddlStmt, dd);
-
-			//if constraint is primary key or unique key, add it to the vector
-			if (cdn.getConstraintType() == DataDictionary.PRIMARYKEY_CONSTRAINT ||
-			cdn.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT)
-			{
-				/* In case of create table, the vector can have only ConstraintDefinitionNode
-				* elements. In case of alter table, it can have both ConstraintDefinitionNode
-				* (for new constraints) and ConstraintDescriptor(for pre-existing constraints).
-				*/
-
-				Object destConstraint;
-				String destName = null;
-				String[] destColumnNames = null;
-
-				for (int i=0; i<constraintsVector.size();i++)
-				{
-
-					destConstraint = constraintsVector.elementAt(i);
-					if (destConstraint instanceof ConstraintDefinitionNode)
-					{
-						ConstraintDefinitionNode destCDN = (ConstraintDefinitionNode)destConstraint;
-						destName = destCDN.getConstraintMoniker();
-						destColumnNames = destCDN.getColumnList().getColumnNames();
-					}
-					else if (destConstraint instanceof ConstraintDescriptor)
-					{
-						//will come here only for pre-existing constraints in case of alter table
-						ConstraintDescriptor destCD = (ConstraintDescriptor)destConstraint;
-						destName = destCD.getConstraintName();
-						destColumnNames = destCD.getColumnDescriptors().getColumnNames();
-					}
-					//check if there are multiple constraints with same set of columns
-					if (columnsMatch(cdn.getColumnList().getColumnNames(), destColumnNames))
-						throw StandardException.newException(SQLState.LANG_MULTIPLE_CONSTRAINTS_WITH_SAME_COLUMNS,
-						cdn.getConstraintMoniker(), destName);
-				}
-				constraintsVector.addElement(cdn);
-			}
-
-			/* Make sure that there are no duplicate constraint names in the list */
-			if (cdn instanceof ConstraintDefinitionNode)
-				checkForDuplicateConstraintNames(ddlStmt, constraintHT, cdn.getConstraintMoniker());
-
-			/* Make sure that the constraint we are trying to drop exists */
-			if (cdn.getConstraintType() == DataDictionary.DROP_CONSTRAINT)
-			{
-				/*
-				** If no schema descriptor, then must be an invalid
-				** schema name.
-				*/
-
-				String dropConstraintName = cdn.getConstraintMoniker();
-
-				if (dropConstraintName != null) {
-
-					String dropSchemaName = cdn.getDropSchemaName();
-
-					SchemaDescriptor sd = dropSchemaName == null ? td.getSchemaDescriptor() : 
-											getSchemaDescriptor(dropSchemaName);
-
-					ConstraintDescriptor cd =
-								dd.getConstraintDescriptorByName(
-										td, sd, dropConstraintName,
-										false);
-					if (cd == null)
-					{
-						throw StandardException.newException(SQLState.LANG_DROP_NON_EXISTENT_CONSTRAINT,
-								(sd.getSchemaName() + "."+ dropConstraintName),
-								td.getQualifiedName());
-					}
-					/* Statement is dependendent on the ConstraintDescriptor */
-					getCompilerContext().createDependency(cd);
-				}
-			}
-
-			/* For primary/unique/unique keys, verify that the constraint's column
-			 * list contains valid columns and does not contain any duplicates
-			 * (Also, all columns in a primary key will be set to non-null,
-				but only in Cloudscape mode. SQL and DB2 require explict NOT NULL.
-			 */
-			if (cdn.hasPrimaryKeyConstraint() ||
-				cdn.hasForeignKeyConstraint() ||
-				cdn.hasUniqueKeyConstraint())
-			{
-				verifyUniqueColumnList(ddlStmt, cdn);
-				/* Raise error if primary or unique key columns can be nullable. */
-				if (cdn.hasPrimaryKeyConstraint() || cdn.hasUniqueKeyConstraint())
-				{
-					setColumnListToNotNull(cdn, td);
-				}
-			}
-		}
-
-		/* Can have only one autoincrement column in DB2 mode */
-		if (numAutoCols > 1)
-			throw StandardException.newException(SQLState.LANG_MULTIPLE_AUTOINCREMENT_COLUMNS);
-
-	}
-	
-	/**
-	 * Count the number of constraints of the specified type.
-	 *
-	 * @param constraintType	The constraint type to search for.
-	 *
-	 * @return int	The number of constraints of the specified type.
-	 */
-	public int countConstraints(int constraintType)
-	{
-		int	numConstraints = 0;
-		int size = size();
-
-		for (int index = 0; index < size; index++)
-		{
-			ConstraintDefinitionNode cdn;
-			TableElementNode element = (TableElementNode) elementAt(index);
-
-			if (! (element instanceof ConstraintDefinitionNode))
-			{
-				continue;
-			}
-
-			cdn = (ConstraintDefinitionNode) element;
-
-			if (constraintType == cdn.getConstraintType())
-			{
-				numConstraints++;
-			}
-		}
-
-		return numConstraints;
-	}
-
-	/**
-	 * Count the number of columns.
-	 *
-	 * @return int	The number of columns.
-	 */
-	public int countNumberOfColumns()
-	{
-		return numColumns;
-	}
-
-	/**
-	 * Fill in the ColumnInfo[] for this table element list.
-	 * 
-	 * @param colInfos	The ColumnInfo[] to be filled in.
-	 *
-	 * @return int		The number of constraints in the create table.
-	 */
-	public int genColumnInfos(ColumnInfo[] colInfos)
-	{
-		int	numConstraints = 0;
-		int size = size();
-
-		for (int index = 0; index < size; index++)
-		{
-			if (((TableElementNode) elementAt(index)).getElementType() == TableElementNode.AT_DROP_COLUMN)
-			{
-				colInfos[index] = new ColumnInfo(
-								((TableElementNode) elementAt(index)).getName(),
-								null, null, null, null, null,
-								ColumnInfo.DROP, 0, 0);
-				break;
-			}
-
-			if (! (elementAt(index) instanceof ColumnDefinitionNode))
-			{
-				if (SanityManager.DEBUG)
-				{
-					SanityManager.ASSERT( elementAt(index) instanceof ConstraintDefinitionNode,
-						"elementAt(index) expected to be instanceof " +
-						"ConstraintDefinitionNode");
-				}
-
-				/* Remember how many constraints that we've seen */
-				numConstraints++;
-				continue;
-			}
-
-			ColumnDefinitionNode coldef = (ColumnDefinitionNode) elementAt(index);
-
-			colInfos[index - numConstraints] = 
-				new ColumnInfo(coldef.getColumnName(),
-							   coldef.getDataTypeServices(),
-							   coldef.getDefaultValue(),
-							   coldef.getDefaultInfo(),
-							   (UUID) null,
-							   coldef.getOldDefaultUUID(),
-							   coldef.getAction(),
-							   (coldef.isAutoincrementColumn() ? 
-								coldef.getAutoincrementStart() : 0),
-							   (coldef.isAutoincrementColumn() ? 
-								coldef.getAutoincrementIncrement() : 0));
-
-			/* Remember how many constraints that we've seen */
-			if (coldef.hasConstraint())
-			{
-				numConstraints++;
-			}
-		}
-
-		return numConstraints;
-	}
-	/**
-	 * Append goobered up ResultColumns to the table's RCL.
-	 * This is useful for binding check constraints for CREATE and ALTER TABLE.
-	 *
-	 * @param table		The table in question.
-	 *
-	 * @return Nothing.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public void appendNewColumnsToRCL(FromBaseTable table)
-		throws StandardException
-	{
-		int				 size = size();
-		ResultColumnList rcl = table.getResultColumns();
-		TableName		 exposedName = table.getTableName();
-
-		for (int index = 0; index < size; index++)
-		{
-			if (elementAt(index) instanceof ColumnDefinitionNode)
-			{
-				ColumnDefinitionNode cdn = (ColumnDefinitionNode) elementAt(index);
-				ResultColumn	resultColumn;
-				ValueNode		valueNode;
-
-				/* Build a ResultColumn/BaseColumnNode pair for the column */
-				valueNode = (ValueNode) getNodeFactory().getNode(
-											C_NodeTypes.BASE_COLUMN_NODE,
-											cdn.getColumnName(),
-									  		exposedName,
-											cdn.getDataTypeServices(),
-											getContextManager());
-
-				resultColumn = (ResultColumn) getNodeFactory().getNode(
-												C_NodeTypes.RESULT_COLUMN,
-												cdn.getDataTypeServices(), 
-												valueNode,
-												getContextManager());
-				resultColumn.setName(cdn.getColumnName());
-				rcl.addElement(resultColumn);
-			}
-		}
-	}
-
-	/**
-	 * Bind and validate all of the check constraints in this list against
-	 * the specified FromList.  
-	 *
-	 * @param FromList		The FromList in question.
-	 *
-	 * @return Nothing.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	void bindAndValidateCheckConstraints(FromList fromList)
-		throws StandardException
-	{
-		CompilerContext cc;
-		FromBaseTable				table = (FromBaseTable) fromList.elementAt(0);
-		int						  size = size();
-
-		cc = getCompilerContext();
-
-		Vector aggregateVector = new Vector();
-
-		for (int index = 0; index < size; index++)
-		{
-			ConstraintDefinitionNode cdn;
-			TableElementNode element = (TableElementNode) elementAt(index);
-			ValueNode	checkTree;
-
-			if (! (element instanceof ConstraintDefinitionNode))
-			{
-				continue;
-			}
-
-			cdn = (ConstraintDefinitionNode) element;
-
-			if (cdn.getConstraintType() != DataDictionary.CHECK_CONSTRAINT)
-			{
-				continue;
-			}
-
-			checkTree = cdn.getCheckCondition();
-
-			// bind the check condition
-			// verify that it evaluates to a boolean
-			final int previousReliability = cc.getReliability();
-			try
-			{
-				/* Each check constraint can have its own set of dependencies.
-				 * These dependencies need to be shared with the prepared
-				 * statement as well.  We create a new auxiliary provider list
-				 * for the check constraint, "push" it on the compiler context
-				 * by swapping it with the current auxiliary provider list
-				 * and the "pop" it when we're done by restoring the old 
-				 * auxiliary provider list.
-				 */
-				ProviderList apl = new ProviderList();
-
-				ProviderList prevAPL = cc.getCurrentAuxiliaryProviderList();
-				cc.setCurrentAuxiliaryProviderList(apl);
-
-				// Tell the compiler context to only allow deterministic nodes
-				cc.setReliability( CompilerContext.CHECK_CONSTRAINT );
-				checkTree = checkTree.bindExpression(fromList, (SubqueryList) null,
-										 aggregateVector);
-
-				// no aggregates, please
-				if (aggregateVector.size() != 0)
-				{
-					throw StandardException.newException(SQLState.LANG_INVALID_CHECK_CONSTRAINT, cdn.getConstraintText());
-				}
-				
-				checkTree = checkTree.checkIsBoolean();
-				cdn.setCheckCondition(checkTree);
-
-				/* Save the APL off in the constraint node */
-				if (apl.size() > 0)
-				{
-					cdn.setAuxiliaryProviderList(apl);
-				}
-
-				// Restore the previous AuxiliaryProviderList
-				cc.setCurrentAuxiliaryProviderList(prevAPL);
-			}
-			finally
-			{
-				cc.setReliability(previousReliability);
-			}
-	
-			/* We have a valid check constraint, now build an array of
-			 * 1-based columnIds that the constraint references.
-			 */
-			ResultColumnList rcl = table.getResultColumns();
-			int		numReferenced = rcl.countReferencedColumns();
-			int[]	checkColumnReferences = new int[numReferenced];
-
-			rcl.recordColumnReferences(checkColumnReferences, 1);
-			cdn.setCheckColumnReferences(checkColumnReferences);
-
-			/* Now we build a list with only the referenced columns and
-			 * copy it to the cdn.  Thus we can build the array of
-			 * column names for the referenced columns during generate().
-			 */
-			ResultColumnList refRCL =
-						(ResultColumnList) getNodeFactory().getNode(
-												C_NodeTypes.RESULT_COLUMN_LIST,
-												getContextManager());
-			rcl.copyReferencedColumnsToNewList(refRCL);
-
-			/* A column check constraint can only refer to that column. If this is a
-			 * column constraint, we should have an RCL with that column
-			 */
-			if (cdn.getColumnList() != null)
-			{
-				String colName = ((ResultColumn)(cdn.getColumnList().elementAt(0))).getName();
-				if (numReferenced > 1 ||
-					!colName.equals(((ResultColumn)(refRCL.elementAt(0))).getName()))
-					throw StandardException.newException(SQLState.LANG_DB2_INVALID_CHECK_CONSTRAINT, colName);
-				
-			}
-			cdn.setColumnList(refRCL);
-
-			/* Clear the column references in the RCL so each check constraint
-			 * starts with a clean list.
-			 */
-			rcl.clearColumnReferences();
-		}
-	}
-
-	/**
-	 * Fill in the ConstraintConstantAction[] for this create/alter table.
-	 * 
-	 * @param conActions	The ConstraintConstantAction[] to be filled in.
-	 * @param tableName		The name of the Table being created.
-	 * @param sd			The schema for that table.
-	 * @param dd		The DataDictionary
-	 *
-	 * @return Nothing.
-	 *
-	 * @exception StandardException		Thrown on failure
-	 */
-	void genConstraintActions(
-				ConstraintConstantAction[] conActions,
-				String tableName,
-				SchemaDescriptor tableSd,
-				DataDictionary dd)
-		throws StandardException
-	{
-		int size = size();
-		int conActionIndex = 0;
-		for (int index = 0; index < size; index++)
-		{
-			String[]	columnNames = null;
-			String		generatedConstraintName;
-			TableElementNode ten = (TableElementNode) elementAt(index);
-			IndexConstantAction indexAction = null;
-
-			if (! ten.hasConstraint())
-			{
-				continue;
-			}
-
-			if (ten instanceof ColumnDefinitionNode)
-			{
-				continue;
-			}
-
-			ConstraintDefinitionNode constraintDN = (ConstraintDefinitionNode) ten;
-
-			if (constraintDN.getColumnList() != null)
-			{
-				columnNames = new String[constraintDN.getColumnList().size()];
-				constraintDN.getColumnList().exportNames(columnNames);
-			}
-
-			int constraintType = constraintDN.getConstraintType();
-			String constraintText = constraintDN.getConstraintText();
-
-			/*
-			** If the constraint is not named (e.g.
-			** create table x (x int primary key)), then
-			** the constraintSd is the same as the table.
-			*/
-			String constraintName = constraintDN.getConstraintMoniker();
-
-			/* At execution time, we will generate a unique name for the backing
-			 * index (for CREATE CONSTRAINT) and we will look up the conglomerate
-			 * name (for DROP CONSTRAINT).
-			 */
-			if (constraintDN.requiresBackingIndex())
-			{
-				indexAction = genIndexAction(constraintDN.requiresUniqueIndex(),
-											 null, constraintDN, 
-											 columnNames, true, tableSd, tableName,
-											 constraintType, dd);
-			}
-
-			if (constraintType == DataDictionary.DROP_CONSTRAINT)
-			{
-				conActions[conActionIndex] = 
-					getGenericConstantActionFactory().
-						getDropConstraintConstantAction(
-												 constraintName, 
-												 constraintDN.getDropSchemaName(), /// FiX
-												 tableName,
-												 td.getUUID(),
-												 tableSd.getSchemaName(),
-												 indexAction,
-												 constraintDN.getDropBehavior(),
-                                                 constraintDN.getVerifyType());
-			}
-			else
-			{
-				ProviderList apl = constraintDN.getAuxiliaryProviderList();
-				ConstraintInfo refInfo = null;
-				ProviderInfo[]	providerInfos = null;
-
-				if (constraintDN instanceof FKConstraintDefinitionNode)
-				{
-					refInfo = ((FKConstraintDefinitionNode)constraintDN).getReferencedConstraintInfo();
-				}				
-
-				/* Create the ProviderInfos, if the constraint is dependent on any Providers */
-				if (apl != null && apl.size() > 0)
-				{
-					/* Get all the dependencies for the current statement and transfer
-					 * them to this view.
-					 */
-					DependencyManager dm = dd.getDependencyManager();
-					providerInfos = dm.getPersistentProviderInfos(apl);
-				}
-				else
-				{
-					providerInfos = new ProviderInfo[0];
-				}
-
-				conActions[conActionIndex++] = 
-					getGenericConstantActionFactory().
-						getCreateConstraintConstantAction(
-												 constraintName, 
-											     constraintType,
-												 tableName,
-												 ((td != null) ? td.getUUID() : (UUID) null),
-												 tableSd.getSchemaName(),
-												 columnNames,
-												 indexAction,
-												 constraintText,
-												 true, 		// enabled
-												 refInfo,
-												 providerInfos);
-			}
-		}
-	}
-
-      //check if one array is same as another 
-	private boolean columnsMatch(String[] columnNames1, String[] columnNames2)
-		throws StandardException
-	{
-		int srcCount, srcSize, destCount,destSize;
-		boolean match = true;
-
-		if (columnNames1.length != columnNames2.length)
-			return false;
-
-		srcSize = columnNames1.length;
-		destSize = columnNames2.length;
-
-		for (srcCount = 0; srcCount < srcSize; srcCount++)
-		{
-			match = false;
-			for (destCount = 0; destCount < destSize; destCount++) {
-				if (columnNames1[srcCount].equals(columnNames2[destCount])) {
-					match = true;
-					break;
-				}
-			}
-			if (match == false)
-				return false;
-		}
-
-		return true;
-	}
-
-	private IndexConstantAction genIndexAction(
-										boolean	isUnique,
-										String indexName,
-										ConstraintDefinitionNode cdn,
-										String[] columnNames,
-										boolean isConstraint,
-										SchemaDescriptor sd,
-										String tableName,
-										int constraintType,
-										DataDictionary dd)
-		throws StandardException
-	{
-		if ( indexName == null ) { indexName = cdn.getBackingIndexName(dd); }
-
-		if (constraintType == DataDictionary.DROP_CONSTRAINT)
-		{
-			return	getGenericConstantActionFactory().getDropIndexConstantAction(
-									  null,
-									  indexName,
-									  tableName,
-									  sd.getSchemaName(),
-									  td.getUUID(),
-									  td.getHeapConglomerateId());
-		}
-		else
-		{
-			boolean[]	isAscending = new boolean[columnNames.length];
-			for (int i = 0; i < isAscending.length; i++)
-				isAscending[i] = true;
-			return	getGenericConstantActionFactory().getCreateIndexConstantAction(
-									isUnique,
-									"BTREE", // indexType
-									sd.getSchemaName(),
-									indexName,
-									tableName,
-									((td != null) ? td.getUUID() : (UUID) null),
-									0, // conglomId
-									columnNames,
-									isAscending,
-									isConstraint,
-									cdn.getBackingIndexUUID(),
-									cdn.getProperties());
-		}
-	}
-
-	/**
-	 * Check to make sure that there are no duplicate column names
-	 * in the list.  (The comparison here is case sensitive.
-	 * The work of converting column names that are not quoted
-	 * identifiers to upper case is handled by the parser.)
-	 * RESOLVE: This check will also be performed by alter table.
-	 *
-	 * @param ddlStmt	DDLStatementNode which contains this list
-	 * @param ht		Hashtable for enforcing uniqueness.
-	 * @param colName	Column name to check for.
-	 *
-	 * @return	None
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	private void checkForDuplicateColumns(DDLStatementNode ddlStmt,
-									Hashtable ht,
-									String colName)
-			throws StandardException
-	{
-		Object object = ht.put(colName, colName);
-		if (object != null)
-		{
-			/* RESOLVE - different error messages for create and alter table */
-			if (ddlStmt instanceof CreateTableNode)
-			{
-				throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_CREATE, colName);
-			}
-		}
-	}
-
-	/**
-	 * Check to make sure that there are no duplicate constraint names
-	 * in the list.  (The comparison here is case sensitive.
-	 * The work of converting column names that are not quoted
-	 * identifiers to upper case is handled by the parser.)
-	 * RESOLVE: This check will also be performed by alter table.
-	 *
-	 * @param ddlStmt	DDLStatementNode which contains this list
-	 * @param outer		The element to check against.  Only check
-	 *						TableElements that come after this one, since this
-	 *						one has been checked against the TableElements
-	 *						before it.
-	 *
-	 * @return	None
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	private void checkForDuplicateConstraintNames(DDLStatementNode ddlStmt,
-									Hashtable ht,
-									String constraintName)
-			throws StandardException
-	{
-		if (constraintName == null)
-			return;
-
-		Object object = ht.put(constraintName, constraintName);
-		if (object != null) {
-
-			/* RESOLVE - different error messages for create and alter table */
-			if (ddlStmt instanceof CreateTableNode)
-			{
-				/* RESOLVE - new error message */
-				throw StandardException.newException(SQLState.LANG_DUPLICATE_CONSTRAINT_NAME_CREATE, 
-						constraintName);
-			}
-		}
-	}
-
-	/**
-	 * Verify that a primary/unique table constraint has a valid column list.
-	 * (All columns in table and no duplicates.)
-	 *
-	 * @param ddlStmt	The outer DDLStatementNode
-	 * @param cdn		The ConstraintDefinitionNode
-	 *
-	 * @return Nothing.
-	 *
-	 * @exception	StandardException	Thrown if the column list is invalid
-	 */
-	private void verifyUniqueColumnList(DDLStatementNode ddlStmt,
-								ConstraintDefinitionNode cdn)
-		throws StandardException
-	{
-		String invalidColName;
-
-		/* Verify that every column in the list appears in the table's list of columns */
-		if (ddlStmt instanceof CreateTableNode)
-		{
-			invalidColName = cdn.getColumnList().verifyCreateConstraintColumnList(this);
-			if (invalidColName != null)
-			{
-				throw StandardException.newException(SQLState.LANG_INVALID_CREATE_CONSTRAINT_COLUMN_LIST, 
-								ddlStmt.getRelativeName(),
-								invalidColName);
-			}
-		}
-		else
-		{
-			/* RESOLVE - alter table will need to get table descriptor */
-		}
-
-		/* Check the uniqueness of the column names within the list */
-		invalidColName = cdn.getColumnList().verifyUniqueNames(false);
-		if (invalidColName != null)
-		{
-			throw StandardException.newException(SQLState.LANG_DUPLICATE_CONSTRAINT_COLUMN_NAME, invalidColName);
-		}
-	}
-
-	/**
-	 * Set all columns in that appear in a primary/unique key constraint in a create
-	 * table statement to NOT NULL in Cloudscape mode and raises an error in DB2 mode.
-	 *
-	 * @param cdn		The ConstraintDefinitionNode
-	 * @param td		TableDescriptor for the table
-	 *
-	 * @return Nothing.
-	 */
-	private void setColumnListToNotNull(ConstraintDefinitionNode cdn, TableDescriptor td)
-		throws StandardException
-	{
-		ResultColumnList rcl = cdn.getColumnList();
-		int rclSize = rcl.size();
-		for (int index = 0; index < rclSize; index++)
-		{
-			String colName = ((ResultColumn) rcl.elementAt(index)).getName();
-
-			/* For ALTER TABLE ADD CONSTRAINT, make sure columns are not nullable for
-			 * primary and unique constraints.
-			 */
-			if (td != null && cdn instanceof ConstraintDefinitionNode)
-			{
-				ColumnDescriptor cd = td.getColumnDescriptor(colName);
-				if (cd != null && cd.getType().isNullable())
-					throw StandardException.newException(SQLState.LANG_DB2_ADD_UNIQUE_OR_PRIMARY_KEY_ON_NULL_COLS, colName);
-			}
-
-			setColumnToNotNull(colName);
-		}
-	}
-
-	/**
-	 * Set a column that appears in a primary/unique key constraint in
-	 * a create table statement to NOT NULL (but only in Cloudscape mode).
-	 *
-	 * @param colName	The column name
-	 *
-	 * @return Nothing.
-	 */
-	private void setColumnToNotNull(String colName) throws StandardException
-	{
-		int size = size();
-
-		for (int index = 0; index < size; index++)
-		{
-			TableElementNode tableElement = (TableElementNode) elementAt(index);
-
-			if (tableElement instanceof ColumnDefinitionNode)
-			{
-				ColumnDefinitionNode cdn = (ColumnDefinitionNode) tableElement;
-				if (colName.equals(cdn.getColumnName()))
-				{
-					DataTypeDescriptor dtd = cdn.getDataTypeServices();
-
-					if (dtd.isNullable())
-						throw StandardException.newException(SQLState.LANG_DB2_ADD_UNIQUE_OR_PRIMARY_KEY_ON_NULL_COLS, colName);
-				}
-			}
-		}
-	}
-
-	/**
-	 * Determine whether or not the parameter matches a column name in this list.
-	 *
-	 * @param colName	The column name to search for.
-	 *
-	 * @return boolean  Whether or not a match is found.
-	 */
-	public boolean containsColumnName(String colName)
-	{
-		int size = size();
-		for (int index = 0; index < size; index++)
-		{
-			TableElementNode tableElement = (TableElementNode) elementAt(index);
-
-			if (tableElement instanceof ColumnDefinitionNode)
-			{
-				if (colName.equals(((ColumnDefinitionNode) tableElement).getName()))
-				{
-					return true;
-				}
-			}
-		}
-
-		return false;
-	}
-}
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package	org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.sql.compile.CompilerContext;
+import org.apache.derby.iapi.sql.compile.C_NodeTypes;
+
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+
+import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;
+import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
+import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
+
+import org.apache.derby.iapi.sql.depend.DependencyManager;
+import org.apache.derby.iapi.sql.depend.ProviderInfo;
+import org.apache.derby.iapi.sql.depend.ProviderList;
+
+import org.apache.derby.iapi.reference.SQLState;
+
+import org.apache.derby.impl.sql.execute.ColumnInfo;
+import org.apache.derby.impl.sql.execute.ConstraintInfo;
+import org.apache.derby.impl.sql.execute.ConstraintConstantAction;
+import org.apache.derby.impl.sql.execute.IndexConstantAction;
+
+import	org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList;
+
+import org.apache.derby.catalog.UUID;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * A TableElementList represents the list of columns and other table elements
+ * such as constraints in a CREATE TABLE or ALTER TABLE statement.
+ *
+ * @author Jeff Lichtman
+ */
+
+public class TableElementList extends QueryTreeNodeVector
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	int				numColumns;
+	TableDescriptor td;
+
+	/**
+	 * Add a TableElementNode to this TableElementList
+	 *
+	 * @param tableElement	The TableElementNode to add to this list
+	 *
+	 * @return	Nothing
+	 */
+
+	public void addTableElement(TableElementNode tableElement)
+	{
+		addElement(tableElement);
+		if ((tableElement instanceof ColumnDefinitionNode) ||
+			tableElement.getElementType() == TableElementNode.AT_DROP_COLUMN)
+		{
+			numColumns++;
+		}
+	} 
+
+	/**
+	 * Convert this object to a String.  See comments in QueryTreeNode.java
+	 * for how this should be done for tree printing.
+	 *
+	 * @return	This object as a String
+	 */
+
+	public String toString()
+	{
+		if (SanityManager.DEBUG)
+		{
+			StringBuffer	buffer = new StringBuffer("");
+
+			for (int index = 0; index < size(); index++)
+			{
+				buffer.append(elementAt(index).toString()).append("\n");
+			}
+
+			return buffer.toString();
+		}
+		else
+		{
+			return "";
+		}
+	}
+
+	/**
+	 * Validate this TableElementList.  This includes checking for
+	 * duplicate columns names, and checking that user types really exist.
+	 *
+	 * @param ddlStmt	DDLStatementNode which contains this list
+	 * @param dd		DataDictionary to use
+	 * @param td		TableDescriptor for table, if existing table.
+	 *
+	 * @return	None
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	void validate(DDLStatementNode ddlStmt,
+					     DataDictionary dd,
+						 TableDescriptor td)
+					throws StandardException
+	{
+ 		this.td = td;
+		int numAutoCols = 0;
+
+		int			size = size();
+		Hashtable	columnHT = new Hashtable(size + 2, (float) .999);
+		Hashtable	constraintHT = new Hashtable(size + 2, (float) .999);
+		//all the primary key/unique key constraints for this table
+		Vector constraintsVector = new Vector();
+
+		//special case for alter table (td is not null in case of alter table)
+		if (td != null)
+		{
+			//In case of alter table, get the already existing primary key and unique
+			//key constraints for this table. And then we will compare them with  new
+			//primary key/unique key constraint column lists.
+			ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td);
+			ConstraintDescriptor cd;
+
+			if (cdl != null) //table does have some pre-existing constraints defined on it
+			{
+				for (int i=0; i<cdl.size();i++)
+				{
+					cd = cdl.elementAt(i);
+					//if the constraint type is not primary key or unique key, ignore it.
+					if (cd.getConstraintType() == DataDictionary.PRIMARYKEY_CONSTRAINT ||
+					cd.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT)
+						constraintsVector.addElement(cd);
+				}
+			}
+		}
+
+		int tableType = TableDescriptor.BASE_TABLE_TYPE;
+		if (ddlStmt instanceof CreateTableNode)
+			tableType = ((CreateTableNode)ddlStmt).tableType;
+
+		for (int index = 0; index < size; index++)
+		{
+			TableElementNode tableElement = (TableElementNode) elementAt(index);
+
+			if (tableElement instanceof ColumnDefinitionNode)
+			{
+				ColumnDefinitionNode cdn = (ColumnDefinitionNode) elementAt(index);
+				if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE &&
+					(cdn.getDataTypeServices().getTypeId().isLongConcatableTypeId() ||
+					cdn.getDataTypeServices().getTypeId().isUserDefinedTypeId()))
+				{
+					throw StandardException.newException(SQLState.LANG_LONG_DATA_TYPE_NOT_ALLOWED, cdn.getColumnName());
+				}
+				checkForDuplicateColumns(ddlStmt, columnHT, cdn.getColumnName());
+				cdn.checkUserType(td);
+				cdn.bindAndValidateDefault(dd, td);
+				
+				cdn.validateAutoincrement(dd, td, tableType);
+
+				if (tableElement instanceof ModifyColumnNode)
+				{
+					ModifyColumnNode mcdn = (ModifyColumnNode)cdn;
+					mcdn.checkExistingConstraints(td);
+				} else if (cdn.isAutoincrementColumn())
+					numAutoCols ++;
+			}
+			else if (tableElement.getElementType() == TableElementNode.AT_DROP_COLUMN)
+			{
+				String colName = tableElement.getName();
+				if (td.getColumnDescriptor(colName) == null)
+				{
+					throw StandardException.newException(
+												SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE,
+												colName,
+												td.getQualifiedName());
+				}
+				break;
+			}
+
+			/* The rest of this method deals with validating constraints */
+			if (! (tableElement.hasConstraint()))
+			{
+				continue;
+			}
+
+			ConstraintDefinitionNode cdn = (ConstraintDefinitionNode) tableElement;
+
+			cdn.bind(ddlStmt, dd);
+
+			//if constraint is primary key or unique key, add it to the vector
+			if (cdn.getConstraintType() == DataDictionary.PRIMARYKEY_CONSTRAINT ||
+			cdn.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT)
+			{
+				/* In case of create table, the vector can have only ConstraintDefinitionNode
+				* elements. In case of alter table, it can have both ConstraintDefinitionNode
+				* (for new constraints) and ConstraintDescriptor(for pre-existing constraints).
+				*/
+
+				Object destConstraint;
+				String destName = null;
+				String[] destColumnNames = null;
+
+				for (int i=0; i<constraintsVector.size();i++)
+				{
+
+					destConstraint = constraintsVector.elementAt(i);
+					if (destConstraint instanceof ConstraintDefinitionNode)
+					{
+						ConstraintDefinitionNode destCDN = (ConstraintDefinitionNode)destConstraint;
+						destName = destCDN.getConstraintMoniker();
+						destColumnNames = destCDN.getColumnList().getColumnNames();
+					}
+					else if (destConstraint instanceof ConstraintDescriptor)
+					{
+						//will come here only for pre-existing constraints in case of alter table
+						ConstraintDescriptor destCD = (ConstraintDescriptor)destConstraint;
+						destName = destCD.getConstraintName();
+						destColumnNames = destCD.getColumnDescriptors().getColumnNames();
+					}
+					//check if there are multiple constraints with same set of columns
+					if (columnsMatch(cdn.getColumnList().getColumnNames(), destColumnNames))
+						throw StandardException.newException(SQLState.LANG_MULTIPLE_CONSTRAINTS_WITH_SAME_COLUMNS,
+						cdn.getConstraintMoniker(), destName);
+				}
+				constraintsVector.addElement(cdn);
+			}
+
+			/* Make sure that there are no duplicate constraint names in the list */
+			if (cdn instanceof ConstraintDefinitionNode)
+				checkForDuplicateConstraintNames(ddlStmt, constraintHT, cdn.getConstraintMoniker());
+
+			/* Make sure that the constraint we are trying to drop exists */
+			if (cdn.getConstraintType() == DataDictionary.DROP_CONSTRAINT)
+			{
+				/*
+				** If no schema descriptor, then must be an invalid
+				** schema name.
+				*/
+
+				String dropConstraintName = cdn.getConstraintMoniker();
+
+				if (dropConstraintName != null) {
+
+					String dropSchemaName = cdn.getDropSchemaName();
+
+					SchemaDescriptor sd = dropSchemaName == null ? td.getSchemaDescriptor() : 
+											getSchemaDescriptor(dropSchemaName);
+
+					ConstraintDescriptor cd =
+								dd.getConstraintDescriptorByName(
+										td, sd, dropConstraintName,
+										false);
+					if (cd == null)
+					{
+						throw StandardException.newException(SQLState.LANG_DROP_NON_EXISTENT_CONSTRAINT,
+								(sd.getSchemaName() + "."+ dropConstraintName),
+								td.getQualifiedName());
+					}
+					/* Statement is dependendent on the ConstraintDescriptor */
+					getCompilerContext().createDependency(cd);
+				}
+			}
+
+			/* For primary/unique/unique keys, verify that the constraint's column
+			 * list contains valid columns and does not contain any duplicates
+			 * (Also, all columns in a primary key will be set to non-null,
+				but only in Cloudscape mode. SQL and DB2 require explict NOT NULL.
+			 */
+			if (cdn.hasPrimaryKeyConstraint() ||
+				cdn.hasForeignKeyConstraint() ||
+				cdn.hasUniqueKeyConstraint())
+			{
+				verifyUniqueColumnList(ddlStmt, cdn);
+				/* Raise error if primary or unique key columns can be nullable. */
+				if (cdn.hasPrimaryKeyConstraint() || cdn.hasUniqueKeyConstraint())
+				{
+					setColumnListToNotNull(cdn, td);
+				}
+			}
+		}
+
+		/* Can have only one autoincrement column in DB2 mode */
+		if (numAutoCols > 1)
+			throw StandardException.newException(SQLState.LANG_MULTIPLE_AUTOINCREMENT_COLUMNS);
+
+	}
+	
+	/**
+	 * Count the number of constraints of the specified type.
+	 *
+	 * @param constraintType	The constraint type to search for.
+	 *
+	 * @return int	The number of constraints of the specified type.
+	 */
+	public int countConstraints(int constraintType)
+	{
+		int	numConstraints = 0;
+		int size = size();
+
+		for (int index = 0; index < size; index++)
+		{
+			ConstraintDefinitionNode cdn;
+			TableElementNode element = (TableElementNode) elementAt(index);
+
+			if (! (element instanceof ConstraintDefinitionNode))
+			{
+				continue;
+			}
+
+			cdn = (ConstraintDefinitionNode) element;
+
+			if (constraintType == cdn.getConstraintType())
+			{
+				numConstraints++;
+			}
+		}
+
+		return numConstraints;
+	}
+
+	/**
+	 * Count the number of columns.
+	 *
+	 * @return int	The number of columns.
+	 */
+	public int countNumberOfColumns()
+	{
+		return numColumns;
+	}
+
+	/**
+	 * Fill in the ColumnInfo[] for this table element list.
+	 * 
+	 * @param colInfos	The ColumnInfo[] to be filled in.
+	 *
+	 * @return int		The number of constraints in the create table.
+	 */
+	public int genColumnInfos(ColumnInfo[] colInfos)
+	{
+		int	numConstraints = 0;
+		int size = size();
+
+		for (int index = 0; index < size; index++)
+		{
+			if (((TableElementNode) elementAt(index)).getElementType() == TableElementNode.AT_DROP_COLUMN)
+			{
+				colInfos[index] = new ColumnInfo(
+								((TableElementNode) elementAt(index)).getName(),
+								null, null, null, null, null,
+								ColumnInfo.DROP, 0, 0);
+				break;
+			}
+
+			if (! (elementAt(index) instanceof ColumnDefinitionNode))
+			{
+				if (SanityManager.DEBUG)
+				{
+					SanityManager.ASSERT( elementAt(index) instanceof ConstraintDefinitionNode,
+						"elementAt(index) expected to be instanceof " +
+						"ConstraintDefinitionNode");
+				}
+
+				/* Remember how many constraints that we've seen */
+				numConstraints++;
+				continue;
+			}
+
+			ColumnDefinitionNode coldef = (ColumnDefinitionNode) elementAt(index);
+
+			colInfos[index - numConstraints] = 
+				new ColumnInfo(coldef.getColumnName(),
+							   coldef.getDataTypeServices(),
+							   coldef.getDefaultValue(),
+							   coldef.getDefaultInfo(),
+							   (UUID) null,
+							   coldef.getOldDefaultUUID(),
+							   coldef.getAction(),
+							   (coldef.isAutoincrementColumn() ? 
+								coldef.getAutoincrementStart() : 0),
+							   (coldef.isAutoincrementColumn() ? 
+								coldef.getAutoincrementIncrement() : 0));
+
+			/* Remember how many constraints that we've seen */
+			if (coldef.hasConstraint())
+			{
+				numConstraints++;
+			}
+		}
+
+		return numConstraints;
+	}
+	/**
+	 * Append goobered up ResultColumns to the table's RCL.
+	 * This is useful for binding check constraints for CREATE and ALTER TABLE.
+	 *
+	 * @param table		The table in question.
+	 *
+	 * @return Nothing.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public void appendNewColumnsToRCL(FromBaseTable table)
+		throws StandardException
+	{
+		int				 size = size();
+		ResultColumnList rcl = table.getResultColumns();
+		TableName		 exposedName = table.getTableName();
+
+		for (int index = 0; index < size; index++)
+		{
+			if (elementAt(index) instanceof ColumnDefinitionNode)
+			{
+				ColumnDefinitionNode cdn = (ColumnDefinitionNode) elementAt(index);
+				ResultColumn	resultColumn;
+				ValueNode		valueNode;
+
+				/* Build a ResultColumn/BaseColumnNode pair for the column */
+				valueNode = (ValueNode) getNodeFactory().getNode(
+											C_NodeTypes.BASE_COLUMN_NODE,
+											cdn.getColumnName(),
+									  		exposedName,
+											cdn.getDataTypeServices(),
+											getContextManager());
+
+				resultColumn = (ResultColumn) getNodeFactory().getNode(
+												C_NodeTypes.RESULT_COLUMN,
+												cdn.getDataTypeServices(), 
+												valueNode,
+												getContextManager());
+				resultColumn.setName(cdn.getColumnName());
+				rcl.addElement(resultColumn);
+			}
+		}
+	}
+
+	/**
+	 * Bind and validate all of the check constraints in this list against
+	 * the specified FromList.  
+	 *
+	 * @param FromList		The FromList in question.
+	 *
+	 * @return Nothing.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	void bindAndValidateCheckConstraints(FromList fromList)
+		throws StandardException
+	{
+		CompilerContext cc;
+		FromBaseTable				table = (FromBaseTable) fromList.elementAt(0);
+		int						  size = size();
+
+		cc = getCompilerContext();
+
+		Vector aggregateVector = new Vector();
+
+		for (int index = 0; index < size; index++)
+		{
+			ConstraintDefinitionNode cdn;
+			TableElementNode element = (TableElementNode) elementAt(index);
+			ValueNode	checkTree;
+
+			if (! (element instanceof ConstraintDefinitionNode))
+			{
+				continue;
+			}
+
+			cdn = (ConstraintDefinitionNode) element;
+
+			if (cdn.getConstraintType() != DataDictionary.CHECK_CONSTRAINT)
+			{
+				continue;
+			}
+
+			checkTree = cdn.getCheckCondition();
+
+			// bind the check condition
+			// verify that it evaluates to a boolean
+			final int previousReliability = cc.getReliability();
+			try
+			{
+				/* Each check constraint can have its own set of dependencies.
+				 * These dependencies need to be shared with the prepared
+				 * statement as well.  We create a new auxiliary provider list
+				 * for the check constraint, "push" it on the compiler context
+				 * by swapping it with the current auxiliary provider list
+				 * and the "pop" it when we're done by restoring the old 
+				 * auxiliary provider list.
+				 */
+				ProviderList apl = new ProviderList();
+
+				ProviderList prevAPL = cc.getCurrentAuxiliaryProviderList();
+				cc.setCurrentAuxiliaryProviderList(apl);
+
+				// Tell the compiler context to only allow deterministic nodes
+				cc.setReliability( CompilerContext.CHECK_CONSTRAINT );
+				checkTree = checkTree.bindExpression(fromList, (SubqueryList) null,
+										 aggregateVector);
+
+				// no aggregates, please
+				if (aggregateVector.size() != 0)
+				{
+					throw StandardException.newException(SQLState.LANG_INVALID_CHECK_CONSTRAINT, cdn.getConstraintText());
+				}
+				
+				checkTree = checkTree.checkIsBoolean();
+				cdn.setCheckCondition(checkTree);
+
+				/* Save the APL off in the constraint node */
+				if (apl.size() > 0)
+				{
+					cdn.setAuxiliaryProviderList(apl);
+				}
+
+				// Restore the previous AuxiliaryProviderList
+				cc.setCurrentAuxiliaryProviderList(prevAPL);
+			}
+			finally
+			{
+				cc.setReliability(previousReliability);
+			}
+	
+			/* We have a valid check constraint, now build an array of
+			 * 1-based columnIds that the constraint references.
+			 */
+			ResultColumnList rcl = table.getResultColumns();
+			int		numReferenced = rcl.countReferencedColumns();
+			int[]	checkColumnReferences = new int[numReferenced];
+
+			rcl.recordColumnReferences(checkColumnReferences, 1);
+			cdn.setCheckColumnReferences(checkColumnReferences);
+
+			/* Now we build a list with only the referenced columns and
+			 * copy it to the cdn.  Thus we can build the array of
+			 * column names for the referenced columns during generate().
+			 */
+			ResultColumnList refRCL =
+						(ResultColumnList) getNodeFactory().getNode(
+												C_NodeTypes.RESULT_COLUMN_LIST,
+												getContextManager());
+			rcl.copyReferencedColumnsToNewList(refRCL);
+
+			/* A column check constraint can only refer to that column. If this is a
+			 * column constraint, we should have an RCL with that column
+			 */
+			if (cdn.getColumnList() != null)
+			{
+				String colName = ((ResultColumn)(cdn.getColumnList().elementAt(0))).getName();
+				if (numReferenced > 1 ||
+					!colName.equals(((ResultColumn)(refRCL.elementAt(0))).getName()))
+					throw StandardException.newException(SQLState.LANG_DB2_INVALID_CHECK_CONSTRAINT, colName);
+				
+			}
+			cdn.setColumnList(refRCL);
+
+			/* Clear the column references in the RCL so each check constraint
+			 * starts with a clean list.
+			 */
+			rcl.clearColumnReferences();
+		}
+	}
+
+	/**
+	 * Fill in the ConstraintConstantAction[] for this create/alter table.
+	 * 
+	 * @param conActions	The ConstraintConstantAction[] to be filled in.
+	 * @param tableName		The name of the Table being created.
+	 * @param sd			The schema for that table.
+	 * @param dd		The DataDictionary
+	 *
+	 * @return Nothing.
+	 *
+	 * @exception StandardException		Thrown on failure
+	 */
+	void genConstraintActions(
+				ConstraintConstantAction[] conActions,
+				String tableName,
+				SchemaDescriptor tableSd,
+				DataDictionary dd)
+		throws StandardException
+	{
+		int size = size();
+		int conActionIndex = 0;
+		for (int index = 0; index < size; index++)
+		{
+			String[]	columnNames = null;
+			String		generatedConstraintName;
+			TableElementNode ten = (TableElementNode) elementAt(index);
+			IndexConstantAction indexAction = null;
+
+			if (! ten.hasConstraint())
+			{
+				continue;
+			}
+
+			if (ten instanceof ColumnDefinitionNode)
+			{
+				continue;
+			}
+
+			ConstraintDefinitionNode constraintDN = (ConstraintDefinitionNode) ten;
+
+			if (constraintDN.getColumnList() != null)
+			{
+				columnNames = new String[constraintDN.getColumnList().size()];
+				constraintDN.getColumnList().exportNames(columnNames);
+			}
+
+			int constraintType = constraintDN.getConstraintType();
+			String constraintText = constraintDN.getConstraintText();
+
+			/*
+			** If the constraint is not named (e.g.
+			** create table x (x int primary key)), then
+			** the constraintSd is the same as the table.
+			*/
+			String constraintName = constraintDN.getConstraintMoniker();
+
+			/* At execution time, we will generate a unique name for the backing
+			 * index (for CREATE CONSTRAINT) and we will look up the conglomerate
+			 * name (for DROP CONSTRAINT).
+			 */
+			if (constraintDN.requiresBackingIndex())
+			{
+				indexAction = genIndexAction(constraintDN.requiresUniqueIndex(),
+											 null, constraintDN, 
+											 columnNames, true, tableSd, tableName,
+											 constraintType, dd);
+			}
+
+			if (constraintType == DataDictionary.DROP_CONSTRAINT)
+			{
+				conActions[conActionIndex] = 
+					getGenericConstantActionFactory().
+						getDropConstraintConstantAction(
+												 constraintName, 
+												 constraintDN.getDropSchemaName(), /// FiX
+												 tableName,
+												 td.getUUID(),
+												 tableSd.getSchemaName(),
+												 indexAction,
+												 constraintDN.getDropBehavior(),
+                                                 constraintDN.getVerifyType());
+			}
+			else
+			{
+				ProviderList apl = constraintDN.getAuxiliaryProviderList();
+				ConstraintInfo refInfo = null;
+				ProviderInfo[]	providerInfos = null;
+
+				if (constraintDN instanceof FKConstraintDefinitionNode)
+				{
+					refInfo = ((FKConstraintDefinitionNode)constraintDN).getReferencedConstraintInfo();
+				}				
+
+				/* Create the ProviderInfos, if the constraint is dependent on any Providers */
+				if (apl != null && apl.size() > 0)
+				{
+					/* Get all the dependencies for the current statement and transfer
+					 * them to this view.
+					 */
+					DependencyManager dm = dd.getDependencyManager();
+					providerInfos = dm.getPersistentProviderInfos(apl);
+				}
+				else
+				{
+					providerInfos = new ProviderInfo[0];
+				}
+
+				conActions[conActionIndex++] = 
+					getGenericConstantActionFactory().
+						getCreateConstraintConstantAction(
+												 constraintName, 
+											     constraintType,
+												 tableName,
+												 ((td != null) ? td.getUUID() : (UUID) null),
+												 tableSd.getSchemaName(),
+												 columnNames,
+												 indexAction,
+												 constraintText,
+												 true, 		// enabled
+												 refInfo,
+												 providerInfos);
+			}
+		}
+	}
+
+      //check if one array is same as another 
+	private boolean columnsMatch(String[] columnNames1, String[] columnNames2)
+		throws StandardException
+	{
+		int srcCount, srcSize, destCount,destSize;
+		boolean match = true;
+
+		if (columnNames1.length != columnNames2.length)
+			return false;
+
+		srcSize = columnNames1.length;
+		destSize = columnNames2.length;
+
+		for (srcCount = 0; srcCount < srcSize; srcCount++)
+		{
+			match = false;
+			for (destCount = 0; destCount < destSize; destCount++) {
+				if (columnNames1[srcCount].equals(columnNames2[destCount])) {
+					match = true;
+					break;
+				}
+			}
+			if (match == false)
+				return false;
+		}
+
+		return true;
+	}
+
+	private IndexConstantAction genIndexAction(
+										boolean	isUnique,
+										String indexName,
+										ConstraintDefinitionNode cdn,
+										String[] columnNames,
+										boolean isConstraint,
+										SchemaDescriptor sd,
+										String tableName,
+										int constraintType,
+										DataDictionary dd)
+		throws StandardException
+	{
+		if ( indexName == null ) { indexName = cdn.getBackingIndexName(dd); }
+
+		if (constraintType == DataDictionary.DROP_CONSTRAINT)
+		{
+			return	getGenericConstantActionFactory().getDropIndexConstantAction(
+									  null,
+									  indexName,
+									  tableName,
+									  sd.getSchemaName(),
+									  td.getUUID(),
+									  td.getHeapConglomerateId());
+		}
+		else
+		{
+			boolean[]	isAscending = new boolean[columnNames.length];
+			for (int i = 0; i < isAscending.length; i++)
+				isAscending[i] = true;
+			return	getGenericConstantActionFactory().getCreateIndexConstantAction(
+									isUnique,
+									"BTREE", // indexType
+									sd.getSchemaName(),
+									indexName,
+									tableName,
+									((td != null) ? td.getUUID() : (UUID) null),
+									0, // conglomId
+									columnNames,
+									isAscending,
+									isConstraint,
+									cdn.getBackingIndexUUID(),
+									cdn.getProperties());
+		}
+	}
+
+	/**
+	 * Check to make sure that there are no duplicate column names
+	 * in the list.  (The comparison here is case sensitive.
+	 * The work of converting column names that are not quoted
+	 * identifiers to upper case is handled by the parser.)
+	 * RESOLVE: This check will also be performed by alter table.
+	 *
+	 * @param ddlStmt	DDLStatementNode which contains this list
+	 * @param ht		Hashtable for enforcing uniqueness.
+	 * @param colName	Column name to check for.
+	 *
+	 * @return	None
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	private void checkForDuplicateColumns(DDLStatementNode ddlStmt,
+									Hashtable ht,
+									String colName)
+			throws StandardException
+	{
+		Object object = ht.put(colName, colName);
+		if (object != null)
+		{
+			/* RESOLVE - different error messages for create and alter table */
+			if (ddlStmt instanceof CreateTableNode)
+			{
+				throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_CREATE, colName);
+			}
+		}
+	}
+
+	/**
+	 * Check to make sure that there are no duplicate constraint names
+	 * in the list.  (The comparison here is case sensitive.
+	 * The work of converting column names that are not quoted
+	 * identifiers to upper case is handled by the parser.)
+	 * RESOLVE: This check will also be performed by alter table.
+	 *
+	 * @param ddlStmt	DDLStatementNode which contains this list
+	 * @param outer		The element to check against.  Only check
+	 *						TableElements that come after this one, since this
+	 *						one has been checked against the TableElements
+	 *						before it.
+	 *
+	 * @return	None
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	private void checkForDuplicateConstraintNames(DDLStatementNode ddlStmt,
+									Hashtable ht,
+									String constraintName)
+			throws StandardException
+	{
+		if (constraintName == null)
+			return;
+
+		Object object = ht.put(constraintName, constraintName);
+		if (object != null) {
+
+			/* RESOLVE - different error messages for create and alter table */
+			if (ddlStmt instanceof CreateTableNode)
+			{
+				/* RESOLVE - new error message */
+				throw StandardException.newException(SQLState.LANG_DUPLICATE_CONSTRAINT_NAME_CREATE, 
+						constraintName);
+			}
+		}
+	}
+
+	/**
+	 * Verify that a primary/unique table constraint has a valid column list.
+	 * (All columns in table and no duplicates.)
+	 *
+	 * @param ddlStmt	The outer DDLStatementNode
+	 * @param cdn		The ConstraintDefinitionNode
+	 *
+	 * @return Nothing.
+	 *
+	 * @exception	StandardException	Thrown if the column list is invalid
+	 */
+	private void verifyUniqueColumnList(DDLStatementNode ddlStmt,
+								ConstraintDefinitionNode cdn)
+		throws StandardException
+	{
+		String invalidColName;
+
+		/* Verify that every column in the list appears in the table's list of columns */
+		if (ddlStmt instanceof CreateTableNode)
+		{
+			invalidColName = cdn.getColumnList().verifyCreateConstraintColumnList(this);
+			if (invalidColName != null)
+			{
+				throw StandardException.newException(SQLState.LANG_INVALID_CREATE_CONSTRAINT_COLUMN_LIST, 
+								ddlStmt.getRelativeName(),
+								invalidColName);
+			}
+		}
+		else
+		{
+			/* RESOLVE - alter table will need to get table descriptor */
+		}
+
+		/* Check the uniqueness of the column names within the list */
+		invalidColName = cdn.getColumnList().verifyUniqueNames(false);
+		if (invalidColName != null)
+		{
+			throw StandardException.newException(SQLState.LANG_DUPLICATE_CONSTRAINT_COLUMN_NAME, invalidColName);
+		}
+	}
+
+	/**
+	 * Set all columns in that appear in a primary/unique key constraint in a create
+	 * table statement to NOT NULL in Cloudscape mode and raises an error in DB2 mode.
+	 *
+	 * @param cdn		The ConstraintDefinitionNode
+	 * @param td		TableDescriptor for the table
+	 *
+	 * @return Nothing.
+	 */
+	private void setColumnListToNotNull(ConstraintDefinitionNode cdn, TableDescriptor td)
+		throws StandardException
+	{
+		ResultColumnList rcl = cdn.getColumnList();
+		int rclSize = rcl.size();
+		for (int index = 0; index < rclSize; index++)
+		{
+			String colName = ((ResultColumn) rcl.elementAt(index)).getName();
+
+			/* For ALTER TABLE ADD CONSTRAINT, make sure columns are not nullable for
+			 * primary and unique constraints.
+			 */
+			if (td != null && cdn instanceof ConstraintDefinitionNode)
+			{
+				ColumnDescriptor cd = td.getColumnDescriptor(colName);
+				if (cd != null && cd.getType().isNullable())
+					throw StandardException.newException(SQLState.LANG_DB2_ADD_UNIQUE_OR_PRIMARY_KEY_ON_NULL_COLS, colName);
+			}
+
+			setColumnToNotNull(colName);
+		}
+	}
+
+	/**
+	 * Set a column that appears in a primary/unique key constraint in
+	 * a create table statement to NOT NULL (but only in Cloudscape mode).
+	 *
+	 * @param colName	The column name
+	 *
+	 * @return Nothing.
+	 */
+	private void setColumnToNotNull(String colName) throws StandardException
+	{
+		int size = size();
+
+		for (int index = 0; index < size; index++)
+		{
+			TableElementNode tableElement = (TableElementNode) elementAt(index);
+
+			if (tableElement instanceof ColumnDefinitionNode)
+			{
+				ColumnDefinitionNode cdn = (ColumnDefinitionNode) tableElement;
+				if (colName.equals(cdn.getColumnName()))
+				{
+					DataTypeDescriptor dtd = cdn.getDataTypeServices();
+
+					if (dtd.isNullable())
+						throw StandardException.newException(SQLState.LANG_DB2_ADD_UNIQUE_OR_PRIMARY_KEY_ON_NULL_COLS, colName);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Determine whether or not the parameter matches a column name in this list.
+	 *
+	 * @param colName	The column name to search for.
+	 *
+	 * @return boolean  Whether or not a match is found.
+	 */
+	public boolean containsColumnName(String colName)
+	{
+		int size = size();
+		for (int index = 0; index < size; index++)
+		{
+			TableElementNode tableElement = (TableElementNode) elementAt(index);
+
+			if (tableElement instanceof ColumnDefinitionNode)
+			{
+				if (colName.equals(((ColumnDefinitionNode) tableElement).getName()))
+				{
+					return true;
+				}
+			}
+		}
+
+		return false;
+	}
+}
+

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableElementNode.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableElementNode.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableElementNode.java	Fri Sep 24 10:33:20 2004
@@ -1,182 +1,182 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package	org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-/**
- * A TableElementNode is an item in a TableElementList, and represents
- * a single table element such as a column or constraint in a CREATE TABLE
- * or ALTER TABLE statement.
- *
- * @author Jeff Lichtman
- */
-
-public class TableElementNode extends QueryTreeNode
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-    /////////////////////////////////////////////////////////////////////////
-	//
-	//	CONSTANTS
-	//
-	/////////////////////////////////////////////////////////////////////////
-
-	public	static	final	int	AT_UNKNOWN						= 0;
-	public	static	final	int	AT_ADD_FOREIGN_KEY_CONSTRAINT	= 1;
-	public	static	final	int	AT_ADD_PRIMARY_KEY_CONSTRAINT	= 2;
-	public	static	final	int	AT_ADD_UNIQUE_CONSTRAINT		= 3;
-	public	static	final	int	AT_ADD_CHECK_CONSTRAINT			= 4;
-	public	static	final	int	AT_DROP_CONSTRAINT				= 5;
-	public	static	final	int	AT_MODIFY_COLUMN				= 6;
-	public	static	final	int	AT_DROP_COLUMN					= 7;
-
-
-	/////////////////////////////////////////////////////////////////////////
-	//
-	//	STATE
-	//
-	/////////////////////////////////////////////////////////////////////////
-
-	String	name;
-	int		elementType;	// simple element nodes can share this class,
-							// eg., drop column and rename table/column/index
-							// etc., no need for more classes, an effort to
-							// minimize footprint
-
-	/////////////////////////////////////////////////////////////////////////
-	//
-	//	BEHAVIOR
-	//
-	/////////////////////////////////////////////////////////////////////////
-
-	/**
-	 * Initializer for a TableElementNode
-	 *
-	 * @param name	The name of the table element, if any
-	 */
-
-	public void init(Object name)
-	{
-		this.name = (String) name;
-	}
-
-	/**
-	 * Initializer for a TableElementNode
-	 *
-	 * @param name	The name of the table element, if any
-	 */
-
-	public void init(Object name, Object elementType)
-	{
-		this.name = (String) name;
-		this.elementType = ((Integer) elementType).intValue();
-	}
-
-	/**
-	 * Convert this object to a String.  See comments in QueryTreeNode.java
-	 * for how this should be done for tree printing.
-	 *
-	 * @return	This object as a String
-	 */
-
-	public String toString()
-	{
-		if (SanityManager.DEBUG)
-		{
-			return "name: " + name + "\n" +
-				super.toString();
-		}
-		else
-		{
-			return "";
-		}
-	}
-
-	/**
-	 * Does this element have a primary key constraint.
-	 *
-	 * @return boolean	Whether or not this element has a primary key constraint
-	 */
-	boolean hasPrimaryKeyConstraint()
-	{
-		return false;
-	}
-
-	/**
-	 * Does this element have a unique key constraint.
-	 *
-	 * @return boolean	Whether or not this element has a unique key constraint
-	 */
-	boolean hasUniqueKeyConstraint()
-	{
-		return false;
-	}
-
-	/**
-	 * Does this element have a foreign key constraint.
-	 *
-	 * @return boolean	Whether or not this element has a foreign key constraint
-	 */
-	boolean hasForeignKeyConstraint()
-	{
-		return false;
-	}
-
-	/**
-	 * Does this element have a check constraint.
-	 *
-	 * @return boolean	Whether or not this element has a check constraint
-	 */
-	boolean hasCheckConstraint()
-	{
-		return false;
-	}
-
-	/**
-	 * Does this element have a constraint on it.
-	 *
-	 * @return boolean	Whether or not this element has a constraint on it
-	 */
-	boolean hasConstraint()
-	{
-		return false;
-	}
-
-	/**
-	 * Get the name from this node.
-	 *
-	 * @return String	The name.
-	 */
-	public String getName()
-	{
-		return name;
-	}
-
-	/**
-	  *	Get the type of this table element.
-	  *
-	  *	@return	one of the constants at the front of this file
-	  */
-	int	getElementType()
-	{
-		if ( hasForeignKeyConstraint() ) { return AT_ADD_FOREIGN_KEY_CONSTRAINT; }
-		else if ( hasPrimaryKeyConstraint() ) { return AT_ADD_PRIMARY_KEY_CONSTRAINT; }
-		else if ( hasUniqueKeyConstraint() ) { return AT_ADD_UNIQUE_CONSTRAINT; }
-		else if ( hasCheckConstraint() ) { return AT_ADD_CHECK_CONSTRAINT; }
-		else if ( this instanceof ConstraintDefinitionNode ) { return AT_DROP_CONSTRAINT; }
-		else if ( this instanceof ModifyColumnNode ) { return AT_MODIFY_COLUMN; }
-		else { return elementType; }
-	}
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package	org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+/**
+ * A TableElementNode is an item in a TableElementList, and represents
+ * a single table element such as a column or constraint in a CREATE TABLE
+ * or ALTER TABLE statement.
+ *
+ * @author Jeff Lichtman
+ */
+
+public class TableElementNode extends QueryTreeNode
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+    /////////////////////////////////////////////////////////////////////////
+	//
+	//	CONSTANTS
+	//
+	/////////////////////////////////////////////////////////////////////////
+
+	public	static	final	int	AT_UNKNOWN						= 0;
+	public	static	final	int	AT_ADD_FOREIGN_KEY_CONSTRAINT	= 1;
+	public	static	final	int	AT_ADD_PRIMARY_KEY_CONSTRAINT	= 2;
+	public	static	final	int	AT_ADD_UNIQUE_CONSTRAINT		= 3;
+	public	static	final	int	AT_ADD_CHECK_CONSTRAINT			= 4;
+	public	static	final	int	AT_DROP_CONSTRAINT				= 5;
+	public	static	final	int	AT_MODIFY_COLUMN				= 6;
+	public	static	final	int	AT_DROP_COLUMN					= 7;
+
+
+	/////////////////////////////////////////////////////////////////////////
+	//
+	//	STATE
+	//
+	/////////////////////////////////////////////////////////////////////////
+
+	String	name;
+	int		elementType;	// simple element nodes can share this class,
+							// eg., drop column and rename table/column/index
+							// etc., no need for more classes, an effort to
+							// minimize footprint
+
+	/////////////////////////////////////////////////////////////////////////
+	//
+	//	BEHAVIOR
+	//
+	/////////////////////////////////////////////////////////////////////////
+
+	/**
+	 * Initializer for a TableElementNode
+	 *
+	 * @param name	The name of the table element, if any
+	 */
+
+	public void init(Object name)
+	{
+		this.name = (String) name;
+	}
+
+	/**
+	 * Initializer for a TableElementNode
+	 *
+	 * @param name	The name of the table element, if any
+	 */
+
+	public void init(Object name, Object elementType)
+	{
+		this.name = (String) name;
+		this.elementType = ((Integer) elementType).intValue();
+	}
+
+	/**
+	 * Convert this object to a String.  See comments in QueryTreeNode.java
+	 * for how this should be done for tree printing.
+	 *
+	 * @return	This object as a String
+	 */
+
+	public String toString()
+	{
+		if (SanityManager.DEBUG)
+		{
+			return "name: " + name + "\n" +
+				super.toString();
+		}
+		else
+		{
+			return "";
+		}
+	}
+
+	/**
+	 * Does this element have a primary key constraint.
+	 *
+	 * @return boolean	Whether or not this element has a primary key constraint
+	 */
+	boolean hasPrimaryKeyConstraint()
+	{
+		return false;
+	}
+
+	/**
+	 * Does this element have a unique key constraint.
+	 *
+	 * @return boolean	Whether or not this element has a unique key constraint
+	 */
+	boolean hasUniqueKeyConstraint()
+	{
+		return false;
+	}
+
+	/**
+	 * Does this element have a foreign key constraint.
+	 *
+	 * @return boolean	Whether or not this element has a foreign key constraint
+	 */
+	boolean hasForeignKeyConstraint()
+	{
+		return false;
+	}
+
+	/**
+	 * Does this element have a check constraint.
+	 *
+	 * @return boolean	Whether or not this element has a check constraint
+	 */
+	boolean hasCheckConstraint()
+	{
+		return false;
+	}
+
+	/**
+	 * Does this element have a constraint on it.
+	 *
+	 * @return boolean	Whether or not this element has a constraint on it
+	 */
+	boolean hasConstraint()
+	{
+		return false;
+	}
+
+	/**
+	 * Get the name from this node.
+	 *
+	 * @return String	The name.
+	 */
+	public String getName()
+	{
+		return name;
+	}
+
+	/**
+	  *	Get the type of this table element.
+	  *
+	  *	@return	one of the constants at the front of this file
+	  */
+	int	getElementType()
+	{
+		if ( hasForeignKeyConstraint() ) { return AT_ADD_FOREIGN_KEY_CONSTRAINT; }
+		else if ( hasPrimaryKeyConstraint() ) { return AT_ADD_PRIMARY_KEY_CONSTRAINT; }
+		else if ( hasUniqueKeyConstraint() ) { return AT_ADD_UNIQUE_CONSTRAINT; }
+		else if ( hasCheckConstraint() ) { return AT_ADD_CHECK_CONSTRAINT; }
+		else if ( this instanceof ConstraintDefinitionNode ) { return AT_DROP_CONSTRAINT; }
+		else if ( this instanceof ModifyColumnNode ) { return AT_MODIFY_COLUMN; }
+		else { return elementType; }
+	}
+
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableName.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableName.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableName.java	Fri Sep 24 10:33:20 2004
@@ -1,285 +1,285 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package	org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.sql.dictionary.DataDictionary;
-import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
-import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
-
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-import org.apache.derby.iapi.reference.Property;
-import org.apache.derby.iapi.reference.SQLState;
-
-/**
- * A TableName represents a qualified name, externally represented as a schema name
- * and an object name separated by a dot. This class is mis-named: it is used to
- * represent the names of other object types in addition to tables.
- *
- * @author Jerry Brenner
- */
-
-public class TableName extends QueryTreeNode
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	/* Both schemaName and tableName can be null, however, if 
-	** tableName is null then schemaName must also be null.
-	*/
-	String	tableName;
-	String	schemaName;
-
-	/*
-	** These fields are used to track the being and end
-	** offset of the token from which the TableName came.
-	** These are always set to legitimate values in the
-	** parser.  If a tableName has been generated elsewhere,
-	** they may not be set.  -1 means unset.
-	*/
-	private int		tokBeginOffset = -1;
-	private int		tokEndOffset = -1;
-
-	/**
-	 * Initializer for when you have both the table and schema names.
-	 *
-	 * @param schemaName	The name of the schema being referenced
-	 * @param tableName		The name of the table being referenced	 
-	 */
-
-	public void init(Object schemaName, Object tableName)
-	{
-		this.schemaName = (String) schemaName;
-		this.tableName = (String) tableName;
-	}
-
-	/**
-	 * Initializer for when you have both the table and schema names.
-	 *
-	 * @param schemaName	The name of the schema being referenced
-	 * @param tableName		The name of the table being referenced	 
-	 * @param tokBeginOffset begin position of token for the table name 
-	 *					identifier from parser.  pass in -1 if unknown
-	 * @param tokEndOffset	end position of token for the table name 
-	 *					identifier from parser.  pass in -1 if unknown
-	 */
-	public void init
-	(
-		Object schemaName, 
-		Object tableName, 
-		Object	tokBeginOffset,
-		Object	tokEndOffset
-	)
-	{
-		this.schemaName = (String) schemaName;
-		this.tableName = (String) tableName;
-		this.tokBeginOffset = ((Integer) tokBeginOffset).intValue();
-		this.tokEndOffset = ((Integer) tokEndOffset).intValue();
-	}
-
-	/**
-	 * Get the table name (without the schema name).
-	 *
-	 * @return Table name as a String
-	 */
-
-	public String getTableName()
-	{
-		return tableName;
-	}
-
-	/**
-	 * Get the schema name.
-	 *
-	 * @return Schema name as a String
-	 */
-
-	public String getSchemaName()
-	{
-		return schemaName;
-	}
-
-	/**
-	 * Get the begin offset of the parser token for the table name
-	 * Will only be set when the TableName was generated by the
-	 * parser.
-	 *
-	 * @return the begin offset of the token.  -1 means unknown
-	 */
-	public int getTokenBeginOffset()
-	{
-		return tokBeginOffset;
-	}
-
-	/**
-	 * Get the end offset of the parser token for the table name.
-	 * Will only be set when the TableName was generated by the
-	 * parser.
-	 *
-	 * @return the end offset of the token.  -1 means unknown
-	 */
-	public int getTokenEndOffset()
-	{
-		return tokEndOffset;
-	}
-
-	/**
-	 * Set the schema name.
-	 *
-	 * @param schemaName	 Schema name as a String
-	 *
-	 * @return Nothing.
-	 */
-
-	public void setSchemaName(String schemaName)
-	{
-		this.schemaName = schemaName;
-	}
-
-	/**
-	 * Get the full table name (with the schema name, if explicitly
-	 * specified).
-	 *
-	 * @return Full table name as a String
-	 */
-
-	public String getFullTableName()
-	{
-		if (schemaName != null)
-			return schemaName + "." + tableName;
-		else
-			return tableName;
-	}
-
-	/**
-	 * Convert this object to a String.  See comments in QueryTreeNode.java
-	 * for how this should be done for tree printing.
-	 *
-	 * @return	This object as a String
-	 */
-
-	public String toString()
-	{
-		return getFullTableName();
-	}
-
-	/**
-	 * 2 TableNames are equal if their both their schemaNames and tableNames are
-	 * equal, or if this node's full table name is null (which happens when a
-	 * SELECT * is expanded).  Also, only check table names if the schema
-	 * name(s) are null.
-	 *
-	 * @param otherTableName	The other TableName.
-	 *
-	 * @return boolean		Whether or not the 2 TableNames are equal.
-	 */
-	public boolean equals(TableName otherTableName)
-	{
-		String fullTableName = getFullTableName();
-		if (fullTableName == null)
-		{
-			return true;
-		}
-		else if ((schemaName == null) || 
-				 (otherTableName.getSchemaName() == null))
-		{
-			return tableName.equals(otherTableName.getTableName());
-		}
-		else
-		{
-			return fullTableName.equals(otherTableName.getFullTableName());
-		}
-	}
-
-	/**
-	 * 2 TableNames are equal if their both their schemaNames and tableNames are
-	 * equal, or if this node's full table name is null (which happens when a
-	 * SELECT * is expanded).  Also, only check table names if the schema
-	 * name(s) are null.
-	 *
-	 * @param otherSchemaName	The other TableName.
-	 * @param otherTableName	The other TableName.
-	 *
-	 * @return boolean		Whether or not the 2 TableNames are equal.
-	 */
-	public boolean equals(String otherSchemaName, String otherTableName)
-	{
-		String fullTableName = getFullTableName();
-		if (fullTableName == null)
-		{
-			return true;
-		}
-		else if ((schemaName == null) || 
-				 (otherSchemaName == null))
-		{
-			return tableName.equals(otherTableName);
-		}
-		else
-		{
-			return fullTableName.equals(otherSchemaName+"."+otherTableName);
-		}
-	}
-
-	///////////////////////////////////////////////////////////////////////
-	//
-	//	BIND METHODS
-	//
-	///////////////////////////////////////////////////////////////////////
-
-	/**
-	  *	Bind this TableName. This means filling in the schema name if it
-	  *	wasn't specified.
-	  *
-	  *	@param	dataDictionary	Data dictionary to bind against.
-	  *
-	  *	@exception StandardException		Thrown on error
-	  */
-	public void	bind( DataDictionary	dataDictionary )
-		                       throws StandardException
-	{
-        schemaName = getSchemaDescriptor(schemaName).getSchemaName();
-	}
-
-	///////////////////////////////////////////////////////////////////////
-	//
-	//	OBJECT INTERFACE
-	//
-	///////////////////////////////////////////////////////////////////////
-
-	/**
-	  *	Returns a hashcode for this tableName. This allows us to use TableNames
-	  *	as keys in hash lists.
-	  *
-	  *	@return	hashcode for this tablename
-	  */
-	public	int	hashCode()
-	{
-		return	getFullTableName().hashCode();
-	}
-
-	/**
-	  *	Compares two TableNames. Needed for hashing logic to work.
-	  *
-	  *	@param	other	other tableName
-	  */
-	public	boolean	equals( Object other )
-	{
-		if ( !( other instanceof TableName ) ) { return false; }
-
-		TableName		that = (TableName) other;
-
-		return	this.getFullTableName().equals( that.getFullTableName() );
-	}
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package	org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;
+import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+import org.apache.derby.iapi.reference.Property;
+import org.apache.derby.iapi.reference.SQLState;
+
+/**
+ * A TableName represents a qualified name, externally represented as a schema name
+ * and an object name separated by a dot. This class is mis-named: it is used to
+ * represent the names of other object types in addition to tables.
+ *
+ * @author Jerry Brenner
+ */
+
+public class TableName extends QueryTreeNode
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	/* Both schemaName and tableName can be null, however, if 
+	** tableName is null then schemaName must also be null.
+	*/
+	String	tableName;
+	String	schemaName;
+
+	/*
+	** These fields are used to track the being and end
+	** offset of the token from which the TableName came.
+	** These are always set to legitimate values in the
+	** parser.  If a tableName has been generated elsewhere,
+	** they may not be set.  -1 means unset.
+	*/
+	private int		tokBeginOffset = -1;
+	private int		tokEndOffset = -1;
+
+	/**
+	 * Initializer for when you have both the table and schema names.
+	 *
+	 * @param schemaName	The name of the schema being referenced
+	 * @param tableName		The name of the table being referenced	 
+	 */
+
+	public void init(Object schemaName, Object tableName)
+	{
+		this.schemaName = (String) schemaName;
+		this.tableName = (String) tableName;
+	}
+
+	/**
+	 * Initializer for when you have both the table and schema names.
+	 *
+	 * @param schemaName	The name of the schema being referenced
+	 * @param tableName		The name of the table being referenced	 
+	 * @param tokBeginOffset begin position of token for the table name 
+	 *					identifier from parser.  pass in -1 if unknown
+	 * @param tokEndOffset	end position of token for the table name 
+	 *					identifier from parser.  pass in -1 if unknown
+	 */
+	public void init
+	(
+		Object schemaName, 
+		Object tableName, 
+		Object	tokBeginOffset,
+		Object	tokEndOffset
+	)
+	{
+		this.schemaName = (String) schemaName;
+		this.tableName = (String) tableName;
+		this.tokBeginOffset = ((Integer) tokBeginOffset).intValue();
+		this.tokEndOffset = ((Integer) tokEndOffset).intValue();
+	}
+
+	/**
+	 * Get the table name (without the schema name).
+	 *
+	 * @return Table name as a String
+	 */
+
+	public String getTableName()
+	{
+		return tableName;
+	}
+
+	/**
+	 * Get the schema name.
+	 *
+	 * @return Schema name as a String
+	 */
+
+	public String getSchemaName()
+	{
+		return schemaName;
+	}
+
+	/**
+	 * Get the begin offset of the parser token for the table name
+	 * Will only be set when the TableName was generated by the
+	 * parser.
+	 *
+	 * @return the begin offset of the token.  -1 means unknown
+	 */
+	public int getTokenBeginOffset()
+	{
+		return tokBeginOffset;
+	}
+
+	/**
+	 * Get the end offset of the parser token for the table name.
+	 * Will only be set when the TableName was generated by the
+	 * parser.
+	 *
+	 * @return the end offset of the token.  -1 means unknown
+	 */
+	public int getTokenEndOffset()
+	{
+		return tokEndOffset;
+	}
+
+	/**
+	 * Set the schema name.
+	 *
+	 * @param schemaName	 Schema name as a String
+	 *
+	 * @return Nothing.
+	 */
+
+	public void setSchemaName(String schemaName)
+	{
+		this.schemaName = schemaName;
+	}
+
+	/**
+	 * Get the full table name (with the schema name, if explicitly
+	 * specified).
+	 *
+	 * @return Full table name as a String
+	 */
+
+	public String getFullTableName()
+	{
+		if (schemaName != null)
+			return schemaName + "." + tableName;
+		else
+			return tableName;
+	}
+
+	/**
+	 * Convert this object to a String.  See comments in QueryTreeNode.java
+	 * for how this should be done for tree printing.
+	 *
+	 * @return	This object as a String
+	 */
+
+	public String toString()
+	{
+		return getFullTableName();
+	}
+
+	/**
+	 * 2 TableNames are equal if their both their schemaNames and tableNames are
+	 * equal, or if this node's full table name is null (which happens when a
+	 * SELECT * is expanded).  Also, only check table names if the schema
+	 * name(s) are null.
+	 *
+	 * @param otherTableName	The other TableName.
+	 *
+	 * @return boolean		Whether or not the 2 TableNames are equal.
+	 */
+	public boolean equals(TableName otherTableName)
+	{
+		String fullTableName = getFullTableName();
+		if (fullTableName == null)
+		{
+			return true;
+		}
+		else if ((schemaName == null) || 
+				 (otherTableName.getSchemaName() == null))
+		{
+			return tableName.equals(otherTableName.getTableName());
+		}
+		else
+		{
+			return fullTableName.equals(otherTableName.getFullTableName());
+		}
+	}
+
+	/**
+	 * 2 TableNames are equal if their both their schemaNames and tableNames are
+	 * equal, or if this node's full table name is null (which happens when a
+	 * SELECT * is expanded).  Also, only check table names if the schema
+	 * name(s) are null.
+	 *
+	 * @param otherSchemaName	The other TableName.
+	 * @param otherTableName	The other TableName.
+	 *
+	 * @return boolean		Whether or not the 2 TableNames are equal.
+	 */
+	public boolean equals(String otherSchemaName, String otherTableName)
+	{
+		String fullTableName = getFullTableName();
+		if (fullTableName == null)
+		{
+			return true;
+		}
+		else if ((schemaName == null) || 
+				 (otherSchemaName == null))
+		{
+			return tableName.equals(otherTableName);
+		}
+		else
+		{
+			return fullTableName.equals(otherSchemaName+"."+otherTableName);
+		}
+	}
+
+	///////////////////////////////////////////////////////////////////////
+	//
+	//	BIND METHODS
+	//
+	///////////////////////////////////////////////////////////////////////
+
+	/**
+	  *	Bind this TableName. This means filling in the schema name if it
+	  *	wasn't specified.
+	  *
+	  *	@param	dataDictionary	Data dictionary to bind against.
+	  *
+	  *	@exception StandardException		Thrown on error
+	  */
+	public void	bind( DataDictionary	dataDictionary )
+		                       throws StandardException
+	{
+        schemaName = getSchemaDescriptor(schemaName).getSchemaName();
+	}
+
+	///////////////////////////////////////////////////////////////////////
+	//
+	//	OBJECT INTERFACE
+	//
+	///////////////////////////////////////////////////////////////////////
+
+	/**
+	  *	Returns a hashcode for this tableName. This allows us to use TableNames
+	  *	as keys in hash lists.
+	  *
+	  *	@return	hashcode for this tablename
+	  */
+	public	int	hashCode()
+	{
+		return	getFullTableName().hashCode();
+	}
+
+	/**
+	  *	Compares two TableNames. Needed for hashing logic to work.
+	  *
+	  *	@param	other	other tableName
+	  */
+	public	boolean	equals( Object other )
+	{
+		if ( !( other instanceof TableName ) ) { return false; }
+
+		TableName		that = (TableName) other;
+
+		return	this.getFullTableName().equals( that.getFullTableName() );
+	}
+
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableOperatorNode.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableOperatorNode.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableOperatorNode.java	Fri Sep 24 10:33:20 2004
@@ -1,877 +1,877 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package	org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.services.context.ContextManager;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
-import org.apache.derby.iapi.sql.compile.CompilerContext;
-import org.apache.derby.iapi.sql.compile.Optimizable;
-import org.apache.derby.iapi.sql.compile.Visitable;
-import org.apache.derby.iapi.sql.compile.Visitor;
-import org.apache.derby.iapi.sql.compile.Optimizer;
-import org.apache.derby.iapi.sql.compile.OptimizableList;
-import org.apache.derby.iapi.sql.compile.CostEstimate;
-import org.apache.derby.iapi.sql.compile.OptimizerFactory;
-import org.apache.derby.iapi.sql.compile.RequiredRowOrdering;
-import org.apache.derby.iapi.sql.compile.C_NodeTypes;
-
-import org.apache.derby.iapi.sql.dictionary.DataDictionary;
-import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
-
-import org.apache.derby.iapi.util.JBitSet;
-
-import java.util.Properties;
-
-/**
- * A TableOperatorNode represents a relational operator like UNION, INTERSECT,
- * JOIN, etc. that takes two tables as parameters and returns a table.  The
- * parameters it takes are represented as ResultSetNodes.
- *
- * Currently, all known table operators are binary operators, so there are no
- * subclasses of this node type called "BinaryTableOperatorNode" and
- * "UnaryTableOperatorNode".
- *
- * @author Jeff Lichtman
- */
-
-public abstract class TableOperatorNode extends FromTable
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	boolean			nestedInParens;
-	ResultSetNode	leftResultSet;
-	ResultSetNode	rightResultSet;
-	Optimizer		leftOptimizer;
-	Optimizer		rightOptimizer;
-	private boolean 	leftModifyAccessPathsDone;
-	private boolean 	rightModifyAccessPathsDone;
-
-	/**
-	 * Initializer for a TableOperatorNode.
-	 *
-	 * @param leftResultSet		The ResultSetNode on the left side of this node
-	 * @param rightResultSet	The ResultSetNode on the right side of this node
-	 * @param tableProperties	Properties list associated with the table
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public void init(Object leftResultSet,
-							 Object rightResultSet,
-							 Object tableProperties)
-				throws StandardException
-	{
-		/* correlationName is always null */
-		init(null, tableProperties);
-		this.leftResultSet = (ResultSetNode) leftResultSet;
-		this.rightResultSet = (ResultSetNode) rightResultSet;
-	}
-
-	/**
-	 * @see Optimizable#modifyAccessPath
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public Optimizable modifyAccessPath(JBitSet outerTables) throws StandardException
-	{
-		boolean callModifyAccessPaths = false;
-
-		if (leftResultSet instanceof FromTable)
-		{
-			if (leftOptimizer != null)
-				leftOptimizer.modifyAccessPaths();
-			else
-			{
-				leftResultSet = 
-					(ResultSetNode)
-						((FromTable) leftResultSet).modifyAccessPath(outerTables);
-			}
-			leftModifyAccessPathsDone = true;
-		}
-		else
-		{
-			callModifyAccessPaths = true;
-		}
-
-		if (rightResultSet instanceof FromTable)
-		{
-			if (rightOptimizer != null)
-				rightOptimizer.modifyAccessPaths();
-			else
-			{
-				rightResultSet = 
-					(ResultSetNode)
-						((FromTable) rightResultSet).modifyAccessPath(outerTables);
-			}
-			rightModifyAccessPathsDone = true;
-		}
-		else
-		{
-			callModifyAccessPaths = true;
-		}
-
-		if (callModifyAccessPaths)
-		{
-			return (Optimizable) modifyAccessPaths();
-		}
-		return this;
-	}
-
-	/** @see Optimizable#verifyProperties 
-	 * @exception StandardException		Thrown on error
-	 */
-	public void verifyProperties(DataDictionary dDictionary)
-		throws StandardException
-	{
-		if (leftResultSet instanceof Optimizable)
-		{
-			((Optimizable) leftResultSet).verifyProperties(dDictionary);
-		}
-		if (rightResultSet instanceof Optimizable)
-		{
-			((Optimizable) rightResultSet).verifyProperties(dDictionary);
-		}
-
-		super.verifyProperties(dDictionary);
-	}
-
-	/**
-	 * Convert this object to a String.  See comments in QueryTreeNode.java
-	 * for how this should be done for tree printing.
-	 *
-	 * @return	This object as a String
-	 */
-
-	public String toString()
-	{
-		if (SanityManager.DEBUG)
-		{
-			return "nestedInParens: " + nestedInParens + "\n" +
-				leftResultSet.toString() + "\n" +
-				rightResultSet.toString() + "\n" + 
-				super.toString();
-		}
-		else
-		{
-			return "";
-		}
-	}
-
-	/**
-	 * Prints the sub-nodes of this object.  See QueryTreeNode.java for
-	 * how tree printing is supposed to work.
-	 *
-	 * @param depth		The depth of this node in the tree
-	 *
-	 * @return	Nothing
-	 */
-
-	public void printSubNodes(int depth)
-	{
-		if (SanityManager.DEBUG)
-		{
-			super.printSubNodes(depth);
-
-			if (leftResultSet != null)
-			{
-				printLabel(depth, "leftResultSet: ");
-				leftResultSet.printSubNodes(depth + 1);
-			}
-
-			if (rightResultSet != null)
-			{
-				printLabel(depth, "rightResultSet: ");
-				rightResultSet.printSubNodes(depth + 1);
-			}
-		}
-	}
-
-	/**
-	 * Get the leftResultSet from this node.
-	 *
-	 * @return ResultSetNode	The leftResultSet from this node.
-	 */
-	public ResultSetNode getLeftResultSet()
-	{
-		return leftResultSet;
-	}
-
-	/**
-	 * Get the rightResultSet from this node.
-	 *
-	 * @return ResultSetNode	The rightResultSet from this node.
-	 */
-	public ResultSetNode getRightResultSet()
-	{
-		return rightResultSet;
-	}
-
-	public ResultSetNode getLeftmostResultSet()
-	{
-		if (leftResultSet instanceof TableOperatorNode)
-		{
-			return ((TableOperatorNode) leftResultSet).getLeftmostResultSet();
-		}
-		else
-		{
-			return leftResultSet;
-		}
-	}
-
-	public void setLeftmostResultSet(ResultSetNode newLeftResultSet)
-	{
-		if (leftResultSet instanceof TableOperatorNode)
-		{
-			((TableOperatorNode) leftResultSet).setLeftmostResultSet(newLeftResultSet);
-		}
-		else
-		{
-			this.leftResultSet = newLeftResultSet;
-		}
-	}
-
-	/**
-	 * Set the (query block) level (0-based) for this FromTable.
-	 *
-	 * @param level		The query block level for this FromTable.
-	 *
-	 * @return Nothing
-	 */
-	public void setLevel(int level)
-	{
-		super.setLevel(level);
-		if (leftResultSet instanceof FromTable)
-		{
-			((FromTable) leftResultSet).setLevel(level);
-		}
-		if (rightResultSet instanceof FromTable)
-		{
-			((FromTable) rightResultSet).setLevel(level);
-		}
-	}
-
-	/**
-	 * Return the exposed name for this table, which is the name that
-	 * can be used to refer to this table in the rest of the query.
-	 *
-	 * @return	The exposed name for this table.
-	 */
-
-	public String getExposedName()
-	{
-		return null;
-	}
-
-	/**
-	 * Mark whether or not this node is nested in parens.  (Useful to parser
-	 * since some trees get created left deep and others right deep.)
-	 *
-	 * @param nestedInParens	Whether or not this node is nested in parens.
-	 *
-	 * @return Nothing.
-	 */
-	public void setNestedInParens(boolean nestedInParens)
-	{
-		this.nestedInParens = nestedInParens;
-	}
-
-	/**
-	 * Return whether or not the table operator for this node was
-	 * nested in parens in the query.  (Useful to parser
-	 * since some trees get created left deep and others right deep.)
-	 *
-	 * @return boolean		Whether or not this node was nested in parens.
-	 */
-	public boolean getNestedInParens()
-	{
-		return nestedInParens;
-	}
-
-
-	/**
-	 * Bind the non VTI tables in this TableOperatorNode. This means getting
-	 * their TableDescriptors from the DataDictionary.
-	 * We will build an unbound RCL for this node.  This RCL must be
-	 * "bound by hand" after the underlying left and right RCLs
-	 * are bound.
-	 *
-	 * @param dataDictionary	The DataDictionary to use for binding
-	 * @param fromListParam		FromList to use/append to.
-	 *
-	 * @return	ResultSetNode		Returns this.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public ResultSetNode bindNonVTITables(DataDictionary dataDictionary, 
-						  FromList fromListParam) 
-							throws StandardException
-	{
-		leftResultSet = leftResultSet.bindNonVTITables(dataDictionary, fromListParam);
-		rightResultSet = rightResultSet.bindNonVTITables(dataDictionary, fromListParam);
-		/* Assign the tableNumber */
-		if (tableNumber == -1)  // allow re-bind, in which case use old number
-			tableNumber = getCompilerContext().getNextTableNumber();
-
-		return this;
-	}
-
-	/**
-	 * Bind the VTI tables in this TableOperatorNode. This means getting
-	 * their TableDescriptors from the DataDictionary.
-	 * We will build an unbound RCL for this node.  This RCL must be
-	 * "bound by hand" after the underlying left and right RCLs
-	 * are bound.
-	 *
-	 * @param fromListParam		FromList to use/append to.
-	 *
-	 * @return	ResultSetNode		Returns this.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public ResultSetNode bindVTITables(FromList fromListParam) 
-							throws StandardException
-	{
-		leftResultSet = leftResultSet.bindVTITables(fromListParam);
-		rightResultSet = rightResultSet.bindVTITables(fromListParam);
-
-		return this;
-	}
-
-	/**
-	 * Bind the expressions under this TableOperatorNode.  This means
-	 * binding the sub-expressions, as well as figuring out what the
-	 * return type is for each expression.
-	 *
-	 * @return	Nothing
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public void bindExpressions(FromList fromListParam)
-				throws StandardException
-	{
-		/*
-		** Parameters not allowed in select list of either side of union,
-		** except when the union is for a table constructor.
-		*/
-		if ( ! (this instanceof UnionNode) ||
-			 ! ((UnionNode) this).tableConstructor())
-		{
-			leftResultSet.rejectParameters();
-			rightResultSet.rejectParameters();
-		}
-
-		leftResultSet.bindExpressions(fromListParam);
-		rightResultSet.bindExpressions(fromListParam);
-	}
-
-	/**
-	 * Check for (and reject) ? parameters directly under the ResultColumns.
-	 * This is done for SELECT statements.  For TableOperatorNodes, we
-	 * simply pass the check through to the left and right children.
-	 *
-	 * @return	Nothing
-	 *
-	 * @exception StandardException		Thrown if a ? parameter found
-	 *									directly under a ResultColumn
-	 */
-
-	public void rejectParameters() throws StandardException
-	{
-		leftResultSet.rejectParameters();
-		rightResultSet.rejectParameters();
-	}
-
-	/**
-	 * Bind the expressions in this ResultSetNode if it has tables.  This means binding the
-	 * sub-expressions, as well as figuring out what the return type is for
-	 * each expression.
-	 *
-	 * @param fromListParam		FromList to use/append to.
-	 *
-	 * @return	Nothing
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public void bindExpressionsWithTables(FromList fromListParam)
-					throws StandardException
-	{
-		/*
-		** Parameters not allowed in select list of either side of union,
-		** except when the union is for a table constructor.
-		*/
-		if ( ! (this instanceof UnionNode) ||
-			 ! ((UnionNode) this).tableConstructor())
-		{
-			leftResultSet.rejectParameters();
-			rightResultSet.rejectParameters();
-		}
-
-		leftResultSet.bindExpressionsWithTables(fromListParam);
-		rightResultSet.bindExpressionsWithTables(fromListParam);
-	}
-
-	/**
-	 * Bind the result columns of this ResultSetNode when there is no
-	 * base table to bind them to.  This is useful for SELECT statements,
-	 * where the result columns get their types from the expressions that
-	 * live under them.
-	 *
-	 * @param fromListParam		FromList to use/append to.
-	 *
-	 * @return	Nothing
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public void bindResultColumns(FromList fromListParam)
-					throws StandardException
-	{
-		leftResultSet.bindResultColumns(fromListParam);
-		rightResultSet.bindResultColumns(fromListParam);
-	}
-
-	/**
-	 * Bind the result columns for this ResultSetNode to a base table.
-	 * This is useful for INSERT and UPDATE statements, where the
-	 * result columns get their types from the table being updated or
-	 * inserted into.
-	 * If a result column list is specified, then the verification that the 
-	 * result column list does not contain any duplicates will be done when
-	 * binding them by name.
-	 *
-	 * @param targetTableDescriptor	The TableDescriptor for the table being
-	 *				updated or inserted into
-	 * @param targetColumnList	For INSERT statements, the user
-	 *					does not have to supply column
-	 *					names (for example, "insert into t
-	 *					values (1,2,3)".  When this
-	 *					parameter is null, it means that
-	 *					the user did not supply column
-	 *					names, and so the binding should
-	 *					be done based on order.  When it
-	 *					is not null, it means do the binding
-	 *					by name, not position.
-	 * @param statement			Calling DMLStatementNode (Insert or Update)
-	 * @param fromListParam		FromList to use/append to.
-	 *
-	 * @return	Nothing
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public void bindResultColumns(TableDescriptor targetTableDescriptor,
-					FromVTI targetVTI,
-					ResultColumnList targetColumnList,
-					DMLStatementNode statement,
-					FromList fromListParam)
-				throws StandardException
-	{
-		leftResultSet.bindResultColumns(targetTableDescriptor,
-										targetVTI,
-										targetColumnList,
-										statement, fromListParam);
-		rightResultSet.bindResultColumns(targetTableDescriptor,
-										targetVTI,
-										targetColumnList,
-										statement, fromListParam);
-	}
-
-	/** 
-	 * Determine whether or not the specified name is an exposed name in
-	 * the current query block.
-	 *
-	 * @param name	The specified name to search for as an exposed name.
-	 * @param schemaName	Schema name, if non-null.
-	 * @param exactMatch	Whether or not we need an exact match on specified schema and table
-	 *						names or match on table id.
-	 *
-	 * @return The FromTable, if any, with the exposed name.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	protected FromTable getFromTableByName(String name, String schemaName, boolean exactMatch)
-		throws StandardException
-	{
-		FromTable result = leftResultSet.getFromTableByName(name, schemaName, exactMatch);
-
-		/* We search both sides for a TableOperatorNode (join nodes)
-		 * but only the left side for a UnionNode.
-		 */
-		if (result == null)
-		{
-			result = rightResultSet.getFromTableByName(name, schemaName, exactMatch);
-		}
-		return result;
-	}
-
-	/** 
-	 * Put a ProjectRestrictNode on top of each FromTable in the FromList.
-	 * ColumnReferences must continue to point to the same ResultColumn, so
-	 * that ResultColumn must percolate up to the new PRN.  However,
-	 * that ResultColumn will point to a new expression, a VirtualColumnNode, 
-	 * which points to the FromTable and the ResultColumn that is the source for
-	 * the ColumnReference.  
-	 * (The new PRN will have the original of the ResultColumnList and
-	 * the ResultColumns from that list.  The FromTable will get shallow copies
-	 * of the ResultColumnList and its ResultColumns.  ResultColumn.expression
-	 * will remain at the FromTable, with the PRN getting a new 
-	 * VirtualColumnNode for each ResultColumn.expression.)
-	 * We then project out the non-referenced columns.  If there are no referenced
-	 * columns, then the PRN's ResultColumnList will consist of a single ResultColumn
-	 * whose expression is 1.
-	 *
-	 * @param numTables			Number of tables in the DML Statement
-	 * @param gbl				The group by list, if any
-	 * @param fromList			The from list, if any
-	 *
-	 * @return The generated ProjectRestrictNode atop the original FromTable.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public ResultSetNode preprocess(int numTables,
-									GroupByList gbl,
-									FromList fromList)
-								throws StandardException
-	{
-		leftResultSet = leftResultSet.preprocess(numTables, gbl, fromList);
-		/* If leftResultSet is a FromSubquery, then we must explicitly extract
-		 * out the subquery (flatten it).  (SelectNodes have their own
-		 * method of flattening them.
-		 */
-		if (leftResultSet instanceof FromSubquery)
-		{
-			leftResultSet = ((FromSubquery) leftResultSet).extractSubquery(numTables);
-		}
-		rightResultSet = rightResultSet.preprocess(numTables, gbl, fromList);
-		/* If rightResultSet is a FromSubquery, then we must explicitly extract
-		 * out the subquery (flatten it).  (SelectNodes have their own
-		 * method of flattening them.
-		 */
-		if (rightResultSet instanceof FromSubquery)
-		{
-			rightResultSet = ((FromSubquery) rightResultSet).extractSubquery(numTables);
-		}
-
-		/* Build the referenced table map (left || right) */
-		referencedTableMap = (JBitSet) leftResultSet.getReferencedTableMap().clone();
-		referencedTableMap.or((JBitSet) rightResultSet.getReferencedTableMap());
-		referencedTableMap.set(tableNumber);
-
-		/* Only generate a PRN if this node is not a flattenable join node. */
-		if (isFlattenableJoinNode())
-		{
-			return this;
-		}
-		else
-		{
-			/* Project out any unreferenced RCs before we generate the PRN.
-			 * NOTE: We have to do this at the end of preprocess since it has to 
-			 * be from the bottom up.  We can't do it until the join expression is 
-			 * bound, since the join expression may contain column references that
-			 * are not referenced anywhere else above us.
-			 */
-            projectResultColumns();
-			return genProjectRestrict(numTables);
-		}
-	}
-
-    /**
-     * Find the unreferenced result columns and project them out. This is used in pre-processing joins
-     * that are not flattened into the where clause.
-     */
-    void projectResultColumns() throws StandardException
-    {
-        resultColumns.doProjection();
-    }
-    
-    /**
-     * Set the referenced columns in the column list if it may not be correct.
-     */
-    void setReferencedColumns()
-    {}
-    
-	/**
-	 * Optimize a TableOperatorNode. 
-	 *
-	 * @param dataDictionary	The DataDictionary to use for optimization
-	 * @param predicateList		The PredicateList to apply.
-	 *
-	 * @return	ResultSetNode	The top of the optimized query tree
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public ResultSetNode optimize(DataDictionary dataDictionary,
-								  PredicateList predicateList,
-								  double outerRows)
-				throws StandardException
-	{
-		/* Get an optimizer, so we can get a cost structure */
-		Optimizer optimizer =
-							getOptimizer(
-								(FromList) getNodeFactory().getNode(
-									C_NodeTypes.FROM_LIST,
-									getNodeFactory().doJoinOrderOptimization(),
-									this,
-									getContextManager()),
-									predicateList,
-									dataDictionary,
-									(RequiredRowOrdering) null);
-
-		costEstimate = optimizer.newCostEstimate();
-
-		/* RESOLVE: This is just a stub for now */
-		leftResultSet = leftResultSet.optimize(
-											dataDictionary,
-											predicateList,
-											outerRows);
-		rightResultSet = rightResultSet.optimize(
-											dataDictionary,
-											predicateList,
-											outerRows);
-
-		/* The cost is the sum of the two child costs */
-		costEstimate.setCost(leftResultSet.getCostEstimate().getEstimatedCost(),
-							 leftResultSet.getCostEstimate().rowCount(),
-							 leftResultSet.getCostEstimate().singleScanRowCount() +
-							 rightResultSet.getCostEstimate().singleScanRowCount());
-
-		costEstimate.add(rightResultSet.costEstimate, costEstimate);
-
-		return this;
-	}
-
-	/**
-	 * @see ResultSetNode#modifyAccessPaths
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public ResultSetNode modifyAccessPaths() throws StandardException
-	{
-		/* Beetle 4454 - union all with another union all would modify access
-		 * paths twice causing NullPointerException, make sure we don't
-		 * do this again, if we have already done it in modifyAccessPaths(outertables)
-		 */
-		if (!leftModifyAccessPathsDone)
-		{
-			if (leftOptimizer != null)
-				leftOptimizer.modifyAccessPaths();
-			else
-				leftResultSet = leftResultSet.modifyAccessPaths();
-		}
-		if (!rightModifyAccessPathsDone)
-		{
-			if (rightOptimizer != null)
-				rightOptimizer.modifyAccessPaths();
-			else
-				rightResultSet = rightResultSet.modifyAccessPaths();
-		}
-		return this;
-	}
-
-	/**
-	 * Search to see if a query references the specifed table name.
-	 *
-	 * @param name		Table name (String) to search for.
-	 * @param baseTable	Whether or not name is for a base table
-	 *
-	 * @return	true if found, else false
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public boolean referencesTarget(String name, boolean baseTable)
-		throws StandardException
-	{
-		return leftResultSet.referencesTarget(name, baseTable) ||
-			   rightResultSet.referencesTarget(name, baseTable);
-	}
-
-	/**
-	 * Return true if the node references SESSION schema tables (temporary or permanent)
-	 *
-	 * @return	true if references SESSION schema tables, else false
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public boolean referencesSessionSchema()
-		throws StandardException
-	{
-		return leftResultSet.referencesSessionSchema() ||
-			   rightResultSet.referencesSessionSchema();
-	}
-
-	/** 
-	 * Optimize a source result set to this table operator.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	protected ResultSetNode optimizeSource(
-							Optimizer optimizer,
-							ResultSetNode sourceResultSet,
-							PredicateList predList,
-							CostEstimate outerCost)
-			throws StandardException
-	{
-		ResultSetNode	retval;
-
-		if (sourceResultSet instanceof FromTable)
-		{
-			FromList optList = (FromList) getNodeFactory().getNode(
-									C_NodeTypes.FROM_LIST,
-									getNodeFactory().doJoinOrderOptimization(),
-									sourceResultSet,
-									getContextManager());
-
-			/* If there is no predicate list, create an empty one */
-			if (predList == null)
-				predList = (PredicateList) getNodeFactory().getNode(
-												C_NodeTypes.PREDICATE_LIST,
-												getContextManager());
-
-			LanguageConnectionContext lcc = getLanguageConnectionContext();
-			OptimizerFactory optimizerFactory = lcc.getOptimizerFactory();
-			optimizer = optimizerFactory.getOptimizer(optList,
-													predList,
-													getDataDictionary(),
-													(RequiredRowOrdering) null,
-													getCompilerContext().getNumTables(),
-													  lcc);
-
-			if (sourceResultSet == leftResultSet)
-			{
-				leftOptimizer = optimizer;
-			}
-			else if (sourceResultSet == rightResultSet)
-			{
-				rightOptimizer = optimizer;
-			}
-			else
-			{
-				if (SanityManager.DEBUG)
-					SanityManager.THROWASSERT("Result set being optimized is neither left nor right");
-			}
-			
-			/*
-			** Set the estimated number of outer rows from the outer part of
-			** the plan.
-			*/
-			optimizer.setOuterRows(outerCost.rowCount());
-
-			/* Optimize the underlying result set */
-			while (optimizer.getNextPermutation())
-			{
-				while (optimizer.getNextDecoratedPermutation())
-				{
-					optimizer.costPermutation();
-				}
-			}
-
-			retval = sourceResultSet;
-		}
-		else
-		{
-			retval = sourceResultSet.optimize(
-										optimizer.getDataDictionary(),
-										predList,
-										outerCost.rowCount());
-		}
-
-		return retval;
-	}
-
-	/**
-	 * Decrement (query block) level (0-based) for 
-	 * all of the tables in this ResultSet tree.
-	 * This is useful when flattening a subquery.
-	 *
-	 * @param decrement	The amount to decrement by.
-	 *
-	 * @return Nothing;
-	 */
-	void decrementLevel(int decrement)
-	{
-		leftResultSet.decrementLevel(decrement);
-		rightResultSet.decrementLevel(decrement);
-	}
-
-	/**
-	 * Replace any DEFAULTs with the associated tree for the default.
-	 *
-	 * @param ttd	The TableDescriptor for the target table.
-	 * @param tcl	The RCL for the target table.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	void replaceDefaults(TableDescriptor ttd, ResultColumnList tcl) 
-		throws StandardException
-	{
-		leftResultSet.replaceDefaults(ttd, tcl);
-		rightResultSet.replaceDefaults(ttd, tcl);
-	}
-
-	/**
-	 * Notify the underlying result set tree that the result is
-	 * ordering dependent.  (For example, no bulk fetch on an index
-	 * if under an IndexRowToBaseRow.)
-	 *
-	 * @return Nothing.
-	 */
-	void markOrderingDependent()
-	{
-		leftResultSet.markOrderingDependent();
-		rightResultSet.markOrderingDependent();
-	}
-
-	/**
-	 * Accept a visitor, and call v.visit()
-	 * on child nodes as necessary.  
-	 * 
-	 * @param v the visitor
-	 *
-	 * @exception StandardException on error
-	 */
-	public Visitable accept(Visitor v) 
-		throws StandardException
-	{
-		if (v.skipChildren(this))
-		{
-			return v.visit(this);
-		}
-
-		Visitable returnNode = super.accept(v);
-
-		if (leftResultSet != null && !v.stopTraversal())
-		{
-			leftResultSet = (ResultSetNode)leftResultSet.accept(v);
-		}
-		if (rightResultSet != null && !v.stopTraversal())
-		{
-			rightResultSet = (ResultSetNode)rightResultSet.accept(v);
-		}
-		return returnNode;
-	}
-
-	/** 
-	 * apparently something special needs to be done for me....
-	 */
-	public boolean needsSpecialRCLBinding()
-	{
-		return true;
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package	org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.services.context.ContextManager;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
+import org.apache.derby.iapi.sql.compile.CompilerContext;
+import org.apache.derby.iapi.sql.compile.Optimizable;
+import org.apache.derby.iapi.sql.compile.Visitable;
+import org.apache.derby.iapi.sql.compile.Visitor;
+import org.apache.derby.iapi.sql.compile.Optimizer;
+import org.apache.derby.iapi.sql.compile.OptimizableList;
+import org.apache.derby.iapi.sql.compile.CostEstimate;
+import org.apache.derby.iapi.sql.compile.OptimizerFactory;
+import org.apache.derby.iapi.sql.compile.RequiredRowOrdering;
+import org.apache.derby.iapi.sql.compile.C_NodeTypes;
+
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
+
+import org.apache.derby.iapi.util.JBitSet;
+
+import java.util.Properties;
+
+/**
+ * A TableOperatorNode represents a relational operator like UNION, INTERSECT,
+ * JOIN, etc. that takes two tables as parameters and returns a table.  The
+ * parameters it takes are represented as ResultSetNodes.
+ *
+ * Currently, all known table operators are binary operators, so there are no
+ * subclasses of this node type called "BinaryTableOperatorNode" and
+ * "UnaryTableOperatorNode".
+ *
+ * @author Jeff Lichtman
+ */
+
+public abstract class TableOperatorNode extends FromTable
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	boolean			nestedInParens;
+	ResultSetNode	leftResultSet;
+	ResultSetNode	rightResultSet;
+	Optimizer		leftOptimizer;
+	Optimizer		rightOptimizer;
+	private boolean 	leftModifyAccessPathsDone;
+	private boolean 	rightModifyAccessPathsDone;
+
+	/**
+	 * Initializer for a TableOperatorNode.
+	 *
+	 * @param leftResultSet		The ResultSetNode on the left side of this node
+	 * @param rightResultSet	The ResultSetNode on the right side of this node
+	 * @param tableProperties	Properties list associated with the table
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public void init(Object leftResultSet,
+							 Object rightResultSet,
+							 Object tableProperties)
+				throws StandardException
+	{
+		/* correlationName is always null */
+		init(null, tableProperties);
+		this.leftResultSet = (ResultSetNode) leftResultSet;
+		this.rightResultSet = (ResultSetNode) rightResultSet;
+	}
+
+	/**
+	 * @see Optimizable#modifyAccessPath
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public Optimizable modifyAccessPath(JBitSet outerTables) throws StandardException
+	{
+		boolean callModifyAccessPaths = false;
+
+		if (leftResultSet instanceof FromTable)
+		{
+			if (leftOptimizer != null)
+				leftOptimizer.modifyAccessPaths();
+			else
+			{
+				leftResultSet = 
+					(ResultSetNode)
+						((FromTable) leftResultSet).modifyAccessPath(outerTables);
+			}
+			leftModifyAccessPathsDone = true;
+		}
+		else
+		{
+			callModifyAccessPaths = true;
+		}
+
+		if (rightResultSet instanceof FromTable)
+		{
+			if (rightOptimizer != null)
+				rightOptimizer.modifyAccessPaths();
+			else
+			{
+				rightResultSet = 
+					(ResultSetNode)
+						((FromTable) rightResultSet).modifyAccessPath(outerTables);
+			}
+			rightModifyAccessPathsDone = true;
+		}
+		else
+		{
+			callModifyAccessPaths = true;
+		}
+
+		if (callModifyAccessPaths)
+		{
+			return (Optimizable) modifyAccessPaths();
+		}
+		return this;
+	}
+
+	/** @see Optimizable#verifyProperties 
+	 * @exception StandardException		Thrown on error
+	 */
+	public void verifyProperties(DataDictionary dDictionary)
+		throws StandardException
+	{
+		if (leftResultSet instanceof Optimizable)
+		{
+			((Optimizable) leftResultSet).verifyProperties(dDictionary);
+		}
+		if (rightResultSet instanceof Optimizable)
+		{
+			((Optimizable) rightResultSet).verifyProperties(dDictionary);
+		}
+
+		super.verifyProperties(dDictionary);
+	}
+
+	/**
+	 * Convert this object to a String.  See comments in QueryTreeNode.java
+	 * for how this should be done for tree printing.
+	 *
+	 * @return	This object as a String
+	 */
+
+	public String toString()
+	{
+		if (SanityManager.DEBUG)
+		{
+			return "nestedInParens: " + nestedInParens + "\n" +
+				leftResultSet.toString() + "\n" +
+				rightResultSet.toString() + "\n" + 
+				super.toString();
+		}
+		else
+		{
+			return "";
+		}
+	}
+
+	/**
+	 * Prints the sub-nodes of this object.  See QueryTreeNode.java for
+	 * how tree printing is supposed to work.
+	 *
+	 * @param depth		The depth of this node in the tree
+	 *
+	 * @return	Nothing
+	 */
+
+	public void printSubNodes(int depth)
+	{
+		if (SanityManager.DEBUG)
+		{
+			super.printSubNodes(depth);
+
+			if (leftResultSet != null)
+			{
+				printLabel(depth, "leftResultSet: ");
+				leftResultSet.printSubNodes(depth + 1);
+			}
+
+			if (rightResultSet != null)
+			{
+				printLabel(depth, "rightResultSet: ");
+				rightResultSet.printSubNodes(depth + 1);
+			}
+		}
+	}
+
+	/**
+	 * Get the leftResultSet from this node.
+	 *
+	 * @return ResultSetNode	The leftResultSet from this node.
+	 */
+	public ResultSetNode getLeftResultSet()
+	{
+		return leftResultSet;
+	}
+
+	/**
+	 * Get the rightResultSet from this node.
+	 *
+	 * @return ResultSetNode	The rightResultSet from this node.
+	 */
+	public ResultSetNode getRightResultSet()
+	{
+		return rightResultSet;
+	}
+
+	public ResultSetNode getLeftmostResultSet()
+	{
+		if (leftResultSet instanceof TableOperatorNode)
+		{
+			return ((TableOperatorNode) leftResultSet).getLeftmostResultSet();
+		}
+		else
+		{
+			return leftResultSet;
+		}
+	}
+
+	public void setLeftmostResultSet(ResultSetNode newLeftResultSet)
+	{
+		if (leftResultSet instanceof TableOperatorNode)
+		{
+			((TableOperatorNode) leftResultSet).setLeftmostResultSet(newLeftResultSet);
+		}
+		else
+		{
+			this.leftResultSet = newLeftResultSet;
+		}
+	}
+
+	/**
+	 * Set the (query block) level (0-based) for this FromTable.
+	 *
+	 * @param level		The query block level for this FromTable.
+	 *
+	 * @return Nothing
+	 */
+	public void setLevel(int level)
+	{
+		super.setLevel(level);
+		if (leftResultSet instanceof FromTable)
+		{
+			((FromTable) leftResultSet).setLevel(level);
+		}
+		if (rightResultSet instanceof FromTable)
+		{
+			((FromTable) rightResultSet).setLevel(level);
+		}
+	}
+
+	/**
+	 * Return the exposed name for this table, which is the name that
+	 * can be used to refer to this table in the rest of the query.
+	 *
+	 * @return	The exposed name for this table.
+	 */
+
+	public String getExposedName()
+	{
+		return null;
+	}
+
+	/**
+	 * Mark whether or not this node is nested in parens.  (Useful to parser
+	 * since some trees get created left deep and others right deep.)
+	 *
+	 * @param nestedInParens	Whether or not this node is nested in parens.
+	 *
+	 * @return Nothing.
+	 */
+	public void setNestedInParens(boolean nestedInParens)
+	{
+		this.nestedInParens = nestedInParens;
+	}
+
+	/**
+	 * Return whether or not the table operator for this node was
+	 * nested in parens in the query.  (Useful to parser
+	 * since some trees get created left deep and others right deep.)
+	 *
+	 * @return boolean		Whether or not this node was nested in parens.
+	 */
+	public boolean getNestedInParens()
+	{
+		return nestedInParens;
+	}
+
+
+	/**
+	 * Bind the non VTI tables in this TableOperatorNode. This means getting
+	 * their TableDescriptors from the DataDictionary.
+	 * We will build an unbound RCL for this node.  This RCL must be
+	 * "bound by hand" after the underlying left and right RCLs
+	 * are bound.
+	 *
+	 * @param dataDictionary	The DataDictionary to use for binding
+	 * @param fromListParam		FromList to use/append to.
+	 *
+	 * @return	ResultSetNode		Returns this.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public ResultSetNode bindNonVTITables(DataDictionary dataDictionary, 
+						  FromList fromListParam) 
+							throws StandardException
+	{
+		leftResultSet = leftResultSet.bindNonVTITables(dataDictionary, fromListParam);
+		rightResultSet = rightResultSet.bindNonVTITables(dataDictionary, fromListParam);
+		/* Assign the tableNumber */
+		if (tableNumber == -1)  // allow re-bind, in which case use old number
+			tableNumber = getCompilerContext().getNextTableNumber();
+
+		return this;
+	}
+
+	/**
+	 * Bind the VTI tables in this TableOperatorNode. This means getting
+	 * their TableDescriptors from the DataDictionary.
+	 * We will build an unbound RCL for this node.  This RCL must be
+	 * "bound by hand" after the underlying left and right RCLs
+	 * are bound.
+	 *
+	 * @param fromListParam		FromList to use/append to.
+	 *
+	 * @return	ResultSetNode		Returns this.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public ResultSetNode bindVTITables(FromList fromListParam) 
+							throws StandardException
+	{
+		leftResultSet = leftResultSet.bindVTITables(fromListParam);
+		rightResultSet = rightResultSet.bindVTITables(fromListParam);
+
+		return this;
+	}
+
+	/**
+	 * Bind the expressions under this TableOperatorNode.  This means
+	 * binding the sub-expressions, as well as figuring out what the
+	 * return type is for each expression.
+	 *
+	 * @return	Nothing
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public void bindExpressions(FromList fromListParam)
+				throws StandardException
+	{
+		/*
+		** Parameters not allowed in select list of either side of union,
+		** except when the union is for a table constructor.
+		*/
+		if ( ! (this instanceof UnionNode) ||
+			 ! ((UnionNode) this).tableConstructor())
+		{
+			leftResultSet.rejectParameters();
+			rightResultSet.rejectParameters();
+		}
+
+		leftResultSet.bindExpressions(fromListParam);
+		rightResultSet.bindExpressions(fromListParam);
+	}
+
+	/**
+	 * Check for (and reject) ? parameters directly under the ResultColumns.
+	 * This is done for SELECT statements.  For TableOperatorNodes, we
+	 * simply pass the check through to the left and right children.
+	 *
+	 * @return	Nothing
+	 *
+	 * @exception StandardException		Thrown if a ? parameter found
+	 *									directly under a ResultColumn
+	 */
+
+	public void rejectParameters() throws StandardException
+	{
+		leftResultSet.rejectParameters();
+		rightResultSet.rejectParameters();
+	}
+
+	/**
+	 * Bind the expressions in this ResultSetNode if it has tables.  This means binding the
+	 * sub-expressions, as well as figuring out what the return type is for
+	 * each expression.
+	 *
+	 * @param fromListParam		FromList to use/append to.
+	 *
+	 * @return	Nothing
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public void bindExpressionsWithTables(FromList fromListParam)
+					throws StandardException
+	{
+		/*
+		** Parameters not allowed in select list of either side of union,
+		** except when the union is for a table constructor.
+		*/
+		if ( ! (this instanceof UnionNode) ||
+			 ! ((UnionNode) this).tableConstructor())
+		{
+			leftResultSet.rejectParameters();
+			rightResultSet.rejectParameters();
+		}
+
+		leftResultSet.bindExpressionsWithTables(fromListParam);
+		rightResultSet.bindExpressionsWithTables(fromListParam);
+	}
+
+	/**
+	 * Bind the result columns of this ResultSetNode when there is no
+	 * base table to bind them to.  This is useful for SELECT statements,
+	 * where the result columns get their types from the expressions that
+	 * live under them.
+	 *
+	 * @param fromListParam		FromList to use/append to.
+	 *
+	 * @return	Nothing
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public void bindResultColumns(FromList fromListParam)
+					throws StandardException
+	{
+		leftResultSet.bindResultColumns(fromListParam);
+		rightResultSet.bindResultColumns(fromListParam);
+	}
+
+	/**
+	 * Bind the result columns for this ResultSetNode to a base table.
+	 * This is useful for INSERT and UPDATE statements, where the
+	 * result columns get their types from the table being updated or
+	 * inserted into.
+	 * If a result column list is specified, then the verification that the 
+	 * result column list does not contain any duplicates will be done when
+	 * binding them by name.
+	 *
+	 * @param targetTableDescriptor	The TableDescriptor for the table being
+	 *				updated or inserted into
+	 * @param targetColumnList	For INSERT statements, the user
+	 *					does not have to supply column
+	 *					names (for example, "insert into t
+	 *					values (1,2,3)".  When this
+	 *					parameter is null, it means that
+	 *					the user did not supply column
+	 *					names, and so the binding should
+	 *					be done based on order.  When it
+	 *					is not null, it means do the binding
+	 *					by name, not position.
+	 * @param statement			Calling DMLStatementNode (Insert or Update)
+	 * @param fromListParam		FromList to use/append to.
+	 *
+	 * @return	Nothing
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public void bindResultColumns(TableDescriptor targetTableDescriptor,
+					FromVTI targetVTI,
+					ResultColumnList targetColumnList,
+					DMLStatementNode statement,
+					FromList fromListParam)
+				throws StandardException
+	{
+		leftResultSet.bindResultColumns(targetTableDescriptor,
+										targetVTI,
+										targetColumnList,
+										statement, fromListParam);
+		rightResultSet.bindResultColumns(targetTableDescriptor,
+										targetVTI,
+										targetColumnList,
+										statement, fromListParam);
+	}
+
+	/** 
+	 * Determine whether or not the specified name is an exposed name in
+	 * the current query block.
+	 *
+	 * @param name	The specified name to search for as an exposed name.
+	 * @param schemaName	Schema name, if non-null.
+	 * @param exactMatch	Whether or not we need an exact match on specified schema and table
+	 *						names or match on table id.
+	 *
+	 * @return The FromTable, if any, with the exposed name.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	protected FromTable getFromTableByName(String name, String schemaName, boolean exactMatch)
+		throws StandardException
+	{
+		FromTable result = leftResultSet.getFromTableByName(name, schemaName, exactMatch);
+
+		/* We search both sides for a TableOperatorNode (join nodes)
+		 * but only the left side for a UnionNode.
+		 */
+		if (result == null)
+		{
+			result = rightResultSet.getFromTableByName(name, schemaName, exactMatch);
+		}
+		return result;
+	}
+
+	/** 
+	 * Put a ProjectRestrictNode on top of each FromTable in the FromList.
+	 * ColumnReferences must continue to point to the same ResultColumn, so
+	 * that ResultColumn must percolate up to the new PRN.  However,
+	 * that ResultColumn will point to a new expression, a VirtualColumnNode, 
+	 * which points to the FromTable and the ResultColumn that is the source for
+	 * the ColumnReference.  
+	 * (The new PRN will have the original of the ResultColumnList and
+	 * the ResultColumns from that list.  The FromTable will get shallow copies
+	 * of the ResultColumnList and its ResultColumns.  ResultColumn.expression
+	 * will remain at the FromTable, with the PRN getting a new 
+	 * VirtualColumnNode for each ResultColumn.expression.)
+	 * We then project out the non-referenced columns.  If there are no referenced
+	 * columns, then the PRN's ResultColumnList will consist of a single ResultColumn
+	 * whose expression is 1.
+	 *
+	 * @param numTables			Number of tables in the DML Statement
+	 * @param gbl				The group by list, if any
+	 * @param fromList			The from list, if any
+	 *
+	 * @return The generated ProjectRestrictNode atop the original FromTable.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public ResultSetNode preprocess(int numTables,
+									GroupByList gbl,
+									FromList fromList)
+								throws StandardException
+	{
+		leftResultSet = leftResultSet.preprocess(numTables, gbl, fromList);
+		/* If leftResultSet is a FromSubquery, then we must explicitly extract
+		 * out the subquery (flatten it).  (SelectNodes have their own
+		 * method of flattening them.
+		 */
+		if (leftResultSet instanceof FromSubquery)
+		{
+			leftResultSet = ((FromSubquery) leftResultSet).extractSubquery(numTables);
+		}
+		rightResultSet = rightResultSet.preprocess(numTables, gbl, fromList);
+		/* If rightResultSet is a FromSubquery, then we must explicitly extract
+		 * out the subquery (flatten it).  (SelectNodes have their own
+		 * method of flattening them.
+		 */
+		if (rightResultSet instanceof FromSubquery)
+		{
+			rightResultSet = ((FromSubquery) rightResultSet).extractSubquery(numTables);
+		}
+
+		/* Build the referenced table map (left || right) */
+		referencedTableMap = (JBitSet) leftResultSet.getReferencedTableMap().clone();
+		referencedTableMap.or((JBitSet) rightResultSet.getReferencedTableMap());
+		referencedTableMap.set(tableNumber);
+
+		/* Only generate a PRN if this node is not a flattenable join node. */
+		if (isFlattenableJoinNode())
+		{
+			return this;
+		}
+		else
+		{
+			/* Project out any unreferenced RCs before we generate the PRN.
+			 * NOTE: We have to do this at the end of preprocess since it has to 
+			 * be from the bottom up.  We can't do it until the join expression is 
+			 * bound, since the join expression may contain column references that
+			 * are not referenced anywhere else above us.
+			 */
+            projectResultColumns();
+			return genProjectRestrict(numTables);
+		}
+	}
+
+    /**
+     * Find the unreferenced result columns and project them out. This is used in pre-processing joins
+     * that are not flattened into the where clause.
+     */
+    void projectResultColumns() throws StandardException
+    {
+        resultColumns.doProjection();
+    }
+    
+    /**
+     * Set the referenced columns in the column list if it may not be correct.
+     */
+    void setReferencedColumns()
+    {}
+    
+	/**
+	 * Optimize a TableOperatorNode. 
+	 *
+	 * @param dataDictionary	The DataDictionary to use for optimization
+	 * @param predicateList		The PredicateList to apply.
+	 *
+	 * @return	ResultSetNode	The top of the optimized query tree
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public ResultSetNode optimize(DataDictionary dataDictionary,
+								  PredicateList predicateList,
+								  double outerRows)
+				throws StandardException
+	{
+		/* Get an optimizer, so we can get a cost structure */
+		Optimizer optimizer =
+							getOptimizer(
+								(FromList) getNodeFactory().getNode(
+									C_NodeTypes.FROM_LIST,
+									getNodeFactory().doJoinOrderOptimization(),
+									this,
+									getContextManager()),
+									predicateList,
+									dataDictionary,
+									(RequiredRowOrdering) null);
+
+		costEstimate = optimizer.newCostEstimate();
+
+		/* RESOLVE: This is just a stub for now */
+		leftResultSet = leftResultSet.optimize(
+											dataDictionary,
+											predicateList,
+											outerRows);
+		rightResultSet = rightResultSet.optimize(
+											dataDictionary,
+											predicateList,
+											outerRows);
+
+		/* The cost is the sum of the two child costs */
+		costEstimate.setCost(leftResultSet.getCostEstimate().getEstimatedCost(),
+							 leftResultSet.getCostEstimate().rowCount(),
+							 leftResultSet.getCostEstimate().singleScanRowCount() +
+							 rightResultSet.getCostEstimate().singleScanRowCount());
+
+		costEstimate.add(rightResultSet.costEstimate, costEstimate);
+
+		return this;
+	}
+
+	/**
+	 * @see ResultSetNode#modifyAccessPaths
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public ResultSetNode modifyAccessPaths() throws StandardException
+	{
+		/* Beetle 4454 - union all with another union all would modify access
+		 * paths twice causing NullPointerException, make sure we don't
+		 * do this again, if we have already done it in modifyAccessPaths(outertables)
+		 */
+		if (!leftModifyAccessPathsDone)
+		{
+			if (leftOptimizer != null)
+				leftOptimizer.modifyAccessPaths();
+			else
+				leftResultSet = leftResultSet.modifyAccessPaths();
+		}
+		if (!rightModifyAccessPathsDone)
+		{
+			if (rightOptimizer != null)
+				rightOptimizer.modifyAccessPaths();
+			else
+				rightResultSet = rightResultSet.modifyAccessPaths();
+		}
+		return this;
+	}
+
+	/**
+	 * Search to see if a query references the specifed table name.
+	 *
+	 * @param name		Table name (String) to search for.
+	 * @param baseTable	Whether or not name is for a base table
+	 *
+	 * @return	true if found, else false
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public boolean referencesTarget(String name, boolean baseTable)
+		throws StandardException
+	{
+		return leftResultSet.referencesTarget(name, baseTable) ||
+			   rightResultSet.referencesTarget(name, baseTable);
+	}
+
+	/**
+	 * Return true if the node references SESSION schema tables (temporary or permanent)
+	 *
+	 * @return	true if references SESSION schema tables, else false
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public boolean referencesSessionSchema()
+		throws StandardException
+	{
+		return leftResultSet.referencesSessionSchema() ||
+			   rightResultSet.referencesSessionSchema();
+	}
+
+	/** 
+	 * Optimize a source result set to this table operator.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	protected ResultSetNode optimizeSource(
+							Optimizer optimizer,
+							ResultSetNode sourceResultSet,
+							PredicateList predList,
+							CostEstimate outerCost)
+			throws StandardException
+	{
+		ResultSetNode	retval;
+
+		if (sourceResultSet instanceof FromTable)
+		{
+			FromList optList = (FromList) getNodeFactory().getNode(
+									C_NodeTypes.FROM_LIST,
+									getNodeFactory().doJoinOrderOptimization(),
+									sourceResultSet,
+									getContextManager());
+
+			/* If there is no predicate list, create an empty one */
+			if (predList == null)
+				predList = (PredicateList) getNodeFactory().getNode(
+												C_NodeTypes.PREDICATE_LIST,
+												getContextManager());
+
+			LanguageConnectionContext lcc = getLanguageConnectionContext();
+			OptimizerFactory optimizerFactory = lcc.getOptimizerFactory();
+			optimizer = optimizerFactory.getOptimizer(optList,
+													predList,
+													getDataDictionary(),
+													(RequiredRowOrdering) null,
+													getCompilerContext().getNumTables(),
+													  lcc);
+
+			if (sourceResultSet == leftResultSet)
+			{
+				leftOptimizer = optimizer;
+			}
+			else if (sourceResultSet == rightResultSet)
+			{
+				rightOptimizer = optimizer;
+			}
+			else
+			{
+				if (SanityManager.DEBUG)
+					SanityManager.THROWASSERT("Result set being optimized is neither left nor right");
+			}
+			
+			/*
+			** Set the estimated number of outer rows from the outer part of
+			** the plan.
+			*/
+			optimizer.setOuterRows(outerCost.rowCount());
+
+			/* Optimize the underlying result set */
+			while (optimizer.getNextPermutation())
+			{
+				while (optimizer.getNextDecoratedPermutation())
+				{
+					optimizer.costPermutation();
+				}
+			}
+
+			retval = sourceResultSet;
+		}
+		else
+		{
+			retval = sourceResultSet.optimize(
+										optimizer.getDataDictionary(),
+										predList,
+										outerCost.rowCount());
+		}
+
+		return retval;
+	}
+
+	/**
+	 * Decrement (query block) level (0-based) for 
+	 * all of the tables in this ResultSet tree.
+	 * This is useful when flattening a subquery.
+	 *
+	 * @param decrement	The amount to decrement by.
+	 *
+	 * @return Nothing;
+	 */
+	void decrementLevel(int decrement)
+	{
+		leftResultSet.decrementLevel(decrement);
+		rightResultSet.decrementLevel(decrement);
+	}
+
+	/**
+	 * Replace any DEFAULTs with the associated tree for the default.
+	 *
+	 * @param ttd	The TableDescriptor for the target table.
+	 * @param tcl	The RCL for the target table.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	void replaceDefaults(TableDescriptor ttd, ResultColumnList tcl) 
+		throws StandardException
+	{
+		leftResultSet.replaceDefaults(ttd, tcl);
+		rightResultSet.replaceDefaults(ttd, tcl);
+	}
+
+	/**
+	 * Notify the underlying result set tree that the result is
+	 * ordering dependent.  (For example, no bulk fetch on an index
+	 * if under an IndexRowToBaseRow.)
+	 *
+	 * @return Nothing.
+	 */
+	void markOrderingDependent()
+	{
+		leftResultSet.markOrderingDependent();
+		rightResultSet.markOrderingDependent();
+	}
+
+	/**
+	 * Accept a visitor, and call v.visit()
+	 * on child nodes as necessary.  
+	 * 
+	 * @param v the visitor
+	 *
+	 * @exception StandardException on error
+	 */
+	public Visitable accept(Visitor v) 
+		throws StandardException
+	{
+		if (v.skipChildren(this))
+		{
+			return v.visit(this);
+		}
+
+		Visitable returnNode = super.accept(v);
+
+		if (leftResultSet != null && !v.stopTraversal())
+		{
+			leftResultSet = (ResultSetNode)leftResultSet.accept(v);
+		}
+		if (rightResultSet != null && !v.stopTraversal())
+		{
+			rightResultSet = (ResultSetNode)rightResultSet.accept(v);
+		}
+		return returnNode;
+	}
+
+	/** 
+	 * apparently something special needs to be done for me....
+	 */
+	public boolean needsSpecialRCLBinding()
+	{
+		return true;
+	}
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java	Fri Sep 24 10:33:20 2004
@@ -1,827 +1,827 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package	org.apache.derby.impl.sql.compile;
-
-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.services.sanity.SanityManager;
-import org.apache.derby.iapi.sql.compile.C_NodeTypes;
-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.store.access.Qualifier;
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.sql.compile.TypeCompiler;
-import org.apache.derby.iapi.types.NumberDataValue;
-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.store.access.Qualifier;
-import org.apache.derby.iapi.reference.SQLState;
-import org.apache.derby.iapi.reference.ClassName;
-import org.apache.derby.iapi.services.classfile.VMOpcode;
-
-import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
-import org.apache.derby.iapi.util.JBitSet;
-
-import java.lang.reflect.Modifier;
-
-import java.sql.Types;
-import java.util.Vector;
-/**
- * A TernaryOperatorNode represents a built-in ternary operators.
- * This covers  built-in functions like substr().
- * Java operators are not represented here: the JSQL language allows Java
- * methods to be called from expressions, but not Java operators.
- *
- * @author Jerry Brenner
- */
-
-public class TernaryOperatorNode extends ValueNode
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-	String		operator;
-	String		methodName;
-	int			operatorType;
-	ValueNode	receiver; 
-
-	ValueNode	leftOperand;
-	ValueNode	rightOperand;
-
-	String		resultInterfaceType;
-	String		receiverInterfaceType;
-	String		leftInterfaceType;
-	String		rightInterfaceType;
-	int			trimType;
-
-	public static final int TRIM = 0;
-	public static final int LOCATE = 1;
-	public static final int SUBSTRING = 2;
-	public static final int LIKE = 3;
-	static final String[] TernaryOperators = {"trim", "LOCATE", "substring", "like"};
-	static final String[] TernaryMethodNames = {"trim", "locate", "substring", "like"};
-	static final String[] TernaryResultType = {ClassName.StringDataValue, 
-			ClassName.NumberDataValue,
-			ClassName.ConcatableDataValue,
-			ClassName.BooleanDataValue};
-	static final String[][] TernaryArgType = {
-	{ClassName.StringDataValue, ClassName.StringDataValue, "java.lang.Integer"},
-	{ClassName.StringDataValue, ClassName.StringDataValue, ClassName.NumberDataValue},
-	{ClassName.ConcatableDataValue, ClassName.NumberDataValue, ClassName.NumberDataValue},
-	{ClassName.DataValueDescriptor, ClassName.DataValueDescriptor, ClassName.DataValueDescriptor}
-	};
-
-	/**
-	 * Initializer for a TernaryOperatorNode
-	 *
-	 * @param receiver		The receiver (eg, string being operated on in substr())
-	 * @param leftOperand	The left operand of the node
-	 * @param rightOperand	The right operand of the node
-	 * @param operatorType	The type of the operand
-	 */
-
-	public void init(
-					Object receiver,
-					Object leftOperand,
-					Object rightOperand,
-					Object operatorType,
-					Object trimType)
-	{
-		this.receiver = (ValueNode) receiver;
-		this.leftOperand = (ValueNode) leftOperand;
-		this.rightOperand = (ValueNode) rightOperand;
-		this.operatorType = ((Integer) operatorType).intValue();
-		this.operator = (String) TernaryOperators[this.operatorType];
-		this.methodName = (String) TernaryMethodNames[this.operatorType];
-		this.resultInterfaceType = (String) TernaryResultType[this.operatorType];
-		this.receiverInterfaceType = (String) TernaryArgType[this.operatorType][0];
-		this.leftInterfaceType = (String) TernaryArgType[this.operatorType][1];
-		this.rightInterfaceType = (String) TernaryArgType[this.operatorType][2];
-		if (trimType != null)
-				this.trimType = ((Integer) trimType).intValue();
-	}
-
-	/**
-	 * Convert this object to a String.  See comments in QueryTreeNode.java
-	 * for how this should be done for tree printing.
-	 *
-	 * @return	This object as a String
-	 */
-
-	public String toString()
-	{
-		if (SanityManager.DEBUG)
-		{
-			return "operator: " + operator + "\n" +
-				"methodName: " + methodName + "\n" + 
-				"resultInterfaceType: " + resultInterfaceType + "\n" + 
-				"receiverInterfaceType: " + receiverInterfaceType + "\n" + 
-				"leftInterfaceType: " + leftInterfaceType + "\n" + 
-				"rightInterfaceType: " + rightInterfaceType + "\n" + 
-				super.toString();
-		}
-		else
-		{
-			return "";
-		}
-	}
-
-	/**
-	 * Set the clause that this node appears in.
-	 *
-	 * @param clause	The clause that this node appears in.
-	 *
-	 * @return Nothing.
-	 */
-	public void setClause(int clause)
-	{
-		super.setClause(clause);
-		receiver.setClause(clause);
-		leftOperand.setClause(clause);
-		if (rightOperand != null)
-		{
-			rightOperand.setClause(clause);
-		}
-	}
-
-	/**
-	 * Prints the sub-nodes of this object.  See QueryTreeNode.java for
-	 * how tree printing is supposed to work.
-	 *
-	 * @param depth		The depth of this node in the tree
-	 *
-	 * @return	Nothing
-	 */
-
-	public void printSubNodes(int depth)
-	{
-		if (SanityManager.DEBUG)
-		{
-			super.printSubNodes(depth);
-
-			if (receiver != null)
-			{
-				printLabel(depth, "receiver: ");
-				receiver.treePrint(depth + 1);
-			}
-
-			if (leftOperand != null)
-			{
-				printLabel(depth, "leftOperand: ");
-				leftOperand.treePrint(depth + 1);
-			}
-
-			if (rightOperand != null)
-			{
-				printLabel(depth, "rightOperand: ");
-				rightOperand.treePrint(depth + 1);
-			}
-		}
-	}
-
-	/**
-	 * Bind this expression.  This means binding the sub-expressions,
-	 * as well as figuring out what the return type is for this expression.
-	 *
-	 * @param fromList		The FROM list for the query this
-	 *				expression is in, for binding columns.
-	 * @param subqueryList		The subquery list being built as we find SubqueryNodes
-	 * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
-	 *
-	 * @return	The new top of the expression tree.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public ValueNode bindExpression(FromList fromList, SubqueryList subqueryList,
-		Vector	aggregateVector) 
-			throws StandardException
-	{
-		receiver = receiver.bindExpression(fromList, subqueryList, 
-			aggregateVector);
-		leftOperand = leftOperand.bindExpression(fromList, subqueryList, 
-			aggregateVector);
-
-		if (rightOperand != null)
-		{
-			rightOperand = rightOperand.bindExpression(fromList, subqueryList, 
-				aggregateVector);
-		}
-		if (operatorType == TRIM)
-			trimBind();
-		else if (operatorType == LOCATE)
-			locateBind();
-		else if (operatorType == SUBSTRING)
-			substrBind();
-
-		return this;
-	}
-
-	/**
-	 * Preprocess an expression tree.  We do a number of transformations
-	 * here (including subqueries, IN lists, LIKE and BETWEEN) plus
-	 * subquery flattening.
-	 * NOTE: This is done before the outer ResultSetNode is preprocessed.
-	 *
-	 * @param	numTables			Number of tables in the DML Statement
-	 * @param	outerFromList		FromList from outer query block
-	 * @param	outerSubqueryList	SubqueryList from outer query block
-	 * @param	outerPredicateList	PredicateList from outer query block
-	 *
-	 * @return		The modified expression
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public ValueNode preprocess(int numTables,
-								FromList outerFromList,
-								SubqueryList outerSubqueryList,
-								PredicateList outerPredicateList) 
-					throws StandardException
-	{
-		receiver = receiver.preprocess(numTables,
-											 outerFromList, outerSubqueryList,
-											 outerPredicateList);
-
-		leftOperand = leftOperand.preprocess(numTables,
-											 outerFromList, outerSubqueryList,
-											 outerPredicateList);
-		if (rightOperand != null)
-		{
-			rightOperand = rightOperand.preprocess(numTables,
-												   outerFromList, outerSubqueryList,
-												   outerPredicateList);
-		}
-		return this;
-	}
-	/**
-	 * Do code generation for this ternary operator.
-	 *
-	 * @param acb	The ExpressionClassBuilder for the class we're generating
-	 * @param mb	The method the expression will go into
-	 *
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public void generateExpression(ExpressionClassBuilder acb,
-											MethodBuilder mb)
-		throws StandardException
-	{
-		int nargs = 0;
-		String receiverType = null;
-
-		/* Allocate an object for re-use to hold the result of the operator */
-		LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, resultInterfaceType);
-
-		receiver.generateExpression(acb, mb);
-		if (operatorType == TRIM)
-		{
-			mb.push(trimType);
-			mb.getField(field);
-			nargs = 2;
-			receiverType = receiverInterfaceType;
-		}
-		else if (operatorType == LOCATE)
-		{
-			leftOperand.generateExpression(acb, mb); 
-			mb.upCast(leftInterfaceType);
-			rightOperand.generateExpression(acb, mb);
-			mb.upCast(rightInterfaceType);
-			mb.getField(field);
-			nargs = 3;
-		
-		}
-		else if (operatorType == SUBSTRING)
-		{
-			leftOperand.generateExpression(acb, mb); 
-			mb.upCast(leftInterfaceType);
-			if (rightOperand != null)
-			{
-				rightOperand.generateExpression(acb, mb);
-				mb.upCast(rightInterfaceType);
-			}
-			else
-			{
-				mb.pushNull(rightInterfaceType);
-			}
-
-			mb.getField(field); // third arg
-			mb.push(receiver.getTypeServices().getMaximumWidth());
-			nargs = 4;
-			receiverType = receiverInterfaceType;
-		}
-		mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType, methodName, resultInterfaceType, nargs);
-
-		/*
-		** Store the result of the method call in the field, so we can re-use
-		** the object.
-		*/
-		mb.putField(field);
-	}
-
-	/**
-	 * Set the leftOperand to the specified ValueNode
-	 *
-	 * @param newLeftOperand	The new leftOperand
-	 *
-	 * @return None.
-	 */
-	public void setLeftOperand(ValueNode newLeftOperand)
-	{
-		leftOperand = newLeftOperand;
-	}
-
-	/**
-	 * Get the leftOperand
-	 *
-	 * @return The current leftOperand.
-	 */
-	public ValueNode getLeftOperand()
-	{
-		return leftOperand;
-	}
-
-	/**
-	 * Set the rightOperand to the specified ValueNode
-	 *
-	 * @param newRightOperand	The new rightOperand
-	 *
-	 * @return None.
-	 */
-	public void setRightOperand(ValueNode newRightOperand)
-	{
-		rightOperand = newRightOperand;
-	}
-
-	/**
-	 * Get the rightOperand
-	 *
-	 * @return The current rightOperand.
-	 */
-	public ValueNode getRightOperand()
-	{
-		return rightOperand;
-	}
-
-	/**
-	 * Categorize this predicate.  Initially, this means
-	 * building a bit map of the referenced tables for each predicate.
-	 * If the source of this ColumnReference (at the next underlying level) 
-	 * is not a ColumnReference or a VirtualColumnNode then this predicate
-	 * will not be pushed down.
-	 *
-	 * For example, in:
-	 *		select * from (select 1 from s) a (x) where x = 1
-	 * we will not push down x = 1.
-	 * NOTE: It would be easy to handle the case of a constant, but if the
-	 * inner SELECT returns an arbitrary expression, then we would have to copy
-	 * that tree into the pushed predicate, and that tree could contain
-	 * subqueries and method calls.
-	 * RESOLVE - revisit this issue once we have views.
-	 *
-	 * @param referencedTabs	JBitSet with bit map of referenced FromTables
-	 * @param simplePredsOnly	Whether or not to consider method
-	 *							calls, field references and conditional nodes
-	 *							when building bit map
-	 *
-	 * @return boolean		Whether or not source.expression is a ColumnReference
-	 *						or a VirtualColumnNode.
-	 * @exception StandardException			Thrown on error
-	 */
-	public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly)
-		throws StandardException
-	{
-		boolean pushable;
-		pushable = receiver.categorize(referencedTabs, simplePredsOnly);
-		pushable = (leftOperand.categorize(referencedTabs, simplePredsOnly) && pushable);
-		if (rightOperand != null)
-		{
-			pushable = (rightOperand.categorize(referencedTabs, simplePredsOnly) && pushable);
-		}
-		return pushable;
-	}
-
-	/**
-	 * Remap all ColumnReferences in this tree to be clones of the
-	 * underlying expression.
-	 *
-	 * @return ValueNode			The remapped expression tree.
-	 *
-	 * @exception StandardException			Thrown on error
-	 */
-	public ValueNode remapColumnReferencesToExpressions()
-		throws StandardException
-	{
-		receiver = receiver.remapColumnReferencesToExpressions();
-		leftOperand = leftOperand.remapColumnReferencesToExpressions();
-		if (rightOperand != null)
-		{
-			rightOperand = rightOperand.remapColumnReferencesToExpressions();
-		}
-		return this;
-	}
-
-	/**
-	 * Return whether or not this expression tree represents a constant expression.
-	 *
-	 * @return	Whether or not this expression tree represents a constant expression.
-	 */
-	public boolean isConstantExpression()
-	{
-		return (receiver.isConstantExpression() &&
-				leftOperand.isConstantExpression() &&
-				(rightOperand == null || rightOperand.isConstantExpression()));
-	}
-
-	/** @see ValueNode#constantExpression */
-	public boolean constantExpression(PredicateList whereClause)
-	{
-		return (receiver.constantExpression(whereClause) &&
-				leftOperand.constantExpression(whereClause) &&
-				(rightOperand == null ||
-					rightOperand.constantExpression(whereClause)));
-	}
-
-	/**
-	 * Accept a visitor, and call v.visit()
-	 * on child nodes as necessary.  
-	 * 
-	 * @param v the visitor
-	 *
-	 * @exception StandardException on error
-	 */
-	public Visitable accept(Visitor v) 
-		throws StandardException
-	{
-		Visitable returnNode = v.visit(this);
-	
-		if (v.skipChildren(this))
-		{
-			return returnNode;
-		}
-
-		if (receiver != null && !v.stopTraversal())
-		{
-			receiver = (ValueNode)receiver.accept(v);
-		}
-
-		if (leftOperand != null && !v.stopTraversal())
-		{
-			leftOperand = (ValueNode)leftOperand.accept(v);
-		}
-
-		if (rightOperand != null && !v.stopTraversal())
-		{
-			rightOperand = (ValueNode)rightOperand.accept(v);
-		}
-		
-		return returnNode;
-	}
-	/**
-	 * Bind trim expression. 
-	 * @return	The new top of the expression tree.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	private ValueNode trimBind() 
-			throws StandardException
-	{
-		TypeId	receiverType;
-		TypeId	resultType = TypeId.getBuiltInTypeId(Types.VARCHAR);
-
-		// handle parameters here
-
-		/* Is there a ? parameter for the receiver? */
-		if (receiver.isParameterNode())
-		{
-			/*
-			** According to the SQL standard, if trim has a ? receiver,
-			** its type is varchar with the implementation-defined maximum length
-			** for a varchar.
-			*/
-	
-			((ParameterNode) receiver).setDescriptor(getVarcharDescriptor());
-		}
-
-		/* Is there a ? parameter on the left? */
-		if (leftOperand.isParameterNode())
-		{
-			/* Set the left operand type to varchar. */
-			((ParameterNode) leftOperand).setDescriptor(getVarcharDescriptor());
-		}
-
-		bindToBuiltIn();
-
-		/*
-		** Check the type of the receiver - this function is allowed only on
-		** string value types.  
-		*/
-		receiverType = receiver.getTypeId();
-		if (receiverType.userType())
-			throwBadType("trim", receiverType.getSQLTypeName());
-
-		receiver = castArgToString(receiver);
-
-		if ((receiverType.getTypeFormatId() == StoredFormatIds.CLOB_TYPE_ID) ||
-		   (receiverType.getTypeFormatId() == StoredFormatIds.NCLOB_TYPE_ID)) {
-		// special case for CLOBs: if we start with a CLOB, we have to get
-		// a CLOB as a result (as opposed to a VARCHAR), because we can have a 
-		// CLOB that is beyond the max length of VARCHAR (ex. "clob(100k)").
-		// This is okay because CLOBs, like VARCHARs, allow variable-length
-		// values (which is a must for the trim to actually work).
-			resultType = receiverType;
-		}
-
-		/*
-		** Check the type of the leftOperand (trimSet).
-		** The leftOperand should be a string value type.  
-		*/
-		TypeId	leftCTI;
-		leftCTI = leftOperand.getTypeId();
-		if (leftCTI.userType())
-			throwBadType("trim", leftCTI.getSQLTypeName());
-
-		leftOperand = castArgToString(leftOperand);
-
-		/*
-		** The result type of trim is varchar.
-		*/
-		setResultType(resultType);
-
-		return this;
-	}
-	/*
-	** set result type for operator
-	*/
-	private void setResultType(TypeId resultType) throws StandardException
-	{
-		setType(new DataTypeDescriptor(
-						resultType,
-						true,
-						receiver.getTypeServices().getMaximumWidth()
-					)
-				);
-	}
-	/**
-	 * Bind locate operator
-	 *
-	 * @return	The new top of the expression tree.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public ValueNode locateBind() throws StandardException
-	{
-		TypeId	firstOperandType, secondOperandType, offsetType;
-
-		/*
-		 * Is there a ? parameter for the first arg.  Copy the 
-		 * left/firstOperand's.  If the left/firstOperand are both parameters,
-		 * both will be max length.
-		 */
-		if( receiver.isParameterNode())
-		{
-			if( leftOperand.isParameterNode())
-			{
-				((ParameterNode) receiver).setDescriptor(getVarcharDescriptor());
-			}
-			else
-			{
-				if( leftOperand.getTypeId().isStringTypeId() )
-				{
-					((ParameterNode) receiver).setDescriptor(
-							         leftOperand.getTypeServices());
-				}
-			}
-		}
-							                            
-		/*
-		 * Is there a ? parameter for the second arg.  Copy the receiver's.
-		 * If the receiver are both parameters, both will be max length.
-		 */
-		if(leftOperand.isParameterNode())
-		{
-			if(receiver.isParameterNode())
-			{
-				((ParameterNode) leftOperand).setDescriptor(getVarcharDescriptor());
-			}
-			else
-			{
-				if( receiver.getTypeId().isStringTypeId() )
-				{
-					((ParameterNode) leftOperand).setDescriptor(
-							         receiver.getTypeServices());
-				}
-			}
-		}
-
-		/*
-		 * Is there a ? paramter for the third arg.  It will be an int.
-		 */
-		if( rightOperand.isParameterNode())
-		{
-			((ParameterNode) rightOperand).setDescriptor(
-				new DataTypeDescriptor(TypeId.INTEGER_ID, true)); 
-		}
-
-		bindToBuiltIn();
-
-		/*
-		** Check the type of the operand - this function is allowed only
-		** for: receiver = CHAR
-		**      firstOperand = CHAR
-		**      secondOperand = INT
-		*/
-		secondOperandType = leftOperand.getTypeId();
-		offsetType = rightOperand.getTypeId();
-		firstOperandType = receiver.getTypeId();
-
-		if (!firstOperandType.isStringTypeId() ||
-			!secondOperandType.isStringTypeId() || 
-			offsetType.getJDBCTypeId() != Types.INTEGER)
-			throw StandardException.newException(SQLState.LANG_DB2_FUNCTION_INCOMPATIBLE,
-					"LOCATE", "FUNCTION");
-
-		/*
-		** The result type of a LocateFunctionNode is an integer.
-		*/
-		setType(new DataTypeDescriptor(TypeId.INTEGER_ID, 
-				receiver.getTypeServices().isNullable())); 
-
-		return this;
-	}
-
-	/* cast arg to a varchar */
-	protected ValueNode castArgToString(ValueNode vn) throws StandardException
-	{
-		TypeCompiler vnTC = vn.getTypeCompiler();
-		if (! vn.getTypeId().isStringTypeId())
-		{
-			ValueNode newNode = (ValueNode)
-						getNodeFactory().getNode(
-							C_NodeTypes.CAST_NODE,
-							vn,
-							DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, true,
-							                vnTC.getCastToCharWidth(
-							                    vn.getTypeServices())),
-							getContextManager());
-			((CastNode) newNode).bindCastNodeOnly();
-			return newNode;
-		}
-		return vn;
-	}
-
-	/**
-	 * Bind substr expression.  
-	 *
-	 * @return	The new top of the expression tree.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
- 	public ValueNode substrBind() 
-			throws StandardException
-	{
-		TypeId	receiverType;
-		TypeId	resultType;
-
-		// handle parameters here
-
-		/* Is there a ? parameter for the receiver? */
-		if (receiver.isParameterNode())
-		{
-			/*
-			** According to the SQL standard, if substr has a ? receiver,
-			** its type is varchar with the implementation-defined maximum length
-			** for a varchar.
-			*/
-	
-			((ParameterNode) receiver).setDescriptor(getVarcharDescriptor());
-		}
-
-		/* Is there a ? parameter on the left? */
-		if (leftOperand.isParameterNode())
-		{
-			/* Set the left operand type to int. */
-			((ParameterNode) leftOperand).setDescriptor(							
-				new DataTypeDescriptor(TypeId.INTEGER_ID, true)); 
-		}
-
-		/* Is there a ? parameter on the right? */
-		if ((rightOperand != null) && rightOperand.isParameterNode())
-		{
-			/* Set the right operand type to int. */
-			((ParameterNode) rightOperand).setDescriptor(							
-				new DataTypeDescriptor(TypeId.INTEGER_ID, true)); 
-		}
-
-		bindToBuiltIn();
-
-		if (!leftOperand.getTypeId().isNumericTypeId() ||
-			(rightOperand != null && !rightOperand.getTypeId().isNumericTypeId()))
-			throw StandardException.newException(SQLState.LANG_DB2_FUNCTION_INCOMPATIBLE, "SUBSTR", "FUNCTION");
-
-		/*
-		** Check the type of the receiver - this function is allowed only on
-		** string value types.  
-		*/
-		resultType = receiverType = receiver.getTypeId();
-		switch (receiverType.getJDBCTypeId())
-		{
-			case Types.CHAR:
-			case Types.VARCHAR:
-			case Types.LONGVARCHAR:
-			case Types.CLOB:
-				break;
-			default:
-			{
-				throwBadType("SUBSTR", receiverType.getSQLTypeName());
-			}
-		}
-
-		// Determine the maximum length of the result
-		int resultLen = receiver.getTypeServices().getMaximumWidth();
-
-		if (rightOperand != null && rightOperand instanceof ConstantNode)
-		{
-			if (((ConstantNode)rightOperand).getValue().getInt() < resultLen)
-				resultLen = ((ConstantNode)rightOperand).getValue().getInt();
-		}
-
-		/*
-		** The result type of substr is a string type
-		*/
-		setType(new DataTypeDescriptor(
-						resultType,
-						true,
-						resultLen
-					));
-
-		return this;
-	}
-
-	public ValueNode getReceiver()
-	{
-		return receiver;
-	}
-
-	/* throw bad type message */
-	private void throwBadType(String funcName, String type) 
-		throws StandardException
-	{
-		throw StandardException.newException(SQLState.LANG_UNARY_FUNCTION_BAD_TYPE, 
-										funcName,
-										type);
-	}
-
-	/* bind arguments to built in types */
-	protected void bindToBuiltIn() 
-		throws StandardException
-	{
-		/* If the receiver is not a built-in type, then generate a bound conversion
-		 * tree to a built-in type.
-		 */
-		if (! receiver.getTypeId().systemBuiltIn())
-		{
-			receiver = receiver.genSQLJavaSQLTree();
-		}
-
-		/* If the left operand is not a built-in type, then generate a bound conversion
-		 * tree to a built-in type.
-		 */
-		if (! leftOperand.getTypeId().systemBuiltIn())
-		{
-			leftOperand = leftOperand.genSQLJavaSQLTree();
-		}
-
-		/* If the right operand is not a built-in type, then generate a bound conversion
-		 * tree to a built-in type.
-		 */
-		if (rightOperand != null)
-		{
-			if (! rightOperand.getTypeId().systemBuiltIn())
-			{
-				rightOperand = rightOperand.genSQLJavaSQLTree();
-			}
-		}
-	}
-
-	private DataTypeDescriptor getVarcharDescriptor() {
-		return new DataTypeDescriptor(TypeId.getBuiltInTypeId(Types.VARCHAR), true);
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package	org.apache.derby.impl.sql.compile;
+
+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.services.sanity.SanityManager;
+import org.apache.derby.iapi.sql.compile.C_NodeTypes;
+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.store.access.Qualifier;
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.sql.compile.TypeCompiler;
+import org.apache.derby.iapi.types.NumberDataValue;
+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.store.access.Qualifier;
+import org.apache.derby.iapi.reference.SQLState;
+import org.apache.derby.iapi.reference.ClassName;
+import org.apache.derby.iapi.services.classfile.VMOpcode;
+
+import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
+import org.apache.derby.iapi.util.JBitSet;
+
+import java.lang.reflect.Modifier;
+
+import java.sql.Types;
+import java.util.Vector;
+/**
+ * A TernaryOperatorNode represents a built-in ternary operators.
+ * This covers  built-in functions like substr().
+ * Java operators are not represented here: the JSQL language allows Java
+ * methods to be called from expressions, but not Java operators.
+ *
+ * @author Jerry Brenner
+ */
+
+public class TernaryOperatorNode extends ValueNode
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+	String		operator;
+	String		methodName;
+	int			operatorType;
+	ValueNode	receiver; 
+
+	ValueNode	leftOperand;
+	ValueNode	rightOperand;
+
+	String		resultInterfaceType;
+	String		receiverInterfaceType;
+	String		leftInterfaceType;
+	String		rightInterfaceType;
+	int			trimType;
+
+	public static final int TRIM = 0;
+	public static final int LOCATE = 1;
+	public static final int SUBSTRING = 2;
+	public static final int LIKE = 3;
+	static final String[] TernaryOperators = {"trim", "LOCATE", "substring", "like"};
+	static final String[] TernaryMethodNames = {"trim", "locate", "substring", "like"};
+	static final String[] TernaryResultType = {ClassName.StringDataValue, 
+			ClassName.NumberDataValue,
+			ClassName.ConcatableDataValue,
+			ClassName.BooleanDataValue};
+	static final String[][] TernaryArgType = {
+	{ClassName.StringDataValue, ClassName.StringDataValue, "java.lang.Integer"},
+	{ClassName.StringDataValue, ClassName.StringDataValue, ClassName.NumberDataValue},
+	{ClassName.ConcatableDataValue, ClassName.NumberDataValue, ClassName.NumberDataValue},
+	{ClassName.DataValueDescriptor, ClassName.DataValueDescriptor, ClassName.DataValueDescriptor}
+	};
+
+	/**
+	 * Initializer for a TernaryOperatorNode
+	 *
+	 * @param receiver		The receiver (eg, string being operated on in substr())
+	 * @param leftOperand	The left operand of the node
+	 * @param rightOperand	The right operand of the node
+	 * @param operatorType	The type of the operand
+	 */
+
+	public void init(
+					Object receiver,
+					Object leftOperand,
+					Object rightOperand,
+					Object operatorType,
+					Object trimType)
+	{
+		this.receiver = (ValueNode) receiver;
+		this.leftOperand = (ValueNode) leftOperand;
+		this.rightOperand = (ValueNode) rightOperand;
+		this.operatorType = ((Integer) operatorType).intValue();
+		this.operator = (String) TernaryOperators[this.operatorType];
+		this.methodName = (String) TernaryMethodNames[this.operatorType];
+		this.resultInterfaceType = (String) TernaryResultType[this.operatorType];
+		this.receiverInterfaceType = (String) TernaryArgType[this.operatorType][0];
+		this.leftInterfaceType = (String) TernaryArgType[this.operatorType][1];
+		this.rightInterfaceType = (String) TernaryArgType[this.operatorType][2];
+		if (trimType != null)
+				this.trimType = ((Integer) trimType).intValue();
+	}
+
+	/**
+	 * Convert this object to a String.  See comments in QueryTreeNode.java
+	 * for how this should be done for tree printing.
+	 *
+	 * @return	This object as a String
+	 */
+
+	public String toString()
+	{
+		if (SanityManager.DEBUG)
+		{
+			return "operator: " + operator + "\n" +
+				"methodName: " + methodName + "\n" + 
+				"resultInterfaceType: " + resultInterfaceType + "\n" + 
+				"receiverInterfaceType: " + receiverInterfaceType + "\n" + 
+				"leftInterfaceType: " + leftInterfaceType + "\n" + 
+				"rightInterfaceType: " + rightInterfaceType + "\n" + 
+				super.toString();
+		}
+		else
+		{
+			return "";
+		}
+	}
+
+	/**
+	 * Set the clause that this node appears in.
+	 *
+	 * @param clause	The clause that this node appears in.
+	 *
+	 * @return Nothing.
+	 */
+	public void setClause(int clause)
+	{
+		super.setClause(clause);
+		receiver.setClause(clause);
+		leftOperand.setClause(clause);
+		if (rightOperand != null)
+		{
+			rightOperand.setClause(clause);
+		}
+	}
+
+	/**
+	 * Prints the sub-nodes of this object.  See QueryTreeNode.java for
+	 * how tree printing is supposed to work.
+	 *
+	 * @param depth		The depth of this node in the tree
+	 *
+	 * @return	Nothing
+	 */
+
+	public void printSubNodes(int depth)
+	{
+		if (SanityManager.DEBUG)
+		{
+			super.printSubNodes(depth);
+
+			if (receiver != null)
+			{
+				printLabel(depth, "receiver: ");
+				receiver.treePrint(depth + 1);
+			}
+
+			if (leftOperand != null)
+			{
+				printLabel(depth, "leftOperand: ");
+				leftOperand.treePrint(depth + 1);
+			}
+
+			if (rightOperand != null)
+			{
+				printLabel(depth, "rightOperand: ");
+				rightOperand.treePrint(depth + 1);
+			}
+		}
+	}
+
+	/**
+	 * Bind this expression.  This means binding the sub-expressions,
+	 * as well as figuring out what the return type is for this expression.
+	 *
+	 * @param fromList		The FROM list for the query this
+	 *				expression is in, for binding columns.
+	 * @param subqueryList		The subquery list being built as we find SubqueryNodes
+	 * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
+	 *
+	 * @return	The new top of the expression tree.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public ValueNode bindExpression(FromList fromList, SubqueryList subqueryList,
+		Vector	aggregateVector) 
+			throws StandardException
+	{
+		receiver = receiver.bindExpression(fromList, subqueryList, 
+			aggregateVector);
+		leftOperand = leftOperand.bindExpression(fromList, subqueryList, 
+			aggregateVector);
+
+		if (rightOperand != null)
+		{
+			rightOperand = rightOperand.bindExpression(fromList, subqueryList, 
+				aggregateVector);
+		}
+		if (operatorType == TRIM)
+			trimBind();
+		else if (operatorType == LOCATE)
+			locateBind();
+		else if (operatorType == SUBSTRING)
+			substrBind();
+
+		return this;
+	}
+
+	/**
+	 * Preprocess an expression tree.  We do a number of transformations
+	 * here (including subqueries, IN lists, LIKE and BETWEEN) plus
+	 * subquery flattening.
+	 * NOTE: This is done before the outer ResultSetNode is preprocessed.
+	 *
+	 * @param	numTables			Number of tables in the DML Statement
+	 * @param	outerFromList		FromList from outer query block
+	 * @param	outerSubqueryList	SubqueryList from outer query block
+	 * @param	outerPredicateList	PredicateList from outer query block
+	 *
+	 * @return		The modified expression
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+	public ValueNode preprocess(int numTables,
+								FromList outerFromList,
+								SubqueryList outerSubqueryList,
+								PredicateList outerPredicateList) 
+					throws StandardException
+	{
+		receiver = receiver.preprocess(numTables,
+											 outerFromList, outerSubqueryList,
+											 outerPredicateList);
+
+		leftOperand = leftOperand.preprocess(numTables,
+											 outerFromList, outerSubqueryList,
+											 outerPredicateList);
+		if (rightOperand != null)
+		{
+			rightOperand = rightOperand.preprocess(numTables,
+												   outerFromList, outerSubqueryList,
+												   outerPredicateList);
+		}
+		return this;
+	}
+	/**
+	 * Do code generation for this ternary operator.
+	 *
+	 * @param acb	The ExpressionClassBuilder for the class we're generating
+	 * @param mb	The method the expression will go into
+	 *
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public void generateExpression(ExpressionClassBuilder acb,
+											MethodBuilder mb)
+		throws StandardException
+	{
+		int nargs = 0;
+		String receiverType = null;
+
+		/* Allocate an object for re-use to hold the result of the operator */
+		LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, resultInterfaceType);
+
+		receiver.generateExpression(acb, mb);
+		if (operatorType == TRIM)
+		{
+			mb.push(trimType);
+			mb.getField(field);
+			nargs = 2;
+			receiverType = receiverInterfaceType;
+		}
+		else if (operatorType == LOCATE)
+		{
+			leftOperand.generateExpression(acb, mb); 
+			mb.upCast(leftInterfaceType);
+			rightOperand.generateExpression(acb, mb);
+			mb.upCast(rightInterfaceType);
+			mb.getField(field);
+			nargs = 3;
+		
+		}
+		else if (operatorType == SUBSTRING)
+		{
+			leftOperand.generateExpression(acb, mb); 
+			mb.upCast(leftInterfaceType);
+			if (rightOperand != null)
+			{
+				rightOperand.generateExpression(acb, mb);
+				mb.upCast(rightInterfaceType);
+			}
+			else
+			{
+				mb.pushNull(rightInterfaceType);
+			}
+
+			mb.getField(field); // third arg
+			mb.push(receiver.getTypeServices().getMaximumWidth());
+			nargs = 4;
+			receiverType = receiverInterfaceType;
+		}
+		mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType, methodName, resultInterfaceType, nargs);
+
+		/*
+		** Store the result of the method call in the field, so we can re-use
+		** the object.
+		*/
+		mb.putField(field);
+	}
+
+	/**
+	 * Set the leftOperand to the specified ValueNode
+	 *
+	 * @param newLeftOperand	The new leftOperand
+	 *
+	 * @return None.
+	 */
+	public void setLeftOperand(ValueNode newLeftOperand)
+	{
+		leftOperand = newLeftOperand;
+	}
+
+	/**
+	 * Get the leftOperand
+	 *
+	 * @return The current leftOperand.
+	 */
+	public ValueNode getLeftOperand()
+	{
+		return leftOperand;
+	}
+
+	/**
+	 * Set the rightOperand to the specified ValueNode
+	 *
+	 * @param newRightOperand	The new rightOperand
+	 *
+	 * @return None.
+	 */
+	public void setRightOperand(ValueNode newRightOperand)
+	{
+		rightOperand = newRightOperand;
+	}
+
+	/**
+	 * Get the rightOperand
+	 *
+	 * @return The current rightOperand.
+	 */
+	public ValueNode getRightOperand()
+	{
+		return rightOperand;
+	}
+
+	/**
+	 * Categorize this predicate.  Initially, this means
+	 * building a bit map of the referenced tables for each predicate.
+	 * If the source of this ColumnReference (at the next underlying level) 
+	 * is not a ColumnReference or a VirtualColumnNode then this predicate
+	 * will not be pushed down.
+	 *
+	 * For example, in:
+	 *		select * from (select 1 from s) a (x) where x = 1
+	 * we will not push down x = 1.
+	 * NOTE: It would be easy to handle the case of a constant, but if the
+	 * inner SELECT returns an arbitrary expression, then we would have to copy
+	 * that tree into the pushed predicate, and that tree could contain
+	 * subqueries and method calls.
+	 * RESOLVE - revisit this issue once we have views.
+	 *
+	 * @param referencedTabs	JBitSet with bit map of referenced FromTables
+	 * @param simplePredsOnly	Whether or not to consider method
+	 *							calls, field references and conditional nodes
+	 *							when building bit map
+	 *
+	 * @return boolean		Whether or not source.expression is a ColumnReference
+	 *						or a VirtualColumnNode.
+	 * @exception StandardException			Thrown on error
+	 */
+	public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly)
+		throws StandardException
+	{
+		boolean pushable;
+		pushable = receiver.categorize(referencedTabs, simplePredsOnly);
+		pushable = (leftOperand.categorize(referencedTabs, simplePredsOnly) && pushable);
+		if (rightOperand != null)
+		{
+			pushable = (rightOperand.categorize(referencedTabs, simplePredsOnly) && pushable);
+		}
+		return pushable;
+	}
+
+	/**
+	 * Remap all ColumnReferences in this tree to be clones of the
+	 * underlying expression.
+	 *
+	 * @return ValueNode			The remapped expression tree.
+	 *
+	 * @exception StandardException			Thrown on error
+	 */
+	public ValueNode remapColumnReferencesToExpressions()
+		throws StandardException
+	{
+		receiver = receiver.remapColumnReferencesToExpressions();
+		leftOperand = leftOperand.remapColumnReferencesToExpressions();
+		if (rightOperand != null)
+		{
+			rightOperand = rightOperand.remapColumnReferencesToExpressions();
+		}
+		return this;
+	}
+
+	/**
+	 * Return whether or not this expression tree represents a constant expression.
+	 *
+	 * @return	Whether or not this expression tree represents a constant expression.
+	 */
+	public boolean isConstantExpression()
+	{
+		return (receiver.isConstantExpression() &&
+				leftOperand.isConstantExpression() &&
+				(rightOperand == null || rightOperand.isConstantExpression()));
+	}
+
+	/** @see ValueNode#constantExpression */
+	public boolean constantExpression(PredicateList whereClause)
+	{
+		return (receiver.constantExpression(whereClause) &&
+				leftOperand.constantExpression(whereClause) &&
+				(rightOperand == null ||
+					rightOperand.constantExpression(whereClause)));
+	}
+
+	/**
+	 * Accept a visitor, and call v.visit()
+	 * on child nodes as necessary.  
+	 * 
+	 * @param v the visitor
+	 *
+	 * @exception StandardException on error
+	 */
+	public Visitable accept(Visitor v) 
+		throws StandardException
+	{
+		Visitable returnNode = v.visit(this);
+	
+		if (v.skipChildren(this))
+		{
+			return returnNode;
+		}
+
+		if (receiver != null && !v.stopTraversal())
+		{
+			receiver = (ValueNode)receiver.accept(v);
+		}
+
+		if (leftOperand != null && !v.stopTraversal())
+		{
+			leftOperand = (ValueNode)leftOperand.accept(v);
+		}
+
+		if (rightOperand != null && !v.stopTraversal())
+		{
+			rightOperand = (ValueNode)rightOperand.accept(v);
+		}
+		
+		return returnNode;
+	}
+	/**
+	 * Bind trim expression. 
+	 * @return	The new top of the expression tree.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	private ValueNode trimBind() 
+			throws StandardException
+	{
+		TypeId	receiverType;
+		TypeId	resultType = TypeId.getBuiltInTypeId(Types.VARCHAR);
+
+		// handle parameters here
+
+		/* Is there a ? parameter for the receiver? */
+		if (receiver.isParameterNode())
+		{
+			/*
+			** According to the SQL standard, if trim has a ? receiver,
+			** its type is varchar with the implementation-defined maximum length
+			** for a varchar.
+			*/
+	
+			((ParameterNode) receiver).setDescriptor(getVarcharDescriptor());
+		}
+
+		/* Is there a ? parameter on the left? */
+		if (leftOperand.isParameterNode())
+		{
+			/* Set the left operand type to varchar. */
+			((ParameterNode) leftOperand).setDescriptor(getVarcharDescriptor());
+		}
+
+		bindToBuiltIn();
+
+		/*
+		** Check the type of the receiver - this function is allowed only on
+		** string value types.  
+		*/
+		receiverType = receiver.getTypeId();
+		if (receiverType.userType())
+			throwBadType("trim", receiverType.getSQLTypeName());
+
+		receiver = castArgToString(receiver);
+
+		if ((receiverType.getTypeFormatId() == StoredFormatIds.CLOB_TYPE_ID) ||
+		   (receiverType.getTypeFormatId() == StoredFormatIds.NCLOB_TYPE_ID)) {
+		// special case for CLOBs: if we start with a CLOB, we have to get
+		// a CLOB as a result (as opposed to a VARCHAR), because we can have a 
+		// CLOB that is beyond the max length of VARCHAR (ex. "clob(100k)").
+		// This is okay because CLOBs, like VARCHARs, allow variable-length
+		// values (which is a must for the trim to actually work).
+			resultType = receiverType;
+		}
+
+		/*
+		** Check the type of the leftOperand (trimSet).
+		** The leftOperand should be a string value type.  
+		*/
+		TypeId	leftCTI;
+		leftCTI = leftOperand.getTypeId();
+		if (leftCTI.userType())
+			throwBadType("trim", leftCTI.getSQLTypeName());
+
+		leftOperand = castArgToString(leftOperand);
+
+		/*
+		** The result type of trim is varchar.
+		*/
+		setResultType(resultType);
+
+		return this;
+	}
+	/*
+	** set result type for operator
+	*/
+	private void setResultType(TypeId resultType) throws StandardException
+	{
+		setType(new DataTypeDescriptor(
+						resultType,
+						true,
+						receiver.getTypeServices().getMaximumWidth()
+					)
+				);
+	}
+	/**
+	 * Bind locate operator
+	 *
+	 * @return	The new top of the expression tree.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public ValueNode locateBind() throws StandardException
+	{
+		TypeId	firstOperandType, secondOperandType, offsetType;
+
+		/*
+		 * Is there a ? parameter for the first arg.  Copy the 
+		 * left/firstOperand's.  If the left/firstOperand are both parameters,
+		 * both will be max length.
+		 */
+		if( receiver.isParameterNode())
+		{
+			if( leftOperand.isParameterNode())
+			{
+				((ParameterNode) receiver).setDescriptor(getVarcharDescriptor());
+			}
+			else
+			{
+				if( leftOperand.getTypeId().isStringTypeId() )
+				{
+					((ParameterNode) receiver).setDescriptor(
+							         leftOperand.getTypeServices());
+				}
+			}
+		}
+							                            
+		/*
+		 * Is there a ? parameter for the second arg.  Copy the receiver's.
+		 * If the receiver are both parameters, both will be max length.
+		 */
+		if(leftOperand.isParameterNode())
+		{
+			if(receiver.isParameterNode())
+			{
+				((ParameterNode) leftOperand).setDescriptor(getVarcharDescriptor());
+			}
+			else
+			{
+				if( receiver.getTypeId().isStringTypeId() )
+				{
+					((ParameterNode) leftOperand).setDescriptor(
+							         receiver.getTypeServices());
+				}
+			}
+		}
+
+		/*
+		 * Is there a ? paramter for the third arg.  It will be an int.
+		 */
+		if( rightOperand.isParameterNode())
+		{
+			((ParameterNode) rightOperand).setDescriptor(
+				new DataTypeDescriptor(TypeId.INTEGER_ID, true)); 
+		}
+
+		bindToBuiltIn();
+
+		/*
+		** Check the type of the operand - this function is allowed only
+		** for: receiver = CHAR
+		**      firstOperand = CHAR
+		**      secondOperand = INT
+		*/
+		secondOperandType = leftOperand.getTypeId();
+		offsetType = rightOperand.getTypeId();
+		firstOperandType = receiver.getTypeId();
+
+		if (!firstOperandType.isStringTypeId() ||
+			!secondOperandType.isStringTypeId() || 
+			offsetType.getJDBCTypeId() != Types.INTEGER)
+			throw StandardException.newException(SQLState.LANG_DB2_FUNCTION_INCOMPATIBLE,
+					"LOCATE", "FUNCTION");
+
+		/*
+		** The result type of a LocateFunctionNode is an integer.
+		*/
+		setType(new DataTypeDescriptor(TypeId.INTEGER_ID, 
+				receiver.getTypeServices().isNullable())); 
+
+		return this;
+	}
+
+	/* cast arg to a varchar */
+	protected ValueNode castArgToString(ValueNode vn) throws StandardException
+	{
+		TypeCompiler vnTC = vn.getTypeCompiler();
+		if (! vn.getTypeId().isStringTypeId())
+		{
+			ValueNode newNode = (ValueNode)
+						getNodeFactory().getNode(
+							C_NodeTypes.CAST_NODE,
+							vn,
+							DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, true,
+							                vnTC.getCastToCharWidth(
+							                    vn.getTypeServices())),
+							getContextManager());
+			((CastNode) newNode).bindCastNodeOnly();
+			return newNode;
+		}
+		return vn;
+	}
+
+	/**
+	 * Bind substr expression.  
+	 *
+	 * @return	The new top of the expression tree.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+ 	public ValueNode substrBind() 
+			throws StandardException
+	{
+		TypeId	receiverType;
+		TypeId	resultType;
+
+		// handle parameters here
+
+		/* Is there a ? parameter for the receiver? */
+		if (receiver.isParameterNode())
+		{
+			/*
+			** According to the SQL standard, if substr has a ? receiver,
+			** its type is varchar with the implementation-defined maximum length
+			** for a varchar.
+			*/
+	
+			((ParameterNode) receiver).setDescriptor(getVarcharDescriptor());
+		}
+
+		/* Is there a ? parameter on the left? */
+		if (leftOperand.isParameterNode())
+		{
+			/* Set the left operand type to int. */
+			((ParameterNode) leftOperand).setDescriptor(							
+				new DataTypeDescriptor(TypeId.INTEGER_ID, true)); 
+		}
+
+		/* Is there a ? parameter on the right? */
+		if ((rightOperand != null) && rightOperand.isParameterNode())
+		{
+			/* Set the right operand type to int. */
+			((ParameterNode) rightOperand).setDescriptor(							
+				new DataTypeDescriptor(TypeId.INTEGER_ID, true)); 
+		}
+
+		bindToBuiltIn();
+
+		if (!leftOperand.getTypeId().isNumericTypeId() ||
+			(rightOperand != null && !rightOperand.getTypeId().isNumericTypeId()))
+			throw StandardException.newException(SQLState.LANG_DB2_FUNCTION_INCOMPATIBLE, "SUBSTR", "FUNCTION");
+
+		/*
+		** Check the type of the receiver - this function is allowed only on
+		** string value types.  
+		*/
+		resultType = receiverType = receiver.getTypeId();
+		switch (receiverType.getJDBCTypeId())
+		{
+			case Types.CHAR:
+			case Types.VARCHAR:
+			case Types.LONGVARCHAR:
+			case Types.CLOB:
+				break;
+			default:
+			{
+				throwBadType("SUBSTR", receiverType.getSQLTypeName());
+			}
+		}
+
+		// Determine the maximum length of the result
+		int resultLen = receiver.getTypeServices().getMaximumWidth();
+
+		if (rightOperand != null && rightOperand instanceof ConstantNode)
+		{
+			if (((ConstantNode)rightOperand).getValue().getInt() < resultLen)
+				resultLen = ((ConstantNode)rightOperand).getValue().getInt();
+		}
+
+		/*
+		** The result type of substr is a string type
+		*/
+		setType(new DataTypeDescriptor(
+						resultType,
+						true,
+						resultLen
+					));
+
+		return this;
+	}
+
+	public ValueNode getReceiver()
+	{
+		return receiver;
+	}
+
+	/* throw bad type message */
+	private void throwBadType(String funcName, String type) 
+		throws StandardException
+	{
+		throw StandardException.newException(SQLState.LANG_UNARY_FUNCTION_BAD_TYPE, 
+										funcName,
+										type);
+	}
+
+	/* bind arguments to built in types */
+	protected void bindToBuiltIn() 
+		throws StandardException
+	{
+		/* If the receiver is not a built-in type, then generate a bound conversion
+		 * tree to a built-in type.
+		 */
+		if (! receiver.getTypeId().systemBuiltIn())
+		{
+			receiver = receiver.genSQLJavaSQLTree();
+		}
+
+		/* If the left operand is not a built-in type, then generate a bound conversion
+		 * tree to a built-in type.
+		 */
+		if (! leftOperand.getTypeId().systemBuiltIn())
+		{
+			leftOperand = leftOperand.genSQLJavaSQLTree();
+		}
+
+		/* If the right operand is not a built-in type, then generate a bound conversion
+		 * tree to a built-in type.
+		 */
+		if (rightOperand != null)
+		{
+			if (! rightOperand.getTypeId().systemBuiltIn())
+			{
+				rightOperand = rightOperand.genSQLJavaSQLTree();
+			}
+		}
+	}
+
+	private DataTypeDescriptor getVarcharDescriptor() {
+		return new DataTypeDescriptor(TypeId.getBuiltInTypeId(Types.VARCHAR), true);
+	}
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TestConstraintNode.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TestConstraintNode.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TestConstraintNode.java	Fri Sep 24 10:33:20 2004
@@ -1,141 +1,141 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package	org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.sql.compile.C_NodeTypes;
-
-import org.apache.derby.iapi.services.compiler.MethodBuilder;
-import org.apache.derby.iapi.reference.ClassName;
-
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.types.TypeId;
-import org.apache.derby.iapi.types.BooleanDataValue;
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-
-import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
-import org.apache.derby.iapi.services.classfile.VMOpcode;
-
-import java.util.Vector;
-
-/**
- * A TestConstraintNode is used to determine when a constraint
- * has been violated.
- *
- * @author jeff
- */
-
-public class TestConstraintNode extends UnaryLogicalOperatorNode
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-	private String sqlState;
-	private String tableName;
-	private String constraintName;
-
-	/**
-	 * Initializer for a TestConstraintNode
-	 *
-	 * @param operand	The operand of the constraint test
-	 * @param sqlState	The SQLState of the exception to throw if the
-	 *					constraint has failed
-	 * @param tableName	The name of the table that the constraint is on
-	 * @param constraintName	The name of the constraint being checked
-	 */
-
-	public void init(Object booleanValue,
-					 Object sqlState,
-					 Object tableName,
-					 Object constraintName)
-	{
-		super.init(booleanValue, "throwExceptionIfFalse");
-		this.sqlState = (String) sqlState;
-		this.tableName = (String) tableName;
-		this.constraintName = (String) constraintName;
-	}
-
-	/**
-	 * Bind this logical operator.  All that has to be done for binding
-	 * a logical operator is to bind the operand, check that the operand
-	 * is SQLBoolean, and set the result type to SQLBoolean.
-	 *
-	 * @param fromList			The query's FROM list
-	 * @param subqueryList		The subquery list being built as we find SubqueryNodes
-	 * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
-	 *
-	 * @return	The new top of the expression tree.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public ValueNode bindExpression(
-		FromList fromList, SubqueryList subqueryList,
-		Vector	aggregateVector)
-			throws StandardException
-	{
-		bindUnaryOperator(fromList, subqueryList, aggregateVector);
-
-		/*
-		** If the operand is not boolean, cast it.
-		*/
-
-		if ( ! operand.getTypeServices().getTypeId().getSQLTypeName().equals(
-														TypeId.BOOLEAN_NAME))
-		{
-			operand = (ValueNode)
-				getNodeFactory().getNode(
-					C_NodeTypes.CAST_NODE,
-					operand,
-					new DataTypeDescriptor(TypeId.BOOLEAN_ID, true),
-					getContextManager());
-			((CastNode) operand).bindCastNodeOnly();
-		}
-
-		/* Set the type info */
-		setFullTypeInfo();
-
-		return this;
-	}
-
-	/**
-	 * Do code generation for the TestConstraint operator.
-	 *
-	 * @param acb	The ExpressionClassBuilder for the class we're generating
-	 * @param mb	The method the expression will go into
-	 *
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public void generateExpression(ExpressionClassBuilder acb,
-											MethodBuilder mb)
-									throws StandardException
-	{
-
-		/*
-		** This generates the following code:
-		**
-		** operand.testConstraint(sqlState, tableName, constraintName)
-		*/
-
-		operand.generateExpression(acb, mb);
-
-		mb.push(sqlState);
-		mb.push(tableName);
-		mb.push(constraintName);
-
-		mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.BooleanDataValue,
-				"throwExceptionIfFalse", ClassName.BooleanDataValue, 3);
-
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package	org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.sql.compile.C_NodeTypes;
+
+import org.apache.derby.iapi.services.compiler.MethodBuilder;
+import org.apache.derby.iapi.reference.ClassName;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.types.TypeId;
+import org.apache.derby.iapi.types.BooleanDataValue;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+
+import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
+import org.apache.derby.iapi.services.classfile.VMOpcode;
+
+import java.util.Vector;
+
+/**
+ * A TestConstraintNode is used to determine when a constraint
+ * has been violated.
+ *
+ * @author jeff
+ */
+
+public class TestConstraintNode extends UnaryLogicalOperatorNode
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+	private String sqlState;
+	private String tableName;
+	private String constraintName;
+
+	/**
+	 * Initializer for a TestConstraintNode
+	 *
+	 * @param operand	The operand of the constraint test
+	 * @param sqlState	The SQLState of the exception to throw if the
+	 *					constraint has failed
+	 * @param tableName	The name of the table that the constraint is on
+	 * @param constraintName	The name of the constraint being checked
+	 */
+
+	public void init(Object booleanValue,
+					 Object sqlState,
+					 Object tableName,
+					 Object constraintName)
+	{
+		super.init(booleanValue, "throwExceptionIfFalse");
+		this.sqlState = (String) sqlState;
+		this.tableName = (String) tableName;
+		this.constraintName = (String) constraintName;
+	}
+
+	/**
+	 * Bind this logical operator.  All that has to be done for binding
+	 * a logical operator is to bind the operand, check that the operand
+	 * is SQLBoolean, and set the result type to SQLBoolean.
+	 *
+	 * @param fromList			The query's FROM list
+	 * @param subqueryList		The subquery list being built as we find SubqueryNodes
+	 * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
+	 *
+	 * @return	The new top of the expression tree.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public ValueNode bindExpression(
+		FromList fromList, SubqueryList subqueryList,
+		Vector	aggregateVector)
+			throws StandardException
+	{
+		bindUnaryOperator(fromList, subqueryList, aggregateVector);
+
+		/*
+		** If the operand is not boolean, cast it.
+		*/
+
+		if ( ! operand.getTypeServices().getTypeId().getSQLTypeName().equals(
+														TypeId.BOOLEAN_NAME))
+		{
+			operand = (ValueNode)
+				getNodeFactory().getNode(
+					C_NodeTypes.CAST_NODE,
+					operand,
+					new DataTypeDescriptor(TypeId.BOOLEAN_ID, true),
+					getContextManager());
+			((CastNode) operand).bindCastNodeOnly();
+		}
+
+		/* Set the type info */
+		setFullTypeInfo();
+
+		return this;
+	}
+
+	/**
+	 * Do code generation for the TestConstraint operator.
+	 *
+	 * @param acb	The ExpressionClassBuilder for the class we're generating
+	 * @param mb	The method the expression will go into
+	 *
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public void generateExpression(ExpressionClassBuilder acb,
+											MethodBuilder mb)
+									throws StandardException
+	{
+
+		/*
+		** This generates the following code:
+		**
+		** operand.testConstraint(sqlState, tableName, constraintName)
+		*/
+
+		operand.generateExpression(acb, mb);
+
+		mb.push(sqlState);
+		mb.push(tableName);
+		mb.push(constraintName);
+
+		mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.BooleanDataValue,
+				"throwExceptionIfFalse", ClassName.BooleanDataValue, 3);
+
+	}
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TimeTypeCompiler.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TimeTypeCompiler.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TimeTypeCompiler.java	Fri Sep 24 10:33:20 2004
@@ -1,167 +1,167 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1999, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.services.loader.ClassFactory;
-
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-import org.apache.derby.iapi.types.DateTimeDataValue;
-import org.apache.derby.iapi.types.DataValueFactory;
-import org.apache.derby.iapi.types.TypeId;
-
-import org.apache.derby.iapi.sql.compile.TypeCompiler;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-import java.sql.Types;
-import org.apache.derby.iapi.reference.ClassName;
-
-public class TimeTypeCompiler extends BaseTypeCompiler
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1999_2004;
-	/* TypeCompiler methods */
-
-	/**
-	 * Dates are comparable to timestamps and to comparable
-	 * user types.
-	 *
-	 * @param otherType the type of the instance to compare with this type.
-	 * @param forEquals True if this is an = or <> comparison, false
-	 *					otherwise.
-	 * @param cf		A ClassFactory
-	 * @return true if otherType is comparable to this type, else false.
-	 */
-	public boolean comparable(TypeId otherType,
-                              boolean forEquals,
-                              ClassFactory cf)
-	{
-		int otherJDBCTypeId = otherType.getJDBCTypeId();
-
-		// Long types cannot be compared
-		if (otherType.isLongConcatableTypeId())
-			return false;
-
-		if (otherJDBCTypeId == Types.TIME || otherType.isStringTypeId())
-			return true;
-
-		TypeCompiler otherTC = getTypeCompiler(otherType);
-
-		/* User types know the rules for what can be compared to them */
-		if (otherType.userType())
-		{
-			return otherTC.comparable(getTypeId(), forEquals, cf);
-		}
-
-		return false;
-	}
-
-	/**
-	 * User types are convertible to other user types only if
-	 * (for now) they are the same type and are being used to
-	 * implement some JDBC type.  This is sufficient for
-	 * date/time types; it may be generalized later for e.g.
-	 * comparison of any user type with one of its subtypes.
-	 *
-	 * @see TypeCompiler#convertible 
-	 */
-	public boolean convertible(TypeId otherType,
-							   boolean forDataTypeFunction)
-	{
-
-		if (otherType.isStringTypeId() && 
-			(!otherType.isLOBTypeId()) &&
-			!otherType.isLongVarcharTypeId())
-		{
-			return true;
-		}
-
-
-		/*
-		** If same type, convert always ok.
-		*/
-		return (getStoredFormatIdFromTypeId() == 
-				otherType.getTypeFormatId());
-		   
-	}
-
-	/** @see TypeCompiler#compatible */
-	public boolean compatible(TypeId otherType)
-	{
-		return convertible(otherType,false);
-	}
-
-	/**
-	 * User types are storable into other user types that they
-	 * are assignable to. The other type must be a subclass of
-	 * this type, or implement this type as one of its interfaces.
-	 *
-	 * Built-in types are also storable into user types when the built-in
-	 * type's corresponding Java type is assignable to the user type.
-	 *
-	 * @param otherType the type of the instance to store into this type.
-	 * @param cf		A ClassFactory
-	 * @return true if otherType is storable into this type, else false.
-	 */
-	public boolean storable(TypeId otherType, ClassFactory cf)
-	{
-		int	otherJDBCTypeId = otherType.getJDBCTypeId();
-
-		if (otherJDBCTypeId == Types.TIME ||
-			(otherJDBCTypeId == Types.CHAR) ||
-			(otherJDBCTypeId == Types.VARCHAR))
-		{
-			return true;
-		}
-
-		return cf.getClassInspector().assignableTo(
-			   otherType.getCorrespondingJavaTypeName(),
-			   "java.sql.Time");
-	}
-
-	/** @see TypeCompiler#interfaceName */
-	public String interfaceName()
-	{
-		return ClassName.DateTimeDataValue;
-	}
-			
-	/**
-	 * @see TypeCompiler#getCorrespondingPrimitiveTypeName
-	 */
-
-	public String getCorrespondingPrimitiveTypeName()
-	{
-		return "java.sql.Time";
-	}
-
-	/**
-	 * @see TypeCompiler#getCastToCharWidth
-	 */
-	public int getCastToCharWidth(DataTypeDescriptor dts)
-	{
-		return 8;
-	}
-
-	public double estimatedMemoryUsage(DataTypeDescriptor dtd)
-	{
-		return 12.0;
-	}
-
-	protected String nullMethodName()
-	{
-		return "getNullTime";
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1999, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.services.loader.ClassFactory;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+import org.apache.derby.iapi.types.DateTimeDataValue;
+import org.apache.derby.iapi.types.DataValueFactory;
+import org.apache.derby.iapi.types.TypeId;
+
+import org.apache.derby.iapi.sql.compile.TypeCompiler;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+import java.sql.Types;
+import org.apache.derby.iapi.reference.ClassName;
+
+public class TimeTypeCompiler extends BaseTypeCompiler
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1999_2004;
+	/* TypeCompiler methods */
+
+	/**
+	 * Dates are comparable to timestamps and to comparable
+	 * user types.
+	 *
+	 * @param otherType the type of the instance to compare with this type.
+	 * @param forEquals True if this is an = or <> comparison, false
+	 *					otherwise.
+	 * @param cf		A ClassFactory
+	 * @return true if otherType is comparable to this type, else false.
+	 */
+	public boolean comparable(TypeId otherType,
+                              boolean forEquals,
+                              ClassFactory cf)
+	{
+		int otherJDBCTypeId = otherType.getJDBCTypeId();
+
+		// Long types cannot be compared
+		if (otherType.isLongConcatableTypeId())
+			return false;
+
+		if (otherJDBCTypeId == Types.TIME || otherType.isStringTypeId())
+			return true;
+
+		TypeCompiler otherTC = getTypeCompiler(otherType);
+
+		/* User types know the rules for what can be compared to them */
+		if (otherType.userType())
+		{
+			return otherTC.comparable(getTypeId(), forEquals, cf);
+		}
+
+		return false;
+	}
+
+	/**
+	 * User types are convertible to other user types only if
+	 * (for now) they are the same type and are being used to
+	 * implement some JDBC type.  This is sufficient for
+	 * date/time types; it may be generalized later for e.g.
+	 * comparison of any user type with one of its subtypes.
+	 *
+	 * @see TypeCompiler#convertible 
+	 */
+	public boolean convertible(TypeId otherType,
+							   boolean forDataTypeFunction)
+	{
+
+		if (otherType.isStringTypeId() && 
+			(!otherType.isLOBTypeId()) &&
+			!otherType.isLongVarcharTypeId())
+		{
+			return true;
+		}
+
+
+		/*
+		** If same type, convert always ok.
+		*/
+		return (getStoredFormatIdFromTypeId() == 
+				otherType.getTypeFormatId());
+		   
+	}
+
+	/** @see TypeCompiler#compatible */
+	public boolean compatible(TypeId otherType)
+	{
+		return convertible(otherType,false);
+	}
+
+	/**
+	 * User types are storable into other user types that they
+	 * are assignable to. The other type must be a subclass of
+	 * this type, or implement this type as one of its interfaces.
+	 *
+	 * Built-in types are also storable into user types when the built-in
+	 * type's corresponding Java type is assignable to the user type.
+	 *
+	 * @param otherType the type of the instance to store into this type.
+	 * @param cf		A ClassFactory
+	 * @return true if otherType is storable into this type, else false.
+	 */
+	public boolean storable(TypeId otherType, ClassFactory cf)
+	{
+		int	otherJDBCTypeId = otherType.getJDBCTypeId();
+
+		if (otherJDBCTypeId == Types.TIME ||
+			(otherJDBCTypeId == Types.CHAR) ||
+			(otherJDBCTypeId == Types.VARCHAR))
+		{
+			return true;
+		}
+
+		return cf.getClassInspector().assignableTo(
+			   otherType.getCorrespondingJavaTypeName(),
+			   "java.sql.Time");
+	}
+
+	/** @see TypeCompiler#interfaceName */
+	public String interfaceName()
+	{
+		return ClassName.DateTimeDataValue;
+	}
+			
+	/**
+	 * @see TypeCompiler#getCorrespondingPrimitiveTypeName
+	 */
+
+	public String getCorrespondingPrimitiveTypeName()
+	{
+		return "java.sql.Time";
+	}
+
+	/**
+	 * @see TypeCompiler#getCastToCharWidth
+	 */
+	public int getCastToCharWidth(DataTypeDescriptor dts)
+	{
+		return 8;
+	}
+
+	public double estimatedMemoryUsage(DataTypeDescriptor dtd)
+	{
+		return 12.0;
+	}
+
+	protected String nullMethodName()
+	{
+		return "getNullTime";
+	}
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TimestampOperatorNode.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TimestampOperatorNode.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TimestampOperatorNode.java	Fri Sep 24 10:33:20 2004
@@ -1,115 +1,115 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package	org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.types.TypeId;
-import org.apache.derby.iapi.types.DataValueFactory;
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-import org.apache.derby.iapi.services.compiler.MethodBuilder;
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
-
-import org.apache.derby.iapi.reference.ClassName;
-import org.apache.derby.iapi.reference.SQLState;
-
-import org.apache.derby.iapi.services.classfile.VMOpcode;
-
-import java.sql.Types;
-
-import java.util.Vector;
-
-/**
- * The TimestampOperatorNode class implements the timestamp( date, time) function.
- */
-
-public class TimestampOperatorNode extends BinaryOperatorNode
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2004;
-
-    /**
-     * Initailizer for a TimestampOperatorNode.
-     *
-     * @param date The date
-     * @param time The time
-     */
-
-    public void init( Object date,
-                      Object time)
-    {
-        leftOperand = (ValueNode) date;
-        rightOperand = (ValueNode) time;
-        operator = "timestamp";
-        methodName = "getTimestamp";
-    }
-
-
-	/**
-	 * Bind this expression.  This means binding the sub-expressions,
-	 * as well as figuring out what the return type is for this expression.
-	 *
-	 * @param fromList		The FROM list for the query this
-	 *				expression is in, for binding columns.
-	 * @param subqueryList		The subquery list being built as we find SubqueryNodes
-	 * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
-	 *
-	 * @return	The new top of the expression tree.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public ValueNode bindExpression(
-		FromList fromList, SubqueryList subqueryList,
-		Vector	aggregateVector) 
-			throws StandardException
-	{
-		leftOperand = leftOperand.bindExpression(fromList, subqueryList, 
-			aggregateVector);
-		rightOperand = rightOperand.bindExpression(fromList, subqueryList, 
-			aggregateVector);
-
-        TypeId leftTypeId = leftOperand.getTypeId();
-        TypeId rightTypeId = rightOperand.getTypeId();
-        if( !(leftTypeId.isStringTypeId() || leftTypeId.getJDBCTypeId() == Types.DATE || leftOperand.isParameterNode()))
-            throw StandardException.newException(SQLState.LANG_BINARY_OPERATOR_NOT_SUPPORTED, 
-                                                 operator, leftTypeId.getSQLTypeName(), rightTypeId.getSQLTypeName());
-        if( !(rightTypeId.isStringTypeId() || rightTypeId.getJDBCTypeId() == Types.TIME || rightOperand.isParameterNode()))
-            throw StandardException.newException(SQLState.LANG_BINARY_OPERATOR_NOT_SUPPORTED, 
-                                                 operator, leftTypeId.getSQLTypeName(), rightTypeId.getSQLTypeName());
-        setType(DataTypeDescriptor.getBuiltInDataTypeDescriptor( Types.TIMESTAMP));
-		return genSQLJavaSQLTree();
-	} // end of bindExpression
-
-    /**
-	 * Do code generation for this binary operator.
-	 *
-	 * @param acb	The ExpressionClassBuilder for the class we're generating
-	 * @param mb	The method the code to place the code
-	 *
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	public void generateExpression(ExpressionClassBuilder acb,
-											MethodBuilder mb)
-		throws StandardException
-	{
-        acb.pushDataValueFactory(mb);
-		leftOperand.generateExpression(acb, mb);
-        mb.cast( ClassName.DataValueDescriptor);
-		rightOperand.generateExpression(acb, mb);
-        mb.cast( ClassName.DataValueDescriptor);
-        mb.callMethod( VMOpcode.INVOKEINTERFACE, null, methodName, ClassName.DateTimeDataValue, 2);
-    } // end of generateExpression
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package	org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.types.TypeId;
+import org.apache.derby.iapi.types.DataValueFactory;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+import org.apache.derby.iapi.services.compiler.MethodBuilder;
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
+
+import org.apache.derby.iapi.reference.ClassName;
+import org.apache.derby.iapi.reference.SQLState;
+
+import org.apache.derby.iapi.services.classfile.VMOpcode;
+
+import java.sql.Types;
+
+import java.util.Vector;
+
+/**
+ * The TimestampOperatorNode class implements the timestamp( date, time) function.
+ */
+
+public class TimestampOperatorNode extends BinaryOperatorNode
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2004;
+
+    /**
+     * Initailizer for a TimestampOperatorNode.
+     *
+     * @param date The date
+     * @param time The time
+     */
+
+    public void init( Object date,
+                      Object time)
+    {
+        leftOperand = (ValueNode) date;
+        rightOperand = (ValueNode) time;
+        operator = "timestamp";
+        methodName = "getTimestamp";
+    }
+
+
+	/**
+	 * Bind this expression.  This means binding the sub-expressions,
+	 * as well as figuring out what the return type is for this expression.
+	 *
+	 * @param fromList		The FROM list for the query this
+	 *				expression is in, for binding columns.
+	 * @param subqueryList		The subquery list being built as we find SubqueryNodes
+	 * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
+	 *
+	 * @return	The new top of the expression tree.
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public ValueNode bindExpression(
+		FromList fromList, SubqueryList subqueryList,
+		Vector	aggregateVector) 
+			throws StandardException
+	{
+		leftOperand = leftOperand.bindExpression(fromList, subqueryList, 
+			aggregateVector);
+		rightOperand = rightOperand.bindExpression(fromList, subqueryList, 
+			aggregateVector);
+
+        TypeId leftTypeId = leftOperand.getTypeId();
+        TypeId rightTypeId = rightOperand.getTypeId();
+        if( !(leftTypeId.isStringTypeId() || leftTypeId.getJDBCTypeId() == Types.DATE || leftOperand.isParameterNode()))
+            throw StandardException.newException(SQLState.LANG_BINARY_OPERATOR_NOT_SUPPORTED, 
+                                                 operator, leftTypeId.getSQLTypeName(), rightTypeId.getSQLTypeName());
+        if( !(rightTypeId.isStringTypeId() || rightTypeId.getJDBCTypeId() == Types.TIME || rightOperand.isParameterNode()))
+            throw StandardException.newException(SQLState.LANG_BINARY_OPERATOR_NOT_SUPPORTED, 
+                                                 operator, leftTypeId.getSQLTypeName(), rightTypeId.getSQLTypeName());
+        setType(DataTypeDescriptor.getBuiltInDataTypeDescriptor( Types.TIMESTAMP));
+		return genSQLJavaSQLTree();
+	} // end of bindExpression
+
+    /**
+	 * Do code generation for this binary operator.
+	 *
+	 * @param acb	The ExpressionClassBuilder for the class we're generating
+	 * @param mb	The method the code to place the code
+	 *
+	 *
+	 * @exception StandardException		Thrown on error
+	 */
+
+	public void generateExpression(ExpressionClassBuilder acb,
+											MethodBuilder mb)
+		throws StandardException
+	{
+        acb.pushDataValueFactory(mb);
+		leftOperand.generateExpression(acb, mb);
+        mb.cast( ClassName.DataValueDescriptor);
+		rightOperand.generateExpression(acb, mb);
+        mb.cast( ClassName.DataValueDescriptor);
+        mb.callMethod( VMOpcode.INVOKEINTERFACE, null, methodName, ClassName.DateTimeDataValue, 2);
+    } // end of generateExpression
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TimestampTypeCompiler.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TimestampTypeCompiler.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TimestampTypeCompiler.java	Fri Sep 24 10:33:20 2004
@@ -1,196 +1,196 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1999, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.services.loader.ClassFactory;
-
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-import org.apache.derby.iapi.types.DateTimeDataValue;
-import org.apache.derby.iapi.types.DataValueFactory;
-import org.apache.derby.iapi.types.TypeId;
-
-import org.apache.derby.iapi.sql.compile.TypeCompiler;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-import java.sql.Types;
-import org.apache.derby.iapi.reference.ClassName;
-
-public class TimestampTypeCompiler extends BaseTypeCompiler
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1999_2004;
-	/* TypeCompiler methods */
-
-	/**
-	 * Timestamps are comparable to timestamps and to comparable
-	 * user types.
-	 *
-	 * @param otherType the type of the instance to compare with this type.
-	 * @param forEquals True if this is an = or <> comparison, false
-	 *					otherwise.
-	 * @param cf		A ClassFactory
-	 * @return true if otherType is comparable to this type, else false.
-	 */
-	public boolean comparable(TypeId otherType,
-                              boolean forEquals,
-                              ClassFactory cf)
-	{
-		 return comparable(getTypeId(), otherType, forEquals, cf);
-	}
-
-	boolean comparable(TypeId leftType,
-						TypeId otherType,
-						boolean forEquals,
-						ClassFactory cf)
-    {
-
-		int otherJDBCTypeId = otherType.getJDBCTypeId();
-
-		// Long types cannot be compared
-		if (otherType.isLongConcatableTypeId())
-			return false;
-
-		TypeCompiler otherTC = getTypeCompiler(otherType);
-		if (otherJDBCTypeId == Types.TIMESTAMP || otherType.isStringTypeId())
-			return true;
-
-		/* User types know the rules for what can be compared to them */
-		if (otherType.userType())
-		{
-			return otherTC.comparable(getTypeId(), forEquals, cf);
-		}
-
-		return false;
-	}
-
-	/**
-	 * User types are convertible to other user types only if
-	 * (for now) they are the same type and are being used to
-	 * implement some JDBC type.  This is sufficient for
-	 * date/time types; it may be generalized later for e.g.
-	 * comparison of any user type with one of its subtypes.
-	 *
-	 * @see TypeCompiler#convertible 
-	 *
-	 */
-	public boolean convertible(TypeId otherType, 
-							   boolean forDataTypeFunction)
-	{
-		if (otherType.isStringTypeId()&& 
-			(!otherType.isLongConcatableTypeId()))
-		{
-			return true;
-		}
-		
-		int otherJDBCTypeId = otherType.getJDBCTypeId();
-
-		/*
-		** At this point, we have only date/time.  If
-		** same type, convert always ok.
-		*/
-		if (otherJDBCTypeId == Types.TIMESTAMP)
-		{
-			return true;
-		}
-
-		/*
-		** Otherwise, we can convert timestamp to
-		** date or time only.
-		*/
-		return ((otherJDBCTypeId == Types.DATE) ||
-				(otherJDBCTypeId == Types.TIME));
-	}
-
-        /**
-         * Tell whether this type (timestamp) is compatible with the given type.
-         *
-         * @param otherType     The TypeId of the other type.
-         */
-	public boolean compatible(TypeId otherType)
-	{
-		if (otherType.isStringTypeId() &&
-			(!otherType.isLongConcatableTypeId()))
-		{
-			return true;
-		}
-
-		/*
-		** Both are timestamp datatypes and hence compatible.
-		*/
-		return (getStoredFormatIdFromTypeId() ==
-				otherType.getTypeFormatId());
-	}
-
-	/**
-	 * User types are storable into other user types that they
-	 * are assignable to. The other type must be a subclass of
-	 * this type, or implement this type as one of its interfaces.
-	 *
-	 * Built-in types are also storable into user types when the built-in
-	 * type's corresponding Java type is assignable to the user type.
-	 *
-	 * @param otherType the type of the instance to store into this type.
-	 * @param cf		A ClassFactory
-	 * @return true if otherType is storable into this type, else false.
-	 */
-	public boolean storable(TypeId otherType, ClassFactory cf)
-	{
-		int	otherJDBCTypeId = otherType.getJDBCTypeId();
-
-		if (otherJDBCTypeId == Types.TIMESTAMP ||
-			(otherJDBCTypeId == Types.CHAR) ||
-			(otherJDBCTypeId == Types.VARCHAR))
-		{
-			return true;
-		}
-
-		return cf.getClassInspector().assignableTo(
-			   otherType.getCorrespondingJavaTypeName(),
-			   "java.sql.Timestamp");
-	}
-
-	/** @see TypeCompiler#interfaceName */
-	public String interfaceName()
-	{
-		return ClassName.DateTimeDataValue;
-	}
-			
-	/**
-	 * @see TypeCompiler#getCorrespondingPrimitiveTypeName
-	 */
-
-	public String getCorrespondingPrimitiveTypeName()
-	{
-		return "java.sql.Timestamp";
-	}
-
-	/**
-	 * @see TypeCompiler#getCastToCharWidth
-	 */
-	public int getCastToCharWidth(DataTypeDescriptor dts)
-	{
-		return 26; // DATE TIME.milliseconds (extra few for good measure)
-	}
-
-	public double estimatedMemoryUsage(DataTypeDescriptor dtd)
-	{
-		return 12.0;
-	}
-	protected String nullMethodName()
-	{
-		return "getNullTimestamp";
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1999, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.services.loader.ClassFactory;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+import org.apache.derby.iapi.types.DateTimeDataValue;
+import org.apache.derby.iapi.types.DataValueFactory;
+import org.apache.derby.iapi.types.TypeId;
+
+import org.apache.derby.iapi.sql.compile.TypeCompiler;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+import java.sql.Types;
+import org.apache.derby.iapi.reference.ClassName;
+
+public class TimestampTypeCompiler extends BaseTypeCompiler
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1999_2004;
+	/* TypeCompiler methods */
+
+	/**
+	 * Timestamps are comparable to timestamps and to comparable
+	 * user types.
+	 *
+	 * @param otherType the type of the instance to compare with this type.
+	 * @param forEquals True if this is an = or <> comparison, false
+	 *					otherwise.
+	 * @param cf		A ClassFactory
+	 * @return true if otherType is comparable to this type, else false.
+	 */
+	public boolean comparable(TypeId otherType,
+                              boolean forEquals,
+                              ClassFactory cf)
+	{
+		 return comparable(getTypeId(), otherType, forEquals, cf);
+	}
+
+	boolean comparable(TypeId leftType,
+						TypeId otherType,
+						boolean forEquals,
+						ClassFactory cf)
+    {
+
+		int otherJDBCTypeId = otherType.getJDBCTypeId();
+
+		// Long types cannot be compared
+		if (otherType.isLongConcatableTypeId())
+			return false;
+
+		TypeCompiler otherTC = getTypeCompiler(otherType);
+		if (otherJDBCTypeId == Types.TIMESTAMP || otherType.isStringTypeId())
+			return true;
+
+		/* User types know the rules for what can be compared to them */
+		if (otherType.userType())
+		{
+			return otherTC.comparable(getTypeId(), forEquals, cf);
+		}
+
+		return false;
+	}
+
+	/**
+	 * User types are convertible to other user types only if
+	 * (for now) they are the same type and are being used to
+	 * implement some JDBC type.  This is sufficient for
+	 * date/time types; it may be generalized later for e.g.
+	 * comparison of any user type with one of its subtypes.
+	 *
+	 * @see TypeCompiler#convertible 
+	 *
+	 */
+	public boolean convertible(TypeId otherType, 
+							   boolean forDataTypeFunction)
+	{
+		if (otherType.isStringTypeId()&& 
+			(!otherType.isLongConcatableTypeId()))
+		{
+			return true;
+		}
+		
+		int otherJDBCTypeId = otherType.getJDBCTypeId();
+
+		/*
+		** At this point, we have only date/time.  If
+		** same type, convert always ok.
+		*/
+		if (otherJDBCTypeId == Types.TIMESTAMP)
+		{
+			return true;
+		}
+
+		/*
+		** Otherwise, we can convert timestamp to
+		** date or time only.
+		*/
+		return ((otherJDBCTypeId == Types.DATE) ||
+				(otherJDBCTypeId == Types.TIME));
+	}
+
+        /**
+         * Tell whether this type (timestamp) is compatible with the given type.
+         *
+         * @param otherType     The TypeId of the other type.
+         */
+	public boolean compatible(TypeId otherType)
+	{
+		if (otherType.isStringTypeId() &&
+			(!otherType.isLongConcatableTypeId()))
+		{
+			return true;
+		}
+
+		/*
+		** Both are timestamp datatypes and hence compatible.
+		*/
+		return (getStoredFormatIdFromTypeId() ==
+				otherType.getTypeFormatId());
+	}
+
+	/**
+	 * User types are storable into other user types that they
+	 * are assignable to. The other type must be a subclass of
+	 * this type, or implement this type as one of its interfaces.
+	 *
+	 * Built-in types are also storable into user types when the built-in
+	 * type's corresponding Java type is assignable to the user type.
+	 *
+	 * @param otherType the type of the instance to store into this type.
+	 * @param cf		A ClassFactory
+	 * @return true if otherType is storable into this type, else false.
+	 */
+	public boolean storable(TypeId otherType, ClassFactory cf)
+	{
+		int	otherJDBCTypeId = otherType.getJDBCTypeId();
+
+		if (otherJDBCTypeId == Types.TIMESTAMP ||
+			(otherJDBCTypeId == Types.CHAR) ||
+			(otherJDBCTypeId == Types.VARCHAR))
+		{
+			return true;
+		}
+
+		return cf.getClassInspector().assignableTo(
+			   otherType.getCorrespondingJavaTypeName(),
+			   "java.sql.Timestamp");
+	}
+
+	/** @see TypeCompiler#interfaceName */
+	public String interfaceName()
+	{
+		return ClassName.DateTimeDataValue;
+	}
+			
+	/**
+	 * @see TypeCompiler#getCorrespondingPrimitiveTypeName
+	 */
+
+	public String getCorrespondingPrimitiveTypeName()
+	{
+		return "java.sql.Timestamp";
+	}
+
+	/**
+	 * @see TypeCompiler#getCastToCharWidth
+	 */
+	public int getCastToCharWidth(DataTypeDescriptor dts)
+	{
+		return 26; // DATE TIME.milliseconds (extra few for good measure)
+	}
+
+	public double estimatedMemoryUsage(DataTypeDescriptor dtd)
+	{
+		return 12.0;
+	}
+	protected String nullMethodName()
+	{
+		return "getNullTimestamp";
+	}
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/Token.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/Token.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/Token.java	Fri Sep 24 10:33:20 2004
@@ -1,102 +1,102 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.sql.compile;
-
-/**
- * Describes the input token stream.
- */
-
-public class Token {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-
-  /**
-   * An integer that describes the kind of this token.  This numbering
-   * system is determined by JavaCCParser, and a table of these numbers is
-   * stored in the file ...Constants.java.
-   */
-  public int kind;
-
-  /**
-   * beginLine and beginColumn describe the position of the first character
-   * of this token; endLine and endColumn describe the position of the
-   * last character of this token.
-   */
-  public int beginLine, beginColumn, endLine, endColumn;
-
-  /**
-   * beginOffset and endOffset are useful for siphoning substrings out of
-   * the Statement so that we can recompile the substrings at upgrade time.
-   * For instance, VIEW definitions and the Restrictions on Published Tables
-   * need to be recompiled at upgrade time.
-   */
-  public int beginOffset, endOffset;
-
-  /**
-   * The string image of the token.
-   */
-  public String image;
-
-  /**
-   * A reference to the next regular (non-special) token from the input
-   * stream.  If this is the last token from the input stream, or if the
-   * token manager has not read tokens beyond this one, this field is
-   * set to null.  This is true only if this token is also a regular
-   * token.  Otherwise, see below for a description of the contents of
-   * this field.
-   */
-  public Token next;
-
-  /**
-   * This field is used to access special tokens that occur prior to this
-   * token, but after the immediately preceding regular (non-special) token.
-   * If there are no such special tokens, this field is set to null.
-   * When there are more than one such special token, this field refers
-   * to the last of these special tokens, which in turn refers to the next
-   * previous special token through its specialToken field, and so on
-   * until the first special token (whose specialToken field is null).
-   * The next fields of special tokens refer to other special tokens that
-   * immediately follow it (without an intervening regular token).  If there
-   * is no such token, this field is null.
-   */
-  public Token specialToken;
-
-  /**
-   * Returns the image.
-   */
-  public String toString()
-  {
-     return image;
-  }
-
-  /**
-   * Returns a new Token object, by default. However, if you want, you
-   * can create and return subclass objects based on the value of ofKind.
-   * Simply add the cases to the switch for all those special cases.
-   * For example, if you have a subclass of Token called IDToken that
-   * you want to create if ofKind is ID, simlpy add something like :
-   *
-   *    case MyParserConstants.ID : return new IDToken();
-   *
-   * to the following switch statement. Then you can cast matchedToken
-   * variable to the appropriate type and use it in your lexical actions.
-   */
-  public static final Token newToken(int ofKind)
-  {
-     switch(ofKind)
-     {
-       default : return new Token();
-     }
-  }
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.sql.compile;
+
+/**
+ * Describes the input token stream.
+ */
+
+public class Token {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+
+  /**
+   * An integer that describes the kind of this token.  This numbering
+   * system is determined by JavaCCParser, and a table of these numbers is
+   * stored in the file ...Constants.java.
+   */
+  public int kind;
+
+  /**
+   * beginLine and beginColumn describe the position of the first character
+   * of this token; endLine and endColumn describe the position of the
+   * last character of this token.
+   */
+  public int beginLine, beginColumn, endLine, endColumn;
+
+  /**
+   * beginOffset and endOffset are useful for siphoning substrings out of
+   * the Statement so that we can recompile the substrings at upgrade time.
+   * For instance, VIEW definitions and the Restrictions on Published Tables
+   * need to be recompiled at upgrade time.
+   */
+  public int beginOffset, endOffset;
+
+  /**
+   * The string image of the token.
+   */
+  public String image;
+
+  /**
+   * A reference to the next regular (non-special) token from the input
+   * stream.  If this is the last token from the input stream, or if the
+   * token manager has not read tokens beyond this one, this field is
+   * set to null.  This is true only if this token is also a regular
+   * token.  Otherwise, see below for a description of the contents of
+   * this field.
+   */
+  public Token next;
+
+  /**
+   * This field is used to access special tokens that occur prior to this
+   * token, but after the immediately preceding regular (non-special) token.
+   * If there are no such special tokens, this field is set to null.
+   * When there are more than one such special token, this field refers
+   * to the last of these special tokens, which in turn refers to the next
+   * previous special token through its specialToken field, and so on
+   * until the first special token (whose specialToken field is null).
+   * The next fields of special tokens refer to other special tokens that
+   * immediately follow it (without an intervening regular token).  If there
+   * is no such token, this field is null.
+   */
+  public Token specialToken;
+
+  /**
+   * Returns the image.
+   */
+  public String toString()
+  {
+     return image;
+  }
+
+  /**
+   * Returns a new Token object, by default. However, if you want, you
+   * can create and return subclass objects based on the value of ofKind.
+   * Simply add the cases to the switch for all those special cases.
+   * For example, if you have a subclass of Token called IDToken that
+   * you want to create if ofKind is ID, simlpy add something like :
+   *
+   *    case MyParserConstants.ID : return new IDToken();
+   *
+   * to the following switch statement. Then you can cast matchedToken
+   * variable to the appropriate type and use it in your lexical actions.
+   */
+  public static final Token newToken(int ofKind)
+  {
+     switch(ofKind)
+     {
+       default : return new Token();
+     }
+  }
+
+}

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TransactionStatementNode.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TransactionStatementNode.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TransactionStatementNode.java	Fri Sep 24 10:33:20 2004
@@ -1,58 +1,58 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.sql.compile
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-
-package	org.apache.derby.impl.sql.compile;
-
-import org.apache.derby.iapi.services.context.ContextManager;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-/**
- * A TransactionStatementNode represents any type of Transaction statement: 
- * SET TRANSACTION, COMMIT, and ROLLBACK.
- *
- * @author Ames Carlson
- */
-
-public abstract class TransactionStatementNode extends StatementNode
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	int activationKind()
-	{
-		   return StatementNode.NEED_NOTHING_ACTIVATION;
-	}
-	/**
-	 * COMMIT and ROLLBACK are allowed to commit
-	 * and rollback, duh.
-	 *
-	 * @return false 
-	 */	
-	public boolean isAtomic() 
-	{
-		return false;
-	}
-
-	/**
-	 * Returns whether or not this Statement requires a set/clear savepoint
-	 * around its execution.  The following statement "types" do not require them:
-	 *		Cursor	- unnecessary and won't work in a read only environment
-	 *		Xact	- savepoint will get blown away underneath us during commit/rollback
-	 *
-	 * @return boolean	Whether or not this Statement requires a set/clear savepoint
-	 */
-	public boolean needsSavepoint()
-	{
-		return false;
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.sql.compile
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+
+package	org.apache.derby.impl.sql.compile;
+
+import org.apache.derby.iapi.services.context.ContextManager;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+/**
+ * A TransactionStatementNode represents any type of Transaction statement: 
+ * SET TRANSACTION, COMMIT, and ROLLBACK.
+ *
+ * @author Ames Carlson
+ */
+
+public abstract class TransactionStatementNode extends StatementNode
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	int activationKind()
+	{
+		   return StatementNode.NEED_NOTHING_ACTIVATION;
+	}
+	/**
+	 * COMMIT and ROLLBACK are allowed to commit
+	 * and rollback, duh.
+	 *
+	 * @return false 
+	 */	
+	public boolean isAtomic() 
+	{
+		return false;
+	}
+
+	/**
+	 * Returns whether or not this Statement requires a set/clear savepoint
+	 * around its execution.  The following statement "types" do not require them:
+	 *		Cursor	- unnecessary and won't work in a read only environment
+	 *		Xact	- savepoint will get blown away underneath us during commit/rollback
+	 *
+	 * @return boolean	Whether or not this Statement requires a set/clear savepoint
+	 */
+	public boolean needsSavepoint()
+	{
+		return false;
+	}
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ConnectionEnv.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ConnectionEnv.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ConnectionEnv.java	Fri Sep 24 10:33:20 2004
@@ -1,205 +1,205 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-
-import java.util.Hashtable;
-import java.util.Enumeration;
-import java.util.Properties;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-
-import org.apache.derby.tools.JDBCDisplayUtil;
-import org.apache.derby.iapi.tools.i18n.LocalizedOutput;
-
-/**
-	To enable multi-user use of ij.Main2
-
-	@author jerry
- */
-class ConnectionEnv {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	Hashtable sessions = new Hashtable();
-	private Session currSession;
-	private String tag;
-	private boolean only;
-	private static final String CONNECTION_PROPERTY = "ij.connection";
-    private String protocol;
-
-	ConnectionEnv(int userNumber, boolean printUserNumber, boolean theOnly) {
-		if (printUserNumber)
-			tag = "("+(userNumber+1)+")";
-		only = theOnly;
-	}
-
-	/**
-		separate from the constructor so that connection
-		failure does not prevent object creation.
-	 */
-	void init(LocalizedOutput out) throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {
-
-		Connection c = util.startJBMS(null,null);
-
-		// only load up ij.connection.* properties if there is
-		// only one ConnectionEnv in the system.
-		if (only) {
-		    Properties p = System.getProperties();
-		    protocol = p.getProperty(ij.PROTOCOL_PROPERTY);
-
-	        String prefix = CONNECTION_PROPERTY + ".";
-		    for (Enumeration e = p.propertyNames(); e.hasMoreElements(); )
-		    {
-		    	String key = (String)e.nextElement();
-		    	if (key.startsWith(prefix)) {
-		    		String name = key.substring(prefix.length());
-		    		installConnection(name.toUpperCase(java.util.Locale.ENGLISH), 
-						p.getProperty(key), out);
-		    	}
-		    }
-		}
-
-		if (c!=null) // have a database from the startup?
-		{
-			String sname=Session.DEFAULT_NAME+sessions.size();
-			Session s = new Session(c,tag,sname);
-			sessions.put(sname,s);
-			currSession = s;
-		}
-
-	}
-
-	void doPrompt(boolean newStatement, LocalizedOutput out) {
-		if (currSession != null) currSession.doPrompt(newStatement, out, sessions.size()>1);
-		else utilMain.doPrompt(newStatement, out, tag);
-	}
-	
-	Connection getConnection() {
-		if (currSession == null) return null;
-		return currSession.getConnection();
-	}
-
-	/**
-		Making a new connection, add it to the pool, and make it current.
-	 */
-	void addSession(Connection conn,String name) {
-		String aName;
-		if (name == null) aName = getUniqueConnectionName();
-		else aName = name;
-		Session s = new Session(conn, tag, aName);
-		sessions.put(aName, s);
-		currSession = s;
-	}
-
-  //returns a unique Connection# name by going through existing sessions
-  public String getUniqueConnectionName() {
-    int newNum = 0;
-    boolean newConnectionNameOk = false;
-    String newConnectionName = "";
-    Enumeration enum;
-    while (!newConnectionNameOk){
-      newConnectionName = Session.DEFAULT_NAME + newNum;
-      newConnectionNameOk = true;
-      enum = sessions.keys();
-      while (enum.hasMoreElements() && newConnectionNameOk){
-        if (((String)enum.nextElement()).equals(newConnectionName))
-           newConnectionNameOk = false;
-      }
-      newNum = newNum + 1;
-    }
-    return newConnectionName;
-  }
-
-	Session getSession() {
-		return currSession;
-	}
-
-	Hashtable getSessions() {
-		return sessions;
-	}
-
-	Session setCurrentSession(String name) {
-		currSession = (Session) sessions.get(name);
-		return currSession;
-	}
-
-	boolean haveSession(String name) {
-		return (name != null) && (sessions.size()>0) && (null != sessions.get(name));
-	}
-
-	void removeCurrentSession() throws SQLException {
-		if (currSession ==null) return;
-		sessions.remove(currSession.getName());
-		currSession.close();
-		currSession = null;
-	}
-
-	void removeSession(String name) throws SQLException {
-		Session s = (Session) sessions.remove(name);
-		s.close();
-		if (currSession == s)
-			currSession = null;
-	}
-
-	void removeAllSessions() throws SQLException {
-		if (sessions == null || sessions.size() == 0)
-			return;
-		else
-			for (Enumeration e = sessions.keys(); e.hasMoreElements(); ) {
-				String n = (String)e.nextElement();
-				removeSession(n);
-			}
-	}
-
-	private void installConnection(String name, String value, LocalizedOutput out) throws SQLException {
-		// add protocol if no driver matches url
-		boolean noDriver = false;
-		try {
-			// if we have a full URL, make sure it's loaded first
-			try {
-				if (value.startsWith("jdbc:"))
-					util.loadDriverIfKnown(value);
-			} catch (Exception e) {
-				// want to continue with the attempt
-			}
-			DriverManager.getDriver(value);
-		} catch (SQLException se) {
-			noDriver = true;
-		}
-		if (noDriver && (protocol != null)) {
-			value = protocol + value;
-		}
-
-		if (sessions.get(name) != null) {
-			throw ijException.alreadyHaveConnectionNamed(name);
-		}
-		try {
-			
-			String user = util.getSystemProperty("ij.user");
-			String password = util.getSystemProperty("ij.password");
-			Properties connInfo =  util.updateConnInfo(user, password,null);
-														   
-			Connection theConnection = 
-				DriverManager.getConnection(value, connInfo);
-																			   
-		    addSession(theConnection,name);
-		} catch (Throwable t) {
-			JDBCDisplayUtil.ShowException(out,t);
-		}
-	}
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+import org.apache.derby.tools.JDBCDisplayUtil;
+import org.apache.derby.iapi.tools.i18n.LocalizedOutput;
+
+/**
+	To enable multi-user use of ij.Main2
+
+	@author jerry
+ */
+class ConnectionEnv {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	Hashtable sessions = new Hashtable();
+	private Session currSession;
+	private String tag;
+	private boolean only;
+	private static final String CONNECTION_PROPERTY = "ij.connection";
+    private String protocol;
+
+	ConnectionEnv(int userNumber, boolean printUserNumber, boolean theOnly) {
+		if (printUserNumber)
+			tag = "("+(userNumber+1)+")";
+		only = theOnly;
+	}
+
+	/**
+		separate from the constructor so that connection
+		failure does not prevent object creation.
+	 */
+	void init(LocalizedOutput out) throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+		Connection c = util.startJBMS(null,null);
+
+		// only load up ij.connection.* properties if there is
+		// only one ConnectionEnv in the system.
+		if (only) {
+		    Properties p = System.getProperties();
+		    protocol = p.getProperty(ij.PROTOCOL_PROPERTY);
+
+	        String prefix = CONNECTION_PROPERTY + ".";
+		    for (Enumeration e = p.propertyNames(); e.hasMoreElements(); )
+		    {
+		    	String key = (String)e.nextElement();
+		    	if (key.startsWith(prefix)) {
+		    		String name = key.substring(prefix.length());
+		    		installConnection(name.toUpperCase(java.util.Locale.ENGLISH), 
+						p.getProperty(key), out);
+		    	}
+		    }
+		}
+
+		if (c!=null) // have a database from the startup?
+		{
+			String sname=Session.DEFAULT_NAME+sessions.size();
+			Session s = new Session(c,tag,sname);
+			sessions.put(sname,s);
+			currSession = s;
+		}
+
+	}
+
+	void doPrompt(boolean newStatement, LocalizedOutput out) {
+		if (currSession != null) currSession.doPrompt(newStatement, out, sessions.size()>1);
+		else utilMain.doPrompt(newStatement, out, tag);
+	}
+	
+	Connection getConnection() {
+		if (currSession == null) return null;
+		return currSession.getConnection();
+	}
+
+	/**
+		Making a new connection, add it to the pool, and make it current.
+	 */
+	void addSession(Connection conn,String name) {
+		String aName;
+		if (name == null) aName = getUniqueConnectionName();
+		else aName = name;
+		Session s = new Session(conn, tag, aName);
+		sessions.put(aName, s);
+		currSession = s;
+	}
+
+  //returns a unique Connection# name by going through existing sessions
+  public String getUniqueConnectionName() {
+    int newNum = 0;
+    boolean newConnectionNameOk = false;
+    String newConnectionName = "";
+    Enumeration enum;
+    while (!newConnectionNameOk){
+      newConnectionName = Session.DEFAULT_NAME + newNum;
+      newConnectionNameOk = true;
+      enum = sessions.keys();
+      while (enum.hasMoreElements() && newConnectionNameOk){
+        if (((String)enum.nextElement()).equals(newConnectionName))
+           newConnectionNameOk = false;
+      }
+      newNum = newNum + 1;
+    }
+    return newConnectionName;
+  }
+
+	Session getSession() {
+		return currSession;
+	}
+
+	Hashtable getSessions() {
+		return sessions;
+	}
+
+	Session setCurrentSession(String name) {
+		currSession = (Session) sessions.get(name);
+		return currSession;
+	}
+
+	boolean haveSession(String name) {
+		return (name != null) && (sessions.size()>0) && (null != sessions.get(name));
+	}
+
+	void removeCurrentSession() throws SQLException {
+		if (currSession ==null) return;
+		sessions.remove(currSession.getName());
+		currSession.close();
+		currSession = null;
+	}
+
+	void removeSession(String name) throws SQLException {
+		Session s = (Session) sessions.remove(name);
+		s.close();
+		if (currSession == s)
+			currSession = null;
+	}
+
+	void removeAllSessions() throws SQLException {
+		if (sessions == null || sessions.size() == 0)
+			return;
+		else
+			for (Enumeration e = sessions.keys(); e.hasMoreElements(); ) {
+				String n = (String)e.nextElement();
+				removeSession(n);
+			}
+	}
+
+	private void installConnection(String name, String value, LocalizedOutput out) throws SQLException {
+		// add protocol if no driver matches url
+		boolean noDriver = false;
+		try {
+			// if we have a full URL, make sure it's loaded first
+			try {
+				if (value.startsWith("jdbc:"))
+					util.loadDriverIfKnown(value);
+			} catch (Exception e) {
+				// want to continue with the attempt
+			}
+			DriverManager.getDriver(value);
+		} catch (SQLException se) {
+			noDriver = true;
+		}
+		if (noDriver && (protocol != null)) {
+			value = protocol + value;
+		}
+
+		if (sessions.get(name) != null) {
+			throw ijException.alreadyHaveConnectionNamed(name);
+		}
+		try {
+			
+			String user = util.getSystemProperty("ij.user");
+			String password = util.getSystemProperty("ij.password");
+			Properties connInfo =  util.updateConnInfo(user, password,null);
+														   
+			Connection theConnection = 
+				DriverManager.getConnection(value, connInfo);
+																			   
+		    addSession(theConnection,name);
+		} catch (Throwable t) {
+			JDBCDisplayUtil.ShowException(out,t);
+		}
+	}
+
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/Main.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/Main.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/Main.java	Fri Sep 24 10:33:20 2004
@@ -1,252 +1,252 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import org.apache.derby.tools.JDBCDisplayUtil;
-import org.apache.derby.iapi.tools.i18n.LocalizedResource;
-import org.apache.derby.iapi.tools.i18n.LocalizedInput;
-import org.apache.derby.iapi.tools.i18n.LocalizedOutput;
-
-import java.io.FileInputStream;
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.FileOutputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import java.io.IOException;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-
-import java.util.*;
-
-/**
- * This is the controller for ij. It uses two parsers:
- * one to grab the next statement, and another to
- * see if it is an ij command, and if so execute it.
- * If it is not an ij command, it is treated as a JSQL
- * statement and executed against the current connection.
- * ijParser controls the current connection, and so contains
- * all of the state information for executing JSQL statements.
- * <p>
- * This was written to facilitate a test harness for language
- * functionality tests.
- *
- * @author ames
- *
- */
-public class Main {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-	public LocalizedOutput out;
-	public utilMain utilInstance;
-	public Class langUtilClass;
-
-
-
-	/**
-	 * ij can be used directly on a shell command line through
-	 * its main program.
-	 * @param args allows 1 file name to be specified, from which
-	 *    input will be read; if not specified, stdin is used.
-	 */
-	public static void main(String[] args)	
-		throws IOException 
-	{
-		mainCore(args, new Main(true));
-	}
-
-	public static void mainCore(String[] args, Main main)
-		throws IOException 
-	{
-		LocalizedInput in = null;
-		InputStream in1 = null;
-		Main me;
-		String file;
-		String inputResourceName;
-		boolean gotProp;
-
-		String tmpUnicode = null;
-		Properties connAttributeDefaults = null;
-
-		// load the property file if specified
-		gotProp = util.getPropertyArg(args);
-
-		// get the default connection attributes
-		connAttributeDefaults = util.getConnAttributeArg(args);
-		// adjust the application in accordance with derby.ui.locale and derby.ui.codeset
-    main.initAppUI();
-
-		LocalizedResource langUtil = LocalizedResource.getInstance();
-        
-		LocalizedOutput out = langUtil.getNewOutput(System.out);
-
-		file = util.getFileArg(args);
-		inputResourceName = util.getInputResourceNameArg(args);
-		if (util.invalidArgs(args, gotProp, file, inputResourceName)) {
-			util.Usage(out);
-      		return;
-		}
-		else if (inputResourceName != null) {
-			in = langUtil.getNewInput(util.getResourceAsStream(inputResourceName));
-			if (in == null) {
-				out.println(langUtil.getTextMessage("IJ_IjErroResoNo",inputResourceName));
-				return;
-			}
-		} else if (file == null) {
-			in = langUtil.getNewInput(System.in);
-            out.flush();
-    	} else {
-      		try {
-				in1 = new FileInputStream(file);
-				if (in1 != null) {
-                    in1 = new BufferedInputStream(in1, utilMain.BUFFEREDFILESIZE);
-					in = langUtil.getNewInput(in1);
-                }
-      		} catch (FileNotFoundException e) {
-				if (Boolean.getBoolean("ij.searchClassPath")) {
-					in = langUtil.getNewInput(util.getResourceAsStream(file));
-                }
-				if (in == null) {
-				  out.println(langUtil.getTextMessage("IJ_IjErroFileNo",file));
-        		  return;
-				}
-      		}
-    	}
-
-		// set initial Unicode Escape Mode
-		tmpUnicode = util.getSystemProperty("ij.unicodeEscape");
-		if ((tmpUnicode != null) && tmpUnicode.toUpperCase(Locale.ENGLISH).equals("ON")) {
-			LocalizedResource.setUnicodeEscape(true);
-		} 
-		String outFile = util.getSystemProperty("ij.outfile");
-		if (outFile != null && outFile.length()>0) {
-			LocalizedOutput oldOut = out;
-			try {
-				out = langUtil.getNewOutput(new FileOutputStream(outFile));
-			}
-			catch (IOException ioe) {
-				oldOut.println(langUtil.getTextMessage("IJ_IjErroUnabTo",outFile));
-			}
-		}
-
-		// the old property name is deprecated...
-		String maxDisplayWidth = util.getSystemProperty("maximumDisplayWidth");
-		if (maxDisplayWidth==null) 
-			maxDisplayWidth = util.getSystemProperty("ij.maximumDisplayWidth");
-		if (maxDisplayWidth != null && maxDisplayWidth.length() > 0) {
-			try {
-				int maxWidth = Integer.parseInt(maxDisplayWidth);
-				JDBCDisplayUtil.setMaxDisplayWidth(maxWidth);
-			}
-			catch (NumberFormatException nfe) {
-				out.println(langUtil.getTextMessage("IJ_IjErroMaxiVa", maxDisplayWidth));
-			}
-		}
-
-		/* Use the main parameter to get to
-		 * a new Main that we can use.  
-		 * (We can't do the work in Main(out)
-		 * until after we do all of the work above
-		 * us in this method.
-		 */
-		me = main.getMain(out);
-
-		/* Let the processing begin! */
-		me.go(in, out, connAttributeDefaults);
-		in.close(); out.close();
-	}
-
-	/**
-	 * Get the right Main (according to 
-	 * the JDBC version.
-	 *
-	 * @return	The right main (according to the JDBC version).
-	 */
-	public Main getMain(LocalizedOutput out)
-	{
-		return new Main(out);
-	}
-
-	/**
-	 * Get the right utilMain (according to 
-	 * the JDBC version.
-	 *
-	 * @return	The right utilMain (according to the JDBC version).
-	 */
-	public utilMain getutilMain(int numConnections, LocalizedOutput out)
-	{
-		return new utilMain(numConnections, out);
-	}
-
-	/**
-		Give a shortcut to go on the utilInstance so
-		we don't expose utilMain.
-	 */
-	public void go(LocalizedInput in, LocalizedOutput out , 
-				   Properties connAttributeDefaults)
-	{
-		LocalizedInput[] inA = { in } ;
-		utilInstance.go(inA, out,connAttributeDefaults);
-	}
-
-	public void go(InputStream in, PrintStream out, 
-				   Properties connAttributeDefaults)
-	{
-    initAppUI();
-    	LocalizedResource langUtil = LocalizedResource.getInstance();
-		go(langUtil.getNewInput(in), langUtil.getNewOutput(out),
-			   connAttributeDefaults);
-	}
-
-	/**
-	 * create an ij tool waiting to be given input and output streams.
-	 */
-	public Main() {
-		this(null);
-	}
-
-	public Main(LocalizedOutput out) {
-		if (out!=null) {
-			this.out = out;
-		} else {
-	        this.out = LocalizedResource.getInstance().getNewOutput(System.out);
-		}
-		utilInstance = getutilMain(1, this.out);
-	}
-
-	/**
-	 * This constructor is only used so that we 
-	 * can get to the right Main based on the
-	 * JDBC version.  We don't do any work in
-	 * this constructor and we only use this
-	 * object to get to the right Main via
-	 * getMain().
-	 */
-	public Main(boolean trash)
-	{
-	}
-  public void initAppUI(){
-    //To fix a problem in the AppUI implementation, a reference to the AppUI class is
-    //maintained by this tool.  Without this reference, it is possible for the
-    //AppUI class to be garbage collected and the initialization values lost.
-    //langUtilClass = LocalizedResource.class;
-
-		// adjust the application in accordance with derby.ui.locale and derby.ui.codeset
-	LocalizedResource.getInstance();	
-  }
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import org.apache.derby.tools.JDBCDisplayUtil;
+import org.apache.derby.iapi.tools.i18n.LocalizedResource;
+import org.apache.derby.iapi.tools.i18n.LocalizedInput;
+import org.apache.derby.iapi.tools.i18n.LocalizedOutput;
+
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.io.IOException;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+import java.util.*;
+
+/**
+ * This is the controller for ij. It uses two parsers:
+ * one to grab the next statement, and another to
+ * see if it is an ij command, and if so execute it.
+ * If it is not an ij command, it is treated as a JSQL
+ * statement and executed against the current connection.
+ * ijParser controls the current connection, and so contains
+ * all of the state information for executing JSQL statements.
+ * <p>
+ * This was written to facilitate a test harness for language
+ * functionality tests.
+ *
+ * @author ames
+ *
+ */
+public class Main {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+	public LocalizedOutput out;
+	public utilMain utilInstance;
+	public Class langUtilClass;
+
+
+
+	/**
+	 * ij can be used directly on a shell command line through
+	 * its main program.
+	 * @param args allows 1 file name to be specified, from which
+	 *    input will be read; if not specified, stdin is used.
+	 */
+	public static void main(String[] args)	
+		throws IOException 
+	{
+		mainCore(args, new Main(true));
+	}
+
+	public static void mainCore(String[] args, Main main)
+		throws IOException 
+	{
+		LocalizedInput in = null;
+		InputStream in1 = null;
+		Main me;
+		String file;
+		String inputResourceName;
+		boolean gotProp;
+
+		String tmpUnicode = null;
+		Properties connAttributeDefaults = null;
+
+		// load the property file if specified
+		gotProp = util.getPropertyArg(args);
+
+		// get the default connection attributes
+		connAttributeDefaults = util.getConnAttributeArg(args);
+		// adjust the application in accordance with derby.ui.locale and derby.ui.codeset
+    main.initAppUI();
+
+		LocalizedResource langUtil = LocalizedResource.getInstance();
+        
+		LocalizedOutput out = langUtil.getNewOutput(System.out);
+
+		file = util.getFileArg(args);
+		inputResourceName = util.getInputResourceNameArg(args);
+		if (util.invalidArgs(args, gotProp, file, inputResourceName)) {
+			util.Usage(out);
+      		return;
+		}
+		else if (inputResourceName != null) {
+			in = langUtil.getNewInput(util.getResourceAsStream(inputResourceName));
+			if (in == null) {
+				out.println(langUtil.getTextMessage("IJ_IjErroResoNo",inputResourceName));
+				return;
+			}
+		} else if (file == null) {
+			in = langUtil.getNewInput(System.in);
+            out.flush();
+    	} else {
+      		try {
+				in1 = new FileInputStream(file);
+				if (in1 != null) {
+                    in1 = new BufferedInputStream(in1, utilMain.BUFFEREDFILESIZE);
+					in = langUtil.getNewInput(in1);
+                }
+      		} catch (FileNotFoundException e) {
+				if (Boolean.getBoolean("ij.searchClassPath")) {
+					in = langUtil.getNewInput(util.getResourceAsStream(file));
+                }
+				if (in == null) {
+				  out.println(langUtil.getTextMessage("IJ_IjErroFileNo",file));
+        		  return;
+				}
+      		}
+    	}
+
+		// set initial Unicode Escape Mode
+		tmpUnicode = util.getSystemProperty("ij.unicodeEscape");
+		if ((tmpUnicode != null) && tmpUnicode.toUpperCase(Locale.ENGLISH).equals("ON")) {
+			LocalizedResource.setUnicodeEscape(true);
+		} 
+		String outFile = util.getSystemProperty("ij.outfile");
+		if (outFile != null && outFile.length()>0) {
+			LocalizedOutput oldOut = out;
+			try {
+				out = langUtil.getNewOutput(new FileOutputStream(outFile));
+			}
+			catch (IOException ioe) {
+				oldOut.println(langUtil.getTextMessage("IJ_IjErroUnabTo",outFile));
+			}
+		}
+
+		// the old property name is deprecated...
+		String maxDisplayWidth = util.getSystemProperty("maximumDisplayWidth");
+		if (maxDisplayWidth==null) 
+			maxDisplayWidth = util.getSystemProperty("ij.maximumDisplayWidth");
+		if (maxDisplayWidth != null && maxDisplayWidth.length() > 0) {
+			try {
+				int maxWidth = Integer.parseInt(maxDisplayWidth);
+				JDBCDisplayUtil.setMaxDisplayWidth(maxWidth);
+			}
+			catch (NumberFormatException nfe) {
+				out.println(langUtil.getTextMessage("IJ_IjErroMaxiVa", maxDisplayWidth));
+			}
+		}
+
+		/* Use the main parameter to get to
+		 * a new Main that we can use.  
+		 * (We can't do the work in Main(out)
+		 * until after we do all of the work above
+		 * us in this method.
+		 */
+		me = main.getMain(out);
+
+		/* Let the processing begin! */
+		me.go(in, out, connAttributeDefaults);
+		in.close(); out.close();
+	}
+
+	/**
+	 * Get the right Main (according to 
+	 * the JDBC version.
+	 *
+	 * @return	The right main (according to the JDBC version).
+	 */
+	public Main getMain(LocalizedOutput out)
+	{
+		return new Main(out);
+	}
+
+	/**
+	 * Get the right utilMain (according to 
+	 * the JDBC version.
+	 *
+	 * @return	The right utilMain (according to the JDBC version).
+	 */
+	public utilMain getutilMain(int numConnections, LocalizedOutput out)
+	{
+		return new utilMain(numConnections, out);
+	}
+
+	/**
+		Give a shortcut to go on the utilInstance so
+		we don't expose utilMain.
+	 */
+	public void go(LocalizedInput in, LocalizedOutput out , 
+				   Properties connAttributeDefaults)
+	{
+		LocalizedInput[] inA = { in } ;
+		utilInstance.go(inA, out,connAttributeDefaults);
+	}
+
+	public void go(InputStream in, PrintStream out, 
+				   Properties connAttributeDefaults)
+	{
+    initAppUI();
+    	LocalizedResource langUtil = LocalizedResource.getInstance();
+		go(langUtil.getNewInput(in), langUtil.getNewOutput(out),
+			   connAttributeDefaults);
+	}
+
+	/**
+	 * create an ij tool waiting to be given input and output streams.
+	 */
+	public Main() {
+		this(null);
+	}
+
+	public Main(LocalizedOutput out) {
+		if (out!=null) {
+			this.out = out;
+		} else {
+	        this.out = LocalizedResource.getInstance().getNewOutput(System.out);
+		}
+		utilInstance = getutilMain(1, this.out);
+	}
+
+	/**
+	 * This constructor is only used so that we 
+	 * can get to the right Main based on the
+	 * JDBC version.  We don't do any work in
+	 * this constructor and we only use this
+	 * object to get to the right Main via
+	 * getMain().
+	 */
+	public Main(boolean trash)
+	{
+	}
+  public void initAppUI(){
+    //To fix a problem in the AppUI implementation, a reference to the AppUI class is
+    //maintained by this tool.  Without this reference, it is possible for the
+    //AppUI class to be garbage collected and the initialization values lost.
+    //langUtilClass = LocalizedResource.class;
+
+		// adjust the application in accordance with derby.ui.locale and derby.ui.codeset
+	LocalizedResource.getInstance();	
+  }
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/Main14.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/Main14.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/Main14.java	Fri Sep 24 10:33:20 2004
@@ -1,100 +1,100 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 2002, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import org.apache.derby.tools.JDBCDisplayUtil;
-
-
-import java.io.BufferedInputStream;
-import java.io.FileOutputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.io.IOException;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-
-import org.apache.derby.iapi.tools.i18n.LocalizedOutput;
-/**
- * This is the controller for the JDBC3.0 version
- * of ij.
- * <p>
- * This was written to facilitate a test harness for the
- * holding cursors over commit functionality in JDBC3.0.
- *
- */
-public class Main14 extends Main
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2002_2004;
-	/**
-	 * ij can be used directly on a shell command line through
-	 * its main program.
-	 * @param args allows 1 file name to be specified, from which
-	 *    input will be read; if not specified, stdin is used.
-	 */
-	public static void main(String[] args)	throws IOException 
-	{
-		Main.mainCore(args, new Main14(true));
-	}
-
-	/**
-	 * create an ij tool waiting to be given input and output streams.
-	 */
-	public Main14() 
-	{
-		this(null);
-	}
-
-	public Main14(LocalizedOutput out) 
-	{
-		super(out);
-	}
-
-	/**
-	 * This constructor is only used so that we 
-	 * can get to the right Main based on the
-	 * JDBC version.  We don't do any work in
-	 * this constructor and we only use this
-	 * object to get to the right Main via
-	 * getMain().
-	 */
-	public Main14(boolean trash)
-	{
-		super(trash);
-	}
-	/**
-	 * Get the right Main (according to 
-	 * the JDBC version.
-	 *
-	 * @return	The right Main (according to the JDBC version).
-	 */
-	public Main getMain(LocalizedOutput out)
-	{
-		return new Main14(out);
-	}
-
-	/**
-	 * Get the right utilMain (according to 
-	 * the JDBC version.
-	 *
-	 * @return	The right utilMain (according to the JDBC version).
-	 */
-	public utilMain getutilMain(int numConnections, LocalizedOutput out)
-	{
-		return new utilMain14(numConnections, out);
-	}
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 2002, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import org.apache.derby.tools.JDBCDisplayUtil;
+
+
+import java.io.BufferedInputStream;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.IOException;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+import org.apache.derby.iapi.tools.i18n.LocalizedOutput;
+/**
+ * This is the controller for the JDBC3.0 version
+ * of ij.
+ * <p>
+ * This was written to facilitate a test harness for the
+ * holding cursors over commit functionality in JDBC3.0.
+ *
+ */
+public class Main14 extends Main
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2002_2004;
+	/**
+	 * ij can be used directly on a shell command line through
+	 * its main program.
+	 * @param args allows 1 file name to be specified, from which
+	 *    input will be read; if not specified, stdin is used.
+	 */
+	public static void main(String[] args)	throws IOException 
+	{
+		Main.mainCore(args, new Main14(true));
+	}
+
+	/**
+	 * create an ij tool waiting to be given input and output streams.
+	 */
+	public Main14() 
+	{
+		this(null);
+	}
+
+	public Main14(LocalizedOutput out) 
+	{
+		super(out);
+	}
+
+	/**
+	 * This constructor is only used so that we 
+	 * can get to the right Main based on the
+	 * JDBC version.  We don't do any work in
+	 * this constructor and we only use this
+	 * object to get to the right Main via
+	 * getMain().
+	 */
+	public Main14(boolean trash)
+	{
+		super(trash);
+	}
+	/**
+	 * Get the right Main (according to 
+	 * the JDBC version.
+	 *
+	 * @return	The right Main (according to the JDBC version).
+	 */
+	public Main getMain(LocalizedOutput out)
+	{
+		return new Main14(out);
+	}
+
+	/**
+	 * Get the right utilMain (according to 
+	 * the JDBC version.
+	 *
+	 * @return	The right utilMain (according to the JDBC version).
+	 */
+	public utilMain getutilMain(int numConnections, LocalizedOutput out)
+	{
+		return new utilMain14(numConnections, out);
+	}
+
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ParseException.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ParseException.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ParseException.java	Fri Sep 24 10:33:20 2004
@@ -1,208 +1,208 @@
-/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-package org.apache.derby.impl.tools.ij;
-
-/**
- * This exception is thrown when parse errors are encountered.
- * You can explicitly create objects of this exception type by
- * calling the method generateParseException in the generated
- * parser.
- *
- * You can modify this class to customize your error reporting
- * mechanisms so long as you retain the public fields.
- */
-public class ParseException extends Exception {
-  /**
-			IBM Copyright &copy notice.
-   */
-  public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-  /**
-   * This constructor is used by the method "generateParseException"
-   * in the generated parser.  Calling this constructor generates
-   * a new object of this type with the fields "currentToken",
-   * "expectedTokenSequences", and "tokenImage" set.  The boolean
-   * flag "specialConstructor" is also set to true to indicate that
-   * this constructor was used to create this object.
-   * This constructor calls its super class with the empty string
-   * to force the "toString" method of parent class "Throwable" to
-   * print the error message in the form:
-   *     ParseException: <result of getMessage>
-   */
-  public ParseException(Token currentTokenVal,
-                        int[][] expectedTokenSequencesVal,
-                        String[] tokenImageVal
-                       )
-  {
-    super("");
-    specialConstructor = true;
-    currentToken = currentTokenVal;
-    expectedTokenSequences = expectedTokenSequencesVal;
-    tokenImage = tokenImageVal;
-  }
-
-  /**
-   * The following constructors are for use by you for whatever
-   * purpose you can think of.  Constructing the exception in this
-   * manner makes the exception behave in the normal way - i.e., as
-   * documented in the class "Throwable".  The fields "errorToken",
-   * "expectedTokenSequences", and "tokenImage" do not contain
-   * relevant information.  The JavaCC generated code does not use
-   * these constructors.
-   */
-
-  public ParseException() {
-    super();
-    specialConstructor = false;
-  }
-
-  public ParseException(String message) {
-    super(message);
-    specialConstructor = false;
-  }
-
-  /**
-   * This variable determines which constructor was used to create
-   * this object and thereby affects the semantics of the
-   * "getMessage" method (see below).
-   */
-  protected boolean specialConstructor;
-
-  /**
-   * This is the last token that has been consumed successfully.  If
-   * this object has been created due to a parse error, the token
-   * followng this token will (therefore) be the first error token.
-   */
-  public Token currentToken;
-
-  /**
-   * Each entry in this array is an array of integers.  Each array
-   * of integers represents a sequence of tokens (by their ordinal
-   * values) that is expected at this point of the parse.
-   */
-  public int[][] expectedTokenSequences;
-
-  /**
-   * This is a reference to the "tokenImage" array of the generated
-   * parser within which the parse error occurred.  This array is
-   * defined in the generated ...Constants interface.
-   */
-  public String[] tokenImage;
-
-  /**
-   * This method has the standard behavior when this object has been
-   * created using the standard constructors.  Otherwise, it uses
-   * "currentToken" and "expectedTokenSequences" to generate a parse
-   * error message and returns it.  If this object has been created
-   * due to a parse error, and you do not catch it (it gets thrown
-   * from the parser), then this method is called during the printing
-   * of the final stack trace, and hence the correct error message
-   * gets displayed.
-   */
-  public String getMessage() {
-    if (!specialConstructor) {
-      return super.getMessage();
-    }
-    String expected = "";
-    int maxSize = 0;
-    for (int i = 0; i < expectedTokenSequences.length; i++) {
-      if (maxSize < expectedTokenSequences[i].length) {
-        maxSize = expectedTokenSequences[i].length;
-      }
-      for (int j = 0; j < expectedTokenSequences[i].length; j++) {
-        expected += tokenImage[expectedTokenSequences[i][j]] + " ";
-      }
-      if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
-        expected += "...";
-      }
-      expected += eol + "    ";
-    }
-    String retval = "Encountered \"";
-    Token tok = currentToken.next;
-    for (int i = 0; i < maxSize; i++) {
-      if (i != 0) retval += " ";
-      if (tok.kind == 0) {
-        retval += tokenImage[0];
-        break;
-      }
-      retval += add_escapes(tok.image);
-      tok = tok.next;
-    }
-    retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
- /*
-  * for output compatibility with previous releases, do not report expected tokens.
-  *
-    retval += "." + eol;
-    if (expectedTokenSequences.length == 1) {
-      retval += "Was expecting:" + eol + "    ";
-    } else {
-      retval += "Was expecting one of:" + eol + "    ";
-    }
-    retval += expected;
-  */
-    return retval;
-  }
-
-  /**
-   * The end of line string for this machine.
-   */
-  protected String eol = System.getProperty("line.separator", "\n");
-
-  /**
-   * Used to convert raw characters to their escaped version
-   * when these raw version cannot be used as part of an ASCII
-   * string literal.
-   */
-  protected String add_escapes(String str) {
-      StringBuffer retval = new StringBuffer();
-      char ch;
-      for (int i = 0; i < str.length(); i++) {
-        switch (str.charAt(i))
-        {
-           case 0 :
-              continue;
-           case '\b':
-              retval.append("\\b");
-              continue;
-           case '\t':
-              retval.append("\\t");
-              continue;
-           case '\n':
-              retval.append("\\n");
-              continue;
-           case '\f':
-              retval.append("\\f");
-              continue;
-           case '\r':
-              retval.append("\\r");
-              continue;
-           case '\"':
-              retval.append("\\\"");
-              continue;
-           case '\'':
-              retval.append("\\\'");
-              continue;
-           case '\\':
-              retval.append("\\\\");
-              continue;
-           default:
-              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
-                 String s = "0000" + Integer.toString(ch, 16);
-                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
-              } else {
-                 retval.append(ch);
-              }
-              continue;
-        }
-      }
-      return retval.toString();
-   }
-
-}
+/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+package org.apache.derby.impl.tools.ij;
+
+/**
+ * This exception is thrown when parse errors are encountered.
+ * You can explicitly create objects of this exception type by
+ * calling the method generateParseException in the generated
+ * parser.
+ *
+ * You can modify this class to customize your error reporting
+ * mechanisms so long as you retain the public fields.
+ */
+public class ParseException extends Exception {
+  /**
+			IBM Copyright &copy notice.
+   */
+  public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+  /**
+   * This constructor is used by the method "generateParseException"
+   * in the generated parser.  Calling this constructor generates
+   * a new object of this type with the fields "currentToken",
+   * "expectedTokenSequences", and "tokenImage" set.  The boolean
+   * flag "specialConstructor" is also set to true to indicate that
+   * this constructor was used to create this object.
+   * This constructor calls its super class with the empty string
+   * to force the "toString" method of parent class "Throwable" to
+   * print the error message in the form:
+   *     ParseException: <result of getMessage>
+   */
+  public ParseException(Token currentTokenVal,
+                        int[][] expectedTokenSequencesVal,
+                        String[] tokenImageVal
+                       )
+  {
+    super("");
+    specialConstructor = true;
+    currentToken = currentTokenVal;
+    expectedTokenSequences = expectedTokenSequencesVal;
+    tokenImage = tokenImageVal;
+  }
+
+  /**
+   * The following constructors are for use by you for whatever
+   * purpose you can think of.  Constructing the exception in this
+   * manner makes the exception behave in the normal way - i.e., as
+   * documented in the class "Throwable".  The fields "errorToken",
+   * "expectedTokenSequences", and "tokenImage" do not contain
+   * relevant information.  The JavaCC generated code does not use
+   * these constructors.
+   */
+
+  public ParseException() {
+    super();
+    specialConstructor = false;
+  }
+
+  public ParseException(String message) {
+    super(message);
+    specialConstructor = false;
+  }
+
+  /**
+   * This variable determines which constructor was used to create
+   * this object and thereby affects the semantics of the
+   * "getMessage" method (see below).
+   */
+  protected boolean specialConstructor;
+
+  /**
+   * This is the last token that has been consumed successfully.  If
+   * this object has been created due to a parse error, the token
+   * followng this token will (therefore) be the first error token.
+   */
+  public Token currentToken;
+
+  /**
+   * Each entry in this array is an array of integers.  Each array
+   * of integers represents a sequence of tokens (by their ordinal
+   * values) that is expected at this point of the parse.
+   */
+  public int[][] expectedTokenSequences;
+
+  /**
+   * This is a reference to the "tokenImage" array of the generated
+   * parser within which the parse error occurred.  This array is
+   * defined in the generated ...Constants interface.
+   */
+  public String[] tokenImage;
+
+  /**
+   * This method has the standard behavior when this object has been
+   * created using the standard constructors.  Otherwise, it uses
+   * "currentToken" and "expectedTokenSequences" to generate a parse
+   * error message and returns it.  If this object has been created
+   * due to a parse error, and you do not catch it (it gets thrown
+   * from the parser), then this method is called during the printing
+   * of the final stack trace, and hence the correct error message
+   * gets displayed.
+   */
+  public String getMessage() {
+    if (!specialConstructor) {
+      return super.getMessage();
+    }
+    String expected = "";
+    int maxSize = 0;
+    for (int i = 0; i < expectedTokenSequences.length; i++) {
+      if (maxSize < expectedTokenSequences[i].length) {
+        maxSize = expectedTokenSequences[i].length;
+      }
+      for (int j = 0; j < expectedTokenSequences[i].length; j++) {
+        expected += tokenImage[expectedTokenSequences[i][j]] + " ";
+      }
+      if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
+        expected += "...";
+      }
+      expected += eol + "    ";
+    }
+    String retval = "Encountered \"";
+    Token tok = currentToken.next;
+    for (int i = 0; i < maxSize; i++) {
+      if (i != 0) retval += " ";
+      if (tok.kind == 0) {
+        retval += tokenImage[0];
+        break;
+      }
+      retval += add_escapes(tok.image);
+      tok = tok.next;
+    }
+    retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
+ /*
+  * for output compatibility with previous releases, do not report expected tokens.
+  *
+    retval += "." + eol;
+    if (expectedTokenSequences.length == 1) {
+      retval += "Was expecting:" + eol + "    ";
+    } else {
+      retval += "Was expecting one of:" + eol + "    ";
+    }
+    retval += expected;
+  */
+    return retval;
+  }
+
+  /**
+   * The end of line string for this machine.
+   */
+  protected String eol = System.getProperty("line.separator", "\n");
+
+  /**
+   * Used to convert raw characters to their escaped version
+   * when these raw version cannot be used as part of an ASCII
+   * string literal.
+   */
+  protected String add_escapes(String str) {
+      StringBuffer retval = new StringBuffer();
+      char ch;
+      for (int i = 0; i < str.length(); i++) {
+        switch (str.charAt(i))
+        {
+           case 0 :
+              continue;
+           case '\b':
+              retval.append("\\b");
+              continue;
+           case '\t':
+              retval.append("\\t");
+              continue;
+           case '\n':
+              retval.append("\\n");
+              continue;
+           case '\f':
+              retval.append("\\f");
+              continue;
+           case '\r':
+              retval.append("\\r");
+              continue;
+           case '\"':
+              retval.append("\\\"");
+              continue;
+           case '\'':
+              retval.append("\\\'");
+              continue;
+           case '\\':
+              retval.append("\\\\");
+              continue;
+           default:
+              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+                 String s = "0000" + Integer.toString(ch, 16);
+                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+              } else {
+                 retval.append(ch);
+              }
+              continue;
+        }
+      }
+      return retval.toString();
+   }
+
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/Session.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/Session.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/Session.java	Fri Sep 24 10:33:20 2004
@@ -1,161 +1,161 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import org.apache.derby.iapi.tools.i18n.LocalizedOutput;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.Statement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Hashtable;
-
-/**
-	Session holds the objects local to a particular database session,
-	which starts with a connection and is all other JDBC
-	stuff used on that connection, along with some ij state
-	that is connection-based as well.
-
-	This is separated out to localize database objects and
-	also group objects by session.
-
-	@author ames
- */
-class Session {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-	static final String DEFAULT_NAME="CONNECTION";
-
-	boolean singleSession = true;
-	Connection conn = null;
-	String tag, name;
-	Hashtable prepStmts = new Hashtable();
-	Hashtable cursorStmts = new Hashtable();
-	Hashtable cursors = new Hashtable();
-	Hashtable asyncStmts = new Hashtable();
-	boolean isJCC= false;      // Is this the IBM UNIVERSAL DRIVER.
-
-	Session(Connection newConn, String newTag, String newName) {
-		conn = newConn;
-		tag = newTag;
-		name = newName;
-
-		try
-		{
-			isJCC = conn.getMetaData().getDriverName().startsWith("IBM DB2 JDBC Universal Driver");
-		}
-		catch (SQLException se)
-		{
-			// if there is a problem getting the driver name we will 
-			// assume it is not jcc.
-		}
-	}
-
-	Connection getConnection() {
-		// CHECK: should never be null
-		return conn;
-	}
-
-	boolean getIsJCC()
-	{
-		return isJCC;
-	}
-
-	String getName() {
-		return name;
-	}
-
-	Object addPreparedStatement(String name, PreparedStatement ps) {
-		return prepStmts.put(name,ps);
-	}
-
-	Object addCursorStatement(String name, Statement s) {
-		return cursorStmts.put(name, s);
-	}
-
-	Object addCursor(String name, ResultSet rs) {
-		return cursors.put(name, rs);
-	}
-
-	Object addAsyncStatement(String name, AsyncStatement s) {
-		return asyncStmts.put(name, s);
-	}
-
-	PreparedStatement getPreparedStatement(String name) {
-		return (PreparedStatement) prepStmts.get(name);
-	}
-
-	Statement getCursorStatement(String name) {
-		return (Statement)cursorStmts.get(name);
-	}
-
-	ResultSet getCursor(String name) {
-		return (ResultSet)cursors.get(name);
-	}
-
-	AsyncStatement getAsyncStatement(String name) {
-		return (AsyncStatement)asyncStmts.get(name);
-	}
-
-	boolean removePreparedStatement(String name) {
-		return prepStmts.remove(name)!=null;
-	}
-
-	boolean removeCursorStatement(String name) {
-		return cursorStmts.remove(name)!=null;
-	}
-
-	boolean removeCursor(String name) {
-		return cursors.remove(name)!=null;
-	}
-
-    void doPrompt(boolean newStatement, LocalizedOutput out, boolean multiSessions) {
-		// check if tag should be increased...
-		if (multiSessions && singleSession) {
-			singleSession = false;
-
-			if (tag == null) tag = "("+name+")";
-			else tag = tag.substring(0,tag.length()-1)+":"+name+")";
-		}
-
-		// check if tag should be reduced...
-		if (!multiSessions && !singleSession) {
-			singleSession = true;
-
-			if (tag == null) {}
-			else if (tag.length() == name.length()+2) tag = null;
-			else tag = tag.substring(0,tag.length()-2-name.length())+")";
-		}
-
-		utilMain.doPrompt(newStatement, out, tag);
-	}
-
-	void close() throws SQLException {
-
-		if (!conn.isClosed())
-		{
-			if  (!conn.getAutoCommit() && name != null && ! name.startsWith("XA"))
-				conn.rollback();
-			conn.close();
-		}
-
-		prepStmts.clear(); // should we check & close them individually?
-		cursorStmts.clear();
-		cursors.clear();
-		asyncStmts.clear();
-
-		conn = null;
-	}
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import org.apache.derby.iapi.tools.i18n.LocalizedOutput;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.Statement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Hashtable;
+
+/**
+	Session holds the objects local to a particular database session,
+	which starts with a connection and is all other JDBC
+	stuff used on that connection, along with some ij state
+	that is connection-based as well.
+
+	This is separated out to localize database objects and
+	also group objects by session.
+
+	@author ames
+ */
+class Session {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+	static final String DEFAULT_NAME="CONNECTION";
+
+	boolean singleSession = true;
+	Connection conn = null;
+	String tag, name;
+	Hashtable prepStmts = new Hashtable();
+	Hashtable cursorStmts = new Hashtable();
+	Hashtable cursors = new Hashtable();
+	Hashtable asyncStmts = new Hashtable();
+	boolean isJCC= false;      // Is this the IBM UNIVERSAL DRIVER.
+
+	Session(Connection newConn, String newTag, String newName) {
+		conn = newConn;
+		tag = newTag;
+		name = newName;
+
+		try
+		{
+			isJCC = conn.getMetaData().getDriverName().startsWith("IBM DB2 JDBC Universal Driver");
+		}
+		catch (SQLException se)
+		{
+			// if there is a problem getting the driver name we will 
+			// assume it is not jcc.
+		}
+	}
+
+	Connection getConnection() {
+		// CHECK: should never be null
+		return conn;
+	}
+
+	boolean getIsJCC()
+	{
+		return isJCC;
+	}
+
+	String getName() {
+		return name;
+	}
+
+	Object addPreparedStatement(String name, PreparedStatement ps) {
+		return prepStmts.put(name,ps);
+	}
+
+	Object addCursorStatement(String name, Statement s) {
+		return cursorStmts.put(name, s);
+	}
+
+	Object addCursor(String name, ResultSet rs) {
+		return cursors.put(name, rs);
+	}
+
+	Object addAsyncStatement(String name, AsyncStatement s) {
+		return asyncStmts.put(name, s);
+	}
+
+	PreparedStatement getPreparedStatement(String name) {
+		return (PreparedStatement) prepStmts.get(name);
+	}
+
+	Statement getCursorStatement(String name) {
+		return (Statement)cursorStmts.get(name);
+	}
+
+	ResultSet getCursor(String name) {
+		return (ResultSet)cursors.get(name);
+	}
+
+	AsyncStatement getAsyncStatement(String name) {
+		return (AsyncStatement)asyncStmts.get(name);
+	}
+
+	boolean removePreparedStatement(String name) {
+		return prepStmts.remove(name)!=null;
+	}
+
+	boolean removeCursorStatement(String name) {
+		return cursorStmts.remove(name)!=null;
+	}
+
+	boolean removeCursor(String name) {
+		return cursors.remove(name)!=null;
+	}
+
+    void doPrompt(boolean newStatement, LocalizedOutput out, boolean multiSessions) {
+		// check if tag should be increased...
+		if (multiSessions && singleSession) {
+			singleSession = false;
+
+			if (tag == null) tag = "("+name+")";
+			else tag = tag.substring(0,tag.length()-1)+":"+name+")";
+		}
+
+		// check if tag should be reduced...
+		if (!multiSessions && !singleSession) {
+			singleSession = true;
+
+			if (tag == null) {}
+			else if (tag.length() == name.length()+2) tag = null;
+			else tag = tag.substring(0,tag.length()-2-name.length())+")";
+		}
+
+		utilMain.doPrompt(newStatement, out, tag);
+	}
+
+	void close() throws SQLException {
+
+		if (!conn.isClosed())
+		{
+			if  (!conn.getAutoCommit() && name != null && ! name.startsWith("XA"))
+				conn.rollback();
+			conn.close();
+		}
+
+		prepStmts.clear(); // should we check & close them individually?
+		cursorStmts.clear();
+		cursors.clear();
+		asyncStmts.clear();
+
+		conn = null;
+	}
+
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/StatementFinder.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/StatementFinder.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/StatementFinder.java	Fri Sep 24 10:33:20 2004
@@ -1,318 +1,318 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import java.io.IOException;
-import java.io.Reader;
-
-/**
-	StatementGrabber looks through an input stream for
-	the next JSQL statement.  A statement is considered to
-	be any tokens up to the next semicolon or EOF.
-	<p>
-	Semicolons inside comments, strings, and delimited identifiers
-	are not considered to be statement terminators but to be
-	part of those tokens.
-	<p>
-	The only comment form currently recognized is the SQL comment,
-	which begins with "--" and ends at the next EOL.
-	<p>
-	Strings and delimited identifiers are permitted to contain
-	newlines; the actual IJ or JSQL parsers will report errors when
-	those cases occur.
-	<p>
-	There are no escaped characters, i.e. "\n" is considered to
-	be two characters, '\' and 'n'.
-
-	@author ames
- */
-
-public class StatementFinder {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-
-	private Reader source; 
-	private StringBuffer statement = new StringBuffer();
-	private int state;
-	private boolean atEOF = false;
-	private boolean peekEOF = false;
-	private char peekChar;
-	private boolean peeked = false;
-
-	// state variables
-	private static final int IN_STATEMENT = 0;
-	private static final int IN_STRING = 1;
-	private static final int IN_SQLCOMMENT = 2;
-	private static final int END_OF_STATEMENT = 3;
-	private static final int END_OF_INPUT = 4;
-
-	// special state-changing characters
-	private static final char MINUS = '-';
-	private static final char SINGLEQUOTE = '\'';
-	private static final char DOUBLEQUOTE = '\"';
-	private static final char SEMICOLON = ';';
-	private static final char NEWLINE = '\n';
-	private static final char RETURN = '\r';
-	private static final char SPACE = ' ';
-	private static final char TAB = '\t';
-	private static final char FORMFEED = '\f';
-
-	/**
-		The constructor does not assume the stream is data input
-		or buffered, so it will wrap it appropriately.
-
-		@param s the input stream for reading statements from.
-	 */
-	public StatementFinder(Reader s) { 
-		source = s;
-	}
-
-	/**
-		Reinit is used to redirect the finder to another stream.
-		The previous stream should not have been in a PEEK state.
-
-		@param s the input stream for reading statements from.
-	 */
-	public void ReInit(Reader s) { 
-	    try {
-			source.close();
-		} catch (IOException ioe) {
-			// just be quiet if it is already gone
-		}
-		source = s;
-		state = IN_STATEMENT;
-		atEOF = false;
-		peekEOF = false;
-		peeked = false;
-	}
-
-	public void close() throws IOException {
-		source.close();
-	}
-
-	/**
-		get the next statement in the input stream. Returns it,
-		dropping its closing semicolon if it has one. If there is
-		no next statement, return a null.
-
-		@return the next statement in the input stream.
-	 */
-	public String nextStatement() {
-		boolean haveSemi = false;
-		char nextChar;
-
-		// initialize fields for getting the next statement
-		statement.setLength(0);
-		if (state == END_OF_INPUT) return null;
-
-		state = IN_STATEMENT;
-
-		// skip leading whitespace
-		nextChar = peekChar();
-		if (peekEOF()) {
-			state = END_OF_INPUT;
-			return null;
-		}
-		if (whiteSpace(nextChar)) {
-			while (whiteSpace(peekChar()) && ! peekEOF());
-			if (peekEOF()) {
-				state = END_OF_INPUT;
-				return null;
-			}
-		}
-
-		while (state != END_OF_STATEMENT && state != END_OF_INPUT) {
-
-			// get the next character from the input
-			nextChar = readChar();
-			if (atEOF()) {
-				state = END_OF_INPUT;
-				break;
-			}
-
-			switch(nextChar) {
-				case MINUS:
-					readSingleLineComment(nextChar);
-					break;
-				case SINGLEQUOTE:
-				case DOUBLEQUOTE:
-					readString(nextChar);
-					break;
-				case SEMICOLON:
-					haveSemi = true;
-					state = END_OF_STATEMENT;
-					break;
-				default:
-					// keep going, just a normal character
-					break;
-			}
-		}
-
-		if (haveSemi)
-			statement.setLength(statement.length()-1);
-		return statement.toString();
-	}
-
-	/**
-		Determine if the given character is considered whitespace
-
-		@param c the character to consider
-		@return true if the character is whitespace
-	 */
-	private boolean whiteSpace(char c) {
-		return (c == SPACE ||
-		    	c == TAB ||
-		    	c == RETURN ||
-		    	c == NEWLINE ||
-		    	c == FORMFEED);
-	}
-
-	/**
-		Advance the source stream to the end of a comment if it
-		is on one, assuming the first character of
-		a potential single line comment has been found.
-		If it is not a comment, do not advance the stream.
-		<p>
-		The form of a single line comment is, in regexp, XX.*$,
-		where XX is two instances of commentChar.
-
-		@param commentChar the character whose duplication signifies
-			the start of the comment.
-	 */
-	private void readSingleLineComment(char commentChar) {
-		char nextChar;
-
-		nextChar = peekChar();
-		// if next char is EOF, we are done.
-		if (peekEOF()) return;
-
-		// if nextChar is not a minus, it was just a normal minus,
-		// nothing special to do
-		if (nextChar != commentChar) return;
-
-		// we are really in a comment
-		readChar(); // grab the minus for real.
-
-		state = IN_SQLCOMMENT;
-		do {
-			nextChar = peekChar();
-			if (peekEOF()) {
-				// let the caller process the EOF, don't read it
-				state = IN_STATEMENT;
-				return;
-			}
-			switch (nextChar) {
-				case NEWLINE:
-				case RETURN:
-					readChar(); // okay to process the character
-					state = IN_STATEMENT;
-					return;
-				default:
-					readChar(); // process the character, still in comment
-					break;
-			}
-		} while (state == IN_SQLCOMMENT); // could be while true...
-	}
-
-	/**
-		Advance the stream to the end of the string.
-		Assumes the opening delimiter of the string has been read.
-		This handles the SQL ability to put the delimiter within
-		the string by doubling it, by reading those as two strings
-		sitting next to one another.  I.e, 'Mary''s lamb' is read
-		by this class as two strings, 'Mary' and 's lamb'.
-		<p>
-		The delimiter of the string is expected to be repeated at
-		its other end. If the other flavor of delimiter occurs within
-		the string, it is just a normal character within it.
-		<p>
-		All characters except the delimiter are permitted within the
-		string. If EOF is hit before the closing delimiter is found,
-		the end of the string is assumed. Parsers using this parser
-		will detect the error in that case and return appropriate messages.
-
-		@param stringDelimiter the starting and ending character
-			for the string being read.
-	 */
-	private void readString(char stringDelimiter) {
-		state = IN_STRING;
-		do {
-			char nextChar = readChar();
-
-			if (atEOF()) {
-				state = END_OF_INPUT;
-				return;
-			}
-
-			if (nextChar == stringDelimiter) {
-				// we've reached the end of the string
-				state = IN_STATEMENT;
-				return;
-			}
-
-			// still in string
-		} while (state == IN_STRING); // could be while true...
-	}
-
-	private boolean atEOF() {
-		return atEOF;
-	}
-
-	private boolean peekEOF() {
-		return peekEOF;
-	}
-
-	/**
-		return the next character in the source stream and
-		append it to the statement buffer.
-
-		@return the next character in the source stream.
-	 */
-	private char readChar() {
-		if (!peeked) peekChar();
-
-		peeked = false;
-		atEOF = peekEOF;
-
-		if (!atEOF) statement.append(peekChar);
-
-		return peekChar;
-	}
-
-	/**
-		return the next character in the source stream, without
-		advancing.
-
-		@return the next character in the source stream.
-	 */
-	private char peekChar() {
-		peeked = true;
-		char c = '\00';
-
-		try {
-		    int cInt;
-
-			// REMIND: this is assuming a flat ascii source file.
-			// will need to beef it up at some future point to
-			// understand whether the stream is ascii or something else.
-			cInt = source.read();
-			peekEOF = (cInt == -1);
-			if (!peekEOF) c = (char)cInt;
-		} catch (IOException ie) {
-			throw ijException.iOException(ie);
-		}
-
-		peekChar = c;
-		return c;
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+	StatementGrabber looks through an input stream for
+	the next JSQL statement.  A statement is considered to
+	be any tokens up to the next semicolon or EOF.
+	<p>
+	Semicolons inside comments, strings, and delimited identifiers
+	are not considered to be statement terminators but to be
+	part of those tokens.
+	<p>
+	The only comment form currently recognized is the SQL comment,
+	which begins with "--" and ends at the next EOL.
+	<p>
+	Strings and delimited identifiers are permitted to contain
+	newlines; the actual IJ or JSQL parsers will report errors when
+	those cases occur.
+	<p>
+	There are no escaped characters, i.e. "\n" is considered to
+	be two characters, '\' and 'n'.
+
+	@author ames
+ */
+
+public class StatementFinder {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+
+	private Reader source; 
+	private StringBuffer statement = new StringBuffer();
+	private int state;
+	private boolean atEOF = false;
+	private boolean peekEOF = false;
+	private char peekChar;
+	private boolean peeked = false;
+
+	// state variables
+	private static final int IN_STATEMENT = 0;
+	private static final int IN_STRING = 1;
+	private static final int IN_SQLCOMMENT = 2;
+	private static final int END_OF_STATEMENT = 3;
+	private static final int END_OF_INPUT = 4;
+
+	// special state-changing characters
+	private static final char MINUS = '-';
+	private static final char SINGLEQUOTE = '\'';
+	private static final char DOUBLEQUOTE = '\"';
+	private static final char SEMICOLON = ';';
+	private static final char NEWLINE = '\n';
+	private static final char RETURN = '\r';
+	private static final char SPACE = ' ';
+	private static final char TAB = '\t';
+	private static final char FORMFEED = '\f';
+
+	/**
+		The constructor does not assume the stream is data input
+		or buffered, so it will wrap it appropriately.
+
+		@param s the input stream for reading statements from.
+	 */
+	public StatementFinder(Reader s) { 
+		source = s;
+	}
+
+	/**
+		Reinit is used to redirect the finder to another stream.
+		The previous stream should not have been in a PEEK state.
+
+		@param s the input stream for reading statements from.
+	 */
+	public void ReInit(Reader s) { 
+	    try {
+			source.close();
+		} catch (IOException ioe) {
+			// just be quiet if it is already gone
+		}
+		source = s;
+		state = IN_STATEMENT;
+		atEOF = false;
+		peekEOF = false;
+		peeked = false;
+	}
+
+	public void close() throws IOException {
+		source.close();
+	}
+
+	/**
+		get the next statement in the input stream. Returns it,
+		dropping its closing semicolon if it has one. If there is
+		no next statement, return a null.
+
+		@return the next statement in the input stream.
+	 */
+	public String nextStatement() {
+		boolean haveSemi = false;
+		char nextChar;
+
+		// initialize fields for getting the next statement
+		statement.setLength(0);
+		if (state == END_OF_INPUT) return null;
+
+		state = IN_STATEMENT;
+
+		// skip leading whitespace
+		nextChar = peekChar();
+		if (peekEOF()) {
+			state = END_OF_INPUT;
+			return null;
+		}
+		if (whiteSpace(nextChar)) {
+			while (whiteSpace(peekChar()) && ! peekEOF());
+			if (peekEOF()) {
+				state = END_OF_INPUT;
+				return null;
+			}
+		}
+
+		while (state != END_OF_STATEMENT && state != END_OF_INPUT) {
+
+			// get the next character from the input
+			nextChar = readChar();
+			if (atEOF()) {
+				state = END_OF_INPUT;
+				break;
+			}
+
+			switch(nextChar) {
+				case MINUS:
+					readSingleLineComment(nextChar);
+					break;
+				case SINGLEQUOTE:
+				case DOUBLEQUOTE:
+					readString(nextChar);
+					break;
+				case SEMICOLON:
+					haveSemi = true;
+					state = END_OF_STATEMENT;
+					break;
+				default:
+					// keep going, just a normal character
+					break;
+			}
+		}
+
+		if (haveSemi)
+			statement.setLength(statement.length()-1);
+		return statement.toString();
+	}
+
+	/**
+		Determine if the given character is considered whitespace
+
+		@param c the character to consider
+		@return true if the character is whitespace
+	 */
+	private boolean whiteSpace(char c) {
+		return (c == SPACE ||
+		    	c == TAB ||
+		    	c == RETURN ||
+		    	c == NEWLINE ||
+		    	c == FORMFEED);
+	}
+
+	/**
+		Advance the source stream to the end of a comment if it
+		is on one, assuming the first character of
+		a potential single line comment has been found.
+		If it is not a comment, do not advance the stream.
+		<p>
+		The form of a single line comment is, in regexp, XX.*$,
+		where XX is two instances of commentChar.
+
+		@param commentChar the character whose duplication signifies
+			the start of the comment.
+	 */
+	private void readSingleLineComment(char commentChar) {
+		char nextChar;
+
+		nextChar = peekChar();
+		// if next char is EOF, we are done.
+		if (peekEOF()) return;
+
+		// if nextChar is not a minus, it was just a normal minus,
+		// nothing special to do
+		if (nextChar != commentChar) return;
+
+		// we are really in a comment
+		readChar(); // grab the minus for real.
+
+		state = IN_SQLCOMMENT;
+		do {
+			nextChar = peekChar();
+			if (peekEOF()) {
+				// let the caller process the EOF, don't read it
+				state = IN_STATEMENT;
+				return;
+			}
+			switch (nextChar) {
+				case NEWLINE:
+				case RETURN:
+					readChar(); // okay to process the character
+					state = IN_STATEMENT;
+					return;
+				default:
+					readChar(); // process the character, still in comment
+					break;
+			}
+		} while (state == IN_SQLCOMMENT); // could be while true...
+	}
+
+	/**
+		Advance the stream to the end of the string.
+		Assumes the opening delimiter of the string has been read.
+		This handles the SQL ability to put the delimiter within
+		the string by doubling it, by reading those as two strings
+		sitting next to one another.  I.e, 'Mary''s lamb' is read
+		by this class as two strings, 'Mary' and 's lamb'.
+		<p>
+		The delimiter of the string is expected to be repeated at
+		its other end. If the other flavor of delimiter occurs within
+		the string, it is just a normal character within it.
+		<p>
+		All characters except the delimiter are permitted within the
+		string. If EOF is hit before the closing delimiter is found,
+		the end of the string is assumed. Parsers using this parser
+		will detect the error in that case and return appropriate messages.
+
+		@param stringDelimiter the starting and ending character
+			for the string being read.
+	 */
+	private void readString(char stringDelimiter) {
+		state = IN_STRING;
+		do {
+			char nextChar = readChar();
+
+			if (atEOF()) {
+				state = END_OF_INPUT;
+				return;
+			}
+
+			if (nextChar == stringDelimiter) {
+				// we've reached the end of the string
+				state = IN_STATEMENT;
+				return;
+			}
+
+			// still in string
+		} while (state == IN_STRING); // could be while true...
+	}
+
+	private boolean atEOF() {
+		return atEOF;
+	}
+
+	private boolean peekEOF() {
+		return peekEOF;
+	}
+
+	/**
+		return the next character in the source stream and
+		append it to the statement buffer.
+
+		@return the next character in the source stream.
+	 */
+	private char readChar() {
+		if (!peeked) peekChar();
+
+		peeked = false;
+		atEOF = peekEOF;
+
+		if (!atEOF) statement.append(peekChar);
+
+		return peekChar;
+	}
+
+	/**
+		return the next character in the source stream, without
+		advancing.
+
+		@return the next character in the source stream.
+	 */
+	private char peekChar() {
+		peeked = true;
+		char c = '\00';
+
+		try {
+		    int cInt;
+
+			// REMIND: this is assuming a flat ascii source file.
+			// will need to beef it up at some future point to
+			// understand whether the stream is ascii or something else.
+			cInt = source.read();
+			peekEOF = (cInt == -1);
+			if (!peekEOF) c = (char)cInt;
+		} catch (IOException ie) {
+			throw ijException.iOException(ie);
+		}
+
+		peekChar = c;
+		return c;
+	}
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/UCode_CharStream.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/UCode_CharStream.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/UCode_CharStream.java	Fri Sep 24 10:33:20 2004
@@ -1,410 +1,410 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-/* Generated By:JavaCC: Do not edit this line. UCode_CharStream.java Version 0.7pre6 */
-package org.apache.derby.impl.tools.ij;
-
-/**
- * An implementation of interface CharStream, where the stream is assumed to
- * contain only Unicode characters.
- */
-
-public final class UCode_CharStream implements CharStream
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-  public static final boolean staticFlag = false;
-  public int bufpos = -1;
-  int bufsize;
-  int available;
-  int tokenBegin;
-  private int bufline[];
-  private int bufcolumn[];
-
-  private int column = 0;
-  private int line = 1;
-
-  private boolean prevCharIsCR = false;
-  private boolean prevCharIsLF = false;
-
-  private java.io.Reader inputStream;
-
-  private char[] nextCharBuf;
-  private char[] buffer;
-  private int maxNextCharInd = 0;
-  private int nextCharInd = -1;
-
-  private final void ExpandBuff(boolean wrapAround)
-  {
-     char[] newbuffer = new char[bufsize + 2048];
-     int newbufline[] = new int[bufsize + 2048];
-     int newbufcolumn[] = new int[bufsize + 2048];
-
-     try
-     {
-        if (wrapAround)
-        {
-           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
-           System.arraycopy(buffer, 0, newbuffer,
-                                             bufsize - tokenBegin, bufpos);
-           buffer = newbuffer;
-
-           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
-           System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
-           bufline = newbufline;
-
-           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
-           System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
-           bufcolumn = newbufcolumn;
-
-           bufpos += (bufsize - tokenBegin);
-        }
-        else
-        {
-           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
-           buffer = newbuffer;
-
-           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
-           bufline = newbufline;
-
-           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
-           bufcolumn = newbufcolumn;
-
-           bufpos -= tokenBegin;
-        }
-     }
-     catch (Throwable t)
-     {
-        throw new Error(t.getMessage());
-     }
-
-     available = (bufsize += 2048);
-     tokenBegin = 0;
-  }
-
-  private final void FillBuff() throws java.io.IOException
-  {
-     if (maxNextCharInd == 4096)
-        maxNextCharInd = nextCharInd = 0;
-
-     int i;
-     try {
-        if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
-                                            4096 - maxNextCharInd)) == -1)
-        {
-           inputStream.close();
-           throw new java.io.IOException();
-        }
-        else
-           maxNextCharInd += i;
-        return;
-     }
-     catch(java.io.IOException e) {
-        if (bufpos != 0)
-        {
-           --bufpos;
-           backup(0);
-        }
-        else
-        {
-           bufline[bufpos] = line;
-           bufcolumn[bufpos] = column;
-        }
-        if (tokenBegin == -1)
-           tokenBegin = bufpos;
-        throw e;
-     }
-  }
-
-  private final char ReadChar() throws java.io.IOException
-  {
-     if (++nextCharInd >= maxNextCharInd)
-        FillBuff();
-
-     return nextCharBuf[nextCharInd];
-  }
-     
-  public char BeginToken() throws java.io.IOException
-  {     
-     tokenBegin = -1;
-     char c = readChar();
-     tokenBegin = bufpos;
-
-     return c;
-  }     
-
-  private final void UpdateLineColumn(char c)
-  {
-     column++;
-
-     if (prevCharIsLF)
-     {
-        prevCharIsLF = false;
-        line += (column = 1);
-     }
-     else if (prevCharIsCR)
-     {
-        prevCharIsCR = false;
-        if (c == '\n')
-        {
-           prevCharIsLF = true;
-        }
-        else
-           line += (column = 1);
-     }
-
-     switch (c)
-     {
-        case '\r' :
-           prevCharIsCR = true;
-           break;
-        case '\n' :
-           prevCharIsLF = true;
-           break;
-        case '\t' :
-           column--;
-           column += (8 - (column & 07));
-           break;
-        default :
-           break;
-     }
-  }
-
-  private int inBuf = 0;
-  public final char readChar() throws java.io.IOException
-  {
-     if (inBuf > 0)
-     {
-        --inBuf;
-        return (char)buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos];
-     }
-
-	 bufpos++;
-     char c = ReadChar();
-     UpdateLineColumn(c);
-
-     if (bufpos == available)
-     {
-        if (available == bufsize)
-        {
-           if (tokenBegin > 2048)
-           {
-              bufpos = 0;
-              available = tokenBegin;
-           }
-           else if (tokenBegin < 0)
-              bufpos = 0;
-           else
-              ExpandBuff(false);
-        }
-        else if (available > tokenBegin)
-           available = bufsize;
-        else if ((tokenBegin - available) < 2048)
-           ExpandBuff(true);
-        else
-           available = tokenBegin;
-     }
-
-     return (buffer[bufpos] = c);
-  }
-
-  /**
-   * @deprecated 
-   * @see #getEndColumn
-   */
-
-  public final int getColumn() {
-     return bufcolumn[bufpos];
-  }
-
-  /**
-   * @deprecated 
-   * @see #getEndLine
-   */
-
-  public final int getLine() {
-     return bufline[bufpos];
-  }
-
-  public final int getEndColumn() {
-     return bufcolumn[bufpos];
-  }
-
-  public final int getEndLine() {
-     return bufline[bufpos];
-  }
-
-  public final int getBeginColumn() {
-     return bufcolumn[tokenBegin];
-  }
-
-  public final int getBeginLine() {
-     return bufline[tokenBegin];
-  }
-
-  public final void backup(int amount) {
-
-    inBuf += amount;
-    if ((bufpos -= amount) < 0)
-       bufpos += bufsize;
-  }
-
-  public UCode_CharStream(java.io.Reader dstream,
-                 int startline, int startcolumn, int buffersize)
-  {
-    inputStream = dstream;
-    line = startline;
-    column = startcolumn - 1;
-
-    available = bufsize = buffersize;
-    buffer = new char[buffersize];
-    nextCharBuf = new char[buffersize];
-    bufline = new int[buffersize];
-    bufcolumn = new int[buffersize];
-  }
-		
-
-  public UCode_CharStream(java.io.Reader dstream,
-                                        int startline, int startcolumn)
-  {
-     this(dstream, startline, startcolumn, 4096);
-  }
-
-  public void ReInit(java.io.Reader dstream,
-                 int startline, int startcolumn, int buffersize)
-  {
-    inputStream = dstream;
-    line = startline;
-    column = startcolumn - 1;
-
-    if (buffer == null || buffersize != buffer.length)
-    {
-      available = bufsize = buffersize;
-      buffer = new char[buffersize];
-      nextCharBuf = new char[buffersize];
-      bufline = new int[buffersize];
-      bufcolumn = new int[buffersize];
-    }
-  	tokenBegin = inBuf = maxNextCharInd = 0; 
-	nextCharInd = bufpos = -1; 
-  }
-
-  public void ReInit(java.io.Reader dstream,
-                                        int startline, int startcolumn)
-  {
-     ReInit(dstream, startline, startcolumn, 4096);
-  }
-  public UCode_CharStream(java.io.InputStream dstream, int startline,
-  int startcolumn, int buffersize)
-  {
-     this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
-  }
-
-  public UCode_CharStream(java.io.InputStream dstream, int startline,
-                                                           int startcolumn)
-  {
-     this(dstream, startline, startcolumn, 4096);
-  }
-
-  public void ReInit(java.io.InputStream dstream, int startline,
-  int startcolumn, int buffersize)
-  {
-     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
-  }
-  public void ReInit(java.io.InputStream dstream, int startline,
-                                                           int startcolumn)
-  {
-     ReInit(dstream, startline, startcolumn, 4096);
-  }
-
-  public final String GetImage()
-  {
-     if (bufpos >= tokenBegin)
-        return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
-     else
-        return new String(buffer, tokenBegin, bufsize - tokenBegin) +
-                              new String(buffer, 0, bufpos + 1);
-  }
-
-  public final char[] GetSuffix(int len)
-  {
-     char[] ret = new char[len];
-
-     if ((bufpos + 1) >= len)
-        System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
-     else
-     {
-        System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
-                                                          len - bufpos - 1);
-        System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
-     }
-
-     return ret;
-  }
-
-  public void Done()
-  {
-     nextCharBuf = null;
-     buffer = null;
-     bufline = null;
-     bufcolumn = null;
-  }
-
-  /**
-   * Method to adjust line and column numbers for the start of a token.<BR>
-   */
-  public void adjustBeginLineColumn(int newLine, int newCol)
-  {
-     int start = tokenBegin;
-     int len;
-
-     if (bufpos >= tokenBegin)
-     {
-        len = bufpos - tokenBegin + inBuf + 1;
-     }
-     else
-     {
-        len = bufsize - tokenBegin + bufpos + 1 + inBuf;
-     }
-
-     int i = 0, j = 0, k = 0;
-     int nextColDiff = 0, columnDiff = 0;
-
-     while (i < len &&
-            bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
-     {
-        bufline[j] = newLine;
-        nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
-        bufcolumn[j] = newCol + columnDiff;
-        columnDiff = nextColDiff;
-        i++;
-     } 
-
-     if (i < len)
-     {
-        bufline[j] = newLine++;
-        bufcolumn[j] = newCol + columnDiff;
-
-        while (i++ < len)
-        {
-           if (bufline[j = start % bufsize] != bufline[++start % bufsize])
-              bufline[j] = newLine++;
-           else
-              bufline[j] = newLine;
-        }
-     }
-
-     line = bufline[j];
-     column = bufcolumn[j];
-  }
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+/* Generated By:JavaCC: Do not edit this line. UCode_CharStream.java Version 0.7pre6 */
+package org.apache.derby.impl.tools.ij;
+
+/**
+ * An implementation of interface CharStream, where the stream is assumed to
+ * contain only Unicode characters.
+ */
+
+public final class UCode_CharStream implements CharStream
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+  public static final boolean staticFlag = false;
+  public int bufpos = -1;
+  int bufsize;
+  int available;
+  int tokenBegin;
+  private int bufline[];
+  private int bufcolumn[];
+
+  private int column = 0;
+  private int line = 1;
+
+  private boolean prevCharIsCR = false;
+  private boolean prevCharIsLF = false;
+
+  private java.io.Reader inputStream;
+
+  private char[] nextCharBuf;
+  private char[] buffer;
+  private int maxNextCharInd = 0;
+  private int nextCharInd = -1;
+
+  private final void ExpandBuff(boolean wrapAround)
+  {
+     char[] newbuffer = new char[bufsize + 2048];
+     int newbufline[] = new int[bufsize + 2048];
+     int newbufcolumn[] = new int[bufsize + 2048];
+
+     try
+     {
+        if (wrapAround)
+        {
+           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+           System.arraycopy(buffer, 0, newbuffer,
+                                             bufsize - tokenBegin, bufpos);
+           buffer = newbuffer;
+
+           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+           System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+           bufline = newbufline;
+
+           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+           System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
+           bufcolumn = newbufcolumn;
+
+           bufpos += (bufsize - tokenBegin);
+        }
+        else
+        {
+           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+           buffer = newbuffer;
+
+           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+           bufline = newbufline;
+
+           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+           bufcolumn = newbufcolumn;
+
+           bufpos -= tokenBegin;
+        }
+     }
+     catch (Throwable t)
+     {
+        throw new Error(t.getMessage());
+     }
+
+     available = (bufsize += 2048);
+     tokenBegin = 0;
+  }
+
+  private final void FillBuff() throws java.io.IOException
+  {
+     if (maxNextCharInd == 4096)
+        maxNextCharInd = nextCharInd = 0;
+
+     int i;
+     try {
+        if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
+                                            4096 - maxNextCharInd)) == -1)
+        {
+           inputStream.close();
+           throw new java.io.IOException();
+        }
+        else
+           maxNextCharInd += i;
+        return;
+     }
+     catch(java.io.IOException e) {
+        if (bufpos != 0)
+        {
+           --bufpos;
+           backup(0);
+        }
+        else
+        {
+           bufline[bufpos] = line;
+           bufcolumn[bufpos] = column;
+        }
+        if (tokenBegin == -1)
+           tokenBegin = bufpos;
+        throw e;
+     }
+  }
+
+  private final char ReadChar() throws java.io.IOException
+  {
+     if (++nextCharInd >= maxNextCharInd)
+        FillBuff();
+
+     return nextCharBuf[nextCharInd];
+  }
+     
+  public char BeginToken() throws java.io.IOException
+  {     
+     tokenBegin = -1;
+     char c = readChar();
+     tokenBegin = bufpos;
+
+     return c;
+  }     
+
+  private final void UpdateLineColumn(char c)
+  {
+     column++;
+
+     if (prevCharIsLF)
+     {
+        prevCharIsLF = false;
+        line += (column = 1);
+     }
+     else if (prevCharIsCR)
+     {
+        prevCharIsCR = false;
+        if (c == '\n')
+        {
+           prevCharIsLF = true;
+        }
+        else
+           line += (column = 1);
+     }
+
+     switch (c)
+     {
+        case '\r' :
+           prevCharIsCR = true;
+           break;
+        case '\n' :
+           prevCharIsLF = true;
+           break;
+        case '\t' :
+           column--;
+           column += (8 - (column & 07));
+           break;
+        default :
+           break;
+     }
+  }
+
+  private int inBuf = 0;
+  public final char readChar() throws java.io.IOException
+  {
+     if (inBuf > 0)
+     {
+        --inBuf;
+        return (char)buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos];
+     }
+
+	 bufpos++;
+     char c = ReadChar();
+     UpdateLineColumn(c);
+
+     if (bufpos == available)
+     {
+        if (available == bufsize)
+        {
+           if (tokenBegin > 2048)
+           {
+              bufpos = 0;
+              available = tokenBegin;
+           }
+           else if (tokenBegin < 0)
+              bufpos = 0;
+           else
+              ExpandBuff(false);
+        }
+        else if (available > tokenBegin)
+           available = bufsize;
+        else if ((tokenBegin - available) < 2048)
+           ExpandBuff(true);
+        else
+           available = tokenBegin;
+     }
+
+     return (buffer[bufpos] = c);
+  }
+
+  /**
+   * @deprecated 
+   * @see #getEndColumn
+   */
+
+  public final int getColumn() {
+     return bufcolumn[bufpos];
+  }
+
+  /**
+   * @deprecated 
+   * @see #getEndLine
+   */
+
+  public final int getLine() {
+     return bufline[bufpos];
+  }
+
+  public final int getEndColumn() {
+     return bufcolumn[bufpos];
+  }
+
+  public final int getEndLine() {
+     return bufline[bufpos];
+  }
+
+  public final int getBeginColumn() {
+     return bufcolumn[tokenBegin];
+  }
+
+  public final int getBeginLine() {
+     return bufline[tokenBegin];
+  }
+
+  public final void backup(int amount) {
+
+    inBuf += amount;
+    if ((bufpos -= amount) < 0)
+       bufpos += bufsize;
+  }
+
+  public UCode_CharStream(java.io.Reader dstream,
+                 int startline, int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    available = bufsize = buffersize;
+    buffer = new char[buffersize];
+    nextCharBuf = new char[buffersize];
+    bufline = new int[buffersize];
+    bufcolumn = new int[buffersize];
+  }
+		
+
+  public UCode_CharStream(java.io.Reader dstream,
+                                        int startline, int startcolumn)
+  {
+     this(dstream, startline, startcolumn, 4096);
+  }
+
+  public void ReInit(java.io.Reader dstream,
+                 int startline, int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    if (buffer == null || buffersize != buffer.length)
+    {
+      available = bufsize = buffersize;
+      buffer = new char[buffersize];
+      nextCharBuf = new char[buffersize];
+      bufline = new int[buffersize];
+      bufcolumn = new int[buffersize];
+    }
+  	tokenBegin = inBuf = maxNextCharInd = 0; 
+	nextCharInd = bufpos = -1; 
+  }
+
+  public void ReInit(java.io.Reader dstream,
+                                        int startline, int startcolumn)
+  {
+     ReInit(dstream, startline, startcolumn, 4096);
+  }
+  public UCode_CharStream(java.io.InputStream dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+     this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
+  }
+
+  public UCode_CharStream(java.io.InputStream dstream, int startline,
+                                                           int startcolumn)
+  {
+     this(dstream, startline, startcolumn, 4096);
+  }
+
+  public void ReInit(java.io.InputStream dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
+  }
+  public void ReInit(java.io.InputStream dstream, int startline,
+                                                           int startcolumn)
+  {
+     ReInit(dstream, startline, startcolumn, 4096);
+  }
+
+  public final String GetImage()
+  {
+     if (bufpos >= tokenBegin)
+        return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+     else
+        return new String(buffer, tokenBegin, bufsize - tokenBegin) +
+                              new String(buffer, 0, bufpos + 1);
+  }
+
+  public final char[] GetSuffix(int len)
+  {
+     char[] ret = new char[len];
+
+     if ((bufpos + 1) >= len)
+        System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+     else
+     {
+        System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+                                                          len - bufpos - 1);
+        System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+     }
+
+     return ret;
+  }
+
+  public void Done()
+  {
+     nextCharBuf = null;
+     buffer = null;
+     bufline = null;
+     bufcolumn = null;
+  }
+
+  /**
+   * Method to adjust line and column numbers for the start of a token.<BR>
+   */
+  public void adjustBeginLineColumn(int newLine, int newCol)
+  {
+     int start = tokenBegin;
+     int len;
+
+     if (bufpos >= tokenBegin)
+     {
+        len = bufpos - tokenBegin + inBuf + 1;
+     }
+     else
+     {
+        len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+     }
+
+     int i = 0, j = 0, k = 0;
+     int nextColDiff = 0, columnDiff = 0;
+
+     while (i < len &&
+            bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
+     {
+        bufline[j] = newLine;
+        nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+        bufcolumn[j] = newCol + columnDiff;
+        columnDiff = nextColDiff;
+        i++;
+     } 
+
+     if (i < len)
+     {
+        bufline[j] = newLine++;
+        bufcolumn[j] = newCol + columnDiff;
+
+        while (i++ < len)
+        {
+           if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+              bufline[j] = newLine++;
+           else
+              bufline[j] = newLine;
+        }
+     }
+
+     line = bufline[j];
+     column = bufcolumn[j];
+  }
+
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijConnectionResult.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijConnectionResult.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijConnectionResult.java	Fri Sep 24 10:33:20 2004
@@ -1,38 +1,38 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-
-/**
- * @author ames
- */
-class ijConnectionResult extends ijResultImpl {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-
-	Connection conn;
-
-	ijConnectionResult(Connection c) {
-		conn = c;
-	}
-
-	public boolean isConnection() { return true; }
-
-	public Connection getConnection() { return conn; }
-
-	public SQLWarning getSQLWarnings() throws SQLException { return conn.getWarnings(); }
-	public void clearSQLWarnings() throws SQLException { conn.clearWarnings(); }
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+
+/**
+ * @author ames
+ */
+class ijConnectionResult extends ijResultImpl {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+
+	Connection conn;
+
+	ijConnectionResult(Connection c) {
+		conn = c;
+	}
+
+	public boolean isConnection() { return true; }
+
+	public Connection getConnection() { return conn; }
+
+	public SQLWarning getSQLWarnings() throws SQLException { return conn.getWarnings(); }
+	public void clearSQLWarnings() throws SQLException { conn.clearWarnings(); }
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijException.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijException.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijException.java	Fri Sep 24 10:33:20 2004
@@ -1,148 +1,148 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import org.apache.derby.iapi.tools.i18n.LocalizedResource;
-import java.io.IOException;
-
-/**
-	ijException is used to get messages from the ij parser to
-	the main ij loop. Because this is not under the protocol/impl
-	umbrella, it does not have available to it the message service.
-	At this time, all messages are hard-coded in this file. A more
-	serviceable solution may need to be found.
-
-	@author ames.
- */
-
-public class ijException extends RuntimeException {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-
-	private	final static String	IllegalStatementName="IJ_IllegalStatementName";
-	private final static String NotYetImplemented="IJ_NotYetImpl";
-	private final static String AlreadyHaveConnectionNamed = "IJ_AlreHaveACon";
-	private final static String BangException = "IJ_ExceRunnComm";
-	private final static String ConnectionGetWarningsFailed = "IJ_UnabToGetWar";
-	private final static String ClassNotFoundForProtocol = "IJ_CoulNotLocaC";
-	private final static String ClassNotFound = "IJ_CoulNotLocaC_5";
-	private final static String DisconnectFailed = "IJ_FailToDisc";
-	private final static String DriverNotClassName = "IJ_DrivNotClasN";
-	private final static String FileNotFound = "IJ_FileNotFoun";
-	private final static String ForwardOnlyCursor = "IJ_IsNotAlloOnA";
-	private final static String GetConnectionFailed = "IJ_GetcCallFail";
-	private final static String IOException = "IJ_Ioex";
-	private final static String NeedToDisconnect = "IJ_NeedToDiscFi";
-	private final static String NoSuchAsyncStatement = "IJ_NoAsynStatEx";
-	private final static String NoSuchConnection = "IJ_NoConnExisWi";
-	private final static String NoSuchProtocol = "IJ_NoProtExisWi";
-	private final static String NotJDBC20 = "IJ_IsOnlySuppIn";
-	private final static String NoUsingResults = "IJ_UsinClauHadN";
-	private final static String ObjectWasNull = "IJ_UnabToEsta";
-	private final static String ResultSetGetWarningsFailed = "IJ_UnabToGetWar_19";
-    private final static String ResourceNotFound = "IJ_ResoNotFoun";
-	private final static String ScrollCursorsNotSupported = "IJ_ScroCursAre1";
-	private final static String HoldCursorsNotSupported = "IJ_HoldCursAre4";
-	private final static String StatementGetWarningsFailed = "IJ_UnabToGetWar_22";
-	private final static String WaitInterrupted = "IJ_WaitForStatI";
-	private final static String ZeroInvalidForAbsolute = "IJ_0IsAnInvaVal";
-
-	public ijException(String message) {
-		super(message);
-	}
-
-	static ijException notYetImplemented() {
-		return new ijException(LocalizedResource.getMessage(NotYetImplemented));
-	}
-
-	static ijException illegalStatementName(String n) {
-		return new ijException(LocalizedResource.getMessage(IllegalStatementName, n));
-	}
-	static ijException alreadyHaveConnectionNamed(String n) {
-		return new ijException(LocalizedResource.getMessage(AlreadyHaveConnectionNamed, n));
-	}
-	static ijException bangException(Throwable t) {
-		return new ijException(LocalizedResource.getMessage(BangException, t.toString()));
-	}
-	static ijException classNotFoundForProtocol(String p) {
-		return new ijException(LocalizedResource.getMessage(ClassNotFoundForProtocol, p));
-	}
-	static ijException classNotFound(String c) {
-		return new ijException(LocalizedResource.getMessage(ClassNotFound, c));
-	}
-	static ijException connectionGetWarningsFailed() {
-		return new ijException(LocalizedResource.getMessage(ConnectionGetWarningsFailed));
-	}
-	static ijException disconnectFailed() {
-		return new ijException(LocalizedResource.getMessage(DisconnectFailed));
-	}
-	static ijException driverNotClassName(String c) {
-		return new ijException(LocalizedResource.getMessage(DriverNotClassName, c));
-	}
-	static ijException fileNotFound() {
-		return new ijException(LocalizedResource.getMessage(FileNotFound));
-	}
-	static public ijException forwardOnlyCursor(String operation) {
-		return new ijException(LocalizedResource.getMessage(ForwardOnlyCursor, operation));
-	}
-	static ijException resourceNotFound() {
-		return new ijException(LocalizedResource.getMessage(ResourceNotFound));
-	}
-	static ijException getConnectionFailed() {
-		return new ijException(LocalizedResource.getMessage(GetConnectionFailed));
-	}
-	static ijException iOException(IOException t) {
-		return new ijException(LocalizedResource.getMessage(IOException, t.getMessage()));
-	}
-	static ijException needToDisconnect() {
-		return new ijException(LocalizedResource.getMessage(NeedToDisconnect));
-	}
-	static ijException noSuchAsyncStatement(String c) {
-		return new ijException(LocalizedResource.getMessage(NoSuchAsyncStatement, c));
-	}
-	static ijException noSuchConnection(String c) {
-		return new ijException(LocalizedResource.getMessage(NoSuchConnection, c));
-	}
-	static ijException noSuchProtocol(String c) {
-		return new ijException(LocalizedResource.getMessage(NoSuchProtocol, c));
-	}
-	static public ijException notJDBC20(String operation) {
-		return new ijException(LocalizedResource.getMessage(NotJDBC20, operation));
-	}
-	static ijException noUsingResults() {
-		return new ijException(LocalizedResource.getMessage(NoUsingResults));
-	}
-	static public ijException objectWasNull(String objectName) {
-		return new ijException(LocalizedResource.getMessage(ObjectWasNull, objectName));
-	}
-	static ijException resultSetGetWarningsFailed() {
-		return new ijException(LocalizedResource.getMessage(ResultSetGetWarningsFailed));
-	}
-	static ijException scrollCursorsNotSupported() {
-		return new ijException(LocalizedResource.getMessage(ScrollCursorsNotSupported));
-	}
-	//IJImpl20.utilMain can't throw exception for holdable cursors if
-	//following not declared public
-	public static ijException holdCursorsNotSupported() {
-		return new ijException(LocalizedResource.getMessage(HoldCursorsNotSupported));
-	}
-	static ijException statementGetWarningsFailed() {
-		return new ijException(LocalizedResource.getMessage(StatementGetWarningsFailed));
-	}
-	static ijException waitInterrupted(Throwable t) {
-		return new ijException(LocalizedResource.getMessage(WaitInterrupted, t.toString()));
-	}
-	public static ijException zeroInvalidForAbsolute() {
-		return new ijException(LocalizedResource.getMessage(ZeroInvalidForAbsolute));
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import org.apache.derby.iapi.tools.i18n.LocalizedResource;
+import java.io.IOException;
+
+/**
+	ijException is used to get messages from the ij parser to
+	the main ij loop. Because this is not under the protocol/impl
+	umbrella, it does not have available to it the message service.
+	At this time, all messages are hard-coded in this file. A more
+	serviceable solution may need to be found.
+
+	@author ames.
+ */
+
+public class ijException extends RuntimeException {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+
+	private	final static String	IllegalStatementName="IJ_IllegalStatementName";
+	private final static String NotYetImplemented="IJ_NotYetImpl";
+	private final static String AlreadyHaveConnectionNamed = "IJ_AlreHaveACon";
+	private final static String BangException = "IJ_ExceRunnComm";
+	private final static String ConnectionGetWarningsFailed = "IJ_UnabToGetWar";
+	private final static String ClassNotFoundForProtocol = "IJ_CoulNotLocaC";
+	private final static String ClassNotFound = "IJ_CoulNotLocaC_5";
+	private final static String DisconnectFailed = "IJ_FailToDisc";
+	private final static String DriverNotClassName = "IJ_DrivNotClasN";
+	private final static String FileNotFound = "IJ_FileNotFoun";
+	private final static String ForwardOnlyCursor = "IJ_IsNotAlloOnA";
+	private final static String GetConnectionFailed = "IJ_GetcCallFail";
+	private final static String IOException = "IJ_Ioex";
+	private final static String NeedToDisconnect = "IJ_NeedToDiscFi";
+	private final static String NoSuchAsyncStatement = "IJ_NoAsynStatEx";
+	private final static String NoSuchConnection = "IJ_NoConnExisWi";
+	private final static String NoSuchProtocol = "IJ_NoProtExisWi";
+	private final static String NotJDBC20 = "IJ_IsOnlySuppIn";
+	private final static String NoUsingResults = "IJ_UsinClauHadN";
+	private final static String ObjectWasNull = "IJ_UnabToEsta";
+	private final static String ResultSetGetWarningsFailed = "IJ_UnabToGetWar_19";
+    private final static String ResourceNotFound = "IJ_ResoNotFoun";
+	private final static String ScrollCursorsNotSupported = "IJ_ScroCursAre1";
+	private final static String HoldCursorsNotSupported = "IJ_HoldCursAre4";
+	private final static String StatementGetWarningsFailed = "IJ_UnabToGetWar_22";
+	private final static String WaitInterrupted = "IJ_WaitForStatI";
+	private final static String ZeroInvalidForAbsolute = "IJ_0IsAnInvaVal";
+
+	public ijException(String message) {
+		super(message);
+	}
+
+	static ijException notYetImplemented() {
+		return new ijException(LocalizedResource.getMessage(NotYetImplemented));
+	}
+
+	static ijException illegalStatementName(String n) {
+		return new ijException(LocalizedResource.getMessage(IllegalStatementName, n));
+	}
+	static ijException alreadyHaveConnectionNamed(String n) {
+		return new ijException(LocalizedResource.getMessage(AlreadyHaveConnectionNamed, n));
+	}
+	static ijException bangException(Throwable t) {
+		return new ijException(LocalizedResource.getMessage(BangException, t.toString()));
+	}
+	static ijException classNotFoundForProtocol(String p) {
+		return new ijException(LocalizedResource.getMessage(ClassNotFoundForProtocol, p));
+	}
+	static ijException classNotFound(String c) {
+		return new ijException(LocalizedResource.getMessage(ClassNotFound, c));
+	}
+	static ijException connectionGetWarningsFailed() {
+		return new ijException(LocalizedResource.getMessage(ConnectionGetWarningsFailed));
+	}
+	static ijException disconnectFailed() {
+		return new ijException(LocalizedResource.getMessage(DisconnectFailed));
+	}
+	static ijException driverNotClassName(String c) {
+		return new ijException(LocalizedResource.getMessage(DriverNotClassName, c));
+	}
+	static ijException fileNotFound() {
+		return new ijException(LocalizedResource.getMessage(FileNotFound));
+	}
+	static public ijException forwardOnlyCursor(String operation) {
+		return new ijException(LocalizedResource.getMessage(ForwardOnlyCursor, operation));
+	}
+	static ijException resourceNotFound() {
+		return new ijException(LocalizedResource.getMessage(ResourceNotFound));
+	}
+	static ijException getConnectionFailed() {
+		return new ijException(LocalizedResource.getMessage(GetConnectionFailed));
+	}
+	static ijException iOException(IOException t) {
+		return new ijException(LocalizedResource.getMessage(IOException, t.getMessage()));
+	}
+	static ijException needToDisconnect() {
+		return new ijException(LocalizedResource.getMessage(NeedToDisconnect));
+	}
+	static ijException noSuchAsyncStatement(String c) {
+		return new ijException(LocalizedResource.getMessage(NoSuchAsyncStatement, c));
+	}
+	static ijException noSuchConnection(String c) {
+		return new ijException(LocalizedResource.getMessage(NoSuchConnection, c));
+	}
+	static ijException noSuchProtocol(String c) {
+		return new ijException(LocalizedResource.getMessage(NoSuchProtocol, c));
+	}
+	static public ijException notJDBC20(String operation) {
+		return new ijException(LocalizedResource.getMessage(NotJDBC20, operation));
+	}
+	static ijException noUsingResults() {
+		return new ijException(LocalizedResource.getMessage(NoUsingResults));
+	}
+	static public ijException objectWasNull(String objectName) {
+		return new ijException(LocalizedResource.getMessage(ObjectWasNull, objectName));
+	}
+	static ijException resultSetGetWarningsFailed() {
+		return new ijException(LocalizedResource.getMessage(ResultSetGetWarningsFailed));
+	}
+	static ijException scrollCursorsNotSupported() {
+		return new ijException(LocalizedResource.getMessage(ScrollCursorsNotSupported));
+	}
+	//IJImpl20.utilMain can't throw exception for holdable cursors if
+	//following not declared public
+	public static ijException holdCursorsNotSupported() {
+		return new ijException(LocalizedResource.getMessage(HoldCursorsNotSupported));
+	}
+	static ijException statementGetWarningsFailed() {
+		return new ijException(LocalizedResource.getMessage(StatementGetWarningsFailed));
+	}
+	static ijException waitInterrupted(Throwable t) {
+		return new ijException(LocalizedResource.getMessage(WaitInterrupted, t.toString()));
+	}
+	public static ijException zeroInvalidForAbsolute() {
+		return new ijException(LocalizedResource.getMessage(ZeroInvalidForAbsolute));
+	}
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijExceptionResult.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijExceptionResult.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijExceptionResult.java	Fri Sep 24 10:33:20 2004
@@ -1,40 +1,40 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-
-/**
- * This is an impl for just returning errors from
- * JDBC statements. Used by Async to capture its result
- * for WaitFor.
- *
- * @author ames
- */
-class ijExceptionResult extends ijResultImpl {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-
-	SQLException except;
-
-	ijExceptionResult(SQLException e) {
-		except = e;
-	}
-
-	public boolean isException() { return true; }
-	public SQLException getException() { return except; }
-
-	public SQLWarning getSQLWarnings() { return null; }
-	public void clearSQLWarnings() { }
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+
+/**
+ * This is an impl for just returning errors from
+ * JDBC statements. Used by Async to capture its result
+ * for WaitFor.
+ *
+ * @author ames
+ */
+class ijExceptionResult extends ijResultImpl {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+
+	SQLException except;
+
+	ijExceptionResult(SQLException e) {
+		except = e;
+	}
+
+	public boolean isException() { return true; }
+	public SQLException getException() { return except; }
+
+	public SQLWarning getSQLWarnings() { return null; }
+	public void clearSQLWarnings() { }
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijFatalException.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijFatalException.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijFatalException.java	Fri Sep 24 10:33:20 2004
@@ -1,50 +1,50 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import org.apache.derby.iapi.tools.i18n.LocalizedResource;
-import java.io.IOException;
-import java.sql.SQLException;
-/**
- * Used for fatal IJ exceptions
- */
-
-public class ijFatalException extends RuntimeException {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-
-	private final static String FatalException = LocalizedResource.getMessage("IJ_FataExceTerm");
-	private SQLException e;
-
-	public ijFatalException() 
-	{
-		super(FatalException);
-		e = null;
-	}
-
-	public ijFatalException(SQLException e) 
-	{
-		super(FatalException); 
-		this.e = e;
-	}
-
-	public String getSQLState()
-	{
-		return e.getSQLState();
-	}
-	
-	public String toString()
-	{
-		return LocalizedResource.getMessage("IJ_Fata01",e.getSQLState(),e.getMessage());
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import org.apache.derby.iapi.tools.i18n.LocalizedResource;
+import java.io.IOException;
+import java.sql.SQLException;
+/**
+ * Used for fatal IJ exceptions
+ */
+
+public class ijFatalException extends RuntimeException {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+
+	private final static String FatalException = LocalizedResource.getMessage("IJ_FataExceTerm");
+	private SQLException e;
+
+	public ijFatalException() 
+	{
+		super(FatalException);
+		e = null;
+	}
+
+	public ijFatalException(SQLException e) 
+	{
+		super(FatalException); 
+		this.e = e;
+	}
+
+	public String getSQLState()
+	{
+		return e.getSQLState();
+	}
+	
+	public String toString()
+	{
+		return LocalizedResource.getMessage("IJ_Fata01",e.getSQLState(),e.getMessage());
+	}
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijMultiResult.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijMultiResult.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijMultiResult.java	Fri Sep 24 10:33:20 2004
@@ -1,60 +1,60 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.Statement;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.util.Vector;
-
-/**
- * This is an impl for a statement execution; the result
- * is either an update count or result set depending
- * on what was executed.
- *
- * @author ames
- */
-class ijMultiResult extends ijResultImpl {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-
-	Vector results = new Vector();
-	Statement statement;
-	ResultSet rs;
-	boolean closeWhenDone;
-
-	ijMultiResult(Statement s, ResultSet rs, boolean c) {
-		statement = s;
-		this.rs = rs;
-		closeWhenDone = c;
-	}
-
-	public void addStatementResult(Statement s) throws SQLException {
-System.out.println("adding statement "+results.size()+1);
-		if (s.getUpdateCount() >=0)
-			results.addElement(new Integer(s.getUpdateCount()));
-		else
-			results.addElement(s.getResultSet());
-	}
-
-	public boolean isMulti() { return true; }
-
-	public Statement getStatement() { return statement; }
-	public ResultSet getResultSet() { return rs; }
-	public void closeStatement() throws SQLException { if (closeWhenDone) statement.close(); }
-
-	public SQLWarning getSQLWarnings() { return null; }
-	public void clearSQLWarnings() { }
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.util.Vector;
+
+/**
+ * This is an impl for a statement execution; the result
+ * is either an update count or result set depending
+ * on what was executed.
+ *
+ * @author ames
+ */
+class ijMultiResult extends ijResultImpl {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+
+	Vector results = new Vector();
+	Statement statement;
+	ResultSet rs;
+	boolean closeWhenDone;
+
+	ijMultiResult(Statement s, ResultSet rs, boolean c) {
+		statement = s;
+		this.rs = rs;
+		closeWhenDone = c;
+	}
+
+	public void addStatementResult(Statement s) throws SQLException {
+System.out.println("adding statement "+results.size()+1);
+		if (s.getUpdateCount() >=0)
+			results.addElement(new Integer(s.getUpdateCount()));
+		else
+			results.addElement(s.getResultSet());
+	}
+
+	public boolean isMulti() { return true; }
+
+	public Statement getStatement() { return statement; }
+	public ResultSet getResultSet() { return rs; }
+	public void closeStatement() throws SQLException { if (closeWhenDone) statement.close(); }
+
+	public SQLWarning getSQLWarnings() { return null; }
+	public void clearSQLWarnings() { }
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijResult.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijResult.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijResult.java	Fri Sep 24 10:33:20 2004
@@ -1,59 +1,59 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.Statement;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.util.Vector;
-
-/**
- * This is a wrapper for results coming out of the
- * ij parser.
- *
- * @author ames
- *
- */
-public interface ijResult {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-	boolean isConnection();
-	boolean isStatement();
-	boolean isResultSet() throws SQLException;
-	boolean isUpdateCount() throws SQLException;
-	boolean isNextRowOfResultSet();
-	boolean isVector();
-	boolean isMulti();
-	boolean isException();
-	boolean hasWarnings() throws SQLException ;
-
-	Connection getConnection();
-	Statement getStatement();
-	int getUpdateCount() throws SQLException;
-	ResultSet getResultSet() throws SQLException;
-	ResultSet getNextRowOfResultSet();
-	Vector getVector();
-	SQLException getException();
-
-	void closeStatement() throws SQLException ;
-
-	/*
-		Since they will all need to do warning calls/clears, may as
-		well stick it here.
-	 */
-	SQLWarning getSQLWarnings() throws SQLException ;
-	void clearSQLWarnings() throws SQLException ;
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.util.Vector;
+
+/**
+ * This is a wrapper for results coming out of the
+ * ij parser.
+ *
+ * @author ames
+ *
+ */
+public interface ijResult {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+	boolean isConnection();
+	boolean isStatement();
+	boolean isResultSet() throws SQLException;
+	boolean isUpdateCount() throws SQLException;
+	boolean isNextRowOfResultSet();
+	boolean isVector();
+	boolean isMulti();
+	boolean isException();
+	boolean hasWarnings() throws SQLException ;
+
+	Connection getConnection();
+	Statement getStatement();
+	int getUpdateCount() throws SQLException;
+	ResultSet getResultSet() throws SQLException;
+	ResultSet getNextRowOfResultSet();
+	Vector getVector();
+	SQLException getException();
+
+	void closeStatement() throws SQLException ;
+
+	/*
+		Since they will all need to do warning calls/clears, may as
+		well stick it here.
+	 */
+	SQLWarning getSQLWarnings() throws SQLException ;
+	void clearSQLWarnings() throws SQLException ;
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijVectorResult.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijVectorResult.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijVectorResult.java	Fri Sep 24 10:33:20 2004
@@ -1,41 +1,41 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import java.util.Vector;
-import java.sql.SQLWarning;
-
-/**
- * This is an impl for a simple Vector of strings.
- *
- * @author ames
- */
-class ijVectorResult extends ijResultImpl {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-
-	Vector vec;
-	SQLWarning warns;
-
-	ijVectorResult(Vector v, SQLWarning w) {
-		vec = v;
-		warns = w;
-	}
-
-	public boolean isVector() { return true; }
-
-	public Vector getVector() { return vec; }
-
-	public SQLWarning getSQLWarnings() { return warns; }
-	public void clearSQLWarnings() { warns = null; }
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import java.util.Vector;
+import java.sql.SQLWarning;
+
+/**
+ * This is an impl for a simple Vector of strings.
+ *
+ * @author ames
+ */
+class ijVectorResult extends ijResultImpl {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+
+	Vector vec;
+	SQLWarning warns;
+
+	ijVectorResult(Vector v, SQLWarning w) {
+		vec = v;
+		warns = w;
+	}
+
+	public boolean isVector() { return true; }
+
+	public Vector getVector() { return vec; }
+
+	public SQLWarning getSQLWarnings() { return warns; }
+	public void clearSQLWarnings() { warns = null; }
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijWarningResult.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijWarningResult.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/ijWarningResult.java	Fri Sep 24 10:33:20 2004
@@ -1,41 +1,41 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-
-/**
- * This is an impl for just returning warnings from
- * JDBC objects we don't want the caller to touch.
- * They are already cleared from the underlying
- * objects, doing clearSQLWarnings here is redundant.
- *
- * @author ames
- */
-class ijWarningResult extends ijResultImpl {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-
-	SQLWarning warn;
-
-	ijWarningResult(SQLWarning w) {
-		warn = w;
-	}
-
-	public SQLWarning getSQLWarnings() { return warn; }
-	public void clearSQLWarnings() { warn = null; }
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+
+/**
+ * This is an impl for just returning warnings from
+ * JDBC objects we don't want the caller to touch.
+ * They are already cleared from the underlying
+ * objects, doing clearSQLWarnings here is redundant.
+ *
+ * @author ames
+ */
+class ijWarningResult extends ijResultImpl {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+
+	SQLWarning warn;
+
+	ijWarningResult(SQLWarning w) {
+		warn = w;
+	}
+
+	public SQLWarning getSQLWarnings() { return warn; }
+	public void clearSQLWarnings() { warn = null; }
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTestCase.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTestCase.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTestCase.java	Fri Sep 24 10:33:20 2004
@@ -1,287 +1,287 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import java.util.Hashtable;
-import java.util.Properties;
-import java.lang.Math;
-import java.io.FileNotFoundException;
-import java.io.BufferedInputStream;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-
-import org.apache.derby.iapi.tools.i18n.*;
-
-/**
- */
-public class mtTestCase
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-	public String name = null;
-	public String file = null;
-	public String propFile = null;
-	public float weight = (float).5;
-	public Hashtable ignoreErrors = null;
-	public String description = null;
-
-
-	private int iterations;
-	private int attempts;
-
-	public void mtTestCase()
-	{ };
-
-	public void setName(String name)
-	{
-		this.name = name;
-	}
-	public String getName()
-	{
-		return name;
-	}
-
-	public void setFile(String name)
-	{
-		this.file = name;
-	}
-
-	public void setInputDir(String dir)
-	{
-		file = dir + "/" + file;
-	}
-
-	public String getFile()
-	{
-		return file;
-	}
-	
-	public void setPropFile(String name)
-	{
-		this.propFile = name;
-	}
-
-	public String getPropFile()
-	{
-		return propFile;
-	}
-
-	public void setWeight(int weight)
-	{
-		this.weight = (float)(weight/100.0);
-	}
-	
-	public void setIgnoreErrors(Hashtable t)
-	{
-		this.ignoreErrors = t;
-	}
-	
-	public void setDescription(String description)
-	{
-		this.description = description;
-	}
-
-	/**
-	** Initialize the test case.  See initialize(String)
-	*/
-	public synchronized BufferedInputStream initialize() 
-			throws FileNotFoundException, IOException
-	{
-		return initialize(null);
-	}
-
-	/**
-	** Initizalize the test case.  Loads up the properties
-	** file and sets the input stream.  Used to set up
-	** prior to running the thread.
-	*/
-	public synchronized BufferedInputStream initialize(String inputDir) 
-			throws FileNotFoundException, IOException
-	{
-		String filePath; 
-		BufferedInputStream	inStream = null;
-
-		// load up properties
-		if (propFile != null)
-		{	
-			BufferedInputStream	propStream;
-			Properties		p;
-			String propPath = (inputDir == null) ?
-						propFile : 
-				(inputDir + "/" + propFile);
-			
-			try 
-			{
-				propStream = new BufferedInputStream(new FileInputStream(propPath));
-			} catch (FileNotFoundException e)
-			{
-				System.out.println(name+": unable to find properties file "+propPath);
-				throw e;
-			}
-
-			p = System.getProperties();
-			p.load(propStream);
-			// for network server need to alter url
-			String framework = p.getProperty("framework");
-			
-			if (framework != null && framework.equals("DB2jNet"))
-			{
-				String newURLPrefix= "jdbc:derby:net://localhost:1527/";
-				updateURLProperties(p,newURLPrefix);
-				p.setProperty("ij.user","APP");
-				p.setProperty("ij.password","PWD");
-			}
-			System.setProperties(p);
-		}
-		// set input stream
-		filePath = (inputDir == null) ?
-						file : (inputDir + "/" + file);
-
-		try 
-		{
-			inStream = new BufferedInputStream(new FileInputStream(filePath), 
-							utilMain.BUFFEREDFILESIZE);		
-		} catch (FileNotFoundException e)
-		{
-			System.out.println("unable to find properties file "+filePath);
-			throw e;
-		}
-		return inStream;
-	}
-
-	/**
-	** Attempt to grab this test case.  
-	** Uses random number and the weight of this
-	** case to determine if the grab was successful.
-	** 
-	** @return true/false
-	*/
-	public synchronized boolean grab()
-	{
-		attempts++;
-		if (java.lang.Math.random() < weight)
-		{
-			iterations++;
-			return true;
-		}
-		else
-		{
-			return false;
-		}
-	}
-
-	/**
-	** Run the test case.  Invokes IJ to do our
-	** dirty work.
-	*/
-	public void runMe(LocalizedOutput log, LocalizedOutput out, BufferedInputStream infile)
-	{
-		utilMain	utilInstance;
-        LocalizedInput is;
-        is = LocalizedResource.getInstance().getNewInput(infile);
-
-		LocalizedInput [] in = { is };
-	
-		out.println("--------------"+file+"-----------------");
-		utilInstance = new utilMain(1, out, ignoreErrors);
-		utilInstance.setMtUse(true);
-		utilInstance.go(in, out, (java.util.Properties) null);
-		log.flush();
-		out.flush();
-	}
-
-	public void updateURLProperties(Properties p, String newURLPrefix)
-	{
-		String[] propsToUpdate = {"ij.database", "ij.protocol",
-								  "database"};
-		for (int i = 0; i < propsToUpdate.length; i++)
-		{
-			String key = propsToUpdate[i];
-			String val = p.getProperty(key);
-			if (val != null)
-				p.setProperty(key,alterURL(val,newURLPrefix));
-		}
-	}
-
-
-	public String alterURL(String url, String newURLPrefix)
-	{
-		String urlPrefix = "jdbc:derby:";
-	
-		if (url.startsWith(newURLPrefix))
-			return url;
-
-		// If we don't have a URL prefix for this framework
-		// just return
-		if (newURLPrefix == null)
-			return url;
-	
-		if (url.equals(urlPrefix)) // Replace embedded
-			return newURLPrefix;
-
-		if (url.startsWith(urlPrefix))
-		{
-			// replace jdbc:derby: with our url:
-			url = newURLPrefix +
-				url.substring(urlPrefix.length());
-
-		}
-		else
-		{
-			if (! (url.startsWith("jdbc:")))
-	    {
-			url = newURLPrefix + url;
-	    }
-		}
-		//System.out.println("New url:" +url);
-		return url;
-    }
-  
-
-// NOTE: tried invoking ij directly, but had some problems,
-// so stick with calling utilMain().	
-//	/**
-//	** Run the test case.  Invokes IJ to do our
-//	** dirty work.
-//	*/
-//	public void runMe(AppStreamWriter log, AppStreamWriter out, BufferedInputStream infile)
-//	{
-//		ASCII_UCodeESC_CharStream charStream;
-//		ijTokenManager	ijTokMgr;
-//		ij	ijParser;
-//	
-//		
-//		out.println("--------------"+file+"-----------------");
-//		charStream = new ASCII_UCodeESC_CharStream(in, 1, 1);
-//		ijTokMgr = new ijTokenManager(charStream);
-//		ijParser = new ij(ijTokMgr, System.out, this);
-//		log.flush();
-//		out.flush();
-//	}
-
-	/**
-	** Name says it all
-	*/
-	public String toString()
-	{
-		return "name: "+name+
-				"\n\tfile: "+file+
-				"\n\tproperties: "+propFile+
-				"\n\tweight: "+weight+
-				"\n\tignoreErrors: "+ignoreErrors+
-				"\n\tdescription: "+description;
-	}
-
-	
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import java.util.Hashtable;
+import java.util.Properties;
+import java.lang.Math;
+import java.io.FileNotFoundException;
+import java.io.BufferedInputStream;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import org.apache.derby.iapi.tools.i18n.*;
+
+/**
+ */
+public class mtTestCase
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+	public String name = null;
+	public String file = null;
+	public String propFile = null;
+	public float weight = (float).5;
+	public Hashtable ignoreErrors = null;
+	public String description = null;
+
+
+	private int iterations;
+	private int attempts;
+
+	public void mtTestCase()
+	{ };
+
+	public void setName(String name)
+	{
+		this.name = name;
+	}
+	public String getName()
+	{
+		return name;
+	}
+
+	public void setFile(String name)
+	{
+		this.file = name;
+	}
+
+	public void setInputDir(String dir)
+	{
+		file = dir + "/" + file;
+	}
+
+	public String getFile()
+	{
+		return file;
+	}
+	
+	public void setPropFile(String name)
+	{
+		this.propFile = name;
+	}
+
+	public String getPropFile()
+	{
+		return propFile;
+	}
+
+	public void setWeight(int weight)
+	{
+		this.weight = (float)(weight/100.0);
+	}
+	
+	public void setIgnoreErrors(Hashtable t)
+	{
+		this.ignoreErrors = t;
+	}
+	
+	public void setDescription(String description)
+	{
+		this.description = description;
+	}
+
+	/**
+	** Initialize the test case.  See initialize(String)
+	*/
+	public synchronized BufferedInputStream initialize() 
+			throws FileNotFoundException, IOException
+	{
+		return initialize(null);
+	}
+
+	/**
+	** Initizalize the test case.  Loads up the properties
+	** file and sets the input stream.  Used to set up
+	** prior to running the thread.
+	*/
+	public synchronized BufferedInputStream initialize(String inputDir) 
+			throws FileNotFoundException, IOException
+	{
+		String filePath; 
+		BufferedInputStream	inStream = null;
+
+		// load up properties
+		if (propFile != null)
+		{	
+			BufferedInputStream	propStream;
+			Properties		p;
+			String propPath = (inputDir == null) ?
+						propFile : 
+				(inputDir + "/" + propFile);
+			
+			try 
+			{
+				propStream = new BufferedInputStream(new FileInputStream(propPath));
+			} catch (FileNotFoundException e)
+			{
+				System.out.println(name+": unable to find properties file "+propPath);
+				throw e;
+			}
+
+			p = System.getProperties();
+			p.load(propStream);
+			// for network server need to alter url
+			String framework = p.getProperty("framework");
+			
+			if (framework != null && framework.equals("DB2jNet"))
+			{
+				String newURLPrefix= "jdbc:derby:net://localhost:1527/";
+				updateURLProperties(p,newURLPrefix);
+				p.setProperty("ij.user","APP");
+				p.setProperty("ij.password","PWD");
+			}
+			System.setProperties(p);
+		}
+		// set input stream
+		filePath = (inputDir == null) ?
+						file : (inputDir + "/" + file);
+
+		try 
+		{
+			inStream = new BufferedInputStream(new FileInputStream(filePath), 
+							utilMain.BUFFEREDFILESIZE);		
+		} catch (FileNotFoundException e)
+		{
+			System.out.println("unable to find properties file "+filePath);
+			throw e;
+		}
+		return inStream;
+	}
+
+	/**
+	** Attempt to grab this test case.  
+	** Uses random number and the weight of this
+	** case to determine if the grab was successful.
+	** 
+	** @return true/false
+	*/
+	public synchronized boolean grab()
+	{
+		attempts++;
+		if (java.lang.Math.random() < weight)
+		{
+			iterations++;
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+
+	/**
+	** Run the test case.  Invokes IJ to do our
+	** dirty work.
+	*/
+	public void runMe(LocalizedOutput log, LocalizedOutput out, BufferedInputStream infile)
+	{
+		utilMain	utilInstance;
+        LocalizedInput is;
+        is = LocalizedResource.getInstance().getNewInput(infile);
+
+		LocalizedInput [] in = { is };
+	
+		out.println("--------------"+file+"-----------------");
+		utilInstance = new utilMain(1, out, ignoreErrors);
+		utilInstance.setMtUse(true);
+		utilInstance.go(in, out, (java.util.Properties) null);
+		log.flush();
+		out.flush();
+	}
+
+	public void updateURLProperties(Properties p, String newURLPrefix)
+	{
+		String[] propsToUpdate = {"ij.database", "ij.protocol",
+								  "database"};
+		for (int i = 0; i < propsToUpdate.length; i++)
+		{
+			String key = propsToUpdate[i];
+			String val = p.getProperty(key);
+			if (val != null)
+				p.setProperty(key,alterURL(val,newURLPrefix));
+		}
+	}
+
+
+	public String alterURL(String url, String newURLPrefix)
+	{
+		String urlPrefix = "jdbc:derby:";
+	
+		if (url.startsWith(newURLPrefix))
+			return url;
+
+		// If we don't have a URL prefix for this framework
+		// just return
+		if (newURLPrefix == null)
+			return url;
+	
+		if (url.equals(urlPrefix)) // Replace embedded
+			return newURLPrefix;
+
+		if (url.startsWith(urlPrefix))
+		{
+			// replace jdbc:derby: with our url:
+			url = newURLPrefix +
+				url.substring(urlPrefix.length());
+
+		}
+		else
+		{
+			if (! (url.startsWith("jdbc:")))
+	    {
+			url = newURLPrefix + url;
+	    }
+		}
+		//System.out.println("New url:" +url);
+		return url;
+    }
+  
+
+// NOTE: tried invoking ij directly, but had some problems,
+// so stick with calling utilMain().	
+//	/**
+//	** Run the test case.  Invokes IJ to do our
+//	** dirty work.
+//	*/
+//	public void runMe(AppStreamWriter log, AppStreamWriter out, BufferedInputStream infile)
+//	{
+//		ASCII_UCodeESC_CharStream charStream;
+//		ijTokenManager	ijTokMgr;
+//		ij	ijParser;
+//	
+//		
+//		out.println("--------------"+file+"-----------------");
+//		charStream = new ASCII_UCodeESC_CharStream(in, 1, 1);
+//		ijTokMgr = new ijTokenManager(charStream);
+//		ijParser = new ij(ijTokMgr, System.out, this);
+//		log.flush();
+//		out.flush();
+//	}
+
+	/**
+	** Name says it all
+	*/
+	public String toString()
+	{
+		return "name: "+name+
+				"\n\tfile: "+file+
+				"\n\tproperties: "+propFile+
+				"\n\tweight: "+weight+
+				"\n\tignoreErrors: "+ignoreErrors+
+				"\n\tdescription: "+description;
+	}
+
+	
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTestSuite.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTestSuite.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTestSuite.java	Fri Sep 24 10:33:20 2004
@@ -1,180 +1,180 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import java.util.Vector;
-import java.util.Enumeration;
-import java.util.Properties;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.lang.Math;
-
-/**
- */
-public class mtTestSuite
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-	private Vector cases;
-	private Vector last;
-	private Vector init;
-	private mtTime time;
-	private int numThreads;
-	private String rootDir = null;
-
-
-	mtTestSuite(int numThreads, mtTime time, 
-			Vector initCases, Vector testCases, Vector finalCases)
-	{
-		this.numThreads = numThreads;
-		this.time = time;
-		this.cases = testCases;
-		this.init = initCases;
-		this.last = finalCases;
-	}
-
-	public void init()
-	{
-		boolean loadInitFailed = loadCases(init);
-		boolean loadTestsFailed = loadCases(cases);
-		boolean loadLastFailed = loadCases(last);
-
-		if ((loadInitFailed == true) ||
-			(loadTestsFailed == true) ||
-			(loadLastFailed == true))
-		{
-			throw new Error("Initialization Error");
-		}
-	}
-
-	/**
-	** @return boolean indicates if there was a problem loading
-	** 	the file
-	*/
-	private boolean loadCases(Vector cases)
-	{
-		if (cases == null)
-			return false;
-
-		boolean gotError = false;
-		Enumeration e = cases.elements();
-		mtTestCase tcase;
- 
-		while (e.hasMoreElements())
-		{
-			tcase = (mtTestCase)e.nextElement();
-			try
-			{
-				tcase.initialize(rootDir);
-			}
-			catch (Throwable t)
-			{
-				gotError = true;
-			}
-		}
-
-		return gotError;
-	}
-
-	public void setRoot(String rootDir)
-	{
-		this.rootDir = rootDir;
-	}
-
-	public String getRoot()
-	{
-		return rootDir;
-	}
-
-	public int getNumThreads()
-	{
-		return numThreads;
-	}
-
-	public Vector getCases()
-	{
-		return cases;
-	}
-
-	public Vector getInitCases()
-	{
-		return init;
-	}
-
-	public Vector getFinalCases()
-	{
-		return last;
-	}
-
-	public mtTime getTime()
-	{
-		return time;
-	}
-
-	public long getTimeMillis()
-	{
-		return ((time.hours * 360) +
-				(time.minutes * 60) +
-				(time.seconds)) * 1000;
-	}
-
-	public String toString()
-	{
-		String str;
-		int	len;
-		int i;
-	
-		str = "TEST CASES\nNumber of Threads: "+numThreads;
-		str +="\nTime: "+time;
-		str +="\nNumber of Initializers: "+init.size()+"\n";
-		for (i = 0, len = init.size(); i < len; i++)
-		{
-			str += init.elementAt(i).toString() + "\n";
-		}
-
-		str +="\nNumber of Cases: "+cases.size()+"\n";
-		for (i = 0, len = cases.size(); i < len; i++)
-		{
-			str += cases.elementAt(i).toString() + "\n";
-		}
-
-		str +="\nNumber of Final Cases: "+last.size()+"\n";
-		for (i = 0, len = last.size(); i < len; i++)
-		{
-			str += last.elementAt(i).toString() + "\n";
-		}
-
-		return str;
-	}
-
-	/*
-	** Grab a test case.  Pick one randomly and
-	** try to grab that case.  If we get it we are
-	** done.  Otherwise, try try again.
-	*/
-	public mtTestCase grabTestCase() 
-	{
-		int numCases = cases.size();
-		int caseNum;
-		mtTestCase testCase;
-
-		do
-		{
-			caseNum = (int)((java.lang.Math.random() * 1311) % numCases);
-			testCase = (mtTestCase)cases.elementAt(caseNum);
-		}
-		while (testCase.grab() == false);
-	
-		return testCase;	
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.Math;
+
+/**
+ */
+public class mtTestSuite
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+	private Vector cases;
+	private Vector last;
+	private Vector init;
+	private mtTime time;
+	private int numThreads;
+	private String rootDir = null;
+
+
+	mtTestSuite(int numThreads, mtTime time, 
+			Vector initCases, Vector testCases, Vector finalCases)
+	{
+		this.numThreads = numThreads;
+		this.time = time;
+		this.cases = testCases;
+		this.init = initCases;
+		this.last = finalCases;
+	}
+
+	public void init()
+	{
+		boolean loadInitFailed = loadCases(init);
+		boolean loadTestsFailed = loadCases(cases);
+		boolean loadLastFailed = loadCases(last);
+
+		if ((loadInitFailed == true) ||
+			(loadTestsFailed == true) ||
+			(loadLastFailed == true))
+		{
+			throw new Error("Initialization Error");
+		}
+	}
+
+	/**
+	** @return boolean indicates if there was a problem loading
+	** 	the file
+	*/
+	private boolean loadCases(Vector cases)
+	{
+		if (cases == null)
+			return false;
+
+		boolean gotError = false;
+		Enumeration e = cases.elements();
+		mtTestCase tcase;
+ 
+		while (e.hasMoreElements())
+		{
+			tcase = (mtTestCase)e.nextElement();
+			try
+			{
+				tcase.initialize(rootDir);
+			}
+			catch (Throwable t)
+			{
+				gotError = true;
+			}
+		}
+
+		return gotError;
+	}
+
+	public void setRoot(String rootDir)
+	{
+		this.rootDir = rootDir;
+	}
+
+	public String getRoot()
+	{
+		return rootDir;
+	}
+
+	public int getNumThreads()
+	{
+		return numThreads;
+	}
+
+	public Vector getCases()
+	{
+		return cases;
+	}
+
+	public Vector getInitCases()
+	{
+		return init;
+	}
+
+	public Vector getFinalCases()
+	{
+		return last;
+	}
+
+	public mtTime getTime()
+	{
+		return time;
+	}
+
+	public long getTimeMillis()
+	{
+		return ((time.hours * 360) +
+				(time.minutes * 60) +
+				(time.seconds)) * 1000;
+	}
+
+	public String toString()
+	{
+		String str;
+		int	len;
+		int i;
+	
+		str = "TEST CASES\nNumber of Threads: "+numThreads;
+		str +="\nTime: "+time;
+		str +="\nNumber of Initializers: "+init.size()+"\n";
+		for (i = 0, len = init.size(); i < len; i++)
+		{
+			str += init.elementAt(i).toString() + "\n";
+		}
+
+		str +="\nNumber of Cases: "+cases.size()+"\n";
+		for (i = 0, len = cases.size(); i < len; i++)
+		{
+			str += cases.elementAt(i).toString() + "\n";
+		}
+
+		str +="\nNumber of Final Cases: "+last.size()+"\n";
+		for (i = 0, len = last.size(); i < len; i++)
+		{
+			str += last.elementAt(i).toString() + "\n";
+		}
+
+		return str;
+	}
+
+	/*
+	** Grab a test case.  Pick one randomly and
+	** try to grab that case.  If we get it we are
+	** done.  Otherwise, try try again.
+	*/
+	public mtTestCase grabTestCase() 
+	{
+		int numCases = cases.size();
+		int caseNum;
+		mtTestCase testCase;
+
+		do
+		{
+			caseNum = (int)((java.lang.Math.random() * 1311) % numCases);
+			testCase = (mtTestCase)cases.elementAt(caseNum);
+		}
+		while (testCase.grab() == false);
+	
+		return testCase;	
+	}
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTester.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTester.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTester.java	Fri Sep 24 10:33:20 2004
@@ -1,113 +1,113 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import java.util.Vector;
-import java.io.IOException;
-import java.io.FileNotFoundException;
-import java.io.BufferedInputStream;
-import java.util.Date;
-
-import org.apache.derby.iapi.tools.i18n.LocalizedOutput;
-
-/**
- * mtTester grabs test and runs them forever.
- * The spawner of tester is responsible for 
- * killing it.
- */
-public class mtTester implements Runnable
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-	private mtTestSuite	suite;
-	private String		name;
-	private LocalizedOutput	log;
-	private LocalizedOutput	out;
-	private boolean		stop = false;
-							
-	public mtTester(String name, mtTestSuite suite, LocalizedOutput out, LocalizedOutput log)
-	{ 
-		this.name = name;
-		this.suite = suite;
-		this.log = log;
-		this.out = out;
-		log.println("...initialized "+ name + " at " + new Date());
-	}
-
-	/**
-	** Run until killed or until there is a problem.
-	** If we get other than 'connection closed' we'll
-	** signal that we recieved a fatal error before
-	** quittiing; otherwise, we are silent.
-	*/
-	public void run()
-	{
-		int numIterations = 0;
-
-		try 
-		{
-			mtTestCase testCase;
-			BufferedInputStream	in;
-
-			// loop until we get an error or
-			// are killed.	
-			while (!stop)
-			{
-				numIterations++;
-				testCase = suite.grabTestCase();
-				try 
-				{
-					in = testCase.initialize(suite.getRoot());
-				} catch (FileNotFoundException e) 
-				{
-					System.out.println(e);
-					return;
-				}
-				catch (IOException e)
-				{
-					System.out.println(e);
-					return;
-				}
-	
-				log.println(name + ": "+ testCase.getName() + " " + new Date());
-				testCase.runMe(log, out, in);
-			}
-		}	
-		catch (ijFatalException e)
-		{
-
-			/*
-			** If we got connection closed (XJ010), we'll
-			** assume that we were deliberately killed
-			** via a Thread.stop() and it was caught by
-			** jbms.  Otherwise, we'll print out an
-			** error message.
-			*/
-			if (e.getSQLState() == null || !(e.getSQLState().equals("XJ010")))
-			{
-				log.println(name + ": TERMINATING due to unexpected error:\n"+e);
-				throw new ThreadDeath();
-			}
-		}
-		if (stop)
-		{
-			log.println(name + ": stopping on request after " + numIterations +
-						" iterations");
-		}
-	}
-
-	public void stop()
-	{
-		stop = true;
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import java.util.Vector;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.io.BufferedInputStream;
+import java.util.Date;
+
+import org.apache.derby.iapi.tools.i18n.LocalizedOutput;
+
+/**
+ * mtTester grabs test and runs them forever.
+ * The spawner of tester is responsible for 
+ * killing it.
+ */
+public class mtTester implements Runnable
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+	private mtTestSuite	suite;
+	private String		name;
+	private LocalizedOutput	log;
+	private LocalizedOutput	out;
+	private boolean		stop = false;
+							
+	public mtTester(String name, mtTestSuite suite, LocalizedOutput out, LocalizedOutput log)
+	{ 
+		this.name = name;
+		this.suite = suite;
+		this.log = log;
+		this.out = out;
+		log.println("...initialized "+ name + " at " + new Date());
+	}
+
+	/**
+	** Run until killed or until there is a problem.
+	** If we get other than 'connection closed' we'll
+	** signal that we recieved a fatal error before
+	** quittiing; otherwise, we are silent.
+	*/
+	public void run()
+	{
+		int numIterations = 0;
+
+		try 
+		{
+			mtTestCase testCase;
+			BufferedInputStream	in;
+
+			// loop until we get an error or
+			// are killed.	
+			while (!stop)
+			{
+				numIterations++;
+				testCase = suite.grabTestCase();
+				try 
+				{
+					in = testCase.initialize(suite.getRoot());
+				} catch (FileNotFoundException e) 
+				{
+					System.out.println(e);
+					return;
+				}
+				catch (IOException e)
+				{
+					System.out.println(e);
+					return;
+				}
+	
+				log.println(name + ": "+ testCase.getName() + " " + new Date());
+				testCase.runMe(log, out, in);
+			}
+		}	
+		catch (ijFatalException e)
+		{
+
+			/*
+			** If we got connection closed (XJ010), we'll
+			** assume that we were deliberately killed
+			** via a Thread.stop() and it was caught by
+			** jbms.  Otherwise, we'll print out an
+			** error message.
+			*/
+			if (e.getSQLState() == null || !(e.getSQLState().equals("XJ010")))
+			{
+				log.println(name + ": TERMINATING due to unexpected error:\n"+e);
+				throw new ThreadDeath();
+			}
+		}
+		if (stop)
+		{
+			log.println(name + ": stopping on request after " + numIterations +
+						" iterations");
+		}
+	}
+
+	public void stop()
+	{
+		stop = true;
+	}
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTime.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTime.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/mtTime.java	Fri Sep 24 10:33:20 2004
@@ -1,36 +1,36 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-/**
- */
-public class mtTime
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-	public int hours;
-	public int minutes;
-	public int seconds;
-
-	mtTime(int hours, int minutes, int seconds)
-	{ 
-		this.hours = hours;
-		this.minutes = minutes;
-		this.seconds = seconds;
-	}
-
-	public String toString()
-	{
-		return hours+":"+minutes+":"+seconds;
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+/**
+ */
+public class mtTime
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+	public int hours;
+	public int minutes;
+	public int seconds;
+
+	mtTime(int hours, int minutes, int seconds)
+	{ 
+		this.hours = hours;
+		this.minutes = minutes;
+		this.seconds = seconds;
+	}
+
+	public String toString()
+	{
+		return hours+":"+minutes+":"+seconds;
+	}
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/util.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/util.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/util.java	Fri Sep 24 10:33:20 2004
@@ -1,735 +1,735 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import org.apache.derby.tools.JDBCDisplayUtil;
-import org.apache.derby.iapi.tools.i18n.*;
-
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.io.IOException;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Statement;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.Types;
-
-import java.util.Properties;
-import java.util.Vector;
-import java.util.Stack;
-import java.math.BigDecimal;
-
-/**
-	Methods used to control setup for apps as
-	well as display some internal ij structures.
-
-	@see org.apache.derby.tools.JDBCDisplayUtil
-	@author ames
- */
-public class util implements java.security.PrivilegedAction {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-
-	private util() {}
-
-	//-----------------------------------------------------------------
-	// Methods for starting up JBMS
-
-	/**
-	 * Find the argument that follows the specified parameter.
-	 *
-	 *	@param param the parameter (e.g. "-p")
-	 *	@param args	the argument list to consider.
-	 *
-	 *	@return the argument that follows the parameter, or null if not found
-	 */
-	static public String getArg(String param, String[] args)
-	{
-		int pLocn;
-		Properties p;
-
-		if (args == null) return null;
-
-		for (pLocn=0; pLocn<args.length; pLocn++) {
-			if (param.equals(args[pLocn])) break;
-		}
-		if (pLocn >= (args.length-1))  // not found or no file
-			return null;
-
-		return args[pLocn+1];
-	}
-
-	/**
-		ij is started with "-p[r] file OtherArgs";
-		the file contains properties to control the driver and database
-		used to run ij, and can provide additional system properties.
-		<p>
-		getPropertyArg will look at the args and take out a "-p <file>" pair,
-		reading the file into the system properties.
-		<p>
-		If there was a -p without a following <file>, no action is taken.
-
-		@exception IOException thrown if file not found
-
-		@param args	the argument list to consider.
-		@return true if a property item was found and loaded.
-	 */
-	static public boolean getPropertyArg(String[] args) throws IOException {
-		String n;
-		InputStream in1;
-		Properties p;
-
-		if ((n = getArg("-p", args))!= null){
-			in1 = new FileInputStream(n);
-			in1 = new BufferedInputStream(in1);
-		}
-		else if ((n = getArg("-pr", args)) != null) {
-			in1 = getResourceAsStream(n);
-			if (in1 == null) throw ijException.resourceNotFound();
-		}
-		else
-			return false;
-
-		p = System.getProperties();
-
-		// Trim off excess whitespace in property file, if any, and
-		// then load those properties into 'p'.
-		util.loadWithTrimmedValues(in1, p);
-
-		return true;
-	}
-
-	/**
-		ij is started with "-ca[r] file OtherArgs";
-		the file contains connection attibute properties 
-		to pass to getConnection
-		<p>
-		getConnAttributeArg will look at the args and take out a 
-		"-ca[r] <file>" pair and returning the Properties
-		<p>
-
-		@exception IOException thrown if file not found
-
-		@param args	the argument list to consider.
-		@return  properties in the file
-	 */
-	static public Properties getConnAttributeArg(String[] args) 
-		throws IOException 
-	{
-		String n;
-		InputStream in1;
-		Properties p = new Properties();
-
-		if ((n = getArg("-ca", args))!= null){
-			in1 = new FileInputStream(n);
-			in1 = new BufferedInputStream(in1);
-		}
-		else if ((n = getArg("-car", args)) != null) {
-			in1 = getResourceAsStream(n);
-			if (in1 == null) throw ijException.resourceNotFound();
-		}
-		else
-			return null;
-
-		// Trim off excess whitespace in property file, if any, and
-		// then load those properties into 'p'.
-		util.loadWithTrimmedValues(in1, p);
-
-		return p;
-	}
-
-
-
-	/**
-	  Convenience routine to qualify a resource name with "ij.defaultPackageName"
-	  if it is not qualified (does not begin with a "/").
-
-	  @param absolute true means return null if the name is not absolute and false
-	  means return partial names. 
-	  */
-	static String qualifyResourceName(String resourceName, boolean absolute)
-	{
-		resourceName=resourceName.trim();
-		if (resourceName.startsWith("/"))
-		{
-			return resourceName;
-		}
-		else
-		{
-			String pName = util.getSystemProperty("ij.defaultResourcePackage").trim();
-			if (pName == null) return null;
-			if ((pName).endsWith("/"))
-				resourceName = pName+resourceName;
-			else
-				resourceName = pName+"/"+resourceName;
-			if (absolute && !resourceName.startsWith("/"))
-				return null;
-			else
-				return resourceName;
-		}
-	}
-	/**
-	  Convenience routine to get a resource as a BufferedInputStream. If the
-	  resourceName is not absolute (does not begin with a "/") this qualifies
-	  the name with the "ij.defaultResourcePackage" name.
-
-	  @param String the name of the resource
-	  @return a buffered stream for the resource if it exists and null otherwise.
-	  */
-	static public InputStream getResourceAsStream(String resourceName) 
-	{
-		Class c= util.class;
-		resourceName = qualifyResourceName(resourceName,true);
-		if (resourceName == null) 
-			return null;
-		InputStream is = c.getResourceAsStream(resourceName);
-		if (is != null) 
-			is = new BufferedInputStream(is, utilMain.BUFFEREDFILESIZE);
-		return is;
-	}
-
-	/**
-	  Return the name of the ij command file or null if none is
-	  specified. The command file may be proceeded with -f flag on
-	  the command line. Alternatively, the command file may be 
-	  specified without a -f flag. In this case we assume the first
-	  unknown argument is the command file.
-
-	  <P>
-	  This should only be called after calling invalidArgs.
-
-	  <p>
-	  If there is no such argument, a null is returned.
-
-	  @param args	the argument list to consider.
-	  @return the name of the first argument not preceded by "-p",
-	  null if none found.
-	  
-	  @exception IOException thrown if file not found
-	 */
-	static public String getFileArg(String[] args) throws IOException {
-		String fileName;
-		int fLocn;
-		boolean foundP = false;
-
-		if (args == null) return null;
-		if ((fileName=getArg("-f",args))!=null) return fileName;
-		//
-		//The first unknown arg is the file
-		for (int ix=0; ix < args.length; ix++)
-			if(args[ix].equals("-f")  ||
-			   args[ix].equals("-fr") ||
-			   args[ix].equals("-ca")  ||
-			   args[ix].equals("-car")  ||
-			   args[ix].equals("-p")  ||
-			   args[ix].equals("-pr"))
-				ix++; //skip the parameter to these args
-			else
-				return args[ix];
-		return null;
-	}
-
-	/**
-	  Return the name of a resource containing input commands or
-	  null iff none has been specified.
-	  */
- 	static public String getInputResourceNameArg(String[] args) {
-		return getArg("-fr", args);
-	}
-
-	/**
-	  Verify the ij line arguments command arguments.
-	  @return true if the args are invalid
-	  <UL>
-	  <LI>Only legal argument provided.
-	  <LI>Only specify a quantity once.
-	  </UL>
-	 */
-	static public boolean invalidArgs(String[] args, boolean gotProp, String file,
-									   String inputResourceName) {
-		int countSupported = 0;
-		boolean haveInput = false;
-		for (int ix=0; ix < args.length; ix++)
-		{
-			//
-			//If the arguemnt is a supported flag skip the flags argument
-			if(!haveInput && (args[ix].equals("-f") || args[ix].equals("-fr")))
-			{
-				haveInput = true;
-				ix++;
-				if (ix >= args.length) return true;
-			}
-
-			else if ((args[ix].equals("-p") || args[ix].equals("-pr") ||
-					  args[ix].equals("-ca") || args[ix].equals("-car") ))
-			{
-				// next arg is the file/resource name
-				ix++;
-				if (ix >= args.length) return true;
-			}
-
-
-			//
-			//Assume the first unknown arg is a file name.
-			else if (!haveInput)
-			{
-				haveInput = true;
-			}
-
-			else
-			{
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * print a usage message for invocations of main().
-	 */
-	static void Usage(LocalizedOutput out) {
-     	out.println(
-		LocalizedResource.getMessage("IJ_UsageJavaComCloudToolsIjPPropeInput"));
-		out.flush();
-   	}
-
-
-    private static final Class[] STRING_P = { "".getClass() };
-    private static final Class[] INT_P = { Integer.TYPE };
-
-
-    static public void setupDataSource(Object ds) throws Exception {
-	// Loop over set methods on Datasource object, if there is a property
-	// then call the method with corresponding value.
-	java.lang.reflect.Method[] methods = ds.getClass().getMethods();
-	for (int i = 0; i < methods.length; i++) {
-	    java.lang.reflect.Method m = methods[i];
-	    String name = m.getName();
-	    if (name.startsWith("set") && (name.length() > "set".length())) {
-		String property = name.substring("set".length()); // setXyyyZwww
-		property = "ij.dataSource."+property.substring(0,1).toLowerCase(java.util.Locale.ENGLISH)+ property.substring(1); // xyyyZwww
-		String value = util.getSystemProperty(property);
-		//System.out.println("setupDateSource: method="+name+" property="+property+" value="+((value==null)?"null":value));
-		if (value != null) {
-		    try {
-			// call string method
-			m.invoke(ds, new Object[] {value});
-		    } catch (Throwable ignore) {
-			// failed, assume it's an integer parameter
-			m.invoke(ds, new Object[] {Integer.valueOf(value)});
-		    }
-		}
-	    }
-	}
-    }
-
-	/**
-		This will look for the System properties "ij.driver" and "ij.database"
-		and return a java.sql.Connection if it successfully connects.
-		The deprecated driver and database properties are examined first.
-		<p>
-		If no connection was possible, it will return a null.
-		<p>
-		Failure to load the driver class is quietly ignored.
-
-		@param defaultDriver the driver to use if no property value found
-		@param defaultURL the database URL to use if no property value found
-		@param connInfo Connection attributes to pass to getConnection
-		@return a connection to the defaultURL if possible; null if not.
-		@exception SQLException on failure to connect.
-		@exception ClassNotFoundException on failure to load driver.
-		@exception InstantiationException on failure to load driver.
-		@exception IllegalAccessException on failure to load driver.
-	 */
-    static public Connection startJBMS(String defaultDriver, String defaultURL,
-				       Properties connInfo) 
-	throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException
-    {
-	Connection con = null;
-        String driverName;
-        String databaseURL;
-
-	// deprecate the non-ij prefix.  actually, we should defer to jdbc.drivers...
-        driverName = util.getSystemProperty("driver");
-        if (driverName == null) driverName = util.getSystemProperty("ij.driver");
-	if (driverName == null || driverName.length()==0) driverName = defaultDriver;
-        if (driverName != null) {
-	    util.loadDriver(driverName);
-	}
-
-	String jdbcProtocol = util.getSystemProperty("ij.protocol");
-	if (jdbcProtocol != null)
-	    util.loadDriverIfKnown(jdbcProtocol);
-
-	// deprecate the non-ij prefix name
-	databaseURL = util.getSystemProperty("database");
-	if (databaseURL == null) databaseURL = util.getSystemProperty("ij.database");
-	if (databaseURL == null || databaseURL.length()==0) databaseURL = defaultURL;
-	if (databaseURL != null) {
-	    // add protocol if might help find driver.
-	    boolean noDriver = false;
-	    try {
-		// if have full URL, load driver for it
-		if (databaseURL.startsWith("jdbc:"))
-		    util.loadDriverIfKnown(databaseURL);
-		DriverManager.getDriver(databaseURL);
-	    } catch (SQLException se) {
-		noDriver = true;
-	    }
-	    if (noDriver && jdbcProtocol != null)
-		databaseURL = jdbcProtocol+databaseURL;
-
-	    String user = util.getSystemProperty("ij.user");
-	    String password = util.getSystemProperty("ij.password");
-
-	    // Update connInfo for ij system properties and
-	    // framework network server
-
-	    connInfo = updateConnInfo(user, password,connInfo);
-
-	    // JDBC driver
-	    String driver = System.getProperty("driver");
-	    if (driver == null) {
-		driver = "org.apache.derby.jdbc.EmbeddedDriver";
-	    }
-
-	    // handle datasource property
-	    String dsName = System.getProperty("ij.dataSource");
-	    if (dsName == null) {
-		loadDriver(driver);
-		con = DriverManager.getConnection(databaseURL,connInfo);
-		return con;
-
-	    } else { // a datasource
-		// Get a new proxied connection through DataSource
-		Object ds = null; // really javax.sql.DataSource
-		try {
-		    Class dc = Class.forName(dsName);
-		    ds = dc.newInstance();
-		    
-		    // set datasource properties
-		    setupDataSource(ds);
-
-		    // Java method call "by hand" {  con = ds.getConnection(); }
-		    {
-			java.lang.reflect.Method m = dc.getMethod("getConnection", null); 
-			con = (java.sql.Connection) m.invoke(ds, new Object[] {});
-		    }
-		} catch (Throwable error) {
-		    error.printStackTrace(System.out);
-		}
-		return con;
-	    } // datasource
-	}
-	// failed
-	return null;
-    }
-
-
-	public static Properties updateConnInfo(String user, String password, Properties connInfo)
-	{
-		String framework = util.getSystemProperty("framework");
-		String ijGetMessages = util.getSystemProperty("ij.retrieveMessagesFromServerOnGetMessage");
-		boolean retrieveMessages = false;
-		
-		
-		// For JCC make sure we set it to retrieve messages
-		if (framework != null  && ((framework.equals("DB2jNet") 
-									|| framework.equals("DB2jcc"))))
-			retrieveMessages = true;
-		
-		if (ijGetMessages != null)
-		{
-			if (ijGetMessages.equals("false"))
-				retrieveMessages = false;
-			else
-				retrieveMessages = true;
-			
-		}
-		
-		if (connInfo == null)
-			connInfo = new Properties();
-		
-		if (retrieveMessages == true)
-		{
-			connInfo.put("retrieveMessagesFromServerOnGetMessage",
-						 "true");
-		}
-		if (user != null)
-			connInfo.put("user",user);
-		if (password != null)
-			connInfo.put("password", password);
-		
-		return connInfo;
-	}
-
-	/**
-		Utility interface that defaults driver and database to null.
-
-		@return a connection to the defaultURL if possible; null if not.
-		@exception SQLException on failure to connect.
-		@exception ClassNotFoundException on failure to load driver.
-		@exception InstantiationException on failure to load driver.
-		@exception IllegalAccessException on failure to load driver.
-	 */
-    static public Connection startJBMS() throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {
-		return startJBMS(null,null);
-	}
-	
-	/**
-	   Utility interface that defaults connInfo to null
-	   <p>
-
-
-		@param defaultDriver the driver to use if no property value found
-		@param defaultURL the database URL to use if no property value found
-		@return a connection to the defaultURL if possible; null if not.
-		@exception SQLException on failure to connect.
-		@exception ClassNotFoundException on failure to load driver.
-		@exception InstantiationException on failure to load driver.
-		@exception IllegalAccessException on failure to load driver.
-	 */
-    static public Connection startJBMS(String defaultDriver, String defaultURL) 
-			throws SQLException, ClassNotFoundException, InstantiationException,
-				   IllegalAccessException {
-		return startJBMS(defaultDriver,defaultURL,null);
-		
-	}
-	//-----------------------------------------------------------------
-	// Methods for displaying and checking results
-	// See org.apache.derby.tools.JDBCDisplayUtil for more general displays.
-
-
-	/**
-		Display a vector of strings to the out stream.
-	 */
-	public static void DisplayVector(LocalizedOutput out, Vector v) {
-		int l = v.size();
-		for (int i=0;i<l;i++)
-			out.println(v.elementAt(i));
-	}
-
-	/**
-		Display a vector of statements to the out stream.
-	public static void DisplayVector(AppStreamWriter out, Vector v, Connection conn) throws SQLException {
-		int l = v.size();
-AppUI.out.println("SIZE="+l);
-		for (int i=0;i<l;i++) {
-			Object o = v.elementAt(i);
-			if (o instanceof Integer) { // update count
-				JDBCDisplayUtil.DisplayUpdateCount(out,((Integer)o).intValue());
-			} else { // o instanceof ResultSet
-			    JDBCDisplayUtil.DisplayResults(out,(ResultSet)o,conn);
-				((ResultSet)o).close(); // release the result set
-			}
-		}
-	}
-	 */
-
-	/**
-		Display a statement that takes parameters by
-		stuffing it with rows from the result set and
-		displaying each result each time through.
-		Deal with autocommit behavior along the way.
-
-		@exception SQLException thrown on db error
-		@exception ijException thrown on ij error
-	 */
-	public static void DisplayMulti(LocalizedOutput out, PreparedStatement ps,
-		ResultSet rs, Connection conn) throws SQLException, ijException {
-
-		boolean autoCommited = false; // mark if autocommit in place
-		boolean exec = false; // mark the first time through
-		boolean anotherUsingRow = false;	// remember if there's another row 
-											// from using.
-		ResultSetMetaData rsmd = rs.getMetaData();
-		int numCols = rsmd.getColumnCount();
-
-		/* NOTE: We need to close the USING RS first
-		 * so that RunTimeStatistic gets info from
-		 * the user query.
-		 */
-		anotherUsingRow = rs.next();
-
-		while (! autoCommited && anotherUsingRow) {
-			// note the first time through
-			if (!exec) {
-				exec = true;
-
-				// send a warning if additional results may be lost
-				if (conn.getAutoCommit()) {
-					out.println(LocalizedResource.getMessage("IJ_IjWarniAutocMayCloseUsingResulSet"));
-					autoCommited = true;
-				}
-			}
-
-			// We need to make sure we pass along the scale, because
-			// setObject assumes a scale of zero (beetle 4365)
-			for (int c=1; c<=numCols; c++) {
-				ps.setObject(c,rs.getObject(c),
-					 rsmd.getColumnType(c),
-					 rsmd.getScale(c));
-			}
-
-
-			// Advance in the USING RS
-			anotherUsingRow = rs.next();
-			// Close the USING RS when exhausted and appropriate
-			// NOTE: Close before the user query
-			if (! anotherUsingRow || conn.getAutoCommit()) //if no more rows or if auto commit is on, close the resultset
-			{
-				rs.close();
-			}
-
-			/*
-				4. execute the statement against those parameters
-			 */
-
-			ps.execute();
-			JDBCDisplayUtil.DisplayResults(out,ps,conn);
-
-			/*
-				5. clear the parameters
-			 */
-			ps.clearParameters();
-		}
-		if (!exec) {
-			rs.close(); //this means, using clause didn't qualify any rows. Just close the resultset associated with using clause
-			throw ijException.noUsingResults();
-		}
-		// REMIND: any way to look for more rsUsing rows if autoCommit?
-		// perhaps just document the behavior... 
-	}
-
-	public static final String getSystemProperty(String propertyName) {
-		try
-		{
-			if (propertyName.startsWith("ij.") || propertyName.startsWith("derby."))
-			{
-				util u = new util();
-				u.key = propertyName;
-				return (String) java.security.AccessController.doPrivileged(u);
-			}
-			else
-			{
-				return System.getProperty(propertyName);
-			}
-		} catch (SecurityException se) {
-			return null;
-		}
-	}
-
-	private String key;
-
-	public final Object run() {
-		return System.getProperty(key);
-	}
-	/** 
-	 * Read a set of properties from the received input stream, strip
-	 * off any excess white space that exists in those property values,
-	 * and then add those newly-read properties to the received
-	 * Properties object; not explicitly removing the whitespace here can
-	 * lead to problems.
-	 *
-	 * This method exists because of the manner in which the jvm reads
-	 * properties from file--extra spaces are ignored after a _key_, but
-	 * if they exist at the _end_ of a property decl line (i.e. as part
-	 * of a _value_), they are preserved, as outlined in the Java API:
-	 *
-	 * "Any whitespace after the key is skipped; if the first non-
-	 * whitespace character after the key is = or :, then it is ignored
- 	 * and any whitespace characters after it are also skipped. All
-	 * remaining characters on the line become part of the associated
-	 * element string."
-	 *
-	 * @param iStr: An input stream from which the new properties are to be
-	 *  loaded (should already be initialized).
-	 * @param prop: A set of properties to which the properties from
-	 *  iStr will be added (should already be initialized).
-	 * @return A final properties set consisting of 'prop' plus all
-	 * properties loaded from 'iStr' (with the extra whitespace (if any)
-	 *  removed from all values), will be returned via the parameter.
-	 *
-		Copied here to avoid dependency on an engine class.
-	 **/
-	private static void loadWithTrimmedValues(InputStream iStr,
-		Properties prop) throws IOException {
-
-		// load the properties from the received input stream.
-		Properties p = new Properties();
-		p.load(iStr);
-
-		// Now, trim off any excess whitespace, if any, and then
-		// add the properties from file to the received Properties
-		// set.
-		for (java.util.Enumeration propKeys = p.propertyNames();
-		  propKeys.hasMoreElements();) {
-		// get the value, trim off the whitespace, then store it
-		// in the received properties object.
-			String tmpKey = (String)propKeys.nextElement();
-			String tmpValue = p.getProperty(tmpKey);
-			tmpValue = tmpValue.trim();
-			prop.put(tmpKey, tmpValue);
-		}
-
-		return;
-
-	}
-
-	private static final String[][] protocolDrivers =
-		{
-		  { "jdbc:derby:net:",			"com.ibm.db2.jcc.DB2Driver"},
-		  { "jdbc:derby:",				"org.apache.derby.jdbc.EmbeddedDriver" },
-		};
-
-	/**
-		Find the appropriate driver and load it, given a JDBC URL.
-		No action if no driver known for a given URL.
-
-		@param jdbcProtocol the protocol to try.
-
-		@exception ClassNotFoundException if unable to
-			locate class for driver.
-		@exception InstantiationException if unable to
-			create an instance.
-		@exception IllegalAccessException if driver class constructor not visible.
-	 */
-	public static void loadDriverIfKnown(String jdbcProtocol) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
-		for (int i=0; i < protocolDrivers.length; i++) {
-			if (jdbcProtocol.startsWith(protocolDrivers[i][0])) {
-				loadDriver(protocolDrivers[i][1]);
-				break; // only want the first one
-			}
-		}
-	}
-
-	/**
-		Load a driver given a class name.
-
-		@exception ClassNotFoundException if unable to
-			locate class for driver.
-		@exception InstantiationException if unable to
-			create an instance.
-		@exception IllegalAccessException if driver class constructor not visible.
-	 */
-	public static void loadDriver(String driverClass) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
-        Class.forName(driverClass).newInstance();
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import org.apache.derby.tools.JDBCDisplayUtil;
+import org.apache.derby.iapi.tools.i18n.*;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.IOException;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.Types;
+
+import java.util.Properties;
+import java.util.Vector;
+import java.util.Stack;
+import java.math.BigDecimal;
+
+/**
+	Methods used to control setup for apps as
+	well as display some internal ij structures.
+
+	@see org.apache.derby.tools.JDBCDisplayUtil
+	@author ames
+ */
+public class util implements java.security.PrivilegedAction {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+
+	private util() {}
+
+	//-----------------------------------------------------------------
+	// Methods for starting up JBMS
+
+	/**
+	 * Find the argument that follows the specified parameter.
+	 *
+	 *	@param param the parameter (e.g. "-p")
+	 *	@param args	the argument list to consider.
+	 *
+	 *	@return the argument that follows the parameter, or null if not found
+	 */
+	static public String getArg(String param, String[] args)
+	{
+		int pLocn;
+		Properties p;
+
+		if (args == null) return null;
+
+		for (pLocn=0; pLocn<args.length; pLocn++) {
+			if (param.equals(args[pLocn])) break;
+		}
+		if (pLocn >= (args.length-1))  // not found or no file
+			return null;
+
+		return args[pLocn+1];
+	}
+
+	/**
+		ij is started with "-p[r] file OtherArgs";
+		the file contains properties to control the driver and database
+		used to run ij, and can provide additional system properties.
+		<p>
+		getPropertyArg will look at the args and take out a "-p <file>" pair,
+		reading the file into the system properties.
+		<p>
+		If there was a -p without a following <file>, no action is taken.
+
+		@exception IOException thrown if file not found
+
+		@param args	the argument list to consider.
+		@return true if a property item was found and loaded.
+	 */
+	static public boolean getPropertyArg(String[] args) throws IOException {
+		String n;
+		InputStream in1;
+		Properties p;
+
+		if ((n = getArg("-p", args))!= null){
+			in1 = new FileInputStream(n);
+			in1 = new BufferedInputStream(in1);
+		}
+		else if ((n = getArg("-pr", args)) != null) {
+			in1 = getResourceAsStream(n);
+			if (in1 == null) throw ijException.resourceNotFound();
+		}
+		else
+			return false;
+
+		p = System.getProperties();
+
+		// Trim off excess whitespace in property file, if any, and
+		// then load those properties into 'p'.
+		util.loadWithTrimmedValues(in1, p);
+
+		return true;
+	}
+
+	/**
+		ij is started with "-ca[r] file OtherArgs";
+		the file contains connection attibute properties 
+		to pass to getConnection
+		<p>
+		getConnAttributeArg will look at the args and take out a 
+		"-ca[r] <file>" pair and returning the Properties
+		<p>
+
+		@exception IOException thrown if file not found
+
+		@param args	the argument list to consider.
+		@return  properties in the file
+	 */
+	static public Properties getConnAttributeArg(String[] args) 
+		throws IOException 
+	{
+		String n;
+		InputStream in1;
+		Properties p = new Properties();
+
+		if ((n = getArg("-ca", args))!= null){
+			in1 = new FileInputStream(n);
+			in1 = new BufferedInputStream(in1);
+		}
+		else if ((n = getArg("-car", args)) != null) {
+			in1 = getResourceAsStream(n);
+			if (in1 == null) throw ijException.resourceNotFound();
+		}
+		else
+			return null;
+
+		// Trim off excess whitespace in property file, if any, and
+		// then load those properties into 'p'.
+		util.loadWithTrimmedValues(in1, p);
+
+		return p;
+	}
+
+
+
+	/**
+	  Convenience routine to qualify a resource name with "ij.defaultPackageName"
+	  if it is not qualified (does not begin with a "/").
+
+	  @param absolute true means return null if the name is not absolute and false
+	  means return partial names. 
+	  */
+	static String qualifyResourceName(String resourceName, boolean absolute)
+	{
+		resourceName=resourceName.trim();
+		if (resourceName.startsWith("/"))
+		{
+			return resourceName;
+		}
+		else
+		{
+			String pName = util.getSystemProperty("ij.defaultResourcePackage").trim();
+			if (pName == null) return null;
+			if ((pName).endsWith("/"))
+				resourceName = pName+resourceName;
+			else
+				resourceName = pName+"/"+resourceName;
+			if (absolute && !resourceName.startsWith("/"))
+				return null;
+			else
+				return resourceName;
+		}
+	}
+	/**
+	  Convenience routine to get a resource as a BufferedInputStream. If the
+	  resourceName is not absolute (does not begin with a "/") this qualifies
+	  the name with the "ij.defaultResourcePackage" name.
+
+	  @param String the name of the resource
+	  @return a buffered stream for the resource if it exists and null otherwise.
+	  */
+	static public InputStream getResourceAsStream(String resourceName) 
+	{
+		Class c= util.class;
+		resourceName = qualifyResourceName(resourceName,true);
+		if (resourceName == null) 
+			return null;
+		InputStream is = c.getResourceAsStream(resourceName);
+		if (is != null) 
+			is = new BufferedInputStream(is, utilMain.BUFFEREDFILESIZE);
+		return is;
+	}
+
+	/**
+	  Return the name of the ij command file or null if none is
+	  specified. The command file may be proceeded with -f flag on
+	  the command line. Alternatively, the command file may be 
+	  specified without a -f flag. In this case we assume the first
+	  unknown argument is the command file.
+
+	  <P>
+	  This should only be called after calling invalidArgs.
+
+	  <p>
+	  If there is no such argument, a null is returned.
+
+	  @param args	the argument list to consider.
+	  @return the name of the first argument not preceded by "-p",
+	  null if none found.
+	  
+	  @exception IOException thrown if file not found
+	 */
+	static public String getFileArg(String[] args) throws IOException {
+		String fileName;
+		int fLocn;
+		boolean foundP = false;
+
+		if (args == null) return null;
+		if ((fileName=getArg("-f",args))!=null) return fileName;
+		//
+		//The first unknown arg is the file
+		for (int ix=0; ix < args.length; ix++)
+			if(args[ix].equals("-f")  ||
+			   args[ix].equals("-fr") ||
+			   args[ix].equals("-ca")  ||
+			   args[ix].equals("-car")  ||
+			   args[ix].equals("-p")  ||
+			   args[ix].equals("-pr"))
+				ix++; //skip the parameter to these args
+			else
+				return args[ix];
+		return null;
+	}
+
+	/**
+	  Return the name of a resource containing input commands or
+	  null iff none has been specified.
+	  */
+ 	static public String getInputResourceNameArg(String[] args) {
+		return getArg("-fr", args);
+	}
+
+	/**
+	  Verify the ij line arguments command arguments.
+	  @return true if the args are invalid
+	  <UL>
+	  <LI>Only legal argument provided.
+	  <LI>Only specify a quantity once.
+	  </UL>
+	 */
+	static public boolean invalidArgs(String[] args, boolean gotProp, String file,
+									   String inputResourceName) {
+		int countSupported = 0;
+		boolean haveInput = false;
+		for (int ix=0; ix < args.length; ix++)
+		{
+			//
+			//If the arguemnt is a supported flag skip the flags argument
+			if(!haveInput && (args[ix].equals("-f") || args[ix].equals("-fr")))
+			{
+				haveInput = true;
+				ix++;
+				if (ix >= args.length) return true;
+			}
+
+			else if ((args[ix].equals("-p") || args[ix].equals("-pr") ||
+					  args[ix].equals("-ca") || args[ix].equals("-car") ))
+			{
+				// next arg is the file/resource name
+				ix++;
+				if (ix >= args.length) return true;
+			}
+
+
+			//
+			//Assume the first unknown arg is a file name.
+			else if (!haveInput)
+			{
+				haveInput = true;
+			}
+
+			else
+			{
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * print a usage message for invocations of main().
+	 */
+	static void Usage(LocalizedOutput out) {
+     	out.println(
+		LocalizedResource.getMessage("IJ_UsageJavaComCloudToolsIjPPropeInput"));
+		out.flush();
+   	}
+
+
+    private static final Class[] STRING_P = { "".getClass() };
+    private static final Class[] INT_P = { Integer.TYPE };
+
+
+    static public void setupDataSource(Object ds) throws Exception {
+	// Loop over set methods on Datasource object, if there is a property
+	// then call the method with corresponding value.
+	java.lang.reflect.Method[] methods = ds.getClass().getMethods();
+	for (int i = 0; i < methods.length; i++) {
+	    java.lang.reflect.Method m = methods[i];
+	    String name = m.getName();
+	    if (name.startsWith("set") && (name.length() > "set".length())) {
+		String property = name.substring("set".length()); // setXyyyZwww
+		property = "ij.dataSource."+property.substring(0,1).toLowerCase(java.util.Locale.ENGLISH)+ property.substring(1); // xyyyZwww
+		String value = util.getSystemProperty(property);
+		//System.out.println("setupDateSource: method="+name+" property="+property+" value="+((value==null)?"null":value));
+		if (value != null) {
+		    try {
+			// call string method
+			m.invoke(ds, new Object[] {value});
+		    } catch (Throwable ignore) {
+			// failed, assume it's an integer parameter
+			m.invoke(ds, new Object[] {Integer.valueOf(value)});
+		    }
+		}
+	    }
+	}
+    }
+
+	/**
+		This will look for the System properties "ij.driver" and "ij.database"
+		and return a java.sql.Connection if it successfully connects.
+		The deprecated driver and database properties are examined first.
+		<p>
+		If no connection was possible, it will return a null.
+		<p>
+		Failure to load the driver class is quietly ignored.
+
+		@param defaultDriver the driver to use if no property value found
+		@param defaultURL the database URL to use if no property value found
+		@param connInfo Connection attributes to pass to getConnection
+		@return a connection to the defaultURL if possible; null if not.
+		@exception SQLException on failure to connect.
+		@exception ClassNotFoundException on failure to load driver.
+		@exception InstantiationException on failure to load driver.
+		@exception IllegalAccessException on failure to load driver.
+	 */
+    static public Connection startJBMS(String defaultDriver, String defaultURL,
+				       Properties connInfo) 
+	throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException
+    {
+	Connection con = null;
+        String driverName;
+        String databaseURL;
+
+	// deprecate the non-ij prefix.  actually, we should defer to jdbc.drivers...
+        driverName = util.getSystemProperty("driver");
+        if (driverName == null) driverName = util.getSystemProperty("ij.driver");
+	if (driverName == null || driverName.length()==0) driverName = defaultDriver;
+        if (driverName != null) {
+	    util.loadDriver(driverName);
+	}
+
+	String jdbcProtocol = util.getSystemProperty("ij.protocol");
+	if (jdbcProtocol != null)
+	    util.loadDriverIfKnown(jdbcProtocol);
+
+	// deprecate the non-ij prefix name
+	databaseURL = util.getSystemProperty("database");
+	if (databaseURL == null) databaseURL = util.getSystemProperty("ij.database");
+	if (databaseURL == null || databaseURL.length()==0) databaseURL = defaultURL;
+	if (databaseURL != null) {
+	    // add protocol if might help find driver.
+	    boolean noDriver = false;
+	    try {
+		// if have full URL, load driver for it
+		if (databaseURL.startsWith("jdbc:"))
+		    util.loadDriverIfKnown(databaseURL);
+		DriverManager.getDriver(databaseURL);
+	    } catch (SQLException se) {
+		noDriver = true;
+	    }
+	    if (noDriver && jdbcProtocol != null)
+		databaseURL = jdbcProtocol+databaseURL;
+
+	    String user = util.getSystemProperty("ij.user");
+	    String password = util.getSystemProperty("ij.password");
+
+	    // Update connInfo for ij system properties and
+	    // framework network server
+
+	    connInfo = updateConnInfo(user, password,connInfo);
+
+	    // JDBC driver
+	    String driver = System.getProperty("driver");
+	    if (driver == null) {
+		driver = "org.apache.derby.jdbc.EmbeddedDriver";
+	    }
+
+	    // handle datasource property
+	    String dsName = System.getProperty("ij.dataSource");
+	    if (dsName == null) {
+		loadDriver(driver);
+		con = DriverManager.getConnection(databaseURL,connInfo);
+		return con;
+
+	    } else { // a datasource
+		// Get a new proxied connection through DataSource
+		Object ds = null; // really javax.sql.DataSource
+		try {
+		    Class dc = Class.forName(dsName);
+		    ds = dc.newInstance();
+		    
+		    // set datasource properties
+		    setupDataSource(ds);
+
+		    // Java method call "by hand" {  con = ds.getConnection(); }
+		    {
+			java.lang.reflect.Method m = dc.getMethod("getConnection", null); 
+			con = (java.sql.Connection) m.invoke(ds, new Object[] {});
+		    }
+		} catch (Throwable error) {
+		    error.printStackTrace(System.out);
+		}
+		return con;
+	    } // datasource
+	}
+	// failed
+	return null;
+    }
+
+
+	public static Properties updateConnInfo(String user, String password, Properties connInfo)
+	{
+		String framework = util.getSystemProperty("framework");
+		String ijGetMessages = util.getSystemProperty("ij.retrieveMessagesFromServerOnGetMessage");
+		boolean retrieveMessages = false;
+		
+		
+		// For JCC make sure we set it to retrieve messages
+		if (framework != null  && ((framework.equals("DB2jNet") 
+									|| framework.equals("DB2jcc"))))
+			retrieveMessages = true;
+		
+		if (ijGetMessages != null)
+		{
+			if (ijGetMessages.equals("false"))
+				retrieveMessages = false;
+			else
+				retrieveMessages = true;
+			
+		}
+		
+		if (connInfo == null)
+			connInfo = new Properties();
+		
+		if (retrieveMessages == true)
+		{
+			connInfo.put("retrieveMessagesFromServerOnGetMessage",
+						 "true");
+		}
+		if (user != null)
+			connInfo.put("user",user);
+		if (password != null)
+			connInfo.put("password", password);
+		
+		return connInfo;
+	}
+
+	/**
+		Utility interface that defaults driver and database to null.
+
+		@return a connection to the defaultURL if possible; null if not.
+		@exception SQLException on failure to connect.
+		@exception ClassNotFoundException on failure to load driver.
+		@exception InstantiationException on failure to load driver.
+		@exception IllegalAccessException on failure to load driver.
+	 */
+    static public Connection startJBMS() throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {
+		return startJBMS(null,null);
+	}
+	
+	/**
+	   Utility interface that defaults connInfo to null
+	   <p>
+
+
+		@param defaultDriver the driver to use if no property value found
+		@param defaultURL the database URL to use if no property value found
+		@return a connection to the defaultURL if possible; null if not.
+		@exception SQLException on failure to connect.
+		@exception ClassNotFoundException on failure to load driver.
+		@exception InstantiationException on failure to load driver.
+		@exception IllegalAccessException on failure to load driver.
+	 */
+    static public Connection startJBMS(String defaultDriver, String defaultURL) 
+			throws SQLException, ClassNotFoundException, InstantiationException,
+				   IllegalAccessException {
+		return startJBMS(defaultDriver,defaultURL,null);
+		
+	}
+	//-----------------------------------------------------------------
+	// Methods for displaying and checking results
+	// See org.apache.derby.tools.JDBCDisplayUtil for more general displays.
+
+
+	/**
+		Display a vector of strings to the out stream.
+	 */
+	public static void DisplayVector(LocalizedOutput out, Vector v) {
+		int l = v.size();
+		for (int i=0;i<l;i++)
+			out.println(v.elementAt(i));
+	}
+
+	/**
+		Display a vector of statements to the out stream.
+	public static void DisplayVector(AppStreamWriter out, Vector v, Connection conn) throws SQLException {
+		int l = v.size();
+AppUI.out.println("SIZE="+l);
+		for (int i=0;i<l;i++) {
+			Object o = v.elementAt(i);
+			if (o instanceof Integer) { // update count
+				JDBCDisplayUtil.DisplayUpdateCount(out,((Integer)o).intValue());
+			} else { // o instanceof ResultSet
+			    JDBCDisplayUtil.DisplayResults(out,(ResultSet)o,conn);
+				((ResultSet)o).close(); // release the result set
+			}
+		}
+	}
+	 */
+
+	/**
+		Display a statement that takes parameters by
+		stuffing it with rows from the result set and
+		displaying each result each time through.
+		Deal with autocommit behavior along the way.
+
+		@exception SQLException thrown on db error
+		@exception ijException thrown on ij error
+	 */
+	public static void DisplayMulti(LocalizedOutput out, PreparedStatement ps,
+		ResultSet rs, Connection conn) throws SQLException, ijException {
+
+		boolean autoCommited = false; // mark if autocommit in place
+		boolean exec = false; // mark the first time through
+		boolean anotherUsingRow = false;	// remember if there's another row 
+											// from using.
+		ResultSetMetaData rsmd = rs.getMetaData();
+		int numCols = rsmd.getColumnCount();
+
+		/* NOTE: We need to close the USING RS first
+		 * so that RunTimeStatistic gets info from
+		 * the user query.
+		 */
+		anotherUsingRow = rs.next();
+
+		while (! autoCommited && anotherUsingRow) {
+			// note the first time through
+			if (!exec) {
+				exec = true;
+
+				// send a warning if additional results may be lost
+				if (conn.getAutoCommit()) {
+					out.println(LocalizedResource.getMessage("IJ_IjWarniAutocMayCloseUsingResulSet"));
+					autoCommited = true;
+				}
+			}
+
+			// We need to make sure we pass along the scale, because
+			// setObject assumes a scale of zero (beetle 4365)
+			for (int c=1; c<=numCols; c++) {
+				ps.setObject(c,rs.getObject(c),
+					 rsmd.getColumnType(c),
+					 rsmd.getScale(c));
+			}
+
+
+			// Advance in the USING RS
+			anotherUsingRow = rs.next();
+			// Close the USING RS when exhausted and appropriate
+			// NOTE: Close before the user query
+			if (! anotherUsingRow || conn.getAutoCommit()) //if no more rows or if auto commit is on, close the resultset
+			{
+				rs.close();
+			}
+
+			/*
+				4. execute the statement against those parameters
+			 */
+
+			ps.execute();
+			JDBCDisplayUtil.DisplayResults(out,ps,conn);
+
+			/*
+				5. clear the parameters
+			 */
+			ps.clearParameters();
+		}
+		if (!exec) {
+			rs.close(); //this means, using clause didn't qualify any rows. Just close the resultset associated with using clause
+			throw ijException.noUsingResults();
+		}
+		// REMIND: any way to look for more rsUsing rows if autoCommit?
+		// perhaps just document the behavior... 
+	}
+
+	public static final String getSystemProperty(String propertyName) {
+		try
+		{
+			if (propertyName.startsWith("ij.") || propertyName.startsWith("derby."))
+			{
+				util u = new util();
+				u.key = propertyName;
+				return (String) java.security.AccessController.doPrivileged(u);
+			}
+			else
+			{
+				return System.getProperty(propertyName);
+			}
+		} catch (SecurityException se) {
+			return null;
+		}
+	}
+
+	private String key;
+
+	public final Object run() {
+		return System.getProperty(key);
+	}
+	/** 
+	 * Read a set of properties from the received input stream, strip
+	 * off any excess white space that exists in those property values,
+	 * and then add those newly-read properties to the received
+	 * Properties object; not explicitly removing the whitespace here can
+	 * lead to problems.
+	 *
+	 * This method exists because of the manner in which the jvm reads
+	 * properties from file--extra spaces are ignored after a _key_, but
+	 * if they exist at the _end_ of a property decl line (i.e. as part
+	 * of a _value_), they are preserved, as outlined in the Java API:
+	 *
+	 * "Any whitespace after the key is skipped; if the first non-
+	 * whitespace character after the key is = or :, then it is ignored
+ 	 * and any whitespace characters after it are also skipped. All
+	 * remaining characters on the line become part of the associated
+	 * element string."
+	 *
+	 * @param iStr: An input stream from which the new properties are to be
+	 *  loaded (should already be initialized).
+	 * @param prop: A set of properties to which the properties from
+	 *  iStr will be added (should already be initialized).
+	 * @return A final properties set consisting of 'prop' plus all
+	 * properties loaded from 'iStr' (with the extra whitespace (if any)
+	 *  removed from all values), will be returned via the parameter.
+	 *
+		Copied here to avoid dependency on an engine class.
+	 **/
+	private static void loadWithTrimmedValues(InputStream iStr,
+		Properties prop) throws IOException {
+
+		// load the properties from the received input stream.
+		Properties p = new Properties();
+		p.load(iStr);
+
+		// Now, trim off any excess whitespace, if any, and then
+		// add the properties from file to the received Properties
+		// set.
+		for (java.util.Enumeration propKeys = p.propertyNames();
+		  propKeys.hasMoreElements();) {
+		// get the value, trim off the whitespace, then store it
+		// in the received properties object.
+			String tmpKey = (String)propKeys.nextElement();
+			String tmpValue = p.getProperty(tmpKey);
+			tmpValue = tmpValue.trim();
+			prop.put(tmpKey, tmpValue);
+		}
+
+		return;
+
+	}
+
+	private static final String[][] protocolDrivers =
+		{
+		  { "jdbc:derby:net:",			"com.ibm.db2.jcc.DB2Driver"},
+		  { "jdbc:derby:",				"org.apache.derby.jdbc.EmbeddedDriver" },
+		};
+
+	/**
+		Find the appropriate driver and load it, given a JDBC URL.
+		No action if no driver known for a given URL.
+
+		@param jdbcProtocol the protocol to try.
+
+		@exception ClassNotFoundException if unable to
+			locate class for driver.
+		@exception InstantiationException if unable to
+			create an instance.
+		@exception IllegalAccessException if driver class constructor not visible.
+	 */
+	public static void loadDriverIfKnown(String jdbcProtocol) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+		for (int i=0; i < protocolDrivers.length; i++) {
+			if (jdbcProtocol.startsWith(protocolDrivers[i][0])) {
+				loadDriver(protocolDrivers[i][1]);
+				break; // only want the first one
+			}
+		}
+	}
+
+	/**
+		Load a driver given a class name.
+
+		@exception ClassNotFoundException if unable to
+			locate class for driver.
+		@exception InstantiationException if unable to
+			create an instance.
+		@exception IllegalAccessException if driver class constructor not visible.
+	 */
+	public static void loadDriver(String driverClass) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+        Class.forName(driverClass).newInstance();
+	}
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/utilMain.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/utilMain.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/utilMain.java	Fri Sep 24 10:33:20 2004
@@ -1,929 +1,929 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-                
-import org.apache.derby.iapi.reference.JDBC20Translation;
-import org.apache.derby.iapi.reference.JDBC30Translation;
-
-import org.apache.derby.tools.JDBCDisplayUtil;
-import org.apache.derby.iapi.tools.i18n.*;
-
-import org.apache.derby.iapi.services.info.ProductVersionHolder;
-import org.apache.derby.iapi.services.info.ProductGenusNames;
-
-import org.apache.derby.iapi.error.PublicAPI;
-import org.apache.derby.iapi.error.StandardException;
-
-import java.util.Stack;
-import java.util.Hashtable;
-import java.util.Properties;
-
-import java.io.InputStream;
-import java.io.FileInputStream;
-import java.io.BufferedInputStream;
-import java.io.FileNotFoundException;
-import java.io.StringReader;
-import java.sql.DriverManager;
-import java.sql.Driver;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.ResultSet;
-import java.sql.Statement;
-import java.sql.PreparedStatement;
-
-import java.lang.reflect.*;
-
-/**
-	This class is utilities specific to the two ij Main's.
-	This factoring enables sharing the functionality for
-	single and dual connection ij runs.
-
-	@author jerry
- */
-public class utilMain implements java.security.PrivilegedAction {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
-
-  private static Class[] CONN_PARAM = { Integer.TYPE };
-  private static Object[] CONN_ARG = { new Integer(JDBC30Translation.CLOSE_CURSORS_AT_COMMIT)};
-
-	StatementFinder[] commandGrabber;
-	UCode_CharStream charStream;
-	ijTokenManager ijTokMgr;
-	ij ijParser;
-	ConnectionEnv[] connEnv;
-	int currCE;
-	private int		numConnections;
-	private boolean fileInput;
-	private boolean initialFileInput;
-	private boolean mtUse;
-	private boolean firstRun = true;
-	private LocalizedOutput out = null;
-	private Properties connAttributeDefaults;
-	private Hashtable ignoreErrors;
-
-	protected boolean isJCC;	//The driver being used is JCC
-
-	/*
-		In the goodness of time, this could be an ij property
-	 */
-	public static final int BUFFEREDFILESIZE = 2048;
-
-	/*
-	 * command can be redirected, so we stack up command
-	 * grabbers as needed.
-	 */
-	Stack oldGrabbers = new Stack();
-
-	LocalizedResource langUtil = LocalizedResource.getInstance();
-	/**
-	 * Set up the test to run with 'numConnections' connections/users.
-	 *
-	 * @param numConnections	The number of connections/users to test.
-	 */
-	public utilMain(int numConnections, LocalizedOutput out)
-		throws ijFatalException
-	{
-		this(numConnections, out, (Hashtable)null);
-	}
-
-	/**
-	 * Set up the test to run with 'numConnections' connections/users.
-	 *
-	 * @param numConnections	The number of connections/users to test.
-	 * @param ignoreErrors		A list of errors to ignore.  If null,
-	 *							all errors are printed out and nothing
-	 *							is fatal.  If non-null, if an error is
-	 *							hit and it is in this list, it is silently	
-	 *							ignore.  Otherwise, an ijFatalException is
-	 *							thrown.  ignoreErrors is used for stress
-	 *							tests.
-	 */
-	public utilMain(int numConnections, LocalizedOutput out, Hashtable ignoreErrors)
-		throws ijFatalException
-	{
-		String framework_property = util.getSystemProperty("framework");
-		
-		if (framework_property != null)
-		{
-			if (framework_property.equals("DB2jNet") 
-					|| framework_property.equals("DB2jcc"))
-				isJCC = true;
-		}
-		/* init the parser; give it no input to start with.
-		 * (1 parser for entire test.)
-		 */
-		charStream = new UCode_CharStream(
-						new StringReader(" "), 1, 1);
-		ijTokMgr = new ijTokenManager(charStream);
-		ijParser = new ij(ijTokMgr, getUtilMain());
-		this.out = out;
-		this.ignoreErrors = ignoreErrors;
-
-		this.numConnections = numConnections;
-		/* 1 StatementFinder and ConnectionEnv per connection/user. */
-		commandGrabber = new StatementFinder[numConnections];
-		connEnv = new ConnectionEnv[numConnections];
-
-		for (int ictr = 0; ictr < numConnections; ictr++)
-		{
-		    commandGrabber[ictr] = new StatementFinder(langUtil.getNewInput(System.in));
-			connEnv[ictr] = new ConnectionEnv(ictr, (numConnections > 1), (numConnections == 1));
-			try {
-				connEnv[ictr].init(out);
-			} catch (SQLException s) {
-				JDBCDisplayUtil.ShowException(out, s); // will continue past connect failure
-			} catch (ClassNotFoundException c) {
-				JDBCDisplayUtil.ShowException(out, c); // will continue past driver failure
-			} catch (InstantiationException i) {
-				JDBCDisplayUtil.ShowException(out, i); // will continue past driver failure
-			} catch (IllegalAccessException ia) {
-				JDBCDisplayUtil.ShowException(out, ia); // will continue past driver failure
-			}
-		}
-
-		/* Start with connection/user 0 */
-		currCE = 0;
-		fileInput = false;
-		initialFileInput = false;
-		firstRun = true;
-	}
-
-
-	/**
-	 * run ij over the specified input, sending output to the
-	 * specified output. Any prior input and output will be lost.
-	 *
-	 * @param in source for input to ij
-	 * @param out sink for output from ij
-	 * @param connAttributeDefaults  connection attributes from -ca ij arg
-	 */
-	public void go(LocalizedInput[] in, LocalizedOutput out,
-				   Properties connAttributeDefaults) throws ijFatalException
-	{
-		boolean done = false;
-
-		String command = null;
-
-		this.out = out;
-		this.connAttributeDefaults = connAttributeDefaults;
-		
-		ijParser.setConnection(connEnv[currCE], (numConnections > 1));
-		fileInput = initialFileInput = (!in[currCE].isStandardInput());
-
-		for (int ictr = 0; ictr < commandGrabber.length; ictr++) {
-			commandGrabber[ictr].ReInit(in[ictr]);
-		}
-
-		if (firstRun) {
-
-			// figure out which version this is
-			InputStream versionStream = (InputStream) java.security.AccessController.doPrivileged(this);
-
-			// figure out which version this is
-			ProductVersionHolder ijVersion = 
-				ProductVersionHolder.getProductVersionHolderFromMyEnv(versionStream);
-
-			String version;
-			if (ijVersion != null)
-			{
-				version = "" + ijVersion.getMajorVersion() + "." +
-					ijVersion.getMinorVersion();
-			}
-			else
-			{
-				version = "?";
-			}
-
-   			out.println(langUtil.getTextMessage("IJ_IjVers30C199", version));
-			for (int i=connEnv.length-1;i>=0;i--) { // print out any initial warnings...
-				Connection c = connEnv[i].getConnection();
-				if (c!=null) {
-					JDBCDisplayUtil.ShowWarnings(out,c);
-				}
-			}
-			firstRun = false;
-
-      		//check if the property is set to not show select count and set the static variable
-      		//accordingly. 
-    		boolean showNoCountForSelect = Boolean.getBoolean("ij.showNoCountForSelect");
-      		JDBCDisplayUtil.showSelectCount = !showNoCountForSelect;
-
-      		//check if the property is set to not show initial connections and accordingly set the
-      		//static variable.
-    		boolean showNoConnectionsAtStart = Boolean.getBoolean("ij.showNoConnectionsAtStart");
-      		if (!(showNoConnectionsAtStart)) {
-         		try {
-           			ijResult result = ijParser.showConnectionsMethod(true);
- 					displayResult(out,result,connEnv[currCE].getConnection());
-         		} catch (SQLException ex) {
-           			handleSQLException(out,ex);
-         		}
-      		}
-    	}
-
-		while (!ijParser.exit && !done) {
-			try{
-				ijParser.setConnection(connEnv[currCE], (numConnections > 1));
-			} catch(Throwable t){
-				//do nothing
-				}
-
-			connEnv[currCE].doPrompt(true, out);
-   			try {
-				command = null;
-
-				out.flush();
-				command = commandGrabber[currCE].nextStatement();
-
-				// if there is no next statement,
-				// pop back to the top saved grabber.
-				while (command == null && ! oldGrabbers.empty()) {
-					// close the old input file if not System.in
-					if (fileInput) commandGrabber[currCE].close();
-					commandGrabber[currCE] = (StatementFinder)oldGrabbers.pop();
-					if (oldGrabbers.empty())
-						fileInput = initialFileInput;
-					command = commandGrabber[currCE].nextStatement();
-				}
-
-				// if there are no grabbers left,
-				// we are done.
-				if (command == null && oldGrabbers.empty()) {
-					done = true;
-				}
-				else {
-					boolean	elapsedTimeOn = ijParser.getElapsedTimeState();
-					long	beginTime = 0;
-					long	endTime;
-
-					if (fileInput) {
-						out.println(command+";");
-						out.flush();
-					}
-
-					charStream.ReInit(new StringReader(command), 1, 1);
-					ijTokMgr.ReInit(charStream);
-					ijParser.ReInit(ijTokMgr);
-
-					if (elapsedTimeOn) {
-						beginTime = System.currentTimeMillis();
-					}
-
-					ijResult result = ijParser.ijStatement();
-					displayResult(out,result,connEnv[currCE].getConnection());
-
-					// if something went wrong, an SQLException or ijException was thrown.
-					// we can keep going to the next statement on those (see catches below).
-					// ijParseException means we try the SQL parser.
-
-					/* Print the elapsed time if appropriate */
-					if (elapsedTimeOn) {
-						endTime = System.currentTimeMillis();
-						out.println(langUtil.getTextMessage("IJ_ElapTime0Mil", 
-						langUtil.getNumberAsString(endTime - beginTime)));
-					}
-
-					// would like when it completes a statement
-					// to see if there is stuff after the ;
-					// and before the <EOL> that we will IGNORE
-					// (with a warning to that effect)
-				}
-
-    			} catch (ParseException e) {
-					if (command != null) doCatch(command);
-				} catch (TokenMgrError e) {
-					if (command != null) doCatch(command);
-    			} catch (SQLException e) {
-					// SQL exception occurred in ij's actions; print and continue
-					// unless it is considered fatal.
-					handleSQLException(out,e);
-    			} catch (ijException e) {
-					// exception occurred in ij's actions; print and continue
-    			  	out.println(langUtil.getTextMessage("IJ_IjErro0",e.getMessage()));
-					doTrace(e);
-    			} catch (Throwable e) {
-    			  	out.println(langUtil.getTextMessage("IJ_JavaErro0",e.toString()));
-					doTrace(e);
-				}
-
-			/* Go to the next connection/user, if there is one */
-			currCE = ++currCE % connEnv.length;
-		}
-
-		// we need to close all sessions when done; otherwise we have
-		// a problem when a single VM runs successive IJ threads
-		try {
-			for (int i = 0; i < connEnv.length; i++) {
-				connEnv[i].removeAllSessions();
-			}
-		} catch (SQLException se ) {
-			handleSQLException(out,se);
-		}
-		// similarly must close input files
-		for (int i = 0; i < numConnections; i++) {
-			try {
-				if (!in[i].isStandardInput() )
-					in[i].close();	
-			} catch (Exception e ) {
-    			  	out.println(langUtil.getTextMessage("IJ_CannotCloseInFile",
-					e.toString()));
-			}
-		}
-
-		/*
-			If an exit was requested, then we will be shutting down.
-		 */
-		if (ijParser.exit || (initialFileInput && !mtUse)) {
-			Driver d = null;
-			try {
-			    d = DriverManager.getDriver("jdbc:derby:");
-			} catch (Exception e) {
-				d = null;
-			}
-			if (d!=null) { // do we have a driver running? shutdown on exit.
-				try {
-					DriverManager.getConnection("jdbc:derby:;shutdown=true");
-				} catch (SQLException e) {
-					// ignore the errors, they are expected.
-				}
-			}
-		}
-  	}
-
-	private void displayResult(LocalizedOutput out, ijResult result, Connection conn) throws SQLException {
-		// display the result, if appropriate.
-		if (result!=null) {
-			if (result.isConnection()) {
-				if (result.hasWarnings()) {
-					JDBCDisplayUtil.ShowWarnings(out,result.getSQLWarnings());
-					result.clearSQLWarnings();
-				}
-			} else if (result.isStatement()) {
-				Statement s = result.getStatement();
-				try {
-				    JDBCDisplayUtil.DisplayResults(out,s,connEnv[currCE].getConnection());
-				} catch (SQLException se) {
-				    result.closeStatement();
-					throw se;
-				}
-				result.closeStatement();
-			} else if (result.isNextRowOfResultSet()) {
-				ResultSet r = result.getNextRowOfResultSet();
-				JDBCDisplayUtil.DisplayCurrentRow(out,r,connEnv[currCE].getConnection());
-			} else if (result.isVector()) {
-				util.DisplayVector(out,result.getVector());
-				if (result.hasWarnings()) {
-					JDBCDisplayUtil.ShowWarnings(out,result.getSQLWarnings());
-					result.clearSQLWarnings();
-				}
-			} else if (result.isMulti()) {
-			    try {
-				    util.DisplayMulti(out,(PreparedStatement)result.getStatement(),result.getResultSet(),connEnv[currCE].getConnection());
-				} catch (SQLException se) {
-				    result.closeStatement();
-					throw se;
-				}
-				result.closeStatement(); // done with the statement now
-				if (result.hasWarnings()) {
-					JDBCDisplayUtil.ShowWarnings(out,result.getSQLWarnings());
-					result.clearSQLWarnings();
-				}
-			} else if (result.isException()) {
-				JDBCDisplayUtil.ShowException(out,result.getException());
-			}
-		}
-	}
-
-	/**
-	 * catch processing on failed commands. This really ought to
-	 * be in ij somehow, but it was easier to catch in Main.
-	 */
-	private void doCatch(String command) {
-		// this retries the failed statement
-		// as a JSQL statement; it uses the
-		// ijParser since that maintains our
-		// connection and state.
-
-	    try {
-			boolean	elapsedTimeOn = ijParser.getElapsedTimeState();
-			long	beginTime = 0;
-			long	endTime;
-
-			if (elapsedTimeOn) {
-				beginTime = System.currentTimeMillis();
-			}
-
-			ijResult result = ijParser.executeImmediate(command);
-			displayResult(out,result,connEnv[currCE].getConnection());
-
-			/* Print the elapsed time if appropriate */
-			if (elapsedTimeOn) {
-				endTime = System.currentTimeMillis();
-				out.println(langUtil.getTextMessage("IJ_ElapTime0Mil_4", 
-				langUtil.getNumberAsString(endTime - beginTime)));
-			}
-
-	    } catch (SQLException e) {
-			// SQL exception occurred in ij's actions; print and continue
-			// unless it is considered fatal.
-			handleSQLException(out,e);
-	    } catch (ijException i) {
-	  		out.println(langUtil.getTextMessage("IJ_IjErro0_5", i.getMessage()));
-			doTrace(i);
-		} catch (ijTokenException ie) {
-	  		out.println(langUtil.getTextMessage("IJ_IjErro0_6", ie.getMessage()));
-			doTrace(ie);
-	    } catch (Throwable t) {
-	  		out.println(langUtil.getTextMessage("IJ_JavaErro0_7", t.toString()));
-			doTrace(t);
-	    }
-	}
-
-	/**
-	 * This routine displays SQL exceptions and decides whether they
-	 * are fatal or not, based on the ignoreErrors field. If they
-	 * are fatal, an ijFatalException is thrown.
-	 * Lifted from ij/util.java:ShowSQLException
-	 */
-	public void handleSQLException(LocalizedOutput out, SQLException e) 
-		throws ijFatalException
-	{
-		String errorCode;
-		String sqlState = null;
-		SQLException fatalException = null;
-
-		if (Boolean.getBoolean("ij.showErrorCode")) {
-			errorCode = langUtil.getTextMessage("IJ_Erro0", 
-			langUtil.getNumberAsString(e.getErrorCode()));
-		}
-		else {
-			errorCode = "";
-		}
-
-		for (; e!=null; e=e.getNextException())
-		{
-			/*
-			** If we are to throw errors, then throw the exceptions
-			** that aren't in the ignoreErrors list.  If
-			** the ignoreErrors list is null we don't throw
-			** any errors.
-			*/
-		 	if (ignoreErrors != null) 
-			{
-				sqlState = e.getSQLState();
-				if ((sqlState != null) &&
-					(ignoreErrors.get(sqlState) != null))
-				{
-					continue;
-				}
-				else
-				{
-					fatalException = e;
-				}
-			}
-
-			String st1 = JDBCDisplayUtil.mapNull(e.getSQLState(),langUtil.getTextMessage("IJ_NoSqls"));
-			String st2 = JDBCDisplayUtil.mapNull(e.getMessage(),langUtil.getTextMessage("IJ_NoMess"));
-			out.println(langUtil.getTextMessage("IJ_Erro012",  st1, st2, errorCode));
-			JDBCDisplayUtil.doTrace(out, e);
-		}
-		if (fatalException != null)
-		{
-			throw new ijFatalException(fatalException);
-		}
-	}
-
-	/**
-	 * stack trace dumper
-	 */
-	private void doTrace(Throwable t) {
-		if (util.getSystemProperty("ij.exceptionTrace") != null) {
-			t.printStackTrace(out);
-		}
-		out.flush();
-	}
-
-	void newInput(String fileName) {
-		FileInputStream newFile = null;
-		try {
-			newFile = new FileInputStream(fileName);
-      	} catch (FileNotFoundException e) {
-        	throw ijException.fileNotFound();
-		}
-		if (newFile == null) return;
-
-		// if the file was opened, move to use it for input.
-		oldGrabbers.push(commandGrabber[currCE]);
-	    commandGrabber[currCE] = 
-                new StatementFinder(langUtil.getNewInput(new BufferedInputStream(newFile, BUFFEREDFILESIZE)));
-		fileInput = true;
-	}
-
-	void newResourceInput(String resourceName) {
-		InputStream is = util.getResourceAsStream(resourceName);
-		if (is==null) throw ijException.resourceNotFound();
-		oldGrabbers.push(commandGrabber[currCE]);
-	    commandGrabber[currCE] = 
-                new StatementFinder(langUtil.getNewInput(new BufferedInputStream(is, BUFFEREDFILESIZE)));
-		fileInput = true;
-	}
-
-	/**
-	 * REMIND: eventually this might be part of StatementFinder,
-	 * used at each carriage return to show that it is still "live"
-	 * when it is reading multi-line input.
-	 */
-	static void doPrompt(boolean newStatement, LocalizedOutput out, String tag) 
-	 {
-		if (newStatement) {
-	  		out.print("ij"+(tag==null?"":tag)+"> ");
-		}
-		else {
-			out.print("> ");
-		}
-		out.flush();
-	}
-
-	void setMtUse(boolean b) {
-		mtUse = b;
-	}
-
-	// JDBC 2.0 support
-
-	/**
-	 * Return the right utilMain to use.  (JDBC 1.1 or 2.0)
-	 *
-	 */
-	public utilMain getUtilMain()
-	{
-		return this;
-	}
-
-	/**
-	 * Connections by default create ResultSet objects with holdability true. This method can be used
-	 * to change the holdability of the connection by passing one of ResultSet.HOLD_CURSORS_OVER_COMMIT
-	 * or ResultSet.CLOSE_CURSORS_AT_COMMIT. We implement this using reflection in jdk13 and lower
-	 *
-	 * @param conn			The connection.
-	 * @param holdType	The new holdability for the Connection object.
-	 *
-	 * @return	The connection object with holdability set to passed value.
-	 */
-	public Connection setHoldability(Connection conn, int holdType)
-		throws SQLException
-	{
-    //Prior to db2 compatibility work, the default holdability for connections was close cursors over commit and all the tests
-    //were written based on that assumption
-    //Later, as part of db2 compatibility, we changed the default holdability for connection to hold cursors over commit.
-    //But in order for the existing tests to work fine, the tests needed a way to set the holdability to close cursors for connections
-    //Since there is no direct jdbc api in jdk13 and lower to do that, we are using reflection to set the holdability to close cursors
-    try { //for jdks prior to jdk14, need to use reflection to set holdability to false. 
-    	Method sh = conn.getClass().getMethod("setHoldability", CONN_PARAM);
-    	sh.invoke(conn, CONN_ARG);
-    } catch( Exception e) {
-    	throw PublicAPI.wrapStandardException( StandardException.plainWrapException( e));
-    }
-    return conn;
-	}
-
-	/**
-	 * Retrieves the current holdability of ResultSet objects created using this
-	 * Connection object. We implement this using reflection in jdk13 and lower
-	 *
-	 * @return  The holdability, one of ResultSet.HOLD_CURSORS_OVER_COMMIT
-	 * or ResultSet.CLOSE_CURSORS_AT_COMMIT
-	 *
-	 */
-	public int getHoldability(Connection conn)
-		throws SQLException
-	{
-    //this method is used to make sure we are not trying to create a statement with holdability different than the connection holdability
-    //This is because jdk13 and lower does not have support for that.
-    //The holdability of connection and statement can differ if connection holdability is set to close cursor on commit using reflection
-    //and statement is getting created with holdability true
-    //Another instance of holdability of connection and statement not being same is when connection holdability is hold cursor
-    //over commit and statement is being created with holdability false
-    int defaultHoldability = JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;
-    try {
-    	Method sh = conn.getClass().getMethod("getHoldability", null);
-    	defaultHoldability = ((Integer)sh.invoke(conn, null)).intValue();
-    } catch( Exception e) {
-    	throw PublicAPI.wrapStandardException( StandardException.plainWrapException( e));
-    }
-    return defaultHoldability;
-	}
-
-	/**
-	 * Create the right kind of statement (scrolling or not)
-	 * off of the specified connection.
-	 *
-	 * @param conn			The connection.
-	 * @param scrollType	The scroll type of the cursor.
-	 *
-	 * @return	The statement.
-	 */
-	public Statement createStatement(Connection conn, int scrollType, int holdType)
-		throws SQLException
-	{
-    	//following if is used to make sure we are not trying to create a statement with holdability different that the connection
-    	//holdability. This is because jdk13 and lower does not have support for that.
-    	//The holdability of connection and statement can differ if connection holdability is set to close cursor on commit using reflection
-    	//and statement is getting created with holdability true
-    	//Another instance of holdability of connection and statement not being same is when connection holdability is hold cursor
-    	//over commit and statement is being created with holdability false
-    	if (holdType != getHoldability(conn))
-    	{
-        	throw ijException.holdCursorsNotSupported();
-    	}
-      
-    	Statement stmt;
-        try {
-        	stmt = conn.createStatement(scrollType, JDBC20Translation.CONCUR_READ_ONLY);
-        } catch(AbstractMethodError ame) {
-        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
-        //to jdbc 1.x functionality
-        	stmt = conn.createStatement();
-        }
-		return stmt;
-	}
-
-	/**
-	 * Position on the specified row of the specified ResultSet.
-	 *
-	 * @param rs	The specified ResultSet.
-	 * @param row	The row # to move to.
-	 *				(Negative means from the end of the result set.)
-	 *
-	 * @return	NULL.
-	 *
-	 * @exception	SQLException thrown on error.
-	 *				(absolute() not supported pre-JDBC2.0)
-	 */
-	public ijResult absolute(ResultSet rs, int row)
-		throws SQLException
-	{
-        boolean forwardOnly;
-    	try {
-		// absolute is only allowed on scroll cursors
-		    forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
-        } catch (AbstractMethodError ame) {
-        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
-        //to jdbc 1.x functionality
-            forwardOnly = true;
-        }
-        if (forwardOnly)
-		{
-			throw ijException.forwardOnlyCursor("ABSOLUTE");
-		}
-
-		// 0 is an invalid value for row
-		if (row == 0)
-		{
-			throw ijException.zeroInvalidForAbsolute();
-		}
-
-		return new ijRowResult(rs, rs.absolute(row));
-	}
-
-	/**
-	 * Move the cursor position by the specified amount.
-	 *
-	 * @param rs	The specified ResultSet.
-	 * @param row	The # of rows to move.
-	 *				(Negative means toward the beginning of the result set.)
-	 *
-	 * @return	NULL.
-	 *
-	 * @exception	SQLException thrown on error.
-	 *				(relative() not supported pre-JDBC2.0)
-	 */
-	public ijResult relative(ResultSet rs, int row)
-		throws SQLException
-	{
-    	boolean forwardOnly;
-        try {
-        	forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
-        } catch (AbstractMethodError ame) {
-        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
-        //to jdbc 1.x functionality
-            forwardOnly = true;
-        }
-		// relative is only allowed on scroll cursors
-		if (forwardOnly)
-		{
-			throw ijException.forwardOnlyCursor("RELATIVE");
-		}
-
-		return new ijRowResult(rs, rs.relative(row));
-	}
-
-	/**
-	 * Position before the first row of the specified ResultSet
-	 * and return NULL to the user.
-	 *
-	 * @param rs	The specified ResultSet.
-	 *
-	 * @return	NULL.
-	 *
-	 * @exception	SQLException thrown on error.
-	 *				(beforeFirst() not supported pre-JDBC2.0)
-	 */
-	public ijResult beforeFirst(ResultSet rs)
-		throws SQLException
-	{
-    	boolean forwardOnly;
-        try {
-        	forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
-        } catch (AbstractMethodError ame) {
-        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
-        //to jdbc 1.x functionality
-            forwardOnly = true;
-        }
-		// before first is only allowed on scroll cursors
-		if (forwardOnly)
-		{
-			throw ijException.forwardOnlyCursor("BEFORE FIRST");
-		}
-
-		rs.beforeFirst();
-		return new ijRowResult(rs, false);
-	}
-
-	/**
-	 * Position on the first row of the specified ResultSet
-	 * and return that row to the user.
-	 *
-	 * @param rs	The specified ResultSet.
-	 *
-	 * @return	The first row of the ResultSet.
-	 *
-	 * @exception	SQLException thrown on error.
-	 *				(first() not supported pre-JDBC2.0)
-	 */
-	public ijResult first(ResultSet rs)
-		throws SQLException
-	{
-    	boolean forwardOnly;
-        try {
-        	forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
-        } catch (AbstractMethodError ame) {
-        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
-        //to jdbc 1.x functionality
-            forwardOnly = true;
-        }
-		// first is only allowed on scroll cursors
-		if (forwardOnly)
-		{
-			throw ijException.forwardOnlyCursor("FIRST");
-		}
-
-		return new ijRowResult(rs, rs.first());
-	}
-
-	/**
-	 * Position after the last row of the specified ResultSet
-	 * and return NULL to the user.
-	 *
-	 * @param rs	The specified ResultSet.
-	 *
-	 * @return	NULL.
-	 *
-	 * @exception	SQLException thrown on error.
-	 *				(afterLast() not supported pre-JDBC2.0)
-	 */
-	public ijResult afterLast(ResultSet rs)
-		throws SQLException
-	{
-    	boolean forwardOnly;
-        try {
-        	forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
-        } catch (AbstractMethodError ame) {
-        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
-        //to jdbc 1.x functionality
-            forwardOnly = true;
-        }
-		// after last is only allowed on scroll cursors
-		if (forwardOnly)
-		{
-			throw ijException.forwardOnlyCursor("AFTER LAST");
-		}
-
-		rs.afterLast();
-		return new ijRowResult(rs, false);
-	}
-
-	/**
-	 * Position on the last row of the specified ResultSet
-	 * and return that row to the user.
-	 *
-	 * @param rs	The specified ResultSet.
-	 *
-	 * @return	The last row of the ResultSet.
-	 *
-	 * @exception	SQLException thrown on error.
-	 *				(last() not supported pre-JDBC2.0)
-	 */
-	public ijResult last(ResultSet rs)
-		throws SQLException
-	{
-    	boolean forwardOnly;
-        try {
-        	forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
-        } catch (AbstractMethodError ame) {
-        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
-        //to jdbc 1.x functionality
-            forwardOnly = true;
-        }
-		// last is only allowed on scroll cursors
-		if (forwardOnly)
-		{
-			throw ijException.forwardOnlyCursor("LAST");
-		}
-
-		return new ijRowResult(rs, rs.last());
-	}
-
-	/**
-	 * Position on the previous row of the specified ResultSet
-	 * and return that row to the user.
-	 *
-	 * @param rs	The specified ResultSet.
-	 *
-	 * @return	The previous row of the ResultSet.
-	 *
-	 * @exception	SQLException thrown on error.
-	 *				(previous() not supported pre-JDBC2.0)
-	 */
-	public ijResult previous(ResultSet rs)
-		throws SQLException
-	{
-    	boolean forwardOnly;
-        try {
-        	forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
-        } catch (AbstractMethodError ame) {
-        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
-        //to jdbc 1.x functionality
-            forwardOnly = true;
-        }
-		// first is only allowed on scroll cursors
-		if (forwardOnly)
-		{
-			throw ijException.forwardOnlyCursor("PREVIOUS");
-		}
-
-		return new ijRowResult(rs, rs.previous());
-	}
-
-	/**
-	 * Get the current row number
-	 *
-	 * @param rs	The specified ResultSet.
-	 *
-	 * @return	The current row number
-	 *
-	 * @exception	SQLException thrown on error.
-	 *				(getRow() not supported pre-JDBC2.0)
-	 */
-	public int getCurrentRowNumber(ResultSet rs)
-		throws SQLException
-	{
-		boolean forwardOnly;
-		try 
-		{
-			forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
-		} catch (AbstractMethodError ame) 
-		{
-			//because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
-			//to jdbc 1.x functionality
-			forwardOnly = true;
-        }
-
-		// getCurrentRow is only allowed on scroll cursors
-		if (forwardOnly)
-		{
-			throw ijException.forwardOnlyCursor("GETCURRENTROWNUMBER");
-		}
-
-		return rs.getRow();
-	}
-
-	public Properties getConnAttributeDefaults ()
-	{
-		return connAttributeDefaults;
-	}
-
-	public final Object run() {
-		return  getClass().getResourceAsStream(ProductGenusNames.TOOLS_INFO);
-	}
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1997, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+                
+import org.apache.derby.iapi.reference.JDBC20Translation;
+import org.apache.derby.iapi.reference.JDBC30Translation;
+
+import org.apache.derby.tools.JDBCDisplayUtil;
+import org.apache.derby.iapi.tools.i18n.*;
+
+import org.apache.derby.iapi.services.info.ProductVersionHolder;
+import org.apache.derby.iapi.services.info.ProductGenusNames;
+
+import org.apache.derby.iapi.error.PublicAPI;
+import org.apache.derby.iapi.error.StandardException;
+
+import java.util.Stack;
+import java.util.Hashtable;
+import java.util.Properties;
+
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+import java.io.FileNotFoundException;
+import java.io.StringReader;
+import java.sql.DriverManager;
+import java.sql.Driver;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.sql.PreparedStatement;
+
+import java.lang.reflect.*;
+
+/**
+	This class is utilities specific to the two ij Main's.
+	This factoring enables sharing the functionality for
+	single and dual connection ij runs.
+
+	@author jerry
+ */
+public class utilMain implements java.security.PrivilegedAction {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1997_2004;
+
+  private static Class[] CONN_PARAM = { Integer.TYPE };
+  private static Object[] CONN_ARG = { new Integer(JDBC30Translation.CLOSE_CURSORS_AT_COMMIT)};
+
+	StatementFinder[] commandGrabber;
+	UCode_CharStream charStream;
+	ijTokenManager ijTokMgr;
+	ij ijParser;
+	ConnectionEnv[] connEnv;
+	int currCE;
+	private int		numConnections;
+	private boolean fileInput;
+	private boolean initialFileInput;
+	private boolean mtUse;
+	private boolean firstRun = true;
+	private LocalizedOutput out = null;
+	private Properties connAttributeDefaults;
+	private Hashtable ignoreErrors;
+
+	protected boolean isJCC;	//The driver being used is JCC
+
+	/*
+		In the goodness of time, this could be an ij property
+	 */
+	public static final int BUFFEREDFILESIZE = 2048;
+
+	/*
+	 * command can be redirected, so we stack up command
+	 * grabbers as needed.
+	 */
+	Stack oldGrabbers = new Stack();
+
+	LocalizedResource langUtil = LocalizedResource.getInstance();
+	/**
+	 * Set up the test to run with 'numConnections' connections/users.
+	 *
+	 * @param numConnections	The number of connections/users to test.
+	 */
+	public utilMain(int numConnections, LocalizedOutput out)
+		throws ijFatalException
+	{
+		this(numConnections, out, (Hashtable)null);
+	}
+
+	/**
+	 * Set up the test to run with 'numConnections' connections/users.
+	 *
+	 * @param numConnections	The number of connections/users to test.
+	 * @param ignoreErrors		A list of errors to ignore.  If null,
+	 *							all errors are printed out and nothing
+	 *							is fatal.  If non-null, if an error is
+	 *							hit and it is in this list, it is silently	
+	 *							ignore.  Otherwise, an ijFatalException is
+	 *							thrown.  ignoreErrors is used for stress
+	 *							tests.
+	 */
+	public utilMain(int numConnections, LocalizedOutput out, Hashtable ignoreErrors)
+		throws ijFatalException
+	{
+		String framework_property = util.getSystemProperty("framework");
+		
+		if (framework_property != null)
+		{
+			if (framework_property.equals("DB2jNet") 
+					|| framework_property.equals("DB2jcc"))
+				isJCC = true;
+		}
+		/* init the parser; give it no input to start with.
+		 * (1 parser for entire test.)
+		 */
+		charStream = new UCode_CharStream(
+						new StringReader(" "), 1, 1);
+		ijTokMgr = new ijTokenManager(charStream);
+		ijParser = new ij(ijTokMgr, getUtilMain());
+		this.out = out;
+		this.ignoreErrors = ignoreErrors;
+
+		this.numConnections = numConnections;
+		/* 1 StatementFinder and ConnectionEnv per connection/user. */
+		commandGrabber = new StatementFinder[numConnections];
+		connEnv = new ConnectionEnv[numConnections];
+
+		for (int ictr = 0; ictr < numConnections; ictr++)
+		{
+		    commandGrabber[ictr] = new StatementFinder(langUtil.getNewInput(System.in));
+			connEnv[ictr] = new ConnectionEnv(ictr, (numConnections > 1), (numConnections == 1));
+			try {
+				connEnv[ictr].init(out);
+			} catch (SQLException s) {
+				JDBCDisplayUtil.ShowException(out, s); // will continue past connect failure
+			} catch (ClassNotFoundException c) {
+				JDBCDisplayUtil.ShowException(out, c); // will continue past driver failure
+			} catch (InstantiationException i) {
+				JDBCDisplayUtil.ShowException(out, i); // will continue past driver failure
+			} catch (IllegalAccessException ia) {
+				JDBCDisplayUtil.ShowException(out, ia); // will continue past driver failure
+			}
+		}
+
+		/* Start with connection/user 0 */
+		currCE = 0;
+		fileInput = false;
+		initialFileInput = false;
+		firstRun = true;
+	}
+
+
+	/**
+	 * run ij over the specified input, sending output to the
+	 * specified output. Any prior input and output will be lost.
+	 *
+	 * @param in source for input to ij
+	 * @param out sink for output from ij
+	 * @param connAttributeDefaults  connection attributes from -ca ij arg
+	 */
+	public void go(LocalizedInput[] in, LocalizedOutput out,
+				   Properties connAttributeDefaults) throws ijFatalException
+	{
+		boolean done = false;
+
+		String command = null;
+
+		this.out = out;
+		this.connAttributeDefaults = connAttributeDefaults;
+		
+		ijParser.setConnection(connEnv[currCE], (numConnections > 1));
+		fileInput = initialFileInput = (!in[currCE].isStandardInput());
+
+		for (int ictr = 0; ictr < commandGrabber.length; ictr++) {
+			commandGrabber[ictr].ReInit(in[ictr]);
+		}
+
+		if (firstRun) {
+
+			// figure out which version this is
+			InputStream versionStream = (InputStream) java.security.AccessController.doPrivileged(this);
+
+			// figure out which version this is
+			ProductVersionHolder ijVersion = 
+				ProductVersionHolder.getProductVersionHolderFromMyEnv(versionStream);
+
+			String version;
+			if (ijVersion != null)
+			{
+				version = "" + ijVersion.getMajorVersion() + "." +
+					ijVersion.getMinorVersion();
+			}
+			else
+			{
+				version = "?";
+			}
+
+   			out.println(langUtil.getTextMessage("IJ_IjVers30C199", version));
+			for (int i=connEnv.length-1;i>=0;i--) { // print out any initial warnings...
+				Connection c = connEnv[i].getConnection();
+				if (c!=null) {
+					JDBCDisplayUtil.ShowWarnings(out,c);
+				}
+			}
+			firstRun = false;
+
+      		//check if the property is set to not show select count and set the static variable
+      		//accordingly. 
+    		boolean showNoCountForSelect = Boolean.getBoolean("ij.showNoCountForSelect");
+      		JDBCDisplayUtil.showSelectCount = !showNoCountForSelect;
+
+      		//check if the property is set to not show initial connections and accordingly set the
+      		//static variable.
+    		boolean showNoConnectionsAtStart = Boolean.getBoolean("ij.showNoConnectionsAtStart");
+      		if (!(showNoConnectionsAtStart)) {
+         		try {
+           			ijResult result = ijParser.showConnectionsMethod(true);
+ 					displayResult(out,result,connEnv[currCE].getConnection());
+         		} catch (SQLException ex) {
+           			handleSQLException(out,ex);
+         		}
+      		}
+    	}
+
+		while (!ijParser.exit && !done) {
+			try{
+				ijParser.setConnection(connEnv[currCE], (numConnections > 1));
+			} catch(Throwable t){
+				//do nothing
+				}
+
+			connEnv[currCE].doPrompt(true, out);
+   			try {
+				command = null;
+
+				out.flush();
+				command = commandGrabber[currCE].nextStatement();
+
+				// if there is no next statement,
+				// pop back to the top saved grabber.
+				while (command == null && ! oldGrabbers.empty()) {
+					// close the old input file if not System.in
+					if (fileInput) commandGrabber[currCE].close();
+					commandGrabber[currCE] = (StatementFinder)oldGrabbers.pop();
+					if (oldGrabbers.empty())
+						fileInput = initialFileInput;
+					command = commandGrabber[currCE].nextStatement();
+				}
+
+				// if there are no grabbers left,
+				// we are done.
+				if (command == null && oldGrabbers.empty()) {
+					done = true;
+				}
+				else {
+					boolean	elapsedTimeOn = ijParser.getElapsedTimeState();
+					long	beginTime = 0;
+					long	endTime;
+
+					if (fileInput) {
+						out.println(command+";");
+						out.flush();
+					}
+
+					charStream.ReInit(new StringReader(command), 1, 1);
+					ijTokMgr.ReInit(charStream);
+					ijParser.ReInit(ijTokMgr);
+
+					if (elapsedTimeOn) {
+						beginTime = System.currentTimeMillis();
+					}
+
+					ijResult result = ijParser.ijStatement();
+					displayResult(out,result,connEnv[currCE].getConnection());
+
+					// if something went wrong, an SQLException or ijException was thrown.
+					// we can keep going to the next statement on those (see catches below).
+					// ijParseException means we try the SQL parser.
+
+					/* Print the elapsed time if appropriate */
+					if (elapsedTimeOn) {
+						endTime = System.currentTimeMillis();
+						out.println(langUtil.getTextMessage("IJ_ElapTime0Mil", 
+						langUtil.getNumberAsString(endTime - beginTime)));
+					}
+
+					// would like when it completes a statement
+					// to see if there is stuff after the ;
+					// and before the <EOL> that we will IGNORE
+					// (with a warning to that effect)
+				}
+
+    			} catch (ParseException e) {
+					if (command != null) doCatch(command);
+				} catch (TokenMgrError e) {
+					if (command != null) doCatch(command);
+    			} catch (SQLException e) {
+					// SQL exception occurred in ij's actions; print and continue
+					// unless it is considered fatal.
+					handleSQLException(out,e);
+    			} catch (ijException e) {
+					// exception occurred in ij's actions; print and continue
+    			  	out.println(langUtil.getTextMessage("IJ_IjErro0",e.getMessage()));
+					doTrace(e);
+    			} catch (Throwable e) {
+    			  	out.println(langUtil.getTextMessage("IJ_JavaErro0",e.toString()));
+					doTrace(e);
+				}
+
+			/* Go to the next connection/user, if there is one */
+			currCE = ++currCE % connEnv.length;
+		}
+
+		// we need to close all sessions when done; otherwise we have
+		// a problem when a single VM runs successive IJ threads
+		try {
+			for (int i = 0; i < connEnv.length; i++) {
+				connEnv[i].removeAllSessions();
+			}
+		} catch (SQLException se ) {
+			handleSQLException(out,se);
+		}
+		// similarly must close input files
+		for (int i = 0; i < numConnections; i++) {
+			try {
+				if (!in[i].isStandardInput() )
+					in[i].close();	
+			} catch (Exception e ) {
+    			  	out.println(langUtil.getTextMessage("IJ_CannotCloseInFile",
+					e.toString()));
+			}
+		}
+
+		/*
+			If an exit was requested, then we will be shutting down.
+		 */
+		if (ijParser.exit || (initialFileInput && !mtUse)) {
+			Driver d = null;
+			try {
+			    d = DriverManager.getDriver("jdbc:derby:");
+			} catch (Exception e) {
+				d = null;
+			}
+			if (d!=null) { // do we have a driver running? shutdown on exit.
+				try {
+					DriverManager.getConnection("jdbc:derby:;shutdown=true");
+				} catch (SQLException e) {
+					// ignore the errors, they are expected.
+				}
+			}
+		}
+  	}
+
+	private void displayResult(LocalizedOutput out, ijResult result, Connection conn) throws SQLException {
+		// display the result, if appropriate.
+		if (result!=null) {
+			if (result.isConnection()) {
+				if (result.hasWarnings()) {
+					JDBCDisplayUtil.ShowWarnings(out,result.getSQLWarnings());
+					result.clearSQLWarnings();
+				}
+			} else if (result.isStatement()) {
+				Statement s = result.getStatement();
+				try {
+				    JDBCDisplayUtil.DisplayResults(out,s,connEnv[currCE].getConnection());
+				} catch (SQLException se) {
+				    result.closeStatement();
+					throw se;
+				}
+				result.closeStatement();
+			} else if (result.isNextRowOfResultSet()) {
+				ResultSet r = result.getNextRowOfResultSet();
+				JDBCDisplayUtil.DisplayCurrentRow(out,r,connEnv[currCE].getConnection());
+			} else if (result.isVector()) {
+				util.DisplayVector(out,result.getVector());
+				if (result.hasWarnings()) {
+					JDBCDisplayUtil.ShowWarnings(out,result.getSQLWarnings());
+					result.clearSQLWarnings();
+				}
+			} else if (result.isMulti()) {
+			    try {
+				    util.DisplayMulti(out,(PreparedStatement)result.getStatement(),result.getResultSet(),connEnv[currCE].getConnection());
+				} catch (SQLException se) {
+				    result.closeStatement();
+					throw se;
+				}
+				result.closeStatement(); // done with the statement now
+				if (result.hasWarnings()) {
+					JDBCDisplayUtil.ShowWarnings(out,result.getSQLWarnings());
+					result.clearSQLWarnings();
+				}
+			} else if (result.isException()) {
+				JDBCDisplayUtil.ShowException(out,result.getException());
+			}
+		}
+	}
+
+	/**
+	 * catch processing on failed commands. This really ought to
+	 * be in ij somehow, but it was easier to catch in Main.
+	 */
+	private void doCatch(String command) {
+		// this retries the failed statement
+		// as a JSQL statement; it uses the
+		// ijParser since that maintains our
+		// connection and state.
+
+	    try {
+			boolean	elapsedTimeOn = ijParser.getElapsedTimeState();
+			long	beginTime = 0;
+			long	endTime;
+
+			if (elapsedTimeOn) {
+				beginTime = System.currentTimeMillis();
+			}
+
+			ijResult result = ijParser.executeImmediate(command);
+			displayResult(out,result,connEnv[currCE].getConnection());
+
+			/* Print the elapsed time if appropriate */
+			if (elapsedTimeOn) {
+				endTime = System.currentTimeMillis();
+				out.println(langUtil.getTextMessage("IJ_ElapTime0Mil_4", 
+				langUtil.getNumberAsString(endTime - beginTime)));
+			}
+
+	    } catch (SQLException e) {
+			// SQL exception occurred in ij's actions; print and continue
+			// unless it is considered fatal.
+			handleSQLException(out,e);
+	    } catch (ijException i) {
+	  		out.println(langUtil.getTextMessage("IJ_IjErro0_5", i.getMessage()));
+			doTrace(i);
+		} catch (ijTokenException ie) {
+	  		out.println(langUtil.getTextMessage("IJ_IjErro0_6", ie.getMessage()));
+			doTrace(ie);
+	    } catch (Throwable t) {
+	  		out.println(langUtil.getTextMessage("IJ_JavaErro0_7", t.toString()));
+			doTrace(t);
+	    }
+	}
+
+	/**
+	 * This routine displays SQL exceptions and decides whether they
+	 * are fatal or not, based on the ignoreErrors field. If they
+	 * are fatal, an ijFatalException is thrown.
+	 * Lifted from ij/util.java:ShowSQLException
+	 */
+	public void handleSQLException(LocalizedOutput out, SQLException e) 
+		throws ijFatalException
+	{
+		String errorCode;
+		String sqlState = null;
+		SQLException fatalException = null;
+
+		if (Boolean.getBoolean("ij.showErrorCode")) {
+			errorCode = langUtil.getTextMessage("IJ_Erro0", 
+			langUtil.getNumberAsString(e.getErrorCode()));
+		}
+		else {
+			errorCode = "";
+		}
+
+		for (; e!=null; e=e.getNextException())
+		{
+			/*
+			** If we are to throw errors, then throw the exceptions
+			** that aren't in the ignoreErrors list.  If
+			** the ignoreErrors list is null we don't throw
+			** any errors.
+			*/
+		 	if (ignoreErrors != null) 
+			{
+				sqlState = e.getSQLState();
+				if ((sqlState != null) &&
+					(ignoreErrors.get(sqlState) != null))
+				{
+					continue;
+				}
+				else
+				{
+					fatalException = e;
+				}
+			}
+
+			String st1 = JDBCDisplayUtil.mapNull(e.getSQLState(),langUtil.getTextMessage("IJ_NoSqls"));
+			String st2 = JDBCDisplayUtil.mapNull(e.getMessage(),langUtil.getTextMessage("IJ_NoMess"));
+			out.println(langUtil.getTextMessage("IJ_Erro012",  st1, st2, errorCode));
+			JDBCDisplayUtil.doTrace(out, e);
+		}
+		if (fatalException != null)
+		{
+			throw new ijFatalException(fatalException);
+		}
+	}
+
+	/**
+	 * stack trace dumper
+	 */
+	private void doTrace(Throwable t) {
+		if (util.getSystemProperty("ij.exceptionTrace") != null) {
+			t.printStackTrace(out);
+		}
+		out.flush();
+	}
+
+	void newInput(String fileName) {
+		FileInputStream newFile = null;
+		try {
+			newFile = new FileInputStream(fileName);
+      	} catch (FileNotFoundException e) {
+        	throw ijException.fileNotFound();
+		}
+		if (newFile == null) return;
+
+		// if the file was opened, move to use it for input.
+		oldGrabbers.push(commandGrabber[currCE]);
+	    commandGrabber[currCE] = 
+                new StatementFinder(langUtil.getNewInput(new BufferedInputStream(newFile, BUFFEREDFILESIZE)));
+		fileInput = true;
+	}
+
+	void newResourceInput(String resourceName) {
+		InputStream is = util.getResourceAsStream(resourceName);
+		if (is==null) throw ijException.resourceNotFound();
+		oldGrabbers.push(commandGrabber[currCE]);
+	    commandGrabber[currCE] = 
+                new StatementFinder(langUtil.getNewInput(new BufferedInputStream(is, BUFFEREDFILESIZE)));
+		fileInput = true;
+	}
+
+	/**
+	 * REMIND: eventually this might be part of StatementFinder,
+	 * used at each carriage return to show that it is still "live"
+	 * when it is reading multi-line input.
+	 */
+	static void doPrompt(boolean newStatement, LocalizedOutput out, String tag) 
+	 {
+		if (newStatement) {
+	  		out.print("ij"+(tag==null?"":tag)+"> ");
+		}
+		else {
+			out.print("> ");
+		}
+		out.flush();
+	}
+
+	void setMtUse(boolean b) {
+		mtUse = b;
+	}
+
+	// JDBC 2.0 support
+
+	/**
+	 * Return the right utilMain to use.  (JDBC 1.1 or 2.0)
+	 *
+	 */
+	public utilMain getUtilMain()
+	{
+		return this;
+	}
+
+	/**
+	 * Connections by default create ResultSet objects with holdability true. This method can be used
+	 * to change the holdability of the connection by passing one of ResultSet.HOLD_CURSORS_OVER_COMMIT
+	 * or ResultSet.CLOSE_CURSORS_AT_COMMIT. We implement this using reflection in jdk13 and lower
+	 *
+	 * @param conn			The connection.
+	 * @param holdType	The new holdability for the Connection object.
+	 *
+	 * @return	The connection object with holdability set to passed value.
+	 */
+	public Connection setHoldability(Connection conn, int holdType)
+		throws SQLException
+	{
+    //Prior to db2 compatibility work, the default holdability for connections was close cursors over commit and all the tests
+    //were written based on that assumption
+    //Later, as part of db2 compatibility, we changed the default holdability for connection to hold cursors over commit.
+    //But in order for the existing tests to work fine, the tests needed a way to set the holdability to close cursors for connections
+    //Since there is no direct jdbc api in jdk13 and lower to do that, we are using reflection to set the holdability to close cursors
+    try { //for jdks prior to jdk14, need to use reflection to set holdability to false. 
+    	Method sh = conn.getClass().getMethod("setHoldability", CONN_PARAM);
+    	sh.invoke(conn, CONN_ARG);
+    } catch( Exception e) {
+    	throw PublicAPI.wrapStandardException( StandardException.plainWrapException( e));
+    }
+    return conn;
+	}
+
+	/**
+	 * Retrieves the current holdability of ResultSet objects created using this
+	 * Connection object. We implement this using reflection in jdk13 and lower
+	 *
+	 * @return  The holdability, one of ResultSet.HOLD_CURSORS_OVER_COMMIT
+	 * or ResultSet.CLOSE_CURSORS_AT_COMMIT
+	 *
+	 */
+	public int getHoldability(Connection conn)
+		throws SQLException
+	{
+    //this method is used to make sure we are not trying to create a statement with holdability different than the connection holdability
+    //This is because jdk13 and lower does not have support for that.
+    //The holdability of connection and statement can differ if connection holdability is set to close cursor on commit using reflection
+    //and statement is getting created with holdability true
+    //Another instance of holdability of connection and statement not being same is when connection holdability is hold cursor
+    //over commit and statement is being created with holdability false
+    int defaultHoldability = JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;
+    try {
+    	Method sh = conn.getClass().getMethod("getHoldability", null);
+    	defaultHoldability = ((Integer)sh.invoke(conn, null)).intValue();
+    } catch( Exception e) {
+    	throw PublicAPI.wrapStandardException( StandardException.plainWrapException( e));
+    }
+    return defaultHoldability;
+	}
+
+	/**
+	 * Create the right kind of statement (scrolling or not)
+	 * off of the specified connection.
+	 *
+	 * @param conn			The connection.
+	 * @param scrollType	The scroll type of the cursor.
+	 *
+	 * @return	The statement.
+	 */
+	public Statement createStatement(Connection conn, int scrollType, int holdType)
+		throws SQLException
+	{
+    	//following if is used to make sure we are not trying to create a statement with holdability different that the connection
+    	//holdability. This is because jdk13 and lower does not have support for that.
+    	//The holdability of connection and statement can differ if connection holdability is set to close cursor on commit using reflection
+    	//and statement is getting created with holdability true
+    	//Another instance of holdability of connection and statement not being same is when connection holdability is hold cursor
+    	//over commit and statement is being created with holdability false
+    	if (holdType != getHoldability(conn))
+    	{
+        	throw ijException.holdCursorsNotSupported();
+    	}
+      
+    	Statement stmt;
+        try {
+        	stmt = conn.createStatement(scrollType, JDBC20Translation.CONCUR_READ_ONLY);
+        } catch(AbstractMethodError ame) {
+        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
+        //to jdbc 1.x functionality
+        	stmt = conn.createStatement();
+        }
+		return stmt;
+	}
+
+	/**
+	 * Position on the specified row of the specified ResultSet.
+	 *
+	 * @param rs	The specified ResultSet.
+	 * @param row	The row # to move to.
+	 *				(Negative means from the end of the result set.)
+	 *
+	 * @return	NULL.
+	 *
+	 * @exception	SQLException thrown on error.
+	 *				(absolute() not supported pre-JDBC2.0)
+	 */
+	public ijResult absolute(ResultSet rs, int row)
+		throws SQLException
+	{
+        boolean forwardOnly;
+    	try {
+		// absolute is only allowed on scroll cursors
+		    forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
+        } catch (AbstractMethodError ame) {
+        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
+        //to jdbc 1.x functionality
+            forwardOnly = true;
+        }
+        if (forwardOnly)
+		{
+			throw ijException.forwardOnlyCursor("ABSOLUTE");
+		}
+
+		// 0 is an invalid value for row
+		if (row == 0)
+		{
+			throw ijException.zeroInvalidForAbsolute();
+		}
+
+		return new ijRowResult(rs, rs.absolute(row));
+	}
+
+	/**
+	 * Move the cursor position by the specified amount.
+	 *
+	 * @param rs	The specified ResultSet.
+	 * @param row	The # of rows to move.
+	 *				(Negative means toward the beginning of the result set.)
+	 *
+	 * @return	NULL.
+	 *
+	 * @exception	SQLException thrown on error.
+	 *				(relative() not supported pre-JDBC2.0)
+	 */
+	public ijResult relative(ResultSet rs, int row)
+		throws SQLException
+	{
+    	boolean forwardOnly;
+        try {
+        	forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
+        } catch (AbstractMethodError ame) {
+        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
+        //to jdbc 1.x functionality
+            forwardOnly = true;
+        }
+		// relative is only allowed on scroll cursors
+		if (forwardOnly)
+		{
+			throw ijException.forwardOnlyCursor("RELATIVE");
+		}
+
+		return new ijRowResult(rs, rs.relative(row));
+	}
+
+	/**
+	 * Position before the first row of the specified ResultSet
+	 * and return NULL to the user.
+	 *
+	 * @param rs	The specified ResultSet.
+	 *
+	 * @return	NULL.
+	 *
+	 * @exception	SQLException thrown on error.
+	 *				(beforeFirst() not supported pre-JDBC2.0)
+	 */
+	public ijResult beforeFirst(ResultSet rs)
+		throws SQLException
+	{
+    	boolean forwardOnly;
+        try {
+        	forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
+        } catch (AbstractMethodError ame) {
+        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
+        //to jdbc 1.x functionality
+            forwardOnly = true;
+        }
+		// before first is only allowed on scroll cursors
+		if (forwardOnly)
+		{
+			throw ijException.forwardOnlyCursor("BEFORE FIRST");
+		}
+
+		rs.beforeFirst();
+		return new ijRowResult(rs, false);
+	}
+
+	/**
+	 * Position on the first row of the specified ResultSet
+	 * and return that row to the user.
+	 *
+	 * @param rs	The specified ResultSet.
+	 *
+	 * @return	The first row of the ResultSet.
+	 *
+	 * @exception	SQLException thrown on error.
+	 *				(first() not supported pre-JDBC2.0)
+	 */
+	public ijResult first(ResultSet rs)
+		throws SQLException
+	{
+    	boolean forwardOnly;
+        try {
+        	forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
+        } catch (AbstractMethodError ame) {
+        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
+        //to jdbc 1.x functionality
+            forwardOnly = true;
+        }
+		// first is only allowed on scroll cursors
+		if (forwardOnly)
+		{
+			throw ijException.forwardOnlyCursor("FIRST");
+		}
+
+		return new ijRowResult(rs, rs.first());
+	}
+
+	/**
+	 * Position after the last row of the specified ResultSet
+	 * and return NULL to the user.
+	 *
+	 * @param rs	The specified ResultSet.
+	 *
+	 * @return	NULL.
+	 *
+	 * @exception	SQLException thrown on error.
+	 *				(afterLast() not supported pre-JDBC2.0)
+	 */
+	public ijResult afterLast(ResultSet rs)
+		throws SQLException
+	{
+    	boolean forwardOnly;
+        try {
+        	forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
+        } catch (AbstractMethodError ame) {
+        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
+        //to jdbc 1.x functionality
+            forwardOnly = true;
+        }
+		// after last is only allowed on scroll cursors
+		if (forwardOnly)
+		{
+			throw ijException.forwardOnlyCursor("AFTER LAST");
+		}
+
+		rs.afterLast();
+		return new ijRowResult(rs, false);
+	}
+
+	/**
+	 * Position on the last row of the specified ResultSet
+	 * and return that row to the user.
+	 *
+	 * @param rs	The specified ResultSet.
+	 *
+	 * @return	The last row of the ResultSet.
+	 *
+	 * @exception	SQLException thrown on error.
+	 *				(last() not supported pre-JDBC2.0)
+	 */
+	public ijResult last(ResultSet rs)
+		throws SQLException
+	{
+    	boolean forwardOnly;
+        try {
+        	forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
+        } catch (AbstractMethodError ame) {
+        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
+        //to jdbc 1.x functionality
+            forwardOnly = true;
+        }
+		// last is only allowed on scroll cursors
+		if (forwardOnly)
+		{
+			throw ijException.forwardOnlyCursor("LAST");
+		}
+
+		return new ijRowResult(rs, rs.last());
+	}
+
+	/**
+	 * Position on the previous row of the specified ResultSet
+	 * and return that row to the user.
+	 *
+	 * @param rs	The specified ResultSet.
+	 *
+	 * @return	The previous row of the ResultSet.
+	 *
+	 * @exception	SQLException thrown on error.
+	 *				(previous() not supported pre-JDBC2.0)
+	 */
+	public ijResult previous(ResultSet rs)
+		throws SQLException
+	{
+    	boolean forwardOnly;
+        try {
+        	forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
+        } catch (AbstractMethodError ame) {
+        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
+        //to jdbc 1.x functionality
+            forwardOnly = true;
+        }
+		// first is only allowed on scroll cursors
+		if (forwardOnly)
+		{
+			throw ijException.forwardOnlyCursor("PREVIOUS");
+		}
+
+		return new ijRowResult(rs, rs.previous());
+	}
+
+	/**
+	 * Get the current row number
+	 *
+	 * @param rs	The specified ResultSet.
+	 *
+	 * @return	The current row number
+	 *
+	 * @exception	SQLException thrown on error.
+	 *				(getRow() not supported pre-JDBC2.0)
+	 */
+	public int getCurrentRowNumber(ResultSet rs)
+		throws SQLException
+	{
+		boolean forwardOnly;
+		try 
+		{
+			forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
+		} catch (AbstractMethodError ame) 
+		{
+			//because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
+			//to jdbc 1.x functionality
+			forwardOnly = true;
+        }
+
+		// getCurrentRow is only allowed on scroll cursors
+		if (forwardOnly)
+		{
+			throw ijException.forwardOnlyCursor("GETCURRENTROWNUMBER");
+		}
+
+		return rs.getRow();
+	}
+
+	public Properties getConnAttributeDefaults ()
+	{
+		return connAttributeDefaults;
+	}
+
+	public final Object run() {
+		return  getClass().getResourceAsStream(ProductGenusNames.TOOLS_INFO);
+	}
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/utilMain14.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/utilMain14.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/utilMain14.java	Fri Sep 24 10:33:20 2004
@@ -1,145 +1,145 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 2002, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-                
-import org.apache.derby.iapi.reference.JDBC20Translation;
-import org.apache.derby.iapi.reference.JDBC30Translation;
-
-import java.util.Hashtable;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-import org.apache.derby.iapi.tools.i18n.LocalizedOutput;
-/**
-	This class is utilities specific to the two ij Main's.
-	This factoring enables sharing the functionality for
-	single and dual connection ij runs.
-
-	@author jerry
- */
-public class utilMain14 extends utilMain
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2002_2004;
-    private static final String JDBC_NOTSUPPORTED = "JDBC 3 method called - not yet supported";
-	/**
-	 * Set up the test to run with 'numConnections' connections/users.
-	 *
-	 * @param numConnections	The number of connections/users to test.
-	 *
-	 * @return Nothing.
-	 */
-	public utilMain14(int numConnections, LocalizedOutput out)
-		throws ijFatalException
-	{
-		super(numConnections, out, (Hashtable)null);
-	}
-
-	/**
-	 * Set up the test to run with 'numConnections' connections/users.
-	 *
-	 * @param numConnections	The number of connections/users to test.
-	 * @param ignoreErrors		A list of errors to ignore.  If null,
-	 *							all errors are printed out and nothing
-	 *							is fatal.  If non-null, if an error is
-	 *							hit and it is in this list, it is silently	
-	 *							ignore.  Otherwise, an ijFatalException is
-	 *							thrown.  ignoreErrors is used for stress
-	 *							tests.
-	 *
-	 * @return Nothing.
-	 */
-	public utilMain14(int numConnections, LocalizedOutput out, Hashtable ignoreErrors)
-		throws ijFatalException
-	{
-		super(numConnections, out, ignoreErrors);
-	}
-
-	/**
-	 * Return the right utilMain to use.  (JDBC 1.1 or 2.0 or 3.0)
-	 *
-	 */
-	public utilMain getUtilMain()
-	{
-		return this;
-	}
-
-	/**
-	 * Connections by default create ResultSet objects with holdability true. This method can be used
-	 * to change the holdability of the connection by passing one of ResultSet.HOLD_CURSORS_OVER_COMMIT
-	 * or ResultSet.CLOSE_CURSORS_AT_COMMIT
-	 *
-	 * @param conn			The connection.
-	 * @param holdType	The new holdability for the Connection object.
-	 *
-	 * @return	The connection object with holdability set to passed value.
-	 */
-	public Connection setHoldability(Connection conn, int holdType)
-		throws SQLException
-	{
-		conn.setHoldability(holdType);
-		return conn;
-	}
-
-	/**
-		JDBC 3.0
-	 * Retrieves the current holdability of ResultSet objects created using this
-	 * Connection object.
-	 *
-	 *
-	 * @return  The holdability, one of ResultSet.HOLD_CURSORS_OVER_COMMIT
-	 * or ResultSet.CLOSE_CURSORS_AT_COMMIT
-	 *
-	 */
-	public int getHoldability(Connection conn)
-		throws SQLException
-	{
-		return conn.getHoldability();
-	}
-
-	/**
-	 * Create the right kind of statement (scrolling or not)
-	 * off of the specified connection.
-	 *
-	 * @param conn			The connection.
-	 * @param scrollType	The scroll type of the cursor.
-	 *
-	 * @return	The statement.
-	 */
-	public Statement createStatement(Connection conn, int scrollType, int holdType)
-		throws SQLException
-	{
-    	Statement stmt;
-        try {
-        	stmt = conn.createStatement(scrollType, JDBC20Translation.CONCUR_READ_ONLY, holdType);
-        }catch(SQLException se) {
-			//since jcc doesn't yet support JDBC3.0 we have to go back to JDBC2.0 
-			if (isJCC && se.getMessage().equals(JDBC_NOTSUPPORTED))
-	        	stmt = conn.createStatement(scrollType, JDBC20Translation.CONCUR_READ_ONLY);
-			else 
-				throw se;
-		}
-        catch(AbstractMethodError ame) {
-	        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need
-	        //to go back to jdbc 1.x functionality
-			//The jcc obfuscated jar gets this error
-			if (isJCC)
-	        	stmt = conn.createStatement(scrollType, JDBC20Translation.CONCUR_READ_ONLY);
-			else
-	        	stmt = conn.createStatement();
-		}
-		return stmt;
-	}
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 2002, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+                
+import org.apache.derby.iapi.reference.JDBC20Translation;
+import org.apache.derby.iapi.reference.JDBC30Translation;
+
+import java.util.Hashtable;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.derby.iapi.tools.i18n.LocalizedOutput;
+/**
+	This class is utilities specific to the two ij Main's.
+	This factoring enables sharing the functionality for
+	single and dual connection ij runs.
+
+	@author jerry
+ */
+public class utilMain14 extends utilMain
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2002_2004;
+    private static final String JDBC_NOTSUPPORTED = "JDBC 3 method called - not yet supported";
+	/**
+	 * Set up the test to run with 'numConnections' connections/users.
+	 *
+	 * @param numConnections	The number of connections/users to test.
+	 *
+	 * @return Nothing.
+	 */
+	public utilMain14(int numConnections, LocalizedOutput out)
+		throws ijFatalException
+	{
+		super(numConnections, out, (Hashtable)null);
+	}
+
+	/**
+	 * Set up the test to run with 'numConnections' connections/users.
+	 *
+	 * @param numConnections	The number of connections/users to test.
+	 * @param ignoreErrors		A list of errors to ignore.  If null,
+	 *							all errors are printed out and nothing
+	 *							is fatal.  If non-null, if an error is
+	 *							hit and it is in this list, it is silently	
+	 *							ignore.  Otherwise, an ijFatalException is
+	 *							thrown.  ignoreErrors is used for stress
+	 *							tests.
+	 *
+	 * @return Nothing.
+	 */
+	public utilMain14(int numConnections, LocalizedOutput out, Hashtable ignoreErrors)
+		throws ijFatalException
+	{
+		super(numConnections, out, ignoreErrors);
+	}
+
+	/**
+	 * Return the right utilMain to use.  (JDBC 1.1 or 2.0 or 3.0)
+	 *
+	 */
+	public utilMain getUtilMain()
+	{
+		return this;
+	}
+
+	/**
+	 * Connections by default create ResultSet objects with holdability true. This method can be used
+	 * to change the holdability of the connection by passing one of ResultSet.HOLD_CURSORS_OVER_COMMIT
+	 * or ResultSet.CLOSE_CURSORS_AT_COMMIT
+	 *
+	 * @param conn			The connection.
+	 * @param holdType	The new holdability for the Connection object.
+	 *
+	 * @return	The connection object with holdability set to passed value.
+	 */
+	public Connection setHoldability(Connection conn, int holdType)
+		throws SQLException
+	{
+		conn.setHoldability(holdType);
+		return conn;
+	}
+
+	/**
+		JDBC 3.0
+	 * Retrieves the current holdability of ResultSet objects created using this
+	 * Connection object.
+	 *
+	 *
+	 * @return  The holdability, one of ResultSet.HOLD_CURSORS_OVER_COMMIT
+	 * or ResultSet.CLOSE_CURSORS_AT_COMMIT
+	 *
+	 */
+	public int getHoldability(Connection conn)
+		throws SQLException
+	{
+		return conn.getHoldability();
+	}
+
+	/**
+	 * Create the right kind of statement (scrolling or not)
+	 * off of the specified connection.
+	 *
+	 * @param conn			The connection.
+	 * @param scrollType	The scroll type of the cursor.
+	 *
+	 * @return	The statement.
+	 */
+	public Statement createStatement(Connection conn, int scrollType, int holdType)
+		throws SQLException
+	{
+    	Statement stmt;
+        try {
+        	stmt = conn.createStatement(scrollType, JDBC20Translation.CONCUR_READ_ONLY, holdType);
+        }catch(SQLException se) {
+			//since jcc doesn't yet support JDBC3.0 we have to go back to JDBC2.0 
+			if (isJCC && se.getMessage().equals(JDBC_NOTSUPPORTED))
+	        	stmt = conn.createStatement(scrollType, JDBC20Translation.CONCUR_READ_ONLY);
+			else 
+				throw se;
+		}
+        catch(AbstractMethodError ame) {
+	        //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need
+	        //to go back to jdbc 1.x functionality
+			//The jcc obfuscated jar gets this error
+			if (isJCC)
+	        	stmt = conn.createStatement(scrollType, JDBC20Translation.CONCUR_READ_ONLY);
+			else
+	        	stmt = conn.createStatement();
+		}
+		return stmt;
+	}
+
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/xaAbstractHelper.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/xaAbstractHelper.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/xaAbstractHelper.java	Fri Sep 24 10:33:20 2004
@@ -1,48 +1,48 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1999, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-
-import java.sql.SQLException;
-import java.sql.Connection;
-
-/*
-	An interface for running xa tests.
-	The real implementation is only loaded if the requisite javax classes are
-	in the classpath. 
- */
-interface xaAbstractHelper
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1999_2004;
-
-	void XADataSourceStatement(ij parser, Token dbname, Token shut, String create) throws SQLException;
-	void XAConnectStatement(ij parser, Token user, Token pass, String id) throws SQLException;
-	void XADisconnectStatement(ij parser, String n) throws SQLException;
-	Connection XAGetConnectionStatement(ij parser, String n) throws SQLException;
-	void CommitStatement(ij parser, Token onePhase, Token twoPhase, int xid) throws SQLException;
-	void EndStatement(ij parser, int flag, int xid) throws SQLException;
-	void ForgetStatement(ij parser, int xid) throws SQLException;
-	void PrepareStatement(ij parser, int xid) throws SQLException;
-	ijResult RecoverStatement(ij parser, int flag) throws SQLException;
-	void RollbackStatement(ij parser, int xid) throws SQLException;
-	void StartStatement(ij parser, int flag, int xid) throws SQLException;
-	Connection DataSourceStatement(ij parser, Token dbname, Token protocol,
-								   Token userT, Token passT, String id) throws SQLException;
-	void CPDataSourceStatement(ij parser, Token dbname, Token protocol) throws SQLException;
-	void CPConnectStatement(ij parser, Token userT, Token passT, String n) throws SQLException;
-	Connection CPGetConnectionStatement(ij parser, String n) throws SQLException;
-	void CPDisconnectStatement(ij parser, String n) throws SQLException;
-	void setFramework(String framework);
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1999, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+
+import java.sql.SQLException;
+import java.sql.Connection;
+
+/*
+	An interface for running xa tests.
+	The real implementation is only loaded if the requisite javax classes are
+	in the classpath. 
+ */
+interface xaAbstractHelper
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1999_2004;
+
+	void XADataSourceStatement(ij parser, Token dbname, Token shut, String create) throws SQLException;
+	void XAConnectStatement(ij parser, Token user, Token pass, String id) throws SQLException;
+	void XADisconnectStatement(ij parser, String n) throws SQLException;
+	Connection XAGetConnectionStatement(ij parser, String n) throws SQLException;
+	void CommitStatement(ij parser, Token onePhase, Token twoPhase, int xid) throws SQLException;
+	void EndStatement(ij parser, int flag, int xid) throws SQLException;
+	void ForgetStatement(ij parser, int xid) throws SQLException;
+	void PrepareStatement(ij parser, int xid) throws SQLException;
+	ijResult RecoverStatement(ij parser, int flag) throws SQLException;
+	void RollbackStatement(ij parser, int xid) throws SQLException;
+	void StartStatement(ij parser, int flag, int xid) throws SQLException;
+	Connection DataSourceStatement(ij parser, Token dbname, Token protocol,
+								   Token userT, Token passT, String id) throws SQLException;
+	void CPDataSourceStatement(ij parser, Token dbname, Token protocol) throws SQLException;
+	void CPConnectStatement(ij parser, Token userT, Token passT, String n) throws SQLException;
+	Connection CPGetConnectionStatement(ij parser, String n) throws SQLException;
+	void CPDisconnectStatement(ij parser, String n) throws SQLException;
+	void setFramework(String framework);
+
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/xaHelper.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/xaHelper.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/ij/xaHelper.java	Fri Sep 24 10:33:20 2004
@@ -1,528 +1,528 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.ij
-   (C) Copyright IBM Corp. 1999, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.ij;
-
-import org.apache.derby.iapi.tools.i18n.LocalizedResource;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Locale;
-import java.util.Vector;
-
-import javax.transaction.xa.Xid;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.XAException;
-import javax.sql.PooledConnection;
-import javax.sql.XAConnection;
-import javax.sql.XADataSource;
-import javax.sql.DataSource;
-import javax.sql.ConnectionPoolDataSource;
-
-/*
- * The real xa helper class.  Load this class only if we know the javax classes
- * are in the class path.
- */
-class xaHelper implements xaAbstractHelper
-{
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1999_2004;
-
-	private XADataSource currentXADataSource;
-	private XAConnection currentXAConnection;
-
-	private String databaseName;
-
-	// non xa stuff
-	private DataSource currentDataSource;
-	private ConnectionPoolDataSource currentCPDataSource;
-	private PooledConnection currentPooledConnection;
-
-  private String framework_property;
-
-  xaHelper()
-  {
-  }
-	  
-	  
-   public void setFramework(String framework)
-  {
-    this.framework_property = framework_property;
-  }
-	
-	private Xid makeXid(int xid)
-	{
-		return new ijXid(xid, databaseName.getBytes());
-	}
-
-	public void XADataSourceStatement(ij parser, Token dbname, Token shutdown,
-									String create)
-		 throws SQLException
-	{
-		try
-		{
-			  currentXADataSource = (XADataSource) getXADataSource();
-
-			  databaseName = parser.stringValue(dbname.image);
-			  xaHelper.setDataSourceProperty(currentXADataSource, "databaseName", databaseName);
-			  xaHelper.setDataSourceProperty(currentXADataSource, "dataSourceName", databaseName);
-
-			if (shutdown != null && shutdown.toString().toLowerCase(Locale.ENGLISH).equals("shutdown"))
-			{
-			  xaHelper.setDataSourceProperty(currentXADataSource, "shutdownDatabase", "shutdown");
-
-				// do a getXAConnection to shut it down */
-				currentXADataSource.getXAConnection().getConnection();
-
-				currentXADataSource = null;
-				currentXAConnection = null;
-			}
-			else if (create != null)
-			{
-				if (create.toLowerCase(java.util.Locale.ENGLISH).equals("create"))
-				{
-					xaHelper.setDataSourceProperty(currentXADataSource, "createDatabase", "create");
-
-					/* do a getXAConnection to create it */
-					XAConnection conn = currentXADataSource.getXAConnection();
-					conn.close();
-
-					xaHelper.setDataSourceProperty(currentXADataSource, "createDatabase", null);
-				}
-			}
-		}
-		catch (Throwable t)
-		{
-			handleException(t);
-		}	
-	}
-
-
-	public void XAConnectStatement(ij parser, Token user, Token pass, String id)
-		 throws SQLException
-	{
-		try
-		{
-			if (currentXAConnection != null)
-			{
-				try {
-					currentXAConnection.close();
-				} catch (SQLException sqle) {
-				}
-
-				currentXAConnection = null;
-			}
-
-			String username = null;
-			String password = "";
-
-			if (pass != null)
-				password = parser.stringValue(pass.image);
-
-			if (user != null)
-			{
-				username = parser.stringValue(user.image);
-
-				currentXAConnection = 
-					currentXADataSource.getXAConnection(username, password);
-			}
-			else
-			{
-
-				currentXAConnection = currentXADataSource.getXAConnection();
-			}
-
-		}
-		catch (Throwable t)
-		{
-			handleException(t);
-		}
-	}
-
-	public void XADisconnectStatement(ij parser, String n) throws SQLException
-	{
-		if (currentXAConnection == null)
-			throw ijException.noSuchConnection("XAConnection");
-		currentXAConnection.close();
-		currentXAConnection = null;
-	}
-
-	public Connection XAGetConnectionStatement(ij parser, String n) throws SQLException
-	{
-		try
-		{
-			return currentXAConnection.getConnection();
-		}
-		catch(Throwable t)
-		{
-			handleException(t);
-		}
-		return null;
-	}
-
-	public void CommitStatement(ij parser, Token onePhase, Token twoPhase, 
-								int xid) 
-		 throws SQLException
-	{
-		try
-		{	
-			currentXAConnection.getXAResource().commit(makeXid(xid), (onePhase != null));
-		}
-		catch(Throwable t)
-		{
-			handleException(t);
-		}
-	}
-
-	public void EndStatement(ij parser, int flag, int xid) throws SQLException
-	{
-		try
-		{	
-			currentXAConnection.getXAResource().end(makeXid(xid), flag);
-		}
-		catch(Throwable t)
-		{
-			handleException(t);
-		}
-	}
-
-	public void ForgetStatement(ij parser, int xid) throws SQLException
-	{
-		try
-		{	
-			currentXAConnection.getXAResource().forget(makeXid(xid));
-		}
-		catch(Throwable t)
-		{
-			handleException(t);
-		}
-	}
-
-	public void PrepareStatement(ij parser, int xid) throws SQLException
-	{
-		try
-		{	
-			currentXAConnection.getXAResource().prepare(makeXid(xid));
-		}
-		catch(Throwable t)
-		{
-			handleException(t);
-		}
-	}
-
-	public ijResult RecoverStatement(ij parser, int flag) throws SQLException
-	{
-		Object[] val = null;
-
-		try
-		{	
-			val = currentXAConnection.getXAResource().recover(flag);
-		}
-		catch(Throwable t)
-		{
-			handleException(t);
-		}
-
-		Vector v = new Vector();
-		v.addElement("");
-		v.addElement(LocalizedResource.getMessage("IJ_Reco0InDoubT", LocalizedResource.getNumber(val.length)));
-		v.addElement("");
-		for (int i = 0; i < val.length; i++)
-			v.addElement(LocalizedResource.getMessage("IJ_Tran01", LocalizedResource.getNumber(i+1), val[i].toString()));
-
-		return new ijVectorResult(v,null);
-
-	}
-
-	public void RollbackStatement(ij parser, int xid) throws SQLException
-	{
-		try
-		{	
-			currentXAConnection.getXAResource().rollback(makeXid(xid));
-		}
-		catch(Throwable t)
-		{
-			handleException(t);
-		}
-
-	}
-
-	public void StartStatement(ij parser, int flag, int xid) throws SQLException
-	{
-		try
-		{	
-			currentXAConnection.getXAResource().start(makeXid(xid), flag);
-		}
-		catch(Throwable t)
-		{
-			handleException(t);
-		}
-	}
-
-	private void handleException(Throwable t) throws SQLException
-	{
-		if (t instanceof SQLException)
-		{
-			// let ij handle it
-			throw (SQLException)t;
-		}
-		if (t instanceof XAException)
-		{
-			int errorCode = ((XAException)t).errorCode;
-			String error = LocalizedResource.getMessage("IJ_IlleValu");
-
-			// XA_RBBASE 100
-			// XA_RBROLLBACK 100
-			// XA_RBCOMMFAIL 101
-			// XA_RBDEADLOCK 102
-			// XA_RBINTEGRITY 103
-			// XA_RBOTHER 104
-			// XA_RBPROTO 105
-			// XA_RBTIMEOUT 106
-			// XA_RBTRANSIENT 107
-			// XA_RBEND 107
-			//
-			// XA_RDONLY 3
-			// XA_RETRY 4
-			// XA_HEURMIX 5
-			// XA_HEURRB 6
-			// XA_HEURCOM 7
-			// XA_HEURHAZ 8
-			// XA_NOMIGRATE 9
-			//
-			// XAER_ASYNC -2
-			// XAER_RMERR -3
-			// XAER_NOTA -4
-			// XAER_INVAL -5
-			// XAER_PROTO -6
-			// XAER_RMFAIL -7
-			// XAER_DUPID -8
-			// XAER_OUTSIDE -9
-
-			switch(errorCode)
-			{
-			case XAException.XA_HEURCOM : error = "XA_HEURCOM "; break;
-			case XAException.XA_HEURHAZ : error = "XA_HEURHAZ"; break;
-			case XAException.XA_HEURMIX : error = "XA_HEURMIX"; break;
-			case XAException.XA_HEURRB : error = "XA_HEURRB "; break;
-			case XAException.XA_NOMIGRATE : error = "XA_NOMIGRATE "; break;
-				// case XAException.XA_RBBASE : error = "XA_RBBASE "; break;
-			case XAException.XA_RBCOMMFAIL : error = "XA_RBCOMMFAIL "; break;
-			case XAException.XA_RBDEADLOCK : error = "XA_RBDEADLOCK "; break;
-				// case XAException.XA_RBEND : error = "XA_RBEND "; break;
-			case XAException.XA_RBINTEGRITY : error = "XA_RBINTEGRITY "; break;
-			case XAException.XA_RBOTHER : error = "XA_RBOTHER "; break;
-			case XAException.XA_RBPROTO : error = "XA_RBPROTO "; break;
-			case XAException.XA_RBROLLBACK : error = "XA_RBROLLBACK "; break;
-			case XAException.XA_RBTIMEOUT : error = "XA_RBTIMEOUT "; break;
-			case XAException.XA_RBTRANSIENT : error = "XA_RBTRANSIENT "; break;
-			case XAException.XA_RDONLY : error = "XA_RDONLY "; break;
-			case XAException.XA_RETRY : error = "XA_RETRY "; break;
-			case XAException.XAER_ASYNC : error = "XAER_ASYNC "; break;
-			case XAException.XAER_DUPID : error = "XAER_DUPID "; break;
-			case XAException.XAER_INVAL : error = "XAER_INVAL "; break;
-			case XAException.XAER_NOTA : error = "XAER_NOTA "; break;
-			case XAException.XAER_OUTSIDE : error = "XAER_OUTSIDE "; break;
-			case XAException.XAER_PROTO : error = "XAER_PROTO "; break;
-			case XAException.XAER_RMERR : error = "XAER_RMERR "; break;
-			case XAException.XAER_RMFAIL : error = "XAER_RMFAIL "; break;
-			}
-			throw new ijException(error);
-
-		}
-		else // StandardException or run time exception, log it first
-		{
-			String info = LocalizedResource.getMessage("IJ_01SeeClouLog", t.toString(), t.getMessage());
-			t.printStackTrace(System.out);
-			throw new ijException(info);
-		}
-	}
-
-
-	// non-xa stuff. DataSource and ConnectionPoolDataSource
-	public Connection DataSourceStatement(ij parser, Token dbname, Token protocol,
-									Token userT, Token passT, String id)
-		 throws SQLException
-	{
-
-		try {
-			currentDataSource = (DataSource) (Class.forName("org.apache.derby.jdbc.EmbeddedDataSource").newInstance());
-		} catch (Exception e) {
-			throw new SQLException(e.toString());
-		}
-		databaseName = parser.stringValue(dbname.image);
-		xaHelper.setDataSourceProperty(currentDataSource, "databaseName", databaseName);
-
-		// make a connection
-		Connection c = null;
-		String username = null;
-		String password = "";
-
-		if (passT != null)
-			password = parser.stringValue(passT.image);
-
-		if (userT != null)
-		{
-			username = parser.stringValue(userT.image);
-			c = currentDataSource.getConnection(username, password);
-		}
-		else
-		{
-			c = currentDataSource.getConnection();
-		}
-
-		return c;
-
-	}
-
-	public void CPDataSourceStatement(ij parser, Token dbname, Token protocol)
-		 throws SQLException
-	{
-		try {
-			currentCPDataSource = (ConnectionPoolDataSource) (Class.forName("org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource").newInstance());
-		} catch (Exception e) {
-			throw new SQLException(e.toString());
-		}
-		databaseName = parser.stringValue(dbname.image);
-		xaHelper.setDataSourceProperty(currentCPDataSource, "databaseName", databaseName);
-	}
-
-	public void CPConnectStatement(ij parser, Token userT, Token passT, String n)
-		 throws SQLException
-	{
-		String username = null;
-		String password = "";
-
-		if (passT != null)
-			password = parser.stringValue(passT.image);
-
-		if (userT != null)
-		{
-			username = parser.stringValue(userT.image);
-			currentPooledConnection =
-				currentCPDataSource.getPooledConnection(username, password);
-		}
-		else
-		{
-			currentPooledConnection =
-				currentCPDataSource.getPooledConnection();
-		}
-	}
-
-	public Connection CPGetConnectionStatement(ij parser, String n) 
-		 throws SQLException 
-	{
-		return currentPooledConnection.getConnection();
-	}
-
-	public void CPDisconnectStatement(ij parser, String n) throws SQLException
-	{
-		if (currentPooledConnection == null)
-			throw ijException.noSuchConnection(LocalizedResource.getMessage("IJ_Pool"));
-		currentPooledConnection.close();
-		currentPooledConnection = null;
-	}
-
-	/**
-	 * Get a DataSource that supports distributed transactions.
-	 *
-	 * @return XADataSource object 
-	 *
-	 * @exception Exception if XaDataSource is not in class path.
-	 */
-	private XADataSource getXADataSource() throws Exception
-	{
-		// We need to construct this object in this round about fashion because
-		// if we new it directly, then it will the tools.jar file to bloat.
-		try
-		{
-			return (XADataSource)(Class.forName("org.apache.derby.jdbc.EmbeddedXADataSource").newInstance());
-		}
-		catch(ClassNotFoundException cnfe) {
-			throw new ijException(LocalizedResource.getMessage("IJ_XAClass"));
-		}
-		catch (InstantiationException e) { }
-		catch (IllegalAccessException e) { }
-
-		throw new ijException(LocalizedResource.getMessage("IJ_XANoI"));
-	}
-	private static final Class[] STRING_P = { copyrightNotice.getClass() };
-	private static final Class[] INT_P = { Integer.TYPE };
-
-	private static void setDataSourceProperty(Object ds, String property, String value) throws SQLException {
-
-		String methodName =
-			"set" + Character.toUpperCase(property.charAt(0)) + property.substring(1);
-
-		try {
-			java.lang.reflect.Method m = ds.getClass().getMethod(methodName, STRING_P);
-			m.invoke(ds, new Object[] {value});
-			return;
-		} catch (/*NoSuchMethod*/Exception nsme) {
-			throw new SQLException(property + " ???");
-			//java.lang.reflect.Method m = ds.getClass().getMethod("set" + property, INT_P);
-			//m.invoke(ds, new Object[] {Integer.valueOf(value)});
-		}
-	}
-}
-
-class ijXid implements Xid, java.io.Serializable
-{
-  private static final long serialVersionUID = 64467452100036L;
-
-	private final int format_id;
-	private final byte[] global_id;
-	private final byte[] branch_id;
-
-
-	ijXid(int xid, byte[] id)
-	{
-		format_id = xid;
-		global_id = id;
-		branch_id = id;
-		
-	}
-    /**
-     * Obtain the format id part of the Xid.
-     * <p>
-     *
-     * @return Format identifier. O means the OSI CCR format.
-     **/
-    public int getFormatId()
-    {
-        return(format_id);
-    }
-
-    /**
-     * Obtain the global transaction identifier part of XID as an array of 
-     * bytes.
-     * <p>
-     *
-	 * @return A byte array containing the global transaction identifier.
-     **/
-    public byte[] getGlobalTransactionId()
-    {
-        return(global_id);
-    }
-
-    /**
-     * Obtain the transaction branch qualifier part of the Xid in a byte array.
-     * <p>
-     *
-	 * @return A byte array containing the branch qualifier of the transaction.
-     **/
-    public byte[] getBranchQualifier()
-    {
-        return(branch_id);
-    }
-}
-
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.ij
+   (C) Copyright IBM Corp. 1999, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.ij;
+
+import org.apache.derby.iapi.tools.i18n.LocalizedResource;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.XAException;
+import javax.sql.PooledConnection;
+import javax.sql.XAConnection;
+import javax.sql.XADataSource;
+import javax.sql.DataSource;
+import javax.sql.ConnectionPoolDataSource;
+
+/*
+ * The real xa helper class.  Load this class only if we know the javax classes
+ * are in the class path.
+ */
+class xaHelper implements xaAbstractHelper
+{
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1999_2004;
+
+	private XADataSource currentXADataSource;
+	private XAConnection currentXAConnection;
+
+	private String databaseName;
+
+	// non xa stuff
+	private DataSource currentDataSource;
+	private ConnectionPoolDataSource currentCPDataSource;
+	private PooledConnection currentPooledConnection;
+
+  private String framework_property;
+
+  xaHelper()
+  {
+  }
+	  
+	  
+   public void setFramework(String framework)
+  {
+    this.framework_property = framework_property;
+  }
+	
+	private Xid makeXid(int xid)
+	{
+		return new ijXid(xid, databaseName.getBytes());
+	}
+
+	public void XADataSourceStatement(ij parser, Token dbname, Token shutdown,
+									String create)
+		 throws SQLException
+	{
+		try
+		{
+			  currentXADataSource = (XADataSource) getXADataSource();
+
+			  databaseName = parser.stringValue(dbname.image);
+			  xaHelper.setDataSourceProperty(currentXADataSource, "databaseName", databaseName);
+			  xaHelper.setDataSourceProperty(currentXADataSource, "dataSourceName", databaseName);
+
+			if (shutdown != null && shutdown.toString().toLowerCase(Locale.ENGLISH).equals("shutdown"))
+			{
+			  xaHelper.setDataSourceProperty(currentXADataSource, "shutdownDatabase", "shutdown");
+
+				// do a getXAConnection to shut it down */
+				currentXADataSource.getXAConnection().getConnection();
+
+				currentXADataSource = null;
+				currentXAConnection = null;
+			}
+			else if (create != null)
+			{
+				if (create.toLowerCase(java.util.Locale.ENGLISH).equals("create"))
+				{
+					xaHelper.setDataSourceProperty(currentXADataSource, "createDatabase", "create");
+
+					/* do a getXAConnection to create it */
+					XAConnection conn = currentXADataSource.getXAConnection();
+					conn.close();
+
+					xaHelper.setDataSourceProperty(currentXADataSource, "createDatabase", null);
+				}
+			}
+		}
+		catch (Throwable t)
+		{
+			handleException(t);
+		}	
+	}
+
+
+	public void XAConnectStatement(ij parser, Token user, Token pass, String id)
+		 throws SQLException
+	{
+		try
+		{
+			if (currentXAConnection != null)
+			{
+				try {
+					currentXAConnection.close();
+				} catch (SQLException sqle) {
+				}
+
+				currentXAConnection = null;
+			}
+
+			String username = null;
+			String password = "";
+
+			if (pass != null)
+				password = parser.stringValue(pass.image);
+
+			if (user != null)
+			{
+				username = parser.stringValue(user.image);
+
+				currentXAConnection = 
+					currentXADataSource.getXAConnection(username, password);
+			}
+			else
+			{
+
+				currentXAConnection = currentXADataSource.getXAConnection();
+			}
+
+		}
+		catch (Throwable t)
+		{
+			handleException(t);
+		}
+	}
+
+	public void XADisconnectStatement(ij parser, String n) throws SQLException
+	{
+		if (currentXAConnection == null)
+			throw ijException.noSuchConnection("XAConnection");
+		currentXAConnection.close();
+		currentXAConnection = null;
+	}
+
+	public Connection XAGetConnectionStatement(ij parser, String n) throws SQLException
+	{
+		try
+		{
+			return currentXAConnection.getConnection();
+		}
+		catch(Throwable t)
+		{
+			handleException(t);
+		}
+		return null;
+	}
+
+	public void CommitStatement(ij parser, Token onePhase, Token twoPhase, 
+								int xid) 
+		 throws SQLException
+	{
+		try
+		{	
+			currentXAConnection.getXAResource().commit(makeXid(xid), (onePhase != null));
+		}
+		catch(Throwable t)
+		{
+			handleException(t);
+		}
+	}
+
+	public void EndStatement(ij parser, int flag, int xid) throws SQLException
+	{
+		try
+		{	
+			currentXAConnection.getXAResource().end(makeXid(xid), flag);
+		}
+		catch(Throwable t)
+		{
+			handleException(t);
+		}
+	}
+
+	public void ForgetStatement(ij parser, int xid) throws SQLException
+	{
+		try
+		{	
+			currentXAConnection.getXAResource().forget(makeXid(xid));
+		}
+		catch(Throwable t)
+		{
+			handleException(t);
+		}
+	}
+
+	public void PrepareStatement(ij parser, int xid) throws SQLException
+	{
+		try
+		{	
+			currentXAConnection.getXAResource().prepare(makeXid(xid));
+		}
+		catch(Throwable t)
+		{
+			handleException(t);
+		}
+	}
+
+	public ijResult RecoverStatement(ij parser, int flag) throws SQLException
+	{
+		Object[] val = null;
+
+		try
+		{	
+			val = currentXAConnection.getXAResource().recover(flag);
+		}
+		catch(Throwable t)
+		{
+			handleException(t);
+		}
+
+		Vector v = new Vector();
+		v.addElement("");
+		v.addElement(LocalizedResource.getMessage("IJ_Reco0InDoubT", LocalizedResource.getNumber(val.length)));
+		v.addElement("");
+		for (int i = 0; i < val.length; i++)
+			v.addElement(LocalizedResource.getMessage("IJ_Tran01", LocalizedResource.getNumber(i+1), val[i].toString()));
+
+		return new ijVectorResult(v,null);
+
+	}
+
+	public void RollbackStatement(ij parser, int xid) throws SQLException
+	{
+		try
+		{	
+			currentXAConnection.getXAResource().rollback(makeXid(xid));
+		}
+		catch(Throwable t)
+		{
+			handleException(t);
+		}
+
+	}
+
+	public void StartStatement(ij parser, int flag, int xid) throws SQLException
+	{
+		try
+		{	
+			currentXAConnection.getXAResource().start(makeXid(xid), flag);
+		}
+		catch(Throwable t)
+		{
+			handleException(t);
+		}
+	}
+
+	private void handleException(Throwable t) throws SQLException
+	{
+		if (t instanceof SQLException)
+		{
+			// let ij handle it
+			throw (SQLException)t;
+		}
+		if (t instanceof XAException)
+		{
+			int errorCode = ((XAException)t).errorCode;
+			String error = LocalizedResource.getMessage("IJ_IlleValu");
+
+			// XA_RBBASE 100
+			// XA_RBROLLBACK 100
+			// XA_RBCOMMFAIL 101
+			// XA_RBDEADLOCK 102
+			// XA_RBINTEGRITY 103
+			// XA_RBOTHER 104
+			// XA_RBPROTO 105
+			// XA_RBTIMEOUT 106
+			// XA_RBTRANSIENT 107
+			// XA_RBEND 107
+			//
+			// XA_RDONLY 3
+			// XA_RETRY 4
+			// XA_HEURMIX 5
+			// XA_HEURRB 6
+			// XA_HEURCOM 7
+			// XA_HEURHAZ 8
+			// XA_NOMIGRATE 9
+			//
+			// XAER_ASYNC -2
+			// XAER_RMERR -3
+			// XAER_NOTA -4
+			// XAER_INVAL -5
+			// XAER_PROTO -6
+			// XAER_RMFAIL -7
+			// XAER_DUPID -8
+			// XAER_OUTSIDE -9
+
+			switch(errorCode)
+			{
+			case XAException.XA_HEURCOM : error = "XA_HEURCOM "; break;
+			case XAException.XA_HEURHAZ : error = "XA_HEURHAZ"; break;
+			case XAException.XA_HEURMIX : error = "XA_HEURMIX"; break;
+			case XAException.XA_HEURRB : error = "XA_HEURRB "; break;
+			case XAException.XA_NOMIGRATE : error = "XA_NOMIGRATE "; break;
+				// case XAException.XA_RBBASE : error = "XA_RBBASE "; break;
+			case XAException.XA_RBCOMMFAIL : error = "XA_RBCOMMFAIL "; break;
+			case XAException.XA_RBDEADLOCK : error = "XA_RBDEADLOCK "; break;
+				// case XAException.XA_RBEND : error = "XA_RBEND "; break;
+			case XAException.XA_RBINTEGRITY : error = "XA_RBINTEGRITY "; break;
+			case XAException.XA_RBOTHER : error = "XA_RBOTHER "; break;
+			case XAException.XA_RBPROTO : error = "XA_RBPROTO "; break;
+			case XAException.XA_RBROLLBACK : error = "XA_RBROLLBACK "; break;
+			case XAException.XA_RBTIMEOUT : error = "XA_RBTIMEOUT "; break;
+			case XAException.XA_RBTRANSIENT : error = "XA_RBTRANSIENT "; break;
+			case XAException.XA_RDONLY : error = "XA_RDONLY "; break;
+			case XAException.XA_RETRY : error = "XA_RETRY "; break;
+			case XAException.XAER_ASYNC : error = "XAER_ASYNC "; break;
+			case XAException.XAER_DUPID : error = "XAER_DUPID "; break;
+			case XAException.XAER_INVAL : error = "XAER_INVAL "; break;
+			case XAException.XAER_NOTA : error = "XAER_NOTA "; break;
+			case XAException.XAER_OUTSIDE : error = "XAER_OUTSIDE "; break;
+			case XAException.XAER_PROTO : error = "XAER_PROTO "; break;
+			case XAException.XAER_RMERR : error = "XAER_RMERR "; break;
+			case XAException.XAER_RMFAIL : error = "XAER_RMFAIL "; break;
+			}
+			throw new ijException(error);
+
+		}
+		else // StandardException or run time exception, log it first
+		{
+			String info = LocalizedResource.getMessage("IJ_01SeeClouLog", t.toString(), t.getMessage());
+			t.printStackTrace(System.out);
+			throw new ijException(info);
+		}
+	}
+
+
+	// non-xa stuff. DataSource and ConnectionPoolDataSource
+	public Connection DataSourceStatement(ij parser, Token dbname, Token protocol,
+									Token userT, Token passT, String id)
+		 throws SQLException
+	{
+
+		try {
+			currentDataSource = (DataSource) (Class.forName("org.apache.derby.jdbc.EmbeddedDataSource").newInstance());
+		} catch (Exception e) {
+			throw new SQLException(e.toString());
+		}
+		databaseName = parser.stringValue(dbname.image);
+		xaHelper.setDataSourceProperty(currentDataSource, "databaseName", databaseName);
+
+		// make a connection
+		Connection c = null;
+		String username = null;
+		String password = "";
+
+		if (passT != null)
+			password = parser.stringValue(passT.image);
+
+		if (userT != null)
+		{
+			username = parser.stringValue(userT.image);
+			c = currentDataSource.getConnection(username, password);
+		}
+		else
+		{
+			c = currentDataSource.getConnection();
+		}
+
+		return c;
+
+	}
+
+	public void CPDataSourceStatement(ij parser, Token dbname, Token protocol)
+		 throws SQLException
+	{
+		try {
+			currentCPDataSource = (ConnectionPoolDataSource) (Class.forName("org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource").newInstance());
+		} catch (Exception e) {
+			throw new SQLException(e.toString());
+		}
+		databaseName = parser.stringValue(dbname.image);
+		xaHelper.setDataSourceProperty(currentCPDataSource, "databaseName", databaseName);
+	}
+
+	public void CPConnectStatement(ij parser, Token userT, Token passT, String n)
+		 throws SQLException
+	{
+		String username = null;
+		String password = "";
+
+		if (passT != null)
+			password = parser.stringValue(passT.image);
+
+		if (userT != null)
+		{
+			username = parser.stringValue(userT.image);
+			currentPooledConnection =
+				currentCPDataSource.getPooledConnection(username, password);
+		}
+		else
+		{
+			currentPooledConnection =
+				currentCPDataSource.getPooledConnection();
+		}
+	}
+
+	public Connection CPGetConnectionStatement(ij parser, String n) 
+		 throws SQLException 
+	{
+		return currentPooledConnection.getConnection();
+	}
+
+	public void CPDisconnectStatement(ij parser, String n) throws SQLException
+	{
+		if (currentPooledConnection == null)
+			throw ijException.noSuchConnection(LocalizedResource.getMessage("IJ_Pool"));
+		currentPooledConnection.close();
+		currentPooledConnection = null;
+	}
+
+	/**
+	 * Get a DataSource that supports distributed transactions.
+	 *
+	 * @return XADataSource object 
+	 *
+	 * @exception Exception if XaDataSource is not in class path.
+	 */
+	private XADataSource getXADataSource() throws Exception
+	{
+		// We need to construct this object in this round about fashion because
+		// if we new it directly, then it will the tools.jar file to bloat.
+		try
+		{
+			return (XADataSource)(Class.forName("org.apache.derby.jdbc.EmbeddedXADataSource").newInstance());
+		}
+		catch(ClassNotFoundException cnfe) {
+			throw new ijException(LocalizedResource.getMessage("IJ_XAClass"));
+		}
+		catch (InstantiationException e) { }
+		catch (IllegalAccessException e) { }
+
+		throw new ijException(LocalizedResource.getMessage("IJ_XANoI"));
+	}
+	private static final Class[] STRING_P = { copyrightNotice.getClass() };
+	private static final Class[] INT_P = { Integer.TYPE };
+
+	private static void setDataSourceProperty(Object ds, String property, String value) throws SQLException {
+
+		String methodName =
+			"set" + Character.toUpperCase(property.charAt(0)) + property.substring(1);
+
+		try {
+			java.lang.reflect.Method m = ds.getClass().getMethod(methodName, STRING_P);
+			m.invoke(ds, new Object[] {value});
+			return;
+		} catch (/*NoSuchMethod*/Exception nsme) {
+			throw new SQLException(property + " ???");
+			//java.lang.reflect.Method m = ds.getClass().getMethod("set" + property, INT_P);
+			//m.invoke(ds, new Object[] {Integer.valueOf(value)});
+		}
+	}
+}
+
+class ijXid implements Xid, java.io.Serializable
+{
+  private static final long serialVersionUID = 64467452100036L;
+
+	private final int format_id;
+	private final byte[] global_id;
+	private final byte[] branch_id;
+
+
+	ijXid(int xid, byte[] id)
+	{
+		format_id = xid;
+		global_id = id;
+		branch_id = id;
+		
+	}
+    /**
+     * Obtain the format id part of the Xid.
+     * <p>
+     *
+     * @return Format identifier. O means the OSI CCR format.
+     **/
+    public int getFormatId()
+    {
+        return(format_id);
+    }
+
+    /**
+     * Obtain the global transaction identifier part of XID as an array of 
+     * bytes.
+     * <p>
+     *
+	 * @return A byte array containing the global transaction identifier.
+     **/
+    public byte[] getGlobalTransactionId()
+    {
+        return(global_id);
+    }
+
+    /**
+     * Obtain the transaction branch qualifier part of the Xid in a byte array.
+     * <p>
+     *
+	 * @return A byte array containing the branch qualifier of the transaction.
+     **/
+    public byte[] getBranchQualifier()
+    {
+        return(branch_id);
+    }
+}
+
+

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/sysinfo/Main.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/sysinfo/Main.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/sysinfo/Main.java	Fri Sep 24 10:33:20 2004
@@ -1,951 +1,951 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.sysinfo
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.impl.tools.sysinfo;
-
-import java.util.Locale;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.io.InputStream;
-import java.util.Properties;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-import java.util.StringTokenizer;
-import java.io.File;
-import java.util.zip.ZipFile;
-import java.io.IOException;
-import java.util.zip.ZipEntry;
-import java.io.FileInputStream;
-import java.util.Vector;
-import java.io.InputStream;
-import java.lang.reflect.Method;
-
-import org.apache.derby.iapi.services.info.PropertyNames;
-import org.apache.derby.iapi.services.info.ProductVersionHolder;
-import org.apache.derby.iapi.services.info.ProductGenusNames;
-import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.tools.i18n.*;
-
-
-/**
-  <i>Copyright &#169; 1998, Cloudscape, Inc.   All rights reserved.</i>
-
-  <P>
-  SysInfo reports values relevant to the Cloudscape product found on
-  the CLASSPATH.  It looks for a file called sysinfo.properties in
-  the CLASSPATH using getResourceAsStream. If the file
-  is not found, or some other exception occurs, the
-  value returned will be that set for the key
-  SysInfo.failureTag, or be the value "<info unavailable>".
-
-  <P>
-  This class can be used to print out system information at the
-  command line by issuing the command:
-  <PRE>
-    java com.ibm.db2j.tools.SysInfo.main
-  </PRE>
-  Alternatively, you can use SysInfo within your program to display
-  Cloudscape information; a Cloudscape version string is returned by this Java code:
-  <PRE>
-    new Main().toString();
-  </PRE>
-
- */
-
-
-public final class Main {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-
-  /**
-    Application entry point for SysInfo.   This will print out
-    the Cloudscape product information as well as a snapshot of
-    the System properties.
-  */
-  public static void main(String args[]) {
-        // adjust the application in accordance with derby.ui.locale and derby.ui.codeset
-        LocalizedResource.getInstance();
-
-		LocalizedOutput out;
-
-        //using AppStreamReader(extends InputStreamReader) for conversion into specific codeset
-
-		out = LocalizedResource.OutputWriter();
-
-       // because we're in a static method, we need to
-       // get our own instance variable
-    parseArgs (args);
-
-    if (cptester == true)
-	getClasspathInfo (args, out);
-    else
-	getMainInfo (out, setPause);
-
-  } // end of main (String args[])
-
-public static void getMainInfo (java.io.PrintWriter aw, boolean pause) {
-
-    aw.println (javaSep);
-    reportJavaInfo (aw);
-    aw.println (jbmsSep);
-    reportCloudscape (aw);
-
-    aw.println (sep);
-
-    // Locales info
-    try {
-      reportLocales (aw);
-    }
-    catch (Exception e) {
-
-      aw.println (Main.getTextMessage ("SIF01.Q"));
-      aw.println (Main.getTextMessage ("SIF01.B"));
-    }
-
-
-    if (pause) {
-     pause();
-    }
-
-  } // end of getMainInfo (AppStreamWriter aw, boolean printLicense, boolean pause)
-
-
-  private static boolean setPause = false;
-
-  private static boolean setLicense = false;
-
-  private static boolean cptester = false;
-
-  private static void parseArgs (String args[]) {
-
-    if (args == null) {
-
-      return;
-    }
-
-
-    for (int i = 0; i < args.length; i++) {
-
-      if (args[i].equals ("-pause")) {
-
-        setPause = true;
-      }
-
-      if (args[i].equals ("-cp")) {
-
-        cptester=true;
-      }
-
-    } // end for
-
-  } // end of parseArgs (String args[])
-
-
-  /**
-    For the benefit of DOS box users, this method waits for input
-    before returning
-  */
-  private static void pause () {
-
-    try {
-
-      System.out.print (Main.getTextMessage ("SIF01.C"));
-      BufferedReader br = new BufferedReader (new InputStreamReader (System.in));
-      br.readLine ();
-    }
-    catch (IOException ioe) {
-
-      //just return
-    }
-
-  } // end of pause ()
-
-  /**
-    prints out the jbms info to the specified AppStreamWriter.
-    @param aw the AppStreamWriter to use. If null, System.out is
-    used
-  */
-
-  private static void reportCloudscape (java.io.PrintWriter localAW) {
-
-	  String classpath;
-
-	  try {
-		  classpath = System.getProperty("java.class.path");
-	  }
-	  catch (SecurityException se) {
-		  classpath = null;
-	  }
-
-    ZipInfoProperties zip[]= Main.getAllInfo (classpath);
-
-    if (zip != null) {
-
-      for (int i = 0; i < zip.length; i++) {
-
-        String thisInfo = "[" + zip[i].getLocation () + "] " +
-                                zip[i].getVersionBuildInfo ();
-
-        localAW.println (thisInfo);
-      }
-    }
-
-    else {
-
-      localAW.println (Main.getTextMessage ("SIF01.D"));
-    }
-
-
-  } // end of reportCloudscape
-
-
-  /**
-    Writes out the relevant info about the Java environment to
-    the specified AppStreamWriter.
-
-    @param aw The AppStreamWriter to write info out to. If this is
-    null, the info is written to System.out
-  */
-
-  private static void reportJavaInfo (java.io.PrintWriter localAW) {
-
-	
-
-    localAW.println (Main.getTextMessage ("SIF02.A",
-                                                           getJavaProperty ("java.version")));
-
-    localAW.println (Main.getTextMessage ("SIF02.B",
-                                                           getJavaProperty ("java.vendor")));
-
-    localAW.println (Main.getTextMessage ("SIF02.C",
-                                                           getJavaProperty ("java.home")));
-
-    localAW.println (Main.getTextMessage ("SIF02.D",
-                                                           getJavaProperty ("java.class.path")));
-
-    localAW.println (Main.getTextMessage ("SIF02.E",
-                                                           getJavaProperty ("os.name")));
-
-    localAW.println (Main.getTextMessage ("SIF02.F",
-                                                           getJavaProperty ("os.arch")));
-
-    localAW.println (Main.getTextMessage ("SIF02.G",
-                                                           getJavaProperty ("os.version")));
-
-    localAW.println (Main.getTextMessage ("SIF02.H",
-                                                           getJavaProperty ("user.name")));
-
-    localAW.println (Main.getTextMessage ("SIF02.I",
-                                                           getJavaProperty ("user.home")));
-
-    localAW.println (Main.getTextMessage ("SIF02.J",
-                                                           getJavaProperty ("user.dir")));
-
-  } // end of reportJavaInfo
-
-
-
-  /**
-    Return Java properties from java.lang.System. Will catch
-    SecurityExceptions and note them for displaying information.
-
-    @return the Java property value or a string capturing a
-    security exception.
-   */
-
-  private static String getJavaProperty (String whichProperty) {
-
-    String property;
-    String unavailable = Main.getTextMessage ("SIF01.H");
-
-    try {
-
-      property = System.getProperty (whichProperty, unavailable);
-      return property;
-    }
-    catch (SecurityException se) {
-
-      return Main.getTextMessage ("SIF01.I", se);
-    }
-
-  } // end of getJavaProperty (String whichProperty)
-
-
-
-  /**
-    for use by the main () method
-   */
-
-  private final static String sep     = "------------------------------------------------------";
-  private final static String javaSep = Main.getTextMessage ("SIF01.L");
-
-  private final static String jbmsSep = Main.getTextMessage ("SIF01.M");
-
-  private final static String licSep  = Main.getTextMessage ("SIF01.N");
-
-  private final static String locSep  = Main.getTextMessage ("SIF01.P");
-
-  private final static String curLoc  = Main.getTextMessage ("SIF01.T");
-
-  /**
-    The name of the failure tag in the information file.
-    The failure tag's value provides a default value if
-    any other properties are missing.
-   */
-  private final static String failureTag = Main.getTextMessage ("SIF01.J");
-
-  private static void getClasspathInfo (String args[], java.io.PrintWriter aw) {
-
-    Main.useMe (args, aw);
-  }
-
-
-
-
-  /**
-    Writes out information about the locales with the
-    product.
-
-    @param aw the AppStreamWriter to which the info is written. If this
-    value is null, the info is written to System.out
-
-  */
-  private static void reportLocales (java.io.PrintWriter localAW) {          // throws StandardException {
-
-    boolean cur_loc = true;
-
-    localAW.println (locSep);
-
-    // Read all the possible locales, and test for each one, if it loads.
-    // If so, then read the properties, and print them out.
-
-	Locale[] supportedLocales = Locale.getAvailableLocales();
-	String[] stringLocales = new String[supportedLocales.length];
-    for (int i = 0; i < supportedLocales.length; i++)
-	{
-		stringLocales[i] = supportedLocales[i].toString();
-	}
-	java.util.Arrays.sort(stringLocales);
-
-    Properties p = new Properties ();
-    for (int i = 0; i < stringLocales.length; i++) {
-
-      String localeResource =
-         "/org/apache/derby/info/locale_" + stringLocales[i] + ".properties";
-
-      try {
-
-        InputStream is = p.getClass().getResourceAsStream (localeResource);
-
-        if (is == null) {
-//           localAW.println("resource is null: " + localeResource);
-        }
-        else {
-
-          try {
-			  p.clear();
-            p.load (is);
-        //Displaying Current Locale
-	    if (cur_loc)
-		{
-	Locale loc = null;
-	loc = Locale.getDefault();
-        localAW.println(Main.getTextMessage ("SIF01.T") + "  [" + loc.getDisplayLanguage() + "/" +  loc.getDisplayCountry() + " [" + loc + "]]");
-		cur_loc = false;
-		}
-
-	//Beetle 5079: do not print unlocalized locale names to console, only print locale code.
-	String localeName = p.getProperty("derby.locale.external.name");
-	localeName = localeName.substring(localeName.indexOf("[")+1);
-	localeName = localeName.substring(0,localeName.indexOf("]"));
-	
-            localAW.println (Main.getTextMessage ("SIF01.R",
-                                                                   localeName));
-
-
-			int major = Integer.valueOf(p.getProperty ("derby.locale.version.major")).intValue();
-			int minor = Integer.valueOf(p.getProperty ("derby.locale.version.minor")).intValue();
-			int maint = Integer.valueOf(p.getProperty ("derby.locale.version.maint")).intValue();
-			int build = Integer.valueOf(p.getProperty ("derby.locale.build.number")).intValue();
-
-			String lv = ProductVersionHolder.fullVersionString(major, minor, maint, false, build);
-
-
-            localAW.println (Main.getTextMessage ("SIF01.S", lv));
-
-
-          }
-          catch (IOException ioe) {
-
-            //This case is a bit ugly. If we get an IOException, we return
-            //null. Though this correctly reflects that the product is not
-            //available for use, it may be confusing to users that we swallow
-            //the IO error here.
-
-            localAW.println("Could not get locale properties from : " + is);
-          }
-        }
-
-      }
-      catch (Throwable t) {
-        localAW.println ("Could not load resource: " + localeResource);
-        localAW.println ("Exception: " + t);
-      }
-
-    }
-
-
-    localAW.println (sep);
-
-  } // end of reportLocales
-
-	/* for arguments, choose from one of:*/
-	private static final String EMBEDDED = "embedded";
-
-	/* you can add this if you like*/
-	private static final String TOOLS = "tools";
-
-	private static final String NET = "server";
-	private static final String CLIENT = "client";
-
-	/* you can add this if you like */
-
-	private static final String MAINUSAGESTRING = "java org.apache.derby.tools.sysinfo -cp";
-
-	private static final String USAGESTRINGPARTA = MAINUSAGESTRING + " [ [ " + EMBEDDED + " ][ " + NET + " ][ " + CLIENT + "] [ " + TOOLS + " ] [ ";
-    private static final String USAGESTRINGPARTB = ".class ] ]";
-
-  static  void useMe(String[] args, java.io.PrintWriter pw) {
-	  java.io.PrintWriter localPW = pw;
-
-	    if (localPW == null)
-	    {
-	        localPW = new java.io.PrintWriter(System.out);
-	    }
-
-
-      int length = args.length;
-	  if (length==1) {
-
-		  try {
-			  tryAllClasspaths(localPW);
-
-		  }
-
-		  catch (Throwable t) {
-
-		  }
-	  }
-	  else {
-		  try {
-			  trySomeClasspaths(args, localPW);
-		  }
-
-		  catch (Throwable t) {
-
-		  }
-	  }
-
-  }
-
-
-
-
-
-	  private static void tryAllClasspaths(java.io.PrintWriter localPW) throws Throwable {
-		  localPW.println(Main.getTextMessage("SIF08.B"));
-		  localPW.println(Main.getTextMessage("SIF08.C", MAINUSAGESTRING + " args"));
-		  StringBuffer successes = new StringBuffer(Main.getTextMessage("SIF08.D")+ crLf());
-		  StringBuffer failures = new StringBuffer(crLf() + Main.getTextMessage("SIF08.E") + crLf());
-		  tryCoreClasspath(successes, failures);
-		  tryNetClasspath(successes, failures);
-		  tryClientClasspath(successes, failures);
-		  tryUtilsClasspath(successes, failures);
-		  localPW.println(successes.toString());
-		  if (!failures.toString().equals(crLf() + Main.getTextMessage("SIF08.E") + crLf())) {
-			  localPW.println(failures.toString());
-		  }
-		  else {
-
-			  localPW.println(Main.getTextMessage("SIF08.F"));
-		  }
-		  localPW.flush();
-	  }
-
-	private static void trySomeClasspaths(String[] args, java.io.PrintWriter localPW) throws Throwable {
-
-		boolean seenArg = false;
-		StringBuffer successes = new StringBuffer(Main.getTextMessage("SIF08.D")+ crLf());
-		StringBuffer failures = new StringBuffer(crLf() + Main.getTextMessage("SIF08.E") + crLf());
-
-		if (argumentsContain(args, EMBEDDED))
-		{
-
-			tryCoreClasspath(successes, failures);
-			seenArg =true;
-
-		}
-		if (argumentsContain(args,NET)) {
-		  tryNetClasspath(successes, failures);
-			seenArg =true;
-
-		}
-		if (argumentsContain(args,CLIENT)) {
-		  tryClientClasspath(successes, failures);
-			seenArg =true;
-
-		}
-
-		if (argumentsContain(args,TOOLS) || argumentsContain(args,"utils")) {
-		  tryUtilsClasspath(successes, failures);
-			seenArg =true;
-
-		}
-
-
-		String userclass = argumentMatches(args, ".class");
-		if (!userclass.equals("")) {
-			tryMyClasspath(argumentMatches(args, ".class"), Main.getTextMessage("SIF08.H", userclass), successes, failures);
-			seenArg =true;
-		}
-
-		if (seenArg)
-		{
-
-			localPW.println(successes.toString());
-			if (!failures.toString().equals(crLf() + Main.getTextMessage("SIF08.E") + crLf())) {
-				localPW.println(failures.toString());
-			}
-			else {
-
-				localPW.println(Main.getTextMessage("SIF08.F"));
-			}
-		}
-		else
-		{
-			localPW.println(Main.getTextMessage("SIF08.A", USAGESTRINGPARTA, USAGESTRINGPARTB));
-		}
-		localPW.flush();
-
-	}
-
-	private static void tryCoreClasspath(StringBuffer successes, StringBuffer failures) {
-		tryMyClasspath("org.apache.derby.database.Database", Main.getTextMessage("SIF08.J","derby.jar" ), successes, failures);
-	}
-	private static void tryNetClasspath(StringBuffer successes, StringBuffer failures) {
-		tryMyClasspath("org.apache.derby.drda.NetworkServerControl", Main.getTextMessage("SIF08.I", "derbynet.jar"), successes, failures);
-	}
-	private static void tryClientClasspath(StringBuffer successes, StringBuffer failures) {
-		tryMyClasspath("com.ibm.db2.jcc.DB2Driver", Main.getTextMessage("SIF08.L", "db2jcc.jar"), successes, failures);
-	}
-
-	private static void tryUtilsClasspath(StringBuffer successes, StringBuffer failures) {
-		tryMyClasspath("org.apache.derby.tools.ij", Main.getTextMessage("SIF08.Q", "derbytools.jar"), successes, failures);
-	}
-
-	private static void tryMyClasspath(String cn, String library, StringBuffer successes, StringBuffer failures) {
-
-		try {
-			Class.forName(cn);
-			successes.append(found(cn, library));
-		}
-
-		catch (Throwable t) {
-
-			failures.append(notFound(cn, library));
-
-		}
-
-
-	}
-
-	private static void tryAsResource(String cn, String library, StringBuffer successes, StringBuffer failures) {
-
-		try {
-			java.io.InputStream in = cn.getClass().getResourceAsStream(cn);
-			in.close();
-			successes.append(found(cn, library));
-		}
-
-		catch (Throwable t) {
-			failures.append(notFound(cn, library));
-
-		}
-
-	}
-
-	private static String found(String cn, String library) {
-		StringBuffer temp = new StringBuffer(crLf());
-		temp.append("   " + library);
-		temp.append(crLf());
-		temp.append(crLf());
-		return temp.toString();
-	}
-	private static String notFound(String cn, String library) {
-
-		StringBuffer temp = new StringBuffer(crLf());
-		temp.append("   " + library);
-		temp.append(crLf());
-		temp.append("    " + Main.getTextMessage("SIF08.U", cn));
-		temp.append(crLf());
-		temp.append(crLf());
-		return temp.toString();
-	}
-
-	private static String crLf() {
-		return System.getProperty("line.separator");
-	}
-
-	private static String lookForMainArg(String[] args, java.io.PrintWriter localPW)
-	{
-		int length=args.length;
-		String[] legalargs = new String[1];
-		legalargs[0] = EMBEDDED;
-
-		int argsfound = 0;
-		String whichargument="";
-
-		for (int i = 0; i < length; i++) {
-
-			for (int j=0; j < legalargs.length; j++) {
-				if (args[i].toUpperCase(java.util.Locale.ENGLISH).equals(legalargs[j].toUpperCase(java.util.Locale.ENGLISH))) {
-					argsfound++;
-					whichargument=legalargs[j];
-				}
-			}
-		}
-		if (argsfound > 1 || argsfound < 1) {
-            localPW.println(Main.getTextMessage("SIF08.A", USAGESTRINGPARTA, USAGESTRINGPARTB));
-			return "";
-		}
-		return whichargument;
-	}
-
-	private static boolean argumentsContain(String[] args, String s) {
-		for (int i = 0; i < args.length; i++) {
-			if (args[i].equalsIgnoreCase(s))
-				return true;
-		}
-		return false;
-
-	}
-
-	private static String argumentMatches(String[] args, String ss) {
-	    String userclass = "";
-		int length = args.length;
-		for (int i = 0; i < length; i++) {
-			if (args[i].endsWith(ss)) {
-				userclass = args[i].substring(0,args[i].length()-6) ;
-
-			}
-
-		}
-		return userclass;
-	}
-
-	/*
-	** Code related to loading info fromjar files.
-	*/
-
-    private static final String infoNames[] = {
-
-                                    "org/apache/derby/info/" +
-                                    org.apache.derby.iapi.services.info.ProductGenusNames.DBMS +
-                                    ".properties",
-
-
-                                    "org/apache/derby/info/" +
-                                    org.apache.derby.iapi.services.info.ProductGenusNames.TOOLS +
-                                    ".properties",
-
-                                    "org/apache/derby/info/" +
-                                    org.apache.derby.iapi.services.info.ProductGenusNames.NET +
-                                    ".properties"
-                                };
-
-    public static ZipInfoProperties[] getAllInfo(String classpath)
-    {
-        try
-        {
-			if (classpath != null) {
-				String cp [] = parseClasspath(classpath);
-				Vector v = new Vector();
-				for (int i = 0; i < cp.length; i++)
-				{
-					ZipInfoProperties zip = checkForInfo(cp[i]);
-					if (zip != null)
-					{
-						v.addElement(zip);
-					}
-				}
-				if (v.size() > 0)
-				{
-					ZipInfoProperties zips[] = new ZipInfoProperties[v.size()];
-					v.copyInto(zips);
-					return zips;
-				}
-			}
-            return loadZipFromResource();
-
-        }
-        catch (SecurityException se)
-        {
-            ZipInfoProperties zip[] = new ZipInfoProperties[1];
-            zip[0] = new ZipInfoProperties(null);
-            zip[0].setLocation (Main.getTextMessage ("SIF03.C"));
-            return zip;
-        }
-    }
-
-    /**
-        This method returns exactly one ZipInfoProperty in the array.
-        If it is able to load the sysinfo file as a resource, it returns
-        the ZipInfoProperty associated with that. Otherwise, the ZipInfoProperty
-        will be empty.
-     */
-    private static ZipInfoProperties [] loadZipFromResource()
-    {
-		java.util.ArrayList al = new java.util.ArrayList();
-
-        for (int i = 0; i < infoNames.length; i++)
-        {
-			String resource = "/".concat(infoNames[i]);
-
-            InputStream is = new Main().getClass().getResourceAsStream(resource);
-			if (is == null)
-				continue;
-
-			ZipInfoProperties ze = new ZipInfoProperties(ProductVersionHolder.getProductVersionHolderFromMyEnv(is));
-			ze.setLocation(resource);
-
-			al.add(ze);
-        }
-
-        if (al.size() == 0)
-        {
-            return null;
-        }
-
-        ZipInfoProperties[] zip = new ZipInfoProperties[al.size()];
-
-		al.toArray(zip);
-
-        return zip;
-    }
-
-    private static String [] parseClasspath(String cp)
-    {
-        StringTokenizer st = new StringTokenizer(cp, File.pathSeparator);
-        int count = st.countTokens();
-        if (count == 0)
-        {
-            return null;
-        }
-
-        String vals[] = new String[count];
-        for (int i =0; i < count; i++)
-        {
-            vals[i] = st.nextToken();
-        }
-        return vals;
-    }
-
-    private static ZipInfoProperties checkForInfo(String cpEntry)
-    {
-        File f = new File(cpEntry);
-        if ( ! f.exists())
-        {
-            return null;
-        }
-
-        if (f.isDirectory())
-        {
-            ZipInfoProperties zip = checkDirectory(cpEntry);
-            return zip;
-        }
-
-        if (f.isFile())
-        {
-            ZipInfoProperties zip = checkFile(cpEntry);
-            return zip;
-        }
-        return null;
-
-
-    }
-
-    private static ZipInfoProperties checkDirectory(String dirname)
-    {
-        boolean foundOne = false;
-        File f = null;
-        for (int i = 0; i < infoNames.length; i++)
-        {
-            String localSysinfo = infoNames[i].replace('/', File.separatorChar);
-            f = new File(dirname, localSysinfo);
-            if (f.exists())
-            {
-                foundOne = true;
-                break;
-            }
-        }
-
-        if (!foundOne || (f == null))
-        {
-            return null;
-        }
-
-        try
-        {
-            InputStream bis = new FileInputStream(f);
-
-            ZipInfoProperties zip = new ZipInfoProperties(ProductVersionHolder.getProductVersionHolderFromMyEnv(bis));
-            zip.setLocation(new File(dirname).getCanonicalPath().replace('/', File.separatorChar));
-            return zip;
-        }
-        catch (IOException ioe)
-        {
-            return null;
-        }
-
-    }
-
-    private static ZipInfoProperties checkFile(String filename)
-    {
-        // try to create a ZipFile from it
-
-	// Check to see if it's a version of db2jcc.jar and if so, report the version number. 
-	if (filename.indexOf("db2jcc") >= 0)
-	{
-	    Class c = null;
-	    Method m = null;
-	    Object o = null;
-	    Integer build = null;
-	    Integer major = null;
-            Integer minor = null;
-	    try 
-	    {
-                try 
-		{
-		    c = Class.forName("com.ibm.db2.jcc.DB2Driver");
-		    m = c.getMethod("getJCCBuildNumber", null);
-		    o = c.newInstance();
-		    build = (Integer)m.invoke(o,null);
-		} catch (ClassNotFoundException cnfe) {
-		    c = Class.forName("com.ibm.db2.jcc.DB2Version");
-		    m = c.getMethod("getBuildNumber", null);
-		    o = c.newInstance();
-		    build = (Integer)m.invoke(o,null);
-	        } 
-		m = c.getMethod("getMajorVersion", null);
-		major = (Integer)m.invoke(o,null);
-		m = c.getMethod("getMinorVersion", null);
-		minor = (Integer)m.invoke(o,null);
-
-		ProductVersionHolder jccVersion = ProductVersionHolder.getProductVersionHolder(
-			"IBM Corp.",
-			"DB2 Java Common Client",
-			"DRDA:jcc",
-			major.intValue(),
-			minor.intValue(),
-			0,
-			0,
-			build.intValue(),
-			Boolean.FALSE);
-
-		ZipInfoProperties zip = new ZipInfoProperties(jccVersion);
-
-        zip.setLocation(new File(filename).getCanonicalPath().replace('/', File.separatorChar));
-		return zip;
-            } catch (Exception e) { return null; }
-	}
-
-        try
-        {
-            ZipFile zf = new ZipFile(filename);
-            // try to get a ZipEntry from the ZipFile
-
-            ZipEntry thisEntry = null;
-
-            for (int i =0; i < infoNames.length; i++)
-            {
-                thisEntry = zf.getEntry(infoNames[i]);
-                if (thisEntry != null)
-                {
-                    break;
-                }
-            }
-
-            if (thisEntry == null)
-            {
-                return null;
-            }
-
-            InputStream bis = zf.getInputStream(thisEntry);
-            if (bis == null)
-            {
-                return null;
-            }
-
-            ZipInfoProperties zip = new ZipInfoProperties(ProductVersionHolder.getProductVersionHolderFromMyEnv(bis));
-            zip.setLocation(new File(filename).getCanonicalPath().replace('/', File.separatorChar));
-            return zip;
-
-        }
-        catch (IOException ioe)
-        {
-            //guess not
-            return null;
-        }
-
-    }
-
-	/*
-	** Message handling
-	*/
-	private static ResourceBundle getBundle() {
-		try {
-			return ResourceBundle.getBundle("org.apache.derby.loc.sysinfoMessages");
-		} catch (MissingResourceException mre) {
-		}
-		return null;
-	}
-
-	public static String getTextMessage(String msgId) {
-		return getCompleteMessage(msgId, (Object[]) null);
-	}
-	public static String getTextMessage(String msgId, Object a1) {
-
-		return getCompleteMessage(msgId, new Object[] {a1});
-	}
-	public static String getTextMessage(String msgId, Object a1, Object a2) {
-		return getCompleteMessage(msgId, new Object[] {a1, a2});
-	}
-	public static String getTextMessage(String msgId, Object a1, Object a2, Object a3) {
-		return getCompleteMessage(msgId, new Object[] {a1, a2, a3});
-	}
-	public static String getTextMessage(String msgId, Object a1, Object a2, Object a3, Object a4) {
-		return getCompleteMessage(msgId, new Object[] {a1, a2, a3, a4});
-	}
-
-	/**
-	 */
-	public static String getCompleteMessage(String msgId, Object[] arguments) {
-
-		// we have a base file (sysinfoMessages.properties) so don't give us a last chance.
-		return org.apache.derby.iapi.services.i18n.MessageService.formatMessage(getBundle(), msgId, arguments, false);
-	}
-} // end of class Main
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.sysinfo
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.impl.tools.sysinfo;
+
+import java.util.Locale;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.io.InputStream;
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
+import java.io.File;
+import java.util.zip.ZipFile;
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+import java.io.FileInputStream;
+import java.util.Vector;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+
+import org.apache.derby.iapi.services.info.PropertyNames;
+import org.apache.derby.iapi.services.info.ProductVersionHolder;
+import org.apache.derby.iapi.services.info.ProductGenusNames;
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.tools.i18n.*;
+
+
+/**
+  <i>Copyright &#169; 1998, Cloudscape, Inc.   All rights reserved.</i>
+
+  <P>
+  SysInfo reports values relevant to the Cloudscape product found on
+  the CLASSPATH.  It looks for a file called sysinfo.properties in
+  the CLASSPATH using getResourceAsStream. If the file
+  is not found, or some other exception occurs, the
+  value returned will be that set for the key
+  SysInfo.failureTag, or be the value "<info unavailable>".
+
+  <P>
+  This class can be used to print out system information at the
+  command line by issuing the command:
+  <PRE>
+    java com.ibm.db2j.tools.SysInfo.main
+  </PRE>
+  Alternatively, you can use SysInfo within your program to display
+  Cloudscape information; a Cloudscape version string is returned by this Java code:
+  <PRE>
+    new Main().toString();
+  </PRE>
+
+ */
+
+
+public final class Main {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+
+  /**
+    Application entry point for SysInfo.   This will print out
+    the Cloudscape product information as well as a snapshot of
+    the System properties.
+  */
+  public static void main(String args[]) {
+        // adjust the application in accordance with derby.ui.locale and derby.ui.codeset
+        LocalizedResource.getInstance();
+
+		LocalizedOutput out;
+
+        //using AppStreamReader(extends InputStreamReader) for conversion into specific codeset
+
+		out = LocalizedResource.OutputWriter();
+
+       // because we're in a static method, we need to
+       // get our own instance variable
+    parseArgs (args);
+
+    if (cptester == true)
+	getClasspathInfo (args, out);
+    else
+	getMainInfo (out, setPause);
+
+  } // end of main (String args[])
+
+public static void getMainInfo (java.io.PrintWriter aw, boolean pause) {
+
+    aw.println (javaSep);
+    reportJavaInfo (aw);
+    aw.println (jbmsSep);
+    reportCloudscape (aw);
+
+    aw.println (sep);
+
+    // Locales info
+    try {
+      reportLocales (aw);
+    }
+    catch (Exception e) {
+
+      aw.println (Main.getTextMessage ("SIF01.Q"));
+      aw.println (Main.getTextMessage ("SIF01.B"));
+    }
+
+
+    if (pause) {
+     pause();
+    }
+
+  } // end of getMainInfo (AppStreamWriter aw, boolean printLicense, boolean pause)
+
+
+  private static boolean setPause = false;
+
+  private static boolean setLicense = false;
+
+  private static boolean cptester = false;
+
+  private static void parseArgs (String args[]) {
+
+    if (args == null) {
+
+      return;
+    }
+
+
+    for (int i = 0; i < args.length; i++) {
+
+      if (args[i].equals ("-pause")) {
+
+        setPause = true;
+      }
+
+      if (args[i].equals ("-cp")) {
+
+        cptester=true;
+      }
+
+    } // end for
+
+  } // end of parseArgs (String args[])
+
+
+  /**
+    For the benefit of DOS box users, this method waits for input
+    before returning
+  */
+  private static void pause () {
+
+    try {
+
+      System.out.print (Main.getTextMessage ("SIF01.C"));
+      BufferedReader br = new BufferedReader (new InputStreamReader (System.in));
+      br.readLine ();
+    }
+    catch (IOException ioe) {
+
+      //just return
+    }
+
+  } // end of pause ()
+
+  /**
+    prints out the jbms info to the specified AppStreamWriter.
+    @param aw the AppStreamWriter to use. If null, System.out is
+    used
+  */
+
+  private static void reportCloudscape (java.io.PrintWriter localAW) {
+
+	  String classpath;
+
+	  try {
+		  classpath = System.getProperty("java.class.path");
+	  }
+	  catch (SecurityException se) {
+		  classpath = null;
+	  }
+
+    ZipInfoProperties zip[]= Main.getAllInfo (classpath);
+
+    if (zip != null) {
+
+      for (int i = 0; i < zip.length; i++) {
+
+        String thisInfo = "[" + zip[i].getLocation () + "] " +
+                                zip[i].getVersionBuildInfo ();
+
+        localAW.println (thisInfo);
+      }
+    }
+
+    else {
+
+      localAW.println (Main.getTextMessage ("SIF01.D"));
+    }
+
+
+  } // end of reportCloudscape
+
+
+  /**
+    Writes out the relevant info about the Java environment to
+    the specified AppStreamWriter.
+
+    @param aw The AppStreamWriter to write info out to. If this is
+    null, the info is written to System.out
+  */
+
+  private static void reportJavaInfo (java.io.PrintWriter localAW) {
+
+	
+
+    localAW.println (Main.getTextMessage ("SIF02.A",
+                                                           getJavaProperty ("java.version")));
+
+    localAW.println (Main.getTextMessage ("SIF02.B",
+                                                           getJavaProperty ("java.vendor")));
+
+    localAW.println (Main.getTextMessage ("SIF02.C",
+                                                           getJavaProperty ("java.home")));
+
+    localAW.println (Main.getTextMessage ("SIF02.D",
+                                                           getJavaProperty ("java.class.path")));
+
+    localAW.println (Main.getTextMessage ("SIF02.E",
+                                                           getJavaProperty ("os.name")));
+
+    localAW.println (Main.getTextMessage ("SIF02.F",
+                                                           getJavaProperty ("os.arch")));
+
+    localAW.println (Main.getTextMessage ("SIF02.G",
+                                                           getJavaProperty ("os.version")));
+
+    localAW.println (Main.getTextMessage ("SIF02.H",
+                                                           getJavaProperty ("user.name")));
+
+    localAW.println (Main.getTextMessage ("SIF02.I",
+                                                           getJavaProperty ("user.home")));
+
+    localAW.println (Main.getTextMessage ("SIF02.J",
+                                                           getJavaProperty ("user.dir")));
+
+  } // end of reportJavaInfo
+
+
+
+  /**
+    Return Java properties from java.lang.System. Will catch
+    SecurityExceptions and note them for displaying information.
+
+    @return the Java property value or a string capturing a
+    security exception.
+   */
+
+  private static String getJavaProperty (String whichProperty) {
+
+    String property;
+    String unavailable = Main.getTextMessage ("SIF01.H");
+
+    try {
+
+      property = System.getProperty (whichProperty, unavailable);
+      return property;
+    }
+    catch (SecurityException se) {
+
+      return Main.getTextMessage ("SIF01.I", se);
+    }
+
+  } // end of getJavaProperty (String whichProperty)
+
+
+
+  /**
+    for use by the main () method
+   */
+
+  private final static String sep     = "------------------------------------------------------";
+  private final static String javaSep = Main.getTextMessage ("SIF01.L");
+
+  private final static String jbmsSep = Main.getTextMessage ("SIF01.M");
+
+  private final static String licSep  = Main.getTextMessage ("SIF01.N");
+
+  private final static String locSep  = Main.getTextMessage ("SIF01.P");
+
+  private final static String curLoc  = Main.getTextMessage ("SIF01.T");
+
+  /**
+    The name of the failure tag in the information file.
+    The failure tag's value provides a default value if
+    any other properties are missing.
+   */
+  private final static String failureTag = Main.getTextMessage ("SIF01.J");
+
+  private static void getClasspathInfo (String args[], java.io.PrintWriter aw) {
+
+    Main.useMe (args, aw);
+  }
+
+
+
+
+  /**
+    Writes out information about the locales with the
+    product.
+
+    @param aw the AppStreamWriter to which the info is written. If this
+    value is null, the info is written to System.out
+
+  */
+  private static void reportLocales (java.io.PrintWriter localAW) {          // throws StandardException {
+
+    boolean cur_loc = true;
+
+    localAW.println (locSep);
+
+    // Read all the possible locales, and test for each one, if it loads.
+    // If so, then read the properties, and print them out.
+
+	Locale[] supportedLocales = Locale.getAvailableLocales();
+	String[] stringLocales = new String[supportedLocales.length];
+    for (int i = 0; i < supportedLocales.length; i++)
+	{
+		stringLocales[i] = supportedLocales[i].toString();
+	}
+	java.util.Arrays.sort(stringLocales);
+
+    Properties p = new Properties ();
+    for (int i = 0; i < stringLocales.length; i++) {
+
+      String localeResource =
+         "/org/apache/derby/info/locale_" + stringLocales[i] + ".properties";
+
+      try {
+
+        InputStream is = p.getClass().getResourceAsStream (localeResource);
+
+        if (is == null) {
+//           localAW.println("resource is null: " + localeResource);
+        }
+        else {
+
+          try {
+			  p.clear();
+            p.load (is);
+        //Displaying Current Locale
+	    if (cur_loc)
+		{
+	Locale loc = null;
+	loc = Locale.getDefault();
+        localAW.println(Main.getTextMessage ("SIF01.T") + "  [" + loc.getDisplayLanguage() + "/" +  loc.getDisplayCountry() + " [" + loc + "]]");
+		cur_loc = false;
+		}
+
+	//Beetle 5079: do not print unlocalized locale names to console, only print locale code.
+	String localeName = p.getProperty("derby.locale.external.name");
+	localeName = localeName.substring(localeName.indexOf("[")+1);
+	localeName = localeName.substring(0,localeName.indexOf("]"));
+	
+            localAW.println (Main.getTextMessage ("SIF01.R",
+                                                                   localeName));
+
+
+			int major = Integer.valueOf(p.getProperty ("derby.locale.version.major")).intValue();
+			int minor = Integer.valueOf(p.getProperty ("derby.locale.version.minor")).intValue();
+			int maint = Integer.valueOf(p.getProperty ("derby.locale.version.maint")).intValue();
+			int build = Integer.valueOf(p.getProperty ("derby.locale.build.number")).intValue();
+
+			String lv = ProductVersionHolder.fullVersionString(major, minor, maint, false, build);
+
+
+            localAW.println (Main.getTextMessage ("SIF01.S", lv));
+
+
+          }
+          catch (IOException ioe) {
+
+            //This case is a bit ugly. If we get an IOException, we return
+            //null. Though this correctly reflects that the product is not
+            //available for use, it may be confusing to users that we swallow
+            //the IO error here.
+
+            localAW.println("Could not get locale properties from : " + is);
+          }
+        }
+
+      }
+      catch (Throwable t) {
+        localAW.println ("Could not load resource: " + localeResource);
+        localAW.println ("Exception: " + t);
+      }
+
+    }
+
+
+    localAW.println (sep);
+
+  } // end of reportLocales
+
+	/* for arguments, choose from one of:*/
+	private static final String EMBEDDED = "embedded";
+
+	/* you can add this if you like*/
+	private static final String TOOLS = "tools";
+
+	private static final String NET = "server";
+	private static final String CLIENT = "client";
+
+	/* you can add this if you like */
+
+	private static final String MAINUSAGESTRING = "java org.apache.derby.tools.sysinfo -cp";
+
+	private static final String USAGESTRINGPARTA = MAINUSAGESTRING + " [ [ " + EMBEDDED + " ][ " + NET + " ][ " + CLIENT + "] [ " + TOOLS + " ] [ ";
+    private static final String USAGESTRINGPARTB = ".class ] ]";
+
+  static  void useMe(String[] args, java.io.PrintWriter pw) {
+	  java.io.PrintWriter localPW = pw;
+
+	    if (localPW == null)
+	    {
+	        localPW = new java.io.PrintWriter(System.out);
+	    }
+
+
+      int length = args.length;
+	  if (length==1) {
+
+		  try {
+			  tryAllClasspaths(localPW);
+
+		  }
+
+		  catch (Throwable t) {
+
+		  }
+	  }
+	  else {
+		  try {
+			  trySomeClasspaths(args, localPW);
+		  }
+
+		  catch (Throwable t) {
+
+		  }
+	  }
+
+  }
+
+
+
+
+
+	  private static void tryAllClasspaths(java.io.PrintWriter localPW) throws Throwable {
+		  localPW.println(Main.getTextMessage("SIF08.B"));
+		  localPW.println(Main.getTextMessage("SIF08.C", MAINUSAGESTRING + " args"));
+		  StringBuffer successes = new StringBuffer(Main.getTextMessage("SIF08.D")+ crLf());
+		  StringBuffer failures = new StringBuffer(crLf() + Main.getTextMessage("SIF08.E") + crLf());
+		  tryCoreClasspath(successes, failures);
+		  tryNetClasspath(successes, failures);
+		  tryClientClasspath(successes, failures);
+		  tryUtilsClasspath(successes, failures);
+		  localPW.println(successes.toString());
+		  if (!failures.toString().equals(crLf() + Main.getTextMessage("SIF08.E") + crLf())) {
+			  localPW.println(failures.toString());
+		  }
+		  else {
+
+			  localPW.println(Main.getTextMessage("SIF08.F"));
+		  }
+		  localPW.flush();
+	  }
+
+	private static void trySomeClasspaths(String[] args, java.io.PrintWriter localPW) throws Throwable {
+
+		boolean seenArg = false;
+		StringBuffer successes = new StringBuffer(Main.getTextMessage("SIF08.D")+ crLf());
+		StringBuffer failures = new StringBuffer(crLf() + Main.getTextMessage("SIF08.E") + crLf());
+
+		if (argumentsContain(args, EMBEDDED))
+		{
+
+			tryCoreClasspath(successes, failures);
+			seenArg =true;
+
+		}
+		if (argumentsContain(args,NET)) {
+		  tryNetClasspath(successes, failures);
+			seenArg =true;
+
+		}
+		if (argumentsContain(args,CLIENT)) {
+		  tryClientClasspath(successes, failures);
+			seenArg =true;
+
+		}
+
+		if (argumentsContain(args,TOOLS) || argumentsContain(args,"utils")) {
+		  tryUtilsClasspath(successes, failures);
+			seenArg =true;
+
+		}
+
+
+		String userclass = argumentMatches(args, ".class");
+		if (!userclass.equals("")) {
+			tryMyClasspath(argumentMatches(args, ".class"), Main.getTextMessage("SIF08.H", userclass), successes, failures);
+			seenArg =true;
+		}
+
+		if (seenArg)
+		{
+
+			localPW.println(successes.toString());
+			if (!failures.toString().equals(crLf() + Main.getTextMessage("SIF08.E") + crLf())) {
+				localPW.println(failures.toString());
+			}
+			else {
+
+				localPW.println(Main.getTextMessage("SIF08.F"));
+			}
+		}
+		else
+		{
+			localPW.println(Main.getTextMessage("SIF08.A", USAGESTRINGPARTA, USAGESTRINGPARTB));
+		}
+		localPW.flush();
+
+	}
+
+	private static void tryCoreClasspath(StringBuffer successes, StringBuffer failures) {
+		tryMyClasspath("org.apache.derby.database.Database", Main.getTextMessage("SIF08.J","derby.jar" ), successes, failures);
+	}
+	private static void tryNetClasspath(StringBuffer successes, StringBuffer failures) {
+		tryMyClasspath("org.apache.derby.drda.NetworkServerControl", Main.getTextMessage("SIF08.I", "derbynet.jar"), successes, failures);
+	}
+	private static void tryClientClasspath(StringBuffer successes, StringBuffer failures) {
+		tryMyClasspath("com.ibm.db2.jcc.DB2Driver", Main.getTextMessage("SIF08.L", "db2jcc.jar"), successes, failures);
+	}
+
+	private static void tryUtilsClasspath(StringBuffer successes, StringBuffer failures) {
+		tryMyClasspath("org.apache.derby.tools.ij", Main.getTextMessage("SIF08.Q", "derbytools.jar"), successes, failures);
+	}
+
+	private static void tryMyClasspath(String cn, String library, StringBuffer successes, StringBuffer failures) {
+
+		try {
+			Class.forName(cn);
+			successes.append(found(cn, library));
+		}
+
+		catch (Throwable t) {
+
+			failures.append(notFound(cn, library));
+
+		}
+
+
+	}
+
+	private static void tryAsResource(String cn, String library, StringBuffer successes, StringBuffer failures) {
+
+		try {
+			java.io.InputStream in = cn.getClass().getResourceAsStream(cn);
+			in.close();
+			successes.append(found(cn, library));
+		}
+
+		catch (Throwable t) {
+			failures.append(notFound(cn, library));
+
+		}
+
+	}
+
+	private static String found(String cn, String library) {
+		StringBuffer temp = new StringBuffer(crLf());
+		temp.append("   " + library);
+		temp.append(crLf());
+		temp.append(crLf());
+		return temp.toString();
+	}
+	private static String notFound(String cn, String library) {
+
+		StringBuffer temp = new StringBuffer(crLf());
+		temp.append("   " + library);
+		temp.append(crLf());
+		temp.append("    " + Main.getTextMessage("SIF08.U", cn));
+		temp.append(crLf());
+		temp.append(crLf());
+		return temp.toString();
+	}
+
+	private static String crLf() {
+		return System.getProperty("line.separator");
+	}
+
+	private static String lookForMainArg(String[] args, java.io.PrintWriter localPW)
+	{
+		int length=args.length;
+		String[] legalargs = new String[1];
+		legalargs[0] = EMBEDDED;
+
+		int argsfound = 0;
+		String whichargument="";
+
+		for (int i = 0; i < length; i++) {
+
+			for (int j=0; j < legalargs.length; j++) {
+				if (args[i].toUpperCase(java.util.Locale.ENGLISH).equals(legalargs[j].toUpperCase(java.util.Locale.ENGLISH))) {
+					argsfound++;
+					whichargument=legalargs[j];
+				}
+			}
+		}
+		if (argsfound > 1 || argsfound < 1) {
+            localPW.println(Main.getTextMessage("SIF08.A", USAGESTRINGPARTA, USAGESTRINGPARTB));
+			return "";
+		}
+		return whichargument;
+	}
+
+	private static boolean argumentsContain(String[] args, String s) {
+		for (int i = 0; i < args.length; i++) {
+			if (args[i].equalsIgnoreCase(s))
+				return true;
+		}
+		return false;
+
+	}
+
+	private static String argumentMatches(String[] args, String ss) {
+	    String userclass = "";
+		int length = args.length;
+		for (int i = 0; i < length; i++) {
+			if (args[i].endsWith(ss)) {
+				userclass = args[i].substring(0,args[i].length()-6) ;
+
+			}
+
+		}
+		return userclass;
+	}
+
+	/*
+	** Code related to loading info fromjar files.
+	*/
+
+    private static final String infoNames[] = {
+
+                                    "org/apache/derby/info/" +
+                                    org.apache.derby.iapi.services.info.ProductGenusNames.DBMS +
+                                    ".properties",
+
+
+                                    "org/apache/derby/info/" +
+                                    org.apache.derby.iapi.services.info.ProductGenusNames.TOOLS +
+                                    ".properties",
+
+                                    "org/apache/derby/info/" +
+                                    org.apache.derby.iapi.services.info.ProductGenusNames.NET +
+                                    ".properties"
+                                };
+
+    public static ZipInfoProperties[] getAllInfo(String classpath)
+    {
+        try
+        {
+			if (classpath != null) {
+				String cp [] = parseClasspath(classpath);
+				Vector v = new Vector();
+				for (int i = 0; i < cp.length; i++)
+				{
+					ZipInfoProperties zip = checkForInfo(cp[i]);
+					if (zip != null)
+					{
+						v.addElement(zip);
+					}
+				}
+				if (v.size() > 0)
+				{
+					ZipInfoProperties zips[] = new ZipInfoProperties[v.size()];
+					v.copyInto(zips);
+					return zips;
+				}
+			}
+            return loadZipFromResource();
+
+        }
+        catch (SecurityException se)
+        {
+            ZipInfoProperties zip[] = new ZipInfoProperties[1];
+            zip[0] = new ZipInfoProperties(null);
+            zip[0].setLocation (Main.getTextMessage ("SIF03.C"));
+            return zip;
+        }
+    }
+
+    /**
+        This method returns exactly one ZipInfoProperty in the array.
+        If it is able to load the sysinfo file as a resource, it returns
+        the ZipInfoProperty associated with that. Otherwise, the ZipInfoProperty
+        will be empty.
+     */
+    private static ZipInfoProperties [] loadZipFromResource()
+    {
+		java.util.ArrayList al = new java.util.ArrayList();
+
+        for (int i = 0; i < infoNames.length; i++)
+        {
+			String resource = "/".concat(infoNames[i]);
+
+            InputStream is = new Main().getClass().getResourceAsStream(resource);
+			if (is == null)
+				continue;
+
+			ZipInfoProperties ze = new ZipInfoProperties(ProductVersionHolder.getProductVersionHolderFromMyEnv(is));
+			ze.setLocation(resource);
+
+			al.add(ze);
+        }
+
+        if (al.size() == 0)
+        {
+            return null;
+        }
+
+        ZipInfoProperties[] zip = new ZipInfoProperties[al.size()];
+
+		al.toArray(zip);
+
+        return zip;
+    }
+
+    private static String [] parseClasspath(String cp)
+    {
+        StringTokenizer st = new StringTokenizer(cp, File.pathSeparator);
+        int count = st.countTokens();
+        if (count == 0)
+        {
+            return null;
+        }
+
+        String vals[] = new String[count];
+        for (int i =0; i < count; i++)
+        {
+            vals[i] = st.nextToken();
+        }
+        return vals;
+    }
+
+    private static ZipInfoProperties checkForInfo(String cpEntry)
+    {
+        File f = new File(cpEntry);
+        if ( ! f.exists())
+        {
+            return null;
+        }
+
+        if (f.isDirectory())
+        {
+            ZipInfoProperties zip = checkDirectory(cpEntry);
+            return zip;
+        }
+
+        if (f.isFile())
+        {
+            ZipInfoProperties zip = checkFile(cpEntry);
+            return zip;
+        }
+        return null;
+
+
+    }
+
+    private static ZipInfoProperties checkDirectory(String dirname)
+    {
+        boolean foundOne = false;
+        File f = null;
+        for (int i = 0; i < infoNames.length; i++)
+        {
+            String localSysinfo = infoNames[i].replace('/', File.separatorChar);
+            f = new File(dirname, localSysinfo);
+            if (f.exists())
+            {
+                foundOne = true;
+                break;
+            }
+        }
+
+        if (!foundOne || (f == null))
+        {
+            return null;
+        }
+
+        try
+        {
+            InputStream bis = new FileInputStream(f);
+
+            ZipInfoProperties zip = new ZipInfoProperties(ProductVersionHolder.getProductVersionHolderFromMyEnv(bis));
+            zip.setLocation(new File(dirname).getCanonicalPath().replace('/', File.separatorChar));
+            return zip;
+        }
+        catch (IOException ioe)
+        {
+            return null;
+        }
+
+    }
+
+    private static ZipInfoProperties checkFile(String filename)
+    {
+        // try to create a ZipFile from it
+
+	// Check to see if it's a version of db2jcc.jar and if so, report the version number. 
+	if (filename.indexOf("db2jcc") >= 0)
+	{
+	    Class c = null;
+	    Method m = null;
+	    Object o = null;
+	    Integer build = null;
+	    Integer major = null;
+            Integer minor = null;
+	    try 
+	    {
+                try 
+		{
+		    c = Class.forName("com.ibm.db2.jcc.DB2Driver");
+		    m = c.getMethod("getJCCBuildNumber", null);
+		    o = c.newInstance();
+		    build = (Integer)m.invoke(o,null);
+		} catch (ClassNotFoundException cnfe) {
+		    c = Class.forName("com.ibm.db2.jcc.DB2Version");
+		    m = c.getMethod("getBuildNumber", null);
+		    o = c.newInstance();
+		    build = (Integer)m.invoke(o,null);
+	        } 
+		m = c.getMethod("getMajorVersion", null);
+		major = (Integer)m.invoke(o,null);
+		m = c.getMethod("getMinorVersion", null);
+		minor = (Integer)m.invoke(o,null);
+
+		ProductVersionHolder jccVersion = ProductVersionHolder.getProductVersionHolder(
+			"IBM Corp.",
+			"DB2 Java Common Client",
+			"DRDA:jcc",
+			major.intValue(),
+			minor.intValue(),
+			0,
+			0,
+			build.intValue(),
+			Boolean.FALSE);
+
+		ZipInfoProperties zip = new ZipInfoProperties(jccVersion);
+
+        zip.setLocation(new File(filename).getCanonicalPath().replace('/', File.separatorChar));
+		return zip;
+            } catch (Exception e) { return null; }
+	}
+
+        try
+        {
+            ZipFile zf = new ZipFile(filename);
+            // try to get a ZipEntry from the ZipFile
+
+            ZipEntry thisEntry = null;
+
+            for (int i =0; i < infoNames.length; i++)
+            {
+                thisEntry = zf.getEntry(infoNames[i]);
+                if (thisEntry != null)
+                {
+                    break;
+                }
+            }
+
+            if (thisEntry == null)
+            {
+                return null;
+            }
+
+            InputStream bis = zf.getInputStream(thisEntry);
+            if (bis == null)
+            {
+                return null;
+            }
+
+            ZipInfoProperties zip = new ZipInfoProperties(ProductVersionHolder.getProductVersionHolderFromMyEnv(bis));
+            zip.setLocation(new File(filename).getCanonicalPath().replace('/', File.separatorChar));
+            return zip;
+
+        }
+        catch (IOException ioe)
+        {
+            //guess not
+            return null;
+        }
+
+    }
+
+	/*
+	** Message handling
+	*/
+	private static ResourceBundle getBundle() {
+		try {
+			return ResourceBundle.getBundle("org.apache.derby.loc.sysinfoMessages");
+		} catch (MissingResourceException mre) {
+		}
+		return null;
+	}
+
+	public static String getTextMessage(String msgId) {
+		return getCompleteMessage(msgId, (Object[]) null);
+	}
+	public static String getTextMessage(String msgId, Object a1) {
+
+		return getCompleteMessage(msgId, new Object[] {a1});
+	}
+	public static String getTextMessage(String msgId, Object a1, Object a2) {
+		return getCompleteMessage(msgId, new Object[] {a1, a2});
+	}
+	public static String getTextMessage(String msgId, Object a1, Object a2, Object a3) {
+		return getCompleteMessage(msgId, new Object[] {a1, a2, a3});
+	}
+	public static String getTextMessage(String msgId, Object a1, Object a2, Object a3, Object a4) {
+		return getCompleteMessage(msgId, new Object[] {a1, a2, a3, a4});
+	}
+
+	/**
+	 */
+	public static String getCompleteMessage(String msgId, Object[] arguments) {
+
+		// we have a base file (sysinfoMessages.properties) so don't give us a last chance.
+		return org.apache.derby.iapi.services.i18n.MessageService.formatMessage(getBundle(), msgId, arguments, false);
+	}
+} // end of class Main
+

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/sysinfo/ZipInfoProperties.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/sysinfo/ZipInfoProperties.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/impl/tools/sysinfo/ZipInfoProperties.java	Fri Sep 24 10:33:20 2004
@@ -1,77 +1,77 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.impl.tools.sysinfo
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-//ZipInfoProperties
-
-package org.apache.derby.impl.tools.sysinfo;
-
-import java.util.Properties;
-import java.io.OutputStream;
-import org.apache.derby.iapi.services.info.PropertyNames;
-import org.apache.derby.iapi.services.info.ProductVersionHolder;
-
-public class ZipInfoProperties // extends Properties
-	/**
-		IBM Copyright &copy notice.
-	*/
-
-{ private static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-
-	private final ProductVersionHolder	version;
-    /**
-        full path to zip (or expanded zip)
-        C:/cloudscape/lib/tools.zip
-            -or-
-        D:\myWorkDir\cloudscape\lib\ *expanded*
-
-        The base name (at the end) should be the same as the zipNameString
-     */
-    private  String location;
-
-	ZipInfoProperties(ProductVersionHolder version) {
-		this.version = version;
-	}
-
-	/**
-		Method to get only the "interesting" pieces of information
-        for the customer, namely the version number (2.0.1) and
-		the beta status and the build number
-		@return a value for displaying to the user via Sysinfo
-    */
-    public String getVersionBuildInfo()
-    {
-        if (version == null)
-		{
-			return Main.getTextMessage ("SIF04.C");
-		}
-
-		if ("DRDA:jcc".equals(version.getProductTechnologyName()))
-			return version.getSimpleVersionString() + " - (" + version.getBuildNumber() + ")";
-
-		return version.getVersionBuildString(true);
-
-    }
-
-    public String getLocation()
-    {
-		if (location == null)
-			return Main.getTextMessage ("SIF01.H");
-        return location;
-    }
-
-	void setLocation(String location) {
-		this.location = location;
-	}
-
-
-
-}
-
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.impl.tools.sysinfo
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+//ZipInfoProperties
+
+package org.apache.derby.impl.tools.sysinfo;
+
+import java.util.Properties;
+import java.io.OutputStream;
+import org.apache.derby.iapi.services.info.PropertyNames;
+import org.apache.derby.iapi.services.info.ProductVersionHolder;
+
+public class ZipInfoProperties // extends Properties
+	/**
+		IBM Copyright &copy notice.
+	*/
+
+{ private static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+
+	private final ProductVersionHolder	version;
+    /**
+        full path to zip (or expanded zip)
+        C:/cloudscape/lib/tools.zip
+            -or-
+        D:\myWorkDir\cloudscape\lib\ *expanded*
+
+        The base name (at the end) should be the same as the zipNameString
+     */
+    private  String location;
+
+	ZipInfoProperties(ProductVersionHolder version) {
+		this.version = version;
+	}
+
+	/**
+		Method to get only the "interesting" pieces of information
+        for the customer, namely the version number (2.0.1) and
+		the beta status and the build number
+		@return a value for displaying to the user via Sysinfo
+    */
+    public String getVersionBuildInfo()
+    {
+        if (version == null)
+		{
+			return Main.getTextMessage ("SIF04.C");
+		}
+
+		if ("DRDA:jcc".equals(version.getProductTechnologyName()))
+			return version.getSimpleVersionString() + " - (" + version.getBuildNumber() + ")";
+
+		return version.getVersionBuildString(true);
+
+    }
+
+    public String getLocation()
+    {
+		if (location == null)
+			return Main.getTextMessage ("SIF01.H");
+        return location;
+    }
+
+	void setLocation(String location) {
+		this.location = location;
+	}
+
+
+
+}
+
+

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/tools/JDBCDisplayUtil.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/tools/JDBCDisplayUtil.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/tools/JDBCDisplayUtil.java	Fri Sep 24 10:33:20 2004
@@ -1,1193 +1,1193 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.tools
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.tools;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Statement;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.Types;
-
-import java.util.Properties;
-import java.util.Enumeration;
-import java.util.Vector;
-
-import org.apache.derby.iapi.tools.i18n.LocalizedResource;
-
-import org.apache.derby.impl.tools.ij.ijException;
-
-/**
-	
-	This class contains utility methods for displaying JDBC objects and results.
-	
-	<p>
-	All of the methods are static. The output stream
-	to write to is always passed in, along with the
-	JDBC objects to display.
-
-	@author ames
- */
-public class JDBCDisplayUtil { 
-
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-
-	// used to control display
-	static final private int MINWIDTH = 4;
-	static private int maxWidth = 128;
-    static public boolean showSelectCount = false;
-
-    static {
-        // initialize the locale support functions to default value of JVM 
-        LocalizedResource.getInstance();
-    }
-
-
-	//-----------------------------------------------------------------
-	// Methods for initialization resource bundle and codeset's output
-	
-	/**
-	 * init method - will init the class to support a locale and
-	 * codeset based on the derby.ui.locale and derby.ui.codeset
-	 * properties if exists or using the default values from the JVM.
-	 */
-	static public boolean init() {
-		return (LocalizedResource.getInstance() != null);
-	}
-
-	/**
-	 * init method - will init the class to support a locale and
-	 * codeset based on the derby.ui.locale properties and on the 
-     * given codeset if exists or using the default values from the JVM.
-	 */
-	public static boolean init(String codeset) {
-		return init(codeset, null);
-	}
-
-	/**
-	 * init method - will init the class to support a locale and
-	 * codeset based on the given codeset and locale.
-	 * If the parameters are null it will try to init use derby.ui.locale
-	 * and derby.ui.codeset properties if exists or using the default
-	 * values from the JVM.
-	 */
-	public static boolean init(String pCodeset, String pLocale) {
-		LocalizedResource.getInstance().init(pCodeset, pLocale,null);
-		return true;
-	}
-
-	//-----------------------------------------------------------------
-	// Methods for displaying and checking errors
-
-	/**
-		Print information about the exception to the given PrintWriter.
-		For non-SQLExceptions, does a stack trace. For SQLExceptions,
-		print a standard error message and walk the list, if any.
-
-		@param out the place to write to
-		@param e the exception to display
-	 */
-	static public void ShowException(PrintWriter out, Throwable e) {
-		if (e == null) return;
-
-		if (e instanceof SQLException)
-			ShowSQLException(out, (SQLException)e);
-		else
-			e.printStackTrace(out);
-	}
-
-	/**
-		Print information about the SQL exception to the given PrintWriter.
-		Walk the list of exceptions, if any.
-
-		@param out the place to write to
-		@param e the exception to display
-	 */
-	static public void ShowSQLException(PrintWriter out, SQLException e) {
-		String errorCode;
-
-		if (Boolean.getBoolean("ij.showErrorCode")) {
-			errorCode = LocalizedResource.getMessage("UT_Error0", LocalizedResource.getNumber(e.getErrorCode()));
-		}
-		else {
-			errorCode = "";
-		}
-
-		while (e!=null) {
-			String p1 = mapNull(e.getSQLState(),LocalizedResource.getMessage("UT_NoSqlst"));
-			String p2 = mapNull(e.getMessage(),LocalizedResource.getMessage("UT_NoMessa"));
-			out.println(LocalizedResource.getMessage("UT_Error012", p1, p2,errorCode));
-			doTrace(out, e);
-			e=e.getNextException();
-		}
-	}
-
-	/**
-		Print information about the SQL warnings for the connection
-		to the given PrintWriter.
-		Walks the list of exceptions, if any.
-
-		@param out the place to write to
-		@param theConnection the connection that may have warnings.
-	 */
-	static public void ShowWarnings(PrintWriter out, Connection theConnection) {
-	    try {
-		// GET CONNECTION WARNINGS
-		SQLWarning warning = null;
-
-		if (theConnection != null) {
-			ShowWarnings(out, theConnection.getWarnings());
-		}
-
-		if (theConnection != null) {
-			theConnection.clearWarnings();
-		}
-	    } catch (SQLException e) {
-			ShowSQLException(out, e);
-	    }
-	} // ShowWarnings
-
-	/**
-		@param out the place to write to
-		@param warning the SQLWarning
-	*/
-	static public void ShowWarnings(PrintWriter out, SQLWarning warning) {
-		while (warning != null) {
-			String p1 = mapNull(warning.getSQLState(),LocalizedResource.getMessage("UT_NoSqlst_7"));
-			String p2 = mapNull(warning.getMessage(),LocalizedResource.getMessage("UT_NoMessa_8"));
-			out.println(LocalizedResource.getMessage("UT_Warni01", p1, p2));
-			warning = warning.getNextWarning();
-		}
-	}
-
-	/**
-		Print information about the SQL warnings for the ResultSet
-		to the given PrintWriter.
-		Walk the list of exceptions, if any.
-	
-		@param out the place to write to
-		@param rs the ResultSet that may have warnings on it
-	 */
-	static public void ShowWarnings(PrintWriter out, ResultSet rs) {
-	    try {
-		// GET RESULTSET WARNINGS
-		SQLWarning warning = null;
-
-		if (rs != null) {
-			ShowWarnings(out, rs.getWarnings());
-		}
-
-		if (rs != null) {
-			rs.clearWarnings();
-		}
-	    } catch (SQLException e) {
-			ShowSQLException(out, e);
-	    }
-	} // ShowResultSetWarnings
-
-	/**
-		Print information about the SQL warnings for the Statement
-		to the given PrintWriter.
-		Walks the list of exceptions, if any.
-
-		@param out the place to write to
-		@param s the Statement that may have warnings on it
-	 */
-	static public void ShowWarnings(PrintWriter out, Statement s)
-	{
-	    try {
-		// GET STATEMENT WARNINGS
-		SQLWarning warning = null;
-
-		if (s != null) {
-			ShowWarnings(out, s.getWarnings());
-		}
-
-		if (s != null) {
-			s.clearWarnings();
-		}
-	    } catch (SQLException e) {
-			ShowSQLException(out, e);
-	    }
-	} // ShowStatementWarnings
-
-	//-----------------------------------------------------------------
-	// Methods for displaying and checking results
-
-	// REMIND: make this configurable...
-	static final private int MAX_RETRIES = 0;
-
-	/**
-		Pretty-print the results of a statement that has been executed.
-		If it is a select, gathers and prints the results.  Display
-		partial results up to the first error.
-		If it is not a SELECT, determine if rows were involved or not,
-		and print the appropriate message.
-
-		@param out the place to write to
-		@param stmt the Statement to display
-		@param conn the Connection against which the statement was executed
-
-		@exception SQLException on JDBC access failure
-	 */
-	static public void DisplayResults(PrintWriter out, Statement stmt, Connection conn )
-		throws SQLException
-	{
-		indent_DisplayResults( out, stmt, conn, 0);			
-	}
-
-	static private void indent_DisplayResults
-	(PrintWriter out, Statement stmt, Connection conn, int indentLevel)
-		throws SQLException {
-
-		checkNotNull(stmt, "Statement");
-
-		ResultSet rs = stmt.getResultSet();
-		if (rs != null) {
-			indent_DisplayResults(out, rs, conn, indentLevel);
-			rs.close(); // let the result set go away
-		}
-		else {
-			DisplayUpdateCount(out,stmt.getUpdateCount(), indentLevel);
-		}
-
-		ShowWarnings(out,stmt);
-	} // DisplayResults
-
-	/**
-		@param out the place to write to
-		@param count the update count to display
-		@param indentLevel number of tab stops to indent line
-	 */
-	static void DisplayUpdateCount(PrintWriter out, int count, int indentLevel ) {
-		if (count == 1) {
-			indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_1RowInserUpdatDelet"));
-		}
-		else if (count >= 0) {
-			indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_0RowsInserUpdatDelet", LocalizedResource.getNumber(count)));
-		}
-		else {
-			indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_StateExecu"));
-		}
-	}
-
-	/**
-		@param out the place to write to
-		@param rs the ResultSet to display
-		@param conn the Connection against which the ResultSet was retrieved
-
-		@exception SQLException on JDBC access failure
-	 */
-	static public void DisplayResults(PrintWriter out, ResultSet rs, Connection conn)
-		throws SQLException
-	{
-		indent_DisplayResults( out, rs, conn, 0);
-	}
-
-	static private void indent_DisplayResults
-	(PrintWriter out, ResultSet rs, Connection conn, int indentLevel)
-		throws SQLException {
-		ResultSetMetaData rsmd = rs.getMetaData();
-		checkNotNull(rsmd, "ResultSetMetaData");
-		Vector nestedResults;
-    int numberOfRowsSelected = 0;
-
-		// autocommit must be off or the nested cursors
-		// are closed when the outer statement completes.
-		if (!conn.getAutoCommit())
-			nestedResults = new Vector();
-		else
-			nestedResults = null;
-
-		int len = indent_DisplayBanner(out,rsmd, indentLevel);
-
-		// When displaying rows, keep going past errors
-		// unless/until the maximum # of errors is reached.
-		boolean doNext = true;
-		int retry = 0;
-		while (doNext) {
-			try {
-				doNext = rs.next();
-				if (doNext) {
-
-		    		DisplayRow(out, rs, rsmd, len, nestedResults, conn, indentLevel);
-					ShowWarnings(out, rs);
-					numberOfRowsSelected++;
-				}
-			} catch (SQLException e) {
-				// REVISIT: might want to check the exception
-				// and for some, not bother with the retry.
-				if (++retry > MAX_RETRIES)
-					throw e;
-				else
-					ShowSQLException(out, e);
-			}
-		}
-		if (showSelectCount == true) {
-		   if (numberOfRowsSelected == 1) {
-			   out.println();
-			   indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_1RowSelec"));
-		   } else if (numberOfRowsSelected >= 0) {
-			   out.println();
-		       indentedPrintLine( out, indentLevel, 
-			LocalizedResource.getMessage("UT_0RowsSelec", LocalizedResource.getNumber(numberOfRowsSelected)));
-		   }
-		}
-
-		DisplayNestedResults(out, nestedResults, conn, indentLevel );
-		nestedResults = null;
-	}
-
-	/**
-		@param out the place to write to
-		@param nr the vector of results
-		@param conn the Connection against which the ResultSet was retrieved
-		@param indentLevel number of tab stops to indent line
-
-		@exception SQLException thrown on access error
-	 */
-	static private void DisplayNestedResults(PrintWriter out, Vector nr, Connection conn, int indentLevel )
-		throws SQLException {
-
-		if (nr == null) return;
-
-		String b=LocalizedResource.getMessage("UT_JDBCDisplayUtil_16");
-		String oldString="0";
-
-		for (int i=0; i < nr.size(); i++) {
-			LocalizedResource.OutputWriter().println();
-
-			//just too clever to get the extra +s
-			String t = Integer.toString(i);
-			if (t.length() > oldString.length()) {
-				oldString = t;
-				b=b+LocalizedResource.getMessage("UT_JDBCDisplayUtil_17");
-			}
-
-			LocalizedResource.OutputWriter().println(b);
-			LocalizedResource.OutputWriter().println(LocalizedResource.getMessage("UT_Resul0", LocalizedResource.getNumber(i)));
-			LocalizedResource.OutputWriter().println(b);
-			indent_DisplayResults(out, (ResultSet) nr.elementAt(i), conn, indentLevel);
-		}
-	}
-
-	/**
-		Fetch the next row of the result set, and if it
-		exists format and display a banner and the row.
-
-		@param out the place to write to
-		@param rs the ResultSet in use
-		@param conn the Connection against which the ResultSet was retrieved
-
-		@exception SQLException on JDBC access failure
-	 */
-	static public void DisplayNextRow(PrintWriter out, ResultSet rs, Connection conn )
-		throws SQLException
-	{
-		indent_DisplayNextRow( out, rs, conn, 0 );
-	}
-
-	static private void indent_DisplayNextRow(PrintWriter out, ResultSet rs, Connection conn, int indentLevel )
-		throws SQLException {
-
-		Vector nestedResults;
-
-		// autocommit must be off or the nested cursors
-		// are closed when the outer statement completes.
-		if (!conn.getAutoCommit())
-			nestedResults = new Vector();
-		else
-			nestedResults = null;
-
-		checkNotNull(rs, "ResultSet");
-
-		ResultSetMetaData rsmd = rs.getMetaData();
-		checkNotNull(rsmd, "ResultSetMetaData");
-
-		// Only print stuff out if there is a row to be had.
-		if (rs.next()) {
-			int rowLen = indent_DisplayBanner(out, rsmd, indentLevel);
-    		DisplayRow(out, rs, rsmd, rowLen, nestedResults, conn, indentLevel );
-		}
-		else {
-			indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_NoCurreRow"));
-		}
-
-		ShowWarnings(out, rs);
-
-		DisplayNestedResults(out, nestedResults, conn, indentLevel );
-		nestedResults = null;
-
-	} // DisplayNextRow
-
-	/**
-		Display the current row of the result set along with
-		a banner. Assume the result set is on a row.
-
-		@param out the place to write to
-		@param rs the ResultSet in use
-		@param conn the Connection against which the ResultSet was retrieved
-
-		@exception SQLException on JDBC access failure
-	 */
-	static public void DisplayCurrentRow(PrintWriter out, ResultSet rs, Connection conn )
-		throws SQLException
-	{
-		indent_DisplayCurrentRow( out, rs, conn, 0 );
-	}
-
-	static private void indent_DisplayCurrentRow(PrintWriter out, ResultSet rs, Connection conn, int indentLevel )
-		throws SQLException {
-
-		Vector nestedResults;
-
-		if (rs == null) {
-			indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_NoCurreRow_19"));
-			return;
-		}
-
-		// autocommit must be off or the nested cursors
-		// are closed when the outer statement completes.
-		if (!conn.getAutoCommit())
-			nestedResults = new Vector();
-		else
-			nestedResults = null;
-
-		ResultSetMetaData rsmd = rs.getMetaData();
-		checkNotNull(rsmd, "ResultSetMetaData");
-
-		int rowLen = indent_DisplayBanner(out, rsmd, indentLevel);
-   		DisplayRow(out, rs, rsmd, rowLen, nestedResults, conn, indentLevel );
-
-		ShowWarnings(out, rs);
-
-		DisplayNestedResults(out, nestedResults, conn, indentLevel );
-		nestedResults = null;
-
-	} // DisplayNextRow
-
-	/**
-		Print a banner containing the column labels separated with '|'s
-		and a line of '-'s.  Each field is as wide as the display
-		width reported by the metadata.
-
-		@param out the place to write to
-		@param rsmd the ResultSetMetaData to use
-
-		@exception SQLException on JDBC access failure
-	 */
-	static public int DisplayBanner(PrintWriter out, ResultSetMetaData rsmd )
-		throws SQLException
-	{
-		return indent_DisplayBanner( out, rsmd, 0 );
-	}
-
-	static private int indent_DisplayBanner(PrintWriter out, ResultSetMetaData rsmd, int indentLevel )
-		throws SQLException	{
-
-		StringBuffer buf = new StringBuffer();
-
-		int numCols = rsmd.getColumnCount();
-		int rowLen;
-
-		// do some precalculation so the buffer is allocated only once
-		// buffer is twice as long as the display length plus one for a newline
-		rowLen = (numCols - 1); // for the column separators
-		for (int i=1; i <= numCols; i++) {
-			rowLen += Math.min(maxWidth,
-				Math.max((rsmd.isNullable(i) == 
-							ResultSetMetaData.columnNoNulls)?
-							0 : MINWIDTH, LocalizedResource.getInstance().getColumnDisplaySize(rsmd, i)));
-		}
-		buf.ensureCapacity(rowLen);
-
-		// get column header info
-		// truncate it to the column display width
-		// add a bar between each item.
-		for (int i=1; i <= numCols; i++) {
-
-			if (i>1)
-				buf.append('|');
-
-			String s = rsmd.getColumnLabel(i);
-
-			int w = Math.min(maxWidth,
-				Math.max(((rsmd.isNullable(i) == 
-							ResultSetMetaData.columnNoNulls)?
-							0 : MINWIDTH), LocalizedResource.getInstance().getColumnDisplaySize(rsmd, i)));
-
-			if (s.length() < w) {
-				// build a string buffer to hold the whitespace
-				StringBuffer blanks = new StringBuffer(s);
-				blanks.ensureCapacity(w);
-
-				// try to paste on big chunks of space at a time.
-				for (int k=blanks.length()+64; k<=w; k+=64)
-					blanks.append(
-          "                                                                ");
-				for (int k=blanks.length()+16; k<=w; k+=16)
-					blanks.append("                ");
-				for (int k=blanks.length()+4; k<=w; k+=4)
-					blanks.append("    ");
-				for (int k=blanks.length(); k<w; k++)
-					blanks.append(' ');
-
-				buf.append(blanks);
-				// REMIND: could do more cleverness, like keep around
-				// past buffers to reuse...
-			}
-			else if (s.length() > w)  {
-				if (w > 1) 
-					buf.append(s.substring(0,w-1));
-				if (w > 0) 
-					buf.append('&');
-			}
-			else {
-				buf.append(s);
-			}
-		}
-
-		buf.setLength(Math.min(rowLen, 1024));
-		indentedPrintLine( out, indentLevel, buf);
-
-		// now print a row of '-'s
-		for (int i=0; i<Math.min(rowLen, 1024); i++)
-			buf.setCharAt(i, '-');
-		indentedPrintLine( out, indentLevel, buf);
-
-		buf = null;
-
-		return rowLen;
-	} // DisplayBanner
-
-	/**
-		Print one row of a result set, padding each field to the
-		display width and separating them with '|'s
-
-		@param out the place to write to
-		@param rs the ResultSet to use
-		@param rsmd the ResultSetMetaData to use
-		@param rowLen
-		@param nestedResults
-		@param conn
-		@param indentLevel number of tab stops to indent line
-
-		@exception SQLException thrown on JDBC access failure
-	 */
-	static private void DisplayRow(PrintWriter out, ResultSet rs, ResultSetMetaData rsmd, int rowLen, Vector nestedResults, Connection conn, int indentLevel )
-		throws SQLException
-	{
-		StringBuffer buf = new StringBuffer();
-		buf.ensureCapacity(rowLen);
-
-		int numCols = rsmd.getColumnCount();
-		int i;
-
-		// get column header info
-		// truncate it to the column display width
-		// add a bar between each item.
-		for (i=1; i <= numCols; i++){
-			if (i>1)
-				buf.append('|');
-
-			String s;
-			switch (rsmd.getColumnType(i)) {
-			default:
-				s = LocalizedResource.getInstance().getLocalizedString(rs, rsmd, i );
-				break;
-			case org.apache.derby.iapi.reference.JDBC20Translation.SQL_TYPES_JAVA_OBJECT:
-			case Types.OTHER:
-			{
-				Object o = rs.getObject(i);
-				if (o == null) { s = "NULL"; }
-				else if (o instanceof ResultSet && nestedResults != null)
-				{
-					s = LocalizedResource.getMessage("UT_Resul0_20", LocalizedResource.getNumber(nestedResults.size()));
-					nestedResults.addElement(o);
-				}
-				else
-				{
-					try {
-						s = rs.getString(i);
-					} catch (SQLException se) {
-						// oops, they don't support refetching the column
-						s = o.toString();
-					}
-				}
-			}
-			break;
-			}
-			if (s==null) s = "NULL";
-
-			int w = Math.min(maxWidth,
-				Math.max((rsmd.isNullable(i) == 
-							ResultSetMetaData.columnNoNulls)?
-							0 : MINWIDTH, LocalizedResource.getInstance().getColumnDisplaySize(rsmd, i)));
-			if (s.length() < w) {
-				StringBuffer fullS = new StringBuffer(s);
-				fullS.ensureCapacity(w);
-				for (int k=s.length(); k<w; k++)
-					fullS.append(' ');
-				s = fullS.toString();
-			}
-			else if (s.length() > w)
-				// add the & marker to know it got cut off
-				s = s.substring(0,w-1)+"&";
-
-			buf.append(s);
-		}
-		indentedPrintLine( out, indentLevel, buf);
-
-	} // DisplayRow
-
-	/**
-		Check if an object is null, and if it is, throw an exception
-		with an informative parameter about what was null.
-		The exception is a run-time exception that is internal to ij.
-
-		@param o the object to test
-		@param what the information to include in the error if it is null
-	 */
-	public static void checkNotNull(Object o, String what) {
-		if (o == null) {
-			throw ijException.objectWasNull(what);
-		}
-	} // checkNotNull
-
-	/**
-		Map the string to the value if it is null.
-
-		@param s the string to test for null
-		@param nullValue the value to use if s is null
-
-		@return if s is non-null, s; else nullValue.
-	 */
-	static public String mapNull(String s, String nullValue) {
-		if (s==null) return nullValue;
-		return s;
-	}
-
-	/**
-		If the property ij.exceptionTrace is true, display the stack
-		trace to the print stream. Otherwise, do nothing.
-
-		@param out the output stream to write to
-		@param e the exception to display
-	 */
-	static public void doTrace(PrintWriter out, Exception e) {
-		if (Boolean.getBoolean("ij.exceptionTrace")) {
-			e.printStackTrace(out);
-		    out.flush();
-		}
-	}
-
-	static public void setMaxDisplayWidth(int maxDisplayWidth) {
-		maxWidth = maxDisplayWidth;
-	}
-
-	static	private	void	indentedPrintLine( PrintWriter out, int indentLevel, String text )
-	{
-		indent( out, indentLevel );
-		out.println( text );
-	}
-
-	static	private	void	indentedPrintLine( PrintWriter out, int indentLevel, StringBuffer text )
-	{
-		indent( out, indentLevel );
-		out.println( text );
-	}
-
-	static	private	void	indent( PrintWriter out, int indentLevel )
-	{
-		for ( int ictr = 0; ictr < indentLevel; ictr++ ) { out.print( "  " ); }
-	}
-
-	// ================
-
-	static public void ShowException(PrintStream out, Throwable e) {
-		if (e == null) return;
-
-		if (e instanceof SQLException)
-			ShowSQLException(out, (SQLException)e);
-		else
-			e.printStackTrace(out);
-	}
-
-	static public void ShowSQLException(PrintStream out, SQLException e) {
-		String errorCode;
-
-		if (Boolean.getBoolean("ij.showErrorCode")) {
-			errorCode = " (errorCode = " + e.getErrorCode() + ")";
-		}
-		else {
-			errorCode = "";
-		}
-
-		while (e!=null) {
-			out.println("ERROR "+mapNull(e.getSQLState(),"(no SQLState)")+": "+
-				 mapNull(e.getMessage(),"(no message)")+errorCode);
-			doTrace(out, e);
-			e=e.getNextException();
-		}
-	}
-
-	static public void ShowWarnings(PrintStream out, Connection theConnection) {
-	    try {
-		// GET CONNECTION WARNINGS
-		SQLWarning warning = null;
-
-		if (theConnection != null) {
-			ShowWarnings(out, theConnection.getWarnings());
-		}
-
-		if (theConnection != null) {
-			theConnection.clearWarnings();
-		}
-	    } catch (SQLException e) {
-			ShowSQLException(out, e);
-	    }
-	} // ShowWarnings
-
-	static public void ShowWarnings(PrintStream out, SQLWarning warning) {
-		while (warning != null) {
-			out.println("WARNING "+
-				mapNull(warning.getSQLState(),"(no SQLState)")+": "+
-				mapNull(warning.getMessage(),"(no message)"));
-			warning = warning.getNextWarning();
-		}
-	}
-
-	static public void ShowWarnings(PrintStream out, ResultSet rs) {
-	    try {
-		// GET RESULTSET WARNINGS
-		SQLWarning warning = null;
-
-		if (rs != null) {
-			ShowWarnings(out, rs.getWarnings());
-		}
-
-		if (rs != null) {
-			rs.clearWarnings();
-		}
-	    } catch (SQLException e) {
-			ShowSQLException(out, e);
-	    }
-	} // ShowResultSetWarnings
-
-	static public void ShowWarnings(PrintStream out, Statement s)
-	{
-	    try {
-		// GET STATEMENT WARNINGS
-		SQLWarning warning = null;
-
-		if (s != null) {
-			ShowWarnings(out, s.getWarnings());
-		}
-
-		if (s != null) {
-			s.clearWarnings();
-		}
-	    } catch (SQLException e) {
-			ShowSQLException(out, e);
-	    }
-	} // ShowStatementWarnings
-
-	static public void DisplayResults(PrintStream out, Statement stmt, Connection conn )
-		throws SQLException
-	{
-		indent_DisplayResults( out, stmt, conn, 0);			
-	}
-
-	static private void indent_DisplayResults
-	(PrintStream out, Statement stmt, Connection conn, int indentLevel)
-		throws SQLException {
-
-		checkNotNull(stmt, "Statement");
-
-		ResultSet rs = stmt.getResultSet();
-		if (rs != null) {
-			indent_DisplayResults(out, rs, conn, indentLevel);
-			rs.close(); // let the result set go away
-		}
-		else {
-			DisplayUpdateCount(out,stmt.getUpdateCount(), indentLevel);
-		}
-
-		ShowWarnings(out,stmt);
-	} // DisplayResults
-
-	static void DisplayUpdateCount(PrintStream out, int count, int indentLevel ) {
-		if (count == 1) {
-			indentedPrintLine( out, indentLevel, "1 row inserted/updated/deleted");
-		}
-		else if (count >= 0) {
-			indentedPrintLine( out, indentLevel, count+" rows inserted/updated/deleted");
-		}
-		else {
-			indentedPrintLine( out, indentLevel, "Statement executed.");
-		}
-	}
-
-	static public void DisplayResults(PrintStream out, ResultSet rs, Connection conn)
-		throws SQLException
-	{
-		indent_DisplayResults( out, rs, conn, 0);
-	}
-
-	static private void indent_DisplayResults
-	(PrintStream out, ResultSet rs, Connection conn, int indentLevel)
-		throws SQLException {
-		ResultSetMetaData rsmd = rs.getMetaData();
-		checkNotNull(rsmd, "ResultSetMetaData");
-		Vector nestedResults;
-    int numberOfRowsSelected = 0;
-
-		// autocommit must be off or the nested cursors
-		// are closed when the outer statement completes.
-		if (!conn.getAutoCommit())
-			nestedResults = new Vector();
-		else
-			nestedResults = null;
-
-		int len = indent_DisplayBanner(out,rsmd, indentLevel);
-
-		// When displaying rows, keep going past errors
-		// unless/until the maximum # of errors is reached.
-		boolean doNext = true;
-		int retry = 0;
-		while (doNext) {
-			try {
-				doNext = rs.next();
-				if (doNext) {
-
-		    		DisplayRow(out, rs, rsmd, len, nestedResults, conn, indentLevel);
-					ShowWarnings(out, rs);
-					numberOfRowsSelected++;
-				}
-			} catch (SQLException e) {
-				// REVISIT: might want to check the exception
-				// and for some, not bother with the retry.
-				if (++retry > MAX_RETRIES)
-					throw e;
-				else
-					ShowSQLException(out, e);
-			}
-		}
-		if (showSelectCount == true) {
-		   if (numberOfRowsSelected == 1) {
-			   out.println();
-			   indentedPrintLine( out, indentLevel, "1 row selected");
-		   } else if (numberOfRowsSelected >= 0) {
-			   out.println();
-		       indentedPrintLine( out, indentLevel, numberOfRowsSelected + " rows selected");
-		   }
-		}
-
-		DisplayNestedResults(out, nestedResults, conn, indentLevel );
-		nestedResults = null;
-	}
-
-	static private void DisplayNestedResults(PrintStream out, Vector nr, Connection conn, int indentLevel )
-		throws SQLException {
-
-		if (nr == null) return;
-
-		String s="+ ResultSet #";
-		String b="++++++++++++++++";
-		String oldString="0";
-
-		for (int i=0; i < nr.size(); i++) {
-			System.out.println();
-
-			//just too clever to get the extra +s
-			String t = Integer.toString(i);
-			if (t.length() > oldString.length()) {
-				oldString = t;
-				b=b+"+";
-			}
-
-			System.out.println(b);
-			System.out.println(s+i+" +");
-			System.out.println(b);
-			indent_DisplayResults(out, (ResultSet) nr.elementAt(i), conn, indentLevel);
-		}
-	}
-
-	static public void DisplayNextRow(PrintStream out, ResultSet rs, Connection conn )
-		throws SQLException
-	{
-		indent_DisplayNextRow( out, rs, conn, 0 );
-	}
-
-	static private void indent_DisplayNextRow(PrintStream out, ResultSet rs, Connection conn, int indentLevel )
-		throws SQLException {
-
-		Vector nestedResults;
-
-		// autocommit must be off or the nested cursors
-		// are closed when the outer statement completes.
-		if (!conn.getAutoCommit())
-			nestedResults = new Vector();
-		else
-			nestedResults = null;
-
-		checkNotNull(rs, "ResultSet");
-
-		ResultSetMetaData rsmd = rs.getMetaData();
-		checkNotNull(rsmd, "ResultSetMetaData");
-
-		// Only print stuff out if there is a row to be had.
-		if (rs.next()) {
-			int rowLen = indent_DisplayBanner(out, rsmd, indentLevel);
-    		DisplayRow(out, rs, rsmd, rowLen, nestedResults, conn, indentLevel );
-		}
-		else {
-			indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_NoCurreRow"));
-		}
-
-		ShowWarnings(out, rs);
-
-		DisplayNestedResults(out, nestedResults, conn, indentLevel );
-		nestedResults = null;
-
-	} // DisplayNextRow
-
-	static public void DisplayCurrentRow(PrintStream out, ResultSet rs, Connection conn )
-		throws SQLException
-	{
-		indent_DisplayCurrentRow( out, rs, conn, 0 );
-	}
-
-	static private void indent_DisplayCurrentRow(PrintStream out, ResultSet rs, Connection conn, int indentLevel )
-		throws SQLException {
-
-		Vector nestedResults;
-
-		if (rs == null) {
-			indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_NoCurreRow_19"));
-			return;
-		}
-
-		// autocommit must be off or the nested cursors
-		// are closed when the outer statement completes.
-		if (!conn.getAutoCommit())
-			nestedResults = new Vector();
-		else
-			nestedResults = null;
-
-		ResultSetMetaData rsmd = rs.getMetaData();
-		checkNotNull(rsmd, "ResultSetMetaData");
-
-		int rowLen = indent_DisplayBanner(out, rsmd, indentLevel);
-   		DisplayRow(out, rs, rsmd, rowLen, nestedResults, conn, indentLevel );
-
-		ShowWarnings(out, rs);
-
-		DisplayNestedResults(out, nestedResults, conn, indentLevel );
-		nestedResults = null;
-
-	} // DisplayNextRow
-
-	static public int DisplayBanner(PrintStream out, ResultSetMetaData rsmd )
-		throws SQLException
-	{
-		return indent_DisplayBanner( out, rsmd, 0 );
-	}
-
-	static private int indent_DisplayBanner(PrintStream out, ResultSetMetaData rsmd, int indentLevel )
-		throws SQLException	{
-
-		StringBuffer buf = new StringBuffer();
-
-		int numCols = rsmd.getColumnCount();
-		int rowLen;
-
-		// do some precalculation so the buffer is allocated only once
-		// buffer is twice as long as the display length plus one for a newline
-		rowLen = (numCols - 1); // for the column separators
-		for (int i=1; i <= numCols; i++) {
-			rowLen += Math.min(maxWidth,
-				Math.max((rsmd.isNullable(i) == 
-							ResultSetMetaData.columnNoNulls)?
-							0 : MINWIDTH,
-						rsmd.getColumnDisplaySize(i)));
-		}
-		buf.ensureCapacity(rowLen);
-
-		// get column header info
-		// truncate it to the column display width
-		// add a bar between each item.
-		for (int i=1; i <= numCols; i++) {
-
-			if (i>1)
-				buf.append('|');
-
-			String s = rsmd.getColumnLabel(i);
-
-			int w = Math.min(maxWidth,
-				Math.max(((rsmd.isNullable(i) == 
-							ResultSetMetaData.columnNoNulls)?
-							0 : MINWIDTH),
-						rsmd.getColumnDisplaySize(i)));
-
-			if (s.length() < w) {
-				// build a string buffer to hold the whitespace
-				StringBuffer blanks = new StringBuffer(s);
-				blanks.ensureCapacity(w);
-
-				// try to paste on big chunks of space at a time.
-				for (int k=blanks.length()+64; k<=w; k+=64)
-					blanks.append(
-          "                                                                ");
-				for (int k=blanks.length()+16; k<=w; k+=16)
-					blanks.append("                ");
-				for (int k=blanks.length()+4; k<=w; k+=4)
-					blanks.append("    ");
-				for (int k=blanks.length(); k<w; k++)
-					blanks.append(' ');
-
-				buf.append(blanks);
-				// REMIND: could do more cleverness, like keep around
-				// past buffers to reuse...
-			}
-			else if (s.length() > w)  {
-				if (w > 1) 
-					buf.append(s.substring(0,w-1));
-				if (w > 0) 
-					buf.append('&');
-			}
-			else {
-				buf.append(s);
-			}
-		}
-
-		buf.setLength(Math.min(rowLen, 1024));
-		indentedPrintLine( out, indentLevel, buf);
-
-		// now print a row of '-'s
-		for (int i=0; i<Math.min(rowLen, 1024); i++)
-			buf.setCharAt(i, '-');
-		indentedPrintLine( out, indentLevel, buf);
-
-		buf = null;
-
-		return rowLen;
-	} // DisplayBanner
-
-	static private void DisplayRow(PrintStream out, ResultSet rs, ResultSetMetaData rsmd, int rowLen, Vector nestedResults, Connection conn, int indentLevel )
-		throws SQLException
-	{
-		StringBuffer buf = new StringBuffer();
-		buf.ensureCapacity(rowLen);
-
-		int numCols = rsmd.getColumnCount();
-		int i;
-
-		// get column header info
-		// truncate it to the column display width
-		// add a bar between each item.
-		for (i=1; i <= numCols; i++){
-			if (i>1)
-				buf.append('|');
-
-			String s;
-			switch (rsmd.getColumnType(i)) {
-			default:
-				s = rs.getString(i);
-				break;
-			case org.apache.derby.iapi.reference.JDBC20Translation.SQL_TYPES_JAVA_OBJECT:
-			case Types.OTHER:
-			{
-				Object o = rs.getObject(i);
-				if (o == null) { s = "NULL"; }
-				else if (o instanceof ResultSet && nestedResults != null)
-				{
-					s = "ResultSet #"+nestedResults.size();
-					nestedResults.addElement(o);
-				}
-				else
-				{
-					try {
-						s = rs.getString(i);
-					} catch (SQLException se) {
-						// oops, they don't support refetching the column
-						s = o.toString();
-					}
-				}
-			}
-			break;
-			}
-
-			if (s==null) s = "NULL";
-
-			int w = Math.min(maxWidth,
-				Math.max((rsmd.isNullable(i) == 
-							ResultSetMetaData.columnNoNulls)?
-							0 : MINWIDTH,
-						rsmd.getColumnDisplaySize(i)));
-			if (s.length() < w) {
-				StringBuffer fullS = new StringBuffer(s);
-				fullS.ensureCapacity(w);
-				for (int k=s.length(); k<w; k++)
-					fullS.append(' ');
-				s = fullS.toString();
-			}
-			else if (s.length() > w)
-				// add the & marker to know it got cut off
-				s = s.substring(0,w-1)+"&";
-
-			buf.append(s);
-		}
-		indentedPrintLine( out, indentLevel, buf);
-
-	} // DisplayRow
-
-	static public void doTrace(PrintStream out, Exception e) {
-		if (Boolean.getBoolean("ij.exceptionTrace")) {
-			e.printStackTrace(out);
-		    out.flush();
-		}
-	}
-
-	static	private	void	indentedPrintLine( PrintStream out, int indentLevel, String text )
-	{
-		indent( out, indentLevel );
-		out.println( text );
-	}
-
-	static	private	void	indentedPrintLine( PrintStream out, int indentLevel, StringBuffer text )
-	{
-		indent( out, indentLevel );
-		out.println( text );
-	}
-
-	static	private	void	indent( PrintStream out, int indentLevel )
-	{
-		for ( int ictr = 0; ictr < indentLevel; ictr++ ) { out.print( "  " ); }
-	}
-	
-	// ==========================
-}
-
-
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.tools
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.tools;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.Types;
+
+import java.util.Properties;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.derby.iapi.tools.i18n.LocalizedResource;
+
+import org.apache.derby.impl.tools.ij.ijException;
+
+/**
+	
+	This class contains utility methods for displaying JDBC objects and results.
+	
+	<p>
+	All of the methods are static. The output stream
+	to write to is always passed in, along with the
+	JDBC objects to display.
+
+	@author ames
+ */
+public class JDBCDisplayUtil { 
+
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+
+	// used to control display
+	static final private int MINWIDTH = 4;
+	static private int maxWidth = 128;
+    static public boolean showSelectCount = false;
+
+    static {
+        // initialize the locale support functions to default value of JVM 
+        LocalizedResource.getInstance();
+    }
+
+
+	//-----------------------------------------------------------------
+	// Methods for initialization resource bundle and codeset's output
+	
+	/**
+	 * init method - will init the class to support a locale and
+	 * codeset based on the derby.ui.locale and derby.ui.codeset
+	 * properties if exists or using the default values from the JVM.
+	 */
+	static public boolean init() {
+		return (LocalizedResource.getInstance() != null);
+	}
+
+	/**
+	 * init method - will init the class to support a locale and
+	 * codeset based on the derby.ui.locale properties and on the 
+     * given codeset if exists or using the default values from the JVM.
+	 */
+	public static boolean init(String codeset) {
+		return init(codeset, null);
+	}
+
+	/**
+	 * init method - will init the class to support a locale and
+	 * codeset based on the given codeset and locale.
+	 * If the parameters are null it will try to init use derby.ui.locale
+	 * and derby.ui.codeset properties if exists or using the default
+	 * values from the JVM.
+	 */
+	public static boolean init(String pCodeset, String pLocale) {
+		LocalizedResource.getInstance().init(pCodeset, pLocale,null);
+		return true;
+	}
+
+	//-----------------------------------------------------------------
+	// Methods for displaying and checking errors
+
+	/**
+		Print information about the exception to the given PrintWriter.
+		For non-SQLExceptions, does a stack trace. For SQLExceptions,
+		print a standard error message and walk the list, if any.
+
+		@param out the place to write to
+		@param e the exception to display
+	 */
+	static public void ShowException(PrintWriter out, Throwable e) {
+		if (e == null) return;
+
+		if (e instanceof SQLException)
+			ShowSQLException(out, (SQLException)e);
+		else
+			e.printStackTrace(out);
+	}
+
+	/**
+		Print information about the SQL exception to the given PrintWriter.
+		Walk the list of exceptions, if any.
+
+		@param out the place to write to
+		@param e the exception to display
+	 */
+	static public void ShowSQLException(PrintWriter out, SQLException e) {
+		String errorCode;
+
+		if (Boolean.getBoolean("ij.showErrorCode")) {
+			errorCode = LocalizedResource.getMessage("UT_Error0", LocalizedResource.getNumber(e.getErrorCode()));
+		}
+		else {
+			errorCode = "";
+		}
+
+		while (e!=null) {
+			String p1 = mapNull(e.getSQLState(),LocalizedResource.getMessage("UT_NoSqlst"));
+			String p2 = mapNull(e.getMessage(),LocalizedResource.getMessage("UT_NoMessa"));
+			out.println(LocalizedResource.getMessage("UT_Error012", p1, p2,errorCode));
+			doTrace(out, e);
+			e=e.getNextException();
+		}
+	}
+
+	/**
+		Print information about the SQL warnings for the connection
+		to the given PrintWriter.
+		Walks the list of exceptions, if any.
+
+		@param out the place to write to
+		@param theConnection the connection that may have warnings.
+	 */
+	static public void ShowWarnings(PrintWriter out, Connection theConnection) {
+	    try {
+		// GET CONNECTION WARNINGS
+		SQLWarning warning = null;
+
+		if (theConnection != null) {
+			ShowWarnings(out, theConnection.getWarnings());
+		}
+
+		if (theConnection != null) {
+			theConnection.clearWarnings();
+		}
+	    } catch (SQLException e) {
+			ShowSQLException(out, e);
+	    }
+	} // ShowWarnings
+
+	/**
+		@param out the place to write to
+		@param warning the SQLWarning
+	*/
+	static public void ShowWarnings(PrintWriter out, SQLWarning warning) {
+		while (warning != null) {
+			String p1 = mapNull(warning.getSQLState(),LocalizedResource.getMessage("UT_NoSqlst_7"));
+			String p2 = mapNull(warning.getMessage(),LocalizedResource.getMessage("UT_NoMessa_8"));
+			out.println(LocalizedResource.getMessage("UT_Warni01", p1, p2));
+			warning = warning.getNextWarning();
+		}
+	}
+
+	/**
+		Print information about the SQL warnings for the ResultSet
+		to the given PrintWriter.
+		Walk the list of exceptions, if any.
+	
+		@param out the place to write to
+		@param rs the ResultSet that may have warnings on it
+	 */
+	static public void ShowWarnings(PrintWriter out, ResultSet rs) {
+	    try {
+		// GET RESULTSET WARNINGS
+		SQLWarning warning = null;
+
+		if (rs != null) {
+			ShowWarnings(out, rs.getWarnings());
+		}
+
+		if (rs != null) {
+			rs.clearWarnings();
+		}
+	    } catch (SQLException e) {
+			ShowSQLException(out, e);
+	    }
+	} // ShowResultSetWarnings
+
+	/**
+		Print information about the SQL warnings for the Statement
+		to the given PrintWriter.
+		Walks the list of exceptions, if any.
+
+		@param out the place to write to
+		@param s the Statement that may have warnings on it
+	 */
+	static public void ShowWarnings(PrintWriter out, Statement s)
+	{
+	    try {
+		// GET STATEMENT WARNINGS
+		SQLWarning warning = null;
+
+		if (s != null) {
+			ShowWarnings(out, s.getWarnings());
+		}
+
+		if (s != null) {
+			s.clearWarnings();
+		}
+	    } catch (SQLException e) {
+			ShowSQLException(out, e);
+	    }
+	} // ShowStatementWarnings
+
+	//-----------------------------------------------------------------
+	// Methods for displaying and checking results
+
+	// REMIND: make this configurable...
+	static final private int MAX_RETRIES = 0;
+
+	/**
+		Pretty-print the results of a statement that has been executed.
+		If it is a select, gathers and prints the results.  Display
+		partial results up to the first error.
+		If it is not a SELECT, determine if rows were involved or not,
+		and print the appropriate message.
+
+		@param out the place to write to
+		@param stmt the Statement to display
+		@param conn the Connection against which the statement was executed
+
+		@exception SQLException on JDBC access failure
+	 */
+	static public void DisplayResults(PrintWriter out, Statement stmt, Connection conn )
+		throws SQLException
+	{
+		indent_DisplayResults( out, stmt, conn, 0);			
+	}
+
+	static private void indent_DisplayResults
+	(PrintWriter out, Statement stmt, Connection conn, int indentLevel)
+		throws SQLException {
+
+		checkNotNull(stmt, "Statement");
+
+		ResultSet rs = stmt.getResultSet();
+		if (rs != null) {
+			indent_DisplayResults(out, rs, conn, indentLevel);
+			rs.close(); // let the result set go away
+		}
+		else {
+			DisplayUpdateCount(out,stmt.getUpdateCount(), indentLevel);
+		}
+
+		ShowWarnings(out,stmt);
+	} // DisplayResults
+
+	/**
+		@param out the place to write to
+		@param count the update count to display
+		@param indentLevel number of tab stops to indent line
+	 */
+	static void DisplayUpdateCount(PrintWriter out, int count, int indentLevel ) {
+		if (count == 1) {
+			indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_1RowInserUpdatDelet"));
+		}
+		else if (count >= 0) {
+			indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_0RowsInserUpdatDelet", LocalizedResource.getNumber(count)));
+		}
+		else {
+			indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_StateExecu"));
+		}
+	}
+
+	/**
+		@param out the place to write to
+		@param rs the ResultSet to display
+		@param conn the Connection against which the ResultSet was retrieved
+
+		@exception SQLException on JDBC access failure
+	 */
+	static public void DisplayResults(PrintWriter out, ResultSet rs, Connection conn)
+		throws SQLException
+	{
+		indent_DisplayResults( out, rs, conn, 0);
+	}
+
+	static private void indent_DisplayResults
+	(PrintWriter out, ResultSet rs, Connection conn, int indentLevel)
+		throws SQLException {
+		ResultSetMetaData rsmd = rs.getMetaData();
+		checkNotNull(rsmd, "ResultSetMetaData");
+		Vector nestedResults;
+    int numberOfRowsSelected = 0;
+
+		// autocommit must be off or the nested cursors
+		// are closed when the outer statement completes.
+		if (!conn.getAutoCommit())
+			nestedResults = new Vector();
+		else
+			nestedResults = null;
+
+		int len = indent_DisplayBanner(out,rsmd, indentLevel);
+
+		// When displaying rows, keep going past errors
+		// unless/until the maximum # of errors is reached.
+		boolean doNext = true;
+		int retry = 0;
+		while (doNext) {
+			try {
+				doNext = rs.next();
+				if (doNext) {
+
+		    		DisplayRow(out, rs, rsmd, len, nestedResults, conn, indentLevel);
+					ShowWarnings(out, rs);
+					numberOfRowsSelected++;
+				}
+			} catch (SQLException e) {
+				// REVISIT: might want to check the exception
+				// and for some, not bother with the retry.
+				if (++retry > MAX_RETRIES)
+					throw e;
+				else
+					ShowSQLException(out, e);
+			}
+		}
+		if (showSelectCount == true) {
+		   if (numberOfRowsSelected == 1) {
+			   out.println();
+			   indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_1RowSelec"));
+		   } else if (numberOfRowsSelected >= 0) {
+			   out.println();
+		       indentedPrintLine( out, indentLevel, 
+			LocalizedResource.getMessage("UT_0RowsSelec", LocalizedResource.getNumber(numberOfRowsSelected)));
+		   }
+		}
+
+		DisplayNestedResults(out, nestedResults, conn, indentLevel );
+		nestedResults = null;
+	}
+
+	/**
+		@param out the place to write to
+		@param nr the vector of results
+		@param conn the Connection against which the ResultSet was retrieved
+		@param indentLevel number of tab stops to indent line
+
+		@exception SQLException thrown on access error
+	 */
+	static private void DisplayNestedResults(PrintWriter out, Vector nr, Connection conn, int indentLevel )
+		throws SQLException {
+
+		if (nr == null) return;
+
+		String b=LocalizedResource.getMessage("UT_JDBCDisplayUtil_16");
+		String oldString="0";
+
+		for (int i=0; i < nr.size(); i++) {
+			LocalizedResource.OutputWriter().println();
+
+			//just too clever to get the extra +s
+			String t = Integer.toString(i);
+			if (t.length() > oldString.length()) {
+				oldString = t;
+				b=b+LocalizedResource.getMessage("UT_JDBCDisplayUtil_17");
+			}
+
+			LocalizedResource.OutputWriter().println(b);
+			LocalizedResource.OutputWriter().println(LocalizedResource.getMessage("UT_Resul0", LocalizedResource.getNumber(i)));
+			LocalizedResource.OutputWriter().println(b);
+			indent_DisplayResults(out, (ResultSet) nr.elementAt(i), conn, indentLevel);
+		}
+	}
+
+	/**
+		Fetch the next row of the result set, and if it
+		exists format and display a banner and the row.
+
+		@param out the place to write to
+		@param rs the ResultSet in use
+		@param conn the Connection against which the ResultSet was retrieved
+
+		@exception SQLException on JDBC access failure
+	 */
+	static public void DisplayNextRow(PrintWriter out, ResultSet rs, Connection conn )
+		throws SQLException
+	{
+		indent_DisplayNextRow( out, rs, conn, 0 );
+	}
+
+	static private void indent_DisplayNextRow(PrintWriter out, ResultSet rs, Connection conn, int indentLevel )
+		throws SQLException {
+
+		Vector nestedResults;
+
+		// autocommit must be off or the nested cursors
+		// are closed when the outer statement completes.
+		if (!conn.getAutoCommit())
+			nestedResults = new Vector();
+		else
+			nestedResults = null;
+
+		checkNotNull(rs, "ResultSet");
+
+		ResultSetMetaData rsmd = rs.getMetaData();
+		checkNotNull(rsmd, "ResultSetMetaData");
+
+		// Only print stuff out if there is a row to be had.
+		if (rs.next()) {
+			int rowLen = indent_DisplayBanner(out, rsmd, indentLevel);
+    		DisplayRow(out, rs, rsmd, rowLen, nestedResults, conn, indentLevel );
+		}
+		else {
+			indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_NoCurreRow"));
+		}
+
+		ShowWarnings(out, rs);
+
+		DisplayNestedResults(out, nestedResults, conn, indentLevel );
+		nestedResults = null;
+
+	} // DisplayNextRow
+
+	/**
+		Display the current row of the result set along with
+		a banner. Assume the result set is on a row.
+
+		@param out the place to write to
+		@param rs the ResultSet in use
+		@param conn the Connection against which the ResultSet was retrieved
+
+		@exception SQLException on JDBC access failure
+	 */
+	static public void DisplayCurrentRow(PrintWriter out, ResultSet rs, Connection conn )
+		throws SQLException
+	{
+		indent_DisplayCurrentRow( out, rs, conn, 0 );
+	}
+
+	static private void indent_DisplayCurrentRow(PrintWriter out, ResultSet rs, Connection conn, int indentLevel )
+		throws SQLException {
+
+		Vector nestedResults;
+
+		if (rs == null) {
+			indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_NoCurreRow_19"));
+			return;
+		}
+
+		// autocommit must be off or the nested cursors
+		// are closed when the outer statement completes.
+		if (!conn.getAutoCommit())
+			nestedResults = new Vector();
+		else
+			nestedResults = null;
+
+		ResultSetMetaData rsmd = rs.getMetaData();
+		checkNotNull(rsmd, "ResultSetMetaData");
+
+		int rowLen = indent_DisplayBanner(out, rsmd, indentLevel);
+   		DisplayRow(out, rs, rsmd, rowLen, nestedResults, conn, indentLevel );
+
+		ShowWarnings(out, rs);
+
+		DisplayNestedResults(out, nestedResults, conn, indentLevel );
+		nestedResults = null;
+
+	} // DisplayNextRow
+
+	/**
+		Print a banner containing the column labels separated with '|'s
+		and a line of '-'s.  Each field is as wide as the display
+		width reported by the metadata.
+
+		@param out the place to write to
+		@param rsmd the ResultSetMetaData to use
+
+		@exception SQLException on JDBC access failure
+	 */
+	static public int DisplayBanner(PrintWriter out, ResultSetMetaData rsmd )
+		throws SQLException
+	{
+		return indent_DisplayBanner( out, rsmd, 0 );
+	}
+
+	static private int indent_DisplayBanner(PrintWriter out, ResultSetMetaData rsmd, int indentLevel )
+		throws SQLException	{
+
+		StringBuffer buf = new StringBuffer();
+
+		int numCols = rsmd.getColumnCount();
+		int rowLen;
+
+		// do some precalculation so the buffer is allocated only once
+		// buffer is twice as long as the display length plus one for a newline
+		rowLen = (numCols - 1); // for the column separators
+		for (int i=1; i <= numCols; i++) {
+			rowLen += Math.min(maxWidth,
+				Math.max((rsmd.isNullable(i) == 
+							ResultSetMetaData.columnNoNulls)?
+							0 : MINWIDTH, LocalizedResource.getInstance().getColumnDisplaySize(rsmd, i)));
+		}
+		buf.ensureCapacity(rowLen);
+
+		// get column header info
+		// truncate it to the column display width
+		// add a bar between each item.
+		for (int i=1; i <= numCols; i++) {
+
+			if (i>1)
+				buf.append('|');
+
+			String s = rsmd.getColumnLabel(i);
+
+			int w = Math.min(maxWidth,
+				Math.max(((rsmd.isNullable(i) == 
+							ResultSetMetaData.columnNoNulls)?
+							0 : MINWIDTH), LocalizedResource.getInstance().getColumnDisplaySize(rsmd, i)));
+
+			if (s.length() < w) {
+				// build a string buffer to hold the whitespace
+				StringBuffer blanks = new StringBuffer(s);
+				blanks.ensureCapacity(w);
+
+				// try to paste on big chunks of space at a time.
+				for (int k=blanks.length()+64; k<=w; k+=64)
+					blanks.append(
+          "                                                                ");
+				for (int k=blanks.length()+16; k<=w; k+=16)
+					blanks.append("                ");
+				for (int k=blanks.length()+4; k<=w; k+=4)
+					blanks.append("    ");
+				for (int k=blanks.length(); k<w; k++)
+					blanks.append(' ');
+
+				buf.append(blanks);
+				// REMIND: could do more cleverness, like keep around
+				// past buffers to reuse...
+			}
+			else if (s.length() > w)  {
+				if (w > 1) 
+					buf.append(s.substring(0,w-1));
+				if (w > 0) 
+					buf.append('&');
+			}
+			else {
+				buf.append(s);
+			}
+		}
+
+		buf.setLength(Math.min(rowLen, 1024));
+		indentedPrintLine( out, indentLevel, buf);
+
+		// now print a row of '-'s
+		for (int i=0; i<Math.min(rowLen, 1024); i++)
+			buf.setCharAt(i, '-');
+		indentedPrintLine( out, indentLevel, buf);
+
+		buf = null;
+
+		return rowLen;
+	} // DisplayBanner
+
+	/**
+		Print one row of a result set, padding each field to the
+		display width and separating them with '|'s
+
+		@param out the place to write to
+		@param rs the ResultSet to use
+		@param rsmd the ResultSetMetaData to use
+		@param rowLen
+		@param nestedResults
+		@param conn
+		@param indentLevel number of tab stops to indent line
+
+		@exception SQLException thrown on JDBC access failure
+	 */
+	static private void DisplayRow(PrintWriter out, ResultSet rs, ResultSetMetaData rsmd, int rowLen, Vector nestedResults, Connection conn, int indentLevel )
+		throws SQLException
+	{
+		StringBuffer buf = new StringBuffer();
+		buf.ensureCapacity(rowLen);
+
+		int numCols = rsmd.getColumnCount();
+		int i;
+
+		// get column header info
+		// truncate it to the column display width
+		// add a bar between each item.
+		for (i=1; i <= numCols; i++){
+			if (i>1)
+				buf.append('|');
+
+			String s;
+			switch (rsmd.getColumnType(i)) {
+			default:
+				s = LocalizedResource.getInstance().getLocalizedString(rs, rsmd, i );
+				break;
+			case org.apache.derby.iapi.reference.JDBC20Translation.SQL_TYPES_JAVA_OBJECT:
+			case Types.OTHER:
+			{
+				Object o = rs.getObject(i);
+				if (o == null) { s = "NULL"; }
+				else if (o instanceof ResultSet && nestedResults != null)
+				{
+					s = LocalizedResource.getMessage("UT_Resul0_20", LocalizedResource.getNumber(nestedResults.size()));
+					nestedResults.addElement(o);
+				}
+				else
+				{
+					try {
+						s = rs.getString(i);
+					} catch (SQLException se) {
+						// oops, they don't support refetching the column
+						s = o.toString();
+					}
+				}
+			}
+			break;
+			}
+			if (s==null) s = "NULL";
+
+			int w = Math.min(maxWidth,
+				Math.max((rsmd.isNullable(i) == 
+							ResultSetMetaData.columnNoNulls)?
+							0 : MINWIDTH, LocalizedResource.getInstance().getColumnDisplaySize(rsmd, i)));
+			if (s.length() < w) {
+				StringBuffer fullS = new StringBuffer(s);
+				fullS.ensureCapacity(w);
+				for (int k=s.length(); k<w; k++)
+					fullS.append(' ');
+				s = fullS.toString();
+			}
+			else if (s.length() > w)
+				// add the & marker to know it got cut off
+				s = s.substring(0,w-1)+"&";
+
+			buf.append(s);
+		}
+		indentedPrintLine( out, indentLevel, buf);
+
+	} // DisplayRow
+
+	/**
+		Check if an object is null, and if it is, throw an exception
+		with an informative parameter about what was null.
+		The exception is a run-time exception that is internal to ij.
+
+		@param o the object to test
+		@param what the information to include in the error if it is null
+	 */
+	public static void checkNotNull(Object o, String what) {
+		if (o == null) {
+			throw ijException.objectWasNull(what);
+		}
+	} // checkNotNull
+
+	/**
+		Map the string to the value if it is null.
+
+		@param s the string to test for null
+		@param nullValue the value to use if s is null
+
+		@return if s is non-null, s; else nullValue.
+	 */
+	static public String mapNull(String s, String nullValue) {
+		if (s==null) return nullValue;
+		return s;
+	}
+
+	/**
+		If the property ij.exceptionTrace is true, display the stack
+		trace to the print stream. Otherwise, do nothing.
+
+		@param out the output stream to write to
+		@param e the exception to display
+	 */
+	static public void doTrace(PrintWriter out, Exception e) {
+		if (Boolean.getBoolean("ij.exceptionTrace")) {
+			e.printStackTrace(out);
+		    out.flush();
+		}
+	}
+
+	static public void setMaxDisplayWidth(int maxDisplayWidth) {
+		maxWidth = maxDisplayWidth;
+	}
+
+	static	private	void	indentedPrintLine( PrintWriter out, int indentLevel, String text )
+	{
+		indent( out, indentLevel );
+		out.println( text );
+	}
+
+	static	private	void	indentedPrintLine( PrintWriter out, int indentLevel, StringBuffer text )
+	{
+		indent( out, indentLevel );
+		out.println( text );
+	}
+
+	static	private	void	indent( PrintWriter out, int indentLevel )
+	{
+		for ( int ictr = 0; ictr < indentLevel; ictr++ ) { out.print( "  " ); }
+	}
+
+	// ================
+
+	static public void ShowException(PrintStream out, Throwable e) {
+		if (e == null) return;
+
+		if (e instanceof SQLException)
+			ShowSQLException(out, (SQLException)e);
+		else
+			e.printStackTrace(out);
+	}
+
+	static public void ShowSQLException(PrintStream out, SQLException e) {
+		String errorCode;
+
+		if (Boolean.getBoolean("ij.showErrorCode")) {
+			errorCode = " (errorCode = " + e.getErrorCode() + ")";
+		}
+		else {
+			errorCode = "";
+		}
+
+		while (e!=null) {
+			out.println("ERROR "+mapNull(e.getSQLState(),"(no SQLState)")+": "+
+				 mapNull(e.getMessage(),"(no message)")+errorCode);
+			doTrace(out, e);
+			e=e.getNextException();
+		}
+	}
+
+	static public void ShowWarnings(PrintStream out, Connection theConnection) {
+	    try {
+		// GET CONNECTION WARNINGS
+		SQLWarning warning = null;
+
+		if (theConnection != null) {
+			ShowWarnings(out, theConnection.getWarnings());
+		}
+
+		if (theConnection != null) {
+			theConnection.clearWarnings();
+		}
+	    } catch (SQLException e) {
+			ShowSQLException(out, e);
+	    }
+	} // ShowWarnings
+
+	static public void ShowWarnings(PrintStream out, SQLWarning warning) {
+		while (warning != null) {
+			out.println("WARNING "+
+				mapNull(warning.getSQLState(),"(no SQLState)")+": "+
+				mapNull(warning.getMessage(),"(no message)"));
+			warning = warning.getNextWarning();
+		}
+	}
+
+	static public void ShowWarnings(PrintStream out, ResultSet rs) {
+	    try {
+		// GET RESULTSET WARNINGS
+		SQLWarning warning = null;
+
+		if (rs != null) {
+			ShowWarnings(out, rs.getWarnings());
+		}
+
+		if (rs != null) {
+			rs.clearWarnings();
+		}
+	    } catch (SQLException e) {
+			ShowSQLException(out, e);
+	    }
+	} // ShowResultSetWarnings
+
+	static public void ShowWarnings(PrintStream out, Statement s)
+	{
+	    try {
+		// GET STATEMENT WARNINGS
+		SQLWarning warning = null;
+
+		if (s != null) {
+			ShowWarnings(out, s.getWarnings());
+		}
+
+		if (s != null) {
+			s.clearWarnings();
+		}
+	    } catch (SQLException e) {
+			ShowSQLException(out, e);
+	    }
+	} // ShowStatementWarnings
+
+	static public void DisplayResults(PrintStream out, Statement stmt, Connection conn )
+		throws SQLException
+	{
+		indent_DisplayResults( out, stmt, conn, 0);			
+	}
+
+	static private void indent_DisplayResults
+	(PrintStream out, Statement stmt, Connection conn, int indentLevel)
+		throws SQLException {
+
+		checkNotNull(stmt, "Statement");
+
+		ResultSet rs = stmt.getResultSet();
+		if (rs != null) {
+			indent_DisplayResults(out, rs, conn, indentLevel);
+			rs.close(); // let the result set go away
+		}
+		else {
+			DisplayUpdateCount(out,stmt.getUpdateCount(), indentLevel);
+		}
+
+		ShowWarnings(out,stmt);
+	} // DisplayResults
+
+	static void DisplayUpdateCount(PrintStream out, int count, int indentLevel ) {
+		if (count == 1) {
+			indentedPrintLine( out, indentLevel, "1 row inserted/updated/deleted");
+		}
+		else if (count >= 0) {
+			indentedPrintLine( out, indentLevel, count+" rows inserted/updated/deleted");
+		}
+		else {
+			indentedPrintLine( out, indentLevel, "Statement executed.");
+		}
+	}
+
+	static public void DisplayResults(PrintStream out, ResultSet rs, Connection conn)
+		throws SQLException
+	{
+		indent_DisplayResults( out, rs, conn, 0);
+	}
+
+	static private void indent_DisplayResults
+	(PrintStream out, ResultSet rs, Connection conn, int indentLevel)
+		throws SQLException {
+		ResultSetMetaData rsmd = rs.getMetaData();
+		checkNotNull(rsmd, "ResultSetMetaData");
+		Vector nestedResults;
+    int numberOfRowsSelected = 0;
+
+		// autocommit must be off or the nested cursors
+		// are closed when the outer statement completes.
+		if (!conn.getAutoCommit())
+			nestedResults = new Vector();
+		else
+			nestedResults = null;
+
+		int len = indent_DisplayBanner(out,rsmd, indentLevel);
+
+		// When displaying rows, keep going past errors
+		// unless/until the maximum # of errors is reached.
+		boolean doNext = true;
+		int retry = 0;
+		while (doNext) {
+			try {
+				doNext = rs.next();
+				if (doNext) {
+
+		    		DisplayRow(out, rs, rsmd, len, nestedResults, conn, indentLevel);
+					ShowWarnings(out, rs);
+					numberOfRowsSelected++;
+				}
+			} catch (SQLException e) {
+				// REVISIT: might want to check the exception
+				// and for some, not bother with the retry.
+				if (++retry > MAX_RETRIES)
+					throw e;
+				else
+					ShowSQLException(out, e);
+			}
+		}
+		if (showSelectCount == true) {
+		   if (numberOfRowsSelected == 1) {
+			   out.println();
+			   indentedPrintLine( out, indentLevel, "1 row selected");
+		   } else if (numberOfRowsSelected >= 0) {
+			   out.println();
+		       indentedPrintLine( out, indentLevel, numberOfRowsSelected + " rows selected");
+		   }
+		}
+
+		DisplayNestedResults(out, nestedResults, conn, indentLevel );
+		nestedResults = null;
+	}
+
+	static private void DisplayNestedResults(PrintStream out, Vector nr, Connection conn, int indentLevel )
+		throws SQLException {
+
+		if (nr == null) return;
+
+		String s="+ ResultSet #";
+		String b="++++++++++++++++";
+		String oldString="0";
+
+		for (int i=0; i < nr.size(); i++) {
+			System.out.println();
+
+			//just too clever to get the extra +s
+			String t = Integer.toString(i);
+			if (t.length() > oldString.length()) {
+				oldString = t;
+				b=b+"+";
+			}
+
+			System.out.println(b);
+			System.out.println(s+i+" +");
+			System.out.println(b);
+			indent_DisplayResults(out, (ResultSet) nr.elementAt(i), conn, indentLevel);
+		}
+	}
+
+	static public void DisplayNextRow(PrintStream out, ResultSet rs, Connection conn )
+		throws SQLException
+	{
+		indent_DisplayNextRow( out, rs, conn, 0 );
+	}
+
+	static private void indent_DisplayNextRow(PrintStream out, ResultSet rs, Connection conn, int indentLevel )
+		throws SQLException {
+
+		Vector nestedResults;
+
+		// autocommit must be off or the nested cursors
+		// are closed when the outer statement completes.
+		if (!conn.getAutoCommit())
+			nestedResults = new Vector();
+		else
+			nestedResults = null;
+
+		checkNotNull(rs, "ResultSet");
+
+		ResultSetMetaData rsmd = rs.getMetaData();
+		checkNotNull(rsmd, "ResultSetMetaData");
+
+		// Only print stuff out if there is a row to be had.
+		if (rs.next()) {
+			int rowLen = indent_DisplayBanner(out, rsmd, indentLevel);
+    		DisplayRow(out, rs, rsmd, rowLen, nestedResults, conn, indentLevel );
+		}
+		else {
+			indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_NoCurreRow"));
+		}
+
+		ShowWarnings(out, rs);
+
+		DisplayNestedResults(out, nestedResults, conn, indentLevel );
+		nestedResults = null;
+
+	} // DisplayNextRow
+
+	static public void DisplayCurrentRow(PrintStream out, ResultSet rs, Connection conn )
+		throws SQLException
+	{
+		indent_DisplayCurrentRow( out, rs, conn, 0 );
+	}
+
+	static private void indent_DisplayCurrentRow(PrintStream out, ResultSet rs, Connection conn, int indentLevel )
+		throws SQLException {
+
+		Vector nestedResults;
+
+		if (rs == null) {
+			indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_NoCurreRow_19"));
+			return;
+		}
+
+		// autocommit must be off or the nested cursors
+		// are closed when the outer statement completes.
+		if (!conn.getAutoCommit())
+			nestedResults = new Vector();
+		else
+			nestedResults = null;
+
+		ResultSetMetaData rsmd = rs.getMetaData();
+		checkNotNull(rsmd, "ResultSetMetaData");
+
+		int rowLen = indent_DisplayBanner(out, rsmd, indentLevel);
+   		DisplayRow(out, rs, rsmd, rowLen, nestedResults, conn, indentLevel );
+
+		ShowWarnings(out, rs);
+
+		DisplayNestedResults(out, nestedResults, conn, indentLevel );
+		nestedResults = null;
+
+	} // DisplayNextRow
+
+	static public int DisplayBanner(PrintStream out, ResultSetMetaData rsmd )
+		throws SQLException
+	{
+		return indent_DisplayBanner( out, rsmd, 0 );
+	}
+
+	static private int indent_DisplayBanner(PrintStream out, ResultSetMetaData rsmd, int indentLevel )
+		throws SQLException	{
+
+		StringBuffer buf = new StringBuffer();
+
+		int numCols = rsmd.getColumnCount();
+		int rowLen;
+
+		// do some precalculation so the buffer is allocated only once
+		// buffer is twice as long as the display length plus one for a newline
+		rowLen = (numCols - 1); // for the column separators
+		for (int i=1; i <= numCols; i++) {
+			rowLen += Math.min(maxWidth,
+				Math.max((rsmd.isNullable(i) == 
+							ResultSetMetaData.columnNoNulls)?
+							0 : MINWIDTH,
+						rsmd.getColumnDisplaySize(i)));
+		}
+		buf.ensureCapacity(rowLen);
+
+		// get column header info
+		// truncate it to the column display width
+		// add a bar between each item.
+		for (int i=1; i <= numCols; i++) {
+
+			if (i>1)
+				buf.append('|');
+
+			String s = rsmd.getColumnLabel(i);
+
+			int w = Math.min(maxWidth,
+				Math.max(((rsmd.isNullable(i) == 
+							ResultSetMetaData.columnNoNulls)?
+							0 : MINWIDTH),
+						rsmd.getColumnDisplaySize(i)));
+
+			if (s.length() < w) {
+				// build a string buffer to hold the whitespace
+				StringBuffer blanks = new StringBuffer(s);
+				blanks.ensureCapacity(w);
+
+				// try to paste on big chunks of space at a time.
+				for (int k=blanks.length()+64; k<=w; k+=64)
+					blanks.append(
+          "                                                                ");
+				for (int k=blanks.length()+16; k<=w; k+=16)
+					blanks.append("                ");
+				for (int k=blanks.length()+4; k<=w; k+=4)
+					blanks.append("    ");
+				for (int k=blanks.length(); k<w; k++)
+					blanks.append(' ');
+
+				buf.append(blanks);
+				// REMIND: could do more cleverness, like keep around
+				// past buffers to reuse...
+			}
+			else if (s.length() > w)  {
+				if (w > 1) 
+					buf.append(s.substring(0,w-1));
+				if (w > 0) 
+					buf.append('&');
+			}
+			else {
+				buf.append(s);
+			}
+		}
+
+		buf.setLength(Math.min(rowLen, 1024));
+		indentedPrintLine( out, indentLevel, buf);
+
+		// now print a row of '-'s
+		for (int i=0; i<Math.min(rowLen, 1024); i++)
+			buf.setCharAt(i, '-');
+		indentedPrintLine( out, indentLevel, buf);
+
+		buf = null;
+
+		return rowLen;
+	} // DisplayBanner
+
+	static private void DisplayRow(PrintStream out, ResultSet rs, ResultSetMetaData rsmd, int rowLen, Vector nestedResults, Connection conn, int indentLevel )
+		throws SQLException
+	{
+		StringBuffer buf = new StringBuffer();
+		buf.ensureCapacity(rowLen);
+
+		int numCols = rsmd.getColumnCount();
+		int i;
+
+		// get column header info
+		// truncate it to the column display width
+		// add a bar between each item.
+		for (i=1; i <= numCols; i++){
+			if (i>1)
+				buf.append('|');
+
+			String s;
+			switch (rsmd.getColumnType(i)) {
+			default:
+				s = rs.getString(i);
+				break;
+			case org.apache.derby.iapi.reference.JDBC20Translation.SQL_TYPES_JAVA_OBJECT:
+			case Types.OTHER:
+			{
+				Object o = rs.getObject(i);
+				if (o == null) { s = "NULL"; }
+				else if (o instanceof ResultSet && nestedResults != null)
+				{
+					s = "ResultSet #"+nestedResults.size();
+					nestedResults.addElement(o);
+				}
+				else
+				{
+					try {
+						s = rs.getString(i);
+					} catch (SQLException se) {
+						// oops, they don't support refetching the column
+						s = o.toString();
+					}
+				}
+			}
+			break;
+			}
+
+			if (s==null) s = "NULL";
+
+			int w = Math.min(maxWidth,
+				Math.max((rsmd.isNullable(i) == 
+							ResultSetMetaData.columnNoNulls)?
+							0 : MINWIDTH,
+						rsmd.getColumnDisplaySize(i)));
+			if (s.length() < w) {
+				StringBuffer fullS = new StringBuffer(s);
+				fullS.ensureCapacity(w);
+				for (int k=s.length(); k<w; k++)
+					fullS.append(' ');
+				s = fullS.toString();
+			}
+			else if (s.length() > w)
+				// add the & marker to know it got cut off
+				s = s.substring(0,w-1)+"&";
+
+			buf.append(s);
+		}
+		indentedPrintLine( out, indentLevel, buf);
+
+	} // DisplayRow
+
+	static public void doTrace(PrintStream out, Exception e) {
+		if (Boolean.getBoolean("ij.exceptionTrace")) {
+			e.printStackTrace(out);
+		    out.flush();
+		}
+	}
+
+	static	private	void	indentedPrintLine( PrintStream out, int indentLevel, String text )
+	{
+		indent( out, indentLevel );
+		out.println( text );
+	}
+
+	static	private	void	indentedPrintLine( PrintStream out, int indentLevel, StringBuffer text )
+	{
+		indent( out, indentLevel );
+		out.println( text );
+	}
+
+	static	private	void	indent( PrintStream out, int indentLevel )
+	{
+		for ( int ictr = 0; ictr < indentLevel; ictr++ ) { out.print( "  " ); }
+	}
+	
+	// ==========================
+}
+
+
+

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/tools/URLCheck.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/tools/URLCheck.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/tools/URLCheck.java	Fri Sep 24 10:33:20 2004
@@ -1,174 +1,174 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.tools
-   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.tools;
-
-import org.apache.derby.iapi.reference.Attribute;
-import org.apache.derby.iapi.tools.i18n.LocalizedResource;
-import org.apache.derby.impl.tools.ij.AttributeHolder;
-import java.util.Vector;
-import java.util.Properties;
-import java.util.Enumeration;
-import java.util.StringTokenizer;
-import java.lang.reflect.Field;
-import java.sql.SQLException;
-
-/**
- * This class takes a string used for a connection URL and checks for
- * correctness.
- * To turn off output in ij, use the command line
- * property of -DURLCheck=false.
- *
- * param anURL	 The URL used to connect to a database.
- *
- */
-
-public class URLCheck {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
-
-  public Vector attributes;
-  public static Vector booleanAttributes;
-  //Need so that AppUI class does not get garbage collected
-  LocalizedResource langUtil = LocalizedResource.getInstance();
-  Vector validProps;
-
-  public URLCheck(String anURL) {
-
-    try {
-      //Initialize the AppUI class
-
-      //Parse the URL string into properties.
-      Properties props = getAttributes(anURL, new Properties());
-      check();
-    }
-    catch (Exception ex) {
-      ex.printStackTrace();
-    }
-  }
- 
-
-  public static void main(String[] args) {
-    if (args.length > 0) {
-      //Get the first argument passed in.
-      URLCheck aCheck = new URLCheck(args[0]);
-    }
-  }
-  public void check(){
-    Enumeration enum = attributes.elements();
-    while (enum.hasMoreElements()) {
-      AttributeHolder anAttribute = (AttributeHolder)enum.nextElement();
-      //The check for duplicate must be done at the URLCheck level
-      //and not by each specific attribute.  Only URLCheck knowns about
-      //all of the attributes and names.
-      checkForDuplicate(anAttribute);
-      //Have each attribute check as much about themself as possible.
-      anAttribute.check( validProps);
-    }
-  }
-  public void checkForDuplicate(AttributeHolder anAttribute){
-    Enumeration enum = attributes.elements();
-    while (enum.hasMoreElements()) {
-      AttributeHolder aHolder = (AttributeHolder)enum.nextElement();
-      //If a duplicate is found, make sure that the message is only shown
-      //once for each attribute.
-      if (anAttribute != aHolder && anAttribute.getName().equals(aHolder.getName())) {
-        anAttribute.addError(langUtil.getTextMessage("TL_dupAtt"));
-      }
-    }
-
-  }
-	public Properties getAttributes(String url, Properties props) throws Exception {
-		
-		String protocol = "";
-
-        if( url.startsWith( "jdbc:derby:net:"))
-		{
-            validProps = null;
-		}
-        else if( url.startsWith( "jdbc:derby:"))
-		{
-			protocol = "jdbc:derby:";
-            validProps = getValidCloudscapeProps();
-		}
-        else
-            validProps = null;
-
-		
-		//Parse the url into attributes and put them in a Properties object.
-		StringTokenizer st = new StringTokenizer(url.substring(protocol.length()), ";:\"");
-		attributes = new Vector();
-		while (st.hasMoreTokens()) {
-      AttributeHolder anAttribute = new AttributeHolder();
-      String anAtt = "";
-      String aValue = "";
-	  String aToken = st.nextToken();
-      //The "=" is the seperator between key and value.
-	  int eqPos = aToken.indexOf('=');
-	  if (eqPos == -1) {
-		  //If there is no "=" this is not an attribute
-		  continue;
-      }
-      else {
-        anAtt = (aToken.substring(0, eqPos)).trim();
-        aValue = (aToken.substring(eqPos + 1)).trim();
-
-      }
-      anAttribute.setName(anAtt);
-      anAttribute.setValue(aValue);
-      anAttribute.setToken(aToken);
-      attributes.addElement(anAttribute);
-      props.put(anAtt, aToken);
-	}
-		return props;
-	}
-
-  public static Vector getBooleanAttributes(){
-    if (booleanAttributes == null) {
-      booleanAttributes = new Vector();
-		  booleanAttributes.addElement(Attribute.DATA_ENCRYPTION);
-		  booleanAttributes.addElement(Attribute.CREATE_ATTR);
-		  booleanAttributes.addElement(Attribute.SHUTDOWN_ATTR);
-		  booleanAttributes.addElement(Attribute.UPGRADE_ATTR);
-    }
-    return booleanAttributes;
-  }
-
-    private static Vector validCloudscapeProps;
-    private Vector getValidCloudscapeProps()
-    {
-        if( validCloudscapeProps == null)
-        {
-            try
-            {
-                Vector props = new Vector();
-                Class att = Attribute.class;
-                //Use reflection to get the list of valid keys from the Attribute class.
-                //The Attribute class is an interface and therefore all the field
-                //for it are public.
-                Field[] fields = att.getFields();
-                for (int i = 0; i < fields.length; i++)
-                {
-                    Field aField = (Field)fields[i];
-                    props.addElement(aField.get(att));
-                }
-                validCloudscapeProps = props;
-            }
-            catch (Exception ex)
-            {
-                ex.printStackTrace();
-            }
-        }
-        return validCloudscapeProps;
-    } // end of getValidCloudscapeProps
-
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.tools
+   (C) Copyright IBM Corp. 2000, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.tools;
+
+import org.apache.derby.iapi.reference.Attribute;
+import org.apache.derby.iapi.tools.i18n.LocalizedResource;
+import org.apache.derby.impl.tools.ij.AttributeHolder;
+import java.util.Vector;
+import java.util.Properties;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.lang.reflect.Field;
+import java.sql.SQLException;
+
+/**
+ * This class takes a string used for a connection URL and checks for
+ * correctness.
+ * To turn off output in ij, use the command line
+ * property of -DURLCheck=false.
+ *
+ * param anURL	 The URL used to connect to a database.
+ *
+ */
+
+public class URLCheck {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2000_2004;
+
+  public Vector attributes;
+  public static Vector booleanAttributes;
+  //Need so that AppUI class does not get garbage collected
+  LocalizedResource langUtil = LocalizedResource.getInstance();
+  Vector validProps;
+
+  public URLCheck(String anURL) {
+
+    try {
+      //Initialize the AppUI class
+
+      //Parse the URL string into properties.
+      Properties props = getAttributes(anURL, new Properties());
+      check();
+    }
+    catch (Exception ex) {
+      ex.printStackTrace();
+    }
+  }
+ 
+
+  public static void main(String[] args) {
+    if (args.length > 0) {
+      //Get the first argument passed in.
+      URLCheck aCheck = new URLCheck(args[0]);
+    }
+  }
+  public void check(){
+    Enumeration enum = attributes.elements();
+    while (enum.hasMoreElements()) {
+      AttributeHolder anAttribute = (AttributeHolder)enum.nextElement();
+      //The check for duplicate must be done at the URLCheck level
+      //and not by each specific attribute.  Only URLCheck knowns about
+      //all of the attributes and names.
+      checkForDuplicate(anAttribute);
+      //Have each attribute check as much about themself as possible.
+      anAttribute.check( validProps);
+    }
+  }
+  public void checkForDuplicate(AttributeHolder anAttribute){
+    Enumeration enum = attributes.elements();
+    while (enum.hasMoreElements()) {
+      AttributeHolder aHolder = (AttributeHolder)enum.nextElement();
+      //If a duplicate is found, make sure that the message is only shown
+      //once for each attribute.
+      if (anAttribute != aHolder && anAttribute.getName().equals(aHolder.getName())) {
+        anAttribute.addError(langUtil.getTextMessage("TL_dupAtt"));
+      }
+    }
+
+  }
+	public Properties getAttributes(String url, Properties props) throws Exception {
+		
+		String protocol = "";
+
+        if( url.startsWith( "jdbc:derby:net:"))
+		{
+            validProps = null;
+		}
+        else if( url.startsWith( "jdbc:derby:"))
+		{
+			protocol = "jdbc:derby:";
+            validProps = getValidCloudscapeProps();
+		}
+        else
+            validProps = null;
+
+		
+		//Parse the url into attributes and put them in a Properties object.
+		StringTokenizer st = new StringTokenizer(url.substring(protocol.length()), ";:\"");
+		attributes = new Vector();
+		while (st.hasMoreTokens()) {
+      AttributeHolder anAttribute = new AttributeHolder();
+      String anAtt = "";
+      String aValue = "";
+	  String aToken = st.nextToken();
+      //The "=" is the seperator between key and value.
+	  int eqPos = aToken.indexOf('=');
+	  if (eqPos == -1) {
+		  //If there is no "=" this is not an attribute
+		  continue;
+      }
+      else {
+        anAtt = (aToken.substring(0, eqPos)).trim();
+        aValue = (aToken.substring(eqPos + 1)).trim();
+
+      }
+      anAttribute.setName(anAtt);
+      anAttribute.setValue(aValue);
+      anAttribute.setToken(aToken);
+      attributes.addElement(anAttribute);
+      props.put(anAtt, aToken);
+	}
+		return props;
+	}
+
+  public static Vector getBooleanAttributes(){
+    if (booleanAttributes == null) {
+      booleanAttributes = new Vector();
+		  booleanAttributes.addElement(Attribute.DATA_ENCRYPTION);
+		  booleanAttributes.addElement(Attribute.CREATE_ATTR);
+		  booleanAttributes.addElement(Attribute.SHUTDOWN_ATTR);
+		  booleanAttributes.addElement(Attribute.UPGRADE_ATTR);
+    }
+    return booleanAttributes;
+  }
+
+    private static Vector validCloudscapeProps;
+    private Vector getValidCloudscapeProps()
+    {
+        if( validCloudscapeProps == null)
+        {
+            try
+            {
+                Vector props = new Vector();
+                Class att = Attribute.class;
+                //Use reflection to get the list of valid keys from the Attribute class.
+                //The Attribute class is an interface and therefore all the field
+                //for it are public.
+                Field[] fields = att.getFields();
+                for (int i = 0; i < fields.length; i++)
+                {
+                    Field aField = (Field)fields[i];
+                    props.addElement(aField.get(att));
+                }
+                validCloudscapeProps = props;
+            }
+            catch (Exception ex)
+            {
+                ex.printStackTrace();
+            }
+        }
+        return validCloudscapeProps;
+    } // end of getValidCloudscapeProps
+
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/tools/dblook.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/tools/dblook.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/tools/dblook.java	Fri Sep 24 10:33:20 2004
@@ -1,1128 +1,1128 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.tools
-   (C) Copyright IBM Corp. 2003, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.tools;
-
-import java.io.BufferedReader;
-import java.io.StringReader;
-
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.Connection;
-import java.sql.Statement;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Timestamp;
-
-import java.util.HashMap;
-import java.util.StringTokenizer;
-import java.util.ArrayList;
-
-import org.apache.derby.iapi.tools.i18n.LocalizedResource;
-
-import org.apache.derby.impl.tools.cslook.DB_Check;
-import org.apache.derby.impl.tools.cslook.DB_Index;
-import org.apache.derby.impl.tools.cslook.DB_Jar;
-import org.apache.derby.impl.tools.cslook.DB_Key;
-import org.apache.derby.impl.tools.cslook.DB_Table;
-import org.apache.derby.impl.tools.cslook.DB_Schema;
-import org.apache.derby.impl.tools.cslook.DB_StoredProcedure;
-import org.apache.derby.impl.tools.cslook.DB_Trigger;
-import org.apache.derby.impl.tools.cslook.DB_View;
-import org.apache.derby.impl.tools.cslook.Logs;
-
-public class dblook {
-
-	/* 
-		IBM Copyright &copy notice.
-	*/
-	/**
-		IBM Copyright &copy notice.
-	*/
-
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2003_2004;
-
-	// DB2 enforces a maximum of 30 tables to be specified as part of
-	// the table list.
-	public static final int DB2_MAX_NUMBER_OF_TABLES = 30;
-
-	private Connection conn;
-	private static PreparedStatement getColNameFromNumberQuery;
-
-	// Mappings from id to name for schemas and tables (for ease
-	// of reference).
-	protected static HashMap schemaMap;
-	protected static HashMap tableIdToNameMap;
-
-	// Command-line Parameters.
-	protected static String sourceDBUrl;
-	protected static String ddlFileName;
-	protected static String stmtDelimiter;
-	protected static boolean appendLogs;
-	protected static ArrayList tableList;
-	protected static String schemaParam;
-	protected static String targetSchema;
-	protected static boolean skipViews;
-	protected static boolean verbose;
-	private static String sourceDBName;
-
-	private static String lookLogName = "dblook.log";
-
-	private final static String DEFAULT_LOCALE= "en";
-	private final static String DEFAULT_LOCALE_COUNTRY="US";
-	private static LocalizedResource langUtil;
-
-	/* ************************************************
-	 * main:
-	 * Initialize program state by creating a dblook object,
-	 * and then start the DDL generation by calling "go".
-	 * ****/
-
-	public static void main(String[] args) {
-
-		dblook looker = new dblook(args);
-		try {
-			looker.go(sourceDBUrl, sourceDBName);
-		} catch (Exception e) {
-		// Errors are logged and printed to console according
-		// to command line arguments, so just ignore here.
-		}
-
-	}
-
-	/* ************************************************
-	 * Constructor:
-	 * Parse the command line, initialize logs, echo program variables,
-	 * and load the Cloudscape driver.
-	 * @param args args[0] is the database URL.  All other command-line
-	 *  parameters are read as system properties.
-	 * ****/
-
-	public dblook(String[] args) {
-
-        // Adjust the application in accordance with derby.ui.locale
-		// and derby.ui.codeset
-		langUtil = LocalizedResource.getInstance();
-
-		// Initialize class variables.
-		initState();
-
-		// Parse the command line.
-		if (!parseArgs(args)) {
-			System.out.println(lookupMessage("CSLOOK_Usage"));
-			System.exit(1);
-		}
-
-		showVariables();
-
-		if (!loadDriver()) {
-		// Failed when loading the driver.  We already printed
-		// the exception, so just return.
-			return;
-		}
-
-		schemaMap = new HashMap();
-		tableIdToNameMap = new HashMap();
-
-	}
-
-	/* ************************************************
-	 * initState:
-	 * Initialize class variables.
-	 ****/
-
-	private void initState() {
-
-		sourceDBUrl = null;
-		ddlFileName = null;
-		stmtDelimiter = null;
-		appendLogs = false;
-		tableList = null;
-		targetSchema = null;
-		schemaParam = null;
-		skipViews = false;
-		verbose= false;
-		sourceDBName = null;
-		return;
-
-	}
-
-	/* ************************************************
-	 * parseArgs:
-	 * Parse the command-line arguments.  There is only one
-	 * actual argument (database url); the rest of the parameters
-	 * are read in as System properties.
-	 * @param args args[0] is the url for the source database.
-	 * @return true if all parameters were loaded and the output
-	 *  files were successfully created; false otherwise.
-	 ****/
-
-	private boolean parseArgs(String[] args) {
-
-		if (args.length < 2)
-		// must have minimum of 2 args: "-d" and "<dbUrl>".
-			return false;
-
-		int st = 0;
-		for (int i = 0; i < args.length; i++) {
-			st = loadParam(args, i);
-			if (st == -1)
-				return false;
-			i = st;
-		}
-
-		if (sourceDBUrl == null) {
-		// must have at least a database url.
-			return false;	
-		}
-
-		// At this point, all parameters should have been read into
-		// their respective class variables.  Use those
-		// variables for some further processing.
-
-		// Setup logs.
-		boolean okay = Logs.initLogs(lookLogName, ddlFileName, appendLogs,
-		 	verbose, (stmtDelimiter == null ? ";" : stmtDelimiter));
-
-		// Get database name.
-		sourceDBName = extractDBNameFromUrl(sourceDBUrl);
-
-		// Set up schema restriction.
-		if ((schemaParam != null) && (schemaParam.length() > 0) &&
-			(schemaParam.charAt(0) != '"'))
-		// not quoted, so upper case, then add quotes.
-		{
-			targetSchema = addQuotes(expandDoubleQuotes(
-				schemaParam.toUpperCase(java.util.Locale.ENGLISH)));
-		}
-		else
-			targetSchema = addQuotes(expandDoubleQuotes(stripQuotes(schemaParam)));
-		return okay;
-
-	}
-
-	/* ************************************************
-	 * loadParam:
-	 * Read in a flag and its corresponding values from
-	 * list of command line arguments, starting at
-	 * the start'th argument.
-	 * @return The position of the argument that was
-	 *  most recently processed.
-	 ****/
-
-	private int loadParam(String [] args, int start) {
-
-		if ((args[start].length() == 0) || args[start].charAt(0) != '-')
-		// starting argument should be a flag; if it's
-		// not, ignore it.
-			return start;
-
-		boolean haveVal = (args.length > start + 1);
-		switch (args[start].charAt(1)) {
-
-			case 'd':
-				if (!haveVal)
-					return -1;
-				if (args[start].length() == 2)
-					sourceDBUrl = args[++start];
-				return start;
-
-			case 'z':
-				if (!haveVal)
-					return -1;
-				if (args[start].length() == 2)
-					schemaParam = args[++start];
-				return start;
-
-			case 't':
-				if (!haveVal)
-					return -1;
-				if (args[start].equals("-td")) {
-					stmtDelimiter = args[++start];
-					return start;
-				}
-				else if (args[start].equals("-t"))
-				// list of tables.
-					return extractTableNamesFromList(args, start+1);
-				return -1;
-			case 'o':
-				if (!haveVal)
-					return -1;
-				if ((args[start].length() == 2) && (args[start+1].length() > 0))
-					ddlFileName = args[++start];
-				return start;
-
-			case 'a':
-				if (args[start].equals("-append")) {
-					appendLogs = true;
-					return start;
-				}
-				return -1;
-
-			case 'n':
-				if (args[start].equals("-noview")) {
-					skipViews = true;
-					return start;
-				}
-				return -1;
-
-			case 'v':
-				if (args[start].equals("-verbose")) {
-					verbose = true;
-					return start;
-				}
-				return -1;
-
-			default:
-				return -1;
-
-		}
-
-	}
-
-	/* ************************************************
-	 * loadDriver:
-	 * Load db2j driver.
-	 * @param precondition sourceDBUrl has been loaded.
-	 * @return false if anything goes wrong; true otherwise.
-	 ****/
-
-	private boolean loadDriver() {
-
-		String db2jDriver;
-		if (sourceDBUrl.indexOf(":net://") != -1)
-			db2jDriver = "com.ibm.db2.jcc.DB2Driver";
-		else
-			db2jDriver = "org.apache.derby.jdbc.EmbeddedDriver";
-		try {
-			Class.forName(db2jDriver).newInstance();
-		} catch (Exception e)
-		{
-			Logs.debug(e);
-			return false;
-		}
-
-		return true;
-
-	}
-
-	/* ************************************************
-	 * extractDBNameFromUrl:
-	 * Given a database url, parse out the actual name
-	 * of the database.  This is required for creation
-	 * the DB2JJARS directory (the database name is part
-	 * of the path to the jar).
-	 * @param dbUrl The database url from which to extract the
-	 *  the database name.
-	 * @return the name of the database (including its
-	 *  path, if provided) that is referenced by the url.
-	 ****/
-
-	protected String extractDBNameFromUrl(String dbUrl) {
-
-		if (dbUrl == null)
-		// shouldn't happen; ignore it here, as an error
-		// will be thrown we try to connect.
-			return "";
-
-		int start = dbUrl.indexOf("jdbc:derby:");
-		if (start == -1)
-		// not a valid url; just ignore it (an error
-		// will be thrown when we try to connect).
-			return "";
-
-		start = dbUrl.indexOf("net://");
-		if (start == -1)
-		// standard url (jdbc:derby:<dbname>).  Database
-		// name starts right after "cloudscape:".  The "11" in
-		// the following line is the length of "cloudscape:".
-			start = dbUrl.indexOf("cloudscape:") + 11;
-		else
-		// Network Server url.  Database name starts right
-		// after next slash (":net://hostname:port/<dbname>).
-		// The "6" in the following line is the length of
-		// "net://".
-			start = dbUrl.indexOf("/", start+6) + 1;
-
-		int stop = -1;
-		if (dbUrl.charAt(start) == '"') {
-		// database name is quoted; end of the name is the
-		// closing quote.
-			start++;
-			stop = dbUrl.indexOf("\"", start);
-		}
-		else {
-		// Database name ends with the start of a list of connection	
-		// attributes.  This list can begin with either a colon
-		// or a semi-colon.
-			stop = dbUrl.indexOf(":", start);
-			if (stop != -1) {
-				if ((dbUrl.charAt(stop+1) == '/') ||
-						(dbUrl.charAt(stop+1) == '\\'))
-				// then this colon is part of the path (ex. "C:"),
-				// so ignore it.
-					stop = dbUrl.indexOf(":", stop+2);
-			}
-			int stop2 = dbUrl.length();
-			if (stop == -1)
-			// no colons; see if we can find a semi-colon.
-				stop = dbUrl.indexOf(";", start);
-			else
-				stop2 = dbUrl.indexOf(";", start);
-			stop = (stop <= stop2 ? stop : stop2);
-		}
-
-		if (stop == -1)
-		// we have a url that ends with database name (no
-		// other attributes appended).
-			stop = dbUrl.length();
-
-		return dbUrl.substring(start, stop);
-
-	}
-
-	/* ************************************************
-	 * extractTableNamesFromList:
-	 * Given an array of command line arguments containing
-	 * a list of table names beginning at start'th position,
-	 * read the list of table names and store them as
-	 * our target table list.  Names without quotes are
-	 * turned into ALL CAPS and then double quotes are
-	 * added; names whcih already have double quotes are
-	 * stored exactly as they are. NOTE: DB2 enforces
-	 * maximum of 30 tables, and ignores the rest; so
-	 * do we.
-	 * @param args Array of command line arguments.
-	 * @start Position of the start of the list of tables
-	 *  with the args array.
-	 * @return The position of the last table name in
-	 *  the list of table names.
-	 ****/
-
-	private int extractTableNamesFromList(String [] args,
-		int start)
-	{
-
-		int argIndex = start;
-		int count = 0;
-		tableList = new ArrayList();
-		while (argIndex < args.length) {
-
-			if (((args[argIndex].length() > 0) && (args[argIndex].charAt(0) == '-')) ||
-				(++count > DB2_MAX_NUMBER_OF_TABLES))
-			// we're done with the table list.
-				break;
-
-			if ((args[argIndex].length() > 0) && (args[argIndex].charAt(0) == '"'))
-			// it's quoted.
-				tableList.add(addQuotes(expandDoubleQuotes(
-					stripQuotes(args[argIndex++]))));
-			else
-			// not quoted, so make it all caps, then add
-			// quotes.
-				tableList.add(addQuotes(
-					expandDoubleQuotes(args[argIndex++].toUpperCase(
-					java.util.Locale.ENGLISH))));
-
-		}
-
-		if (tableList.size() == 0)
-			tableList = null;
-
-		return argIndex - 1;
-
-	}
-
-	/* ************************************************
-	 * showVariables:
-	 * Echo primary variables to output, so user can see
-	 * what s/he specified.
-	 ****/
-
-	private void showVariables() {
-
-		if (ddlFileName != null) {
-			Logs.reportString("============================\n");
-			Logs.reportMessage("CSLOOK_FileCreation");
-			if (verbose)
-				writeVerboseOutput("CSLOOK_OutputLocation",
-					ddlFileName);
-		}
-
-		Logs.reportMessage("CSLOOK_Timestamp",
-			new Timestamp(System.currentTimeMillis()).toString());
-		Logs.reportMessage("CSLOOK_DBName", sourceDBName);
-		Logs.reportMessage("CSLOOK_DBUrl", sourceDBUrl);
-		if (tableList != null)
-			Logs.reportMessage("CSLOOK_TargetTables");
-		if (schemaParam != null)
-			Logs.reportMessage("CSLOOK_TargetSchema", stripQuotes(schemaParam));
-		Logs.reportString("appendLogs: " + appendLogs + "\n");
-		return;
-
-	}
-
-	/* ************************************************
-	 * go:
-	 * Connect to the source database, prepare statements,
-	 * and load a list of table id-to-name mappings.  Then,
-	 * generate the DDL for the various objects in the
-	 * database by making calls to static methods of helper
-	 * classes (one helper class for each type of database
-	 * object).  If a particular object type should not be
-	 * generated (because of the user-specified command-
-	 * line), then we enforce that here.
-	 * @precondition all user-specified parameters have
-	 *  been loaded.
-	 * @param srcUrl The full url of the database, as obtained
-	 *  from parseArgs().
-	 * @param srcName The name of the database (as opposed to
-	 *  the URL), as obtained from parseArgs().  This is
-	 *  needed for locating any jar files that might'
-	 *  exist in the source database.
-	 * @return DDL for the source database has been
-	 *  generated and printed to output, subject to
-	 *  user-specified restrictions.
-	 * ****/
-
-	public void go(String srcUrl, String srcName)
-		throws Exception
-	{
-
-		try
-		{
-
-			// Connect to the database, prepare statements,
-			// and load id-to-name mappings.
-			this.conn = DriverManager.getConnection(srcUrl);
-			try {
-				prepForDump();
-			} catch (SQLException sqlE) {
-				Logs.debug(sqlE);
-				Logs.debug(Logs.unRollExceptions(sqlE), (String)null);
-				Logs.cleanup();
-				return;
-			}
-			catch (Exception e) {
-				Logs.debug(e);
-				Logs.cleanup();
-				return;
-			}
-
-			// Generate DDL.
-
-			// Start with schemas, since we might need them to
-			// exist for jars to load properly.
-			DB_Schema.doSchemas(this.conn,
-				(tableList != null) && (targetSchema == null));
-
-			if (tableList == null) {
-			// Don't do these if user just wants table-related objects.
-				DB_Jar.doJars(srcName, this.conn);
-				DB_StoredProcedure.doStoredProcedures(this.conn);
-			}
-
-			DB_Table.doTables(this.conn, tableIdToNameMap);
-			DB_Index.doIndexes(this.conn);
-			DB_Key.doKeys(this.conn);
-			DB_Check.doChecks(this.conn);
-
-			if (!skipViews)
-				DB_View.doViews(this.conn);
-
-			DB_Trigger.doTriggers(this.conn);
-
-			// That's it; we're done.
-			if (getColNameFromNumberQuery != null)
-				getColNameFromNumberQuery.close();
-			Logs.cleanup();
-
-		}
-		catch (SQLException sqlE)
-		{
-			Logs.debug(sqlE);
-			Logs.debug(Logs.unRollExceptions(sqlE), (String)null);
-			Logs.cleanup();
-			throw sqlE;
-		}
-		catch (Exception e)
-		{
-			Logs.debug(e);
-			Logs.cleanup();
-			throw e;
-		}
-		finally {
-		// Close our connection.
-			conn.commit();
-			conn.close();
-		}
-
-	}
-
-	/* ************************************************
-	 * prepForDump:
-	 * Prepare any useful statements (i.e. statements that
-	 * are required by more than one helper class) and load
-	 * the id-to-name mappings for the source database.
-	 ****/
-
-	private void prepForDump() throws Exception {
-
-		// We're only SELECTing throughout all of this, so no need
-		// to commit (plus, disabling commit makes it easier to
-		// have multiple ResultSets open on the same connection).
-		this.conn.setAutoCommit(false);
-
-		// Prepare statements.
-		getColNameFromNumberQuery = conn.prepareStatement(
-			"SELECT COLUMNNAME FROM SYS.SYSCOLUMNS WHERE " +
-			"REFERENCEID = ? AND COLUMNNUMBER = ?");
-
-		// Load list of user tables and table ids, for general use.
-		Statement stmt = conn.createStatement();
-		ResultSet rs = stmt.executeQuery("SELECT T.TABLEID, T.TABLENAME, " +
-				"S.SCHEMANAME FROM SYS.SYSTABLES T, SYS.SYSSCHEMAS S " + 
-				"WHERE T.TABLETYPE = 'T' AND T.SCHEMAID = S.SCHEMAID");
-
-		while (rs.next()) {
-			String tableName = addQuotes(expandDoubleQuotes(rs.getString(2)));
-			String schemaName = addQuotes(expandDoubleQuotes(rs.getString(3)));
-			tableIdToNameMap.put(rs.getString(1), 
-				schemaName + "." + tableName);
-		}
-
-		// Load schema id's and names.
-		rs = stmt.executeQuery("SELECT SCHEMAID, SCHEMANAME FROM " +
-			"SYS.SYSSCHEMAS");
-		while (rs.next()) {
-			schemaMap.put(rs.getString(1),
-				addQuotes(expandDoubleQuotes(rs.getString(2))));
-		}
-
-		stmt.close();
-
-		// Load default property values.
-		return;
-
-	}
-
-	/* ************************************************
-	 * getColumnListFromDescription:
-	 * Takes string description of column numbers in the
-	 * form of "(2, 1, 3...)" and the id of the table
-	 * having those columns, and then returns a string
-	 * with the column numbers replaced by their actual
-	 * names ('2' is replaced with the 2nd column in the
-	 * table, '1' with the first column, etc.).
-	 * @param tableId the id of the table to which the column
-	 *   numbers should be applied.
-	 * @param description a string holding a list of column
-	 *  numbers, enclosed in parentheses and separated
-	 *  by commas.
-	 * @return a new string with the column numbers in
-	 *  'description' replaced by their column names;
-	 *  also, the parentheses have been stripped off.
-	 ****/
-
-	public static String getColumnListFromDescription(String tableId,
-		String description) throws SQLException
-	{
-
-		StringBuffer sb = new StringBuffer();
-		StringTokenizer tokenizer = new StringTokenizer(
-			description.substring(description.indexOf("(") + 1,
-				description.lastIndexOf(")")), " ,", true);
-
-		boolean firstCol = true;
-		while (tokenizer.hasMoreTokens()) {
-
-			String tok = tokenizer.nextToken().trim();
-			if (tok.equals(""))
-				continue;
-			else if (tok.equals(",")) {
-				firstCol = false;
-				continue;
-			}
-			try {
-				String colName = getColNameFromNumber(tableId,
-					(Integer.valueOf(tok)).intValue());
-				if (!firstCol)
-					sb.append(", ");
-				sb.append(colName);
-			} catch (NumberFormatException e) {
-			// not a number; could be "ASC" or "DESC" tag,
-			// which is okay; otherwise, something's wrong.
-				tok = tok.toUpperCase();
-				if (tok.equals("DESC") || tok.equals("ASC"))
-				// then this is okay; just add the token to result.
-					sb.append(" " + tok);
-				else
-				// shouldn't happen.
-					Logs.debug("INTERNAL ERROR: read a non-number (" +
-						tok + ") when a column number was expected:\n" +
-						description, (String)null);
-			}
-
-		}
-
-		return sb.toString();
-
-	}
-
-	/* ************************************************
-	 * getColNameFromNumber:
-	 * Takes a tableid and a column number colNum, and
-	 * returns the name of the colNum'th column in the
-	 * table with tableid.
-	 * @param tableid id of the table.
-	 * @param colNum number of the column for which we want
-	 *  the name.
-	 * @return The name of the colNum'th column in the
-	 *  table with tableid.
-	 ****/
-
-	public static String getColNameFromNumber(String tableId,
-		int colNum) throws SQLException
-	{
-
-		getColNameFromNumberQuery.setString(1, tableId);
-		getColNameFromNumberQuery.setInt(2, colNum);
-		ResultSet rs = getColNameFromNumberQuery.executeQuery();
-
-		if (!rs.next()) {
-		// shouldn't happen.
-			Logs.debug("INTERNAL ERROR: Failed column number " +
-				"lookup for table " + lookupTableId(tableId) +
-				", column " + colNum, (String)null);
-			rs.close();
-			return "";
-		}
-		else {
-			String colName = addQuotes(expandDoubleQuotes(rs.getString(1)));
-			rs.close();
-			return colName;
-		}
-
-	}
-
-	/* ************************************************
-	 * addQuotes:
-	 * Add quotes to the received object name, and return
-	 * the result.
-	 * @param name the name to which to add quotes.
-	 * @return the name with double quotes around it.
-	 ****/
-
-	public static String addQuotes(String name) {
-
-		if (name == null)
-			return null;
-
-		return "\"" + name + "\"";
-
-	}
-
-	/* ************************************************
-	 * stripQuotes:
-	 * Takes a name and, if the name is enclosed in
-	 * quotes, strips the quotes off.  This method
-	 * assumes that the received String either has no quotes,
-	 * or has a quote (double or single) as the very first
-	 * AND very last character.
-	 * @param quotedName a name with quotes as the first
-	 *  and last character, or else with no quotes at all.
-	 * @return quotedName, without the quotes.
-	 ****/
-
-	public static String stripQuotes(String quotedName) {
-
-		if (quotedName == null)
-			return null;
-
-		if ((quotedName.indexOf("\"") == -1) &&
-			(quotedName.indexOf("'") == -1))
-		// nothing to do.
-			return quotedName;
-
-		return quotedName.substring(1, quotedName.length() - 1);
-
-	}
-
-	/* ************************************************
-	 * isExcludedTable:
-	 * Takes a table name and determines whether or not
-	 * the DDL for objects related to that table should be
-	 * generated.
-	 * @param tableName name of the table to check.
-	 * @return true if 1) the user specified a table list
-	 *  and that list does NOT include the received name; or
-	 *  2) if the user specified a schema restriction and
-	 *  the received name does NOT have that schema; false
-	 *  otherwise.
-	 ****/
-
-	public static boolean isExcludedTable(String tableName) {
-
-		if (tableName == null)
-			return true;
-
-		int dot = tableName.indexOf(".");
-		if (dot != -1) {
-		// strip off the schema part of the name, and see if we're
-		// okay to use it.
-			if (isIgnorableSchema(tableName.substring(0, dot)))
-			// then we exclude this table.
-				return true;
-			tableName = tableName.substring(dot + 1,
-				tableName.length());
-		}
-
-		return ((tableList != null) && !tableList.contains(tableName));
-
-	}
-
-	/* ************************************************
-	 * Takes a schema name and determines whether or
-	 * not the DDL for objects with that schema should
-	 * be generated.
-	 * @param schemaName schema name to be checked.
-	 * @return true if 1) the user specified a target
-	 *  schema and that target is NOT the same as the
-	 *  received schema name, or 2) the schema is a
-	 *  system schema (SYS, SYSVISUAL, or SYSIBM);
-	 *  false otherwise;
-	 ****/
-
-    public static final String[] ignorableSchemaNames = {
-        "SYSIBM",
-        "SYS",
-        "SYSVISUAL",
-        "SYSCAT",
-        "SYSFUN",
-        "SYSPROC",
-        "SYSSTAT",
-        "NULLID",
-        "SYSCS_ADMIN",
-        "SYSCS_DIAG",
-        "SYSCS_UTIL",
-        "SQLJ"};
-
-	public static boolean isIgnorableSchema(String schemaName) {
-
-		if ((targetSchema != null) && (!schemaName.equals(targetSchema)))
-			return true;
-
-		schemaName = stripQuotes(schemaName);
-
-        boolean ret = false;
-
-        for (int i = ignorableSchemaNames.length - 1; i >= 0;)
-        {
-            if ((ret = ignorableSchemaNames[i--].equalsIgnoreCase(schemaName)))
-                break;
-        }
-
-        return(ret);
-	}
-
-	/* ************************************************
-	 * Takes a string and determines whether or not that
-	 * string makes reference to any of the table names
-	 * in the user-specified table list.
-	 * @param str The string in which to search for table names.
-	 * @return true if 1) the user didn't specify a
-	 *  target table list, or 2) the received string
-	 *  contains at least one of the table names in the
-	 *  user-specified target list; false otherwise.
-	 ****/
-
-	public static boolean stringContainsTargetTable(String str) {
-
-		if (str == null)
-		// if the string is null, it can't possibly contain
-		// any table names.
-			return false;
-
-		if (tableList == null)
-		// if we have no target tables, then default to true.
-			return true;
-
-		int strLen = str.length();
-		for (int i = 0; i < tableList.size(); i++) {
-
-			String tableName = (String)tableList.get(i);
-			tableName = expandDoubleQuotes(stripQuotes(tableName));
-			int nameLen = tableName.length();
-			String strCopy;
-			if (tableName.equals(tableName.toUpperCase(
-				java.util.Locale.ENGLISH)))
-			// case doesn't matter.
-				strCopy = str.toUpperCase();
-			else
-				strCopy = str;
-			int pos = strCopy.indexOf(tableName);
-			while (pos != -1) {
-
-				// If we found it, make sure it's really a match.
-				// First, see if it's part of another word.
-				if (!partOfWord(str, pos, nameLen, strLen)) {
-
-					// See if the match is in quotes--if so, then
-					// it should match the table name's case.
-					if ((pos >= 1) && (strCopy.charAt(pos-1) == '"') &&
-					  (pos + nameLen < strCopy.length()) &&
-					  (strCopy.charAt(pos+nameLen) == '"'))
-					{ // match is quoted; check it's case.
-						if (str.substring(pos,
-							pos + nameLen).equals(tableName))
-						// everything checks out.
-							return true;
-					}
-					else
-					// match isn't quoted, so we're okay as is.
-						return true;
-				}
-
-				pos = str.indexOf(tableName, pos + nameLen);
-
-			}
-		}
-
-		// If we get here, we didn't find it.
-		return false;
-
-	}
-
-	/* ************************************************
-	 * partOfWord:
-	 * Returns true if the part of the string given by
-	 * str.substring(pos, pos + nameLen) is part of
-	 * another word.
-	 * @param str The string in which we're looking.
-	 * @param pos The position at which the substring in
-	 *  question begins.
-	 * @param nameLen the length of the substring in
-	 *  question.
-	 * @param strLen The length of the string in which
-	 *  we're looking.
-	 * @return true if the substring from pos to
-	 *  pos+nameLen is part of larger word (i.e.
-	 *  if it has a letter/digit immediately before
-	 *  or after); false otherwise.
-	 ****/
-
-	private static boolean partOfWord (String str,
-		int pos, int nameLen, int strLen)
-	{
-
-		boolean somethingBefore = false;
-		if (pos > 0) {
-			char c = str.charAt(pos-1);
-			somethingBefore = ((c == '_') ||
-				Character.isLetterOrDigit(c));
-		}
-
-		boolean somethingAfter = false;
-		if (pos + nameLen < strLen) {
-			char c = str.charAt(pos + nameLen);
-			somethingAfter = ((c == '_') ||
-				Character.isLetterOrDigit(c));
-		}
-
-		return (somethingBefore || somethingAfter);
-
-	}
-
-	/* ************************************************
-	 * expandDoubleQuotes:
-	 * If the received SQL id contains a quote, we have
-	 * to expand it into TWO quotes so that it can be
-	 * treated correctly at parse time.
-	 * @param name Id that we want to print.
-	 ****/
-
-	public static String expandDoubleQuotes(String name) {
-
-		if ((name == null) || (name.indexOf("\"") < 0))
-		// nothing to do.
-			return name;
-
-		char [] cA = name.toCharArray();
-
-		// Worst (and extremely unlikely) case is every 
-		// character is a double quote, which means the
-		// escaped string would need to be 2 times as long.
-		char [] result = new char[2*cA.length];
-
-		int j = 0;
-		for (int i = 0; i < cA.length; i++) {
-
-			if (cA[i] == '"') {
-				result[j++] = '"';
-				result[j++] = '"';
-			}
-			else
-				result[j++] = cA[i];
-
-		}
-
-		return new String(result, 0, j);
-
-	}
-
-	/* ************************************************
-	 * lookupSchemaId:
-	 * Return the schema name corresponding to the
-	 * received schema id.
-	 * @param schemaId The id to look up.
-	 * @return the schema name.
-	 ****/
-
-	public static String lookupSchemaId(String schemaId) {
-
-		return (String)(schemaMap.get(schemaId));
-
-	}
-
-	/* ************************************************
-	 * lookupTableId:
-	 * Return the table name corresponding to the
-	 * received table id.
-	 * @param tableId The id to look up.
-	 * @return the table name.
-	 ****/
-
-	public static String lookupTableId(String tableId) {
-
-		return (String)(tableIdToNameMap.get(tableId));
-
-	}
-
-	/* ************************************************
-	 * writeVerboseOutput:
-	 * Writes the received string as "verbose" output,
-	 * meaning that we write it to System.err.  We
-	 * choose System.err so that the string doesn't
-	 * show up if the user pipes dblook output to
-	 * a file (unless s/he explicitly pipes System.err
-	 * output to that file, as well).
-	 * @param key Key for the message to be printed as
-	 *  verbose output.
-	 * @param value Value to be substituted into the
-	 *  message.
-	 * @return message for received key has been printed
-	 *  to System.err.
-	 ****/
-
-	public static void writeVerboseOutput(String key,
-		String value) {
-
-		if (value == null)
-			System.err.println(lookupMessage(key));
-		else
-			System.err.println(lookupMessage(key,
-				new String [] {value}));
-		return;
-
-	}
-
-	/* ************************************************
-	 * lookupMessage:
-	 * Retrieve a localized message.
-	 * @param key The key for the localized message.
-	 * @return the message corresponding to the received
-	 *  key.
-	 ****/
-
-	public static String lookupMessage(String key) {
-
-		return lookupMessage(key, null);
-
-	}
-
-	/* ************************************************
-	 * lookupMessage:
-	 * Retreive a localized message.
-	 * @param key The key for the localized message.
-	 * @param vals Array of values to be used in the
-	 *   message.
-	 * @return the message corresponding to the received
-	 *  key, with the received values substituted where
-	 *  appropriate.
-	 ****/
-
-	public static String lookupMessage(String key, String[] vals) {
-	
-		String msg = "";
-		if (vals == null)
-			msg = langUtil.getTextMessage(key);
-		else {
-			switch (vals.length) {
-				case 1: msg = langUtil.getTextMessage(
-							key, vals[0]);
-						break;
-				case 2: msg = langUtil.getTextMessage(
-							key, vals[0], vals[1]);
-						break;
-				default: /* shouldn't happen */
-						break;
-			}
-		}
-
-		return msg;
-
-	}
-
-	/* ************************************************
-	 * removeNewlines:
-	 * Remove any newline characters from the received
-	 * string (replace them with spaces).
-	 * @param str The string from which we are removing
-	 *  all newline characters.
-	 * @return The string, with all newline characters
-	 *  replaced with spaces.
-	 ****/
-
-	public static String removeNewlines(String str) {
-
-		if (str == null)
-		// don't do anything.
-			return null;
-
-		StringBuffer result = null;
-		try {
-
-			BufferedReader strVal = new BufferedReader (new StringReader(str));
-			for (String txt = strVal.readLine(); txt != null;
-				txt = strVal.readLine())
-			{
-				if (result == null)
-					result = new StringBuffer(txt);
-				else {
-					result.append(" ");
-					result.append(txt);
-				}
-			}
-
-			return result.toString();
-
-		} catch (Exception e) {
-		// if something went wrong, just return the string as is--
-		// worst case is that the generated DDL is correct, it just
-		// can't be run in a DB2 CLP script (because of the newline
-		// characters).
-			return str;
-		}
-
-	}
-
-}
-
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.tools
+   (C) Copyright IBM Corp. 2003, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.tools;
+
+import java.io.BufferedReader;
+import java.io.StringReader;
+
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Connection;
+import java.sql.Statement;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Timestamp;
+
+import java.util.HashMap;
+import java.util.StringTokenizer;
+import java.util.ArrayList;
+
+import org.apache.derby.iapi.tools.i18n.LocalizedResource;
+
+import org.apache.derby.impl.tools.cslook.DB_Check;
+import org.apache.derby.impl.tools.cslook.DB_Index;
+import org.apache.derby.impl.tools.cslook.DB_Jar;
+import org.apache.derby.impl.tools.cslook.DB_Key;
+import org.apache.derby.impl.tools.cslook.DB_Table;
+import org.apache.derby.impl.tools.cslook.DB_Schema;
+import org.apache.derby.impl.tools.cslook.DB_StoredProcedure;
+import org.apache.derby.impl.tools.cslook.DB_Trigger;
+import org.apache.derby.impl.tools.cslook.DB_View;
+import org.apache.derby.impl.tools.cslook.Logs;
+
+public class dblook {
+
+	/* 
+		IBM Copyright &copy notice.
+	*/
+	/**
+		IBM Copyright &copy notice.
+	*/
+
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_2003_2004;
+
+	// DB2 enforces a maximum of 30 tables to be specified as part of
+	// the table list.
+	public static final int DB2_MAX_NUMBER_OF_TABLES = 30;
+
+	private Connection conn;
+	private static PreparedStatement getColNameFromNumberQuery;
+
+	// Mappings from id to name for schemas and tables (for ease
+	// of reference).
+	protected static HashMap schemaMap;
+	protected static HashMap tableIdToNameMap;
+
+	// Command-line Parameters.
+	protected static String sourceDBUrl;
+	protected static String ddlFileName;
+	protected static String stmtDelimiter;
+	protected static boolean appendLogs;
+	protected static ArrayList tableList;
+	protected static String schemaParam;
+	protected static String targetSchema;
+	protected static boolean skipViews;
+	protected static boolean verbose;
+	private static String sourceDBName;
+
+	private static String lookLogName = "dblook.log";
+
+	private final static String DEFAULT_LOCALE= "en";
+	private final static String DEFAULT_LOCALE_COUNTRY="US";
+	private static LocalizedResource langUtil;
+
+	/* ************************************************
+	 * main:
+	 * Initialize program state by creating a dblook object,
+	 * and then start the DDL generation by calling "go".
+	 * ****/
+
+	public static void main(String[] args) {
+
+		dblook looker = new dblook(args);
+		try {
+			looker.go(sourceDBUrl, sourceDBName);
+		} catch (Exception e) {
+		// Errors are logged and printed to console according
+		// to command line arguments, so just ignore here.
+		}
+
+	}
+
+	/* ************************************************
+	 * Constructor:
+	 * Parse the command line, initialize logs, echo program variables,
+	 * and load the Cloudscape driver.
+	 * @param args args[0] is the database URL.  All other command-line
+	 *  parameters are read as system properties.
+	 * ****/
+
+	public dblook(String[] args) {
+
+        // Adjust the application in accordance with derby.ui.locale
+		// and derby.ui.codeset
+		langUtil = LocalizedResource.getInstance();
+
+		// Initialize class variables.
+		initState();
+
+		// Parse the command line.
+		if (!parseArgs(args)) {
+			System.out.println(lookupMessage("CSLOOK_Usage"));
+			System.exit(1);
+		}
+
+		showVariables();
+
+		if (!loadDriver()) {
+		// Failed when loading the driver.  We already printed
+		// the exception, so just return.
+			return;
+		}
+
+		schemaMap = new HashMap();
+		tableIdToNameMap = new HashMap();
+
+	}
+
+	/* ************************************************
+	 * initState:
+	 * Initialize class variables.
+	 ****/
+
+	private void initState() {
+
+		sourceDBUrl = null;
+		ddlFileName = null;
+		stmtDelimiter = null;
+		appendLogs = false;
+		tableList = null;
+		targetSchema = null;
+		schemaParam = null;
+		skipViews = false;
+		verbose= false;
+		sourceDBName = null;
+		return;
+
+	}
+
+	/* ************************************************
+	 * parseArgs:
+	 * Parse the command-line arguments.  There is only one
+	 * actual argument (database url); the rest of the parameters
+	 * are read in as System properties.
+	 * @param args args[0] is the url for the source database.
+	 * @return true if all parameters were loaded and the output
+	 *  files were successfully created; false otherwise.
+	 ****/
+
+	private boolean parseArgs(String[] args) {
+
+		if (args.length < 2)
+		// must have minimum of 2 args: "-d" and "<dbUrl>".
+			return false;
+
+		int st = 0;
+		for (int i = 0; i < args.length; i++) {
+			st = loadParam(args, i);
+			if (st == -1)
+				return false;
+			i = st;
+		}
+
+		if (sourceDBUrl == null) {
+		// must have at least a database url.
+			return false;	
+		}
+
+		// At this point, all parameters should have been read into
+		// their respective class variables.  Use those
+		// variables for some further processing.
+
+		// Setup logs.
+		boolean okay = Logs.initLogs(lookLogName, ddlFileName, appendLogs,
+		 	verbose, (stmtDelimiter == null ? ";" : stmtDelimiter));
+
+		// Get database name.
+		sourceDBName = extractDBNameFromUrl(sourceDBUrl);
+
+		// Set up schema restriction.
+		if ((schemaParam != null) && (schemaParam.length() > 0) &&
+			(schemaParam.charAt(0) != '"'))
+		// not quoted, so upper case, then add quotes.
+		{
+			targetSchema = addQuotes(expandDoubleQuotes(
+				schemaParam.toUpperCase(java.util.Locale.ENGLISH)));
+		}
+		else
+			targetSchema = addQuotes(expandDoubleQuotes(stripQuotes(schemaParam)));
+		return okay;
+
+	}
+
+	/* ************************************************
+	 * loadParam:
+	 * Read in a flag and its corresponding values from
+	 * list of command line arguments, starting at
+	 * the start'th argument.
+	 * @return The position of the argument that was
+	 *  most recently processed.
+	 ****/
+
+	private int loadParam(String [] args, int start) {
+
+		if ((args[start].length() == 0) || args[start].charAt(0) != '-')
+		// starting argument should be a flag; if it's
+		// not, ignore it.
+			return start;
+
+		boolean haveVal = (args.length > start + 1);
+		switch (args[start].charAt(1)) {
+
+			case 'd':
+				if (!haveVal)
+					return -1;
+				if (args[start].length() == 2)
+					sourceDBUrl = args[++start];
+				return start;
+
+			case 'z':
+				if (!haveVal)
+					return -1;
+				if (args[start].length() == 2)
+					schemaParam = args[++start];
+				return start;
+
+			case 't':
+				if (!haveVal)
+					return -1;
+				if (args[start].equals("-td")) {
+					stmtDelimiter = args[++start];
+					return start;
+				}
+				else if (args[start].equals("-t"))
+				// list of tables.
+					return extractTableNamesFromList(args, start+1);
+				return -1;
+			case 'o':
+				if (!haveVal)
+					return -1;
+				if ((args[start].length() == 2) && (args[start+1].length() > 0))
+					ddlFileName = args[++start];
+				return start;
+
+			case 'a':
+				if (args[start].equals("-append")) {
+					appendLogs = true;
+					return start;
+				}
+				return -1;
+
+			case 'n':
+				if (args[start].equals("-noview")) {
+					skipViews = true;
+					return start;
+				}
+				return -1;
+
+			case 'v':
+				if (args[start].equals("-verbose")) {
+					verbose = true;
+					return start;
+				}
+				return -1;
+
+			default:
+				return -1;
+
+		}
+
+	}
+
+	/* ************************************************
+	 * loadDriver:
+	 * Load db2j driver.
+	 * @param precondition sourceDBUrl has been loaded.
+	 * @return false if anything goes wrong; true otherwise.
+	 ****/
+
+	private boolean loadDriver() {
+
+		String db2jDriver;
+		if (sourceDBUrl.indexOf(":net://") != -1)
+			db2jDriver = "com.ibm.db2.jcc.DB2Driver";
+		else
+			db2jDriver = "org.apache.derby.jdbc.EmbeddedDriver";
+		try {
+			Class.forName(db2jDriver).newInstance();
+		} catch (Exception e)
+		{
+			Logs.debug(e);
+			return false;
+		}
+
+		return true;
+
+	}
+
+	/* ************************************************
+	 * extractDBNameFromUrl:
+	 * Given a database url, parse out the actual name
+	 * of the database.  This is required for creation
+	 * the DB2JJARS directory (the database name is part
+	 * of the path to the jar).
+	 * @param dbUrl The database url from which to extract the
+	 *  the database name.
+	 * @return the name of the database (including its
+	 *  path, if provided) that is referenced by the url.
+	 ****/
+
+	protected String extractDBNameFromUrl(String dbUrl) {
+
+		if (dbUrl == null)
+		// shouldn't happen; ignore it here, as an error
+		// will be thrown we try to connect.
+			return "";
+
+		int start = dbUrl.indexOf("jdbc:derby:");
+		if (start == -1)
+		// not a valid url; just ignore it (an error
+		// will be thrown when we try to connect).
+			return "";
+
+		start = dbUrl.indexOf("net://");
+		if (start == -1)
+		// standard url (jdbc:derby:<dbname>).  Database
+		// name starts right after "cloudscape:".  The "11" in
+		// the following line is the length of "cloudscape:".
+			start = dbUrl.indexOf("cloudscape:") + 11;
+		else
+		// Network Server url.  Database name starts right
+		// after next slash (":net://hostname:port/<dbname>).
+		// The "6" in the following line is the length of
+		// "net://".
+			start = dbUrl.indexOf("/", start+6) + 1;
+
+		int stop = -1;
+		if (dbUrl.charAt(start) == '"') {
+		// database name is quoted; end of the name is the
+		// closing quote.
+			start++;
+			stop = dbUrl.indexOf("\"", start);
+		}
+		else {
+		// Database name ends with the start of a list of connection	
+		// attributes.  This list can begin with either a colon
+		// or a semi-colon.
+			stop = dbUrl.indexOf(":", start);
+			if (stop != -1) {
+				if ((dbUrl.charAt(stop+1) == '/') ||
+						(dbUrl.charAt(stop+1) == '\\'))
+				// then this colon is part of the path (ex. "C:"),
+				// so ignore it.
+					stop = dbUrl.indexOf(":", stop+2);
+			}
+			int stop2 = dbUrl.length();
+			if (stop == -1)
+			// no colons; see if we can find a semi-colon.
+				stop = dbUrl.indexOf(";", start);
+			else
+				stop2 = dbUrl.indexOf(";", start);
+			stop = (stop <= stop2 ? stop : stop2);
+		}
+
+		if (stop == -1)
+		// we have a url that ends with database name (no
+		// other attributes appended).
+			stop = dbUrl.length();
+
+		return dbUrl.substring(start, stop);
+
+	}
+
+	/* ************************************************
+	 * extractTableNamesFromList:
+	 * Given an array of command line arguments containing
+	 * a list of table names beginning at start'th position,
+	 * read the list of table names and store them as
+	 * our target table list.  Names without quotes are
+	 * turned into ALL CAPS and then double quotes are
+	 * added; names whcih already have double quotes are
+	 * stored exactly as they are. NOTE: DB2 enforces
+	 * maximum of 30 tables, and ignores the rest; so
+	 * do we.
+	 * @param args Array of command line arguments.
+	 * @start Position of the start of the list of tables
+	 *  with the args array.
+	 * @return The position of the last table name in
+	 *  the list of table names.
+	 ****/
+
+	private int extractTableNamesFromList(String [] args,
+		int start)
+	{
+
+		int argIndex = start;
+		int count = 0;
+		tableList = new ArrayList();
+		while (argIndex < args.length) {
+
+			if (((args[argIndex].length() > 0) && (args[argIndex].charAt(0) == '-')) ||
+				(++count > DB2_MAX_NUMBER_OF_TABLES))
+			// we're done with the table list.
+				break;
+
+			if ((args[argIndex].length() > 0) && (args[argIndex].charAt(0) == '"'))
+			// it's quoted.
+				tableList.add(addQuotes(expandDoubleQuotes(
+					stripQuotes(args[argIndex++]))));
+			else
+			// not quoted, so make it all caps, then add
+			// quotes.
+				tableList.add(addQuotes(
+					expandDoubleQuotes(args[argIndex++].toUpperCase(
+					java.util.Locale.ENGLISH))));
+
+		}
+
+		if (tableList.size() == 0)
+			tableList = null;
+
+		return argIndex - 1;
+
+	}
+
+	/* ************************************************
+	 * showVariables:
+	 * Echo primary variables to output, so user can see
+	 * what s/he specified.
+	 ****/
+
+	private void showVariables() {
+
+		if (ddlFileName != null) {
+			Logs.reportString("============================\n");
+			Logs.reportMessage("CSLOOK_FileCreation");
+			if (verbose)
+				writeVerboseOutput("CSLOOK_OutputLocation",
+					ddlFileName);
+		}
+
+		Logs.reportMessage("CSLOOK_Timestamp",
+			new Timestamp(System.currentTimeMillis()).toString());
+		Logs.reportMessage("CSLOOK_DBName", sourceDBName);
+		Logs.reportMessage("CSLOOK_DBUrl", sourceDBUrl);
+		if (tableList != null)
+			Logs.reportMessage("CSLOOK_TargetTables");
+		if (schemaParam != null)
+			Logs.reportMessage("CSLOOK_TargetSchema", stripQuotes(schemaParam));
+		Logs.reportString("appendLogs: " + appendLogs + "\n");
+		return;
+
+	}
+
+	/* ************************************************
+	 * go:
+	 * Connect to the source database, prepare statements,
+	 * and load a list of table id-to-name mappings.  Then,
+	 * generate the DDL for the various objects in the
+	 * database by making calls to static methods of helper
+	 * classes (one helper class for each type of database
+	 * object).  If a particular object type should not be
+	 * generated (because of the user-specified command-
+	 * line), then we enforce that here.
+	 * @precondition all user-specified parameters have
+	 *  been loaded.
+	 * @param srcUrl The full url of the database, as obtained
+	 *  from parseArgs().
+	 * @param srcName The name of the database (as opposed to
+	 *  the URL), as obtained from parseArgs().  This is
+	 *  needed for locating any jar files that might'
+	 *  exist in the source database.
+	 * @return DDL for the source database has been
+	 *  generated and printed to output, subject to
+	 *  user-specified restrictions.
+	 * ****/
+
+	public void go(String srcUrl, String srcName)
+		throws Exception
+	{
+
+		try
+		{
+
+			// Connect to the database, prepare statements,
+			// and load id-to-name mappings.
+			this.conn = DriverManager.getConnection(srcUrl);
+			try {
+				prepForDump();
+			} catch (SQLException sqlE) {
+				Logs.debug(sqlE);
+				Logs.debug(Logs.unRollExceptions(sqlE), (String)null);
+				Logs.cleanup();
+				return;
+			}
+			catch (Exception e) {
+				Logs.debug(e);
+				Logs.cleanup();
+				return;
+			}
+
+			// Generate DDL.
+
+			// Start with schemas, since we might need them to
+			// exist for jars to load properly.
+			DB_Schema.doSchemas(this.conn,
+				(tableList != null) && (targetSchema == null));
+
+			if (tableList == null) {
+			// Don't do these if user just wants table-related objects.
+				DB_Jar.doJars(srcName, this.conn);
+				DB_StoredProcedure.doStoredProcedures(this.conn);
+			}
+
+			DB_Table.doTables(this.conn, tableIdToNameMap);
+			DB_Index.doIndexes(this.conn);
+			DB_Key.doKeys(this.conn);
+			DB_Check.doChecks(this.conn);
+
+			if (!skipViews)
+				DB_View.doViews(this.conn);
+
+			DB_Trigger.doTriggers(this.conn);
+
+			// That's it; we're done.
+			if (getColNameFromNumberQuery != null)
+				getColNameFromNumberQuery.close();
+			Logs.cleanup();
+
+		}
+		catch (SQLException sqlE)
+		{
+			Logs.debug(sqlE);
+			Logs.debug(Logs.unRollExceptions(sqlE), (String)null);
+			Logs.cleanup();
+			throw sqlE;
+		}
+		catch (Exception e)
+		{
+			Logs.debug(e);
+			Logs.cleanup();
+			throw e;
+		}
+		finally {
+		// Close our connection.
+			conn.commit();
+			conn.close();
+		}
+
+	}
+
+	/* ************************************************
+	 * prepForDump:
+	 * Prepare any useful statements (i.e. statements that
+	 * are required by more than one helper class) and load
+	 * the id-to-name mappings for the source database.
+	 ****/
+
+	private void prepForDump() throws Exception {
+
+		// We're only SELECTing throughout all of this, so no need
+		// to commit (plus, disabling commit makes it easier to
+		// have multiple ResultSets open on the same connection).
+		this.conn.setAutoCommit(false);
+
+		// Prepare statements.
+		getColNameFromNumberQuery = conn.prepareStatement(
+			"SELECT COLUMNNAME FROM SYS.SYSCOLUMNS WHERE " +
+			"REFERENCEID = ? AND COLUMNNUMBER = ?");
+
+		// Load list of user tables and table ids, for general use.
+		Statement stmt = conn.createStatement();
+		ResultSet rs = stmt.executeQuery("SELECT T.TABLEID, T.TABLENAME, " +
+				"S.SCHEMANAME FROM SYS.SYSTABLES T, SYS.SYSSCHEMAS S " + 
+				"WHERE T.TABLETYPE = 'T' AND T.SCHEMAID = S.SCHEMAID");
+
+		while (rs.next()) {
+			String tableName = addQuotes(expandDoubleQuotes(rs.getString(2)));
+			String schemaName = addQuotes(expandDoubleQuotes(rs.getString(3)));
+			tableIdToNameMap.put(rs.getString(1), 
+				schemaName + "." + tableName);
+		}
+
+		// Load schema id's and names.
+		rs = stmt.executeQuery("SELECT SCHEMAID, SCHEMANAME FROM " +
+			"SYS.SYSSCHEMAS");
+		while (rs.next()) {
+			schemaMap.put(rs.getString(1),
+				addQuotes(expandDoubleQuotes(rs.getString(2))));
+		}
+
+		stmt.close();
+
+		// Load default property values.
+		return;
+
+	}
+
+	/* ************************************************
+	 * getColumnListFromDescription:
+	 * Takes string description of column numbers in the
+	 * form of "(2, 1, 3...)" and the id of the table
+	 * having those columns, and then returns a string
+	 * with the column numbers replaced by their actual
+	 * names ('2' is replaced with the 2nd column in the
+	 * table, '1' with the first column, etc.).
+	 * @param tableId the id of the table to which the column
+	 *   numbers should be applied.
+	 * @param description a string holding a list of column
+	 *  numbers, enclosed in parentheses and separated
+	 *  by commas.
+	 * @return a new string with the column numbers in
+	 *  'description' replaced by their column names;
+	 *  also, the parentheses have been stripped off.
+	 ****/
+
+	public static String getColumnListFromDescription(String tableId,
+		String description) throws SQLException
+	{
+
+		StringBuffer sb = new StringBuffer();
+		StringTokenizer tokenizer = new StringTokenizer(
+			description.substring(description.indexOf("(") + 1,
+				description.lastIndexOf(")")), " ,", true);
+
+		boolean firstCol = true;
+		while (tokenizer.hasMoreTokens()) {
+
+			String tok = tokenizer.nextToken().trim();
+			if (tok.equals(""))
+				continue;
+			else if (tok.equals(",")) {
+				firstCol = false;
+				continue;
+			}
+			try {
+				String colName = getColNameFromNumber(tableId,
+					(Integer.valueOf(tok)).intValue());
+				if (!firstCol)
+					sb.append(", ");
+				sb.append(colName);
+			} catch (NumberFormatException e) {
+			// not a number; could be "ASC" or "DESC" tag,
+			// which is okay; otherwise, something's wrong.
+				tok = tok.toUpperCase();
+				if (tok.equals("DESC") || tok.equals("ASC"))
+				// then this is okay; just add the token to result.
+					sb.append(" " + tok);
+				else
+				// shouldn't happen.
+					Logs.debug("INTERNAL ERROR: read a non-number (" +
+						tok + ") when a column number was expected:\n" +
+						description, (String)null);
+			}
+
+		}
+
+		return sb.toString();
+
+	}
+
+	/* ************************************************
+	 * getColNameFromNumber:
+	 * Takes a tableid and a column number colNum, and
+	 * returns the name of the colNum'th column in the
+	 * table with tableid.
+	 * @param tableid id of the table.
+	 * @param colNum number of the column for which we want
+	 *  the name.
+	 * @return The name of the colNum'th column in the
+	 *  table with tableid.
+	 ****/
+
+	public static String getColNameFromNumber(String tableId,
+		int colNum) throws SQLException
+	{
+
+		getColNameFromNumberQuery.setString(1, tableId);
+		getColNameFromNumberQuery.setInt(2, colNum);
+		ResultSet rs = getColNameFromNumberQuery.executeQuery();
+
+		if (!rs.next()) {
+		// shouldn't happen.
+			Logs.debug("INTERNAL ERROR: Failed column number " +
+				"lookup for table " + lookupTableId(tableId) +
+				", column " + colNum, (String)null);
+			rs.close();
+			return "";
+		}
+		else {
+			String colName = addQuotes(expandDoubleQuotes(rs.getString(1)));
+			rs.close();
+			return colName;
+		}
+
+	}
+
+	/* ************************************************
+	 * addQuotes:
+	 * Add quotes to the received object name, and return
+	 * the result.
+	 * @param name the name to which to add quotes.
+	 * @return the name with double quotes around it.
+	 ****/
+
+	public static String addQuotes(String name) {
+
+		if (name == null)
+			return null;
+
+		return "\"" + name + "\"";
+
+	}
+
+	/* ************************************************
+	 * stripQuotes:
+	 * Takes a name and, if the name is enclosed in
+	 * quotes, strips the quotes off.  This method
+	 * assumes that the received String either has no quotes,
+	 * or has a quote (double or single) as the very first
+	 * AND very last character.
+	 * @param quotedName a name with quotes as the first
+	 *  and last character, or else with no quotes at all.
+	 * @return quotedName, without the quotes.
+	 ****/
+
+	public static String stripQuotes(String quotedName) {
+
+		if (quotedName == null)
+			return null;
+
+		if ((quotedName.indexOf("\"") == -1) &&
+			(quotedName.indexOf("'") == -1))
+		// nothing to do.
+			return quotedName;
+
+		return quotedName.substring(1, quotedName.length() - 1);
+
+	}
+
+	/* ************************************************
+	 * isExcludedTable:
+	 * Takes a table name and determines whether or not
+	 * the DDL for objects related to that table should be
+	 * generated.
+	 * @param tableName name of the table to check.
+	 * @return true if 1) the user specified a table list
+	 *  and that list does NOT include the received name; or
+	 *  2) if the user specified a schema restriction and
+	 *  the received name does NOT have that schema; false
+	 *  otherwise.
+	 ****/
+
+	public static boolean isExcludedTable(String tableName) {
+
+		if (tableName == null)
+			return true;
+
+		int dot = tableName.indexOf(".");
+		if (dot != -1) {
+		// strip off the schema part of the name, and see if we're
+		// okay to use it.
+			if (isIgnorableSchema(tableName.substring(0, dot)))
+			// then we exclude this table.
+				return true;
+			tableName = tableName.substring(dot + 1,
+				tableName.length());
+		}
+
+		return ((tableList != null) && !tableList.contains(tableName));
+
+	}
+
+	/* ************************************************
+	 * Takes a schema name and determines whether or
+	 * not the DDL for objects with that schema should
+	 * be generated.
+	 * @param schemaName schema name to be checked.
+	 * @return true if 1) the user specified a target
+	 *  schema and that target is NOT the same as the
+	 *  received schema name, or 2) the schema is a
+	 *  system schema (SYS, SYSVISUAL, or SYSIBM);
+	 *  false otherwise;
+	 ****/
+
+    public static final String[] ignorableSchemaNames = {
+        "SYSIBM",
+        "SYS",
+        "SYSVISUAL",
+        "SYSCAT",
+        "SYSFUN",
+        "SYSPROC",
+        "SYSSTAT",
+        "NULLID",
+        "SYSCS_ADMIN",
+        "SYSCS_DIAG",
+        "SYSCS_UTIL",
+        "SQLJ"};
+
+	public static boolean isIgnorableSchema(String schemaName) {
+
+		if ((targetSchema != null) && (!schemaName.equals(targetSchema)))
+			return true;
+
+		schemaName = stripQuotes(schemaName);
+
+        boolean ret = false;
+
+        for (int i = ignorableSchemaNames.length - 1; i >= 0;)
+        {
+            if ((ret = ignorableSchemaNames[i--].equalsIgnoreCase(schemaName)))
+                break;
+        }
+
+        return(ret);
+	}
+
+	/* ************************************************
+	 * Takes a string and determines whether or not that
+	 * string makes reference to any of the table names
+	 * in the user-specified table list.
+	 * @param str The string in which to search for table names.
+	 * @return true if 1) the user didn't specify a
+	 *  target table list, or 2) the received string
+	 *  contains at least one of the table names in the
+	 *  user-specified target list; false otherwise.
+	 ****/
+
+	public static boolean stringContainsTargetTable(String str) {
+
+		if (str == null)
+		// if the string is null, it can't possibly contain
+		// any table names.
+			return false;
+
+		if (tableList == null)
+		// if we have no target tables, then default to true.
+			return true;
+
+		int strLen = str.length();
+		for (int i = 0; i < tableList.size(); i++) {
+
+			String tableName = (String)tableList.get(i);
+			tableName = expandDoubleQuotes(stripQuotes(tableName));
+			int nameLen = tableName.length();
+			String strCopy;
+			if (tableName.equals(tableName.toUpperCase(
+				java.util.Locale.ENGLISH)))
+			// case doesn't matter.
+				strCopy = str.toUpperCase();
+			else
+				strCopy = str;
+			int pos = strCopy.indexOf(tableName);
+			while (pos != -1) {
+
+				// If we found it, make sure it's really a match.
+				// First, see if it's part of another word.
+				if (!partOfWord(str, pos, nameLen, strLen)) {
+
+					// See if the match is in quotes--if so, then
+					// it should match the table name's case.
+					if ((pos >= 1) && (strCopy.charAt(pos-1) == '"') &&
+					  (pos + nameLen < strCopy.length()) &&
+					  (strCopy.charAt(pos+nameLen) == '"'))
+					{ // match is quoted; check it's case.
+						if (str.substring(pos,
+							pos + nameLen).equals(tableName))
+						// everything checks out.
+							return true;
+					}
+					else
+					// match isn't quoted, so we're okay as is.
+						return true;
+				}
+
+				pos = str.indexOf(tableName, pos + nameLen);
+
+			}
+		}
+
+		// If we get here, we didn't find it.
+		return false;
+
+	}
+
+	/* ************************************************
+	 * partOfWord:
+	 * Returns true if the part of the string given by
+	 * str.substring(pos, pos + nameLen) is part of
+	 * another word.
+	 * @param str The string in which we're looking.
+	 * @param pos The position at which the substring in
+	 *  question begins.
+	 * @param nameLen the length of the substring in
+	 *  question.
+	 * @param strLen The length of the string in which
+	 *  we're looking.
+	 * @return true if the substring from pos to
+	 *  pos+nameLen is part of larger word (i.e.
+	 *  if it has a letter/digit immediately before
+	 *  or after); false otherwise.
+	 ****/
+
+	private static boolean partOfWord (String str,
+		int pos, int nameLen, int strLen)
+	{
+
+		boolean somethingBefore = false;
+		if (pos > 0) {
+			char c = str.charAt(pos-1);
+			somethingBefore = ((c == '_') ||
+				Character.isLetterOrDigit(c));
+		}
+
+		boolean somethingAfter = false;
+		if (pos + nameLen < strLen) {
+			char c = str.charAt(pos + nameLen);
+			somethingAfter = ((c == '_') ||
+				Character.isLetterOrDigit(c));
+		}
+
+		return (somethingBefore || somethingAfter);
+
+	}
+
+	/* ************************************************
+	 * expandDoubleQuotes:
+	 * If the received SQL id contains a quote, we have
+	 * to expand it into TWO quotes so that it can be
+	 * treated correctly at parse time.
+	 * @param name Id that we want to print.
+	 ****/
+
+	public static String expandDoubleQuotes(String name) {
+
+		if ((name == null) || (name.indexOf("\"") < 0))
+		// nothing to do.
+			return name;
+
+		char [] cA = name.toCharArray();
+
+		// Worst (and extremely unlikely) case is every 
+		// character is a double quote, which means the
+		// escaped string would need to be 2 times as long.
+		char [] result = new char[2*cA.length];
+
+		int j = 0;
+		for (int i = 0; i < cA.length; i++) {
+
+			if (cA[i] == '"') {
+				result[j++] = '"';
+				result[j++] = '"';
+			}
+			else
+				result[j++] = cA[i];
+
+		}
+
+		return new String(result, 0, j);
+
+	}
+
+	/* ************************************************
+	 * lookupSchemaId:
+	 * Return the schema name corresponding to the
+	 * received schema id.
+	 * @param schemaId The id to look up.
+	 * @return the schema name.
+	 ****/
+
+	public static String lookupSchemaId(String schemaId) {
+
+		return (String)(schemaMap.get(schemaId));
+
+	}
+
+	/* ************************************************
+	 * lookupTableId:
+	 * Return the table name corresponding to the
+	 * received table id.
+	 * @param tableId The id to look up.
+	 * @return the table name.
+	 ****/
+
+	public static String lookupTableId(String tableId) {
+
+		return (String)(tableIdToNameMap.get(tableId));
+
+	}
+
+	/* ************************************************
+	 * writeVerboseOutput:
+	 * Writes the received string as "verbose" output,
+	 * meaning that we write it to System.err.  We
+	 * choose System.err so that the string doesn't
+	 * show up if the user pipes dblook output to
+	 * a file (unless s/he explicitly pipes System.err
+	 * output to that file, as well).
+	 * @param key Key for the message to be printed as
+	 *  verbose output.
+	 * @param value Value to be substituted into the
+	 *  message.
+	 * @return message for received key has been printed
+	 *  to System.err.
+	 ****/
+
+	public static void writeVerboseOutput(String key,
+		String value) {
+
+		if (value == null)
+			System.err.println(lookupMessage(key));
+		else
+			System.err.println(lookupMessage(key,
+				new String [] {value}));
+		return;
+
+	}
+
+	/* ************************************************
+	 * lookupMessage:
+	 * Retrieve a localized message.
+	 * @param key The key for the localized message.
+	 * @return the message corresponding to the received
+	 *  key.
+	 ****/
+
+	public static String lookupMessage(String key) {
+
+		return lookupMessage(key, null);
+
+	}
+
+	/* ************************************************
+	 * lookupMessage:
+	 * Retreive a localized message.
+	 * @param key The key for the localized message.
+	 * @param vals Array of values to be used in the
+	 *   message.
+	 * @return the message corresponding to the received
+	 *  key, with the received values substituted where
+	 *  appropriate.
+	 ****/
+
+	public static String lookupMessage(String key, String[] vals) {
+	
+		String msg = "";
+		if (vals == null)
+			msg = langUtil.getTextMessage(key);
+		else {
+			switch (vals.length) {
+				case 1: msg = langUtil.getTextMessage(
+							key, vals[0]);
+						break;
+				case 2: msg = langUtil.getTextMessage(
+							key, vals[0], vals[1]);
+						break;
+				default: /* shouldn't happen */
+						break;
+			}
+		}
+
+		return msg;
+
+	}
+
+	/* ************************************************
+	 * removeNewlines:
+	 * Remove any newline characters from the received
+	 * string (replace them with spaces).
+	 * @param str The string from which we are removing
+	 *  all newline characters.
+	 * @return The string, with all newline characters
+	 *  replaced with spaces.
+	 ****/
+
+	public static String removeNewlines(String str) {
+
+		if (str == null)
+		// don't do anything.
+			return null;
+
+		StringBuffer result = null;
+		try {
+
+			BufferedReader strVal = new BufferedReader (new StringReader(str));
+			for (String txt = strVal.readLine(); txt != null;
+				txt = strVal.readLine())
+			{
+				if (result == null)
+					result = new StringBuffer(txt);
+				else {
+					result.append(" ");
+					result.append(txt);
+				}
+			}
+
+			return result.toString();
+
+		} catch (Exception e) {
+		// if something went wrong, just return the string as is--
+		// worst case is that the generated DDL is correct, it just
+		// can't be run in a DB2 CLP script (because of the newline
+		// characters).
+			return str;
+		}
+
+	}
+
+}
+

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/tools/ij.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/tools/ij.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/tools/ij.java	Fri Sep 24 10:33:20 2004
@@ -1,76 +1,76 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.tools
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.tools;
-
-import org.apache.derby.iapi.services.info.JVMInfo;
-
-import org.apache.derby.impl.tools.ij.Main;
-
-import java.io.IOException;
-
-/**
-	
-	ij is Cloudscape's interactive JDBC scripting tool.
-	It is a simple utility for running scripts against a Cloudscape database.
-	You can also use it interactively to run ad hoc queries.
-	ij provides several commands for ease in accessing a variety of JDBC features.
-	<P>
-
-	To run from the command line enter the following:
-	<p>
-	java [options] org.apache.derby.tools.ij [arguments]
-	<P>
-	ij is can also be used with any database server that supports a JDBC driver.
-*/
-public class ij {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-
-  /**
-  	@exception IOException thrown if cannot access input or output files.
-   */
-  static public void main(String[] args) throws IOException {
-
-	  /* We decide which verion of ij (2.0 or 4.0) to
-	   * load based on the same criteria that the JDBC driver
-	   * uses.
-	   */
-	  if (JVMInfo.JDK_ID == 2)
-	  {
-		  Main.main(args);
-	  }
-	  else
-	  {
-		  org.apache.derby.impl.tools.ij.Main14.main(args);
-	  }
-  }
-
-  private ij() { // no instances allowed
-  }
-  
-  public static String getArg(String param, String[] args)
-  {
-	  return org.apache.derby.impl.tools.ij.util.getArg(param, args);
-  }
-
-  public static void getPropertyArg(String[] args) throws IOException
-  {
-	  org.apache.derby.impl.tools.ij.util.getPropertyArg(args);
-  }
-
-  public static java.sql.Connection startJBMS()
-	  throws java.sql.SQLException, IllegalAccessException, ClassNotFoundException, InstantiationException
-  {			
-		return org.apache.derby.impl.tools.ij.util.startJBMS();
-  }
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.tools
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.tools;
+
+import org.apache.derby.iapi.services.info.JVMInfo;
+
+import org.apache.derby.impl.tools.ij.Main;
+
+import java.io.IOException;
+
+/**
+	
+	ij is Cloudscape's interactive JDBC scripting tool.
+	It is a simple utility for running scripts against a Cloudscape database.
+	You can also use it interactively to run ad hoc queries.
+	ij provides several commands for ease in accessing a variety of JDBC features.
+	<P>
+
+	To run from the command line enter the following:
+	<p>
+	java [options] org.apache.derby.tools.ij [arguments]
+	<P>
+	ij is can also be used with any database server that supports a JDBC driver.
+*/
+public class ij {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+
+  /**
+  	@exception IOException thrown if cannot access input or output files.
+   */
+  static public void main(String[] args) throws IOException {
+
+	  /* We decide which verion of ij (2.0 or 4.0) to
+	   * load based on the same criteria that the JDBC driver
+	   * uses.
+	   */
+	  if (JVMInfo.JDK_ID == 2)
+	  {
+		  Main.main(args);
+	  }
+	  else
+	  {
+		  org.apache.derby.impl.tools.ij.Main14.main(args);
+	  }
+  }
+
+  private ij() { // no instances allowed
+  }
+  
+  public static String getArg(String param, String[] args)
+  {
+	  return org.apache.derby.impl.tools.ij.util.getArg(param, args);
+  }
+
+  public static void getPropertyArg(String[] args) throws IOException
+  {
+	  org.apache.derby.impl.tools.ij.util.getPropertyArg(args);
+  }
+
+  public static java.sql.Connection startJBMS()
+	  throws java.sql.SQLException, IllegalAccessException, ClassNotFoundException, InstantiationException
+  {			
+		return org.apache.derby.impl.tools.ij.util.startJBMS();
+  }
+}

Modified: incubator/derby/code/trunk/java/tools/org/apache/derby/tools/sysinfo.java
==============================================================================
--- incubator/derby/code/trunk/java/tools/org/apache/derby/tools/sysinfo.java	(original)
+++ incubator/derby/code/trunk/java/tools/org/apache/derby/tools/sysinfo.java	Fri Sep 24 10:33:20 2004
@@ -1,196 +1,196 @@
-/*
-
-   Licensed Materials - Property of IBM
-   Cloudscape - Package org.apache.derby.tools
-   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
-   US Government Users Restricted Rights - Use, duplication or
-   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-
- */
-
-package org.apache.derby.tools;
-
-import org.apache.derby.iapi.services.info.ProductVersionHolder;
-import org.apache.derby.iapi.services.info.JVMInfo;
-import org.apache.derby.impl.tools.sysinfo.Main;
-
-/**
-	
-   This class displays system information to system out.
-	 
-	To run from the command-line, enter the following:
-	<p>
-	<code>java org.apache.derby.tools.sysinfo</code>
-	<p>
-	<p>
-	Also available on this class are methods which allow you to determine
-	the version of the code for the system without actually booting a database.
-	Please note that this is the Cloudscape version of the .jar files, not of your databases.
-	<p>
-	The numbering scheme for released Cloudscape products is <b><code>m1.m2.m3 </code></b>
-	where <b><code>m1</code></b> is the major release version, <b><code>m2</code></b> is the minor release version,
-	and <b><code>m3</code></b> is the maintenance level. Versions of the product with the same
-	major and minor version numbers are considered feature compatible. 
-	<p>Valid major and minor versions are always greater than zero. Valid maintenance
-	versions are greater than or equal to zero.
-
-
-*/
-public class sysinfo {
-	/**
-		IBM Copyright &copy notice.
-	*/
-	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
-
-  static public void main(String[] args) {
-    Main.main(args);
-  }
-
-  private sysinfo() { // no instances allowed
-  }
-
-	/**
-		The genus name for the IBM Cloudscape code. Use this to determine the version of the
-		IBM Cloudscape embedded code in cs.jar.
-	*/
-	public static final String DBMS="DBMS";
-
-	/**
-	 *	The genus name for the tools code. Use this to determine the version of 
-		code in cstools.jar
-	 */
-	public static final String TOOLS="tools";
-
-
-	/**
-		gets the major version of the IBM Cloudscape embedded code.
-		@return	the major version. Returns -1 if not found.
-	 */
-  static public int getMajorVersion()
-  {
-    return getMajorVersion(DBMS);
-  }
-
-
-	/**
-		gets the major version of the specified code library. 
-		@param genus	which library to get the version of. Valid inputs include
-			DBMS, TOOLS
-		@return the major version. Return -1 if the information is not found. 
-    */		
-  static public int getMajorVersion(String genus)
-  {
-        ProductVersionHolder pvh = ProductVersionHolder.getProductVersionHolderFromMyEnv(genus);
-        if (pvh == null)
-        {
-            return -1;
-        }
-
-        return pvh.getMajorVersion();
-  }
-
-
-	/**
-		gets the minor version of the IBM Cloudscape embedded code.
-		@return	the minor version. Returns -1 if not found.
-	 */
-  static public int getMinorVersion()
-  {
-    return getMinorVersion(DBMS);
-  }
-
-	/**
-		gets the minor version of the specified code library. 
-		@param genus	which library to get the version of. Valid inputs include
-			DBMS, TOOLS.
-		@return the minor version. Return -1 if the information is not found. 
-    */	
-  static public int getMinorVersion(String genus)
-  {
-        ProductVersionHolder pvh = ProductVersionHolder.getProductVersionHolderFromMyEnv(genus);
-        if (pvh == null)
-        {
-            return -1;
-        }
-
-        return pvh.getMinorVersion();
-  }
-
-	/**
-		gets the build number for the IBM Cloudscape embedded library
-		@return the build number, or -1 if the information is not found.
-	*/
-  static public int getBuildNumber()
-  {
-    return getBuildNumber("DBMS");
-  }
-
-	/**
-		gets the build number for the specified library
-		@param genus which library to get the build number for. Valid inputs are
-			DBMS, TOOLS
-		@return the build number, or -1 if the information is not found.
-	*/
-  static public int getBuildNumber(String genus)
-  {
-        ProductVersionHolder pvh = ProductVersionHolder.getProductVersionHolderFromMyEnv(genus);
-        if (pvh == null)
-        {
-            return -1;
-        }
-
-        return pvh.getBuildNumber();
-  }
-
-
-	/**
-		gets the product name for the IBM Cloudscape embedded library
-		@return the name
-	*/
-  static public String getProductName()
-  {
-    return getProductName("DBMS");
-  }
-
-	/**
-		gets the external name for the specified code library.
-		@param genus which library to get the name for
-		@return the name.
-	*/
-
-  static public String getProductName(String genus)
-  {
-        ProductVersionHolder pvh = ProductVersionHolder.getProductVersionHolderFromMyEnv(genus);
-        if (pvh == null)
-        {
-            return Main.getTextMessage ("SIF01.K");
-        }
-
-        return pvh.getProductName();
-  }
-
-  /**
-	Return the version information string for the specified library including alpha or beta indicators.
-  */
-  static public String getVersionString() {
-	return getVersionString(DBMS);
-  }
-
-  /**
-	Return the version information string for the IBM Cloudscape embedded library including alpha or beta indicators.
-  */
-  static public String getVersionString(String genus) {
-
-        ProductVersionHolder pvh = ProductVersionHolder.getProductVersionHolderFromMyEnv(genus);
-        if (pvh == null)
-        {
-            return Main.getTextMessage ("SIF01.K");
-        }
-		
-		return pvh.getVersionBuildString(false);
-  }
-
-  public static void getInfo (java.io.PrintWriter out) {
-    Main.getMainInfo(out, false);
-  }
-}
+/*
+
+   Licensed Materials - Property of IBM
+   Cloudscape - Package org.apache.derby.tools
+   (C) Copyright IBM Corp. 1998, 2004. All Rights Reserved.
+   US Government Users Restricted Rights - Use, duplication or
+   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+
+ */
+
+package org.apache.derby.tools;
+
+import org.apache.derby.iapi.services.info.ProductVersionHolder;
+import org.apache.derby.iapi.services.info.JVMInfo;
+import org.apache.derby.impl.tools.sysinfo.Main;
+
+/**
+	
+   This class displays system information to system out.
+	 
+	To run from the command-line, enter the following:
+	<p>
+	<code>java org.apache.derby.tools.sysinfo</code>
+	<p>
+	<p>
+	Also available on this class are methods which allow you to determine
+	the version of the code for the system without actually booting a database.
+	Please note that this is the Cloudscape version of the .jar files, not of your databases.
+	<p>
+	The numbering scheme for released Cloudscape products is <b><code>m1.m2.m3 </code></b>
+	where <b><code>m1</code></b> is the major release version, <b><code>m2</code></b> is the minor release version,
+	and <b><code>m3</code></b> is the maintenance level. Versions of the product with the same
+	major and minor version numbers are considered feature compatible. 
+	<p>Valid major and minor versions are always greater than zero. Valid maintenance
+	versions are greater than or equal to zero.
+
+
+*/
+public class sysinfo {
+	/**
+		IBM Copyright &copy notice.
+	*/
+	public static final String copyrightNotice = org.apache.derby.iapi.reference.Copyright.SHORT_1998_2004;
+
+  static public void main(String[] args) {
+    Main.main(args);
+  }
+
+  private sysinfo() { // no instances allowed
+  }
+
+	/**
+		The genus name for the IBM Cloudscape code. Use this to determine the version of the
+		IBM Cloudscape embedded code in cs.jar.
+	*/
+	public static final String DBMS="DBMS";
+
+	/**
+	 *	The genus name for the tools code. Use this to determine the version of 
+		code in cstools.jar
+	 */
+	public static final String TOOLS="tools";
+
+
+	/**
+		gets the major version of the IBM Cloudscape embedded code.
+		@return	the major version. Returns -1 if not found.
+	 */
+  static public int getMajorVersion()
+  {
+    return getMajorVersion(DBMS);
+  }
+
+
+	/**
+		gets the major version of the specified code library. 
+		@param genus	which library to get the version of. Valid inputs include
+			DBMS, TOOLS
+		@return the major version. Return -1 if the information is not found. 
+    */		
+  static public int getMajorVersion(String genus)
+  {
+        ProductVersionHolder pvh = ProductVersionHolder.getProductVersionHolderFromMyEnv(genus);
+        if (pvh == null)
+        {
+            return -1;
+        }
+
+        return pvh.getMajorVersion();
+  }
+
+
+	/**
+		gets the minor version of the IBM Cloudscape embedded code.
+		@return	the minor version. Returns -1 if not found.
+	 */
+  static public int getMinorVersion()
+  {
+    return getMinorVersion(DBMS);
+  }
+
+	/**
+		gets the minor version of the specified code library. 
+		@param genus	which library to get the version of. Valid inputs include
+			DBMS, TOOLS.
+		@return the minor version. Return -1 if the information is not found. 
+    */	
+  static public int getMinorVersion(String genus)
+  {
+        ProductVersionHolder pvh = ProductVersionHolder.getProductVersionHolderFromMyEnv(genus);
+        if (pvh == null)
+        {
+            return -1;
+        }
+
+        return pvh.getMinorVersion();
+  }
+
+	/**
+		gets the build number for the IBM Cloudscape embedded library
+		@return the build number, or -1 if the information is not found.
+	*/
+  static public int getBuildNumber()
+  {
+    return getBuildNumber("DBMS");
+  }
+
+	/**
+		gets the build number for the specified library
+		@param genus which library to get the build number for. Valid inputs are
+			DBMS, TOOLS
+		@return the build number, or -1 if the information is not found.
+	*/
+  static public int getBuildNumber(String genus)
+  {
+        ProductVersionHolder pvh = ProductVersionHolder.getProductVersionHolderFromMyEnv(genus);
+        if (pvh == null)
+        {
+            return -1;
+        }
+
+        return pvh.getBuildNumber();
+  }
+
+
+	/**
+		gets the product name for the IBM Cloudscape embedded library
+		@return the name
+	*/
+  static public String getProductName()
+  {
+    return getProductName("DBMS");
+  }
+
+	/**
+		gets the external name for the specified code library.
+		@param genus which library to get the name for
+		@return the name.
+	*/
+
+  static public String getProductName(String genus)
+  {
+        ProductVersionHolder pvh = ProductVersionHolder.getProductVersionHolderFromMyEnv(genus);
+        if (pvh == null)
+        {
+            return Main.getTextMessage ("SIF01.K");
+        }
+
+        return pvh.getProductName();
+  }
+
+  /**
+	Return the version information string for the specified library including alpha or beta indicators.
+  */
+  static public String getVersionString() {
+	return getVersionString(DBMS);
+  }
+
+  /**
+	Return the version information string for the IBM Cloudscape embedded library including alpha or beta indicators.
+  */
+  static public String getVersionString(String genus) {
+
+        ProductVersionHolder pvh = ProductVersionHolder.getProductVersionHolderFromMyEnv(genus);
+        if (pvh == null)
+        {
+            return Main.getTextMessage ("SIF01.K");
+        }
+		
+		return pvh.getVersionBuildString(false);
+  }
+
+  public static void getInfo (java.io.PrintWriter out) {
+    Main.getMainInfo(out, false);
+  }
+}